From 6b15695578f07a3f72c4c9475c1a261a3021472a Mon Sep 17 00:00:00 2001 From: mental Date: Mon, 16 Jan 2006 02:36:01 +0000 Subject: [PATCH] moving trunk for module inkscape --- .cvsignore | 35 + AUTHORS | 78 + COPYING | 340 + COPYING.LIB | 515 + ChangeLog | 9028 +++++++ HACKING.de.txt | 88 + HACKING.fr.txt | 91 + HACKING.it.txt | 83 + HACKING.txt | 86 + INSTALL | 232 + Info.plist.in | 133 + Makefile.am | 194 + Makefile.mingw | 145 + Makefile.mingw.common | 232 + Makefile.mingw.common.old | 209 + Makefile.mingw.old | 80 + NEWS | 439 + README | 75 + README.ca.txt | 44 + README.de.txt | 40 + README.es.txt | 75 + README.fr.txt | 76 + README.it.txt | 38 + TRANSLATORS | 64 + autogen.sh | 200 + config.h.mingw | 49 + configure.ac | 818 + cxxtest/COPYING | 504 + cxxtest/README | 63 + cxxtest/TODO | 34 + cxxtest/Versions | 152 + cxxtest/cxxtest.spec | 40 + cxxtest/cxxtest/Descriptions.cpp | 58 + cxxtest/cxxtest/Descriptions.h | 74 + cxxtest/cxxtest/DummyDescriptions.cpp | 49 + cxxtest/cxxtest/DummyDescriptions.h | 76 + cxxtest/cxxtest/ErrorFormatter.h | 281 + cxxtest/cxxtest/ErrorPrinter.h | 55 + cxxtest/cxxtest/Flags.h | 121 + cxxtest/cxxtest/GlobalFixture.cpp | 23 + cxxtest/cxxtest/GlobalFixture.h | 30 + cxxtest/cxxtest/Gui.h | 178 + cxxtest/cxxtest/LinkedList.cpp | 172 + cxxtest/cxxtest/LinkedList.h | 65 + cxxtest/cxxtest/Mock.h | 350 + cxxtest/cxxtest/ParenPrinter.h | 21 + cxxtest/cxxtest/QtGui.h | 271 + cxxtest/cxxtest/RealDescriptions.cpp | 311 + cxxtest/cxxtest/RealDescriptions.h | 223 + cxxtest/cxxtest/Root.cpp | 18 + cxxtest/cxxtest/SelfTest.h | 7 + cxxtest/cxxtest/StdHeaders.h | 25 + cxxtest/cxxtest/StdValueTraits.h | 229 + cxxtest/cxxtest/StdioFilePrinter.h | 41 + cxxtest/cxxtest/StdioPrinter.h | 22 + cxxtest/cxxtest/TeeListener.h | 182 + cxxtest/cxxtest/TestListener.h | 70 + cxxtest/cxxtest/TestRunner.h | 125 + cxxtest/cxxtest/TestSuite.cpp | 138 + cxxtest/cxxtest/TestSuite.h | 512 + cxxtest/cxxtest/TestTracker.cpp | 248 + cxxtest/cxxtest/TestTracker.h | 114 + cxxtest/cxxtest/ValueTraits.cpp | 140 + cxxtest/cxxtest/ValueTraits.h | 377 + cxxtest/cxxtest/Win32Gui.h | 531 + cxxtest/cxxtest/X11Gui.h | 327 + cxxtest/cxxtest/YesNoRunner.h | 29 + cxxtest/cxxtestgen.pl | 551 + cxxtest/cxxtestgen.py | 593 + cxxtest/docs/convert.pl | 83 + cxxtest/docs/guide.html | 1960 ++ cxxtest/docs/index.html | 56 + cxxtest/docs/qt.png | Bin 0 -> 13630 bytes cxxtest/docs/qt2.png | Bin 0 -> 11684 bytes cxxtest/docs/win32.png | Bin 0 -> 1709 bytes cxxtest/docs/x11.png | Bin 0 -> 1342 bytes cxxtest/sample/Construct | 64 + cxxtest/sample/CreatedTest.h | 31 + cxxtest/sample/DeltaTest.h | 27 + cxxtest/sample/EnumTraits.h | 39 + cxxtest/sample/ExceptionTest.h | 52 + cxxtest/sample/FixtureTest.h | 37 + cxxtest/sample/Makefile.PL | 32 + cxxtest/sample/Makefile.bcc32 | 94 + cxxtest/sample/Makefile.msvc | 93 + cxxtest/sample/Makefile.unix | 88 + cxxtest/sample/MessageTest.h | 30 + cxxtest/sample/SimpleTest.h | 59 + cxxtest/sample/TraitsTest.h | 69 + cxxtest/sample/aborter.tpl | 16 + cxxtest/sample/file_printer.tpl | 22 + cxxtest/sample/gui/GreenYellowRed.h | 57 + cxxtest/sample/mock/Dice.cpp | 14 + cxxtest/sample/mock/Dice.h | 13 + cxxtest/sample/mock/Makefile | 22 + cxxtest/sample/mock/MockStdlib.h | 31 + cxxtest/sample/mock/T/stdlib.h | 13 + cxxtest/sample/mock/TestDice.h | 62 + cxxtest/sample/mock/mock_stdlib.cpp | 2 + cxxtest/sample/mock/real_stdlib.cpp | 2 + cxxtest/sample/mock/roll.cpp | 11 + cxxtest/sample/msvc/CxxTest_1_Run.dsp | 93 + cxxtest/sample/msvc/CxxTest_2_Build.dsp | 94 + cxxtest/sample/msvc/CxxTest_3_Generate.dsp | 93 + cxxtest/sample/msvc/CxxTest_Workspace.dsw | 59 + cxxtest/sample/msvc/FixFiles.bat | 212 + cxxtest/sample/msvc/Makefile | 36 + cxxtest/sample/msvc/ReadMe.txt | 30 + cxxtest/sample/only.tpl | 33 + cxxtest/sample/parts/Makefile.unix | 39 + cxxtest/sample/winddk/Makefile | 2 + cxxtest/sample/winddk/Makefile.inc | 15 + cxxtest/sample/winddk/RunTests.tpl | 13 + cxxtest/sample/winddk/SOURCES | 46 + cxxtest/sample/yes_no_runner.cpp | 11 + debian/.cvsignore | 10 + debian/changelog | 233 + debian/compat | 1 + debian/control | 32 + debian/copyright | 38 + debian/dirs | 1 + debian/docs | 2 + debian/inkscape.applications | 7 + debian/inkscape.menu | 5 + debian/inkscape.xpm | 95 + debian/mime | 2 + debian/rules | 101 + delautogen.sh | 14 + distro | 289 + doc/.cvsignore | 3 + doc/API | 61 + doc/ChangeLog_archive.txt | 10577 +++++++++ doc/Makefile.am | 16 + doc/NewAppArchitecture/01-title.svg | 216 + doc/NewAppArchitecture/02-outline.svg | 416 + doc/NewAppArchitecture/03-current.svg | 476 + doc/NewAppArchitecture/04-current-main.svg | 584 + doc/NewAppArchitecture/05-current-objects.svg | 1145 + .../06-current-desktop-view.svg | 667 + .../07-current-problems.svg | 612 + doc/NewAppArchitecture/08-inkscape-gtkmm.svg | 472 + .../09-future-capabilities.svg | 484 + doc/NewAppArchitecture/10-future-main.svg | 503 + doc/NewAppArchitecture/11-future-ink-app.svg | 507 + .../12-future-run-modes.svg | 936 + .../13-future-ink-app-editor.svg | 1403 ++ doc/NewAppArchitecture/14-evolving.svg | 511 + doc/README.document | 77 + doc/WISHLIST | 51 + doc/architecture.svg | 607 + doc/architecture.txt | 490 + doc/class-hierarchy.dia | Bin 0 -> 6668 bytes doc/coordinates.txt | 53 + doc/extension_system.txt | 411 + doc/extension_system.xml | 237 + doc/fonts.txt | 40 + doc/inkscape-shadow.README | 63 + doc/inkscape-uml.dia | Bin 0 -> 7779 bytes doc/keys-html.xsl | 182 + doc/keys-svg.xsl | 1315 ++ doc/keys.README | 26 + doc/keys.fr.html | 903 + doc/keys.fr.xml | 927 + doc/keys.html | 1060 + doc/keys.xml | 1104 + doc/spsvgview.txt | 15 + fix-roff-punct | 139 + inkscape.desktop.in | 19 + inkscape.fr.pod | 395 + inkscape.ico | Bin 0 -> 12862 bytes inkscape.nsi | 1 + inkscape.png | Bin 0 -> 1521 bytes inkscape.pod | 514 + inkscape.spec.in | 119 + inkscape16.ico | Bin 0 -> 894 bytes inkscape32-16.ico | Bin 0 -> 766 bytes inkscape32.ico | Bin 0 -> 3262 bytes inkscape32x16col.ico | Bin 0 -> 766 bytes inkscape64.ico | Bin 0 -> 12862 bytes inkview.1.in | 52 + libgc.supp | 15 + m4/Makefile.am | 3 + m4/codeset.m4 | 23 + m4/gettext.m4 | 587 + m4/glibc21.m4 | 32 + m4/iconv.m4 | 103 + m4/isc-posix.m4 | 26 + m4/lcmessage.m4 | 32 + m4/progtest.m4 | 59 + mingwenv.bat | 4 + mkinstalldirs | 150 + packaging/autopackage/.cvsignore | 1 + packaging/autopackage/default.apspec.in | 63 + packaging/inkscape.16.png.bz2 | Bin 0 -> 609 bytes packaging/inkscape.32.png.bz2 | Bin 0 -> 1030 bytes packaging/inkscape.48.png.bz2 | Bin 0 -> 1951 bytes packaging/macosx/Resources/EPS.icns | Bin 0 -> 45195 bytes packaging/macosx/Resources/EPSI.icns | Bin 0 -> 45195 bytes packaging/macosx/Resources/Inkscape.icns | Bin 0 -> 51289 bytes .../macosx/Resources/MenuBar.nib/classes.nib | 4 + .../macosx/Resources/MenuBar.nib/info.nib | 23 + .../macosx/Resources/MenuBar.nib/objects.xib | 73 + .../Resources/ProgressWindow.nib/classes.nib | 4 + .../Resources/ProgressWindow.nib/info.nib | 18 + .../Resources/ProgressWindow.nib/objects.xib | 53 + packaging/macosx/Resources/SVG_plain.icns | Bin 0 -> 45252 bytes packaging/macosx/Resources/bin/getdisplay.sh | 9 + packaging/macosx/Resources/bin/inkscape | 40 + packaging/macosx/Resources/inkscape_svg.icns | Bin 0 -> 52648 bytes packaging/macosx/Resources/openDoc | 8 + packaging/macosx/Resources/postscript.icns | Bin 0 -> 45198 bytes packaging/macosx/Resources/script | 35 + .../English.lproj/InfoPlist.strings | Bin 0 -> 520 bytes .../English.lproj/main.nib/classes.nib | 4 + .../English.lproj/main.nib/info.nib | 19 + .../English.lproj/main.nib/objects.xib | 271 + packaging/macosx/ScriptExec/Info.plist | 39 + .../macosx/ScriptExec/MenuBar.nib/classes.nib | 4 + .../macosx/ScriptExec/MenuBar.nib/info.nib | 23 + .../macosx/ScriptExec/MenuBar.nib/objects.xib | 73 + .../ScriptExec.xcode/project.pbxproj | 451 + .../ScriptExec.xcode/sveinbjornt.pbxuser | 378 + .../ScriptExec.xcode/voisine.pbxuser | 729 + .../macosx/ScriptExec/ScriptExec_Prefix.pch | 5 + packaging/macosx/ScriptExec/main.c | 624 + packaging/macosx/ScriptExec/openDoc | 4 + packaging/macosx/ScriptExec/script | 4 + packaging/macosx/ScriptExec/version.plist | 16 + packaging/osx-app.sh | 231 + packaging/win32/english.nsh | 154 + packaging/win32/german.nsh | 158 + packaging/win32/header.bmp | Bin 0 -> 25818 bytes packaging/win32/inkscape.nsi | 1055 + packaging/win32/inkscape.nsi.uninstall | 20 + po/.cvsignore | 14 + po/ChangeLog | 1010 + po/Makefile.mingw | 23 + po/Makevars | 25 + po/POTFILES.in | 343 + po/am.po | 9942 ++++++++ po/az.po | 10742 +++++++++ po/bad.po.test | 85 + po/bad.po.test.exp | 74 + po/be.po | 10986 +++++++++ po/ca.po | 9595 ++++++++ po/check-markup | 190 + po/cs.po | 9518 ++++++++ po/da.po | 11342 +++++++++ po/de.po | 10519 +++++++++ po/el.po | 11553 +++++++++ po/es.po | 9641 ++++++++ po/es_MX.po | 10812 +++++++++ po/et.po | 10370 ++++++++ po/eu.po | 10738 +++++++++ po/fr.po | 9703 ++++++++ po/ga.po | 10146 ++++++++ po/gl.po | 11428 +++++++++ po/hu.po | 9671 ++++++++ po/it.po | 9615 ++++++++ po/ja.po | 9284 ++++++++ po/mk.po | 9817 ++++++++ po/nb.po | 10881 +++++++++ po/nl.po | 9647 ++++++++ po/nn.po | 9552 ++++++++ po/pa.po | 9129 +++++++ po/pl.po | 10368 ++++++++ po/pt.po | 11506 +++++++++ po/pt_BR.po | 10586 +++++++++ po/ru.po | 9565 ++++++++ po/sk.po | 10264 ++++++++ po/sl.po | 9543 ++++++++ po/sr.po | 9526 ++++++++ po/sr@Latn.po | 9541 ++++++++ po/sv.po | 11496 +++++++++ po/tr.po | 11567 +++++++++ po/uk.po | 9561 ++++++++ po/zh_CN.po | 11366 +++++++++ share/.cvsignore | 2 + share/Makefile.am | 22 + share/README | 5 + share/clipart/.cvsignore | 2 + share/clipart/Makefile.am | 13 + share/clipart/README | 25 + share/clipart/README-ribbon.txt | 13 + share/clipart/inkscape.logo.svg | 52 + share/clipart/orav.svg | 121 + share/clipart/ribbon.svg | 93 + share/clipart/tux.png | Bin 0 -> 71610 bytes share/clipart/tux.svg | 175 + share/examples/.cvsignore | 2 + share/examples/Makefile.am | 19 + share/examples/README | 5 + share/examples/art-nouveau-P3.svg | 475 + share/examples/data_uri.svg | 110 + share/examples/eastern-motive-P4G.svg | 1435 ++ share/examples/flow-go.svg | 59 + share/examples/flowsample.svg | 80 + share/examples/gradient.svg | 1514 ++ share/examples/i18n.svg | 415 + share/examples/istest.pov | 163 + share/examples/markers.svg | 854 + share/examples/stars.svgz | Bin 0 -> 34102 bytes share/examples/tesselation-P3.svg | 994 + share/examples/text-on-path.svg | 374 + share/examples/tiger.svgz | Bin 0 -> 34776 bytes share/extensions/.cvsignore | 2 + share/extensions/Makefile.am | 99 + share/extensions/README | 12 + share/extensions/SpSVG.pm | 351 + share/extensions/addnodes.inx | 13 + share/extensions/addnodes.py | 92 + share/extensions/ai_input.inx | 16 + share/extensions/ai_output.inx | 16 + share/extensions/bezmisc.py | 250 + share/extensions/bluredge.inx | 13 + share/extensions/cubicsuperpath.py | 83 + share/extensions/dia.inx | 15 + share/extensions/dia2svg.sh | 13 + share/extensions/dots.inx | 14 + share/extensions/dots.py | 75 + share/extensions/dropshadow.inx | 13 + share/extensions/dxf_input.inx | 16 + share/extensions/dxf_output.inx | 17 + share/extensions/embed_raster_in_svg.pl | 122 + share/extensions/embedimage.inx | 12 + share/extensions/embedimage.py | 60 + share/extensions/eps_input.inx | 17 + share/extensions/epsi_output.inx | 17 + share/extensions/extractimage.inx | 13 + share/extensions/extractimage.py | 50 + share/extensions/ffgeom.py | 127 + share/extensions/ffmet.inx | 23 + share/extensions/ffms.inx | 23 + share/extensions/ffproc.py | 194 + share/extensions/ffscale.py | 73 + share/extensions/ffset.inx | 21 + share/extensions/ffss.inx | 21 + share/extensions/fretfind.py | 186 + share/extensions/gimpgrad.inx | 14 + share/extensions/grid.inx | 16 + share/extensions/handles.inx | 12 + share/extensions/handles.py | 56 + share/extensions/ill2svg.pl | 374 + share/extensions/inkex.py | 103 + share/extensions/inkscape-shadow-white.sh | 2 + share/extensions/inkscape-shadow.sh | 2 + share/extensions/interp.inx | 17 + share/extensions/interp.py | 332 + share/extensions/kochify.inx | 12 + share/extensions/kochify.py | 86 + share/extensions/kochify_load.inx | 12 + share/extensions/kochify_load.py | 60 + share/extensions/lindenmayer.inx | 17 + share/extensions/lindenmayer.py | 88 + share/extensions/motion.inx | 14 + share/extensions/motion.py | 119 + share/extensions/pdf_output.inx | 17 + .../extensions/pdf_output_via_gs_on_win32.inx | 24 + share/extensions/ps2dxf.sh | 10 + share/extensions/ps2epsi.sh | 9 + share/extensions/ps2pdf.cmd | 10 + share/extensions/ps2pdf.sh | 2 + share/extensions/ps_input.inx | 17 + share/extensions/pturtle.py | 80 + share/extensions/radiusrand.inx | 15 + share/extensions/radiusrand.py | 65 + share/extensions/randompnt.inx | 11 + share/extensions/randompos.inx | 11 + share/extensions/rtree.inx | 14 + share/extensions/rtree.py | 59 + share/extensions/simplepath.py | 201 + share/extensions/simplestyle.py | 27 + share/extensions/sk2svg.sh | 12 + share/extensions/sk_input.inx | 15 + share/extensions/straightseg.inx | 14 + share/extensions/straightseg.py | 69 + share/extensions/summersnight.inx | 12 + share/extensions/summersnight.py | 99 + share/extensions/svg_and_media_zip_output.inx | 18 + share/extensions/svg_and_media_zip_output.py | 123 + share/extensions/svg_dropshadow | 88 + share/extensions/svgz_input.inx | 17 + share/extensions/svgz_output.inx | 17 + share/extensions/txt2svg.inx | 16 + share/extensions/txt2svg.pl | 33 + share/extensions/wavy.inx | 17 + share/extensions/wavy.py | 133 + share/extensions/whirl.inx | 16 + share/extensions/whirl.py | 65 + share/extensions/wmf_input.inx | 14 + share/fonts/.cvsignore | 2 + share/fonts/Makefile.am | 7 + share/fonts/README | 5 + share/gradients/.cvsignore | 2 + share/gradients/Makefile.am | 7 + share/gradients/README | 5 + share/icons/.cvsignore | 3 + share/icons/David_icons.svg | 13562 +++++++++++ share/icons/Makefile.am | 19 + share/icons/README | 7 + share/icons/README.David_icons | 3 + share/icons/README.crispy_icons | 3 + share/icons/README.icon_themes | 29 + share/icons/crispy_icons.svg | 11734 +++++++++ share/icons/icons.svg | 8262 +++++++ share/icons/inkscape.svg | 204 + share/keyboards/.cvsignore | 2 + share/keyboards/Makefile.am | 7 + share/keyboards/README | 5 + share/markers/.cvsignore | 3 + share/markers/Makefile.am | 9 + share/markers/markers.svg | 615 + share/palettes/.cvsignore | 2 + share/palettes/Makefile.am | 11 + share/palettes/README | 4 + share/palettes/Tango-Palette.gpl | 31 + share/palettes/svg.gpl | 141 + share/palettes/webhex.gpl | 219 + share/palettes/websafe22.gpl | 25 + share/patterns/.cvsignore | 2 + share/patterns/Makefile.am | 7 + share/patterns/README | 5 + share/screens/.cvsignore | 2 + share/screens/Makefile.am | 12 + share/screens/README | 4 + share/screens/about.svg | 409 + share/screens/keys.fr.svg | 844 + share/screens/keys.sl.svg | 737 + share/screens/keys.svg | 967 + share/templates/.cvsignore | 2 + share/templates/A4.svg | 39 + share/templates/A4_landscape.svg | 36 + share/templates/CD_cover_300dpi.svg | 36 + share/templates/Letter.svg | 36 + share/templates/Letter_landscape.svg | 36 + share/templates/Makefile.am | 38 + share/templates/README | 12 + share/templates/black_opaque.svg | 36 + share/templates/business_card_85x54mm.svg | 37 + share/templates/business_card_90x50mm.svg | 38 + share/templates/default.cs.svg | 42 + share/templates/default.de.svg | 37 + share/templates/default.es.svg | 37 + share/templates/default.fr.svg | 37 + share/templates/default.hu.svg | 37 + share/templates/default.it.svg | 37 + share/templates/default.pl.svg | 37 + share/templates/default.svg | 37 + share/templates/default_mm.svg | 37 + share/templates/default_pt.svg | 37 + share/templates/desktop_1024x768.svg | 37 + share/templates/desktop_1600x1200.svg | 37 + share/templates/desktop_640x480.svg | 37 + share/templates/desktop_800x600.svg | 38 + share/templates/icon_16x16.svg | 42 + share/templates/icon_32x32.svg | 42 + share/templates/icon_48x48.svg | 42 + share/templates/icon_64x64.svg | 43 + share/templates/no_borders.svg | 37 + share/templates/no_layers.svg | 35 + share/templates/web_banner_468x60.svg | 37 + share/templates/web_banner_728x90.svg | 37 + share/templates/white_opaque.svg | 37 + share/tutorials/.cvsignore | 2 + share/tutorials/Makefile.am | 49 + share/tutorials/README | 11 + share/tutorials/gpl-2.svg | 2051 ++ share/tutorials/making_markers.svg | 905 + share/tutorials/oldguitar.jpg | Bin 0 -> 19785 bytes share/tutorials/potrace-de.png | Bin 0 -> 2745 bytes share/tutorials/potrace-fr.png | Bin 0 -> 6468 bytes share/tutorials/potrace.png | Bin 0 -> 2686 bytes share/tutorials/tutorial-advanced.es.svg | 467 + share/tutorials/tutorial-advanced.fr.svg | 325 + share/tutorials/tutorial-advanced.ja.svg | 314 + share/tutorials/tutorial-advanced.sl.svg | 411 + share/tutorials/tutorial-advanced.svg | 475 + share/tutorials/tutorial-basic.ca.svg | 650 + share/tutorials/tutorial-basic.de.svg | 535 + share/tutorials/tutorial-basic.es.svg | 479 + share/tutorials/tutorial-basic.fr.svg | 452 + share/tutorials/tutorial-basic.ja.svg | 401 + share/tutorials/tutorial-basic.nn.svg | 379 + share/tutorials/tutorial-basic.ru.svg | 3036 +++ share/tutorials/tutorial-basic.sl.svg | 437 + share/tutorials/tutorial-basic.svg | 562 + share/tutorials/tutorial-calligraphy.es.svg | 548 + share/tutorials/tutorial-calligraphy.fr.svg | 480 + share/tutorials/tutorial-calligraphy.sl.svg | 627 + share/tutorials/tutorial-calligraphy.svg | 637 + share/tutorials/tutorial-elements.es.svg | 582 + share/tutorials/tutorial-elements.fr.svg | 619 + share/tutorials/tutorial-elements.sl.svg | 596 + share/tutorials/tutorial-elements.svg | 606 + share/tutorials/tutorial-shapes.ca.svg | 6689 ++++++ share/tutorials/tutorial-shapes.es.svg | 619 + share/tutorials/tutorial-shapes.fr.svg | 670 + share/tutorials/tutorial-shapes.ja.svg | 600 + share/tutorials/tutorial-shapes.sl.svg | 751 + share/tutorials/tutorial-shapes.svg | 766 + share/tutorials/tutorial-tips.es.svg | 535 + share/tutorials/tutorial-tips.fr.svg | 472 + share/tutorials/tutorial-tips.sl.svg | 533 + share/tutorials/tutorial-tips.svg | 536 + share/tutorials/tutorial-tracing.de.svg | 186 + share/tutorials/tutorial-tracing.es.svg | 184 + share/tutorials/tutorial-tracing.fr.svg | 187 + share/tutorials/tutorial-tracing.sl.svg | 208 + share/tutorials/tutorial-tracing.svg | 215 + share/tutorials/tux.png | Bin 0 -> 8085 bytes share/ui/.cvsignore | 2 + share/ui/Makefile.am | 11 + share/ui/keybindings.rc | 126 + share/ui/menus-bars.xml | 280 + share/ui/toolbox.xml | 13 + share/ui/units.txt | 20 + share/ui/units.xml | 101 + src/.cvsignore | 19 + src/Doxyfile | 269 + src/Makefile.am | 261 + src/Makefile.mingw | 123 + src/Makefile.mingw.old | 53 + src/Makefile_insert | 339 + src/algorithms/.cvsignore | 2 + src/algorithms/Makefile_insert | 5 + src/algorithms/find-if-before.h | 51 + src/algorithms/find-last-if.h | 51 + src/algorithms/longest-common-suffix.h | 114 + src/algorithms/makefile.in | 17 + src/application/.cvsignore | 3 + src/application/Makefile_insert | 14 + src/application/app-prototype.cpp | 43 + src/application/app-prototype.h | 53 + src/application/application.cpp | 163 + src/application/application.h | 65 + src/application/editor.cpp | 416 + src/application/editor.h | 139 + src/application/makefile.in | 17 + src/approx-equal.h | 25 + src/arc-context.cpp | 447 + src/arc-context.h | 62 + src/attributes-test.cpp | 473 + src/attributes.cpp | 348 + src/attributes.h | 318 + src/bad-uri-exception.h | 34 + src/brokenimage.xpm | 88 + src/check-header-compile.in | 41 + src/color-rgba.h | 194 + src/color.cpp | 468 + src/color.h | 95 + src/composite-undo-stack-observer.cpp | 136 + src/composite-undo-stack-observer.h | 165 + src/conn-avoid-ref.cpp | 176 + src/conn-avoid-ref.h | 57 + src/connector-context.cpp | 1350 ++ src/connector-context.h | 112 + src/context-fns.cpp | 192 + src/context-fns.h | 27 + src/debug/.cvsignore | 3 + src/debug/Makefile_insert | 15 + src/debug/event-tracker.h | 224 + src/debug/event.h | 75 + src/debug/gc-heap.h | 52 + src/debug/heap.cpp | 65 + src/debug/heap.h | 63 + src/debug/logger.cpp | 204 + src/debug/logger.h | 171 + src/debug/makefile.in | 17 + src/debug/simple-event.h | 51 + src/debug/sysv-heap.cpp | 79 + src/debug/sysv-heap.h | 47 + src/decimal-round.h | 44 + src/desktop-affine.cpp | 40 + src/desktop-affine.h | 36 + src/desktop-events.cpp | 452 + src/desktop-events.h | 55 + src/desktop-handles.cpp | 122 + src/desktop-handles.h | 71 + src/desktop-style.cpp | 1006 + src/desktop-style.h | 87 + src/desktop.cpp | 1400 ++ src/desktop.h | 289 + src/dialogs/.cvsignore | 5 + src/dialogs/Makefile_insert | 75 + src/dialogs/clonetiler.cpp | 2578 ++ src/dialogs/clonetiler.h | 31 + src/dialogs/debugdialog.cpp | 348 + src/dialogs/debugdialog.h | 104 + src/dialogs/dialog-events.cpp | 247 + src/dialogs/dialog-events.h | 66 + src/dialogs/display-settings.cpp | 1575 ++ src/dialogs/display-settings.h | 69 + src/dialogs/eek-preview.cpp | 522 + src/dialogs/eek-preview.h | 112 + src/dialogs/export.cpp | 1753 ++ src/dialogs/export.h | 24 + src/dialogs/extensions.cpp | 128 + src/dialogs/extensions.h | 61 + src/dialogs/filedialog-win32.cpp | 381 + src/dialogs/filedialog.cpp | 1439 ++ src/dialogs/filedialog.h | 172 + src/dialogs/fill-style.cpp | 546 + src/dialogs/fill-style.h | 35 + src/dialogs/find.cpp | 763 + src/dialogs/find.h | 31 + src/dialogs/iconpreview.cpp | 320 + src/dialogs/iconpreview.h | 84 + src/dialogs/in-dt-coordsys.cpp | 37 + src/dialogs/in-dt-coordsys.h | 19 + src/dialogs/input.cpp | 273 + src/dialogs/input.h | 32 + src/dialogs/item-properties.cpp | 497 + src/dialogs/item-properties.h | 38 + src/dialogs/layer-properties.cpp | 199 + src/dialogs/layer-properties.h | 110 + src/dialogs/makefile.in | 17 + src/dialogs/object-attributes.cpp | 140 + src/dialogs/object-attributes.h | 37 + src/dialogs/object-properties.cpp | 318 + src/dialogs/object-properties.h | 34 + src/dialogs/rdf.cpp | 1002 + src/dialogs/rdf.h | 124 + src/dialogs/sp-attribute-widget.cpp | 802 + src/dialogs/sp-attribute-widget.h | 128 + src/dialogs/stroke-style.cpp | 1726 ++ src/dialogs/stroke-style.h | 35 + src/dialogs/swatches.cpp | 516 + src/dialogs/swatches.h | 93 + src/dialogs/text-edit.cpp | 915 + src/dialogs/text-edit.h | 24 + src/dialogs/tiledialog.cpp | 872 + src/dialogs/tiledialog.h | 190 + src/dialogs/unclump.cpp | 371 + src/dialogs/unclump.h | 20 + src/dialogs/xml-tree.cpp | 1575 ++ src/dialogs/xml-tree.h | 29 + src/dir-util-test.cpp | 48 + src/dir-util.cpp | 278 + src/dir-util.h | 33 + src/display/.cvsignore | 7 + src/display/Makefile_insert | 66 + src/display/bezier-utils-test.cpp | 334 + src/display/bezier-utils-work.txt | 34 + src/display/bezier-utils.cpp | 983 + src/display/bezier-utils.h | 49 + src/display/canvas-arena.cpp | 451 + src/display/canvas-arena.h | 58 + src/display/canvas-bpath.cpp | 485 + src/display/canvas-bpath.h | 99 + src/display/canvas-grid.cpp | 308 + src/display/canvas-grid.h | 49 + src/display/curve.cpp | 1289 + src/display/curve.h | 133 + src/display/display-forward.h | 46 + src/display/gnome-canvas-acetate.cpp | 100 + src/display/gnome-canvas-acetate.h | 41 + src/display/guideline.cpp | 198 + src/display/guideline.h | 55 + src/display/makefile.in | 17 + src/display/nr-arena-forward.h | 51 + src/display/nr-arena-glyphs.cpp | 679 + src/display/nr-arena-glyphs.h | 109 + src/display/nr-arena-group.cpp | 256 + src/display/nr-arena-group.h | 46 + src/display/nr-arena-image.cpp | 258 + src/display/nr-arena-image.h | 51 + src/display/nr-arena-item.cpp | 1155 + src/display/nr-arena-item.h | 188 + src/display/nr-arena-shape.cpp | 1298 + src/display/nr-arena-shape.h | 213 + src/display/nr-arena.cpp | 131 + src/display/nr-arena.h | 57 + src/display/nr-gradient-gpl.cpp | 306 + src/display/nr-gradient-gpl.h | 41 + src/display/nr-plain-stuff-gdk.cpp | 46 + src/display/nr-plain-stuff-gdk.h | 32 + src/display/nr-plain-stuff.cpp | 94 + src/display/nr-plain-stuff.h | 33 + src/display/sodipodi-ctrl.cpp | 494 + src/display/sodipodi-ctrl.h | 65 + src/display/sodipodi-ctrlrect.cpp | 330 + src/display/sodipodi-ctrlrect.h | 70 + src/display/sp-canvas-util.cpp | 307 + src/display/sp-canvas-util.h | 61 + src/display/sp-canvas.cpp | 2074 ++ src/display/sp-canvas.h | 186 + src/display/sp-ctrlline.cpp | 217 + src/display/sp-ctrlline.h | 45 + src/display/sp-ctrlquadr.cpp | 210 + src/display/sp-ctrlquadr.h | 43 + src/display/testnr.cpp | 24 + src/document-private.h | 67 + src/document-undo.cpp | 322 + src/document.cpp | 1093 + src/document.h | 218 + src/dom/.cvsignore | 3 + src/dom/001.css | 214 + src/dom/Filt.java | 77 + src/dom/ImplGen.java | 180 + src/dom/Makefile.static | 71 + src/dom/Makefile_insert | 57 + src/dom/README | 25 + src/dom/acid.css | 110 + src/dom/base.css | 32 + src/dom/charclass.cpp | 451 + src/dom/charclass.h | 185 + src/dom/css.h | 4121 ++++ src/dom/css.idl | 633 + src/dom/cssparser.cpp | 1669 ++ src/dom/cssparser.h | 286 + src/dom/cssprop.txt | 123 + src/dom/dom.h | 2204 ++ src/dom/dom.idl | 548 + src/dom/domimpl.cpp | 2984 +++ src/dom/domimpl.h | 2002 ++ src/dom/domstream.cpp | 874 + src/dom/domstream.h | 674 + src/dom/domstring.cpp | 414 + src/dom/domstring.h | 309 + src/dom/domstringimpl.h | 107 + src/dom/events.h | 1351 ++ src/dom/events.idl | 298 + src/dom/inkscape.css | 493 + src/dom/inkscape.logo.svg | 52 + src/dom/js/Makefile | 1471 ++ src/dom/js/README | 20 + src/dom/js/fdlibm/e_acos.c | 147 + src/dom/js/fdlibm/e_acosh.c | 105 + src/dom/js/fdlibm/e_asin.c | 156 + src/dom/js/fdlibm/e_atan2.c | 165 + src/dom/js/fdlibm/e_atanh.c | 110 + src/dom/js/fdlibm/e_cosh.c | 133 + src/dom/js/fdlibm/e_exp.c | 202 + src/dom/js/fdlibm/e_fmod.c | 184 + src/dom/js/fdlibm/e_gamma.c | 71 + src/dom/js/fdlibm/e_gamma_r.c | 70 + src/dom/js/fdlibm/e_hypot.c | 173 + src/dom/js/fdlibm/e_j0.c | 524 + src/dom/js/fdlibm/e_j1.c | 523 + src/dom/js/fdlibm/e_jn.c | 315 + src/dom/js/fdlibm/e_lgamma.c | 71 + src/dom/js/fdlibm/e_lgamma_r.c | 347 + src/dom/js/fdlibm/e_log.c | 184 + src/dom/js/fdlibm/e_log10.c | 134 + src/dom/js/fdlibm/e_pow.c | 386 + src/dom/js/fdlibm/e_rem_pio2.c | 221 + src/dom/js/fdlibm/e_remainder.c | 120 + src/dom/js/fdlibm/e_scalb.c | 89 + src/dom/js/fdlibm/e_sinh.c | 122 + src/dom/js/fdlibm/e_sqrt.c | 497 + src/dom/js/fdlibm/fdlibm.h | 273 + src/dom/js/fdlibm/k_cos.c | 134 + src/dom/js/fdlibm/k_rem_pio2.c | 354 + src/dom/js/fdlibm/k_sin.c | 114 + src/dom/js/fdlibm/k_standard.c | 785 + src/dom/js/fdlibm/k_tan.c | 170 + src/dom/js/fdlibm/s_asinh.c | 101 + src/dom/js/fdlibm/s_atan.c | 175 + src/dom/js/fdlibm/s_cbrt.c | 133 + src/dom/js/fdlibm/s_ceil.c | 120 + src/dom/js/fdlibm/s_copysign.c | 72 + src/dom/js/fdlibm/s_cos.c | 118 + src/dom/js/fdlibm/s_erf.c | 356 + src/dom/js/fdlibm/s_expm1.c | 267 + src/dom/js/fdlibm/s_fabs.c | 70 + src/dom/js/fdlibm/s_finite.c | 71 + src/dom/js/fdlibm/s_floor.c | 121 + src/dom/js/fdlibm/s_frexp.c | 99 + src/dom/js/fdlibm/s_ilogb.c | 85 + src/dom/js/fdlibm/s_isnan.c | 74 + src/dom/js/fdlibm/s_ldexp.c | 66 + src/dom/js/fdlibm/s_lib_version.c | 73 + src/dom/js/fdlibm/s_log1p.c | 211 + src/dom/js/fdlibm/s_logb.c | 79 + src/dom/js/fdlibm/s_matherr.c | 64 + src/dom/js/fdlibm/s_modf.c | 132 + src/dom/js/fdlibm/s_nextafter.c | 124 + src/dom/js/fdlibm/s_rint.c | 131 + src/dom/js/fdlibm/s_scalbn.c | 107 + src/dom/js/fdlibm/s_signgam.c | 40 + src/dom/js/fdlibm/s_significand.c | 68 + src/dom/js/fdlibm/s_sin.c | 118 + src/dom/js/fdlibm/s_tan.c | 112 + src/dom/js/fdlibm/s_tanh.c | 122 + src/dom/js/fdlibm/w_acos.c | 78 + src/dom/js/fdlibm/w_acosh.c | 78 + src/dom/js/fdlibm/w_asin.c | 80 + src/dom/js/fdlibm/w_atan2.c | 79 + src/dom/js/fdlibm/w_atanh.c | 81 + src/dom/js/fdlibm/w_cosh.c | 77 + src/dom/js/fdlibm/w_exp.c | 88 + src/dom/js/fdlibm/w_fmod.c | 78 + src/dom/js/fdlibm/w_gamma.c | 85 + src/dom/js/fdlibm/w_gamma_r.c | 81 + src/dom/js/fdlibm/w_hypot.c | 78 + src/dom/js/fdlibm/w_j0.c | 105 + src/dom/js/fdlibm/w_j1.c | 106 + src/dom/js/fdlibm/w_jn.c | 128 + src/dom/js/fdlibm/w_lgamma.c | 85 + src/dom/js/fdlibm/w_lgamma_r.c | 81 + src/dom/js/fdlibm/w_log.c | 78 + src/dom/js/fdlibm/w_log10.c | 81 + src/dom/js/fdlibm/w_pow.c | 99 + src/dom/js/fdlibm/w_remainder.c | 77 + src/dom/js/fdlibm/w_scalb.c | 95 + src/dom/js/fdlibm/w_sinh.c | 77 + src/dom/js/fdlibm/w_sqrt.c | 77 + src/dom/js/js.c | 2333 ++ src/dom/js/js.mak | 4025 ++++ src/dom/js/js.msg | 251 + src/dom/js/jsapi.c | 4187 ++++ src/dom/js/jsapi.h | 1752 ++ src/dom/js/jsarena.c | 565 + src/dom/js/jsarena.h | 302 + src/dom/js/jsarray.c | 1429 ++ src/dom/js/jsarray.h | 77 + src/dom/js/jsatom.c | 911 + src/dom/js/jsatom.h | 409 + src/dom/js/jsautocfg.h | 50 + src/dom/js/jsbit.h | 113 + src/dom/js/jsbool.c | 244 + src/dom/js/jsbool.h | 62 + src/dom/js/jsclist.h | 139 + src/dom/js/jscntxt.c | 702 + src/dom/js/jscntxt.h | 496 + src/dom/js/jscompat.h | 57 + src/dom/js/jsconfig.h | 489 + src/dom/js/jscpucfg.c | 377 + src/dom/js/jscpucfg.h | 200 + src/dom/js/jsdate.c | 2234 ++ src/dom/js/jsdate.h | 118 + src/dom/js/jsdbgapi.c | 1240 + src/dom/js/jsdbgapi.h | 345 + src/dom/js/jsdhash.c | 763 + src/dom/js/jsdhash.h | 573 + src/dom/js/jsdtoa.c | 3155 +++ src/dom/js/jsdtoa.h | 130 + src/dom/js/jsemit.c | 4471 ++++ src/dom/js/jsemit.h | 547 + src/dom/js/jsexn.c | 1081 + src/dom/js/jsexn.h | 102 + src/dom/js/jsfile.c | 2610 ++ src/dom/js/jsfile.h | 50 + src/dom/js/jsfun.c | 2059 ++ src/dom/js/jsfun.h | 151 + src/dom/js/jsgc.c | 1423 ++ src/dom/js/jsgc.h | 230 + src/dom/js/jshash.c | 479 + src/dom/js/jshash.h | 152 + src/dom/js/jsinterp.c | 4284 ++++ src/dom/js/jsinterp.h | 292 + src/dom/js/jslibmath.h | 290 + src/dom/js/jslock.c | 1241 + src/dom/js/jslock.h | 289 + src/dom/js/jslocko.asm | 59 + src/dom/js/jslog2.c | 83 + src/dom/js/jslong.c | 281 + src/dom/js/jslong.h | 437 + src/dom/js/jsmath.c | 477 + src/dom/js/jsmath.h | 55 + src/dom/js/jsnum.c | 1058 + src/dom/js/jsnum.h | 280 + src/dom/js/jsobj.c | 3900 +++ src/dom/js/jsobj.h | 464 + src/dom/js/jsopcode.c | 2660 +++ src/dom/js/jsopcode.h | 273 + src/dom/js/jsopcode.tbl | 333 + src/dom/js/jsosdep.h | 127 + src/dom/js/jsotypes.h | 211 + src/dom/js/jsparse.c | 3547 +++ src/dom/js/jsparse.h | 337 + src/dom/js/jsprf.c | 1212 + src/dom/js/jsprf.h | 148 + src/dom/js/jsprvtd.h | 174 + src/dom/js/jspubtd.h | 564 + src/dom/js/jsregexp.c | 3773 +++ src/dom/js/jsregexp.h | 168 + src/dom/js/jsscan.c | 1315 ++ src/dom/js/jsscan.h | 264 + src/dom/js/jsscope.c | 1581 ++ src/dom/js/jsscope.h | 386 + src/dom/js/jsscript.c | 1287 + src/dom/js/jsscript.h | 178 + src/dom/js/jsshell.msg | 50 + src/dom/js/jsstddef.h | 83 + src/dom/js/jsstr.c | 4502 ++++ src/dom/js/jsstr.h | 439 + src/dom/js/jstypes.h | 388 + src/dom/js/jsutil.c | 157 + src/dom/js/jsutil.h | 106 + src/dom/js/jsxdrapi.c | 690 + src/dom/js/jsxdrapi.h | 193 + src/dom/js/prmjtime.c | 646 + src/dom/js/prmjtime.h | 95 + src/dom/js/resource.h | 15 + src/dom/knut.svg | 51 + src/dom/ls.h | 940 + src/dom/ls.idl | 171 + src/dom/lsimpl.cpp | 437 + src/dom/lsimpl.cpp.orig | 671 + src/dom/lsimpl.h | 376 + src/dom/makefile.in | 17 + src/dom/meyerweb.css | 181 + src/dom/mingwenv.bat | 2 + src/dom/phoebedom.h | 86 + src/dom/prop-css.cpp | 1161 + src/dom/prop-css.txt | 1082 + src/dom/prop-css2.cpp | 1304 + src/dom/prop-svg.cpp | 735 + src/dom/prop-svg.txt | 651 + src/dom/ranges.idl | 122 + src/dom/sandb1.css | 149 + src/dom/smil.h | 2167 ++ src/dom/smil.idl | 369 + src/dom/smilimpl.cpp | 854 + src/dom/smilimpl.h | 765 + src/dom/stringstream.cpp | 161 + src/dom/stringstream.h | 126 + src/dom/stylesheets.h | 465 + src/dom/stylesheets.idl | 71 + src/dom/svg.h | 4474 ++++ src/dom/svg.idl | 1751 ++ src/dom/svgimpl.cpp | 1870 ++ src/dom/svgimpl.h | 5108 ++++ src/dom/svglsimpl.cpp | 90 + src/dom/svglsimpl.h | 217 + src/dom/svgparser.cpp | 762 + src/dom/svgparser.h | 151 + src/dom/svgtypes.h | 6889 ++++++ src/dom/testdom.cpp | 110 + src/dom/testsvg.cpp | 97 + src/dom/transforms.svg | 39 + src/dom/traversal.h | 444 + src/dom/traversal.idl | 102 + src/dom/uri.cpp | 454 + src/dom/uri.h | 186 + src/dom/uristream.cpp | 456 + src/dom/uristream.h | 207 + src/dom/uritest.cpp | 76 + src/dom/views.h | 1961 ++ src/dom/views.idl | 254 + src/dom/xmlreader.cpp | 981 + src/dom/xmlreader.h | 129 + src/dom/xpath.h | 349 + src/dom/xpath.idl | 115 + src/dom/xpathimpl.cpp | 236 + src/dom/xpathimpl.h | 263 + src/dom/xpathparser.cpp | 1910 ++ src/dom/xpathparser.h | 845 + src/dom/xpathtest.cpp | 1399 ++ src/dom/xpathtests.cpp | 1290 + src/draw-anchor.cpp | 99 + src/draw-anchor.h | 44 + src/draw-context.cpp | 664 + src/draw-context.h | 100 + src/dropper-context.cpp | 428 + src/dropper-context.h | 58 + src/dyna-draw-context.cpp | 958 + src/dyna-draw-context.h | 116 + src/enums.h | 77 + src/event-context.cpp | 1033 + src/event-context.h | 139 + src/extension/.cvsignore | 5 + src/extension/Makefile_insert | 37 + src/extension/api.cpp | 92 + src/extension/db.cpp | 239 + src/extension/db.h | 81 + src/extension/dependency.cpp | 261 + src/extension/dependency.h | 83 + src/extension/dxf2svg/GPL.txt | 340 + src/extension/dxf2svg/LGPL.txt | 504 + src/extension/dxf2svg/Makefile | 21 + src/extension/dxf2svg/README | 41 + src/extension/dxf2svg/aci2rgb.cpp | 114 + src/extension/dxf2svg/blocks.cpp | 88 + src/extension/dxf2svg/blocks.h | 38 + src/extension/dxf2svg/dxf2svg.cpp | 106 + src/extension/dxf2svg/dxf_input.inx | 16 + src/extension/dxf2svg/dxf_input_windows.inx | 17 + src/extension/dxf2svg/entities.cpp | 1031 + src/extension/dxf2svg/entities.h | 256 + src/extension/dxf2svg/entities2elements.cpp | 681 + src/extension/dxf2svg/entities2elements.h | 53 + src/extension/dxf2svg/read_dxf.cpp | 273 + src/extension/dxf2svg/read_dxf.h | 31 + src/extension/dxf2svg/tables.cpp | 211 + src/extension/dxf2svg/tables.h | 71 + src/extension/dxf2svg/tables2svg_info.cpp | 35 + src/extension/dxf2svg/tables2svg_info.h | 9 + src/extension/dxf2svg/test_dxf.cpp | 99 + src/extension/effect.cpp | 200 + src/extension/effect.h | 91 + src/extension/error-file.cpp | 109 + src/extension/error-file.h | 45 + src/extension/extension-forward.h | 34 + src/extension/extension.cpp | 637 + src/extension/extension.h | 207 + src/extension/implementation/.cvsignore | 5 + src/extension/implementation/Makefile_insert | 13 + .../implementation/implementation.cpp | 181 + src/extension/implementation/implementation.h | 127 + src/extension/implementation/makefile.in | 17 + src/extension/implementation/plugin-link.h | 68 + src/extension/implementation/plugin.cpp | 328 + src/extension/implementation/plugin.h | 121 + src/extension/implementation/script.cpp | 1053 + src/extension/implementation/script.h | 86 + src/extension/init.cpp | 243 + src/extension/init.h | 36 + src/extension/input.cpp | 261 + src/extension/input.h | 60 + src/extension/internal/.cvsignore | 5 + src/extension/internal/Makefile_insert | 42 + src/extension/internal/bluredge.cpp | 157 + src/extension/internal/bluredge.h | 43 + src/extension/internal/eps-out.cpp | 108 + src/extension/internal/eps-out.h | 47 + src/extension/internal/gdkpixbuf-input.cpp | 176 + src/extension/internal/gdkpixbuf-input.h | 31 + src/extension/internal/gimpgrad.cpp | 233 + src/extension/internal/gimpgrad.h | 49 + src/extension/internal/gnome.cpp | 443 + src/extension/internal/gnome.h | 58 + src/extension/internal/grid.cpp | 272 + src/extension/internal/grid.h | 43 + src/extension/internal/latex-pstricks-out.cpp | 128 + src/extension/internal/latex-pstricks-out.h | 49 + src/extension/internal/latex-pstricks.cpp | 362 + src/extension/internal/latex-pstricks.h | 70 + src/extension/internal/makefile.in | 17 + src/extension/internal/pov-out.cpp | 482 + src/extension/internal/pov-out.h | 52 + src/extension/internal/ps-out.cpp | 94 + src/extension/internal/ps-out.h | 45 + src/extension/internal/ps.cpp | 1264 + src/extension/internal/ps.h | 108 + src/extension/internal/svg.cpp | 248 + src/extension/internal/svg.h | 48 + src/extension/internal/svgz.cpp | 99 + src/extension/internal/svgz.h | 41 + src/extension/internal/win32.cpp | 499 + src/extension/internal/win32.h | 91 + src/extension/makefile.in | 17 + src/extension/output.cpp | 262 + src/extension/output.h | 58 + src/extension/parameter.cpp | 778 + src/extension/parameter.h | 71 + src/extension/plugin/.cvsignore | 7 + src/extension/plugin/Makefile_insert | 30 + src/extension/plugin/makefile.in | 17 + src/extension/prefdialog.cpp | 48 + src/extension/prefdialog.h | 44 + src/extension/print.cpp | 125 + src/extension/print.h | 84 + src/extension/script/.cvsignore | 3 + src/extension/script/InkscapeBinding.cpp | 199 + src/extension/script/InkscapeBinding.h | 168 + src/extension/script/InkscapeInterpreter.cpp | 93 + src/extension/script/InkscapeInterpreter.h | 68 + src/extension/script/InkscapePerl.cpp | 80 + src/extension/script/InkscapePerl.h | 73 + src/extension/script/InkscapePython.cpp | 120 + src/extension/script/InkscapePython.h | 74 + src/extension/script/InkscapeScript.cpp | 177 + src/extension/script/InkscapeScript.h | 87 + src/extension/script/Makefile.tmp | 89 + src/extension/script/Makefile_insert | 36 + src/extension/script/README.txt | 41 + src/extension/script/bindtest.cpp | 86 + src/extension/script/cpptest.cpp | 22 + src/extension/script/inkscape_perl.i | 77 + src/extension/script/inkscape_perl.pm | 178 + src/extension/script/inkscape_perl.pm.h | 187 + src/extension/script/inkscape_perl_wrap.cpp | 1334 ++ src/extension/script/inkscape_py.i | 6 + src/extension/script/inkscape_py.py | 130 + src/extension/script/inkscape_py.py.h | 139 + src/extension/script/inkscape_py_wrap.cpp | 1408 ++ src/extension/script/js/Makefile | 1471 ++ src/extension/script/js/README | 20 + src/extension/script/js/fdlibm/e_acos.c | 147 + src/extension/script/js/fdlibm/e_acosh.c | 105 + src/extension/script/js/fdlibm/e_asin.c | 156 + src/extension/script/js/fdlibm/e_atan2.c | 165 + src/extension/script/js/fdlibm/e_atanh.c | 110 + src/extension/script/js/fdlibm/e_cosh.c | 133 + src/extension/script/js/fdlibm/e_exp.c | 202 + src/extension/script/js/fdlibm/e_fmod.c | 184 + src/extension/script/js/fdlibm/e_gamma.c | 71 + src/extension/script/js/fdlibm/e_gamma_r.c | 70 + src/extension/script/js/fdlibm/e_hypot.c | 173 + src/extension/script/js/fdlibm/e_j0.c | 524 + src/extension/script/js/fdlibm/e_j1.c | 523 + src/extension/script/js/fdlibm/e_jn.c | 315 + src/extension/script/js/fdlibm/e_lgamma.c | 71 + src/extension/script/js/fdlibm/e_lgamma_r.c | 347 + src/extension/script/js/fdlibm/e_log.c | 184 + src/extension/script/js/fdlibm/e_log10.c | 134 + src/extension/script/js/fdlibm/e_pow.c | 386 + src/extension/script/js/fdlibm/e_rem_pio2.c | 221 + src/extension/script/js/fdlibm/e_remainder.c | 120 + src/extension/script/js/fdlibm/e_scalb.c | 89 + src/extension/script/js/fdlibm/e_sinh.c | 122 + src/extension/script/js/fdlibm/e_sqrt.c | 497 + src/extension/script/js/fdlibm/fdlibm.h | 273 + src/extension/script/js/fdlibm/k_cos.c | 134 + src/extension/script/js/fdlibm/k_rem_pio2.c | 354 + src/extension/script/js/fdlibm/k_sin.c | 114 + src/extension/script/js/fdlibm/k_standard.c | 785 + src/extension/script/js/fdlibm/k_tan.c | 170 + src/extension/script/js/fdlibm/s_asinh.c | 101 + src/extension/script/js/fdlibm/s_atan.c | 175 + src/extension/script/js/fdlibm/s_cbrt.c | 133 + src/extension/script/js/fdlibm/s_ceil.c | 120 + src/extension/script/js/fdlibm/s_copysign.c | 72 + src/extension/script/js/fdlibm/s_cos.c | 118 + src/extension/script/js/fdlibm/s_erf.c | 356 + src/extension/script/js/fdlibm/s_expm1.c | 267 + src/extension/script/js/fdlibm/s_fabs.c | 70 + src/extension/script/js/fdlibm/s_finite.c | 71 + src/extension/script/js/fdlibm/s_floor.c | 121 + src/extension/script/js/fdlibm/s_frexp.c | 99 + src/extension/script/js/fdlibm/s_ilogb.c | 85 + src/extension/script/js/fdlibm/s_isnan.c | 74 + src/extension/script/js/fdlibm/s_ldexp.c | 66 + .../script/js/fdlibm/s_lib_version.c | 73 + src/extension/script/js/fdlibm/s_log1p.c | 211 + src/extension/script/js/fdlibm/s_logb.c | 79 + src/extension/script/js/fdlibm/s_matherr.c | 64 + src/extension/script/js/fdlibm/s_modf.c | 132 + src/extension/script/js/fdlibm/s_nextafter.c | 124 + src/extension/script/js/fdlibm/s_rint.c | 131 + src/extension/script/js/fdlibm/s_scalbn.c | 107 + src/extension/script/js/fdlibm/s_signgam.c | 40 + .../script/js/fdlibm/s_significand.c | 68 + src/extension/script/js/fdlibm/s_sin.c | 118 + src/extension/script/js/fdlibm/s_tan.c | 112 + src/extension/script/js/fdlibm/s_tanh.c | 122 + src/extension/script/js/fdlibm/w_acos.c | 78 + src/extension/script/js/fdlibm/w_acosh.c | 78 + src/extension/script/js/fdlibm/w_asin.c | 80 + src/extension/script/js/fdlibm/w_atan2.c | 79 + src/extension/script/js/fdlibm/w_atanh.c | 81 + src/extension/script/js/fdlibm/w_cosh.c | 77 + src/extension/script/js/fdlibm/w_exp.c | 88 + src/extension/script/js/fdlibm/w_fmod.c | 78 + src/extension/script/js/fdlibm/w_gamma.c | 85 + src/extension/script/js/fdlibm/w_gamma_r.c | 81 + src/extension/script/js/fdlibm/w_hypot.c | 78 + src/extension/script/js/fdlibm/w_j0.c | 105 + src/extension/script/js/fdlibm/w_j1.c | 106 + src/extension/script/js/fdlibm/w_jn.c | 128 + src/extension/script/js/fdlibm/w_lgamma.c | 85 + src/extension/script/js/fdlibm/w_lgamma_r.c | 81 + src/extension/script/js/fdlibm/w_log.c | 78 + src/extension/script/js/fdlibm/w_log10.c | 81 + src/extension/script/js/fdlibm/w_pow.c | 99 + src/extension/script/js/fdlibm/w_remainder.c | 77 + src/extension/script/js/fdlibm/w_scalb.c | 95 + src/extension/script/js/fdlibm/w_sinh.c | 77 + src/extension/script/js/fdlibm/w_sqrt.c | 77 + src/extension/script/js/js.c | 2333 ++ src/extension/script/js/js.mak | 4025 ++++ src/extension/script/js/js.msg | 251 + src/extension/script/js/jsapi.c | 4187 ++++ src/extension/script/js/jsapi.h | 1752 ++ src/extension/script/js/jsarena.c | 565 + src/extension/script/js/jsarena.h | 302 + src/extension/script/js/jsarray.c | 1429 ++ src/extension/script/js/jsarray.h | 77 + src/extension/script/js/jsatom.c | 911 + src/extension/script/js/jsatom.h | 409 + src/extension/script/js/jsautocfg.h | 50 + src/extension/script/js/jsbit.h | 113 + src/extension/script/js/jsbool.c | 244 + src/extension/script/js/jsbool.h | 62 + src/extension/script/js/jsclist.h | 139 + src/extension/script/js/jscntxt.c | 702 + src/extension/script/js/jscntxt.h | 496 + src/extension/script/js/jscompat.h | 57 + src/extension/script/js/jsconfig.h | 489 + src/extension/script/js/jscpucfg.c | 377 + src/extension/script/js/jscpucfg.h | 200 + src/extension/script/js/jsdate.c | 2234 ++ src/extension/script/js/jsdate.h | 118 + src/extension/script/js/jsdbgapi.c | 1240 + src/extension/script/js/jsdbgapi.h | 345 + src/extension/script/js/jsdhash.c | 763 + src/extension/script/js/jsdhash.h | 573 + src/extension/script/js/jsdtoa.c | 3155 +++ src/extension/script/js/jsdtoa.h | 130 + src/extension/script/js/jsemit.c | 4471 ++++ src/extension/script/js/jsemit.h | 547 + src/extension/script/js/jsexn.c | 1081 + src/extension/script/js/jsexn.h | 102 + src/extension/script/js/jsfile.c | 2610 ++ src/extension/script/js/jsfile.h | 50 + src/extension/script/js/jsfun.c | 2059 ++ src/extension/script/js/jsfun.h | 151 + src/extension/script/js/jsgc.c | 1423 ++ src/extension/script/js/jsgc.h | 230 + src/extension/script/js/jshash.c | 479 + src/extension/script/js/jshash.h | 152 + src/extension/script/js/jsinterp.c | 4284 ++++ src/extension/script/js/jsinterp.h | 292 + src/extension/script/js/jslibmath.h | 290 + src/extension/script/js/jslock.c | 1241 + src/extension/script/js/jslock.h | 289 + src/extension/script/js/jslocko.asm | 59 + src/extension/script/js/jslog2.c | 83 + src/extension/script/js/jslong.c | 281 + src/extension/script/js/jslong.h | 437 + src/extension/script/js/jsmath.c | 477 + src/extension/script/js/jsmath.h | 55 + src/extension/script/js/jsnum.c | 1058 + src/extension/script/js/jsnum.h | 280 + src/extension/script/js/jsobj.c | 3900 +++ src/extension/script/js/jsobj.h | 464 + src/extension/script/js/jsopcode.c | 2660 +++ src/extension/script/js/jsopcode.h | 273 + src/extension/script/js/jsopcode.tbl | 333 + src/extension/script/js/jsosdep.h | 127 + src/extension/script/js/jsotypes.h | 211 + src/extension/script/js/jsparse.c | 3547 +++ src/extension/script/js/jsparse.h | 337 + src/extension/script/js/jsprf.c | 1212 + src/extension/script/js/jsprf.h | 148 + src/extension/script/js/jsprvtd.h | 174 + src/extension/script/js/jspubtd.h | 564 + src/extension/script/js/jsregexp.c | 3773 +++ src/extension/script/js/jsregexp.h | 168 + src/extension/script/js/jsscan.c | 1315 ++ src/extension/script/js/jsscan.h | 264 + src/extension/script/js/jsscope.c | 1581 ++ src/extension/script/js/jsscope.h | 386 + src/extension/script/js/jsscript.c | 1287 + src/extension/script/js/jsscript.h | 178 + src/extension/script/js/jsshell.msg | 50 + src/extension/script/js/jsstddef.h | 83 + src/extension/script/js/jsstr.c | 4502 ++++ src/extension/script/js/jsstr.h | 439 + src/extension/script/js/jstypes.h | 388 + src/extension/script/js/jsutil.c | 157 + src/extension/script/js/jsutil.h | 106 + src/extension/script/js/jsxdrapi.c | 690 + src/extension/script/js/jsxdrapi.h | 193 + src/extension/script/js/prmjtime.c | 646 + src/extension/script/js/prmjtime.h | 95 + src/extension/script/js/resource.h | 15 + src/extension/script/makefile.in | 17 + src/extension/script/quotefile.pl | 82 + src/extension/script/runme.py | 8 + src/extension/script/wrap_swig_module.sh | 27 + src/extension/system.cpp | 476 + src/extension/system.h | 44 + src/extension/timer.cpp | 214 + src/extension/timer.h | 72 + src/extract-uri-test.cpp | 56 + src/extract-uri.cpp | 40 + src/extract-uri.h | 20 + src/file.cpp | 1337 ++ src/file.h | 171 + src/fill-or-stroke.h | 9 + src/fixes.cpp | 193 + src/fontsize-expansion.cpp | 30 + src/fontsize-expansion.h | 9 + src/forward.h | 208 + src/gc-alloc.h | 89 + src/gc-anchored.cpp | 39 + src/gc-anchored.h | 185 + src/gc-core.h | 212 + src/gc-finalized.h | 155 + src/gc-managed.h | 84 + src/gc.cpp | 279 + src/geom.cpp | 172 + src/geom.h | 30 + src/gnuc-attribute.h | 11 + src/gradient-chemistry.cpp | 1133 + src/gradient-chemistry.h | 82 + src/gradient-context.cpp | 468 + src/gradient-context.h | 56 + src/gradient-drag.cpp | 1108 + src/gradient-drag.h | 143 + src/grid-snapper.cpp | 78 + src/grid-snapper.h | 46 + src/guide-snapper.cpp | 52 + src/guide-snapper.h | 52 + src/help.cpp | 59 + src/help.h | 35 + src/helper/.cvsignore | 9 + src/helper/HACKING | 35 + src/helper/Makefile_insert | 51 + src/helper/action.cpp | 228 + src/helper/action.h | 91 + src/helper/gnome-utils.cpp | 108 + src/helper/gnome-utils.h | 36 + src/helper/helper-forward.h | 35 + src/helper/makefile.in | 17 + src/helper/png-write.cpp | 205 + src/helper/png-write.h | 23 + src/helper/sp-marshal.cpp.mingw | 520 + src/helper/sp-marshal.h.mingw | 125 + src/helper/sp-marshal.list | 16 + src/helper/stlport.h | 26 + src/helper/stock-items.cpp | 267 + src/helper/stock-items.h | 20 + src/helper/unit-menu.cpp | 372 + src/helper/unit-menu.h | 59 + src/helper/units-test.cpp | 115 + src/helper/units.cpp | 260 + src/helper/units.h | 146 + src/helper/window.cpp | 47 + src/helper/window.h | 28 + src/inkjar/.cvsignore | 5 + src/inkjar/Makefile_insert | 10 + src/inkjar/jar.cpp | 541 + src/inkjar/jar.h | 151 + src/inkjar/makefile.in | 17 + src/inkscape-private.h | 62 + src/inkscape-stock.cpp | 51 + src/inkscape-stock.h | 150 + src/inkscape.cpp | 1413 ++ src/inkscape.h | 86 + src/inkscape.rc | 3 + src/inkscape_version.h.mingw | 1 + src/inkview.cpp | 491 + src/interface.cpp | 1197 + src/interface.h | 85 + src/io/.cvsignore | 5 + src/io/Makefile.tst | 47 + src/io/Makefile_insert | 29 + src/io/base64stream.cpp | 315 + src/io/base64stream.h | 122 + src/io/crystalegg.xml | 769 + src/io/doc2html.xsl | 63 + src/io/ftos.cpp | 482 + src/io/ftos.h | 54 + src/io/gzipstream.cpp | 458 + src/io/gzipstream.h | 121 + src/io/inkscapestream.cpp | 842 + src/io/inkscapestream.h | 669 + src/io/makefile.in | 17 + src/io/simple-sax.cpp | 1493 ++ src/io/simple-sax.h | 97 + src/io/streamtest.cpp | 244 + src/io/stringstream.cpp | 128 + src/io/stringstream.h | 96 + src/io/sys.cpp | 300 + src/io/sys.h | 51 + src/io/uristream.cpp | 499 + src/io/uristream.h | 173 + src/io/xsltstream.cpp | 220 + src/io/xsltstream.h | 124 + src/isnan.h | 57 + src/jabber_whiteboard/.cvsignore | 2 + src/jabber_whiteboard/Makefile_insert | 77 + src/jabber_whiteboard/buddy-list-manager.cpp | 84 + src/jabber_whiteboard/buddy-list-manager.h | 59 + src/jabber_whiteboard/callbacks.cpp | 206 + src/jabber_whiteboard/callbacks.h | 79 + src/jabber_whiteboard/chat-handler.cpp | 249 + src/jabber_whiteboard/chat-handler.h | 63 + .../connection-establishment.cpp | 307 + src/jabber_whiteboard/defines.h | 98 + src/jabber_whiteboard/deserializer.cpp | 417 + src/jabber_whiteboard/deserializer.h | 285 + src/jabber_whiteboard/empty.cpp | 14 + src/jabber_whiteboard/error-codes.h | 41 + src/jabber_whiteboard/internal-constants.cpp | 76 + src/jabber_whiteboard/internal-constants.h | 83 + .../invitation-confirm-dialog.cpp | 66 + .../invitation-confirm-dialog.h | 69 + src/jabber_whiteboard/jabber-handlers.cpp | 65 + src/jabber_whiteboard/jabber-handlers.h | 86 + src/jabber_whiteboard/makefile.in | 17 + src/jabber_whiteboard/message-aggregator.cpp | 64 + src/jabber_whiteboard/message-aggregator.h | 135 + src/jabber_whiteboard/message-contexts.cpp | 134 + src/jabber_whiteboard/message-contexts.h | 39 + src/jabber_whiteboard/message-handler.cpp | 456 + src/jabber_whiteboard/message-handler.h | 88 + src/jabber_whiteboard/message-node.h | 134 + src/jabber_whiteboard/message-processors.cpp | 330 + src/jabber_whiteboard/message-processors.h | 176 + src/jabber_whiteboard/message-queue.cpp | 138 + src/jabber_whiteboard/message-queue.h | 177 + src/jabber_whiteboard/message-tags.cpp | 67 + src/jabber_whiteboard/message-tags.h | 139 + src/jabber_whiteboard/message-utilities.cpp | 452 + src/jabber_whiteboard/message-utilities.h | 84 + .../node-tracker-event-tracker.cpp | 56 + .../node-tracker-event-tracker.h | 66 + src/jabber_whiteboard/node-tracker-observer.h | 119 + src/jabber_whiteboard/node-tracker.cpp | 368 + src/jabber_whiteboard/node-tracker.h | 300 + src/jabber_whiteboard/node-utilities.cpp | 119 + src/jabber_whiteboard/node-utilities.h | 61 + src/jabber_whiteboard/pedrodom.cpp | 784 + src/jabber_whiteboard/pedrodom.h | 308 + src/jabber_whiteboard/pedroxmpp.cpp | 4786 ++++ src/jabber_whiteboard/pedroxmpp.h | 1023 + src/jabber_whiteboard/serializer.cpp | 304 + src/jabber_whiteboard/serializer.h | 118 + src/jabber_whiteboard/session-file-player.cpp | 176 + src/jabber_whiteboard/session-file-player.h | 99 + .../session-file-selector.cpp | 90 + src/jabber_whiteboard/session-file-selector.h | 61 + src/jabber_whiteboard/session-file.cpp | 140 + src/jabber_whiteboard/session-file.h | 78 + src/jabber_whiteboard/session-manager.cpp | 1118 + src/jabber_whiteboard/session-manager.h | 568 + src/jabber_whiteboard/tracker-node.h | 94 + src/jabber_whiteboard/typedefs.h | 159 + src/jabber_whiteboard/undo-stack-observer.cpp | 181 + src/jabber_whiteboard/undo-stack-observer.h | 75 + src/knot-enums.h | 58 + src/knot-holder-entity.h | 62 + src/knot.cpp | 926 + src/knot.h | 127 + src/knotholder.cpp | 229 + src/knotholder.h | 79 + src/layer-fns.cpp | 186 + src/layer-fns.h | 37 + src/libavoid/.cvsignore | 3 + src/libavoid/Makefile_insert | 33 + src/libavoid/README | 5 + src/libavoid/connector.cpp | 408 + src/libavoid/connector.h | 93 + src/libavoid/debug.h | 61 + src/libavoid/geometry.cpp | 260 + src/libavoid/geometry.h | 75 + src/libavoid/geomtypes.h | 61 + src/libavoid/graph.cpp | 986 + src/libavoid/graph.h | 127 + src/libavoid/incremental.cpp | 139 + src/libavoid/incremental.h | 39 + src/libavoid/libavoid.h | 40 + src/libavoid/makefile.in | 17 + src/libavoid/makepath.cpp | 462 + src/libavoid/makepath.h | 42 + src/libavoid/polyutil.cpp | 86 + src/libavoid/polyutil.h | 41 + src/libavoid/shape.cpp | 176 + src/libavoid/shape.h | 73 + src/libavoid/static.cpp | 76 + src/libavoid/static.h | 38 + src/libavoid/timer.cpp | 168 + src/libavoid/timer.h | 92 + src/libavoid/vertices.cpp | 438 + src/libavoid/vertices.h | 124 + src/libavoid/visibility.cpp | 653 + src/libavoid/visibility.h | 57 + src/libcroco/.cvsignore | 3 + src/libcroco/Makefile_insert | 64 + src/libcroco/README | 11 + src/libcroco/cr-additional-sel.c | 468 + src/libcroco/cr-additional-sel.h | 112 + src/libcroco/cr-attr-sel.c | 221 + src/libcroco/cr-attr-sel.h | 74 + src/libcroco/cr-cascade.c | 197 + src/libcroco/cr-cascade.h | 74 + src/libcroco/cr-declaration.c | 775 + src/libcroco/cr-declaration.h | 136 + src/libcroco/cr-doc-handler.c | 252 + src/libcroco/cr-doc-handler.h | 298 + src/libcroco/cr-enc-handler.c | 177 + src/libcroco/cr-enc-handler.h | 96 + src/libcroco/cr-fonts.c | 761 + src/libcroco/cr-fonts.h | 314 + src/libcroco/cr-input.c | 1112 + src/libcroco/cr-input.h | 174 + src/libcroco/cr-libxml-node-iface.c | 81 + src/libcroco/cr-libxml-node-iface.h | 14 + src/libcroco/cr-node-iface.h | 35 + src/libcroco/cr-num.c | 299 + src/libcroco/cr-num.h | 127 + src/libcroco/cr-om-parser.c | 1107 + src/libcroco/cr-om-parser.h | 98 + src/libcroco/cr-parser.c | 4408 ++++ src/libcroco/cr-parser.h | 128 + src/libcroco/cr-parsing-location.c | 153 + src/libcroco/cr-parsing-location.h | 70 + src/libcroco/cr-prop-list.c | 360 + src/libcroco/cr-prop-list.h | 80 + src/libcroco/cr-pseudo.c | 153 + src/libcroco/cr-pseudo.h | 64 + src/libcroco/cr-rgb.c | 621 + src/libcroco/cr-rgb.h | 94 + src/libcroco/cr-sel-eng.c | 1541 ++ src/libcroco/cr-sel-eng.h | 112 + src/libcroco/cr-selector.c | 277 + src/libcroco/cr-selector.h | 95 + src/libcroco/cr-simple-sel.c | 308 + src/libcroco/cr-simple-sel.h | 130 + src/libcroco/cr-statement.c | 2608 ++ src/libcroco/cr-statement.h | 440 + src/libcroco/cr-string.c | 168 + src/libcroco/cr-string.h | 76 + src/libcroco/cr-style.c | 2851 +++ src/libcroco/cr-style.h | 339 + src/libcroco/cr-stylesheet.c | 178 + src/libcroco/cr-stylesheet.h | 102 + src/libcroco/cr-term.c | 791 + src/libcroco/cr-term.h | 190 + src/libcroco/cr-tknzr.c | 2760 +++ src/libcroco/cr-tknzr.h | 115 + src/libcroco/cr-token.c | 635 + src/libcroco/cr-token.h | 212 + src/libcroco/cr-utils.c | 1343 ++ src/libcroco/cr-utils.h | 249 + src/libcroco/libcroco.h | 48 + src/libcroco/makefile.in | 17 + src/libnr/.cvsignore | 13 + src/libnr/Makefile_insert | 167 + src/libnr/have_mmx.S | 47 + src/libnr/in-svg-plane-test.cpp | 58 + src/libnr/in-svg-plane-test.h | 81 + src/libnr/in-svg-plane.h | 33 + src/libnr/libnr.def | 89 + src/libnr/makefile.in | 17 + src/libnr/n-art-bpath.h | 61 + src/libnr/nr-blit.cpp | 300 + src/libnr/nr-blit.h | 32 + src/libnr/nr-compose-transform.cpp | 360 + src/libnr/nr-compose-transform.h | 43 + src/libnr/nr-compose.cpp | 986 + src/libnr/nr-compose.h | 69 + src/libnr/nr-convex-hull-ops.h | 29 + src/libnr/nr-convex-hull.h | 49 + src/libnr/nr-coord.h | 29 + src/libnr/nr-dim2.h | 22 + src/libnr/nr-forward.h | 42 + src/libnr/nr-gradient.cpp | 317 + src/libnr/nr-gradient.h | 47 + src/libnr/nr-i-coord.h | 25 + src/libnr/nr-macros.h | 71 + src/libnr/nr-matrix-div.cpp | 22 + src/libnr/nr-matrix-div.h | 21 + src/libnr/nr-matrix-fns.cpp | 54 + src/libnr/nr-matrix-fns.h | 50 + src/libnr/nr-matrix-ops.h | 45 + src/libnr/nr-matrix-rotate-ops.cpp | 18 + src/libnr/nr-matrix-rotate-ops.h | 20 + src/libnr/nr-matrix-scale-ops.cpp | 37 + src/libnr/nr-matrix-scale-ops.h | 14 + src/libnr/nr-matrix-test.cpp | 197 + src/libnr/nr-matrix-test.h | 221 + src/libnr/nr-matrix-translate-ops.cpp | 26 + src/libnr/nr-matrix-translate-ops.h | 36 + src/libnr/nr-matrix.cpp | 607 + src/libnr/nr-matrix.h | 453 + src/libnr/nr-maybe.h | 140 + src/libnr/nr-object.cpp | 295 + src/libnr/nr-object.h | 157 + src/libnr/nr-path-code.h | 28 + src/libnr/nr-path.cpp | 461 + src/libnr/nr-path.h | 62 + src/libnr/nr-pixblock-line.cpp | 92 + src/libnr/nr-pixblock-line.h | 28 + src/libnr/nr-pixblock-pattern.cpp | 126 + src/libnr/nr-pixblock-pattern.h | 28 + src/libnr/nr-pixblock-pixel.cpp | 230 + src/libnr/nr-pixblock-pixel.h | 28 + src/libnr/nr-pixblock.cpp | 411 + src/libnr/nr-pixblock.h | 95 + src/libnr/nr-pixops.h | 46 + src/libnr/nr-point-fns-test.cpp | 107 + src/libnr/nr-point-fns-test.h | 141 + src/libnr/nr-point-fns.cpp | 74 + src/libnr/nr-point-fns.h | 104 + src/libnr/nr-point-l.h | 95 + src/libnr/nr-point-matrix-ops.h | 47 + src/libnr/nr-point-ops.h | 88 + src/libnr/nr-point.h | 159 + src/libnr/nr-rect-l.cpp | 22 + src/libnr/nr-rect-l.h | 131 + src/libnr/nr-rect-ops.h | 51 + src/libnr/nr-rect.cpp | 233 + src/libnr/nr-rect.h | 255 + src/libnr/nr-render.h | 25 + src/libnr/nr-rotate-fns-test.cpp | 43 + src/libnr/nr-rotate-fns-test.h | 54 + src/libnr/nr-rotate-fns.cpp | 66 + src/libnr/nr-rotate-fns.h | 29 + src/libnr/nr-rotate-matrix-ops.cpp | 19 + src/libnr/nr-rotate-matrix-ops.h | 21 + src/libnr/nr-rotate-ops.h | 43 + src/libnr/nr-rotate-test.cpp | 89 + src/libnr/nr-rotate-test.h | 112 + src/libnr/nr-rotate.h | 66 + src/libnr/nr-scale-matrix-ops.cpp | 26 + src/libnr/nr-scale-matrix-ops.h | 13 + src/libnr/nr-scale-ops.h | 40 + src/libnr/nr-scale-test.cpp | 71 + src/libnr/nr-scale-test.h | 92 + src/libnr/nr-scale-translate-ops.cpp | 19 + src/libnr/nr-scale-translate-ops.h | 20 + src/libnr/nr-scale.h | 50 + src/libnr/nr-svp-private.h | 30 + src/libnr/nr-svp-render.cpp | 615 + src/libnr/nr-svp-render.h | 30 + src/libnr/nr-svp.cpp | 180 + src/libnr/nr-svp.h | 65 + src/libnr/nr-translate-matrix-ops.cpp | 27 + src/libnr/nr-translate-matrix-ops.h | 22 + src/libnr/nr-translate-ops.h | 43 + src/libnr/nr-translate-rotate-ops.cpp | 20 + src/libnr/nr-translate-rotate-ops.h | 21 + src/libnr/nr-translate-scale-ops.cpp | 25 + src/libnr/nr-translate-scale-ops.h | 20 + src/libnr/nr-translate-test.cpp | 65 + src/libnr/nr-translate-test.h | 87 + src/libnr/nr-translate.h | 34 + src/libnr/nr-types-test.cpp | 105 + src/libnr/nr-types-test.h | 145 + src/libnr/nr-types.cpp | 68 + src/libnr/nr-types.h | 47 + src/libnr/nr-values.cpp | 23 + src/libnr/nr-values.h | 45 + src/libnr/nr_config.h.mingw | 12 + src/libnr/nr_config.h.win32 | 14 + src/libnr/nr_mmx_R8G8B8A8_P_EMPTY_A8_RGBAP.S | 125 + .../nr_mmx_R8G8B8A8_P_R8G8B8A8_P_A8_RGBAP.S | 231 + ...G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_TRANSFORM.S | 414 + src/libnr/nr_mmx_R8G8B8_R8G8B8_R8G8B8A8_P.S | 227 + src/libnr/testnr.cpp | 92 + src/libnrtype/.cvsignore | 5 + src/libnrtype/FontFactory.cpp | 630 + src/libnrtype/FontFactory.h | 112 + src/libnrtype/FontInstance.cpp | 763 + src/libnrtype/Layout-TNG-Compute.cpp | 1514 ++ src/libnrtype/Layout-TNG-Input.cpp | 270 + src/libnrtype/Layout-TNG-OutIter.cpp | 994 + src/libnrtype/Layout-TNG-Output.cpp | 469 + src/libnrtype/Layout-TNG-Scanline-Maker.h | 169 + src/libnrtype/Layout-TNG-Scanline-Makers.cpp | 189 + src/libnrtype/Layout-TNG.cpp | 45 + src/libnrtype/Layout-TNG.h | 1029 + src/libnrtype/Makefile_insert | 42 + src/libnrtype/RasterFont.cpp | 431 + src/libnrtype/RasterFont.h | 66 + src/libnrtype/TextWrapper.cpp | 937 + src/libnrtype/TextWrapper.h | 139 + src/libnrtype/boundary-type.h | 31 + src/libnrtype/font-glyph.h | 29 + src/libnrtype/font-instance.h | 121 + src/libnrtype/font-style-to-pos.cpp | 120 + src/libnrtype/font-style-to-pos.h | 20 + src/libnrtype/font-style.h | 38 + src/libnrtype/libnrtype.def | 59 + src/libnrtype/makefile.in | 17 + src/libnrtype/nr-type-pos-def.cpp | 268 + src/libnrtype/nr-type-pos-def.h | 102 + src/libnrtype/nr-type-primitives.cpp | 167 + src/libnrtype/nr-type-primitives.h | 50 + src/libnrtype/nrtype-forward.h | 23 + src/libnrtype/one-box.h | 28 + src/libnrtype/one-glyph.h | 46 + src/libnrtype/one-para.h | 20 + src/libnrtype/raster-glyph.h | 49 + src/libnrtype/raster-position.h | 46 + src/libnrtype/text-boundary.h | 49 + src/line-snapper.cpp | 80 + src/line-snapper.h | 44 + src/livarot/.cvsignore | 7 + src/livarot/AVL.cpp | 965 + src/livarot/AVL.h | 95 + src/livarot/AlphaLigne.cpp | 304 + src/livarot/AlphaLigne.h | 90 + src/livarot/BitLigne.cpp | 172 + src/livarot/BitLigne.h | 66 + src/livarot/Livarot.h | 34 + src/livarot/LivarotDefs.h | 170 + src/livarot/Makefile_insert | 45 + src/livarot/MyMath.h | 281 + src/livarot/MySeg.cpp | 867 + src/livarot/MySeg.h | 147 + src/livarot/Path.cpp | 908 + src/livarot/Path.h | 387 + src/livarot/PathConversion.cpp | 1575 ++ src/livarot/PathCutting.cpp | 1487 ++ src/livarot/PathOutline.cpp | 1493 ++ src/livarot/PathSimplify.cpp | 1397 ++ src/livarot/PathStroke.cpp | 756 + src/livarot/Shape.cpp | 2282 ++ src/livarot/Shape.h | 562 + src/livarot/ShapeDraw.cpp | 103 + src/livarot/ShapeMisc.cpp | 1228 + src/livarot/ShapeRaster.cpp | 2009 ++ src/livarot/ShapeSweep.cpp | 3327 +++ src/livarot/float-line.cpp | 918 + src/livarot/float-line.h | 136 + src/livarot/int-line.cpp | 1066 + src/livarot/int-line.h | 107 + src/livarot/livarot-forward.h | 28 + src/livarot/makefile.in | 17 + src/livarot/path-description.cpp | 171 + src/livarot/path-description.h | 165 + src/livarot/sweep-event-queue.h | 54 + src/livarot/sweep-event.cpp | 275 + src/livarot/sweep-event.h | 45 + src/livarot/sweep-tree-list.cpp | 47 + src/livarot/sweep-tree-list.h | 37 + src/livarot/sweep-tree.cpp | 558 + src/livarot/sweep-tree.h | 82 + src/macros.h | 54 + src/main.cpp | 1543 ++ src/make.dep | 19683 ++++++++++++++++ src/make.exclude | 80 + src/make.files | 1339 ++ src/make.ofiles | 1307 + src/makedef.pl | 61 + src/marker-status.cpp | 23 + src/marker-status.h | 19 + src/media.cpp | 27 + src/media.h | 24 + src/memeq.h | 25 + src/menus-skeleton.h | 252 + src/message-context.cpp | 94 + src/message-context.h | 118 + src/message-stack.cpp | 160 + src/message-stack.h | 177 + src/message.h | 49 + src/mkdep.pl | 565 + src/mkfiles.pl | 226 + src/mod360-test.cpp | 70 + src/mod360.cpp | 29 + src/mod360.h | 17 + src/modifier-fns.h | 64 + src/node-context.cpp | 964 + src/node-context.h | 69 + src/nodepath.cpp | 3675 +++ src/nodepath.h | 266 + src/object-edit.cpp | 1074 + src/object-edit.h | 29 + src/object-hierarchy.cpp | 213 + src/object-hierarchy.h | 119 + src/object-snapper.cpp | 176 + src/object-snapper.h | 68 + src/object-ui.cpp | 351 + src/object-ui.h | 32 + src/path-chemistry.cpp | 369 + src/path-chemistry.h | 35 + src/path-prefix.h | 83 + src/pen-context.cpp | 1084 + src/pen-context.h | 62 + src/pencil-context.cpp | 591 + src/pencil-context.h | 52 + src/pixmaps/cursor-arc.xpm | 38 + src/pixmaps/cursor-arrow.xpm | 38 + src/pixmaps/cursor-calligraphy.xpm | 38 + src/pixmaps/cursor-connector.xpm | 39 + src/pixmaps/cursor-dropper.xpm | 38 + src/pixmaps/cursor-ellipse.xpm | 38 + src/pixmaps/cursor-gradient.xpm | 38 + src/pixmaps/cursor-node-d.xpm | 38 + src/pixmaps/cursor-node-m.xpm | 38 + src/pixmaps/cursor-node.xpm | 38 + src/pixmaps/cursor-pen.xpm | 38 + src/pixmaps/cursor-pencil.xpm | 38 + src/pixmaps/cursor-rect.xpm | 38 + src/pixmaps/cursor-select-d.xpm | 38 + src/pixmaps/cursor-select-m.xpm | 38 + src/pixmaps/cursor-spiral.xpm | 38 + src/pixmaps/cursor-star.xpm | 38 + src/pixmaps/cursor-text-insert.xpm | 38 + src/pixmaps/cursor-text.xpm | 38 + src/pixmaps/cursor-zoom-out.xpm | 38 + src/pixmaps/cursor-zoom.xpm | 38 + src/pixmaps/handles.xpm | 260 + src/plugin.def | 7 + src/preferences-skeleton.h | 266 + src/preferences.cpp | 92 + src/preferences.h | 44 + src/prefix.cpp | 427 + src/prefix.h | 122 + src/prefs-utils.cpp | 186 + src/prefs-utils.h | 42 + src/print.cpp | 228 + src/print.h | 58 + src/proofs | 332 + src/rect-context.cpp | 501 + src/rect-context.h | 51 + src/registrytool.cpp | 211 + src/registrytool.h | 56 + src/remove-last.h | 31 + src/removeoverlap/.cvsignore | 5 + src/removeoverlap/Makefile_insert | 31 + src/removeoverlap/block.cpp | 279 + src/removeoverlap/block.h | 59 + src/removeoverlap/blocks.cpp | 190 + src/removeoverlap/blocks.h | 49 + src/removeoverlap/constraint.cpp | 29 + src/removeoverlap/constraint.h | 52 + src/removeoverlap/generate-constraints.cpp | 302 + src/removeoverlap/generate-constraints.h | 78 + src/removeoverlap/makefile.in | 17 + src/removeoverlap/pairingheap/.cvsignore | 5 + src/removeoverlap/pairingheap/PairingHeap.cpp | 309 + src/removeoverlap/pairingheap/PairingHeap.h | 111 + src/removeoverlap/pairingheap/dsexceptions.h | 9 + src/removeoverlap/placement_SolveVPSC.cpp | 130 + src/removeoverlap/placement_SolveVPSC.h | 53 + .../remove_rectangle_overlap-test.cpp | 308 + .../remove_rectangle_overlap.cpp | 109 + src/removeoverlap/remove_rectangle_overlap.h | 21 + src/removeoverlap/removeoverlap.cpp | 80 + src/removeoverlap/removeoverlap.h | 17 + src/removeoverlap/solve_VPSC.cpp | 265 + src/removeoverlap/solve_VPSC.h | 41 + src/removeoverlap/variable.cpp | 20 + src/removeoverlap/variable.h | 46 + src/require-config.h | 3 + src/round-test.cpp | 91 + src/round.h | 32 + src/rubberband.cpp | 82 + src/rubberband.h | 64 + src/satisfied-guide-cns.cpp | 33 + src/satisfied-guide-cns.h | 25 + src/selcue.cpp | 153 + src/selcue.h | 64 + src/select-context.cpp | 823 + src/select-context.h | 52 + src/selection-chemistry.cpp | 2217 ++ src/selection-chemistry.h | 108 + src/selection-describer.cpp | 121 + src/selection-describer.h | 46 + src/selection.cpp | 450 + src/selection.h | 347 + src/seltrans-handles.cpp | 42 + src/seltrans-handles.h | 57 + src/seltrans.cpp | 1332 ++ src/seltrans.h | 151 + src/shortcuts-default-xml.cpp | 243 + src/shortcuts.cpp | 195 + src/shortcuts.h | 39 + src/slideshow.cpp | 105 + src/slideshow.h | 31 + src/snap.cpp | 406 + src/snap.h | 114 + src/snapped-point.cpp | 61 + src/snapped-point.h | 56 + src/snapper.cpp | 180 + src/snapper.h | 113 + src/sp-anchor.cpp | 220 + src/sp-anchor.h | 34 + src/sp-animation.cpp | 290 + src/sp-animation.h | 75 + src/sp-clippath.cpp | 408 + src/sp-clippath.h | 61 + src/sp-conn-end-pair.cpp | 275 + src/sp-conn-end-pair.h | 91 + src/sp-conn-end.cpp | 298 + src/sp-conn-end.h | 51 + src/sp-cursor.cpp | 115 + src/sp-cursor.h | 20 + src/sp-defs.cpp | 172 + src/sp-defs.h | 44 + src/sp-ellipse.cpp | 863 + src/sp-ellipse.h | 105 + src/sp-flowdiv.cpp | 730 + src/sp-flowdiv.h | 84 + src/sp-flowregion.cpp | 544 + src/sp-flowregion.h | 50 + src/sp-flowtext.cpp | 681 + src/sp-flowtext.h | 56 + src/sp-gradient-fns.h | 76 + src/sp-gradient-reference.cpp | 22 + src/sp-gradient-reference.h | 31 + src/sp-gradient-spread.h | 22 + src/sp-gradient-test.cpp | 139 + src/sp-gradient-units.h | 21 + src/sp-gradient-vector.h | 42 + src/sp-gradient.cpp | 1809 ++ src/sp-gradient.h | 95 + src/sp-guide-attachment.h | 43 + src/sp-guide-constraint.h | 44 + src/sp-guide.cpp | 326 + src/sp-guide.h | 64 + src/sp-image.cpp | 1200 + src/sp-image.h | 60 + src/sp-item-group.cpp | 699 + src/sp-item-group.h | 61 + src/sp-item-notify-moveto.cpp | 76 + src/sp-item-notify-moveto.h | 22 + src/sp-item-rm-unsatisfied-cns.cpp | 40 + src/sp-item-rm-unsatisfied-cns.h | 19 + src/sp-item-transform.cpp | 148 + src/sp-item-transform.h | 29 + src/sp-item-update-cns.cpp | 45 + src/sp-item-update-cns.h | 19 + src/sp-item.cpp | 1320 ++ src/sp-item.h | 246 + src/sp-line.cpp | 227 + src/sp-line.h | 44 + src/sp-linear-gradient-fns.h | 40 + src/sp-linear-gradient.h | 36 + src/sp-marker-loc.h | 29 + src/sp-marker.cpp | 639 + src/sp-marker.h | 93 + src/sp-mask.cpp | 375 + src/sp-mask.h | 63 + src/sp-metadata.cpp | 223 + src/sp-metadata.h | 39 + src/sp-metric.h | 26 + src/sp-metrics.cpp | 108 + src/sp-metrics.h | 21 + src/sp-namedview.cpp | 989 + src/sp-namedview.h | 136 + src/sp-object-group.cpp | 132 + src/sp-object-group.h | 33 + src/sp-object-repr.cpp | 208 + src/sp-object-repr.h | 41 + src/sp-object.cpp | 1548 ++ src/sp-object.h | 539 + src/sp-offset.cpp | 1238 + src/sp-offset.h | 108 + src/sp-paint-server.cpp | 163 + src/sp-paint-server.h | 66 + src/sp-path.cpp | 325 + src/sp-path.h | 46 + src/sp-pattern.cpp | 979 + src/sp-pattern.h | 98 + src/sp-polygon.cpp | 225 + src/sp-polygon.h | 33 + src/sp-polyline.cpp | 177 + src/sp-polyline.h | 28 + src/sp-radial-gradient-fns.h | 40 + src/sp-radial-gradient.h | 39 + src/sp-rect.cpp | 561 + src/sp-rect.h | 65 + src/sp-root.cpp | 678 + src/sp-root.h | 81 + src/sp-shape.cpp | 919 + src/sp-shape.h | 62 + src/sp-skeleton.cpp | 215 + src/sp-skeleton.h | 48 + src/sp-spiral.cpp | 617 + src/sp-spiral.h | 91 + src/sp-star.cpp | 544 + src/sp-star.h | 59 + src/sp-stop-fns.h | 17 + src/sp-stop.h | 56 + src/sp-string.cpp | 178 + src/sp-string.h | 30 + src/sp-style-elem-test.cpp | 118 + src/sp-style-elem.cpp | 407 + src/sp-style-elem.h | 36 + src/sp-symbol.cpp | 467 + src/sp-symbol.h | 53 + src/sp-text.cpp | 913 + src/sp-text.h | 88 + src/sp-textpath.h | 51 + src/sp-tspan.cpp | 572 + src/sp-tspan.h | 49 + src/sp-use-reference.cpp | 248 + src/sp-use-reference.h | 76 + src/sp-use.cpp | 712 + src/sp-use.h | 64 + src/spiral-context.cpp | 473 + src/spiral-context.h | 51 + src/splivarot.cpp | 1607 ++ src/splivarot.h | 58 + src/star-context.cpp | 484 + src/star-context.h | 57 + src/streams-gzip.cpp | 149 + src/streams-gzip.h | 66 + src/streams-handles.cpp | 119 + src/streams-handles.h | 103 + src/streams-jar.cpp | 146 + src/streams-jar.h | 69 + src/streams-zlib.cpp | 223 + src/streams-zlib.h | 97 + src/streq.h | 25 + src/strneq.h | 25 + src/style-test.cpp | 770 + src/style.cpp | 3703 +++ src/style.h | 509 + src/svg-profile.h | 287 + src/svg-view-widget.cpp | 249 + src/svg-view-widget.h | 62 + src/svg-view.cpp | 230 + src/svg-view.h | 75 + src/svg/.cvsignore | 5 + src/svg/HACKING | 7 + src/svg/Makefile_insert | 58 + src/svg/css-ostringstream-test.h | 73 + src/svg/css-ostringstream.cpp | 76 + src/svg/css-ostringstream.h | 80 + src/svg/ftos.cpp | 485 + src/svg/ftos.h | 54 + src/svg/gnome-canvas-bpath-util.cpp | 179 + src/svg/gnome-canvas-bpath-util.h | 48 + src/svg/itos.cpp | 77 + src/svg/makefile.in | 17 + src/svg/round.cpp | 47 + src/svg/sp-svg.def | 26 + src/svg/stringstream-test.h | 70 + src/svg/stringstream.cpp | 69 + src/svg/stringstream.h | 76 + src/svg/strip-trailing-zeros.cpp | 42 + src/svg/strip-trailing-zeros.h | 20 + src/svg/svg-affine.cpp | 265 + src/svg/svg-color.cpp | 324 + src/svg/svg-length.cpp | 515 + src/svg/svg-length.h | 66 + src/svg/svg-path.cpp | 710 + src/svg/svg.h | 85 + src/text-chemistry.cpp | 390 + src/text-chemistry.h | 34 + src/text-context.cpp | 1537 ++ src/text-context.h | 89 + src/text-editing.cpp | 1660 ++ src/text-editing.h | 52 + src/text-tag-attributes.h | 145 + src/tools-switch.cpp | 248 + src/tools-switch.h | 52 + src/trace/.cvsignore | 4 + src/trace/Makefile_insert | 34 + src/trace/filterset.cpp | 959 + src/trace/filterset.h | 82 + src/trace/imagemap-gdk.cpp | 206 + src/trace/imagemap-gdk.h | 46 + src/trace/imagemap.cpp | 331 + src/trace/imagemap.h | 292 + src/trace/makefile.in | 17 + src/trace/potrace/.cvsignore | 3 + src/trace/potrace/auxiliary.h | 60 + src/trace/potrace/bitmap.h | 97 + src/trace/potrace/curve.cpp | 107 + src/trace/potrace/curve.h | 74 + src/trace/potrace/decompose.cpp | 481 + src/trace/potrace/decompose.h | 17 + src/trace/potrace/greymap.cpp | 889 + src/trace/potrace/greymap.h | 58 + src/trace/potrace/inkscape-potrace.cpp | 712 + src/trace/potrace/inkscape-potrace.h | 231 + src/trace/potrace/lists.h | 286 + src/trace/potrace/potracelib.cpp | 109 + src/trace/potrace/potracelib.h | 131 + src/trace/potrace/progress.h | 79 + src/trace/potrace/render.cpp | 242 + src/trace/potrace/render.h | 28 + src/trace/potrace/trace.cpp | 1231 + src/trace/potrace/trace.h | 15 + src/trace/trace.cpp | 322 + src/trace/trace.h | 246 + src/traits/.cvsignore | 2 + src/traits/Makefile_insert | 5 + src/traits/copy.h | 48 + src/traits/function.h | 122 + src/traits/list-copy.h | 45 + src/traits/makefile.in | 17 + src/traits/reference.h | 49 + src/ui/.cvsignore | 3 + src/ui/Makefile_insert | 18 + src/ui/dialog/.cvsignore | 3 + src/ui/dialog/Makefile_insert | 63 + src/ui/dialog/aboutbox.cpp | 682 + src/ui/dialog/aboutbox.h | 50 + src/ui/dialog/align-and-distribute.cpp | 1051 + src/ui/dialog/align-and-distribute.h | 120 + src/ui/dialog/dialog-manager.cpp | 191 + src/ui/dialog/dialog-manager.h | 72 + src/ui/dialog/dialog.cpp | 359 + src/ui/dialog/dialog.h | 94 + src/ui/dialog/document-metadata.cpp | 306 + src/ui/dialog/document-metadata.h | 84 + src/ui/dialog/document-properties.cpp | 503 + src/ui/dialog/document-properties.h | 103 + src/ui/dialog/export.cpp | 58 + src/ui/dialog/export.h | 59 + src/ui/dialog/extension-editor.cpp | 48 + src/ui/dialog/extension-editor.h | 52 + src/ui/dialog/fill-and-stroke.cpp | 62 + src/ui/dialog/fill-and-stroke.h | 61 + src/ui/dialog/find.cpp | 58 + src/ui/dialog/find.h | 59 + src/ui/dialog/inkscape-preferences.cpp | 525 + src/ui/dialog/inkscape-preferences.h | 140 + src/ui/dialog/layer-editor.cpp | 48 + src/ui/dialog/layer-editor.h | 52 + src/ui/dialog/makefile.in | 17 + src/ui/dialog/memory.cpp | 244 + src/ui/dialog/memory.h | 54 + src/ui/dialog/messages.cpp | 185 + src/ui/dialog/messages.h | 98 + src/ui/dialog/scriptdialog.cpp | 248 + src/ui/dialog/scriptdialog.h | 65 + src/ui/dialog/session-player.cpp | 229 + src/ui/dialog/session-player.h | 124 + src/ui/dialog/text-properties.cpp | 59 + src/ui/dialog/text-properties.h | 60 + src/ui/dialog/tracedialog.cpp | 562 + src/ui/dialog/tracedialog.h | 63 + src/ui/dialog/transformation.cpp | 955 + src/ui/dialog/transformation.h | 239 + src/ui/dialog/tree-editor.cpp | 53 + src/ui/dialog/tree-editor.h | 61 + src/ui/dialog/whiteboard-connect.cpp | 192 + src/ui/dialog/whiteboard-connect.h | 88 + src/ui/dialog/whiteboard-sharewithchat.cpp | 147 + src/ui/dialog/whiteboard-sharewithchat.h | 93 + src/ui/dialog/whiteboard-sharewithuser.cpp | 214 + src/ui/dialog/whiteboard-sharewithuser.h | 110 + src/ui/dialog/xml-editor.cpp | 48 + src/ui/dialog/xml-editor.h | 52 + src/ui/icons.cpp | 696 + src/ui/icons.h | 36 + src/ui/makefile.in | 17 + src/ui/previewable.h | 62 + src/ui/previewfillable.h | 49 + src/ui/previewholder.cpp | 153 + src/ui/previewholder.h | 60 + src/ui/stock-items.cpp | 215 + src/ui/stock-items.h | 37 + src/ui/stock.cpp | 187 + src/ui/stock.h | 192 + src/ui/view/.cvsignore | 3 + src/ui/view/Makefile_insert | 27 + src/ui/view/desktop-affine.cpp | 0 src/ui/view/desktop-affine.h | 0 src/ui/view/desktop-events.cpp | 0 src/ui/view/desktop-events.h | 0 src/ui/view/desktop-handles.cpp | 0 src/ui/view/desktop-handles.h | 0 src/ui/view/desktop-style.cpp | 0 src/ui/view/desktop-style.h | 0 src/ui/view/desktop.cpp | 0 src/ui/view/desktop.h | 0 src/ui/view/edit-widget-interface.h | 134 + src/ui/view/edit-widget.cpp | 1701 ++ src/ui/view/edit-widget.h | 211 + src/ui/view/edit.cpp | 28 + src/ui/view/edit.h | 27 + src/ui/view/makefile.in | 17 + src/ui/view/view-widget.cpp | 135 + src/ui/view/view-widget.h | 97 + src/ui/view/view.cpp | 163 + src/ui/view/view.h | 148 + src/ui/widget/.cvsignore | 3 + src/ui/widget/Makefile_insert | 62 + src/ui/widget/button.cpp | 51 + src/ui/widget/button.h | 56 + src/ui/widget/color-picker.cpp | 167 + src/ui/widget/color-picker.h | 65 + src/ui/widget/color-preview.cpp | 122 + src/ui/widget/color-preview.h | 50 + src/ui/widget/combo-text.cpp | 92 + src/ui/widget/combo-text.h | 66 + src/ui/widget/entity-entry.cpp | 161 + src/ui/widget/entity-entry.h | 84 + src/ui/widget/handlebox.cpp | 48 + src/ui/widget/handlebox.h | 50 + src/ui/widget/icon-widget.cpp | 165 + src/ui/widget/icon-widget.h | 63 + src/ui/widget/imageicon.cpp | 442 + src/ui/widget/imageicon.h | 138 + src/ui/widget/labelled.cpp | 102 + src/ui/widget/labelled.h | 65 + src/ui/widget/licensor.cpp | 146 + src/ui/widget/licensor.h | 59 + src/ui/widget/makefile.in | 17 + src/ui/widget/notebook-page.cpp | 49 + src/ui/widget/notebook-page.h | 50 + src/ui/widget/page-sizer.cpp | 357 + src/ui/widget/page-sizer.h | 67 + src/ui/widget/panel.cpp | 248 + src/ui/widget/panel.h | 80 + src/ui/widget/preferences-widget.cpp | 278 + src/ui/widget/preferences-widget.h | 117 + src/ui/widget/registered-widget.cpp | 409 + src/ui/widget/registered-widget.h | 175 + src/ui/widget/registry.cpp | 58 + src/ui/widget/registry.h | 54 + src/ui/widget/ruler.cpp | 197 + src/ui/widget/ruler.h | 88 + src/ui/widget/scalar-unit.cpp | 252 + src/ui/widget/scalar-unit.h | 85 + src/ui/widget/scalar.cpp | 217 + src/ui/widget/scalar.h | 86 + src/ui/widget/selected-style.cpp | 977 + src/ui/widget/selected-style.h | 212 + src/ui/widget/style-swatch.cpp | 244 + src/ui/widget/style-swatch.h | 88 + src/ui/widget/svg-canvas.cpp | 92 + src/ui/widget/svg-canvas.h | 56 + src/ui/widget/tolerance-slider.cpp | 142 + src/ui/widget/tolerance-slider.h | 61 + src/ui/widget/toolbox.cpp | 269 + src/ui/widget/toolbox.h | 73 + src/ui/widget/unit-menu.cpp | 181 + src/ui/widget/unit-menu.h | 70 + src/ui/widget/zoom-status.cpp | 127 + src/ui/widget/zoom-status.h | 61 + src/undo-stack-observer.h | 68 + src/unit-constants.h | 39 + src/uri-references.cpp | 165 + src/uri-references.h | 138 + src/uri.cpp | 263 + src/uri.h | 91 + src/utest/.cvsignore | 4 + src/utest/Makefile_insert | 5 + src/utest/makefile.in | 17 + src/utest/test-1ary-cases.h | 43 + src/utest/test-2ary-cases.h | 44 + src/utest/utest.h | 134 + src/util/.cvsignore | 5 + src/util/Makefile_insert | 25 + src/util/compose.hpp | 393 + src/util/filter-list.h | 65 + src/util/forward-pointer-iterator.h | 120 + src/util/glib-list-iterators.h | 238 + src/util/list-container-test.cpp | 204 + src/util/list-container.h | 352 + src/util/list.h | 407 + src/util/makefile.in | 17 + src/util/map-list.h | 68 + src/util/reverse-list.h | 68 + src/util/shared-c-string-ptr.cpp | 50 + src/util/shared-c-string-ptr.h | 77 + src/util/tuple.h | 182 + src/util/ucompose.hpp | 438 + src/util/units.cpp | 344 + src/util/units.h | 88 + src/verbs.cpp | 2254 ++ src/verbs.h | 375 + src/version.cpp | 64 + src/version.h | 58 + src/widgets/.cvsignore | 5 + src/widgets/Makefile_insert | 75 + src/widgets/button.cpp | 324 + src/widgets/button.h | 69 + src/widgets/dash-selector.cpp | 379 + src/widgets/dash-selector.h | 48 + src/widgets/desktop-widget.cpp | 1270 + src/widgets/desktop-widget.h | 201 + src/widgets/font-selector.cpp | 722 + src/widgets/font-selector.h | 67 + src/widgets/gradient-image.cpp | 277 + src/widgets/gradient-image.h | 46 + src/widgets/gradient-selector.cpp | 342 + src/widgets/gradient-selector.h | 79 + src/widgets/gradient-toolbar.cpp | 665 + src/widgets/gradient-toolbar.h | 21 + src/widgets/gradient-vector.cpp | 1115 + src/widgets/gradient-vector.h | 61 + src/widgets/icon.cpp | 924 + src/widgets/icon.h | 51 + src/widgets/layer-selector.cpp | 588 + src/widgets/layer-selector.h | 110 + src/widgets/makefile.in | 17 + src/widgets/paint-selector.cpp | 963 + src/widgets/paint-selector.h | 110 + src/widgets/ruler.cpp | 663 + src/widgets/ruler.h | 84 + src/widgets/select-toolbar.cpp | 540 + src/widgets/select-toolbar.h | 34 + src/widgets/shrink-wrap-button.cpp | 55 + src/widgets/shrink-wrap-button.h | 35 + src/widgets/sp-color-gtkselector.cpp | 170 + src/widgets/sp-color-gtkselector.h | 55 + src/widgets/sp-color-notebook.cpp | 625 + src/widgets/sp-color-notebook.h | 105 + src/widgets/sp-color-preview.cpp | 196 + src/widgets/sp-color-preview.h | 47 + src/widgets/sp-color-scales.cpp | 741 + src/widgets/sp-color-scales.h | 108 + src/widgets/sp-color-selector.cpp | 351 + src/widgets/sp-color-selector.h | 95 + src/widgets/sp-color-slider.cpp | 687 + src/widgets/sp-color-slider.h | 67 + src/widgets/sp-color-wheel-selector.cpp | 295 + src/widgets/sp-color-wheel-selector.h | 90 + src/widgets/sp-color-wheel.cpp | 1163 + src/widgets/sp-color-wheel.h | 80 + src/widgets/sp-widget.cpp | 260 + src/widgets/sp-widget.h | 52 + src/widgets/sp-xmlview-attr-list.cpp | 181 + src/widgets/sp-xmlview-attr-list.h | 54 + src/widgets/sp-xmlview-content.cpp | 165 + src/widgets/sp-xmlview-content.h | 53 + src/widgets/sp-xmlview-tree.cpp | 424 + src/widgets/sp-xmlview-tree.h | 55 + src/widgets/spinbutton-events.cpp | 137 + src/widgets/spinbutton-events.h | 30 + src/widgets/spw-utilities.cpp | 255 + src/widgets/spw-utilities.h | 56 + src/widgets/toolbox.cpp | 3028 +++ src/widgets/toolbox.h | 57 + src/widgets/widget-sizes.h | 52 + src/winmain.cpp | 34 + src/xml/.cvsignore | 10 + src/xml/Makefile_insert | 86 + src/xml/attribute-record.h | 39 + src/xml/comment-node.h | 52 + src/xml/composite-node-observer.cpp | 308 + src/xml/composite-node-observer.h | 86 + src/xml/croco-node-iface.cpp | 68 + src/xml/croco-node-iface.h | 12 + src/xml/document.h | 50 + src/xml/element-node.h | 49 + src/xml/event-fns.h | 28 + src/xml/event.cpp | 489 + src/xml/event.h | 150 + src/xml/invalid-operation-exception.h | 47 + src/xml/log-builder.cpp | 78 + src/xml/log-builder.h | 66 + src/xml/makefile.in | 17 + src/xml/node-event-vector.h | 47 + src/xml/node-fns.cpp | 103 + src/xml/node-fns.h | 44 + src/xml/node-iterators.h | 61 + src/xml/node-observer.h | 68 + src/xml/node.h | 131 + src/xml/quote-test.cpp | 82 + src/xml/quote-test.h | 31 + src/xml/quote.cpp | 86 + src/xml/quote.h | 7 + src/xml/repr-action-test.cpp | 77 + src/xml/repr-action-test.h | 31 + src/xml/repr-css.cpp | 261 + src/xml/repr-io.cpp | 786 + src/xml/repr-sorting.cpp | 53 + src/xml/repr-sorting.h | 11 + src/xml/repr-util.cpp | 553 + src/xml/repr.cpp | 107 + src/xml/repr.h | 261 + src/xml/session.h | 56 + src/xml/simple-document.cpp | 40 + src/xml/simple-document.h | 57 + src/xml/simple-node.cpp | 731 + src/xml/simple-node.h | 167 + src/xml/simple-session.cpp | 122 + src/xml/simple-session.h | 84 + src/xml/sp-css-attr.h | 33 + src/xml/text-node.h | 52 + src/xml/transaction-logger.h | 52 + src/zoom-context.cpp | 241 + src/zoom-context.h | 35 + tools-version.sh | 38 + utf8-to-roff | 300 + 2342 files changed, 1108845 insertions(+) create mode 100644 .cvsignore create mode 100644 AUTHORS create mode 100644 COPYING create mode 100644 COPYING.LIB create mode 100644 ChangeLog create mode 100644 HACKING.de.txt create mode 100644 HACKING.fr.txt create mode 100644 HACKING.it.txt create mode 100644 HACKING.txt create mode 100644 INSTALL create mode 100644 Info.plist.in create mode 100644 Makefile.am create mode 100644 Makefile.mingw create mode 100644 Makefile.mingw.common create mode 100644 Makefile.mingw.common.old create mode 100644 Makefile.mingw.old create mode 100644 NEWS create mode 100644 README create mode 100755 README.ca.txt create mode 100644 README.de.txt create mode 100644 README.es.txt create mode 100644 README.fr.txt create mode 100644 README.it.txt create mode 100644 TRANSLATORS create mode 100755 autogen.sh create mode 100644 config.h.mingw create mode 100644 configure.ac create mode 100644 cxxtest/COPYING create mode 100644 cxxtest/README create mode 100644 cxxtest/TODO create mode 100644 cxxtest/Versions create mode 100644 cxxtest/cxxtest.spec create mode 100644 cxxtest/cxxtest/Descriptions.cpp create mode 100644 cxxtest/cxxtest/Descriptions.h create mode 100644 cxxtest/cxxtest/DummyDescriptions.cpp create mode 100644 cxxtest/cxxtest/DummyDescriptions.h create mode 100644 cxxtest/cxxtest/ErrorFormatter.h create mode 100644 cxxtest/cxxtest/ErrorPrinter.h create mode 100644 cxxtest/cxxtest/Flags.h create mode 100644 cxxtest/cxxtest/GlobalFixture.cpp create mode 100644 cxxtest/cxxtest/GlobalFixture.h create mode 100644 cxxtest/cxxtest/Gui.h create mode 100644 cxxtest/cxxtest/LinkedList.cpp create mode 100644 cxxtest/cxxtest/LinkedList.h create mode 100644 cxxtest/cxxtest/Mock.h create mode 100644 cxxtest/cxxtest/ParenPrinter.h create mode 100644 cxxtest/cxxtest/QtGui.h create mode 100644 cxxtest/cxxtest/RealDescriptions.cpp create mode 100644 cxxtest/cxxtest/RealDescriptions.h create mode 100644 cxxtest/cxxtest/Root.cpp create mode 100644 cxxtest/cxxtest/SelfTest.h create mode 100644 cxxtest/cxxtest/StdHeaders.h create mode 100644 cxxtest/cxxtest/StdValueTraits.h create mode 100644 cxxtest/cxxtest/StdioFilePrinter.h create mode 100644 cxxtest/cxxtest/StdioPrinter.h create mode 100644 cxxtest/cxxtest/TeeListener.h create mode 100644 cxxtest/cxxtest/TestListener.h create mode 100644 cxxtest/cxxtest/TestRunner.h create mode 100644 cxxtest/cxxtest/TestSuite.cpp create mode 100644 cxxtest/cxxtest/TestSuite.h create mode 100644 cxxtest/cxxtest/TestTracker.cpp create mode 100644 cxxtest/cxxtest/TestTracker.h create mode 100644 cxxtest/cxxtest/ValueTraits.cpp create mode 100644 cxxtest/cxxtest/ValueTraits.h create mode 100644 cxxtest/cxxtest/Win32Gui.h create mode 100644 cxxtest/cxxtest/X11Gui.h create mode 100644 cxxtest/cxxtest/YesNoRunner.h create mode 100755 cxxtest/cxxtestgen.pl create mode 100755 cxxtest/cxxtestgen.py create mode 100644 cxxtest/docs/convert.pl create mode 100644 cxxtest/docs/guide.html create mode 100644 cxxtest/docs/index.html create mode 100644 cxxtest/docs/qt.png create mode 100644 cxxtest/docs/qt2.png create mode 100644 cxxtest/docs/win32.png create mode 100644 cxxtest/docs/x11.png create mode 100644 cxxtest/sample/Construct create mode 100644 cxxtest/sample/CreatedTest.h create mode 100644 cxxtest/sample/DeltaTest.h create mode 100644 cxxtest/sample/EnumTraits.h create mode 100644 cxxtest/sample/ExceptionTest.h create mode 100644 cxxtest/sample/FixtureTest.h create mode 100755 cxxtest/sample/Makefile.PL create mode 100644 cxxtest/sample/Makefile.bcc32 create mode 100644 cxxtest/sample/Makefile.msvc create mode 100644 cxxtest/sample/Makefile.unix create mode 100644 cxxtest/sample/MessageTest.h create mode 100644 cxxtest/sample/SimpleTest.h create mode 100644 cxxtest/sample/TraitsTest.h create mode 100644 cxxtest/sample/aborter.tpl create mode 100644 cxxtest/sample/file_printer.tpl create mode 100644 cxxtest/sample/gui/GreenYellowRed.h create mode 100644 cxxtest/sample/mock/Dice.cpp create mode 100644 cxxtest/sample/mock/Dice.h create mode 100644 cxxtest/sample/mock/Makefile create mode 100644 cxxtest/sample/mock/MockStdlib.h create mode 100644 cxxtest/sample/mock/T/stdlib.h create mode 100644 cxxtest/sample/mock/TestDice.h create mode 100644 cxxtest/sample/mock/mock_stdlib.cpp create mode 100644 cxxtest/sample/mock/real_stdlib.cpp create mode 100644 cxxtest/sample/mock/roll.cpp create mode 100644 cxxtest/sample/msvc/CxxTest_1_Run.dsp create mode 100644 cxxtest/sample/msvc/CxxTest_2_Build.dsp create mode 100644 cxxtest/sample/msvc/CxxTest_3_Generate.dsp create mode 100644 cxxtest/sample/msvc/CxxTest_Workspace.dsw create mode 100644 cxxtest/sample/msvc/FixFiles.bat create mode 100644 cxxtest/sample/msvc/Makefile create mode 100644 cxxtest/sample/msvc/ReadMe.txt create mode 100644 cxxtest/sample/only.tpl create mode 100644 cxxtest/sample/parts/Makefile.unix create mode 100644 cxxtest/sample/winddk/Makefile create mode 100644 cxxtest/sample/winddk/Makefile.inc create mode 100644 cxxtest/sample/winddk/RunTests.tpl create mode 100644 cxxtest/sample/winddk/SOURCES create mode 100644 cxxtest/sample/yes_no_runner.cpp create mode 100644 debian/.cvsignore create mode 100644 debian/changelog create mode 100644 debian/compat create mode 100644 debian/control create mode 100644 debian/copyright create mode 100644 debian/dirs create mode 100644 debian/docs create mode 100644 debian/inkscape.applications create mode 100644 debian/inkscape.menu create mode 100644 debian/inkscape.xpm create mode 100644 debian/mime create mode 100755 debian/rules create mode 100755 delautogen.sh create mode 100755 distro create mode 100644 doc/.cvsignore create mode 100644 doc/API create mode 100644 doc/ChangeLog_archive.txt create mode 100644 doc/Makefile.am create mode 100644 doc/NewAppArchitecture/01-title.svg create mode 100644 doc/NewAppArchitecture/02-outline.svg create mode 100644 doc/NewAppArchitecture/03-current.svg create mode 100644 doc/NewAppArchitecture/04-current-main.svg create mode 100644 doc/NewAppArchitecture/05-current-objects.svg create mode 100644 doc/NewAppArchitecture/06-current-desktop-view.svg create mode 100644 doc/NewAppArchitecture/07-current-problems.svg create mode 100644 doc/NewAppArchitecture/08-inkscape-gtkmm.svg create mode 100644 doc/NewAppArchitecture/09-future-capabilities.svg create mode 100644 doc/NewAppArchitecture/10-future-main.svg create mode 100644 doc/NewAppArchitecture/11-future-ink-app.svg create mode 100644 doc/NewAppArchitecture/12-future-run-modes.svg create mode 100644 doc/NewAppArchitecture/13-future-ink-app-editor.svg create mode 100644 doc/NewAppArchitecture/14-evolving.svg create mode 100644 doc/README.document create mode 100644 doc/WISHLIST create mode 100644 doc/architecture.svg create mode 100644 doc/architecture.txt create mode 100644 doc/class-hierarchy.dia create mode 100644 doc/coordinates.txt create mode 100644 doc/extension_system.txt create mode 100644 doc/extension_system.xml create mode 100644 doc/fonts.txt create mode 100644 doc/inkscape-shadow.README create mode 100644 doc/inkscape-uml.dia create mode 100644 doc/keys-html.xsl create mode 100644 doc/keys-svg.xsl create mode 100644 doc/keys.README create mode 100644 doc/keys.fr.html create mode 100644 doc/keys.fr.xml create mode 100644 doc/keys.html create mode 100644 doc/keys.xml create mode 100644 doc/spsvgview.txt create mode 100755 fix-roff-punct create mode 100644 inkscape.desktop.in create mode 100644 inkscape.fr.pod create mode 100644 inkscape.ico create mode 100644 inkscape.nsi create mode 100644 inkscape.png create mode 100644 inkscape.pod create mode 100644 inkscape.spec.in create mode 100644 inkscape16.ico create mode 100644 inkscape32-16.ico create mode 100644 inkscape32.ico create mode 100644 inkscape32x16col.ico create mode 100644 inkscape64.ico create mode 100644 inkview.1.in create mode 100644 libgc.supp create mode 100644 m4/Makefile.am create mode 100644 m4/codeset.m4 create mode 100644 m4/gettext.m4 create mode 100644 m4/glibc21.m4 create mode 100644 m4/iconv.m4 create mode 100644 m4/isc-posix.m4 create mode 100644 m4/lcmessage.m4 create mode 100644 m4/progtest.m4 create mode 100755 mingwenv.bat create mode 100755 mkinstalldirs create mode 100644 packaging/autopackage/.cvsignore create mode 100644 packaging/autopackage/default.apspec.in create mode 100644 packaging/inkscape.16.png.bz2 create mode 100644 packaging/inkscape.32.png.bz2 create mode 100644 packaging/inkscape.48.png.bz2 create mode 100644 packaging/macosx/Resources/EPS.icns create mode 100644 packaging/macosx/Resources/EPSI.icns create mode 100644 packaging/macosx/Resources/Inkscape.icns create mode 100644 packaging/macosx/Resources/MenuBar.nib/classes.nib create mode 100644 packaging/macosx/Resources/MenuBar.nib/info.nib create mode 100644 packaging/macosx/Resources/MenuBar.nib/objects.xib create mode 100644 packaging/macosx/Resources/ProgressWindow.nib/classes.nib create mode 100644 packaging/macosx/Resources/ProgressWindow.nib/info.nib create mode 100644 packaging/macosx/Resources/ProgressWindow.nib/objects.xib create mode 100644 packaging/macosx/Resources/SVG_plain.icns create mode 100755 packaging/macosx/Resources/bin/getdisplay.sh create mode 100755 packaging/macosx/Resources/bin/inkscape create mode 100644 packaging/macosx/Resources/inkscape_svg.icns create mode 100755 packaging/macosx/Resources/openDoc create mode 100644 packaging/macosx/Resources/postscript.icns create mode 100755 packaging/macosx/Resources/script create mode 100644 packaging/macosx/ScriptExec/English.lproj/InfoPlist.strings create mode 100644 packaging/macosx/ScriptExec/English.lproj/main.nib/classes.nib create mode 100644 packaging/macosx/ScriptExec/English.lproj/main.nib/info.nib create mode 100644 packaging/macosx/ScriptExec/English.lproj/main.nib/objects.xib create mode 100644 packaging/macosx/ScriptExec/Info.plist create mode 100644 packaging/macosx/ScriptExec/MenuBar.nib/classes.nib create mode 100644 packaging/macosx/ScriptExec/MenuBar.nib/info.nib create mode 100644 packaging/macosx/ScriptExec/MenuBar.nib/objects.xib create mode 100644 packaging/macosx/ScriptExec/ScriptExec.xcode/project.pbxproj create mode 100644 packaging/macosx/ScriptExec/ScriptExec.xcode/sveinbjornt.pbxuser create mode 100644 packaging/macosx/ScriptExec/ScriptExec.xcode/voisine.pbxuser create mode 100644 packaging/macosx/ScriptExec/ScriptExec_Prefix.pch create mode 100644 packaging/macosx/ScriptExec/main.c create mode 100755 packaging/macosx/ScriptExec/openDoc create mode 100755 packaging/macosx/ScriptExec/script create mode 100644 packaging/macosx/ScriptExec/version.plist create mode 100644 packaging/osx-app.sh create mode 100644 packaging/win32/english.nsh create mode 100644 packaging/win32/german.nsh create mode 100644 packaging/win32/header.bmp create mode 100644 packaging/win32/inkscape.nsi create mode 100644 packaging/win32/inkscape.nsi.uninstall create mode 100644 po/.cvsignore create mode 100644 po/ChangeLog create mode 100644 po/Makefile.mingw create mode 100644 po/Makevars create mode 100644 po/POTFILES.in create mode 100644 po/am.po create mode 100644 po/az.po create mode 100644 po/bad.po.test create mode 100644 po/bad.po.test.exp create mode 100644 po/be.po create mode 100644 po/ca.po create mode 100755 po/check-markup create mode 100644 po/cs.po create mode 100644 po/da.po create mode 100644 po/de.po create mode 100644 po/el.po create mode 100644 po/es.po create mode 100644 po/es_MX.po create mode 100644 po/et.po create mode 100644 po/eu.po create mode 100644 po/fr.po create mode 100644 po/ga.po create mode 100644 po/gl.po create mode 100644 po/hu.po create mode 100644 po/it.po create mode 100644 po/ja.po create mode 100755 po/mk.po create mode 100644 po/nb.po create mode 100644 po/nl.po create mode 100644 po/nn.po create mode 100644 po/pa.po create mode 100644 po/pl.po create mode 100644 po/pt.po create mode 100644 po/pt_BR.po create mode 100644 po/ru.po create mode 100644 po/sk.po create mode 100644 po/sl.po create mode 100644 po/sr.po create mode 100644 po/sr@Latn.po create mode 100644 po/sv.po create mode 100644 po/tr.po create mode 100644 po/uk.po create mode 100644 po/zh_CN.po create mode 100644 share/.cvsignore create mode 100644 share/Makefile.am create mode 100644 share/README create mode 100644 share/clipart/.cvsignore create mode 100644 share/clipart/Makefile.am create mode 100644 share/clipart/README create mode 100644 share/clipart/README-ribbon.txt create mode 100644 share/clipart/inkscape.logo.svg create mode 100644 share/clipart/orav.svg create mode 100644 share/clipart/ribbon.svg create mode 100644 share/clipart/tux.png create mode 100644 share/clipart/tux.svg create mode 100644 share/examples/.cvsignore create mode 100644 share/examples/Makefile.am create mode 100644 share/examples/README create mode 100644 share/examples/art-nouveau-P3.svg create mode 100644 share/examples/data_uri.svg create mode 100644 share/examples/eastern-motive-P4G.svg create mode 100644 share/examples/flow-go.svg create mode 100644 share/examples/flowsample.svg create mode 100644 share/examples/gradient.svg create mode 100644 share/examples/i18n.svg create mode 100644 share/examples/istest.pov create mode 100644 share/examples/markers.svg create mode 100644 share/examples/stars.svgz create mode 100644 share/examples/tesselation-P3.svg create mode 100644 share/examples/text-on-path.svg create mode 100644 share/examples/tiger.svgz create mode 100644 share/extensions/.cvsignore create mode 100644 share/extensions/Makefile.am create mode 100644 share/extensions/README create mode 100644 share/extensions/SpSVG.pm create mode 100644 share/extensions/addnodes.inx create mode 100644 share/extensions/addnodes.py create mode 100644 share/extensions/ai_input.inx create mode 100644 share/extensions/ai_output.inx create mode 100755 share/extensions/bezmisc.py create mode 100644 share/extensions/bluredge.inx create mode 100755 share/extensions/cubicsuperpath.py create mode 100644 share/extensions/dia.inx create mode 100755 share/extensions/dia2svg.sh create mode 100644 share/extensions/dots.inx create mode 100755 share/extensions/dots.py create mode 100644 share/extensions/dropshadow.inx create mode 100644 share/extensions/dxf_input.inx create mode 100644 share/extensions/dxf_output.inx create mode 100755 share/extensions/embed_raster_in_svg.pl create mode 100644 share/extensions/embedimage.inx create mode 100644 share/extensions/embedimage.py create mode 100644 share/extensions/eps_input.inx create mode 100644 share/extensions/epsi_output.inx create mode 100644 share/extensions/extractimage.inx create mode 100644 share/extensions/extractimage.py create mode 100755 share/extensions/ffgeom.py create mode 100644 share/extensions/ffmet.inx create mode 100644 share/extensions/ffms.inx create mode 100755 share/extensions/ffproc.py create mode 100755 share/extensions/ffscale.py create mode 100644 share/extensions/ffset.inx create mode 100644 share/extensions/ffss.inx create mode 100755 share/extensions/fretfind.py create mode 100644 share/extensions/gimpgrad.inx create mode 100644 share/extensions/grid.inx create mode 100644 share/extensions/handles.inx create mode 100755 share/extensions/handles.py create mode 100644 share/extensions/ill2svg.pl create mode 100755 share/extensions/inkex.py create mode 100755 share/extensions/inkscape-shadow-white.sh create mode 100755 share/extensions/inkscape-shadow.sh create mode 100644 share/extensions/interp.inx create mode 100755 share/extensions/interp.py create mode 100644 share/extensions/kochify.inx create mode 100755 share/extensions/kochify.py create mode 100644 share/extensions/kochify_load.inx create mode 100755 share/extensions/kochify_load.py create mode 100644 share/extensions/lindenmayer.inx create mode 100755 share/extensions/lindenmayer.py create mode 100644 share/extensions/motion.inx create mode 100755 share/extensions/motion.py create mode 100644 share/extensions/pdf_output.inx create mode 100644 share/extensions/pdf_output_via_gs_on_win32.inx create mode 100644 share/extensions/ps2dxf.sh create mode 100755 share/extensions/ps2epsi.sh create mode 100644 share/extensions/ps2pdf.cmd create mode 100755 share/extensions/ps2pdf.sh create mode 100644 share/extensions/ps_input.inx create mode 100755 share/extensions/pturtle.py create mode 100644 share/extensions/radiusrand.inx create mode 100755 share/extensions/radiusrand.py create mode 100644 share/extensions/randompnt.inx create mode 100644 share/extensions/randompos.inx create mode 100644 share/extensions/rtree.inx create mode 100755 share/extensions/rtree.py create mode 100755 share/extensions/simplepath.py create mode 100755 share/extensions/simplestyle.py create mode 100755 share/extensions/sk2svg.sh create mode 100644 share/extensions/sk_input.inx create mode 100644 share/extensions/straightseg.inx create mode 100755 share/extensions/straightseg.py create mode 100644 share/extensions/summersnight.inx create mode 100755 share/extensions/summersnight.py create mode 100644 share/extensions/svg_and_media_zip_output.inx create mode 100644 share/extensions/svg_and_media_zip_output.py create mode 100644 share/extensions/svg_dropshadow create mode 100644 share/extensions/svgz_input.inx create mode 100644 share/extensions/svgz_output.inx create mode 100644 share/extensions/txt2svg.inx create mode 100755 share/extensions/txt2svg.pl create mode 100644 share/extensions/wavy.inx create mode 100755 share/extensions/wavy.py create mode 100644 share/extensions/whirl.inx create mode 100644 share/extensions/whirl.py create mode 100644 share/extensions/wmf_input.inx create mode 100644 share/fonts/.cvsignore create mode 100644 share/fonts/Makefile.am create mode 100644 share/fonts/README create mode 100644 share/gradients/.cvsignore create mode 100644 share/gradients/Makefile.am create mode 100644 share/gradients/README create mode 100644 share/icons/.cvsignore create mode 100644 share/icons/David_icons.svg create mode 100644 share/icons/Makefile.am create mode 100644 share/icons/README create mode 100644 share/icons/README.David_icons create mode 100644 share/icons/README.crispy_icons create mode 100644 share/icons/README.icon_themes create mode 100644 share/icons/crispy_icons.svg create mode 100644 share/icons/icons.svg create mode 100644 share/icons/inkscape.svg create mode 100644 share/keyboards/.cvsignore create mode 100644 share/keyboards/Makefile.am create mode 100644 share/keyboards/README create mode 100644 share/markers/.cvsignore create mode 100644 share/markers/Makefile.am create mode 100644 share/markers/markers.svg create mode 100644 share/palettes/.cvsignore create mode 100644 share/palettes/Makefile.am create mode 100644 share/palettes/README create mode 100644 share/palettes/Tango-Palette.gpl create mode 100644 share/palettes/svg.gpl create mode 100644 share/palettes/webhex.gpl create mode 100644 share/palettes/websafe22.gpl create mode 100644 share/patterns/.cvsignore create mode 100644 share/patterns/Makefile.am create mode 100644 share/patterns/README create mode 100644 share/screens/.cvsignore create mode 100644 share/screens/Makefile.am create mode 100644 share/screens/README create mode 100644 share/screens/about.svg create mode 100644 share/screens/keys.fr.svg create mode 100644 share/screens/keys.sl.svg create mode 100644 share/screens/keys.svg create mode 100644 share/templates/.cvsignore create mode 100644 share/templates/A4.svg create mode 100644 share/templates/A4_landscape.svg create mode 100644 share/templates/CD_cover_300dpi.svg create mode 100644 share/templates/Letter.svg create mode 100644 share/templates/Letter_landscape.svg create mode 100644 share/templates/Makefile.am create mode 100644 share/templates/README create mode 100644 share/templates/black_opaque.svg create mode 100644 share/templates/business_card_85x54mm.svg create mode 100644 share/templates/business_card_90x50mm.svg create mode 100644 share/templates/default.cs.svg create mode 100644 share/templates/default.de.svg create mode 100644 share/templates/default.es.svg create mode 100644 share/templates/default.fr.svg create mode 100644 share/templates/default.hu.svg create mode 100644 share/templates/default.it.svg create mode 100644 share/templates/default.pl.svg create mode 100644 share/templates/default.svg create mode 100644 share/templates/default_mm.svg create mode 100644 share/templates/default_pt.svg create mode 100644 share/templates/desktop_1024x768.svg create mode 100644 share/templates/desktop_1600x1200.svg create mode 100644 share/templates/desktop_640x480.svg create mode 100644 share/templates/desktop_800x600.svg create mode 100644 share/templates/icon_16x16.svg create mode 100644 share/templates/icon_32x32.svg create mode 100644 share/templates/icon_48x48.svg create mode 100644 share/templates/icon_64x64.svg create mode 100644 share/templates/no_borders.svg create mode 100644 share/templates/no_layers.svg create mode 100644 share/templates/web_banner_468x60.svg create mode 100644 share/templates/web_banner_728x90.svg create mode 100644 share/templates/white_opaque.svg create mode 100644 share/tutorials/.cvsignore create mode 100644 share/tutorials/Makefile.am create mode 100644 share/tutorials/README create mode 100644 share/tutorials/gpl-2.svg create mode 100644 share/tutorials/making_markers.svg create mode 100644 share/tutorials/oldguitar.jpg create mode 100644 share/tutorials/potrace-de.png create mode 100644 share/tutorials/potrace-fr.png create mode 100644 share/tutorials/potrace.png create mode 100644 share/tutorials/tutorial-advanced.es.svg create mode 100644 share/tutorials/tutorial-advanced.fr.svg create mode 100644 share/tutorials/tutorial-advanced.ja.svg create mode 100644 share/tutorials/tutorial-advanced.sl.svg create mode 100644 share/tutorials/tutorial-advanced.svg create mode 100644 share/tutorials/tutorial-basic.ca.svg create mode 100644 share/tutorials/tutorial-basic.de.svg create mode 100644 share/tutorials/tutorial-basic.es.svg create mode 100644 share/tutorials/tutorial-basic.fr.svg create mode 100644 share/tutorials/tutorial-basic.ja.svg create mode 100644 share/tutorials/tutorial-basic.nn.svg create mode 100644 share/tutorials/tutorial-basic.ru.svg create mode 100644 share/tutorials/tutorial-basic.sl.svg create mode 100644 share/tutorials/tutorial-basic.svg create mode 100644 share/tutorials/tutorial-calligraphy.es.svg create mode 100644 share/tutorials/tutorial-calligraphy.fr.svg create mode 100644 share/tutorials/tutorial-calligraphy.sl.svg create mode 100644 share/tutorials/tutorial-calligraphy.svg create mode 100644 share/tutorials/tutorial-elements.es.svg create mode 100644 share/tutorials/tutorial-elements.fr.svg create mode 100644 share/tutorials/tutorial-elements.sl.svg create mode 100755 share/tutorials/tutorial-elements.svg create mode 100644 share/tutorials/tutorial-shapes.ca.svg create mode 100644 share/tutorials/tutorial-shapes.es.svg create mode 100644 share/tutorials/tutorial-shapes.fr.svg create mode 100644 share/tutorials/tutorial-shapes.ja.svg create mode 100644 share/tutorials/tutorial-shapes.sl.svg create mode 100644 share/tutorials/tutorial-shapes.svg create mode 100644 share/tutorials/tutorial-tips.es.svg create mode 100644 share/tutorials/tutorial-tips.fr.svg create mode 100644 share/tutorials/tutorial-tips.sl.svg create mode 100644 share/tutorials/tutorial-tips.svg create mode 100644 share/tutorials/tutorial-tracing.de.svg create mode 100644 share/tutorials/tutorial-tracing.es.svg create mode 100644 share/tutorials/tutorial-tracing.fr.svg create mode 100644 share/tutorials/tutorial-tracing.sl.svg create mode 100644 share/tutorials/tutorial-tracing.svg create mode 100644 share/tutorials/tux.png create mode 100644 share/ui/.cvsignore create mode 100644 share/ui/Makefile.am create mode 100644 share/ui/keybindings.rc create mode 100644 share/ui/menus-bars.xml create mode 100644 share/ui/toolbox.xml create mode 100644 share/ui/units.txt create mode 100644 share/ui/units.xml create mode 100644 src/.cvsignore create mode 100644 src/Doxyfile create mode 100644 src/Makefile.am create mode 100644 src/Makefile.mingw create mode 100644 src/Makefile.mingw.old create mode 100644 src/Makefile_insert create mode 100644 src/algorithms/.cvsignore create mode 100644 src/algorithms/Makefile_insert create mode 100644 src/algorithms/find-if-before.h create mode 100644 src/algorithms/find-last-if.h create mode 100644 src/algorithms/longest-common-suffix.h create mode 100644 src/algorithms/makefile.in create mode 100644 src/application/.cvsignore create mode 100644 src/application/Makefile_insert create mode 100644 src/application/app-prototype.cpp create mode 100644 src/application/app-prototype.h create mode 100644 src/application/application.cpp create mode 100644 src/application/application.h create mode 100644 src/application/editor.cpp create mode 100644 src/application/editor.h create mode 100644 src/application/makefile.in create mode 100644 src/approx-equal.h create mode 100644 src/arc-context.cpp create mode 100644 src/arc-context.h create mode 100644 src/attributes-test.cpp create mode 100644 src/attributes.cpp create mode 100644 src/attributes.h create mode 100644 src/bad-uri-exception.h create mode 100644 src/brokenimage.xpm create mode 100755 src/check-header-compile.in create mode 100644 src/color-rgba.h create mode 100644 src/color.cpp create mode 100644 src/color.h create mode 100644 src/composite-undo-stack-observer.cpp create mode 100644 src/composite-undo-stack-observer.h create mode 100644 src/conn-avoid-ref.cpp create mode 100644 src/conn-avoid-ref.h create mode 100644 src/connector-context.cpp create mode 100644 src/connector-context.h create mode 100644 src/context-fns.cpp create mode 100644 src/context-fns.h create mode 100644 src/debug/.cvsignore create mode 100644 src/debug/Makefile_insert create mode 100644 src/debug/event-tracker.h create mode 100644 src/debug/event.h create mode 100644 src/debug/gc-heap.h create mode 100644 src/debug/heap.cpp create mode 100644 src/debug/heap.h create mode 100644 src/debug/logger.cpp create mode 100644 src/debug/logger.h create mode 100644 src/debug/makefile.in create mode 100644 src/debug/simple-event.h create mode 100644 src/debug/sysv-heap.cpp create mode 100644 src/debug/sysv-heap.h create mode 100644 src/decimal-round.h create mode 100644 src/desktop-affine.cpp create mode 100644 src/desktop-affine.h create mode 100644 src/desktop-events.cpp create mode 100644 src/desktop-events.h create mode 100644 src/desktop-handles.cpp create mode 100644 src/desktop-handles.h create mode 100644 src/desktop-style.cpp create mode 100644 src/desktop-style.h create mode 100644 src/desktop.cpp create mode 100644 src/desktop.h create mode 100644 src/dialogs/.cvsignore create mode 100644 src/dialogs/Makefile_insert create mode 100644 src/dialogs/clonetiler.cpp create mode 100644 src/dialogs/clonetiler.h create mode 100644 src/dialogs/debugdialog.cpp create mode 100644 src/dialogs/debugdialog.h create mode 100644 src/dialogs/dialog-events.cpp create mode 100644 src/dialogs/dialog-events.h create mode 100644 src/dialogs/display-settings.cpp create mode 100644 src/dialogs/display-settings.h create mode 100644 src/dialogs/eek-preview.cpp create mode 100644 src/dialogs/eek-preview.h create mode 100644 src/dialogs/export.cpp create mode 100644 src/dialogs/export.h create mode 100644 src/dialogs/extensions.cpp create mode 100644 src/dialogs/extensions.h create mode 100644 src/dialogs/filedialog-win32.cpp create mode 100644 src/dialogs/filedialog.cpp create mode 100644 src/dialogs/filedialog.h create mode 100644 src/dialogs/fill-style.cpp create mode 100644 src/dialogs/fill-style.h create mode 100644 src/dialogs/find.cpp create mode 100644 src/dialogs/find.h create mode 100644 src/dialogs/iconpreview.cpp create mode 100644 src/dialogs/iconpreview.h create mode 100644 src/dialogs/in-dt-coordsys.cpp create mode 100644 src/dialogs/in-dt-coordsys.h create mode 100644 src/dialogs/input.cpp create mode 100644 src/dialogs/input.h create mode 100644 src/dialogs/item-properties.cpp create mode 100644 src/dialogs/item-properties.h create mode 100644 src/dialogs/layer-properties.cpp create mode 100644 src/dialogs/layer-properties.h create mode 100644 src/dialogs/makefile.in create mode 100644 src/dialogs/object-attributes.cpp create mode 100644 src/dialogs/object-attributes.h create mode 100644 src/dialogs/object-properties.cpp create mode 100644 src/dialogs/object-properties.h create mode 100644 src/dialogs/rdf.cpp create mode 100644 src/dialogs/rdf.h create mode 100644 src/dialogs/sp-attribute-widget.cpp create mode 100644 src/dialogs/sp-attribute-widget.h create mode 100644 src/dialogs/stroke-style.cpp create mode 100644 src/dialogs/stroke-style.h create mode 100644 src/dialogs/swatches.cpp create mode 100644 src/dialogs/swatches.h create mode 100644 src/dialogs/text-edit.cpp create mode 100644 src/dialogs/text-edit.h create mode 100644 src/dialogs/tiledialog.cpp create mode 100644 src/dialogs/tiledialog.h create mode 100644 src/dialogs/unclump.cpp create mode 100644 src/dialogs/unclump.h create mode 100644 src/dialogs/xml-tree.cpp create mode 100644 src/dialogs/xml-tree.h create mode 100644 src/dir-util-test.cpp create mode 100644 src/dir-util.cpp create mode 100644 src/dir-util.h create mode 100644 src/display/.cvsignore create mode 100644 src/display/Makefile_insert create mode 100644 src/display/bezier-utils-test.cpp create mode 100644 src/display/bezier-utils-work.txt create mode 100644 src/display/bezier-utils.cpp create mode 100644 src/display/bezier-utils.h create mode 100644 src/display/canvas-arena.cpp create mode 100644 src/display/canvas-arena.h create mode 100644 src/display/canvas-bpath.cpp create mode 100644 src/display/canvas-bpath.h create mode 100644 src/display/canvas-grid.cpp create mode 100644 src/display/canvas-grid.h create mode 100644 src/display/curve.cpp create mode 100644 src/display/curve.h create mode 100644 src/display/display-forward.h create mode 100644 src/display/gnome-canvas-acetate.cpp create mode 100644 src/display/gnome-canvas-acetate.h create mode 100644 src/display/guideline.cpp create mode 100644 src/display/guideline.h create mode 100644 src/display/makefile.in create mode 100644 src/display/nr-arena-forward.h create mode 100644 src/display/nr-arena-glyphs.cpp create mode 100644 src/display/nr-arena-glyphs.h create mode 100644 src/display/nr-arena-group.cpp create mode 100644 src/display/nr-arena-group.h create mode 100644 src/display/nr-arena-image.cpp create mode 100644 src/display/nr-arena-image.h create mode 100644 src/display/nr-arena-item.cpp create mode 100644 src/display/nr-arena-item.h create mode 100644 src/display/nr-arena-shape.cpp create mode 100644 src/display/nr-arena-shape.h create mode 100644 src/display/nr-arena.cpp create mode 100644 src/display/nr-arena.h create mode 100644 src/display/nr-gradient-gpl.cpp create mode 100644 src/display/nr-gradient-gpl.h create mode 100644 src/display/nr-plain-stuff-gdk.cpp create mode 100644 src/display/nr-plain-stuff-gdk.h create mode 100644 src/display/nr-plain-stuff.cpp create mode 100644 src/display/nr-plain-stuff.h create mode 100644 src/display/sodipodi-ctrl.cpp create mode 100644 src/display/sodipodi-ctrl.h create mode 100644 src/display/sodipodi-ctrlrect.cpp create mode 100644 src/display/sodipodi-ctrlrect.h create mode 100644 src/display/sp-canvas-util.cpp create mode 100644 src/display/sp-canvas-util.h create mode 100644 src/display/sp-canvas.cpp create mode 100644 src/display/sp-canvas.h create mode 100644 src/display/sp-ctrlline.cpp create mode 100644 src/display/sp-ctrlline.h create mode 100644 src/display/sp-ctrlquadr.cpp create mode 100644 src/display/sp-ctrlquadr.h create mode 100644 src/display/testnr.cpp create mode 100644 src/document-private.h create mode 100644 src/document-undo.cpp create mode 100644 src/document.cpp create mode 100644 src/document.h create mode 100644 src/dom/.cvsignore create mode 100755 src/dom/001.css create mode 100755 src/dom/Filt.java create mode 100755 src/dom/ImplGen.java create mode 100755 src/dom/Makefile.static create mode 100644 src/dom/Makefile_insert create mode 100644 src/dom/README create mode 100755 src/dom/acid.css create mode 100755 src/dom/base.css create mode 100755 src/dom/charclass.cpp create mode 100755 src/dom/charclass.h create mode 100755 src/dom/css.h create mode 100755 src/dom/css.idl create mode 100755 src/dom/cssparser.cpp create mode 100755 src/dom/cssparser.h create mode 100755 src/dom/cssprop.txt create mode 100755 src/dom/dom.h create mode 100755 src/dom/dom.idl create mode 100755 src/dom/domimpl.cpp create mode 100755 src/dom/domimpl.h create mode 100755 src/dom/domstream.cpp create mode 100755 src/dom/domstream.h create mode 100755 src/dom/domstring.cpp create mode 100755 src/dom/domstring.h create mode 100755 src/dom/domstringimpl.h create mode 100755 src/dom/events.h create mode 100755 src/dom/events.idl create mode 100755 src/dom/inkscape.css create mode 100755 src/dom/inkscape.logo.svg create mode 100644 src/dom/js/Makefile create mode 100644 src/dom/js/README create mode 100644 src/dom/js/fdlibm/e_acos.c create mode 100644 src/dom/js/fdlibm/e_acosh.c create mode 100644 src/dom/js/fdlibm/e_asin.c create mode 100644 src/dom/js/fdlibm/e_atan2.c create mode 100644 src/dom/js/fdlibm/e_atanh.c create mode 100644 src/dom/js/fdlibm/e_cosh.c create mode 100644 src/dom/js/fdlibm/e_exp.c create mode 100644 src/dom/js/fdlibm/e_fmod.c create mode 100644 src/dom/js/fdlibm/e_gamma.c create mode 100644 src/dom/js/fdlibm/e_gamma_r.c create mode 100644 src/dom/js/fdlibm/e_hypot.c create mode 100644 src/dom/js/fdlibm/e_j0.c create mode 100644 src/dom/js/fdlibm/e_j1.c create mode 100644 src/dom/js/fdlibm/e_jn.c create mode 100644 src/dom/js/fdlibm/e_lgamma.c create mode 100644 src/dom/js/fdlibm/e_lgamma_r.c create mode 100644 src/dom/js/fdlibm/e_log.c create mode 100644 src/dom/js/fdlibm/e_log10.c create mode 100644 src/dom/js/fdlibm/e_pow.c create mode 100644 src/dom/js/fdlibm/e_rem_pio2.c create mode 100644 src/dom/js/fdlibm/e_remainder.c create mode 100644 src/dom/js/fdlibm/e_scalb.c create mode 100644 src/dom/js/fdlibm/e_sinh.c create mode 100644 src/dom/js/fdlibm/e_sqrt.c create mode 100644 src/dom/js/fdlibm/fdlibm.h create mode 100644 src/dom/js/fdlibm/k_cos.c create mode 100644 src/dom/js/fdlibm/k_rem_pio2.c create mode 100644 src/dom/js/fdlibm/k_sin.c create mode 100644 src/dom/js/fdlibm/k_standard.c create mode 100644 src/dom/js/fdlibm/k_tan.c create mode 100644 src/dom/js/fdlibm/s_asinh.c create mode 100644 src/dom/js/fdlibm/s_atan.c create mode 100644 src/dom/js/fdlibm/s_cbrt.c create mode 100644 src/dom/js/fdlibm/s_ceil.c create mode 100644 src/dom/js/fdlibm/s_copysign.c create mode 100644 src/dom/js/fdlibm/s_cos.c create mode 100644 src/dom/js/fdlibm/s_erf.c create mode 100644 src/dom/js/fdlibm/s_expm1.c create mode 100644 src/dom/js/fdlibm/s_fabs.c create mode 100644 src/dom/js/fdlibm/s_finite.c create mode 100644 src/dom/js/fdlibm/s_floor.c create mode 100644 src/dom/js/fdlibm/s_frexp.c create mode 100644 src/dom/js/fdlibm/s_ilogb.c create mode 100644 src/dom/js/fdlibm/s_isnan.c create mode 100644 src/dom/js/fdlibm/s_ldexp.c create mode 100644 src/dom/js/fdlibm/s_lib_version.c create mode 100644 src/dom/js/fdlibm/s_log1p.c create mode 100644 src/dom/js/fdlibm/s_logb.c create mode 100644 src/dom/js/fdlibm/s_matherr.c create mode 100644 src/dom/js/fdlibm/s_modf.c create mode 100644 src/dom/js/fdlibm/s_nextafter.c create mode 100644 src/dom/js/fdlibm/s_rint.c create mode 100644 src/dom/js/fdlibm/s_scalbn.c create mode 100644 src/dom/js/fdlibm/s_signgam.c create mode 100644 src/dom/js/fdlibm/s_significand.c create mode 100644 src/dom/js/fdlibm/s_sin.c create mode 100644 src/dom/js/fdlibm/s_tan.c create mode 100644 src/dom/js/fdlibm/s_tanh.c create mode 100644 src/dom/js/fdlibm/w_acos.c create mode 100644 src/dom/js/fdlibm/w_acosh.c create mode 100644 src/dom/js/fdlibm/w_asin.c create mode 100644 src/dom/js/fdlibm/w_atan2.c create mode 100644 src/dom/js/fdlibm/w_atanh.c create mode 100644 src/dom/js/fdlibm/w_cosh.c create mode 100644 src/dom/js/fdlibm/w_exp.c create mode 100644 src/dom/js/fdlibm/w_fmod.c create mode 100644 src/dom/js/fdlibm/w_gamma.c create mode 100644 src/dom/js/fdlibm/w_gamma_r.c create mode 100644 src/dom/js/fdlibm/w_hypot.c create mode 100644 src/dom/js/fdlibm/w_j0.c create mode 100644 src/dom/js/fdlibm/w_j1.c create mode 100644 src/dom/js/fdlibm/w_jn.c create mode 100644 src/dom/js/fdlibm/w_lgamma.c create mode 100644 src/dom/js/fdlibm/w_lgamma_r.c create mode 100644 src/dom/js/fdlibm/w_log.c create mode 100644 src/dom/js/fdlibm/w_log10.c create mode 100644 src/dom/js/fdlibm/w_pow.c create mode 100644 src/dom/js/fdlibm/w_remainder.c create mode 100644 src/dom/js/fdlibm/w_scalb.c create mode 100644 src/dom/js/fdlibm/w_sinh.c create mode 100644 src/dom/js/fdlibm/w_sqrt.c create mode 100644 src/dom/js/js.c create mode 100644 src/dom/js/js.mak create mode 100644 src/dom/js/js.msg create mode 100644 src/dom/js/jsapi.c create mode 100644 src/dom/js/jsapi.h create mode 100644 src/dom/js/jsarena.c create mode 100644 src/dom/js/jsarena.h create mode 100644 src/dom/js/jsarray.c create mode 100644 src/dom/js/jsarray.h create mode 100644 src/dom/js/jsatom.c create mode 100644 src/dom/js/jsatom.h create mode 100644 src/dom/js/jsautocfg.h create mode 100644 src/dom/js/jsbit.h create mode 100644 src/dom/js/jsbool.c create mode 100644 src/dom/js/jsbool.h create mode 100644 src/dom/js/jsclist.h create mode 100644 src/dom/js/jscntxt.c create mode 100644 src/dom/js/jscntxt.h create mode 100644 src/dom/js/jscompat.h create mode 100644 src/dom/js/jsconfig.h create mode 100644 src/dom/js/jscpucfg.c create mode 100644 src/dom/js/jscpucfg.h create mode 100644 src/dom/js/jsdate.c create mode 100644 src/dom/js/jsdate.h create mode 100644 src/dom/js/jsdbgapi.c create mode 100644 src/dom/js/jsdbgapi.h create mode 100644 src/dom/js/jsdhash.c create mode 100644 src/dom/js/jsdhash.h create mode 100644 src/dom/js/jsdtoa.c create mode 100644 src/dom/js/jsdtoa.h create mode 100644 src/dom/js/jsemit.c create mode 100644 src/dom/js/jsemit.h create mode 100644 src/dom/js/jsexn.c create mode 100644 src/dom/js/jsexn.h create mode 100644 src/dom/js/jsfile.c create mode 100644 src/dom/js/jsfile.h create mode 100644 src/dom/js/jsfun.c create mode 100644 src/dom/js/jsfun.h create mode 100644 src/dom/js/jsgc.c create mode 100644 src/dom/js/jsgc.h create mode 100644 src/dom/js/jshash.c create mode 100644 src/dom/js/jshash.h create mode 100644 src/dom/js/jsinterp.c create mode 100644 src/dom/js/jsinterp.h create mode 100644 src/dom/js/jslibmath.h create mode 100644 src/dom/js/jslock.c create mode 100644 src/dom/js/jslock.h create mode 100644 src/dom/js/jslocko.asm create mode 100644 src/dom/js/jslog2.c create mode 100644 src/dom/js/jslong.c create mode 100644 src/dom/js/jslong.h create mode 100644 src/dom/js/jsmath.c create mode 100644 src/dom/js/jsmath.h create mode 100644 src/dom/js/jsnum.c create mode 100644 src/dom/js/jsnum.h create mode 100644 src/dom/js/jsobj.c create mode 100644 src/dom/js/jsobj.h create mode 100644 src/dom/js/jsopcode.c create mode 100644 src/dom/js/jsopcode.h create mode 100644 src/dom/js/jsopcode.tbl create mode 100644 src/dom/js/jsosdep.h create mode 100644 src/dom/js/jsotypes.h create mode 100644 src/dom/js/jsparse.c create mode 100644 src/dom/js/jsparse.h create mode 100644 src/dom/js/jsprf.c create mode 100644 src/dom/js/jsprf.h create mode 100644 src/dom/js/jsprvtd.h create mode 100644 src/dom/js/jspubtd.h create mode 100644 src/dom/js/jsregexp.c create mode 100644 src/dom/js/jsregexp.h create mode 100644 src/dom/js/jsscan.c create mode 100644 src/dom/js/jsscan.h create mode 100644 src/dom/js/jsscope.c create mode 100644 src/dom/js/jsscope.h create mode 100644 src/dom/js/jsscript.c create mode 100644 src/dom/js/jsscript.h create mode 100644 src/dom/js/jsshell.msg create mode 100644 src/dom/js/jsstddef.h create mode 100644 src/dom/js/jsstr.c create mode 100644 src/dom/js/jsstr.h create mode 100644 src/dom/js/jstypes.h create mode 100644 src/dom/js/jsutil.c create mode 100644 src/dom/js/jsutil.h create mode 100644 src/dom/js/jsxdrapi.c create mode 100644 src/dom/js/jsxdrapi.h create mode 100644 src/dom/js/prmjtime.c create mode 100644 src/dom/js/prmjtime.h create mode 100644 src/dom/js/resource.h create mode 100755 src/dom/knut.svg create mode 100755 src/dom/ls.h create mode 100755 src/dom/ls.idl create mode 100755 src/dom/lsimpl.cpp create mode 100755 src/dom/lsimpl.cpp.orig create mode 100755 src/dom/lsimpl.h create mode 100644 src/dom/makefile.in create mode 100755 src/dom/meyerweb.css create mode 100755 src/dom/mingwenv.bat create mode 100755 src/dom/phoebedom.h create mode 100755 src/dom/prop-css.cpp create mode 100755 src/dom/prop-css.txt create mode 100755 src/dom/prop-css2.cpp create mode 100755 src/dom/prop-svg.cpp create mode 100755 src/dom/prop-svg.txt create mode 100755 src/dom/ranges.idl create mode 100755 src/dom/sandb1.css create mode 100755 src/dom/smil.h create mode 100755 src/dom/smil.idl create mode 100755 src/dom/smilimpl.cpp create mode 100755 src/dom/smilimpl.h create mode 100755 src/dom/stringstream.cpp create mode 100755 src/dom/stringstream.h create mode 100755 src/dom/stylesheets.h create mode 100755 src/dom/stylesheets.idl create mode 100755 src/dom/svg.h create mode 100755 src/dom/svg.idl create mode 100755 src/dom/svgimpl.cpp create mode 100755 src/dom/svgimpl.h create mode 100755 src/dom/svglsimpl.cpp create mode 100755 src/dom/svglsimpl.h create mode 100755 src/dom/svgparser.cpp create mode 100755 src/dom/svgparser.h create mode 100755 src/dom/svgtypes.h create mode 100755 src/dom/testdom.cpp create mode 100755 src/dom/testsvg.cpp create mode 100755 src/dom/transforms.svg create mode 100755 src/dom/traversal.h create mode 100755 src/dom/traversal.idl create mode 100755 src/dom/uri.cpp create mode 100755 src/dom/uri.h create mode 100755 src/dom/uristream.cpp create mode 100755 src/dom/uristream.h create mode 100755 src/dom/uritest.cpp create mode 100755 src/dom/views.h create mode 100755 src/dom/views.idl create mode 100755 src/dom/xmlreader.cpp create mode 100755 src/dom/xmlreader.h create mode 100755 src/dom/xpath.h create mode 100755 src/dom/xpath.idl create mode 100755 src/dom/xpathimpl.cpp create mode 100755 src/dom/xpathimpl.h create mode 100755 src/dom/xpathparser.cpp create mode 100755 src/dom/xpathparser.h create mode 100755 src/dom/xpathtest.cpp create mode 100755 src/dom/xpathtests.cpp create mode 100644 src/draw-anchor.cpp create mode 100644 src/draw-anchor.h create mode 100644 src/draw-context.cpp create mode 100644 src/draw-context.h create mode 100644 src/dropper-context.cpp create mode 100644 src/dropper-context.h create mode 100644 src/dyna-draw-context.cpp create mode 100644 src/dyna-draw-context.h create mode 100644 src/enums.h create mode 100644 src/event-context.cpp create mode 100644 src/event-context.h create mode 100644 src/extension/.cvsignore create mode 100644 src/extension/Makefile_insert create mode 100644 src/extension/api.cpp create mode 100644 src/extension/db.cpp create mode 100644 src/extension/db.h create mode 100644 src/extension/dependency.cpp create mode 100644 src/extension/dependency.h create mode 100644 src/extension/dxf2svg/GPL.txt create mode 100644 src/extension/dxf2svg/LGPL.txt create mode 100644 src/extension/dxf2svg/Makefile create mode 100644 src/extension/dxf2svg/README create mode 100644 src/extension/dxf2svg/aci2rgb.cpp create mode 100644 src/extension/dxf2svg/blocks.cpp create mode 100644 src/extension/dxf2svg/blocks.h create mode 100644 src/extension/dxf2svg/dxf2svg.cpp create mode 100644 src/extension/dxf2svg/dxf_input.inx create mode 100644 src/extension/dxf2svg/dxf_input_windows.inx create mode 100644 src/extension/dxf2svg/entities.cpp create mode 100644 src/extension/dxf2svg/entities.h create mode 100644 src/extension/dxf2svg/entities2elements.cpp create mode 100644 src/extension/dxf2svg/entities2elements.h create mode 100644 src/extension/dxf2svg/read_dxf.cpp create mode 100644 src/extension/dxf2svg/read_dxf.h create mode 100644 src/extension/dxf2svg/tables.cpp create mode 100644 src/extension/dxf2svg/tables.h create mode 100644 src/extension/dxf2svg/tables2svg_info.cpp create mode 100644 src/extension/dxf2svg/tables2svg_info.h create mode 100644 src/extension/dxf2svg/test_dxf.cpp create mode 100644 src/extension/effect.cpp create mode 100644 src/extension/effect.h create mode 100644 src/extension/error-file.cpp create mode 100644 src/extension/error-file.h create mode 100644 src/extension/extension-forward.h create mode 100644 src/extension/extension.cpp create mode 100644 src/extension/extension.h create mode 100644 src/extension/implementation/.cvsignore create mode 100644 src/extension/implementation/Makefile_insert create mode 100644 src/extension/implementation/implementation.cpp create mode 100644 src/extension/implementation/implementation.h create mode 100644 src/extension/implementation/makefile.in create mode 100644 src/extension/implementation/plugin-link.h create mode 100644 src/extension/implementation/plugin.cpp create mode 100644 src/extension/implementation/plugin.h create mode 100644 src/extension/implementation/script.cpp create mode 100644 src/extension/implementation/script.h create mode 100644 src/extension/init.cpp create mode 100644 src/extension/init.h create mode 100644 src/extension/input.cpp create mode 100644 src/extension/input.h create mode 100644 src/extension/internal/.cvsignore create mode 100644 src/extension/internal/Makefile_insert create mode 100644 src/extension/internal/bluredge.cpp create mode 100644 src/extension/internal/bluredge.h create mode 100644 src/extension/internal/eps-out.cpp create mode 100644 src/extension/internal/eps-out.h create mode 100644 src/extension/internal/gdkpixbuf-input.cpp create mode 100644 src/extension/internal/gdkpixbuf-input.h create mode 100644 src/extension/internal/gimpgrad.cpp create mode 100644 src/extension/internal/gimpgrad.h create mode 100644 src/extension/internal/gnome.cpp create mode 100644 src/extension/internal/gnome.h create mode 100644 src/extension/internal/grid.cpp create mode 100644 src/extension/internal/grid.h create mode 100644 src/extension/internal/latex-pstricks-out.cpp create mode 100644 src/extension/internal/latex-pstricks-out.h create mode 100644 src/extension/internal/latex-pstricks.cpp create mode 100644 src/extension/internal/latex-pstricks.h create mode 100644 src/extension/internal/makefile.in create mode 100644 src/extension/internal/pov-out.cpp create mode 100644 src/extension/internal/pov-out.h create mode 100644 src/extension/internal/ps-out.cpp create mode 100644 src/extension/internal/ps-out.h create mode 100644 src/extension/internal/ps.cpp create mode 100644 src/extension/internal/ps.h create mode 100644 src/extension/internal/svg.cpp create mode 100644 src/extension/internal/svg.h create mode 100644 src/extension/internal/svgz.cpp create mode 100644 src/extension/internal/svgz.h create mode 100644 src/extension/internal/win32.cpp create mode 100644 src/extension/internal/win32.h create mode 100644 src/extension/makefile.in create mode 100644 src/extension/output.cpp create mode 100644 src/extension/output.h create mode 100644 src/extension/parameter.cpp create mode 100644 src/extension/parameter.h create mode 100644 src/extension/plugin/.cvsignore create mode 100644 src/extension/plugin/Makefile_insert create mode 100644 src/extension/plugin/makefile.in create mode 100644 src/extension/prefdialog.cpp create mode 100644 src/extension/prefdialog.h create mode 100644 src/extension/print.cpp create mode 100644 src/extension/print.h create mode 100644 src/extension/script/.cvsignore create mode 100644 src/extension/script/InkscapeBinding.cpp create mode 100644 src/extension/script/InkscapeBinding.h create mode 100644 src/extension/script/InkscapeInterpreter.cpp create mode 100644 src/extension/script/InkscapeInterpreter.h create mode 100644 src/extension/script/InkscapePerl.cpp create mode 100644 src/extension/script/InkscapePerl.h create mode 100644 src/extension/script/InkscapePython.cpp create mode 100644 src/extension/script/InkscapePython.h create mode 100644 src/extension/script/InkscapeScript.cpp create mode 100644 src/extension/script/InkscapeScript.h create mode 100644 src/extension/script/Makefile.tmp create mode 100644 src/extension/script/Makefile_insert create mode 100644 src/extension/script/README.txt create mode 100644 src/extension/script/bindtest.cpp create mode 100644 src/extension/script/cpptest.cpp create mode 100644 src/extension/script/inkscape_perl.i create mode 100644 src/extension/script/inkscape_perl.pm create mode 100644 src/extension/script/inkscape_perl.pm.h create mode 100644 src/extension/script/inkscape_perl_wrap.cpp create mode 100644 src/extension/script/inkscape_py.i create mode 100644 src/extension/script/inkscape_py.py create mode 100644 src/extension/script/inkscape_py.py.h create mode 100644 src/extension/script/inkscape_py_wrap.cpp create mode 100644 src/extension/script/js/Makefile create mode 100644 src/extension/script/js/README create mode 100644 src/extension/script/js/fdlibm/e_acos.c create mode 100644 src/extension/script/js/fdlibm/e_acosh.c create mode 100644 src/extension/script/js/fdlibm/e_asin.c create mode 100644 src/extension/script/js/fdlibm/e_atan2.c create mode 100644 src/extension/script/js/fdlibm/e_atanh.c create mode 100644 src/extension/script/js/fdlibm/e_cosh.c create mode 100644 src/extension/script/js/fdlibm/e_exp.c create mode 100644 src/extension/script/js/fdlibm/e_fmod.c create mode 100644 src/extension/script/js/fdlibm/e_gamma.c create mode 100644 src/extension/script/js/fdlibm/e_gamma_r.c create mode 100644 src/extension/script/js/fdlibm/e_hypot.c create mode 100644 src/extension/script/js/fdlibm/e_j0.c create mode 100644 src/extension/script/js/fdlibm/e_j1.c create mode 100644 src/extension/script/js/fdlibm/e_jn.c create mode 100644 src/extension/script/js/fdlibm/e_lgamma.c create mode 100644 src/extension/script/js/fdlibm/e_lgamma_r.c create mode 100644 src/extension/script/js/fdlibm/e_log.c create mode 100644 src/extension/script/js/fdlibm/e_log10.c create mode 100644 src/extension/script/js/fdlibm/e_pow.c create mode 100644 src/extension/script/js/fdlibm/e_rem_pio2.c create mode 100644 src/extension/script/js/fdlibm/e_remainder.c create mode 100644 src/extension/script/js/fdlibm/e_scalb.c create mode 100644 src/extension/script/js/fdlibm/e_sinh.c create mode 100644 src/extension/script/js/fdlibm/e_sqrt.c create mode 100644 src/extension/script/js/fdlibm/fdlibm.h create mode 100644 src/extension/script/js/fdlibm/k_cos.c create mode 100644 src/extension/script/js/fdlibm/k_rem_pio2.c create mode 100644 src/extension/script/js/fdlibm/k_sin.c create mode 100644 src/extension/script/js/fdlibm/k_standard.c create mode 100644 src/extension/script/js/fdlibm/k_tan.c create mode 100644 src/extension/script/js/fdlibm/s_asinh.c create mode 100644 src/extension/script/js/fdlibm/s_atan.c create mode 100644 src/extension/script/js/fdlibm/s_cbrt.c create mode 100644 src/extension/script/js/fdlibm/s_ceil.c create mode 100644 src/extension/script/js/fdlibm/s_copysign.c create mode 100644 src/extension/script/js/fdlibm/s_cos.c create mode 100644 src/extension/script/js/fdlibm/s_erf.c create mode 100644 src/extension/script/js/fdlibm/s_expm1.c create mode 100644 src/extension/script/js/fdlibm/s_fabs.c create mode 100644 src/extension/script/js/fdlibm/s_finite.c create mode 100644 src/extension/script/js/fdlibm/s_floor.c create mode 100644 src/extension/script/js/fdlibm/s_frexp.c create mode 100644 src/extension/script/js/fdlibm/s_ilogb.c create mode 100644 src/extension/script/js/fdlibm/s_isnan.c create mode 100644 src/extension/script/js/fdlibm/s_ldexp.c create mode 100644 src/extension/script/js/fdlibm/s_lib_version.c create mode 100644 src/extension/script/js/fdlibm/s_log1p.c create mode 100644 src/extension/script/js/fdlibm/s_logb.c create mode 100644 src/extension/script/js/fdlibm/s_matherr.c create mode 100644 src/extension/script/js/fdlibm/s_modf.c create mode 100644 src/extension/script/js/fdlibm/s_nextafter.c create mode 100644 src/extension/script/js/fdlibm/s_rint.c create mode 100644 src/extension/script/js/fdlibm/s_scalbn.c create mode 100644 src/extension/script/js/fdlibm/s_signgam.c create mode 100644 src/extension/script/js/fdlibm/s_significand.c create mode 100644 src/extension/script/js/fdlibm/s_sin.c create mode 100644 src/extension/script/js/fdlibm/s_tan.c create mode 100644 src/extension/script/js/fdlibm/s_tanh.c create mode 100644 src/extension/script/js/fdlibm/w_acos.c create mode 100644 src/extension/script/js/fdlibm/w_acosh.c create mode 100644 src/extension/script/js/fdlibm/w_asin.c create mode 100644 src/extension/script/js/fdlibm/w_atan2.c create mode 100644 src/extension/script/js/fdlibm/w_atanh.c create mode 100644 src/extension/script/js/fdlibm/w_cosh.c create mode 100644 src/extension/script/js/fdlibm/w_exp.c create mode 100644 src/extension/script/js/fdlibm/w_fmod.c create mode 100644 src/extension/script/js/fdlibm/w_gamma.c create mode 100644 src/extension/script/js/fdlibm/w_gamma_r.c create mode 100644 src/extension/script/js/fdlibm/w_hypot.c create mode 100644 src/extension/script/js/fdlibm/w_j0.c create mode 100644 src/extension/script/js/fdlibm/w_j1.c create mode 100644 src/extension/script/js/fdlibm/w_jn.c create mode 100644 src/extension/script/js/fdlibm/w_lgamma.c create mode 100644 src/extension/script/js/fdlibm/w_lgamma_r.c create mode 100644 src/extension/script/js/fdlibm/w_log.c create mode 100644 src/extension/script/js/fdlibm/w_log10.c create mode 100644 src/extension/script/js/fdlibm/w_pow.c create mode 100644 src/extension/script/js/fdlibm/w_remainder.c create mode 100644 src/extension/script/js/fdlibm/w_scalb.c create mode 100644 src/extension/script/js/fdlibm/w_sinh.c create mode 100644 src/extension/script/js/fdlibm/w_sqrt.c create mode 100644 src/extension/script/js/js.c create mode 100644 src/extension/script/js/js.mak create mode 100644 src/extension/script/js/js.msg create mode 100644 src/extension/script/js/jsapi.c create mode 100644 src/extension/script/js/jsapi.h create mode 100644 src/extension/script/js/jsarena.c create mode 100644 src/extension/script/js/jsarena.h create mode 100644 src/extension/script/js/jsarray.c create mode 100644 src/extension/script/js/jsarray.h create mode 100644 src/extension/script/js/jsatom.c create mode 100644 src/extension/script/js/jsatom.h create mode 100644 src/extension/script/js/jsautocfg.h create mode 100644 src/extension/script/js/jsbit.h create mode 100644 src/extension/script/js/jsbool.c create mode 100644 src/extension/script/js/jsbool.h create mode 100644 src/extension/script/js/jsclist.h create mode 100644 src/extension/script/js/jscntxt.c create mode 100644 src/extension/script/js/jscntxt.h create mode 100644 src/extension/script/js/jscompat.h create mode 100644 src/extension/script/js/jsconfig.h create mode 100644 src/extension/script/js/jscpucfg.c create mode 100644 src/extension/script/js/jscpucfg.h create mode 100644 src/extension/script/js/jsdate.c create mode 100644 src/extension/script/js/jsdate.h create mode 100644 src/extension/script/js/jsdbgapi.c create mode 100644 src/extension/script/js/jsdbgapi.h create mode 100644 src/extension/script/js/jsdhash.c create mode 100644 src/extension/script/js/jsdhash.h create mode 100644 src/extension/script/js/jsdtoa.c create mode 100644 src/extension/script/js/jsdtoa.h create mode 100644 src/extension/script/js/jsemit.c create mode 100644 src/extension/script/js/jsemit.h create mode 100644 src/extension/script/js/jsexn.c create mode 100644 src/extension/script/js/jsexn.h create mode 100644 src/extension/script/js/jsfile.c create mode 100644 src/extension/script/js/jsfile.h create mode 100644 src/extension/script/js/jsfun.c create mode 100644 src/extension/script/js/jsfun.h create mode 100644 src/extension/script/js/jsgc.c create mode 100644 src/extension/script/js/jsgc.h create mode 100644 src/extension/script/js/jshash.c create mode 100644 src/extension/script/js/jshash.h create mode 100644 src/extension/script/js/jsinterp.c create mode 100644 src/extension/script/js/jsinterp.h create mode 100644 src/extension/script/js/jslibmath.h create mode 100644 src/extension/script/js/jslock.c create mode 100644 src/extension/script/js/jslock.h create mode 100644 src/extension/script/js/jslocko.asm create mode 100644 src/extension/script/js/jslog2.c create mode 100644 src/extension/script/js/jslong.c create mode 100644 src/extension/script/js/jslong.h create mode 100644 src/extension/script/js/jsmath.c create mode 100644 src/extension/script/js/jsmath.h create mode 100644 src/extension/script/js/jsnum.c create mode 100644 src/extension/script/js/jsnum.h create mode 100644 src/extension/script/js/jsobj.c create mode 100644 src/extension/script/js/jsobj.h create mode 100644 src/extension/script/js/jsopcode.c create mode 100644 src/extension/script/js/jsopcode.h create mode 100644 src/extension/script/js/jsopcode.tbl create mode 100644 src/extension/script/js/jsosdep.h create mode 100644 src/extension/script/js/jsotypes.h create mode 100644 src/extension/script/js/jsparse.c create mode 100644 src/extension/script/js/jsparse.h create mode 100644 src/extension/script/js/jsprf.c create mode 100644 src/extension/script/js/jsprf.h create mode 100644 src/extension/script/js/jsprvtd.h create mode 100644 src/extension/script/js/jspubtd.h create mode 100644 src/extension/script/js/jsregexp.c create mode 100644 src/extension/script/js/jsregexp.h create mode 100644 src/extension/script/js/jsscan.c create mode 100644 src/extension/script/js/jsscan.h create mode 100644 src/extension/script/js/jsscope.c create mode 100644 src/extension/script/js/jsscope.h create mode 100644 src/extension/script/js/jsscript.c create mode 100644 src/extension/script/js/jsscript.h create mode 100644 src/extension/script/js/jsshell.msg create mode 100644 src/extension/script/js/jsstddef.h create mode 100644 src/extension/script/js/jsstr.c create mode 100644 src/extension/script/js/jsstr.h create mode 100644 src/extension/script/js/jstypes.h create mode 100644 src/extension/script/js/jsutil.c create mode 100644 src/extension/script/js/jsutil.h create mode 100644 src/extension/script/js/jsxdrapi.c create mode 100644 src/extension/script/js/jsxdrapi.h create mode 100644 src/extension/script/js/prmjtime.c create mode 100644 src/extension/script/js/prmjtime.h create mode 100644 src/extension/script/js/resource.h create mode 100644 src/extension/script/makefile.in create mode 100644 src/extension/script/quotefile.pl create mode 100644 src/extension/script/runme.py create mode 100644 src/extension/script/wrap_swig_module.sh create mode 100644 src/extension/system.cpp create mode 100644 src/extension/system.h create mode 100644 src/extension/timer.cpp create mode 100644 src/extension/timer.h create mode 100644 src/extract-uri-test.cpp create mode 100644 src/extract-uri.cpp create mode 100644 src/extract-uri.h create mode 100644 src/file.cpp create mode 100644 src/file.h create mode 100644 src/fill-or-stroke.h create mode 100644 src/fixes.cpp create mode 100644 src/fontsize-expansion.cpp create mode 100644 src/fontsize-expansion.h create mode 100644 src/forward.h create mode 100644 src/gc-alloc.h create mode 100644 src/gc-anchored.cpp create mode 100644 src/gc-anchored.h create mode 100644 src/gc-core.h create mode 100644 src/gc-finalized.h create mode 100644 src/gc-managed.h create mode 100644 src/gc.cpp create mode 100644 src/geom.cpp create mode 100644 src/geom.h create mode 100644 src/gnuc-attribute.h create mode 100644 src/gradient-chemistry.cpp create mode 100644 src/gradient-chemistry.h create mode 100644 src/gradient-context.cpp create mode 100644 src/gradient-context.h create mode 100644 src/gradient-drag.cpp create mode 100644 src/gradient-drag.h create mode 100644 src/grid-snapper.cpp create mode 100644 src/grid-snapper.h create mode 100644 src/guide-snapper.cpp create mode 100644 src/guide-snapper.h create mode 100644 src/help.cpp create mode 100644 src/help.h create mode 100644 src/helper/.cvsignore create mode 100644 src/helper/HACKING create mode 100644 src/helper/Makefile_insert create mode 100644 src/helper/action.cpp create mode 100644 src/helper/action.h create mode 100644 src/helper/gnome-utils.cpp create mode 100644 src/helper/gnome-utils.h create mode 100644 src/helper/helper-forward.h create mode 100644 src/helper/makefile.in create mode 100644 src/helper/png-write.cpp create mode 100644 src/helper/png-write.h create mode 100644 src/helper/sp-marshal.cpp.mingw create mode 100644 src/helper/sp-marshal.h.mingw create mode 100644 src/helper/sp-marshal.list create mode 100644 src/helper/stlport.h create mode 100644 src/helper/stock-items.cpp create mode 100644 src/helper/stock-items.h create mode 100644 src/helper/unit-menu.cpp create mode 100644 src/helper/unit-menu.h create mode 100644 src/helper/units-test.cpp create mode 100644 src/helper/units.cpp create mode 100644 src/helper/units.h create mode 100644 src/helper/window.cpp create mode 100644 src/helper/window.h create mode 100644 src/inkjar/.cvsignore create mode 100644 src/inkjar/Makefile_insert create mode 100644 src/inkjar/jar.cpp create mode 100644 src/inkjar/jar.h create mode 100644 src/inkjar/makefile.in create mode 100644 src/inkscape-private.h create mode 100644 src/inkscape-stock.cpp create mode 100644 src/inkscape-stock.h create mode 100644 src/inkscape.cpp create mode 100644 src/inkscape.h create mode 100644 src/inkscape.rc create mode 100644 src/inkscape_version.h.mingw create mode 100644 src/inkview.cpp create mode 100644 src/interface.cpp create mode 100644 src/interface.h create mode 100644 src/io/.cvsignore create mode 100644 src/io/Makefile.tst create mode 100644 src/io/Makefile_insert create mode 100644 src/io/base64stream.cpp create mode 100644 src/io/base64stream.h create mode 100644 src/io/crystalegg.xml create mode 100644 src/io/doc2html.xsl create mode 100644 src/io/ftos.cpp create mode 100644 src/io/ftos.h create mode 100644 src/io/gzipstream.cpp create mode 100644 src/io/gzipstream.h create mode 100644 src/io/inkscapestream.cpp create mode 100644 src/io/inkscapestream.h create mode 100644 src/io/makefile.in create mode 100644 src/io/simple-sax.cpp create mode 100644 src/io/simple-sax.h create mode 100644 src/io/streamtest.cpp create mode 100644 src/io/stringstream.cpp create mode 100644 src/io/stringstream.h create mode 100644 src/io/sys.cpp create mode 100644 src/io/sys.h create mode 100644 src/io/uristream.cpp create mode 100644 src/io/uristream.h create mode 100644 src/io/xsltstream.cpp create mode 100644 src/io/xsltstream.h create mode 100644 src/isnan.h create mode 100644 src/jabber_whiteboard/.cvsignore create mode 100644 src/jabber_whiteboard/Makefile_insert create mode 100644 src/jabber_whiteboard/buddy-list-manager.cpp create mode 100644 src/jabber_whiteboard/buddy-list-manager.h create mode 100644 src/jabber_whiteboard/callbacks.cpp create mode 100644 src/jabber_whiteboard/callbacks.h create mode 100644 src/jabber_whiteboard/chat-handler.cpp create mode 100644 src/jabber_whiteboard/chat-handler.h create mode 100644 src/jabber_whiteboard/connection-establishment.cpp create mode 100644 src/jabber_whiteboard/defines.h create mode 100644 src/jabber_whiteboard/deserializer.cpp create mode 100644 src/jabber_whiteboard/deserializer.h create mode 100644 src/jabber_whiteboard/empty.cpp create mode 100644 src/jabber_whiteboard/error-codes.h create mode 100644 src/jabber_whiteboard/internal-constants.cpp create mode 100644 src/jabber_whiteboard/internal-constants.h create mode 100644 src/jabber_whiteboard/invitation-confirm-dialog.cpp create mode 100644 src/jabber_whiteboard/invitation-confirm-dialog.h create mode 100644 src/jabber_whiteboard/jabber-handlers.cpp create mode 100644 src/jabber_whiteboard/jabber-handlers.h create mode 100644 src/jabber_whiteboard/makefile.in create mode 100644 src/jabber_whiteboard/message-aggregator.cpp create mode 100644 src/jabber_whiteboard/message-aggregator.h create mode 100644 src/jabber_whiteboard/message-contexts.cpp create mode 100644 src/jabber_whiteboard/message-contexts.h create mode 100644 src/jabber_whiteboard/message-handler.cpp create mode 100644 src/jabber_whiteboard/message-handler.h create mode 100644 src/jabber_whiteboard/message-node.h create mode 100644 src/jabber_whiteboard/message-processors.cpp create mode 100644 src/jabber_whiteboard/message-processors.h create mode 100644 src/jabber_whiteboard/message-queue.cpp create mode 100644 src/jabber_whiteboard/message-queue.h create mode 100644 src/jabber_whiteboard/message-tags.cpp create mode 100644 src/jabber_whiteboard/message-tags.h create mode 100644 src/jabber_whiteboard/message-utilities.cpp create mode 100644 src/jabber_whiteboard/message-utilities.h create mode 100644 src/jabber_whiteboard/node-tracker-event-tracker.cpp create mode 100644 src/jabber_whiteboard/node-tracker-event-tracker.h create mode 100644 src/jabber_whiteboard/node-tracker-observer.h create mode 100644 src/jabber_whiteboard/node-tracker.cpp create mode 100644 src/jabber_whiteboard/node-tracker.h create mode 100644 src/jabber_whiteboard/node-utilities.cpp create mode 100644 src/jabber_whiteboard/node-utilities.h create mode 100644 src/jabber_whiteboard/pedrodom.cpp create mode 100644 src/jabber_whiteboard/pedrodom.h create mode 100644 src/jabber_whiteboard/pedroxmpp.cpp create mode 100644 src/jabber_whiteboard/pedroxmpp.h create mode 100644 src/jabber_whiteboard/serializer.cpp create mode 100644 src/jabber_whiteboard/serializer.h create mode 100644 src/jabber_whiteboard/session-file-player.cpp create mode 100644 src/jabber_whiteboard/session-file-player.h create mode 100644 src/jabber_whiteboard/session-file-selector.cpp create mode 100644 src/jabber_whiteboard/session-file-selector.h create mode 100644 src/jabber_whiteboard/session-file.cpp create mode 100644 src/jabber_whiteboard/session-file.h create mode 100644 src/jabber_whiteboard/session-manager.cpp create mode 100644 src/jabber_whiteboard/session-manager.h create mode 100644 src/jabber_whiteboard/tracker-node.h create mode 100644 src/jabber_whiteboard/typedefs.h create mode 100644 src/jabber_whiteboard/undo-stack-observer.cpp create mode 100644 src/jabber_whiteboard/undo-stack-observer.h create mode 100644 src/knot-enums.h create mode 100644 src/knot-holder-entity.h create mode 100644 src/knot.cpp create mode 100644 src/knot.h create mode 100644 src/knotholder.cpp create mode 100644 src/knotholder.h create mode 100644 src/layer-fns.cpp create mode 100644 src/layer-fns.h create mode 100644 src/libavoid/.cvsignore create mode 100644 src/libavoid/Makefile_insert create mode 100644 src/libavoid/README create mode 100644 src/libavoid/connector.cpp create mode 100644 src/libavoid/connector.h create mode 100644 src/libavoid/debug.h create mode 100644 src/libavoid/geometry.cpp create mode 100644 src/libavoid/geometry.h create mode 100644 src/libavoid/geomtypes.h create mode 100644 src/libavoid/graph.cpp create mode 100644 src/libavoid/graph.h create mode 100644 src/libavoid/incremental.cpp create mode 100644 src/libavoid/incremental.h create mode 100644 src/libavoid/libavoid.h create mode 100644 src/libavoid/makefile.in create mode 100644 src/libavoid/makepath.cpp create mode 100644 src/libavoid/makepath.h create mode 100644 src/libavoid/polyutil.cpp create mode 100644 src/libavoid/polyutil.h create mode 100644 src/libavoid/shape.cpp create mode 100644 src/libavoid/shape.h create mode 100644 src/libavoid/static.cpp create mode 100644 src/libavoid/static.h create mode 100644 src/libavoid/timer.cpp create mode 100644 src/libavoid/timer.h create mode 100644 src/libavoid/vertices.cpp create mode 100644 src/libavoid/vertices.h create mode 100644 src/libavoid/visibility.cpp create mode 100644 src/libavoid/visibility.h create mode 100644 src/libcroco/.cvsignore create mode 100644 src/libcroco/Makefile_insert create mode 100644 src/libcroco/README create mode 100644 src/libcroco/cr-additional-sel.c create mode 100644 src/libcroco/cr-additional-sel.h create mode 100644 src/libcroco/cr-attr-sel.c create mode 100644 src/libcroco/cr-attr-sel.h create mode 100644 src/libcroco/cr-cascade.c create mode 100644 src/libcroco/cr-cascade.h create mode 100644 src/libcroco/cr-declaration.c create mode 100644 src/libcroco/cr-declaration.h create mode 100644 src/libcroco/cr-doc-handler.c create mode 100644 src/libcroco/cr-doc-handler.h create mode 100644 src/libcroco/cr-enc-handler.c create mode 100644 src/libcroco/cr-enc-handler.h create mode 100644 src/libcroco/cr-fonts.c create mode 100644 src/libcroco/cr-fonts.h create mode 100644 src/libcroco/cr-input.c create mode 100644 src/libcroco/cr-input.h create mode 100644 src/libcroco/cr-libxml-node-iface.c create mode 100644 src/libcroco/cr-libxml-node-iface.h create mode 100644 src/libcroco/cr-node-iface.h create mode 100644 src/libcroco/cr-num.c create mode 100644 src/libcroco/cr-num.h create mode 100644 src/libcroco/cr-om-parser.c create mode 100644 src/libcroco/cr-om-parser.h create mode 100644 src/libcroco/cr-parser.c create mode 100644 src/libcroco/cr-parser.h create mode 100644 src/libcroco/cr-parsing-location.c create mode 100644 src/libcroco/cr-parsing-location.h create mode 100644 src/libcroco/cr-prop-list.c create mode 100644 src/libcroco/cr-prop-list.h create mode 100644 src/libcroco/cr-pseudo.c create mode 100644 src/libcroco/cr-pseudo.h create mode 100644 src/libcroco/cr-rgb.c create mode 100644 src/libcroco/cr-rgb.h create mode 100644 src/libcroco/cr-sel-eng.c create mode 100644 src/libcroco/cr-sel-eng.h create mode 100644 src/libcroco/cr-selector.c create mode 100644 src/libcroco/cr-selector.h create mode 100644 src/libcroco/cr-simple-sel.c create mode 100644 src/libcroco/cr-simple-sel.h create mode 100644 src/libcroco/cr-statement.c create mode 100644 src/libcroco/cr-statement.h create mode 100644 src/libcroco/cr-string.c create mode 100644 src/libcroco/cr-string.h create mode 100644 src/libcroco/cr-style.c create mode 100644 src/libcroco/cr-style.h create mode 100644 src/libcroco/cr-stylesheet.c create mode 100644 src/libcroco/cr-stylesheet.h create mode 100644 src/libcroco/cr-term.c create mode 100644 src/libcroco/cr-term.h create mode 100644 src/libcroco/cr-tknzr.c create mode 100644 src/libcroco/cr-tknzr.h create mode 100644 src/libcroco/cr-token.c create mode 100644 src/libcroco/cr-token.h create mode 100644 src/libcroco/cr-utils.c create mode 100644 src/libcroco/cr-utils.h create mode 100644 src/libcroco/libcroco.h create mode 100644 src/libcroco/makefile.in create mode 100644 src/libnr/.cvsignore create mode 100644 src/libnr/Makefile_insert create mode 100644 src/libnr/have_mmx.S create mode 100644 src/libnr/in-svg-plane-test.cpp create mode 100644 src/libnr/in-svg-plane-test.h create mode 100644 src/libnr/in-svg-plane.h create mode 100644 src/libnr/libnr.def create mode 100644 src/libnr/makefile.in create mode 100644 src/libnr/n-art-bpath.h create mode 100644 src/libnr/nr-blit.cpp create mode 100644 src/libnr/nr-blit.h create mode 100644 src/libnr/nr-compose-transform.cpp create mode 100644 src/libnr/nr-compose-transform.h create mode 100644 src/libnr/nr-compose.cpp create mode 100644 src/libnr/nr-compose.h create mode 100644 src/libnr/nr-convex-hull-ops.h create mode 100644 src/libnr/nr-convex-hull.h create mode 100644 src/libnr/nr-coord.h create mode 100644 src/libnr/nr-dim2.h create mode 100644 src/libnr/nr-forward.h create mode 100644 src/libnr/nr-gradient.cpp create mode 100644 src/libnr/nr-gradient.h create mode 100644 src/libnr/nr-i-coord.h create mode 100644 src/libnr/nr-macros.h create mode 100644 src/libnr/nr-matrix-div.cpp create mode 100644 src/libnr/nr-matrix-div.h create mode 100644 src/libnr/nr-matrix-fns.cpp create mode 100644 src/libnr/nr-matrix-fns.h create mode 100644 src/libnr/nr-matrix-ops.h create mode 100644 src/libnr/nr-matrix-rotate-ops.cpp create mode 100644 src/libnr/nr-matrix-rotate-ops.h create mode 100644 src/libnr/nr-matrix-scale-ops.cpp create mode 100644 src/libnr/nr-matrix-scale-ops.h create mode 100644 src/libnr/nr-matrix-test.cpp create mode 100644 src/libnr/nr-matrix-test.h create mode 100644 src/libnr/nr-matrix-translate-ops.cpp create mode 100644 src/libnr/nr-matrix-translate-ops.h create mode 100644 src/libnr/nr-matrix.cpp create mode 100644 src/libnr/nr-matrix.h create mode 100644 src/libnr/nr-maybe.h create mode 100644 src/libnr/nr-object.cpp create mode 100644 src/libnr/nr-object.h create mode 100644 src/libnr/nr-path-code.h create mode 100644 src/libnr/nr-path.cpp create mode 100644 src/libnr/nr-path.h create mode 100644 src/libnr/nr-pixblock-line.cpp create mode 100644 src/libnr/nr-pixblock-line.h create mode 100644 src/libnr/nr-pixblock-pattern.cpp create mode 100644 src/libnr/nr-pixblock-pattern.h create mode 100644 src/libnr/nr-pixblock-pixel.cpp create mode 100644 src/libnr/nr-pixblock-pixel.h create mode 100644 src/libnr/nr-pixblock.cpp create mode 100644 src/libnr/nr-pixblock.h create mode 100644 src/libnr/nr-pixops.h create mode 100644 src/libnr/nr-point-fns-test.cpp create mode 100644 src/libnr/nr-point-fns-test.h create mode 100644 src/libnr/nr-point-fns.cpp create mode 100644 src/libnr/nr-point-fns.h create mode 100644 src/libnr/nr-point-l.h create mode 100644 src/libnr/nr-point-matrix-ops.h create mode 100644 src/libnr/nr-point-ops.h create mode 100644 src/libnr/nr-point.h create mode 100644 src/libnr/nr-rect-l.cpp create mode 100644 src/libnr/nr-rect-l.h create mode 100644 src/libnr/nr-rect-ops.h create mode 100644 src/libnr/nr-rect.cpp create mode 100644 src/libnr/nr-rect.h create mode 100644 src/libnr/nr-render.h create mode 100644 src/libnr/nr-rotate-fns-test.cpp create mode 100644 src/libnr/nr-rotate-fns-test.h create mode 100644 src/libnr/nr-rotate-fns.cpp create mode 100644 src/libnr/nr-rotate-fns.h create mode 100644 src/libnr/nr-rotate-matrix-ops.cpp create mode 100644 src/libnr/nr-rotate-matrix-ops.h create mode 100644 src/libnr/nr-rotate-ops.h create mode 100644 src/libnr/nr-rotate-test.cpp create mode 100644 src/libnr/nr-rotate-test.h create mode 100644 src/libnr/nr-rotate.h create mode 100644 src/libnr/nr-scale-matrix-ops.cpp create mode 100644 src/libnr/nr-scale-matrix-ops.h create mode 100644 src/libnr/nr-scale-ops.h create mode 100644 src/libnr/nr-scale-test.cpp create mode 100644 src/libnr/nr-scale-test.h create mode 100644 src/libnr/nr-scale-translate-ops.cpp create mode 100644 src/libnr/nr-scale-translate-ops.h create mode 100644 src/libnr/nr-scale.h create mode 100644 src/libnr/nr-svp-private.h create mode 100644 src/libnr/nr-svp-render.cpp create mode 100644 src/libnr/nr-svp-render.h create mode 100644 src/libnr/nr-svp.cpp create mode 100644 src/libnr/nr-svp.h create mode 100644 src/libnr/nr-translate-matrix-ops.cpp create mode 100644 src/libnr/nr-translate-matrix-ops.h create mode 100644 src/libnr/nr-translate-ops.h create mode 100644 src/libnr/nr-translate-rotate-ops.cpp create mode 100644 src/libnr/nr-translate-rotate-ops.h create mode 100644 src/libnr/nr-translate-scale-ops.cpp create mode 100644 src/libnr/nr-translate-scale-ops.h create mode 100644 src/libnr/nr-translate-test.cpp create mode 100644 src/libnr/nr-translate-test.h create mode 100644 src/libnr/nr-translate.h create mode 100644 src/libnr/nr-types-test.cpp create mode 100644 src/libnr/nr-types-test.h create mode 100644 src/libnr/nr-types.cpp create mode 100644 src/libnr/nr-types.h create mode 100644 src/libnr/nr-values.cpp create mode 100644 src/libnr/nr-values.h create mode 100644 src/libnr/nr_config.h.mingw create mode 100644 src/libnr/nr_config.h.win32 create mode 100644 src/libnr/nr_mmx_R8G8B8A8_P_EMPTY_A8_RGBAP.S create mode 100644 src/libnr/nr_mmx_R8G8B8A8_P_R8G8B8A8_P_A8_RGBAP.S create mode 100644 src/libnr/nr_mmx_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_TRANSFORM.S create mode 100644 src/libnr/nr_mmx_R8G8B8_R8G8B8_R8G8B8A8_P.S create mode 100644 src/libnr/testnr.cpp create mode 100644 src/libnrtype/.cvsignore create mode 100644 src/libnrtype/FontFactory.cpp create mode 100644 src/libnrtype/FontFactory.h create mode 100644 src/libnrtype/FontInstance.cpp create mode 100755 src/libnrtype/Layout-TNG-Compute.cpp create mode 100755 src/libnrtype/Layout-TNG-Input.cpp create mode 100755 src/libnrtype/Layout-TNG-OutIter.cpp create mode 100755 src/libnrtype/Layout-TNG-Output.cpp create mode 100755 src/libnrtype/Layout-TNG-Scanline-Maker.h create mode 100755 src/libnrtype/Layout-TNG-Scanline-Makers.cpp create mode 100755 src/libnrtype/Layout-TNG.cpp create mode 100755 src/libnrtype/Layout-TNG.h create mode 100644 src/libnrtype/Makefile_insert create mode 100644 src/libnrtype/RasterFont.cpp create mode 100644 src/libnrtype/RasterFont.h create mode 100644 src/libnrtype/TextWrapper.cpp create mode 100644 src/libnrtype/TextWrapper.h create mode 100644 src/libnrtype/boundary-type.h create mode 100644 src/libnrtype/font-glyph.h create mode 100644 src/libnrtype/font-instance.h create mode 100644 src/libnrtype/font-style-to-pos.cpp create mode 100644 src/libnrtype/font-style-to-pos.h create mode 100644 src/libnrtype/font-style.h create mode 100644 src/libnrtype/libnrtype.def create mode 100644 src/libnrtype/makefile.in create mode 100644 src/libnrtype/nr-type-pos-def.cpp create mode 100644 src/libnrtype/nr-type-pos-def.h create mode 100644 src/libnrtype/nr-type-primitives.cpp create mode 100644 src/libnrtype/nr-type-primitives.h create mode 100644 src/libnrtype/nrtype-forward.h create mode 100644 src/libnrtype/one-box.h create mode 100644 src/libnrtype/one-glyph.h create mode 100644 src/libnrtype/one-para.h create mode 100644 src/libnrtype/raster-glyph.h create mode 100644 src/libnrtype/raster-position.h create mode 100644 src/libnrtype/text-boundary.h create mode 100644 src/line-snapper.cpp create mode 100644 src/line-snapper.h create mode 100644 src/livarot/.cvsignore create mode 100644 src/livarot/AVL.cpp create mode 100644 src/livarot/AVL.h create mode 100644 src/livarot/AlphaLigne.cpp create mode 100644 src/livarot/AlphaLigne.h create mode 100644 src/livarot/BitLigne.cpp create mode 100644 src/livarot/BitLigne.h create mode 100644 src/livarot/Livarot.h create mode 100644 src/livarot/LivarotDefs.h create mode 100644 src/livarot/Makefile_insert create mode 100644 src/livarot/MyMath.h create mode 100644 src/livarot/MySeg.cpp create mode 100644 src/livarot/MySeg.h create mode 100644 src/livarot/Path.cpp create mode 100644 src/livarot/Path.h create mode 100644 src/livarot/PathConversion.cpp create mode 100644 src/livarot/PathCutting.cpp create mode 100644 src/livarot/PathOutline.cpp create mode 100644 src/livarot/PathSimplify.cpp create mode 100644 src/livarot/PathStroke.cpp create mode 100644 src/livarot/Shape.cpp create mode 100644 src/livarot/Shape.h create mode 100644 src/livarot/ShapeDraw.cpp create mode 100644 src/livarot/ShapeMisc.cpp create mode 100644 src/livarot/ShapeRaster.cpp create mode 100644 src/livarot/ShapeSweep.cpp create mode 100644 src/livarot/float-line.cpp create mode 100644 src/livarot/float-line.h create mode 100644 src/livarot/int-line.cpp create mode 100644 src/livarot/int-line.h create mode 100644 src/livarot/livarot-forward.h create mode 100644 src/livarot/makefile.in create mode 100644 src/livarot/path-description.cpp create mode 100644 src/livarot/path-description.h create mode 100644 src/livarot/sweep-event-queue.h create mode 100644 src/livarot/sweep-event.cpp create mode 100644 src/livarot/sweep-event.h create mode 100644 src/livarot/sweep-tree-list.cpp create mode 100644 src/livarot/sweep-tree-list.h create mode 100644 src/livarot/sweep-tree.cpp create mode 100644 src/livarot/sweep-tree.h create mode 100644 src/macros.h create mode 100644 src/main.cpp create mode 100644 src/make.dep create mode 100644 src/make.exclude create mode 100644 src/make.files create mode 100644 src/make.ofiles create mode 100644 src/makedef.pl create mode 100644 src/marker-status.cpp create mode 100644 src/marker-status.h create mode 100644 src/media.cpp create mode 100644 src/media.h create mode 100644 src/memeq.h create mode 100644 src/menus-skeleton.h create mode 100644 src/message-context.cpp create mode 100644 src/message-context.h create mode 100644 src/message-stack.cpp create mode 100644 src/message-stack.h create mode 100644 src/message.h create mode 100755 src/mkdep.pl create mode 100755 src/mkfiles.pl create mode 100644 src/mod360-test.cpp create mode 100644 src/mod360.cpp create mode 100644 src/mod360.h create mode 100644 src/modifier-fns.h create mode 100644 src/node-context.cpp create mode 100644 src/node-context.h create mode 100644 src/nodepath.cpp create mode 100644 src/nodepath.h create mode 100644 src/object-edit.cpp create mode 100644 src/object-edit.h create mode 100644 src/object-hierarchy.cpp create mode 100644 src/object-hierarchy.h create mode 100644 src/object-snapper.cpp create mode 100644 src/object-snapper.h create mode 100644 src/object-ui.cpp create mode 100644 src/object-ui.h create mode 100644 src/path-chemistry.cpp create mode 100644 src/path-chemistry.h create mode 100644 src/path-prefix.h create mode 100644 src/pen-context.cpp create mode 100644 src/pen-context.h create mode 100644 src/pencil-context.cpp create mode 100644 src/pencil-context.h create mode 100644 src/pixmaps/cursor-arc.xpm create mode 100644 src/pixmaps/cursor-arrow.xpm create mode 100644 src/pixmaps/cursor-calligraphy.xpm create mode 100644 src/pixmaps/cursor-connector.xpm create mode 100644 src/pixmaps/cursor-dropper.xpm create mode 100644 src/pixmaps/cursor-ellipse.xpm create mode 100644 src/pixmaps/cursor-gradient.xpm create mode 100644 src/pixmaps/cursor-node-d.xpm create mode 100644 src/pixmaps/cursor-node-m.xpm create mode 100644 src/pixmaps/cursor-node.xpm create mode 100644 src/pixmaps/cursor-pen.xpm create mode 100644 src/pixmaps/cursor-pencil.xpm create mode 100644 src/pixmaps/cursor-rect.xpm create mode 100644 src/pixmaps/cursor-select-d.xpm create mode 100644 src/pixmaps/cursor-select-m.xpm create mode 100644 src/pixmaps/cursor-spiral.xpm create mode 100644 src/pixmaps/cursor-star.xpm create mode 100644 src/pixmaps/cursor-text-insert.xpm create mode 100644 src/pixmaps/cursor-text.xpm create mode 100644 src/pixmaps/cursor-zoom-out.xpm create mode 100644 src/pixmaps/cursor-zoom.xpm create mode 100644 src/pixmaps/handles.xpm create mode 100644 src/plugin.def create mode 100644 src/preferences-skeleton.h create mode 100644 src/preferences.cpp create mode 100644 src/preferences.h create mode 100644 src/prefix.cpp create mode 100644 src/prefix.h create mode 100644 src/prefs-utils.cpp create mode 100644 src/prefs-utils.h create mode 100644 src/print.cpp create mode 100644 src/print.h create mode 100644 src/proofs create mode 100644 src/rect-context.cpp create mode 100644 src/rect-context.h create mode 100644 src/registrytool.cpp create mode 100644 src/registrytool.h create mode 100644 src/remove-last.h create mode 100644 src/removeoverlap/.cvsignore create mode 100644 src/removeoverlap/Makefile_insert create mode 100644 src/removeoverlap/block.cpp create mode 100644 src/removeoverlap/block.h create mode 100644 src/removeoverlap/blocks.cpp create mode 100644 src/removeoverlap/blocks.h create mode 100644 src/removeoverlap/constraint.cpp create mode 100644 src/removeoverlap/constraint.h create mode 100644 src/removeoverlap/generate-constraints.cpp create mode 100644 src/removeoverlap/generate-constraints.h create mode 100644 src/removeoverlap/makefile.in create mode 100644 src/removeoverlap/pairingheap/.cvsignore create mode 100644 src/removeoverlap/pairingheap/PairingHeap.cpp create mode 100644 src/removeoverlap/pairingheap/PairingHeap.h create mode 100644 src/removeoverlap/pairingheap/dsexceptions.h create mode 100755 src/removeoverlap/placement_SolveVPSC.cpp create mode 100755 src/removeoverlap/placement_SolveVPSC.h create mode 100644 src/removeoverlap/remove_rectangle_overlap-test.cpp create mode 100755 src/removeoverlap/remove_rectangle_overlap.cpp create mode 100755 src/removeoverlap/remove_rectangle_overlap.h create mode 100644 src/removeoverlap/removeoverlap.cpp create mode 100644 src/removeoverlap/removeoverlap.h create mode 100644 src/removeoverlap/solve_VPSC.cpp create mode 100644 src/removeoverlap/solve_VPSC.h create mode 100644 src/removeoverlap/variable.cpp create mode 100644 src/removeoverlap/variable.h create mode 100644 src/require-config.h create mode 100644 src/round-test.cpp create mode 100644 src/round.h create mode 100644 src/rubberband.cpp create mode 100644 src/rubberband.h create mode 100644 src/satisfied-guide-cns.cpp create mode 100644 src/satisfied-guide-cns.h create mode 100644 src/selcue.cpp create mode 100644 src/selcue.h create mode 100644 src/select-context.cpp create mode 100644 src/select-context.h create mode 100644 src/selection-chemistry.cpp create mode 100644 src/selection-chemistry.h create mode 100644 src/selection-describer.cpp create mode 100644 src/selection-describer.h create mode 100644 src/selection.cpp create mode 100644 src/selection.h create mode 100644 src/seltrans-handles.cpp create mode 100644 src/seltrans-handles.h create mode 100644 src/seltrans.cpp create mode 100644 src/seltrans.h create mode 100644 src/shortcuts-default-xml.cpp create mode 100644 src/shortcuts.cpp create mode 100644 src/shortcuts.h create mode 100644 src/slideshow.cpp create mode 100644 src/slideshow.h create mode 100644 src/snap.cpp create mode 100644 src/snap.h create mode 100644 src/snapped-point.cpp create mode 100644 src/snapped-point.h create mode 100644 src/snapper.cpp create mode 100644 src/snapper.h create mode 100644 src/sp-anchor.cpp create mode 100644 src/sp-anchor.h create mode 100644 src/sp-animation.cpp create mode 100644 src/sp-animation.h create mode 100644 src/sp-clippath.cpp create mode 100644 src/sp-clippath.h create mode 100644 src/sp-conn-end-pair.cpp create mode 100644 src/sp-conn-end-pair.h create mode 100644 src/sp-conn-end.cpp create mode 100644 src/sp-conn-end.h create mode 100644 src/sp-cursor.cpp create mode 100644 src/sp-cursor.h create mode 100644 src/sp-defs.cpp create mode 100644 src/sp-defs.h create mode 100644 src/sp-ellipse.cpp create mode 100644 src/sp-ellipse.h create mode 100644 src/sp-flowdiv.cpp create mode 100644 src/sp-flowdiv.h create mode 100644 src/sp-flowregion.cpp create mode 100644 src/sp-flowregion.h create mode 100644 src/sp-flowtext.cpp create mode 100644 src/sp-flowtext.h create mode 100644 src/sp-gradient-fns.h create mode 100644 src/sp-gradient-reference.cpp create mode 100644 src/sp-gradient-reference.h create mode 100644 src/sp-gradient-spread.h create mode 100644 src/sp-gradient-test.cpp create mode 100644 src/sp-gradient-units.h create mode 100644 src/sp-gradient-vector.h create mode 100644 src/sp-gradient.cpp create mode 100644 src/sp-gradient.h create mode 100644 src/sp-guide-attachment.h create mode 100644 src/sp-guide-constraint.h create mode 100644 src/sp-guide.cpp create mode 100644 src/sp-guide.h create mode 100644 src/sp-image.cpp create mode 100644 src/sp-image.h create mode 100644 src/sp-item-group.cpp create mode 100644 src/sp-item-group.h create mode 100644 src/sp-item-notify-moveto.cpp create mode 100644 src/sp-item-notify-moveto.h create mode 100644 src/sp-item-rm-unsatisfied-cns.cpp create mode 100644 src/sp-item-rm-unsatisfied-cns.h create mode 100644 src/sp-item-transform.cpp create mode 100644 src/sp-item-transform.h create mode 100644 src/sp-item-update-cns.cpp create mode 100644 src/sp-item-update-cns.h create mode 100644 src/sp-item.cpp create mode 100644 src/sp-item.h create mode 100644 src/sp-line.cpp create mode 100644 src/sp-line.h create mode 100644 src/sp-linear-gradient-fns.h create mode 100644 src/sp-linear-gradient.h create mode 100644 src/sp-marker-loc.h create mode 100644 src/sp-marker.cpp create mode 100644 src/sp-marker.h create mode 100644 src/sp-mask.cpp create mode 100644 src/sp-mask.h create mode 100644 src/sp-metadata.cpp create mode 100644 src/sp-metadata.h create mode 100644 src/sp-metric.h create mode 100644 src/sp-metrics.cpp create mode 100644 src/sp-metrics.h create mode 100644 src/sp-namedview.cpp create mode 100644 src/sp-namedview.h create mode 100644 src/sp-object-group.cpp create mode 100644 src/sp-object-group.h create mode 100644 src/sp-object-repr.cpp create mode 100644 src/sp-object-repr.h create mode 100644 src/sp-object.cpp create mode 100644 src/sp-object.h create mode 100644 src/sp-offset.cpp create mode 100644 src/sp-offset.h create mode 100644 src/sp-paint-server.cpp create mode 100644 src/sp-paint-server.h create mode 100644 src/sp-path.cpp create mode 100644 src/sp-path.h create mode 100644 src/sp-pattern.cpp create mode 100644 src/sp-pattern.h create mode 100644 src/sp-polygon.cpp create mode 100644 src/sp-polygon.h create mode 100644 src/sp-polyline.cpp create mode 100644 src/sp-polyline.h create mode 100644 src/sp-radial-gradient-fns.h create mode 100644 src/sp-radial-gradient.h create mode 100644 src/sp-rect.cpp create mode 100644 src/sp-rect.h create mode 100644 src/sp-root.cpp create mode 100644 src/sp-root.h create mode 100644 src/sp-shape.cpp create mode 100644 src/sp-shape.h create mode 100644 src/sp-skeleton.cpp create mode 100644 src/sp-skeleton.h create mode 100644 src/sp-spiral.cpp create mode 100644 src/sp-spiral.h create mode 100644 src/sp-star.cpp create mode 100644 src/sp-star.h create mode 100644 src/sp-stop-fns.h create mode 100644 src/sp-stop.h create mode 100644 src/sp-string.cpp create mode 100644 src/sp-string.h create mode 100644 src/sp-style-elem-test.cpp create mode 100644 src/sp-style-elem.cpp create mode 100644 src/sp-style-elem.h create mode 100644 src/sp-symbol.cpp create mode 100644 src/sp-symbol.h create mode 100644 src/sp-text.cpp create mode 100644 src/sp-text.h create mode 100644 src/sp-textpath.h create mode 100644 src/sp-tspan.cpp create mode 100644 src/sp-tspan.h create mode 100644 src/sp-use-reference.cpp create mode 100644 src/sp-use-reference.h create mode 100644 src/sp-use.cpp create mode 100644 src/sp-use.h create mode 100644 src/spiral-context.cpp create mode 100644 src/spiral-context.h create mode 100644 src/splivarot.cpp create mode 100644 src/splivarot.h create mode 100644 src/star-context.cpp create mode 100644 src/star-context.h create mode 100644 src/streams-gzip.cpp create mode 100644 src/streams-gzip.h create mode 100644 src/streams-handles.cpp create mode 100644 src/streams-handles.h create mode 100644 src/streams-jar.cpp create mode 100644 src/streams-jar.h create mode 100644 src/streams-zlib.cpp create mode 100644 src/streams-zlib.h create mode 100644 src/streq.h create mode 100644 src/strneq.h create mode 100644 src/style-test.cpp create mode 100644 src/style.cpp create mode 100644 src/style.h create mode 100644 src/svg-profile.h create mode 100644 src/svg-view-widget.cpp create mode 100644 src/svg-view-widget.h create mode 100644 src/svg-view.cpp create mode 100644 src/svg-view.h create mode 100644 src/svg/.cvsignore create mode 100644 src/svg/HACKING create mode 100644 src/svg/Makefile_insert create mode 100644 src/svg/css-ostringstream-test.h create mode 100644 src/svg/css-ostringstream.cpp create mode 100644 src/svg/css-ostringstream.h create mode 100644 src/svg/ftos.cpp create mode 100644 src/svg/ftos.h create mode 100644 src/svg/gnome-canvas-bpath-util.cpp create mode 100644 src/svg/gnome-canvas-bpath-util.h create mode 100644 src/svg/itos.cpp create mode 100644 src/svg/makefile.in create mode 100644 src/svg/round.cpp create mode 100644 src/svg/sp-svg.def create mode 100644 src/svg/stringstream-test.h create mode 100644 src/svg/stringstream.cpp create mode 100644 src/svg/stringstream.h create mode 100644 src/svg/strip-trailing-zeros.cpp create mode 100644 src/svg/strip-trailing-zeros.h create mode 100644 src/svg/svg-affine.cpp create mode 100644 src/svg/svg-color.cpp create mode 100644 src/svg/svg-length.cpp create mode 100644 src/svg/svg-length.h create mode 100644 src/svg/svg-path.cpp create mode 100644 src/svg/svg.h create mode 100644 src/text-chemistry.cpp create mode 100644 src/text-chemistry.h create mode 100644 src/text-context.cpp create mode 100644 src/text-context.h create mode 100644 src/text-editing.cpp create mode 100644 src/text-editing.h create mode 100644 src/text-tag-attributes.h create mode 100644 src/tools-switch.cpp create mode 100644 src/tools-switch.h create mode 100644 src/trace/.cvsignore create mode 100644 src/trace/Makefile_insert create mode 100644 src/trace/filterset.cpp create mode 100644 src/trace/filterset.h create mode 100644 src/trace/imagemap-gdk.cpp create mode 100644 src/trace/imagemap-gdk.h create mode 100644 src/trace/imagemap.cpp create mode 100644 src/trace/imagemap.h create mode 100644 src/trace/makefile.in create mode 100644 src/trace/potrace/.cvsignore create mode 100644 src/trace/potrace/auxiliary.h create mode 100644 src/trace/potrace/bitmap.h create mode 100644 src/trace/potrace/curve.cpp create mode 100644 src/trace/potrace/curve.h create mode 100644 src/trace/potrace/decompose.cpp create mode 100644 src/trace/potrace/decompose.h create mode 100644 src/trace/potrace/greymap.cpp create mode 100644 src/trace/potrace/greymap.h create mode 100644 src/trace/potrace/inkscape-potrace.cpp create mode 100644 src/trace/potrace/inkscape-potrace.h create mode 100644 src/trace/potrace/lists.h create mode 100644 src/trace/potrace/potracelib.cpp create mode 100644 src/trace/potrace/potracelib.h create mode 100644 src/trace/potrace/progress.h create mode 100644 src/trace/potrace/render.cpp create mode 100644 src/trace/potrace/render.h create mode 100644 src/trace/potrace/trace.cpp create mode 100644 src/trace/potrace/trace.h create mode 100644 src/trace/trace.cpp create mode 100644 src/trace/trace.h create mode 100644 src/traits/.cvsignore create mode 100644 src/traits/Makefile_insert create mode 100644 src/traits/copy.h create mode 100644 src/traits/function.h create mode 100644 src/traits/list-copy.h create mode 100644 src/traits/makefile.in create mode 100644 src/traits/reference.h create mode 100644 src/ui/.cvsignore create mode 100644 src/ui/Makefile_insert create mode 100644 src/ui/dialog/.cvsignore create mode 100644 src/ui/dialog/Makefile_insert create mode 100644 src/ui/dialog/aboutbox.cpp create mode 100644 src/ui/dialog/aboutbox.h create mode 100644 src/ui/dialog/align-and-distribute.cpp create mode 100644 src/ui/dialog/align-and-distribute.h create mode 100644 src/ui/dialog/dialog-manager.cpp create mode 100644 src/ui/dialog/dialog-manager.h create mode 100644 src/ui/dialog/dialog.cpp create mode 100644 src/ui/dialog/dialog.h create mode 100644 src/ui/dialog/document-metadata.cpp create mode 100644 src/ui/dialog/document-metadata.h create mode 100644 src/ui/dialog/document-properties.cpp create mode 100644 src/ui/dialog/document-properties.h create mode 100644 src/ui/dialog/export.cpp create mode 100644 src/ui/dialog/export.h create mode 100644 src/ui/dialog/extension-editor.cpp create mode 100644 src/ui/dialog/extension-editor.h create mode 100644 src/ui/dialog/fill-and-stroke.cpp create mode 100644 src/ui/dialog/fill-and-stroke.h create mode 100644 src/ui/dialog/find.cpp create mode 100644 src/ui/dialog/find.h create mode 100644 src/ui/dialog/inkscape-preferences.cpp create mode 100644 src/ui/dialog/inkscape-preferences.h create mode 100644 src/ui/dialog/layer-editor.cpp create mode 100644 src/ui/dialog/layer-editor.h create mode 100644 src/ui/dialog/makefile.in create mode 100644 src/ui/dialog/memory.cpp create mode 100644 src/ui/dialog/memory.h create mode 100644 src/ui/dialog/messages.cpp create mode 100644 src/ui/dialog/messages.h create mode 100644 src/ui/dialog/scriptdialog.cpp create mode 100644 src/ui/dialog/scriptdialog.h create mode 100644 src/ui/dialog/session-player.cpp create mode 100644 src/ui/dialog/session-player.h create mode 100644 src/ui/dialog/text-properties.cpp create mode 100644 src/ui/dialog/text-properties.h create mode 100644 src/ui/dialog/tracedialog.cpp create mode 100644 src/ui/dialog/tracedialog.h create mode 100644 src/ui/dialog/transformation.cpp create mode 100644 src/ui/dialog/transformation.h create mode 100644 src/ui/dialog/tree-editor.cpp create mode 100644 src/ui/dialog/tree-editor.h create mode 100644 src/ui/dialog/whiteboard-connect.cpp create mode 100644 src/ui/dialog/whiteboard-connect.h create mode 100644 src/ui/dialog/whiteboard-sharewithchat.cpp create mode 100644 src/ui/dialog/whiteboard-sharewithchat.h create mode 100644 src/ui/dialog/whiteboard-sharewithuser.cpp create mode 100644 src/ui/dialog/whiteboard-sharewithuser.h create mode 100644 src/ui/dialog/xml-editor.cpp create mode 100644 src/ui/dialog/xml-editor.h create mode 100644 src/ui/icons.cpp create mode 100644 src/ui/icons.h create mode 100644 src/ui/makefile.in create mode 100644 src/ui/previewable.h create mode 100644 src/ui/previewfillable.h create mode 100644 src/ui/previewholder.cpp create mode 100644 src/ui/previewholder.h create mode 100644 src/ui/stock-items.cpp create mode 100644 src/ui/stock-items.h create mode 100644 src/ui/stock.cpp create mode 100644 src/ui/stock.h create mode 100644 src/ui/view/.cvsignore create mode 100644 src/ui/view/Makefile_insert create mode 100644 src/ui/view/desktop-affine.cpp create mode 100644 src/ui/view/desktop-affine.h create mode 100644 src/ui/view/desktop-events.cpp create mode 100644 src/ui/view/desktop-events.h create mode 100644 src/ui/view/desktop-handles.cpp create mode 100644 src/ui/view/desktop-handles.h create mode 100644 src/ui/view/desktop-style.cpp create mode 100644 src/ui/view/desktop-style.h create mode 100644 src/ui/view/desktop.cpp create mode 100644 src/ui/view/desktop.h create mode 100644 src/ui/view/edit-widget-interface.h create mode 100644 src/ui/view/edit-widget.cpp create mode 100644 src/ui/view/edit-widget.h create mode 100644 src/ui/view/edit.cpp create mode 100644 src/ui/view/edit.h create mode 100644 src/ui/view/makefile.in create mode 100644 src/ui/view/view-widget.cpp create mode 100644 src/ui/view/view-widget.h create mode 100644 src/ui/view/view.cpp create mode 100644 src/ui/view/view.h create mode 100644 src/ui/widget/.cvsignore create mode 100644 src/ui/widget/Makefile_insert create mode 100644 src/ui/widget/button.cpp create mode 100644 src/ui/widget/button.h create mode 100644 src/ui/widget/color-picker.cpp create mode 100644 src/ui/widget/color-picker.h create mode 100644 src/ui/widget/color-preview.cpp create mode 100644 src/ui/widget/color-preview.h create mode 100644 src/ui/widget/combo-text.cpp create mode 100644 src/ui/widget/combo-text.h create mode 100644 src/ui/widget/entity-entry.cpp create mode 100644 src/ui/widget/entity-entry.h create mode 100644 src/ui/widget/handlebox.cpp create mode 100644 src/ui/widget/handlebox.h create mode 100644 src/ui/widget/icon-widget.cpp create mode 100644 src/ui/widget/icon-widget.h create mode 100644 src/ui/widget/imageicon.cpp create mode 100644 src/ui/widget/imageicon.h create mode 100644 src/ui/widget/labelled.cpp create mode 100644 src/ui/widget/labelled.h create mode 100644 src/ui/widget/licensor.cpp create mode 100644 src/ui/widget/licensor.h create mode 100644 src/ui/widget/makefile.in create mode 100644 src/ui/widget/notebook-page.cpp create mode 100644 src/ui/widget/notebook-page.h create mode 100644 src/ui/widget/page-sizer.cpp create mode 100644 src/ui/widget/page-sizer.h create mode 100644 src/ui/widget/panel.cpp create mode 100644 src/ui/widget/panel.h create mode 100644 src/ui/widget/preferences-widget.cpp create mode 100644 src/ui/widget/preferences-widget.h create mode 100644 src/ui/widget/registered-widget.cpp create mode 100644 src/ui/widget/registered-widget.h create mode 100644 src/ui/widget/registry.cpp create mode 100644 src/ui/widget/registry.h create mode 100644 src/ui/widget/ruler.cpp create mode 100644 src/ui/widget/ruler.h create mode 100644 src/ui/widget/scalar-unit.cpp create mode 100644 src/ui/widget/scalar-unit.h create mode 100644 src/ui/widget/scalar.cpp create mode 100644 src/ui/widget/scalar.h create mode 100644 src/ui/widget/selected-style.cpp create mode 100644 src/ui/widget/selected-style.h create mode 100644 src/ui/widget/style-swatch.cpp create mode 100644 src/ui/widget/style-swatch.h create mode 100644 src/ui/widget/svg-canvas.cpp create mode 100644 src/ui/widget/svg-canvas.h create mode 100644 src/ui/widget/tolerance-slider.cpp create mode 100644 src/ui/widget/tolerance-slider.h create mode 100644 src/ui/widget/toolbox.cpp create mode 100644 src/ui/widget/toolbox.h create mode 100644 src/ui/widget/unit-menu.cpp create mode 100644 src/ui/widget/unit-menu.h create mode 100644 src/ui/widget/zoom-status.cpp create mode 100644 src/ui/widget/zoom-status.h create mode 100644 src/undo-stack-observer.h create mode 100644 src/unit-constants.h create mode 100644 src/uri-references.cpp create mode 100644 src/uri-references.h create mode 100644 src/uri.cpp create mode 100644 src/uri.h create mode 100644 src/utest/.cvsignore create mode 100644 src/utest/Makefile_insert create mode 100644 src/utest/makefile.in create mode 100644 src/utest/test-1ary-cases.h create mode 100644 src/utest/test-2ary-cases.h create mode 100644 src/utest/utest.h create mode 100644 src/util/.cvsignore create mode 100644 src/util/Makefile_insert create mode 100644 src/util/compose.hpp create mode 100644 src/util/filter-list.h create mode 100644 src/util/forward-pointer-iterator.h create mode 100644 src/util/glib-list-iterators.h create mode 100644 src/util/list-container-test.cpp create mode 100644 src/util/list-container.h create mode 100644 src/util/list.h create mode 100644 src/util/makefile.in create mode 100644 src/util/map-list.h create mode 100644 src/util/reverse-list.h create mode 100644 src/util/shared-c-string-ptr.cpp create mode 100644 src/util/shared-c-string-ptr.h create mode 100644 src/util/tuple.h create mode 100644 src/util/ucompose.hpp create mode 100644 src/util/units.cpp create mode 100644 src/util/units.h create mode 100644 src/verbs.cpp create mode 100644 src/verbs.h create mode 100644 src/version.cpp create mode 100644 src/version.h create mode 100644 src/widgets/.cvsignore create mode 100644 src/widgets/Makefile_insert create mode 100644 src/widgets/button.cpp create mode 100644 src/widgets/button.h create mode 100644 src/widgets/dash-selector.cpp create mode 100644 src/widgets/dash-selector.h create mode 100644 src/widgets/desktop-widget.cpp create mode 100644 src/widgets/desktop-widget.h create mode 100644 src/widgets/font-selector.cpp create mode 100644 src/widgets/font-selector.h create mode 100644 src/widgets/gradient-image.cpp create mode 100644 src/widgets/gradient-image.h create mode 100644 src/widgets/gradient-selector.cpp create mode 100644 src/widgets/gradient-selector.h create mode 100644 src/widgets/gradient-toolbar.cpp create mode 100644 src/widgets/gradient-toolbar.h create mode 100644 src/widgets/gradient-vector.cpp create mode 100644 src/widgets/gradient-vector.h create mode 100644 src/widgets/icon.cpp create mode 100644 src/widgets/icon.h create mode 100644 src/widgets/layer-selector.cpp create mode 100644 src/widgets/layer-selector.h create mode 100644 src/widgets/makefile.in create mode 100644 src/widgets/paint-selector.cpp create mode 100644 src/widgets/paint-selector.h create mode 100644 src/widgets/ruler.cpp create mode 100644 src/widgets/ruler.h create mode 100644 src/widgets/select-toolbar.cpp create mode 100644 src/widgets/select-toolbar.h create mode 100644 src/widgets/shrink-wrap-button.cpp create mode 100644 src/widgets/shrink-wrap-button.h create mode 100644 src/widgets/sp-color-gtkselector.cpp create mode 100644 src/widgets/sp-color-gtkselector.h create mode 100644 src/widgets/sp-color-notebook.cpp create mode 100644 src/widgets/sp-color-notebook.h create mode 100644 src/widgets/sp-color-preview.cpp create mode 100644 src/widgets/sp-color-preview.h create mode 100644 src/widgets/sp-color-scales.cpp create mode 100644 src/widgets/sp-color-scales.h create mode 100644 src/widgets/sp-color-selector.cpp create mode 100644 src/widgets/sp-color-selector.h create mode 100644 src/widgets/sp-color-slider.cpp create mode 100644 src/widgets/sp-color-slider.h create mode 100644 src/widgets/sp-color-wheel-selector.cpp create mode 100644 src/widgets/sp-color-wheel-selector.h create mode 100644 src/widgets/sp-color-wheel.cpp create mode 100644 src/widgets/sp-color-wheel.h create mode 100644 src/widgets/sp-widget.cpp create mode 100644 src/widgets/sp-widget.h create mode 100644 src/widgets/sp-xmlview-attr-list.cpp create mode 100644 src/widgets/sp-xmlview-attr-list.h create mode 100644 src/widgets/sp-xmlview-content.cpp create mode 100644 src/widgets/sp-xmlview-content.h create mode 100644 src/widgets/sp-xmlview-tree.cpp create mode 100644 src/widgets/sp-xmlview-tree.h create mode 100644 src/widgets/spinbutton-events.cpp create mode 100644 src/widgets/spinbutton-events.h create mode 100644 src/widgets/spw-utilities.cpp create mode 100644 src/widgets/spw-utilities.h create mode 100644 src/widgets/toolbox.cpp create mode 100644 src/widgets/toolbox.h create mode 100644 src/widgets/widget-sizes.h create mode 100644 src/winmain.cpp create mode 100644 src/xml/.cvsignore create mode 100644 src/xml/Makefile_insert create mode 100644 src/xml/attribute-record.h create mode 100644 src/xml/comment-node.h create mode 100644 src/xml/composite-node-observer.cpp create mode 100644 src/xml/composite-node-observer.h create mode 100644 src/xml/croco-node-iface.cpp create mode 100644 src/xml/croco-node-iface.h create mode 100644 src/xml/document.h create mode 100644 src/xml/element-node.h create mode 100644 src/xml/event-fns.h create mode 100644 src/xml/event.cpp create mode 100644 src/xml/event.h create mode 100644 src/xml/invalid-operation-exception.h create mode 100644 src/xml/log-builder.cpp create mode 100644 src/xml/log-builder.h create mode 100644 src/xml/makefile.in create mode 100644 src/xml/node-event-vector.h create mode 100644 src/xml/node-fns.cpp create mode 100644 src/xml/node-fns.h create mode 100644 src/xml/node-iterators.h create mode 100644 src/xml/node-observer.h create mode 100644 src/xml/node.h create mode 100644 src/xml/quote-test.cpp create mode 100644 src/xml/quote-test.h create mode 100644 src/xml/quote.cpp create mode 100644 src/xml/quote.h create mode 100644 src/xml/repr-action-test.cpp create mode 100644 src/xml/repr-action-test.h create mode 100644 src/xml/repr-css.cpp create mode 100644 src/xml/repr-io.cpp create mode 100644 src/xml/repr-sorting.cpp create mode 100644 src/xml/repr-sorting.h create mode 100644 src/xml/repr-util.cpp create mode 100644 src/xml/repr.cpp create mode 100644 src/xml/repr.h create mode 100644 src/xml/session.h create mode 100644 src/xml/simple-document.cpp create mode 100644 src/xml/simple-document.h create mode 100644 src/xml/simple-node.cpp create mode 100644 src/xml/simple-node.h create mode 100644 src/xml/simple-session.cpp create mode 100644 src/xml/simple-session.h create mode 100644 src/xml/sp-css-attr.h create mode 100644 src/xml/text-node.h create mode 100644 src/xml/transaction-logger.h create mode 100644 src/zoom-context.cpp create mode 100644 src/zoom-context.h create mode 100755 tools-version.sh create mode 100755 utf8-to-roff diff --git a/.cvsignore b/.cvsignore new file mode 100644 index 000000000..34abb3914 --- /dev/null +++ b/.cvsignore @@ -0,0 +1,35 @@ +Makefile.in +Makefile +configure +config.log +config.h.in +config.h +config.sub +config.guess +ltconfig +ltmain.sh +config.cache +stamp-h* +build-stamp +config.status +libtool +aclocal.m4 +intl +config.h.in +ABOUT-NLS +inkscape.spec +*.1 +*.o +*.svg +intltool-* +inkscape.desktop +GNOME_Sodipodi.oaf +autom4te*cache +toru +inkscape-*.tar.gz +builddir +Info.plist +compile +depcomp +install-sh +missing diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 000000000..832676b60 --- /dev/null +++ b/AUTHORS @@ -0,0 +1,78 @@ +Josh Andler +John Bintz +Arpad Biro +Daniel Borgmann +Hans Breuer +Nicu Buculei +Bulia Byak +Chema Celorio +Johan Ceuppens +Zbigniew Chyla +Alexander Clausen +John Cliff +Kees Cook +Ben Cromwell +Robert Crosbie +Jon Cruz +Daniel Díaz +Larry Doolittle +Tim Dwyer +Maxim V. Dziumanenko +Danilo Egan +Frank Felfe +Andrew Fitzsimon +Edward Flick +Fred +Ben Fowler +Ted Gould +Bryce Harrington +Carl Hetherington +Karl Ove Hufthammer +Richard Hughes +Nathan Hurst +Thomas Ingham +Bob Jamison +Lauris Kaplinski +Lynn Kerby +Petr Kovar +Raph Levien +Nicklas Lindgren +Vitaly Lipatov +Colin Marquardt +Dmitry G. Mastrukov +Matiphas +Michael Meeks +Federico Mena +MenTaLguY +Aubanel Monnier +Derek P. Moore +Peter Moulder +Jörg Müller +Yukihiro Nakai +Christian Neumair +Andreas Nilsson +Mitsuru Oka +Jon Phillips +Zdenko Podobny +Alexandre Prokoudine +Alexey Remizov +Frederic Rodrigo +Juarez Rudsatz +Xavier Conde Rueda +Christian Schaller +Tom von Schwerdtner +Shivaken +BoÅ¡tjan Å petič +Aaron Spike +Kaushik Sridharan +Ralf Stephan +Dariusz Stojek +Pat Suwalski +Adib Taraben +David Turner +Aleksandar Urosevic +Lucas Vieites +Michael Wybrow +Daniel Yacob +David Yip +Masatake Yamato diff --git a/COPYING b/COPYING new file mode 100644 index 000000000..b83f24b68 --- /dev/null +++ b/COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/COPYING.LIB b/COPYING.LIB new file mode 100644 index 000000000..5ca31f63b --- /dev/null +++ b/COPYING.LIB @@ -0,0 +1,515 @@ + + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations +below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. +^L + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it +becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. +^L + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control +compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. +^L + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply, and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License +may add an explicit geographical distribution limitation excluding those +countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms +of the ordinary General Public License). + + To apply these terms, attach the following notices to the library. +It is safest to attach them to the start of each source file to most +effectively convey the exclusion of warranty; and each file should +have at least the "copyright" line and a pointer to where the full +notice is found. + + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +Also add information on how to contact you by electronic and paper +mail. + +You should also get your employer (if you work as a programmer) or +your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James +Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 000000000..e10c81f71 --- /dev/null +++ b/ChangeLog @@ -0,0 +1,9028 @@ +2006-01-12 Marco Scholten + + * /src/ui/dialog/inkscape-preferences.cpp & .h + Converted preferences dialog to gtkmm + * added /src/ui/widget/preferences-widget.cpp & .h + * src/verbs.cpp + updated to start new dialog. + +2006-01-11 Michael Wybrow + + * src/sp-item-group.cpp, src/sp-path.cpp, src/sp-star.cpp, + src/extension/internal/svg.cpp, src/ui/widget/ruler.cpp: + Fix some compilation problems on Mac OS X after recent + includes cleanup. + +2006-01-05 Jon A. Cruz + + * src/widgets/desktop-widget.cpp: + Corrected resize behavior of canvas/swatches split. + +2006-01-06 Mathieu Dimanche + + * src/util/units.cpp: forcin 'C' locale for reading units.txt file + Fixes bug #1391348. + +2006-01-05 MenTaLguY + + * src/libnr/nr-maybe.h: fix constness/local reference issues + +2006-01-04 MenTaLguY + + * src/Makefile_insert, src/shortcuts-default-xml.cpp, + src/shortcuts.cpp, src/shortcuts.xml: + + Moved default shortcuts XML file into a string constant (for now); + replaced hard-coded structure with code to read XML file. + +2006-01-04 Peter Moulder + + * src/extension/internal/ps.cpp (setup): Clarify the meaning of + `Print destination', mentioning the new possibility of leaving + as empty. + * (PrintPS::begin) If print destination is an empty string, then + don't pass `-P %s' to lpr: just let lpr use its default. + * (PrintPS::init) Change default print destination from `lp' to empty + string. + +2006-01-04 Jon A. Cruz + + * src/widgets/desktop-widget.cpp: + Adding split pane for swatches. + +2006-01-03 Michael Wybrow + + * src/libavoid/visibility.cpp: Add operator!= for the EdgePair class. + This is needed to compile on Tru64 UNIX. Fixes bug #1386755. + +2005-12-30 Josh Andler + + * src/ui/widget/selected-style.cpp, src/ui/widget/selected-style.h + Added "invert" function to right-click menu of style selector. + +2005-12-22 Jon A. Cruz + + * share/palettes/Tango-Palette.gpl: + Updated to newer version from the Tango project. + +2005-12-21 Jon A. Cruz + + * src/interface.cpp, src/preferences-skeleton.h, + src/widgets/desktop-widget.h, src/widgets/desktop-widget.cpp: + Adding panels/swatches to main UI. + +2005-11-23 Tim Dwyer + + * src/removeoverlap/*.{cpp,h}: Bug fix in removeoverlap algorithm that + should finally get timestamps working properly. Specifically, heap + timestamps are now refreshed before a merge. + +2005-12-19 Michael Wybrow + + * src/sp-conn-end.cpp, src/connector-context.cpp: Have connectors + draw to the correct position on shape bounding boxes. Previously + the point where connectors were drawn was on straight line between + the two endpoints. These points now lie on the line between the + second last point on the polyline and the center of the shape. + + * src/display/curve.cpp, src/display/curve.hpp: Added a couple of + functions that return the second and second-last points in a curve. + + * src/removeoverlap/generate-constraints.cpp: Moved the + #include "isnan.h" to be the final include. This fixes a + compilation error on OS X. + +2005-12-16 Carl Hetherington + + * src/conn-avoid-ref.cpp, sp-conn-end-pair.cpp, sp-conn-end.cpp, + sp-item.cpp, sp-shape.cpp, dialogs/clonetiler.cpp, + dialogs/stroke-style.cpp, dialogs/tiledialog.cpp, + dialogs/unclump.cpp, display/nr-arena-shape.cpp, + display/nr-arena-shape.h, widgets/icon.cpp: more NRRect removal. + + * src/desktop.cpp, src/desktop.h, src/dyna-draw-context.cpp, + src/selection-chemistry.cpp, src/sp-namedview.cpp, src/verbs.cpp, + src/display/sp-canvas.cpp, src/display/sp-canvas.h, + src/ui/view/edit-widget.cpp, src/ui/widget/zoom-status.cpp, + src/widgets/desktop-widget.cpp: more NRRect removals and cleanups. + + * src/grid-snapper.cpp: snap only to visible grid lines (patch + from mtou). + +2005-12-15 Carl Hetherington + + * src/conn-avoid-ref.cpp, src/gradient-chemistry.cpp, + src/sp-conn-end.cpp, src/sp-item.{cpp,h}: NR::Rect version of + sp_item_invoke_bbox (SPItem::invokeBbox). Use it in some places. + +2005-12-14 Carl Hetherington + + * src/dyna-draw-context.cpp, src/gradient-context.cpp, + src/selection.h, src/sp-flowtext.cpp, src/sp-item.cpp, + src/sp-item.h, src/sp-shape.cpp, src/sp-text.cpp, + src/dialogs/layer-properties.cpp, + src/extension/internal/bluredge.cpp, + src/extension/internal/grid.cpp, src/ui/dialog/transformation.cpp, + src/widgets/desktop-widget.cpp: remove NRMatrix version of + sp_item_i2d_affine(). Some include file adjustments. + + * src/arc-context.cpp: some very minor cleanups. + + * src/svg/svg-length.{cpp,h}, src/helper/units.cpp: use INCH + rather than IN to avoid breaking the compile on some systems. + +2005-12-13 Carl Hetherington + + * src/arc-context.cpp, src/connector-context.cpp, + src/context-fns.cpp, src/desktop-affine.cpp, src/desktop-affine.h, + src/desktop-events.cpp, src/desktop.cpp, src/desktop.h, + src/draw-anchor.cpp src/dropper-context.cpp, + src/dyna-draw-context.cpp, src/event-context.cpp + src/gradient-context.cpp, src/knot.cpp, src/node-context.cpp, + src/object-snapper.cpp src/pen-context.cpp, + src/pencil-context.cpp, src/rect-context.cpp + src/select-context.cpp, src/selection-chemistry.cpp, + src/sp-item.cpp, src/sp-item.h src/spiral-context.cpp, + src/star-context.cpp, src/text-context.cpp src/zoom-context.cpp, + src/ui/widget/ruler.cpp: make desktop's transforms private + members. + + * src/document.cpp, src/object-edit.cpp, src/sp-ellipse.cpp, + src/sp-ellipse.h, src/sp-gradient.cpp, src/sp-image.cpp, + src/sp-image.h, src/sp-line.cpp, src/sp-line.h, + src/sp-linear-gradient.h, src/sp-marker.cpp, src/sp-marker.h, + src/sp-pattern.cpp, src/sp-pattern.h, src/sp-radial-gradient.h, + src/sp-rect.cpp, src/sp-rect.h, src/sp-root.cpp, src/sp-root.h, + src/sp-star.cpp, src/sp-symbol.h, src/sp-text.cpp, + src/sp-textpath.h, src/sp-tspan.cpp, src/sp-use.cpp, src/sp-use.h, + src/text-tag-attributes.h, src/helper/units.cpp, + src/helper/units.h, src/libnrtype/Layout-TNG-Compute.cpp, + src/libnrtype/Layout-TNG-Input.cpp, + src/libnrtype/Layout-TNG-OutIter.cpp, + src/libnrtype/Layout-TNG-Output.cpp, src/libnrtype/Layout-TNG.h, + src/libnrtype/TextWrapper.cpp, src/svg/svg-length.cpp, + src/svg/svg.h: partial C++-ificiation of SPSVGLength. Rename it + to SVGLength. + +2005-12-13 Mathieu Dimanche + + * src/snapped-point.{cpp,h} : new files. + + * src/Makefile_insert : Added the new files + + * src/arc-context.cpp, src/connector-context.cpp, + src/context-fns.cpp, src/draw-context.cpp, src/nodepath.cpp, + src/object-edit.cpp, src/pencil-context.cpp, + src/selection-chemistry.cpp, src/seltrans.cpp, src/snap.cpp, + src/spiral-context.cpp, src/star-context.cpp, + src/line-snapper.cpp, src/line-snapper.h, src/object-snapper.cpp, + src/object-snapper.h src/snapper.cpp, src/snapper.h, + src/event-context.cpp, src/rect-context.cpp, + src/select-context.cpp : Use SnappedPoint class + + * src/color-rgba.h : Added rgba32 unsigned int handling and + "inverse" members (NEED TO BE TESTED) + +2005-12-12 MenTaLguY + + * src/widgets/desktop-widget.cpp: moved some widgets into statusbar + widget for more aesthetic appearance + +2005-12-12 Carl Hetherington + + * src/arc-context.cpp: minor cleanups. Use SnapManager more. Use + Inkscape::setup_for_drag_start. + + * src/connector-context.cpp, src/draw-context.cpp, + src/object-edit.cpp, src/pencil-context.cpp, src/rect-context.cpp, + src/spiral-context.cpp, src/star-context.cpp: use SnapManager. + + * src/rect-context.cpp, src/spiral-context.cpp, + src/star-context.cpp: use Inkscape::setup_for_drag_start(). + + * src/snapper.{cpp,h}: simplify snap point types code. + + * src/context-fns.{cpp,h}: add setup_for_drag_start(). + + * src/dyna-draw-context.cpp: remove unused and erroneous snapping code. + + * src/pen-context.cpp: remove unused variable. + + * src/draw-context.cpp: use SnapManager. + + * src/nodepath.cpp: const fixes. Use SnapManager. + + * src/selection-chemistry.cpp, src/seltrans.cpp: some cleanups. + Use new snap API. + + * src/snap.{cpp,h}: remove some dead code. + + * src/sp-item.{cpp,h}, src/node-context.cpp, src/draw-context.cpp: + remove an unnecessary parameter from sp_item_dt2i_affine(). + +2005-12-09 Carl Hetherington + + * src/object-snapper.cpp: make node snapping work again. + + * src/star-context.cpp: use SnapManager. Some other minor cleanups. + + * src/arc-context.cpp, src/connector-context.cpp, + src/dyna-draw-context.cpp, src/pen-context.cpp, + src/pencil-context.cpp, src/rect-context.cpp, + src/selection-chemistry.cpp, src/spiral-context.cpp, + src/star-context.cpp, src/text-context.cpp: use + Inkscape::have_viable_layer. + + * src/context-fns.{cpp,h}: new files. + + * src/arc-context.cpp, src/context-fns.{cpp,h}, + src/rect-context.cpp: abstract common code into context-fns and + clean it up a bit. + +2005-12-08 Carl Hetherington + + * src/grid-snapper.cpp, src/guide-snapper.cpp, src/line-snapper.h: + coding style. Change how lines are defined. + + * src/grid-snapper.h, src/guide-snapper.h: coding style. + + * src/line-snapper.cpp, src/object-snapper.{cpp,h}: Coding style. + Various cleanups. Small API changes. + + * src/snap.cpp: changes to Snapper API. Added work-in-progress SnapManager. + + * src/snapper.{cpp,h}: API cleanups. + + * src/sp-namedview.{cpp,h}: added getSnappers(). + + * src/seltrans.cpp: Cleanup and fix moveTo(). Go back to snapping + to snap points rather than the convex hull, at least for a bit. + +2005-12-07 Carl Hetherington + + * src/libnr/nr-convex-hull.h: remove unnecessary includes. + + * src/line-snapper.{cpp,h}, src/object-snapper.{cpp,h}, + src/attributes.{cpp,h}, src/desktop.cpp, src/dyna-draw-context.cpp + src/arc-context.cpp, src/grid-snapper.h, src/nodepath.cpp, + src/rect-context.cpp, src/selection-chemistry.cpp, + src/seltrans.cpp, src/snap.{cpp,h}, src/snapper.{cpp,h}, + src/sp-namedview.{cpp,h}, src/spiral-context.cpp, + src/star-context.cpp, src/dialogs/desktop-properties.{cpp,h}, + src/Makefile_insert: first cut of object snapping. + + * src/grid-snapper.cpp, src/guide-snapper.{cpp,h}: use Inkscape namespace. + +2005-12-06 Carl Hetherington + + * src/libnr/nr-maybe.h: add missing public: to class IsNot. + + * src/splivarot.{cpp,h}: declare some more functions. Fix + get_nearest_position_on_Path to not crash if you call it with an + Item that isn't Shape or Text. + + * src/node-context.cpp: adapt for changes in splivarot.{cpp,h}. + + * src/nodepath.cpp: remove declaration of a function now declared + in splivarot.h. + +2005-12-05 Carl Hetherington + + * src/desktop.cpp, src/tools-switch.cpp, + src/dialogs/clonetiler.cpp, src/dialogs/display-settings.cpp: + re-jig #includes slightly. + + * src/seltrans.{cpp,h}, src/selcue.{cpp,h}: C++-ification and cleanup. + + * src/select-context.{cpp,h}, src/seltrans-handles.h: adapt for + changes to SelTrans. + + * src/event-context.{cpp,h}: adapt for changes to SelCue. + + * src/rect-context.cpp, src/gradient-context.cpp: remove unnecessary include. + + * src/connector-context.h, src/draw-context.h: add a forward + declaration. + + * src/dropper-context.{cpp,h}: remove an unused variable and its + associated includes. + + * src/main.cpp: fix comment for renamed SPSelCue. + + * src/dialogs/display-settings.cpp: adapt for slightly re-jigged SelCue. + +2005-12-04 Ted Gould + + * po/POTFILES.in: + + Adding the .inx files as [type: gettext/xml] so that they will get + translated. Good stuff. + + * share/extensions/addnodes.inx, share/extensions/ai_input.inx, + share/extensions/ai_output.inx, share/extensions/bluredge.inx, + share/extensions/dia.inx, share/extensions/dots.inx, + share/extensions/dropshadow.inx, share/extensions/dxf_input.inx, + share/extensions/dxf_output.inx, share/extensions/embedimage.inx, + share/extensions/eps_input.inx, share/extensions/epsi_output.inx, + share/extensions/ffmet.inx, share/extensions/ffms.inx, + share/extensions/ffset.inx, share/extensions/ffss.inx, + share/extensions/gimpgrad.inx, share/extensions/grid.inx, + share/extensions/handles.inx, share/extensions/interp.inx, + share/extensions/kochify.inx, share/extensions/kochify_load.inx, + share/extensions/lindenmayer.inx, share/extensions/motion.inx, + share/extensions/pdf_output.inx, share/extensions/ps_input.inx, + share/extensions/radiusrand.inx, share/extensions/randompnt.inx, + share/extensions/randompos.inx, share/extensions/rtree.inx, + share/extensions/sk_input.inx, share/extensions/straightseg.inx, + share/extensions/summersnight.inx, share/extensions/svgz_input.inx, + share/extensions/svgz_output.inx, share/extensions/txt2svg.inx, + share/extensions/wavy.inx, share/extensions/whirl.inx, + share/extensions/wmf_input.inx: + + Marking the user visible strings as translatable. + + * src/extension/dependency.cpp, src/extension/extension.cpp, + src/extension/init.cpp, src/extension/input.cpp, src/extension/output.cpp, + src/extension/parameter.cpp: + + Changed to handle translated .inx files. They will find the data, and + mark the right strings as translated. + + * src/extension/effect.cpp, src/extension/effect.h, src/interface.cpp: + + Changed menu handling to be push instead of pull + +2005-12-02 Carl Hetherington + + * src/dropper-context.cpp: coding style. + * src/sp-namedview.cpp, src/sp-namedview.h, src/desktop.cpp: some + C++-ification of SPNamedView. + +2005-12-01 MenTaLguY + + * src/widgets/desktop-widget.cpp: shuffle status bar around again; + add a grippie so we don't have to care about the corner of the window + getting covered up + +2005-12-01 MenTaLguY + + * src/widgets/icon.cpp: refactored a bit around the icon prerendering + code and added a timer; also kick off the task immediately rather + than waiting for the first expose event + +2005-12-01 MenTaLguY + + * src/widgets/desktop-widget.cpp: + + moved zoom selector away from the right edge so it won't get covered + by window manager decorations + +2005-12-01 MenTaLguY + + * src/help.cpp, src/ui/dialog/aboutbox.h, src/ui/dialog/aboutbox.cpp: + + Moved creation of the splash widget into the about dialog code, + and tweaked the appearance of the dialog in a lot of subtle ways + -- we now use an AspectFrame to constrain the aspect ratio of the + splash view, and also finally get the correct initial size for the + dialog while still allowing it to be arbitrarily resized. + +2005-12-01 Carl Hetherington + + * src/sp-namedview.cpp: coding style. + +2005-12-01 Jon A. Cruz + + * src/widgets/icon.cpp: added idle calback pre-render. + +2005-11-30 MenTaLguY + + * src/ui/dialog/aboutbox.cpp: make 'close' button default widget, + and rename "About" tab to "_Splash" + +2005-11-30 Carl Hetherington + + * src/svg/svg-path.cpp: add missing #include of assert.h for + assert() + * src/dialogs/xml-tree.cpp: fix uninitialised variable + warnings, move some declarations to first use, coding style fixes. + * src/snap.cpp, src/snap.h, src/sp-namedview.cpp: split + snap.{cpp,h} up into snapper.{cpp,h}, grid-snapper.{cpp,h}, + guide-snapper.{cpp,h}. Refactor and simplify. Add another + namedview_free_snap(). + * src/geom.cpp, src/geom.h: cosmetic renaming. + * src/pen-context.cpp: a few minor cleanups to + pen_handle_button_press(). Other snapping cleanups. + * src/draw-context.cpp, src/draw-context.h: split + spdc_endpoint_snap_internal() into two functions. + * src/pencil-context.cpp: snapping cleanups. + * src/ui/widget/unit-menu.cpp: remove definition of a variable + that's just been made static. + +2005-11-26 MenTaLguY + + * src/ui/dialog/aboutbox.cpp, src/ui/dialog/aboutbox.h: + clean up and simplify About dialog; fix memory management (mostly) + +2005-11-25 Robert Crosbie + + * replaced sp_repr_ref with direct cal to Inkscape::GC::anchor + * replaced sp_repr_unref with direct call to Inkscape::GC::release + * replaced sp_repr_set_attr with direct call to repr->setAttribute + +2005-11-24 MenTaLguY + + * src/shortcuts.cpp, src/interface.cpp: prune back shortcuts API in + preparation for configurable key bindings work + +2005-11-24 MenTaLguY + + * src/sp-item.cpp: remedy erroneous initialization of doubles with NULL + +2005-11-24 MenTaLguY + + * src/seltrans.cpp: prune dead wood (sp_sel_trans_handle_click) + +2005-11-24 MenTaLguY + + * src/display/canvas-arena.cpp, src/display/canvas-bpath.cpp, + src/display/canvas-grid.cpp, src/display/guideline.cpp, + src/display/sodipodi-ctrl.cpp, src/display/sodipodi-ctrlrect.cpp, + src/display/sp-canvas-util.cpp, src/display/sp-canvas-util.h, + src/display/sp-ctrlline.cpp, src/display/sp-ctrlquadr.cpp: + + cosmetic renaming + +2005-11-23 Robert Crosbie + + * replaced sp_repr_change_order with direct cal to repr->changeOrder + * replaced sp_repr_add_child with direct call to repr->addChild + * replaced sp_repr_remove_child with direct call to repr->removeChild + +2005-11-23 Peter Moulder + + * src/ui/dialog/align-and-distribute.h, src/ui/dialog/align-and-distribute.cpp: + Add new action ActionRemoveOverlaps, and add new button & two spin buttons + to the Align & Distribute dialog box, to remove overlaps between objects. + * configure.ac: New directory src/removeoverlap. + * src/Makefile.am: Build new library removeoverlap/libremoveoverlap.a. + * src/Makefile_insert: Link against new library removeoverlap/libremoveoverlap.a. + +2005-11-23 Michael Wybrow + + * packaging/osx-app.sh, packaging/macosx/Resources/bin/inkscape: + Include some missing modules required by gnome-vfs and set shell + variables to point to these modules within the OS X app bundle. + Fixes bug #1363390. + +2005-11-21 Michael Wybrow + + * packaging/osx-app.sh: Fix a typo resulting from last change. + +2005-11-18 Michael Wybrow + + * packaging/osx-app.sh: Add libXinerama.1.dylib to the app bundle + since users of OS X 10.3.x will not have this file. + +2005-11-12 Jon Phillips + + * po/it.po po/sr.po po/sr@Latn.po: Fixed these po files so that + Inkscape builds okay. + + +2005-11-12 Ralf Stephan + + * src/ui/view/edit-widget.h, src/ui/view/edit-widget.cpp: + new-gui: made complete statusbar widget, equals old-gui now + * src/widgets/layer-selector.h, src/ui/widget/selected-style.h: + classes have now a constructor with default parameter + * src/ui/widget/zoom-status.cpp: smaller font + +2005-11-12 MenTaLguY + + * src/display/canvas-arena.cpp, src/display/canvas-bpath.cpp, + src/display/canvas-grid.cpp, src/display/guideline.cpp, + src/display/sodipodi-ctrl.cpp, src/display/sodipodi-ctrlrect.cpp, + src/display/sp-canvas-util.cpp, src/display/sp-canvas-util.h, + src/display/sp-canvas.cpp, src/display/sp-canvas.h, + src/display/sp-ctrlline.cpp, src/display/sp-ctrlquadr.cpp: + + Refactor canvas buffer code a little. Hint: if you have two flags + and an invariant that one will be false if the other is true and + vice-versa, you can represent them with a single flag. Fixed + cut-and-paste madness between sp_canvas_buf_ensure_buf and + sp_canvas_clear_buf also. Finally, renamed sp_canvas_buf_ensure_buf + to sp_canvas_prepare_buf. + +2005-11-09 Michael Wybrow + + * src/sp-item.cpp: Call updateRepr before emitting the transformed + signal in sp_item_write_transform. This fixes bug #1303423. + + * packaging/osx-app.sh: Fixes to allow building app bundles on both + OS X 10.4 and earlier versions of the OS without altering the script. + Also, add a note that Inkscape needs to be configured with + --enable-osxapp when building the OS X package. + + * po/nl.po: Fix an "Unmatched closing " warning. + +2005-11-08 Ralf Stephan + + merged with branch CXXIFICATION_VIEW_AND_WIDGET + * src/arc-context.cpp, src/dyna-draw-context.cpp, src/event-context.cpp, + src/file.cpp, gradient-context.cpp, src/inkscape.cpp, src/interface.cpp, + src/rect-context.cpp, src/select-context.cpp, src/seltrans.cpp, + src/sp-namedview.cpp, src/spiral-context.cpp, src/star-context.cpp, + src/verbs.cpp, dialogs/dialog-events.cpp, src/dialogs/layer-properties.cpp, + src/ui/dialog/dialog.cpp, src/widgets/desktop-widget.cpp, + src/widgets/desktop-widget.h: + move gtk code into desktop-widget.cpp, called via desktop + * src/ui/view/Makefile_insert: added files edit-widget-interface.h, + edit-widget.cpp, edit-widget.h + the EditWidget is the Gtkmm version of the SPDesktopWidget + * src/ui/widget/Makefile_insert: added files ruler.cpp, ruler.h, + svg-canvas.cpp, svg-canvas.h, zoom-status.cpp, zoom-status.h + these are widgets part of the EditWidget + * src/file.cpp, src/inkscape.cpp, src/ui/dialog/dialog.cpp, + src/ui/dialog/dialog.h, src/application/application.h, + src/application/application.cpp: + divide code /wrt Application::getNewGui(): if true, it's called by the + Gtkmm application and the inkscape object is meaningless + * src/application/app-prototype.h: + replace UI specific return value of getWindow() with void* + * src/application/editor.cpp, src/application/editor.h: + made Editor a singleton, collect global UI code here that (for Gtk+) + lives in inkscape.cpp and elsewhere + * src/desktop-events.cpp, src/desktop.cpp, src/event-context.cpp, + src/nodepath.cpp, src/seltrans.cpp: + simplify calls to desktop->set_coordinate_status + * src/desktop-handles.cpp, src/desktop-handles.h, + src/extension/internal/ps.cpp, src/widgets/gradient-toolbar.cpp, + src/widgets/toolbox.cpp: + widget is no longer available through desktop + * src/Makefile_insert: added files preferences.h preferences.cpp + src/inkscape.h, src/inkscape.cpp, src/application/editor.cpp: + move preferences handling into preferences.cpp/h + * src/desktop.cpp, src/desktop.h: + use EditWidgetInterface, more cosmetics + * src/desktop.cpp, src/inkview.cpp, src/slideshow.cpp, src/svg-view-widget.cpp, + src/svg-view.cpp, src/svg-view.h, src/ui/view/view.cpp, src/ui/view/view.h: + streamline setDoc()/setDocument() logic + * src/inkview.cpp: include empty func bodies to make linker happy + +2005-11-08 ------------0.43 + +2005-11-06 Ted Gould + + * 0.43pre2 + +2005-11-01 Jon A. Cruz + + * src/io/base64stream.h, src/io/base64stream.cpp: + Applied modified patch 1341198. + +2005-10-31 Jon A. Cruz + + * src/verbs.cpp: + Applied patch from RFE 1247694. + +2005-10-26 Jon A. Cruz + + * share/screens/about.svg: + Trimmed bad lines. Fixed bug 1310742. + +2005-10-24 Ted Gould + + * 0.43pre1 + +2005-10-22 Jon A. Cruz + + * Makefile.mingw, src/io/sys.cpp: + Patch 1334818. + +2005-10-22 Jon A. Cruz + + * src/main.cpp, src/io/sys.cpp: + Updating Win32 parameter filename handling. + +2005-10-22 Michael Wybrow + + * src/connector-context.cpp: Correct two typos. Fixes bug #1333915. + +2005-10-21 Michael Wybrow + + * src/connector-context.cpp: Fix a bug where undoing creation of + new connectors revealed intermediate steps. + + * src/libavoid/connector.cpp, src/libavoid/connector.h, + src/libavoid/makepath.cpp, src/libavoid/static.cpp: + Applied a couple of libavoid fixes. One of which addresses + a possible crash bug. + +2005-10-19 Ted Gould + + * 0.43pre0 + +2005-10-19 Jon A. Cruz + + * inkscape32-16.ico: patch 1323419 + +2005-10-17 Michael Wybrow + + * src/conn-avoid-ref.cpp: Don't pass avoided objects to libavoid + if they have the 'cloned' flag set. Fixes bug #1328401. + +2005-10-17 Jon A. Cruz + + * src/main.cpp, src/io/sys.h, src/io/sys.cpp: + Switched command-line name conversion from filename to locale. + Fixes bug #1250124. + +2005-10-16 Michael Wybrow + + * src/sp-conn-end.cpp: Don't update the repr for the curve while + manually rerouting connector endpoints. This speeds up undo/redo + and allows responsive rerouting with the xml editor window open. + Fixes bug #1315489. + + * po/ca.po: Fix unclosed found in translations. + +2005-10-15 Michael Wybrow + + * src/isnan.h: Update to allow compilation on OSX 10.4. + + * src/connector-context.cpp, src/connector-context.h, + src/tools-switch.cpp: Allow double-clicking on connectors + in the selector tool to swap to the connector tool. + +2005-10-14 Jon A. Cruz + + * share/palettes/Makefile.am, share/palettes/Tango-Palette.gpl: + Adding the Tango palette. + +2005-10-13 MenTaLguY + + * share/screens/about.svg: New copy for about dialog; did some + vector clean-up and re-enabled the coffee stains. + +2005-10-10 Michael Wybrow + + * src/sp-conn-end-pair.cpp, src/sp-conn-end-pair.h: + Reroute connector lines if the object itself is moved or + transformed. Previously a routed line would not unroute if it + was moved away from the blocking objects. Fixes bug #1303493. + +2005-10-07 Michael Wybrow + + * packaging/macosx/Resources/script, src/path-prefix.h: + Don't assume the OSX app bundle will be named "Inkscape.app". + This caused things like tool icons to disappear if the app + bundle was renamed, e.g., to "Inscape-0.42.2.app". + Fixes bug #1289648. + +2005-10-06 Michael Wybrow + + * src/sp-conn-end-pair.cpp: Fix a bug where connectors could + sometimes be given strange routes if there was a transform on + either of the objects that the connector was attached to. + + * src/conn-avoid-ref.cpp, src/sp-conn-end.cpp: Add a call to + sp_document_ensure_up_to_date before checking bounding boxes + in response to a transform signal. This is because some + objects (e.g., text) will not give the correct bbox until its + update function has been called and its internal representation + has been updated. This fixes bug #1303523. + + * src/dialogs/display-settings.cpp, src/dialogs/display-settings.h: + Restore the Connector tool preferences tab. Use same ordering + for tools as on the toolbar. Add the standard selection cue + option to the connector tool preferences. Fixes bug #1303360. + +2005-10-05 Michael Wybrow + + * packaging/osx-app.sh: Include locale files in the OSX package and + a couple of minor updates for building packages on OSX 10.4.x. + + * packaging/macosx/Resources/bin/inkscape: Fix a problem in setting + LANG to the current OSX language before launching Inkscape. + With this fix, the Inkscape app bundle will obey the user's + language setting in the system preferences on OSX. + +2005-09-30 Ralf Stephan + + * src/desktop.*, src/widget/desktop-widget.cpp: + make empty destructor, fixes #1291009 + +2005-09-29 Michael Wybrow + + * Info.plist.in: Associate .svgz files with Inkscape on OSX. + Fixes bug #1307083. + +2005-09-27 MenTaLguY + + * src/gc-anchored.h: emphasize initial refcount + + * src/desktop.h, src/svg-view-widget.cpp, src/ui/view/view-widget.cpp, + src/ui/view/view.cpp, src/ui/view/view.h, + src/widgets/desktop-widget.cpp: + + Move _whole_ UI::View::View hierarchy over to the garbage collector + and fix anchor imbalances; you can't do this piecemeal. + +2005-09-23 Ben Fowler + + * autogen.sh: Cleanup error message. + +2005-09-20 Carl Hetherington + + * src/file.cpp, src/file.h, src/help.cpp: don't replace empty + desktops with help files / tutorials. Fixes 1249067. + +2005-09-17 Ralf Stephan + + * src/jabber_whiteboard/typedefs.h: + gcc4 needs more const correctness, fixes #1294298 + +2005-09-17 Ralf Stephan + + * src/desktop.h, src/desktop.cpp, src/interface.cpp, + src/dialogs/layer-properties.cpp, src/ui/view/view.cpp, + src/widgets/desktop-widget.cpp: + correcting old and new oversights, fixes #1290982 + +2005-09-15 Peter Moulder + + * src/xml/repr-util.cpp (sp_repr_set_double): Split into two + functions (sp_repr_set_svg_double, sp_repr_set_css_double) + according to whether or not an exponent is allowed. Update callers. + (sp_repr_set_double_default): Remove this unused function. + +2005-09-15 Carl Hetherington + + * src/object-edit.cpp: fix idiotic bug introduced in previous commit. + +2005-09-14 Carl Hetherington + + * src/knot.cpp, src/knotholder.cpp: coding style. + +2005-09-13 Ralf Stephan + + * src/desktop.h, src/desktop.cpp, src/svg-view.h, src/svg-view.cpp, + src/ui/view/view.h, src/ui/view/view.cpp, src/ui/view/edit.h: + View::setDocument() did not call same function in subclass + * src/widgets/select-toolbar.cpp: removed usage of SP_DT_WIDGET + * src/desktop.cpp: removed last sp_desktop_* function names + +2005-09-13 Carl Hetherington + + * src/object-edit.cpp: Add some comments. Minor refactoring. + Snap points when editing rectangles; partial fix for bug 1282399. + + * packaging/win32/inkscape.nsi: Correct spelling of associations + and associated; fix for bug 1283916. + +2005-09-12 Jon A. Cruz + + * src/dialogs/iconpreview.cpp, src/dialogs/iconpreview.h, + src/widgets/icon.cpp: + Icon preview now toggles between selection or whole document. + Fixes REF #1281883. + +2005-09-12 Ralf Stephan + + * src/widgets/ruler.cpp: fixed precision problem (bug #1242995) + +2005-09-12 Peter Moulder + + * src/libnrtype/Layout-TNG-Compute.cpp (Calculator::_measureUnbrokenSpan): + Fix line breaking for [supposedly] non-breaking whitespace characters. + +2005-09-11 Ralf Stephan + + * po/nl.po: replaced all instances of "verkleint" with "verkleind" + (bug #1277695) + +2005-09-10 Jon A. Cruz + + * src/preferences-skeleton.h, src/dialogs/iconpreview.cpp: + Made icon preview sizes configurable. Fixes REF #1281885. + +2005-09-08 Carl Hetherington + + * src/object-edit.cpp: Coding style in SPRect portion. Add + Emacs/vim mode blocks. + +2005-09-08 Ralf Stephan + + * src/desktop.cpp, src/ui/view/view.cpp: + removed placement new signal construction + * src/desktop.cpp: selection is no longer anchored + * src/desktop.cpp, src/desktop.h: further cleanup + * src/main.cpp: minor changes in doxygen main page + +2005-09-08 MenTaLguY + + * src/xml/document.h, src/xml/session.h, src/xml/simple-session.cpp, + src/xml/simple-session.h: + + Add Session and Document createElementNode, createCommentNode, + and createTextNode methods + +2005-09-06 Ralf Stephan + + * src/desktop-handles.h, src/desktop-handles.cpp: + added macros SP_DT_MSGSTACK/NAMEDVIEW/WIDGET, moved last + macros from desktop.h + * src/desktop.h src/desktop.cpp, src/sp-namedview.h, + src/sp-namedview.cpp: + moved default_metric and default_unit into namedview + * src/desktop.h src/desktop.cpp, src/widgets/desktop-widget.h, + src/widgets/desktop-widget.cpp: + moved window member into desktop widget + * src/dialogs/clonetiler.cpp, src/dialogs/color-picker.cpp, + src/dialogs/desktop-properties.cpp, src/dialogs/dialog-events.cpp , + src/dialogs/display-settings.cpp, src/dialogs/export.cpp, + src/dialogs/stroke-style.cpp, src/dialogs/swatches.cpp, + src/dialogs/transformation.cpp, src/dropper-context.cpp, + src/extension/internal/ps.cpp, src/gradient-context.cpp, + src/jabber_whiteboard/callbacks.cpp, + src/jabber_whiteboard/chat-handler.cpp, + src/jabber_whiteboard/message-processors.cpp, + src/jabber_whiteboard/message-queue.cpp, + src/jabber_whiteboard/session-manager.cpp, + src/path-chemistry.cpp, src/satisfied-guide-cns.cpp, + src/sp-text.cpp, src/text-chemistry.cpp, + src/trace/potrace/inkscape-potrace.cpp, + src/trace/trace.cpp, src/ui/dialog/align-and-distribute.cpp: + removed dependency on desktop.h + * src/arc-context.cpp, src/desktop-events.cpp, src/inkscape.cpp, + src/interface.cpp, src/nodepath.cpp, src/rect-context.cpp, + src/select-context.cpp, src/seltrans.cpp, src/spiral-context.cpp, + src/star-context.cpp, src/text-context.cpp, src/ui/dialog/dialog.cpp, + src/widgets/select-toolbar.cpp, src/widgets/toolbox.cpp: + minor adaptation due to the above changes + * src/ui/dialog/session-player.cpp: didn't #include config.h + +2005-09-06 Michael Wybrow + + * doc/keys.html, doc/keys.xml, share/screens/keys.svg, + src/shortcuts.cpp: + Add keyboard shortcuts for the connector tool -- Ctrl+F2 and 'o'. + +2005-09-05 Ralf Stephan + + * src/document.cpp, src/draw-anchor.cpp, src/knotholder.cpp, + src/main.cpp, src/object-ui.cpp, src/selcue.cpp, + src/sp-marker.cpp, src/sp-root.cpp, src/sp-shape.cpp, + src/sp-star.cpp, src/sp-symbol.cpp, src/sp-tspan.cpp, + src/dialogs/docker.cpp, src/dialogs/extensions.cpp, + src/dialogs/text-edit.cpp, src/dialogs/tiledialog.cpp, + src/extension/system.cpp, src/widgets/gradient-vector.cpp, + src/jabber_whiteboard/session-file-player.cpp, + src/widgets/paint-selector.cpp, src/widgets/sp-widget.cpp, + src/widgets/spw-utilities.cpp, src/extension/implementation/script.cpp, + src/ui/dialog/transformation.cpp, src/seltrans.h, + src/widgets/sp-widget.h: + removed dependency on desktop.h + * src/select-context.cpp, src/tools-switch.cpp, + src/dialogs/display-settings.cpp, src/dialogs/fill-style.cpp, + src/dialogs/object-properties.cpp, src/dialogs/clonetiler.cpp: + added dependencies because of above changes + +2005-09-04 Kees Cook + + * TRANSLATORS, Makefile.am, src/verbs.cpp, src/help.cpp, + src/ui/dialog/aboutbox.h, src/ui/dialog/aboutbox.cpp, + src/menus-skeleton.h, src/ui/dialog/Makefile_insert: + Implemented AboutDialog following the Gnome style. + * packaging/win32/inkscape.nsi: added quotes around execution name. + +2005-09-04 Ralf Stephan + + * src/desktop.cpp, src/dropper-context.cpp, src/forward.h, + src/interface.cpp, src/main.cpp, src/sp-anchor.cpp, + src/sp-text.cpp, src/splivarot.cpp, src/svg-view-widget.cpp, + src/svg-view-widget.h, src/svg-view.h, src/extension/effect.h, + src/extension/implementation/plugin-link.h, + src/jabber_whiteboard/session-manager.cpp, + src/ui/dialog/dialog.cpp, src/ui/view/edit.h, + src/ui/view/view-widget.cpp, src/ui/view/view-widget.h, + src/ui/view/view.cpp, src/ui/view/view.h: + minor edits to completely remove SPView identifier, and some + dependencies + +2005-09-04 Michael Wybrow + + * src/sp-conn-end-pair.cpp: Fix a crash bug when undoing connectors + on Linux x86 where we were calling a signal destructor. + + * src/io/sys.cpp: Build fix - conditionally include + if using glib 2.6.0 or greater, since it is not available in earlier + versions. + +2005-09-04 Ralf Stephan + + * src/svg-view-widget.h, src/svg-view-widget.cpp, src/Makefile_insert: + separated SPSVGViewWidget from SPSVGView + * src/desktop.h, src/svg-view.h, src/ui/view/edit.h, + src/ui/view/view-widget.h, src/ui/view/view.h, + src/widgets/desktop-widget.h, src/desktop.cpp, + src/svg-view.cpp, src/ui/view/view-widget.cpp, + src/ui/view/view.cpp, src/widgets/desktop-widget.cpp: + moved SPDesktop from GObject to C++/sigc++ + * src/forward.h: + removed SP_DESKTOP*, SP_SVG_VIEW* macros and dependencies + * src/widgets/layer-selector.h, src/widgets/layer-selector.cpp: + changed to sigc++ but disabled call + * src/desktop-events.cpp: removed desktop_enter_notify() + * src/sp-anchor.cpp: removed handling of mouse over/out + * src/helper/action.h, src/sp-use.cpp: added missing dependency + * src/arc-context.cpp, src/desktop-affine.cpp, src/desktop-events.cpp, + src/desktop-handles.cpp, src/dyna-draw-context.cpp, + src/event-context.cpp, src/file.cpp, src/gradient-context.cpp, + src/gradient-drag.cpp, src/help.cpp, src/inkscape.cpp, + src/inkview.cpp, src/interface.cpp, src/knot.cpp, + src/knotholder.cpp, src/node-context.cpp, src/nodepath.cpp, + src/object-ui.cpp, src/path-chemistry.cpp, src/rect-context.cpp, + src/rubberband.cpp, src/satisfied-guide-cns.cpp, + src/select-context.cpp, src/selection-chemistry.cpp, + src/seltrans.cpp, src/shortcuts.cpp, src/slideshow.cpp, + src/sp-anchor.cpp, src/sp-flowtext.cpp, src/sp-namedview.cpp, + src/sp-text.cpp, src/spiral-context.cpp, src/splivarot.cpp, + src/star-context.cpp, src/text-context.cpp, src/text-editing.cpp, + src/tools-switch.cpp, src/verbs.cpp, src/zoom-context.cpp, + src/dialogs/clonetiler.cpp, src/dialogs/desktop-properties.cpp, + src/dialogs/dialog-events.cpp, src/dialogs/export.cpp, + src/dialogs/filedialog.cpp, src/dialogs/iconpreview.cpp, + src/dialogs/layer-properties.cpp, src/dialogs/stroke-style.cpp, + src/dialogs/transformation.cpp, src/dialogs/xml-tree.cpp, + src/extension/effect.cpp, src/extension/implementation/script.cpp, + src/extension/internal/grid.cpp, src/extension/internal/ps.cpp, + src/helper/window.cpp, src/ui/dialog/dialog.cpp, + src/ui/widget/imageicon.cpp, src/widgets/gradient-toolbar.cpp, + src/widgets/layer-selector.cpp, src/widgets/select-toolbar.cpp, + src/widgets/toolbox.cpp: + minor adaptations due to the above changes + * src/desktop-events.h: removed dependencies + * src/selection.cpp: improved doxygen documentation + +2005-09-04 Michael Wybrow + + * src/connector-context.cpp: Fix a bug where a data structure was + not being freed, triggering an assertion failure and Inkscape to + crash sometimes when the connector tool context was switched. + +2005-09-03 Aaron Spike + + * src/node-context.cpp, src/livarot.cpp: Fixing a problem where node + adding and curve dragging operate on fills. A special thank you to + Simon Budig of GIMP fame for working with me and giving very + thorough explanations of his curve dragging code. + +2005-09-03 Michael Wybrow + + * src/libavoid/connector.cpp, src/libavoid/connector.h: Autoroute + connectors while they are being drawn in the connector context. + + * src/sp-conn-end.cpp: Fix a bug where connectors attached to shapes + were not always getting updated. Their path was sometimes thought + to be valid even when it was not. + +2005-09-02 Michael Wybrow + + * src/sp-conn-end.cpp: Fix a bug where connectors not attached to + shapes were not updating correctly if an object was dropped on + their path. + +2005-09-01 Michael Wybrow + + * src/sp-conn-end.cpp, src/sp-conn-end.h, src/sp-conn-end-pair.cpp, + src/sp-conn-end-pair.h, src/sp-path.cpp, src/libavoid/graph.cpp, + src/libavoid/incremental.cpp: + + Connectors now automagically reroute as a result of any 'avoided' + object being placed on their path. They also update to better + paths when blocking shapes are removed. + + * src/connector-context.cpp: Update TODO list. Only show endpoints + and allow manipulation of paths marked as connectors. + + * src/libavoid/connector.cpp, src/libavoid/connector.h: Connectors + with invalid paths can now notify other code via a callback, + rather than just setting a boolean flag. + + * src/conn-avoid-ref.cpp: Fix an obscure crash bug in the connector + routing code where we were still using a freed data structure. + +2005-08-31 Michael Wybrow + + * src/conn-avoid-ref.cpp, src/conn-avoid-ref.h: Use the correct + coordinate system when passing shape geometry to libavoid. + Add a small amount of buffer space around objects. + + * src/attributes-test.cpp, src/attributes.cpp, src/attributes.h, + src/path.cpp: Add code to handle the "inkscape:connector-type" + attribute. + + * src/sp-conn-end-pair.cpp, src/sp-conn-end-pair.h: Store information + about type paths, to determine whether they are connectors. Keep + a reference to the libavoid representation if necessary. Add code + to call libavoid to get a path for a connector. + + * src/sp-conn-end.cpp: Call the connector routing code when connector + ends are moved. Move connector endpoints rather than stretching + when adjusting to draw to shape edge. + + * src/libavoid/connector.cpp, src/libavoid/connector.h: Make the + connector references aware of their own initialisation state. + + * src/connector-context.cpp: Update TODO list. Update for other + changes. Fix a bug where multi-segment connectors had a solid + black fill while being dragged. + + * src/display/curve.cpp, src/display/curve.h: Add a function to + simply move the two endpoints of a curve. + +2005-08-30 Michael Wybrow + + * src/conn-avoid-ref.cpp, src/libavoid/connector.cpp, + src/libavoid/graph.cpp, src/libavoid/makepath.cpp, + src/libavoid/shape.cpp, src/libavoid/vertices.cpp, + src/libavoid/vertices.h, src/libavoid/visibility.cpp: + + Use a better system for unique IDs within libavoid. This properly + addresses a hack in SPAvoidRef that was unsafe on amd64 machines. + + * configure.ac: Add the src/libavoid subdir. + +2005-08-29 Michael Wybrow + + * src/attributes.cpp, src/connector-context.cpp, src/sp-item.cpp: + Use "inkscape:connector-avoid" instead of "inkscape:avoid". + +2005-08-29 Michael Wybrow + + * src/libavoid/timer.cpp: Remove some code assuming a fixed size for + timer types. + +2005-08-29 Michael Wybrow + + * src/connector-context.cpp: Fix a problem where the context didn't + notice the current selection when it was entered. Also, fix a + problem where connectors disappeared for a moment when an endpoint + was clicked (for rerouting), but before the mouse was moved. + +2005-08-29 David Yip + + * src/ui/dialog/whiteboard-connect.{cpp,h}, + src/ui/dialog/whiteboard-sharewithchat.{cpp,h}: + Improved widget layout (switched to Gtk::Table) + + * src/jabber_whiteboard/session-manager.cpp: + Fixed crash that occurred when connecting via SSL to a Jabber + server that does not support SSL + +2005-08-28 Michael Wybrow + + * src/Makefile_insert, src/attributes-test.cpp, src/attributes.cpp, + src/attributes.h, src/conn-avoid-ref.cpp, src/conn-avoid-ref.h, + src/forward.h, src/sp-item.cpp, src/sp-item.h: + + Add code that handles the "inkscape:avoid" attribute, used to mark + whether an item should be avoided for the purposes of routing + connectors. This code also calls libavoid when an 'avoided' + item is moved/transformed. + + * src/connector-context.cpp, src/connector-context.h, + src/widgets/toolbox.cpp: + + Add a couple of buttons to the connector context's toolbar to + allow selected objects to be marked as avoided or ignored for the + purpose of connector routing. + + * src/libavoid/debug.h, src/libavoid/geomtypes.h, + src/libavoid/polyutil.cpp, src/libavoid/polyutil.h, + src/libavoid/shape.cpp: + + Misc fixes: turn off debugging output, put types in the Avoid + namespace, and add an assertion for a special case that can + cause problems. + +2005-08-28 Michael Wybrow + + * share/icons/icons.svg: Add a couple of icons for the connector + context toolbar. + +2005-08-27 Michael Wybrow + + * src/Makefile.am, src/Makefile_insert, src/libavoid/*: + Add libavoid code, the library that does all the path planning + work for autorouting connectors. + +2005-08-27 Michael Wybrow + + * src/Makefile_insert: Remove a reference to the previously moved + src/desktop-widget.h. This wasn't breaking the build, but was + stopping me from generating tags files. + +2005-08-25 Ralf Stephan + + * src/ui/view/edit.h, src/ui/view/view.h, src/ui/view/view.cpp, + src/ui/view/view-widget.h, src/ui/view/view-widget.cpp, + src/widgets/desktop-widget.h, src/svg-view.h, src/desktop.cpp: + separated SPViewWidget from SPView + * src/connector-context.cpp, src/dyna-draw-context.cpp, + src/file.cpp, src/gradient-context.cpp, src/knot.cpp, + src/node-context.cpp, src/nodepath.cpp, src/path-chemistry.cpp, + src/pen-context.cpp, src/pencil-context.cpp, src/rect-context.cpp, + src/selection-chemistry.cpp, src/spiral-context.cpp, + src/splivarot.cpp, src/star-context.cpp, src/text-chemistry.cpp, + src/text-context.cpp, src/verbs.cpp, src/dialogs/display-settings.cpp, + src/dialogs/layer-properties.cpp, src/dialogs/find.cpp, + src/dialogs/clonetiler.cpp, src/trace/trace.cpp, + src/trace/potrace/inkscape-potrace.cpp: + all these files relied on a dependency in view.h to include + code for MessageStack and/or MessageContext which is now removed + * dialogs/desktop-properties.cpp: improved doxygen documentation + +2005-08-25 Ralf Stephan + + * src/desktop.cpp, src/widgets/desktop-widget.h, + src/widgets/desktop-widget.cpp: + abstracted out all Gtk+ calls from SPDesktop into SPDesktopWidget + * src/Doxyfile, src/main.cpp, src/desktop.cpp: + improved doxygen documentation + +2005-08-25 Michael Wybrow + + * src/connector-context.cpp, src/connector-context.h: + Change the connector context to use Inkscape's standard selection + mechanism. Show connector endpoint handles for single connectors + in the selection. This is the proposed interaction changes as + discussed on the mailing list. See the post there for a greater + description of the change. + +2005-08-24 Ralf Stephan + + * src/widgets/desktop-widget.h, src/widgets/desktop-widget.cpp: + separated SPDesktopWidget from SPDesktop + * src/desktop-widget.h: removed + * src/toolbox.cpp, src/toolbox.h, src/select-toolbar.cpp, + src/select-toolbar.h, src/gradient-toolbar.cpp, + src/gradient-toolbar.h: moved into src/widgets + * src/desktop.h, src/desktop.cpp, src/desktop-events.cpp, + src/verbs.cpp, src/Makefile_insert, src/widgets/Makefile_insert, + src/arc-context.cpp, src/dyna-draw-context.cpp, + src/gradient-context.cpp, src/rect-context.cpp, + src/select-context.cpp, src/spiral-context.cpp, + src/star-context.cpp, src/interface.cpp, src/seltrans.cpp: + adapted following SPDesktopWidget separation + +2005-08-24 David Yip + + * src/jabber_whiteboard/session-manager.{cpp.h}, + src/jabber_whiteboard/callbacks.cpp, + src/ui/dialog/whiteboard-connect.{cpp,h}: + added support for XMPP over SSL to Inkboard + +2005-08-22 Ralf Stephan + + * src/dialogs/desktop-properties.cpp, src/dialogs/display-settings.cpp: + both dialogs are now unresizable (bug #1237865) + * src/main.cpp: enhanced doxygen main page + +2005-08-21 Michael Wybrow + + * packaging/osx-app.sh: Added a command line option which allows + the executable and bundled dylibs to be stripped, significantly + reducing the package size. + +2005-08-20 Ralf Stephan + + * src/desktop-style.cpp: fixed bug 1247989: nonstroked objects are + no longer counted in stroke_average_width() + * src/Doxyfile: added 3 more files + * src/main.cpp: introduced doc hierarchy on doxygen main page + * src/desktop-style.cpp: improved doxygen documentation + +2005-08-20 Michael Wybrow + + * src/connector-context.cpp, src/connector-context.h: + Rework connector context to extend SPEventContext instead of + SPDrawContext, and remove most of the borrowed draw context + code. + +2005-08-20 Michael Wybrow + + * src/menus-skeleton.h: correct the verb for "Select All In All Layers" + since it was just showing a verb error in the menu. + +2005-08-19 Kees Cook + + * autogen.sh, tools-version.sh, distro: report Ubuntu correctly, detect + and reject unsafe automake versions (1.9.0 -> 1.9.6). + +2005-08-19 Michael Wybrow + + * src/dialogs/display-settings.cpp: + Align the "Oversample bitmaps" option in the preferences + dialog with all the other options. + +2005-08-18 Michael Wybrow + + * src/Makefile_insert: Added connector-context.{cpp,h} + + * src/connector-context.cpp, src/connector-context.h: New code for + the connector context. Handles the interaction of creating and + modifying connectors. + + * src/sp-conn-end.cpp, src/sp-conn-end.h: Added sp_conn_adjust_path + for adjusting the path of connectors to the edge of shapes, and + sp_conn_end_detach to detach a connector endpoint from a shape. + Also, when there is only a single shape attached to a connector + and it is moved, then reroute the connector leaving its unattached + endpoint where it is, rather than just moving the whole thing with + the shape. + + * src/preferences-skeleton.h, src/toolbox.cpp, src/tools-switch.cpp, + src/tools-switch.h, src/verbs.cpp, src/verbs.h, + src/dialogs/display-settings.cpp, src/dialogs/display-settings.h: + + Enable the connector context. Give it a preferences tab, toolbox, + icon, etc. Also, correct some vim modelines. + + * src/display/sp-canvas.cpp: Allow enter and leave events to be generated + for canvas items when mouse buttons are depressed. + + * src/pixmaps/cursor-connector.xpm: A cursor for connector context. + +2005-08-18 Jon A. Cruz + + * src/knot.cpp: Corrected type conflict for crash bugs. + +2005-08-18 Ralf Stephan + + * src/Doxyfile: added 4 more files + * src/extension/implementation/plugin-link.h, + src/extension/internal/gimpgrad.cpp: improved doxygen documentation + +2005-08-16 Ralf Stephan + + * src/desktop.h, src/desktop.cpp: replaced gboolean with bool + * src/display/curve.cpp: made is_moveto() inline + * src/knot.cpp, src/extension/extension.cpp, src/helper/action.cpp: + added editor footer + * src/desktop.h, src/desktop.cpp, src/knot.cpp, src/sp-gradient.cpp, + src/display/curve.cpp, src/extension/extension.cpp, + src/extension/implementation/plugin.h, + src/extension/implementation/plugin.cpp, + src/extension/internal/gimpgrad.cpp, src/helper/action.cpp: + improved doxygen documentation + +2005-08-14 MenTaLguY + + * src/widgets/layer-selector.cpp: quick fix for crash bug when + deleting unnamed layer [bug 1255843] + +2005-08-14 Michael Wybrow + + * packaging/macosx/ScriptExec/main.c: Allow the user to ignore the + automatic fixing of the fontconfig problem and fix the problem + manually. Don't pop up the dialog again in this case when they + relaunch Inkscape. + +2005-08-13 Ralf Stephan + + * src/menus-skeleton.h: fixed cvs bug where, in the default menus.xml, + given submenus didn't have correct names, so translation on + non-English systems was missed. + +2005-08-13 Michael Wybrow + + * packaging/macosx/Resources/script, packaging/macosx/ScriptExec/main.c: + + Fix for the fontconfig cache problem on OS X 10.4. The first time + Inkscape is launched on 10.4 machines, after checking X11 is available, + a dialog is brought up informing users of the fontconfig problem. The + dialog has a button to run fc-cache as root. If chosen, an OS X + authentication dialog in launched and fc-cache is run following the + authentication. A file is stored in ~/.inkscape to mark that fc-cache + has been run. + +2005-08-11 Ralf Stephan + + * src/sp-gradient.cpp,src/sp-gradient-fns.h,src/event-context.h, + src/event-context.cpp: replaced gboolean with bool + * src/document-undo.cpp: added editor footer + * src/sp-gradient.cpp, src/desktop.cpp, src/document.h, + src/document.cpp, src/document-undo.cpp, src/event-context.h, + src/event-context.cpp, src/selection.h: + improved doxygen documentation + +2005-08-10 David Yip + + * src/Makefile_insert: added composite-undo-stack-observer.{cpp,h} + + * src/document.{cpp.h}, + src/document-undo.cpp, src/document-private.h: + added hooks for undo stack observer + + * src/jabber_whiteboard/Makefile_insert: added new classes + + * src/jabber_whiteboard/callbacks.cpp: moved document initialization actions + here (not the best idea, admittedly...) + + * src/jabber_whiteboard/connection-establishment.cpp, + src/jabber_whiteboard/session-manager.*, + src/jabber_whiteboard/chat-handler.cpp: updated to work with new listeners + + * src/jabber_whiteboard/message-contexts.cpp, + src/jabber_whiteboard/message-handler.*, + src/jabber_whiteboard/message-tags.*, + src/jabber_whiteboard/defines.h: new message types (TODO: trim out dead + types) + + * src/jabber_whiteboard/message-queue.*, + * src/jabber_whiteboard/message-node.h: made MessageNode capable of + representing more message types, as required by callbacks.cpp + and new commit model + + * src/jabber_whiteboard/message-utilities.*: new utilities, although + this entire class should be going bye-bye soon (its main tasks have been + taken over by SerializerNodeObserver) + + * src/jabber_whiteboard/node-tracker.*: removal of node-level locks + + * src/jabber_whiteboard/node-utilities.*: removal of unnecessary methods; + this class should also be removed soon + + * src/jabber_whiteboard/session-file-selector.cpp: miscellaneous tweaks + + * src/jabber_whiteboard/typedefs.h: new type definitions to handle the new + commit model (TODO: prune unnecessary types) + + * src/xml/event.cpp: small hack to get Inkboard working (shouldn't be + there, but I'm still learning my way around XML::Node and + XML::Session...help welcome) + + * src/undo-stack-observer.h: interface for classes that watch undo, redo, + and undo log commit events + + * src/composite-undo-stack-observer.*: similar to CompositeNodeObserver; + combines multiple undo stack observers + + * src/jabber_whiteboard/serializer-node-observer.*: XML::Event serializer + + * src/jabber_whiteboard/deserializer.*: XML::Event deserializer + + * src/jabber_whiteboard/tracker-action-observer.*: simple observer to + watch for added and removed nodes in undo/redo actions (put aside for + now) + + * src/jabber_whiteboard/undo-stack-observer.*: Inkboard's undo stack + observer implementation + +2005-08-10 Ralf Stephan + + * src/main.cpp: introduced doxygen doc main page with links + +2005-08-09 Ralf Stephan + + * src/Doxyfile: added 5 more files + * src/display/curve.h, src/display/curve.cpp, src/knot.cpp, + src/dialogs/export.cpp: replaced gboolean with bool + * src/display/curve.cpp: removed sp_curve_finish() as it is nowhere + called, made sp_curve_ensure_space() static + * src/sp-object.cpp, src/sp-item.cpp, src/libnr/n-art-bpath.h, + src/libnr/nr-path-code.h, src/ui/view/view.cpp, src/dialogs/export.cpp, + src/display/bezier-utils.cpp, src/display/curve.h, + src/display/curve.cpp, src/knot.h, src/knot.cpp: + improved doxygen documentation + +2005-08-08 MenTaLguY + + * README.txt, README: make autotools happy + +2005-08-06 MenTaLguY + + * Makefile.am, HACKING, HACKING_de, HACKING_fr, HACKING_it, + HACKING.txt, HACKING.de.txt, HACKING.fr.txt, HACKING.it.txt, + README, README_ca, README_de, README_fr, README_it, + README.txt, README.ca.txt, README.de.txt, README.fr.txt, README.it.txt: + + saner filenames + +2005-08-06 MenTaLguY + + * src/xml/Makefile_insert, src/xml/log-builder.cpp, + src/xml/log-builder.h, src/xml/simple-session.cpp, + src/xml/simple-session.h: + + Implement XML::LogBuilder class and use it from XML::SimpleSession. + +2005-08-06 MenTaLguY + + * src/xml/event.h, src/xml/event.cpp, src/xml/event-fns.h: + rejigger the way XML event logs are handled, based on NodeObservers + +2005-08-06 MenTaLguY + + * src/xml/simple-session.cpp: minor formatting cleanups + +2005-08-06 Ted Gould + + * src/interface.cpp, src/verbs.cpp, src/verbs.h: + + Adding in a hash table for Verb ID lookups. This makes searching for them + in the dynamic menus much faster. + +2005-08-06 Ralf Stephan + + * src/sp-offset.cpp: + removed a dependency, made refresh_offset_source() static + * src/svg-view.cpp, src/svg-view.h, src/sp-spiral.cpp, src/sp-spiral.h: + replaced gboolean with bool + * src/sp-offset.cpp, src/sp-root.cpp, src/sp-stop.h, src/sp-spiral.h, + src/sp-spiral.cpp, src/svg-view.h, src/svg-view.cpp, src/style.cpp: + improved doxygen documentation + +2005-08-05 MenTaLguY + + * inkscape.spec.in: include translated manpages + +2005-08-05 Michael Wybrow + + * po/nl.po: fix a typo: close a bold tag. + +2005-08-03 David Yip + + * src/jabber_whiteboard/typedefs.h: + fixed incorrect template specialization syntax, + removed duplicate definitions (oops...) + + * src/gc-alloc.h: + removed explicit keyword from allocator constructors, as it is + necessary to allow implicit conversion for rebinding. Some + containers in the libstdc++ in GCC 3.4.x require this, such as anything + using the standard library's red-black tree implementation -- + std::set, std::map, std::multimap + +2005-08-03 Ralf Stephan + + * src/pen-context.cpp: made sp_pen_context_root_handler static + * src/snap.h: removed getSnapToBBox() declaration + * src/sp-stop.h: removed three dependencies + * src/Doxyfile: added further 3 files + * src/object-hierarchy.cpp, src/pen-context.h, src/pen-context.cpp, + src/pencil-context.h, src/pencil-context.cpp, src/snap.h, + src/snap.cpp, src/sp-stop.h, src/sp-gradient.h, src/sp-gradient.cpp, + src/sp-linear-gradient.h, src/sp-radial-gradient.h: + improved doxygen documentation + +2005-08-03 David Yip + + * src/jabber_whiteboard/Makefile_insert, + src/jabber_whiteboard/message-handler.cpp, + src/jabber_whiteboard/empty.cpp: + fixing some build issues (Apple's ar doesn't like creating + archives with an empty member list, so empty.cpp is a null + placeholder to be used as the sole member in the jabber_whiteboard + archive in the event that a user does not wish to enable + Inkboard) + +2005-08-02 Bryce Harrington + + * src/ui/dialog/*.*: Update copyrights + + * doc/WISHLIST: s/Sodipodi/Inkscape/ + + * src/desktop.cpp: Rename SPView to Inkscape::UI::View::View + + * changing include file syntax from "" to <> where appropriate + + * Changing copyrights to be consistent + +2005-08-03 David Yip + + * src/menus-skeleton.h: + added WITH_INKBOARD ifdef to prevent Inkboard options from being + compiled into the menu skeleton if the Inkboard code is not enabled + +2005-08-03 Michael Wybrow + + * src/display/curve.cpp: Correctly free an array with "delete []". + +2005-08-02 David Yip + + * src/jabber/whiteboard/node-tracker.cpp: + removed unnecessary anchoring of XML::Nodes in XMLNodeTracker + +2005-08-02 David Yip + + * src/jabber_whiteboard/typedefs.h: + moved back to GC::Alloc from traceable_allocator + + * src/jabber_whiteboard/node-tracker.cpp: + fixed anchor-release problem with XML::Nodes in XMLNodeTracker + +2005-08-01 MenTaLguY + + * src/gc.cpp, src/gc-core.h: Hans says it's okay to use + GC_malloc_atomic_uncollectable + +2005-08-01 MenTaLguY + + * src/gc-alloc.h: fix improper allocation size + +2005-08-01 David Yip + + * src/jabber_whiteboard/message-handler.cpp: removed some + debug output + + * src/dialogs/whiteboard-sharewithchat.cpp: removed some excess + debugging code + + * src/jabber_whiteboard/session-manager.cpp: removed + redundant if (x == NULL) tests surrounding delete + +2005-08-01 David Yip + + * src/ui/icons.cpp, src/ui/stock-items.cpp, src/ui/stock.cpp, + src/ui/stock.h: + added Inkboard UI stock items + + * src/dialogs/whiteboard*: + old C/Gtk Inkboard dialogs for collecting user input necessary + to establish Jabber connections and Inkboard sessions (they're + still used in some parts of the Inkboard code) + + * src/Makefile.am, src/Makefile_insert, src/desktop.cpp, + src/desktop.h, src/document.cpp, src/file.cpp, src/file.h, + src/menus-skeleton.h, src/verbs.cpp, src/verbs.h: + added necessary UI code to access Inkboard functions + + * src/jabber_whiteboard/Makefile_insert, + src/jabber_whiteboard/buddy-list-manager.*, + src/jabber_whiteboard/callbacks.*, + src/jabber_whiteboard/chat-handler.*, + src/jabber_whiteboard/connection-establishment.*, + src/jabber_whiteboard/defines.h, + src/jabber_whiteboard/error*, + src/jabber_whiteboard/internal-constants.*, + src/jabber_whiteboard/invitation-confirm-dialog.*, + src/jabber_whiteboard/jabber-handlers.*, + src/jabber_whiteboard/makefile*, + src/jabber_whiteboard/message-*, + src/jabber_whiteboard/node-*, + src/jabber_whiteboard/received-message-helpers.cpp, + src/jabber_whiteboard/player-functors.*, + src/jabber_whiteboard/session-*, + src/jabber_whiteboard/tracker-node.h, + src/jabber_whiteboard/typedefs.h: + Initial commit of Inkboard code + * src/ui/dialog/session-player*, + src/ui/dialog/whiteboard*: + C++/Gtkmm replacements for some old C/Gtk dialogs + * configure.ac: + added Inkboard configure checks + * src/ui/view/edit.cpp, + src/ui/view/edit.h, + src/ui/view/view.cpp: + added Inkboard code stubs to new Gtkmm code + * share/ui/menus-bars.xml: + added Inkboard code stubs to menu UI XML + +2005-08-01 Ralf Stephan + + * src/sp-object.cpp: improved doxygen documentation + +2005-07-31 Ralf Stephan + + * src/nodepath.cpp: removed three dependencies + +2005-07-31 MenTaLguY + + * src/sp-object.cpp, src/sp-object.h, src/sp-use.cpp: + adopt more consistent refcounting policy + + * src/sp-object.h: make second parameter to sp_object_ref and + sp_object_unref optional + +2005-07-30 Ralf Stephan + + * src/draw-anchor.cpp, src/nodepath.h: reduced dependencies + * src/nodepath.cpp: removed duplicate dependency, added two from + nodepath.h, made triangle_area() inline + * src/node-context.cpp: added dependency removed from nodepath.h + * src/Doxyfile: added 2 further files to the scanned list + * src/nodepath.h: moved function docs into nodepath.cpp + * src/color.cpp: made file work with src/Doxyfile + * src/color.cpp, src/draw-anchor.cpp, src/geom.cpp, src/nodepath.cpp: + improved doxygen documentation + * src/event-context.cpp: added a \todo + * src/geom.cpp: added editor footer + +2005-07-30 Ted Gould + + * src/Makefile_insert, src/inkscape.cpp, src/inkscape.h, + src/interface.cpp, src/selection.cpp, src/verbs.cpp, src/verbs.h, + src/extension/effect.cpp, src/extension/effect.h, src/menus-skeleton.h: + + Doing two things. One, making menus configurable by an external xml file + and the second is enabling sensitivity in the verbs. These are both in + pretty basic states right now, but workable. + +2005-07-29 MenTaLguY + + * src/shortcuts.cpp: made Ctrl+Shift+G the "primary" ungroup shortcut + +2005-07-28 Carl Hetherington + + * src/arc-context.cpp: CodingStyle. Replace gboolean with bool. + + * src/desktop-events.cpp: CodingStyle: whitespace. Add editor + variables block. gboolean exorcism. Declaration-to-first-use fixes. + + +2005-07-27 Peter Moulder + + * src/style.h (SP_SCALE24_MAX): Change from 0xffffff to 0xff0000, + and add documentation for choice of value. + (SP_SCALE24_TO_FLOAT) Return a double instead of a float. + (SP_SCALE24_FROM_FLOAT) Change rounding behaviour. + These changes are intended to combat float rounding bugs on x86. + + * src/style.cpp (sp_style_merge_from_style_string): Use libcroco + to parse style="..." attribute strings, to improve CSS parsing. + +2005-07-27 Ralf Stephan + + * src/Doxyfile: added 10 further files to the scanned list + * src/gc-anchored.h, src/gc-managed.h, src/object-hierarchy.h, + src/pencil-context.h, src/selection.h, src/sp-object.h, src/sp-spiral.h, + src/svg-view.h, src/verbs.h, src/livarot/float-line.h, src/util/list.h, + src/widgets/paint-selector.h, src/xml/repr.h: + made file work with src/Doxyfile + * src/livarot/int-line.h, src/livarot/float-line.h: + moved part of documentation into *.cpp file + * src/gc-anchored.h, src/knot-holder-entity.h, src/nodepath.h, + src/pen-context.h, src/pencil-context.h, src/selection.h, + src/sp-gradient.h, src/sp-gradient.cpp, src/sp-item.h, src/sp-object.h, + src/sp-spiral.h, src/style.h, src/svg-view.h, src/extension/extension.h, + src/libnr/nr-matrix.h, src/livarot/int-line.h, src/livarot/int-line.cpp, + src/livarot/float-line.h, src/livarot/float-line.cpp, + src/livarot/sweep-event.h, src/livarot/sweep-event-queue.h, + src/util/list.h, src/widgets/paint-selector.h, src/xml/repr.h, + src/xml/repr.cpp: documentation improvements + * src/sp-item.h: added editor footer + +2005-07-26 Peter Moulder + + * src/svg/stringstream.h, src/svg/stringstream.cpp: + Trim trailing zeros from after the decimal point when writing + float or double to Inkscape::SVGOStringStream. + * src/style-test.cpp: Update expected output accordingly. + * src/svg/stringstream-test.h: New unit test. + * src/Makefile.am, src/svg/Makefile_insert: Add the new unit test. + * src/svg/Makefile_insert: + Don't link unused ftos.cpp, but do link new file stringstream.cpp. + +2005-07-26 Michael Wybrow + + * share/icons/icons.svg: Add icon for connector context. + +2005-07-25 Ralf Stephan + + * src/libnr/nr-pixblock.h: interface cleanup of NRPixBlock: size and mode + are now named enums, empty is now bool, changes to function interfaces + because of that, changed C macros to C++ inline functions, changed clean + flag in some function interfaces from int to bool. + * src/libnr/nr-pixblock.cpp: adaptations due to changes in nr-pixblock.h, + added assert to ...setup_extern() which remains a bit ... risky, + * src/display/sp-canvas.cpp: + made sp_canvas_item_construct() static, inlined two other functions + * src/svg-view.cpp: piped emit_resized through C++ façade (incomplete) + * src/ui/view/view.h: removed legacyMessageContext() member + * src/Doxyfile: added files, and options to collect todo and bugs + * src/display/curve.cpp: moved member docs into curve.h + * src/event-context.cpp: long line cosmetics, moved a function for clarity + * src/sp-offset.h, src/sp-spiral.cpp, src/svg-view.cpp, + src/libnr/nr-types.h: added editor footer + * src/color-rgba.h, src/draw-anchor.h, src/event-context.*, src/knot-*.h, + src/message-*.h, src/modifier-fns.h, src/nodepath.h, + src/pencil-context.cpp, src/pen-context.*, src/snap.*, src/sp-gradient.h, + src/sp-gradient-fns.h, src/sp-item.cpp, src/sp-item-notify-moveto.h, + src/sp-linear-gradient*, src/sp-offset.*, src/sp-radial-gradient*, + src/sp-spiral.cpp, src/style.cpp, src/svg-view.cpp, src/verbs.cpp, + src/dialogs/export.cpp, src/display/bezier-utils.cpp, + src/display/curve.*, src/diplay/sp-canvas.*, + src/extension/implementation/plugin*, src/extension/internal/gimpgrad.h, + src/libnr/nr-matrix.h, src/libnr/nr-matrix-scale-ops.h, + src/libnr/nr-matrix-translate-ops.h, src/libnr/nr-pixblock.*, + src/libnr/nr-point.h, src/libnr/nr-rotate.h, src/libnr/nr-rotate-fns.h, + src/libnr/nr-scale-matrix-ops.h, src/libnr/nr-types.h, + src/livarot/int-line.h, src/ui/view/view.*: + + made file work with src/Doxygen, doxygen documentation improvements + +2005-07-24 Ted Gould + + * 0.42 Release + +2005-07-21 Ted Gould + + * 0.42pre3 + +2005-05-21 Kees Cook + + * share/icons/*xpm, src/ui/dialog/transformation.cpp, + src/ui/widget/labelled.cpp, src/ui/widget/labelled.h: + Hooked up Gtkmmified Icon manager correctly. (bug 1217367) + * Makefile.mingw, Makefile.mingw.common: patch 1241293 for build fixes + +2005-07-12 Ted Gould + + * 0.42pre2 + +2005-07-11 MenTaLguY + + * src/debug/logger.cpp: wrap stack vector in method to avoid + potential static initialization issues + + * src/sp-object.cpp: add refcount logging + +2005-07-09 MenTaLguY + + * src/document-undo.cpp, src/inkscape.cpp, src/debug/event.h, + src/debug/logger.cpp, src/debug/logger.h, src/debug/simple-event.h, + src/xml/composite-node-observer.cpp, src/xml/event.cpp, + src/xml/simple-node.cpp: + + Categorize debugging events and add the ability to filter them + via setting the INKSCAPE_DEBUG_FILTER environment variable to + a comma-separated list of debug event categories. + +2005-07-06 Ben Fowler + + * src/interface.cpp: Spackle for Bug 1217361 "freeze on quitting + with transform dialog" + +2005-07-06 Ben Fowler + + * src/interface.cpp: Whitespace changes only + +2005-07-06 Michael Wybrow + + * Info.plist.in, packaging/osx-app.sh, packaging/macosx/*: + + Changes and new files required to build an Inkscape dmg on Mac OS X. + +2005-07-05 Ted Gould + + * 0.42pre1 + +2005-07-04 MenTaLguY + + * src/sp-metadata.cpp: strip id= attributes under rdf:RDF elements + +2005-07-04 MenTaLguY + + * src/sp-object.cpp, src/xml/node-fns.h, src/xml/node-fns.cpp: + don't force id= attributes on anything except elements in the SVG, + Sodipodi, or Inkscape namespaces. + +2005-07-04 MenTaLguY + + * src/verbs.cpp: redo cryve's fix to use defaultLabel() rather than + label() + +2005-07-04 Bryce Harrington + + * src/livarot/float-line.cpp: Patch from Ralf Stephan + to suppress two warnings. + +2005-06-28 Ted Gould + + * src/verbs.h: + + Changing from gnu::hash_map to std::map. The only reason this was a + hash_map before is because I was stealing code that I didn't understand, + and a std::map works as well. This fixes bug #1172199 for Tru64. + +2005-06-28 Ted Gould + + * src/extension/dependency.cpp: + + Fix for #1169396 -- setting the default type for a dependency to file, + this seems to be the only way that the print function could end up using + undefined memory, and then passing it on the gettext. + +2005-06-28 Ted Gould + + * src/extension/implementation/script.cpp, + src/extension/implementation/script.h: + + Adding support for information coming back on STDERR from scripts. This + fixes bug #1220959 and RFE #1178941 + +2005-07-04 Peter Moulder + + * src/sp-stop.h, sp-gradient.cpp, widgets/gradient-vector.cpp: + Implement currentColor as possible value for stop-color, as per spec. + +2005-07-02 Kees Cook + + * src/dialog/rdf.cpp: Added FreeArt license, RFE #1230981. + +2005-06-30 Bryce Harrington + + * inkscape.nsi: Fix for bug #1230744 'wrong installer language' + by theadib. + + * src/swatches.cpp: Fix for bug #1217973. The KDE swatches file + consists of 3 column numbers (missing 4th column), and also lacks + an ending newline. In this situation, the name variable returned + from trim() could be null, thus causing a segfault when used as an + input to Glib::ustring. + + * src/sp-image.cpp: Patch for bug #1210100 by bpfowler to help + narrow in on the cause of the bug. + + * README: Requested change for bug #1174991. Directions for + installation of perl libs + +2005-07-01 Ben Fowler + + * src/desktop.cpp src/svg-view.cpp src/dialogs/display-settings.cpp + src/dialogs/export.cpp src/dialogs/find.cpp + src/extension/internal/ps.cpp: Replaced calls to gtk_widget_set_usize + with GTK2 version. + +2005-06-30 Bryce Harrington + + * inkscape.pod, src/main.cpp: Applying Makzu's patch to implement + --vacuum-defs + +2005-06-28 Ted Gould + + * 0.42pre0 + +2005-06-23 MenTaLguY + + * src/extension/implementation/script.cpp: + support for ruby scripts (interpreter="ruby") + +2005-06-20 Ted Gould + + * src/desktop.cpp, src/desktop.h, src/document-private.h, + src/document.cpp, src/document.h, src/extension/effect.h, + src/extension/implementation/script.cpp: + + Adding in a signal to show that the document is being reconstructed from + another document. This is used by the scripting extensions implementation + to say to the desktops that they need to save their object references + as strings instead of pointers -- and then recreate them when the + reconstruction is complete. + + * src/extension/prefdialog.cpp: Making "OK" have focus. + + * src/verbs.cpp, src/verbs.h: Some prototype code to start making verbs + sensitive or not. Not tied in to anything currently. + +2005-06-20 MenTaLguY + + * src/xml/repr-io.cpp: whoops... don't emit xmlns:xml + +2005-06-18 Richard Hughes + + * src/text-context.cpp, src/text-context.h, src/libnrtype/Layout-TNG.h: + implement double- and triple-clicking of text for selecting the + current word and line respectively + +2005-06-16 MenTaLguY + + * src/interface.cpp: removed "Go to root" context menu item + + * src/widgets/layer-selector.cpp: hide "(root)" unless it is the current + layer + +2005-06-11 Aaron Spike + + * confiugre.ac, + packaging/autopackage/default.apspec.in: + + Adding the autopackage specfile + +2005-06-10 Richard Hughes + + * src/text-context.cpp: + use ctrl-left/right for moving cursor by word in text mode, + and ctrl-a for select all text + +2005-06-09 Bryce Harrington + + * src/ui/dialogs/align-and-distribute.cpp, + src/ui/dialogs/align-and-distribute.h, + src/verbs.cpp: + Hooking up Aubanel's new align and distribute dialog + +2005-06-09 Peter Moulder + + * src/text-context.cpp (sp_text_context_root_handler): + Greater conformance to ISO 14755 for unicode entry. We now + implement all of the ``Basic method'' portion of that spec + except for non-latin hexadecimal digits (first 6 letters of + other alphabets). (Instead, we do the same as for all other + shortcuts, viz. force a group0 (latin) interpretation of the + keypress.) + +2005-06-07 Peter Moulder + + * src/pen-context.cpp (spdc_endpoint_snap): Pen tool: do snapping + (i.e. namedview_free_snap_all_types) even for initial point. + + * src/Makefile.am (INCLUDES), src/extension/script/Makefile_insert + (extension_script_libscript_a_CXXFLAGS): + + Put PERL_CFLAGS PYTHON_CFLAGS into global INCLUDES rather than + using a libscript_a_CXXFLAGS var (which involved creating .o files + specific to that lib). + +2005-06-06 Ted Gould + + * src/extensions/effect.cpp: + + Adding in the code so that effects can be undoable. + + * src/extensions/implementation/script.[cpp,h] + + Adding in the code so that a new window is not displayed when an + effect is executed. Now it is in the same window (much nicer). + + * src/extensions/internal/latex*.[cpp,h] + + Patches from the mailing list to add LaTeX output. + +2005-06-04 MenTaLguY + + * src/extensions/init.cpp: + + That tears it. Showing the error dialog on startup goes. I've + had to respond to one too many bloody bug reports. If we released + 0.42 with this too we'll drive away users permanently. As it was, + a lot of people were assuming 0.41 was broken when they saw this + and reverted to 0.40. + +2005-05-31 MenTaLguY + + * src/preferences-skeleton.h: disable extension error dialog on startup + -- I'm sick of hearing that Inkscape is broken because people see + this dialog on startup. It makes us look bad. + + We're not going to repeat this for 0.42 -- find a better approach. + +2005-05-28 MenTaLguY + + * src/document.cpp, src/sp-ellipse.cpp, src/sp-flowdiv.cpp, + src/sp-flowtext.cpp, src/sp-object.cpp, src/sp-object.h, + src/sp-path.cpp, src/sp-rect.cpp, src/sp-root.cpp, src/sp-root.h, + src/sp-shape.cpp, src/version.cpp, src/version.h: + + propagate SVG version upwards, and move SPVersion into Inkscape + namespace + +2005-05-24 Simarilius + + * src/verbs.cpp, src/dialogs/tiledialog.cpp, src/dialogs/tiledialog.h, + src/ui/dialogs/dialog-manager.cpp + + Converted the tiledialog over to the inkscape:ui:dialog class and hooked + it into dialog manager + +2005-05-24 Ted Gould + + * src/extension/dependency.cpp, src/extension/extension.cpp, + src/extension/extension.h, src/extension/init.cpp, + src/extension/implementation/script.cpp: + + Applying patch 1199856 which allows Inkscape to have multiple directories + for extensions. Currently those are /share/inkscape/extensions and + ~/.inkscape/extensions. The patch was written by Aaron Spike. + +2005-05-23 Ted Gould + + * share/extensions/ + + Adding in Aaron Spike's extensions so that they come with the standard + build. Lot's of useful stuff that is worth having for most users. + +2005-05-19 MenTaLguY + + * src/verbs.cpp, src/ui/dialog/align-and-distribute.h, + src/ui/dialog/dialog-manager.cpp, src/ui/dialog/dialog-manager.h, + src/ui/dialog/document-preferences.h, src/ui/dialog/export.h, + src/ui/dialog/extension-editor.h, src/ui/dialog/fill-and-stroke.h, + src/ui/dialog/find.h, src/ui/dialog/inkscape-preferences.h, + src/ui/dialog/layer-editor.h, src/ui/dialog/messages.h, + src/ui/dialog/text-properties.h, src/ui/dialog/transformation.h, + src/ui/dialog/xml-editor.h, src/ui/view/edit.cpp: + + refactoring of the dialog manager code, introducing factory + functions and a method specifically for showing a dialog + +2005-05-19 MenTaLguY + + * src/widgets/layer-selector.cpp, src/widgets/layer-selector.h: + + fix layer property undo crash bugs (#1192708 and #1171704) + +2005-05-19 MenTaLguY + + * src/debug/Makefile_insert, src/debug/sysv-heap.cpp, + src/debug/sysv-heap.h, src/gc.cpp, src/debug/gc-heap.h, + src/debug/heap.cpp: + + moved GC Heap statistics stuff into libdebug to ease circular + dependencies + +2005-05-17 MenTaLguY + + * src/ui/dialog/memory.cpp: + + reduce magnitude of memory jitter somewhat by avoiding some vector + resizing and copying + +2005-05-16 MenTaLguY + + * src/gc.cpp, src/debug/heap.cpp, src/debug/heap.h: + + revised Debug::Heap API slightly + + * src/ui/dialog/memory.cpp, src/ui/dialog/memory.h: + + thousands separators and other niceties. 'apply' now forces a + garbage collection and immediate update. + +2005-05-16 MenTaLguY + + * src/ui/dialog/memory.cpp: re-use existing rows, though it doesn't + seem to help memory jitter much + +2005-05-15 MenTaLguY + + * src/debug/heap.cpp: fix bounds error + + * src/ui/dialog/memory.cpp, src/ui/dialog/memory.h: + + flesh out basic memory info dialog + +2005-05-15 MenTaLguY + + * configure.ac: cleaned up tests + + * src/debug/heap.cpp: fixed feature macro names + +2005-05-15 MenTaLguY + + * configure.ac: added tests for mallinfo and malloc.h + + * src/gc.cpp, src/debug/heap.cpp, src/debug/heap.h: + + fix up Debug::Heap API slightly + +2005-05-14 MenTaLguY + + * src/interface.cpp, src/verbs.cpp, src/verbs.h, + src/ui/dialog/Makefile_insert, src/ui/dialog/dialog-manager.cpp, + src/ui/dialog/dialog-manager.h, src/ui/dialog/memory.cpp, + src/ui/dialog/memory.h: + + added skeletal memory statistics dialog + +2005-05-12 Juerg Billeter + + * configure.ac: Have pkgconfig explicitly require gdkmm-2.4 & glibmm-2.4 + (used directly by Inkscape), rather than relying on transitive + dependencies. It's said that this is required in some cases with + pkgconfig 0.17 and later. + +2005-05-08 Bryce Harrington + + * ChangeLog configure.ac src/Makefile_insert src/desktop-widget.h + src/desktop.h src/dropper-context.cpp src/file.cpp + src/shortcuts.cpp src/sp-text.cpp src/splivarot.cpp + src/svg-view.h src/text-context.cpp src/verbs.cpp + src/extension/implementation/plugin-link.h + src/extension/internal/grid.cpp src/helper/action.h + src/helper/window.cpp src/ui/dialog/dialog.cpp + src/ui/dialog/messages.cpp src/ui/view/view.cpp + src/ui/view/view.h: + + Moving view.* into src/ui/view/ + +2005-05-09 MenTaLguY + + * src/gc-alloc.h: const-correctness fix + +2005-05-08 Bryce Harrington + + * configure.ac: Defaulting with-gnome-vfs to on if library is + present. + + * po/POTFILES.in : Fixed error causing compile failure + + * src/Makefile_insert src/arc-context.cpp src/desktop-events.cpp + src/desktop.cpp src/desktop.h src/dyna-draw-context.cpp + src/gradient-context.cpp src/gradient-toolbar.cpp + src/interface.cpp src/make.dep src/make.files + src/rect-context.cpp src/select-context.cpp + src/select-toolbar.cpp src/seltrans.cpp src/spiral-context.cpp + src/star-context.cpp src/toolbox.cpp src/verbs.cpp src/view.cpp + src/view.h src/application/application.cpp + src/application/application.h src/application/editor.cpp + src/application/editor.h src/ui/dialog/align-and-distribute.cpp + src/ui/dialog/align-and-distribute.h + src/ui/dialog/dialog-manager.cpp src/ui/dialog/dialog-manager.h + src/ui/dialog/dialog.cpp src/ui/dialog/dialog.h + src/ui/dialog/document-preferences.cpp + src/ui/dialog/document-preferences.h src/ui/dialog/export.cpp + src/ui/dialog/export.h src/ui/dialog/extension-editor.cpp + src/ui/dialog/extension-editor.h + src/ui/dialog/fill-and-stroke.cpp + src/ui/dialog/fill-and-stroke.h src/ui/dialog/find.cpp + src/ui/dialog/find.h src/ui/dialog/inkscape-preferences.cpp + src/ui/dialog/inkscape-preferences.h + src/ui/dialog/layer-editor.cpp src/ui/dialog/layer-editor.h + src/ui/dialog/messages.h src/ui/dialog/text-properties.cpp + src/ui/dialog/text-properties.h + src/ui/dialog/transformation.cpp src/ui/dialog/transformation.h + src/ui/dialog/tree-editor.h src/ui/dialog/xml-editor.cpp + src/ui/dialog/xml-editor.h src/ui/view/Makefile_insert + src/ui/view/edit.cpp src/ui/view/edit.h : + + Renaming sp-desktop-widget.h to desktop-widget.h for + consistency with other desktop files. Beginning migration of + desktop-* and view* files into ui/view/ subdir. Incorporating + DialogManager into existing SPDesktop code. Making SPView + derive from GObject. Changing Messages dialog to run via + DialogManager. Removing getName() and getDesc() routines from + Dialogs. + +2005-05-08 MenTaLguY + + * src/Makefile_insert: change link order since the GC code now + depends on the debugging stuff + + * src/debug/Makefile_insert, src/debug/heap.cpp, src/debug/heap.h: + + added heap statistics stuff + + * src/gc.cpp: register the GC heap with the heap statistics facility + +2005-05-07 MenTaLguY + + * src/gc-anchored.h, src/gc-core.h, src/gc-finalized.h, + src/gc-managed.h, src/gc.cpp: + + hide the global Ops structure from the outside world, and expose + some additional libgc API. + +2005-05-07 Ted Gould + + * src/extension/parameter.cpp: bug fix for empty string parameter + + * share/extensions/dropshadow.inx, + src/extension/implementation/script.cpp: + + Adding in an "interpreter" attribute for "command" that will prepend + the command with the interpreter. Right now only "perl" and "python" + work, and they only prepend "perl" and "python", but more will be + added later. + +2005-05-07 MenTaLguY + + * src/xml/composite-node-observer.cpp: bug fixes + + * src/xml/simple-node.cpp, src/xml/simple-node.h: switch to using + CompositeNodeObserver, which has saner add/remove semantics + + * src/util/list-container-test.cpp: add another test, just to be sure + + * src/dialogs/xml-tree.cpp: remove need for is_interactive flag on + attribute changes (the flag is effectively disabled by the other + changes) + +2005-05-05 MenTaLguY + + * src/debug/event.h, src/debug/logger.cpp: + + PropertyPair is now its own class + + * src/xml/simple-node.cpp: add logging of XML node mutation + + * src/xml/Makefile_insert, src/xml/composite-node-observer.cpp, + src/xml/composite-node-observer.h: + + added CompositeNodeObserver class, which will eventually replace + the existing notifier lists + +2005-05-05 MenTaLguY + + * src/inkscape.cpp: try to cleanly terminate log in case of crashes + +2005-05-05 MenTaLguY + + * src/document-undo.cpp, src/debug/Makefile_insert, src/debug/logger.cpp, + src/debug/simple-event.h, src/xml/event.cpp: + + add debug logging for undo+redo+transactions + +2005-05-05 MenTaLguY + + * src/inkscape.cpp, src/main.cpp: initialize and shutdown debug log + from more reliable place + + * src/debug/logger.cpp: clean up log via std::atexit() + +2005-05-04 MenTaLguY + + * configure.ac, src/Makefile.am, src/Makefile_insert, + src/debug/Makefile_insert, src/debug/makefile.in: + + added src/debug/ subdir + + * src/gc-alloc.h: no default management type for now + + * src/debug/event-tracker.h, src/debug/event.h, src/debug/logger.cpp, + src/debug/logger.h: simple XML logging facility + + * src/util/Makefile_insert: fixed cut-and-paste error + +2005-04-29 Jon A. Cruz + * src/dialogs/swatches.cpp, src/dialogs/eek-preview.h, + src/dialogs/eek-preview.cpp: + + Added property to swatch to block taking focus. + +2005-04-28 Jon A. Cruz + * src/dialogs/Makefile_insert, src/dialogs/eek-preview.cpp, + src/dialogs/eek-preview.h, src/dialogs/swatches.cpp, + src/dialogs/swatches.h, src/ui/previewholder.cpp, + src/ui/previewable.h, src/ui/widget/panel.cpp: + + Adding new widget for color swatch usage. + +2005-04-24 Bryce Harrington + + * src/Makefile.am src/Makefile_insert, + src/application/Makefile_insert, src/application/editor.cpp, + src/application/editor.h, src/extension/internal/svg.cpp, + src/ui/Makefile_insert, src/ui/view/Makefile_insert, + src/ui/view/edit.cpp, src/ui/view/edit.h, src/ui/view/makefile.in, + src/application/editor-impl.cpp, src/application/editor-impl.h: + + Renaming EditorImpl to UI::View::Edit + + Fixing bug 1185873 "batch mode crasher" caused by VFS being + called with relative paths. Adding a check to see whether the + input is a valid uri, and if not, just calling sp_document_new + directly. + + +2005-04-23 Ted Gould + + * src/extension/input.cpp, src/extension/input.h, + src/extension/output.cpp, src/extension/output.h, + src/extension/system.cpp, src/extension/implementation/implementation.cpp, + src/extension/implementation/implementation.h, + src/extension/implementation/plugin-link.h, + src/extension/implementation/plugin.cpp, + src/extension/implementation/plugin.h, + src/extension/implementation/script.cpp, + src/extension/implementation/script.h, src/extension/internal/eps-out.cpp, + src/extension/internal/eps-out.h: + + Changing the prototype for the input/output preferences to be closer to + that of Effects. This is a good thing because now autogui can be used for + all, and it is much cleaner. Unfortunately, this caused alot of files to + be changed. Also, this sets up the extensions dialog (we're only using + one now) to be integrated into the GTKmm codebase easier. + +2005-04-21 Jon A. Cruz + * src/widgets/sp-color-wheel-selector.cpp, + src/widgets/sp-color-scales.h, src/widgets/sp-color-slider.cpp, + src/widgets/sp-color-scales.cpp: + Changed CMYK selector to display values as 0-100. Fixes REF #1124499. + +2005-04-21 Jon A. Cruz + * src/xml/repr-io.cpp: + Expand entities; matches 0.41 behavior. Fixes bug #1157478. + +2005-04-20 Jon A. Cruz + * src/sp-object-repr.cpp: + Turned off the half-done element. Fixes bug #1119935. + +2005-04-19 Carl Hetherington + + * src/pen-context.cpp: snap first point to grid correctly, fixing + #1152057. Remove a pointless call to spdc_endpoint_snap(). + + * src/main.cpp: support for command-line export of PS and EPS, + with options. + +2005-04-19 Piers Titus van der Torren + * src/seltrans.cpp: + Fixed skew so it displays and snaps to angle instead of percentage. + +2005-04-18 Peter Moulder + + * src/extension/internal/pov-out.cpp (PovOutput::save): + Was dividing component bytes by 256 instead of the usual 255 to get + floating point component. Changed to use sp_color_get_rgb_floatv + instead. (N.B. This change is wrong if pov files disallow 1.0.) + + Multiply opacity by product of all ancestors' opacity property computed + value. + +2005-04-18 Carl Hetherington + + * src/sp-line.cpp, src/dialogs/unclump.cpp, + src/extension/internal/ps.cpp, + src/libnrtype/Layout-TNG-Output.cpp, + src/Layout-TNG-Scanline-Makers.cpp, src/livarot/PathCutting.cpp: + add missing include of nr-point-matrix-ops.h. + +2005-04-17 Jon A. Cruz + * src/toolbox.cpp: + + Corrected improper use of static. Fixes bug #1171919. + +2005-04-16 Ted Gould + + * src/extension/extension.cpp, src/extension/parameter.cpp: + + Adding in autogui for strings and booleans. Also making everything + a little more robust. + +2005-04-17 cyreve + + * src/: sp-text.cpp, sp-text.h, text-context.cpp, text-editing.cpp, + text-editing.h, libnrtype/Layout-TNG-Compute.cpp: hook up keys + for adding rotate= attribute to text elements + + * src/libnrtype/Layout-TNG-OutIter.cpp: visual cursor left/right in + counterdirectional text runs + +2005-04-16 cyreve + + * src/: display/nr-arena-glyphs.cpp, libnrtype/FontInstance.cpp, + libnrtype/RasterFont.cpp, libnrtype/font-instance.h, + libnrtype/font-style.h: make miter-limit work for text outlines + (bug 1094430) + +2005-04-16 Ted Gould + + * src/main.cpp: + + Added a command-line arguement --extension-directory to find what + extension directory Inkscape is configured for. This should be + helpful for external extensions that want to use the same path + as Inkscape itself on their install. + + * src/extension/extension.cpp, src/extension/init.cpp: + + Putting in half of Aaron's fix, mostly the one to keep things from + crashing, next we need to examine how to add multiple search paths + for extension dependencies. + + Also, added a check so that autogui won't create a GUI if there are + no preferences. + +2005-04-13 Jon Phillips + * src/toolbox.cpp: removed code that was beeping and prepped for new + drag-n-drop color swatches. + +2005-04-13 cyreve + + * src/path-chemistry.cpp: wire up converting object to path for + flowtext + +2005-04-13 Jon A. Cruz + * src/dialogs/swatches.cpp: + + Simple drag-n-drop out from color swatches. + +2005-04-12 cyreve + + * src/: selection-chemistry.cpp, text-context.cpp, text-context.h, + text-editing.cpp, text-editing.h: cut and copy selected text (bug + 1175441) + +2005-04-12 Ted Gould + + * src/extension/extension.cpp, src/extension/extension.h, + src/extension/parameter.cpp, src/extension/parameter.h, + src/extension/implementation/script.cpp: + + This is support for having command line arguments from the parameters, + mostly this is a quick hack to get Aaron working, I'll clean it up + shortly, I promise. But, it does seem to be working right now. More + polish shortly. + +2005-04-10 Jon A. Cruz + * src/interface.cpp: + + Adding drag-n-drop support for arbitrary images. Fixes bug 1177714. + + +2005-04-10 Ted Gould + + * Lots of files: + + Moving around the plugins, and disabling the feature. I've put all + the functionality into the internal directory. This should allow for + the features to be used until plugins could work. Also, adding in + features to do autogui with the parameters of a given extension. + +2005-04-09 Bryce + + * src/view.h, src/application/editor-impl.cpp, + src/application/editor-impl.h, src/svg-view.h: + + C++-ification. Created some C++ wrapper member functions for + SPView and SPSVGView, to enable Gtkmmification of SPDesktop + +2005-04-09 MenTaLguY + + * src/selection.cpp, src/selection.h, src/dialogs/align.cpp, + src/extension/implementation/script.cpp, + src/extension/plugin/bluredge.cpp, src/util/glib-list-iterators.h: + + excise STL abuse, and fix up the glib list iterators + +2005-04-09 MenTaLguY + + * src/file.cpp, src/interface.cpp, src/shortcuts.cpp, + src/sp-object-repr.cpp, src/sp-skeleton.cpp, src/verbs.cpp, + src/dialogs/export.cpp, src/display/nr-arena-item.cpp, + src/libnrtype/FontFactory.cpp, src/libnrtype/TextWrapper.h, + src/livarot/ShapeMisc.cpp, src/livarot/float-line.cpp: + + combined several different 64-bit cleanness patches + +2005-04-08 Jon Phillips + * src/ui/dialog/dialog-manager.cpp src/ui/dialog/dialog-manager.h: + added copyright statements about dialog manager code I wrote. + +2005-04-08 MenTaLguY + + * src/draw-context.cpp, src/dyna-draw-context.cpp, src/path-chemistry.cpp, + src/selection-chemistry.cpp, src/selection.cpp, src/selection.h, + src/splivarot.cpp, src/extension/plugin/bluredge.cpp, + src/trace/trace.cpp: + + renaming Inkscape::Selection methods that deal with XML::Nodes + +2005-04-08 MenTaLguY + + * src/document-undo.cpp: try again with handling incomplete transactions + more gracefully + +2005-04-06 Peter Moulder + + * src/io/sys.h, src/io/sys.cpp (dir_open, dir_read_utf8name): + New functions: utf8 wrappers around g_dir_open, g_dir_read_name. + +2005-04-02 Bryce Harrington + + * configure.ac share/ui/menus-bars.xml, src/Makefile.am, + src/Makefile_insert, src/file.cpp, + src/application/editor-impl.cpp, + src/application/editor-impl.h, + src/extension/init.cpp, src/extension/input.cpp, + src/extension/system.cpp, + src/extension/implementation/implementation.cpp, + src/extension/implementation/plugin.cpp, + src/extension/implementation/script.cpp, + src/extension/internal/svg.cpp + : Implementing preliminary load-from-URI functionality. + + +2005-04-02 MenTaLguY + + * src/document-undo.cpp, src/xml/event-fns.h, src/xml/event.cpp, + src/xml/event.h: + + more debugging info for incomplete transactions + +2005-04-02 Peter Moulder + + * src/sp-gradient.cpp: Fix crash with cycles in gradient hrefs. + +2005-04-01 Jon A. Cruz + * src/ui/widget/panel.h, src/ui/widget/panel.cpp, src/ui/previewholder.h, + src/ui/previewholder.cpp,src/dialogs/swatches.cpp, + src/dialogs/swatches.h: + Added UI for switching palettes + +2005-04-01 Peter Moulder + * src/style.cpp (sp_style_merge_from_dying_parent): New function to + combine the styles of the element and its ghost child when + unlinking. + * src/sp-use.cpp: Use it. + +2005-03-31 Jon A. Cruz + * src/ui/widget/panel.cpp, src/ui/widget/panel.h, src/path-prefix.h, + src/dialogs/swatches.cpp, src/dialogs/swatches.h + share/palettes/Makefile.am, share/palettes/svg.gpl: + Adding palette loading. + +2005-03-31 Jean-François Lemaire + * share/icons/David_icons.svg: new icon theme by David Christian Berg + + * share/icons/README.icons: explanations on how to use the theme + +2005-03-30 Jean-François Lemaire + * share/icons/icons.svg: included the layer menu icons + + * src/verbs.cpp: assigned names for the layer menu icons + +2005-03-24 Jon A. Cruz + * src/ui/widget/panel.h, src/ui/widget/panel.cpp, + src/ui/previewholder.h, src/ui/previewfillable.h, + src/dialogs/iconpreview.cpp, src/dialogs/swatches.cpp: + Adding panel menu + +2005-03-27 Jon Phillips + * src/toolbox.cpp src/toolbox.h src/ui/dialog/dialog-manager.cpp + src/ui/dialog/dialog-manager.h: Added generic dialog adding, + deleting, and getting and fixed toolboxes to be static with no + warnings. + +2005-03-26 Bryce + + * share/ui/keybindings.rc, share/ui/menus-bars.xml + src/application/editor-impl.cpp, src/application/editor-impl.h, + src/extension/internal/svg.cpp, src/ui/dialog/Makefile_insert, + src/ui/dialog/dialog-manager.cpp, + src/ui/dialog/dialog-manager.h, src/ui/dialog/messages.cpp, + src/ui/dialog/messages.h: Initial implementation of canvas in + gtkmm. Incorporating Messages dialog. + + +2005-03-24 MenTaLguY + + * src/sp-item.cpp: fix relative transforms to accommodate viewbox + +2005-03-24 Jon A. Cruz + + * src/ui/Makefile_insert, src/dialogs/swatches.cpp, + src/dialogs/swatches.h, src/ui/previewable.h, + src/ui/previewfillable.h, src/ui/previewholder.cpp, + src/ui/previewholder.h: + Refactoring previewable functionality to be more generic + +2005-03-24 cyreve + + * src/: text-context.cpp, text-editing.cpp, text-editing.h: + functions for applying style to selected text, and wire them + up to ctrl-b/ctrl-i for bold/italic + +2005-03-23 Jon Phillips + * src/toolbox.h src/toolbox.cpp: Fixed warning messages. + +2005-03-23 Jon A. Cruz + + * src/ui/previewable.h, src/ui/Makefile_insert, + src/dialogs/swatches.h, src/dialogs/swatches.cpp: + Preliminary work for 'Previewable' interface. + +2005-03-23 cyreve + + * src/: sp-text.cpp, libnrtype/Layout-TNG-Compute.cpp, + libnrtype/Layout-TNG-Output.cpp: make text on path work correctly + with accent glyphs and suchlike + + * src/: text-chemistry.cpp, libnrtype/Layout-TNG.h: apply text's + alignment to startOffset on new textpath elements, fixes bug + 1168145 + + * src/libnrtype/Layout-TNG-OutIter.cpp: selecting text to the end + sometimes displays wrong + +2005-03-22 MenTaLguY + + * src/arc-context.cpp, src/desktop-handles.cpp, + src/desktop-handles.h, src/desktop.cpp, src/desktop.h, + src/document.h, src/draw-context.cpp, src/draw-context.h, + src/file.cpp, src/forward.h, src/gradient-context.cpp, + src/gradient-drag.cpp, src/gradient-drag.h, src/gradient-toolbar.cpp, + src/inkscape-private.h, src/inkscape.cpp, src/node-context.cpp, + src/node-context.h, src/nodepath.cpp, src/object-ui.cpp, + src/path-chemistry.cpp, src/rect-context.cpp, src/selcue.cpp, + src/selcue.h, src/select-context.cpp, src/select-toolbar.cpp, + src/selection-chemistry.cpp, src/selection-chemistry.h, + src/selection-describer.cpp, src/selection-describer.h, + src/selection.cpp, src/selection.h, src/seltrans.cpp, + src/seltrans.h, src/sp-flowtext.cpp, src/spiral-context.cpp, + src/splivarot.cpp, src/star-context.cpp, src/text-chemistry.cpp, + src/text-context.cpp, src/toolbox.cpp, src/verbs.cpp, + src/dialogs/align.cpp, src/dialogs/clonetiler.cpp, + src/dialogs/display-settings.cpp, src/dialogs/fill-style.cpp, + src/dialogs/find.cpp, src/dialogs/iconpreview.cpp, + src/dialogs/item-properties.cpp, src/dialogs/object-properties.cpp, + src/dialogs/stroke-style.cpp, src/dialogs/text-edit.cpp, + src/dialogs/tiledialog.cpp, src/dialogs/transformation.cpp, + src/dialogs/xml-tree.cpp, src/extension/plugin/bluredge.cpp, + src/extension/plugin/grid.cpp, src/trace/trace.cpp, + src/ui/dialog/dialog.cpp, src/ui/dialog/dialog.h, + src/ui/dialog/transformation.cpp, src/ui/dialog/transformation.h, + src/widgets/sp-widget.cpp, src/widgets/sp-widget.h: + + SPSelection -> Inkscape::Selection + +2005-03-22 cyreve + + * src/text-context.cpp: pressing esc doesn't hide text selection + + * src/: text-context.cpp, text-context.h, text-editing.cpp, + text-editing.h, libnrtype/Layout-TNG-OutIter.cpp, + libnrtype/Layout-TNG.h: make text selection inverse + +2005-03-21 Jon Phillips + + * share/icons/icons.svg src/dropper-context.cpp + src/dropper-context.h src/toolbox.cpp src/toolbox.h + src/dialogs/display-settings.cpp: Added controls for eye dropper + so that I could get color values. Removed option from application + preferences. + +2005-03-21 MenTaLguY + + * src/util/Makefile_insert, src/util/glib-list.h, + src/util/glib-list-iterators.h: + + retired old Glib list to Util::List adaptor and replaced it with + new iterator classes that directly wrap the Glib list types + +2005-03-21 cyreve + + * src/: text-editing.cpp, libnrtype/Layout-TNG-OutIter.cpp: text + selection doesn't show when it starts at the end of a line + + * src/: text-context.cpp, text-editing.cpp: crash on overtyping + selection, and displayed selection not removed on overtype + + * src/text-editing.cpp: kerning information placed wrongly in text + after child span element + + * src/libnrtype/Layout-TNG-OutIter.cpp: crash when pressing home key + + * src/: text-context.cpp, text-context.h: text selection using the + mouse + + * src/: make.dep, make.files, make.ofiles, + libnrtype/Layout-TNG-OutIter.cpp: further optimisation of text + selection, and an implementation for text on a path + + * src/: text-editing.cpp, libnrtype/Layout-TNG-OutIter.cpp, + libnrtype/Layout-TNG.h: optimisation of text selection and fixing + some bugs in it + +2005-03-18 MenTaLguY + + * src/arc-context.cpp, src/file.cpp, src/gradient-context.cpp, + src/node-context.cpp, src/object-ui.cpp, src/path-chemistry.cpp, + src/rect-context.cpp, src/select-context.cpp, + src/selection-chemistry.cpp, src/selection.cpp, src/selection.h, + src/sp-flowtext.cpp, src/spiral-context.cpp, src/splivarot.cpp, + src/star-context.cpp, src/text-chemistry.cpp, src/text-context.cpp, + src/dialogs/find.cpp, src/dialogs/in-dt-coordsys.cpp, + src/dialogs/xml-tree.cpp: + + cleaned up the selection API slightly + +2005-03-20 cyreve + + * src/: text-context.cpp, text-context.h, text-editing.cpp, + text-editing.h, libnrtype/Layout-TNG-OutIter.cpp, + libnrtype/Layout-TNG.h: initial implementation of text selection + (keyboard only) + + * src/libnrtype/Layout-TNG-OutIter.cpp: making + createSelectionShape() work + + * src/: sp-text.cpp, sp-text.h: text-anchor sometimes won't work in + text on a path when x/y coordinates are set + + * src/libnrtype/Layout-TNG-Output.cpp: text on path: cut characters + before start of path and calculate bounding box correctly when + this happens + +2005-03-14 Jon A. Cruz + * src/dialogs/Makefile_insert, src/dialogs/swatches.cpp, + src/dialogs/swatches.h, src/verbs.h, src/verbs.cpp, + src/interface.cpp: + Initial cut of swatches panel. + +2005-03-19 cyreve + + * src/libnrtype/Layout-TNG-Compute.cpp: rendering of + multiple-character clusters in rtl text is wrong (bug 1166603) + + * src/: make.dep, make.files, make.ofiles, sp-text.cpp, sp-text.h, + text-editing.cpp: glue kerning info back together on deleting + line breaks + + * src/sp-tspan.cpp: textpath startOffset attribute doesn't save + correctly when it's a percentage (remnants of bug 1124722) + + * src/: text-context.cpp, text-context.h, text-editing.cpp, + text-editing.h, libnrtype/Layout-TNG.h: use Layout::iterator for + storing cursor position. Fixes bug 1093660 related to rtl cursor + movement + + * src/libnrtype/: Layout-TNG-OutIter.cpp, Layout-TNG.h: implement + backend cursor movement functions properly for multidirectional + text + + * src/libnrtype/Layout-TNG-Output.cpp: create more efficient + postscript output + + * src/libnrtype/: Layout-TNG-OutIter.cpp, Layout-TNG-Output.cpp, + Layout-TNG.h: obey text-align attribute when fitting text to a + path (fixes bug 1124722) + + * src/: attributes-test.cpp, attributes.cpp, attributes.h, + sp-flowtext.cpp, sp-text.cpp, sp-tspan.cpp, sp-tspan.h, + style-test.cpp, libnrtype/Layout-TNG-Output.cpp: wire up + startOffset attribute to textpath and fix bugs in it + + * src/sp-flowtext.cpp: unflow text command loses formatting + + * src/xml/repr-io.cpp: xml pretty-printer adding whitespace in + xml:space=preserve elements + + * src/: sp-flowtext.cpp, text-editing.cpp: line breaks not being + put before strings immediately following para elements, and + deleting line breaks copies style wrongly + +2005-03-18 MenTaLguY + + * src/file.cpp, src/sp-item-group.cpp, src/xml/Makefile_insert, + src/xml/node-fns-tree.cpp, src/xml/node-fns-tree.h, + src/xml/node-fns.cpp, src/xml/node-fns.h, src/xml/node-iterators.h, + src/xml/repr.cpp, src/xml/simple-node.cpp: + + renamed node-fns-tree to node-fns, and moved sp_repr_prev etc + into Inkscape::XML namespace (as e.g. previous_node) + +2005-03-18 cyreve + + * src/libnrtype/Layout-TNG-Compute.cpp: cursor position on blank + first line sometimes goes wrong + + * src/: make.dep, make.files, make.ofiles, text-editing.cpp: + spurious line break added before text in text and font dialog + (bug 1166016) + + * src/: make.dep, make.files, make.ofiles, libnrtype/FlowBoxes.cpp, + libnrtype/FlowBoxes.h, libnrtype/FlowDefs.h, + libnrtype/FlowDest.cpp, libnrtype/FlowDest.h, + libnrtype/FlowEater.cpp, libnrtype/FlowEater.h, + libnrtype/FlowRes.cpp, libnrtype/FlowRes.h, + libnrtype/FlowResOut.cpp, libnrtype/FlowSols.cpp, + libnrtype/FlowSols.h, libnrtype/FlowSrc.cpp, libnrtype/FlowSrc.h, + libnrtype/FlowSrcText.cpp, libnrtype/FlowSrcText.h, + libnrtype/FlowStyle.cpp, libnrtype/FlowStyle.h, + libnrtype/FlowUtils.cpp, libnrtype/FlowUtils.h, + libnrtype/Makefile_insert: remove all old text layout code (7,577 + lines) + + * src/: sp-flowregion.cpp, sp-flowregion.h, sp-flowtext.cpp, + sp-string.cpp, sp-tspan.cpp: purge flow_dest class from code + + * src/: text-editing.cpp, libnrtype/Layout-TNG-Compute.cpp, + libnrtype/Layout-TNG.cpp, libnrtype/Layout-TNG.h: define a value + for line-height:normal and use it consistently + + * src/: sp-text.cpp, sp-text.h, text-editing.cpp: adjust kerning + attributes on adding/removing line breaks + +2005-03-17 MenTaLguY + + * src/display/nr-arena-group.cpp, src/display/nr-arena-item.cpp: + + whoops, we were calling the 'children' vfunc rather than + 'last_child' when appending, hence the bug... fixed now. + +2005-03-17 cyreve + + * src/: sp-text.cpp, libnrtype/Layout-TNG-Compute.cpp, + libnrtype/Layout-TNG-OutIter.cpp, libnrtype/Layout-TNG.h: x,y + attributes on tspans set wrongly when alignment != left (bug + 1165427) + + * src/: sp-text.cpp, sp-text.h: break before tspan role=line + elements, ie allow first tspan not to have role=line + + * src/: make.dep, make.files, make.ofiles, sp-flowtext.cpp, + sp-object.cpp: fix inheritance problems with xml:space attribute + + * src/libnrtype/Layout-TNG-OutIter.cpp: crash on pressing enter + immediately after creating text + + * src/: object-ui.cpp, sp-flowtext.cpp: set xml:space=preserve on + new flowdiv elements + + * src/libnrtype/Layout-TNG-Compute.cpp: second try at solving + numerical problems when line-height is set + + * src/: sp-flowtext.cpp, sp-flowtext.h, verbs.cpp: slightly + objectify SPFlowtext and rearrange its updating a tiny bit + + * src/: path-chemistry.cpp, sp-flowregion.cpp, sp-offset.cpp, + sp-text.cpp, sp-text.h, sp-use-reference.cpp, splivarot.cpp: + slightly objectify SPText & rearrange updating code, also fixes + bug causing all letters to appear on top of each other + + * src/libnrtype/Layout-TNG-Compute.cpp: characters will draw + multiple times when x or y attributes set + +2005-03-16 cyreve + + * src/text-editing.cpp: kerning: add/remove kerns with + insertion/deletion of characters, and only apply kerns to the + topmost xml object + + * src/: help.cpp, selection-chemistry.cpp, sp-text.cpp, sp-text.h, + text-context.cpp, text-editing.cpp, text-editing.h, + dialogs/text-edit.cpp: move functions applying to both text and + flowtext to text-editing & rename them. Also fixes crash on + letter/linespacing adjustment for flowtext + + * src/text-editing.cpp: fix crash on pressing delete at the end of + text + + * src/: text-editing.cpp, libnrtype/Layout-TNG-Compute.cpp, + libnrtype/Layout-TNG-OutIter.cpp, libnrtype/Layout-TNG.h: + position cursor correctly in empty text objects + + * src/: sp-item-group.cpp, sp-object.cpp: optimise adding children + to the end of a group - big improvement for tile clones + + * src/: sp-flowtext.cpp, sp-text.cpp, text-context.cpp, + text-editing.cpp, text-editing.h: text editing fixes: track line + breaks with preceding para tag, finish abstracting line + break/remove functions to work on flowtext + + * src/libnrtype/Layout-TNG-Compute.cpp: cursor positioning + off-by-one in some cases of wrapped text + +2005-03-15 cyreve + + * src/libnrtype/Layout-TNG-Compute.cpp: small tweak to make cursor + positioning work right in counterdirectional spans in fully + justified text + + * src/sp-text.cpp: tweak function for adjusting linespacing by + keyboard to be more precise + + * src/: attributes-test.cpp, attributes.cpp, make.dep, make.files, + make.ofiles, style-test.cpp, style.cpp, + libnrtype/Layout-TNG-Output.cpp: make the unit tests pass for the + new styles, and workaround build breakage when pango < 1.8 + installed + + * src/: sp-flowtext.cpp, sp-flowtext.h, + libnrtype/Layout-TNG-Compute.cpp, + libnrtype/Layout-TNG-Scanline-Makers.cpp, libnrtype/Layout-TNG.h: + wiring up full justification to old attribute & fixing bugs in + it, which turned in to a major refactoring of layout code + +2005-03-14 Jon Phillips + * src/attributes-test.cpp, src/attributes.cpp, src/attributes.h, + src/desktop.cpp, src/sp-namedview.cpp, src/sp-namedview.h, + src/dialogs/desktop-properties.cpp: + Added showpageshadow preference to document preferences. Set to + on automatically and saves with document if off. + +2005-03-14 MenTaLguY + + * src/display/nr-arena-item.h, src/display/nr-arena-item.cpp, + src/display/nr-arena-group.cpp: + + added virtual accessor for last child + +2005-03-14 Jon A. Cruz + * src/interface.cpp, src/verb.cpp, src/verbs.h, + src/ui/widget/panel.cpp, src/dialogs/Makefile_insert, + src/dialogs/extensions.cpp, src/dialogs/extensions.h, + src/extension/error-file.cpp: + Added rough cut of initial extensions panel and dialog. + +2005-03-13 Bryce Harrington + + * src/path-prefix.h: Rearranging linking of libui and libutil + + * src/application/application.cpp, src/application/application.h + src/application/editor-impl.cpp, + src/ui/dialog/dialog-manager.cpp, src/ui/dialog/dialog.cpp, + src/ui/dialog/dialog.h, src/ui/widget/labelled.cpp, + src/ui/dialog/transformation.h, src/ui/dialog/transformation.cpp, + src/ui/widget/unit-menu.h, src/util/units.cpp: + Integrating Transformation dialog. Removing hardcoded paths. + + * share/icons/Makefile.in, share/icons/arrows-horiz.svg, + share/icons/arrows-vert.svg, share/icons/arrows_hor.xpm, + share/icons/arrows_ver.xpm, share/icons/rotate.svg, + share/icons/rotate.xpm, share/icons/scale_hor.xpm, + share/icons/scale_ver.xpm, share/icons/Makefile.am: + Adding icons needed by transformation dialog + + * share/ui/units.txt, share/ui/units.xml: + Moving units into ui/ subdir. Dunno if this is the best + location for them, but pjrm thought it'd be ok for now. + +2005-03-13 cyreve + + * src/sp-text.cpp: allow adjusting letter spacing when cursor is at + eol + + * src/: make.dep, make.files, make.ofiles, + libnrtype/Layout-TNG-Compute.cpp, + libnrtype/Layout-TNG-OutIter.cpp, + libnrtype/Layout-TNG-Output.cpp, libnrtype/Layout-TNG.h: fix + kerning when align != left, and fix linespacing < 100 + + * src/: sp-flowtext.cpp, sp-text.cpp, sp-text.h, style.cpp, + style.h, libnrtype/Layout-TNG-Compute.cpp, + libnrtype/Layout-TNG-Input.cpp, libnrtype/Layout-TNG-OutIter.cpp, + libnrtype/Layout-TNG-Output.cpp, + libnrtype/Layout-TNG-Scanline-Maker.h, libnrtype/Layout-TNG.h: + implement line-height css property, & fix percentage handling in + style + +2005-03-12 MenTaLguY + + * src/node-context.cpp, src/node-context.h, src/nodepath.cpp, + src/nodepath.h, src/toolbox.cpp, src/dialogs/align.cpp: + + Renamed Path namespace to Inkscape::NodePath, to avoid conflict + with livarot + +2005-03-12 Kees Cook + + * inkscape.nsi: added German translation from Adib Taraben. + +2005-03-12 MenTaLguY + + * src/sp-namedview.cpp, src/sp-metadata.cpp: it's valid for an SPObject + 'write' method to be passed the object's own XML node; account for this. + +2005-03-12 MenTaLguY + + * src/xml/simple-node.cpp: assert that src != this in + SimpleNode::mergeFrom + +2005-03-12 MenTaLguY + + * src/gc-alloc.h: minor cosmetic adjustments + + * src/util/list-container.h: pedantically correct implementation of + ListContainer::max_size() + + * src/xml/simple-node.cpp: use Util::ListContainer iterators in a more + STL-ish fashion + +2005-03-12 Jon A. Cruz + * src/ui/widget/panel.h, src/ui/widget/panel.cpp, + src/ui/widget/Makefile_insert, src/dialogs/iconpreview.h, + src/dialogs/iconpreview.cpp: + Initial addition of Panel. + +2005-03-12 cyreve + + * src/sp-flowtext.cpp: text unflow command losing space characters: + add xml:space to generated elements + + * src/: attributes.cpp, attributes.h, make.dep, make.files, + make.ofiles, sp-flowtext.cpp, sp-text.cpp, style.cpp, style.h, + text-context.cpp, text-editing.cpp, dialogs/text-edit.cpp, + libnrtype/FlowRes.cpp, libnrtype/Layout-TNG-Compute.cpp, + libnrtype/Layout-TNG-Input.cpp: add several new text properties + to SPStyle and rearrange some of the existing ones, also remove + spurious warning on applying kerning + + * src/sp-flowtext.cpp: svg spec requires us to break after flowline + content, not before + +2005-03-11 cyreve + + * src/desktop-style.cpp, src/sp-text.cpp, src/sp-text.h, + src/sp-tspan.cpp, src/sp-tspan.h, src/text-chemistry.cpp, +src/text-editing.cpp, + src/text-editing.h: combine the common attribute handling for text, + tspan and textpath into one class + + * src/sp-flowtext.cpp, src/sp-string.cpp: reimplement xml:space attribute + + * src/sp-text.cpp, src/libnrtype/Layout-TNG-OutIter.cpp, + src/libnrtype/Layout-TNG.h: apply calculated x/y attributes to tspan + role=line elements + + * src/libnrtype/Layout-TNG-Output.cpp: postscript text output + incorrectly scaled (and other problems) + +2005-03-10 cyreve + + * src/sp-flowdiv.h, src/sp-flowtext.h, + src/sp-text.cpp, src/sp-text.h, src/sp-tspan.h, src/text-context.cpp, + src/text-editing.cpp, src/text-editing.h, + src/libnrtype/Layout-TNG-Compute.cpp, + src/libnrtype/Layout-TNG-OutIter.cpp: clean up xml tree properly on + deleting line break, & fix various compile issues + + * src/nodepath.cpp, src/sp-flowdiv.cpp, + src/sp-flowdiv.h, src/sp-flowtext.cpp, src/sp-flowtext.h, +src/sp-string.cpp, + src/sp-string.h, src/sp-text.cpp, src/sp-text.h, src/sp-tspan.cpp, +src/sp-tspan.h, + src/text-editing.cpp, src/verbs.cpp, src/libnrtype/FontInstance.cpp, + src/libnrtype/font-instance.h, src/livarot/Shape.h, + src/libnrtype/Layout-TNG-Compute.cpp, src/libnrtype/Layout-TNG-Input.cpp, + src/libnrtype/Layout-TNG-OutIter.cpp, + src/libnrtype/Layout-TNG-Output.cpp, + src/libnrtype/Layout-TNG-Scanline-Maker.h, + src/libnrtype/Layout-TNG-Scanline-Makers.cpp, + src/libnrtype/Layout-TNG.cpp, libnrtype/Layout-TNG.h: huge rewrite of + text layout (and some text editing) code + +2005-03-07 Kees Cook + + * src/libnr/have_mmx.S, src/libnr/nr_mmx_R8G8B8A8_P_EMPTY_A8_RGBAP.S, + src/libnr/nr_mmx_R8G8B8A8_P_R8G8B8A8_P_A8_RGBAP.S, + src/libnr/nr_mmx_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_TRANSFORM.S, + src/libnr/nr_mmx_R8G8B8_R8G8B8_R8G8B8A8_P.S: execstack patch + from Mike Hearn. + +2005-03-07 Jon A. Cruz + * src/interface.cpp, src/verbs.h, src.verbs.cpp, src/widgets/icon.cpp, + src/dialogs/iconpreview.h, src/dialogs/iconpreview.cpp, + src/dialogs/Makefile_insert: + Initial cut of icon preview. + +2005-03-05 Bryce Harrington + + * share/icons/*.svg, share/icons/Makefile.am: Adding icons for + new gui interface + + * src/ui/icons.cpp: Fixing some paths + + * src/main.cpp src/application/Makefile_insert, + src/application/app-prototype.h, + src/application/application.cpp src/application/editor.cpp, + src/ui/widget/toolbox.cpp, + src/application/editor-impl.cpp: + Broke out editor-impl class to its own file. Continued getting + the new interface to the point where it'll load and run. + + * share/ui/keybindings.rc, share/ui/toolbox.xml, share/ui/menus-bars.xml: + Migrating some of the UI definition stuff into main codebase + +2005-03-05 Jon A. Cruz + * src/widgets/layer-selector.cpp, src/widgets/icon.h, + src/widgets/icon.cpp, src/dialogs/align.cpp, src/dialogs/find.cpp, + src/dialogs/object-properties.cpp, src/dialogs/stroke-style.cpp, + src/dialogs/text-edit.cpp, src/dialogs/transformation.cpp, + src/dialogs/xml-tree.cpp, src/interface.cpp: + Purging PixBufFactory and sp_icon_new_scaled. + +2005-03-05 Jon A. Cruz + * src/widgets/icon.cpp, src/widgets/icon.cpp: Switched icon loading + to be deferred and react to theme changes on-the-fly. + +2005-03-05 Bryce Harrington + + * src/application/Makefile_insert, + src/application/app-prototype.cpp, + src/application/editor.h, + src/application/app-prototype.h, + src/application/application.cpp: + Adding Application::AppPrototype class + * src/application/editor.cpp, + src/application/editor.h: + Changing member function getImpl() to getWindow() + +2005-03-04 Jon A. Cruz + * src/widgets/icon.cpp: Changed stock item loading to use stock + GtkImage widgets directly. + +2005-03-03 MenTaLguY + + * src/widgets/icon.cpp: more idiomatic iteration + +2005-03-02 Jon A. Cruz + * src/toolbox.cpp: Added preference to make the top toolbox 'small'. + +2005-03-02 Jon A. Cruz + * src/desktop-events.cpp, src/desktop.cpp, src/gradient-toolbar.cpp, + src/interface.cpp, src/select-toolbar.cpp, src/toolbox.cpp, + src/toolbox.h, src/dialogs/find.cpp, + src/dialogs/object-properties.cpp, src/dialogs/stroke-style.cpp, + src/dialogs/text-edit.cpp, src/dialogs/transformation.cpp, + src/dialogs/xml-tree.cpp, src/widgets/button.cpp, + src/widgets/button.h, src/widgets/icon.cpp, src/widgets/icon.h, + src/widgets/layer-selector.cpp, src/widgets/paint-selector.cpp, + src/widgets/widget-sizes.h: + Initial pass removing hardcoded icon sizes. + +2005-03-01 MenTaLguY + + * src/extensions/internal/ps.cpp: apply patch from Michael Forbes + (miforbes@mbhs.edu) to support gradient fills in Postscript + +2005-03-01 MenTaLguY + + * src/xml/node.h, src/xml/simple-node.cpp, src/xml/simple-node.h: + + begin migration of notification interface to use NodeObserver + rather than NodeEventVector + +2005-03-01 MenTaLguY + + * src/xml/Makefile_insert, src/xml/node-listener.h, src/xml/repr.cpp, + src/xml/simple-node.cpp, src/xml/simple-node.h: + + reworked listener list to use Util::ListContainer + + * src/xml/node-observer.h: minor name cleanups + +2005-03-01 MenTaLguY + + * src/Makefile.am, src/algorithms/find-if-before.h: + + added new generic algorithm + +2005-03-01 MenTaLguY + + * src/Makefile.am, src/util/Makefile_insert, + src/util/list-container-test.cpp, src/util/list-container.h: + + tests and fixes for Util::ListContainer + +2005-03-01 MenTaLguY + + * src/Makefile.am, src/libnr/Makefile_insert, src/xml/Makefile_insert: + use in-tree copy of cxxtest + + * src/util/Makefile_insert, src/util/list-container.h: + add Util::List-based STL container + +2005-02-28 SwinginCelt + + * Fixed an improper conversion of sp_repr_document_merge that was causing + extra data being written to the prefrences file every time inkscape + exited. + +2005-02-26 SwinginCelt + + * Replaced all sp_repr_set_content calls with direct call to + repr->setContent. + * Replaced all sp_repr_merge calls with direct call to + repr->mergeFrom. + * Removed inline sp_repr_document_merge because it wasn't used anywhere. + * Removed inline sp_repr_set_content because it wasn't used anywhere. + +2005-02-26 MenTaLguY + + * cxxtest: imported cxxtest tree + +2005-02-24 Jon A. Cruz + * src/main.cpp, io/sys.h, io/sys.cpp: + Refactoring input filename conversion and fallback. + Fixes bug #1151536. + +2005-02-22 Jon A. Cruz + * src/main.cpp: + Refactoring sp_main_*. Adding cleanup phase on extracted filename list. + +2005-02-22 Bryce Harrington + + * src/main.cpp, src/application/application.cpp: Adding --new-gui + option. + +2005-02-22 Ted Gould + + * src/interface.cpp: + + Changing the effects menu to be driven by the preferences file so that the + file can be the same whether or not the effects are shown. + +2005-02-22 MenTaLguY + + * src/desktop-style.cpp, src/selection-chemistry.cpp, + src/xml/attribute-record.h, src/xml/node.h, src/xml/repr-css.cpp, + src/xml/repr-io.cpp, src/xml/simple-node.cpp, src/xml/simple-node.h: + + use Inkscape::Util::List for attribute lists, and sprinkle some + appropriate 'using's in to make things less verbose + +2005-02-22 Jon A. Cruz + * src/inkscape.cpp, src/main.cpp, src/extension/input.cpp, src/io/sys.cpp, + src/xml/repr-io.cpp: + Better catching of problematic filenames. + Made segv handler only use dialog box when app is using a gui. + Fixes bug #1145847. + +2005-02-22 Ted Gould + + * src/extension/effect.cpp, src/extension/prefdialog.cpp, + src/extension/prefdialog.h, + src/extension/implementation/implementation.cpp, + src/extension/implementation/implementation.h, + src/extension/implementation/plugin-link.h, + src/extension/implementation/plugin.cpp, + src/extension/implementation/plugin.h, + src/extension/implementation/script.cpp, + src/extension/implementation/script.h, src/extension/plugin/grid.cpp: + + Changing the API of the effects preferences so that it doesn't use + sockets and plugs anymore. Now there is a generic widget passed down so + that should work on every platform. + + * src/extension/plugin/grid.cpp: + + Fixing the grid so that it uses the right axis. + + * share/extensions/Makefile.am, share/extensions/bluredge.inx, + share/extensions/randompnt.inx, share/extensions/randompos.inx, + src/extension/plugin/Makefile_insert, src/extension/plugin/bluredge.cpp, + src/extension/plugin/randompnt.cpp, src/extension/plugin/randompos.cpp: + + Adding some cool new effects, well, they're not really done yet, + but getting the basis code into CVS so I don't loose it :) + +2005-02-21 MenTaLguY + + * src/file.cpp, src/sp-item-group.cpp, src/xml/Makefile_insert, + src/xml/node-fns-tree.cpp, src/xml/node-fns-tree.h, + src/xml/repr-get-children.cpp, src/xml/repr-get-children.h, + src/xml/repr.cpp, src/xml/simple-node.cpp: + + renamed header files + + * src/xml/Makefile_insert, src/xml/invalid-operation-exception.h: + + added Inkscape::XML::InvalidOperationException + + * src/xml/simple-node.h: + + avoid a second indirect function call from SimpleNode::appendChild + +2005-02-20 SwinginCelt + + * Replaced all sp_repr_attr calls with direct call to + repr->attribute. + * Replaced all sp_repr_document_unref calls with direct call to + Inkscape::GC::release(...). + * Removed iinline sp_repr_document_ref because it wasn't used anywhere. + +2005-02-20 MenTaLguY + + * src/inkscape.cpp: removed unused signals + +2005-02-19 MenTaLguY + + * src/arc-context.cpp, src/desktop.cpp, src/document-private.h, + src/document-undo.cpp, src/document.cpp, src/event-context.cpp, + src/gradient-chemistry.cpp, src/gradient-chemistry.h, + src/gradient-drag.cpp, src/gradient-drag.h, src/node-context.cpp, + src/rect-context.cpp, src/sp-object.cpp, src/spiral-context.cpp, + src/star-context.cpp, src/toolbox.cpp, + src/dialogs/desktop-properties.cpp, src/widgets/gradient-vector.cpp, + src/widgets/layer-selector.cpp, src/widgets/sp-widget.cpp, + src/widgets/sp-xmlview-attr-list.cpp, src/widgets/sp-xmlview-content.cpp, + src/widgets/sp-xmlview-tree.cpp, src/xml/Makefile_insert, + src/xml/attribute-record.h, src/xml/document.h, src/xml/event-fns.h, + src/xml/event.cpp, src/xml/event.h, src/xml/node-event-vector.h, + src/xml/node-iterators.h, src/xml/node-listener.h, src/xml/node.h, + src/xml/repr-action-test.cpp, src/xml/repr-css.cpp, src/xml/repr-io.cpp, + src/xml/repr-sorting.cpp, src/xml/repr-util.cpp, src/xml/repr.cpp, + src/xml/repr.h, src/xml/simple-document.h, src/xml/simple-node.cpp, + src/xml/simple-node.h, src/xml/simple-session.cpp, + src/xml/sp-css-attr.h, src/xml/sp-repr-action-fns.h, + src/xml/sp-repr-action.cpp, src/xml/sp-repr-action.h, + src/xml/sp-repr-attr.h, src/xml/sp-repr-doc.h, + src/xml/sp-repr-event-vector.h, src/xml/sp-repr-iterators.h, + src/xml/sp-repr-listener.h, src/xml/sp-repr.h: + + renamed header files to match new class names + +2005-02-19 MenTaLguY + + * src/arc-context.cpp, src/arc-context.h, src/desktop-events.cpp, + src/desktop-style.cpp, src/desktop-style.h, src/desktop.cpp, + src/document-private.h, src/document-undo.cpp, src/document.cpp, + src/document.h, src/draw-context.cpp, src/dyna-draw-context.cpp, + src/dyna-draw-context.h, src/event-context.cpp, src/event-context.h, + src/file.cpp, src/gradient-chemistry.cpp, src/inkscape.cpp, + src/inkscape.h, src/inkview.cpp, src/interface.cpp, src/knotholder.cpp, + src/knotholder.h, src/layer-fns.cpp, src/main.cpp, src/node-context.cpp, + src/nodepath.cpp, src/nodepath.h, src/object-ui.cpp, + src/path-chemistry.cpp, src/prefs-utils.cpp, src/rect-context.cpp, + src/rect-context.h, src/selection-chemistry.cpp, src/selection.cpp, + src/selection.h, src/seltrans.cpp, src/sp-anchor.cpp, + src/sp-animation.cpp, src/sp-clippath.cpp, src/sp-conn-end-pair.cpp, + src/sp-conn-end-pair.h, src/sp-defs.cpp, src/sp-ellipse.cpp, + src/sp-flowdiv.cpp, src/sp-flowregion.cpp, src/sp-flowtext.cpp, + src/sp-gradient-fns.h, src/sp-gradient-test.cpp, src/sp-gradient.cpp, + src/sp-guide.cpp, src/sp-image.cpp, src/sp-item-group.cpp, + src/sp-item.cpp, src/sp-item.h, src/sp-line.cpp, + src/sp-linear-gradient-fns.h, src/sp-marker.cpp, src/sp-mask.cpp, + src/sp-metadata.cpp, src/sp-namedview.cpp, src/sp-namedview.h, + src/sp-object-group.cpp, src/sp-object-repr.cpp, src/sp-object-repr.h, + src/sp-object.cpp, src/sp-object.h, src/sp-offset.cpp, src/sp-offset.h, + src/sp-path.cpp, src/sp-pattern.cpp, src/sp-polygon.cpp, + src/sp-polyline.cpp, src/sp-radial-gradient-fns.h, src/sp-rect.cpp, + src/sp-root.cpp, src/sp-shape.cpp, src/sp-skeleton.cpp, + src/sp-spiral.cpp, src/sp-star.cpp, src/sp-string.cpp, + src/sp-symbol.cpp, src/sp-text.cpp, src/sp-tspan.cpp, + src/sp-use-reference.h, src/sp-use.cpp, src/spiral-context.cpp, + src/spiral-context.h, src/splivarot.cpp, src/star-context.cpp, + src/star-context.h, src/style.cpp, src/style.h, src/text-chemistry.cpp, + src/text-context.cpp, src/text-editing.cpp, src/toolbox.cpp, + src/verbs.cpp, src/application/application.cpp, + src/application/application.h, src/application/editor.h, + src/dialogs/clonetiler.cpp, src/dialogs/desktop-properties.cpp, + src/dialogs/export.cpp, src/dialogs/fill-style.cpp, src/dialogs/rdf.cpp, + src/dialogs/sp-attribute-widget.cpp, src/dialogs/sp-attribute-widget.h, + src/dialogs/stroke-style.cpp, src/dialogs/text-edit.cpp, + src/dialogs/tiledialog.cpp, src/dialogs/xml-tree.cpp, + src/ecma/EcmaBinding.cpp, src/ecma/EcmaBinding.h, + src/extension/dependency.cpp, src/extension/dependency.h, + src/extension/effect.cpp, src/extension/effect.h, + src/extension/extension.cpp, src/extension/extension.h, + src/extension/input.cpp, src/extension/input.h, + src/extension/output.cpp, src/extension/output.h, + src/extension/print.cpp, src/extension/print.h, src/extension/system.cpp, + src/extension/implementation/plugin.cpp, + src/extension/implementation/script.cpp, + src/extension/implementation/script.h, + src/extension/internal/gdkpixbuf-input.cpp, + src/extension/internal/pov-out.cpp, src/extension/internal/ps.cpp, + src/extension/internal/svg.cpp, src/extension/plugin/grid.cpp, + src/helper/stock-items.cpp, src/trace/trace.cpp, + src/widgets/dash-selector.cpp, src/widgets/dash-selector.h, + src/widgets/gradient-selector.cpp, src/widgets/gradient-vector.cpp, + src/widgets/layer-selector.cpp, src/widgets/layer-selector.h, + src/widgets/paint-selector.cpp, src/widgets/sp-widget.cpp, + src/widgets/sp-widget.h, src/widgets/sp-xmlview-attr-list.cpp, + src/widgets/sp-xmlview-attr-list.h, src/widgets/sp-xmlview-content.cpp, + src/widgets/sp-xmlview-content.h, src/widgets/sp-xmlview-tree.cpp, + src/widgets/sp-xmlview-tree.h, src/widgets/spw-utilities.h, + src/xml/comment-node.h, src/xml/element-node.h, src/xml/node-observer.h, + src/xml/repr-action-test.cpp, src/xml/repr-css.cpp, + src/xml/repr-get-children.cpp, src/xml/repr-get-children.h, + src/xml/repr-io.cpp, src/xml/repr-sorting.cpp, src/xml/repr-sorting.h, + src/xml/repr-util.cpp, src/xml/repr.cpp, src/xml/repr.h, + src/xml/session.h, src/xml/simple-document.h, src/xml/simple-node.cpp, + src/xml/simple-node.h, src/xml/simple-session.cpp, + src/xml/simple-session.h, src/xml/sp-css-attr.h, + src/xml/sp-repr-action-fns.h, src/xml/sp-repr-action.cpp, + src/xml/sp-repr-action.h, src/xml/sp-repr-attr.h, + src/xml/sp-repr-doc.h, src/xml/sp-repr-event-vector.h, + src/xml/sp-repr-iterators.h, src/xml/sp-repr-listener.h, + src/xml/sp-repr.h, src/xml/text-node.h, src/xml/transaction-logger.h: + + SPRepr -> Inkscape::XML::Node + SPReprDoc -> Inkscape::XML::Document + SPReprAttr -> Inkscape::XML::AttributeRecord + SPReprAction -> Inkscape::XML::Event + SPReprEventVector -> Inkscape::XML::EventVector + SPReprListener -> Inkscape::XML::NodeListener + + etc.. + +2005-02-19 Jon A. Cruz + * src/extension/extension.h, src/extension/internal/svg.cpp, + src/extension/internal/svgz.cpp: + Fixing .svgz Inkscape save and adding .svgz Plain save. + Fixes bug #1144223 + +2005-02-18 Jon A. Cruz + * src/Makefile.am, src/libnr/Makefile_insert, + src/libnr/nr-point-fns-test.h src/libnr/nr-types-test.h: + Adding initial version of CxxTest test cases. + +2005-02-17 Jon A. Cruz + + * src/io/gzipinputstream.h, src/io/gzipinputstream.cpp: Changed + decompression to be streammed and removed hardcoded limit. + +2005-02-17 MenTaLguY + + * src/inkscape.h, src/inkscape.cpp, src/desktop.cpp: + + rewrote "last desktop standing" test to not suck + +2005-02-15 SwinginCelt + + * Replaced some sp_repr_attr calls with direct call to + repr->attribute. + +2005-02-16 John Cliff + + * src/dialogs/tiledialog.h, src/dialogs/tiledialog.cpp, + src/dialogs/makefile_insert, src/verbs.cpp, src/verbs.h: + Added a dialog that allows you to arrange the selection + in a grid pattern with user defined spacing. + its in objects->grid arrange... + +2005-02-15 SwinginCelt + + * Replaced inline function sp_repr_name with direct call to + repr->name. + * Replaced inline function sp_repr_content with direct call to + repr->content. + * Replaced inline function sp_repr_has_attr with direct call to + repr->matchAttributeName. + +2005-02-15 MenTaLguY + + * src/document.cpp, src/document.h, src/file.cpp, src/help.cpp, + src/inkscape.cpp, src/inkview.cpp, src/slideshow.cpp, + src/dialogs/filedialog.cpp, src/dialogs/stroke-style.cpp, + src/extension/internal/gdkpixbuf-input.cpp, + src/extension/internal/svg.cpp, src/extension/plugin/gimpgrad.cpp, + src/helper/stock-items.cpp, src/widgets/icon.cpp: + + removed unused SPDocument::advertize + +2005-02-14 MenTaLguY + + * src/document.cpp: remove redundant assignment that appears to confuse + gcc anyhow + +2005-02-14 SwinginCelt + + * Replaced inline function sp_repr_set_position_absolute with + direct call to repr>->setPosition. + +2005-02-13 Bryce + + * src/main.cpp, src/application/application.cpp, src/inkscape.h, + src/application/editor-impl.h, src/application/editor.cpp + src/application/editor.h, src/ui/dialog/dialog-manager.cpp, + src/ui/dialog/dialog-manager.h, src/application/app-prototype.h + src/application/application.h: Integrating I::A::Application + into the execution path. Now its run() routine is called from + main(). + + * src/application/Makefile_insert, src/application/makefile.in, + src/application/editor-impl.h, src/application/editor.cpp, + src/application/editor.h: Initial import of inkscape_gtkmm + code. Also see doc/NewAppArchitecture/ presentation for the + rationale behind this. + + * src/ui/dialog/align-and-distribute.cpp, +src/ui/dialog/align-and-distribute.h, + src/ui/dialog/dialog-manager.cpp, src/ui/dialog/dialog-manager.h, + src/ui/dialog/dialog.cpp, src/ui/dialog/dialog.h, + src/ui/dialog/document-preferences.cpp, +src/ui/dialog/document-preferences.h, + src/ui/dialog/export.cpp, src/ui/dialog/export.h, + src/ui/dialog/extension-editor.cpp, src/ui/dialog/extension-editor.h, + src/ui/dialog/fill-and-stroke.cpp, src/ui/dialog/fill-and-stroke.h, + src/ui/dialog/find.cpp, src/ui/dialog/find.h, + src/ui/dialog/inkscape-preferences.cpp, +src/ui/dialog/inkscape-preferences.h, + src/ui/dialog/layer-editor.cpp, src/ui/dialog/layer-editor.h, + src/ui/dialog/messages.cpp, src/ui/dialog/messages.h, + src/ui/dialog/text-properties.cpp, src/ui/dialog/text-properties.h, + src/ui/dialog/tree-editor.cpp, src/ui/dialog/tree-editor.h, + src/ui/dialog/xml-editor.cpp, src/ui/dialog/xml-editor.h, + src/ui/widget/combo-text.cpp, src/ui/widget/combo-text.h, + src/ui/widget/handlebox.cpp, src/ui/widget/handlebox.h, + src/ui/widget/icon-widget.cpp, src/ui/widget/icon-widget.h, + src/ui/widget/labelled.cpp, src/ui/widget/labelled.h, + src/ui/widget/notebook-page.cpp, src/ui/widget/notebook-page.h, + src/ui/widget/scalar-unit.cpp, src/ui/widget/scalar-unit.h, + src/ui/widget/scalar.cpp, src/ui/widget/scalar.h, + src/ui/widget/toolbox.cpp, src/ui/widget/toolbox.h, + src/ui/widget/unit-menu.cpp, src/ui/widget/unit-menu.h: + Initial import of the gtkmm code. These are mainly + unimplemented stubs, but have few dependencies so are easy to + integrate at this stage. + + * src/ui/widget/Makefile_insert, src/ui/widget/makefile.in, + src/ui/dialog/Makefile_insert, src/ui/dialog/makefile.in, + src/ui/Makefile_insert, src/ui/makefile.in: Adding makefile + support for new code. + + * io/simple-sax.h, io/simple-sax.cpp: Adding Jon's simple SAX + code + + * util/units.h, util/units.cpp: New inkscape_gtkmm units code + +2005-02-12 MenTaLguY + + * src/document.cpp, src/document.h, src/sp-gradient-test.cpp: + + SPDocument is now a "real C++ class", managed by the garbage collector + +2005-02-12 MenTaLguY + + * src/document-private.h, src/document.cpp, src/document.h, src/view.cpp, + src/view.h, src/dialogs/xml-tree.cpp: + + switched SPDocument to sigc++ signals + +2005-02-12 Kees Cook + + * Makefile.am, configure.ac, Makefile.mingw.common, inkscape.nsi: undoing + my "configure" changes. Was dumb and forgot about native compiles on + win32. + * inkview.1.in, share/extensions/inkscape-shadow-white.sh, + share/extensions/inkscape-shadow.sh: corrections found by Wolfram + Quester during Debian packaging. + * src/desktop-events.cpp, src/file.cpp, src/gradient-chemistry.cpp, + src/interface.cpp, src/layer-fns.cpp, src/nodepath.cpp, + src/object-ui.cpp, src/path-chemistry.cpp, src/prefs-utils.cpp, + src/selection-chemistry.cpp, src/seltrans.cpp, src/sp-flowtext.cpp, + src/sp-object.cpp, src/sp-pattern.cpp, src/sp-text.cpp, src/splivarot.cpp, + src/text-editing.cpp, src/dialogs/clonetiler.cpp, src/dialogs/rdf.cpp, + src/dialogs/stroke-style.cpp, src/dialogs/xml-tree.cpp, + src/extension/internal/gdkpixbuf-input.cpp, src/extension/plugin/grid.cpp, + src/widgets/gradient-selector.cpp, src/xml/repr-action-test.cpp, + src/xml/repr-css.cpp, src/xml/repr-io.cpp, src/xml/repr-util.cpp, + src/xml/repr.cpp, src/xml/repr.h: inline function removal patches from + Robert Crosbie. + +2005-02-11 Kees Cook + + * src/Makefile.mingw, src/make.*: win32 compile updates. + * src/extensions/internal/gnome.cpp: added my missing "comment" code. + * src/shortcuts.cpp, doc/keys.xml, doc/keys.html, share/screens/keys.svg: + added explicit ctrl-w. since gtk already binds it, we may as well show it. + +2005-02-10 Jon A. Cruz + + * src/inkscape.cpp: Changed from SHGetSpecialFolderPath to + SHGetSpecialFolderLocation. Fixes bug #1085641 + +2005-02-10 MenTaLguY + + * src/document.h, src/document.cpp: get rid of casting macro uses + +2005-02-10 MenTaLguY + + * src/desktop.cpp, src/document-undo.cpp, src/document.cpp, src/file.cpp, + src/gradient-chemistry.cpp, src/inkscape.cpp, src/interface.cpp, + src/sp-metadata.cpp, src/sp-namedview.cpp, src/sp-object-repr.cpp, + src/sp-object.cpp, src/svg-view.cpp, src/uri-references.cpp, + src/view.cpp, src/dialogs/stroke-style.cpp, + src/widgets/gradient-selector.cpp, src/widgets/gradient-vector.cpp: + + get rid needless uses of SP_IS_DOCUMENT (if we can't trust the + compiler's type checking, what can we trust?) + +2005-02-10 MenTaLguY + + * src/desktop-style.h, src/desktop.h, src/document.h, src/event-context.h, + src/inkscape.h, src/knotholder.h, src/nodepath.h, + src/selection-chemistry.h, src/selection.h, src/sp-conn-end-pair.h, + src/sp-object-repr.h, src/sp-object.h, src/style.h, + src/dialogs/sp-attribute-widget.h, src/extension/implementation/script.h, + src/xml/repr-get-children.h, src/xml/repr.h, src/xml/sp-repr-action.h, + src/xml/sp-repr-attr.h, src/xml/xml-forward.h: + + got rid of xml-forward.h + +2005-02-10 Kees Cook + + * configure.ac, Makefile.am, src/Makefile.am, Makefile.mingw.common.in, + inkscape.nsi.in: setting up "configure" to build the other files that + expect version numbers to get updated. Including mingw files in dist + package. + +2005-02-10 Jon A. Cruz + * src/io/uristream.h, src/io/uristream.cpp, + src/extension/internal/svg.h, src/extension/internal/svg.cpp, + src/extension/internal/Makefile_insert, + src/extension/internal/extension.h, + src/extension/internal/init.cpp: + Adding internal .svgz load and save extension. + Probable fix for bugs #1074996, #1050361, #925033, #1052307 + +2005-02-08 Kees Cook + + * src/extension/implementation/script.cpp: proper /tmp handling. + Closes bug #1074996. + * src/inkscape.cpp, src/inkscape.h, src/dialogs/export.cpp: correction + for export dialog paths. Closes bug #1114714. + * inkscape.nsi, Makefile.mingw.common: version bumps + * src/text-context.cpp: removed preedit code; it was broken and unneeded. + +2005-02-08 Ted Gould + + * Released 0.41 + +2005-02-01 Kees Cook + + * src/xml/sp-css-attr.h, src/desktop-style.cpp, src/xml/repr-css.cpp, + src/xml/repr.h: Fixed SPCSSAttr to be a "real" class, at mental's + direction. Fixes my "default prefs don't show attrs" bug. + * src/helper/stock-items.cpp: removing redundant code. + * src/libnr/nr-point.h, src/libnrtype/FlowUtils.h, src/livarot/Shape.h: + added explicit initializations to keep valgrind happy. + * src/dir-util.cpp, src/sp-path.cpp, src/splivarot.cpp, + src/svg/svg-length.cpp, src/widgets/icon.cpp: + cleaning up memory leaks detected by valgrind. + * src/extension/dependancy.cpp: made repr-attr tags untranslatable. + * src/extension/system.cpp: correcting extension autodetection when + there are conflicting matching modules. + * src/dialogs/filedialog.cpp, src/extension/extension.h, + src/extension/internal/svg.cpp: .svgz loading works again as + expected. Non-functioning modules are not listed in file dialogs. + * src/text-context.cpp, src/text-editing.cpp: preedit modes don't + work correctly for multi-byte characters. See bug 1086769. + +2005-01-31 Jon A. Cruz + * src/file.cpp, src/inkscape.cpp, src/interface.cpp, + src/dialogs/export.cpp, src/extension/init.cpp: + sanitize messages before passing to display dialogs. + +2005-01-31 Kees Cook + + * src/libnrtype/FontFactory.cpp: added a crude font name detection + routine to work around a Pango crash bug. This can be removed once + Pango is fixed. See bug #1025565. Actually, I figured out a fix. + * print.cpp, print.h, sp-shape.cpp, extension/print.cpp, + extension/print.h, extension/implementation/implementation.cpp, + extension/implementation/implementation.h, + extension/implementation/plugin.cpp, extension/implementation/plugin.h, + extension/internal/gnome.h, extension/internal/ps.cpp, + extension/internal/ps.h, extension/internal/win32.h: + In an attempt to start debugging print rendering, I've added the + Print::comment function so that SPItem boundries can be easily + seen in rendered output. + * src/preferences-skeleton.h, src/sp-shape.cpp, + src/dialogs/display-settings.cpp, src/extension/internal/ps.cpp: + Added printout comments for print debugging. Fixed dash output + bug #1104050. + * src/dialogs/rdf.cpp: fixed rdf:bag displays. Closes bug #1113316. + +2005-01-30 Jon A. Cruz + * src/io/sys.h, src/io/sys.cpp: added utility routine to cleanup + strings with invalid UTF-8 for display. + +2004-01-30 Kees Cook + + * src/make.dep, src/make.exclude, src/make.files, src/make.ofiles, + src/io/uristream.cpp, src/io/sys.cpp: additional win32 changes + using Jon Cruz's new mkdir function. Getting Win32 to compile the + "io" directory. Closes bug #1107305. + * src/file.cpp, src/inkscape-stock.cpp, src/inkscape.cpp, + src/interface.cpp, src/main.cpp, src/dialogs/export.cpp, + src/dialogs/stroke-style.cpp, src/extension/input.cpp, + src/extension/implementation/script.cpp, src/helper/stock-items.cpp, + src/io/sys.cpp, src/io/sys.h, src/widgets/icon.cpp: wrapped + g_file_test with new Inkscape::IO::file_test since g_file_test isn't + utf8-safe. + * src/inkscape.cpp: removed call to g_free on non-alloced string. + fixed up crash-save location to be utf8-okay. + * src/extension/extension.cpp: convert from utf8 before open. + * src/sp-spiral.cpp, src/object-edit.cpp: found place where CLAMP on + spiral's t0 wasn't working. Closes bug #1075640. + +2004-01-28 MenTaLguY + + * src/sp-object.h, src/sp-object.cpp: + efficiency fixes which should be helpful when loading large documents + +2005-01-29 Jon A. Cruz + + * src/file.h, src/file.cpp, src/inkscape.cpp, src/sp-image.cpp, + src/extension/implementation/script.cpp, + src/extension/internal/pov-out.cpp, src/extension/internal/ps.cpp, + src/extension/plugin/gimpgrad.cpp, src/helper/png-write.cpp, + src/io/Makefile_insert, src/io/sys.h, src/io/sys.cpp, + src/trace/imagemap.cpp, src/xml/repr-io.cpp: + + Refactored open routine to better location. + +2004-01-28 Kees Cook + + * configure.ac: added test for libgc 6.4 or better. + * src/main.cpp: calling new SPRepr methods instead of inline wrappers. + +2004-01-27 MenTaLguY + + * src/xml/simple-node.h, src/xml/simple-node.cpp: + + SimpleNode::lastChild() and SimpleNode::appendChild() are now + O(1) rather than O(n) + +2004-01-26 MenTaLguY + + * src/xml/repr-util.cpp, src/xml/repr.cpp, src/xml/repr.h, + src/xml/sp-repr-action.h, src/xml/sp-repr-event-vector.h: + + inlined legacy wrappers + + * src/xml/simple-node.cpp: really fixed #1108231 now + +2005-01-25 Jon A. Cruz + + * src/interface.cpp: Passed file import call to shared code. + Fixed bug #1108620. + +2005-01-25 MenTaLguY + + * src/xml/simple-node.cpp: fixed bug #1108231 + +2005-01-25 Peter Moulder + + * src/dialogs/desktop-properties.cpp: Changed set of paper sizes offered: + + Removed `Folio' pagesize (which means a different paper size to + different people; will Folio be missed? If so, can we improve + the name?). + + Changed ISO page sizes (A0..A10, B0..B10) to match official ISO + specification in mm. + + Note that these differ from ghostscript's idea of page sizes; + see comment in desktop-properties.cpp for speculation of + possible problems (fuzziness from antialiasing). + + (Note also that our previous sizes differed even more from + gs_statd.ps...) + + Coalesced Ledger and Tabloid to a single entry (11x17in); + previously they differed in size. + + Changed Icon 16x16 from 16pt to 16px; similarly Icon 32x32 and + Banner 468x60. + +2004-01-24 MenTaLguY + + * src/xml/simple-node.cpp: potential fix for bug #1108231 + +2004-01-23 Ted Gould + + * po/POTFILES.in, share/extensions/dia.inx, + src/preferences-skeleton.h, src/extension/Makefile_insert, + src/extension/dependency.cpp, src/extension/dependency.h, + src/extension/error-file.cpp, src/extension/error-file.h, + src/extension/extension.cpp, src/extension/extension.h, + src/extension/init.cpp, src/extension/prefdialog.cpp: + + Adding in functionality to write out an error log based on the failing to + load of extensions. There is also a new error dialog that appears if one + or more fail to alert the user and tell them where the error log is + stored. In the log there is more complex descriptions of what failed. + +2004-01-23 MenTaLguY + + * src/sp-object.cpp: fix for id binding bug + +2004-01-23 MenTaLguY + + * src/xml/repr-io.cpp: don't complain about not having a namespace + URI for the standard xml: prefix + + * src/desktop-style.cpp, src/desktop.cpp, src/document-undo.cpp, + src/file.cpp, src/gradient-chemistry.cpp, src/inkscape.cpp, + src/interface.cpp, src/nodepath.cpp, src/object-edit.cpp, + src/path-chemistry.cpp, src/prefs-utils.cpp, src/select-toolbar.cpp, + src/selection-chemistry.cpp, src/sp-defs.cpp, src/sp-flowdiv.cpp, + src/sp-flowtext.cpp, src/sp-gradient.cpp, src/sp-item.cpp, + src/sp-object-group.cpp, src/sp-object-repr.cpp, src/sp-object.cpp, + src/sp-offset.cpp, src/sp-pattern.cpp, src/sp-string.cpp, + src/sp-text.cpp, src/sp-tspan.cpp, src/sp-use.cpp, src/splivarot.cpp, + src/text-chemistry.cpp, src/text-context.cpp, src/text-editing.cpp, + src/dialogs/clonetiler.cpp, src/dialogs/display-settings.cpp, + src/dialogs/stroke-style.cpp, src/dialogs/xml-tree.cpp, + src/extension/extension.h, src/extension/implementation/script.cpp, + src/widgets/dash-selector.cpp, src/widgets/gradient-vector.cpp, + src/widgets/sp-xmlview-tree.cpp, src/xml/Makefile_insert, + src/xml/comment-node.h, src/xml/element-node.h, + src/xml/repr-action-test.cpp, src/xml/repr-css.cpp, + src/xml/repr-get-children.cpp, src/xml/repr-io.cpp, + src/xml/repr-private.h, src/xml/repr-util.cpp, src/xml/repr.cpp, + src/xml/repr.h, src/xml/simple-document.cpp, src/xml/simple-document.h, + src/xml/simple-node.cpp, src/xml/simple-node.h, + src/xml/sp-repr-action.cpp, src/xml/sp-repr-doc.h, src/xml/sp-repr.h, + src/xml/text-node.h: + + got rid of xml/repr-private.h, removed + sp_repr_document_createTextNode(), made SPRepr and SPReprDoc abstract + interfaces, and moved the SPRepr implementations into separate files + in the Inkscape::XML namespace + + * src/util/shared-c-string-ptr.h: added equality operators to avoid + certain ambiguities + +2004-01-22 MenTaLguY + + * src/xml/Makefile_insert, src/xml/repr-private.h, src/xml/repr.cpp, + src/xml/session.h, src/xml/simple-session.cpp, src/xml/simple-session.h, + src/xml/sp-repr-action.cpp, src/xml/transaction-logger.h: + + added Inkscape::XML::Session and Inkscape::XML::TransactionLogger + to provide a new interface for transactions, rather than doing it from + SPReprDoc + +2004-01-22 MenTaLguY + + * src/xml/Makefile_insert, src/xml/node-observer.h, + src/xml/repr-private.h, src/xml/repr.cpp: + + moved repr loging behind generic observer interface + +2005-01-22 Ted Gould + + * src/display/canvas-grid.cpp, src/display/canvas-grid.h; + + Fixing 1103001. Now major grid lines work alot more like you + think that they should. + +2005-01-21 MenTaLguY + + * src/util/Makefile_insert, src/util/shared-c-string-ptr.cpp, + src/util/shared-c-string-ptr.h, src/util/shared-c-string.cpp, + src/util/shared-c-string.h, src/xml/repr-io.cpp, + src/xml/repr-private.h, src/xml/repr-util.cpp, src/xml/repr.cpp, + src/xml/sp-repr-action.h, src/xml/sp-repr-attr.h: + + renamed Util::SharedCString to Util::SharedCStringPtr, which is + more descriptive of what it actually is + +2005-01-21 MenTaLguY + + * src/xml/repr-private.h, src/xml/repr-util.cpp, src/xml/repr.cpp: + + simplify the cacheing of repr position indices, and make it something + that can work with an abstract interface + +2005-01-20 Kees Cook + + * src/file.cpp: added some debug output to help bulia debug bug #1102318. + * configure.ac: more attempts at detecting the -lgc libs. + +2005-01-19 Kees Cook + + * configure.ac: trying to correct the -lgc detection. + * inkscape.pod: added theme details. + * src/widgets/widget-sizes.h: went from 20 to 24 for toolbar icon size + to match other GTK applications. + * src/extension/db.cpp: corrected STL "not found" handling. Didn't + fix bug #1102318. + +2005-01-18 Kees Cook + + * src/inkscape.h, src/inkscape.cpp, src/widgets/icons.cpp: + Added basic theme support! Whee! + * share/inkscape/icons.svg: restoring original up/down/flip icons since + icons are themable now. We should stick to our original look. + * share/screens/about.svg: added Brisgeek's 0.41 about screen. Had + to tweak background: looks like doc background isn't imported. + * share/icons/*.xpm, share/icons/*.png: removed them. Not being used. + +2005-01-17 MenTaLguY + + * src/desktop-style.cpp, src/inkscape.cpp, src/interface.cpp, + src/path-chemistry.cpp, src/prefs-utils.cpp, src/selection-chemistry.cpp, + src/sp-flowtext.cpp, src/sp-gradient.cpp, src/sp-object.cpp, + src/sp-text.cpp, src/sp-tspan.cpp, src/splivarot.cpp, + src/dialogs/xml-tree.cpp, src/extension/internal/pov-out.cpp, + src/widgets/dash-selector.cpp, src/xml/repr-css.cpp, + src/xml/repr-get-children.cpp, src/xml/repr-io.cpp, + src/xml/repr-private.h, src/xml/repr-util.cpp, src/xml/repr.cpp, + src/xml/sp-repr-action.cpp: + + Made all SPRepr fields private, and moved most functionality into + member functions. Also shuffled SPReprDoc members, to avoid + need for SPReprDoc to be finalized. + +2005-01-17 Kees Cook + + * share/markers/markers.svg: applied patch #990884, which provides a + few mirrored arrows until marker transforms are finished. + * share/icons/icons.svg: updates per Bulia's request. + +2005-01-16 MenTaLguY + + * src/sp-object.cpp: non-elements no longer get ids assigned + +2005-01-15 MenTaLguY + + * src/arc-context.cpp, src/document-private.h, src/document.cpp, + src/document.h, src/event-context.cpp, src/node-context.cpp, + src/rect-context.cpp, src/sp-object.cpp, src/spiral-context.cpp, + src/star-context.cpp, src/toolbox.cpp, src/uri-references.cpp, + src/dialogs/desktop-properties.cpp, src/widgets/gradient-vector.cpp, + src/widgets/layer-selector.cpp, src/widgets/sp-widget.cpp, + src/widgets/sp-xmlview-attr-list.cpp, src/widgets/sp-xmlview-content.cpp, + src/widgets/sp-xmlview-tree.cpp, src/xml/repr.cpp, + src/xml/sp-repr-event-vector.h: + + Removed attribute setting callback, and decoupled ids and object/repr + bindings (object <-> repr associations are now remembered directly, + though ids are still tracked too). + + This means it is now possible to set a null id on an object without + anything breaking (hopefully). For now we will still assign ids + to everything by default... + +2005-01-15 MenTaLguY + + * src/arc-context.cpp, src/event-context.cpp, src/node-context.cpp, + src/rect-context.cpp, src/sp-object.cpp, src/spiral-context.cpp, + src/star-context.cpp, src/toolbox.cpp, + src/dialogs/desktop-properties.cpp, src/widgets/gradient-vector.cpp, + src/widgets/layer-selector.cpp, src/widgets/sp-widget.cpp, + src/widgets/sp-xmlview-attr-list.cpp, src/widgets/sp-xmlview-content.cpp, + src/widgets/sp-xmlview-tree.cpp, src/xml/repr.cpp, + src/xml/sp-repr-event-vector.h: + + remove all veto callbacks but setting attributes + +2005-01-15 Kees Cook + + * src/inkscape.cpp: correcting windows path for preferences. Closes + bug #933461. + + * src/file.cpp, src/nodepath.cpp, src/selection-describer.cpp, + src/seltrans.cpp, src/sp-item-group.cpp, src/sp-path.cpp, + src/sp-spiral.cpp, src/sp-star.cpp, src/dialogs/find.cpp: + Using ngettext for plural localized strings. Please try to keep this + up. Closes bug #1076872. + + * share/icons/Makefile.am, share/icons/icons.svg, src/inkscape-stock.cpp, + src/inkscape-stock.h, src/dialogs/stroke-style.cpp, + src/dialogs/text-edit.cpp, src/dialogs/transformation.cpp, + src/dialogs/xml-tree.cpp: Finished the last of the missing pixmap + replacements from Andreas Nilsson. Fixed some mistakes in the earlier + changes (need to call sp_icon_new_scaled not sp_icon_new). + +2005-01-14 MenTaLguY + + * src/gc.cpp: leave the free space multiplier at the default, which + will hopefully (according to Hans) avoid some of the odd gc issues + we've had, if nothing else does + +2005-01-14 Kees Cook + + * share/icons/Makefile.am, share/icons/icons.svg, src/inkscape-stock.cpp, + src/inkscape-stock.h, src/verbs.cpp, src/dialogs/stroke-style.cpp, + src/dialogs/transformation.cpp, src/widgets/icon.cpp, src/widgets/icon.h, + src/widgets/paint-selector.cpp: + Fixed up code and replaced pixmaps with icons from myself and + Andreas Nilsson. + +2005-01-11 MenTaLguY + + * src/xml/repr-io.cpp: promote non-namespaced SVG documents into SVG + namespace + +2005-01-08 MenTaLguY + + * src/Makefile_insert, src/gc-anchored.cpp, src/gc-anchored.h: + abstracted allocation of anchors + +2005-01-06 Ted Gould + + * src/interface.cpp, src/extension/effect.cpp, + src/extension/implementation/implementation.cpp, + src/extension/implementation/implementation.h, + src/extension/implementation/plugin-link.h, + src/extension/implementation/plugin.cpp, + src/extension/implementation/plugin.h, + src/extension/implementation/script.cpp, + src/extension/implementation/script.h, src/extension/plugin/gimpgrad.cpp, + src/extension/plugin/grid.cpp: + + Changing the effects preferences so that it uses sockets and plugs which + will allow out of process GUIs to work too. This is a first pass with + nothing beautiful, but it does seem to work. + +2005-01-03 MenTaLguY + + * src/document.cpp, src/main.cpp, src/sp-root.cpp: + get rid of ugly xmlns hacks + + * src/inkscape.cpp, src/extension/internal/svg.cpp, src/xml/repr-io.cpp: + automatically include xmlns declarations for the required namespaces, + and make a best effort at using a default namespace when requested + and possible + +2005-01-02 Kees Cook + + * share/icons/icons.svg: updated view and location + * src/document.cpp, src/dialogs/rdf.cpp: fixed another bug in metadata + due to svg: prefix change. + * src/inkscape-stock.h, src/inkscape-stock.cpp, share/icons/Makefile.am: + removed unused xpm icons + +2005-01-02 Peter Moulder + + * src/fontsize-expansion.h, src/fontsize-expansion.cpp: + New files. + * src/Makefile_insert: Add the new files to libinkpre_a_SOURCES. + * src/desktop-style.cpp (sp_desktop_apply_css_recursive): + When calling sp_css_attr_scale, change the expansion calculation + to use fontsize_expansion(). + * src/sp-text.cpp (sp_text_set_transform): Similarly use + fontsize_expansion() instead of generic m.expansion(). + +2005-01-01 Kees Cook + + * src/extension/db.h, src/extension/db.cpp, src/extension/init.cpp: + created "modulelist" to maintain initialization order for extension + lists. + +2004-12-31 MenTaLguY + + * src/xml/repr-io.cpp, src/xml/repr.h: initial scaffoliding for more + cosmetic use of prefixes in output files (and eventually more proper + namespace handling for output as well) + +2004-12-31 Peter Moulder + + * src/sp-text.cpp (sp_text_set_transform): Change scaling of font size. + The result should be closer to what CorelDraw, XaraX, Canvas 7 and + Expression3 do according to vellum, though I don't know the exact + rule that they use. + +2004-12-25 Ted Gould + + * share/extensions/grid.inx, src/extension/extension.cpp, + src/extension/extension.h, src/extension/plugin/grid.cpp: + + Futher improvements to the grid plugin. This involves mostly adding in + parameters at this time, but, ofcourse, I never implemented floating + point parameters -- so that had to be done first. More modular code so + that things can be adjusted externally better. + +2004-12-25 Ted Gould + + * share/extensions/Makefile.am, share/extensions/grid.inx, + src/extension/implementation/plugin-link.h, + src/extension/implementation/plugin.cpp, + src/extension/plugin/Makefile_insert, src/extension/plugin/gimpgrad.cpp, + src/extension/plugin/grid.cpp: + + Adding in a new effect plugin, grid. It draws a grid on the canvas which + is just an easy way to do some neat things. It is mostly done, but still + needs cleanup. Some other files required modification to make this + possible. + +2004-12-25 MenTaLguY + + * src/event-context.cpp: removed unused handler + +2004-12-25 Ted Gould + + * share/extensions/svg_dropshadow: + + Changing to use "svg:g" instead of "g" for the group. + + * src/verbs.cpp, src/extension/effect.cpp, src/extension/effect.h, + src/extension/system.cpp, src/extension/system.h, + src/extension/implementation/implementation.cpp, + src/extension/implementation/implementation.h, + src/extension/implementation/plugin.cpp, + src/extension/implementation/plugin.h, + src/extension/implementation/script.cpp, + src/extension/implementation/script.h: + + Final stuff to get Effects working as well as the did before, which + is okay, but not great. This involved changing the API to get an SPView + instead of an SPDocument because then I can get the selection information + from the view that is being used. + +2004-12-24 MenTaLguY + + * src/sp-object-repr.cpp, src/sp-tspan.cpp, src/splivarot.cpp, + src/dialogs/rdf.cpp, src/dialogs/xml-tree.cpp, + src/widgets/sp-xmlview-tree.cpp, src/xml/repr-io.cpp, + src/xml/repr-private.h, src/xml/repr-util.cpp, src/xml/repr.cpp, + src/xml/repr.h: + + cleaned out unused code and unhygenic macros, as well as fixing + constructors for text and comment nodes + +2004-12-24 Ted Gould + + * src/verbs.cpp, src/extension/effect.cpp, src/extension/effect.h: + + Okay, now the effects menu really works! Well, the implementation seems + to be broken, but the wrapper seems to be all working. + +2004-12-24 Ted Gould + + * src/interface.cpp, src/verbs.cpp, src/verbs.h, src/extension/effect.cpp, + src/extension/effect.h: + + Getting the Effects menu basically working. This included some fixes to + the verbs where they were incrementing the database incorrectly. The + effects are the first component to take advantage of the dynamically + created verbs, and exercised new code. Now the basic menu is available, + but there is no functionality there. + +2004-12-24 Ted Gould + + * src/interface.cpp, src/verbs.cpp, src/verbs.h: + + Basic code for the effects menu. + + * src/dialogs/filedialog.cpp, src/dialogs/filedialog.h, + src/extension/db.cpp, src/extension/db.h: + + Changing the DB access functions to use std::list instead of GSList so + that it is more standard, and we get rid of a specialized class that + really isn't that useful. Less memory usage, and fixes a leak. + + * src/extension/effect.cpp, src/extension/effect.h: + + Adding in a "Last Effect" to be used in the menus. + + * src/extension/extension-forward.h, src/extension/extension.cpp, + src/extension/extension.h, src/extension/input.cpp, + src/extension/output.cpp, src/extension/timer.cpp, src/extension/timer.h, + src/extension/Makefile_insert: + + Adding in the timer functions so that modules will unload in a given + amount of time. For more information on this read the documentation + in the files. Kinda a lazy deallocation. + + * src/extension/implementation/implementation.cpp: + + Fix unload so that it is not recursive. + +2004-12-23 MenTaLguY + + * src/arc-context.cpp, src/document.cpp, src/draw-context.cpp, + src/dyna-draw-context.cpp, src/file.cpp, src/gradient-chemistry.cpp, + src/interface.cpp, src/layer-fns.cpp, src/main.cpp, src/object-ui.cpp, + src/path-chemistry.cpp, src/rect-context.cpp, + src/selection-chemistry.cpp, src/sp-anchor.cpp, src/sp-clippath.cpp, + src/sp-defs.cpp, src/sp-ellipse.cpp, src/sp-flowdiv.cpp, + src/sp-flowregion.cpp, src/sp-flowtext.cpp, src/sp-gradient-test.cpp, + src/sp-gradient.cpp, src/sp-image.cpp, src/sp-item-group.cpp, + src/sp-line.cpp, src/sp-marker.cpp, src/sp-mask.cpp, + src/sp-object-group.cpp, src/sp-object-repr.cpp, src/sp-offset.cpp, + src/sp-path.cpp, src/sp-pattern.cpp, src/sp-polygon.cpp, + src/sp-polyline.cpp, src/sp-rect.cpp, src/sp-root.cpp, + src/sp-spiral.cpp, src/sp-star.cpp, src/sp-symbol.cpp, src/sp-text.cpp, + src/sp-tspan.cpp, src/sp-use.cpp, src/spiral-context.cpp, + src/splivarot.cpp, src/star-context.cpp, src/text-chemistry.cpp, + src/text-context.cpp, src/dialogs/find.cpp, src/dialogs/rdf.cpp, + src/dialogs/xml-tree.cpp, src/ecma/EcmaBinding.cpp, + src/extension/internal/gdkpixbuf-input.cpp, + src/extension/internal/svg.cpp, src/livarot/ShapeDraw.cpp, + src/xml/repr-io.cpp, src/xml/repr-util.cpp, src/xml/repr.cpp: + + use normalized qnames for SVG elements too + +2004-12-23 Kees Cook + + * configure.ac, src/Makefile_insert, src/extension/script/Makefile_insert: + adding Perl and Python compile tests. Corrected library locations. + * src/extension/script/InkscapeScript.h, + src/extension/script/InkscapePython.cpp, + src/extension/script/InkscapeScript.cpp: white space fix, and + added config.h, and some small debugging for myself. Hope Bob doesn't + mind! :) + * src/dialogs/scriptdialog.cpp: added comments to default code. + +2004-12-22 Kees Cook + + * configure.ac, src/extension/script/Makefile_insert: automake cleanups + to deal with perl/python detection. + +2004-12-20 David Turner + * src/widgets/gradient-vector.cpp: + Fixed bug with gradient stops at 0 and 100%. Closes 1085920. + +2004-12-18 Bob Jamison + + * src/extensions/script/*: + New files that enable embedding of scripting languages + in Inkscape. Currently using Swig to embed Perl and Python. + + * autoconf.ac: + Allow opting for perl or python with --with-perl=yes|no + and --with-python=yes|no + +2004-12-15 Peter Moulder + + * streq.h (streq), strneq.h (strneq), memeq.h (memeq): + New convenience functions for strcmp(a,b)==0 etc. + + * src/dir-util.cpp (sp_relative_path_from_path): + Fix when base is a string prefix of path but a directory prefix + (e.g. path=/foo/barney, base=/foo/bar). + +2004-12-10 Peter Moulder + + * src/sp-conn-end.cpp (sp_conn_end_move_compensate): + Fix for undo/save: wasn't calling updateRepr(). + +2004-12-09 Peter Moulder + + * src/style.cpp (sp_style_merge_from_style_string): + More standards-conforming parsing of style strings into prop:value + pairs. + +2004-12-08 Peter Moulder + + * src/style.h, src/style.cpp, src/libnrtype/font-style-to-pos.cpp: + Fix font-weight value: s/darker/bolder/. + + * src/style.cpp (sp_style_merge_from_parent): + Fix bug with specifying stroke-width with unit of em or ex. + (We were ignoring the number, treating it as 1em or 1ex.) + + * src/style.h, src/style.cpp (sp_style_read_dash, + sp_style_write_string, sp_style_write_difference): + Allow `inherit' as a value for dasharray. + (Also plug small memory leak in sp_style_read_dash.) + +2004-12-07 Peter Moulder + + * src/style.cpp (sp_style_write_string): + Fix for when stroke-dasharray either explicitly set to `none', or + inherits non-none. + + * src/style.cpp (sp_style_write_ienum): + Fix: preserve explicit `inherit' request. + * (sp_style_read, sp_style_merge_property): + Allow explicit `inherit' for `display' property. + + * src/style.cpp (sp_style_read): + Fix copy&paste bug affecting `visibility' and `display' properties. + +2004-12-07 David Turner + + * src/libnrtype/RasterFont.cpp, src/display/nr-arena-shape.cpp: + Fixed dash rendering bug (#1077213) + +2004-12-06 Peter Moulder + + * src/style.h, src/style.cpp: Support all `display' values + required by SVG 1.1. (No functional change, insofar as the new + values all have the same behaviour as our existing `block' value + in SVG.) + * src/sp-item.cpp, src/style.cpp: Use `inline' (SP_CSS_DISPLAY_INLINE) + rather than `block' as our generic display value meaning `don't hide + this', as per spec. + + * src/style.cpp: Prefer to write lr-tb etc. rather than the + abbreviations lr etc. (Also add comment saying why.) + +2004-12-03 Peter Moulder + + * src/dialogs/xml-tree.cpp (on_attr_select_row_set_value_content): + Fix segfault: treat NULL as empty string for display purposes. + +2004-11-30 Peter Moulder + + * src/svg/svg.h, src/svg/sp-svg.def, src/svg/svg-length.cpp: + (sp_svg_boolean_read, sp_svg_write_percentage): + Remove these unused functions. + (sp_svg_length_read_lff, sp_svg_number_write_d, + sp_svg_number_write_i): Mark static. + + * configure.ac: + When adding -lgc to LIBS, also add its dependencies -lpthread -ldl. + +2004-11-28 Ted Gould + + * 0.40 + +2004-11-25 MenTaLguY + + * share/tutorials/tutorial-calligraphy.svg: spelling fix + + * src/widgets/layer-selector.cpp: fixing the layer selector update bug; + sigc++ apparently doesn't deal with reference arguments very well + +2004-11-25 MenTaLguY + + * src/layer-fns.cpp: fix layer creation within sublayers + + * src/dialogs/layer-properties.cpp: fix dialog leak + +2004-11-25 MenTaLguY + + * src/inkscape.cpp: eliminate duplicated code across #ifdefs + + * src/verbs.cpp, src/dialogs/layer-properties.cpp, + src/dialogs/layer-properties.h: + + LayerPropertiesDialog is no longer a singleton, since it's kind of a + per-desktop (well, ideally per-document) thing. Remaining to do: + fix update of layer selector widget, and eliminate leak of dialog + objects. + +2004-11-24 Kees Cook + + * inkscape.spec: added SMP flags, added static library link capability. + +2004-11-24 Peter Moulder + + * src/draw-context.cpp (spdc_concat_colors_and_flush): + Do nothing if empty curve; in particular, don't try to close an + empty curve. + + * src/pen-context.cpp (spdc_endpoint_snap): + Fix use of uninitialized value when snapping. + +2004-11-23 Bryce Harrington + + * src/dialogs/layer-properties.cpp: Fixing bug causing two new + layers to get created when hitting enter + +2004-11-23 Kees Cook + + * share/tutorials: added Josh's changes, resized, repositioned for + 800x600. + * src/verbs.h, src/verbs.cpp, src/interface.cpp: added tracing + tutorial. + +2004-11-23 MenTaLguY + + * src/rect-context.cpp: disallow drawing on locked or invisible layers + + * src/widgets/layer-properties.h, src/widgets/layer-properties.cpp: + slight HIG-ification + + * src/desktop.cpp, src/desktop.h, src/widgets/layer-selector.cpp, + src/widgets/layer-selector.h, src/verbs.cpp, src/sp-desktop-widget.h + + removed vestigal layer renaming thing + + * src/verbs.cpp, src/dialogs/layer-properties.cpp, + src/dialogs/layer-properties.h: + + reuse dialog for creating layers as well as for renaming them + +2004-11-22 Peter Moulder + + * src/display/bezier-utils.cpp (generate_bezier): For the sake of + our current pencil tool, don't use free optimization of the end + tangent vector. + +2004-11-21 MenTaLguY + + * src/verbs.cpp: add accels for layer menu items + +2004-11-21 Bryce Harrington + + * src/dialogs/layer-properties.cpp, src/verbs.cpp, + src/dialogs/layer-properties.h: Hooking up layer rename + functionality, and making it show correctly. + + * src/dialogs/debugdialog.cpp, src/dialogs/find.cpp, + src/dialogs/tracedialog.cpp: Fixing dialog show behavior + +2004-11-21 Kees Cook + + * src/sp-object.cpp, src/sp-metadata.cpp: added some debugging, and + fixed a dumb error in my metadata _release handler. Should mostly + close bug 1069772. + * src/Makefile_insert, src/sp-skeleton.cpp, src/sp-skeleton.h: + created some example SPObject implementations for a basis for any + new SPObjects in the future. + * src/dialogs/xml-tree.cpp: fixing logic bug in identability checker. + Added immutability test to actually close 1069772. + * share/icons/icons.svg, src/verbs.cpp, src/interface.cpp: adding + icons for the "new" menu, vacuum, reverse, make bitmap, and trace. + +2004-11-20 Jon A. Cruz + + * src/extension/db.h, src/extension/db.cpp, src/dialogs/filedialog.cpp: + Added extension matching pattern. Fixed bug 1064888. + + * src/dialogs/filedialog.cpp (isValidImageFile): + Fixed previewing bug 1067551. + +2004-11-20 Peter Moulder + + * src/display/bezier-utils.cpp (sp_bezier_fit_cubic_full): + Add splitpoints parameter. Callers updated. + + * src/display/bezier-utils.cpp + (sp_bezier_fit_cubic_r, sp_bezier_fit_cubic_full): + Change last parameter from lg_max_beziers to max_beziers. + Callers updated. + +2004-11-19 Bryce + + * src/dialogs/layer-properties.cpp, + src/dialogs/layer-properties.h: Adding some widgets. + +2004-11-18 Bryce + + * src/dialogs/Makefile_insert, src/dialogs/makefile.msc, + src/dialogs/layer-properties.h, src/dialogs/layer-properties.h: + Adding a layer properties dialog for renaming layers + + * src/desktop.cpp src/interface.cpp, src/verbs.cpp, + src/verbs.h src/dialogs/layer-properties.cpp, + src/dialogs/layer-properties.h, + src/widgets/layer-selector.cpp: Hooking in layer props dialog. + +2004-11-16 MenTaLguY + + * src/widgets/document-tree-model.cpp, src/widgets/document-tree-model.h, + src/widgets/layer-selector.cpp, src/widgets/Makefile_insert: + + removed Widgets::DocumentTreeModel because unused + + * src/xml/repr-private.h, src/xml/repr-util.cpp, src/xml/repr.cpp, + src/xml/repr.h: + + cache successive sibling counts (self+subsequent siblings) in SPRepr + to make sp_repr_n_children() and sp_repr_position() more efficient, + which will be needed later for e.g. GTK tree models. + + sp_repr_nth_child() isn't any faster as a result of the changes, + but it probably won't need to be + + * src/xml/repr.cpp: fixed refcount leak in SPRepr::SPRepr(SPRepr const &) + +2004-11-15 MenTaLguY + + * src/gc.cpp: add initial stubs that print an informative error + if the GC functions are used before Inkscape::GC::init() is called + +2004-11-14 MenTaLguY + + * configure.ac, src/gc-core.h, src/gc-managed.h, src/gc-anchored.h, + src/gc-finalized.h, src/gc.cpp: + + make disabling the collector a run-time rather than a compile-time + option; there are now three garbage collector options, selectable + by setting the _INKSCAPE_GC environment variable: + + * enable - the normal collector (default) + * debug - the debugging collector + * disable - use standard malloc in place of the libgc allocator + +2004-11-14 Peter Moulder + + * src/display/bezier-utils.cpp: Make end tangent/s be unconstrained for + sp_bezier_fit_cubic, sp_bezier_fit_cubic_r, and around corner nodes. + + * src/pencil-context.cpp (fit_and_split): Allow the bezier fitter to + choose the middle control points freely except to the extent required + for smooth nodes. + + * src/display/bezier-utils.cpp (generate_bezier): + If either end tangent is specified as zero then estimate the + corresponding control point without constraining its direction + from the endpoint. + + * src/pencil-context.h, src/pencil-context.cpp + (fit_and_split, sp_pencil_context_init): Explicitly remember required + tangent instead of using "first two points" hack. + + * src/display/bezier-utils.cpp (sp_bezier_fit_cubic_full): + Detect & prevent "ghost spikes", by allowing a corner node if + the specified tangent would result in a spike. + + * src/display/bezier-utils.cpp (generate_bezier): Better handling + of the case of infinite solutions for the lengths of the two + tangent vectors: try requiring that the lengths equal each other, + and solving for that length (just one variable). + +2004-11-13 Kees Cook + + * src/document.cpp: wrapped updateDisplay call in undo insensitivity. + Closes bug #1030436. + +2004-11-12 MenTaLguY + + * src/main.cpp: fpresetsticky -> fpsetsticky + + * src/verbs.cpp: cast width changes + + * src/libnrtype/FlowBoxes.h, src/libnrtype/FlowDefs.h, + src/libnrtype/FlowDest.h, src/libnrtype/FlowEater.h, + src/libnrtype/FlowRes.h, src/libnrtype/FlowSols.h, + src/libnrtype/FlowSrc.h, src/libnrtype/FlowSrcText.h, + src/libnrtype/FlowStyle.h, src/libnrtype/FlowUtils.h: + remove stdint.h which isn't being used here + + * src/widgets/icon.h, src/widgets/icon.cpp: + icon greys out when insensitive + + * src/gc-anchored.h, src/gc-finalized.h, src/gc-managed.h: + documentation + + * src/verbs.cpp: changed cast to reinterpret_cast to hopefully + avoid compiler warning + +2004-11-11 Kees Cook + + * src/seltrans.cpp, src/select-context.cpp: ref counting SPObjects + correctly so undo's don't blow up an active resize/move. Closes + bug #1018756. + +2004-11-11 MenTaLguY + + * src/inkscape.cpp, src/main.cpp, src/widgets/icon.cpp: + removed sp_bitmap_icons + + * configure.ac, src/sp-image.cpp, src/object-ui.cpp: + removed stale autotrace support code + +2004-11-10 MenTaLguY + + * src/sp-item.cpp, src/sp-clippath.cpp, src/cp-mask.cpp: + minor refcounting tweaks + + * src/sp-image.cpp: fixed failure to release GdkPixbufLoader when + done with it (fixes bug #1063054) + +2004-11-10 Kees Cook + + * configure.ac, src/gc-core.h: corrected gc.h path detection. + +2004-11-09 MenTaLguY + + * src/dialogs/fileselector.cpp: fixed cut-and-paste refcount bug + between SVGPreview::setFileName and SVGPreview::setFromMem that + was leaking bitmap image preview SPDocuments + +2004-11-09 Bryce Harrington + + * src/dialogs/item-properties.cpp + +2004-11-09 MenTaLguY + + * src/sp-item.cpp, src/style.cpp, src/style.h: + use 'display' rather than 'visibility' for hiding, and give display + a more "modern" representation in SPStyle like visibility's + +2004-11-09 Kees Cook + + * src/dialogs/xml-tree.cpp: added better context to the status bar. + added warning flash for id conflicts. + * src/toolbox.cpp: killed some copy/paste code while bug hunting. + +2004-11-08 Peter Moulder + + * src/sp-item.h, src/sp-item.cpp + (isExplicitlyHidden, setExplicitlyHidden): New methods. + + * src/dialogs/item-properties.cpp: Change from having a `Visible' + checkbox that explicitly sets the SVG visibility property to + having a `Hide' checkbox that controls whether or not the + element has visibility:hidden. (Mitigates #1061934.) + + * src/sp-object.h, src/sp-object.cpp (visible, setVisible): + Remove these methods. + +2004-11-07 MenTaLguY + + * src/gc-finalized.h: fix for Debian bug #279991 (cast to ptrdiff_t + rather than int), and basic documentation + +2004-11-06 MenTaLguY + + * src/sp-item.cpp: fix desktop-specific version of SPItem::isHidden() + to deal correctly with parent visibility + +2004-11-05 MenTaLguY + + * src/widgets/layer-selector.cpp: more work on making the lock/hide + buttons actually do something + + * src/sp-item.cpp, src/sp-item.h: implement lock/hide related methods + + * src/verbs.cpp: "Remove All Kerns" -> "Remove Manual Kerning" + +2004-11-04 Kees Cook + + * src/dialogs/rdf.h, src/dialogs/rdf.cpp: added rdf:Bag for the + dc:subject keyword list. Closed bug #1021025. + * src/dialogs/xml-tree.cpp, src/widgets/sp-xmlview-attr-list.cpp, + src/widgets/sp-xmlview-attr-list.h: added status bar to XML + editor. added row-change callback for XML tree view. This + all supports a possible future solution to bug #869683. + * src/dialogs/desktop-properties.cpp: memory leak in RDF code. + +2004-11-04 MenTaLguY + + * src/widgets/layer-selector.cpp: togglable images and formatting + changes (make current layer bold) + + * src/uri.h, src/uri.cpp: added assignment operator + +2004-11-03 MenTaLguY + + * src/widgets/Makefile_insert, src/widgets/shrink-wrap-button.cpp, + src/widgets/shrink-wrap-button.h: + + added Inkscape::Widgets::shrink_wrap_button, to make any gtk button + an SPButton-like shrink-wrapped button + + * src/widgets/layer-selector.h, src/widgets/layer-selector.cpp: + + abandon SPButton for layer selector buttons + +2004-11-03 Peter Moulder + + * po/check-markup: New script: detects markup problems<7b> + in the translated strings. (~10 such problems found.) + * Makefile.am (all, check, distcheck): Run po/check-markup (with + varying permissiveness of errors). + +2004-11-02 MenTaLguY + + * doc/keys.xml: added documentation of layer keys + +2004-11-01 Kees Cook + + * src/dialogs/align.cpp, src/dialogs/debugdialog.cpp: localized + some missed strings. + +2004-11-01 MenTaLguY + + * share/icons/icons.svg: gave bulia's eye icons ids + + * src/widgets/layer-selector.h, src/widgets/layers-selector.cpp: + fixed up visibility/lock toggles... now to make them actually do + something + +2004-10-31 MenTaLguY + + * src/util/glib-list.h: adaptor for glib lists + + * src/widgets/layer-selector.h, src/widgets/layer-selector.cpp: + save the repr next to the SPObject + +2004-10-30 MenTaLguY + + * src/util/list.h: more list cleanups and documentation + + * src/verbs.cpp: call sp_document_done() for layer verbs too + +2004-10-30 Bryce Harrington + + * src/dialogs/item-properties.cpp, src/sp-object.h: Cleaning up + stubs, disabling some more of the desc code to prevent crash. + The change to SPObject::label() broke the label editing code; + fixing it. + +2004-10-30 Kees Cook + + * src/sp-metadata.cpp, src/sp-metadata.h, src/Makefile_insert, + src/document.cpp, src/sp-object-repr.cpp, src/sp-object.cpp: + I've created my very first SPObject! SPMetadata is alive! No + more nasty hack to have it disappear from SVG Plain. Mental + won't have to take away my CVS access any more! :) + * inkscape2.nsi: update from Adib Taraben + +2004-10-30 Peter Moulder + + * src/libnr/nr-matrix.cpp (nr_matrix_invert): + Fix for last commit to this file, which broke src==dest case. + * src/libnr/nr-matrix-test.cpp: Add test cases for nr_matrix_invert. + +2004-10-30 MenTaLguY + + * src/widgets/layer-selector.cpp, src/widgets/layer-selector.h: + update when layers added/removed/reordered. + + * src/verbs.h, src/verbs.cpp: added "rename layer" verb. + +2004-10-29 Kees Cook + + * src/Makefile_insert, src/trace/Makefile_insert, + src/util/Makefile_insert: distcheck cleanups. + +2004-10-29 MenTaLguY + + * src/widgets/layer-selector.cpp: default labels in italic + + * src/sp-object.h, src/sp-object.cpp: inkscape:label fixes + + * src/layer-fns.cpp: make ordering of layers complete; not just among + siblings + + * src/util/list.h: documentation update + +2004-10-29 Bryce Harrington + + * layer-fns.cpp: documenting + * layer-selector.cpp: documenting & fixing funky widget resizing + * object-ui.cpp, dialogs/item-properties.cpp, sp-object.h, + sp-object.cpp, widgets/layer-selector.cpp: add ability to set + inkscape:label from "Item Properties", remove id setting from + "Item Properties", switch to using + SPObject::label()/SPObject?::defaultLabel() in UI where object + ID is currently used. Documenting. Switching from "label" to + "inkscape:label" where appropriate. Adding + visible()/setVisible() functions and activating checkbox. + * dialogs/item-properties.cpp: Adding title and desc boxes. + Adjusting layout of dialog a bit. Changing to use of tables + instead of horiz/vert boxes for layout. Setting to inactive + until some underlying bits get finished. + +2004-10-29 Kees Cook + + * src/dialogs/export.cpp: moved function-based static state variable + into the dialog state variables. Closes bug #993447. + * src/display/curve.cpp: fixed compile warning. + * src/sp-namedview.cpp: wasn't ref counting correctly. Closes #955020. + +2004-10-29 Jon A. Cruz + + * src/sp-image.cpp, src/extension/internal/gdkpixbuf-input.cpp: + Refactoring filenames and file opening + Scales imported images if DPI is known and not 72 DPI. Fixes + #1029755 + +2004-10-29 MenTaLguY + + * src/widgets/layer-selector.cpp, src/verbs.cpp: + unselect objects when layer is manually switched + +2004-10-28 Kees Cook + + * src/document-undo.cpp, src/document.cpp, src/sp-namedview.cpp, + src/sp-text.cpp, src/dialogs/desktop-properties.cpp, + src/dialogs/export.cpp, src/extension/input.cpp, + src/extension/output.cpp, src/extension/system.cpp: + Fixing calls to sp_document_set_undo_sensitive to correct allow for + nesting, as suggested by mental. Found while tracking down bug + #1030436. + +2004-10-28 MenTaLguY + + * src/util/list.h: cleanups of list class. I think, aside from + documentation and maybe fixes for g++ 3.4 (if required), this + is the last set of changes I will need to make. + + * src/sp-item.cpp, src/splivarot.cpp, src/util/reverse-list.h, + src/util/filter-list.h, src/util/map-list.h: + adjust for changes in the list class' interface + + * src/desktop.cpp, src/sp-desktop-widget.h: + removed old layer selector and added SPDesktop::itemIsHidden() + + * src/widgets/layer-selector.cpp, src/widgets/layer-selector.h: + more work; it's now at least as functional as the old selector it + replaces + +2004-10-27 Kees Cook + + * src/libnr/nr-point.h: use NR::X and NR::Y instead of "0" and "1". + * src/dialogs/export.cpp: stack/register weirdness requires a function + call to get true == comparison of NR::Rect's. Closes bug #1048614. + * src/dialogs/align.cpp: saving erased iterator. Closes bug #1054270. + * share/extensions/ill2svg.pl: added strict, warnings, and detection + of Image::Magick module. Closes bug #990659. + * src/dialogs/find.h, src/dialogs/find.cpp: removed unfinished new + find dialog instantiation. Closes bug #1048802. + +2004-10-27 Carl Hetherington + + * src/extension/output.cpp: better fix for 1004134 after advice + from Ted. + +2004-10-26 Carl Hetherington + + * src/extension/output.cpp: don't reset modified flag until after + save has happened, in case it fails. Fixes 1004134. + + * src/livarot/ShapeSweep.cpp: fix a typo in my cleanups. Fixes + 1048151. + +2004-10-25 Bryce Harringotn + + * file.cpp, file.h, dialogs/export.cpp: Adding error return logic + for png export code so that failure to write can be tracked. + Adding an error dialog for when this occurs. Fixes bug 1038932. + + * extension/system.cpp: Changing sp_ui_error_dialog to g_warning + so won't crash when running from commandline. Fixes bug + 1000350. + + * inkscape.cpp, inkscape.h, main.cpp, dialogs/filedialog.cpp: + Adding Inkscape::Application::use_gui flag as temporary hack to + prevent gui dialogs from being used when running from + commandline. Fixes bug 1045067. + +2004-10-26 Carl Hetherington + + * src/livarot/PathCutting.cpp: fix a couple of bugs that I + introduced that cause crashes on cut path. + +2004-10-25 Kees Cook + + * src/sp-object.cpp: nasty hack to not export metadata on "Plain SVG". + I promise I'll fix this with a proper SPObject soon. + +2004-10-25 Jon A. Cruz + * src/file.cpp, src/file.h, src/inkscape.cpp, src/sp-image.cpp, + src/uri.cpp, src/uri.h, src/dialogs/filedialog.cpp, + src/extension/input.cpp, src/extension/implementation/script.cpp, + src/extension/internal/pov-out.cpp, src/extension/internal/ps.cpp, + src/extension/internal/win32.h, src/extension/plugin/gimpgrad.cpp, + src/helper/png-write.cpp, src/trace/imagemap.cpp, src/xml/repr-io.cpp: + + Refactoring filenames and file opening + +2004-10-24 MenTaLguY + + * src/Makefile.am: added/removed files + + * src/util/copy-list.h: nobody's using it right now, get rid of it + + * src/traits/copy.h, src/traits/list-copy.h: + traits for determining the type to make a copy of a value + + * src/sp-item.cpp, src/util/filter-list.h src/util/map-list.h, + src/util/reverse-list.h, src/widgets/layer-selector.cpp + src/xml/sp-repr-action.cpp: + + let the list functions infer their own result type (where possible) + + * src/util/forward-pointer-iterator.h: its value type is a reference + +2004-10-23 MenTaLguY + + * src/desktop.cpp: removed vertical usize limits on statusbar + + * src/widgets/layer-selector.cpp, src/widgets/layer-selector.h: + more layer selector work; simplfied model and customized CellRenderer + settings a bit + + * src/attributes.cpp, src/attributes.h, src/sp-object.cpp, src/sp-object.h: + add inkscape:label attribute + + * src/file.cpp, src/sp-anchor.h, src/sp-animation.h, src/sp-chars.h, + src/sp-clippath.h, src/sp-conn-end.cpp, src/sp-defs.h, src/sp-ellipse.h, + src/sp-gradient.h, src/sp-guide.h, src/sp-image.h, src/sp-line.h, + src/sp-linear-gradient.h, src/sp-marker.h, src/sp-mask.h, + src/sp-namedview.h, src/sp-object-group.h, src/sp-offset.h, src/sp-path.h, + src/sp-pattern.h, src/sp-polygon.h, src/sp-polyline.h, + src/sp-radial-gradient.h, src/sp-rect.cpp, src/sp-rect.h, src/sp-root.h, + src/sp-spiral.h, src/sp-star.h, src/sp-stop.h, src/sp-string.h, + src/sp-symbol.h, src/sp-text.h, src/sp-tspan.h, src/sp-use.h, + src/sp-offset.cpp, src/sp-shape.h: + + make inheritance actual + +2004-10-23 Peter Moulder + + * src/libnr/*: Move some things from nr-matrix-ops.h to new files. + + * src/libnr/nr-point-fns.h, src/libnr/nr-point-fns.cpp: + New function is_zero. Move is_unit_vector here + (was private to sp-spiral.cpp). + + * src/display/bezier-utils-test.cpp: Disable a test, replacing with a + todo printf and adding a comment explaining. + +2004-10-22 Peter Moulder + + * src/pencil-context.cpp: Ensure that data points array p is uniqued + and contains no NaNs. + + * src/libnr/nr-point-fns.cpp (LInfty): Fix bug with NaN coordinates: + return NaN (rather than unspecified behaviour). + * src/libnr/nr-point-fns-test.cpp: Add test cases for L1,L2,LInfty + handling of NaN. + + * src/pencil-context.cpp: Fix bug: undesirable interactions between + snapping and snap-to-anchor. + +2004-10-21 MenTaLguY + + * src/desktop.cpp: SPDesktop::currentRoot() should pull from + the current layer hierarchy just like SPDesktop::currentLayer(); + doubly so, since currently when switching documents the layer hierarchy + is updated before the document is switched + + * src/util/Makefile_insert, src/util/copy-list.h: add list copy thingy + + * src/util/list.h: add rest() + + * src/util/reverse-list.h: bug fixes to reverse_list_in_place() + + * src/widgets/layer-selector.cpp, src/widgets/layer-selector.h: + more work on layer selector + +2004-10-21 Carl Hetherington + + * src/livarot/Path.cpp, src/livarot/Path.h, + src/livarot/PathConversion.cpp, src/livarot/PathCutting.cpp, + src/livarot/PathOutline.cpp, src/livarot/PathSimplify.cpp, + src/livarot/ShapeMisc.cpp: excise separate path description data + structure. + + * src/livarot/Path.h, src/livarot/Path.cpp, + src/livarot/PathConversion.cpp, src/livarot/PathCutting.cpp, + src/livarot/PathOutline.cpp, src/livarot/PathSimplify.cpp, + src/livarot/ShapeMisc.cpp, src/livarot/livarot-forward.h: move + path description structs into their own files, and rename a few + member variables. + + * src/livarot/Path.h, src/livarot/PathConversion.cpp, + src/livarot/PathOutline.cpp: remove some unused functions. + +2004-10-20 Carl Hetherington + + * src/livarot/Path.cpp: fix for 1050379, and probably lots of + others. + + * src/livarot/Path.h, src/livarot/PathOutline.cpp: bug fix for a + previous commit. + + * src/livarot/Path.cpp: fix a memory leak. + +2004-10-19 Carl Hetherington + + * src/livarot/Path.h, src/livarot/PathSimplify.cpp: more + simplification cleanups. + + * src/livarot/PathStroke.cpp: coding style cleanups. + + * src/livarot/Path.h, src/livarot/PathSimplify.cpp, + src/livarot/PathStroke.cpp: more cleanups; don't modify Path::pts + and Path::nbPt. + + * src/livarot/Path.cpp, src/livarot/Path.h, + src/livarot/PathConversion.cpp, src/livarot/PathCutting.cpp, + src/livarot/PathSimplify.cpp, src/livarot/PathStroke.cpp: use a + std::vector for Path::pts. + +2004-10-18 Carl Hetherington + + * src/livarot/Path.h, src/livarot/PathSimplify.cpp: coding style + and const cleanups. + + * src/livarot/PathSimplify.cpp: some very minor cleanups, and + temporary comments for myself. + + * src/livarot/PathConversion.cpp: coding style cleanups. + + * src/livarot/PathConversion.cpp: fix for bug 1048827. + + * src/livarot/Path.h, src/livarot/PathSimplify.cpp: clean up + simplification code. + +2004-10-17 MenTaLguY + + * share/templates/Makefile.am, share/templates/layers.svg: + added a layer template + + * src/widgets/layer-selector.h, src/widgets/layer-selector.cpp: + more layer selector work + + * src/util/filter-list.h, src/util/Makefile_insert: + added filter_list() + +2004-10-15 Carl Hetherington + + * src/livarot/PathSimplify.cpp: remove #ifdef + pseudo_douglas_pecker code that wasn't being used. + +2004-10-15 MenTaLguY + + * src/view.h: removed obsolete status message functions + + * src/attributes.h: remove unused #define + + * src/sp-object.cpp: fix for bug #1048268 (inkscape:collect being written + in "plain SVG" files) + + * src/sp-item.h, src/sp-item.cpp: added isLocked() and isHidden() + predicates + + * src/sp-item.cpp, src/sp-style.cpp: basic support for visibility CSS + property + +2004-10-14 Ted Gould + + * share/extension/*.inkmod -> *.inx + src/extension/init.cpp + + Changing the filename extension that is used to identify Inkscape + extensions to the one specified in the design document. + +2004-10-14 MenTaLguY + + * src/util/list.h: more 3.4 fixes + +2004-10-13 MenTaLguY + + * src/util/list.h, src/util/forward-pointer-iterator.h: + + fixes to (hopefully) build with g++ 3.4 (and generally be less evil + anyway) + +2004-10-14 Carl Hetherington + + * src/livarot/int-line.cpp: coding style cleanups. + + * src/livarot/float-line.cpp, src/livarot/float-line.h: + refactoring, removal of dead code. + + * src/display/guideline.cpp, src/display/guideline.h: coding style + cleanups. + + * src/livarot/Path.cpp, src/livarot/Path.h, + src/livarot/PathConversion.cpp, src/livarot/PathCutting.cpp, + src/livarot/PathSimplify.cpp, src/livarot/PathStroke.cpp: merge + Path::path_lineto and Path::path_lineto_b. + +2004-10-14 Carl Hetherington + + * src/Path.cpp, src/Path.h, src/PathConversion.cpp, + src/PathCutting.cpp, src/PathOutline.cpp, src/PathSimplify.cpp, + src/ShapeMisc.cpp: use a vector of pointers for Path::descr_cmd. + + * src/livarot/Ligne.cpp, src/livarot/Ligne.h, + src/livarot/int-line.cpp, src/livarot/int-line.h, + src/livarot/float-line.cpp, src/livarot/float-line.h, + src/livarot/livarot-forward.h, src/livarot/ShapeRaster.cpp, + src/sp-flowregion.cpp, src/display/canvas-bpath.cpp, + src/display/nr-arena-glyphs.cpp, src/display/nr-arena-shape.cpp, + src/display/sp-ctrlline.cpp, src/libnrtype/FlowDest.cpp, + src/libnrtype/RasterFont.cpp: split Ligne into float-line and + int-line. + + * src/libnrtype/FlowDest.cpp, src/libnrtype/RasterFont.cpp, + src/libnrtype/raster-position.h, src/livarot/float-line.cpp, + src/livarot/float-line.h, src/livarot/int-line.cpp: use + std::vector for arrays in FloatLigne. + + * src/livarot/float-line.cpp, src/livarot/float-line.h: remove + lots of dead code. Make some methods private. + +2004-10-12 MenTaLguY + + * src/Makefile.am: added files + + * src/layer-fns.cpp, src/sp-item.cpp: use iterators, simplifying code + + * src/sp-object.cpp, src/splivarot.cpp: adapt to new version of + Inkscape::Algorithms::longest_common_suffix + + * src/sp-object.h, src/sp-repr-iterators.h: add new iterator classes + + * src/algorithms/find-last-if.h: add counterpart of std::find_if + + * src/algorithms/longest-common-suffix.h: rewrite to use iterators + + * src/algorithms/longest-prefix.h, src/algorithms/longest-suffix.h, + src/algorithms/shortest-prefix.h, src/algorithms/shortest-suffix.h: + + removed; these algorithms are no longer necessary when using + iterators + + * src/traits/list.h: no longer needed + + * src/traits/reference.h: add "Pointer" member type + + * src/util/Makefile_insert: shuffled files + + * src/util/list.h: reworked Inkscape::Util::List to be a "handle" type + that can also be used as an STL iterator + + * src/util/forward-pointer-iterator.h: treat a pointer as an iterator, + given a base pointer type and a type which defines the iteration + strategy + + * src/util/map.h: obsolete + + * src/util/map-list.h: iterator-based implementation + + * src/traits/tree-iterator.h: no longer necessary (superceded by + specific applications of Inkscape::Util::ForwardPointerIterator) + + * src/sp-object-tree-iterator.h, src/util/parent-axis.h, + src/util/sibling-axis.h: obsolete + + * src/util/map.h, src/util/reverse.h: obsolete + + * src/util/map-list.h, src/util/reverse-list.h: + iterator-based implementations + + * src/xml/Makefile_insert: added file + + * src/xml/repr.h: removed old tree iterator stuff + + * src/xml/sp-repr-action.cpp, src/xml/sp-repr-action.h: use new + pointer iterator facility + + * src/xml/sp-repr-iterators.h: pointer iterators for SPRepr + +2004-10-12 Peter Moulder + + * src/display/bezier-utils.h, src/display/bezier-utils.cpp + (sp_bezier_fit_cubic_r, sp_bezier_fit_cubic_full): Change the meaning + of the last parameter: was max_depth, now lg_max_beziers, with the + relationship lg_max_beziers = max_depth + 1. Callers updated. + + * src/xml/repr.cpp (sp_repr_change_order): + Add g_return_if_fail for some conditions that would break structural + integrity, and add a TODO comment indicating incompleteness. + Use sp_repr_prev function. + + * src/xml/repr-get-children.h, src/xml/repr-get-children.cpp + (sp_repr_prev_sibling): Rename to sp_repr_prev for consistency + with sp_repr_next. Don't consider it an error for child to be + NULL or parentless. Callers updated. + + * src/draw-context.cpp (spdc_concat_colors_and_flush, + spdc_flush_white): Misc readability cleanups. + + * src/display/curve.cpp (sp_curve_reverse): Fix a bug where the + reversed curve wrongly included a trailing moveto command. (Bug + introduced in my 2004-09-05 change: one of the callers I didn't + know how to cause to run.) + +2004-10-12 Ted Gould + + * share/extensions/ai_input.inkmod, share/extensions/ai_output.inkmod, + share/extensions/dia.inkmod, share/extensions/dropshadow.inkmod, + share/extensions/eps_input.inkmod, share/extensions/epsi_output.inkmod, + share/extensions/gimpgrad.inkmod, share/extensions/ps_input.inkmod, + share/extensions/roundhole.inkmod, share/extensions/sk_input.inkmod, + share/extensions/svgz_input.inkmod, share/extensions/svgz_output.inkmod, + share/extensions/txt2svg.inkmod, share/extensions/wmf_input.inkmod, + src/extension/dependency.cpp, src/extension/dependency.h, + src/extension/extension.cpp, src/extension/init.cpp: + + Moving all of the dependency stuff from the scripts, up to the root + extension level. This means that everyone can have dependencies, and + dependency checking (a good thing). This makes use of the new + 'Dependency' class that is also in the extension directory. + +2004-10-11 Peter Moulder + + * src/pencil-context.cpp (sp_pencil_context_root_handler): Split into + many functions, fixing some illegal union aliasing along the way (as + was done for sp_pen_context_root_handler). + + * src/modifier-fns.h: New file of inline functions based on macros.h + MOD__CTRL etc. macros. + * src/Makefile_insert: Add the new file. + + * src/pen-context.h: Change size of p array from SP_DRAW_MAX_POINTS to + 5 now that we aren't sharing with SPPencilContext. + + * src/draw-context.cpp, src/draw-context.h, src/pen-context.cpp, + src/pen-context.h, src/pencil-context.cpp, src/pencil-context.h: + Move npoints,p from SPDrawContext to both SPPenContext and + SPPencilContext. + + * src/draw-context.cpp, src/draw-context.h: Split off new files + pen-context.h, pen-context.cpp, pencil-context.h, pencil-context.cpp, + draw-anchor.h, draw-anchor.cpp. + * src/Makefile_insert: Add the new files. + +2004-10-10 Ted Gould + + * src/event-context.cpp, src/file.cpp, src/file.h, src/print.cpp, + src/print.h, src/selection-chemistry.h, src/sp-image.cpp, src/sp-item.cpp, + src/sp-marker.cpp, src/sp-root.cpp, src/sp-shape.cpp, src/sp-symbol.cpp, + src/tools-switch.cpp, src/dialogs/export.cpp, src/dialogs/filedialog.cpp, + src/extension/Makefile_insert, src/extension/db.cpp, + src/extension/dependency.cpp, src/extension/dependency.h, + src/extension/effect.cpp, src/extension/effect.h, + src/extension/extension-forward.h, src/extension/extension.cpp, + src/extension/extension.h, src/extension/input.cpp, src/extension/input.h, + src/extension/output.cpp, src/extension/output.h, src/extension/print.cpp, + src/extension/print.h, src/extension/system.cpp, + src/extension/internal/eps-out.cpp, src/extension/internal/ps.cpp, + src/extension/internal/svg.cpp, src/libnrtype/FlowResOut.cpp: + + Splitting out the different types of extensions into their own files so + that the overall dependencies can be reduced. Caused a ripple through + lots of other files. Hopefully the dependency situation is better now. + +2004-10-10 Peter Moulder + + * src/draw-context.cpp: + Change xp,yp file globals to NR::Point pen_draw_origin_w. + + * src/draw-context.cpp (sp_pen_context_root_handler): + Split into many routines. Fix some illegal union member aliasing. + (pen_handle_key_press): Minor code cleanups in backspace handling. + (pen_handle_motion_notify): Make tolerance var local instead of + file-global. (This transformation is applicable to many + dragtolerance users.) + + * src/draw-context.cpp (spdc_endpoint_snap_handle): + Change argument type from SPDrawContext to SPPenContext, and + specialize definition accordingly. Caller updated. + + * src/draw-context.h: Change red_curve_is_valid from char to bool. + * src/draw-context.cpp: Change red_curve_is_valid assignments from + 0x00/0x01 to false/true (using find & replace). + +2004-10-07 Carl Hetherington + + * src/nr-object.cpp, src/nr-object.h: coding style and const + fixes. + + * src/nr-rect.cpp: added a doxygen comment. Some coding style + fixes. + + * src/sp-paint-server.cpp: coding style fixes. + + * src/nr-arena-item.cpp, src/nr-arena-item.h: move a comment to + the .cpp file and make it doxygen-style. + + * src/livarot/Path.cpp: coding style cleanups. Add an assert to + Path::Transform(). + + * src/livarot/Path.cpp, src/livarot/Path.h: fix some archaic + notation. + + * src/livarot/Ligne.cpp: coding style cleanups. + + * src/livarot/PathOutline.cpp, src/livarot/Path.h: fix a rather + nasty hack in the outlining code. + + * src/livarot/Path.cpp, src/livarot/Path.h, + src/livarot/PathConversion.cpp, src/livarot/PathCutting.cpp, + src/livarot/PathOutline.cpp, src/livarot/PathSimplify.cpp, + src/livarot/ShapeMisc.cpp, src/splivarot.cpp, src/sp-offset.cpp: + use std::vector for Path::descr_cmd. + + * src/livarot/Path.cpp, src/livarot/Path.h, + src/livarot/PathConversion.cpp, src/livarot/PathCutting.cpp, + src/livarot/PathOutline.cpp, src/livarot/PathSimplify.cpp, + src/livarot/ShapeMisc.cpp: getType() and setType() in Path::path_descr. + +2004-10-07 Peter Moulder + + * src/sp-object-repr.cpp (sp_repr_type_lookup): Distinguish between XML + element name and sodipodi:type attribute value: use a separate table + for each. + * src/sp-object-repr.h, src/sp-object-repr.cpp (sp_object_type_lookup): + Don't export this function. (Also rename it to name_to_gtype and + change its definition for separate tables.) + +2004-10-03 Kees Cook + + * src/dialogs/rdf.cpp, src/dialogs/repr-util.cpp, src/dialogs/repr.h: + Since "dc:title" can appear at multiple XML levels, a way to + control max depth in searching was added. (Closes bug #1009290) + +2004-09-30 MenTaLguY + + * src/widgets/document-tree-model.cpp: + more bug fixes + + * src/widgets/layer-selector.cpp, src/widgets/layer-selector.h: + get the layer selector sort of in more order + +2004-09-28 Ted Gould + + * src/verbs.cpp, src/verbs.h, src/view.cpp: + + Making it so that actions get deleted as views get destroyed. + +2004-09-27 Ted Gould + + * src/desktop.h, src/forward.h, src/interface.cpp, src/interface.h, + src/select-toolbar.cpp, src/shortcuts.cpp, src/shortcuts.h, + src/toolbox.cpp, src/toolbox.h, src/verbs.cpp, src/verbs.h, + src/dialogs/align.cpp, src/dialogs/align.h, + src/dialogs/desktop-properties.cpp, src/dialogs/display-settings.cpp, + src/dialogs/export.cpp, src/dialogs/find.cpp, + src/dialogs/item-properties.cpp, src/dialogs/object-properties.cpp, + src/dialogs/text-edit.cpp, src/dialogs/transformation.cpp, + src/dialogs/xml-tree.cpp, src/helper/action.cpp, src/helper/action.h: + + Wow, alot of files changed. The ones that changed the most are + verb.cpp and verb.h, which are almost entirely different. What happened + here is the verbs were made object oriented. So, as the verbs + are built into everything, lots of files changed. Now the code + for the verbs is much cleaner, and I think a little bit faster. + Also, it will be easier to extend the verbs for use in effects. + +2004-09-26 Peter Moulder + + * src/libnr/nr-matrix.h, src/libnr/nr-matrix.cpp: + Get rid of operator NR::translate(), which was allowing + *implicit* (and typically lossy) conversion to NR::translate, + and which made a bug hard to find. + + * src/sp-gradient-test.cpp: New unit test file. I believe this is the + first test that tests an SPObject. + * src/Makefile_insert, src/Makefile.am: Invoke the new test. + +2004-09-24 MenTaLguY + + * src/selection-chemistry.cpp: + + "select all" and "clear" now operate on the current layer rather than on + the document root + + * src/verbs.cpp, src/shortcuts.cpp, layer-fns.cpp, src/sp-item.cpp: + + keyboard shortcuts and fixes for layer verbs + +2004-09-23 MenTaLguY + + * src/message-stack.h, src/message-stack.cpp: + + return id of flashed messages so they are cancellable + + * src/message-context.h, src/message-context.cpp: + + message context flashes now supercede one another, as regular + messages do (they do not supercede regular messages though) + + * src/interface.cpp, src/layer-fns.cpp, src/layer-fns.h, src/verbs.cpp: + + initial stab at layers menu; not everything works the way it should + quite yet + + * src/message-context.h, src/message-context.cpp: + + added flash methods to Inkscape::MessageContext + + * src/gc-core.h, src/display/nr-arena-glyphs.cpp, +src/display/nr-arena-group.cpp, + src/display/nr-arena-item.cpp, src/display/nr-arena-item.h, + src/display/nr-arena-shape.cpp, src/libnr/nr-object.cpp, +src/libnr/nr-object.h, + + eliminate more sources of leaks; managed objects shouldn't use refcounts + among themselves + + * src/xml/repr.cpp: don't nuke log pointer + +2004-09-21 MenTaLguY + + * src/gc-finalized.h: fix for stupid bug preventing finalizable objects + from being collected + + * src/Makefile_insert, src/gc.cpp, src/gc-core.h: + move Inkscape::GC::init out-of-line, and funnel GC warnings through + glib + +2004-09-21 Peter Moulder + + * src/sp-marker.h, src/sp-marker.cpp (sp_marker_show_instance): + Change to using NR::Matrix instead of NRMatrix. Update caller. + + * src/sp-gradient.cpp (sp_gradient_get_g2d_matrix, + sp_gradient_get_gs2d_matrix, sp_gradient_set_gs2d_matrix): + New NR::Matrix/NR::Rect versions of existing functions. + + * src/libnr/nr-matrix-translate-ops.h (operator/): New function. + + * src/libnr/nr-matrix-scale-ops.cpp: New file. + * src/libnr/nr-matrix-scale-ops.h (operator/(Matrix,scale)): + New function. + +2004-09-20 Peter Moulder + + * src/sp-gradient.h: Change gradientTransform from NRMatrix to + NR::Matrix. Users updated. + + * src/Makefile.am (EXTRA_DIST), Makefile_insert + dialogs/Makefile_insert extension/implementation/Makefile_insert + extension/internal/Makefile_insert helper/Makefile_insert + livarot/Makefile_insert (blah_SOURCES): + Add some .h files for `make dist'. + +2004-09-19 MenTaLguY + + * src/gc-core.h: don't defer finalizers + + * src/gc-core.h: bump up free space divisor -- collections should + happen ~32x more frequently + +2004-09-19 Carl Hetherington + + * src/display/canvas-bpath.cpp, src/display/nr-arena-shape.cpp, + src/display/sp-ctrlline.cpp, src/libnrtype/RasterFont.cpp, + src/livarot/Shape.h, src/livarot/ShapeRaster.cpp: remove some + unused parameters from calls to raster code. + + * src/livarot/ShapeRaster.cpp: coding style cleanups. + + * src/livarot/Shape.h, src/livarot/ShapeRaster.cpp: factored out + _updateIntersection(). + + * src/livarot/AVL.cpp, src/livarot/AVL.h: remove DblLinked. Cleanups. + +2004-09-18 MenTaLguY + + * src/dialogs/filedialog.cpp: unref the preview document we created + +2004-09-18 Carl Hetherington + + * src/livarot/AVL.cpp, src/livarot/AVL.h, + src/livarot/DblLinked.cpp, src/livarot/DblLinked.h, + src/livarot/LivarotDefs.h, src/livarot/ShapeRaster.cpp, + src/livarot/ShapeSweep.cpp, src/livarot/sweep-tree.cpp, + src/livarot/sweep-tree.h, src/sweep-event.h: replace leftFoo and + rightFoo with foo[2] in a few places. Associated cleanups. + + * src/livarot/Shape.h: use Side rather than a bool for + TesteIntersection. Add some methods. Remove some unused variables. + + * src/livarot/ShapeSweep.cpp: simplify TesteIntersection with use + of Side. + + * src/livarot/sweep-event.h: const fix. + + * src/livarot/sweep-event.cpp: simplifications with use of Side. + + * src/sp-offset.cpp, src/splivarot.cpp, src/livarot/Shape.cpp, + src/livarot/ShapeMisc.cpp, src/ShapeSweep.cpp: lastA/firstA in + Shape::dg_point -> + + further work on stroking; break out bezier approximation into + public functions + +2004-09-10 MenTaLguY + + * src/render/polygon.h, src/render/shape-builder.h, + src/render/shape-builder.cpp, src/render/stroke.h, + src/render/dash.h: + + beginnings of a simple alternate renderer + +2004-09-09 Carl Hetherington + + * src/sp-flowtext.cpp, src/sp-offset.cpp, src/splivarot.cpp, + src/display/nr-arena-shape.cpp, src/libnrtype/FlowDest.cpp, + src/livarot/PathConversion.cpp, src/livarot/Shape.h: make + Shape::nbPt and Shape::nbAr private and provide accessor methods. + + * src/display/nr-arena-shape.cpp, src/livarot/Shape.h: make + Shape::flags private. + + * src/splivarot.cpp, src/livarot/PathStroke.cpp, + src/livarot/Shape.cpp, src/livarot/Shape.h, src/livarot/ShapeMisc.cpp, + src/livarot/ShapeRaster.cpp, src/livarot/ShapeSweep.cpp: + Clean up handling of flags in Shape class + + * src/livarot/AlphaLigne.cpp, src/livarot/Path.cpp, + src/livarot/PathSimplify.cpp, src/livarot/Shape.cpp, + src/livarot/ShapeSweepUtils.cpp: it's ok to free NULL. + + * src/livarot/Shape.h, src/sp-offset.cpp, src/splivarot.cpp, + src/display/nr-arena-shape.cpp: Make Shape::pts private and offer + a read-only accessor. + + * src/livarot/Shape.cpp, src/livarot/Shape.h, + src/livarot/ShapeDraw.cpp, src/livarot/ShapeMisc.cpp, + src/livarot/ShapeRaster.cpp, src/livarot/ShapeSweep.cpp, src/ + livarot/ShapeSweepUtils.cpp, src/livarot/ShapeUtils.h: Rename + Shape::pts to Shape::_pts, and use getPoint() wherever possible. + + * src/sp-offset.cpp, src/splivarot.cpp, src/livarot/Shape.cpp, + src/livarot/Shape.h, src/livarot/ShapeMisc.cpp, + src/livarot/ShapeRaster.cpp, src/livarot/ShapeSweep.cpp: Add + dg_point::totalDegree() and make use of it. + + +2004-09-08 MenTaLguY + + * src/libnr/nr-object.h, src/libnr/nr-object.cpp: fix NRObject + initialization + + * configure.in, src/gc-core.h, src/gc-managed.h, src/gc-anchored, + src/gc-finalized.h: + + add a --disable-gc ./configure option to omit garbage collection + from the build (the normal allocator will be used, although + memory will obviously leak since it does not get explicitly freed) + + * src/xml/repr.cpp: SPRepr's copy constructor needs to properly + initialize its fields + + * src/xml/repr-util.cpp, src/xml/repr-private.h, + src/xml/repr.h, src/xml/repr.cpp: + + new child-count-related routines, and added mutation signals + to SPReprDoc + + * src/desktop.cpp: call the "Active Group" widget by its TRUE NAME! + + * src/widgets/Makefile_insert, src/widgets/document-tree-model.cpp, + src/widgets/document-tree-model.h, src/widgets/layer-selector.cpp, + src/widgets/layer-selector.h: + + very cursory start on new layers UI + +2004-09-08 Carl Hetherington + + * src/helper/stock-items.cpp: fix a bad free(). Improve coding + style compliance. + + * src/libnrtype/FlowRes.cpp: slightly unpleasant fix for a buffer + overrun. + +2004-09-07 MenTaLguY + + * src/livarot/Shape.cpp, src/livarot/Shape.h, src/livarot/ShapeMisc.cpp, + src/livarot/ShapeSweep.cpp: + + use std::vector for points array (seems to crash less?) + + * src/livarot/AlphaLigne.cpp, src/livarot/BitLigne.cpp, + src/livarot/Ligne.cpp, src/livarot/Path.cpp, + src/livarot/PathCutting.cpp, src/livarot/PathSimplify.cpp, + src/livarot/Shape.cpp, src/livarot/ShapeMisc.cpp, + src/livarot/ShapeSweep.cpp, src/livarot/ShapeSweepUtils.cpp: + + switch to glib's allocator routines, which have the expected + semantics + + * src/livarot/evil-malloc.h: removed + +2004-09-07 Ted Gould + + * src/color-rgba.h: + + Some comments and some little code clean up things. Added a couple + of constructors to make life a little simpler. + +2004-09-06 Ted Gould + * src/extension/plugin/gimgrad.cpp, src/extension/implementation/plugin* + share/extension/gimpgrad.inkmod, src/extension/system.cpp, + src/extension/extension.h: + + Mega commit. This commit does two things, it adds in the ability to + do plugins in Inkscape. This means that there are loadable modules + that can be used for just about anything. It also provides a sample + implementation of a plugin to load GIMP gradients. This means that + GIMP gradients can be imported into Inkscape, giving a larger set of + gradients that can be used in Inkscape. + + Currently, nothing here is really complete, but it is functional. The + plugins really only work for input plugins, and the GIMP gradient example + isn't very robust. They will come shortly. + +2004-09-05 Peter Moulder + + * src/display/curve.h, src/display/curve.cpp: + Change x,y members to NR::Point. + Rename posset (spiced&spiked hot milk) to posSet as per CodingStyle. + + * src/display/curve.cpp (sp_curve_reverse): Previously this + routine returned only the last subpath, and made it an open + path. Now it preserves all aspects of the curve other than + reversing it. I believe this change makes no difference to the + draw-context and dyna-draw-context callers (though I haven't + managed to test all of these callers), whereas for the `reverse + path' command, users presumably expect the new behaviour. + + * src/display/curve.cpp (sp_curve_closepath_current): + Fix bad assertion. + + * src/libnr/nr-matrix-fns.h, src/libnr/nr-matrix-fns.cpp + (get_translation): New function. + + * src/sp-polygon.cpp (polygon_get_value): Use static linkage. + (sp_polygon_set): Remove debugging output. Add `todo' comment. + +2004-09-03 MenTaLguY + + * src/attributes.cpp, src/attributes.h, src/sp-namedview.cpp, + src/sp-namedview.h: + + remember previously selected layer on load + +2004-09-02 MenTaLguY + + * src/attributes.cpp, src/attributes.h, src/sp-item-group.cpp: + + reintroduced the inkscape:groupmode attribute + + * src/gc-core.h, src/gc-finalized.h, src/gc-anchored.h, + src/libnr/nr-object.cpp: + + remove USE_LIBGC macro again + +2004-08-30 MenTaLguY + + * src/sp-object.cpp: + + ref the object while SPObject::deleteObject runs, so it doesn't + get destroyed halfway through [ fix for bug #1012874 ] + +2004-08-29 MenTaLguY + + * src/gc-core.h: + + turn off scanning of dynamic library data segments; we don't need + it, and it seems to cause problems on FC2 + +2004-08-27 MenTaLguY + + * src/traits/function.h: add typedefs for all argument positions, + specifying 'void' for all arguments after the last + + * src/livarot/evil-malloc.h, src/livarot/BitLigne.cpp, + src/livarot/PathCutting.cpp, src/livarot/PathSimplify.cpp, + src/livarot/Shape.cpp, src/livarot/ShapeSweepUtils.cpp: + + work around livarot bugs so I can use ElectricFence + + * src/gc-core.h, src/gc-finalized.h, src/gc-anchored.h, + src/libnr/nr-object.cpp: + + make the garbage collector easy to disable by undefining + USE_LIBGC in src/gc-core.h + +2004-08-26 MenTaLguY + + * src/document-private.h, src/document.h, src/document.cpp: + + add notification signal when resources are added or removed + +2004-08-25 Peter Moulder + + * src/xml/repr-css.cpp (sp_repr_css_print): + Fix for shared string change. + + * src/sp-text.cpp (sp_text_description): + Fix for when font Name() call fails. + + * src/sp-text.cpp: CodingStyle changes, including moving some + declarations to first use. + Remove unused __SP_TEXT_C__ define. + +2004-08-25 Carl Hetherington + + * src/sp-cursor.cpp, src/sp-cursor.h, src/sp-guide.cpp: + coding style cleanups. + +2004-08-24 MenTaLguY + + * src/gc-anchor.h: fix to always use the GC base address, since + that will not always be the same as 'this', when I::GC::Anchored + is used via multiple inheritance. + +2004-08-24 Peter Moulder + + * src/libnrtype/TextWrapper.h, src/libnrtype/TextWrapper.cpp (AppendUTF8): + Use strlen instead of for-loop. + Change printf to g_return_if_fail (and document that the argument + must be valid UTF-8). + Mark the text pointer as not being written through (const). + +2004-08-23 MenTaLguY + + * src/xml/repr.cpp, src/xml/sp-repr-action.h: + + removed stupid default 'next' constructor arguments and force them + to be specified explicitly (and fix the omission of one, which + fixes bug #1014541) + +2004-08-22 MenTaLguY + + * src/Makefile_insert, src/gc-alloc.h: + + introduced a GC-aware STL allocator + + * src/document-private.h, src/document.h, src/document.cpp: + + switch to using STL map for "id changed" signals + +2004-08-21 MenTaLguY + + * src/Makefile_insert, src/util/Makefile_insert: get libinkutil + deps straightened out + + * src/document-private.h, src/document-undo.cpp, src/document.cpp: + + adapt for new APIs, header cleanups/refactorings + + * src/gc-core.h, src/gc-anchored.h, src/gc-finalized.h, src/gc-managed.h: + + rewrote interface to Boehm GC for increased flexibility; there are now + three main classes: + + - Inkscape::GC::Managed: objects managed by the GC; replaces + Inkscape::GC::Object + + - Inkscape::GC::Finalized: objects for which the GC will call + destructors automatically; replaces + Inkscape::GC::FinalizedObject + + - Inkscape::GC::Anchored: managed objects which can be 'anchored' + to prevent collection while non-gc-aware + objects are holding references; replaces + Inkscape::Refcounted + + Note that they no longer inherit from each other(!), so you will + need to mix-and-match via multiple inheritance. The latter two + don't do anything useful without the first, however. + + * src/gc-object.h, src/refcounted.h: removed + + * src/message-context.cpp, src/message-stack.h, src/selection.h, + src/view.cpp, src/libnr/nr-object.h, src/util/list.h, + src/xml/sp-repr-attr.h, src/xml/sp-repr-listener.h, src/desktop.cpp: + + adopt new GC API and header refatorings + + * src/Makefile.am, src/util/Makefile_insert: + + list util/* files in util's Makefile_insert now. + + * src/util/reverse.h: revive anx fix Inkscape::Util::reverse + + * src/util/share-c-string.cpp, src/util/share-c-string.h: removed + + * src/util/shared-c-string.cpp, src/util/shared-c-string.h: + + employ the type system to make shared strings a little safer to use; + you can still shoot yourself in the foot, but at least now you need + to aim and pull the trigger first + + * src/xml/Makefile_insert, src/xml/repr-action-test.cpp, + src/xml/sp-repr-action-fns.h, src/xml/sp-repr-action.h: + + reorganize transaction logging files + + * src/xml/repr-action-test.cpp: updated headers + + * src/xml/repr-action.cpp, src/xml/repr-action.h: removed + + * src/xml/repr-private.h, src/xml/repr.cpp, src/xml/repr.h: + + update for new GC API and shared strings + + * src/xml/sp-repr-action-fns.h, src/xml/sp-repr-action.cpp, + src/xml/sp-repr-action.h: + + header refactoring and new GC API + + * src/xml/sp-repr-attr.h, src/xml/sp-repr-listener.h: + + new GC API + +2004-08-20 Carl Hetherington + + * src/zoom-context.cpp, src/view.cpp, src/version.cpp, + src/sp-defs.cpp: coding style cleanups. + + * src/sp-polygon.cpp: coding style and a few other small cleanups. + + * src/sp-anchor.cpp: coding style cleanups. Remove unnecessary + static variable. + +2004-08-18 Bryce Harrington + + * autogen.sh: Fixing the 'missing ltmain.sh' bug + +2004-08-17 Peter Moulder + + * src/sp-star.cpp: Use cast to guint32 instead of using modulo 2**32. + Fix a uint compilation bug on Windows reported by mrchapp. + Mark a few functions as static. + +2004-08-16 Peter Moulder + + * src/sp-conn-end.cpp (change_endpts): + Use new sp_curve_stretch_endpoints function: i.e. preserve the + shape of the connector path. + + * src/display/curve.h, src/display/curve.cpp + (sp_curve_stretch_endpoints): New function. + + * src/sp-use-reference.cpp: CodingStyle changes. + + * src/sp-item.h, src/sp-item.cpp (sp_item_write_transform): + Indicate that adv won't get written to. + + * src/sp-rect.cpp (sp_rect_set_transform): Call sp_rect_set_shape, + so that bbox is up-to- src/livarot/PathConversion.cpp, +src/livarot/Shape.cpp, + src/livarot/Shape.h, src/livarot/ShapeDraw.cpp, src/livarot/ShapeMisc.cpp, + src/livarot/ShapeRaster.cpp, src/livarot/ShapeSweep.cpp, + src/livarot/ShapeSweepUtils.cpp: + Revert these files to their state prior to mental's "2004-08-08" + entry (the change made in 2004-08-09 02:23 UTC). + +2004-08-11 Peter Moulder + + * src/algorithms/longest-common-suffix.h: Fix bug I introduced three + days ago. + + * src/attributes.h, src/attributes.cpp: New attributes + SP_ATTR_CONNECTION_START, SP_ATTR_CONNECTION_END. + * src/sp-conn-end.h, src/sp-conn-end.cpp, + src/sp-conn-end-pair.h, src/sp-conn-end-pair.cpp: + New files. + * src/Makefile_insert (libinkpre_a_SOURCES): Add the new files. + + * src/sp-path.cpp, src/sp-path.h: Call the new connector stuff. + + * src/display/curve.h, src/display/curve.cpp + (sp_curve_first_point, sp_curve_last_point): New functions. + + (sp_curve_transform): Re-implement with NR::Matrix/NR::Point. + The old code appears to be buggy for sheer/rotate matrices + due to calculating each y coord using the new corresponding x coord + instead of the previous value. + + Also add NR::translate version. + + Get rid of the return value. Callers updated. + + * src/sp-item.h, src/sp-item.cpp: (i2anc_affine): New function + (essentially a rename of existing private partial_xform function, but + differing behaviour on encountering non-SPItem in the hierarchy). + + (i2i_affine): New function (essentially a rename of existing + SPItem::getRelativeAffine). Implement SPItem::getRelativeAffine in + terms of the new function. + + (sp_item_dt2i_affine): NR::Matrix version. + + * src/libnr/nr-path.h (c, setC): new methods. + +2004-08-09 Peter Moulder + + * src/desktop-affine.cpp (sp_desktop_w2doc_affine, + sp_desktop_doc2w_affine, sp_desktop_doc2d_xy_point), + src/knotholder.cpp (knot_moved_handler), src/sp-item.cpp + (SPItem::getRelativeTransform), src/sp-rect.cpp + (sp_rect_set_transform), src/display/sp-canvas-util.cpp + (sp_canvas_item_i2i_affine, sp_canvas_item_set_i2w_affine): + Cleanup: Use the new division operators instead of multiplication by + inverse. (Currently the division operators are implemented as + multiplication by inverse.) + + * src/splivarot.cpp, src/livarot/Shape.cpp, src/livarot/ShapeMisc.cpp, + src/livarot/ShapeRaster.cpp, src/livarot/ShapeSweep.cpp: + Hurriedly fix some problems caused by overly-hurried changes. + Address some signed/unsigned warnings. + Add some assertions. + (Haven't checked the performance cost of the assertions.) + + * src/livarot/Shape.h: Make constructors explicit. + +2004-08-08 MenTaLguY + + * src/sp-flowregion.cpp, src/sp-flowtext.cpp, src/sp-offset.cpp, + src/splivarot.cpp, src/display/nr-arena-shape.cpp, + src/livarot/PathConversion.cpp, src/livarot/Shape.cpp, + src/livarot/Shape.h, src/livarot/ShapeDraw.cpp, + src/livarot/ShapeMisc.cpp, src/livarot/ShapeRaster.cpp, + src/livarot/ShapeSweep.cpp, src/livarot/ShapeSweepUtils.cpp: + + replace ad-hoc realloced arrays with std::vector and deal with + uninitialized data problems that valgrind complained about + + * libgc.supp: valgrind suppression profile for libgc, which necessarily + reads and runs comparisons on a lot of uninitalized data; the present + form of this file is probably too broad however + +2004-08-08 Peter Moulder + + * src/libnr/nr-matrix-div.h, src/libnr/nr-matrix-div.cpp: + operator/(NR::Point, NR::Matrix), operator/(NR::Matrix, NR::Matrix): + new functions, new files. + + * src/algorithms/longest-common-suffix.h: + Handle in O(1) time the common case of equal tails. + Documentation. + +2004-08-08 Ted Gould + + * src/svg-profile.h, src/Makefile_insert: + + Adding the first support in for trying to determine which profiles are + used with certain functionality, and if that is used by the current + document. Really, right now, there is no code changes to anything that + compiles. But this is the header file that contains the class that + I'm plannig to use in the future. + +2004-08-07 Peter Moulder + + * src/libnrtype/RasterFont.h, src/libnrtype/RasterFont.cpp: + Get rid of argumentless constructor (which was leaving + style.transform as random bits), replace with constructor taking + style argument. Caller updated. + Disable default copy constructor and operator=. + +2004-08-06 MenTaLguY + + * configure.in, src/gc-core.h, src/gc-object.h, + src/display/nr-arena-glyphs.cpp, src/display/nr-arena-group.cpp, + src/display/nr-arena-image.cpp, src/display/nr-arena-item.cpp, + src/display/nr-arena-shape.cpp, src/display/nr-arena.cpp, + src/helper/action.cpp, src/libnr/nr-object.cpp, src/libnr/nr-object.h: + + make NRObject GC-aware + +2004-08-06 David Turner + * src/sp-shape.cpp (sp_shape_marker_get_transform): Make marker handling +match + SVG spec better. + +2004-08-06 Peter Moulder + + * src/libnr/nr-matrix.h, src/libnr/nr-matrix.cpp: + NR::Matrix *= NR::scale: new. + + * src/sp-object.cpp, src/sp-object.h, src/sp-object-tree-iterator.h: + Move TreeIterator specialization to snew file + sp-object-tree-iterator.h. + Mark several pointers as not being written through. + Correspondingly change TreeIterator specialization to + instead of . + + * display/nr-arena-item.cpp, display/nr-arena-item.h: + Add NR::Matrix version of nr_arena_item_set_transform. + + * src/sp-item.h, src/sp-item.cpp (getRelativeTransform, partial_xform): + Mark pointers as not written through. + + * src/arc-context.cpp, src/draw-context.cpp, src/dyna-draw-context.cpp, + src/path-chemistry.cpp, src/rect-context.cpp, + src/selection-chemistry.cpp, src/seltrans.cpp, src/sp-flowdiv.cpp, + src/sp-flowregion.cpp, src/sp-flowtext.cpp, src/sp-item-group.cpp, + src/sp-item-notify-moveto.cpp, src/sp-item-transform.cpp, + src/sp-item.cpp, src/sp-item.h, src/sp-offset.cpp, src/sp-rect.cpp, + src/sp-shape.cpp, src/sp-use.cpp, src/spiral-context.cpp, + src/splivarot.cpp, src/star-context.cpp, src/text-context.cpp, + src/dialogs/item-properties.cpp: + Change SPItem->transform from NRMatrix to NR::Matrix. + + * src/libnr/nr-matrix-ops.h (operator*(NR::Matrix, NRMatrix)): new. + + * src/libnr/nr-matrix.h: NR::Matrix *= NR::translate: new operator. + + * src/nodepath.cpp: Mark NodeSort operator< as static. + Indentation as per CodingStyle. + + * src/libnr/nr-scale.h (NR::scale(double)): new constructor. + + * src/svg/svg-affine.cpp (sp_svg_transform_write), src/svg/svg.h: + Add NR::Matrix version. + +2004-08-05 Peter Moulder + + * src/display/bezier-utils.cpp: Misc. minor changes. + +2004-08-04 MenTaLguY + + * configure.in, src/gc-object.h, src/refcounted.h: + + start using libgc in earnest; Inkscape::Refcounted is now GC-aware + +2004-08-04 Peter Moulder + + * src/nodepath.cpp: Cleanups: Mark some things as static. Switch from + pointer to reference in some places. Make const placement conform to + CodingStyle. + + * src/inkview.cpp (sp_svgview_main_key_press): Accept some common keys + like PgUp, q. + + * src/draw-context.cpp (fit_and_split): + Slight simplification: don't handle impossible condition npoints < 2. + * src/proofs: Update accordingly. (Also add some bezier-utils proofs.) + +2004-08-04 David Turner + + * sp-path.cpp: 'd' is a required attribute for paths. Ensure that + all paths have it. + +2004-08-03 MenTaLguY + + * src/dialogs/rdf.cpp, src/xml/repr-util.cpp, src/xml/repr.h: + removed sp_repr_recursive_drop() which is unneeded and + creates unnecessary thrash in the undo logs + + * src/livarot/Shape.h, src/livarot/Shape.cpp, + src/livarot/ShapeSweep.cpp, src/livarot/ShapeMisc.cpp: + + experiment to replace ad-hoc realloc() arrays with std::vector + +2004-08-02 David Turner + + * file.cpp, file.h, interface.cpp, toolbox.cpp, verbs.cpp, verbs.h: + + Added vacuum command to remove unused defs. + +2004-08-02 MenTaLguY + + * configure.in: sigc++ 2.0.2 (and before?) has a bug that + causes us to crash. require >= 2.0.3 + + * src/Makefile.am, src/Makefile_insert, src/gc-core.h, + src/gc-object.h, src/algorithms/longest-common-suffix.h, + src/traits/list.h, src/traits/reference.h, src/util/flip.h, + src/util/fold.h, src/util/list-iterator.h, src/util/list.h, + src/util/map.h, src/util/parent-axis.h, src/util/reverse.h, + src/util/sibling-axis.h, src/util/tuple.h, src/util/zip.h: + + more "functional" work + +2004-08-02 Peter Moulder + + * src/display/curve.cpp, src/display/curve.h: + Greater conformance with CodingStyle. + +2004-07-31 David Turner + + * dialogs/xml-tree.cpp: Improved focus, added keystroke for attr commit. + +2004-07-31 Ted Gould + + * src/extension/extension.cpp, + src/extension/implementation/implementation.cpp, + src/extension/implementation/implementation.h, + src/extension/implementation/script.cpp, + src/extension/implementation/script.h, src/extension/internal/eps-out.cpp, + src/extension/internal/eps-out.h: + + Okay, changed the prefs_ prototypes to include which extension they are + working with. This should clean up some warnings before they become + problems later. + +2004-07-31 Ted Gould + + * src/print.cpp, src/extension/extension.cpp, src/extension/extension.h, + src/extension/internal/eps-out.cpp, src/extension/internal/ps.cpp: + + Changed the get and set param prototypes so that they aren't overloaded + anymore - this was flaky. Also added a document to the prototype so + that document specific parameters can be supported in the future. + +2004-07-28 David Turner + + * sp-gradient.cpp, widgets/gradient-vector.cpp: fixed gradient handling to + properly render gradients with sharp color boundaries + +2004-07-29 Peter Moulder + + * src/inkview.cpp: Make the window title be the name of the + instead of the current file instead of the first file. + + * src/round-test.cpp: New unit-test file. + + * src/desktop.h, src/sp-desktop-widget.h: + Move SPDesktopWidget stuff from desktop.h to new file + sp-desktop-widget.h. + + * debian/*: Copy lots of changes from wolfi's official Debian package + of inkscape. + Also use separate builddir, which simplifies the `clean' target. + +2004-07-24 MenTaLguY + + * configure.in, src/Makefile.am, src/main.cpp, src/gc-core.h: + added libgc dependency + + * src/Makefile.am, traits/function.h: + added trait class for functions and C++ "functors" + + * src/Makefile.am, util/flip.h: + added flip() which, given a function with two arguments, + returns an identical function with its arguments reversed + +2004-07-23 MenTaLguY + + * src/Makefile.am, src/traits/reference.h, src/util/tuple.h: + added generic Tuple type + +2004-07-23 Ted Gould + + * src/attributes.cpp, src/attributes.h, src/sp-namedview.cpp, + src/sp-namedview.h, src/dialogs/desktop-properties.cpp, + src/display/canvas-grid.cpp, src/display/canvas-grid.h: + + Adding in the ability to have 'emphasis grid lines' where some lines are a + different color than others. In the default case every fifth grid line + gets to be 0x11 darker alpha. Nothing that will get in your way, but + enough that you can find the spacing. All parameters are changeable in + document preferences. + +2004-07-23 Peter Moulder + + * autogen.sh: Move unversioned automake to last resort. + +2004-07-20 Kees Cook + + * src/dialogs/desktop-preferences.cpp: corrected my usage of static + l18n strings. + * src/dialogs/stroke-style.cpp: fixed missing l18n. (bug #994837) + * src/dialogs/sp-attribute-widget.cpp: went hunting for other static + l18n strings. Fixed some here too. + * autogen.sh: cleanups and more debugging. + * share/extensions/sk2svg.sh: tempfile cleanups from pjrm (patch #990009) + +2004-07-20 Nathan Hurst + + * debian/changelog, configure.in: Moved to 0.40cvs and updated + debian stuff. + +2004-07-18 MenTaLguY + + * configure.in, src/Makefile.am, src/algorithms/Makefile_insert, + src/algorithms/makefile.in, src/traits/Makefile_insert, + src/traits/makefile.in, src/util/Makefile_insert, src/util/makefile.in: + + added src/algorithms, src/traits, and src/util subdirs + + * src/algorithms/longest-common-suffix.h: + + added generic "longest common suffix" algorithm + + * src/traits/list.h: added traits class for lists + + * src/traits/tree-iterator.h: added traits class for n-ary tree iterators + + * src/util/list-iterator.h: STL iterator for lists + + * src/util/parent-axis.h: parent "axis" of tree iterator as list + + * src/util/sibling-axis.h: sibling "axis" of tree iterator as list + + * src/xml/repr.h: specialize Traits::TreeIterator for SPRepr * + + * src/sp-object.h: specialize Traits::TreeIterator for SPObject * + + * src/sp-object.cpp: use generic "longest common suffix" to find + nearest common ancestor + + * src/splivarot.cpp: use genric "longest common suffix" to find + nearest common ancestor here too + +2004-07-18 Kees Cook + + * Makefile.am, configure.in, autogen.sh, toolversions.sh: + cleaning up some automake misbehavior from the gtkmm patch. + automake 1.4isms snuck back in. + * src/desktop-events.cpp: unlocalized strings updated. + +2004-07-18 Peter Moulder + + * src/sp-path.cpp (sp_path_write): Handle shape->curve==NULL. + +2004-07-18 MenTaLguY + + * Makefile.am, configure.in, m4/Makefile.am, m4/codeset.m4, m4/gettext.m4, + m4/glibc21.m4, m4/iconv.m4, m4/isc-posix.m4, m4/lcmessage.m4, + m4/progtest.m4, src/arc-context.cpp, src/arc-context.h, src/desktop.cpp, + src/desktop.h, src/document.cpp, src/document.h, src/draw-context.cpp, + src/draw-context.h, src/event-context.h, src/main.cpp, + src/message-stack.h, src/node-context.cpp, src/node-context.h, + src/nodepath.cpp, src/nodepath.h, src/object-hierarchy.h, + src/rect-context.cpp, src/rect-context.h, src/selcue.cpp, src/selcue.h, + src/selection-describer.cpp, src/selection-describer.h, + src/selection.h, src/seltrans.cpp, src/sp-gradient.cpp, + src/sp-item.cpp, src/sp-item.h, src/sp-object.cpp, src/sp-object.h, + src/sp-offset.cpp, src/sp-offset.h, src/sp-pattern.cpp, src/sp-use.cpp, + src/sp-use.h, src/spiral-context.cpp, src/spiral-context.h, + src/star-context.cpp, src/star-context.h, src/text-context.cpp, + src/text-context.h, src/toolbox.cpp, src/uri-references.cpp, + src/uri-references.h, src/view.cpp, src/view.h, + src/dialogs/xml-tree.cpp: + + merged Aubanel MONNIER's gtkmm upgrade patch + +2004-07-17 Carl Hetherington + + * src/sp-use.cpp: fix a compiler warning (closes #992960) + + * src/sp-offset.cpp: fix a compiler warning (closes #992960) + + * src/sp-text.cpp: fix a compiler warning (closes #992959) + +2004-07-16 Kees Cook + + * src/verbs.h, src/verbs.cpp: added "sp_verbs_find" function for bryce. + +2004-07-15 Ted Gould + + * 0.39 Release + +2004-07-14 MenTaLguY + + * src/sp-object.cpp: disable recursive update warning for release + + * src/select-context.cpp: work around probable cut-and-paste bug + between sp_select_context_item_handler and + sp_select_context_root_handler by checking for drag_escaped + +2004-07-13 MenTaLguY + + * src/make.exclude: omit extension/script/js/js.c from build + +2004-07-13 Peter Moulder + + * src/dialogs/rdf.cpp: Don't add dc:description entry to SVG files. + + * src/utest/utest.h: Add include guard. + +2004-07-12 Peter Moulder + + * src/decimal-round.h (decimal_round): New file, new function. + * src/round.h (decimal_round): New file, new function. + * src/Makefile_insert: Add to libinkpost_a_SOURCES. + +2004-07-11 MenTaLguY + + * src/document.h, src/document-undo.cpp: + added sp_document_get_undo_sensitive() for capturing and restoring + undo sensitivity + + * src/sp-object.cpp: don't log id changes made to resolve + duplicate ids (to avoid undo badness) (fix for bug #989023) + +2004-07-11 Kees Cook + + * src/preferences-skeleton.h, src/extension/init.cpp: with simarilius, + tracked down the cause of bug #988445. Extension code now has a + small section that validates preferences for valid extension names. + * src/dialogs/filedialog-win32.cpp: corrected an assert test, and + changed dialog to take the passed window title. + * autogen.sh, config.h.mingw, configure.in, src/Makefile_insert, + src/help.cpp, src/inkscape-stock.cpp, src/inkscape.cpp, src/main.cpp, + src/make.dep, src/make.files, src/path-prefix.h, src/prefix.cpp, + src/prefix.h, src/dialogs/stroke-style.cpp, + src/extension/Makefile_insert, src/extension/init.cpp, + src/extension/implementation/Makefile_insert, + src/extension/implementation/script.cpp, + src/extension/internal/Makefile_insert, src/helper/stock-items.cpp, + src/widgets/icon.cpp: + Cleaned up all the path #define's and usage. In the process found at + least 3 separate bugs associated with file locations. This should + hopefully work for Win32 as well. Bottom line in this change: don't use + INKSCAPE_DATADIR anywhere except in "path-prefix.h". This includes + an update to the autopackage code as well with fixes so that + a change to "--enable-binreloc" will get recompiled correctly. These + changes should address bug #978391. + +2004-07-11 Carl Hetherington + + * src/attributes.cpp, src/attributes.h: remove confusing + snaptogrid and snaptoguides options. + + * src/desktop-events.cpp: use inkscape:guide-bbox instead of + snaptoguides to turn guides on. + + * src/desktop.cpp: no need to worry about Snapper::getEnabled(). + + * src/snap.cpp, src/snap.h: Remove explicit enabled flag from + Snapper, as itconfuses people. Added + namedview_dim_snap_all_types(). Return useful stuff from + vector_snap_list. + + * src/rect-context.cpp: Use hack to make snapping kind of work + even with snap-to-bbox enabled. + + * src/sp-namedview.cpp, src/dialogs/desktop-properties.cpp: remove + snaptogrid and snaptoguides options as they confuse people. Use + better names for the scale origin radio buttons, as suggested by + Bulia. + + * src/seltrans.cpp: Fix some cases where snap wasn't correctly applied. + +2004-07-10 MenTaLguY + + * src/sp-image.cpp: prospective fix for bug #979858 + + * src/select-context.cpp, src/select-context.h, + src/seltrans.cpp, src/seltrans.h: + + gave SPSelTrans its own Inkscape::MessageContext, fixing + bug #977971 + +2004-07-10 Kees Cook + + * src/knot.cpp: solved bug #988513: knot could stay grabbed in + situations where the tool went away but never got "button_release" + event. This patch uses the "enter" and "leave" notifiers to disable + the grab before a "motion" can come and snag the knot. + +2004-07-09 Kees Cook + + * src/widgets/paint-selector.cpp: solved bug #984902: the pattern + menu was being destroyed since it was remaining part of the frame + that was being destroyed whenever the selector changed. It gets + ref-counted, disconnected, and destroyed correctly now. + * mkinstalldirs: automake 1.8 stopped including "mkinstalldirs", but + intltool still uses it. We'll need to keep this until intltool + fixes the bug. intltool 0.31 and earlier are all buggy. + +2004-07-09 Carl Hetherington + + * src/draw-context.cpp: remove some debugging g_prints. + +2004-07-08 MenTaLguY + + * src/interface.cpp: fixed crash on desktop context menu + + * src/desktop.h, src/desktop.cpp: + + added SPDesktop::isWithinViewport() to conveniently determine + if an item is within view + + also made isLayer() const + + * src/sp-object.h: added SPObject::hasChildren() predicate + + * src/sp-object.cpp: revert to old behavior of breaking parent + link before emitting "release" signal + + * src/selection-chemistry.cpp: rewrote sp_selection_item_next() + and sp_selection_item_prev() to work with layers + +2004-07-08 Carl Hetherington + + * src/libnrtype/FontFactory.cpp: disable printing of debug + messages. + + * src/sp-item-group.cpp: give it a snappoints method to fix + 937318. + + * src/draw-context.cpp: fix a couple of places where Shift isn't + checked before snapping. + + +2004-07-07 MenTaLguY + + * src/desktop.cpp, src/interface.cpp: remove the word "layer" + for now, and disable the layer selector when the user is not + inside a group + +2004-07-07 Kees Cook + + * src/dialogs/desktop-properties.cpp: added a few g_asserts, and + added a missing sp_signal_disconnect_by_data for the color picker, + which closes bug #975864. Stopped accidentally calling + sp_document_done from the update handler (fixes bug #986411). + * src/dialogs/dialog-events.cpp, src/helper/action.cpp: + whitespace changes, typo fixes, added a few g_asserts. + * src/selection-chemistry.cpp, src/desktop.cpp: when deleting items + from the desktop, the selection context may need to be cleared since + it may have pointers to the deleted items. To do this, I just + reselect the current tool (fixes bug #983243). + * src/dialogs/xml-tree.cpp, src/dialogs/desktop-properties.cpp: + corrected tooltips memory handling. + +2004-07-06 MenTaLguY + + * src/desktop.cpp: minor tweaks to make the existing layers + code easier to work with in its current state (particularly, + to sidestep some existing bugs that otherwise require more + UI work to fix) + +2004-07-06 Carl Hetherington + + * src/seltrans.cpp, src/sp-namedview.cpp, + src/display/bezier-utils.cpp, src/libnr/nr-types.cpp: + isnan appears to need a std:: namespace qualifier. + +2004-07-06 Ted Gould + + * src/libnr/nr-point.h, src/libnr/nr-rect.h: + + Adding in a function to round the points and rectangles. Using this + for less precise comparisons. Also, added in a function to print + each of these. + + * src/dialogs/export.cpp: + + Major revisions to do all kinds of fun stuff. The major one being + that filenames and dpi's can now be stored on selections. This + makes it so that people working on a section of a document can export + it consistently. + +2004-07-06 Peter Moulder + + * src/sp-typeset-utils.h: Greatly reduce #includes. + + * src/color-rgba.h, src/Makefile_insert, src/desktop.h: + Move ColorRGBA from desktop.h to new file color-rgba.h. + * src/desktop.cpp, src/dropper-context.cpp: #include it. + +2004-07-05 Kees Cook + + * src/dialogs/desktop-properties.cpp, src/dialogs/rdf.cpp, + src/dialogs/rdf.h: added multiline data entry items, reduced + overall width of the dialog, and created the license entry areas. + Auto-detection of license on load works now. + +2004-07-05 MenTaLguY + + * src/desktop.cpp: comitted further work which gives us a + partially-functional layers menu (not actually hooked up to + change layers yet), and it is not always updated when it needs + to be (yet). It does also fix the crash though. + + * src/desktop.cpp, src/desktop.h, src/document.cpp, + src/sp-item-group.cpp, src/sp-item-group.h: + + additional layers work; backed off on promoting siblings to + layers automatically and reintroduced "global" layer mode + +2004-07-05 Carl Hetherington + + * src/desktop.cpp: prevent crash by adding a check for + layer == NULL to SPDesktopWidget::_buildLayerStatusMenuItem. + + * src/selection-chemistry.cpp: prevent crash on copying empty + groups. + +2004-07-04 MenTaLguY + + * src/sp-object.cpp: fixed bug #979281 -- I had accidentally + reversed the sense of a test in SPObject::requestModified(), + such that CHILD_MODIFIED notifications were never being sent + + * src/widgets/sp-color-notebook.cpp: always assume colors are + 8-digit hex rrggbbaa, and zero-fill accordingly + + HAPPY NATHAN#@$?#$#@$!?!?!? + + * src/desktop.cpp, src/desktop.h, src/document.cpp, src/document.h, + src/interface.cpp, src/select-context.cpp, src/selection-chemistry.cpp, + src/sp-item-group.cpp, src/sp-item-group.h, src/widgets/widget-sizes.h: + + Added selection-changes-current-layer and other layer refinements. + Except for fixing the currently broken layer combo box on the status + bar, I think this is pretty much the last of the layerish work I'm + willing to do for 0.39 since we're in freeze now. + +2004-07-03 Kees Cook + + * src/document.cpp, src/dialogs/desktop-properties.cpp, + src/dialogs/rdf.cpp, src/dialogs/rdf.h: + Added several more RDF entities. Created entry tooltips. Set + a few RDF defaults for the document. + +2004-07-03 MenTaLguY + + * src/desktop.cpp, src/document.cpp: + + siblings of a layer now become layers too + + * src/interface.cpp: switched to command names suggested by bulia + + * src/object-hierarchy.cpp, src/object-hierarchy.h: + + bugfixes and cleanups + + * src/sp-item-group.cpp, src/sp-item-group.h, src/sp-root.cpp: + + new layerMode() and setLayerMode() methods; SPGroupMode becomes + SPGroup::LayerMode + + * src/sp-object.h: added isSiblingOf() method + + * src/sp-object.cpp: leave parent pointer in place until after + "release" handlers finish + +2004-07-02 Kees Cook + + * src/document.cpp, src/dialogs/desktop-properties.cpp, + src/dialogs/rdf.cpp, src/dialogs/rdf.h, src/xml/repr.h: + Made RDF's writable now. Handling modifications and defaults. + Mental and others will most likely kill me when they finally + read this code. + +2004-07-02 MenTaLguY + + * src/attributes.cpp, src/attributes.h, src/sp-item-group.cpp, + src/sp-item-group.h: + + Removed the "inkscape:groupmode" attribute and added note about how + the group/layer mode setting needs to be per-view, not global. + + * src/desktop.cpp, src/desktop.h, + src/object-hierarchy.cpp, src/object-hierarchy.h: + + Added notification signals for switching layers, as well as putting + groups in layer mode when they are being used as layers. + + Notably, you can now call SPDesktop::connectCurrentLayerChanged() to + connect to a SigC++ signal to be notified when the current layer + changes. + + * src/interface.cpp, src/object-ui.cpp: + + Fixed up the "Enter Group" and "Leave Group" context menu + commands a bit, and implement them both in the same places. + +2004-07-02 Carl Hetherington + + * src/desktop-snap.cpp, src/desktop-snap.h, src/snap.cpp, src/snap.h, + src/Makefile_insert src/arc-context.cpp src/draw-context.cpp + src/dyna-draw-context.cpp src/make.dep src/make.files src/make.ofiles + src/makefile.msc src/nodepath.cpp src/rect-context.cpp + src/select-context.cpp src/selection-chemistry.cpp src/seltrans.cpp + src/sp-namedview.h src/spiral-context.cpp src/star-context.cpp: + renamed desktop-snap.* to snap.* since it has nothing to do with the + desktop any more. + + * src/draw-context.cpp: Temporary hack to prevent snapping + completely failing to work when snapping to bbox points. Support + shift-disables-snap for freehand drawing. + + * src/snap.cpp, src/snap.h: Added some temporary methods to assist + with hacks elsewhere. + +2004-07-01 Kees Cook + + * src/xml/repr.h, src/xml/repr-util.h, src/dialogs/rdf.cpp: + moved "repr_lookup_name" into the repr-util collection so + that the RDF stuff doesn't need to know about SPRepr internals. + Now that I've started to grok the SPRepr stuff, this seems best. + Added "sp_repr_recursive_drop" for use in the future when I may + want to throw away an entire tree of SPRepr items (like ditching + a blank "dc:rights" section). + +2004-07-01 MenTaLguY + + * src/sp-item.cpp: fix clip path loading bug + + * src/sp-object.cpp: relax analness about object ids a little + +2004-06-30 Kees Cook + + * src/dialogs/desktop-properties.cpp, src/dialogs/rdf.h, + src/dialogs/rdf.cpp: built the various functions needed to extract + the RDF text elements from the DOM. XML in the document will now + be displayed in the entry fields. + +2004-06-28 MenTaLguY + + * src/xml/repr-action.cpp, src/xml/repr-action.h, src/xml/repr-css.cpp, + src/xml/repr-io.cpp, src/xml/repr-private.h, src/xml/repr-util.cpp, + src/xml/repr.cpp, src/xml/sp-repr-attr.h: applied peter's patch to + break out NRReprAttr + + * src/sp-object.cpp, src/sp-object.h: + + added SPObject::nearestCommonAncestor, which given another SPObject + returns the nearest common ancestor of the two SPObjects. + + * src/sp-item.cpp, src/sp-item.h: + + added SPItem::getRelativeTransform, which computes the SPItem's + transform relative to another SPObject + + * src/arc-context.cpp, src/draw-context.cpp, src/dyna-draw-context.cpp, + src/rect-context.cpp, src/spiral-context.cpp, src/star-context.cpp, + src/text-context.cpp: + + drawing tools now cope with drawing within transformed groups + (i.e. layers) + +2004-06-27 MenTaLguY + + * src/sp-object.h: remove sp_object_request_update, + sp_object_invoke_update, sp_object_invoke_modified, + sp_object_request_modified, and sp_object_invoke_write, which have been + deprecated and are now completely unused + + * src/Makefile_insert, src/desktop.cpp, src/desktop.h, + src/object-hierarchy.cpp, src/object-hierarchy.h, src/sp-object.cpp, + src/sp-object.h: + + Implemented SPDesktop::setCurrentLayer(), introducing + Inkscape::ObjectHierarchy to permit falling back to parents if + the current layer is removed. + + * src/object-ui.cpp, src/interface.cpp: really crude hack of + Sodipodi-like "enter group" and "leave group" + +2004-06-26 MenTaLguY + + * src/refcounted.h: allow reffing/unreffing const objects + + * src/arc-context.cpp, src/draw-context.cpp, src/dropper-context.cpp, + src/event-context.cpp, src/event-context.h, src/node-context.cpp, + src/rect-context.cpp, src/selcue.cpp, src/selcue.h, + src/select-context.cpp, src/select-context.h, src/seltrans.cpp, + src/seltrans.h, src/spiral-context.cpp, src/star-context.cpp, + src/text-context.cpp, src/zoom-context.cpp: + + Make SPSelTrans and SPSelCue proper C++ classes with constructors. + + * src/document.h, src/dialogs/xml-tree.cpp: removed sp_document_lookup_id + + * src/sp-object.cpp: clarify what is happening with bug #980407 -- + the clone is getting attached to the repr before the original SPObject + is. + +2004-06-26 Carl Hetherington + + * src/node-context.cpp: make sure nodepath->nodeContext is set up + when the selection changes. Fixes 936739. + +2004-06-25 MenTaLguY + + * src/display/sp-canvas.cpp: enabled win32 current item workaround on + all platforms + +2004-06-25 Kees Cook + + * src/dialogs/rdf.h, src/dialogs/rdf.cpp, src/dialogs/Makefile_insert, + src/dialogs/desktop-properties.cpp: + + Added data entry widgets for document metadata, including a rough + license selector, and debug rdf generator. Corrected whitespace, + added table for RDF entity lookup, tag, and title mapping. Added + initial loading framework. Cleaned up rdf_work_entity_t usage. + +2004-06-25 Carl Hetherington + + * src/sp-namedview.cpp: cleanups in grid snap settings. Fix a + typo. + + * src/seltrans.cpp: optional default origin for scaling. Fixes + to snap during scale. + + * src/seltrans.h: s/opposit/opposite/. Add some comments. + + * src/dialogs/display-settings.cpp: add default scale origin + option. + + * src/desktop-snap.h: changes to snap_list_scale prototype. + + * src/desktop-snap.cpp: snap_list_scale now returns whether + it snapped or not. The best scale snap is now the one that + changes the scale factor least, rather than the one that + results in the snap point being closest to where it used to be. + + * src/display/sp-canvas.cpp: fix for win32 freeze-at-border bug, + copied from SP. + + * src/knot.cpp, src/select-context.cpp: change spellings from + British to American English for translators. + +2004-06-24 rejon + + * src/verbs.cpp: I changed the reverse command to be more verbose and + explanative. + +2004-06-24 MenTaLguY + + * src/seltrans.cpp: slight change to make showing/hiding center + mark easier later on + + * configure.in, src/main.cpp, src/star-context.cpp, + src/display/bezier-utils.cpp, src/display/canvas-bpath.cpp, + src/display/nr-arena-glyphs.cpp, src/display/nr-arena-shape.cpp, + src/display/sp-ctrlline.cpp, src/libnr/nr-svp.cpp, + src/libnrtype/FontFactory.cpp, src/libnrtype/RasterFont.cpp, + src/livarot/AlphaLigne.cpp, src/livarot/BitLigne.cpp, + src/livarot/Ligne.cpp, src/livarot/PathOutline.cpp, + src/livarot/ShapeMisc.cpp, src/widgets/font-selector.cpp: + + fixes for floating-point portability issues, courtesy of + Colin Marquardt. + + * src/extensions/init.cpp: dirent.h requires inttypes.h on OS X + +2004-06-23 MenTaLguY + + * src/Makefile_insert, src/desktop.cpp, src/managed.h, + src/message-context.cpp, src/message-stack.h, src/refcounted.h, + src/selection.h, src/view.cpp: + + Changed my mind. + + Inkscape::Managed is more properly called Inkscape::Refcounted + + * src/libnrtype/Makefile_insert, src/libnrtype/codepages.h, + src/libnrtype/cp1250.cpp, src/libnrtype/cp1251.cpp, + src/libnrtype/cp1252.cpp, src/libnrtype/cp1253.cpp, + src/libnrtype/cp1254.cpp, src/libnrtype/cp1255.cpp, + src/libnrtype/cp1256.cpp, src/libnrtype/cp1257.cpp, + src/libnrtype/cp1258.cpp, src/libnrtype/cp874.cpp, + src/libnrtype/cp932.cpp, src/libnrtype/cp936.cpp, + src/libnrtype/cp949.cpp, src/libnrtype/cp950.cpp: + + removed unused Win32 codepage crap + +2004-06-23 Carl Hetherington + + * src/inkscape.cpp: Don't connect to SIGBUS on Win32, as + it doesn't seem to exist. Add Emacs mode line. + Declaration-to-first-use and coding style cleanups. + + * src/desktop-snap.h: a few double -> NR::Coord fixes. + + * src/nodepath.cpp: turn off snapping when Shift is held down. + Some minor cleanups. + + * src/dialogs/display-settings.cpp: remove my rather dubious + move_with_grid option. + + * src/select-context.cpp: rationalise grid modifiers; now Shift + disables snap and Alt snaps movement to the grid. + +2004-06-23 Peter Moulder + + * share/extensions/dia2svg.sh: Fix bashism and insecure tempfile usage. + +2004-06-23 Ted Gould + + * share/extensions/dropshadow.inkmod, share/extensions/roundhole.inkmod, + src/extension/system.cpp: + + Setting it up so that poorly formed inkmod files generate actual GTK + warnings so that they can be easily hidden. Also, fixing these two inkmod + files so that they don't generate the above mentioned warnings. + +2004-06-22 Kees Cook + + * src/inkscape.cpp: added SIGBUS and SIGABRT handling. + +2004-06-22 John Cliff + + * src/object-edit.cpp: Added knots for manipulation of pattern fills. + * src/sp-shape.cpp, src/sp-shape.h: Added sp_shape_set_pattern to + explictly set the transform rather than multiplying like adjust. + + +2004-06-22 Carl Hetherington + + * src/sp-shape.cpp: add sp_shape_snappoints. + + * src/desktop-snap.cpp: minor cleanups. Added a comment. + + * src/sp-text.cpp: removed an old comment. + + * src/sp-ellipse.cpp: fix snappoints method now that the parent + class method has changed. + + * src/sp-rect.cpp: snappoints method is not required as it's now + handled by SPShape. + + * src/sp-image.cpp: use SPItem's snappoints method. + + * src/file.cpp: fix another call to g_file_test with a + possibly-NULL parameter. Fixes #977413. + +2004-06-21 Carl Hetherington + + * src/file.cpp: don't call g_file_test with a NULL path. Fixes + #976703. + + * src/desktop-snap.cpp: default to snapping to bounding boxes when + snapping is first enabled. Rework in terms of SPNamedView rather + than SPDesktop. + + * src/desktop-snap.h: rework in terms of SPNamedView rather than + SPDesktop. + + * src/arc-context.cpp, src/draw-context.cpp, + src/dyna-draw-context.cpp, src/nodepath.cpp src/rect-context.cpp, + src/select-context.cpp, src/selection-chemistry.cpp, + src/seltrans.cpp, src/sp-namedview.cpp, src/spiral-context.cpp, + src/star-context.cpp: Adapt for changes to snap code naming. + + * src/seltrans.cpp: cleanups to sp_sel_trans_skew_request and + sp_sel_trans_scale_request. + +2004-06-20 Ted Gould + + * share/extensions/ai_input.inkmod, share/extensions/ai_output.inkmod, + share/extensions/dia.inkmod, share/extensions/dropshadow.inkmod, + share/extensions/epsi_output.inkmod, share/extensions/roundhole.inkmod, + share/extensions/svgz_input.inkmod, share/extensions/svgz_output.inkmod, + share/extensions/txt2svg.inkmod, src/extension/extension.h, + src/extension/system.cpp, src/extension/implementation/script.cpp, + src/extension/internal/eps-out.cpp, + src/extension/internal/gdkpixbuf-input.cpp, + src/extension/internal/gnome.cpp, src/extension/internal/ps-out.cpp, + src/extension/internal/ps.cpp, src/extension/internal/svg.cpp, + src/extension/internal/win32.cpp: + + Changing the naming of the extensions to be more Java style naming to + allow for more extension in the future. + +2004-06-21 Peter Moulder + + * src/extension/internal/ps.cpp (PrintPS): Initialize _stream to + NULL (fixes segfaults when exporting to an unopenable file), and + initialize _bitmap to false instead of random. + +2004-06-20 MenTaLguY + + * src/desktop.cpp, src/managed.h, src/message-context.h, + src/message-stack.h, src/message.h, src/view.cpp: + + Document classes, and change Managed to have an initial refcount + of one at creation. + +2004-06-20 Peter Moulder + + * src/libnrtype/FontFactory.cpp, src/libnrtype/FontInstance.cpp, + src/libnrtype/font-instance.h: If both WIN32 and WITH_XFT are + defined, then use just the WITH_XFT code. (I don't know if it's + possible for both to be defined, but we might as well document + that the existing code doesn't handle both being defined, AFAICT.) + + * src/libnrtype/FontFactory.cpp (ink_strstr): Document brokenness. + (is_regular, is_nonbold, is_italic, etc.): Mark as static. + + * src/Makefile.am (EXTRA_DIST): Remove reference to deleted files + libnrtype/nr-type-w32.cpp, libnrtype/nr-type-w32.h, + libnrtype/nr-type-xft.cpp, libnrtype/nr-type-xft.h. + + * src/config.h.win32: Define PACKAGE_TARNAME, for require-config.h. + More accurate mathematical constants (20 decimal places instead of 3). + +2004-06-19 MenTaLguY + + * src/desktop.cpp, src/managed.h, src/rect-context.cpp, + src/rect-context.h, src/selection.h, src/view.cpp: + + SPSelection now derives from Inkscape::Managed + + * src/Makefile_insert, src/select-context.cpp, src/select-context.h, + src/selection-describer.h, src/selection-describer.cpp: + + Introduced Inkscape::SelectionDescriber to which SPSelectContext + delegates the task of displaying descriptions of the current + selection. This fixes bug #945735. + +2004-06-19 Carl Hetherington + + * src/desktop-snap.{cpp,h}: sp_desktop_dim_snap_list returns + whether or not it snapped anything. + + * src/select-context.cpp: fix snap on move behaviour (again) + + * src/widgets/dash-selector.cpp: fix off-by-one spotted by + valgrind. + +2004-06-19 Peter Moulder + + * src/extension/internal/ps.cpp (begin): Add some basic error handling. + + * src/extension/internal/ps.cpp (setup): Simplify an expression now that + _bitmap is a bool. + + * src/extension/internal/ps.h: Twiddle the order of the fields. + Replace bitfields with bool/short. + + * src/libnrtype/Makefile_insert, src/libnrtype/FontInstance.h, + src/make.files, src/make.ofiles, src/make.dep: + Remove src/libnrtype/FontInstance.h (see change below). + + * src/libnrtype/RasterFont.h, src/libnrtype/raster-glyph.h, + src/libnrtype/raster-position.h: + Move raster_glyph, raster_position from RasterFont.h to new files + raster-glyph.h, raster-position.h. + * src/libnrtype/Makefile_insert: Add the new files to SOURCES. + + * src/libnrtype/FontInstance.h, src/libnrtype/font-glyph.h, + src/libnrtype/font-instance.h, src/libnrtype/font-style.h: + Move font_glyph, font_instance, and font_style definitions from + FontInstance.h into new files font-glyph.h, font-instance.h, + font-style.h. + * src/libnrtype/Makefile_insert: Add the new files to SOURCES. + + * src/libnrtype/nrtype-forward.h: New file. + * src/libnrtype/Makefile_insert: Add it to SOURCES. + * src/libnrtype/FontFactory.h, src/libnrtype/TextWrapper.h: + #include it (replacing local declarations in some cases). + + * src/livarot/livarot-forward.h: New file. + * src/livarot/Ligne.h, src/livarot/Path.h, src/livarot/Shape.h: + #include it (replacing local declarations in some cases). + * src/livarot/Makefile_insert: Add it to SOURCES. + +2004-08-18 Ted Gould + + * src/file.cpp, src/preferences-skeleton.h: + + Adding the feature that the save and open directories are saved in the + preferences. The last one will be used. + +2004-08-18 Carl Hetherington + + * src/widgets/font-selector.cpp: uint -> guint to fix + compile errors. + + * src/desktop-snap.{cpp,h}: make snap functions aware of the + type of point they are snapping, so they can decide whether + to ignore it. + + * src/arc-context.cpp, src/rect-context.cpp, + src/spiral-context.cpp, src/star-context.cpp, + src/draw-context.cpp, src/dyna-draw-context.cpp, src/nodepath.cpp, + src/selection-chemistry.cpp, src/seltrans.cpp: + temporarily update for changes to snapping API. + + * src/sp-namedview.cpp, src/dialogs/desktop-properties.cpp: + adapt for small changes to Snapper API. + + * src/select-context.cpp: use new snapping API. + +2004-08-17 Bryce Harrington + + * nodepath.cpp path-chemistry.cpp selection-chemistry.cpp, + seltrans.cpp sp-typeset.cpp splivarot.cpp text-context.cpp, + tools-switch.cpp dialogs/find.cpp: Converting statusbar + messages from old style to new, as per + http://inkscape.org/cgi-bin/wiki.pl?StatusbarAPI + +2004-06-18 Peter Moulder + + * src/mkdep.pl: Add `by mkdep.pl' to `automatically generated' line. + + * src/dialogs/desktop-properties.cpp: + Greater conformance to CodingStyle. Add FIXME comment. + + * src/sp-namedview.cpp: Tighter scoping for iteration var. + Simplify some code by greater use of cheap sp_unit_get_by_id. + +2004-06-17 MenTaLguY + + * src/Makefile_insert, src/arc-context.cpp, src/arc-context.h, + src/desktop-events.cpp, src/desktop.cpp, src/desktop.h, + src/draw-context.cpp, src/dropper-context.cpp, src/event-context.cpp, + src/event-context.h, src/file.cpp, src/interface.cpp, src/knot.cpp, + src/managed.h, src/message-context.cpp, src/message-context.h, + src/message-stack.cpp, src/message-stack.h, src/message.h, + src/select-context.cpp, src/view.cpp, src/view.h, + src/libnrtype/FontFactory.cpp, src/libnrtype/nr-type-primitives.h, + src/widgets/font-selector.cpp: + + New status messages primitives (statusbar bug not fixed yet though). + +2004-06-17 Carl Hetherington + + * src/helper/stock-items.cpp: fix a compiler warning. Minor + coding style cleanups. + + * src/arc-context.cpp, src/desktop-snap.cpp, src-desktop-snap.h, + src/rect-context.cpp, src/spiral-context.cpp, + src/star-context.cpp: Replace desktop.h include with forward + references in desktop-snap.h, and add desktop.h includes in + files which require them. + + * src/widgets/spw-utilities.cpp, src/widgets/spw-utilities.h: + add spw_vbox_checkbutton. + + * src/attributes.cpp, src/attributes.h, src/sp-namedview.cpp, + src/sp-namedview.h, src/desktop-snap.cpp, src/desktop-snap.h, + src/desktop.cpp, src/desktop.h, + src/dialogs/desktop-properties.cpp, src/seltrans.cpp, + src/seltrans.h, src/selection.cpp, src/selection.h, + src/select-context.cpp, src/selection-chemistry.cpp: + + Start of new and hopefully improved snapping code. + +2004-06-17 Peter Moulder + + * src/helper/units.h, src/helper/units.cpp: + (sp_unit_get_by_id): new function. + (sp_convert_distance_full): Change arguments & return value. + Call g_log if no conversion possible. + Callers updated. + (sp_unit_get_default, sp_unit_get_by_name): Remove unused functions. + sp_units: Less rounding error in unittobase. + +2004-06-16 Carl Hetherington + + * src/sp-item.h: added a comment. + +2004-06-15 Ted Gould + + * share/extensions/ai_input.inkmod: + Removing the command-line argument to specify line endings. + + * src/print.cpp, src/print.h, src/sp-text.cpp, + src/extension/extension.cpp, src/extension/extension.h, + src/extension/implementation/implementation.cpp, + src/extension/implementation/implementation.h, + src/extension/internal/ps.cpp, src/extension/internal/ps.h: + + Changing it so that the text to vector is its own function. This way it + can be used as a parameter in Postscript, but then can be easily used for + drivers which only support vector drawing. + +2004-06-16 Peter Moulder + + * src/select-toolbar.cpp: Cleanups and preparation for px units. + + * src/helper/units.h, src/helper/units.cpp: + Add reference version of sp_points_get_units, sp_units_get_points. + Implement as simple multiplication instead of sp_convert_distance. + (sp_units_table_sane): New function. + * src/helper/units-test.cpp: Test sp_units_table_sane. + + * src/sp-object-repr.cpp: Move some declarations to first use. + * src/sp-object-repr.h, src/sp-object-repr.cpp (sp_object_type_register): + Change return type to void. + + * src/sp-item.cpp (sp_item_repr_compare_position): + Reimplement as shallow wrapper around sp_repr_compare_position. + + * src/helper/units.h, src/helper/units.cpp: + SPUnitId: new enum, to allow replacing string lookups. + Get rid of handling for unused SP_UNIT_USERSPACE. + Remove unused SPUnit.version field. + + * src/helper/units-test.cpp (test_bases): Test sp_unit_get_identity. + + * src/helper/Makefile_insert (helper_units_test_LDADD): Fix the previous + commit: -lglib-2.0 instead of -lglib. + +2004-06-15 Peter Moulder + + * src/Makefile.am, src/helper/Makefile_insert, + src/helper/units-test.cpp: + New unit test file units-test.cpp. + + * src/select-toolbar.cpp: Greater conformance to CodingStyle. + +2004-06-14 Carl Hetherington + + * src/libnrtype/TextWrapper.cpp: Fix what looks like an off-by-one. + + * ChangeLog, src/prefs-utils.cpp: + Fix bracketing typo that causes an array to be overrun. + +2004-06-14 Peter Moulder + + * src/sp-path.cpp: Move some declarations to first use. + +2004-06-13 Kees Cook + + * src/xml/repr.h, src/xml/repr-utils.cpp: adding additional RDF URIs + to the default namespace prefix list. + +2004-06-13 MenTaLguY + + * src/arc-context.cpp, src/desktop.cpp, src/desktop.h, src/document.cpp, + src/document.h, src/draw-context.cpp, src/dyna-draw-context.cpp, + src/file.cpp, src/gradient-chemistry.cpp, src/interface.cpp, + src/rect-context.cpp, src/selection-chemistry.cpp, src/sp-object.cpp, + src/sp-object.h, src/spiral-context.cpp, src/splivarot.cpp, + src/star-context.cpp, src/svg-view.h, src/text-context.cpp, + src/extension/internal/gdkpixbuf-input.cpp: + + added SPDesktop::currentRoot() and SPDesktop::currentLayer(), which + report the current "view" root and current "editing" layer, + respectively; I've also added SPObject::appendReprChild(). + + Between the two of them, they replace sp_document_add_repr, which + has been removed. Generally to add a repr to a document, you would + now use either: + + SP_DOCUMENT_DEFS(document)->appendReprChild(repr); + + or: + + desktop->currentLayer()->appendReprChild(repr); + +2004-06-13 Peter Moulder + + * src/sp-clippath.h, src/sp-gradient.h, src/sp-marker.h, src/sp-mask.h, +src/sp-pattern.h: + Explicitly mark _acceptObject as virtual. + (Already declared as virtual in base class.) + + * src/file.cpp, src/main.cpp: Greater conformance to CodingStyle. + + * src/node-context.h, src/selcue.h, src/sp-pattern.h, + src/widgets/sp-color-wheel-selector.h: + Add missing includes as found by src/check-header-compile. + + * src/Makefile_insert: + * src/sp-use-reference.cpp: + * src/sp-use-reference.h: + * src/sp-use.cpp: + * src/sp-use.h: + Move SPUseReference from sp-use.h to new files sp-use-reference.h, + sp-use-reference.cpp. + + * src/sp-use.h (_acceptObject): Fix can't-use-ancestor check. + + * src/uri-references.h (getOwner): Fix copy&paste bug. + +2004-06-11 MenTaLguY + + * src/sp-object.h, src/sp-object.cpp: + + migrated several SPObject methods to C++ methods: + + sp_object_invoke_write -> SPObject::updateRepr + sp_object_request_update -> SPObject::requestDisplayUpdate + sp_object_invoke_update -> SPObject::updateDisplay + sp_object_request_modified -> SPObject::requestModified + sp_object_invoke_modified -> SPObject::emitModified + + (leaving deprecated wrappers in place for now) + + * src/document.cpp, src/object-edit.cpp, src/sp-clippath.cpp, + src/sp-defs.cpp, src/sp-ellipse.cpp, src/sp-image.cpp, + src/sp-item-group.cpp, src/sp-item.cpp, src/sp-line.cpp, + src/sp-marker.cpp, src/sp-mask.cpp, src/sp-offset.cpp, + src/sp-pattern.cpp, src/sp-rect.cpp, src/sp-root.cpp, + src/sp-shape.cpp, src/sp-spiral.cpp, src/sp-star.cpp, + src/sp-symbol.cpp, src/sp-text.cpp, src/sp-typeset.cpp, + src/sp-use.cpp, src/dialogs/stroke-style.cpp, src/sp-path.cpp: + + transitioned to SPObject::requestDisplayUpdate and + SPObject::updateDisplay + + * src/arc-context.cpp, src/document.cpp, src/gradient-chemistry.cpp, + src/knotholder.cpp, src/main.cpp, src/rect-context.cpp, + src/sp-anchor.cpp, src/sp-clippath.cpp, src/sp-defs.cpp, + src/sp-gradient.cpp, src/sp-item-group.cpp, src/sp-item.cpp, + src/sp-mask.cpp, src/sp-namedview.cpp, src/sp-object-group.cpp, + src/sp-object.cpp, src/sp-object.h, src/sp-offset.cpp, + src/sp-pattern.cpp, src/sp-rect.cpp, src/sp-shape.cpp, + src/sp-spiral.cpp, src/sp-text.cpp, src/sp-use.cpp, + src/spiral-context.cpp, src/splivarot.cpp, src/star-context.cpp, + src/style.cpp, src/toolbox.cpp, src/dialogs/fill-style.cpp, + src/dialogs/stroke-style.cpp, src/extension/internal/svg.cpp: + + transitioned to SPObject::requestModified, SPObject::emitModified, + and SPObject::updateRepr; also reworked "minimal" version of + updateRepr. + + * src/sp-object.h: added a little documentation + + * src/document.cpp, src/document.h, src/file.cpp, + src/gradient-chemistry.cpp, src/help.cpp, src/object-ui.cpp, + src/selection-chemistry.cpp, src/selection.cpp, src/seltrans.cpp, + src/sp-clippath.cpp, src/sp-item-group.cpp, src/sp-mask.cpp, + src/sp-namedview.cpp, src/sp-object.cpp, src/sp-offset.cpp, + src/sp-pattern.cpp, src/sp-root.cpp, src/sp-text.cpp, + src/sp-typeset.cpp, src/sp-use.cpp, src/splivarot.cpp, + src/uri-references.cpp, src/dialogs/fill-style.cpp, + src/dialogs/item-properties.cpp, src/dialogs/stroke-style.cpp, + src/helper/stock-items.cpp, src/widgets/gradient-selector.cpp, + src/widgets/gradient-vector.cpp, src/widgets/icon.cpp: + + replaced sp_document_lookup_id with SPDocument::getObjectById, + and SPDocument::getObjectByRepr + + (left deprecated stub in place, but it should be unused at this point) + +2004-06-11 Ted Gould + + * src/file.cpp, src/inkscape.cpp, src/interface.cpp, src/prefs-utils.cpp, + src/prefs-utils.h: + + Moving the recent document setting and getting code into the prefs-utils + files so that they'll be with the preferences (which they really kinda + are). Then, moved the place where they are set from the removing of the + document to where the files are opened and 'save as'd. (yes, I made up a + word/contraction). + +2004-06-10 Carl Hetherington + + * src/desktop-snap.cpp, src/desktop-snap.h, + src/satisfied-guide-cns.cpp, src/satisfied-guide-cns.h, + select-context.cpp, selection.cpp, selection.h, seltrans.cpp, + seltrans.h, sp-ellipse.cpp, sp-image.cpp, + sp-item-notify-moveto.cpp, sp-item-rm-unsatisfied-cns.cpp, + sp-item-update-cns.cpp, sp-item.cpp, sp-item.h, sp-offset.cpp, + sp-rect.cpp, sp-spiral.cpp, sp-star.cpp, sp-text.cpp: + + Use a std::vector to store snap points, rather than a fixed-size + array. + +2004-06-09 Carl Hetherington + + * src/desktop-snap.cpp, src/desktop-snap.h: Coding style fixes. + Use NR::Coord rather than double where appropriate. Added some + comments. Use NR::Dim2 where appropriate. Use NR_HUGE rather + than hardcoded 1e18s. + + * src/rect-context.cpp, src/nodepath.cpp, src/arc-context.cpp: + Adapt for changes to sp_desktop_dim_snap prototype. + + * src/select-context.cpp: + Adapt for changes to sp_desktop_dim_snap_list prototype. + +2004-06-08 MenTaLguY + + * src/display/sp-canvas.h, src/livarot/DblLinked.h, + src/livarot/LivarotDefs.h, src/livarot/AVL.h, src/livarot/Shape.h, + src/livarot/ShapeUtils.h, src/livarot/Ligne.h, + src/object-edit.cpp, src/spiral-context.cpp, src/sp-shape.cpp: + + Portability fixes from Colin Marquardt . + +2004-06-08 Carl Hetherington + + * src/main.cpp: remove the call to + Extension::Internal::PrintWin32::init() entirely after Ted pointed + out that it would be called by code in src/extension/init.cpp + anyway. + +2004-06-08 Ted Gould + + * src/main.cpp: + + Added in a version command to our command line args. This fixes + enhancement request 968642. + +2004-06-07 MenTaLguY + + * src/document.cpp, src/document.h, src/document-undo.cpp, + src/sp-object.h, src/sp-object.cpp: + renamed object garbage collection routines to fit the "orphan" + terminology + +2004-06-07 Carl Hetherington + + * src/main.cpp: tentative fix for startup crash on Win32. Ensure + that Extension::Internal::PrintWin32::init() is not called until + after inkscape_application_init(). + +2004-06-07 Ted Gould + + * src/inkscape.cpp, src/main.cpp: + + Moving the initialization of the extensions into the Inkscape application + init. I have mixed feelings on this. On one hand, basically extension + init gets called directly after applicaiton init and extensions init has + nothing to do with anything else in main. On the other hand I'm not sure + that it is directly related to the structure of the application itself. + Comments are welcome. + +2004-06-06 MenTaLguY + + * src/attributes.cpp, src/attributes.h: added inkscape:collect attribute + to specify orphan collection policy (collect with parent, or always + collect) + + * src/document-undo.cpp, src/document.cpp, src/document.h: added an orphan + collection pass as part of comitting an undo step + + * src/sp-object.cpp, src/sp-object.h: + add total hrefcount for all descendants, and basic orphan collection + facilities + + * src/gradient-chemistry.cpp, src/dialogs/stroke-style.cpp, + src/extension/internal/gdkpixbuf-input.cpp: + mark automatically added gradients, patterns, and markers for orphan + collection + +2004-06-06 Bryce Harrington + + * libnrtype/nr-type-xft.cpp, libnrtype/nr-font.cpp, + libnrtype/nr-rasterfont.cpp, libnrtype/nr-type-directory.cpp, + libnrtype/nr-typeface.cpp, libnrtype/nr-type-w32.cpp, + libnrtype/nr-type-ft2.cpp, libnrtype/nr-type-pos-def.cpp, + libnrtype/nr-type-primitives.cpp: + + Documenting the routines. This adds basic code docs for + everything in libnrtype. + +2004-06-06 Ted Gould + + * src/main.cpp, src/preferences-skeleton.h, src/extension/extension.cpp: + + Making it so that the extension parameters get saved in the Inkscape + preferences. Most people will notice that their printer gets saved now. + But this does alot more than that. Added an "extensions" group to the + preferences skeleton for all these settings. All settings get saved as + "module ID"."param name". Also had to change where the extensions get + init'd in the startup to put it behind the Inkscape application so that + prerefences could be used. + +2004-06-03 Ted Gould + + * src/file.cpp, src/dialog/filedialog.cpp: + + Making the whole file dialog alot more fun. Basically, now the + first filename will always be unique on files that don't have a + filename already. And, if you've selected a different default + extension, that extension's filename extension will be placed + on the file. Also, when you change the extension to save with + in the dialog, the filename extension will change with you (assuming + that you were using filename extensions previously ofcourse). + Finally, the checkbox to autoappend extensions is no insensitive + when "Autodetect" is selected. + +2004-06-03 MenTaLguY + + * src/file.cpp, src/extension/internal/ps.cpp, + src/extension/internal/win32.cpp, src/sp-pattern.cpp, + src/dialogs/stroke-style.cpp, src/display/nr-arena-glyphs.cpp, + src/display/nr-arena-group.cpp, src/display/nr-arena-image.cpp, + src/display/nr-arena-item.cpp, src/display/nr-arena-shape.cpp, + src/widgets/icon.cpp, src/dialogs/nr-arena-item.h: + + Introduced the notion of "parent" NRGCs + +2004-06-02 bulia byak + + * src/selection.h, src/selection.cpp: + + * preferences-skeleton.h dialogs/display-settings.cpp sp-item.cpp: New +settings + for various compensations + + * sp-shape.cpp sp-shape.h sp-rect.cpp sp-path.cpp: Factored out adjustments + (stroke and pattern so far) from optimizing items into sp-shape. + + * libnr: Added distance function for a couple of points. Added expansions +for X and Y. + + * object-edit.cpp sp-rect.cpp sp-item.cpp toolbox.cpp: Made rect use +absolute + radii, added recursive compensation on item_transform. Added new knot for + rect, moved corner knots to the top right corner. Rect toolbar shows visible + rx/ry. + + * toolbox.cpp: Finally got the freeze semaphores right (prevent loops for + changes both from the repr and from toolbar UI). + + * sp-namedview.cpp: Guarding against nan in zoom, cx, cy + + * select-toolbar.cpp helper/unit-menu.cpp helper/unit-menu.h: Fix units menu +size + + * node-context.cpp: Second Esc or empty-click deselects object + + * desktop.cpp desktop.h: Restored sticky zoom + + * preferences-skeleton.h extension/internal/gdkpixbuf-input.cpp file.cpp: Do +not + group import if only one item; move its defs to our defs; select and move + under cursor the imported item/group. Optionally import bitmaps as filled + rects. + + * many -context files: Decoupled seltrans and selcue so that the latter can +be + used outside of selector; enabled optional selcue in all tools + + * many files: New set_color signals on desktop, switching the dropper to +them; + needs to be redone for style. Excise the old inkscape::color_set signal. + + * dialogs/stroke-style.cpp: Fix the "all clubs" marker preview bug. In +markers + menu, skip document markers with stockid only if the same stockid is in + markers.svg; add separator. + + * many fill and stroke files: Remove old mode selector, remove dropper +checkbox + (now always on). Remember active colorselector page. Remove redundant checks + in setting color (fixes at least one bug). Cosmetics, cleanup, b/w icons, + shortened labels, added mnemonics and tooltips, removed the drop-down modes + list. Switched color spinbuttons to 0..255 enabling 0..1 floats to be typed +as + well. + + * dialogs/find.* et al: Find dialog, command + + * selection-chemistry.cpp: Fix copying objects from different parents; fix +and + reorganize copying gradients, recurse into groups + + * dialogs/xml-tree.cpp: Removed unused desktop shutdown signal, fixes +problem + with saving window settings on exit + + * select-toolbar.cpp: Percentage unit, lock toggle, NR::Rectification + + * sp-object.cpp path-chemistry.cpp splivarot.cpp et al: Sending +_delete_signal + recursively for descendants; switched to deleteObject where appropriate to + notify clones + + * preferences-skeleton.h desktop.cpp desktop.h interface.cpp: Window layout + fully configurable, commands in the View menu + + * path-chemistry.cpp: Fixed transform when combining inside group + + * preferences-skeleton.h sp-item.cpp dialogs/display-settings.cpp: Fixes in + scalestroke (coded by Carl): arbitrary depth recusion, setting stroke-width + via repr, pref in the transforms tab + + * widgets/sp-xmlview-attr-list.cpp: More robust listener + +2004-06-01 Ted Gould + + * src/extension/internal/gdkpixbuf-input.cpp: + Making it so that the lists of extensions and mimetypes are + used in the creation of the plugins. Also, free'ing everything + properly so that we don't have a memory leak. + +2004-05-30 MenTaLguY + + * src/selection.h, src/selection.cpp: + rework SPSelection to be SPObject- rather than SPItem- oriented; + this will be needed later for the layers/document tree dialog + (and could prove useful for the XML editor later too) + + * src/sp-item.h: make SPItem a proper C++ subclass of SPObject + + * src/dialogs/item-properties.cpp: + correct overly intimate knowledge of SPObject (use SP_OBJECT_ID rather + than directly accessing the SPObject::id member) + +2004-05-27 Kees Cook + + * src/extension/internal/ps.h, src/extension/internal/ps.cpp: + Hopefully fixed the locale problems in the PS output generator. + * src/sp-offset.cpp, src/display/bezier-utils-test.cpp, + src/display/nr-arena-item.cpp, src/libnr/nr-svp-render.cpp, + src/libnr/testnr.cpp, src/livarot/AlphaLigne.cpp, + src/livarot/Ligne.cpp, src/livarot/Path.cpp, + src/livarot/PathCutting.cpp, src/livarot/Shape.cpp, + src/livarot/ShapeDraw.cpp, src/livarot/ShapeSweep.cpp, + src/svg/svg-affine.cpp: added comments and notes to all remaining + "printf"ish calls that have %g or %f in them. Most are just debug + output, etc. Hopefully we are actually free of locale bugs! :) + * src/desktop.h, src/desktop.cpp: desktop's knowledge of + fullscreen-ness doesn't depend on having the ability to DO it. Other + functions already test "is_fullscreen" to alter their behavior. + +2004-05-23 Peter Moulder + + * src/extension/system.h, src/extension/system.cpp (build_from_file): + Remove unused second argument. Callers updated. + * src/extension/system.cpp (build_from_reprdoc): + Just one call to sp_repr_name per child. + * src/extension/system.h, src/extension/system.cpp: + Cleanup: greater conformance to CodingStyle. + +2004-05-23 MenTaLguY + + * src/libnrtype/Makefile_insert, src/libnrtype/nr-type-gnome.cpp, + src/libnrtype/nr-type-gnome.h, src/libnrtype/nr-type-dictionary: + + removed gnome-print libnrtype backend + +2004-05-20 Peter Moulder + + * src/xml/repr.h, src/xml/repr-util.cpp: + Remove unused function sp_repr_set_position_relative. + + * src/xml/repr-util.cpp (sp_repr_compare_position, sp_repr_position): + Minor cleanups. + +2004-05-19 Peter Moulder + + * src/sp-use.cpp: Cleanup: greater conformance to CodingStyle. + + * src/sp-item-group.cpp (sp_item_group_ungroup): Fix bug #956334: + ungrouping was reversing the order of the group members. + + * src/xml/repr-get-children.h, src/xml/repr-get-children.cpp: New files. + * src/xml/Makefile_insert (xml_libspxml_a_SOURCES): Add the new files. + + * src/xml/repr-private.h, src/xml/repr.cpp (sp_repr_nth_child): + Remove this unused function. + + * src/xml/repr.h, src/xml/repr.cpp (sp_repr_parent): + Mark pointer as not written through (const). + +2004-05-18 Peter Moulder + + * src/xml/repr.cpp: Cleanup: greater conformance to CodingStyle. + + * src/Makefile_insert: Add missing dependencies on inkscape_version.h. + * src/display/Makefile_insert: Adapt dependency object names for + `subdir-objects' automake option. + * src/helper/Makefile_insert: Adapt dependency object names for + lack of libspchelp-specific CPPFLAGS. + +2004-05-17 Carl Hetherington + + * src/libnrtype/nr-type-w32.cpp: Tentative fix for + build problems on Win32. + + * src/extension/internal/svg.cpp: Coding style cleanups. + +2004-05-17 Peter Moulder + + * src/sp-item.h, src/sp-item.cpp: Remove unused + distance-conversion functions sp_item_distance_to_svg_bbox, + sp_item_distance_to_svg_viewport. + + * src/sp-item.cpp: Cleanup: greater conformance to CodingStyle. + + * acinclude.m4: Remove. + +2004-05-16 Carl Hetherington + + * src/extension/internal/svg.cpp: + Throw an exception if sp_repr_save_file fails. This should close + bug 948921. + +2004-05-16 Peter Moulder + + * src/check-header-compile.in: New script. + * configure.in: Add it to list of files for substitution. + + * src/star-context.cpp: Minor cleanups, and use g_strdup_printf instead + of fixed-size buffer for translated string. + + * src/selection-chemistry.cpp: Use NR::Rect bounds() method instead of + old bounds(NRRect*). + + * src/document.cpp (sp_document_create): + * src/preferences-skeleton.h: + Use INKSCAPE_VERSION from inkscape_version.h instead of VERSION. + + * src/libnr/nr-rotate-test.cpp: Use new rotate_equalp function. + + * src/libnr/nr-translate-ops.h (operator-): New function. + + * src/select-context.cpp: + * src/selection-chemistry.cpp: + * src/xml/repr.h: + * src/sp-defs.h: + Cleanup: greater conformance to CodingStyle. + + * src/libnr/nr-macros.h: Don't #include nr-matrix.h, nr-rect.h. + + * src/arc-context.h, src/desktop-affine.h, src/dir-util.h, + src/draw-context.h, src/dyna-draw-context.h, src/help.h, + src/knotholder.h, src/prefs-utils.h, src/select-toolbar.h, + src/sp-clippath.h, src/sp-mask.h, src/sp-pattern.h, src/sp-use.h, + src/text-context.h, src/toolbox.h, src/tools-switch.h, + src/dialogs/dialog-events.h, src/dialogs/sp-attribute-widget.h, + src/display/sp-canvas.h, src/helper/gnome-utils.h, + src/helper/png-write.h, src/helper/stock-items.h, src/inkjar/jar.h, + src/libnr/nr-matrix.cpp, src/libnr/nr-point-l.h, + src/svg/stringstream.h, src/svg/svg-affine.cpp, + src/widgets/gradient-selector.h, src/widgets/paint-selector.h, + src/widgets/spinbutton-events.h, src/widgets/spw-utilities.h, + src/xml/repr-action.h: + Add missing header files as detected by check-header-compile script. + + * src/libnr/nr-rotate-fns.h, src/libnr/nr-rotate-fns.cpp: New files. + * src/libnr/nr-rotate-fns-test.cpp: New unit test. + * src/libnr/Makefile_insert, src/Makefile.am: Reference new files, + add to unit tests. + + * src/libnr/nr-rotate.h: Add Coord,Coord constructor. + + * src/libnr/nr-rotate.h, src/libnr/nr-rotate-ops.h (operator*=): + New method. + + * src/libnr/nr-point-fns.h (point_equalp): New function. + + * src/radial.h: Remove this unused header. + + * src/xml/xml-forward.h: New file. + * src/xml/Makefile_insert: Add it to xml_libspxml_a_SOURCES. + * src/xml/repr-private.h: Include it. + +2004-05-16 MenTaLguY + + * src/libnrtype/nr-type-directory.cpp, src/libnrtype/nr-type-ft2.cpp, + src/libnrtype/nr-type-ft2.h, src/libnrtype/nr-type-gnome.h, + src/libnrtype/nr-type-w32.h, src/libnrtype/nr-type-xft.cpp, + src/libnrtype/nr-typeface.h: + + transition to C++ inheritance + + * src/verbs.cpp, src/helper/action.h, src/helper/action.cpp, + src/widgets/button.cpp, src/libnr/nr-object.cpp, src/libnr/nr-object.h: + + removed barely-used "in-place construction" facility for NRObject + + * src/helper/action.h, src/helper/action.cpp, + src/display/nr-arena-glyphs.cpp, src/display/nr-arena-glyphs.h, + src/display/nr-arena-image.cpp, src/display/nr-arena-image.h, + src/display/nr-arena-item.cpp, src/display/nr-arena-shape.cpp, + src/helper/action.cpp, src/helper/action.h, src/libnr/nr-object.cpp, + src/libnr/nr-object.h, src/libnrtype/nr-type-ft2.cpp, + src/libnrtype/nr-type-gnome.cpp, src/libnrtype/nr-type-w32.cpp, + src/libnrtype/nr-typeface.cpp: + + Made NRObject "C++-compatible". All C++ features including virtual + methods and RTTI should now be available to NRObject subclasses + _provided_: + + a) there is an unbroken chain of _C++_ inheritance from the subclass + back to NRObject + + b) the NRObject-derived inheritance chain is always first in cases + of multiple inheritance (the NRObject must be first in the memory + layout) + + c) The subclass in question overrides NRObjectClass::cpp_ctor in its + own class_init function, with a pointer to a function that calls + the specific subclass' constructor (via placement new -- you will + need to #include for this to work) + + n.b. Objects of classes which do not override cpp_ctor will appear + to the C++ runtime system (RTTI and virtual dispatch, at least) as + objects of the closest ancestor class which does override it + (NRObject or NRActiveObject if nothing else). + +2004-05-15 MenTaLguY + + * src/display/nr-arena-shape.h, src/display/nr-arena-shape.cpp: + further reduced dependency on SPStyle + +2004-05-14 Peter Moulder + + * src/libnr/nr-path.cpp, src/libnr/nr-path.h (nr_path_matrix_bbox_union): + Get rid of no-longer-needed tolerance arg. Update callers. + + * src/selection.cpp, src/sp-chars.cpp, src/sp-image.cpp, + src/sp-item-group.cpp, src/sp-item.cpp, src/sp-item.h, + src/sp-marker.cpp, src/sp-root.cpp, src/sp-shape.cpp, + src/sp-symbol.cpp, src/sp-text.cpp, src/sp-typeset.cpp, + src/sp-use.cpp, src/dialogs/fill-style.cpp, + src/dialogs/stroke-style.cpp, src/display/nr-arena-shape.cpp, + src/libnr/nr-path.cpp, src/libnr/nr-path.h, + src/libnrtype/nr-font.cpp, src/libnrtype/nr-rasterfont.cpp, + src/libnrtype/nr-type-gnome.cpp, src/widgets/icon.cpp, + src/widgets/paint-selector.cpp: + Change argument from NRMatrix to NR::Matrix in SPItemClass->bbox, + sp_item_invoke_bbox, sp_item_invoke_bbox_full, + nr_path_matrix_bbox_union. Users updated. + + * src/libnr/nr-rect.h, src/libnr/nr-rect.cpp (nr_rect_union_pt): + new function. + + * src/libnr/nr-matrix-fns.h, src/libnr/nr-matrix-fns.cpp + (NR::transform): new function. + + * src/Makefile_insert: Move fixes.cpp from libinkpre.a to libinkpost.a. + * src/xml/Makefile_insert (xml_repr_action_test_LDADD): + Add libinkpost.a, for fixes.o. `make check' now works again. + + * src/sp-text.cpp (sp_text_set_transform): + Don't include SP_OBJECT_CHILD_MODIFIED_FLAG in flags for + sp_object_request_update. Addresses `critical' warning. + +2004-05-13 John Cliff + + * src/dialogs/stroke-style.cpp: Switched to using get_stock to retrieve +markers. + * src/helpers/stock-items.h, src/helpers/stock-items.cpp: created to handle +stock items. + * src/prefix.h: Added marker and gradient directorys. + +2004-05-13 Kees Cook + + * configure.in, src/main.cpp, config.h.mingw, debian/rules: + made popt a requirement instead of an option. + +2004-05-13 Carl Hetherington + + * sp-color-notebook.cpp: Fix uninitialised value spotted by valgrind. + + * stroke-style.cpp: + Fix ink_extract_marker_name returning a pointer into a free()d buffer. + +2004-05-13 Ted Gould + + * src/file.cpp: + Making the default filename _("untitled.svg") + +2004-05-12 Kees Cook + + * config.h.mingw: added g_ascii_strtod macro. + +2004-05-12 Carl Hetherington + + * src/dialogs/export.cpp: fix faulty logic with exporting of + selections, as reported by Artemio on the ML. + + * src/dialogs/desktop-properties.cpp: Fix a gtk_table size. + Make use of spw_dropdown in one place. + + * src/select-context.cpp: Remove alt-drag "slow move" mode. + Make alt-drag move without any grid snap, even if the grid + is enabled. Add a new mode, shift-drag, which preserves + objects' grid offsets rather than snapping their snappoints. + + * src/selection-chemistry.cpp: Pasted objects have the same + offset from the grid as the original, if the grid is enabled. + Also a NRRect -> NR::Rect fix thrown in for no extra charge. + + * src/dialogs/display-settings.cpp: Added option to reverse + the actions of drag and shift-drag when moving objects. + +2004-05-12 Peter Moulder + + * src/main.cpp (main): Test ENABLE_NLS instead of HAVE_NLS (which + wasn't getting defined). Restores translations on *nix systems + when inkscape translations aren't in system-wide /usr/share/locale. + +2004-05-10 Carl Hetherington + + * src/sp-item.cpp, src/dialogs/display-settings.cpp: primitive + support for preserving line widths when scaling. Thanks to Bulia + for telling me what to do :) + * src/dialogs/align.cpp: refactor some cut-and-paste code into + a separate function. Remove NRRect. Declaration-to-first-use + cleanups. + * src/dialogs/transformation.cpp, src/dialogs/fill-stype.cpp: + NRRect removal. Declaration-to-first-use cleanups. + +2004-05-09 MenTaLguY + + * src/sp-paint-server.h: SPPaintServer now uses C++ inheritance + + (bigger question -- should SPPaintServer derive from SPObject? I think + not, actually ... it's more something that should be aggregated into + the various paint-server-capable types) + + * src/display/nr-arena-shape.h, src/display/nr-arena-shape.cpp: + first steps in removing SPStyle dependency from NRArenaShape -- + add fill and stroke paint server members, and use those instead + of reading directly from an SPStyle. + +2004-05-09 Kees Cook + + * src/libnrtype/nr-type-xft.cpp: added patch 898200, hopefully this + won't break anyone. + * src/dialogs/desktop-properties.cpp: added patch 947127, along with + some orientation bugfixes, list cleanup, and logic to select the + correct menu items based on document settings. + * configure.in: default to always replace g_ascii_strtod. + +2004-05-08 Kees Cook + + * src/extension/internal/gdkpixbuf-input.cpp: skip SVG files. (open bug) + * configure.in, src/Makefile_insert, src/fixes.cpp: added replacement + for g_ascii_strtod, since it has locale-related bugs in gnome 2.0. + The upstream version is fixed, so some day, we won't need this any + more. (fixes "ugly icons" bug, and possibly the spinbutton locale bug) + * src/dyna-draw-context.cpp, src/rect-context.cpp, src/sp-namedview.cpp, + src/sp-object.cpp, src/sp-object.h, src/sp-pattern.cpp, + src/sp-polygon.cpp, src/sp-polyline.cpp, src/sp-root.cpp, + src/sp-spiral.cpp, src/sp-star.cpp, src/sp-symbol.cpp, + src/sp-text.cpp, src/spiral-context.cpp, src/star-context.cpp, + src/svg/ftos.cpp, src/svg/svg-affine.cpp, src/svg/svg-color.cpp, + src/svg/svg-length.cpp: adding "config.h", making a few extra + locale-sensitive functions use g_ascii versions. + +2004-05-08 MenTaLguY + + * src/sp-item.cpp: move "transformed" signal emission after actual + application of transform + + * src/xml/repr-action.cpp, src/xml/repr-action.h, src/xml/repr.cpp: + fix lifecycle issues with content and attribute strings + + * src/sp-object.h, src/sp-object.cpp: added SPObject::setId() + +2004-05-08 Kees Cook + + * src/verbs.cpp, src/help.cpp: localizing "about" and "keys" stuff. + * po/*.po: rebuilt for new strings. + +2004-05-08 Carl Hetherington + + * src/dialogs/desktop-properties.cpp: the usual cleanups. Also + add some sp_document_done()s in various places. + +2004-05-08 bulia byak + + * widgets/paint-selector.cpp: Tooltips, slight cosmetics + + * main.cpp: --help edit + + * sp-use.h sp-use.cpp: Redid move compensation using _transformed_signal + + * sp-item.h sp-item.cpp: Added _transformed_signal, emitted by +write_transform, + passes the difference transform relative to the old one (not the new +transform + set) + + * nodepath.cpp: Fix lagging update of the other handle for smooth nodes + + * widgets/dash-selector.cpp: (Almost) fixed display of shorter-than-0.5 +dashes + in selector; proper fixing will require manual drawing the dashes instead of + using gdk dashes + + * preferences-skeleton.h: lots of new dasharrays + + * dialogs/stroke-style.cpp: Remove repetitive code; relocation patch from + mhearn; fixed, reenabled, and automated marker previews (no need for +previews + in markers.svg) + + * share/markers/markers.svg: Cleanup, sizes, remove manual previews + + * style.cpp: Disabled warning for overflow property (we need it for markers) + + * splivarot.cpp: Fixed transform when doing boolop inside group + + * libnr/nr-path.cpp: Ported fix from sodi, fixes two bugs with endnodes of a + curve on the same hor/vert line + + * sp-namedview.cpp: Use set_default_size instead of _resize for setting +window + from namedview + + * preferences-skeleton.h dialogs/item-properties.cpp: Objects props + transientized (better late than never) + + * dialogs/display-settings.cpp: Added simplify threshold + + * sp-use.cpp: Mega-kill use on unlink + + * preferences-skeleton.h dialogs/display-settings.cpp: Orphaned clones +options + + * sp-item-group.cpp: Prevent jumps when ungrouping clone with its original + + * sp-object.cpp: Fix crash when deleting clone and its original + + * toolbox.cpp, tool contexts: Alt-x and top panel keyboard shortcuts now +work + for all tools + + * sp-use.cpp enums.h: Unlink option on self-delete + + * sp-use.cpp: Fix: disappeating clone on undoing ungrouping (_show finally +works properly) + + * splivarot.cpp: Boolops: cleanup, preserve id, parent, position, fix to +take + style from the bottom object + + * interface.cpp verbs.cpp shortcuts.cpp: Mnemonics, tooltips, shortcuts, + cleanup, autoraise removed from menu + +2004-05-07 Kees Cook + + * src/verbs.cpp: re-localizing tutorials. My goof! + * po/POTFILES.in: removed arikkei references + +2004-05-07 Carl Hetherington + + * src/desktop.cpp: make sure that a SPNamedView's modified signal + is connected to the SPDesktop even when a file is loaded into an + existing SPDesktop. Fixes problems whereby grid snap does not + work for the first file loaded in a session. Fix a && -> & typo. + + * src/sp-object.cpp: declaration-to-first-use and coding style + cleanups. + +2004-05-05 Spundun Bhatt + + * configure.in: Stole Nathan's configure hack and used it to + support gtkmm-2.4 + +2004-05-06 Ted Gould + + * src/file.cpp, src/extension/extension.cpp, src/extension/init.cpp, + src/extension/internal/Makefile_insert, + src/extension/internal/gdkpixbuf-input.cpp, + src/extension/internal/gdkpixbuf-input.h: + Changing the import functionality so that it works much more like open. + You can use any format, and it will place that file directly in the + document that you are working on. Added input extensions that cover all + of the bitmap formats that are covered with gdkpixbuf. Also, more + formats can be used using the scripting system. + +2004-05-06 Carl Hetherington + + * src/sp-line.cpp, src/sp-mask.cpp, src/sp-metrics.cpp: + declaration-to-first-use and coding style cleanups + +2004-05-05 MenTaLguY + + * src/libnrtype/nr-type-dictionary.cpp: removed 'private-fonts' + feature (we should rely on fontconfig for "custom" font stuff) + + * configure.in, src/Makefile_include, src/Makefile.am, + src/libarikkei/*: removed the now unused libarikkei + +2004-05-05 Nathan Hurst + + * src/dialogs/text-edit.cpp, configure.in: Added support for spell + checking in text dialog. + +2004-05-04 MenTaLguY + + * src/display/nr-arena-glyphs.h: fixed cut-and-paste error in + NRArenaGlyphsGroup::create() + + * src/selection.cpp, src/selection.h: fixed global "changed" propagation + +2004-05-02 MenTaLguY + + * src/file.cpp, src/print.cpp, src/sp-chars.cpp, src/sp-clippath.cpp, + src/sp-image.cpp, src/sp-item-group.cpp, src/sp-mask.cpp, + src/sp-pattern.cpp, src/sp-shape.cpp, src/sp-text.cpp, + src/sp-use.cpp, src/dialogs/stroke-style.cpp, + src/display/canvas-arena.cpp, src/display/nr-arena-glyphs.cpp, + src/display/nr-arena-glyphs.h, src/display/nr-arena-group.h, + src/display/nr-arena-image.h, src/display/nr-arena-item.cpp, + src/display/nr-arena-item.h, src/display/nr-arena-shape.h, + src/display/nr-arena.h, src/libnr/nr-object.h, src/widgets/icon.cpp: + + removed nr_arena_item_new in favor of static ::create() functions + which call NRArenaItem::init() to perform setup (i.e. setting + NRArenaItem::arena). Eventually NRArenaItem::init() and + nr_arena_item_init will merge and become NRArenaItem's constructor. + +2004-04-30 MenTaLguY + + * src/sp-use.cpp: call parent class' write methods rather than + attempting to do everything (wrongly) ourselves; among other + things, transform attributes weren't getting written + + * src/sp-object.h, src/sp-object.cpp: + + designate a "successor" object so we still perform as + expected if objects are replaced in the middle of e.g. a + bulk delete operation + + * src/sp-use.cpp: cleanups and succession logic for + deletion + + * src/widgets/sp-hwrap-box.cpp, src/widgets/sp-hwrap-box.h, + src/widgets/sp-vwrap-box.cpp, src/widgets/sp-vwrap-box.h, + src/widgets/sp-wrap-box.cpp, src/widgets/sp-wrap-box.h, + src/widgets/test-wrapbox.cpp, src/widgets/Makefile_insert: + + Removed unused (and imperfect) "wrapbox" widgets. + + * src/sp-object.h, src/sp-object.cpp, src/sp-item-group.cpp: + + Removed unused sp_object_invoke_forall and sp_object_sequence + methods. (forall might be nice to have, but we can do better + implementation-wise now that we're in C++-land) + +2004-04-30 njh + + * main.cpp: replaced gtk_init with g_type_init for console mode. + Closes 944969. + +2004-04-29 MenTaLguY + + * src/sp-image.cpp, src/sp-item.cpp, src/sp-item.h, src/sp-line.cpp, + src/sp-path.cpp, src/sp-rect.cpp, src/sp-text.cpp: + + write_transform becomes set_transform, which applies the given + transform to the object without (!) invoking a repr write + + * src/sp-star.cpp, src/svg/svg-length.h, src/svg/svg-length.cpp, + src/svg-types.h, src/svg/svg.h: + + replaced raw integers with real units enum + + * src/libnr/nr-matrix.h: + + removed dead assertion (it's always valid to retrieve the + translation component of a matrix) + + * src/selection-chemistry.cpp: + + delete items via SPItem (SPObject), not repr + + * src/sp-object.h, src/sp-object.cpp: + + added SPObject::deleteObject() and a delete notification signal; + SPObject now inherits from GObject in the C++ sense + + * src/sp-use.h: + + don't accept references to the use or its ancestors (preventing + infinite loops) + + * src/sp-use.cpp, src/sp-use.h: + + added automatic deletion when referrent is deleted + + * src/uri-reference.h: + + added URIReference::getOwner() + +2004-04-29 Carl Hetherington + + * src/extension/internal/win32.cpp: add textToPath parameter to + description in order to fix #944131. + +2004-04-28 Carl Hetherington + + * src/desktop.cpp, src/inkscape.cpp, src/sp-namedview.cpp + Part of the fix for #942149. Also fixed some compiler warnings. + + * src/display/nr-arena.cpp: Fixed an unused variable warning. + + * src/main.cpp: Fix a warning that is raised on Windows. + +2004-04-28 bulia byak + + * inkscape.cpp: Fixed prev/next desktop; numbered from 0 + + * Lots of files: Replaced all strtod() and atof() by g_ascii_strtod() + + * interface.cpp verbs.cpp: Tooltip edits + + * view.cpp view.h desktop.cpp: Signal and function to pop statusbar message + + * dialogs/dialog-events.cpp: Only set the UTILITY hint for non-modal +windows, + fixes "disappearing save as" + + * toolbox.cpp widgets/widget-sizes.h widgets/button.cpp: Got rid of button + relief, top panel made less tall + + * desktop.cpp preferences-skeleton.h dialogs/display-settings.cpp: Done away + with the sticky zoom button, now in prefs + + * path-chemistry.cpp: Preserve id= in combine/break, convert to paths; +preserve + z-order in combine/break; cleanups + + * splivarot.cpp: New selection API, Simplify preserves id= + + * select-context.cpp preferences-skeleton.h sp-item.cpp display-settings.cpp + splivarot.cpp sp-item-group.cpp sp-item-transform.cpp + sp-item-notify-moveto.cpp nodepath.cpp node-context.cpp seltrans.cpp + seltrans.h: Switched to global preservetransform, transform writing + unification (no more manual transform= setting all over the place), stamp + preserves parent, mental's new SPSelection API, pruning dead code + + * verbs.cpp interface.cpp: Eliminated Dialogs menu, added ... to dialog + commands, rearrangements, menu items display tooltips in statusbar when + selected + + * sp-item-group.cpp sp-item-group.h: Made document_done optional in ungroup +(not + done when the function is called from another function) + + * dialogs/display-settings.cpp enums.h preferences-skeleton.h sp-use.cpp + sp-use.h: Clone move compensation (3 modes), settable in prefs + + * seltrans.cpp selection-chemistry.cpp: Do not translate a clone if its +original + is in the selection + + * verbs.cpp verbs.h interface.cpp shortcuts.cpp sp-use.cpp sp-use.h + selection-chemistry.cpp selection-chemistry.h: Unlink Clone verb and menu + command (preserves id=) + + * selection-chemistry.cpp selection-chemistry.h verbs.h verbs.cpp +shortcuts.cpp + interface.cpp: Select Original verb and command, scrolls to the original + + * selection-chemistry.cpp selection-chemistry.h verbs.cpp verbs.h +interface.cpp: + Clone command + + * sp-use.h sp-use.cpp: Use URIReference; Propagate update to parent class + (SPItem) (fixes redraw on dragging a clone) + + * dropper-context.cpp dropper-context.h dialogs/display-settings.cpp: + Implemented pick modes (pick either actual color with transparency or +visible + color without transparency); added statusbar indication; color is only set +on + mouse release + + * seltrans.cpp display/sodipodi-ctrlrect.cpp: Finally the correct selection +cue + rect (fixed displacement) + +2004-04-27 Carl Hetherington + + * src/desktop.cpp: Check for there being no items when zooming to + the drawing. This fixes bug #942137. + +2004-04-26 Carl Hetherington + + * config.h.mingw, prefix.h: + INKSCAPE_VERSION moved to inkscape_version.h. + INKSCAPE_{PIXMAP,SCREENS,TUTORIALS,MARKERS}DIR moved to prefix.h + + * src/Makefile.mingw, src/inkscape_version.h.mingw + Use CVS inkscape_version.h.mingw for inkscape_version.h on Win32. + + * src/sp-use.cpp: fix a warning. + +2004-04-26 Ted Gould + + * share/extensions/ai_input.inkmod, share/extensions/dia.inkmod, + share/extensions/txt2svg.inkmod, src/extension/extension.cpp, + src/extension/internal/svg.cpp: + + Making the names of the input extensions look like the output ones. + Also, threw in a slight memory savings in removing the implementation on + deactivated extensions. + +2004-04-26 MenTaLguY + + * src/selection.cpp: migrate to new glib idle API + + * src/extension/db.cpp: can't call ->deactivated() on a NULL pointer.. + +2004-04-26 Peter Moulder + + * configure.in: Replace use of old AM_PROG_LIBTOOL macro with + AC_PROG_LIBTOOL. + +2004-04-26 Ted Gould + + * share/extensions/epsi_output.inkmod: + + Added in a check for ps2epsi + + * src/dialogs/filedialog.cpp, src/extension/db.cpp, src/extension/db.h, + src/extension/extension.cpp, src/extension/extension.h, + src/extension/init.cpp, src/extension/system.cpp: + + Implementing a 'deactivated' extension. This means that it should + still exist, but show up as insensitive in any GUI element that could use + it. The idea here is that users should know what they don't have, but + Inkscape supports. + +2004-04-26 Nathan Hurst + + * src/{libnr,libnrtype,widgets,display,helper,.}*.{h,cpp}: moved + from typedef _name name; to C++ style struct name; forward + references. + +2004-04-25 Ted Gould + + * share/extensions/ai_output.inkmod, share/extensions/dia.inkmod, + share/extensions/dropshadow.inkmod, share/extensions/epsi_output.inkmod, + share/extensions/roundhole.inkmod, share/extensions/svgz_input.inkmod, + share/extensions/svgz_output.inkmod, share/extensions/txt2svg.inkmod, + src/extension/implementation/script.cpp, + src/extension/implementation/script.h: + + Adding in support for superior checking of dependencies. Now scripts + can include a line, which will look for a binary in the path. So + something like dia input will no be loaded if there isn't dia available in + the path. + +2004-04-25 Carl Hetherington + + * src/verbs.cpp, src/rect-context.cpp, src/spiral-context.cpp, + src/event-context.cpp, src/text-context.cpp, + src/dialogs/stroke-style.cpp, src/xml-tree.cpp, src/widgets/sp-widget.cpp: + SPSelection OO-ification. + + * src/display/curve.cpp: Don't raise a critical error if a new + curve cannot be created in sp_curve_new_from_bpath(). This can + happen if a file contains a strange path, like one with only a + move in it and nothing else. This is part of the fix for bug + 934882. + + * src/sp-path.cpp: cope with sp_curve_new_from_bpath() returning + NULL in sp_path_set(). This is the other part of the fix for 934882. + + * src/path-chemistry.cpp, src/sp-offset.cpp, src/sp-ellipse.cpp, + src/display/nr-arena-glyhs.cpp: + added asserts for calls to sp_curve_new_from_bpath() which look + like they might not expect it to return NULL. + + * src/desktop.h: add a comment about how SPDesktop::selection + should never generally be NULL. + + * src/desktop-handles.cpp: ensure that sp_desktop_selection never + returns NULL, so that we don't have to check for this eventuality + elsewhere. + + * src/arc-context.cpp, src/seltrans.cpp, src/desktop.cpp: be less defensive +about + SPDesktop::selection being NULL. + + * src/path-chemistry.cpp, src/select-context.cpp, + src/selection-chemistry.cpp, src/star-context.cpp, + src/dialogs/align.cpp, src/dialogs/item-properties.cpp, +src/dialogs/text-edit.cpp: + SPSelection OO-ification. Also some coding style and + declaration-to-first-use cleanups. + + * src/toolbox.cpp: SPSelection OO-ification. Various cleanups. + + * src/selection.h: remove deprecated access functions. + + * src/dialogs/fill-style.cpp: declaration-to-first-use cleanups. + + * src/selection.cpp: add vim and Emacs mode blocks. + + * src/object-ui.cpp: very minor coding style fix. + +2004-04-24 MenTaLguY + + * src/arc-context.cpp, src/dyna-draw-context.cpp, src/object-ui.cpp, + src/path-chemistry.cpp, src/rect-context.cpp, src/select-context.cpp, + src/select-toolbar.cpp, src/selection-chemistry.cpp, src/selection.h, + src/spiral-context.cpp, src/star-context.cpp, src/text-context.cpp, + src/verbs.cpp, src/dialogs/export.cpp, src/dialogs/fill-style.cpp, + src/dialogs/in-dt-coordsys.cpp, src/dialogs/stroke-style.cpp, + src/dialogs/transformation.cpp, src/dialogs/xml-tree.cpp: + + removed sp_selection_set_item(), sp_selection_set_repr(), + sp_selection_is_empty(), sp_selection_item_selected(), + and sp_selection_repr_selected() + +2004-04-24 Ted Gould + + * share/extensions/ill2svg.pl: + + Applying a patch made to the Sodipodi list by Tuukka Pasanen which adds in + support for text in Illustrator files. Also, I backed out the changes + which removed being able to specify the line endings. This will, by + default, force them back to mac compatible. Mac files didn't work with + those changes. + +2004-04-24 Peter Moulder + + * configure.in: Tentatively remove config.h definitions of + INKSCAPE_MARKERSDIR, INKSCAPE_PIXMAPDIR, INKSCAPE_SCREENSDIR, + INKSCAPE_TUTORIALSDIR, with the understanding that these are to be + provided by prefix.h. + * src/prefix.h: Define INKSCAPE_MARKERSDIR. + + * src/extension/extension.cpp (Extension): + * src/extension/init.cpp (check_extensions): + Address warning. + + * src/dialogs/stroke-style.cpp: #include prefix.h. + + * src/Makefile.am (EXTRA_DIST): Add */makefile.in. + + * src/libnr/Makefile_insert (libnr_libnr_a_SOURCES): + Add libnr/nr-convex-hull.h, needed by sp-canvas.cpp. + +2004-04-24 Ted Gould + + * src/Makefile_include, src/prefix.cpp: + + Removing the redefition of NULL and adding to the make system. + +2004-04-24 Ted Gould + + * src/extension/db.cpp, src/extension/db.h, src/extension/extension.cpp, + src/extension/extension.h, src/extension/init.cpp, + src/extension/internal/eps-out.cpp, src/extension/internal/eps-out.h, + src/extension/internal/ps-out.cpp, src/extension/internal/ps-out.h: + + Adding in more checks for individual extensions. All of them + should still pass though. Also, moved the extension database from + glib to STL. This allows extensions to be deleted while using the + foreach functions (which causes instability with the glib hash + table). + +2004-04-24 Peter Moulder + + * src/dialogs/Makefile_insert: + * src/display/Makefile_insert: + * src/xml/Makefile_insert: + Get rid of unneeded CPPFLAGS specification. + + * src/Makefile.am: + * src/Makefile_insert: + New generated file inkscape_version.h, to replace + -DINKSCAPE_VERSION=\"$(VERSION)\". + * src/help.cpp: #include it. + +2004-04-23 Peter Moulder + + * src/sp-polygon.cpp: + * src/splivarot.cpp: + * src/style.cpp: + Change include stringstream.h to include svg/stringstream.h. + + * src/Makefile.am, src/Makefile_insert: Change libinkscape.a use + to eliminate triple compilation of these object files. + + * src/Makefile.am: Use `subdir-objects' option. + + * src/Makefile.am: Add global INCLUDES setting. + * src/*/Makefile_insert: Get rid of now-redundant $(INKSCAPE_CFLAGS) + from *_CPPFLAGS. + + * src/*/makefile.in: `%' as a target doesn't behave as intended, + so replace with less general `clean %.a %.o' and add .SUFFIXES. + +2004-04-22 Ted Gould + + * src/draw-context.cpp, src/dropper-context.cpp, + src/dyna-draw-context.cpp, src/node-context.cpp, src/nodepath.cpp, + src/sp-ellipse.cpp, src/sp-offset.cpp, src/sp-path.cpp, + src/sp-polygon.cpp, src/sp-shape.cpp, src/splivarot.cpp, src/toolbox.cpp, + src/display/curve.cpp, src/display/nr-arena-shape.cpp, + src/extension/internal/gnome.cpp, src/extension/internal/ps.cpp, + src/libnr/nr-path.cpp, src/libnr/nr-path.h, + src/libnrtype/nr-rasterfont.cpp, src/libnrtype/nr-type-ft2.cpp, + src/libnrtype/nr-type-gnome.cpp, src/libnrtype/nr-type-w32.cpp, + src/libnrtype/nr-typeface.cpp, src/livarot/PathCutting.cpp, + src/svg/gnome-canvas-bpath-util.cpp, src/svg/svg-path.cpp: + + Changing the ART_ enums to NR_ so that if libart is include (like if + you are building gnome-print) it doesn't conflict with the internal + definitions. + + * share/extensions/svgz_output.inkmod, src/extension/extension.cpp, + src/extension/init.cpp, src/extension/implementation/script.cpp: + + Adding in a little more checking code. Now extensions can start + deleting themseleves if they fail certain tests. More tests are + needed, along with more testing of this feature. Consider this + an 'early release' of the feature. ;) + +2004-04-22 Peter Moulder + + * src/Makefile.am: Make non-recursive. Now sources */Makefile_insert. + See HACKING or discussion on mailing list. + * autogen.sh: Bump requirement from automake-1.6 to automake-1.7. + * configure.in: Don't generate src/blah/Makefile, but do generate + src/blah/makefile. + * src/*/Makefile.am: Remove. + * src/*/makefile.in: New wrapper makefiles to allow typing `make' from + subdirectories of src. (Not used by compiles started from top-level + or from src/.) + +2004-04-21 MenTaLguY + + * src/libnrtype/nr-type-w32.h: fixed unremoved underscores + + * src/select-context.cpp, src/selection.cpp, src/selection.h, + src/seltrans.cpp, src/tools-switch.cpp, src/dialogs/align.cpp: + remove improper twiddling of desktop message line from SPSelection; + some additional work is now required in SPSelectContext to update + the message properly in all cases. + + * src/selection.h, src/selection.cpp: touched up and documented + SPSelection + + * src/uri-references.h: documentation touch-ups + +2004-04-20 Kees Cook + + * src/file.cpp, src/desktop.cpp: moved sp_file_open unselection code into + sp_desktop_change_document. Generalized Carl's fix for unref counting + since it applies in both cases. (My bad!) + +2004-04-20 MenTaLguY + + * src/text-context.cpp: merged Carl's fix for signal cleanup + + * src/selection.h: marked wrappers for old API as deprecated + +2004-04-20 Carl Hetherington + + * src/extension/internal/ps.cpp, src/extension/internal/ps.h: + Fixed some bugs in exporting images that seem to have been + introduced when the code was copied from the gimp. They caused + problems when exporting bitmap images to PS. + + * src/file.cpp: fix bug whereby the first file loaded in a session + would not have its modified status checked when closed. Hence if + you modified the first file you loaded and then closed it, you + would not be asked to confirm the close. + + * src/preferences-skeleton.h: add \n to the end of each line to + fix bug 938368. + +2004-04-19 MenTaLguY + + * src/arc-context.cpp, src/desktop-handles.h, src/desktop.h, + src/draw-context.cpp, src/draw-context.h, src/forward.h, + src/inkscape-private.h, src/inkscape.cpp, src/node-context.cpp, + src/node-context.h, src/rect-context.cpp, src/selection-chemistry.cpp, + src/selection-chemistry.h, src/selection.cpp, src/selection.h, + src/seltrans.h, src/spiral-context.cpp, src/star-context.cpp, + src/star-context.h, src/text-context.cpp, src/dialogs/xml-tree.cpp, + src/widgets/sp-widget.h: + + finished GObject removal from SPSelection + + * src/arc-context.h, src/arc-context.cpp, src/desktop.cpp, src/desktop.h, + src/draw-context.cpp, src/draw-context.h, src/node-context.cpp, + src/node-context.h, src/rect-context.cpp, src/rect-context.h, + src/selection.cpp, src/selection.h, src/seltrans.cpp, src/seltrans.h, + src/spiral-context.cpp, src/spiral-context.h, src/text-context.cpp, + src/text-context.h, src/toolbox.cpp: + + migrated SPSelection to SigC++ signals (though it's a bit messy + right now) + +2004-04-19 Peter Moulder + + * src/dialogs/stroke-style.cpp: Cleanups: greater conformance to + CodingStyle. Moved some declarations to their first use. + +2004-04-19 Carl Hetherington + + * src/dialogs/stroke-style.cpp, libnr/nr-rect-l.cpp: + Fix a couple of compiler warnings. + + * src/dialogs/filedialog-win32.cpp: add OFN_NOCHANGEDIR to Win32 + flags in OPENFILENAME structs. This prevents the open / save + boxes from changing the current directory. Any change to the + current directory causes problems for subsequent attempts to + load icons from pixmaps. Also, fix a bug whereby the save + dialogue would sometimes not open due to being passed a filename + it didn't like. + +2004-04-19 bulia byak + + * shortcuts.cpp selection-chemistry.cpp selection-chemistry.h verbs.cpp +verbs.h + interface.cpp: Clone command (Edit menu, Shift+Ctrl+N) + + * sp-use.cpp: Update propagated to parent class (SPItem), misc fixes + + * sp-polygon.cpp: Fix for points= updating by adding set_shape call into +_write + (bug 910142) + + * text-context.cpp: Do not create text object unless a printable key was + pressed; fixes 934280 + + * widgets/dash-selector.cpp dialogs/stroke-style.cpp: Removed marker +buttons, + fixed g_free crash in marker menus, added tooltips, added stroke-miterlimit + spinbutton + + * splivarot.cpp: Outline handles multiple objects; All commands use correct + stroke_miterlimit + + * splivarot.cpp sp-offset.cpp: Fix for 932642 + + * helper/sodipodi-ctrlrect.cpp: Simplify and fix dashes and offsets + + * widgets/gradient-selector.cpp: Tooltip edits + + * verbs.cpp verbs.h interface.cpp...: Remove tool options + + * seltrans.cpp: Pivot marker made inverse + + * toolbox.cpp: More defocusing + + * *-context.cpp: Eliminated config widgets from all tools + + * toolbox.cpp sp-ellipse.cpp: Ellipse fixes, tooltips + + * verbs.cpp: Options -> Preferences + + * dialogs/display-settings.cpp: An options dialog, completely new; selector + widget grafted here + + * preferences-skeleton.h node-context.cpp select-context.cpp: scaling uses + defaultscale + + * dialogs/display-settings.cpp display/nr-arena-image.cpp: Make oversample + saveable + + * toolbox.cpp: Aux toolbar for calligraphic + + * preferences-skeleton.h: fill-opacity:1 for calligraphic + + * select-context.cpp seltrans.cpp seltrans.cpp: Patch to enable box and none + options for per-object selection cue + + * main.cpp: Removed C-locale setting, not needed anymore; temporary switch +of + gettext encoding for console output + + * inkscape.cpp: Memory fix from sodi + + * right-click finishes pen (patch by Carl) draw-context.cpp + +2004-04-19 Carl Hetherington + + * src/livarot/ShapeRaster.cpp + Fix an unitialised value error that was spotted by valgrind. + +2004-04-18 MenTaLguY + + * src/selection.cpp, src/selection.h, src/selection-chemistry.cpp, + src/seltrans.cpp, src/nodepath.cpp: + made all SPSelection members private, and changed all methods into + real C++ methods (with temporary inline wrappers for the old C + pseudo-methods) + +2004-04-18 Carl Hetherington + + * src/print.cpp, src/print.h, src/sp-text.cpp + src/extension/extension.cpp src/extension/extension.h, + src/extension/implementation/implementation.cpp, + src/extension/implementation/implementation.h, + src/extension/internal/eps-out.cpp, src/extension/internal/eps-out.h, + src/extension/internal/ps.cpp, src/extension/internal/ps.h, + Add very basic feature to allow PS text to be exported as real + text, rather than being converted to paths first. Needs some + work, mostly on font handling. + + * src/seltrans.cpp: Slightly improve placement of the bounding + box selection cue. + + * src/sp-shape.cpp: various marker-related cleanups, mostly factoring out + common code into functions. + +2004-04-17 MenTaLguY + * src/inkscape.cpp, src/node-context.cpp, src/selection-chemistry.cpp, + src/selection.cpp, src/selection.h, src/seltrans.cpp, src/sp-gradient.cpp, + src/sp-item.cpp, src/sp-offset.cpp, src/dialogs/transformation.cpp, + src/libnr/nr-rect.cpp, src/libnr/nr-rect.h: + Cleaned up NR::Rect API and made SPSelection's desktop pointer private. + + * src/display/sp-canvas.cpp, src/libnr/nr-convex-hull.h, + src/libnr/nr-rect.h: + + First use of NR::ConvexHull (for propagating canvas bounding boxes) + +2004-04-17 Kees Cook + + * share/icons/icons.svg, src/verbs.cpp: made last three ugly menu icons. + +2004-04-17 Nathan Hurst + + * configure.in src/draw-context.cpp src/dropper-context.cpp + src/dyna-draw-context.cpp src/nodepath.cpp src/nodepath.h + src/path-chemistry.cpp src/sp-chars.cpp src/sp-ellipse.cpp + src/sp-offset.cpp src/sp-path.cpp src/sp-polygon.cpp + src/sp-shape.cpp src/sp-text.cpp src/splivarot.cpp src/style.cpp + src/style.h src/dialogs/fill-style.cpp + src/dialogs/object-properties.cpp src/dialogs/stroke-style.cpp + src/display/canvas-bpath.cpp src/display/canvas-bpath.h + src/display/canvas-grid.h src/display/curve.cpp + src/display/curve.h src/display/nr-arena-glyphs.cpp + src/display/nr-arena-glyphs.h src/display/nr-arena-shape.cpp + src/display/sodipodi-ctrl.cpp src/display/sodipodi-ctrl.h + src/display/sodipodi-ctrlrect.h src/display/sp-canvas-util.cpp + src/display/sp-canvas-util.h src/display/sp-canvas.cpp + src/display/sp-canvas.h src/display/sp-ctrlline.cpp + src/extension/internal/ps.cpp src/extension/internal/ps.h + src/libnr/Makefile.am src/libnr/libnr.def src/libnr/nr-path.cpp + src/libnr/nr-path.h src/libnr/nr-svp-private.h + src/libnr/nr-svp-render.cpp src/libnr/nr-svp-render.h + src/libnr/nr-svp.cpp src/libnr/nr-svp.h + src/libnrtype/nr-rasterfont.cpp src/libnrtype/nr-type-ft2.cpp + src/libnrtype/nr-type-gnome.cpp src/libnrtype/nr-type-w32.cpp + src/libnrtype/nr-typeface.cpp src/livarot/PathCutting.cpp + src/svg/gnome-canvas-bpath-util.cpp + src/svg/gnome-canvas-bpath-util.h src/svg/svg-path.cpp + src/svg/svg.h: removed libart. + + * src/libnr/nr-svp-uncross.cpp src/libnr/nr-svp-uncross.h: deleted + uncross and SVL routines. + + +2004-04-15 Carl Hetherington + + * src/make.exclude, src/make.dep, src/make.files, src/make.ofiles: + Various fixes to the Win32 build following rearrangement of some + source files and cleanups to libnr. + + * src/sp-text.cpp: remove an unused variable. + + * src/display/sodipodi-ctrlrect.cpp: removed two unused variables. + +2004-04-16 MenTaLguY + + * src/selection.cpp, src/selection.h, src/forward.h: initial + C++ification of SPSelection class + +2004-04-15 Kees Cook + + * debian/control, debian/changes: dropping (currently) unused + dependancies. Added "0.39cvs" tag. + +2004-04-15 Carl Hetherington + + * src/seltrans.cpp, src/helper/sodipodi-ctrlrect.cpp, + src/helper/sodipodi-ctrlrect.h: + Use black, dashed bounding boxes for indicating itemselection, + rather than red, solid boxes (as suggested by Bulia). + + * src/desktop.cpp: + Small fix for the problem whereby the first file loaded in an + Inkscape session will not have its grid set up properly. This was + my patch #935013. + + * src/dialogs/filedialog-win32.cpp: + Use the extension system to build the list of allowable file types + for save. This means that save as PS and EPS work properly. + + * src/streams-zlib.cpp, src/livarot/PathConversion.cpp, + src/livarot/PathCutting.cpp, src/livarot/PathSimplify.cpp, + src/livarot/PathStroke.cpp, src/livarot/Shape.cpp, + src/livarot/ShapeMisc.cpp, src/display/nr-arena-glyphs.cpp, + src/helper/sodipodi-ctrlrect.cpp, src/helper/sp-canvas.cpp, + src/extension/internal/win32.cpp: + Fix compiler warnings, mostly about unused variables. + + * src/helper/sp-canvas-util.cpp: + Fix what I and someone else considered to be an obvious typo. The + function in question isn't used, however, so it's a bit difficult + to test. + + * src/libnrtype/nr-rasterfont.cpp: + Fix a warning wrt a cast from NR::Matrix to NRMatrix. + + * src/sp-shape.cpp: + Fix bug #935758. + + +2004-04-14 Ted Gould + + * src/file.cpp, dialogs/filedialog.cpp: + Making it so that the filename will get placed in the save as dialog + if there is a name for the file. Otherwise the last save directory + is used (properly now) + +2004-04-15 MenTaLguY + + * most files in src/: removed many old "compatable" struct typedefs + + * src/libarikkei/arikkei-dict.cpp, src/libarikkei/arikkei-dict.h: + removed unused arikkei files + + * configure.in: added gtkmm dependency + +2004-04-14 Kees Cook + + * src/helper/unit-menu.cpp: Turns out I found a 2nd bug while + investigating patch 934358. I've applied this patch again, which gives + us the entire fix. + * src/draw-context.cpp: Investigated patch 934351 from cth103. Applied a + slight variation to conform to the function calling styles of that code. + * configure.in: Implemented gcc version test for >= 3.0.0 + * src/file.cpp, src/interface.cpp, share/icons/icons.svg, src/verbs.cbb: + finished "File / Revert" implementation. Found a memory leak in + "file_save". Added more sanity checking to "sp_file_revert" and more + status messages. + * src/main.cpp, src/file.h, src/file.cpp: removed redundant code, +implemented + in "sp_file_open". + +2004-04-13 Kees Cook + + * tools-version.sh: added a possible fix for BSDish tools. + * configure.in, share/patterns/Makefile.am: inkscape janitor strikes + again! This is a quick cleanup to Ted's new directories. Looks + like "patterns" got left out. + * share/clipart/.cvsignore, share/templates/.cvsignore, + share/examples/.cvsignore, share/fonts/.cvsignore, + share/gradients/.cvsignore, share/keyboards/.cvsignore, + share/palettes/.cvsignore, share/patterns/.cvsignore: + Added Makefile build-cruft to .cvsignores. + * src/helper/unit-menu.cpp: applied a variation to patch 934358 from cth103 + to fix grid unit changing bug. + * configure.in: fixed capitalization of "libpng" to avoid confusion. + * src/sp-namedview.cpp, src/document.cpp, src/document.h, src/file.cpp, + src/file.h, src/document-undo.cpp, src/interface.cpp, src/verbs.cpp, + src/verbs.h: + Newly opened files will only create new windows if the current document + is untouched. (RFE#928517) + Added support for future "File/Revert" handling. Needs + a little more support in the SPDocument structure. See notes in + "src/file.cpp", function "sp_file_revert_dialog". + +2004-04-13 Ted Gould + + * configure.in, share/Makefile.am, share/clipart/Makefile.am, + share/examples/Makefile.am, share/fonts/Makefile.am + share/gradients/Makefile.am, share/keyboards/Makefile.am + share/markers/Makefile.am, share/palettes/Makefile.am + share/screens/Makefile.am, share/templates/Makefile.am: + Making it so that the clipart and everything else gets put in + the tarball, and also get installed in the share directory. Many + of these have just 'README' files, but they now have good place- + holders for further development. + +2004-04-12 Kees Cook + + * src/dialogs/stroke-style.cpp, src/Makefile.am, src/dialogs/Makefile.am, + src/widgets/Makefile.am, configure.in: fixed up INKSCAPE_*DIR paths so CVS + will compile happily for me. This way if paths change, files will be + recompiled. The old way would let configure run again (changing the + datadir path) without forcing a recompile, which could break the + compiled paths. + +2004-04-13 John Cliff + * src/sp-shape.cpp, src/dialogs/stroke-style.cpp: + Couple of changes to marker related code, mid and end markers now point in +correct + direction, turning off start markers behaves correctly. + This follows on from changes made by me and Carl Hetherington that were +commited + yesterday to + src/inkscape-stock.cpp, src/sp-item.cpp, src/sp-marker.cpp, +src/sp-shape.cpp, + src/style.cpp, src/style.h, src/dialogs/stroke-style.cpp + to implement marker UI and fixes to the marker rendering code. + +2004-04-11 Ted Gould + + * src/extension/system.cpp, src/extension/internal/eps-out.cpp + src/extension/internal/eps-out.h: + First pass at a file save dialog with EPS output. The dialog + sets the bounding box in the file. Comments encouraged. + +2004-04-11 Ted Gould + + * src/file.cpp, src/main.cpp, src/print.cpp, src/extension/init.cpp, + src/extension/init.h, src/extension/system.cpp, src/extension/system.h, + src/extension/implementation/script.cpp, +src/extension/internal/eps-out.cpp, + src/extension/internal/gnome.cpp, src/extension/internal/ps-out.cpp, + src/extension/internal/ps.cpp, src/extension/internal/svg.cpp, + src/extension/internal/win32.cpp: + Change alot of files, but small changes. Basically just took + system.cpp and init.cpp and finally ported them to the Inkscape:: + Extension namespace. Cleaned up the code in them a bunch, it is + much easier to read now! All the other files are just referencing + these changes. + +2004-04-11 Kees Cook + + * src/verbs.h, src/verbs.cpp, src/interface.cpp, src/interface.h: replaced + the rest of the missing menu verbs: "View New", "Cleanup". Created + generic function to add icons to a given menu item (for submenu icons + mostly). + * share/icons/icons.svg: added "selection_cleanup", "selection_deselect", + "selection_select_all". Corrected "view_new" and "selection_smooth", + "dialog_toggle", "dialog_tool_options", "file_open_recent". + * src/selection-chemistry.cpp, src/selection-chemistry.h: renamed + "selection_cleanup" function. + +2004-04-11 Jon Phillip + + * Makefile.mingw share/Makefile.am src/Makefile.am + share/markers/Makefile.am share/markers/.cvsignore config.h.mingw + configure.in: + Added the proper infrastructure to get files to the right location for + markers. + + * share/tutorials/tipsandtricks.svg: Deleted the URL trick because it no + longer works or something. + +2004-04-11 Kees Cook + + * src/verbs.h, src/verbs.cpp: added verbs for the Help and Tutorials menus. + * src/interface.cpp: replaced contents of sp_ui_menu_help to use new verbs. + * src/help.h, src/help.cpp: replaced sp_help_keys with more generic + sp_help_open_screen, similar to sp_help_open_tutorial. + * share/icons/icons.svg: created really ugly "help_tutorials" and + "help_keys" icons. The "help_keys" one needs the most help. :) + +2004-04-09 Ted Gould + + * share/extensions/Makefile.am, share/extensions/epsi_output.inkmod, + share/extensions/ps2epsi.sh, src/extension/extension.cpp, + src/extension/extension.h, src/extension/init.cpp, + src/extension/implementation/implementation.cpp, + src/extension/implementation/implementation.h, + src/extension/implementation/script.cpp, + src/extension/implementation/script.h, + src/extension/internal/Makefile.am, src/extension/internal/eps-out.cpp, + src/extension/internal/eps-out.h, src/extension/internal/ps.cpp: + + Okay, these are some changes that I've had in my directory for + a little while. + + 1) adding the basics of checking extensions. This will allow + them to remove themselves based on their dependencies failing. + + 2) Adding the concepts of a 'helper extension' to scripts. This + allows them to use other extensions for handling the data, so + they don't have to deal with SVG directly - Inkscape will + build the pipeline. An example of this is the epsi output. + + 3) Adding the bounding box change provided by Carl Hetherington + to the Postscript output. The EPS output plugin sets this, so + now EPSes have smaller bounding boxes. A GUI needs to be + written for this setting. + +2004-04-08 MenTaLguY + + * configure.in, src/svg/ftos.cpp: fix for OS X build + + * src/extensions/internal.ps.cpp: crash fix + +2004-04-07 MenTaLguY + + * src/xml/repr.cpp: adjusted the advertising comment in the default + document template (we need a real default document template, btw) + + * src/svg/ftos.cpp, src/svg/itos.cpp, src/svg/round.cpp, + src/svg/ftos.h, src/svg/stringstream.h: incorporated Bryce's number + serializing code (disabled for now, due to the impending release) + + * src/dialogs/stroke-style.cpp, src/dialogs/sp-shape.cpp: + nuked unused variables + +2004-04-07 bulia byak + + * icons.svg: Alignment fix + + * src/select-toolbar.cpp: Swapped rotate buttons + + * share/tutorials/: Cleanup, added Russian translation of basic + + * extension/extension.cpp extension/system.cpp extension/internal/ps.cpp + extension/implementation/script/cpp: Fixes to make non-ascii filenames work +again + + * src/verbs.cpp: Remove xpm icon that causes trouble on win32 + + * share/examples/: new gradient.svg, tiger.svgz, cleanup + + * src/widgets/gradient-vector.cpp: Crash fix: loading new gradient into the + editor does not completely reset it + + * share/icons/icons.svg: New dialog icons, draw tool icons, changed colors + + * src/dialogs/align.cpp src/helper/bezier-utils.cpp: remove pjrm's debug +output + + * share/tutorials/: SVG cleanup: remove unused font properties, wrong radius + paths in ellipses (leftovers from old versions). Expanded & updated tips & +tricks. + + * file.cpp: Set uri on save in one place; save 'offcially' from here only + + * system.cpp system.h: Remove redundant uri-setting on open and save, add + official arg to sp_module_system_save to prevent docname/docbase changing on + temporary saves + + * many files: _() fixes, edits in labels, messages, tooltips, mnemonics + + * src/inkscape.cpp: remove redundancy in error messages for failing to load +prefs + + * share/extensions src/extension/internal: Renaming file formats to include +(*.ext) + + * src/interface.cpp src/dialogs/filedialog.cpp: Transientize, make modal + open/save dialogs, ditto for warning overwrite and make it unresizeable + + * src/dialogs/xml-tree.cpp: Do not deselect item on canvas when a +non-selectable + thing is highlighted in xml editor + + * src/sp-guide.cpp: Guide position updated after undo + + * src/widgets/sp-xmlview-attr-list.cpp: Max length of viewable attributes + increased + + * many files: Adib's svgostringstream patches to remove printfs + + * src/selection-chemistry.cpp: Crash fix when pasting style to an object +that + has none (e.g. group) + + * src/knot.cpp: Knot dragging autoscrolls + + * src/sp-text.cpp src/text-context.cpp: Cursor movements autoscroll + + * src/desktop.h src/desktop.cpp: autoscrollspeed can be overridden in call +to + sp_desktop_scroll_to_point + + * src/text-context.cpp src/sp-text.cpp: Text cursor made inverse. Initial +cursor + after click is no longer horizontal. + + * src/helper/sp-ctrlline.cpp: Always-visible inversion for ctrlline + + * src/libnrtype/nr-type-w32.cpp: Fix stretch and variant on win32 + + * src/widgets/gradient-vector.cpp: Undo fix; new stop takes average of its + neighbors' colors; is between stops even when the last stop is selected + +2004-04-06 Ted Gould + + * src/file.cpp, src/dialogs/filedialog.cpp, src/extension/extension.cpp, + src/extension/system.cpp: + Moving code around so that the filename extension gets put on by + the extension that is saving the file. This adds a couple complications + in that the extension now needs to check for overwriting the file + and also set the document URI. Better overall, but a PITA. + +2004-04-05 njh + + * debian/rules,debian/control: applied patch from Kees Cook to remove + obsolete libraries, and to tidy things up a tad. + +2004-04-04 Ted Gould + + * src/main.cpp, src/extension/extension.cpp, src/extension/system.cpp: + Now the input autodetect will try the SVG filter if the autodetect + fails. This was done by the command line, but now it is done + everywhere. + +2004-04-04 MenTaLguY + + * src/xml/repr-io.cpp, src/xml/repr.cpp, src/xml/repr.h: + Take the full list of document node children from libxml, and + append them in the correct order. This fixes bug #929348. + + * src/xml/repr-io.cpp, src/xml/repr.cpp, src/xml/repr-private.h: + Added API for coping with comments at the root level (i.e. siblings + of the root XML node), and made corresponding changes to the repr-io + code. In theory this should be enough to preserve them upon loading, + though in practice it still doesn't appear to be working (bug #929348). + Is there some libxml thing we need to do? + +2004-04-04 Ted Gould + + * a bunch of files + Sorry, I seem to be in some delay getting e-mail. Anyway, a few + files were changed to add in a new parameter 'dataloss' Basically + this signifies that a format was used to save that may not save + the whole document and thus, a pop-up is elevated on close to signal + that you might want to 'really save' this document. + +2004-04-03 Ted Gould + + * share/extensions/svgz_input.inkmod, src/file.cpp, + src/extension/extension.cpp, src/extension/internal/svg.cpp: + Making it so that input extensions can specify the output extension + that gets used to save them. If this field isn't filled in, the value + gets set to NULL, and then the Save As dialog is used instead of + just trying to save. + +2004-04-03 Ted Gould + + * src/file.cpp, src/main.cpp, src/extension/extension.cpp, + src/extension/extension.h, src/extension/system.cpp, + src/extension/internal/svg.cpp: + Fixing the output_extension flag to not be saved in a file, but also + to be able to be specified by the input module. Also, this fixes + the commandline processing of files to make them use the extension + system. + +2004-04-02 Ted Gould + + * src/file.cpp, src/extension/db.cpp, src/extension/internal/svg.cpp: + Changing it so that SVG documents open and default to with + extension namespace. Also, autodetect is reenabled. + +2004-04-03 Peter Moulder + + * src/helper/bezier-utils.cpp (NewtonRaphsonRootFind): Fix my + previous commit. + +2004-04-02 Ted Gould + + * share/extensions/svgz_output.inkmod, src/main.cpp, src/print.cpp, + src/extension/init.cpp, src/extension/implementation/script.cpp, + src/extension/implementation/script.h, + src/extension/internal/Makefile.am, src/extension/internal/ps-out.cpp, + src/extension/internal/ps-out.h, src/extension/internal/ps.cpp: + Fixing the commandline printing. This required fixing both the + print driver to handle the newer extensions stuff. It seems + happy now. I went ahead and implemented save as postscript + while I was at it. + +2004-04-02 Peter Moulder + + * src/helper/bezier-utils.cpp (NewtonRaphsonRootFind): Ensure that the + "improved" value is never worse than the previous guess. + + * src/helper/bezier-utils.cpp: + Greater CodingStyle conformance, mainly whitespace changes. + + * src/helper/bezier-utils.cpp (sp_bezier_fit_cubic_full): + Always reparameterize between generate_bezier and calc_max_error. + Switch from discouraged alloca (see man page) to g_new, at cost of + some extra g_free calls in the code. + (reparameterize): Do in-place modification. + + * src/helper/bezier-utils-test.cpp: + Add tests for generate_bezier, sp_bezier_fit_cubic_full. + Change to a simpler test bezier. + + * src/helper/bezier-utils.cpp (sp_darray_left_tangent, + sp_darray_right_tangent): + Switch to using just the two end points for calculating the gradient. + (The old code could sometimes cause g_warning's.) + Correct the documentation of requirements. + (sp_darray_center_tangent): Similarly remove the #if'ed out code for + looking at more than two points. + +See doc/Changelog_archive.txt for older entries + +# Local Variables: +# tab-width:8 +# indent-tabs-mode:t +# End: +# vim: tabstop=4:noexpandtab:shiftwidth=4 diff --git a/HACKING.de.txt b/HACKING.de.txt new file mode 100644 index 000000000..0c3c44277 --- /dev/null +++ b/HACKING.de.txt @@ -0,0 +1,88 @@ +Abhängigkeiten +============== +grep Build-Depends debian/control, um eine Liste der (Debian)-Pakete zu +sehen, die zum Compilieren nötig sind. + +Die RPM-Unterstützung ist unvollständig. Die Datei inkscape.spec.in hat +eine partielle Liste der Abhängigkeiten: + + grep Requires inkscape.spec.in + +Momentan beschreibt die Datei nur ein Paket. Wenn Sie eine RPM-basierte +Linux-Distribution benutzen, würden Sie anderen helfen, wenn Sie die +Requires/BuildRequires Zeilen entsprechend updaten. + +Patches +======= + +Wenn Sie keinen CVS Zugang haben, benutzen Sie bitte den Patch Tracker +. + +Wiki +==== + +Lesen Sie bitte http://www.inkscape.org/cgi-bin/wiki.pl?CompilingInkscape +um mehr über Compilation zu erfahren, z.B. wo man benötigte Software +finden kann und andere Tips für Entwickler. + + +Zu Inkscape beitragen +===================== +Inkscape begrüßt jeden Ihrer Beiträge der hilft, es zu einem vollständig +SVG-unterstützenden Zeichenprogramm zu machen. + +Während viele der Entwickler am Programm selbst arbeiten, Fehler beheben +und neue Features implementieren, werden auch Ihre anderweitigen +Fähigkeiten gebraucht, um Inkscape noch mächtiger und erfolgreicher +zu machen. Sie haben wahrscheinlich schon längst eine Idee, woran Sie +gerne arbeiten würden. Wenn nicht, hier sind ein paar: + +* Picken Sie sich eine Fehlermeldung aus dem Sourceforge Bug Tracker +heraus und schicken Sie einen Patch ("diff -uNrp" or "cvs diff -up"). +* Wählen Sie eine Verbesserung und implementieren Sie sie. +* Arbeiten Sie an den Übersetzungen im po/ Verzeichnis. +* Versuchen Sie, einen neuen Fehler zu finden, und berichten Sie. +* Helfen Sie, Fragen von neuen Benutzern auf Jabber, IRC oder den +Mailinglisten zu beantworten. +* Entwerfen Sie Dokumente mit Tips oder Hilfen, nutzen Sie unseren Wiki. + + +CVS Zugang +========== +Lesen Sie bitte http://sourceforge.net/cvs/?group_id=93438 +wie man CVS nutzt oder den Quellenbaum mit einem Browser liest. + +Wir vergeben CVS Zugang an Leute, die ihr Interesse daran bewiesen +haben, den Code zu verbessern. Der Beweis ist einfach: Reichen Sie +zwei Verbesserungen ein und verlangen Sie Zugang. + + +Patch Akzeptanz +=============== +Unser Motto betreffend Veränderungen am Programm ist "Zuerst patchen, +später fragen". Anstatt eine Idee endlos zu debattieren, ermutigen wir +Leute, erst einmal den Code zu schreiben, auch als Prototyp. Das wird +dann in den Zweig der Programmänderungen eingebracht, wo es zunächst +getestet wird. Schwerwiegende und das gesamte Programm betreffende Designentscheidungen sollten natürlich vorher in der devel-Mailingliste +angesprochen werden. + + +Coding Style +============ +Bitte lesen Sie die Coding Style Guidelines +(http://www.inkscape.org/doc/coding_style.php) +Wenn Sie das Dokument nicht interessiert, halten Sie sich bitte +zumindest grob an den Stil des bereits vorhandenen Quelltexts. + + +Makefiles +========= +Das src/Makefile.am bezieht sich auf die Makefile_insert Dateien in +jedem einzelnen Directory. Im Endeffekt bleibt es dadurch eine Datei, +daher sind Definitionen von Variablen (auch INCLUDES etc.) überall +zugänglich. + +Wenn Sie daher ein eigenes Directory mit Makefile erstellen, benutzen +Sie bitte einen Prefix (zB blah_) für lokale Variable in blah/Makefile_insert +oder definieren Sie globale Variable in src/Makefile.am. Insbesondere +sind check_PROGRAMS, DISTCLEANFILES, etc. in src/Makefile.am zu finden. diff --git a/HACKING.fr.txt b/HACKING.fr.txt new file mode 100644 index 000000000..767853e5b --- /dev/null +++ b/HACKING.fr.txt @@ -0,0 +1,91 @@ +Compiler la version cvs +======================= +grep Build-Depends debian/control permet d'afficher une liste de paquets(Debian) +nécessaires à la compilation. + +inkscape.spec.in contient une liste partielle de spécifications : + + grep Requires inkscape.spec.in + +Au moment où ce texte est écrit, il n'y a qu'un paquet; si vous utilisez une +distribution basée sur des RPMs, pensez à mettre à jour les lignes +Requires/BuildRequires afin d'aider les autres utilisateurs de votre +distribution. Si vous n'avez pas d'accès en écriture au CVS, vous pouvez +soumettre un patch auprès de +. + + +Consultez http://www.inkscape.org/cgi-bin/wiki.pl?CompilingInkscape pour des +remarques plus complètes sur la compilation, comprenant des explications sur +comment trouver les paquets nécessaires pour votre distribution et des +suggestions pour les développeurs. + + +Contribuer à Inkscape +===================== +Inkscape accepte volontiers vos contributions pour aider à en faire un +programme de dessin totalement conforme à la norme SVG pour la communeauté du +logiciel libre. + +Alors que beaucoup de développeurs travaillent sur la correction de bugs et la +création de nouvelles fonctionnalités, il est important de noter que même les +non-programmeurs peuvent contribuer à la puissance et au succès d'Inkscape. +Vous avez probablement une idée d'une chose sur laquelle vous aimeriez +travailler. Sinon, voivi quelques façons d'apporter votre aide : + + * Sélectionner un bug, le corriger et envoyer un path ("diff -uNrp" ou + "cvs diff -up") + * Choisir une fonctionnalité que vous aimeriez développer et la coder + * Si vous maîtrisez une langue en plus de l'anglais, travailler sur le + fichier i18n de celle-ci dans le répertoire /po + * Trouver un nouveau bug et le rapporter + * Aider à répondre aux questions des nouveaux "Inkscapeurs" sur Jabber, IRC + ou les mailing lists + * Ecrire un article pour la promotion d'Inkscape + * Ecrire un HOWTO décrivant une astuce ou technique que vous avez trouvé + + +Accès CVS +========= +Consultez http://sourceforge.net/cvs/?group_id=93438 pour voir comment accéder +au CVS, y compris depuis un client web. +Nous donnons un accès en écriture au CVS à toute personne ayant démontré une +motivation pour aider à développer le code. Prouver votre motivation est très +simple : fournir deux contributions et demander un accès. + + +Décisions de patch +================== +Notre ligne de conduite quant aux modifications du code est "coder d'abord, +poser les questions ensuite". Quand quelqu'un a une idée, plutôt que de la +débattre sans fin, nous encourageons les gens à aller de l'avant et coder +quelquechose (même un prototypage). Ce code est ensuite incorporé dans la +branche de développement afin de l'essayer, le tester, le pousser et +l'améliorer. Nous pensons que la meilleure façon de vérifier qu'une idée est +bonne est de la tester en conditions réelles. + + +Style de codage +=============== +Veuillez consulter les recommandations de style de codage +(http://www.inkscape.org/doc/coding_style.php) si vous avez des questions +spécifiques quant au style à utiliser dans le code. Si lire ces recommandations +ne vous intéresse pas, inspirez vous du style du code environnant, de façon à +rester au moins cohérent. + + +Makefiles +========= +Les fichiers Makefiles du répertoire src sont plus ou moins fusionnés dans le +fichier src/Makefile.am qui fournit les informations nécessaires aux fichiers +Makefile_insert de chaque répertoire. + +Notez que cela ne reste logiquement qu'un fichier, donc les définitions de +variables (comme les INCLUDES etc.) sont partagées, et les variables définies +dans un Makefile_insert peuvent être utilisées dans un autre. + +An conséquence, envisagez soit d'ajouter un préfixe `blah_' au nom de toutes +les variables que vous définiriez dans blah/Makefile_insert (si cela doit +rester local pour ce Makefile_insert), ou en mettre la définition dans +src/Makefile.am. En particulier, les fichiers check_PROGRAMS, DISTCLEANFILES, +etc sont dans src/Makefile.am. \ No newline at end of file diff --git a/HACKING.it.txt b/HACKING.it.txt new file mode 100644 index 000000000..c2d67a72b --- /dev/null +++ b/HACKING.it.txt @@ -0,0 +1,83 @@ +Compilare la versione CVS +========================= +Esegui `grep Build-Depends debian/control` per avere una lista dei pacchetti (Debian) +necessari per la compilazione. + +inkscape.spec.in contiene una lista parziale dei requisiti: + + grep Requires inkscape.spec.in + +Al momento, questa lista contiene un solo pacchetto; se usi usa distribuzione +basata su RPM, sei pregato di aggiornare le linee Requires/BuildRequires in modo +da aiutare gli altri utenti della tua stessa distribuzione. Se non hai accesso in +scrittura al CVS, puoi inviare una patch al sistema di gestione delle patch +. + +Consulta http://www.inkscape.org/cgi-bin/wiki.pl?CompilingInkscape per informazioni +più generali sulla compilazione, incluso come trovare i pacchetti necessari per la +propria distribuzione e alcuni suggerimenti per gli sviluppatori. + + +Contribuire a Inkscape +======================== +Inkscape accetta volentieri i tuoi contributi per lo sviluppo +di un programma di disegno completamente compatibile con SVG +per la comunità Open Source. + +Mentre diversi sviluppatori lavorano per correggere i bug o implementare +nuove funzioni, è comunque necessario che anche i non programmatori contribuiscano +a rendere Inkscape uno strumento utile e potente. +Probabilmente tu hai già un'idea a proposito di cosa potresti occuparti. +In caso contrario, questi sono solo alcuni suggerimenti: + + * Controlla un bug, correggilo e manda una patch ("diff -uNrp" o "cvs diff -up") + * Scegli una funzione che ti piacerebbe fosse implementata e sviluppala + * Se parli un'altra lingua che non sia l'inglese, lavora sul file per l'i18n della tua + lingua disponibile nella cartella po/ + * Scopri nuovi bug e segnalali + * Rispondi a domande dei nuovi utenti su Jabber, IRC o mailing list + * Scrivi un articolo per pubblicizzare Inkscape + * Scrivi un HOWTO su qualche trucco o tecnica che trovi utile + + +Accesso CVS +========== +Consulta http://sourceforge.net/cvs/?group_id=93438 per i modi di accesso al CVS, +tra la consultazione del CVS client web. + +L'acceso in scrittura al CVS viene dato a tutti quelli che dimostrino interesse +nello sviluppo del codice. La prova è semplice: fornisci un paio di contributi e richiedi +l'accesso. + + +Implementazione delle patch +=============== +Il nostro motto per i cambiamenti del codice è "Prima sviluppa, poi parla". +Quando qualcuno ha un'idea, invece di parlarne a lungo e senza risultati, è +meglio che prosegua e sviluppi qualcosa (anche solo un prototipo). +Questo verrà incorporato nel ramo di sviluppo per essere testato, migliorato +e commentato. Lo schema è semplice: il migliore modo per giudicare un'idea è +vederla in azione. + + +Stile del codice +============ +Consulta le Linee Guida per lo Stile del codice +(http://www.inkscape.org/doc/coding_style.php) se hai delle domande specifiche +sullo stile. Se non fosse sufficiente, adeguati allo stile del codice già presente, +in modo da avere un minimo di coerenza. + +Makefile +========= +Tutti i Makefile sotto alla directory src sono grosso modo fusi in un unico src/Makefile.am +che attinge dai vari Makefile_insert delle directory. + +Esso è comunque un'unico file, per cui le definizioni delle variabili (anche di +INCLUDES ecc.) sono condivise, e le variabili definite in un +Makefile_insert possono essere usate in un altro. + +Quindi, prendi in considerazione il consiglio di aggiungere un prefisso (tipo `blah_') +al nome delle variabili definite in blah/Makefile_insert (se il loro ambito è locale), o +inserisci le definizioni in src/Makefile.am. In particolare, +controlla che check_PROGRAMS, DISTCLEANFILES, etc. siano in src/Makefile.am. + diff --git a/HACKING.txt b/HACKING.txt new file mode 100644 index 000000000..6120634e7 --- /dev/null +++ b/HACKING.txt @@ -0,0 +1,86 @@ +Compiling the CVS version +========================= +grep Build-Depends debian/control to see a list of (Debian) packages needed for +compilation. + +inkscape.spec.in has a partial list of requirements: + + grep Requires inkscape.spec.in + +At the time of writing, it contains only one package; if you use an RPM-based +distribution, then please consider updating the Requires/BuildRequires lines to +help other users of your distribution. If you don't have CVS write access, +then you can submit a patch to the patch tracker +. + + +See http://www.inkscape.org/cgi-bin/wiki.pl?CompilingInkscape for more general +remarks about compiling, including how to find some of the needed packages for +your distribution, and suggestions for developers. + + +Contributing to Inkscape +======================== +Inkscape welcomes your contributions to help turn it into a fully +SVG-compliant drawing program for the Open Source community. + +While many developers work on fixing bugs and creating new features, it +is worth strong emphasis that even non-programmers can help make +Inkscape more powerful and successful. You probably already have an idea +of something you'd like to work on. If not, here are just a few ways you +can help: + + * Pick a bug, fix it, and send in a patch ("diff -uNrp" or "cvs diff -up") + * Choose a feature you want to see developed, and make it + * If you speak a language in addition to English, work on your + language's i18n file in the po/ directory + * Find a new bug and report it + * Help answer questions for new Inkscapers on Jabber, IRC or the + mailing lists + * Write an article advocating Inkscape + * Author a HOWTO describing a trick or technique you've figured out + + +CVS Access +========== +See http://sourceforge.net/cvs/?group_id=93438 for how to access CVS, +including browsing CVS from a web client. + +We give CVS write access out to people with proven interest in helping develop +the codebase. Proving your interest is straightforward: Make two +contributions and request access. + + +Patch Decisions +=============== +Our motto for changes to the codebase is "Patch first, ask questions +later". When someone has an idea, rather than endlessly debating it, we +encourage folks to go ahead and code something up (even prototypish). +This is then incorporated into the development branch of the code for +folks to try out, poke and prod, and tinker with. We figure, the best +way to see if an idea fits is to try it on for size. + + +Coding Style +============ +Please refer to the Coding Style Guidelines +(http://www.inkscape.org/doc/coding_style.php) if you have specific questions +on the style to use for code. If reading style guidelines doesn't interest +you, just follow the general style of the surrounding code, so that it is at +least consistent. + + +Makefiles +========= +Makefiles under the src directory are all more or less merged into one +src/Makefile.am that sources the Makefile_insert files from each directory. + +Note that it's still logically just one file, so variable definitions +(including INCLUDES etc.) are shared, and variables defined in one +Makefile_insert can be used in another. + +Thus, consider either adding a `blah_' prefix to the name of any variables you +define in blah/Makefile_insert (if it's intended to be local to that +Makefile_insert), or putting the definition in src/Makefile.am. In particular, +note that check_PROGRAMS, DISTCLEANFILES, etc. are in src/Makefile.am. + diff --git a/INSTALL b/INSTALL new file mode 100644 index 000000000..ecca22bda --- /dev/null +++ b/INSTALL @@ -0,0 +1,232 @@ +Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002 Free Software +Foundation, Inc. + + This file is free documentation; the Free Software Foundation gives +unlimited permission to copy, distribute and modify it. + +Basic Installation +================== + + If you have problems compiling Inkscape, then see +http://www.inkscape.org/cgi-bin/wiki.pl?CompilingInkscape . + + The remainder of this file gives generic installation instructions. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, and a +file `config.log' containing compiler output (useful mainly for +debugging `configure'). + + It can also use an optional file (typically called `config.cache' +and enabled with `--cache-file=config.cache' or simply `-C') that saves +the results of its tests to speed up reconfiguring. (Caching is +disabled by default to prevent problems with accidental use of stale +cache files.) + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If you are using the cache, and at +some point `config.cache' contains results you don't want to keep, you +may remove or edit it. + + The file `configure.ac' (or `configure.in') is used to create +`configure' by a program called `autoconf'. You only need +`configure.ac' if you want to change it or regenerate `configure' using +a newer version of `autoconf'. + +The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. If you're + using `csh' on an old version of System V, you might need to type + `sh ./configure' instead to prevent `csh' from trying to execute + `configure' itself. + + Running `configure' takes awhile. While running, it prints some + messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Optionally, type `make check' to run any self-tests that come with + the package. + + 4. Type `make install' to install the programs and any data files and + documentation. + + 5. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + +Compilers and Options +===================== + + Some systems require unusual options for compilation or linking that +the `configure' script does not know about. Run `./configure --help' +for details on some of the pertinent environment variables. + + You can give `configure' initial values for configuration parameters +by setting variables in the command line or in the environment. Here +is an example: + + ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix + + *Note Defining Variables::, for more details. + +Compiling For Multiple Architectures +==================================== + + You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you must use a version of `make' that +supports the `VPATH' variable, such as GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. + + If you have to use a `make' that does not support the `VPATH' +variable, you have to compile the package for one architecture at a +time in the source code directory. After you have installed the +package for one architecture, use `make distclean' before reconfiguring +for another architecture. + +Installation Names +================== + + By default, `make install' will install the package's files in +`/usr/local/bin', `/usr/local/man', etc. You can specify an +installation prefix other than `/usr/local' by giving `configure' the +option `--prefix=PATH'. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +give `configure' the option `--exec-prefix=PATH', the package will use +PATH as the prefix for installing programs and libraries. +Documentation and other data files will still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like `--bindir=PATH' to specify different values for particular +kinds of files. Run `configure --help' for a list of the directories +you can set and what kinds of files go in them. + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + +Optional Features +================= + + Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + +Specifying the System Type +========================== + + There may be some features `configure' cannot figure out +automatically, but needs to determine by the type of machine the package +will run on. Usually, assuming the package is built to be run on the +_same_ architectures, `configure' can figure that out, but if it prints +a message saying it cannot guess the machine type, give it the +`--build=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name which has the form: + + CPU-COMPANY-SYSTEM + +where SYSTEM can have one of these forms: + + OS KERNEL-OS + + See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the machine type. + + If you are _building_ compiler tools for cross-compiling, you should +use the `--target=TYPE' option to select the type of system they will +produce code for. + + If you want to _use_ a cross compiler, that generates code for a +platform different from the build platform, you should specify the +"host" platform (i.e., that on which the generated programs will +eventually be run) with `--host=TYPE'. + +Sharing Defaults +================ + + If you want to set default values for `configure' scripts to share, +you can create a site shell script called `config.site' that gives +default values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Defining Variables +================== + + Variables not defined in a site shell script can be set in the +environment passed to `configure'. However, some packages may run +configure again during the build, and the customized values of these +variables may be lost. In order to avoid this problem, you should set +them in the `configure' command line, using `VAR=value'. For example: + + ./configure CC=/usr/local2/bin/gcc + +will cause the specified gcc to be used as the C compiler (unless it is +overridden in the site shell script). + +`configure' Invocation +====================== + + `configure' recognizes the following options to control how it +operates. + +`--help' +`-h' + Print a summary of the options to `configure', and exit. + +`--version' +`-V' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`--cache-file=FILE' + Enable the cache: use and save the results of the tests in FILE, + traditionally `config.cache'. FILE defaults to `/dev/null' to + disable caching. + +`--config-cache' +`-C' + Alias for `--cache-file=config.cache'. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to `/dev/null' (any error + messages will still be shown). + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`configure' also accepts some other, not widely useful, options. Run +`configure --help' for more details. + diff --git a/Info.plist.in b/Info.plist.in new file mode 100644 index 000000000..20ed2e680 --- /dev/null +++ b/Info.plist.in @@ -0,0 +1,133 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + Inkscape + CFBundleGetInfoString + @VERSION@, Copyright 2003-2005 Inkscape Developers + CFBundleIconFile + Inkscape.icns + CFBundleIdentifier + org.inkscape.Inkscape + CFBundleDocumentTypes + + + CFBundleTypeExtensions + + SVGZ + + CFBundleTypeIconFile + inkscape_svg.icns + CFBundleTypeMIMETypes + + svgz + + CFBundleTypeName + SVGZ + CFBundleTypeOSTypes + + SVGZ + + CFBundleTypeRole + Viewer + + + CFBundleTypeExtensions + + EPS + + CFBundleTypeIconFile + EPS.icns + CFBundleTypeMIMETypes + + eps + + CFBundleTypeName + EPS + CFBundleTypeOSTypes + + EPS + + CFBundleTypeRole + Viewer + + + CFBundleTypeExtensions + + EPSI + + CFBundleTypeIconFile + EPSI.icns + CFBundleTypeMIMETypes + + epsi + + CFBundleTypeName + EPSI + CFBundleTypeOSTypes + + EPSI + + CFBundleTypeRole + Viewer + + + CFBundleTypeExtensions + + SVG + + CFBundleTypeIconFile + inkscape_svg.icns + CFBundleTypeMIMETypes + + svg + + CFBundleTypeName + SVG + CFBundleTypeOSTypes + + SVG + + CFBundleTypeRole + Viewer + + + CFBundleTypeExtensions + + PS + + CFBundleTypeIconFile + postscript.icns + CFBundleTypeMIMETypes + + ps + + CFBundleTypeName + Postscript + CFBundleTypeOSTypes + + PS + + CFBundleTypeRole + Viewer + + + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + APPL + CFBundleShortVersionString + @VERSION@ + CFBundleSignature + Inks + CFBundleVersion + @VERSION@ + NSHumanReadableCopyright + Copyright 2005 Inkscape Developers, GNU General Public License. + LSMinimumSystemVersion + 10.3 + + diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 000000000..abc305adc --- /dev/null +++ b/Makefile.am @@ -0,0 +1,194 @@ +## Process this file with automake to produce Makefile.in + +SUBDIRS = src doc share po + +appicondir = $(datadir)/pixmaps +appicon_DATA = inkscape.png + +Graphicsdir = $(datadir)/applications +Graphics_in_files = inkscape.desktop.in +Graphics_DATA = $(Graphics_in_files:.desktop.in=.desktop) +@INTLTOOL_DESKTOP_RULE@ + +## dist-hook: +## mkdir $(distdir)/samples +## cp $(srcdir)/samples/*svg $(distdir)/samples +## cp $(srcdir)/samples/*png $(distdir)/samples +## cp $(srcdir)/AUTHORS $(distdir) +## cp $(srcdir)/NEWS $(distdir) + + +man_MANS = inkscape.1 \ + inkview.1 + +EXTRA_DIST = \ + fix-roff-punct \ + intltool-extract.in \ + intltool-merge.in \ + intltool-update.in \ + mkinstalldirs \ + $(Graphics_in_files) \ + po/check-markup \ + utf8-to-roff \ + inkscape.1 \ + inkscape.fr.1 \ + inkscape.pod \ + inkscape.fr.pod \ + inkscape.spec.in \ + inkscape.spec \ + Info.plist.in \ + Info.plist \ + inkscape.nsi \ + config.h.mingw Makefile.mingw Makefile.mingw.common mingwenv.bat \ + README README.ca.txt README.de.txt README.es.txt README.fr.txt README.it.txt \ + HACKING.txt HACKING.de.txt HACKING.fr.txt HACKING.it.txt \ + TRANSLATORS \ + inkscape.png \ + inkscape.ico inkscape16.ico inkscape32-16.ico inkscape32.ico inkscape64.ico \ + cxxtest/COPYING \ + cxxtest/cxxtestgen.pl \ + cxxtest/cxxtestgen.py \ + cxxtest/cxxtest/Descriptions.cpp \ + cxxtest/cxxtest/Descriptions.h \ + cxxtest/cxxtest/DummyDescriptions.cpp \ + cxxtest/cxxtest/DummyDescriptions.h \ + cxxtest/cxxtest/ErrorFormatter.h \ + cxxtest/cxxtest/ErrorPrinter.h \ + cxxtest/cxxtest/Flags.h \ + cxxtest/cxxtest/GlobalFixture.cpp \ + cxxtest/cxxtest/GlobalFixture.h \ + cxxtest/cxxtest/Gui.h \ + cxxtest/cxxtest/LinkedList.cpp \ + cxxtest/cxxtest/LinkedList.h \ + cxxtest/cxxtest/Mock.h \ + cxxtest/cxxtest/ParenPrinter.h \ + cxxtest/cxxtest/QtGui.h \ + cxxtest/cxxtest/RealDescriptions.cpp \ + cxxtest/cxxtest/RealDescriptions.h \ + cxxtest/cxxtest/Root.cpp \ + cxxtest/cxxtest/SelfTest.h \ + cxxtest/cxxtest/StdHeaders.h \ + cxxtest/cxxtest/StdValueTraits.h \ + cxxtest/cxxtest/StdioFilePrinter.h \ + cxxtest/cxxtest/StdioPrinter.h \ + cxxtest/cxxtest/TeeListener.h \ + cxxtest/cxxtest/TestListener.h \ + cxxtest/cxxtest/TestRunner.h \ + cxxtest/cxxtest/TestSuite.cpp \ + cxxtest/cxxtest/TestSuite.h \ + cxxtest/cxxtest/TestTracker.cpp \ + cxxtest/cxxtest/TestTracker.h \ + cxxtest/cxxtest/ValueTraits.cpp \ + cxxtest/cxxtest/ValueTraits.h \ + cxxtest/cxxtest/Win32Gui.h \ + cxxtest/cxxtest/X11Gui.h \ + cxxtest/cxxtest/YesNoRunner.h \ + debian/changelog \ + debian/compat \ + debian/control \ + debian/copyright \ + debian/dirs \ + debian/docs \ + debian/inkscape.applications \ + debian/inkscape.menu \ + debian/inkscape.xpm \ + debian/mime \ + debian/rules \ + packaging/autopackage/default.apspec.in \ + packaging/osx-app.sh \ + packaging/macosx/Resources/MenuBar.nib/classes.nib \ + packaging/macosx/Resources/MenuBar.nib/info.nib \ + packaging/macosx/Resources/MenuBar.nib/objects.xib \ + packaging/macosx/Resources/EPS.icns \ + packaging/macosx/Resources/EPSI.icns \ + packaging/macosx/Resources/Inkscape.icns \ + packaging/macosx/Resources/SVG_plain.icns \ + packaging/macosx/Resources/inkscape_svg.icns \ + packaging/macosx/Resources/openDoc \ + packaging/macosx/Resources/postscript.icns \ + packaging/macosx/Resources/script \ + packaging/macosx/Resources/ProgressWindow.nib/classes.nib \ + packaging/macosx/Resources/ProgressWindow.nib/info.nib \ + packaging/macosx/Resources/ProgressWindow.nib/objects.xib \ + packaging/macosx/Resources/bin/getdisplay.sh \ + packaging/macosx/Resources/bin/inkscape \ + packaging/macosx/ScriptExec/English.lproj/main.nib/classes.nib \ + packaging/macosx/ScriptExec/English.lproj/main.nib/info.nib \ + packaging/macosx/ScriptExec/English.lproj/main.nib/objects.xib \ + packaging/macosx/ScriptExec/English.lproj/InfoPlist.strings \ + packaging/macosx/ScriptExec/Info.plist \ + packaging/macosx/ScriptExec/ScriptExec_Prefix.pch \ + packaging/macosx/ScriptExec/main.c \ + packaging/macosx/ScriptExec/openDoc \ + packaging/macosx/ScriptExec/script \ + packaging/macosx/ScriptExec/version.plist \ + packaging/macosx/ScriptExec/MenuBar.nib/classes.nib \ + packaging/macosx/ScriptExec/MenuBar.nib/info.nib \ + packaging/macosx/ScriptExec/MenuBar.nib/objects.xib \ + packaging/macosx/ScriptExec/ScriptExec.xcode/project.pbxproj \ + packaging/macosx/ScriptExec/ScriptExec.xcode/sveinbjornt.pbxuser \ + packaging/macosx/ScriptExec/ScriptExec.xcode/voisine.pbxuser \ + packaging/win32/inkscape.nsi \ + packaging/win32/inkscape.nsi.uninstall \ + packaging/win32/english.nsh \ + packaging/win32/german.nsh \ + packaging/win32/header.bmp \ + po/Makefile.mingw \ + src/Makefile.mingw src/inkscape_version.h.mingw src/inkscape.rc src/makedef.pl \ + src/helper/sp-marshal.h.mingw src/helper/sp-marshal.cpp.mingw + +# Note: it isn't clear that debian/* belongs in the tar file: +# tarfile users should be able to use the official Debian packages. +# They were added to EXTRA_DIST in v1.5, in response to a message on +# inkscape-devel from "Carlos Ingelmo " on 2003-11-12 01:35. + +# We want the built inkscape.1 to go in the distributed .tar.gz so +# that .tar.gz users don't need a full perl distribution to get a man +# page. + +DISTCLEANFILES = inkscape.desktop \ + intltool-extract \ + intltool-merge \ + intltool-update + +#ACLOCAL_AMFLAGS = -I m4 + +SUFFIXES = .pod .1 +inkscape.1 inkscape.fr.1: fix-roff-punct Makefile.am AUTHORS utf8-to-roff +.pod.1: + set -e; \ + d=`sed -n 's,/,-,g;s,.*\$$[D]ate: \(..........\).*,\1,p' $<`; \ + pod2man $< \ + | sed 's/^\.TH .*/.TH INKSCAPE 1 "'"$$d"'" "Inkscape-$(VERSION)" "Inkscape"/' \ + | perl -pe 'if (/^\[\% .*INCLUDE.*AUTHORS.* \%\]/) { open(FOO, "$(srcdir)/AUTHORS");$$_ = join(",\n", map { chomp; $$_ } ) . "\n"; }' \ + | perl $(srcdir)/fix-roff-punct \ + | perl -CI $(srcdir)/utf8-to-roff \ + > tmp.$$$$ \ + && mv tmp.$$$$ $@ +# man 7 groff_char for further remarks on charset encoding for man pages. + +install-data-local: inkscape.fr.1 + $(mkinstalldirs) $(DESTDIR)$(mandir)/fr/man1 + $(INSTALL_DATA) `if [ -f inkscape.fr.1 ]; then :; else echo $(srcdir)/;fi`inkscape.fr.1 $(DESTDIR)$(mandir)/fr/man1/inkscape.1 + +.PHONY: warn_markup +noinst_DATA = warn_markup +warn_markup: + @if perl $(srcdir)/po/check-markup $(srcdir)/po/*.po; [ $$? = 1 ]; then \ + echo "WARNING: Bad markup found in translations. Please consider fixing the above problems." >&2; \ + fi + +.PHONY: check_markup +check_DATA = check_markup +check_markup: + perl $(srcdir)/po/check-markup $(srcdir)/po/*.po || [ $$? = 127 ] +# # `make check' probably shouldn't require perl to be installed, hence ignoring 127. + +distcheck-hook: + perl $(srcdir)/po/check-markup $(srcdir)/po/*.po + +test-check-markup: + if perl -e 42; then \ + perl $(srcdir)/po/check-markup $(srcdir)/po/bad.po.test 2>&1 \ + | diff $(srcdir)/po/bad.po.test.exp -; \ + fi diff --git a/Makefile.mingw b/Makefile.mingw new file mode 100644 index 000000000..8adf29113 --- /dev/null +++ b/Makefile.mingw @@ -0,0 +1,145 @@ + + +include ./Makefile.mingw.common + + +all: config.h $(GTKDOS)$(S)bin$(S)intl.dll + $(MAKE) -C po -f Makefile.mingw + $(MAKE) -C src -f Makefile.mingw + +config.h: config.h.mingw + $(CP) config.h.mingw config.h + +$(GTKDOS)$(S)bin$(S)intl.dll: + $(CP) $(GTKDOS)$(S)bin$(S)libintl-2.dll $(GTKDOS)$(S)bin$(S)intl.dll + +dist-strip: dist + -$(RMDIRREC) CVS $(RMDIRREC1) + -$(RMREC) .cvsignore $(RMREC1) + -$(RMREC) Makefile $(RMREC1) + -$(RMREC) Makefile.am $(RMREC1) + -$(RMREC) Makefile.in $(RMREC1) + -$(RMDIR) inkscape$(S)lib$(S)glib-2.0$(S)include + -$(RMDIR) inkscape$(S)lib$(S)gtk-2.0$(S)include + strip inkscape$(S)inkscape.exe + strip inkscape$(S)inkview.exe + strip inkscape$(S)libatkmm-1.6-1.dll + strip inkscape$(S)libglibmm-2.4-1.dll + strip inkscape$(S)libgdkmm-2.4-1.dll + strip inkscape$(S)libgtkmm-2.4-1.dll + strip inkscape$(S)libpangomm-1.4-1.dll + strip inkscape$(S)libsigc-2.0-0.dll + strip inkscape$(S)freetype6.dll + strip inkscape$(S)libatk-1.0-0.dll + strip inkscape$(S)libgdk-win32-2.0-0.dll + strip inkscape$(S)libgdk_pixbuf-2.0-0.dll + strip inkscape$(S)libglib-2.0-0.dll + strip inkscape$(S)libgmodule-2.0-0.dll + strip inkscape$(S)libgobject-2.0-0.dll + strip inkscape$(S)libgtk-win32-2.0-0.dll + strip inkscape$(S)libgthread-2.0-0.dll + strip inkscape$(S)libpango-1.0-0.dll + strip inkscape$(S)libpangoft2-1.0-0.dll + strip inkscape$(S)libpangowin32-1.0-0.dll + strip inkscape$(S)freetype6.dll + strip inkscape$(S)libfontconfig-1.dll +# strip inkscape$(S)libxml2.dll +# strip inkscape$(S)xmlparse.dll + strip inkscape$(S)jpeg62.dll + strip inkscape$(S)libtiff3.dll + strip inkscape$(S)libpng13.dll +# strip inkscape$(S)zlib1.dll +# strip inkscape$(S)iconv.dll +# strip inkscape$(S)libintl-2.dll +# strip inkscape$(S)intl.dll + strip inkscape$(S)popt1.dll + strip inkscape$(S)perl58.dll + strip inkscape$(S)python24.dll + -$(RM) inkscape$(S)gdb.exe + +dist: + $(MAKE) -C src -f Makefile.mingw + -$(RMDIR) inkscape + $(MKDIR) inkscape + $(CP) src$(S)inkscape.exe inkscape + $(CP) src$(S)inkview.exe inkscape + $(CP) AUTHORS inkscape + $(CP) COPYING inkscape + $(CP) COPYING.LIB inkscape + $(CP) NEWS inkscape + $(CP) HACKING.* inkscape + $(CP) README inkscape$(S)README.txt + $(CP) README.* inkscape + $(CP) TRANSLATORS inkscape + $(CP) $(GTKDOS)$(S)bin$(S)libatkmm-1.6-1.dll inkscape + $(CP) $(GTKDOS)$(S)bin$(S)libglibmm-2.4-1.dll inkscape + $(CP) $(GTKDOS)$(S)bin$(S)libgdkmm-2.4-1.dll inkscape + $(CP) $(GTKDOS)$(S)bin$(S)libgtkmm-2.4-1.dll inkscape + $(CP) $(GTKDOS)$(S)bin$(S)libpangomm-1.4-1.dll inkscape + $(CP) $(GTKDOS)$(S)bin$(S)libsigc-2.0-0.dll inkscape + $(CP) $(GTKDOS)$(S)bin$(S)freetype6.dll inkscape + $(CP) $(GTKDOS)$(S)bin$(S)libatk-1.0-0.dll inkscape + $(CP) $(GTKDOS)$(S)bin$(S)libgdk-win32-2.0-0.dll inkscape + $(CP) $(GTKDOS)$(S)bin$(S)libgdk_pixbuf-2.0-0.dll inkscape + $(CP) $(GTKDOS)$(S)bin$(S)libglib-2.0-0.dll inkscape + $(CP) $(GTKDOS)$(S)bin$(S)libgmodule-2.0-0.dll inkscape + $(CP) $(GTKDOS)$(S)bin$(S)libgobject-2.0-0.dll inkscape + $(CP) $(GTKDOS)$(S)bin$(S)libgtk-win32-2.0-0.dll inkscape + $(CP) $(GTKDOS)$(S)bin$(S)libgthread-2.0-0.dll inkscape + $(CP) $(GTKDOS)$(S)bin$(S)libcairo-2.dll inkscape + $(CP) $(GTKDOS)$(S)bin$(S)libpangocairo-1.0-0.dll inkscape + $(CP) $(GTKDOS)$(S)bin$(S)libpango-1.0-0.dll inkscape + $(CP) $(GTKDOS)$(S)bin$(S)libpangoft2-1.0-0.dll inkscape + $(CP) $(GTKDOS)$(S)bin$(S)libpangowin32-1.0-0.dll inkscape + $(CP) $(GTKDOS)$(S)bin$(S)freetype6.dll inkscape + $(CP) $(GTKDOS)$(S)bin$(S)libfontconfig-1.dll inkscape + $(CP) $(GTKDOS)$(S)bin$(S)libxml2.dll inkscape + $(CP) $(GTKDOS)$(S)bin$(S)xmlparse.dll inkscape + $(CP) $(GTKDOS)$(S)bin$(S)jpeg62.dll inkscape + $(CP) $(GTKDOS)$(S)bin$(S)libtiff3.dll inkscape + $(CP) $(GTKDOS)$(S)bin$(S)libpng13.dll inkscape + $(CP) $(GTKDOS)$(S)bin$(S)msvcr70.dll inkscape + $(CP) $(GTKDOS)$(S)bin$(S)zlib1.dll inkscape + $(CP) $(GTKDOS)$(S)bin$(S)iconv.dll inkscape + $(CP) $(GTKDOS)$(S)bin$(S)libintl-2.dll inkscape + $(CP) $(GTKDOS)$(S)bin$(S)libintl-2.dll inkscape$(S)intl.dll + $(CP) $(GTKDOS)$(S)bin$(S)popt1.dll inkscape + $(CP) $(GTKDOS)$(S)perl$(S)bin$(S)perl58.dll inkscape + $(CP) $(GTKDOS)$(S)python$(S)python24.dll inkscape + $(CPDIR) $(GTKDOS)$(S)etc inkscape$(S)etc + $(CP) $(GTKDOS)$(S)share$(S)themes$(S)MS-Windows$(S)gtk-2.0$(S)gtkrc inkscape$(S)etc$(S)gtk-2.0 +# echo #### Inserted by Inkscape Makefile.mingw > inkscape$(S)etc$(S)gtk-2.0$(S)gtkrc +# echo $(subst /",\", $(subst ",$(E)", gtk-font-name="verdana 9" >> inkscape$(S)etc$(S)gtk-2.0$(S)gtkrc)) +# echo #### >> inkscape$(S)etc$(S)gtk-2.0$(S)gtkrc + $(MKDIR) inkscape$(S)lib + $(CPDIR) $(GTKDOS)$(S)lib$(S)gtk-2.0 inkscape$(S)lib$(S)gtk-2.0 + $(CPDIR) $(GTKDOS)$(S)lib$(S)glib-2.0 inkscape$(S)lib$(S)glib-2.0 + $(CPDIR) $(GTKDOS)$(S)lib$(S)locale inkscape$(S)lib$(S)locale + $(CPDIR) $(GTKDOS)$(S)lib$(S)pango inkscape$(S)lib$(S)pango +# $(MKDIR) inkscape$(S)fonts +# $(CP) $(GTKDOS)$(S)fonts$(S)*.ttf inkscape$(S)fonts + $(CPDIR) share inkscape$(S)share + $(CPDIR) $(GTKDOS)$(S)share$(S)themes inkscape$(S)share$(S)themes + $(CPDIR) doc inkscape$(S)doc + $(MKDIR) inkscape$(S)data + $(MKDIR) inkscape$(S)locale + $(MAKE) -C po -f Makefile.mingw dist + $(MKDIR) inkscape$(S)modules + $(MKDIR) inkscape$(S)plugins + -$(CP) src$(S)extension$(S)plugin$(S)*.dll inkscape$(S)plugins + $(CP) $(GTKDOS)$(S)bin$(S)gdb.exe inkscape + @echo "##################### D O N E ####################" + +clean: + -$(RMDIR) inkscape + -$(RM) inkscape*.zip + $(MAKE) -C src -f Makefile.mingw clean + $(MAKE) -C po -f Makefile.mingw clean + +minimal: + $(MAKE) -C src -f Makefile.mingw + -$(RM) inkscape$(S)inkscape.exe + $(CP) src$(S)inkscape.exe inkscape + @echo "##################### D O N E ####################" + + diff --git a/Makefile.mingw.common b/Makefile.mingw.common new file mode 100644 index 000000000..cea909bf3 --- /dev/null +++ b/Makefile.mingw.common @@ -0,0 +1,232 @@ +########################################################################### +# $Id$ +# File: Makefile.mingw.common +# Does: Common definitions for all Makefile.mingw files +# Author: Bob Jamison & the Inkscape Guys +########################################################################### + +####### Sense whether we are on a DOS box or cross-compiling +ifdef ComSpec +BUILD=native +DOSSHELL=CMD_EXE +else +ifdef COMSPEC +BUILD=native +DOSSHELL=COMMAND_COM +else +BUILD=cross +endif +endif + + + + +########################################################################## +# FILE SEPARATORS +# $(S) will be set to one of these +########################################################################## +BSLASH := \\# +FSLASH := / + + + +########################################################################## +# CROSS / NATIVE SWITCHES +########################################################################## +ifeq ($(BUILD),cross) + + + +########################################################################## +# CROSS COMPILER SETTINGS +########################################################################## + +CC = i686-pc-mingw32-gcc +CXX = i686-pc-mingw32-g++ +AS = i686-pc-mingw32-as +AR = i686-pc-mingw32-ar +RANLIB = i686-pc-mingw32-ranlib +WINDRES = i686-pc-mingw32-windres +LD = i686-pc-mingw32-ld +DLLWRAP = i686-pc-mingw32-dllwrap +DLLTOOL = i686-pc-mingw32-dlltool + +####### file separator +S = $(FSLASH) + +####### escape character for echo +E = / + +####### file manipulation programs +CP = cp +RMDIR = rm -rf +MKDIR = mkdir +CPDIR = cp -rf +MSGFMT = msgfmt +RMREC = find ./inkscape -type f -name +RMREC1 = |xargs $(RM) +RMDIRREC = find ./inkscape -type d -name +RMDIRREC1 = |xargs $(RMDIR) + +####### Where is your GTK directory? +GTK=/target + +####### Same thing, file system style +GTKDOS=$(GTK) + +DTG := $(shell date +%y%m%d.%H%M) + +else + +########################################################################## +# NATIVE COMPILER SETTINGS +########################################################################## + +CC = mingw32-gcc +CXX = mingw32-g++ +AS = as +AR = mingw32-ar +RANLIB = ranlib +WINDRES = windres +DLLWRAP = dllwrap +DLLTOOL = dlltool + +####### file separator +S = $(BSLASH) + +####### escape character for echo +E = + +####### file manipulation programs +CP = copy + +####### are we on WinNt and beyond? +ifeq ($(DOSSHELL),CMD_EXE) +RMDIR = rmdir /s /q +RM = del +else +RMDIR = deltree /y +RM = del +endif +MKDIR = mkdir +CPDIR = xcopy /e /i +RMREC = cd inkscape & $(RM) /s /q +RMREC1 = & cd .. +RMDIRREC = cd inkscape & $(RMDIR) /s +RMDIRREC1 = & cd .. + +####### Where is your GTK directory? +GTK=c:/gtk28 + +####### Same thing, DOS style +GTKDOS=c:\gtk28 + +####### Command to process .po files --> .mo +MSGFMT = $(GTKDOS)$(S)bin$(S)msgfmt + +####### change me!! +DTG := 20050626 + +endif +########################################################################## +# END CROSS / NATIVE SWITCHES +########################################################################## + + +###### VERSION NUMBER +# VERSION_NR = 0.41+devel +# VERSION = \"$(VERSION_NR)-${DTG}\" + +VERSION_NR = 0.43+devel +VERSION = \"$(VERSION_NR)\" + +####### the XP_WIN def is necessary for libjs.a +CFLAGS = -O3 -Wall -mms-bitfields -DVERSION=$(VERSION) \ +-DXP_WIN -D_INTL_REDIRECT_INLINE -DHAVE_CONFIG_H + +####### Inkboard abilities. +####### You must 'make -f Makefile.mingw clean' when turning this on or off +#CFLAGS += -DWITH_INKBOARD + + +####### IMPLICIT RULES +.cpp.o: + $(CXX) $(CFLAGS) $(INC) -c -o $@ $< + +.c.o: + $(CC) $(CFLAGS) $(INC) -c -o $@ $< + + + + + +########################################################################## +# INCLUDES AND LIBRARIES +########################################################################## + +GTKINC = -DGLIBMM_DLL \ +-I$(GTK)/include/glibmm-2.4 -I$(GTK)/lib/glibmm-2.4/include \ +-I$(GTK)/include/gtkmm-2.4 -I$(GTK)/lib/gtkmm-2.4/include \ +-I$(GTK)/include/gdkmm-2.4 -I$(GTK)/lib/gdkmm-2.4/include \ +-I$(GTK)/include/pangomm-1.4 \ +-I$(GTK)/include/atkmm-1.6 -I$(GTK)/include/cairo \ +-I$(GTK)/include/sigc++-2.0 -I$(GTK)/lib/sigc++-2.0/include \ +-I$(GTK)/include/gtk-2.0 -I$(GTK)/lib/gtk-2.0/include \ +-I$(GTK)/include/atk-1.0 -I$(GTK)/include/pango-1.0 \ +-I$(GTK)/include/glib-2.0 -I$(GTK)/lib/glib-2.0/include + + +####### Our Gtk libs +####### we removed the '-Wl,--enable-runtime-pseudo-reloc' option, as +####### it proved to be very dangerous +####### with Gtk::TreeViewColumn +GTKLIB = -L$(GTK)/lib -lloudmouth-1 \ +-lgtkmm-2.4 -lgdkmm-2.4 -lglibmm-2.4 \ +-latkmm-1.6 -lpangomm-1.4 -lsigc-2.0 \ +-lgtk-win32-2.0 -lgdk-win32-2.0 -latk-1.0 \ +-lgdk_pixbuf-2.0 -lm -lpangoft2-1.0 -lpangowin32-1.0 -lpango-1.0 \ +-lgobject-2.0 -lgmodule-2.0 -lgthread-2.0 -lglib-2.0 + +####### For PERL +####### (note: perl's config.h has some nested comments) +PERLINC = -Wno-comment -I$(GTK)/perl/lib/CORE +PERLLIB = -L$(GTK)/perl/lib/CORE -lperl58 + +####### For Python +PYTHONINC = -I$(GTK)/python/include +PYTHONLIB = -L$(GTK)/python/libs -lpython24 +#PYTHONLIB = -L$(GTK)/python/libs/libpython24.a + +####### remove -DLIBXML_STATIC +INC = -I. -I.. -I../.. $(GTKINC) -I$(GTK)/include \ +$(PERLINC) $(PYTHONINC) -I$(GTK)/include/loudmouth-1.0 \ +-I$(GTK)/include/libxml2 -I$(GTK)/include/freetype2 \ + + +LIBS = $(GTKLIB) $(PERLLIB) $(PYTHONLIB) \ +$(GTK)/bin/libxml2.dll \ +$(GTK)/lib/iconv.lib \ +-lfreetype.dll -lfontconfig.dll \ +-lpng -lpopt $(GTK)/lib/zdll.lib \ +-lgc -mwindows -lws2_32 -lintl + + +########################################################################## +# END INCLUDES AND LIBRARIES +########################################################################## + + + + +########################################################################## +# E N D O F F I L E +########################################################################## + + + + + + + + + diff --git a/Makefile.mingw.common.old b/Makefile.mingw.common.old new file mode 100644 index 000000000..e24991fb4 --- /dev/null +++ b/Makefile.mingw.common.old @@ -0,0 +1,209 @@ +########################################################################### +# $Id$ +# File: Makefile.mingw.common +# Does: Common definitions for all Makefile.mingw files +# Author: Bob Jamison & the Inkscape Guys +########################################################################### + +####### Sense whether we are on a DOS box or cross-compiling +ifdef ComSpec +BUILD=native +DOSSHELL=CMD_EXE +else +ifdef COMSPEC +BUILD=native +DOSSHELL=COMMAND_COM +else +BUILD=cross +endif +endif + + + + +########################################################################## +# FILE SEPARATORS +# $(S) will be set to one of these +########################################################################## +BSLASH := \\# +FSLASH := / + + + +########################################################################## +# CROSS / NATIVE SWITCHES +########################################################################## +ifeq ($(BUILD),cross) + + + +########################################################################## +# CROSS COMPILER SETTINGS +########################################################################## + +CC = i686-pc-mingw32-gcc +CXX = i686-pc-mingw32-g++ +AS = i686-pc-mingw32-as +AR = i686-pc-mingw32-ar +RANLIB = i686-pc-mingw32-ranlib +WINDRES = i686-pc-mingw32-windres +LD = i686-pc-mingw32-ld +DLLWRAP = i686-pc-mingw32-dllwrap +DLLTOOL = i686-pc-mingw32-dlltool + +####### file separator +S = $(FSLASH) + +####### file manipulation programs +CP = cp +RMDIR = rm -rf +MKDIR = mkdir +CPDIR = cp -rf +MSGFMT = msgfmt + +####### Where is your GTK directory? +GTK=/target + +####### Same thing, file system style +GTKDOS=$(GTK) + +DTG := $(shell date +%y%m%d.%H%M) + +else + +########################################################################## +# NATIVE COMPILER SETTINGS +########################################################################## + +CC = mingw32-gcc +CXX = mingw32-g++ +AS = as +AR = mingw32-ar +RANLIB = ranlib +WINDRES = windres +DLLWRAP = dllwrap +DLLTOOL = dlltool + +####### file separator +S = $(BSLASH) + +####### file manipulation programs +CP = copy + +####### are we on WinNt and beyond? +ifeq ($(DOSSHELL),CMD_EXE) +RMDIR = rmdir /s /q +RM = del +else +RMDIR = deltree /y +RM = del +endif +MKDIR = mkdir +CPDIR = xcopy /e /i + +####### Where is your GTK directory? +GTK=c:/gtk + +####### Same thing, DOS style +GTKDOS=c:\gtk + +####### Command to process .po files --> .mo +MSGFMT = $(GTKDOS)$(S)bin$(S)msgfmt + +####### change me!! +DTG := 20050626 + +endif +########################################################################## +# END CROSS / NATIVE SWITCHES +########################################################################## + + +###### VERSION NUMBER +# VERSION_NR = 0.41+devel +# VERSION = \"$(VERSION_NR)-${DTG}\" + +VERSION_NR = 0.42+pre0 +VERSION = \"$(VERSION_NR)\" + +####### the XP_WIN def is necessary for libjs.a +CFLAGS = -O3 -Wall -mms-bitfields -DVERSION=$(VERSION) \ +-DXP_WIN -D_INTL_REDIRECT_INLINE -DHAVE_CONFIG_H + + +####### IMPLICIT RULES +.cpp.o: + $(CXX) $(CFLAGS) $(INC) -c -o $@ $< + +.c.o: + $(CC) $(CFLAGS) $(INC) -c -o $@ $< + + + + + +########################################################################## +# INCLUDES AND LIBRARIES +########################################################################## + +GTKINC = \ +-I$(GTK)/include/glibmm-2.4 -I$(GTK)/lib/glibmm-2.4/include \ +-I$(GTK)/include/gtkmm-2.4 -I$(GTK)/lib/gtkmm-2.4/include \ +-I$(GTK)/include/gdkmm-2.4 -I$(GTK)/lib/gdkmm-2.4/include \ +-I$(GTK)/include/pangomm-1.4 \ +-I$(GTK)/include/atkmm-1.6 \ +-I$(GTK)/include/sigc++-2.0 -I$(GTK)/lib/sigc++-2.0/include \ +-I$(GTK)/include/gtk-2.0 -I$(GTK)/lib/gtk-2.0/include \ +-I$(GTK)/include/atk-1.0 -I$(GTK)/include/pango-1.0 \ +-I$(GTK)/include/glib-2.0 -I$(GTK)/lib/glib-2.0/include + + +####### New way with static C++ libs +GTKLIB = -L$(GTK)/lib \ +-lgtkmm-2.4 -lgdkmm-2.4 -lglibmm-2.4 \ +-latkmm-1.6 -lpangomm-1.4 -lsigc-2.0 \ +-lgtk-win32-2.0 -lgdk-win32-2.0 -latk-1.0 \ +-lgdk_pixbuf-2.0 -lm -lpangoft2-1.0 -lpangowin32-1.0 -lpango-1.0 \ +-lgobject-2.0 -lgmodule-2.0 -lgthread-2.0 -lglib-2.0 + +####### For PERL +####### (note: perl's config.h has some nested comments) +PERLINC = -Wno-comment -I$(GTK)/perl/lib/CORE +PERLLIB = -L$(GTK)/perl/lib/CORE -lperl58 + +####### For Python +PYTHONINC = -I$(GTK)/python/include +PYTHONLIB = -L$(GTK)/python/libs -lpython24 +#PYTHONLIB = -L$(GTK)/python/libs/libpython24.a + +####### remove -DLIBXML_STATIC +INC = -I. -I.. -I../.. $(GTKINC) -I$(GTK)/include \ +$(PERLINC) $(PYTHONINC) -I$(GTK)/include/libxml2 \ +-I$(GTK)/include/freetype2 \ + + +LIBS = $(GTKLIB) $(PERLLIB) $(PYTHONLIB) -lxml2 \ +$(GTK)/lib/iconv.lib \ +-lfreetype6.dll -lfontconfig-1.dll -lpng -lpopt $(GTK)/lib/zdll.lib \ +-lgc -mwindows -lws2_32 -lintl + + +########################################################################## +# END INCLUDES AND LIBRARIES +########################################################################## + + + + +########################################################################## +# E N D O F F I L E +########################################################################## + + + + + + + + + diff --git a/Makefile.mingw.old b/Makefile.mingw.old new file mode 100644 index 000000000..bd4ca5d1e --- /dev/null +++ b/Makefile.mingw.old @@ -0,0 +1,80 @@ + + +include ./Makefile.mingw.common + + +all: config.h + $(MAKE) -C po -f Makefile.mingw + $(MAKE) -C src -f Makefile.mingw + +config.h: config.h.mingw + $(CP) config.h.mingw config.h + +dist: + $(MAKE) -C src -f Makefile.mingw + -$(RMDIR) inkscape + $(MKDIR) inkscape + $(CP) src$(S)inkscape.exe inkscape +# $(CP) src$(S)inkview.exe inkscape +# $(CP) src$(S)inkscape.dll inkscape + $(CP) $(GTKDOS)$(S)bin$(S)freetype6.dll inkscape + $(CP) $(GTKDOS)$(S)bin$(S)libatk-1.0-0.dll inkscape + $(CP) $(GTKDOS)$(S)bin$(S)libgdk-win32-2.0-0.dll inkscape + $(CP) $(GTKDOS)$(S)bin$(S)libgdk_pixbuf-2.0-0.dll inkscape + $(CP) $(GTKDOS)$(S)bin$(S)libglib-2.0-0.dll inkscape + $(CP) $(GTKDOS)$(S)bin$(S)libgmodule-2.0-0.dll inkscape + $(CP) $(GTKDOS)$(S)bin$(S)libgobject-2.0-0.dll inkscape + $(CP) $(GTKDOS)$(S)bin$(S)libgtk-win32-2.0-0.dll inkscape + $(CP) $(GTKDOS)$(S)bin$(S)libgthread-2.0-0.dll inkscape +# $(CP) $(GTKDOS)$(S)bin$(S)libiconv-2.dll inkscape + $(CP) $(GTKDOS)$(S)bin$(S)libpango-1.0-0.dll inkscape + $(CP) $(GTKDOS)$(S)bin$(S)libpangoft2-1.0-0.dll inkscape + $(CP) $(GTKDOS)$(S)bin$(S)libpangowin32-1.0-0.dll inkscape + $(CP) $(GTKDOS)$(S)bin$(S)freetype6.dll inkscape + $(CP) $(GTKDOS)$(S)bin$(S)libfontconfig-1.dll inkscape + $(CP) $(GTKDOS)$(S)bin$(S)libxml2-2.dll inkscape + $(CP) $(GTKDOS)$(S)bin$(S)jpeg62.dll inkscape + $(CP) $(GTKDOS)$(S)bin$(S)libpng12.dll inkscape + $(CP) $(GTKDOS)$(S)bin$(S)msvcr70.dll inkscape + $(CP) $(GTKDOS)$(S)bin$(S)zlib1.dll inkscape + $(CP) $(GTKDOS)$(S)bin$(S)iconv.dll inkscape + $(CP) $(GTKDOS)$(S)bin$(S)intl.dll inkscape + $(CP) $(GTKDOS)$(S)bin$(S)xmlparse.dll inkscape + $(CP) $(GTKDOS)$(S)perl$(S)bin$(S)perl58.dll inkscape + $(CP) $(GTKDOS)$(S)python$(S)python24.dll inkscape + $(CPDIR) $(GTKDOS)$(S)etc inkscape$(S)etc + echo "#### Inserted by Inkscape Makefile.mingw" > inkscape$(S)etc$(S)gtk-2.0$(S)gtkrc + echo "gtk-font-name=\"verdana 9\"" >> inkscape$(S)etc$(S)gtk-2.0$(S)gtkrc + echo "" >> inkscape$(S)etc$(S)gtk-2.0$(S)gtkrc + $(MKDIR) inkscape$(S)lib + $(CPDIR) $(GTKDOS)$(S)lib$(S)gtk-2.0 inkscape$(S)lib$(S)gtk-2.0 + $(CPDIR) $(GTKDOS)$(S)lib$(S)glib-2.0 inkscape$(S)lib$(S)glib-2.0 + $(CPDIR) $(GTKDOS)$(S)lib$(S)locale inkscape$(S)lib$(S)locale + $(CPDIR) $(GTKDOS)$(S)lib$(S)pango inkscape$(S)lib$(S)pango + $(MKDIR) inkscape$(S)fonts + $(CP) $(GTKDOS)$(S)fonts$(S)*.ttf inkscape$(S)fonts + $(CPDIR) share inkscape$(S)share + $(CPDIR) $(GTKDOS)$(S)share$(S)themes inkscape$(S)share + $(CPDIR) doc inkscape$(S)doc + $(MKDIR) inkscape$(S)data + $(MKDIR) inkscape$(S)locale + $(MAKE) -C po -f Makefile.mingw dist + $(MKDIR) inkscape$(S)modules + $(MKDIR) inkscape$(S)plugins + -$(CP) src$(S)extension$(S)plugin$(S)*.dll inkscape$(S)plugins + $(CP) $(GTKDOS)$(S)bin$(S)gdb.exe inkscape + @echo "##################### D O N E ####################" + +clean: + -$(RMDIR) inkscape + -$(RM) inkscape*.zip + $(MAKE) -C src -f Makefile.mingw clean + $(MAKE) -C po -f Makefile.mingw clean + +minimal: + $(MAKE) -C src -f Makefile.mingw + $(RM) inkscape$(S)inkscape.exe + $(CP) src$(S)inkscape.exe inkscape + @echo "##################### D O N E ####################" + + diff --git a/NEWS b/NEWS new file mode 100644 index 000000000..5c4070c5b --- /dev/null +++ b/NEWS @@ -0,0 +1,439 @@ + Release Notes + Inkscape 0.43 + +In brief + + The focus of this release is on the exciting new features sponsored by + Google via their Summer of Code program. However, we have quite a bunch of + other stuff too. Here are the highlights: + + * Connectors: A new Connector tool implements creation, editing, and + autorouting (object-avoiding) of connector lines between objects. + Indispensable for diagramming. (A Google SoC project.) + * Inkboard collaborative editing: You can now connect to other Inkscape + users over the Net and edit a shared document together, watching + others' changes and making yours! (A Google SoC project.) + * Pressure and tilt sensitivity: the Calligraphy tool can now use a + tablet pen with pressure/tilt support to vary the width and angle of + the calligraphic stroke. + * Better node editing: You can freely drag/bend/stretch a Bezier curve + by any point (not only by a node), as well as add a new node at any + point on the curve. + * New extensions for envelope distortion, whirling, and adding nodes. + * Improved precision, expanded limits, many usability improvements and + bugfixes. + + Tavmjong Bah has updated his online book, A Guide to Inkscape + (http://tavmjong.free.fr/INKSCAPE/MANUAL/html/index.php), to cover + the Inkscape 0.43 features. This guide is not included with the Inkscape + release. Users are encouraged to read the guide in addition to these + release notes and the help included with Inkscape. + +Connectors + + * Inkscape now includes preliminary support for connectors. Connectors + are lines drawn between objects, that stay connected to the objects as + these objects are manipulated. Any object may have a "connector-avoid" + property, which, when set, causes connectors to automatically route + around the object. + + * The Connector tool (Ctrl+F2 or the o key) is a new way of creating and + rerouting connectors, as well as marking objects "avoided" for the + purpose of routing connectors. + + * A new connector can be drawn by clicking and dragging from any + point on the canvas. The connector is finalized when the mouse is + released. Connectors can also be created with two clicks, rather + than click-and-drag, if this is preferred. In this case, click once + on an empty point on the canvas to begin drawing the connector, + then move the mouse to the new connector's target point and then + click again to finalize the connector. Single clicking on a canvas + object selects/deselects that object, just as in other tools. + + * Connection point handles are shown while the mouse cursor is + hovering over a non-connector object in the connector tool. + Currently they are shown only at the center of objects. When + creating a connector, if the connector is started or ended over a + connection point then the connector will be attached to that + object. From then on the connector will be automatically rerouted + whenever the attached object is moved. + + * Connectors attached to objects are currently drawn to the bounding + box of those objects. It is planned that they will be drawn instead + to the edges of objects. + + * A selected connector will show two endpoint handles. By clicking + and dragging these, the connector can be rerouted and + attached/detached from objects. + + * The Make connectors avoid selected objects button marks all objects + in the selection as "avoided", causing all current and future + connectors to automatically avoid these objects. + + * The Make connectors ignore selected objects button marks all + objects in the selection as "ignored", causing all current and + future connectors to completely ignore these objects. This is the + default for all canvas items, i.e., no objects are automatically + routed around by default. + +Inkboard + + A first release of the Inkboard collaborative editing system (also known + as a "white board") is present in this version of Inkscape. + + * Inkboard must be enabled at compile time by passing --enable-inkboard + to the configure script: Inkboard has known bugs, and may present + security issues. + + * Inkboard uses the XMPP (http://www.xmpp.org/) protocol (used by Jabber + (http://www.jabber.org/)) to link together Inkscape clients in a + shared document session. Therefore, if you have a Jabber account, you + can use Inkboard. (There are some exceptions, which are listed below + in the "Known issues" section.) Inkboard uses the Loudmouth + (http://loudmouth.imendio.org/) library for Jabber connectivity; + versions 0.17.2 and above of the Loudmouth library are known to work. + + * Inkboard sessions may occur between two users or a group of users in a + chatroom setting. + + Inkboard usage + + * You must first connect to a Jabber server before sharing a document. + To do this, go to Whiteboard -> Connect to Jabber server. You will be + prompted to enter a server name, your username, and password. You may + specify a specific port to connect on, and whether or not you would + like to connect via SSL. + + * After connecting, you may establish a session with another user or a + chatroom. To connect to another user, go to Whiteboard -> Share with + user. Inkboard can import your Jabber contact list, and will present a + list of online contacts to you. You may select any contact in the + contact list, or enter a Jabber ID to connect to. + + * Similarly, you can establish a connection with a chatroom by going to + Whiteboard -> Share with chatroom. + + * If you are contacted by another user, Inkscape will present a dialog + telling you that you have received an invitation. The dialog contains + the Jabber ID of the user contacting you, and offers you three + choices: decline the invitation, accept the invitation, or accept the + invitation in a new window. + + * Inkboard can record a session's contents for playback at a later time. + + * If you are establishing a session, click the Write session file + checkbox in the share with user dialog to enable session + recording. You will need to provide the name of a file to which + the session contents can be written. + * If you are accepting a session invitation, click the Write + session file checkbox in the invitation dialog to enable session + recording. You will need to provide the name of a file to which + the session contents can be written. + * To play back a session, go to Whiteboard -> Open session file. + + * The Whiteboard -> Dump XML tracker menu item is intended for debugging + purposes only. + +Pressure and tilt sensitivity + + Support for extended input devices has been added. + + * The Calligraphy tool now has optional pressure and tilt support from + an input device such as a tablet. Pressure can be used to alter the + width of the pen and tilt can be used to alter the angle of the pen's + nib. + + * A standard input device dialog has been added (in File menu). Input + device settings are saved to and loaded from the preferences. + +Node tool + + * Clicking on a selected path selects the two nodes closest to the click + point. Shift+click adds or removes these two nodes to the node + selection (when only one path is selected; otherwise Shift+click works + as in Selector). + + * Double click or Ctrl+Alt+click anywhere on the selected path (even if + it is under other objects) creates a new node at the click point, + without changing the shape of the path. (Previously, you could only + add a node in the middle of a segment by using a toolbar button.) + + * You can now edit the selected path (even if it's under other objects) + by dragging any curve point, not only node(s) as before. In many cases + it's a much more convenient way to reshape paths than anything + available before. When you drag a curve close enough to one of the + nodes, only that node's handle(s) are affected; if you drag a point + midway between two nodes, both nodes' handles are adjusted. + + * When mouse is over a draggable path, the cursor is changed to + include a hand. + + * As in Selector, if you press Shift before starting to drag, you always + get a node selection rubberband rectangle (even if you start on a path + but not a node!). + + * After duplicating (Shift+D) an endnode, the selected node is always + the new endnode, so you can move it at once. + + * Selected nodes are displayed a little larger than non-selected ones. + +Extensions + + * Add Nodes: Adds nodes to the selected paths. Each segment of the + selected path is subdivided into ceil(Length/Max) equal length + segments. Lengths are measured in SVG User Units calculated from the + path data and does not take into account any transforms. + + * Whirl: Twists the selected paths around the specified center point. + + * Summer's Night: Linearly distorts a path into the destination + quadrilateral. The destination quadrilateral is specified by a four + node path (closed or not). To use, draw and position a four node path. + Select the four node path first and then add to selection the path you + wish to distort. The original position of the four nodes is considered + to be clockwise around the bounding box of the path to distort + beginning in the upper left corner. + + * The Wavy extension is renamed to Function Plotter and got many fixes + and improvements. Importantly, now you don't have to provide an + analytic formula for the derivative; instead, check the "Calculate the + first derivative numerically" checkbox and it will itself calculate + the angle at each node. In the function/derivative formulas, you can + use functions from the math (http://docs.python.org/lib/module-math.html) + and random (http://docs.python.org/lib/module-random.html) Python + modules. As before, you need to have a rectangle selected before calling + this extension. + + * Development continues on SVGSlice but it has not yet been fully + integrated into Inkscape. Please visit Digital Unleashed + (http://www.digitalunleashed.com/giving.php) for details and downloads. + +More new functionality + + * A separate project, the Open Clip Art Library Browser provides an easy + way to browse local and remote clipart collections and insert clipart + into Inkscape. Please visit + http://www.python.org/pypi/clipartbrowser/0.41 for details and + downloads. (A Google SoC project.) + + * A separate utility has been developed to convert between DXF and SVG + formats. Please visit http://sourceforge.net/projects/dxf-svg-convert + for details and downloads. (A Google SoC project.) + + * Improved support for viewBox: If the root element of your + document has width/height attributes set in percentage units and + there's a viewBox on that element, then: + + * The canvas size is set to the value of the viewBox attribute. + * Changing the canvas size in Document Preferences sets the + viewBox, without touching the width/height values. + + This does not affect regular documents created in Inkscape, but + makes it easier to edit other SVG files that use viewBox. + + * The new command line parameter, --export-area-snap, used with bitmap + export to snap the export area outwards to the nearest integer SVG + user unit (px) values. If you are using the default export resolution + of 90dpi and your graphics are pixel-snapped to minimize antialiasing, + this switch allows you to preserve this alignment even if you are + exporting an area (for example, with --export-id or + --export-area-drawing) which is itself not pixel-aligned. + + * When saving as Postscript, you now have the option to convert or not + convert texts to paths (previously only available for EPS export). + +Interface and usability + + * The Icon Preview dialog has been improved. A toggle has been added to + switch between previewing the entire document or just the current + selection. A larger 128x128 size has been added to the defaults. The + sizes are now read from the preferences file and can be customized. + + * Rectangles and ellipses now use different handle shapes, so it's much + easier to see which handle does what. The two square handles change + the size of the object, while the two round handles adjust the + rounding corners (in rectangles) and arc/segment ends (in ellipses). + + * The controls for the Rectangle tool now include W and H fields for + setting the width/height of selected rectangle(s) numerically. + + * In the controls of Rectangle and Ellipse tools, the "Not rounded" and + "Make whole" buttons are now grayed out when the selected object + cannot use the corresponding function (i.e. when a rectangle is + already not rounded and the ellipse is already whole, which are the + defaults). + + * When editing text with the Text tool, the keypad + and - keys type the + corresponding characters if NumLock is on (otherwise they zoom in and + out as before). (Still does not work on Windows.) + + * In the Text tool, Ctrl+Up and Ctrl+Down now move one paragraph up or + down correspondingly. + + * The Calligraphic tool, in addition to the Ctrl+F6 shortcut, has a new + one-letter shortcut, `c'. + + * The Pen, Pencil, and Calligraphy tools finally have mouse cursors of + their own. + + * The canvas width/height fields in Document Preferences are never + grayed out. Instead, the menu of the canvas sizes scrolls itself to + "Custom" or to an appropriate standard size as you edit width/height. + + * Rectangle editing handles now snap to grid/guides (snapping for other + shapes' handles is expected to come in subsequent releases). + + * The pattern move handle is restricted to horizontal/vertical when Ctrl + is pressed. + + * In the Selector, dragging the rotation center handle snaps to the + edges and central axes of the selection's bounding box. + + * In the Pen tool, while you are drawing a path, the statusbar displays + the distance and angle of the current mouse point from the last + created node of the path. This makes it easy to create a path from the + given lengths and angles of linear segments. When you are dragging to + create a curve handle, the statusbar also displays the length and the + angle of the handle. + + * A new preference option, Compass-like angle display (in the Steps + tab), allows you to have absolute angles specified in a compass + notation (0 at north, 0 to 360 range, increasing clockwise) instead of + the default trigonometric notation (0 at east, -180 to 180 range, + increasing counterclockwise). This affects the statusbar angle display + for path segments and the handles in Pen and Node tools. + + * The Pen and Pencil tools now display helpful statusbar hints when the + mouse is over one of the end anchors of the selected path. + + * The precision of most editable length fields is increased from 0.01 to + 0.001. + + * The minimum zoom is extended from 4% to 1%. + + * Work has begun on menu sensitivity and configurability, but has been + disabled in the release. + +Packaging, documentation, examples + + * The windows installer has now a modular structure that allows the + selection of separate features such as examples, tutorials, or + translations. All options are supported for a silent installation. + * Windows packages now contain the release notes (NEWS file), authors + and translators lists, the README file, the GPL and the LGPL license + files. + * The Inkscape man page is updated with additional examples. + * The About dialog now more closely resembles the stock Gtk About + dialog. A full list of authors and translators, as well as the license + are now viewable. + +Translations + + * The MacOS X package now includes interface translations and reads the + user language setting, as specified in System Preferences, to use the + corresponding translation language. + * Many interface and tutorial translations have been updated. + +Important bugfixes + + * A systematic error when scaling objects with stroke via the Selector + controls panel (W and H fields) is fixed. + * In stroke dash patterns in CSS, comma separators were erroneously + replaced by spaces upon writing the document. For now, Inkscape will + still be capable of reading both space-separated and comma-separated + lists (for compatibility with old files), but it now always writes + correct comma-separated lists on output. + * Due to a bug, Inkscape tended to replace relative paths to embedded + images by absolute, which made them fail after moving a document to + another computer; this is fixed. + * The precision of most boolean operations and offsets is improved, + especially noticeably for small paths. + * In text on path, in some cases letters were distributed unevenly along + a curve; this is now fixed. + * Searching by text in the Find dialog (Ctrl+F) was broken, now fixed. + * Some of the stock markers were missing in the marker menus in the Fill + & Stroke dialog. + * The bounding box of a stroke with markers now includes the markers. + +Internal progress + + * Source documentation: the big goal is to have a brief description for + classes and most functions in every source file; this now holds for + more than 100 files of the 1350 files in the source code. The doxygen + index file now shows many useful links to external documentation and a + categorization of main directory files which should be useful for + beginners in particular. + * Removed trailing fractional zeros in SVG for cleaner and more compact + markup. + * C++ Encapsulation: the View class hierarchy has been reimplemented in + C++, after separating the widget classes from each class. The number + of dependencies on the central file desktop.h (about 100) was reduced + by half. + +Known issues + + Windows 95/98/ME support + + * Due to issues in GTK 2.8 beyond our control this version of Inkscape + will not work on Windows 95/98/ME. Please do not send us crash reports + from those platforms. We hope to be able to resume support for these + platforms in the future, but no specific committments can be made at + this point. + + Problems on Linux under KDE + + * SuSE, Fedora Core 4: Inkscape and other GTK programs are known to + crash if the KDE Baghira theme and the package gtk_qt_engine are + installed. If you experience Inkscape crashes on KDE, please try to + install a different theme from Baghira, or uninstall the gtk_qt_engine + package from your system. + * Kubuntu: For similar reasons, Inkscape can crash on Kubuntu Breezy + when, at the same time, the gtk2-engines-smooth package is installed. + Removing it resolves the problem. Both problems also affect older + versions of Inkscape. + + Pressure and tilt sensitivity + + * Pressure and tilt sensitivity do not currently work on MacOS X, due to + a limitation of the MacOS X version of X11. + * There are known issues with the current version of the X.org server + not releasing events on extended devices that use pressure + sensitivity. What that translates to is you can start a stroke, but + when you lift your pen, the stroke won't end (and will just continue + when you put your pen back on the tablet). This seem to be linked to + the usage of /dev/psaux for the mouse instead of /dev/input/mouseXX, + see http://linuxwacom.sourceforge.net/index.php/howto/mouse1) + * The current version of GTK for Windows has a bug that affects tilt + sensitivity. + + Inkboard + + * Imported bitmaps are not transmitted to other users in a whiteboard + session. + * At present, Inkboard relies on Loudmouth + (http://loudmouth.imendio.org/) to provide Jabber connectivity, + which means that it is limited to Linux builds of Inkscape. + Inkboard is currently being redesigned to use a cross-platform + Jabber client; this redesign will be present in a future release. + * Inkboard cannot yet connect to Google Talk clients. This will be + remedied in a future release. (The reason is because it expects the + "server" portion of a Jabber ID to be the same as the server that it + contacts, which is not the case for the Google Talk network.) + * Inkboard's handling of concurrent modifications is still very rough. + Future releases will make this more robust. + + See http://sourceforge.net/tracker/?group_id=93438&atid=604306 for a + full list of known issues. If you find a bug not listed here, then please + report the bug: see instructions at http://inkscape.org/report_bugs.php + (the Report Bugs link from http://inkscape.org/). + +Previous releases + + * ReleaseNotes042 (http://inkscape.org/cgi-bin/wiki.pl?ReleaseNotes042) + * ReleaseNotes041 (http://inkscape.org/cgi-bin/wiki.pl?ReleaseNotes041) + * ReleaseNotes040 (http://inkscape.org/cgi-bin/wiki.pl?ReleaseNotes040) + * ReleaseNotes039 (http://inkscape.org/cgi-bin/wiki.pl?ReleaseNotes039) + * ReleaseNotes038 (http://inkscape.org/cgi-bin/wiki.pl?ReleaseNotes038) + * ReleaseNotes037 (http://inkscape.org/cgi-bin/wiki.pl?ReleaseNotes037) + * ReleaseNotes036 (http://inkscape.org/cgi-bin/wiki.pl?ReleaseNotes036) + * ReleaseNotes035 (http://inkscape.org/cgi-bin/wiki.pl?ReleaseNotes035) diff --git a/README b/README new file mode 100644 index 000000000..66fe6f2eb --- /dev/null +++ b/README @@ -0,0 +1,75 @@ + +Inkscape. Draw Freely. +====================== + +http://www.inkscape.org/ + +Inkscape is an open source drawing tool with capabilities similar to +Illustrator, Freehand, and CorelDraw that uses the W3C standard scalable +vector graphics format (SVG). Some supported SVG features include +basic shapes, paths, text, markers, clones, alpha blending, transforms, +gradients, and grouping. In addition, Inkscape supports Creative Commons +meta-data, node-editing, layers, complex path operations, text-on-path, +and SVG XML editing. It also imports several formats like EPS, Postscript, +JPEG, PNG, BMP, and TIFF and exports PNG as well as multiple vector-based +formats. + +Inkscape's main motivation is to provide the Open Source community +with a fully W3C compliant XML, SVG, and CSS2 drawing tool. Additional +planned work includes conversion of the codebase from C/Gtk to C++/Gtkmm, +emphasizing a lightweight core with powerful features added through +an extension mechanism, and the establishment of a friendly, open, +community-oriented development processes. + +Inkscape uses the standard procedure for compilation and installation: + + ./configure + make + make install + +If a "./configure" file is not present, you can create it by running +the "./autogen.sh" command, which calls in turn a number of other +programs such as automake and autoconf. See INSTALL for more +details. + + +Required Dependencies +===================== +The Inkscape core depends on several other libraries that you will need +install, if they're not already present on your system. The most +typical libraries you may need to install are: + + * Boehm-GC + * libsigc++ + * glibmm + * gtkmm + +Please see http://www.inkscape.org/cgi-bin/wiki.pl?CompilingInkscape for the +most current dependencies, including links to the source tarballs. + + +Extension Dependencies +====================== +Inkscape also has a number of extensions for implementing various +features such as support for non-SVG file formats, etc. In theory, all +extensions are optional, however in practice you will want to have these +installed and working. Unfortunately, there is a great deal of +variability in how you can get these functioning properly. Here are +some recommendations: + +First, make sure you have Perl and Python. If you're on Windows you +should also install Cygwin. + +Next, you'll need to ensure the dependencies for each extension is +present. Depending on which extensions you need, the dependencies are +going to vary, but here are some you may need to install: + + * XML::Parser + * XML::XQL + +If you install dependencies to non-standard locations, such as +installing XML::Parser someplace in your home directory, you may need to +take some extra steps to indicate where those dependencies are to be +found. For instance, with Perl modules, set the PERLLIB or PERL5LIB +variable (see `man perlrun`) + diff --git a/README.ca.txt b/README.ca.txt new file mode 100755 index 000000000..5080d83ab --- /dev/null +++ b/README.ca.txt @@ -0,0 +1,44 @@ + +Inkscape. Dibuixeu amb llibertat +================================ + +http://www.inkscape.org/ + + +L'Inkscape és una eina de dibuix de codi obert amb capacitats semblants +a l'Illustrator, Freehand i CorelDraw, que usa el format estàndard del W3C +per a gràfics vectorials escalables. Algunes de les característiques SVG +suportades inclouen formes bàsiques, camins, textos, marcadors, clons, +composició amb transparències, transformacions, degradats i agrupament. +A més, l'Inkscape treballa amb metadades de Creative Commons, edició de nodes, +capes, operacions complexes amb camins, text en camins i edició XML d'SVG. +També importa diferents formats, com EPS, Postscript, JPEG, PNG, BMP i TIFF +i exporta a PNG, així com múltiples formats basats en vectors. + +La motivació principal d'Inkscape és proporcionar a la comunitat Open Source +una eina de dibuix que s'ajusti completament als estàndards del W3C XML, SVG +i CSS2. Està planejada la conversió del codi base de C/Gtk a C++/Gtkmm, +posant èmfasi a un nucli lleuger amb potents característiques afegides +mitjançant un mecanisme d'extensions, i l'establiment d'un procés de +desenvolupament amicable, obert i orientat a la comunitat. + +L'Inkscape usa el procediment estàndard per a compilació i instal·lació: + + ./configure + make + make install + +Si no trobeu el fitxer "./configure", podeu crear-lo executant l'ordre +"./autogen.sh", que crida a d'altres programes diferents com l'automake +i l'autoconf. Veieu INSTALL per a més detalls. + +Podeu consultar a http://www.inkscape.org/cgi-bin/wiki.pl?CompilingInkscape les +dependències més habituals. + +Feu-nos saber si heu modificat l'Inkscape d'alguna manera usable. + +Veieu el fitxer HACKING per a més informació sobre el desenvolupament +d'Inkscape. + +La versió en català d'Inkscape ha estat desenvolupada per Softcatalà: +http://www.softcatala.org/. diff --git a/README.de.txt b/README.de.txt new file mode 100644 index 000000000..ba07d34dd --- /dev/null +++ b/README.de.txt @@ -0,0 +1,40 @@ +Inkscape. Frei zeichnen. +======================== + +http://www.inkscape.org/ + +Inkscape ist ein quelloffenes Zeichenwerkzeug mit Fähigkeiten ähnlich +wie Illustrator, Freehand und CorelDraw. Es verwendet das vom W3C +(Web Consortium) standardisierte SVG-Format, das vektorbasiert und damit +beliebig skalierbar ist. Unterstützte SVG-Features sind unter anderem +die grundlegenden Formen, Pfade, Text, Marker, Klone, Alpha Blending, +Transforms, Gradienten und Gruppierung. Außerdem werden Creative Commons- +Metadata, das Editieren von Knoten, Layer, komplexe Pfadoperationen, +Text-auf-Pfad und direktes XML-Editieren unterstützt. Das Programm kann +Dokumentformate wie EPS, Postscript, JPEG, PNG, BMP und TIFF importieren +und exportiert PNG ebenso wie mehrere vektorbasierte Formate. + +Das Hauptziel von Inkscape besteht darin, der Open Source Gemeinschaft +ein Zeichen-Tool zur Verfügung zu stellen, welches die W3C-Standards +XML, SVG und CSS2 vollständig implementiert. Zusätzlich ist Arbeit am +Programmcode geplant; dieser soll von C/Gtk nach C++/Gtkmm konvertiert +werden, und so einen leichtgewichtigen Kern mit mächtigen Features betonen, +die über einen Erweiterungsmechanismus ('extensions') angehängt werden. +Nicht zuletzt geht es auch um die Einrichtung eines freundlichen, offenen, +community-orientierten Entwicklungsprozesses. + +Inkscape nutzt die Standardprozedur für Compilation und Installation: + + ./configure + make + make install + +Detalliertere Information hierzu siehe in der Datei INSTALL. +Wg. Voraussetzungen und Abhängigkeiten von anderer Software +siehe http://www.inkscape.org/cgi-bin/wiki.pl?CompilingInkscape + +Wenn Sie inkscape in einer neuen, brauchbaren Weise verändern, +lassen Sie uns an den Änderungen teilhaben. + +Lesen Sie bitte auch die Datei HACKING_de mit mehr Info, was +Entwicklung von Inkscape angeht. diff --git a/README.es.txt b/README.es.txt new file mode 100644 index 000000000..8ca8a2ce0 --- /dev/null +++ b/README.es.txt @@ -0,0 +1,75 @@ + +Inkscape. Dibuja en libertad. +============================= + +http://www.inkscape.org/ + +Inkscape es una herramienta de dibujo de código abierto con capacidades +similares a Illustrator, Freehand y CorelDraw, que utiliza el formato estándar +para gráficos vectoriales escalables (SVG = scalable vector graphics) del W3C. +Algunas de las características de SVG incluidas son: formas básicas, trazos, +texto, marcadores, clones, mezclas alfa, transformaciones, degradados y +agrupación. Además Inkscape permite la inclusión de metadatos de Creative Commons, +edición de nodos, capas, operaciones complejas con trazos, textos en trayectos +y edición de XML SVG. También importa varios formatos, por ejemplo, EPS, +Postscript, JPEG, PNG, BMP y TIFF y exporta en PNG, así como en varios formatos +basados en vectores. + +La principal motivación de Inkscape es la de proporcionar a la comunidad de +código abierto con una herramienta de dibujo que cumpla con las especificaciones +XML, SVG y CSS2 del W3C. Entre las tareas planeadas adicionales se encuentra la +conversión del código de C/Gtk a C++/Gtkmm, haciendo hincapié en un núcleo +ligero con la posibilidad de añadir características potentes a través de un +mecanismo de extensiones y el establecimiento de un proceso de desarrollo +amistoso, abierto y orientado a la comunidad. + +Inkscape utiliza el procedimiento estándar para su compilación e instalación: + +./configure make make install + +Si no existe un archivo «./configure» puede crearlo al ejecutar el comando +«./autogen.sh» que, a su vez, llamará a otros programas como automake y autoconf. +Vea el archivo INSTALL para obtener más detalles. + + +Dependencias requeridas +===================== +El núcleo de Inkscape depende de varias otras bibliotecas que necesitará +instalar si no existen ya en su sistema. Las bibliotecas que normalmente +necesitará instalar son: + + * Boehm-GC + * libsigc++ + * glibmm + * gtkmm + +Acceda a http://www.inkscape.org/cgi-bin/wiki.pl?CompilingInkscape para obtener +una lista de las dependencias más actuales, además de los enlaces a los paquetes +de código fuente. + + +Dependencias de extensiones +====================== +Inkscape también dispone de varias extensiones que desarrollan algunas +características como el soporte para formatos de archivos distintos de SVG, etc. +Teóricamente todas las extensiones son opcionales, aunque en la practica querrá +tenerlas instaladas y funcionando. Desafortunadamente hay una gran variedad de +formas de conseguir que éstas funcionen correctamente. He aquí algunas +recomendaciones: + +En primer lugar, asegúrese de que tiene Perl y Python. Si utiliza windows +también debería instalar Cygwin. + +Además deberá asegurarse de que estén presentes las dependencias de cada +extensión. Las dependencias variarán según las extensiones que necesite; aquí hay +algunas que necesitará instalar: + + * XML::Parser + * XML::XQL + +Si instala dependencias en rutas que no son las habituales, como por ejemplo +instalar XML::Parser en algún lugar de su directorio personal, deberá dar +algunos pasos más para indicar dónde se encuentran esas dependencias. Por ejemplo, +con los módulos de Perl, ajuste la variable PERLLIB o PERL5LIB (véase +«man perlrun») + diff --git a/README.fr.txt b/README.fr.txt new file mode 100644 index 000000000..074cbdda6 --- /dev/null +++ b/README.fr.txt @@ -0,0 +1,76 @@ +Inkscape. Dessinez librement. +============================= + +http://www.inkscape.org/ + +Inkscape est un logiciel de dessin vectoriel libre avec des possibilités +similaires à celles d'Illustrator, Freehand ou CorelDraw et utilisant le format +standard du W3C "scalable vector graphics" (SVG). Formes basiques, chemins, +texte, marqueurs, clonage, transparence, transformations, dégradés et groupage +figurent parmi les fonctionnalités SVG supportées. De plus, Inkscape supporte +les meta-données Creative Commons, l'édition de nœuds, les calques, les +opérations complexes sur les chemins, le texte suivant un chemin, et l'édition +du SVG XML. Il peut aussi importer depuis plusieurs formats comme EPS, +Postscript, JPEG, PNG, BMP, et TIFF et exporter en PNG aussi bien qu'en de +nombreux formats vectoriels. + +Le but principal d'Inkscape est de fournir à la communauté du logiciel libre +un outil de dessin totalement conforme aux spécifications XML, SVG et CSS2 du +W3C. De plus les tâches planifiées incluent la conversion du code de C/Gtk en +C++/Gtkmm, la mise en valeur d'un noyau léger avec des fonctionnalités ajoutées +par un mécanisme d'extension, et l'établissement d'un processus de +développement amical, ouvert et tourné vers la communeauté. + +Inkscape se compile et s'installe selon la procédure standard : + + ./configure + make + make install + +Si le fichier "./configure" n'est pas présent, vous pouvez le créer en +exécutant la commande "./autogen.sh", qui appelle alternativement d'autres +programmes tels que automake et autoconf. Consultez le fichier INSTALL pour de +plus amples détails. + + +Dépendances nécessaires +======================= +Le cœur d'Inkscape dépend de plusieurs autres bibliothèques qu'il vous faudra +installer si elle ne sont pas déjà présentes sur votre système. Typiquement, +vous devriez avoir à installer : + * Boehm-GC + * libsigc++ + * glibmm + * gtkmm + +Veuillez consulter http://www.inkscape.org/cgi-bin/wiki.pl?CompilingInkscape +pour les dépendances les plus courantes, cette page comportant aussi des liens +les fichiers sources (au format .tar.gz) + + +Dépendances pour les extensions +=============================== +Inkscape comporte aussi un certain nombre d'extensions apportant diverses +fonctionnalités (comme le support de formats de fichiers autres que le SVG...). +En théorie toutes les extensions sont optionnelles; cependant, en pratique, +vous voudrez sans doute les installer et faire fonctionner. Malheureusement, +leur bon fonctionnement peut beaucoup varier. Voici quelques recommandations : + +D'abord, vérifiez que Python et Perl sont bien installés. Sous Windows, +installez aussi Cygwin. + +Ensuite, assurez-vous que les dépendances nécessaires à chaque extension sont +présentes. Ces dépendances varient en fonction des extensions dont vous avez +besoin, mais en voici que vous devriez installer de toute façon : + * XML::Parser + * XML::XQL + +Si vous installez des dépendances dans des emplacements non standards (ex : si +vous installez XML::Parser dans votre répertoire personnel), il vous faudra +peut-être effectuer quelques étapes supplémentaires afin d'indiquer où ces +dépendances peuvent être trouvées. Par exemple, pour les modules Perl, il vous +faut définir les variables PERLLIB ou PERL5LIB (voyez 'man perlrun'). + + + +Traduction par Matiphas (matiphas _chez_ free point fr), 2005. diff --git a/README.it.txt b/README.it.txt new file mode 100644 index 000000000..88361ee7a --- /dev/null +++ b/README.it.txt @@ -0,0 +1,38 @@ + +Inkscape. Disegna in Libertà. +============================= + +http://www.inkscape.org/ + +Inkscape è un programma open source per il disegno, simile a Illustrator, +Freehand e CorelDraw, che si basa sul formato standard W3C "scalable vector +graphics" (SVG). Tra le caratteristiche supportate da SVG vi sono le forme base, +i tracciati, i testi, i segnali, i cloni, le trasparenze, le trasformazioni, +i gradienti e i gruppi. Inkscape supporta inoltre i meta-dati Creative Commons, +la modifica sui nodi, i livelli, le operazioni complesse sui livelli, i testi su +tracciato e la modifica dell'XML SVG. Può importare da diversi formati come EPS, +Postscript, JPEG, PNG, BMP e TIFF e esportare in PNG ed in altri formati basati su +vettori multipli. + +Lo scopo principale di Inkscape è quello di fornire alla comunità Open Source uno +strumento di disegno che rispetti pienamente gli standard W3C XML, SVG e CSS2. +Inoltre il piano di sviluppo prevede una conversione del codice da C/Gtk a C++/Gtkmm, +maggiore importanza all'aggiunta di funzioni tramite il meccanismo delle estensioni e +la creazione di un processo di sviluppo aperto, collaborativo e orientato alla comunità. + +Inkscape usa la procedura standard per la compilazione e l'installazione: + + ./configure + make + make install + +Se il file "./configure" non esiste, lo puoi creare con il comando "./autogen.sh", +che si basa su altri programmi quali automake e autoconf. Consulta il file INSTALL +per ulteriori dettagli. + +Visita http://www.inkscape.org/cgi-bin/wiki.pl?CompilingInkscape per la più +recente lista delle dipendenze. + +Se apporti delle modifiche utili ad Inkscape, condividile con la comunità. + +Per ulteriori informazioni sullo sviluppo di Inkscape, consulta il file HACKING_it. diff --git a/TRANSLATORS b/TRANSLATORS new file mode 100644 index 000000000..722af5433 --- /dev/null +++ b/TRANSLATORS @@ -0,0 +1,64 @@ +Adib Taraben , 2004. +Alastair McKinstry , 2000. +Aleksandar UroÅ¡ević +Alessio Frusciante , 2002, 2003. +Alexandre Prokoudine , 2005. +Alexey Remizov , 2004. +Álvaro Lopes , 2001, 2002 +Andreas Hyden , 2000. +Arman Aksoy , 2003. +Arpad Biro , 2004, 2005. +Benedikt Roth , 2000 +BoÅ¡tjan Å petič , 2004, 2005. +Brisa Francesco , 2000. +bulia byak , 2004. +Christian Meyer , 2000-2002. +Christian Neumair , 2002, 2003. +Christian Rose , 2000, 2001, 2002, 2003. +Christophe Merlet (RedFox) , 2000-2002. +Colin Marquardt , 2004, 2005. +Daniel Díaz , 2004 +Александар Урошевић +Didier Conchaudron , 2003. +Duarte Loreto 2002,2003 (Maintainer) +Fatih Demir , 2000. +Francesc Dorca , 2003. Traducció sodipodi. +Francisco Javier F. Serrador , 2003. +Francisco Xosé Vázquez Grandal , 2001. +Frederic Rodrigo , 2004-2005. +Ge'ez Frontier Foundation , 2002. +Jörg Müller , 2005. +Jeroen van der Vegt , 2003, 2005. +Jose Antonio Salgueiro Aquino , 2003. +Josef Vybiral , 2005. +Juarez Rudsatz , 2004 +Junichi Uekawa , 2002. +Kai Lahmann , 2000 +Karl Ove Hufthammer , 2004, 2005. +Keld Simonsen , 2000-2001. +Kjartan Maraas , 2000-2002. +Lauris Kaplinski , 2000. +Luca Bruno , 2005. +Lucas Vieites Fariña, 2003-2005. +Martin Srebotnjak, , 2005. +Masatake YAMATO , 2002. +Matiphas , 2004. +Mattias Hultgren , 2005. +Maxim Dziumanenko , 2004 +Mitsuru Oka , 2002. +Mufit Eribol , 2000. +Quico Llach , 2000. Traducció sodipodi. +Raymond Ostertag , 2002-2003. +shivaken , 2004. +Simos Xenitellis , 2001. +Takeshi Aihana , 2000-2001. +Jose Antonio Salgueiro . +Valek Filippov , 2000, 2003. +Vincent van Adrighem , 2003. +Vital Khilko , 2003 +Vitaly Lipatov , 2002, 2004. +Wang Li , 2002 +Xavier Conde Rueda , 2004, 2005 +Yukihiro Nakai , 2000, 2003. +Yuri Syrota , 2000. +Zdenko Podobný , 2003, 2004. diff --git a/autogen.sh b/autogen.sh new file mode 100755 index 000000000..9342738d6 --- /dev/null +++ b/autogen.sh @@ -0,0 +1,200 @@ +#!/bin/sh + +# This script does all the magic calls to automake/autoconf and +# friends that are needed to configure a cvs checkout. As described in +# the file HACKING you need a couple of extra tools to run this script +# successfully. +# +# If you are compiling from a released tarball you don't need these +# tools and you shouldn't use this script. Just call ./configure +# directly. + + +PROJECT="Inkscape" +TEST_TYPE=-f +FILE=inkscape.spec.in + +AUTOCONF_REQUIRED_VERSION=2.52 +AUTOMAKE_REQUIRED_VERSION=1.7 +GLIB_REQUIRED_VERSION=2.0.0 +INTLTOOL_REQUIRED_VERSION=0.17 + +srcdir=`dirname $0` +test -z "$srcdir" && srcdir=. +ORIGDIR=`pwd` +cd $srcdir + +${srcdir}/tools-version.sh + +check_version () +{ + if expr $1 \>= $2 > /dev/null; then + echo "yes (version $1)" + else + echo "Too old (found version $1)!" + DIE=1 + fi +} + +attempt_command () { + IGNORE=$1 + shift + + echo "Running $@ ..." + ERR="`$@ 2>&1`" + errcode=$? + if [ "x$IGNORE" = "x" ]; then + ERR=`echo "$ERR"` + else + ERR=`echo "$ERR" | egrep -v "$IGNORE"` + fi + if [ "x$ERR" != "x" ]; then + echo "$ERR" | awk '{print " " $0}' + fi + if [ $errcode -gt 0 ]; then + echo "Please fix the error conditions and try again." + exit 1 + fi +} + +echo +echo "I am testing that you have the required versions of libtool, autoconf," +echo "automake, glib-gettextize and intltoolize. This test is not foolproof and" +echo "if anything goes wrong, there may be guidance in the file HACKING.txt" +echo + +DIE=0 + +echo -n "checking for autoconf >= $AUTOCONF_REQUIRED_VERSION ... " +if (autoconf --version) < /dev/null > /dev/null 2>&1; then + VER=`autoconf --version \ + | grep -iw autoconf | sed "s/.* \([0-9.]*\)[-a-z0-9]*$/\1/"` + check_version $VER $AUTOCONF_REQUIRED_VERSION +else + echo + echo " You must have autoconf installed to compile $PROJECT." + echo " Download the appropriate package for your distribution," + echo " or get the source tarball at ftp://ftp.gnu.org/pub/gnu/" + DIE=1; +fi + +echo -n "checking for automake >= $AUTOMAKE_REQUIRED_VERSION ... " +# Prefer earlier versions just so that the earliest supported version gets test coverage by developers. +if (automake-1.7 --version) < /dev/null > /dev/null 2>&1; then + AUTOMAKE=automake-1.7 + ACLOCAL=aclocal-1.7 +elif (automake-1.8 --version) < /dev/null > /dev/null 2>&1; then + AUTOMAKE=automake-1.8 + ACLOCAL=aclocal-1.8 +elif (automake --version) < /dev/null > /dev/null 2>&1; then + # Leave unversioned automake for a last resort: it may be a version earlier + # than what we require. + # (In particular, it might mean automake 1.4: that version didn't default to + # installing a versioned name.) + AUTOMAKE=automake + ACLOCAL=aclocal +else + echo + echo " You must have automake 1.7 or newer installed to compile $PROJECT." + echo " Get ftp://ftp.gnu.org/pub/gnu/automake/automake-1.8.5.tar.gz" + echo " (or a newer version of 1.8 if it is available; note that 1.9 is buggy)" + DIE=1 +fi +if test x$AUTOMAKE != x; then + VER=`$AUTOMAKE --version \ + | grep automake | sed "s/.* \([0-9.]*\)[-a-z0-9]*$/\1/"` + check_version $VER $AUTOMAKE_REQUIRED_VERSION + + # Exclude automake 1.9.[0-6] + if expr $VER \>= 1.9.0 >/dev/null && expr $VER \<= 1.9.6 >/dev/null ; then + echo + echo " You must have automake less than 1.9.0 or newer than 1.9.6" + echo " Get ftp://ftp.gnu.org/pub/gnu/automake/automake-1.8.5.tar.gz" + echo " (or a newer version of 1.8 if it is available)" + DIE=1 + fi +fi + +echo -n "checking for glib-gettextize >= $GLIB_REQUIRED_VERSION ... " +if (glib-gettextize --version) < /dev/null > /dev/null 2>&1; then + VER=`glib-gettextize --version \ + | grep glib-gettextize | sed "s/.* \([0-9.]*\)/\1/"` + check_version $VER $GLIB_REQUIRED_VERSION +else + echo + echo " You must have glib-gettextize installed to compile $PROJECT." + echo " glib-gettextize is part of glib-2.0, so you should already" + echo " have it. Make sure it is in your PATH." + DIE=1 +fi + +echo -n "checking for intltool >= $INTLTOOL_REQUIRED_VERSION ... " +if (intltoolize --version) < /dev/null > /dev/null 2>&1; then + VER=`intltoolize --version \ + | grep intltoolize | sed "s/.* \([0-9.]*\)/\1/"` + check_version $VER $INTLTOOL_REQUIRED_VERSION +else + echo + echo " You must have intltool installed to compile $PROJECT." + echo " Get the latest version from" + echo " ftp://ftp.gnome.org/pub/GNOME/sources/intltool/" + DIE=1 +fi + +if test "$DIE" -eq 1; then + echo + echo "Please install/upgrade the missing tools and call me again." + echo + exit 1 +fi + + +test $TEST_TYPE $FILE || { + echo + echo "You must run this script in the top-level $PROJECT directory." + echo + exit 1 +} + + +if test -z "$ACLOCAL_FLAGS"; then + + acdir=`$ACLOCAL --print-ac-dir` + m4list="glib-2.0.m4 glib-gettext.m4 gtk-2.0.m4 intltool.m4 pkg.m4" + + for file in $m4list + do + if [ ! -f "$acdir/$file" ]; then + echo + echo "WARNING: aclocal's directory is $acdir, but..." + echo " no file $acdir/$file" + echo " You may see fatal macro warnings below." + echo " If these files are installed in /some/dir, set the ACLOCAL_FLAGS " + echo " environment variable to \"-I /some/dir\", or install" + echo " $acdir/$file." + echo + fi + done +fi + +echo "" + +attempt_command 'underquoted definition of|[\)\#]Extending' \ + $ACLOCAL $ACLOCAL_FLAGS + +# optionally feature autoheader +(autoheader --version) < /dev/null > /dev/null 2>&1 && { + attempt_command '' autoheader +} + +attempt_command '' libtoolize --copy --force +attempt_command '' $AUTOMAKE --add-missing +attempt_command '' autoconf +attempt_command '^(Please add the files| codeset| progtest|from the|or directly|You will also|ftp://ftp.gnu.org|$)' \ + glib-gettextize --copy --force +attempt_command '' intltoolize --copy --force --automake + +echo "" +echo "Done! Please run './configure' now." + +cd $ORIGDIR diff --git a/config.h.mingw b/config.h.mingw new file mode 100644 index 000000000..c80c9089b --- /dev/null +++ b/config.h.mingw @@ -0,0 +1,49 @@ +#ifndef _CONFIG_H_ +#define _CONFIG_H_ + +#ifndef WIN32 +#define WIN32 +#endif + +/** + * This is for require-config.h, whose + * purpose I cannot fathom. + */ +#define PACKAGE_TARNAME + +/*###################################### +#### RESOURCE DIRECTORIES +######################################*/ + +#define INKSCAPE_DATADIR "." +#define PACKAGE_LOCALE_DIR "locale" + + +/*###################################### +#### OTHER DEFINITIONS +######################################*/ + +#define GETTEXT_PACKAGE "inkscape" + +#define PACKAGE_STRING VERSION + +#define HAVE_STRING_H 1 +#define HAVE_MALLOC_H 1 +#define HAVE_STDLIB_H 1 +#define HAVE_SYS_STAT_H 1 + +#define ENABLE_NLS 1 +#define HAVE_BIND_TEXTDOMAIN_CODESET 1 + +/* keep binreloc off */ +#define BR_PTHREADS 0 +#undef ENABLE_BINRELOC + +#define PANGO_ENABLE_ENGINE 1 + +#define HAVE_GTK_WINDOW_FULLSCREEN 1 + +#define g_ascii_strtod fixed_g_ascii_strtod + + +#endif /* _CONFIG_H_ */ diff --git a/configure.ac b/configure.ac new file mode 100644 index 000000000..dd3981c60 --- /dev/null +++ b/configure.ac @@ -0,0 +1,818 @@ +dnl Process this file with autoconf to produce a configure script. + +AC_PREREQ(2.50) +AC_INIT(inkscape, 0.43+devel) +dnl N.B. After 0.40, please change to `0.40+cvs' instead of `0.41cvs'. +dnl Rationale: (i) placate simple version comparison software such as +dnl `dpkg --compare-versions'. (ii) We don't always know what the next +dnl version is going to be called until about the time we release it +dnl (whereas we always know what the previous version was called). +AC_CANONICAL_HOST +AC_CONFIG_SRCDIR(src/main.cpp) +AM_INIT_AUTOMAKE + +AM_CONFIG_HEADER(config.h) + +AC_PROG_INTLTOOL(0.22) + +dnl These next few lines are needed only while libcroco is in our source tree. +AC_PROG_CC +AM_PROG_CC_C_O +if test "$GCC" = "yes"; then + # Enable some warnings from gcc. + + # -Wno-pointer-sign is probably new in gcc 4.0; certainly it isn't accepted + # by gcc 2.95. + ink_svd_CFLAGS="$CFLAGS" + CFLAGS="-Wno-pointer-sign $CFLAGS" + AC_COMPILE_IFELSE([int dummy; +], , CFLAGS="$ink_svd_CFLAGS",) + CFLAGS="-Wall -W $CFLAGS" +fi + +AC_LANG(C++) +AC_ISC_POSIX +AC_PROG_CXX +AM_PROG_CC_STDC +AM_PROG_AS +AC_HEADER_STDC + +dnl Honor aclocal flags +ACLOCAL="$ACLOCAL $ACLOCAL_FLAGS" + +dnl RANLIB is outdated now +dnl AC_PROG_RANLIB +AM_PROG_LIBTOOL + +dnl Verify our GCC version +if test "x$GXX" = "xyes"; then + AC_MSG_CHECKING([GNU compiler version]) + + cc_version=["`$CXX $CXXFLAGS -v 2>&1 = 3.0 is needed to compile inkscape]) + fi +fi + +dnl ****************************** +dnl Gettext stuff +dnl ****************************** +GETTEXT_PACKAGE="AC_PACKAGE_NAME" +AC_SUBST(GETTEXT_PACKAGE) +AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE,"$GETTEXT_PACKAGE",[Translation domain used]) +dnl Add the languages which your application supports here. +ALL_LINGUAS="am az be ca cs da de el es es_MX et eu fr ga gl hu it ja mk nb nl nn pa pl pt pt_BR ru sk sl sr sr@Latn sv tr uk zh_CN" +AM_GLIB_GNU_GETTEXT + +AC_PATH_PROG(PKG_CONFIG, pkg-config, no) +if test "x$PKG_CONFIG" = "xno"; then + AC_MSG_ERROR(You have to install pkg-config to compile inkscape.) +fi + +AC_CHECK_LIB(png, png_read_info, [AC_CHECK_HEADER(png.h, png_ok=yes, png_ok=no)], png_ok=no, -lz -lm) +if test "x$png_ok" != "xyes"; then + AC_MSG_ERROR([libpng >= 1.2 is needed to compile inkscape]) +fi + +dnl Handle possible dlopen requirement for libgc +dnl Isn't this internal to something in autoconf? Couldn't find it... +AC_CHECK_LIB([dld], [shl_load], [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld"], [AC_CHECK_FUNC([dlopen], + [lt_cv_dlopen="dlopen"], + [AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], + [AC_CHECK_LIB([svld], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], + [AC_CHECK_LIB([dld], [dld_link], + [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld"]) + ]) + ]) + ]) + ]) + +AC_CHECK_HEADERS([gc.h gc/gc.h], + [ + # To test for the different required libs, I have to + # overcome autoconf's caching system, so I change the + # desired function name. They're all in libgc. + # The "break" will exit from the top level + # AC_CHECK_HEADERS. + gc_libs="" + AC_CHECK_LIB(gc, GC_init, + [gc_ok=yes; + LIBS="-lgc $gc_libs $LIBS"; + break], [gc_ok=no], [$gc_libs]) + gc_libs="-lpthread" + AC_CHECK_LIB(gc, GC_malloc, + [gc_ok=yes; + LIBS="-lgc $gc_libs $LIBS"; + break], [gc_ok=no], [$gc_libs]) + gc_libs="$lt_cv_dlopen_libs" + AC_CHECK_LIB(gc, GC_realloc, + [gc_ok=yes; + LIBS="-lgc $gc_libs $LIBS"; + break], [gc_ok=no], [$gc_libs]) + gc_libs="-lpthread $lt_cv_dlopen_libs" + AC_CHECK_LIB(gc, GC_free, + [gc_ok=yes; + LIBS="-lgc $gc_libs $LIBS"; + break], [gc_ok=no], [$gc_libs]) + break], + [gc_ok=no]) +if test "x$gc_ok" = "xyes"; then + AC_MSG_CHECKING([libgc version 6.4+]) + AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ + #ifdef HAVE_GC_GC_H + # include + #else + # include + #endif + #include + extern unsigned GC_version; + int main(void){ + unsigned min = ((6 << 16) | (4 << 8) | 0); + printf("%d.%d.%d ",GC_version >> 16, (GC_version >> 8) & 0xFF, GC_version & 0xFF); + if (GC_version>=min) return 0; + return 1; + }]])], + [gc_ok=yes], + [gc_ok=no] + ) + AC_MSG_RESULT([$gc_ok]) +fi +if test "x$gc_ok" != "xyes"; then + AC_MSG_ERROR([libgc (the Boehm Conservative Collector) 6.4+, is needed to compile inkscape -- http://www.hpl.hp.com/personal/Hans_Boehm/gc]) +fi + +AC_CHECK_HEADERS([malloc.h]) +AC_CHECK_FUNCS([mallinfo], [ + AC_CHECK_MEMBERS([struct mallinfo.usmblks, + struct mallinfo.fsmblks, + struct mallinfo.uordblks, + struct mallinfo.fordblks, + struct mallinfo.hblkhd],,, + [#include ]) +]) + +AC_PATH_PROG(FREETYPE_CONFIG, freetype-config, no) +if test "x$FREETYPE_CONFIG" = "xno"; then + AC_MSG_ERROR([Cannot find freetype-config]) +fi +FREETYPE_CFLAGS=`$FREETYPE_CONFIG --cflags` +FREETYPE_LIBS=`$FREETYPE_CONFIG --libs` +AC_SUBST(FREETYPE_CFLAGS) +AC_SUBST(FREETYPE_LIBS) + +dnl ****************************** +dnl Win32 +dnl ****************************** +AC_MSG_CHECKING([for Win32 platform]) +case "$host" in + *-*-mingw*) + platform_win32=yes + INKSCAPE_CFLAGS="$INKSCAPE_CFLAGS -mms-bitfields -DLIBXML_STATIC" + ;; + *) + platform_win32=no + ;; +esac +AC_MSG_RESULT([$platform_win32]) +AM_CONDITIONAL(PLATFORM_WIN32, test "$platform_win32" = "yes") + +dnl ****************************** +dnl Xft checking +dnl ****************************** + +AC_ARG_WITH(xft, + AC_HELP_STRING([--with-xft], [use xft scalable font database (default is auto)]), + [with_xft=$withval], [with_xft=auto]) + +if test "x$with_xft" != "xno" ; then + dnl Test fontconfig package + PKG_CHECK_MODULES(XFT, xft, xft_ok=yes, xft_ok=no) + if test "x$xft_ok" != "xyes"; then + dnl test xft package + PKG_CHECK_MODULES(XFT, fontconfig, xft_ok=yes, xft_ok=no) + if test "x$xft_ok" != "xyes"; then + dnl Have to test xft presence + AC_CHECK_HEADER(X11/Xft/Xft.h, xft_ok=yes, xft_ok=no) + if test "x$xft_ok" != "xyes"; then + dnl No xft found + if test "x$with_xft" = "xyes"; then + dnl Xft was explicitly asked, so stop + AC_MSG_ERROR([--with-xft was specified, but appropriate development packages could not be found]) + fi + else + dnl Working Xft1 + XFT_LIBS="-L/usr/X11R6/lib -lXft " + fi + fi + fi +else + dnl Asked to ignore xft + xft_ok=no +fi + +AC_SUBST(XFT_CFLAGS) +AC_SUBST(XFT_LIBS) + +AM_CONDITIONAL(USE_XFT, test "x$xft_ok" = "xyes") +if test "x$xft_ok" = "xyes"; then + AC_DEFINE(WITH_XFT, 1, [Use Xft font database]) +fi + +dnl ****************************** +dnl pangoft2 for xft +dnl ****************************** + +if test "x$xft_ok" = "xyes"; then + PKG_CHECK_MODULES(PANGOFT2, pangoft2, pango_ok=yes, pango_ok=no) + if test "x$pango_ok" = "xyes"; then + XFT_LIBS="$XFT_LIBS $PANGOFT2_LIBS" + fi +fi + +dnl ****************************** +dnl GnomePrint checking +dnl ****************************** + +AC_ARG_WITH(gnome-print, + AC_HELP_STRING([--with-gnome-print], [use gnome print font database and spooler frontend]), + [with_gp=$withval], [with_gp=auto]) + +if test "x$with_gp" = "xyes"; then + dnl Have to test gnome-print presence + PKG_CHECK_MODULES(GNOME_PRINT, libgnomeprint-2.2 >= 1.116.0 libgnomeprintui-2.2 >= 1.116.0, gp=yes, gp=no) + if test "x$gp" != "xyes"; then + dnl No gnome-print found + if test "x$with_gp" = "xyes"; then + dnl Gnome-print was explicitly asked, so stop + AC_MSG_ERROR([--with-gnome-print was specified, but appropriate libgnomeprint development packages could not be found]) + else + # gp is no, tell us for the log file + AC_MSG_RESULT($gp) + fi + fi +else + dnl Asked to ignore gnome-print + gp=no +fi + +AC_SUBST(GNOME_PRINT_CFLAGS) +AC_SUBST(GNOME_PRINT_LIBS) + +AM_CONDITIONAL(USE_GNOME_PRINT, test "x$gp" = "xyes") +if test "x$gp" = "xyes"; then + AC_DEFINE(WITH_GNOME_PRINT, 1, [Use gnome print font database and spooler frontend]) +fi + +dnl ****************************** +dnl gnome vfs checking +dnl ****************************** + +AC_ARG_WITH(gnome-vfs, + AC_HELP_STRING([--with-gnome-vfs], [use gnome vfs for loading files]), + [with_gnome_vfs=$withval], [with_gnome_vfs=auto]) + +if test "x$with_gnome_vfs" = "xno"; then + dnl Asked to ignore gnome-vfs + gnome_vfs=no +else + dnl Have to test gnome-vfs presence + PKG_CHECK_MODULES(GNOME_VFS, gnome-vfs-2.0 >= 2.0, gnome_vfs=yes, gnome_vfs=no) + if test "x$gnome_vfs" != "xyes"; then + dnl No gnome-vfs found + if test "x$with_gnome_vfs" = "xyes"; then + dnl Gnome-VFS was explicitly asked for, so stop + AC_MSG_ERROR([--with-gnome-vfs was specified, but appropriate libgnomevfs development packages could not be found]) + else + # gnome-vfs is no, tell us for the log file + AC_MSG_RESULT($gnome_vfs) + fi + fi +fi + +AM_CONDITIONAL(USE_GNOME_VFS, test "x$gnome_vfs" = "xyes") +if test "x$gnome_vfs" = "xyes"; then + AC_DEFINE(WITH_GNOME_VFS, 1, [Use gnome vfs file load functionality]) +fi + +AC_SUBST(GNOME_VFS_CFLAGS) +AC_SUBST(GNOME_VFS_LIBS) + +dnl ****************************** +dnl libinkjar checking +dnl ****************************** + +AC_ARG_WITH(inkjar, + AC_HELP_STRING([--without-inkjar], [disable openoffice files (SVG jars)]),[with_ij=$withval], [with_ij=yes]) + +if test "x$with_ij" = "xyes"; then + AC_DEFINE(WITH_INKJAR, 1, [enable openoffice files (SVG jars)]) + AC_C_BIGENDIAN + AC_CHECK_HEADERS(zlib.h) + ij=yes +else + ij=no +fi +AM_CONDITIONAL(INKJAR, test "$with_ij" = "yes") + +ink_spell_pkg= +if pkg-config --exists gtkspell-2.0; then + ink_spell_pkg=gtkspell-2.0 + AC_DEFINE(WITH_GTKSPELL, 1, [enable gtk spelling widget]) +fi + +dnl ****************************** +dnl PERL checking +dnl ****************************** + +AC_MSG_CHECKING(for Perl development environment) +AC_ARG_WITH(perl, + AC_HELP_STRING([--with-perl], [use Perl for embedded scripting]), + [with_perl=$withval], [with_perl=skipped]) + +if test "x$with_perl" = "xyes"; then + checkPERL_CFLAGS=`perl -MExtUtils::Embed -e perl_inc 2>/dev/null` + if test "$?" -gt "0"; then + with_perl="no" + else + checkPERL_LDFLAGS=`perl -MExtUtils::Embed -e ldopts 2>/dev/null` + if test "$?" -gt "0"; then + with_perl="no" + else + with_perl="yes" + fi + fi +fi +AC_MSG_RESULT([$with_perl]) +if test "x$with_perl" = "xyes"; then + # Test that we actually have the perl libraries installed + oldCFLAGS="$CFLAGS" + oldLDFLAGS="$LDFLAGS" + CFLAGS="$CFLAGS $checkPERL_CFLAGS" + LDFLAGS="$LDFLAGS $checkPERL_LDFLAGS" + AC_CHECK_FUNC([perl_parse],[ + PERL_CFLAGS="$checkPERL_CFLAGS" + PERL_LDFLAGS="$checkPERL_LDFLAGS" + AC_DEFINE(WITH_PERL, 1, [use Perl for embedded scripting]) + ],[ + with_perl="no" + ]) + CFLAGS="$oldCFLAGS" + LDFLAGS="$oldLDFLAGS" +fi +AM_CONDITIONAL(WITH_PERL, test "x$with_perl" = "xyes") +AC_SUBST(PERL_CFLAGS) +AC_SUBST(PERL_LDFLAGS) + +dnl ****************************** +dnl Python checking +dnl ****************************** + +AC_MSG_CHECKING(for Python development environment) +AC_ARG_WITH(python, + AC_HELP_STRING([--with-python], [use Python for embedded scripting]), + [with_python=$withval], [with_python=skipped]) + +if test "x$with_python" = "xyes"; then + checkPYTHON_CFLAGS=`python -c "import distutils.sysconfig ; print '-I%s' % distutils.sysconfig.get_config_var('INCLUDEPY')" 2>/dev/null` + if test "$?" -gt "0"; then + with_python="no" + else + checkPYTHON_LIBS=`python -c "import distutils.sysconfig ; print '%s/%s %s' % (distutils.sysconfig.get_config_var('LIBPL'),distutils.sysconfig.get_config_var('LIBRARY'),distutils.sysconfig.get_config_var('LIBS'))" 2>/dev/null` + if test "$?" -gt "0"; then + with_python="no" + else + with_python="yes" + fi + fi +fi +AC_MSG_RESULT([$with_python]) +if test "x$with_python" = "xyes"; then + # Test that we actually have the python libraries installed + oldCFLAGS="$CFLAGS" + oldLIBS="$LIBS" + CFLAGS="$CFLAGS $checkPYTHON_CFLAGS" + LIBS="$LIBS $checkPYTHON_LIBS" + AC_CHECK_FUNC([Py_Initialize],[ + PYTHON_CFLAGS="$checkPYTHON_CFLAGS" + PYTHON_LIBS="$checkPYTHON_LIBS" + AC_DEFINE(WITH_PYTHON, 1, [use Python for embedded scripting]) + ],[ + with_python="no" + ]) + CFLAGS="$oldCFLAGS" + LIBS="$oldLIBS" +fi +AM_CONDITIONAL(WITH_PYTHON, test "x$with_python" = "xyes") +AC_SUBST(PYTHON_CFLAGS) +AC_SUBST(PYTHON_LIBS) + +dnl ****************************** +dnl Inkboard dependency checking +dnl ****************************** + +with_inkboard="no" + +AC_MSG_CHECKING(for loudmouth-1.0+) + +AC_ARG_ENABLE(inkboard, + AS_HELP_STRING([--enable-inkboard], [enable Inkboard online whiteboard facility (disabled by default)]), + with_inkboard=$enableval,with_inkboard=no) + +if test "x$with_inkboard" = "xyes"; then + PKG_CHECK_MODULES(LIBLOUDMOUTH, loudmouth-1.0, loudmouth_ok=yes, loudmouth_ok=no) + if test "x$loudmouth_ok" = "xyes"; then + with_inkboard="yes" + AC_DEFINE(WITH_INKBOARD,1,[Build in Inkboard support]) + else + with_inkboard="no" + fi +else + with_inkboard="no" +fi + +AC_MSG_RESULT($with_inkboard) +AM_CONDITIONAL(WITH_INKBOARD, test "x$with_inkboard" = "xyes") +AC_SUBST(LIBLOUDMOUTH_CFLAGS) +AC_SUBST(LIBLOUDMOUTH_LIBS) + +dnl ****************************** +dnl Unconditional dependencies +dnl ****************************** + +dnl *** NOTE: when we move to gtk 2.6 or later, we can remove the +dnl ********* the override for g_ascii_strtod below... +PKG_CHECK_MODULES(INKSCAPE, gdkmm-2.4 glibmm-2.4 gtkmm-2.4 gtk+-2.0 >= 2.4.0 libxml-2.0 >= 2.6.0 libxslt >= 1.0.15 sigc++-2.0 >= 2.0.3 $ink_spell_pkg gthread-2.0 >= 2.0) + +dnl Shouldn't we test for libpng and libz? +INKSCAPE_LIBS="$INKSCAPE_LIBS -lpng -lz" + +AC_CHECK_HEADER(popt.h, + [INKSCAPE_LIBS="$INKSCAPE_LIBS -lpopt"], + AC_MSG_ERROR([libpopt is required])) + +dnl Check for bind_textdomain_codeset, including -lintl if GLib brings it in. +sp_save_LIBS=$LIBS +LIBS="$LIBS $INKSCAPE_LIBS" +AC_CHECK_FUNCS(bind_textdomain_codeset) +dnl Check for gtk_window_fullscreen in gtk (>= 2.2) +AC_CHECK_FUNCS(gtk_window_set_default_icon_from_file) +AC_CHECK_FUNCS(gtk_window_fullscreen) +LIBS=$sp_save_LIBS + + +dnl Check for binary relocation support +dnl Hongli Lai + +AC_ARG_ENABLE(binreloc, + [ --enable-binreloc compile with binary relocation support], + enable_binreloc=$enableval,enable_binreloc=no) + +AC_MSG_CHECKING(whether binary relocation support should be enabled) +if test "$enable_binreloc" = "yes"; then + AC_MSG_RESULT(yes) + AC_MSG_CHECKING(for linker mappings at /proc/self/maps) + if test -e /proc/self/maps; then + AC_MSG_RESULT(yes) + else + AC_MSG_RESULT(no) + AC_MSG_ERROR(/proc/self/maps is not available. Binary relocation cannot be enabled.) + enable_binreloc="no" + fi + +elif test "$enable_binreloc" = "auto"; then + AC_MSG_RESULT(yes when available) + AC_MSG_CHECKING(for linker mappings at /proc/self/maps) + if test -e /proc/self/maps; then + AC_MSG_RESULT(yes) + enable_binreloc=yes + + AC_MSG_CHECKING(whether everything is installed to the same prefix) + if test "$bindir" = '${exec_prefix}/bin' -a "$sbindir" = '${exec_prefix}/sbin' -a \ + "$datadir" = '${prefix}/share' -a "$libdir" = '${exec_prefix}/lib' -a \ + "$libexecdir" = '${exec_prefix}/libexec' -a "$sysconfdir" = '${prefix}/etc' + then + AC_MSG_RESULT(yes) + else + AC_MSG_RESULT(no) + AC_MSG_NOTICE(Binary relocation support will be disabled.) + enable_binreloc=no + fi + + else + AC_MSG_RESULT(no) + enable_binreloc=no + fi + +elif test "$enable_binreloc" = "no"; then + AC_MSG_RESULT(no) +else + AC_MSG_RESULT(no (unknown value "$enable_binreloc")) + enable_binreloc=no +fi +AC_DEFINE(BR_PTHREADS,[0],[Use binreloc thread support?]) +if test "$enable_binreloc" = "yes"; then + AC_DEFINE(ENABLE_BINRELOC,,[Use AutoPackage?]) +fi + +AC_ARG_ENABLE(osxapp, + [ --enable-osxapp compile with OSX .app data dir paths], + enable_osxapp=$enableval,enable_osxapp=no) +if test "$enable_osxapp" = "yes"; then + AC_DEFINE(ENABLE_OSX_APP_LOCATIONS,,[Build with OSX .app data dir paths?]) +fi + +dnl ****************************** +dnl Reported by autoscan +dnl ****************************** +AC_CHECK_FUNCS(pow) +# if we did not find pow(), see if it's in libm. +if test x"$ac_cv_func_pow" = x"no" ; then + AC_CHECK_LIB(m,pow) +fi +AC_CHECK_FUNCS(sqrt) +AC_CHECK_FUNCS(floor) +AC_CHECK_FUNCS(gettimeofday) +AC_CHECK_FUNCS(memmove) +AC_CHECK_FUNCS(memset) +AC_CHECK_FUNCS(mkdir) +AC_CHECK_FUNCS(strncasecmp) +AC_CHECK_FUNCS(strpbrk) +AC_CHECK_FUNCS(strrchr) +AC_CHECK_FUNCS(strspn) +AC_CHECK_FUNCS(strstr) +AC_CHECK_FUNCS(strtoul) +AC_CHECK_FUNCS(fpsetmask) +AC_CHECK_FUNCS(ecvt) +AC_CHECK_HEADERS(ieeefp.h) +AC_CHECK_HEADERS(fcntl.h) +AC_CHECK_HEADERS(libintl.h) +AC_CHECK_HEADERS(stddef.h) +AC_CHECK_HEADERS(sys/time.h) +AC_FUNC_STAT +AC_FUNC_STRFTIME +AC_FUNC_STRTOD +AC_HEADER_STAT +AC_HEADER_TIME +AC_STRUCT_TM +AC_TYPE_MODE_T +AC_TYPE_SIGNAL + +dnl Work around broken gcc 3.3 (seen on OSX) where "ENABLE_NLS" isn't +dnl set correctly because the gettext function isn't noticed. +if test "$ac_cv_header_libintl_h" = "yes" && + test "$ac_cv_func_bind_textdomain_codeset" = "yes" && + test "$gt_cv_func_have_gettext" != "yes"; then + AC_DEFINE(ENABLE_NLS) +fi + +dnl ****************************** +dnl Compilation warnings +dnl ****************************** +if test "$GXX" = "yes"; then + # Enable some warnings from g++. + + # Rationale: a number of bugs in inkscape have been fixed by enabling g++ + # warnings and addressing the produced warnings. Usually the committing + # developer is the best person to address the warnings. + + ink_svd_CXXFLAGS="$CXXFLAGS" + CXXFLAGS="-Wno-unused-parameter $CXXFLAGS" + # -Wno-unused-parameter isn't accepted by gcc 2.95. + AC_COMPILE_IFELSE([int dummy; +], , CXXFLAGS="-Wno-unused $ink_svd_CXXFLAGS",) + # Note: At least one bug has been caught from unused parameter warnings, + # so it might be worth trying not to disable it. + # One way of selectively disabling the warnings (i.e. only where the + # programmer deliberately isn't using the parameter, e.g. for a callback) + # is to remove the parameter name (leaving just its type), as is done + # in src/seltrans.cpp:sp_seltrans_handle_event; this indicates that the + # programmer deliberately has an unused parameter (e.g. because it's used + # as a callback or similar function pointer use). + + CXXFLAGS="-Wall -W -Wpointer-arith -Wcast-align -Wsign-compare -Woverloaded-virtual -Wswitch $CXXFLAGS" + + dnl Test for arch-specific situations. + case "$host_cpu" in + mips|mipsel) + dnl Symbol tables can get too large: this uses alternate tables + dnl See http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=283476 + CXXFLAGS="$CXXFLAGS -Wa,-xgot" + CFLAGS="$CFLAGS -Wa,-xgot" + ;; + esac +fi + +dnl ****************************** +dnl Plugin Support +dnl ****************************** +dnl +dnl UPDATE: This is unconditional now (Lauris) +dnl +dnl AC_ARG_WITH(modules, AC_HELP_STRING([--with-modules], [Compile with plugin support (experimental)]), [mod=$withval], [mod=yes]) +dnl +dnl AM_CONDITIONAL(USE_MODULES, test "x$mod" = "xyes") +dnl if test "x$mod" = "xyes"; then +dnl AC_DEFINE(WITH_MODULES, 1, [Use experimental module support]) +dnl fi + +AC_DEFINE(WITH_MODULES, 1, [Use experimental module support]) + +dnl ****************************** +dnl libinkscape +dnl ****************************** +dnl +dnl AC_ARG_ENABLE(libinkscape, AC_HELP_STRING([--enable-libinkscape], [Compile dynamic library (experimental)]), [splib=$enableval], [splib=no]) +dnl +dnl AM_CONDITIONAL(ENABLE_LIBINKSCAPE, test "x$splib" != "xno") +dnl + +AC_SUBST(INKSCAPE_CFLAGS) +AC_SUBST(INKSCAPE_LIBS) + +# +# Checks to see if we should compile in MMX support (there will be +# a runtime test when the code is actually run to see if it should +# be used - this just checks if we can compile it.) +# +# This code is partially taken from Mesa +# +dnl Let people disable the MMX optimization +AC_ARG_ENABLE(mmx, [ --disable-mmx Don't use MMX optimization [default=auto]], enable_mmx="$enableval", enable_mmx=auto) + +AC_MSG_CHECKING(for x86 platform) +case $host_cpu in + i386|i486|i586|i686|i786|k6|k7) + use_x86_asm=yes + ;; + *) + use_x86_asm=no +esac +AC_MSG_RESULT($use_x86_asm) + +dnl Are we going to use MMX extensions +use_mmx_asm=no + +AC_MSG_CHECKING(compiler support for MMX) + +if test x$enable_mmx = xauto ; then + if test $use_x86_asm = yes; then + save_ac_ext=$ac_ext + ac_ext=S + + cp $srcdir/src/libnr/nr_mmx_R8G8B8A8_P_R8G8B8A8_P_A8_RGBAP.S conftest.S + if AC_TRY_EVAL(ac_compile); then + use_mmx_asm=yes + fi + dnl rm -f conftest.[oS] + + ac_ext=$save_ac_ext + fi + +dnl Enforce usage of MMX extensions +elif test x$enable_mmx = xyes ; then + use_mmx_asm=yes +else + use_mmx_asm=no +fi + +if test $use_mmx_asm = yes; then + AC_DEFINE(WITH_MMX, 1, [Use MMX optimizations, if CPU supports it]) + AC_MSG_RESULT(yes) +else + AC_MSG_RESULT(no) +fi + +AM_CONDITIONAL(USE_MMX, test x$use_mmx_asm = xyes) + +dnl Override the default g_ascii_strtod +AC_DEFINE(g_ascii_strtod, fixed_g_ascii_strtod, [Pre-1.107 gstrfuncs.c version of g_ascii_strtod is broken]) + +dnl Figure out where the datadir actually is +if test "x${datadir}" = 'x${prefix}/share'; then + if test "x${prefix}" = "xNONE"; then + runtime_datadir="${ac_default_prefix}/share" + else + runtime_datadir="${prefix}/share" + fi +else + runtime_datadir="${datadir}" +fi + +inkscape_sharedir="${runtime_datadir}/${PACKAGE_NAME}" + +dnl Define our data paths for config.h +AC_SUBST(INKSCAPE_DATADIR) +AC_DEFINE_UNQUOTED([INKSCAPE_DATADIR], "${runtime_datadir}", + [Base data directory -- only path-prefix.h should use it!]) +AC_SUBST(PACKAGE_LOCALE_DIR) +AC_DEFINE_UNQUOTED([PACKAGE_LOCALE_DIR], "${runtime_datadir}/locale", + [Localization directory]) +AC_SUBST(INKSCAPE_LIBDIR) +AC_DEFINE_UNQUOTED([INKSCAPE_LIBDIR], "${prefix}/lib", + [Base library directory -- only path-prefix.h should use it!]) + +dnl Have to add module makefiles (lauris) + +AC_CONFIG_FILES([ +Makefile +src/Makefile +src/check-header-compile +src/algorithms/makefile +src/application/makefile +src/debug/makefile +src/dialogs/makefile +src/display/makefile +src/dom/makefile +src/extension/implementation/makefile +src/extension/internal/makefile +src/extension/makefile +src/extension/plugin/makefile +src/extension/script/makefile +src/helper/makefile +src/inkjar/makefile +src/io/makefile +src/libcroco/makefile +src/libnr/makefile +src/libnrtype/makefile +src/libavoid/makefile +src/livarot/makefile +src/jabber_whiteboard/makefile +src/removeoverlap/makefile +src/svg/makefile +src/trace/makefile +src/traits/makefile +src/ui/dialog/makefile +src/ui/makefile +src/ui/view/makefile +src/ui/widget/makefile +src/utest/makefile +src/util/makefile +src/widgets/makefile +src/xml/makefile +doc/Makefile +po/Makefile.in +share/Makefile +share/clipart/Makefile +share/examples/Makefile +share/extensions/Makefile +share/fonts/Makefile +share/gradients/Makefile +share/icons/Makefile +share/keyboards/Makefile +share/markers/Makefile +share/palettes/Makefile +share/patterns/Makefile +share/screens/Makefile +share/templates/Makefile +share/tutorials/Makefile +share/ui/Makefile +packaging/autopackage/default.apspec +inkscape.spec +Info.plist +inkview.1 +]) + +AH_BOTTOM([ + + +]) + +AC_OUTPUT + +echo " +Configuration: + + Source code location: ${srcdir} + Destination path prefix: ${prefix} + Compiler: ${CXX} + CPPFLAGS: ${CPPFLAGS} + CXXFLAGS: ${CXXFLAGS} + CFLAGS: ${CFLAGS} + LDFLAGS: ${LDFLAGS} + + Use Xft font database: ${xft_ok} + Use gnome-print: ${gp} + Use gnome-vfs: ${gnome_vfs} + Use openoffice files: ${ij} + Use MMX optimizations: ${use_mmx_asm} + Use relocation support: ${enable_binreloc} + Use Python extensions: ${with_python} + Use Perl extensions: ${with_perl} + Enable Inkboard: ${with_inkboard} +" diff --git a/cxxtest/COPYING b/cxxtest/COPYING new file mode 100644 index 000000000..b1e3f5a26 --- /dev/null +++ b/cxxtest/COPYING @@ -0,0 +1,504 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/cxxtest/README b/cxxtest/README new file mode 100644 index 000000000..40722cd94 --- /dev/null +++ b/cxxtest/README @@ -0,0 +1,63 @@ +Introduction +------------ + +CxxTest is a JUnit/CppUnit/xUnit-like framework for C++. + +Its advantages over existing alternatives are that it: + - Doesn't require RTTI + - Doesn't require member template functions + - Doesn't require exception handling + - Doesn't require any external libraries (including memory management, + file/console I/O, graphics libraries) + +This makes it extremely portable and usable. + +CxxTest is available under the GNU Lesser General Public Licence (LGPL). +See http://www.gnu.org/copyleft/lesser.html for the license. + +Simple user's guide +------------------- + +1. Create a test suite header file: + +MyTest.h: + #include + + class MyTestSuite : public CxxTest::TestSuite + { + public: + void testAddition( void ) + { + TS_ASSERT( 1 + 1 > 1 ); + TS_ASSERT_EQUALS( 1 + 1, 2 ); + } + }; + + +2. Generate the tests file: + + # cxxtestgen.pl -o tests.cpp MyTestSuite.h + + +3. Create a main function that runs the tests + +main.cpp: + #include + + int main( void ) + { + CxxText::ErrorPrinter::runAllTests(); + return 0; + } + + +4. Compile and run! + + # g++ -o main main.cpp tests.cpp + # ./main + Running 1 test(s).OK! + + +Advanced User's Guide +--------------------- +See docs/guide.html. diff --git a/cxxtest/TODO b/cxxtest/TODO new file mode 100644 index 000000000..7a7f926e5 --- /dev/null +++ b/cxxtest/TODO @@ -0,0 +1,34 @@ +This is an -*- Outline -*- of ideas for future versions of CxxTest. +It is not meant to be "human readable". + +* CxxTest To Do list + +** Mock framework + +Write some mocks + +*** Distribution +Seperate packages (w/ binaries)? How would that be used? +For Windows: .lib for "Real" and "Mock" parts. +For Linux: Maybe. Different compilers etc. +So probably only source release with Makefiles and .ds[pw]? Or just Win32 binary. + +**** Installation? +extract cxxtest-x.y.z.tar.gz +(extract cxxtest-mock-x.y.z.tar.gz) ? +make -C cxxtest/Real +make -C cxxtest/Mock + +or maybe make -C cxxtest -f Makefile.mock +but then Makefile.mock.bcc32, Makefile.mock.msvc, Makefile.mock.gcc, and heaven knows what else. + +Could put the Makefile.mock.* in cxxtest/Real and cxxtest/Mock or in cxxtest/T + +Maybe this should be a different package altogether? +Seems logical, since they evolve separately. But then you'd want to download both. + +** Thoughts +-fomit-frame-pointer + +** TS_HEX + diff --git a/cxxtest/Versions b/cxxtest/Versions new file mode 100644 index 000000000..b35cba20a --- /dev/null +++ b/cxxtest/Versions @@ -0,0 +1,152 @@ +CxxTest Releases +================ + +Version 3.10.1 (2004-12-01): +---------------------------- + - Improved support for VC7 + - Fixed clash with some versions of STL + +Version 3.10.0 (2004-11-20): +---------------------------- + - Added mock framework for global functions + - Added TS_ASSERT_THROWS_ASSERT and TS_ASSERT_THROWS_EQUALS + - Added CXXTEST_ENUM_TRAITS + - Improved support for STL classes (vector, map etc.) + - Added support for Digital Mars compiler + - Reduced root/part compilation time and binary size + - Support C++-style commenting of tests + +Version 3.9.1 (2004-01-19): +--------------------------- + - Fixed small bug with runner exit code + - Embedded test suites are now deprecated + +Version 3.9.0 (2004-01-17): +--------------------------- + - Added TS_TRACE + - Added --no-static-init + - CxxTest::setAbortTestOnFail() works even without --abort-on-fail + +Version 3.8.5 (2004-01-08): +--------------------------- + - Added --no-eh + - Added CxxTest::setAbortTestOnFail() and CXXTEST_DEFAULT_ABORT + - Added CxxTest::setMaxDumpSize() + - Added StdioFilePrinter + +Version 3.8.4 (2003-12-31): +--------------------------- + - Split distribution into cxxtest and cxxtest-selftest + - Added `sample/msvc/FixFiles.bat' + +Version 3.8.3 (2003-12-24): +--------------------------- + - Added TS_ASSERT_PREDICATE + - Template files can now specify where to insert the preamble + - Added a sample Visual Studio workspace in `sample/msvc' + - Can compile in MSVC with warning level 4 + - Changed output format slightly + +Version 3.8.1 (2003-12-21): +--------------------------- + - Fixed small bug when using multiple --part files. + - Fixed X11 GUI crash when there's no X server. + - Added GlobalFixture::setUpWorld()/tearDownWorld() + - Added leaveOnly(), activateAllTests() and `sample/only.tpl' + - Should now run without warnings on Sun compiler. + +Version 3.8.0 (2003-12-13): +--------------------------- + - Fixed bug where `Root.cpp' needed exception handling + - Added TS_ASSERT_RELATION + - TSM_ macros now also tell you what went wrong + - Renamed Win32Gui::free() to avoid clashes + - Now compatible with more versions of Borland compiler + - Improved the documentation + +Version 3.7.1 (2003-09-29): +--------------------------- + - Added --version + - Compiles with even more exotic g++ warnings + - Win32 Gui compiles with UNICODE + - Should compile on some more platforms (Sun Forte, HP aCC) + +Version 3.7.0 (2003-09-20): +--------------------------- + - Added TS_ASSERT_LESS_THAN_EQUALS + - Minor cleanups + +Version 3.6.1 (2003-09-15): +--------------------------- + - Improved QT GUI + - Improved portability some more + +Version 3.6.0 (2003-09-04): +--------------------------- + - Added --longlong + - Some portability improvements + +Version 3.5.1 (2003-09-03): +--------------------------- + - Major internal rewrite of macros + - Added TS_ASSERT_SAME_DATA + - Added --include option + - Added --part and --root to enable splitting the test runner + - Added global fixtures + - Enhanced Win32 GUI with timers, -keep and -title + - Now compiles with strict warnings + +Version 3.1.1 (2003-08-27): +--------------------------- + - Fixed small bug in TS_ASSERT_THROWS_*() + +Version 3.1.0 (2003-08-23): +--------------------------- + - Default ValueTraits now dumps value as hex bytes + - Fixed double invocation bug (e.g. TS_FAIL(functionWithSideEffects())) + - TS_ASSERT_THROWS*() are now "abort on fail"-friendly + - Win32 GUI now supports Windows 98 and doesn't need comctl32.lib + +Version 3.0.1 (2003-08-07): +--------------------------- + - Added simple GUI for X11, Win32 and Qt + - Added TS_WARN() macro + - Removed --exit-code + - Improved samples + - Improved support for older (pre-std::) compilers + - Made a PDF version of the User's Guide + +Version 2.8.4 (2003-07-21): +--------------------------- + - Now supports g++-3.3 + - Added --have-eh + - Fixed bug in numberToString() + +Version 2.8.3 (2003-06-30): +--------------------------- + - Fixed bugs in cxxtestgen.pl + - Fixed warning for some compilers in ErrorPrinter/StdioPrinter + - Thanks Martin Jost for pointing out these problems! + +Version 2.8.2 (2003-06-10): +--------------------------- + - Fixed bug when using CXXTEST_ABORT_TEST_ON_FAIL without standard library + - Added CXXTEST_USER_TRAITS + - Added --abort-on-fail + +Version 2.8.1 (2003-01-16): +--------------------------- + - Fixed charToString() for negative chars + +Version 2.8.0 (2003-01-13): +--------------------------- + - Added CXXTEST_ABORT_TEST_ON_FAIL for xUnit-like behaviour + - Added `sample/winddk' + - Improved ValueTraits + - Improved output formatter + - Started version history + +Version 2.7.0 (2002-09-29): +--------------------------- + - Added embedded test suites + - Major internal improvements diff --git a/cxxtest/cxxtest.spec b/cxxtest/cxxtest.spec new file mode 100644 index 000000000..0f1ded6c5 --- /dev/null +++ b/cxxtest/cxxtest.spec @@ -0,0 +1,40 @@ +Name: cxxtest +Summary: CxxTest Testing Framework for C++ +Version: 3.10.1 +Release: 1 +Copyright: LGPL +Group: Development/C++ +Source: cxxtest-%{version}.tar.gz +BuildRoot: /tmp/cxxtest-build +BuildArch: noarch +Prefix: /usr + +%description +CxxTest is a JUnit/CppUnit/xUnit-like framework for C++. +Its advantages over existing alternatives are that it: + - Doesn't require RTTI + - Doesn't require member template functions + - Doesn't require exception handling + - Doesn't require any external libraries (including memory management, + file/console I/O, graphics libraries) + +%prep +%setup -n cxxtest + +%build + +%install +install -m 755 -d $RPM_BUILD_ROOT/usr/bin $RPM_BUILD_ROOT/usr/include/cxxtest +install -m 755 cxxtestgen.p[ly] $RPM_BUILD_ROOT/usr/bin/ +install -m 644 cxxtest/* $RPM_BUILD_ROOT/usr/include/cxxtest/ + +%clean +rm -rf $RPM_BUILD_ROOT + +%files +%attr(-, root, root) %doc README +%attr(-, root, root) %doc sample +%attr(-, root, root) /usr/include/cxxtest +%attr(-, root, root) /usr/bin/cxxtestgen.pl +%attr(-, root, root) /usr/bin/cxxtestgen.py + diff --git a/cxxtest/cxxtest/Descriptions.cpp b/cxxtest/cxxtest/Descriptions.cpp new file mode 100644 index 000000000..143f8f8fd --- /dev/null +++ b/cxxtest/cxxtest/Descriptions.cpp @@ -0,0 +1,58 @@ +#ifndef __cxxtest__Descriptions_cpp__ +#define __cxxtest__Descriptions_cpp__ + +#include + +namespace CxxTest +{ + TestDescription::~TestDescription() {} + SuiteDescription::~SuiteDescription() {} + WorldDescription::~WorldDescription() {} + + // + // Convert total tests to string + // +#ifndef _CXXTEST_FACTOR + char *WorldDescription::strTotalTests( char *s ) const + { + numberToString( numTotalTests(), s ); + return s; + } +#else // _CXXTEST_FACTOR + char *WorldDescription::strTotalTests( char *s ) const + { + char *p = numberToString( numTotalTests(), s ); + + if ( numTotalTests() <= 1 ) + return s; + + unsigned n = numTotalTests(); + unsigned numFactors = 0; + + for ( unsigned factor = 2; (factor * factor) <= n; factor += (factor == 2) ? 1 : 2 ) { + unsigned power; + + for ( power = 0; (n % factor) == 0; n /= factor ) + ++ power; + + if ( !power ) + continue; + + p = numberToString( factor, copyString( p, (numFactors == 0) ? " = " : " * " ) ); + if ( power > 1 ) + p = numberToString( power, copyString( p, "^" ) ); + ++ numFactors; + } + + if ( n > 1 ) { + if ( !numFactors ) + copyString( p, tracker().failedTests() ? " :(" : tracker().warnings() ? " :|" : " :)" ); + else + numberToString( n, copyString( p, " * " ) ); + } + return s; + } +#endif // _CXXTEST_FACTOR +}; + +#endif // __cxxtest__Descriptions_cpp__ diff --git a/cxxtest/cxxtest/Descriptions.h b/cxxtest/cxxtest/Descriptions.h new file mode 100644 index 000000000..bd373ec76 --- /dev/null +++ b/cxxtest/cxxtest/Descriptions.h @@ -0,0 +1,74 @@ +#ifndef __cxxtest__Descriptions_h__ +#define __cxxtest__Descriptions_h__ + +// +// TestDescription, SuiteDescription and WorldDescription +// hold information about tests so they can be run and reported. +// + +#include + +namespace CxxTest +{ + class TestSuite; + + class TestDescription : public Link + { + public: + virtual ~TestDescription(); + + virtual const char *file() const = 0; + virtual unsigned line() const = 0; + virtual const char *testName() const = 0; + virtual const char *suiteName() const = 0; + + virtual void run() = 0; + + virtual const TestDescription *next() const = 0; + virtual TestDescription *next() = 0; + }; + + class SuiteDescription : public Link + { + public: + virtual ~SuiteDescription(); + + virtual const char *file() const = 0; + virtual unsigned line() const = 0; + virtual const char *suiteName() const = 0; + virtual TestSuite *suite() const = 0; + + virtual unsigned numTests() const = 0; + virtual const TestDescription &testDescription( unsigned /*i*/ ) const = 0; + + virtual TestDescription *firstTest() = 0; + virtual const TestDescription *firstTest() const = 0; + virtual SuiteDescription *next() = 0; + virtual const SuiteDescription *next() const = 0; + + virtual void activateAllTests() = 0; + virtual bool leaveOnly( const char * /*testName*/ ) = 0; + }; + + class WorldDescription : public Link + { + public: + virtual ~WorldDescription(); + + virtual unsigned numSuites( void ) const = 0; + virtual unsigned numTotalTests( void ) const = 0; + virtual const SuiteDescription &suiteDescription( unsigned /*i*/ ) const = 0; + + enum { MAX_STRLEN_TOTAL_TESTS = 32 }; + char *strTotalTests( char * /*buffer*/ ) const; + + virtual SuiteDescription *firstSuite() = 0; + virtual const SuiteDescription *firstSuite() const = 0; + + virtual void activateAllTests() = 0; + virtual bool leaveOnly( const char * /*suiteName*/, const char * /*testName*/ = 0 ) = 0; + }; +} + +#endif // __cxxtest__Descriptions_h__ + diff --git a/cxxtest/cxxtest/DummyDescriptions.cpp b/cxxtest/cxxtest/DummyDescriptions.cpp new file mode 100644 index 000000000..c862e439d --- /dev/null +++ b/cxxtest/cxxtest/DummyDescriptions.cpp @@ -0,0 +1,49 @@ +#include + +namespace CxxTest +{ + DummyTestDescription::DummyTestDescription() {} + + const char *DummyTestDescription::file() const { return ""; } + unsigned DummyTestDescription::line() const { return 0; } + const char *DummyTestDescription::testName() const { return ""; } + const char *DummyTestDescription::suiteName() const { return ""; } + bool DummyTestDescription::setUp() { return true;} + void DummyTestDescription::run() {} + bool DummyTestDescription::tearDown() { return true;} + + TestDescription *DummyTestDescription::next() { return 0; } + const TestDescription *DummyTestDescription::next() const { return 0; } + + DummySuiteDescription::DummySuiteDescription() : _test() {} + + const char *DummySuiteDescription::file() const { return ""; } + unsigned DummySuiteDescription::line() const { return 0; } + const char *DummySuiteDescription::suiteName() const { return ""; } + TestSuite *DummySuiteDescription::suite() const { return 0; } + unsigned DummySuiteDescription::numTests() const { return 0; } + const TestDescription &DummySuiteDescription::testDescription( unsigned ) const { return _test; } + SuiteDescription *DummySuiteDescription::next() { return 0; } + TestDescription *DummySuiteDescription::firstTest() { return 0; } + const SuiteDescription *DummySuiteDescription::next() const { return 0; } + const TestDescription *DummySuiteDescription::firstTest() const { return 0; } + void DummySuiteDescription::activateAllTests() {} + bool DummySuiteDescription::leaveOnly( const char * /*testName*/ ) { return false; } + + bool DummySuiteDescription::setUp() { return true;} + bool DummySuiteDescription::tearDown() { return true;} + + DummyWorldDescription::DummyWorldDescription() : _suite() {} + + unsigned DummyWorldDescription::numSuites( void ) const { return 0; } + unsigned DummyWorldDescription::numTotalTests( void ) const { return 0; } + const SuiteDescription &DummyWorldDescription::suiteDescription( unsigned ) const { return _suite; } + SuiteDescription *DummyWorldDescription::firstSuite() { return 0; } + const SuiteDescription *DummyWorldDescription::firstSuite() const { return 0; } + void DummyWorldDescription::activateAllTests() {} + bool DummyWorldDescription::leaveOnly( const char * /*suiteName*/, const char * /*testName*/ ) { return false; } + + bool DummyWorldDescription::setUp() { return true;} + bool DummyWorldDescription::tearDown() { return true;} +} + diff --git a/cxxtest/cxxtest/DummyDescriptions.h b/cxxtest/cxxtest/DummyDescriptions.h new file mode 100644 index 000000000..c9215d125 --- /dev/null +++ b/cxxtest/cxxtest/DummyDescriptions.h @@ -0,0 +1,76 @@ +#ifndef __cxxtest__DummyDescriptions_h__ +#define __cxxtest__DummyDescriptions_h__ + +// +// DummyTestDescription, DummySuiteDescription and DummyWorldDescription +// + +#include + +namespace CxxTest +{ + class DummyTestDescription : public TestDescription + { + public: + DummyTestDescription(); + + const char *file() const; + unsigned line() const; + const char *testName() const; + const char *suiteName() const; + bool setUp(); + void run(); + bool tearDown(); + + TestDescription *next(); + const TestDescription *next() const; + }; + + class DummySuiteDescription : public SuiteDescription + { + public: + DummySuiteDescription(); + + const char *file() const; + unsigned line() const; + const char *suiteName() const; + TestSuite *suite() const; + unsigned numTests() const; + const TestDescription &testDescription( unsigned ) const; + SuiteDescription *next(); + TestDescription *firstTest(); + const SuiteDescription *next() const; + const TestDescription *firstTest() const; + void activateAllTests(); + bool leaveOnly( const char * /*testName*/ ); + + bool setUp(); + bool tearDown(); + + private: + DummyTestDescription _test; + }; + + class DummyWorldDescription : public WorldDescription + { + public: + DummyWorldDescription(); + + unsigned numSuites( void ) const; + unsigned numTotalTests( void ) const; + const SuiteDescription &suiteDescription( unsigned ) const; + SuiteDescription *firstSuite(); + const SuiteDescription *firstSuite() const; + void activateAllTests(); + bool leaveOnly( const char * /*suiteName*/, const char * /*testName*/ = 0 ); + + bool setUp(); + bool tearDown(); + + private: + DummySuiteDescription _suite; + }; +} + +#endif // __cxxtest__DummyDescriptions_h__ + diff --git a/cxxtest/cxxtest/ErrorFormatter.h b/cxxtest/cxxtest/ErrorFormatter.h new file mode 100644 index 000000000..968c310c2 --- /dev/null +++ b/cxxtest/cxxtest/ErrorFormatter.h @@ -0,0 +1,281 @@ +#ifndef __cxxtest__ErrorFormatter_h__ +#define __cxxtest__ErrorFormatter_h__ + +// +// The ErrorFormatter is a TestListener that +// prints reports of the errors to an output +// stream. Since we cannot rely ou the standard +// iostreams, this header defines a base class +// analogout to std::ostream. +// + +#include +#include +#include +#include + +namespace CxxTest +{ + class OutputStream + { + public: + virtual ~OutputStream() {} + virtual void flush() {}; + virtual OutputStream &operator<<( unsigned /*number*/ ) { return *this; } + virtual OutputStream &operator<<( const char * /*string*/ ) { return *this; } + + typedef void (*Manipulator)( OutputStream & ); + + virtual OutputStream &operator<<( Manipulator m ) { m( *this ); return *this; } + static void endl( OutputStream &o ) { (o << "\n").flush(); } + }; + + class ErrorFormatter : public TestListener + { + public: + ErrorFormatter( OutputStream *o, const char *preLine = ":", const char *postLine = "" ) : + _dotting( true ), + _reported( false ), + _o(o), + _preLine(preLine), + _postLine(postLine) + { + } + + int run() + { + TestRunner::runAllTests( *this ); + return tracker().failedTests(); + } + + void enterWorld( const WorldDescription & /*desc*/ ) + { + (*_o) << "Running " << totalTests; + _o->flush(); + _dotting = true; + _reported = false; + } + + static void totalTests( OutputStream &o ) + { + char s[WorldDescription::MAX_STRLEN_TOTAL_TESTS]; + const WorldDescription &wd = tracker().world(); + o << wd.strTotalTests( s ) << (wd.numTotalTests() == 1 ? " test" : " tests"); + } + + void enterSuite( const SuiteDescription & ) + { + _reported = false; + } + + void enterTest( const TestDescription & ) + { + _reported = false; + } + + void leaveTest( const TestDescription & ) + { + if ( !tracker().testFailed() ) { + ((*_o) << ".").flush(); + _dotting = true; + } + } + + void leaveWorld( const WorldDescription &desc ) + { + if ( !tracker().failedTests() ) { + (*_o) << "OK!" << endl; + return; + } + newLine(); + (*_o) << "Failed " << tracker().failedTests() << " of " << totalTests << endl; + unsigned numPassed = desc.numTotalTests() - tracker().failedTests(); + (*_o) << "Success rate: " << (numPassed * 100 / desc.numTotalTests()) << "%" << endl; + } + + void trace( const char *file, unsigned line, const char *expression ) + { + stop( file, line ) << "Trace: " << + expression << endl; + } + + void warning( const char *file, unsigned line, const char *expression ) + { + stop( file, line ) << "Warning: " << + expression << endl; + } + + void failedTest( const char *file, unsigned line, const char *expression ) + { + stop( file, line ) << "Error: Test failed: " << + expression << endl; + } + + void failedAssert( const char *file, unsigned line, const char *expression ) + { + stop( file, line ) << "Error: Assertion failed: " << + expression << endl; + } + + void failedAssertEquals( const char *file, unsigned line, + const char *xStr, const char *yStr, + const char *x, const char *y ) + { + stop( file, line ) << "Error: Expected (" << + xStr << " == " << yStr << "), found (" << + x << " != " << y << ")" << endl; + } + + void failedAssertSameData( const char *file, unsigned line, + const char *xStr, const char *yStr, + const char *sizeStr, const void *x, + const void *y, unsigned size ) + { + stop( file, line ) << "Error: Expected " << sizeStr << " (" << size << ") bytes to be equal at (" << + xStr << ") and (" << yStr << "), found:" << endl; + dump( x, size ); + (*_o) << " differs from" << endl; + dump( y, size ); + } + + void failedAssertDelta( const char *file, unsigned line, + const char *xStr, const char *yStr, const char *dStr, + const char *x, const char *y, const char *d ) + { + stop( file, line ) << "Error: Expected (" << + xStr << " == " << yStr << ") up to " << dStr << " (" << d << "), found (" << + x << " != " << y << ")" << endl; + } + + void failedAssertDiffers( const char *file, unsigned line, + const char *xStr, const char *yStr, + const char *value ) + { + stop( file, line ) << "Error: Expected (" << + xStr << " != " << yStr << "), found (" << + value << ")" << endl; + } + + void failedAssertLessThan( const char *file, unsigned line, + const char *xStr, const char *yStr, + const char *x, const char *y ) + { + stop( file, line ) << "Error: Expected (" << + xStr << " < " << yStr << "), found (" << + x << " >= " << y << ")" << endl; + } + + void failedAssertLessThanEquals( const char *file, unsigned line, + const char *xStr, const char *yStr, + const char *x, const char *y ) + { + stop( file, line ) << "Error: Expected (" << + xStr << " <= " << yStr << "), found (" << + x << " > " << y << ")" << endl; + } + + void failedAssertRelation( const char *file, unsigned line, + const char *relation, const char *xStr, const char *yStr, + const char *x, const char *y ) + { + stop( file, line ) << "Error: Expected " << relation << "( " << + xStr << ", " << yStr << " ), found !" << relation << "( " << x << ", " << y << " )" << endl; + } + + void failedAssertPredicate( const char *file, unsigned line, + const char *predicate, const char *xStr, const char *x ) + { + stop( file, line ) << "Error: Expected " << predicate << "( " << + xStr << " ), found !" << predicate << "( " << x << " )" << endl; + } + + void failedAssertThrows( const char *file, unsigned line, + const char *expression, const char *type, + bool otherThrown ) + { + stop( file, line ) << "Error: Expected (" << expression << ") to throw (" << + type << ") but it " << (otherThrown ? "threw something else" : "didn't throw") << + endl; + } + + void failedAssertThrowsNot( const char *file, unsigned line, const char *expression ) + { + stop( file, line ) << "Error: Expected (" << expression << ") not to throw, but it did" << + endl; + } + + protected: + OutputStream *outputStream() const + { + return _o; + } + + private: + ErrorFormatter( const ErrorFormatter & ); + ErrorFormatter &operator=( const ErrorFormatter & ); + + OutputStream &stop( const char *file, unsigned line ) + { + newLine(); + reportTest(); + return (*_o) << file << _preLine << line << _postLine << ": "; + } + + void newLine( void ) + { + if ( _dotting ) { + (*_o) << endl; + _dotting = false; + } + } + + void reportTest( void ) + { + if( _reported ) + return; + (*_o) << "In " << tracker().suite().suiteName() << "::" << tracker().test().testName() << ":" << endl; + _reported = true; + } + + void dump( const void *buffer, unsigned size ) + { + if ( !buffer ) + dumpNull(); + else + dumpBuffer( buffer, size ); + } + + void dumpNull() + { + (*_o) << " (null)" << endl; + } + + void dumpBuffer( const void *buffer, unsigned size ) + { + unsigned dumpSize = size; + if ( maxDumpSize() && dumpSize > maxDumpSize() ) + dumpSize = maxDumpSize(); + + const unsigned char *p = (const unsigned char *)buffer; + (*_o) << " { "; + for ( unsigned i = 0; i < dumpSize; ++ i ) + (*_o) << byteToHex( *p++ ) << " "; + if ( dumpSize < size ) + (*_o) << "... "; + (*_o) << "}" << endl; + } + + static void endl( OutputStream &o ) + { + OutputStream::endl( o ); + } + + bool _dotting; + bool _reported; + OutputStream *_o; + const char *_preLine; + const char *_postLine; + }; +}; + +#endif // __cxxtest__ErrorFormatter_h__ diff --git a/cxxtest/cxxtest/ErrorPrinter.h b/cxxtest/cxxtest/ErrorPrinter.h new file mode 100644 index 000000000..53d942532 --- /dev/null +++ b/cxxtest/cxxtest/ErrorPrinter.h @@ -0,0 +1,55 @@ +#ifndef __cxxtest__ErrorPrinter_h__ +#define __cxxtest__ErrorPrinter_h__ + +// +// The ErrorPrinter is a simple TestListener that +// just prints "OK" if everything goes well, otherwise +// reports the error in the format of compiler messages. +// The ErrorPrinter uses std::cout +// + +#include + +#ifndef _CXXTEST_HAVE_STD +# define _CXXTEST_HAVE_STD +#endif // _CXXTEST_HAVE_STD + +#include +#include + +#ifdef _CXXTEST_OLD_STD +# include +#else // !_CXXTEST_OLD_STD +# include +#endif // _CXXTEST_OLD_STD + +namespace CxxTest +{ + class ErrorPrinter : public ErrorFormatter + { + public: + ErrorPrinter( CXXTEST_STD(ostream) &o = CXXTEST_STD(cout), const char *preLine = ":", const char *postLine = "" ) : + ErrorFormatter( new Adapter(o), preLine, postLine ) {} + virtual ~ErrorPrinter() { delete outputStream(); } + + private: + class Adapter : public OutputStream + { + CXXTEST_STD(ostream) &_o; + public: + Adapter( CXXTEST_STD(ostream) &o ) : _o(o) {} + void flush() { _o.flush(); } + OutputStream &operator<<( const char *s ) { _o << s; return *this; } + OutputStream &operator<<( Manipulator m ) { return OutputStream::operator<<( m ); } + OutputStream &operator<<( unsigned i ) + { + char s[1 + 3 * sizeof(unsigned)]; + numberToString( i, s ); + _o << s; + return *this; + } + }; + }; +} + +#endif // __cxxtest__ErrorPrinter_h__ diff --git a/cxxtest/cxxtest/Flags.h b/cxxtest/cxxtest/Flags.h new file mode 100644 index 000000000..be2f9f288 --- /dev/null +++ b/cxxtest/cxxtest/Flags.h @@ -0,0 +1,121 @@ +#ifndef __cxxtest__Flags_h__ +#define __cxxtest__Flags_h__ + +// +// These are the flags that control CxxTest +// + +#if !defined(CXXTEST_FLAGS) +# define CXXTEST_FLAGS +#endif // !CXXTEST_FLAGS + +#if defined(CXXTEST_HAVE_EH) && !defined(_CXXTEST_HAVE_EH) +# define _CXXTEST_HAVE_EH +#endif // CXXTEST_HAVE_EH + +#if defined(CXXTEST_HAVE_STD) && !defined(_CXXTEST_HAVE_STD) +# define _CXXTEST_HAVE_STD +#endif // CXXTEST_HAVE_STD + +#if defined(CXXTEST_OLD_TEMPLATE_SYNTAX) && !defined(_CXXTEST_OLD_TEMPLATE_SYNTAX) +# define _CXXTEST_OLD_TEMPLATE_SYNTAX +#endif // CXXTEST_OLD_TEMPLATE_SYNTAX + +#if defined(CXXTEST_OLD_STD) && !defined(_CXXTEST_OLD_STD) +# define _CXXTEST_OLD_STD +#endif // CXXTEST_OLD_STD + +#if defined(CXXTEST_ABORT_TEST_ON_FAIL) && !defined(_CXXTEST_ABORT_TEST_ON_FAIL) +# define _CXXTEST_ABORT_TEST_ON_FAIL +#endif // CXXTEST_ABORT_TEST_ON_FAIL + +#if defined(CXXTEST_NO_COPY_CONST) && !defined(_CXXTEST_NO_COPY_CONST) +# define _CXXTEST_NO_COPY_CONST +#endif // CXXTEST_NO_COPY_CONST + +#if defined(CXXTEST_FACTOR) && !defined(_CXXTEST_FACTOR) +# define _CXXTEST_FACTOR +#endif // CXXTEST_FACTOR + +#if defined(CXXTEST_PARTIAL_TEMPLATE_SPECIALIZATION) && !defined(_CXXTEST_PARTIAL_TEMPLATE_SPECIALIZATION) +# define _CXXTEST_PARTIAL_TEMPLATE_SPECIALIZATION +#endif // CXXTEST_PARTIAL_TEMPLATE_SPECIALIZATION + +#if defined(CXXTEST_LONGLONG) +# if defined(_CXXTEST_LONGLONG) +# undef _CXXTEST_LONGLONG +# endif +# define _CXXTEST_LONGLONG CXXTEST_LONGLONG +#endif // CXXTEST_LONGLONG + +#ifndef CXXTEST_MAX_DUMP_SIZE +# define CXXTEST_MAX_DUMP_SIZE 0 +#endif // CXXTEST_MAX_DUMP_SIZE + +#if defined(_CXXTEST_ABORT_TEST_ON_FAIL) && !defined(CXXTEST_DEFAULT_ABORT) +# define CXXTEST_DEFAULT_ABORT true +#endif // _CXXTEST_ABORT_TEST_ON_FAIL && !CXXTEST_DEFAULT_ABORT + +#if !defined(CXXTEST_DEFAULT_ABORT) +# define CXXTEST_DEFAULT_ABORT false +#endif // !CXXTEST_DEFAULT_ABORT + +#if defined(_CXXTEST_ABORT_TEST_ON_FAIL) && !defined(_CXXTEST_HAVE_EH) +# warning "CXXTEST_ABORT_TEST_ON_FAIL is meaningless without CXXTEST_HAVE_EH" +# undef _CXXTEST_ABORT_TEST_ON_FAIL +#endif // _CXXTEST_ABORT_TEST_ON_FAIL && !_CXXTEST_HAVE_EH + +// +// Some minimal per-compiler configuration to allow us to compile +// + +#ifdef __BORLANDC__ +# if __BORLANDC__ <= 0x520 // Borland C++ 5.2 or earlier +# ifndef _CXXTEST_OLD_STD +# define _CXXTEST_OLD_STD +# endif +# ifndef _CXXTEST_OLD_TEMPLATE_SYNTAX +# define _CXXTEST_OLD_TEMPLATE_SYNTAX +# endif +# endif +# if __BORLANDC__ >= 0x540 // C++ Builder 4.0 or later +# ifndef _CXXTEST_NO_COPY_CONST +# define _CXXTEST_NO_COPY_CONST +# endif +# ifndef _CXXTEST_LONGLONG +# define _CXXTEST_LONGLONG __int64 +# endif +# endif +#endif // __BORLANDC__ + +#ifdef _MSC_VER // Visual C++ +# ifndef _CXXTEST_LONGLONG +# define _CXXTEST_LONGLONG __int64 +# endif +# if (_MSC_VER >= 0x51E) +# ifndef _CXXTEST_PARTIAL_TEMPLATE_SPECIALIZATION +# define _CXXTEST_PARTIAL_TEMPLATE_SPECIALIZATION +# endif +# endif +# pragma warning( disable : 4127 ) +# pragma warning( disable : 4290 ) +# pragma warning( disable : 4511 ) +# pragma warning( disable : 4512 ) +# pragma warning( disable : 4514 ) +#endif // _MSC_VER + +#ifdef __GNUC__ +# if (__GNUC__ > 2) || (__GNUC__ == 2 && __GNUC_MINOR__ >= 9) +# ifndef _CXXTEST_PARTIAL_TEMPLATE_SPECIALIZATION +# define _CXXTEST_PARTIAL_TEMPLATE_SPECIALIZATION +# endif +# endif +#endif // __GNUC__ + +#ifdef __DMC__ // Digital Mars +# ifndef _CXXTEST_OLD_STD +# define _CXXTEST_OLD_STD +# endif +#endif + +#endif // __cxxtest__Flags_h__ diff --git a/cxxtest/cxxtest/GlobalFixture.cpp b/cxxtest/cxxtest/GlobalFixture.cpp new file mode 100644 index 000000000..29c6ab83a --- /dev/null +++ b/cxxtest/cxxtest/GlobalFixture.cpp @@ -0,0 +1,23 @@ +#ifndef __cxxtest__GlobalFixture_cpp__ +#define __cxxtest__GlobalFixture_cpp__ + +#include + +namespace CxxTest +{ + bool GlobalFixture::setUpWorld() { return true; } + bool GlobalFixture::tearDownWorld() { return true; } + bool GlobalFixture::setUp() { return true; } + bool GlobalFixture::tearDown() { return true; } + + GlobalFixture::GlobalFixture() { attach( _list ); } + GlobalFixture::~GlobalFixture() { detach( _list ); } + + GlobalFixture *GlobalFixture::firstGlobalFixture() { return (GlobalFixture *)_list.head(); } + GlobalFixture *GlobalFixture::lastGlobalFixture() { return (GlobalFixture *)_list.tail(); } + GlobalFixture *GlobalFixture::nextGlobalFixture() { return (GlobalFixture *)next(); } + GlobalFixture *GlobalFixture::prevGlobalFixture() { return (GlobalFixture *)prev(); } +} + +#endif // __cxxtest__GlobalFixture_cpp__ + diff --git a/cxxtest/cxxtest/GlobalFixture.h b/cxxtest/cxxtest/GlobalFixture.h new file mode 100644 index 000000000..c8173633f --- /dev/null +++ b/cxxtest/cxxtest/GlobalFixture.h @@ -0,0 +1,30 @@ +#ifndef __cxxtest__GlobalFixture_h__ +#define __cxxtest__GlobalFixture_h__ + +#include + +namespace CxxTest +{ + class GlobalFixture : public Link + { + public: + virtual bool setUpWorld(); + virtual bool tearDownWorld(); + virtual bool setUp(); + virtual bool tearDown(); + + GlobalFixture(); + ~GlobalFixture(); + + static GlobalFixture *firstGlobalFixture(); + static GlobalFixture *lastGlobalFixture(); + GlobalFixture *nextGlobalFixture(); + GlobalFixture *prevGlobalFixture(); + + private: + static List _list; + }; +} + +#endif // __cxxtest__GlobalFixture_h__ + diff --git a/cxxtest/cxxtest/Gui.h b/cxxtest/cxxtest/Gui.h new file mode 100644 index 000000000..ac53b298f --- /dev/null +++ b/cxxtest/cxxtest/Gui.h @@ -0,0 +1,178 @@ +#ifndef __CXXTEST__GUI_H +#define __CXXTEST__GUI_H + +// +// GuiListener is a simple base class for the differes GUIs +// GuiTuiRunner combines a GUI with a text-mode error formatter +// + +#include + +namespace CxxTest +{ + class GuiListener : public TestListener + { + public: + GuiListener() : _state( GREEN_BAR ) {} + virtual ~GuiListener() {} + + virtual void runGui( int &argc, char **argv, TestListener &listener ) + { + enterGui( argc, argv ); + TestRunner::runAllTests( listener ); + leaveGui(); + } + + virtual void enterGui( int & /*argc*/, char ** /*argv*/ ) {} + virtual void leaveGui() {} + + // + // The easy way is to implement these functions: + // + virtual void guiEnterWorld( unsigned /*numTotalTests*/ ) {} + virtual void guiEnterSuite( const char * /*suiteName*/ ) {} + virtual void guiEnterTest( const char * /*suiteName*/, const char * /*testName*/ ) {} + virtual void yellowBar() {} + virtual void redBar() {} + + // + // The hard way is this: + // + void enterWorld( const WorldDescription &d ) { guiEnterWorld( d.numTotalTests() ); } + void enterSuite( const SuiteDescription &d ) { guiEnterSuite( d.suiteName() ); } + void enterTest( const TestDescription &d ) { guiEnterTest( d.suiteName(), d.testName() ); } + void leaveTest( const TestDescription & ) {} + void leaveSuite( const SuiteDescription & ) {} + void leaveWorld( const WorldDescription & ) {} + + void warning( const char * /*file*/, unsigned /*line*/, const char * /*expression*/ ) + { + yellowBarSafe(); + } + + void failedTest( const char * /*file*/, unsigned /*line*/, const char * /*expression*/ ) + { + redBarSafe(); + } + + void failedAssert( const char * /*file*/, unsigned /*line*/, const char * /*expression*/ ) + { + redBarSafe(); + } + + void failedAssertEquals( const char * /*file*/, unsigned /*line*/, + const char * /*xStr*/, const char * /*yStr*/, + const char * /*x*/, const char * /*y*/ ) + { + redBarSafe(); + } + + void failedAssertSameData( const char * /*file*/, unsigned /*line*/, + const char * /*xStr*/, const char * /*yStr*/, + const char * /*sizeStr*/, const void * /*x*/, + const void * /*y*/, unsigned /*size*/ ) + { + redBarSafe(); + } + + void failedAssertDelta( const char * /*file*/, unsigned /*line*/, + const char * /*xStr*/, const char * /*yStr*/, const char * /*dStr*/, + const char * /*x*/, const char * /*y*/, const char * /*d*/ ) + { + redBarSafe(); + } + + void failedAssertDiffers( const char * /*file*/, unsigned /*line*/, + const char * /*xStr*/, const char * /*yStr*/, + const char * /*value*/ ) + { + redBarSafe(); + } + + void failedAssertLessThan( const char * /*file*/, unsigned /*line*/, + const char * /*xStr*/, const char * /*yStr*/, + const char * /*x*/, const char * /*y*/ ) + { + redBarSafe(); + } + + void failedAssertLessThanEquals( const char * /*file*/, unsigned /*line*/, + const char * /*xStr*/, const char * /*yStr*/, + const char * /*x*/, const char * /*y*/ ) + { + redBarSafe(); + } + + void failedAssertPredicate( const char * /*file*/, unsigned /*line*/, + const char * /*predicate*/, const char * /*xStr*/, const char * /*x*/ ) + { + redBarSafe(); + } + + void failedAssertRelation( const char * /*file*/, unsigned /*line*/, + const char * /*relation*/, const char * /*xStr*/, const char * /*yStr*/, + const char * /*x*/, const char * /*y*/ ) + { + redBarSafe(); + } + + void failedAssertThrows( const char * /*file*/, unsigned /*line*/, + const char * /*expression*/, const char * /*type*/, + bool /*otherThrown*/ ) + { + redBarSafe(); + } + + void failedAssertThrowsNot( const char * /*file*/, unsigned /*line*/, + const char * /*expression*/ ) + { + redBarSafe(); + } + + protected: + void yellowBarSafe() + { + if ( _state < YELLOW_BAR ) { + yellowBar(); + _state = YELLOW_BAR; + } + } + + void redBarSafe() + { + if ( _state < RED_BAR ) { + redBar(); + _state = RED_BAR; + } + } + + private: + enum { GREEN_BAR, YELLOW_BAR, RED_BAR } _state; + }; + + template + class GuiTuiRunner : public TeeListener + { + int &_argc; + char **_argv; + GuiT _gui; + TuiT _tui; + + public: + GuiTuiRunner( int &argc, char **argv ) : + _argc( argc ), + _argv( argv ) + { + setFirst( _gui ); + setSecond( _tui ); + } + + int run() + { + _gui.runGui( _argc, _argv, *this ); + return tracker().failedTests(); + } + }; +}; + +#endif //__CXXTEST__GUI_H diff --git a/cxxtest/cxxtest/LinkedList.cpp b/cxxtest/cxxtest/LinkedList.cpp new file mode 100644 index 000000000..fb81d64ca --- /dev/null +++ b/cxxtest/cxxtest/LinkedList.cpp @@ -0,0 +1,172 @@ +#ifndef __cxxtest__LinkedList_cpp__ +#define __cxxtest__LinkedList_cpp__ + +#include + +namespace CxxTest +{ + List GlobalFixture::_list = { 0, 0 }; + List RealSuiteDescription::_suites = { 0, 0 }; + + void List::initialize() + { + _head = _tail = 0; + } + + Link *List::head() + { + Link *l = _head; + while ( l && !l->active() ) + l = l->next(); + return l; + } + + const Link *List::head() const + { + Link *l = _head; + while ( l && !l->active() ) + l = l->next(); + return l; + } + + Link *List::tail() + { + Link *l = _tail; + while ( l && !l->active() ) + l = l->prev(); + return l; + } + + const Link *List::tail() const + { + Link *l = _tail; + while ( l && !l->active() ) + l = l->prev(); + return l; + } + + bool List::empty() const + { + return (_head == 0); + } + + unsigned List::size() const + { + unsigned count = 0; + for ( const Link *l = head(); l != 0; l = l->next() ) + ++ count; + return count; + } + + Link *List::nth( unsigned n ) + { + Link *l = head(); + while ( n -- ) + l = l->next(); + return l; + } + + void List::activateAll() + { + for ( Link *l = _head; l != 0; l = l->justNext() ) + l->setActive( true ); + } + + void List::leaveOnly( const Link &link ) + { + for ( Link *l = head(); l != 0; l = l->next() ) + if ( l != &link ) + l->setActive( false ); + } + + Link::Link() : + _next( 0 ), + _prev( 0 ), + _active( true ) + { + } + + Link::~Link() + { + } + + bool Link::active() const + { + return _active; + } + + void Link::setActive( bool value ) + { + _active = value; + } + + Link * Link::justNext() + { + return _next; + } + + Link * Link::justPrev() + { + return _prev; + } + + Link * Link::next() + { + Link *l = _next; + while ( l && !l->_active ) + l = l->_next; + return l; + } + + Link * Link::prev() + { + Link *l = _prev; + while ( l && !l->_active ) + l = l->_prev; + return l; + } + + const Link * Link::next() const + { + Link *l = _next; + while ( l && !l->_active ) + l = l->_next; + return l; + } + + const Link * Link::prev() const + { + Link *l = _prev; + while ( l && !l->_active ) + l = l->_prev; + return l; + } + + void Link::attach( List &l ) + { + if ( l._tail ) + l._tail->_next = this; + + _prev = l._tail; + _next = 0; + + if ( l._head == 0 ) + l._head = this; + l._tail = this; + } + + void Link::detach( List &l ) + { + if ( _prev ) + _prev->_next = _next; + else + l._head = _next; + + if ( _next ) + _next->_prev = _prev; + else + l._tail = _prev; + } +}; + +#endif // __cxxtest__LinkedList_cpp__ diff --git a/cxxtest/cxxtest/LinkedList.h b/cxxtest/cxxtest/LinkedList.h new file mode 100644 index 000000000..983a6e244 --- /dev/null +++ b/cxxtest/cxxtest/LinkedList.h @@ -0,0 +1,65 @@ +#ifndef __cxxtest__LinkedList_h__ +#define __cxxtest__LinkedList_h__ + +#include + +namespace CxxTest +{ + struct List; + class Link; + + struct List + { + Link *_head; + Link *_tail; + + void initialize(); + + Link *head(); + const Link *head() const; + Link *tail(); + const Link *tail() const; + + bool empty() const; + unsigned size() const; + Link *nth( unsigned n ); + + void activateAll(); + void leaveOnly( const Link &link ); + }; + + class Link + { + public: + Link(); + virtual ~Link(); + + bool active() const; + void setActive( bool value = true ); + + Link *justNext(); + Link *justPrev(); + + Link *next(); + Link *prev(); + const Link *next() const; + const Link *prev() const; + + virtual bool setUp() = 0; + virtual bool tearDown() = 0; + + void attach( List &l ); + void detach( List &l ); + + private: + Link *_next; + Link *_prev; + bool _active; + + Link( const Link & ); + Link &operator=( const Link & ); + }; +} + +#endif // __cxxtest__LinkedList_h__ + diff --git a/cxxtest/cxxtest/Mock.h b/cxxtest/cxxtest/Mock.h new file mode 100644 index 000000000..647088e80 --- /dev/null +++ b/cxxtest/cxxtest/Mock.h @@ -0,0 +1,350 @@ +#ifndef __cxxtest__Mock_h__ +#define __cxxtest__Mock_h__ + +// +// The default namespace is T:: +// +#ifndef CXXTEST_MOCK_NAMESPACE +# define CXXTEST_MOCK_NAMESPACE T +#endif // CXXTEST_MOCK_NAMESPACE + +// +// MockTraits: What to return when no mock object has been created +// +#define __CXXTEST_MOCK__TRAITS \ + namespace CXXTEST_MOCK_NAMESPACE \ + { \ + template \ + class MockTraits \ + { \ + public: \ + static T defaultValue() { return 0; } \ + }; \ + }; + +// +// extern "C" when needed +// +#ifdef __cplusplus +# define CXXTEST_EXTERN_C extern "C" +#else +# define CXXTEST_EXTERN_C +#endif // __cplusplus + +// +// Prototypes: For "normal" headers +// +#define __CXXTEST_MOCK__PROTOTYPE( MOCK, TYPE, NAME, ARGS, REAL, CALL ) \ + namespace CXXTEST_MOCK_NAMESPACE { TYPE NAME ARGS; } + +#define __CXXTEST_MOCK_VOID__PROTOTYPE( MOCK, NAME, ARGS, REAL, CALL ) \ + __CXXTEST_MOCK__PROTOTYPE( MOCK, void, NAME, ARGS, REAL, CALL ) + +#define __CXXTEST_SUPPLY__PROTOTYPE( MOCK, TYPE, NAME, ARGS, REAL, CALL ) \ + TYPE REAL ARGS; + +#define __CXXTEST_SUPPLY_VOID__PROTOTYPE( MOCK, NAME, ARGS, REAL, CALL ) \ + __CXXTEST_SUPPLY__PROTOTYPE( MOCK, void, NAME, ARGS, REAL, CALL ) + +// +// Class declarations: For test files +// +#define __CXXTEST_MOCK__CLASS_DECLARATION( MOCK, TYPE, NAME, ARGS, REAL, CALL ) \ + namespace CXXTEST_MOCK_NAMESPACE { \ + class Base_##MOCK : public CxxTest::Link \ + { \ + public: \ + Base_##MOCK(); \ + ~Base_##MOCK(); \ + bool setUp(); \ + bool tearDown(); \ + \ + static Base_##MOCK ¤t(); \ + \ + virtual TYPE NAME ARGS = 0; \ + \ + private: \ + static CxxTest::List _list; \ + }; \ + \ + class Real_##MOCK : public Base_##MOCK \ + { \ + public: \ + TYPE NAME ARGS; \ + }; \ + \ + class _Unimplemented_##MOCK : public Base_##MOCK \ + { \ + public: \ + TYPE NAME ARGS; \ + }; \ + } + +#define __CXXTEST_MOCK_VOID__CLASS_DECLARATION( MOCK, NAME, ARGS, REAL, CALL ) \ + __CXXTEST_MOCK__CLASS_DECLARATION( MOCK, void, NAME, ARGS, REAL, CALL ) + +#define __CXXTEST_SUPPLY__CLASS_DECLARATION( MOCK, TYPE, NAME, ARGS, REAL, CALL ) \ + namespace CXXTEST_MOCK_NAMESPACE { \ + class Base_##MOCK : public CxxTest::Link \ + { \ + public: \ + Base_##MOCK(); \ + ~Base_##MOCK(); \ + bool setUp(); \ + bool tearDown(); \ + \ + static Base_##MOCK ¤t(); \ + \ + virtual TYPE NAME ARGS = 0; \ + \ + private: \ + static CxxTest::List _list; \ + }; \ + \ + class _Unimplemented_##MOCK : public Base_##MOCK \ + { \ + public: \ + TYPE NAME ARGS; \ + }; \ + } + +#define __CXXTEST_SUPPLY_VOID__CLASS_DECLARATION( MOCK, NAME, ARGS, REAL, CALL ) \ + __CXXTEST_SUPPLY__CLASS_DECLARATION( MOCK, void, NAME, ARGS, REAL, CALL ) + +// +// Class implementation: For test source files +// +#define __CXXTEST_MOCK__COMMON_CLASS_IMPLEMENTATION( MOCK, NAME ) \ + namespace CXXTEST_MOCK_NAMESPACE { \ + \ + CxxTest::List Base_##MOCK::_list = { 0, 0 }; \ + \ + Base_##MOCK::Base_##MOCK() { attach( _list ); } \ + Base_##MOCK::~Base_##MOCK() { detach( _list ); } \ + bool Base_##MOCK::setUp() { return true; } \ + bool Base_##MOCK::tearDown() { return true; } \ + \ + Base_##MOCK &Base_##MOCK::current() \ + { \ + if ( _list.empty() ) \ + static _Unimplemented_##MOCK unimplemented; \ + return *(Base_##MOCK *)_list.tail(); \ + } \ + } + +#define __CXXTEST_MOCK__CLASS_IMPLEMENTATION( MOCK, TYPE, NAME, ARGS, REAL, CALL ) \ + __CXXTEST_MOCK__COMMON_CLASS_IMPLEMENTATION( MOCK, NAME ) \ + namespace CXXTEST_MOCK_NAMESPACE { \ + TYPE Real_##MOCK::NAME ARGS \ + { \ + return REAL CALL; \ + } \ + \ + TYPE _Unimplemented_##MOCK::NAME ARGS \ + { \ + while ( false ) \ + return NAME CALL; \ + __CXXTEST_MOCK_UNIMPLEMENTED( NAME, ARGS ); \ + return MockTraits::defaultValue(); \ + } \ + \ + TYPE NAME ARGS \ + { \ + return Base_##MOCK::current().NAME CALL; \ + } \ + } + +#define __CXXTEST_MOCK_VOID__CLASS_IMPLEMENTATION( MOCK, NAME, ARGS, REAL, CALL ) \ + __CXXTEST_MOCK__COMMON_CLASS_IMPLEMENTATION( MOCK, NAME ) \ + namespace CXXTEST_MOCK_NAMESPACE { \ + void Real_##MOCK::NAME ARGS \ + { \ + REAL CALL; \ + } \ + \ + void _Unimplemented_##MOCK::NAME ARGS \ + { \ + while ( false ) \ + NAME CALL; \ + __CXXTEST_MOCK_UNIMPLEMENTED( NAME, ARGS ); \ + } \ + \ + void NAME ARGS \ + { \ + Base_##MOCK::current().NAME CALL; \ + } \ + } + +#define __CXXTEST_SUPPLY__CLASS_IMPLEMENTATION( MOCK, TYPE, NAME, ARGS, REAL, CALL ) \ + __CXXTEST_MOCK__COMMON_CLASS_IMPLEMENTATION( MOCK, NAME ) \ + namespace CXXTEST_MOCK_NAMESPACE { \ + TYPE _Unimplemented_##MOCK::NAME ARGS \ + { \ + while ( false ) \ + return NAME CALL; \ + __CXXTEST_MOCK_UNIMPLEMENTED( NAME, ARGS ); \ + return MockTraits::defaultValue(); \ + } \ + } \ + \ + TYPE REAL ARGS \ + { \ + return CXXTEST_MOCK_NAMESPACE::Base_##MOCK::current().NAME CALL; \ + } + +#define __CXXTEST_SUPPLY_VOID__CLASS_IMPLEMENTATION( MOCK, NAME, ARGS, REAL, CALL ) \ + __CXXTEST_MOCK__COMMON_CLASS_IMPLEMENTATION( MOCK, NAME ) \ + namespace CXXTEST_MOCK_NAMESPACE { \ + void _Unimplemented_##MOCK::NAME ARGS \ + { \ + while ( false ) \ + NAME CALL; \ + __CXXTEST_MOCK_UNIMPLEMENTED( NAME, ARGS ); \ + } \ + } \ + \ + void REAL ARGS \ + { \ + CXXTEST_MOCK_NAMESPACE::Base_##MOCK::current().NAME CALL; \ + } \ + +// +// Error for calling mock function w/o object +// +#define __CXXTEST_MOCK_UNIMPLEMENTED( NAME, ARGS ) \ + TS_FAIL( CXXTEST_MOCK_NAMESPACE_STR #NAME #ARGS " called with no " \ + CXXTEST_MOCK_NAMESPACE_STR "Base_" #NAME " object" ); \ + +#define CXXTEST_MOCK_NAMESPACE_STR __CXXTEST_STR(CXXTEST_MOCK_NAMESPACE) "::" +#define __CXXTEST_STR(X) __CXXTEST_XSTR(X) +#define __CXXTEST_XSTR(X) #X + +#if defined(CXXTEST_MOCK_TEST_SOURCE_FILE) +// +// Test source file: Prototypes, class declarations and implementation +// +#include + +__CXXTEST_MOCK__TRAITS; + +#define CXXTEST_MOCK( MOCK, TYPE, NAME, ARGS, REAL, CALL ) \ + __CXXTEST_MOCK__PROTOTYPE( MOCK, TYPE, NAME, ARGS, REAL, CALL ) \ + __CXXTEST_MOCK__CLASS_DECLARATION( MOCK, TYPE, NAME, ARGS, REAL, CALL ) \ + __CXXTEST_MOCK__CLASS_IMPLEMENTATION( MOCK, TYPE, NAME, ARGS, REAL, CALL ) + +#define CXXTEST_MOCK_VOID( MOCK, NAME, ARGS, REAL, CALL ) \ + __CXXTEST_MOCK_VOID__PROTOTYPE( MOCK, NAME, ARGS, REAL, CALL ) \ + __CXXTEST_MOCK_VOID__CLASS_DECLARATION( MOCK, NAME, ARGS, REAL, CALL ) \ + __CXXTEST_MOCK_VOID__CLASS_IMPLEMENTATION( MOCK, NAME, ARGS, REAL, CALL ) + +#define CXXTEST_SUPPLY( MOCK, TYPE, NAME, ARGS, REAL, CALL ) \ + __CXXTEST_SUPPLY__PROTOTYPE( MOCK, TYPE, NAME, ARGS, REAL, CALL ) \ + __CXXTEST_SUPPLY__CLASS_DECLARATION( MOCK, TYPE, NAME, ARGS, REAL, CALL ) \ + __CXXTEST_SUPPLY__CLASS_IMPLEMENTATION( MOCK, TYPE, NAME, ARGS, REAL, CALL ) + +#define CXXTEST_SUPPLY_VOID( MOCK, NAME, ARGS, REAL, CALL ) \ + __CXXTEST_SUPPLY_VOID__PROTOTYPE( MOCK, NAME, ARGS, REAL, CALL ) \ + __CXXTEST_SUPPLY_VOID__CLASS_DECLARATION( MOCK, NAME, ARGS, REAL, CALL ) \ + __CXXTEST_SUPPLY_VOID__CLASS_IMPLEMENTATION( MOCK, NAME, ARGS, REAL, CALL ) + +#elif defined(CXXTEST_FLAGS) || defined(CXXTEST_RUNNING) +// +// Test file other than source: Prototypes and class declarations +// +#include + +__CXXTEST_MOCK__TRAITS; + +#define CXXTEST_MOCK( MOCK, TYPE, NAME, ARGS, REAL, CALL ) \ + __CXXTEST_MOCK__PROTOTYPE( MOCK, TYPE, NAME, ARGS, REAL, CALL ) \ + __CXXTEST_MOCK__CLASS_DECLARATION( MOCK, TYPE, NAME, ARGS, REAL, CALL ) + +#define CXXTEST_MOCK_VOID( MOCK, NAME, ARGS, REAL, CALL ) \ + __CXXTEST_MOCK_VOID__PROTOTYPE( MOCK, NAME, ARGS, REAL, CALL ) \ + __CXXTEST_MOCK_VOID__CLASS_DECLARATION( MOCK, NAME, ARGS, REAL, CALL ) + +#define CXXTEST_SUPPLY( MOCK, TYPE, NAME, ARGS, REAL, CALL ) \ + __CXXTEST_SUPPLY__PROTOTYPE( MOCK, TYPE, NAME, ARGS, REAL, CALL ) \ + __CXXTEST_SUPPLY__CLASS_DECLARATION( MOCK, TYPE, NAME, ARGS, REAL, CALL ) + +#define CXXTEST_SUPPLY_VOID( MOCK, NAME, ARGS, REAL, CALL ) \ + __CXXTEST_SUPPLY_VOID__PROTOTYPE( MOCK, NAME, ARGS, REAL, CALL ) \ + __CXXTEST_SUPPLY_VOID__CLASS_DECLARATION( MOCK, NAME, ARGS, REAL, CALL ) + +#elif defined(CXXTEST_MOCK_REAL_SOURCE_FILE) +// +// Real source file: "Real" implementations +// +#define CXXTEST_MOCK( MOCK, TYPE, NAME, ARGS, REAL, CALL ) \ + namespace CXXTEST_MOCK_NAMESPACE { TYPE NAME ARGS { return REAL CALL; } } + +#define CXXTEST_MOCK_VOID( MOCK, NAME, ARGS, REAL, CALL ) \ + namespace CXXTEST_MOCK_NAMESPACE { void NAME ARGS { REAL CALL; } } + +#else +// +// Ordinary header file: Just prototypes +// + +#define CXXTEST_MOCK( MOCK, TYPE, NAME, ARGS, REAL, CALL ) \ + __CXXTEST_MOCK__PROTOTYPE( MOCK, TYPE, NAME, ARGS, REAL, CALL ) + +#define CXXTEST_MOCK_VOID( MOCK, NAME, ARGS, REAL, CALL ) \ + __CXXTEST_MOCK_VOID__PROTOTYPE( MOCK, NAME, ARGS, REAL, CALL ) + +#define CXXTEST_SUPPLY( MOCK, TYPE, NAME, ARGS, REAL, CALL ) \ + __CXXTEST_SUPPLY__PROTOTYPE( MOCK, TYPE, NAME, ARGS, REAL, CALL ) + +#define CXXTEST_SUPPLY_VOID( MOCK, NAME, ARGS, REAL, CALL ) \ + __CXXTEST_SUPPLY_VOID__PROTOTYPE( MOCK, NAME, ARGS, REAL, CALL ) + +#endif // Ordinary header file + +// +// How to supply extern "C" functions +// +#define CXXTEST_SUPPLY_C( MOCK, TYPE, NAME, ARGS, REAL, CALL ) \ + CXXTEST_EXTERN_C __CXXTEST_SUPPLY__PROTOTYPE( MOCK, TYPE, NAME, ARGS, REAL, CALL ) \ + CXXTEST_SUPPLY( MOCK, TYPE, NAME, ARGS, REAL, CALL ) + +#define CXXTEST_SUPPLY_VOID_C( MOCK, NAME, ARGS, REAL, CALL ) \ + CXXTEST_EXTERN_C __CXXTEST_SUPPLY_VOID__PROTOTYPE( MOCK, NAME, ARGS, REAL, CALL ) \ + CXXTEST_SUPPLY_VOID( MOCK, NAME, ARGS, REAL, CALL ) + +// +// Usually we mean the global namespace +// +#define CXXTEST_MOCK_GLOBAL( TYPE, NAME, ARGS, CALL ) \ + CXXTEST_MOCK( NAME, TYPE, NAME, ARGS, ::NAME, CALL ) + +#define CXXTEST_MOCK_VOID_GLOBAL( NAME, ARGS, CALL ) \ + CXXTEST_MOCK_VOID( NAME, NAME, ARGS, ::NAME, CALL ) + +#define CXXTEST_SUPPLY_GLOBAL( TYPE, NAME, ARGS, CALL ) \ + CXXTEST_SUPPLY( NAME, TYPE, NAME, ARGS, NAME, CALL ) + +#define CXXTEST_SUPPLY_VOID_GLOBAL( NAME, ARGS, CALL ) \ + CXXTEST_SUPPLY_VOID( NAME, NAME, ARGS, NAME, CALL ) + +#define CXXTEST_SUPPLY_GLOBAL_C( TYPE, NAME, ARGS, CALL ) \ + CXXTEST_SUPPLY_C( NAME, TYPE, NAME, ARGS, NAME, CALL ) + +#define CXXTEST_SUPPLY_VOID_GLOBAL_C( NAME, ARGS, CALL ) \ + CXXTEST_SUPPLY_VOID_C( NAME, NAME, ARGS, NAME, CALL ) + +// +// What to return when no mock object has been created. +// The default value of 0 usually works, but some cases may need this. +// +#define CXXTEST_MOCK_DEFAULT_VALUE( TYPE, VALUE ) \ + namespace CXXTEST_MOCK_NAMESPACE \ + { \ + template<> \ + class MockTraits \ + { \ + public: \ + static TYPE defaultValue() { return VALUE; } \ + }; \ + } + +#endif // __cxxtest__Mock_h__ diff --git a/cxxtest/cxxtest/ParenPrinter.h b/cxxtest/cxxtest/ParenPrinter.h new file mode 100644 index 000000000..9ecf31053 --- /dev/null +++ b/cxxtest/cxxtest/ParenPrinter.h @@ -0,0 +1,21 @@ +#ifndef __cxxtest__ParenPrinter_h__ +#define __cxxtest__ParenPrinter_h__ + +// +// The ParenPrinter is identical to the ErrorPrinter, except it +// prints the line number in a format expected by some compilers +// (notably, MSVC). +// + +#include + +namespace CxxTest +{ + class ParenPrinter : public ErrorPrinter + { + public: + ParenPrinter( CXXTEST_STD(ostream) &o = CXXTEST_STD(cout) ) : ErrorPrinter( o, "(", ")" ) {} + }; +} + +#endif // __cxxtest__ParenPrinter_h__ diff --git a/cxxtest/cxxtest/QtGui.h b/cxxtest/cxxtest/QtGui.h new file mode 100644 index 000000000..889825106 --- /dev/null +++ b/cxxtest/cxxtest/QtGui.h @@ -0,0 +1,271 @@ +#ifndef __cxxtest__QtGui_h__ +#define __cxxtest__QtGui_h__ + +// +// The QtGui displays a simple progress bar using the Qt Toolkit. It +// has been tested with versions 2.x and 3.x. +// +// Apart from normal Qt command-line arguments, it accepts the following options: +// -minimized Start minimized, pop up on error +// -keep Don't close the window at the end +// -title TITLE Set the window caption +// +// If both are -minimized and -keep specified, GUI will only keep the +// window if it's in focus. +// + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace CxxTest +{ + class QtGui : public GuiListener + { + public: + void enterGui( int &argc, char **argv ) + { + parseCommandLine( argc, argv ); + createApplication( argc, argv ); + } + + void enterWorld( const WorldDescription &wd ) + { + createWindow( wd ); + processEvents(); + } + + void guiEnterSuite( const char *suiteName ) + { + showSuiteName( suiteName ); + } + + void guiEnterTest( const char *suiteName, const char *testName ) + { + setCaption( suiteName, testName ); + advanceProgressBar(); + showTestName( testName ); + showTestsDone( _progressBar->progress() ); + processEvents(); + } + + void yellowBar() + { + setColor( 255, 255, 0 ); + setIcon( QMessageBox::Warning ); + getTotalTests(); + processEvents(); + } + + void redBar() + { + if ( _startMinimized && _mainWindow->isMinimized() ) + showNormal(); + setColor( 255, 0, 0 ); + setIcon( QMessageBox::Critical ); + getTotalTests(); + processEvents(); + } + + void leaveGui() + { + if ( keep() ) { + showSummary(); + _application->exec(); + } + else + _mainWindow->close( true ); + } + + private: + QString _title; + bool _startMinimized, _keep; + unsigned _numTotalTests; + QString _strTotalTests; + QApplication *_application; + QWidget *_mainWindow; + QVBoxLayout *_layout; + QProgressBar *_progressBar; + QStatusBar *_statusBar; + QLabel *_suiteName, *_testName, *_testsDone; + + void parseCommandLine( int argc, char **argv ) + { + _startMinimized = _keep = false; + _title = argv[0]; + + for ( int i = 1; i < argc; ++ i ) { + QString arg( argv[i] ); + if ( arg == "-minimized" ) + _startMinimized = true; + else if ( arg == "-keep" ) + _keep = true; + else if ( arg == "-title" && (i + 1 < argc) ) + _title = argv[++i]; + } + } + + void createApplication( int &argc, char **argv ) + { + _application = new QApplication( argc, argv ); + } + + void createWindow( const WorldDescription &wd ) + { + getTotalTests( wd ); + createMainWindow(); + createProgressBar(); + createStatusBar(); + setMainWidget(); + if ( _startMinimized ) + showMinimized(); + else + showNormal(); + } + + void getTotalTests() + { + getTotalTests( tracker().world() ); + } + + void getTotalTests( const WorldDescription &wd ) + { + _numTotalTests = wd.numTotalTests(); + char s[WorldDescription::MAX_STRLEN_TOTAL_TESTS]; + _strTotalTests = wd.strTotalTests( s ); + } + + void createMainWindow() + { + _mainWindow = new QWidget(); + _layout = new QVBoxLayout( _mainWindow ); + } + + void createProgressBar() + { + _layout->addWidget( _progressBar = new QProgressBar( _numTotalTests, _mainWindow ) ); + _progressBar->setProgress( 0 ); + setColor( 0, 255, 0 ); + setIcon( QMessageBox::Information ); + } + + void createStatusBar() + { + _layout->addWidget( _statusBar = new QStatusBar( _mainWindow ) ); + _statusBar->addWidget( _suiteName = new QLabel( _statusBar ), 2 ); + _statusBar->addWidget( _testName = new QLabel( _statusBar ), 4 ); + _statusBar->addWidget( _testsDone = new QLabel( _statusBar ), 1 ); + } + + void setMainWidget() + { + _application->setMainWidget( _mainWindow ); + } + + void showMinimized() + { + _mainWindow->showMinimized(); + } + + void showNormal() + { + _mainWindow->showNormal(); + centerWindow(); + } + + void setCaption( const QString &suiteName, const QString &testName ) + { + _mainWindow->setCaption( _title + " - " + suiteName + "::" + testName + "()" ); + } + + void showSuiteName( const QString &suiteName ) + { + _suiteName->setText( "class " + suiteName ); + } + + void advanceProgressBar() + { + _progressBar->setProgress( _progressBar->progress() + 1 ); + } + + void showTestName( const QString &testName ) + { + _testName->setText( testName + "()" ); + } + + void showTestsDone( unsigned testsDone ) + { + _testsDone->setText( asString( testsDone ) + " of " + _strTotalTests ); + } + + static QString asString( unsigned n ) + { + return QString::number( n ); + } + + void setColor( int r, int g, int b ) + { + QPalette palette = _progressBar->palette(); + palette.setColor( QColorGroup::Highlight, QColor( r, g, b ) ); + _progressBar->setPalette( palette ); + } + + void setIcon( QMessageBox::Icon icon ) + { +#if QT_VERSION >= 0x030000 + _mainWindow->setIcon( QMessageBox::standardIcon( icon ) ); +#else // Qt version < 3.0.0 + _mainWindow->setIcon( QMessageBox::standardIcon( icon, QApplication::style().guiStyle() ) ); +#endif // QT_VERSION + } + + void processEvents() + { + _application->processEvents(); + } + + void centerWindow() + { + QWidget *desktop = QApplication::desktop(); + int xCenter = desktop->x() + (desktop->width() / 2); + int yCenter = desktop->y() + (desktop->height() / 2); + + int windowWidth = (desktop->width() * 4) / 5; + int windowHeight = _mainWindow->height(); + _mainWindow->setGeometry( xCenter - (windowWidth / 2), yCenter - (windowHeight / 2), windowWidth, windowHeight ); + } + + bool keep() + { + if ( !_keep ) + return false; + if ( !_startMinimized ) + return true; + return (_mainWindow == _application->activeWindow()); + } + + void showSummary() + { + QString summary = _strTotalTests + (_numTotalTests == 1 ? " test" : " tests"); + if ( tracker().failedTests() ) + summary = "Failed " + asString( tracker().failedTests() ) + " of " + summary; + else + summary = summary + " passed"; + + _mainWindow->setCaption( _title + " - " + summary ); + + _statusBar->removeWidget( _suiteName ); + _statusBar->removeWidget( _testName ); + _testsDone->setText( summary ); + } + }; +}; + +#endif // __cxxtest__QtGui_h__ diff --git a/cxxtest/cxxtest/RealDescriptions.cpp b/cxxtest/cxxtest/RealDescriptions.cpp new file mode 100644 index 000000000..1e21ca762 --- /dev/null +++ b/cxxtest/cxxtest/RealDescriptions.cpp @@ -0,0 +1,311 @@ +#ifndef __cxxtest__RealDescriptions_cpp__ +#define __cxxtest__RealDescriptions_cpp__ + +// +// NOTE: If an error occur during world construction/deletion, CxxTest cannot +// know where the error originated. +// + +#include + +namespace CxxTest +{ + RealTestDescription::RealTestDescription() + { + } + + RealTestDescription::RealTestDescription( List &argList, + SuiteDescription &argSuite, + unsigned argLine, + const char *argTestName ) + { + initialize( argList, argSuite, argLine, argTestName ); + } + + void RealTestDescription::initialize( List &argList, + SuiteDescription &argSuite, + unsigned argLine, + const char *argTestName ) + { + _suite = &argSuite; + _line = argLine; + _testName = argTestName; + attach( argList ); + } + + bool RealTestDescription::setUp() + { + if ( !suite() ) + return false; + + for ( GlobalFixture *gf = GlobalFixture::firstGlobalFixture(); gf != 0; gf = gf->nextGlobalFixture() ) { + bool ok; + _TS_TRY { ok = gf->setUp(); } + _TS_LAST_CATCH( { ok = false; } ); + + if ( !ok ) { + doFailTest( file(), line(), "Error in GlobalFixture::setUp()" ); + return false; + } + } + + _TS_TRY { + _TSM_ASSERT_THROWS_NOTHING( file(), line(), "Exception thrown from setUp()", suite()->setUp() ); + } + _TS_CATCH_ABORT( { return false; } ); + + return true; + } + + bool RealTestDescription::tearDown() + { + if ( !suite() ) + return false; + + _TS_TRY { + _TSM_ASSERT_THROWS_NOTHING( file(), line(), "Exception thrown from tearDown()", suite()->tearDown() ); + } + _TS_CATCH_ABORT( { return false; } ); + + for ( GlobalFixture *gf = GlobalFixture::lastGlobalFixture(); gf != 0; gf = gf->prevGlobalFixture() ) { + bool ok; + _TS_TRY { ok = gf->tearDown(); } + _TS_LAST_CATCH( { ok = false; } ); + + if ( !ok ) { + doFailTest( file(), line(), "Error in GlobalFixture::tearDown()" ); + return false; + } + } + + return true; + } + + const char *RealTestDescription::file() const { return _suite->file(); } + unsigned RealTestDescription::line() const { return _line; } + const char *RealTestDescription::testName() const { return _testName; } + const char *RealTestDescription::suiteName() const { return _suite->suiteName(); } + + TestDescription *RealTestDescription::next() { return (RealTestDescription *)Link::next(); } + const TestDescription *RealTestDescription::next() const { return (const RealTestDescription *)Link::next(); } + + TestSuite *RealTestDescription::suite() const { return _suite->suite(); } + + void RealTestDescription::run() + { + _TS_TRY { runTest(); } + _TS_CATCH_ABORT( {} ) + ___TSM_CATCH( file(), line(), "Exception thrown from test" ); + } + + RealSuiteDescription::RealSuiteDescription() {} + RealSuiteDescription::RealSuiteDescription( const char *argFile, + unsigned argLine, + const char *argSuiteName, + List &argTests ) + { + initialize( argFile, argLine, argSuiteName, argTests ); + } + + void RealSuiteDescription::initialize( const char *argFile, + unsigned argLine, + const char *argSuiteName, + List &argTests ) + { + _file = argFile; + _line = argLine; + _suiteName = argSuiteName; + _tests = &argTests; + + attach( _suites ); + } + + const char *RealSuiteDescription::file() const { return _file; } + unsigned RealSuiteDescription::line() const { return _line; } + const char *RealSuiteDescription::suiteName() const { return _suiteName; } + + TestDescription *RealSuiteDescription::firstTest() { return (RealTestDescription *)_tests->head(); } + const TestDescription *RealSuiteDescription::firstTest() const { return (const RealTestDescription *)_tests->head(); } + SuiteDescription *RealSuiteDescription::next() { return (RealSuiteDescription *)Link::next(); } + const SuiteDescription *RealSuiteDescription::next() const { return (const RealSuiteDescription *)Link::next(); } + + unsigned RealSuiteDescription::numTests() const { return _tests->size(); } + + const TestDescription &RealSuiteDescription::testDescription( unsigned i ) const + { + return *(RealTestDescription *)_tests->nth( i ); + } + + void RealSuiteDescription::activateAllTests() + { + _tests->activateAll(); + } + + bool RealSuiteDescription::leaveOnly( const char *testName ) + { + for ( TestDescription *td = firstTest(); td != 0; td = td->next() ) { + if ( stringsEqual( td->testName(), testName ) ) { + _tests->leaveOnly( *td ); + return true; + } + } + return false; + } + + StaticSuiteDescription::StaticSuiteDescription() {} + StaticSuiteDescription::StaticSuiteDescription( const char *argFile, unsigned argLine, + const char *argSuiteName, TestSuite &argSuite, + List &argTests ) : + RealSuiteDescription( argFile, argLine, argSuiteName, argTests ) + { + doInitialize( argSuite ); + } + + void StaticSuiteDescription::initialize( const char *argFile, unsigned argLine, + const char *argSuiteName, TestSuite &argSuite, + List &argTests ) + { + RealSuiteDescription::initialize( argFile, argLine, argSuiteName, argTests ); + doInitialize( argSuite ); + } + + void StaticSuiteDescription::doInitialize( TestSuite &argSuite ) + { + _suite = &argSuite; + } + + TestSuite *StaticSuiteDescription::suite() const + { + return _suite; + } + + bool StaticSuiteDescription::setUp() { return true; } + bool StaticSuiteDescription::tearDown() { return true; } + + CommonDynamicSuiteDescription::CommonDynamicSuiteDescription() {} + CommonDynamicSuiteDescription::CommonDynamicSuiteDescription( const char *argFile, unsigned argLine, + const char *argSuiteName, List &argTests, + unsigned argCreateLine, unsigned argDestroyLine ) : + RealSuiteDescription( argFile, argLine, argSuiteName, argTests ) + { + doInitialize( argCreateLine, argDestroyLine ); + } + + void CommonDynamicSuiteDescription::initialize( const char *argFile, unsigned argLine, + const char *argSuiteName, List &argTests, + unsigned argCreateLine, unsigned argDestroyLine ) + { + RealSuiteDescription::initialize( argFile, argLine, argSuiteName, argTests ); + doInitialize( argCreateLine, argDestroyLine ); + } + + void CommonDynamicSuiteDescription::doInitialize( unsigned argCreateLine, unsigned argDestroyLine ) + { + _createLine = argCreateLine; + _destroyLine = argDestroyLine; + } + + List &RealWorldDescription::suites() + { + return RealSuiteDescription::_suites; + } + + unsigned RealWorldDescription::numSuites( void ) const + { + return suites().size(); + } + + unsigned RealWorldDescription::numTotalTests( void ) const + { + unsigned count = 0; + for ( const SuiteDescription *sd = firstSuite(); sd != 0; sd = sd->next() ) + count += sd->numTests(); + return count; + } + + SuiteDescription *RealWorldDescription::firstSuite() + { + return (RealSuiteDescription *)suites().head(); + } + + const SuiteDescription *RealWorldDescription::firstSuite() const + { + return (const RealSuiteDescription *)suites().head(); + } + + const SuiteDescription &RealWorldDescription::suiteDescription( unsigned i ) const + { + return *(const RealSuiteDescription *)suites().nth( i ); + } + + void RealWorldDescription::activateAllTests() + { + suites().activateAll(); + for ( SuiteDescription *sd = firstSuite(); sd != 0; sd = sd->next() ) + sd->activateAllTests(); + } + + bool RealWorldDescription::leaveOnly( const char *suiteName, const char *testName ) + { + for ( SuiteDescription *sd = firstSuite(); sd != 0; sd = sd->next() ) { + if ( stringsEqual( sd->suiteName(), suiteName ) ) { + if ( testName ) + if ( !sd->leaveOnly( testName ) ) + return false; + suites().leaveOnly( *sd ); + return true; + } + } + return false; + } + + bool RealWorldDescription::setUp() + { + for ( GlobalFixture *gf = GlobalFixture::firstGlobalFixture(); gf != 0; gf = gf->nextGlobalFixture() ) { + bool ok; + _TS_TRY { ok = gf->setUpWorld(); } + _TS_LAST_CATCH( { ok = false; } ); + + if ( !ok ) { + reportError( "Error setting up world" ); + return false; + } + } + + return true; + } + + bool RealWorldDescription::tearDown() + { + for ( GlobalFixture *gf = GlobalFixture::lastGlobalFixture(); gf != 0; gf = gf->prevGlobalFixture() ) { + bool ok; + _TS_TRY { ok = gf->tearDownWorld(); } + _TS_LAST_CATCH( { ok = false; } ); + + if ( !ok ) { + reportError( "Error tearing down world" ); + return false; + } + } + + return true; + } + + void RealWorldDescription::reportError( const char *message ) + { + doWarn( __FILE__, 5, message ); + } + + void activateAllTests() + { + RealWorldDescription().activateAllTests(); + } + + bool leaveOnly( const char *suiteName, const char *testName ) + { + return RealWorldDescription().leaveOnly( suiteName, testName ); + } +} + +#endif // __cxxtest__RealDescriptions_cpp__ + diff --git a/cxxtest/cxxtest/RealDescriptions.h b/cxxtest/cxxtest/RealDescriptions.h new file mode 100644 index 000000000..14c457de7 --- /dev/null +++ b/cxxtest/cxxtest/RealDescriptions.h @@ -0,0 +1,223 @@ +#ifndef __cxxtest__RealDescriptions_h__ +#define __cxxtest__RealDescriptions_h__ + +// +// The "real" description classes +// + +#include +#include +#include + +namespace CxxTest +{ + class RealTestDescription : public TestDescription + { + public: + RealTestDescription(); + RealTestDescription( List &argList, SuiteDescription &argSuite, unsigned argLine, const char *argTestName ); + void initialize( List &argList, SuiteDescription &argSuite, unsigned argLine, const char *argTestName ); + + const char *file() const; + unsigned line() const; + const char *testName() const; + const char *suiteName() const; + + TestDescription *next(); + const TestDescription *next() const; + + TestSuite *suite() const; + + bool setUp(); + void run(); + bool tearDown(); + + private: + RealTestDescription( const RealTestDescription & ); + RealTestDescription &operator=( const RealTestDescription & ); + + virtual void runTest() = 0; + + SuiteDescription *_suite; + unsigned _line; + const char *_testName; + }; + + class RealSuiteDescription : public SuiteDescription + { + public: + RealSuiteDescription(); + RealSuiteDescription( const char *argFile, unsigned argLine, const char *argSuiteName, List &argTests ); + + void initialize( const char *argFile, unsigned argLine, const char *argSuiteName, List &argTests ); + + const char *file() const; + unsigned line() const; + const char *suiteName() const; + + TestDescription *firstTest(); + const TestDescription *firstTest() const; + SuiteDescription *next(); + const SuiteDescription *next() const; + + unsigned numTests() const; + const TestDescription &testDescription( unsigned i ) const; + + void activateAllTests(); + bool leaveOnly( const char *testName ); + + private: + RealSuiteDescription( const RealSuiteDescription & ); + RealSuiteDescription &operator=( const RealSuiteDescription & ); + + const char *_file; + unsigned _line; + const char *_suiteName; + List *_tests; + + static List _suites; + friend class RealWorldDescription; + }; + + class StaticSuiteDescription : public RealSuiteDescription + { + public: + StaticSuiteDescription(); + StaticSuiteDescription( const char *argFile, unsigned argLine, + const char *argSuiteName, TestSuite &argSuite, + List &argTests ); + + void initialize( const char *argFile, unsigned argLine, + const char *argSuiteName, TestSuite &argSuite, + List &argTests ); + TestSuite *suite() const; + + bool setUp(); + bool tearDown(); + + private: + StaticSuiteDescription( const StaticSuiteDescription & ); + StaticSuiteDescription &operator=( const StaticSuiteDescription & ); + + void doInitialize( TestSuite &argSuite ); + + TestSuite *_suite; + }; + + class CommonDynamicSuiteDescription : public RealSuiteDescription + { + public: + CommonDynamicSuiteDescription(); + CommonDynamicSuiteDescription( const char *argFile, unsigned argLine, + const char *argSuiteName, List &argTests, + unsigned argCreateLine, unsigned argDestroyLine ); + + void initialize( const char *argFile, unsigned argLine, + const char *argSuiteName, List &argTests, + unsigned argCreateLine, unsigned argDestroyLine ); + + protected: + unsigned _createLine, _destroyLine; + + private: + void doInitialize( unsigned argCreateLine, unsigned argDestroyLine ); + }; + + template + class DynamicSuiteDescription : public CommonDynamicSuiteDescription + { + public: + DynamicSuiteDescription() {} + DynamicSuiteDescription( const char *argFile, unsigned argLine, + const char *argSuiteName, List &argTests, + S *&argSuite, unsigned argCreateLine, + unsigned argDestroyLine ) : + CommonDynamicSuiteDescription( argFile, argLine, argSuiteName, argTests, argCreateLine, argDestroyLine ) + { + _suite = &argSuite; + } + + void initialize( const char *argFile, unsigned argLine, + const char *argSuiteName, List &argTests, + S *&argSuite, unsigned argCreateLine, + unsigned argDestroyLine ) + { + CommonDynamicSuiteDescription::initialize( argFile, argLine, + argSuiteName, argTests, + argCreateLine, argDestroyLine ); + _suite = &argSuite; + } + + TestSuite *suite() const { return realSuite(); } + + bool setUp(); + bool tearDown(); + + private: + S *realSuite() const { return *_suite; } + void setSuite( S *s ) { *_suite = s; } + + void createSuite() + { + setSuite( S::createSuite() ); + } + + void destroySuite() + { + S *s = realSuite(); + setSuite( 0 ); + S::destroySuite( s ); + } + + S **_suite; + }; + + template + bool DynamicSuiteDescription::setUp() + { + _TS_TRY { + _TSM_ASSERT_THROWS_NOTHING( file(), _createLine, "Exception thrown from createSuite()", createSuite() ); + _TSM_ASSERT( file(), _createLine, "createSuite() failed", suite() != 0 ); + } + _TS_CATCH_ABORT( { return false; } ); + + return (suite() != 0); + } + + template + bool DynamicSuiteDescription::tearDown() + { + if ( !_suite ) + return true; + + _TS_TRY { + _TSM_ASSERT_THROWS_NOTHING( file(), _destroyLine, "destroySuite() failed", destroySuite() ); + } + _TS_CATCH_ABORT( { return false; } ); + + return true; + } + + class RealWorldDescription : public WorldDescription + { + public: + static List &suites(); + unsigned numSuites( void ) const; + unsigned numTotalTests( void ) const; + SuiteDescription *firstSuite(); + const SuiteDescription *firstSuite() const; + const SuiteDescription &suiteDescription( unsigned i ) const; + void activateAllTests(); + bool leaveOnly( const char *suiteName, const char *testName = 0 ); + + bool setUp(); + bool tearDown(); + static void reportError( const char *message ); + }; + + void activateAllTests(); + bool leaveOnly( const char *suiteName, const char *testName = 0 ); +} + +#endif // __cxxtest__RealDescriptions_h__ + diff --git a/cxxtest/cxxtest/Root.cpp b/cxxtest/cxxtest/Root.cpp new file mode 100644 index 000000000..c4320fde7 --- /dev/null +++ b/cxxtest/cxxtest/Root.cpp @@ -0,0 +1,18 @@ +#ifndef __cxxtest__Root_cpp__ +#define __cxxtest__Root_cpp__ + +// +// This file holds the "root" of CxxTest, i.e. +// the parts that must be in a source file file. +// + +#include +#include +#include +#include +#include +#include +#include +#include + +#endif // __cxxtest__Root_cpp__ diff --git a/cxxtest/cxxtest/SelfTest.h b/cxxtest/cxxtest/SelfTest.h new file mode 100644 index 000000000..6d6b96e7d --- /dev/null +++ b/cxxtest/cxxtest/SelfTest.h @@ -0,0 +1,7 @@ +#ifndef __cxxtest_SelfTest_h__ +#define __cxxtest_SelfTest_h__ + +#define CXXTEST_SUITE(name) +#define CXXTEST_CODE(member) + +#endif // __cxxtest_SelfTest_h__ diff --git a/cxxtest/cxxtest/StdHeaders.h b/cxxtest/cxxtest/StdHeaders.h new file mode 100644 index 000000000..7c80b76f9 --- /dev/null +++ b/cxxtest/cxxtest/StdHeaders.h @@ -0,0 +1,25 @@ +#ifndef __cxxtest_StdHeaders_h__ +#define __cxxtest_StdHeaders_h__ + +// +// This file basically #includes the STL headers. +// It exists to support warning level 4 in Visual C++ +// + +#ifdef _MSC_VER +# pragma warning( push, 1 ) +#endif // _MSC_VER + +#include +#include +#include +#include +#include +#include +#include + +#ifdef _MSC_VER +# pragma warning( pop ) +#endif // _MSC_VER + +#endif // __cxxtest_StdHeaders_h__ diff --git a/cxxtest/cxxtest/StdValueTraits.h b/cxxtest/cxxtest/StdValueTraits.h new file mode 100644 index 000000000..036796b0d --- /dev/null +++ b/cxxtest/cxxtest/StdValueTraits.h @@ -0,0 +1,229 @@ +#ifndef __cxxtest_StdValueTraits_h__ +#define __cxxtest_StdValueTraits_h__ + +// +// This file defines ValueTraits for std:: stuff. +// It is #included by if you +// define CXXTEST_HAVE_STD +// + +#include +#include + +#ifdef _CXXTEST_OLD_STD +# define CXXTEST_STD(x) x +#else // !_CXXTEST_OLD_STD +# define CXXTEST_STD(x) std::x +#endif // _CXXTEST_OLD_STD + +#ifndef CXXTEST_USER_VALUE_TRAITS + +namespace CxxTest +{ + // + // NOTE: This should have been + // template + // class ValueTraits< std::basic_string > {}; + // But MSVC doesn't support it (yet). + // + + // + // If we have std::string, we might as well use it + // + class StdTraitsBase + { + public: + StdTraitsBase &operator<<( const CXXTEST_STD(string) &s ) { _s += s; return *this; } + const char *asString() const { return _s.c_str(); } + + private: + CXXTEST_STD(string) _s; + }; + + // + // std::string + // + CXXTEST_TEMPLATE_INSTANTIATION + class ValueTraits : public StdTraitsBase + { + public: + ValueTraits( const CXXTEST_STD(string) &s ) + { + *this << "\""; + for ( unsigned i = 0; i < s.length(); ++ i ) { + char c[sizeof("\\xXX")]; + charToString( s[i], c ); + *this << c; + } + *this << "\""; + } + }; + + CXXTEST_COPY_CONST_TRAITS( CXXTEST_STD(string) ); + +#ifndef _CXXTEST_OLD_STD + // + // std::wstring + // + CXXTEST_TEMPLATE_INSTANTIATION + class ValueTraits)> : public StdTraitsBase + { + public: + ValueTraits( const CXXTEST_STD(basic_string) &s ) + { + *this << "L\""; + for ( unsigned i = 0; i < s.length(); ++ i ) { + char c[sizeof("\\x12345678")]; + charToString( (unsigned long)s[i], c ); + *this << c; + } + *this << "\""; + } + }; + + CXXTEST_COPY_CONST_TRAITS( CXXTEST_STD(basic_string) ); +#endif // _CXXTEST_OLD_STD + + // + // Convert a range defined by iterators to a string + // This is useful for almost all STL containers + // + template + void dumpRange( Stream &s, Iterator first, Iterator last ) + { + s << "{ "; + while ( first != last ) { + s << TS_AS_STRING(*first); + ++ first; + s << ((first == last) ? " }" : ", "); + } + } + +#ifdef _CXXTEST_PARTIAL_TEMPLATE_SPECIALIZATION + // + // std::pair + // + template + class ValueTraits< CXXTEST_STD(pair) > : public StdTraitsBase + { + public: + ValueTraits( const CXXTEST_STD(pair) &p ) + { + *this << "<" << TS_AS_STRING( p.first ) << ", " << TS_AS_STRING( p.second ) << ">"; + } + }; + + // + // std::vector + // + template + class ValueTraits< CXXTEST_STD(vector) > : public StdTraitsBase + { + public: + ValueTraits( const CXXTEST_STD(vector) &v ) + { + dumpRange( *this, v.begin(), v.end() ); + } + }; + + // + // std::list + // + template + class ValueTraits< CXXTEST_STD(list) > : public StdTraitsBase + { + public: + ValueTraits( const CXXTEST_STD(list) &l ) + { + dumpRange( *this, l.begin(), l.end() ); + } + }; + + // + // std::set + // + template + class ValueTraits< CXXTEST_STD(set) > : public StdTraitsBase + { + public: + ValueTraits( const CXXTEST_STD(set) &s ) + { + dumpRange( *this, s.begin(), s.end() ); + } + }; + + // + // std::map + // + template + class ValueTraits< CXXTEST_STD(map) > : public StdTraitsBase + { + public: + ValueTraits( const CXXTEST_STD(map) &m ) + { + dumpRange( *this, m.begin(), m.end() ); + } + }; + + // + // std::deque + // + template + class ValueTraits< CXXTEST_STD(deque) > : public StdTraitsBase + { + public: + ValueTraits( const CXXTEST_STD(deque) &d ) + { + dumpRange( *this, d.begin(), d.end() ); + } + }; + + // + // std::multiset + // + template + class ValueTraits< CXXTEST_STD(multiset) > : public StdTraitsBase + { + public: + ValueTraits( const CXXTEST_STD(multiset) &ms ) + { + dumpRange( *this, ms.begin(), ms.end() ); + } + }; + + // + // std::multimap + // + template + class ValueTraits< CXXTEST_STD(multimap) > : public StdTraitsBase + { + public: + ValueTraits( const CXXTEST_STD(multimap) &mm ) + { + dumpRange( *this, mm.begin(), mm.end() ); + } + }; + + // + // std::complex + // + template + class ValueTraits< CXXTEST_STD(complex) > : public StdTraitsBase + { + public: + ValueTraits( const CXXTEST_STD(complex) &c ) + { + if ( !c.imag() ) + *this << TS_AS_STRING(c.real()); + else if ( !c.real() ) + *this << "(" << TS_AS_STRING(c.imag()) << " * i)"; + else + *this << "(" << TS_AS_STRING(c.real()) << " + " << TS_AS_STRING(c.imag()) << " * i)"; + } + }; +#endif // _CXXTEST_PARTIAL_TEMPLATE_SPECIALIZATION +}; + +#endif // CXXTEST_USER_VALUE_TRAITS + +#endif // __cxxtest_StdValueTraits_h__ diff --git a/cxxtest/cxxtest/StdioFilePrinter.h b/cxxtest/cxxtest/StdioFilePrinter.h new file mode 100644 index 000000000..47984b69b --- /dev/null +++ b/cxxtest/cxxtest/StdioFilePrinter.h @@ -0,0 +1,41 @@ +#ifndef __cxxtest__StdioFilePrinter_h__ +#define __cxxtest__StdioFilePrinter_h__ + +// +// The StdioFilePrinter is a simple TestListener that +// just prints "OK" if everything goes well, otherwise +// reports the error in the format of compiler messages. +// This class uses , i.e. FILE * and fprintf(). +// + +#include +#include + +namespace CxxTest +{ + class StdioFilePrinter : public ErrorFormatter + { + public: + StdioFilePrinter( FILE *o, const char *preLine = ":", const char *postLine = "" ) : + ErrorFormatter( new Adapter(o), preLine, postLine ) {} + virtual ~StdioFilePrinter() { delete outputStream(); } + + private: + class Adapter : public OutputStream + { + Adapter( const Adapter & ); + Adapter &operator=( const Adapter & ); + + FILE *_o; + + public: + Adapter( FILE *o ) : _o(o) {} + void flush() { fflush( _o ); } + OutputStream &operator<<( unsigned i ) { fprintf( _o, "%u", i ); return *this; } + OutputStream &operator<<( const char *s ) { fputs( s, _o ); return *this; } + OutputStream &operator<<( Manipulator m ) { return OutputStream::operator<<( m ); } + }; + }; +} + +#endif // __cxxtest__StdioFilePrinter_h__ diff --git a/cxxtest/cxxtest/StdioPrinter.h b/cxxtest/cxxtest/StdioPrinter.h new file mode 100644 index 000000000..af5bc6b63 --- /dev/null +++ b/cxxtest/cxxtest/StdioPrinter.h @@ -0,0 +1,22 @@ +#ifndef __cxxtest__StdioPrinter_h__ +#define __cxxtest__StdioPrinter_h__ + +// +// The StdioPrinter is an StdioFilePrinter which defaults to stdout. +// This should have been called StdOutPrinter or something, but the name +// has been historically used. +// + +#include + +namespace CxxTest +{ + class StdioPrinter : public StdioFilePrinter + { + public: + StdioPrinter( FILE *o = stdout, const char *preLine = ":", const char *postLine = "" ) : + StdioFilePrinter( o, preLine, postLine ) {} + }; +} + +#endif // __cxxtest__StdioPrinter_h__ diff --git a/cxxtest/cxxtest/TeeListener.h b/cxxtest/cxxtest/TeeListener.h new file mode 100644 index 000000000..88afdd3ed --- /dev/null +++ b/cxxtest/cxxtest/TeeListener.h @@ -0,0 +1,182 @@ +#ifndef __cxxtest__TeeListener_h__ +#define __cxxtest__TeeListener_h__ + +// +// A TeeListener notifies two "reular" TestListeners +// + +#include +#include + +namespace CxxTest +{ + class TeeListener : public TestListener + { + public: + TeeListener() + { + setFirst( _dummy ); + setSecond( _dummy ); + } + + virtual ~TeeListener() + { + } + + void setFirst( TestListener &first ) + { + _first = &first; + } + + void setSecond( TestListener &second ) + { + _second = &second; + } + + void enterWorld( const WorldDescription &d ) + { + _first->enterWorld( d ); + _second->enterWorld( d ); + } + + void enterSuite( const SuiteDescription &d ) + { + _first->enterSuite( d ); + _second->enterSuite( d ); + } + + void enterTest( const TestDescription &d ) + { + _first->enterTest( d ); + _second->enterTest( d ); + } + + void trace( const char *file, unsigned line, const char *expression ) + { + _first->trace( file, line, expression ); + _second->trace( file, line, expression ); + } + + void warning( const char *file, unsigned line, const char *expression ) + { + _first->warning( file, line, expression ); + _second->warning( file, line, expression ); + } + + void failedTest( const char *file, unsigned line, const char *expression ) + { + _first->failedTest( file, line, expression ); + _second->failedTest( file, line, expression ); + } + + void failedAssert( const char *file, unsigned line, const char *expression ) + { + _first->failedAssert( file, line, expression ); + _second->failedAssert( file, line, expression ); + } + + void failedAssertEquals( const char *file, unsigned line, + const char *xStr, const char *yStr, + const char *x, const char *y ) + { + _first->failedAssertEquals( file, line, xStr, yStr, x, y ); + _second->failedAssertEquals( file, line, xStr, yStr, x, y ); + } + + void failedAssertSameData( const char *file, unsigned line, + const char *xStr, const char *yStr, + const char *sizeStr, const void *x, + const void *y, unsigned size ) + { + _first->failedAssertSameData( file, line, xStr, yStr, sizeStr, x, y, size ); + _second->failedAssertSameData( file, line, xStr, yStr, sizeStr, x, y, size ); + } + + void failedAssertDelta( const char *file, unsigned line, + const char *xStr, const char *yStr, const char *dStr, + const char *x, const char *y, const char *d ) + { + _first->failedAssertDelta( file, line, xStr, yStr, dStr, x, y, d ); + _second->failedAssertDelta( file, line, xStr, yStr, dStr, x, y, d ); + } + + void failedAssertDiffers( const char *file, unsigned line, + const char *xStr, const char *yStr, + const char *value ) + { + _first->failedAssertDiffers( file, line, xStr, yStr, value ); + _second->failedAssertDiffers( file, line, xStr, yStr, value ); + } + + void failedAssertLessThan( const char *file, unsigned line, + const char *xStr, const char *yStr, + const char *x, const char *y ) + { + _first->failedAssertLessThan( file, line, xStr, yStr, x, y ); + _second->failedAssertLessThan( file, line, xStr, yStr, x, y ); + } + + void failedAssertLessThanEquals( const char *file, unsigned line, + const char *xStr, const char *yStr, + const char *x, const char *y ) + { + _first->failedAssertLessThanEquals( file, line, xStr, yStr, x, y ); + _second->failedAssertLessThanEquals( file, line, xStr, yStr, x, y ); + } + + void failedAssertPredicate( const char *file, unsigned line, + const char *predicate, const char *xStr, const char *x ) + { + _first->failedAssertPredicate( file, line, predicate, xStr, x ); + _second->failedAssertPredicate( file, line, predicate, xStr, x ); + } + + void failedAssertRelation( const char *file, unsigned line, + const char *relation, const char *xStr, const char *yStr, + const char *x, const char *y ) + { + _first->failedAssertRelation( file, line, relation, xStr, yStr, x, y ); + _second->failedAssertRelation( file, line, relation, xStr, yStr, x, y ); + } + + void failedAssertThrows( const char *file, unsigned line, + const char *expression, const char *type, + bool otherThrown ) + { + _first->failedAssertThrows( file, line, expression, type, otherThrown ); + _second->failedAssertThrows( file, line, expression, type, otherThrown ); + } + + void failedAssertThrowsNot( const char *file, unsigned line, + const char *expression ) + { + _first->failedAssertThrowsNot( file, line, expression ); + _second->failedAssertThrowsNot( file, line, expression ); + } + + void leaveTest( const TestDescription &d ) + { + _first->leaveTest(d); + _second->leaveTest(d); + } + + void leaveSuite( const SuiteDescription &d ) + { + _first->leaveSuite(d); + _second->leaveSuite(d); + } + + void leaveWorld( const WorldDescription &d ) + { + _first->leaveWorld(d); + _second->leaveWorld(d); + } + + private: + TestListener *_first, *_second; + TestListener _dummy; + }; +}; + + +#endif // __cxxtest__TeeListener_h__ diff --git a/cxxtest/cxxtest/TestListener.h b/cxxtest/cxxtest/TestListener.h new file mode 100644 index 000000000..0eeb5234e --- /dev/null +++ b/cxxtest/cxxtest/TestListener.h @@ -0,0 +1,70 @@ +#ifndef __cxxtest__TestListener_h__ +#define __cxxtest__TestListener_h__ + +// +// TestListener is the base class for all "listeners", +// i.e. classes that receive notifications of the +// testing process. +// +// The names of the parameters are in comments to avoid +// "unused parameter" warnings. +// + +#include + +namespace CxxTest +{ + class TestListener + { + public: + TestListener() {} + virtual ~TestListener() {} + + virtual void enterWorld( const WorldDescription & /*desc*/ ) {} + virtual void enterSuite( const SuiteDescription & /*desc*/ ) {} + virtual void enterTest( const TestDescription & /*desc*/ ) {} + virtual void trace( const char * /*file*/, unsigned /*line*/, + const char * /*expression*/ ) {} + virtual void warning( const char * /*file*/, unsigned /*line*/, + const char * /*expression*/ ) {} + virtual void failedTest( const char * /*file*/, unsigned /*line*/, + const char * /*expression*/ ) {} + virtual void failedAssert( const char * /*file*/, unsigned /*line*/, + const char * /*expression*/ ) {} + virtual void failedAssertEquals( const char * /*file*/, unsigned /*line*/, + const char * /*xStr*/, const char * /*yStr*/, + const char * /*x*/, const char * /*y*/ ) {} + virtual void failedAssertSameData( const char * /*file*/, unsigned /*line*/, + const char * /*xStr*/, const char * /*yStr*/, + const char * /*sizeStr*/, const void * /*x*/, + const void * /*y*/, unsigned /*size*/ ) {} + virtual void failedAssertDelta( const char * /*file*/, unsigned /*line*/, + const char * /*xStr*/, const char * /*yStr*/, + const char * /*dStr*/, const char * /*x*/, + const char * /*y*/, const char * /*d*/ ) {} + virtual void failedAssertDiffers( const char * /*file*/, unsigned /*line*/, + const char * /*xStr*/, const char * /*yStr*/, + const char * /*value*/ ) {} + virtual void failedAssertLessThan( const char * /*file*/, unsigned /*line*/, + const char * /*xStr*/, const char * /*yStr*/, + const char * /*x*/, const char * /*y*/ ) {} + virtual void failedAssertLessThanEquals( const char * /*file*/, unsigned /*line*/, + const char * /*xStr*/, const char * /*yStr*/, + const char * /*x*/, const char * /*y*/ ) {} + virtual void failedAssertPredicate( const char * /*file*/, unsigned /*line*/, + const char * /*predicate*/, const char * /*xStr*/, const char * /*x*/ ) {} + virtual void failedAssertRelation( const char * /*file*/, unsigned /*line*/, + const char * /*relation*/, const char * /*xStr*/, const char * /*yStr*/, + const char * /*x*/, const char * /*y*/ ) {} + virtual void failedAssertThrows( const char * /*file*/, unsigned /*line*/, + const char * /*expression*/, const char * /*type*/, + bool /*otherThrown*/ ) {} + virtual void failedAssertThrowsNot( const char * /*file*/, unsigned /*line*/, + const char * /*expression*/ ) {} + virtual void leaveTest( const TestDescription & /*desc*/ ) {} + virtual void leaveSuite( const SuiteDescription & /*desc*/ ) {} + virtual void leaveWorld( const WorldDescription & /*desc*/ ) {} + }; +} + +#endif // __cxxtest__TestListener_h__ diff --git a/cxxtest/cxxtest/TestRunner.h b/cxxtest/cxxtest/TestRunner.h new file mode 100644 index 000000000..43f0832e2 --- /dev/null +++ b/cxxtest/cxxtest/TestRunner.h @@ -0,0 +1,125 @@ +#ifndef __cxxtest_TestRunner_h__ +#define __cxxtest_TestRunner_h__ + +// +// TestRunner is the class that runs all the tests. +// To use it, create an object that implements the TestListener +// interface and call TestRunner::runAllTests( myListener ); +// + +#include +#include +#include +#include + +namespace CxxTest +{ + class TestRunner + { + public: + static void runAllTests( TestListener &listener ) + { + tracker().setListener( &listener ); + _TS_TRY { TestRunner().runWorld(); } + _TS_LAST_CATCH( { tracker().failedTest( __FILE__, __LINE__, "Exception thrown from world" ); } ); + tracker().setListener( 0 ); + } + + static void runAllTests( TestListener *listener ) + { + if ( listener ) { + listener->warning( __FILE__, __LINE__, "Deprecated; Use runAllTests( TestListener & )" ); + runAllTests( *listener ); + } + } + + private: + void runWorld() + { + RealWorldDescription wd; + WorldGuard sg; + + tracker().enterWorld( wd ); + if ( wd.setUp() ) { + for ( SuiteDescription *sd = wd.firstSuite(); sd; sd = sd->next() ) + if ( sd->active() ) + runSuite( *sd ); + + wd.tearDown(); + } + tracker().leaveWorld( wd ); + } + + void runSuite( SuiteDescription &sd ) + { + StateGuard sg; + + tracker().enterSuite( sd ); + if ( sd.setUp() ) { + for ( TestDescription *td = sd.firstTest(); td; td = td->next() ) + if ( td->active() ) + runTest( *td ); + + sd.tearDown(); + } + tracker().leaveSuite( sd ); + } + + void runTest( TestDescription &td ) + { + StateGuard sg; + + tracker().enterTest( td ); + if ( td.setUp() ) { + td.run(); + td.tearDown(); + } + tracker().leaveTest( td ); + } + + class StateGuard + { +#ifdef _CXXTEST_HAVE_EH + bool _abortTestOnFail; +#endif // _CXXTEST_HAVE_EH + unsigned _maxDumpSize; + + public: + StateGuard() + { +#ifdef _CXXTEST_HAVE_EH + _abortTestOnFail = abortTestOnFail(); +#endif // _CXXTEST_HAVE_EH + _maxDumpSize = maxDumpSize(); + } + + ~StateGuard() + { +#ifdef _CXXTEST_HAVE_EH + setAbortTestOnFail( _abortTestOnFail ); +#endif // _CXXTEST_HAVE_EH + setMaxDumpSize( _maxDumpSize ); + } + }; + + class WorldGuard : public StateGuard + { + public: + WorldGuard() : StateGuard() + { +#ifdef _CXXTEST_HAVE_EH + setAbortTestOnFail( CXXTEST_DEFAULT_ABORT ); +#endif // _CXXTEST_HAVE_EH + setMaxDumpSize( CXXTEST_MAX_DUMP_SIZE ); + } + }; + }; + + // + // For --no-static-init + // + void initialize(); +}; + + +#endif // __cxxtest_TestRunner_h__ diff --git a/cxxtest/cxxtest/TestSuite.cpp b/cxxtest/cxxtest/TestSuite.cpp new file mode 100644 index 000000000..bc14c2cd8 --- /dev/null +++ b/cxxtest/cxxtest/TestSuite.cpp @@ -0,0 +1,138 @@ +#ifndef __cxxtest__TestSuite_cpp__ +#define __cxxtest__TestSuite_cpp__ + +#include + +namespace CxxTest +{ + // + // TestSuite members + // + TestSuite::~TestSuite() {} + void TestSuite::setUp() {} + void TestSuite::tearDown() {} + + // + // Test-aborting stuff + // + static bool currentAbortTestOnFail = false; + + bool abortTestOnFail() + { + return currentAbortTestOnFail; + } + + void setAbortTestOnFail( bool value ) + { + currentAbortTestOnFail = value; + } + + void doAbortTest() + { +# if defined(_CXXTEST_HAVE_EH) + if ( currentAbortTestOnFail ) + throw AbortTest(); +# endif // _CXXTEST_HAVE_EH + } + + // + // Max dump size + // + static unsigned currentMaxDumpSize = CXXTEST_MAX_DUMP_SIZE; + + unsigned maxDumpSize() + { + return currentMaxDumpSize; + } + + void setMaxDumpSize( unsigned value ) + { + currentMaxDumpSize = value; + } + + // + // Some non-template functions + // + void doTrace( const char *file, unsigned line, const char *message ) + { + tracker().trace( file, line, message ); + } + + void doWarn( const char *file, unsigned line, const char *message ) + { + tracker().warning( file, line, message ); + } + + void doFailTest( const char *file, unsigned line, const char *message ) + { + tracker().failedTest( file, line, message ); + TS_ABORT(); + } + + void doFailAssert( const char *file, unsigned line, + const char *expression, const char *message ) + { + if ( message ) + tracker().failedTest( file, line, message ); + tracker().failedAssert( file, line, expression ); + TS_ABORT(); + } + + bool sameData( const void *x, const void *y, unsigned size ) + { + if ( size == 0 ) + return true; + + if ( x == y ) + return true; + + if ( !x || !y ) + return false; + + const char *cx = (const char *)x; + const char *cy = (const char *)y; + while ( size -- ) + if ( *cx++ != *cy++ ) + return false; + + return true; + } + + void doAssertSameData( const char *file, unsigned line, + const char *xExpr, const void *x, + const char *yExpr, const void *y, + const char *sizeExpr, unsigned size, + const char *message ) + { + if ( !sameData( x, y, size ) ) { + if ( message ) + tracker().failedTest( file, line, message ); + tracker().failedAssertSameData( file, line, xExpr, yExpr, sizeExpr, x, y, size ); + TS_ABORT(); + } + } + + void doFailAssertThrows( const char *file, unsigned line, + const char *expr, const char *type, + bool otherThrown, + const char *message ) + { + if ( message ) + tracker().failedTest( file, line, message ); + + tracker().failedAssertThrows( file, line, expr, type, otherThrown ); + TS_ABORT(); + } + + void doFailAssertThrowsNot( const char *file, unsigned line, + const char *expression, const char *message ) + { + if ( message ) + tracker().failedTest( file, line, message ); + + tracker().failedAssertThrowsNot( file, line, expression ); + TS_ABORT(); + } +}; + +#endif // __cxxtest__TestSuite_cpp__ diff --git a/cxxtest/cxxtest/TestSuite.h b/cxxtest/cxxtest/TestSuite.h new file mode 100644 index 000000000..fc5a206a7 --- /dev/null +++ b/cxxtest/cxxtest/TestSuite.h @@ -0,0 +1,512 @@ +#ifndef __cxxtest__TestSuite_h__ +#define __cxxtest__TestSuite_h__ + +// +// class TestSuite is the base class for all test suites. +// To define a test suite, derive from this class and add +// member functions called void test*(); +// + +#include +#include +#include +#include + +#ifdef _CXXTEST_HAVE_STD +# include +#endif // _CXXTEST_HAVE_STD + +namespace CxxTest +{ + class TestSuite + { + public: + virtual ~TestSuite(); + virtual void setUp(); + virtual void tearDown(); + }; + + class AbortTest {}; + void doAbortTest(); +# define TS_ABORT() CxxTest::doAbortTest() + + bool abortTestOnFail(); + void setAbortTestOnFail( bool value = CXXTEST_DEFAULT_ABORT ); + + unsigned maxDumpSize(); + void setMaxDumpSize( unsigned value = CXXTEST_MAX_DUMP_SIZE ); + + void doTrace( const char *file, unsigned line, const char *message ); + void doWarn( const char *file, unsigned line, const char *message ); + void doFailTest( const char *file, unsigned line, const char *message ); + void doFailAssert( const char *file, unsigned line, const char *expression, const char *message ); + + template + bool equals( X x, Y y ) + { + return (x == y); + } + + template + void doAssertEquals( const char *file, unsigned line, + const char *xExpr, X x, + const char *yExpr, Y y, + const char *message ) + { + if ( !equals( x, y ) ) { + if ( message ) + tracker().failedTest( file, line, message ); + tracker().failedAssertEquals( file, line, xExpr, yExpr, TS_AS_STRING(x), TS_AS_STRING(y) ); + TS_ABORT(); + } + } + + void doAssertSameData( const char *file, unsigned line, + const char *xExpr, const void *x, + const char *yExpr, const void *y, + const char *sizeExpr, unsigned size, + const char *message ); + + template + bool differs( X x, Y y ) + { + return !(x == y); + } + + template + void doAssertDiffers( const char *file, unsigned line, + const char *xExpr, X x, + const char *yExpr, Y y, + const char *message ) + { + if ( !differs( x, y ) ) { + if ( message ) + tracker().failedTest( file, line, message ); + tracker().failedAssertDiffers( file, line, xExpr, yExpr, TS_AS_STRING(x) ); + TS_ABORT(); + } + } + + template + bool lessThan( X x, Y y ) + { + return (x < y); + } + + template + void doAssertLessThan( const char *file, unsigned line, + const char *xExpr, X x, + const char *yExpr, Y y, + const char *message ) + { + if ( !lessThan(x, y) ) { + if ( message ) + tracker().failedTest( file, line, message ); + tracker().failedAssertLessThan( file, line, xExpr, yExpr, TS_AS_STRING(x), TS_AS_STRING(y) ); + TS_ABORT(); + } + } + + template + bool lessThanEquals( X x, Y y ) + { + return (x <= y); + } + + template + void doAssertLessThanEquals( const char *file, unsigned line, + const char *xExpr, X x, + const char *yExpr, Y y, + const char *message ) + { + if ( !lessThanEquals( x, y ) ) { + if ( message ) + tracker().failedTest( file, line, message ); + tracker().failedAssertLessThanEquals( file, line, xExpr, yExpr, TS_AS_STRING(x), TS_AS_STRING(y) ); + TS_ABORT(); + } + } + + template + void doAssertPredicate( const char *file, unsigned line, + const char *pExpr, const P &p, + const char *xExpr, X x, + const char *message ) + { + if ( !p( x ) ) { + if ( message ) + tracker().failedTest( file, line, message ); + tracker().failedAssertPredicate( file, line, pExpr, xExpr, TS_AS_STRING(x) ); + TS_ABORT(); + } + } + + template + void doAssertRelation( const char *file, unsigned line, + const char *rExpr, const R &r, + const char *xExpr, X x, + const char *yExpr, Y y, + const char *message ) + { + if ( !r( x, y ) ) { + if ( message ) + tracker().failedTest( file, line, message ); + tracker().failedAssertRelation( file, line, rExpr, xExpr, yExpr, TS_AS_STRING(x), TS_AS_STRING(y) ); + TS_ABORT(); + } + } + + template + bool delta( X x, Y y, D d ) + { + return ((y >= x - d) && (y <= x + d)); + } + + template + void doAssertDelta( const char *file, unsigned line, + const char *xExpr, X x, + const char *yExpr, Y y, + const char *dExpr, D d, + const char *message ) + { + if ( !delta( x, y, d ) ) { + if ( message ) + tracker().failedTest( file, line, message ); + + tracker().failedAssertDelta( file, line, xExpr, yExpr, dExpr, + TS_AS_STRING(x), TS_AS_STRING(y), TS_AS_STRING(d) ); + TS_ABORT(); + } + } + + void doFailAssertThrows( const char *file, unsigned line, + const char *expr, const char *type, + bool otherThrown, + const char *message ); + + void doFailAssertThrowsNot( const char *file, unsigned line, + const char *expression, const char *message ); + +# ifdef _CXXTEST_HAVE_EH +# define _TS_TRY try +# define _TS_CATCH_TYPE(t, b) catch t b +# define _TS_CATCH_ABORT(b) _TS_CATCH_TYPE( (const CxxTest::AbortTest &), b ) +# define _TS_LAST_CATCH(b) _TS_CATCH_TYPE( (...), b ) +# define _TSM_LAST_CATCH(f,l,m) _TS_LAST_CATCH( { (CxxTest::tracker()).failedTest(f,l,m); } ) +# ifdef _CXXTEST_HAVE_STD +# define ___TSM_CATCH(f,l,m) \ + catch(const std::exception &e) { (CxxTest::tracker()).failedTest(f,l,e.what()); } \ + _TSM_LAST_CATCH(f,l,m) +# else // !_CXXTEST_HAVE_STD +# define ___TSM_CATCH(f,l,m) _TSM_LAST_CATCH(f,l,m) +# endif // _CXXTEST_HAVE_STD +# define __TSM_CATCH(f,l,m) \ + _TS_CATCH_ABORT( { throw; } ) \ + ___TSM_CATCH(f,l,m) +# define __TS_CATCH(f,l) __TSM_CATCH(f,l,"Unhandled exception") +# define _TS_CATCH __TS_CATCH(__FILE__,__LINE__) +# else // !_CXXTEST_HAVE_EH +# define _TS_TRY +# define ___TSM_CATCH(f,l,m) +# define __TSM_CATCH(f,l,m) +# define __TS_CATCH(f,l) +# define _TS_CATCH +# define _TS_CATCH_TYPE(t, b) +# define _TS_LAST_CATCH(b) +# define _TS_CATCH_ABORT(b) +# endif // _CXXTEST_HAVE_EH + + // TS_TRACE +# define _TS_TRACE(f,l,e) CxxTest::doTrace( (f), (l), TS_AS_STRING(e) ) +# define TS_TRACE(e) _TS_TRACE( __FILE__, __LINE__, e ) + + // TS_WARN +# define _TS_WARN(f,l,e) CxxTest::doWarn( (f), (l), TS_AS_STRING(e) ) +# define TS_WARN(e) _TS_WARN( __FILE__, __LINE__, e ) + + // TS_FAIL +# define _TS_FAIL(f,l,e) CxxTest::doFailTest( (f), (l), TS_AS_STRING(e) ) +# define TS_FAIL(e) _TS_FAIL( __FILE__, __LINE__, e ) + + // TS_ASSERT +# define ___ETS_ASSERT(f,l,e,m) { if ( !(e) ) CxxTest::doFailAssert( (f), (l), #e, (m) ); } +# define ___TS_ASSERT(f,l,e,m) { _TS_TRY { ___ETS_ASSERT(f,l,e,m); } __TS_CATCH(f,l) } + +# define _ETS_ASSERT(f,l,e) ___ETS_ASSERT(f,l,e,0) +# define _TS_ASSERT(f,l,e) ___TS_ASSERT(f,l,e,0) + +# define ETS_ASSERT(e) _ETS_ASSERT(__FILE__,__LINE__,e) +# define TS_ASSERT(e) _TS_ASSERT(__FILE__,__LINE__,e) + +# define _ETSM_ASSERT(f,l,m,e) ___ETS_ASSERT(f,l,e,TS_AS_STRING(m) ) +# define _TSM_ASSERT(f,l,m,e) ___TS_ASSERT(f,l,e,TS_AS_STRING(m) ) + +# define ETSM_ASSERT(m,e) _ETSM_ASSERT(__FILE__,__LINE__,m,e) +# define TSM_ASSERT(m,e) _TSM_ASSERT(__FILE__,__LINE__,m,e) + + // TS_ASSERT_EQUALS +# define ___ETS_ASSERT_EQUALS(f,l,x,y,m) CxxTest::doAssertEquals( (f), (l), #x, (x), #y, (y), (m) ) +# define ___TS_ASSERT_EQUALS(f,l,x,y,m) { _TS_TRY { ___ETS_ASSERT_EQUALS(f,l,x,y,m); } __TS_CATCH(f,l) } + +# define _ETS_ASSERT_EQUALS(f,l,x,y) ___ETS_ASSERT_EQUALS(f,l,x,y,0) +# define _TS_ASSERT_EQUALS(f,l,x,y) ___TS_ASSERT_EQUALS(f,l,x,y,0) + +# define ETS_ASSERT_EQUALS(x,y) _ETS_ASSERT_EQUALS(__FILE__,__LINE__,x,y) +# define TS_ASSERT_EQUALS(x,y) _TS_ASSERT_EQUALS(__FILE__,__LINE__,x,y) + +# define _ETSM_ASSERT_EQUALS(f,l,m,x,y) ___ETS_ASSERT_EQUALS(f,l,x,y,TS_AS_STRING(m)) +# define _TSM_ASSERT_EQUALS(f,l,m,x,y) ___TS_ASSERT_EQUALS(f,l,x,y,TS_AS_STRING(m)) + +# define ETSM_ASSERT_EQUALS(m,x,y) _ETSM_ASSERT_EQUALS(__FILE__,__LINE__,m,x,y) +# define TSM_ASSERT_EQUALS(m,x,y) _TSM_ASSERT_EQUALS(__FILE__,__LINE__,m,x,y) + + // TS_ASSERT_SAME_DATA +# define ___ETS_ASSERT_SAME_DATA(f,l,x,y,s,m) CxxTest::doAssertSameData( (f), (l), #x, (x), #y, (y), #s, (s), (m) ) +# define ___TS_ASSERT_SAME_DATA(f,l,x,y,s,m) { _TS_TRY { ___ETS_ASSERT_SAME_DATA(f,l,x,y,s,m); } __TS_CATCH(f,l) } + +# define _ETS_ASSERT_SAME_DATA(f,l,x,y,s) ___ETS_ASSERT_SAME_DATA(f,l,x,y,s,0) +# define _TS_ASSERT_SAME_DATA(f,l,x,y,s) ___TS_ASSERT_SAME_DATA(f,l,x,y,s,0) + +# define ETS_ASSERT_SAME_DATA(x,y,s) _ETS_ASSERT_SAME_DATA(__FILE__,__LINE__,x,y,s) +# define TS_ASSERT_SAME_DATA(x,y,s) _TS_ASSERT_SAME_DATA(__FILE__,__LINE__,x,y,s) + +# define _ETSM_ASSERT_SAME_DATA(f,l,m,x,y,s) ___ETS_ASSERT_SAME_DATA(f,l,x,y,s,TS_AS_STRING(m)) +# define _TSM_ASSERT_SAME_DATA(f,l,m,x,y,s) ___TS_ASSERT_SAME_DATA(f,l,x,y,s,TS_AS_STRING(m)) + +# define ETSM_ASSERT_SAME_DATA(m,x,y,s) _ETSM_ASSERT_SAME_DATA(__FILE__,__LINE__,m,x,y,s) +# define TSM_ASSERT_SAME_DATA(m,x,y,s) _TSM_ASSERT_SAME_DATA(__FILE__,__LINE__,m,x,y,s) + + // TS_ASSERT_DIFFERS +# define ___ETS_ASSERT_DIFFERS(f,l,x,y,m) CxxTest::doAssertDiffers( (f), (l), #x, (x), #y, (y), (m) ) +# define ___TS_ASSERT_DIFFERS(f,l,x,y,m) { _TS_TRY { ___ETS_ASSERT_DIFFERS(f,l,x,y,m); } __TS_CATCH(f,l) } + +# define _ETS_ASSERT_DIFFERS(f,l,x,y) ___ETS_ASSERT_DIFFERS(f,l,x,y,0) +# define _TS_ASSERT_DIFFERS(f,l,x,y) ___TS_ASSERT_DIFFERS(f,l,x,y,0) + +# define ETS_ASSERT_DIFFERS(x,y) _ETS_ASSERT_DIFFERS(__FILE__,__LINE__,x,y) +# define TS_ASSERT_DIFFERS(x,y) _TS_ASSERT_DIFFERS(__FILE__,__LINE__,x,y) + +# define _ETSM_ASSERT_DIFFERS(f,l,m,x,y) ___ETS_ASSERT_DIFFERS(f,l,x,y,TS_AS_STRING(m)) +# define _TSM_ASSERT_DIFFERS(f,l,m,x,y) ___TS_ASSERT_DIFFERS(f,l,x,y,TS_AS_STRING(m)) + +# define ETSM_ASSERT_DIFFERS(m,x,y) _ETSM_ASSERT_DIFFERS(__FILE__,__LINE__,m,x,y) +# define TSM_ASSERT_DIFFERS(m,x,y) _TSM_ASSERT_DIFFERS(__FILE__,__LINE__,m,x,y) + + // TS_ASSERT_LESS_THAN +# define ___ETS_ASSERT_LESS_THAN(f,l,x,y,m) CxxTest::doAssertLessThan( (f), (l), #x, (x), #y, (y), (m) ) +# define ___TS_ASSERT_LESS_THAN(f,l,x,y,m) { _TS_TRY { ___ETS_ASSERT_LESS_THAN(f,l,x,y,m); } __TS_CATCH(f,l) } + +# define _ETS_ASSERT_LESS_THAN(f,l,x,y) ___ETS_ASSERT_LESS_THAN(f,l,x,y,0) +# define _TS_ASSERT_LESS_THAN(f,l,x,y) ___TS_ASSERT_LESS_THAN(f,l,x,y,0) + +# define ETS_ASSERT_LESS_THAN(x,y) _ETS_ASSERT_LESS_THAN(__FILE__,__LINE__,x,y) +# define TS_ASSERT_LESS_THAN(x,y) _TS_ASSERT_LESS_THAN(__FILE__,__LINE__,x,y) + +# define _ETSM_ASSERT_LESS_THAN(f,l,m,x,y) ___ETS_ASSERT_LESS_THAN(f,l,x,y,TS_AS_STRING(m)) +# define _TSM_ASSERT_LESS_THAN(f,l,m,x,y) ___TS_ASSERT_LESS_THAN(f,l,x,y,TS_AS_STRING(m)) + +# define ETSM_ASSERT_LESS_THAN(m,x,y) _ETSM_ASSERT_LESS_THAN(__FILE__,__LINE__,m,x,y) +# define TSM_ASSERT_LESS_THAN(m,x,y) _TSM_ASSERT_LESS_THAN(__FILE__,__LINE__,m,x,y) + + // TS_ASSERT_LESS_THAN_EQUALS +# define ___ETS_ASSERT_LESS_THAN_EQUALS(f,l,x,y,m) \ + CxxTest::doAssertLessThanEquals( (f), (l), #x, (x), #y, (y), (m) ) +# define ___TS_ASSERT_LESS_THAN_EQUALS(f,l,x,y,m) \ + { _TS_TRY { ___ETS_ASSERT_LESS_THAN_EQUALS(f,l,x,y,m); } __TS_CATCH(f,l) } + +# define _ETS_ASSERT_LESS_THAN_EQUALS(f,l,x,y) ___ETS_ASSERT_LESS_THAN_EQUALS(f,l,x,y,0) +# define _TS_ASSERT_LESS_THAN_EQUALS(f,l,x,y) ___TS_ASSERT_LESS_THAN_EQUALS(f,l,x,y,0) + +# define ETS_ASSERT_LESS_THAN_EQUALS(x,y) _ETS_ASSERT_LESS_THAN_EQUALS(__FILE__,__LINE__,x,y) +# define TS_ASSERT_LESS_THAN_EQUALS(x,y) _TS_ASSERT_LESS_THAN_EQUALS(__FILE__,__LINE__,x,y) + +# define _ETSM_ASSERT_LESS_THAN_EQUALS(f,l,m,x,y) ___ETS_ASSERT_LESS_THAN_EQUALS(f,l,x,y,TS_AS_STRING(m)) +# define _TSM_ASSERT_LESS_THAN_EQUALS(f,l,m,x,y) ___TS_ASSERT_LESS_THAN_EQUALS(f,l,x,y,TS_AS_STRING(m)) + +# define ETSM_ASSERT_LESS_THAN_EQUALS(m,x,y) _ETSM_ASSERT_LESS_THAN_EQUALS(__FILE__,__LINE__,m,x,y) +# define TSM_ASSERT_LESS_THAN_EQUALS(m,x,y) _TSM_ASSERT_LESS_THAN_EQUALS(__FILE__,__LINE__,m,x,y) + + // TS_ASSERT_PREDICATE +# define ___ETS_ASSERT_PREDICATE(f,l,p,x,m) \ + CxxTest::doAssertPredicate( (f), (l), #p, p(), #x, (x), (m) ) +# define ___TS_ASSERT_PREDICATE(f,l,p,x,m) \ + { _TS_TRY { ___ETS_ASSERT_PREDICATE(f,l,p,x,m); } __TS_CATCH(f,l) } + +# define _ETS_ASSERT_PREDICATE(f,l,p,x) ___ETS_ASSERT_PREDICATE(f,l,p,x,0) +# define _TS_ASSERT_PREDICATE(f,l,p,x) ___TS_ASSERT_PREDICATE(f,l,p,x,0) + +# define ETS_ASSERT_PREDICATE(p,x) _ETS_ASSERT_PREDICATE(__FILE__,__LINE__,p,x) +# define TS_ASSERT_PREDICATE(p,x) _TS_ASSERT_PREDICATE(__FILE__,__LINE__,p,x) + +# define _ETSM_ASSERT_PREDICATE(f,l,m,p,x) ___ETS_ASSERT_PREDICATE(f,l,p,x,TS_AS_STRING(m)) +# define _TSM_ASSERT_PREDICATE(f,l,m,p,x) ___TS_ASSERT_PREDICATE(f,l,p,x,TS_AS_STRING(m)) + +# define ETSM_ASSERT_PREDICATE(m,p,x) _ETSM_ASSERT_PREDICATE(__FILE__,__LINE__,m,p,x) +# define TSM_ASSERT_PREDICATE(m,p,x) _TSM_ASSERT_PREDICATE(__FILE__,__LINE__,m,p,x) + + // TS_ASSERT_RELATION +# define ___ETS_ASSERT_RELATION(f,l,r,x,y,m) \ + CxxTest::doAssertRelation( (f), (l), #r, r(), #x, (x), #y, (y), (m) ) +# define ___TS_ASSERT_RELATION(f,l,r,x,y,m) \ + { _TS_TRY { ___ETS_ASSERT_RELATION(f,l,r,x,y,m); } __TS_CATCH(f,l) } + +# define _ETS_ASSERT_RELATION(f,l,r,x,y) ___ETS_ASSERT_RELATION(f,l,r,x,y,0) +# define _TS_ASSERT_RELATION(f,l,r,x,y) ___TS_ASSERT_RELATION(f,l,r,x,y,0) + +# define ETS_ASSERT_RELATION(r,x,y) _ETS_ASSERT_RELATION(__FILE__,__LINE__,r,x,y) +# define TS_ASSERT_RELATION(r,x,y) _TS_ASSERT_RELATION(__FILE__,__LINE__,r,x,y) + +# define _ETSM_ASSERT_RELATION(f,l,m,r,x,y) ___ETS_ASSERT_RELATION(f,l,r,x,y,TS_AS_STRING(m)) +# define _TSM_ASSERT_RELATION(f,l,m,r,x,y) ___TS_ASSERT_RELATION(f,l,r,x,y,TS_AS_STRING(m)) + +# define ETSM_ASSERT_RELATION(m,r,x,y) _ETSM_ASSERT_RELATION(__FILE__,__LINE__,m,r,x,y) +# define TSM_ASSERT_RELATION(m,r,x,y) _TSM_ASSERT_RELATION(__FILE__,__LINE__,m,r,x,y) + + // TS_ASSERT_DELTA +# define ___ETS_ASSERT_DELTA(f,l,x,y,d,m) CxxTest::doAssertDelta( (f), (l), #x, (x), #y, (y), #d, (d), (m) ) +# define ___TS_ASSERT_DELTA(f,l,x,y,d,m) { _TS_TRY { ___ETS_ASSERT_DELTA(f,l,x,y,d,m); } __TS_CATCH(f,l) } + +# define _ETS_ASSERT_DELTA(f,l,x,y,d) ___ETS_ASSERT_DELTA(f,l,x,y,d,0) +# define _TS_ASSERT_DELTA(f,l,x,y,d) ___TS_ASSERT_DELTA(f,l,x,y,d,0) + +# define ETS_ASSERT_DELTA(x,y,d) _ETS_ASSERT_DELTA(__FILE__,__LINE__,x,y,d) +# define TS_ASSERT_DELTA(x,y,d) _TS_ASSERT_DELTA(__FILE__,__LINE__,x,y,d) + +# define _ETSM_ASSERT_DELTA(f,l,m,x,y,d) ___ETS_ASSERT_DELTA(f,l,x,y,d,TS_AS_STRING(m)) +# define _TSM_ASSERT_DELTA(f,l,m,x,y,d) ___TS_ASSERT_DELTA(f,l,x,y,d,TS_AS_STRING(m)) + +# define ETSM_ASSERT_DELTA(m,x,y,d) _ETSM_ASSERT_DELTA(__FILE__,__LINE__,m,x,y,d) +# define TSM_ASSERT_DELTA(m,x,y,d) _TSM_ASSERT_DELTA(__FILE__,__LINE__,m,x,y,d) + + // TS_ASSERT_THROWS +# define ___TS_ASSERT_THROWS(f,l,e,t,m) { \ + bool _ts_threw_expected = false, _ts_threw_else = false; \ + _TS_TRY { e; } \ + _TS_CATCH_TYPE( (t), { _ts_threw_expected = true; } ) \ + _TS_CATCH_ABORT( { throw; } ) \ + _TS_LAST_CATCH( { _ts_threw_else = true; } ) \ + if ( !_ts_threw_expected ) { CxxTest::doFailAssertThrows( (f), (l), #e, #t, _ts_threw_else, (m) ); } } + +# define _TS_ASSERT_THROWS(f,l,e,t) ___TS_ASSERT_THROWS(f,l,e,t,0) +# define TS_ASSERT_THROWS(e,t) _TS_ASSERT_THROWS(__FILE__,__LINE__,e,t) + +# define _TSM_ASSERT_THROWS(f,l,m,e,t) ___TS_ASSERT_THROWS(f,l,e,t,TS_AS_STRING(m)) +# define TSM_ASSERT_THROWS(m,e,t) _TSM_ASSERT_THROWS(__FILE__,__LINE__,m,e,t) + + // TS_ASSERT_THROWS_ASSERT +# define ___TS_ASSERT_THROWS_ASSERT(f,l,e,t,a,m) { \ + bool _ts_threw_expected = false, _ts_threw_else = false; \ + _TS_TRY { e; } \ + _TS_CATCH_TYPE( (t), { a; _ts_threw_expected = true; } ) \ + _TS_CATCH_ABORT( { throw; } ) \ + _TS_LAST_CATCH( { _ts_threw_else = true; } ) \ + if ( !_ts_threw_expected ) { CxxTest::doFailAssertThrows( (f), (l), #e, #t, _ts_threw_else, (m) ); } } + +# define _TS_ASSERT_THROWS_ASSERT(f,l,e,t,a) ___TS_ASSERT_THROWS_ASSERT(f,l,e,t,a,0) +# define TS_ASSERT_THROWS_ASSERT(e,t,a) _TS_ASSERT_THROWS_ASSERT(__FILE__,__LINE__,e,t,a) + +# define _TSM_ASSERT_THROWS_ASSERT(f,l,m,e,t,a) ___TS_ASSERT_THROWS_ASSERT(f,l,e,t,a,TS_AS_STRING(m)) +# define TSM_ASSERT_THROWS_ASSERT(m,e,t,a) _TSM_ASSERT_THROWS_ASSERT(__FILE__,__LINE__,m,e,t,a) + + // TS_ASSERT_THROWS_EQUALS +# define TS_ASSERT_THROWS_EQUALS(e,t,x,y) TS_ASSERT_THROWS_ASSERT(e,t,TS_ASSERT_EQUALS(x,y)) +# define TSM_ASSERT_THROWS_EQUALS(m,e,t,x,y) TSM_ASSERT_THROWS_ASSERT(m,e,t,TSM_ASSERT_EQUALS(m,x,y)) + + // TS_ASSERT_THROWS_DIFFERS +# define TS_ASSERT_THROWS_DIFFERS(e,t,x,y) TS_ASSERT_THROWS_ASSERT(e,t,TS_ASSERT_DIFFERS(x,y)) +# define TSM_ASSERT_THROWS_DIFFERS(m,e,t,x,y) TSM_ASSERT_THROWS_ASSERT(m,e,t,TSM_ASSERT_DIFFERS(m,x,y)) + + // TS_ASSERT_THROWS_DELTA +# define TS_ASSERT_THROWS_DELTA(e,t,x,y,d) TS_ASSERT_THROWS_ASSERT(e,t,TS_ASSERT_DELTA(x,y,d)) +# define TSM_ASSERT_THROWS_DELTA(m,e,t,x,y,d) TSM_ASSERT_THROWS_ASSERT(m,e,t,TSM_ASSERT_DELTA(m,x,y,d)) + + // TS_ASSERT_THROWS_SAME_DATA +# define TS_ASSERT_THROWS_SAME_DATA(e,t,x,y,s) TS_ASSERT_THROWS_ASSERT(e,t,TS_ASSERT_SAME_DATA(x,y,s)) +# define TSM_ASSERT_THROWS_SAME_DATA(m,e,t,x,y,s) TSM_ASSERT_THROWS_ASSERT(m,e,t,TSM_ASSERT_SAME_DATA(m,x,y,s)) + + // TS_ASSERT_THROWS_LESS_THAN +# define TS_ASSERT_THROWS_LESS_THAN(e,t,x,y) TS_ASSERT_THROWS_ASSERT(e,t,TS_ASSERT_LESS_THAN(x,y)) +# define TSM_ASSERT_THROWS_LESS_THAN(m,e,t,x,y) TSM_ASSERT_THROWS_ASSERT(m,e,t,TSM_ASSERT_LESS_THAN(m,x,y)) + + // TS_ASSERT_THROWS_LESS_THAN_EQUALS +# define TS_ASSERT_THROWS_LESS_THAN_EQUALS(e,t,x,y) TS_ASSERT_THROWS_ASSERT(e,t,TS_ASSERT_LESS_THAN_EQUALS(x,y)) +# define TSM_ASSERT_THROWS_LESS_THAN_EQUALS(m,e,t,x,y) TSM_ASSERT_THROWS_ASSERT(m,e,t,TSM_ASSERT_LESS_THAN_EQUALS(m,x,y)) + + // TS_ASSERT_THROWS_PREDICATE +# define TS_ASSERT_THROWS_PREDICATE(e,t,p,v) TS_ASSERT_THROWS_ASSERT(e,t,TS_ASSERT_PREDICATE(p,v)) +# define TSM_ASSERT_THROWS_PREDICATE(m,e,t,p,v) TSM_ASSERT_THROWS_ASSERT(m,e,t,TSM_ASSERT_PREDICATE(m,p,v)) + + // TS_ASSERT_THROWS_RELATION +# define TS_ASSERT_THROWS_RELATION(e,t,r,x,y) TS_ASSERT_THROWS_ASSERT(e,t,TS_ASSERT_RELATION(r,x,y)) +# define TSM_ASSERT_THROWS_RELATION(m,e,t,r,x,y) TSM_ASSERT_THROWS_ASSERT(m,e,t,TSM_ASSERT_RELATION(m,r,x,y)) + + // TS_ASSERT_THROWS_ANYTHING +# define ___TS_ASSERT_THROWS_ANYTHING(f,l,e,m) { \ + bool _ts_threw = false; \ + _TS_TRY { e; } \ + _TS_LAST_CATCH( { _ts_threw = true; } ) \ + if ( !_ts_threw ) { CxxTest::doFailAssertThrows( (f), (l), #e, "...", false, (m) ); } } + +# define _TS_ASSERT_THROWS_ANYTHING(f,l,e) ___TS_ASSERT_THROWS_ANYTHING(f,l,e,0) +# define TS_ASSERT_THROWS_ANYTHING(e) _TS_ASSERT_THROWS_ANYTHING(__FILE__, __LINE__, e) + +# define _TSM_ASSERT_THROWS_ANYTHING(f,l,m,e) ___TS_ASSERT_THROWS_ANYTHING(f,l,e,TS_AS_STRING(m)) +# define TSM_ASSERT_THROWS_ANYTHING(m,e) _TSM_ASSERT_THROWS_ANYTHING(__FILE__,__LINE__,m,e) + + // TS_ASSERT_THROWS_NOTHING +# define ___TS_ASSERT_THROWS_NOTHING(f,l,e,m) { \ + _TS_TRY { e; } \ + _TS_CATCH_ABORT( { throw; } ) \ + _TS_LAST_CATCH( { CxxTest::doFailAssertThrowsNot( (f), (l), #e, (m) ); } ) } + +# define _TS_ASSERT_THROWS_NOTHING(f,l,e) ___TS_ASSERT_THROWS_NOTHING(f,l,e,0) +# define TS_ASSERT_THROWS_NOTHING(e) _TS_ASSERT_THROWS_NOTHING(__FILE__,__LINE__,e) + +# define _TSM_ASSERT_THROWS_NOTHING(f,l,m,e) ___TS_ASSERT_THROWS_NOTHING(f,l,e,TS_AS_STRING(m)) +# define TSM_ASSERT_THROWS_NOTHING(m,e) _TSM_ASSERT_THROWS_NOTHING(__FILE__,__LINE__,m,e) + + + // + // This takes care of "signed <-> unsigned" warnings + // +# define CXXTEST_COMPARISONS(CXXTEST_X, CXXTEST_Y, CXXTEST_T) \ + inline bool equals( CXXTEST_X x, CXXTEST_Y y ) { return (((CXXTEST_T)x) == ((CXXTEST_T)y)); } \ + inline bool equals( CXXTEST_Y y, CXXTEST_X x ) { return (((CXXTEST_T)y) == ((CXXTEST_T)x)); } \ + inline bool differs( CXXTEST_X x, CXXTEST_Y y ) { return (((CXXTEST_T)x) != ((CXXTEST_T)y)); } \ + inline bool differs( CXXTEST_Y y, CXXTEST_X x ) { return (((CXXTEST_T)y) != ((CXXTEST_T)x)); } \ + inline bool lessThan( CXXTEST_X x, CXXTEST_Y y ) { return (((CXXTEST_T)x) < ((CXXTEST_T)y)); } \ + inline bool lessThan( CXXTEST_Y y, CXXTEST_X x ) { return (((CXXTEST_T)y) < ((CXXTEST_T)x)); } \ + inline bool lessThanEquals( CXXTEST_X x, CXXTEST_Y y ) { return (((CXXTEST_T)x) <= ((CXXTEST_T)y)); } \ + inline bool lessThanEquals( CXXTEST_Y y, CXXTEST_X x ) { return (((CXXTEST_T)y) <= ((CXXTEST_T)x)); } + +# define CXXTEST_INTEGRAL(CXXTEST_T) \ + CXXTEST_COMPARISONS( signed CXXTEST_T, unsigned CXXTEST_T, unsigned CXXTEST_T ) + + CXXTEST_INTEGRAL( char ) + CXXTEST_INTEGRAL( short ) + CXXTEST_INTEGRAL( int ) + CXXTEST_INTEGRAL( long ) +# ifdef _CXXTEST_LONGLONG + CXXTEST_INTEGRAL( _CXXTEST_LONGLONG ) +# endif // _CXXTEST_LONGLONG + +# define CXXTEST_SMALL_BIG(CXXTEST_SMALL, CXXTEST_BIG) \ + CXXTEST_COMPARISONS( signed CXXTEST_SMALL, unsigned CXXTEST_BIG, unsigned CXXTEST_BIG ) \ + CXXTEST_COMPARISONS( signed CXXTEST_BIG, unsigned CXXTEST_SMALL, unsigned CXXTEST_BIG ) + + CXXTEST_SMALL_BIG( char, short ) + CXXTEST_SMALL_BIG( char, int ) + CXXTEST_SMALL_BIG( short, int ) + CXXTEST_SMALL_BIG( char, long ) + CXXTEST_SMALL_BIG( short, long ) + CXXTEST_SMALL_BIG( int, long ) + +# ifdef _CXXTEST_LONGLONG + CXXTEST_SMALL_BIG( char, _CXXTEST_LONGLONG ) + CXXTEST_SMALL_BIG( short, _CXXTEST_LONGLONG ) + CXXTEST_SMALL_BIG( int, _CXXTEST_LONGLONG ) + CXXTEST_SMALL_BIG( long, _CXXTEST_LONGLONG ) +# endif // _CXXTEST_LONGLONG +} + +#endif // __cxxtest__TestSuite_h__ diff --git a/cxxtest/cxxtest/TestTracker.cpp b/cxxtest/cxxtest/TestTracker.cpp new file mode 100644 index 000000000..f3ce78188 --- /dev/null +++ b/cxxtest/cxxtest/TestTracker.cpp @@ -0,0 +1,248 @@ +#ifndef __cxxtest__TestTracker_cpp__ +#define __cxxtest__TestTracker_cpp__ + +#include + +namespace CxxTest +{ + bool TestTracker::_created = false; + + TestTracker::TestTracker() + { + if ( !_created ) { + initialize(); + _created = true; + } + } + + TestTracker::~TestTracker() + { + } + + TestTracker & TestTracker::tracker() + { + static TestTracker theTracker; + return theTracker; + } + + void TestTracker::initialize() + { + _warnings = 0; + _failedTests = 0; + _testFailedAsserts = 0; + _suiteFailedTests = 0; + _failedSuites = 0; + setListener( 0 ); + _world = 0; + _suite = 0; + _test = 0; + } + + const TestDescription *TestTracker::fixTest( const TestDescription *d ) const + { + return d ? d : &dummyTest(); + } + + const SuiteDescription *TestTracker::fixSuite( const SuiteDescription *d ) const + { + return d ? d : &dummySuite(); + } + + const WorldDescription *TestTracker::fixWorld( const WorldDescription *d ) const + { + return d ? d : &dummyWorld(); + } + + const TestDescription &TestTracker::dummyTest() const + { + return dummySuite().testDescription(0); + } + + const SuiteDescription &TestTracker::dummySuite() const + { + return dummyWorld().suiteDescription(0); + } + + const WorldDescription &TestTracker::dummyWorld() const + { + return _dummyWorld; + } + + void TestTracker::setListener( TestListener *l ) + { + _l = l ? l : &_dummyListener; + } + + void TestTracker::enterWorld( const WorldDescription &wd ) + { + setWorld( &wd ); + _warnings = _failedTests = _testFailedAsserts = _suiteFailedTests = _failedSuites = 0; + _l->enterWorld( wd ); + } + + void TestTracker::enterSuite( const SuiteDescription &sd ) + { + setSuite( &sd ); + _testFailedAsserts = _suiteFailedTests = 0; + _l->enterSuite(sd); + } + + void TestTracker::enterTest( const TestDescription &td ) + { + setTest( &td ); + _testFailedAsserts = false; + _l->enterTest(td); + } + + void TestTracker::leaveTest( const TestDescription &td ) + { + _l->leaveTest( td ); + setTest( 0 ); + } + + void TestTracker::leaveSuite( const SuiteDescription &sd ) + { + _l->leaveSuite( sd ); + setSuite( 0 ); + } + + void TestTracker::leaveWorld( const WorldDescription &wd ) + { + _l->leaveWorld( wd ); + setWorld( 0 ); + } + + void TestTracker::trace( const char *file, unsigned line, const char *expression ) + { + _l->trace( file, line, expression ); + } + + void TestTracker::warning( const char *file, unsigned line, const char *expression ) + { + countWarning(); + _l->warning( file, line, expression ); + } + + void TestTracker::failedTest( const char *file, unsigned line, const char *expression ) + { + countFailure(); + _l->failedTest( file, line, expression ); + } + + void TestTracker::failedAssert( const char *file, unsigned line, const char *expression ) + { + countFailure(); + _l->failedAssert( file, line, expression ); + } + + void TestTracker::failedAssertEquals( const char *file, unsigned line, + const char *xStr, const char *yStr, + const char *x, const char *y ) + { + countFailure(); + _l->failedAssertEquals( file, line, xStr, yStr, x, y ); + } + + void TestTracker::failedAssertSameData( const char *file, unsigned line, + const char *xStr, const char *yStr, + const char *sizeStr, const void *x, + const void *y, unsigned size ) + { + countFailure(); + _l->failedAssertSameData( file, line, xStr, yStr, sizeStr, x, y, size ); + } + + void TestTracker::failedAssertDelta( const char *file, unsigned line, + const char *xStr, const char *yStr, const char *dStr, + const char *x, const char *y, const char *d ) + { + countFailure(); + _l->failedAssertDelta( file, line, xStr, yStr, dStr, x, y, d ); + } + + void TestTracker::failedAssertDiffers( const char *file, unsigned line, + const char *xStr, const char *yStr, + const char *value ) + { + countFailure(); + _l->failedAssertDiffers( file, line, xStr, yStr, value ); + } + + void TestTracker::failedAssertLessThan( const char *file, unsigned line, + const char *xStr, const char *yStr, + const char *x, const char *y ) + { + countFailure(); + _l->failedAssertLessThan( file, line, xStr, yStr, x, y ); + } + + void TestTracker::failedAssertLessThanEquals( const char *file, unsigned line, + const char *xStr, const char *yStr, + const char *x, const char *y ) + { + countFailure(); + _l->failedAssertLessThanEquals( file, line, xStr, yStr, x, y ); + } + + void TestTracker::failedAssertPredicate( const char *file, unsigned line, + const char *predicate, const char *xStr, const char *x ) + { + countFailure(); + _l->failedAssertPredicate( file, line, predicate, xStr, x ); + } + + void TestTracker::failedAssertRelation( const char *file, unsigned line, + const char *relation, const char *xStr, const char *yStr, + const char *x, const char *y ) + { + countFailure(); + _l->failedAssertRelation( file, line, relation, xStr, yStr, x, y ); + } + + void TestTracker::failedAssertThrows( const char *file, unsigned line, + const char *expression, const char *type, + bool otherThrown ) + { + countFailure(); + _l->failedAssertThrows( file, line, expression, type, otherThrown ); + } + + void TestTracker::failedAssertThrowsNot( const char *file, unsigned line, const char *expression ) + { + countFailure(); + _l->failedAssertThrowsNot( file, line, expression ); + } + + void TestTracker::setWorld( const WorldDescription *w ) + { + _world = fixWorld( w ); + setSuite( 0 ); + } + + void TestTracker::setSuite( const SuiteDescription *s ) + { + _suite = fixSuite( s ); + setTest( 0 ); + } + + void TestTracker::setTest( const TestDescription *t ) + { + _test = fixTest( t ); + } + + void TestTracker::countWarning() + { + ++ _warnings; + } + + void TestTracker::countFailure() + { + if ( ++ _testFailedAsserts == 1 ) { + ++ _failedTests; + if ( ++ _suiteFailedTests == 1 ) + ++ _failedSuites; + } + } +}; + +#endif // __cxxtest__TestTracker_cpp__ diff --git a/cxxtest/cxxtest/TestTracker.h b/cxxtest/cxxtest/TestTracker.h new file mode 100644 index 000000000..c85abff14 --- /dev/null +++ b/cxxtest/cxxtest/TestTracker.h @@ -0,0 +1,114 @@ +#ifndef __cxxtest__TestTracker_h__ +#define __cxxtest__TestTracker_h__ + +// +// The TestTracker tracks running tests +// The actual work is done in CountingListenerProxy, +// but this way avoids cyclic references TestListener<->CountingListenerProxy +// + +#include +#include + +namespace CxxTest +{ + class TestListener; + + class TestTracker : public TestListener + { + public: + virtual ~TestTracker(); + + static TestTracker &tracker(); + + const TestDescription *fixTest( const TestDescription *d ) const; + const SuiteDescription *fixSuite( const SuiteDescription *d ) const; + const WorldDescription *fixWorld( const WorldDescription *d ) const; + + const TestDescription &test() const { return *_test; } + const SuiteDescription &suite() const { return *_suite; } + const WorldDescription &world() const { return *_world; } + + bool testFailed() const { return (testFailedAsserts() > 0); } + bool suiteFailed() const { return (suiteFailedTests() > 0); } + bool worldFailed() const { return (failedSuites() > 0); } + + unsigned warnings() const { return _warnings; } + unsigned failedTests() const { return _failedTests; } + unsigned testFailedAsserts() const { return _testFailedAsserts; } + unsigned suiteFailedTests() const { return _suiteFailedTests; } + unsigned failedSuites() const { return _failedSuites; } + + void enterWorld( const WorldDescription &wd ); + void enterSuite( const SuiteDescription &sd ); + void enterTest( const TestDescription &td ); + void leaveTest( const TestDescription &td ); + void leaveSuite( const SuiteDescription &sd ); + void leaveWorld( const WorldDescription &wd ); + void trace( const char *file, unsigned line, const char *expression ); + void warning( const char *file, unsigned line, const char *expression ); + void failedTest( const char *file, unsigned line, const char *expression ); + void failedAssert( const char *file, unsigned line, const char *expression ); + void failedAssertEquals( const char *file, unsigned line, + const char *xStr, const char *yStr, + const char *x, const char *y ); + void failedAssertSameData( const char *file, unsigned line, + const char *xStr, const char *yStr, + const char *sizeStr, const void *x, + const void *y, unsigned size ); + void failedAssertDelta( const char *file, unsigned line, + const char *xStr, const char *yStr, const char *dStr, + const char *x, const char *y, const char *d ); + void failedAssertDiffers( const char *file, unsigned line, + const char *xStr, const char *yStr, + const char *value ); + void failedAssertLessThan( const char *file, unsigned line, + const char *xStr, const char *yStr, + const char *x, const char *y ); + void failedAssertLessThanEquals( const char *file, unsigned line, + const char *xStr, const char *yStr, + const char *x, const char *y ); + void failedAssertPredicate( const char *file, unsigned line, + const char *predicate, const char *xStr, const char *x ); + void failedAssertRelation( const char *file, unsigned line, + const char *relation, const char *xStr, const char *yStr, + const char *x, const char *y ); + void failedAssertThrows( const char *file, unsigned line, + const char *expression, const char *type, + bool otherThrown ); + void failedAssertThrowsNot( const char *file, unsigned line, const char *expression ); + + private: + TestTracker( const TestTracker & ); + TestTracker &operator=( const TestTracker & ); + + static bool _created; + TestListener _dummyListener; + DummyWorldDescription _dummyWorld; + unsigned _warnings, _failedTests, _testFailedAsserts, _suiteFailedTests, _failedSuites; + TestListener *_l; + const WorldDescription *_world; + const SuiteDescription *_suite; + const TestDescription *_test; + + const TestDescription &dummyTest() const; + const SuiteDescription &dummySuite() const; + const WorldDescription &dummyWorld() const; + + void setWorld( const WorldDescription *w ); + void setSuite( const SuiteDescription *s ); + void setTest( const TestDescription *t ); + void countWarning(); + void countFailure(); + + friend class TestRunner; + + TestTracker(); + void initialize(); + void setListener( TestListener *l ); + }; + + inline TestTracker &tracker() { return TestTracker::tracker(); } +}; + +#endif // __cxxtest__TestTracker_h__ diff --git a/cxxtest/cxxtest/ValueTraits.cpp b/cxxtest/cxxtest/ValueTraits.cpp new file mode 100644 index 000000000..7d29ada9d --- /dev/null +++ b/cxxtest/cxxtest/ValueTraits.cpp @@ -0,0 +1,140 @@ +#ifndef __cxxtest__ValueTraits_cpp__ +#define __cxxtest__ValueTraits_cpp__ + +#include + +namespace CxxTest +{ + // + // Non-inline functions from ValueTraits.h + // + + char digitToChar( unsigned digit ) + { + if ( digit < 10 ) + return (char)('0' + digit); + if ( digit <= 10 + 'Z' - 'A' ) + return (char)('A' + digit - 10); + return '?'; + } + + const char *byteToHex( unsigned char byte ) + { + static char asHex[3]; + asHex[0] = digitToChar( byte >> 4 ); + asHex[1] = digitToChar( byte & 0x0F ); + asHex[2] = '\0'; + return asHex; + } + + char *copyString( char *dst, const char *src ) + { + while ( (*dst = *src) != '\0' ) { + ++ dst; + ++ src; + } + return dst; + } + + bool stringsEqual( const char *s1, const char *s2 ) + { + char c; + while ( (c = *s1++) == *s2++ ) + if ( c == '\0' ) + return true; + return false; + } + + char *charToString( unsigned long c, char *s ) + { + switch( c ) { + case '\\': return copyString( s, "\\\\" ); + case '\"': return copyString( s, "\\\"" ); + case '\'': return copyString( s, "\\\'" ); + case '\0': return copyString( s, "\\0" ); + case '\a': return copyString( s, "\\a" ); + case '\b': return copyString( s, "\\b" ); + case '\n': return copyString( s, "\\n" ); + case '\r': return copyString( s, "\\r" ); + case '\t': return copyString( s, "\\t" ); + } + if ( c >= 32 && c <= 127 ) { + s[0] = (char)c; + s[1] = '\0'; + return s + 1; + } + else { + s[0] = '\\'; + s[1] = 'x'; + if ( c < 0x10 ) { + s[2] = '0'; + ++ s; + } + return numberToString( c, s + 2, 16UL ); + } + } + + char *charToString( char c, char *s ) + { + return charToString( (unsigned long)(unsigned char)c, s ); + } + + char *bytesToString( const unsigned char *bytes, unsigned numBytes, unsigned maxBytes, char *s ) + { + bool truncate = (numBytes > maxBytes); + if ( truncate ) + numBytes = maxBytes; + + s = copyString( s, "{ " ); + for ( unsigned i = 0; i < numBytes; ++ i, ++ bytes ) + s = copyString( copyString( s, byteToHex( *bytes ) ), " " ); + if ( truncate ) + s = copyString( s, "..." ); + return copyString( s, " }" ); + } + +#ifndef CXXTEST_USER_VALUE_TRAITS + unsigned ValueTraits::requiredDigitsOnLeft( double t ) + { + unsigned digits = 1; + for ( t = (t < 0.0) ? -t : t; t > 1.0; t /= BASE ) + ++ digits; + return digits; + } + + char *ValueTraits::doNegative( double &t ) + { + if ( t >= 0 ) + return _asString; + _asString[0] = '-'; + t = -t; + return _asString + 1; + } + + void ValueTraits::hugeNumber( double t ) + { + char *s = doNegative( t ); + s = doubleToString( t, s, 0, 1 ); + s = copyString( s, "." ); + s = doubleToString( t, s, 1, DIGITS_ON_RIGHT ); + s = copyString( s, "E" ); + s = numberToString( requiredDigitsOnLeft( t ) - 1, s ); + } + + void ValueTraits::normalNumber( double t ) + { + char *s = doNegative( t ); + s = doubleToString( t, s ); + s = copyString( s, "." ); + for ( unsigned i = 0; i < DIGITS_ON_RIGHT; ++ i ) + s = numberToString( (unsigned)(t *= BASE) % BASE, s ); + } + + char *ValueTraits::doubleToString( double t, char *s, unsigned skip, unsigned max ) + { + return numberToString( t, s, BASE, skip, max ); + } +#endif // !CXXTEST_USER_VALUE_TRAITS +}; + +#endif // __cxxtest__ValueTraits_cpp__ diff --git a/cxxtest/cxxtest/ValueTraits.h b/cxxtest/cxxtest/ValueTraits.h new file mode 100644 index 000000000..71145ada7 --- /dev/null +++ b/cxxtest/cxxtest/ValueTraits.h @@ -0,0 +1,377 @@ +#ifndef __cxxtest__ValueTraits_h__ +#define __cxxtest__ValueTraits_h__ + +// +// ValueTraits are used by CxxTest to convert arbitrary +// values used in TS_ASSERT_EQUALS() to a string representation. +// +// This header file contains value traits for builtin integral types. +// To declare value traits for new types you should instantiate the class +// ValueTraits. +// + +#include + +#ifdef _CXXTEST_OLD_TEMPLATE_SYNTAX +# define CXXTEST_TEMPLATE_INSTANTIATION +#else // !_CXXTEST_OLD_TEMPLATE_SYNTAX +# define CXXTEST_TEMPLATE_INSTANTIATION template<> +#endif // _CXXTEST_OLD_TEMPLATE_SYNTAX + +namespace CxxTest +{ + // + // This is how we use the value traits + // +# define TS_AS_STRING(x) CxxTest::traits(x).asString() + + // + // Char representation of a digit + // + char digitToChar( unsigned digit ); + + // + // Convert byte value to hex digits + // Returns pointer to internal buffer + // + const char *byteToHex( unsigned char byte ); + + // + // Convert byte values to string + // Returns one past the copied data + // + char *bytesToString( const unsigned char *bytes, unsigned numBytes, unsigned maxBytes, char *s ); + + // + // Copy a string. + // Returns one past the end of the destination string + // Remember -- we can't use the standard library! + // + char *copyString( char *dst, const char *src ); + + // + // Compare two strings. + // Remember -- we can't use the standard library! + // + bool stringsEqual( const char *s1, const char *s2 ); + + // + // Represent a character value as a string + // Returns one past the end of the string + // This will be the actual char if printable or '\xXXXX' otherwise + // + char *charToString( unsigned long c, char *s ); + + // + // Prevent problems with negative (signed char)s + // + char *charToString( char c, char *s ); + + // + // The default ValueTraits class dumps up to 8 bytes as hex values + // + template + class ValueTraits + { + enum { MAX_BYTES = 8 }; + char _asString[sizeof("{ ") + sizeof("XX ") * MAX_BYTES + sizeof("... }")]; + + public: + ValueTraits( const T &t ) { bytesToString( (const unsigned char *)&t, sizeof(T), MAX_BYTES, _asString ); } + const char *asString( void ) const { return _asString; } + }; + + // + // traits( T t ) + // Creates an object of type ValueTraits + // + template + inline ValueTraits traits( T t ) + { + return ValueTraits( t ); + } + + // + // You can duplicate the implementation of an existing ValueTraits + // +# define CXXTEST_COPY_TRAITS(CXXTEST_NEW_CLASS, CXXTEST_OLD_CLASS) \ + CXXTEST_TEMPLATE_INSTANTIATION \ + class ValueTraits< CXXTEST_NEW_CLASS > \ + { \ + ValueTraits< CXXTEST_OLD_CLASS > _old; \ + public: \ + ValueTraits( CXXTEST_NEW_CLASS n ) : _old( (CXXTEST_OLD_CLASS)n ) {} \ + const char *asString( void ) const { return _old.asString(); } \ + } + + // + // Certain compilers need separate declarations for T and const T + // +# ifdef _CXXTEST_NO_COPY_CONST +# define CXXTEST_COPY_CONST_TRAITS(CXXTEST_CLASS) +# else // !_CXXTEST_NO_COPY_CONST +# define CXXTEST_COPY_CONST_TRAITS(CXXTEST_CLASS) CXXTEST_COPY_TRAITS(CXXTEST_CLASS, const CXXTEST_CLASS) +# endif // _CXXTEST_NO_COPY_CONST + + // + // Avoid compiler warnings about unsigned types always >= 0 + // + template inline bool negative( N n ) { return n < 0; } + template inline N abs( N n ) { return negative(n) ? -n : n; } + +# define CXXTEST_NON_NEGATIVE(Type) \ + CXXTEST_TEMPLATE_INSTANTIATION \ + inline bool negative( Type ) { return false; } \ + CXXTEST_TEMPLATE_INSTANTIATION \ + inline Type abs( Type value ) { return value; } + + CXXTEST_NON_NEGATIVE( bool ) + CXXTEST_NON_NEGATIVE( unsigned char ) + CXXTEST_NON_NEGATIVE( unsigned short int ) + CXXTEST_NON_NEGATIVE( unsigned int ) + CXXTEST_NON_NEGATIVE( unsigned long int ) +# ifdef _CXXTEST_LONGLONG + CXXTEST_NON_NEGATIVE( unsigned _CXXTEST_LONGLONG ) +# endif // _CXXTEST_LONGLONG + + // + // Represent (integral) number as a string + // Returns one past the end of the string + // Remember -- we can't use the standard library! + // + template + char *numberToString( N n, char *s, + N base = 10, + unsigned skipDigits = 0, + unsigned maxDigits = (unsigned)-1 ) + { + if ( negative(n) ) { + *s++ = '-'; + n = abs(n); + } + + N digit = 1; + while ( digit <= (n / base) ) + digit *= base; + N digitValue; + for ( ; digit >= 1 && skipDigits; n -= digit * digitValue, digit /= base, -- skipDigits ) + digitValue = (unsigned)(n / digit); + for ( ; digit >= 1 && maxDigits; n -= digit * digitValue, digit /= base, -- maxDigits ) + *s++ = digitToChar( (unsigned)(digitValue = (unsigned)(n / digit)) ); + + *s = '\0'; + return s; + } + + // + // All the specific ValueTraits follow. + // You can #define CXXTEST_USER_VALUE_TRAITS if you don't want them + // + +#ifndef CXXTEST_USER_VALUE_TRAITS + // + // ValueTraits: const char * const & + // This is used for printing strings, as in TS_FAIL( "Message" ) + // + CXXTEST_TEMPLATE_INSTANTIATION + class ValueTraits + { + ValueTraits &operator=( const ValueTraits & ); + const char *_asString; + + public: + ValueTraits( const char * const &value ) : _asString( value ) {} + ValueTraits( const ValueTraits &other ) : _asString( other._asString ) {} + const char *asString( void ) const { return _asString; } + }; + + CXXTEST_COPY_TRAITS( const char *, const char * const & ); + CXXTEST_COPY_TRAITS( char *, const char * const & ); + + // + // ValueTraits: bool + // + CXXTEST_TEMPLATE_INSTANTIATION + class ValueTraits + { + bool _value; + + public: + ValueTraits( const bool value ) : _value( value ) {} + const char *asString( void ) const { return _value ? "true" : "false"; } + }; + + CXXTEST_COPY_CONST_TRAITS( bool ); + +# ifdef _CXXTEST_LONGLONG + // + // ValueTraits: signed long long + // + CXXTEST_TEMPLATE_INSTANTIATION + class ValueTraits + { + typedef _CXXTEST_LONGLONG T; + char _asString[2 + 3 * sizeof(T)]; + public: + ValueTraits( T t ) { numberToString( t, _asString ); } + const char *asString( void ) const { return _asString; } + }; + + CXXTEST_COPY_CONST_TRAITS( signed _CXXTEST_LONGLONG ); + + // + // ValueTraits: unsigned long long + // + CXXTEST_TEMPLATE_INSTANTIATION + class ValueTraits + { + typedef unsigned _CXXTEST_LONGLONG T; + char _asString[1 + 3 * sizeof(T)]; + public: + ValueTraits( T t ) { numberToString( t, _asString ); } + const char *asString( void ) const { return _asString; } + }; + + CXXTEST_COPY_CONST_TRAITS( unsigned _CXXTEST_LONGLONG ); +# endif // _CXXTEST_LONGLONG + + // + // ValueTraits: signed long + // + CXXTEST_TEMPLATE_INSTANTIATION + class ValueTraits + { + typedef signed long int T; + char _asString[2 + 3 * sizeof(T)]; + public: + ValueTraits( T t ) { numberToString( t, _asString ); } + const char *asString( void ) const { return _asString; } + }; + + CXXTEST_COPY_CONST_TRAITS( signed long int ); + + // + // ValueTraits: unsigned long + // + CXXTEST_TEMPLATE_INSTANTIATION + class ValueTraits + { + typedef unsigned long int T; + char _asString[1 + 3 * sizeof(T)]; + public: + ValueTraits( T t ) { numberToString( t, _asString ); } + const char *asString( void ) const { return _asString; } + }; + + CXXTEST_COPY_CONST_TRAITS( unsigned long int ); + + // + // All decimals are the same as the long version + // + + CXXTEST_COPY_TRAITS( const signed int, const signed long int ); + CXXTEST_COPY_TRAITS( const unsigned int, const unsigned long int ); + CXXTEST_COPY_TRAITS( const signed short int, const signed long int ); + CXXTEST_COPY_TRAITS( const unsigned short int, const unsigned long int ); + CXXTEST_COPY_TRAITS( const unsigned char, const unsigned long int ); + + CXXTEST_COPY_CONST_TRAITS( signed int ); + CXXTEST_COPY_CONST_TRAITS( unsigned int ); + CXXTEST_COPY_CONST_TRAITS( signed short int ); + CXXTEST_COPY_CONST_TRAITS( unsigned short int ); + CXXTEST_COPY_CONST_TRAITS( unsigned char ); + + // + // ValueTraits: char + // Returns 'x' for printable chars, '\x??' for others + // + CXXTEST_TEMPLATE_INSTANTIATION + class ValueTraits + { + char _asString[sizeof("'\\xXX'")]; + public: + ValueTraits( char c ) { copyString( charToString( c, copyString( _asString, "'" ) ), "'" ); } + const char *asString( void ) const { return _asString; } + }; + + CXXTEST_COPY_CONST_TRAITS( char ); + + // + // ValueTraits: signed char + // Same as char, some compilers need it + // + CXXTEST_COPY_TRAITS( const signed char, const char ); + CXXTEST_COPY_CONST_TRAITS( signed char ); + + // + // ValueTraits: double + // + CXXTEST_TEMPLATE_INSTANTIATION + class ValueTraits + { + public: + ValueTraits( double t ) + { + ( requiredDigitsOnLeft( t ) > MAX_DIGITS_ON_LEFT ) ? + hugeNumber( t ) : + normalNumber( t ); + } + + const char *asString( void ) const { return _asString; } + + private: + enum { MAX_DIGITS_ON_LEFT = 24, DIGITS_ON_RIGHT = 4, BASE = 10 }; + char _asString[1 + MAX_DIGITS_ON_LEFT + 1 + DIGITS_ON_RIGHT + 1]; + + static unsigned requiredDigitsOnLeft( double t ); + char *doNegative( double &t ); + void hugeNumber( double t ); + void normalNumber( double t ); + char *doubleToString( double t, char *s, unsigned skip = 0, unsigned max = (unsigned)-1 ); + }; + + CXXTEST_COPY_CONST_TRAITS( double ); + + // + // ValueTraits: float + // + CXXTEST_COPY_TRAITS( const float, const double ); + CXXTEST_COPY_CONST_TRAITS( float ); +#endif // !CXXTEST_USER_VALUE_TRAITS +}; + +#ifdef _CXXTEST_HAVE_STD +# include +#endif // _CXXTEST_HAVE_STD + +// +// CXXTEST_ENUM_TRAITS +// +#define CXXTEST_ENUM_TRAITS( TYPE, VALUES ) \ + namespace CxxTest \ + { \ + CXXTEST_TEMPLATE_INSTANTIATION \ + class ValueTraits \ + { \ + TYPE _value; \ + char _fallback[sizeof("(" #TYPE ")") + 3 * sizeof(TYPE)]; \ + public: \ + ValueTraits( TYPE value ) { \ + _value = value; \ + numberToString( _value, copyString( _fallback, "(" #TYPE ")" ) ); \ + } \ + const char *asString( void ) const \ + { \ + switch ( _value ) \ + { \ + VALUES \ + default: return _fallback; \ + } \ + } \ + }; \ + } + +#define CXXTEST_ENUM_MEMBER( MEMBER ) \ + case MEMBER: return #MEMBER; + +#endif // __cxxtest__ValueTraits_h__ diff --git a/cxxtest/cxxtest/Win32Gui.h b/cxxtest/cxxtest/Win32Gui.h new file mode 100644 index 000000000..6b3e7583a --- /dev/null +++ b/cxxtest/cxxtest/Win32Gui.h @@ -0,0 +1,531 @@ +#ifndef __cxxtest__Win32Gui_h__ +#define __cxxtest__Win32Gui_h__ + +// +// The Win32Gui displays a simple progress bar using the Win32 API. +// +// It accepts the following command line options: +// -minimized Start minimized, pop up on error +// -keep Don't close the window at the end +// -title TITLE Set the window caption +// +// If both -minimized and -keep are specified, GUI will only keep the +// window if it's in focus. +// +// N.B. If you're wondering why this class doesn't use any standard +// library or STL ( would have been nice) it's because it only +// uses "straight" Win32 API. +// + +#include + +#include +#include + +namespace CxxTest +{ + class Win32Gui : public GuiListener + { + public: + void enterGui( int &argc, char **argv ) + { + parseCommandLine( argc, argv ); + } + + void enterWorld( const WorldDescription &wd ) + { + getTotalTests( wd ); + _testsDone = 0; + startGuiThread(); + } + + void guiEnterSuite( const char *suiteName ) + { + showSuiteName( suiteName ); + reset( _suiteStart ); + } + + void guiEnterTest( const char *suiteName, const char *testName ) + { + ++ _testsDone; + setTestCaption( suiteName, testName ); + showTestName( testName ); + showTestsDone(); + progressBarMessage( PBM_STEPIT ); + reset( _testStart ); + } + + void yellowBar() + { + setColor( 255, 255, 0 ); + setIcon( IDI_WARNING ); + getTotalTests(); + } + + void redBar() + { + if ( _startMinimized ) + showMainWindow( SW_SHOWNORMAL ); + setColor( 255, 0, 0 ); + setIcon( IDI_ERROR ); + getTotalTests(); + } + + void leaveGui() + { + if ( keep() ) + { + showSummary(); + WaitForSingleObject( _gui, INFINITE ); + } + DestroyWindow( _mainWindow ); + } + + private: + const char *_title; + bool _startMinimized, _keep; + HANDLE _gui; + WNDCLASSEX _windowClass; + HWND _mainWindow, _progressBar, _statusBar; + HANDLE _canStartTests; + unsigned _numTotalTests, _testsDone; + char _strTotalTests[WorldDescription::MAX_STRLEN_TOTAL_TESTS]; + enum { + STATUS_SUITE_NAME, STATUS_SUITE_TIME, + STATUS_TEST_NAME, STATUS_TEST_TIME, + STATUS_TESTS_DONE, STATUS_WORLD_TIME, + STATUS_TOTAL_PARTS + }; + int _statusWidths[STATUS_TOTAL_PARTS]; + unsigned _statusOffsets[STATUS_TOTAL_PARTS]; + unsigned _statusTotal; + char _statusTestsDone[sizeof("1000000000 of (100%)") + WorldDescription::MAX_STRLEN_TOTAL_TESTS]; + DWORD _worldStart, _suiteStart, _testStart; + char _timeString[sizeof("00:00:00")]; + + void parseCommandLine( int argc, char **argv ) + { + _startMinimized = _keep = false; + _title = argv[0]; + + for ( int i = 1; i < argc; ++ i ) + { + if ( !lstrcmpA( argv[i], "-minimized" ) ) + _startMinimized = true; + else if ( !lstrcmpA( argv[i], "-keep" ) ) + _keep = true; + else if ( !lstrcmpA( argv[i], "-title" ) && (i + 1 < argc) ) + _title = argv[++i]; + } + } + + void getTotalTests() + { + getTotalTests( tracker().world() ); + } + + void getTotalTests( const WorldDescription &wd ) + { + _numTotalTests = wd.numTotalTests(); + wd.strTotalTests( _strTotalTests ); + } + + void startGuiThread() + { + _canStartTests = CreateEvent( NULL, TRUE, FALSE, NULL ); + DWORD threadId; + _gui = CreateThread( NULL, 0, &(Win32Gui::guiThread), (LPVOID)this, 0, &threadId ); + WaitForSingleObject( _canStartTests, INFINITE ); + } + + static DWORD WINAPI guiThread( LPVOID parameter ) + { + ((Win32Gui *)parameter)->gui(); + return 0; + } + + void gui() + { + registerWindowClass(); + createMainWindow(); + initCommonControls(); + createProgressBar(); + createStatusBar(); + centerMainWindow(); + showMainWindow(); + startTimer(); + startTests(); + + messageLoop(); + } + + void registerWindowClass() + { + _windowClass.cbSize = sizeof(_windowClass); + _windowClass.style = CS_HREDRAW | CS_VREDRAW; + _windowClass.lpfnWndProc = &(Win32Gui::windowProcedure); + _windowClass.cbClsExtra = 0; + _windowClass.cbWndExtra = sizeof(LONG); + _windowClass.hInstance = (HINSTANCE)NULL; + _windowClass.hIcon = (HICON)NULL; + _windowClass.hCursor = (HCURSOR)NULL; + _windowClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); + _windowClass.lpszMenuName = NULL; + _windowClass.lpszClassName = TEXT("CxxTest Window Class"); + _windowClass.hIconSm = (HICON)NULL; + + RegisterClassEx( &_windowClass ); + } + + void createMainWindow() + { + _mainWindow = createWindow( _windowClass.lpszClassName, WS_OVERLAPPEDWINDOW ); + } + + void initCommonControls() + { + HMODULE dll = LoadLibraryA( "comctl32.dll" ); + if ( !dll ) + return; + + typedef void (WINAPI *FUNC)( void ); + FUNC func = (FUNC)GetProcAddress( dll, "InitCommonControls" ); + if ( !func ) + return; + + func(); + } + + void createProgressBar() + { + _progressBar = createWindow( PROGRESS_CLASS, WS_CHILD | WS_VISIBLE | PBS_SMOOTH, _mainWindow ); + +#ifdef PBM_SETRANGE32 + progressBarMessage( PBM_SETRANGE32, 0, _numTotalTests ); +#else // No PBM_SETRANGE32, use PBM_SETRANGE + progressBarMessage( PBM_SETRANGE, 0, MAKELPARAM( 0, (WORD)_numTotalTests ) ); +#endif // PBM_SETRANGE32 + progressBarMessage( PBM_SETPOS, 0 ); + progressBarMessage( PBM_SETSTEP, 1 ); + greenBar(); + UpdateWindow( _progressBar ); + } + + void createStatusBar() + { + _statusBar = createWindow( STATUSCLASSNAME, WS_CHILD | WS_VISIBLE, _mainWindow ); + setRatios( 4, 1, 3, 1, 3, 1 ); + } + + void setRatios( unsigned suiteNameRatio, unsigned suiteTimeRatio, + unsigned testNameRatio, unsigned testTimeRatio, + unsigned testsDoneRatio, unsigned worldTimeRatio ) + { + _statusTotal = 0; + _statusOffsets[STATUS_SUITE_NAME] = (_statusTotal += suiteNameRatio); + _statusOffsets[STATUS_SUITE_TIME] = (_statusTotal += suiteTimeRatio); + _statusOffsets[STATUS_TEST_NAME] = (_statusTotal += testNameRatio); + _statusOffsets[STATUS_TEST_TIME] = (_statusTotal += testTimeRatio); + _statusOffsets[STATUS_TESTS_DONE] = (_statusTotal += testsDoneRatio); + _statusOffsets[STATUS_WORLD_TIME] = (_statusTotal += worldTimeRatio); + } + + HWND createWindow( LPCTSTR className, DWORD style, HWND parent = (HWND)NULL ) + { + return CreateWindow( className, NULL, style, 0, 0, 0, 0, parent, + (HMENU)NULL, (HINSTANCE)NULL, (LPVOID)this ); + } + + void progressBarMessage( UINT message, WPARAM wParam = 0, LPARAM lParam = 0 ) + { + SendMessage( _progressBar, message, wParam, lParam ); + } + + void centerMainWindow() + { + RECT screen; + getScreenArea( screen ); + + LONG screenWidth = screen.right - screen.left; + LONG screenHeight = screen.bottom - screen.top; + + LONG xCenter = (screen.right + screen.left) / 2; + LONG yCenter = (screen.bottom + screen.top) / 2; + + LONG windowWidth = (screenWidth * 4) / 5; + LONG windowHeight = screenHeight / 10; + LONG minimumHeight = 2 * (GetSystemMetrics( SM_CYCAPTION ) + GetSystemMetrics( SM_CYFRAME )); + if ( windowHeight < minimumHeight ) + windowHeight = minimumHeight; + + SetWindowPos( _mainWindow, HWND_TOP, + xCenter - (windowWidth / 2), yCenter - (windowHeight / 2), + windowWidth, windowHeight, 0 ); + } + + void getScreenArea( RECT &area ) + { + if ( !getScreenAreaWithoutTaskbar( area ) ) + getWholeScreenArea( area ); + } + + bool getScreenAreaWithoutTaskbar( RECT &area ) + { + return (SystemParametersInfo( SPI_GETWORKAREA, sizeof(RECT), &area, 0 ) != 0); + } + + void getWholeScreenArea( RECT &area ) + { + area.left = area.top = 0; + area.right = GetSystemMetrics( SM_CXSCREEN ); + area.bottom = GetSystemMetrics( SM_CYSCREEN ); + } + + void showMainWindow() + { + showMainWindow( _startMinimized ? SW_MINIMIZE : SW_SHOWNORMAL ); + UpdateWindow( _mainWindow ); + } + + void showMainWindow( int mode ) + { + ShowWindow( _mainWindow, mode ); + } + + enum { TIMER_ID = 1, TIMER_DELAY = 1000 }; + + void startTimer() + { + reset( _worldStart ); + reset( _suiteStart ); + reset( _testStart ); + SetTimer( _mainWindow, TIMER_ID, TIMER_DELAY, 0 ); + } + + void reset( DWORD &tick ) + { + tick = GetTickCount(); + } + + void startTests() + { + SetEvent( _canStartTests ); + } + + void messageLoop() + { + MSG message; + while ( BOOL haveMessage = GetMessage( &message, NULL, 0, 0 ) ) + if ( haveMessage != -1 ) + DispatchMessage( &message ); + } + + static LRESULT CALLBACK windowProcedure( HWND window, UINT message, WPARAM wParam, LPARAM lParam ) + { + if ( message == WM_CREATE ) + setUp( window, (LPCREATESTRUCT)lParam ); + + Win32Gui *that = (Win32Gui *)GetWindowLong( window, GWL_USERDATA ); + return that->handle( window, message, wParam, lParam ); + } + + static void setUp( HWND window, LPCREATESTRUCT create ) + { + SetWindowLong( window, GWL_USERDATA, (LONG)create->lpCreateParams ); + } + + LRESULT handle( HWND window, UINT message, WPARAM wParam, LPARAM lParam ) + { + switch ( message ) + { + case WM_SIZE: resizeControls(); break; + + case WM_TIMER: updateTime(); break; + + case WM_CLOSE: + case WM_DESTROY: + case WM_QUIT: + ExitProcess( 0 ); + + default: return DefWindowProc( window, message, wParam, lParam ); + } + return 0; + } + + void resizeControls() + { + RECT r; + GetClientRect( _mainWindow, &r ); + LONG width = r.right - r.left; + LONG height = r.bottom - r.top; + + GetClientRect( _statusBar, &r ); + LONG statusHeight = r.bottom - r.top; + LONG resizeGripWidth = statusHeight; + LONG progressHeight = height - statusHeight; + + SetWindowPos( _progressBar, HWND_TOP, 0, 0, width, progressHeight, 0 ); + SetWindowPos( _statusBar, HWND_TOP, 0, progressHeight, width, statusHeight, 0 ); + setStatusParts( width - resizeGripWidth ); + } + + void setStatusParts( LONG width ) + { + for ( unsigned i = 0; i < STATUS_TOTAL_PARTS; ++ i ) + _statusWidths[i] = (width * _statusOffsets[i]) / _statusTotal; + + statusBarMessage( SB_SETPARTS, STATUS_TOTAL_PARTS, _statusWidths ); + } + + void statusBarMessage( UINT message, WPARAM wParam = 0, const void *lParam = 0 ) + { + SendMessage( _statusBar, message, wParam, (LPARAM)lParam ); + } + + void greenBar() + { + setColor( 0, 255, 0 ); + setIcon( IDI_INFORMATION ); + } + +#ifdef PBM_SETBARCOLOR + void setColor( BYTE red, BYTE green, BYTE blue ) + { + progressBarMessage( PBM_SETBARCOLOR, 0, RGB( red, green, blue ) ); + } +#else // !PBM_SETBARCOLOR + void setColor( BYTE, BYTE, BYTE ) + { + } +#endif // PBM_SETBARCOLOR + + void setIcon( LPCTSTR icon ) + { + SendMessage( _mainWindow, WM_SETICON, ICON_BIG, (LPARAM)loadStandardIcon( icon ) ); + } + + HICON loadStandardIcon( LPCTSTR icon ) + { + return LoadIcon( (HINSTANCE)NULL, icon ); + } + + void setTestCaption( const char *suiteName, const char *testName ) + { + setCaption( suiteName, "::", testName, "()" ); + } + + void setCaption( const char *a = "", const char *b = "", const char *c = "", const char *d = "" ) + { + unsigned length = lstrlenA( _title ) + sizeof( " - " ) + + lstrlenA( a ) + lstrlenA( b ) + lstrlenA( c ) + lstrlenA( d ); + char *name = allocate( length ); + lstrcpyA( name, _title ); + lstrcatA( name, " - " ); + lstrcatA( name, a ); + lstrcatA( name, b ); + lstrcatA( name, c ); + lstrcatA( name, d ); + SetWindowTextA( _mainWindow, name ); + deallocate( name ); + } + + void showSuiteName( const char *suiteName ) + { + setStatusPart( STATUS_SUITE_NAME, suiteName ); + } + + void showTestName( const char *testName ) + { + setStatusPart( STATUS_TEST_NAME, testName ); + } + + void showTestsDone() + { + wsprintfA( _statusTestsDone, "%u of %s (%u%%)", + _testsDone, _strTotalTests, + (_testsDone * 100) / _numTotalTests ); + setStatusPart( STATUS_TESTS_DONE, _statusTestsDone ); + } + + void updateTime() + { + setStatusTime( STATUS_WORLD_TIME, _worldStart ); + setStatusTime( STATUS_SUITE_TIME, _suiteStart ); + setStatusTime( STATUS_TEST_TIME, _testStart ); + } + + void setStatusTime( unsigned part, DWORD start ) + { + unsigned total = (GetTickCount() - start) / 1000; + unsigned hours = total / 3600; + unsigned minutes = (total / 60) % 60; + unsigned seconds = total % 60; + + if ( hours ) + wsprintfA( _timeString, "%u:%02u:%02u", hours, minutes, seconds ); + else + wsprintfA( _timeString, "%02u:%02u", minutes, seconds ); + + setStatusPart( part, _timeString ); + } + + bool keep() + { + if ( !_keep ) + return false; + if ( !_startMinimized ) + return true; + return (_mainWindow == GetForegroundWindow()); + } + + void showSummary() + { + stopTimer(); + setSummaryStatusBar(); + setSummaryCaption(); + } + + void setStatusPart( unsigned part, const char *text ) + { + statusBarMessage( SB_SETTEXTA, part, text ); + } + + void stopTimer() + { + KillTimer( _mainWindow, TIMER_ID ); + setStatusTime( STATUS_WORLD_TIME, _worldStart ); + } + + void setSummaryStatusBar() + { + setRatios( 0, 0, 0, 0, 1, 1 ); + resizeControls(); + + const char *tests = (_numTotalTests == 1) ? "test" : "tests"; + if ( tracker().failedTests() ) + wsprintfA( _statusTestsDone, "Failed %u of %s %s", + tracker().failedTests(), _strTotalTests, tests ); + else + wsprintfA( _statusTestsDone, "%s %s passed", _strTotalTests, tests ); + + setStatusPart( STATUS_TESTS_DONE, _statusTestsDone ); + } + + void setSummaryCaption() + { + setCaption( _statusTestsDone ); + } + + char *allocate( unsigned length ) + { + return (char *)HeapAlloc( GetProcessHeap(), 0, length ); + } + + void deallocate( char *data ) + { + HeapFree( GetProcessHeap(), 0, data ); + } + }; +}; + +#endif // __cxxtest__Win32Gui_h__ diff --git a/cxxtest/cxxtest/X11Gui.h b/cxxtest/cxxtest/X11Gui.h new file mode 100644 index 000000000..f14431d94 --- /dev/null +++ b/cxxtest/cxxtest/X11Gui.h @@ -0,0 +1,327 @@ +#ifndef __cxxtest__X11Gui_h__ +#define __cxxtest__X11Gui_h__ + +// +// X11Gui displays a simple progress bar using X11 +// +// It accepts the following command-line arguments: +// -title - Sets the application title +// -fn or -font <font> - Sets the font +// -bg or -background <color> - Sets the background color (default=Grey) +// -fg or -foreground <color> - Sets the text color (default=Black) +// -green/-yellow/-red <color> - Sets the colors of the bar +// + +#include <cxxtest/Gui.h> + +#include <X11/Xlib.h> +#include <X11/Xutil.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +namespace CxxTest +{ + class X11Gui : public GuiListener + { + public: + void enterGui( int &argc, char **argv ) + { + parseCommandLine( argc, argv ); + } + + void enterWorld( const WorldDescription &wd ) + { + openDisplay(); + if ( _display ) { + createColors(); + createWindow(); + createGc(); + createFont(); + centerWindow(); + initializeEvents(); + initializeBar( wd ); + processEvents(); + } + } + + void guiEnterTest( const char *suiteName, const char *testName ) + { + if ( _display ) { + ++ _testsDone; + setWindowName( suiteName, testName ); + redraw(); + } + } + + void yellowBar() + { + if ( _display ) { + _barColor = getColor( _yellowName ); + getTotalTests(); + processEvents(); + } + } + + void redBar() + { + if ( _display ) { + _barColor = getColor( _redName ); + getTotalTests(); + processEvents(); + } + } + + void leaveGui() + { + if ( _display ) { + freeFontInfo(); + destroyGc(); + destroyWindow(); + closeDisplay(); + } + } + + private: + const char *_programName; + Display *_display; + Window _window; + unsigned _numTotalTests, _testsDone; + char _strTotalTests[WorldDescription::MAX_STRLEN_TOTAL_TESTS]; + const char *_foregroundName, *_backgroundName; + const char *_greenName, *_yellowName, *_redName; + unsigned long _foreground, _background, _barColor; + int _width, _height; + GC _gc; + const char *_fontName; + XID _fontId; + XFontStruct *_fontInfo; + int _textHeight, _textDescent; + long _eventMask; + Colormap _colormap; + + void parseCommandLine( int &argc, char **argv ) + { + _programName = argv[0]; + + _fontName = 0; + _foregroundName = "Black"; + _backgroundName = "Grey"; + _greenName = "Green"; + _yellowName = "Yellow"; + _redName = "Red"; + + for ( int i = 1; i + 1 < argc; ++ i ) { + if ( !strcmp( argv[i], "-title" ) ) + _programName = argv[++ i]; + else if ( !strcmp( argv[i], "-fn" ) || !strcmp( argv[i], "-font" ) ) + _fontName = argv[++ i]; + else if ( !strcmp( argv[i], "-fg" ) || !strcmp( argv[i], "-foreground" ) ) + _foregroundName = argv[++ i]; + else if ( !strcmp( argv[i], "-bg" ) || !strcmp( argv[i], "-background" ) ) + _backgroundName = argv[++ i]; + else if ( !strcmp( argv[i], "-green" ) ) + _greenName = argv[++ i]; + else if ( !strcmp( argv[i], "-yellow" ) ) + _yellowName = argv[++ i]; + else if ( !strcmp( argv[i], "-red" ) ) + _redName = argv[++ i]; + } + } + + void openDisplay() + { + _display = XOpenDisplay( NULL ); + } + + void createColors() + { + _colormap = DefaultColormap( _display, 0 ); + _foreground = getColor( _foregroundName ); + _background = getColor( _backgroundName ); + } + + unsigned long getColor( const char *colorName ) + { + XColor color; + XParseColor( _display, _colormap, colorName, &color ); + XAllocColor( _display, _colormap, &color ); + return color.pixel; + } + + void createWindow() + { + _window = XCreateSimpleWindow( _display, RootWindow( _display, 0 ), 0, 0, 1, 1, 0, 0, _background ); + } + + void createGc() + { + _gc = XCreateGC( _display, _window, 0, 0 ); + } + + void createFont() + { + if ( !loadFont() ) + useDefaultFont(); + getFontInfo(); + _textHeight = _fontInfo->ascent + _fontInfo->descent; + _textDescent = _fontInfo->descent; + } + + bool loadFont() + { + if ( !_fontName ) + return false; + _fontId = XLoadFont( _display, _fontName ); + return (XSetFont( _display, _gc, _fontId ) == Success); + } + + void useDefaultFont() + { + _fontId = XGContextFromGC( _gc ); + } + + void getFontInfo() + { + _fontInfo = XQueryFont( _display, _fontId ); + } + + void freeFontInfo() + { + XFreeFontInfo( NULL, _fontInfo, 1 ); + } + + void initializeEvents() + { + _eventMask = ExposureMask; + XSelectInput( _display, _window, _eventMask ); + } + + void initializeBar( const WorldDescription &wd ) + { + getTotalTests( wd ); + _testsDone = 0; + _barColor = getColor( _greenName ); + } + + void getTotalTests() + { + getTotalTests( tracker().world() ); + } + + void getTotalTests( const WorldDescription &wd ) + { + _numTotalTests = wd.numTotalTests(); + wd.strTotalTests( _strTotalTests ); + } + + void centerWindow() + { + XMapWindow( _display, _window ); + + Screen *screen = XDefaultScreenOfDisplay( _display ); + int screenWidth = WidthOfScreen( screen ); + int screenHeight = HeightOfScreen( screen ); + int xCenter = screenWidth / 2; + int yCenter = screenHeight / 2; + + _width = (screenWidth * 4) / 5; + _height = screenHeight / 14; + + XMoveResizeWindow( _display, _window, xCenter - (_width / 2), yCenter - (_height / 2), _width, _height ); + } + + void processEvents() + { + redraw(); + + XEvent event; + while( XCheckMaskEvent( _display, _eventMask, &event ) ) + redraw(); + } + + void setWindowName( const char *suiteName, const char *testName ) + { + unsigned length = strlen( _programName ) + strlen( suiteName ) + strlen( testName ) + sizeof( " - ::()" ); + char *name = (char *)malloc( length ); + sprintf( name, "%s - %s::%s()", _programName, suiteName, testName ); + XSetStandardProperties( _display, _window, name, 0, 0, 0, 0, 0 ); + free( name ); + } + + void redraw() + { + getWindowSize(); + drawSolidBar(); + drawDividers(); + drawPercentage(); + flush(); + } + + void getWindowSize() + { + XWindowAttributes attributes; + XGetWindowAttributes( _display, _window, &attributes ); + _width = attributes.width; + _height = attributes.height; + } + + void drawSolidBar() + { + unsigned barWidth = (_width * _testsDone) / _numTotalTests; + + XSetForeground( _display, _gc, _barColor ); + XFillRectangle( _display, _window, _gc, 0, 0, barWidth, _height ); + + XSetForeground( _display, _gc, _background ); + XFillRectangle( _display, _window, _gc, barWidth, 0, _width + 1 - barWidth, _height ); + } + + void drawDividers() + { + if(_width / _numTotalTests < 5) + return; + for ( unsigned i = 1; i < _testsDone; ++ i ) { + int x = (_width * i) / _numTotalTests; + XDrawLine( _display, _window, _gc, x, 0, x, _height); + } + } + + void drawPercentage() + { + XSetForeground( _display, _gc, _foreground ); + + char str[sizeof("1000000000 of ") + sizeof(_strTotalTests) + sizeof(" (100%)")]; + sprintf( str, "%u of %s (%u%%)", _testsDone, _strTotalTests, (_testsDone * 100) / _numTotalTests ); + unsigned len = strlen( str ); + + int textWidth = XTextWidth( _fontInfo, str, len ); + + XDrawString( _display, _window, _gc, + (_width - textWidth) / 2, ((_height + _textHeight) / 2) - _textDescent, + str, len ); + } + + void flush() + { + XFlush( _display ); + } + + void destroyGc() + { + XFreeGC( _display, _gc ); + } + + void destroyWindow() + { + XDestroyWindow( _display, _window ); + } + + void closeDisplay() + { + XCloseDisplay( _display ); + } + }; +}; + +#endif //__cxxtest__X11Gui_h__ diff --git a/cxxtest/cxxtest/YesNoRunner.h b/cxxtest/cxxtest/YesNoRunner.h new file mode 100644 index 000000000..e7b83b6bb --- /dev/null +++ b/cxxtest/cxxtest/YesNoRunner.h @@ -0,0 +1,29 @@ +#ifndef __cxxtest__YesNoRunner_h__ +#define __cxxtest__YesNoRunner_h__ + +// +// The YesNoRunner is a simple TestListener that +// just returns true iff all tests passed. +// + +#include <cxxtest/TestRunner.h> +#include <cxxtest/TestListener.h> + +namespace CxxTest +{ + class YesNoRunner : public TestListener + { + public: + YesNoRunner() + { + } + + int run() + { + TestRunner::runAllTests( *this ); + return tracker().failedTests(); + } + }; +} + +#endif // __cxxtest__YesNoRunner_h__ diff --git a/cxxtest/cxxtestgen.pl b/cxxtest/cxxtestgen.pl new file mode 100755 index 000000000..378b0a38e --- /dev/null +++ b/cxxtest/cxxtestgen.pl @@ -0,0 +1,551 @@ +#!/usr/bin/perl -w +use strict; +use Getopt::Long; + +sub usage() { + print STDERR "Usage: $0 [OPTIONS] <input file(s)>\n"; + print STDERR "Generate test source file for CxxTest.\n"; + print STDERR "\n"; + print STDERR " -v, --version Write CxxTest version\n"; + print STDERR " -o, --output=NAME Write output to file NAME\n"; + print STDERR " --runner=CLASS Create a main() function that runs CxxTest::CLASS\n"; + print STDERR " --gui=CLASS Like --runner, with GUI component\n"; + print STDERR " --error-printer Same as --runner=ErrorPrinter\n"; + print STDERR " --abort-on-fail Abort tests on failed asserts (like xUnit)\n"; + print STDERR " --have-std Use standard library (even if not found in tests)\n"; + print STDERR " --no-std Don't use standard library (even if found in tests)\n"; + print STDERR " --have-eh Use exception handling (even if not found in tests)\n"; + print STDERR " --no-eh Don't use exception handling (even if found in tests)\n"; + print STDERR " --longlong=[TYPE] Use TYPE as `long long' (defaut = long long)\n"; + print STDERR " --template=TEMPLATE Use TEMPLATE file to generate the test runner\n"; + print STDERR " --include=HEADER Include \"HEADER\" in test runner before other headers\n"; + print STDERR " --root Write CxxTest globals\n"; + print STDERR " --part Don't write CxxTest globals\n"; + print STDERR " --no-static-init Don't rely on static initialization\n"; + exit -1; +} + +main(); + +sub main { + parseCommandline(); + scanInputFiles(); + writeOutput(); +} + +# +# Handling the command line +# + +my ($output, $runner, $gui, $template, $abortOnFail, $haveEh, $noEh, $haveStd, $noStd); +my ($root, $part, $noStaticInit, $longlong, $factor); +my @headers = (); + +sub parseCommandline() { + @ARGV = expandWildcards(@ARGV); + GetOptions( 'version' => \&printVersion, + 'output=s' => \$output, + 'template=s' => \$template, + 'runner=s' => \$runner, + 'gui=s', => \$gui, + 'error-printer' => sub { $runner = 'ErrorPrinter'; $haveStd = 1; }, + 'abort-on-fail' => \$abortOnFail, + 'have-eh' => \$haveEh, + 'no-eh' => \$noEh, + 'have-std' => \$haveStd, + 'no-std' => \$noStd, + 'include=s' => \@headers, + 'root' => \$root, + 'part' => \$part, + 'no-static-init' => \$noStaticInit, + 'factor' => \$factor, + 'longlong:s' => \$longlong + ) or usage(); + scalar @ARGV or $root or usage(); + + if ( defined($noStaticInit) && (defined($root) || defined($part)) ) { + die "--no-static-init cannot be used with --root/--part\n"; + } + + if ( $gui && !$runner ) { + $runner = 'StdioPrinter'; + } + + if ( defined($longlong) && !$longlong ) { + $longlong = 'long long'; + } + + foreach my $header (@headers) { + if ( !($header =~ m/^["<].*[>"]$/) ) { + $header = "\"$header\""; + } + } +} + +sub printVersion() { + print "This is CxxTest version 3.10.1.\n"; + exit 0; +} + +sub expandWildcards() { + my @result = (); + while( my $fn = shift @_ ) { + push @result, glob($fn); + } + return @result; +} + +# +# Reading the input files and scanning for test cases +# + +my (@suites, $suite, $test, $inBlock); +my $numTotalTests = 0; + +sub scanInputFiles() { + foreach my $file (@ARGV) { + scanInputFile( $file ); + } + scalar @suites or $root or die("No tests defined\n"); +} + +sub scanInputFile($) { + my ($file) = @_; + open FILE, "<$file" or die("Cannot open input file \"$file\"\n"); + + my $line; + while (defined($line = <FILE>)) { + scanLineForExceptionHandling( $line ); + scanLineForStandardLibrary( $line ); + + scanLineForSuiteStart( $file, $., $line ); + + if ( $suite ) { + if ( lineBelongsToSuite( $suite, $., $line ) ) { + scanLineForTest( $., $line ); + scanLineForCreate( $., $line ); + scanLineForDestroy( $., $line ); + } + } + } + closeSuite(); + close FILE; +} + +sub lineBelongsToSuite($$$) { + my ($suite, $lineNo, $line) = @_; + if ( !$suite->{'generated'} ) { + return 1; + } + + if ( !$inBlock ) { + $inBlock = lineStartsBlock( $line ); + } + if ( $inBlock ) { + addLineToBlock( $suite->{'file'}, $lineNo, $line ); + } + return $inBlock; +} + +sub scanLineForExceptionHandling($) { + my ($line) = @_; + if ( $line =~ m/\b(try|throw|catch|TSM?_ASSERT_THROWS[A-Z_]*)\b/ ) { + addExceptionHandling(); + } +} + +sub scanLineForStandardLibrary($) { + my ($line) = @_; + if ( $line =~ m/\b(std\s*::|CXXTEST_STD|using\s+namespace\s+std\b|^\s*\#\s*include\s+<[a-z0-9]+>)/ ) { + addStandardLibrary(); + } +} + +sub scanLineForSuiteStart($$$) { + my ($fileName, $lineNo, $line) = @_; + if ( $line =~ m/\bclass\s+(\w+)\s*:\s*public\s+((::)?\s*CxxTest\s*::\s*)?TestSuite\b/ ) { + startSuite( $1, $fileName, $lineNo, 0 ); + } + if ( $line =~ m/\bCXXTEST_SUITE\s*\(\s*(\w*)\s*\)/ ) { + print "$fileName:$lineNo: Warning: Inline test suites are deprecated.\n"; + startSuite( $1, $fileName, $lineNo, 1 ); + } +} + +sub startSuite($$$$) { + my ($name, $file, $line, $generated) = @_; + closeSuite(); + $suite = { 'name' => $name, + 'file' => $file, + 'line' => $line, + 'generated' => $generated, + 'create' => 0, + 'destroy' => 0, + 'tests' => [], + 'lines' => [] }; +} + +sub lineStartsBlock($) { + my ($line) = @_; + return $line =~ m/\bCXXTEST_CODE\s*\(/; +} + +sub scanLineForTest($$) { + my ($lineNo, $line) = @_; + if ( $line =~ m/^([^\/]|\/[^\/])*\bvoid\s+([Tt]est\w+)\s*\(\s*(void)?\s*\)/ ) { + addTest( $2, $lineNo ); + } +} + +sub addTest($$$) { + my ($name, $line) = @_; + $test = { 'name' => $name, + 'line' => $line }; + push @{suiteTests()}, $test; +} + +sub addLineToBlock($$$) { + my ($fileName, $lineNo, $line) = @_; + $line = fixBlockLine( $fileName, $lineNo, $line ); + $line =~ s/^.*\{\{//; + my $end = ($line =~ s/\}\}.*//s); + push @{$suite->{'lines'}}, $line; + if ( $end ) { + $inBlock = 0; + } +} + +sub fixBlockLine($$$) { + my ($fileName, $lineNo, $line) = @_; + my $fileLine = cstr($fileName) . "," . $lineNo; + $line =~ s/\b(E?TSM?_(ASSERT[A-Z_]*|FAIL))\s*\(/_$1($fileLine,/g; + return $line; +} + +sub scanLineForCreate($$) { + my ($lineNo, $line) = @_; + if ( $line =~ m/\bstatic\s+\w+\s*\*\s*createSuite\s*\(\s*(void)?\s*\)/ ) { + addCreateSuite( $lineNo ); + } +} + +sub scanLineForDestroy($$) { + my ($lineNo, $line) = @_; + if ( $line =~ m/\bstatic\s+void\s+destroySuite\s*\(\s*\w+\s*\*\s*\w*\s*\)/ ) { + addDestroySuite( $lineNo ); + } +} + +sub closeSuite() { + if ( $suite && scalar @{suiteTests()} ) { + verifySuite(); + rememberSuite(); + } + undef $suite; +} + +sub addCreateSuite($) { + $suite->{'createSuite'} = $_[0]; +} + +sub addDestroySuite($) { + $suite->{'destroySuite'} = $_[0]; +} + +sub addExceptionHandling() { + $haveEh = 1 unless defined($noEh); +} + +sub addStandardLibrary() { + $haveStd = 1 unless defined($noStd); +} + +sub verifySuite() { + if (suiteCreateLine() || suiteDestroyLine()) { + die("Suite ", suiteName(), " must have both createSuite() and destroySuite()\n") + unless (suiteCreateLine() && suiteDestroyLine()); + } +} + +sub rememberSuite() { + push @suites, $suite; + $numTotalTests += scalar @{$suite->{'tests'}}; +} + +sub suiteName() { return $suite->{'name'}; } +sub suiteTests() { return $suite->{'tests'}; } +sub suiteCreateLine() { return $suite->{'createSuite'}; } +sub suiteDestroyLine() { return $suite->{'destroySuite'}; } +sub fileName() { return $suite->{'file'}; } +sub fileString() { return cstr(fileName()); } +sub testName() { return $test->{'name'}; } +sub testLine() { return $test->{'line'}; } + +sub suiteObject() { return "suite_".suiteName(); } + +sub cstr($) { + my $file = $_[0]; + $file =~ s/\\/\\\\/g; + return "\"".$file."\""; +} + +# +# Writing the test source file +# + +sub writeOutput() { + $template ? writeTemplateOutput() : writeSimpleOutput(); +} + +sub startOutputFile() { + if ( !standardOutput() ) { + open OUTPUT_FILE,">$output" or die("Cannot create output file \"$output\"\n"); + select OUTPUT_FILE; + } + print "/* Generated file, do not edit */\n\n"; +} + +sub standardOutput() { + return !$output; +} + +sub writeSimpleOutput() { + startOutputFile(); + writePreamble(); + writeMain(); + writeWorld(); +} + +my ($didPreamble, $didWorld); + +sub writeTemplateOutput() { + openTemplateFile(); + startOutputFile(); + my $line; + while (defined($line = <TEMPLATE_FILE>)) { + if ( $line =~ m/^\s*\#\s*include\s*<cxxtest\// ) { + writePreamble(); + print $line; + } elsif ( $line =~ m/^\s*<CxxTest\s+preamble>\s*$/ ) { + writePreamble(); + } elsif ( $line =~ m/^\s*<CxxTest\s+world>\s*$/ ) { + writeWorld(); + } else { + print $line; + } + } +} + +sub openTemplateFile() { + open TEMPLATE_FILE, "<$template" or die("Cannot open template file \"$template\"\n"); +} + +sub writePreamble() { + return if $didPreamble; + print "#ifndef CXXTEST_RUNNING\n"; + print "#define CXXTEST_RUNNING\n"; + print "#endif\n"; + print "\n"; + if ( $haveStd ) { + print "#define _CXXTEST_HAVE_STD\n"; + } + if ( $haveEh ) { + print "#define _CXXTEST_HAVE_EH\n"; + } + if ( $abortOnFail ) { + print "#define _CXXTEST_ABORT_TEST_ON_FAIL\n"; + } + if ( $longlong ) { + print "#define _CXXTEST_LONGLONG $longlong\n"; + } + if ( $factor ) { + print "#define _CXXTEST_FACTOR\n"; + } + foreach my $header (@headers) { + print "#include $header\n"; + } + print "#include <cxxtest/TestListener.h>\n"; + print "#include <cxxtest/TestTracker.h>\n"; + print "#include <cxxtest/TestRunner.h>\n"; + print "#include <cxxtest/RealDescriptions.h>\n"; + print "#include <cxxtest/$runner.h>\n" if $runner; + print "#include <cxxtest/$gui.h>\n" if $gui; + print "\n"; + $didPreamble = 1; +} + +sub writeWorld() { + return if $didWorld; + writePreamble(); + writeSuites(); + ($root or !$part) and writeRoot(); + $noStaticInit and writeInitialize(); + $didWorld = 1; +} + +sub writeSuites() { + foreach (@suites) { + $suite = $_; + writeInclude(fileName()); + if ( $suite->{'generated'} ) { generateSuite(); } + dynamicSuite() ? writeSuitePointer() : writeSuiteObject(); + writeTestList(); + writeSuiteDescription(); + writeTestDescriptions(); + } +} + +sub dynamicSuite() { + return suiteCreateLine(); +} + +my $lastIncluded; + +sub writeInclude($) { + my $file = $_[0]; + return if $lastIncluded && ($file eq $lastIncluded); + print "#include \"$file\"\n\n"; + $lastIncluded = $file; +} + +sub generateSuite() { + print "class ", suiteName(), " : public CxxTest::TestSuite {\n"; + print "public:\n"; + foreach my $line (@{$suite->{'lines'}}) { + print $line; + } + print "};\n\n"; +} + +sub writeTestDescriptionsBase() { + my $class = "TestDescriptionBase_" . suiteName(); + print "class $class : public CxxTest::TestDescription {\n"; + print "public:\n"; + print " const char *file() const { return ", fileString(), "; }\n"; + print " const char *suiteName() const { return \"", suiteName(), "\"; }\n"; + print "};\n\n"; +} + +sub writeSuitePointer() { + if ( $noStaticInit ) { + print "static ", suiteName(), " *", suiteObject(), ";\n\n"; + } else { + print "static ", suiteName(), " *", suiteObject(), " = 0;\n\n"; + } +} + +sub writeSuiteObject() { + print "static ", suiteName(), " ", suiteObject(), ";\n\n"; +} + +sub testList() { + return "Tests_" . suiteName(); +} + +sub writeTestList() { + if ( $noStaticInit ) { + printf "static CxxTest::List %s;\n", testList(); + } else { + printf "static CxxTest::List %s = { 0, 0 };\n", testList(); + } +} + +sub writeTestDescriptions() { + foreach (@{suiteTests()}) { + $test = $_; + writeTestDescription(); + } +} + +sub suiteDescription() { + return "suiteDescription_" . suiteName(); +} + +sub writeTestDescription() { + my $class = "TestDescription_" . suiteName() . "_" . testName(); + printf "static class $class : public CxxTest::RealTestDescription {\n"; + printf "public:\n"; + $noStaticInit or + printf " $class() : CxxTest::RealTestDescription( %s, %s, %s, \"%s\" ) {}\n", + testList(), suiteDescription(), testLine(), testName(); + printf " void runTest() { %s }\n", dynamicSuite() ? dynamicRun() : staticRun(); + printf "} testDescription_%s_%s;\n\n", suiteName(), testName(); +} + +sub dynamicRun() { + return sprintf( "if ( %s ) %s->%s();", suiteObject(), suiteObject(), testName() ); +} + +sub staticRun() { + return sprintf( "%s.%s();", suiteObject(), testName() ); +} + +sub writeSuiteDescription() { + dynamicSuite() ? writeDynamicDescription() : writeStaticDescription(); +} + +sub writeDynamicDescription() { + printf "CxxTest::DynamicSuiteDescription<%s> %s", suiteName(), suiteDescription(); + if ( !$noStaticInit ) { + printf "( %s, %s, \"%s\", %s, %s, %s, %s )", + fileString(), $suite->{'line'}, suiteName(), testList(), + suiteObject(), suiteCreateLine(), suiteDestroyLine(); + } + print ";\n\n"; +} + +sub writeStaticDescription() { + printf "CxxTest::StaticSuiteDescription %s", suiteDescription(); + if ( !$noStaticInit ) { + printf "( %s, %s, \"%s\", %s, %s )", fileString(), $suite->{'line'}, suiteName(), suiteObject(), testList(); + } + print ";\n\n"; +} + +sub writeRoot() { + print "#include <cxxtest/Root.cpp>\n"; +} + +sub writeInitialize() { + print "namespace CxxTest {\n"; + print " void initialize()\n"; + print " {\n"; + foreach (@suites) { + $suite = $_; + printf " %s.initialize();\n", testList(); + if ( dynamicSuite() ) { + printf " %s = 0;\n", suiteObject(); + printf " %s.initialize( %s, %s, \"%s\", %s, %s, %s, %s );\n", + suiteDescription(), fileString(), $suite->{'line'}, suiteName(), testList(), + suiteObject(), suiteCreateLine(), suiteDestroyLine(); + } else { + printf " %s.initialize( %s, %s, \"%s\", %s, %s );\n", + suiteDescription(), fileString(), $suite->{'line'}, suiteName(), suiteObject(), testList(); + } + + foreach (@{suiteTests()}) { + $test = $_; + printf " testDescription_%s_%s.initialize( %s, %s, %s, \"%s\" );\n", + suiteName(), testName(), testList(), suiteDescription(), testLine(), testName(); + } + } + print " }\n"; + print "}\n"; +} + +sub writeMain() { + if ( $gui ) { + print "int main( int argc, char *argv[] ) {\n"; + $noStaticInit && + print " CxxTest::initialize();\n"; + print " return CxxTest::GuiTuiRunner<CxxTest::$gui, CxxTest::$runner>( argc, argv ).run();\n"; + print "}\n"; + } + elsif ( $runner ) { + print "int main() {\n"; + $noStaticInit && + print " CxxTest::initialize();\n"; + print " return CxxTest::$runner().run();\n"; + print "}\n"; + } +} diff --git a/cxxtest/cxxtestgen.py b/cxxtest/cxxtestgen.py new file mode 100755 index 000000000..831d23ab4 --- /dev/null +++ b/cxxtest/cxxtestgen.py @@ -0,0 +1,593 @@ +#!/usr/bin/python +'''Usage: %s [OPTIONS] <input file(s)> +Generate test source file for CxxTest. + + -v, --version Write CxxTest version + -o, --output=NAME Write output to file NAME + --runner=CLASS Create a main() function that runs CxxTest::CLASS + --gui=CLASS Like --runner, with GUI component + --error-printer Same as --runner=ErrorPrinter + --abort-on-fail Abort tests on failed asserts (like xUnit) + --have-std Use standard library (even if not found in tests) + --no-std Don\'t use standard library (even if found in tests) + --have-eh Use exception handling (even if not found in tests) + --no-eh Don\'t use exception handling (even if found in tests) + --longlong=[TYPE] Use TYPE (default: long long) as long long + --template=TEMPLATE Use TEMPLATE file to generate the test runner + --include=HEADER Include HEADER in test runner before other headers + --root Write CxxTest globals + --part Don\'t write CxxTest globals + --no-static-init Don\'t rely on static initialization +''' + +import re +import sys +import getopt +import glob +import string + +# Global variables +suites = [] +suite = None +inBlock = 0 + +outputFileName = None +runner = None +gui = None +root = None +part = None +noStaticInit = None +templateFileName = None +headers = [] + +haveExceptionHandling = 0 +noExceptionHandling = 0 +haveStandardLibrary = 0 +noStandardLibrary = 0 +abortOnFail = 0 +factor = 0 +longlong = 0 + +def main(): + '''The main program''' + files = parseCommandline() + scanInputFiles( files ) + writeOutput() + +def usage( problem = None ): + '''Print usage info and exit''' + if problem is None: + print usageString() + sys.exit(0) + else: + sys.stderr.write( usageString() ) + abort( problem ) + +def usageString(): + '''Construct program usage string''' + return __doc__ % sys.argv[0] + +def abort( problem ): + '''Print error message and exit''' + sys.stderr.write( '\n' ) + sys.stderr.write( problem ) + sys.stderr.write( '\n\n' ) + sys.exit(2) + +def parseCommandline(): + '''Analyze command line arguments''' + try: + options, patterns = getopt.getopt( sys.argv[1:], 'o:r:', + ['version', 'output=', 'runner=', 'gui=', + 'error-printer', 'abort-on-fail', 'have-std', 'no-std', + 'have-eh', 'no-eh', 'template=', 'include=', + 'root', 'part', 'no-static-init', 'factor', 'longlong='] ) + except getopt.error, problem: + usage( problem ) + setOptions( options ) + return setFiles( patterns ) + +def setOptions( options ): + '''Set options specified on command line''' + global outputFileName, templateFileName, runner, gui, haveStandardLibrary, factor, longlong + global haveExceptionHandling, noExceptionHandling, abortOnFail, headers, root, part, noStaticInit + for o, a in options: + if o in ('-v', '--version'): + printVersion() + elif o in ('-o', '--output'): + outputFileName = a + elif o == '--template': + templateFileName = a + elif o == '--runner': + runner = a + elif o == '--gui': + gui = a + elif o == '--include': + if not re.match( r'^["<].*[>"]$', a ): + a = ('"%s"' % a) + headers.append( a ) + elif o == '--error-printer': + runner = 'ErrorPrinter' + haveStandardLibrary = 1 + elif o == '--abort-on-fail': + abortOnFail = 1 + elif o == '--have-std': + haveStandardLibrary = 1 + elif o == '--no-std': + noStandardLibrary = 1 + elif o == '--have-eh': + haveExceptionHandling = 1 + elif o == '--no-eh': + noExceptionHandling = 1 + elif o == '--root': + root = 1 + elif o == '--part': + part = 1 + elif o == '--no-static-init': + noStaticInit = 1 + elif o == '--factor': + factor = 1 + elif o == '--longlong': + if a: + longlong = a + else: + longlong = 'long long' + + if noStaticInit and (root or part): + abort( '--no-static-init cannot be used with --root/--part' ) + + if gui and not runner: + runner = 'StdioPrinter' + +def printVersion(): + '''Print CxxTest version and exit''' + sys.stdout.write( "This is CxxTest version 3.10.1.\n" ) + sys.exit(0) + +def setFiles( patterns ): + '''Set input files specified on command line''' + files = expandWildcards( patterns ) + if len(files) is 0 and not root: + usage( "No input files found" ) + return files + +def expandWildcards( patterns ): + '''Expand all wildcards in an array (glob)''' + fileNames = [] + for pathName in patterns: + patternFiles = glob.glob( pathName ) + for fileName in patternFiles: + fileNames.append( fixBackslashes( fileName ) ) + return fileNames + +def fixBackslashes( fileName ): + '''Convert backslashes to slashes in file name''' + return re.sub( r'\\', '/', fileName, 0 ) + +def scanInputFiles(files): + '''Scan all input files for test suites''' + for file in files: + scanInputFile(file) + global suites + if len(suites) is 0 and not root: + abort( 'No tests defined' ) + +def scanInputFile(fileName): + '''Scan single input file for test suites''' + file = open(fileName) + lineNo = 0 + while 1: + line = file.readline() + if not line: + break + lineNo = lineNo + 1 + + scanInputLine( fileName, lineNo, line ) + closeSuite() + file.close() + +def scanInputLine( fileName, lineNo, line ): + '''Scan single input line for interesting stuff''' + scanLineForExceptionHandling( line ) + scanLineForStandardLibrary( line ) + + scanLineForSuiteStart( fileName, lineNo, line ) + + global suite + if suite: + scanLineInsideSuite( suite, lineNo, line ) + +def scanLineInsideSuite( suite, lineNo, line ): + '''Analyze line which is part of a suite''' + global inBlock + if lineBelongsToSuite( suite, lineNo, line ): + scanLineForTest( suite, lineNo, line ) + scanLineForCreate( suite, lineNo, line ) + scanLineForDestroy( suite, lineNo, line ) + +def lineBelongsToSuite( suite, lineNo, line ): + '''Returns whether current line is part of the current suite. + This can be false when we are in a generated suite outside of CXXTEST_CODE() blocks + If the suite is generated, adds the line to the list of lines''' + if not suite['generated']: + return 1 + + global inBlock + if not inBlock: + inBlock = lineStartsBlock( line ) + if inBlock: + inBlock = addLineToBlock( suite, lineNo, line ) + return inBlock + + +std_re = re.compile( r"\b(std\s*::|CXXTEST_STD|using\s+namespace\s+std\b|^\s*\#\s*include\s+<[a-z0-9]+>)" ) +def scanLineForStandardLibrary( line ): + '''Check if current line uses standard library''' + global haveStandardLibrary, noStandardLibrary + if not haveStandardLibrary and std_re.search(line): + if not noStandardLibrary: + haveStandardLibrary = 1 + +exception_re = re.compile( r"\b(throw|try|catch|TSM?_ASSERT_THROWS[A-Z_]*)\b" ) +def scanLineForExceptionHandling( line ): + '''Check if current line uses exception handling''' + global haveExceptionHandling, noExceptionHandling + if not haveExceptionHandling and exception_re.search(line): + if not noExceptionHandling: + haveExceptionHandling = 1 + +suite_re = re.compile( r'\bclass\s+(\w+)\s*:\s*public\s+((::)?\s*CxxTest\s*::\s*)?TestSuite\b' ) +generatedSuite_re = re.compile( r'\bCXXTEST_SUITE\s*\(\s*(\w*)\s*\)' ) +def scanLineForSuiteStart( fileName, lineNo, line ): + '''Check if current line starts a new test suite''' + m = suite_re.search( line ) + if m: + startSuite( m.group(1), fileName, lineNo, 0 ) + m = generatedSuite_re.search( line ) + if m: + sys.stdout.write( "%s:%s: Warning: Inline test suites are deprecated.\n" % (fileName, lineNo) ) + startSuite( m.group(1), fileName, lineNo, 1 ) + +def startSuite( name, file, line, generated ): + '''Start scanning a new suite''' + global suite + closeSuite() + suite = { 'name' : name, + 'file' : file, + 'cfile' : cstr(file), + 'line' : line, + 'generated' : generated, + 'object' : 'suite_%s' % name, + 'dobject' : 'suiteDescription_%s' % name, + 'tlist' : 'Tests_%s' % name, + 'tests' : [], + 'lines' : [] } + +def lineStartsBlock( line ): + '''Check if current line starts a new CXXTEST_CODE() block''' + return re.search( r'\bCXXTEST_CODE\s*\(', line ) is not None + +test_re = re.compile( r'^([^/]|/[^/])*\bvoid\s+([Tt]est\w+)\s*\(\s*(void)?\s*\)' ) +def scanLineForTest( suite, lineNo, line ): + '''Check if current line starts a test''' + m = test_re.search( line ) + if m: + addTest( suite, m.group(2), lineNo ) + +def addTest( suite, name, line ): + '''Add a test function to the current suite''' + test = { 'name' : name, + 'suite' : suite, + 'class' : 'TestDescription_%s_%s' % (suite['name'], name), + 'object' : 'testDescription_%s_%s' % (suite['name'], name), + 'line' : line, + } + suite['tests'].append( test ) + +def addLineToBlock( suite, lineNo, line ): + '''Append the line to the current CXXTEST_CODE() block''' + line = fixBlockLine( suite, lineNo, line ) + line = re.sub( r'^.*\{\{', '', line ) + + e = re.search( r'\}\}', line ) + if e: + line = line[:e.start()] + suite['lines'].append( line ) + return e is None + +def fixBlockLine( suite, lineNo, line): + '''Change all [E]TS_ macros used in a line to _[E]TS_ macros with the correct file/line''' + return re.sub( r'\b(E?TSM?_(ASSERT[A-Z_]*|FAIL))\s*\(', + r'_\1(%s,%s,' % (suite['cfile'], lineNo), + line, 0 ) + +create_re = re.compile( r'\bstatic\s+\w+\s*\*\s*createSuite\s*\(\s*(void)?\s*\)' ) +def scanLineForCreate( suite, lineNo, line ): + '''Check if current line defines a createSuite() function''' + if create_re.search( line ): + addSuiteCreateDestroy( suite, 'create', lineNo ) + +destroy_re = re.compile( r'\bstatic\s+void\s+destroySuite\s*\(\s*\w+\s*\*\s*\w*\s*\)' ) +def scanLineForDestroy( suite, lineNo, line ): + '''Check if current line defines a destroySuite() function''' + if destroy_re.search( line ): + addSuiteCreateDestroy( suite, 'destroy', lineNo ) + +def cstr( str ): + '''Convert a string to its C representation''' + return '"' + string.replace( str, '\\', '\\\\' ) + '"' + + +def addSuiteCreateDestroy( suite, which, line ): + '''Add createSuite()/destroySuite() to current suite''' + if suite.has_key(which): + abort( '%s:%s: %sSuite() already declared' % ( suite['file'], str(line), which ) ) + suite[which] = line + +def closeSuite(): + '''Close current suite and add it to the list if valid''' + global suite + if suite is not None: + if len(suite['tests']) is not 0: + verifySuite(suite) + rememberSuite(suite) + suite = None + +def verifySuite(suite): + '''Verify current suite is legal''' + if suite.has_key('create') and not suite.has_key('destroy'): + abort( '%s:%s: Suite %s has createSuite() but no destroySuite()' % + (suite['file'], suite['create'], suite['name']) ) + if suite.has_key('destroy') and not suite.has_key('create'): + abort( '%s:%s: Suite %s has destroySuite() but no createSuite()' % + (suite['file'], suite['destroy'], suite['name']) ) + +def rememberSuite(suite): + '''Add current suite to list''' + global suites + suites.append( suite ) + +def writeOutput(): + '''Create output file''' + if templateFileName: + writeTemplateOutput() + else: + writeSimpleOutput() + +def writeSimpleOutput(): + '''Create output not based on template''' + output = startOutputFile() + writePreamble( output ) + writeMain( output ) + writeWorld( output ) + output.close() + +include_re = re.compile( r"\s*\#\s*include\s+<cxxtest/" ) +preamble_re = re.compile( r"^\s*<CxxTest\s+preamble>\s*$" ) +world_re = re.compile( r"^\s*<CxxTest\s+world>\s*$" ) +def writeTemplateOutput(): + '''Create output based on template file''' + template = open(templateFileName) + output = startOutputFile() + while 1: + line = template.readline() + if not line: + break; + if include_re.search( line ): + writePreamble( output ) + output.write( line ) + elif preamble_re.search( line ): + writePreamble( output ) + elif world_re.search( line ): + writeWorld( output ) + else: + output.write( line ) + template.close() + output.close() + +def startOutputFile(): + '''Create output file and write header''' + if outputFileName is not None: + output = open( outputFileName, 'w' ) + else: + output = sys.stdout + output.write( "/* Generated file, do not edit */\n\n" ) + return output + +wrotePreamble = 0 +def writePreamble( output ): + '''Write the CxxTest header (#includes and #defines)''' + global wrotePreamble, headers, longlong + if wrotePreamble: return + output.write( "#ifndef CXXTEST_RUNNING\n" ) + output.write( "#define CXXTEST_RUNNING\n" ) + output.write( "#endif\n" ) + output.write( "\n" ) + if haveStandardLibrary: + output.write( "#define _CXXTEST_HAVE_STD\n" ) + if haveExceptionHandling: + output.write( "#define _CXXTEST_HAVE_EH\n" ) + if abortOnFail: + output.write( "#define _CXXTEST_ABORT_TEST_ON_FAIL\n" ) + if longlong: + output.write( "#define _CXXTEST_LONGLONG %s\n" % longlong ) + if factor: + output.write( "#define _CXXTEST_FACTOR\n" ) + for header in headers: + output.write( "#include %s\n" % header ) + output.write( "#include <cxxtest/TestListener.h>\n" ) + output.write( "#include <cxxtest/TestTracker.h>\n" ) + output.write( "#include <cxxtest/TestRunner.h>\n" ) + output.write( "#include <cxxtest/RealDescriptions.h>\n" ) + if runner: + output.write( "#include <cxxtest/%s.h>\n" % runner ) + if gui: + output.write( "#include <cxxtest/%s.h>\n" % gui ) + output.write( "\n" ) + wrotePreamble = 1 + +def writeMain( output ): + '''Write the main() function for the test runner''' + if gui: + output.write( 'int main( int argc, char *argv[] ) {\n' ) + if noStaticInit: + output.write( ' CxxTest::initialize();\n' ) + output.write( ' return CxxTest::GuiTuiRunner<CxxTest::%s, CxxTest::%s>( argc, argv ).run();\n' % (gui, runner) ) + output.write( '}\n' ) + elif runner: + output.write( 'int main() {\n' ) + if noStaticInit: + output.write( ' CxxTest::initialize();\n' ) + output.write( ' return CxxTest::%s().run();\n' % runner ) + output.write( '}\n' ) + +wroteWorld = 0 +def writeWorld( output ): + '''Write the world definitions''' + global wroteWorld, part + if wroteWorld: return + writePreamble( output ) + writeSuites( output ) + if root or not part: + writeRoot( output ) + if noStaticInit: + writeInitialize( output ) + wroteWorld = 1 + +def writeSuites(output): + '''Write all TestDescriptions and SuiteDescriptions''' + for suite in suites: + writeInclude( output, suite['file'] ) + if isGenerated(suite): + generateSuite( output, suite ) + if isDynamic(suite): + writeSuitePointer( output, suite ) + else: + writeSuiteObject( output, suite ) + writeTestList( output, suite ) + writeSuiteDescription( output, suite ) + writeTestDescriptions( output, suite ) + +def isGenerated(suite): + '''Checks whether a suite class should be created''' + return suite['generated'] + +def isDynamic(suite): + '''Checks whether a suite is dynamic''' + return suite.has_key('create') + +lastIncluded = '' +def writeInclude(output, file): + '''Add #include "file" statement''' + global lastIncluded + if file == lastIncluded: return + output.writelines( [ '#include "', file, '"\n\n' ] ) + lastIncluded = file + +def generateSuite( output, suite ): + '''Write a suite declared with CXXTEST_SUITE()''' + output.write( 'class %s : public CxxTest::TestSuite {\n' % suite['name'] ) + output.write( 'public:\n' ) + for line in suite['lines']: + output.write(line) + output.write( '};\n\n' ) + +def writeSuitePointer( output, suite ): + '''Create static suite pointer object for dynamic suites''' + if noStaticInit: + output.write( 'static %s *%s;\n\n' % (suite['name'], suite['object']) ) + else: + output.write( 'static %s *%s = 0;\n\n' % (suite['name'], suite['object']) ) + +def writeSuiteObject( output, suite ): + '''Create static suite object for non-dynamic suites''' + output.writelines( [ "static ", suite['name'], " ", suite['object'], ";\n\n" ] ) + +def writeTestList( output, suite ): + '''Write the head of the test linked list for a suite''' + if noStaticInit: + output.write( 'static CxxTest::List %s;\n' % suite['tlist'] ) + else: + output.write( 'static CxxTest::List %s = { 0, 0 };\n' % suite['tlist'] ) + +def writeTestDescriptions( output, suite ): + '''Write all test descriptions for a suite''' + for test in suite['tests']: + writeTestDescription( output, suite, test ) + +def writeTestDescription( output, suite, test ): + '''Write test description object''' + output.write( 'static class %s : public CxxTest::RealTestDescription {\n' % test['class'] ) + output.write( 'public:\n' ) + if not noStaticInit: + output.write( ' %s() : CxxTest::RealTestDescription( %s, %s, %s, "%s" ) {}\n' % + (test['class'], suite['tlist'], suite['dobject'], test['line'], test['name']) ) + output.write( ' void runTest() { %s }\n' % runBody( suite, test ) ) + output.write( '} %s;\n\n' % test['object'] ) + +def runBody( suite, test ): + '''Body of TestDescription::run()''' + if isDynamic(suite): return dynamicRun( suite, test ) + else: return staticRun( suite, test ) + +def dynamicRun( suite, test ): + '''Body of TestDescription::run() for test in a dynamic suite''' + return 'if ( ' + suite['object'] + ' ) ' + suite['object'] + '->' + test['name'] + '();' + +def staticRun( suite, test ): + '''Body of TestDescription::run() for test in a non-dynamic suite''' + return suite['object'] + '.' + test['name'] + '();' + +def writeSuiteDescription( output, suite ): + '''Write SuiteDescription object''' + if isDynamic( suite ): + writeDynamicDescription( output, suite ) + else: + writeStaticDescription( output, suite ) + +def writeDynamicDescription( output, suite ): + '''Write SuiteDescription for a dynamic suite''' + output.write( 'CxxTest::DynamicSuiteDescription<%s> %s' % (suite['name'], suite['dobject']) ) + if not noStaticInit: + output.write( '( %s, %s, "%s", %s, %s, %s, %s )' % + (suite['cfile'], suite['line'], suite['name'], suite['tlist'], + suite['object'], suite['create'], suite['destroy']) ) + output.write( ';\n\n' ) + +def writeStaticDescription( output, suite ): + '''Write SuiteDescription for a static suite''' + output.write( 'CxxTest::StaticSuiteDescription %s' % suite['dobject'] ) + if not noStaticInit: + output.write( '( %s, %s, "%s", %s, %s )' % + (suite['cfile'], suite['line'], suite['name'], suite['object'], suite['tlist']) ) + output.write( ';\n\n' ) + +def writeRoot(output): + '''Write static members of CxxTest classes''' + output.write( '#include <cxxtest/Root.cpp>\n' ) + +def writeInitialize(output): + '''Write CxxTest::initialize(), which replaces static initialization''' + output.write( 'namespace CxxTest {\n' ) + output.write( ' void initialize()\n' ) + output.write( ' {\n' ) + for suite in suites: + output.write( ' %s.initialize();\n' % suite['tlist'] ) + if isDynamic(suite): + output.write( ' %s = 0;\n' % suite['object'] ) + output.write( ' %s.initialize( %s, %s, "%s", %s, %s, %s, %s );\n' % + (suite['dobject'], suite['cfile'], suite['line'], suite['name'], + suite['tlist'], suite['object'], suite['create'], suite['destroy']) ) + else: + output.write( ' %s.initialize( %s, %s, "%s", %s, %s );\n' % + (suite['dobject'], suite['cfile'], suite['line'], suite['name'], + suite['object'], suite['tlist']) ) + + for test in suite['tests']: + output.write( ' %s.initialize( %s, %s, %s, "%s" );\n' % + (test['object'], suite['tlist'], suite['dobject'], test['line'], test['name']) ) + + output.write( ' }\n' ) + output.write( '}\n' ) + +main() diff --git a/cxxtest/docs/convert.pl b/cxxtest/docs/convert.pl new file mode 100644 index 000000000..9d83f1c0c --- /dev/null +++ b/cxxtest/docs/convert.pl @@ -0,0 +1,83 @@ +#!/usr/bin/perl + +die "Usage: $0 <text file> <html file> <TexInfo file>\n" + unless scalar @ARGV == 3; + +my ($text, $html, $texi) = @ARGV; + +open TEXT, "<$text" or die "Cannot open text file \"$text\"\n"; +open HTML, ">$html" or die "Cannot create html file \"$html\"\n"; +open TEXI, ">$texi" or die "Cannot create TexInfo file \"$texi\"\n"; + +print HTML "<html>"; + +sub analyze($) { + my ($line) = @_; + my ($htmlLine, $texiLine) = ($line, $line); + + # command line options + $texiLine =~ s/ (--?[a-z-]*)/ \@option{$1}/g; + $htmlLine =~ s/ (--?[a-z-]*)/ <tt>$1<\/tt>/g; + + # [Class::]function() + $texiLine =~ s/([^A-Za-z])(([A-Z][A-Za-z0-9]*::)?[A-Za-z0-9]+\(\))/$1\@code{$2}/g; + $htmlLine =~ s/([^A-Za-z])(([A-Z][A-Za-z0-9]*::)?[A-Za-z0-9]+\(\))/$1<code>$2<\/code>/g; + + # `file' + $texiLine =~ s/`([A-Za-z.\/]*)'/\@file{$1}/g; + $htmlLine =~ s/`([A-Za-z.\/]*)'/<tt>`$1'<\/tt>/g; + + # TS... + $texiLine =~ s/(^|[^A-Z])(TS[A-Za-z_*()]*)/$1\@code{$2}/g; + $htmlLine =~ s/(^|[^A-Z])(TS[A-Za-z_*()]*)/$1<code>$2<\/code>/g; + + # CXXTEST_ + $texiLine =~ s/(CXXTEST_[A-Z_]*)/\@code{$1}/g; + $htmlLine =~ s/(CXXTEST_[A-Z_]*)/<tt>$1<\/tt>/g; + + return ($htmlLine, $texiLine); +} + +my $line; +my $inRelease = 0; +while ( defined( $line = <TEXT> ) ) { + chomp $line; + if ( $line =~ m/^CxxTest Releases/ ) { + print HTML "<title>CxxTest Releases\n"; + print HTML "

CxxTest Releases

\n\n"; + + print TEXI "\@appendix Version history\n"; + print TEXI "\@itemize \@bullet\n"; + } + elsif ( $line =~ m/^(.*):$/ ) { + if ( $inRelease ) { + print HTML "\n\n"; + print TEXI "\@end itemize\n"; + } + + print HTML "

$1

\n"; + print HTML "
    \n"; + + print TEXI "\@item\n\@strong{$1}\n"; + print TEXI "\@itemize \@minus\n"; + + $inRelease = 1; + } + elsif ( $line =~ m/^ - (.*)$/ ) { + my ($htmlLine, $texiLine) = analyze($1); + print HTML "
  • $htmlLine
  • \n"; + print TEXI "\@item\n$texiLine\n"; + } +} + +if ( $inRelease ) { + print HTML "
\n\n"; + print TEXI "\@end itemize\n\n"; +} + +print HTML "\n"; +print TEXI "\@end itemize\n"; + +close TEXT or die "Error closing text file \"$text\"\n"; +close HTML or die "Error closing html file \"$html\"\n"; +close TEXI or die "Error closing TexInfo file \"$texi\"\n"; diff --git a/cxxtest/docs/guide.html b/cxxtest/docs/guide.html new file mode 100644 index 000000000..fb435fb8f --- /dev/null +++ b/cxxtest/docs/guide.html @@ -0,0 +1,1960 @@ + + +CxxTest User's Guide + + + + + + +

CxxTest User's Guide

+Table of contents + +

1 Introduction

+ +

CxxTest is a JUnit/CppUnit/xUnit-like framework for C++. + +

Its advantages over existing alternatives are that it: +

    +
  • Doesn't require RTTI +
  • Doesn't require member template functions +
  • Doesn't require exception handling +
  • Doesn't require any external libraries (including memory management, file/console I/O, graphics libraries) +
+ In other words, CxxTest is designed to be as portable as possible. Its +only requirements are a reasonably modern C++ compiler and either Perl +or Python. However, when advanced features are supported in your +environment, CxxTest can use them, e.g. catch unhandled exceptions and +even display a GUI. + +

In addition, CxxTest is slightly easier to use than the C++ +alternatives, since you don't need to "register" your tests. It also +features some extras like a richer set of assertions and even support +for a "to do" list (see TS_WARN()). + +

CxxTest is available under the +GNU Lesser General Public License. + +

1.1 About this guide

+ +

This guide is not intended as an introduction to Extreme Progamming +and/or unit testing. It describes the design and usage of CxxTest. + +

2 Getting started

+ +

2.1 Getting CxxTest

+ +

The homepage for CxxTest is http://cxxtest.sourceforge.net. You +can always get the latest release from the SourceForge download page, +here +or here. The latest version +of this guide is available online at +http://cxxtest.sourceforge.net/guide.html. A PDF version is also +available at http://cxxtest.sourceforge.net/guide.pdf. + +

2.2 Your first test!

+ +

Here's a simple step-by-step guide: + +

    + +
  1. Tests are organized into "Test Suites". + Test suites are written in header files. + +

    A test suite is a class that inherits from CxxTest::TestSuite. + A test is a public void (void) member function of that class whose name starts with test, + e.g. testDirectoryScanner(), test_cool_feature() and even TestImportantBugFix(). + +

    +          
    +          // MyTestSuite.h
    +          #include <cxxtest/TestSuite.h>
    +          
    +          class MyTestSuite : public CxxTest::TestSuite 
    +          {
    +          public:
    +             void testAddition( void )
    +             {
    +                TS_ASSERT( 1 + 1 > 1 );
    +                TS_ASSERT_EQUALS( 1 + 1, 2 );
    +             }
    +          };
    +          
    +
    + +

  2. After you have your test suites, you use CxxTest to generate a "test runner" source file: + +
    +     # cxxtestgen.pl --error-printer -o runner.cpp MyTestSuite.h
    +     
    + +

    or, for those less fortunate: + +

    +     C:\tmp> perl -w cxxtestgen.pl --error-printer -o runner.cpp MyTestSuite.h
    +     
    + +

  3. You would then simply compile the resulting file: + +
    +     # g++ -o runner runner.cpp
    +     
    + +

    or perhaps + +

    +     C:\tmp> cl -GX -o runner.exe runner.cpp
    +     
    + +

    or maybe even + +

    +     C:\tmp> bcc32 -erunner.exe runner.cpp
    +     
    + +

  4. Finally, you run the tests and enjoy a well tested piece of software: + +
    +     # ./runner
    +     Running 1 test.OK!
    +     
    + +
+ +

2.3 Your second test

+ +

Now let's see what failed tests look like. +We will add a failing test to the previous example: + +

+     
+     // MyTestSuite.h
+     #include <cxxtest/TestSuite.h>
+     
+     class MyTestSuite : public CxxTest::TestSuite 
+     {
+     public:
+        void testAddition( void )
+        {
+           TS_ASSERT( 1 + 1 > 1 );
+           TS_ASSERT_EQUALS( 1 + 1, 2 );
+        }
+     
+        void testMultiplication( void )
+        {
+           TS_ASSERT_EQUALS( 2 * 2, 5 );
+        }
+     };
+     
+
+ +

Generate, compile and run the test runner, and you will get this: + +

+     
+     # ./runner
+     Running 2 tests.
+     MyTestSuite.h:15: Expected (2 * 2 == 5), found (4 != 5)
+     Failed 1 of 2 tests
+     Success rate: 50%
+     
+
+ +

Fixing the bug is left as an excercise to the reader. + +

2.4 Graphical user interface

+ + (v3.0.1) +CxxTest can also display a simple GUI. The way to do this is depends on +your compiler, OS and environment, but try the following pointers: +
    + +
  • Under Windows with Visual C++, run perl cxxtestgen.pl -o runner.cpp +--gui=Win32Gui MyTestSuite.h. + +
  • Under X-Windows, try ./cxxtestgen.pl -o runner.cpp +--gui=X11Gui MyTestSuite. You may need to tell the compiler +where to find X, usually something like g++ -o runner +-L/usr/X11R6/lib runner.cpp -lX11. + +
  • If you have Qt installed, try running +cxxtestgen.pl with the option --gui=QtGui. As +always, compile and link the the Qt headers and libraries. + +
+ +

See Graphical user interface and Running the samples for +more information. + +

3 Really using CxxTest

+ +

There is much more to CxxTest than seeing if two times two is four. +You should probably take a look at the samples in the CxxTest distribution. +Other than that, here are some more in-depth explanations. + +

3.1 What can you test

+ +

Here are the different "assertions" you can use in your tests: + +

Macro Description Example + +
TS_FAIL(message) +Fail unconditionally +TS_FAIL("Test not implemented"); + +
TS_ASSERT(expr) +Verify (expr) is true +TS_ASSERT(messageReceived()); + +
TS_ASSERT_EQUALS(x, y) +Verify (x==y) +TS_ASSERT_EQUALS(nodeCount(), 14); + +
TS_ASSERT_SAME_DATA(x, y, size) +Verify two buffers are equal +TS_ASSERT_SAME_DATA(input, output,, size); + +
TS_ASSERT_DELTA(x, y, d) +Verify (x==y) up to d +TS_ASSERT_DELTA(sqrt(4.0), 2.0, 0.0001); + +
TS_ASSERT_DIFFERS(x, y) +Verify !(x==y) +TS_ASSERT_DIFFERS(exam.numTook(), exam.numPassed()); + +
TS_ASSERT_LESS_THAN(x, y) +Verify (x<y) +TS_ASSERT_LESS_THAN(ship.speed(), SPEED_OF_LIGHT); + +
TS_ASSERT_LESS_THAN_EQUALS(x, y) +Verify (x<=y) +TS_ASSERT_LESS_THAN_EQUALS(requests, items); + +
TS_ASSERT_PREDICATE(R, x) +Verify P(x) +TS_ASSERT_PREDICATE(SeemsReasonable, salary); + +
TS_ASSERT_RELATION(R, x, y) +Verify x R y +TS_ASSERT_RELATION(std::greater, salary, average); + +
TS_ASSERT_THROWS(expr, type) +Verify that (expr) throws a specific type of exception +TS_ASSERT_THROWS(parse(file), Parser::ReadError); + +
TS_ASSERT_THROWS_EQUALS(expr, arg, x, y) +Verify type and value of what (expr) throws +(See text) + +
TS_ASSERT_THROWS_ASSERT(expr, arg, assertion) +Verify type and value of what (expr) throws +(See text) + +
TS_ASSERT_THROWS_ANYTHING(expr) +Verify that (expr) throws an exception +TS_ASSERT_THROWS_ANYTHING(buggy()); + +
TS_ASSERT_THROWS_NOTHING(expr) +Verify that (expr) doesn't throw anything +TS_ASSERT_THROWS_NOTHING(robust()); + +
TS_WARN(message) +Print message as a warning +TS_WARN("TODO: Check invalid parameters"); + +
TS_TRACE(message) +Print message as an informational message +TS_TRACE(errno); + +
+ +

3.1.1 TS_FAIL

+ +

+ +

TS_FAIL just fails the test. +It is like an assert(false) with an error message. +For example: + +

+     
+     void testSomething( void )
+     {
+        TS_FAIL( "I don't know how to test this!" );
+     }
+     
+
+ +

3.1.2 TS_ASSERT

+ +

+ +

TS_ASSERT is the basic all-around tester. It works just like the +well-respected assert() macro (which I sincerely hope you know and +use!) An example: + +

+     
+     void testSquare( void )
+     {
+        MyFileLibrary::createEmptyFile( "test.bin" );
+        TS_ASSERT( access( "test.bin", 0 ) == 0 );
+     }
+     
+
+ +

3.1.3 TS_ASSERT_EQUALS

+ +

+ +

This is the second most useful tester. +As the name hints, it is used to test if two values are equal. + +

+     
+     void testSquare( void )
+     {
+        TS_ASSERT_EQUALS( square(-5), 25 );
+     }
+     
+
+ +

3.1.4 TS_ASSERT_SAME_DATA

+ +

+ + (v3.5.1) +This assertion is similar to TS_ASSERT_EQUALS(), except that it +compares the contents of two buffers in memory. If the comparison +fails, the standard runner dumps the contents of both buffers as hex +values. + +

+     
+     void testCopyMemory( void )
+     {
+        char input[77], output[77];
+        myCopyMemory( output, input, 77 );
+        TS_ASSERT_SAME_DATA( input, output, 77 );
+     }
+     
+
+ +

3.1.5 TS_ASSERT_DELTA

+ +

+ +

Similar to TS_ASSERT_EQUALS(), this macro +verifies two values are equal up to a delta. +This is basically used for floating-point values. + +

+     
+     void testSquareRoot( void )
+     {
+        TS_ASSERT_DELTA( squareRoot(4.0), 2.0, 0.00001 );
+     }
+     
+
+ +

3.1.6 TS_ASSERT_DIFFERS

+ +

+ +

The opposite of TS_ASSERT_EQUALS(), this macro is used to assert +that two values are not equal. + +

+     
+     void testNumberGenerator( void )
+     {
+        int first = generateNumber();
+        int second = generateNumber();
+        TS_ASSERT_DIFFERS( first, second );
+     }
+     
+
+ +

3.1.7 TS_ASSERT_LESS_THAN

+ +

+ +

This macro asserts that the first operand is less than the second. + +

+     
+     void testFindLargerNumber( void )
+     {
+        TS_ASSERT_LESS_THAN( 23, findLargerNumber(23) );
+     }
+     
+
+ +

3.1.8 TS_ASSERT_LESS_THAN_EQUALS

+ +

+ + (v3.7.0) +Not surprisingly, this macro asserts that the first operand is less than or equals the second. + +

+     
+     void testBufferSize( void )
+     {
+        TS_ASSERT_LESS_THAN_EQUALS( bufferSize(), MAX_BUFFER_SIZE );
+     }
+     
+
+ +

3.1.9 TS_ASSERT_PREDICATE

+ +

+ + (v3.8.2) +This macro can be seen as a generalization of +TS_ASSERT(). It takes as an argument the name of a class, +similar to an STL unary_function, and evaluates +operator(). The advantage this has over +TS_ASSERT() is that you can see the failed value. + +

+     
+     class IsPrime
+     {
+     public:
+        bool operator()( unsigned ) const;
+     };
+     
+     // ...
+     
+     void testPrimeGenerator( void )
+     {
+        TS_ASSERT_PREDICATE( IsPrime, generatePrime() );
+     }
+     
+
+ +

3.1.10 TS_ASSERT_RELATION

+ +

+ + (v3.8.0) +Closely related to +TS_ASSERT_PREDICATE(), this macro can be seen as a +generalization of TS_ASSERT_EQUALS(), +TS_ASSERT_DIFFERS(), +TS_ASSERT_LESS_THAN() and +TS_ASSERT_LESS_THAN_EQUALS(). It takes as an argument the +name of a class, similar to an STL binary_function, and evaluates +operator(). This can be used to very simply assert comparisons +which are not covered by the builtin macros. + +

+     
+     void testGreater( void )
+     {
+        TS_ASSERT_RELATION( std::greater<int>, ticketsSold(), 1000 );
+     }
+     
+
+ +

3.1.11 TS_ASSERT_THROWS and friends

+ +

+ +

These assertions are used to test whether an expression throws an exception. +TS_ASSERT_THROWS is used when you want to verify the type of exception +thrown, and TS_ASSERT_THROWS_ANYTHING is used to just make sure something +is thrown. As you might have guessed, TS_ASSERT_THROWS_NOTHING asserts +that nothing is thrown. + + (v3.10.0) +TS_ASSERT_THROWS_EQUALS checks the type of the +exception as in TS_ASSERT_THROWS then allows you to compare two +value (one of which will presumably be the caught object). +TS_ASSERT_THROWS_ASSERT is the general case, and allows you to +make any assertion about the thrown value. These macros may seem a +little complicated, but they can be very useful; see below for an +example. + +

+     
+     void testFunctionsWhichThrowExceptions( void )
+     {
+        TS_ASSERT_THROWS_NOTHING( checkInput(1) );
+        TS_ASSERT_THROWS( checkInput(-11), std::runtime_error );
+        TS_ASSERT_THROWS_ANYTHING( thirdPartyFunction() );
+     
+        TS_ASSERT_THROWS_EQUALS( validate(), const std::exception &e, 
+                                 e.what(), "Invalid value" );
+        TS_ASSERT_THROWS_ASSERT( validate(), const Error &e, 
+                                 TS_ASSERT_DIFFERS( e.code(), SUCCESS ) );
+     }
+     
+
+ +

3.1.12 TS_TRACE and TS_WARN

+ +

+ + + (v3.0.1) +TS_WARN just prints out a message, like the +#warning preprocessor directive. I find it very useful for "to +do" items. For example: + +

+     
+     void testToDoList( void )
+     {
+        TS_WARN( "TODO: Write some tests!" );
+        TS_WARN( "TODO: Make $$$ fast!" );
+     }
+     
+
+ +

In the GUI, TS_WARN sets the bar color to yellow (unless it was +already red). + + (v3.9.0) +TS_TRACE is the same, except that it +doesn't change the color of the progress bar. + +

3.1.13 The ETS_ macros

+ +

The TS_ macros mentioned above will catch exceptions thrown from tested code +and fail the test, as if you called TS_FAIL(). +Sometimes, however, you may want to catch the exception yourself; when you do, you can +use the ETS_ versions of the macros. + +

+     
+     void testInterestingThrower()
+     {
+        // Normal way: if an exception is caught we can't examine it
+        TS_ASSERT_EQUALS( foo(2), 4 );
+     
+        // More elaborate way:
+        try { ETS_ASSERT_EQUALS( foo(2), 4 ); } 
+        catch( const BadFoo &e ) { TS_FAIL( e.bar() ); }
+     }
+     
+
+ +

3.1.14 The TSM_ macros

+ +

Sometimes the default output generated by the ErrorPrinter doesn't give you enough +information. This often happens when you move common test functionality to helper functions +inside the test suite; when an assertion fails, you do not know its origin. + +

In the example below (which is the file sample/MessageTest.h from the CxxTest distribution), +we need the message feature to know which invocation of checkValue() failed: + +

+     
+     class MessageTest : public CxxTest::TestSuite
+     {
+     public:
+        void testValues()
+        {
+           checkValue( 0, "My hovercraft" );
+           checkValue( 1, "is full" );
+           checkValue( 2, "of eels" );
+        }
+     
+        void checkValue( unsigned value, const char *message )
+        {
+           TSM_ASSERT( message, value );
+           TSM_ASSERT_EQUALS( message, value, value * value );
+        }
+     };
+     
+
+ +
3.1.14.1 The ETSM_ macros
+ +

Note: As with normal asserts, all TSM_ macros have their +non-exception-safe counterparts, the ETSM_ macros. + +

3.2 Running the samples

+ +

+ +

CxxTest comes with some samples in the sample/ subdirectory of +the distribution. If you look in that directory, you will see three +Makefiles: Makefile.unix, Makefile.msvc and +Makefile.bcc32 which are for Linux/Unix, MS Visual C++ and +Borland C++, repectively. These files are provided as a starting point, +and some options may need to be tweaked in them for your system. + +

If you are running under Windows, a good guess would be to run +nmake -fMakefile.msvc run_win32 (you may need to run +VCVARS32.BAT first). Under Linux, make +-fMakefile.unix run_x11 should probably work. + +

3.3 Test fixtures

+ +

When you have several test cases for the same module, +you often find that all of them start with more or less +the same code--creating objects, files, inputs, etc. +They may all have a common ending, too--cleaning up +the mess you left. + +

You can (and should) put all this code in a common place by overriding +the virtual functions TestSuite::setUp() and +TestSuite::tearDown(). setUp() will +then be called before each test, and tearDown() +after each test. + +

+     
+     class TestFileOps : public CxxTest::TestSuite 
+     {
+     public:
+        void setUp() { mkdir( "playground" ); }
+        void tearDown() { system( "rm -Rf playground"); }
+     
+        void testCreateFile()
+        {
+           FileCreator fc( "playground" );
+           fc.createFile( "test.bin" );
+           TS_ASSERT_EQUALS( access( "playground/test.bin", 0 ), 0 );
+        }
+     };
+     
+
+ +

Note new users: This is probably the single most important +feature to use when your tests become non-trivial. + +

3.3.1 Test suite level fixtures

+ +

setUp()/tearDown() are executed around each test case. If +you need a fixture on the test suite level, i.e. something that gets +constructed once before all the tests in the test suite are run, see +Dynamically creating test suites below. + +

3.4 Integrating with your build environment

+ +

It's very hard to maintain your tests if you have to generate, compile and run the test runner +manually all the time. +Fortunately, that's why we have build tools! + +

3.4.1 Overview

+ +

Let's assume you're developing an application. +What I usually do is the following: +

    +
  • Split the application into a library and a main module that just calls + the library classes. + This way, the test runner will be able to access all your classes through + the library. +
  • Create another application (or target, or project, or whatever) for the test runner. + Make the build tool generate it automatically. +
  • For extra points, make the build tool run the tests automatically. +
+ +

3.4.2 Actually doing it

+ +

Unfortunately, there are way too many different build tools and IDE's for me +to give ways to use CxxTest with all of them. + +

I will try to outline the usage for some cases. + +

3.4.2.1 Using Makefiles
+ +

Generating the tests with a makefile is pretty straightforward. +Simply add rules to generate, compile and run the test runner. + +

+     
+     all: lib run_tests app
+     
+     # Rules to build your targets
+     lib: ...
+     
+     app: ...
+     
+     # A rule that runs the unit tests
+     run_tests: runner
+             ./runner
+     
+     # How to build the test runner
+     runner: runner.cpp lib
+             g++ -o $@ $^
+     
+     # How to generate the test runner
+     runner.cpp: SimpleTest.h ComplicatedTest.h
+              cxxtestgen.pl -o $@ --error-printer $^
+     
+
+ +
3.4.2.2 Using Cons
+ + Cons is a powerful and +versatile make replacement which uses Perl scripts instead of Makefiles. + +

See sample/Construct in the CxxTest distribution for an example of building CxxTest test runners +with Cons. + +

3.4.2.3 Using Microsoft Visual Studio
+ +

I have tried several ways to integrate CxxTest with visual studio, none of +which is perfect. Take a look at sample/msvc in the distribution +to see the best solution I'm aware of. Basically, the workspace has three +projects: + +

    +
  • The project CxxTest_3_Generate runs cxxtestgen. + +
  • The project CxxTest_2_Build compiles the generated file. + +
  • The project CxxTest_1_Run runs the tests. +
+ +

This method certainly works, and the test results are conveniently +displayed as compilation errors and warnings (for +TS_WARN()). However, there are still a few things missing; +to integrate this approach with your own project, you usually need to +work a little bit and tweak some makefiles and project options. I have +provided a small script in sample/msvc/FixFiles.bat to automate +some of the process. + +

3.4.2.4 Using Microsoft Windows DDK
+ +

Unit testing for device drivers?! Why not? +And besides, the build utility can also be used to build +user-mode application. + +

To use CxxTest with the build utility, +you add the generated tests file as an extra dependency +using the NTBUILDTARGET0 macro and the Makefile.inc +file. + +

You can see an example of how to do this in the CxxTest distribution +under sample/winddk. + +

3.5 Graphical user interface

+ +

+ +

There are currently three GUIs implemented: native Win32, native X11 and +Qt. To use this feature, just specify --gui=X11Gui, +--gui=Win32Gui or --gui=QtGui as a parameter for +cxxtestgen (instead of e.g. --error-printer). A +progress bar is displayed, but the results are still written to standard +output, where they can be processed by your IDE (e.g. Emacs or Visual +Studio). The default behavior of the GUI is to close the window after +the last test. + +

Note that whatevr GUI you use, you can combine it with the +--runner option to control the formatting of the text output, +e.g. Visual Studio likes it better if you use +--runner=ParenPrinter. + +

3.5.1 Starting the GUI minimized

+ +

If you run the generated Win32 or Qt GUIs with the command line +-minimized, the test window will start minimized (iconified) +and only pop up if there is an error (the bar turns red). This is useful +if you find the progress bar distracting and only want to check it if +something happens. + +

3.5.2 Leaving the GUI open

+ +

The Win32 GUI accepts the -keep which instructs it to leave the +window open after the tests are done. This allows you to see how many +tests failed and how much time it took. + +

3.5.3 Screenshots!

+ +

As with any self-respecting GUI application, here are some screenshots for +you to enjoy: + +

    + +
  • Using the Qt GUI on Linux (with the WindowMaker window manager): +
    qt.png
    +

    +

  • Using the Win32 GUI on Windows 98: +
    win32.png
    +

    +

  • Using the X11 GUI (with the venerable TWM): +
    x11.png
    +

    +

  • And of course, no GUI is complete without the ability to mess around with +its appearance: +
    qt2.png
    +

    +

    Ahhh. Nothing like a beautiful user interface. + +

+ +

4 Advanced topics

+ +

Topics in this section are more technical, and you probably won't find them +interesting unless you need them. + +

4.1 Aborting tests after failures

+ +

Usually, when a TS_ASSERT_* macro fails, CxxTest moves on to the +next line. In many cases, however, this is not the desired behavior. +Consider the following code: + +

+     
+     void test_memset()
+     {
+        char *buffer = new char[1024];
+        TS_ASSERT( buffer );
+        memset( buffer, 0, 1024 ); // But what if buffer == 0?
+     }
+     
+
+ +

If you have exception handling enabled, you can make CxxTest exit each +test as soon as a failure occurs. To do this, you need to define +CXXTEST_ABORT_TEST_ON_FAIL before including the CxxTest +headers. This can be done using the --abort-on-fail +command-line option or in a template file; see +sample/aborter.tpl in the distribution. Note that if CxxTest +doesn't find evidence of exception handling when scanning your files, +this feature will not work. To overcome this, use the +--have-eh command-line option. + +

4.1.1 Controlling this behavior at runtime

+ + (v3.8.5) +In some scenarios, you may want some tests to abort on +failed assertions and others to continue. To do this you use the +--abort-on-fail option and call the function +CxxTest::setAbortTestOnFail( bool ) to change the runtime +behavior. This flag is reset (normally, to true) after each +test, but you can set it in your test suite's setUp() function to +modify the behavior for all tests in a suite. + + (v3.9.0) +Note that this behavior is available whenever you have +exception handling (--have-eh or CXXTEST_HAVE_EH); all +--abort-on-fail does is set the default to true. + +

4.2 Commenting out tests

+ +

CxxTest does a very simple analysis of the input files, which is sufficient in most cases. +This means, for example, that you can't indent you test code in "weird" ways. + +

A slight inconvenience arises, however, when you want to comment out +tests. Commenting out the tests using C-style comments or the +preprocessor will not work: + +

+     
+     class MyTest : public CxxTest::TestSuite
+     {
+     public:
+     /*
+        void testCommentedOutStillGetsCalled()
+        {
+        }
+     */
+     
+     #if 0
+        void testMarkedOutStillGetsCalled()
+        {
+        }
+     #endif
+     };
+     
+
+ + (v3.10.0) +If you need to comment out tests, use C++-style +comments. Also, if you just don't want CxxTest to run a specific test +function, you can temporarily change its name, e.g. by prefixing it with +x: + +
+     
+     class MyTest : public CxxTest::TestSuite
+     {
+     public:
+     // void testFutureStuff()
+     // {
+     // }
+     
+        void xtestFutureStuff()
+        {
+        }
+     };
+     
+
+ +

4.3 Comparing equality for your own types

+ +

You may have noticed that TS_ASSERT_EQUALS() only works for built-in +types. +This is because CxxTest needs a way to compare object and to convert them to strings, +in order to print them should the test fail. + +

If you do want to use TS_ASSERT_EQUALS() on your own data types, +this is how you do it. + +

4.3.1 The equality operator

+ +

First of all, don't forget to implement the equality operator (operator==()) +on your data types! + +

4.3.2 Value traits

+ +

Since CxxTest tries not to rely on any external library (including the standard library, +which is not always available), conversion from arbitrary data types to strings +is done using value traits. + +

For example, to convert an integer to a string, CxxTest does the following actions: +

    +
  • int i = value to convert; +
  • CxxTest::ValueTraits<int> converter(i); +
  • string = converter.asString(); +
+ +

CxxTest comes with predefined ValueTraits for int, +char, dobule etc. in cxxtest/ValueTraits.h in the +cxxtest-selftest archive. + +

4.3.3 Unknown types

+ +

Obviously, CxxTest doesn't "know" about all possible types. +The default ValueTraits class for unknown types dumps up to 8 bytes of the value in hex format. + +

For example, the following code +

+     
+     #include <cxxtest/TestSuite.h>
+     
+     class TestMyData : public CxxTest::TestSuite 
+     {
+     public:
+        struct Data
+        {
+           char data[3];
+        };
+     
+        void testCompareData()
+        {
+           Data x, y;
+           memset( x.data, 0x12, sizeof(x.data) );
+           memset( y.data, 0xF6, sizeof(y.data) );
+           TS_ASSERT_EQUALS( x, y );
+        }
+     };
+     
+
+ would output +
+     
+     Running 1 test.
+     TestMyData.h:16: Expected (x == y), found ({ 12 12 12 } != { F6 F6 F6 })
+     Failed 1 of 1 test
+     Success rate: 0%
+     
+
+ +

4.3.4 Enumeration traits

+ + (v3.10.0) +CxxTest provides a simple way to define value traits for +your enumeration types, which is very handy for things like status +codes. To do this, simply use CXXTEST_VALUE_TRAITS as in the +following example: + +
+     
+     enum Status { STATUS_IDLE, STATUS_BUSY, STATUS_ERROR };
+     
+     CXXTEST_ENUM_TRAITS( Status,
+                          CXXTEST_ENUM_MEMBER( STATUS_IDLE )
+                          CXXTEST_ENUM_MEMBER( STATUS_BUSY )
+                          CXXTEST_ENUM_MEMBER( STATUS_ERROR ) );
+     
+
+ +

See sample/EnumTraits.h for a working sample. + +

4.3.5 Defining new value traits

+ +

Defining value traits for new (non-enumeration) types is easy. All you +need is to define a way to convert an object of your class to a +string. You can use this example as a possible skeleton: + +

+     
+     class MyClass 
+     {
+        int _value;
+     
+     public:
+        MyClass( int value ) : _value( value ) {}
+        int value() const { return _value; }
+     
+        // CxxTest requires a copy constructor
+        MyClass( const MyClass &other ) : _value( other._value ) {}
+     
+        // If you want to use TS_ASSERT_EQUALS
+        bool operator== ( const MyClass &other ) const { return _value == other._value; }
+     
+        // If you want to use TS_ASSERT_LESS_THAN
+        bool operator== ( const MyClass &other ) const { return _value < other._value; }
+     };
+     
+     #ifdef CXXTEST_RUNNING
+     #include <cxxtest/ValueTraits.h>
+     #include <stdio.h>
+     
+     namespace CxxTest 
+     {
+        CXXTEST_TEMPLATE_INSTANTIATION
+        class ValueTraits<MyClass> 
+        {
+           char _s[256];
+     
+        public:
+           ValueTraits( const MyClass &m ) { sprintf( _s, "MyClass( %i )", m.value() ); }
+           const char *asString() const { return _s; }
+        };
+     };
+     #endif // CXXTEST_RUNNING
+     
+
+ +
4.3.5.1 Defining value traits for template classes
+ +

A simple modification to the above scheme allows you to define value +traits for your template classes. Unfortunately, this syntax (partial +template specialization) is not supported by some popular C++ compilers. +Here is an example: + +

+     
+     template<class T>
+     class TMyClass
+     {
+        T _value;
+     
+     public:
+        TMyClass( const T &value ) : _value( value );
+        const T &value() const { return _value; }
+     
+        // CxxTest requires a copy constructor
+        TMyClass( const TMyClass<T> &other ) : _value( other._value ) {}
+        
+        // If you want to use TS_ASSERT_EQUALS
+        bool operator== ( const TMyClass<T> &other ) const { return _value == other._value; }
+     };
+     
+     #ifdef CXXTEST_RUNNING
+     #include <cxxtest/ValueTraits.h>
+     #include <typeinfo>
+     #include <sstream>
+     
+     namespace CxxTest 
+     {
+        template<class T>
+        class ValueTraits< TMyClass<T> > 
+        {
+           std::ostringstream _s;
+     
+        public:
+           ValueTraits( const TMyClass<T> &t ) 
+              { _s << typeid(t).name() << "( " << t.value() << " )"; }
+           const char *asString() const { return _s.str().c_str(); }
+        };
+     };
+     #endif // CXXTEST_RUNNING
+     
+
+ +

4.3.6 Overriding the default value traits

+ + (v2.8.2) +If you don't like the way CxxTest defines the default ValueTraits, +you can override them by #define-ing CXXTEST_USER_VALUE_TRAITS; +this causes CxxTest to omit the default definitions, and from there on you are +free to implement them as you like. + +

You can see a sample of this technique in test/UserTraits.tpl in +the cxxtest-selftest archive. + +

4.4 Global Fixtures

+ + (v3.5.1) +The setUp() and tearDown() functions allow +to to have code executed before and after each test. What if you want +some code to be executed before all tests in all test suites? +Rather than duplicate that code, you can use global fixtures. +These are basically classes that inherit from +CxxTest::GlobalFixture. All objects of such classes are +automatically notified before and after each test case. It is best to +create them as static objects so they get called right from the start. +Look at test/GlobalFixtures.h in the cxxtest-selftest +archive. + +

Note: Unlike setUp() and tearDown() in +TestSuite, global fixtures should return a bool value to +indicate success/failure. + +

4.4.1 World fixtures

+ + (v3.8.1) +CxxTest also allows you to specify code which is executed +once at the start of the testing process (and the corresponding cleanup +code). To do this, create (one or more) global fixture objects and +implement setUpWorld()/tearDownWorld(). For an example, +see test/WorldFixtures.h in the cxxtest-selftest archive. + +

4.5 Mock Objects

+ + (v3.10.0) +Mock Objects are a very useful testing tool, which +consists (in a nutshell) of passing special objects to tested code. For +instance, to test a class that implements some protocol over TCP, you +might have it use an abstract ISocket interface and in the tests +pass it a MockSocket object. This MockSocket object can +then do anything your tests find useful, e.g. keep a log of all data +"sent" to verify later. + +

So far, so good. But the problem when developing in C/C++ is that your +code probably needs to call global functions which you cannot +override. Just consider any code which uses fopen(), +fwrite() and fclose(). It is not very elegant to have +this code actually create files while being tested. Even more +importantly, you (should) want to test how the code behaves when "bad" +things happen, say when fopen() fails. Although for some cases +you can cause the effects to happen in the test code, this quickly +becomes "hairy" and unmaintainable. + +

CxxTest solves this problem by allowing you to override any global +function while testing. Here is an outline of how it works, before we +see an actual example: +

    + +
  • For each function you want to override, you use the macro +CXXTEST_MOCK_GLOBAL to "prepare" the function (all is explained +below in excruciating detail). + +
  • In the tested code you do not call the global functions directly; +rather, you access them in the T (for Test) namespace. For +instance, your code needs to call T::fopen() instead of +fopen(). This is the equivalent of using abstract interfaces +instead of concrete classes. + +
  • You link the "real" binary with a source file that implements +T::fopen() by simply calling the original fopen(). + +
  • You link the test binary with a source file that implements +T::fopen() by calling a mock object. + +
  • To test, you should create a class that inherits T::Base_fopen +and implement its fopen() function. Simply by creating an object +of this class, calls made to T::fopen() will be redirected to it. + +
+ +

This may seem daunting at first, so let us work our way through a simple +example. Say we want to override the well known standard library +function time(). + +

    + +
  • Prepare a header file to be used by both the real and test code. +
    +          
    +          // T/time.h
    +          #include <time.h>
    +          #include <cxxtest/Mock.h>
    +          
    +          CXXTEST_MOCK_GLOBAL( time_t,        /* Return type          */
    +                               time,          /* Name of the function */
    +                               ( time_t *t ), /* Prototype            */
    +                               ( t )          /* Argument list        */ );
    +          
    +
    + +
  • In our tested code, we now include the special header instead of the +system-supplied one, and call T::time() instead of time(). +
    +          
    +          // code.cpp
    +          #include <T/time.h>
    +          
    +          int generateRandomNumber()
    +          {
    +              return T::time( NULL ) * 3;
    +          }
    +          
    +
    + +
  • We also need to create a source file that implements T::time() by +calling the real function. This is extremely easy: just define +CXXTEST_MOCK_REAL_SOURCE_FILE before you include the header file: +
    +          
    +          // real_time.cpp
    +          #define CXXTEST_MOCK_REAL_SOURCE_FILE
    +          #include <T/time.h>
    +          
    +
    + +
  • Before we can start testing, we need a different implementation of +T::time() for our tests. This is just as easy as the previous +one: +
    +          
    +          // mock_time.cpp
    +          #define CXXTEST_MOCK_TEST_SOURCE_FILE
    +          #include <T/time.h>
    +          
    +
    + +
  • Now comes the fun part. In our test code, all we need to do is create a +mock, and the tested code will magically call it: +
    +          
    +          // TestRandom.h
    +          #include <cxxtest/TestSuite.h>
    +          #include <T/time.h>
    +          
    +          class TheTimeIsOne : public T::Base_time
    +          {
    +          public:
    +              time_t time( time_t * ) { return 1; }
    +          };
    +          
    +          class TestRandom : public CxxTest::TestSuite
    +          {
    +          public:
    +              void test_Random()
    +              {
    +                  TheTimeIsOne t;
    +                  TS_ASSERT_EQUALS( generateRandomNumber(), 3 );
    +              }
    +          };
    +          
    +
    + +
+ +

4.5.1 Actually doing it

+ +

I know that this might seem a bit heavy at first glance, but once you +start using mock objects you will never go back. The hardest part may +be getting this to work with your build system, which is why I have +written a simple example much like this one in sample/mock, which +uses GNU Make and G++. + +

4.5.2 Advanced topic with mock functions

+ +
4.5.2.1 Void functions
+ +

Void function are a little different, and you use +CXXTEST_MOCK_VOID_GLOBAL to override them. This is identical to +CXXTEST_MOCK_GLOBAL except that it doesn't specify the return +type. Take a look in sample/mock/T/stdlib.h for a demonstation. + +

4.5.2.2 Calling the real functions while testing
+ +

From time to time, you might want to let the tested code call the real +functions (while being tested). To do this, you create a special mock +object called e.g. T::Real_time. While an object of this class +is present, calls to T::time() will be redirected to the real +function. + +

4.5.2.3 When there is no real function
+ +

Sometimes your code needs to call functions which are not available when +testing. This happens for example when you test driver code using a +user-mode test runner, and you need to call kernel functions. You can +use CxxTest's mock framework to provide testable implementations for the +test code, while maintaing the original functions for the real code. +This you do with CXXTEST_SUPPLY_GLOBAL (and +CXXTEST_SUPPLY_VOID_GLOBAL). For example, say you want to supply +your code with the Win32 kernel function IoCallDriver: +

+     
+     CXXTEST_SUPPLY_GLOBAL( NTSTATUS,                /* Return type */
+                            IoCallDriver,            /* Name        */
+                            ( PDEVICE_OBJECT Device, /* Prototype   */
+                              PIRP Irp ),
+                            ( Device, Irp )          /* How to call */ );
+     
+
+ The tested code (your driver) can now call IoCallDriver() +normally (no need for T::), and the test code uses +T::Base_IoCallDriver as with normal mock objects. + +

Note: Since these macros can also be used to actually declare +the function prototypes (e.g. in the above example you might not be able +to include the real <ntddk.h> from test code), they also have an +extern "C" version which declares the functions with C +linkage. These are CXXTEST_SUPPLY_GLOBAL_C and +CXXTEST_SUPPLY_GLOBAL_VOID_C. + +

4.5.2.4 Functions in namespaces
+ +

Sometimes the functions you want to override are not in the global +namespace like time(): they may be global functions in other +namespaces or even static class member functions. The default mock +implementation isn't suitable for these. For them, you can use the +generic CXXTEST_MOCK, which is best explained by example. Say you +have a namespace Files, and you want to override the function +bool Files::FileExists( const String &name ), so that the mock +class will be called T::Base_Files_FileExists and the function to +implement would be fileExists. You would define it thus (of +course, you would normally want the mock class name and member function +to be the same as the real function): +

+     
+     CXXTEST_MOCK( Files_FileExists,       /* Suffix of mock class  */
+                   bool,                   /* Return type           */
+                   fileExists,             /* Name of mock member   */
+                   ( const String &name ), /* Prototype             */
+                   Files::FileExists,      /* Name of real function */
+                   ( name )                /* Parameter list        */ );
+     
+
+ Needless to say, there is also CXXTEST_MOCK_VOID for void functions. + +

There is also an equivalent version for CXXTEST_SUPPLY_GLOBAL, as +demonstrated by another function from the Win32 DDK: +

+     
+     CXXTEST_SUPPLY( AllocateIrp,         /* => T::Base_AllocateIrp */
+                     PIRP,                /* Return type            */
+                     allocateIrp,         /* Name of mock member    */
+                     ( CCHAR StackSize ), /* Prototype              */
+                     IoAllocateIrp,       /* Name of real function  */
+                     ( StackSize )        /* Parameter list         */ );
+     
+
+ And, with this macro you have CXXTEST_SUPPLY_VOID and of course +CXXTEST_SUPPLY_C and CXXTEST_SUPPLY_VOID_C. + +
4.5.2.5 Overloaded functions
+ +

If you have two or more global functions which have the same name, you +cannot create two mock classes with the same name. The solution is to +use the general CXXTEST_MOCK/CXXTEST_MOCK_VOID as above: +just give the two mock classes different names. + +

4.5.2.6 Changing the mock namespace
+ +

Finally, if you don't like or for some reason can't use the T:: +namespace for mock functions, you can change it by defining +CXXTEST_MOCK_NAMESPACE. Have fun. + +

4.6 Test Listeners and Test Runners

+ +

A TestListener is a class that receives notifications about +the testing process, notably which assertions failed. CxxTest defines +a standard test listener class, ErrorPrinter, which is +responsible for printing the dots and messages seen above. When the +test runners generated in the examples run, they create an +ErrorPrinter and pass it to +TestRunner::runAllTests(). As you might have guessed, this +functions runs all the test you've defined and reports to the +TestListener it was passed. + +

4.6.1 Other test listeners

+ +

If you don't like or can't use the ErrorPrinter, you can use +any other test listener. +To do this you have to omit the --error-printer, --runner= +or --gui= switch when generating the tests file. +It is then up to you to write the main() function, using the +test listener of your fancy. + +

4.6.1.1 The stdio printer
+ +

If the ErrorPrinter's usage of std::cout clashes +with your environment or is unsupported by your compiler, don't dispair! +You may still be able to use the StdioPrinter, which does the +exact same thing but uses good old printf(). + +

To use it, invoke cxxtestgen.pl with the --runner=StdioPrinter option. + + (v3.8.5) +Note: cxxtest/StdioPrinter makes +reference to stdout as the default output stream. In some +environments you may have <stdio.h> but not stdout, which +will cause compiler errors. To overcome this problem, use +--runner=StdioFilePrinter, which is exactly the same as +--runner=StdioPrinter, but with no default output stream. + +

4.6.1.2 The Yes/No runner
+ +

As an example, CxxTest also provides the simplest possible test listener, +one that just reports if there were any failures. +You can see an example of using this listener in sample/yes_no_runner.cpp. + +

4.6.1.3 Template files
+ +

To use you own test runner, or to use the supplied ones in different ways, you can use +CxxTest template files. These are ordinary source files with the embedded "command" +<CxxTest world> which tells cxxtestgen.pl to insert the world definition +at that point. You then specify the template file using the --template option. + +

See samples/file_printer.tpl for an example. + +

Note: CxxTest needs to insert certain definitions and +#include directives in the runner file. It normally does that +before the first #include <cxxtest/*.h> found in the template +file. If this behvaior is not what you need, use the "command" +<CxxTest preamble>. See test/preamble.tpl in the +cxxtest-selftest archive for an example of this. + +

4.7 Dynamically creating test suites

+ +

+Usually, your test suites are instantiated statically in the tests file, i.e. say you +defined class MyTest : public CxxTest::TestSuite, the generated file will +contain something like static MyTest g_MyTest;. + +

If, however, your test suite must be created dynamically (it may need a constructor, +for instance), CxxTest doesn't know how to create it unless you tell it how. +You do this by writing two static functions, createSuite() and destroySuite(). + +

See sample/CreatedTest.h for a demonstration. + +

4.8 Static initialization

+ + (v3.9.0) +The generated runner source file depends quite +heavily on static initialization of the various "description" object +used to run your tests. If your compiler/linker has a problem with this +approach, use the --no-static-init option. + +

Appendix A Command line options

+ +

Here are the different command line options for cxxtestgen: + +

A.1 --version

+ + (v3.7.1) +Specify --version or -v to see the version of CxxTest you are using. + +

A.2 --output

+ +

Specify --output=FILE or -o FILE to determine the output file name. + +

A.3 --error-printer

+ +

This option creates a test runner which uses the standard error printer class. + +

A.4 --runner

+ +

Specify --runner=CLASS to generate a test +runner that #includes <cxxtest/CLASS.h> and uses +CxxTest::CLASS as the test runner. + +

The currently available runners are: +

+
--runner=ErrorPrinter +
This is the standard error printer, which formats its output to std::cout. + +
--runner=ParenPrinter +
Identical to ErrorPrinter except that it prints line numbers in parantheses. +This is the way Visual Studio expects it. + +
--runner=StdioPrinter +
The same as ErrorPrinter except that it uses printf +instead of cout. + +
--runner=YesNoRunner +
This runner doesn't produce any output, merely returns a true/false result. + +
+ +

A.5 --gui

+ +

Specify --gui=CLASS to generate a test runner that +#includes <cxxtest/CLASS.h> and uses CxxTest::CLASS +to display a graphical user interface. This option can be combined with +the --runner option to determine the text-mode output format. +The default is the standard error printer. + +

There are three different GUIs: +

+
--gui=Win32Gui +
A native Win32 GUI. It has been tested on Windows 98, 2000 and XP and +should work unmodified on other 32-bit versions of Windows. + +
--gui=X11Gui +
A native XLib GUI. This GUI is very spartan and should work on any X server. + +
--gui=QtGui +
A GUI that uses the Qt library from Troll. It has been tested with Qt versiond 2.2.1 and 3.0.1. +
+ +

A.6 --include

+ + (v3.5.1) +If you specify --include=FILE, cxxtestgen will add +#include "FILE" to the runner before including any other header. +This allows you to define things that modify the behavior of CxxTest, +e.g. your own ValueTraits. + +

Note: If you want the runner to #inculde <FILE>, specify +it on the command line, e.g. --include=<FILE>. You will most +likely need to use shell escapes, e.g. "--include=<FILE>" or +--include=\<FILE\>. + +

Examples: --include=TestDefs.h or --include=\<GlobalDefs.h\>. + +

A.7 --template

+ +

Specify --template=FILE to use FILE as a template file. +This is for cases for which --runner and/or --include +are not enough. One example is the Windows DDK; see +sample/winddk in the distribution. + +

A.8 --have-eh

+ + (v2.8.4) +cxxtestgen will scan its input files for uses of exception +handling; if found, the TS_ macros will catch exceptions, +allowing the testing to continue. Use --have-eh to tell +cxxtestgen to enable that functionality even if exceptions +are not used in the input files. + +

A.9 --no-eh

+ + (v3.8.5) +If you want cxxtestgen to ignore what may look as uses of +exception handling in your test files, specify --no-eh. + +

A.10 --have-std

+ + (v3.10.0) +Same as --have-eh but for the standard library; +basically, if you use this flag, CxxTest will print the values of +std::string. + +

Note: If you reference the standard library anywhere in your +test files, CxxTest will (usually) recognize it and automatically define +this. + +

A.11 --no-std

+ + (v3.10.0) +The counterpart to --have-std, this tells +CxxTest to ignore any evidence it finds for the std:: namespace +in your code. Use it if your environment does not support std:: +but cxxtestgen thinks it does. + +

A.12 --longlong

+ + (v3.6.0) +Specify --longlong=TYPE to have CxxTest recognize TYPE +as "long long" (e.g. --longlong=__int64). If you specify +just --longlong= (no type), CxxTest will use the default type +name of long long. + +

A.13 --abort-on-fail

+ + (v2.8.2) +This useful option tells CxxTest to abort the current test when any +TS_ASSERT macro has failed. + +

A.14 --part

+ + (v3.5.1) +This option tells CxxTest now to write the CxxTest globals in the output +file. Use this to link together more than one generated file. + +

A.15 --root

+ + (v3.5.1) +This is the counterpart of --part; it makes sure that the +Cxxtest globals are written to the output file. If you specify this +option, you can use cxxtestgen without any input files to +create a file that hold only the "root" runner. + +

A.16 --no-static-init

+ + (v3.9.0) +Use this option if you encounter problems with the static +initializations in the test runner. + +

Appendix B Controlling the behavior of CxxTest

+ +

Here are various #defines you can use to modify how CxxTest +works. You will need to #define them before including any +of the CxxTest headers, so use them in a template file or with the +--include option. + +

B.1 CXXTEST_HAVE_STD

+ +

This is equivalent to the --have-std option. + +

B.2 CXXTEST_HAVE_EH

+ +

This is equivalent to the --have-eh option. + +

B.3 CXXTEST_ABORT_TEST_ON_FAIL

+ + (v2.8.0) +This is equivalent to the --abort-on-fail option. + +

B.4 CXXTEST_USER_VALUE_TRAITS

+ +

This tells CxxTest you wish to define you own ValueTraits. It will only +declare the default traits, which dump up to 8 bytes of the data as hex +values. + +

B.5 CXXTEST_OLD_TEMPLATE_SYNTAX

+ +

Some compilers (e.g. Borland C++ 5) don't support the standard way of +instantiating template classes. Use this define to overcome the problem. + +

B.6 CXXTEST_OLD_STD

+ +

Again, this is used to support pre-std:: standard libraries. + +

B.7 CXXTEST_MAX_DUMP_SIZE

+ +

This sets the standard maximum number of bytes to dump if +TS_ASSERT_SAME_DATA() fails. The default is 0, meaning +no limit. + +

B.8 CXXTEST_DEFAULT_ABORT

+ +

This sets the default value of the dynamic "abort on fail" flag. Of +course, this flag is only used when "abort on fail" is enabled. + +

B.9 CXXTEST_LONGLONG

+ +

This is equivalent to --longlong. + +

Appendix C Runtime options

+ +

The following functions can be called during runtime (i.e. from your +tests) to control the behavior of CxxTest. They are reset to their +default values after each test is executed (more precisely, after +tearDown() is called). Consequently, if you set them in the +setUp() function, they will be valid for the entire test suite. + +

C.1 setAbortTestOnFail( bool )

+ +

This only works when you have exception handling. It can be used to +tell CxxTest to temporarily change its behavior. The default value of +the flag is false, true if you set --abort-on-fail, +or CXXTEST_DEFAULT_ABORT if you #define it. + +

C.2 setMaxDumpSize( unsigned )

+ +

This temporarily sets the maximum number of bytes to dump if +TS_ASSERT_SAME_DATA() fails. The default is 0, meaning +no limit, or CXXTEST_MAX_DUMP_SIZE if you #define it. + +

Appendix D Version history

+ +
    +
  • Version 3.10.0 (2004-11-20) +
      +
    • Added mock framework for global functions +
    • Added TS_ASSERT_THROWS_ASSERT and TS_ASSERT_THROWS_EQUALS +
    • Added CXXTEST_ENUM_TRAITS +
    • Improved support for STL classes (vector, map etc.) +
    • Added support for Digital Mars compiler +
    • Reduced root/part compilation time and binary size +
    • Support C++-style commenting of tests +
    +
  • Version 3.9.1 (2004-01-19) +
      +
    • Fixed small bug with runner exit code +
    • Embedded test suites are now deprecated +
    +
  • Version 3.9.0 (2004-01-17) +
      +
    • Added TS_TRACE +
    • Added --no-static-init +
    • CxxTest::setAbortTestOnFail() works even without --abort-on-fail +
    +
  • Version 3.8.5 (2004-01-08) +
      +
    • Added --no-eh +
    • Added CxxTest::setAbortTestOnFail() and CXXTEST_DEFAULT_ABORT +
    • Added CxxTest::setMaxDumpSize() +
    • Added StdioFilePrinter +
    +
  • Version 3.8.4 (2003-12-31) +
      +
    • Split distribution into cxxtest and cxxtest-selftest +
    • Added sample/msvc/FixFiles.bat +
    +
  • Version 3.8.3 (2003-12-24) +
      +
    • Added TS_ASSERT_PREDICATE +
    • Template files can now specify where to insert the preamble +
    • Added a sample Visual Studio workspace in sample/msvc +
    • Can compile in MSVC with warning level 4 +
    • Changed output format slightly +
    +
  • Version 3.8.1 (2003-12-21) +
      +
    • Fixed small bug when using multiple --part files. +
    • Fixed X11 GUI crash when there's no X server. +
    • Added GlobalFixture::setUpWorld()/tearDownWorld() +
    • Added leaveOnly(), activateAllTests() and sample/only.tpl +
    • Should now run without warnings on Sun compiler. +
    +
  • Version 3.8.0 (2003-12-13) +
      +
    • Fixed bug where Root.cpp needed exception handling +
    • Added TS_ASSERT_RELATION +
    • TSM_ macros now also tell you what went wrong +
    • Renamed Win32Gui::free() to avoid clashes +
    • Now compatible with more versions of Borland compiler +
    • Improved the documentation +
    +
  • Version 3.7.1 (2003-09-29) +
      +
    • Added --version +
    • Compiles with even more exotic g++ warnings +
    • Win32 Gui compiles with UNICODE +
    • Should compile on some more platforms (Sun Forte, HP aCC) +
    +
  • Version 3.7.0 (2003-09-20) +
      +
    • Added TS_ASSERT_LESS_THAN_EQUALS +
    • Minor cleanups +
    +
  • Version 3.6.1 (2003-09-15) +
      +
    • Improved QT GUI +
    • Improved portability some more +
    +
  • Version 3.6.0 (2003-09-04) +
      +
    • Added --longlong +
    • Some portability improvements +
    +
  • Version 3.5.1 (2003-09-03) +
      +
    • Major internal rewrite of macros +
    • Added TS_ASSERT_SAME_DATA +
    • Added --include option +
    • Added --part and --root to enable splitting the test runner +
    • Added global fixtures +
    • Enhanced Win32 GUI with timers, -keep and -title +
    • Now compiles with strict warnings +
    +
  • Version 3.1.1 (2003-08-27) +
      +
    • Fixed small bug in TS_ASSERT_THROWS_*() +
    +
  • Version 3.1.0 (2003-08-23) +
      +
    • Default ValueTraits now dumps value as hex bytes +
    • Fixed double invocation bug (e.g. TS_FAIL(functionWithSideEffects())) +
    • TS_ASSERT_THROWS*() are now "abort on fail"-friendly +
    • Win32 GUI now supports Windows 98 and doesn't need comctl32.lib +
    +
  • Version 3.0.1 (2003-08-07) +
      +
    • Added simple GUI for X11, Win32 and Qt +
    • Added TS_WARN() macro +
    • Removed --exit-code +
    • Improved samples +
    • Improved support for older (pre-std::) compilers +
    • Made a PDF version of the User's Guide +
    +
  • Version 2.8.4 (2003-07-21) +
      +
    • Now supports g++-3.3 +
    • Added --have-eh +
    • Fixed bug in numberToString() +
    +
  • Version 2.8.3 (2003-06-30) +
      +
    • Fixed bugs in cxxtestgen.pl +
    • Fixed warning for some compilers in ErrorPrinter/StdioPrinter +
    • Thanks Martin Jost for pointing out these problems! +
    +
  • Version 2.8.2 (2003-06-10) +
      +
    • Fixed bug when using CXXTEST_ABORT_TEST_ON_FAIL without standard library +
    • Added CXXTEST_USER_TRAITS +
    • Added --abort-on-fail +
    +
  • Version 2.8.1 (2003-01-16) +
      +
    • Fixed charToString() for negative chars +
    +
  • Version 2.8.0 (2003-01-13) +
      +
    • Added CXXTEST_ABORT_TEST_ON_FAIL for xUnit-like behaviour +
    • Added sample/winddk +
    • Improved ValueTraits +
    • Improved output formatter +
    • Started version history +
    +
  • Version 2.7.0 (2002-09-29) +
      +
    • Added embedded test suites +
    • Major internal improvements +
    + +
+ +

+ +

+

Table of Contents

+ +
+ + + + diff --git a/cxxtest/docs/index.html b/cxxtest/docs/index.html new file mode 100644 index 000000000..05ac5b3ba --- /dev/null +++ b/cxxtest/docs/index.html @@ -0,0 +1,56 @@ + +CxxTest +

Introduction

+ +

CxxTest is a JUnit/CppUnit/xUnit-like framework for C++. + +

Its advantages over existing alternatives are that it: +

    +
  • Doesn't require RTTI +
  • Doesn't require member template functions +
  • Doesn't require exception handling +
  • Doesn't require any external libraries (including memory management, + file/console I/O, graphics libraries) +
  • Is distributed entirely as a set of header files +
+ +

This makes it extremely portable and usable. + +

CxxTest is available under the GNU +Lesser General Public License. + +

See the user's guide for information. +It is also available as a PDF file. + +

The version history is available here. + +

Getting CxxTest

+You can always get the latest release from +here or +here. + +

There are several files you can download: +

    +
  • cxxtest-version-1.noarch.rpm +
  • cxxtest-version.tar.gz +
  • cxxtest-version.zip +
  • cxxtest-guide-version.pdf (the user's guide) +
+Note that, since CxxTest consists entirely of header files, +there is no distinction between source and binary distribution. + +

There are also files called cxxtest-selftest-*: these +are used (usually by me) to test the portability of CxxTest, so you +can probably do without them. + +

If you just can't wait for the next release, I sometimes upload betas +to here. + +

Getting started

+Get the sources and build the samples in the sample subdirectory. + +
+

+ SourceForge Logo + + diff --git a/cxxtest/docs/qt.png b/cxxtest/docs/qt.png new file mode 100644 index 0000000000000000000000000000000000000000..56a7a67478772098b321733e9ee36b737f13f40a GIT binary patch literal 13630 zcmYkjb8u$C);;`$6Wg5Fwmr$jwr$(CZQHh!iR~v&Cbo@l?tAaA>ig%^sZ;x`y?d{< zdv|qpN65>H!^7af0002^-x8vV005}zzxUrzp#Pp&G(MOBz)!$$Q6Xjb>`Nbk@RG@t z9XnCBY{bsJ?ff7FG+NFEW|~Iv>H*Y@OY0xvg8^hb^#hRi$>BbL?vS{i25@Z#kiB3^KYtwCEkAE<_?d2JaonGEE1Yk?on2Qb z9lOm`R9^GHoa}r*YJ&hmN*ST=Iv@;XIu5TlthyPH%nR3M={M7qSt(AcUmn@S^lhBM>Jvv zF1}N*ydyTv3+Tc00U?@5t&L|M>g|aRT>uBsIpgHoc5;;zB)6QZVmp)wHaeW}y-HLw z)m*YHIpSjGRCmd(rHZiBUOr#m4nc#8bhzA^ndOvT`%Nbw%^zc|XYvlwDJ zR~q;g(3Gn2l=lY@@<7hSHl0ezTV5K?q9uPq9+#;GJ!uoXt}YFM5nc)R@O$37XjyNO zZdIOEcx|Fr=(9!>Z)Q8jBQRf1Q=R8zH@4BWev_0RkkUr;T1lMFV#X+EhB zfaxd4CK}M`>P%E2p481a5i2sZ7<+t}`0|v)`(^ds)=t_G8wg@Jf1wP*sA8`}i>{(& z!D$^qGpwJlTV!fH&3%GnEu!3u&9US{qKx`J*Y|@nA(y=}tQ}x+b|ts`LVj7CGUNp@ z^^WHA*L0kWqGFqOR2$i^On<*}CgC6# z`=?9m5dbnQsoeQ$ZJOzP9mS02Q}<~pvnMqyLD?UgxY3)?i>RC{qoj`pG@h3_<$~pjP&{8NRq6MtkRtnF5q)dPSXZMZb(41 zm@KW>VCPnqzJk*aWd1rTszF%3ZE7D4v_L#k3DvQXVh~3T`9zE&ZPa&RalZ9TqR7HQ>3z%30-j0B)k2y7wEbRyVK?x|D>@8IF>EA zbHM(AebY@Uzz{TGU|8&qf|td@3{+*5QKJ7>QE8%IiNYmCP=$XMnbCO2A5g80ED9Mw z(yft_&Fshg7fQO2f(Jy}@DHQL2gy)u9t?UcP3^t-7~Jgpb48AFC0FDW>kUtE+LsCk zb&yuH3z_oxueV*i59wn^;dV->`V+&yPIqUv9pYFcGA!5lE3M8=U}cHYOGMh%A453# z;V#!Al3`dbiNa_t$_2yHLqv4@+&$2v9t5EBKqK3u=8B0>nk!Jpv==VQ z2o4q3nM|5ZjvmkU$+Q2URR-F&iCP7eNo56(8yQlEObs0elHbaMuAYi41FA*FNlnQV zImMW%YhYqT(P~T}9Z?OBfhER6R#{NY2@j!F3|CloKW}lBD zu|o2ou(|8nEFY_937G|Ti5H$l=)KGSh>k%EeaZ%vywMPkfr{FzlxY>n>xU6PAI{U z*QO9Kz|2vt2Dt)6nqj9|tPBaGFEj$y1Y43d5@7H4DkEOv6`aXMKhOp96&60vVBLRlk;q&u75N4zu9Ok=__X zq_4AfJ27E@LX!>J)d$8%pRC~$@*+e)XqruISW1TWEUX|?W z)Q;!b2&ra&#hK`IS@o|Dh4b>3uvG+~kaVYjw0%REG?!KykL=WAkx8ztBelY6$FrNP{Fmo%mQH)y`F{@MN=2vtceD06O-1G#%u2A zmiv_*9`{iJ8;hgK%-TKfpt~0j4jV{b{gB(Xjb;fWlg35&;en@Y)IaZu@Py%Lxw^i( zFy&N_O}ySXXN^(?HEEG5jJtejeaje-j{TkW+q&kgaa1+lEM-k~)$U|%D9(CqJnIY zS{-5&U}*0)@MJ;I%LOz!$n(h_4LxZrQ%89+mn8YpuV7M0DxdRzuww}#wz9IvOE`wm z2lFOL44+37KZeo(E>TQHj_phlbg3Cj*Ku_fRkcpa0$7%rD|Be)Fm4bOu(jnQxyNRJ z(j;-559CMK3te5%wOn4~=U@JI>h^X9YF7ntF3GekzjPzVW@J{Vfb>tVH&nMF)Rio> ze>VPwNrbBiTsJOfK{+yX$?^@t*Bx)1sbM8>V%WW?>!VGZ#*~mX=lIRVDQIKQncoWLl!1Wz~r0 z#f%psp|FFg2te6q&Sk0%xE^Ylwn8mkO^;0~8^$3}?5dHiQ zG5j{Sl4G(>XNQ9{geOjnsA;&!p(>dq_b$(HAZAlcR6-|5Uw85$O_uZhy=B(|Gf&PZ;n zHTiO5@=k5^8`qsLB3B0+sCrm(LnQfd@N;C+G8h#}s}IvbAg0nJ`9l&tDd?idPBhe{ zUvgfj40yP-%}xa_Inm+jkJlE@$P%&)ZgKJWba#0=y1wZ+%mB1?d>Z+DE+A18-H1zO zW(f3jLfS|(wqnltt>yYAL#7=(E(nbcE)@C9%;FS?sQ%R=j{`K~c(`qB;5ONvq{Dt4O&MhCPZ|2Ve|Z^I z=wa*1u&rw?H@C=vDM8%L)iHOLQX`F^Kz1@_2JUjvzqVqF zg++S5ISiAug)T0J^KKfdY#NX4bxI%Fr4o#^%ij^k^cO^${Ua?D5Q3NQ1m4mp(O?4| z+JWME=qZu4UadmK`L(gS)3&mqq+Q$a7AqG*f@)%Yk9;5tPw`GYd4+*5IAmq)Oq~0g z4nm`d;q2a_T?PK-mB0zNSQ=}uNi<}DH-|S{j~}ew>($!pPM-f{DVG<91sQM?1LwYd z1_VCO_P+YOzW=y;&DvRp%DQGWvD^}Jx**2Fg^Sc^7NOja*T^ToWhzSJQF%p+`1*VH zIvq?Ei%KIkkdembS99+z1>Ui4b$;3r+FDk7-&VD5u*BnfK;4{4$- zZCfZXwUyuPB&HdMw5?>BfyPqun7x`Y^=7P^3B0@Fu&3~IXVl%E9s@LHf+#b~ z8d2E?N3;&_lrGkgM_X4YFjcN3`G#J1WACTS#2(gn45ax0d5%~s-Ab0#=wJSkS9l9o z)Z2IE^AC)2ltEe$}|oMJ3q1a4ph|UBZuUsH|^s(Oc!V_@&t5xtm@M ztZ;KqWi0!iJ#NXT-4Ac2O(8*4fp}h8-K-9799p z3Vn@=qKy;n~|F!r(;BAMNGW{+tj?L0~kyEmf!?W zOc*G&I4O)p_VwL&Cx0!ES57iazQo%5#Hqk~MdSb~STNA#SV6QX6&zv|LsYfUYiU(& z0|bY0+@V-YqS3vlLo9r;>G5Vu{Hvx#r`jVi^mgE0cnhD;rj|txL*f-LIGNhNZj0xu zTnxl&by8&a*<7oipRU5h+*rK7fGY_twBs-P*KAwMjyD#almo@c+!&UCiLZ*33o0u} znAZQAs8rOvi?+nx`Gbf!$86jf<@tI@WD*!z9XT zzbl~G9doFboA^A2OMn%>FVdBei`M2csD54hv~SuHTI6WhW=;Zy2$+#=t^(*|1T$4r z%6tP?duU`MkX?m~%)r{Ds}78&v?VY@+U3!ZN*2u1x>Xe92_TM%DDU?JVZi3B@_k!} z;{1|wW)sWqmY**vXQUlu0^D-QnZae!)QMH=Mw=8!aw0Ex&~c%rIF*tgGbZ3eu(z=A zG~f>G4k@F$KSS8+#wYjqi`P>DsmW~d zw)2+f|CWLkksTf?F^_dr%R-u8yZK_2(p+DVJw!$#V^rg5GD2IN?a2t~{RrTpix#aO zYv7I3Mn{PRyI{sanx=r8qMO)F*SFuPsW}D+5f0OZKM!QUQ5O?fG~;3bKQiPi>CV?XFo1Jtv(35~c`3!g6|utc;^ zDKzxU$`|v%BEolbu_?pdUw}`WEK<%)m=8BatW^HaEnV>sO_y9vVT24*P0IBbm6kng zUm{5zIH=s3)7nRu<6INn8#m1T7Sz zXbf!>ajpyu6~Z55m*XTtiybvFm_}tSWgTcLP|`CiVdL_PlR)7c{pH3x=a!1K-$;C2 zR;jf+vG?4|Qc32;F9g#(XZw+uW4g}z;V8#s$Yq~7hLio%t@ zU0r?BbEMPAoGs6rCdbqAdW~g&ZDUa7%TWU~gAnW!jZmNKS$;;dl&TzQ62+bb);>qP z&Z4x>?2_-r^%I-VTFJ$R4>C4O4GwTvH!fz(&f%Z%E|G?Z^zMID-zD!mgonls1{VtH znnLjXeavQpj_{(vmh8_rW@`C3Tr%zJyR5>?lk;|e#+`Teu51e;Y#T?zj^N1zSYx?bR%eegil9 z5HaJTVkJfY@oMq%=-A?iVW^+6Ucq`542Ge6HJcgwM_HWWsTL3pxy5%DV5|n`ih+FQ zI~{9Jc~Z|(%B~UI+fM=F8{GA?pXzaz`&Sj^mc*}s(GyDJ4G^|*ODCO$Vl^F(xJ5?q zXL@mxEej6RI-sdMyT^SqZ)QpKtO|>B&13khOqjv)H`(*oaFR9bD^izA8~fkUW9+@ zzV0r_!A{XT#QtIhm8(d^CT%0x@r=I83)=gpzkp5O|aDpl2Xv~D+*uWoT zil_@B_?Z{Kig`SWJ=STEw(mg$qt)8cjsk}h9-Ix!-FX^m$cuqwjTr-`Ocm*8DH=!X zchtPrk11{p^tG;X<@=IxI7d_nC9~lwk|AykxnsT+m&H$7$fgz+7UJY}-qWDLx`En7 zTTxLn_plSD4E;}rHSWp1rGfWP2Y9FH5u`_NZe3CTdY{R9Pj@_ijk9XtlnqsV3df$wc>FN%TlE zbqBLWWw{$7qzF5aHRANh|2Xb9QZr?wYw=9s zfws95JXfi66OvGU7rX0aD_RHRgU5me~$EQLViN=#92aj|qf~9JOd* z!^nT zW?>m>Rt~AJTk`|!(}F(_q90xM(e-n#!s;3!&k;4?PeDtjqH)`ejLS)BN|7dI6}WHs z#~gfubM#N%?q4dPQM0gNbPh&`^Zb!WIqXEHC4UctNI;}=V^J(s4-j}?w)@^D<^1lJ zK;w2LyS6BP;4GhSgg|+Jy3Ka*esA}^OqL0}vWk+nR@9_%$(w@U(RW&1)Y(BDu#ECr z*uY|QMJ@JfCUtZ=o#MWD_{}_%;;B|3_Zrq%)CUr+>KMF(8H3usdW#mbCL|3%}g1kgA5@1p_sXEy6&A6!nYY0<^dF{3b zQl%R5BS*Ft&L}NzMbtymM=I88e~x?SLu?2k(y&AtN1@LMYD{h4J9^o7AeY&oH7wH? zWT*G&*|bp_+j>^?z+V3PJyHB)z+ytE&+n54usGk=>C^N2Xh*u0#P>a#9w4K!q6M4V;AT>GA6zFLEO;eJL)zp@u$ z$S7xbkh=cKSZ6PL|mjGf5fc8vg*ZRBC%S0kDt%VTP3O6Qlpm z6|7~E5yZ>Q#*t?gh+C9$MTtJdwSyf#Q?BoeVy-qnEb9em2#%FzS=NdQpA)g?^c6lD zgK6C?@1$EAc#myh=)A#{uk(nPiobT#XC9J3GJ|;vN8aJ?8cIoXM2sVp;Kr}bU}O0T zx4#@|lawnj=d$R_+KD_ONu*D1uIV~BGCQcdNK``|tMkhSMteZzN0N~4x>ph|Y=y>S z*L0WB`u;#~AjDnjy9(_De?5)7nDdO>l7U;BywY*^+Kl}}tq3GNN$5 zb7UrodxoW`ecW7kerMTa(r2heu~F;p#BaH8N%7uTdyZkfFYStc;ce2& zUF*UO;!-BjQ*7$WHjC~gO*L!L#zBr(+0?U*dfzet2=aR5Ue0*`)5Gh|{`n3#L!5-- z7)+d`Aw^ARtA~>qVngkZ6E?G7>}!%-z15w(UDdEE33i%;&ZH}9KWGZV$fQ*B`03<8 z6<>TGm4)}!&+-W%db#dW z{k-}J59wU)GOUrD+L5bTXnJlJnt_dJDXh1PUQu{NQ&7@N;dB-LlJA;|A81YpA-qVU zII*2_jSfnF7CN_aYTzj;I^N#QUrhKG&My^8n&hC_^@Hg9j7A5Zp9fTRIyXE%4*fb+ zu(76SW`#Vjv zwQGq9$;$V}vPFS0EqUYwwe>k*@mLh_<8VVj7{LCCm)VlrX z86!w%GY|vk8yrKq{&_p3j)Y#68UR3h{m)r|)2eYp^hB9Z)b=qi4GyIo(Qzl-FqUbg zw73v8G5~`+KK-|&h9#iPf6!Qv(|EkKF{Esz7LoHZn+gMk7*Su=fLVV}SBHXoD=Y-j zjQUrB$scFB_Yw_QP_i9`EMmU$>HL)AyuUME){Fa+EgyH5zFr6WDq4vJ0i7AJlwJOe z6zDA3E{TiiJuQVPYi8}@pgKASz9P>X!StloLIO?gKp#w&WoUg_qMzmCcDRlQH{^Cq zGV11pR@D1#m0Q=*D%0$JTvN4QN}#@dq<;mmm{3^$C?A1Y)fmY*7Z5*PcEa->S8m;C zy;&kC;~+EjslF$~59!7I_TAJgdDCnI`;;-AgaFMMfD70wFHzleYolVfIk&q82c7cP zA{`}NM!dnn!+{@)FHAOMt`UJPo2>y0yQrnhVYlro<>gFwr_dKsWQK23I$;(7&5p5{ z+{{ig2EjtmI2d0iKB!yDbu`~m$o~4ZIBxM5TvL}68>0r%41^#SE32@GA((tkelDDn zHaOlF5xsQeZ)bpIhkG4_%Gk9qt~&cB`II)r@>x3CeP-H?J0B`0$Y2H_mayGcwX)ZY zdXEgfp4j{g9rN>Mm+*5a?(4{pw*fj=UhwT`2)ZzbM<`+zbwc{1?>k^gpG`RC%6V&= zWJct>ogjOe75qfq1D>ELeI#kUGGcr}LmT&1{o6uI}gh%pL;}Rg$o~8}GlSC`(B!JP@_BOZ*2^ggJhX+Nd%bKH$&? zZi9Xc?z6mP#nR5Vm*2yOn_Q3ptdU!T1kdT^odMCWI~6v3cQ%oI&|4LGcIsLhS#R%?a*1o3!@UTb6?ZDgeDanZ z^aui)Xl=6n@z$+d0y?#aS+RHJkR%~ z9WRk{x_lj2QcdC8`p#j0+*<@_F1DJ49ilY4o+(ph2xqzpnF+j~qGk^k4`B;fsWkv7|Vq8gg^-w{D>MgBhsp|-;R#cDoR zLn%Au`%y;NH{|>OXmEfT`#@or{a;d_(|+l@{x@Bn=oM)mulJK~8*xI{!3Uc2>7PPD zz2vN^ywT9lMNm_*QW<(26RYVX7l=3y1B>c+?tjm-NEmtkFQfl||6wP4g#5{f93n?O zeij$9Ej?SRSCV%mgNqPbKp@;(M=Y5Qu7z7(kcRjDO6@i&vdL6VO<-jP+J- z*O|QEAQFDP%=*&i?F=wv(E1f#du`T;;rHLZEO(FDo~aU!O9Vr+yTAFa zPF2Qw;2*vce=fkZx^!=V)fK0>{uvnd!GN(ZYK?VxAq^Yoykqy^q!JHEz>TOfsG4+ zL-?8Z7DuBmulB6#$&p8`f{nO08Fn8Bs(M*9A(2_Obp5u~ zm(^krb`RseFGlyx`Qr_=zdr7Q{0?`+0xazkKH%28xZgQ)rwRUvq4e2jybpc-ITkqN z4jnb^yUQ?z3)1s{;&)EBjYxB+u={>xK9yw(7P`iaF~9s*(c9U!acN`mryE&>Sf5|d zeSWJt?uaLRIiE}&L6BQ<+lyr1VslM;{7&+l&%o1x`nmtq4wP#)3ZpB zxxgRbuQ1T&B^q*3B%o>PyFn%1f6jq@`YtGLr=I)ZcSzp^Eev8wF9s+Fqy(_S>f~}{ z?uah)Cub>ckMbpz&Vn-*WM!(n&6S~C?^*jsC_y9rcJkPN^Q?AHE2DBBMJwx)F7e3F zL5C=BOD#5}Vk>jU{W1J+V^+)&nAq8S;j?4*_pb5JVEM4Vp}hqSMd9G?P}8Ko;i)l5 zy5LVcu{XSBlz!!is85LY)-5oHMU}sTCd!6}iQATBE0P3`8ub!o(a_9_6{8c05*so& z0}##Z)mF#nQt1=W{onu=YEwYEJS{{z6UaTO-WqPEeKa)7TGUh$S{=YeM^diE(N2n+ zQ7+x|-(kd~>?FqJRwHA4qp5{^V(e0lUkaw(gVjda@{B3i(H)>c(| zQkQ2+#1hkYdb&mQZas;qu{7!B*XcRw{EH!oN}) zYNl_`99@8q5zf(YwHk#tvXI9~mrW`I5C<2woVh4P;ZCyvnmX=)p_G~QVPzvnsJYCO zDtd_*&2;KLETumeB#ulI>L(B)<_pTERh7Sih)J2Fr4`bYU8m@m#b9mO69{_m719#p zv1ZJ{bc9A(4z_k=Rg8;<1x1*+tzronQg40G<(`x%NGY{gjlV+4#x#ULmHO@Drq@b7JiQJ1vRGz_5@$%rxkv z?X{C3G6{Vi&JPzn??{T-FD;V`kSla!~)X;ia$=K<~mOquvmONC=8_-A(1Z`J&via&g3tq>MmgqP*0vdQSG;&A7dsV!=oQ|BA`v&>T98SO7=v*_wE+d%G7$S4hvWE9Uf>|zUb$JAeF5G1@_s}-JN4}`1f`OG*!2V4!2UBR| z^8S;ZLmh|ZQYpWZW{h-l?;kUf3sqVz8MShBk`VodrJQp=jbjbhn_1oeB1uZEg&b?G zK!Gpz(^}p=2rU)14Cty)iI#J9k$()ZBbYssuxT^@adMM~1K*AnrB#mND$D)hv{~C!>bAAg(*KQw#W5xH}%J!};6dYp>!N*sI zv{(gBAhlYiP6k{y2Zht9=W+5v&PEJkc;#c;Xo2lPU0&D381PMj(9*`Us?Couq2mA@ zbZ&wVG3-@4N#N5(uzr?UvMQT^U=u5m{4q>ki{M@hVx!H?wmO_;HBoM~L8u6pt^t^u zV4sLom=>DnN=eTZl0qOsFN|$lzJ47eR; zZG%I!0Ny~`=?0PfA@}){Ve6ULtkL)$mu^aB=tM+DZD8nG;}kqDr-Kwrx+OrXVC`(}grT9e!UM#{w^VqjJ7? zq!X$^(#Fent=_kmI;+=Fo^-CQo&B0kB0(uKnNT8!;x#R`QN|rRi;rd+#a0dqblG92 zBDejpneuCi_sJ>Do|REJjx*c-5=>_$owOPQ&^03}nVbc=_87613{oa}M+le-HkfwtC_UEmpMrxzZI?@AluieTZUj_GrL(%AEe$$3y^!Pzi zvHDqy@iH-xl}V@Z??9KKEdS*sD^>g)Arolp(iMu4?9y2m2Mn-ViOgx?tQK3a=&2Ye zzxjq>chFbp_Nj4iZlXC>knuz?FAA|pQuOSh0#HcwIX)*Vw0z<8T8p+0{=Jy!*AgOC zTN5g-tzwS3#6A@AAtSRvWU)EsdQy-nX5SS;`ER_D1{c1T~$cs=3q>H zw6VRd=K!fq&u@e|j9ofAk0CAD8E%R$6fR_C|G(@j^A}QWS>egba$uy}d33Q2@aRT{ zVJl9;%v?HGxUfrU@`dtgGxSl}0M1q+XiEZAHX(|@P(1uS_U_vgR4O&*&ipN@x!*hb zNo{ccjY0#E1mt&tM}BAk+;Y9a^4LRMG;3;kEHSuacrQU(2F6RlP$oTVD*clLL5|R7 z#Hnd-psnguowM)I=-NqnqC|UJfi$cWF*@y?1=x$C9X0yEFH`im#0hAu{p;!Ei}1MgjmEsrLX@k@9IF)Fd+>z! zN6Vomx}VwI8(kMw(X17W%kZdnXQ8m{_S3)iA8=hW1GclHZw1dGQQ1R`-hpZMt*bpp ze~q=wWYjkhFnM31zCSQ~NE(H6#EDhhy0Z2{KF-?uUSGlp{oWSK!uf(iJhC{f`4F<{ zWX8!07=Qk{!YB+Yi^s<#G;8&vi(Rs_TT|a0uc~=G`{HbQ2ahpGiLYCKYA24|5M78Q zDe-^|86cK+WmOw|m|k&)`4LiY+Ak4R-~`@Pq*puIq;(pZ-gu?OL$;SFuhZ6Pl=cBe z#heicFbCD;Nn5}!iFNsNz!}dR@@43#@e2m=VyYEBb^gz!DTlC57&~4vFg>k5p&c`~ z!v(fDoJN$%aZ4vX$->cCsC%YFzO7%%C8e0S{sgHy`Hiqbs(x%4S;1fm6w$UrOMUkI zmXb!1vGP`I^CQdytOhmdTqu#IlYHdyT-ku3{7S&aK5>S|cmbOgS@U`K*{?i$6_=3B*;hA^q9#EnADPF9G6Z_tGJL`QT@7UXO*Y%W1*kVup8=tyUVf)3s)?S zBX=bhoCAhM#n#l9C1N0ciO((;s}4g85`KcweRA}kolr9wZn>K+_vo*OX9|0(WBXuB z&zl_q@$xqB_kSi`%$DICfMdXUbtx;q@hbp}m?H3%bBIGnh(ny^ z=#OcR>aCz+6{hiikN{L#BIa8m&o+nY%(Mn~Ks)2UHr6gb)Gh6#Y=1|J8_TycB|ZgD z)|268yS>5R9=o20>5nB#?^~E3Z~$MZkYTL%7ARN%k_tJNA19L^05DDj1`gp%`~;5# zo)1fbL|Mpq%K#>?j~LhwvD+;stcS?&|HoBwpE`1ZFRsD!t}C7YKJ}U6DBmM=fe)L= zqp_V0Ag3n-;S0ve#1E4V0Yw^pOXJsE9MzqEs`JP(^1ED{n5Ql|K*qlUSA0`xt$JTu z02rw}1jk|u^1Lrlj06mU%0F!& zJrD~fG|e{|M!?=zSb96z7r>wx0d}!0h!ftl3B$9Z8Iw3wFSSgP6XWxTavF&w52y!A z4K67x55;POh0KL;fNW|?dEM^!2MK30G#W4d0hneN8d5@9mH3$g4?BN0c`X zoL9^=a%L?NhJ4f&6MY#&!QuR;!Vhq}QJl?Nosza~38_t0ok_HeP9ry1B8hQEui@2OcJuDnh%GWW)b^%SBH24g)NH={fDk+)5DWrkbO%J9l*xpkNF*<0 z%uF=5hz9u--KcF?V6aeNEs?8;{y>ohObw)S8+d1$1NWLS`L(S=&V@XF&tSKIte~pT zPdO{6j|LN`IbQ^JZ23)s5H|?yud`SXg%B!nf@oo1MbIQF&bBj2Huj4sgoDH*)x8<5 zU|6KPL#e8dy#!4`$dH2i7p%z|fi9_$_le*M>A$R(=-#LaW5CAOAs|_D>J8NIB#HJX zwXA;=Bax5$^2{0O=Q=rzLh0vy?QGux6;;b`FN();LYbrJAN^qj8|X)%g0e;drV#)3x*>(|k*0HGafdCpB}T5XFJ`KC3*=r>bK#) z4Bt_{`p=W*P8sinr4)kjrAz0H>=op2P>g=V)1Xy0zZ|7_8{;*{P75 z+AEz+{}m;Es(F(J9zE}*(#BiVHaVeSkuBDI?3?QWJkb!r;D%W=t!WkrY-Gf7?`+oi zaYe5@=LAfvW zct3d`;8Xi+kcjV&djP4zOvOlSp+Rfh857TP)v5W!SH9_h#zI!nUv}latko<2R1-Fr=u%J9!a> zx7m?LU|7LX*$;a3%zP83q$Ot2nIBh*!>MZIGmhZsIirBP)4h3W<|&DOw8VFd;Job1 zwWEOKp@ zAhwTslp5ric^!TcjB?1;D0Qwk;bttuoQRDS^g*LC+A*q1LC0X1m*|O>@Rxw4!}J_j zm;11?$irCp>Z;Rx{AJP`~j?IN)_pir_3aFP`Wvl~})v3A?E|w3(5+bzZ zqt=bvqU#1v^OHoky;8?>jLXs@&MLuDdJTO;cswD8F-@3*R_qyFz9ac*QheFmfhZ^E zUBp>L59i;`C$lqp7)`Lz&IyM2UEqD$LHN3{WbEi5bx{6b)T4Gl^XwS~DV@pJ;)38&&*SwtX986SwX#~_-l)w?jZnXE zy%2Mwug&Vh`RE79ohVPHx&zFz0Ao8O@+ z#x>CeF(3oNR)n$Q5^lm(e7nnmSR5n^VY8F-zWE4N*w-?ae=coMFEC~>CkfILLCpmj z4z>=Su0H;Tqywv4C!RS6#dp*JOHeQ<8fu0E0}(S&Dw*(76ywI6%zo<7N({jxr?V9@ z7|lVc?V)sJgK3uE;}%FqB@*ZkVrc&s@TAObc&c5(Gk#4DUqQXc!rjj7`fb-;j_Rv9 zj27AYRZ=c>da`bLgu)20K3hM zfwyA76F8{)Ni_nGal+7Agjft1+6f{^VT$it;(r^w4Wm+-)4rqDsEkF1_KoNHSZ?u) z`Xi{NjdQr4_VW)1PIYCac*jzktNvwkckmBvbyvrU$jm4hu8;8ahLs+sO2VUXDH`8p zfgD_PqQ5%GUGWvzJrxA+;zsL@%km%U;%>j6?98v~aJYO-LRm0rnDoR)0$kp?^lzo= z__*92%?UZRc)Jzf`MAS;wtgk>`rcujiS1{S{q|2KH9VBWpm>hLNrEq2w;;;Z^+-Tz zVSfBcc^7_$dqojP6TW2PtX*DvIh^hg33D`$iy8#NXJ8B$;27Y@YF zmVqvAcTN!!he=SVc~l*qu-w>k=*5NbTR!1?O)o$l}w3E_;a5Jt@zZbv#=8Y3yF=!IeaI3zlD3) z#+y=%MhZ<9&Khw@!R$;HyTgW;TIGDX`FPZ0_;H{HM@e$oGjTQZcKlA~urc3FVv^nW zg6eyJe)v8yGZRoE9^~pILPc(y#@L$hvVYkl+|j4CqXb?1B|*&$N6t=xyP0jVhy`i> zCnRGB-wep+AYjd4to@V~-nS=DbMN>KRvo+Lbo>61|GJK2(3hcm#sf&Ppmd3hp!xY!EG=*BrrhQVTb@ z#pzLND3bd(4$j8khztha55bVH@_WiUXGc3RmwOF_Iyd^)Y+XBq3H}Pl1n1&lfx)R8 zOD;K8hL(flp=zE!%Xk3PfCR8O`BYA4ar|yXozYN4~3nG3Jp)Y%hF36 zYAbrA<9KPYBEi5wQOai9H(AWmF5O0JZ4G@88|?(`>jCf>WE|NV3-4tMO+=dyxH{NMMER30rY#(O#6%I zAf9EMB{y_;GD`p>^c1$kB_1~=lquqP%3(IhbrPaOc-#6X73t(okQ-vyc8l<9k3%7r z8)D?Rpa(MRuSQD01NCi?$T(Xy!X5 z-%1X0AX9xU^;Qwn_39~8^bO2?m4eeNeW!B79D0rYaF#WQGs<&&xgGnWO{5U!sZCP8 z!a;;?U~9s3tdK&K{57V7VbM#`<^r*7EaUNUl-KbwPHGrQq)HZh%PXjH8lHWzka z|7N>5iYuwQj;)b{`ua0snJm*NbEep!a6BH4rB>(y!P#JjH%up;u3ZByRR6m><3<-~ z)yKy1Ru2r$Mh$@g-EoIieC+sr*bz0~Gu=mbsq05pFUi~W0D*5hH8b@j9vI zRmA?o+TJQQr=0$n(K7f_Ih?G@NpXtu7kawrL&`Zd9v}% zN}Qp9NYvbca7;=CzdF73UtfmS89X`wHm#dOEZ# z)psm_>e&wO7CiF;97}L~>S=fI>cnPDw=RP_t0xrv0 zx8`wGYE*7kDko#P3~l?6Lrwl5v2rXiGqG@3ACUD!=o$aXL#R$x!*YbWe@!Mrl!h2G zggZqY>aP3`vhVBVL1#j1ZDTNL z>fbO;WGXRU*Yi$fG9yPf7vd|Np;r6jo9XD}t*{zIlm<~mjLm$6)v<W< zzHtv7-D7p{lis)x)2AxsSK`t_cR#*yaZ_e~!v$`G7%62@lMfB8@xrSTJ6MOQ?qZ`^ z0jYIGM%P-qKAm53Ad!B4sQ?-WZ7QPEyv?O*9whZUIXu7}jH_oOiq$koT8-8n^4G6g zw!rr_iuGem-ax$m3N31QnKNhkcoxBb*tZ0Zb6-X9IKje~Y^X1MWs~Iop z*PsnQr2B!Od|O~^X%wt$UWKJiO_nzd&h2%FwtP*xGtX}yL_Rhr*yoH^Y-6onCb#by$3rdy z7If)jv}hTQMF-Xw`7(SfA74J0nStksGwIk;4k#2i9fTc4m+59hrQaUmqj8AtDcVp~ zqV=1ML^KUDafYzzgig`4Y3jP6f5%In#ZAx|S%oGIZ3}Ept;{fwwqM zQN?$s$Q$dPTgxU7iWSI7DQHgWz9u?Oo|X$^(TnOK7W}Y6vV1a+)h3?iXY2=x2wP4s zPnmku$G2EvTc!gwXeSK6Ib3P?>$2nOM?a<-BJu|?cfXvCnb^F)aO~;U3mLvWaYW}1 zck~B!J-&t)`FK8mc20eqyS+*p?&cz!e@sf{tV!V>Uh*hHVAA7ws=!Bs7@b1(5VfQ% z3DTr<{0w$~;8WPeijn>jpJ=Aioa;Z;zpEh%e;Kd=kEY7Cx>nYX&st(F)m$XW5tm~? zI4Mwn3G%b-@SZK*r*~7iXQUNu@DwEq34YnH>P-UtwndJ3N|Qzy+jtupI8b5J`J2qW4wWaRGX zQ68?VFc~jui|tN_cyy)DY)8a5bg>0$<{{|d`vFE0wb_-&`Z}}0&eV3YLjqIYomGQ#f5@UoZNu^XaXg$Wx#!XAJ1?=+_}Aa+vyd89~jk?ZuM!uGWXOMwVzc7SSjV*DqR^)Vp-avzfr49m+_ zbnP;ZD--m-J^2{Gh4aQfa#d*GyMIVHO1GD_4rF|K(!QIGwF(iFgVNuq8xn7lv<-{* zMO%5#>y<=>4pBgBl5)sSx{l-kkCLy-!9QmHlE5hbZz3+4VFJ5v`6|rfgHH^B4NwC^xu!_+>ay z{ZWz%5w2At3VJlh$NlK3xazEQWBY`S$^P%|MuXWUVi#vkp~Q$aYxbMmX&zL#_#%$l zqJ$}+AFWKIvNM6;86N)bn$5aj-T49rEVn0PjMK-!PZGfB0RDiC08%$}(_lws%4SwF z@83taRl6XL;CPcf(Ei4*ZC9yJHp=!8Cci^DB^=+dOR3v~Galq$OP^8giXina&O;qY z+8r;M_-2G<=|+gHk8>rXs5=LL`zEC5CIboY8Vuw=t^L-rqqD-jh~R;sn@IPQRxM}5 zRlf-vKg%z_53}(Vk}ME6{hHOEOS!1vOkL%elj=41%?}jSHzYHzB@7_LhAGc(Ydq~m z(yHNXc_$&=i{Vm(h_wvEFk|t1$cu7dvTN+zV8b0R6rsG-uR9%{AJEP94kcy z2^~zzVs0K`5}q6zdk5=>h+UGJI%14Zs?5dxY&B_D`%YLc9I}`74&VLhP|UYt*vAFx z=J)<`*=H!@n*_ZPD0YW>1AmFbsaj{4-#objDGHbMT6$^Q8eUVHY*t8LrKq@4!^jYP zI>?6PSB~AIZ%W04T%NXhpkB2~Ww5aYHoT_Dep*IB_D&7X9-;siJb3j`Nuvkv_b+9T zf7Z})tumiVp{Fx?a-y`0L62ow&un{Wcar!Ey*rzPY8zsHq#T!NE zgT*6D$)eli?A=R8+bV)0ae{(diGN-ax&09 z7B+?k{6Pr>!kc`ofr6p9SRYW%Isgg~lrD#-797l~@XON?CmR|Je3%T{?gA!d_U|ie z-PuOgmI$vb=aSqo!7T*Gxtg@cj^#bwpE?~5`g67JuPcnU*p{r&a2b~d#>|ldaAT!B zJPtLtLWzX9X_Sp;x;JhLg=M?SKcSh7Wfo*N{?tj?FB0tM(4DKgTXfe6vzsZ;VjYty zxfxosi+i~q^mUK@+}z+wGYKEX5ED@4n%y zU|4)l(0v&i+48<(kR5XnHWJ4@?pm2*R5`Uv{u?c@IlThH3;%A@W~<|%(xcU0T8P?~8T|rrP{s_jXilqceZ=3~Cf%?2Ovq3aE`hg&b z@9wP*uksX+g4Pm^EEd++sURqWTMIGEe-?1J%$m_6{mPeI20iEPw=JV%_J^{WnO2{X z1oRf2Kw-ZO1%C!)aonSllqvh0|EC*plgHfgq@D(_Gp9c5m8q=0;dFu9GTvFflsScU zk4XJ$UL#hl(+MQiv9FjpP-+h}`Go%UI`P$L^&P^V6VV$$Fr)SFmUbE`BjM};4pCQV*cX>T#=$;aJs(-4;RghunRLRXIY z7ONR=JS#4hd2Z`=lfThJ#PXR7fS~(NE1gBwyLgm8#L7nH=~&lsgdEh1?SRC>Y9zbGzP zzs0Ai%V1atsK(^721&*>v4kVL-LE!vy$!}fDJ%U8%ZR1U_vh0aYax+;FhJgyW~1}8 z_3^s3)|k<-KB*75JR4(EEJyzjk(60{z-frrn~ThAT@%?X-nr$=9ZHM$PP2c17a4dQ z+Pi0Pe%ACqFSojuI^B9*>H=jI{zps;%JXhPwF7UqZb6^Q;S}v8yf1Fc%Xw3}_#bc@ zJxc7^q?>%B`4{vIubxe#h5wOV6O7_1npa}4`1i|YDDOl%q;F{||49G|YUJ?)SN*?E z`yYAfAl;Sv+<%~tYpY+|m8tOmtKW{Up6%a#J|%tHIeDn^zF&LS*)QAb(s;+Cm(xjj z9k~9a$N=%&be~M~Ngy3A9WjZyz(k^kVDJ9RZKVoLMKLFft^cdK`VZ|OC3(9>wf(Nm zg^Cip?A5TaFihYEK^#_Ssf~ubT_F}xyN<8RDf8!mCg4v(N63M#UrKU!@$AAX4V|RE z(M*EF%YjGM;*{j(?nc}l|mBR_?71rqrh2%`QwPS17(6-)Wh=TxxaJDoBA z-Z!OK@NwQl@#a{ua5soyiN!VjC8^6 zpORn{*jPu7H$l~5c}0Z_AjhVtMCns0je3*l`=T|>~xB=mW zCjXQFPgEcUyq4I8l~f9r{%7wm(!0qa-A?EV|M_TQNN8$zy06mzw<#Ay@L!G!OAYyd zP=k*`;`@*E|9}%VRT$9x!~H*>Y7`cPr!Bfu`9Dv&#x$e?QoWO`sp@*&ovnZxj?lXk zY%*Nn{`Ei^bO@gOBvk6ONFQ$AC5r#~Ff${`{$sEnB^>YDQqke+|5zUL`(~pxGv5y6 z4?X=qF^D^jDYIVPWABst)yuHeSrE=~#XtrzH>nn+3!o0I~6$cag^b>8TswN9Lx$-tqia zrrPCmw{PX1P_z6isa}=AtnOQ5u;-QH$C1V9ZJF{WJ%dj4Wjc=<)m@;4dzJUciAmSn zS>2ZRJ<9DcT<>b8`dOdkYFSeK3c98cZ@uU3T!nLUuZ|y$O%kGDZV^4`5K=<0_^3*7 z6|X?53opaIb=feQ;eH4E;Y4GiL4-#cO9wywdz5>Ia+r>FJNF3*Q-J9t%v$X+Xf;5R z(2G7R-%`8^I7ttV-{5*|>F&f-dUkx?dR5B>-Ept`yyHc|Nyk@oCX59d7?H7S*dqzN*ma1yiT5WzR@S}E{ry^-5sq9}@#nhPr2{6*wQWtF z)%#H~6OLZV0FOa`8lNLk(GJ^gy^5QWENQmK&F?Tfu3Yf@o{JirxWm2nO8DagFLxx% z0cLo|^pZN-oMOoh*#zfKUQ?yX@%V&DIFrhCaWfGoOOX+3)h(Ix$1&+~mciP!VNab4 z^sfMT@C|o*>5YAsEcN6i)d}rr*E3M9>%}GvV+0O!`WpgxwPYEp@UVLNIG`i~7y(%++sJWgGAEWGxaacLR}_co+2u-#ayr zp8PcF0|Ozh>nn2)5+9xj7iQ}>t%@&Y!s0gy7DtP^84cJO8I+h>9WB5sxvoo^{3Z+h-u$J+@p9=| z2izJpvEr9bLKj+^tPp*Lv+_;ifd@JGv;IwCCK)%I=Y@Fs%%=uVk15?qd#b4yE%to_ zEhm7uiFnECSc%cn!lrT7>)&IUqza1kCka(8-Bnc)%C7Hqc)+s^`q)+R;56lqt4&&h zuDoD*t--*>vi;r)%kBWhA>5ws zeFqG6SfVFC6O`?>ED9c)l_&q`PtHOk^wX${&)Rt%(e>tlH{4aT`Y(O6UH_FRtGi&P zx#YHPvI9AuWkqm!)bO)8b3)`uZGw|H(#XX+Qd*E=$m(UQU>Qitnw#|MCLj~xvFt=46hsG)v-L$ z#tOE=YjM%t4V@jW&cSZm7RRxT-LY%Lfy1qT7N^lU+#}9vsP&|m!=9s^jJsR ztMD&Ht`kiht>(OQ*guPr^!v}*v3&?%DiOW1Iow9Y>@u`n>iaRfyMftP9r82|8`nua zt9RJD-WuZr3~H;m`}9jms~prMiQyIxGK)2bUZ|`^xXe~f-K#LYk`WK%nfQX#!}S4I z>I5(%Mid8AU+1~ELRHMk7u`}}cgRSKv2b*eVrBd>La)w~w2mRC58R$9 zQG4UbOxnIB^SMUjgblX!RCl=L^{s(d&wx2O(`8}WJRcGG+Ru`RJ7IUd=XRGDejuT6 zAEC=B<{6La@j{#jZr_$s%@(`osR7&edcs**fOM<-`OrqMa~DijbN;N+O(8sEk?~u} zgQSRac9Dc~XPA4(fwD5);yQ~HpJvS;y@if&hFTgQWpJp<%F>^Y$bFzsMVCx{=l3o< zIg=mgp7YppfwSAXl;)_Zk9;{Q_}Xi}BcPh!WIf_c=+cIX2a{$)eQQc!P+i1doF*xPe|eQzzQVN3l^^Odb?ZtyvMtLotpZ0 zzY>wX*WXndUrQ>)rtB~23evR2l+MNYwKaAH30by&dSfxezRYduaBt;7&BU!CTTsT3 zO+~Mr(WX`?T2QTbk-$;O{q#CA^*-j)`9679r3_bna!9&bfa;w`H;I}<$&sWC16R`6{XBi(d6~O8^l^)9poG(rN?#Jw zjF8BXWRbxS_e+f%vYLcXgXz1BIDi}qp5?{cyHA0ZFqDQ3FU;3pOZNC6{k2F52&Q)3mR?fv4 zacg9~pDG@XDIb$B1Ce)}Shp;{Te_b^FD+X4loT)HDd*DA(8HaWZh$e{wBkDN_{5x# z;;K$I{1a_`A_-m?0?aFp$ntsrhVpRZe=&??Fc)8^!=E+P`}=#qs}Cc}^Y=MBjI__} PYk;_jjBur(p8x*?UY1SQ literal 0 HcmV?d00001 diff --git a/cxxtest/docs/win32.png b/cxxtest/docs/win32.png new file mode 100644 index 0000000000000000000000000000000000000000..5de325bb1905c915793f7ac637dc38715068ddb5 GIT binary patch literal 1709 zcmV;e22%NnP)fB$c9Z$LmmUteE8KR*Ef0H$KjCjbBd32;bRa{vGm zbN~PnbOGLGA9w%&1@=iqK~#9!?VXF3;wlhDgZ7LL>Ybi{5) zUMt2Vys9`B62NVavC5GFv*Lg39^a$?Q|J10WmC7|r^_ z{THqEm;KVC0+lhy?5UI4;ds(5r{iJiae=!< z!V~$elE-d|i_C0pcKEK1%=EFSW%xpCKp(#HPJ`Zuv_1CWUSywTlcCyR@qmuO}3q+6ZDzhJ1XK^xXpZAYMW^Hcv ztyR~r-_OsT%>KMsr_4C(N}t8o_6TQIW}d4_GP}*TIcsW@*>FIkS*x&4Ya*I;GSh!Y zneDAp`n?`!yZ6)OkxYf%^biI}alP}c6y(^p>D1A*2YSiG8_oM?0^v>4GERqLhzX;k znu`cO&{Hy-0a9?_R3|(=9X^GB`x;W%VM~EB1Jo_5vu_2Fm|LbQo}bi z*15m2D@I3Zu+9RW5zRjuu`(OhO&QJ3CnB@cc|vA(o-}{G29(I_Y2G9&<)8k*Fyy3b z5_WW;Nva92O+qwrqa&t?@=mN>kIYy!Bk!BNwYk~f3zz-d{>)rYr%q1Kl*BaiJww#q zNuBs*=9xH0W~5zb=1J#Xo30w2tq}@*>yue1H{0#rPlFFnZ~GV5-C~X+WyaePt;qS{ zMFY{y8N!6jXp`P(7CMnMI^M?$WH#PchGi!1G}&jGhu1biJHDQc$|7nqp=} z5_A2c=?KD`9I?J9bF-w;`Np;?nI*h$)^dJ1AN6@Zu9(Ch;;w8E7M(L4keIt5*|u2# z^4!ZgVJvi~>4`gJRBo2!UUeovVRTLfdZ(#%eKJe_6o7uF*>ZT-=kqP203Bf+1!DWd zu-P({Ja$Vs(X8ct%`zjmskharS7vGkw}i~idR|s6vkzfLsA)2;0#7sp;G;3Q82~vM zqS+RJTx?8kwq088pk6jMnl=AZnzTazCfJzV3^D`RKr{mdpt%`j1~P$Y1`2@O3={y- z3={yl87Kgv87Kg9Gf)6TGf)8JW}pCwW}pDb%|HPV%|HQ=n}Gr#nt=i!Hv$Q$4o;xSdI&l)GxX z)2zvs0u*vrb-$qjnI(Z}b{#d@Qh=f|8*;Pp=aIuGvG1Pw>e$~}_SVlwjNj(%oNXby z9fcU&xfY^iMlL!si+s)6XhtVO*_CD3tMQL3Ow;4}{#19Q zOaU^Nq@hwW>jy*n6)(sLJI5ko@YL#CSKfQT<{0CQdEG@CD^N4CSc2$Z=Foa`%ifV|r1Je)whOICa7io9#A` zn;Cy9vTuaUn8RI}*~a8dmGB$sw^52KBGyjF>mr&JF{g~XgkF?iUe4YwP+>=OD)Z!K z!h>>E_Jq+HnF#}m_)RQmYC>i~I~}jrE3<&XZnSbHbIuX1%6M*OBH|5;Cfhs>+(T{_ zYp3+Og3R10o^eE{GM=0D3x{>NyaN+``|dOynT@O0P@z~fll^i}#M#M<(mPF6oy_bT z)--k7 zFPYmv2E9*`-K8SW5tYf@tOjbbr2zTdWmSgUZ1rSw7gL#uW=ns?>Lb6bwe$!ciX86p zs1E<92@23hv(J}j*sx{WTA3~VEiO<$YJ8IjfQAYIane%E{+PvmLnt~d`n`xkVW2Tl(39(jS46wAkBaJ+UNy9vr zOME<0F_#%$<%wViM7f?il<=Ot>EGNe@zU)tPoC}z=f_-PCZsG?L=ucURQ13`{LC^j z3qI^a_+ZxRjl8_kk#3Qbil#r3mOgHAOWv|CJ2*DeP@4~iN|5Kf%1Nx)oGJ&b)QsIt z$WR=Dg^+n-1kz8s@g9qGT-KQyY)UDA;KSl}jk8*Q90(>i9ZM7Xd>eViXgk6->7Mae z7(_USR@+SEhApbQd`I4Do3gtp-|ra>Ff5|Y>a5oT53R@wOEHf`FA!rn9N|;1xXU!5 zX)Y<(&e34v3MH=^(wFF8F|zrMlWPQR6@U5(@zBcJB8B_(%{rQGFfl3Bf+5(!f7rYp z#}YJbCoG-Ljl5KS4GC=?@syNF|Eyh@moHRuR0}wDny6*hU8pHauFeT5M_$w3-jNXO zSv@AJc$a+TY8NrC#^s|i^|KeK1YEdJ(DMdfOL6QVBW>+iOY2cD=beau#=;EI1pTD0 zl3=y)9gmfT^xM56=~2jh*K{)X3Y+$tm@nQf#08^>yZ3 zTC+t?5L@uG&1h~SrqNVDShCEQEh%gw&=|8EeL3h&WKL6No*9pIT!-fHLWbrzb(rtm zQtCC2zogm89F9E)Lx3S6#Z4F%um)1qad)1QD2WIRoM6@vyO}!ebW`}?+3Cv9iLKIYS`TE-6We)tQJu!58-wX) zWNhl~CAinJTm#2|A-Hi1!TewLm9$Edx!cE)^5^kG|F#S)8XaQVr;Am*Wkv|2F(=A= z_TtFdqFaRqcM8=FUulT8cM}>52`yCmDynJX`{ylHgS<{4W zf>I9(0ZDB}5xhl?)u^>)Nd4R@E48D8$pH)wOsCx-QsJ-0S-TBGG1oApqPEgD9D1<8 zaBA+YV+CYSIGzb=cn3)heh|}p_#p3(Zqj=?)bl2;#k2@_0d&l^pkh` z%-UmRba9|I@Uda^p--Yd6O-R|bYt;>Uid_VJ MJp*8M(3tC=00!Tf?*IS* literal 0 HcmV?d00001 diff --git a/cxxtest/sample/Construct b/cxxtest/sample/Construct new file mode 100644 index 000000000..b8019616a --- /dev/null +++ b/cxxtest/sample/Construct @@ -0,0 +1,64 @@ +# -*- Perl -*- + +# +# This file shows how to use CxxTest with Cons +# + +$env = new cons( CXX => ("$^O" eq 'MSWin32') ? 'cl -nologo -GX' : 'c++', + CPPPATH => '..', + CXXTESTGEN => 'perl -w ../cxxtestgen.pl' ); + +@tests = <*.h>; + +# The error printer is the most basic runner +CxxTestErrorPrinter $env 'error_printer', @tests; + +# You can also specify which runner you want to use +CxxTestRunner $env 'stdio_printer', 'StdioPrinter', @tests; + +# For more control, use template files +CxxTestTemplate $env 'file_printer', 'file_printer.tpl', @tests; + +# Or, you can always separate the tests from the runner +CxxTest $env 'tests.cpp', '', @tests; +Program $env 'yes_no_runner', ('yes_no_runner.cpp', 'tests.cpp'); + + +# +# Here is the code used to build these files +# You can use this in your own Construct files +# + +# cons::CxxTest $env $dst, $options, @srcs +# Generates a CxxTest source file, passing the specified options to cxxtestgen +sub cons::CxxTest($$$@) { + my ($env, $dst, $options, @srcs) = @_; + Command $env $dst, @srcs, "%CXXTESTGEN -o %> ${options} %<"; +} + +# cons::CxxTestTemplate $env $dst, $template, @srcs +# Generates and builds a CxxTest runner using a template file +sub cons::CxxTestTemplate($$$@) { + my ($env, $dst, $template, @srcs) = @_; + my $source = "${dst}.cpp"; + CxxTest $env $source, "--template=${template}", ($template, @srcs); + Program $env $dst, $source; +} + +# cons::CxxTestRunner $env $dst, $runner, @srcs +# Generates and builds a CxxTest runner using the --runner option +sub cons::CxxTestRunner($$$@) { + my ($env, $dst, $runner, @srcs) = @_; + my $source = "${dst}.cpp"; + CxxTest $env $source, "--runner=${runner}", @srcs; + Program $env $dst, $source; +} + +# cons::CxxTestErrorPrinter $env $dst, @srcs +# Generates and builds a CxxTest ErrorPrinter +sub cons::CxxTestErrorPrinter($$@) { + my ($env, $dst, @srcs) = @_; + CxxTestRunner $env $dst, 'ErrorPrinter', @srcs; +} + + diff --git a/cxxtest/sample/CreatedTest.h b/cxxtest/sample/CreatedTest.h new file mode 100644 index 000000000..84e8ae8a4 --- /dev/null +++ b/cxxtest/sample/CreatedTest.h @@ -0,0 +1,31 @@ +#ifndef __CREATEDTEST_H +#define __CREATEDTEST_H + +#include +#include +#include + +// +// This test suite shows what to do when your test case +// class cannot be instantiated statically. +// As an example, this test suite requires a non-default constructor. +// + +class CreatedTest : public CxxTest::TestSuite +{ + char *_buffer; +public: + CreatedTest( unsigned size ) : _buffer( new char[size] ) {} + virtual ~CreatedTest() { delete [] _buffer; } + + static CreatedTest *createSuite() { return new CreatedTest( 16 ); } + static void destroySuite( CreatedTest *suite ) { delete suite; } + + void test_nothing() + { + TS_FAIL( "Nothing to test" ); + } +}; + + +#endif // __CREATEDTEST_H diff --git a/cxxtest/sample/DeltaTest.h b/cxxtest/sample/DeltaTest.h new file mode 100644 index 000000000..7223c3af2 --- /dev/null +++ b/cxxtest/sample/DeltaTest.h @@ -0,0 +1,27 @@ +#ifndef __DELTATEST_H +#define __DELTATEST_H + +#include +#include + +class DeltaTest : public CxxTest::TestSuite +{ + double _pi, _delta; + +public: + void setUp() + { + _pi = 3.1415926535; + _delta = 0.0001; + } + + void testSine() + { + TS_ASSERT_DELTA( sin(0.0), 0.0, _delta ); + TS_ASSERT_DELTA( sin(_pi / 6), 0.5, _delta ); + TS_ASSERT_DELTA( sin(_pi / 2), 1.0, _delta ); + TS_ASSERT_DELTA( sin(_pi), 0.0, _delta ); + } +}; + +#endif // __DELTATEST_H diff --git a/cxxtest/sample/EnumTraits.h b/cxxtest/sample/EnumTraits.h new file mode 100644 index 000000000..1a987318f --- /dev/null +++ b/cxxtest/sample/EnumTraits.h @@ -0,0 +1,39 @@ +// +// This is a test of CxxTest's ValueTraits for enumerations. +// +#include + +// +// First define your enumeration +// +enum Answer { + Yes, + No, + Maybe, + DontKnow, + DontCare +}; + +// +// Now make CxxTest aware of it +// +CXXTEST_ENUM_TRAITS( Answer, + CXXTEST_ENUM_MEMBER( Yes ) + CXXTEST_ENUM_MEMBER( No ) + CXXTEST_ENUM_MEMBER( Maybe ) + CXXTEST_ENUM_MEMBER( DontKnow ) + CXXTEST_ENUM_MEMBER( DontCare ) ); + +class EnumTraits : public CxxTest::TestSuite +{ +public: + void test_Enum_traits() + { + TS_FAIL( Yes ); + TS_FAIL( No ); + TS_FAIL( Maybe ); + TS_FAIL( DontKnow ); + TS_FAIL( DontCare ); + TS_FAIL( (Answer)1000 ); + } +}; diff --git a/cxxtest/sample/ExceptionTest.h b/cxxtest/sample/ExceptionTest.h new file mode 100644 index 000000000..68363c874 --- /dev/null +++ b/cxxtest/sample/ExceptionTest.h @@ -0,0 +1,52 @@ +#ifndef __EXCEPTIONTEST_H +#define __EXCEPTIONTEST_H + +#include + +// +// This test suite demonstrates the use of TS_ASSERT_THROWS +// + +class ExceptionTest : public CxxTest::TestSuite +{ +public: + void testAssertion( void ) + { + // This assert passes, since throwThis() throws (Number) + TS_ASSERT_THROWS( throwThis(3), const Number & ); + // This assert passes, since throwThis() throws something + TS_ASSERT_THROWS_ANYTHING( throwThis(-30) ); + // This assert fails, since throwThis() doesn't throw char * + TS_ASSERT_THROWS( throwThis(5), const char * ); + // This assert fails since goodFunction() throws nothing + TS_ASSERT_THROWS_ANYTHING( goodFunction(1) ); + // The regular TS_ASSERT macros will catch unhandled exceptions + TS_ASSERT_EQUALS( throwThis(3), 333 ); + // You can assert that a function throws nothing + TS_ASSERT_THROWS_NOTHING( throwThis(-1) ); + // If you want to catch the exceptions yourself, use the ETS_ marcos + try { + ETS_ASSERT_EQUALS( throwThis(3), 333 ); + } catch( const Number & ) { + TS_FAIL( "throwThis(3) failed" ); + } + } + +private: + void goodFunction( int ) + { + } + + class Number + { + public: + Number( int ) {} + }; + + int throwThis( int i ) + { + throw Number( i ); + } +}; + +#endif // __EXCEPTIONTEST_H diff --git a/cxxtest/sample/FixtureTest.h b/cxxtest/sample/FixtureTest.h new file mode 100644 index 000000000..653c7a14a --- /dev/null +++ b/cxxtest/sample/FixtureTest.h @@ -0,0 +1,37 @@ +#ifndef __FIXTURETEST_H +#define __FIXTURETEST_H + +#include +#include + +// +// This test suite shows how to use setUp() and tearDown() +// to initialize data common to all tests. +// setUp()/tearDown() will be called before and after each +// test. +// + +class FixtureTest : public CxxTest::TestSuite +{ + char *_buffer; +public: + void setUp() + { + _buffer = new char[1024]; + } + + void tearDown() + { + delete [] _buffer; + } + + void test_strcpy() + { + strcpy( _buffer, "Hello, world!" ); + TS_ASSERT_EQUALS( _buffer[0], 'H' ); + TS_ASSERT_EQUALS( _buffer[1], 'E' ); + } +}; + + +#endif // __FIXTURETEST_H diff --git a/cxxtest/sample/Makefile.PL b/cxxtest/sample/Makefile.PL new file mode 100755 index 000000000..d29afcc68 --- /dev/null +++ b/cxxtest/sample/Makefile.PL @@ -0,0 +1,32 @@ +#!/usr/bin/perl +# +# This isn't a "real" `Makefile.PL' +# It just copies the correct `Makefile.*' to `Makefile' +# +use strict; +use Getopt::Long; +use File::Copy; + +sub usage() { + die "Usage: $0 [--bcc32]\n"; +} + +my $source; +my $target = 'Makefile'; +my $windows = $ENV{'windir'}; + +GetOptions( 'bcc32' => sub { $source = 'Makefile.bcc32' } ) or usage(); +if ( !defined( $source ) ) { + $source = $windows ? 'Makefile.msvc' : 'Makefile.unix'; +} + +unlink($target); +$windows ? copy($source, $target) : symlink($source, $target); + +print "`Makefile' is now `$source'.\n"; + +# +# Local Variables: +# compile-command: "perl Makefile.PL" +# End: +# diff --git a/cxxtest/sample/Makefile.bcc32 b/cxxtest/sample/Makefile.bcc32 new file mode 100644 index 000000000..907b98d59 --- /dev/null +++ b/cxxtest/sample/Makefile.bcc32 @@ -0,0 +1,94 @@ +# +# Makefile for Borland C++ +# Make sure bcc32.exe is in the PATH or change CXXC below +# + +# For the Win32 GUI +#WIN32_FLAGS = user32.lib comctl32.lib + +# For the Qt GUI +#QTDIR = c:\qt +QT_FLAGS = -I$(QTDIR)/include $(QTDIR)/lib/qt.lib + + +TARGETS = error_printer.exe stdio_printer.exe yes_no_runner.exe file_printer.exe aborter.exe only.exe +GUI_TARGETS = win32_runner.exe qt_runner.exe +TESTS = *.h +GUI_TESTS = gui/GreenYellowRed.h $(TESTS) +TESTGEN = perl -w ../cxxtestgen.pl +CXXC = bcc32.exe -w- -I. -I.. + +all: $(TARGETS) + +clean: + del *~ *.o *.obj + del $(TARGETS) + del $(GUI_TARGETS) + del tests.cpp error_printer.cpp stdio_printer.cpp file_printer.cpp aborter.cpp only.cpp + del win32_runner.cpp qt_runner.cpp + +distclean: clean + del Makefile + +run: error_printer.exe + error_printer.exe + +run_win32: win32_runner.exe + win32_runner.exe + +run_qt: qt_runner.exe + qt_runner.exe + +error_printer.cpp: $(TESTS) + $(TESTGEN) -o error_printer.cpp --error-printer $(TESTS) + +stdio_printer.cpp: $(TESTS) + $(TESTGEN) -o stdio_printer.cpp --runner=StdioPrinter $(TESTS) + +file_printer.cpp: file_printer.tpl $(TESTS) + $(TESTGEN) -o file_printer.cpp --template=file_printer.tpl $(TESTS) + +aborter.cpp: aborter.tpl $(TESTS) + $(TESTGEN) -o aborter.cpp --template=aborter.tpl $(TESTS) + +only.cpp: only.tpl $(TESTS) + $(TESTGEN) -o only.cpp --template=only.tpl $(TESTS) + +tests.cpp: $(TESTS) + $(TESTGEN) -o tests.cpp $(TESTS) + +win32_runner.cpp: $(GUI_TESTS) + $(TESTGEN) -o win32_runner.cpp --gui=Win32Gui $(GUI_TESTS) + +qt_runner.cpp: $(GUI_TESTS) + $(TESTGEN) -o qt_runner.cpp --gui=QtGui $(GUI_TESTS) + +error_printer.exe: error_printer.cpp + $(CXXC) -eerror_printer.exe error_printer.cpp + +stdio_printer.exe: stdio_printer.cpp + $(CXXC) -estdio_printer.exe stdio_printer.cpp + +file_printer.exe: file_printer.cpp + $(CXXC) -efile_printer.exe file_printer.cpp + +only.exe: only.cpp + $(CXXC) -eonly.exe only.cpp + +aborter.exe: aborter.cpp + $(CXXC) -eaborter.exe aborter.cpp + +yes_no_runner.exe: yes_no_runner.cpp tests.cpp + $(CXXC) -eyes_no_runner.exe yes_no_runner.cpp tests.cpp + +win32_runner.exe: win32_runner.cpp + $(CXXC) -ewin32_runner.exe win32_runner.cpp $(WIN32_FLAGS) + +qt_runner.exe: qt_runner.cpp + $(CXXC) -o qt_runner.exe qt_runner.cpp $(QT_FLAGS) + +# +# Local Variables: +# compile-command: "make -fMakefile.bcc32" +# End: +# diff --git a/cxxtest/sample/Makefile.msvc b/cxxtest/sample/Makefile.msvc new file mode 100644 index 000000000..35ce2f9b1 --- /dev/null +++ b/cxxtest/sample/Makefile.msvc @@ -0,0 +1,93 @@ +# +# Makefile for Microsoft Visual C++ +# Make sure cl.exe is in the PATH (run vcvars.bat) or change CXXC below +# + +# For the Win32 GUI +WIN32_FLAGS = user32.lib + +# For the Qt GUI +# QTDIR = c:\qt +QT_FLAGS = -I$(QTDIR)/include $(QTDIR)/lib/qt.lib + +TARGETS = error_printer.exe stdio_printer.exe yes_no_runner.exe file_printer.exe aborter.exe only.exe +GUI_TARGETS = win32_runner.exe qt_runner.exe +TESTS = *.h +GUI_TESTS = gui/GreenYellowRed.h $(TESTS) +TESTGEN = perl -w ../cxxtestgen.pl +CXXC = cl.exe -GX -W3 -WX -I. -I.. + +all: $(TARGETS) + +clean: + del *~ *.o *.obj + del $(TARGETS) + del $(GUI_TARGETS) + del tests.cpp error_printer.cpp stdio_printer.cpp file_printer.cpp aborter.cpp only.cpp + del win32_runner.cpp qt_runner.cpp + +distclean: clean + del Makefile + +run: error_printer.exe + error_printer.exe + +run_win32: win32_runner.exe + win32_runner.exe + +run_qt: qt_runner.exe + qt_runner.exe + +error_printer.cpp: $(TESTS) + $(TESTGEN) -o error_printer.cpp --error-printer $(TESTS) + +stdio_printer.cpp: $(TESTS) + $(TESTGEN) -o stdio_printer.cpp --runner=StdioPrinter $(TESTS) + +file_printer.cpp: file_printer.tpl $(TESTS) + $(TESTGEN) -o file_printer.cpp --template=file_printer.tpl $(TESTS) + +aborter.cpp: aborter.tpl $(TESTS) + $(TESTGEN) -o aborter.cpp --template=aborter.tpl $(TESTS) + +only.cpp: only.tpl $(TESTS) + $(TESTGEN) -o only.cpp --template=only.tpl $(TESTS) + +tests.cpp: $(TESTS) + $(TESTGEN) -o tests.cpp $(TESTS) + +win32_runner.cpp: $(GUI_TESTS) + $(TESTGEN) -o win32_runner.cpp --gui=Win32Gui $(GUI_TESTS) + +qt_runner.cpp: $(GUI_TESTS) + $(TESTGEN) -o qt_runner.cpp --gui=QtGui $(GUI_TESTS) + +error_printer.exe: error_printer.cpp + $(CXXC) -o error_printer.exe error_printer.cpp + +stdio_printer.exe: stdio_printer.cpp + $(CXXC) -o stdio_printer.exe stdio_printer.cpp + +file_printer.exe: file_printer.cpp + $(CXXC) -o file_printer.exe file_printer.cpp + +only.exe: only.cpp + $(CXXC) -o only.exe only.cpp + +aborter.exe: aborter.cpp + $(CXXC) -o aborter.exe aborter.cpp + +yes_no_runner.exe: yes_no_runner.cpp tests.cpp + $(CXXC) -o yes_no_runner.exe yes_no_runner.cpp tests.cpp + +win32_runner.exe: win32_runner.cpp + $(CXXC) -o win32_runner.exe win32_runner.cpp $(WIN32_FLAGS) + +qt_runner.exe: qt_runner.cpp + $(CXXC) -o qt_runner.exe qt_runner.cpp $(QT_FLAGS) + +# +# Local Variables: +# compile-command: "nmake -fMakefile.msvc" +# End: +# diff --git a/cxxtest/sample/Makefile.unix b/cxxtest/sample/Makefile.unix new file mode 100644 index 000000000..ee52c8f77 --- /dev/null +++ b/cxxtest/sample/Makefile.unix @@ -0,0 +1,88 @@ +# +# Makefile for UN*X-like systems +# + +# Change this line if you want a different compiler +CXXC = c++ -Wall -W -Werror -I. -I.. + +# If you want to use python, specify USE_PYTHON=1 on the command line +ifdef USE_PYTHON + TESTGEN = ../cxxtestgen.py +else + TESTGEN = ../cxxtestgen.pl +endif + +# For the X11 GUI +X11_FLAGS = -I/usr/X11R6/include -L/usr/X11R6/lib -lX11 + +# For the Qt GUI +#QTDIR = /usr/lib/qt +QTLIB = -lqt-mt +#QTLIB = -lqt +QT_FLAGS = -I$(QTDIR)/include -L$(QTDIR)/lib $(QTLIB) -O2 + +TARGETS = error_printer stdio_printer yes_no_runner file_printer aborter only +GUI_TARGETS = x11_runner qt_runner +TESTS = *.h +GUI_TESTS = gui/GreenYellowRed.h $(TESTS) + +all: $(TARGETS) + +clean: + rm -f *~ *.o *.obj $(TARGETS) $(GUI_TARGETS) + rm -f tests.cpp error_printer.cpp stdio_printer.cpp file_printer.cpp aborter.cpp only.cpp + rm -f x11_runner.cpp qt_runner.cpp + +distclean: clean + rm -f Makefile + +run: error_printer + ./error_printer + +run_x11: x11_runner + ./x11_runner + +run_qt: qt_runner + ./qt_runner + +error_printer.cpp: $(TESTS) + $(TESTGEN) -o $@ --error-printer $(TESTS) + +stdio_printer.cpp: $(TESTS) + $(TESTGEN) -o $@ --runner=StdioPrinter $(TESTS) + +file_printer.cpp: file_printer.tpl $(TESTS) + $(TESTGEN) -o $@ --template=file_printer.tpl $(TESTS) + +aborter.cpp: aborter.tpl $(TESTS) + $(TESTGEN) -o $@ --template=aborter.tpl $(TESTS) + +only.cpp: only.tpl $(TESTS) + $(TESTGEN) -o $@ --template=only.tpl $(TESTS) + +tests.cpp: $(TESTS) + $(TESTGEN) -o $@ $(TESTS) + +x11_runner.cpp: $(GUI_TESTS) + $(TESTGEN) -o $@ --gui=X11Gui $(GUI_TESTS) + +qt_runner.cpp: $(GUI_TESTS) + $(TESTGEN) -o $@ --gui=QtGui $(GUI_TESTS) + +%: %.cpp + $(CXXC) -o $@ $< + +yes_no_runner: yes_no_runner.cpp tests.cpp + $(CXXC) -o $@ $^ + +x11_runner: x11_runner.cpp + $(CXXC) -o $@ $^ $(X11_FLAGS) + +qt_runner: qt_runner.cpp + $(CXXC) -o $@ $^ $(QT_FLAGS) + +# +# Local Variables: +# compile-command: "make -fMakefile.unix" +# End: +# diff --git a/cxxtest/sample/MessageTest.h b/cxxtest/sample/MessageTest.h new file mode 100644 index 000000000..621289f78 --- /dev/null +++ b/cxxtest/sample/MessageTest.h @@ -0,0 +1,30 @@ +#ifndef __MESSAGETEST_H +#define __MESSAGETEST_H + +#include + +// +// The [E]TSM_ macros can be used to print a specified message +// instead of the default one. +// This is useful when you refactor your tests, as shown below +// + +class MessageTest : public CxxTest::TestSuite +{ +public: + void testValues() + { + checkValue( 0, "My hovercraft" ); + checkValue( 1, "is full" ); + checkValue( 2, "of eels" ); + } + + void checkValue( unsigned value, const char *message ) + { + TSM_ASSERT( message, value != 0 ); + TSM_ASSERT_EQUALS( message, value, value * value ); + } +}; + + +#endif // __MESSAGETEST_H diff --git a/cxxtest/sample/SimpleTest.h b/cxxtest/sample/SimpleTest.h new file mode 100644 index 000000000..b3fae12ca --- /dev/null +++ b/cxxtest/sample/SimpleTest.h @@ -0,0 +1,59 @@ +#ifndef __SIMPLETEST_H +#define __SIMPLETEST_H + +#include + +// +// A simple test suite: Just inherit CxxTest::TestSuite and write tests! +// + +class SimpleTest : public CxxTest::TestSuite +{ +public: + void testEquality() + { + TS_ASSERT_EQUALS( 1, 1 ); + TS_ASSERT_EQUALS( 1, 2 ); + TS_ASSERT_EQUALS( 'a', 'A' ); + TS_ASSERT_EQUALS( 1.0, -12345678900000000000000000000000000000000000000000.1234 ); + } + + void testAddition() + { + TS_ASSERT_EQUALS( 1 + 1, 2 ); + TS_ASSERT_EQUALS( 2 + 2, 5 ); + } + + void TestMultiplication() + { + TS_ASSERT_EQUALS( 2 * 2, 4 ); + TS_ASSERT_EQUALS( 4 * 4, 44 ); + TS_ASSERT_DIFFERS( -2 * -2, 4 ); + } + + void testComparison() + { + TS_ASSERT_LESS_THAN( (int)1, (unsigned long)2 ); + TS_ASSERT_LESS_THAN( -1, -2 ); + } + + void testTheWorldIsCrazy() + { + TS_ASSERT_EQUALS( true, false ); + } + + void test_Failure() + { + TS_FAIL( "Not implemented" ); + TS_FAIL( 1569779912 ); + } + + void test_TS_WARN_macro() + { + TS_WARN( "Just a friendly warning" ); + TS_WARN( "Warnings don't abort the test" ); + } +}; + + +#endif // __SIMPLETEST_H diff --git a/cxxtest/sample/TraitsTest.h b/cxxtest/sample/TraitsTest.h new file mode 100644 index 000000000..14659385d --- /dev/null +++ b/cxxtest/sample/TraitsTest.h @@ -0,0 +1,69 @@ +#ifndef __TRAITSTEST_H +#define __TRAITSTEST_H + +// +// This example shows how to use TS_ASSERT_EQUALS for your own classes +// +#include +#include + +// +// Define your class with operator== +// +#include +#include + +class Pet +{ + char _name[128]; +public: + Pet( const char *petName ) { strcpy( _name, petName ); } + + const char *name() const { return _name; } + + bool operator== ( const Pet &other ) const + { + return !strcmp( name(), other.name() ); + } +}; + +// +// Instantiate CxxTest::ValueTraits<*your class*> +// Note: Most compilers do not require that you define both +// ValueTraits and ValueTraits, but some do. +// +namespace CxxTest +{ + CXXTEST_TEMPLATE_INSTANTIATION + class ValueTraits + { + char _asString[256]; + + public: + ValueTraits( const Pet &pet ) { sprintf( _asString, "Pet(\"%s\")", pet.name() ); } + const char *asString() const { return _asString; } + }; + + CXXTEST_COPY_CONST_TRAITS( Pet ); +} + +// +// Here's how it works +// +class TestFunky : public CxxTest::TestSuite +{ +public: + void testPets() + { + Pet pet1("dog"), pet2("cat"); + TS_ASSERT_EQUALS( pet1, pet2 ); + Pet cat("cat"), gato("cat"); + TS_ASSERT_DIFFERS( cat, gato ); +#ifdef _CXXTEST_HAVE_STD + typedef CXXTEST_STD(string) String; + TS_ASSERT_EQUALS( String("Hello"), String("World!") ); +#endif // _CXXTEST_HAVE_STD + } +}; + +#endif // __TRAITSTEST_H diff --git a/cxxtest/sample/aborter.tpl b/cxxtest/sample/aborter.tpl new file mode 100644 index 000000000..14fc50d2c --- /dev/null +++ b/cxxtest/sample/aborter.tpl @@ -0,0 +1,16 @@ +// -*- C++ -*- +// This template file demonstrates the use of CXXTEST_ABORT_TEST_ON_FAIL +// + +#define CXXTEST_HAVE_STD +#define CXXTEST_ABORT_TEST_ON_FAIL +#include + +int main() +{ + return CxxTest::ErrorPrinter().run(); +} + +// The CxxTest "world" + + diff --git a/cxxtest/sample/file_printer.tpl b/cxxtest/sample/file_printer.tpl new file mode 100644 index 000000000..a9627d6d0 --- /dev/null +++ b/cxxtest/sample/file_printer.tpl @@ -0,0 +1,22 @@ +// -*- C++ -*- +// This is a sample of a custom test runner +// using CxxTest template files. +// This prints the output to a file given on the command line. +// + +#include +#include + +int main( int argc, char *argv[] ) +{ + if ( argc != 2 ) { + fprintf( stderr, "Usage: %s \n", argv[0] ); + return -1; + } + + return CxxTest::StdioPrinter( fopen( argv[1], "w" ) ).run(); +} + +// The CxxTest "world" + + diff --git a/cxxtest/sample/gui/GreenYellowRed.h b/cxxtest/sample/gui/GreenYellowRed.h new file mode 100644 index 000000000..446b23345 --- /dev/null +++ b/cxxtest/sample/gui/GreenYellowRed.h @@ -0,0 +1,57 @@ +#include + +#ifdef _WIN32 +# include +# define CXXTEST_SAMPLE_GUI_WAIT() Sleep( 1000 ) +#else // !_WIN32 + extern "C" unsigned sleep( unsigned seconds ); +# define CXXTEST_SAMPLE_GUI_WAIT() sleep( 1 ) +#endif // _WIN32 + +class GreenYellowRed : public CxxTest::TestSuite +{ +public: + void wait() + { + CXXTEST_SAMPLE_GUI_WAIT(); + } + + void test_Start_green() + { + wait(); + } + + void test_Green_again() + { + TS_TRACE( "Still green" ); + wait(); + } + + void test_Now_yellow() + { + TS_WARN( "Yellow" ); + wait(); + } + + void test_Cannot_go_back() + { + wait(); + } + + void test_Finally_red() + { + TS_FAIL( "Red" ); + wait(); + } + + void test_Cannot_go_back_to_yellow() + { + TS_WARN( "Yellow?" ); + wait(); + } + + void test_Cannot_go_back_to_green() + { + wait(); + } +}; diff --git a/cxxtest/sample/mock/Dice.cpp b/cxxtest/sample/mock/Dice.cpp new file mode 100644 index 000000000..161b80fa2 --- /dev/null +++ b/cxxtest/sample/mock/Dice.cpp @@ -0,0 +1,14 @@ +#include +#include "Dice.h" + +Dice::Dice() +{ + T::srand( T::time( 0 ) ); +} + +unsigned Dice::roll() +{ + return (T::rand() % 6) + 1; +} + + diff --git a/cxxtest/sample/mock/Dice.h b/cxxtest/sample/mock/Dice.h new file mode 100644 index 000000000..94271417e --- /dev/null +++ b/cxxtest/sample/mock/Dice.h @@ -0,0 +1,13 @@ +#ifndef __DICE_H +#define __DICE_H + +class Dice +{ +public: + Dice(); + + unsigned roll(); +}; + +#endif // __DICE_H + diff --git a/cxxtest/sample/mock/Makefile b/cxxtest/sample/mock/Makefile new file mode 100644 index 000000000..709b7cbe9 --- /dev/null +++ b/cxxtest/sample/mock/Makefile @@ -0,0 +1,22 @@ +all: roll run + +clean: + rm -f *~ *.o roll test test.cpp + +CXXTEST = ../.. +CCFLAGS = -I. -I$(CXXTEST) + +roll: roll.o Dice.o real_stdlib.o + g++ -o $@ $^ + +run: test + ./test + +test: test.o Dice.o mock_stdlib.o + g++ -o $@ $^ + +.cpp.o: + g++ -c -o $@ $(CCFLAGS) $< + +test.cpp: TestDice.h + $(CXXTEST)/cxxtestgen.pl -o $@ --error-printer $< diff --git a/cxxtest/sample/mock/MockStdlib.h b/cxxtest/sample/mock/MockStdlib.h new file mode 100644 index 000000000..aee62bafe --- /dev/null +++ b/cxxtest/sample/mock/MockStdlib.h @@ -0,0 +1,31 @@ +#include + +class MockStdlib : + public T::Base_srand, + public T::Base_rand, + public T::Base_time +{ +public: + unsigned lastSeed; + + void srand( unsigned seed ) + { + lastSeed = seed; + } + + int nextRand; + + int rand() + { + return nextRand; + } + + time_t nextTime; + + time_t time( time_t *t ) + { + if ( t ) + *t = nextTime; + return nextTime; + } +}; diff --git a/cxxtest/sample/mock/T/stdlib.h b/cxxtest/sample/mock/T/stdlib.h new file mode 100644 index 000000000..30306ba22 --- /dev/null +++ b/cxxtest/sample/mock/T/stdlib.h @@ -0,0 +1,13 @@ +#ifndef __T__STDLIB_H +#define __T__STDLIB_H + +#include +#include + +#include + +CXXTEST_MOCK_VOID_GLOBAL( srand, ( unsigned seed ), ( seed ) ); +CXXTEST_MOCK_GLOBAL( int, rand, ( void ), () ); +CXXTEST_MOCK_GLOBAL( time_t, time, ( time_t *t ), ( t ) ); + +#endif // __T__STDLIB_H diff --git a/cxxtest/sample/mock/TestDice.h b/cxxtest/sample/mock/TestDice.h new file mode 100644 index 000000000..35b3b7eec --- /dev/null +++ b/cxxtest/sample/mock/TestDice.h @@ -0,0 +1,62 @@ +#include +#include "Dice.h" +#include "MockStdlib.h" + +class TestDice : public CxxTest::TestSuite +{ +public: + MockStdlib *stdlib; + + void setUp() + { + TS_ASSERT( stdlib = new MockStdlib ); + } + + void tearDown() + { + delete stdlib; + } + + void test_Randomize_uses_time() + { + stdlib->nextTime = 12345; + Dice dice; + TS_ASSERT_EQUALS( stdlib->lastSeed, 12345 ); + } + + void test_Roll() + { + Dice dice; + + stdlib->nextRand = 0; + TS_ASSERT_EQUALS( dice.roll(), 1 ); + + stdlib->nextRand = 2; + TS_ASSERT_EQUALS( dice.roll(), 3 ); + + stdlib->nextRand = 5; + TS_ASSERT_EQUALS( dice.roll(), 6 ); + + stdlib->nextRand = 7; + TS_ASSERT_EQUALS( dice.roll(), 2 ); + } + + void test_Temporary_override_of_one_mock_function() + { + Dice dice; + + stdlib->nextRand = 2; + TS_ASSERT_EQUALS( dice.roll(), 3 ); + + class Five : public T::Base_rand { int rand() { return 5; } }; + + Five *five = new Five; + TS_ASSERT_EQUALS( dice.roll(), 6 ); + TS_ASSERT_EQUALS( dice.roll(), 6 ); + TS_ASSERT_EQUALS( dice.roll(), 6 ); + delete five; + + stdlib->nextRand = 1; + TS_ASSERT_EQUALS( dice.roll(), 2 ); + } +}; diff --git a/cxxtest/sample/mock/mock_stdlib.cpp b/cxxtest/sample/mock/mock_stdlib.cpp new file mode 100644 index 000000000..148a044d2 --- /dev/null +++ b/cxxtest/sample/mock/mock_stdlib.cpp @@ -0,0 +1,2 @@ +#define CXXTEST_MOCK_TEST_SOURCE_FILE +#include diff --git a/cxxtest/sample/mock/real_stdlib.cpp b/cxxtest/sample/mock/real_stdlib.cpp new file mode 100644 index 000000000..db02f3a15 --- /dev/null +++ b/cxxtest/sample/mock/real_stdlib.cpp @@ -0,0 +1,2 @@ +#define CXXTEST_MOCK_REAL_SOURCE_FILE +#include diff --git a/cxxtest/sample/mock/roll.cpp b/cxxtest/sample/mock/roll.cpp new file mode 100644 index 000000000..20ea967af --- /dev/null +++ b/cxxtest/sample/mock/roll.cpp @@ -0,0 +1,11 @@ +#include +#include "Dice.h" + +int main() +{ + Dice dice; + printf( "First roll: %u\n", dice.roll() ); + printf( "Second roll: %u\n", dice.roll() ); + + return 0; +} diff --git a/cxxtest/sample/msvc/CxxTest_1_Run.dsp b/cxxtest/sample/msvc/CxxTest_1_Run.dsp new file mode 100644 index 000000000..6bc00e7f4 --- /dev/null +++ b/cxxtest/sample/msvc/CxxTest_1_Run.dsp @@ -0,0 +1,93 @@ +# Microsoft Developer Studio Project File - Name="CxxTest_1_Run" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) External Target" 0x0106 + +CFG=CxxTest_1_Run - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "CxxTest_1_Run.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "CxxTest_1_Run.mak" CFG="CxxTest_1_Run - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "CxxTest_1_Run - Win32 Release" (based on "Win32 (x86) External Target") +!MESSAGE "CxxTest_1_Run - Win32 Debug" (based on "Win32 (x86) External Target") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" + +!IF "$(CFG)" == "CxxTest_1_Run - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Cmd_Line "NMAKE /f CxxTest_1_Run.mak" +# PROP BASE Rebuild_Opt "/a" +# PROP BASE Target_File "CxxTest_1_Run.exe" +# PROP BASE Bsc_Name "CxxTest_1_Run.bsc" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Cmd_Line "nmake DIR=Release run" +# PROP Rebuild_Opt "/a" +# PROP Target_File "Release\run.log" +# PROP Bsc_Name "" +# PROP Target_Dir "" + +!ELSEIF "$(CFG)" == "CxxTest_1_Run - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Cmd_Line "NMAKE /f CxxTest_1_Run.mak" +# PROP BASE Rebuild_Opt "/a" +# PROP BASE Target_File "CxxTest_1_Run.exe" +# PROP BASE Bsc_Name "CxxTest_1_Run.bsc" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Cmd_Line "nmake DIR=Debug run" +# PROP Rebuild_Opt "/a" +# PROP Target_File "Debug\run.log" +# PROP Bsc_Name "" +# PROP Target_Dir "" + +!ENDIF + +# Begin Target + +# Name "CxxTest_1_Run - Win32 Release" +# Name "CxxTest_1_Run - Win32 Debug" + +!IF "$(CFG)" == "CxxTest_1_Run - Win32 Release" + +!ELSEIF "$(CFG)" == "CxxTest_1_Run - Win32 Debug" + +!ENDIF + +# Begin Source File + +SOURCE=.\Makefile +# End Source File +# Begin Source File + +SOURCE=.\ReadMe.txt +# End Source File +# End Target +# End Project diff --git a/cxxtest/sample/msvc/CxxTest_2_Build.dsp b/cxxtest/sample/msvc/CxxTest_2_Build.dsp new file mode 100644 index 000000000..04727fd33 --- /dev/null +++ b/cxxtest/sample/msvc/CxxTest_2_Build.dsp @@ -0,0 +1,94 @@ +# Microsoft Developer Studio Project File - Name="CxxTest_2_Build" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=CxxTest_2_Build - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "CxxTest_2_Build.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "CxxTest_2_Build.mak" CFG="CxxTest_2_Build - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "CxxTest_2_Build - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "CxxTest_2_Build - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "CxxTest_2_Build - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "..\.." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x40d /d "NDEBUG" +# ADD RSC /l 0x40d /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"Release/runner.exe" + +!ELSEIF "$(CFG)" == "CxxTest_2_Build - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "..\.." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x40d /d "_DEBUG" +# ADD RSC /l 0x40d /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"Debug/runner.exe" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "CxxTest_2_Build - Win32 Release" +# Name "CxxTest_2_Build - Win32 Debug" +# Begin Source File + +SOURCE=.\ReadMe.txt +# End Source File +# Begin Source File + +SOURCE=.\runner.cpp +# End Source File +# End Target +# End Project diff --git a/cxxtest/sample/msvc/CxxTest_3_Generate.dsp b/cxxtest/sample/msvc/CxxTest_3_Generate.dsp new file mode 100644 index 000000000..5bbad94ce --- /dev/null +++ b/cxxtest/sample/msvc/CxxTest_3_Generate.dsp @@ -0,0 +1,93 @@ +# Microsoft Developer Studio Project File - Name="CxxTest_3_Generate" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) External Target" 0x0106 + +CFG=CxxTest_3_Generate - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "CxxTest_3_Generate.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "CxxTest_3_Generate.mak" CFG="CxxTest_3_Generate - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "CxxTest_3_Generate - Win32 Release" (based on "Win32 (x86) External Target") +!MESSAGE "CxxTest_3_Generate - Win32 Debug" (based on "Win32 (x86) External Target") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" + +!IF "$(CFG)" == "CxxTest_3_Generate - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Cmd_Line "NMAKE /f CxxTest_3_Generate.mak" +# PROP BASE Rebuild_Opt "/a" +# PROP BASE Target_File "CxxTest_3_Generate.exe" +# PROP BASE Bsc_Name "CxxTest_3_Generate.bsc" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Cmd_Line "nmake runner.cpp" +# PROP Rebuild_Opt "/a" +# PROP Target_File "runner.cpp" +# PROP Bsc_Name "" +# PROP Target_Dir "" + +!ELSEIF "$(CFG)" == "CxxTest_3_Generate - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Cmd_Line "NMAKE /f CxxTest_3_Generate.mak" +# PROP BASE Rebuild_Opt "/a" +# PROP BASE Target_File "CxxTest_3_Generate.exe" +# PROP BASE Bsc_Name "CxxTest_3_Generate.bsc" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Cmd_Line "nmake runner.cpp" +# PROP Rebuild_Opt "/a" +# PROP Target_File "runner.cpp" +# PROP Bsc_Name "" +# PROP Target_Dir "" + +!ENDIF + +# Begin Target + +# Name "CxxTest_3_Generate - Win32 Release" +# Name "CxxTest_3_Generate - Win32 Debug" + +!IF "$(CFG)" == "CxxTest_3_Generate - Win32 Release" + +!ELSEIF "$(CFG)" == "CxxTest_3_Generate - Win32 Debug" + +!ENDIF + +# Begin Source File + +SOURCE=.\Makefile +# End Source File +# Begin Source File + +SOURCE=.\ReadMe.txt +# End Source File +# End Target +# End Project diff --git a/cxxtest/sample/msvc/CxxTest_Workspace.dsw b/cxxtest/sample/msvc/CxxTest_Workspace.dsw new file mode 100644 index 000000000..5dbf84190 --- /dev/null +++ b/cxxtest/sample/msvc/CxxTest_Workspace.dsw @@ -0,0 +1,59 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "CxxTest_1_Run"=.\CxxTest_1_Run.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name CxxTest_2_Build + End Project Dependency +}}} + +############################################################################### + +Project: "CxxTest_2_Build"=.\CxxTest_2_Build.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name CxxTest_3_Generate + End Project Dependency +}}} + +############################################################################### + +Project: "CxxTest_3_Generate"=.\CxxTest_3_Generate.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/cxxtest/sample/msvc/FixFiles.bat b/cxxtest/sample/msvc/FixFiles.bat new file mode 100644 index 000000000..fb14a6c49 --- /dev/null +++ b/cxxtest/sample/msvc/FixFiles.bat @@ -0,0 +1,212 @@ +@rem = '--*-Perl-*-- +@echo off +if "%OS%" == "Windows_NT" goto WinNT +perl -x -S "%0" %1 %2 %3 %4 %5 %6 %7 %8 %9 +goto endofperl +:WinNT +perl -x -S %0 %* +if NOT "%COMSPEC%" == "%SystemRoot%\system32\cmd.exe" goto endofperl +if %errorlevel% == 9009 echo You do not have Perl in your PATH. +if errorlevel 1 goto script_failed_so_exit_with_non_zero_val 2>nul +goto endofperl +@rem '; +#!/usr/bin/perl -w +#line 15 +use strict; +use English; +use Getopt::Long; + +$OUTPUT_AUTOFLUSH = 1; + +sub usage() { + print STDERR "Usage: $0 \n\n"; + print STDERR "Fix Makefile and CxxTest_2_Build.dsp for your setup.\n\n"; + print STDERR " --cxxtest=DIR Assume CxxTest is installed in DIR (default: '..\\..')\n"; + print STDERR " --tests=SPEC Use SPEC for the test files (default: '../gui/*.h ../*.h')\n\n"; + print STDERR "You must specify at least one option.\n"; + exit -1; +} + +my ($cxxtest, $tests); +my ($Makefile, $CxxTest_2_Build); + +sub main { + parseCommandline(); + fixFiles(); +} + +sub parseCommandline() { + GetOptions( 'cxxtest=s' => \$cxxtest, + 'tests=s' => \$tests, + ) or usage(); + + usage() unless (defined($cxxtest) || defined($tests)); + $cxxtest = '..\\..' unless defined($cxxtest); + $tests = '../gui/*.h ../*.h' unless defined($tests); +} + +sub fixFiles() { + fixFile( $Makefile, 'Makefile' ); + fixFile( $CxxTest_2_Build, 'CxxTest_2_Build.dsp' ); +} + +sub fixFile($$) { + my ($data, $output) = @_; + + print "$output..."; + + $data =~ s//$tests/g; + $data =~ s//$cxxtest/g; + + open OUTPUT, ">$output" or die "Cannot create output file \"$output\"\n"; + print OUTPUT $data; + close OUTPUT; + + print "OK\n"; +} + +$Makefile = +'# Where to look for the tests +TESTS = + +# Where the CxxTest distribution is unpacked +CXXTESTDIR = + +# Check CXXTESTDIR +!if !exist($(CXXTESTDIR)\cxxtestgen.pl) +!error Please fix CXXTESTDIR +!endif + +# cxxtestgen needs Perl or Python +!if defined(PERL) +CXXTESTGEN = $(PERL) $(CXXTESTDIR)/cxxtestgen.pl +!elseif defined(PYTHON) +CXXTESTGEN = $(PYTHON) $(CXXTESTDIR)/cxxtestgen.py +!else +!error You must define PERL or PYTHON +!endif + +# The arguments to pass to cxxtestgen +# - ParenPrinter is the way MSVC likes its compilation errors +# - --have-eh/--abort-on-fail are nice when you have them +CXXTESTGEN_FLAGS = --gui=Win32Gui --runner=ParenPrinter --have-eh --abort-on-fail + +# How to generate the test runner, "runner.cpp" +runner.cpp: $(TESTS) + $(CXXTESTGEN) $(CXXTESTGEN_FLAGS) -o $@ $(TESTS) + +# Command-line arguments to the runner +RUNNER_FLAGS = -title "CxxTest Runner" + +# How to run the tests, which should be in DIR\runner.exe +run: $(DIR)\runner.exe + $(DIR)\runner.exe $(RUNNER_FLAGS) +'; + +$CxxTest_2_Build = +'# Microsoft Developer Studio Project File - Name="CxxTest_2_Build" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=CxxTest_2_Build - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "CxxTest_2_Build.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "CxxTest_2_Build.mak" CFG="CxxTest_2_Build - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "CxxTest_2_Build - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "CxxTest_2_Build - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "CxxTest_2_Build - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x40d /d "NDEBUG" +# ADD RSC /l 0x40d /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"Release/runner.exe" + +!ELSEIF "$(CFG)" == "CxxTest_2_Build - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x40d /d "_DEBUG" +# ADD RSC /l 0x40d /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /out:"Debug/runner.exe" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "CxxTest_2_Build - Win32 Release" +# Name "CxxTest_2_Build - Win32 Debug" +# Begin Source File + +SOURCE=.\ReadMe.txt +# End Source File +# Begin Source File + +SOURCE=.\runner.cpp +# End Source File +# End Target +# End Project +'; + +main(); + +__END__ +:endofperl + +rem +rem Local Variables: +rem compile-command: "perl FixFiles.bat" +rem End: +rem diff --git a/cxxtest/sample/msvc/Makefile b/cxxtest/sample/msvc/Makefile new file mode 100644 index 000000000..606004d4c --- /dev/null +++ b/cxxtest/sample/msvc/Makefile @@ -0,0 +1,36 @@ +# Where to look for the tests +TESTS = ..\gui\*.h ..\*.h + +# Where the CxxTest distribution is unpacked +CXXTESTDIR = ..\.. + +# Check CXXTESTDIR +!if !exist($(CXXTESTDIR)\cxxtestgen.pl) +!error Please fix CXXTESTDIR +!endif + +# cxxtestgen needs Perl or Python +!if defined(PERL) +CXXTESTGEN = $(PERL) $(CXXTESTDIR)/cxxtestgen.pl +!elseif defined(PYTHON) +CXXTESTGEN = $(PYTHON) $(CXXTESTDIR)/cxxtestgen.py +!else +!error You must define PERL or PYTHON +!endif + +# The arguments to pass to cxxtestgen +# - ParenPrinter is the way MSVC likes its compilation errors +# - --have-eh/--abort-on-fail are nice when you have them +CXXTESTGEN_FLAGS = \ + --gui=Win32Gui \ + --runner=ParenPrinter \ + --have-eh \ + --abort-on-fail + +# How to generate the test runner, `runner.cpp' +runner.cpp: $(TESTS) + $(CXXTESTGEN) $(CXXTESTGEN_FLAGS) -o $@ $(TESTS) + +# How to run the tests, which should be in DIR\runner.exe +run: $(DIR)\runner.exe + $(DIR)\runner.exe diff --git a/cxxtest/sample/msvc/ReadMe.txt b/cxxtest/sample/msvc/ReadMe.txt new file mode 100644 index 000000000..816fce45b --- /dev/null +++ b/cxxtest/sample/msvc/ReadMe.txt @@ -0,0 +1,30 @@ +Sample files for Visual Studio +============================== + +There are three projects in this workspace: + + - CxxTest_3_Generate runs cxxtestgen to create runner.cpp + - CxxTest_2_Build compiles the generated file + - CxxTest_1_Run runs the compiled binary + +Whenever you build this workspace, the tests are run, and any failed assertions +are displayed as compilation errors (you can browse them using F4). + +Note that to run this sample, you need first to create an environment +variable PERL or PYTHON, e.g. PERL=c:\perl\bin\perl.exe + + +To use these .dsp and .dsw files in your own project, run FixFiles.bat +to adjust them to where you've placed CxxTest and your own tests. + +If you want to use just the .dsp files in your own workspace, don't +forget to: + + - Set up the dependencies (CxxTest_3_Generate depends on + CxxTest_2_Build which depends on CxxTest_1_Run) + + - Add your own include paths, libraries etc. to the CxxTest_2_Build project + + +NOTE: I haven't used "Post-Build Step" to run the tests because I +wanted the tests to be executed even if nothing has changed. diff --git a/cxxtest/sample/only.tpl b/cxxtest/sample/only.tpl new file mode 100644 index 000000000..b2a7277cf --- /dev/null +++ b/cxxtest/sample/only.tpl @@ -0,0 +1,33 @@ +// -*- C++ -*- +#include +#include + +int main( int argc, char *argv[] ) +{ + if ( argc < 2 || argc > 3 ) { + fprintf( stderr, "Usage: only []\n\n" ); + fprintf( stderr, "Available tests:\n" ); + CxxTest::RealWorldDescription wd; + for ( CxxTest::SuiteDescription *sd = wd.firstSuite(); sd; sd = sd->next() ) + for ( CxxTest::TestDescription *td = sd->firstTest(); td; td = td->next() ) + fprintf( stderr, " - %s::%s()\n", sd->suiteName(), td->testName() ); + return 1; + } + + const char *suiteName = argv[1]; + const char *testName = (argc > 2) ? argv[2] : 0; + if ( !CxxTest::leaveOnly( suiteName, testName ) ) { + if ( testName ) + fprintf( stderr, "Cannot find %s::%s()\n", argv[1], argv[2] ); + else + fprintf( stderr, "Cannot find class %s\n", argv[1] ); + return 2; + } + + return CxxTest::StdioPrinter().run(); +} + + +// The CxxTest "world" + + diff --git a/cxxtest/sample/parts/Makefile.unix b/cxxtest/sample/parts/Makefile.unix new file mode 100644 index 000000000..5e6ae4e43 --- /dev/null +++ b/cxxtest/sample/parts/Makefile.unix @@ -0,0 +1,39 @@ +# +# (GNU) Makefile for UN*X-like systems +# This makefile shows how to make a different runner for each test +# + +.PHONY: all clean + +all: run + +clean: + rm -f *~ *.cpp *.o runner + +CXXTESTDIR = ../.. +CXXTESTGEN = $(CXXTESTDIR)/cxxtestgen.pl +CXXTESTFLAGS = --have-eh --abort-on-fail + +TESTS = $(wildcard ../*Test.h) +OBJS = runner.o $(TESTS:../%.h=%.o) + +run: runner + ./runner + +runner: $(OBJS) + c++ -o $@ $^ + +%.o: %.cpp + c++ -c -o $@ -I $(CXXTESTDIR) -I .. $^ + +%.cpp: ../%.h + $(CXXTESTGEN) $(CXXTESTFLAGS) --part -o $@ $^ + +runner.cpp: + $(CXXTESTGEN) $(CXXTESTFLAGS) --root --error-printer -o $@ + +# +# Local Variables: +# compile-command: "make -fMakefile.unix" +# End: +# diff --git a/cxxtest/sample/winddk/Makefile b/cxxtest/sample/winddk/Makefile new file mode 100644 index 000000000..8bf25333e --- /dev/null +++ b/cxxtest/sample/winddk/Makefile @@ -0,0 +1,2 @@ +# Standard DDK Makefile +!include $(NTMAKEENV)\makefile.def diff --git a/cxxtest/sample/winddk/Makefile.inc b/cxxtest/sample/winddk/Makefile.inc new file mode 100644 index 000000000..edc6f8c8c --- /dev/null +++ b/cxxtest/sample/winddk/Makefile.inc @@ -0,0 +1,15 @@ +# -*- Makefile -*- + +# +# Tell the DDK how to generate RunTests.cpp from RunTests.tpl and the tests +# + +PERL=perl +PYTHON=python +CXXTESTGEN=$(PERL) $(CXXTESTDIR)/cxxtestgen.pl +#CXXTESTGEN=$(PYTHON) $(CXXTESTDIR)/cxxtestgen.py + +TEST_SUITES=$(SUITESDIR)/*.h + +RunTests.cpp: RunTests.tpl $(TEST_SUITES) + $(CXXTESTGEN) -o $@ --template=RunTests.tpl $(TEST_SUITES) diff --git a/cxxtest/sample/winddk/RunTests.tpl b/cxxtest/sample/winddk/RunTests.tpl new file mode 100644 index 000000000..917f14b4d --- /dev/null +++ b/cxxtest/sample/winddk/RunTests.tpl @@ -0,0 +1,13 @@ +// -*- C++ -*- + +// +// The DDK doesn't handle too well +// +#include + +int __cdecl main() +{ + return CxxTest::StdioPrinter().run(); +} + + diff --git a/cxxtest/sample/winddk/SOURCES b/cxxtest/sample/winddk/SOURCES new file mode 100644 index 000000000..dae014888 --- /dev/null +++ b/cxxtest/sample/winddk/SOURCES @@ -0,0 +1,46 @@ +# -*- Makefile -*- + +# +# Build this sample with the Windows DDK (XP or later) +# +SUITESDIR=.. +CXXTESTDIR=../.. + +# +# Build a user-mode application +# +TARGETNAME=RunTests +TARGETPATH=. +TARGETTYPE=PROGRAM + +# +# Make it a console-mode app +# +UMTYPE=console + +# +# Add CxxTest and tests directory to include path +# +INCLUDES=$(SUITESDIR);$(CXXTESTDIR) + +# +# Enable exception handling and standard library +# +USE_NATIVE_EH=1 +LINKER_FLAGS=$(LINKER_FLAGS) -IGNORE:4099 +386_WARNING_LEVEL=-W3 -WX -wd4290 + +TARGETLIBS=\ + $(CRT_LIB_PATH)\libcp.lib \ + $(CRT_LIB_PATH)\libc.lib + +# +# Only one source file -- the generated test runner +# +SOURCES=RunTests.cpp + +# +# This line tells the build utility to process Makefile.inc +# +NTTARGETFILE0=RunTests.cpp + diff --git a/cxxtest/sample/yes_no_runner.cpp b/cxxtest/sample/yes_no_runner.cpp new file mode 100644 index 000000000..c32b94cd5 --- /dev/null +++ b/cxxtest/sample/yes_no_runner.cpp @@ -0,0 +1,11 @@ +// +// A sample program that uses class YesNoRunner to run all the tests +// and find out if all pass. +// + +#include + +int main() +{ + return CxxTest::YesNoRunner().run(); +} diff --git a/debian/.cvsignore b/debian/.cvsignore new file mode 100644 index 000000000..d7047c667 --- /dev/null +++ b/debian/.cvsignore @@ -0,0 +1,10 @@ +files +postinst.debhelper +postrm.debhelper +substvars +tmp +inkscape +inkscape[^.]* +inkscape.[^amx]* +inkscape.[amx][^ep]* +inkscape.[amx][ep][^mnp]* diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 000000000..648a2f223 --- /dev/null +++ b/debian/changelog @@ -0,0 +1,233 @@ +inkscape (0.42+0.43pre2-1) unstable; urgency=medium + + * Upstream release + + -- Ted Gould Mon, 6 Nov 2005 23:19:00 -0700 + +inkscape (0.42+0.43pre1-1) unstable; urgency=medium + + * Upstream release + + -- Ted Gould Mon, 24 Oct 2005 23:19:00 -0700 + +inkscape (0.42-1) unstable; urgency=medium + + * Upstream release + + -- Ted Gould Tue, 24 Jul 2005 22:23:00 -0700 + +inkscape (0.41+0.42pre3-1) unstable; urgency=low + + * Upstream pre-release + + -- Ted Gould Tue, 21 Jul 2005 20:15:00 -0700 + +inkscape (0.41+0.42pre2-1) unstable; urgency=low + + * Upstream pre-release + + -- Ted Gould Tue, 12 Jul 2005 21:45:00 -0700 + +inkscape (0.41+0.42pre1-1) unstable; urgency=low + + * Upstream pre-release + + -- Ted Gould Mon, 4 Jul 2005 21:45:00 -0700 + +inkscape (0.40+0.41pre3-1) unstable; urgency=low + + * Upstream pre-release + + -- Kees Cook Sat, 5 Feb 2005 21:45:00 -0700 + +inkscape (0.40) unstable; urgency=low + + * New upstream version: + + + First version that supports layers. + + Text on path. + + Improved calligraphy pen, freehand pencil and star tool. + + Three new tutorials. + + More detail at http://www.inkscape.org/cgi-bin/wiki.pl?ReleaseNotes + + -- Peter Moulder Sun, 28 Nov 2004 23:04:36 +1100 + +inkscape (0.39+cvs) unstable; urgency=low + + * Reduce differences from wolfi's official Debian package. + + + Greatly-trimmed changelog entries. + + Sort build-depends. + + -- Peter Moulder Tue, 27 Jul 2004 22:05:07 +1000 + +inkscape (0.39cvs) unstable; urgency=low + + * CVS package + + -- Kees Cook Thu, 15 Apr 2004 12:45:00 -0700 + +inkscape (0.39) unstable; urgency=low + + * New upstream version: + + + New SVG features: markers (aka arrowheads), clones (svg:use), + mostly-complete support for pattern tiles. + + Pango: better text appearance + + New dialogs: Preferences, Find, RDF Metadata + + New documentation, new translations + + See NEWS for a longer list. + + -- Peter Moulder Sun, 18 Jul 2004 11:14:09 +1000 + +inkscape (0.38.1+0.39pre4-1) unstable; urgency=low + + * New upstream version + * upload sponsored by Guido Guenther + + -- Wolfram Quester Tue, 13 Jul 2004 17:32:39 +0200 + +inkscape (0.38.1+0.39pre3-1) unstable; urgency=low + + * New upstream version + * This is upstream version 0.39pre3. The versioning of debian is to make + sure the final version 0.39 is greater than this pre-Versions + * removed "Conflicts: inkscape-cvs" and "Provides: inkscape" from debian/control + because the regular inkscape package should be installable parallel to + inkscape-cvs (if I ever have time to create this one) + * added "Suggests: sketch" to debian/control because inkscape can use sketch + to export eps. + + -- Wolfram Quester Fri, 9 Jul 2004 00:24:02 +0200 + +inkscape (0.38.1-4) unstable; urgency=low + + * added link to the inkscape homepage to debian/control + * added "Conflicts: inkscape-cvs" and "Provides: inkscape" to debian/control + to ensure proper handling of the new inkscape-cvs package + * upload sponsored by Guido Guenther + + -- Wolfram Quester Thu, 10 Jun 2004 16:13:35 +0200 + +inkscape (0.38.1-3) unstable; urgency=low + + * move debian/menu to debian/inkscape.menu. This was needed because upstream + includes a slightly diffent inkscape.menu file. Thanks to Karsten Merker. + * upload sponsored by Karsten Merker + + -- Wolfram Quester Tue, 20 Apr 2004 18:44:45 +0200 + +inkscape (0.38.1-2) unstable; urgency=low + + * fixed wording of package description in debian/control + (thanks to Karsten Merker) + * upload sponsored by Karsten Merker + + -- Wolfram Quester Mon, 19 Apr 2004 15:50:48 +0200 + +inkscape (0.38.1-1) unstable; urgency=low + + * New upstream release to fix two bugs itroduced in the flurry of last-day + activity. + * added my fix to the KEYBINDINGS-section in inkscape.1.in again + * upload sponsored by Guido Guenther and + Karsten Merker + + + -- Wolfram Quester Mon, 12 Apr 2004 21:11:01 +0200 + +inkscape (0.38-1) unstable; urgency=low + + * New upstream release: + Main goal for this release was to fix as many bugs as possible. Apart from + that, some new features and usability enhancements were included. Have a + look at /usr/share/doc/inkscape/NEWS for more information. + * remove debian/inkview.1 since it was included upstream. + * added my fix to the KEYBINDINGS-section in inkscape.1.in again + * don't remove po/*.gmo in debian/rules any longer + * remove debian/examples and dh_installexamples + * upload sponsored by Guido Guenther and + Karsten Merker + + -- Wolfram Quester Thu, 8 Apr 2004 12:24:13 +0200 + +inkscape (0.37-5) unstable; urgency=low + + * remove Guido Guenther from Uploaders + * insert a pair of #ifdef DEBUG_MARKERS ... #endif in + src/dialogs/stroke-style.cpp, sp_stroke_style_set_marker_buttons() + as suggested by + http://cvs.sourceforge.net/viewcvs.py/inkscape/inkscape/src/dialogs/stroke-style.cpp?r1=1.23&r2=1.24&hideattic=0 + (closes: #241668) + * upload sponsored by Guido Guenther + + -- Wolfram Quester Fri, 2 Apr 2004 19:09:03 +0200 + +inkscape (0.37-4) unstable; urgency=low + + * took updated po/es.po from upstream + * remove po/*.gmo in debian/rules + * added mime-type image/svg to debian/mime + * upload sponsored by Guido Guenther + + -- Wolfram Quester Tue, 30 Mar 2004 11:20:18 +0200 + +inkscape (0.37-3) unstable; urgency=low + + * converted inkscape.png to debian/inkscape.xpm and use this icon in the + menus (Trying to avoid lintians menu-icon-not-in-xpm-format) + * use dh_installexamples correctly. inkscape can display them even if + they are gzipped. (Closes: #232254) + * upload sponsored by Guido Guenther + * added manpage for inkview + * fixed KEYBINDINGS-section in inkscape.1 + * added inkscape.applications to have an entry in nautilus' "open with + another application" menu. I still don't know how I get an entry in "open + with" + + -- Wolfram Quester Fri, 13 Feb 2004 01:15:37 +0100 + +inkscape (0.37-2) unstable; urgency=low + + * the ./intltool-* scripts need libxml-parser-perl. + + -- Guido Guenther Wed, 11 Feb 2004 15:36:31 +0100 + +inkscape (0.37-1) unstable; urgency=low + + * new upstream version + * added libsigc++-1.2-dev to Build-Depends + * removed no more existing TODO from debian/docs + * upload sponsored by Guido Guenther + + -- Wolfram Quester Tue, 10 Feb 2004 14:02:10 +0100 + +inkscape (0.36-3) unstable; urgency=low + + * enable installation of debian menus + * install examples to /usr/share/doc/inkscape/ + * added mime-support + + -- Wolfram Quester Tue, 13 Jan 2004 11:36:43 +0100 + +inkscape (0.36-2) unstable; urgency=low + + * fix versioning in debian/changelog + * remove sodipodi changelog from debian/ directory + * add myself to uploaders + + -- Guido Guenther Fri, 26 Dec 2003 23:01:02 +0100 + +inkscape (0.36-1) unstable; urgency=low + + * Initial release in Debian. closes: #220795. + * Adopted package description from Nathan Hurst + + -- Wolfram Quester Thu, 18 Dec 2003 12:36:30 +0100 + +inkscape (0.35-1) unstable; urgency=low + + * Initial release of the new code tree. + + -- Nathan Hurst Wed, 12 Nov 2003 15:33:14 +1100 diff --git a/debian/compat b/debian/compat new file mode 100644 index 000000000..b8626c4cf --- /dev/null +++ b/debian/compat @@ -0,0 +1 @@ +4 diff --git a/debian/control b/debian/control new file mode 100644 index 000000000..01b75a1cb --- /dev/null +++ b/debian/control @@ -0,0 +1,32 @@ +Source: inkscape +Section: graphics +Priority: optional +Maintainer: Nathan Hurst (njh) +Build-Depends: debhelper (>= 4.0.0), intltool, libart-2.0-dev (>= 2.3.10), libgc-dev (>= 1:6.5-1), libglib2.0-dev, libgnomevfs2-dev, libgtk2.0-dev (>= 2.0.6-1), libglibmm-2.4-dev (>> 2.6.1-1), libgtkmm-2.4-dev (>> 2.4.11-2), libgtkspell-dev (>= 2.0.10-3), libpango1.0-dev, libpng12-dev, libpopt-dev, libsigc++-2.0-dev (>= 2.0.10-3), libtool, libxml-parser-perl, libxml2-dev (>= 2.6.0), libxslt1-dev, pkg-config, zlib1g-dev +Standards-Version: 3.6.1 + +Package: inkscape +Architecture: any +Depends: ${shlibs:Depends} +Suggests: dia, libwmf-bin, pstoedit, sketch, libxml-xql-perl +Description: Vector based drawing program + Inkscape loads and saves a subset of the SVG (Scalable Vector Graphics) + format, a standard maintained by the WWW consortium. + . + Inkscape user interface should be familiar from CorelDraw and similar + drawing programs. There are rectangles, ellipses, text items, bitmap + images and freehand curves. + As an added bonus both vector and bitmap objects can have alpha + transparency and can be arbitrarily transformed. + . + Inkscape supports multiple opened files and multiple views per file. + Graphics can be printed and exported to png bitmaps. + . + Homepage: http://www.inkscape.org/ + . + If you wish to import postscript or pdf files, then you need pstoedit + and sketch. + dia is needed only if you wish to import Dia files. + libwmf-bin is needed only if you wish to import Windows metafile + (.wmf) files. + libxml-xql-perl is needed only by the drop-shadow effect. diff --git a/debian/copyright b/debian/copyright new file mode 100644 index 000000000..a816f104f --- /dev/null +++ b/debian/copyright @@ -0,0 +1,38 @@ +This package was debianized by Wolfram Quester on +Wed, 12 Nov 2003 10:39:40 +0100. + +It was downloaded from http://inkscape.sourceforge.net/ + +Upstream Authors: + Hans Breuer + Bulia Byak + Chema Celorio + Zbigniew Chyla + Robert Crosbie + Danilo Egan + Frank Felfe + Ted Gould + Bryce Harrington + Nathan Hurst + Bob Jamison + Lauris Kaplinski + Lynn Kerby + Petr Kovar + Raph Levien + Vitaly Lipatov + Dmitry G. Mastrukov + Michael Meeks + Frederico Mena + MenTaLguY + Yukihiro Nakai + Christian Neumair + Mitsuru Oka + Christian Schaller + Tom von Schwerdtner + Daniel Yacob + Masatake Yamato + +License: GNU GPL + +On Debian systems, the text of the Gnu GPL can be found in +/usr/share/common-licenses/GPL. diff --git a/debian/dirs b/debian/dirs new file mode 100644 index 000000000..15738b85d --- /dev/null +++ b/debian/dirs @@ -0,0 +1 @@ +usr/share/application-registry/ diff --git a/debian/docs b/debian/docs new file mode 100644 index 000000000..50bd824bb --- /dev/null +++ b/debian/docs @@ -0,0 +1,2 @@ +NEWS +README diff --git a/debian/inkscape.applications b/debian/inkscape.applications new file mode 100644 index 000000000..842b83737 --- /dev/null +++ b/debian/inkscape.applications @@ -0,0 +1,7 @@ +inkscape + command=inkscape + name=inkscape + can_open_multiple_files=true + expects_uris=false + requires_terminal=false + mime_types=image/svg,image/svg+xml diff --git a/debian/inkscape.menu b/debian/inkscape.menu new file mode 100644 index 000000000..2af2c6611 --- /dev/null +++ b/debian/inkscape.menu @@ -0,0 +1,5 @@ +?package(inkscape): needs="X11" section="Apps/Graphics"\ + hints="Vector"\ + title="Inkscape" command="/usr/bin/inkscape"\ + icon="/usr/share/pixmaps/inkscape.xpm"\ + longtitle="Vector based drawing program" diff --git a/debian/inkscape.xpm b/debian/inkscape.xpm new file mode 100644 index 000000000..33cae69d2 --- /dev/null +++ b/debian/inkscape.xpm @@ -0,0 +1,95 @@ +/* XPM */ +static char * inkscape_xpm[] = { +"32 32 60 1", +" c None", +". c #000000", +"+ c #050505", +"@ c #646464", +"# c #404040", +"$ c #232323", +"% c #C9C9C9", +"& c #FFFFFF", +"* c #FEFEFE", +"= c #939393", +"- c #070707", +"; c #5F5F5F", +"> c #F2F2F2", +", c #CECECE", +"' c #252525", +") c #030303", +"! c #9E9E9E", +"~ c #5A5A5A", +"{ c #9C9C9C", +"] c #FBFBFB", +"^ c #9B9B9B", +"/ c #0D0D0D", +"( c #707070", +"_ c #D1D1D1", +": c #ADADAD", +"< c #565656", +"[ c #929292", +"} c #C7C7C7", +"| c #272727", +"1 c #1B1B1B", +"2 c #F8F8F8", +"3 c #656565", +"4 c #636363", +"5 c #DADADA", +"6 c #181818", +"7 c #171717", +"8 c #454545", +"9 c #3A3A3A", +"0 c #EDEDED", +"a c #0A0A0A", +"b c #1A1A1A", +"c c #BBBBBB", +"d c #1F1F1F", +"e c #020202", +"f c #525252", +"g c #010101", +"h c #3D3D3D", +"i c #1C1C1C", +"j c #505050", +"k c #0B0B0B", +"l c #060606", +"m c #080808", +"n c #878888", +"o c #999A9A", +"p c #7A7C7C", +"q c #484949", +"r c #282828", +"s c #202020", +"t c #555656", +"u c #808282", +" ", +" .... ", +" .+@#.. ", +" .$%&*=-. ", +" .;>&&&&,'. ", +" )!&&&&&&&>~. ", +" .{&&&]&&&&&&^/ ", +" .(&&&_:&&&&&<[}| ", +" .12&&&34&&>5&6.78. ", +" ..9&&&0ab*cdefg..... ", +" ...d( +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# + +PN=`basename $0` +VER="0.8.1+inkscape" + +# +# Fatal($msg,$retval) +# +# Display an error message to stderr and exit +# +Fatal () { + echo -e "${PN}: $1\nTerminating...." 1>&2 + test -n "$2" && exit $2 + exit 1 +} + + +# +# Help() +# +# Display help information and exit +# +Help () { + cat <. +EOF + exit 0 +} + +# +# Version() +# +# Display version information and exit +# +Version () { + cat < SPDocument + SPImage + SPPath -> SPShape -> SPRect + -> SPEllipse + -> SPChars -> SPText diff --git a/doc/ChangeLog_archive.txt b/doc/ChangeLog_archive.txt new file mode 100644 index 000000000..ab5c262e4 --- /dev/null +++ b/doc/ChangeLog_archive.txt @@ -0,0 +1,10577 @@ +See ChangeLog for newer entries + +2004-03-31 Ted Gould + + * src/interface.cpp: Changing the default size so that it matches + the default template size. This way, for blank documents, the + window doesn't open and then resize. + +2004-03-31 Ted Gould + * src/file.cpp, src/dialogs/filedialog.cpp, src/extension/db.cpp, + src/extension/db.h, src/extension/system.cpp: + A bunch of changes for Bulia's bug 925875. Basically now the + save dialog remembers which extension you've used. This also + means that save works with non-standard extensions. Also, it + will add extensions for you if you didn't put them on. Finally, + the error dialog doesn't come up if you hit cancel in the + 'Save As...' dialog. Whew! + + * src/preferences-skeleton.h: Added in settings to make the save + extension global, along with whether or not the files should have + extensions tacked on the end of them. + +2004-03-31 Ted Gould + + * src/interface.cpp, src/interface.h, src/file.cpp: + Adding a cute little dialog to tell you if you are about to + overwrite a file you want to keep. This fixes bug #911237 + +2004-03-30 Jon Phillips + + * share/icons/icons.svg src/interface.cpp src/verbs.cpp src/verbs.h: + Added rest of icons for the menu. I think they are a good start. + There still needs to be continuity between styles, but at least + all needed icons are present. I didn't create icons for elements + that are going to be removed eventually. + + * share/tutorials/tipsandtricks.svg src/help.cpp src/interface.cpp: + Added this tutorial so that people can consolidate their information + onto this page. + +2004-03-30 Ted Gould + + * src/file.cpp, src/file.h, src/dialogs/filedialog-win32.cpp, + src/dialogs/filedialog.cpp, src/dialogs/filedialog.h + src/extension/system.cpp, src/extension/system.h, + src/extension/implementation/script.cpp: + Making all of the file operations have lists of the extensions + that can be used to save and open. This also fixes the bug + which talks about mis-saving file without an error - there is + an error message now. Probably not the most clear, but you + won't miss it. + +2004-03-29 Peter Moulder + + * src/helper/bezier-utils-test.cpp: Finish the sp_bezier_fit_cubic test. + + * src/dyna-draw-context.cpp, src/mod360.cpp, src/mod360.h, + src/Makefile.am: Move mod360 to new files mod360.cpp, mod360.h. + Add unit test for it. + +2004-03-28 Bryce Harrington + + * inkscape.cpp, inkscape.h, xml/repr-io.cpp, xml/repr.h: Adding + better error handling for the situation where the + preferences.xml file is not successfully loaded. In this case, + we want to suppress saving it, lest we overwrite the file with + the default skeleton preferences. + +2004-03-28 Jon Phillips + + * src/interface.cpp src/select-toolbar.cpp src/verbs.cpp src/verbs.h: + Changed rotate verb to be SP_VERB_OBJECT_ROTATE_90_CW so that I can + now install SP_VERB_OBJECT_ROTATE_90_CCW. + + * share/icons/icons.svg src/interface.cpp src/select-toolbar.cpp + src/selection-chemistry.cpp src/selection-chemistry.h + src/verbs.cpp src/verbs.h: Added rotation 90 degrees CCW to the menu, + icons, and the interface. It was a pretty simple thing to do but was + not available on the interface. + +2004-03-28 MenTaLguY + + * src/sp-gradient.cpp: request SP_OBJECT_MODIFIED_FLAG if gradient stops + are added or removed + +2004-03-27 bulia byak + + * src/main.cpp: Removed redundancy in error messages, reworded some + + * src/verbs.cpp src/toolbox.cpp src/nodepath.cpp src/inkscape.cpp + src/extension/internal/ps.cpp src/main.cpp: Typos, reported by Arpad Biro + + * AUTHORS: Added John Cliff, Fred (long overdue), Adib + + * src/widgets/gradient-vector.cpp: John Cliff: multistage gradient editor + + * src/splivarot.cpp src/style.cpp src/xml/repr-util.cpp src/sp-polygon.cpp: + Adib's svgostringstream patches + + * src/toolbox.cpp: All default buttons work correctly with undo, use freezing to + prevent double changes; tooltip edits, formatting; defocusing on all widgets + + * src/display/nr-arena-image.cpp: Tentative fix for 906376: image always uses + _P_P_P_ compositing + + * src/dialogs/item-properties.cpp: Refixing the slider 0.99 problem properly, + reported by simarilius + + * src/help.cpp src/help.h src/interface.cpp: Expanded and split tutorial, all + tutorials in submenu + + * src/sp-text.cpp: Do not write dx/dy if they only contain 0s + + * src/verbs.cpp src/verbs.h src/splivarot.cpp src/splivarot.h src/shortcuts.cpp: + Inset/outset by pixels: commands, keys + + * src/preferences-skeleton.h: Default nudge 2pt + + * src/event-context.cpp: Increased accelerated-scroll delay + + * src/sp-text.cpp,h src/text-context.cpp: Clicking positions cursor closest to + the click point + + * src/extension/internal/ps.cpp: Print dialog transient; Enter activates print; + patches from sodi to flush stream and add boundingBox to PS output + + * src/dialogs/xml-tree.cpp: XML editor watches desktop change + + * src/sp-root.cpp: Fix from sodi: default preserveAspectRatio value + + * src/libnrtype/nr-type-w32.cpp: Fix for 915440 (from sodi) + +2004-03-27 Peter Moulder + + * src/dyna-draw-context.cpp (sp_dyna_draw_context_set): + Tweak angle setting: prefer 0.0 instead of 360.0. + + * src/dyna-draw-context.h, src/dyna-draw-context.cpp: Cleanup: + Greater conformance to CodingStyle. Mostly whitespace changes. + +2004-03-24 Ted Gould + + * src/extension/db.[ch]: Adding in functions to get lists of + input and output extensions for the file dialogs + +2004-03-25 Alexander Clausen + + * src/inkview.cpp Fix inkview crash on startup + +2004-03-24 Ted Gould + + * Minor changes to get distcheck to work. + +2004-03-24 Peter Moulder + + * src/draw-context.h, src/draw-context.cpp: Cleanup: greater + conformance to CodingStyle. Mostly whitespace changes. + +2004-03-23 Peter Moulder + + * src/widgets/sp-widget.h, src/widgets/sp-widget.cpp + (sp_widget_new_repr): Remove this unused function. + + * src/libnrtype/nr-rasterfont.cpp (nr_rasterfont_ensure_glyph_slot): + Address compiler warning. + + * src/seltrans.cpp (sp_sel_trans_ungrab): Disable the persistent + snapping stuff added 2004-02-19. + + * src/desktop-events.cpp (sp_dt_ruler_event): Minor cleanup. + +2004-03-19 bulia byak + + * src/selection-chemistry.cpp: Prevent it from scaling above 1e6 pt + + * src/preferences-skeleton.h src/dialogs/dialog-events.cpp: "Skip taskbar" hint + for dialogs + + * src/selection-chemistry.cpp: Patch for copying gradients from johncliff + + * src/event-context.cpp: Increased accelerated-scroll delay + + * nr-pixops.h: INK_COMPOSE: Always-visible inversion compose method + + * sp-gradient.cpp: Default linear gradient goes through center + + * nr-plain-stuff.cpp: Tweaked checkerboard size and color + + * gradient-position.cpp: Inverse colors for handles, axes, and bbox; dragging + snaps with Ctrl; radius handle in radial gradient + + * src/sp-rect.cpp src/sp-path.cpp: Finished fixing 918478 + + * src/gradient-chemistry.cpp src/widgets/gradient-vector.cpp: Fix for 902319, + remove some debug output + + * src/toolbox.cpp: Polygon mode off by default + + * src/toolbox.cpp: Crash fix, reported by David Christian Berg + + * src/radial.h src/nodepath.cpp: Moved Radial:: to nodepath.h for now + + * stringstream.h: New stream class for serialization + + * svg-path.cpp: Use new stream class + + * src/toolbox.cpp: Smarter Sharpness, r1 and r2 undistinguishable for the user + + * src/svg/svg-path.cpp: Restore mising break (fixes smearing for paths with h and v) + + * src/dialogs/align.cpp src/dialogs/transformation.cpp: Reverse pjrm's change in delete + handlers (fixes crash on closing) + + * src/splivarot.cpp: Simplify threshold depends on selection size, not item size + + * src/select-toolbar.cpp: Reordered select toolbar buttons + + * icons.svg: Reworked selector toolbar icons + +2004-03-17 Ted Gould + + * src/extension/db.h, src/extension/db.cpp, src/extension/extension.cpp, + src/extension/system.cpp: Changing the database stuff to be C++ + object oriented (actually it wasn't OO before). But this helps + as we start to connect to the File dialogs. + +2004-03-16 Ted Gould + + * src/file.cpp, + src/file.h, + src/extension/Makefile.am, + src/extension/extension.cpp, + src/extension/extension.h, + src/extension/menu.cpp, + src/extension/system.cpp, + src/extension/implementation/implementation.cpp, + src/extension/implementation/implementation.h, + src/extension/implementation/script.cpp, + src/extension/implementation/script.h: + A few of changes. + 1) removed the extensions menu stuff from the build as it seems + no one is using it. + 2) Changing Filter to Effect internally to the extensions + 3) Adding an exception to the save and open extensions to + signal a failure. There is no way to test this currently, + but it doesn't break anything. + +2004-03-16 jon phillips + + * share/icons/icons.svg: Added a couple of icons but haven't linked them + to the code yet. + + * share/tutorials/elementsofdesign.svg: Added the first part of the + basic graphics for this tutorial. I added boxes for the rest, which + I need to finish. I need to use Bulia's tutorial top part to keep + the tutorials consistent. + +2004-03-16 bulia byak + + * nr-type-directory.cpp: Cache NRTypeFaceDef *, not NRTypeFace *, fixes 916155 + + * src/arc-context.cpp src/arc-context.h src/event-context.h src/rect-context.cpp + src/spiral-context.cpp src/spiral-context.h src/star-context.cpp + src/star-context.h src/toolbox.cpp: John Cliff's patch #2 for shape tools, + with my fixes + + * icons.svg: Tweaks: stroke to curve, flip/rotate, text + + * src/sp-ellipse.cpp: Fixes: SPArc never writes ; in d=, no L to the center when start==end + + * src/nodepath.cpp: Fix for 916119 + + * src/widgets/icon.cpp: Remove not-enough-room-for-icon warning + + * src/dialogs/text-edit.cpp src/dialogs/dialog-events.cpp: Do not eat key events in the text view + +2004-03-15 Peter Moulder + + * src/widgets/gradient-vector.cpp + (sp_gradient_vector_widget_load_gradient, sp_gradient_vector_color_dragged): + Cleanup: Convert to table-driven style. + + * src/style.cpp (sp_style_read_from_object): Additional check. + + * src/rect-context.cpp: Cleanup: Coding Style conformance, + move declarations to first use. + + * src/sp-gradient.cpp (sp_gradient_rebuild_vector): Add assertion. + +2004-03-15 Ted Gould + + * src/extension/extension.cpp: Adding in some comments for my + previous checkin and also adding in the integer functions that + I forgot (but aren't used yet). + +2004-03-14 Jon Phillips + + * src/toolbox.cpp src/verbs.cpp src/interface.cpp + share/icons/icons.svg: Added all the icons in the VIEW + menu. They might need some tweaking, but its a start. Also + cleaned up some coding conventions for these files. + +2004-03-14 Bryce Harrington + + * src/view.cpp: Adding an accumulator function for checking + return values of shutdown signal handlers, so that if any one of + them returns a value indicating an abort of the shutdown, the + shutdown process will be aborted. + +2004-03-14 Ted Gould + + * src/extension/extension.cpp, src/extension/extension.h, + src/extension/internal/ps.cpp: Adding in parameters for extensions. + This will make it so that extensions can have easy settings that + are used. They are not currently persistent - but that will be + a future feature. + +2004-03-14 MenTaLguY + + * src/ast/*: more AST sketching + + * src/xml/repr.cpp: existing listeners were getting dropped when new + listeners were added; this fix makes the behavior documented in + bug #896706 a little worse, but fixes bug #915913 + + * src/sp-use.cpp: SPUse does not need to manually detach its child + anymore, so now it doesn't + + * src/sp-object.cpp: detach our SPRepr listener before we start + releasing our children, which makes listener removal faster (since + we are then always removing from the beginning of the listener + list -- i.e. removing in roughly the order in which they were added) + This should help bug #896706 a little more. + + * src/event-context.cpp, src/node-context.cpp, src/rect-context.cpp, + src/sp-object.cpp, src/sp-offset.cpp, src/dialogs/desktop-properties.cpp, + src/dialogs/xml-tree.cpp, src/widgets/sp-widget.cpp, + src/widgets/sp-xmlview-attr-list.cpp, src/widgets/sp-xmlview-tree.cpp, + src/xml/repr-private.h, src/xml/repr-util.cpp, src/xml/repr.cpp, + src/xml/repr.h: + SPObjects now ::write() immediately on attribute changes, if those + changes are "interactive" (i.e. from the XML editor); this fixes + the problem with SPStar's points= attribute updating (bug #910142) + + * src/sp-clippath.cpp, src/sp-mask.cpp, src/sp-namedview.cpp, + src/sp-root.cpp, src/sp-symbol.cpp: + simplified SPObject::remove_child handlers, focusing particularly + on making them not rely on the repr still being attached + + * src/sp-object.cpp: SPObject::remove_child is now invoked after + the repr has been removed (fixes bug #916188) + + * src/text-context.cpp: don't unparent the repr if it's already + been unparented (fixes bug #915435) + +2004-03-14 rejon + + * src/toolbox.cpp share/icons/icons.svg: Cleaned the file up to coding + standards. I also have begun to add new icons to our program. + +2004-03-13 MenTaLguY + + * src/document.cpp: bumped the update limit on documents a bit + (bug #896076) + + * src/sp-text.cpp: SPString now copes with parents that don't have style + information (comment on bug #896706) + + * src/xml/repr.cpp, src/xml/repr-private.h: + adding listeners is now O(1), which should make files which make heavy + use of more tolerable; I decided to add an extra "last" pointer + rather than just prepending to the list (which would have reversed + its order, and make the common case for removal traverse the entire + list -- removal is still O(N) overall, but at least this way we usually + hit the best-case) (bug #896076) + +2004-03-11 bulia byak + + * src/sp-item.h src/sp-item.cpp: Restore i2root_affine: same as i2doc but + without c2p, fixes 914039 + + * src/selection-chemistry.cpp: Grouping z-order fix + + * src/path-chemistry.cpp: Combine/Break Apart fixes: preserve z-order and + parent, diagnostics, multiple selected, cleanup, fixes + + * src/libnrtype/nr-type-directory.cpp: Fix win32 memory hog (unfreed + g_ascii_tolower in ink_strstr), implement caching of looked-up faces + +2004-03-10 bulia byak + + * src/sp-offset.cpp: Coalesce threshold depends on item size (less transform), + guarding against invalid item bbox, comments + + * src/sp-text.cpp: TODO comment for effective_dx/dy + + * src/splivarot.cpp src/preferences-skeleton.h: Inset/Outset handle multiple + selections, preserve z-order and grouping; Simplify handles multiple + selections, preserves z-order and grouping, threshold taken from prefs, + accelerated + + * src/node-context.cpp src/text-context.cpp: Disregard groups when clicking + + * src/shortcuts.cpp: Ctrl+/ for division, ctrl-alt-/ for slice (cut path), + bigger window for keys + + * src/rect-context.cpp src/rect-context.h: Knotholder, signals and listeners, + selection by click, tolerance, Esc deselects + + * src/toolbox.cpp: Rect toolbar: Spinbuttons cosmetics, keys, defocusing, + tooltips, fixes + + * src/shortcuts.cpp: Ctrl+e zooms to window, export is ctrl+shift+e now + + * src/selection-chemistry.cpp: Z-order fixes: Raise rewritten, diagnostics, + relative raise/lower only for overlapping objects + + * src/verbs.cpp: raise/lower commands named more consistently + + * src/sp-item.cpp src/sp-item.h: Sorting function for items + + * src/selection-chemistry.cpp: fix for 910017 + + * src/splivarot.cpp: Remove fill for slice + +2004-03-09 rejon + + * samples: Moved the contents of samples into the proper share dirs. + + * share/tutorials/tutorial.svg: Moved the default tutorial.svg to this + location. It was in the wrong place. + + * share/tutorials/elementsofdesign.svg src/help.cpp src/interface.cpp: + Added the textual gloss of this new tutorial. I need to add some + more graphics to it. But I just wanted to first of all flesh out + the document so that others could chunk in graphics and so + forth. + +2004-03-09 MenTaLguY + + * src/ast/*: more AST work + + * src/sp-text.cpp: fixed uninitialized variable + + * src/sp-text.cpp: rewrote recursive character-counting algorithm + +2004-03-08 MenTaLguY + + * src/sp-text.cpp: fixes for initialization and updating of SPString + +2004-03-07 MenTaLguY + + * src/sp-item.cpp: the item's arenaitems shouldn't be destroyed until + its children have had a chance to clean up + + * src/sp-object.cpp: fix sp_object_reorder() to correctly handle + next == NULL + + * src/sp-item.cpp, src/sp-object-group.cpp, src/sp-object-repr.cpp, + src/sp-object.cpp, src/sp-object.h, src/sp-text.cpp, src/sp-use.cpp: + finished transition to SPObject::children + + * src/sp-text.cpp: reworked SPTSpan a bit so that it copes with + the child changes a little better with respect to SPTSpan::string + +2004-03-06 MenTaLguY + + * src/ast/*: initial work on AST code + + * src/libnr/nr-convex-hull-ops.h, src/libnr/nr-convex-hull.h, + src/libnr/nr-matrix-fns.h, src/libnr/nr-maybe.h, + src/libnr/nr-rect-ops.h: + basic cleanups and work on NR::ConvexHull + + * src/document.cpp, src/gradient-chemistry.cpp, + src/selection-chemistry.cpp, src/selection.cpp, src/sp-clippath.cpp, + src/sp-defs.cpp, src/sp-defs.h, src/sp-gradient.cpp, src/sp-gradient.h, + src/sp-item-group.cpp, src/sp-item-group.h, src/sp-item.cpp, + src/sp-item.h, src/sp-mask.cpp, src/sp-namedview.cpp, + src/sp-object-group.cpp, src/sp-object-group.h, src/sp-object-repr.cpp, + src/sp-object.cpp, src/sp-object.h, src/sp-pattern.cpp, src/sp-pattern.h, + src/sp-root.cpp, src/sp-text.cpp, src/sp-text.h, + src/widgets/gradient-vector.cpp: + + children are now uniformly handled by SPObject + +2004-03-05 bulia byak + + * src/desktop.cpp src/preferences-skeleton.h: Autoscroll now accepts + distance-from-edge parameter, may be negative, default is + options.autoscrolldistance = -10 + + * src/style.cpp src/style.h src/document.cpp: Store uri for paintsever and + serialize it back instead of paintserver id. find_items functions do not find + insensitive items by default. + + * src/sp-item.cpp: tentative fix: do not remove style attribute if + write_difference fails or object has no parent + + * src/desktop-events.cpp: transientize guide dialog + + * splivarot.cpp, livarot/*: fred's new rasterizer, fixes + + * src/widgets/gradient-vector.cpp: fix 906301 + + * src/dialogs/text-edit.cpp: do not rebuild text of object if not changed in the + dialog, fixes 906279 + + * src/selection.cpp: suppress a few meaningless warnings + + * src/xml/repr.cpp: fix for 907056, 906222 + + * about.svg: redrawn from rejon's draft, with a highlight on lauris :) + + * libnrtype: Full font-variant, font-weight, font-stretch support. Better family + and style matching algorithm. Support for generic families and multiple family + specifications. Xft sees all font styles, reads pfa fonts again. Font styles + are sorted in the list and use the native style names with Xft. + + * src/sp-text.cpp,h src/text-context.cpp: Keys, function for adjusting linespacing + + * keys.xml,svg,html: Linespacing keys + +2004-03-05 Peter Moulder + + * src/draw-context.cpp (fit_and_split, + sp_pencil_context_root_handler, spdc_add_freehand_point): + * src/dyna-draw-context.cpp (sp_dyna_draw_timeout_handler, + sp_dyna_draw_context_root_handler, fit_and_split_line, + fit_and_split_calligraphics): + Cleanups. + + * src/Makefile.am: Fix missing backslash at end of line. + +2004-03-05 Ted Gould + * src/extension/impelementation/implementation.cpp, + src/extension/impelementation/implementation.h, + src/extension/impelementation/script.h, + src/extension/impelementation/script.cpp: + Adding in some more comments and doing some general cleanup + of the code. It is getting better everyday. + +2004-03-05 Ted Gould + + * src/Makefile.am: Adding back in inkview. This was fixed by + Bob, but he didn't add it back in. It's back in the build now. + Thanks Bob for fixing my mistakes! + +2004-03-04 Ted Gould + + * src/extension/extension.h: Cleaning up and adding comments. + +2004-03-04 Peter Moulder + + * src/livarot/Shape.cpp (Distance): Convert to DistanceLE(p, d) + function returning true iff Distance(p) <= d. (Saves 7% of total + inkscape CPU time for "big scribbles" test cases.) Update callers. + +2004-03-04 Ted Gould + + * src/extension/system.cpp, src/extension/system.h, + src/extension/extension.cpp, src/extension/extension.h, + src/extension/init.cpp, src/extension/internal/gnome.cpp, + src/extension/internal/ps.cpp, src/extension/internal/svg.cpp, + src/extension/internal/win32.cpp: + Making it so that an implementation is a require element to + build an extension. This means that checking for one in every + other function is not required. Makes a touch more sense. + +2004-03-04 Jon A. Cruz + + * src/file.cpp, src/interface.cpp, src/inkscape-stock.cpp, + src/sp-image.cpp, src/helper/png-write.cpp, + src/widgets/icon.cpp: + Fixed filename/URI translation to keep UTF-8 internally. + +2004-03-03 Peter Moulder + + * src/seltrans.cpp (sign): + New function to replace `FOO / fabs(FOO)' expressions in various places. + * src/seltrans.cpp (sp_sel_trans_stretch_request, sp_sel_trans_stretch): + Fix #906221. Also change the behaviour to allow growing. + + * src/libnr/nr-scale.h: operator[]: new versions returning writable reference. + + * src/desktop-snap.h, src/desktop-snap.cpp + (sp_desktop_vector_snap_list): + Change final arg from NR::Point to NR::scale. Update callers. + +2004-03-02 Ted Gould + + * src/Makefile.am, src/print.cpp, + src/extension/db.cpp, src/extension/db.h, + src/extension/extension.cpp, src/extension/extension.h, + src/extension/system.cpp, src/extension/system.h, + src/extension/init.cpp, src/extension/menu.cpp, + src/extension/impelementation/Makefile.am, + src/extension/impelementation/implementation.cpp, + src/extension/impelementation/implementation.h, + src/extension/impelementation/script.h, + src/extension/impelementation/script.cpp, + src/extension/internal/gnome.cpp, src/extension/internal/gnome.h, + src/extension/internal/ps.cpp, src/extension/internal/ps.h, + src/extension/internal/svg.cpp, src/extension/internal/svg.h, + src/extension/internal/win32.cpp, src/extension/internal/win32.h: + + Turning the extensions stuff into having C++ objects instead + of GTK+ objects. This affected a lot of files. + +2004-03-02 Peter Moulder + + * src/helper/curve.h, src/helper/curve.cpp + (sp_curve_new_from_foreign_bpath and many static functions): + Mark various ArtBpath[] parameters as not being written to. + + * src/draw-context.cpp (fit_and_split): Fix to fix to edge case in + freehand tool. (Hopefully to be replaced by different approach.) + + * src/dialogs/transformation.cpp (sp_transformation_move_apply, + sp_transformation_scale_apply, sp_transformation_rotate_apply, + sp_transformation_skew_apply): + Remove unused `copy' parameter. Update caller. + + * src/dialogs/align.cpp, src/dialogs/transformation.cpp: Cleanups. + + * src/display/nr-arena-shape.cpp (nr_arena_shape_set_path): + Remove affine argument (all current callers were passing NULL) and + unused `lieutenant' argument. Update callers. + + * src/selection-chemistry.h, src/selection-chemistry.cpp + (sp_selection_delete, sp_selection_duplicate, sp_edit_clear_all, + sp_edit_select_all, sp_selection_group, sp_selection_ungroup, + sp_selection_raise, sp_selection_raise_to_top, sp_selection_lower, + sp_selection_lower_to_bottom, sp_selection_cut, sp_selection_copy, + sp_selection_paste, sp_selection_paste_style): + Remove unused parameters. Update callers. + +2004-03-01 Nathan Hurst + + * src/draw-context.cpp: Fixed edge case in freehand tool. Added + comment about curve fitting. + +2004-03-01 Peter Moulder + + * src/sp-guide.cpp (sp_guide_set_property, sp_guide_get_property): + Minor cleanups. + + * src/interface.h, src/interface.cpp + (sp_ui_new_view, sp_ui_new_view_preview): Make static. + + * src/dyna-draw-context.cpp (sp_ddc_defaults): + * src/rect-context.cpp (sp_rc_defaults): + Cleanup: Use table and loop instead of copy&paste. + + * configure.in: If -Wno-unused-parameter isn't recognized (g++ 3.2 and + earlier) then use -Wno-unused. + + * src/libnr/nr-point.h: NR::Point: Add explicit copy constructor and + operator= in the hope of fixing #907059. + + * src/desktop-events.cpp (sp_dt_ruler_event): NR::Point'ification. + + * src/selection.cpp (sp_selection_item_selected): + * src/seltrans.cpp (sp_sel_trans_stretch_request): + * src/display/nr-arena-shape.cpp (shape_run_A8_OR): + * src/livarot/PathStroke.cpp (DoJoin): + * src/livarot/ShapeMisc.cpp (ReFormeBezierTo): + Address compiler warnings. + +2004-02-28 Jon Phillips + + * share/*: Move extensions, icons, and made a new folder screens + for screens that are pulled up in using inkscape. Please test + this heavily as it implements the most troublesome chunks of the + directory reorganization. + + * Makefile.am, Makefile.mingw, config.h.mingw, configure.in: + Changed to coincide with the new changes. + +2004-02-28 Nathan Hurst + + * src/nodepath.cpp,h: Moved radial to class Radial. Moved + NodePath into namespace Path and partially classified. + +2004-02-28 Peter Moulder + + * src/nodepath.cpp: Mark several functions as static. + + * src/dialogs/stroke-style.cpp: Rename DEBUG_MARKERS ifdef to + WITH_MARKER_GUI, and make more things conditional on it. + (Fixes failing assertion for the !defined case.) + +2004-02-27 Alexander Clausen + + * src/desktop-events.cpp: fix my last fix *sigh* + + * src/inkview.cpp: fix inkview crash when none of the files + on commandline exist, add very basic error reporting + +2004-02-27 Peter Moulder + + * src/dialogs/stroke-style.cpp (sp_stroke_style_set_marker_buttons): + Cleanup: restructure. + + * src/dialogs/Makefile.am: in-dt-coordsys.cpp, in-dt-coordsys.h: + New files. + * src/dialogs/xml-tree.cpp (set_dt_select): Fix bug when clicked on a + shape that's a descendent of a node: don't try to select it + in the canvas. + +2004-02-26 Peter Moulder + + * src/dialogs/stroke-style.cpp: + Fix: free marker_xpm[i] instead of marker_xpm. + Misc cleanups. + + * src/Makefile.am: New files extract-uri.cpp, extract-uri.h. + New unit test extract-uri-test.cpp. + * src/style.cpp (extract_uri): Move to src/extract-uri.cpp, and fix. + + * src/Makefile.am (inkscapelib_src): + marker-status.h, marker-status.cpp: New files. + * src/dialogs/stroke-style.cpp, src/sp-shape.cpp, src/style.cpp: + Change marker debugging status messages from conditional g_message + to unconditional marker_status call. + + * src/dialogs/stroke-style.cpp (marker_id_to_string): + Remove unused function. + +2004-02-24 Alexander Clausen + + * src/desktop-events.cpp: Fix crash when opening the guide dialog for + the second time + +2004-02-24 bulia byak + + * src/helper/sodipodi-ctrlrect.cpp: A smart always-visible inversion for ctrlrect border + + * src/select-toolbar.cpp: Fix for 873723 + + * src/style.h src/style.cpp: write_difference only writes what is .set in the target style + + * src/selection-chemistry.cpp: Paste style merges the style of the clipboard + with the object's current style + + * src/xml/repr-io.cpp: Do not cut leading/trailing whitespace on text nodes, + only reject all-whitespace nodes + + * src/pixmaps/handles.xpm src/seltrans.cpp src/knot.cpp src/nodepath.cpp + src/helper/sodipodi-ctrl.cpp: Changed xor compositing for ctrls, made seltrans + handles inverse, tweaked knot colors + + * doc/keys-html.xsl doc/keys.html: keys.html now validates + + * src/desktop.cpp src/desktop.h: New function to autoscroll desktop so a point + becomes visible + + * src/rubberband.cpp src/select-context.cpp src/nodepath.cpp: Use the new + function to scroll desktop to a point + + * src/desktop.cpp src/preferences-skeleton.h: options.autoscrollspeed + +2004-02-24 Peter Moulder + + * src/libnr/nr-matrix.h: Add `explicit' to Matrix constructors + from rotate/scale/translate, to reduce the number of mysterious + implicit conversions used in client code. + Don't #include nr-rotate-ops.h, nr-scale-ops.h, nr-translate-ops.h. + + * src/selection-chemistry.cpp (sp_selection_apply_affine): + Change final argument from double[6] to NR::Matrix. + Update callers. + (sp_selection_scale_relative): Change from dx,dy to NR::scale argument. + Update callers. + (sp_selection_scale, sp_selection_scale_times): Cleanup. + + * src/libnr/Makefile.am: + New files nr-rotate-test.cpp, nr-scale-test.cpp, nr-translate-test.cpp. + * src/libnr/nr-matrix-test.cpp: Move lots of things to the new files. + Add tests for the operator* additions of 2004-02-23. + Don't #include .cpp files where linking against them suffices. + + * src/livarot/Makefile.am (Path_test_LDADD): Fix order of libs. + + * src/select-toolbar.cpp (sp_object_layout_any_value_changed): + NR::Matrix'ification. + +2004-02-23 MenTaLguY + + * src/selection-chemistry.cpp, src/selection-chemistry.h, + src/seltrans.cpp, src/seltrans.h, src/verbs.cpp, + src/dialogs/transformation.cpp, src/libnr/nr-point-fns.h, + src/libnr/nr-point.h, src/libnr/nr-rect.h: more NRPoint removal + +2004-02-23 Peter Moulder + + * src/sp-item-transform.cpp (sp_item_rotate_rel): + Use NR::Rect and .midpoint. + + * src/dropper-context.cpp (sp_dropper_context_root_handler): + * src/sp-text.cpp (sp_string_set_shape): + Cleanup: use translate rather than setting individual matrix elements. + + * src/libnr/nr-matrix-ops.h (operator*: Matrix*rotate, translate*scale, + scale*translate, Matrix*scale): New functions. + +2004-02-22 Ted Gould + + * src/extension/Makefile.am, src/extension/implementation/Makefile.am, + src/Makefile.am, po/POTFILES.in, po/*.po (because of previous change): + Okay, I screwed up. Here are some distcheck fixes for various + things. Still not entirely clean. But these are much closer + than we were. + +2004-02-22 Ted Gould + + * src/modules -> src/extensions: + Changing the directory name so that it fits the new naming + conventions that we're working with. + +2004-02-23 Peter Moulder + + * src/desktop.cpp (sp_desktop_init, sp_desktop_set_display_area): + * src/libnrtype/nr-font.cpp (nr_font_generic_glyph_outline_get): + * src/libnrtype/nr-typeface.cpp (nr_font_new_default): + Don't use implicit NR::Matrix conversions. + + * src/libnr/nr-translate-ops.h (operator!=): new. + + * src/sp-item.h, src/sp-item.cpp (sp_item_bbox_desktop): + Add NR::Rect version. + + * src/inkview.cpp: Address compiler warning: declare is_jar iff it is + defined, i.e. #ifdef WITH_INKJAR. + + * src/desktop-snap.cpp, src/desktop.h, src/object-edit.cpp, + src/sp-root.cpp, src/livarot/PathConversion.cpp, + src/widgets/sp-color-wheel.cpp: + Add some #include's to reduce how much nr-matrix.h must pull in. + + * src/desktop-affine.cpp, src/knotholder.cpp, + src/desktop-events.cpp, src/nodepath.cpp, src/sp-ellipse.cpp, + src/sp-image.cpp, src/sp-item-notify-moveto.cpp, src/sp-rect.cpp, + src/text-context.cpp: + #include libnr/nr-matrix-ops.h. + +2004-02-22 Ted Gould + + * doc/Makefile.am, po/POTFILES.in: keeping these up to date + for distchecks. + +2004-02-21 Ted Gould + + * extensions/txt2svg.inkmod, extensions/txt2svg.pl: + Adding a script that Bryce wrote that will take in text. Plus + the inkscape module file to make it so that you can open text + files in Inkscape. + +2004-02-21 MenTaLguY + + * src/xml/repr-util.cpp, src/xml/repr.h: added RDF namespace by default + + * src/inkscape.cpp, src/inkscape.h, src/widgets/sp-widget.cpp, + src/inkview.cpp: nuked global 'inkscape' variable and replaced + it with a module-local variable and an accessor function. + + * src/uri.h, src/uri.c: added native filename to/from thingy + +2004-02-20 bulia byak + + * src/text-context.cpp: [shift+]alt+arrows to kern + + * src/sp-text.cpp,h: Complete support for dx/dy vectors, including inheritance + as per SVG spec. Preserve dx/dy lists in editing. Function to adjust dx/dy by + screen pixels. + + * src/svg/svg-length.cpp: Function to read length in absolute units + only. Function to read a length into a float instead of SPSVGLength. Function + to read a length vector into a list of SPSVGLength's. + + * src/sp-root.cpp src/sp-image.cpp src/sp-offset.cpp src/sp-spiral.cpp: + Eliminated sp_svg_length_read_ldd calls and ugly repetitive unit checks, used + sp_svg_length_read_[computed_]absolute instead. + + * doc/keys.xml doc/keys.html icons/keys.svg: Updated guide and grid + shortcuts. Added paste in place, more notes. Added kerning keys and notes. + + * src/libnrtype/nr-type-ft2.cpp: Crash fix, patch 895344. + + * src/sp-namedview.cpp src/sp-namedview.h: Proper showguides support, functions + for toggling guides and grid. + + * src/desktop-events.cpp: Turn showguides on when creating a new guide. + + * src/verbs.cpp: Used the new toggle functions for showguides and showgrid. + + * src/interface.cpp: Added Guides to View. + + * src/xml/repr-util.cpp: sp_repr_get_boolean fix. + + * src/dialogs/desktop-properties.cpp: Reenabled showguides support, added + namedview listener to reflect outside changes to the namedview. + +2004-02-20 Peter Moulder + + * Lots of files: Refine #include's according to reorganization of + libnr/nr-types.h and libnr/nr-matrix.h. + + * src/libnr/Makefile.am (libnr_a_SOURCES): + nr-coord.h nr-dim2.h nr-i-coord.h nr-matrix-ops.h nr-point-l.h + nr-point-ops.h nr-point.h nr-rect-l.h nr-rotate.h nr-rotate-ops.h + nr-scale-ops.h nr-scale.h nr-translate-ops.h nr-translate.h: + New files; code moved from nr-types.h and nr-matrix.h. + * src/libnr/nr-matrix.h: + * src/libnr/nr-types.h: + #include the new files. + + * src/desktop-affine.h, src/desktop-affine.cpp + (sp_desktop_w2d_xy_point, sp_desktop_d2w_xy_point, + sp_desktop_w2doc_xy_point, sp_desktop_doc2w_xy_point, + sp_desktop_d2doc_xy_point, sp_desktop_doc2d_xy_point, + sp_desktop_root2dt_xy_point, sp_desktop_dt2root_xy_point): + Remove old NRPoint versions of these functions. + + * src/select-toolbar.cpp: + * src/toolbox.cpp: + * src/widgets/spw-utilities.cpp: + Remove unused #include sp-item-transform.h. + + * src/sp-item-transform.cpp (sp_item_rotate_rel): NR::Matrix'ification. + + * src/sp-item-transform.h, src/sp-item-transform.cpp + (sp_item_scale_rel, sp_item_skew_rel): Remove these unused functions. + + * src/sp-item-transform.h, src/sp-item-transform.cpp + (sp_item_rotate_rel, sp_item_move_rel): Change from pair of points to + NR::rotate and NR::translate respectively. Update callers. + + * src/node-context.cpp (sp_node_context_root_handler): + * src/rect-context.cpp (sp_rect_context_root_handler): + * src/zoom-context.cpp (sp_zoom_context_root_handler): + NR::Point'ification and var cleanup. + + * src/event-context.cpp + (sp_event_context_private_root_handler, set_event_location): + * src/dialogs/align.cpp (sp_align_arrange_clicked): + NR::Point'ification. + + * src/desktop.h (sp_desktop_zoom_relative_keep_point, + sp_desktop_scroll_world): Add NR::Point version. + +2004-02-19 Johan Ceuppens + + * src/inkjar/jar.cpp, src/inkjar/jar.h src/inkview.cpp: + inkview accepts .jar archives of SVG files on the command line. + +2004-02-19 Peter Moulder + + * src/Makefile.am: sp-item-rm-unsatisfied-cns.cpp, + sp-item-rm-unsatisfied-cns.h, sp-guide-attachment.h, + sp-item-notify-moveto.cpp, sp-item-notify-moveto.h, + sp-guide-constraint.h, satisfied-guide-cns.cpp, + satisfied-guide-cns.h, sp-item-update-cns.cpp, + sp-item-update-cns.h: New files. + * src/desktop-events.cpp (sp_dt_guide_event): + * src/seltrans.cpp (sp_sel_trans_ungrab): + * src/sp-guide.cpp (sp_guide_moveto, sp_guide_remove): + * src/sp-guide.h: + * src/sp-item.cpp (sp_item_set): + * src/sp-item.h: + Make snap-to-guide more persistent. (Still not saved to XML though.) + + * src/sp-spiral.cpp (sp_spiral_fit_and_draw, sp_spiral_set_shape): + Address NRPoint warning. + + * src/widgets/icon.cpp (sp_icon_paint): Cleanup. + + * src/libnr/nr-types.h: Change deprecated-cast warning from runtime + to compile-time. + + * src/helper/sp-canvas.h, src/helper/sp-canvas.cpp + (sp_canvas_world_pt_inside_window): New function. + +2004-02-18 MenTaLguY + + * src/widgets/icon.cpp, src/widgets/icon.h: rewrote to use gdk for + compositing; now it looks tolerable with ANY theme! + + * src/dialogs/item-properties.cpp: slight stabs at implementing "visible" + + * src/libnr/nr-types.h: added warning for deprecated casts + +2004-02-18 Peter Moulder + + * src/dialogs/align.cpp (sp_align_arrange_clicked): Cleanup. + + * src/sp-item-transform.cpp (sp_item_move_rel): NR::Matrix'ification. + + * src/desktop-events.cpp (sp_dt_guide_event): Get guide line dialog + working again: double-click on a guide to show the guide dialog. + + * src/utest/utest.h (UTEST_NAMED_ASSERT): + Wrap this macro in static_cast(). + +2004-02-17 MenTaLguY + + * src/interface.cpp: fixed signal connection in recent items menu + + * src/file.cpp: fix compile and pass UTF-8 "URIs" down to module code + +2004-02-17 Peter Moulder + + * src/sp-guide.h, src/sp-guide.cpp (sp_guide_moveto, + sp_guide_position_set): + Combine into a single sp_guide_moveto routine accepting a `commit' + argument. Update callers. + +2004-02-16 MenTaLguY + + * src/interface.cpp: fixed bug with underscores in 'open recent' filenames + + * src/libnr/nr-rect.h, src/libnr/nr-types.h: moved NR::Rect to nr-rect.h, + minor updates + + * src/libnr/nr-maybe.h: continued work on maybe implementation + + * src/libnr/nr-types.h, src/libnr/nr-rect.cpp, src/libnr/nr-maybe.h, + src/seltrans.cpp: + started on revising the NR::Rect stuff, and introduced NR::ConvexHull + +2004-02-16 Peter Moulder + + * src/xml/repr.cpp (sp_repr_document_root): Fix typo in most recent commit. + +2004-02-14 MenTaLguY + + * src/svg/svg-path.cpp: switched to locale-safe iostreams-based path + serialization. + + * src/xml/repr-io.cpp, src/xml/repr.cpp, src/widgets/sp-xmlview-tree.cpp, + src/widgets/sp-xmlview-content.cpp, src/dialogs/xml-tree.cpp: + basic support for XML comments + +2004-02-14 bulia byak + + * src/dialogs/dialog-events.cpp: Added UTILITY hint to sp_transientize() + + * po/fr.po: Update from f.rodrigo@tuxfamily.org + + * src/interface.cpp: Fix for underscore in the recent files menu, by alxrem + + * src/event-context.cpp src/preferences-skeleton.h: Accelerated scrolling by Ctrl-arrows + + * src/event-context.cpp: Ctrl-middle-click zooms in + + * doc/keys.xml doc/keys-svg.xsl doc/keys-html.xsl doc/keys.html icons/keys.svg: + Updated middle and right buttons scroll/zoom, cosmetics + + * src/shortcuts.cpp: Menu shortcut fix + + * src/verbs.cpp,h: New verb: deselect + + * src/selection.cpp,h: Removed unused function + + * src/interface.cpp: Removed Edit/Clear All, added Edit/Deselect. Comment fix + + * src/toolbox.cpp: Spelling fix: symmetric, not symmetrical + + * src/desktop.cpp,h: sp_desktop_point(): returns mouse point in document coordinates + + * src/selection-chemistry.cpp,h: sp_selection_paste obeys in_place parameter + + * src/verbs.cpp src/verbs.h src/shortcuts.cpp: Paste in place verb, shortcut + + * src/interface.cpp: Paste In Place command in Edit + + * src/selection-chemistry.cpp: Toolbar message fix + +2004-02-14 MenTaLguY + + * src/libnr/nr-types.h: added intersects() and contains() tests + for points and rects + +2004-02-13 Peter Moulder + + * src/selection.cpp (sp_selection_snappoints): + * src/sp-image.cpp (sp_image_snappoints): + * src/sp-item.cpp (sp_item_private_snappoints): + Don't use more than two opposite points of bounding box. + + * src/seltrans.cpp (sp_show_handles): Add precondition !seltrans.empty. + * src/proofs: Update accordingly. + * src/seltrans.cpp: Change seltrans from pointer to reference in + several places. + +2004-02-13 Johan Ceuppens + + * src/inkjar/{jar.cpp,jar.h}: changed some file offsets, + uncompressing multiple files in a jar works now. There + is an improved testing program at the end of jar.cpp. + +2004-02-12 Peter Moulder + + * src/seltrans.cpp (sp_sel_trans_update_volatile_state): + Minor cleanups. + + * src/desktop-snap.h, src/desktop-snap.cpp + (sp_desktop_horizontal_snap, sp_desktop_vertical_snap, + sp_desktop_horizontal_snap_list_scale, + sp_desktop_vertical_snap_list_scale, + sp_desktop_horizontal_snap_list_skew, + sp_desktop_vertical_snap_list_skew): + Remove these now-unused functions. + + * src/arc-context.cpp (sp_arc_drag): + * src/rect-context.cpp (sp_rect_drag): + Simplification: use sp_desktop_dim_snap instead of + sp_desktop_horizontal_snap / sp_desktop_vertical_snap. + + * src/desktop-snap.cpp (sp_desktop_vector_snap): Minor cleanups. + + * src/libnr/Makefile.am, src/libnr/nr-point-fns-test.cpp: + New unit test file nr-point-fns-test.cpp. + + * src/libnr/nr-point-fns.h, src/libnr/nr-point-fns.cpp (unit_vector): + New function. + + * src/livarot/Path.h: Trim unnecessary includes. + + * src/livarot/LivarotDefs.h: #include (moved from Path.h). + + * src/livarot/PathOutline.cpp, src/livarot/PathSimplify.cpp, + src/livarot/PathStroke.cpp, src/sp-offset.cpp: + #include libnr/nr-point-fns.h. + +2004-02-12 MenTaLguY + + * src/xml/repr-util.cpp, src/xml/repr.h: pruned some obsolete + functions + +2004-02-12 Johan Ceuppens + + * configure.in src/Makefile.am: --with-inkjar (default no) + * src/inkjar/Makefile.am src/inkjar/jar.cpp src/inkjar/jar.h: + inital import of libinkjar, this can be moved to LGPL after + rewriting the macros. + +2004-02-11 Peter Moulder + + * src/seltrans.cpp (sp_sel_trans_handle_new_event, + sp_sel_trans_handle_request): NR::Point'ification. + + * src/seltrans-handles.cpp, src/seltrans-handles.h, src/seltrans.cpp: + Preserve constness of SPSelTransHandle's. + + * src/sp-item.h, src/sp-item.cpp (sp_item_set_item_transform): + Make static. Use NR::Matrix, and avoid NULL special case. + Update callers. + + * src/sp-item.h, src/sp-item.cpp (sp_item_set_i2d_affine): + Get rid of NRMatrix version. + Calculate 1.25 directly rather than less accurate reciprocal of 0.8. + + * src/libnr/nr-matrix.h, src/libnr/nr-matrix.cpp (matrix_equalp): + New function. + (assert_close): Use matrix_equalp. + + * src/seltrans.h, src/seltrans.cpp (sp_sel_trans_transform): + Get rid of non-NR::Point version. Make affine argument const. + Update callers. + + * src/desktop-events.cpp (sp_dt_guide_event): NR::Point'ification. + + * src/view.h (sp_view_set_position): Add NR::Point version. + + * src/desktop.h (sp_desktop_set_coordinate_status): + Add NR::Point version. + +2004-02-09 bulia byak + + * doc/keys.xml doc/keys-svg.xsl: Keys and Mouse Reference: source, SVG stylesheet + + * icons/keys.svg: Keys SVG chart (generated, do not edit) + + * icons/Makefile.am: Added keys.svg + + * src/help.cpp src/help.h src/interface.cpp: Added Keys and Mouse command + + * doc/keyboard-shortcuts.txt Obsoleted, removed + + * doc/keys-html.xsl doc/keys.html: Keys reference in HTML, stylesheet for HTML + + * doc/Makefile.am: updated + + * src/libnr/nr-pixblock.cpp: A better fix for 859364 + + * src/libnrtype/nr-rasterfont.cpp: Reverting my previous fix for 859364, a better + one is in nr-pixblock.cpp + + * icons/tutorial.svg: Switched to Bitstream Vera, updated tutorial + + * src/file.cpp: Fix for save bug 891852 + + * src/preferences-skeleton.h: transientpolicy=1 again + + * src/nodepath.cpp: Ctrl-Alt-drag fix in point_line_closest() + + * src/select-toolbar.cpp: Small space before unit selector + + * src/widgets/paint-selector.cpp: Hidden buttons removed + +2004-02-09 MenTaLguY + + * src/interface.cpp: disabled the autoraise checkbox on Windows + + * src/widgets/paint-selector.cpp, src/widgets/paint-selector.h: + removed unused selector-type buttons (with Bulia) + +2004-02-09 Jon A. Cruz + + * src/widgets/sp-color-wheel.h, src/widgets/sp-color-wheel.cpp, + src/widgets/sp-color-wheel-selector.h, + src/widgets/sp-color-wheel-selector.cpp, + src/widgets/sp-color-gtkselector.cpp, + src/widgets/sp-color-notebook.cpp + Added new, smaller color wheel selector. + +2004-02-09 Peter Moulder + + * src/desktop-affine.cpp, src/desktop-snap.cpp, + src/desktop-snap.h, src/desktop.cpp, src/knotholder.cpp, + src/nodepath.cpp, src/selection-chemistry.cpp, src/seltrans.cpp, + src/seltrans.h, src/sp-ellipse.cpp, src/sp-image.cpp, + src/sp-item.cpp, src/sp-item.h, src/sp-rect.cpp, src/sp-root.cpp, + src/text-context.cpp, src/dialogs/xml-tree.cpp, + src/libnr/Makefile.am, src/libnr/nr-matrix.cpp, + src/libnr/nr-matrix.h, src/libnr/nr-types.h, + src/libnrtype/nr-rasterfont.cpp, src/livarot/Path.h, + src/livarot/PathConversion.cpp, src/livarot/PathSimplify.cpp, + src/livarot/ShapeSweep.cpp, src/widgets/gradient-position.cpp, + src/widgets/sp-color-wheel-selector.cpp, + src/widgets/sp-color-wheel.cpp: + Change matrices to be suitable for right multiplication. + (Also miscellaneous cleanups as mentioned below.) + + * src/widgets/sp-color-wheel-selector.cpp + (sp_color_wheel_selector_get_type): + Address harmless warning: add value_table initializer. + + * src/display/nr-arena-group.h, src/display/nr-arena-group.cpp + (nr_arena_group_set_child_transform): Add NR::Matrix version. + + * src/verbs.cpp: Add g++-2.95 portability for hash_map. + (Still using hash_map, though, not yet GHashTable.) + + * src/uri-references.h (operator=): Remove definition, forcing link + errors for accidental usage. + + * src/sp-chars.h, src/sp-chars.cpp (sp_chars_add_element): + Add NR::Matrix version. + + * src/selection.cpp (sp_selection_snappoints): Performance fix: add + just 4 corner points, not a thousand. + + * src/print.h, src/print.cpp (sp_print_bind): Add NR::Matrix version. + + * src/inkscape.cpp: #include sys/types.h, sys/stat.h. + + * src/desktop.h (SP_DESKTOP_ZOOM): Define in terms of expansion() + function instead of implicit casting. + + * src/arc-context.cpp, src/document.cpp, src/draw-context.cpp, + src/selection.cpp, src/selection.h, + src/sp-ellipse.cpp, src/sp-gradient.cpp, src/sp-image.cpp, + src/sp-namedview.cpp, src/sp-offset.cpp, src/sp-rect.cpp, + src/sp-spiral.cpp, src/sp-star.cpp, + src/sp-text.cpp, src/bonobo/canvas-translator.cpp: + Cleanups: greater conformance to Coding_Style, combine declaration + and first assignment of some vars. + +2004-02-08 MenTaLguY + + * src/interface.cpp: added "Autoraise Dialogs" menu item to toggle + the transient policy thing + +2004-02-08 Bryce Harrington + + * src/sp-namedview.cpp: This assert appears to serve no purpose + except to cause Inkscape to crash when the user chooses to + exit the app when the XML editor is open. Commenting out the + assert doesn't seem to cause any particular untoward behavior. + + * src/xml/: repr.cpp, repr.h: Hacking in a check to prevent + deletion of the namedview entity, in order to close bug + Inkscape Bug #850971. + +2004-02-07 Johan Ceuppens + * src/libnrtype/nr-type-gnome.cpp src/libnrtype/nr-type-directory + src/libnrtype/nr-type-xft.cpp src/widgets/font-selector.cpp + src/print.cpp src/module.h src/module.cpp + modules/gnome.cpp: activated --with-gnome-print + libnrtype/nr-type-primitives.h: removed possible gchar signedness + bug. + +2004-02-07 Nathan Hurst + + * src/widgets/gradient-position.*: modified the gradient knot + editor to manipulate the knots, rather than rebuilding a gradient + from scratch each time. + +2004-02-07 MenTaLguY + + * src/xml/repr.h, src/xml/repr-util.cpp: + + cleaned up old code in #if 0 sections + + * src/display/canvas-arena.cpp, src/display/nr-arena-glyphs.cpp, + src/display/nr-arena-item.cpp, src/display/nr-arena-shape.cpp, + src/display/nr-arena.cpp, src/display/nr-arena.h: + + cleaned up old code in #if 0 sections + + * src/desktop-affine.cpp, src/desktop.cpp, src/draw-context.cpp, + src/dropper-context.cpp, src/dyna-draw-context.cpp, + src/seltrans.cpp, src/sp-root.cpp, src/sp-text.cpp, + src/libnr/nr-macros.h, src/libnr/nr-types.h, src/libnr/nr-matrix.h, + src/libnr/nr-matrix.cpp, src/libnrtype/nr-font.cpp, + src/libnrtype/nr-rasterfont.cpp, src/livarot/PathSimplify.cpp, + src/livarot/ShapeSweep.cpp: + + The array data member of NR::Matrix is now private; use the + [] operator to access elements individually. More matrix routines + now pass by reference, and the casting operators to cast to NRMatrix + no longer leak memory (by allocating temporary objects that were + never freed). + + * src/modules/db.cpp: cleaned up some very grotty code that gcc 3.4 + (rightly) refused to compile + + * src/xml/repr-action.cpp: undo of content changes was pulling + from the wrong union member (note to self: unions = evil) + This fixes the problem with text editing undos yielding the wrong + apparent undo order (bug #861462). + +2004-02-05 bulia byak + + * src/sp-text.cpp src/sp-text.h: Function to adjust letterspacing + + * src/style.cpp: Comments + + * src/text-context.cpp: Alt+<> adjust letterspacing + + * src/helper/png-write.cpp: PNG comment: Software: www.inkscape.org + + * src/text-context.cpp: Support keypad keys, keypad +/- always zoom even when editing + + * src/shortcuts.cpp: Enable keypad Del + + * src/event-context.cpp: Enable keypad arrows with Ctrl to scroll canvas + + * src/zoom-context.cpp src/rect-context.cpp src/arc-context.cpp src/star-context.cpp + src/spiral-context.cpp src/draw-context.cpp src/dyna-draw-context.cpp + src/text-context.cpp src/dropper-context.cpp: Swallow keypad up/down keys too, + preventing them from focusing the zoom field + +2004-02-05 Jon Phillips + + * src/dialogs/item-properties.cpp, src/dialogs/item-properties.h, + src/dialogs/object-attributes.cpp, src/dialogs/object-attributes.h, + src/dialogs/object-properties.cpp, src/dialogs/object-properties.h, + src/dialogs/sp-attribute-widget.cpp, src/dialogs/sp-attribute-widget.h, + src/dialogs/stroke-style.cpp, src/dialogs/stroke-style.h, + src/dialogs/text-edit.cpp, src/dialogs/text-edit.h, + src/dialogs/tool-options.cpp, src/dialogs/tool-options.h, + src/dialogs/transformation.cpp, src/dialogs/transformation.h, + src/dialogs/xml-tree.cpp, src/dialogs/xml-tree.h, + src/dialogs/xml-tree.cpp, src/dialogs/xml-tree.h: Converted + the aforementioned to coding style. + + +2004-02-04 Ted Gould + + * src/desktop-snap.cpp: Removing some unused code that had + been replaced. + +2004-02-04 jon phillips + + * COPYING, COPYING.LIB, ChangeLog, Makefile.am, Makefile.mingw, + Makefile.mingw.common, NEWS, README, autogen.sh, configure.in, + inkscape-cvs-0.ebuild, inkscape.1.in, inkscape.spec.in: + all files converted from tabs to 4 spaces and cleaned up the + coding style, tested, they build, and have committed. + + * extension/*: I converted all files to coding style. + + * src/dialogs/align.cpp, src/dialogs/align.h, + src/dialogs/desktop-properties.cpp, src/dialogs/desktop-properties.h, + src/dialogs/dialog-events.cpp, src/dialogs/dialog-events.h: Converted + the following files to use our coding convention. + + * src/dialogs/desktop-properties.cpp, src/dialogs/desktop-properties.h, + src/dialogs/display-settings.cpp, src/dialogs/display-settings.h, + src/dialogs/export.cpp, src/dialogs/export.h, + src/dialogs/fill-style.cpp, src/dialogs/fill-style.h: converted the + aforementioned files to new coding conventions. + +2004-02-04 bulia byak + + * src/style.h src/style.cpp src/sp-text.cpp: Read-only (so far) support for + letter-spacing CSS property + + * src/event-context.cpp src/select-context.cpp src/draw-context.cpp + src/dyna-draw-context.cpp src/knotholder.cpp src/nodepath.cpp src/object-edit.cpp: + Trimming #if 0 + + * src/text-context.cpp: Trimming #if 0, removing unneeded document_done + + * src/spiral-context.cpp src/star-context.cpp: Trimming #if 0, enabling ctrl-drag + + * src/dialogs/dialog-events.cpp src/preferences-skeleton.h: Added + options.transientpolicy, 1 as default + + * src/preferences-skeleton.h: Increased options.keyscroll + + * src/dialogs/xml-tree.cpp: Fix for 852619, fix for failed asserts when selecting root + + * src/widgets/gradient-selector.cpp: Fix for 854514, 856682 + +2004-02-02 Peter Moulder + + * src/desktop-snap.h, src/desktop-snap.cpp: Indicate that the snap_list + functions don't modify the passed snap points. For the wrapper versions, + don't bother "copying back the new [actually unchanged] versions". + +2004-01-31 bulia byak + + * src/zoom-context.cpp src/rect-context.cpp src/arc-context.cpp src/star-context.cpp + src/spiral-context.cpp src/draw-context.cpp src/dyna-draw-context.cpp + src/text-context.cpp src/dropper-context.cpp: Fix to swallow up/down keys in + contexts so as to prevent zoom field from activation, but allow ctrl with up/down + keys to scroll canvas. + + * src/interface.cpp: Removed New Preview, Remove Transform commands. Added Tutorial + command to Help. + + * src/preferences-skeleton.h: Reduced default stroke width to 1 pt. + + * src/help.cpp src/help.h: Tutorial command. + + * icons/tutorial.svg: First try at the tutorial. + + * icons/Makefile.am: Adding tutorial. + + * src/nodepath.cpp: No-nodepath crash fixes. + + * doc/architecture.svg: Added namedview. + + * doc/default.svg: Removed, now reworked into icons/tutorial.svg. + + * src/event-context.cpp: Swapped scrollwheel modifiers. + + * src/xml/repr.cpp src/xml/repr-io.cpp: Small comment fix. + +2004-01-31 Johan Ceuppens + * src/verbs.cpp src/verbs.h: removed sp_fullscreen and put it in + desktop.cpp and desktop.h as fullscreen + * configure.in src/interface.cpp src/shortcuts.cpp src/inkscape.cpp + src/inkscape.h src/desktop.cpp src/desktop.h: + Added HAVE_GTK_WINDOW_FULLSCREEN as conditional compilation based + on a function check for gtk_window_fullscreen in configure script + +2004-01-30 Johan Ceuppens + * src/verbs.cpp src/verbs.h: Added fullscreen verb. Fullscreen action + is in SP_VERB_IS_ZOOM. + * src/interface.cpp: Added fullscreen menuitem. + * src/shortcuts.cpp: Linked in fullscreen shortcut (untested) + * src/inkscape.cpp src/inkscape.h + * src/desktop.cpp src/desktop.h: Added is_fullscreen gboolean to + SPDesktop. + +2004-01-30 Peter Moulder + + * src/libnr/nr-path.h, src/libnr/nr-path.cpp: Mark some functions + as not modifying the matrix passed to them. + + * src/display/nr-arena-group.h, src/display/nr-arena-group.cpp + (nr_arena_group_set_child_transform): + Indicate that matrix isn't written to. + + * src/sp-item-transform.cpp (sp_item_rotate_rel, sp_item_scale_rel, + sp_item_skew_rel), + src/sp-marker.cpp (sp_marker_update, sp_marker_show_instance), + src/sp-shape.cpp (sp_shape_bbox), + src/sp-symbol.cpp (sp_symbol_update, sp_symbol_show, sp_symbol_print), + src/display/nr-arena-shape.cpp (nr_arena_shape_update, nr_arena_shape_pick): + Remove uses of nr_matrix_f_from_d. + * src/libnr/nr-matrix.h, src/libnr/nr-matrix.cpp (nr_matrix_f_from_d), + src/libnr/libnr.def: + Remove now-unused nr_matrix_f_from_d. + + * src/nodepath.cpp (sp_nodepath_new), + src/path-chemistry.cpp (sp_selected_path_combine, sp_selected_path_break_apart), + src/selection-chemistry.cpp (sp_selection_apply_affine), + src/selection.cpp (sp_selection_bbox_document), + src/sp-item.cpp (sp_item_bbox_desktop, sp_item_private_snappoints), + src/sp-pattern.cpp (sp_pattern_painter_new), + src/modules/gnome.cpp (sp_module_print_gnome_fill), + src/widgets/icon.cpp (sp_icon_image_load_svg): + Remove uses of nr_matrix_d_from_f. + * src/libnr/nr-matrix.h, src/libnr/nr-matrix.cpp (nr_matrix_d_from_f), + src/libnr/libnr.def: + Remove now-unused nr_matrix_d_from_f. + + * src/sp-item.h, src/sp-item.cpp (sp_item_set_i2d_affine_d, + sp_item_i2doc_affine_d, sp_item_i2d_affine_d, sp_item_dt2i_affine_d): + Merge _d version with non-_d version. Update callers. + + * src/rubberband.h, src/rubberband.cpp (sp_rubberband_start): + Add NR::Point version. + Implement x,y version as call to NR::Point version. + +2004-01-29 Peter Moulder + + * src/desktop-snap.h, src/desktop-snap.cpp (sp_desktop_dim_snap_list): + Export this function. + (sp_desktop_horizontal_snap_list, sp_desktop_vertical_snap_list): + Remove these now-unused functions. + * src/select-context.cpp (sp_selection_moveto): + Use sp_desktop_dim_snap_list instead of + sp_desktop_horizontal_snap_list, sp_desktop_vertical_snap_list. + + * src/select-context.cpp (sp_selection_moveto): Fix what appears to be + a memory leak. + + * src/rubberband.h, src/rubberband.cpp (sp_rubberband_move): + Add NR::Point version. + + * src/seltrans.h (sp_sel_trans_point_desktop): Add NR::Point version. + + * src/seltrans.h, src/seltrans.cpp (sp_sel_trans_point_desktop, + sp_sel_trans_origin_desktop): Indicate that pointer isn't written through. + + * src/node-context.cpp, src/select-context.cpp: + Make some globals static. + + * src/style.cpp (sp_style_read_pfloat, SPS_READ_IFLOAT_IF_UNSET, + SPS_READ_PFLOAT_IF_UNSET): Remove these unused functions/macros. + +2004-01-28 MenTaLguY + + * src/toolbox.cpp: aux toolbar now expands properly when torn off + (fix for bug #874923) + + * src/libnr/nr-svp.cpp, src/libnr/nr-stroke.cpp, + src/libnr/nr-svp-private.h, src/libnr/nr-svp.h, + src/libnr/nr-svp-render.cpp, src/libnr/nr-svp-uncross.cpp: + + NRCoord -> NR::Coord + + * src/interface.cpp: removed Filters menu + + * src/modules/win32.cpp: the Win32 GDI uses BRGx, rather than + RGBA, so we reverse the B and R bytes before blitting (fix + for bug #887428) + +2004-01-28 Peter Moulder + + * src/seltrans.cpp: Various cleanups, including addressing some + warnings, and doing some more NR::Point'ification. + + * src/knot.h, src/knot.cpp (sp_knot_set_position): Change from + pass-by-value to pass-by-const-reference. + + * src/geom.cpp (sp_intersector_line_intersection): Restore + definition of previous local `cross' function, but "inline" the + dot(rot90(a), b) definition. This makes the definition conform to + the documentation. + * src/desktop-snap.cpp (sp_intersector_a_vector_snap): Undo a recent + change that adapted to the previously-introduced bug in + sp_intersector_line_intersection. + + * icons/Makefile.am: s/icons_dir/iconsdir/g for automake. + * src/dialogs/Makefile.am, src/widgets/Makefile.am: + s/icons_dir/iconsdir/g for consistency with icons/Makefile.am. + +2004-01-27 jon phillips + + * Makefile.am: changed 'glade' globally to 'icons' + + * Makefile.mingw: changed 'glade' globally to 'icons' + + * config.h.mingw: changed 'INKSCAPE_GLADEDIR' to 'INKSCAPE_ICONS_DIR' + + * configure.in: changed 'glade' globally to 'icons' + + * Makefile.am: changed 'gladedir' to 'icons_dir', and fixed spacing, + changed 'glad_DATA' to 'icons_DATA' + + * glade/about_svg.tmpl: changed 'glade' globally to 'icons' + + * po/pl.po: changed 'glade' globally to 'icons' + + * src/config.h.win32: changed 'SODIPODI_GLADEDIR' to 'SODIPODI_ICONS_DIR' + * src/dialogs/Makefile.am: changed 'gladedir' to 'icons_dir', changed + '-DINKSCAPE_GLADEDIR=\""$(gladedir)"\" \' to + '-DINKSCAPE_ICONS_DIR=\""$(icons_dir)"\" \' + + * src/dialogs/makefile.msc: changed 'gladedir' to 'icons_dir' + + * src/dialogs/object-properties.cpp: changed 'INKSCAPE_GLADEDIR' to + 'INKSCAPE_ICONS_DIR' + + * src/dialogs/stroke-style.cpp: changed 'INKSCAPE_GLADEDIR' to + 'INKSCAPE_ICONS_DIR' + + * src/widgets/Makefile.am: changed 'gladedir' to 'icons_dir' + + * src/widgets/icon.cpp: changed 'glade' globally to 'icons' + + * src/widgets/makefile.msc: changed 'gladedir' to 'icons_dir' + + +2004-01-26 bulia byak + + * src/inkscape.cpp: failed assertion fix + + * src/shortcuts.cpp: Linked/dynamic offset shortcuts, zoom to page width + + * src/preferences-skeleton.h: Add inkscape:pageopacity, borderopacity + + * src/attributes.cpp,h src/sp-namedview.cpp,h: Add inkscape:pageopacity + + * src/dialogs/desktop-properties.cpp: Get/set inkscape:pageopacity in the page + background color picker; reword and rearrange labels, spacing fix + + * src/dialogs/export.cpp: Use inkscape:pageopacity for export background; fix crash on + exit + + * src/file.cpp: Remove debug output when exporting + + * src/sp-gradient.cpp src/svg/svg-path.cpp src/libnr/nr-compose.cpp src/dir-util.cpp + src/desktop.cpp: Fixes from sodipodi + + * src/main.cpp: Fix PNG size limits when exporting from commandline + + * src/style.cpp src/style.h: currentColor support from sodipodi + + * src/sp-gradient.cpp: Fix for 876614 from sodipodi + + * src/dialogs/desktop-properties.cpp: Convert meters to cm on writing (to make + svg/@height and svg/@width SVG compliant) + + * src/sp-rect.cpp: Fix in description + + * src/dialogs/text-edit.cpp: Fix bug: undo broken when font applied to more than one + text object. And another bug: do not apply text, only style, when more than one text + object selected. + + * src/widgets/font-selector.cpp: Make font and style lists scroll automatically to + show selected row + +2004-01-26 Peter Moulder + + * config.h.win32: Remove this outdated and apparently-unused file. + + * src/livarot/Path-test.cpp: new file. + * src/livarot/Makefile.am: New test program Path-test. + Remove $(cflags) from INCLUDES. + + * configure.in: Adjust some things for our C to C++ transition. + Add warning flags to CXXFLAGS if the compiler is g++. + +2004-01-26 MenTaLguY + + * src/configure.in, src/Makefile.am, src/modules/Makefile.am, + src/libnrtype/Makefile.am: + merged patch #847856 for autotools builds on mingw/win32 + + * src/sp-marker.h: added a URIReference subclass for markers + + * src/sp-path.cpp: fixed backwards-compatiblilty thing with + (ancient) Sodipodi + + * src/xml/repr-action.c, src/xml/repr-action.h, + src/xml/repr-private.h, src/xml/repr.cpp: + + made SPReprDoc::is_logging a C++ bool, and fixed sp_repr_rollback() + to respect the no-logging-during-rollback invariant + +2004-01-25 MenTaLguY + + * src/sp-object-repr.cpp, src/splivarot.cpp, src/sp-offset.cpp: + changed "offset" to "inkscape:offset" for sodipodi:type + +2004-01-24 bryce + + * src/dialogs/stroke-style.cpp: Hooking up marker buttons to + underlying marker style setting code, & etc. + +2004-01-24 bulia byak + + * src/document.cpp src/sp-namedview.cpp: Desensitize undo for changing document uri + and for saving window geometry/viewarea into namedview + + * src/xml/repr-util.cpp: Increase precision in set_double_attr + + * src/arc-context.cpp: Call invoke_write when finishing arc, instead of setting attrs + manually + + * src/sp-ellipse.cpp: Add write method to genericellipse; fix handling of start and + end attrs; fix undo bug (877238) + +2004-01-24 MenTaLguY + + * src/xml/repr-action.h, src/xml/repr-action.c: made the + SPReprAction::act union anonymous, and reworked the transaction + log optimization code. sp_repr_coalesce_log() should be a bit + faster now, and no more strcmp()s. + +2004-01-23 Peter Moulder + + * src/livarot/Path.h, src/livarot/Path.cpp (Path::Affiche): remove + unused function. + Doing so allows removal of path_descr_moveto::pathLength field and the + code for calculating its value. + + * src/livarot/Path.cpp (SizeForData): Change from private method to + static function. + Use new function roundup_div instead of `%' calculation. + + (Path::CloseSubpath): Remove loop that calculated pathLength. + Consequently remove the no-longer-used argument. Update callers. + + (Path::MoveTo, Path::LineTo, Path::CubicTo, Path::ArcTo, + Path::TempBezierTo, Path::EndBezierTo, Path::IntermBezierTo, + Path::BezierTo, Path::AddPoint, Path::PointAt, + Path::PointAndTangentAt): + Change some C-style casts to reinterpret_cast's. + + (Path::PointAt, Path::PointAndTangentAt): code transformations + in preparation for merging some branches. + + * src/libnr/nr-types-test.cpp (main): Update for NR::Point .pt + privateness change. + + * src/libnr/nr-svp-uncross.cpp (nr_segment_intersection): Mark some + pointer arguments as not being written through. + Add doc comment. + + * src/selection-chemistry.cpp (sp_matrix_d_set_rotate): + Slight reduction in numerical error. + (Also rename variables from `angle' to `angle_degrees' in several + places.) + + * src/node-context.cpp (sp_node_context_root_handler): + * src/object-edit.cpp (sp_arc_start_set, sp_arc_end_set, + sp_spiral_inner_set, sp_spiral_outer_set): + * src/select-context.cpp (sp_select_context_root_handler): + * src/seltrans.cpp (sp_sel_trans_rotate_request): + Fix for options.rotationsnapsperpi == 0. + + * src/event-context.cpp (sp_event_context_private_root_handler): + Address warning. + +2004-01-22 bulia byak + + * src/attributes.h src/attributes.cpp: Added pagecolor, bordercolor, borderopacity (from sodipodi), pageshadow. + + * src/sp-namedview.h src/sp-namedview.cpp: Added reading page attributes. + + * src/desktop.cpp: Added setting page and border color (from sodipodi), pageshadow taken from namedview. + + * src/preferences-skeleton.h: Moved pageshadow into namedview, added page and border colors to the template. + + * src/dialogs/desktop-properties.cpp: Added page and border color selectors (from + sodipodi), moved former document settings here. + + * src/verbs.cpp src/verbs.h: Removed document settings, renamed editing window into document options. + + * src/interface.cpp: Removed document settings command. + + * src/dialogs/document-properties.cpp,h src/dialogs/tool-attributes.cpp,h: Removed. + + * src/dialogs/object-properties.cpp: Removed size and position dialog. + + * src/dialogs/Makefile.am: Removed unused dialogs. + + * src/verbs.cpp src/verbs.h: Removed unused dialog verbs. + + * src/dyna-draw-context.cpp: Removed debug output. + + * src/node-context.h: New members for tracking left, right/alt, ctrl. + + * src/nodepath.cpp: Reorganize [] <> code, add update_repr (oops). Fix near-zero handles behavior with <>. + + * src/sp-item-transform.cpp: More correct transformation writing method: use each + item's transform writer instead of simply adding transform= attribute. + + * src/document.cpp src/document.h src/document-undo.cpp: Added + sp_document_ensure_up_to_date on each undoable action, fixes bbox problems (bug + 879249). Added callback to reset actionkey on each selection change, so that + same-key actions on different objects are not lumped together. + + * src/selection-chemistry.cpp: Removed spurious sp_selection_changed calls from all + transformation functions, coalesced [] <> rotates and scales. + + * src/select-toolbar.cpp: Coalesced spinbutton moves and scales. + +2004-01-21 MenTaLguY + + * src/desktop-snap.cpp, src/desktop.cpp, src/nodepath.cpp, + src/object-edit.cpp, src/sp-namedview.cpp, src/sp-offset.cpp, + src/splivarot.cpp, src/uri.h, src/dialogs/desktop-properties.cpp, + src/libnr/nr-matrix.cpp, src/libnr/nr-matrix.h, + src/libnr/nr-point-fns.cpp, src/libnr/nr-point-fns.h, + src/libnr/nr-rect.cpp, src/libnr/nr-types.cpp, src/libnr/nr-types.h, + src/livarot/Path.cpp, src/livarot/PathConversion.cpp, + src/livarot/PathOutline.cpp, src/livarot/PathSimplify.cpp, + src/livarot/PathStroke.cpp, src/livarot/Shape.cpp, + src/livarot/ShapeMisc.cpp, src/livarot/ShapeSweep.cpp, + src/livarot/ShapeSweepUtils.cpp: + Cleanup; made data member of NR::Point private and replaced + a few 'magic' [0] and [1] indices with the more meaningful NR::X + and NR::Y. + +2004-01-20 Jon Phillips + + * src/help.cpp: I cleaned up the code a little according to our coding + standards and have/am adding comments to the help system. + +2004-01-20 bulia byak + + * src/selection-chemistry.cpp,h: New scaling utility functions + + * src/select-context.cpp: <> [] with modifiers to scale/rotate objects + + * src/nodepath.cpp,h: New functions for scaling and rotating nodes + + * src/node-context.cpp: <> [] with modifiers to scale/rotate nodes, left/right + modifiers affect one of the two handles + + * src/node-context.h: New node context members for tracking left/right alt/ctrl + + * src/event-context.cpp: Use cursor coords when zooming by scrollwheel (fixme) + +2004-01-19 MenTaLguY + + * src/dialogs/xml-tree.cpp: automatically scroll tree view to show selected item + +2004-01-19 Jon Phillips + + * src/desktop.cpp: Changed the document shadow to be an option. It is + option.pageshadow. I also made some wrapper code so that if the value + is set to 0, then the constructor for page shadow is not + initialized. + +2004-01-18 bulia byak + + * src/sp-spiral.cpp,h: Moved defines to .h + + * src/object-edit.cpp: Reenabled restricted ctrl-rotation of spiral and arc. Added + alt-drag in spiral to lock radius. Used PI/options.rotationsnapsperpi everywhere + instead of PI/4. + + * src/selection-chemistry.cpp,h src/select-context.cpp: Enable [ ] keys to rotate + selected objects by rotationsnapsperpi. Alt [ ] rotate by angular pixels. + + * src/event-context.cpp src/preferences-skeleton.h src/desktop.h src/zoom-context.cpp + src/select-context.cpp: Behavior fixes, simplifications, & unifications in handling + dragtolerance, rubberband, and shift/ctrl+selection + + * src/event-context.cpp src/preferences-skeleton.h src/desktop.h: Define & use new + options for scrolling distances: keyscroll, wheelscroll + +2004-01-18 MenTaLguY + + * src/uri.h, src/uri.cpp, src/uri-reference.h, src/uri-reference.cpp, + src/sp-item.h, src/sp-item.cpp, src/sp-clippath.h, + src/sp-gradient.h, src/sp-gradient.cpp, src/sp-mask.h, + src/sp-item.h, src/sp-item.cpp: + + Reworked URIs to use libxml, and URIReferences to be specialized + for particular object types. Also switched gradients to using + URIReferences. + +2004-01-17 Jon + + * src/desktop.cpp: Changed the document shadow to 1 pixel. It as + set to 5, which is really cheesy. I changed it in the + constructor for SP_desktop_new in the function + sp_ctrlrect_set_shadow(). + +2004-01-17 Bryce + + * src/sp-root.cpp, src/sp-symbol.cpp: Fixing NRMatrix's a -> &a + so codebase will build. + + * Adding marker xpm's to Makefile.in so the button images display + in the stroke style dialog (must do a make install) + +2004-01-17 MenTaLguY + + * src/uri.h, src/uri.cpp, src/uri-references.cpp: + new Inkscape::URI implementation using libxml URI stuff + +2004-01-15 bulia byak + + * src/preferences-skeleton.h: Added: tools.freehand.perncil tolerance, + options.zoomincrement, rotationsnapsperpi, maxrecentdocuments + + * src/seltrans.cpp src/draw-context.cpp src/nodepath.cpp: Rotation snaps taken from + preferences + + * src/inkscape.cpp: Max recent documents from prefs + + * src/desktop.cpp,h: New _keep_point zoom functions + + * src/event-context.cpp: Zoom in/out on (shift+)middle click, use + options.dragtolerance, use options.zoomincrement, use _keep_point zoom functions + + * src/verbs.cpp: Use options.zoomincrement + + * src/zoom-context.cpp: Use options.zoomincrement, use _keep_point zoom functions + + * src/tools-switch.cpp: Fix for 865740 + + * src/draw-context.cpp: Fix for 877188 + + * src/nodepath.cpp: Swapped ctrl-click and ctrl-alt-click + + * src/knot.cpp src/knotholder.cpp src/nodepath.cpp: Knot colors, using XOR paint mode + + * src/widgets/widget-sizes.h src/desktop.cpp: Coord skip taken from define, limited + height of the bottom bar + + * src/splivarot.h src/splivarot.cpp src/verbs.cpp src/verbs.h src/interface.cpp: Added + dynamic and linked offsets to menu + + * src/knot.cpp src/select-context.cpp src/zoom-context.cpp src/draw-context.cpp: + Unified within_tolerance handling; take curve fitting tolerance from preferences in + freehand tool (default 10) + +2004-01-15 MenTaLguY + + * glade/about.svg, glade/about_svg.tmpl, samples/inkscape.logo.svg: + updated to match the current standard logos from + inskcape_project/artwork + +2004-01-15 Nathan Hurst + + * src/livarot/* an ungodly number of changes for improved use of + NR::Point. Const propagation. Minor bugfixes. + +2004-01-15 Peter Moulder + + * src/widgets/paint-selector.cpp (sp_paint_selector_set_color_alpha, + sp_paint_selector_get_color_alpha, sp_paint_selector_system_color_set), + src/widgets/sp-color-gtkselector.cpp (ColorGtkselector::_colorChanged), + src/widgets/sp-color-notebook.cpp (ColorNotebook::_colorChanged, + ColorNotebook::_updateRgbaEntry), src/widgets/sp-color-selector.cpp + (ColorSelector::setAlpha, ColorSelector::setColorAlpha, + ColorSelector::_updateInternals): + Add assertions that alpha is in [0.0, 1.0]. + + * src/libnr/nr-types.h, src/libnr/nr-rect.cpp (NR::Rect::corner): + Change argument to unsigned, thus changing remainder operator to modulo + operator, thus fixing bug for "negative" arguments (-1u etc.). + + * src/dialogs/stroke-style.cpp (sp_stroke_style_paint_update_repr): fix + bug with unsigned->float alpha conversion. + + * src/nodepath.cpp (angle_normalize): Remove no-longer-used function. + + * src/draw-context.cpp (spdc_endpoint_snap_internal): Fix for + negative options.rotationsnapsperpi. + +2004-01-14 Peter Moulder + + * src/selection-chemistry.cpp (sp_selection_item_next, + sp_selection_item_prev): cleanups, including moving some common + code into new static function scroll_to_show_item. + + * src/widgets/font-selector.h, src/widgets/font-selector.cpp + (sp_font_selector_set_font_fuzzy): Remove this unused function. + + * src/sp-text.cpp (sp_text_font_style_to_lookup), + src/dialogs/text-edit.cpp (sp_text_edit_dialog_font_style_to_lookup): + Move this duplicated function to src/libnrtype/font-style-to-pos.cpp + as font_style_to_pos, rewriting & fixing its bugs in the process. + Adjust callers. + * src/libnrtype/font-style-to-pos.cpp, src/libnrtype/font-style-to-pos.h: + New files. + * src/libnrtype/Makefile.am: Mention the new files. + * src/libnrtype/nr-type-pos-def.h: Make the default constructor fill in + sensible values. + Add constants for CSS weight numbers. + +2004-01-13 MenTaLguY + + * src/object-ui.cpp: 'Fill Settings' -> 'Fill and Stroke' + + * src/FilePath.cpp, src/FilePath.h: removed until we can rethink + the file stuff + +2004-01-13 Peter Moulder + + * src/libnrtype/nr-type-directory.h, + src/libnrtype/nr-type-directory.cpp (nr_type_directory_lookup_fuzzy): + Change second arg from char const* to NRTypePosDef. + (nr_type_calculate_position) Move to nr-type-pos-def.cpp as implicit + NRTypePosDef constructor from string. + * src/libnrtype/nr-typeface.h: NRTypePosDef changed from struct to class. + * src/libnrtype/nr-type-pos-def.h, src/libnrtype/nr-type-pos-def.cpp: + new files. + * src/libnrtype/Makefile.am: Mention the new files. + + * src/sp-text.cpp (sp_text_font_style_to_lookup): Fix segfault I + introduced, reported by ishmal. + +2004-01-12 bulia byak + + * src/sp-rect.cpp: Removed coordinates from rect description + + * src/selection-chemistry.cpp: Delete fix from sodipodi, more statusbar diagnostics + + * src/prefs-utils.cpp,h: New functions for setting/getting string values + + * src/dialogs/export.cpp: Export dialog tracks selection and document changes (fix for + 853849). Export area, dpi remembered in prefs. Misc fixes and cleanups + + * src/preferences-skeleton.h: New options for export: exportarea, defaultxdpi + + * src/widgets/spw-utilities.cpp,h: New function for recursively searching widgets for + key/value pair + + * src/svg/svg-affine.cpp: Ignore whitespace at the end of transform attribute - fix + for 850943 (from sodipodi) + + * src/select-toolbar.cpp: Correctly handle zero dimensions - fix for 871552 + +2004-01-12 Peter Moulder + + * src/sp-gradient.cpp (sp_gradient_repr_set_vector): "Fix" a memory + leak. However, I haven't worked out how to get this code to run, in + order to check that the guessed replacement code is correct. Instead + I've inserted a g_warning and a TODO comment. + + * src/libnrtype/nr-type-directory.cpp + (nr_type_calculate_position): Fix bug where `ultra bold' and `extra + bold' were getting parsed as `bold'. + (nr_type_distance_family_better, nr_type_distance_position_better): + Rename to nr_type_distance_family and nr_type_distance_position + respectively, and return just the distance. + (nr_type_distance_family): Use g_ascii_strcasecmp instead of + strcasecmp/stricmp. + (nr_type_distance_family): Return unsigned instead of float. + (nr_type_distance_position): Use double instead of float. + + * src/libnrtype/nr-rasterfont.cpp + (nr_rasterfont_generic_glyph_area_get, + nr_rasterfont_generic_glyph_mask_render): Suppress warning: + s/CLAMP/MIN/ if the type is unsigned and the lower bound is 0. + + * src/helper/sp-canvas.cpp (paint): Cache canvas->{x0,y0} + + GTK_WIDGET(canvas)->allocation.{width,height}. + Remove some commented-out variables. + + * src/tools-switch.cpp, src/tools-switch.h: Make some functions static. + (tools_num2name): Remove unused function. + (tools_isactive): Add assertion of not accessing past the end of the + array. + + * src/knot.cpp (sp_knot_handler): Fix bug where event wasn't + getting consumed. + Get rid of hypot macro. + + * src/svg/svg-affine.cpp (sp_svg_transform_write): Add assertions + that buffer overflow hasn't occurred. + + * src/sp-text.cpp (sp_text_font_style_to_lookup), + src/dialogs/text-edit.cpp (sp_text_edit_dialog_font_style_to_lookup): + Slight restructuring using g_snprintf instead of less readable (& + slightly less efficient in this case) strlen/memcpy. + + * src/sp-metrics.h: Increase accuracy of PT_PER_CM etc. + Add FIXME comment. + + * src/dialogs/item-properties.cpp, src/display/nr-arena-shape.cpp: + Address `-Wshadow' warnings. + + * src/nodepath.h, src/nodepath.cpp: Make some functions static. + (sp_nodepath_node_deselect) Remove unused function. + + * src/dialogs/align.cpp (sp_quick_align_dialog): Switch to data-driven approach. + Mark some things as static. + (sp_quick_align_dialog_close) Remove unused function. + (sp_align_arrange_clicked) Change aligns constant array from ints to + doubles. Adjust caller. + +2004-01-11 Iain + + * src/modules/ps.cpp: Swap the Print and Cancel buttons around, and + remove the separator. + +2004-01-11 bulia byak + + * src/desktop.cpp,h: New functions and SPDesktop members for maintaining lists of past + and future zooms. New commands for toggling rulers and scrollbars, removed old and + unused toggle_borders. Zoom spinbutton editable again, coord_status uses gtk_label + instead of statusbar, misc cosmetics. Reduced sizes of the window bottom + stuff. Save/restore the status of rulers and scrollbars in preferences. + + * src/preferences-skeleton.h: New options: showrulers, showscrollbars. Added default + namedview for a 640x480 new document window. + + * src/widgets/spinbutton-events.cpp,h: Common spinbutton callbacks. + + * src/widgets/Makefile.am: Added spinbutton-events. + + * src/select-toolbar.cpp: Remove code into spinbutton-events. + + * src/widgets/widget-sizes.h: Added sizes for bottom stuff: zoom field, coord status, + statusbar. Misc cosmetic changes. + + * src/verbs.cpp,h: New verbs for next/prev zoom. New verbs for toggling rulers and + scrollbars. + + * src/sp-namedview.cpp: Cancel past zooms at the end of window_from_document. + + * src/shortcuts.cpp: `, shift-` to navigate the history of zooms. Ctrl-r, Ctrl-b to + toggle rulers and scrollbars. + + * src/interface.cpp: Added next/prev zoom commands in the view menu. Added three + toggle commands (grid, rulers, scrollbars) in the view menu. + + * src/widgets/ruler.cpp: Use fixed smaller font size, defined in widget-sizes. + +2004-01-10 bulia byak + + * src/draw-context.cpp: Changed alt to shift for one-handle drag. + +2004-01-10 Peter Moulder + + * src/desktop-events.cpp, src/desktop-snap.cpp, src/draw-context.cpp, + src/gradient-chemistry.cpp, src/selection-chemistry.cpp, + src/seltrans.cpp, src/sp-shape.cpp: + Address some `-Wshadow' warnings. + + * src/attributes.cpp, src/color.cpp, src/inkscape.cpp, + src/interface.cpp, src/helper/units.h, src/libnrtype/nr-type-xft.cpp, + src/svg/svg-color.cpp, src/widgets/gradient-vector.cpp: + Address some `-Wwrite-strings' warnings. + + * src/document.h, src/document.cpp, + src/prefs-utils.h, src/prefs-utils.cpp, + src/select-toolbar.cpp, + src/helper/unit-menu.h, src/helper/unit-menu.cpp, + src/libnr/nr-object.h, src/libnr/nr-object.cpp: + Mark some pointer function arguments as not being written through. + + * src/path-chemistry.cpp (sp_selected_path_combine): Fix what appears + to be a memory leak. Change string concatenation from Omega(n^2) to + Omega(n). + +2004-01-09 bulia byak + + * src/zoom-context.cpp: Added drag tolerance + + * src/widgets/widget-sizes.h: Spinbutton steps defined here + + * src/widgets/spw-utilities.cpp,h: New function for recursively searching widgets for data + + * src/select-context.cpp: Alt-x activates aux toolbar + + * src/select-toolbar.cpp: Implement esc, ctrl-z, up/down, pgup/pgdn, tab in the aux + toolbar, identified default spinbutton for activating by alt-x + + * src/nodepath.cpp: Fix for uninitialized variable, reported by Bob Jamison + + * src/draw-context.cpp: Fix for 873092; Never snap if hitting anchor + +2004-01-08 bulia byak + + * src/select-context.cpp: Fixed ctrl-drag (without breaking ctrl-click) + + * src/verbs.cpp: Tooltip edits + + * src/desktop.cpp: Changed initial statusbar message (suggested by Daniel Diaz) + + * src/tools-switch.cpp src/nodepath.cpp src/selection.cpp: Edited statusbar messages, + made them translatable + +2004-01-08 Nathan Hurst + + * src/helper, src/libnr and various: removed senescent code inside + #if 0s and changed scoping of variables to be close to use. minor + performance tweeks. + +2004-01-08 Peter Moulder + + * src/widgets/sp-color-notebook.cpp (getCurrentSelector): Address + unsignedness warning (thus fixing a minor buglet). + + * Too many files to list (58 .cpp files, phew!): Address `missing + initializer for member _GTypeInfo::value_table' warnings. + + * src/toolbox.cpp, src/helper/sp-canvas.cpp: Address miscellaneous + other `missing initializer' warnings. + + * src/libnr/nr-values.h, src/libnr/nr-values.cpp: Add `Point + component_vectors[2]' global constant (moved from desktop-snap.cpp). + + * src/sp-namedview.cpp: + Combine SPNamedview .hguides & .vguides into .guides. + Combine .gridspacingx, .gridspacingy scalars into .gridspacing Point. + Consequently reduce copy&paste code both here & in callers. + + * src/sp-guide.h, src/sp-guide.cpp (sp_guide_moveto, + sp_guide_position_set): Take a scalar (.position value) as argument, + not a point. + (sp_guide_position_from_pt): new function. Adapt callers. + (sp_guide_description): New function. + (sp_guide_compare): Remove, not used. + Change SPGuide.orientation (horizontal/vertical enum) to .normal (a + Point to be used with dot product), as a step towards allowing + arbitrary-direction guide lines. + + * src/desktop-events.cpp: Adapt to SPGuide change. + Remove some #if 0'ed code that would otherwise require updating. + + * src/desktop-snap.h, src/desktop-snap.cpp: Convert some pass-by-value + Point arguments to const references. Unexport + sp_desktop_dim_snap_list_scale. Adapt to above changes. + + * src/dialogs/desktop-properties.cpp: Adapt to .gridspacing change. + +2004-01-07 Peter Moulder + + * src/geom.h, src/geom.cpp (sp_intersector_line_intersection): + change arguments from `Point' to `Point const &'. + + * src/libnr/nr-types.h: Move cross to its sole user, src/geom.cpp. + +2004-01-06 bulia byak + + * src/widgets/spw-utilities.cpp,h: Recursive font setting functions + + * src/widgets/widget-sizes.h: New: defines sizes and intervals, for toolbars etc. + + * src/select-toolbar.cpp src/helper/unit-menu.cpp src/toolbox.cpp,h: Use + widget-sizes.h and recursive font_set + +2004-01-06 Peter Moulder + + * src/desktop-snap.cpp: Make the `horizontal' and `vertical' + global constants be static. + Similarly, make functions sp_intersector_a_vector_snap, + sp_desktop_dim_snap_list static. + + * configure.in: Fix sigc++ checking code: add it to the existing + PKG_CHECK_MODULES(INKSCAPE, ...) list instead of modifying + $CXXFLAGS,$LIBS. + + * distro: Remove some bashisms: change `function f {...}' to + `f () {...}', and invoke self with `sh' rather than `bash'. + + Also change a strange-looking "tr ' ' ' '" to "tr -s ' '", as + a guess as to the intended meaning. (The actual meaning of the + original is a noop.) + +2004-01-06 bulia byak + + * src/document-undo.cpp src/document.h: Undo and redo now return gbooleans + + * src/selection-chemistry.{cpp|h}: sp_undo, sp_redo: new, with statusbar + diagnostics. Duplicate command adds statusbar diagnostics, places duplicate + into the source's parent instead of document root + + * src/verbs.cpp: Use sp_undo, sp_redo. Tooltip edits + + * src/toolbox.cpp src/toolbox.h: New aux_toolbox_space() + + * src/interface.cpp: New commands in view (cycling desktops) and dialogs (hide dialogs) + + * src/main.cpp: Removed unneeded include + + * src/select-toolbar.cpp src/select-toolbar.h: New selector aux toolbar with XYWH + spinbuttons (taken mostly from the size&position dialog) + + * src/toolbox.cpp src/toolbox.h: Removed selector aux toolbar code from here + + * src/helper/unit-menu.cpp: Use abbreviations in the unit menu + + * src/widgets/sp-widget.cpp: Added checks that the inkscape object is valid before + disconnecting SPWidget from it + +2004-01-06 MenTaLguY + + * src/Makefile.am: removed monostd.h + + * src/sp-item.cpp, src/uri-reference.h, src/uri-reference.cpp: + redid URI reference stuff a bit + +2004-01-06 Nathan Hurst + + * src/desktop-snap.{h,cpp} is now built using NR::Point. + +2004-01-06 Nathan Hurst + + * src/draw-context.cpp closing a segment now remains snapped. + Lots of snapping fixes. + +2004-01-05 MenTaLguY + + * src/uri-references.cpp, src/uri-references.h, + src/uri.cpp, src/uri.h, sp-item.cpp: + new URI code + +2004-01-04 MenTaLguY + + * src/object-ui.cpp: flattened group submenu + + * src/uri-references.cpp: fixed initialization bug; for + pre-existing references, the "release" signal wasn't being + connected + +2004-01-04 Peter Moulder + + * src/helper/bezier-utils.cpp: Greater use of NR::Point instead of + NRPoint. (Readability improved as a result.) + Get rid of now-unused sp_vector_add etc. functions. + Get rid of MAXPOINTS fixed upper limit, in the process making more efficient. + NewtonRaphsonFindRoot: handle the case where f'(u) <= 0. (Previously + it would seek a local maximum instead of minimum in this case.) + Rename lots of static functions according to our coding standards. + Fix some documentation. + Filter out any NaN points in the input. + Change the iteration cutoff from the square of the requested error to + 3 * the requested error. Change the "acceptable error" test from `<' + to `<='. + * src/helper/bezier_utils.h (sp_bezier_fit_cubic_full): change + arguments from NRPoint to NR::Point. + * src/sp-spiral.cpp: Adapt to sp_bezier_fit_cubic_full change. + Greater use of NR::Point instead of NRPoint. + + * src/helper/curve.h, src/helper/curve.cpp (sp_curve_moveto, + sp_curve_lineto, sp_curve_curveto): Add convenience wrappers that + take n NR::Point's instead of 2*n gdoubles. + + * src/helper/curve.h, src/helper/curve.cpp: Indicate that certain + functions don't modify the curve passed to them. + + * src/libnr/nr-types.h: operator[], operator+=, operator/=, unary operator-, + operator==, operator!=: new. Remove methods L1,L2,Linfty, move them to + functions in nr-point-fns.{h,cpp}. Rename Normalize to normalize with + more sophisticated non-inline implementation in nr-types.cpp. + * src/libnr/{nr-types.cpp,nr-point-fns.h,nr-point-fns.cpp}: new files. + * src/libnr/nr-types-test.cpp: new unit test file. + * src/libnr/Makefile.am: mention the new files. + + * src/Makefile.am: Add `check-recursive: all-recursive' dependency + (and a comment with related discussion). + + * src/xml/Makefile.am: Append $(EXEEXT) to executables in TESTS. + + * src/verbs.cpp (sp_action_get_title): Get rid of fixed-sized buffer. + + * src/nodepath.cpp: Miscellaneous cleanups including fixing + erroneous indentation, changing `g_list_length(foo) == 0' to `foo + == NULL', removing unused function closest_of_three, specifying + some functions as `static', adding doc. + + * src/inkscape.cpp (inkscape_remove_desktop): Change + `g_slist_length (foo) == 0' to `foo == NULL'. + + * src/dyna-draw-context.cpp (fit_and_split_calligraphics): Fix the + calculation of BEZIER_MAX_LENGTH. + Add assertions that the corresponding buffers haven't been overrun. + +2004-01-03 Ted Gould + + * src/helper/bezier-utils.cpp, src/inkscape-stock.h: + Fixing some Doxygen errors. + +2004-01-03 bulia byak + + * src/dialogs/dialog-events.{cpp|h}: Hide/unhide callbacks + + * all dialog files: Connected hide/unhide signals + + * src/inkscape.cpp src/inkscape.h: New functions for dialog hide, unhide, toggle + + * src/verbs.cpp src/verbs.h: New verb for dialog toggle + + * src/shortcuts.cpp: F12, quoteleft toggle dialogs + + * src/desktop.cpp: Zoom field width increased + + * src/node-context.cpp: Crash fix by Robert Crosbie + +2004-01-03 MenTaLguY + + * src/inkscape.cpp, src/inkscape.h, src/main.cpp: + fixes to preference loading + + * src/uri-reference.h: documented Inkscape::URIReference + + * src/sp-item.cpp: fixed double hunref problem + + * src/sp-item.cpp, src/uri-references.h, src/uri-references.cpp: + reworked Inkscape::URIReference a little + + * src/sp-item.cpp: masks now use Inkscape::URIReference as well + +2004-01-02 MenTaLguY + + * src/shortcuts.cpp: zoom in shortcut fix for german and other + keyboards from schumaml + + * configure.in: added SigC++ 1.2 dependency + + * src/document-private.h, src/document.h, src/document.cpp, + src/sp-item.h, src/sp-item.cpp, src/uri-reference.h, + src/uri-reference.cpp: rewrote URI monitoring code using SigC++ + + * src/inkscape.cpp: fix some portability issues + + * src/inkscape.cpp, src/widgets/icon.cpp, src/monostd.h: cleaning up + more platform stuff + + * src/dir-util.cpp, src/dir-util.h, src/dialogs/export.cpp: + remove sp_filename_from_path(); use g_path_from_filename instead + +2004-01-02 Alexander Clausen + + * src/spsvgview.cpp src/inkview.cpp src/Makefile.am: re-enabled svg viewer, + renamed to inkview to avoid name clash with spsvgview from sodipodi + +2004-01-01 bulia byak + + * src/desktop.cpp: Pass keyboard events from desktop widget to event contexts (if + there is no current item on the canvas); now all keys work regardless of mouse + position, so long as the document window has focus. + + * src/verbs.cpp src/verbs.h: New verbs for switching desktops + + * src/inkscape.cpp src/inkscape.h: New functions for switching desktops + + * src/nodepath.cpp: Fix crash: Tab when no nodepath + + * src/shortcuts.cpp: Ctrl-Tab, Shift-Ctrl-Tab cycle desktops + + * src/node-context.cpp src/event-context.cpp src/select-context.cpp: Do not consume + Ctrl-Tab/Shift-Ctrl-Tab in contexts. Explicitly run the corresponding verb in + event-context.cpp because otherwise GTK gobbles it. + + * src/splivarot.cpp: Edits in statusbar error messages + +2004-01-01 MenTaLguY + + * src/document-private.h, src/document.h, src/document.cpp, + src/sp-item.h, src/sp-item.cpp, src/uri-reference.h, + src/uri-reference.cpp: + added code to handle notifications when uri/id mappings + changed + + * src/desktop.cpp, src/style.cpp: compilation cleanups + + * src/libnr/nr-types.h: documented NR::Coord and NR::ICoord + +2003-12-31 MenTaLguY + + * removed *S variants of NR structs + + * src/libnr/gen_nr_config.c: removed! + + * src/xml/repr.h, src/xml/repr-private.h, src/xml/repr-io.cpp, + src/xml/repr.cpp: very preliminary comment support + + * configure.in, src/desktop.cpp, src/main.cpp: removed gtkmm + dependency for now + +2003-12-30 bulia byak + + * src/selection-chemistry.cpp: Grouping: Statusbar messages for nothing to group or + only one object, prevent crash when trying to group objects with different parents, + add new group to the members' common parent rather than to the document + root. Ungrouping: ungroup all groups in selection, statusbar messages for nothing to + ungroup. + + * src/node-context.cpp src/node-context.h src/knotholder.h src/knotholder.cpp + src/nodepath.h src/nodepath.cpp src/document-undo.cpp: Add repr listener in node + context recreating nodepath or knotholder when the repr was changed outside of the + node editor, remove the change selection signal hack in document_undo, fixes many + bugs. + +2003-12-28 Daniel Borgmann + + * src/main.cpp: Include gtkmm/main.h and gtkmmify the main loop + + * src/desktop.cpp: convert save confirmation dialog to Gtkmm + +2003-12-28 Peter Moulder + + * src/helper/Makefile.am: Try not to require Gnu make. + +2003-12-27 Alexander Clausen + + * src/interface.{h,cpp} (sp_ui_error_dialog): new function. + + * src/file.cpp src/main.cpp src/dialogs/export.cpp src/interface.cpp: use it + +2003-12-27 bulia byak + + * src/draw-context.cpp: Added drag_tolerance to bezier tool, messages to statusbar + + * src/knot.cpp: Do not consume Esc when not escaping knot dragging + + * src/select-context.cpp: Enable dragging objects selected within group + +2003-12-27 Peter Moulder + + * src/helper/bezier-utils.cpp: Simplifications & documentation. + +2003-12-26 bulia byak + + * src/document.cpp: added rel2abs to sp_document_set_uri, simplified + + * src/document.cpp: removed rel2abs into dir-util + + * src/dir-util.cpp src/dir-util.h: moved rel2abs and abs2rel here + + * src/modules/svg.cpp: Cleaned up svg_save: removed extraneous setting of docbase and + docname, moved uri_set before save, added comments + + * src/document.h src/document.cpp src/desktop.h src/desktop.cpp: item_at_point: add + into_groups; group_at_point: new + + * src/selection.cpp: When selecting a group, deselect all its descendants to prevent + double selection + + * src/select-context.cpp src/select-context.h: Added ctrl-click/ctrl-shift-click to + select/add to selection regardless of grouping + + * src/verbs.cpp: 2 more mnemo changes + +2003-12-26 Nathan Hurst + + * libnr: moving towards a fully class based Point and Matrix. + This change adds an initial sketch of matrix. + +2003-12-26 MenTaLguY + + * configure.in: added Gtkmm dependency, removed AC_FUNC_MALLOC + +2003-12-25 MenTaLguY + + * src/desktop.cpp: changed g_sprintf to g_strdup_printf + +2003-12-25 Daniel Borgmann + + * src/interface.cpp src/verbs.cpp: Fixed a few more mnemonics (mostly + duplicates) and changed shortcut labels to use uppercase letters like the + rest of the world. :-) + +2003-12-25 Alexander Clausen + + * src/file.cpp src/main.cpp src/dialogs/export.cpp: Made error dialogs + and progressbar transient and non-resizable; made export file selector + transient. + +2003-12-24 bulia byak + + * src/select-context.cpp: Added statusbar update in a few places + + * src/interface.cpp: Changed order of keyboard modifiers. Split view and object menus. + + * src/verbs.cpp: A couple fixes in mnemonics to better match shortcuts + + * samples/tux.svg: Added missing sodipodi namespace, added namedview + +2003-12-24 Alexander Clausen + + * src/file.cpp src/modules/system.cpp: Fix for 860199; returning NULL in + sp_module_system_open when doc == NULL; added error dialog. + + * src/main.cpp: Add error dialog when file given on command line does not + exist, and create an empty document in that case. + +2003-12-24 MenTaLguY + + * src/verbs.cpp: renamed 'XOR' to 'Exclude' on the menu + + * src/object-ui.cpp: moved object-specific menuitems out onto the + main context menu, instead of sequestered in their own submenus. + +2003-12-24 Alexander Clausen + + * src/interface.cpp: + Added partial DND (drop part only for now) for image/svg and image/svg+xml, + and a tweak to make uri-dnd with konqueror work. + +2003-12-24 Daniel Borgmann + + * src/interface.cpp src/verbs.cpp src/object-ui.cpp src/modules/menu.cpp: + Added mnemonics and some HIGification + + * src/verbs.cpp: New: sp_action_get_title(), get action name without + underscores (for use in dialog titles or other places without mnemonics) + +2003-12-23 bulia byak + + * src/helper/sp-canvas.h: float-to-double fix + + * src/sp-namedview.h src/sp-namedview.cpp: New namedview attributes for zoom and + window geometry; functions for updating them from a desktop and for setting up a + desktop from these attributes + + * src/preferences-skeleton.h: new options.savewindowgeometry + + * src/attributes.h src/attributes.cpp: New namedview attributes + + * src/desktop.cpp: Remove/comment out extraneous code. Float-to-double fixes, prevent + sliding when zooming in at max zoom. + + * src/file.cpp src/main.cpp src/interface.cpp: Added document_from_window and + window_from_document hooks to file opening and saving functions + + * src/document.cpp: New: inkscape_rel2abs() (based on g_rel2abs by Shigio Yamaguchi), + store absolute filenames in document->uri. Fixed reading namedview template from + preferences, fixed namedview template id, added comments. + + * src/nodepath.cpp: Ctrl + click node: delete node + + * src/desktop.cpp src/file.cpp src/file.h: New save confirm dialog (patch by spark) + +2003-12-23 MenTaLguY + + * src/desktop.cpp: shortened rulers to canvas dimensions for now + + * src/main.cpp, src/Makefile.am: renamed DATADIR to INKSCAPE_DATADIR + for the remaining platforms + +2003-12-23 Peter Moulder + + * src/desktop-snap.h, src/desktop-snap.cpp (all functions): + Indicate that the given point(s) aren't modified by these functions. + +2003-12-22 bulia byak + + * src/nodepath.cpp: Ctrl + Alt + click node: toggle smooth/cusp/symmetric. + + * src/select-context.cpp: No more snapping back to the origin because of drag + tolerance (once you trespass the drag tolerance limit once, it does not affect you + anymore). + + * src/knot.cpp: Used global drag tolerance, no snapping to the origin. + + * src/node-context.cpp: Click outside of nodepath deselects. Added drag tolerance for + selecting non-selected paths by click. Removed drag_escaped - there's no dragging to + escape in node context (only in knot). + +2003-12-22 bulia byak + + * src/nodepath.cpp src/nodepath.h>: restrict control handle movement with ctrl, alt, + shift; utility functions for radial coordinates; fixed several crashes when nodepath + operations are called but there's no nodepath + + * src/desktop.cpp: filled in sp_desktop_set_coordinate_status implementation, added + comment + +2003-12-22 Peter Moulder + + * src/helper/bezier-utils.cpp (sp_darray_center_tangent, + sp_darray_left_tangent, sp_darray_right_tangent), + src/helper/bezier-utils.h, src/sp-spiral.h, src/sp-spiral.cpp + (sp_spiral_get_tangent): + Make these functions static. + + * src/helper/bezier-utils.cpp (GenerateBezier): Back out accidental + commit of inserted g_assert(!isnan(bezier coordinate)). (Having a NaN + bezier coordinate is usually a problem, perhaps worth warning about, + but it's hard to make it impossible, so it shouldn't be g_assert.) + Reported by bulia byak. + +2003-12-22 Nathan Hurst + + * Added a new class NR::Point which will replace NRPoint + throughout the code, and replace things like .cx, .cx in the + circle structure. + +2003-12-21 MenTaLguY + + * Finally cleaned up the linker issues + +2003-12-21 Peter Moulder + + * src/Makefile.am (inkscapelib_src): + src/livarot/Makefile.am (libvarot_a_SOURCES): + Add some header files to SOURCES, so that `make distcheck' works. + + * src/style.cpp (sp_style_read_ipaint): Skip leading whitespace. + Fixes #853804. Improves rendering of Dia-exported SVG. + +2003-12-20 Peter Moulder + + * src/sp-spiral.cpp (sp_spiral_set): Fix clamping of t0 value: change + min from -1.0 to 0.0 as per all other t0 clamps and as required in some + circumstances by sp_spiral_get_xy. + (sp_spiral_fit_and_draw): Avoid useless adjacent dups in point sampling. + + (sp_spiral_fit_and_draw, sp_spiral_set_shape): Call proper tangent + routine instead of trying to estimate from samples. + (sp_spiral_get_tangent): New function. + + * src/helper/bezier-utils.cpp (sp_bezier_fit_cubic): Implement as a call + to sp_bezier_fit_cubic_r. + (sp_bezier_fit_cubic_full): Mark *tHat1 and *tHat2 as const. + (sp_bezier_fit_cubic_full, ChordLengthParameterize): Add minimal + handling for the case where the input data is a zero-length path. + (NewtonRaphsonRootFind): If "improved" value is NaN or +/-inf then + return the original. + + * src/libnr/nr-macros.h (CLAMP): Change the behaviour if the first + argument is NaN: previously it would return NaN, now it returns the + requested lower bound. Document the behaviour. Add an assertion that + the requested lower bound <= the requested upper bound. + + * src/libnrtype/nr-type-ft2.cpp (nr_typeface_ft2_lookup): Change apparently-erroneous + arguments to CLAMP, and add a FIXME comment indicating that the new arguments are + just a guess as to the original intent. + +2003-12-20 MenTaLguY + + * src/help.cpp, glade/about_svg.tmpl, glade/about.svg: + fixed version display in about box + + * src/desktop.cpp, src/desktop.h, src/document.cpp, src/document.h: + added sp_desktop_item_at_point() + +2003-12-19 bulia byak + + * src/sp-item.cpp src/sp-item.h: new sp_item_get_arenaitem (by mental) + + * src/main.cpp src/file.cpp src/file.h src/dialogs/export.cpp: export UI improvements + (patches from the tracker) + + * src/select-context.cpp: shift-click selection is now in root_handler, uses + sp_document_item_at_point(); changed shift-rubberband selection to always select + instead of toggle + + * src/document.h src/document.cpp: wrong order of arguments in overlap() fixed; new: + sp_document_item_at_point(), uses sp_item_get_arenaitem + + * src/Makefile.am: fix: ps.c -> ps.cpp + + * src/nodepath.cpp: dragging node with ctrl+alt restricts it to the directions of its + handles and their perpendiculars + +2003-12-19 MenTaLguY + + * Fixed most shortcut key regressions from the SPAction rework + + * Renamed the Inkscape class (struct really) to Inkscape::Application; we can now + use the Inkscape namespace. + + * src/toolbox.cpp, src/helper/action.cpp, src/helper/action.h: + SPActions now know their desktop, and toolbar buttons get it assigned correctly + + * src/desktop.cpp, src/interface.h, src/interface.cpp, src/verbs.cpp: + Verbs now use the desktop associated with an action rather than SP_ACTIVE_DESKTOP + +2003-12-18 Jon A. Cruz + + * fix for 859133; Reduced number of generated events. + +2003-12-18 Jon A. Cruz + + * src/widgets/sp-color-gtkselector.cpp: fix for 859131; Changed descriptive name of GTK+ + selector. + +2003-12-18 MenTaLguY + + * First steps towards making actions per-view + +2003-12-17 Jon A. Cruz + + * src/widgets/sp-color-notebook.cpp: fix for 859128; changed selectors to grow when + given more space. + +2003-12-17 Jon A. Cruz + + * Converted color selectors to C++ classes. + +2003-12-18 Nathan Hurst + + * Merged NRPointF and D, similarly Matrix and Rect. + +2003-12-18 Peter Moulder + + * src/toolbox.cpp: re-added spiral button (reverting MenTaLguY's change). + +2003-12-17 bulia byak + + * src/xml/repr-io.cpp src/xml/repr.h: fix to suppress formatting whitespace when + serializing text and its children + + * src/select-context.cpp: shift now prevents dragging objects, creating rubberband + instead + +2003-12-17 Nathan Hurst + + * provided some initial thoughts on how to do Points uniformly across inkscape. geom.h + * partial currying of zoom menu + +2003-12-17 MenTaLguY + + * src/toolbox.cpp: removed spiral button + +2003-12-16 bulia byak + + * src/nodepath.cpp src/nodepath.h: node drag is now restricted to hor/vert by ctrl + +2003-12-16 bulia byak + + * src/seltrans.cpp: fix for 860201; ctrl restricts rotation by 15 degrees (from + sodipodi); used new status display function + + * src/sp-text.cpp: removed non-printable char error into text-context, removed + extraneous assignment + + * src/verbs.cpp: typo fix + + * src/knot.cpp: in cancelling drag, use the knot's desktop instead of active; add + statusbar flash + + * src/draw-context.cpp: changing useful messages to statusf_flash, removing useless + debug output + + * src/nodepath.cpp: statusbar error message if joining nodes fails; expanded + update_statusbar + + * src/select-context.cpp: statusbar flash when esc cancels selection or drag + + * src/selection.cpp: expanded update_statusbar + + * src/text-context.cpp: used statusf_flash for no-break space, added non-printable + char error + + * src/tools-switch.cpp: added default statusbar message for each tool + + * src/desktop.cpp: new handler for status_set, with timeout; initialize message in + statusbar + + * src/view.cpp src/view.h: status_set signal: added msec, removed isdefault; added + _flash and _error functions for temporary statusbar display; added docs + +2003-12-14 Ted Gould + + * src/widgets/button.cpp, src/helper/action.h, src/helper/action.cpp, + src/verbs.h, src/verbs.cpp, src/toolbox.cpp, src/shortcuts.h, + src/shortcuts.cpp, src/interface.h, src/interface.cpp: + Adding in a sp_verb_t to identify verbs to make later conversions + easier. Also adding an arguement to the perform function of + SPActionEventVector so that data can be passed to modules (when + they're converted to action/verb). + +2003-12-14 MenTaLguY + + * src/view.h, src/view.c: added new utility things for setting status + + * src/draw-context.c, src/text-context.c, src/view.c, src/view.h: + retired sp_status_display() and sp_status_clear() + +2003-12-14 bulia byak + + * src/verbs.h src/verbs.c: changed 'offset' to 'outset' (more logical), added simplify + path command + + * src/interface.c: added sp_key_name to make shortcuts more readable, added simplify + path command, regrouped commands more logically + + * src/shortcuts.c: changed shortcuts for boolean ops, readability, minor cleanups + + * src/inkscape.c: increased max length of recent documents list to 15, fixed trimming + the list + + * src/seltrans.c: fixed crash when scaling very small objects at max zoom + +2003-12-12 MenTaLguY + + * doc/Makefile.am, Makefile.am, configure.in: include doc/ + subdirectory in distribution tarballs + + * src/widgets/icon.c: final tweaks for getting icon highlights + right on buttons (temporary hack, hopefully) + + * src/splivarot.cpp: compilation fix + + * src/widgets/sp-color-notebook.c: minor tweak so selector menu + is a little more obvious + +2003-12-12 bulia byak + + * src/svg/svg-path.c src/desktop.h src/libnr/gen_nr_config.c src/libnr/nr-object.c + src/libnr/nr-types.h: made all floats doubles and all shorts ints in libnr; maximum + zoom is increased to 256; SVG paths are stored with 8 digits precision (was 6) + +2003-12-11 bulia byak + + * src/node-context.c adding node edit statusbar updates + + * src/selection.c: update statusbar only if selector is active + + * src/tools-switch.c: update statusbar when selector is activated + + * src/nodepath.c src/nodepath.h: function for node edit statusbar display; fixes for + several tab-cycling and node-deleting bugs + + * src/sp-path.c: added description for SPPath (used in statusbar display) + + * src/draw-context.c: moved some messages from console to statusbar + + * src/view.c src/view.h: utility functions for statusbar display + + * src/text-context.c: statusbar display for unimode + +2003-12-10 Ted Gould + + * configure.in: Changing to 0.37cvs + +2003-12-10 bulia byak + + * src/verbs.c: SELECT_ALL is now tool-sensitive, comments + + * src/shortcuts.c: ctrl-a for the SELECT_ALL global verb; h and v for flips + + * src/interface.c: split edit menu into edit and object + + * src/node-context.c: removed ctrl-a, now taken care of by the global verb + + * src/nodepath.c: select_all silently returns if given null arg + + * doc/keyboard-shortcuts.txt: new shortcuts from wiki + +2003-12-09 bulia byak + + * src/helper/png-write.c: fix for png comments (from sodipodi) + + * src/nodepath.c: fix for 856700, 856686; a better control point positioning for + join_segment + + * src/shortcuts.c: fix default shortcut for star tool + + * src/prefs-utils.c src/prefs-utils.h: new *_limited functions to get data guarding + against through-the-roof values + + * src/select-context.c src/node-context.c: using *_limited functions to get preference + values + + * src/document-undo.c: fix in sp_document_maybe_done to combine same-key steps + + * src/selection-chemistry.c src/nodepath.c: put subsequent same-direction arrow-key + movements into one undo step + + * src/sp-text.c src/sp-text.h: removed the preservews argument of sp_text_insert + + * src/text-context.c src/text-context.h: if there's no text object selected, keys are + not consumed; fixed passing unconsumed keys to parent context; any non-hex-digit now + cancels unimode + + * src/dialogs/transformation.c: re-fixing pjrm's fix properly + +2003-12-08 bulia byak + + * src/sp-text.c: fixed typing non-ascii chars; copied (with fixes) treatment of + xml:space from sodipodi 0.33 + + * src/sp-text.h: small fix from sodipodi 0.33 + + * src/text-context.c: copied sp_text_context_preedit_reset and related code from + sodipodi 0.33; xml:space='preserve' is added to newly created text objects; esc + deselects; uncatched keys are passed on; misc fixes + +2003-12-08 MenTaLguY + + * src/widgets/button.c: put errors to rest for now + + * src/document-undo.c: removed code to limit undo list length + +2003-12-07 MenTaLguY + + * src/widgets/button.c: fixed unsignedness warning + +2003-12-06 bulia byak + + * src/dialogs/align.c: tooltip fix (from sodipodi) + + * src/libnr/nr-stroke.c: fix for 853827, rendering of short paths (from sodipodi) + + * src/sp-text.c src/sp-text.h src/text-context.c: enabled home/end in text (from sodipodi) + + * src/document-undo.c: increased MAX_UNDO to 512 + + * src/file.c src/dialogs/export.c: fix for 851012: the smallest possible exported png + is now 1x1 + + * src/widgets/font-selector.c: fix for 851789: no exponential display in font size field + +2003-12-06 MenTaLguY + + * src/desktop.c: permit the canvas widget to take keyboard focus + + * src/widgets/button.c, src/widgets/button.h: reworked perform + callback as separate callback, so we can use + g_signal_handlers_{un,}block...() on it rather than the stupid + semaphore counter thing I had originally. + + Also switched to sp_icon_new() instead of sp_icon_new_scaled(), as + otherwise the small icons were too small (but the large icons are + now smaller than they could be... darn it... ><) + +2003-12-05 Bryce W. Harrington + + * style.*, sp-path.*, sp-shape.*, more: Hooking up preliminary + support for path markers (arrowheads). Also adding + documentation, fixing if statement style, etc. + +2003-12-05 MenTaLguY + + * src/widgets/icon.c, src/widgets/button.c, src/widgets/button.h, src/toolbox.c: + Reworked SPButton to derive from GtkToggleButton. + + * src/svg/svg-length.c, src/helper/units.c: removed #ifdef WIN32 insanity + + * src/Makefile.am, src/extension.c, + src/extension.h, src/extensions-skeleton.h, + src/main.c, src/inkscape.c, src/toolbox.c: Removed dead code left + over from first extensions implementation + + * configure.in, src/main.c: removed freebsd-specific test and just check for fpsetmask() instead + + * src/verbs.c: fixed quit icon + +2003-12-04 bulia byak + + * src/toolbox.c: added convert to curves button, cosmetic changes in aux toolbar + + * src/text-context.c: made text editing via xml editor undoable + + * src/nodepath.c: new functions to duplicate node, fixes to node_break and selection + functions, new (presently unused) functions for saving/restoring node selection + + * src/node-context.c: shift-d to duplicate node, all keys now work regardless of capslock + + * src/document-undo.c: temp fix: undo emits selection_changed signal for node editor + to update display + + * src/selection.c: new function without arguments to emit change_selection signal + + * src/selection.h: new function without arguments to emit change_selection signal + + * src/nodepath.h: new functions to duplicate node, new (presently unused) functions + for saving/restoring node selection + +2003-12-04 MenTaLguY + + * src/desktop.c: rearranged toolbars so aux toolbar is topmost + * src/toolbox.c: made toolbars detachable + +2003-12-02 bulia byak + + * src/file.c: made open and save dialogs modal and transient + +2003-12-02 bulia byak + + * src/interface.c: removed tool attributes command + * src/preferences-skeleton.h: added branch for export dialog + * src/file.c: made import dialog transient + * src/verbs.c: changed some dialog names and tooltips + * src/shortcuts.c: changed shortcuts for transform and text dialogs + * src/dialogs/display-settings.c: fixed dialog title + * src/dialogs/export.c: made unsinkable, remembering size and position, added label + for filename + +2003-11-30 MenTaLguY + + * src/xml/repr-io.c, src/attributes.c, src/attributes.h, + src/sp-object.h, src/sp-object.c: merged basis for Oka's + xml:space support + + * src/toolbox.c: made tool buttons larger, aux buttons smaller + + * src/document-undo.c: fixed bug with undo/redo past the + beginning/end of the undo history + +2003-11-29 bulia byak + + * src/selection-ch emistry.c src/selection-chemistry.h src/verbs.c src/verbs.h + src/shortcuts.c src/interface.c: new function, verb, shortcut (shift-ctrl-v), menu + command: paste style (apply the style of copied object to selection). If more than + one object is copied, the first one in the clipboard list is taken as the source of + the style. + +2003-11-30 Peter Moulder + + * src/style.c (sp_style_merge_from_parent): Fix some + unsigned-related bugs with "font-weight=lighter", + "font-stretch=narrower", "opacity=...". + + * src/modules/system.c (sp_module_system_save): Partial fix for + unrecognized filetype: show a CRITICAL warning instead of + segfaulting due to uninitialized var. + + * src/document.c (sp_document_new), file.c (file_open_ok, + sp_file_open_dialog, sp_file_save_dialog, sp_file_do_import), + main.c (sp_main_console), src/module.c (sp_module_finalize, + sp_module_input_finalize, sp_module_input_build, + sp_module_output_finalize, sp_module_output_build), + src/sp-anchor.c (sp_anchor_set), src/sp-image.c (sp_image_set), + src/sp-text.c (sp_string_release, sp_string_read_content, + sp_string_set_shape), src/sp-use.c (sp_use_release), src/style.c + (sp_style_unref, sp_style_merge_property, + sp_style_merge_from_parent, sp_text_style_unref, + sp_style_read_istring), src/bonobo/embeddable-document.c + (sp_bonobo_stream_read, sp_embeddable_document_ps_save), + src/dialogs/stroke-style.c (sp_stroke_style_scale_line), + src/dialogs/text-edit.c (sp_text_edit_dialog_text_changed), + src/helper/sodipodi-ctrl.c (sp_ctrl_build_cache), + src/modules/ps.c (sp_ps_print_image), + src/widgets/font-selector.c (sp_font_preview_set_phrase), + src/widgets/gradient-image.c (sp_gradient_image_size_allocate), + src/xml/repr-action.c (coalesce_chgattr, coalesce_chgcontent, + free_action), src/xml/repr.c (repr_finalize, sp_repr_merge): + Minor cleanup: replace `if (POINTER_EXPR) g_free (POINTER_EXPR)' + with the simpler (more readable) `g_free (POINTER_EXPR)'. + +2003-11-29 Kees Cook + + * src/utest/.cvsignore: adding "Makefile" + * src/desktop.c: sp_desktop_pop_event_context could use uninit'd *ec + * src/desktop.h: missing declaration of sp_desktop_zoom_page_width + * src/libnrtype/nr-rasterfont.c: give *spx and srs default values + * dialogs/dialog-events.c: remove unused *w and *dtw + +2003-11-29 MenTaLguY + + * src/interface.c: switched to GNOME HIG menu style + + * src/toolbox.c: gave the aux toolbox a fixed (minimum) size so + the workspace will jiggle less as different tools are selected. + + * src/utest/Makefile.am, src/utest/utest.c, src/utest/utest.h, + src/xml/Makefile.am: turned the utest stuff into a giant .h + file again, which hopefully won't confuse things like the .inc + extension did. + +2003-11-29 bulia byak + + * shortening tooltips, new verb and menu command for zoom to page width + +2003-11-29 Bryce Harrington + + * README: Updating "Sodipodi" to "Inkscape", removing some + obviously obsolete bits. + + * inkscape.1.in, inkscape.pod: Totally rewriting manpage from + scratch. The old one appeared to be for some other application, + because it was just a list of options, 90% of which aren't + implemented. I chose to do it in POD for convenience, but hand + edited the 1.in file to remove bits about "Perl Documentation", + etc. + + * General: Some fixes to recently added code that broke the g++ + compile. + +2003-11-29 Peter Moulder + + * src/utest/Makefile.am, src/utest/utest.c, src/utest/utest.inc, + src/utest/utest.h, src/xml/Makefile.am, src/xml/repr-action-test.c: + Split utest.inc into utest.h and utest.c. Update users. + + Make utest.c,utest.h formatting conform more to doc/coding-style.txt. + + Have utest.c built into libutest.a (see src/utest/Makefile.am + comments). + + * src/xml/repr-action.c (reverse_log): Add doc comment. Rename some vars. + + * src/xml/repr-action.c (sp_repr_replay_log, sp_repr_undo_log), + src/xml/repr-action.h, src/document-undo.c (sp_document_cancel, + sp_document_redo, sp_document_undo): Remove the unused doc + argument to sp_repr_replay_log, sp_repr_undo_log. Update callers. + +2003-11-28 Peter Moulder + + * extensions/ai_input.inkmod, extensions/dia.inkmod, + extensions/svgz_input.inkmod, extensions/svgz_output.inkmod: + Change the filename extension from `foo' to `.foo'; i.e. the + filename must end in `.foo' to be considered a match, rather + than merely ending in `foo'. + + It appears that the sole users of this data are in src/system.c + (open_internal, save_internal). + + I've found no documentation needing updating, according to + `rgrep -i extension doc'. + + * src/system.c (open_internal, save_internal): Minor effec tweaks: + fewer strlen calculations. + + * src/dialogs/transformation.c: Fix uninitialized-var bug. + +2003-11-28 MenTaLguY + + * src/document.c, src/document-undo.c, src/document-private.h: + renamed SPDocumentPrivate::undo_size to ::history_size. Fixed + long-standing undo bug, where maybe_done() would neglect to + start a new transaction if the previous transaction log were + empty. + + * src/xml/repr-action-test.c, src/utest/utest.inc: made test + control structure a little clearer (hopefully) by hiding it. + Also some initial Doxygenification of the unit testing stuff. + + * src/Makefile.am: added utest/ subdir + + * doc/architecture.svg: reworked architecture diagram a bit + + * doc/class-hierarchy.dia: added first shot at documenting the + class hierarchy in Dia + + * src/modules/svg.c, src/modules/win32.c: change "...with + xmlns:sodipodi namespace" to "...with extension namespaces" + + * src/xml/repr-action.c: fixed log optimizer to check + SPReprAction::type before coalescing adjacent actions + +2003-11-27 Bryce + * doc/architecture.svg: Added architecture.svg to try to capture + the subsystems at a block layer level. Defining colors, working + up basic structure, etc. + * Adding defines, functions, etc. for allowing markers into + inkscape-stock.h, sp-marker.*, sp-path.c, sp-shape.h, style.*, + and dialogs/stroke-style.c + * Added some new UI utility functions to spw-utilities.* and + changed dialog/stroke-style.c to use them, in order to simplify + redundancies in the code a bit. + +2003-11-27 MenTaLguY + + * src/desktop.c: the coord status bar area should not have a + resize handle + +2003-11-27 bulia byak + + * all dialogs remember size and position across sessions + * all dialogs are unsinkable (re-transientizing to the current document) + * all dialogs are closeable by ctrl-f4 and ctrl-w, defocusable by esc + * dialogs titles unified, added shortcut display in the titles + +2003-11-27 MenTaLguY + + * src/utest/Makefile.am, src/utest/utest.inc: new minimalist + unit testing framework + + * src/xml/Makefile.am, src/xml/repr-action-test.c: some tests + for the XML transaction stuff + + * src/desktop.c: reshuffled the widgets, switched to an embedded + toolbox, switched to using real GtkStatusbars for the status bar, + and (for the present) nuked the body of + sp_desktop_set_coordinate_status() since it had been #ifdeffed + out for ages anyway + + * src/desktop.h: removed another constant #ifdef + + * src/widgets/button.c: lobotomized toggle buttons temporarily, + so multiple windows having independent tool states wouldn't confuse + toolboxes :/ .. the real fix is to rework SPAction and friends + to not be so global-minded + + * src/event-context.h: changed sp_ui_generic_menu to + sp_ui_context_menu + + * src/interface.c: reworked the menu structure and introduced + sp_ui_main_menubar to create the menubar; changed sp_ui_generic_menu + to sp_ui_context_menu + + * src/main.c: remove the floating toolbox + + * src/shortcuts.c: remove shortcuts related to the floating toolbox + + * src/verbs.c, src.verbs.h: removing floating toolbox verb + + * src/widgets/sp-toolbox.c, + src/widgets/sp-toolbox.h, + src/widgets/Makefile.am: nuked floating toolbox window + +2003-11-25 bulia byak + + * src/select-context.c src/preferences-skeleton.h: new option: drag tolerance + +2003-11-25 bulia byak + + * src/dialogs/dialog-events.c src/dialogs/dialog-events.h: new callback and utility + functions for defocusing + * src/widgets/sp-color-selector.c src/widgets/dash-selector.c + src/dialogs/stroke-style.c: spinbuttons, text fields defocus on enter + +2003-11-24 bulia byak + + * src/dialogs/display-settings.c src/display/canvas-arena.c: cursor tolerance now + stored in preferences, default changed to 2.0 + +2003-11-24 bulia byak + + * src/preferences-skeleton.h: new group for global interface options + * src/prefs-utils.h src/prefs-utils.c: new functions for double attributes + * src/select-context.c src/node-context.c: nudge distance (without alt) is taken from preferences (default 1 mm) + +2003-11-24 bulia byak + + New keys in node editor: + * esc deselects and cancels rubberband and node dragging + * ctrl-a selects all nodes + * tab and shift-tab cycle through nodes of the current shape + +2003-11-23 Bryce Harrington + + * Added include for document.h to knot.c for declaring + sp_document_undo, as g++ didn't like not having it declared. + +2003-11-22 bulia byak + + * unified handling of arrow keys in selector and node editor + * lots of new keys for switching tools and calling dialogs + * space works as temporary selector toggle + * new: tools-switch.{c,h} utilities for switching tools + * cleaned up zoom shortcts (1-5) + * keys for toggling grid (#) and guides (|) + * esc deselects, cancels rubberband selection, dragging or transformation + (in selector) + * quit (ctrl-q) now works everywhere + * new document is opened on startup if none was given on command line + * closing last open document shuts down the program + * floating toolbox is at most one copy, as are other dialogs + * toolbox command is moved to the dialogs menu, ctrl-` as shortcut + * document windows closeable by ctrl-f4 + * cleaned up status line messages, changed "items" to "objects" + * quit confirmation dialog appears near the cursor and is transient + * fix: killing quit confirmation dialog was interpreted as No instead + of Cancel + * preferences are now saved in case of a crash + * preferences are saved on exit + * new: prefs-utils.{c,h} utilities for handling preferences + * misc fixes + * misc shortcuts + +2003-11-18 Ted Gould + + * src/modules/system.c: Passed the wrong pointer. Fix is by + Robert Crosbie. + +2003-11-18 Ted Gould + + * src/widgets/sp-toolbox.c: Adding in an include for gtkimage.h + to get the stock functions. This fixes the build under g++. + +2003-11-18 Ted Gould + + * src/modules/extension.c: Changing mkstemp to g_mkstemp for + compatibility. + +2003-11-17 Kees Cook + + * configure.in: SF Patch #843537: more cast corrections from joncruz + +2003-11-17 Ted Gould + + * src/modules/init.c: Changing the process for handeling a directory + that doesn't exist. Now passing out a warning, and then returning. + The warning is on the command line so most users won't have to deal + with it (it _shouldn't_ happen anyway ;) Fixes: #843333. + +2003-11-17 Kees Cook + + * SF Patch #841940: autoconf update from joncruz + * SF Patch #842949: lpr fixes from Lynn Kerby + * SF Patch #842951: variable declaration fixes in interface.c + * SF Patch #842953: small color picker update from John Bintz + * SF Patch #842955: additional Darwin updates from Peter + * Fixed stroke style literal string bug that caused warnings + * SF Patch #842958: updated inkscape.desktop.in slightly + * SF Patch #843170: freetype include corrections + * SF Patch #843326: fixups for g++ compilation from joncruz + * Adding some more missing "extern C" sections for g++ compiles + * Small type corrections to quite g++ during -Wall + * Changed all the #endif // __cplusplus into a standard C comment + +2003-11-16 MenTaLguY + + * src/document.c: reworked sp_desktop_items_*in_box family to be layer-aware + +2003-11-16 Kees Cook + + * Cleaned up "desactivate" into "deactivate" + * Fixed GDK_SCROLL event from mouse wheel scrolling + * Cleaned up .cvsignore entries for fewer cvs warnings + +2003-11-16 MenTaLguY + + * dialogs/xml-tree.c: events should not be intercepted for the XML dialog + +2003-11-16 MenTaLguY + + * src/version.c: ME R DUM. Had the arguments to sscanf() reversed. + +2003-11-16 Ted Gould + + * Updating everything so that it builds under g++ again. Much + of the updates were to the recently checked in modules code. + +2003-11-16 MenTaLguY + + * New version code (version.c/version.h) + * Introduced inkscape namespace in parallel with sodipodi namespace + * Fixed a lot of attribute enum names to reflect sodipodi versus inkscape namespaces + * src/document.c: new version processing, plus namespace fixes + * SP_OBJECT_WRITE_INKSCAPE is now SP_OBJECT_WRITE_EXT + * Inkscape and Sodipodi versions are tracked separately + * First crack at layers! set inkscape:groupmode to "layer" or "group" depending on how you want a group to behave + * A little dead code removal + +2003-11-15 MenTaLguY + + * Mege Jon's improved src/help.c patch from the mailing list (with some temporary cruft of my own that I hope he'll forgive me for) + +2003-11-14 Ted Gould + + * Fixed up the module code alot. Now extentions are usable with + a XML file in the /usr/share/inkscape/modules directory. + +2003-11-12 Jon Cruz + * Fix warnings due to missing casts - nr-rasterfont.c (840539) + * Fix warnings due to missing casts - desktop-snap.c (840543) + * Fix warnings due to missing casts - help.c (840545) + +2003-11-11 Robert Crosbie + + * Remove kde option from configure (840504) + * Remove icon hash from sp_icon_new_full (840506) + +2003-11-11 magnethead + + * src/dialogs/transformation.c (sp_transformation_dialog_new): + Removed images from tabs + * src/dialogs/object-properties.c (sp_object_properties_dialog): + Removed images from tabs + +2003-11-11 Ted Gould + + * Starting 0.36 development + +2003-11-10 Ted Gould + + * Release 0.35 + +2003-11-08 Bryce Harrington + * Updated About dialog + * Fixed bug on Editing Windows dialog + +2003-11-08 Manny the Gnome + * Remove KDE dialog option + +2003-11-06 Bulia Byak + * Add cursor-key support + +2003-10-19 MenTaLguY + + * src/xml/repr-io.c (sp_repr_svg_read_node): handle CDATA + sections properly + + * Most of the tree. Unsodipodified pretty much everything I could + find. New temporary icons, etc etc... + +2003-10-23 Ted Gould + + * src/*/Makefile.am: Changing the include paths to make distcheck + get closer to passing. + +2003-10-22 Ted Gould + + * configure.in: Changing version to 0.32-hydra1. This is after + much discussion and serious contemplation (okay, we never really + got out the magic eight ball). + +2003-10-22 Ted Gould + + * src/dialogs/desktop-properties.c, src/widgets/spw-utilities.c, + src/widgets/spw-utilities.h: Cleaning up desktop properties by + abstracting things into functions. This patch was written by + Bryce Harrington and is tracker entry #822497. + +2003-10-21 Ted Gould + + * src/interface.c: Changing it so there is an Open Recent menu on + the Sodipodi menu and the toolbar menu. This removes some clutter + in the menu. This is tracker entry #820223 and the author is + unknown. + +2003-10-21 Ted Gould + + * src/dialogs/text-edit.c: Make it so that changes can be applied + to multiple blocks of text. This patch was submitted by Petr + Kovar and is tracker #816676. + +2003-10-17 Ted Gould + + * src/dialogs/object-properties.c: Applying a patch by Lynn Kerby + which is tracker number 799363. This makes it so that if just + the units are changed the object does not get updated. + +2003-10-16 Ted Gould + + * src/Makefile.am: Adding the modules to the linking of the + spsvgview executable. This fixes the KDE build. This was tracker + issue 819963 but unfortunately we don't know who submitted it. + +2003-10-15 Ted Gould + + * configure.in: Adding a -hydra to the version number. + +2003-10-15 Ted Gould + + * Changelog: Applying the patch from Mental to do transactions + in the XML. It is tracker number: 819745. More info to follow + which is (written by Mental) + + * src/document-private.h: removed old SPAction struct and + modified SPDocumentPrivate to use new SPReprAction type + + * src/document-undo.c: removed all sp_action stuff, + sp_document_priv_done(), and all repr callbacks + (sp_document_set_sensitive): start/suspend transactions on Repr + document + (sp_document_done): now just a wrapper for + sp_document_maybe_done(), of which it is a special case + (sp_document_maybe_done): use new transaction facility, and + properly trim undo list size to MAX_UNDO + (sp_document_cancel): new SPDocument method for aborting (and + undoing) current operation + (sp_document_undo, sp_document_redo): rewritten for transactions + + * src/document.c (sp_document_init): updated SPDocumentPrivate + initialization + (sp_document_destroy): clean up partial action list + (sp_document_idle_handler): removed undo stack warning + (sp_document_warn_undo_stack): removed + + * src/document.h: added sp_document_cancel() + + * src/sp-object.c (sp_object_invoke_build): minor cleanup + (sp_object_repr_child_added, sp_object_repr_remove_child, + sp_object_repr_order_changed, sp_object_repr_attr_changed, + sp_object_repr_content_changed): removed calls to document + callbacks + + * src/dialogs/xml-tree.c: enabled delete button for _all_ + attributes [I later plann on enabling/disabling it based on + a call to the repr's change_attr veto callback] + (after_tree_move): roll back the transaction if the node + didn't want to be moved + (on_attr_select_row_enable): used to be + on_attr_select_row_enable_if_not_id() + (cmd_indent_node, cmd_unindent_node): removed usage of + sp_repr_move in favor of simple operations with transactions + + * src/widgets/sp-xmlview-tree (repoint_nodes): no longer needed + (add_node): switched to an if cascade instead of a switch + statement, since SP_REPR_TYPE (repr) is no longer an integer + (tree_move): use simple operations instead of sp_repr_move + + * src/xml/Makefile.am: added sp-action.c to build + + * src/xml/repr-action.c, src/xml/repr-action.h: transaction + logging facility for reprs using linked lists of SPReprAction + structs (conceptually, logs) + + * src/xml/repr-private.h: introduced SPReprClass for different + node types and added SPRepr::doc field for doc pointer. + SPReprDoc is now a proper subclass of SPRepr. + + * src/xml/repr-util.c (sp_repr_move, sp_repr_transfer_ids): + removed + + * src/xml/repr.c: added logging macros and SPRepr subclassing + + * src/xml/repr.h: removed sp_repr_move() + +2003-10-09 Ted Gould + + * src/libnrtype/nr-type-directory.c: Applying a patch to + fix the compile from Vitaly Lipatov. + +2003-10-08 Ted Gould + + * glade/icons.svg src/nodepath.c src/nodepath.h + src/toolbox.c src/dialogs/node-edit.c src/dialogs/node-edit.h: + Adding another patch from Bob Jamison which is in the tracker + under 819054. This patch adds an alternate join function. It + also adds this function to the tool box with an icon. + +2003-10-08 Ted Gould + + * src/.cvsignore: Adding in spsvgview for cleaner diff's + +2003-10-08 Ted Gould + + * src/dialogs/item-properties.c: Submitting a patch from + Bob Jamison which is in the tracker under 819043. This adds + the ID to the item properties dialog. + +2003-10-06 Ted Gould + + * Changelog: Start of the hydra-october branch + +2003-10-06 Lauris Kaplinski + + * src/libarikkei/Makefile.am: New stuff from ariariki + + * src/libnrtype/nr-type-xft.c (nr_type_read_xft_list): Moved here + + * src/libnrtype/nr-type-directory.c (nr_type_build): From ariariki + (nr_type_read_private_list): Use libarikkei tokenizer + (nr_type_register): Made public + + * src/libnrtype/Makefile.am: Added libarikkei stuff + + * configure.in: Added libarikkei/Makefile + +2003-09-18 Mitsuru Oka + + * Initial IA-64 Linux support. + + * libnr/nr-object.h defined new type NRType. + + * src/desktop.c ... src/modules/win32.h ... many files: + modified all of the unsigned int GObject type by GType and + unsigned int NRObject type by NRType. + +2003-08-17 Lauris Kaplinski + + * src/libnrtype/nr-type-ft2.c (nr_typeface_ft2_setup): Check whether font + has assigned code points on BMP private area + (nr_typeface_ft2_lookup): Map BMP private area directly to glyph index only + if it is free, use planes F and 10 for direct mapping + +2003-08-17 Danilo Å egan + + * configure.in: Added "sr" and "sr@Latn" to ALL_LINGUAS. + +2003-07-23 Dmitry G. Mastrukov + + * configure.in: Added Belarusian to ALL_LINGUAS. + +2003-07-21 Christian Neumair + + * src/verbs.c: Fix another typo (preciely->precisely). + +2003-07-21 Christian Neumair + + * src/widgets/paint-selector.c: Fix a typo (colospace->Colorspace). + +2003-07-15 Masatake YAMATO + + * src/helper/sp-ctrlline.h: Fix a typo(x2->x1). + +2003-07-12 Yukihiro Nakai + + * src/text-context.c (sptc_preedit_changed): New signal handler + (sp_text_context_setup): Connect "preedit_changed" signal + (sp_text_context_root_handler): Return TRUE (needed for Gtk+ IM) + + * src/verbs.c (sp_verbs_init): Wrap action name and tip into _() + +2003-07-11 Lauris Kaplinski + + * src/event-context.c (sp_event_context_private_root_handler): Handle + GDK_SCROLL (thanks to Tomas Znamenacek) + + * src/xml/repr-util.c (sp_xml_dtoa): Do not print trailing zeroes + + * src/xml/repr.c (sp_repr_document_new): Removed ATTLIST xmlns:xlink + + * src/libnr/nr-svp-private.h: New file + +2003-07-09 Lauris Kaplinski + + * src/libnr/nr-stroke.c: Implement most functionality + + * src/libnr/nr-svp-uncross.c (nr_svl_uncross_full): Process some corner cases + properly + +2003-07-07 Masatake YAMATO + + * src/shortcuts.c (sp_shortcut_table_load): set shortcut + for SP_VERB_EDIT_SELECT_ALL. + + * src/selection-chemistry.[ch] (sp_edit_select_all): New function. + + * src/verbs.c (sp_verb_action_edit_perform): Added case + SP_VERB_EDIT_CLEAR_ALL and SP_VERB_EDIT_SELECT_ALL. + (SP_VERB_IS_EDIT): Extended to SP_VERB_EDIT_SELECT_ALL. + +2003-07-04 Lauris Kaplinski + + * src/svg/svg-length.c (sp_svg_length_set): New method + + * src/sp-spiral.c (sp_spiral_write): Write path here + + * src/sp-image.c (sp_image_repr_read_image): Treat NULL docbase as current directory + + * src/sp-gradient.c (sp_gradient_write): Merged code with flatten_attribute + (sp_lineargradient_write): Ditto + (sp_radialgradient_write): Ditto + + * src/rect-context.c (sp_rect_context_root_handler): Get motion hints + + * src/helper/sp-canvas.c (SP_CANVAS_UPDATE_PRIORITY): Use higher priority + + * src/document.c (SP_DOCUMENT_UPDATE_PRIORITY): Use higher priority + +2003-06-30 Lauris Kaplinski + + * src/libnrtype/nr-type-ft2.c (nr_typeface_ft2_glyph_outline_get): Do not + load outlines multiple times, fixes serious memleak + +2003-06-28 Lauris Kaplinski + + * src/dialogs/text-edit.c (sp_text_edit_dialog): Added line spacing combo + (sp_text_edit_dialog_update_object): Update line spacing + (sp_text_edit_dialog_read_selection): Update control + + * src/sp-text.c (sp_text_set): Parse "sodipodi:linespacing" + (sp_text_set_shape): Use line spacing + + * src/attributes.c: Added "sodipodi:linespacing" + +2003-06-27 Lauris Kaplinski + + * src/dialogs/desktop-properties.c (sp_dtw_border_layer_toggled): New callback + (sp_desktop_dialog_new): Added border layer + (sp_dtw_update): Track border layer + + * src/spsvgview.c: Implement slideshow + + * src/sp-namedview.c (sp_namedview_set): Track borderlayer + + * src/desktop.c (sp_desktop_new): Add page border directly to + main group + (sp_dt_namedview_modified): Track border layer + + * src/attributes.c: Added "borderlayer" + +2003-06-22 Lauris Kaplinski + + * src/sp-pattern.c (sp_pattern_update): Implemented, patterns show up again + (sp_pattern_painter_new): Painter is not GObject anymore, fixes crash + (sp_pattern_painter_free): Ditto + + * src/sp-root.c: Removed namedview tracking + + * src/sp-object-repr.c (sp_object_type_lookup): Do not register GUI types + (sp_object_type_register): New method + + * src/sp-namedview.c (sp_document_namedview): Moved it here to clean + up dependency chain + + * src/sp-item-group.c (sp_item_group_get_child_by_name): New method + + * src/main.c (sp_main_gui): Register GUI object types + (sp_main_console): Ditto + + * src/document.c (sp_document_create): Check for namedview using name only + + * src/Makefile.am (spsvgview_SOURCES): Uncommented spsvgview + + * src/libnr/nr-object.c: Use listener arrays instead of lists + +2003-06-20 Lauris Kaplinski + + * configure.in: Version 0.33pre + +2003-06-19 Masatake YAMATO + + * src/dialogs/desktop-properties.c (sp_color_picker_clicked): Enable "Close" + button. + (sp_color_picker_window_close): New function. + +2003-06-18 Lauris Kaplinski + + * src/dialogs/object-properties.c (sp_object_properties_dialog_destroy): Disconnect + signals here, fixes crash + +2003-06-18 Masatake YAMATO + + * src/toolbox.c (sp_toolbox_*_create): passed tt to + sp_toolbox_new. + + * src/dialogs/align.c (sp_align_add_button): passed a + GtkTooltips object to sp_button_new_from_data. + (sp_quick_align_dialog): created a new GtkTooltips object + and passed it to sp_align_add_button. + + * src/widgets/sp-toolbox.c (sp_toolbox_new): passed a + GtkTooltips object to sp_button_new_from_data. + Fix a spelling miss. + + * src/widgets/sp-toolbox.h (sp_toolbox_new): passed a + GtkTooltips object. + +2003-06-17 Lauris Kaplinski + + * src/sp-image.c (sp_image_set): Fix potential crash + (sp_image_update): Move code here, so canvas items do not dereference + destroyed pixbuf data + + * src/seltrans.c (sp_sel_trans_handle_request): Reverse shift behaviour for + rotation (thanks to Pat) + +2003-06-16 Lauris Kaplinski + + * src/verbs.c: Added 'print direct' option + + * src/interface.c (sp_ui_file_menu): Added print direct if needed + + * src/toolbox.c (sp_toolbox_file_create): Compose print + print direct if needed + +2003-06-15 Lauris Kaplinski + + * src/modules/ps.c (sp_module_print_plain_setup): Added bitmap/ps choice and + preferred bitmap resolution selector + (sp_module_print_plain_finish): If user prefers bitmap printing, composite + full page from NRArena here + +2003-06-13 Lauris Kaplinski + + * src/event-context.c (sp_event_context_private_root_handler): Removed + desktop dialog double-click binding + + * src/widgets/icon.c (sp_icon_new_scaled): New method + (sp_icon_new_full): Refactored static method + (sp_icon_image_load_svg): Use scale factor + + * src/xml/repr-io.c (sp_repr_do_read): Unref node after attaching + (sp_repr_svg_read_node): Ditto + + * src/xml/repr.c (sp_repr_document_new): Ditto + +2003-06-12 Lauris Kaplinski + + * src/modules/ps.c: Ported Ascii85 filter from The GIMP + +2003-06-09 Lauris Kaplinski + + * src/modules/kde.cpp (sp_kde_get_save_filename): New method + (sp_kde_get_write_filename): New method + (sp_kde_get_open_filename): Use dir/filter/title + + * src/file.c (sp_file_open_dialog): Use KDE file dialog if WITH_KDE + (sp_file_save_dialog): Ditto + (sp_file_import): Ditto + +2003-06-05 Lauris Kaplinski + + * src/print.c: Only high-level stuff + + * src/modules/gnome.c: Moved gnome print frontend here + + * src/modules/ps.*: Moved plain print frontend here + +2003-05-25 Lauris Kaplinski + + * src/sp-item.h: Removed ::menu and ::knot_holder virtual methods + + * src/object-edit.c: New file, collect all knotholder methods from + item implementations here + + * src/object-edit.h (sp_item_knot_holder): New file + + * src/object-ui.c: New file, collect all Gtk related methods from + object implementations here + + * src/object-ui.h (sp_object_menu): New file + +2003-05-24 Lauris Kaplinski + + * src/print.c (sp_print_preview_document): Use ::set_preview if present + + * src/module.h: Added virtual methof for setting preview + + * src/helper/kde.cpp (sp_module_print_kde_finish): Got working + (sp_module_print_kde_set_preview): New method + +2003-05-18 Hans Breuer + + * src/monostd.h : (new file) some defines and includes + mostly to make up the WIN32 lack of unistd.h + + * config.h.win32 src/makefile.msc src/*/makefile.msc : + (new files) to build Sodipodi on win32 with M$ toolchain + + * src/winmain.c : (new file) WinMain in it's own file simply + calling main() + * src/main.c : build the common main() for win32 too + + * src/sodipodi.rc : (new file) to compile in the application + icon on win32 + + * src/file.c : use G_DIR_SEPARATOR[_S] instead of '/' ["/"] + make the file selection work better on win32 + + * src/sp-image.c : read images defined by xlink:href="file://... + + * src/sodipodi.c : #inculed "monostd.h" to get S_ISDIR and + S_ISREG on win32 + + * src/libnr/nr-values.h : when building as DLL exporting + variables is quite ugly. Define some constant matrices as + static for win32 to avoid exporting. + + * src/libnrtype/nr-type-directory.c : #include + for win32::open() etc. + + * src/libnrtype/nr-type-w32.c : #ifdef HANGUL_CHARSET, + older SDK headers don't have it + + * src/libnrtype/nr-type-w32.H : #define WIN32_LEAN_AND_MEAN + before including to reduce namespace pollution + + * src/svg/svg-length.c : #include to get WIN32 + + * src/widgets/icon.c : S_ISREG, S_ISDIR + + * src/xml/sp-xml.def src/svg/sp-svg.def + src/libnr/sp-libnr.def src/libnrtype/sp-libnrtype.def : + (new files) to export functios from modules built as DLLs + + * src/helpers/gnome-utils.c(gnome_uri_list_extract_filenames) : + use g_filename_from_uri() + * src/toolbox.c src/interface.c : don't leak the uri list + + * src/xml/repr-util.c : use g_strcasecmp for portability + * src/svg/svg-length.c : ... and g_snprintf + +2003-05-18 Lauris Kaplinski + + * src/sp-item.c (sp_item_invoke_print): Only if item is printable + + * src/display/nr-arena-item.c (nr_arena_item_set_visible): New method + (nr_arena_item_invoke_render): Honour visibility + + * src/dialogs/item-properties.c (sp_item_widget_printability_toggled): Implement + + * src/sp-item.c (sp_item_set): Added "sodipodi:printable" attribute + +2003-05-14 Lauris Kaplinski + + * src/widgets/button.c (sp_button_set_composed_tooltip): Add primary shortcut + dynamically to tooltip + +2003-05-13 Lauris Kaplinski + + * src/toolbox.c (sp_maintoolbox_create_toplevel): Use sp_window_new + + * src/helper/window.c: New file, implement shortcut processing + + * src/helper/window.h: New file + +2003-05-12 Lauris Kaplinski + + * src/text-context.c (sp_text_context_forget_text): Set object to + NULL before destroying, so resulting selection::changed does not mess up + + * src/selection-chemistry.c: Removed undo and redo frontends + + * src/shortcuts.c: Moved shortcut code here + +2003-05-11 Lauris Kaplinski + + * src/zoom-context.c: Removed bogus zoom ui handlers + + * src/sodipodi.c (sodipodi_init): Initialize some shortcuts + + * src/toolbox.c (sp_toolbox_button_clicked): New callback + (sp_toolbox_button_new_from_verb): New method + (sp_toolbox_zoom_create): Use verbs + + * src/interface.c (sp_ui_menu_activate): Universal callback + (sp_ui_menu_append_item_from_verb): New method + (sp_ui_view_menu): Use verbs for zoom menu items + + * src/event-context.c (sp_event_context_private_root_handler): Use actions for + certain keycodes + + * src/verbs.c: New file + + * src/verbs.h: New file + + * src/helper/action.c: New file + + * src/helper/action.h: New file + +2003-05-07 Lauris Kaplinski + + * src/libnr/nr-svp-uncross.c (nr_svl_uncross_full): Break slice endpoints if + there can be potential crossing + +2003-05-06 Lauris Kaplinski + + * src/libnr/nr-svp-render.c (nr_svp_render): Fix some running sum problems + +2003-05-04 Lauris Kaplinski + + * src/libnrtype/nr-rasterfont.c (nr_rasterfont_generic_glyph_mask_render): Render + using NRSVP and mask OR + (nr_rasterfont_ensure_glyph_slot): Build NRSVP + +2003-05-03 Lauris Kaplinski + + * src/helper/Makefile.am: Removed art-utils.h + + * src/libnr/nr-svp.c (nr_svl_build_finish_segment): New helper + (nr_svl_build_moveto): Ditto + (nr_svl_build_lineto): Ditto + (nr_svl_build_curveto): New helper + (nr_svl_from_art_vpath): Use NRSVLBuild + (nr_svl_from_art_bpath): New method + +2003-05-02 Lauris Kaplinski + + * sodipodi.desktop.in: Updated by Michael Terry + +2003-05-01 Lauris Kaplinski + + * src/svg/svg-length.c (sp_svg_number_write_d): Fixed rounding overflow + +2003-05-01 Christian Schaller + * Fixed up desktop.in file to conform to latest freedesktop standard + * Fixed up spec.in file to actually work + * Added missing extensions-skeleton.h to makefile + * Added spec file to EXTRA_DIST + +2003-05-01 Lauris Kaplinski + + * src/display/nr-arena-item.c (nr_arena_item_children): Return correct + value (thanks to MentaLguY) + +2003-04-29 Lauris Kaplinski + + * src/libnr/nr-svp.h: Use more compact format for segments + + * src/libnr/nr-svp.c (nr_svp_from_svl): Use max segment length + +2003-04-28 Lauris Kaplinski + + * src/libnr/nr-svp-render.c (nr_svp_render): New method + (nr_pixblock_render_svp_mask_or): New method + (nr_pixblock_render_svl_mask_or): Renamed old one + (nr_svl_render): Ditto + + * src/libnr/nr-svp.c (nr_svp_point_wind): Implement + (nr_line_point_distance2): Helper + (nr_svp_point_distance): Ditto + (nr_svp_from_svl): New method, implemented packed format and + renamed old one to S(orted)V(ertex)L(ist) + (nr_svp_free): Ditto + + * src/display/nr-arena-shape.h: Port all basics to NRSVP + +2003-04-27 Lauris Kaplinski + + * src/knotholder.c (knot_ungrabbed_handler): Flush object here + + * src/xml/repr-util.c (sp_xml_dtoa): Take '-' into accounti if + copying integral part + + * src/svg/svg-length.c (sp_svg_length_update): New method + + * src/sp-spiral.c (sp_spiral_update): New method + + * src/sp-star.c (sp_star_update): New method + + * src/sp-ellipse.c (sp_genericellipse_update): Use generic ::set_shape + + * src/sp-rect.c (sp_rect_update): Use generic ::set_shape + +2003-04-24 Lauris Kaplinski + + * src/libnr/nr-svp-uncross.c (nr_svp_uncross_full): Concat segment start only if + within epsilon, snap intersection point at yslice, if close + +2003-04-23 Lauris Kaplinski + + * src/widgets/sp-color-slider.c (sp_color_slider_paint): Use proper style painters, + so Gdk/Gtk crash bug does not show up anymore + + * src/xml/repr-io.c (sp_repr_read_file): Substitute entities (by MentaL) + (sp_repr_read_mem): Ditto + + * src/style.c (sp_style_merge_from_style_string): Complain only if not the end + of the style string (thanks to MenTaL) + +2003-04-22 Lauris Kaplinski + + * src/print.c (sp_module_print_plain_begin): Magic by MenTaL + + * src/libnr/nr-svp-uncross.c (nr_svp_uncross_full): Works properly now for + all stress-tests except zap. + +2003-04-18 Lauris Kaplinski + + * src/display/nr-arena-shape.c (nr_arena_shape_update): Switch fill + completely to new renderer + (nr_arena_shape_render): Ditto, but use masks as before + + * src/libnr/nr-svp-uncross.c (nr_svp_uncross_full): Pass most stress-tests + +2003-04-15 Lauris Kaplinski + + * src/libnr/nr-svp-render.c (nr_pixblock_render_svp_mask_or): new method + (nr_pixblock_render_svp_rgba): Frontend, implement for all pixblock modes + (nr_svp_run_A8_OR): Run callback implementation + (nr_svp_run_R8G8B8): Ditto + (nr_svp_run_R8G8B8A8P_EMPTY): Ditto + (nr_svp_run_R8G8B8A8P_R8G8B8A8P): Ditto + (nr_svp_run_R8G8B8A8N_R8G8B8A8N): Ditto + (nr_svp_render): Implement using generic run callbacks + +2003-04-14 Lauris Kaplinski + + * src/libnr/nr-svp-render.c (nr_pixblock_render_svp_rgba): Do runs properly, + skip if coverage stays 0 + +2003-04-13 Lauris Kaplinski + + * src/libnr/nr-svp-render.c: Moved here from old arena code + + * src/libnr/nr-svp-render.h: Ditto + + * src/libnr/nr-svp.c: Ditto + + * src/libnr/nr-svp.h: Ditto + + * src/display/nr-arena-shape.h: Optional experimental new renderer + + * src/libnrtype/nr-typeface.h: Port to NRObject + + * src/display/canvas-arena.c (sp_canvas_arena_init): Use active object + listener instead of g-signals + (sp_canvas_arena_destroy): Ditto + + * src/display/nr-arena.h: Derive from NRActiveobject + + * src/display/nr-object.c (nr_object_delete): proper lifecycle management + (nr_object_setup): Ditto, automatic object + (nr_object_release): Ditto + (nr_active_object_get_type): Added NRActiveObject + + * src/display/nr-object.h: Added NRActiveObject + +2003-04-12 Lauris Kaplinski + + * src/display/nr-object.c: Reimplement in standalone way + + * src/display/nr-object.h: Reimplement in standalone way + +2003-04-06 Lauris Kaplinski + + * src/sp-marker.c (sp_marker_show_dimension): Reimplement + (sp_marker_show_instance): Ditto + + * src/display/nr-arena-shape.c (nr_arena_shape_finalize): Detach markers + + * src/sp-shape.c (sp_shape_update_marker_view): Test orientation + +2003-03-25 Lauris Kaplinski + + * src/display/nr-arena-item.c: Removed ::event signal + + * src/display/nr-object.h: Frontend for future glib-free object system + +2003-03-21 Lauris Kaplinski + + * src/sp-shape.c (sp_shape_update): Update marker properly + (sp_shape_set_marker): Parse all three marker types + + * src/sp-marker.c (sp_marker_update): Set reference point in child2parent matrix + (sp_marker_show_dimension): Copy and set arena items properly + (sp_marker_show_instance): Set base transfoarm and scale by line width if needed + +2003-03-17 Lauris Kaplinski + + * src/uri-references.c (sp_uri_reference_resolve): Allow '_' and + '-' in xlink names. + +2003-03-15 Lauris Kaplinski + + * src/display/nr-arena-item.h: Made opacity 8-bit integer + +2003-03-12 Lauris Kaplinski + + * src/sp-marker.c (sp_marker_update): Do it properly + (sp_marker_write): Do it properly (almost) + +2003-03-11 Lauris Kaplinski + + * src/print.c (sp_module_print_plain_class_init): Use correct destructor + + * src/sp-marker.c (sp_marker_set): Implement all attributes + +2003-03-09 Lauris Kaplinski + + * src/sp-object-repr.c (sp_object_type_lookup): Added marker type + + * src/sp-marker.h: New file + + * src/sp-marker.c: New file + + * src/display/nr-arena-image.c (nr_arena_image_render): Use pixblock + area instead the active area (that may be bigger) + + * src/helper/kde.cpp: Added SPModulePrintKDE object + (sp_kde_get_module_print): Contructor + + * src/print.c: Port to modules, add KDE option + + * src/module.c (sp_module_register): Check for id, fix crash + (sp_module_unregister): Ditto + (sp_module_print_get_type): Implement SPModulePrint + + * src/document.h: Renamed private to priv to be nice with c++ + + * src/Makefile.am (kdeldadd): Added LIB_KDEPRINT + + * configure.in: Enable modules by default + +2003-03-04 MenTaLguY + + * src/desktop.c: changed zoom_status to a spin button with logarithmic increment and a handy context menu + (sp_dtw_zoom_*): added various event handlers for the new zoom spin button + (sp_desktop_zoom_page): factored out code duplicated with zoom-context.c + (sp_desktop_zoom_selection): ditto + (sp_desktop_zoom_drawing): ditto + (sp_desktop_widget_init): removed unused SPDesktopWidget::zoom member and replaced zoom label with a spin button + + * src/desktop.h: removed unused SPDesktopWidget::zoom member, added new sp_desktop_zoom_* methods + + * src/zoom-context.c (sp_zoom_drawing): factored out code to desktop.c + (sp_zoom_page): NRRectD -> NRRectF, factored out code to desktop.c + (sp_zoom_selection): factored out code to desktop.c + +2003-03-06 Lauris Kaplinski + + * src/helper/Makefile.am: Compile KDE module if needed + + * src/main.c (sp_main_gui): Initialize/shutdown KDE module if WITH_KDE + + * src/file.c (sp_file_open_dialog): Use KDE file dialog, if WITH_KDE + + * src/Makefile.am: Add KDE libraries if needed + + * configure.in: Added --with[out]-kde configuration option + + * autogen.sh: Added (again) libtoolize + + * acinclude.m4: KDE specific autostuff + + * src/helper/kde.cpp: New file + + * src/helper/kde.h: New file + + * src/helper/kde-private.h: SPKDEBridge sefinition for moc preprocessor + +2003-03-03 Lauris Kaplinski + + * src/widgets/sp-color-slider.h: Use LGPL + + * src/widgets/sp-color-slider.c: Use LGPL + + * src/libnr/nr-rect.h: Use sensible NULL/empty semantics for union and intersection + + * src/libnr/nr-rect.c: Ditto + + * src/libnr/gen_nr_config.c: Generate basic typedefs (borrowed fromlibart) + + * src/display/nr-arena-item.c (nr_arena_item_invoke_update): Cleanup + (nr_arena_item_invoke_render): Ditto + +2003-03-01 Lauris Kaplinski + + * src/modules/*: Various module implementations by Ted Gould + + * extensions/*: Put various unsorted extensions stuff here + + * src/module.c: New file + + * src/module.h: New file + + * src/draw-context.c (sp_draw_context_root_handler): Use 'a' instead of '+' + as append/new toggle + (spdc_concat_colors_and_flush): Cut continuation tolerance to avoid extra points at corners + (spdc_pen_set_point): Draw line segments if appropriate + +2003-02-25 Lauris Kaplinski + + * src/main.c (main): Use bind_textdomain_codeset to force utf-8 encoding + (sp_main_console): Init gdk if WITH_XFT + + * src/file.c (sp_export_get_rows): Do not set EMPTY flag on pixblock, or background + will be forgotten + +2003-02-24 Lauris Kaplinski + + * src/dialogs/align.c (sp_quick_align_dialog): Added "distribute" tab + (sp_align_distribute_h_clicked): New method + (sp_align_distribute_v_clicked): Ditto + + * configure.in: Removed PACKAGE_LOCALE_DIR definition + + * src/Makefile.am (INCLUDES): Set PACKAGE_LOCALE_DIR here + + * configure.in: Skip xft checking if fontcofig present + +2003-02-23 Lauris Kaplinski + + * src/print.c (sp_print_fill): Use new paint server signature (does it work?) + + * src/document.c (sp_document_idle_handler): Use new flags signature + (sp_document_ensure_up_to_date): Ditto + + * src/sp-shape.c (sp_shape_modified): Removed style_modified, instead set + style here, if flags indicate the need + + * src/sp-text.c (sp_tspan_update): Calculate relative distances here + (sp_text_update): Ditto + + * src/sp-object.h: Split update and modified flags, involves changes in + most places actually using them + + * src/gradient-chemistry.c (sp_gradient_ensure_private_normalized): Recycle + available gradients, instead of always creating new + (sp_gradient_ensure_radial_private_normalized): Ditto + + * configure.in: Version 0.32pre + +2003-02-22 Lauris Kaplinski + + * src/sp-text.c (sp_text_set_shape): Honour single dx and dy attributes + + * configure.in: Added check for fontconfig to retrieve nonstandard include directories + +2003-02-21 Lauris Kaplinski + + * src/sp-image.c (sp_image_set): Set canvas item properties in ::update + (sp_image_update): Implement + + * src/dialogs/fill-style.c (sp_fill_style_widget_paint_changed): Set CMYK before RGB + + * src/dialogs/stroke-style.c (sp_stroke_style_paint_changed): Set CMYK before RGB + +2003-02-20 Lauris Kaplinski + + * src/sp-gradient.c (sp_gradient_rebuild_vector): Fix crash if 2 stops coincide + + * src/libnrtype/nr-rasterfont.c (nr_rasterfont_generic_glyph_mask_render): Get real + bounding box, clip to pixblock area for SVP glyphs + + * src/sp-polygon.c (sp_polygon_write): Write points always + +2003-02-18 Lauris Kaplinski + + * src/dialogs/export.c (sp_export_dialog): Default to document name + png + (sp_export_spinbutton_new): Pack more functions here + + * src/sp-chars.c (sp_chars_update): Implement + + * src/sp-text.c (sp_tspan_update): Implement + + * Makefile.am: Port back to glib gettext + + * configure.in: Port back to glib gettext + + * autogen.sh: Copied working version from The Gimp + + * src/helper/sp-canvas.c (sp_canvas_paint_rect): Try to fit area into pixelstore + instead of using default image size always + +2003-02-17 Lauris Kaplinski + + * src/sp-path.h: Turned SPPath/SPShape hierachy upside down, so they make sense + now, when we do not derive text and clippath from SPPath anymore + + * src/sp-shape.h: Ditto + +2003-02-16 Lauris Kaplinski + + * src/file.c (file_open_ok): Set directory if OK clicked on it (thanks to Aron Rubin) + (file_import_ok): Ditto + + * src/sp-ellipse.c (sp_round): Fix sp_round + +2003-02-15 Lauris Kaplinski + + * src/widgets/paint-selector.c (sp_paint_selector_system_color_set): New method + (sp_paint_selector_set_mode_color): Added 'get from dropper' checkbox + + * src/dialogs/object-properties.c (sp_object_properties_color_set): Handler + of system 'color_set' signal, used for getting color value from dropper + + * src/dialogs/stroke-style.c (sp_stroke_style_paint_system_color_set): New method + + * src/dialogs/fill-style.c (sp_fill_style_widget_system_color_set): New method + + * src/toolbox.c (sp_toolbox_draw_create): Added dropper tool + + * src/sodipodi.c (sodipodi_class_init): Added 'color_set' signal + (sodipodi_set_color): Frontend to signal + (sodipodi_init_config): Use config_name instead of hardcoded 'preferences' + + * src/dropper-context.c (sp_dropper_context_root_handler): Scale colors + to [0.0 - 1.0] range and signal hub + + * src/widgets/menu.c: New file, implement sensible menu API + + * src/widgets/menu.h: New file + +2003-02-13 Lauris Kaplinski + + * src/dropper-context.h: New file + + * src/dropper-context.c: New file + +2003-02-11 Lauris Kaplinski + + * src/desktop.c (sp_desktop_widget_init): Create tooltips, enable sticky zoom + (sp_desktop_widget_size_allocate): Calculate sticky zoom by area instead of MIN (x, y) + + * src/helper/sp-canvas.h: Added floating point scroll coordinates + + * src/helper/sp-canvas.c (scroll_to): Preserver floating point coordinates + + * src/display/nr-arena-group.c (nr_arena_group_set_child_transform): Do + not force full update if not needed + + * src/display/nr-arena-item.c (nr_arena_item_set_clip): Do not force + full update if not needed + (nr_arena_item_set_mask): Ditto + (nr_arena_item_set_transform): Ditto + +2003-02-09 Lauris Kaplinski + + * src/libnr/nr-gradient.c (nr_lgradient_render_R8G8B8A8N_EMPTY): New shortcut + + * src/libnr/nr-gradient.h: Made x0 and x0 integers - this introduces possible + upt to 0.7 pixel error, but other rendering parts are not exact anyways + + * src/sp-paint-server.h: Fill function signature change + +2003-02-08 Lauris Kaplinski + + * src/libnr/nr-gradient.c (nr_rgradient_render_generic_symmetric): Special + case NR_PIXBLOCK_MODE_R8G8B8A8N and full opacity + + * src/sp-gradient.c (sp_radialgradient_set): Initialize focal point to center if unset + + * src/libnr/nr-gradient.c (nr_lgradient_render_R8G8B8A8N): Special-cased full opacity + + * configure.in: 0.30.1 + + * src/libnrtype/nr-rasterfont.c (nr_rasterfont_ensure_glyph_slot): Use + 32 bit integer bbox initially before deciding whether it fits in 16 bit + +2003-02-08 gettextize + + * Makefile.am (SUBDIRS): Add intl, m4. + (EXTRA_DIST): Add config.rpath. + * configure.in (AC_OUTPUT): Add intl/Makefile, po/Makefile.in, m4/Makefile. + +2003-02-07 Lauris Kaplinski + + * src/help.c (sp_help_about): Make default window size the same as document + + * src/style.c: Use custom winding rule and stroke parameter enumerations + + * src/enums.h: Define winding rules and stroke parameters + +2003-02-06 Lauris Kaplinski + + * src/sp-rect.c (sp_rect_rx_set): Set ::set value(s) + (sp_rect_ry_set): Ditto + + * src/sp-item.c (sp_item_update): Set arena item transform here + + * src/dialogs/fill-style.c (sp_fill_style_widget_update_repr): Made non-recursive + (sp_fill_style_widget_update): Ditto + + * src/sp-shape.c (sp_shape_write_transform): Working path tranformation optimizer + + * src/widgets/sp-color-slider.c (sp_color_slider_adjustment_value_changed): Add + some extra pixels around arrow dirtified area + (sp_color_slider_paint): Use gtk_draw_box instead of gtk_draw_shadow + (sp_color_slider_realize): Attach style + +2003-02-04 Lauris Kaplinski + + * src/sodipodi.c (sodipodi_load_config): Generic method by Bryce + (sodipodi_load_preferences): Frontend, same + (sodipodi_load_extensions): Ditto + (sodipodi_get_repr): Test for "extensions" + (sodipodi_init_config): Generic method by Bryce + (sodipodi_init_preferences): Frontend by Bryce + (sodipodi_init_extensions): Ditto + + * src/toolbox.c (sp_toolbox_extension_create): Implemented by Bryce + + * src/extension.c: New file by Bryce Harrington + + * src/extension.h: New file by Bryce Harrington + + * src/extensions-skeleton.h: Ditto + + * src/sp-mask.c: support maskContentUnits + + * src/nodepath.c (create_curve): Do not add 50 to y (why was it here?) + + * src/sp-item-group.c (sp_group_update): Propagate only if update flag set + + * src/sp-item.c (sp_item_set): Set clippath and mask bbox + (sp_item_update): Ditto + + * src/sp-clippath.c (sp_clippath_build): Implement + (sp_clippath_set): Ditto, clipPathUnits attribute + (sp_clippath_update): Ditto + (sp_clippath_show): Use bbox if needed + (sp_clippath_set_bbox): New method + +2003-02-03 Lauris Kaplinski + + * src/sp-item.c (sp_item_release): Release mask + (sp_item_mask_release): New handler + (sp_item_mask_modified): Ditto + (sp_item_set): Parse mask + (sp_item_show): Show mask + (sp_item_private_hide): Hide mask + + * src/display/nr-arena-item.c (nr_arena_item_invoke_render): Do masking + (nr_arena_item_private_dispose): Release mask + (nr_arena_item_invoke_update): Update mask + (nr_arena_item_set_mask): New method + + * src/sp-root.c (sp_root_build): Do not check for xmlns:sodipodi to determine + version, as this is set automatically in xml loader + + * src/slideshow.h: New file + + * src/slideshow.c: New file + +2003-02-02 Lauris Kaplinski + + * src/sp-rect.c (sp_rect_set): Accept 0.0 as valid for x, y, width and height + (sp_rect_write): Use 0.0 as default for rx, ry + + * src/rect-context.c (sp_rect_finish): Use ::write to be sure + + * src/display/nr-arena-shape.c (nr_arena_shape_clip): OR masks + + * src/sp-defs.c (sp_defs_update): Implement + (sp_defs_modified): Ditto + + * src/sp-clippath.c (sp_clippath_update): Implement + (sp_clippath_modified): Ditto + (sp_clippath_show): Fix + (sp_clippath_hide): Implement + + * src/sp-item.c (sp_item_set): Fix clippath + (sp_item_show): Ditto + (sp_item_private_hide): Ditto + (sp_item_display_key_new): New method + + * src/sp-item.h: Use new signature for ::show and ::hide + +2003-02-01 Daniel Yacob + + * configure.in: Added "am" (Amharic) to ALL_LINGUAS. + +2003-02-01 Lauris Kaplinski + + * src/sp-use.c (sp_use_init): Set width and height default to 100% + (sp_use_set): Ditto + (sp_use_bbox): use child transform + (sp_use_update): Calculate relative lengths, set new viewport + + * src/sp-object.c: Removed ::dispose and some commented out code + + * src/sp-symbol.c: New file + + * src/sp-symbol.h: New file + + * src/enums.h: New file + + * src/xml/repr-io.c (sp_repr_svg_read_node): Return if entity declaration + + * src/sp-root.c (sp_root_init): Set correct default viewport values + (sp_root_build): Read 'x', 'y', 'version', 'preserveAspectRatio' + (sp_root_set): Parse added attributes, accept percentages for x, y, width, height + (sp_root_update): Set up proper transformations to support aspect ratios + + * src/sp-item.h: Added viewPort and item2viewPort transformation to item context + + * src/document.c (sp_document_ensure_up_to_date): Set initial viewport + and identity transforms in item context + (sp_document_idle_handler): Ditto + + * src/attributes.h: Added 'version' and 'preserveAspectRatio' + +2003-01-31 Masatake YAMATO + + * src/main.c (POPT_TABLEEND): Define if it is not defined in + popt.h. copied from forntline. + +2003-01-30 Lauris Kaplinski + + * src/helper/guideline.c (sp_guideline_render): Do not round int + + * src/interface.c (sp_ui_close_view): Get widget pointer before killing object + +2003-01-28 Lauris Kaplinski + + * configure.in: Version 0.30pre + + * src/sp-image.c (sp_image_bbox): Calculate bbox properly + +2003-01-28 gettextize + + * Makefile.am (SUBDIRS): Add intl, m4. + (EXTRA_DIST): Add config.rpath. + * configure.in (AC_OUTPUT): Add intl/Makefile, po/Makefile.in, m4/Makefile. + +2003-01-28 Lauris Kaplinski + + * src/libnrtype/codepages.h: Win9x codepage declarations + + * src/main.c (WinMain): Use new toplevel toolbox constructor + + * src/text-context.c (sp_text_context_root_handler): Added Gdk_U to unimode + + * src/libnrtype/nr-type-w32.c: Implement ANSI charset and styles + + * src/libnrtype/nr-type-directory.c (nr_type_directory_build): Honour + stretch attribute in searches + + * src/toolbox.c (sp_maintoolbox_create_toplevel): Broke constructor + into two parts to allow multiple toolboxes + + * src/interface.c (sp_ui_view_show_toolbox): New method + (sp_ui_view_dock_toolbox): Ditto + (sp_ui_view_remove_toolbox): Ditto + (sp_ui_view_menu): Added menu items for creating toolboxes + (sp_create_window): Pack toplevel hbox into window + +2003-01-26 Lauris Kaplinski + + * src/helper/art-utils.c (sp_vpath_from_bpath_transform_closepath): Moved + array expansion to the right place (thanks to Lynn Kerby) + +2003-01-25 Lauris Kaplinski + + * src/dialogs/xml-tree.c (sp_xml_tree_dialog): Allow horizontal scrollbar + so we do not expand window infinitely + + * src/sp-use.c (sp_use_update): Implemented by MenTaLguY + (sp_use_modified): Ditto + + * src/libnr/nr-path.c (nr_curve_bbox): Implement fast and exact bbox (thanks to Nathan) + (nr_curve_bbox_wind_distance): Use exact bbox + +2003-01-25 Nathan Hurst + + * src/desktop-snap.c: Fixed vector snapping code, replaced horizontal and + vertical snapping with generic vector versions + +2003-01-21 Lauris Kaplinski + + * src/nodepath.c (create_curve): Use NR_MATRIX_DF_TRANSFORM_X (Thanks to + MenTaLguY for finding these NRPointF/ArtPoint mismatches) + +2003-01-20 Lauris Kaplinski + + * src/libnrtype/nr-type-gnome.c (nr_typeface_gnome_new): Ditto + + * src/print.c (sp_print_preview_document): Fix gnome-print support + (sp_print_document): Ditto + + * src/libnrtype/nr-type-xft.c (nr_type_xft_init): Added ebug printout + + * src/widgets/button.c (sp_button_button_press): Do not grab mouse + (sp_button_button_release): Ditto + +2003-01-19 Lauris Kaplinski + + * src/desktop.c (sp_dtw_status_frame_size_request): Always request minimum size + + * configure.in: Define GETTEXT_PACKAGE properly (Thanks to Christian Rose) + + * src/libnrtype/nr-type-xft.c (nr_type_xft_init): Removed CORE, so Xft fontlist + should now be read properly with Debian PPC and or fontconfig systems + +2003-01-15 MenTaLguY + + * src/sp-object.c (sp_object_get_unique_id): don't include namespace prefix when generating ids + +2003-01-15 MenTaLguY + + * src/widgets/sp-xmlview-tree.c (add_node): tree nodes associated with elements pretend they initially have a NULL id + (element_attr_changed): display elements with a NULL id properly + +2003-01-15 MenTaLguY + + * src/xml/repr-private.h: added SPXMLNs structure + + * src/xml/repr.h: added decls for sp_xml_ns_uri_prefix() and sp_xml_ns_prefix_uri() + + * src/xml/repr-io.c: improved handling of namespace prefixes + (sp_repr_qualified_name): added hashtable to keep track of NS prefixes used + (sp_repr_read_node): Ditto + (sp_repr_do_read): Ditto + replaced if cascade with calls to sp_xml_ns_uri_prefix() + (sp_repr_set_xmlns_attr): helper to set xmlns attributes + + * src/xml/repr-util.c: added namespaces list + (sp_xml_ns_register_defaults): procedure to initialize namespace mapping list + (sp_xml_ns_auto_prefix): helper routine to automatically select a "good" prefix for a given namespace URI + (sp_xml_ns_uri_prefix): returns a prefix to use for a given namespace URI, registering a mapping automatically if necessary + (sp_xml_ns_prefix_uri): returns the namespace URI registered for a given prefix + +2003-01-13 MenTaLguY + + * src/desktop.c (sp_dtw_desktop_shutdown): rearranged close confirmation buttons according to the Gnome HIG + +2003-01-18 Lauris Kaplinski + + * src/seltrans.c (sp_sel_trans_grab): Build array of selected item transformations + (sp_sel_trans_transform): Use original transforms to avoid rounding errors + (sp_sel_trans_ungrab): Release array + + * src/dialogs/transformation.c: Implemented scaling percentages + +2003-01-17 Lauris Kaplinski + + * src/draw-context.c (spdc_set_startpoint): Snap startpoint (thanks to Nathan) + (sp_pen_context_root_handler): Ditto + + * src/dialogs/transformation.c: Implement simple move dialog + +2003-01-16 Lauris Kaplinski + + * src/helper/guideline.c (sp_guideline_new): Changed signature, fixes + granular new guideline placement bug + (sp_guideline_render): Use normal rounding, so guideline and object are aligned + + * src/sp-item.h: Changed the signature of ::snappoints, this forced me to + use NRPoints near everywhere else too + +2003-01-15 Lauris Kaplinski + + * src/draw-context.c (spdc_endpoint_snap): Make Ctrl to restrict directions + to multitudes of 15 degrees (thanks to Nathan Hurst) + +2003-01-13 Lauris Kaplinski + + * src/file.c (sp_file_open_dialog): Rearrange + (sp_file_save_dialog): Ditto + (sp_file_save_document): Ditto + +2003-01-13 MenTaLguY + + * src/toolbox.c (sp_maintoolbox_create): turned off user resizing of toolbox so it autoresizes properly + +2003-01-13 MenTaLguY + + * src/toolbox.c (sp_maintoolbox_create): turned off user resizing of toolbox so it autoresizes properly + + + * src/print.c (sp_print_plain_bind): Move generic PS code here + (sp_print_plain_release): Ditto + (sp_print_plain_fill): Ditto + (sp_print_plain_stroke): Ditto + (sp_print_plain_image_R8G8B8A8_N): Ditto + (sp_print_document): Implement very-very simple non-gnome print dialog + +2003-01-12 Lauris Kaplinski + + * src/main.c: Made --without-popt working + +2003-01-11 MenTaLguY + + * src/xml/repr-io.c: removed bogus ATTLIST from DOCTYPE + (sp_repr_read_file): factored out duplicated code into sp_repr_do_read + added parameter for default namespace + (sp_repr_read_mem): factored out duplicated code into sp_repr_do_read + added parameter for default namespace + (sp_repr_do_read): merged duplicated code from sp_repr_read_* family + (sp_repr_do_read): insert xmlns decls for common namespaces + (sp_repr_qualified_name): basic namespace handling for SVG, XLink, and Sodipodi namespaces + (sp_repr_read_node): added parameter for default namespace + (sp_repr_read_node): removed dead code and broken re-addition of xmlns declarations (xlink?) + (repr_quote_write): UTF8 is ASCII-compatible -- removed inaccurate comment + + * src/xml/repr.h: added SP_*_NS_URI macros + + * src/document.c (sp_document_new): SVG is default NS + (sp_document_new_from_mem): SVG is default NS + + * src/file.c (file_import_ok): SVG is default NS + + * src/interface.c (sp_ui_import_one_file): SVG is default NS + + * src/sodipodi.c (sodipodi_init): no default NS + (sodipodi_load_preferences): no default NS + +2003-01-11 Lauris Kaplinski + + * configure.in: Check for xft + + * src/libnrtype/Makefile.am: Added xft_sources + + * src/libnrtype/nr-type-directory.c (nr_type_read_xft_list): Load xft typefaces + + * src/libnrtype/nr-type-xft.h: New file + + * src/libnrtype/nr-type-xft.c: New file + +2003-01-10 MenTaLguY + + * src/dialogs/item-properties.c (sp_item_widget_new): made unimplemented controls insensitive + +2003-01-04 MenTaLguY + + * src/text-context.c (sp_text_context_finalize): folded back + into sp_text_context_finish + (sp_text_context_root_handler): Gtk IM now gets first refusal of + key press _and_ release events; toggling "unicode mode" now triggers an + IM reset; "unicode mode" bypasses IM entirely + + +2003-01-04 Lauris Kaplinski + + * src/text-context.c (sp_text_context_root_handler): Moved IM back to + beginning (thanks to MenTaLguY for pointing this out) + + * src/sp-object.c (sp_object_invoke_update): Merge styles only if parent changed + + * src/sp-text.c (sp_text_update): Implement + + * src/sp-text.c (sp_string_modified): Chain invocation so style gets updated + + * src/widgets/sp-xmlview-content.c: Port to GtkTextView + + * src/dialogs/xml-tree.c: Port to GtkTextView + + * src/text-context.c (sp_text_context_root_handler): Consume xdigits in unicode mode + + * configure.in: Removed GTK_ENABLE_BROKEN + + * src/dialogs/text-edit.c: Use GtkTextView/Buffer + + * src/xml/repr-util.c (sp_repr_transfer_ids): Helper by MenTaLguY + (sp_repr_move): Ditto + +2003-01-03 Lauris Kaplinski + + * src/dialogs/xml-tree.c: Updated (MenTaLguY) + + * src/dialogs/item-properties.c (sp_item_widget_new): Added slider (MenTaLguY) + + * src/text-context.c (sp_text_context_setup): Set up Gtk IM (thanks to MenTaLguY) + (sp_text_context_setup_text): Move code here (MenTaLguY) + (sp_text_context_root_handler): Process Gtk IM (MenTaLguY) + (sptc_commit): Gtk IM signal handler (MenTaLguY) + + * src/sp-text.c (sp_text_insert): Replace < 32 and not whitespace with space + + * src/selection.c (SP_SELECTION_UPDATE_PRIORITY): Set Gtk - 11 + + * src/document.c (SP_DOCUMENT_UPDATE_PRIORITY): Set GTK - 12 + +2003-01-01 Lauris Kaplinski + + * src/widgets/button.c (sp_button_paint_arrow): Draw something + +2002-12-29 Lauris Kaplinski + + * src/event-context.c (sp_event_context_private_root_handler): Pan with + Shift+Button3 too (useful with windows and < 3 button mice) + + * src/toolbox.c (sp_toolbox_file_create): Mek print buttons insensitive + + * src/sp-text.c (sp_text_write_transform): Fixed it + + * src/main.c (sp_do_export_png): Initialize y0 + + * src/file.c (sp_export_png_file): Use pixelstore, export min 64 rows at once, + fix miscalculated rowstride + +2002-12-28 Lauris Kaplinski + + * src/libnrtype/nr-type-directory.c (nr_type_read_w32_list): Use + windows native fonts, if applicable + + * src/libnrtype/nr-type-w32.h: New file + + * src/libnrtype/nr-type-w32.c: New file + +2002-12-27 Lauris Kaplinski + + * src/print.c (sp_print_image_R8G8B8A8_N): Implement direct PS version + +2002-12-26 Lauris Kaplinski + + * src/print.c (sp_print_bpath): Helper + (sp_print_bind): Implement non-gnome-print version + (sp_print_release): Ditto + (sp_print_fill): Ditto + (sp_print_stroke): Implement non-gnome-print version + + * src/widgets/icon.c (sp_icon_image_load): Generic image loader + + * src/desktop.c (sp_desktop_widget_update_zoom): Make working again + + * src/widgets/button.c: New file + + * src/widgets/button.h: New file + + * src/toolbox.c (sp_toolbox_draw_create): Port to brand new SPButton + +2002-12-17 Lauris Kaplinski + + * src/desktop.c (sp_desktop_widget_init): Some cleanup + + * src/widgets/ruler.c: Moved to widgets subdir + + * src/widgets/ruler.h: Moved to widgets subdir + +2002-12-16 Lauris Kaplinski + + * configure.in: --with[out]-gnome-print argument, thanks to MentaLguY + +2002-12-15 Lauris Kaplinski + + * src/sp-guide.c (sp_guide_set): Fixed horiz/vert + + * src/desktop-events.c (sp_dt_ruler_event): Fixed + (sp_dt_guide_event): Fixed + + * src/helper/guideline.h: Renamed to avoid conflict with SPGuide object, + several signature changes + + * src/helper/guideline.c: Ditto, removed properties + + * src/helper/sp-canvas.c (sp_canvas_window_to_world): Oops, was meant to be y0 + (sp_canvas_world_to_window): Ditto + +2002-12-14 Lauris Kaplinski + + * src/dialogs/desktop-properties.c: Fully functional color picker + + * src/display/nr-arena-item.h: Ported rendering from NRBuffer to NRPixBlock, + involves changes in most Arena objects. Added NO_CACHE flag to rendering. + +2002-12-13 Lauris Kaplinski + + * src/widgets/paint-selector.c (sp_paint_selector_style_button_add): Changed + SODIPODI_GLADEDIR -> SODIPODI_PIXAMPDIR (Thanks to Ted Gould) + +2002-12-11 Lauris Kaplinski + + * src/sp-guide.c (sp_guide_class_init): Removed translatability of properties + + * src/knot.c (sp_knot_class_init): Removed translatability of properties + + * src/helper/sp-guide.c (sp_guideline_class_init): Removed translatability + from properties (who needs this?) + + * src/widgets/icon.h: New file, use as frontend to image loading + + * src/widgets/icon.c: New file + + * src/document.c (sp_document_create): Generic method, implement + constructors as frontends + + * src/sodipodi.c (sodipodi_dispose): Only unref documents and let + them manage list + + * glade/icons.svg: New icon definition file + +2002-12-08 Lauris Kaplinski + + * src/dialogs/align.c (sp_align_arrange_clicked): Collected all + arrangement methods into generic one + (create_base_menu): Compact + (sp_align_add_menuitem): New helper + (sp_quick_align_dialog): Use value matrix instead of different callbacks + +2002-12-07 Lauris Kaplinski + + * src/helper/sp-canvas.c (sp_canvas_expose): Free rects + + * src/attributes.h: Added animation-specific attributes + + * src/sp-animation.c: New file, only skeleton at moment + + * src/sp-animation.h: New file + +2002-12-06 Masatake YAMATO + + * tools-version.sh: print the path to the tools. + +2002-12-06 Lauris Kaplinski + + * src/sp-root.c (sp_root_update): Implement + + * src/sp-rect.c (sp_rect_update): Implement + (sp_rect_set): Request update instead of setting shape immediately + + * src/sp-item-group.c (sp_group_update): Implement + + * src/sp-object.h: Replaced ::read_attr with ::set, signature change. + This involves modification in all subclasses as well. + + * src/attributes.h: New file. We enumerate/define all allowed attributes + and properties, to save few string compares later. + + * src/attributes.c: New file + +2002-12-04 Lauris Kaplinski + + * src/sp-object.c (sp_object_request_update): New method. We implement + separate ::update cascade that precedes ::modified, and is meant to + be used for building item states (styles, paths and so on). In many + aspects it shares code path with ::modified. + (sp_object_invoke_update): Ditto + +Wed Dec 4 01:05:05 2002 Mitsuru Oka + + * src/widget/sp-menu-button.c: Fixed to work well. + + * src/toolbox.c: enable draw buttons. + Comment out signal_connect_after. + +2002-12-03 Lauris Kaplinski + + * src/sp-item.h: Replaced libart transforms and bboxes with libnr ones - + this involves changes almost every file there. + + * src/main.c: Added POPT_AUTOHELP + +2002-12-03 Masatake YAMATO + + * tools-version.sh (TOOLS): Added automake-1.6 and + aclocal-1.6. Suggested by MenTaLguY. + (srcdir): remove version number from grep pattern. + +2002-12-02 Lauris Kaplinski + + * src/helper/sp-canvas.h: Made scrolling offsets integers + + * src/helper/sp-canvas.c (scroll_to): Scroll instead of draw + + * tools-version.sh (ENVPATTERN): Added FLAGS + +2002-12-02 Masatake YAMATO + + * distro, tools-version.sh: New files. + distro comes from distro-0.8.1(http://distro.pipfield.ca/). + distro and tools-version.sh should be included only in CVS version + of sodipodi. + + * autogen.sh: Call tools-version.sh. + +2002-12-02 Lauris Kaplinski + + * src/dialogs/desktop-properties.c: Partial color picker implementation + +2002-12-01 Lauris Kaplinski + + * src/dialogs/text-edit.c: GtkObject/GObject cleanup + + * src/file.c: Ditto + + * TODO: Update with 0.29 tasks + + * src/sp-gradient.c: GtkObject/GObject cleanup + + * src/widgets/sp-widget.c: Ditto + + * src/widgets/gradient-selector.c: Ditto + + * src/widgets/gradient-vector.c: Ditto + + * src/widgets/gradient-position.c: Ditto + + * src/widgets/gradient-image.c: Ditto + + * src/dialogs/fill-style.c: Ditto + +2002-11-30 Lauris Kaplinski + + * src/view.h: Derive directly from GObject + +2002-11-30 Masatake YAMATO + + * configure.in (ENABLE_AUTOTRACE): Comment out autotrace/frontline + checking till frontline becomes gtk+2 based. + +2002-11-30 Lauris Kaplinski + + * src/selection.h: Inherit directly from GObject + + * src/event-context.h: Inherit directly from GObject + + * src/helper/sp-canvas.c (sp_canvas_item_dispose): Set xform to NULL + + * src/display/canvas-arena.c (sp_canvas_arena_destroy): Fixed typo, so + multiple destroys are allowed + + * src/nodepath.c: Removed external cursor pointers + + * src/knot.c (sp_knot_set_property): Ref new cursors + + * src/document.c (sp_document_get_type): Inherit directly from GObject + +2002-11-29 Lauris Kaplinski + + * src/knot.c (sp_knot_handler): Signature change, return correct value as it should + + * src/helper/sp-canvas.c (scroll_to): Blit window, unless explicitly forbidden + (sp_canvas_size_allocate): Update onlu changed areas + + * src/sp-item.c (sp_item_invoke_bbox): Signature change + + * src/desktop.c (sp_desktop_widget_update_rulers): Reenabled it + (sp_desktop_set_display_area): Only update canvas root if zoom factor changes + (sp_desktop_update_scrollbars): Working + + * src/helper/sp-canvas.c (paint): use full visible are for clipping, fixed + type on specifying area dimensionf in event + (sp_canvas_get_viewbox): New method + + * src/desktop.c (sp_desktop_set_display_area): New method, replaces show_region + (sp_desktop_get_display_area): Replacement for ... + (sp_desktop_zoom_absolute): Use generic sp_desktop_set_visible_area + (sp_desktop_zoom_relative): Ditto + +2002-11-28 Lauris Kaplinski + + * configure.in: ... and everyting else - merged SODIPODI_GTK2_BRANCH + + * po/Makevars: Added this + +2002-11-28 gettextize + + * Makefile.am (SUBDIRS): Add intl, m4. + (EXTRA_DIST): Add config.rpath. + * configure.in (AC_OUTPUT): Add intl/Makefile, po/Makefile.in, m4/Makefile. + +2002-11-27 gettextize + + * Makefile.am (SUBDIRS): New variable. + (ACLOCAL_AMFLAGS): New variable. + (EXTRA_DIST): New variable. + * configure.in (AC_OUTPUT): Add intl/Makefile, po/Makefile.in, m4/Makefile. + +2002-11-25 Lauris Kaplinski + + * configure.in: Version 0.29pre + +2002-11-25 Lauris Kaplinski + + * src/display/nr-arena-glyphs.c (nr_arena_glyphs_group_add_component): Skip + if zero-sized valid path + + * src/libnr/nr-path.c (nr_path_matrix_f_bbox_f_union): Allow NULL path member + (nr_path_matrix_f_point_f_bbox_wind_distance): Ditto + (nr_path_duplicate_transform): Ditto + + * src/libnrtype/nr-typeface.h: Added family member to definition + + * src/libnrtype/nr-type-directory.c (nr_type_register): Use family from def + + * src/libnrtype/nr-type-ft2.c (nr_type_ft2_build_def): Set family member + + * src/libnrtype/nr-type-gnome.c (nr_type_gnome_build_def): Set family member + +2002-11-23 Lauris Kaplinski + + * src/dyna-draw-context.c: Clamp drag to [0.0 1.0] + +2002-11-23 Masatake YAMATO + + * src/node-context.c: Inlucde document.h. + (sp_node_context_stamp): New function. + (sp_node_context_root_handler): Do stamp if space key + is pressed during dragging. + + * src/nodepath.c (stamp_repr): New function. + (node_event): Do stamp if the space key is pressed. + (node_ctrl_event): New function. + (sp_nodepath_node_new): Connected node_ctrl_event to n->p.knot::event. + Connected node_ctrl_event to n->n.knot::event. + + * src/helper/bezier-utils.c (sp_bezier_fit_cubic_full): Fix memry leaks(u, uPrime). + This leaks are reported by Michel Schinz . + +2002-11-22 Lauris Kaplinski + + * src/libnrtype/nr-type-gnome.c (nr_typeface_gnome_lookup): Added all + glyphs to 0xe000 private plane as well. + + * src/widgets/gradient-selector.c (sp_gradient_selector_set_spread): Set + position widget spread as well + (sp_gradient_selector_spread_activate): Ditto + +2002-11-21 Lauris Kaplinski + + * src/helper/curve.c (sp_curve_closepath): Reinitialize pointers, as we may + have reallocated path in helper + + * src/knotholder.h: Added hook for knot ungrabbing + + * src/knotholder.c (knot_ungrabbed_handler): Implement + (sp_knot_holder_destroy): Free list items + + * src/sp-ellipse.c (sp_arc_start_set): Use genericellipse closed marker + (sp_arc_end_set): Ditto + (sp_arc_set_elliptical_path_attribute): Ditto + + * autogen.sh: Added '--intl' to gettextize flags, seems to be safe for + older gettexts as well + + * src/dialogs/xml-tree.c (on_tree_select_row): Remove extra blockade + counting (thanks to MenTaLguY) + (on_tree_unselect_row): Ditto + +2002-11-20 Masatake YAMATO + + * src/seltrans.c (sp_sel_trans_init): Set null to + stamp_cache. + (sp_sel_trans_ungrab): Clear stamp_cache. + (sp_sel_trans_stamp): If available, use stamp_cache. + Else build stamp_cache. l0 is removed. Don't + free the list here. + + * src/seltrans.h: Included glib.h. + (struct _SPSelTrans): added new field stamp_cache. + +2002-11-20 Lauris Kaplinski + + * src/interface.c (sp_ui_dialog_menu): Do not bring up > 1 transform dialogs at once + + * src/seltrans.c (sp_sel_trans_stamp): Reversing still was not correct, + replaced it with explicit sort + +2002-11-20 Masatake YAMATO + + * src/seltrans.c (sp_sel_trans_stamp): The order of + selections is reversed before stamping. + + The bug was reported by Michel Schinz . + +2002-11-19 Lauris Kaplinski + + * src/desktop.c (sp_desktop_prepare_shutdown): New method, allowing us nice + cleanup before ::destroy is invoked + (sp_dtw_desktop_shutdown): Prepare desktop for shutdown + + * src/sp-text.c (sp_text_is_empty): Treat unicode private plane as graphical + + * src/libnrtype/nr-type-ft2.c (nr_typeface_ft2_lookup): Use private plane + direct index, if no unimap + (nr_typeface_ft2_new): Set unimap flag according to whether we have + unicode mapping table or not + +2002-11-18 Lauris Kaplinski + + * configure.in (FREETYPE_LIBS): Added direct freetype check + + * src/widgets/dash-selector.c (sp_dash_selector_menu_item_new): Use created + GC, as widget is not mapped yet + (sp_dash_selector_new): Load stroke definitions from preferences + +2002-11-17 Lauris Kaplinski + + * src/helper/sodipodi-ctrl.c (sp_ctrl_build_cache): Cleaned up bitmap build + +2002-11-17 Masatake YAMATO + + * src/dialogs/xml-tree.c (sp_xml_tree_dialog): Added small + space between attribute name text field and set attribute + button. + +2002-11-17 Lauris Kaplinski + + * src/dialogs/xml-tree.c (sp_xml_tree_dialog): Cleanup by MenTaLguY + + * src/widgets/sp-xmlview-attr-list.c (event_attr_changed): Clamping string + width to 64[+3], thanks to MenTaLguY + +2002-11-16 Lauris Kaplinski + + * src/helper/sp-canvas.c (sp_canvas_motion): Get pointer if motion hints are requested + + * src/select-context.c (sp_select_context_item_handler): Use motion hints + + * src/dialogs/text-edit.c (sp_text_edit_dialog_read_selection): Kill annoying + warning about position > length + + * src/style.h (SP_SCALE24_FROM_FLOAT): Use temporary (double) cast + (SP_SCALE24_TO_FLOAT): Ditto + + * src/dialogs/xml-tree.c (cmd_set_attr): Use gal unicode wrappers + + * src/widgets/sp-xmlview-attr-list.c (event_attr_changed): Use gal unicode wrappers + + * src/widgets/sp-xmlview-content.c (event_content_changed): Use gal unicode wrappers + (sp_xmlview_content_changed): Ditto + + * src/widgets/sp-xmlview-tree.c (element_attr_changed): Use gal unicode wrapper + (text_content_changed): Ditto + + * src/dialogs/xml-tree.c: Sorted out includes a bit + (set_tree_desktop): Comment aout transient, as some WMs do not do it proper + (on_desktop_selection_changed): Set/release block + (on_tree_unselect_row): Ditto + (on_tree_select_row): Ditto + (get_dt_select): Use selection helper methods + +2002-11-15 Lauris Kaplinski + + * src/libnrtype/nr-type-gnome.c (nr_typeface_gnome_glyph_outline_get): Use + metrics properly + + * src/libnrtype/nr-type-ft2.c (nr_typeface_ft2_ensure_slot_v): Implement for + font missing vertical metrics + (nr_typeface_ft2_ensure_outline): Ditto + + * src/libnrtype/nr-type-directory.c (nr_type_read_private_list): Read face + number from proper place + + * src/libnrtype/nr-font.c (nr_font_generic_glyph_area_get): Implement + + * src/sp-text.c (sp_string_calculate_dimensions): Use metrics properly + (sp_string_set_shape): Ditto + + * src/print.c (sp_print_stroke): Print dash + +2002-11-14 Lauris Kaplinski + + * src/file.c (sp_file_exit): Close all views before exiting + + * src/interface.c (sp_ui_close_view): Destroy viewwidget properly + (sp_ui_close_all): New method + + * src/sp-rect.c (sp_rect_write_transform): Adjust dash in addition to stroke width + + * src/display/nr-arena-shape.c (nr_arena_shape_update): Only dash if + total dash length is >= 1.0 pixels + + * src/dialogs/stroke-style.c (sp_stroke_style_line_update_repr): Divide + dash values by line width + (sp_stroke_style_scale_line): Multiply dash values by line width + (sp_stroke_style_line_update): Ditto + + * src/widgets/dash-selector.c (sp_dash_selector_set_dash): Use 1/1000 of + total dash distance as delta + + * src/sp-gradient.c (sp_gradient_write): Set xlink:href attribute + (sp_stop_write): Do it the right way + +2002-11-13 Lauris Kaplinski + + * src/style.c (sp_style_read_dash): Allow comma separators + (sp_style_read): Read dash presentation attributes + + * src/widgets/dash-selector.c: New file + + * src/widgets/dash-selector.h: New file + + * src/dialogs/stroke-style.c (sp_stroke_style_line_widget_new): Added dash + pattern selector + (sp_stroke_style_line_update): Update dash + (sp_stroke_style_line_update_repr): Ditto + (sp_stroke_style_line_dash_changed): Callback + +2002-11-12 Lauris Kaplinski + + * src/dialogs/xml-tree.c: Naviagtion buttons, better layout and other + improvements by MenTaLguY + +2002-11-12 Masatake YAMATO + + * configure.in: required frontline-0.5.4. + You can get both autotrace and frontline from + http://sourceforge.net/autotrace. + (AC_PROG_AS): wrapped by ifdef. + Missing to add ChangeLog before commiting. + +2002-11-11 Lauris Kaplinski + + * src/libnr/nr-gradient.c (nr_rgradient_render_generic_symmetric): Fix + array read overflow + (nr_rgradient_render_generic_optimized): Ditto + + * src/widgets/paint-selector.c (sp_paint_selector_write_lineargradient): Normalize + gradient transform and recalculate positions before applying + (sp_paint_selector_write_radialgradient): Ditto + + * src/widgets/gradient-selector.c (sp_gradient_selector_set_mode): New method + (sp_gradient_selector_init): Added units and spread optionmenu + + * src/widgets/gradient-position.c (sp_gradient_position_motion_notify): Comment + out nonuniform placement, as it did not work correctly + + * src/libnr/nr-matrix.c (nr_matrix_d_invert): Fix really silly bug generating identities + (nr_matrix_f_invert): Ditto + + * src/dialogs/stroke-style.c (sp_stroke_style_paint_update): Set gradient props + + * src/dialogs/fill-style.c (sp_fill_style_widget_update): Set gradient props + + * src/sp-gradient.h: Changed units enumeration, so 0 is default + + * src/display/nr-arena-shape.c (nr_arena_shape_pick): Re-enable SVP based check, + only do winding check, if object is filled + + * src/file.c: Removed printing code, only frontends remain + + * src/print.c (sp_print_document): Implement + (sp_print_document_to_file): Ditto + + * src/sp-gradient.c (sp_gradient_ensure_colors): Fixed writing last color + outside of allocated color vector + +2002-11-10 Lauris Kaplinski + + * configure.in: Commented out AM_PROG_AS, as there is not such macro + in my installation + + * src/libnrtype/nr-typeface.h: Signature change for outline unref + + * src/libnrtype/nr-type-gnome.c (nr_typeface_gnome_glyph_outline_get): Implemented + vertical metrics outline + (nr_typeface_gnome_glyph_advance_get): Ditto for advance + + * src/libnrtype/nr-type-directory.c: Cleaned up a lot, now we can hopefully + work with multiple font sources + + * src/libnrtype/nr-type-directory.h: Moved namelist to nr-type-primitives + + * src/libnrtype/nr-type-primitives.c: New file + + * src/libnrtype/nr-type-primitives.h: New file + + * src/libnrtype/nr-type-ft2.c: New file + + * src/libnrtype/nr-type-ft2.h: New file + +2002-11-09 Masatake YAMATO + + * configure.in (AM_CONDITIONAL(USING_OAF)): moved to toplevel. + (AM_PROG_AS): used to check gas/as. + + * src/toolbox.c (sp_update_draw_toolbox): tooltips + are added to the buttons. + (gtk_event_box_new_with_image_file_and_tooltips) + (gtk_event_box_force_draw_parent): New functions. + + * src/widgets/sp-menu-button.c (sp_menu_button_draw_arrow): New function. + (sp_menu_button_draw): used sp_menu_button_draw_arrow. + (sp_menu_button_expose): ditto. + +2002-11-06 Masatake YAMATO + + * src/helper/curve.c (sp_curve_new_from_bpath): Initialize substart + field. + (sp_curve_reverse): assert if bs->code is ART_MOVETO_OPEN + or ART_MOVETO. + + Added functions that converts multiple items to curves. + * src/path-chemistry.c (sp_selected_item_to_curved_repr): + Use sp_selected_item_to_curved_repr0. + (sp_selected_path_to_curves0): New function. + (sp_selected_path_to_curves): New function. + (SP_TOCURVE_*): Placeholders. + +2002-11-05 Lauris Kaplinski + + * src/dialogs/export.c: Made glade-free dialog + + * src/file.c (sp_export_png_file): Make filename const + + * configure.in (CFLAGS): Added GCC warnings + +2002-11-03 Lauris Kaplinski + + * src/dialogs/node-edit.c: Removed unused glade stuff + +2002-11-04 Masatake YAMATO + + * src/dialogs/xml-tree.c (sp_xml_tree_dialog): Added vpaned + between sp_xmlview_attr_list_new and text fields. + +2002-11-03 Lauris Kaplinski + + * Makefile.am (SUBDIRS): Removed macros + + * autogen.sh: Made self-contained + + * configure.in: Removed macros + + * src/widgets/sp-xmlview-tree.c: new file by MenTaLguY + + * src/widgets/sp-xmlview-content.c: new file by MenTaLguY + + * src/widgets/sp-xmlview-attr-list.c: new file by MenTaLguY + + * src/libnrtype/nr-type-directory.c: Parsing works for normal fonts + +2002-11-02 Masatake YAMATO + + * README: removed GYVE. + + * doc/keybindings.txt: added a item for stamping. + + * doc/architecture.txt: Fix a typo in a document. + / is forgotten in a sample svg. + + * src/rect-context.c (sp_rect_context_config_widget): Fix a typo in a + label. + +2002-11-01 Lauris Kaplinski + + * src/desktop.h: s/GtkEventBoxClass/SPViewClass/; thanks to MenTaLguY + + * configure.in (have_gnome_print): Gnome-print support can be disabled + + * src/libnrtype/Makefile.am (INCLUDES): SODIPODI_GNOME_PRINT_CFLAGS + + * src/Makefile.am (sodipodi_LDADD): Added SODIPODI_GNOME_PRINT_LIBS + (INCLUDES): Same for CFLAGS + +2002-10-31 Lauris Kaplinski + + * src/widgets/font-selector.c (struct _SPFontSelector): Use NRNameListss + (sp_font_selector_init): Setup family namelist + (sp_font_selector_family_select_row): Setup style namelist + (sp_font_selector_set_font): Use namelist + + * src/libnrtype/nr-type-directory.c (nr_type_directory_lookup): New method + (nr_type_directory_style_list_get): Return list of full names + + * src/libnrtype/nr-typeface.h: Added full name, removed generic style query + +2002-10-31 Masatake YAMATO + + * src/sp-image.c (autotrace_dialog): invokeed frontline_init + if it is defined. in-cvs version of frontline defines + frontline_init. + +2002-10-27 Lauris Kaplinski + + * src/helper/curve.c (sp_bpath_clean): Fixed warning (thanks to MenTaLguY) + +2002-10-26 Lauris Kaplinski + + * src/dialogs/text-edit.c (sp_text_edit_dialog_update_object): Make + style srings lowercase before applying + + * src/dialogs/desktop-properties.c (sp_desktop_dialog_new): Added + togglebutton for showing/hiding page border + + * src/desktop.c (sp_dt_namedview_modified): Show/hide page border + + * src/sp-namedview.c (sp_namedview_read_attr): Listen to "showborder" + +2002-10-25 Lauris Kaplinski + + * src/dialogs/item-properties.c: Removed libglade dependency + +2002-10-23 Lauris Kaplinski + + * configure.in: Added check for popt.h + + * src/dialogs/align.c: Removed libglade dependency + + * src/toolbox.c: Removed libglade dependency + +2002-10-22 Lauris Kaplinski + + * src/toolbox.c (sp_toolbox_button_new): Helper + (sp_toolbox_toggle_button_new): Ditto + (sp_toolbox_file_create): Degladeified method + + * src/file.c (sp_file_export_dialog): Frontend + + * src/toolbox.c (sp_toolbox_toggle_button_new): Helper + (sp_toolbox_draw_create): Use previous + + * src/main.c: #include + +Mon Oct 21 13:31:41 2002 Mitsuru Oka + + * configure.in: Fixed dependency bug. + Removed --with/without-gnome-xml2 config option. + +2002-10-21 Lauris Kaplinski + + * src/widgets/sp-toolbox.c: Removed whole gtk.h inclusion + + * src/toolbox.c: Added missing headers + + * src/print.c (sp_print_image_R8G8B8A8_N): Implement + (sp_print_preview): Remove root transform + (sp_print_fill): Do not apply ctm twice + +Mon Oct 21 02:11:08 2002 Mitsuru Oka + + * autogen.sh: Fixed package version in echo message. + + * configure.in: Rewrite using PKG_CHECK_MODULES. + It reduced verbose package checks. + + * src/main.c: Removed unused GNOME headers. + + * src/sp-ellipse.c: Ditto. + + * src/sp-image.c: Ditto. + + * src/toolbox.c: Ditto. + + * src/dialogs/align.c: Ditto. + + * src/dialogs/desktop-properties.c: Ditto. + + * src/dialogs/display-settings.c: Ditto. + + * src/dialogs/document-properties.c: Ditto. + + * src/dialogs/object-attributes.c: Ditto. + + * src/dialogs/object-properties.c: Ditto. + + * src/dialogs/stroke-style.c: Ditto. + + * src/dialogs/text-edit.c: Ditto. + + * src/dialogs/tool-attributes.c: Ditto. + + * src/dialogs/tool-options.c: Ditto. + + * src/helper/units.c: Ditto. + + * src/widgets/font-selector.c: Ditto. + + * src/widgets/gradient-selector.c: Ditto. + + * src/widgets/paint-selector.c: Ditto. + + * src/widgets/sp-color-selector.c: Ditto. + + * src/selection.c: Renamed release handler. + + * src/sp-gradient.c: Fixed non existence destroy signal bug. + + * src/sp-item.c: Ditto. + + * src/style.c: Ditto. + + * src/widgets/gradient-image.c: Ditto. + + * src/widgets/gradient-vector.c: Ditto. + + * src/sp-object.c: Cleanup. + +Sun Oct 20 12:22:03 2002 Mitsuru Oka + + * autogen.sh: Specify automake version to 1.6.1. + + * configure.in: Cleanup. + + * src/desktop-events.c: Cleanup and removed unused gnome header. + + * src/desktop.c: Ditto. + + * src/draw-context.c: Ditto. + + * src/dyna-draw-context.c: Ditto. + + * src/event-context.c: Ditto. + + * src/rect-context.c: Ditto. + + * src/spiral-context.c: Ditto. + + * src/star-context.c: Ditto. + + * src/file.c: Ditto. + + * src/help.c: Ditto. + + * src/main.c: Ditto. + + * src/sp-anchor.c: Ditto. + + * src/sp-item-group.c: Ditto. + + * src/sp-item.c: Ditto. + + * src/sp-rect.c: Ditto. + + * src/sp-shape.c: Ditto. + + * src/sp-spiral.c: Ditto. + + * src/sp-star.c: Ditto. + + * src/interface.c: Ditto. + We lost icon for sp_about function. + + * src/sp-image.c: Cleanup and removed unused gnome header. + Replaced by GtkDialog. + + * src/document.c: Ditto. + + * src/sodipodi.c: Ditto. + + * src/sp-namedview.c: Fixed bug that SPGuide was unrefed by + gtk_object_unref. + + * src/sp-object.c: Fixed up release/disopse/finalize policy. + We now got works again. + (sp_object_class_init): Fixed object signal handler connection bug + at release signal creation. + + * src/sp-pattern.c: Moved to g_object_unref. + + * src/sp-root.c (sp_root_release): Check if namedviews is NULL. + + * src/sp-text.c: Moved to g_object_unref. + Removed unused gnome dependency. + + * src/svg-view.c: Moved to g_object_unref and + g_object_get/set_data. + + * src/toolbox.c: Reverted from SPWrap to GtkTable. + It's not a time to use SPWrap. + + * src/dialogs/export.c: Moved arena object to GObject functions. + + * src/dialogs/item-properties.c: Moved to g_object_unref. + + * src/dialogs/xml-tree.c: Cleanup. + + * src/display/nr-arena-glyphs.c: Moved from finalize to dispose. + + * src/display/nr-arena-group.c: Ditto. + + * src/display/nr-arena-image.c: Ditto. + + * src/display/nr-arena-item.c: Ditto. + + * src/display/nr-arena-shape.c: Ditto. + + * src/display/nr-arena.c: Ditto. + + * src/xml/sp-color-selector.c (sp_color_selector_init): Added + GINT_TO_POINTER cast. + +2002-10-20 Lauris Kaplinski + + * src/libnr/nr-compose-transform.c (nr_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_TRANSFORM): + Use mmx subcomposers if needed + + * src/libnr/nr_mmx_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_TRANSFORM.S: New file + +2002-10-19 Lauris Kaplinski + + * src/libnr/nr-compose-transform.c (nr_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_TRANSFORM_0): + Split composer + (nr_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_TRANSFORM_n): Ditto + +2002-10-18 Lauris Kaplinski + + * src/libnr/nr_mmx_R8G8B8A8_P_EMPTY_A8_RGBAP.S: new file + + * src/libnr/nr-path.c (nr_path_matrix_f_bbox_f_union): Moved bpath + bbox calculation here + (nr_curve_bbox): Rearrange comparisons + +Thu Oct 17 15:25:43 2002 Mitsuru Oka + + * Removed macros directory. + + * Makefile.am, autogen.sh, configure.in: Corresponding changes. + +2002-10-17 Lauris Kaplinski + + * src/helper/sp-canvas.c: Use idle priority lower than Gtk redraw + + * src/display/nr-arena-shape.c (nr_arena_shape_pick): Use libnr + distance7wind calculation, if item is not at render state + (nr_arena_shape_update): Only update bbox, if render state is not + needed. This gave us approximately 10x faster dragging of comlex shapes + + * src/libnr/nr-path.c (nr_line_wind_distance): New helper method + (nr_curve_bbox_wind_distance): Ditto + (nr_path_matrix_f_point_f_bbox_wind_distance): Fast method to find + bbox and/or wind and/or distance to bezier path + +2002-10-16 Lauris Kaplinski + + * src/print.h: New file, frontend to printing + + * src/print.c: New file, frontend to printing + +2002-10-15 Davide Puricelli + + * debian/*: Updated + +2002-10-15 Lauris Kaplinski + + * src/sp-item.c (sp_item_invoke_print): Rename, signature change + + * src/sp-item.h: SPItem::print signature change + + * src/forward.h: Added SPPrintContext + + * src/libnr/testnr.c (main): Fill mask with blocks of transparent, opaque + and random data. This should be closer to reality and (surprise!) gives better + performance numbers too! + + * src/libnrtype/nr-typeface.c: Moved everyting to virtual method vector + +Sun Oct 13 20:54:15 2002 Mitsuru Oka + + * autogen.sh: Come from GNOME2. + +Sun Oct 13 20:27:04 2002 Mitsuru Oka + + * src/desktop-events.c, src/desktop.c, + src/dialogs/object-properties.c: + Moved gnome_pixmap_new_from_file to gtk_image_new_from_file. + + * src/draw-context.c: Replaced finalize with destory. + + * src/sp-polygon.c: Fixed property bug which did not work + correctly. + + * src/widgets/sp-wrap-box.c, src/widgets/sp-wrap-box.h, + src/widgets/sp-hwrap-box.c, src/widgets/sp-hwrap-box.h, + src/widgets/sp-vwrap-box.c, src/widgets/sp-vwrap-box.h: New files. + + * src/widgets/test-wrapbox.c: New file. + + * src/widgets/Makefile.am: Added wrapbox stuffs. + + * src/widgets/.cvsignore: Added test-wrapbox. + + * src/widgets/sp-toolbox.c: Used g_signal_new instead of + gtk_signal_new, because we need accumulater to control signal + handler flow, and previous codes are not perfect. + +Sun Oct 13 04:18:41 2002 Mitsuru Oka + + * src/sodipodi.c, sodipodi.h: sodipodi_get_elapsed_time() + was useless, so removed. + + * src/knot.c: Replaced finalize with dispose. + use GDK_CURRENT_TIME instead of sodipodi_get_elapsed_time(). + + * src/select-context.c: Use GDK_CURRENT_TIME instead of + sodipodi_get_elapsed_time(). + + * src/style.c: Replaced destroy with release. + + * src/text-context.c: Replaced finalize with destory, + because it's not a direct subclass of GObject. + Replaced noisy gtk_signal_disconnect_by_data with + g_signal_handlers_disconnect_matched. + + * src/toolbox.c: Use normal gtk_menu_item_set_submenu instead of + original gtk_menu_popup callback. + + * src/sp-object.c: Fixed illegal signal emission. + + * src/selection.c: + + * src/dialogs/fill-style.c: Added required headler files. + + * src/dialogs/item-properties.c: Depressed warning. + + * src/display/canvas-arena.c: Use GDK_CURRENT_TIME instead of + sodipodi_get_elapsed_time(). + + * src/helper/sp-guide.c: Cleanup. + + * src/widgets/sp-menu-button.c: Use GDK_CURRENT_TIME instead of + sodipodi_get_elapsed_time(). + Changed popup style. + +2002-10-13 Lauris Kaplinski + + * src/helper/sp-canvas.c (uta_clear): Experimental method + (paint): Return, if events pending (commented out) + (do_update): Return value + (idle_handler): Use update return value + + * src/libnr/testnr.c: Speed test + + * src/libnr/nr_mmx_R8G8B8_R8G8B8_R8G8B8A8_P.S: New file + + * src/helper/sp-canvas-util.c (sp_canvas_clear_buffer): Be quick + + * src/helper/sp-canvas.h: Moved update flags back here + + * src/display/canvas-arena.c (sp_canvas_arena_update): Sort updates according to affine (again) + + * src/libnr/have_mmx.S: New file (copied from gdk-pixbuf) + + * configure.in (use_mmx_asm): Check for mmx + + * src/libnr/nr-compose.c (nr_R8G8B8A8_P_R8G8B8A8_P_A8_RGBA32): Use mmx if present + + * src/libnr/nr_mmx_R8G8B8A8_P_R8G8B8A8_P_A8_RGBAP.S: Assembler code + +2002-10-11 Lauris Kaplinski + + * src/helper/sp-canvas.h: Changed object type to SPCanvas, cleanup + + * src/helper/sp-canvas.c: Ditto + +2002-10-10 Lauris Kaplinski + + * src/helper/sp-canvas.c: Local version of praised GnomeCanvas + + * src/helper/sp-canvas.h: Local version of praised GnomeCanvas + + * src/libnr/nr-gradient.c (nr_rgradient_render_generic_symmetric): Optimize + +2002-10-09 Lauris Kaplinski + + * src/libnr/nr-blit.c (nr_blit_pixblock_mask_rgba32): New method + + * src/libnr/nr-gradient.c (nr_rgradient_renderer_setup): Do r == 0 correctly + (nr_rgradient_render_generic_optimized): Optimize + (nr_rgradient_render_block_end): New method + + * configure.in: Version 0.28pre + +2002-10-09 Lauris Kaplinski + + * configure.in: Version 0.27 + + * src/text-context.c (sp_text_context_root_handler): Only turn off unimode, + if there really is string associated with key + +2002-10-09 Masatake YAMATO + + * src/sp-image.c (load_splines): changed the order + of arguments. this change is for frontline-0.5.3. + + * configure.in: required frontline-0.5.3. + To build sodipodi with frontline you have to get: + http://autotrace.sourceforge.net/snapshots/autotrace-0.30.8.tar.gz + http://autotrace.sourceforge.net/frontline/frontline-0.5.3.tar.gz + +2002-10-08 Lauris Kaplinski + + * src/widgets/gradient-position.c (sp_gradient_position_motion_notify): Do + not mess with lineargradient skew + + * src/sp-ellipse.c (sp_arc_modified): Continue upstream + +Mon Oct 7 01:41:23 2002 Mitsuru Oka + + * Merged from HEAD branch. + +2002-10-07 Lauris Kaplinski + + * src/sp-text.c: Moved frontends here + + * src/dialogs/node-edit.h: Moved declarations here + + * src/desktop.c (sp_desktop_widget_view_position_set): Use grid placement + (sp_desktop_widget_namedview_modified): Read grid placement + (sp_desktop_widget_update_rulers): Use grid placement + (sp_desktop_set_coordinate_status): Disable, until sorted out + + * src/widgets/font-selector.c (sp_font_selector_set_font): Implement + + * src/libnrtype/nr-rasterfont.c (nr_rasterfont_ensure_glyph_slot): Oops, alloc + and clear the right number of blocks + + * src/libnr/nr-compose.c (nr_R8G8B8_R8G8B8_A8_RGBA32): Implement + (nr_R8G8B8_EMPTY_A8_RGBA32): Implement + + * src/libnr/nr-blit.c (nr_blit_pixblock_mask_rgba32): Implement + + * src/widgets/font-selector.c (sp_font_preview_expose): Implement + (sp_font_preview_set_font): Ditto + + * src/libnr/nr-pixblock-pattern.h: New file + + * src/libnr/nr-pixblock-pattern.c: New file + +2002-10-06 Lauris Kaplinski + + * src/toolbox.c (sp_toolbox_draw_create): Do not expand/fill use correct name for text + + * sodipodi.spec.in: Update to cleaner version by Dag Vieers + + * src/sp-text.c (sp_text_is_empty): New method + (sp_string_release): Use ::release, not ::destroy + (sp_tspan_release): Ditto + (sp_text_release): Ditto + + * src/text-context.c (sp_text_context_selection_changed): Forget text + (sp_text_context_forget_text): New method, remove empty text item + + * src/sp-text.c (sp_tspan_build): Ensure there is always text child + + * src/sp-item-group.c (sp_group_bbox): Do not set bbox to 0,0,0,0 + + * src/select-context.c (sp_select_context_root_handler): Set grabbed to NULL on release + + * src/path-chemistry.c (sp_selected_path_combine): Use item2root transform + (sp_selected_path_break_apart): Ditto + + * src/sp-item.c (sp_item_i2root_affine): New method + + * src/widgets/gradient-position.c (sp_gradient_position_motion_notify): Reset + gradient relative transform to symmetric rectilinear if dragging + + * src/style.c (sp_style_merge_ipaint): Use "release" signal + (sp_style_read_ipaint): Ditto + + * src/sp-pattern.c (sp_pattern_read_attr): Use "release" signal + + * src/sp-item.c (sp_item_read_attr): Use "release" signal + + * src/sp-image.c (autotrace_dialog): Connect "release" instead of "destroy" + + * src/sp-gradient.c (sp_gradient_href_release): Use "release" instead of "destroy" + +2002-10-06 suzuki toshiya + + * src/libnr/Makefile.am (libnr_a_SOURCES): added + nr-gradient.h. (nr-gradient.c appeared twice.) + +2002-10-04 Masatake YAMATO + + * src/widgets/font-selector.c: Inlucded stdlib.h for atof. + +2002-10-05 Lauris Kaplinski + + * src/libnr/nr-gradient.c (nr_rgradient_renderer_setup): Use different base renderers + (nr_rgradient_render_block_symmetric): Split frontend + (nr_rgradient_render_block_optimized): Ditto + (nr_rgradient_render_generic_optimized): Asymmetric renderer + + * src/sp-object.c (sp_object_invoke_release): new frontend + (sp_object_detach): release object + (sp_object_detach_unref): Ditto + + * src/sp-object.h: Added ::release virtual method + + * src/sp-object.c (sp_object_invoke_shutdown): New method + +2002-10-04 Lauris Kaplinski + + * src/sp-item-group.c (sp_item_group_ungroup): Rewrite it, so it moves + all non-items to main node, preserving logical order and building + objects in correct sequence + + * src/desktop-affine.c: Methods for root coordinate system, fixes misplacement bug + + * src/libnrtype/nr-rasterfont.c: Made working + + * src/libnrtype/nr-font.c (nr_font_new_default): Do linking + (nr_font_unref): Ditto + + * src/libnrtype/nr-type-directory.c (nr_typeface_unref): Moved here, implemented list + + * src/display/nr-arena-glyphs.c (nr_arena_glyphs_update): Port to rfont + (nr_arena_glyphs_pick): Ditto (placeholder) + (nr_arena_glyphs_set_path): Ditto + (nr_arena_glyphs_fill_mask): Ditto + + * src/libnr/nr-matrix.h (NR_MATRIX_DF_EXPANSION): New macro + (NR_MATRIX_DF_EXPANSION2): Ditto + +2002-10-03 Lauris Kaplinski + + * src/sp-text.c (sp_text_set_shape): Make document insensitive temporarily + + * src/text-context.c (sp_text_context_root_handler): Allow entering + unicode mode by Ctrl-u + +2002-10-02 Lauris Kaplinski + + * src/sp-chars.c (sp_chars_add_element): Signature change + (sp_chars_show): Ditto + + * src/display/nr-arena-glyphs.c (nr_arena_glyphs_group_add_component): Signature change + + * src/libnrtype/nr-rasterfont.c (nr_rasterfont_new): Set it up + (nr_rasterfont_unref): Release glyph slots + (nr_rasterfont_render_glyph_mask): Implement + (nr_rasterfont_ensure_glyph_slot): New helper + + * src/sp-text.c: Port to new chars signature + + * src/sp-chars.h: Use font instead of typeface + + * src/libnr/nr-gradient.c (nr_lgradient_render_block): Signature change + (nr_lgradient_renderer_setup): Use generic base class + (nr_rgradient_renderer_setup): Ditto + (nr_rgradient_render_block): Signature change + + * src/libnr/nr-render.h: New file + +2002-10-01 Lauris Kaplinski + + * src/dialogs/text-edit.c (sp_text_edit_dialog_update_object): Use libnrtype + (sp_text_edit_dialog_read_selection): Ditto + (sp_text_edit_dialog_font_changed): Ditto + + * src/libnrtype/nr-type-directory.h: Implement NRNameList + + * src/libnrtype/nr-type-directory.c (nr_type_directory_lookup_fuzzy): Force lowercase + (nr_type_directory_family_list_destructor): Implement + (nr_type_directory_family_list_get): Ditto + (nr_type_directory_style_list_destructor): Ditto + (nr_type_directory_style_list_get): Ditto + + * src/widgets/font-selector.c: New file + + * src/widgets/font-selector.h: New file + + * src/libnrtype/nr-rasterfont.c: New file + + * src/libnrtype/nr-rasterfont.h: New file + + * src/libnr/nr-matrix.c (nr_matrix_f_set_scale): Correct signature + + * src/sp-text.c (sp_font_get_glyph_bbox): Use libnrtype + (sp_font_get_glyph_advance): Ditto + (sp_font_get_glyph_bbox_lr2tb): Ditto + (sp_string_calculate_dimensions): Ditto + (sp_string_set_shape): Ditto + + * src/sp-chars.c (sp_chars_destroy): Use libnrtype + (sp_chars_bbox): Ditto + (sp_chars_show): Ditto + (sp_chars_clear): Ditto + (sp_chars_add_element): Ditto + (sp_chars_normalized_bpath): Ditto + (sp_chars_do_print): Ditto + + * src/sp-chars.h (sp_chars_set_paintbox): Use libnrtype + + * src/libnrtype/nr-type-gnome.h: Placeholder + + * src/libnrtype/nr-type-directory.c: New file + + * src/libnrtype/nr-type-directory.h: New file + + * src/libnrtype/nr-font.c: New file + + * src/libnrtype/nr-font.h: New file + + * src/libnrtype/nr-typeface.c: New file + + * src/libnrtype/nr-typeface.h: New file + + * src/Makefile.am (SUBDIRS): Added libnrtype + + * src/libnr/nr-path.h: Placeholder + +2002-09-30 Lauris Kaplinski + + * src/widgets/gradient-position.c (spgp_clip_line): New method + (spgp_draw_rect): Ditto + +Sun Sep 29 14:17:31 2002 Mitsuru Oka + + * src/knot.c, knot.h: Moved SPKnot from subclass of GtkObject + to GObject. + + * src/knotholder.c: Ditto + + * src/seltrans.c: Ditto + + * src/selection.c: Migrated dispose to destroy for remainder. + + * src/desktop-events.c: Fixed to connect signal handler correctly. + + * src/desktop.c: Fixed to add button correctly. + + * src/sp-use.c: Depressed gchar * warnings. + + * src/sp-guide.c: Indented. + +2002-09-29 Lauris Kaplinski + + * src/sp-gradient.c (sp_gradient_set_gs2d_matrix_f): Oops, write the right transform + + * src/widgets/gradient-position.c: Use new sensible internals + + * src/widgets/gradient-position.h: Ported to ne internals + + * src/widgets/paint-selector.c (sp_paint_selector_set_mode_gradient): Removed + separate linear/radial optionmenu + + * src/widgets/gradient-selector.c (sp_gradient_selector_set_gs2d_matrix_f): New method + (sp_gradient_selector_get_gs2d_matrix_f): Ditto + (sp_gradient_selector_set_rgradient_position): Implement + (sp_gradient_selector_init): Pax buttons under vector + + * src/widgets/gradient-position.c: New positioning syntax, lots of radial stuff + + * src/libnr/nr-matrix.h (NR_MATRIX_DF_TRANSFORM_X): Convenience macro + (NR_MATRIX_DF_TRANSFORM_Y): Ditto + + * src/dialogs/object-properties.c (sp_object_properties_dialog): Shorten string + + * src/dialogs/stroke-style.c (sp_stroke_style_paint_update): Use new + gradient widgets syntax + (sp_stroke_style_paint_dragged): Ditto + (sp_stroke_style_paint_changed): Ditto + + * src/dialogs/fill-style.c (sp_fill_style_widget_update): Use new gradient + widgets syntax for bbox, transform, position + (sp_fill_style_widget_paint_dragged): Ditto, use helper + (sp_fill_style_widget_paint_changed): Ditto + + * src/sp-gradient.c (sp_gradient_get_gs2d_matrix_f): New method + (sp_gradient_set_gs2d_matrix_f): Ditto + (sp_gradient_write): Implement + (sp_lineargradient_write): Ditto + (sp_radialgradient_write): Ditto + + * src/select-context.c (sp_select_context_root_handler): Process button + release only if grabbed + +2002-09-28 Lauris Kaplinski + + * src/widgets/gradient-vector.c (sp_gvs_rebuild_gui_full): Do not add id label + + * src/widgets/paint-selector.c (sp_paint_selector_init): Added radial button + (sp_paint_selector_set_style_buttons): Set radial + (sp_paint_selector_set_mode_gradient): Set correct button + + * glade/Makefile.am (pixmaps): Added fill_radial.xpm + +Sat Sep 28 14:35:21 2002 Mitsuru Oka + + * src/toolbox.c: Use gtk_window_set_resizable() instead of + gtk_window_set_policy(), because it is deprecated in GTK+2. + + * src/file.c: Depressed warning on gnome_print_master_perview_new. + + * src/sp-object.h, sp-object.c: Added destroy signal and + remove dispose signal. + + * src/selection.c, sp-gradient.c, style.c, + src/widgets/gradient-vector.c: Moved dispose to destroy. + + * src/sp-guide.c: Added property. + + * src/helper/sp-guide.c: Added property. + + * src/sp-namedview.c: Moved gtk_object_unref to g_object_unref. + + * src/dialogs/text-edit.c: Removed some GNOME dependencies. + + * src/helper/gnome-utils.h gnome-utils.c: New file. + Utilities to help to remove GNOME libraries. + + * src/interface.c: Moved some GNOME functions to gnome-utils.h. + +2002-09-27 Lauris Kaplinski + + * src/widgets/paint-selector.c (sp_paint_selector_get_gradient_position_floatv): Set radial + + * src/libnr/nr-pixblock-pixel.c (nr_compose_pixblock_pixblock_pixel): Kill + division by zero, if fg and bg are both fully transparent + + * src/dialogs/fill-style.c (sp_fill_style_widget_update): Implement radial + (sp_fill_style_widget_paint_dragged): Ditto + (sp_fill_style_widget_paint_changed): Ditto + + * src/sp-gradient.c (sp_radialgradient_set_position): New method + + * src/gradient-chemistry.c (sp_gradient_ensure_radial_private_normalized): New method + (sp_gradient_get_radial_private_normalized): Ditto + (sp_item_force_fill_radialgradient_vector): Ditto + (sp_item_force_stroke_radialgradient_vector): Ditto + +2002-09-27 Lauris Kaplinski + + * src/widgets/paint-selector.c (sp_paint_selector_set_gradient_radial): New method + + * src/widgets/gradient-position.c (sp_gradient_position_set_mode): New method + (sp_gradient_position_update): Setup linear/radial renderer as needed + + * src/widgets/gradient-selector.c (sp_gradient_selector_set_mode): New method + (sp_gradient_selector_set_lgradient_position): Renamed method + (sp_gradient_selector_set_rgradient_position): Ditto + (sp_gradient_selector_get_lgradient_position_floatv): Renamed method + (sp_gradient_selector_get_rgradient_position_floatv): Ditto + + * src/libnr/nr-pixblock-pixel.c (nr_compose_pixblock_pixblock_pixel): Fixed + R8G8B8 target to render channels separately + + * src/sp-gradient.c (sp_gradient_from_position_xy): Made gradient method, + changed signature, added gradientTransform to list + (sp_gradient_to_position_xy): Ditto + + * src/libnr/nr-pixblock-pixel.c: New file + + * src/libnr/nr-pixblock-pixel.h: New file + + * src/libnr/nr-gradient.c (nr_lgradient_renderer_setup): Use gradientspace + (nr_lgradient_render_block): Use generic renderer, if no specific one + (nr_lgradient_render_generic): Implement + + * src/sp-gradient.c (sp_gradient_render_vector_block_rgb): Compose correctly + + * src/libnr/nr-blit.c (nr_compose_pixblock_pixblock_pixel): Generic pixel composer + +2002-09-26 Masatake YAMATO + + * src/select-context.c (sp_select_context_root_handler): + used sp_canvas_item_grab where I want to receive key_press event. + (sp_select_context_item_handler): Ditto. + +2002-09-26 Lauris Kaplinski + + * src/libnr/nr-gradient.c: New file + + * src/libnr/nr-gradient.h: New file + + * src/sp-gradient.c (sp_lineargradient_painter_new): Construct libnr renderer + (sp_lg_fill): Use it + (sp_radialgradient_painter_new): Construct renderer + (sp_rg_fill): Use it + + * src/sp-shape.c (sp_shape_print): Clear pixelstore + + * src/sp-chars.c (sp_chars_print_bpath): Clear pixelstore before each rendering + + * src/sp-gradient.c (sp_rg_fill): Oops, moved declaration before statements + (sp_rg_fill): Ditto + +2002-09-25 Lauris Kaplinski + + * src/libnr/nr-compose.c (nr_R8G8B8A8_N_EMPTY_R8G8B8A8_P): Oops, evil bug + + * src/libnr/nr-rect.c (nr_rect_d_matrix_d_transform): New method + (nr_rect_f_matrix_f_transform): Ditto + + * src/sp-object-repr.c (sp_object_type_lookup): Added + + * src/sp-pattern.h: New file + + * src/sp-pattern.c: New file + + * src/Makefile.am (sodipodi_SOURCES): Added sp-pattern.[c,h] + + * src/sp-gradient.c (sp_rg_fill): Implement, seems correct although SLOW + (sp_radialgradient_painter_new): Implement, except viewport percentages + (sp_radialgradient_read_attr): Initialize right numbers + (sp_radialgradient_init): Ditto + +Tue Sep 24 01:01:21 2002 Mitsuru Oka + + * src/interface.c (sp_ui_menu_append_item): Fixed to work well, + even if label is exist and stock is not exist. + + * src/widgets/sp-menu-button.c (sp_menu_button_menu_position): + Modified for popup menu calculation. + + * src/widgets/sp-toolbox.c: Added GTK_SIGNAL_FUNC cast. + +2002-09-24 Masatake YAMATO + + * src/select-context.c (sp_select_context_root_handler, + sp_select_context_item_handler): used GDK_space instead + of GDK_BUTTON_2. Added Lauris's event mask code after + grabbing an item. + + * src/seltrans.c (sp_sel_trans_handle_stamp): removed. + (sp_seltrans_handle_event): handled "pressing space" as + stamping. + (gdk/gdkkeysyms.h): included. + + * src/knot.c (sp_knot_class_init): removed "stamped" signal + again. + (sp_knot_handler): didn't emit stamped anymore. + +2002-09-24 Lauris Kaplinski + + * src/libnr/nr-matrix.c (nr_matrix_d_set_scale): new method + (nr_matrix_f_set_scale): Ditto + + * src/sp-use.c (sp_use_href_changed): Use unref instead of destroy + (sp_use_destroy): Ditto + + * src/seltrans.c (sp_sel_trans_scale): Allow scaling in one dimension, + if it is > 0.0 + (sp_sel_trans_scale_request): Snap in one dimension, if > 0.0 + + * src/sp-path.c (sp_path_bbox): Allow empty bboxen + + * src/helper/art-utils.c (sp_bpath_matrix_d_bbox_d_union): Union always, + even if computed bbox is empty + +Mon Sep 23 01:37:09 2002 Mitsuru Oka + + * src/widgets/sp-menu-button.c: Clean up code. + + * src/widgets/sp-menu-button.c (sp_menu_button_menu_position): + In GTK+2, button widget share its window among toplevel window, + so I fixed offset calculation. + + * src/knot.c: Clean up unused marshaller. + + * src/knotholder.c: Ported. + +2002-09-23 Lauris Kaplinski + + * src/helper/sp-canvas-util.c (sp_canvas_item_grab): new method to + circumvent GnomeCanvas bug + + * src/knot.c (sp_knot_handler): Use sp_canvas_item_grab + +2002-09-23 Masatake YAMATO + + * src/knot.c (sp_knot_class_init): Added "stamped" signal + (sp_knot_handler): Emit it + + * src/select-context.c (sp_select_context_item_handler): Do stamping + (sp_select_context_root_handler): Ditto + + * src/seltrans.c (sp_sel_trans_stamp): new method + (sp_show_handles): Connect "stamped" signal + (sp_sel_trans_handle_stamp): new handler + +2002-09-23 Lauris Kaplinski + + * src/seltrans.c (sp_seltrans_handle_event): Just here for my debugging + + * src/knot.c (sp_knot_handler): No ungrabbing, added TOP CANVAS HACK, + so we can now get key events and do not kill Gdk + + * configure.in: Version 0.27pre + +Sun Sep 22 22:06:57 2002 Mitsuru Oka + + * src/desktop.c: add destroy call for GtkDialog. + + * src/sp-object.c, sp-polyline.c, style.c, + src/display/canvas-area.c, src/widgets/gradient-image.c, + gradient-vector.c: Ported and fixed. + + * src/sp-ruler.c: Bug fixed that + misspelling s/GtkHRuler/SPHRuler/ and s/GtkVRuler/SPVRuler/. + + * src/widgets/sp-menu-button.c, sp-menu-button.h, src/toolbox.c: + Found duplicated signal "activate". + So, renamed SPMenuButton::activate to "activate-item" and + did corresponding change for toolbox.c. + + * src/helper/sp-ctrlline.c: Avoid to duplicated free call for ctrlline->svp. + +2002-09-22 Lauris Kaplinski + + * configure.in: Version 0.26 + + * src/main.c: #include , thanks to Masatake + +Sun Sep 22 22:21:14 2002 Mitsuru Oka + + * src/sp-ruler.c: Bug fixed that + misspelling s/GtkHRuler/SPHRuler/ and s/GtkVRuler/SPVRuler/. + +Sat Sep 21 03:02:21 2002 Mitsuru Oka + + * Now, sodipodi can build and start up again (but often cause segv). + + * src/display/canvas-arena.c, nr-arena-glyphs.h, nr-arena.c: + Ported. + + * src/dialogs/export.c, text-edit.c: Ported. + + * src/widgets/sp-color-slider.c, sp-menu-button.c: Ported. + + * src/*.c, *.h: Ported. + + * glade/*.glade: conveted to glade-2. + +2002-09-21 Lauris Kaplinski + + * src/dialogs/fill-style.c (sp_fill_style_widget_new): Fill rule selector + (sp_fill_style_widget_update): Update fill rule selector + (sp_fill_style_widget_update_repr): Ditto + (sp_fill_style_widget_fill_rule_activate): Set fill-rule + + * src/document.c (sp_document_new): Do not set style + + * src/xml/repr.c (sp_repr_merge): Duplicate node without id key + + * src/sp-path.c (sp_path_build): Set fill to none for old version open path + + * src/bonobo/embeddable-document.c (sp_embeddable_document_pf_load): New + document constructor signature, thanks to Ted Gould + (sp_embeddable_document_ps_load): Ditto + (sp_embeddable_document_new): Ditto + + * src/help.c (sp_help_about): use sp_text_set_repr_multiline + + * src/style.c (sp_style_write_difference): Rewind pointer + + * src/sp-ellipse.c (sp_genericellipse_set_shape): Request modified + (sp_arc_modified): Implement, write path attribute + +2002-09-20 Lauris Kaplinski + + * src/sp-object.c (sp_object_private_write): Duplicate repr if needed + + * src/xml/repr-util.c (sp_repr_set_double_default): New method + + * src/sp-rect.c (sp_rect_write): Set default on radiuses + + * src/sp-root.c (sp_root_write): Set namespaces here + + * src/xml/repr.c (sp_repr_document_new): Set doctype and comment + + * src/xml/repr-io.c (sp_repr_read_file): Set doctype and comment if SVG + (sp_repr_read_mem): Ditto + (sp_repr_save_stream): Save doctype and comment + +Thu Sep 19 19:24:04 2002 Mitsuru Oka + + * src/sp-marshal.*, src/Makefile.am: Removed old marshaller codes. + +2002-09-19 Lauris Kaplinski + + * src/sp-text.c (sp_string_set_shape): Update position array + (sp_text_get_cursor_coords): New method + (sp_text_set_shape): Set tspan position to text, if unset; Limit block + to tspans with unspecified role + (sp_text_insert_line): Implement + + * src/text-context.c (sp_text_context_setup): Set blink to 250ms + (sp_text_context_selection_modified): Implement, update cursor position + (sp_text_context_selection_changed): Ditto + (sp_text_context_root_handler): Cursor placement, insertion and deletion + work as they should + + * src/display/nr-arena-shape.c (nr_arena_shape_update): Do not try to + fill paths consisting of single lineto + + * src/gradient-chemistry.c (sp_gradient_ensure_private_normalized): Only keep + if hrefcount == 1 (fixed bug) + + * src/style.c (sp_style_read): Only parse CMYK if RGBA present + +2002-09-18 Lauris Kaplinski + + * src/sp-ellipse.c (sp_arc_set_elliptical_path_attribute): Lay 2PI arcs as 2 segments + (sp_arc_write): Write SVG if it really is one + + * src/style.c (sp_style_write_ienum): We compare computed values, to + avoid unnecessary setting of attributes + (sp_style_merge_from_parent): Set only computed values for everything + + * src/helper/art-utils.c (sp_vpath_from_bpath_closepath): New method, + borrowed relevant helpers from libart code + + * src/display/nr-arena-shape.c (nr_arena_shape_update): Closeall if filled, + limit min width to 0.125 instead of cutting it to 0 + +2002-09-17 Lauris Kaplinski + + * src/event-context.c (sp_event_context_destroy): Do not disconnect + desktop signal, as there is no such + (sp_event_context_new): Do not connect desktop signal + + * src/draw-context.c (sp_pencil_context_root_handler): Changed grabbing only + to happen, if pointer is moved button-down. This changed irritating + double-click total grab problem. + (sp_pen_context_root_handler): Ditto + + * src/display/nr-arena-group.c (nr_arena_group_update): Multiply + with group second transformation + + * src/display/nr-arena-group.h: Added child_affine member + + * src/sp-root.c (sp_root_read_attr): Use NRMatrixD for viewbox + (sp_root_show): Implement, apply viewBox + (sp_root_bbox): Ditto + (sp_root_print): Ditto + + * src/sp-item.c (sp_item_i2doc_affine): Apply viewBox + +Tue Sep 17 13:50:40 2002 Mitsuru Oka + + * src/dialogs/stroke-style.c: A few fix from my office. + +Mon Sep 16 21:31:33 2002 Mitsuru Oka + + * src/display/*: Really done. + + * src/*: Half done, but partially adhock. + +Mon Sep 16 14:22:10 2002 Mitsuru Oka + + * Start migration to GTK+2 environment. + + * Makefile.am, configure.in, acconfig.h: Use pkgconfig, GLib2, + Pango, GTK+2, GNOME2, etc. + + * src/dialogs/*: Done. + + * src/display/*: Done. + + * src/helper/*: Done. + + * src/svg/*: Done. + + * src/widgets/*: Done. + + * src/xml/*: Done. + + * src/*: Partialy done. + +2002-09-16 Lauris Kaplinski + + * src/helper/png-write.c (sp_png_get_block_stripe): Helper + (sp_png_write_rgba): Use striped writer + (sp_png_write_rgba_striped): New method + + * src/dialogs/export.c (sp_export_get_rows): Renderer + (sp_export_do_export): Use striped exporter + + * src/file.c: Added - Thanks to Masatake for finding it + +2002-09-15 Lauris Kaplinski + + * src/display/nr-arena-image.c (nr_arena_image_render): Use libnr + transformed composition methods + + * src/libnr/nr-compose-transform.c: New file + + * src/libnr/nr-compose-transform.h: New file + +2002-09-15 Masatake YAMATO + + * src/toolbox.c (sp_maintoolbox_drag_data_received): made + it a static scoped function. + (sp_maintoolbox_create): Connected sp_maintoolbox_drag_data_received + to maintoolbox. (glade based version is obsoleted.) + + * src/toolbox.c (sp_maintoolbox_drag_data_received): removed + declaration. + +2002-09-15 Lauris Kaplinski + + * src/file.c (sp_file_save_as): Added "file type" optionmenu + (sp_file_save_type_activate): Helper + (file_save_ok): Save plain SVG if needed + + * src/sp-namedview.c (sp_namedview_write): Implement + + * src/sp-text.c (sp_text_write): Implement + + * src/sp-use.c (sp_use_write): implement + + * src/sp-root.c (sp_root_write): Implement + + * src/sp-polyline.c (sp_polyline_write): Implement + + * src/sp-line.c (sp_line_write): Implement + + * src/sp-image.c (sp_image_write): Implement + + * src/sp-gradient.c (sp_stop_write): Implement + + * src/sp-defs.c (sp_defs_write): Implement + + * src/sp-clippath.c (sp_clippath_write): Implement + + * src/sp-anchor.c (sp_anchor_write): Implement + + * src/sp-polygon.c (sp_polygon_write): new ::write syntax + + * src/sp-spiral.c (sp_spiral_write): New ::write syntax + + * src/sp-star.c (sp_star_write): New ::write syntax + + * src/sp-ellipse.c (sp_ellipse_write): New ::write syntax + (sp_circle_write): Ditto + (sp_arc_write): Ditto + + * src/sp-rect.c (sp_rect_write): New ::write syntax + + * src/sp-shape.c (sp_shape_write): New ::write syntax + + * src/star-context.c (sp_star_finish): New ::write syntax + + * src/spiral-context.c (sp_spiral_finish): New ::write syntax + + * src/knotholder.c (knot_moved_handler): new ::write syntax + + * src/sp-object.c (sp_object_invoke_write): Renamed and enhanced + ::write_repr method, can now construct trees and write plain SVG + + * src/sp-item-group.c (sp_group_write): Implement + +2002-09-14 Lauris Kaplinski + + * src/toolbox.c (sp_maintoolbox_menu_button_press): Construct main + menu here dynamically + + * src/main.c (sp_main_console): Hide documents for nongui, slideshow + + * src/interface.c (sp_ui_file_menu): Recent list + (sp_ui_main_menu): Ditto + (sp_menu_append_recent_documents): New helper + + * src/help.c (sp_help_about): Hide document from list + + * src/file.c (sp_file_open): New method + (sp_file_open_dialog): Renamed old sp_file_open + + * src/sodipodi.c (sodipodi_add_document): Emit "new_document" + (sodipodi_remove_document): Emit "destroy_document", update recent list + (sodipodi_segv_handler): Truncate filenames to sensible part + + * src/toolbox.c (sp_maintoolbox_open_one_file_with_check): Use sp_file_open + +2002-09-13 Lauris Kaplinski + + * src/draw-context.c (sp_pencil_context_root_handler): Clear anchors + (spdc_finish_endpoint): Ditto + (spdc_pen_finish): Ditto + + * src/document.h: Moved uri/base/name to main structure + + * src/draw-context.c (sp_pen_context_finish): Call parent method, fixes + habit of crashing after using pen + +2002-09-12 Lauris Kaplinski + + * src/libnr/*: Started composing sensible library at last + + * src/document.c: Fix DTD typo + + * src/main.c (sp_main_gui): Moved setting LC_NUMERIC after gnome init + (sp_main_console): Set LC_NUMERIC to "C" here too + +2002-09-11 Lauris Kaplinski + + * configure.in: Version 0.26pre + + * src/display/Makefile.am (libspdisplay_a_SOURCES): Removed fill.[c,h] and stroke.[c,h] + +2002-09-11 Lauris Kaplinski + + * src/node-context.c (sp_node_context_item_handler): Do not + select, if rubberband has been dragged + + * src/widgets/sp-menu-button.c (sp_menu_button_draw): Implement, + draw small indication arrow here + (sp_menu_button_expose): Ditto + + * src/helper/curve.c (sp_bpath_clean): New method + (sp_curve_new_from_bpath): Clean bpath, if not good + (sp_curve_new_from_static_bpath): Ditto + (sp_curve_new_from_foreign_bpath): Ditto + + * src/macros.h: Some new macros + + * src/sp-object.c (sp_object_modified): Oops! Replaced '&&' with '&', + this fixed super-slow rendering during drag bug + +2002-09-10 Lauris Kaplinski + + * src/selection-chemistry.c (sp_group_cleanup): Helper + (sp_edit_cleanup): New method + + * src/path-chemistry.c (sp_path_cleanup): New method + + * src/draw-context.c (sp_draw_context_finish): Implement + + * src/seltrans.c (sp_sel_trans_ungrab): Do not set identity + + * src/sp-item-transform.c: Do not set identity transform + + * src/sp-text.c (sp_text_write_transform): Do not write identity + + * src/sp-rect.c (sp_rect_write_transform): Do not write identity + + * src/xml/repr.c (sp_repr_remove_listener_by_data): Oops, removed excess step + + * src/sp-shape.c (sp_shape_build): Force style rewrite for old versions + + * src/view.c (sp_view_widget_view_destroy): handler + (sp_view_widget_set_view): Connect "destroy" + + * src/main.c (sp_do_export_png): Move exporting code here, implement + --export-width, --export-height, --export-backround arguments + + * src/helper/nr-plain-stuff.c (nr_render_r8g8b8a8_r8g8b8a8_alpha): Implement + using internal composer + + * src/sp-item.c (sp_item_paint): Render buffer instead of copy + +2002-09-09 Masatake YAMATO + + * src/sp-image.c (autotrace_dialog): Used + gtk_signal_connect_object_while_alive and + gtk_signal_connect_object instead of gtk_signal_connect_while_alive + and gtk_signal_connect. + (object_destroyed): Removed. + (load_trace_result): ask the user whehter loading or net. + + * configure.in (AM_PATH_FRONTLINE): Check the version of frontline(>= 0.5.1). + +2002-09-09 Zbigniew Chyla + + * src/draw-context.c, src/dyna-draw-context.c, src/select-context.c, + src/spiral-context.c, src/star-context.c, + src/dialogs/tool-attributes.c, src/dialogs/tool-options.c, + src/dialogs/xml-tree.c: Added + +2002-09-09 Lauris Kaplinski + + * src/gradient-chemistry.c (sp_gradient_ensure_private_normalized): Normalize + if flag is set, but hrefcount > 1 + (sp_item_force_fill_lineargradient_vector): Check for hrefcount + (sp_item_force_stroke_lineargradient_vector): Ditto + + * src/interface.c: Added + + * glade/toolbox.glade: Fixed non-ASCII character + +2002-09-08 Lauris Kaplinski + + * src/dialogs/export.c (sp_export_do_export): Fixed affine + + * src/main.c (sp_main_console): Fixed affine + + * src/toolbox.c (sp_maintoolbox_create): Construct main window by hand + + * src/interface.c (sp_ui_main_menu): New method + + * src/help.c (sp_help_about): Use document width and height + + * src/svg-view.c (sp_svg_view_rescale): Use pixel coords + (sp_svg_view_widget_size_request): Ditto + + * src/spiral-context.c (sp_spiral_context_config_widget): Implement + (sp_spiral_context_setup): Ditto + (sp_spiral_context_set): Ditto + + * src/star-context.c (sp_star_context_config_widget): Implement + + * src/desktop.c (sp_desktop_new): Use repr key for initial select context + + * src/select-context.c (sp_select_context_config_widget): Implement + (sp_select_context_transform_toggled): Helper + (sp_select_context_show_toggled): Ditto + + * src/display/nr-arena-shape.c (nr_arena_shape_update): Do not stroke, + if width < 0.125 + + * src/display/nr-arena-glyphs.c (nr_arena_glyphs_group_update): Use paintbox + (nr_arena_glyphs_group_set_paintbox): New method + (nr_arena_glyphs_update): Do not stroke if width < 0.125 + (nr_arena_glyphs_render): Do not render here + (nr_arena_glyphs_fill_mask): New helper + (nr_arena_glyphs_stroke_mask): Ditto + (nr_arena_glyphs_group_update): Create painters here + (nr_arena_glyphs_group_render): Render here + + * src/dialogs/tool-attributes.c (sp_tool_attributes_dialog_setup): Added + SPSelectContext + + * src/dialogs/stroke-style.c (sp_stroke_style_paint_update): Use new gradient + position widget logic + (sp_stroke_style_paint_dragged): Ditto + (sp_stroke_style_paint_changed): Ditto + + * src/dialogs/fill-style.c (sp_fill_style_widget_update): Use new gradient + position widget logic + (sp_fill_style_widget_paint_dragged): Ditto + (sp_fill_style_widget_paint_changed): Ditto + + * src/sp-shape.c (sp_shape_show): Calculate and set paintbox + (sp_shape_modified): Ditto + + * src/sp-gradient.c (sp_lineargradient_from_position): New method + (sp_lineargradient_to_position): Ditto + + * src/sp-chars.c (sp_chars_print_bpath): Implement via nr plain buffers + (sp_chars_set_paintbox): New method + + * src/seltrans.c (sp_sel_trans_shutdown): Destroy handles and canvasitems + + * src/seltrans.h: Added modifieable parameters + + * src/selection.c (sp_selection_bbox_document): New method + + * src/select-context.c (sp_select_context_set): Implement this + + * src/arc-context.c (sp_arc_finish): Oops, set sodipodi namespace + +2002-09-07 Lauris Kaplinski + + * src/style.c (sp_length_differ): Oops, if units differ check value + + * src/sp-paint-server.h: painter contructor signature change + + * src/display/nr-arena-shape.c: Remove group stuff + (nr_arena_shape_set_paintbox): New method + + * src/display/nr-arena-shape.h: Remove group stuff + + * src/sp-object.c (sp_object_get_style_property): read presentation attr + + * src/sp-chars.c (sp_chars_style_modified): Use nr_arena_glyphs_group + (sp_chars_show): Ditto + (sp_chars_clear): Ditto + (sp_chars_add_element): Ditto + + * src/sp-shape.c (sp_shape_modified): Set paintbox + (sp_shape_style_modified): Use single nr_arena_shape + (sp_shape_show): Ditto + (sp_shape_remove_comp): Ditto + (sp_shape_add_comp): Ditto + + * src/macros.h: Add total silencing + + * src/sp-gradient.c (sp_lineargradient_painter_new): Implement userSpaceOnUse + except percentages (still not clear, what to do with those), but do + bbox correctly + +2002-09-06 Lauris Kaplinski + + * src/dialogs/text-edit.c (sp_text_edit_dialog_update_object): Generic method + (sp_text_edit_dialog_set_default): New method + (sp_text_edit_dialog_read_selection): Read defaults if no text + (sp_text_edit_dialog_text_changed): Update default button + (sp_text_edit_dialog_font_changed): Ditto + (sp_text_edit_dialog_any_toggled): Ditto + (sp_ted_get_selected_text_item): Helper + + * src/dialogs/tool-options.c (sp_tool_options_dialog_setup): Implement + using sp_event_context_config_widget + + * src/event-context.h: Added ::config_widget virtual method + + * src/event-context.c (sp_event_context_config_widget): New method + + * src/dyna-draw-context.c (sp_dyna_draw_context_config_widget): new method + +2002-09-05 Lauris Kaplinski + + * src/dialogs/stroke-style.c (sp_stroke_style_paint_construct): Handler + (sp_stroke_style_paint_attr_changed): Ditto + (sp_stroke_style_repr_get_style): Helper + (sp_stroke_style_paint_update_repr): For SPRepr associated styles + (sp_stroke_style_paint_changed): Write bare repr if needed + (sp_stroke_style_line_construct): Handler + (sp_stroke_style_line_attr_changed): Ditto + (sp_stroke_style_line_update_repr): Alternate parser + (sp_stroke_style_width_changed): Write repr if needed + (sp_stroke_style_any_toggled): Ditto + + * src/dialogs/object-properties.c (sp_object_properties_dialog): build + optionmenu for choosing between selection/tools + + * src/dialogs/fill-style.c (sp_fill_style_widget_new): Attach attr_changed + (sp_fill_style_repr_get_style): Helper + (sp_fill_style_widget_update_repr): Repr-associated version updater + (sp_fill_style_widget_paint_changed): Write repr instead of item list if needed + + * src/widgets/sp-widget.c (spw_repr_attr_changed): Repr callback + (sp_widget_new_global): Build from sodipodi + (sp_widget_new_repr): Build from repr + (sp_widget_construct_global): Constructor + (sp_widget_construct_repr): Ditto + + * src/style.c (sp_style_new): New method + (sp_style_read): Move evrything here + (sp_style_read_from_object): Frontend + (sp_style_read_from_repr): Ditto + +2002-09-04 Lauris Kaplinski + + * src/sp-path.c (sp_path_build): Update SODIPODI-PATH-NODE-TYPES attribute + +2002-09-03 Lauris Kaplinski + + * src/sp-text.c (sp_text_set_shape): Oooooooops, use MAX for bbox other corner + + * src/document.c (sp_document_new): Set docname attribute after build + + * src/sp-text.c (sp_text_find_version): Helper + (sp_text_build): Build tspans etc. if 0.0 < version < 0.25 + + * src/sp-ellipse.c (sp_arc_find_version): Helper + (sp_arc_build): Per-version attributes + (sp_arc_read_attr): Ditto + + * src/document.c (sp_document_new): Delay namespaces etc. to determine version + (sp_document_new_from_mem): Ditto + + * src/document.h: Bring some members here + +2002-09-02 Lauris Kaplinski + + * src/dialogs/stroke-style.c (sp_stroke_style_line_update): Make insensitive, if not stroked + + * src/sp-rect.c (sp_rect_write_transform): Adjust stroke width, if scale changes + + * src/sp-text.c: Port to SPSVGUnits + + * src/sp-root.c: Port to SPSVGLength, use pixels as basic units from now on + + * src/sp-rect.c: Port to SPSVGLength + + * src/sp-image.c: Port to SPSVGLength + + * src/sp-gradient.c: Port to SPSVGLength + + * src/sp-ellipse.c: Port to SPSVGLength + + * src/file.c (sp_do_file_print_to_printer): Fix px/pt ratio + (sp_do_file_print_preview): Ditto + + * src/document.c (sp_document_width): Fix px/pt ratio + (sp_document_height): Ditto + (sp_document_new): Add sodipodi:version + (sp_document_new_from_mem): Ditto + + * src/desktop.c (sp_desktop_init): Fix px/pt ratio in doc2dt matrix + + * src/svg/svg-length.c (sp_svg_length_read): New method + (sp_svg_length_read_lff): Ditto + (sp_svg_length_unset): Ditto + + * src/svg/svg-types.h: New file + + * src/dialogs/Makefile.am (libspdialogs_a_SOURCES): Added tool-options.[c,h] + +2002-08-30 Lauris Kaplinski + + * src/sp-text.c (sp_text_set_shape): Do layouting here, so we can handle blocks + + * src/dialogs/text-edit.c (sp_text_edit_dialog): Layout radiobuttons + (sp_text_edit_dialog_apply): Do layout + (sp_text_edit_dialog_read_selection): Ditto + + * src/sp-text.c (sp_font_get_glyph_bbox): New helper + (sp_font_get_glyph_advance): Ditto + (sp_font_get_glyph_bbox_lr2tb): Ditto + (sp_string_calculate_dimensions): Do vertical dimension correctly + (sp_string_set_shape): Ditto + +2002-08-29 Lauris Kaplinski + + * src/sp-text.c (sp_string_calculate_dimensions): New method + + * configure.in: Rewind required gnome-print version to 0.29 + + * src/sp-object.h: Added viewport and user flags + + * src/style.c: Added functional 'text-anchor' property + + * src/style.h: Added functional 'text-anchor' property + + * src/svg/svg-color.c (sp_svg_read_color): Read rgb(r,g,b) variants + + * src/style.c: Created new IEnum type with immediate and computed members, + ported font-style, font-variant, font-weight, font-stretch to it + + * src/sp-text.c (sp_string_set_shape): Use computed 'font-style' value + + * glade/Makefile.am (glade_DATA): Removed text-dialog.glade + + * src/dialogs/text-edit.c: Get rid of glade + +2002-08-28 Lauris Kaplinski + + * src/display/canvas-arena.c: Ref active item, so it does not disappear + + * src/style.c: Implement SPIFontSize and various helpers for it + + * src/sp-text.c: New font size type + + * src/sp-shape.c: 24-bit opacity scale + + * src/sp-item.c (sp_item_read_attr): Reread style for font-size + + * src/sp-image.c: 24-bit opacity scale + + * src/sp-chars.c: 24-bit opacity scale + + * src/gradient-chemistry.c: 24-bit opacity scale + + * src/file.c (sp_do_file_print_preview): Ensure up-to-date + (sp_do_file_print_to_printer): Ditto + +2002-08-27 Lauris Kaplinski + + * src/dialogs/export.c (sp_export_do_export): Fix affine (one more time) + + * src/sp-item.c (sp_item_paint): Ensure document is up-to-date + + * src/sp-chars.c (sp_chars_print_bpath): Use new transformed bpath bbox + (sp_chars_bbox): Ditto + + * src/sp-path.c (sp_path_bbox): Use new transformed bpath bbox + + * src/helper/art-utils.c (sp_bpath_matrix_d_bbox_d_union): New method + (sp_bpath_segment_bbox_d): Helper + +2002-08-26 Lauris Kaplinski + + * src/dialogs/text-edit.c (sp_text_dialog_apply): Oops, set size, not some crap here + + * src/sp-chars.c (sp_chars_do_print): New direct method + (sp_chars_print_bpath): Helper + + * src/gradient-chemistry.c (sp_item_repr_set_style_gradient): Set recursive + +2002-08-25 Lauris Kaplinski + + * src/text-context.c (sp_text_context_finalize): Do not use desktop here + (sp_text_context_finish): Implement, release desktop stuff here + + * src/sp-text.c (sp_text_normalized_bpath): New method + (sp_text_print): Implement, still needs SPChars method + + * src/sp-chars.c (sp_chars_normalized_bpath): New method + + * src/path-chemistry.c (sp_selected_path_to_curves): Convert the new text object + + * src/interface.c (sp_ui_file_menu): Use helpers, the right export dialog + + * src/draw-context.c (sp_pen_context_finish): Flush object + (sp_pen_context_root_handler): Added 'BackSpace', should work OK now + + * src/event-context.c (sp_event_context_finish): New method and virtual method + + * src/desktop.c (sp_desktop_set_event_context): Finish eventcontext + + * src/helper/curve.c (sp_curve_backspace): New method + +2002-08-24 Lauris Kaplinski + + * src/helper/curve.c (sp_curve_append): Handle open/closed end and start + + * src/preferences-skeleton.h: Added pen tool, made AI style default + + * src/draw-context.c (sp_draw_context_setup): Set attach + (sp_draw_context_root_handler): React to '+' key + (spdc_set_attach): Set/clear append mode + (spdc_attach_selection): Renamed + (spdc_detach_selection): New method + (spdc_reset_white): Only need white, not all colors + (sp_pencil_context_root_handler): Destroy green anchor on release + (sp_pen_context_setup): Handle "mode" attribute + (sp_pen_context_set): Ditto + (sp_pen_context_root_handler): Has now AI style (default) and click-click modes + (spdc_pen_set_ctrl): Handle modes + (spdc_pen_finish): New method + +2002-08-23 Lauris Kaplinski + + * src/dialogs/sp-attribute-widget.h: It can now be attached to mere SPRepr too + + * src/dialogs/sp-attribute-widget.c (sp_attribute_widget_new_repr): New constructor + (sp_attribute_widget_set_repr): New method + (sp_attribute_table_new_repr): New constructor + (sp_attribute_table_set_repr): New method + + * src/star-context.c (sp_star_context_set): Attribute reader + (sp_star_context_setup): parse attributes + + * src/marshal.c (sp_marshal_NONE__STRING_BOOL): New method + + * src/interface.c (sp_ui_dialog_menu): Tool attributes menu + + * src/event-broker.c: Added event context node location + + * src/dyna-draw-context.c (sp_dyna_draw_context_set): Attribute reader + (sp_dyna_draw_context_setup): Parse attributes + + * src/draw-context.h: Added selection member + + * src/view.c (sp_view_set_position): Frontend to virtual method + (sp_view_set_status): Ditto + + * src/view.h: Added virtual methods for marking status and position + + * src/desktop.c (sp_desktop_widget_view_status_set): Moved status to + parent container, where it belongs + (sp_desktop_widget_view_position_set): Same for position + (sp_desktop_widget_new): Listen status and position signals + + * src/dialogs/tool-attributes.c: New file + + * src/dialogs/tool-attributes.h: New file + +2002-08-20 Lauris Kaplinski + + * src/dyna-draw-context.c: Removed control knot, as we do not attach to anything + + * src/xml/repr.c (sp_repr_unref): Implemented launching destroy listener + + * src/xml/repr-private.h: Added destroy listener + +2002-08-19 Lauris Kaplinski + + * src/sodipodi.c (sodipodi_segv_handler): Do better names and inform user about these + + * src/selection-chemistry.c (sp_item_list_common_parent_group): Helper + (sp_selection_raise): Made it to work with all item combinations + (sp_selection_lower): Ditto, do not lower under non-items + + * src/sp-item-group.c (sp_group_order_changed): Fix item order calculation + +2002-08-18 Lauris Kaplinski + + * src/document-undo.c (sp_document_order_changed): Set correct action type + +2002-08-17 Lauris Kaplinski + + * src/selection-chemistry.c (sp_selection_ungroup): Use method from item group + + * src/sp-item-group.c (sp_item_group_ungroup): Preserve order and styles + + * src/style.c (sp_style_read_from_object): Synchronized with new style structure + (sp_style_merge_property): Ditto + (sp_style_merge_from_object_parent): Ditto + (sp_style_merge_ipaint): Renamed + (sp_style_write_string): New write semantics + (sp_style_write_difference): New method + (sp_text_style_write): New write semantics + (sp_style_read_ifloat): Rename + (sp_style_read_iscale30): Ditto + (sp_style_read_ienum): Ditto + (sp_style_read_istring): Ditto + (sp_style_read_ipaint): Ditto + (sp_style_write_ifloat): Signature, semantics and name change + (sp_style_write_iscale30): Ditto + (sp_style_write_ienum): Ditto + (sp_style_write_istring): Ditto + (sp_style_write_ipaint): Ditto + (sp_paint_differ): Helper + + * src/style.h: Renamed inherited types, changed miterlimit to ifloat + + * src/color.c (sp_color_is_equal): New method + + * src/style.c (sp_style_merge_from_style_string): Accept (although warn) + properties without end marker + + * src/dialogs/export.c (sp_export_do_export): Use correct transformation + + * src/main.c: Added command-line export functionality + (main): Cleanup + (sp_main_gui): Broke GUI-specific stuff here + (sp_main_console): Same for console mode, implement export, use current dor for print + +2002-08-16 Lauris Kaplinski + + * src/toolbox.c (sp_maintoolbox_create): Moved draw toolbox to separate method + (sp_toolbox_draw_set_object): Callback + (sp_toolbox_draw_create): New method, create MenuButtons + (sp_update_draw_toolbox): Use MenuButtons + + * src/event-broker.c: Added pen context, use pencil and pen instead of draw + + * src/draw-context.c: Break draw context into parent, pencil and pen + + * src/draw-context.h: Ditto + + * src/widgets/sp-menu-button.h: New file + + * src/widgets/sp-menu-button.c: New file, implement something similar to + GtkOptionmenu, but with some sodipodi-specific sugar + + * glade/draw_pen.xpm: New file + + * src/draw-context.c (sp_draw_context_finalize): Destroy pen controls + (sp_draw_context_setup): Setup pen controls + (sp_draw_context_root_handler): Do pen stuff + (spdc_pen_set_point): New helper + (spdc_pen_set_ctrl): Ditto + (spdc_pen_finish_segment): Ditto + + * src/helper/sp-ctrlline.c (sp_ctrlline_set_rgba32): New method + +2002-08-15 Lauris Kaplinski + + * src/toolbox.c (sp_update_draw_toolbox): Freehand keeps undo/redo sensitive now + + * src/document.c (sp_document_ensure_up_to_date): New method + + * src/draw-context.c (sp_draw_context_setup): Read selection data + (sp_draw_context_root_handler): Use colors for freehand, place green anchor + (spdc_selection_changed): Use read_selection + (spdc_selection_modified): Ditto + (spdc_read_selection): New method + (spdc_add_freehand_point): Ditto + (spdc_concat_colors_and_flush): Check, whehter green anchor exist, do contiguous append + (fit_and_split): Use continious append + (sp_draw_anchor_destroy): Signature change + +2002-08-14 Lauris Kaplinski + + * src/draw-context.c (sp_draw_context_destroy): Do not destroy start and end anchors + (sp_draw_context_selection_modified): Save white curves in desktop coordinates + (sp_draw_context_root_handler): Use state indicator, change addline modes on release + (spdc_concat_colors_and_flush): Use continuous append + (spdc_flush_white): Translate everything to item coordinates here + + * src/draw-context.h: Replace booleans with single state indicator + + * src/helper/curve.c (sp_curve_transform): New method + (sp_curve_append_continuous): New method + +2002-08-12 Lauris Kaplinski + + * src/draw-context.c (spdc_finish_endpoint): Cleanup + (spdc_flush_white): Do concat, create object if needed, do red->white transform if needed + (spdc_clear_red_data): Helper + + * src/draw-context.h: Member rename + + * src/helper/curve.c (sp_curve_append): Append the whole curve, not just last segment + (sp_curve_concat): Set lengths etc. correctly, fixes draw crash + +2002-08-08 Lauris Kaplinski + + * src/dialogs/text-edit.c (sp_text_dialog_apply): Why there were strdups here? + + * src/style.c (sp_style_read_from_object): Cleanup font-family and font-size + (sp_style_merge_property): Ditto + (sp_style_merge_from_object_parent): Ditto + (sp_text_style_write): Ditto + (sp_style_read_inherited_float): New helper + (sp_style_read_inherited_string): Ditto + (sp_style_write_inherited_float): Ditto + (sp_style_write_inherited_string): Ditto + + * src/sp-text.c (sp_text_set_repr_text_multiline): Set roles and line positions + +2002-08-07 Lauris Kaplinski + + * src/sp-text.c (sp_text_read_attr): Request relayout + (sp_text_child_added): Ditto + (sp_text_remove_child): Ditto + (sp_text_modified): Check, whether relayout is needed + (sp_text_request_relayout): Helper + + * src/style.c (sp_style_merge_from_object_parent): Inherit font size (still wrong) + + * src/text-context.c (sp_text_context_root_handler): Allow control key + to be passed, send nonbreaking space for Ctrl+Space + + * src/sp-text.c (sp_string_set_shape): Try to collect spaces across item boundaries + (sp_tspan_set_shape): Ditto + (sp_text_set_shape): Ditto + +2002-08-05 Lauris Kaplinski + + * src/text-context.c (sp_text_context_root_handler): Use sp_text_append + + * src/sp-text.c (sp_text_append): New method + +2002-07-31 Lauris Kaplinski + + * src/text-context.c (sp_text_context_finalize): Use it instead of ::destroy + (sp_text_context_setup): Create cursor + (sp_text_context_root_handler): Show cursor + (sp_text_context_selection_changed): Update cursor + (sp_text_context_timeout): Blink handler + + * src/text-context.h: Added cursor + +2002-07-30 Lauris Kaplinski + + * src/Makefile.am (sodipodi_SOURCES): Added macros.h + + * src/sp-text.c (sp_text_write_transform): Do multiline transforming + the right way + + * src/macros.h: New file for useful macros + +2002-07-29 Lauris Kaplinski + + * src/sp-text.c (sp_tspan_build): Get attributes at right place, read role as well + (sp_tspan_read_attr): Parse "sodipodi:role" attribute + (sp_text_append_line): New method + + * src/sp-text.h: Specify role for element + +2002-07-26 Lauris Kaplinski + + * src/sp-text.c (sp_string_set_shape): Changed signature, pass layout and currentpoint + (sp_tspan_set_shape): New method + (sp_text_build): Use normal order, as shape will be set asynchronously + (sp_text_read_attr): Request update everywhere + (sp_text_child_added): Fix bug, now keep old children in list + (sp_text_set_shape): New method, nothing interesting yet + + * src/text-context.c (sp_text_context_selection_changed): Set active object + to NULL, if nothing selected + +2002-07-24 Lauris Kaplinski + + * src/sp-object.c (sp_object_modified): Merge style with parent if needed, + moved style_modified after signal + + * src/sp-text.c (sp_tspan_modified): Include style flag in cascade + (sp_text_modified): Ditto + (sp_string_modified): Re-enable it (although this is probably not correct) + + * src/style.c (sp_style_merge_from_object_parent): Merge writing mode + + * src/sp-item-group.c (sp_group_modified): Include style flag in cascade + + * src/sp-gradient.c (sp_gradient_modified): Include style flag in cascade + +2002-07-22 Lauris Kaplinski + + * src/style.c (sp_style_new_from_object): Renamed sp_style_new + (sp_style_read_from_object): Use SP_SCALE30 for opacity, new paint structure + (sp_style_merge_property): Ditto + (sp_style_merge_from_object_parent): Renamed sp_style_merge_from_object, + read only from immediate parent (which should have merged from ancestors itself) + (sp_style_write_string): Use SP_SCALE30 for opacity, new paint structure + (sp_style_clear): Ditto + (sp_style_set_opacity): Ditto + (sp_style_read_inherited_scale30): New method + (sp_style_write_inherited_scale30): Ditto + (sp_style_read_inherited_paint): Renamed, parse "inherit" value + (sp_style_write_inherited_paint): Ditto, write it + (sp_style_merge_inherited_paint): Do hunref here + (sp_style_set_fill_color_rgba): Do hunref instead of gtk_object_unref, new structure + (sp_style_set_fill_color_cmyka): Ditto + (sp_style_set_stroke_color_rgba): Ditto + (sp_style_set_stroke_color_cmyka): Ditto + (sp_style_read_color_cmyk): Helper method here + (sp_style_merge_from_style_string): Renamed method + + * src/style.h: Created new 30-bit scaled value type, used for opacity + Renamed SPPaint to SPInheritedPaint + +Sat Jul 13 19:47:16 2002 Davide Puricelli + + * po/ja.po: Updated, thanks Junichi Uekawa + +Sat Jul 13 05:52:15 2002 Mitsuru Oka + + * src/sp-item-group.c (sp_group_bbox): Fixed group selection bug - + thanks to Ted Gould and his bug report. + +2002-05-20 Lauris Kaplinski + + * src/xml/repr-io.c (sp_repr_svg_read_node): Add namespaces back - + thanks to Pawel + + * src/dialogs/xml-tree.c: Complete refactoring by Pawel Palucha + + * src/document.c (sp_document_lookup_id): Check values + +2002-04-21 Masatake YAMATO + + * src/toolbox.c (sp_maintoolbox_open_files): Use + gnome_uri_list_extract_filenames. + + * src/interface.c (sp_ui_import_files): Ditto. + +2002-04-19 Lauris Kaplinski + + * src/text-context.c (sp_text_context_root_handler): Port to new + text object (incomplete) + (sp_text_context_selection_changed): Ditto + + * src/sp-text.c: Lot of new stuff, shows something on screen at last + + * src/sp-object.c (sp_object_modified): Do not allow reentrancy + - think SPText will like it + + * src/sp-item.c: Removed sp_item_update and virtual method + + * src/sp-item-group.c: Removed ::update method + +2002-04-17 Lauris Kaplinski + + * src/sp-rect.c (sp_rect_rx_set): Make argument const, kill warning + (sp_rect_ry_set): Ditto + +2002-04-12 Lauris Kaplinski + + * src/sp-text.h: Broke into SPText, SPTSpan and SPString objects + + * src/sp-text.c (sp_text_build): Build and TEXT elements + + * src/forward.h: Moved SPText and SPTSpan here + +2002-04-08 Lauris Kaplinski + + * src/sp-item.h: Changed ::bbox signature + + * src/sp-item.c (sp_item_invoke_bbox): New generic method + (sp_item_bbox_desktop): renamed old method + + * src/display/nr-arena-glyphs.c: Ditto + + * src/display/nr-arena-glyphs.h: New file + + * src/sp-chars.c (sp_chars_get_type): Change parent class + (sp_chars_class_init): Ditto + (sp_chars_destroy): New elements structure + (sp_chars_style_modified): New virtual method + (sp_chars_bbox): Ditto + (sp_chars_show): Ditto + (sp_chars_print): Ditto (not implemented) + (sp_chars_clear): New structure + (sp_chars_add_element): Ditto + + * src/sp-chars.h: Derive directly from item instead of shape + + * src/dialogs/align.c (sp_quick_align_arrange): New bbox logic + + * src/dialogs/export.c (sp_export_drawing): New bbox logic + +Sun Apr 7 01:37:29 2002 Mitsuru Oka + + * src/style.c: (sp_style_read_from_object): Fixed to work stroke-cmyk. + + * src/sp-item.c: (sp_item_read_attr): Ditto + +2002-04-06 Lauris Kaplinski + + * src/xml/repr-io.c (sp_repr_read_file): Use new signature + (sp_repr_read_mem): Ditto + (sp_repr_qualified_name): New method + (sp_repr_svg_read_node): Signature change, create text nodes + + * src/xml/repr-util.c (sp_xml_document_createTextNode): New method + (sp_xml_document_createElement): Ditto + (sp_xml_document_createElementNS): Ditto + (sp_xml_node_get_Document): Ditto + (sp_xml_element_setAttributeNS): Ditto + + * src/xml/repr.c (sp_repr_new_from_code): Set type + + * src/svg/svg-length.c (sp_svg_read_number_f): New method with right signature + (sp_svg_read_number_d): Ditto + + * src/style.c (sp_style_privatize_text): New method + (sp_style_merge_property): Moved text properties here + + * src/sp-text.c (sp_text_init): No properties + (sp_text_build): No style anymore + (sp_text_style_modified): New virtual method + (sp_text_font_weight_to_gp): Helper + (sp_text_font_italic_to_gp): Ditto + (sp_text_set_shape): Use style properties, hackish support for vertical writing + + * src/sp-text.h: Removed properties from object, as these are handled by style + +2002-04-04 Lauris Kaplinski + + * src/helper/canvas-bpath.c (sp_canvas_bpath_init): Can be filled now + (sp_canvas_bpath_destroy): Ditto + (sp_canvas_bpath_update): Ditto + (sp_canvas_bpath_render): Ditto + (sp_canvas_bpath_point): Ditto + (sp_canvas_bpath_set_fill): New method + (sp_canvas_bpath_set_stroke): Name change + + * src/display/nr-arena-shape.c (nr_arena_shape_render): No real_opacity + anymore + + * src/sp-shape.c (sp_shape_print): No real opacity anymore + + * src/dyna-draw-context.c (sp_dyna_draw_context_setup): Port to + canvas bpath instead of canvas shape + (clear_current): Ditto + (fit_and_split_line): Ditto + (fit_and_split_calligraphics): Ditto + (draw_temporary_box): Ditto + + * src/draw-context.c (sp_draw_context_setup): Port to new canvas bpath + (fit_and_split): Ditto + + * src/dialogs/item-properties.c: Removed #ifdef 0 code + + * src/style.c (sp_style_new): Require object validity + (sp_style_merge_property): Moved actual code to new method + (sp_style_merge_from_string): Does not clear style anymore, thus name change + (sp_style_paint_server_modified): Use sp_object_request_modified + (sp_style_set_fill_color_rgba): Request modified + (sp_style_set_fill_color_cmyka): Ditto + (sp_style_set_stroke_color_rgba): Ditto + (sp_style_set_stroke_color_cmyka): Ditto + (sp_style_set_opacity): Ditto + (sp_style_property_index): New enumerated property codes + + * src/sp-shape.c (sp_shape_style_modified): Renamed method + + * src/sp-item.c (sp_item_read_attr): Use sp_object_request_modified + (sp_item_style_modified): Renamed method, otherwise same + + * src/sp-item-group.c (sp_group_class_init): No ::style_changed anymore + + * src/sp-object.c (sp_object_request_modified): Accept style modification + flag (but not alone) + (sp_object_modified): Ditto, invoke ::style_changed if needed + + * src/sp-object.h (SP_OBJECT_STYLE_MODIFIED_FLAG): New flag - we now + collect style modifications into single-step async apply too + +Sun Mar 31 19:09:25 2002 Mitsuru Oka + + * src/sp-rect.c (sp_rect_*_set): Fixed a little. + +2002-03-22 Davide Puricelli + + * Updated debian/ directory, synced with Debian unstable. + +2002-03-18 Lauris Kaplinski + + * configure.in: Disabled frontline check, until I find time + to make it to work without frontline too + +2002-03-18 Masatake YAMATO + + * src/toolbox.h (sp_maintoolbox_drag_data_received): New + declaration. + + * src/toolbox.c (sp_maintoolbox_open_one_file) + (sp_maintoolbox_open_files, sp_maintoolbox_drag_data_received): + New functions. + (sp_maintoolbox_create): Invoked gtk_drag_dest_set + against ui. + (toolbox_drop_target_info, toolbox_drop_target_entries, + ENTRIES_SIZE, ntoolbox_drop_target_entries): New constants + and macros for DnD. + + * src/interface.c (sp_ui_import_one_file, sp_ui_import_files) + (sp_ui_drag_data_received): New functions. + (sp_create_window): sp_ui_drag_data_received is connected + to "drag_data_received" of ui. Invoked gtk_drag_dest_set + against ui. + (nui_drop_target_entries, ENTRIES_SIZE, ui_drop_target_entries, + ui_drop_target_info): New constants and macros for DnD. + + * glade/toolbox.glade: sp_maintoolbox_drag_data_received is + connected to drag_data_received of maintoolbox. + +2002-03-18 Masatake YAMATO + + * configure.in (ENABLE_AUTOTRACE): Check Frontline. + + * acconfig.h: Added ENABLE_AUTOTRACE. + + * src/sp-image.c: Added code that supports Frontline. + New codes are wrapped by ENABLE_AUTOTRACE. + +Tue Mar 19 02:30:40 2002 Mitsuru Oka + + * New SPRect rx, ry editing feature in node context. + + * src/sp-rect.c (sp_rect_rx_get): New method for KnotHolder + (sp_rect_rx_set): Ditto + (sp_rect_ry_get): Ditto + (sp_rect_ry_set): Ditto + (sp_rect_knot_holder): Ditto + (sp_rect_write_repr): New method + (sp_rect_glue_set_shape): Ditto + +2002-03-14 Stanislav Visnovsky + + * configure.in: Added "sk" to ALL_LINGUAS. + +Sun Mar 10 21:00:01 2002 Mitsuru Oka + + * src/document.c (sp_document_partial_items_in_box): + New method. Return list of items, that the parts of the item + containd in box. + + * select-context.h: Add button_press_shift attribute + + * select-context.c: (sp_select_context_root_handler): + New feature to select items which is partially contained in + rubberband box with shift key. + +Wed Mar 6 01:52:09 2002 Mitsuru Oka + + * Support open/closed arc feature. We can edit it on node edit. + + * src/sp-ellipse.c (sp_genericellipse_side): New method to + determine point is inside or outside. + (sp_arc_start_set): Add is_closed feature + (sp_arc_end_set): Ditto + + * src/sp-ellipse.h: Add SPArc::is_closed attribute + + * src/preferences-skeleton.h: Modified arc style + + * src/arc-context.c: Ditto + + +2002-03-05 Lauris Kaplinski + + * src/display/nr-arena-shape.c (nr_arena_shape_pick): Use delta (tolerance) + + * src/display/canvas-arena.c (sp_canvas_arena_update): Use global delta (tolerance) + (sp_canvas_arena_point): Ditto + (sp_canvas_arena_event): Ditto + + * src/display/nr-arena-item.c (nr_arena_item_invoke_pick): Changed + virtual method signature + + * src/dialogs/display-settings.c (sp_display_dialog_cursor_tolerance_changed): Implement + (sp_display_dialog_new): Create pick tolerance spinbutton + + * src/view.c (sp_view_shutdown): New method and signal + (sp_view_request_redraw): New virtual method + + * src/sodipodi.c (sodipodi_refresh_display): Use sp_view_request_redraw + + * src/interface.c (sp_ui_delete): Use sp_view_shutdown + (sp_ui_menu_append_item): Helper + (sp_ui_file_menu): New method + (sp_ui_edit_menu): Ditto + (sp_ui_selection_menu): Ditto + (sp_ui_view_menu): Ditto + (sp_ui_event_context_menu): Ditto + (sp_ui_dialog_menu): Ditto + (sp_ui_generic_menu): Ditto + + * src/file.c (sp_file_exit): Use sodipodi_exit method + + * src/event-context.c (sp_event_root_menu_popup): Use sp_ui_generic_menu + + * src/desktop.c (sp_desktop_request_redraw): New virtual method implementation + (sp_desktop_widget_set_focus): Do that widget method instead + + * src/desktop-events.c (sp_dt_ruler_event): Do not use desktop->owner + + * src/Makefile.am (INCLUDES): -DSODIPODI_PIXMAPDIR + +Mon Mar 4 01:23:05 2002 Mitsuru Oka + + * src/sp-ellipse.c (sp_genericellipse_normalize): Fixed start and + end arg conditions. + (sp_arc_start_set): Added per pi/4 radian constraint with control key. + (sp_arc_end_set): Ditto + +Sun Mar 3 03:40:07 2002 Mitsuru Oka + + * Merged from ge-arc-branch + + * src/sp-ellipse.h (SPArc): New class + + * src/sp-ellipse.c (sp_arc_*): New methods + + * src/arc-context.c: New event context for SPArc. Mainly it is + renamed from ellipse-context.c. + So we should remove ellipse-context.c later. + + * src/arc-context.h: Ditto + + * glade/draw_arc.xpm: New pixmap file for draw arc tool. + Now, we does not need draw_ellipse.xpm. + + * src/pixmaps/cursor-arc.xpm: Ditto + +2002-02-25 Lauris Kaplinski + + * src/helper/curve.c (sp_curve_append): Do not requite non-empty curves + + * src/draw-context.c (fit_and_split): Commetn out boundary checks + + * src/document.c (sp_document_idle_handler): Bring up uncommited undo + warning, if compiled with debug + (sp_action_print_pending_list): Debug method + (sp_document_warn_undo_stack): Ditto + + * src/document-private.h: Moved idel_id into base struct + +2002-02-23 Lauris Kaplinski + + * src/helper/units.c (sp_points_get_units): New method + (sp_units_get_points): Ditto + + * src/dialogs/object-properties.c: Made layout dynamic + + * src/document-undo.c (sp_document_private_done): New static method + (sp_document_done): Just a wrapper + (sp_document_maybe_done): Implement the real thing + + * src/document-private.h: Moved document definition here + +2002-02-21 Lauris Kaplinski + + * src/dialogs/stroke-style.c (sp_stroke_style_any_toggled): Handle + cap/join style changes + (sp_stroke_style_widget_new): Create cap/join togglebuttons + (sp_stroke_style_widget_update): Set cap/join selector activity + (sp_stroke_style_set_join_buttons): New method + (sp_stroke_style_set_cap_buttons): Ditto + +2002-02-19 Lauris Kaplinski + + * src/dialogs/stroke-style.c: New file + + * src/dialogs/stroke-style.h: New file + + * src/helper/units.c (sp_distance_get_units): New method + (sp_distance_get_points): Ditto + + * src/helper/units.h: Moved SPDistance here + + * src/style.h: Moved SPDistance to units.h + + * src/display/nr-arena-shape.c (nr_arena_shape_render): Render gradient + strokes as well + + * src/dialogs/object-properties.c: Start rewriting to use dynamic + fill/stroke widgets instead of original glade dialog + + * src/dialogs/stroke-style.h: New file + + * src/dialogs/stroke-style.c: New file + + * src/gradient-chemistry.c (sp_style_change_property): Reimplement, + hopefully the correct way now + + * src/widgets/gradient-position.c (sp_gradient_position_update): Pre + build local renderer here + + * src/helper/nr-gradient.c (nr_lgradient_renderer_setup_r8g8b8a8): Do + not allocate renderer, allow using static ones too + (nr_lgradient_renderer_setup_r8g8b8): Ditto + + * src/widgets/paint-selector.c (sp_paint_selector_set_style_buttons): Do not + activate pattern and fractal fill buttons + +2002-02-18 Lauris Kaplinski + + * src/widgets/paint-selector.c: Lot of rearrangements everywhere - + I am too tired to write all these down. Basically we have one frontend + megawidget SPPaintSelector, that interfaces to colors, gradient and more. + +2002-02-10 Lauris Kaplinski + + * src/desktop.c (sp_desktop_widget_destroy): Removed stale signal + disconnect (no idea what it was originally for) + +2002-02-09 Lauris Kaplinski + + * configure.in: Removed rbuf, frgba, new font checks and arena switch + + * src/sp-namedview.c (sp_namedview_setup_grid_item): Grid settings are + always in points, units are there just for user preference + (sp_namedview_read_attr): Ditto + + * src/desktop-snap.c (sp_desktop_horizontal_snap): Read snap distances + from new desktop members + (sp_desktop_vertical_snap): Ditto + (sp_desktop_vector_snap): Ditto + (sp_desktop_circular_snap): Ditto + + * src/desktop-handles.c (sp_desktop_canvas): Update to new desktop structure + + * src/sodipodi.c (sodipodi_activate_desktop_private): Default method + implementation to chain activation signal on desktop + (sodipodi_deactivate_desktop_private): Ditto + + * src/desktop.c (sp_desktop_new): Owner does not have document pointer + any more, so had to change signature here + (sp_desktop_widget_init): Moved activation signals to public constructor + (sp_dtw_desktop_activate): Activation signal handler + (sp_dtw_desktop_deactivate): Ditto + (sp_desktop_widget_new): Use desktop "activate" and "deactivate" signals + instead of sodipodi ones, signature change + (sp_desktop_class_init): Added "activate" and "deactivate" signals + + * src/dialogs/display-settings.c: Removed glade, made mostly dynamic + + * src/sodipodi.c (sodipodi_remove_desktop): Emit "destroy_desktop" if + destroyed one was not active too + (sodipodi_refresh_display): Convenience method + +2002-02-08 Lauris Kaplinski + + * src/dialogs/document-properties.c: Do not use glade anymore, made + everything dynamic + + * src/helper/canvas-grid.c (sp_grid_hline): Use helpers from ctrlrect + (sp_grid_vline): Ditto + (sp_cgrid_render): Render real grid instead of dots + + * src/xml/repr-util.c (sp_repr_get_boolean): Saner conveninence method + (sp_repr_get_int): Ditto + (sp_repr_get_double): Ditto + (sp_repr_set_boolean): Ditto + (sp_repr_set_int): Ditto + (sp_repr_set_double): Ditto + + * src/svg/svg-length.c (sp_svg_read_length): Added meter + + * src/dialogs/sp-attribute-widget.c (sp_attribute_widget_changed): Kill warning + (sp_attribute_widget_set_object): Ditto + (sp_attribute_widget_object_modified): Ditto + (sp_attribute_table_set_object): Ditto + (sp_attribute_table_object_modified): Ditto + (sp_attribute_table_entry_changed): Ditto + + * src/dialogs/desktop-properties.c: Do not use glade anymore, made + everything dynamic + + * src/sp-namedview.c (sp_namedview_init): Do not init distances here, + as ::build invokes full reread anyways + (sp_namedview_read_attr): Use saner structure and read measured distances + (sp_namedview_setup_grid_item): Convert distances to points here + (sp_str_to_bool): Convenience stuff (should be moved to some central place) + (sp_nv_read_length): Ditto + (sp_nv_read_opacity): Ditto + + * src/sp-namedview.h: Use real units for distances, some cleanup + + * src/desktop-snap.c (sp_desktop_horizontal_snap): Ported to namedview + changed internals + (sp_desktop_vertical_snap): Ditto + (sp_desktop_vector_snap): Ditto + (sp_desktop_circular_snap): Ditto + +2002-02-04 Frank Felfe + + * src/sp-item.c (sp_item_distance_to_svg_bbox): Fix compilation error + +2002-02-03 Lauris Kaplinski + + * src/helper/units.c: Fix userspace/device confusion + + * src/sp-gradient.c (sp_stop_read_attr): Convert percentages to dimensionless + units + + * src/gradient-chemistry.c (sp_gradient_vector_release_references): New + method to prepare gradient vector for deletion + + * src/dialogs/gradient-vector.c (sp_gradient_vector_selector_init): Connect + button dialogs + (sp_gvs_rebuild_gui_full): Set selection to current active gradient + (sp_gvs_gradient_edit_clicked): From old gradient selector + (sp_gvs_gradient_add_clicked): Ditto + (sp_gvs_gradient_delete_clicked): Ditto + +2002-02-02 Kjartan Maraas + + * glade/object_props.glade: Fix a typo. s/Mitter/Miter/ + +2002-01-27 Lauris Kaplinski + + * src/bonobo/Makefile.am (INCLUDES): Remove excess -I + +2002-01-21 Lauris Kaplinski + + * src/sp-item.c (sp_item_distance_to_svg_viewport): New method + (sp_item_distance_to_svg_bbox): Ditto + (sp_item_style_changed): Use generic distance conversion method + + * src/helper/units.c: New file, ported from libgnomeprint, we collect + all unit management into here + + * src/helper/units.h: New file + + * src/svg/svg-length.c (sp_svg_write_percentage): New unit logic + (sp_svg_read_length): Ditto + + * src/helper/unit-menu.c: Ported widget from libgnomeprint + + * src/helper/unit-menu.h: Ported widget from libgnomeprint + + * src/dialogs/text-edit.c (sp_text_read_selection): New unit logic + + * src/dialogs/object-properties.c (sp_object_properties_apply_stroke): New + unit logic + + * src/dialogs/gradient-selector.c (sp_gradient_widget_new): Use + SPGradientVectorSelector here + + * src/style.c (sp_style_read_from_string): New unit logic + (sp_style_write_string): Ditto + (sp_style_init): Ditto + + * src/sp-text.c (sp_text_read_attr): New unit logic + + * src/sp-star.c (sp_star_read_attr): New unit logic + + * src/sp-spiral.c (sp_spiral_read_attr): New unit logic + + * src/sp-shape-style.c (sp_stroke_read): New unit logic + + * src/sp-root.c (sp_root_read_attr): New unit logic + + * src/sp-rect.c (sp_rect_read_attr): New unit logic + + * src/sp-namedview.c (sp_namedview_read_attr): New unit logic + + * src/sp-item.c (sp_item_style_changed): New unit logic + + * src/sp-image.c (sp_image_read_attr): New unit logic + + * src/sp-ellipse.c (sp_circle_read_attr): New unit logic + + * src/dyna-draw-context.c (sp_dyna_draw_context_setup): New unit logic + (fit_and_split_line): Ditto + (fit_and_split_calligraphics): Ditto + + * src/desktop-events.c (sp_dt_simple_guide_dialog): Use new unit widget + (guide_dialog_apply): Ditto + +2002-01-13 Wang Jian + + * configure.in(ALL_LINGUAS): Added zh_CN for Simplifed Chinese. + +2002-01-05 Mitsuru Oka + + * src/helper/bezier-utils.c (BEZIER_DEBUG): inhibit debug messages. + +2002-01-04 Zbigniew Chyla + + * src/desktop.c (sp_desktop_widget_init, sp_desktop_widget_set_title, + sp_desktop_widget_shutdown): Marked strings for translation. + + * src/document.c (sp_document_new, sp_document_new_from_mem): Ditto. + +2002-01-01 Zbigniew Chyla + + * configure.in: Added "AC_PROG_INTLTOOL(0.11)" line. + + * Makefile.am: Use intltool. + + * GNOME_Sodipodi.oaf.in: New, copied from GNOME_Sodipodi.oafinfo. + + * sodipodi.desktop.in: New, generated from sodipodi.desktop. + + * GNOME_Sodipodi.oafinfo, sodipodi.desktop: Removed. + + * glade/Makefile.am (glade_DATA): Removed *.c. + + * glade/*.c: Removed. + + * .cvsignore: Added intltool-*, sodipodi.desktop, GNOME_Sodipodi.oaf. + + * src/bonobo/svg-doc-factory.c, src/desktop.c, src/dialogs/align.c, + src/dialogs/display-settings.c, src/dialogs/document-properties.c, + src/dialogs/fill-style.c, src/dialogs/gradient-selector.c, + src/dialogs/gradient-vector.c, src/dialogs/item-properties.c, + src/dialogs/object-attributes.c, src/dialogs/object-properties.c, + src/help.c, src/helper/unit-menu.c, src/main.c, src/sodipodi.c, + src/sp-anchor.c, src/sp-image.c, src/sp-item-group.c, src/sp-rect.c, + src/sp-shape.c, src/sp-spiral.c, src/sp-star.c, src/sp-text.c, + src/widgets/sp-color-selector.c: Added missing #include . + +2001-12-30 Lauris Kaplinski + + * src/widgets/sp-color-selector.c (sp_color_selector_adjustment_changed): Set + updating flag here, so we get single "changed" signal whatever happens + + * src/sp-gradient.c (sp_gradient_repr_set_vector): Allow setting our + own vector too here + + * src/sp-object.h (SP_OBJECT_NEXT): New macro + + * src/gradient-chemistry.c (sp_gradient_ensure_vector_normalized): Should + work as intended now + (sp_gradient_ensure_private_normalized): Ditto + (sp_gradient_repr_set_link): Set NULL link too + +2001-12-30 Mitsuru Oka + + * src/sp-spiral.c src/sp-star.c: + Revert to previous cx, cy attribute implementation. + Because SVG standard shape introduce cx, cy, + so we coordinate to that policy. + + * src/sp-spiral.c (sp_spiral_get_polar): New function + (sp_spiral_is_invalid): New function to protect attributes + consistency. sp_spiral_read_attr use it. + +2001-12-29 Mitsuru Oka + + * src/knotholder.c src/knotholder.h + (sp_knot_holder_add_full): New method + + * src/sp-spiral.c: Removed cx, cy attribute, + so we use item matrix for that. + Fixed up debug code. + + * src/sp-star.c src/sp-star.h src/star-context.c: + Removed cx, cy attribute + +2001-12-29 Mitsuru Oka + + * src/knotholder.c (knot_moved_handler): + Lauris found a incorrect invert matrix bug. I just fixed it. + +2001-12-28 Simos Xenitellis + + * configure.in: Added "el" (Greek) to ALL_LINGUAS. + +2001-12-28 Lauris Kaplinski + + * src/sp-gradient.c: Lot of changes due to class member rearrangement + (sp_gradient_repr_flatten_attributes): New method + (sp_gradient_repr_set_vector): Ditto + + * src/sp-gradient.h: Moved gradientUnits and gradientTransform to + base SPGradient class, added ::flatten_attributes virtual method + + * src/gradient-chemistry.c (sp_gradient_ensure_vector_normalized): Works + now for lonely gradients as well + + * src/desktop-events.c (guide_dialog_apply): Flush undo + (guide_dialog_delete): Ditto + (sp_dt_guide_event): Ditto + + * src/widgets/sp-color-selector.c: Added 'rrggbbaa' hex value entry, + use SPColor helpers instead of doing conversions here, added some + generic color methods and renamed/changed signature of old ones. + + * src/widgets/sp-color-slider.c (sp_color_slider_paint): Update arrow + the right way + + * src/helper/nr-plain-stuff.c (nr_render_rgba32_rgb): Use computed channels + instead of plain color ones + + * src/helper/nr-plain-stuff-gdk.c (nr_gdk_draw_rgba32_solid): New method + + * src/text-context.c (sp_text_context_setup): Some XIM handling + (sp_text_context_destroy): Ditto + (sp_text_context_root_handler): Ditto + + * src/sp-gradient.c: Killed gcc 3 warnings + + * src/draw-context.c: Started rewriting of drawing context, added 4-member + path cache (instead of 2 in old version), the goal is to make selection + continuation and pen tool + + * src/draw-context.h: New members in class + + * src/color.c (sp_color_get_colorspace_class): Broke colorspace descriptor + into class (process | spot) and type (rgb | cmyk), added new methods and + renamed old one accordingly + (sp_color_get_colorspace_type): Ditto + (sp_color_rgb_to_hsv_floatv): Convenience method + (sp_color_hsv_to_rgb_floatv): Ditto + (sp_color_rgb_to_cmyk_floatv): Ditto + (sp_color_cmyk_to_rgb_floatv): Ditto + + * src/color.h: New convenience macros and methods + + * configure.in (have_bonobo): Made --without-bonobo default + + * src/widgets/sp-color-preview.c: New file, implement simple + color preview object, a la the one in Gtk+ color selector + + * src/widgets/sp-color-preview.h: New file + +2001-12-21 Mitsuru Oka + + * src/sp-spiral.*, spiral-context.c + (sp_spiral_inner_*, sp_spiral_outer_*, sp_spiral_knot_holder): + Add SPKnotHolder codes + (sp_spiral_set_shape, sp_spiral_fit_and_draw): + Fixed some drawing bugs + + * src/dyna-draw-context.*, sp-shape.c, sp-star.c: + Clean up codes + +2001-12-15 Lauris Kaplinski + + * src/helper/canvas-bpath.h: New file + + * src/helper/canvas-bpath.c: New file + + * src/helper/Makefile.am (libspchelp_a_SOURCES): Added + canvas-bpath.[c,h] + + * src/helper/curve.c (sp_curve_ref): Signature change + (sp_curve_unref): Ditto + + * src/display/Makefile.am (nr_sources): Removed stale files + + * src/helper/bezier-utils.c (sp_bezier_fit_cubic): Added argument + checks, signature change, cleanup + (sp_bezier_fit_cubic_r): Ditto + (sp_bezier_fit_cubic_full): Ditto + + * src/helper/bezier-utils.h: Changed fit method signatures + + * src/draw-context.c (fit_and_split): Use new sp_bezier_fit signature + + * src/dyna-draw-context.c (fit_and_split_line): Use new sp_bezier_fit + signature + (fit_and_split_caligraphics): Ditto + +2001-12-07 Lauris Kaplinski + + * src/sodipodi.c (sodipodi_application_new): Catch SIGFPE and SIGILL as well + + * src/sp-gradient.c (sp_gradient_write_colors): Skip, if integer stop + values coincide (fixes div 0 bug with gradients) + +2001-11-25 Duarte Loreto + + * Added Alvaro Lopes portuguese translation to configure.in (ALL_LINGUAS) + +01-11-19 Lauris Kaplinski + + * src/preferences-skeleton.h: Removed '%' from opacity + +2001-11-12 Lauris Kaplinski + + * src/display/canvas-arena.c (sp_canvas_arena_render): Try to fit + buffer, instead of just using 64x64 rectangles + + * src/sp-rect.c: Remove Gtk+ arguments + + * src/display/nr-arena-image.c (nr_arena_image_update): Request + rendering previous area + +2001-11-11 Lauris Kaplinski + + * src/sp-rect.c (sp_rect_write_transform): Scale rx and ry + (sp_rect_menu): Implement + (sp_rect_rect_properties): Implement + + * src/dialogs/object-properties.c (sp_object_properties_apply_fill): Use + float value, not percentage + (sp_object_properties_apply_stroke): Ditto + + * src/file.c (file_save_ok): Update relative image references + + * src/sp-image.c (sp_image_destroy): Unregister resource + (sp_image_build): Register resource + + * src/sp-spiral.c (sp_spiral_menu): Implement + (sp_spiral_spiral_properties): Generic attributes dialog + +2001-11-10 Lauris Kaplinski + + * src/sp-anchor.c (sp_anchor_menu): New method + (sp_anchor_link_properties): Ditto + (sp_anchor_link_follow): Ditto + (sp_anchor_link_remove): Ditto + + * src/sp-star.c (sp_star_menu): New method + (sp_star_star_properties): Ditto + + * src/sp-item.c (sp_item_create_link): New method + + * src/sp-item-group.c (sp_item_group_ungroup): Ungroup anchors too + + * src/forward.h: Added SPAnchor + + * src/dialogs/sp-attribute-widget.h: New file, implement generic + asynchronous attribute widget, and table of attribute widgets + + * src/dialogs/sp-attribute-widget.c: New file + + * src/dialogs/object-attributes.h: New file, implement generic + asynchronous object attribute dialog + + * src/dialogs/object-attributes.c: New file + + * src/display/Makefile.am (INCLUDES): Added SODIPODI_CFLAGS + + * src/sp-anchor.c: New file, implement SVG element. Actual event + code is pure experimental and need some serious thinking. + + * src/sp-anchor.h: Ditto + + * src/svg-view.c (arena_handler): Forward arena events to SPEvents + + * src/sp-object-repr.c (sp_object_type_lookup): parse as anchor + + * src/sp-item.h: Added ::event virtual method plus some test code + + * src/sp-item.c (sp_item_event): New method + + * src/desktop.c (sp_desktop_new): Moved drawing behind all other layers + (sp_desktop_document_resized): Resize page frame + + * src/helper/sodipodi-ctrlrect.h: More complex structure to represent + page frame as well + + * src/helper/sodipodi-ctrlrect.c (sp_ctrlrect_hline): New render method + (sp_ctrlrect_vline): Ditto + (sp_ctrlrect_area): Ditto + (sp_ctrlrect_render): Use more complex structure + (sp_ctrlrect_update): Ditto + (sp_ctrlrect_set_area): New method + (sp_ctrlrect_set_color): Ditto + (sp_ctrlrect_set_shadow): Ditto + +2001-11-09 Lauris Kaplinski + + * src/display/nr-arena-image.c (nr_arena_image_update): Implemented + explicit geometry + (nr_arena_image_set_geometry): New method + + * src/sp-image.c: Implemented "x", "y", "width", "height" + (sp_image_read_attr): Ditto + (sp_image_bbox): Ditto + (sp_image_print): Ditto + (sp_image_show): Ditto + (sp_image_write_transform): Implement + + * src/file.c (file_import_ok): Try to load pixbuf and set + "width" and "height" attributes + + * src/desktop.c: Some cleanups of View/Widget structure + + * src/desktop.h: Ditto + + * glade/Makefile.am (images): Added about.svg + +2001-11-08 Lauris Kaplinski + + * src/svg/svg-affine.c (sp_svg_write_affine): Write scale and + translate, if everything can be represented by these + + * src/sp-text.c (sp_text_write_transform): Implement + + * src/sp-rect.c (sp_rect_write_transform): Implement + + * src/sp-item.c (sp_item_write_transform): New class and virtual + method pair, to allow object to optimize representation (i.e. + rects can set x,y,width,height instead of just transformation + + * src/seltrans.c (sp_sel_trans_ungrab): Use sp_item_write_transform + + * src/selection-chemistry.c: Use sp_item_write_transform + + * src/help.c (sp_help_about): Set title string to "Sodipodi VERSION" + + * src/Makefile.am (INCLUDES): Define SODIPODI_VERSION + + * src/xml/repr-io.c (repr_write): Avoid newlines in content + + * src/view.c: Sorted out lot os signalling stuff + + * src/svg-view.c: Lot of work, basically works + + * src/sp-root.c (sp_root_modified): Call parent method as well + + * src/interface.c (sp_ui_new_view_preview): New method + (sp_create_window): Sort out editable/non-editable views + + * src/help.c (sp_help_about): Create about maunally (not much here yet) + + * src/desktop.c: Use ::document_resized virtual method + +2001-10-31 Lauris Kaplinski + + * src/dialogs/text-edit.c (sp_text_read_selection): Use gal + utf8/editable methods + (sp_text_dialog_apply): Ditto + (sp_text_dialog_text_changed): Ditto + + * src/sp-text.c (sp_text_set_shape): Use correct utf8 methods + + * src/display/nr-arena-image.c (nr_arena_image_class_init): Use + correct parent class + +2001-10-31 Mitsuru Oka + + * src/knotholder.c: + Removed unnecessary ref/unref. + Added sp_object_invoke_write_repr() to reflect item changes to repr + + * src/sp-object.c: Added new virtual function SPObject::write_repr() + + * src/sp-object.h: Ditto + + * src/sp-shape.c (sp_shape_write_repr): Added + + * src/sp-star.c (sp_star_write_repr): Added. + Moved subclass of SPShape to SPPolygon + + * src/star-context.c: Ditto + +2001-10-30 Mitsuru Oka + + * src/knotholder.c: New file + We can manage plural SPKnot in one SPKnotHolder. + SPKnotHolder is created by SPItem::knot_holder virtual function. + Moving SPKnot is propageted to another SPKnot. + * src/knotholder.h: Ditto + + * src/node-context.c: Added SPKnotHolder + * src/node-context.h: Ditto + + * src/sp-item.c: Added knot_holder virtual function. + * src/sp-item.h: Ditto + + * src/sp-shape.c: Added set_shape virtual function. + It is used to build bpath from extra shape attributes. + + * src/sp-shape.h: Ditto + + * src/sp-star.c: Added knot_holder and set_shape implementations. + (sp_star_build_repr): Modified function name. + * src/sp-star.h: Ditto + + * src/sp-spiral.c: Added set_shape implementation. + (sp_spiral_build_repr): Modified function name. + * src/sp-spiral.h: Ditto + + * src/star-context.c: Modified build_repr function name. + * src/spiral-context.c: Ditto + +2001-10-29 Lauris Kaplinski + + * src/desktop.c (sp_desktop_coordinate_status): Free allocated memory + + * src/display/nr-arena-shape.c (nr_arena_shape_group_add_component): Unref + item once it is added + +2001-10-29 Mitsuru Oka + + * src/desktop.c: + Added gtk_object_unref() after *_add_child to fix memory leaks. + + * src/document: Ditto + + * src/selection-chemistry.c: Ditto + + * src/sp-item-group.c: Ditto + + * src/sp-clippath.c, src/sp-use.c: Ditto + Missing to add ChangeLog before commiting. + +2001-10-23 Mitsuru Oka + + * src/sp-star.*, src/sp-spiral.*, src/star-context.* and + spiral-context.*: + Add SPStar, SPStarContext, SPSpiral and SPSpiralContext classes. + SPStar and SPSpiral behave as new shape and they can convert to + bezier curves. More works are required. + + * glade/draw_star.xpm, glade/draw_spiral.xpm, src/pixmaps/cursor-star.xpm, + src/pixmaps/cursor-spiral.xpm: + Add toolbox icon and mouse cursor for star and spiral. + + * src/helper/bezier-utils.*: + Add lowlevel APIs and reformat source code. + + * src/xml/repr-io.c: + Fix repr_write() to generate more short SVG. + New code support tags generation. + + * src/xml/repr-util.c, src/xml/repr.*, src/sodipodi.c: + Add new SPRepr APIs sp_repr_lookup_child(), sp_repr_overwrite (), + and sp_repr_document_overwrite () + Now, we can merge ~/.sodipodi/preferences into preferences_skeleton. + +2001-10-23 Lauris Kaplinski + + * src/file.c (sp_file_new): Use new signatures + (file_open_ok): Ditto + + * src/interface.c (sp_create_window): New signature + + * src/desktop.c: Break desktop functionality into SPView/SPViewWidget + parts, wrap most of the old code in ugly way, but we can go on + cleaning it up method-by-method + + * src/desktop.h: Ditto + + * src/view.h: New file + + * src/view.c: New file, we implement abstract base classes for + all document views (editable, noneditable, widget, non-widget) + here + + * src/svg-view.h: New file + + * src/svg-view.c: New file, implementing SVG preview + + * src/marshal.h: New file + + * src/marshal.c: New file + +2001-10-20 Lauris Kaplinski + + * src/sp-root.c (sp_root_read_attr): Removed desktop->document coordinate + setup from here - it has to be done in desktop instead + +2001-10-19 Frank Felfe + + * src/widgets/sp-toolbox.*: patch from MenTaLguY + change seperate button into toggle button and add arrow to + hide button indicating state of toolbox + + * src/path-chemistry.c (sp_selected_path_to_curves): apply to all paths in selection + + * src/selection-chemistry.c (sp_selection_delete): remove widget text + + * src/desktop.c (sp_desktop_set_focus): make canvas catch key events + + * src/desktop-events.c (sp_desktop_root_handler): don't grab focus here + +2001-10-18 Lauris Kaplinski + + * src/display/nr-arena-image.c (nr_arena_image_render): Use right + pixel coposers + + * configure.in: Version 0.25 + +2001-10-18 Lauris Kaplinski + + * src/sp-item-group.c: Removed paint virtual method implementation + + * src/sp-image.c: Ditto + + * src/sp-shape.c: Ditto + + * src/sp-use.c: Ditto + + * src/sp-item.c (sp_item_paint): Ported to NRArena/::show() + + * src/sp-item.h: Removed ::paint() + + * samples: Removed extra sample files (these are in clipart distribution) + +2001-10-17 Lauris Kaplinski + + * src/display/nr-arena*: Merged NR_ARENA branch into HEAD. + NRArena is new experimental display list engine, that replaces + most canvas stuff for SVG items (old canvas code is still + used for controls etc.). + It is less integrated with Gtk widgetry, and should also allow reuse + of code for paint-server type things (patterns, symbols etc.). + NRArena rendering also allows higher-level graphic stuff, from + masking to filters, to be implemented. + +2001-10-13 Mitsuru Oka + + * src/dynadraw-context.c: Removed rotating brush bug + + * src/draw-context.h: Removed duplicate bezier-fitting code + +2001-10-12 Lauris Kaplinski + + * src/sp-clippath.c: New file + + * src/sp-clippath.h: New file + + * src/sp-object-group.c (sp_objectgroup_build): Check child type + (sp_objectgroup_child_added): Ditto + + * src/sp-object-group.h: Removed useless 'tranparent' member + +2001-10-07 Lauris Kaplinski + + * src/display/nr-primitives.c (nr_irect_union): New method + + * src/helper/nr-buffers.h: New file + + * src/helper/nr-buffers.c: New file + + * src/helper/nr-plain-stuff.c (nr_render_rgba32_rgba32): New method + +2001-10-06 Lauris Kaplinski + + * src/sp-item.c (sp_item_read_attr): Query presentation attributes + + * src/style.c (sp_style_read_from_object): Added some presentation attributes + +2001-10-05 Lauris Kaplinski + + * src/sp-use.c (sp_use_build): Reinclude, change 'href' to 'xlink:href' + + * src/sp-object.c (sp_object_style_changed): Use SP_OBJECT_MODIFIED_FLAG + + * src/document.c (sp_document_new): Force "height" and "width" attributes, + if not present already + (sp_document_new_from_mem): Ditto + +2001-10-04 Lauris Kaplinski + + * src/xml/repr-io.c (sp_repr_save_stream): Correct header + +2001-10-02 Peter Moulder + + * src/xml/repr-io.c (repr_quote_write): New method, quotes + special chars correctly for xml + (repr_write): Use repr_quote_write + +2001-10-02 Lauris Kaplinski + + * src/dyna-draw-context.c: Stroking by Mitsuru Oka + + * src/helper/bezier-utils.h: New file by Motsuru oka + + * src/helper/bezier-utils.c: Ditto + + * src/sp-shape.c (sp_shape_print): Translate gradients the right way + +2001-10-01 Lauris Kaplinski + + * src/sp-shape.c (sp_shape_print): Use rule for clip and fill + (sp_shape_paint): Use winding rule + +2001-09-30 Lauris Kaplinski + + * src/style.c (sp_style_write_string): Write rule + (sp_style_read_from_string): Parse rule + + * src/style.h: Made rule libart enum + + * src/display/path-archetype.c (sp_path_at): Search by rule + (sp_path_at_new): Rewind with rule + (sp_pat_equal): Compare rules + + * src/display/path-archetype.h: Added rule argument + + * src/display/cpath-component.c (sp_cpath_comp_new): Init rule + (sp_cpath_comp_update): Use rule + (sp_cpath_comp_change): Ditto + + * src/display/cpath-component.h: Added rule member + + * src/display/canvas-shape.c (sp_canvas_shape_update): Set fill rule + +2001-09-29 Lauris Kaplinski + + * src/selection-chemistry.c (sp_selection_lower_to_bottom): Do not lower + behind non-items (i.e. base object) + (sp_selection_lower): Ditto + + * configure.in: Version 0.24.1 + + * src/document.c (sp_document_new): Set xmlns:xlink + (sp_document_new_from_mem): Ditto + + * src/sp-defs.c (sp_defs_destroy): Correct list emptying + + * src/dialogs/gradient-selector.c (sp_gradient_selector_add_vector_clicked): unref repr + + * src/gradient-chemistry.c (sp_object_ensure_fill_gradient_normalized): unref repr + + * src/helper/art-utils.c (art_rgb_run_rgba): Fix 255/256 bug + + * src/display/canvas-shape.c (sp_canvas_shape_render): Removed #ifdef 0 code + + * src/widgets/gradient-image.c (sp_gradient_image_expose): Draw grabage + using fresh new nr functions + (sp_gradient_image_update): Ditto (not used) + + * src/helper/nr-plain-stuff.h: New file + + * src/helper/nr-plain-stuff.c: New file + + * src/helper/nr-plain-stuff-gdk.h: New file + + * src/helper/nr-plain-stuff-gdk.c: New file + +2001-09-27 Lauris Kaplinski + + * src/dialogs/object-properties.c (sp_object_properties_dialog): Create + dynamic fill page + + * src/sp-shape.c (sp_shape_print): Print gradients (somewhat) + (sp_shape_paint): Paint gradients (somewhat) + + * src/document.c (sp_document_new_from_mem): Use fresh namespace + + * src/xml/repr-io.c (sp_repr_save_stream): Write fresher descriptor + + * src/widgets/gradient-position.c: New file and widget + + * src/widgets/gradient-position.h: New file and widget + + * src/dialogs/gradient-selector.c (sp_gradient_widget_new): Make + delete vector inactive, shorter button names, create gradient + positioning widget + (sp_gradient_selector_load_selection): Update positioning widget + (sp_gradient_selection_position_dragged): Implement + (sp_gradient_selection_position_changed): Implement + + * src/sodipodi.c (sodipodi_segv_handler): Abort on recursion + +2001-09-26 Lauris Kaplinski + + * src/sp-text.c (sp_text_read_attr): Use unit-loading method for x & y + +2001-09-25 Christopher R. Gabriel + + * sodipodi.1.in: new man page + * configure.in: Likewise + * Makefile.am (man_MANS): Likewise + +2001-09-24 Frank Felfe + + * src/helper/sodipodi-ctrl.*: New ctrl-shapes + + * src/knot.*: Ditto + + * src/pixmaps/cursor-node-d.xpm: New file + + * src/pixmaps/cursor-node-m.xpm: New file + + * src/pixmaps/cursor-select-d.xpm: New file + + * src/pixmaps/cursor-select-m.xpm: New file + + * src/pixmaps/handles.xpm: New file + + * src/sp-cursor.* (sp_cursor_new_from_xpm): New function + + * src/seltrans.c: Use new ctrl-shapes and cursors + + * src/seltrans-handles.*: Use new ctrl-shapes + + * src/select-context.c (sp_node_context_class_init): Init cursors and handle pix + + * src/nodepath.* (node_event): Redirect key events + (node_key): New key handler + (sp_node_selected_break): Handle first and last node + (node_ctrl_moved): Update ctrlline after setting coords + (sp_nodepath_node_new): Use new ctrl-shapes and cursors + + * src/node-context.c (sp_node_context_class_init): Init cursors + +2001-09-22 Mitsuru Oka + + * src/dynadraw-context.c: New file + + * src/dynadraw-context.h: New file + + * src/event-context.c (sp_event_context_set_dynahand): New handler + +2001-09-21 Lauris Kaplinski + + * src/svg/svg-path.c: Quick port of latest librsvg path code + +2001-09-19 Lauris Kaplinski + + * src/document.c (sp_document_destroy): Remove document + (sp_document_new): Add document + (sp_document_new_from_mem): Ditto + + * src/sodipodi.c (sodpodi_remove_document): New method + (sodpodi_add_document): Ditto + (sodipodi_segv_handler): Not very intelligent signal handler + +2001-09-18 Lauris Kaplinski + + * src/dialogs/gradient-selector.c (sp_gradient_selector_add_vector_clicked): + New handler + (sp_gradient_selector_delete_vector_clicked): Ditto (empty) + (sp_gradient_selector_load_selection): New method + + * src/desktop.c (sp_desktop_init): Typo fix + +2001-09-17 Lauris Kaplinski + + * src/dialogs/gradient-vector.c (sp_gradient_vector_widget_destroy): Handler + (sp_gradient_vector_gradient_destroy): Ditto + (sp_gradient_vector_gradient_modified): Ditto + (sp_gradient_vector_color_dragged): Ditto + (sp_gradient_vector_color_changed): Ditto + (sp_gradient_vector_widget_load_gradient): Connect/disconnect signals, + handle NULL gradient etc. + + * src/sp-gradient.c (sp_gradient_set_vector): New method + + * src/widgets/gradient-image.c (sp_gradient_image_update): New method + (sp_gradient_image_gradient_modified): Handler + (sp_gradient_image_gradient_destroy): Ditto + (sp_gradient_image_set_gradient): New method + (sp_gradient_image_unrealize): Implement + (sp_gradient_image_realize): Ditto + +2001-09-16 Lauris Kaplinski + + * src/dialogs/gradient-selector.c (sp_gradient_widget_new): Added buttons + (sp_gradient_selector_edit_vector_clicked): Handler + + * src/sp-defs.c (sp_defs_build): Use attach method + +2001-09-15 Lauris Kaplinski + + * src/sp-gradient.c: Added radial gradient + + * src/sp-gradient.h: Ditto + + * src/sp-paint-server.c (sp_paint_server_destroy): Do not leak painters + + * src/gradient-chemistry.c (sp_gradient_ensure_vector_normalized): New method + (sp_item_force_fill_lineargradient_vector): Ditto + + * src/sp-object.h (SP_OBJECT_STYLE): New macro + +2001-09-14 Lauris Kaplinski + + * src/zoom-context.c (sp_zoom_2_to_1): Noop if no active desktop + (sp_zoom_1_to_2): Ditto + +2001-09-07 Lauris Kaplinski + + * src/sp-header.c: New file, implements document header, consisting + of nested nodes, for different resource definitions + + * src/sp-header.h: New file + + * src/forward.h: Added SPHeader forward typedefs + +2001-09-05 Lauris Kaplinski + + * src/document.c (sp_document_del_repr): Moved here, commented out + (sp_document_add_repr): Moved here, made non-item compatible + + * src/style.c (sp_style_object_destroyed): Catcher method + (sp_style_new): Signature change + (sp_style_ref): Ditto + (sp_style_unref): Ditto + + * src/sp-paint-server.c (sp_paint_server_destroy): Removed insane + paint server referencing by painters and replaced it witw (a bit) + less insane stale painter maintenance + (sp_paint_server_painter_new): Ditto + (sp_paint_server_painter_free): Ditto + (sp_painter_free): Ditto + (sp_painter_stale_fill): Ditto + + * src/sp-object.c (sp_object_invoke_build): Added verbose error + + * src/style.c (sp_style_paint_server_destroy): Implemented signal-based + paintserver spying, instead of hardrefing it + (sp_style_paint_server_changed): Ditto + (sp_style_merge_paint): Ditto + + * src/sp-object.c (sp_object_ref): Wrapper method for debugging + (sp_object_unref): Ditto + (sp_object_attach_reref): Convenience connect method + (sp_object_detach_unref): Ditto + +2001-09-04 Lauris Kaplinski + + * src/sp-shape.c (sp_shape_print): Do not fill open paths + + * src/document.c (sp_document_add_resource): Implemented simple + named resource lists + (sp_document_remove_resource): Ditto + (sp_document_get_resource_list): Ditto + +2001-09-03 Lauris Kaplinski + + * src/sp-gradient.c: Added middle SPGradient class and morphed + LinearGradient accordingly + + * src/sp-gradient.h: Added middle SPGradient Class + + * src/forward.h: Declare stops and gradients here + + * src/dialogs/gradient-vector.c: New file + + * src/dialogs/gradient-vector.h: New file + + * src/bonobo/embeddable-document.c (sp_embeddable_document_ps_save): + Kill warning + + * src/select-context.c: Kill warning + +2001-08-31 Lauris Kaplinski + + * src/forward.h: typedef SPDefs[Class] here + + * src/sp-root.h: Added pointer to root-level node + + * src/sp-gradient.c (sp_stop_get_type): Fixed type on type init + +2001-08-30 Lauris Kaplinski + + * src/document.c (sp_document_new): Use fill-opacity 0.5, not 50% + +2001-08-21 Lauris Kaplinski + + * src/dialogs/fill-style.c: Implement CMYK/RGB colorspace switching + + * src/widgets/sp-color-selector.c: Implement CMYK read/set methods + + * src/widgets/sp-color-slider.c (sp_color_slider_adjustment_value_changed): Set + local value, even if arrow is not visible + + * src/color.c: New file + + * src/color.h: New file + + * src/sp-item.c (sp_item_read_attr): Check for "fill-cmyk" + + * src/style.c (sp_style_read_from_object): Parse "fill-cmyk" (quick hack) + +2001-08-20 Lauris Kaplinski + + * src/svg/svg-path.c (svg_parse_path_data): Kill warning + + * src/widgets/sp-color-selector.c: New file & class + + * src/widgets/sp-color-slider.c: New file & class + + * src/sp-object.c (sp_object_style_changed): New virtual method + +2001-08-13 Lauris Kaplinski + + * src/selection-chemistry.c (sp_selection_copy): Use prepend/reverse + (sp_item_compare_order): New method + (sp_item_list_sort_by_visual_order): New method + + * src/sp-path.c (sp_path_read_attr): Req modification + + * src/sp-item.c (sp_item_toggle_sensitivity): Call document::done + (sp_item_reset_transformation): Ditto + (sp_item_read_attr): Request modifiaction for style change + + * src/sp-object.h (SP_OBJECT_PARENT): Added convenience macros + +2001-08-01 Lauris Kaplinski + + * src/document-undo.c (sp_document_undo): Fresh logic + (sp_document_redo): Ditto + (sp_document_child_added): Real listener + (sp_document_child_removed): Ditto + (sp_document_attr_changed): Ditto + (sp_document_content_changed): Ditto + (sp_document_order_changed): Ditto + (sp_document_add_repr): Fresh logic, use only as wrapper + (sp_document_del_repr): Ditto + (sp_document_clear_undo): Use new logic, free actions at last + (sp_document_clear_redo): Ditto + (sp_action_list_undo): New functions, plus handful children + (sp_action_list_redo): Ditto + (sp_action_new): New function + (sp_action_free): Ditto + (sp_action_free_list): Ditto + +2001-07-31 Lauris Kaplinski + + * src/xml/repr.c (sp_repr_ref): Return referenced repr + (sp_repr_unref): Ditto + (sp_repr_duplicate): Cleanup + (sp_repr_set_content): Ditto, new handler signatures + + * src/xml/repr-private.h: Lot of signature changes + +2001-07-30 Lauris Kaplinski + + * src/sp-item-group.c: #include for i18n + + * src/sp-item.c: Ditto + + * src/event-context.c: Ditto + + * src/toolbox.c: Ditto + +2001-07-25 Lauris Kaplinski + + * src/document-undo.c (sp_document_maybe_done): New function + +2001-07-19 Lauris Kaplinski + + * src/dialogs/sp-widget.c (sp_widget_modify_selection): New function + (sp_widget_show): Connect "modify_selection" + (sp_widget_hide): Disconnect by data + (sp_widget_new): New function + (sp_widget_class_init): Added signals + (sp_widget_change_selection): Emit signal + (sp_widget_set_selection): Ditto + + * src/sodipodi.c (sodipodi_selection_modified): New function + (sodipodi_class_init): Added "modify_selection" signal + + * src/selection.c (sp_selection_idle_handler): Signal sodipodi + + * src/document.c (sp_document_class_init): Added "modified" signal + (sp_document_idle_handler): Emit modified signal + + * src/seltrans.c (sp_sel_trans_sel_modified): New function + + * src/sp-item.c (sp_item_set_item_transform): New function + + * src/sp-object.c (sp_object_class_init): Add "modified" signal + (sp_object_request_modified): New function + (sp_object_modified): New base method + + * src/sp-object.h (SP_OBJECT_UNSET_FLAGS): Added modifiaction state flags + and handlers for scheduling and emitting modifiaction signal + + * src/selection.c (sp_selection_class_init): Added "modified" signal + (sp_selection_destroy): Remove pending idle, if present + (sp_selection_selected_item_modified): Added handler for object signal + (sp_selection_idle_handler): Emit our own modified signal in idle loop + + * src/selection.h: Added idle id and ::modified virtual member + +2001-07-17 Lauris Kaplinski + + * src/sp-namedview.c (sp_namedview_get_name): Initialize exception + + * src/sp-item-group.c (sp_item_group_ungroup_activate): New function + (sp_item_group_ungroup): Implement this + + * src/sp-item.c (sp_item_select_this): New function + (sp_item_private_menu): Added "Select this" + (sp_item_properties): Select item + + * src/desktop.c (sp_desktop_menu_popup): Use new signature + + * src/event-context.c (sp_event_root_menu_popup): Use desktop + in signature instead of widget + + * src/sp-object.c (sp_object_getAttribute): Return NULL, if + exception is not clear + (sp_object_setAttribute): Ditto + (sp_object_removeAttribute): Ditto + +2001-07-08 Lauris Kaplinski + + * src/xml/repr-io.c (sp_repr_svg_read_node): Preserve namespaces for + everything but "svg" + +2001-07-07 F.J.Franklin + + * src/svg/svg-color.c (sp_svg_read_color): Accept ';' as + terminator + + * src/sp_image.c (sp_image_repr_read_dataURI): New function + (sp_image_repr_read_b64): New function + (sp_image_read_attr): Accept embedded data + + * configure.in: Added --with-libwmf switch + + * src/xml/repr-io.c (sp_repr_read_file): Read *.wmf using libwmf + (sp_wmf_convert): New function + (sp_wmf_image_name): New function + +2001-07-07 Frank Felfe + + * src/desktop.h: Added number field + + * src/desktop.c (sp_desktop_new): Initialize number from + namedview viewcount + (sp_desktop_set_title): Compose name from uri, nameview and number + + * src/document.c (sp_document_set_uri): New method + + * src/file.c (file_save_ok): Set ducument uri + + * src/interface.c (sp_create_window): Set desktop title + + * src/select-context.c (sp_select_context_root_handler): Added + backward cycling + + * src/selection-chemistry.c (sp_selection_item_next): Cleared + list mess + (sp_selection_item_prev): New function + + * src/sp-item-group.c (sp_item_group_item_list): New function + + * src/sp-namedview.h: Added viewcount field + + * src/sp-namedview.c (sp_namedview_get_name): New method + + * doc/keybindings.txt: Added Shift-Tab + +2001-06-07 Lauris Kaplinski + + * configure.in: Version 0.24 + + * src/sp-item.c (sp_item_read_attr): Quick noscale hack + for style stroke widths + + * src/display/canvas-shape.c (sp_canvas_shape_update): Use + stroke_width as well ;) + +2001-05-24 Lauris Kaplinski + + * src/seltrans-handles.*: Make structs const + + * src/seltrans.*: Make view type variable, move it to + header for adding GUI later + +2001-05-23 Frank Felfe + + * src/desktop-snap.*: Implement circualr and list snapping + + * src/sp-item.*: New virtual function ::snappoints() + + * src/seltrans.c: New structure + + * src/sp-rect.c (sp_rect_snappointss): Implement + + * src/sp-ellipse.c (sp_ellipse_snappoints): Ditto + + * src/sp-text.c (sp_text_snappoints): Ditto + + * src/sp-image.c (sp_image_snappoints): Ditto + +2001-05-18 Lauris Kaplinski + + * configure.in: Version 0.23 final + + * src/sp-gradient.c (sp_lg_fill): Do opacity + + * src/document-undo.c (sp_document_redo): Fixed bug in redoing + order changes + +2001-05-17 Lauris Kaplinski + + * src/toolbox.c (sp_maintoolbox_create): Show toolbox, if + it already exists and reference sodipodi + (sp_maintoolbox_close): Hide toolbox + + * glade/Makefile.am (glade_DATA): Added item.glade, item.c + + * configure.in: Version 0.23 + + * src/dialogs/display-settings.h: New file + + * glade/Makefile.am (glade_DATA): Added display.glade, display.c + +2001-05-06 Lauris Kaplinski + + * configure.in (use_arena): Added with-arena flag + + * acconfig.h: Added ARENA + +2001-04-16 Jesus Bravo Alvarez + + * configure.in: Added gl (Galician) to ALL_LINGUAS + +2001-04-14 Lauris Kaplinski + + * everywhere (TM): Changed the basic structure of Reprs (they are + not GtkObjects any more) and SPObjects (they have own list sequence + instead of using GLists) + +2001-04-06 Lauris Kaplinski + + * src/sp-item-group.c (sp_item_group_ungroup): New method + + * src/draw-context.c (set_to_accumulated): Transform path instead of + setting initial transform, so clear transform does not do interesting + things for freehand curves ;-) + +2001-04-04 Lauris Kaplinski + + * src/file.c (sp_file_open): Do not connect "delete_event" + (sp_file_save_as): Ditto + (sp_file_import): Ditto, do not use static widget pointer + (sp_file_export): Ditto + (sp_file_save_document): Clear "modified" attribute + (file_save_ok): Ditto + + * src/svg/svg.h: #include glib.h instead of full gtk.h + + * src/svg/svg-stroke.c: #include string.h, kill warning + + * src/svg/svg-font.c: Ditto + + * src/sp-shape-style.c: Ditto + + * src/sp-metrics.h: #include gtkruler.h intead of full gtk.h + + * src/zoom-context.c (sp_zoom_page): Get document from desktop + instead of using ACTIVE_DOCUMENT + + * src/slide-context.c: New file, implement slideshow context + + * src/main.c (main): Create slideshow, if requested + +2001-03-22 Lauris Kaplinski + + * src/svg/Makefile.am (INCLUDES): Add SODIPODI_CFLAGS + +2001-03-21 Lauris Kaplinski + + * src/sodipodi.h: Remove Sodipodi typedef + + * src/forward.h: Typedef Sodipodi here + + * src/dialogs/sp-widget.c: New file + + * src/dialogs/sp-widget.h: New file, implement abstract base class for + configuration widgets + + * glade/Makefile.am (pixmaps): Added guide_dialog.png + + * src/dialogs/document-properties.c (sp_document_dialog_delete): New function, or + we crash if user closes dialog + + * src/dialogs/desktop-properties.c (sp_desktop_dialog_delete): New function, or + we crash if user closes window + + * src/draw-context.c (sp_draw_context_root_handler): Do not crash for zero + length lines PLEEAAAASSSSEEEEE! + + * src/selection-chemistry.c (sp_selection_group): Use copy/del/add to make + undo system happy + +2001-03-20 Frank Felfe + + * src/nodepath.c (node_ctrl_moved) : set coorinate status + + * src/seltrans.c (sp_sel_trans_handle_new_event) : set coordinate status + + * src/sp-guide.* : new functions sp_guide_set, sp_guide_remove + + * src/helper/unit-menu.h : add abbreviation string into unitdesc + + * src/event-context.c (set_event_location) : set coordinate status + popup desktop-properties on double click + + * src/desktop.* : new functions for statusbars + (sp_desktop_indicator_*) : make indicator only show when decorations are visible + + * src/desktop-events.* : new guideline dialog + small changes in sp_dt_ruler_event, sp_dt_guide_event + + * src/*_context.c (sp_*_context_root_handler) : make desktop->acetate + grab mouse events during drawing + + * glade/guide_dialog.png: New file + +2001-03-20 Lauris Kaplinski + + * src/sp-item-group.c (sp_group_menu): Add "Ungroup" item (does nothing at moment) + + * src/display/canvas-bgroup.c (sp_canvas_bgroup_point): Test sensitivity and stickyness + (sp_canvas_bgroup_set_sensitive): New function + + * src/display/canvas-shape.c (sp_canvas_shape_point): Test sensitivity and stickyness + (sp_canvas_shape_set_sensitive): New function + + * src/sp-item-group.c (sp_group_read_attr): Read "insensitive" too + + * src/sp-shape.c (sp_shape_read_attr): Read "insensitive" too + + * src/sp-item.c (sp_item_private_menu): Set menuitem label depending on sensibility + + * src/desktop.c (sp_desktop_init): Bind "event" to manipulate sticky state + + * src/display/canvas-image.c (sp_canvas_image_point): Check for + SP_CANVAS_STICKY_FLAG + + * src/desktop.c (sp_desktop_event): New function, Set SP_CANVAS_STICKY_FLAG if + user holds Shift key + +2001-03-09 Lauris Kaplinski + + * glade/Makefile.am (pixmaps): Added all pixmaps to dist + + * configure.in: Version 0.22 + +2001-03-09 Frank Felfe + + * src/desktop.c (sp_desktop_update_scrollbars): Cleanup + + * src/event-context.c (sp_event_context_private_root_handler): Use + Gdk keysyms instead of numeric values. Add moving/panning keybindings, + space for root menu popup + (sp_event_root_menu_popup): Pop menu on space + + * select-context.c (sp_select_context_root_handler): Use Gdk keysyms + instead of numeric values + + * selection-chemistry.c (sp_selection_move_screen): New function + (sp_selection_item_next): New function + + * doc/keybingings.txt: New keybingings + +2001-03-09 Lauris Kaplinski + + * src/nodepath.c (node_event): Update repr after deletion + + * src/file.c (file_open_ok): Destroy widget instead of hiding + (file_open_cancel): New function + (sp_file_open): Connect new cancel handler + (file_save_ok): Exit from private main loop + (file_save_cancel): New function + (sp_file_save_as): Connect new cancel handler, enter private loop + (file_import_cancel): New function + (sp_file_import): Connect new cancel handler + (file_export_cancel): New function + (sp_file_export): Connect new cancel handler + +2001-03-08 Lauris Kaplinski + + * src/interface.c (sp_ui_delete): New function presenting close + dialog box if needed + (sp_ui_close_view): Use sp_ui_delete () + (sp_create_window): Connect "delete_event" and set window title + + * src/file.c (sp_file_save_document): New function + + * src/document-undo.c (sp_document_done): Set "modified" attribute + + * src/file.c (file_save_ok): Clear "modified" attribute + +2001-03-07 Lauris Kaplinski + + * doc/keybindings.txt: Register node editing keystrokes + + * src/desktop.c (sp_desktop_new): Do not grab focus here + + * src/helper/sodipodi-ctrl.c: Added shape argument type + (sp_ctrl_class_init): Ditto + (sp_ctrl_init): Ditto + (sp_ctrl_set_arg): Ditto + (sp_ctrl_update): New logic, keep node absolute size always odd number + (sp_ctrl_point): Ditto + (draw_line): New function + (draw_point): New function + (sp_ctrl_render): New logic, draw diamond shape + + * src/desktop-events.c (sp_desktop_root_handler): Grab focus on + acetate enter notify + + * src/knot.c (sp_knot_set_arg): Set shape attribute + (sp_knot_handler): Grab focus on enter notify + (sp_knot_update_ctrl): Set shape + (sp_knot_set_ctrl_state): New function + + * src/node-context.c (sp_node_context_root_handler): Process keypresses + + * src/nodepath.c (sp_nodepath_node_new): Connect "event" and set knot shape + (node_clicked): Toggle type on Ctrl-click + (node_event): New signal handler for keypresses + (sp_nodepath_set_node_type): Set knot shape + +2001-02-21 Michael Meeks + + * configure.in: depend on Bonobo >= 0.37. + +2001-02-21 Lauris Kaplinski + + * configure.in: Commented out GNOME_PRINT_CHECK + +2001-02-19 Lauris Kaplinski + + * src/desktop.c (sp_desktop_connect_item): New function + + * src/sp-item.c (sp_item_view_new_prepend): View list management + (sp_item_view_list_remove): Ditto + + * src/sp-item.h: SPItemView - new object encapsulating view. I also induced + changes in almost all source files + + * src/sp-item-group.h: New file + + * src/bonobo/embeddable-drawing.c (sp_embeddable_drawing_get_type): + Use new bonobo object stuff + (sp_embeddable_drawing_factory): Ditto + + * src/bonobo/embeddable-desktop.c (sp_embeddable_desktop_get_type): + Use new bonobo object stuff + (sp_embeddable_desktop_factory): Ditto + + * src/bonobo/embeddable-document.c (sp_embeddable_document_get_type): + Use new bonobo object stuff + (sp_embeddable_document_new): Ditto + +2001-02-17 Lauris Kaplinski + + * src/sp-object.c (sp_object_getAttribute): New function + (sp_object_setAttribute): New function + (sp_object_removeAttribute): New function + +2001-02-11 Lauris Kaplinski + + * configure.in: Added es to ALL_LINGUAS + +2001-02-07 Lauris Kaplinski + + * src/dialogs/object-properties.c: Added channel sliders + * glade/object_props.glade: Ditto + * samples/mangatips6.svg: New file + * samples/mangatips7.svg: New file + * samples/mangatips8.svg: New file + * samples/mangatips9.svg: New file + * samples/mangatips10.svg: New file + +2001-02-06 Lauris Kaplinski + + * samples/mangatips3.svg: New file + * samples/mangatips4.svg: New file + * samples/mangatips5.svg: New file + +2001-01-29 Fatih Demir + + * src/widgets/.cvsignore: Added this. + +2001-01-26 Lauris Kaplinski + + * configure.in: Version 0.21 + +2001-01-24 Lauris Kaplinski + + * src/document-undo.c (sp_document_add_repr): Do not expect repr + always correspond to item + + * src/toolbox.c (sp_maintoolbox_create): Save edit/undo/redo widgets + (sp_update_draw_toolbox): Unsensitize undo/redo for draw and node + contexts + +2001-01-09 Lauris Kaplinski + + * src/desktop (sp_desktop_change_document): Update namedviews aslo + +2001-01-09 Lauris Kaplinski + + * samples/mangatips1.svg: New file + * samples/mangatips2.svg: New file + + * src/xml/Makefile.am: Use SODIPODI_CFLAGS + +2001-01-08 Frank Felfe + + * desktop.*: use gnomeappbar in desktop-window, + use gtk_combo_text widget from libgal + + * src/desktop-events.c: use gnomeappbar + + * src/event-context.c: global keybindings + + * src/select-context.c: keybindings + + * src/text-context.c: filter Ctrl-keys for keybindings + + * src/interface.c: connect to focus-in-event from desktop-window + + * glade/toolbox.glade: keybindings for the maintoolbox-menu + + * doc/keybindings.txt + +2001-01-08 Lauris Kaplinski + + * src/selection-chemistry.c (sp_selection_rotate_90): Brought + function here from toolbox.c and renamed + + * glade/toolbox.glade: Use sp_selection_rotate_90 + + * src/desktop_snap.* (sp_desktop_circular_snap): New function + + * src/rect-context.c (sp_rect_context_destroy): Finish object, if exists + + * src/ellipse-context.c: (sp_ellipse_context_destroy): Ditto + +2001-01-04 Lauris Kaplinski + + * src/helper/sodipodi-ctrlrect.*: Draw by hand instead of using + libart. That fixed ugly-ugly freezing bug in Mandrake + + * src/preferences-skeleton.h: New file, encoding default preferences + + * glade/sodipodi.glade: Changes _Uus to _New in menu ;) + + * src_sodipodi.* (sodipodi_load_preferences): New function + (sodipodi_save_preferences): New function + (sodipodi_get_repr): New function for retrieving data from preferences + DOM tree. + + * src/draw-context.c (set_to_accumulated): Use style preferences + * src/rect-context.c (sp_rect_drag): Ditto + * src/ellipse-context.c (sp_ellipse_drag): Ditto + * src/text-context.c (sp_text_context_root_handler): Ditto + (sp_text_complete): ungrab keyboard + + * src/toolbox.c (sp_toolbox_create): Use preferences + +2001-01-02 Lauris Kaplinski + + * src/widgets/sp-toolbox.*: general toolbox implementation + + * src/toolbox.c: Use SPToolBox widget, load and save toolbox states + + * src/sodipodi.* (sodipodi_set_key): New function for setting + preference values into xml tree + (sodipodi_get_key): Ditto + (sodipodi_set_key_as_number): Ditto + (sodipodi_get_key_as_number): Ditto + + * src/xml/repr-io.c (sp_repr_read_file): Load whatever element node as root + (sp_repr_read_mem): Ditto + +2000-12-31 Michael Meeks + + * src/xml/repr-io.c (sp_repr_save_file): split into + (sp_repr_save_stream): here. + + * src/bonobo/embeddable-document.c (sp_embeddable_document_pf_load), + (sp_embeddable_document_pf_save): update signatures for new persistfile API. + +2000-12-30 Lauris Kaplinski + + * src/main.c (main): Reenable command-line filenames + + * src/sodipodi.* (sodipodi_application_new): New function + +2000-12-29 Michael Meeks + + * src/bonobo/embeddable-document.c (sp_embeddable_document_factory): upd. + + * Makefile.am (oafdir): kill gnorba bits, update naming. + + * src/bonobo/svg-doc-factory.c (sp_svg_doc_factory_init): upd. + (sp_svg_factory): new multi factory. + + * GNOME_Sodipodi.oafinfo: add, rename stuff. + + * configure.in (have_bonobo): require bonobo >= 0.30 + +2000-12-28 Christopher R. Gabriel + + * configure.in (ALL_LINGUAS): 'it' + +2000-12-27 Lauris Kaplinski + + * src/display/nr-svp-uncross.c: Lot of clenaup + + * src/display/nr-svp-render: Comment out printouts + + * src/display/nr-primitives.h: #define NR_COORD_TOLERANCE + +2000-12-26 Lauris Kaplinski + + * src/display/nr-svp-uncross.c (nr_svp_uncross_full): more cases - + rays, intersection - some cleanups + + * src/display/nr-svp-render.c (nr_svp_render_rgb_rgba): Cleanups + +2000-12-25 Lauris Kaplinski + + * src/display/nr-primitives.h: Move NRCoord and NRPoint here + * src/display/nr-primitives.c: NRDRect methods + + * src/display/nr-svp.*: Rewrite. NRSVP is now simple ordered + segment and we use linked (sorted) lists for describing more + complex geometries + * src/display/nr-svp-uncross.*: Ditto, partial implementation + * src/display/nr-svp-render.* Ditto. Works. + +2000-12-21 Lauris Kaplinski + + * src/display/nr-svp-render.c: Lot's of cleanup + +2000-12-20 Lauris Kaplinski + + * src/display/nr-svp-render.c (nr_svp_render_rgb_rgba): It + works to some extent! + * src/display/canvas-shape.c (sp-canvas_shape_render): Use New + Rendering, #ifdef NEW_RENDER + + * src/display/testnr.c: Silly file + +2000-12-19 Lauris Kaplinski + + * src/display/nr-uta.*: UTA Implementation + + * src/display/nr-aa-canvas.*: RGB Buffer canvas + + * src/display/sp-arena.*: Widget, using RGB canvas + + * src/display/sp-canvas-item.*: Item subclass for arena + * src/display/sp-canvas-group.*: Ditto + +2000-12-17 Lauris Kaplinski + + * src/display/nr-primitves.h: typedef NRPoint + + * src/display/nr-canvas.*: More code + * src/display/nr-canvas-item.*: Ditto + * src/display/nr-canvas-group.*: Ditto + +2000-12-16 Lauris Kaplinski + + * src/display/nr-canvas-group.*: Base class for canvas groups + * src/display/nr-primitives.*: Graphic primitives + +2000-12-15 Lauris Kaplinski + + * src/display/nr-canvas.*: Experimental new rendering stuff (not working) + * src/display/nr-canvas-item.*: Ditto (not working) + * src/display/nr-svp.*: Ditto (works) + * src/display/nr-svp-uncross.*: Ditto (works) + * src/display/nr-svp-render.*: Not working yet + + * configure.in: Added {with|without}-new-render switch + +2000-11-30 Szabolcs Ban + + * glade/toolbox.c: corrected "zom factor" to "zoom factor" + +2000-11-30 Szabolcs Ban + + * configure.in (ALL_LINGUAS): add hu. + +2000-11-26 Lauris Kaplinski + + * src/toolbox.c (sp_maintoolbox_create): Strip toolbox names + (sp_toolbox_create_widgets): Make windows toplevel + + * glade/*.glade: Make windows to be toplevel + +2000-11-25 Christopher R. Gabriel + + * debian/: added the debian scripts from package maintainer, + Davide Puricelli + +2000-11-17 Yuri Syrota + + * glade/transformation.c + * glade/transformation.glade: correct "vertival move" to "vertical move" + +2000-11-17 Lauris Kaplinski + + * src/dialogs/text/edit.c (sp-text-dialog-close): Destroy + dialog, so font listing will be regenerated + +2000-11-02 Michael Meeks + + * configure.in: Check for bonobo >= 0.27 + +2000-10-27 Michael Meeks + + * configure.in (ALL_LINGUAS): add pt_BR. + +2000-10-26 Lauris Kaplinski + + * configure.in: Define libxml include path + + * src/Makefile.am: Use libxml include path + + * src/main.c: Ditto + + * src/xml/Makefile.am: Ditto + + * src/xml/repr-io.c: Ditto + +2000-10-21 Zbigniew Chyla + + * configure.in: Added pl to ALL_LINGUAS. + +2000-10-21 Zbigniew Chyla + + * sodipodi/src/toolbox.c (sp_maintoolbox_create): + Marked strings for translation. + +2000-10-18 Christophe Merlet + + * configure.in: Oups, forgotten to add French (fr) to $ALL_LINGUAS + +2000-10-18 Christophe Merlet + + * sodipodi.desktop: Added French string. + +2000-10-17 Lauris Kaplinski + + * src/nodepath.c (sp_nodepath_node_destroy): fixed YANC (Yet + Another Nodepath Crash) + +2000-10-16 Frank Felfe + + * glade/toolbox.glade: Updated zoom toolbox + + * src/desktop-events.*: Added sp_canvas_root_handler + + * src/desktop.c: Added statusbar, clean up zooming + + * src/sp-metrics.* (sp_metric_to_metric_string): A way to + suppress metric identifier in strings + + * src/sp-ruler.c: Copy GtkRuler object + + * src/zoom-context.c: Use desktop region markup with border + + * src/bonobo/embeddable-desktop.c: Ditto + +2000-10-13 Lauris Kaplinski + + * src/text-context.c (sp_text_context_item_handler): Return + if repr == NULL; Commit changes to undo stack. + +2000-10-11 Lauris Kaplinski + + * src/draw-context.c (sp_draw_context-destroy): Detach signal + +2000-10-11 Frederic Devernay + + * Makefile.am: Use test -r for compatibility + + * src/Makefile.am: Remove -export-dynamic + + * src/main.c: Use libxml 1.8.8/2.0 + + * src/interface.c: Make fake_dialogs nonstatic + + * src/xml/repr-io.c: Use libxml 1.8.8/2.0 + +2000-10-09 Lauris Kaplinski + + * configure.in: Version 0.20 + + * src/helper/unit-menu.*: New convenience object + + * src/desktop.c (sp_desktop_destroy): Destroy first eventcontext, + then selection + + * src/draw-context.c: Make silent + + * src/file.c (sp_file_import_ok): Use "xlink:href" for images + + * src/sp-image.c (sp_image_read_attr): Use "xlink:href" + (sp_image_repr_read_image): Ditto + + * src/svg/svg.h: Use bitfield for units + +2000-10-08 Lauris Kaplinski + + * src/dialogs/object-properties.c: Do not keep CSS objects, so + fill & stroke do not overwrite each other settings + +2000-10-08 Frank Felfe + + * glade/align.glade: Improvements + + * glade/object_props.glade: New layout + + * src/sp-ruler.*: New files, implementing wrapper for Gtk rulers + + * src/sp-metrics.*: Default metrics, ruler metrics + + * src/desktop.c (sp_desktop_init): use ruler wrappers + +2000-10-07 Lauris Kaplinski + + * src/desktop.c (sp_desktop_realize): Zoom to page on first display + + * src/document-undo.c (sp_document_done): Limit undo to 128 levels + + * src/document.c (sp_document_new): Set docbase & docname before + creating object tree + + * src/sp-image.c (sp_image_repr_read_image): Find right root repr + + * src/sp-shape.c (sp_shape_paint): Use right stroke width + + * src/dialogs/export.c (sp_export_do_export): use ::paint() method + + * src/xml/repr-io.c (sp_repr_svg_read_node): Return on comment and text + nodes + + * src/xml/repr.c (sp_repr_document): Implement + +2000-10-06 Lauris Kaplinski + + * glade/document.glade: Page setup dialog + + * src/dialogs/document-properties.c: Implement page + setup dialog + + * src/desktop.*: Keep page rectangle in SPDesktop + + * src/sp-root.c: Update page rectangle + + * src/file.c (sp_file_print_to_printer): gnome_print_bgeinpage () + Remove FRGBA creation + + * src/dialogs/export.c (sp_export_do_export): gnome_print_beginpage () + + * glade/sodipodi.glade: Add document & xml tree to properties menu + + * src/interface.c (sp_create_window): Remove ugly buttons + + * src/mdi-ui.*: Removed + * src/dialogs/object-fill.*, object-stroke.*: Removed + +2000-10-05 Lauris Kaplinski + + * src/helper/canvas-grid.*: Grid item for canvas + + * src/sp-namedview.c: Use & update grid + + * src/desktop-snap.c: Snap to grid + +2000-10-04 Frank Felfe + + * glade/transformation.glade: Improved dialog + + * glade/*.xpm: New icons + + * src/dialogs/transformation.*: Improved dialog + + * src/selection-chemistry.*: new transformation functions + + * src/sp-metrics.*: New files + +2000-10-04 Lauris Kaplinski + + * src/nodepath.c: #define reasonable knot colors + (sp_nodepath_selected_nodes_move): Implement snapping + (node_ctrl_request): Implement snapping + +2000-10-03 Lauris Kaplinski + + * src/nodepath.c (update_repr): Call sp_document_done () + + * src/dialogs/desktop-properties.*: Use new dialog layout + + * glade/desktop.glade: Use new dialog layout + + * src/sp-guide.*: "color" and "hicolor" attributes + + * src/sp-namedview.*: Bunch of new attributes + + * src/desktop-events.c (sp_dt_guide_event): Use guide colors + (sp_dt_ruler_event): Use guide colors + +2000-10-02 Lauris Kaplinski + + * src/knot.c (sp_knot_set_flag): Implement different outlines + (sp_knot_update_ctrl): New function to set SPCtrl colors + + * src/nodepath.*: Mostly rewritten + + * src/node-context.*: Use new SPNodePath + +2000-09-30 Yukihiro Nakai + + * configure.in ALL_LINGUAS: Add Japanese 'ja' + +2000-09-21 Pablo Saratxaga + + * configure.in: ALL_LINGUAS: added 'ca' for Catalan translation. + +2000-09-18 Lauris Kaplinski + + * src/dialogs/object-properties.*: New combined fill + stroke + + transformation dialog by Frank Felfe + + * glade/*.xpm: Lots of new icons etc. by Frank Felfe + + * src/desktop.*, interface.c, select-context.c, seltrans.c: Changes + + * selection-chemistry.* (sp_selection_apply_affine): New function by + Frank Felfe + (sp_selection_remove_transforms): Same + +2000-09-17 Lauris Kaplinski + + * src/draw-context.c (sp_draw_context_root_handler): Handle Ctrl + and fix an missing segment, while continuing Ctrl-aligned line. + + * src/ellipse-context.c (sp_ellipse_read-attr): Use sodipodi namespace + for "start", "end". Replace "closed" with "open", so closed is default + + * src/sp-ellipse_context.c: Ditto + + * src/sp-object.c: #define SP_OBJECT_CLONED_FLAG + + * src/sp-root.c (sp_root_read_attr): Tru to read "viewBox" attribute. + The implementation is hackish, but it works, until document size is fixed + + * src/display/canvas-shape.c (sp_canvas_shape_update): Calculate correct + line thickness + +2000-09-16 Lauris Kaplinski + + * src/draw-context.*: Freehand should work OK now + + * src/display/canvas-shape.c (sp_canvas_shape_render): Test, if + archetype has stroke SVP + + * src/display/path-archetype.c (sp_path_at_new): Disturb Vpaths + before stroking - this removes ugly random crashing in art_uta_from_svp + +2000-09-15 Lauris Kaplinski + + * src/sp-line.h, sp-line.c: item + + * src/sp-polyline.h, sp-polyline.c: item + + * src/sp-polygon.c, sp-polygon.h: item + + * src/sp-object-repr.c (sp_object_type_lookup): Register new item types + + * src/helper/curve.c (sp_curve_closepath): Add point, if end != start + +2000-09-14 Lauris Kaplinski + + * src/Makefile.am: Define GNOME_PIXMAPDIR + + * src/main.c (main): Set default icon + + * interface.c (sp_create_window): Set icon + + * src/sp-text.c (sp_text_set_shape): Use helvetica for unknown font + + * src/helper/art-utils.* (art_svp_translate): New function + (art_uta_from_svp_translated): Use art_svp_translate () + + * draw-context.*: Use experimental spline fitting for freehand + lines, during drawing generate many small lines, instead of + one big. + +2000-09-13 Lauris Kaplinski + + * desktop-snap.c, desktop-snap.h (sp_desktop_horizontal_snap): + Implemented + (sp_desktop_vertical_snap): Ditto + (sp_desktop_free_snap): Rewrote, using horiz. and vert. snapping + (sp-desktop_vector_snap): Implemented + + * rect-context.c, rect-context.h: Rewrote event handling stuff, + so it now supports (hopefully) all snapping chemistry + + * sp-namedview.c (sp_namedview_build, sp_namedview_read_arg): + Implemented arguments "snaptoguides" and "guidetolerance" + + * sp-rect.c (sp_rect_set_arg): Implemented Gtk+ argument setting + + * ellipse-context.c, ellipse-context.h: Ditto + +2000-09-12 Lauris Kaplinski + + * src/*.c, glade/desktop.*, src/dialog/desktop-properties.*: + Hacked together a preliminary guideline support stuff. It + sucks really for anything other than scaling, but now we have + at least something to improve in future. + +2000-09-09 Lauris Kaplinski + + * sodipodi.c, sodipodi-private.h: New filed. Bye-bye to + Gnome-MDI interface, instead we have much more convenient + sodipodi object. + This introduced many changes mostly everywhere. + + * src/helper/gt1*, src/helper/parseAFM.*: removed gt1 library, + as it is now accessible through gnome-print + + * Makefile.am, src/Makefile.am, glade/Makefile.am: We'll pass + 'make distcheck' again + + * src/sp-item-group.c: Children update, if parent's style is + changed + +2000-09-06 Lauris Kaplinski + + * glade/*: Added Frank Felfe new icons and toolbopx stuff + + * src/toolbox.*: Toolbox stuff (Frank Felfe) + + * src/sp-item-transform.*: Same + +2000-08-24 Alastait McKinstry + + * configure.in: ALL_LINGUAS: added 'ga' for Irish translation. + +2000-08-19 Lauris Kaplinski + + * glade/transformation.glade: Transformation dialog (Frank Felfe) + + * src/dilaogs/transfomration.*: Transfomration dialog (Frank Felfe) + + * src/mdi-ui.c: Added transformation dialog + + * po/POTFILES.in: Added glade/transformation.c + +2000-08-18 Lauris Kaplinski + + * configure.in: Version 0.19 + * Makefile.am: Comment out dist-hook + * sodipodi.spec.in: Build 0 + + * glade/align.glade: Added alignment base selection + + * po/POTFILES.in: Added src/dialogs/align.c + + * src/desktop.c: Display page borders + + * src/sp-text.c: break text at newlines + + * src/dialogs/align.c: New algorithm plus alignment base selection + +2000-08-15 Lauris Kaplinski + + * glade/stroke.glade: Moved dialog to separate file + * Added Frank Felfe icons, that I forgot last time + +2000-08-10 Lauris Kaplinski + + * src/main.c (main): Commented out arg parsing - it segfaulted for me + + * glade/align.glade + * glade/al* + * src/dialogs/align.*: Alignmeant dialog by Frank Felfe + + * configure.in: Need bonobo >= 0.17 + + * src/bonobo/embeddable-document.c (sp_bonobo_stream_read): Bonobo API change + +2000-08-10 Lauris Kaplinski + + * doc/architecture.txt: First step in generating developers documentation + +2000-08-09 Lauris Kaplinski + + * glade/*.xpm: Added Frank Felfe's node editing icons and node dialog + + * src/sp-ellipse.c (sp_ellipse_description): return "Ellipse" + + * src/sp-text.c (sp_text_description): Return either contents or "Text" if NULL + +2000-08-07 Lauris Kaplinski + + * configure.in: Require gnome-print >= 0.21 + + * glade/text-dialog.glade: New layout, suitable for gnome-font-selection + + * src/Makefile.am: Add libunicode + + * src/sp-chars.h: + * src/sp-chars.c: + * src/sp-text.h: + * src/sp-text.c: Use gnome-font instead of wrapper + + * src/dialogs/text-edit.c: Use new GnomeFontSelection and GnomeFontPreview + +2000-08-03 Michael Meeks + + * configure.in: update for BonoboX + +2000-07-01 Lauris Kaplinski + + * src/sp-namedview.c (and everywhere else): Guides are visible, + although not functional yet. + + * src/desktop.c (sp_desktop_new): Use document + namedview + combination for creating desktop. + +2000-07-01 Lauris Kaplinski + + * src/file.c (sp_do_file_print_preview): Don't use FRGBA, as + print preview can handle alpha itself + + * src/sp-object-group.h + * src/object-group.c: Added SPObjectGroup to handle groups of + invisible objects (such as NamedViews) + + * src/sp-namedview.h: + * src/sp-namedview.c: Extends SPObjectGroup + + * src/xml/sp-repr.c (sp-repr-destroy): fix hash table destroy + +2000-06-21 Chema Celorio + + * src/file.c (sp_do_file_print_preview): added print preview + stuff. new function + (sp_print_preview_destroy_cb): new function + (sp_file_print_preview): new function + modified the menu to include a print preview item + +2000-06-21 Lauris Kaplinski + + * src/selection.c (sp_selection_update_statusbar): Added original + idea of printing sp_image_description (), if single item is + selected + + * glade/*.xpm: Jeff's icons. I need to find a way to use png + variants, xpm sucks + +2000-06-21 Chema Celorio + + * src/desktop.c (sp_desktop_set_status): it was #if'ed out, + reenabel it. + + * src/selection.c (SP_SELECTION_C): added debug messages and macro + If lauris does not like them I will take them away. + (sp_selection_update_statusbar): new function + + * src/mdi.c (sp_mdi_app_created): add statusbar to main window. + +2000-06-11 Benedikt Roth + + * configure.in: Added de to ALL_LINGUAS. + * sodipodi.desktop: Added German translations + +2000-06-05 Lauris Kaplinski + + * src/dialogs/export.c (sp_export_do_export): use pixbuf context, + instead of rbuf + +2000-06-05 Michael Meeks + + * src/dialogs/export.c (sp_export_do_export): s/rbuf_rgba_new/rbuf_new/ + + * src/bonobo/embeddable-document.c: kill a load of redundant prototypes, + and re-order to suit. (sp_embeddable_document_ps_save), + (sp_embeddable_document_ps_load): fix for new stream API. + (sp_embeddable_document_factory): update stream constructor. + +2000-05-14 Lauris Kaplinski + + * src/knot.*: Lot of rearranging, new signals + + * src/seltrans.c: Changes induced by new knot signalling + Added fake snapping to PostScript points (remove it, if you dare ;) + +2000-05-13 Lauris Kaplinski + + * src/document-private.h: Removed width and height attributes + + * src/sp-root.c: Added "width" and "height" readable attributes + +2000-05-12 Lauris Kaplinski + + * src/xml/repr.h: A bit rearranging, added SPReprDoc, induces + changes almost everywhere else + + * src/document-private.h: Hide all document internal structure + +2000-05-12 Lauris Kaplinski + + * src/sp-namedview.*: Implemented skeleton + + * src/sp-guide.*: Implemented skeleton + + * src/sp-object-repr.c: Added NamedView and Guide + + * src/helper/sp-guide.*: Changed name to SPGuideLine + +2000-05-11 Lauris Kaplinski + + * src/desktop-events.c: Collected events to separate file + Added guidline and grid positioning skeleton + + * src/helper/sp-guide.*: Guideline implementation + +2000-05-10 Lauris Kaplinski + + * glade/*.xpm: Some new icons (thanks to Jeff Mrochuk) + + * src/knot.*: signals clicked, grabbed, ungrabbed, moved + Many fixes and enhancements + + * src/seltrans.c: Use knots instead of Ctrl canvas items + +2000-05-09 Michael Meeks + + * src/bonobo/svg-doc-factory.c (sp_svg_doc_factory_init): add + config.h + OAFIID. + + * Makefile.am: Install oaf data. + + * src/main.c (main): re-tool for oaf. + + * configure.in: Check for oaf. + +2000-05-06 Lauris Kaplinski + + * src/knot.h: Added signals "grab", "ungrab" and "move" + * src/knot.c: Implemented signals, event etc. + +2000-05-05 Lauris Kaplinski + + * src/desktop-handles.h: Added SP_DT_IS_EDITABLE + * src/knot.*: started implementing universal handle object for + all contexts + +2000-05-05 Lauris Kaplinski + + * src/Makefile.am: Define $gladedir, which has been forgotten :) + * src/sp-image.c (sp_image_print): Do it :) + +2000-05-03 Lauris Kaplinski + + * src/main.c: Uncommented line interpreting unknown command-line + arguments as filenames + * src/document-undo.c (sp_document_undo): If attribute is 'id', find + affected object from 'new' instead of 'key' + * src/dialogs/xml-tree.c: Added missing sp_document_done flushes + * src/sp-object.c (sp_object_read_attr): Fixed def-ing repr + id attribute instead of objects one + +2000-05-02 Lauris Kaplinski + + * src/sp-item-group.c (sp_group_build): Check that xml node is + known, before trying to build object from it + +2000-05-02 Lauris Kaplinski + + * src/sp-gradient.*: Implemented skeleton for gradient fills + * src/sp-object-repr.c: Gradient parsing + +2000-05-01 Lauris Kaplinski + + * src/helper/sodipodi-ctrl.c: Fixed bug in ::render, which left + buffer->is_bg untouched + * src/sp-defs.*: New objects, implementing nodes + * src/sp-group.*: Groups have both item and non-item members + * src/sp-image.c: Changed "src" attribute to "href" + +2000-04-29 Lauris Kaplinski + + * xml/repr.*: Reprs are now GtkObjects + * xml/repr-io.c: Preliminary namespacing (xmlns:sodipodi) + +2000-04-29 Lauris Kaplinski + + * src/dialogs/xml-tree.c (sp_xml_tree_change_attribute_long): + new function to change long attribute (GtkEntry does not like + long strings). Also attribute changing in xml pushes Undo stack. + +2000-04-28 Lauris Kaplinski + + * glade/Makefile.am: Added xml-tree.glade + + * src/dialogs/xml-tree.c (sp_xml_tree_change_attribute): implemented + this + +2000-04-27 Miguel de Icaza + + * glade/Makefile.am: New file. + + * src/dialogs/Makefile.am (gladedir): Define gladedir based on + $datadir + + * Makefile.am: Remove the local install hack stuff. And process + the glade directory. + + * configure.in: Do not define PACKAGE_GLADEDIR based on the output + of gnome-config. Let the Makefile.am compute that value from the + various $prefix settings. + +2000-04-27 Lauris Kaplinski + + * src/dialogs/xml-tree.c: Attribute deletion mostly work + +2000-04-27 Lauris Kaplinski + + * src/dialogs/xml-tree.*: Started implementing direct xml editing + + * glade/xml-tree.glade: XML editing dialogs + +2000-04-26 Lauris Kaplinski + + * helper/curve.c (sp_curve_split): Fixed evil memcpy size bug + +2000-04-24 Lauris Kaplinski + + * src/selection-chemistry.c: Implemented Cut/Copy/Paste + +2000-04-23 Lauris Kaplinski + + * src/document.h: added aspect and clip attributes + + * src/bonobo/embeddable-desktop.c: keep full page always visible + + * src/bonobo/embeddable-document.c: print scaled full page + +2000-04-21 Lauris Kaplinski + + * src/mdi-document.c: extract ACTIVE_DOCUMENT for ACTIVE_DESKTOP + instead of MDIChild + + * glade/sodipodi.glade: Popup menu + + * src/event-context.c: (sp_event_context_private_root_handler) + Popup menu on button 3, if event is not consumed + + * src/zoom-context.c: (sp_zoom_context_root_handler) + Assign zoom_out to Shift+Button1 to free Button3 for popup + + * src/draw-context.c: (sp_draw_context_root_handler) + Invoke parent handler, if event is not consumed + +2000-04-21 Lauris Kaplinski + + * configure.in: removed plugins/Makefile (not yet folks!) + + * src/bonobo/embeddable-document.c (sp_embeddable_document_factory): + switched to original gnome-print-context instead of FRGBA + +2000-04-21 Michael Meeks + + * configure.in (have_bonobo): add -lbonobo-print + + * src/bonobo/embeddable-document.c (sp_embeddable_document_factory): + add the print interface. + +2000-04-21 Fatih Demir + + * configure.in : Added tr to ALL_LINGUAS . + + * sodipodi.desktop : Added [tr] .. + +2000-04-20 Lauris Kaplinski + + * glade/sodipodi.glade: toggling rulers and scrollbars on/off + * desktop.c: construct it by hand, borders can be removed + * mdi-desktop.c: new logic for activating desktops (bonobo needed it) + * bonobo/embeddable-document.c: removed MDI refcounting + * bonobo/embeddable-desktop.c: added MDI refcounting, active desktop + management and hiding borders, if not active + +2000-04-20 Andreas Hyden + + * sodipodi.desktop: Added Swedish translation. + * configure.in: Added sv to ALL_LINGUAS. + +2000-04-19 Lauris Kaplinski + + * configure.in: Added chack for GnomePrintRBuf and GnomePrintFRGBA + * sp-shape.c: if FRGBA is present, do not emulate alpha + * file.c: print via FRGBA, if present + * dialogs/export.c: export via RBuf, if present + * sp-object.c: fixed infinite loop in allocating id-s + +2000-04-17 Lauris Kaplinski + + * src/sp-image.c: completed migration to new gdk-pixbuf + * src/display/canvas-image.c: completed migration + +2000-04-17 Michael Meeks + + * src/sp-image.c (sp_image_pixbuf_force_rgba): fix. + (sp_image_bbox): fix. + +2000-04-14 Lauris Kaplinski + + * Makefile.am: fixed .desktop inclusion to distribution + +2000-04-12 Pablo Saratxaga Pablo + + * configure.in (ALL_LINGUAS): Add Danish + +200-04-09 Lauris Kaplinski + + * bonobo/canvas-translator.*: implemented a translator group, which + translates xlib canvas calls to antialiased canvas ones. + +200-04-09 Lauris Kaplinski + + * document.c: Removed bad memory corruption bug in ::destroy + * embeddable-document.c: Added PersistentFile interface + * embeddable-drawing.*: Added BonoboCanvasComponent interface + +200-04-08 Lauris Kaplinski + + * Makefile.am: create sodipodi-bonobo symlink if we use bonobo + * src/sodipodi/*: Added bonobo component, nothing interesting yet + +200-04-07 Lauris Kaplinski + + * sodipodi.gnorba: added this, embeddable document will follow soon + * configure.in: added bonobo check + +200-04-07 Lauris Kaplinski + + * sp-shape.c: It prints now semitransparent shapes, rendering these + to bitmaps. No clipping yet and resolution is hardcoded to 72dpi + +200-04-05 Kjartan Maraas + + * no.po: Added no to ALL_LINGUAS. + +2000-04-05 Lauris Kaplinski + + * sp-document.c, sp-file.c, sp-image.c: removed namespace. How to + extract this correctly from libxml? + +2000-04-05 Lauris Kaplinski + + * xml/repr.c: added order_changed_pre callback + * document-undo.c: stacking order changes are now undoable + * sp-document.c, sp-file.c, sp-image.c: added namespace "sodipodi", + still have to do official definition + +2000-04-04 Lauris Kaplinski + + * xml/repr-io.c: save DTD & standard header + * dialogs/object-*: modify default fill & stroke, if nothing selected + +2000-04-04 Lauris Kaplinski + + * selection.*: Added functions to select via reprs (now when we have + unique id-s there isn't any reason thare wasn't such) + +2000-04-02 Lauris Kaplinski + + * xml/repr-io.c: A very quick hack to load real svg code (DTD & stuff). + * sp-shape.c: Fixed bug in exporting open paths, so they are not filled + anymore. + * sp-image.c: We can print semitransparent images, although better do not + stretch these very much + +2000-04-02 Lauris Kaplinski + + * document-undo.c, document.c: Undo should now work! + +2000-04-01 Lauris Kaplinski + + * document.c: Some undoing/redoing works (duplicate & delete) + +2000-04-01 Lauris Kaplinski + + * sp-item-group.c: cleaned up signals, reordering should work now + * hunted memory leaks & removed most obvious ones + +2000-03-31 Lauris Kaplinski + + * Basically completed rewrite, most things do not work + +2000-03-30 Lauris Kaplinski + + * Bumped version number to 0.18 & started rewrite of object system + +2000-03-29 Lauris Kaplinski + + * Modified argument parsing, --without-gui, if present, has to be first + * argument, but otherwise now all GNOME/Gtk args work + * You can also specify multiple files for displaying or printing + +2000-03-28 Lauris Kaplinski + + * Added cute little squirrel to /gnome/apps/Graphics ;-) + * src/desktop.c: Set canvas background to white + * Makefile.am: added samples to tarball + +2000-03-27 Lauris Kaplinski + + * main.c: Applied Yukihiro Nakai FreeBSD patches + * main.c: Set LC_NUMERIC to "C", to avoid localisation of SVG files :-( + +2000-01-25 Lauris Kaplinski + + * dialogs/export.*: a bit better png exporting, still sucks + +2000-01-25 Lauris Kaplinski + + * sp-image.c: Cleanups here and there + * display/canvas-image.c: point method uses alpha, removed SVP-s + +2000-01-23 Lauris Kaplinski + + * helper/art*: functions for rendering into RGBA buffer + * file.*, sp-shape.*, sp-image.*: exporting png bitmaps + +2000-01-23 Lauris Kaplinski + + * Uses SPCurve everywhere + +2000-01-19 Lauris Kaplinski + + * src/helper/sodipodi-ctrl.*: removed aa rendering + +2000-01-18 David Metcalfe (crdjm@sgi.com) + + * Added command line options: + . [ -f ] file to load file at startup + . -p file to print the file without the GUI starting + . -t file to send the print output to the named file + * -t is currently required for -p as I couldn't find a way of creating + a GnomePrinter that goes to the default printer. ?? + * Printing doesn't require that X be started + +2000-01-16 Lauris Kaplinski + + * Bumped version to 0.17 + * Most things, that worked in 0.15 work again + * still looses selections, dialogs suck etc. + +2000-01-14 Lauris Kaplinski + + * Now uses Gnome MDI + * Stroke & fill dialogs almost work for multiple displays + +2000-01-08 Lauris Kaplinski + + * Major rewrite of object system + * Multiple views almost work + * Multiple documents almost work + * Rects, Ellipses, Drawing and Nodes almost work + * Nothing else works ;-( + +1999-12-30 Lauris Kaplinski + + * Bumped version number to 0.15 + * Node editing works enough to be usable + * Images use relative paths, if possible + * Text can show accented chars + +1999-12-25 Lauris Kaplinski + + * Increased version number to 0.14 + * Preliminary node editing mode + * Stacking order can be changed again + * Convert to Curves, Combine & Separate functions + * Corrected repr refcounting - much fewer segfaults now + * Countless bugfixes here & there + +1999-12-23 Lauris Kaplinski + + * Major cleanup - most things work better now, but some + don't work at all :-( + * Implemented SPChars class + * Text editing + * svg importing + * loading, saving and printing almost works + +1999-09-02 Lauris Kaplinski + + * Rewrote many things and hacked up the rest. + Removed Gdome dependency, as I had neither time nor patience + to mess with it. As a temporary solution I've created SPRepr objects, + which can contain xml data. + Added functions: group, ungroup, delete, duplicate, to_front, + to_back, up, down + Freehand drawing almost works although need some cleanup + Outlines are implemented, although not usable yet + Rect can handle round corners i hope + Ellipse can be sliced + +# Local Variables: +# tab-width:8 +# indent-tabs-mode:t +# End: +# vim: tabstop=4:noexpandtab:shiftwidth=4 diff --git a/doc/Makefile.am b/doc/Makefile.am new file mode 100644 index 000000000..ef23aed1a --- /dev/null +++ b/doc/Makefile.am @@ -0,0 +1,16 @@ +EXTRA_DIST = API \ + README.document \ + WISHLIST \ + architecture.svg \ + architecture.txt \ + class-hierarchy.dia \ + coordinates.txt \ + fonts.txt \ + inkscape-shadow.README \ + keys.README \ + keys.xml \ + keys.fr.xml \ + keys-svg.xsl \ + keys-html.xsl \ + keys.html \ + keys.fr.html diff --git a/doc/NewAppArchitecture/01-title.svg b/doc/NewAppArchitecture/01-title.svg new file mode 100644 index 000000000..3c53650a5 --- /dev/null +++ b/doc/NewAppArchitecture/01-title.svg @@ -0,0 +1,216 @@ + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + Bryce Harrington + Application Architecture + diff --git a/doc/NewAppArchitecture/02-outline.svg b/doc/NewAppArchitecture/02-outline.svg new file mode 100644 index 000000000..8e5fe3366 --- /dev/null +++ b/doc/NewAppArchitecture/02-outline.svg @@ -0,0 +1,416 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Overview + * Current inkscape gui/app architecture* Problems with current architecture* Current inkscape_gtkmm architecture* Future capabilities we'd like to support* Next generation architecture* Evolving to next gen inkscape architecture + + + diff --git a/doc/NewAppArchitecture/03-current.svg b/doc/NewAppArchitecture/03-current.svg new file mode 100644 index 000000000..af762c9bf --- /dev/null +++ b/doc/NewAppArchitecture/03-current.svg @@ -0,0 +1,476 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Current Inkscape Architecture + * Core assumption: This is a Linux GUI Editor _only_ + Well, plus a GUI viewer, too + Well, plus non-GUI cmdline tool, too + Well, plus all the above on Windows, too + (Architecture has grown organically)* Core architecture + Gtk::Main - runs program + Inkscape::Application - GUI editing mode - Contains 'Document's - Each Document has one or more 'View's - An editable View is called a 'Desktop' + Other run modes (inkview, cmdline) handled uniquely + + + diff --git a/doc/NewAppArchitecture/04-current-main.svg b/doc/NewAppArchitecture/04-current-main.svg new file mode 100644 index 000000000..ba7446884 --- /dev/null +++ b/doc/NewAppArchitecture/04-current-main.svg @@ -0,0 +1,584 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + main() Process Flow + + main() + WinMain() + + + + sp_main_console() + + sp_main_gui() + + + + + + slideshow modesp_slideshow_new(files) + + editor modesp_file_open(files) + + + diff --git a/doc/NewAppArchitecture/05-current-objects.svg b/doc/NewAppArchitecture/05-current-objects.svg new file mode 100644 index 000000000..9892f628e --- /dev/null +++ b/doc/NewAppArchitecture/05-current-objects.svg @@ -0,0 +1,1145 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Current Objects + + Inkscape::Application + + Args + + Prefs + + + + + + + + + + + + + + + + + + + + + + Doc + Doc + Doc + Desktop + Desktop + Desktop + + + diff --git a/doc/NewAppArchitecture/06-current-desktop-view.svg b/doc/NewAppArchitecture/06-current-desktop-view.svg new file mode 100644 index 000000000..03a03c538 --- /dev/null +++ b/doc/NewAppArchitecture/06-current-desktop-view.svg @@ -0,0 +1,667 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Views and Desktops + + Desktop + + View + + SPView - Base class for SVG views - Has a pointer to a doc (SPDocument) - Contains message stack and message context - Handles status messages - Handles redrawing screen - Emits signals on view changes - Provides sp_desktop_widget_new() + SPDesktop - Subclass of SPView - Implements an "Editable view" - Holds pointer to Inkscape::Application - Contains scrollbar, ruler, canvas, guides, etc. - Defines scroll limits, zoom min/max, fullscreen - Manages event contexts, coordinate systems, zooming, etc. + + + diff --git a/doc/NewAppArchitecture/07-current-problems.svg b/doc/NewAppArchitecture/07-current-problems.svg new file mode 100644 index 000000000..dde3c36a8 --- /dev/null +++ b/doc/NewAppArchitecture/07-current-problems.svg @@ -0,0 +1,612 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Problems + * Inkscape seems to want to have "run modes" + editor, viewer, cmdline, more...? + If we needed a new mode, it would be hard to fit in except as hacks + Currently, these modes implemented as exceptions, but it's buggy - popping up warning dialogs in cmdline mode - inconsistent URI / UTF handling - duplication of code for different modes may lead to divergences* main() has too much code in it (>750 lines) + cmdline handling code needs broken out separately* winmain() is not well integrated (Q's listed in makefiles)* Current architecture is C / Gtk+; we need C++ / Gtkmm + + + diff --git a/doc/NewAppArchitecture/08-inkscape-gtkmm.svg b/doc/NewAppArchitecture/08-inkscape-gtkmm.svg new file mode 100644 index 000000000..d1c86db8d --- /dev/null +++ b/doc/NewAppArchitecture/08-inkscape-gtkmm.svg @@ -0,0 +1,472 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + inkscape_gtkmm Architecture + * Very much a work-in-progress + top level architecture still incomplete* Inkscape::Application + Modelled after current Inkscape::Application struct + Inkscape::ApplicationImpl allows 'interface hiding' - Helps keep *.h include hierarchy trim and clean - Subclasses Gtk::Window !! problem, only one Window per application - No code for creating/managing documents + + + diff --git a/doc/NewAppArchitecture/09-future-capabilities.svg b/doc/NewAppArchitecture/09-future-capabilities.svg new file mode 100644 index 000000000..f2ea7183c --- /dev/null +++ b/doc/NewAppArchitecture/09-future-capabilities.svg @@ -0,0 +1,484 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Future Capabilities Desired + * Make it easier to have multiple run-modes + Commandline mode (--no-gui) + Presentation mode (inkview *.svg) + Old Gtk+ interface (--old-gui) + New Gtkmm interface (--new-gui) + Whiteboard interface (inkboard) + Gimp-style interface? + GUI testing mode? + Animation playing mode? + More...?* Inkscape::Application should be run-mode neutral + Provide high level services / registries for all run modes + + + diff --git a/doc/NewAppArchitecture/10-future-main.svg b/doc/NewAppArchitecture/10-future-main.svg new file mode 100644 index 000000000..aad183838 --- /dev/null +++ b/doc/NewAppArchitecture/10-future-main.svg @@ -0,0 +1,503 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Future main() + int main(int argc, char *argv[]){ Inkscape::Application app(argc, argv); return app.run();}* All logic moved inside Inkscape::Application + popt, homedir path detection, prefs, extensions, etc. + Run mode handling* Could also include a definition of WinMain here if needed + + + diff --git a/doc/NewAppArchitecture/11-future-ink-app.svg b/doc/NewAppArchitecture/11-future-ink-app.svg new file mode 100644 index 000000000..e39b493c6 --- /dev/null +++ b/doc/NewAppArchitecture/11-future-ink-app.svg @@ -0,0 +1,507 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Future Inkscape::Application + Inkscape::Application + Option handling - Select run mode from $arg[0] and/or opts given + Paths (homedir, config file dir, share dir, etc.) + Preferences + Extensions registry + Primary Run Mode object creation/maintenance Inkscape::Application::RunMode* runmode;Inkscape::Application::RunMode + Each run mode will subclass this base class + Provides an 'implementation hiding' ability similar to Inkscape::ApplicationImpl in inkscape_gtkmm + + + diff --git a/doc/NewAppArchitecture/12-future-run-modes.svg b/doc/NewAppArchitecture/12-future-run-modes.svg new file mode 100644 index 000000000..a579d9de5 --- /dev/null +++ b/doc/NewAppArchitecture/12-future-run-modes.svg @@ -0,0 +1,936 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Future Run Modes + + Inkscape::Application::RunMode + + I::A::Editor + + I::A::Presenter + + I::A::Whiteboard + + I::A::Cmdline + + I::A::TestSuite + + I::A::Player + + BASECLASS + RUN MODESUB-CLASSES + $ inkscape + $ inkview + $ inkboard + $ inkscape --no-gui + $ inkscape --test + $ inkscape --play + + + + + + + diff --git a/doc/NewAppArchitecture/13-future-ink-app-editor.svg b/doc/NewAppArchitecture/13-future-ink-app-editor.svg new file mode 100644 index 000000000..bb07a3fdb --- /dev/null +++ b/doc/NewAppArchitecture/13-future-ink-app-editor.svg @@ -0,0 +1,1403 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Current Objects + + Inkscape::Application::Editor + + + + + Inkscape::Document + + + + + + + + + + + + + + + + Doc + MultiPageDoc + Doc + I::V::Edit + I::V::Play + Inkscape::View::* + + + Palettes + + + + + I::V::Edit + + + + + + + + + diff --git a/doc/NewAppArchitecture/14-evolving.svg b/doc/NewAppArchitecture/14-evolving.svg new file mode 100644 index 000000000..165c6b9c3 --- /dev/null +++ b/doc/NewAppArchitecture/14-evolving.svg @@ -0,0 +1,511 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Evolving inkscape_gtkmm + * Expand Inkscape::Application + High level services (GC, args, paths) + Registries (extensions, prefs, etc.)* Create new Inkscape::Application::RunMode + Abstract base class* Refactor Inkscape::Application::ApplicationImpl + Rename it to Inkscape::Application::Editor + Make it subclass I::A::RunMode + Move items from SPDesktop into here* Create new Inkscape::Application::Cmdline + Make it subclass I::A::RunMode + Move stuff from main.cpp into here + + + diff --git a/doc/README.document b/doc/README.document new file mode 100644 index 000000000..e5f958cbb --- /dev/null +++ b/doc/README.document @@ -0,0 +1,77 @@ +31.03.2000 + +Well, we end with 2 basic objects: + +SPDocument - the base of all nongraphical wizardry. +Although you can well do all things via repr tree, Document will have some +neat features: +Undo stack managing: start_undo_step, end_undo_step +Selection grabbing - we can select via reprs, which is otherwise impossible +NB! SPDocument is SPRepr ref holder NB! + +SPDesktop - the base of all graphical wizardry + +What follows, is outdated... + +Document hierarchy + +This is currently in active rewrite. Structure should be something like: + +SPApp - main application thing, probably GnomeMDI in future +SPDesktop - one view to one document +SPDocument - SPItem tree rootmost element + +SPItem tree refers to xml backbone (currently reprs) and Canvas trees. +Backbone does not know anything about other items/classes/objects. There +can be more than one canvas tree (desktop) associated with document. + +There is (and should be more) event interconnection between different +objects. + +Editing can be done to all three levels, but should end up with modifying +reprs. No other change will be saved. +1. Non-interactive modifications (for example changing object color) +These should be done directly to backbone. Probably I'll implement a separate +wrapper thing (sp-app-repr-interface.h or similar) to minimize the need +to include lot of headers for such modules. These will be also probably the +first interface to plugins. +Such modifications will instantly propagate to all items and views and will +be preserved when saving, duplicating & so on. + +2. Interactive modifications to SPItems +These are a bit faster (no need of coding/decoding, allocing, freeing xml +attributes). Changes will display instantly to all views, but WILL NOT +propagate back to xml. The right way to use such things is: +When button pressed, grab mouse pointer +Do modifications to SPItem +When button released, write modifications to SPRepr + +3. Interactive modifications to GnomeCanvasItems +These affect only the current display (desktop) and DO NOT propagate back +neither to SPItems, nor SPReprs. Use with same caution, as the class above. + +Undo/Redo, when implemented, will be probably extracted from xml + +There are several more things, like +SPSelection - a per desktop selection (selection.h) +Handful of canvas groups for grid, guidelines & so on (desktop.h) +Intermediate holders of currently modified data (all contexts) +SPNodepath (nodepath.h) + +--------------------- + +Document == SPRoot +Provides convenience constructors + +Selection { /* opaque */ } +Per desktop structure, pointing to selected items + +Desktop { + Selection selection + Document document +} + +macro ACTIVE_DESKTOP ;) gives current active desktop ;-) +There will be probably several macros to deduce affected desktop from +UI events (menus & so on) + diff --git a/doc/WISHLIST b/doc/WISHLIST new file mode 100644 index 000000000..e083a591b --- /dev/null +++ b/doc/WISHLIST @@ -0,0 +1,51 @@ + +Inkscape Wishlist +----------------- +This file is for capturing random details about desired development +work, ideas, etc. The Inkscape feature request page is probably a +better location for such things, but this can serve as a convenient +scratchpad. + + +Rework xml tree +=============== +use reprs as lightweight wrappers around gnome-xml, +keeping syntax as close to DOM as possible + + +Split SPDesktop object into modular inherited objects +===================================================== +SPDesktop - base, has drawing group, no contexts +SPEDesktop - editable desktop - more full-featured +SPNamedDesktop - Desktop, deriving its layout from NamedView - i.e. guides, + grid etc. will be saved per-desktop + +desktop_show_borders/hide_borders - show/hide rulers & stuff - usable for + Bonobo component + + + +Javascript for Animation support(?) +=================================== +> The mozilla javascript engine is under dual MPL/GPL +> (http://lxr.mozilla.org/seamonkey/source/js/src/) and written in C. +> Hopefully there's some nice way to build off that... + +The main reason JavaScript would be tricky is that it would be modifying +the document out from under you via the DOM, so you couldn't have a +"time slider" or something like you could for the SMIL stuff. + +That's a real headache, and the only way I can see it working is if the +document is cloned and played back in a separate "audition" window, then +the modified document thrown away at the end. + +But then, why implement Javascript in Inkscape? An audition feature +that calls out to an external player application would work just as well +(and indeed, that's exactly how applications like Flash cope with +scripting). + +[ note that implementing scripting for Inkscape itself is a separate +issue, and probably warrants a language-agnostic scripting interface +like the GIMP's PDB, only less grotty ] + +-- Mental \ No newline at end of file diff --git a/doc/architecture.svg b/doc/architecture.svg new file mode 100644 index 000000000..72ca07d18 --- /dev/null +++ b/doc/architecture.svg @@ -0,0 +1,607 @@ + + + + + + + + + + + + + Module subsystem(src/modules/*) + SPModules (aka plugins) handle filtering, input and export ofSPModuleDocs (wrapped SPDocuments) and to eventuallyencompass more functionality like e.g. providing toolimplementations. + + + + + New Renderer(src/libnr/*) + New Renderer Typesetting (src/libnr/libnrtype/*) + Display Glue(src/display/*) + View subsystem(src/view.*, src/desktop*.*, src/svg-view.* and others) + SPView is an abstract class representing a "view" of an SPDocument. Ithas a companion SPViewWidget class for the associated display widget.SPDesktop is an editable SPView, and SPSVGView is a display-only view(e.g. the about box). Both maintain an SPCanvas and provide anSPCanvasArena for SPObjects to display on. They have associatedSPViewWidget subclasses: SPDesktopWidget and SPSVGViewWidget.SPDesktop is also responsible for maintaining the current selection inan SPSelection.SPDesktopWidget isn't just a bare canvas; it includes the scrollbars andother decorations.SPEventContexts handle tool state and interaction. + This subsystem provides a lightweight arena abstraction.NRArena - a collection of lightweight renderable NRArenaItems.SPCanvasArena - an SPCanvasItem that renders the contents of anNRArena. + The new rendering subsystem mostly replaces libart. It rendersfilled/stroked bezier curves and polygons into NRPixBlocks (imagebuffers) + Adaptor routines for using Xft, Win32, Gnome, and Freetype 2 to managefont metrics and outlines. + + SPCanvas - handles input eventsSPCanvasItem - objects that can be displayed on SPCanvas + SVG Canvas(src/helper/sp-canvas*) + + SVG document model(src/sp-*.h and others) + Enforces validity constraints on the SPRepr document.SPDocument - an SVG document containing SPObjects.SPObjects - handles short term changes & propagateslonger term ones to the SPReprSPItems - SPObjects that can be rendered. They have hide() and show()methods for creating an associated NRArenaItem in a given NRArena. + + XML doc model(src/xml/*) + SPRepr - node in an XMLdocument (elements,attributes, and text nodes).Transactions are loggedfor replaying/undoingchanges. + Cruft subsystem - (src/svg/*) + Assorted stuff left over fromwhen Sodipodi forked fromGill which doesn't have a betterhome. + Inkscape Graphical User Interface (src/widgets, src/dialogs) + widgets/* - Utilities and custom widgets to assist in implementingthe Inkscape GUI and to enforce a common look and feel styleacross the application. + dialogs/* - Code for creating the various UI dialogs in theapplication. + dialogs/xml-tree.* - Code forcreating and maintaining aninterface for editing XML trees. + diff --git a/doc/architecture.txt b/doc/architecture.txt new file mode 100644 index 000000000..14b038b6e --- /dev/null +++ b/doc/architecture.txt @@ -0,0 +1,490 @@ +Sodipodi internal architecture + +1. Overview + +The Sodipodi display and editing engine is built using the +"Model-View-Controller" (MVC) paradigm. Unlike "classic" MVC +programs, we have further split model into two distinct layers, +'backbone' and 'document'. This has proven to be extremely powerful +technique, giving us clear and fast implementation, functional +granularity and easy expandibility. + +1.1. Agnostic XML backbone + +The basis of the sodipodi document is its plain XML representation in +memory. This is a tree-shaped structure, in which each node is +represented by a lightweight typeless object (SPRepr). These objects +implement a minimal interface of both control (methods) and mutation +events (callbacks). We use the term 'agnostic' for describing that +part of model, to underline the typeless nature of SPRepr. More or +less, this is just an XML file representation in memory. + +1.2. Typed SVG document + +The most actively used part of the sodipodi document model is the SVG +object tree. This is constructed on top of the XML tree, and reacts to +all mutation events in the agnostic tree, thus always keeping its +internal state synchronized with the backbone. The opposite is not +true - the XML backbone is not aware of the SVG object tree, and thus +does not react to its modifications. If writeback to the backbone is +needed, it must be requested explicitly by the controller. The SVG +tree is constructed of SPObject subclasses - in general there is one +subclass for each SVG element type, plus abstract base classes. + +1.3. NRArena view + +NRarena is an abstract display engine that allows construction of +'display caches' from NRArenaItem subclasses. These are lightweight, +having only some basic object types, and used for most of the display +needs of Sodipodi. Both the editing window, and the bitmap export +code create special NRArena instances, and ask the SVG document to +show itself to the given NRArena. There is a ::show virtual method, +implemented by all visible object classes, that adds an NRArenaItem +node to the display tree. The completed display cache is used for fast +screen updates and stripe based bitmap exports. During the NRArena +lifetime SVG objects keep all of the display cache elements constantly +updated, thus ensuring the display is always up to date. + +1.4. Controllers + +Like the model suggests, controllers can be implemented acting on +different layers. Which one is best depends on the type of action +that the given controller performs. Usually very generic and +single-shot operating controllers act on the SPRepr layer, while those +providing visual feedback or tied to a certain object type act on the +SPObject layer. + + + +2. Detailed view + +2.1. SPRepr + +The most basic SVG (XML) document backbone is implemented as an +in-memory tree of SPRepr objects, each object corresponding to a +single node in the XML file. Currently there are only two types of +SPReprs - normal element nodes and text nodes. More types may be +added in the future, but the structure will probably always remain +much simpler (and faster) than DOM. + +SPRepr may have: +- attributes (keyword/value) pairs +- content (text) +- child nodes + +Attribute values are textual, and no checks are performed in that +layer to ensure document validity. Also, CSS style strings are +unparsed in that layer. The SPRepr tree is built during document +loading or creation. As it is textual and always synchronized with the +display, unfiltered saving involves just dumping it into a file. + +The basic API acting on SPRepr level is really spartan. + +SPRepr *sp_repr_new (const unsigned char *name) +SPRepr *sp_repr_new_text (const unsigned char *content) +SPRepr *sp_repr_ref (SPRepr *repr) +SPRepr *sp_repr_unref (SPRepr *repr) +SPRepr *sp_repr_duplicate (SPRepr *repr) + +int sp_repr_set_content (SPRepr *repr, const unsigned char *content) +int sp_repr_set_attr (SPRepr *repr, const unsigned char *key, const unsigned char *value) +int sp_repr_add_child (SPRepr *repr, SPRepr *child, SPRepr *ref) +int sp_repr_remove_child (SPRepr *repr, SPRepr *child) +int sp_repr_change_order (SPRepr *repr, SPRepr *child, SPRepr *ref) + +In addition there are some accessor methods and lot of convenience ones. + +Each SPRepr can have one or many event vectors associated with it. +Event vector is a block of callback pointers for different kind of +mutation events. + +void sp_repr_add_listener (SPRepr *repr, const SPReprEventVector *vector, void *data) +void sp_repr_remove_listener_by_data (SPRepr *repr, void *data) + +struct _SPReprEventVector { + void (* destroy) (SPRepr *repr, gpointer data); + gboolean (* add_child) (SPRepr *repr, SPRepr *child, SPRepr *ref, gpointer data); + void (* child_added) (SPRepr *repr, SPRepr *child, SPRepr *ref, gpointer data); + gboolean (* remove_child) (SPRepr *repr, SPRepr *child, SPRepr *ref, gpointer data); + void (* child_removed) (SPRepr *repr, SPRepr *child, SPRepr *ref, gpointer data); + gboolean (* change_attr) (SPRepr *repr, const guchar *key, const guchar *oldval, const guchar *newval, gpointer data); + void (* attr_changed) (SPRepr *repr, const guchar *key, const guchar *oldval, const guchar *newval, gpointer data); + gboolean (* change_content) (SPRepr *repr, const guchar *oldcontent, const guchar *newcontent, gpointer data); + void (* content_changed) (SPRepr *repr, const guchar *oldcontent, const guchar *newcontent, gpointer data); + gboolean (* change_order) (SPRepr *repr, SPRepr *child, SPRepr *oldref, SPRepr *newref, gpointer data); + void (* order_changed) (SPRepr *repr, SPRepr *child, SPRepr *oldref, SPRepr *newref, gpointer data); +} + +All events, except destroys (which are unconditional), have pre- and +post- event callbacks. The pre-event callback's return value is used to +signal whether the given modification is allowed. If it is FALSE the +operation will be cancelled and the invoking method will also return +FALSE. Using callbacks in block is much more convenient than adding +them one-by-one, as the listening code usually wants to install several +handlers at once, and the same set of handlers for many different +nodes. NULL pointers are allowed in event vector. + +Although the most important functionality of the SPRepr tree is to +serve as a document backbone, it has other functions besides +that. SPReprs are also used to store preferences, the copy buffer and +the undo stack. + + + +2.2. SPObject + +SPObject is an abstract base class of all of the document nodes at the +SVG document level. Each SPObject subclass implements a certain SVG +element node type, or is an abstract base class for different node +types. The SPObject layer is bound to the SPRepr layer, closely +following the SPRepr mutations via callbacks. During creation, +SPObject parses and interprets all textual attributes and CSS style +strings of the SPRepr, and later updates the internal state whenever +it receives a signal about a change. The opposite is not true - there +are methods manipulating SPObjects directly and such changes do not +propagate to the SPRepr layer. This is important for implementation of +the undo stack, animations and other features. + +SPObjects are bound to the higher-level container SPDocument, which +provides document level functionality such as the undo stack, +dictionary and so on. + +SPObjects are implemented using the Gtk object system (GObjects in gtk +2 version), which provides an extremely powerful and flexible OO +framework in pure C. + +SPObject class hierarchy + +SPObject ABSTRACT + SPObjectGroup ABSTRACT + SPNamedView + SPClipPath + SPGuide + SPPaintServer ABSTRACT + SPGradient ABSTRACT + SPLinearGradient + SPRadialGradient + SPPattern + SPDefs + SPItem ABSTRACT + SPGroup + SPRoot + SPAnchor + SPImage + SPPath ABSTARCT + SPShape + SPLine + SPPolyLine + SPPolygon + SPStar + SPRect + SPSpiral + SPGenericEllipse ABSTRACT + SPCircle + SPEllipse + SPArc + SPChars ABSTRACT + SPString TEXT NODE + SPDefs + SPText + SPTSpan + +SPObject internals + +struct _SPObject { + GtkObject object; + unsigned int hrefcount; + SPDocument *document; + SPObject *parent; + SPObject *next; + SPRepr *repr; + unsigned char *id; + SPStyle *style; + const unsigned char *title; + const unsigned char *description; +}; + +The basic refcounting is handled by the parent class +(GtkObject). Hrefcount is used for weak references, for example, to +determine whether any graphical element references a certain gradient +node. The parent and next fields are used to establish the tree +structure. Id is copy of the SPRepr 'id' attribute for normal nodes, +and is used as a unique index of all objects in the given document. + +Virtual methods + +/******** Disclaimer *******/ +This will change a lot in the future + +void ::build (SPObject *object, SPDocument *document, SPRepr *repr) + +This has to be invoked immediately after creation of an SPObject. The +frontend method ensures that the new object is properly attached to +the document and repr; implementation then will parse all of the attributes, +generate the children objects and so on. Invoking ::build on the SPRoot +object results in creation of the whole document tree (this is, what +SPDocument does after the creation of the XML tree). + +void ::release (SPObject *object) + +This is the opposite of ::build. It has to be invoked as soon as the +object is removed from the tree, even if it is still alive according +to reference count. The frontend unregisters the object from the +document and releases the SPRepr bindings; implementations should free +state data and release all child objects. Invoking ::release on +SPRoot destroys the whole document tree. + +void ::child_added (SPObject *object, SPRepr *child, SPRepr *ref) +void ::remove_child (SPObject *object, SPRepr *child) +void ::order_changed (SPObject *object, SPRepr *repr, SPRepr *oldref, SPRepr *newref) + +These are invoked whenever the given mutation event happens in the XML +tree. ::remove_child is invoked BEFORE removal from the XML tree +happens, so grouping objects can safely release the child data. The +other two will be invoked AFTER the actual XML tree mutation. Only +grouping objects have to implement these. + +void ::read_attr (SPObject *object, const unsigned char *key) + +Signals object that the XML attribute is changed. The frontend checks +for 'id' attribute; implementations have to read the actual attribute +value and update the internal state. + +void ::read_content (SPObject *object) + +Signals object that the XML node content has changed. Only meaningful for +SPString implementing XML TEXT node. + +void ::modified (SPObject *object, unsigned int flags) + +Virtual method AND signal implementing asynchronous state change +notification. Whenever the object internal state changes, it requests +that ::modified will be scheduled from the idle loop. Flags are given +as hints as to what exactly changes. Read the relevant section for +more information. + +SPRepr ::write (SPObject *object, SPRepr *repr, unsigned int flags) + +Requests SPObject internal state to be written back to the SPRepr. If +the SP_OBJECT_WRITE_BUILD flag is set, SPRepr is created, if necessary. +This is used at various places, most notably to generate a plain SVG +document, and to complete certain GUI operations. + + + +2.3. SPItem + +SPItem is an abstract base class for all graphic (visible) SVG nodes. It +is a subclass of SPObject, with great deal of specific functionality. + +SPItem internals + +struct _SPItem { + SPObject object; + unsigned int sensitive : 1; + unsigned int stop_paint: 1; + double affine[6]; + SPItemView *display; + SPClipPath *clip; +}; + +Affine is a 3x2 matrix describing transformation from the item to the +parent local coordinate systems. Each display in linked list has a link +to a single NRArenaItem that implements actual renderable image of +the item. + +Virtual methods + +/******** Disclaimer *******/ +This will change a lot in the future +Only the most important are listed + +void ::bbox (SPItem *item, ArtDRect *bbox, const double *transform) + +Calculates item's logical bounding box. The logical bbox does not +take into account the stroke width, nor certain other visual +properties. Transformation is a 3x2 matrix describing coordinate +transform from the item's local coordinate system to the coordinate +system of the bounding box. + +void ::print (SPItem *item, SPPrintContext *ctx) + +Prints the item's visual representation, using the internal printing +frontend. In the future this may be turned into a more generic +exporting method. + +char ::description (SPItem *item) + +Gives a short description of the item suitable for use in a statusbar, +etc. + +NRArenaItem ::show (SPItem *item, NRArena *arena) + +Creates an NRArena display cache representation of the item. The +frontend places the generated item into a hierarchy; implementations +have to build a correct NRArenaItem and keep it up to date. + +void (* hide) (SPitem *item, NRArena *arena) + +The opposite of ::show. + +void ::write_transform (SPItem *item, SPRepr *repr, double *transform) + +Tries to remove the extra transformation by modifying other aspects of +the item representation. For example, by changing the rectangle width +and height, the scaling component of the transformation can be +dropped. This is used to make the SVG file more human-readable. + +void ::menu (SPItem *item, SPDesktop *desktop, GtkMenu *menu) + +Appends item specific lines into the menu. This is used to generate +the context menu, and will probably move into a separate module in +the future. + + + +2.4 SPDocument + +SPDocument serves as the container of both model trees (agnostic XML +and typed object tree), and implements all of the document-level +functionality used by the program. + +SPDocument implements undo and redo stacks and an id-based object +dictionary. Thanks to unique id attributes, the latter can be used to +map from the XML tree back to the object tree. Documents are +themselves registered by the main program metaobject 'Sodipodi', which +does elementary bookeeping. + +SPDocument performs the basic operations needed for asynchronous +update notification (SPObject ::modified virtual method), and implements +the 'modified' signal, as well. + +Many document level operations, like load, save, print, export and so on, +use SPDocument as their basic datatype. + +2.4.1. Undo and Redo implementation + +Using the split document model gives sodipodi a very simple and clean +undo implementation. Whenever mutation occurs in the XML tree, +SPObject invokes one of the five corresponding handlers of its +container document. This writes down a generic description of the +given action, and appends it to the recent action list, kept by the +document. There will be as many action records as there are mutation +events, which are all kept and processed together in the undo +stack. Two methods exist to indicate that the given action is completed: + +void sp_document_done (SPDocument *document) +void sp_document_maybe_done (SPDocument *document, const unsigned char *key) + +Both move the recent action list into the undo stack and clear the +list afterwards. While the first method does an unconditional push, +the second one first checks the key of the most recent stack entry. If +the keys are identical, the current action list is appended to the +existing stack entry, instead of pushing it onto its own. This +behaviour can be used to collect multi-step actions (like winding the +Gtk spinbutton) from the UI into a single undoable step. + +For controls implemented by Sodipodi itself, implementing undo as a +single step is usually done in a more efficent way. Most controls have +the abstract model of grab, drag, release, and change user +action. During the grab phase, all modifications are done to the +SPObject directly - i.e. they do not change XML tree, and thus do not +generate undo actions either. Only at the release phase (normally +associated with releasing the mousebutton), changes are written back +to the XML tree, thus generating only a single set of undo actions. + + +2.5. SPView and SPviewWidget + +SPView is an abstract base class of all UI document views. This +includes both the editing window and the SVG preview, but does not +include the non-UI RGBA buffer-based NRArenas nor the XML editor or +similar views. The SPView base class has very little functionality of +its own. + +SPViewWidget is a GUI widget that contain a single SPView. It is also +an abstract base class with little funtionality of its own. + +2.6. SPDesktop + +SPDesktop is a subclass of SPView, implementing an editable document +canvas. It is extensively used by many UI controls that need certain +visual representations of their own. + +SPDesktop provides a certain set of SPCanvasItems, serving as GUI +layers of different control objects. The one containing the whole +document is the drawing layer. In addition to it, there are grid, +guide, sketch and control layers. The sketch layer is used for +temporary drawing objects, before the real objects in document are +created. The control layer contains editing knots, rubberband and +similar non-document UI objects. + +Each SPDesktop is associated with a SPNamedView node of the document +tree. Currently, all desktops are created from a single main named +view, but in the future there may be support for different ones. +SPNamedView serves as an in-document container for desktop-related +data, like grid and guideline placement, snapping options and so on. + +Associated with each SPDesktop are the two most important editing +related objects - SPSelection and SPEventContext. + +Sodipodi keeps track of the active desktop and invokes notification +signals whenever it changes. UI elements can use these to update their +display to the selection of the currently active editing window. + +2.7. SPSelection + +This is a per-desktop object that keeps the list of selected objects +at the given desktop. Both SPItem and SPRepr lists can be retrieved +from the selection. Many actions operate on the selection, so it is +widely used throughout the Sodipodi code. + +SPSelection also implements its own asynchronous notification signals, +that UI elements can listen to. + +2.8. SPEventContext + +SPEventContext is an abstract base class of all tools. As the name +indicates, event context implementations process UI events (mouse +movements and keypresses) and take actions (like creating or modifying +objects). There is one event context implementation for each tool, +plus few abstract base classes. Writing a new tool involves +subclassing SPEventContext. + + + +3. Some thoughts + +3.1. Why do we need a two-level model tree? + +The need for a typed object tree is obvious if we want to utilize OO +programming - which we certainly want to do. Although implemented in pure C, +Sodipodi uses the gtk (glib in future versions) type and object system, +which gives us an extremely powerful set of OO functionality. As SVG is +designed with inheritance in mind, using object subclassing to represent +it is perfectly the right thing to do. + +But there are also areas where typed object structure would make +things more complex. For example, to implement the copy buffer we had +to save the full state of copied objects. While this could be done +with the separate virtual method of SPObject, we can use a much easier +way and create the duplicate corresponding SPRepr. As our document +model already has to implement generation of full object +representation for SPRepr tree of nodes, generation of new objects +during paste happens automatically when the given SPRepr is inserted +into XML tree. The agnostic xml tree is also used for undo stack, as +described earlier. + +The main benefit comes from the extreme simplicity of the XML tree +manipulation API. All operations can be done, using only around 10 +methods, which makes code much more robust, and is perfect for +implementing compatibility sensitive things, like a plugin API. + +The XML tree also makes implementing two SVG features - cloning and +animations - much easier by providing an invariant backbone. + + + +22. Novemebr 2002 +Lauris Kaplinski + diff --git a/doc/class-hierarchy.dia b/doc/class-hierarchy.dia new file mode 100644 index 0000000000000000000000000000000000000000..0781ffc943bfebb0f78daa0fadfc028dff074728 GIT binary patch literal 6668 zcmY+|1yEFN`#*3*l#~vUQjkVKx|R|I6j%@>l#p&brsw(sMNPCjJw#|JJ}q!^_G4FMv*elG}*q&!UxE*rhvz`_AqE;US28@ zQ9f|t^$M;H?I2aEv@}+hsPAL`RR*tTf%B4OUj1~txN>^wz*>P7sH>RV%T#O`;BX}i z$gtelLwd?pK@C<66VW3UtI@>`;_1uF6=@F5pRUhtX0%LCF~3H zCs)3^PG0%>^PaLT6&mFoJTGM(0+=)TTF!M8R=Yn=QHGVWX}^#!DL!=WPn<8P0GI13 zMi2Csu{OX!iHr7rN|RA;TPp(QK{fl;S6{Lb{lKN`0XLaDq`COtsl1ylz#r%Wb`PbH zSRpAhv^yZp{OdIUSzZ1WYyP=Bpse`xqgBJf!7j4mt3pgC&U_thW4XELtEZFWUC6QM z(ENRRX>YHzD|KI$3)0zuxiQ^*H|71bE$qViKnbq9(TTcva=q3hdiASw`kMp$ipXlf z`|nCV0HNZ^$;(*Nvj?xKEHXO^V*{i|kj;WEqjkq4EzGN(;a?S*Mvzq<(HX*5KYEWF zcn@Yqkmwrw>eb>9fx}+BYZVFjiu`HP!WdYxqH5JLnm2zMIJZnREdya+p6+6dt>ml- zZ@Dfn>u85Nb|`YWwUvuRL~11bL@aKYHy9Zx3=B+>Cfe_%G(A_^<+hPMV_U_jB?r|b2X5P7WwH$&gZ)zdS@#TEsf@Haxe}rvm0CUM*7fVy~T={Gq}) z;`rKOS4Im|n*JSl%1?y~PI?<%dlK7grmIy+6A+ zsCb>XR9x=VYw8IV7XrU5t7vS#!nk(lG59X>D>0ViuoYXU=~|_D6J)p&sQr9be8(ek z|KhMHIY2)?lvLT##EJ0Na;#q9-{u9C*{cb@%H(S?ARiU+~Y)2qko^frJDGrS|4fypV5EF^Qy-V zCG`NYUpoLi_t3oB21oAJqF;VTk?f|ugU$WAu}}Q3)TZB)$OYh5-=F>CLM)B$1$(`v znn}GpH?4oMEqI z*jLOyX~YHmjd?_=?ZbXYDLMyw|5}D?;XwUrzTg;0S0t7k(CZu0ue9|)ofVsa$#XUi zg)aoQxF7}%LI!Z(ObvgwHgP8PD-2J&JLY`SuE;t7Nbf( zzL{NHdjY;Pp^zmA%E{ze*pW1^F&ZLT0gvsTZ*xL!e7 zH}oejz2^CD**m3|jR(g2^j~K7^6dm&$5Rl_y&F_YU*U%Nv|x`sw-3X21f)xra{mN` ztD)1n@WWhAG5k)}gC6JQhoQN(10LTa5pLSMI^M-Wu!XLH5G=)xcmM`F>fjc2OkwYs zo(fL$HnY}$e9HVK7ORbW2(6;a$t^ep>iyi;uEg;2Z71>aq2=^<53s#==^FI1R6K7_ zGaG{c6L@yBch0S_OBif44?{o^|EQ?atKIf-ipPfM@TWh=cG9|3>2tZYcX0G;iyO2vbA2oaYyq(M_6^6sHToi-{s_i4GZ z;QGCF`0~a*_X)GQ4>X>ckRj;1C-EL?S@-P^`cLS%W}w_Jis232j*T`zW-TYf++^h< zl_DSOl$km)gq3>CAU9HGI=6-16buhNCaqKbQ=GReq9H~|9M!$foOv^a-9T`*lzg#d zy|C?#fOItW@#sqLKG~}`d=SAu7tOhQf471nKYUOQmusqlPV{WP|AJ{C-qT;G-TM>U zG3D`??g^#fZ>9XS0p}2q*QKkg)z2b;SqEf+BmH6R1OSx4A>0Zzd2lCAn1V|z^8<=q zqF(7Uo@PH55}MSN)*0lNblgp7Y62HK}1=+2q zRNZw$lEJ@bVt`U%kTUU6$%Bq$%Etd!x5DHO@%Yve^A5XApL_%tI(31D$Jk2URn$-^ z+kIJayQtloe5>VzJTHn%lXzDnG0K=BnM>zjdZau+`};+#VnqEUM+TIg=i-+}qBkag z*a>q+rPQ$5nR`a_HFgWCcF5(+fxHY~8OYy){yFL3E_cf7>S5YQ^^2B&siWiYLMc-oj<;HwRd9?X5eJgDH-MK|bj2kyQ zk{N}#tjV4{*L8$JF6>{#Jd5KVq_rijB{B^bQb`$5NkO*lq&bH5bFUZ<;Nth90G?)X zs#?4hj`po)Op74#<(BqsC-^f4`?o=9%A?7S9_ph7tv5%VXxiogsVR@4sdVPbAWLd1 zPv61l2!RkW{QL-~!LUCn>GX~sT?y$Fkv*Yg5L_97Qbuf5B2K28`cSWN6?A!wCEFcw zegp`~c*lByC647@6EhOCl1&pr>7b1AL{%F~KN`?=Gk^Yj33udfaVGt6izU({md&%} z8?~cObv0`Rw>ff2v8aYY=aCM~M%6MkABd*UBpo9H2a9*7uW7q%aKOcL;$TNNc?wX1 zMqAnUg|;&lH;W)kdYx-})Q%MgLw%g0imjrLG#keB$SsoTG*$l6jWThIn`gZcs^Dm- z^W6|1*?MTi^kIT$%HA(IMv^%5TdUWQ3i}(;kI_nd^8gbbeix}bPObaSlWLDs{N*&% zw1apPNi#S=S7!K6+pM|TdOUn|NuZ`n!TJ{<>L5~?SZ^l1=%nTf%?nxIB^ij{66 zs$!~otGtKHWG{F}$$B|%qzlIJ+l+Ok5Z|4C@Y4T5)G3zg>*N%Uk*{ zu;N<=A`bmTj3gQLgH%%2M$oGdPU+ek`jH3vEi8S8#IAdCffxJ}eyE0EOm~N62 zR{1sFU+zukrBs1AQXS=-7YW7Q_3J|nk3B@r`Dv?t1bS>go%_6|5~$&wquV3>P2?90 z=+4&Y&W_yZ&0exfQ)K*&>2~=u%%8e@)1KYgc(wp6jatMPU+@*z4w*1$SReBLzJ02G z>^Z*QOSacAt)O&(>&U#iy+`ClC?Ay7rTd1r=0v7O9Oh5WL>Wz%><^<(4H3b40|vE_ z{`>~wn^=N2ic-)9yfU<%TkHzYnEp19nkyDE%7t@$(Qb*&MSI(MJBPx>xA`&z+3|4 z&l{=~Z~kZ5=;ZSJcNHm6P6@f0qiw_Vif6o?-eq2Oc;?0v{JF*N+j@KgO;rVaQ>X=L z57D+|vgu!!hqng}N}+q}(WHVz(&V2ZUc_!4>GNMg*n6#b)Jp+dT%LV6+%eLK;q<%bS> ztBiH#+WvS0?qHxsMQQDIWIIv6-A}E>1cUqAwCtTm_05Bxc(aB5j!>|!r;zwQkZ3P8 zxi{Zk<5|vYzMZBIkocC*UM3W|l?OP>3AO`=T!14YMYww4T8h>jbUji;b8kz66I4r> zi$18BS8TA-afwih!dt_$$-6y&I^DKV*aA^U@{OELAgJk#G$j|Qxy4zjez&qh1&UYY zs-CK_+}h9QhlpP*(bwxw{P*y>CM=8-W*fW5y{y2GU(s5<7jR(m>7G&n?|%PKC5luZ zmLmGr?Io<5XSyT=^8xcjei#8lK7mMo<{}K?f7F$@A1#x zoB7y?ta8VGY720DqFwWvc9&dmmt1|+A^RsmoloS}yh5brJDnF@9>N9gNNS!$wGn_Q z$jl@t)6TRi^8yiz-Xr_}8lI~QD4rDDI$}_&)?cvARU;gHpKF2#;yzIC6F9H%jS_T1 zt@WBwJKc^U%#^TeLi`<{h<%uQ=n)u+eTBF;a(Myv{ayICaqW-N0v$+ z4D#MX?#|nW6EcyR@ww!6h5i%Xw!bwP7$>d`u`j2qcJ~!&KeA?pFjDR|>voJWv%Q*| zPmPXJc)12ldwPePWx&nhQWuEF6wDDpq7tHsS+sX)#gPivB=S!LGeNHcgGZfE;2CYVPwbJB8L>4MBFHt z7VUo?QGfN&xe~9r&_`!y(?cd?x6QhlaA%jrfl)(?ocmEyz20}#KcN!EZ>LU0wd1bx zP$bhxTuZBN{7(F>cT3({e;Satj`{QgwPkAFft0(eD5HI-IqLox!%tgv3fEzez6*Of zHp{7uG2=;OBL6}Q^tE)0q75$3Iqw(vk?UJO|I2%?^de2^rg`!Ys$lQiBu2yLuR~B% z7BKSz+qB=g+4WR?cA946Jy_(M)<~+^1OAf305=p6nAsx(g*0Rr$vfGj3agzz)?q;= zmQ!_YYQiZ>q`^s(MxTU5*zPK(K!9H*<=cg7*N4kPjGfWb89GjN-bY@R^o%qdNbBvB ztiyc13Y1o0F`yv$M5Ng8oXsh02eWDDz+tc^#FTCoi)xxhzYVn)E$c41oqsR-pTMCZ zDdU?GrS!z;d3O8VQK9&S5_QQrpplD(!8oNk$1+HM#&O+xO*l+ckUm(S#3FCBWGw$? zW@u%;Ml&Xg9q2>v)d{&f3AC3zd#-)ZsczrDq*%~pQ{(A%q8e~sDtntImvn*%LMU+q zPM{OGaTHh-k^Kct1Wy4JB{ULZn2{EQa?%|vfsoBw(-2M4^j*$H$jfFWLun;igg;4l z3abrH8D9QKl{B@UU;QwM&!Pjgj0ebB6noJTx%&FSiAdynt)r#Wv;0~J+rMlk%=VS_AQ1lVZyHPxooe3~Td5)EL0Nwl2wz8tTP zcJ`u%$KFWhVbw5;kUOEwjZ6Yv0^UHnuJn^FZ#sa*^TK`CL|qKx^%AZ&*OFRu8TDt% z&5xgIKXBi7b$9OeTE0O>{g+=dDXfN!F;3AnGZ8KcakTHeouE!vRkx_5)lykzn7x+J zp!FLw%%3&vA5Yt889aZIp)J8uwiFQcJ018egXVGQS`l~ux@N{f&Bf7v@7^>W@r=tRq~8`ODxBXztl)=0=TKZVyor5_)`PT_$UInBB{g>h zl{>OEzq`ECp#V`Y@HFoW@RLUy%*imlg6_Vc;AN7 z2h&hE@2RcH8Diu&C?>z378l~DM=7oLpHC{+fsnZX$&vo?Ti?Gbiu0d=b~g6jfp9-& zGw-6=7)!@HK7|X^*ah$4$X*3puOH968(^M3gusC=_o}sd6|a1u-fUj=mnQF29ci2z8%A%tvp;tKPO@H4eD}7k zIxg&2ecwE0YdmODZo<%yKsPx>npf-z>R!w^^9L6|U4m>1f-l1JUQ)pM6iz=QCB$_Bnc*@+(@@7^UNQE zUVb^@r)^59xZ{|gzJH+jqh~cBj;6>hx7fC@xUXLu?J_>};Jvmw)fMu92IV-eF)W12 zwzYpPay7xffVGX79L285?HMXdk%{+2o7%#swdv|?hKE0Z?j>q932|YgSgOH9h#FI` z__&^m34tivI+W4;lfAKM4)JbZXqFc&&pCYpv7-HyUixdtGc&2!aQ?0HhtCS6=4TMs z`c%S#4r6Mktkdp>`11|8cNjwY( zyJ8@s=E*y=2j-Tm*X#W`+0DR{$&W_6PxhNjV^TXh*v57;tf2bi2ed6F!kAm7NtLYT z7IGwhLLakzIlR103%(^AlU7@FRIeP&`lTouzZ@N|U3qdR1-X^S2mMk0ncpup)J`!t zS)}*(Ev^?@*UYKSP+883uB*4N*Ns2ok?F>Cnb<%wA%U8buFr%~{|N)g&e4+a)Zhfo znca+f)KLg$`{~cq-20)cb}7xcR;hXf2+Pk^>0OenT1N$k8iBqHBn1FY*=ic%^qD&? zji{eGVih+wf`l1kMq$2@kfnvG3(%9mtQ3KVlDA&z+p^haC0EcTdSI?zQ!vM@ri6H3M;VD?Wiz6}Tip0Y6 diff --git a/doc/extension_system.txt b/doc/extension_system.txt new file mode 100644 index 000000000..39ab9b37d --- /dev/null +++ b/doc/extension_system.txt @@ -0,0 +1,411 @@ +== Inkscape Extensions == + +=== Introduction === + +The extensions system in Inkscape is a way for adding functionality to +Inkscape, without affecting the core of the program itself. We want +Inkscape to follow a core-plus-modules approach similar to that adopted +by many successful open source projects such as the Linux kernel, Perl, +Apache, Gimp, and so on. There are many different types of extension +mechanisms, including file format conversion tools, filter scripts that +process SVG, user interface elements that can be added at runtime, and +so forth. + +This proposal defines a design for handling this wide variety of +extensions in a flexible manner. This document provides a way to +understand the extensions system, and how extensions fit into this +overall system. + +Much of the documentation that will be useful for users of the extension +system is not included in this document, it is autogenerated from the +source code and placed on the Inkscape webpage. While this is less +convienient, it is more correct, and maintained as the source code is +modified. Please look aton the Inkscape webpage also. + + +=== Terminology === + +*Extension* - An extension is something that extends the functionality + of Inkscape without being directly part of the core. This implies + that it should be easy to remove or add, and nothing in the core should + depend on it directly. + +*Extension Type* - Establishes the functional interface that the + Extension provides, including the types of messages it handles and what + is contained in its data structures. + +*Extension Implementation* - Defines how the extension is accessed; + i.e. through message passing, pipe/exec calls with commandline + arguments, direct function calls, etc. + +*Plug-in* - An extension that is implemented through a loadable library. + This is a .so file on Unix-like systems or a .dll on Win32. The + libraries should not be loaded until they are used. + +*Script* - A script is a type of extension that is implemented through + an external program that recieves and sets SVG data through files and + pipes. This allows Inkscape to use programs that handle SVG but are + targeted differently, seemlessly inside of Inkscape. + +*Language Binding* - A special type of plug-in that wraps a scripting + language interpreter such as Perl, Python, Lisp, etc. A user + interested in programmatic access to Inkscape's internals via one of + these languages can install (or create) the relevant Language Binding + Plug-in to achieve this. + +*INX* - *'INkscape eXtension'* - The filename extension used for XML + metadata files that describe each Inkscape Extension. + +*Internal Extension* - A part of the Inkscape codebase which uses the + extension system in order to make it more modular. This code is + compiled into Inkscape, but appears as an extension to all other code + in the codebase. + + +=== Requirements === + + * Uses a general language binding system so it's easy to add new + language binding support. + * Allows direct interaction with the document object model including + changing. + * Allows some limited interaction with the Inkscape UI such as + manipulating grids, overlays, etc. + * Allows direct interaction with file load/save/export/print + subsystem. + * Guaranteed to work properly with the undo system, even if the + extension is not written carefully. + * Well documented so is easy for people to learn how to make new + extensions. + * Each extension can be implemented, distributed, and managed + independently of the core project. + * Icons, buttons, and other UI elements for extensions fit seamlessly + into main application GUI. + * User can easily select which extensions to automatically load into + application at startup. + * Loading of extensions shall not seriously slow startup time or make + a major impact on memory footprint. + * Failure of a extension shall not leave the drawing in an + inconsistent state. + * Main application must gracefully recover from extension crashes or + other serious problems with extension execution. + * Dependencies for particular extensions must be clearly identified for user if missing. + + +=== Overview === + +Different kinds of extensions can be categorized in two ways. First, +but what the extension does: File format converters, printing, SVG +manipulation, symbol libraries, etc. Second, by how the extension is +implemented: command-line scripts, dynamically loaded libraries, +internal compiled-in code, etc. + +The first kind of categorization is called the *Extension Type*. This +essentially establishes a calling interface and the set of messages the +extension must be able to receive and handle. For example, extensions +of type Print must have a way to handle 'print' message. + +The second is the *Extension Implementation*. This defines the +mechanism Inkscape must use for passing messages to the extension. For +example, commandline scripts would have messages passed as commandline +arguments, whereas loadable plug-ins would have the messages passed to +the plug-in's message handler routine. + +The categories of both Extension Types and Extension Implementations are +left open ended. This way, if someone comes up with new ideas for ways +to extend Inkscape that doesn't fit within the existing models, they can +add these mechanisms in a straightforward fashion. + +For the purposes of this document, however, we focus on just the +following Types and Implementations: + +Extension + "Input" - loading various file formats + "Output" - saving as various file formats + "Effect" - apply some sort of change to SVG elements in the doc + "Print" - prints using different drivers or modes + "Collection" - a group of objects that have thumbnails and images that + can be used inside a document. Libraries can be + searchable and may be presented in a hierarchical + structure + +"Extension Implementations" + "Internal" - code that is internal to Inkscape which uses the + extension system for some functionality + "Script" - a cmdline program that takes an SVG document to its + STDIN and emits a modified SVG document to its STDOUT, + with control messages given as commandline parameters. + + "Plug-in" - a loadable module with a message handler routine that + receives messages and that operates on the Inkscape API + functions directly. + +=== Extension System Basics === + +Leaving the topic of Types and Implementations aside, we can make some +generalizations about how all Extensions work, and behaviors or +attributes that all Extensions share. This includes how they are +registered, how they handle preferences, how dependency resolution is +achieved, and versioning. These common behaviors are all established +via a base class that all Extension Types derive from. + +=== Extension Base Class === + +The Extension base class holds the attribute data that all extensions +must have and establishes the base functionality that all extensions +share. All extensions have the following properties: + +"ID" - A unique identifier for this extension that is used for refering +to the extension and naming its parameters in the configuration files. + +"Name" - The textual name of the extension, it is used for user +interaction with the extension. It is used for users to identify the +extension. + +"Parameters" - Each extension keeps a record of all of the parameters +that it has. The can be changed internally, through a GUI, or by other +extensions. Parameters can be found and adjusted using functions that +are within the base class. + +=== Extension Registry === + +Inkscape maintains a data structure of all the registered extensions. +This registry can be queried against to retrieve lists of extensions +meeting various conditions (such as all Input extensions). + +The Extension Registry contains all extensions whether or not they +failed their dependency checking on startup. This allows for additional +information to be displayed on the reasoning behind marking the +extension as disabled. + +The registry can be reloaded from the Inkscape GUI while Inkscape is +running. This can be used to add new extensions into the system, or +help debug new extensions. When the registry is reloaded all extensions +are first unloaded, then they're specification files are re-read. + +=== Handling Preferences === + +Individual extensions can have their own preferences which are used by +the extension. These are typically attributes of the operation that can +be modified by the user through a dialog. It is also possible to have +other extensions modify these values when they are using an extension. +For most extensions, these will be edited by a dialog that relates to +the preferences of the user. + +The preferences themselves are defined in the inx file that describes +the extension. In this definition there is the name, the type, and the +default value. The types are: boolean, integer, float and string. +Other types can be developed using these as a basis. If there is no +custom value set the default value is used. + +When a value is written to a preference for an extension, that value is +saved in the global preferences for Inkscape using the ID of the module +as the basis for the naming. At next use (including after restarting +the application) this value is used instead of the default. This allows +user preferences on a extension to remain persistent throughout uses of +Inkscape. + +=== INX Files === + +The INX file is the description of the Inkscape Extension. It provides +all of the information that is used to identify the extension, and +determine what type of extension it is. This file is loaded on startup +of Inkscape, and the objects relating to the extension are created. All +extensions have an inx file, but many internal extensions compile this +file into the codebase (to reduce dependencies). + +The INX file also contains information on the dependencies that are +required for the extension to operate. These dependencies can be +everything from required files, required libraries or other extensions +that help this one. The dependencies are checked as the file is loaded, +and an extension is marked as dead if they are not met. Also +dependencies can check different versions of particular objects to see +if they are met. + + +=== Extension Types === + +Each Extension is identified by it's 'Type'. This determines the type +of programmatic interface that it adheres to, enabling Inkscape to know +what functionality it can expect from the extension. + +=== Input === + +An input extension provides a way to get data into Inkscape. This type +of extension creates a document given a filename. This is done by using +the 'open' method within the class. Also, there is a 'prefs' function +which will generate a GtkDialog. This dialog is then used to get any +settings that the incomming file and extension my use. This function is +executed, and the dialog returns, before the open method is called. + +There are also several other settings stored in an Input extension. +This includes information on the type of file the input module can take +in including its filename extension and mime type. Also, there is a +space to store a tooltip for additional information on the file type in +the file dialog. Lastly, there is the key of which Output extension is +recommended for saving this filetype. This is useful, as there is no +other direct links between the Input and Ouput functions, and a user +expects to be able to open and save without using the 'Save As...' +dialog. + +=== Output === + +An output extension controls how SVG documents are exported from +Inkscape. This type of extension creates a file given a document +object. This is done using the 'save' method within the class. + +The method for how files are exported depends on what type of +Implementation is used. For Scripts, the file is first saved as a +temporary SVG file, and then processed by calling the commandline +programs to convert it. For Plug-ins, the document object is passed to +the extension with a 'save' message and a filename, and the extension +program performs the file save operation itself. + +=== Effect === + +Effect extensions cause a modification of a loaded document. For +example, it might add a new shape to the drawing, or change all selected +objects to be purple with green dotted borders. + +=== Print === + +The Print Extension Type is for extensions that interface with printing +subsystems. Examples would be Win32, postscript, and GNOME Print. + +=== Collection === + + +=== Creating Extensions === + +In this chapter, we discuss how to create an extension from scratch, +incorporate into Inkscape, and release it for the general Inkscape +community to use. This chapter can be read independently of the rest of +the document, using the rest as reference material. + +=== Selecting an Extension Strategy === + +First of all, you will need to select the method you'll use for creating your extension. + +Scripts are the simplest extensions to create, because they work through +STDIN/STDOUT, so you need to know very little about Inkscape internals +to make them work. However, their ability to interact with the Inkscape +internals is limited compared with other approaches. For file format +converters, this is usually fine. You can also create filters programs +that take the entire document to its STDIN, process it, and return a +modified copy to STDOUT. Some control of the extension is possible via +its commandline arguments. + +One of the nice things about Scripts is that they can be written in any +language. It need not even be a scripting language - as long as it +handles STDIN and STDOUT and uses commandline arguments, you can write +it however you wish. + +Plug-ins are more powerful than Scripts, but require more knowledge of +Inkscape internals, and must be written according to specific criteria. +Generally, since these are loaded as dynamic objects, they'll need to be +written in a language that can generate them, such as C or C++. + +The best of both worlds can be available through Language Bindings, +which are Plug-ins that wrapper a script interpreter. This enables you +to call various Inkscape internal routines through your scripting +language's functions. If someone has created a Language Binding for +your language of choice, you're all set, otherwise you'll have to create +a Plug-in for it. Language Binding Plug-ins have a few more +requirements than ordinary Plug-ins, and require a greater amount of +knowledge of the Inkscape internals, so it can take quite some time to +do properly. + +Internal Extensions are in a way the reverse of a normal Extension, in +that instead of providing a way to hook into Inkscape from the outside, +they provide hooks from inside Inkscape. These are used directly by +Inkscape, such as in the case of compiled-in printing modules. Most +users will never need to write this type of extension, they are pretty +much for Inkscape core developers only. + +=== Writeing Your Extension === + +This section provides some guidance and examples for implementing +different kinds of Extensions. + +=== Writing Script Extensions === + +=== Writing Plug-in Extensions === + +=== Writing Language Binding Plug-in Extensions === + +=== Creating an INX File === + +Every extension must have a corrosponding *.inx file. This is an XML +file that provides Inkscape with information about the module and allows +it to load the info without needing to access the module itself. The +*.inx file contains enough info for Inkscape to set up menu items and +know what kinds of functionality to expect from the extension. + +=== Packaging Your Extension === + +=== Contributing Your Extensino to the Inkscape Community === + +Once your extension is complete, you may wish to share it with the +community. There are of course no hard and fast rules for how to share +your work, but this section illustrates some approaches. + +=== Listing Your Extension === + +First, you will need to put your extension someplace that others can +find and download it. If you have adequate webspace, you could simply +upload it to your web server. More typically, you will want to upload +it to a mirroring system like SourceForge (http://www.sourceforge.net), +CPAN (http://www.cpan.org), and the like. The Inkscape project may also +be willing to host your extension; contact the admins for more info. + +It can also be helpful to list your extension with one of the various +software registries, such as Freshmeat (http://www.freshmeat.net). You +should also list it on the Inkscape Wiki site. + +=== Announcing Your Extension === + +After posting your extension someplace from which it can be downloaded, +you should also announce its availability, by sending an email to +inkscape-announce@lists.sourceforge.net. You may also want to announce +it on other related sites; for instance, if you've written a plug-in to +allow operation of Imagemagick from within Inkscape, it could be a good +idea to announce it to the Imagemagick list. + + +=== Incorporating Your Extension in to Inkscape === + +Because the intent with the extension system is to break things *out* +from the core, most extensions should be packaged and distributed +independently of the main Inkscape distribution. However, for ease of +user installation, an extension-pack can be shipped along with the core +Inkscape package. Also, certain extensions may be so critical to +Inkscape operation (such as for printing) that they should be included +in the core. + +If your extension seems like it should be incorporated into the Inkscape +core, contact the Inkscape developers about this, and discuss how best +to include it in the distribution with them. + +=== Conclusion === + +It is anticipated that the incorporation of this extensions capability +will bring Inkscape added power and flexibility while avoiding bloating +the core with cool-but-rarely-used functionality. Further, it empowers +users and non-core Inkscape developers to extend the application with +their own new capabilities, without needing to gain special access and +acceptance by the project. Dynamic loading of functionality will also +allow Inkscape to remain 'lean and mean', loading up functionality on an +as-needed basis, and conserving memory by unloading functionality when +it is not needed. + +The key point of this design specification is the architectural concept +of separately identifying an extension's interface type, or 'Extension +Type', from its implementation method, or 'Extension Implementation'. +This feature enables Inkscape to be extended in a variety of mechanisms, +including ways not yet foreseen. + + +=== History and references === + +Base design taken from Ted Gould's Extension System work. + +This document originally authored by Bryce Harrington, July 2004 diff --git a/doc/extension_system.xml b/doc/extension_system.xml new file mode 100644 index 000000000..1e59eda91 --- /dev/null +++ b/doc/extension_system.xml @@ -0,0 +1,237 @@ + + + + Inkscape Extensions + + Introduction + The extensions system in Inkscape is a way for adding functionality to Inkscape, without affecting the core of the program itself. We want Inkscape to follow a core-plus-modules approach similar to that adopted by many successful open source projects such as the Linux kernel, Perl, Apache, Gimp, and so on. There are many different types of extension mechanisms, including file format conversion tools, filter scripts that process SVG, user interface elements that can be added at runtime, and so forth. + This proposal defines a design for handling this wide variety of extensions in a flexible manner. This document provides a way to understand the extensions system, and how extensions fit into this overall system. + Much of the documentation that will be useful for users of the extension system is not included in this document, it is autogenerated from the source code and placed on the Inkscape webpage. While this is less convienient, it is more correct, and maintained as the source code is modified. Please look aton the Inkscape webpage also. + + + Terminology + Extension - An extension is something that extends the functionality of Inkscape without being directly part of the core. This implies that it should be easy to remove or add, and nothing in the core should depend on it directly. + Extension Type - Establishes the functional interface that the Extension provides, including the types of messages it handles and what is contained in its data structures. + Extension Implementation - Defines how the extension is accessed; i.e. through message passing, pipe/exec calls with commandline arguments, direct function calls, etc. + Plug-in - An extension that is implemented through a loadable library. This is a .so file on Unix-like systems or a .dll on Win32. The libraries should not be loaded until they are used. + Script - A script is a type of extension that is implemented through an external program that recieves and sets SVG data through files and pipes. This allows Inkscape to use programs that handle SVG but are targeted differently, seemlessly inside of Inkscape. + Language Binding - A special type of plug-in that wraps a scripting language interpreter such as Perl, Python, Lisp, etc. A user interested in programmatic access to Inkscape's internals via one of these languages can install (or create) the relevant Language Binding Plug-in to achieve this. + INX - 'INkscape eXtension' - The filename extension used for XML metadata files that describe each Inkscape Extension. + Internal Extension - A part of the Inkscape codebase which uses the extension system in order to make it more modular. This code is compiled into Inkscape, but appears as an extension to all other code in the codebase. + + + Requirements + + Uses a general language binding system so it's easy to add new language binding support. + Allows direct interaction with the document object model including changing. + Allows some limited interaction with the Inkscape UI such as manipulating grids, overlays, etc. + Allows direct interaction with file load/save/export/print subsystem. + Guaranteed to work properly with the undo system, even if the extension is not written carefully. + Well documented so is easy for people to learn how to make new extensions. + Each extension can be implemented, distributed, and managed independently of the core project. + Icons, buttons, and other UI elements for extensions fit seamlessly into main application GUI. + User can easily select which extensions to automatically load into application at startup. + Loading of extensions shall not seriously slow startup time or make a major impact on memory footprint. + Failure of a extension shall not leave the drawing in an inconsistent state. + Main application must gracefully recover from extension crashes or other serious problems with extension execution. + Dependencies for particular extensions must be clearly identified for user if missing. + + + + Overview + Different kinds of extensions can be categorized in two ways. First, but what the extension does: File format converters, printing, SVG manipulation, symbol libraries, etc. Second, by how the extension is implemented: command-line scripts, dynamically loaded libraries, internal compiled-in code, etc. + The first kind of categorization is called the Extension Type. This essentially establishes a calling interface and the set of messages the extension must be able to receive and handle. For example, extensions of type Print must have a way to handle 'print' message. + The second is the Extension Implementation. This defines the mechanism Inkscape must use for passing messages to the extension. For example, commandline scripts would have messages passed as commandline arguments, whereas loadable plug-ins would have the messages passed to the plug-in's message handler routine. + The categories of both Extension Types and Extension Implementations are left open ended. This way, if someone comes up with new ideas for ways to extend Inkscape that doesn't fit within the existing models, they can add these mechanisms in a straightforward fashion. + For the purposes of this document, however, we focus on just the following Types and Implementations: + + + Extension Types + + + + Input + + loading various file formats + + + + Output + + saving as various file formats + + + + Effect + + apply some sort of change to SVG elements in the doc + + + + Print + + prints using different drivers or modes + + + + Collection + + a group of objects that have thumbnails and images that can be used inside a document. Libraries can be searchable and may be presented in a hierarchical structure + + + + + + + Extension Implementations + + + + Internal + + code that is internal to Inkscape which uses the extension system for some functionality + + + + Script + + a cmdline program that takes an SVG document to its STDIN and emits a modified SVG document to its STDOUT, with control messages given as commandline parameters. + + + + Plug-in + + a loadable module with a message handler routine that receives messages and that operates on the Inkscape API functions directly. + + + + + + + + + Extension System Basics + Leaving the topic of Types and Implementations aside, we can make some generalizations about how all Extensions work, and behaviors or attributes that all Extensions share. This includes how they are registered, how they handle preferences, how dependency resolution is achieved, and versioning. These common behaviors are all established via a base class that all Extension Types derive from. +
+ Extension Base Class + The Extension base class holds the attribute data that all extensions must have and establishes the base functionality that all extensions share. All extensions have the following properties: + + + ID + A unique identifier for this extension that is used for refering to the extension and naming its parameters in the configuration files. + + + Name + The textual name of the extension, it is used for user interaction with the extension. It is used for users to identify the extension. + + + Parameters + Each extension keeps a record of all of the parameters that it has. The can be changed internally, through a GUI, or by other extensions. Parameters can be found and adjusted using functions that are within the base class. + + +
+
+ Extension Registry + Inkscape maintains a data structure of all the registered extensions. This registry can be queried against to retrieve lists of extensions meeting various conditions (such as all Input extensions). + The Extension Registry contains all extensions whether or not they failed their dependency checking on startup. This allows for additional information to be displayed on the reasoning behind marking the extension as disabled. + The registry can be reloaded from the Inkscape GUI while Inkscape is running. This can be used to add new extensions into the system, or help debug new extensions. When the registry is reloaded all extensions are first unloaded, then they're specification files are re-read. +
+
+ Handling Preferences + Individual extensions can have their own preferences which are used by the extension. These are typically attributes of the operation that can be modified by the user through a dialog. It is also possible to have other extensions modify these values when they are using an extension. For most extensions, these will be edited by a dialog that relates to the preferences of the user. + The preferences themselves are defined in the inx file that describes the extension. In this definition there is the name, the type, and the default value. The types are: boolean, integer, float and string. Other types can be developed using these as a basis. If there is no custom value set the default value is used. + When a value is written to a preference for an extension, that value is saved in the global preferences for Inkscape using the ID of the module as the basis for the naming. At next use (including after restarting the application) this value is used instead of the default. This allows user preferences on a extension to remain persistent throughout uses of Inkscape. +
+
+ INX Files + The INX file is the description of the Inkscape Extension. It provides all of the information that is used to identify the extension, and determine what type of extension it is. This file is loaded on startup of Inkscape, and the objects relating to the extension are created. All extensions have an inx file, but many internal extensions compile this file into the codebase (to reduce dependencies). + The INX file also contains information on the dependencies that are required for the extension to operate. These dependencies can be everything from required files, required libraries or other extensions that help this one. The dependencies are checked as the file is loaded, and an extension is marked as dead if they are not met. Also dependencies can check different versions of particular objects to see if they are met. +
+
+ + Extension Types + Each Extension is identified by it's 'Type'. This determines the type of programmatic interface that it adheres to, enabling Inkscape to know what functionality it can expect from the extension. +
+ Input + An input extension provides a way to get data into Inkscape. This type of extension creates a document given a filename. This is done by using the 'open' method within the class. Also, there is a 'prefs' function which will generate a GtkDialog. This dialog is then used to get any settings that the incomming file and extension my use. This function is executed, and the dialog returns, before the open method is called. + There are also several other settings stored in an Input extension. This includes information on the type of file the input module can take in including its filename extension and mime type. Also, there is a space to store a tooltip for additional information on the file type in the file dialog. Lastly, there is the key of which Output extension is recommended for saving this filetype. This is useful, as there is no other direct links between the Input and Ouput functions, and a user expects to be able to open and save without using the 'Save As...' dialog. +
+
+ Output + An output extension controls how SVG documents are exported from Inkscape. This type of extension creates a file given a document object. This is done using the 'save' method within the class. + The method for how files are exported depends on what type of Implementation is used. For Scripts, the file is first saved as a temporary SVG file, and then processed by calling the commandline programs to convert it. For Plug-ins, the document object is passed to the extension with a 'save' message and a filename, and the extension program performs the file save operation itself. +
+
+ Effect + Effect extensions cause a modification of a loaded document. For example, it might add a new shape to the drawing, or change all selected objects to be purple with green dotted borders. +
+
+ Print + The Print Extension Type is for extensions that interface with printing subsystems. Examples would be Win32, postscript, and GNOME Print. +
+
+ Collection +
+
+ + Creating Extensions + In this chapter, we discuss how to create an extension from scratch, incorporate into Inkscape, and release it for the general Inkscape community to use. This chapter can be read independently of the rest of the document, using the rest as reference material. +
+ Selecting an Extension Strategy + First of all, you will need to select the method you'll use for creating your extension. + Scripts are the simplest extensions to create, because they work through STDIN/STDOUT, so you need to know very little about Inkscape internals to make them work. However, their ability to interact with the Inkscape internals is limited compared with other approaches. For file format converters, this is usually fine. You can also create filters programs that take the entire document to its STDIN, process it, and return a modified copy to STDOUT. Some control of the extension is possible via its commandline arguments. + One of the nice things about Scripts is that they can be written in any language. It need not even be a scripting language - as long as it handles STDIN and STDOUT and uses commandline arguments, you can write it however you wish. + Plug-ins are more powerful than Scripts, but require more knowledge of Inkscape internals, and must be written according to specific criteria. Generally, since these are loaded as dynamic objects, they'll need to be written in a language that can generate them, such as C or C++. + The best of both worlds can be available through Language Bindings, which are Plug-ins that wrapper a script interpreter. This enables you to call various Inkscape internal routines through your scripting language's functions. If someone has created a Language Binding for your language of choice, you're all set, otherwise you'll have to create a Plug-in for it. Language Binding Plug-ins have a few more requirements than ordinary Plug-ins, and require a greater amount of knowledge of the Inkscape internals, so it can take quite some time to do properly. + Internal Extensions are in a way the reverse of a normal Extension, in that instead of providing a way to hook into Inkscape from the outside, they provide hooks from inside Inkscape. These are used directly by Inkscape, such as in the case of compiled-in printing modules. Most users will never need to write this type of extension, they are pretty much for Inkscape core developers only. +
+
+ Writeing Your Extension + This section provides some guidance and examples for implementing different kinds of Extensions. +
+ Writing Script Extensions +
+
+ Writing Plug-in Extensions +
+
+ Writing Language Binding Plug-in Extensions +
+
+
+ Creating an INX File + Every extension must have a corrosponding *.inx file. This is an XML file that provides Inkscape with information about the module and allows it to load the info without needing to access the module itself. The *.inx file contains enough info for Inkscape to set up menu items and know what kinds of functionality to expect from the extension. +
+
+ Packaging Your Extension +
+
+ Contributing Your Extensino to the Inkscape Community + Once your extension is complete, you may wish to share it with the community. There are of course no hard and fast rules for how to share your work, but this section illustrates some approaches. +
+ Listing Your Extension + First, you will need to put your extension someplace that others can find and download it. If you have adequate webspace, you could simply upload it to your web server. More typically, you will want to upload it to a mirroring system like SourceForge (http://www.sourceforge.net), CPAN (http://www.cpan.org), and the like. The Inkscape project may also be willing to host your extension; contact the admins for more info. + It can also be helpful to list your extension with one of the various software registries, such as Freshmeat (http://www.freshmeat.net). You should also list it on the Inkscape Wiki site. +
+
+ Announcing Your Extension + After posting your extension someplace from which it can be downloaded, you should also announce its availability, by sending an email to inkscape-announce@lists.sourceforge.net. You may also want to announce it on other related sites; for instance, if you've written a plug-in to allow operation of Imagemagick from within Inkscape, it could be a good idea to announce it to the Imagemagick list. +
+
+ Incorporating Your Extension in to Inkscape + Because the intent with the extension system is to break things *out* from the core, most extensions should be packaged and distributed independently of the main Inkscape distribution. However, for ease of user installation, an extension-pack can be shipped along with the core Inkscape package. Also, certain extensions may be so critical to Inkscape operation (such as for printing) that they should be included in the core. + If your extension seems like it should be incorporated into the Inkscape core, contact the Inkscape developers about this, and discuss how best to include it in the distribution with them. +
+
+
+ + Conclusion + It is anticipated that the incorporation of this extensions capability will bring Inkscape added power and flexibility while avoiding bloating the core with cool-but-rarely-used functionality. Further, it empowers users and non-core Inkscape developers to extend the application with their own new capabilities, without needing to gain special access and acceptance by the project. Dynamic loading of functionality will also allow Inkscape to remain 'lean and mean', loading up functionality on an as-needed basis, and conserving memory by unloading functionality when it is not needed. + The key point of this design specification is the architectural concept of separately identifying an extension's interface type, or 'Extension Type', from its implementation method, or 'Extension Implementation'. This feature enables Inkscape to be extended in a variety of mechanisms, including ways not yet foreseen. + + + History and references + Base design taken from Ted Gould's Extension System work. + This document originally authored by Bryce Harrington, July 2004 + +
diff --git a/doc/fonts.txt b/doc/fonts.txt new file mode 100644 index 000000000..815e79c36 --- /dev/null +++ b/doc/fonts.txt @@ -0,0 +1,40 @@ +Remarks about fonts + +1. System-wide font sources + +Sodipodi tries to extract font information +from different sources. Depending on your library +versions, this may, or may not succeed: + +xft - It usually works, but for some fontconfig setups +compiling this in may fail. In which case there is no +fonts available. + +libgnomeprint - only libgnomeprint 2.0 works currently. + +windows font database - this, of course, is used only +under win32 + +2. User-defined fonts + +If freeType2 support is compiled in (it usually is), +you can add fonts by hand to sodipodi. This can also be +useful to define aliases etc. + +Create file $HOME/.sodipodi/private-fonts + +Add one line for each font + +filename[:face number],font name,family name + +Face number if TrueType collection face number, it can +be omitted safely. +Font and family names should be space-delimited 'true' +names of font. +Example: + +garbdi.ttf,Garamond Bold Italic,Garamond + +2003-05-14 +Lauris Kaplinski + diff --git a/doc/inkscape-shadow.README b/doc/inkscape-shadow.README new file mode 100644 index 000000000..d555fd93f --- /dev/null +++ b/doc/inkscape-shadow.README @@ -0,0 +1,63 @@ +== BLURRED SHADOWS VIA BITMAPS + +The "Make a Bitmap Copy" command (Alt+B) exports a bitmap of +the selected objects (with all other objects hidden), saves it as a +PNG file in the same directory as the document, and imports it +back into the document. + +Via prefs, you can specify an external filter that will be run on the +PNG file after it is exported but before it is imported back. I use +this for grayscaling and blurring the image to create a soft drop +shadow for any object. So for me, Alt+B creates a shadow for +selected objects, and you can set it up to work the same for you. + +The script itself is share/extensions/inkscape-shadow.sh, though +it's not integrated nto the extensions or plugin system in any way. +The script requires Imagemagick 6.x to be installed; you can +modify the script as you like, probably adapting it for effects +other than shadows. The script is Unix-only; you can create +a similar batch file for Windows if you need it (send it to us +if you do). + +To enable this, you set in your ~/.inkscape/preferences.xml: + + + +Here minsize= gives the minimum size of the generated bitmap in +pixels (regardless of the object size); alternatively you can specify +resolution= to set the constant resolution (different pixel size +for different object sizes). + +In filter=, you specify either the full path to the script, or just +"inkscape-shadow.sh" if the script is in your PATH. The script +receives the image filename as the first parameter and the +filter_param1 as the second parameter (more parameters can be +added). This particular script interprets that as the blur radius +in pixels, but of course that depends on the script you use. + +The inkscape-shadow-white.sh script is the same but creates all-white +blurred shadows ("glows") instead of all-black. + +NOTE: I'm not going to provide a GUI for the blurred shadows feature, +for these reasons: + + 1. You have to carry around the shadow PNGs along your SVG. It's + inconvenient, and the PNGs may be much larger than the SVG. + + 2. The shadows are not resolution-independent and are not updated + automatically. For all this, we need to support the gaussian blur SVG + filter (a standard SVG feature). But since we don't have any filter + support yet, hence this hack. + + 3. Both Batik and Adobe have (different) problems with displaying PNGs + with alpha transparency. (Much like the Internet Exploder - shame on + them! :) This means that while this is valid SVG, its usefulness is + pretty much limited to Inkscape only. + +Still, for those who desperately need blurred shadows right now (such +as myself), this feature works well enough. Try it out, it's fun. + diff --git a/doc/inkscape-uml.dia b/doc/inkscape-uml.dia new file mode 100644 index 0000000000000000000000000000000000000000..978a20f0fdc9cec7b7bd85f07bbc5a5f8fef804b GIT binary patch literal 7779 zcmZXZcQD-B|NrAgcZuE!qOK)~&Jsi~tFs{pR*T+Cgy_95(R*El)q8YS^qweT^%^Xq z=Ih>>-~D9f_kPTr|6cDibK3LyJm+aN?xTOd$A{UgZghi*gR6H2WjjsWHA0{+j))Z3 ztSnxS$U_8KDd0IEB7`eTCJ-ku2^N0y{j)V?(JNAd19MNzL;W^nDuz(gBxd8u)dd=T zd;g^C&3JA{X7ya%=6XL(kf@*V8)M*e>u5NY_3vLd0Xa8y((Sid`z+4jQl#mw)c=tXl^kiW}?mFvm=tesC=vn0H-(UWTA%JuwU+46qvZil$7sPpW3Qy0@&yIYP zx;pV~GqJBK96h)65HgZHZ^+Qtntd)8H0jk9c|o+2;>q{?&`j@JxBcD2@4i*C*Ny6M zIHitUxg*MM?e&|cQFoQk+1;+o4hS&gyRM(tjavEqIR7n>{y7s<6XYMTUEe|QS-)=N zPGs$IbOyXV_l@I9=Y7@0XL##%xU4~dh|&1U*U~nVJNw$*gVU!1&vS32R>yct_a7gl zN$~To%UV*d|X?jY<8+On)PcC9j+Zw;T0Wd7TViARQqhU^$NM z)vomM`^$@=%Wakq>ixe#8;4ybXI|5z2j;H#gPXSkFA&cVwvH@1{W_n%mMVeYg=OxZkG@Bwry}jV=1rx6in`R^^i<}&R4iqf@9+i1 zjS}!lis1BI`v(goAUxl)?(Y_N!q0kmS?mXb$1GO8f0jO_#-;fKzb7FARJh|jxE!%G z%%m9%s)Dfz3C8*DZlR2W+qen~zc95}tR`n}F-%d52G_??a`sV?zG~G$0F$ z4JB$9VN}!()a{1#$>PX3yvcv!_@1{rKMu@f7*Kf}X1Ji7MK~W1eX<|=dFS2Fu$F{B zs2Maat838=u3tTvqxjyUY~acfQ}~!Fy{54 zNUu%!kD75q8`oMsy#v0OiH`syo)ojgx#XCBS*j-gzClLgwbySsWQ2hfcC*r~x4VZM zR!Fs>KUlC}uU{;d#Q^YDA)6cR2>egG(5Qflogw+aVe^2u)YK+Wfap9vJ&C_?9hLrdcc!)JA%R@gyV0(HMyIYv- zAM`NF<&THSk|e6Jo1DrUBn&6l8-W4M{I6LAnaRj25ZpuAn2VVBJUbJ;pdo4C_S5QA zf)d$3=wZ}(J5(%7Ch}+ykTJA?w-kXtoZNbrQkFo>^C`s6@Y6rt<57seoYnzkjZ-eY z9y0tN3;SGii-VbY*j3q4LmT+dncp$p!X^9JEU#a9m$OhIr&NdDU@q3Y-ckSE{B!*5 z>cDFBkLn@Ag?GTOQp>MMIPr=VIAtUtuBk#kJrZE;b!t2UIZc-&j|9XH>%K;iy&*3; zKR38CAV+=m1(m=bTm%wyK|ZHZ)sgq}ihq^f!|eX#z7&C}^Q(*u(+C)Y%a*V|e4_DJ)xz3iK+>FStBUFOw+ zdE=Gl@%rX`GudkVi72Eh_1LTBTiR)ytGkE%t4qEn#%sf)6U14_^@q;%-`!4IM0&K52q`uccXPp$^Dz}GdkHsM%)<}>f!@#*43nyKT3R{Y?6-t^)ozoV~FE( zS#SpULYd+u0heQg^Cd2|?(n4BhO&N+pbzcHqd8xiE@B~&mOI**N=6ud6>@*bes?tJ zq(9vs0_H;%JfZS$-szQp%6siRX-zHvbeV#Yw5Z$}SR}M;us2Q0f4fCnr? z?7GxUP64RMvY$8TNR-7s4dMUrix1;{O85rL9>daB(4E+Fvs|{<@KwDxuZRQ87{|K`u9 zmv`pw$XQa(8l6k-I9QXc?NZn85}^5$4{Mgc$ZBUdEj^UIe|=t@?P50w$mS_&qvpS% z4|02~LK|ARAZ7ZAgy%;#cQQ3eH&zUI!M)ypa*?FL<)}`N=?=pP^K)&LLkOzUyQ^jt zbAQyb!RM~I_-e92@1ntUyfhl_|NetJ;&x^jgK%PDP|IOFzBR`ov)cNNd79s}F01@! zokVOMP`(U(0ON?QP9g?}{Ot7dk}!NWONXSiV405ZtFjx(1s4?-A7D8O?3y^b5aqIN zOukbrGAe)B2!X1M$!A4-ZnFeT8K+1ugFh-VC@xNR=z6#2V*4HAgW`5m4F5l^J}XLGLw>KQTxt7hILS_9Z{pZO$_$WX^3DNuSJe%%9z-j; z#^7R%Xh>8?*RD(j)!gtLPwNrr;LmOodT#wKIPrG~4UJNc;N$drOQr%Ww)*#3AL(~c z3~8z_aex+rQ<{Q2YIPUwuJ>!Vb!`Ak>ECKL=^Z5WSPM*W3QN;^AOmQ(ii4C1CCUw^ z^*wO2zMz+4Y>Z~gtar1UFgbUYBwh|!`Z_$C^=Bg%VWpAYK}AnN&8?#o4^#_Jn%SAt zDUefVQ7>V84@ahMzYAWnuzM-J^L+U&fSD6&ly1c@N-&K*3EczJ$78cfk5D(X}-WfJ$w+j#X>iFt$5^Zq*RA~@ySW+2NwoxP%pi$nb7vn^8 z;PjIwEy99vNq?$-m05rEqW>H#z7tj+6J3-QEQ;fi5xm6ZmOy$pD#IM-SmpTEz%T|j zEMq%lP)CoBEQj(Bh?Sw}$u%;9Yr4d6DRz?#eIxsmq_*;IzG)HYr1S5Exe;&YEsO0G zeK$xsa3OM?v@n0Xs>-8)p~=))TyDYhZ+*ymk+PD`pe1hL$^{4_C`b72t46#zE+D$!ppAzL_+`H+b z)yk4+JXP(~BA_xP3Bd|gMkcvaCkgsJ&evv=t=SDRFw#v1;2};!QYB-Bg0zIyGp9o3 zZ5%rS)f5FM_=m~$6dOrzG~4fbR(fA=6I;EjHo0@!?? z3twlK6HnQfo{3z)&%r_f+4vGDX2g4+MW7Z(9iU8ImqOy zfq<*q2Yy8Le0@=H_{B%PUHR!&rpr%zMbOI(m7f6YnI6IDK1eQ+&#B$mM@eMB2mcCr zoNHa0@ItpIoa9KvUwV;M+;Y_e+S9+OeS3n06mJ}XS`ra;i>Kw&odGC=u593n`rQAz zPC4h=pML&2myziq`It|mb+*^H-syQB*|`_H>;s5QKu?$&oOjWNrrx{(A}+$u^B?w1JRgJf@S!NcGSmM-l1&kZM*YO#&w3uZvoWwSZo%WJoabKS@X|-9V}&! zP+emNE4knAF59e^PxIzvGOI-EKBjD{PEsnC&=x&j-=!^SRyt%E3o9KgpO8+xzT9<^ zj1Lh4ywja4tJH!NA`}=R6lSkNyh}6JyH!H*v_9f@x_W>khMTZ~Ra);*OV)5k+u=8j z0HSMq+e~>>r4~-5mdDu1)-`6Ka{X?e8hcF9_nv+Wkp1xAMUVRD9(0MlmW}*65yuO? z^DXSJhG=TKJ)O5VrQqL!ccJr||8I`|9jK2x)3+@i->0zzy@4ZPXc;1ALLskLHYo2g zsQbZsi?93>=Q4tS&Noprn!-u`jE7b7Yqa2Dm2|lZmWzF4_qc-cx6Ug8;$+9l+126Z z-K=21R<;{~#=u)KGEV{1b&N|w23MSwf&Kd1^MLpTx}UI#P))(=&NQn9!ON3BbFeLdiismJQOy4Iyu%F08kt5kv{B3PjE$fy(wF77EAPVHyc zg-Se_RL+AcwokFRu%5}$jT}(CO)Uf}<{~G5UTv1`TH+_MLm~vWx17W=hlh|l2g_{f z)G={JWB$7<%e?0H3vK(BzsYx3+4oH$2?!>r3^FJMi;F;;vZ$B1=;|zfB1mv|#?ye7 zh#{h?6f?Zfj+&)*w`a7if&Yj<)>@Lj9>(NBrRY-mqzPZjgBJIvKX?$?P=mx_#rw%%$_`q!+p=O?tfK7*dMRfMz4bVIF{e z-MRAKiSovA)v_>hi++ca&(USr8-UtA%pTz?pl*8BWDpKlwkTkhQ%DzA z522w@UDV|UC66n{I+lAc8z_XYS~26eZeO6yLp|B1qhads;colj)DBsgU|57uf+iwa zVDfy zTrhv+|0UI&PpW@nKsb8P2g~9MH#LhjMsJ$Y7jGdpLg9ymo9((6r)F7K`b=5ADg4A% zsGGuM_~px13~mEkwr4rCPyPLf(T1sN^5-r`wS+F`7EYe|pNgXR8~Dy`x#WpBNM`qc zY;%ycD{f+-T-hliNh9;Pk{1rr<)3zOdfes~qz5|IxTBJ}Gw}`n(%m#F(baT+{n{bx z#-6Ra_v6itRBwIVsG+nKCkebpbT4G-|=w!lB%ngew3JzI*_H2f9&c`L= z)G6^Y4Yi}et|r6OKUKm;X)G+kd;>#P@%%~HmGg0Eb3W#U0k1zBp?oYypw|G?bQY(OZkP3t@v>d7JL9IP|p;Q6D(8jyctzd~j ziJjD|2n}q=OMF*jwJt`gG$@qkn586+GD3?IShHf^T$yQd8#Hc@Ra9}SRu2F!y82VS zF@kbxeZXi zDd(vJtZ3_Z)|mBH9rfLKKe=?r5Lg-Wp@L|rzBZf9p$IE@1A>w;3Rwq;9>?pKC7Id0 zyg|aEs@Hd%IQ||eF%5;zYe_^R7Ke*D^`y&xD(2jdS`Ph(XiBjz$4z~T3h$Azo@zOU zCN~}3hj^<#vgbwE#4?Nejp>48aH{r%R=@KgOcWlKcJ`hdfTacSiZ+k{$O@)19*DGY6bz{$NAB>#KKDV=)DL85D6;Vt!cnd z9;BANzUliY(Wa||Fp(j*j+lL@@pF_f&HPBSiEx%LOYpzH(McC^N_z`O!MyJU#0FX55b=!w8x|xzEutVe-V7B zA9Wn7fc8i!gmaUoJ>fr|P;`q=YsAIlq4m~n1|1t2FaY9h%(mKXcH$|1G7pYaRmPl(jPewpXj*PU2zr&AA^9jI7Bg*q2o=7_(6@kR?{|e!{#rR=krgCDhVyv zxBt+W9Teg?;3089_?za7I6r*d8pjoL&v;_dtjJq;to zyB|v);7esy@6cHC6l4)TP$-LbiMOR^e0Q0tU|aRw(CV$|yJ=>xSDV1RB+c7{^%?8< z=EPdqLfj{O>TvHdg)UsA=9Hdln6T{G$mSk88X8wXMTz3g#=q z|G6w^ERxoPnpVhfDmLW@g_iCTMBA`Xh1e@6Nx{Q~vH*Om|GH=n3*tokTap#Tupr7) z5Nk`BP^ZRFqoybJ>>8BwvScg1aq?sgJQCeQ2`ir@a|BJ^iOk`vmCb1qrozgzF~!hA zGr21oj^2c@2N(LEBR)Kf`H%~8QS;Rt8;F~p8ui#vVplA0(jZ7+9`2ipreeTcusQsT zi+p*0O#Iqjf1fHQ>`!_PTlwxBKI_n?oJ6kpE}Br8cKvh!f|}+}TIDYfJxp@VmU}$& zG$s>#-E5b^Fjy&P5{F`>LM$vkx#@s2uwK#6u~PFa*q%j8+5ScfpnI*`nfW1C$_ogF zV)Fh^X_|^{MW)6F9adxNoDT5i|jN=O07%56* z!Nh)x?Ii1yt`5Mu#(5X~^{v)WX&k|=zzMqC}Bhmh_ntiRxiOxtx@>g{e2sD`;z#k_+WbE94_^4UR| z{lrP}`M!OhY>6p`_f&Fz5#Q%FO{7RRiygyTU7D<1P^*~3X&t0|yz{t`3qVt7XPp(g z1%%)LA@X77gdEh#v*DFAzr7Twfx5MvU#JC5-VP=O&V5W5ygCBD>}^p^`g4*T#+Fs3t_ zn!xQXj*IY`ECIIv!%b&tt|>pQz#m*N5UNwz>_mJrr+H(i^XYHs=5RtOZrD`#q>sIm z*f%#f-mgRm8cI9(b$Dn%Ms>h4@M_`tfb4(td=zZ7jIW7~9oE)8mk5Tw3#Z+fgT)v3 zxY!>lf%_U$QM>gJQ`LVIpC?3)htCp_Wed$1Twj_N_>q&E@S-?mW}V9`2s*A@a2r^} zpc9Qp>FA`Dcl4(Cg0fXCdx4iHqHx-*PFI(1Tgu2j#cV@3Ot_IoRUs=TEGx$KA_U8S z%5uYR=BMf_*JG}R8&ZyP_i?%j#inoBjmwu7D|Qx{vvWf&5t;s8r3E_n;L)5h5~r*{ zDI`|m1dM*1(zl^aKVgq?-KxVVc#c;>ZkJy!!@Hjozu6-On`PuJ!i20i>jtA@J!?;4FD~sFX z>b`8+>n#JV)q`x z>IzGPw;OM60-hWAgilt)%5Lfu{6!P)+<)Rd2P^JdAf}OZ4dvA?sKgGGca_K>&7|<& zdr+h3A5V!ldA~25QwKlHrToTHir_~6l^ATRj267W9LeH$5EJx63#Al1*fXs3QQJNK zopTD&fJ;A@I8k1l*U|wxFN1iWhcJXG6Iw}Gf>Gr0&m|OSR7Q+z$p3yoiG1+|;TQ~q zEGB9&QViW`xuta?nuCO~8idGTgb)GpBl`*zzk8Bx=S4%&Z5h?gh6DWqys0j=G0{+C zAj%x_WeSW9YgS?L*^r98#rOYj~O`Tj++AsPOP9^_9$h|Eb#KgB~a^;In@6 Sewyi>^zy5fs~DEYkNyu!{Zc3Z literal 0 HcmV?d00001 diff --git a/doc/keys-html.xsl b/doc/keys-html.xsl new file mode 100644 index 000000000..c42e79059 --- /dev/null +++ b/doc/keys-html.xsl @@ -0,0 +1,182 @@ + + + + + + + +Do not edit this file. +It is generated automatically from doc/keys.xml by doc/keys-html.xsl. + + +
+Inkscape keys and mouse reference + + + + + + +
+ +

+ Valid HTML 4.0! +

+ + + + + + +

+
+ + + + + + + + + + + + +

+ +
+ + +

+
+ + + + + + + + + + +, + + + + + + + + + + + + + + + + + + + + + + + + +Shift+ + + + +Ctrl+ + + + +Alt+ + + + +Left + + + +Right + + + + + + + +arrows + + + +Up arrow + + + +Down arrow + + + +Left arrow + + + +Right arrow + + + +Up arrow + + + +Down arrow + + + +mouse wheel + + + +mouse drag + + + +click + + + +middle button drag + + + +middle click + + + +right button drag + + + +right click + + + \ No newline at end of file diff --git a/doc/keys-svg.xsl b/doc/keys-svg.xsl new file mode 100644 index 000000000..688356666 --- /dev/null +++ b/doc/keys-svg.xsl @@ -0,0 +1,1315 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Do not edit this file. +It is generated automatically from doc/keys.xml by doc/keys-svg.xsl. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + click + + + + + + + + + + drag + + + + + + click + + + + + + + + + drag + + + + + + + click + + + + + + + + + + + drag + + + + + + + + + + wheel + + + + + + + + + + + + + + + + + + + + + + Shift + + + + + Ctrl + + + + + Alt + + + + Left + + + + Right + + + + + + + + + + + + + + + + + + + + + + + + + + + arrows + + + + + + + + + + + + + + + + up + + + + + + + down + + + + + + + + + left + + + + + + + right + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +0.4 +1.0 + + + + , + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/doc/keys.README b/doc/keys.README new file mode 100644 index 000000000..7a71c758a --- /dev/null +++ b/doc/keys.README @@ -0,0 +1,26 @@ +To generate HTML and SVG files from keys.xml, you'll need an XSLT +processor. Any decent XSLT 1.0 or XSLT 2.0 processor should work. For example: + +I. Using xsltproc (available on most Linux systems): + +xsltproc keys-html.xsl keys.xml > keys.html +xsltproc keys-svg.xsl keys.xml > keys.svg + +II. Using Saxon (a Java processor that works on any Java-supporting platform): + +1. Install Java + +2. Install Saxon (http://saxon.sf.net) so that saxon.jar is in your Java classpath + +3. Run: + +java net.sf.saxon.Transform doc/keys.xml doc/keys-svg.xsl > icons/keys.svg +java net.sf.saxon.Transform doc/keys.xml doc/keys-html.xsl > doc/keys.html + +(for Saxon 7.*) or + +java com.icl.saxon.StyleSheet doc/keys.xml doc/keys-svg.xsl > icons/keys.svg +java com.icl.saxon.StyleSheet doc/keys.xml doc/keys-html.xsl > doc/keys.html + +(for Saxon 6.*) + diff --git a/doc/keys.fr.html b/doc/keys.fr.html new file mode 100644 index 000000000..f428e3737 --- /dev/null +++ b/doc/keys.fr.html @@ -0,0 +1,903 @@ + +Inkscape keys and mouse reference

+Sauf mention contraire, les touches du pavé numérique (Début, Fin, +, -, les flèches et les chiffres par exemple) sont supposées se comporter comme des touches normales. Se référer au wiki, sur la page KeyboardShortcutsToDo (en anglais), pour voir la discussion sur les autres raccourcis que nous prévoyons d'instaurer; vous pouvez y laisser vos idées et requêtes. +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Outils

F1, +ssélecteur
Espacesélecteur (temporaire)
Espace bascule temporairement vers le sélecteur. Espace de nouveau rebascule vers l'outil précédent.
F2, +nnœud
F3, +zzoom
F4, +rrectangle
F5, +eellipse/arc
F6, +pcrayon (main levée)
Shift+F6, +bstylo (Bézier)
Ctrl+F6, +plume calligraphique
F7, +dpipette
F8, +ttexte
F9, +ispirale
Shift+F9, +*étoile
Un double clic sur le bouton d'un outil ouvre la boîte de dialogue des préférences à l'onglet de l'outil correspondant. +

Fichier

Ctrl+Ncréer un nouveau document
Ctrl+Oouvrir un document SVG
Shift+Ctrl+Eexporter en PNG
Ctrl+Iimporter un bitmap ou SVG
Ctrl+Pimprimer le document
Ctrl+Ssauver le document
Shift+Ctrl+Ssauver sous un autre nom
Ctrl+Qquitter Inkscape

Fenêtre

Ctrl+R(dés)afficher les règles
Ctrl+B(dés)afficher les barres de défilement
F11(dés)afficher en plein écran
F10menu principal
Les menus peuvent aussi être activés en appuyant simultanément sur Alt et la lettre soulignée dans le nom du menu.
Shift+F10, +right clickmenu contextuel
Ctrl+F4, +Ctrl+Wfermer la fenêtre (document)
Quitte Inkscape si la fenêtre courante est le seul document ouvert.
Ctrl+Tabfenêtre (document) suivante
Shift+Ctrl+Tabfenêtre (document) précédente
Permet de circuler entre les fenêtres (documents) en avant ou en arrière.

Dialogues

Shift+Ctrl+FRemplissage et contour
Shift+Ctrl+TTexte et police
Shift+Ctrl+MTransformer
Shift+Ctrl+AAligner et distribuer
Shift+Ctrl+OPropriétés de l'objet
Shift+Ctrl+XEditeur XML
Shift+Ctrl+DPréférences du document
Shift+Ctrl+PPréférences d'Inkscape
Shift+Ctrl+EExporter en PNG
Ctrl+FRechercher
Shift+Alt+BVectoriser un bitmap
Ces raccourcis ouvrent si nécessaire une nouvelle boîte de dialogue, sinon réactivent la boîte correspondante.

(dés)Afficher

F12(dés)afficher les boîtes de dialogue
Masque temporairement les boîtes de dialogue ouvertes. Un appui de plus sur F12 les rend de nouveau visibles.

Dans une boîte de dialogue

Escretourner au canevas
Ctrl+F4, +Ctrl+Wfermer le dialogue
Tabpasser au champ suivant
Shift+Tabpasser au champ précédent
Entréevalider la nouvelle valeur
Valide la nouvelle valeur entrée dans un champ et retourne au canevas.
Ctrl+Entréedéfinir la valeur d'un attribut (éditeur XML)
Valide la nouvelle valeur d'un attribut dans l'éditeur XML (comme cliquer sur le bouton "Définir l'attribut".
Espace, +Entréeactiver le bouton ou la valeur d'une liste.
Ctrl+Préc., +Ctrl+Suiv.naviguer parmi les onglets d'un dialogue

Contrôle

La barre de contrôle en haut de la fenêtre document affiche des champs et des contrôles pour chacun des outils.
Alt+Xaller au premier champ
Entréevalider la nouvelle valeur
Valide la nouvelle valeur entrée dans un champ et retourne au canevas.
Escannuler les modifications, retourner au canevas
Annule la modification d'un champ et retourne au canevas.
Ctrl+Zannuler les modifications
Annule la modification d'un champ mais reste dans ce champ.
Tabpasser au champ suivant
Shift+Tabpasser au champ précédent
Permet de naviguer entre les différents champs de la barre de contrôle (les modifications du champs quitté sont validées).

Modification des valeurs

Up arrow, +Down arrowmodifier la valeur de 0.1
Préc., +Suiv.modifier la valeur de 5.0

Canevas

Zoom

=, ++zoommer
-dézoommer
Les touches +/- du pavé numérique permettent de zoommer même pendant l'édition d'un objet texte.
middle click, +Ctrl+right clickzoommer
Shift+middle click, +Shift+right clickdézoommer
Ctrl+mouse wheel(dé)zoommer
Alt+Zactiver le champ de zoom
Le champ zoom dans le coin inférieur gauche de la fenêtre vous permet de spécifier précisément la valeur de zoom.

Zooms prédéfinis

1zoommer à 1:1
2zoommer à 1:2
3zoommer sur la sélection
4zoommmer sur le dessin
5zoommer sur la page
Ctrl+E, +6zoommer sur la largeur de page

Historique du zoom

`(guillement inversé) zoom précédent
Shift+`zoom suivant
Ces raccourcis permettent de naviguer parmi les différents niveaux de zoom utilisés pendant la session.

Défilement

Ctrl+arrowsfaire défiler le canevas
Ces raccourcis peuvent être accélérés, par une répétition rapide ou un appui continu
middle button dragfaire défiler le canevas
Shift+right button drag, +Ctrl+right button dragfaire défiler le canevas
mouse wheelfaire défiler le canevas verticalement
Shift+mouse wheelfaire défiler le canevas horizontalement

Guides et grille

mouse dragcréer un guide en le tirant depuis une règle
Cliquer-déplacer d'une règle vers le canevas pour créer un nouveau guide. Déplacer un guide vers la règle pour le supprimer.
|, +Shift+\(dés)activer affichage et collage des guides
Pour des valeurs différentes d'affichage/collage des guides, les régler dans les Préférences du document.
Lors de sa création par cliquer-déplacer depuis une règle, l'affichage et le collage des guides sont activés.
#, +Shift+3(dés)activer affichage et collage de la grille
Pour des valeurs différentes d'affichage/collage de la grille, les régler dans les Préférences du document.
Notez que seule la touche 3 du clavier principal a une action, pas celle du pavé numérique.

Calques

Shift+Préc.déplacer au calque supérieur
Shift+Suiv.déplacer au calque inférieur
Ces commandes déplacent les objets sélectionnés d'un calque à un autre.
Shift+Ctrl+Préc.monter le calque
Shift+Ctrl+Suiv.descendre le calque
Shift+Ctrl+Débutmonter le calque au premier plan
Shift+Ctrl+Findescendre le calque à l'arrière plan
Ces commandes déplacent le calque courant parmi sa hiérarchie (normalement d'autres calques)

Objet

Annuler/refaire

Shift+Ctrl+Y, +Ctrl+Zannuler
Shift+Ctrl+Z, +Ctrl+Yrefaire

Presse-papiers

Ctrl+Ccopier la sélection
Copie la sélection dans le presse-papiers Inkscape (et aussi dans le presse-papiers système pour les textes).
Ctrl+Xcouper la sélection
Fonctionne comme un "copier la sélection" suivi de la suppression de la sélection.
Ctrl+Vcoller le presse-papiers
Ceci place les objets du presse-papier sous la souris, ou au centre de la fenêtre si la souris est hors du canevas.
Lors de l'édition d'un texte avec l'outil texte, colle le texte du presse-papiers système dans l'objet texte courant.
Ctrl+Alt+Vcoller sur place
Ceci place les objets du presse-papiers au même emplacement que lors de leur copie.
Shift+Ctrl+Vcoller le style
Ceci applique le style du premier des objet copiés à la sélection courante.

Dupliquer

Ctrl+Ddupliquer la sélection
Les nouveaux objet(s) sont placés exactement au même endroit, au dessus des originaux et sont sélectionnés.

Cloner

Alt+Dcloner l'objet
Un clone peut être déplacé/redimensionné/tourné/incliné indépendament, mais reçoit ses tracé/remplissage/contour de l'original.
Le clone est placé exactement au même endroit, au dessus de l'original et est sélectionné.
Vous ne pouvez cloner qu'un objet à la fois; si vous voulez cloner plusieurs objets ensemble, groupez-les puis clonez le groupe.
Shift+Alt+Ddélier le clone
Délier un clone supprime le lien vers son original, le clone devenant alors une simple copie.
Shift+Dsélectionner l'original
Après sélection d'un clone, cette commande sélectionne l'objet original dont le clone est issu.

Bitmaps

Alt+Bcréer une copie bitmap
Exporte en PNG les objet(s) sélectionnés (les autres objets étant masqués) dans le répertoire du document et réimporte ce PNG.
Le bitmap (PNG) importé est placé exactement au même endroit, au dessus de la sélection originale, et est sélectionné.
Shift+Alt+Bvectoriser le bitmap
Ceci ouvre la boîte de dialogue vectoriser un bitmap, vous permettant de convertir une image bitmap en chemin.

Motif

Alt+Iobjet en motif
Ceci convertit la sélection en un rectangle rempli avec la sélection comme motif de remplissage.
Shift+Alt+Imotif en objet
Sépare tout objet sélectionné rempli avec un motif en deux objets : ce même objet sans remplissage et le motif seul.

Grouper

Shift+Ctrl+U, +Ctrl+Ggrouper les objets sélectionnés
Ctrl+cliquer permet de sélectionner des objets au sein d'un groupe.
Shift+Ctrl+G, +Ctrl+Udégrouper les groupe(s) sélectionnés
Retire un niveau de regroupement; répéter plusieurs fois Ctrl+U permet de dégrouper des groupes imbriqués.

Ordre-Z (superposition)

Débutmonter la sélection au premier plan
Findescendre la sélection à l'arrière plan
Préc.monter la sélection d'un cran
Suiv.descendre la sélection d'un cran

Chemin

Convertir en chemin

Shift+Ctrl+Cconvertir les objet(s) sélectionnés en chemin
Ctrl+Alt+Cconvertir les contour(s) sélectionnés en chemin

Booléens

Ctrl++union
L'union combine plusieurs objets en un seul chemin, fusionnant les recouvrements.
Ctrl+-différence
La différence s'applique à deux objets, extrayant celui du dessus de celui du dessous.
Ctrl+*intersection
L'intersection crée un chemin représentant l'intersection des objets sélectionnés.
Ctrl+^exclusion (ou exclusif)
L'exclusion est similaire à l'union, mais ne s'applique qu'à deux objets et supprime les recouvrements.
Ctrl+/division (coupe)
La division découpe l'objet du dessous en morceaux selon l'objet du dessus, et préserve ses remplissage et contour.
Ctrl+Alt+/découpe des chemins
Découper en chemin découpe le contour de l'objet du dessous aux points d'intersection avec celui du dessus.
Le résultat est sans remplissage.
Le résultat d'une union/différence/intersection/exclusion hérite de l'attribut id (et donc des clones) de l'objet du dessous.
Les division et découpe en chemin peuvent produire plusieurs objets. L'un d'eux, au hasard, hérite de l'id de l'objet du dessous.

Offsets

Ctrl+(éroder le chemin
Ctrl+)dilater le chemin
La distance d'offset par défaut est de 2 px (en pixels SVG, pas en pixels à l'écran).
Alt+(éroder le chemin d'1 pixel
Alt+)dilater le chemin d'1 pixel
Shift+Alt+(éroder le chemin de 10 pixels
Shift+Alt+)dilater le chemin de 10 pixels
Le déplacement réel des pixels dépend du niveau de zoom. Zommer pour ajuster plus finement.
Toutes les commandes (, ) convertissent l'objet en chemin si nécessaire, et produisent un chemin normal.
Ctrl+Jcréer un offset dynamique
Ctrl+Alt+Jcréer un offset lié
Ces commandes produisent un objet offset (autonome ou lié à l'original) que l'on peut éditer avec l'outil nœud. +
Shift+Dsélectionner l'objet source
Après sélection d'un offset lié, cette commande sélectionne l'objet original dont il est issu.

Combiner

Ctrl+Kcombiner les chemins
Cette commande est différente de grouper : des chemins combinés créent un objet, pas un groupe.
Différente aussi d'une union : les recouvrements ne sont pas affectés..
Le remplissage des recouvrements est géré par le champ remplissage (complet/alternatif) du dialogue Remplissage et contour.
Shift+Ctrl+Kséparer les chemins
Sépare les sous-chemins d'un chemin composé; ceci échouera si l'objet est constitué d'un seul chemin.

Simplifier

Ctrl+Lsimplifier
Simplifie les chemin(s) sélectionnés en supprimant quelques nœuds. Si nécessaire, les objets sont convertis en chemins.
En invoquant cette commande plusieurs fois de suite rapidement, elle agira de plus en plus agressivement.
Le seuil par défaut (réglable dans les préférences d'Inkscape) est restauré après une pause.

Sélecteur

Sélection au clavier

Tabsélectionner l'objet suivant
Shift+Tabsélectionner l'objet précédent
Sélectionne les objets selon leur ordre-z (Tab circule de l'arrière au premier plan, Maj+Tab fait l'inverse).
A moins d'avoir fait des réarrangements manuels, le dernier objet créé est au tout premier plan
Aussi, si rien n'est sélectionné, Maj+Tab est une façon pratique de sélectionner le dernier objet créé.
Cette commande s'applique aux objets du calque courant (sauf modification des préférences).
Ctrl+Atout sélectionner (calque courant)
Cette commande s'applique aux objets du calque courant (sauf modification des préférences).
Ctrl+Alt+Atout sélectionner (tous les calques)
Cette commande s'applique aux objets de tout calque visible et déverrouillé.
!inverser la sélection (calque courant)
Inverse la sélection (désélectionne ce qui était sélectionné, et sélectionne tout le reste) du calque courant.
Alt+!inverser la sélection (tous les calques)
Inverse la sélection dans tout calque visible et déverrouillé.
Escdésélectionner
Backspace, +Suppr.supprimer la sélection

Déplacement au clavier

arrowsdéplacer la sélection par incrément(s)
Shift+arrowsdéplacer la sélection de 10x l'incrément
L'incrément de déplacement par défaut est 1mm.
Alt+arrowsdéplacer la sélection d'1 pixel
Alt+Shift+arrowsdéplacer la sélection de 10 pixels
Le déplacement réel à l'échelle du pixel dépend du niveau de zoom. Zommer pour déplacer plus finement.

Rotation au clavier

[, +]tourner la sélection par incrément(s)
L'incrément de rotation par défaut est 15°. ] tourne en sens horaire, [ en sens anti-horaire.
Ctrl+[, +Ctrl+]tourner la sélection de 90 degrés
Alt+[, +Alt+]tourner la sélection d'1 pixel
La rotation réelle à l'échelle du pixel dépend du niveau de zoom. Zommer pour tourner plus finement.

Redimensionnement au clavier

., +>agrandir la sélection par incrément(s)
,, +<rétrécir la sélection par incrément(s)
L'incrément de redimensionnement par défaut est de 2 px (en pixels SVG, pas en pixels à l'écran).
Ctrl+., +Ctrl+>agrandir la sélection à 200%
Ctrl+,, +Ctrl+<rétrécir la sélection à 50%
Alt+., +Alt+>agrandir la sélection d'1 pixel
Alt+,, +Alt+<rétrécir la sélection d'1 pixel
Le redimensionnement réel à l'échelle du pixel dépend du niveau de zoom. Zommer pour dimensionner plus finement.
Le redimensionnement est uniforme autour du centre : il est donc appliqué à la plus grande des deux dimensions.

Retournement au clavier

hretourner la sélection horizontalement
vretourner la sélection verticalement

Sélection à la souris

clicksélectionner un objet
En cliquant (bouton gauche) sur un objet, la sélection précédente est desélectionnée.
Shift+clickalterner la sélection
Maj+cliquer ajoute un objet à la sélection courante s'il n'était pas sélectionné, le retire sinon.

Sélection dans un groupe, en-dessous

Ctrl+clicksélectionner dans un groupe
Sélectionne l'objet sous le curseur, quel que soit le groupe auquel cet objet peut appartenir.
Ctrl+Shift+clickalterner la sélection (dans un groupe)
Alt+clicksélectionner en-dessous
Sélectionne l'objet (sous le curseur) juste en dessous (dans l'ordre-z) l'objet sélectionné le plus bas.
Si l'objet le plus en bas atteint, un Alt+Cliquer de plus sélectionne l'objet au premier plan, circulant ainsi dans l'ordre-z.
Sous Linux, Alt+cliquer et Alt+cliquer-déplacer peuvent être préemptés par le gestionnaire de fenêtre.
Reconfigurez celui-ci afin de pouvoir utiliser ces raccourcis dans Inkscape.
Shift+Alt+clickalterner en-dessous
Ctrl+Alt+clicksélectionner en-dessous, dans des groupes
Shift+Ctrl+Alt+clickalterner en-dessous, dans des groupes

Bande étirable

mouse dragsélectionner plusieurs objets
Cliquer-déplacer autour d'objets les sélectionne par bande étirable; la sélection précédente est désélectionnée.
Shift+mouse dragajouter des objets à la sélection
Normalement, vous devez commencer une bande étirable sur une zone vide.
Mais, en appuyant sur Maj avant, Inkscape effectuera une zone étirable, même si elle commence sur un objet.

Déplacement à la souris

mouse dragsélectionner + déplacer
Cliquer-déplacer sur un objet le sélectionne s'il n'était pas sélectionné, puis déplace la sélection.
Alt+mouse dragdéplacer la sélection
Déplace la sélection courante (sans sélectionner ce qui est sous le curseur), quel que soit le point de départ.
Sous Linux, Alt+cliquer et Alt+cliquer-déplacer peuvent être utilisés par le gestionnaire de fenêtre.
Reconfigurez celui-ci afin de pouvoir utiliser ces raccourcis dans Inkscape.
Ctrl+mouse dragrestreindre à un mouvement vertical/horizontal
Shift+mouse dragdésactiver temporairement le collage
Désactive temporairement le collage à la grille ou aux guides lors de déplacements (grille/guides étant actifs).
mouse dragEspacetamponner une copie
Lors de déplacements/transformations à la souris, un appui sur la barre d'espace dépose une copie de l'objet sélectionné.
Vous pouvez maintenir la barre d'espace appuyée lors d'un déplacement pour obtenir une belle "trainée".

Transformation à la souris

clickalterner poignées arrondi/redimensionnement
mouse dragredimensionner
S'applique aux poignées de redimensionnement.
mouse dragtourner ou incliner
S'applique aux poignées de rotation/inclinaison.

Poignées de redimensionnement

Ctrl+mouse dragredimensionner en préservant le ratio
Shift+mouse dragtransformation symétrique
Appuyer sur Maj pendant une transformation rend cette transformation symétrique autour du centre de la sélection.
Alt+mouse dragmouvement lent
Force un ralentissement des mouvements de la souris, permettant ainsi des modifications plus fines.

Poignées de rotation

Ctrl+mouse dragincliner et étirer
Appuyer sur Ctrl tout en déplaçant une poignée d'inclinaison (pas un coin) permet d'étirer tout en inclinant.
Ctrl+mouse dragtourner la sélection par incrément(s)
L'incrément de rotation par défaut est 15 degrés.

Annuler

Escannuler bande étirable/déplacer/transformer
Un appui sur Esc (le bouton de la souris étant encore pressé) annule la bande étirable, le déplacement ou la transformation.

Main levée

mouse dragdessiner une ligne à main levée
Shift+mouse dragdésactiver temporairement le collage
Désactive temporairement le collage à la grille ou aux guides lors de déplacements (grille/guides étant actifs).
aalterner créer/prolonger
Alterne entre créer une nouvelle ligne et prolonger la ligne sélectionnée (des ancres sont affichées en mode prolonger).

Bézier

Créer des nœuds

clickcréer un nœud anguleux
mouse dragcréer un nœud de Bézier avec 2 poignées
Shift+mouse dragne déplacer qu'une poignée
Ceci ne déplace qu'une poignée (au lieu des deux), pour créer un nœud dur.
Ctrl+mouse dragtourner la poignée par incrément(s)
L'incrément de rotation par défaut est 15 degrés.

Créer des segments

Ctrl+tourner le segment par incrément(s)
+Ceci force la rotation d'un nœud (nouvel angle relativement au nœud précédent) par incrément(s) (15 degrés par défaut) .

Terminer

Entréeterminer le tracé courant
right clickterminer le tracé courant
clickclickterminer le tracé courant
Entrée, clic-droit ou double-clic terminent la ligne courante, annulant le dernier segment non fini (en rouge).

Clavier

Escannuler le tracé courant
Backspaceeffacer le dernier segment du tracé courant
aalterner créer/prolonger
Alterne entre créer une nouvelle ligne et prolonger la ligne sélectionnée (des ancres sont affichées en mode prolonger).

Calligraphie

mouse dragtraver une ligne calligraphique
, +ajuster la largeur de la plume
Up arrow, +Down arrowaduster l'angle de la plume
La largeur et l'angle de la plume peuvent être ajustés tout en dessinant.

Nœud

Sélection au clavier

Tabsélectionner le nœud suivant
Shift+Tabsélectionner le nœud précédent
Ces raccourcis vous permettent de sélectionner n'importe quel nœud du chemin sélectionné.
Ctrl+Asélectionner tous les nœuds du chemin
Escdésélectionner tous les nœuds

Déplacement au clavier

arrowsdéplacer les nœuds sélect. par incrément(s)
Shift+arrowsdéplacer les nœuds sélect. de 10x l'incrément
L'incrément de déplacement par défaut est 1mm.
Alt+arrowsdéplacer les nœuds sélectionnés d'1 pixel
Alt+Shift+arrowsdéplacer les nœuds sélectionnés de 10 pixels
Le déplacement réel à l'échelle du pixel dépend du niveau de zoom. Zommer pour déplacer plus finement.

Rotation des poignées au clavier

[, +]tourner les deux poignées par incrément(s)
L'incrément de rotation par défaut est 15 degrés. ] tourne en sens horaire, [ en sens anti-horaire. Applicable à plusieurs nœuds.
Left Ctrl+[, +Left Ctrl+]tourner la poignée gauche par incrément(s)
Right Ctrl+[, +Right Ctrl+]tourner la poignée droite par incrément(s)
Left Alt+[, +Left Alt+]tourner la poignée gauche d'1 pixel
Right Alt+[, +Right Alt+]tourner la poignée droite d'1 pixel

Redim. des poignées au clavier

<, +>redim. les deux poignées par incrément(s)
L'incrément de redimensionnement par défaut est de 2 px (en pixels SVG, pas en pixels à l'écran). Applicable à plusieurs nœuds.
Left Ctrl+<, +Left Ctrl+>redim. la poignée gauche par incrément(s)
Right Ctrl+<, +Right Ctrl+>redim. la poignée droite par incrément(s)
Left Alt+<, +Left Alt+>redimensionner la poignée gauche d'1 pixel
Right Alt+<, +Right Alt+>redimensionner la poignée droite d'1 pixel
Le redimensionnement réel à l'échelle du pixel dépend du niveau de zoom. Zommer pour dimensionner plus finement.
A la place des touches < et >, vous pouvez utiliser respectivement , (virgule) et . (point).

Modifier le type de segment

Shift+Lrendre rectiligne
Shift+Krendre courbe
Ces commandes exigent que plus de deux nœuds adjacents soient sélectionnés.

Modifier le type de nœud

Shift+Crendre dur
Shift+Srendre doux
Shift+Yrendre symétrique
Ctrl+clickalterner doux/dur/symétrique

Joindre/briser

Shift+Jjoindre les nœuds sélectionnés
Egige que deux (et seulement deux) nœuds terminaux du chemin soient sélectionnés.
Shift+Bbriser les nœud(s) sélectionnés
Après brisure, un seul des deux nœuds est sélectionné. Applicable à plus d'un nœud à la fois.

Supprimer, créer, dupliquer

Backspace, +Suppr.supprimer les nœud(s) sélectionnés
Ctrl+Alt+clicksupprimer le nœud
Ins.insérer des nouveaux nœuds
Ajoute de nouveaux nœud(s) au milieu des segment(s) sélectionnés, et exige la sélection de plus de deux nœuds adjacents.
Shift+Ddupliquer les nœud(s) sélectionnés
Les nouveaux nœuds sont créés sur le même chemin; ils sont placés au-dessus des précédents et sont sélectionnés.

Nœud actif

Le nœud actif est celui sous la souris ou en train d'être déplacé.
Lorsque qu'un nœud est actif, certains raccourcis peuvent ne pas fonctionner;
déplacez votre souris de façon à ce qu'il n'y aie pas de nœud actif si vous voulez les utiliser.
crendre le nœud actif dur
srendre le nœud actif doux
yrendre le nœud actif symétrique
bbriser le nœud actif
Backspacesupprimer le nœud actif

Sélection à la souris

clicksélectionner un objet
Cliquer sur un objet pour le sélectionner.
Les nœuds/poignées de l'objet sélectionné deviennent éditables (vous évitant d'avoir à basculer vers l'outil sélecteur).
clicksélectionner un nœud
Cliquer sur un nœud pour le sélectionner.
Shift+clickalterner la sélection d'un nœud
clickdésélectionner
Cliquer sur une zone vide désélectionne tous les nœuds sélectionnés.

Bande étirable

mouse dragsélectionner plusieurs nœuds
Cliquer-déplacer autour de nœuds les sélectionne par bande étirable; la sélection précédente est désélectionnée.
Shift+mouse dragajouter des nœuds à la sélection

Déplacement à la souris

mouse dragdéplacer les nœuds sélectionnés
Ctrl+mouse dragrestreindre à des mouvements horiz./vert.
Ctrl+Alt+mouse dragdéplacer le long des poignées
Restreint les déplacements selon les directions des poignées et leurs perpendiculaires (soit 8 directions).
Si le nœud a des droites d'un côté ou des deux, le déplacement sera restreint à ces droites et leurs perpendiculaires.
Shift+mouse dragdésactiver temporairement le collage
Le collage des nœuds est activable dans les préférences du document.
Par défaut, seules les boîtes de contour des objets collent à la grille ou aux guides.
mouse dragEspacetamponner une copie
Lors du déplacement nœuds de à la souris, un appui sur la barre d'espace dépose une copie de l'objet sélectionné.
Vous pouvez maintenir la barre d'espace appuyée lors d'un déplacement pour obtenir une belle "trainée".

Déplacement des poignées à la souris

mouse dragdéplacer une poignée de nœud
Ctrl+mouse dragtourner la poignée par incrément(s)
+L'incrément de rotation par défaut est 15 degrés.
Permet aussi de forcer le déplacement selon la direction de la poignée et sa perpendiculaire.
Shift+mouse dragtourner les deux poignées
Alt+mouse dragpréserver la longueur de la poignée
Ctrl, Maj, Alt peuvent être combinés lors du cliquer-déplacer de contrôles.

Inverser

rinverser la direction du chemin

Editer des formes

+L'outil nœud agit aussi sur les poignées des formes (rectangles, ellipses, étoiles, spirales).
Cliquer sur une forme pour la sélectionner.
Voir les les raccourcis des outils de formes correspondants, qui fonctionnent aussi dans l'outil nœud.

Annuler

Escannuler bande étirable/déplacer
Un appui sur Esc (le bouton de la souris étant encore pressé) annule la bande étirable, le déplacement de nœud/poignée.

Zoom

clickzoommer
Shift+clickdézoommer
mouse dragzoommer sur la zone

Pipette

clickcapturer la couleur de remplissage
Shift+clickcapturer la couleur de contour
mouse dragcouleur moyenne de remplissage
Shift+mouse dragcouleur moyenne de contour
Cliquer applique la couleur sous le curseur à la sélection courante. Cliquer-déplacer un disque en calcule la couleur moyenne.
Ctrl+Ccopier la couleur
Copie la couleur sous le curseur vers le presse-papiers, en tant que texte au format RRVVBBAA (8 chiffres hexadécimaux).

Rectangle

Création

mouse dragdessiner un rectangle
Ctrl+mouse dragdessiner un rectangle de ratio entier
Ceci force le rectangle à garder un rapport hauteur/largeur entier (permet aussi de dessiner un carré).
Shift+mouse dragdessiner autour du point de départ
Ceci crée un rectangle symétriquement autour du point de départ.

Edition

clickcliquer sur un rectangle à sélectionner
mouse dragredimensionner ou arrondir
Les deux poignées d'arrondi sont en haut à droite; celles de redimensionnement, en haut à gauche et en bas à droite.
Ctrl+mouse dragpréserver largeur, hauteur ou ratio
S'applique aux poignées de redimensionnement.
Celles-ci redimensionnent le rectangle dans son propre système de coordonnées, avant d'appliquer toute transformation.
Ctrl+mouse dragpréserver l'arrondi
S'applique aux poignées d'arrondi.
Lors de l'arrondi des coins, ne déplacer qu'une poignée (l'autre restant dans le coin) préserve la circularité du coin.
Déplacez les deux poignées pour un arrondi elliptique, ou une seule en appuyant sur Ctrl pour synchroniser la deuxième. +
Escdésélectionner

Ellipse

Création

mouse dragdessiner une ellipse
Ctrl+mouse dragdessiner une ellipse de ratio entier
Ceci force l'ellipse à garder un rapport hauteur/largeur entier (permet aussi de dessiner un cercle).
Shift+mouse dragdessiner autour du point de départ
Ceci crée une ellipse symétriquement autour du point de départ.

Edition

clickcliquer sur une ellipse à sélectionner
mouse dragredimensionner ou "ouvrir"
Les deux poignées d'arc/camembert sont tout à droite; celles de redimensionnement, tout en haut et tout à gauche.
Ctrl+mouse dragforcer la circularité
S'applique aux poignées de redimensionnement.
Celles-ci redimensionnent l'ellipse dans son propre système de coordonnées, avant d'appliquer toute transformation.
Ctrl+mouse dragmodifier l'angle par incréments
S'applique aux poignées d'arc/camembert.
L'incrément d'angle par défaut est de 15 degrés.
Escdésélectionner

Etoile

Création

mouse dragdessiner une étoile
Ctrl+mouse dragtourner l'étoile par incréments
L'incrément d'angle par défaut est de 15 degrés.

Edition

clickcliquer sur une étoile à sélectionner
mouse dragdéplacer une poignée pour modifier l'étoile
Ctrl+mouse draggarder l'étoile strictement radiale
Shift+mouse dragarrondir l'étoile
Shift+clicksupprimer l'arrondi
Alt+mouse dragrendre l'étoile aléatoire
Alt+clicksupprimer le hasard
Escdésélectionner

Spirale

Création

mouse dragdessiner une spirale
Ctrl+mouse dragtourner la spirale par incréments
L'incrément d'angle par défaut est de 15 degrés.

Edition

clickcliquer sur une spirale à sélectionner
mouse dragenrouler/dérouler (poignée intérieure)
Déplacer la poignée intérieure pour modifier le paramètre "rayon intérieur". +
Alt+mouse dragconverger/diverger (poignée intérieure)
Alt+clickforcer divergence=1 (poignée intérieure)
Alt+déplacer verticalement sur la poignée intérieure pour modifier la divergence, Alt+cliquer la remet à 1.
Shift+clickforcer rayon intérieur=0 (poignée intérieure)
Maj+cliquer sur la poignée intérieure la déplace (et donc le départ de la spirale) au centre.
mouse dragenrouler/dérouler (poignée extérieure)
Déplacer la poignée extérieure modifie le nombre de tours. Maj+Alt+cliquer-déplacer pour en/dé-rouler en préservant le rayon.
Shift+mouse dragredimensionner/tourner (poignée extérieure)
Utiliser Maj+Alt pour forcer une rotation seulement (verrouille le rayon de la spirale).
Ctrl+mouse dragtourner une poignée par incréments
L'incrément d'angle par défaut est de 15 degrés. Ceci s'applique aux deux poignées.
Escdésélectionner

Texte

clickcréer/activer un objet texte
Cliquer sur un espace libre ou sur un objet autre qu'un texte affiche un curseur texte; vous pouvez alors taper votre texte.
Cliquer sur un objet texte pour l'activer; le curseur est placé à la fin du texte.
Pour taper des caractères + ou -, utilisez le clavier principal, les touches + et - du pavé numérique étant réservées pour le zoom.
arrowsse déplacer dans un objet texte
Début, +Finaller au début/à la fin de la ligne
Entréecommencer une nouvelle ligne
Escdésélectionner l'objet texte

Caractères spéciaux

Ctrl+U(dés)activer le mode Unicode
Dans ce mode, entrez des chiffres hexadécimaux et validez (Entrée ou Espace) pour obtenir le caractère Unicode correspondant.
Exemple : Ctrl+U 2 0 1 4 Entrée insère un tiret long et sort du mode Unicode.
Utilisez Espace au lieu d'Entrée pour rester en mode Unicode après avoir inséré un caractère.
Un appui sur Esc annule le mode Unicode (sans insérer de caractère).
Ctrl+Espaceinsérer un espace insécable
Un espace insécable est visible même dans un objet texte sans attribut xml:space="preserve".

Inter-lettrage

Alt+>allonger la ligne d'1 pixel
Shift+Alt+>allonger la ligne de 10 pixels
Alt+<rétrécir la ligne d'1 pixel
Shift+Alt+<rétrécir la ligne de 10 pixels
Ces raccourcis agissent lorsque vous éditez un objet texte. Ils ajustent l'inter-lignage de la ligne courante seulement.
La précision réelle de ces ajustements (à l'échelle du pixel) dépend du niveau de zoom. Zommer pour un ajustement plus fin.

Inter-lignage

Ctrl+Alt+>rendre l'objet texte plus haut d'1 pixel
Shift+Ctrl+Alt+>rendre l'objet texte plus haut de 10 pixels
Ctrl+Alt+<rendre l'objet texte plus bas d'1 pixel
Shift+Ctrl+Alt+<rendre l'objet texte plus bas de 10 pixels
Ces raccourcis agissent lorsque vous éditez un objet texte. Ils ajustent l'inter-lignage de l'objet texte courant seulement.
La précision réelle de ces ajustements (à l'échelle du pixel) dépend du niveau de zoom. Zommer pour un ajustement plus fin.

Crénage et déplacement

Alt+arrowsdéplacer les caractères suivants d'1 pixel
Shift+Alt+arrowsdéplacer les caractères suivants de 10 pixels
Ces raccourcis agissent lorsque vous éditez un objet texte.
Elles déplacent (horizontalement ou verticalement) le caractère suivant le curseur et tous les autres jusqu'à la fin de la ligne.
Exemeple : déplacer vers le bas un seul caractère.
Placez le curseur devant le caractère, appuyez sur Alt+Bas, puis derrière et appuyez sur Alt+Haut. +
La précision réelle des déplacements (à l'échelle du pixel) dépend du niveau de zoom. Zommer pour un ajustement plus fin.

Texte suivant un chemin

Shift+Dsélectionner le chemin
Sélectionner un texte suivant un chemin puis utiliser ce raccourci permet de sélectionner le chemin source du texte.

Valid HTML 4.0!

diff --git a/doc/keys.fr.xml b/doc/keys.fr.xml new file mode 100644 index 000000000..a74198de2 --- /dev/null +++ b/doc/keys.fr.xml @@ -0,0 +1,927 @@ + + +

+Sauf mention contraire, les touches du pavé numérique (Début, Fin, +, -, les flèches et les chiffres par exemple) sont supposées se comporter comme des touches normales. Se référer au wiki, sur la page KeyboardShortcutsToDo (en anglais), pour voir la discussion sur les autres raccourcis que nous prévoyons d'instaurer; vous pouvez y laisser vos idées et requêtes. +

+ + + +*
+ + +s sélecteur + sélecteur (temporaire) +Espace bascule temporairement vers le sélecteur. Espace de nouveau rebascule vers l'outil précédent. +n nœud +z zoom +r rectangle +e ellipse/arc +p crayon (main levée) +b stylo (Bézier) + plume calligraphique +d pipette +t texte +i spirale +* étoile +Un double clic sur le bouton d'un outil ouvre la boîte de dialogue des préférences à l'onglet de l'outil correspondant. + + +
+ +*
+ + +N créer un nouveau document +O ouvrir un document SVG +E exporter en PNG +I importer un bitmap ou SVG +P imprimer le document +S sauver le document +S sauver sous un autre nom +Q quitter Inkscape + + +
+ +*
+ + +R (dés)afficher les règles +B (dés)afficher les barres de défilement + (dés)afficher en plein écran + + + + menu principal +Les menus peuvent aussi être activés en appuyant simultanément sur Alt et la lettre soulignée dans le nom du menu. + menu contextuel + + + + W fermer la fenêtre (document) +Quitte Inkscape si la fenêtre courante est le seul document ouvert. + fenêtre (document) suivante + fenêtre (document) précédente +Permet de circuler entre les fenêtres (documents) en avant ou en arrière. + + +
+ + +*
+ +F Remplissage et contour +T Texte et police +M Transformer +A Aligner et distribuer +O Propriétés de l'objet +X Editeur XML +D Préférences du document +P Préférences d'Inkscape +E Exporter en PNG +F Rechercher +B Vectoriser un bitmap +Ces raccourcis ouvrent si nécessaire une nouvelle boîte de dialogue, sinon réactivent la boîte correspondante. + + + +(dés)Afficher + (dés)afficher les boîtes de dialogue +Masque temporairement les boîtes de dialogue ouvertes. Un appui de plus sur F12 les rend de nouveau visibles. + + + +Dans une boîte de dialogue + retourner au canevas + W fermer le dialogue + passer au champ suivant + passer au champ précédent + valider la nouvelle valeur +Valide la nouvelle valeur entrée dans un champ et retourne au canevas. + définir la valeur d'un attribut (éditeur XML) +Valide la nouvelle valeur d'un attribut dans l'éditeur XML (comme cliquer sur le bouton "Définir l'attribut". + activer le bouton ou la valeur d'une liste. + naviguer parmi les onglets d'un dialogue + +
+ +*
+ + +La barre de contrôle en haut de la fenêtre document affiche des champs et des contrôles pour chacun des outils. +X aller au premier champ + valider la nouvelle valeur +Valide la nouvelle valeur entrée dans un champ et retourne au canevas. + annuler les modifications, retourner au canevas +Annule la modification d'un champ et retourne au canevas. +Z annuler les modifications +Annule la modification d'un champ mais reste dans ce champ. + passer au champ suivant + passer au champ précédent +Permet de naviguer entre les différents champs de la barre de contrôle (les modifications du champs quitté sont validées). + + + +Modification des valeurs + modifier la valeur de 0.1 + modifier la valeur de 5.0 + + +
+ +
+ + + + +*
+ + +Zoom += + zoommer +- dézoommer +Les touches +/- du pavé numérique permettent de zoommer même pendant l'édition d'un objet texte. + zoommer + dézoommer + (dé)zoommer +Z activer le champ de zoom +Le champ zoom dans le coin inférieur gauche de la fenêtre vous permet de spécifier précisément la valeur de zoom. + + + +Zooms prédéfinis +1 zoommer à 1:1 +2 zoommer à 1:2 +3 zoommer sur la sélection +4 zoommmer sur le dessin +5 zoommer sur la page +E6 zoommer sur la largeur de page + + + +Historique du zoom +` (guillement inversé) zoom précédent +` zoom suivant +Ces raccourcis permettent de naviguer parmi les différents niveaux de zoom utilisés pendant la session. + + + +Défilement + faire défiler le canevas +Ces raccourcis peuvent être accélérés, par une répétition rapide ou un appui continu + faire défiler le canevas + faire défiler le canevas + faire défiler le canevas verticalement + faire défiler le canevas horizontalement + + + +Guides et grille + créer un guide en le tirant depuis une règle +Cliquer-déplacer d'une règle vers le canevas pour créer un nouveau guide. Déplacer un guide vers la règle pour le supprimer. +| \ (dés)activer affichage et collage des guides +Pour des valeurs différentes d'affichage/collage des guides, les régler dans les Préférences du document. +Lors de sa création par cliquer-déplacer depuis une règle, l'affichage et le collage des guides sont activés. +# 3 (dés)activer affichage et collage de la grille +Pour des valeurs différentes d'affichage/collage de la grille, les régler dans les Préférences du document. +Notez que seule la touche 3 du clavier principal a une action, pas celle du pavé numérique. + +
+ +*
+ + déplacer au calque supérieur + déplacer au calque inférieur +Ces commandes déplacent les objets sélectionnés d'un calque à un autre. + + monter le calque + descendre le calque + monter le calque au premier plan + descendre le calque à l'arrière plan +Ces commandes déplacent le calque courant parmi sa hiérarchie (normalement d'autres calques) + +
+ + +*
+ + +Annuler/refaire +Y Z annuler +Z Y refaire + + + +Presse-papiers +C copier la sélection +Copie la sélection dans le presse-papiers Inkscape (et aussi dans le presse-papiers système pour les textes). +X couper la sélection +Fonctionne comme un "copier la sélection" suivi de la suppression de la sélection. +V coller le presse-papiers +Ceci place les objets du presse-papier sous la souris, ou au centre de la fenêtre si la souris est hors du canevas. +Lors de l'édition d'un texte avec l'outil texte, colle le texte du presse-papiers système dans l'objet texte courant. +V coller sur place +Ceci place les objets du presse-papiers au même emplacement que lors de leur copie. +V coller le style +Ceci applique le style du premier des objet copiés à la sélection courante. + + + +Dupliquer +D dupliquer la sélection +Les nouveaux objet(s) sont placés exactement au même endroit, au dessus des originaux et sont sélectionnés. + + + +Cloner +D cloner l'objet +Un clone peut être déplacé/redimensionné/tourné/incliné indépendament, mais reçoit ses tracé/remplissage/contour de l'original. +Le clone est placé exactement au même endroit, au dessus de l'original et est sélectionné. +Vous ne pouvez cloner qu'un objet à la fois; si vous voulez cloner plusieurs objets ensemble, groupez-les puis clonez le groupe. +D délier le clone +Délier un clone supprime le lien vers son original, le clone devenant alors une simple copie. +D sélectionner l'original +Après sélection d'un clone, cette commande sélectionne l'objet original dont le clone est issu. + + + +Bitmaps +B créer une copie bitmap +Exporte en PNG les objet(s) sélectionnés (les autres objets étant masqués) dans le répertoire du document et réimporte ce PNG. +Le bitmap (PNG) importé est placé exactement au même endroit, au dessus de la sélection originale, et est sélectionné. +B vectoriser le bitmap +Ceci ouvre la boîte de dialogue vectoriser un bitmap, vous permettant de convertir une image bitmap en chemin. + + + +Motif +I objet en motif +Ceci convertit la sélection en un rectangle rempli avec la sélection comme motif de remplissage. +I motif en objet +Sépare tout objet sélectionné rempli avec un motif en deux objets : ce même objet sans remplissage et le motif seul. + + + +Grouper + U G grouper les objets sélectionnés +Ctrl+cliquer permet de sélectionner des objets au sein d'un groupe. +G U dégrouper les groupe(s) sélectionnés +Retire un niveau de regroupement; répéter plusieurs fois Ctrl+U permet de dégrouper des groupes imbriqués. + + + +Ordre-Z (superposition) + monter la sélection au premier plan + descendre la sélection à l'arrière plan + monter la sélection d'un cran + descendre la sélection d'un cran + + +
+ +*
+ + +Convertir en chemin +C convertir les objet(s) sélectionnés en chemin +C convertir les contour(s) sélectionnés en chemin + + + +Booléens ++ union +L'union combine plusieurs objets en un seul chemin, fusionnant les recouvrements. +- différence +La différence s'applique à deux objets, extrayant celui du dessus de celui du dessous. +* intersection +L'intersection crée un chemin représentant l'intersection des objets sélectionnés. +^ exclusion (ou exclusif) +L'exclusion est similaire à l'union, mais ne s'applique qu'à deux objets et supprime les recouvrements. +/ division (coupe) +La division découpe l'objet du dessous en morceaux selon l'objet du dessus, et préserve ses remplissage et contour. +/ découpe des chemins +Découper en chemin découpe le contour de l'objet du dessous aux points d'intersection avec celui du dessus. + Le résultat est sans remplissage. +Le résultat d'une union/différence/intersection/exclusion hérite de l'attribut id (et donc des clones) de l'objet du dessous. +Les division et découpe en chemin peuvent produire plusieurs objets. L'un d'eux, au hasard, hérite de l'id de l'objet du dessous. + + + +Offsets +( éroder le chemin +) dilater le chemin +La distance d'offset par défaut est de 2 px (en pixels SVG, pas en pixels à l'écran). +( éroder le chemin d'1 pixel +) dilater le chemin d'1 pixel +( éroder le chemin de 10 pixels +) dilater le chemin de 10 pixels +Le déplacement réel des pixels dépend du niveau de zoom. Zommer pour ajuster plus finement. +Toutes les commandes (, ) convertissent l'objet en chemin si nécessaire, et produisent un chemin normal. +J créer un offset dynamique +J créer un offset lié +Ces commandes produisent un objet offset (autonome ou lié à l'original) que l'on peut éditer avec l'outil nœud. + +D sélectionner l'objet source +Après sélection d'un offset lié, cette commande sélectionne l'objet original dont il est issu. + + + +Combiner +K combiner les chemins +Cette commande est différente de grouper : des chemins combinés créent un objet, pas un groupe. +Différente aussi d'une union : les recouvrements ne sont pas affectés.. +Le remplissage des recouvrements est géré par le champ remplissage (complet/alternatif) du dialogue Remplissage et contour. +K séparer les chemins +Sépare les sous-chemins d'un chemin composé; ceci échouera si l'objet est constitué d'un seul chemin. + + + +Simplifier +L simplifier +Simplifie les chemin(s) sélectionnés en supprimant quelques nœuds. Si nécessaire, les objets sont convertis en chemins. +En invoquant cette commande plusieurs fois de suite rapidement, elle agira de plus en plus agressivement. +Le seuil par défaut (réglable dans les préférences d'Inkscape) est restauré après une pause. + + +
+ +
+ + + +*
+ + +Sélection au clavier + sélectionner l'objet suivant + sélectionner l'objet précédent +Sélectionne les objets selon leur ordre-z (Tab circule de l'arrière au premier plan, Maj+Tab fait l'inverse). +A moins d'avoir fait des réarrangements manuels, le dernier objet créé est au tout premier plan +Aussi, si rien n'est sélectionné, Maj+Tab est une façon pratique de sélectionner le dernier objet créé. +Cette commande s'applique aux objets du calque courant (sauf modification des préférences). +A tout sélectionner (calque courant) +Cette commande s'applique aux objets du calque courant (sauf modification des préférences). +A tout sélectionner (tous les calques) +Cette commande s'applique aux objets de tout calque visible et déverrouillé. +! inverser la sélection (calque courant) +Inverse la sélection (désélectionne ce qui était sélectionné, et sélectionne tout le reste) du calque courant. +! inverser la sélection (tous les calques) +Inverse la sélection dans tout calque visible et déverrouillé. + désélectionner + supprimer la sélection + + + +Déplacement au clavier + déplacer la sélection par incrément(s) + déplacer la sélection de 10x l'incrément +L'incrément de déplacement par défaut est 1mm. + déplacer la sélection d'1 pixel + déplacer la sélection de 10 pixels +Le déplacement réel à l'échelle du pixel dépend du niveau de zoom. Zommer pour déplacer plus finement. + + + +Rotation au clavier +[ ] tourner la sélection par incrément(s) +L'incrément de rotation par défaut est 15°. ] tourne en sens horaire, [ en sens anti-horaire. +[ ] tourner la sélection de 90 degrés +[ ] tourner la sélection d'1 pixel +La rotation réelle à l'échelle du pixel dépend du niveau de zoom. Zommer pour tourner plus finement. + + + +Redimensionnement au clavier +. > agrandir la sélection par incrément(s) +, < rétrécir la sélection par incrément(s) +L'incrément de redimensionnement par défaut est de 2 px (en pixels SVG, pas en pixels à l'écran). +. > agrandir la sélection à 200% +, < rétrécir la sélection à 50% +. > agrandir la sélection d'1 pixel +, < rétrécir la sélection d'1 pixel +Le redimensionnement réel à l'échelle du pixel dépend du niveau de zoom. Zommer pour dimensionner plus finement. +Le redimensionnement est uniforme autour du centre : il est donc appliqué à la plus grande des deux dimensions. + + + +Retournement au clavier +h retourner la sélection horizontalement +v retourner la sélection verticalement + + + +Sélection à la souris + sélectionner un objet +En cliquant (bouton gauche) sur un objet, la sélection précédente est desélectionnée. + alterner la sélection +Maj+cliquer ajoute un objet à la sélection courante s'il n'était pas sélectionné, le retire sinon. + + + +Sélection dans un groupe, en-dessous + sélectionner dans un groupe +Sélectionne l'objet sous le curseur, quel que soit le groupe auquel cet objet peut appartenir. + alterner la sélection (dans un groupe) + sélectionner en-dessous +Sélectionne l'objet (sous le curseur) juste en dessous (dans l'ordre-z) l'objet sélectionné le plus bas. +Si l'objet le plus en bas atteint, un Alt+Cliquer de plus sélectionne l'objet au premier plan, circulant ainsi dans l'ordre-z. +Sous Linux, Alt+cliquer et Alt+cliquer-déplacer peuvent être préemptés par le gestionnaire de fenêtre. +Reconfigurez celui-ci afin de pouvoir utiliser ces raccourcis dans Inkscape. + alterner en-dessous + sélectionner en-dessous, dans des groupes + alterner en-dessous, dans des groupes + + + +Bande étirable + sélectionner plusieurs objets +Cliquer-déplacer autour d'objets les sélectionne par bande étirable; la sélection précédente est désélectionnée. + ajouter des objets à la sélection +Normalement, vous devez commencer une bande étirable sur une zone vide. +Mais, en appuyant sur Maj avant, Inkscape effectuera une zone étirable, même si elle commence sur un objet. + + + +Déplacement à la souris + sélectionner + déplacer +Cliquer-déplacer sur un objet le sélectionne s'il n'était pas sélectionné, puis déplace la sélection. + déplacer la sélection +Déplace la sélection courante (sans sélectionner ce qui est sous le curseur), quel que soit le point de départ. +Sous Linux, Alt+cliquer et Alt+cliquer-déplacer peuvent être utilisés par le gestionnaire de fenêtre. +Reconfigurez celui-ci afin de pouvoir utiliser ces raccourcis dans Inkscape. + + restreindre à un mouvement vertical/horizontal + désactiver temporairement le collage +Désactive temporairement le collage à la grille ou aux guides lors de déplacements (grille/guides étant actifs). + tamponner une copie +Lors de déplacements/transformations à la souris, un appui sur la barre d'espace dépose une copie de l'objet sélectionné. +Vous pouvez maintenir la barre d'espace appuyée lors d'un déplacement pour obtenir une belle "trainée". + + + +Transformation à la souris + alterner poignées arrondi/redimensionnement + redimensionner +S'applique aux poignées de redimensionnement. + tourner ou incliner +S'applique aux poignées de rotation/inclinaison. + + + +Poignées de redimensionnement + redimensionner en préservant le ratio + + transformation symétrique +Appuyer sur Maj pendant une transformation rend cette transformation symétrique autour du centre de la sélection. + + mouvement lent +Force un ralentissement des mouvements de la souris, permettant ainsi des modifications plus fines. + + + +Poignées de rotation + incliner et étirer +Appuyer sur Ctrl tout en déplaçant une poignée d'inclinaison (pas un coin) permet d'étirer tout en inclinant. + tourner la sélection par incrément(s) +L'incrément de rotation par défaut est 15 degrés. + + + +Annuler + annuler bande étirable/déplacer/transformer +Un appui sur Esc (le bouton de la souris étant encore pressé) annule la bande étirable, le déplacement ou la transformation. + + +
+ +*
+ + dessiner une ligne à main levée + désactiver temporairement le collage +Désactive temporairement le collage à la grille ou aux guides lors de déplacements (grille/guides étant actifs). +a alterner créer/prolonger +Alterne entre créer une nouvelle ligne et prolonger la ligne sélectionnée (des ancres sont affichées en mode prolonger). + +
+ +*
+ + +Créer des nœuds + créer un nœud anguleux + créer un nœud de Bézier avec 2 poignées + ne déplacer qu'une poignée + +Ceci ne déplace qu'une poignée (au lieu des deux), pour créer un nœud dur. + tourner la poignée par incrément(s) +L'incrément de rotation par défaut est 15 degrés. + + + +Créer des segments + tourner le segment par incrément(s) + +Ceci force la rotation d'un nœud (nouvel angle relativement au nœud précédent) par incrément(s) (15 degrés par défaut) . + + + +Terminer + terminer le tracé courant + terminer le tracé courant + terminer le tracé courant +Entrée, clic-droit ou double-clic terminent la ligne courante, annulant le dernier segment non fini (en rouge). + + + +Clavier + annuler le tracé courant + effacer le dernier segment du tracé courant +a alterner créer/prolonger +Alterne entre créer une nouvelle ligne et prolonger la ligne sélectionnée (des ancres sont affichées en mode prolonger). + +
+ +*
+ + traver une ligne calligraphique + ajuster la largeur de la plume + aduster l'angle de la plume +La largeur et l'angle de la plume peuvent être ajustés tout en dessinant. + +
+ + + +
+ + +*
+ + +Sélection au clavier + sélectionner le nœud suivant + sélectionner le nœud précédent +Ces raccourcis vous permettent de sélectionner n'importe quel nœud du chemin sélectionné. +A sélectionner tous les nœuds du chemin + désélectionner tous les nœuds + + + +Déplacement au clavier + déplacer les nœuds sélect. par incrément(s) + déplacer les nœuds sélect. de 10x l'incrément +L'incrément de déplacement par défaut est 1mm. + déplacer les nœuds sélectionnés d'1 pixel + déplacer les nœuds sélectionnés de 10 pixels +Le déplacement réel à l'échelle du pixel dépend du niveau de zoom. Zommer pour déplacer plus finement. + + + +Rotation des poignées au clavier +[ ] tourner les deux poignées par incrément(s) +L'incrément de rotation par défaut est 15 degrés. ] tourne en sens horaire, [ en sens anti-horaire. Applicable à plusieurs nœuds. +[ ] tourner la poignée gauche par incrément(s) +[ ] tourner la poignée droite par incrément(s) +[ ] tourner la poignée gauche d'1 pixel +[ ] tourner la poignée droite d'1 pixel + + + +Redim. des poignées au clavier +< > redim. les deux poignées par incrément(s) +L'incrément de redimensionnement par défaut est de 2 px (en pixels SVG, pas en pixels à l'écran). Applicable à plusieurs nœuds. + +< +> +redim. la poignée gauche par incrément(s) + + +< +> +redim. la poignée droite par incrément(s) + + +< +> +redimensionner la poignée gauche d'1 pixel + + +< +> +redimensionner la poignée droite d'1 pixel + +Le redimensionnement réel à l'échelle du pixel dépend du niveau de zoom. Zommer pour dimensionner plus finement. +A la place des touches < et >, vous pouvez utiliser respectivement , (virgule) et . (point). + + + +Modifier le type de segment +L rendre rectiligne +K rendre courbe +Ces commandes exigent que plus de deux nœuds adjacents soient sélectionnés. + + + +Modifier le type de nœud +C rendre dur +S rendre doux +Y rendre symétrique + alterner doux/dur/symétrique + + + +Joindre/briser +J joindre les nœuds sélectionnés +Egige que deux (et seulement deux) nœuds terminaux du chemin soient sélectionnés. +B briser les nœud(s) sélectionnés +Après brisure, un seul des deux nœuds est sélectionné. Applicable à plus d'un nœud à la fois. + + + +Supprimer, créer, dupliquer + supprimer les nœud(s) sélectionnés + supprimer le nœud + insérer des nouveaux nœuds +Ajoute de nouveaux nœud(s) au milieu des segment(s) sélectionnés, et exige la sélection de plus de deux nœuds adjacents. +D dupliquer les nœud(s) sélectionnés +Les nouveaux nœuds sont créés sur le même chemin; ils sont placés au-dessus des précédents et sont sélectionnés. + + + +Nœud actif +Le nœud actif est celui sous la souris ou en train d'être déplacé. +Lorsque qu'un nœud est actif, certains raccourcis peuvent ne pas fonctionner; +déplacez votre souris de façon à ce qu'il n'y aie pas de nœud actif si vous voulez les utiliser. +c rendre le nœud actif dur +s rendre le nœud actif doux +y rendre le nœud actif symétrique +b briser le nœud actif + supprimer le nœud actif + + + +Sélection à la souris + sélectionner un objet +Cliquer sur un objet pour le sélectionner. +Les nœuds/poignées de l'objet sélectionné deviennent éditables (vous évitant d'avoir à basculer vers l'outil sélecteur). + sélectionner un nœud +Cliquer sur un nœud pour le sélectionner. + alterner la sélection d'un nœud + désélectionner +Cliquer sur une zone vide désélectionne tous les nœuds sélectionnés. + + + +Bande étirable + sélectionner plusieurs nœuds +Cliquer-déplacer autour de nœuds les sélectionne par bande étirable; la sélection précédente est désélectionnée. + ajouter des nœuds à la sélection + + + +Déplacement à la souris + déplacer les nœuds sélectionnés + restreindre à des mouvements horiz./vert. + déplacer le long des poignées +Restreint les déplacements selon les directions des poignées et leurs perpendiculaires (soit 8 directions). +Si le nœud a des droites d'un côté ou des deux, le déplacement sera restreint à ces droites et leurs perpendiculaires. + désactiver temporairement le collage +Le collage des nœuds est activable dans les préférences du document. +Par défaut, seules les boîtes de contour des objets collent à la grille ou aux guides. + tamponner une copie + Lors du déplacement nœuds de à la souris, un appui sur la barre d'espace dépose une copie de l'objet sélectionné. +Vous pouvez maintenir la barre d'espace appuyée lors d'un déplacement pour obtenir une belle "trainée". + + + +Déplacement des poignées à la souris + déplacer une poignée de nœud + tourner la poignée par incrément(s) + +L'incrément de rotation par défaut est 15 degrés. + Permet aussi de forcer le déplacement selon la direction de la poignée et sa perpendiculaire. + tourner les deux poignées + préserver la longueur de la poignée +Ctrl, Maj, Alt peuvent être combinés lors du cliquer-déplacer de contrôles. + + + +Inverser +r inverser la direction du chemin + + + +Editer des formes + +L'outil nœud agit aussi sur les poignées des formes (rectangles, ellipses, étoiles, spirales). +Cliquer sur une forme pour la sélectionner. +Voir les les raccourcis des outils de formes correspondants, qui fonctionnent aussi dans l'outil nœud. + + + + +Annuler + annuler bande étirable/déplacer +Un appui sur Esc (le bouton de la souris étant encore pressé) annule la bande étirable, le déplacement de nœud/poignée. + + +
+ +*
+ + zoommer + dézoommer + zoommer sur la zone + +
+ +
+ + +*
+ + capturer la couleur de remplissage + capturer la couleur de contour + couleur moyenne de remplissage + couleur moyenne de contour +Cliquer applique la couleur sous le curseur à la sélection courante. Cliquer-déplacer un disque en calcule la couleur moyenne. +C copier la couleur +Copie la couleur sous le curseur vers le presse-papiers, en tant que texte au format RRVVBBAA (8 chiffres hexadécimaux). + +
+ + + +*
+ +Création + dessiner un rectangle + dessiner un rectangle de ratio entier +Ceci force le rectangle à garder un rapport hauteur/largeur entier (permet aussi de dessiner un carré). + dessiner autour du point de départ +Ceci crée un rectangle symétriquement autour du point de départ. + + +Edition + cliquer sur un rectangle à sélectionner + redimensionner ou arrondir +Les deux poignées d'arrondi sont en haut à droite; celles de redimensionnement, en haut à gauche et en bas à droite. + préserver largeur, hauteur ou ratio +S'applique aux poignées de redimensionnement. +Celles-ci redimensionnent le rectangle dans son propre système de coordonnées, avant d'appliquer toute transformation. + préserver l'arrondi +S'applique aux poignées d'arrondi. +Lors de l'arrondi des coins, ne déplacer qu'une poignée (l'autre restant dans le coin) préserve la circularité du coin. +Déplacez les deux poignées pour un arrondi elliptique, ou une seule en appuyant sur Ctrl pour synchroniser la deuxième. + + désélectionner + +
+ +*
+ +Création + dessiner une ellipse + dessiner une ellipse de ratio entier +Ceci force l'ellipse à garder un rapport hauteur/largeur entier (permet aussi de dessiner un cercle). + dessiner autour du point de départ +Ceci crée une ellipse symétriquement autour du point de départ. + + +Edition + cliquer sur une ellipse à sélectionner + redimensionner ou "ouvrir" +Les deux poignées d'arc/camembert sont tout à droite; celles de redimensionnement, tout en haut et tout à gauche. + forcer la circularité +S'applique aux poignées de redimensionnement. +Celles-ci redimensionnent l'ellipse dans son propre système de coordonnées, avant d'appliquer toute transformation. + modifier l'angle par incréments +S'applique aux poignées d'arc/camembert. +L'incrément d'angle par défaut est de 15 degrés. + désélectionner + +
+ +*
+ +Création + dessiner une étoile + tourner l'étoile par incréments +L'incrément d'angle par défaut est de 15 degrés. + + +Edition + cliquer sur une étoile à sélectionner + déplacer une poignée pour modifier l'étoile + garder l'étoile strictement radiale + arrondir l'étoile + supprimer l'arrondi + rendre l'étoile aléatoire + supprimer le hasard + désélectionner + +
+ +*
+ +Création + dessiner une spirale + tourner la spirale par incréments +L'incrément d'angle par défaut est de 15 degrés. + + +Edition + cliquer sur une spirale à sélectionner + + enrouler/dérouler (poignée intérieure) +Déplacer la poignée intérieure pour modifier le paramètre "rayon intérieur". + + converger/diverger (poignée intérieure) + forcer divergence=1 (poignée intérieure) +Alt+déplacer verticalement sur la poignée intérieure pour modifier la divergence, Alt+cliquer la remet à 1. + forcer rayon intérieur=0 (poignée intérieure) +Maj+cliquer sur la poignée intérieure la déplace (et donc le départ de la spirale) au centre. + + enrouler/dérouler (poignée extérieure) +Déplacer la poignée extérieure modifie le nombre de tours. Maj+Alt+cliquer-déplacer pour en/dé-rouler en préservant le rayon. + redimensionner/tourner (poignée extérieure) +Utiliser Maj+Alt pour forcer une rotation seulement (verrouille le rayon de la spirale). + + tourner une poignée par incréments +L'incrément d'angle par défaut est de 15 degrés. Ceci s'applique aux deux poignées. + + désélectionner + +
+ + +*
+ + + créer/activer un objet texte + +Cliquer sur un espace libre ou sur un objet autre qu'un texte affiche un curseur texte; vous pouvez alors taper votre texte. +Cliquer sur un objet texte pour l'activer; le curseur est placé à la fin du texte. +Pour taper des caractères + ou -, utilisez le clavier principal, les touches + et - du pavé numérique étant réservées pour le zoom. + se déplacer dans un objet texte + aller au début/à la fin de la ligne + commencer une nouvelle ligne + désélectionner l'objet texte + + + +Caractères spéciaux +U (dés)activer le mode Unicode +Dans ce mode, entrez des chiffres hexadécimaux et validez (Entrée ou Espace) pour obtenir le caractère Unicode correspondant. +Exemple : Ctrl+U 2 0 1 4 Entrée insère un tiret long et sort du mode Unicode. +Utilisez Espace au lieu d'Entrée pour rester en mode Unicode après avoir inséré un caractère. +Un appui sur Esc annule le mode Unicode (sans insérer de caractère). + + insérer un espace insécable +Un espace insécable est visible même dans un objet texte sans attribut xml:space="preserve". + + + +Inter-lettrage +> allonger la ligne d'1 pixel +> allonger la ligne de 10 pixels +< rétrécir la ligne d'1 pixel +< rétrécir la ligne de 10 pixels +Ces raccourcis agissent lorsque vous éditez un objet texte. Ils ajustent l'inter-lignage de la ligne courante seulement. +La précision réelle de ces ajustements (à l'échelle du pixel) dépend du niveau de zoom. Zommer pour un ajustement plus fin. + + + +Inter-lignage +> rendre l'objet texte plus haut d'1 pixel +> rendre l'objet texte plus haut de 10 pixels +< rendre l'objet texte plus bas d'1 pixel +< rendre l'objet texte plus bas de 10 pixels +Ces raccourcis agissent lorsque vous éditez un objet texte. Ils ajustent l'inter-lignage de l'objet texte courant seulement. +La précision réelle de ces ajustements (à l'échelle du pixel) dépend du niveau de zoom. Zommer pour un ajustement plus fin. + + + +Crénage et déplacement + déplacer les caractères suivants d'1 pixel + déplacer les caractères suivants de 10 pixels +Ces raccourcis agissent lorsque vous éditez un objet texte. +Elles déplacent (horizontalement ou verticalement) le caractère suivant le curseur et tous les autres jusqu'à la fin de la ligne. +Exemeple : déplacer vers le bas un seul caractère. +Placez le curseur devant le caractère, appuyez sur Alt+Bas, puis derrière et appuyez sur Alt+Haut. + + + +La précision réelle des déplacements (à l'échelle du pixel) dépend du niveau de zoom. Zommer pour un ajustement plus fin. + + + +Texte suivant un chemin +D sélectionner le chemin +Sélectionner un texte suivant un chemin puis utiliser ce raccourci permet de sélectionner le chemin source du texte. + +
+ +
+ +
diff --git a/doc/keys.html b/doc/keys.html new file mode 100644 index 000000000..a64bffe8a --- /dev/null +++ b/doc/keys.html @@ -0,0 +1,1060 @@ + +Inkscape keys and mouse reference

Unless noted otherwise, keypad keys (such as arrows, Home, End, +, -, digits) are +supposed to work the same as corresponding regular keys. If you have a new shortcut +idea, please contact the developers (by writing to the devel mailing list +or by submitting an +RFE).

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Tools

F1, +sSelector
SpaceSelector (temporary)
Space switches to the Selector tool temporarily; another Space switches back.
F2, +nNode tool
F3, +zZoom tool
F4, +rRectangle tool
F5, +eEllipse/arc tool
F6, +pFreehand (Pencil) tool
Shift+F6, +bBezier (Pen) tool
Ctrl+F6, +cCalligraphic tool
Ctrl+F1, +gGradient tool
F7, +dDropper tool
F8, +tText tool
F9, +iSpiral tool
Shift+F9, +*Star tool
Ctrl+F2, +oConnector tool
Double click on the tool buttons opens the Preferences dialog showing the page of the corresponding tool.

Dialogs

Shift+Ctrl+FFill and Stroke
Shift+Ctrl+WSwatches
Shift+Ctrl+TText and Font
Shift+Ctrl+MTransform
Shift+Ctrl+AAlign and Distribute
Shift+Ctrl+OObject Properties
Shift+Ctrl+XXML Editor
Shift+Ctrl+DDocument Preferences
Shift+Ctrl+PInkscape Preferences
Shift+Ctrl+EExport to PNG
Ctrl+FFind
Shift+Alt+BTrace bitmap
These open a new dialog window if it wasn't open yet, otherwise the corresponding dialog gets focus.

Toggle visibility

F12toggle dialogs
This temporarily hides all open dialogs; another F12 shows them again.

Within a dialog

Escreturn to the canvas
Ctrl+F4, +Ctrl+Wclose the dialog
Tabjump to next widget
Shift+Tabjump to previous widget
Enterset the new value
This accepts the new value you typed in a text field and returns focus to canvas.
Ctrl+Enterin XML Editor, set the attr value
When editing an attribute value in XML Editor, this sets the new value (same as clicking the "Set attribute" button).
Space, +Enteractivate current button or list
Ctrl+PgUp, +Ctrl+PgDnin a multi-tab dialog, switch tabs

Controls bar

The Controls bar at the top of the document window provides different buttons and controls for each tool.
Alt+Xjump to the first editable field
Enteraccept the new value
This accepts the new value you typed in a text field and returns focus to canvas.
Esccancel changes, return to canvas
This cancels any changes you made in a text field and returns focus to canvas.
Ctrl+Zcancel changes
This cancels any changes you made in a text field but you stay in the field.
Tabjump to next field
Shift+Tabjump to previous field
Use these to navigate between fields in the Controls bar (the value in the field you leave, if changed, is accepted).

Changing values

Up arrow, +Down arrowchange value by 0.1
PgUp, +PgDnchange value by 5.0

Canvas

Zoom

=, ++zoom in
-zoom out
The keypad +/- keys do zooming even when you are editing a text object, unless NumLock is on.
middle click, +Ctrl+right clickzoom in
Shift+middle click, +Shift+right clickzoom out
Ctrl+mouse wheelzoom in or out
Shift+middle button dragzoom into the area
Alt+Zactivate zoom field
The zoom field in the lower left corner of the window allows you to specify zoom level precisely.

Preset zooms

1zoom 1:1
2zoom 1:2
3zoom to selection
4zoom to drawing
5zoom to page
Ctrl+E, +6zoom to page width

Zoom history

`(back quote) previous zoom
Shift+`next zoom
With these keys, you can travel back and forth through the history of zooms in this session

Scrolling (panning)

Ctrl+arrowsscroll canvas
Scrolling by keys is accelerated, i.e. it speeds up when you press Ctrl+arrows in quick succession, or press and hold.
middle button dragpan canvas
Shift+right button drag, +Ctrl+right button dragpan canvas
mouse wheelscroll canvas vertically
Shift+mouse wheelscroll canvas horizontally

Guides and grid

mouse dragdrag off a ruler to create guide
Drag off the horizontal or vertical ruler to create a new guideline. Drag a guideline onto the ruler to delete it.
|, +Shift+\toggle guides and snapping to guides
If you want to have different values for guides visibility and snapping, set them via the Document Options dialog.
When you create a new guide by dragging off the ruler, guide visibility and snapping are turned on.
#, +Shift+3toggle grid and snapping to grid
If you want to have different values for grid visibility and snapping, set them via the Document Options dialog.
Note that only the 3 key on the main keyboard works, not on the keypad.

File

Ctrl+Ncreate new document
Ctrl+Oopen an SVG document
Shift+Ctrl+Eexport to PNG
Ctrl+Iimport bitmap or SVG
Ctrl+Pprint document
Ctrl+Ssave document
Shift+Ctrl+Ssave under a new name
Ctrl+Qexit Inkscape

Window

Ctrl+Rtoggle rulers
Ctrl+Btoggle scrollbars
F11toggle fullscreen
F10main menu
Menus can also be activated by Alt with the letter underscored in the menu name.
Shift+F10, +right clickdrop-down (context) menu
Ctrl+F4, +Ctrl+Wclose document window
This shuts down Inkscape if it was the only document window open.
Ctrl+Tabnext document window
Shift+Ctrl+Tabprevious document window
These cycle through the active document windows forward and backward.

Layers

Shift+PgUpmove to layer above
Shift+PgDnmove to layer below
These commands move the selected objects from one layer to another.
Shift+Ctrl+PgUpraise layer
Shift+Ctrl+PgDnlower layer
Shift+Ctrl+Homeraise layer to top
Shift+Ctrl+Endlower layer to bottom
These commands move the current layer among its siblings (normally other layers).

Object

Undo/redo

Shift+Ctrl+Y, +Ctrl+Zundo
Shift+Ctrl+Z, +Ctrl+Yredo

Clipboard

Ctrl+Ccopy selection
This places a copy of the selection to the Inkscape clipboard. Text from text objects is also placed onto the system clipboard.
Ctrl+Xcut selection
This works the same as "copy selection" followed by deleting the selection.
Ctrl+Vpaste clipboard
This places the clipboard objects at the mouse cursor, or at the center of the window if mouse is outside the canvas.
When editing text with the text tool, this pastes the text from the system clipboard into the current text object.
Ctrl+Alt+Vpaste in place
This places the clipboard objects to the original location from which they were copied.
Shift+Ctrl+Vpaste style
This applies the style of the (first of the) coped object(s) to the current selection.
If a gradient handle (in Gradient tool) or a text span (in Text tool) are selected, they get the style instead of the entire object.

Duplicate

Ctrl+Dduplicate selection
New object(s) are placed exactly over the original(s) and selected.

Clone

Alt+Dclone object
A clone can be moved/scaled/rotated/skewed independently, but it updates the path, fill, and stroke from its original.
The clone is placed exactly over the original object and is selected.
You can only clone one object at a time; if you want to clone several objects together, group them and clone the group.
Shift+Alt+Dunlink clone
Unlinking a clone cuts the link to the original, turning the clone into a plain copy.
Shift+Dselect original
To find out which object this is a clone of, select the clone and give this command. The original will be selected.

Bitmaps

Alt+Bcreate a bitmap copy
This exports the selected object(s) (all other objects hidden) as PNG in the document's directory and imports it back.
The imported bitmap is placed over the original selection and is selected.
Shift+Alt+Btrace bitmap
This opens the Trace Bitmap dialog allowing you to convert a bitmap object to path(s).

Patterns

Alt+Iobject(s) to pattern
This converts the selection to a rectangle with tiled pattern fill.
Shift+Alt+Ipattern to object(s)
Each selected object with pattern fill is broken into the same object without fill and a single pattern object.

Group

Shift+Ctrl+U, +Ctrl+Ggroup selected objects
Use Ctrl+click to select objects within group.
Shift+Ctrl+G, +Ctrl+Uungroup selected group(s)
This removes only one level of grouping; press Ctrl+U repeatedly to ungroup nested groups.

Z-order

Homeraise selection to top
Endlower selection to bottom
PgUpraise selection one step
PgDnlower selection one step

Path

Convert to path

Shift+Ctrl+Cconvert selected object(s) to path
Ctrl+Alt+Cconvert stroke to path

Booleans

Ctrl++union
Union combines any number of objects into a single path, removing overlaps.
Ctrl+-difference
Difference works on 2 objects, extracting the top from the bottom.
Ctrl+*intersection
Intersection creates a path representing the common (overlapping) area of all selected objects.
Ctrl+^exclusive OR (XOR)
XOR is similar to Union, except that it works on 2 objects and removes areas where the objects overlap.
Ctrl+/division (cut)
Division cuts the bottom object into pieces by the top object, preserving the fill and stroke of the bottom.
Ctrl+Alt+/cut path
Cut Path cuts the bottom object's stroke only where it is intersected by the top path, removing any fill from the result.
The result of Union, Difference, Intersection, and XOR inherits the id= attribute and therefore the clones of the bottom object.
Division and Cut path normally produce several objects; of them, a random one inherits the id= of the bottom source object.

Offsets

Ctrl+(inset path (towards center)
Ctrl+)outset path (away from center)
The default offset distance is 2 px (SVG pixel units, not screen pixels).
Alt+(inset path by 1 pixel
Alt+)outset path by 1 pixel
Shift+Alt+(inset path by 10 pixels
Shift+Alt+)outset path by 10 pixels
The actual distance for pixel offsets depends on zoom level. Zoom in for finer adjustment.
All the (, ) commands convert the object to path, if necessary, and produce regular path.
Ctrl+Jcreate dynamic offset
Ctrl+Alt+Jcreate linked offset
These commands produce an offset object, editable by the node tool, standalone or linked to the original.
Shift+Dselect source
Selecting a linked offset and giving this command will select the source path of the linked offset.

Combine

Ctrl+Kcombine paths
This is different from grouping in that combined paths create one object.
This is different from Union in that overlapping areas are not affected.
Whether overlapping areas are filled is controlled by the Fill: winding/alternating switch on the Fill & Stroke dialog.
Shift+Ctrl+Kbreak paths apart
This attempts to break an object into constituent paths; it will fail if the object is one solid path.

Simplify

Ctrl+Lsimplify
This command attempts to simplify selected path(s) by removing extra nodes. It converts all objects to paths first.
If you invoke this command several times in quick succession, it will act more and more aggressively.
Invoking Simplify again after a pause restores the default threshold (settable in the Inkscape Preferences dialog).

Selector

Keyboard select

Tabselect next object
Shift+Tabselect previous object
These keys pick objects in their z-order (Tab cycles from bottom to top, Shift+Tab cycles from top to bottom).
Unless you did manual rearrangements, the last object you created is always on top.
As a result, if nothing is selected, pressing Shift+Tab once conveniently selects the object you created last.
This works on objects within the current layer (unless you change that in preferences).
Ctrl+Aselect all (current layer)
This works on objects within the current layer (unless you change that in preferences).
Ctrl+Alt+Aselect all (all layers)
This works on objects in all visible and unlocked layers.
!invert selection (current layer)
This inverts selection (deselects what was selected and vice versa) in the current layer.
Alt+!invert selection (all layers)
This inverts selection (deselects what was selected and vice versa) in visible and unlocked layers.
Escdeselect
Backspace, +Deldelete selection

Keyboard move

arrowsmove selection by the nudge distance
Shift+arrowsmove selection by 10x nudge distance
The default nudge distance is 2 px (SVG pixel units, not screen pixels).
Alt+arrowsmove selection by 1 pixel
Alt+Shift+arrowsmove selection by 10 pixels
The actual distance for pixel movements depends on zoom level. Zoom in for finer movement.

Keyboard scale

., +>scale selection up by the scale step
,, +<scale selection down by the scale step
The default scale step is 2 px (SVG pixel units, not screen pixels).
Ctrl+., +Ctrl+>scale selection to 200%
Ctrl+,, +Ctrl+<scale selection to 50%
Alt+., +Alt+>scale selection up by 1 pixel
Alt+,, +Alt+<scale selection down by 1 pixel
The actual size increment for pixel scaling depends on zoom level. Zoom in for finer scaling.
Scaling is uniform around the center, so that the size increment applies to the larger of the two dimensions.

Keyboard rotate

[, +]rotate selection by the angle step
The default angle step is 15 degrees. ] rotates clockwise, [ rotates counterclockwise.
Ctrl+[, +Ctrl+]rotate selection by 90 degrees
Alt+[, +Alt+]rotate selection by 1 pixel
The actual angle for pixel rotation depends on zoom level. Zoom in for finer movement.

Keyboard flip

hflip selection horizontally
vflip selection vertically

Mouse select

clickselect an object
When you left-click on an object, previous selection is deselected.
Shift+clicktoggle selection
Shift+click adds an object to the current selection if it was not selected, or deselects it otherwise.
clickclickedit the object
For paths, double clicking switches to Node tool; for shapes, to corresponding shape tool; for text, to Text tool.
For groups, double clicking performs the "Enter group" command (the group becomes temporary layer).

Select within group, select under

Ctrl+clickselect within group
Ctrl+click selects the object at click point disregarding any levels of grouping that this object might belong to.
Ctrl+Shift+clicktoggle selection within group
Alt+clickselect under
Alt+click selects the object at click point which is beneath (in z-order) the lowest selected object at click point.
If the bottom object is reached, Alt+click again selects the top object. So, several Alt+clicks cycle through z-order stack at point.
On Linux, Alt+click and Alt+drag may be reserved by the window manager. Reconfigure it so you can use them in Inkscape.
Shift+Alt+clicktoggle under
Ctrl+Alt+clickselect under, in groups
Shift+Ctrl+Alt+clicktoggle under, in groups

Rubberband

mouse dragselect multiple objects
Dragging around objects does "rubberband" selection; previous selection is deselected.
Shift+mouse dragadd objects to selection
Normally, you need to start from an empty space to initiate a rubberband.
However, if you press Shift before dragging, Inkscape will do rubberband selection even if you start from an object.

Mouse move

mouse dragselect + move
Dragging an object selects it if it was not selected, then moves selection.
Alt+mouse dragmove selected
Alt+drag moves the current selection (without selecting what is under cursor), no matter where you start the drag.
On Linux, Alt+click and Alt+drag may be reserved by the window manager. Reconfigure it so you can use them in Inkscape.
Ctrl+mouse dragrestrict movement to horizontal or vertical
Shift+mouse dragtemporarily disable snapping
This temporaily disables snapping to grid or guides when you are dragging with grid or guides on.
mouse dragSpacedrop a copy
When dragging or transforming with mouse, each Space leaves a copy of the selected object.
You can press and hold Space while dragging for a nice "trail."

Mouse transform

clicktoggle scale/rotation handles
mouse dragscale (scale handles)
mouse dragrotate or skew (rotation handles)

Scale handles

Ctrl+mouse dragscale preserving aspect ratio
Shift+mouse dragsymmetric transformation
Holding Shift while transforming makes transformation symmetric around the center of the selection.
Alt+mouse dragslow movement
Holding Alt while transforming makes transformation lag behind mouse movement, allowing finer changes.

Rotation handles

Ctrl+mouse dragsnap skew angle
Holding Ctrl when dragging a skew (non-corner) handle snaps the skew angle to angle steps (default 15 degrees).
Ctrl+mouse dragsnap rotation angle
Holding Ctrl when dragging a rotation (corner) handle snaps the rotation angle to angle steps (default 15 degrees).

Cancel

Esccancel rubberband, move, transformation
Press Esc while mouse button is still down to cancel rubberband selection, move, or transformation of any kind.

Node tool

Keyboard select

Tabselect next node
Shift+Tabselect previous node
These keys select nodes within the selected path
Ctrl+Aselect all nodes in subpath(s)
If the path has multiple subpaths and some nodes selected, this selects all only in subpaths with already selected nodes.
Ctrl+Alt+Aselect all nodes in path
This selects all nodes in the entire path.
!invert selection in subpath(s)
If the path has multiple subpaths and some nodes selected, this inverts selection only in subpaths with already selected nodes.
Alt+!invert selection in path
This inverts selection (deselects what was selected and vice versa) in the entire path.
Escdeselect all nodes

Keyboard move

arrowsmove selected node(s) by the nudge distance
Shift+arrowsmove selected node(s) by 10x nudge distance
The default nudge distance is 2 px (SVG pixel units, not screen pixels).
Alt+arrowsmove selected node(s) by 1 pixel
Alt+Shift+arrowsmove selected node(s) by 10 pixels
The actual distance for pixel movements depends on zoom level. Zoom in for finer movement.

Keyboard handle scale (1 node selected)

<, +>contract/expand both handles by scale step
The default scale step is 2 px (SVG pixel units, not screen pixels). May apply to more than one node.
Left Ctrl+<, +Left Ctrl+>scale left handle by the scale step
Right Ctrl+<, +Right Ctrl+>scale right handle by the scale step
Left Alt+<, +Left Alt+>scale left handle by 1 pixel
Right Alt+<, +Right Alt+>scale right handle by 1 pixel
The actual size increment for pixel scaling depends on zoom level. Zoom in for finer scaling.
Instead of the < and > keys, you can use the , (comma) and . (period) keys respectively.

Keyboard handle rotate (1 node selected)

[, +]rotate both handles by the angle step
The default angle step is 15 degrees. ] rotates clockwise, [ rotates counterclockwise. May apply to more than one node.
Left Ctrl+[, +Left Ctrl+]rotate left handle by the angle step
Right Ctrl+[, +Right Ctrl+]rotate right handle by the angle step
Left Alt+[, +Left Alt+]rotate left handle by 1 pixel
Right Alt+[, +Right Alt+]rotate right handle by 1 pixel

Keyboard scale (>1 nodes selected)

These commands scale the selected nodes as if they were an "object", around the center of that object.
., +>scale nodes up by the scale step
,, +<scale nodes down by the scale step
The default scale step is 2 px (SVG pixel units, not screen pixels).
Alt+., +Alt+>scale nodes up by 1 pixel
Alt+,, +Alt+<scale nodes down by 1 pixel
The actual size increment for pixel scaling depends on zoom level. Zoom in for finer scaling.
Scaling is uniform around the center, so that the size increment applies to the larger of the two dimensions.

Keyboard rotate (>1 nodes selected)

These commands rotate the selected nodes as if they were an "object", around the center of that object.
[, +]rotate nodes by the angle step
The default angle step is 15 degrees. ] rotates clockwise, [ rotates counterclockwise.
Alt+[, +Alt+]rotate nodes by 1 pixel
The actual angle for pixel rotation depends on zoom level. Zoom in for finer movement.

Keyboard flip (>1 nodes selected)

These commands flip the selected nodes as if they were an "object", around the center of that object.
hflip nodes horizontally
vflip nodes vertically

Change segment(s)

Shift+Lmake line
Shift+Umake curve
These commands require that more than two adjacent nodes be selected.

Change node type

Shift+Cmake cusp
Shift+Smake smooth
Shift+Ymake symmetric
Ctrl+clicktoggle smooth/cusp/symmetric

Join/break

Shift+Jjoin selected nodes
This requires that exactly two end nodes within the path be selected.
Shift+Bbreak selected node(s)
After break, only one of each two new nodes is selected. May apply to more than one node.

Delete, create, duplicate

Backspace, +Deldelete selected node(s)
Ctrl+Alt+clickcreate/delete node
Ctrl+Alt+click on a node deletes it; Ctrl+Alt+click on the path between nodes creates a new node in the click point.
clickclickcreate node
Double clicking on the path between nodes creates a node in the click point.
Insinsert new node(s)
This adds new node(s) in the middle(s) of selected segment(s), so it requires that more than two adjacent nodes be selected.
Shift+Dduplicate selected node(s)
New nodes are created on the same path; they are placed exactly over the old ones and are selected.

Mouse select: objects

clickclick a non-selected object to select
Alt+clickselect under
Shift+clicktoggle selection
These work the same as in Selector. The nodes or handles of the single selected object become editable.

Mouse select: nodes

clickselect a node
Clicking on a node selects it.
clickselect two adjacent nodes
Clicking on a selected path between the nodes selects the two nodes closest to the click point.
Shift+clicktoggle selection
This adds/removes a node (if clicked on node) or two nodes (if clicked on path) to/from the node selection.
clickdeselect
Clicking in an empty space deselects all selected nodes. Next click will deselect the object.

Rubberband

mouse dragselect multiple nodes
Dragging around nodes does "rubberband" selection; previous node selection is deselected.
Shift+mouse dragadd nodes to selection
Normally, you need to start from a point not over a path or a node to initiate a rubberband.
However, if you press Shift before dragging, Inkscape will do rubberband selection even if you start over the path.

Node move (mouse)

mouse dragmove selected nodes
Ctrl+mouse dragrestrict movement to horizontal or vertical
Ctrl+Alt+mouse dragmove along handles
This restricts movement to the directions of the node's handles, their continuations and perpendiculars (total 8 snaps).
If the node has straight lines on one or both sides, this will snap it to these lines' directions and perpendiculars instead.
Shift+mouse dragtemporarily disable snapping
Snapping nodes is enabled in Document Preferences. By default, only bounding box of objects snaps to grid/guides.
Shift+mouse dragdrag out handle
If a node has a retracted handle, dragging with Shift lets you drag it out of the node.
mouse dragSpacedrop a copy
When dragging nodes with mouse, each Space leaves a copy of the selected object.
You can press and hold Space while dragging for a nice "trail."

Node handles

mouse dragmove a node handle
Ctrl+mouse dragsnap the handle to angle steps
The default angle step is 15 degrees. This also snaps to the handle's original angle, its continuation and perpendiculars.
Shift+mouse dragrotate both handles
Alt+mouse draglock the handle length
Ctrl, Shift, Alt can be combined when dragging handles.
Ctrl+clickretract the handle
Retracted handle is zero length; use Shift+drag to drag it back out.

Reversing

Shift+rreverse path direction

Editing shapes

Node tool can also drag the handles of shapes (rectangles, ellipses, stars, spirals). Click on a shape to select it.
See the corresponding shape tools for their editing shortcuts, all of which also work in node tool.

Cancel

Esccancel rubberband or move
Press Esc while mouse button is still down to cancel rubberband selection, node move, handle move, or handle move.

Rectangle tool

Drawing

mouse dragdraw a rectangle
Ctrl+mouse dragmake a square or integer-ratio rectangle
This restricts rectangle so its height/width ratio is a whole number.
Shift+mouse dragdraw around the starting point
This creates a rectangle symmetric around the starting point of the mouse drag.

Editing

clickclick an object to select
Alt+clickselect under
Shift+clicktoggle selection
mouse dragdrag a handle to resize or round corners
Initially, the two rounding handles are in the top right corner; two resize handles are in top left and bottom right corners.
Ctrl+mouse draglock width, height, or ratio (resize handles)
Ctrl+mouse draglock the corner circular (rounding handles)
Resize handles change the width and height of the rectangle in its own coordinate system, before any transforms are applied.
When rounding corners, dragging only one rounding handle (with the other at the corner) keeps the corner circular.
You can drag both handles for an elliptic rounded corner, or drag one with Ctrl to make sure the other one is synchronized.
Escdeselect

Ellipse tool

Drawing

mouse dragdraw an ellipse
Ctrl+mouse dragmake circle or integer-ratio ellipse
This restricts ellipse so its height/width ratio is a whole number.
Shift+mouse dragdraw around the starting point
This creates an ellipse symmetric around the starting point of the mouse drag.

Editing

clickclick an object to select
Alt+clickselect under
Shift+clicktoggle selection
mouse dragdrag a handle to resize, make arc or segment
Initially, the two arc/segment handles are in the rightmost point; two resize handles are at the topmost and leftmost points.
Ctrl+mouse draglock circle (resize handles)
Ctrl+mouse dragsnap to angle steps (arc/segment handles)
Resize handles change the width and height of the ellipse in its own coordinate system, before any transforms are applied.
The default angle step is 15 degrees.
Escdeselect

Star tool

Drawing

mouse dragdraw a star
Ctrl+mouse dragsnap star to angle steps
The default angle step is 15 degrees.

Editing

clickclick an object to select
Alt+clickselect under
Shift+clicktoggle selection
mouse dragdrag a handle to vary the star shape
Ctrl+mouse dragkeep star rays radial (no skew)
Shift+mouse draground the star
Shift+clickremove rounding
Alt+mouse dragrandomize the star
Alt+clickremove randomization
Escdeselect

Spiral tool

Drawing

mouse dragdraw a spiral
Ctrl+mouse dragsnap spiral to angle steps
The default angle step is 15 degrees.

Editing

clickclick an object to select
Alt+clickselect under
Shift+clicktoggle selection
mouse dragroll/unroll from inside (inner handle)
Dragging the inner handle adjusts the "inner radius" parameter.
Alt+mouse dragconverge/diverge (inner handle)
Alt+clickreset divergence (inner handle)
Vertical Alt+drag of the inner handle adjusts the "divergence" parameter, Alt+click resets it to 1.
Shift+clickzero inner radius (inner handle)
Shift+click on inner handle makes the spiral start from the center.
mouse dragroll/unroll from outside (outer handle)
Dragging the outer handle adjusts the "turns" parameter. Use Shift+Alt+drag to roll/unroll without changing radius.
Shift+mouse dragscale/rotate (outer handle)
Use Shift+Alt to rotate only (locks the radius of the spiral).
Ctrl+mouse dragsnap handles to angle steps
The default angle step is 15 degrees. This works for both handles.
Escdeselect

Zoom tool

clickzoom in
Shift+clickzoom out
mouse dragzoom into the area

Freehand tool

mouse dragdraw a freehand line
Shift+mouse dragadd to selected path
If a path is selected, Shift+dragging anywhere creates a new subpath instead of a new independent path.
Shift+mouse dragtemporarily disable snapping
Shift also temporaily disables snapping to grid or guides when you are drawing with grid or guides on.

Bezier (Pen) tool

Create nodes

clickcreate a sharp node
If no path is being created, this starts a new path.
Shift+clickadd to selected path
If a path is selected, Shift+clicking anywhere starts a new subpath instead of a new independent path.
mouse dragcreate a bezier node with two handles
Shift+mouse dragmove only one handle
This moves only one handle (instead of both) to create a cusp node.
Ctrl+mouse dragsnap the handle to angle steps
The default angle step is 15 degrees.

Create segments

Ctrl+snap the segment to angle steps
This snaps the new node's angle, relative to the previous node, to angle steps (default 15 degrees).

Finish

Enterfinish current line
right clickfinish current line
clickclickfinish current line
Enter, right click, or double left click finish the current line, discarding the last unfinished (red) segment.

Keyboard

Esccancel current line
Backspace, +Delerase last segment of current line

Calligraphy

mouse dragdraw a calligraphic line
Left arrow, +Right arrowadjust pen width
Up arrow, +Down arrowadjust pen angle
Width and angle can be adjusted while drawing.

Gradient tool

Creating gradients

mouse dragcreate gradient
This creates gradient on selected objects. The Controls bar lets you select linear/radial and fill/stroke for the new gradient.
clickclickcreate default gradient
This creates default (horizontal edge-to-edge for linear, centered edge-to-edge-to-edge for radial) gradient on clicked object.

Handles

Tabselect next handle
Shift+Tabselect previous handle
arrowsmove selected handle by the nudge distance
Shift+arrowsmove selected handle by 10x nudge distance
The default nudge distance is 2 px (SVG pixel units, not screen pixels).
Alt+arrowsmove selected handle by 1 pixel
Alt+Shift+arrowsmove selected handle by 10 pixels
The actual distance for pixel movements depends on zoom level. Zoom in for finer movement.
Escdeselect handle
clickclickopen gradient editor
Double clicking a gradient handle opens the Gradient Editor with that gradient and the clicked handle chosen in the stops list.

Reversing

Shift+rreverse gradient definition
This mirrors the stop positions of the current gradient without moving the gradient handles.

Mouse select

clickclick an object to select
Alt+clickselect under
Shift+clicktoggle selection

Dropper tool

clickpick fill color
Shift+clickpick stroke color
mouse dragaverage fill color
Shift+mouse dragaverage stroke color
Click applies the color under cursor to the current selection. Dragging a radius calculates the average color of a circular area.
If a gradient handle (in Gradient tool) is selected, it gets the color instead of the entire object.
Alt+click, +Alt+mouse dragpick inverse color
If Alt is pressed, picking color (with or without Shift, by click or by drag) picks the inverse of the color.
Ctrl+Ccopy color
This copies the color under cursor to the system clipboard, as text in RRGGBBAA format (8 hex digits).

Text tool

Selecting/creating

clickcreate/select a text object
Clicking in an empty space or on a non-text creates a text object; now you can type your text.
Clicking on a text object selects it; cursor is placed near the click point.
Escdeselect the text object

Text navigation

arrowsmove cursor by one character
Ctrl+Left arrow, +Ctrl+Right arrowmove cursor by one word
Ctrl+Up arrow, +Ctrl+Down arrowmove cursor by one paragraph
Home, +Endgo to beginning/end of line
Ctrl+Home, +Ctrl+Endgo to beginning/end of text
All these commands cancel current text selection, if any.

Flowed text (internal frame)

mouse dragcreate flowed text
Clicking and dragging in an empty space or on a non-text creates a flowed text object with internal frame.
mouse dragadjust frame size
Dragging the handle in the lower right corner of the selected flowed text changes width/height of the frame.
Ctrl+mouse draglock width, height, or ratio of frame
Dragging the corner handle with Ctrl resizes the frame preserving either width, or height, or ratio.

Flowed text (external frame)

Alt+Wflow text into frame
With a text object and a shape/path selected, this flows text into the shape/path.
Both remain separate objects, but are linked; editing the shape/path causes the text to reflow.
Alt+Shift+Wunflow text from frame
This cuts the flowed text's link to the shape/path, producing a single-line regular text object.
Shift+Dselect external frame
To find out which object is the frame of this flowed text, select it and press Shift+D. The frame will be selected.

Text on path

Shift+Dselect path
To find out which path this text is put on, select it and press Shift+D. The path will be selected.

Editing text

To type + and - characters, use the main keyboard; keypad + and - are reserved for zoom (unless NumLock is on).
Enterstart a new line or paragraph
Enter in regular text creates new line; in flowed text it creates a new paragraph
Ctrl+Utoggle Unicode entry
To insert an arbitrary Unicode character, type Ctrl+U, then the hexadecimal code point, then Enter.
For example, Ctrl+U 2 0 1 4 Enter inserts an em-dash.
To stay in Unicode mode after inserting the character, press Space instead of Enter.
Press Esc or another Ctrl+U to cancel Unicode mode without inserting the character.
Ctrl+Spaceinsert no-break space
A no-break space is visible even in a text object without xml:space="preserve".

Selecting text

mouse dragselect text
Left-dragging over a text object selects a text span.
Shift+arrowsselect text by character
Ctrl+Shift+arrowsselect text by word
Shift+Home, +Shift+Endselect to beginning/end of line
Ctrl+Shift+Home, +Ctrl+Shift+Endselect to beginning/end of text
clickclickselect word
clickclickclickselect line
Ctrl+Aselect all text
This selects the entire text of the current text object.

Styling selection

Ctrl+Bmake selection bold
Ctrl+Imake selection italic
Also, you can use the Text&Font or Fill&Stroke dialogs to assign any style to text selection.

Letter spacing

Alt+>expand line/paragraph by 1 pixel
Shift+Alt+>expand line/paragraph by 10 pixels
Alt+<contract line/paragraph by 1 pixel
Shift+Alt+<contract line/paragraph by 10 pixels
These commands (only when editing text) adjust letter spacing in the current line (regular text) or paragraph (flowed text).
The actual adjustment for pixel movements depends on zoom level. Zoom in for finer adjustment.

Line spacing

Ctrl+Alt+>make the text object taller by 1 pixel
Shift+Ctrl+Alt+>make the text object taller by 10 pixels
Ctrl+Alt+<make the text object shorter by 1 pixel
Shift+Ctrl+Alt+<make the text object shorter by 10 pixels
These commands (only when editing text) adjust line spacing in the entire text object (regular or flowed).
The actual adjustment for pixel movements depends on zoom level. Zoom in for finer adjustment.

Kerning and shifting

Alt+arrowsshift characters by 1 pixel
Shift+Alt+arrowsshift characters by 10 pixels
These commands work when editing a regular text object. Kerning does not work in flowed text.
With no selection, they shift (horizontally or vertically) the characters after the cursor until the end of line.
With selection, they shift the selection relative to the rest of text (by inserting opposite kerns at both ends of selection).
The actual adjustment for pixel movements depends on zoom level. Zoom in for finer adjustment.

Rotating

Ctrl+[, +Ctrl+]rotate character(s) by 90 degrees
Alt+[, +Alt+]rotate character(s) by 1 pixel
These commands rotate the next character (without selection) or all characters in the selection (with selection).
Rotation only works in regular text (not flowed text).
The actual angle for pixel rotation depends on zoom level. Zoom in for finer movement.

Valid HTML 4.0!

diff --git a/doc/keys.xml b/doc/keys.xml new file mode 100644 index 000000000..f566480b4 --- /dev/null +++ b/doc/keys.xml @@ -0,0 +1,1104 @@ + + +

Unless noted otherwise, keypad keys (such as arrows, Home, End, +, -, digits) are +supposed to work the same as corresponding regular keys. If you have a new shortcut +idea, please contact the developers (by writing to the devel mailing list +or by submitting an +RFE).

+ + + +*
+ + +s Selector + Selector (temporary) +Space switches to the Selector tool temporarily; another Space switches back. +n Node tool +z Zoom tool +r Rectangle tool +e Ellipse/arc tool +p Freehand (Pencil) tool +b Bezier (Pen) tool +c Calligraphic tool +g Gradient tool +d Dropper tool +t Text tool +i Spiral tool +* Star tool +o Connector tool +Double click on the tool buttons opens the Preferences dialog showing the page of the corresponding tool. + +
+ + +*
+ +F Fill and Stroke +W Swatches +T Text and Font +M Transform +A Align and Distribute +O Object Properties +X XML Editor +D Document Preferences +P Inkscape Preferences +E Export to PNG +F Find +B Trace bitmap +These open a new dialog window if it wasn't open yet, otherwise the corresponding dialog gets focus. + + + +Toggle visibility + toggle dialogs +This temporarily hides all open dialogs; another F12 shows them again. + + + +Within a dialog + return to the canvas + W close the dialog + jump to next widget + jump to previous widget + set the new value +This accepts the new value you typed in a text field and returns focus to canvas. + in XML Editor, set the attr value +When editing an attribute value in XML Editor, this sets the new value (same as clicking the "Set attribute" button). + activate current button or list + in a multi-tab dialog, switch tabs + +
+ +*
+ + +The Controls bar at the top of the document window provides different buttons and controls for each tool. +X jump to the first editable field + accept the new value +This accepts the new value you typed in a text field and returns focus to canvas. + cancel changes, return to canvas +This cancels any changes you made in a text field and returns focus to canvas. +Z cancel changes +This cancels any changes you made in a text field but you stay in the field. + jump to next field + jump to previous field +Use these to navigate between fields in the Controls bar (the value in the field you leave, if changed, is accepted). + + + +Changing values + change value by 0.1 + change value by 5.0 + + +
+ +*
+ + +Zoom += + zoom in +- zoom out +The keypad +/- keys do zooming even when you are editing a text object, unless NumLock is on. + zoom in + zoom out + zoom in or out + zoom into the area +Z activate zoom field +The zoom field in the lower left corner of the window allows you to specify zoom level precisely. + + + +Preset zooms +1 zoom 1:1 +2 zoom 1:2 +3 zoom to selection +4 zoom to drawing +5 zoom to page +E6 zoom to page width + + + +Zoom history +` (back quote) previous zoom +` next zoom +With these keys, you can travel back and forth through the history of zooms in this session + + + +Scrolling (panning) + scroll canvas +Scrolling by keys is accelerated, i.e. it speeds up when you press Ctrl+arrows in quick succession, or press and hold. + pan canvas + pan canvas + scroll canvas vertically + scroll canvas horizontally + + + +Guides and grid + drag off a ruler to create guide +Drag off the horizontal or vertical ruler to create a new guideline. Drag a guideline onto the ruler to delete it. +| \ toggle guides and snapping to guides +If you want to have different values for guides visibility and snapping, set them via the Document Options dialog. +When you create a new guide by dragging off the ruler, guide visibility and snapping are turned on. +# 3 toggle grid and snapping to grid +If you want to have different values for grid visibility and snapping, set them via the Document Options dialog. +Note that only the 3 key on the main keyboard works, not on the keypad. + +
+ + +
+ + + + + + + +*
+ + +N create new document +O open an SVG document +E export to PNG +I import bitmap or SVG +P print document +S save document +S save under a new name +Q exit Inkscape + + +
+ +*
+ + +R toggle rulers +B toggle scrollbars + toggle fullscreen + + + + main menu +Menus can also be activated by Alt with the letter underscored in the menu name. + drop-down (context) menu + + + + W close document window +This shuts down Inkscape if it was the only document window open. + next document window + previous document window +These cycle through the active document windows forward and backward. + + +
+ + +*
+ + move to layer above + move to layer below +These commands move the selected objects from one layer to another. + + raise layer + lower layer + raise layer to top + lower layer to bottom +These commands move the current layer among its siblings (normally other layers). + +
+ + +*
+ + +Undo/redo +Y Z undo +Z Y redo + + + +Clipboard +C copy selection +This places a copy of the selection to the Inkscape clipboard. Text from text objects is also placed onto the system clipboard. +X cut selection +This works the same as "copy selection" followed by deleting the selection. +V paste clipboard +This places the clipboard objects at the mouse cursor, or at the center of the window if mouse is outside the canvas. +When editing text with the text tool, this pastes the text from the system clipboard into the current text object. +V paste in place +This places the clipboard objects to the original location from which they were copied. +V paste style +This applies the style of the (first of the) coped object(s) to the current selection. +If a gradient handle (in Gradient tool) or a text span (in Text tool) are selected, they get the style instead of the entire object. + + + +Duplicate +D duplicate selection +New object(s) are placed exactly over the original(s) and selected. + + + +Clone +D clone object +A clone can be moved/scaled/rotated/skewed independently, but it updates the path, fill, and stroke from its original. +The clone is placed exactly over the original object and is selected. +You can only clone one object at a time; if you want to clone several objects together, group them and clone the group. +D unlink clone +Unlinking a clone cuts the link to the original, turning the clone into a plain copy. +D select original +To find out which object this is a clone of, select the clone and give this command. The original will be selected. + + + +Bitmaps +B create a bitmap copy +This exports the selected object(s) (all other objects hidden) as PNG in the document's directory and imports it back. +The imported bitmap is placed over the original selection and is selected. +B trace bitmap +This opens the Trace Bitmap dialog allowing you to convert a bitmap object to path(s). + + + +Patterns +I object(s) to pattern +This converts the selection to a rectangle with tiled pattern fill. +I pattern to object(s) +Each selected object with pattern fill is broken into the same object without fill and a single pattern object. + + + +Group + U G group selected objects +Use Ctrl+click to select objects within group. +G U ungroup selected group(s) +This removes only one level of grouping; press Ctrl+U repeatedly to ungroup nested groups. + + + +Z-order + raise selection to top + lower selection to bottom + raise selection one step + lower selection one step + + +
+ +*
+ + +Convert to path +C convert selected object(s) to path +C convert stroke to path + + + +Booleans ++ union +Union combines any number of objects into a single path, removing overlaps. +- difference +Difference works on 2 objects, extracting the top from the bottom. +* intersection +Intersection creates a path representing the common (overlapping) area of all selected objects. +^ exclusive OR (XOR) +XOR is similar to Union, except that it works on 2 objects and removes areas where the objects overlap. +/ division (cut) +Division cuts the bottom object into pieces by the top object, preserving the fill and stroke of the bottom. +/ cut path +Cut Path cuts the bottom object's stroke only where it is intersected by the top path, removing any fill from the result. +The result of Union, Difference, Intersection, and XOR inherits the id= attribute and therefore the clones of the bottom object. +Division and Cut path normally produce several objects; of them, a random one inherits the id= of the bottom source object. + + + +Offsets +( inset path (towards center) +) outset path (away from center) +The default offset distance is 2 px (SVG pixel units, not screen pixels). +( inset path by 1 pixel +) outset path by 1 pixel +( inset path by 10 pixels +) outset path by 10 pixels +The actual distance for pixel offsets depends on zoom level. Zoom in for finer adjustment. +All the (, ) commands convert the object to path, if necessary, and produce regular path. +J create dynamic offset +J create linked offset +These commands produce an offset object, editable by the node tool, standalone or linked to the original. +D select source +Selecting a linked offset and giving this command will select the source path of the linked offset. + + + +Combine +K combine paths +This is different from grouping in that combined paths create one object. +This is different from Union in that overlapping areas are not affected. +Whether overlapping areas are filled is controlled by the Fill: winding/alternating switch on the Fill & Stroke dialog. +K break paths apart +This attempts to break an object into constituent paths; it will fail if the object is one solid path. + + + +Simplify +L simplify +This command attempts to simplify selected path(s) by removing extra nodes. It converts all objects to paths first. +If you invoke this command several times in quick succession, it will act more and more aggressively. +Invoking Simplify again after a pause restores the default threshold (settable in the Inkscape Preferences dialog). + + +
+ +
+ + + +*
+ + +Keyboard select + select next object + select previous object +These keys pick objects in their z-order (Tab cycles from bottom to top, Shift+Tab cycles from top to bottom). +Unless you did manual rearrangements, the last object you created is always on top. +As a result, if nothing is selected, pressing Shift+Tab once conveniently selects the object you created last. +This works on objects within the current layer (unless you change that in preferences). +A select all (current layer) +This works on objects within the current layer (unless you change that in preferences). +A select all (all layers) +This works on objects in all visible and unlocked layers. +! invert selection (current layer) +This inverts selection (deselects what was selected and vice versa) in the current layer. +! invert selection (all layers) +This inverts selection (deselects what was selected and vice versa) in visible and unlocked layers. + deselect + delete selection + + + +Keyboard move + move selection by the nudge distance + move selection by 10x nudge distance +The default nudge distance is 2 px (SVG pixel units, not screen pixels). + move selection by 1 pixel + move selection by 10 pixels +The actual distance for pixel movements depends on zoom level. Zoom in for finer movement. + + + +Keyboard scale +. > scale selection up by the scale step +, < scale selection down by the scale step +The default scale step is 2 px (SVG pixel units, not screen pixels). +. > scale selection to 200% +, < scale selection to 50% +. > scale selection up by 1 pixel +, < scale selection down by 1 pixel +The actual size increment for pixel scaling depends on zoom level. Zoom in for finer scaling. +Scaling is uniform around the center, so that the size increment applies to the larger of the two dimensions. + + + +Keyboard rotate +[ ] rotate selection by the angle step +The default angle step is 15 degrees. ] rotates clockwise, [ rotates counterclockwise. +[ ] rotate selection by 90 degrees +[ ] rotate selection by 1 pixel +The actual angle for pixel rotation depends on zoom level. Zoom in for finer movement. + + + +Keyboard flip +h flip selection horizontally +v flip selection vertically + + + +Mouse select + select an object +When you left-click on an object, previous selection is deselected. + toggle selection +Shift+click adds an object to the current selection if it was not selected, or deselects it otherwise. + edit the object +For paths, double clicking switches to Node tool; for shapes, to corresponding shape tool; for text, to Text tool. +For groups, double clicking performs the "Enter group" command (the group becomes temporary layer). +Double clicking in empty space swithes to the parent layer in the hierarchy, if any. + + + +Select within group, select under + select within group +Ctrl+click selects the object at click point disregarding any levels of grouping that this object might belong to. + toggle selection within group + select under +Alt+click selects the object at click point which is beneath (in z-order) the lowest selected object at click point. +If the bottom object is reached, Alt+click again selects the top object. So, several Alt+clicks cycle through z-order stack at point. +On Linux, Alt+click and Alt+drag may be reserved by the window manager. Reconfigure it so you can use them in Inkscape. + toggle under + select under, in groups + toggle under, in groups + enter group + go to parent group + + + +Rubberband + select multiple objects +Dragging around objects does "rubberband" selection; previous selection is deselected. + add objects to selection +Normally, you need to start from an empty space to initiate a rubberband. +However, if you press Shift before dragging, Inkscape will do rubberband selection even if you start from an object. + + + +Mouse move + select + move +Dragging an object selects it if it was not selected, then moves selection. + move selected +Alt+drag moves the current selection (without selecting what is under cursor), no matter where you start the drag. +On Linux, Alt+click and Alt+drag may be reserved by the window manager. Reconfigure it so you can use them in Inkscape. + restrict movement to horizontal or vertical + temporarily disable snapping +This temporaily disables snapping to grid or guides when you are dragging with grid or guides on. + drop a copy +When dragging or transforming with mouse, each Space leaves a copy of the selected object. +You can press and hold Space while dragging for a nice "trail." + + + +Mouse transform + toggle scale/rotation handles + scale (scale handles) + rotate or skew (rotation handles) + + + +Scale handles + scale preserving aspect ratio + + symmetric transformation +Holding Shift while transforming makes transformation symmetric around the center of the selection. + + slow movement +Holding Alt while transforming makes transformation lag behind mouse movement, allowing finer changes. + + + +Rotation handles + snap skew angle +Holding Ctrl when dragging a skew (non-corner) handle snaps the skew angle to angle steps (default 15 degrees). + snap rotation angle +Holding Ctrl when dragging a rotation (corner) handle snaps the rotation angle to angle steps (default 15 degrees). + + + +Cancel + cancel rubberband, move, transformation +Press Esc while mouse button is still down to cancel rubberband selection, move, or transformation of any kind. + + +
+ +
+ + +*
+ + +Keyboard select + select next node + select previous node +These keys select nodes within the selected path +A select all nodes in subpath(s) +If the path has multiple subpaths and some nodes selected, this selects all only in subpaths with already selected nodes. +A select all nodes in path +This selects all nodes in the entire path. +! invert selection in subpath(s) +If the path has multiple subpaths and some nodes selected, this inverts selection only in subpaths with already selected nodes. +! invert selection in path +This inverts selection (deselects what was selected and vice versa) in the entire path. + deselect all nodes + + + +Keyboard move + move selected node(s) by the nudge distance + move selected node(s) by 10x nudge distance +The default nudge distance is 2 px (SVG pixel units, not screen pixels). + move selected node(s) by 1 pixel + move selected node(s) by 10 pixels +The actual distance for pixel movements depends on zoom level. Zoom in for finer movement. + + + +Keyboard handle scale (1 node selected) +< > contract/expand both handles by scale step +The default scale step is 2 px (SVG pixel units, not screen pixels). May apply to more than one node. + +< +> +scale left handle by the scale step + + +< +> +scale right handle by the scale step + + +< +> +scale left handle by 1 pixel + + +< +> +scale right handle by 1 pixel + +The actual size increment for pixel scaling depends on zoom level. Zoom in for finer scaling. +Instead of the < and > keys, you can use the , (comma) and . (period) keys respectively. + + + +Keyboard handle rotate (1 node selected) +[ ] rotate both handles by the angle step +The default angle step is 15 degrees. ] rotates clockwise, [ rotates counterclockwise. May apply to more than one node. +[ ] rotate left handle by the angle step +[ ] rotate right handle by the angle step +[ ] rotate left handle by 1 pixel +[ ] rotate right handle by 1 pixel + + + + +Keyboard scale (>1 nodes selected) +These commands scale the selected nodes as if they were an "object", around the center of that object. +. > scale nodes up by the scale step +, < scale nodes down by the scale step +The default scale step is 2 px (SVG pixel units, not screen pixels). +. > scale nodes up by 1 pixel +, < scale nodes down by 1 pixel +The actual size increment for pixel scaling depends on zoom level. Zoom in for finer scaling. +Scaling is uniform around the center, so that the size increment applies to the larger of the two dimensions. + + + +Keyboard rotate (>1 nodes selected) +These commands rotate the selected nodes as if they were an "object", around the center of that object. +[ ] rotate nodes by the angle step +The default angle step is 15 degrees. ] rotates clockwise, [ rotates counterclockwise. +[ ] rotate nodes by 1 pixel +The actual angle for pixel rotation depends on zoom level. Zoom in for finer movement. + + + +Keyboard flip (>1 nodes selected) +These commands flip the selected nodes as if they were an "object", around the center of that object. +h flip nodes horizontally +v flip nodes vertically + + + + +Change segment(s) +L make line +U make curve +These commands require that more than two adjacent nodes be selected. + + + +Change node type +C make cusp +S make smooth +Y make symmetric + toggle smooth/cusp/symmetric + + + +Join/break +J join selected nodes +This requires that exactly two end nodes within the path be selected. +B break selected node(s) +After break, only one of each two new nodes is selected. May apply to more than one node. + + + +Delete, create, duplicate + delete selected node(s) + create/delete node +Ctrl+Alt+click on a node deletes it; Ctrl+Alt+click on the path between nodes creates a new node in the click point. + create node +Double clicking on the path between nodes creates a node in the click point. + insert new node(s) +This adds new node(s) in the middle(s) of selected segment(s), so it requires that more than two adjacent nodes be selected. +D duplicate selected node(s) +New nodes are created on the same path; they are placed exactly over the old ones and are selected. + + + + + +Mouse select: objects + click a non-selected object to select + select under + toggle selection +These work the same as in Selector. The nodes or handles of the single selected object become editable. + + + +Mouse select: nodes + select a node +Clicking on a node selects it. + select two adjacent nodes +Clicking on a selected path between the nodes selects the two nodes closest to the click point. + toggle selection +This adds/removes a node (if clicked on node) or two nodes (if clicked on path) to/from the node selection. + deselect +Clicking in an empty space deselects all selected nodes. Next click will deselect the object. + + + +Rubberband + select multiple nodes +Dragging around nodes does "rubberband" selection; previous node selection is deselected. + add nodes to selection +Normally, you need to start from a point not over a path or a node to initiate a rubberband. +However, if you press Shift before dragging, Inkscape will do rubberband selection even if you start over the path. + + + + +Node move (mouse) + move selected nodes + restrict movement to horizontal or vertical + move along handles +This restricts movement to the directions of the node's handles, their continuations and perpendiculars (total 8 snaps). +If the node has straight lines on one or both sides, this will snap it to these lines' directions and perpendiculars instead. + temporarily disable snapping +Snapping nodes is enabled in Document Preferences. By default, only bounding box of objects snaps to grid/guides. + drag out handle +If a node has a retracted handle, dragging with Shift lets you drag it out of the node. + drop a copy +When dragging nodes with mouse, each Space leaves a copy of the selected object. +You can press and hold Space while dragging for a nice "trail." + + + +Node handles + move a node handle + snap the handle to angle steps +The default angle step is 15 degrees. This also snaps to the handle's original angle, its continuation and perpendiculars. + rotate both handles + lock the handle length +Ctrl, Shift, Alt can be combined when dragging handles. + retract the handle +Retracted handle is zero length; use Shift+drag to drag it back out. + + + +Reversing +r reverse path direction + + + +Editing shapes +Node tool can also drag the handles of shapes (rectangles, ellipses, stars, spirals). Click on a shape to select it. +See the corresponding shape tools for their editing shortcuts, all of which also work in node tool. + + + + +Cancel + cancel rubberband or move +Press Esc while mouse button is still down to cancel rubberband selection, node move, handle move, or handle move. + + +
+ +
+ + + + + +*
+ +Drawing + draw a rectangle + make a square or integer-ratio rectangle +This restricts rectangle so its height/width ratio is a whole number. + draw around the starting point +This creates a rectangle symmetric around the starting point of the mouse drag. + + +Editing + click an object to select + select under + toggle selection + drag a handle to resize or round corners +Initially, the two rounding handles are in the top right corner; two resize handles are in top left and bottom right corners. + lock width, height, or ratio (resize handles) + lock the corner circular (rounding handles) +Resize handles change the width and height of the rectangle in its own coordinate system, before any transforms are applied. +When rounding corners, dragging only one rounding handle (with the other at the corner) keeps the corner circular. +You can drag both handles for an elliptic rounded corner, or drag one with Ctrl to make sure the other one is synchronized. + deselect + +
+ +*
+ +Drawing + draw an ellipse + make circle or integer-ratio ellipse +This restricts ellipse so its height/width ratio is a whole number. + draw around the starting point +This creates an ellipse symmetric around the starting point of the mouse drag. + + +Editing + click an object to select + select under + toggle selection + drag a handle to resize, make arc or segment +Initially, the two arc/segment handles are in the rightmost point; two resize handles are at the topmost and leftmost points. + lock circle (resize handles) + snap to angle steps (arc/segment handles) +Resize handles change the width and height of the ellipse in its own coordinate system, before any transforms are applied. +The default angle step is 15 degrees. + deselect + +
+ +*
+ +Drawing + draw a star + snap star to angle steps +The default angle step is 15 degrees. + + +Editing + click an object to select + select under + toggle selection + drag a handle to vary the star shape + keep star rays radial (no skew) + round the star + remove rounding + randomize the star + remove randomization + deselect + +
+ +*
+ +Drawing + draw a spiral + snap spiral to angle steps +The default angle step is 15 degrees. + + +Editing + click an object to select + select under + toggle selection + roll/unroll from inside (inner handle) +Dragging the inner handle adjusts the "inner radius" parameter. + converge/diverge (inner handle) + reset divergence (inner handle) +Vertical Alt+drag of the inner handle adjusts the "divergence" parameter, Alt+click resets it to 1. + zero inner radius (inner handle) +Shift+click on inner handle makes the spiral start from the center. + + roll/unroll from outside (outer handle) +Dragging the outer handle adjusts the "turns" parameter. Use Shift+Alt+drag to roll/unroll without changing radius. + scale/rotate (outer handle) +Use Shift+Alt to rotate only (locks the radius of the spiral). + + snap handles to angle steps +The default angle step is 15 degrees. This works for both handles. + + deselect + +
+ + + +
+ + + + + + +*
+ + zoom in + zoom out + zoom into the area + +
+ +*
+ + draw a freehand line + add to selected path +If a path is selected, Shift+dragging anywhere creates a new subpath instead of a new independent path. + temporarily disable snapping +Shift also temporaily disables snapping to grid or guides when you are drawing with grid or guides on. + +
+ +*
+ + +Create nodes + create a sharp node +If no path is being created, this starts a new path. + add to selected path +If a path is selected, Shift+clicking anywhere starts a new subpath instead of a new independent path. + create a bezier node with two handles + move only one handle + +This moves only one handle (instead of both) to create a cusp node. + snap the handle to angle steps +The default angle step is 15 degrees. + + + +Create segments + snap the segment to angle steps +This snaps the new node's angle, relative to the previous node, to angle steps (default 15 degrees). + + + +Finish + finish current line + finish current line + finish current line +Enter, right click, or double left click finish the current line, discarding the last unfinished (red) segment. + + + +Keyboard + cancel current line + erase last segment of current line + +
+ +*
+ + draw a calligraphic line + adjust pen width + adjust pen angle +Width and angle can be adjusted while drawing. + deselect + +
+ +*
+ +Creating gradients + create gradient +This creates gradient on selected objects. The Controls bar lets you select linear/radial and fill/stroke for the new gradient. + create default gradient +This creates default (horizontal edge-to-edge for linear, centered edge-to-edge-to-edge for radial) gradient on clicked object. + + + +Handles + select next handle + select previous handle + move selected handle by the nudge distance + move selected handle by 10x nudge distance +The default nudge distance is 2 px (SVG pixel units, not screen pixels). + move selected handle by 1 pixel + move selected handle by 10 pixels +The actual distance for pixel movements depends on zoom level. Zoom in for finer movement. + deselect handle + open gradient editor +Double clicking a gradient handle opens the Gradient Editor with that gradient and the clicked handle chosen in the stops list. + + + +Reversing +r reverse gradient definition +This mirrors the stop positions of the current gradient without moving the gradient handles. + + + +Mouse select + click an object to select + select under + toggle selection + + +
+ + +*
+ + pick fill color + pick stroke color + average fill color + average stroke color +Click applies the color under cursor to the current selection. Dragging a radius calculates the average color of a circular area. +If a gradient handle (in Gradient tool) is selected, it gets the color instead of the entire object. + pick inverse color +If Alt is pressed, picking color (with or without Shift, by click or by drag) picks the inverse of the color. +C copy color +This copies the color under cursor to the system clipboard, as text in RRGGBBAA format (8 hex digits). + +
+ + +
+ + + + +*
+ + +Selecting/creating + create/select a text object + +Clicking in an empty space or on a non-text creates a text object; now you can type your text. +Clicking on a text object selects it; cursor is placed near the click point. + deselect the text object + + + +Text navigation + move cursor by one character + move cursor by one word + move cursor by one paragraph + go to beginning/end of line + go to beginning/end of text +All these commands cancel current text selection, if any. + + + +Flowed text (internal frame) + create flowed text +Clicking and dragging in an empty space or on a non-text creates a flowed text object with internal frame. + adjust frame size +Dragging the handle in the lower right corner of the selected flowed text changes width/height of the frame. + lock width, height, or ratio of frame +Dragging the corner handle with Ctrl resizes the frame preserving either width, or height, or ratio. + + + +Flowed text (external frame) +W flow text into frame +With a text object and a shape/path selected, this flows text into the shape/path. +Both remain separate objects, but are linked; editing the shape/path causes the text to reflow. +W unflow text from frame +This cuts the flowed text's link to the shape/path, producing a single-line regular text object. +D select external frame +To find out which object is the frame of this flowed text, select it and press Shift+D. The frame will be selected. + + + +Text on path +D select path from text +To find out which path this text is put on, select it and press Shift+D. The path will be selected. + + + +Editing text +To type + and - characters, use the main keyboard; keypad + and - are reserved for zoom (unless NumLock is on). + start a new line or paragraph +Enter in regular text creates new line; in flowed text it creates a new paragraph +U toggle Unicode entry +To insert an arbitrary Unicode character, type Ctrl+U, then the hexadecimal code point, then Enter. +For example, Ctrl+U 2 0 1 4 Enter inserts an em-dash. +To stay in Unicode mode after inserting the character, press Space instead of Enter. +Press Esc or another Ctrl+U to cancel Unicode mode without inserting the character. + insert no-break space +A no-break space is visible even in a text object without xml:space="preserve". + + + +Selecting text + select text +Left-dragging over a text object selects a text span. + select text by character + select text by word + select to beginning/end of line + select to beginning/end of text + select word + select line +A select all text +This selects the entire text of the current text object. + + + +Styling selection +B make selection bold +I make selection italic +Also, you can use the Text&Font or Fill&Stroke dialogs to assign any style to text selection. + + + +Letter spacing +> expand line/paragraph by 1 pixel +> expand line/paragraph by 10 pixels +< contract line/paragraph by 1 pixel +< contract line/paragraph by 10 pixels +These commands (only when editing text) adjust letter spacing in the current line (regular text) or paragraph (flowed text). +The actual adjustment for pixel movements depends on zoom level. Zoom in for finer adjustment. + + + +Line spacing +> make the text object taller by 1 pixel +> make the text object taller by 10 pixels +< make the text object shorter by 1 pixel +< make the text object shorter by 10 pixels +These commands (only when editing text) adjust line spacing in the entire text object (regular or flowed). +The actual adjustment for pixel movements depends on zoom level. Zoom in for finer adjustment. + + + +Kerning and shifting + shift characters by 1 pixel + shift characters by 10 pixels +These commands work when editing a regular text object. Kerning does not work in flowed text. +With no selection, they shift (horizontally or vertically) the characters after the cursor until the end of line. +With selection, they shift the selection relative to the rest of text (by inserting opposite kerns at both ends of selection). +The actual adjustment for pixel movements depends on zoom level. Zoom in for finer adjustment. + + + +Rotating +[ ] rotate character(s) by 90 degrees +[ ] rotate character(s) by 1 pixel +These commands rotate the next character (without selection) or all characters in the selection (with selection). +Rotation only works in regular text (not flowed text). +The actual angle for pixel rotation depends on zoom level. Zoom in for finer movement. + + +
+
+ +
diff --git a/doc/spsvgview.txt b/doc/spsvgview.txt new file mode 100644 index 000000000..f3f7d8892 --- /dev/null +++ b/doc/spsvgview.txt @@ -0,0 +1,15 @@ +Both spsvgview and sodipodi are mostly built frome set of common +libraries (these are static of course, to save people from +versioning pain, but can in theory function as dynamic libs +as well). +The shared dynamic SVG GUI is built from: +* libarikkei, libnr, libnrtype - lowlevel helper code +* libspxml - xml backbone +* libspsvg - svg parsing helpers +* libspdisplay - GUI-independent renderer +* libsodipodi - dynamic SVG document +Sodipodi and spsvgview attach SVG document to different +widgets (SPDesktop and SPSVGView), plus sodipodi adds +extra controller parts (event contexts, selections, dialogs). +The separation is still not 100%, but quite close, and should +be easy to complete, if needed. diff --git a/fix-roff-punct b/fix-roff-punct new file mode 100755 index 000000000..dc3c96c10 --- /dev/null +++ b/fix-roff-punct @@ -0,0 +1,139 @@ +#! /usr/bin/perl -w +use strict; + +# fix-roff-punct: Fix up punctuation usage in automatically-generated +# troff files (man pages). + +# Authors: +# Peter Moulder +# +# Copyright (C) 2004 Monash University +# +# Gnu GPL v2+: +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +# Background: Humans use a number of dash-like characters: +# +# - ASCII hyphen/minus needed for command-line options and other computer +# input; +# - hyphen (`one-to-one'); +# - en dash (`2000-2003'); +# - em dash -- like this. [Not currently handled.] +# +# Troff input spells them as \-, -, \[en], \[em] respectively. (See the +# groff_char.7 man page for a full list of such punctuation characters.) If +# you run `man' with your LC_CTYPE indicating a rich character set like unicode +# (UTF-8 encoding), then it uses different output characters for each of the +# above. +# +# In particular, if your man page source has plain `-' when giving an example +# of a flag or command or other program input, then users won't be able to use +# mouse copy&paste from the formatted man page. + +# This script is something of a hack: it is only big enough to handle a few man +# pages of interest (produced by pod2man). You should manually check the +# changes it makes. + +# Approach: we handle each line a word at a time, and typically make the same +# hyphen-vs-ASCII decision throughout the word. We're a bit haphazard about +# word-splitting, but it's hard to find an example of where we'd be hurt by +# that, and by luck we would do the right thing for many gcc options like +# `-fconstant-string-class=\fICLASS-NAME\fR' (where CLASS-NAME should use a +# hyphen and the others should be ASCII hyphen-minus). +# +# Perl's /e (execute) flag for substitutions does just what we want +# for preserving non-word bits while transforming "words". +# +# We don't currently handle special things like `apt-get' that look like +# hyphenated english words but are actually program names. In general the +# problem is AI complete, e.g. `apt-gettable' could be either hyphen (gettable +# by apt) or ASCII hyphen-minus (able to be processed by the `apt-get' +# program). +# +# We don't currently take hints from font choice. (E.g. text in CR font should +# probably use ASCII hyphen-minus.) +# +# We currently only handle a couple troff requests and escapes (see groff.7). + +sub frob ($); + +my $yearRE = qr/(?:19[6-9]|20[013])[0-9]/; + +sub frob ($) { + my ($x) = @_; + + # Consider splitting into two words. + if ($x =~ m{\A(.*?)(\\(?:[&/,~:d]|f[BRI]|s-?[0-9]+))(.*)\z}) { + my ($before, $s, $after) = ($1, $2, $3); + return frob($before) . $s . frob($after); + } + + if ($x =~ m{\A(.*?)(\.+)\z}) { + my $d = $2; + return frob($1) . $d; + } + + # `32-bit', `5-page'. + if ($x =~ m{\A[0-9]+-[a-z]+\z}) { + return $x; + } + + # Year range: `(C) 1998-2003'. + if ($x =~ m{\A$yearRE\\?-$yearRE\z}) { + $x =~ s{\\?-}{\\[en]}; + return $x; + } + + # ISO date. + if ($x =~ m{\A$yearRE-[01][0-9]-[0-3][0-9]\z}) { + return $x; + } + + # Things likely to be computer input. + if ($x =~ m{[0-9]|\.[a-zA-Z]|\A(?:[-/.]|\\-|\[.*\]\z)}) { + $x =~ s/\\?-/\\-/g; + return $x; + } + + $x =~ s/\\?-/-/g; + return $x; +} + +while(<>) { + if ($_ eq '.tr \(*W-|\(bv\*(Tr' . "\n") { + # Get rid of pod2man's "helpful" munging of pipe symbol. + next; + } + + # Leave ASCII apostrophe unchanged (i.e. \[aq]) for examples. + if (/\A\\\& /) { + s/'/\\[aq]/g; # `\[aq]' = "ascii quote" + } + + if (/\A\.IP /) { + s/\\?-/\\-/g; + s/\\s\\-1/\\s-1/g; + } + elsif (/\A\.IX /) { + s/\\?-/-/g; + } + elsif (!/\A\. *(?:\\"|ds|if|ie)/) { + # As an optimization, we process only words containing `-'. + s{([.@/\\[:alnum:]]*-[-.@/\\[:alnum:]]*)}{frob($1)}ge; + } + print; +} diff --git a/inkscape.desktop.in b/inkscape.desktop.in new file mode 100644 index 000000000..001c7ffd9 --- /dev/null +++ b/inkscape.desktop.in @@ -0,0 +1,19 @@ +[Desktop Entry] +_Name=Inkscape SVG Vector Illustrator +_Comment=Create and edit Scalable Vector Graphics images + +Encoding=UTF-8 +Version=1.0 + +Type=Application +Categories=Application;Graphics;VectorGraphics;GTK; + +MimeType=image/svg+xml + +FilePattern=inkscape +Exec=inkscape %F +TryExec=inkscape +Terminal=false +StartupNotify=true + +Icon=inkscape.png diff --git a/inkscape.fr.pod b/inkscape.fr.pod new file mode 100644 index 000000000..903c79a15 --- /dev/null +++ b/inkscape.fr.pod @@ -0,0 +1,395 @@ + +=head1 NOM + +Inkscape - programme d'édition SVG (Scalable Vector Graphics). + +=head1 SYNOPSIS + +C + +options: + + -?, --help + --usage + -V, --version + + -f, --file=NOM_DE_FICHIER + -s, --slideshow + + -e, --export-png=NOM_DE_FICHIER + -a, --export-area=x0:y0:x1:y1 + -D, --export-area-drawing + -i, --export-id=ID + -j, --export-id-only + -t, --export-use-hints + -b, --export-background=COULEUR + -y, --export-background-opacity=VALEUR + -d, --export-dpi=PPP + -w, --export-width=LARGEUR + -h, --export-height=HAUTEUR + + -P, --export-ps=NOM_DE_FICHIER + -E, --export-eps=NOM_DE_FICHIER + -T, --export-text-to-path + -B, --export-bbox-page + + -l, --export-plain-svg=NOM_DE_FICHIER + + -I, --query-id=ID + -X, --query-x + -Y, --query-y + -W, --query-width + -H, --query-height + + -x, --extension-directory + + -p, --print=IMPRIMANTE + + -g, --with-gui + -z, --without-gui + + --vacuum-defs + + --g-fatal-warnings + +=head1 DESCRIPTION + +B est un éditeur de dessin au format B doté d'une interface graphique, offrant des possibilités similaires à B, B, B, etc. Les fonctionnalités d'Inkscape comprennent une gestion versatile des formes, le dessin à main levée et les courbes de Bézier, le texte multiligne, le texte suivant un chemin, la transparence, les transformations affines, les remplissages par motif ou dégradé l'édition de nœuds, l'export SVG vers PNG, le groupement, les calques, les clones interactifs et bien plus. L'interface est conçue pour être confortable et efficace pour les utilisateurs expérimentés tout en restant conforme aux spécifications de B permettant ainsi aux utilisateurs d'applications GNOME de s'y habituer rapidement. + +Le format B est un format XML standard pour le dessin vectoriel 2D. Il permet de définir des objets sur un dessin par l'utilisation de points, chemins et formes primitives. Les couleurs, fontes, largeur de contour et autres sont spécifiés en tant qu'attributs de 'style' de ces objets. Le but est de rendre possible l'utilisation de fichiers SVG pour un grand nombre de programmes et d'utilisation, SVG étant un standard et ses fichiers du type texte/xml. + +B utilise le SVG comme format natif de ses documents, et a pour but de devenir le plus conforme des programmes de dessin SVG, disponible pour la communeauté du logiciel libre. + + +=head1 OPTIONS + +=over 8 + +=item B<-?>, B<--help> + +Affiche un message d'aide. + +=item B<-V>, B<--version> + +Affiche la version d'Inkscape et la date de compilation. + +=item B<-a> I, B<--export-area>=I + +Pour l'export en PNG, définit la zone à exporter en pixels SVG (unité anonyme de longueur utilisée normalement par le format SVG Inkscape). Le comportement par défaut est d'exporter le canevas entier du document. Le point (0,0) est le coin inférieur gauche. + +=item B<-D>, B<--export-area-drawing> + +Pour l'export en PNG, la zone à exporter est le dessin entier (pas le canevas). Avec cette option, l'image exportée n'affichera que les objets visibles du document sans marge ni massicotage. Peut être combiné avec --export-use-hints. + +=item B<-b> I, B<--export-background>=I + +Couleur de fond du PNG exporté. +Cette valeur peut être n'importe quelle chaîne de couleur supportée par le format SVG, par exmeple "#ff007f" ou "rgb(255, 0, 128)". +Si cette couleur n'est pas définie, la couleur de page définie dans Inkscape via la boîte de dialogue Préférences du document sera utilisée (enregistrée dans l'attribut pagecolor= de l'espace de nom sodipodi:namedview). + +=item B<-d> I, B<--export-dpi>=I + +La résolution utilisée pour l'export en bitmap. +Elle est de 90 par défaut, correspondant à 1 SVG pixel (px, aussi appelé "unité utilisateur") s'exportant vers 1 pixel bitmap. +Cette valeur préempte la PPP enregistrée avec le document si la commande est utilisée avec --export-use-hints. + +=item B<-e> I, B<--export-png>=I + +Spécifie le nom de fichier pour l'export en PNG. +S'il existe déjà, il sera écrasé sans demande de confirmation. + +=item B<-f> I, B<--file>=I + +Ouvre le(s) document(s) spécifié(s). +La chaîne optionnelle peut être omise, c'est à dire que vous pouvez lister les noms de fichier sans -f. + +=item B<-g>, B<--with-gui> + +Tente d'utiliser l'interface graphique (sous Unix, utiliser le serveur X, même si $DISPLAY n'est pas défini). + +=item B<-h> I, B<--export-height>=I + +Hauteur du bitmap généré en pixels. +Cette valeur préempte l'option --export-dpi (ou la PPP enregistrée avec le document si --export-use-hints est aussi utilisé). + +=item B<-i> I, B<--export-id>=I + +La valeur de l'attribut id de l'objet que vous voulez exporter depuis le document. +La boîte de contour de l'objet est exportée; donc avec cette option, --export-area est ignoré. + +=item B<-j>, B<--export-id-only> + +N'exporte que l'objet dont l'id est spécifiée avec avec l'option --export-id. Tout les autres objets seront cachés et n'apparaîtront pas dans le fichier exporté même s'ils chevauchent l'objet effectivement exporté. Cette option est ignorée si --export-id n'est pas aussi utilisé. + +=item B<-l>, B<--export-plain-svg>=I + +Exporte le(s) document(s) en SVG brut, sans espace de nom sodipodi: ou inkscape: et sans métadonnées RDF. + +=item B<-l>, B<--extension-directory> + +Liste le contenu du répertoire d'extensions configuré en tant que tel par Inkscape, puis sort. Cette option est utilisée afin que les extensions externes utilisent la configuration originale générée à l'installation d'Inkscape. + +=item B<-p> I, B<--print>=I + +Imprime le(s) document(s) vers l'imprimante spécifiée en utilisant `lpr -P PRINTER'. +Vous pouvez aussi utiliser `| COMMAND' pour spécifier un tube de commande différent, ou utiliser `> FILENAME' pour écrire le résultat PostScript dans un fichier au lieu de l'imprimer. +N'oubliez pas d'utiliser les guillemets appropriés pour votre shell, ex. +inkscape --print='| ps2pdf - mydoc.pdf' mydoc.svg + +=item B<-s>, B<--slideshow> + +Affiche les fichiers spécifiés un par un, passant au suivant à chaque évènement clavier ou souris. + +=item B<-t>, B<--export-use-hints> + +Utilise le nom de fichier et la PPP enregistrés avec l'objet exporté (uniquement si --export-id est spécifié). +Ces valeurs sont automatiquement spécifiées si vous exportez la sélection depuis Inkscape. +Donc, si par exemple, vous exportez la forme id="path231" en tant que /home/me/shape.png avec une résolution de 300 ppp depuis le document.svg en utilisant l'interface graphique d'Inkscape, et sauvez le document, vous pourrez réexporter plus tard cette forme vers le même fichier et avec la même résolution en utilisant simplement la commande : +inkscape -i path231 -t document.svg + +Si vous utilisez --export-dpi, --export-width, ou --export-height avec cette option, la PPP enregistrée avec le document sera ignorée et la valeur fournie à la ligne de commande utilisée. +Si vous utilisez --export-png avec cette option, le nom de fichier enregistré avec le document sera ignoré et le nom de fichier fourni à la ligne de commande utilisé. + +=item B<-w> I, B<--export-width>=I + +Largeur du bitmap généré en pixels. +Cette valeur préempte l'option --export-dpi setting (ou la PPP enregistrée avec le document si --export-use-hints est aussi utilisé). + +=item B<-y> I, B<--export-background-opacity>=I + +Opacité du fond du PNG exporté. +Cela peut être une valeur entre 0.0 and 1.0 (0.0 : complètement transparent, 1.0 complètement opaque) ou supérieure à 1 et inférieure à255 (255 : complètement opaque). +Si cette valeur n'est pas spécifiée et si l'option -b n'est pas utilisée, l'opacité de la page enregistrée avec le document (dans l'attribut inkscape:pageopacity= de l'espace de nom sodipodi:namedview) sera utilisée. +Si cette valeur n'est pas spécifiée et l'option -b utilisé, la valeur 255 (opacité complète) sera utilisée. + +=item B<-P> I, B<--export-ps>=I + +Exporte le(s) document(s) au format PostScript. + +=item B<-E> I, B<--export-eps>=I + +Exporte le(s) document(s) au format Encapsulated PostScript. + +=item B<-T>, B<--export-text-to-path> + +Convertit les objets texte en chemins lors de l'export, si applicable (ne fonctionne pour le moment qu'avec le format EPS). + +=item B<-B>, B<--export-bbox-page> + +Exporte les fichiers avec pour boîte de contour la page complète, si applicable (ne fonctionne pour le moment qu'avec le format EPS). + +=item B<-I>, B<--query-id> + +ID de l'objet dont les dimensions sont demandées. Si cette option n'est pas utilisée, les demandes retourneront les dimensions du dessin, pas de la page ou de la zone affichée. + +=item B<-X>, B<--query-x> + +Demande l'abscisse (coordonnée X) du dessin ou (si spécifié avec --query-id) de l'objet. La valeur retournée est en px (unité utilisateur SVG). + +=item B<-Y>, B<--query-y> + +Demande l'ordonnée (coordonnée Y) du dessin ou (si spécifié avec --query-id) de l'objet. La valeur retournée est en px (unité utilisateur SVG). + +=item B<-W>, B<--query-width> + +Demande la largeur du dessin ou (si spécifié avec --query-id) de l'objet. La valeur retournée est en px (unité utilisateur SVG). + +=item B<-H>, B<--query-height> + +Demande la hauteur du dessin ou (si spécifié avec --query-id) de l'objet. La valeur retournée est en px (unité utilisateur SVG). + +=item B<--vacuum-defs> + +Supprime tous les items inutilisés de la section defs du fichier SVG. +Cette option n'a pas d'effet propre, mais est très utile quand elle est utilisée conjointement avec l'option -l. + +=item B<-z>, B<--without-gui> + +Ne lance pas l'interface graphique (sous Unix, n'utilise pas le server X); ne traite les fichiers que depuis la console. +Ceci est présupposé pour les options -p, -e, et -l. + +=item B<--g-fatal-warnings> + +Elément des options standards GTK reconnues. Ceci force Inkscape à quitter pour tout avertissement GTK. Cette option est listée parce qu'elle est utilisée à des fins de débuggage. + +=item B<--usage> + +Affiche un bref message sur l'utilisation d'Inkscape. + +=back + +=head1 RACCOURCIS CLAVIER + +Pour obtenir une liste complète des raccourcis clavier et souris, consultez le fichier doc/keys.html, ou utilisez la commande Clavier et souris dans le menu d'aide de l'interface graphique pour en afficher un tableau SVG. + +=head1 CONFIGURATION + +Le fichier de configuration preferences.xml situé dans ~/.inkscape/ est utilisé pour personnaliser les préférences de l'utilisateur. + +=over 8 + +=item B + +Les éléments B du fichier de configuration sont utilisés pour définir les paramètres liés à l'interface graphique, comme l'état ouvert/fermé de certains éléments de l'interface, etc. + +=item B + +Le groupe documents permet de contenir la liste des fichiers récemment ouverts. Chaque document listé indique son uri (chemin) et nom. + +=item B + +Le groupe template est utilisé pour enregistrer les paramètres liés aux documents vides. + +=item B + +Le groupe tools enregistre les les préférences de l'utilisateur quant au style des différents outils (formes, plume calligraphique, etc.). + +=item B + +Le groupe palette permet de définir les styles de pointillés. + +=item B + +Le groupe dialogs permet de retenir la position et la taille de toute boîte de dialogue de l'application, de sorte qu'ils se lancent à l'endroit où l'utilisateur les a placés lors de la dernière utilisation. + +=item B + +Le groupe printing enregistre les différentes configurations d'impression. Chaque configuration est identifiée par un id. Les propriétés incluent I I (true : vrai / false : faux), I, et I. + +=item B + +Le groupe options permet de retenir un certain nombre d'options choisies par l'utilisateur incluant I (incrément), I (incrément de rotation), I (tolérance du curseur), et I (tolérance du cliquer-déplacer). + +=back + +=head1 DIAGNOSTICS + +Le programme retourne la valeur zéro après une utilisation réussie ou différente de zéro après un problème. + +Des messages d'erreur et des avertissements divers peuvent être écrits vers STDERR ou STDOUT. Si le programme se comporte de façon erratique avec un fichier SVG particulier, ou se plante, il est parfois utile de chercher des indices dans ces messages. Il peuvent, par exemple, indiquer qu'un fichier SVG donné contient des éléments ou des attributs non encore supportés par le logiciel. + +=head1 EXEMPLES + +Bien qu'B soit principalement conçu comme une application graphique, il peut aussi être utilisé depuis la ligne de commande pour certaines opérations SVG. + +Imprimer un fichier SVG : + + inkscape nom_de_fichier.svg -p '| lpr' + +Exporter un fichier SVG en PNG : + + inkscape nom_de_fichier.svg --export-png=nom_de_fichier.png -w600 -h400 + +Convertir un document du format SVG Inkscape au format SVG brut : + + inkscape nom_de_fichier1.svg --export-plain-svg=nom_de_fichier2.svg + +Convertir un document SVG en EPS, en convertissant les textes en chemins : + + inkscape nom_de_fichier.svg --export-eps=nom_de_fichier.eps --export-text-to-path + +Demander la largeur de l'objet avec un id="text1555": + + inkscape nom_de_fichier.svg --query-width --query-id text1555 + + +=head1 ENVIRONEMENT + +B pour obtenir l'hôte par défaut et le numéro d'affichage. + +B pour définir le chemin par défaut du répertoire à utiliser pour stocker les fichier temporaires. Ce répertoire est nécessaire. + +=head1 THEMES + +Vous pouvez remplacer le fichier d'icônes par défaut B<$PREFIX>/share/inkscape/icons/icons.svg en utilisant le répertoire B<$HOME>/.inkscape/icons/ . Les icônes sont chargées par nom (ex. : I) ou, quand elles sont introuvables, depuis le fichier I. Si une icône n'est pas trouvée dans l'un de ces emplacements, elle est chargée depuis l'emplacement par défaut du système. + +Les icônes nécessaires sont chargées depuis les fichiers SVG par recherche de l'id SVG correspondant (Par exemple, pour charger l'icône "fill_none" depuis un fichier, le contenu identifié par l'id SVG "fill_none" est rendu en tant que cette icône, qu'il vienne du fichier I ou I). + +=head1 FICHIERS + +B<$HOME>/.inkscape/preferences.xml - Le fichier des préférences de l'utilisateur. + +B<$HOME>/.inkscape/extensions.xml - Les programmes filtres utilisés par l'application. + +B<$HOME>/.inkscape/icons/{*,icons}.svg - Des icônes pour modifier le thème. + +=head1 AUTRES INFORMATIONS + +L'endroit principal pour trouver des informations sur B est http://www.inkscape.org/. Le site web contient des liens vers d'autres éléments pertinents : documentation, didacticiels, manuel de l'utilisateur, exemples, archives des listes d'e-mail, la dernière version d'Inkscape et bien d'autres choses. + +=head1 VOIR AUSSI + +gimp(1), autotrace, potrace, frontline, ill2svg, rsvg(1), xfig(1), sodipodi, karbon14, dia(1X), batik. + +Suite de tests de conformité SVG : http://www.w3.org/Graphics/SVG/Test/ + +Validation de SVG : http://jiggles.w3.org/svgvalidator/ + +I +I +L + +I +I +L + +I +I +L + +I +I +L + + +=head1 NOTES + +Ctrl, Maj et Alt modifient le comportement des actions de cliquer et de cliquer-déplacer pour la plupart des outils. La barre d'état affiche des conseils utiles à ce sujet. + +Pour faire tourner un objet, cliquer dessus avec l'outil sélecteur afin de le sélectionner,puis cliquer dessus à nouveau afin d'activer les poignées de rotation. + +La commande importer fonctionne avec la plupart des formats bitmap (PNG, BMP, JPG, XPM, GIF etc.) et avec le format vectoriel SVG. +La commande ouvrir ne gère que les fichiers SVG. + +Une tablette graphique (Wacom) peut fonctionner avec Inkscape si elle est configurée pour se comporter en tant que périphérique de pointage normal. Nous ne supportons pas encore les fonctionnalités pression/angle ou autres spécifités. + +Inkscape fonctionne dès l'installation avec le serveur X d'Apple, mais pour une utilisation sous XFree86, vous devrez activer l'option "SendCoreEvents". Tout ne semble pas encore marcher aussi bien sous Windows. + + +=head1 BUGS + +Beaucoup de bugs sont connus; veuillez, svp, consulter le site web pour consulter ceux qui ont déjà été rapportés et pour soumettre de nouveaux problèmes. Voici quelques contournements : + +Lors de l'import de SVG généré par ill2svg, tous les chemins sont habituellement groupés. Dégroupez-les manuellement. + +Si vous utilisez des dégradés et étirez l'icône du fichier sauvé dans Nautilus, vous remarquerez que les dégradés ne sont pas bien rendus. Il s'agit d'un problème connu de Nautilus/RSVG et qui peut être contourné en spécifiant le dégradé dans 'l'espace utilisateur' dans l'éditeur de dégradé. + +Consultez aussi la section "Known Issues" des notes de votre version (dans le fichier `NEWS'). + +=head1 AUTEURS + +Ce code doit son existence à un grand nombre de contributeurs tout au long de ses différentes incarnations. La liste qui suit est certainement incomplète, mais permet de reconnaître les nombreuses épaules sur lesquelles cette application s'est appuyée : + +[% INCLUDE "AUTHORS" %] + +Cette page de manuel a été créée par Bryce Harrington +Ebrycehar@bryceharrington.comE. + +=head1 HISTORIQUE + +Le code qui allait devenir Inkscape est né en 1999, avec le programme Gill, GNOME Illustrator, créé par Raph Levien. L'objectif clair de Gill était de supporter complètement le format SVG. Raph a codé le modèle Postcript de courbes de Bézier, incluant le remplissage et le contour, les coiffes et raccords de lignes, le texte, etc. La page de Raph consacrée à Gill se trouve sur http://www.levien.com/svg/. Le travail sur Gill semble avoir diminué ou s'être arrété en 2000. + +L'incarnation suivante du code allait devenir le très populaire Sodipodi, mené par Lauris Kaplinski. Le code est devenu un outil d'illustration puissant après plusieurs années de travail, ajoutant plusieurs nouvelles fonctionnalités, le support multilingue, le portage sous Windows et d'autres systèmes d'exploitation et éliminant certaines dépendances. + +Inkscape a été lancé en 2003 par quatre développeurs actifs de Sodipodi, Bryce Harrington, MenTaLguY, Nathan Hurst, et Ted Gould, qui voulaient faire prendre une orientation différente au code en termes de focalisation sur la conformité SVG, aspect et fonctionnement de l'interface, et d'opportunités de développement ouvertes à plus de participants. + + +=head1 COPYRIGHT ET LICENSE + +B 1999-2005 des auteurs. + +B est un logiciel libre; vous pouvez le redistribuer et/ou le modifier selon les termes de la license GPL. + + +=for comment +$Date: 2005/04/21 19:39:52 $ diff --git a/inkscape.ico b/inkscape.ico new file mode 100644 index 0000000000000000000000000000000000000000..4886269d3bca9037721cc70f39682da66550baf9 GIT binary patch literal 12862 zcmeI2&r7367{}ijb=CT#7HQps21G>=q4c1af{M^RdFcu^OBck02T>?qtRa|q5Iu-g zf;SK5))o8%1P>9kD_(@U7iFQTiTz1N0vt(>OQuve4_inGM5soFQdXUULf-W|#l32=jkyDnkL}Dpf zuH|~f5|5>1hp4Ts-_+LD<`l7nWGOjkX(6GjtLydapEovsJ32c2`0-y|zwhYi5OU-vfbPU%m3bc=1D3RTZCX;@beTG(=h2 z=kp~J|GazmXC$)m^5u^$EiKA4t3gX(`6tU5eSLk;pJ$#f$-S;b^2f`W=?af+k(_wu z3AXFHJJ1|b+3PNVD{4wkKIlr7f{O68%r9s~cf}bqb=(y%j#~MW)AeCnP@Ls*w+e%Y z zT4itHV5}-D@$v~O3wb;qWn2i>)YJ$Od(C_}O>*R-!C>(E`ugnbY;SLGdwY9jWo34D zc5G~{y}g}J-rwI31Ok?&%@_H-ck)e4OPZlgWjJ1-cP?4isOOR z<>jS-N1L~|w_w2O!8ny^2o4VqGk)xa-|wdk2<8c6FO3!*85z01zgM#1TJG=fS9bBi z$;nAb;prS4oKD4oXH`&oadDC7VgC8~`O?x7Yi4uS*4Cz{r{nQB5}2&LCABdM{5V~A zc6O9_H#axRxH5QpdfMIH4M7_iPKKZ&?obB@2TH0ugPWV1^fu>&#P(QBp`oGS@bEBC zT0RYXgj*gIaM%WLJ`mOG>gslPcX_s)K0Zs?-vyjAI8?wCa4k$tP2s~cCpqqM>+9>) z)zxI(Kk3Tzv!*beot;=%lPTb*rqR(+np`^YbRv`rpXaNqtIAsgE|a#lw$g;>rvO6S z-L9^#*hZvMspaKm{s&Qh?@G#N%ZooGZEbDgia0(#9vB#4aX2LfEW_}qvM=YCW~6+{ z`Sql;;3J>?C$<9YQ|^B!JxKkeH)A~+t37UqX@62PY&xiU^tZa6`d-sQr@EfTuTo8a zVZ@+D6Lj3C4FQ~0K_3!fe`(V78`u=uVcJi^&yW{~MXw$cEJ-H?NuD-{I>aJiSS>{3 zn$M6WN~9YJ$&8It>j`IUj9Tx5jnnqC2TRJ~Xv&QD8D&wJmP0+-Z{Qmfh>-wz;>2Pi zh5#mF2>2dzdqbEA(yC#|{2Pdk(fJVpvJOOmtOF775etGrVnGlh76OLR!kx-Xn#6H?W6bq0P_S<+5i9m literal 0 HcmV?d00001 diff --git a/inkscape.nsi b/inkscape.nsi new file mode 100644 index 000000000..a3b7bf7ca --- /dev/null +++ b/inkscape.nsi @@ -0,0 +1 @@ +; Please use the NSIS files in packaging/win32 now diff --git a/inkscape.png b/inkscape.png new file mode 100644 index 0000000000000000000000000000000000000000..74ebe67272344f496202a19c75688fdfb227628f GIT binary patch literal 1521 zcmVoUdB_IR;}=4~zgq95?qfAR##`@DVn|DW@m=bZDtK$^pp z!nHGin*a;&Hz4UE`rW`u;Ibkuzy$C~_0Eg3-}Ysi>%!_ad|aVlWtF*REaSa=9cLc)ea}Zf=&W ztgLw{LJJ@Z7cP|c_I8;K>~_1XTD59kiO>SbqD70OtE)@mfr*I;sj8})7b3I(lAWC` zHk(c2jbq1-Np^PjoE5>h=iA!a!df&|^z`&dVPWB%6Tuhl4;(lUl0bidzZ^PrC@RuT zO-)i=T`dCx10o{ga=E;fm6ey~iU=**1SixPFCtP~TPr0cB~b}rwOW07gw<*lhr=Nv z;@-1oPhYA<@R7GzEHXGa7?Oy~<&vD795EV=GBPp}u>hr|rG7bq$z+mk+qOw>Z?AXV zx^>WIK&`+TJ{QRH=lfht+oSdALoDTn~>gww1 z!X`Fr)~xZ(-@0|H-}TAKN!hn=pRX1$o6S;FQzH(CLrf-9q!naRLx7Znu+C1f-jqah!Y2pLh5eQ|uoeU2T<8(Uxez)80 ze)Gr2$FbRLbar-f`0!!eZgWCwWTykO`=A9QpnHoQJ>D_ zXDxyr$j2;#p2$Znf*#37EP|fNhZUhd4aiTACj-fsgn444w{aCH)C%xP8j+tKZvhy9 z1;999CcQ8UEHwf*ry+TOT;K*HFbI4=8a>O68UQ47{M~hOn?$ENrf*puD`C(hVC}v0?=mE?nS;GiUhm>{)&r z7+`E{j4wMonVOo4#Sj;P&jB0o9ni0iwz%VZ;EUN>sGy)gw(r;>uO2-rUESR>Ha;#M zk-+Ewk&G$eX&@_Ed+C0qY~0;;+4ALLHk+fp?~POhl!t(xITFzwz_L_D)(3%i0auDe zZ~_(aAY_Q~J~L1bQ~{fToD>=4W8f(zNFefnBH$J!+Iiq>)%b}k766-ocYsSN@P>=Z zGp7w&t8#!~bI+^tKVdKfj{^22i}07S_?8IfKASA}tW098XjE&i1wK+qQLuTFTzg%A z)-ga^I^U}r3*U0>y?-r^0M8{*3B^iPQS!!@s+^$0dDvTuv}AT zByua*6~So~%%Zl5De%qIEU8wW^=5*I|D@uK)_bk$+OVqn5{|MN0?`v1*N=A}za7{( z!?ryc(CXThXaQ~n`ZSAn0Jo}Z_r)=Fz6>;Q?VqbcVRyiNP08>ABXE~WG{SjDEMq_; zY9zsUzcR$js(?!=HUjSfy&;aIaN}(~_1`V3kI)RbqY&X!;7+|gjEFWs{-d(Igze*G zqdSVZ9^f_LcRhJPq}}9Gz&+>?2H + +options: + + -?, --help + --usage + -V, --version + + -f, --file=FILENAME + -s, --slideshow + + -e, --export-png=FILENAME + -a, --export-area=x0:y0:x1:y1 + -D, --export-area-drawing + --export-area-snap + -i, --export-id=ID + -j, --export-id-only + -t, --export-use-hints + -b, --export-background=COLOR + -y, --export-background-opacity=VALUE + -d, --export-dpi=DPI + -w, --export-width=WIDTH + -h, --export-height=HEIGHT + + -P, --export-ps=FILENAME + -E, --export-eps=FILENAME + -T, --export-text-to-path + -B, --export-bbox-page + + -l, --export-plain-svg=FILENAME + + -I, --query-id=ID + -X, --query-x + -Y, --query-y + -W, --query-width + -H, --query-height + + -x, --extension-directory + + -p, --print=PRINTER + + -g, --with-gui + -z, --without-gui + + --vacuum-defs + + --g-fatal-warnings + +=head1 DESCRIPTION + +B is a GUI editor for B format +drawing files, with capabilities similar to B, +B, B, etc. Inkscape features include versatile +shapes, bezier paths, freehand drawing, multi-line text, text on path, +alpha blending, arbitrary affine transforms, gradient and pattern fills, node +editing, SVG-to-PNG export, grouping, layers, live clones, and more. The interface is +designed to be comfortable and efficient for skilled users, while +remaining conformant to B standards so that users familiar with +other GNOME applications can learn its interface rapidly. + +B is a W3C standard XML format for 2D vector drawing. It allows +defining objects in the drawing using points, paths, and primitive +shapes. Colors, fonts, stroke width, and so forth are specified as +`style' attributes to these objects. The intent is that since SVG is a +standard, and since its files are text/xml, it will be +possible to use SVG files in a sizeable number of programs and for a +wide range of uses. + +B uses SVG as its native document format, and has the goal of +becoming the most fully compliant drawing program for SVG files +available in the Open Source community. + + +=head1 OPTIONS + +=over 8 + +=item B<-?>, B<--help> + +Show help message + +=item B<-V>, B<--version> + +Show Inkscape version and build date. + +=item B<-a> I, B<--export-area>=I + +In PNG export, set the exported area in SVG user units (anonymous length units normally used +in Inkscape SVG). The default is to export the entire document canvas. The point (0,0) +is the lower-left corner. + +=item B<-D>, B<--export-area-drawing> + +In PNG export, exported area is the entire drawing (not canvas), i.e. the bounding box +of all objects of the document. With this option, the exported image will +display just the visible objects of the document without margins or cropping. Can be +used in combination wtih --export-use-hints. + +=item B<--export-area-snap> + +Snap the export area outwards to the nearest integer SVG user unit (px) values. If you are using the +default export resolution of 90dpi and your graphics are pixel-snapped to minimize antialiasing, this switch +allows you to preserve this alignment even if you are exporting some object's bounding +box (with --export-id or --export-area-drawing) which is itself not pixel-aligned. + +=item B<-b> I, B<--export-background>=I + +Background color of exported PNG. +This may be any SVG supported color string, for example "#ff007f" or "rgb(255, 0, 128)". +If not set, +then the page color set in Inkscape in the Document Options dialog will be used (stored in the pagecolor= attribute of sodipodi:namedview). + +=item B<-d> I, B<--export-dpi>=I + +The resolution used for bitmap export. +The default is 90, which corresponds to 1 SVG user unit +(px, also called "user unit") exporting to 1 bitmap pixel. +This value overrides the DPI hint if used with --export-use-hints. + +=item B<-e> I, B<--export-png>=I + +Specify the filename for PNG export. +If it already exists, the file will be overwritten without asking. + +=item B<-f> I, B<--file>=I + +Open specified document(s). +Option string may be omitted, i.e. you can list the filenames without -f. + +=item B<-g>, B<--with-gui> + +Try to use the GUI (on Unix, use the X server even if $DISPLAY is not set). + +=item B<-h> I, B<--export-height>=I + +The height of generated bitmap in pixels. +This value overrides the --export-dpi setting (or the DPI hint if used with --export-use-hints). + +=item B<-i> I, B<--export-id>=I + +The id attribute value of the object that you want to export from the document. +Exported is the bounding box of the object, so with this option, --export-area is ignored. + +=item B<-j>, B<--export-id-only> + +Only export the object whose id is given in --export-id. All other objects are hidden and won't +show in export even if they overlay the exported object. Without --export-id, this option is ignored. + +=item B<-l>, B<--export-plain-svg>=I + +Export document(s) to plain SVG format, without sodipodi: or inkscape: namespaces and without RDF metadata. + +=item B<-l>, B<--extension-directory> + +Lists the current extension directory that Inkscape is configured to use and +then exits. This is used for external extension to use the same configuration +as the original Inkscape installation. + +=item B<-p> I, B<--print>=I + +Print document(s) to the specified printer using `lpr -P PRINTER'. +Alternatively, use `| COMMAND' to specify a different command to pipe to, +or use `> FILENAME' to write the PostScript output to a file instead of printing. +Remember to do appropriate quoting for your shell, e.g. + +inkscape --print='| ps2pdf - mydoc.pdf' mydoc.svg + +=item B<-s>, B<--slideshow> + +Show given files one by one, switching to the next one by any key or mouse event. + +=item B<-t>, B<--export-use-hints> + +Use export filename and DPI hints stored in the exported object (only with --export-id). +These hints are set automatically when you export selection from within Inkscape. +So, for example, if you export a shape with id="path231" as /home/me/shape.png at 300 dpi from document.svg using Inkscape GUI, and save the document, +then later you will be able to reexport that shape to the same file with the same resolution simply with + +inkscape -i path231 -t document.svg + +If you use --export-dpi, --export-width, or --export-height with this option, +then the DPI hint will be ignored and the value from the command line will be used. +If you use --export-png with this option, +then the filename hint will be ignored and the filename from the command line will be used. + +=item B<-w> I, B<--export-width>=I + +The width of generated bitmap in pixels. +This value overrides the --export-dpi setting (or the DPI hint if used with --export-use-hints). + +=item B<-y> I, B<--export-background-opacity>=I + +Opacity of the background of exported PNG. +This may be a value either between 0.0 and 1.0 (0.0 meaning full transparency, 1.0 full opacity) +or greater than 1 up to 255 (255 meaning full opacity). +If not set and the -b option is not used, +then the page opacity set in Inkscape in the Document Options dialog will be used (stored in the inkscape:pageopacity= attribute of sodipodi:namedview). +If not set but the -b option is used, +then the value of 255 (full opacity) will be used. + +=item B<-P> I, B<--export-ps>=I + +Export document(s) to PostScript format. + +=item B<-E> I, B<--export-eps>=I + +Export document(s) to Encapsulated PostScript format. + +=item B<-T>, B<--export-text-to-path> + +Convert text objects to paths on export, where applicable (currently works with EPS only). + +=item B<-B>, B<--export-bbox-page> + +Export files with the bounding box set to the page size, where applicable (currently works with EPS only). + +=item B<-I>, B<--query-id> + +Set the ID of the object whose dimensions are queried. If not set, query options will +return the dimensions of the drawing (i.e. all document objects), not the page or viewbox + +=item B<-X>, B<--query-x> + +Query the X coordinate of of the drawing or, if specified, of the object with --query-id. The returned value is in px (SVG user units). + +=item B<-Y>, B<--query-y> + +Query the Y coordinate of of the drawing or, if specified, of the object with --query-id. The returned value is in px (SVG user units). + +=item B<-W>, B<--query-width> + +Query the width of of the drawing or, if specified, of the object with --query-id. The returned value is in px (SVG user units). + +=item B<-H>, B<--query-height> + +Query the height of of the drawing or, if specified, of the object with --query-id. The returned value is in px (SVG user units). + +=item B<--vacuum-defs> + +Remove all unused items from the defs section of the SVG file. If this +option is invoked in conjunction with --export-plain-svg, only the exported file +will be affected. If it is used alone, the specified file will be modified in place. + +=item B<-z>, B<--without-gui> + +Do not open the GUI (on Unix, do not use X server); only process the files from console. +This is assumed for -p, -e, -l, and --vacuum-defs options. + +=item B<--g-fatal-warnings> + +Part of the standard GTK option that are recognized. This forces any GTK +warnings to cause Inkscape to abort. This option is listed because it gets +used for debugging. + +=item B<--usage> + +Display a brief usage message. + +=back + +=head1 CONFIGURATION + +The preferences.xml configuration file located in ~/.inkscape/ is used +to customize the application settings for the user. + +=over 8 + +=item B + +The B element(s) of the config file is used to set parameters +related to the GUI interface, such as the open/closed status of various +GUI elements, etc. + +=item B + +The documents group is used for containing the recent files list. Each +document is listed with its uri (path) and name indicated. + +=item B + +The template group is used for storing parameters related to blank +documents. + +=item B + +The tools group is used for storing the user style preferences for +different event contexts (i.e., shapes, freehand or calligraphic stroke +properties, etc.). + +=item B + +The palette group allows setting of dash styles. This allows you to +define the stroke lengths for different kinds of dashes. + +=item B + +The dialogs group allows persisting the position and width of each of +the dialogs in the application, so that they'll start up in the last +place the user had them at the next time the app is run. + +=item B + +The printing group is for storing different printer settings. Each +setting is identified with an id. Properties include I +(true/false), I, and I. + +=item B + +The options group allows persisting various user selected options +including I, I, I, and +I. + +=back + +=head1 DIAGNOSTICS + +The program returns zero on success or non-zero on failure. + +A variety of error messages and warnings are printed to STDERR or +STDOUT. If the program behaves erratically with a particular SVG file +or crashes, it is sometimes useful to look at this output for clues. + +=head1 EXAMPLES + +While obviously B is primarily intended as a GUI application, +it can be used for doing SVG processing on the commandline as well. + +Print an SVG file: + + inkscape filename.svg -p '| lpr' + +Export an SVG file into PNG with the default resolution of 90dpi (one SVG user unit translates to one bitmap pixel): + + inkscape filename.svg --export-png=filename.png + +Same, but force the PNG file to be 600x400 pixels: + + inkscape filename.svg --export-png=filename.png -w600 -h400 + +Same, but export the drawing (bounding box of all objects), not the page: + + inkscape filename.svg --export-png=filename.png --export-area-drawing + +Export to PNG the object with id="text1555", using the output filename and +the resolution that were used for that object last time when it was exported from the GUI: + + inkscape filename.svg --export-id=text1555 --export-use-hints + +Same, but use the default 90dpi resolution, specify the filename, +and snap the exported area outwards to the nearest whole SVG user unit values +(to preserve pixel-alignment of objects and thus minimize antialiasing): + + inkscape filename.svg --export-id=text1555 --export-png=text.png --export-snap-area + +Convert an Inkscape SVG document to plain SVG: + + inkscape filename1.svg --export-plain-svg=filename2.svg + +Convert an SVG document to EPS, converting all texts to paths: + + inkscape filename.svg --export-eps=filename.eps --export-text-to-path + +Query the width of the object with id="text1555": + + inkscape filename.svg --query-width --query-id text1555 + + +=head1 ENVIRONMENT + +B to get the default host and display number. + +B to set the default path of the directory to use for temporary +files. The directory must exist. + +=head1 THEMES + +To load different icons sets instead of the default +B<$PREFIX>/share/inkscape/icons/icons.svg file, the directory +B<$HOME>/.inkscape/icons/ is used. Icons are loaded by name +(e.g. I), or if not found, then from I. If the +icon is not loaded from either of those locations, it falls back to the +default system location. + +The needed icons are loaded from SVG files by searching for the SVG id with +the matching icon name. (For example, to load the "fill_none" icon from +a file, the bounding box seen for SVG id "fill_none" is rendered as the +icon, whether it comes from I or I.) + +=head1 FILES + +B<$HOME>/.inkscape/preferences.xml - The user's preference settings. + +B<$HOME>/.inkscape/extensions.xml - The filter programs to be used in +the application. + +B<$HOME>/.inkscape/icons/{*,icons}.svg - Icons to overload for themes. + +=head1 OTHER INFO + +The canonical place to find B info is at +http://www.inkscape.org/. The website includes links to other relevant +documentation, tutorials, user manual, examples, mailing list archives, +the latest released version of the program, and more. + +=head1 SEE ALSO + +gimp(1), autotrace, potrace, frontline, ill2svg, rsvg(1), xfig(1), sodipodi, +karbon14, dia(1X), batik. + +SVG compliance test suite: http://www.w3.org/Graphics/SVG/Test/ + +SVG validator: http://jiggles.w3.org/svgvalidator/ + +I +I +L + +I +I +L + +I +I +L + +I +I +L + + +=head1 GUI NOTES + +To learn Inkscape's GUI operation, read the tutorials in Help > Tutorials. + +Inkscape can import (File > Import) most bitmap formats (PNG, BMP, JPG, XPM, GIF etc.), +plain text (requires Perl), and AI format (Adobe Illustrator documents, versions up to 7 only; +requires Perl). + +Inkscape exports 32-bit PNG images (File > Export) as well as AI, PS, EPS, PDF (requires +Ghostscript), DXF and several other formats via File > Save as. + +Inkscape can use the pressure and tilt of a graphic tablet pen for width and angle of +the Calligraphic tool. + +Inkscape includes a GUI front-end to the Potrace bitmap tracing engine +(http://potrace.sf.net) which is embedded into Inkscape. + +Inkscape can use external scripts (stdin-to-stdout filters) that are represented by +commands in the Effects menu. A script can have a GUI dialog for setting various +parameters and can get the IDs of the selected objects on which to act via the command +line. Inkscape comes with an assortment of effects written in Python, mostly for path +manipulation. + +=head1 KEYBINDINGS + +To get a complete list of keyboard and mouse shortcuts, view doc/keys.html, or use the Keys and Mouse command in Help menu from the GUI to see an SVG chart. + +=head1 BUGS + +Many bugs are known; please refer to the website (inkscape.org) for reviewing the reported ones and to +report newly found issues. See also the Known Issues section in the Release Notes for +your version (file `NEWS'). + +=head1 AUTHORS + +This codebase owes its existance to a large number of contributors +throughout its various incarnations. The following list is certainly +incomplete, but serves to recognize the many shoulders on which this +application sits: + +[% INCLUDE "AUTHORS" %] + +This man page was put together by Bryce Harrington +Ebrycehar@bryceharrington.comE. + +=head1 HISTORY + +The codebase that would become Inkscape began life in 1999 as the +program Gill, the GNOME Illustrator application, created by Raph +Levien. The stated objective for Gill was to eventually support all of +SVG. Raph implemented the PostScript bezier imaging model, including +stroking and filling, line cap style, line join style, text, etc. +Raph's Gill page is at http://www.levien.com/svg/. Work on Gill appears +to have slowed or ceased in 2000. + +The next incarnation of the codebase was to become the highly popular +program Sodipodi, led by Lauris Kaplinski. The codebase was turned +into a powerful illustration program over the course of several +year's work, adding several new features, multi-lingual support, porting +to Windows and other operating systems, and eliminating dependencies. + +Inkscape was formed in 2003 by four active Sodipodi developers, Bryce +Harrington, MenTaLguY, Nathan Hurst, and Ted Gould, wanting to take a +different direction with the codebase in terms of focus on +SVG compliance, interface look-and-feel, and a desire to open +development opportunities to more participants. + +=head1 COPYRIGHT AND LICENSE + +B 1999-2005 by Authors. + +B is free software; you can redistribute it and/or modify it +under the terms of the GPL. + + +=for comment +$Date$ diff --git a/inkscape.spec.in b/inkscape.spec.in new file mode 100644 index 000000000..84b290cfb --- /dev/null +++ b/inkscape.spec.in @@ -0,0 +1,119 @@ +# If you want to build an executable that uses static libraries, +# build your libraries in a separate root directory, and then run +# the rpmbuild using "--define 'ink_static_root /your/static/rootdir'" + +# To avoid stripping the binaries, you can also: +# "--define '__spec_install_post /usr/lib/rpm/brp-compress'" + +Name: inkscape +Summary: A Vector Drawing Application +Version: @VERSION@ +# Use release "0" so that distro-released versions will override ours. +Release: 0 +License: GPL +Group: Applications/Graphics +Source: %{name}-%{version}.tar.gz +URL: http://inkscape.sourceforge.net/ +Prefix: %{_prefix} +Packager: Automatic +Vendor: The Inkscape Project +BuildRoot: %{_tmppath}/%{name}-%{version}-root + +# See debian/control for a full list of requirements. Maybe someone using an +# rpm-based distribution would like to translate some or all of the Debian +# package names given in debian/control to rpm equivalent packages. +BuildRequires: atk-devel +BuildRequires: desktop-file-utils +BuildRequires: freetype-devel +BuildRequires: gc-devel +BuildRequires: gettext +BuildRequires: gtkmm24-devel +BuildRequires: libart_lgpl-devel >= 2.3.10 +BuildRequires: libgnomeprintui22-devel >= 2.2.0 +BuildRequires: gnome-vfs2-devel +BuildRequires: libpng-devel +BuildRequires: libsigc++20-devel +BuildRequires: libxml2-devel >= 2.4.24 +BuildRequires: libxslt-devel +BuildRequires: pango-devel +BuildRequires: perl-XML-Parser +BuildRequires: pkgconfig +BuildRequires: python-devel +Requires(post): desktop-file-utils +Requires(postun): desktop-file-utils + +Provides: perl(SpSVG) +Provides: perl(SVG) + +%description +Inkscape is an SVG-based generic vector-drawing program for Linux/Unix/Windows/Mac. + +%prep +%setup + +%build +### Needed for snapshot releases. +MYCFLAGS="$RPM_OPT_FLAGS" + +# Deal with static builds +if [ ! -z "%{?ink_static_root}" ]; then + PATH=/extra/static/bin:$PATH + if [ -z "$PKG_CONFIG_PATH" ]; then + PKG_CONFIG_PATH=/usr/local/lib/pkgconfig:/usr/lib/pkgconfig + fi + PKG_CONFIG_PATH=%{ink_static_root}/lib/pkgconfig:$PKG_CONFIG_PATH + CPPFLAGS="-I%{ink_static_root}/include $CPPFLAGS" + LDFLAGS="-L%{ink_static_root}/lib $LDFLAGS" + + export PATH PKG_CONFIG_PATH CPPFLAGS LDFLAGS +fi + +if [ ! -x configure ]; then + CFLAGS="$MYCFLAGS" ./autogen.sh $MYARCH_FLAGS --prefix=%{_prefix} --localstatedir=%{_localstatedir} --sysconfdir=%{_sysconfdir} +else + %configure +fi +make %{?_smp_mflags} + +%install +rm -rf %{buildroot} +%makeinstall + +%clean +rm -rf %{buildroot} + +%files +%defattr(-, root, root) +%doc AUTHORS COPYING ChangeLog NEWS README doc/keys.html +%{_bindir}/inkscape +%{_bindir}/inkview +%{_datadir}/applications/inkscape.desktop +%{_datadir}/locale/*/LC_MESSAGES/inkscape.mo +%{_datadir}/pixmaps/* +%{_datadir}/inkscape/* +%{_mandir}/*/man1/* +%{_mandir}/man1/* + +%changelog +* Wed Nov 30 2005 Daniil Ivanov +- Added BuildRequires and Provides + +* Thu Jul 7 2005 Kees Cook +- Adjusted for plugin relocation + +* Wed Nov 24 2004 Kees Cook +- Added SMP flags so I can build faster +- Added static build capability + +* Sat Jul 17 2004 Bryce W. Harrington +- Removing _libdir and TODO, updating description + +* Thu May 01 2003 Christian Schaller +- Fix up the spec file for current release + +* Mon Sep 23 2002 Dag Wieers +- Update to 0.2.6 + +* Thu Sep 12 2002 Dag Wieers +- Update to 0.2.5 +- Changed SPEC to benefit from macros diff --git a/inkscape16.ico b/inkscape16.ico new file mode 100644 index 0000000000000000000000000000000000000000..aecbcc0684978f73547156733ea007371b823869 GIT binary patch literal 894 zcmb7?zfQw25XK#`M2aF3hKQ~4RtdiYYNc#uCSB>mLRbqE5_HKMG&8W}4{O4}K+9|J z7$`zApJgG%c8bKsXZ!Ac-^sQ@h=VT(0wV45fRG656fQF{+#$!9VW=H>%2k4pkKGpI zrKuN-6a#6-7&hyN``4~jRb#%+vR}2fQc4XH;q%j@2I;}=&B~B0mlrysMV{yVi-*|e zUDwr`>VeJYd0tf&=UfM6bjG>Omu1=aeUcb>!3`OavfJbG@RKOm4iv-ApvSpOF9-~L8j$)uoM*$g_NL?l6 OKo7pP(Cg+s_qqehzHY|= literal 0 HcmV?d00001 diff --git a/inkscape32.ico b/inkscape32.ico new file mode 100644 index 0000000000000000000000000000000000000000..bccc6ed2490b4cc4f3329a2222876edf8b4ee07a GIT binary patch literal 3262 zcmd6q!AiqG5QZlyrll4X4_czMu`1}TXQi~hf+&hti+I%+&{t6O9X#k0h|r6Q6c5Fl z?V*pL!9&sD`q!ahNn%Xe4Y=)eXJ===e|OU^lt{zNvL>nDE^|cF=$By@tOnC4k54qr zO^vg0fau}=?q9vJu5!7Y(2@q5?)OPZB*B-Nvaf3WIBgj#`>G^lW}rW!P$1J298SUm z`E3{r9&+G;{8(@#2SQ5o*46b@r_=Gz#^rN9b26C>W1m~kM~6o%%PY8S{A~ychUCU` zhGF=DA(1FrA>|RL0#zc`Mo)89qL;+VWPYrYSjma5--Rc!3lChaL?B$1LDg&En>9@n{M(yb%d&J`-`v>rXhno` znmKEJ^gad(;-G%8zqijr+qT;;ZTM#1#9s0+7|3d}rjiLLUdN>daNGijTA^#8;86i@rM{#H$7)AsU)+DD`845F;vn5v5=8x1s?% l;Xc*n*hCNW4p9|3$H*1p1T~Emm}&69?Sb!9p>-_!?Hft)KMw!^ literal 0 HcmV?d00001 diff --git a/inkscape32x16col.ico b/inkscape32x16col.ico new file mode 100644 index 0000000000000000000000000000000000000000..7827466abd8be0584d179ef1a8462158d304b802 GIT binary patch literal 766 zcmc&yF>-`34BX4yjISfr)s%Tgo4t6FD0p0OS48I$B}{7zNvsO}<}Fu2 z+}v&Q$tykrlURy3=WYi<5O!d!IqF3@r4;q3114_|mKzowyP8BsE$Jy|;q(wg;#q;W zd`cSDpMAhT5A56_wKFb$N=SUU;I>SCgu;1@*hlh#%+2Oy6$EYEdelGR32}{(}FtZ$&cRL;wH) literal 0 HcmV?d00001 diff --git a/inkscape64.ico b/inkscape64.ico new file mode 100644 index 0000000000000000000000000000000000000000..a059ea00bad0ac2077ee76f8064e5157618d5bab GIT binary patch literal 12862 zcmeI3KZqMg6vju~VGHc|Lkh#_!iaAA&A2QDH=5kZO^7!s}uXCnpS z!W=FPauHApgDZ2mausk80i7Wr2Leiw;&Ql9;X)V};xOhW-|Sn>jb>K6JG-OJ>F}PV z_vX!;@BLunazAtGs}p{ zlOU2MuvRMp?X)4`%35#w<}{4NafvidK_;Yhrs=1Nn@F0PnP3~y1RXYQNv!f6a+*?B zBv#30E$0y{9;@V(sKsJ2pU+2%SRq*@N0!zSDwis?udA&Gt?piT^k&34uUxEXIcC!e zDM7MXQH|u!=c`{;A3c0D91H+F*x%oMyt{pS8^QJK>ugcY4f7L#Sq%xST`rf0!(spL ze)~at|Ty~<@{3nkvBM0~=?ObG^O>xV59o+8-) zp-gO^9Ot~{&D%}dNWn$5b#rU~pZ&=55{YD+Ag56KrgqFW>9y{+C=J)uWDoDX=rw<8 z4qpu^u3c<23TKTRTeg__B#sTM;lRhxAo++F&KIz@l2cC@x7V+&lNz3pkMl(gXvTy| zmPSRdu3a62=oXj9%4aKj)M(=*3aLd_`?iM5DI0iM1(k708&DzunC6|}E;YY(ueJHz z=HR8+a+I>kmNdaAIt$q6RFR}lJGZhK?)3lamoJtfm;fWq5LCpQN%!||I9_;f`{y=& z%%veoJQh>Hs})=2;gEs7I7j%%g947k0O<#!I;QaS$=K`nD+v^pV zkM9&XDe6{4E-XG<2j0CTIT1`sy^-X$u0u6B1>8t#|I)@Q0x#7opI?!2I1bCrLP|w7 z{aI9;h35Q{tE)k?P$TdCQ?>%~E$-MkS|$H*!M8czvdMOX`VX0Bk8ZIXf6n>4FBq%; z$@$R*#+LrYh*d@j9RCr)6TnqzqSqL+6xE7C diff --git a/libgc.supp b/libgc.supp new file mode 100644 index 000000000..c8455dad3 --- /dev/null +++ b/libgc.supp @@ -0,0 +1,15 @@ +{ + boehm collector uninitialized pointer test + Memcheck:Cond + obj:/usr/lib/libgc.so.* + obj:/usr/lib/libgc.so.* + obj:/usr/lib/libgc.so.* +} +{ + boehm collector uninitialized pointer read + Memcheck:Value4 + obj:/usr/lib/libgc.so.* + obj:/usr/lib/libgc.so.* + obj:/usr/lib/libgc.so.* +} + diff --git a/m4/Makefile.am b/m4/Makefile.am new file mode 100644 index 000000000..26e2af705 --- /dev/null +++ b/m4/Makefile.am @@ -0,0 +1,3 @@ +EXTRA_DIST=codeset.m4 glibc21.m4 isc-posix.m4 progtest.m4 gettext.m4 \ + iconv.m4 lcmessage.m4 + diff --git a/m4/codeset.m4 b/m4/codeset.m4 new file mode 100644 index 000000000..59535ebcf --- /dev/null +++ b/m4/codeset.m4 @@ -0,0 +1,23 @@ +# codeset.m4 serial AM1 (gettext-0.10.40) +dnl Copyright (C) 2000-2002 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. + +dnl From Bruno Haible. + +AC_DEFUN([AM_LANGINFO_CODESET], +[ + AC_CACHE_CHECK([for nl_langinfo and CODESET], am_cv_langinfo_codeset, + [AC_TRY_LINK([#include ], + [char* cs = nl_langinfo(CODESET);], + am_cv_langinfo_codeset=yes, + am_cv_langinfo_codeset=no) + ]) + if test $am_cv_langinfo_codeset = yes; then + AC_DEFINE(HAVE_LANGINFO_CODESET, 1, + [Define if you have and nl_langinfo(CODESET).]) + fi +]) diff --git a/m4/gettext.m4 b/m4/gettext.m4 new file mode 100644 index 000000000..45cad8557 --- /dev/null +++ b/m4/gettext.m4 @@ -0,0 +1,587 @@ +# gettext.m4 serial 17 (gettext-0.11.5) +dnl Copyright (C) 1995-2002 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. +dnl +dnl This file can can be used in projects which are not available under +dnl the GNU General Public License or the GNU Library General Public +dnl License but which still want to provide support for the GNU gettext +dnl functionality. +dnl Please note that the actual code of the GNU gettext library is covered +dnl by the GNU Library General Public License, and the rest of the GNU +dnl gettext package package is covered by the GNU General Public License. +dnl They are *not* in the public domain. + +dnl Authors: +dnl Ulrich Drepper , 1995-2000. +dnl Bruno Haible , 2000-2002. + +dnl Macro to add for using GNU gettext. + +dnl Usage: AM_GNU_GETTEXT([INTLSYMBOL], [NEEDSYMBOL], [INTLDIR]). +dnl INTLSYMBOL can be one of 'external', 'no-libtool', 'use-libtool'. The +dnl default (if it is not specified or empty) is 'no-libtool'. +dnl INTLSYMBOL should be 'external' for packages with no intl directory, +dnl and 'no-libtool' or 'use-libtool' for packages with an intl directory. +dnl If INTLSYMBOL is 'use-libtool', then a libtool library +dnl $(top_builddir)/intl/libintl.la will be created (shared and/or static, +dnl depending on --{enable,disable}-{shared,static} and on the presence of +dnl AM-DISABLE-SHARED). If INTLSYMBOL is 'no-libtool', a static library +dnl $(top_builddir)/intl/libintl.a will be created. +dnl If NEEDSYMBOL is specified and is 'need-ngettext', then GNU gettext +dnl implementations (in libc or libintl) without the ngettext() function +dnl will be ignored. If NEEDSYMBOL is specified and is +dnl 'need-formatstring-macros', then GNU gettext implementations that don't +dnl support the ISO C 99 formatstring macros will be ignored. +dnl INTLDIR is used to find the intl libraries. If empty, +dnl the value `$(top_builddir)/intl/' is used. +dnl +dnl The result of the configuration is one of three cases: +dnl 1) GNU gettext, as included in the intl subdirectory, will be compiled +dnl and used. +dnl Catalog format: GNU --> install in $(datadir) +dnl Catalog extension: .mo after installation, .gmo in source tree +dnl 2) GNU gettext has been found in the system's C library. +dnl Catalog format: GNU --> install in $(datadir) +dnl Catalog extension: .mo after installation, .gmo in source tree +dnl 3) No internationalization, always use English msgid. +dnl Catalog format: none +dnl Catalog extension: none +dnl If INTLSYMBOL is 'external', only cases 2 and 3 can occur. +dnl The use of .gmo is historical (it was needed to avoid overwriting the +dnl GNU format catalogs when building on a platform with an X/Open gettext), +dnl but we keep it in order not to force irrelevant filename changes on the +dnl maintainers. +dnl +AC_DEFUN([AM_GNU_GETTEXT], +[ + dnl Argument checking. + ifelse([$1], [], , [ifelse([$1], [external], , [ifelse([$1], [no-libtool], , [ifelse([$1], [use-libtool], , + [errprint([ERROR: invalid first argument to AM_GNU_GETTEXT +])])])])]) + ifelse([$2], [], , [ifelse([$2], [need-ngettext], , [ifelse([$2], [need-formatstring-macros], , + [errprint([ERROR: invalid second argument to AM_GNU_GETTEXT +])])])]) + define(gt_included_intl, ifelse([$1], [external], [no], [yes])) + define(gt_libtool_suffix_prefix, ifelse([$1], [use-libtool], [l], [])) + + AC_REQUIRE([AM_PO_SUBDIRS])dnl + ifelse(gt_included_intl, yes, [ + AC_REQUIRE([AM_INTL_SUBDIR])dnl + ]) + + dnl Prerequisites of AC_LIB_LINKFLAGS_BODY. + AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) + AC_REQUIRE([AC_LIB_RPATH]) + + dnl Sometimes libintl requires libiconv, so first search for libiconv. + dnl Ideally we would do this search only after the + dnl if test "$USE_NLS" = "yes"; then + dnl if test "$gt_cv_func_gnugettext_libc" != "yes"; then + dnl tests. But if configure.in invokes AM_ICONV after AM_GNU_GETTEXT + dnl the configure script would need to contain the same shell code + dnl again, outside any 'if'. There are two solutions: + dnl - Invoke AM_ICONV_LINKFLAGS_BODY here, outside any 'if'. + dnl - Control the expansions in more detail using AC_PROVIDE_IFELSE. + dnl Since AC_PROVIDE_IFELSE is only in autoconf >= 2.52 and not + dnl documented, we avoid it. + ifelse(gt_included_intl, yes, , [ + AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY]) + ]) + + AC_MSG_CHECKING([whether NLS is requested]) + dnl Default is enabled NLS + AC_ARG_ENABLE(nls, + [ --disable-nls do not use Native Language Support], + USE_NLS=$enableval, USE_NLS=yes) + AC_MSG_RESULT($USE_NLS) + AC_SUBST(USE_NLS) + + ifelse(gt_included_intl, yes, [ + BUILD_INCLUDED_LIBINTL=no + USE_INCLUDED_LIBINTL=no + ]) + LIBINTL= + LTLIBINTL= + POSUB= + + dnl If we use NLS figure out what method + if test "$USE_NLS" = "yes"; then + gt_use_preinstalled_gnugettext=no + ifelse(gt_included_intl, yes, [ + AC_MSG_CHECKING([whether included gettext is requested]) + AC_ARG_WITH(included-gettext, + [ --with-included-gettext use the GNU gettext library included here], + nls_cv_force_use_gnu_gettext=$withval, + nls_cv_force_use_gnu_gettext=no) + AC_MSG_RESULT($nls_cv_force_use_gnu_gettext) + + nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext" + if test "$nls_cv_force_use_gnu_gettext" != "yes"; then + ]) + dnl User does not insist on using GNU NLS library. Figure out what + dnl to use. If GNU gettext is available we use this. Else we have + dnl to fall back to GNU NLS library. + + dnl Add a version number to the cache macros. + define([gt_api_version], ifelse([$2], [need-formatstring-macros], 3, ifelse([$2], [need-ngettext], 2, 1))) + define([gt_cv_func_gnugettext_libc], [gt_cv_func_gnugettext]gt_api_version[_libc]) + define([gt_cv_func_gnugettext_libintl], [gt_cv_func_gnugettext]gt_api_version[_libintl]) + + AC_CACHE_CHECK([for GNU gettext in libc], gt_cv_func_gnugettext_libc, + [AC_TRY_LINK([#include +]ifelse([$2], [need-formatstring-macros], +[#ifndef __GNU_GETTEXT_SUPPORTED_REVISION +#define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 0 : -1) +#endif +changequote(,)dnl +typedef int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1]; +changequote([,])dnl +], [])[extern int _nl_msg_cat_cntr; +extern int *_nl_domain_bindings;], + [bindtextdomain ("", ""); +return (int) gettext ("")]ifelse([$2], [need-ngettext], [ + (int) ngettext ("", "", 0)], [])[ + _nl_msg_cat_cntr + *_nl_domain_bindings], + gt_cv_func_gnugettext_libc=yes, + gt_cv_func_gnugettext_libc=no)]) + + if test "$gt_cv_func_gnugettext_libc" != "yes"; then + dnl Sometimes libintl requires libiconv, so first search for libiconv. + ifelse(gt_included_intl, yes, , [ + AM_ICONV_LINK + ]) + dnl Search for libintl and define LIBINTL, LTLIBINTL and INCINTL + dnl accordingly. Don't use AC_LIB_LINKFLAGS_BODY([intl],[iconv]) + dnl because that would add "-liconv" to LIBINTL and LTLIBINTL + dnl even if libiconv doesn't exist. + AC_LIB_LINKFLAGS_BODY([intl]) + AC_CACHE_CHECK([for GNU gettext in libintl], + gt_cv_func_gnugettext_libintl, + [gt_save_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $INCINTL" + gt_save_LIBS="$LIBS" + LIBS="$LIBS $LIBINTL" + dnl Now see whether libintl exists and does not depend on libiconv. + AC_TRY_LINK([#include +]ifelse([$2], [need-formatstring-macros], +[#ifndef __GNU_GETTEXT_SUPPORTED_REVISION +#define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 0 : -1) +#endif +changequote(,)dnl +typedef int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1]; +changequote([,])dnl +], [])[extern int _nl_msg_cat_cntr; +extern +#ifdef __cplusplus +"C" +#endif +const char *_nl_expand_alias ();], + [bindtextdomain ("", ""); +return (int) gettext ("")]ifelse([$2], [need-ngettext], [ + (int) ngettext ("", "", 0)], [])[ + _nl_msg_cat_cntr + *_nl_expand_alias (0)], + gt_cv_func_gnugettext_libintl=yes, + gt_cv_func_gnugettext_libintl=no) + dnl Now see whether libintl exists and depends on libiconv. + if test "$gt_cv_func_gnugettext_libintl" != yes && test -n "$LIBICONV"; then + LIBS="$LIBS $LIBICONV" + AC_TRY_LINK([#include +]ifelse([$2], [need-formatstring-macros], +[#ifndef __GNU_GETTEXT_SUPPORTED_REVISION +#define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 0 : -1) +#endif +changequote(,)dnl +typedef int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1]; +changequote([,])dnl +], [])[extern int _nl_msg_cat_cntr; +extern +#ifdef __cplusplus +"C" +#endif +const char *_nl_expand_alias ();], + [bindtextdomain ("", ""); +return (int) gettext ("")]ifelse([$2], [need-ngettext], [ + (int) ngettext ("", "", 0)], [])[ + _nl_msg_cat_cntr + *_nl_expand_alias (0)], + [LIBINTL="$LIBINTL $LIBICONV" + LTLIBINTL="$LTLIBINTL $LTLIBICONV" + gt_cv_func_gnugettext_libintl=yes + ]) + fi + CPPFLAGS="$gt_save_CPPFLAGS" + LIBS="$gt_save_LIBS"]) + fi + + dnl If an already present or preinstalled GNU gettext() is found, + dnl use it. But if this macro is used in GNU gettext, and GNU + dnl gettext is already preinstalled in libintl, we update this + dnl libintl. (Cf. the install rule in intl/Makefile.in.) + if test "$gt_cv_func_gnugettext_libc" = "yes" \ + || { test "$gt_cv_func_gnugettext_libintl" = "yes" \ + && test "$PACKAGE" != gettext; }; then + gt_use_preinstalled_gnugettext=yes + else + dnl Reset the values set by searching for libintl. + LIBINTL= + LTLIBINTL= + INCINTL= + fi + + ifelse(gt_included_intl, yes, [ + if test "$gt_use_preinstalled_gnugettext" != "yes"; then + dnl GNU gettext is not found in the C library. + dnl Fall back on included GNU gettext library. + nls_cv_use_gnu_gettext=yes + fi + fi + + if test "$nls_cv_use_gnu_gettext" = "yes"; then + dnl Mark actions used to generate GNU NLS library. + INTLOBJS="\$(GETTOBJS)" + BUILD_INCLUDED_LIBINTL=yes + USE_INCLUDED_LIBINTL=yes + LIBINTL="ifelse([$3],[],\${top_builddir}/intl,[$3])/libintl.[]gt_libtool_suffix_prefix[]a $LIBICONV" + LTLIBINTL="ifelse([$3],[],\${top_builddir}/intl,[$3])/libintl.[]gt_libtool_suffix_prefix[]a $LTLIBICONV" + LIBS=`echo " $LIBS " | sed -e 's/ -lintl / /' -e 's/^ //' -e 's/ $//'` + fi + + if test "$gt_use_preinstalled_gnugettext" = "yes" \ + || test "$nls_cv_use_gnu_gettext" = "yes"; then + dnl Mark actions to use GNU gettext tools. + CATOBJEXT=.gmo + fi + ]) + + if test "$gt_use_preinstalled_gnugettext" = "yes" \ + || test "$nls_cv_use_gnu_gettext" = "yes"; then + AC_DEFINE(ENABLE_NLS, 1, + [Define to 1 if translation of program messages to the user's native language + is requested.]) + else + USE_NLS=no + fi + fi + + if test "$USE_NLS" = "yes"; then + + if test "$gt_use_preinstalled_gnugettext" = "yes"; then + if test "$gt_cv_func_gnugettext_libintl" = "yes"; then + AC_MSG_CHECKING([how to link with libintl]) + AC_MSG_RESULT([$LIBINTL]) + AC_LIB_APPENDTOVAR([CPPFLAGS], [$INCINTL]) + fi + + dnl For backward compatibility. Some packages may be using this. + AC_DEFINE(HAVE_GETTEXT, 1, + [Define if the GNU gettext() function is already present or preinstalled.]) + AC_DEFINE(HAVE_DCGETTEXT, 1, + [Define if the GNU dcgettext() function is already present or preinstalled.]) + fi + + dnl We need to process the po/ directory. + POSUB=po + fi + + ifelse(gt_included_intl, yes, [ + dnl If this is used in GNU gettext we have to set BUILD_INCLUDED_LIBINTL + dnl to 'yes' because some of the testsuite requires it. + if test "$PACKAGE" = gettext; then + BUILD_INCLUDED_LIBINTL=yes + fi + + dnl Make all variables we use known to autoconf. + AC_SUBST(BUILD_INCLUDED_LIBINTL) + AC_SUBST(USE_INCLUDED_LIBINTL) + AC_SUBST(CATOBJEXT) + AC_SUBST(INTLOBJS) + + dnl For backward compatibility. Some configure.ins may be using this. + nls_cv_header_intl= + nls_cv_header_libgt= + + dnl For backward compatibility. Some Makefiles may be using this. + DATADIRNAME=share + AC_SUBST(DATADIRNAME) + + dnl For backward compatibility. Some Makefiles may be using this. + INSTOBJEXT=.mo + AC_SUBST(INSTOBJEXT) + + dnl For backward compatibility. Some Makefiles may be using this. + GENCAT=gencat + AC_SUBST(GENCAT) + + dnl Enable libtool support if the surrounding package wishes it. + INTL_LIBTOOL_SUFFIX_PREFIX=gt_libtool_suffix_prefix + AC_SUBST(INTL_LIBTOOL_SUFFIX_PREFIX) + ]) + + dnl For backward compatibility. Some Makefiles may be using this. + INTLLIBS="$LIBINTL" + AC_SUBST(INTLLIBS) + + dnl Make all documented variables known to autoconf. + AC_SUBST(LIBINTL) + AC_SUBST(LTLIBINTL) + AC_SUBST(POSUB) +]) + + +dnl Checks for all prerequisites of the po subdirectory, +dnl except for USE_NLS. +AC_DEFUN([AM_PO_SUBDIRS], +[ + AC_REQUIRE([AC_PROG_MAKE_SET])dnl + AC_REQUIRE([AC_PROG_INSTALL])dnl + AC_REQUIRE([AM_MKINSTALLDIRS])dnl + + dnl Perform the following tests also if --disable-nls has been given, + dnl because they are needed for "make dist" to work. + + dnl Search for GNU msgfmt in the PATH. + dnl The first test excludes Solaris msgfmt and early GNU msgfmt versions. + dnl The second test excludes FreeBSD msgfmt. + AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt, + [$ac_dir/$ac_word --statistics /dev/null >/dev/null 2>&1 && + (if $ac_dir/$ac_word --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi)], + :) + AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT) + + dnl Search for GNU xgettext 0.11 or newer in the PATH. + dnl The first test excludes Solaris xgettext and early GNU xgettext versions. + dnl The second test excludes FreeBSD xgettext. + AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext, + [$ac_dir/$ac_word --omit-header --copyright-holder= /dev/null >/dev/null 2>&1 && + (if $ac_dir/$ac_word --omit-header --copyright-holder= /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi)], + :) + dnl Remove leftover from FreeBSD xgettext call. + rm -f messages.po + + dnl Search for GNU msgmerge 0.11 or newer in the PATH. + AM_PATH_PROG_WITH_TEST(MSGMERGE, msgmerge, + [$ac_dir/$ac_word --update -q /dev/null /dev/null >/dev/null 2>&1], :) + + dnl This could go away some day; the PATH_PROG_WITH_TEST already does it. + dnl Test whether we really found GNU msgfmt. + if test "$GMSGFMT" != ":"; then + dnl If it is no GNU msgfmt we define it as : so that the + dnl Makefiles still can work. + if $GMSGFMT --statistics /dev/null >/dev/null 2>&1 && + (if $GMSGFMT --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then + : ; + else + GMSGFMT=`echo "$GMSGFMT" | sed -e 's,^.*/,,'` + AC_MSG_RESULT( + [found $GMSGFMT program is not GNU msgfmt; ignore it]) + GMSGFMT=":" + fi + fi + + dnl This could go away some day; the PATH_PROG_WITH_TEST already does it. + dnl Test whether we really found GNU xgettext. + if test "$XGETTEXT" != ":"; then + dnl If it is no GNU xgettext we define it as : so that the + dnl Makefiles still can work. + if $XGETTEXT --omit-header --copyright-holder= /dev/null >/dev/null 2>&1 && + (if $XGETTEXT --omit-header --copyright-holder= /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then + : ; + else + AC_MSG_RESULT( + [found xgettext program is not GNU xgettext; ignore it]) + XGETTEXT=":" + fi + dnl Remove leftover from FreeBSD xgettext call. + rm -f messages.po + fi + + AC_OUTPUT_COMMANDS([ + for ac_file in $CONFIG_FILES; do + # Support "outfile[:infile[:infile...]]" + case "$ac_file" in + *:*) ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + esac + # PO directories have a Makefile.in generated from Makefile.in.in. + case "$ac_file" in */Makefile.in) + # Adjust a relative srcdir. + ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'` + ac_dir_suffix="/`echo "$ac_dir"|sed 's%^\./%%'`" + ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'` + # In autoconf-2.13 it is called $ac_given_srcdir. + # In autoconf-2.50 it is called $srcdir. + test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir" + case "$ac_given_srcdir" in + .) top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;; + /*) top_srcdir="$ac_given_srcdir" ;; + *) top_srcdir="$ac_dots$ac_given_srcdir" ;; + esac + if test -f "$ac_given_srcdir/$ac_dir/POTFILES.in"; then + rm -f "$ac_dir/POTFILES" + test -n "$as_me" && echo "$as_me: creating $ac_dir/POTFILES" || echo "creating $ac_dir/POTFILES" + cat "$ac_given_srcdir/$ac_dir/POTFILES.in" | sed -e "/^#/d" -e "/^[ ]*\$/d" -e "s,.*, $top_srcdir/& \\\\," | sed -e "\$s/\(.*\) \\\\/\1/" > "$ac_dir/POTFILES" + # ALL_LINGUAS, POFILES, GMOFILES, UPDATEPOFILES, DUMMYPOFILES depend + # on $ac_dir but don't depend on user-specified configuration + # parameters. + if test -f "$ac_given_srcdir/$ac_dir/LINGUAS"; then + # The LINGUAS file contains the set of available languages. + if test -n "$ALL_LINGUAS"; then + test -n "$as_me" && echo "$as_me: setting ALL_LINGUAS in configure.in is obsolete" || echo "setting ALL_LINGUAS in configure.in is obsolete" + fi + ALL_LINGUAS_=`sed -e "/^#/d" "$ac_given_srcdir/$ac_dir/LINGUAS"` + # Hide the ALL_LINGUAS assigment from automake. + eval 'ALL_LINGUAS''=$ALL_LINGUAS_' + fi + case "$ac_given_srcdir" in + .) srcdirpre= ;; + *) srcdirpre='$(srcdir)/' ;; + esac + POFILES= + GMOFILES= + UPDATEPOFILES= + DUMMYPOFILES= + for lang in $ALL_LINGUAS; do + POFILES="$POFILES $srcdirpre$lang.po" + GMOFILES="$GMOFILES $srcdirpre$lang.gmo" + UPDATEPOFILES="$UPDATEPOFILES $lang.po-update" + DUMMYPOFILES="$DUMMYPOFILES $lang.nop" + done + # CATALOGS depends on both $ac_dir and the user's LINGUAS + # environment variable. + INST_LINGUAS= + if test -n "$ALL_LINGUAS"; then + for presentlang in $ALL_LINGUAS; do + useit=no + if test "%UNSET%" != "$LINGUAS"; then + desiredlanguages="$LINGUAS" + else + desiredlanguages="$ALL_LINGUAS" + fi + for desiredlang in $desiredlanguages; do + # Use the presentlang catalog if desiredlang is + # a. equal to presentlang, or + # b. a variant of presentlang (because in this case, + # presentlang can be used as a fallback for messages + # which are not translated in the desiredlang catalog). + case "$desiredlang" in + "$presentlang"*) useit=yes;; + esac + done + if test $useit = yes; then + INST_LINGUAS="$INST_LINGUAS $presentlang" + fi + done + fi + CATALOGS= + if test -n "$INST_LINGUAS"; then + for lang in $INST_LINGUAS; do + CATALOGS="$CATALOGS $lang.gmo" + done + fi + test -n "$as_me" && echo "$as_me: creating $ac_dir/Makefile" || echo "creating $ac_dir/Makefile" + sed -e "/^POTFILES =/r $ac_dir/POTFILES" -e "/^# Makevars/r $ac_given_srcdir/$ac_dir/Makevars" -e "s|@POFILES@|$POFILES|g" -e "s|@GMOFILES@|$GMOFILES|g" -e "s|@UPDATEPOFILES@|$UPDATEPOFILES|g" -e "s|@DUMMYPOFILES@|$DUMMYPOFILES|g" -e "s|@CATALOGS@|$CATALOGS|g" "$ac_dir/Makefile.in" > "$ac_dir/Makefile" + for f in "$ac_given_srcdir/$ac_dir"/Rules-*; do + if test -f "$f"; then + case "$f" in + *.orig | *.bak | *~) ;; + *) cat "$f" >> "$ac_dir/Makefile" ;; + esac + fi + done + fi + ;; + esac + done], + [# Capture the value of obsolete ALL_LINGUAS because we need it to compute + # POFILES, GMOFILES, UPDATEPOFILES, DUMMYPOFILES, CATALOGS. But hide it + # from automake. + eval 'ALL_LINGUAS''="$ALL_LINGUAS"' + # Capture the value of LINGUAS because we need it to compute CATALOGS. + LINGUAS="${LINGUAS-%UNSET%}" + ]) +]) + + +dnl Checks for all prerequisites of the intl subdirectory, +dnl except for INTL_LIBTOOL_SUFFIX_PREFIX (and possibly LIBTOOL), INTLOBJS, +dnl USE_INCLUDED_LIBINTL, BUILD_INCLUDED_LIBINTL. +AC_DEFUN([AM_INTL_SUBDIR], +[ + AC_REQUIRE([AC_PROG_INSTALL])dnl + AC_REQUIRE([AM_MKINSTALLDIRS])dnl + AC_REQUIRE([AC_PROG_CC])dnl + AC_REQUIRE([AC_CANONICAL_HOST])dnl + AC_REQUIRE([AC_PROG_RANLIB])dnl + AC_REQUIRE([AC_ISC_POSIX])dnl + AC_REQUIRE([AC_HEADER_STDC])dnl + AC_REQUIRE([AC_C_CONST])dnl + AC_REQUIRE([AC_C_INLINE])dnl + AC_REQUIRE([AC_TYPE_OFF_T])dnl + AC_REQUIRE([AC_TYPE_SIZE_T])dnl + AC_REQUIRE([AC_FUNC_ALLOCA])dnl + AC_REQUIRE([AC_FUNC_MMAP])dnl + AC_REQUIRE([jm_GLIBC21])dnl + AC_REQUIRE([gt_INTDIV0])dnl + AC_REQUIRE([jm_AC_TYPE_UINTMAX_T])dnl + AC_REQUIRE([gt_HEADER_INTTYPES_H])dnl + AC_REQUIRE([gt_INTTYPES_PRI])dnl + + AC_CHECK_HEADERS([argz.h limits.h locale.h nl_types.h malloc.h stddef.h \ +stdlib.h string.h unistd.h sys/param.h]) + AC_CHECK_FUNCS([feof_unlocked fgets_unlocked getc_unlocked getcwd getegid \ +geteuid getgid getuid mempcpy munmap putenv setenv setlocale stpcpy \ +strcasecmp strdup strtoul tsearch __argz_count __argz_stringify __argz_next]) + + AM_ICONV + AM_LANGINFO_CODESET + if test $ac_cv_header_locale_h = yes; then + AM_LC_MESSAGES + fi + + dnl intl/plural.c is generated from intl/plural.y. It requires bison, + dnl because plural.y uses bison specific features. It requires at least + dnl bison-1.26 because earlier versions generate a plural.c that doesn't + dnl compile. + dnl bison is only needed for the maintainer (who touches plural.y). But in + dnl order to avoid separate Makefiles or --enable-maintainer-mode, we put + dnl the rule in general Makefile. Now, some people carelessly touch the + dnl files or have a broken "make" program, hence the plural.c rule will + dnl sometimes fire. To avoid an error, defines BISON to ":" if it is not + dnl present or too old. + AC_CHECK_PROGS([INTLBISON], [bison]) + if test -z "$INTLBISON"; then + ac_verc_fail=yes + else + dnl Found it, now check the version. + AC_MSG_CHECKING([version of bison]) +changequote(<<,>>)dnl + ac_prog_version=`$INTLBISON --version 2>&1 | sed -n 's/^.*GNU Bison.* \([0-9]*\.[0-9.]*\).*$/\1/p'` + case $ac_prog_version in + '') ac_prog_version="v. ?.??, bad"; ac_verc_fail=yes;; + 1.2[6-9]* | 1.[3-9][0-9]* | [2-9].*) +changequote([,])dnl + ac_prog_version="$ac_prog_version, ok"; ac_verc_fail=no;; + *) ac_prog_version="$ac_prog_version, bad"; ac_verc_fail=yes;; + esac + AC_MSG_RESULT([$ac_prog_version]) + fi + if test $ac_verc_fail = yes; then + INTLBISON=: + fi +]) + + +AC_DEFUN([AM_MKINSTALLDIRS], +[ + dnl If the AC_CONFIG_AUX_DIR macro for autoconf is used we possibly + dnl find the mkinstalldirs script in another subdir but $(top_srcdir). + dnl Try to locate is. + MKINSTALLDIRS= + if test -n "$ac_aux_dir"; then + MKINSTALLDIRS="$ac_aux_dir/mkinstalldirs" + fi + if test -z "$MKINSTALLDIRS"; then + MKINSTALLDIRS="\$(top_srcdir)/mkinstalldirs" + fi + AC_SUBST(MKINSTALLDIRS) +]) + + +dnl Usage: AM_GNU_GETTEXT_VERSION([gettext-version]) +AC_DEFUN([AM_GNU_GETTEXT_VERSION], []) diff --git a/m4/glibc21.m4 b/m4/glibc21.m4 new file mode 100644 index 000000000..9c9f3db30 --- /dev/null +++ b/m4/glibc21.m4 @@ -0,0 +1,32 @@ +# glibc21.m4 serial 2 (fileutils-4.1.3, gettext-0.10.40) +dnl Copyright (C) 2000-2002 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. + +# Test for the GNU C Library, version 2.1 or newer. +# From Bruno Haible. + +AC_DEFUN([jm_GLIBC21], + [ + AC_CACHE_CHECK(whether we are using the GNU C Library 2.1 or newer, + ac_cv_gnu_library_2_1, + [AC_EGREP_CPP([Lucky GNU user], + [ +#include +#ifdef __GNU_LIBRARY__ + #if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1) || (__GLIBC__ > 2) + Lucky GNU user + #endif +#endif + ], + ac_cv_gnu_library_2_1=yes, + ac_cv_gnu_library_2_1=no) + ] + ) + AC_SUBST(GLIBC21) + GLIBC21="$ac_cv_gnu_library_2_1" + ] +) diff --git a/m4/iconv.m4 b/m4/iconv.m4 new file mode 100644 index 000000000..c5f357982 --- /dev/null +++ b/m4/iconv.m4 @@ -0,0 +1,103 @@ +# iconv.m4 serial AM4 (gettext-0.11.3) +dnl Copyright (C) 2000-2002 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. + +dnl From Bruno Haible. + +AC_DEFUN([AM_ICONV_LINKFLAGS_BODY], +[ + dnl Prerequisites of AC_LIB_LINKFLAGS_BODY. + AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) + AC_REQUIRE([AC_LIB_RPATH]) + + dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV + dnl accordingly. + AC_LIB_LINKFLAGS_BODY([iconv]) +]) + +AC_DEFUN([AM_ICONV_LINK], +[ + dnl Some systems have iconv in libc, some have it in libiconv (OSF/1 and + dnl those with the standalone portable GNU libiconv installed). + + dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV + dnl accordingly. + AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY]) + + dnl Add $INCICONV to CPPFLAGS before performing the following checks, + dnl because if the user has installed libiconv and not disabled its use + dnl via --without-libiconv-prefix, he wants to use it. The first + dnl AC_TRY_LINK will then fail, the second AC_TRY_LINK will succeed. + am_save_CPPFLAGS="$CPPFLAGS" + AC_LIB_APPENDTOVAR([CPPFLAGS], [$INCICONV]) + + AC_CACHE_CHECK(for iconv, am_cv_func_iconv, [ + am_cv_func_iconv="no, consider installing GNU libiconv" + am_cv_lib_iconv=no + AC_TRY_LINK([#include +#include ], + [iconv_t cd = iconv_open("",""); + iconv(cd,NULL,NULL,NULL,NULL); + iconv_close(cd);], + am_cv_func_iconv=yes) + if test "$am_cv_func_iconv" != yes; then + am_save_LIBS="$LIBS" + LIBS="$LIBS $LIBICONV" + AC_TRY_LINK([#include +#include ], + [iconv_t cd = iconv_open("",""); + iconv(cd,NULL,NULL,NULL,NULL); + iconv_close(cd);], + am_cv_lib_iconv=yes + am_cv_func_iconv=yes) + LIBS="$am_save_LIBS" + fi + ]) + if test "$am_cv_func_iconv" = yes; then + AC_DEFINE(HAVE_ICONV, 1, [Define if you have the iconv() function.]) + fi + if test "$am_cv_lib_iconv" = yes; then + AC_MSG_CHECKING([how to link with libiconv]) + AC_MSG_RESULT([$LIBICONV]) + else + dnl If $LIBICONV didn't lead to a usable library, we don't need $INCICONV + dnl either. + CPPFLAGS="$am_save_CPPFLAGS" + LIBICONV= + LTLIBICONV= + fi + AC_SUBST(LIBICONV) + AC_SUBST(LTLIBICONV) +]) + +AC_DEFUN([AM_ICONV], +[ + AM_ICONV_LINK + if test "$am_cv_func_iconv" = yes; then + AC_MSG_CHECKING([for iconv declaration]) + AC_CACHE_VAL(am_cv_proto_iconv, [ + AC_TRY_COMPILE([ +#include +#include +extern +#ifdef __cplusplus +"C" +#endif +#if defined(__STDC__) || defined(__cplusplus) +size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft); +#else +size_t iconv(); +#endif +], [], am_cv_proto_iconv_arg1="", am_cv_proto_iconv_arg1="const") + am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);"]) + am_cv_proto_iconv=`echo "[$]am_cv_proto_iconv" | tr -s ' ' | sed -e 's/( /(/'` + AC_MSG_RESULT([$]{ac_t:- + }[$]am_cv_proto_iconv) + AC_DEFINE_UNQUOTED(ICONV_CONST, $am_cv_proto_iconv_arg1, + [Define as const if the declaration of iconv() needs const.]) + fi +]) diff --git a/m4/isc-posix.m4 b/m4/isc-posix.m4 new file mode 100644 index 000000000..1319dd1c7 --- /dev/null +++ b/m4/isc-posix.m4 @@ -0,0 +1,26 @@ +# isc-posix.m4 serial 2 (gettext-0.11.2) +dnl Copyright (C) 1995-2002 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. + +# This file is not needed with autoconf-2.53 and newer. Remove it in 2005. + +# This test replaces the one in autoconf. +# Currently this macro should have the same name as the autoconf macro +# because gettext's gettext.m4 (distributed in the automake package) +# still uses it. Otherwise, the use in gettext.m4 makes autoheader +# give these diagnostics: +# configure.in:556: AC_TRY_COMPILE was called before AC_ISC_POSIX +# configure.in:556: AC_TRY_RUN was called before AC_ISC_POSIX + +undefine([AC_ISC_POSIX]) + +AC_DEFUN([AC_ISC_POSIX], + [ + dnl This test replaces the obsolescent AC_ISC_POSIX kludge. + AC_CHECK_LIB(cposix, strerror, [LIBS="$LIBS -lcposix"]) + ] +) diff --git a/m4/lcmessage.m4 b/m4/lcmessage.m4 new file mode 100644 index 000000000..ffd4008b8 --- /dev/null +++ b/m4/lcmessage.m4 @@ -0,0 +1,32 @@ +# lcmessage.m4 serial 3 (gettext-0.11.3) +dnl Copyright (C) 1995-2002 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. +dnl +dnl This file can can be used in projects which are not available under +dnl the GNU General Public License or the GNU Library General Public +dnl License but which still want to provide support for the GNU gettext +dnl functionality. +dnl Please note that the actual code of the GNU gettext library is covered +dnl by the GNU Library General Public License, and the rest of the GNU +dnl gettext package package is covered by the GNU General Public License. +dnl They are *not* in the public domain. + +dnl Authors: +dnl Ulrich Drepper , 1995. + +# Check whether LC_MESSAGES is available in . + +AC_DEFUN([AM_LC_MESSAGES], +[ + AC_CACHE_CHECK([for LC_MESSAGES], am_cv_val_LC_MESSAGES, + [AC_TRY_LINK([#include ], [return LC_MESSAGES], + am_cv_val_LC_MESSAGES=yes, am_cv_val_LC_MESSAGES=no)]) + if test $am_cv_val_LC_MESSAGES = yes; then + AC_DEFINE(HAVE_LC_MESSAGES, 1, + [Define if your file defines LC_MESSAGES.]) + fi +]) diff --git a/m4/progtest.m4 b/m4/progtest.m4 new file mode 100644 index 000000000..443c8e306 --- /dev/null +++ b/m4/progtest.m4 @@ -0,0 +1,59 @@ +# progtest.m4 serial 2 (gettext-0.10.40) +dnl Copyright (C) 1996-2002 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. +dnl +dnl This file can can be used in projects which are not available under +dnl the GNU General Public License or the GNU Library General Public +dnl License but which still want to provide support for the GNU gettext +dnl functionality. +dnl Please note that the actual code of the GNU gettext library is covered +dnl by the GNU Library General Public License, and the rest of the GNU +dnl gettext package package is covered by the GNU General Public License. +dnl They are *not* in the public domain. + +dnl Authors: +dnl Ulrich Drepper , 1996. + +# Search path for a program which passes the given test. + +dnl AM_PATH_PROG_WITH_TEST(VARIABLE, PROG-TO-CHECK-FOR, +dnl TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]]) +AC_DEFUN([AM_PATH_PROG_WITH_TEST], +[# Extract the first word of "$2", so it can be a program name with args. +set dummy $2; ac_word=[$]2 +AC_MSG_CHECKING([for $ac_word]) +AC_CACHE_VAL(ac_cv_path_$1, +[case "[$]$1" in + /*) + ac_cv_path_$1="[$]$1" # Let the user override the test with a path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in ifelse([$5], , $PATH, [$5]); do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if [$3]; then + ac_cv_path_$1="$ac_dir/$ac_word" + break + fi + fi + done + IFS="$ac_save_ifs" +dnl If no 4th arg is given, leave the cache variable unset, +dnl so AC_PATH_PROGS will keep looking. +ifelse([$4], , , [ test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4" +])dnl + ;; +esac])dnl +$1="$ac_cv_path_$1" +if test ifelse([$4], , [-n "[$]$1"], ["[$]$1" != "$4"]); then + AC_MSG_RESULT([$]$1) +else + AC_MSG_RESULT(no) +fi +AC_SUBST($1)dnl +]) diff --git a/mingwenv.bat b/mingwenv.bat new file mode 100755 index 000000000..367293e45 --- /dev/null +++ b/mingwenv.bat @@ -0,0 +1,4 @@ +@echo Setting environment variables for MinGw build of Inkscape +set GTK=c:\gtk26 +set path=c:\mingw\bin;%GTK%\bin;%path% + diff --git a/mkinstalldirs b/mkinstalldirs new file mode 100755 index 000000000..5d26a485f --- /dev/null +++ b/mkinstalldirs @@ -0,0 +1,150 @@ +#! /bin/sh +# mkinstalldirs --- make directory hierarchy + +scriptversion=2005-02-02.21 + +# Original author: Noah Friedman +# Created: 1993-05-16 +# Public domain. +# +# This file is maintained in Automake, please report +# bugs to or send patches to +# . + +errstatus=0 +dirmode="" + +usage="\ +Usage: mkinstalldirs [-h] [--help] [--version] [-m MODE] DIR ... + +Create each directory DIR (with mode MODE, if specified), including all +leading file name components. + +Report bugs to ." + +# process command line arguments +while test $# -gt 0 ; do + case $1 in + -h | --help | --h*) # -h for help + echo "$usage" + exit $? + ;; + -m) # -m PERM arg + shift + test $# -eq 0 && { echo "$usage" 1>&2; exit 1; } + dirmode=$1 + shift + ;; + --version) + echo "$0 $scriptversion" + exit $? + ;; + --) # stop option processing + shift + break + ;; + -*) # unknown option + echo "$usage" 1>&2 + exit 1 + ;; + *) # first non-opt arg + break + ;; + esac +done + +for file +do + if test -d "$file"; then + shift + else + break + fi +done + +case $# in + 0) exit 0 ;; +esac + +# Solaris 8's mkdir -p isn't thread-safe. If you mkdir -p a/b and +# mkdir -p a/c at the same time, both will detect that a is missing, +# one will create a, then the other will try to create a and die with +# a "File exists" error. This is a problem when calling mkinstalldirs +# from a parallel make. We use --version in the probe to restrict +# ourselves to GNU mkdir, which is thread-safe. +case $dirmode in + '') + if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then + echo "mkdir -p -- $*" + exec mkdir -p -- "$@" + else + # On NextStep and OpenStep, the `mkdir' command does not + # recognize any option. It will interpret all options as + # directories to create, and then abort because `.' already + # exists. + test -d ./-p && rmdir ./-p + test -d ./--version && rmdir ./--version + fi + ;; + *) + if mkdir -m "$dirmode" -p --version . >/dev/null 2>&1 && + test ! -d ./--version; then + echo "mkdir -m $dirmode -p -- $*" + exec mkdir -m "$dirmode" -p -- "$@" + else + # Clean up after NextStep and OpenStep mkdir. + for d in ./-m ./-p ./--version "./$dirmode"; + do + test -d $d && rmdir $d + done + fi + ;; +esac + +for file +do + set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` + shift + + pathcomp= + for d + do + pathcomp="$pathcomp$d" + case $pathcomp in + -*) pathcomp=./$pathcomp ;; + esac + + if test ! -d "$pathcomp"; then + echo "mkdir $pathcomp" + + mkdir "$pathcomp" || lasterr=$? + + if test ! -d "$pathcomp"; then + errstatus=$lasterr + else + if test ! -z "$dirmode"; then + echo "chmod $dirmode $pathcomp" + lasterr="" + chmod "$dirmode" "$pathcomp" || lasterr=$? + + if test ! -z "$lasterr"; then + errstatus=$lasterr + fi + fi + fi + fi + + pathcomp="$pathcomp/" + done +done + +exit $errstatus + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/packaging/autopackage/.cvsignore b/packaging/autopackage/.cvsignore new file mode 100644 index 000000000..6cfc7e642 --- /dev/null +++ b/packaging/autopackage/.cvsignore @@ -0,0 +1 @@ +default.apspec diff --git a/packaging/autopackage/default.apspec.in b/packaging/autopackage/default.apspec.in new file mode 100644 index 000000000..398f330d3 --- /dev/null +++ b/packaging/autopackage/default.apspec.in @@ -0,0 +1,63 @@ +# autopackage specfile, (C) 2004 Mike Hearn + +[Meta] +RootName: @inkscape.org/inkscape:$SOFTWAREVERSION +ShortName: inkscape +DisplayName: Inkscape Vector Graphics Editor +Summary: Inkscape is an open source SVG editor with capabilities similar to Illustrator, CorelDraw and Visio +SoftwareVersion: @VERSION@ +Maintainer: The Inkscape team +Packager: Aaron Spike +AutopackageTarget: 1.0 + +[Description] +Inkscape is an open source SVG editor with capabilities +similar to Illustrator, CorelDraw, Visio, etc. Supported SVG features +include basic shapes, paths, text, alpha blending, transforms, +gradients, node editing, svg-to-png export, grouping, and more. + +[BuildPrepare] +if [ ! -x configure ]; then + ./autogen.sh +fi +export APBUILD_STATIC="popt gc gccpp gtkmm-2.4 gdkmm-2.4 atkmm-1.6 pangomm-1.4 glibmm-2.4 sigc-2.0 loudmouth-1 Xrender" +PATH=/usr/local/src/inkscape/extra/static/bin:$PATH +PKG_CONFIG_PATH=/usr/local/src/inkscape/extra/static/lib/pkgconfig:/usr/local/lib/pkgconfig:/usr/lib/pkgconfig +CPPFLAGS="-I/usr/local/src/inkscape/extra/static/include" +LDFLAGS="-L/usr/local/src/inkscape/extra/static/lib" +export PATH PKG_CONFIG_PATH CPPFLAGS LDFLAGS +prepareBuild --enable-binreloc --with-gnome-vfs=no --enable-inkboard + +[BuildUnprepare] +unprepareBuild + +[Imports] +echo '*' | import # import everything + +[Prepare] +require @gnu.org/libstdc++ 3 +require @xmlsoft.org/libxml2 2.6 +require @xmlsoft.org/libxslt 1.0 +require @gtk.org/gtk 2.4 +# statically linked for now: require @rpm.org/popt 0.0 +# statically linked: require @libsigc.sourceforge.net/libsigc 3 +require @libpng.org/libpng 3 +# statically linked: require @gtkmm.org/gtkmm2 3 +require @zlib.org/zlib 1 +# require @xfree86.org/xft 2 +# require @freetype.org/freetype 6 +# require @freedesktop.org/fontconfig 1 + +[Install] +installExe bin/inkscape bin/inkview +installMan 1 man/man1/* +installIcon share/pixmaps/inkscape.png +installDesktop "Graphics" share/applications/inkscape.desktop + +copyFiles --nobackup share/locale $PREFIX/share +copyFiles share/inkscape $PREFIX/share +# copyFiles lib/inkscape $PREFIX/lib + +[Uninstall] +uninstallFromLog + diff --git a/packaging/inkscape.16.png.bz2 b/packaging/inkscape.16.png.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..74983b3ac9b297ae8cb3c5c954f1f8e868e126e6 GIT binary patch literal 609 zcmV-n0-pUsT4*^jL0KkKS*2UOHvj;afB*ge`v1T8Wq$wr{kQ*_{D1%N{eS<@YqmGz zp5Oks?ESC-S!hv|+J=A{0BAA*&>A!V02%-Rpa2a6KmnnnAkYmBGz|f!nKEgnnrOr{ z+J>0}ka~c~02vJc00x-`fB*mnng9T3+Ch^ElQjm0k5B*r00ThK0D6r*Ayqv+M9G?m zsAy;dKmf=90B8U-4FQp(KmY&$01XC!003#AXblic`|82j_#hXJt91#WDYSKD!{9d^@=ypf2+_3#01z8s0fM(I5rpwY^mi0+5@9%|wL0f0 zl>w4XtCIGW*jjV*9$*-$C`^C`%cdMZ?KMLrdw6J=GscD%_(Z_09lAAZ9t;EWI7~X< zCKKmZ8an1Ncag;a^evZ_vV}K*1PH1i%1BXcNe38e(at zCTPghMy4j1Xodg)Xahq)gCG+G@ez#xm}u0(U}|aT)bs!&0GreRm;fWt0j85=1lj=7 zF)(OpG}8bCVr0!S0iXh5HiB%3gG9_g1lj-q6A-`yMvV;yjSok4iPPd2?kgcAWMKk0b~dofSL*v8DX4dYX9&N-a|7F3C#FX1AtAmI(M%}W>og~ z#wd`6UkEmOD48#G<|^t@B%%6B3;_YrQ5A@6`8uq5ZCFca&<+UaNQw)-SVK`zhAn3A zqV~hJC^BRW0enPzrSYVq3k7QhkDLWWaXlIWCh023TK6- zqlf_>l70>e5AC*2GvG(!T88~UPO<27M+Kbqp>Ll(Sj=0&=ckt6+!HS_)(yZ+1k8F)O$M ze5is82F4dJv-tdBnYiNSNC99yV!8_uzLnB?EJWpVBRwLy;*5YcVcw7<8=|){MjHlq z$5(hQ*XJ{TLEAnuB*+)cpE4CWset5`z1Bo?=-}`H78L1rLF)Xcf^YmujfYokVQDN) z;rhM<5+SfZ&Pdo`%d!ZcNihs`gzrxnS_HE)jiuFn3pwG`st5fY$X{NZ$aqg7RtIDd zClDU1*9+;vIM;EvXp{$Rdz4#T0rj9VICLsQgcN6!(_??J1&m0Tot$fikw4f%6eP6$ z1`IJga{EMAV~T+>{AywQ{(J)Y#USNC$eG&MNyp1kK76KXTlMR_kHS5Y{TQ-E?Q z$7;ODN)T{)>QkYrfgAiLgJL3RyDSe~5a5F>Jh@i`Re3KD9;D?097q@fa3a<^iRJD^ zNC|N^^)cGLK5HzYJ2#S{(k(*a{`~!>#{`=1AnfjSYTV;3YMAjO$j|}WQ6w__&!}T` zjQ)}O09gVlbJqM&sDmZpOXse?gc6{ehej-wMInT!)L7^q2p4#}k}1N3gd^>J@OYBJ ABLDyZ literal 0 HcmV?d00001 diff --git a/packaging/inkscape.48.png.bz2 b/packaging/inkscape.48.png.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..1017cab1d6c78a395bf2cd12c6518c6f8bc88ce7 GIT binary patch literal 1951 zcmV;Q2VnR@T4*^jL0KkKS<}~OG5`U~fB*mg|NsC0|NsC0|NsC0{r~^}|Nnpg|NsC0 z|NsC0-~Z4A9&^32?|XaRq3(LuyfUZcWJuVWjGomVlPBpwdQ2lj)M)h@G%%Y`^*v3f zdL|$PKy6P=C#khGG!IA`X`spKGzNnvo}s3UX#*n~2-9jb@|rVhPe}DKGt~@DJ*f_- zv?S5!GKZ-2$W0j<8fXt76ZK80=?~QmOn}JIriP8`CPAL4Hm06X9#djsdZs6oKS~Cl zsx--ow2veMAk)-6Pbg`pq{-@SCQURNXgy5;=nYS45t=faDUjNYsixC4CXAXr8bcB3 zFpSjG00i2bQ%@+#`lixkdP7fB(LFMn7>x$hGz0Za&}e9xG%=~@X*6hJ21bKSGzpVK z5a~4Z5rCRt5rCUO&`fA2sk8*ZG!p=ZOanjwG>iZM69QmNXaEd=nV^`M3F$F0Hj@D` z00x65Q#As42>nea)L|JOgu$fR5r%}(i1Yviz!Nk8Owb^}LjzMF!eAo;WZDF1%>=*^ zlT99zCQOVF!2y8lgCt^Pb6GIPoP;VLh7h170Te5o2mnvl8vdF~CX+P)W!gt|uXqMY zPk{ZfCf(No_cU&c7@``itWQ z)*}wgyszjvgr_GyR8JU@y|~qINvL!In2?t`3a>c~CE@TyP+**m8i5OYEI@c|`OIQI z?U72G9_lhjBmiB3&EeMJlL|b|TkCdG8&(SqvYMp_gL><025%DFn>Dw4l zN0g=hnOgx*DlPg+^_rNuLipJyH04`{3?^=|J!nv^S%Q#f0MR5CS!|3TX|r!fvjTN^ zdhR9`kfmanAhCnUMzk@|i%|r`4Y_1t^N3qRF60P}DL@6_o-sLKQz$&lw+x|EuOPuB z(vP}VCj)!DNuG7m&qD*Q^fQ?hP?zK9^_{C>^3Qo=n6ku6LXK6hpnHMdpU$6{AU$&w zbTgwML!1w95wMu;c5sS;vJ~i z^HTWfHF&XXXv?`Fca|Mb~tE9R8QePxACHPTeC-LQ#mwDmQNR8&a3?TnclR$VA zE8qm40I6cS_Hf!_mVQw(Kcy&q31K7q(8h9Ia}(>1=t2n(UG3VWhAwdg;#T>oXzDgb z8@T!SW6Nt9<%`K2G+%`ZYIxEIcF)$(Bd?K2`Ur)UyjWeXS*P@~t{(T=Mq3PG%&PLS ziCD=>N?Hok2VSizkdoP-I~pN#15BgFLE&QXNhiN~=%WFgY>2ByfZ)EU!iM^#NyLRg zdYmswLUdhFmq$1Jek-A(U80&t8H4MJfB|EuU_nuq;ZO(`p-`d0yGu@g-{r72LE_eej8-bp9S(whJ`mFqeO9ZV;vv$j#29 z_f9y#$aY{F-oJ_VR=5Xjsa#{N#x6J?TZ28gK3;ioVTuzVplN=s5*X>#sZBrjQ`bE> z@ipE}O?ndT*S_}c?M^^jT{7rL8a{Fpo}go7QSGJrgYo2rFV`s1`K(J!jLs4q8&-=h zO_B#l?$wW50^tTrZ}hAgn)SX0%o8{F+9nT!GN6&CGxb?1GNmj`4;~m4m4H&geIDH8 z@^aQwN7c@msbtN^`WPw~q0o4gj;D2~=M+lGP$-bHBs>1hAgW&sM&shVxt4%BnHUq= zDjU$~hWim4`<$P|Hy29ub93vmYSVzug?r)qc|;HxprlO;**bi7P1>qXJ2=d^1v=8K z&G)S@+H z$A%Mv@AMqFX6M=M?l!zW5g=R27oc>y*RZ20zsQ81s{4m#Hf##2p$qPZrG)fEpkb%4 zYp5FFwU7eRXuAKhB7qBf|LskfQK=b>nD;c@8eNFOH(=(?#QZ( z8}3=DVJ27^2+1C4|1!Ptm&`I4KZU}NK#+pg5^Mv45wBBbiP9ACq#)P#ULv(kFpdr{NFnnKxeEF1trjQ{47}ZA9l8MY#G*H>hQ#5NQiY*MiG+c+N98|xt lUKTRtJ)BR+@L2}mF>$28H?epFl8i6-yOJrwgod8GL6G@Oqv`+v literal 0 HcmV?d00001 diff --git a/packaging/macosx/Resources/EPS.icns b/packaging/macosx/Resources/EPS.icns new file mode 100644 index 0000000000000000000000000000000000000000..153a21ec976b27edc577a415484de56c1c2c2f39 GIT binary patch literal 45195 zcmeHw2S60p7WV8e9TCJHV@dJlJ!4FaEirkCDZa##uE|SGvqi<;^@%dGja~&&Py_`9 zga87ehays?NtGr|U~!j4*j=^=^PfArOI?cX<^BK9C<$}#J?Gqe?zv~~eCOP8$L2i; zF)Y+}$H7H!Vi=vRk6~eniLsHP-nJY}&!f7!>P}I%pDPP9_>bQoe|Vm|7DITA?UVKeCr;`yWiR>j6k8#Cpf% zh{kjmjp-IOCW~uv@mKtU-47RB+LEkp=I8dQ9zYe~iIs>Q_%HKMDl6RJ-Hp-ukF3x_TRYwyjPwXlD8}=DN%W)u15ECJ$?1Xz_3*xef|>C zgE85LDSxE!|A&|b*^L1s^n=4s68zM_PumypWBg2h{#yAvb|Ign_Zt(VUATyQ>bbkS zxHvd)PMSMn#yQn@?v$1k7UX7Uq(u0g`_LXU$!e;psje(9E54n7>&Ep<=NDOHlQw<3 zBsk+{T3TjiMta)K8#n*-^#5bJ6*l=7Uq6q~3zvg!Y#dz9oI4+p;p@S>KHUg7Pzyc zC8k{{Y;JC9A{xitYpAU%OpW>@GBn`g2V9JHyNzhZn~a)yjSY3xchGoJe_zhUw2IpA zx3u8A@%*9`UQ=UzZFNOy@$Em~<6=`v!~y}Ie_v4Jn0BAn3}kmfWafuZQ`RXIf@9^o zCbWV7g1Y*es>7QhfY&Mz+~+mjtE;;WHM&&~MWPOAtOrgSR<{DR z;C^%Cy%I!I)g=~p=DXHPNU~D!pbc2_dAxF}rduKr-l`T=lcex&ON+1#s`%AwxR_oQ zDd}vj>FB7#NrU$0rmE%#!d77o)X=I(T*{Djwl=Ux-R{!X2W=1Pp_pDp$_Ob<(8wlr z3V0n4I_{yil_XO}6V|av+QU@5gD!4@LPixSm*X;;_zo~gE$0rco ziwTb>OuEEZ8ZoTczD6u8`7l(V$%xzTud-_wwjcu^V8orf|8?Z&^!C0+Osjf`izakC zyv6->@qP(q#JoO6EDBg1yLbJP@1*Sy`Wvz0=H6^M>z{w09diGEXS>>nr&M)IWHqTB zoy->|G4vKK-&WqCGGc=&5^Uw6wC#Is1{2fSE$L&$xRfqy{g{dA(O%xt+H1&!j4p3q zNnrZ4=RbGq?C9uc%UxS>%s}VmFZYy5`&6xX2-+9 z)=ZKQN%FsF%_@hSta8X1_h9>2ai_EhytLXOpSft3SXx+AR8m}6SdgEaouG2a?)kUU z3o~;Hlao`^vvTtD)6~}N$h%!w+fY+^GbuGaGbgVgyT_Uxo3aYa5=-iDCEiHO%+4*$ z>vhOh(Mc(BQJFc(H*RKR<>VC=^*Utz`HN>}G}hj|TT_GA8o~pkk4L867UE5`#zx|v zVZBC={Pc~P^2oLQJaXr*(HL`IkNn8SOiE;T$BbF&ns-sVPA%AV!ai)?JAJN&x~Q!0 zWspif?76xWzfbL33BMcXz<#XH6+5X<1Ntj(eR`))CHl2b1KPxx0hRq5&|XT_P~Xde z_R>vF^*s$}FUE8V6&jkvOr|+d|oSLhNzJ2lV z^$(T|U*EoTtX`>sA@uwIjDDtQw7<@t@tIyKDI9baCC*dZhwhw3O9o$m8>g>S%1vL`tj0f}{d3J(j22W%6q^*GhgD8?W?E`WLc}${3&a_0s(a(z z>brNVD$DPb!PBfDHz(^xY{-@Kr`#}_bv;pOT2XPQthA))HX=+c9y`!+0Fgj`3s5pH-gz2 zq_{5bh%NTw*Fh052W6Wl}jtkFbq}+--w^IV0nfOVqQ@G8UO|}@# zzLnWTZ@hPp)u3NrS9`azBs(tXGVY^w(evCTCtFO*QP|wnOf+GQ?0b3*^>u)Yt!KjhW{QWpNns#rASMJje;T~0-RHS*Zo_UB8c}R2 z@01qb34)D^V#ul@rykP>aUP_MPMBW_Z*O7;zn&*-#RUd@*iFDoTupUDJZhpKI`DRexc2CEoTNXj zx{tRS!doKsepp}I^e1ZakR{R*w_4gu36fq_^8gp(t-5>|)xG+bB&a{zMTm7ok`50} zT{A&4sw>*t2-Gd=Ws!dawdf|qx)NbFUL!3Qj~1h`yQ;0+qLcJ6;p7(1DeoJ zlTy4BmuPj0r4{$Nq=BrYT3Id50tTl^rc|f1QzDTSKd>bAyKlC(LqCL_*)XThq)ZC0 zlvD&DCrk%-0J%HDF|EtODcb(3WGLtIYC;MKZQLP8x#?zV(Vrh*B@ z@McY-af80P5s9*tA(g61Io)h1Wx?w%E~85kJv6nX3YkN04rDR zKWA;DYLGujp`V??gX`(`U|}_r7!` zASfiIj|2T7?2fN{aYANsRb-i$>se1PAK$Bi!6B))`Z&-Zf|@fg+0^| z<#QRaN$cl8e+W%Gb*d=o-039m#xN&$j|<+Y(eLTE`#I1beaf<963!gwrrgdvm|a9!X(T}JSq z!H?xXDYvHCe-hw7C-Uw#^f=Hm4GvUr=Zj0N!#YrY^T%&x^M`PtxL_(@(DB>z#qGQn z@Owjf&`w94t9635p*^THeB8gyH<}eb=;J|atMB!CP<`p`>ECd-e*W5~2bw*oVJC0V zKTiK=`&Y{sSAtU;>_Ux2a>>^VGEVLJdF`@)6o}fuiRupUp%bKO$EN3ZyZ^j)#p}=g z-UUvm*M}lMi+t!rvF!B4^Q5%gY{ly@Pgs~L;I&CbYA2dTH6kQ43ug;lb zh?#u)#rJrDc%TJY)sqWl`l44kPmdKWX9i^ zfQuN<``m12UFRUjs%Tve=m^bV#*%M;+m;PTNPq7-UPk(w>YC18xN`kZ7G(+z{#APV z-6ijTzRBu_cqso$Hl!urZh5H5ztSE84EQV^ECC)G;LJyKuzhx@$iMd6p+1g(QM0DZfae9 zQ+ahwMGCME(U-T5N25LPBy9^cwmEjS31%N(TB@)A1O$g{UX$h_w`V<}rQCP$0X3idP&75I?(Rv_-{=d+^X>A^KHAR2K7=l1=mnOuF6s@OgB%m1` z*4UnG`1X_AO;pVL9A=;De0|~~>$r`FHRX#uh&2%ZC2E$$b31}1F zzBOEHsO#6IQMB(jXlS1|0)G++dgsA(QDo!Y%I4u|9(>U=(*|=Ey|s9O#qjOP=EX|* z3Bwq=1_lPEM@MK+y6E?rXxjJ@+s99WlmhiNiuOs*YpGj<`H##$dFCUwpEcHgxH(Q9 z)6a0~A;tIGkdg_fNNJtF79u#o(TIlaPQ!!e31*crAtQ`I@ zOLa<0ii?2^FL)l2<>Wv%3y`I!r6$G4Mumq3`TP2KT@Csq1+%K4mseEa<#-uZikHxf zi;9TC=as?`5tYi7k`Nai9vT$j>+Nwqnw<>kL6w{etdba!EIukc^qT)Aue0aEP9|YQ zC9R?ohtw>hf>u6^z_hfa#JH&IA%VW$o^Bpt>k~0HP*yONbVM0m%0Q#T3$@isnTST0 zb|X0@@0Ad~J|1(ZA}X;8q8w9`5QQ^Pukw)2v$8VMZY0J=g#`F`INMoACxxw# z!yE@v;GpkblFW?MH?F2}(P zB*%pZdY`dn9Z#&Gm|nxa-oA5}*$#^Fp1p?-?LTnv(BUJ;Po6wwVF5o(He1OWcsn=( zV}*dQIeF^1 zg@cO=+k(yIq7JLLQvE#x{ROV)QFmjrvoq3Q{J!TLSjYU@Rcr$=#&2d@eApzt%fg3A ze$ZWY_SkWssxFeO3noAX);3554h~Mvh#_d8mth#ky-dn%4;=FAA}>dfiu^Dyn`6f{%^NZ^ z<-8^2=jUdnCq;+)owYrAlIX+Q7h`M&eXz;#VVf_L-K{NrcwOP1N|)i}0#W(JKC=f( z9%v4U5Rc4GPl*k^dd}YB5VM!%p~6u7rGohw2$kXR3ax8 z9>j3dmjIE@oXnK?>;9e&_(4`5#+R@)z}QLJbG>8j8e_8niIiMZCLGDLs7D*)~kn)z16dmO4%00ek^M(!k_Uzev%*7`> zqYC-L^-XP&^VL^hulx3gpEeR+i6G(v_Uq>DJGO1!vITU$W5?e8yLKNs zLWwXxdE(fy<0lDlRcbHVvu@5H7ouD@$)zR5MfsVjabVka#F5=wf8Fr?ci;W{`wc$> zucH{!yB{4RRHgPw54UB)>(!*dM&f`x`J_60&GAjIqE*VWb5 zLSlP$WhL~oASXQ~E;96*-{ngez2Uh54>~We^PcBCz@pvVgIs(uyve!I3Fv4j&13=) zLY%a;2zr?k9}^K463h%T4u>c8Zv6}EkT2qs4qhkY6j{)Jtnwlzz z0Ko8a;OUBd&)82VV6H@WpJKZJQh#378DLZbB{UWLX)QTds0b zn88XnOif8nh>eDgVQ>Jnw+9(^s`jQ-`*N@y*iNE7D770Jmrcb!660ecuLocA#b`X9 z0|>EI5g7teHB2;Q-lc=6O(i z1yI2*2ljW=h6QM{GE-AvKN#VQv0E5C2tV5JY?`fAWLgjur~&JkN)ak|I%uPl2V}7K zii`HeY+7u2*3DMEa%zz|O;JgL4uT{qI~E9%;(akYXwPlds`0z*SI!11T7$BClm$XFm3l?p#A!38bz=8z!eA^Z_Ppi^8$UKk(IWZ7&z$ukuV2P7J>7WoLp^7d&6_fyE zHZ25CxALszMe_h2k3EnQY*qAAP+yATTPTdf34zE0X6Gcy-H-x9KYh-R>UoSJn8T5fptI2a=61`)z! z_+m_02QHu%22IRG!cuKw7{ZJk{UO_VugXKm0AkAY`21tvr&SX*(Rsrf_!)^=2r=r(DnY56W;L;Z76YLej2Cs+NJWWOJ5YkbblA7E+O+FV zm~A$1TlZF5k+jMjE|6&P`H%yk z6l2)i!KzA71`uesd6{kBk!4NN6-m`rt!!kdEuaZw$WLf&=xqT~=tGBKq7VVz zppE=uO$`{4*d9`abSe&-nORn(13|kT6C|KyFugwQwW#)BJ}Cc3EVdTuH4|oLM`}Bw z#Wo~e#1XJT3ZW#TG9Qo-1|ouWB<70r+nvqK_U3kUWE4YtDZ81YYL9_pwN#y=Lwgv3 z$WF`>VSc!oPOPY-gBK6ddNCE2Om!pup;VF}heHu@&oyD$9%g+;%#(GevaXMWHoGEAe6i6{jB+1U&Hu z)GL;RE*4AJVqH-tzfF>GgvS=q!y;u?FdV-c7Db0q^Fo;l-b{ySM08dXCdkTxH>BhU zv6wBQITu0?Ykce3?Oc$h4XJBzP70Y94okifNIGoc5Rh1ui<7jpR6@)Y(Sl2DNJg1Y zb}Jj?u=>+rO-PEpL`Pg)U0a`$L`_jJ&z3agNBCY(NsLTL&9CBHwlP6_^d3n_j6IAf z_B`%|6>`LM!6mspNoy@7a&$6d{4WO;2suDPv{I%|2fG1^c0%eX;fiTBf$pT1sN&ki zQdJuP^qD+9HF2CWXjf#%hCfuvo##)Mi7 zD(O%Oi@#OoB(;>#MQ4RjTgYa&v#DAT4}=0j<|ySz=&jD83&46;3!5UwTQOA2XUQP% zOeV9H!gTYU6cNl!!kl9G-0{bqI>dkCtcd(%fqiURGmQs2vS9G3ah>rw{I6y_T!8mww z7a2!N7ug9w3E5kUa1pnI1+E6T@d){8lp`o{sP-fo3YN8ifJ$~dMpd%pbjbK~M2U6h zvOP(9%;q#UMT;n{p@J@r2!^RC-{#5Vf;?tBs<4yW%V?$CbEI~|Uc6i^wuBm-s&SOt z$mpU|Eimgf`wwS{2&zsg%SCP_qg{+RLu%#hIFi=J5pzWB4vZpmm2+kEy5rK*q>l9J zPt5E#upO?5*?|b@JcYtl&XLj12D*^i8Hay8UnIgMmOxEV^%#$-z~z|23FS35Z^?Hc zb>vyh4X0x3*c2CfM+ed!&k9<=;iaUFskWqUeaOKdkA;-9SyD}u%C&(8x-z*e=4Z?7 zRu*X>ZOrpM{>x@=cxfvxwUVIzV${spE1cz~rT7oq_p_`mxrcXc`qqr)pHxHW z2r2t$aZ)(Sjb&vaPHgkzgpK>P)Z+Sfm_93zNT`}{6!b1d7o_FDe-&LQnUSuLE7)=a zX*b#;-4IB~+0@Gq-+5FR8jtV=_s-={RTn<&{24%K#YpRS| zL45ZvCxs1F!j_;CI={R7T$ck?#s!`jT8(@rl-WZW;s&yitKeI8yHRD9P=+hZ1h(C- zsxmGZl?1gD*!L-;C~n7QwdIYy8xXvl(1DLZapPTsglZ_DzSn#FlLIg zN4GQZv65SYAxf!|3*Ams30Fo_7F>h^TWG?SDM@_b-UbA*se77$yxi>w1y*vFssTY> zqDm}5x764LY?9VZUhH;&W|m+hSTll*`~JbHJ9~^-&UqvdnN_Y!A;_>9W0q=_6r=5X zp{h@bkH-LXiP}CWgUu)6+D7$m|M0l9|JU!HBRwjEo}~ znHYnS2LR6lA>qFYMxMGy3GxE`aqK9CdQkAJgCp*=6yCNe&;!9L2#CFO+1Kx?e?UNB zU{G*KXjs_w@bDDPF!J652M?(Eo;qcY0Avc)v$X;44oXZ<1qt==^$)xj6pZ*@Ptgn` z8|^u80Kj8}9y>T#aB!CoUEN%{OiOEy?K!XWPPQueiUOJtSJYj9{{X~R$#n=AdG~?c zR}qYC>CYlp)cUa40kyD4YK(MrRsrW8p48|E@*5IG-nD<%RkEud&QPwdU~a!ki^=E`GK1iqJEndRbFy1|w5WTk3Eq z@=jn4D00-EK(brNhYw$LI9X>S6j@vq;GhnBK+t2bHKYxPBJbS4(~s3OEbN#~&Sa=?-O9Mp!>LUc0wi9N1_U%7#09ZR6KZP^dTs~Q6!(_RO$kZOzC|aRhAF!HL zt1f*w9GPM*%ScL2xpBkA7g+~Hb2xZ71W2-Sgrwx6QrZ3H@M_P}OCJtL2G#+9BZpol zNms;`&0$9i0Y`2Mv{SBUFgjHn2n?ey(~)uHo%{B(l;iaEv$6KS%CVpXaF~u)!>;=} z+ENi5Dm2zB0XaCO>1B)tN8Y)2{~n0x?AZ%SKX&}^(Nj1R|+jq>lt9Ulcww&HVIFmoKkei;Eyrl9tI zaPmb+<9V-T7&uuu!d^JpN}$W#!D=t_84W6ND60*f(VYsJA60Jz(+{$WJwIEzixTU|n1z zmaIaAd$4584#)HjKX~bth4cURzGWj5P-uh)_khrYp=1UezwEFB*v&W`zP<3`Dc?x{ zi?&R&`Sa5dgsmA$2BSkzGTx2>(#vX_Pzc{#m>M6!+WF&GpM1D-<*eD|!-2{W$WVjI zrcJM5nEo02?b|p1^xc=MK3KkN$}hu#%Rq?0LLrK#gRQ*e_Hq1%6~3dXyP;)zepv2?*l~lV9JAl=xJ56Kyq%! zt3fvV4(!?f>-S%+{^*^>3uez736h@P`Zj#-F0i8m!vEXMwr$$5{_{^hczeb+wEBU*{YQ*mM>ZG_ZMfH z?i>wp-8#-I)NjhHDz?bP?RDE#D?fVgZRqse+0!RZ%NPm3Zk;Y7$+?#hfNiq&rxWkK zvuyF}ug;w_V~WYRc{u}+Y;9$f0q`M_Eu69zw@#IlmVe0QJV-SbS#5>^ZY%Oq)Dmyn!x!Pl-k|!l&v^nfBtVufMn=dN2Ua1W=8p z1i;6;tYXidF=N`4i6%z+It-c}rlqGp*%JU~jd1w5eLo(UIAxNliIJh6Hp3Cq)|xmi zOcOM2D=`v_|Gj;Kk;!-?Lwy}BI<$pTAuqng(~OhruiEpmuD-smwiewPzGq-M=gk)Y zg4TeU>$R^qw1BRy#h|-jI&`Dw{_)P@4FlkF9KdysM7wFpp;;Ks4b#<|{NlouAH6*^ zjLxWAd~oU+Okdk%=Bvv;U;U;=G@VhuY`2LUrq3{%{>qY--+!@U5Ug$|)soaNGc$38 z!=HvzURt=~i>;r2)gNJZlvzs|4NJF}oW=}k`V;58_U@Vu`PItki_hOYncZduV0wRe|M{bDzkt!`3~hZQ)2TCG zn)l}Nk3aiv^Fi}XOFs1+4EVbOcKckz@^`1|8<|X;I^%`E&0n(+n0 za`Cb+nM1?@j(@y(-fM5Xx#*3>%UAqpaaCg+V7#m>*pYQ;|0zp1Dh^=PCk#MuQFIXs z9S8t)DbR0N7fYcBA4`D05DXyX;}mjfdt;3%96-nnAnK(2E0bDF2r&lHFSfbjkfWidI zumByfC}p7Fsl){yHMyKy&ZsCuIom|3L2)tl;(&qzcrG2%obfDE$Vg8^spXLaQ_IUo z%n|ROT8=?xIRphBHMJbCWQ_#`{zn4>+E)PIhe&qNH8`gnyUGkSxpplGQ24MgWz--tIvS68 z3;4!CW-9PZP61#s6%L=nr#yjYc6JVRd>&ZlX$}QwT?q^f1s-cq&#p&OJxh!VkB*6o zO-V~lh(!gxToKz|uK9@T5TO9yz^hph3h0i?f>3}UEg~{U0N;!e7Qxu5ZmLI)x~c9Z z@XH@66rgiCz%L81X+p4?7Xc?c+ge){q%1zYi zhvF*@2Lv7x7IVn1_|VX-E;6r{WHX_^p=)%HD}5QR1*fAkrChpLc5wHp(uH`^Jxx6_wB0MZ1w~E(Ac4fs4H+=vP4V_O;F^2hrbrBMj zO?IV5$Hqp4#}t*Nhet-I$;hf$^}6Vtz+THh8Hq#XlP|aw;G0QGLwync9tf-xLSP0X zqeY}JCL$tPN>;|I7YD@}&zMfxvTDhpJkFu=$#p5#it2K_Vnt;_CS@BD5s~5WVLD+= zt(cUj#rI=9VBNukXy|-$U=81eGRn&!Nw7HJ8WmYAfjB^04z-xkYF4_4o>f9wTt39S zN6IH>T=Msiz|(0N8F=QxnCR@R$m^7VsED|%{DRE*Sd<>$yIcmYL%d|xi239um;3{+ z`T^*UbPnq#C=3r@3uA!9U~r+)vEV#=9NmBkMeC+yRB-@bD)fpRDa138BZc^@(nH56 zJv22A%I#^AF}gUw$HXVPt3Lbkn{}UmRAO1iDQ8!(;KUTOl3syg|EzM;N5cP418fGl zbbZswM->3DZgd66?NI{&c98t5PAFH#01)a1`Q%g#V3>Sz=f}(@cWQKoZuVxALsIyY zWs{E>0kDV6a1GhykkmYMHaUs_49X^lM<8`F@h{6J9|rzcBHbt}yiYbc3$R?;=(5S- zIWb~3`QyOO=l$>9rOfD8+TkYUPdHG#ZJp+EqkfL2v7 zfPi2C6Q#uRSqPd}rNU2wtmp=mAr8kT)VbxQ1Hu79WjKH1PpqE0U|2le&k?)=EVH}v0wnZgVs(R9YE>)PbnH;*^}%KPC#)QlKuZLi3V80 zT4(p13UHK9lF3U)6Av(!_Kybu;NJIK01JWuZ1~~8XO+>304fL|rw#?wG{B(%7Ua-t zLl6K?&oCvr@P9FUiVi{neZv5wKNrA-DBW=90?tx_0!x|IQ#coZ0sxP9F2Ifg_xqj; z7#sjVCk6Th00y56=nViot#bi~s1NR~P$zxjEggMBqw&VZCZoTMjg7|}jWf{G z(PC)+AYKpqk$$1kwe^flr%azQbJl?G{|$3HYu3z}&!h0Qk%6vO&!==o5~Zo0M$^(8 zKbd@-OTmv=Iej7(1lPoQbY(P#j?v^fk0Tz@bf>>P&BPF*@S_u^p%qO_-*o2u$CVHN z?9rYXrccrVnzrGTxl12kKB+LDIq?ZPK+`drKJUFJkWb3Ke}WFs=sM$PELiy@@=4hb zGaq{jK)&(Jg{z)OKKXFN^N-sB8eP|T)}l2}CZFv3;c+_v@=azhTKk0Zp#w8a4IXD1 zJ|+2&)&UyzaWXCH($+Vfv*@!Y9Y0BSZ5Xu%Xf%eFuAYG*ody>}cf#zaA^#CNKtq`u z6DHLQl~>z?b_nu3`88?{K$?m1l;>X%Ke@>M9J+oS-4vkInHT0QgyTa``5I*h7`r!wgS#xSZ5Xc>I`C}ekL-w^vHTG`@T}#J)PZL%e}oP^d->Gkc*srZe?k7R9ZSvylcZwEJt6Y{Z@#}8^0%MqCHo$2N;SNk!t-zDtIJmGIsn(+UE8;A z*?Ih#bVT;aj0yVMgF8Ui9Y6KOSKnN=94^RPU%2Q!)xZ1xw0rU3mFdQMT7%wA>Dv0n zQ)j+7_iu2`ed(pY&0qfI)0V8_ck|^b;|9+F+W(E8FlowEbWNEy^Oa?N{@wVe+7sEw zvrP2|DFCGo>*^aAj-xK)DK9N~R`N;jSEg!G0NVd6xBpr?22W@IuUT)EZ_G5&8xEaN zzW+Rh_YckTWy@ZgWH4v~`oJL1Sbq0=f1hfoJ!l2=cHkMyCqJ71oRQ97DF2h!pC7N& z_e0vfL#KXw*5hBbaHjEK5766*XDxsAn}4nRHH&8brQ=`w*ULB29sCIFF@R@1|7#b` z{{LG3XMged$K?OD_BW>gG5!CQ{&&p&#_Vs*{)T=5c-H%$vGq5${>Ikd*!t^v;TrJE znEyff2hR-uBFFsinExH~zhnM)fZOf49rM3q{&(#8Gxq$|96o#U(y{%=*#2W||1q}z z=-F@#_+@PWF}D90+kcGhKc0N2p_#+j{$p(aG4lT7iO>INHa;jFUH->kD*q{*zZ!D* zB+5S;UjI+w{Mpdr$&vHFp8WjXFyhIT3uZw6+tB+z?8(m`4kw;`Z{GA_^ZzjA`O8%s zb{zT-`lqCy+GTO-KZkZ~ShaNSlwtE9G3EKwcUGw{-rT$wtE;3sjyzo;i2kf`yBo?zM2iyty+c zkB0>8VayM{8U8ruuZKCBt*)9ibH?;3rbc=i643kVA9dg{&YzEbQXL&or@kXT?C4Qf m(0N2{9UUFrr+WcM_~`iX%2#Rvor8pw?5BQFeETaK?*0!qeh%~i literal 0 HcmV?d00001 diff --git a/packaging/macosx/Resources/EPSI.icns b/packaging/macosx/Resources/EPSI.icns new file mode 100644 index 0000000000000000000000000000000000000000..4b9a1893fc27a915e8c06427adf51605949968cb GIT binary patch literal 45195 zcmeHw2S8L;7WSJNIwFWY))Y6p#+VpeVzODYiJMr`HQB^8TU6{_SCsdr(W@dNiqaGi z1O%jqDpi_PY0?A+ry$G>Q-t@Q`-aX?Y@7Z6pQj|uyZ4lP?zv~~`_8$~om=)E!mwcL zore~`gJE>GE{27~$47?;U$N$3Iv1*{%I_6s`J828djIjcb?b)f<&c}n8B9$7_zjPs zAUo&4*pM(=0vk8S;%;GKQAugu1zTqhf$0Yd_{|S18*1(qW;?^j8zNy#LBhkP2lwy$ z!p9J?q&7j?EaEpd1)-1ak~L@Q1KOTNeSL5Tl=gF(4rmDP1HKuD>MMZbhv-4GBx?Gf1P?(Zg5Tlx>HSU#FRrhPE zy2s@Iu$lL;p#FbjOo!gxvkSv$Iv6%}6S}s3h;?0GlhoC@P4)S#K=qjU-Zf|LGqR-B*d$(lr`uxT}QY3Vqn^P@P?J>jbs(bfJiVN~{veJ{nd|dx&iy37$R##V5l$93U&AXF))AQnDOKj5S z@0JFp-%d?UOHWTry`6mf4>#Xi(=D*czk2&z2)^WX-NV(!>747uuypSWyqnX_u_-^~ z2L+|)-i}JTX65MYdLcYJ@cd&z=yWbN^~Wst;7IGRv}|t+`!g=CxAH?>_@cU7i#gb| z^_I?O%}={~Uvzakcj1zIbWx1mzU>Dco!(|+y3;0O2{je>O7E5975e4(%1Tqc&CSek zM|*Qjvq03;)YwQgjC)XDQ(2G_aVtF7@A5}njCQw$Xu=x}ns^QMwN>}ffKqO(;9?qu ztq+@t1m zm87&?Sl!lEi<5e-O^uaJk3>RIHMGzwNnFN|w+ri8q;_YC@KMX7I=D@*B;|yRCTL)j zTKT-TM{N&K-wKi`r-^D=B<*nu-bR-+!c9gcsZii@n&ciZNGWRzQWh})aGZ3>LuZ9Z8x9G5aHrdxw#gbtenY&`8h7 zO#L7c8_I`E2m0`R__~2POndxb1-9G%gpTEbgs{x_@-fkW~ z{(*m_b^Gvdg<;`$3NjNiLe5|D_6vx=)8oUNa=gRi&c@uid&9-u^V;=m=wy)JwE2HZ&Q+06s*7hbxzR3hwZK1PCTWuQ!1}c zX=`V`Jc*&Rc*XXzwk{{ut0ci!9?M#O&}1+%tv%8{UX07=a^WXTOo#T`R$;Fr6LPwu zbrpf>(q?|)(B9V8&zC#4;h3J*YhUdxmGyIHGTKna$;9RPJd8URat(oq!7Y%S47r4ciAMqq<|>YD=5g%%gKuC3dk;b zchU+nvhQYRB&TI&=jEk#JF`9SZb40bb=m#=q_m9e-2AK_XSQ$5EGUgHu6dA~n3|E5 zQ;^#mkS!t;l42qy z9_ZJp4am>mm#KhU(=Q;m?;edW_YKHT?8~H7et*oDRgrl&wd>S?T_^0r=D*+PTBMEc z^}X~`$j3cbhw{eMzK!s^VK(f^`drbI`gEYb{_bb@`ZS_n`*fg9j2h6`zXR>n6gBO= z9B8lJR@dIsf%ZyNyGW^~OVnhQlEzC`d{CgKo%GbCI?ym|%7F2ydJA6f9_7>=b@Z)E zhHrngbolnxWn=9s3k+f3|7YwoMXmp}_l(cjv$$Z;RTw|N+ds7DE?zqL`pdZPc8tzY zbJ3~hojcIehLH{%qp#ZhrPUhzBii5Bp2uhbB}9=?A^Nh)&dNwlNs0@*?sJJahfQ^9 zxLp^5U#2&T9=B^JYb$7TMaXY^( zF#kq{g{{4lv&)5x?s3_Pe#9MRZR}AS?B#E-HKd-)yi*X9lp1xd)ZE72(b>iI;-&b! zhDXEP)YK^_}O+eC-qxmt8R?#jsDO9I3=Um+`B^0Cun`gn!qAB5o753@|x1zMr zNc+7fW3v<8lR1_)c8<>HTrVURXNEf3Iy#>7iMVNIiM{sirmZ^C_`+-hQP@;b04-aXc{v!Jb>I$%zQ{RPvP+%*0{wzY@&E{cPa2k9VCPR=TCzNwTC<>&Ry87 zLMMt%#l4cEdm+%}jFc%P1e*L7?~~Ocyx9PCL8_pgf7LD2K}NLTA|0WyEoOfXJk=2o z^_$^=Po+#vB=k6^V788X^r%IWyDz?tU&j*(ae*Emb`$UnS6x*fi@GR@HoTP~sX2BN zC+UwXAL2rNcu1rk59?|g|3FPU)LZT&> zwq4-VHW4JFs=T#@Kx$FXiu`2Mqmz(mOGR0DwX8^jlUn=&DQE@CYoSg}!W1N>6PM~p zqz%nEa%t^7g4DWK2}s(bR$QcsIz39G`Vdm>_Ub#;?d=V91Zmj$09MD{npX6LDR|fh zUFc^>8QzXdHQFVz@`qefPhMQ5YL;XIgEJ&krq$jqmCB1AnUlJmw}q{shp0UZ=G2jt z%ixJpqg^V$E3qJT{%B}Jjq*D{=LnCLgp97dD}{zoL0cO<6DxA42DV&7CV!kSGAHS^ zVeLd4y;Ye@H4qA>oc_49mP=~Ne5$2lG2TXdoTs8ekAsSbSsYT6?|DZqk>Fx_TL-k! z9Z4le!H_>rtzwdzf;jggg%pQY8fpYB2qjCQuM~&hN=u9N^-gJ3;Lywvi#t^!S&xmB zN_cX8tgO17nDap10Z*uSyQWksk#wrG<-kKKq15Ok$=HjvzD4vkDD z6K=zUHHpRz_Uc3=s=ExCtm`hPlMQ!S@U)A|=`utQUCpVROzI{L-NVjZA~7^7c6pIi z0sAg956`9N6@`V6dpgijDbX_h=Dik}d8f$DBP ztlaMSIeW*R9Y3E8zJ4S0W=MEsL`+O<+#hj&#K))h2GFf%qGNsCBSS5(#CxB=>3sg; z70;`F0YOQ90_cw+_q<(-;xdXV!;2#BJG;4icwh4m3`)7vCxHGK(3Ej0C$}Uq?M^~) zCF*nMJL< zW{7)3MbLJ8t!uS{mZ2l4EOgwzO*feoJn9ocYpNdfMo?YZ-Ra+Qw|(*E=11xysD3+d z@!!t;XUEqomQ+Ac8yrFn#R};+3)4^U{bk+qzvYWtAc$%Yh@lf?smG`1b-MhrZsl7q z-ROWI)Eh%loJBEoqC|e?@+FzGPq&)t4$B%O%P`)=Zk9OJ`xaucb+;EP~fhQVQ_8lLMGg|M+U|e#Ps0baZT7Tq5EGIzgxW{Nmz)@zr=d#%(6*h+3jf zzqSVL`+y~aflr%(Lchf+oFyXVPO|GT!du`Caa6DmHl?8 zPZeLQUvPY-_Rjq`sr>_NXTJd3y-6K5z;^Fa#{%rA11uq-58A&%d`;?#uSC1Xe{=gf z%ILa-!UJ_FJP@+5`Y+9zGvJyvLk|NmOzlPcR@gM?YK;7tF$96mZgq$mDc(R=OF%O? zqP9QT@(oQbfyM##{mDmz2sCtl#!Xp~L-Z$G2NH~%n>kcp>iz%;G~;D}8Vq;!C!kGy z@6K?&p{<`vqv+pn(9l131pXut^v=VC#o-P2E1HI69vh)Q>7?6dqG{tt>>oP`N(#EKQS?uksnOjV+<#>LiL;)t|Ln2;!_9Hx zn0@L^Va+pUpW)5(jP@}&J_394cHel2jr;9hdF3!yMb)M0ed05w`|8TC*AH`j z``Mcly1y_`n5OGbnm%Kg>!qoNs_b2NOsCP+=0JMVB0b-CI}f9L$iH?XLZ~^zY%!vY zTgoiK0L{}agzSBOUS4ia4xT+Z3myldzA7a-0SXdBZwB~XyB>UFR|-ZeE9aDHl$OCC zW{FmDaZwSF;rTNWS$1|7MV6MDk`Nmm5gHQU>+RuwE#T86%%YrLR$h*m;iXs!UQ914 zEF=nMs)Qk;j0`B{N{Wk#3=IzO^S*N7VkA2es)H&xqf7ie}HWg;3~ zYI0&+On6AZH4nG*PCg+U{=jTTpg=Z^3Jdc0a)(;CkelDdVYWbll`;E?$ffK~iAVwS zMcfSVzU<;;>mC=nAr`Z%Br33Sq73UMAqr+7t#XmgGc(guljEZ!g8V!#INDf7CWLH= z!R!Z8;9&1wl8p3}#MsEt>z;0Bt=VpwKoX5PP$YPnPHAaL2{p3=X_6A6!-9O=&f2h; z#Xz$@3UlnDAxg(nG=-2<>o%7$cu;bDWU#OMS!Hxo55P2cnC#lUdk?<%vwi#b zoisgl`m`C26HF$H&EcAxTUuG$*xK6J+dDWoI-PYs=i+kS)%60Ty4){c@$m5U^ooHQ zNQ?>fzjDr+bt1l+VtO6>X2-7GCOav{d-okaeBj`r!$*#uICbi@nHl^r*=(*kn`3DW zyzT6Pv5GS=c2hBq&dN+nj*STLbg^Zgyvd`ue(R6vY&S7EL@-$_HqQCRau**Q6}&DdPa^RD(tW5kux_Z;X8TrVPZqqDNoQ(^qxu6C^BKCNAB{V>MwCR;t& zB)!ATgGqkWS$Y2W36IJSlB^9Rm`-vsn2i|PsThIzuI#N=dU!1%-c zuQ+l}Sdl%9uVLS9HQC}pwjSTUYxkagyS+)d`TheJmE^TFvWRt(TSUsO98?P1*!4B+ zg)YW%05pLKA_6^}xhFVeFXyY+S{3J$JNN9_cVG{2wmNk5WE*)ipG-P(^2oW85=VQA zvvq&Y-BT6^3E0fkgvcN-7fVx9oYd)2+6U97Sa&qm;q@!Mw|S9r>w|}VI!LcDQkfUx zZgu0&KU2HY+_-pU>M#MmFIH4d!Zx%#F>|!mKb^ciX;0N zx0m&X%P@gEH+ykN1HX$TX?+lJJ$WKTNRTV*u9!NJWC+WupP5nkQMpAzaWPc9r6)uN zTsg}!Hw<0np@JjQbO z^LJyPW?5bja^@llUDocm4naauK~8#7RFIdm<*9=^fBWIPZ@>QfoAuxQ`12;hJsw0{ z!e(#Tv2**Dty{t7J9q9ouzSzpqm&5KQzwrfKXHn{Ss$9=94du)8ogE9c3QVJ$~|(8P4KzokD=L-m<~Do>m9IFIGcTV^w&iAr4e+^q0lw%7 zN8D+gqa%Ee!C#0mp-a4h&;bbXx&^hhH8oJ!UR6;6TIOe`CB=jXU-$9yynF?|H{grT z-Tk7Q>jm&=7ncAhZwzmAY;XWN8Y(lH0ECbyEhz*olVYR7LV^OB0fvE4UgGEL0h0l>otdf0Nr{OGMB;cj?hqRj6&`joDA50! zkDoVY-DKTp*FeBz;I$KKkdmdP;BGmpO<_7KO+O_mF)lh1Him(I(BBqh*mU(bruvtG z@4$8v?Ln#C(6}rr_Yof(6@D}Dx;IAS@$5i|br+F75LLlMLq$$;5nhPFK6E_V6T$g` zG}xuV4iwBlG~4m4o2;NB9|H@59ja%7*~@_nb~&)Wqc$u+lbMl{1pC1-Z;ai{;6eJ) zif7ei*+r%SNr7tcj;R!(YNvxXI=Mgwd#{*CZ_KLMnrGQ$(JQA0xzm&`NuVG|qN-zo zAR*Qpvw{BHCXH$zFP}0tP|@mD>QNp%nQ~wl7%W({!G??tA_ET+*z&EL**uL3%K%e< z4%Eaz$^oZLj)5mm0;7XLRD@l0X(?a?AhT*Fc-j@`%`cn!@p$Zkl;FcEN-!p66p)w( zP6TByG=ad9Z`rKPYqZ(*>-K}81dlb48d6KJ0?igTli`gqMK(f9ffm2`sEG-ymH;Y34V8YkNzqh* zcZe8p@H3+N>`V~B@eBbA22A7giDp<7DpJFGSgbJ6ZljifEn6)h zA+?z;^u1u)15VDb@ zHiIP$p+2FZzPCSgw-uYWY1}k1*%Dw)(hCD%9@x|zpi?*KunyH9!W_g$SYZ--F{@28 zeUHg@PO&vfYjh=A%tb69&;^BHq7VUIuZiMfbu~DV#1=}0w8{^en3$KR0YR$`6C|Kw zFr7aAHK_jJKB)djBC!4l5uJsU39_=`2`Mp5B4LYZjs>7$wRau6l?$>op>z$7Ng?;bVaYcD zNt-pC0g{MwaFUjqLP(fmT40G4$td;660$)Kt3M6ah@{v`wIoGVHFZe|)D#8stVw-- znD@=3`0%)tyh^@#3lpqI?~#PW*usdSFXHZ40Y^d?cq(j3ny`e(*2;+T^$N%rae#yn zQm#)2zX6I?LS`@JN@&&oE~JLI{QBjRu08_LpT?uQuw)FWR3@_qOVQF|FOZB%*Nj#U zl$QW2fdCB?7`0eJ2d0D;n(anvw73+sLJu5zXn-l2o1ufqMrH-I5;ULkizL0yg^xoA z2$O`6fqFm(p&f9bxi?%QY1gkap%sHhIyA!K7s?%E=2E)&ya-wg*z8s|)e7Q)P(aA- zWgID8=qSDftamrFDPmlRp;kUi4s~a8xwQk8Z3jrb!fa)?v7rg0 zS{&u(GP;l}zDP18NBzYdpdwme96W`SoFk))Z3JM1tgVH(nA^sJPy^g}gyIaU5tQ0h zxsePd%ThoKdE2=Gl>2icIFl)6unTiVMB14cU%o0X^XCQo^PbYf`%| z=+IBcgNj?ssV*wxT0sYGxk4WGi+PriMe4~Ka=lOdx`i8BBE)4DQlu|N&77^$QDIzy z|G47-%hH^CWcTLpOjy2|)vYY(We$sw@{eW*rM<#XUK-@UHa$UDxm-^vs%wSmvjB-i zR~L?w-l6P(vK;uYvI7+}(v=D&TcIawX{aixs%sLq!k`ElCTD^lVaU@UAh94ZEkT~m zKht5av;nJ{%eW}yQ1_hSp0&b~x<{=bzDtLL(u%snmZCd!erKm^haGi~3p_Ej8u?7P zXAAcbH;{!w1>d66nYw2V_i)ucfpzEEu6tZ?DkM}9UIVt3vP*_NF_Ma z=>&9^aEIM>$GPVYQ>LPFq3&2f9~d*m`9h~7@Uc*sgCokQJC`~gs5@LaO?Bfk+^~i& zT)B$G13p`UAU5@xCLp~!?cs)ng4NZ5AU&x&=3rZD>;g7P>m)CC+CevS@DZ#DLB@Um z;M6Buj9JEcA`qEXrcEKpuo+{PXcQNr?R$YvUVc8>yk}?QSrY*|OoI(C+QWwg`1yET z?n03PekO*&bk%~$>~cVonZtv@h_FA5j3XGC7=w`q0M7#<;XeyTp1M~B@&f#E{1}BD zQ}C>vJ?^j!p0+8_1EG)zi1qaH_POTk=jZPq5Ev935^^&%G)X;-yzk(lgWY^jpEgAR zG6Ar(rL`4sw?mKdj!uAKAxNl)udo00fI!6eW|Dds*+6Tus<;jTBkwu5=Nf{M&3#$q${G(A+ph-pNDblk zc9#`oloL{u8vQ_iL!!vL5A421cGSTc$~EOIKay;$tpya>;fj)MscR+4cQ5>hPM8898<<6w+H)OCNrm%81sRDH?#r06Yfx}-NXjrM zvWheF03cK+5of1UI9ozS7L(}&mvyD0!riTlGeWw%J)vjDQieg1wSct`+0leIeAIY- zAFw`q$}F&hydF(<6h&Th=5p=afwd#$483LsCsR#Z%5W(1E?^BPa>QPLvQxx|7hkkF zSY{y_MO$wj8wDaU}cGQg2N zU6IBV>ps@#);M)I9GPORn!)2o{78kHxs5e}TSmlt5Nz{{5;FOmd>Gbg!{Nxg_V4m0 zTTYtn-GAWVL1680;xx`=bNOVg6_e#6CKJzfYuz=6U=di&U8^o_I2@T`El*EKOiE66 z@J0R=df>!ptZNB(Wsz5{z9r?Yn-82$K(BganT1i_>-aBMaQ&W<@a*x16EuRf+x z#ZZ;i(?^9P??%i~B920j5qPYUL1D)>wmm7n-X-Ma)jf>BptMop$k+m6q0T#tm#$c` zY+*(g2Owl-E|JH~Ckimg+%f4;deO`|P^PpAizi8O=MwEl21LWT#z$uMcp z9Zt3fT(}!fo?ELz@kaqCTLKFGJmBOm0CNa9xn%RkU-JjS$vsFSI<=*v4o=RSziFzs zIyf1eaTqu`XYIUIh8{!0$rQ*wB%EBg7{lg%82p5AGWHFQ(e0lEPPX84nlV!x!+sqB zPNtytesJ<-DC7CCc^EiZHNsvv*+QVr=O-9q*sCSO;K|@F5RV4q$(3_4%pifo=Z*qT zwgLzmAV$Excq=hX!;1x2G7iAG20~2%YS#c*vk_7XUD!9}0!Z89;vO)0D~2&lg=IN; z6s(J@#ge-a;T|j*v%xW4{f}OKebIuy{KLF~2`DtegL^>e!B8>-j$gLf0PJQM3h!Qc z<+OLW?`3PI$$|x`2*OqmC4d|X0O@75OelbNE=-LLW9|Cs>rel=YSrvHWy68W zkjUr;m5m$U#4z1+wmWug`T6^=R)4f&`IKLW1DAmify4({5#@!NH) zK3Mj~FD|d&#FvPaN94^{4ggfcmZ3EBXM@J(%(!AbMKm zY>=GO_C|o!{)2mW{Px4wYd(H|$-+7FM}nlM3*Up+-TAk*LHd8Y$@a|~H+=EwNAE3O zFlT-f7nJUSn$>~RKjYYB7J$=*fA!t->#rNX`)bX{A1r-q{+v0b!=luf6)fYQaPg$J zw(T3wZus~5uhy*k$Gh(=m^a5Lsugk_!{gO0TQ+%b9OtDe*Yc@OAeZG3t$`wl& z{`Hkv#=AxXTnop!2m4H!UC9<3IlpDSdez4tz6VOrn=^glwDgexY~geoFfYszVZ5NKsj-|o+h2H``#wjiET&C zJre786O9aXwHP!TOhZR^vKs)-YT@v4`+qt(amplPBLjUMO@=+D zsWEX{h&pK8T52GX{Cmen1EcW<`np;gbm$AGLSA{7ryeKQUA^}cZCzb$O%1vuywAXR z?mI671g!=$*J)jOcp+U=gF$z~wCDye{q6lF8wbGWIDqRMsb=HS!?Q7(Gp4OG`ISYh zK7Ma#7@bkO=}w&c<_Bvx9$0>45Z2CUT>gu( z6E=>fGjYy>_dfmJWd8!+fv7v9^^;$wI#PXR&tJZ3{T9<7{{a9z2Qc<-0Nx4kTZZ)O z^>Z9B1G?_SS@V~D^7W=e_##5Ur1}lS;_18AF0jW882Xdvpsv5}<9_qe09>9SbN+CJ zEoMm5G?@DGf_GPa{p()No`tRhKzc^{Tc6Ucu?Y;_2{T?>_};2-e%;GHyx`~{$ez*q z&$Z(%u?ci-gDJCLf9LO?ZP>J*b8z9#!2mw}^oOsTW5x_^gNZXDA2%-#0Z zuEBUdqjbqi1`C@+*U%k5X~rw_7k}`tuYWQzHT&Y7Q&}w*0H*hc_h%k^?`4ceXK3mg z7*Cz`>ilw%Ywx#{<&uTZ~G4Z z`u_XJ)IST0dV=`h>zY}@b=ObD_5=k zdi{oPRxMfn6?2F@z==tHE$;AIK$7m@*lVw_STYi+3RN(T^fJ;*w#{>o*RQbK}3_KPkS z_ap?Y6*M{EnNRa$@!Sd=PJ@Lci&Pg-2gEn}3IqMB`@M6albdT>BV0X&BeWzKk}F;t|dqSEs4 zfu-eTBi4xbFD=KQvK*2EPg+`zSFpws0{^240nMv`??Wa#VDk0Qu<-DRh{(vO=xBId zNNikud_qDZk))rToC0r+g=63unVCe^%xrYj9sH{R6>$x&DaWoc{f(|)4*(QCBt(@p z2#<`!quvF+F;JPB0DqGJSWJP#=kO*^;F*=BIzA69bJeE;G_Lyl2Lq3_NVA*alxFb} zp^;G$(MhQ(anZmsBQvF&D`MNrH4kweA{F56e=QSI0i6+nvg~18W7NJl{%45?yNU2ChlBLl-Y+>-K z(F5CVgF?yQ5cTBmQ+#EifWSk+Vm8?k8yuY3LFU$wyx5319;r-7q4Z5cR_!rs7h^ns z>d={hF3w>n#S?@$$A^T5%gLffvMMYhEUmdY1#ym}Oxuq$asoVm+%TB{ZIv-vMR?1~ zY+s7?&74j$rViNfG3(hd0ZH*g0Sn^P*1LCN(l=MiOZ?vb&wtDNyrow zV>QzU@X*lp

9=KUfz*0a;{6N@R3&SZGvXXF1q6%7VQS{_YQ~cXN{*%r+m3<$)P&Vq3X%CDb~uWGQ50c zMO+5u8}J^sPzwg~1R)BcmaBM#sb_bc^U(k<^4D z=Pn*q9>AMQy`n%0`Aif@A^)n1&{3)g4Z(C68KcVsd_sJxz54U7)_?oO$HnHQoHBMf z3r%yIRJ#ZK|MK@ z0~n^B-0>-^$sHOTLCxN3awrOawrcVbGXS$IE zVSo&aL{MSM5*k5WrAQ!vRDiH689+cXfQd?C`78v@ca_3Vf~x3xR3Q$>Cc10OO9rF^ zM5=TESHR#yscRo#f5__cK^cLOtIMAuC4j2S|3}gRBNv@NeL7&W`gFi(O3_D=4Ctw1 z|1Tv2xBxA8)tx{0WB?(aFgO=5a_##6HMxL3RqZxX?Po~^2uGO;P+#f(5qSUy=__^AM%UCaFrG4f#;n-`-v2ku$Jw)I z&6YDkF%b73P8T$tVOGzNj~{_js4V~?*Ko?rmnF|GvOkB8 zpGG$YsC4G#`HSHA&~v^=VfT1_>bcK9(q%LXXuvn_yPtjgLgbG|ffp)&6bigp`6CCS7c7571zxoLkra60@<&kM z#mlF@j)&Zo{uksAtAI-W`WLhQy944dTe24!|GLGKq;kkTVORWz`t28b$$vnbQZ)~! z)c4==mAenZwQu*1t=o2;cp-|&Kb$pmfXef_G?qd4W0qj{%_Khsnj)X*6Z)W zzwG`(F8L?3jdceZfZG4+>gkU|mx0lgSC>AI{jb^qTzP$}Is>5nziRuhq4k{h|7yjP z6>rZn(isk&P(A;=u<^^6zdA{8&;;~>L0+)@&JX`ORbO+^3g}hf1u+rR z^*nG5_+>2qp!$OshJTS`@pml#j>X@x_&Xr%_Iw{m0n;V{HHN>^lwh9LDw^WBZSh_aD!E{ztv@!QIi-fBdQP zpTqg9A%{<*`lI3P{~XSr4K1D=x&G_f&)*Fro?NwX2GqX|z5m0W{rur@;>i!^Pan4a z4^y4LT)lDU;s2n2O8U87W~cvic<08|%jQiPw*C=Qoj-kl^@g7}Z~OguUfVYRykYhG z3udV)!0o#SRh_?Gu)~#E+dew)^7R;S&F#NGV)%oLD^X4yHwD|d6 zix$qGH*4~ED8L@Z{otM9Pjmiyn4{UtWT9;t%ru{E`{w6ve^1svg}nkc6yN^FhEM+o{~Ip$ literal 0 HcmV?d00001 diff --git a/packaging/macosx/Resources/Inkscape.icns b/packaging/macosx/Resources/Inkscape.icns new file mode 100644 index 0000000000000000000000000000000000000000..f177047c07fd81ec960f11ebd03967d4f8f1596e GIT binary patch literal 51289 zcmeHw2UrwW_x_#P$`*EkrT5-Jir5fQQN)T3Y$&!>RIJzwGYbgzUSmtt*s!FU#Ay6d zO>9X_{E}GH6QgJnMcVHC&zWUmK|m4o`~RND$%8vH_ultC_uO;OEpsxHF?#Y0Le30M z>fGC#5K2n;gCRt4lMrzW2cmEoLmU+6NDDzU8BgygUn>Vuza2a#;ASRExLfyB^S>SB z&K)dle>e5=Y{TKn+4|Ifvfn>i)UISih3N0_V}g4hoR<8wXtnYau28V_1B2w(8*$3{ znN!{MLvFeo-rV28Fk*l`_uei-183C%=g2R)Cnc(q1;o9gf^^_YNH+X&+&v2Z1RQr$ z0>3JbD{<$ziVhrSF#Yv`b4afc8uP_VI0FM^TGJeN9m;s9IKxyGSK{H$-6I|TEg|+l z-m7BH7(FSP5V}$iRkuwi%4?=G{#OAk<~P33E6Pq2a{jjQrowQVsP2&qCw_pNa9qIq zH_n~Bc8kAM96b%cO2hjnPVv{OJE!5sxhrQ+@Z}YT+vniq`uitO-o*5acduR3D{udG z_Aeezao13Ex2VW)?Zl~*eDcw|9LF8~>)Oc^cTW=n$=ux{gW=?r6F*#s`d#4e8sN@f z*G`-$x&s;DlH=}jcdnc`b@_CQA5$SiW`7^ z_pagG`4hJwrKnJe$=q#n?%Gkng?f?;*E#OXbLTEVM!Y1T8~y2XSC1MDMd$GPhQV-K zaTSsccdo)Exp4RH>2v3fLiTIdi@t;#MFz#y>mVbizsubuqniT#;5m$Limo)OY&bhyUnL!sHW&&k3ibMm3cX&RmYNFaW{qWM%;c2?G!m>gGU%g@|#^>M*8z5Pireh0qWsm_X@PLCtd=~y6 zU1=Lg909y<)7$Mk{)HD!H_Xga645fzP z6i5fV!VEX>7Z&?IOv9R^yoD9z6^7skCA`oE?iSDo7mI_FQ_>6uyg+gJ27B=(6AiX0L${HdKRi({?J%~3O%+w)}W#c z4z^rh_OQ6bV5l^o;#>Ng_mL6QSdmf+aI=)E?NUmDP5J>NC=PyDQd06TC50`082sQtbqZg>2L8#I6ctH` zS_-L+SX*23ZGmOF#fFo03rCTC>$AxwW*o_z*qd~W_GuJ9;&^*|laP=Q^4e>!5%7w2 z@?(9#0TP`~M;sjNNso4cWNYpua$u9LlDikl9@CYirwy*Rd~KZ|x0ja}&%a{D3i9>W zUz1;c`GuT6f4)vRzWeSwa^b=SlAhe2Y|WckgPYYRl3wkD$p;^N@I?H`jdtzs?oKi? zGRUr7yZHKl_~D17W5p=q{vp zk8V|YO=ar(MQ*e;XJ=;;5D-8zGc!qcb~fMF=g*(d+u*8ItH|Zcm&wkZJ4sSf64|_Y zGZ~Z86?CmNa%Wd_BY%99_Y<`{a=W^^@_&|=mc-uPp0sY=n#9J&lDN1y;^X5(G#U-* z+_^K)>*?vq+h$y}KUue66gjXF>RpR_%AocnYsU1))*ZRAe>plj^1oPr#l z1AosX56XtTCjDR=1$euXyv%;&)pd&=;YPjpj&H%YUvzXd-==lRfcKEk#>R%{$6wSj z%F>WLE=~?)_Q*uCXU)7ixkvVjA>F$tkr^{)klC|mlko6xUUqXCaO^-X)GOLM)(Pv6 zeir}GpP0*oY4~RgWybbxM|LfrSts|@!Eq!gz?byt(}#>6J(|p#HH-g4dv4RFO;tOj zr>7IKSj^WmEG&%p`T6l}h5A5#Y~Iw#Ac;+!Ks_4E2qF^G0?io-Xzz zC@6@x+5Y|elX2t5k$Lmxkr5+C@VZ7nfOW@%q9`H~iFjKI4Grb{9NHGPJ8~(NN?t#x zBa~UksiI%B=j$M}2L^Z8BogZA2@MGMlUOBa%o zl0p&^68Jix4PgCufnURPYy)h6?BD3`Q3jL+>yG+2^}7!~I7O~qyGDNg`DfnO;`qB~ z+j>$kV<-voa^Uls+6(2zKT}^tOl<$U#^9fR`iZ>$`s-xw+_?m8A}}zJ2m}JYZE&7} zf15UKs^UI(?i@LM_%L4v$Hds!c0?wV@p?j;QD69n_mH=5-@XLqxpj^k=04%2mtNxS z0NWk)je0>jMvfdwu3x`SP|h#D_=2AU96x@Xy!F;wqz(8-%qNvfc^@T_NO(?c`$2;S z5gfZPAC6t-T(!^FuV2rXL%GrZQEzAmty;ArKm70m!Fk4+GiS(w0|y9lqrPz7f%4&; z2-^$gK)JDxVS8s~W$|;R6DLma<;};d+WeO5Ch<$C$m@)jgg)$&F*5lPzU*)-RPK4t#`f2m_LOD<#)CrE8XmjQ|iin7) zvmLNcU?0G~gZ78#s7vfKINqK*b&A&|j)#efiG06q+qNw)3(k*F9&9i4**IQx=+J@Z zNB@ImP$oQ3$ENz4ez7lNzr!(h=+L30U%!6fySwvw@jliG{Tcd5oR6SS9X4zj?^jT_ zC=YU&=1Y?%O(OgD?c=Yp5BBKMgZDYuUrn6mzsbqTe4VjAs2@}P(GIcin+}`@ELyaP z|HCn5>eQ*cJm}}qkD!l3yF?#_HiCT*%VYmD=QBS?y`vqO{4Mrbv}LSw?E}YNoO@t< zEMLByEMB~r*KyCDJ$Zd>*|LSdzi{C~e%!_Ts7Lg**avYAY0i!3>ELfnZBv`C_O+>> zA@BC>+xdAH+Bc4|*iL9`*hbj@kazIl!TgwmdRn(`9bX39+FS;d4aW!^pV3ZH7SkVI zqb~3d^v3#+CcmE?fG^_KY^U+bHcJ@i>my6!+fhjVEhquzMq z4Za=GmhcbTbkCkWypFY6E#J3sUGVwmpY!;?|NcAgBOk&}fq5POKRln*I&)&<_XCBA z6XK2CxVCBV*AC~QrYBW(rol~z%aF`*pBgg+%wJr+ABROMlZ_c`e$ulLXB5@>R~l7iakSEr|SkMTAc znjlnr^tYM_KV-ypS^M^pR>md}b>8t6n3MT&zuPgm+{LF`?t4T>6>GZmj!RF|V7lPA zc|klkoEhSM!Z4(AM4MYH+3;3B4_oWuA9mrviPgVV>DMao^shd4YPm!z5zu`7r&T5I zi&@2=f1{MkEF@x)F+=Z_Z(jVZ=*O>KN!4ij!It2U`3_QJqDg(AVu}V|DG-R%k$$2l z_2#^I8KY--!$~*5I8BEM)yfd}Z#qm~^h5E&VMjuyIvUy+5AT_M46{9^QVg2iknw%!sTgl;mVgpp+A4_ zWxO4L&Jasv7>du`T2Cm}DEyK0**ST}&j~cF$8~SrM40oXT z?ellJ>lLJ^=z396(N*PLPJiv%ozs@k8rO@iod#NXsK?9E8e}y+=cs%F015o@P|v~^ zISH=Zi7tUH+u(`^X{jhSArA|SVT(VwpmaEkmnDYMl(OQ7ENt$hqcU!M>kHu$F<`?N zcf1Sn!2w%AiaFSmh9eF3@(bDW(sJBGzo{=tWeaY?-aPxD6!ye#l@>>&{t4yEfG5RZ zU>}sE+`p+W=eMmN7V3i^mcrgK2m9ZR?7%Qr?k1fGwHeV5|Zh88f0_pBJ9@K(2cKa7_H@qmTH##D?)>1$=bNa5q_{}3W9f9hEUra+ zbZ$q?^?_?O^Zg8*v*X$p@nXXL$QIZuL|!aAqE8$@zr}eiV&Gg7*8(`dHth@GoEGPn z-tJCh<=k{A+m|mpx=(AE2e;za4a0{IC%L(~{QM5*lDKbyGUGfG=cKq#dE~$zvaMhm zUv_-|w#32Smd}H8%ygI+PM$oOU+dz059j5kwKA^t)~;Pku3o*$uf+=3IYeWn;&Blh z=YhDE{p+v4s&t6+Jk$ZootBoy>mBE$xbDOC3$7bcFSuUVyLT_awUDXZ@E6xUF)=Yb zHqK+;eDh6$^I%*9;k?ka{=+#Z&L^>LFb|f+z48GA1`wRzscWgUcubSk?c{r}i z@j&m4^IDwqM@B}H1q&ANYeihkVxK^{)~s1mXTQ92=MJy)Z@>MP;NRJ^XUY5Tzt6AD z|Ni@LeoxlKS@}DIpXXKiLz^I82-82E{^9lr2?-1_-sp%=2lvUh81D0H5B?IyD~@{= z(Ps7^%;f$|>wR3B4ZU$1dvHKmH$S~aTwIA2ak^!>{0pG}LD0KRh3 zZR3sNIWK=7L#UTbXrE=yZ6P8f@baO7D;uiuNPv-W-Oc;APj!5Q`=O(SSjdlzFeuU@ zyUJBmMi%-*Z5ynJ2?&3WaQWnKZW+15tt5YOYseqmI`SJ=KxoQFoKJq?788kV&LtSD zwt6ilKfxvCbS{UZi?alIq>pdVT&YdC0`D;t10tWgvcb9ThMOGeJ!+{=Mde6&aDXleB;VsN0wX@Y& zTd6w#y@I1&mF1F^988K8sXA7eyK2qy0wK#z5Rx}Br_9aO*~!tq$3Lq$>Y_(3S&liQ z<}j>u>86+W?s{qCntYmNy#e@j%&zeB_4e{`?|**{h}b!oEWzyJAq*>9y!XgKKL2to z&;|;;h6Pk%p}|1`{zD(E192zhl6)*+nZdB~jmN4A=%7RtlsJZosutpih{zV0hriCCPV*JC+oZz^XfM!V!-VU4(rIsG4 zQHsu@$x%)WQiO$ug$r7=m{78n6JGL_N`wqyu~aMrrB)q#!zPt(z{Z2DK6i}3C^hHlc3o4+Qk@qXtP6{9hgNxptq}=`{0kyUi{{}t3UpFtLUGH z??H=~mw`g{!(!kH6jeGxkRL z8cuq1>boVJeuQ*9Ak@&44iFaEfB*-vEfs$LzD~A|j(rZj{`QFvK00&m%WuEG_S0_v z9sib8tl}h}r;VI`e2ioqfNbW)*n^h6JYNUBrZYKW^W9P^w?T2^aQ@5sd`fTZgu1su>{7mxD|^ zlFZA;+uPGh9Xmfew_y324O@1+vhUE*H{Utt<>u}&;lEdI{PM@0zaNwupm&an5sd(> zHRf3PEER`R?L(<#o{X1`m8H+*8MEgzxdkiMY}~qI_r62NCfT^SxVlAOxb)vEHxaJ5 z?9z}`x1s$jVuWdcxVk1HJy}pGn}@xprq2-HrPGGopHCU41#wHvqY-2G~htrJ*< z>;5k;UgFL1k0n6?K@qvXLP*<5VLyOeWe!=uQa&i;t0<&}yMu>^r-Ow|?mv9gxQSD; z<}6_ImaJU6>7^O=l!Jo`fTw@>8E>ucclGi0X99&G^FOui44^AsGt(k~4yp!q6S=#4 zI9o{VEG&Feh72D)ZsOFeISbjvOINOIX=`WiVCm@C;XSnBbMt*Xy?p$c070O?G#Wsc z*8*LjhNdw}>MC|~b9a@AB^s&JyH~%IAtOeQpEPym+=aTuGi@}sl%1W_-ri~7+wXm_ zx4jUudipZ{!T^7{UpD%-W3N{?`4X1ufWq!Y4M<%mS6AB2&5{*cNj$nF_3oECbi|nP z8DmEb>KkTF+1OZWG$8ZLBS$B=fs);Q7(b!EzseasX8sXG-D&J1OIUh}z$mNKnR0Pq zTqy@RE0(*&L`Q@L`Fc27E0mO_r9h=pTM4YKZ8RcV+pa5GItU#dojrXRU!k9$#%dOz z<{mObU0T^%dw5x$C}(G#3+-wr*NG{KgqBJzXqik-DHOC)X-TP6lv+($qts$YM>~6G zcW>55=6}>?%3fIoOvz-lT&|#$N`a-NN-eRnver1d zd3x!*g+4wmqA@Tu?XC$pMNElt+5HO2DsiA39d&>zba8R8l&~l-C6&?^7BWgMrxgmN z(9+V{-j(&#c?rF}-RQvpxT6N3DBFd2c*96fb|In|Em8-VInK1LO3Iitz{rFOD|;7r zorlg-=;h@u>JCVo&5)L{bSGjZ2n_T>tQ|a-9c6E?_QBNjM)kPB^3SBaM6EO2yicG0=&0EO|O<)Ms{ zWmmptjv-v25l^4Q22h?T&sH8oL)qHus!(*$$_T-@(<_v03L1~D z77pvey3)3Su^>q9L30p`*$UgtS>P;}3}*d|DC>C?E3iV{BRGr;ZBO+D6y2-lDDrG? z(csMKfRneRKjrHy@bmLPJ6elSLN#S&CB**n2q5E3I|$mqoa&Wov=ywP4T&F}F?srI z@MOz+u)dT#Vy)(}uz!fHtTYaGwl+*HJjO}jDDuu$u%qnhu-~DhmF!s zoH}z}cFvN5wyZbpMv-M$cM5wltglp_UY-c+V5hNG>uTWAR@6{HU3v&jZ37PbD_G4! zXA+Xoy?6gXFg{G0hHbPoza{16MSFWYfW%9279|4*#3&UW{=VLT4Z#C;8XL9-IBi2E zfDPtZ9H_!x$=bFc4zclFx+f19Jbd){%;~e|LyP5xvR;%L-E%%d3&B}13bk!;5P*Am z0Jx()2(HqZ!P6Q+D9EkbV}@o{;9L(K_{NhxKnN>1}91=mReY~ijIs3 z2MSZ$qB*K_Dk%ikD$*GUmhU%N%t}@;-<8t9Mu@YgUvP`)b{$|y9RTyeag(5fGmDq< zW3!lG9T>`q7KkK~ty)G!gogzOA_cZEZ<;DbspDBxRw_X+hRuJ~jAEe|v0@w?99_Kp zf+J$uferNm8ybT)v_Q9btgFDyO#u`-l0(@`!eUxRMYaeH4h-=_4JS5N;CU;sPnGjPZVup@8-x@;KR)qtN%bd-a@E+`uD zjjikn_~;4LDkY=P0X}RmNm_n$`O?d~EBh2^C_9+Q89UbA*1^pyASAL?`;L{SG+_!f zbq?bK=sB=<26S5H8rmWp!To)(bMgMbN~M(R03Ak93#-rA%i>cz`R)qPOba4qU=Xmg zcXaa(2#abBX4Zd(>(y@%n$NUZ0~seuLUi0JXjLIC zvG)t40s>TiX!owzqF|Sn3YktWR4C+BrtY%%yDQg!{NZRGh}@0{O@ofDvxjd`c+0jO z5|aA#2csE3X_S|PBQBqGu#Et~I^5zB(X_(R$6w_O-PRNB1wDeLQqIUka=DC-`i8wM zMEGBXzyJPS;bIuH3T7W6FaxL5-zBcp|?Pua@~VEF0RKYqXQ--{pZUR=Nmx)Om3hAJEZ7>%W! zi>E)BW^8=d?tPM5y9uE|Y(>D43)>&yF0C|O4#U73f0cM^KrnQWeNUHD3yxH zZuYY3`>QvA;oF+LR-QhW^~+g2Ujou;K-QRj_m^MVDzVLZ50eD z;PPM-Ol{{#xx0g-7Ww%21~@8Ea{`%A2-S1q-H_N4sv{;7*~`{Oo?owDzVPX(<45=H z+_-wBjuj*mS_z|@(bHPk*Z^5TXn24VYeQ>PGy}s*4v~m#T-?0^{Qac9zR*wFw045c z0ZJgy3FR`C71T$mkW!JCn9H`69M`@Dj<=8O+qr4i#m^2Gh*)+2MJr&yGx{vXT4>|o z=4=m&WUNJMIXtq4p_?IMxsz8=Xjq6KG&C}XYSTv2wr#t%UKWJX0Tm@hvl3W-!d!MR z()@Dm+w-5CeEZ0&J2vgTaOOWJjxFm>Q0S21TcvbuM zF|As+?btQ3OXm*l+O`gW)?#U$0G|H9mLx@XFqfSH{pa8Q{N?I5fd1CuS9feYbm6oA zy!Yne>4d^D5c_+sing@G5u8y;loASbn0R9gCt5zSZ}+6W7OANN2lVZc5Fd!Pz)(7x z!aW#j)MeMpmw&i+6TpAI`pvnI0etWFjjx~o?DTtY9A0WcS%6jOz+Ewx;1yx&th7{0 zK{dABe*5d^Z5;jE>N(Qcv$HbCq@}dA%mKH-K=Zf$m>c!AXBE`sK|{1-U6UO90aY z9ypl*e*(adP5|Jx^(W7L`oX)e7cycZp)4$PvK%>UA(Fw)n}}9`ay6k-5551zSJ!So z*ujYn#lPMBW}clGhIQP*TT0wER3ZNG^%ozVc;gTtehi53ynbjtgdD+wL1&R8W2H1~ zJ6gfcpOt^FMN8N3*n8+dpZ)Ojozm@`u;lLV%WV}DB~z;`~Krh=HyVt0hF;27L8jbTEMb{a1kh`oULTT6gj6C#T+d?a)-f7wZ6@ zv7ki6o=Ba-;=1`;qLCdi-fs{k%E@J z$GflJ|G4?xSD*jq-PaDjvUTlOXFoo5{I!FVAoz$9iCAD@q|OkTco`VJ z`1s`UV+Y5>7CI#q>VSihxInY|g+#V)-?c}-!J{TlnZqvGwCms-Kyl@_du3ZW2~ql4 z5vkgWQQKHKxbqGfSv1rDo; z2#I}gc*}O3yCtU#8$DrWcERc`uN->w)S0iY{CXECq(tiAYysWWhP4)0Svz@p`oTEv z=_>L4s>%a@1_b+e0m0`Vz5n*n1L;738`S6=SP>8id|Beb#6ID5PL``cI?H}}3r_wU-g?&9Yk0{s4=;NmD6eM64W zMI)PA3HH@Zc0?RRAg*jHFox7 z2@hZGbT@55__vPkPi3LE=>VM-I>EZkzUP3UBgapfxgdAhx|enzdh`8H&R@Rq$3Nv; zaeC~m^z!lx3<~yEff!ONdoOtMWJ~uoLYw>AGasIK>&X6ogrX^3CA+ zeBF}On|JOzdi>3<&N2a&LpF1w*s!P;;VqbmkT7pGfLmBQO1v-OcvRcDzIkMC7XtoX z3J=vQ!C8R{mNT~LS@YQZl^eG0DeNa>pvmDmx)4YivWXLy?Mg{X=oBYy+qQMfsBj;( zFc9`)-Zpoyd#l{*D=|c31N-#w=pIN+HBjOsd{Iv}f5rNjUU}J01V$ymo<~b1xR%<) z1wSat8#ioV&!mKoacx^i2UwGWDi8ZUde{w>9(G$GQL3F`YK3beWPuO>BMVD2ltsH0 z>$mRO;t%5*BVE>K*lEkUylL)IeqP4nSjmFe;G>q4HuT6d=o-=Wo<-OD+MziT zL3mvIc5Pa>GzZ2Nqa!?sF#@9lhk?U+_1;a)6z#a7?iS0)25v1$bSS9dW=9FcZDFMD z6d%{VtvMh+OEvngQpEJL9&qg#CL8L;$^R-b4WtO zqACyj3Pk&M>C?Ms_il*Z!5keH5InjQ%#+m$n)onlx9mUU+NHi z5@I(reR$f?!9dZ^oFcYu8(d-q!(80m&59;g8TngY+nb{yGKH8Tmh1Cj>xU(Ff$7@O zBS)kG@PK~Fy?P`iCUlB#?*@%bscpcp-L>O^c@)o(TFH=vmFU%mICEg+$qT z-m=~Ao?JOWC>GkngciF=4j2Tt2`KE_rh|B?1N$X|enGt*<6_&kj){tJ%qOnXrcKS9 zG_fv5)1<|unxWAV(g-$12r^}x0}eU*!Di`b??mRDX{Qx z7r44Q;aYwhpgRTj0flr0g~YW3UE-RaU#)`W3Kx?YCVS!hd9%$aMy3x(icam?`p97t z)MYZWV*5L1&Rx9p-;G0JWyBE&N+UQ!oE$(E@t_KR9gNFJSm?Pr<0@F0Pg>^Z>Hw44EvQVaqvWoiLx%v%V7a^{@etC$MmW51&0qG zJRp7TwWF`@d1=p%h4jFIj6ka$7*8c7!MT<>$TAy1!wMn4+Q-_%=(hz1Iop;($h&Th zboJ_$%a<)J$j`IOLF6ny+M>MUlyJq#u6(DKB;ylnRlL~wOgJw+=PMDC|Gl7nZ>LqB? zW?(!6keO8GKx!b5$pGdmPyx)J>0Lx2Q&_4j#gy05ty?y2v|Ya*AVH%%X0C2xASI0L z*oF!YX2X~$9<543tUd!WBHl{w01?n4u}DHu3wCVZ_R>~*^X84B4ZMWHl`EIb8YLb% z(venc{Fz_|pkTcQ<>Tq}bgZm7)C%qxvFM!h%I;To?F1xx>(XnKyBvgGCc`(E9%`{m8c7EYOvF(IR)3|4!ODZ3h|WvP&P!j!q$ zixy-tlbI>vzBZJ=LgR%()1XZ%-Xye%lV#R`A7)_sN9`jPn&DHYOr17$+Kep4j2T%o zCie261rm)@kN{ePm-rF=VH3Km+CWsY$SLus{OCv;|J5|~YVJUei48{I%jyqgW|*GNS$LuZ5{fyBny zKZ(`qz&=^#KUnG@*upBUD9PW$+0j;FV`FRY7SsknDTetQT)kNc$WilXkmni>BDD93 zi0jlg!m*)n5WBeaJS~-skEH7l2azS{w89Cq=Vnb2YPACd4TOUPj9|3V>FkO%%kr3c znY32x0>Jf$g9sBDtt@lx_Dy{LEG!TT1?mq6k@sh`^6Xuv0+Yu>3EZVtap550W1-aSU1p_NEfozLIFAVjiDR^ig|E~o zMvsv<7!D%t3DwBmEi)F%o|iQ_L#L&>B3FaqAhHxFx757c_#7=|hvga!2eGKLT%xgD z{ox=|@KjVmZMv~I@IOg7h;#rHUtFVju9oVAtWOvYBJNjPPvZe$j0yyJ@^BDwUjWh7 z5CeJ*AL!7Ca1c>4pk&uZ8I7SAjSL47_6DRyHINo-sWzyV#)g9k!HyIQDs2zVXgnZ| zl!8o+4+jzU0IYfDSovBi0;PJ|a1cQfAkHx%&IRf6wR9@oq;Qaq06E(nvOr6@qL57q z2WbhQGb=lOHp&U0d}lO*K3zCSAb@7o0v)A*rfFI@h}#(SZ98A#Jt8mc5-k;p8fZ#5 zh%I`|%TnQY9~hce z*8mg@5;h?kq$}VpsevaNWA{|iAngE2XNI&)OGiIlG)Oog&3|PZj@Q|9L21jhg1%Ja zqCvdJDz(~KFPmcsN2wbT4PrYA0H*G&23W2Y1vM@jL^c%W4VkiS<`~kX#zuqC$sovt z%_fk{@yoRq!)1+*28johaqG-cieudU5nQnSCh$sbM=a|D<50f=H8iaHM)M*fO#M?Uxs~K(AOwk}Q zV1tt^Hkz=83HCr@@H^@DHjTyFmn`Vjz(TtL7wM)&A9lAGTG>F9zK-Za}I}H*y zZ!}0xAee7P;GC{*-e{1PKrmy&YNN$Ks|rTiH+wWl;#h6wIx~vV@IrxRjRwiQl%KK6 zj9`pgb47!QjnN=q!{$)6ipF>~V>rks5Ds#D8H`VvsQs~i%@+>x3WkGxy<=A9xK&y~ zP&0;uOsotC`R?UOAaYo9hl5-)3kSKpBNIk#c(FyZhJ$=uBOK(zO_K|>f>zBN4zjCu zILP4@nR!}4Y;%W$WYiT7vUs*mD~NBdaFB@l!a?><6KS=bn=KsVBV)iu9ZxKe%x*`T z7!9(mfoPD-CPss#Hxvz0@U+n&Uz9OANtE?jutdk_AA|+mp+No7AksEWqFlS& zRG@DXl)!+K2BJYM<1G^tle1S>mFdnTQr7tFv!Q4Zy96jTaA}QFbUgK#mxFkAg;GP8 zo0Vb{jV~T(@Z}&>Fq5bly{bkrx~sIoXb@pERAb_5nOPxSqVdstgV7+8SSUBcyj)UF zBBero)E5mx!^=S+pb864uU(LT)_;hrKO98d4vI~!U977T8tqBKK}2n#cxH{_xrtO5 ziu;7&AVM&inu$X;8?fgoF43=-?HVT0}Vkv_&=O(}jb$0O+7v zpb2O$O$!IHMK?8Y`6^?Rqp(XVo9Su8K`4KJ_@DRDXC^N}*cq8xBP`vXYGOQyMMpsG znP-N&w6eLH77rqd1>7XYgqzwo32?DTKXp6^c5nII8i0cKf+oa+!00HSRs&DeRrOTy zAc26CVTQCUk@k7Icn}XjN?%oAY+_K_vP41aM#h6UbX6uM4q0iAAxw}rA|6DQ008}$ zA;2Wd9}nUVld9R(Xe$yG?oEgXvFWNvOq^;CXBpD8co119K-3nn#@0(tT9IhgifVd1 zh@c(74$C)#wT_oGJsue%6_D6FQ7s+r-%Rl!mI?C2#2IGD4$-9f-VP$}0O%QJ=u~^5L$d~ike0xZZpPr;S>C(>A-+J6 z%9u=MWul<7y4eFl;=3j$FEpd*V%^LEA(Jjm?=i=mz_z&pLh$t<(cfJDdcoYvP6Zn3 zYTu0UAP}1%KAgq(SA=$IzIc$G7!UI0$|1=~s}cpS%@_}oQ5g^N?dskjvPUz=gG8Fg zgM70p8AfgIW{wB>utq${=_UON5(R$E8xOMmk$4cMUtXdhu({(wv~|UU%umxL3PPGI z9whwhdR`CmQi>=sF^n|V>p}igZ#+n0dSFxILAEpy4>Goi@gO4_iU-Mi2Js;5Q^kXv ztcu=v-hzEHQ5Aq@&HsK=J_7>?{ekU?-(j8p80&~BY!tz zM>!1ppQkTNEaks>S*-w$t2k%+aObnvL}F>xN5-l}C_n$a1gMjqMpH_wj=o`{Ng4y?W|Am)IKJC#UeZ2yB z)qEe>FYrmNr#l`)U$+2?#iiBVgg-m}bnK){{cUezc+>{cYJJ5Qaz23f!9K#2g{uKNPk5|4C-%Nn;AFC+MPj18eT^oBmF};}v z`kB7|Xig62D;rA=uQz_u+9Oq^1{OZ@1?WmS;FZsfJQ_uB6hO4UlI@Y74;x8NNax1X z9{I}8Yijx&b0N|i%im~v5a6ykV~z8o#!gk9g1!b}t&63NtbQ}o-?wcXf2YQ_eXZ)& zzRdsM(*FZ->Ww&>yY}$yoW>lTO6r(u*4AiauJ6IuB%b`}*xdB+n%_no%}@Umd=vPI zkLIW6`aLl@A+;0a@6h~h&vE;o zoc>`mdp-1!|2jP>e}`v5&;9(Q`vcF0-ZUwFtP`B2=UD5pG<&fNdF`P zJX89|3()>qwY_PI(y$FYbNYrg(7yN?xE)i?O~3VP;JMJ(uYuU-QG3)v-5Pjq^mPl+ z=6TiLr~!*w9?qC{CGzrsCyrv85*K_$Py#wR*<(ihxwm*AnX{ucKB zF`bfnX1x92`HEopi07wN&LOQkb?M%-N6$HL-hYlFl+WS$#nv8yk*(Tx>XOu>NB5p{ z-+Epml>cE|4ocM;C!f&hR&6_W?$WJia^Haqj{d+TJ@T0zP~W zU&BrwkUD7ah722?K5_FGC5`CIjmuhA zvA)(OEG1UhIC%Po@SkSylR9k7#A$PLUN3qkN+{>vtLym-Ew!|D@(GTBZ*X@XkT!nW zJa+N&!k?Pk5DfaV!(Hl&R}soV34sx6Q|LKfyZzpT`%4_}XkU|T^N;~iHcAZ9lpnoLDCh_7-`!pV`aa;q2*?$B!DC(mSzZyOv>rUat1m3ivd7 zgNMj&+tZtQm00>O3v#pP&76`kcI4mzy}Na49}^Mc@8#-Xt(4FW(hIGZ?7XF-$r{lAkvC)Vgs~%srS|KU)TLwl*3scX zex6UjZ|xu3wf~GOO&)pl|1Q;zP9K`uuTPJ}&K=stM1}_XcsScxDITMLOXrsGz3!pR znWj#O_2qj<3`yzVr)Rf>_}JFbpnh*RCtI}~-|E!BL0Ni4b?%j%nm*&ejV4Zm3^!)> zPwolYk82wf85ZR0oiKIB=RXyf-gtXhLr>rpp5g5h@ssEo3y%KWq;{y#AL*aewNr<7 zt)jw%yPbT<8H_z!Z}_Kc{VJd>9Q~u)ckMH9*vO12IdA>m6cH+Z9s%^N;XAaOE6mr} z`jQUy3m}x*c?GxZ01^xxnUT5ZSW}!~d2wcJ>y{A_vukzb^6mBW3nX%tBh1BOlXDMV zs6ULN7Ggb@`UffS3Fe5iwR`lD`uQoLRH4>%TXnH16|WLU|7+XGsHmH@u*&w<&krAs zb;$pt3ZSVcnGX>d#9o-!_B=-%Ir-mrVVUuDXe!IVo_KvdsELUN|;vR zA%5Nq#(3k0km0l3);4NOOQi*Tu(=-PE6+5Qw7R_h+MwvLz<}^KIPTuo*4FTKW0_om z-;fv8OHUoEF5bkm3jLuDk-@$`K?P|0WyRe@LJ=Nfk+A+LfUb$8RmJuCw+F_wfJXNV z{gUtd`m&xzmDi_vOzm6SO;q7E?nG~RZ)ocl!9MP;ZvNp##W)6a*{0&b z^)ee1>J1n)0X+U!Z}@CZY)p8tpNBKDTdQqdd;{J@1B7MwW2WBi9}oYy9EK~S+eC#1 z__#Sa;J4Y~L+X|qM~}dQTO9X!ug5HX=nIcSe_VRSgXQfaV4mmZ>|_sh=fC4FQCQhI zxq1e8s%4Lf{uuo@_{XMK42}v3@^*E`Z`~t3e48Cyja;R+R>Qdjz75_$4-owPSp3Ij zD4P}(=mYI;Z)dBqQd=tEEB0bBI2@@&0>1)*fQF+!A^JWJ-INZ!sh)|co_nvIC(jNa zyjLnLq*7o;ZV*BQ-x?Q!2q*)H@TekAnD8I-YnYRkwc~s}lfv@iMJ^f}WS7fiG7Ae7 z0cEHmLY)%$nViI9=()E$b?w%(U(SPi@)=gDRZ19S;HZ+IS_wuS)Fr^GdhlxBzSk)t zCbnabe!J_D*Kk&?1b!62$Y0qCMh%$r*KkG_PdLx~t*2jDM2ps)dT474X1X4S)vu(l zY=No zn55bhddym(KN#((s?vN7+pDU2ogGlV^tJCEv+GfQGQ-os!QS4^&eql`IBrS>I(73y z&wbe0QKP8W>MDC)jb=B$5c>AY+VqD!)^fhbRoi>bPH)au&pAbloFluBoV$A8sq-JceQ^7lytxxcbhcAgAJDvTIQoai zzI>ajfSn2hXyVSH@d37~%ARiWHt24ktAWDnA*=5;MbSc-tBJ)>5o|;$IFee2)XK@- zD`4oV{r~yw?N{>>oNbhnN*`C{dhTOM$eAih8Vwu9g`4~bH3qjA7d-b!I%tZJQp YwKixoU(@w2B$}D%1>6e_G`j}=A3#%abpQYW literal 0 HcmV?d00001 diff --git a/packaging/macosx/Resources/MenuBar.nib/classes.nib b/packaging/macosx/Resources/MenuBar.nib/classes.nib new file mode 100644 index 000000000..ea58db118 --- /dev/null +++ b/packaging/macosx/Resources/MenuBar.nib/classes.nib @@ -0,0 +1,4 @@ +{ +IBClasses = (); +IBVersion = 1; +} diff --git a/packaging/macosx/Resources/MenuBar.nib/info.nib b/packaging/macosx/Resources/MenuBar.nib/info.nib new file mode 100644 index 000000000..c0f4643ef --- /dev/null +++ b/packaging/macosx/Resources/MenuBar.nib/info.nib @@ -0,0 +1,23 @@ + + + + + IBDocumentLocation + 99 362 356 240 0 0 1280 832 + IBEditorPositions + + 187 + 340 374 240 44 0 0 1280 832 + + IBFramework Version + 349.0 + IBOpenObjects + + 187 + + IBSystem Version + 7F44 + targetFramework + IBCarbonFramework + + diff --git a/packaging/macosx/Resources/MenuBar.nib/objects.xib b/packaging/macosx/Resources/MenuBar.nib/objects.xib new file mode 100644 index 000000000..78f0a0a01 --- /dev/null +++ b/packaging/macosx/Resources/MenuBar.nib/objects.xib @@ -0,0 +1,73 @@ + + + IBCarbonFramework + + NSApplication + + + + MenuBar + + + ScriptExec + + ScriptExec + _NSAppleMenu + + + + _NSMainMenu + + + + + Window + + Window + + + TRUE + Minimize Window + m + mini + + + TRUE + Minimize All Windows + m + 1572864 + mini + + + TRUE + + + TRUE + Bring All to Front + frnt + + + TRUE + Bring in Front + 1572864 + frnt + + + _NSWindowsMenu + + + + + + + + + + + File's Owner + + MenuBar + + + 206 + diff --git a/packaging/macosx/Resources/ProgressWindow.nib/classes.nib b/packaging/macosx/Resources/ProgressWindow.nib/classes.nib new file mode 100644 index 000000000..ea58db118 --- /dev/null +++ b/packaging/macosx/Resources/ProgressWindow.nib/classes.nib @@ -0,0 +1,4 @@ +{ +IBClasses = (); +IBVersion = 1; +} diff --git a/packaging/macosx/Resources/ProgressWindow.nib/info.nib b/packaging/macosx/Resources/ProgressWindow.nib/info.nib new file mode 100644 index 000000000..4e5156002 --- /dev/null +++ b/packaging/macosx/Resources/ProgressWindow.nib/info.nib @@ -0,0 +1,18 @@ + + + + + IBDocumentLocation + 124 298 356 240 0 0 1280 832 + IBFramework Version + 349.0 + IBOpenObjects + + 180 + + IBSystem Version + 7F44 + targetFramework + IBCarbonFramework + + diff --git a/packaging/macosx/Resources/ProgressWindow.nib/objects.xib b/packaging/macosx/Resources/ProgressWindow.nib/objects.xib new file mode 100644 index 000000000..6eaacc43e --- /dev/null +++ b/packaging/macosx/Resources/ProgressWindow.nib/objects.xib @@ -0,0 +1,53 @@ + + + IBCarbonFramework + + NSApplication + + + + 404 523 457 899 + Caching Fonts... + + 0 0 53 376 + + + 19 17 32 270 + TRUE + 1 + 50 + + + 16 284 34 356 + TRUE + 1 + Cancel + quit + + + + FALSE + FALSE + FALSE + FALSE + 51 + 1 + + + + + + + + + + + + + File's Owner + + Window + + + 186 + diff --git a/packaging/macosx/Resources/SVG_plain.icns b/packaging/macosx/Resources/SVG_plain.icns new file mode 100644 index 0000000000000000000000000000000000000000..a309b25b422ed402f339a9756768543cd21b0553 GIT binary patch literal 45252 zcmeHw2S8L;7WSJNIwFcK##mC^>>6WY)R>rTVm5IT(~BmXHPsRo?A;ady=n9+f{KDt zA|OZ)U8+=RQl&`~7@PrwnPFxS?tktZ$^b(#(arw<&x;t|z4x4R@44rmci(r;eeT?{ z=O94@r|vws;uV5ma&-wJBq1RtBKVRukI*@Pr@HcXQMQjWhtNCh=^J+WtVc*_N+z4o z-xqM@+9jJafpH<>wiGdCA?H?6adBx`{(0LoJc`f{5eZxFRW;V$F3LFrx7XTQ+Y1x# zHQ&8+#~0U%C3T6?mNsEia}d7mlH9zD1ov87+rsg!T-qV(c_0zAN}?%3BSfxH+#?aI zu1$U&*DAWZMWT*7_0sMnxQ*!PdC)CrXjgRgz%3DJj)-K6V4lm%qjEKJa&F%Au_p${ zWKWOjPSx$AoAj9ebLCp}RiD5(<(LkK1V;Fu_lfQs(_)LF($cbu^8PUe3h%WDi|(q7 zsWahx>)@EW%759CDd``ROyuFc;*{Wi|Cl=3f19E)=Y#~035KXZmk2_0ucUuWy?JvN zn3Tx|#?(_$Bz`dVn0`%&@1G~H+S=-hV&#~;vT};D({l=xV{$9XEzC*DDvVXm(}x$T zs;lqRR`-v||6YsWUSY%k#+VMiw%ddt7&-(o=VyFveT(S3zCiTVyG?oTEK=ShL>I7r z>%UbNF#mRFprGgPnB;?jd$a@Je>`}<{l9Vl>7YDgEN^vUVuJEY{SeA1Q&Ioa9qPMX>ihB?)@Z)zz|AM;unySj&e?m=#qNC&feX&odTqI}}iS7xS?$*`af*S3r2V!xjEap6k z^s8HeT6C|u@oovGsp^qPy7HZCr3h7u?zaPLp+Hbh*YrxIZ8xjM)d;oSX=!O|hbm$9 zM|?u33Q46>_;u z)+NUktXkCD%kCi_klmC*6Uw{k=Cz3GDO;&dH&1^DL zBO@~_?ad@&G!rfxZo+rqiHl7*Z@`3iY<)907wi}KWoKoir}vxiR(Ib^cHY0ndAMA- z?BgGJJ-y$AHz!Ah#iXSKM>@M*^7aczxH(|LKZm9J6!|74XFHyA_q=j7QN@J6HFx1$ zwDSo06=-||uBE7$@DuYFXr$CuR@|pH}Xd(nc&$F=DabhcSCMuKGsSaet^0ci-5Xt>FCquM30j-RtV;H{#h6t8@6>GMaclH^vUKIjcc_3^5R+Gghw028XteBKB<*o0r2_43BTU!SWnUXUV z9qTAUm+{o64qcs{Lu|Qc8%gMCJ@@&ZGT9JwMlpt3Pp;f>sz@=!oJocDgRs4aU2b$f z7-`K2JwWKcXw7{NIjPSfXWXr>uBy0QS_EFY-yyqr7$@8=EP~BqVPQdjZgza1Lw3!~ zPK(XRE=@~HP0z~7&rj>OX2(0l1tnFL`9%q->6tls1=$1E>`-zi^KN!|dF}O-w9M?> z!n{F;Y!Mb0ni_K>FDv;*MpjN z>(x5sM{motL#`d-kh^wG#FkYZ@oZ zOGOU`uAc5|b5twgcf%amj;UNRGgTTepMULx+bWg#SCs~g8PUTkhc;k5o2sUMkOSk{ z8|vx@8Ze%T?rQ5+(BcPl&wY2_m6T;t~&aTm1Ec6 zUp01p$E%a|N)3#n-~VUyGh40wbq$Qq$g`wy#8s5Aq~AWY7p+(|^7_k^{(6GRQgbos z>YY3A%f_@RT!Oi7^Ji8clJ7A7{?S>25l~7MPbqT+U0X-Uy7OqiYsk3`Q?&IHR^P*+FR z8r9%!9)5wjm6wwqALw#6`nWwYW%JITHXid2xO(;4)oY<-I1xeprW^TN%8hV0UT*vm zJ7VFF$NhrY7mx7WxM4x&JPRvZ`_pI6p1%;A6?d7+X^cB!ODx(Dnidk7>l}6c)^AC% zJZoEfr!%hSFSy6&B>7P{yX)eP*bq;D?VK6w>K&WuS9mfy${e^jo^d^Q;bKC5N+34_ zN$O&cSQF2D?e6Y*hibTKQSF%0z_YTkcRcNK&h27iVS2E6HtZ~#6OUUF&wgW*mE~n} z-E04^d1*;p3o9Et$1^VH&L@>*g*nBuikOiTmsjEwHn`>)9M??)99?)3B6}N9C`#ZA9lNx5E zmCI&pf??arZeljxy~}CPt*@)SQ(2N78{kD=*6?sU=jmWgXxO(kH#JjDL?idEPD6d& zor>a|8;N9sMr=gTwKG6(-_B`fH_dEpY-(z}TVGdGc^hUhKksIGV!SIR?`RRUum$X9 zqk7z;p}zJG>|^j;W@TOmaz`=y9@R2iAh=iS7Jsjq=F#7z&>uIDP$E+J1iY=?6FBj1 z!HyLg(QGPjmlod+fhMP=>{d#oDQx#XQPW1Y7~m$jD|q`~{Tpr|quR+foz~XQ*nPS1 zYDeAEZ-KWyWoK%mpoNQq-7)3<{dP&--h@tJy`Zg?6zK_JO93x(HPsDqxJftFNp`R# zwMRoq#C%Y7k8IV4H%0m#vA(wHI&SiSBi4|#n%l}K#H^~hPqvY*+CmuB-TIb9s6X37 zNwmb$&hxywW(u*YD>~XK+%5WrQJ8{T^imRSXJH| zmz3&Aq>U}Pa%tUd3TfT00yOP@2ic~H8{JQ*+fY*Nu9}-QU0sd!6f*3+3rplyZ3lkM z6y58DCd|`FMs|@>jV_6-;vOIA$xEu0)sie=a2l~?T3uaIsl52UInwRD(b@t1XzR*` zIdw#G8N60%bV=p6Bo;{LdSfT9l-~q8M|iiSWX$ecQm6q2w zx>W!xx8I3s?$~eqqgfCcGAleJJSrwOHZJ~p{Pl!{v_UWW3w7-`Yj4WI%RV;J*~#VX zg-f2l`UM0ft9a3WM`r#OTW}#hr6fK*#p$e@`(^Jd{((WMH&wjocjs>=xcevNgp^t) zCOW&Gcfag~*`y8eqThLW`PN!C<~!E9Wj395J%8~MZgegE)(|iHy;DxE-{BO0)4<~F zbf+_Y@&Yo7hkDU}ZQr@)umgB&=X2*Tf;8W&fkC0+5jRVRdQnY1>_r7s9lur&9yH*( zz<)Z8<39s`m;a>QntK09f&ZK#xYID;K+DuPP|@wrJX^0f>X^#s?R&KoZrRSzEPZbH;W#WD(nnpLGr1KQfr}O2q zvh6P{nypVv`{1*0$pXo6FRCw9JdjJeuYWjmx-OGL=suS&rJD?RQXT9`dxBqPX>bWW z<{V>*I%nGR>q0)EXS90LJymzg0nfuk-cRxfef_0h?&}Z_^Qba(?I|vysrUS6KVMV~ zcd97kFKoa@43~UrY*N=X!m)O@eh3H&LvP-yuYcK|4QR+v?>beEyp6Pt7A{}6@%vL{ z-D>=+?DU(f-u`s6MT%rJ|B4#Yl5Vv;Q0HG64*&{$oDP-(4-Js!LpoTMZ7TM!L$;~E z$G`F#*>{YKo!0MPH7@vhpZ26O^|G_FbMta@^YZd@$vo|wgYMNWwy-QN zGdw;szO*PYAt~iXI-oOoxAHOuH>vhzcM3}zQp+lu%Bm}_C#R%kWM%`llb@~PUhUIr zZl~TXughi8 zH$!q8Ypbs(CZ__go4EiB4Rx>P7u-F4V`F0DuO}uY-$;i(L8F3#l9J)>)o2F6Z=vd` zI;vj34xl6ml8)S=avF)d+_CqkfHiT(*`O+Y<0uOVPu;jnA|JUxOj04ogrh4EEu^N6b{>Rr|-1UkFap=LEe)a9q{SgEjI^UC~oTyRSqmJPOQx;{7)|M_GCV^q}Dj)}A zT|)^NGhV+rR%@sm(xnNsA2MiYpEnMF1O$WgV6-Bl@lIv)*fjS)8<=UmMJrxgx$M-~ z?NReeB?LtfENwkKJ)@)Jv`0?5Dih6^I&S;8nUGb`e@&o$;!_&^t-<`q=btqHA=@vQ zY(LfSEcKvC{fw!eN&SqiokacAu;7AoH;T2Rat#;u8Myqbe~=O z#fCAiuReHjdjA6hyJ@EW%(?T%xSpJ2sEpwC`*a3VZ5(7EG&1nK+j$7bME>c42_fx_ zuqCK+ei^%z05DIt2m<&8`T6h)NaoDS&dSQn$Vg93Nrarlu+RX%D_4WBnWPeo@(NzL zMp-%h$1c?>DJd=nGP2+)OqP=a2`xaDo|c*z7ZVv465#87+5Jku`^khw1+%=Of-EP? zh*GkISzJ^^6+WdDhKVvUQF452R9J9;pZBHn7oxaHkRepbs~{?=amnH$!-B8+db*!I z7jiO@peh*^m1G44gpBer1g51WCd5XD2KjqmayxTAWMcxs1{eo zT0|fzvN=gIi65MGrdaa?!Y{E!(aQzgX{M1KYaAq@e}Zad7GJ$Y_5_u@V2uD z#!Ak>*iFeeCOa!VB`z|+)76%JB2++g{mP&CYCCjw`<_!A>cFl8$E++(j~qL8oNs4i zcIt$gowKv$Dd;hDxQ{E{Ul-^vaJ_)L8Of)pjvYNwk1~%Pzf`V3s5!x$18lJ(?CcyIFLYwC(%DT3hego zaYur~mr={fll3U}xS4f5gyZsg1DaOOpo_{3CO}{^J3Toj_{urkQ-|1ttT%WOA8pxb z{L}Zx&P5d{kj#Ad$u?x0gc1*!)uV)CW;SB5nL6$O>yeWf4?)kI%;dOGUpG7QAV-C@ zC$QeJ_ev1&=dC;WQWR{mCmqE!AeTc&@=@h6GqyD+3su81!3)p^ufKs+(l?C>@N@uW z$4B^GuxB6Qs<6HcthetGp%UXQn@>qlz^*-RNZQ?Gdi<~_>J2qLa`c?IpS87$g}5k{ z4J$hVoJMX|YC`x`cL&Z~fi$>`#HfHv&ivzhwrtw8Z_l2+$DA&QWmIA3xY3;; zwvanFZ9U|8!QFcQt^)@T9^iSog9kZbYI@Yh$KR80cEyYKAcHFJU+VPA0SU#0xf#jP zL0)GpPafF$)3;xL^~D!oZut7&-~UXxCxD2H#7|px>@+qp-nMPK@!owP;?RM;`?2pc zJ$drPvE!yB#|%5Ep^KBYMdcDoDlI84%Fj%V1v9syj_ls{)245~`Q~5WZu$Wj@7`}8 z8nW>M@x?D#2Kd)Kd-v_%f8gMu!-tR1GQfFb-_60UyKgNGF4KYOO)LY*xgaMkA>7a1 zk$>{g?j2iyCV!gp^Uqth8}HhC;Hc@DfQ@bhW62V7sm_bbA>ZSbrRkacEOs_0hn>sG z)4-3pd>)+sm|0w2R$5$`2RaY*JZr--J-mPKE@RSU%I@8J_8mBU^u#IB*8ihl38IeM zK-5zW&h=y+1z87V^%GT9m6a9cki3xxIUS+C7tYvlNz-FTj~-zk)jf9N$6V#on4vaY-J@)#aJ<`PSC9wjRIwK&G%= zqZ1}0>ln4QWX%l7s;#VmRN$P9l-RHUACL3!K;C;hZdIO;Y5R&yv z>*{K2A=$mUvJ!e(kdvMq8xeff$IH{>5;8V!R_36Fl$%W04HyPY;tUL06GTF zJ(&)K5H~F?f?g)aMTdt31+oJS0|NuD`uX~JdtSZ-#Fv7+2~HE)$Y^S^ZnSTp>Iop6 zQB#Ane_?nzupNkxjgE?pilm|pBE!Q&LxOv3Np z53~{{1M)qy(o&L>k`k$;sc-}$E;c$MJTxfK|B8>FH(}ju-DKBD!DNti(`#`j%gVsq za+SNp3{JX!YI0J1Ocd-C1O1@AEy%FxYi~riF9+L!{UzR%(%Yjc*>o%HDDccXhP-I2k(6H zfDATcu~FWHRg1O2ve{x#PAxX4*?p3rgCL2{m<58wIB&uR+Vh(=YJ9wW%DF(rXi#>K zw%}Q`0mHyx!Qve^L~t+}Sdhq8Xx+jUXjEDTnELY|M+RaLB&~7+EO90%9TcJ@?4wIh z1tkEPRSPB1t~_h*Vd^IkaEDWZ4J#=@nY27aTsu`@Gq-ULlmm66<1%?Q^ z!Gtgw-UPeNrqxoUB`i5&Y|N>nfQnK>rQfeoJQZLaZ7evB(Pq(VF4Amd8yg=i;Q}G4 zhEQ*Su%sCGvE8E0vXv=ng%~wMcm{@-P6`PT2dKf`ngwJtF|@n7gY>YtI?UU-ZMuHO z#yb<+;LL`I0|RCVg;WbH3MHvw11we;XuncRL6;pC5P~*{H#XkvP+X7?&&K>J5gWQb zlyYi6B^UvoMd)p3ryWQ%EZAqf*`{7B@9ynUw3TKxae$Tpp#+Qs@*R$CxOWey)m zG=xIP2~djBAM9XNB`5<3G~3;cckIlvM9l8QYKvAbHq;i-gdyZBG&T&jhvv3o^G=OW zW8*CW)`(dY0Q115=KvqY!6$g=_Tc8gKf(%=*o!%xni;!|xARJ@5u@oG)o$L#0Rmm< z5KI&%AR9EXU#zJCBa+xc>X25&L1Sa{igY08uwjD)oE)a3(q4mZ59WjOfg}=3u}(8( zY<#4)GfHBGm|~uY3sNX05uFKvg|ILYtRo3utlQyeY`izOvooU@+RM1jyuS7XC|0Ad zQ%qS+NoH6AqaFzCAq1}xzs=a# zhk`_> z5LaCFDD7(_g8nlEbQ6w@C6&r#)}Sdydfa)$sydh1!Gm-YU?mdaVFIIeOK8BBFv4=& zkVd;}VF$Dzp@jyhqNN2IwAsk4Aa{b{Q*i+?>s^H;GypeAwX$#vXwYg092oA67ZKy? zRW{TTP|1W!Sp2PW2bsB)DL&fxCto5X`C}CwX1eRtZt5_h=NLP2SHbI6imnf zw8x2d=d#@pGkQxJm!`#(mQcZzg$Kgaly7$v@IfBC16SB6Y~_qn{yC)Cu$L^CNX(&z zq-*RIR&u7;tOaJhX8++VF-6xYWjQG<yFD# zBQ4pL@7dYyU^{#N1w3Z9&C*53(fW*q+MLXnu1ngcaO*AoJEH>n`H9dMpw z^VWPjq@~DWZ!(LiB0t;vX2bvOpPPInb^+5-}I~G*ZZcaB*D%T1cXv-Dy z=pW3pTRBKi)|lsg{KqZ)u+mmiW+BD>CFq&6?RHccm6HG7v7cjU&Of|s^Vh~4->jMr z4zx0dMM&F6i$k})!cbloeA}^=GG1v6eT0%Y_KB&TN*ed4n(RY*s_JEd+fVyK&$35K6W{D*%>Ia zR#?(y^a>KX_BeD~(Is3dE@29Ld(ZXQ(Pez#N#NBeWJ8%Plwocl3%d%TMeiB9%pA%{ zWtqsj*SW8Z4@M=$?L@XJWi+M89!hMWAAB%N0(&aa>0T$GvxE|EU&)z)61Gf9~_ZrXgk6jIm2K zN{aFJy-+8=pa5^)b8^V+88obn!DtLC`}th<=!2C3kEX@|dDWuI+zNn}*<+)_m~ber zOk!M_n#7fdA<@Gz;y(*lp0kIBCXO6EdhFOy8cgnkvPg$l;cdGgfTMwAPcLtuE53ey z{{8`hLBSy*pidxURodE&4s+sTPfvN;^bvu7-=_*UmUJe+MDhjPVieSQ5f zTP4>~aOK?x4(`2Bg&{HT!{(hR+LX=aHKIHY&#ww_<(713ILV;|urNFgVERzDqvFcD z_V0G>L87X5gaQuaqbf7%)cIcIYZlgnB=tf7=bW9De3iI&pLYAZn=(4C42%m<&ar)` zN|5-3H>5GJX^G1}! zw{mHM%~FYDzorLS4;V(;Sh%vu{{1_)o$`n)>PB*hBfNIxl7>>vEE`cO*UD7_Hq$V` znhstJoy4@UaAlLdhp&d&nC#haFGb;pk7lF9M&wRX#i*KRW$WUQkLvpES#=uw6_P#{ zu57aBun3hN*u9G{L7|6_dIGL2;Bly{s5i!(!}XR7vc@qCrA@=a?puKAW8lj3P4<}t zAXJr@+KM_XkDKx!Xp(r6%j3d{wVKRg5-q87a2jGFpph#Bt1x{GT$wN-_c4Mou3Y1C z#PsA*$f!DZ3OJjmO959FM)e42&R~6gfudoY$HkR@G}*U*-)_^ho?cGJ4})Jawe$B@ zg0LLdpiqBD>!3hK-1i|8u)|Z@V8%pnWfQ=959|j-``}TGCYzZaKS8l^h|ZD^f7{qw z+p74!!6nqE`iu$T%Db=(fRmMIG6s_=T81(TVLK25R9U88{lf?hN}mv}Of03A>AbRH z)tWW0F3Zg30i?{%qw?7WR3QPOT^2xMMcl&K1qG!5RXr58%&e;)f-VDyG(Ng)O{2ZP z8(b!9XJM>Yi7n@1Y&j5P%g+Dn*fK=+9~N6K8y8!)X|kp93iaSJm2QxhJ``TYNbzuZ z87A$K!^`%76ZgZ*i|Ul9{siDr0&r@D01!OQte zexBp44qgUh90Oj?{b=zz!^@+>%QWadD!g33f*=;X75tF!GVvuzFzp`(UbYbOS_o5; zAbuPNUZ$b*#semJ}jIz0o>b?k^yjeDp8exkU^5V6uz6G6ZRwtlzaW1xO%!5S4{dH`b{ z0ZczpwE!gNcD@i`weP^59Y1~h#fR^{v2xkMCF4QVb6a1BPvZG^cJA2ez1?{G=1m(v zegB=;S1et)q?r$$9)Oa9VT+#6HHxuiLk5{0uVdUTtHGr`0@Xv-9Im z)~{Q;X4SI4J~Q9QWFkOz>lF83pV1^4Bxe}1t*MMU0A3`vhEv#*);aKk_d)_jwv8aS z=(Uy0UtF?y(NlAb40N@hacv$8<8Cv0d)>Q+(Ok)Vap!xy!%LUF@ceT?Ib*7xCX=cA z`p=x>+m4uDPO9evO5TTEV_Y3X1KO=6@r5|JWdTpJu=eG%pD%uX@zV?D0j<6^7%OAe zs`ozmp+Xz1w9asvQbEj&JD-**RQ%${j9 z%|KsAlVwk6YRq^dL>*LaEj5rx{vXI=w2Y~#!D2cQT1zU>2-hF*^Se;e3^57g7LRWLz{1?`I`r#{T(REh+>fO`M5V|abxzDd!_w8qE zN5JehG7V|{YU63na5z+d_Or{^ezxs{FNPxS_Hs)ZtKrqH(@qom4BZ)vUVQVTP5W0L z9)Z2HnpXc{Ui&mIgWIj1xr@1+pxv--){pT&jZZ8 zACPwfJeMW?V#7iQ!hoqeWB!s?-}~a{gXD5b#HQN~$L5(PA1$>f3|RWJ7UHHq?&W{^ z&M=&wB|G!h8e77Up=mJZ>7}o&`{Ktvyxq&r4Fm02885xhv?ivrbf?dIZrSVWzWi|y z_t4TKBOrWM$3H%rYDr9IY8%X6@cb)(|6t?K`*;VI?Hmc{GtJ(5-kdOEX&cO#_uSG~ z-}(5Pt%vyAUNRYp@3YEQu4QqEnM@7csWaz2vt-4a|NP=RW7AWgzH&0V-2%Y%p>Y3G zM_+%MU@%#lx&}sb=0CgSl{N2u^39fmrkhuN;5IS<;0##qlMQR$oTFt1x^>`V3h)Pl1C(M)w?fv@Sko6CpyYZGg;M^J z%Pggogn(!mQ!E|`5Lhc1a=_2WixDuo2SNh8VPOIs5_mje0*BtybTHvjgbAzx^B)=} zz$GeS0!KOupc*E?VFP8DfC=e$%D}-Ri4#0*_Bp?tRZ)hMx~WpV;$r&60S5`lTqfi} zlUYWPvYv)>&m)HCo|liCL_Re4oPgAG2ogMO?m1b>nG6v8j|K=de+9fBBHID8u7-t2 zL_|hLMMcNp&xypvCnO{$CQ-@yDJiLGY3XoIJTohc%6=*bpM?keD#S@$Ba_ZGt^mIP z@~Un?AjA-YgG0l@$%wy)M@9o%_ycT#Yf^GDaE0^f88p}I>>T=pJuuB1B{=XaaPiVd3Es@kxo%(UH-~X=#Zuz;=);W}B7O&ov)&9VIy6?eFiK+5$kYFe4yR zhDw5gZ9A%qh|Cc}B1LCaLOk8ueih)}s<6!;H8|kqcO|J8iG}b1*Nu3CV*qkvujuq!>w}QhHER zVpMDyLS=DEMSyk()Z53HESNKTaNrFuUw98Jh!HFlDUZfR~?7De9@oNeuP#3l6M9bwP0olo2KZMPpL~s~DI)+S2IR zgH9_g4H6wkPdW#E1XXpDXr`<&F)%O_b%tgkaa2?rs)&qEY$qj4nugDys$mq36&&#N z^YiiyO)G8eLEUiy5mJ;`g(^dUbyZ|^k{oQNO=)!MClTPH(UZBq>EKyW~q7!Vu+3PCBMz&WZ4;y!D|#l0PUZey6P zl@gM>TPobw4q1uPq#0f&3osDKS*2=`~5D+2=L`aI*GmU2Eu zOh5^LLCnkWC$06msFD782HhCPUoDW7lAQ2xD)p5%C9}EdhEaeOn-y{}Uf-85KNC`?8*myqoUQ0jKrbB@ zBWP2`2>2qF5b|MF(Ed?V&_{#`#!o^2191YJg8n}eBN#t3{rATRW~q-6Oe9}@0uh3N zRQLZT|6dazP)U8ak!t^u_(1Cf;{)o`;U7LgfD_*b zljH3mQFt;y@TUa`u;9Twd}|qen)bgRA(#qLguw`bn9j-{KSH2Bd;fndLcr~0bkOGu zaL)fD3K5tOoCp9X(0v+C1pHqTA~1)w&K)>9V6T`dSCmd9NMI-%8YBP|UiI(*2OHz{vp)B-(32WB`uXu%+7Ye+hiR4&nouo2YAL4rLLaA(9oGWYrIbssjcr8hOe7DgN}@=<2d#*M>L|=7QrvAif5so^ z07J`Q?vl4AB51TW@^Ak@2N+DPsq>bt8;$pb%H{u_|GTFEs`RJiKz@R^Ara@nt zx<-pud@}mTCR)?8X~G&{FjyMeI(qs{23#!d=?fo)d^GV6FmO7@^qKW-%B%f;2Sn2T z_%-1UK<lcqu z_o#b9?EhbR`$I_Teyo@LTf8Y%^KuH$zxgk$Uc2i6Tzhxz*tXT=_+#ma{QY^;bu~wJ zfT=xo&NDB(vU&|%kj%b(#an&Ke|O|IFgQz_s|F&Og$g$lqIFq&q?ZIGe{lZ6W5d7Dr2n1t zzmxuV(*F)~y92kA{&&*8|Cro=OzuAhHXOr#ncRO&?ms5? zACvo!KfcpY&tY=^F}eR3fB*4^&;O`5J}8}7{>Psx{}G(O8g=*x=O2x&|3`5CY;^Hx z{QR#!e*SI@@o3$$d654$`u>mjAhyH{Az3E4Goih8+ zp`Dx7zq)w#nE8){^8D!=>o8o$8TmR9= zAAj_>jle1|FN=^ literal 0 HcmV?d00001 diff --git a/packaging/macosx/Resources/bin/getdisplay.sh b/packaging/macosx/Resources/bin/getdisplay.sh new file mode 100755 index 000000000..f7f383348 --- /dev/null +++ b/packaging/macosx/Resources/bin/getdisplay.sh @@ -0,0 +1,9 @@ +#!/bin/sh +# +# Author: Aaron Voisine + +if [ "$DISPLAY"x == "x" ]; then + echo :0 > /tmp/display.$UID +else + echo $DISPLAY > /tmp/display.$UID +fi diff --git a/packaging/macosx/Resources/bin/inkscape b/packaging/macosx/Resources/bin/inkscape new file mode 100755 index 000000000..bcfa77662 --- /dev/null +++ b/packaging/macosx/Resources/bin/inkscape @@ -0,0 +1,40 @@ +#!/bin/sh +# +# Author: Aaron Voisine +# Inkscape Modifications: Michael Wybrow + +CWD="`(cd \"\`dirname \\\"$0\\\"\`\"; echo $PWD)`" +TOP="`dirname \"$CWD\"`" + +export "DYLD_LIBRARY_PATH=$TOP/lib" +export "PATH=$CWD:$PATH" +export "PANGO_RC_FILE=$HOME/.inkscape-etc/pangorc" +export "FONTCONFIG_PATH=$TOP/etc/fonts" +export "GTK_IM_MODULE_FILE=$HOME/.inkscape-etc/gtk.immodules" +export "GDK_PIXBUF_MODULE_FILE=$HOME/.inkscape-etc/gdk-pixbuf.loaders" +export "GTK_DATA_PREFIX=$TOP" +export "GTK_EXE_PREFIX=$TOP" +export "GNOME_VFS_MODULE_CONFIG_PATH=$TOP/etc/gnome-vfs-2.0/modules" +export "GNOME_VFS_MODULE_PATH=$TOP/lib/gnome-vfs-2.0/modules" + +export "INKSCAPE_SHAREDIR=$TOP" +export "INKSCAPE_PLUGINDIR=$TOP/lib/inkscape" +export "INKSCAPE_LOCALEDIR=$TOP/locale" + +# TODO: Have to add ".UTF-8" to the LANG since ommiting causes Inkscape +# to crash on startup in locale_from_utf8(). +export "LANG=`grep \"\`defaults read .GlobalPreferences AppleCollationOrder \ + 2>&1\`_\" /usr/share/locale/locale.alias | tail -n1 | sed 's/\./ /' | \ + awk '{print $2}'`.UTF-8" + +mkdir -p ~/.inkscape-etc +sed 's|${HOME}|'"$HOME|g" "$TOP/etc/pango/pangorc" > ~/.inkscape-etc/pangorc +sed 's|${CWD}|'"$TOP|g" "$TOP/etc/pango/pango.modules" \ + > ~/.inkscape-etc/pango.modules +cp -f "$TOP/etc/pango/pangox.aliases" ~/.inkscape-etc/ +sed 's|${CWD}|'"$TOP|g" "$TOP/etc/gtk-2.0/gtk.immodules" \ + > ~/.inkscape-etc/gtk.immodules +sed 's|${CWD}|'"$TOP|g" "$TOP/etc/gtk-2.0/gdk-pixbuf.loaders" \ + > ~/.inkscape-etc/gdk-pixbuf.loaders + +exec "$CWD/inkscape-bin" "$@" diff --git a/packaging/macosx/Resources/inkscape_svg.icns b/packaging/macosx/Resources/inkscape_svg.icns new file mode 100644 index 0000000000000000000000000000000000000000..007bf52cb6ef53fa31670c058bac2c3b1658e324 GIT binary patch literal 52648 zcmeHw2|yIp|M=Toc3JKP1eQ}#JTQ-_>>H((Cy92EmRf$*)J3C111(c?W_Q5@JW@0( z)J(`U@eK0_k1|XxRM7Q67vx&**_{`z5l@RLs<#9w5F(B9wAoQ^-X@9R(`K9HZ6ovyxdI7W%g_GM>hrQf}E>aS!4 zGT)b*larm1mT>aaH*#cgpdddlzaaP4zU|SGG_p9NEh^S*+naGd`Q~=09xW{|+VJPC ztr5vN2cdf6etD4h=q2GR3$({@mEB-v{^aUuDh*}1*$)2of_j9IX7Sz!Y^7DE?|_dC$Y&hfd<&De1s(Rp@S)y{zywG-P+JDF#b znrJ6QG3#<}gLcNqCVixBWXJoBVNKaN_O>*rsdijC%uet#9|R%96C)&@_3o@$vu2M# zx{p6gKJ{~&*I8C~KzAM*aR(afb;EI&#yT7LKz;82MSUViKi<#7_=cT1t^1rCkLx^< zsqQ1FK&wn2~A@K`xWVLJO zcRO}$-~P>)UwySMbme+vla!UJPQ7#M#*O5wm(CvkVd`2WNzBj8%t%YUn{xBUwZv10 z_l}N0yu^Ge(=t6xedqQqRq`KukN)Zwj(C>~=q$@jIGS=xb>;A0ZTx^Whe>{mE@fry$bP?i|Je{$1*!BBklJ2 zZ7V)ie79rtN;q7q$P?%0=45B4UOD_FwSl*D+e#$3R#s3z<=f=t6_u6dWTYhicJ}Nq zM`Oo_A^wf>BD&C~p!7<}%FO(%jMTd~uU|esG7JfBGFmNFWK(fvMAZ6sGmB2GJDPsy z_W3bkh!XVh#}4SV)U^!mMo-H(a-PTpV2l$B@e@Km$g2RwJ> z_ig=<$tSmu9IvdX%zd5Usjg-ZkDYRO%ScaWf!Eg)f+{MQeC|vQ`-9Ij9+qQ1ocYS) zs~`W$GL`oW;EYKcTUXSFLe@6#EmJJasVXkJ&oEU5Z-gOhHCtb@?+a@4<=pMt|EOT( z_xaU@K$+kkTUQ^(3TkSqtEnn}ZNo9Dj$dC_N7stsOiguFZ6OfLOK0Wvbe+7Gsu5Jz z;Ug&P3zk=_GpZk%B8#9c+(zY zyxJ4WBP|;5if@(&ZpdxHc*~bBTQUQTH|s&;T{Mqc^7gihzZPK}TQFYfyv2djdOzQi@!niN+szUiZ^hq@cc9UDlQJKz=j{gL&Ag{>+4E}SmK~Xth4ICak&z@)o z;qT|!6HOsF{;faT48q^=KR{#)@S(+b0zHu}pD*m!`uWl)_2*l}&z3x;Ki@L^(qXNi zFEMbwv46|>OaI~c4e@8_d}sML1mDnkgYs>Ze=;`62S3cydi_hjQ(a3=zSg+m;`P%5 z_2-2>eV%Ik4AT|8EcEC9{tN3U-Dmzhyo|8jp+uIG|NGYDw*mqt!`|PYnrQN>|HyH# zY(Ym3!#`};g3P`t%7P0WnVI*}D7E<=IDhT(A19B- zuGx&F;RPA#8R_X6sj2F_DYtK`RLNKWJac64!L^ZyzcxRE&P3@{nl)Z}+`OquzVgTM zm_5ITZbH1ZuqJ_1nYOS3NxciF0chgcJ&~#l@{P!KePL!+RyO=)WoD#f$hU4@Pda~a zvnv0O&@Yf%IH3nlYqB#l?%~zWtsBXI9^I5&oBM}+1LCcRWen2L*|u=@UK+4<94i0dXL*9Sy!%sJT zw;}=wz9`MhrSqI~bD=4L1}malfBw94)B1Jm)_?KUuKBPETVF=yi{Ls@em-t%3$U^? z?p{BC;_!ik2V(c^KC~kod45rmUr<8o6Te-tb7Ro;%zLRR_m1Hv)l`XjaY;#Wam{x<*T5QrwL0?B`rYe- z*A>F@GA;8L;A=}wS!sD$X<1qAF86oifBT|}Wp94^#qJ1s;FZFhtc>)W(-=@aRqj?% zUQr+I=(Tv=!ok1o{D4yIj-W%nEi1^&$ zLCIgaQdv-#m!~N_2k5reGfZVA`-7u{v$MUegPTk5CEu^5LIagdYQH$zcc|uV(&9GcU`4@oFo!xXce$?9i{mE zsWEdt_g%mgYl|u_agFY?M|qCkUa(5Eu?W}-^vIue^m+OH_n+02YKtnlMpgH#uCE#A zDRp&`m<+$3xS3MCVAaFz>50$2sVyxnzW*nd6I)eXRaumBBFsx@>U=yW`OrQ;GaE~> z-4n|)n6lE6Drm&p!ctXk)zx)(-h+_3F+cIpiJ2m?b^j^fWU!TGWu>Lnm%|Z%6I(@B zyVS1{+uH`_{CVKmn@E73KB6iuE~+Z8C@-slHiAuTO$}A;QkB2g?}dAp4#vGM67qTc z@rf%3_58UO6j65#ux(_iYPT9#nNIZd`R3r>fT2VCd-UK*4zGB7;+fjY^76W*aO8?1 z)mF2+22XtDNgMAMXU&*A(f6^LNehSN)>TuL{EGTyj_w*aHl_cN-i|gxH25>clKDY@ zGPS>N$*rzrDk~~jfF#<)*4EUpA1IK8oqWdT%`4u$Szf}_DHwhw3otytVC!JgvSI2= zgNKX?JX5rB&Vo;W)K*kfGWYLSG0go+48s{h9jc}3oiM!GdbYk6(89u(Yj&UI#8Y1@hgNt6EUp6v@uInguHs<`qAhGabgNg^ zp?XEF0^}&D;y{1NQuU}#UQgAT)dTF>8rap*HFP!U2igm(7qInp0Gh7l)xg@?1fXJs z=<97Px*m>f!cwj$B_|~%Cv*F&RFWV$>1q;vMRfV<fLWG_-s>%?9Hp#yJukU?zyGDyu6~BcmHU~2his2sMfr@yZgLN!7|yXq*lDUYfst6 zkh$|Fwd&oSCa;G!Q(tP;yN?cEG&gYe;IXZEcgvUM!E*y;k2^i+-N6AhdiQJR>A8VV zTI;=gSHZ(?nc-Cz{I`e z-!gH}yZeVh*RDMz8#n(>YZLb?k&{23>UX0x*M9WrS<9wAD=%t3aW8K+alb8_wfwEI zqmx>jxGz{ZX*pc7+gjer#NET`HE1*TspQsNyW6XuO&Rynh*n*@4UDl`NaK9&^SLY8@+39Y2q$DmUI0`)Z>O-`^k63 z|47&V2q*6UAGr2TPTc2_%d}?PWm<&HT-`m~d-n9;_8z$G?xH`bzogUTcT$li2R@pn z`|J~=o3vlJwRq@3msa4&$dL8^`{TvmmDtno0M9k2fF-CN)MM0hqw5(22qkitMub8 zxeeE>NqYnIK!;7HO)(gR&z|hjcqqT!}PaTK4&^7pNEfkY&`He+e}}NUOvs~ zF)aTF4RF#TuSX+O>BF$}-Cd|LOn#2(sfZ|$|8=JHugjIfp6 z*=GK#>-BZ68U1E6Zl|d4;!m^v9dZQk)lt%>`ZewS;%k#9O?qSUB-q3Dz<%yvf%Ym!;&0RNBL;;ihV{eg-S^L-1{?cl+XoEc~rSlp1N|YNTDI7OK>0 z_{vo%kyhC!s#J;U#KeTeg!nl8cjDOb73a_@XdS9HCoT2OO%qj#Ldmn)@nMibO#|LSj4>N5%4f+jbV2Ktr{LQj1}) zQEN$OYYnEU5g(-jbSmfM91R%+flL%x7JypiYv9$Ji2r-4uvonR3UvWSX|RI32v zaYTc@2%(@UN<#xWEK8^;i1-DdZ?yv36R=8%jfsqm0Hza8gd9V1LL?x^w5oMAP=_WA zL<$`NuTmw!iUaXPMJf{jZeslOpOFQYD&`OWP#SYE7kwS@YUOGjUPl0d5d&rnAR-<} z1(TK?MU=(@OO|}$AgwWPQUyC#(dtl@Euh8*7O9M5pph!^w~#oHF~LhZ*<%~fS4jcn zN2~~oj8gT$Lj!~z6B8K`$3jyeCw}@*2mwL_gqs2sOoOg!LaK5QA`BU9xk?q4XbY;1 zjf#qhWLb`g_*q8~QLje58cR;2R%&=^O*q!F9CrYlh~e5Za1vA;au^1q2IPztE#{bR zsScu3=!XCeg9f;d1m^KYsbCk0B95d8 zIcv(16hHkS3I%c^U{h$!I9)~sJC4NfKz@B`;cf}dDj zNG#%M7)Jfdl}wT|F8tlg!-LDXzP(CnbuRIo5I7LV&aFf=g?PExoW zL2MOh(ZDcQa-_${VjWSzlAvJd9TXfKv~;Ob85w^fY=uco^#`R?^eM)0Ocv7gX z@bDz6j!-I>E)5M9V+auuF(;<)2Ct-J1}vm`8GwLncxo8vHrPw(hd01bQcL*&iB{4P z{HVAQ-yTzm|`D=gG5YJ6nrCNa3v;wL^Q&74E@NC^yi8? z8nN&&i3;Ln0U{2fB(BBADPvKbJXR6Ii;IZ{$EJmm0vjHY0H>jXS!F0f*p5M{Jfzq)x+|5-c#g7Zok)i_${-frD!DA z3NYz3u*ET;tD12gwc3ybP0U1t9Wl%X@VrBWBQW@_XoQ%RKoBUB z5T(!xA*cWkl$LjI0Kl+2SbOPl3W-J(VG)3|xJaXg{GYpFBpy;&`al>DOA|5J9B8ct zriQQw&?usUw1E`j^)I7Y(;r0$J(sNkKLkS!oN4L;H?f(`k9T3x3$sH7*jqFT1yB*N zg=s}OQY$O77w#)qXSEGNBZ>etR*5G2p!ZT*E~g*gjGYcr$$>9kBJ@SfMj&D(^mKN2 zbAGiply$Cv%RkTIp3v{Q#}azox8Hubnzp&42EQp+@xg|o5vCra1r8Xw7Tf}1Kr5ttzuoKBQykyUUS=;rVsA@_RF<$+ERrB0nDO_R55C>IShr3(25w>#~$~YR=0+A z+$BIm0C$u(z2*q+sGvW26$Y1FZAQWyXjrA<2%xllMhl%0E7uBz-j5BQQy;-PCtH~g z(M)=kjy$sG+bz(W9(WQPB%oH}X_Xo}b2BUuRS<8AyiS-Bc z4%|CJPSGZISunQcfS)t3XvEiQS%Mn4#}J@`1z{%i?(O-eDmAC1dM#@vd7s{<2f^>V z6WkA(w~)xGP{W{OKw=;ObC{T5D!7_8qZRh=>-uv1`O7!casvxjvX)6_*%|ZbuNq*j zu*y(C0M}1baKMj7)*Ju=1s7?plMbj>)VHsrf6V@$PoKYXYv}hS)uF7#_y6^oOK;&I z(lpQQ6!wS;7>HOz(P$7MiI4>|HVjS=S8LkG%XVbM=55~}IC}b1&pG$-rYd^X20_$CINIWq{La$rTCy=}dMmnzq8+5Y|h$KAcJ-b&9a zEexUHYWVVssw8wix`0V9K#aU^;By0by3e=QuF@r1_dt*UAJYq zlZ)%u7m{vo_Zr~+^uY=AT0LO%>F?=bLX0sbpg{`JD2(9)NSaXVr4_-Ic9FPGz_fSY zU$i`Qkb|SstYe3Vc=YZ+z{`hTf0$T`g65gRU>1>qj9m$yt-wfUv=k%2?9#wC5h|2T zUESQJB9YruL;AT`S=-py**grLC3WfDw{LHEdi9|_JHYe+pjSMl1z&|p#5;(9SfCI} z2wf&x7C^}vvDV$u#nsi#)qxU8#bR>{3o9FmZ4cL8z596ec3Yu5_yZn(3R>{7Xm}BJ z@i|acN?h$7vdLJ>+^SWlLHw1i&X z-^<0nK&d5jDn1w!cp7aegIJm|FCA)bEpd03_OP?10Fuzb!O_vliIR%#hfo_q-x!Q_ zpQk2G4_x?}^3#4^F4MIv7aj!I}tEOO43f(t1#TFHeAEM@x{c+z#2( zJxs0MTfKWHp+xeL$J@)q{G8|H2*x+%-063=4~gV(iK{ zA%W0#*b_s%`}OYW>SS+YWhJ+vY)vi3$iLmOd7Uzpwp(H2=-ku$i4lIUPm_K0seFcq zWb;aF%)lESWUM9!Yss=zp8HBzW3KA7@hnTgH0)WZ0RmuLwrZQ^46?5gQRA^VqXr- z$?@=rMnhqg!XNn-WvkDhK6ZHjZkd-kk7w%GlY=TY7sg3nJ;tJMlnKI_QM~|SlrLf zNJ=<;c<F@+(WZ7LKH*>eaP+qeDe3ve z<&^*q2O%8SF!vawoU?Y!H2^M2L6pQ%3d7k=$~&*l)BwOAw;cq46Oe#1u@wSTwC?M@ zN6%ckk(HgFTTw(Y5}nq$i2{~vG_r!YgyHG-a>gY8{C+P1)x*KwwZHw(sacvE7mn}w z`q1yk_YHyBH=h#FCcP{U#htmBd^_b{VM#?L21+2}p@b{2CzBiule2!JG`EVBb8&m$ zL1HJV!|SP8*{bu$_I!2j_hUbL^WlaY#RK59z#474aP^itE3YtWxVdyyA&f@?6?U*@ z!~+Ub3%c?mpewU)o{Nv&5rD+0*;&^Uj_%(2`>#LmcD1s#u`o3uP%Zd;0k7xH8yVSr zzK}At77KF-k=R~=Y8t?rka0>eLx~JHSukK(nK$ESN>EyM##Y9WC_Oz??54p zW7Y~JeH$UynI8oOzWbIVh5Ajoc+~4^mc)|PgWwU3zJ>|`S2~R)SgLf=7r?~Xqvk;T{B@oKAYe14%s%{N5 zVru;bexsj%c9_qg0eyP9I@V&Qz*uLZJ`gSY_HuKww>B5?6v%DV8_UC2DX7nv0+lmduchae zRF}b{5k>cIU(sm8z!hNv!7Y)Y4{nLm4TzFr&HM8E^mK8swKOx~g&{Zo$Vrnw*|2u? zO67{>pAC;rFJy{~OW;|I^3vkcGO7~dQNvV`Q#)pwW+g;3ScuGD$jsVI$O}h3r&GR8 z^R{eSzczejnBwzsL$eBsFu2k(cp?<1_fnPXiOgV*M0g{@e|rP6vyA`s(Cm@hzuEfb z=8fyug~?ujt&A#!^;U5SRVt`~u2f|NkrDA^tN?3|W_juS^~kRO^&82*Z0+~amfg|c zZC?JtdoMWOq6)1Tc;uwIqzr^oQD0fP0nlRO$ChbMRL>+mWy0gHLA?h>-BPFCyS~{z z@WX|R7Js~OqI5%QQE^pCX-NsDxvrwJ61#V9YS$oB4b48IGa&%VRODYi7pn{$)AyMP z)81cq@>*_bUTJw@-p##F_Ii5wlg_WkWNNFcOUr93>gwP@1}XSH;LF912-5Y642m^5G!G*?>Y5CIXC@stOn)=~BxE@Qmh zm$cDWIBIm~2^@T+NnJM`RWdx53^}Y;cx4Y00ozKQYB_<)StkOO^w#e@Wit`Y}A}S^z?Jhu!I{rV4R%w>3ATVz*qw+2zotQ{V&EV2f<;T z5Or`Ci4}pB(^xYF&{!%23Lcf%+E!zcW1OLI3k?6lR|z(!FLT|=Vb~D`gf;k{hm~+= zz3z$A;Naqe0737$R&#P&-2kqsC(`4^zZ}^dnOt2T?REnPdJ}8rXY}^g=voNrO46PT z4Xj1okZDqE#mV5fO8zuBMWN{*MQS){0dA1u8-AV2T7XOWaACSh)Wl(H~UwoDIDJgbXR7ADF*T1{B!FZ<*>Vkrt4Pt+9&3sTvFoqB-ooljVB zniI4GhF{1$g-kHDD-ss$XV2dO!!l%^QYPVdAYs9N=6g|uKc!40?Nq{o?OXG{0!YC? ziFjiB6BdTc))K)eW#)549Z6VtS{6nG5h}B==tROo-?_`SU{@0=vv%uX!h+N6r2rxr zK-doJM8bmQq>m!k(u?MY$|O@dm9Q{2XhS%G<1pK#lL-sY%nJ`+fl0EPW7(O61?p@V zNC@EY=h}2OVPWhw)#V)_^TK32dq`O5(Ne+!&T4FX#=`mKfeIk3kKv33xQPWg1uo^ln6dEB%vflCU(lGbfNv*~oEx}TYs^?M zW-O5L@jsohpi3~)-SVfHHsvhfVPwo%AQ?-#BnjeIV13q>oP~ecix!M23&s~M7+v3y&sc0YBP?vqFq-Sunn30Y9fs9wcpi>jHjkQU4YO<69PtZ&~=ie9MB1 zP-xx$w=5iR9PQ`t|B_34lNOvuz4XrF5ZUW~79C7l5c~N>$QK1p@%J-rU($l3-{cMQ zkiaPu{6=;lY2h)y+0a`Cz5SfppR_RCFPQZ9r~FK;JC?NYoZkWhVm#%?@6pMm1z*3Q z23TWTN?Neso^0bDZ-cCPLoZqQkDrVKNc-_@I{%V|VScmp;KZY)UGtKKVSdv&m~uZy zaaU$6c>7J&12%u+AsGv8e#wHX-#hEEnT=QY@l3iRXF=lk#(H@$2e3!ya~5pJy}S+& zB7cRS;Q6k|S+E&9AwnJu0F{0cUI%g(B%>#+#{5Blk!`1P79_*RD*)1407?8*`*Rk& zUs_DOi_*`0oUkJ~3;q1w$AXv;>StlviJS$OaWkOIe7U zGoJS2yL2{VVRmE2!j}vE{oK1MW8tx+rmtAo<<`X+3-dakvG8NFjD<;E{fdRymyNGj zFur2pQN3cpn6UuPl+2ntm$6`c#{!n0@f{10qG-%mAP*NC-?4yaXyjpSIct2!0^HB# z9^=?Bv=?FX_F}Qr#{iaAPBTHBm4I04>DvkdgQu2ycFqVSQtwXTXQy?J01*Eu zgG{#8fSCs4pt(-lQ81~ z|HM8zVuW4CKaddA{#YRK?1J&H9~~VS1rkZu$)7l)cG^If${*y=UO&*K^2d5;Cjni} zKM>Ha`2g_WW#dn0hV2@LUC%#6!*NqFueZUad3W;9j`C>>|J^nI zSk~X$(~tpnEC2pJo`&_`>FXcOjlOBk9|nLS`|FDJe^Z=I%fP=u{GGr4(iCI!avSiY z?(_d(f4&AUi*&dBJyQ7xw88!!vHn5+-RFM-9vrN z+XnyFh1Xx2dq40$ZP9;s#-BFv|L+}tkKX?Nx8r{s{BJkMe@_F`FJz4W-RXbY6o3D{ z{>K>q+Yo=d)Bf5N|2lvF^})EWuN&k4Bi4VL{7*OP-`5!b4F%xtT>ts|8sonK`Tqmv zKgRg4j~8A2+m`iDm)`$>fPuE)H?IG?Gyb$8{&xBO|3)Kd!}{+Z;D5SP{>J!kApRKF z|J}I$F<$>~ga7MR`5UkQ8yNrH>;H}Gf5Z15jq$&6!qUYhf8+Y!ko_6sf49aT!}HH> zU4OOd`kQh6-^FgH0bE$zqa6i)b`ie=kFSX-9iEK?+p1rvDCX0&tJBHv*{sU z!}))J-`9Uy(9+LR69`*4i1_ImtPI$AHvhWKtRB>+3*P>U)TjVRNznt z>$3w!`9k`kq5MAt&)<6cjvD3f?;jB09{_tO!48)?Q}-X`>+55feT2jkv8SiEj}Q0t z@$vD661OLX4%U4|btiAV%VbC(jXn^qlN)L04>l R9m8wqlSl>@D*uwx{}1s`%P0T< literal 0 HcmV?d00001 diff --git a/packaging/macosx/Resources/openDoc b/packaging/macosx/Resources/openDoc new file mode 100755 index 000000000..8e6ac0399 --- /dev/null +++ b/packaging/macosx/Resources/openDoc @@ -0,0 +1,8 @@ +#!/bin/sh +# +# Author: Aaron Voisine + +export "DISPLAY=`cat /tmp/display.$UID`" +BASE="`echo "$0" | sed -e 's/\/[A-Za-z]*.app\/Contents\/Resources\/script/\//'`" +cd "$BASE" +exec "$CWD/bin/inkscape" "$@" diff --git a/packaging/macosx/Resources/postscript.icns b/packaging/macosx/Resources/postscript.icns new file mode 100644 index 0000000000000000000000000000000000000000..1f12741da3e1febad71ff0acbcb4ccd8d7918820 GIT binary patch literal 45198 zcmeHw2S8KT_y0@6Mg(!7b#_?$Q#-7ywf(mC+xl&-cGzl{9cr~zTy@mZYJD$@Jrz+< zP=qQ7m8F7!OqsG|%914zOaej@GJy9x_a%VeAizyF_CspQ>z#y$7kllwmB+~<}b zckIEiQ0Fas=D&(zbha^ug~i8TyBvDPfrA-&-Knm;U6>VcjD?vHVUcb}y?n#MlQWo@ z>2Ie3xm;(Dkl3(DCjuKaizp~8EGj9@^K$aw5SVG0fZu$tvZ3a7VYUZ+{HsOST99zB z>F%977f`E6T$>kJpIGVup!eny!J)C6J zw#crdR=GkU5VYN?lPD75ABAF-=8B$h;A^pm-{M2=o|_RX6CE*OmI zPvw|gU`(g0YpQM+-lWFFy&CQ9^Jhq`a!k12B{%m|0nzF)v5JaIO3TZ7#>BtZ%rCsF zF{bu-FJbSPI?8_fF+;2#lT_gAKmQ2tzIse;tyf0rS^X|XV}c>d$uk(Hzf-IpQ+Mv9 zXVE!o=kC?0n^z{>;jayM80HAcmSJ+Lx#B zD#JT9Rq8PX-D~FEE2#hP7}K8Dwr|BSnh}Ostw-0!w=mVUilnaYP0G*iLgiCM!Qm$XeyZW8)%=P5{Il}6Y(p{0XcH5oo%Y4OjXXWw z-JP8|hYz`6=Gj%ZZ7p_dQ#m29{66G7^cbLhwcXmI1@>FEHzZWljk_|RtU3zR{ zbjV>Q$KJ`!Iv_ccVY6TZF zsw5>H!s_<+TAVa#Yig`)y5AyfsfHF>C5cNJvJPQAi!|&m5#DdTUkA78m86W2(gY1` z(jcGLe!u-L>RUlFWwe%B7D?+&!Q1KLM!3nSB;|5kMibu#1}SA7qIOBsrxahN+`O}_ zo+PDrt`$qgVo^tvN}j?*E>}qN60XN*3l+G8A(rw`OEpP!S#&BC-5p{@w_GNZN;_nz zfl)(tcQd=NPFz9A_2IsP>Rv+VOX%5KHO6L?@)m@A8x(3+_9~t8TofVAMV)xpMBq_wQ2e=t+Eprjp=rN zjk|8aE(ztsJPjWf1%7yK=bD9IO55)D^E6ALHnk5=sO*-=s#DrK zm`{&m7|mbub6LB}hfOL;aFtGJ>(}}WCT6f*qT$52lr9s#$Ha_i&utX;`Y|D+%iER_ zm@#e2$F3di?R{LiYZH!{7(Dmsj#6nKZzivq8$7jO^^rn(A8*FxhMf^Re?5Mqy>p;5 zlVm4J{*BJ8ipPnnc$|K>s;aX5c1a-wX;nPdx4p3I`t3rz*tDpiAU`iBD^3-UPn4Bp zl-`VrjZaKT%goNpOI3TbNB!-J(pyn6*P$UJJ2yY8$D5BgBqiUjgqDQl)Qqg0g52JC z>>3&no}K_S$v4t7vvUgzd*iY3+aJ7;aksjrrn(xhF@^67jetzM)q*$D8XAbZrgd5a z^5b`ADj?VN3CJDWhU3hd0r`QQnUu)xj5xD0GH;_coqDk8gl*XDH#Dw!hUlK=Ws*X6 z_FP?xzpOMH;dk?Fvd?vGoJI%6oYy|M-KUu(H9L&H)~^wL)aWoSUQ4@1hj9to+Iu@# zhDll!TDnA!S1M`r+)J+)XlWq1^lb}tx8Gl=yS;7ENW0Pk zgV^`~8T(Ao>VF+QD4A>Zb z*@jQ-Kg8dm{cFVuj22u%6j>CaFRSdVjMS8*xX6nEr-|d3m1o19sylZoE6Q${78k*T zNOorOwM&1V`ojaG+0_vhmgVKQOG}CiZz0081o%$$J8}$~c+48hYP88ik1w}!v(w^2 zj-QA==z@(}yJhotzXk^dg@lHMN8pjzW#WqQ)ho$2BE2~|ar>OH>1)qb-u89PPPI9B z7-w>9?VVhXdYte&6_XizmdI|1-RFeO_#)zpQ$_x{Q2*Zv7RT1X$;I8n)9aK^Ty|n0 zaZ^znyU!7Odd*)|Hxp0X%<(>iLm%Mc=HYqr)am%V+ zX$L`+jlH9b+tK4Ey-z0;q=njK!N#H~;h;VC?3X^Lw(NAyNU{A5G-BJ@J370096#xm zSezN*=H%vfJm6~h5j*U;FW3M0^DYjHWAEbXehjhkIpgR5=bx#iInk$n+wj$wYd7J? z_S$0l=4NIX(TLY_;hPzmw*2<3q#!pYepv4h-2V6m2aM({WH!R%bb+y$Mw_)n?a&M+3#Cam}wq{;4lgDhbtV2EO>uT=64hBtPX2w|{cM~!15zP~L zyn8j?arc@i9_lUyL8yb65a9fY@R)Xw=gzqWdsXN}v8lLSQgk~Ex*U}-g@iz#-|GK+ zbqn5XhPohC(7wOw3hE#wTJaVmp|CyXmmGMeBkq|t!{eS(nVKl*aa_)98+HGFt2lRO zd^^96*CNCPCVbdSz!O|`Redb#q9EGwHio!ne>hIkJ1g(uLQ{A|q#h3IY8tPjE}blq zo>*w(Bqd0CW%Yf$1s59fVN`ePniHV?L>D185J}p-IJHd#$*3xCYbB6c)RQ7V8TIHU z#DM;6Sf8!3~*^Q2yfM0QJTOB!8oXh)5*n?UCV z50!+JuDB(Eh6q7>J3JA~bEpQkOiwE7%x|$F>9vs^L_57rkxMlYa;A*lSz5~_^`!yT z5|IdRr*-BjY0$%<{9YD^)aU!%l!?W-h~C}>ZFDzM!I3j$ovBq!QeP0~QzVz*&`Lv% zpar2|$xRia%U9CUVlViow8?R3W{5=HN|CHi3xxunTRRn1HxhI1%DUkB6z|ZNNW|i9 zrM4V+L?sk@-6YxFiOUHYJXd!}NN5Ae-8Rt3R50N-JXVuv++eS6M54UQkV;i|Io)iy z%YtWJTt=57dgy9H-DFZXY3Lqy{4|N7QL)R5>j6Ma3MwQy6sRqKzZO&J*4~XZ_Cy zg96b_$E;)-0LGhTU*Xc8;(_d+~ z`UKGL&-v{-=#ic74&YI*yx{brz5(?6&DJ{(I61=eIRtZ%cHv^krSQnhH%s~l(6JCe zo0zqn8WZ@AfzSo<(|w5e8S+r^lL~9v<0k>}b1d&peNO-_)e=Ajw?FX{>I|U#ruSaU z;tvu)ae)#Ym!YedkRs=K`r)L43J z(&yYwAHTTazV--e+QFOuKSzJtylTmU3J7WgL#Vk(F8S=G^gnidzjE>aB~?3)dfMQH-@4(i(=?lvFxbtDN`6*@LHuJbr4OZ zIuVk|^5~;^GHL10b7o91#VkJfQx-%XI_duu2QxLD``IsTqJ9xoO8zy4 zjp>`r`eglSdH%hr5%q*S3LzDke2x$y0eH`peN2aB&{eQM&Z=1y(#mDULu;FAon1Vm`SG9NI& zYV1!@eC@M8eVF*lY+&B8gvf!yYe9Z)c2=r7zK(SZym0bNW_o(&&Fq|`XnZ&rey$%lXojebA#$yQhPo8c6xdBm20ta36w0@HjP1{F{y)(|^XWpEs1hf4H~u-dk$Lq%BFh3Sg0 zOu=|<@wKwg4)vkpYxNV3uhibT?)Cy}xt&I?U+0nL-1NDKrpLu%=HT7_@rm18Rk#Vnl&5O z-Jfh)pah@5)etmgzHf;Bq`R@kMAJs^AF6-sIH)I3U&H91Fhx(@8+00)f8x{!>_2U! zzpgn;9I=ls^N=I<(P^F$`{*{$BihI8z!2=o8=CPD8@28>)J+V2RaBjxq!FJn<7bzy zTCL;y{DT+AsJ}2!n5LVKn>1O+^^}!)PwtKi>omI73`kE>r04r?%U+ZX`Oi*7MZ$kh z7*WP8WtL!o<{1}4?mj;+4;}&W?D1Kswkka>B{>1A5hKEb1J7R!{cCFqMk_1llG&s=zjMu3sb|TaURdC9&3SvmI*sBqt7ccnvoH!YF zH~}LnXyp|+)MXLnv@#t6Q&SV-W3Gl@3i3bW?co)+CLUu0WjRwxN0j0v3^Y2tKwoW? zv1oLu$%%0>m&1b3pY=ZB9uT(XI_5Y81+rmuPB*sQXT=erk=D_yO1fpx0DJO~R|jMIKW*8%ZQFKy z#|Jxq+4=jS!+-p71jh*`lf~w6ZEWo99UPsUoLyX8UESP|c^vojJaO`*7vQ5lzGu#! z_47Ly19OlV6A^UgxC858d^N@NBKFy4#B;~aUw+xOd(Ylqf8DqLz`@@UbBZ^M%~rAo z-p($-Sjia}dn*}V%gRhkj=dV}=jp`!J)B2z{X7U`{A9f~ghlGd0LwpOadK(iDNUAK zq^*i2rR;G~7FeD_x?ao5N>7Es`=4}X9SCSs@eEY*WRr}Xy@&ZM^6dan@dyl`MGfE1 z9u42w+0_m4gVFc$i$RIXq?m|6Z&&t#lQK2K3)mW@B-spOPbSGj;bbYkpC}^*D!xoM zGOLO&Shbfg8oRIWnV6ic3>f?6pfhfqgZ5+(rD7ZhFcVndYRFj+?m-UO%lS`iMIX-LWbH*XU57MnOL>ArU(V|3ii6~9W@_pZ$%qPg#;x6~$JaE>Khbd<*E-x=9Gc6%1G~k58 z;lqRmXMc>b5je9+{hU2}_eSIrVQKL7!&V@^WHYrS zcJIj{V}bR7GV5mjh3^F!!=GSfABoy=&L*a8i6?-+nJK z8K9az%9B+_?sbggN+ZKEj)w@5lbI49dC|v}wV$KG`V2N2v<^mE??4Or5Y&Y(D(js* z7Kb}v@;pzdmq-FYn|ax3iBT8NxUu(hd-<;M#lBbZ-A?h{vo~B!lH$wC071>5wpD^c zkJ2v^ii@G#Ej=MB_{=fx!5u%YUHc0-*a7#m5$TmE4zBURe%QEWi}luR+mXQ`1S#hd zIkn2*5Q5Y`;)tSKzjX)_iVAYllcF!3^RPR-d&|17zxaIBs?Sz`@y&PZ37>cnaT;5< zaWfL340GB<^hVI0bwjzKa@{1B6c-idWu(M_b2}3Iwr^Uu_UkXd{Oaqq->>^|^Y&dX z;bCh|VXJ=Xl>w966H3*SFvR30lmftX8R+B2J-m1O=8fy|b)(iprGWLeoxArR z@(5nzjnU`Le-&R~`0B!i^Iw^rlFrR!X0fuFIjmeg^qrQ+fkPhSipok$iVAYU<{^G3 z99f5c-L-R@HNJHe82FdnzwZD22<{ZL;!h~?t!33?bwvF!gx=O*)p*rJsA;VzFM}eD zT&Ud$zi`UKk&PcZuz&wP=6>S?zaKt=v$$OMFrcliw{7sKr`6RFwO9>NjaA{5=0I4K zmz4%#%isIBivyQn;~boA%(3Be9UPpTeE$rihi@x zlVc)+1AM*Uo1SpP-AB2(!Pgl4f!U5&;19*bu0V*_&8@9PrHYUytpGjqv(u7dE{9$W zIOpek2EIAqd(Ow_l=n$5aBWY|V0V8EZ**&L1v*-7EnYJQ2q95gQV41$#YRVlT?%0a zn}>u1Uktnu;O}?#3=p5WO#NfZG4u*>l1E7^jKe*wp0M=+c1KPpGRyxqQvhNG&#CDp$S+z0lPXcJ0phel;l$&dKh=*!_D7yU6BkLL_R98^T6KvV@&4Fx&H zMR*|w8`05dQv|06(qNkgTTn0q(d^7~XtIZbd<-lIcBq~LW-kXS*yO+lkJ_&QO=d<) z5^M+~{V{ekg9rIXd!Buhor+8kvI5oM9##~ga-)OxIk`Xvo3EHCf6TtwfoIob+bgFA z`O^fIBv23}QN^)9kPz#SIYNJKlU{Yexqvb@P|@m@>QO#Co^oLr7_3>e!-kX%A_ET+ zIPo2t**v`pyWm4X94Lx`oC8jo90N}r2Sx{jC<#?`X(?a?AhT~Kc!m`xY8udO-9Wi%tUTBxCKzLo3TjT8oOZ2BQ$BoQHw?;N<~wU3x3hk z;v}>cF!=_lJFKnU`FtBF_aU0V`*CX48ECoTRij{tU>igTli`msTO5UU0t0^WK5J`M zEdf-77AjMyMg2S{swXs_DYk#-?@lY$5q&K8CvxQtF z5APvjAR@d*U#Y1-X4h`lhPUeT?X5TMtg-M(c|->2tX;uv{%8(3NQu`=(qY< zZ{Ct=N75AuRklJla@1z9ggF!_G}QO@hwe@yn|8f$YwI6_9Y}g%Fw6s+ngev`2A$QR z`a_t5_y{XZ>>^^d>!)wG{+UzkK++md60J5ZEFdrjgplUE9jsAL6e{dgE03;UMiHw>EYwLYA?NMTTk}l#1*dT>a5>cfO zNC*QF!8#IiMaFGz*48_7+S}8Mpud#e#8LIfz_5BMrRdNfMj&z&vqV?`Zf$T))ZWeu zlYx;WC(CSGxlqVJ!2AIPRFxqKv^pSgftp;Mf9-CGFuoD(jw+fTE3%x=6TUT6K^osV6GG=v$)dBLMwrJgN&z%8*E; zQU|aUEiKlIWK^EaXyZVA39u3f&@h2fs~vP;ifIwq-lSfuXF(hEz@dj8n4-BEIxyNyk?f_NYl5Hc4jM?x36iB1FSZOv?o7#CuwmCuqv;h9Y4Acg7XyDCnTjJi#= z?HpjiKu6Y47dvPrBs9L84@s}uT8%?1tCbF|(AexCbCS~dF3^;+r-=zoOr$qzahBOj z=>n%Nka~vM#%^ar6GpYT$!w%_Ay;&YWQg|#i8w$-w8A)ea(5X=N*6f_zzA6z3vm&* zodux=xbX=2QB))-ajxF09+Cc+d z8W{ppQ}(krj|=jcZK%Of?j)m?a8Hu@^*ix0vDgM$aH_>cZZD&Y{%D3-uio`*rih^0 zl(O9AwlbP;Vz*-y*)cg+Mz1|6JxUr#&wt0vY6ainikR()kj_&m zj>$PP+KC`{Qa}CIb*BnNxWopi3923AF%`HRQ@EnS#-@#V&ZL1nlezYfYqe~O3%$J^ z*^XxmJ>cw8!uk{k(y;E*o^KCaDsHu*x+sln4;>6;a#{5EHd#UzX(DaN^*{K-kKBk7 zAuhF*Abl}v=A0C6a?29@o6Wmeb~fB!w{7^snsp(wx{U?BY+w;m{?Y8JaFLtKN-w#x z4;>`zJujvd)wRL&*@8qu)rF&=cPYA{E(iXv=t9+ubcI~OmYYah8>&jG>Y9XYFepNb z$(Z0r81gg-NG!-qi;-vZk9N5z9KotKQZ5QP)IATl=ODME?olg<@7d+5u&3^@CFl;F z-`#z(%bB{z1)dmMjeI8DbAo$_8^}VTf^XaHLEW=~d${tRz@ht?>K+%IN`m?coHXuH zlmZvH;|O|i!7VWqsRT#6-GR;y?yyyNJbLahrAjJK>W(e+fiY8@y}I3ikFDGW98pT$ zIo<6_-Qmh;${W6L!vVT*WlEB>@Yx;&v8m5A0eP<51#Z~NS*i{M=||nM0ozhz7qCfM zH|g8$4Bc$NN3bS@8EgKBQ=gnLW*O&!P-Iq_Aq64BW{g>)S6qa)?*&GA`T1z`o}GS{%i+2sHwGj*fEh_Ek?j3XSG7{QVMYjI>N00LAn z%YpqW^whx-z!lte5j=0J0XPac_B-bvaQ;GIU{FwS$feLQIEfLFq#Z}zspNS8!I22( z1Z0-2M4b?HOu@2hWDg$Im3%J*T?`IEe8ZCl!I5|D-V+Wuasq&FHc5aZ7X?s27Gg;u zL7FTP&kGj<5lV$h%ccgL%{pK!J7mmDj*RC+Yk*_L|I)WKPl4_rT zbb`*gOVx!VBfcbGnNT^DPbT7E;z}}3?G`Gun^IY+vvR4a43VY_N8b922J0wNa)u!M zBxFc`b5JO(+Q_hq5o=f)X}WM^HS2x*VIi~Y07tIWJ$dJQmRy=H99hK|%z*;L;V5`x zf+R+X?5cB1s@11T1HmfMWIZ&F3=$~ZmC9gIkUH{d3Oh#2MIA4|;Jp%1Y*QLMeK?1BGX2w+|viHMu?MJq;P>)WZn5lr}6JnYL&l zbFsmaC9f@*o0iD|1euvjCwlS?+N{ULthK@HrMh$vEKVdI&THq+JhC%|^&5sGx7k1(3GI#XVT^ zMhs&d5|-uUQK&Ai6-rhC!aYzj=7?j)rtdsEYu?=F-?nLB0tk)Z;2sQmAd<|0ivH& zTQ+TanJ!Ej@)&AN*|PCP3^P9Nw0ZN7-+lS%@^_Xjp74V%Y#9g{iAkEsa>F;oCJPWYt!WS-V|KW$VUwr!EyKgRhdG_?_r8+@s z%pR8Ux439rd;8C8kFEJ?^`{>$d;7Il=gypN5#0u<4&88d>yK+bfx@{(EliO`^>dC} zR(`a6+0rEoUwYx0sg_%ZgIfzn`Gf{cm{!RaS$MqcuzcCOZ@msm&zwGK?8Nk;@N3~D z5lPPUL-@7D%I|)E^Nqy|UY;{^#^ebWqh@FK1G4p%Nd|z2L=JGuS}e4ZljNLu1Y}!o z-R$|=f_X2_o;hQRm8F@n;WM61x*+Wq%eR-kYaY!OPZhPl$N6>cOLJyD2b5z+o9NT& z#;>nu9o)3f=4@ge7eH|pRE=PC5DnnAf%pRCz3uWj;^{T7ocMI+teHY`~y7VtPi#g&VMu?u(lt1jsv#Nk?1!r+&c}U zd0>V{^NV8#ryNwXF%`}&im z15kBGsh*^6v9-l9IQ(fk;n{ghKiTxbs=ffbi_A{Ss9&_v;wWZHGaftR#Wz>1-L?4F z0Z==maq;(-?${`r(b(y8Uw{8g>tE(x=nuLx+TQ!#%8lwXZT8}2tA9N7&D(&#a{yvj zF-*r#M_qr|$^Gn| zey}`4>habRC(N9tZ)WxM+}D<^`e6rW`%5SLVf2jjm*1y5U}G4@VAxr^Re z`Q^sF+)XcU9SG+$N*63;u&{A-J>${iCOIb_Z-@=@B{CGc>ghgZl9`O@}`xsnZ;PE$xlB&cm9%p zf4F+x&fPz}@y34b$p6H+`HP>OI^($)=Dxc4U&}uJa{cBFA1{1smzE>|E*pRKofqf6 zvT(`LWh+*#Uh~lK)+#KEQJxgECK#NE`X4aQplxk4b`e_03kDhq?7WGOll_~ z#26&M=ps>1KEOdvlL1^lR7!xR=*a+Z`eg-B2H?qL1zfw2Qn`c2kri+Nh`(=E0Nv5Z z3b;|Azh+hdWeJp70lI)Bm3e~4k`{Q-;&N^oqr4Q=Y!f9WMMczu1Ih{DIdmv<#xpIU zB0UwAmS65)T3$9}jduWSX3ulA4+Z2f^Xhu|(FCY;@QiJgfj!acQY3KM(wZ5!Ohh z3?OHK*aBB2+qgKyH8Cj(xWWPSbc$H**tEx}D#m!e)!?~+zMPB57GOE%oxq#LluLVme{i}EGG<~5^S1#ae zU?8~IJB5%vL8-3DVv_9f2~ECQ<_^%I!E4G9U+@YFeh;lD%Yk)dGg+cq65404*DX*z z;$Su9FZE$vM9NbmBGTn#jusKTtKt7$)ou8 zTXOIvG%yPO4wrkEAxR#P~sB9j*q#We|29%V;_aJpX@gFNG*O3HJ;@zk;T%)9%1&A(fcqQfVWiez) z`NJduhAt^bNq}>Gk^mEX>aEpD0IEhiqfbfslTHFCk#ed89+i~a104VNBmq!yIFyvD zk^r_^i^EY#d2gBn3hki~9hHvL=SJlIhgVN}FR3;8*C)5SzCH;~DEy|<-SHR#yy{iViKWK^hfV{xaCFYNi z7(gZF|0PL*p)1cHJ}EF>ds1LH_2|P$3G|e*|4k_YE&$A`;`7Iz5+Fol24)0?E@1yZ zlM&D;ZFiIyK1xDBILw5A_Hy?J&j_Hx_TJ)mXD9?7$q4*o8381?x6a-{3h$cz`%?m= zA#Ko`5)e^U_d}-yv{&cu7{HWEGVSchg1L@ zp*O(ZUpR@ed%eZ&#Y0vE|gc4=W!qwjGl# zA4LJ0zUhRSiymG+sW>!s>?0^ZGccPp`>jWiPs+Z21O;exgVB>;TJ|XNN!d43A9@Nv zzWLO7%O6QT*|~Pg!zw_d8=6m>zv9v4lU?6DtO6k4V)}fIf2#7~H0k~eg31%C%e`T-vTsLKrv?A1c+Kn z`#%Qx52656dzep{QV;(s9lBcYw?Q%3qhG_f0IFbldN#cD=J8%#-wtyMV9uw^S=9b` zr31I&D!?!q_w>BCAB)lZj$xPz=$TG1WaSU7z!R1~qykS`{!j`$arv+z(X}gn^73^n0P>$u{Ob+Jy0&B}{=fPp z;(xDrl2i=7Cxq|6sdE;~G(-k&we+(>WWvnksDjfVZ7m6g@R ziBCN}XNl^co`39G+<0!nC@nL9DtHZzO-x6@Wo9w)xkVcPbo^u0LH6D>OJi*YK>L4c z`~SH1|AVM~W|oyU1N1@wk8l62RfCFGrdk;3LMNWEeA(h>$C+rEfF1)pVfo!}ys-X-~Mq|{dpw* zj>O-Q@1K$HU+uexN54C={}|bSjO;%~_8;o~M*qJ@_8%krkCFYy$o}KecN*F`jO;%~ z_8&v-@w4Y@bO;25nes6+xSXDz%fj8BJ{Ce L6knwXjsO2I=2EmE literal 0 HcmV?d00001 diff --git a/packaging/macosx/Resources/script b/packaging/macosx/Resources/script new file mode 100755 index 000000000..fb67e950c --- /dev/null +++ b/packaging/macosx/Resources/script @@ -0,0 +1,35 @@ +#!/bin/sh +# +# Author: Aaron Voisine +# Inkscape Modifications: Michael Wybrow + +CWD="`dirname \"$0\"`" + +ps -wx -ocommand | grep -e '[X]11' > /dev/null +if [ "$?" != "0" -a ! -f ~/.xinitrc ]; then + echo "rm -f ~/.xinitrc" > ~/.xinitrc + sed 's/xterm/# xterm/' /usr/X11R6/lib/X11/xinit/xinitrc >> ~/.xinitrc +fi + +cp -f "$CWD/bin/getdisplay.sh" /tmp/ +rm -f /tmp/display.$UID +open-x11 /tmp/getdisplay.sh || \ +open -a XDarwin /tmp/getdisplay.sh || \ +echo ":0" > /tmp/display.$UID + +while [ "$?" == "0" -a ! -f /tmp/display.$UID ]; do + sleep 1 +done +export "DISPLAY=`cat /tmp/display.$UID`" + +ps -wx -ocommand | grep -e '[X]11' > /dev/null || exit 11 + +VERSION=`/usr/bin/sw_vers | grep ProductVersion | cut -f2 -d'.'` +if [ "$VERSION" -eq "4" ]; then + # We're on tiger. So need to update fc-cache if it hasn't been done + test -f ~/.inkscape/.fccache || exit 12 +fi + +BASE="`echo "$0" | sed -e 's/\/Contents\/Resources\/script/\//'`" +cd "$BASE" +exec "$CWD/bin/inkscape" "$@" diff --git a/packaging/macosx/ScriptExec/English.lproj/InfoPlist.strings b/packaging/macosx/ScriptExec/English.lproj/InfoPlist.strings new file mode 100644 index 0000000000000000000000000000000000000000..0bb6ef503d4d4a871aa6bdaf69efe88313cab1be GIT binary patch literal 520 zcmbV|OAoI8ZL zF3<@6km{(xlb45L0(;DUTNfsCx^>H@r!{&BxCy9_Cy$O{h_uRBU3^u3@O0TeX8vv4 zHc#J4IC^Om(QM%>=D&@L6)sH@Rpzd0+@_o%Q-cb@`8d61Ihbkb?Q}#MJ+cZ@%ov|O Ssrj0v$=Ot18QLa)=sy8Lr&#a+ literal 0 HcmV?d00001 diff --git a/packaging/macosx/ScriptExec/English.lproj/main.nib/classes.nib b/packaging/macosx/ScriptExec/English.lproj/main.nib/classes.nib new file mode 100644 index 000000000..ea58db118 --- /dev/null +++ b/packaging/macosx/ScriptExec/English.lproj/main.nib/classes.nib @@ -0,0 +1,4 @@ +{ +IBClasses = (); +IBVersion = 1; +} diff --git a/packaging/macosx/ScriptExec/English.lproj/main.nib/info.nib b/packaging/macosx/ScriptExec/English.lproj/main.nib/info.nib new file mode 100644 index 000000000..da8455c15 --- /dev/null +++ b/packaging/macosx/ScriptExec/English.lproj/main.nib/info.nib @@ -0,0 +1,19 @@ + + + + + IBFramework Version + 345.0 + IBOldestOS + 3 + IBOpenObjects + + 29 + 166 + + IBSystem Version + 7B44 + targetFramework + IBCarbonFramework + + diff --git a/packaging/macosx/ScriptExec/English.lproj/main.nib/objects.xib b/packaging/macosx/ScriptExec/English.lproj/main.nib/objects.xib new file mode 100644 index 000000000..92ff05616 --- /dev/null +++ b/packaging/macosx/ScriptExec/English.lproj/main.nib/objects.xib @@ -0,0 +1,271 @@ + + + IBCarbonFramework + + NSApplication + + + + main + + + Foo + + Foo + + + About Foo + 0 + abou + + + _NSAppleMenu + + + + File + + File + + + New + n + new + + + Open… + o + open + + + TRUE + + + Close + w + clos + + + Save + s + save + + + Save As… + S + svas + + + Revert + r + rvrt + + + TRUE + + + Page Setup… + P + page + + + Print… + p + prnt + + + + + + Edit + + Edit + + + Undo + z + undo + + + Redo + Z + redo + + + TRUE + + + Cut + x + cut + + + Copy + c + copy + + + Paste + v + past + + + Delete + clea + + + Select All + a + sall + + + TRUE + + + Special Characters… + chrp + + + + + + Window + + Window + + + Zoom Window + zoom + + + TRUE + Minimize Window + m + mini + + + TRUE + Minimize All Windows + m + 1572864 + mina + + + TRUE + + + TRUE + Bring All to Front + bfrt + + + TRUE + Arrange in Front + 1572864 + frnt + + + _NSWindowsMenu + + + + _NSMainMenu + + + + + + + + + + + + + + + + + + + + + + + + + 204 300 564 780 + Window + + 0 0 360 480 + 0 0 480 360 + + FALSE + TRUE + TRUE + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Files Owner + + MainWindow + + MenuBar + + + 200 + diff --git a/packaging/macosx/ScriptExec/Info.plist b/packaging/macosx/ScriptExec/Info.plist new file mode 100644 index 000000000..9cac37f85 --- /dev/null +++ b/packaging/macosx/ScriptExec/Info.plist @@ -0,0 +1,39 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleDocumentTypes + + + CFBundleTypeExtensions + + * + + CFBundleTypeName + All + CFBundleTypeOSTypes + + **** + + CFBundleTypeRole + Viewer + + + CFBundleExecutable + ScriptExec + CFBundleIconFile + + CFBundleIdentifier + com.apple.myCarbonNibApp + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 1.1 + + diff --git a/packaging/macosx/ScriptExec/MenuBar.nib/classes.nib b/packaging/macosx/ScriptExec/MenuBar.nib/classes.nib new file mode 100644 index 000000000..ea58db118 --- /dev/null +++ b/packaging/macosx/ScriptExec/MenuBar.nib/classes.nib @@ -0,0 +1,4 @@ +{ +IBClasses = (); +IBVersion = 1; +} diff --git a/packaging/macosx/ScriptExec/MenuBar.nib/info.nib b/packaging/macosx/ScriptExec/MenuBar.nib/info.nib new file mode 100644 index 000000000..c0f4643ef --- /dev/null +++ b/packaging/macosx/ScriptExec/MenuBar.nib/info.nib @@ -0,0 +1,23 @@ + + + + + IBDocumentLocation + 99 362 356 240 0 0 1280 832 + IBEditorPositions + + 187 + 340 374 240 44 0 0 1280 832 + + IBFramework Version + 349.0 + IBOpenObjects + + 187 + + IBSystem Version + 7F44 + targetFramework + IBCarbonFramework + + diff --git a/packaging/macosx/ScriptExec/MenuBar.nib/objects.xib b/packaging/macosx/ScriptExec/MenuBar.nib/objects.xib new file mode 100644 index 000000000..78f0a0a01 --- /dev/null +++ b/packaging/macosx/ScriptExec/MenuBar.nib/objects.xib @@ -0,0 +1,73 @@ + + + IBCarbonFramework + + NSApplication + + + + MenuBar + + + ScriptExec + + ScriptExec + _NSAppleMenu + + + + _NSMainMenu + + + + + Window + + Window + + + TRUE + Minimize Window + m + mini + + + TRUE + Minimize All Windows + m + 1572864 + mini + + + TRUE + + + TRUE + Bring All to Front + frnt + + + TRUE + Bring in Front + 1572864 + frnt + + + _NSWindowsMenu + + + + + + + + + + + File's Owner + + MenuBar + + + 206 + diff --git a/packaging/macosx/ScriptExec/ScriptExec.xcode/project.pbxproj b/packaging/macosx/ScriptExec/ScriptExec.xcode/project.pbxproj new file mode 100644 index 000000000..bc081d5ef --- /dev/null +++ b/packaging/macosx/ScriptExec/ScriptExec.xcode/project.pbxproj @@ -0,0 +1,451 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 39; + objects = { + 0249A66BFF388E3F11CA2CEA = { + isa = PBXFileReference; + lastKnownFileType = archive.ar; + name = "libstdc++.a"; + path = "/usr/lib/libstdc++.a"; + refType = 0; + sourceTree = ""; + }; +//020 +//021 +//022 +//023 +//024 +//080 +//081 +//082 +//083 +//084 + 0867D6AAFE840B52C02AAC07 = { + children = ( + 0867D6ABFE840B52C02AAC07, + ); + isa = PBXVariantGroup; + name = InfoPlist.strings; + refType = 4; + sourceTree = ""; + }; + 0867D6ABFE840B52C02AAC07 = { + fileEncoding = 10; + isa = PBXFileReference; + lastKnownFileType = text.plist.strings; + name = English; + path = English.lproj/InfoPlist.strings; + refType = 4; + sourceTree = ""; + }; +//080 +//081 +//082 +//083 +//084 +//190 +//191 +//192 +//193 +//194 + 195DF8CFFE9D517E11CA2CBB = { + children = ( + 8D0C4E970486CD37000505A6, + ); + isa = PBXGroup; + name = Products; + refType = 4; + sourceTree = ""; + }; +//190 +//191 +//192 +//193 +//194 +//200 +//201 +//202 +//203 +//204 + 20286C28FDCF999611CA2CEA = { + buildSettings = { + }; + buildStyles = ( + 4A9504C5FFE6A39111CA0CBA, + 4A9504C6FFE6A39111CA0CBA, + ); + hasScannedForEncodings = 1; + isa = PBXProject; + mainGroup = 20286C29FDCF999611CA2CEA; + projectDirPath = ""; + targets = ( + 8D0C4E890486CD37000505A6, + ); + }; + 20286C29FDCF999611CA2CEA = { + children = ( + 20286C2AFDCF999611CA2CEA, + 20286C2CFDCF999611CA2CEA, + 20286C32FDCF999611CA2CEA, + 195DF8CFFE9D517E11CA2CBB, + ); + isa = PBXGroup; + name = ScriptExec; + path = ""; + refType = 4; + sourceTree = ""; + }; + 20286C2AFDCF999611CA2CEA = { + children = ( + 32DBCF6D0370B57F00C91783, + 20286C2BFDCF999611CA2CEA, + ); + isa = PBXGroup; + name = Sources; + path = ""; + refType = 4; + sourceTree = ""; + }; + 20286C2BFDCF999611CA2CEA = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + path = main.c; + refType = 4; + sourceTree = ""; + }; + 20286C2CFDCF999611CA2CEA = { + children = ( + 664C29F0060ECDC4006EC560, + B8DCE042056DAC3500C390B0, + 8D0C4E960486CD37000505A6, + B8DCE048056DAC5000C390B0, + 0867D6AAFE840B52C02AAC07, + ); + isa = PBXGroup; + name = Resources; + path = ""; + refType = 4; + sourceTree = ""; + }; + 20286C32FDCF999611CA2CEA = { + children = ( + 20286C33FDCF999611CA2CEA, + 4A9504CAFFE6A41611CA0CBA, + 4A9504C8FFE6A3BC11CA0CBA, + 0249A66BFF388E3F11CA2CEA, + B8DCE04E056DACAE00C390B0, + ); + isa = PBXGroup; + name = "External Frameworks and Libraries"; + path = ""; + refType = 4; + sourceTree = ""; + }; + 20286C33FDCF999611CA2CEA = { + fallbackIsa = PBXFileReference; + isa = PBXFrameworkReference; + lastKnownFileType = wrapper.framework; + name = Carbon.framework; + path = /System/Library/Frameworks/Carbon.framework; + refType = 0; + sourceTree = ""; + }; +//200 +//201 +//202 +//203 +//204 +//320 +//321 +//322 +//323 +//324 + 32DBCF6D0370B57F00C91783 = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + path = ScriptExec_Prefix.pch; + refType = 4; + sourceTree = ""; + }; +//320 +//321 +//322 +//323 +//324 +//4A0 +//4A1 +//4A2 +//4A3 +//4A4 + 4A9504C5FFE6A39111CA0CBA = { + buildRules = ( + ); + buildSettings = { + COPY_PHASE_STRIP = NO; + DEBUGGING_SYMBOLS = YES; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + OPTIMIZATION_CFLAGS = "-O0"; + ZERO_LINK = YES; + }; + isa = PBXBuildStyle; + name = Development; + }; + 4A9504C6FFE6A39111CA0CBA = { + buildRules = ( + ); + buildSettings = { + COPY_PHASE_STRIP = YES; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_OPTIMIZATION_LEVEL = s; + ZERO_LINK = NO; + }; + isa = PBXBuildStyle; + name = Deployment; + }; + 4A9504C8FFE6A3BC11CA0CBA = { + fallbackIsa = PBXFileReference; + isa = PBXFrameworkReference; + lastKnownFileType = wrapper.framework; + name = ApplicationServices.framework; + path = /System/Library/Frameworks/ApplicationServices.framework; + refType = 0; + sourceTree = ""; + }; + 4A9504CAFFE6A41611CA0CBA = { + fallbackIsa = PBXFileReference; + isa = PBXFrameworkReference; + lastKnownFileType = wrapper.framework; + name = CoreServices.framework; + path = /System/Library/Frameworks/CoreServices.framework; + refType = 0; + sourceTree = ""; + }; +//4A0 +//4A1 +//4A2 +//4A3 +//4A4 +//660 +//661 +//662 +//663 +//664 + 664C29F0060ECDC4006EC560 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = text.script.sh; + path = openDoc; + refType = 4; + sourceTree = ""; + }; + 664C29F1060ECDC4006EC560 = { + fileRef = 664C29F0060ECDC4006EC560; + isa = PBXBuildFile; + settings = { + }; + }; +//660 +//661 +//662 +//663 +//664 +//8D0 +//8D1 +//8D2 +//8D3 +//8D4 + 8D0C4E890486CD37000505A6 = { + buildPhases = ( + 8D0C4E8A0486CD37000505A6, + 8D0C4E8C0486CD37000505A6, + 8D0C4E8F0486CD37000505A6, + 8D0C4E910486CD37000505A6, + 8D0C4E940486CD37000505A6, + ); + buildRules = ( + ); + buildSettings = { + FRAMEWORK_SEARCH_PATHS = ""; + GCC_ENABLE_TRIGRAPHS = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = NO; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = ScriptExec_Prefix.pch; + GCC_WARN_ABOUT_MISSING_PROTOTYPES = NO; + GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; + GCC_WARN_UNKNOWN_PRAGMAS = NO; + HEADER_SEARCH_PATHS = ""; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(HOME)/Applications"; + LIBRARY_SEARCH_PATHS = ""; + LIBRARY_STYLE = Static; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ""; + OTHER_REZFLAGS = ""; + PRODUCT_NAME = ScriptExec; + SECTORDER_FLAGS = ""; + WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas"; + WRAPPER_EXTENSION = app; + }; + dependencies = ( + ); + isa = PBXNativeTarget; + name = ScriptExec; + productInstallPath = "$(HOME)/Applications"; + productName = ScriptExec; + productReference = 8D0C4E970486CD37000505A6; + productType = "com.apple.product-type.application"; + }; + 8D0C4E8A0486CD37000505A6 = { + buildActionMask = 2147483647; + files = ( + 8D0C4E8B0486CD37000505A6, + ); + isa = PBXHeadersBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + 8D0C4E8B0486CD37000505A6 = { + fileRef = 32DBCF6D0370B57F00C91783; + isa = PBXBuildFile; + settings = { + }; + }; + 8D0C4E8C0486CD37000505A6 = { + buildActionMask = 2147483647; + files = ( + 8D0C4E8D0486CD37000505A6, + B8DCE045056DAC3500C390B0, + B8DCE049056DAC5000C390B0, + 664C29F1060ECDC4006EC560, + ); + isa = PBXResourcesBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + 8D0C4E8D0486CD37000505A6 = { + fileRef = 0867D6AAFE840B52C02AAC07; + isa = PBXBuildFile; + settings = { + }; + }; + 8D0C4E8F0486CD37000505A6 = { + buildActionMask = 2147483647; + files = ( + 8D0C4E900486CD37000505A6, + ); + isa = PBXSourcesBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + 8D0C4E900486CD37000505A6 = { + fileRef = 20286C2BFDCF999611CA2CEA; + isa = PBXBuildFile; + settings = { + ATTRIBUTES = ( + ); + }; + }; + 8D0C4E910486CD37000505A6 = { + buildActionMask = 2147483647; + files = ( + 8D0C4E920486CD37000505A6, + 8D0C4E930486CD37000505A6, + B8DCE04F056DACAE00C390B0, + ); + isa = PBXFrameworksBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + 8D0C4E920486CD37000505A6 = { + fileRef = 20286C33FDCF999611CA2CEA; + isa = PBXBuildFile; + settings = { + }; + }; + 8D0C4E930486CD37000505A6 = { + fileRef = 0249A66BFF388E3F11CA2CEA; + isa = PBXBuildFile; + settings = { + }; + }; + 8D0C4E940486CD37000505A6 = { + buildActionMask = 2147483647; + files = ( + ); + isa = PBXRezBuildPhase; + runOnlyForDeploymentPostprocessing = 0; + }; + 8D0C4E960486CD37000505A6 = { + fileEncoding = 4; + isa = PBXFileReference; + lastKnownFileType = text.plist; + path = Info.plist; + refType = 4; + sourceTree = ""; + }; + 8D0C4E970486CD37000505A6 = { + explicitFileType = wrapper.application; + includeInIndex = 0; + isa = PBXFileReference; + path = ScriptExec.app; + refType = 3; + sourceTree = BUILT_PRODUCTS_DIR; + }; +//8D0 +//8D1 +//8D2 +//8D3 +//8D4 +//B80 +//B81 +//B82 +//B83 +//B84 + B8DCE042056DAC3500C390B0 = { + isa = PBXFileReference; + lastKnownFileType = wrapper.nib; + path = MenuBar.nib; + refType = 4; + sourceTree = ""; + }; + B8DCE045056DAC3500C390B0 = { + fileRef = B8DCE042056DAC3500C390B0; + isa = PBXBuildFile; + settings = { + }; + }; + B8DCE048056DAC5000C390B0 = { + fileEncoding = 30; + isa = PBXFileReference; + lastKnownFileType = text.script.sh; + path = script; + refType = 4; + sourceTree = ""; + }; + B8DCE049056DAC5000C390B0 = { + fileRef = B8DCE048056DAC5000C390B0; + isa = PBXBuildFile; + settings = { + }; + }; + B8DCE04E056DACAE00C390B0 = { + isa = PBXFileReference; + lastKnownFileType = wrapper.framework; + name = Security.framework; + path = /System/Library/Frameworks/Security.framework; + refType = 0; + sourceTree = ""; + }; + B8DCE04F056DACAE00C390B0 = { + fileRef = B8DCE04E056DACAE00C390B0; + isa = PBXBuildFile; + settings = { + }; + }; + }; + rootObject = 20286C28FDCF999611CA2CEA; +} diff --git a/packaging/macosx/ScriptExec/ScriptExec.xcode/sveinbjornt.pbxuser b/packaging/macosx/ScriptExec/ScriptExec.xcode/sveinbjornt.pbxuser new file mode 100644 index 000000000..96c879ab2 --- /dev/null +++ b/packaging/macosx/ScriptExec/ScriptExec.xcode/sveinbjornt.pbxuser @@ -0,0 +1,378 @@ +// !$*UTF8*$! +{ + 20286C28FDCF999611CA2CEA = { + activeBuildStyle = 4A9504C6FFE6A39111CA0CBA; + activeExecutable = B8DCE00B056DABA400C390B0; + activeTarget = 8D0C4E890486CD37000505A6; + addToTargets = ( + 8D0C4E890486CD37000505A6, + ); + breakpoints = ( + ); + codeSenseManager = B8DCE01A056DABA800C390B0; + executables = ( + B8DCE00B056DABA400C390B0, + ); + perUserDictionary = { + PBXConfiguration.PBXFileTableDataSource3.PBXErrorsWarningsDataSource = { + PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; + PBXFileTableDataSourceColumnSortingKey = PBXErrorsWarningsDataSource_LocationID; + PBXFileTableDataSourceColumnWidthsKey = ( + 20, + 480.8799, + 262.2085, + ); + PBXFileTableDataSourceColumnsKey = ( + PBXErrorsWarningsDataSource_TypeID, + PBXErrorsWarningsDataSource_MessageID, + PBXErrorsWarningsDataSource_LocationID, + ); + }; + PBXConfiguration.PBXFileTableDataSource3.PBXFileTableDataSource = { + PBXFileTableDataSourceColumnSortingDirectionKey = 1; + PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID; + PBXFileTableDataSourceColumnWidthsKey = ( + 20, + 508, + 20, + 93, + 43, + 43, + 20, + ); + PBXFileTableDataSourceColumnsKey = ( + PBXFileDataSource_FiletypeID, + PBXFileDataSource_Filename_ColumnID, + PBXFileDataSource_Built_ColumnID, + PBXFileDataSource_ObjectSize_ColumnID, + PBXFileDataSource_Errors_ColumnID, + PBXFileDataSource_Warnings_ColumnID, + PBXFileDataSource_Target_ColumnID, + ); + }; + PBXPerProjectTemplateStateSaveDate = 91075958; + PBXWorkspaceContents = ( + { + PBXProjectWorkspaceModule_StateKey_Rev36 = { + PBXProjectWorkspaceModule_EditorOpen = true; + PBXProjectWorkspaceModule_EmbeddedNavigatorGroup = { + Split0 = { + bookmark = B84D5462056DB5C5005CEF4C; + history = ( + B8DCE149056DAE0000C390B0, + B84D545F056DB5C5005CEF4C, + B84D5460056DB5C5005CEF4C, + ); + prevStack = ( + B8DCE14B056DAE0000C390B0, + B8DCE14C056DAE0000C390B0, + B84D5461056DB5C5005CEF4C, + ); + }; + SplitCount = 1; + }; + PBXProjectWorkspaceModule_OldDetailFrame = "{{0, 0}, {790, 196}}"; + PBXProjectWorkspaceModule_OldEditorFrame = "{{0, 196}, {790, 741}}"; + PBXProjectWorkspaceModule_OldSuperviewFrame = "{{208, 0}, {790, 937}}"; + PBXProjectWorkspaceModule_SGTM = { + PBXBottomSmartGroupGIDs = ( + 1C37FBAC04509CD000000102, + 1C37FAAC04509CD000000102, + 1C08E77C0454961000C914BD, + 1CC0EA4004350EF90044410B, + 1CC0EA4004350EF90041110B, + 1C37FABC05509CD000000102, + 1C37FABC05539CD112110102, + 1C37FABC04509CD000100104, + ); + PBXTopSmartGroupGIDs = ( + ); + }; + }; + }, + ); + "PBXWorkspaceContents:PBXConfiguration.PBXModule.PBXBuildResultsModule" = { + }; + "PBXWorkspaceContents:PBXConfiguration.PBXModule.PBXDebugBreakpointsModule" = { + }; + "PBXWorkspaceContents:PBXConfiguration.PBXModule.PBXDebugCLIModule" = { + }; + "PBXWorkspaceContents:PBXConfiguration.PBXModule.PBXDebugSessionModule" = { + }; + "PBXWorkspaceContents:PBXConfiguration.PBXModule.PBXNavigatorGroup" = { + Split0 = { + bookmark = B8DCE15E056DB05A00C390B0; + history = ( + B8DCE15D056DB05A00C390B0, + ); + }; + SplitCount = 1; + }; + "PBXWorkspaceContents:PBXConfiguration.PBXModule.PBXProjectWorkspaceModule" = { + PBXProjectWorkspaceModule_StateKey_Rev36 = { + PBXProjectWorkspaceModule_EditorOpen = true; + PBXProjectWorkspaceModule_EmbeddedNavigatorGroup = { + Split0 = { + bookmark = B8DCE154056DAE0200C390B0; + history = ( + B8DCE149056DAE0000C390B0, + B8DCE14A056DAE0000C390B0, + ); + prevStack = ( + B8DCE14B056DAE0000C390B0, + B8DCE14C056DAE0000C390B0, + ); + }; + SplitCount = 1; + }; + PBXProjectWorkspaceModule_OldDetailFrame = "{{0, 0}, {790, 196}}"; + PBXProjectWorkspaceModule_OldEditorFrame = "{{0, 196}, {790, 741}}"; + PBXProjectWorkspaceModule_OldSuperviewFrame = "{{208, 0}, {790, 937}}"; + PBXProjectWorkspaceModule_SGTM = { + PBXBottomSmartGroupGIDs = ( + 1C37FBAC04509CD000000102, + 1C37FAAC04509CD000000102, + 1C08E77C0454961000C914BD, + 1CC0EA4004350EF90044410B, + 1CC0EA4004350EF90041110B, + 1C37FABC05509CD000000102, + 1C37FABC05539CD112110102, + 1C37FABC04509CD000100104, + ); + PBXTopSmartGroupGIDs = ( + ); + }; + }; + }; + "PBXWorkspaceContents:PBXConfiguration.PBXModule.PBXRunSessionModule" = { + }; + PBXWorkspaceGeometries = ( + { + Frame = "{{0, 0}, {998, 957}}"; + PBXProjectWorkspaceModule_GeometryKey_Rev11 = { + PBXProjectWorkspaceModule_SGTM_Geometry = { + _collapsingFrameDimension = 0; + _indexOfCollapsedView = 0; + _percentageOfCollapsedView = 0; + sizes = ( + "{{0, 0}, {208, 937}}", + "{{208, 0}, {790, 937}}", + ); + }; + }; + WindowFrame = "{{222, 112}, {998, 1019}}"; + }, + ); + "PBXWorkspaceGeometries:PBXConfiguration.PBXModule.PBXBuildResultsModule" = { + Frame = "{{0, 0}, {480, 216}}"; + WindowFrame = "{{591, 638}, {480, 294}}"; + }; + "PBXWorkspaceGeometries:PBXConfiguration.PBXModule.PBXDebugBreakpointsModule" = { + BreakpointsTreeTableConfiguration = ( + enabledColumn, + 16, + breakpointColumn, + 282.583, + ); + Frame = "{{0, 0}, {208, 494}}"; + WindowFrame = "{{581, 524}, {208, 516}}"; + }; + "PBXWorkspaceGeometries:PBXConfiguration.PBXModule.PBXDebugCLIModule" = { + Frame = "{{0, 0}, {400, 200}}"; + WindowFrame = "{{114, 1150}, {400, 222}}"; + }; + "PBXWorkspaceGeometries:PBXConfiguration.PBXModule.PBXDebugSessionModule" = { + DebugConsoleDrawerSize = "{100, 120}"; + DebugConsoleVisible = None; + DebugConsoleWindowFrame = "{{200, 200}, {500, 300}}"; + DebugSTDIOWindowFrame = "{{200, 200}, {500, 300}}"; + Frame = "{{0, 0}, {745, 442}}"; + WindowFrame = "{{459, 525}, {745, 520}}"; + }; + "PBXWorkspaceGeometries:PBXConfiguration.PBXModule.PBXNavigatorGroup" = { + Frame = "{{0, 0}, {978, 830}}"; + WindowFrame = "{{544, 160}, {978, 908}}"; + }; + "PBXWorkspaceGeometries:PBXConfiguration.PBXModule.PBXProjectWorkspaceModule" = { + Frame = "{{0, 0}, {998, 957}}"; + PBXProjectWorkspaceModule_GeometryKey_Rev11 = { + PBXProjectWorkspaceModule_SGTM_Geometry = { + _collapsingFrameDimension = 0; + _indexOfCollapsedView = 0; + _percentageOfCollapsedView = 0; + sizes = ( + "{{0, 0}, {208, 937}}", + "{{208, 0}, {790, 937}}", + ); + }; + }; + WindowFrame = "{{222, 112}, {998, 1019}}"; + }; + "PBXWorkspaceGeometries:PBXConfiguration.PBXModule.PBXRunSessionModule" = { + Frame = "{{0, 0}, {745, 442}}"; + WindowFrame = "{{518, 40}, {745, 464}}"; + }; + PBXWorkspaceStateSaveDate = 91075958; + }; + perUserProjectItems = { + B84D545F056DB5C5005CEF4C = B84D545F056DB5C5005CEF4C; + B84D5460056DB5C5005CEF4C = B84D5460056DB5C5005CEF4C; + B84D5461056DB5C5005CEF4C = B84D5461056DB5C5005CEF4C; + B84D5462056DB5C5005CEF4C = B84D5462056DB5C5005CEF4C; + B8DCE149056DAE0000C390B0 = B8DCE149056DAE0000C390B0; + B8DCE14B056DAE0000C390B0 = B8DCE14B056DAE0000C390B0; + B8DCE14C056DAE0000C390B0 = B8DCE14C056DAE0000C390B0; + }; + sourceControlManager = B8DCE019056DABA800C390B0; + userBuildSettings = { + }; + }; + 20286C2BFDCF999611CA2CEA = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {908, 15665}}"; + sepNavSelRange = "{25288, 0}"; + sepNavVisRect = "{{0, 12586}, {751, 709}}"; + sepNavWindowFrame = "{{544, 160}, {978, 908}}"; + }; + }; + 32DBCF6D0370B57F00C91783 = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {623, 567}}"; + sepNavSelRange = "{0, 0}"; + sepNavVisRect = "{{0, 0}, {623, 567}}"; + }; + }; + 8D0C4E890486CD37000505A6 = { + activeExec = 0; + executables = ( + B8DCE00B056DABA400C390B0, + ); + }; + 8D0C4E960486CD37000505A6 = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {711, 428}}"; + sepNavSelRange = "{294, 0}"; + sepNavVisRect = "{{0, 0}, {711, 428}}"; + sepNavWindowFrame = "{{217, 489}, {750, 558}}"; + }; + }; + B84D545F056DB5C5005CEF4C = { + fRef = 20286C2BFDCF999611CA2CEA; + isa = PBXTextBookmark; + name = "main.c: 918"; + rLen = 0; + rLoc = 25288; + rType = 0; + vrLen = 1061; + vrLoc = 24915; + }; + B84D5460056DB5C5005CEF4C = { + fRef = B8DCE036056DABFF00C390B0; + isa = PBXBookmark; + }; + B84D5461056DB5C5005CEF4C = { + fRef = 20286C2BFDCF999611CA2CEA; + isa = PBXTextBookmark; + name = "main.c: 918"; + rLen = 0; + rLoc = 25288; + rType = 0; + vrLen = 1061; + vrLoc = 24915; + }; + B84D5462056DB5C5005CEF4C = { + fRef = B8DCE036056DABFF00C390B0; + isa = PBXTextBookmark; + name = "outputType: 1"; + rLen = 0; + rLoc = 11; + rType = 0; + vrLen = 11; + vrLoc = 0; + }; + B8DCE00B056DABA400C390B0 = { + activeArgIndex = 2147483647; + activeArgIndices = ( + ); + argumentStrings = ( + ); + configStateDict = { + }; + debuggerPlugin = GDBDebugging; + dylibVariantSuffix = ""; + enableDebugStr = 1; + environmentEntries = ( + ); + isa = PBXExecutable; + name = ScriptExec; + shlibInfoDictList = ( + ); + sourceDirectories = ( + ); + }; + B8DCE019056DABA800C390B0 = { + isa = PBXSourceControlManager; + scmConfiguration = { + }; + scmType = scm.cvs; + }; + B8DCE01A056DABA800C390B0 = { + indexTemplatePath = ""; + isa = PBXCodeSenseManager; + usesDefaults = 1; + wantsCodeCompletion = 0; + wantsCodeCompletionAutoPopup = 0; + wantsCodeCompletionAutoSuggestions = 0; + wantsCodeCompletionCaseSensitivity = 1; + wantsCodeCompletionOnlyMatchingItems = 1; + wantsCodeCompletionParametersIncluded = 1; + wantsCodeCompletionPlaceholdersInserted = 1; + wantsCodeCompletionTabCompletes = 1; + wantsIndex = 0; + }; + B8DCE034056DABFF00C390B0 = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {751, 215}}"; + sepNavSelRange = "{6, 0}"; + sepNavVisRect = "{{0, 0}, {751, 215}}"; + sepNavWindowFrame = "{{240, 468}, {750, 558}}"; + }; + }; + B8DCE036056DABFF00C390B0 = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {751, 709}}"; + sepNavSelRange = "{11, 0}"; + sepNavVisRect = "{{0, 0}, {751, 709}}"; + }; + }; + B8DCE149056DAE0000C390B0 = { + fRef = 32DBCF6D0370B57F00C91783; + isa = PBXTextBookmark; + name = "ScriptExec_Prefix.pch: 1"; + rLen = 0; + rLoc = 0; + rType = 0; + vrLen = 128; + vrLoc = 0; + }; + B8DCE14B056DAE0000C390B0 = { + fRef = 20286C2BFDCF999611CA2CEA; + isa = PBXTextBookmark; + name = "main.c: 124"; + rLen = 0; + rLoc = 3733; + rType = 0; + vrLen = 1332; + vrLoc = 2912; + }; + B8DCE14C056DAE0000C390B0 = { + fRef = 32DBCF6D0370B57F00C91783; + isa = PBXTextBookmark; + name = "ScriptExec_Prefix.pch: 1"; + rLen = 0; + rLoc = 0; + rType = 0; + vrLen = 128; + vrLoc = 0; + }; +} diff --git a/packaging/macosx/ScriptExec/ScriptExec.xcode/voisine.pbxuser b/packaging/macosx/ScriptExec/ScriptExec.xcode/voisine.pbxuser new file mode 100644 index 000000000..278eceb21 --- /dev/null +++ b/packaging/macosx/ScriptExec/ScriptExec.xcode/voisine.pbxuser @@ -0,0 +1,729 @@ +// !$*UTF8*$! +{ + 0867D6ABFE840B52C02AAC07 = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {608, 595}}"; + sepNavSelRange = "{0, 0}"; + sepNavVisRect = "{{0, 0}, {573, 595}}"; + }; + }; + 20286C28FDCF999611CA2CEA = { + activeBuildStyle = 4A9504C6FFE6A39111CA0CBA; + activeExecutable = 664C29D8060E765D006EC560; + activeTarget = 8D0C4E890486CD37000505A6; + addToTargets = ( + 8D0C4E890486CD37000505A6, + ); + codeSenseManager = 664C29E7060E7681006EC560; + executables = ( + 664C29D8060E765D006EC560, + ); + perUserDictionary = { + PBXConfiguration.PBXFileTableDataSource3.PBXErrorsWarningsDataSource = { + PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; + PBXFileTableDataSourceColumnSortingKey = PBXErrorsWarningsDataSource_LocationID; + PBXFileTableDataSourceColumnWidthsKey = ( + 20, + 365.8799, + 205.2085, + ); + PBXFileTableDataSourceColumnsKey = ( + PBXErrorsWarningsDataSource_TypeID, + PBXErrorsWarningsDataSource_MessageID, + PBXErrorsWarningsDataSource_LocationID, + ); + }; + PBXConfiguration.PBXFileTableDataSource3.PBXFileTableDataSource = { + PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; + PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID; + PBXFileTableDataSourceColumnWidthsKey = ( + 20, + 361, + 20, + 68, + 43, + 43, + 20, + ); + PBXFileTableDataSourceColumnsKey = ( + PBXFileDataSource_FiletypeID, + PBXFileDataSource_Filename_ColumnID, + PBXFileDataSource_Built_ColumnID, + PBXFileDataSource_ObjectSize_ColumnID, + PBXFileDataSource_Errors_ColumnID, + PBXFileDataSource_Warnings_ColumnID, + PBXFileDataSource_Target_ColumnID, + ); + }; + PBXPerProjectTemplateStateSaveDate = 102147745; + PBXPrepackagedSmartGroups_v2 = ( + { + PBXTransientLocationAtTop = bottom; + absolutePathToBundle = ""; + activationKey = OldTargetSmartGroup; + clz = PBXTargetSmartGroup; + description = "Displays all targets of the project."; + globalID = 1C37FABC04509CD000000102; + name = Targets; + preferences = { + image = Targets; + }; + }, + { + PBXTransientLocationAtTop = bottom; + absolutePathToBundle = ""; + clz = PBXTargetSmartGroup2; + description = "Displays all targets of the project as well as nested build phases."; + globalID = 1C37FBAC04509CD000000102; + name = Targets; + preferences = { + image = Targets; + }; + }, + { + PBXTransientLocationAtTop = bottom; + absolutePathToBundle = ""; + clz = PBXExecutablesSmartGroup; + description = "Displays all executables of the project."; + globalID = 1C37FAAC04509CD000000102; + name = Executables; + preferences = { + image = Executable; + }; + }, + { + " PBXTransientLocationAtTop " = bottom; + absolutePathToBundle = ""; + clz = PBXErrorsWarningsSmartGroup; + description = "Displays files with errors or warnings."; + globalID = 1C08E77C0454961000C914BD; + name = "Errors and Warnings"; + preferences = { + fnmatch = ""; + image = WarningsErrors; + recursive = 1; + regex = ""; + root = ""; + }; + }, + { + PBXTransientLocationAtTop = bottom; + absolutePathToBundle = ""; + clz = PBXFilenameSmartGroup; + description = "Filters items in a given group (potentially recursively) based on matching the name with the regular expression of the filter."; + globalID = 1CC0EA4004350EF90044410B; + name = "Implementation Files"; + preferences = { + canSave = 1; + fnmatch = ""; + image = SmartFolder; + isLeaf = 0; + recursive = 1; + regex = "?*\\.[mcMC]"; + root = ""; + }; + }, + { + PBXTransientLocationAtTop = bottom; + absolutePathToBundle = ""; + clz = PBXFilenameSmartGroup; + description = "This group displays Interface Builder NIB Files."; + globalID = 1CC0EA4004350EF90041110B; + name = "NIB Files"; + preferences = { + canSave = 1; + fnmatch = "*.nib"; + image = SmartFolder; + isLeaf = 0; + recursive = 1; + regex = ""; + root = ""; + }; + }, + { + PBXTransientLocationAtTop = no; + absolutePathToBundle = ""; + clz = PBXFindSmartGroup; + description = "Displays Find Results."; + globalID = 1C37FABC05509CD000000102; + name = "Find Results"; + preferences = { + image = spyglass; + }; + }, + { + PBXTransientLocationAtTop = no; + absolutePathToBundle = ""; + clz = PBXBookmarksSmartGroup; + description = "Displays Project Bookmarks."; + globalID = 1C37FABC05539CD112110102; + name = Bookmarks; + preferences = { + image = Bookmarks; + }; + }, + { + PBXTransientLocationAtTop = bottom; + absolutePathToBundle = ""; + clz = XCSCMSmartGroup; + description = "Displays files with interesting SCM status."; + globalID = E2644B35053B69B200211256; + name = SCM; + preferences = { + image = PBXRepository; + isLeaf = 0; + }; + }, + { + PBXTransientLocationAtTop = bottom; + absolutePathToBundle = ""; + clz = PBXSymbolsSmartGroup; + description = "Displays all symbols for the project."; + globalID = 1C37FABC04509CD000100104; + name = "Project Symbols"; + preferences = { + image = ProjectSymbols; + isLeaf = 1; + }; + }, + { + PBXTransientLocationAtTop = bottom; + absolutePathToBundle = ""; + clz = PBXFilenameSmartGroup; + description = "Filters items in a given group (potentially recursively) based on matching the name with the regular expression of the filter."; + globalID = PBXTemplateMarker; + name = "Simple Filter SmartGroup"; + preferences = { + canSave = 1; + fnmatch = "*.nib"; + image = SmartFolder; + isLeaf = 0; + recursive = 1; + regex = ""; + root = ""; + }; + }, + { + PBXTransientLocationAtTop = bottom; + absolutePathToBundle = ""; + clz = PBXFilenameSmartGroup; + description = "Filters items in a given group (potentially recursively) based on matching the name with the regular expression of the filter."; + globalID = PBXTemplateMarker; + name = "Simple Regular Expression SmartGroup"; + preferences = { + canSave = 1; + fnmatch = ""; + image = SmartFolder; + isLeaf = 0; + recursive = 1; + regex = "?*\\.[mcMC]"; + root = ""; + }; + }, + ); + PBXWorkspaceContents = ( + { + PBXProjectWorkspaceModule_StateKey_Rev39 = { + PBXProjectWorkspaceModule_DEGV_Geometry = { + _collapsingFrameDimension = 0; + _indexOfCollapsedView = 0; + _percentageOfCollapsedView = 0; + isCollapsed = yes; + sizes = ( + "{{0, 0}, {618, 0}}", + "{{0, 0}, {618, 627}}", + ); + }; + PBXProjectWorkspaceModule_DataSourceSelectionKey_Rev6 = { + BoundsStr = "{{0, 0}, {603, 195}}"; + Rows = ( + 0, + ); + VisibleRectStr = "{{0, 0}, {0, 0}}"; + }; + PBXProjectWorkspaceModule_EditorOpen = true; + PBXProjectWorkspaceModule_EmbeddedNavigatorGroup = { + PBXSplitModuleInNavigatorKey = { + Split0 = { + bookmark = 669900D70616A634004446AB; + history = ( + 66C09CE20612C8F000E767E6, + 66C09CE30612C8F000E767E6, + 66C09CE40612C8F000E767E6, + 669900D40616A634004446AB, + 669900D50616A634004446AB, + ); + prevStack = ( + 66C09CE60612C8F000E767E6, + 66C09CE70612C8F000E767E6, + 66C09CE80612C8F000E767E6, + 66C09CE90612C8F000E767E6, + 669900D60616A634004446AB, + ); + }; + SplitCount = 1; + }; + }; + PBXProjectWorkspaceModule_GeometryKey_Rev15 = { + PBXProjectWorkspaceModule_SGTM_Geometry = { + _collapsingFrameDimension = 0; + _indexOfCollapsedView = 0; + _percentageOfCollapsedView = 0; + sizes = ( + "{{0, 0}, {182, 627}}", + "{{182, 0}, {618, 627}}", + ); + }; + }; + PBXProjectWorkspaceModule_OldDetailFrame = "{{0, 0}, {618, 0}}"; + PBXProjectWorkspaceModule_OldEditorFrame = "{{0, 0}, {618, 627}}"; + PBXProjectWorkspaceModule_OldSuperviewFrame = "{{182, 0}, {618, 627}}"; + PBXProjectWorkspaceModule_SGTM = { + PBXBottomSmartGroupGIDs = ( + 1C37FBAC04509CD000000102, + 1C37FAAC04509CD000000102, + 1C08E77C0454961000C914BD, + 1CC0EA4004350EF90044410B, + 1CC0EA4004350EF90041110B, + 1C37FABC05509CD000000102, + 1C37FABC05539CD112110102, + E2644B35053B69B200211256, + 1C37FABC04509CD000100104, + ); + PBXSmartGroupTreeModuleColumnData = { + PBXSmartGroupTreeModuleColumnWidthsKey = ( + 165, + ); + PBXSmartGroupTreeModuleColumnsKey_v4 = ( + MainColumn, + ); + }; + PBXSmartGroupTreeModuleOutlineStateKey_v7 = { + PBXSmartGroupTreeModuleOutlineStateExpansionKey = ( + 20286C29FDCF999611CA2CEA, + 20286C2AFDCF999611CA2CEA, + 20286C2CFDCF999611CA2CEA, + 0867D6AAFE840B52C02AAC07, + ); + PBXSmartGroupTreeModuleOutlineStateSelectionKey = ( + ( + 0, + ), + ); + PBXSmartGroupTreeModuleOutlineStateVisibleRectKey = "{{0, 0}, {165, 609}}"; + }; + PBXTopSmartGroupGIDs = ( + ); + }; + }; + }, + ); + "PBXWorkspaceContents:PBXConfiguration.PBXModule.PBXBuildResultsModule" = { + }; + "PBXWorkspaceContents:PBXConfiguration.PBXModule.PBXDebugCLIModule" = { + }; + "PBXWorkspaceContents:PBXConfiguration.PBXModule.PBXDebugSessionModule" = { + Debugger = { + HorizontalSplitView = { + _collapsingFrameDimension = 0; + _indexOfCollapsedView = 0; + _percentageOfCollapsedView = 0; + isCollapsed = yes; + sizes = ( + "{{0, 0}, {283, 209}}", + "{{283, 0}, {462, 209}}", + ); + }; + VerticalSplitView = { + _collapsingFrameDimension = 0; + _indexOfCollapsedView = 0; + _percentageOfCollapsedView = 0; + isCollapsed = yes; + sizes = ( + "{{0, 0}, {745, 209}}", + "{{0, 209}, {745, 213}}", + ); + }; + }; + LauncherConfigVersion = 8; + }; + "PBXWorkspaceContents:PBXConfiguration.PBXModule.PBXNavigatorGroup" = { + PBXSplitModuleInNavigatorKey = { + SplitCount = 1; + }; + }; + "PBXWorkspaceContents:PBXConfiguration.PBXModule.PBXProjectWorkspaceModule" = { + PBXProjectWorkspaceModule_StateKey_Rev39 = { + PBXProjectWorkspaceModule_DEGV_Geometry = { + _collapsingFrameDimension = 0; + _indexOfCollapsedView = 0; + _percentageOfCollapsedView = 0; + isCollapsed = yes; + sizes = ( + "{{0, 0}, {618, 0}}", + "{{0, 0}, {618, 627}}", + ); + }; + PBXProjectWorkspaceModule_DataSourceSelectionKey_Rev6 = { + BoundsStr = "{{0, 0}, {603, 15}}"; + Rows = ( + 0, + ); + VisibleRectStr = "{{0, 0}, {0, 0}}"; + }; + PBXProjectWorkspaceModule_EditorOpen = true; + PBXProjectWorkspaceModule_EmbeddedNavigatorGroup = { + PBXSplitModuleInNavigatorKey = { + Split0 = { + bookmark = 66C09CFB061365AB00E767E6; + history = ( + 66C09CE20612C8F000E767E6, + 66C09CE30612C8F000E767E6, + 66C09CE40612C8F000E767E6, + 66C09CFA061365AB00E767E6, + ); + prevStack = ( + 66C09CE60612C8F000E767E6, + 66C09CE70612C8F000E767E6, + 66C09CE80612C8F000E767E6, + 66C09CE90612C8F000E767E6, + 66C09CEA0612C8F000E767E6, + 66C09CEB0612C8F000E767E6, + ); + }; + SplitCount = 1; + }; + }; + PBXProjectWorkspaceModule_GeometryKey_Rev15 = { + PBXProjectWorkspaceModule_SGTM_Geometry = { + _collapsingFrameDimension = 0; + _indexOfCollapsedView = 0; + _percentageOfCollapsedView = 0; + sizes = ( + "{{0, 0}, {182, 627}}", + "{{182, 0}, {618, 627}}", + ); + }; + }; + PBXProjectWorkspaceModule_OldDetailFrame = "{{0, 0}, {618, 0}}"; + PBXProjectWorkspaceModule_OldEditorFrame = "{{0, 0}, {618, 627}}"; + PBXProjectWorkspaceModule_OldSuperviewFrame = "{{182, 0}, {618, 627}}"; + PBXProjectWorkspaceModule_SGTM = { + PBXBottomSmartGroupGIDs = ( + 1C37FBAC04509CD000000102, + 1C37FAAC04509CD000000102, + 1C08E77C0454961000C914BD, + 1CC0EA4004350EF90044410B, + 1CC0EA4004350EF90041110B, + 1C37FABC05509CD000000102, + 1C37FABC05539CD112110102, + E2644B35053B69B200211256, + 1C37FABC04509CD000100104, + ); + PBXSmartGroupTreeModuleColumnData = { + PBXSmartGroupTreeModuleColumnWidthsKey = ( + 165, + ); + PBXSmartGroupTreeModuleColumnsKey_v4 = ( + MainColumn, + ); + }; + PBXSmartGroupTreeModuleOutlineStateKey_v7 = { + PBXSmartGroupTreeModuleOutlineStateExpansionKey = ( + 20286C29FDCF999611CA2CEA, + 20286C2AFDCF999611CA2CEA, + 20286C2CFDCF999611CA2CEA, + 0867D6AAFE840B52C02AAC07, + 1C08E77C0454961000C914BD, + ); + PBXSmartGroupTreeModuleOutlineStateSelectionKey = ( + ( + 17, + ), + ); + PBXSmartGroupTreeModuleOutlineStateVisibleRectKey = "{{0, 0}, {165, 609}}"; + }; + PBXTopSmartGroupGIDs = ( + ); + }; + }; + }; + "PBXWorkspaceContents:PBXConfiguration.PBXModule.PBXRunSessionModule" = { + LauncherConfigVersion = 3; + Runner = { + HorizontalSplitView = { + _collapsingFrameDimension = 0; + _indexOfCollapsedView = 0; + _percentageOfCollapsedView = 0; + isCollapsed = yes; + sizes = ( + "{{0, 0}, {491, 167}}", + "{{0, 176}, {491, 267}}", + ); + }; + VerticalSplitView = { + _collapsingFrameDimension = 0; + _indexOfCollapsedView = 0; + _percentageOfCollapsedView = 0; + isCollapsed = yes; + sizes = ( + "{{0, 0}, {405, 443}}", + "{{414, 0}, {514, 443}}", + ); + }; + }; + }; + PBXWorkspaceGeometries = ( + { + Frame = "{{0, 0}, {800, 627}}"; + PBXProjectWorkspaceModule_GeometryKey_Rev15 = { + }; + RubberWindowFrame = "54 124 800 669 0 0 1280 832 "; + }, + ); + "PBXWorkspaceGeometries:PBXConfiguration.PBXModule.PBXBuildResultsModule" = { + Frame = "{{0, 0}, {480, 217}}"; + PBXModuleWindowStatusBarHidden = YES; + RubberWindowFrame = "738 441 480 238 0 0 1280 832 "; + }; + "PBXWorkspaceGeometries:PBXConfiguration.PBXModule.PBXDebugCLIModule" = { + Frame = "{{0, 0}, {400, 201}}"; + PBXModuleWindowStatusBarHidden = YES; + RubberWindowFrame = "50 804 400 222 0 0 1280 832 "; + }; + "PBXWorkspaceGeometries:PBXConfiguration.PBXModule.PBXDebugSessionModule" = { + DebugConsoleDrawerSize = "{100, 120}"; + DebugConsoleVisible = None; + DebugConsoleWindowFrame = "{{200, 200}, {500, 300}}"; + DebugSTDIOWindowFrame = "{{200, 200}, {500, 300}}"; + Frame = "{{0, 0}, {745, 422}}"; + RubberWindowFrame = "267 358 745 464 0 0 1280 832 "; + }; + "PBXWorkspaceGeometries:PBXConfiguration.PBXModule.PBXNavigatorGroup" = { + Frame = "{{0, 0}, {750, 481}}"; + PBXModuleWindowStatusBarHidden = YES; + RubberWindowFrame = "15 325 750 502 0 0 1280 832 "; + }; + "PBXWorkspaceGeometries:PBXConfiguration.PBXModule.PBXProjectWorkspaceModule" = { + Frame = "{{0, 0}, {800, 627}}"; + PBXProjectWorkspaceModule_GeometryKey_Rev15 = { + PBXProjectWorkspaceModule_RunWindowVisible = true; + }; + RubberWindowFrame = "54 124 800 669 0 0 1280 832 "; + }; + "PBXWorkspaceGeometries:PBXConfiguration.PBXModule.PBXRunSessionModule" = { + Frame = "{{0, 0}, {870, 445}}"; + PBXModuleWindowStatusBarHidden = YES; + RubberWindowFrame = "267 356 870 466 0 0 1280 832 "; + }; + PBXWorkspaceStateSaveDate = 102147745; + }; + perUserProjectItems = { + 669900D40616A634004446AB = 669900D40616A634004446AB; + 669900D50616A634004446AB = 669900D50616A634004446AB; + 669900D60616A634004446AB = 669900D60616A634004446AB; + 669900D70616A634004446AB = 669900D70616A634004446AB; + 66C09CE20612C8F000E767E6 = 66C09CE20612C8F000E767E6; + 66C09CE30612C8F000E767E6 = 66C09CE30612C8F000E767E6; + 66C09CE40612C8F000E767E6 = 66C09CE40612C8F000E767E6; + 66C09CE60612C8F000E767E6 = 66C09CE60612C8F000E767E6; + 66C09CE70612C8F000E767E6 = 66C09CE70612C8F000E767E6; + 66C09CE80612C8F000E767E6 = 66C09CE80612C8F000E767E6; + 66C09CE90612C8F000E767E6 = 66C09CE90612C8F000E767E6; + }; + sourceControlManager = 664C29E6060E7681006EC560; + userBuildSettings = { + }; + }; + 20286C2BFDCF999611CA2CEA = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {603, 6929}}"; + sepNavSelRange = "{6021, 0}"; + sepNavVisRect = "{{0, 2527}, {603, 595}}"; + sepNavWindowFrame = "{{15, 269}, {750, 558}}"; + }; + }; + 664C29D8060E765D006EC560 = { + activeArgIndex = 2147483647; + activeArgIndices = ( + ); + argumentStrings = ( + ); + configStateDict = { + }; + debuggerPlugin = GDBDebugging; + dylibVariantSuffix = ""; + enableDebugStr = 1; + environmentEntries = ( + ); + isa = PBXExecutable; + name = ScriptExec; + shlibInfoDictList = ( + ); + sourceDirectories = ( + ); + }; + 664C29E6060E7681006EC560 = { + isa = PBXSourceControlManager; + scmConfiguration = { + }; + scmType = scm.cvs; + }; + 664C29E7060E7681006EC560 = { + indexTemplatePath = ""; + isa = PBXCodeSenseManager; + usesDefaults = 1; + wantsCodeCompletion = 1; + wantsCodeCompletionAutoPopup = 0; + wantsCodeCompletionAutoSuggestions = 0; + wantsCodeCompletionCaseSensitivity = 1; + wantsCodeCompletionOnlyMatchingItems = 1; + wantsCodeCompletionParametersIncluded = 1; + wantsCodeCompletionPlaceholdersInserted = 1; + wantsCodeCompletionTabCompletes = 1; + wantsIndex = 1; + }; + 669900D40616A634004446AB = { + fRef = 20286C2BFDCF999611CA2CEA; + isa = PBXTextBookmark; + name = "main.c: 191"; + rLen = 0; + rLoc = 6021; + rType = 0; + vrLen = 1128; + vrLoc = 5389; + }; + 669900D50616A634004446AB = { + fRef = 669900D90616A634004446AB; + isa = PBXTextBookmark; + rLen = 0; + rLoc = 2147483647; + rType = 0; + }; + 669900D60616A634004446AB = { + fRef = 20286C2BFDCF999611CA2CEA; + isa = PBXTextBookmark; + name = "main.c: 191"; + rLen = 0; + rLoc = 6021; + rType = 0; + vrLen = 1128; + vrLoc = 5389; + }; + 669900D70616A634004446AB = { + fRef = 669900D80616A634004446AB; + isa = PBXTextBookmark; + name = "(null): 459"; + rLen = 0; + rLoc = 14343; + rType = 0; + vrLen = 1147; + vrLoc = 13217; + }; + 669900D80616A634004446AB = { + isa = PBXFileReference; + lastKnownFileType = file; + name = main.c; + path = /Users/voisine/Desktop/ScriptExec/main.c; + refType = 0; + sourceTree = ""; + }; + 669900D90616A634004446AB = { + isa = PBXFileReference; + lastKnownFileType = file; + name = main.c; + path = /Users/voisine/Desktop/ScriptExec/main.c; + refType = 0; + sourceTree = ""; + }; + 66C09CE20612C8F000E767E6 = { + fRef = 8D0C4E960486CD37000505A6; + isa = PBXTextBookmark; + name = "Info.plist: 1"; + rLen = 0; + rLoc = 0; + rType = 0; + vrLen = 984; + vrLoc = 0; + }; + 66C09CE30612C8F000E767E6 = { + fRef = 0867D6ABFE840B52C02AAC07; + isa = PBXTextBookmark; + name = "English: 1"; + rLen = 0; + rLoc = 0; + rType = 0; + vrLen = 259; + vrLoc = 0; + }; + 66C09CE40612C8F000E767E6 = { + fRef = B8DCE048056DAC5000C390B0; + isa = PBXTextBookmark; + name = "script: 31"; + rLen = 0; + rLoc = 20; + rType = 0; + vrLen = 20; + vrLoc = 0; + }; + 66C09CE60612C8F000E767E6 = { + fRef = 20286C2BFDCF999611CA2CEA; + isa = PBXTextBookmark; + name = "main.c: 163"; + rLen = 0; + rLoc = 5767; + rType = 0; + vrLen = 858; + vrLoc = 4669; + }; + 66C09CE70612C8F000E767E6 = { + fRef = 8D0C4E960486CD37000505A6; + isa = PBXTextBookmark; + name = "Info.plist: 1"; + rLen = 0; + rLoc = 0; + rType = 0; + vrLen = 984; + vrLoc = 0; + }; + 66C09CE80612C8F000E767E6 = { + fRef = 0867D6ABFE840B52C02AAC07; + isa = PBXTextBookmark; + name = "English: 1"; + rLen = 0; + rLoc = 0; + rType = 0; + vrLen = 259; + vrLoc = 0; + }; + 66C09CE90612C8F000E767E6 = { + fRef = B8DCE048056DAC5000C390B0; + isa = PBXTextBookmark; + name = "script: 1"; + rLen = 0; + rLoc = 0; + rType = 0; + vrLen = 20; + vrLoc = 0; + }; + 8D0C4E890486CD37000505A6 = { + activeExec = 0; + executables = ( + 664C29D8060E765D006EC560, + ); + }; + 8D0C4E960486CD37000505A6 = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {573, 599}}"; + sepNavSelRange = "{0, 0}"; + sepNavVisRect = "{{0, 0}, {573, 595}}"; + }; + }; + B8DCE048056DAC5000C390B0 = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {573, 595}}"; + sepNavSelRange = "{797, 0}"; + sepNavVisRect = "{{0, 0}, {573, 595}}"; + }; + }; +} diff --git a/packaging/macosx/ScriptExec/ScriptExec_Prefix.pch b/packaging/macosx/ScriptExec/ScriptExec_Prefix.pch new file mode 100644 index 000000000..16d7ede3d --- /dev/null +++ b/packaging/macosx/ScriptExec/ScriptExec_Prefix.pch @@ -0,0 +1,5 @@ +// +// Prefix header for all source files of the 'ScriptExec' target in the 'ScriptExec' project. +// + +#include diff --git a/packaging/macosx/ScriptExec/main.c b/packaging/macosx/ScriptExec/main.c new file mode 100644 index 000000000..89b07ddd0 --- /dev/null +++ b/packaging/macosx/ScriptExec/main.c @@ -0,0 +1,624 @@ +/* + Platypus - create MacOS X application bundles that execute scripts + This is the executable that goes into Platypus apps + Copyright (C) 2003 Sveinbjorn Thordarson + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + main.c - main program file + +*/ + +/////////////////////////////////////// +// Includes +/////////////////////////////////////// +#pragma mark Includes + +// Apple stuff +#include +#include +#include +#include + +// Unix stuff +#include +#include +#include +#include + +/////////////////////////////////////// +// Definitions +/////////////////////////////////////// +#pragma mark Definitions + +// name length limits +#define kMaxPathLength 1024 + +// names of files bundled with app +#define kScriptFileName "script" +#define kOpenDocFileName "openDoc" + +// custom carbon events +#define kEventClassRedFatalAlert 911 +#define kEventKindX11Failed 911 +#define kEventKindFCCacheFailed 912 + +//maximum arguments the script accepts +#define kMaxArgumentsToScript 252 + +/////////////////////////////////////// +// Prototypes +/////////////////////////////////////// +#pragma mark Prototypes + +static void *Execute(void *arg); +static void *OpenDoc(void *arg); +static OSErr ExecuteScript(char *script, pid_t *pid); + +static void GetParameters(void); +static char* GetScript(void); +static char* GetOpenDoc(void); + +OSErr LoadMenuBar(char *appName); + +static OSStatus FSMakePath(FSSpec file, char *path, long maxPathSize); +static void RedFatalAlert(Str255 errorString, Str255 expStr); +static short DoesFileExist(char *path); +static OSStatus FixFCCache(void); + +static OSErr AppQuitAEHandler(const AppleEvent *theAppleEvent, + AppleEvent *reply, long refCon); +static OSErr AppOpenDocAEHandler(const AppleEvent *theAppleEvent, + AppleEvent *reply, long refCon); +static OSErr AppOpenAppAEHandler(const AppleEvent *theAppleEvent, + AppleEvent *reply, long refCon); +static OSStatus X11FailedHandler(EventHandlerCallRef theHandlerCall, + EventRef theEvent, void *userData); +static OSStatus FCCacheFailedHandler(EventHandlerCallRef theHandlerCall, + EventRef theEvent, void *userData); +/////////////////////////////////////// +// Globals +/////////////////////////////////////// +#pragma mark Globals + +// process id of forked process +pid_t pid = 0; + +// thread id of threads that start scripts +pthread_t odtid = 0, tid = 0; + +// indicator of whether the script has completed executing +short taskDone = true; + +// execution parameters +char scriptPath[kMaxPathLength]; +char openDocPath[kMaxPathLength]; + +//arguments to the script +char *arguments[kMaxArgumentsToScript+3]; +char *fileArgs[kMaxArgumentsToScript]; +short numArgs = 0; + +extern char **environ; + +#pragma mark - + +/////////////////////////////////////// +// Program entrance point +/////////////////////////////////////// +int main(int argc, char* argv[]) +{ + OSErr err = noErr; + EventTypeSpec X11events = { kEventClassRedFatalAlert, kEventKindX11Failed }; + EventTypeSpec FCCacheEvents = { kEventClassRedFatalAlert, kEventKindFCCacheFailed }; + + InitCursor(); + + //install Apple Event handlers + err += AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, + NewAEEventHandlerUPP(AppQuitAEHandler), + 0, false); + err += AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments, + NewAEEventHandlerUPP(AppOpenDocAEHandler), + 0, false); + err += AEInstallEventHandler(kCoreEventClass, kAEOpenApplication, + NewAEEventHandlerUPP(AppOpenAppAEHandler), + 0, false); + err += InstallEventHandler(GetApplicationEventTarget(), + NewEventHandlerUPP(X11FailedHandler), 1, + &X11events, NULL, NULL); + err += InstallEventHandler(GetApplicationEventTarget(), + NewEventHandlerUPP(FCCacheFailedHandler), 1, + &FCCacheEvents, NULL, NULL); + + if (err) RedFatalAlert("\pInitialization Error", + "\pError initing Apple Event handlers."); + + //create the menu bar + if (err = LoadMenuBar(NULL)) RedFatalAlert("\pInitialization Error", + "\pError loading MenuBar.nib."); + + GetParameters(); //load data from files containing exec settings + + RunApplicationEventLoop(); //Run the event loop + return 0; +} + +#pragma mark - + + +////////////////////////////////// +// Handler for when X11 fails to start +////////////////////////////////// +static OSStatus FCCacheFailedHandler(EventHandlerCallRef theHandlerCall, + EventRef theEvent, void *userData) +{ + + pthread_join(tid, NULL); + if (odtid) pthread_join(odtid, NULL); + + SInt16 itemHit; + + AlertStdAlertParamRec params; + params.movable = true; + params.helpButton = false; + params.filterProc = NULL; + params.defaultText = "\pRun fc-cache"; + params.cancelText = "\pIgnore"; + params.otherText = NULL; + params.defaultButton = kAlertStdAlertOKButton; + params.cancelButton = kAlertStdAlertCancelButton; + params.position = kWindowDefaultPosition; + + StandardAlert(kAlertStopAlert, "\pFont caches may need to be updated", + "\pThere is a problem on OS X 10.4.x where X11 installation does not always generate the necessary fontconfig caches. This can be corrected by running /usr/X11R6/bin/fc-cache as root.\n\nThis may take some time. Please do not close Inkscape.", + ¶ms, &itemHit); + + if (itemHit == kAlertStdAlertOKButton) + { + OSStatus err = FixFCCache(); + + if (err == errAuthorizationSuccess) + { + params.defaultText = (void *) kAlertDefaultOKText; + params.cancelText = NULL; + + StandardAlert(kAlertNoteAlert, "\pFont caches have been updated", + "\pPlease re-run Inkscape.", ¶ms, &itemHit); + system("test -d $HOME/.inkscape || mkdir $HOME/.inkscape; touch $HOME/.inkscape/.fccache"); + } + } + else + { + params.defaultText = (void *) kAlertDefaultOKText; + params.cancelText = NULL; + + StandardAlert(kAlertNoteAlert, "\pFont caches have not been updated", + "\pThey can be updated manually by running the following:\n sudo /usr/X11R6/bin/fc-cache\nOnce you have dealt with this, please re-run Inkscape.", ¶ms, &itemHit); + system("test -d $HOME/.inkscape || mkdir $HOME/.inkscape; touch $HOME/.inkscape/.fccache"); + } + + ExitToShell(); + + return noErr; +} + + +///////////////////////////////////// +// Code to run fc-cache on first run +///////////////////////////////////// +static OSStatus FixFCCache (void) +{ + char* args[1]; + + // Run fc-cache + AuthorizationItem authItems[] = + { + { + kAuthorizationRightExecute, + 23, + "/usr/X11R6/bin/fc-cache", + 0 + } + }; + AuthorizationItemSet authItemSet = + { + 1, + authItems + }; + AuthorizationRef authRef = NULL; + OSStatus err = AuthorizationCreate (NULL, &authItemSet, + kAuthorizationFlagInteractionAllowed | kAuthorizationFlagExtendRights, &authRef); + + if (err == errAuthorizationSuccess) + { + //the arguments parameter to AuthorizationExecuteWithPrivileges is + //a NULL terminated array of C string pointers. + args[0]= NULL; + + AuthorizationExecuteWithPrivileges (authRef, "/usr/X11R6/bin/fc-cache", + kAuthorizationFlagDefaults, args, NULL); + } + AuthorizationFree(authRef, kAuthorizationFlagDestroyRights); + + return err; +} + +/////////////////////////////////// +// Execution thread starts here +/////////////////////////////////// +static void *Execute (void *arg) +{ + EventRef event; + + taskDone = false; + + OSErr err = ExecuteScript(scriptPath, &pid); + if (err == (OSErr)11) { + CreateEvent(NULL, kEventClassRedFatalAlert, kEventKindX11Failed, 0, + kEventAttributeNone, &event); + PostEventToQueue(GetMainEventQueue(), event, kEventPriorityStandard); + } + else if (err == (OSErr)12) { + CreateEvent(NULL, kEventClassRedFatalAlert, kEventKindFCCacheFailed, 0, + kEventAttributeNone, &event); + PostEventToQueue(GetMainEventQueue(), event, kEventPriorityStandard); + } + else ExitToShell(); + return 0; +} + +/////////////////////////////////// +// Open additional documents thread starts here +/////////////////////////////////// +static void *OpenDoc (void *arg) +{ + ExecuteScript(openDocPath, NULL); + return 0; +} + +/////////////////////////////////////// +// Run a script via the system command +/////////////////////////////////////// +static OSErr ExecuteScript (char *script, pid_t *pid) +{ + pid_t wpid = 0, p = 0; + int status, i; + + if (! pid) pid = &p; + + // Generate the array of argument strings before we do any executing + arguments[0] = script; + for (i = 0; i < numArgs; i++) arguments[i + 1] = fileArgs[i]; + arguments[i + 1] = NULL; + + *pid = fork(); //open fork + + if (*pid == (pid_t)-1) exit(13); //error + else if (*pid == 0) { //child process started + execve(arguments[0], arguments, environ); + exit(13); //if we reach this point, there's an error + } + + wpid = waitpid(*pid, &status, 0); //wait while child process finishes + + if (wpid == (pid_t)-1) return wpid; + return (OSErr)WEXITSTATUS(status); +} + +#pragma mark - + +/////////////////////////////////////// +// This function loads all the neccesary settings +// from config files in the Resources folder +/////////////////////////////////////// +static void GetParameters (void) +{ + char *str; + if (! (str = (char *)GetScript())) //get path to script to be executed + RedFatalAlert("\pInitialization Error", + "\pError getting script from application bundle."); + strcpy((char *)&scriptPath, str); + + if (! (str = (char *)GetOpenDoc())) //get path to openDoc + RedFatalAlert("\pInitialization Error", + "\pError getting openDoc from application bundle."); + strcpy((char *)&openDocPath, str); +} + +/////////////////////////////////////// +// Get path to the script in Resources folder +/////////////////////////////////////// +static char* GetScript (void) +{ + CFStringRef fileName; + CFBundleRef appBundle; + CFURLRef scriptFileURL; + FSRef fileRef; + FSSpec fileSpec; + char *path; + + //get CF URL for script + if (! (appBundle = CFBundleGetMainBundle())) return NULL; + if (! (fileName = CFStringCreateWithCString(NULL, kScriptFileName, + kCFStringEncodingASCII))) + return NULL; + if (! (scriptFileURL = CFBundleCopyResourceURL(appBundle, fileName, NULL, + NULL))) return NULL; + + //Get file reference from Core Foundation URL + if (! CFURLGetFSRef(scriptFileURL, &fileRef)) return NULL; + + //dispose of the CF variables + CFRelease(scriptFileURL); + CFRelease(fileName); + + //convert FSRef to FSSpec + if (FSGetCatalogInfo(&fileRef, kFSCatInfoNone, NULL, NULL, &fileSpec, + NULL)) return NULL; + + //create path string + if (! (path = malloc(kMaxPathLength))) return NULL; + if (FSMakePath(fileSpec, path, kMaxPathLength)) return NULL; + if (! DoesFileExist(path)) return NULL; + + return path; +} + +/////////////////////////////////////// +// Gets the path to openDoc in Resources folder +/////////////////////////////////////// +static char* GetOpenDoc (void) +{ + CFStringRef fileName; + CFBundleRef appBundle; + CFURLRef openDocFileURL; + FSRef fileRef; + FSSpec fileSpec; + char *path; + + //get CF URL for openDoc + if (! (appBundle = CFBundleGetMainBundle())) return NULL; + if (! (fileName = CFStringCreateWithCString(NULL, kOpenDocFileName, + kCFStringEncodingASCII))) + return NULL; + if (! (openDocFileURL = CFBundleCopyResourceURL(appBundle, fileName, NULL, + NULL))) return NULL; + + //Get file reference from Core Foundation URL + if (! CFURLGetFSRef( openDocFileURL, &fileRef )) return NULL; + + //dispose of the CF variables + CFRelease(openDocFileURL); + CFRelease(fileName); + + //convert FSRef to FSSpec + if (FSGetCatalogInfo(&fileRef, kFSCatInfoNone, NULL, NULL, &fileSpec, + NULL)) return NULL; + + //create path string + if (! (path = malloc(kMaxPathLength))) return NULL; + if (FSMakePath(fileSpec, path, kMaxPathLength)) return NULL; + if (! DoesFileExist(path)) return NULL; + + return path; +} + +#pragma mark - + +///////////////////////////////////// +// Load menu bar from nib +///////////////////////////////////// +OSErr LoadMenuBar (char *appName) +{ + OSErr err; + IBNibRef nibRef; + + if (err = CreateNibReference(CFSTR("MenuBar"), &nibRef)) return err; + if (err = SetMenuBarFromNib(nibRef, CFSTR("MenuBar"))) return err; + DisposeNibReference(nibRef); + + return noErr; +} + +#pragma mark - + +/////////////////////////////////////// +// Generate path string from FSSpec record +/////////////////////////////////////// +static OSStatus FSMakePath(FSSpec file, char *path, long maxPathSize) +{ + OSErr err = noErr; + FSRef fileRef; + + //create file reference from file spec + if (err = FSpMakeFSRef(&file, &fileRef)) return err; + + // and then convert the FSRef to a path + return FSRefMakePath(&fileRef, path, maxPathSize); +} + +//////////////////////////////////////// +// Standard red error alert, then exit application +//////////////////////////////////////// +static void RedFatalAlert (Str255 errorString, Str255 expStr) +{ + StandardAlert(kAlertStopAlert, errorString, expStr, NULL, NULL); + ExitToShell(); +} + +/////////////////////////////////////// +// Determines whether file exists at path or not +/////////////////////////////////////// +static short DoesFileExist (char *path) +{ + if (access(path, F_OK) == -1) return false; + return true; +} + +#pragma mark - + +/////////////////////////////////////// +// Apple Event handler for Quit i.e. from +// the dock or Application menu item +/////////////////////////////////////// +static OSErr AppQuitAEHandler(const AppleEvent *theAppleEvent, + AppleEvent *reply, long refCon) +{ + #pragma unused (reply, refCon, theAppleEvent) + + while (numArgs > 0) free(fileArgs[numArgs--]); + + if (! taskDone && pid) { //kill the script process brutally + kill(pid, 9); + printf("Platypus App: PID %d killed brutally\n", pid); + } + + pthread_cancel(tid); + if (odtid) pthread_cancel(odtid); + + ExitToShell(); + + return noErr; +} + +///////////////////////////////////// +// Handler for docs dragged on app icon +///////////////////////////////////// +static OSErr AppOpenDocAEHandler(const AppleEvent *theAppleEvent, + AppleEvent *reply, long refCon) +{ + #pragma unused (reply, refCon) + + OSErr err = noErr; + AEDescList fileSpecList; + AEKeyword keyword; + DescType type; + + short i; + long count, actualSize; + + FSSpec fileSpec; + char path[kMaxPathLength]; + + while (numArgs > 0) free(fileArgs[numArgs--]); + + //Read the AppleEvent + err = AEGetParamDesc(theAppleEvent, keyDirectObject, typeAEList, + &fileSpecList); + + err = AECountItems(&fileSpecList, &count); //Count number of files + + for (i = 1; i <= count; i++) { //iteratively process each file + //get fsspec from apple event + if (! (err = AEGetNthPtr(&fileSpecList, i, typeFSS, &keyword, &type, + (Ptr)&fileSpec, sizeof(FSSpec), &actualSize))) + { + //get path from file spec + if ((err = FSMakePath(fileSpec, (unsigned char *)&path, + kMaxPathLength))) return err; + + if (numArgs == kMaxArgumentsToScript) break; + + if (! (fileArgs[numArgs] = malloc(kMaxPathLength))) return true; + + strcpy(fileArgs[numArgs++], (char *)&path); + } + else return err; + } + + if (! taskDone) pthread_create(&odtid, NULL, OpenDoc, NULL); + else pthread_create(&tid, NULL, Execute, NULL); + + return err; +} + +/////////////////////////////// +// Handler for clicking on app icon +/////////////////////////////// +static OSErr AppOpenAppAEHandler(const AppleEvent *theAppleEvent, + AppleEvent *reply, long refCon) +{ + #pragma unused (reply, refCon, theAppleEvent) + + // the app has been opened without any items dragged on to it + pthread_create(&tid, NULL, Execute, NULL); + + return noErr; +} + + +static void OpenURL(Str255 url) +{ + // Use Internet Config to hand the URL to the appropriate application, as + // set by the user in the Internet Preferences pane. + ICInstance icInstance; + // Applications creator code: + OSType signature = 'Inks'; + OSStatus error = ICStart( &icInstance, signature ); + if ( error == noErr ) + { + ConstStr255Param hint = 0x0; + const char* data = url; + long length = strlen(url); + long start = 0; + long end = length; + // Don't bother testing return value (error); launched application will + // report problems. + ICLaunchURL( icInstance, hint, data, length, &start, &end ); + ICStop( icInstance ); + } +} + + +////////////////////////////////// +// Handler for when X11 fails to start +////////////////////////////////// +static OSStatus X11FailedHandler(EventHandlerCallRef theHandlerCall, + EventRef theEvent, void *userData) +{ + #pragma unused(theHanderCall, theEvent, userData) + + pthread_join(tid, NULL); + if (odtid) pthread_join(odtid, NULL); + + SInt16 itemHit; + const char *getX11 = "\pGet X11 for Panther"; + + AlertStdAlertParamRec params; + params.movable = true; + params.helpButton = false; + params.filterProc = NULL; + params.defaultText = (StringPtr) kAlertDefaultOKText; + params.cancelText = getX11; + params.otherText = NULL; + params.defaultButton = kAlertStdAlertOKButton; + params.cancelButton = kAlertStdAlertCancelButton; + params.position = kWindowDefaultPosition; + + StandardAlert(kAlertStopAlert, "\pFailed to start X11", + "\pInkscape.app requires Apple's X11, which is freely downloadable from Apple's website for Panther (10.3.x) users and available as an optional install from the installation DVD for Tiger (10.4.x) users.\n\nPlease install X11 and restart Inkscape.", + ¶ms, &itemHit); + + if (itemHit == kAlertStdAlertCancelButton) + { + OpenURL("http://www.apple.com/downloads/macosx/apple/x11formacosx.html"); + } + + ExitToShell(); + + + return noErr; +} diff --git a/packaging/macosx/ScriptExec/openDoc b/packaging/macosx/ScriptExec/openDoc new file mode 100755 index 000000000..2242173e7 --- /dev/null +++ b/packaging/macosx/ScriptExec/openDoc @@ -0,0 +1,4 @@ +#!/bin/sh + + +echo $1; \ No newline at end of file diff --git a/packaging/macosx/ScriptExec/script b/packaging/macosx/ScriptExec/script new file mode 100755 index 000000000..2242173e7 --- /dev/null +++ b/packaging/macosx/ScriptExec/script @@ -0,0 +1,4 @@ +#!/bin/sh + + +echo $1; \ No newline at end of file diff --git a/packaging/macosx/ScriptExec/version.plist b/packaging/macosx/ScriptExec/version.plist new file mode 100644 index 000000000..a29320186 --- /dev/null +++ b/packaging/macosx/ScriptExec/version.plist @@ -0,0 +1,16 @@ + + + + + BuildVersion + 17 + CFBundleShortVersionString + 0.1 + CFBundleVersion + 0.1 + ProjectName + NibPBTemplates + SourceVersion + 1150000 + + diff --git a/packaging/osx-app.sh b/packaging/osx-app.sh new file mode 100644 index 000000000..954ccb9fc --- /dev/null +++ b/packaging/osx-app.sh @@ -0,0 +1,231 @@ +#! /bin/bash +# Copyright 2005, Kees Cook +# Licensed under GNU General Public License +# +# Usage: osx-app [-s] /path/to/bin/inkscape Info.plist /path/to/packaging/macosx +# +# This attempts to build an Inkscape.app package for OSX, resolving +# Dynamic libraries, etc. Strips the executable and libraries if +# '-s' is given. +# +# Thanks to GNUnet's "build_app" script for help with library dep resolution. +# https://gnunet.org/svn/GNUnet/contrib/OSX/build_app +# +# Fixes and modifications to use Gimp.app style launcher: +# Michael Wybrow +# +# +# Notes: +# The Info.plist file can be found in the base inkscape directory once +# configure has been run. +# The macosx directory is in the inkscape/packaging directory. +# +# When packaging Inkscape for OS X, configure should be run with the +# "--enable-osxapp" option which sets the correct paths for support +# files inside the app bundle. +# +# Thus, the usual use of this file would be to run it from the within the +# inkscape/packaging directory, substituting in the inkscape binary path: +# ./osx-app.sh /path/to/bin/inkscape ../Info.plist macosx + + + +# Handle some version specific details. +VERSION=`/usr/bin/sw_vers | grep ProductVersion | cut -f2 -d'.'` +if [ "$VERSION" -ge "4" ]; then + # We're on Tiger (10.4) or later. + # XCode behaves a little differently in Tiger and later. + XCODEFLAGS="-configuration Deployment" + SCRIPTEXECDIR="ScriptExec/build/Deployment/ScriptExec.app/Contents/MacOS" + # libXinerama.1.dylib is not installed as part of X11 on Panther but + # is introduced as a dependency if Inkscape is compiled on Tiger or + # later. Thus, add the library to the bundle for Panther users + EXTRALIBS="/usr/X11R6/lib/libXinerama.1.dylib" +else + # Panther (10.3) or earlier. + XCODEFLAGS="-buildstyle Deployment" + SCRIPTEXECDIR="ScriptExec/build/ScriptExec.app/Contents/MacOS" + EXTRALIBS="" +fi + + +SW=/sw + +# Package always has the same name. Version information is stored in +# the Info.plist file which is filled in by the configure script. +pkg=Inkscape +package="$pkg.app" + +# TODO: Rewrite handling of command line args and make more robust. + +strip=false +if [ "$1" = "-s" ]; then + strip=true + shift +fi + +binary="$1" +if [ ! -x "$binary" ]; then + echo "Not executable: $binary" >&2 + exit 1 +fi +shift + +plist="$1" +if [ ! -f "$plist" ]; then + echo "Need plist file" >&2 + exit 1 +fi +shift + +resdir=$1 +if [ ! -d $resdir ]; then + echo "Need the macosx packaging directory" >&2 + exit 1 +fi +shift + +# Fix a given executable or library to be relocatable +fixlib () { +if [ ! -d "$1" ]; then + echo $1 + libs="`otool -L $1 | fgrep compatibility | cut -d\( -f1`" + for lib in $libs; do + echo " $lib" + base=`echo $lib | awk -F/ '{print $NF}'` + first=`echo $lib | cut -d/ -f1-3` + to=@executable_path/../lib/$base + if [ $first != /usr/lib -a $first != /usr/X11R6 ]; then + /usr/bin/install_name_tool -change $lib $to $1 + if [ "`echo $lib | fgrep libcrypto`" = "" ]; then + /usr/bin/install_name_tool -id $to ../lib/$base + for ll in $libs; do + base=`echo $ll | awk -F/ '{print $NF}'` + first=`echo $ll | cut -d/ -f1-3` + to=@executable_path/../lib/$base + if [ $first != /usr/lib -a $first != /usr/X11R6 -a "`echo $ll | fgrep libcrypto`" = "" ]; then + /usr/bin/install_name_tool -change $ll $to ../lib/$base + fi + done + fi + fi + done +fi +} + + + +mkdir -p "$package"/Contents/MacOS +mkdir -p "$package"/Contents/Resources/bin +mkdir -p "$package"/Contents/Resources/lib +mkdir -p "$package"/Contents/Resources/locale + +binname=`basename "$binary"` +binpath="$package/Contents/Resources/bin/inkscape-bin" + +cp "$binary" "$binpath" + + +# Build and add the launcher. +( + # Build fails if CC happens to be set (to anything other than CompileC) + unset CC + + cd "$resdir/ScriptExec" + xcodebuild $XCODEFLAGS clean build +) +cp "$resdir/$SCRIPTEXECDIR/ScriptExec" "$package/Contents/MacOS/Inkscape" + +# Pull down all the share files +binary_dir=`dirname "$binary"` +rsync -av "$binary_dir/../share/$binname"/* "$package/Contents/Resources/" +cp "$plist" "$package/Contents/Info.plist" +rsync -av "$binary_dir/../share/locale"/* "$package/Contents/Resources/locale" + +# PkgInfo must match bundle type and creator code from Info.plist +echo "APPLInks" > $package/Contents/PkgInfo + +# Pull in extra requirements. +pkgetc="$package/Contents/Resources/etc" +mkdir -p $pkgetc/pango +cp $SW/etc/pango/pangox.aliases $pkgetc/pango/ +# Need to adjust path and quote incase of spaces in path. +sed -e "s,$SW,\"\${CWD},g" -e 's,\.so ,.so" ,g' $SW/etc/pango/pango.modules > $pkgetc/pango/pango.modules +cat > $pkgetc/pango/pangorc < $pkgetc/gtk-2.0/gdk-pixbuf.loaders +sed -e "s,$SW,\${CWD},g" $SW/etc/gtk-2.0/gtk.immodules > $pkgetc/gtk-2.0/gtk.immodules + +for item in gnome-vfs-mime-magic gnome-vfs-2.0 +do + cp -r $SW/etc/$item $pkgetc/ +done + +pkglib="$package/Contents/Resources/lib" +mkdir -p $pkglib/pango/1.4.0/modules +cp $SW/lib/pango/1.4.0/modules/*.so $pkglib/pango/1.4.0/modules/ + +mkdir -p $pkglib/gtk-2.0/2.4.0/{engines,immodules,loaders} +cp -r $SW/lib/gtk-2.0/2.4.0/engines/* $pkglib/gtk-2.0/2.4.0/engines/ +cp $SW/lib/gtk-2.0/2.4.0/immodules/*.so $pkglib/gtk-2.0/2.4.0/immodules/ +cp $SW/lib/gtk-2.0/2.4.0/loaders/*.so $pkglib/gtk-2.0/2.4.0/loaders/ + +mkdir -p $pkglib/gnome-vfs-2.0/modules +cp $SW/lib/gnome-vfs-2.0/modules/*.so $pkglib/gnome-vfs-2.0/modules/ + +# Find out libs we need from fink (e.g. $SW) - loop until no changes +a=1 +nfiles=0 +endl=true +while $endl; do + echo "Looking for dependencies. Round " $a + libs="`otool -L $pkglib/gtk-2.0/2.4.0/loaders/* $pkglib/gtk-2.0/2.4.0/immodules/* $pkglib/gtk-2.0/2.4.0/engines/*.so $pkglib/pango/1.4.0/modules/* $pkglib/gnome-vfs-2.0/modules/* $package/Contents/Resources/lib/* $binary 2>/dev/null | fgrep compatibility | cut -d\( -f1 | grep $SW | sort | uniq`" + cp -f $libs $package/Contents/Resources/lib + let "a+=1" + nnfiles=`ls $package/Contents/Resources/lib | wc -l` + if [ $nnfiles = $nfiles ]; then + endl=false + else + nfiles=$nnfiles + fi +done + +for libfile in $EXTRALIBS +do + cp -f $libfile $package/Contents/Resources/lib +done + +if [ "$strip" = "true" ]; then + strip -x "$package"/Contents/Resources/lib/*.dylib + strip -ur "$binpath" +fi + +# NOTE: This works for all the dylibs but causes GTK to crash at startup. +# Instead we leave them with their original install_names and set +# DYLD_LIBRARY_PATH within the app bundle before running Inkscape. +# +# Fix package deps +#(cd "$package/Contents/MacOS/bin" +# for file in *; do +# fixlib "$file" +# done +# cd ../lib +# for file in *; do +# fixlib "$file" +# done) + +# Get all the icons and the rest of the script framework +rsync -av $resdir/Resources/* $package/Contents/Resources/ + + +# Make an image +/usr/bin/hdiutil create -srcfolder "$pkg.app" "$pkg.dmg" diff --git a/packaging/win32/english.nsh b/packaging/win32/english.nsh new file mode 100644 index 000000000..cc607eb02 --- /dev/null +++ b/packaging/win32/english.nsh @@ -0,0 +1,154 @@ +; ####################################### +; english.nsh +; english language strings for inkscape installer +; windows code page: 1252 +; Authors: +; Adib Taraben theAdib@yahoo.com +; +!insertmacro MUI_LANGUAGE "English" + +; Product name +LangString lng_Caption ${LANG_ENGLISH} "${PRODUCT_NAME} -- Open Source Scalable Vector Graphics Editor" + +; Button text "Next >" for the license page +LangString lng_LICENSE_BUTTON ${LANG_ENGLISH} "Next >" + +; Bottom text for the license page +LangString lng_LICENSE_BOTTOM_TEXT ${LANG_ENGLISH} "$(^Name) is released under the GNU General Public License (GPL). The license is provided here for information purposes only. $_CLICK" + +; Full install type +LangString lng_Full $(LANG_ENGLISH) "Full" + +; Optimal install type +LangString lng_Optimal $(LANG_ENGLISH) "Optimal" + +; Minimal install type +LangString lng_Minimal $(LANG_ENGLISH) "Minimal" + +; Core install section +LangString lng_Core $(LANG_ENGLISH) "${PRODUCT_NAME} SVG Editor (required)" + +; Core install section description +LangString lng_CoreDesc $(LANG_ENGLISH) "Core ${PRODUCT_NAME} files and dlls" + +; GTK+ install section +LangString lng_GTKFiles $(LANG_ENGLISH) "GTK+ Runtime Environment (required)" + +; GTK+ install section description +LangString lng_GTKFilesDesc $(LANG_ENGLISH) "A multi-platform GUI toolkit, used by ${PRODUCT_NAME}" + +; shortcuts install section +LangString lng_Shortcuts $(LANG_ENGLISH) "Shortcuts" + +; shortcuts install section description +LangString lng_ShortcutsDesc $(LANG_ENGLISH) "Shortcuts for starting ${PRODUCT_NAME}" + +; All user install section +LangString lng_Alluser $(LANG_ENGLISH) "for all users" + +; All user install section description +LangString lng_AlluserDesc $(LANG_ENGLISH) "Install this application for anyone who uses this computer (all users)" + +; Desktop section +LangString lng_Desktop $(LANG_ENGLISH) "Desktop" + +; Desktop section description +LangString lng_DesktopDesc $(LANG_ENGLISH) "Create a shortcut to ${PRODUCT_NAME} on the Desktop" + +; Start Menu section +LangString lng_Startmenu $(LANG_ENGLISH) "Start Menu" + +; Start Menu section description +LangString lng_StartmenuDesc $(LANG_ENGLISH) "Create a Start Menu entry for ${PRODUCT_NAME}" + +; Quick launch section +LangString lng_Quicklaunch $(LANG_ENGLISH) "Quick Launch" + +; Quick launch section description +LangString lng_QuicklaunchDesc $(LANG_ENGLISH) "Create a shortcut to ${PRODUCT_NAME} on the Quick Launch toolbar" + +; File type association for editing +LangString lng_SVGWriter ${LANG_ENGLISH} "Open SVG files with ${PRODUCT_NAME}" + +; File type association for editing description +LangString lng_SVGWriterDesc ${LANG_ENGLISH} "Select ${PRODUCT_NAME} as default editor for SVG files" + +; Context Menu +LangString lng_ContextMenu ${LANG_ENGLISH} "Context Menu" + +; Context Menu description +LangString lng_ContextMenuDesc ${LANG_ENGLISH} "Add ${PRODUCT_NAME} into the Context Menu for SVG files" + + +; Additional files section +LangString lng_Addfiles $(LANG_ENGLISH) "Additional Files" + +; Additional files section description +LangString lng_AddfilesDesc $(LANG_ENGLISH) "Additional Files" + +; Examples section +LangString lng_Examples $(LANG_ENGLISH) "Examples" + +; Examples section description +LangString lng_ExamplesDesc $(LANG_ENGLISH) "Examples using ${PRODUCT_NAME}" + +; Tutorials section +LangString lng_Tutorials $(LANG_ENGLISH) "Tutorials" + +; Tutorials section description +LangString lng_TutorialsDesc $(LANG_ENGLISH) "Tutorials using ${PRODUCT_NAME}" + + +; Languages section +LangString lng_Languages $(LANG_ENGLISH) "Translations" + +; Languages section dscription +LangString lng_LanguagesDesc $(LANG_ENGLISH) "Install various translations for ${PRODUCT_NAME}" + +LangString lng_am $(LANG_ENGLISH) "am Amharic" +LangString lng_az $(LANG_ENGLISH) "az Azerbaijani" +LangString lng_be $(LANG_ENGLISH) "be Byelorussian" +LangString lng_ca $(LANG_ENGLISH) "ca Catalan" +LangString lng_cs $(LANG_ENGLISH) "cs Czech" +LangString lng_da $(LANG_ENGLISH) "da Danish" +LangString lng_de $(LANG_ENGLISH) "de German" +LangString lng_el $(LANG_ENGLISH) "el Greek" +LangString lng_en $(LANG_ENGLISH) "en English" +LangString lng_es $(LANG_ENGLISH) "es Spanish" +LangString lng_es_MX $(LANG_ENGLISH) "es_MX Mexican Spanish" +LangString lng_et $(LANG_ENGLISH) "es Estonian" +LangString lng_fr $(LANG_ENGLISH) "fr French" +LangString lng_ga $(LANG_ENGLISH) "ga Irish" +LangString lng_gl $(LANG_ENGLISH) "gl Gallegan" +LangString lng_hu $(LANG_ENGLISH) "hu Hungarian" +LangString lng_it $(LANG_ENGLISH) "it Italian" +LangString lng_ja $(LANG_ENGLISH) "ja Japanese" +LangString lng_mk $(LANG_ENGLISH) "mk Macedonian" +LangString lng_nb $(LANG_ENGLISH) "nb Norwegian Bokmål" +LangString lng_nl $(LANG_ENGLISH) "nl Dutch" +LangString lng_nn $(LANG_ENGLISH) "nn Norwegian Nynorsk" +LangString lng_pa $(LANG_ENGLISH) "pa Panjabi" +LangString lng_pl $(LANG_ENGLISH) "po Polish" +LangString lng_pt $(LANG_ENGLISH) "pt Portuguese" +LangString lng_pt_BR $(LANG_ENGLISH) "pt_BR Brazilian Portuguese" +LangString lng_ru $(LANG_ENGLISH) "ru Russian" +LangString lng_sk $(LANG_ENGLISH) "sk Slovak" +LangString lng_sl $(LANG_ENGLISH) "sl Slovenian" +LangString lng_sr $(LANG_ENGLISH) "sr Serbian" +LangString lng_sr@Latn $(LANG_ENGLISH) "sr@Latn Serbian in Latin script" +LangString lng_sv $(LANG_ENGLISH) "sv Swedish" +LangString lng_tr $(LANG_ENGLISH) "tr Turkish" +LangString lng_uk $(LANG_ENGLISH) "uk Ukrainian" +LangString lng_zh_CN $(LANG_ENGLISH) "zh_CH Simplifed Chinese" + + + + +; uninstallation options +LangString lng_UInstOpt ${LANG_ENGLISH} "Uninstallation Options" + +; uninstallation options subtitle +LangString lng_UInstOpt1 ${LANG_ENGLISH} "Please make your choices for additional options" + +; Ask to purge the personal preferences +LangString lng_PurgePrefs ${LANG_ENGLISH} "Keep personal Preferences" diff --git a/packaging/win32/german.nsh b/packaging/win32/german.nsh new file mode 100644 index 000000000..33d8c72ac --- /dev/null +++ b/packaging/win32/german.nsh @@ -0,0 +1,158 @@ +; ####################################### +; german.nsh +; german language strings for inkscape installer +; windows code page: 1252 +; Authors: +; Adib Taraben theAdib@yahoo.com +; +!insertmacro MUI_LANGUAGE "German" + +; Product name +LangString lng_Caption ${LANG_GERMAN} "${PRODUCT_NAME} -- Open Source SVG-Vektorillustrator" + +; Button text "Next >" for the license page +LangString lng_LICENSE_BUTTON ${LANG_GERMAN} "Weiter >" + +; Bottom text for the license page +LangString lng_LICENSE_BOTTOM_TEXT ${LANG_GERMAN} "$(^Name) wird unter der GNU General Public License (GPL) veröffentlicht. Die Lizenz dient hier nur der Information. $_CLICK" + +; Full install type +LangString lng_Full $(LANG_GERMAN) "Komplett" + +; Optimal install type +LangString lng_Optimal $(LANG_GERMAN) "Optimal" + +; Minimal install type +LangString lng_Minimal $(LANG_GERMAN) "Minimal" + + +; Core section +LangString lng_Core $(LANG_GERMAN) "${PRODUCT_NAME} Vektorillustrator (erforderlich)" + +; Core section description +LangString lng_CoreDesc $(LANG_GERMAN) "${PRODUCT_NAME} Basis-Dateien und -DLLs" + + +; GTK+ section +LangString lng_GTKFiles $(LANG_GERMAN) "GTK+ Runtime Umgebung (erforderlich)" + +; GTK+ section description +LangString lng_GTKFilesDesc $(LANG_GERMAN) "Ein Multi-Plattform GUI Toolkit, verwendet von ${PRODUCT_NAME}" + + +; shortcuts section +LangString lng_Shortcuts $(LANG_GERMAN) "Verknüpfungen" + +; shortcuts section description +LangString lng_ShortcutsDesc $(LANG_GERMAN) "Verknüpfungen zum Start von ${PRODUCT_NAME}" + +; multi user installation +LangString lng_Alluser ${LANG_GERMAN} "für Alle Benutzer" + +; multi user installation description +LangString lng_AlluserDesc ${LANG_GERMAN} "Installiert diese Anwendung für alle Benutzer dieses Computers (all users)" + +; Start Menu section +LangString lng_Startmenu $(LANG_GERMAN) "Startmenü" + +; Start Menu section description +LangString lng_StartmenuDesc $(LANG_GERMAN) "Erstellt einen Eintrag für ${PRODUCT_NAME} im Startmenü" + +; Desktop section +LangString lng_Desktop $(LANG_GERMAN) "Desktop" + +; Desktop section description +LangString lng_DesktopDesc $(LANG_GERMAN) "Erstellt eine Verknüpfung zu ${PRODUCT_NAME} auf dem Desktop" + +; Quick launch section +LangString lng_Quicklaunch $(LANG_GERMAN) "Schnellstartleiste" + +; Quick launch section description +LangString lng_QuicklaunchDesc $(LANG_GERMAN) "Erstellt eine Verknüpfung zu ${PRODUCT_NAME} auf der Schnellstartleiste" + +; File type association for editing +LangString lng_SVGWriter ${LANG_GERMAN} "Öffne SVG Dateien mit ${PRODUCT_NAME}" + +;LangString lng_UseAs ${LANG_ENGLISH} "Select ${PRODUCT_NAME} as default application for:" +LangString lng_SVGWriterDesc ${LANG_GERMAN} "Wählen Sie ${PRODUCT_NAME} als Standardanwendung für SVG Dateien" + +; Context Menu +LangString lng_ContextMenu ${LANG_GERMAN} "Kontext-Menü" + +; Context Menu description +LangString lng_ContextMenuDesc ${LANG_GERMAN} "Fügt ${PRODUCT_NAME} in das Kontext-Menü für SVG Dateien ein" + + +; Additional Files section +LangString lng_Addfiles $(LANG_GERMAN) "weitere Dateien" + +; additional files section dscription +LangString lng_AddfilesDesc $(LANG_GERMAN) "weitere Dateien" + +; Examples section +LangString lng_Examples $(LANG_GERMAN) "Beispiele" + +; Examples section dscription +LangString lng_ExamplesDesc $(LANG_GERMAN) "Beispiele mit ${PRODUCT_NAME}" + +; Tutorials section +LangString lng_Tutorials $(LANG_GERMAN) "Tutorials" + +; Tutorials section dscription +LangString lng_TutorialsDesc $(LANG_GERMAN) "Tutorials für die Benutzung mit ${PRODUCT_NAME}" + + +; Languages section +LangString lng_Languages $(LANG_GERMAN) "Übersetzungen" + +; Languages section dscription +LangString lng_LanguagesDesc $(LANG_GERMAN) "Installiert verschiedene Übersetzungen für ${PRODUCT_NAME}" + +LangString lng_am $(LANG_GERMAN) "am Amharisch" +LangString lng_az $(LANG_GERMAN) "az Aserbaidschanisch" +LangString lng_be $(LANG_GERMAN) "be Weißrussisch" +LangString lng_ca $(LANG_GERMAN) "ca Katalanisch" +LangString lng_cs $(LANG_GERMAN) "cs Tschechisch" +LangString lng_da $(LANG_GERMAN) "da Dänisch" +LangString lng_de $(LANG_GERMAN) "de Deutsch" +LangString lng_el $(LANG_GERMAN) "el Griechisch" +LangString lng_en $(LANG_GERMAN) "en Englisch" +LangString lng_es $(LANG_GERMAN) "es Spanisch" +LangString lng_es_MX $(LANG_GERMAN) "es_MX Spanisch-Mexio" +LangString lng_et $(LANG_GERMAN) "es Estonisch" +LangString lng_fr $(LANG_GERMAN) "fr Französisch" +LangString lng_ga $(LANG_GERMAN) "ga Irisch" +LangString lng_gl $(LANG_GERMAN) "gl Galizisch" +LangString lng_hu $(LANG_GERMAN) "hu Ungarisch" +LangString lng_it $(LANG_GERMAN) "it Italienisch" +LangString lng_ja $(LANG_GERMAN) "ja Japanisch" +LangString lng_mk $(LANG_GERMAN) "mk Mazedonisch" +LangString lng_nb $(LANG_GERMAN) "nb Norwegisch-Bokmal" +LangString lng_nl $(LANG_GERMAN) "nl Holländisch" +LangString lng_nn $(LANG_GERMAN) "nn Nynorsk-Norwegisch" +LangString lng_pa $(LANG_GERMAN) "pa Panjabi" +LangString lng_pl $(LANG_GERMAN) "po Polnisch" +LangString lng_pt $(LANG_GERMAN) "pt Portugiesisch" +LangString lng_pt_BR $(LANG_GERMAN) "pt_BR Portugiesisch Brazilien" +LangString lng_ru $(LANG_GERMAN) "ru Russisch" +LangString lng_sk $(LANG_GERMAN) "sk Slowakisch" +LangString lng_sl $(LANG_GERMAN) "sl Slowenisch" +LangString lng_sr $(LANG_GERMAN) "sr Serbisch" +LangString lng_sr@Latn $(LANG_GERMAN) "sr@Latn Serbisch mit lat. Buchstaben" +LangString lng_sv $(LANG_GERMAN) "sv Schwedisch" +LangString lng_tr $(LANG_GERMAN) "tr Türkisch" +LangString lng_uk $(LANG_GERMAN) "uk Ukrainisch" +LangString lng_zh_CN $(LANG_GERMAN) "zh_CH Chinesisch (vereinfacht)" + + +; uninstallation options +;LangString lng_UInstOpt ${LANG_ENGLISH} "Uninstallation Options" +LangString lng_UInstOpt ${LANG_GERMAN} "Deinstallations Optionen" + +; uninstallation options subtitle +;LangString lng_UInstOpt1 ${LANG_ENGLISH} "Please make your choices for additional options" +LangString lng_UInstOpt1 ${LANG_GERMAN} "Bitte wählen Sie die optionalen Deinstalltionsparameter" + +; Ask to purge the personal preferences +;LangString lng_PurgePrefs ${LANG_ENGLISH} "Keep Inkscape preferences" +LangString lng_PurgePrefs ${LANG_GERMAN} "behalte persönliche Inkscape-Vorgaben" diff --git a/packaging/win32/header.bmp b/packaging/win32/header.bmp new file mode 100644 index 0000000000000000000000000000000000000000..26e863ec49a5aa1f121e82df24433ec47f5fb60c GIT binary patch literal 25818 zcmc&-caYxIbwz+A0>L&$W{kl$8G>z`;CRf$2^pMV8&hKli6<}t#4sjKoFTzu5ZKrf zG9dbD)mW8PU6oZ?^+f_zR9N)_+xxDz_onSyDd*gK-}}AqlMpiEOEjPGs__TM_r80| zz53Bli=MbZzI`A6{1(2a;QKB3KJ0=olxNH= zUpcdURciUF*_CVNRIHg>xpw}sbqkKIPdk>muqty=)rQ4Y8+O4Z}omsLCc3(Eg$Y_`Dkxz_P*Af18unn+j0-J=O1p*Khj=s zw7uxV_M(qEO0qjjb2>}&I?M9A%JaJ_3cD(cjvp&NeyrqpRatj+S$AzkPhDkC{jr|< zs@{g`-o~1~rrO@-y1tf%zShS6wx<5Jmj3pZ{?4|6uC~Fh_QCGX6Wv{dJzXbyyHE7> z4E6O6_4f@84xGg2#EDZUhfbb6dFnjAoe9I7q-U}xMi}N!`EBmh=kul!Mglnfh5YH` z3ugWyf7XiyvtBMFhOYp_!a2mSNHI)%t2k|9$wFW_$zeFPG<{mx(v-60)5})OD9e~p zzH$~m6{}}guAWm#4Chr6!v(TP0MRGEwA2^QL~j8)+&bYudUkw z4A<8K!(GI%{)2acVdGwp;nv3e4#UH{nhy(xgmF)6wqm%yE%!iM-a%qmaHPHPXh-3P z9Yr5?7H4;s0K;6tus|{Fsw9Tp)ur7vJbcko9g-$>pQ4E{=J6Z-h zfMGj6gU34vW6yD7*ed`I^b3ZA#BgZn)Mt-jHtKNVGdYvSaalSuyF2cg>zpon)gQW{5Ol!-YQv`RI)G`by&(eoLrhdwQT9MGSuPn zl=9^>%2&)R&j5z0z_4QVTw=HmbvWPZP%+%Fqj9VkmV83_E}!04&YxD$DCC zCx*ve9d=ih9j`7&9d_5E4)HMz`eC89wBB{e-sl(F6 zlS4qY$xb$BSM!(w9CQ34EeJInJs ziD7|a*j=T)lyyi9>%v}&I*fYhKwC3<=|D#-da2Z5=OBBj)FCiLFGU@)6bDZZoj3^$ zPkrXS6m^)LJSN+{hfyy@9lBncPYlsZqxTSXSTv6q%6o`9)WuNY-JtdgZJ<-dMVz+4q%A)P%!K&Qw-gESS7ub@1eBQ0K;B; z59?8f{jGQpn+F_*Y^2ADq4mK8hdvXM7LQNb$i~<7OIp57|qj z_YfHJJ$y;u!=gE_6wZBB-@{_eG^j)LQa96R9Y(zrb(k@;0(FR9x(dD2-b3xB7j#;6P(_h?%C3GtEH%Nz~zqLC!P@s6+Hp z)*&!_R^LPP(p-+FcnoDOojx9Qm><+((QM46z|eYW@dC^=NyT^%7f+J+kiAqe#7vV? zCKwXN(=bFS&L97b8<}JN_eX#8y=}86`I$yAbaSa-$R`nX=w=$j5OXOpL>+1`RD(nWo+KQa*_sXnZdn>JKYE|td++~OT_i!Aoi zM&lM+h#}v@9r!4Q?4?IPXmuE(4uxAB1C2batq%}GucaxA4(nCOd}Y2eyDRPW*X%doJ;o$KLoeH zTpG+Y$}NN+VlD-S#w~~;dTA;7A?QV2rNC(XP88hR;YZCC3kE8qB46;1-IZ^wNkQ8isEG!=eRAP>x@_Z4Ewk+wmT&MfTDiPN&(e93L|cI6k-q>#$MlP~OAl!vY{?nwVZ1a(s+6 z_0ONsMM1olDV6g^&qu1jomdNN!=hG@tx1;uiWILTe+(*O`Vwn`mw6!QTnoVolY5b6LX*kmy zXs1piy%cq*It^!NKLY5koiAKx>QV7Q*rQ9*WjBgi=h@ zdq|yzda0jF2_Pj?)7m)G2)8JhZ8MGVL(yr-EilkvE;YT>aSJrkK&Ns1uykeWZQr{o z4y&{OaQMX+KmNeIAFfWLPNN*(^itNL>!sxQz))uzq4{_ZvoO=Nh}I@L4eQYBG&<8z zry+*1dTAxNMM*cFM6Z|DRf1bkF9kV_(@RyS;Y>qr5kJ!yw}4p6UYeLXgai(Lm`x0g zTaZ}bBRUP|QqfBTjxRF}WbaTf1%{|Y=%q_0iRMkc6m?imZlRjD=`_$w-$@>ScF@lF zt57~R__~Br0cciu9J>*=PxH|N{g`Z1B^Hy@m zUh24o&ZQHI=vxrO;(4OeNFC~XNUcrhQtCA1ht%5aJp_!icg%S8=5PJ^8BzMgpByoK z__W_YBU;^(2JQR%V*5_?SKFCZMO^?HtZ9zI?Hc({uhs# zUP^wbIt}&GCTQLV@Gsnm0IptWHDgBA96$$0vrOwXqHp;5}(C4c|k~rR=3{rkO$SNqh@c6;z!6VCbdd zJ?UIZ-vV_g?;+|?dg-Cm*Z=dM?!0v5h;zZ`6MxU&efOr4jVtPQ2*(%yut9pM`WDc< zr4D5-jnhjVx4=xJda395#w}DYMG?{iHvbSFFntRQG&0k$6!kr9fKJ1i#`IEnz*>jo z7H!1PdMUUCJz&-XP(|Jbo(Gcq#n zz4zXa`y*et{7-kKy$#<29ACAz2K5j3;7L@SW{c`H|;N>^7EIU4$DOs zU3B~Hw7|;*i1#g2r;$7jdMUIvHL^OarfPKUv?SdTA$|Ig%=L{?v3Ag>d^lj2B~xVGk^818(w|-$-+&m)j!l+TNB9dabQNa&3~Q5q{`r8ucwC)MnljxdpNq3DerBc^if~!VjgF z3b(*mIFcWz*u*Y6rRV#Kc=|F?=A z8-kg}-b1goMHo^qbyDw#jIii5xrdmEqJJpfll0QSw-65)bE$BAGl12% zkc@DTV90DD-@|%fXmzOBL_Ud@iDECcj4;DAd=IIYCMb&`#De~z`W8}$;yrOF#V5>S z_?gDuL(DXJb6$JwjvvGgE@%1AoX}tT)#HyShRC&f&70hU7*g|g`O?E3l5698Sdyb2 zaF^rwE)#{ZM)IZlB$DG-2RU!?4>8j)=dHOm&NLoFUx(y}&}lRiCB8*sda2Abk@qCr z!f9>ROCh%@$5)-k-a}~Kd2?SIIsD>;B6IHl@(E8rX&hfOQ7(%Ctxe`q`WDb>RP)ws zVkfhS>L1#BNRBV>q0FVo)4&53ZV@xn@ICZ(h`H4AG}PK6ZZSlTZ||Y{`1GF6Z!kSm zHj#}q<~@8qS2%tyb8SwiVOF0WaFE5oduX|~@7-|Sx&LQQ=ALW1$i2`Go#*>an>BHUspcV-y%7T>~h-qhNn zd}*9c!)&6{+H_}z`xcUkVk5-|L4D16*Yq%7s@%e9-j?%bFQw)kW)pp`4ZT#~!-UMG zHz&tgFHrUxAOhxGAXzSMF21#dlZ&ksKn96t5G@e=S_Z?2##-asmo%}w_p}SeG9=5z0`7Tcn?*lVK3D@P0@n4iqeuE`N^%H8iDit zgI~GoOZ!$XRISZr^`#DDxP^L8Zg)+y`bF8;d-Ct0WTKe!?t)&byKADCdVc779;-%=2GeJv84!0#Ts(kNo5Z z=UG&L)E_5+84G0Z2{~`)U*djuz6457R+MkOrsvKaD2_v=u8vskS0iL!+RL;V@qp8V(?e;)_Iwbx#I%{AA2-1vIM6<7G*f9IWd zc64<3AAZ~y0C3;(dGsyz>HeYl7MAlyDT>x+`O=(y<^cmn?pt82k=-?U57j^PSqztn zQr|-Op?FWkF!T>ShEj+9;^Rw3*!5DM)yF_X?@2W8gzR!lo@NZQiE&z+?94DDOs&m0 zzVbu(_~u(U&D-Tmkxis;flnNaU;XM=YiepBQPkDd9XfOCdwQm(30Q!*JhXCwvR;J#l9y$|gDtZQnw58qL$hdB6dNn#Ita z8NUbY^QD+eC5s{a5Lx{}*_qLtx4wtM@%_$>WHAzkp>PY~hrzyu?LE0{qV3FRMp$$j zpD(qXH@v4P*M_L~qj&y82*u4e-`w5Z?dR&8oE*h%+_-W0$tRzD5;ky2NeR9NjNu=Q z`}*puM(tTThgl5z_{a#y)M4b~$L>8j411@)n5XDvn`9k9a5jwXD@a6Qr=WxFQtj^viiB;_~zpWS{pOM zaoj?)iO58WP9r|PXl=5)W;>*A-$MLD!BDg|;rOz<1`K7U@p&5Cw@A?L8g^zJhA~-v zYTf`)-b2f^fmpm;Fo)ig`G;Y6ZN!rr}m0c?mN0ZdQTe5u^UU>$N{hPO?a5%xNbVHnd(541t{Ru5Qw3(0wN zAD@{h=1XI8ZI;D=*2cZ3xH?28N(jE>+Mu<$Y+|H&pUy3qYfGHw9cpd9mvWceWull( zbl#JzL!WDtof+(q`h5${Vz`Vjqu!(My3H37zDP|?^>D3Rxzc}q`WG+0_@e)V1aJue zbXk4b<(6EVWP}w%>~gF3#Jd=>`lQ^#&otb(0L?$bxzzdi@*WaH?WOh}>TQ#1moK%s zlzYIT))shA!tv=n1-(>rZ93D4)`mJv#4fk?QWZ=6{vm8&!BF>r0}q%OhPgJ*rMiC@ z>~fdM-V?GI*tfuK6Rcc}zAF;rh7TXUWy_Y+5sUko$&)7s0A883cxG_hME3FZrh@IR zNgXm11-(@Fo?>Pi^Pb=zx;MvcHwP=RhA&t4IAepGmdKUv)n`9H2^Ok&R z9EMR=-}WsWKXe>F=%t$T=A9_jyv=*^TAS|U^Dc&FF*@Kq$xOrDHFr}X;1=Q^+DwxG z|4=efB71ubnN3vxP_(vaA0Ijm>QJ&6Zl;kNL%IiSId8YSX17gvQ(?tS*#n*x!g&4l z*Ecmag}C{z)6&u|yzoK=TmYQT+a@@TfyFhwi-CM81{#@Z!n+tQPop{wZkx!yh24o# z57^y_5`M^xFlQQO6FtY*nTCtpgWi0V)@Z?2Kr9xxgyG34r#WD}iE zW19CVo~Su5(fdquX~YlxTuQA??_%JlLR=+mg!wuw$-J2QSRb$d@-Uy~iu zm8qle{*kZ7TW`I!udmNTr(Y~zzWm~g%~U3U3sZQnO)=yiu(#KqE6v;62gDuS8Z~_MYTUl;yl*@}=hE`<)r_50TYp zHqr7lT8DD4O~Nz@ys6;d!=Mgz{}3~c?&HViX)IrAS{r5>3^Y2^2!>jR{>G5IZ6bFu zaO-Q;?9ul`Fh2b7!{Prg*R5NJ*D|WWw727LeMLK@dMC=?Ydbw(>gv!kQGRDeF;tyK z=Tdl2elCqN!Y*GLWc8!nHDE}NPtBVqzTSz#V`$!!&ZXG5@Vne{p9a}PL~0UHhn!1g zhZK9j<^dy{h)+J~g}jG;E_FJM?LG0fiTM_|xu^GO+zzSTiJC6=+N2KMeHxq@8hy`? zeKkJ#;Dc>#Z6{8gNJ>f?InvH#paMTw@HXz#U>{$OCdy3(Wc9;+3+}GP@I%Kf{GBN7 z0ejyqJ4bKrRb$WR-ai6 z#xW%7Z96k@o#&7H;hB4>aeU}B!Vhs^NO~z|8pAO1fL#^?y%aD;9(?)IhJO=K^{Z4=pDYjhYk z;oO&G^=;pRH-<3KoIcZt;Eg;@kS`T}=saL|bC2E=xCQrs={@oGCGJE8Sq$U&{>G5j zq1)vSa^C76>JF*b+Wt7u;(qs;F^tKV!nZK*i5N;R<^9qyU&>xey)?R;$bEdt>PH-( z7?N8EhL~x1`;s??aKBVOo2;>$3T&iu zpT=(Psn$l0Z#i#w>npm8;dC0G5q7(4un@^DWGHnxZ@IZAGYtR~&0FVE-WZ}@D!I0p z-L)uRik!FGw{RXX0F1arB5#}64yoKW@%L$LE(L}%)5K*lOs5gORQRE0^)Z*?P849Y zyNP;J0eiq@+~uBG;qFAC4)uO%<@&VDUvei(bQ-Bc-2;|fTa-BX@*@du>{WI@3fL+U^?PL&xz`%A}X# z2Cda0@0aQw;d!_t3=DaLHgjQR=AxamCsy$WE$)}ELAel(W`nJC#I6%UyE z_`Hk3OqA~9dkpCxQu9vO4yn6e8gYF09@<mE3}^-n<--A?`%gY|}f!cCXFuCdzv#yK8d4 z)cnI3z0`KOgImyop~0v=KJ%rLiGp5=nMVA>;MSMChmPaBT$}R`<&H43`s5bg1D0Hy zatp7QS~d}R8o8U8n0w_wPd?7%Q1d=K?*VtA8X-oxl7d$_yC$B<|D?B<@{81h+tyVnMeZ+fX_^||*H zW}>>OdD8>NeHz}}3;aXd0}l3{cnjLJwt(Z~J>)%ay=@ZZOB0dvmYeK)a}V6Y?OQml zE!wxxThQJEw!J5J>r45e-t!J-nq_j69i=F@FL762?s)@4y#>vi?7Sn)UW&&sUGM7i zEW2P>yH)NcZqvJo>v>Z_bQ<1*=1m2E`%*-j=so2Aq0kG-wYmE=aW@qtPviW<({3to zht%yKDz|X=OFchyx4twJC3C5Gz_B`wX7!y1oS>{eFtm)Y8Xx~ev4*g99-FuS18$oWHFq7}#~<*vT&0o%?DeSF!s(EBuc&pQD+jo#G{e0=ajp8Jwal-Js1 zXNEV~CD#_|rPfQ4P2>$)Jcgu*?&hBArFakV_ggrv&CR8_$sTjhd*c#+&zsyrXBw~5 z$n8tLo7k{RIX?b=i|EFXzniEzZ)Ej-FO9t;O#hG^Uw7AHc1SVM#APv=`@~OSQbNe*FJ-6;{O6qS8NLa literal 0 HcmV?d00001 diff --git a/packaging/win32/inkscape.nsi b/packaging/win32/inkscape.nsi new file mode 100644 index 000000000..ff22af02e --- /dev/null +++ b/packaging/win32/inkscape.nsi @@ -0,0 +1,1055 @@ +; ####################################### +; Inkscape NSIS installer project file +; Used as of 0.40 +; ####################################### + +; ####################################### +; DEFINES +; ####################################### +!define PRODUCT_NAME "Inkscape" +!define PRODUCT_VERSION "0.43+devel" +!define PRODUCT_PUBLISHER "Inkscape Organization" +!define PRODUCT_WEB_SITE "http://www.inkscape.org" +!define PRODUCT_DIR_REGKEY "Software\Microsoft\Windows\CurrentVersion\App Paths\inkscape.exe" +!define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" + + + +; ####################################### +; MUI SETTINGS +; ####################################### +; MUI 1.67 compatible ------ +SetCompressor /SOLID lzma +!include "MUI.nsh" +!include "sections.nsh" +!define MUI_ABORTWARNING +!define MUI_ICON "${NSISDIR}\Contrib\Graphics\Icons\modern-install.ico" +!define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\modern-uninstall.ico" +!define MUI_HEADERIMAGE +!define MUI_HEADERIMAGE_BITMAP "header.bmp" +!define MUI_COMPONENTSPAGE_SMALLDESC + + +; Welcome page +!insertmacro MUI_PAGE_WELCOME +; License page +; !define MUI_LICENSEPAGE_RADIOBUTTONS +LicenseForceSelection off +!define MUI_LICENSEPAGE_BUTTON $(lng_LICENSE_BUTTON) +!define MUI_LICENSEPAGE_TEXT_BOTTOM $(lng_LICENSE_BOTTOM_TEXT) +!insertmacro MUI_PAGE_LICENSE "..\..\Copying" +!insertmacro MUI_PAGE_COMPONENTS +; InstType $(lng_Full) +; InstType $(lng_Optimal) +; InstType $(lng_Minimal) +; Directory page +!insertmacro MUI_PAGE_DIRECTORY +; Instfiles page +!insertmacro MUI_PAGE_INSTFILES +; Finish page +!define MUI_FINISHPAGE_RUN "$INSTDIR\inkscape.exe" +!insertmacro MUI_PAGE_FINISH + +; Uninstaller pages +!insertmacro MUI_UNPAGE_CONFIRM +UninstPage custom un.CustomPageUninstall +!insertmacro MUI_UNPAGE_INSTFILES +ShowUninstDetails hide +!insertmacro MUI_UNPAGE_FINISH + +; ####################################### +; STRING LOCALIZATION +; ####################################### +; Thanks to Adib Taraben and Luca Bruno for getting this started +; Add your translation here! :-) +; I had wanted to list the languages alphabetically, but apparently +; the first is the default. So putting English first is just being +; practical. It is not chauvinism or hubris, I swear! ;-) +; default language first + +; Language files +!include "english.nsh" +;!include "catalan.nsh" +;!include "czech.nsh" +;!include "french.nsh" +!include "german.nsh" +;!include "italian.nsh" +;!include "polish.nsh" + +ReserveFile "inkscape.nsi.uninstall" + + +; ####################################### +; SETTINGS +; ####################################### + +Name "${PRODUCT_NAME} ${PRODUCT_VERSION}" +Caption $(lng_Caption) +OutFile "Inkscape-${PRODUCT_VERSION}-1.win32.exe" +InstallDir "$PROGRAMFILES\Inkscape" +InstallDirRegKey HKLM "${PRODUCT_DIR_REGKEY}" "" +ShowInstDetails hide +ShowUnInstDetails hide + +var askMultiUser +Var MultiUser + +; ####################################### +; I N S T A L L E R S E C T I O N S +; ####################################### + +; Turn off old selected section +; GetWindowsVersion +; +; Based on Yazno's function, http://yazno.tripod.com/powerpimpit/ +; Updated by Joost Verburg +; Updated for Windows 98 SE by Matthew Win Tibbals 5-21-03 +; +; Returns on top of stack +; +; Windows Version (95, 98, ME, NT x.x, 2000, XP, 2003) +; or +; '' (Unknown Windows Version) +; +; Usage: +; Call GetWindowsVersion +; Pop $R0 +; ; at this point $R0 is "NT 4.0" or whatnot +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +Function GetWindowsVersion + + Push $R0 + Push $R1 + + ClearErrors + + ReadRegStr $R0 HKLM "SOFTWARE\Microsoft\Windows NT\CurrentVersion" CurrentVersion + + IfErrors 0 lbl_winnt + + ; we are not NT + ReadRegStr $R0 HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion" VersionNumber + + StrCpy $R1 $R0 1 + StrCmp $R1 '4' 0 lbl_error + + StrCpy $R1 $R0 3 + + StrCmp $R1 '4.0' lbl_win32_95 + StrCmp $R1 '4.9' lbl_win32_ME lbl_win32_98 + + lbl_win32_95: + StrCpy $R0 '95' + StrCpy $AskMultiUser "0" + Goto lbl_done + + lbl_win32_98: + StrCpy $R0 '98' + StrCpy $AskMultiUser "0" + Goto lbl_done + lbl_win32_ME: + StrCpy $R0 'ME' + StrCpy $AskMultiUser "0" + Goto lbl_done + + lbl_winnt: + + StrCpy $R1 $R0 1 + + StrCmp $R1 '3' lbl_winnt_x + StrCmp $R1 '4' lbl_winnt_x + + StrCpy $R1 $R0 3 + + StrCmp $R1 '5.0' lbl_winnt_2000 + StrCmp $R1 '5.1' lbl_winnt_XP + StrCmp $R1 '5.2' lbl_winnt_2003 lbl_error + + lbl_winnt_x: + StrCpy $R0 "NT $R0" 6 + Goto lbl_done + + lbl_winnt_2000: + Strcpy $R0 '2000' + Goto lbl_done + + lbl_winnt_XP: + Strcpy $R0 'XP' + Goto lbl_done + + lbl_winnt_2003: + Strcpy $R0 '2003' + Goto lbl_done + + lbl_error: + Strcpy $R0 '' + lbl_done: + + Pop $R1 + Exch $R0 + +FunctionEnd + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + ; StrStr + ; input, top of stack = string to search for + ; top of stack-1 = string to search in + ; output, top of stack (replaces with the portion of the string remaining) + ; modifies no other variables. + ; + ; Usage: + ; Push "this is a long ass string" + ; Push "ass" + ; Call StrStr + ; Pop $R0 + ; ($R0 at this point is "ass string") + + Function StrStr + Exch $R1 ; st=haystack,old$R1, $R1=needle + Exch ; st=old$R1,haystack + Exch $R2 ; st=old$R1,old$R2, $R2=haystack + Push $R3 + Push $R4 + Push $R5 + StrLen $R3 $R1 + StrCpy $R4 0 + ; $R1=needle + ; $R2=haystack + ; $R3=len(needle) + ; $R4=cnt + ; $R5=tmp + loop: + StrCpy $R5 $R2 $R3 $R4 + StrCmp $R5 $R1 done + StrCmp $R5 "" done + IntOp $R4 $R4 + 1 + Goto loop + done: + StrCpy $R1 $R2 "" $R4 + Pop $R5 + Pop $R4 + Pop $R3 + Pop $R2 + Exch $R1 + FunctionEnd + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + ; GetParameters + ; input, none + ; output, top of stack (replaces, with e.g. whatever) + ; modifies no other variables. + + Function GetParameters + + Push $R0 + Push $R1 + Push $R2 + Push $R3 + + StrCpy $R2 1 + StrLen $R3 $CMDLINE + + ;Check for quote or space + StrCpy $R0 $CMDLINE $R2 + StrCmp $R0 '"' 0 +3 + StrCpy $R1 '"' + Goto loop + StrCpy $R1 " " + + loop: + IntOp $R2 $R2 + 1 + StrCpy $R0 $CMDLINE 1 $R2 + StrCmp $R0 $R1 get + StrCmp $R2 $R3 get + Goto loop + + get: + IntOp $R2 $R2 + 1 + StrCpy $R0 $CMDLINE 1 $R2 + StrCmp $R0 " " get + StrCpy $R0 $CMDLINE "" $R2 + + Pop $R3 + Pop $R2 + Pop $R1 + Exch $R0 + + FunctionEnd + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; GetParameterValue +; Chris Morgan 5/10/2004 +; -Updated 4/7/2005 to add support for retrieving a command line switch +; and additional documentation +; +; Searches the command line input, retrieved using GetParameters, for the +; value of an option given the option name. If no option is found the +; default value is placed on the top of the stack upon function return. +; +; This function can also be used to detect the existence of just a +; command line switch like /OUTPUT Pass the default and "OUTPUT" +; on the stack like normal. An empty return string "" will indicate +; that the switch was found, the default value indicates that +; neither a parameter or switch was found. +; +; Inputs - Top of stack is default if parameter isn't found, +; second in stack is parameter to search for, ex. "OUTPUT" +; Outputs - Top of the stack contains the value of this parameter +; So if the command line contained /OUTPUT=somedirectory, "somedirectory" +; will be on the top of the stack when this function returns +; +; Register usage +;$R0 - default return value if the parameter isn't found +;$R1 - input parameter, for example OUTPUT from the above example +;$R2 - the length of the search, this is the search parameter+2 +; as we have '/OUTPUT=' +;$R3 - the command line string +;$R4 - result from StrStr calls +;$R5 - search for ' ' or '"' + +Function GetParameterValue + Exch $R0 ; get the top of the stack(default parameter) into R0 + Exch ; exchange the top of the stack(default) with + ; the second in the stack(parameter to search for) + Exch $R1 ; get the top of the stack(search parameter) into $R1 + + ;Preserve on the stack the registers used in this function + Push $R2 + Push $R3 + Push $R4 + Push $R5 + + Strlen $R2 $R1+2 ; store the length of the search string into R2 + + Call GetParameters ; get the command line parameters + Pop $R3 ; store the command line string in R3 + + # search for quoted search string + StrCpy $R5 '"' ; later on we want to search for a open quote + Push $R3 ; push the 'search in' string onto the stack + Push '"/$R1=' ; push the 'search for' + Call StrStr ; search for the quoted parameter value + Pop $R4 + StrCpy $R4 $R4 "" 1 ; skip over open quote character, "" means no maxlen + StrCmp $R4 "" "" next ; if we didn't find an empty string go to next + + # search for non-quoted search string + StrCpy $R5 ' ' ; later on we want to search for a space since we + ; didn't start with an open quote '"' we shouldn't + ; look for a close quote '"' + Push $R3 ; push the command line back on the stack for searching + Push '/$R1=' ; search for the non-quoted search string + Call StrStr + Pop $R4 + + ; $R4 now contains the parameter string starting at the search string, + ; if it was found +next: + StrCmp $R4 "" check_for_switch ; if we didn't find anything then look for + ; usage as a command line switch + # copy the value after /$R1= by using StrCpy with an offset of $R2, + # the length of '/OUTPUT=' + StrCpy $R0 $R4 "" $R2 ; copy commandline text beyond parameter into $R0 + # search for the next parameter so we can trim this extra text off + Push $R0 + Push $R5 ; search for either the first space ' ', or the first + ; quote '"' + ; if we found '"/output' then we want to find the + ; ending ", as in '"/output=somevalue"' + ; if we found '/output' then we want to find the first + ; space after '/output=somevalue' + Call StrStr ; search for the next parameter + Pop $R4 + StrCmp $R4 "" done ; if 'somevalue' is missing, we are done + StrLen $R4 $R4 ; get the length of 'somevalue' so we can copy this + ; text into our output buffer + StrCpy $R0 $R0 -$R4 ; using the length of the string beyond the value, + ; copy only the value into $R0 + goto done ; if we are in the parameter retrieval path skip over + ; the check for a command line switch + +; See if the parameter was specified as a command line switch, like '/output' +check_for_switch: + Push $R3 ; push the command line back on the stack for searching + Push '/$R1' ; search for the non-quoted search string + Call StrStr + Pop $R4 + StrCmp $R4 "" done ; if we didn't find anything then use the default + StrCpy $R0 "" ; otherwise copy in an empty string since we found the + ; parameter, just didn't find a value + +done: + Pop $R5 + Pop $R4 + Pop $R3 + Pop $R2 + Pop $R1 + Exch $R0 ; put the value in $R0 at the top of the stack +FunctionEnd + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +!macro Language polng lng + SectionIn 1 2 3 + SetOutPath $INSTDIR + File /nonfatal /a "..\..\inkscape\*.${lng}.txt" + SetOutPath $INSTDIR\locale + File /nonfatal /a /r "..\..\inkscape\locale\${polng}" + SetOutPath $INSTDIR\lib\locale + File /nonfatal /a /r "..\..\inkscape\lib\locale\${polng}" + SectionGetFlags ${SecTutorials} $R1 + IntOp $R1 $R1 & ${SF_SELECTED} + IntCmp $R1 ${SF_SELECTED} 0 skip_tutorials + SetOutPath $INSTDIR\share\tutorials + File /nonfatal /a "..\..\inkscape\share\tutorials\*.${lng}.*" + skip_tutorials: +!macroend + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + + + +;-------------------------------- +; Installer Sections + +Section -removeInkscape + ; check for an old installation and clean that dlls and stuff + ClearErrors + IfFileExists $INSTDIR\etc 0 doDeleteLib + DetailPrint "$INSTDIR\etc exists, will be removed" + RmDir /r $INSTDIR\etc + IfErrors 0 +4 + DetailPrint "fatal: failed to delete $INSTDIR\etc" + DetailPrint "aborting installation" + Abort + doDeleteLib: + + ClearErrors + IfFileExists $INSTDIR\lib 0 doDeleteLocale + DetailPrint "$INSTDIR\lib exists, will be removed" + RmDir /r $INSTDIR\lib + IfErrors 0 +4 + DetailPrint "fatal: failed to delete $INSTDIR\lib" + DetailPrint "aborting installation" + Abort + doDeleteLocale: + + ClearErrors + IfFileExists $INSTDIR\locale 0 doDeleteDll + DetailPrint "$INSTDIR\locale exists, will be removed" + RmDir /r $INSTDIR\locale + IfErrors 0 +4 + DetailPrint "fatal: failed to delete $INSTDIR\locale" + DetailPrint "aborting installation" + Abort + doDeleteDll: + + ClearErrors + FindFirst $0 $1 $INSTDIR\*.dll + FindNextLoop: + StrCmp $1 "" FindNextDone + DetailPrint "$INSTDIR\$1 exists, will be removed" + Delete $INSTDIR\$1 + IfErrors 0 +4 + DetailPrint "fatal: failed to delete $INSTDIR\$1" + DetailPrint "aborting installation" + Abort + FindNext $0 $1 + Goto FindNextLoop + FindNextDone: +SectionEnd + +Section $(lng_Core) SecCore + + DetailPrint "Installing Inkscape Core Files ..." + + SectionIn 1 2 3 RO + SetOutPath $INSTDIR + SetOverwrite on + SetAutoClose false + + File /a "..\..\inkscape\ink*.exe" + File /a "..\..\inkscape\AUTHORS" + File /a "..\..\inkscape\COPYING" + File /a "..\..\inkscape\COPYING.LIB" + File /a "..\..\inkscape\NEWS" + File /a "..\..\inkscape\HACKING.txt" + File /a "..\..\inkscape\README" + File /a "..\..\inkscape\TRANSLATORS" + File /nonfatal /a /r "..\..\inkscape\data" + File /nonfatal /a /r "..\..\inkscape\doc" + File /nonfatal /a /r "..\..\inkscape\plugins" + File /nonfatal /a /r /x *.??*.???* /x "examples" /x "tutorials" "..\..\inkscape\share" + SetOutPath $INSTDIR\modules + File /nonfatal /a /r "..\..\inkscape\modules\*.*" + + +SectionEnd + +Section $(lng_GTKFiles) SecGTK + + DetailPrint "Installing GTK Files ..." + + SectionIn 1 2 3 RO + SetOutPath $INSTDIR + SetOverwrite on + File /a /r "..\..\inkscape\*.dll" + File /a /r /x "locale" "..\..\inkscape\lib" + File /a /r "..\..\inkscape\etc" +SectionEnd + +Section $(lng_Alluser) SecAlluser + ; disable this option in Win95/Win98/WinME + SectionIn 1 2 3 + StrCpy $MultiUser "1" +SectionEnd + +SectionGroup $(lng_Shortcuts) SecShortcuts + +Section $(lng_Desktop) SecDesktop + SectionIn 1 2 3 + CreateShortCut "$DESKTOP\Inkscape.lnk" "$INSTDIR\inkscape.exe" +SectionEnd + +Section $(lng_Quicklaunch) SecQuicklaunch + SectionIn 1 2 3 + StrCmp $QUICKLAUNCH $TEMP +2 + CreateShortCut "$QUICKLAUNCH\Inkscape.lnk" "$INSTDIR\inkscape.exe" +SectionEnd + +Section $(lng_SVGWriter) SecSVGWriter + SectionIn 1 2 3 + ; create file associations, test before if needed + DetailPrint "creating file associations" + ReadRegStr $0 HKCR ".svg" "" + StrCmp $0 "" 0 +3 + WriteRegStr HKCR ".svg" "" "svgfile" + WriteRegStr HKCR "svgfile" "" "Scalable Vector Graphics file" + ReadRegStr $0 HKCR ".svgz" "" + StrCmp $0 "" 0 +3 + WriteRegStr HKCR ".svgz" "" "svgfile" + WriteRegStr HKCR "svgfile" "" "Scalable Vector Graphics file" + + DetailPrint "creating default editor" + ClearErrors + ReadRegStr $0 HKCR ".svg" "" + WriteRegStr HKCR "$0\shell\edit\command" "" '"$INSTDIR\Inkscape.exe" "%1"' + ReadRegStr $0 HKCR ".svgz" "" + WriteRegStr HKCR "$0\shell\edit\command" "" '"$INSTDIR\Inkscape.exe" "%1"' + IfErrors 0 +2 + DetailPrint "Uups! Problems creating default editor" +SectionEnd + +Section $(lng_ContextMenu) SecContextMenu + SectionIn 1 2 3 + ; create file associations, test before if needed + DetailPrint "creating file associations" + ReadRegStr $0 HKCR ".svg" "" + StrCmp $0 "" 0 +3 + WriteRegStr HKCR ".svg" "" "svgfile" + WriteRegStr HKCR "svgfile" "" "Scalable Vector Graphics file" + ReadRegStr $0 HKCR ".svgz" "" + StrCmp $0 "" 0 +3 + WriteRegStr HKCR ".svgz" "" "svgfile" + WriteRegStr HKCR "svgfile" "" "Scalable Vector Graphics file" + + DetailPrint "creating context menue" + ClearErrors + ReadRegStr $0 HKCR ".svg" "" + WriteRegStr HKCR "$0\shell\${PRODUCT_NAME}\command" "" '"$INSTDIR\Inkscape.exe" "%1"' + ReadRegStr $0 HKCR ".svgz" "" + WriteRegStr HKCR "$0\shell\${PRODUCT_NAME}\command" "" '"$INSTDIR\Inkscape.exe" "%1"' + IfErrors 0 +2 + DetailPrint "Uups! Problems creating context menue integration" + +SectionEnd + +SectionGroupEnd + +SectionGroup $(lng_Addfiles) SecAddfiles + +Section $(lng_Examples) SecExamples + SectionIn 1 2 + SetOutPath $INSTDIR\share + File /nonfatal /a /r /x "*.??*.???*" "..\..\inkscape\share\examples" +SectionEnd + +Section $(lng_Tutorials) SecTutorials + SectionIn 1 2 + SetOutPath $INSTDIR\share + File /nonfatal /a /r /x "*.??*.???*" "..\..\inkscape\share\tutorials" +SectionEnd + +SectionGroupEnd + +SectionGroup /e $(lng_Languages) SecLanguages + +Section $(lng_am) SecAmharic + !insertmacro Language am am +SectionEnd + +Section $(lng_az) SecAzerbaijani + !insertmacro Language az az +SectionEnd + +Section $(lng_be) SecByelorussian + !insertmacro Language be be +SectionEnd + +Section $(lng_ca) SecCatalan + !insertmacro Language ca ca +SectionEnd + +Section $(lng_cs) SecCzech + !insertmacro Language cs cs +SectionEnd + +Section $(lng_da) SecDanish + !insertmacro Language da da +SectionEnd + +Section $(lng_de) SecGerman + !insertmacro Language 'de' 'de' +SectionEnd + +Section $(lng_el) SecGreek + !insertmacro Language el el +SectionEnd + +Section $(lng_en) SecEnglish + SectionIn 1 2 3 RO +SectionEnd + +Section $(lng_es) SecSpanish + !insertmacro Language 'es' 'es' +SectionEnd + +Section $(lng_es_MX) SecSpanishMexico + !insertmacro Language 'es_MX' 'es_MX' +SectionEnd + +Section $(lng_et) SecEstonian + !insertmacro Language et et +SectionEnd + +Section $(lng_fr) SecFrench + !insertmacro Language 'fr' 'fr' +SectionEnd + +Section $(lng_ga) SecIrish + !insertmacro Language ga ga +SectionEnd + +Section $(lng_gl) SecGallegan + !insertmacro Language gl gl + SectionIn 1 2 3 +SectionEnd + +Section $(lng_hu) SecHungarian + !insertmacro Language hu hu + SectionIn 1 2 3 +SectionEnd + +Section $(lng_it) SecItalian + !insertmacro Language it it + SectionIn 1 2 3 +SectionEnd + +Section $(lng_ja) SecJapanese + !insertmacro Language 'ja' 'jp' +SectionEnd + +Section $(lng_mk) SecMacedonian + !insertmacro Language mk mk +SectionEnd + +Section $(lng_nb) SecNorwegianBokmal + !insertmacro Language nb nb +SectionEnd + +Section $(lng_nl) SecDutch + !insertmacro Language nl nl +SectionEnd + +Section $(lng_nn) SecNorwegianNynorsk + !insertmacro Language nn nn +SectionEnd + +Section $(lng_pa) SecPanjabi + !insertmacro Language pa pa +SectionEnd + +Section $(lng_pl) SecPolish + !insertmacro Language pl pl +SectionEnd + +Section $(lng_pt) SecPortuguese + !insertmacro Language pt pt +SectionEnd + +Section $(lng_pt_BR) SecPortugueseBrazil + !insertmacro Language pt_BR pt_BR +SectionEnd + +Section $(lng_ru) SecRussian + !insertmacro Language ru ru +SectionEnd + +Section $(lng_sk) SecSlovak + !insertmacro Language sk sk +SectionEnd + +Section $(lng_sl) SecSlovenian + !insertmacro Language sl sl +SectionEnd + +Section $(lng_sr) SecSerbian + !insertmacro Language sr sr +SectionEnd + +Section $(lng_sr@Latn) SecSerbianLatin + !insertmacro Language 'sr@Latn' 'sr@Latn' +SectionEnd + +Section $(lng_sv) SecSwedish + !insertmacro Language sv sv +SectionEnd + +Section $(lng_tr) SecTurkish + !insertmacro Language tr tr +SectionEnd + +Section $(lng_uk) SecUkrainian + !insertmacro Language uk uk +SectionEnd + +Section $(lng_zh_CN) SecChineseSimplified + !insertmacro Language zh_CN zh_CN +SectionEnd + +Section -FinalizeInstallation + StrCmp $MultiUser "1" "" SingleUser + DetailPrint "admin mode, registry root will be HKLM" + SetShellVarContext all + Goto endSingleUser + SingleUser: + DetailPrint "single user mode, registry root will be HKCU" + SetShellVarContext current + endSingleUser: + + ; check for writing registry + ClearErrors + WriteRegStr SHCTX "${PRODUCT_DIR_REGKEY}" "" "$INSTDIR\inkscape.exe" + ;IfErrors 0 +4 + ; DetailPrint "fatal: failed to write to ${PRODUCT_DIR_REGKEY}" + ; DetailPrint "aborting installation" + ; Abort + WriteRegStr SHCTX "${PRODUCT_DIR_REGKEY}" "MultiUser" "$MultiUser" + WriteRegStr SHCTX "${PRODUCT_DIR_REGKEY}" "askMultiUser" "$askMultiUser" + + ; start menu entries + CreateDirectory "$SMPROGRAMS\Inkscape" + CreateShortCut "$SMPROGRAMS\Inkscape\Inkscape.lnk" "$INSTDIR\inkscape.exe" + CreateShortCut "$SMPROGRAMS\Inkscape\Uninstall Inkscape.lnk" "$INSTDIR\uninst.exe" + + ; uninstall settings + WriteUninstaller "$INSTDIR\uninst.exe" + WriteRegExpandStr SHCTX "${PRODUCT_UNINST_KEY}" "UninstallString" '"$INSTDIR\uninst.exe"' + WriteRegExpandStr SHCTX "${PRODUCT_UNINST_KEY}" "InstallLocation" "$INSTDIR" + WriteRegStr SHCTX "${PRODUCT_UNINST_KEY}" "DisplayName" "${PRODUCT_NAME} ${PRODUCT_VERSION}" + WriteRegStr SHCTX "${PRODUCT_UNINST_KEY}" "DisplayIcon" "$INSTDIR\Inkscape.exe,0" + WriteRegStr SHCTX "${PRODUCT_UNINST_KEY}" "DisplayVersion" "${PRODUCT_VERSION}" + WriteRegDWORD SHCTX "${PRODUCT_UNINST_KEY}" "NoModify" "1" + WriteRegDWORD SHCTX "${PRODUCT_UNINST_KEY}" "NoRepair" "1" +SectionEnd + +SectionGroupEnd + +; Last the Descriptions +!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN + !insertmacro MUI_DESCRIPTION_TEXT ${SecCore} $(lng_CoreDesc) + !insertmacro MUI_DESCRIPTION_TEXT ${SecGTK} $(lng_GTKFilesDesc) + !insertmacro MUI_DESCRIPTION_TEXT ${SecShortcuts} $(lng_ShortcutsDesc) + !insertmacro MUI_DESCRIPTION_TEXT ${SecAlluser} $(lng_AlluserDesc) + !insertmacro MUI_DESCRIPTION_TEXT ${SecDesktop} $(lng_DesktopDesc) + !insertmacro MUI_DESCRIPTION_TEXT ${SecQuicklaunch} $(lng_QuicklaunchDesc) + !insertmacro MUI_DESCRIPTION_TEXT ${SecSVGWriter} $(lng_SVGWriterDesc) + !insertmacro MUI_DESCRIPTION_TEXT ${SecContextMenu} $(lng_ContextMenuDesc) + !insertmacro MUI_DESCRIPTION_TEXT ${SecAddfiles} $(lng_AddfilesDesc) + !insertmacro MUI_DESCRIPTION_TEXT ${SecExamples} $(lng_ExamplesDesc) + !insertmacro MUI_DESCRIPTION_TEXT ${SecTutorials} $(lng_TutorialsDesc) + !insertmacro MUI_DESCRIPTION_TEXT ${SecLanguages} $(lng_LanguagesDesc) +!insertmacro MUI_FUNCTION_DESCRIPTION_END + +!macro Parameter key Section + Push ${key} + Push "" + Call GetParameterValue + Pop $1 + StrCmp $1 "OFF" 0 +5 + SectionGetFlags ${Section} $0 + IntOp $2 ${SF_SELECTED} ~ + IntOp $0 $0 & $2 + SectionSetFlags ${Section} $0 + StrCmp $1 "ON" 0 +4 + SectionGetFlags ${Section} $0 + IntOp $0 $0 | ${SF_SELECTED} + SectionSetFlags ${Section} $0 +!macroend + +Function .onInit + ;Extract InstallOptions INI files + StrCpy $AskMultiUser "1" + StrCpy $MultiUser "0" + ; this resets AskMultiUser if Win95/98/ME + Call GetWindowsVersion + Pop $R0 + DetailPrint "detected operating system $R0" + ;MessageBox MB_OK "operating system: $R0; AskMultiuser: $AskMultiUser" + + ; hide all user section if win98 + StrCmp $AskMultiUser "1" +2 + SectionSetText ${SecAlluser} "" + + ; hide if quick launch if not available + StrCmp $QUICKLAUNCH $TEMP 0 +2 + SectionSetText ${SecQuicklaunch} "" + + ; proccess command line parameter + !insertmacro Parameter "GTK" ${SecGTK} + !insertmacro Parameter "SHORTCUTS" ${secShortcuts} + !insertmacro Parameter "ALLUSER" ${SecAlluser} + !insertmacro Parameter "DESKTOP" ${SecDesktop} + !insertmacro Parameter "QUICKLAUNCH" ${SecQUICKlaunch} + !insertmacro Parameter "SVGEDITOR" ${SecSVGWriter} + !insertmacro Parameter "CONTEXTMENUE" ${SecContextMenu} + !insertmacro Parameter "ADDFILES" ${SecAddfiles} + !insertmacro Parameter "EXAMPLES" ${SecExamples} + !insertmacro Parameter "TUTORIALS" ${SecTutorials} + !insertmacro Parameter "LANGUAGES" ${SecLanguages} + !insertmacro Parameter "am" ${SecAmharic} + !insertmacro Parameter "az" ${SecAzerbaijani} + !insertmacro Parameter "be" ${SecByelorussian} + !insertmacro Parameter "ca" ${SecCatalan} + !insertmacro Parameter "cs" ${SecCzech} + !insertmacro Parameter "da" ${SecDanish} + !insertmacro Parameter "de" ${SecGerman} + !insertmacro Parameter "el" ${SecGreek} + !insertmacro Parameter "es" ${SecSpanish} + !insertmacro Parameter "es_MX" ${SecSpanishMexico} + !insertmacro Parameter "et" ${SecEstonian} + !insertmacro Parameter "fr" ${SecFrench} + !insertmacro Parameter "ga" ${SecIrish} + !insertmacro Parameter "gl" ${SecGallegan} + !insertmacro Parameter "hu" ${SecHungarian} + !insertmacro Parameter "it" ${SecItalian} + !insertmacro Parameter "ja" ${SecJapanese} + !insertmacro Parameter "mk" ${SecMacedonian} + !insertmacro Parameter "nb" ${SecNorwegianBokmal} + !insertmacro Parameter "nl" ${SecDutch} + !insertmacro Parameter "nn" ${SecNorwegianNynorsk} + !insertmacro Parameter "pa" ${SecPanjabi} + !insertmacro Parameter "pl" ${SecPolish} + !insertmacro Parameter "pt" ${SecPortuguese} + !insertmacro Parameter "pt_BR" ${SecPortugueseBrazil} + !insertmacro Parameter "ru" ${SecRussian} + !insertmacro Parameter "sk" ${SecSlovak} + !insertmacro Parameter "sl" ${SecSlovenian} + !insertmacro Parameter "sr" ${SecSerbian} + !insertmacro Parameter "sr@Latn" ${SecSerbianLatin} + !insertmacro Parameter "sv" ${SecSwedish} + !insertmacro Parameter "tr" ${SecTurkish} + !insertmacro Parameter "uk" ${SecUkrainian} + !insertmacro Parameter "zh_CN" ${SecChineseSimplified} + + Push "?" + Push "TEST" + Call GetParameterValue + Pop $1 + StrCmp $1 "TEST" +3 + MessageBox MB_OK "possible parameters for installer:$\r$\n \ + /?: this help screen$\r$\n \ + /S: silent$\r$\n \ + /D=(directory): where to install inkscape$\r$\n \ + /GTK=(OFF/ON): GTK+ Runtime environment$\r$\n \ + /SHORTCUTS=(OFF/ON): shortcuts to start inkscape$\r$\n \ + /ALLUSER=(OFF/ON): for all users on the computer$\r$\n \ + /DESKTOP=(OFF/ON): Desktop icon$\r$\n \ + /QUICKLAUNCH=(OFF/ON): quick launch icon$\r$\n \ + /SVGEDITOR=(OFF/ON): default SVG editor$\r$\n \ + /CONTEXTMENUE=(OFF/ON): context menue integration$\r$\n \ + /ADDFILES=(OFF/ON): additional files$\r$\n \ + /EXAMPLES=(OFF/ON): examples$\r$\n \ + /TUTORIALS=(OFF/ON): tutorials$\r$\n \ + /LANGUAGES=(OFF/ON): translated menues, examples, etc.$\r$\n \ + /[locale code]=(OFF/ON): e.g am, es, es_MX as in Inkscape supported" + Abort +FunctionEnd + +Function .onSelChange +FunctionEnd + +; -------------------------------------------------- + +Function un.CustomPageUninstall + !insertmacro MUI_HEADER_TEXT "$(lng_UInstOpt)" "$(lng_UInstOpt1)" + !insertmacro MUI_INSTALLOPTIONS_WRITE "inkscape.nsi.uninstall" "Field 1" "Text" "$APPDATA\Inkscape\preferences.xml" + !insertmacro MUI_INSTALLOPTIONS_WRITE "inkscape.nsi.uninstall" "Field 2" "Text" "$(lng_PurgePrefs)" + + !insertmacro MUI_INSTALLOPTIONS_DISPLAY "inkscape.nsi.uninstall" + !insertmacro MUI_INSTALLOPTIONS_READ $MultiUser "inkscape.nsi.uninstall" "Field 2" "State" + DetailPrint "keepfiles = $MultiUser" + ;MessageBox MB_OK "adminmode = $MultiUser MultiUserOS = $askMultiUser" + +FunctionEnd + + +Function un.onInit + + StrCpy $askMultiUser "1" + StrCpy $MultiUser "1" + + ; Test if this was a multiuser installation + ReadRegStr $0 HKLM "${PRODUCT_DIR_REGKEY}" "" + StrCmp $0 "$INSTDIR\inkscape.exe" 0 +4 + ReadRegStr $MultiUser HKLM "${PRODUCT_DIR_REGKEY}" "MultiUser" + ReadRegStr $askMultiUser HKLM "${PRODUCT_DIR_REGKEY}" "askMultiUser" + Goto +3 + ReadRegStr $MultiUser HKCU "${PRODUCT_DIR_REGKEY}" "MultiUser" + ReadRegStr $askMultiUser HKCU "${PRODUCT_DIR_REGKEY}" "askMultiUser" + + + !insertmacro MUI_INSTALLOPTIONS_EXTRACT "inkscape.nsi.uninstall" + + ;check whether Multi user installation ? + SetShellVarContext all + StrCmp $MultiUser "0" 0 +2 + SetShellVarContext current + ;MessageBox MB_OK "adminmode = $MultiUser MultiUserOS = $askMultiUser" + +FunctionEnd + +Section Uninstall + + ; remove personal settings + Delete "$APPDATA\Inkscape\extension-errors.log" + StrCmp $MultiUser "0" 0 endPurge ; multiuser assigned in dialog + DetailPrint "purge personal settings in $APPDATA\Inkscape" + RMDir /r "$APPDATA\Inkscape" + endPurge: + + ; Remove file associations for svg editor + DetailPrint "removing file associations for svg editor" + ClearErrors + ReadRegStr $0 HKCR ".svg" "" + DetailPrint ".svg associated as $0" + IfErrors endUninstSVGEdit + ReadRegStr $1 HKCR "$0\shell\edit\command" "" + IfErrors 0 +2 + DetailPrint "svg editor is $1" + StrCmp $1 '"$INSTDIR\Inkscape.exe" "%1"' 0 +3 + DetailPrint "removing default .svg editor" + DeleteRegKey HKCR "$0\shell\edit\command" + DeleteRegKey /ifempty HKCR "$0\shell\edit" + DeleteRegKey /ifempty HKCR "$0\shell" + DeleteRegKey /ifempty HKCR "$0" + endUninstSVGEdit: + + ClearErrors + ReadRegStr $2 HKCR ".svgz" "" + DetailPrint ".svgz associated as $2" + IfErrors endUninstSVGZEdit + ReadRegStr $3 HKCR "$2\shell\edit\command" "" + IfErrors 0 +2 + DetailPrint "svgz editor is $1" + StrCmp $3 '"$INSTDIR\Inkscape.exe" "%1"' 0 +3 + DetailPrint "removing default .svgz editor" + DeleteRegKey HKCR "$2\shell\edit\command" + DeleteRegKey /ifempty HKCR "$2\shell\edit" + DeleteRegKey /ifempty HKCR "$2\shell" + DeleteRegKey /ifempty HKCR "$2" + endUninstSVGZEdit: + + ; Remove file associations for svg editor + DetailPrint "removing file associations for svg editor" + ClearErrors + ReadRegStr $0 HKCR ".svg" "" + IfErrors endUninstSVGView + ReadRegStr $1 HKCR "$0\shell\open\command" "" + IfErrors 0 +2 + DetailPrint "svg viewer is $1" + StrCmp $1 '"$INSTDIR\Inkscape.exe" "%1"' 0 +3 + DetailPrint "removing default .svg viewer" + DeleteRegKey HKCR "$0\shell\open\command" + DeleteRegKey /ifempty HKCR "$0\shell\open" + DeleteRegKey /ifempty HKCR "$0\shell" + DeleteRegKey /ifempty HKCR "$0" + endUninstSVGView: + + ClearErrors + ReadRegStr $2 HKCR ".svgz" "" + IfErrors endUninstSVGZView + ReadRegStr $3 HKCR "$2\shell\open\command" "" + IfErrors 0 +2 + DetailPrint "svgz viewer is $1" + StrCmp $3 '"$INSTDIR\Inkscape.exe" "%1"' 0 +3 + DetailPrint "removing default .svgz viewer" + DeleteRegKey HKCR "$2\shell\open\command" + DeleteRegKey /ifempty HKCR "$2\shell\open" + DeleteRegKey /ifempty HKCR "$2\shell" + DeleteRegKey /ifempty HKCR "$2" + endUninstSVGZView: + + ; Remove file associations for context menue + DetailPrint "removing file associations for svg editor" + ClearErrors + ReadRegStr $0 HKCR ".svg" "" + IfErrors endUninstSVGContext + DetailPrint "removing default .svg context menue" + DeleteRegKey HKCR "$0\shell\${PRODUCT_NAME}" + DeleteRegKey /ifempty HKCR "$0\shell" + DeleteRegKey /ifempty HKCR "$0" + endUninstSVGContext: + + ClearErrors + ReadRegStr $2 HKCR ".svgz" "" + IfErrors endUninstSVGZContext + DetailPrint "removing default .svgzcontext menue" + DeleteRegKey HKCR "$2\shell\${PRODUCT_NAME}" + DeleteRegKey /ifempty HKCR "$2\shell" + DeleteRegKey /ifempty HKCR "$2" + endUninstSVGZContext: + + ReadRegStr $1 HKCR "$0" "" + StrCmp $1 "" 0 +3 + DetailPrint "removing filetype .svg $0" + DeleteRegKey HKCR ".svg" + + ReadRegStr $3 HKCR "$2" "" + StrCmp $3 "" 0 +3 + DetailPrint "removing filetype .svgz $2" + DeleteRegKey HKCR ".svgz" + + + DetailPrint "removing product regkey" + DeleteRegKey SHCTX "${PRODUCT_DIR_REGKEY}" + DetailPrint "removing uninstall info" + DeleteRegKey SHCTX "${PRODUCT_UNINST_KEY}" + + DetailPrint "removing shortcuts" + Delete "$DESKTOP\Inkscape.lnk" + Delete "$QUICKLAUNCH\Inkscape.lnk" + Delete "$SMPROGRAMS\Inkscape\Uninstall Inkscape.lnk" + Delete "$SMPROGRAMS\Inkscape\Inkscape.lnk" + RMDir "$SMPROGRAMS\Inkscape" + + DetailPrint "removing uninstall info" + RMDir /r "$INSTDIR" + + SetAutoClose false + +SectionEnd + diff --git a/packaging/win32/inkscape.nsi.uninstall b/packaging/win32/inkscape.nsi.uninstall new file mode 100644 index 000000000..fde117bca --- /dev/null +++ b/packaging/win32/inkscape.nsi.uninstall @@ -0,0 +1,20 @@ +[Settings] +NumFields=2 + +[Field 1] +Type=label +Text=Display a Message +Left=0 +Right=-1 +Top=10 +Bottom=20 +State=1 + +[Field 2] +Type=checkbox +Text=Display a MessageBox +Left=10 +Right=-1 +Top=25 +Bottom=35 +State=1 \ No newline at end of file diff --git a/po/.cvsignore b/po/.cvsignore new file mode 100644 index 000000000..1e9da51cf --- /dev/null +++ b/po/.cvsignore @@ -0,0 +1,14 @@ +POTFILES +Makefile.in.in +Makefile.in +Makefile +*.gmo +*.mo +*.pot +messages +missing +cat-id-tbl.c +stamp-cat-id +po2tbl.sed +po2tbl.sed.in +.intltool-merge-cache diff --git a/po/ChangeLog b/po/ChangeLog new file mode 100644 index 000000000..516c3d911 --- /dev/null +++ b/po/ChangeLog @@ -0,0 +1,1010 @@ +2004-06-02 a_b + + * sl.po: update from Bostjan Spetic + +2004-05-26 a_b + + * sr.po: update from Urosevic Aleksandar + +2004-05-14 a_b + + * ca.po: update from Xavier Conde Rueda + +2004-05-04 a_b + + * ca.po: update from Xavier Conde Rueda + +2004-04-20 a_b + + * ca.po: update from Xavier Conde Rueda + +2004-04-14 a_b + + * POTFILES.in: added src/extension/internal/eps-out.cpp, + removed src/extension/menu.cpp and src/extension/menu.h + +2004-04-12 a_b + + * es.po: update from Lucas Vieites + +2004-04-11 a_b + + * hu.po: update (a_b) + +2004-04-11 a_b + + * es_MX.po: update from Daniel Díaz + +2004-04-07 buliabyak@users.sf.net + + * ru.po: update from Alex Remizov and myself + +2004-04-06 buliabyak@users.sf.net + + * fr.po: update from f.rodrigo@tuxfamily.org + +2004-04-04 buliabyak@users.sf.net + + * hu.po: another update from Arpad Biro + +2004-03-27 buliabyak@users.sf.net + + * hu.po: update from Arpad Biro + +2004-03-19 buliabyak@users.sf.net + + * ja.po: update from shivaken + +2004-02-20 buliabyak@users.sf.net + + * es.po: update from Lucas Vieites + +2004-02-14 buliabyak@users.sf.net + + * ru.po: update from Alex Remizov + +2004-02-11 buliabyak@users.sf.net + + * fr.po: update from f.rodrigo@tuxfamily.org + +2003-12-21 Peter Moulder + + * POTFILES.in, *.po: Change .c filenames to .cpp. + +2003-09-24 Vincent van Adrighem + + * nl.po: Dutch translation updated by Jeroen van der Vegt. + +2003-09-11 Jordi Mallach + + * ca.po: Updated Catalan translation by + Francesc Dorca . + +2003-09-08 Stanislav Visnovsky + + * sk.po: Updated Slovak translation by Zdenko Podobny . + +2003-08-18 Vincent van Adrighem + + * nl.po: Dutch translation updated. + +2003-08-17 Danilo Å egan + + * sr.po, sr@Latn.po: Added Serbian translation by Serbian + team (Prevod.org). + +2003-08-14 Christophe Merlet + + * fr.po: Updated French translation from + Didier Conchaudron . + +2003-08-06 Christian Rose + + * .cvsignore: Added more entries. + * sv.po: Updated Swedish translation. + +2003-08-05 Christian Rose + + * sv.po: Updated Swedish translation. + +2003-07-29 Stanislav Visnovsky + + * sk.po: Updated Slovak translation by Zdenko Podobny. + +2003-07-28 Duarte Loreto + + * pt.po: Updated Portuguese translation. + +2003-07-28 Artur Flinta + + * pl.po: Updated Polish translation. + +2003-07-27 Artur Flinta + + * pl.po: Updated Polish translation. + +2003-07-24 Pablo Gonzalo del Campo + + * es.po: Updated Spanish translation by + Francisco Javier F. Serrador . + +2003-07-23 Miloslav Trmac + + * cs.po: Updated Czech translation. + +2003-07-23 Dmitry G. Mastrukov + + * be.po: Added Belarusian translation + from Belarusian team . + +2003-07-21 Christian Neumair + + * de.po: Updated German translation, converted encoding to UTF-8. + +2003-07-17 Vincent van Adrighem + + * nl.po: Dutch translation updated. + +2003-07-11 Pablo Gonzalo del Campo + + * es.po: Updated Spanish translation by + Francisco Javier F. Serrador . + +2003-07-09 Yukihiro Nakai + + * ja.po: Update Japanese translation. + * ja.po: Use UTF-8 now. + +2003-07-07 Vincent van Adrighem + + * nl.po: Dutch translation added. + +2003-06-29 Miloslav Trmac + + * cs.po: Updated Czech translation. + +2003-06-28 Valek Filippov + + * ru.po: Updated russian translation. + +2003-06-28 Miloslav Trmac + + * cs.po: Updated Czech translation. + +2003-06-23 Pablo Gonzalo del Campo + + * es.po: Updated Spanish translation by + Francisco Javier F. Serrador . + +2003-06-18 Michal Bukovjan + + * cs.po: Updated Czech translation. + +2003-06-18 Christophe Merlet + + * fr.po: Updated French translation from + Raymond Ostertag . + +2003-06-17 Pablo Gonzalo del Campo + + * es.po: Updated Spanish translation by + Francisco Javier F. Serrador . + +2003-06-12 Abel Cheung + + * POTFILES.in: Added some files under src/modules, and remove + src/helper/kde.cpp + +2003-05-01 Christian Schaller + * no.po: Updated norwegian translation + +2003-03-03 Lauris Kaplinski + + * POTFILES.in: Added src/module.c + +2003-03-03 Alessio Frusciante + + * it.po: Updated Italian translation. + +2002-02-07 Daniel Yacob + + * am.po: Updated Amharic translation. + +2003-02-03 Fatih Demir + + * tr.po: Committed updated Turkish translation by Arman. + +2003-02-03 Daniel Yacob + + * am.po: Updated Amharic translation. + +2003-02-01 Daniel Yacob + + * am.po: Added Amharic translation. + +2003-01-28 gettextize + + * Makefile.in.in: New file, from gettext-0.11.2. + * boldquot.sed: New file, from gettext-0.11.2. + * en@boldquot.header: New file, from gettext-0.11.2. + * en@quot.header: New file, from gettext-0.11.2. + * insert-header.sin: New file, from gettext-0.11.2. + * quot.sed: New file, from gettext-0.11.2. + * remove-potcdate.sin: New file, from gettext-0.11.2. + * Rules-quot: New file, from gettext-0.11.2. + +2003-01-24 Kjartan Maraas + + * no.po: Updated Norwegian translation. + +2003-01-21 German Poo-Caaman~o + + * es.po: Updated Spanish translation by + jose antonio s.a. + +2003-01-19 Raymond Ostertag + + * fr.po: Update translation. + +2003-01-19 Masatake YAMATO + + * ja.po: Updated translation. + +2002-12-21 Stanislav Visnovsky + + * sk.po: Updated Slovak translation by Zdenko Podobny. + +2002-12-09 Stanislav Visnovsky + + * sk.po: Updated Slovak translation by Zdenko Podobny. + +2002-11-28 gettextize + + * Makefile.in.in: New file, from gettext-0.11.2. + * boldquot.sed: New file, from gettext-0.11.2. + * en@boldquot.header: New file, from gettext-0.11.2. + * en@quot.header: New file, from gettext-0.11.2. + * insert-header.sin: New file, from gettext-0.11.2. + * quot.sed: New file, from gettext-0.11.2. + * remove-potcdate.sin: New file, from gettext-0.11.2. + * Rules-quot: New file, from gettext-0.11.2. + +2002-11-28 gettextize + + * Makefile.in.in: Upgrade to gettext-0.11.2. + +2002-11-27 gettextize + + * Makefile.in.in: Upgrade to gettext-0.11.2. + +2002-11-27 gettextize + + * Makefile.in.in: New file, from gettext-0.11.2. + * boldquot.sed: New file, from gettext-0.11.2. + * en@boldquot.header: New file, from gettext-0.11.2. + * en@quot.header: New file, from gettext-0.11.2. + * insert-header.sin: New file, from gettext-0.11.2. + * quot.sed: New file, from gettext-0.11.2. + * remove-potcdate.sin: New file, from gettext-0.11.2. + * Rules-quot: New file, from gettext-0.11.2. + +2002-11-19 Christian Neumair + + * de.po: Updated German translation (quick&dirty release-rework). + +2002-11-17 gettextize + + * Makefile.in.in: Upgrade to gettext-0.10.40. + +2002-11-17 Christophe Merlet + + * fr.po: Updated French translation from work of + Raymond Ostertag . + +Mon Nov 18 00:57:08 2002 Mitsuru Oka + + * ja.po: Updated translation. + +2002-11-17 Lauris Kaplinski + + * ru.po: Updated translation by Vitaly Lipatov + +2002-11-04 Lauris Kaplinski + + * POTFILES.in: Added dialogs/export.c + +2002-10-31 Lauris Kaplinski + + * POTFILES.in: Added src/print.c + +2002-10-29 Lauris Kaplinski + + * ru.po: Update from Vitaly Lipatov + +Sun Oct 13 23:00:13 2002 Mitsuru Oka + + * ja.po: Merged Japanese translation for 0.26 from works of + Junichi Uekawa . + + * ja.po: Updated recent translations too. + +2002-10-10 German Poo-Caaman~o + + * es.po: Updated Spanish translation by + jose antonio s.a. + +2002-10-01 Lauris Kaplinski + + * POTFILES.in: Added src/widgets/font-selector.c + +Sun Sep 29 01:53:59 2002 Mitsuru Oka + + * ja.po: Fixed to save emergency document as English name. + +Mon Sep 23 20:02:45 2002 Mitsuru Oka + + * ja.po: Updated again :) + +2002-09-23 Lauris Kaplinski + + * POTFILES.in: Added src/rect-context.c + +Mon Sep 23 19:15:05 2002 Mitsuru Oka + + * ja.po: Updated Japanese translation.. + +2002-09-21 Lauris Kaplinski + + * ru.po: Updated translation by Vitaly Lipatov + +2002-09-18 Christophe Merlet + + * fr.po: Updated French translation from work of + Raymond Ostertag . + +2002-09-14 Pablo Gonzalo del Campo + + * es.po: Updated spanish translation by Jose Antonio Salgueiro + +2002-09-11 gettextize + + * Makefile.in.in: Upgrade to gettext-0.10.40. + +2002-09-10 Duarte Loreto + + * pt.po: Updated Portuguese translation. + +2002-09-09 Christian Rose + + * sv.po: Updated Swedish translation. + +2002-09-09 Lauris Kaplinski + + * POTFILES.in: Added tool-options.c + +2002-09-08 Lauris Kaplinski + + * POTFILES.in: Added more files + +2002-09-06 Lauris Kaplinski + + * POTFILES.in: Added src/dyna-draw-context.c + +2002-08-28 Lauris Kaplinski + + * POTFILES.in: Added src/dialogs/text-edit.c + +2002-08-26 Kjartan Maraas + + * no.po: Updated Norwegian (bokmÃ¥l) translation. + +2002-08-25 Duarte Loreto + + * pt.po: Updated Portuguese translation. + +2002-08-24 Kjartan Maraas + + * no.po: Updated Norwegian (bokmÃ¥l) translation. + * POTFILES.in: Added missing files. + +2002-08-24 Duarte Loreto + + * pt.po: Updated Portuguese translation. + +2002-07-12 Dmitry G. Mastrukov + + * ru.po: updated Russian translation from Vitaly Lipatov + . + +2002-05-28 Duarte Loreto + + * pt.po: Updated Portuguese translation. + +2002-05-24 Duarte Loreto + + * pt.po: Updated Portuguese translation. + +2002-05-23 Stanislav Visnovsky + + * sk.po: Updated Slovak translation by Zdenko Podobny . + +2002-04-25 Duarte Loreto + + * pt.po: Updated Portuguese translation. + +Wed Apr 10 00:59:46 2002 Mitsuru Oka + + * ja.po: Updated Japanese translation partially. + +2002-03-24 Zbigniew Chyla + + * pl.po: Updated Polish translation by + GNOME PL Team . + +2002-03-17 Wang Jian + + * zh_CN.po: Updated Simplified Chinese translation by + Wang Li . + +2002-03-14 Stanislav Visnovsky + + * sk.po: Added Slovak translation by Zdenko Podobny . + +2002-03-05 Carlos Perello Marin + + * es.po: Updated by José Antonio Salgueiro + +2002-03-03 Christopher R. Gabriel + + * it.po: Updated italian translation from Alessio Frusciante + + +2002-02-28 Duarte Loreto + + * pt.po: Updated Portuguese translation + +2002-02-09 Lauris Kaplinski + + * POTFILES.in: Removed display, document, desktop glade files, + added corresponding c sources + +2002-02-06 Christian Meyer + + * de.po: Updated German translation. + +2002-02-05 Christian Rose + + * sv.po: Updated Swedish translation. + +2002-02-04 Duarte Loreto + + * pt.po: Updated Portuguese translation + +2002-02-02 Kjartan Maraas + + * no.po: Updated Norwegian (bokmÃ¥l) translation. + +2002-02-02 Christophe Merlet + + * fr.po: Updated French translation from work of + Raymond Ostertag . + +2002-01-29 Wang Jian + + * zh_CN.po: Updated Simplified Chinese translation by + Wang Li . + +2002-01-23 Duarte Loreto + + * pt.po: Updated portuguese translation. + +2002-01-21 Christian Rose + + * POTFILES.in: Sorted and added a missing file. + * sv.po: Updated Swedish translation. + +2002-01-13 Wang Jian + + * zh_CN.po: Added Simplified Chinese translation by + Wang Li . + +2002-01-06 Christian Meyer + + * de.po: Updated German translation. + +2002-01-06 Duarte Loreto + + * pt.po: Updated Portuguese translation. + +2002-01-05 Christian Rose + + * sv.po: Updated Swedish translation. + +2002-01-04 Zbigniew Chyla + + * POTFILES.in: Added src/document.c. + + * pl.po: Updated Polish translation by + GNOME PL Team . + +2002-01-03 Zbigniew Chyla + + * pl.po: Updated Polish translation by + GNOME PL Team . + +2002-01-01 Zbigniew Chyla + + * POTFILES.in: + Removed: glade/align.c, glade/desktop.c, glade/display.c, + glade/document.c, glade/item.c, glade/object_props.c, + glade/sodipodi-glade.c, glade/text-dialog.c, glade/toolbox.c, + glade/transformation.c, glade/xml-tree.c. + Added: glade/align.glade, glade/desktop.glade, glade/display.glade, + glade/document.glade, glade/item.glade, glade/object_props.glade, + glade/sodipodi.glade, glade/text-dialog.glade, glade/toolbox.glade, + glade/transformation.glade, glade/xml-tree.glade, + src/dialogs/fill-style.c, src/dialogs/object-attributes.c, + src/dialogs/object-properties.c, src/help.c, src/sp-spiral.c, + src/sp-star.c, sodipodi.desktop.in, GNOME_Sodipodi.oaf.in. + +2002-01-01 Zbigniew Chyla + + * pl.po: Updated Polish translation by + GNOME PL Team . + +2001-12-28 Simos Xenitellis + + * el.po: Added Greek translation. + +2001-12-26 Fatih Demir + + * tr.po: Small correction in the charset field of the po file. + +2001-12-26 Christian Meyer + + * de.po: Updated German translation. + +2001-12-04 German Poo-Caaman~o + + * sv.po: Updated spanish translation from + José Antonio Salgueiro + +2001-11-25 Duarte Loreto + + * Added Alvaro Lopes portuguese translation + +2001-11-24 Valek Filippov + + * ru.po: updated russian translation. + +2001-11-15 Christian Rose + + * sv.po: Updated Swedish translation. + +2001-11-11 Jesus Bravo Alvarez + + * gl.po: Updated Galician translation from + Francisco Xose Vazquez Grandal + +2001-11-05 Christian Rose + + * sv.po: Updated Swedish translation. + +2001-11-04 Carlos Perelló Marín + + * es.po: Updated Spanish translation by Jose antonio s.a. + + +2001-10-27 Mitsuru Oka + + * ja.po: Updated Japanese translation. + +2001-10-24 Christian Rose + + * sv.po: Updated Swedish translation. + +2001-10-05 Yukihiro Nakai + + * ja.po: Update Japanese translation from Mitsuru Oka. + +2001-10-03 Christian Rose + + * sv.po: Updated Swedish translation. + +2001-09-29 Valek Filippov + + * ru.po: updated russian translation. + +2001-09-12 Christian Rose + + * sv.po: Updated Swedish translation. + +2001-09-10 Pablo Saratxaga + + * ga.po: Updated Irish file + * pt_BR.po: corrected charset entry in header (portuguese doesn't + use cyrillic!!!) + * pl.po: Enabled header + +2001-09-09 Carlos Perelló Marín + + * es.po: Updated Spanish translation by Jose Antonio + Salgueiro + +2001-08-13 Andras Timar + + * hu.po: Updated Hungarian translation. + +2001-07-26 Valek Filippov + + * ru.po: updated russian translation. + +2001-07-24 Christian Rose + + * sv.po: Updated Swedish translation. + +2001-07-08 Carlos Perelló Marín + + * es.po: Updated Spanish translation by Jose Antonio + Salgueiro + +2001-06-24 Matthias Warkus + + * de.po: Updated. + +2001-05-29 Kjartan Maraas + + * ja.po: Update to get rid of warnings in status script. + +2001-05-23 Jesus Bravo Alvarez + + * gl.po: Updated Galician translation from + Francisco Xose Vazquez Grandal + +2001-05-18 Kjartan Maraas + + * no.po: Updated Norwegian translation. + +2001-05-18 Kjartan Maraas + + * POTFILES.in: Updated a lot. + * no.po: Updated Norwegian translation. + +2001-05-17 Christian Rose + + * sv.po: Updated Swedish translation. + * update.pl: Removed obsolete script. + +2001-05-17 Lauris Kaplinski + + * POTFILES.in: Added glade/item.c + +2001-05-16 Lauris Kaplinski + + * POTFILES.in: Added glade/display.c + +2001-04-16 Jesus Bravo Alvarez + + * gl.po: Added Galician translation from + Francisco Xose Vazquez Grandal + +2001-04-11 Akira TAGOH + + * ja.po: Updated Japanese translation + from Takeshi Aihana + +2001-03-14 Christian Meyer + + * de.po: Updated German translation for Matthias Warkus. + +2001-03-11 Carlos Perelló Marín + + * es.po: Updated Spanish translation by Jose Antonio + Salgueiro + +2001-03-11 Valek Filippov + + * ru.po: updated russian translation. + +2001-03-11 Christian Meyer + + * de.po: Cleaned up that file a bit. + +2001-03-08 Christophe Merlet + + * fr.po: Updated French translation. + +2001-03-08 Christian Rose + + * sv.po: Updated Swedish translation. + +2001-03-08 Lauris Kaplinski + + * POTFILES.in: Added src/interface.c + +2001-02-19 Lauris Kaplinski + + * es.po: Updates by Jose Antonio Salgueiro + +2001-02-16 Kjartan Maraas + + * no.po: Updated Norwegian (bokmÃ¥l) translation. + +2001-01-12 Valek Filippov + + * ru.po: updated russian translation. + +2001-02-11 Lauris Kaplinski + + * es.po: Spanish translation by Jose Antonio Salgueiro + + +2001-01-31 Szabolcs Ban + + * hu.po: Terminology fixes by Andras Timar + +2001-01-30 Kjartan Maraas + + * no.po: Updated Norwegian translation. + +2001-01-15 Christophe Merlet + + * fr.po: Updated French translation. + +2001-01-09 Christophe Merlet + + * fr.po: Updated French translation. + +2001-01-09 Valek Filippov + + * ru.po: updated russian translation. + +2001-01-07 Benedikt Roth + + * de.po: Updated German translation + +2001-01-04 Christian Rose + + * sv.po: Updated Swedish translation. + +2000-12-28 Christopher R. Gabriel + + * it.po: Added italian translation from Francesco Brisa + +2000-12-23 Fatih Demir + + * tr.po: Committed updated translation by + Togan Muftuoglu . + +2000-12-19 Christian Rose + + * sv.po: Updated Swedish translation. + +2000-12-15 Valek Filippov + + * ru.po: updated russian translation. + +2000-12-11 Kjartan Maraas + + * no.po: Updated Norwegian translation. + +2000-12-05 Christian Rose + + * sv.po: Updated Swedish translation. + +2000-12-01 Valek Filippov + + * ru.po: updated russian translation. + +2000-11-21 Valek Filippov + + * ru.po: updated russian translation. + +2000-11-18 Christian Rose + + * sv.po: Updated Swedish translation. + +2000-10-30 Valek Filippov + + * ru.po: updated russian translation. + +2000-10-21 Zbigniew Chyla + + * pl.po: Added Polish translation. + +2000-10-18 Christophe Merlet + + * fr.po: Added French translation. + +2000-10-15 Kjartan Maraas + + * no.po: Updated Norwegian translation. + +2000-10-14 Kai Lahmann + + * de.po: Updated German translation + +2000-10-14 Christian Rose + + * sv.po: Updated Swedish translation. + +2000-10-13 Christian Rose + + * sv.po: Updated Swedish translation really much. + +2000-10-10 Yukihiro Nakai + + * ja.po: Update Japanese translation. + +2000-10-07 Kai Lahmann + + * de.po: Updated German translation + +2000-10-04 Yukihiro Nakai + + * ja.po: Update Japanese translation. + +2000-10-04 Kjartan Maraas + + * no.po: Updated Norwegian translation. + +2000-09-25 Yukihiro Nakai + + * ja.po: Updated Japanese translation. + +2000-09-20 Christian Meyer + + * de.po: Fixed some typos. Updated German translation. + +2000-09-19 Kai Lahmann + + * de.po: Updated German translation + +2000-08-24 Alastair McKinstry + + * ga.po: Added Initial Irish translation. + +2000-08-24 Kai Lahmann + + * de.po: Repaired German translation + +2000-08-21 Valek Filippov + + * ru.po: updated russian translation. + +2000-08-19 Kai Lahmann + + * de.po: Updated German translation + +2000-08-19 Valek Filippov + + * ru.po: updated russian translation. + +2000-08-16 Kai Lahmann + + * de.po: Updated German translation + +2000-08-15 Valek Filippov + + * ru.po: updated russian translation. + +2000-08-14 Kai Lahmann + + * de.po: Updated German translation + +2000-08-14 Valek Filippov + + * ru.po: updated russian translation. + +2000-08-13 Valek Filippov + + * ru.po: updated russian translation. + * update.pl: added script. + * POTFILES.in: added missing file. + +2000-08-02 Pablo Saratxaga + + * et.po: added a header to the file, so statistics and checking can + work with it + +2000-07-24 Fatih Demir + + * tr.po: Updated the 1 fuzzy, 1 untranslated entry + to be not fuzzy & untranslated ... + +2000-07-23 Kjartan Maraas + + * no.po: Updated Norwegian translation. + +2000-07-09 Karl Eichwalder + + * de.po: Update from Kai Lahmann . + +2000-06-24 Valek Filippov + + * ru.po: updated russian translation. + +2000-06-11 Benedikt Roth + + * de.po: Added German translation. + +2000-06-11 Fatih Demir + + * tr.po: Updated the Turkish translation. + +2000-06-08 Kjartan Maraas + + * no.po: Updated Norwegian translation. + +2000-06-04 Valek Filippov + + * ru.po: updated russian translation. + * POTFILES.in: added missed files. + +2000-05-23 Valek Filippov + + * ru.po: updated russian translation. + * update.sh: 1.2.5 version. + +2000-05-13 Kjartan Maraas + + * no.po: Updated Norwegian translation. + +2000-05-01 Valek Filippov + + * ru.po: Updated russian translation. + +2000-05-01 Kjartan Maraas + + * no.po: Updated Norwegian translation. + +2000-04-29 Kjartan Maraas + + * no.po: Updated Norwegian translation. + +2000-04-25 Valek Filippov + + * ru.po: Updated russian translation. + +2000-04-21 Fatih Demir + + * tr.po : Added the Turkish translation . + +2000-04-20 Andreas Hyden + + * sv.po: Added Swedish translation. + +2000-04-18 Kjartan Maraas + + * no.po: Updated Norwegian translation. + +2000-04-16 Pablo Saratxaga + + * da.po: Updated Danish file + +2000-04-12 Pablo Saratxaga Pablo + + * da.po: Added Danish file + +2000-04-06 Kjartan Maraas + + * no.po: Added Norwegian translation. + * ru.po: Added Russian translation from Valeri Filippov + . + +2000-01-17 Yuri Syrota + + * .cvsignore: Added. + +2000-01-17 Yuri Syrota + + * update.sh: A little script that lets people + update the .pot file without makefiles etc. + +2000-01-17 Yuri Syrota + + * uk.po: Added Ukrainian translation. + +2000-01-09 Lauris Kaplinski + + * Added et.po to test that localisation works diff --git a/po/Makefile.mingw b/po/Makefile.mingw new file mode 100644 index 000000000..233ae9f19 --- /dev/null +++ b/po/Makefile.mingw @@ -0,0 +1,23 @@ +include ../Makefile.mingw.common + +INKLANG = am az be ca cs da de el es es_MX et fr ga gl hu it ja mk \ +nb nl nn pa pl pt pt_BR ru sk sl sr sr@Latn sv tr uk zh_CN + +LOBJ := $(foreach a, $(INKLANG),$(a).mo ) + +all: $(LOBJ) + +clean: + $(RM) *.mo + +%.mo: %.po + $(MSGFMT) -o $@ $< + + +dist: $(LOBJ) + $(foreach a, $(INKLANG), $(shell $(MKDIR) ..$(S)inkscape$(S)locale$(S)$(a))) + $(foreach a, $(INKLANG), $(shell $(MKDIR) ..$(S)inkscape$(S)locale$(S)$(a)$(S)LC_MESSAGES)) + -$(foreach a, $(INKLANG), $(shell $(CP) $(a).mo ..$(S)inkscape$(S)locale$(S)$(a)$(S)LC_MESSAGES$(S)inkscape.mo)) + + + diff --git a/po/Makevars b/po/Makevars new file mode 100644 index 000000000..3453a43fc --- /dev/null +++ b/po/Makevars @@ -0,0 +1,25 @@ +# Makefile variables for PO directory in any package using GNU gettext. + +# Usually the message domain is the same as the package name. +DOMAIN = $(PACKAGE) + +# These two variables depend on the location of this directory. +subdir = po +top_builddir = .. + +# These options get passed to xgettext. +XGETTEXT_OPTIONS = --keyword=_ --keyword=N_ --keyword=Q_ + +# This is the copyright holder that gets inserted into the header of the +# $(DOMAIN).pot file. Set this to the copyright holder of the surrounding +# package. (Note that the msgstr strings, extracted from the package's +# sources, belong to the copyright holder of the package.) Translators are +# expected to transfer the copyright for their translations to this person +# or entity, or to disclaim their copyright. The empty string stands for +# the public domain; in this case the translators are expected to disclaim +# their copyright. +COPYRIGHT_HOLDER = Lauris Kaplinski, Ximian, Inc. and others + +# This is the list of locale categories, beyond LC_MESSAGES, for which the +# message catalogs shall be used. It is usually empty. +EXTRA_LOCALE_CATEGORIES = diff --git a/po/POTFILES.in b/po/POTFILES.in new file mode 100644 index 000000000..a98de3b6d --- /dev/null +++ b/po/POTFILES.in @@ -0,0 +1,343 @@ +# List of source files containing translatable strings. +# Please keep this file sorted alphabetically. +[encoding: UTF-8] + +inkscape.desktop.in +src/application/editor.cpp +src/arc-context.cpp +src/attributes.cpp +src/color.cpp +src/connector-context.cpp +src/desktop-affine.cpp +src/desktop-events.cpp +src/desktop-handles.cpp +src/desktop.cpp +src/dialogs/clonetiler.cpp +src/dialogs/debugdialog.cpp +src/dialogs/dialog-events.cpp +src/dialogs/display-settings.cpp +src/dialogs/export.cpp +src/dialogs/filedialog-win32.cpp +src/dialogs/filedialog.cpp +src/dialogs/fill-style.cpp +src/dialogs/find.cpp +src/dialogs/iconpreview.cpp +src/dialogs/in-dt-coordsys.cpp +src/dialogs/item-properties.cpp +src/dialogs/layer-properties.cpp +src/dialogs/object-attributes.cpp +src/dialogs/object-properties.cpp +src/dialogs/rdf.cpp +src/dialogs/sp-attribute-widget.cpp +src/dialogs/stroke-style.cpp +src/dialogs/swatches.cpp +src/dialogs/text-edit.cpp +src/dialogs/tiledialog.cpp +src/dialogs/xml-tree.cpp +src/dir-util.cpp +src/display/bezier-utils.cpp +src/display/canvas-arena.cpp +src/display/canvas-bpath.cpp +src/display/canvas-grid.cpp +src/display/curve.cpp +src/display/gnome-canvas-acetate.cpp +src/display/guideline.cpp +src/display/nr-arena-glyphs.cpp +src/display/nr-arena-group.cpp +src/display/nr-arena-image.cpp +src/display/nr-arena-item.cpp +src/display/nr-arena-shape.cpp +src/display/nr-arena.cpp +src/display/nr-gradient-gpl.cpp +src/display/nr-plain-stuff-gdk.cpp +src/display/nr-plain-stuff.cpp +src/display/sodipodi-ctrl.cpp +src/display/sodipodi-ctrlrect.cpp +src/display/sp-canvas-util.cpp +src/display/sp-canvas.cpp +src/display/sp-ctrlline.cpp +src/document-undo.cpp +src/document.cpp +src/draw-anchor.cpp +src/draw-context.cpp +src/dropper-context.cpp +src/dyna-draw-context.cpp +src/event-context.cpp +src/extension/db.cpp +src/extension/dependency.cpp +src/extension/extension.cpp +src/extension/error-file.cpp +src/extension/implementation/implementation.cpp +src/extension/implementation/script.cpp +src/extension/init.cpp +src/extension/internal/eps-out.cpp +src/extension/internal/gdkpixbuf-input.cpp +src/extension/internal/gnome.cpp +src/extension/internal/grid.cpp +src/extension/internal/ps-out.cpp +src/extension/internal/ps.cpp +src/extension/internal/svg.cpp +src/extension/internal/win32.cpp +src/extension/prefdialog.cpp +src/extension/system.cpp +src/extract-uri.cpp +src/file.cpp +src/fixes.cpp +src/geom.cpp +src/gradient-chemistry.cpp +src/gradient-context.cpp +src/gradient-drag.cpp +src/help.cpp +src/helper/action.cpp +src/helper/gnome-utils.cpp +src/helper/png-write.cpp +src/helper/stock-items.cpp +src/helper/unit-menu.cpp +src/helper/units.cpp +src/helper/window.cpp +src/inkjar/jar.cpp +src/inkscape-stock.cpp +src/inkscape.cpp +src/inkview.cpp +src/interface.cpp +src/jabber_whiteboard/callbacks.cpp +src/jabber_whiteboard/chat-handler.cpp +src/jabber_whiteboard/connection-establishment.cpp +src/jabber_whiteboard/invitation-confirm-dialog.cpp +src/jabber_whiteboard/message-handler.cpp +src/jabber_whiteboard/message-processors.cpp +src/jabber_whiteboard/message-queue.cpp +src/jabber_whiteboard/message-utilities.cpp +src/jabber_whiteboard/session-file.cpp +src/jabber_whiteboard/session-file-player.cpp +src/jabber_whiteboard/session-file-selector.cpp +src/jabber_whiteboard/session-manager.cpp +src/knot.cpp +src/knotholder.cpp +src/libnr/nr-blit.cpp +src/libnr/nr-compose-transform.cpp +src/libnr/nr-compose.cpp +src/libnr/nr-gradient.cpp +src/libnr/nr-matrix-fns.cpp +src/libnr/nr-matrix.cpp +src/libnr/nr-object.cpp +src/libnr/nr-path.cpp +src/libnr/nr-pixblock-line.cpp +src/libnr/nr-pixblock-pattern.cpp +src/libnr/nr-pixblock-pixel.cpp +src/libnr/nr-pixblock.cpp +src/libnr/nr-point-fns.cpp +src/libnr/nr-rect-l.cpp +src/libnr/nr-rect.cpp +src/libnr/nr-rotate-fns.cpp +src/libnr/nr-svp-render.cpp +src/libnr/nr-svp.cpp +src/libnr/nr-types.cpp +src/libnr/nr-values.cpp +src/libnrtype/FontFactory.cpp +src/libnrtype/FontInstance.cpp +src/libnrtype/RasterFont.cpp +src/libnrtype/TextWrapper.cpp +src/libnrtype/font-style-to-pos.cpp +src/libnrtype/nr-type-pos-def.cpp +src/libnrtype/nr-type-primitives.cpp +src/livarot/AVL.cpp +src/livarot/AlphaLigne.cpp +src/livarot/BitLigne.cpp +src/livarot/MySeg.cpp +src/livarot/Path.cpp +src/livarot/PathConversion.cpp +src/livarot/PathCutting.cpp +src/livarot/PathOutline.cpp +src/livarot/PathSimplify.cpp +src/livarot/PathStroke.cpp +src/livarot/Shape.cpp +src/livarot/ShapeDraw.cpp +src/livarot/ShapeMisc.cpp +src/livarot/ShapeRaster.cpp +src/livarot/ShapeSweep.cpp +src/main.cpp +src/marker-status.cpp +src/menus-skeleton.h +src/message-context.cpp +src/message-stack.cpp +src/mod360.cpp +src/node-context.cpp +src/nodepath.cpp +src/object-edit.cpp +src/object-ui.cpp +src/path-chemistry.cpp +src/pen-context.cpp +src/pencil-context.cpp +src/prefix.cpp +src/prefs-utils.cpp +src/print.cpp +src/rect-context.cpp +src/rubberband.cpp +src/satisfied-guide-cns.cpp +src/selcue.cpp +src/select-context.cpp +src/selection-chemistry.cpp +src/selection-describer.cpp +src/selection.cpp +src/seltrans-handles.cpp +src/seltrans.cpp +src/shortcuts.cpp +src/slideshow.cpp +src/sp-anchor.cpp +src/sp-clippath.cpp +src/sp-cursor.cpp +src/sp-defs.cpp +src/sp-ellipse.cpp +src/sp-flowregion.cpp +src/sp-flowtext.cpp +src/sp-gradient.cpp +src/sp-guide.cpp +src/sp-image.cpp +src/sp-item-group.cpp +src/sp-item-notify-moveto.cpp +src/sp-item-rm-unsatisfied-cns.cpp +src/sp-item-transform.cpp +src/sp-item-update-cns.cpp +src/sp-item.cpp +src/sp-line.cpp +src/sp-marker.cpp +src/sp-mask.cpp +src/sp-metrics.cpp +src/sp-namedview.cpp +src/sp-object-group.cpp +src/sp-object-repr.cpp +src/sp-object.cpp +src/sp-offset.cpp +src/sp-paint-server.cpp +src/sp-path.cpp +src/sp-pattern.cpp +src/sp-polygon.cpp +src/sp-polyline.cpp +src/sp-rect.cpp +src/sp-root.cpp +src/sp-shape.cpp +src/sp-spiral.cpp +src/sp-star.cpp +src/sp-symbol.cpp +src/sp-text.cpp +src/sp-use-reference.cpp +src/sp-use.cpp +src/spiral-context.cpp +src/splivarot.cpp +src/star-context.cpp +src/streams-gzip.cpp +src/streams-handles.cpp +src/streams-jar.cpp +src/streams-zlib.cpp +src/style.cpp +src/svg-view.cpp +src/svg/gnome-canvas-bpath-util.cpp +src/svg/itos.cpp +src/svg/round.cpp +src/svg/svg-affine.cpp +src/svg/svg-color.cpp +src/svg/svg-length.cpp +src/svg/svg-path.cpp +src/text-chemistry.cpp +src/text-context.cpp +src/tools-switch.cpp +src/trace/potrace/inkscape-potrace.cpp +src/trace/trace.cpp +src/ui/dialog/aboutbox.cpp +src/ui/dialog/align-and-distribute.cpp +src/ui/dialog/document-preferences.cpp +src/ui/dialog/export.cpp +src/ui/dialog/fill-and-stroke.cpp +src/ui/dialog/find.cpp +src/ui/dialog/inkscape-preferences.cpp +src/ui/dialog/memory.cpp +src/ui/dialog/messages.cpp +src/ui/dialog/scriptdialog.cpp +src/ui/dialog/session-player.cpp +src/ui/dialog/text-properties.cpp +src/ui/dialog/tracedialog.cpp +src/ui/dialog/transformation.cpp +src/ui/dialog/whiteboard-connect.cpp +src/ui/dialog/whiteboard-sharewithchat.cpp +src/ui/dialog/whiteboard-sharewithuser.cpp +src/ui/stock-items.cpp +src/ui/view/edit.cpp +src/ui/widget/panel.cpp +src/ui/widget/color-picker.cpp +src/ui/widget/selected-style.cpp +src/ui/widget/page-sizer.cpp +src/ui/widget/panel.cpp +src/ui/widget/toolbox.cpp +src/ui/widget/zoom-status.cpp +src/uri-references.cpp +src/uri.cpp +src/verbs.cpp +src/version.cpp +src/widgets/button.cpp +src/widgets/dash-selector.cpp +src/widgets/desktop-widget.cpp +src/widgets/font-selector.cpp +src/widgets/gradient-image.cpp +src/widgets/gradient-selector.cpp +src/widgets/gradient-toolbar.cpp +src/widgets/gradient-vector.cpp +src/widgets/icon.cpp +src/widgets/layer-selector.cpp +src/widgets/paint-selector.cpp +src/widgets/ruler.cpp +src/widgets/select-toolbar.cpp +src/widgets/sp-color-gtkselector.cpp +src/widgets/sp-color-notebook.cpp +src/widgets/sp-color-preview.cpp +src/widgets/sp-color-scales.cpp +src/widgets/sp-color-selector.cpp +src/widgets/sp-color-slider.cpp +src/widgets/sp-color-wheel-selector.cpp +src/widgets/sp-color-wheel.cpp +src/widgets/sp-widget.cpp +src/widgets/sp-xmlview-attr-list.cpp +src/widgets/sp-xmlview-content.cpp +src/widgets/sp-xmlview-tree.cpp +src/widgets/spinbutton-events.cpp +src/widgets/spw-utilities.cpp +src/widgets/toolbox.cpp +src/winmain.cpp +src/xml/repr-css.cpp +src/xml/repr-io.cpp +src/xml/repr-util.cpp +src/xml/repr.cpp +src/zoom-context.cpp +[type: gettext/xml] share/extensions/addnodes.inx +[type: gettext/xml] share/extensions/ai_input.inx +[type: gettext/xml] share/extensions/ai_output.inx +[type: gettext/xml] share/extensions/dia.inx +[type: gettext/xml] share/extensions/dots.inx +[type: gettext/xml] share/extensions/dropshadow.inx +[type: gettext/xml] share/extensions/dxf_input.inx +[type: gettext/xml] share/extensions/dxf_output.inx +[type: gettext/xml] share/extensions/embedimage.inx +[type: gettext/xml] share/extensions/eps_input.inx +[type: gettext/xml] share/extensions/epsi_output.inx +[type: gettext/xml] share/extensions/ffmet.inx +[type: gettext/xml] share/extensions/ffms.inx +[type: gettext/xml] share/extensions/ffset.inx +[type: gettext/xml] share/extensions/ffss.inx +[type: gettext/xml] share/extensions/handles.inx +[type: gettext/xml] share/extensions/interp.inx +[type: gettext/xml] share/extensions/kochify.inx +[type: gettext/xml] share/extensions/kochify_load.inx +[type: gettext/xml] share/extensions/lindenmayer.inx +[type: gettext/xml] share/extensions/motion.inx +[type: gettext/xml] share/extensions/pdf_output.inx +[type: gettext/xml] share/extensions/ps_input.inx +[type: gettext/xml] share/extensions/radiusrand.inx +[type: gettext/xml] share/extensions/rtree.inx +[type: gettext/xml] share/extensions/sk_input.inx +[type: gettext/xml] share/extensions/straightseg.inx +[type: gettext/xml] share/extensions/summersnight.inx +[type: gettext/xml] share/extensions/svgz_input.inx +[type: gettext/xml] share/extensions/svgz_output.inx +[type: gettext/xml] share/extensions/txt2svg.inx +[type: gettext/xml] share/extensions/wavy.inx +[type: gettext/xml] share/extensions/whirl.inx +[type: gettext/xml] share/extensions/wmf_input.inx diff --git a/po/am.po b/po/am.po new file mode 100644 index 000000000..795f35276 --- /dev/null +++ b/po/am.po @@ -0,0 +1,9942 @@ +# Translations into the Amharic Language. +# Copyright (C) 2002 Free Software Foundation, Inc. +# This file is distributed under the same license as the sodipodi package. +# Ge'ez Frontier Foundation , 2002. +# +# +msgid "" +msgstr "" +"Project-Id-Version: sodipodi\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2005-12-04 11:51-0800\n" +"PO-Revision-Date: 2003-02-01 10:13+EDT\n" +"Last-Translator: Ge'ez Frontier Foundation \n" +"Language-Team: Amharic \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../inkscape.desktop.in.h:1 +msgid "Create and edit Scalable Vector Graphics images" +msgstr "" + +#: ../inkscape.desktop.in.h:2 +msgid "Inkscape SVG Vector Illustrator" +msgstr "" + +#: ../../po/../src/arc-context.cpp:350 +msgid "" +"Ctrl: make circle or integer-ratio ellipse, snap arc/segment angle" +msgstr "" + +#: ../../po/../src/arc-context.cpp:351 ../../po/../src/rect-context.cpp:388 +msgid "Shift: draw around the starting point" +msgstr "" + +#: ../../po/../src/arc-context.cpp:413 +#: ../../po/../src/connector-context.cpp:493 +#: ../../po/../src/dyna-draw-context.cpp:506 +#: ../../po/../src/pen-context.cpp:329 ../../po/../src/pencil-context.cpp:208 +#: ../../po/../src/rect-context.cpp:452 ../../po/../src/spiral-context.cpp:421 +#: ../../po/../src/star-context.cpp:427 +msgid "Current layer is hidden. Unhide it to be able to draw on it." +msgstr "" + +#: ../../po/../src/arc-context.cpp:417 +#: ../../po/../src/connector-context.cpp:497 +#: ../../po/../src/dyna-draw-context.cpp:510 +#: ../../po/../src/pen-context.cpp:336 ../../po/../src/pencil-context.cpp:212 +#: ../../po/../src/rect-context.cpp:456 ../../po/../src/spiral-context.cpp:426 +#: ../../po/../src/star-context.cpp:431 +msgid "Current layer is locked. Unlock it to be able to draw on it." +msgstr "" + +#: ../../po/../src/arc-context.cpp:496 +#, c-format +msgid "" +"Ellipse: %s × %s; with Ctrl to make circle or integer-" +"ratio ellipse; with Shift to draw around the starting point" +msgstr "" + +#: ../../po/../src/connector-context.cpp:518 +#, fuzzy +msgid "Creating new connector" +msgstr "ሰነድ አስቀምት" + +#: ../../po/../src/connector-context.cpp:939 +msgid "Finishing connector" +msgstr "" + +#: ../../po/../src/connector-context.cpp:1108 +msgid "Connection point: click or drag to create a new connector" +msgstr "" + +#: ../../po/../src/connector-context.cpp:1185 +msgid "Connector endpoint: drag to reroute or connect to new shapes" +msgstr "" + +#: ../../po/../src/connector-context.cpp:1278 +msgid "Select at least one non-connector object." +msgstr "" + +#: ../../po/../src/desktop-events.cpp:238 +#, c-format +msgid "%s at %s" +msgstr "" + +#. TRANSLATORS: This string appears when double-clicking on a guide. +#. This is the distance by which the guide is to be moved. +#: ../../po/../src/desktop-events.cpp:277 +msgid " relative by " +msgstr "" + +#. TRANSLATORS: This string appears when double-clicking on a guide. +#. This is the target location where the guide is to be moved. +#: ../../po/../src/desktop-events.cpp:282 +#: ../../po/../src/desktop-events.cpp:395 +msgid " absolute to " +msgstr "" + +#. create dialog +#: ../../po/../src/desktop-events.cpp:348 +msgid "Guideline" +msgstr "" + +#: ../../po/../src/desktop-events.cpp:432 +#, fuzzy, c-format +msgid "Move %s" +msgstr "መንቀሳቅስ" + +#: ../../po/../src/desktop.cpp:678 +msgid "No previous zoom." +msgstr "" + +#: ../../po/../src/desktop.cpp:703 +msgid "No next zoom." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:182 +msgid "Nothing selected." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:188 +msgid "More than one object selected." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:195 +#, c-format +msgid "Object has %d tiled clones." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:200 +msgid "Object has no tiled clones." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:865 +msgid "Select one object whose tiled clones to unclump." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:916 +msgid "Select one object whose tiled clones to remove." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:984 +#: ../../po/../src/selection-chemistry.cpp:1774 +msgid "Select an object to clone." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:990 +#: ../../po/../src/selection-chemistry.cpp:1780 +msgid "" +"If you want to clone several objects, group them and clone the " +"group." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1484 +msgid "Per row:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1497 +msgid "Per column:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1505 +msgid "Randomize:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1656 +msgid "_Symmetry" +msgstr "" + +#. TRANSLATORS: For the following 17 symmetry groups, see +#. * http://www.bib.ulb.ac.be/coursmath/doc/17.htm (visual examples); +#. * http://www.clarku.edu/~djoyce/wallpaper/seventeen.html (English vocabulary); or +#. * http://membres.lycos.fr/villemingerard/Geometri/Sym1D.htm (French vocabulary). +#. +#: ../../po/../src/dialogs/clonetiler.cpp:1664 +msgid "Select one of the 17 symmetry groups for the tiling" +msgstr "" + +#. TRANSLATORS: "translation" means "shift" / "displacement" here. +#: ../../po/../src/dialogs/clonetiler.cpp:1675 +msgid "P1: simple translation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1676 +msgid "P2: 180° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1677 +msgid "PM: reflection" +msgstr "" + +#. TRANSLATORS: "glide reflection" is a reflection and a translation combined. +#. For more info, see http://mathforum.org/sum95/suzanne/symsusan.html +#: ../../po/../src/dialogs/clonetiler.cpp:1680 +msgid "PG: glide reflection" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1681 +msgid "CM: reflection + glide reflection" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1682 +msgid "PMM: reflection + reflection" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1683 +msgid "PMG: reflection + 180° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1684 +msgid "PGG: glide reflection + 180° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1685 +msgid "CMM: reflection + reflection + 180° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1686 +msgid "P4: 90° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1687 +msgid "P4M: 90° rotation + 45° reflection" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1688 +msgid "P4G: 90° rotation + 90° reflection" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1689 +msgid "P3: 120° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1690 +msgid "P31M: reflection + 120° rotation, dense" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1691 +msgid "P3M1: reflection + 120° rotation, sparse" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1692 +msgid "P6: 60° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1693 +msgid "P6M: reflection + 60° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1721 +msgid "S_hift" +msgstr "" + +#. TRANSLATORS: "shift" means: the tiles will be shifted (offset) horizontally by this amount +#: ../../po/../src/dialogs/clonetiler.cpp:1731 +#, no-c-format +msgid "Shift X:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1739 +#, no-c-format +msgid "Horizontal shift per row (in % of tile width)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1747 +#, no-c-format +msgid "Horizontal shift per column (in % of tile width)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1754 +msgid "Randomize the horizontal shift by this percentage" +msgstr "" + +#. TRANSLATORS: "shift" means: the tiles will be shifted (offset) vertically by this amount +#: ../../po/../src/dialogs/clonetiler.cpp:1764 +#, no-c-format +msgid "Shift Y:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1772 +#, no-c-format +msgid "Vertical shift per row (in % of tile height)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1780 +#, no-c-format +msgid "Vertical shift per column (in % of tile height)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1787 +msgid "Randomize the vertical shift by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1795 +msgid "Exponent:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1802 +msgid "Whether rows are spaced evenly (1), converge (<1) or diverge (>1)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1809 +msgid "Whether columns are spaced evenly (1), converge (<1) or diverge (>1)" +msgstr "" + +#. TRANSLATORS: "Alternate" is a verb here +#: ../../po/../src/dialogs/clonetiler.cpp:1817 +#: ../../po/../src/dialogs/clonetiler.cpp:1907 +#: ../../po/../src/dialogs/clonetiler.cpp:1966 +#: ../../po/../src/dialogs/clonetiler.cpp:2022 +#: ../../po/../src/dialogs/clonetiler.cpp:2153 +msgid "Alternate:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1823 +msgid "Alternate the sign of shifts for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1828 +msgid "Alternate the sign of shifts for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1837 +#, fuzzy +msgid "Sc_ale" +msgstr "መለኪያ" + +#: ../../po/../src/dialogs/clonetiler.cpp:1845 +#, fuzzy +msgid "Scale X:" +msgstr "መቶኛዎች" + +#: ../../po/../src/dialogs/clonetiler.cpp:1853 +#, no-c-format +msgid "Horizontal scale per row (in % of tile width)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1861 +#, no-c-format +msgid "Horizontal scale per column (in % of tile width)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1868 +msgid "Randomize the horizontal scale by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1876 +#, fuzzy +msgid "Scale Y:" +msgstr "መቶኛዎች" + +#: ../../po/../src/dialogs/clonetiler.cpp:1884 +#, no-c-format +msgid "Vertical scale per row (in % of tile height)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1892 +#, no-c-format +msgid "Vertical scale per column (in % of tile height)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1899 +msgid "Randomize the vertical scale by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1913 +msgid "Alternate the sign of scales for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1918 +msgid "Alternate the sign of scales for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1927 +#, fuzzy +msgid "_Rotation" +msgstr "ምርጫ" + +#: ../../po/../src/dialogs/clonetiler.cpp:1935 +#, fuzzy +msgid "Angle:" +msgstr "መቶኛዎች" + +#: ../../po/../src/dialogs/clonetiler.cpp:1943 +#, no-c-format +msgid "Rotate tiles by this angle for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1951 +#, no-c-format +msgid "Rotate tiles by this angle for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1958 +msgid "Randomize the rotation angle by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1972 +msgid "Alternate the rotation direction for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1977 +msgid "Alternate the rotation direction for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1985 +msgid "_Opacity" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1993 +msgid "Fade out:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2000 +msgid "Decrease tile opacity by this percentage for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2007 +msgid "Decrease tile opacity by this percentage for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2014 +msgid "Randomize the tile opacity by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2028 +msgid "Alternate the sign of opacity change for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2033 +msgid "Alternate the sign of opacity change for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2041 +#, fuzzy +msgid "Co_lor" +msgstr "ዝጋ" + +#: ../../po/../src/dialogs/clonetiler.cpp:2046 +#, fuzzy +msgid "Initial color: " +msgstr "የማጉያ ቀለም፦" + +#: ../../po/../src/dialogs/clonetiler.cpp:2050 +msgid "Initial color of tiled clones" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2050 +msgid "" +"Initial color for clones (works only if the original has unset fill or " +"stroke)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2065 +msgid "H:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2072 +msgid "Change the tile hue by this percentage for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2079 +msgid "Change the tile hue by this percentage for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2086 +msgid "Randomize the tile hue by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2095 +msgid "S:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2102 +msgid "Change the color saturation by this percentage for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2109 +msgid "Change the color saturation by this percentage for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2116 +msgid "Randomize the color saturation by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2124 +msgid "L:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2131 +msgid "Change the color lightness by this percentage for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2138 +msgid "Change the color lightness by this percentage for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2145 +msgid "Randomize the color lightness by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2159 +msgid "Alternate the sign of color changes for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2164 +msgid "Alternate the sign of color changes for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2172 +#, fuzzy +msgid "_Trace" +msgstr "ላኩ" + +#: ../../po/../src/dialogs/clonetiler.cpp:2179 +msgid "Trace the drawing under the tiles" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2183 +msgid "" +"For each clone, pick a value from the drawing in that clone's location and " +"apply it to the clone" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2197 +msgid "1. Pick from the drawing:" +msgstr "" + +#. ----Hbox2 +#: ../../po/../src/dialogs/clonetiler.cpp:2208 +#: ../../po/../src/dialogs/clonetiler.cpp:2355 +#: ../../po/../src/ui/dialog/tracedialog.cpp:445 +#, fuzzy +msgid "Color" +msgstr "ዝጋ" + +#: ../../po/../src/dialogs/clonetiler.cpp:2209 +msgid "Pick the visible color and opacity" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2216 +#: ../../po/../src/dialogs/clonetiler.cpp:2365 +#: ../share/extensions/dropshadow.inx.h:3 +msgid "Opacity" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2217 +msgid "Pick the total accumulated opacity" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2224 +msgid "R" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2225 +msgid "Pick the Red component of the color" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2232 +msgid "G" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2233 +msgid "Pick the Green component of the color" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2240 +msgid "B" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2241 +msgid "Pick the Blue component of the color" +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2250 +msgid "clonetiler|H" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2251 +msgid "Pick the hue of the color" +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2260 +msgid "clonetiler|S" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2261 +msgid "Pick the saturation of the color" +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2270 +msgid "clonetiler|L" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2271 +msgid "Pick the lightness of the color" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2281 +msgid "2. Tweak the picked value:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2291 +msgid "Gamma-correct:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2296 +msgid "Shift the mid-range of the picked value upwards (>0) or downwards (<0)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2303 +msgid "Randomize:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2308 +msgid "Randomize the picked value by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2315 +#, fuzzy +msgid "Invert:" +msgstr "ነጥብ" + +#: ../../po/../src/dialogs/clonetiler.cpp:2319 +msgid "Invert the picked value" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2325 +msgid "3. Apply the value to the clones':" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2335 +#, fuzzy +msgid "Presence" +msgstr "ሶዲፖዲ" + +#: ../../po/../src/dialogs/clonetiler.cpp:2338 +msgid "" +"Each clone is created with the probability determined by the picked value in " +"that point" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2345 +msgid "Size" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2348 +msgid "Each clone's size is determined by the picked value in that point" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2358 +msgid "" +"Each clone is painted by the picked color (the original must have unset fill " +"or stroke)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2368 +msgid "Each clone's opacity is determined by the picked value in that point" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2395 +msgid "How many rows in the tiling" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2415 +msgid "How many columns in the tiling" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2445 +msgid "Width of the rectangle to be filled" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2470 +msgid "Height of the rectangle to be filled" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2485 +#, fuzzy +msgid "Rows, columns: " +msgstr "ዝጋ" + +#: ../../po/../src/dialogs/clonetiler.cpp:2486 +msgid "Create the specified number of rows and columns" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2495 +msgid "Width, height: " +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2496 +msgid "Fill the specified width and height with the tiling" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2512 +msgid "Use saved size and position of the tile" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2515 +msgid "" +"Pretend that the size and position of the tile are the same as the last time " +"you tiled it (if any), instead of using the current size" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2539 +#, fuzzy +msgid " _Create " +msgstr "መቶኛዎች" + +#: ../../po/../src/dialogs/clonetiler.cpp:2541 +msgid "Create and tile the clones of the selection" +msgstr "" + +#. TRANSLATORS: if a group of objects are "clumped" together, then they +#. are unevenly spread in the given amount of space - as shown in the +#. diagrams on the left in the following screenshot: +#. http://www.inkscape.org/screenshots/gallery/inkscape-0.42-CVS-tiles-unclump.png +#. So unclumping is the process of spreading a number of objects out more evenly. +#: ../../po/../src/dialogs/clonetiler.cpp:2556 +msgid " _Unclump " +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2557 +msgid "Spread out clones to reduce clumping; can be applied repeatedly" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2563 +#, fuzzy +msgid " Re_move " +msgstr "አያያዝን አስወግድ" + +#: ../../po/../src/dialogs/clonetiler.cpp:2564 +msgid "Remove existing tiled clones of the selected object (siblings only)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2580 +#, fuzzy +msgid " R_eset " +msgstr "አያያዝን አስወግድ" + +#. TRANSLATORS: "change" is a noun here +#: ../../po/../src/dialogs/clonetiler.cpp:2582 +msgid "" +"Reset all shifts, scales, rotates, opacity and color changes in the dialog " +"to zero" +msgstr "" + +#: ../../po/../src/dialogs/color-picker.cpp:280 +msgid "Close" +msgstr "ዝጋ" + +#: ../../po/../src/dialogs/debugdialog.cpp:138 +msgid "Messages" +msgstr "" + +#. ## Add a menu for clear() +#: ../../po/../src/dialogs/debugdialog.cpp:144 +#: ../../po/../src/menus-skeleton.h:16 +#: ../../po/../src/ui/dialog/messages.cpp:56 +#: ../../po/../src/ui/dialog/scriptdialog.cpp:181 +#, fuzzy +msgid "_File" +msgstr "ፋይል" + +#. TRANSLATORS: "Clear" is a verb here +#: ../../po/../src/dialogs/debugdialog.cpp:145 +#: ../../po/../src/dialogs/find.cpp:753 +#: ../../po/../src/ui/dialog/messages.cpp:57 +#: ../../po/../src/ui/dialog/scriptdialog.cpp:182 +#, fuzzy +msgid "_Clear" +msgstr "ዝጋ" + +#: ../../po/../src/dialogs/debugdialog.cpp:147 +#: ../../po/../src/ui/dialog/messages.cpp:59 +msgid "Capture log messages" +msgstr "" + +#: ../../po/../src/dialogs/debugdialog.cpp:149 +#: ../../po/../src/ui/dialog/messages.cpp:61 +msgid "Release log messages" +msgstr "" + +#. Notebook tab +#: ../../po/../src/dialogs/desktop-properties.cpp:909 +#: ../../po/../src/ui/dialog/document-preferences.cpp:89 +#: ../../po/../src/ui/widget/panel.cpp:107 +msgid "Grid" +msgstr "" + +#. Checkbuttons +#. / \todo FIXME: gray out snapping when grid is off +#. / \todo FIXME: gray out snapping when grid is off. +#. / Dissenting view: you want snapping without grid. +#: ../../po/../src/dialogs/desktop-properties.cpp:917 +#: ../../po/../src/ui/dialog/document-preferences.cpp:179 +msgid "Show grid" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:917 +#: ../../po/../src/ui/dialog/document-preferences.cpp:179 +#: ../../po/../src/verbs.cpp:2115 +msgid "Show or hide grid" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:918 +#: ../../po/../src/ui/dialog/document-preferences.cpp:180 +msgid "Snap bounding boxes to grid" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:918 +#: ../../po/../src/dialogs/desktop-properties.cpp:1001 +#: ../../po/../src/ui/dialog/document-preferences.cpp:181 +#: ../../po/../src/ui/dialog/document-preferences.cpp:236 +msgid "Snap the edges of the object bounding boxes" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:919 +#: ../../po/../src/ui/dialog/document-preferences.cpp:183 +msgid "Snap nodes to grid" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:919 +#: ../../po/../src/dialogs/desktop-properties.cpp:1002 +#: ../../po/../src/ui/dialog/document-preferences.cpp:184 +#: ../../po/../src/ui/dialog/document-preferences.cpp:239 +msgid "Snap path nodes, text baselines, ellipse centers, etc." +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:937 +#: ../../po/../src/ui/dialog/document-preferences.cpp:186 +msgid "Grid units:" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:939 +#: ../../po/../src/ui/dialog/document-preferences.cpp:187 +msgid "Origin X:" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:942 +#: ../../po/../src/ui/dialog/document-preferences.cpp:189 +msgid "Origin Y:" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:945 +#: ../../po/../src/ui/dialog/document-preferences.cpp:191 +msgid "Spacing X:" +msgstr "ክፍተት X፦" + +#: ../../po/../src/dialogs/desktop-properties.cpp:948 +#: ../../po/../src/ui/dialog/document-preferences.cpp:193 +msgid "Spacing Y:" +msgstr "ክፍተት Y፦" + +#: ../../po/../src/dialogs/desktop-properties.cpp:952 +#: ../../po/../src/dialogs/desktop-properties.cpp:1013 +#: ../../po/../src/ui/dialog/document-preferences.cpp:195 +#: ../../po/../src/ui/dialog/document-preferences.cpp:241 +msgid "Snap units:" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:955 +#: ../../po/../src/dialogs/desktop-properties.cpp:1016 +#: ../../po/../src/ui/dialog/document-preferences.cpp:196 +#: ../../po/../src/ui/dialog/document-preferences.cpp:242 +msgid "Snap distance:" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:958 +#: ../../po/../src/ui/dialog/document-preferences.cpp:199 +#, fuzzy +msgid "Grid line color:" +msgstr "የመጨረሺያ ቀለም" + +#: ../../po/../src/dialogs/desktop-properties.cpp:959 +#: ../../po/../src/ui/dialog/document-preferences.cpp:199 +#, fuzzy +msgid "Grid line color" +msgstr "የመጨረሺያ ቀለም" + +#: ../../po/../src/dialogs/desktop-properties.cpp:959 +#: ../../po/../src/ui/dialog/document-preferences.cpp:200 +#, fuzzy +msgid "Color of grid lines" +msgstr "ክፍተት X፦" + +#: ../../po/../src/dialogs/desktop-properties.cpp:961 +#: ../../po/../src/ui/dialog/document-preferences.cpp:201 +#, fuzzy +msgid "Major grid line color:" +msgstr "የመጨረሺያ ቀለም" + +#: ../../po/../src/dialogs/desktop-properties.cpp:962 +#: ../../po/../src/ui/dialog/document-preferences.cpp:201 +#, fuzzy +msgid "Major grid line color" +msgstr "የመጨረሺያ ቀለም" + +#: ../../po/../src/dialogs/desktop-properties.cpp:962 +#: ../../po/../src/ui/dialog/document-preferences.cpp:202 +msgid "Color of the major (highlighted) grid lines" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:965 +#: ../../po/../src/ui/dialog/document-preferences.cpp:204 +#, fuzzy +msgid "Major grid line every:" +msgstr "የመጨረሺያ ቀለም" + +#. TRANSLATORS: This belongs to the "Major grid line every:" string, +#. see grid settings in the "Document Preferences" dialog +#: ../../po/../src/dialogs/desktop-properties.cpp:977 +#: ../../po/../src/ui/dialog/document-preferences.cpp:204 +#, fuzzy +msgid "lines" +msgstr "ዝጋ" + +#. Guidelines page +#: ../../po/../src/dialogs/desktop-properties.cpp:991 +#: ../../po/../src/ui/dialog/document-preferences.cpp:90 +msgid "Guides" +msgstr "" + +#. / \todo FIXME: gray out snapping when guides are off +#. / Dissenting view: you want snapping without guides. +#: ../../po/../src/dialogs/desktop-properties.cpp:1000 +#: ../../po/../src/ui/dialog/document-preferences.cpp:234 +msgid "Show guides" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1000 +#: ../../po/../src/ui/dialog/document-preferences.cpp:234 +#: ../../po/../src/verbs.cpp:2116 +msgid "Show or hide guides" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1001 +#: ../../po/../src/ui/dialog/document-preferences.cpp:235 +msgid "Snap bounding boxes to guides" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1002 +#: ../../po/../src/ui/dialog/document-preferences.cpp:238 +msgid "Snap points to guides" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1020 +#: ../../po/../src/ui/dialog/document-preferences.cpp:243 +#, fuzzy +msgid "Guide color:" +msgstr "የመጨረሺያ ቀለም" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1021 +#: ../../po/../src/ui/dialog/document-preferences.cpp:243 +msgid "Guideline color" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1021 +#: ../../po/../src/ui/dialog/document-preferences.cpp:244 +msgid "Color of guidelines" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1023 +#: ../../po/../src/ui/dialog/document-preferences.cpp:245 +msgid "Highlight color:" +msgstr "የማጉያ ቀለም፦" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1024 +#: ../../po/../src/ui/dialog/document-preferences.cpp:245 +msgid "Highlighted guideline color" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1024 +#: ../../po/../src/ui/dialog/document-preferences.cpp:246 +msgid "Color of a guideline when it is under mouse" +msgstr "" + +#. Page page +#: ../../po/../src/dialogs/desktop-properties.cpp:1029 +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:855 +#: ../../po/../src/ui/dialog/document-preferences.cpp:88 +#: ../../po/../src/widgets/desktop-widget.cpp:1061 +msgid "Page" +msgstr "ገጽ" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1039 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +#, fuzzy +msgid "Background:" +msgstr "የመጨረሺያ ቀለም" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1040 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +#, fuzzy +msgid "Background color" +msgstr "የመጨረሺያ ቀለም" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1041 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +msgid "" +"Color and transparency of the page background (also used for bitmap export)" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1045 +#: ../../po/../src/ui/dialog/document-preferences.cpp:147 +#, fuzzy +msgid "Show page border" +msgstr "ወሰንን አሳይ" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1049 +#: ../../po/../src/ui/dialog/document-preferences.cpp:148 +msgid "Border on top of drawing" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1052 +#: ../../po/../src/ui/dialog/document-preferences.cpp:149 +#, fuzzy +msgid "Border color:" +msgstr "የመጨረሺያ ቀለም" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1053 +#: ../../po/../src/ui/dialog/document-preferences.cpp:149 +#, fuzzy +msgid "Page border color" +msgstr "የመጨረሺያ ቀለም" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1054 +#: ../../po/../src/ui/dialog/document-preferences.cpp:150 +#, fuzzy +msgid "Color of the page border" +msgstr "ወሰንን አሳይ" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1059 +#: ../../po/../src/ui/dialog/document-preferences.cpp:152 +msgid "Show page shadow" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1063 +#: ../../po/../src/ui/dialog/document-preferences.cpp:153 +#, fuzzy +msgid "Default units:" +msgstr "ነባሮች" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1069 +msgid "Units for the tool controls, ruler, and the statusbar" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1086 +#: ../../po/../src/ui/widget/page-sizer.cpp:209 +#, fuzzy +msgid "Page size:" +msgstr "የወረከት መጠን፦" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1110 +#: ../../po/../src/ui/widget/page-sizer.cpp:219 +msgid "Custom" +msgstr "የተለየ" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1121 +#: ../../po/../src/ui/widget/page-sizer.cpp:225 +#, fuzzy +msgid "Page orientation:" +msgstr "አቀማመጥ፦" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1133 +#: ../../po/../src/ui/widget/page-sizer.cpp:232 +#, fuzzy +msgid "Landscape" +msgstr "ሶዲፖዲ" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1139 +#: ../../po/../src/ui/widget/page-sizer.cpp:234 +#, fuzzy +msgid "Portrait" +msgstr "ነጥብ" + +#. Custom paper frame +#: ../../po/../src/dialogs/desktop-properties.cpp:1148 +#: ../../po/../src/ui/widget/page-sizer.cpp:249 +#, fuzzy +msgid "Custom size" +msgstr "የተለየ" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1160 +#: ../../po/../src/dialogs/export.cpp:269 +#: ../../po/../src/ui/widget/page-sizer.cpp:261 +msgid "Units:" +msgstr "ክፍሎች፦" + +#. Stroke width +#: ../../po/../src/dialogs/desktop-properties.cpp:1162 +#: ../../po/../src/dialogs/export.cpp:310 +#: ../../po/../src/dialogs/object-attributes.cpp:55 +#: ../../po/../src/dialogs/stroke-style.cpp:985 +#: ../../po/../src/ui/widget/page-sizer.cpp:262 +#: ../../po/../src/widgets/toolbox.cpp:1957 +msgid "Width:" +msgstr "ስፋት፦" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1183 +#: ../../po/../src/dialogs/export.cpp:326 +#: ../../po/../src/dialogs/export.cpp:431 +#: ../../po/../src/dialogs/object-attributes.cpp:56 +#: ../../po/../src/ui/widget/page-sizer.cpp:263 +msgid "Height:" +msgstr "እርዝማኔ፦" + +#. +#. * Ownership metadata tab +#. +#: ../../po/../src/dialogs/desktop-properties.cpp:1206 +msgid "Metadata" +msgstr "" + +#. add license selector pull-down +#: ../../po/../src/dialogs/desktop-properties.cpp:1225 +msgid "License" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1255 +msgid "Proprietary" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:212 +msgid "When transforming, show:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:223 +msgid "Objects" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:224 +msgid "Show the actual objects when moving or transforming" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:231 +msgid "Box outline" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:232 +msgid "Show only a box outline of the objects when moving or transforming" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:238 +msgid "Per-object selection cue:" +msgstr "" + +#. sorationsnapsperpi == 0 means no snapping +#: ../../po/../src/dialogs/display-settings.cpp:249 +#: ../../po/../src/dialogs/display-settings.cpp:386 +#: ../../po/../src/dialogs/display-settings.cpp:441 +#: ../../po/../src/dialogs/display-settings.cpp:1482 +#: ../../po/../src/dialogs/stroke-style.cpp:791 +#: ../../po/../src/interface.cpp:741 +#: ../../po/../src/ui/widget/selected-style.cpp:100 +#: ../../po/../src/verbs.cpp:1842 +msgid "None" +msgstr "ምንም" + +#: ../../po/../src/dialogs/display-settings.cpp:250 +msgid "No per-object selection indication" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:256 +msgid "Mark" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:257 +msgid "Each selected object has a diamond mark in the top left corner" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:264 +msgid "Box" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:265 +msgid "Each selected object displays its bounding box" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:270 +msgid "Default scale origin:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:281 +msgid "Opposite bounding box edge" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:282 +msgid "Default scale origin will be on the bounding box of the item" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:288 +msgid "Farthest opposite node" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:289 +msgid "Default scale origin will be on the bounding box of the item's points" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:341 +#, fuzzy +msgid "degrees" +msgstr "deg" + +#: ../../po/../src/dialogs/display-settings.cpp:350 +msgid "" +"Rotating with Ctrl pressed snaps every that much degrees; also, pressing " +"[ or ] rotates by this amount" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:407 +msgid "Rotation snaps every:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:430 +msgid "" +"None: dialogs are treated as regular windows; Normal: dialogs stay on top of " +"document windows; Aggressive: same as Normal but may work better with some " +"window managers." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:451 +msgid "Normal" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:461 +msgid "Aggressive" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:475 +#, fuzzy +msgid "Dialogs on top:" +msgstr "መምረጫዎች" + +#: ../../po/../src/dialogs/display-settings.cpp:645 +#, fuzzy +msgid "Show selection cue" +msgstr "ምርጫ" + +#: ../../po/../src/dialogs/display-settings.cpp:646 +msgid "" +"Whether selected objects display a selection cue (the same as in selector)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:657 +msgid "Enable gradient editing" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:658 +msgid "Whether selected objects display gradient editing controls" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:719 +msgid "No objects selected to take the style from." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:728 +msgid "" +"More than one object selected. Cannot take style from multiple " +"objects." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:767 +#, fuzzy +msgid "Create new objects with:" +msgstr "ጠባየ-አንቀጽ" + +#: ../../po/../src/dialogs/display-settings.cpp:777 +#, fuzzy +msgid "Take from selection" +msgstr "አጥፉ" + +#: ../../po/../src/dialogs/display-settings.cpp:778 +msgid "Remember the style of the (first) selected object as this tool's style" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:782 +#, fuzzy +msgid "Last used style" +msgstr "ለጥፍ" + +#: ../../po/../src/dialogs/display-settings.cpp:782 +msgid "Apply the style you last set on an object" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:790 +msgid "This tool's own style:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:790 +msgid "" +"Each tool may store its own style to apply to the newly created objects. Use " +"the button below to set it." +msgstr "" + +#. Mouse +#: ../../po/../src/dialogs/display-settings.cpp:877 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:55 +#, fuzzy +msgid "Mouse" +msgstr "መንቀሳቅስ" + +#. TRANSLATORS: "Grab" is a noun here. "Grab sensitivity" is intended to mean how +#. * close on the screen you need to be to an object to be able to grab it with mouse (in +#. * pixels). +#: ../../po/../src/dialogs/display-settings.cpp:883 +msgid "Grab sensitivity:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:884 +msgid "" +"How close on the screen you need to be to an object to be able to grab it " +"with mouse (in screen pixels)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:885 +#: ../../po/../src/dialogs/display-settings.cpp:897 +#: ../../po/../src/dialogs/display-settings.cpp:912 +#: ../../po/../src/dialogs/display-settings.cpp:930 +#: ../../po/../src/dialogs/display-settings.cpp:970 +msgid "pixels" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:895 +msgid "Click/drag threshold:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:896 +msgid "" +"Maximum mouse drag (in screen pixels) which is considered a click, not a drag" +msgstr "" + +#. Scrolling +#: ../../po/../src/dialogs/display-settings.cpp:907 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:56 +msgid "Scrolling" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:910 +msgid "Mouse wheel scrolls by:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:911 +msgid "" +"One mouse wheel notch scrolls by this distance in screen pixels " +"(horizontally with Shift)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:920 +msgid "Ctrl+arrows" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:928 +msgid "Scroll by:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:929 +msgid "Pressing Ctrl+arrow key scrolls by this distance (in screen pixels)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:939 +#, fuzzy +msgid "Acceleration:" +msgstr "ምርጫ" + +#: ../../po/../src/dialogs/display-settings.cpp:940 +msgid "" +"Pressing and holding Ctrl+arrow will gradually speed up scrolling (0 for no " +"acceleration)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:949 +msgid "Autoscrolling" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:957 +#, fuzzy +msgid "Speed:" +msgstr "ቀይ፦" + +#: ../../po/../src/dialogs/display-settings.cpp:958 +msgid "" +"How fast the canvas autoscrolls when you drag beyond canvas edge (0 to turn " +"autoscroll off)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:968 +#: ../../po/../src/ui/dialog/tracedialog.cpp:357 +#: ../../po/../src/ui/dialog/tracedialog.cpp:390 +msgid "Threshold:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:969 +msgid "" +"How far (in screen pixels) you need to be from the canvas edge to trigger " +"autoscroll; positive is outside the canvas, negative is within the canvas" +msgstr "" + +#. Steps +#: ../../po/../src/dialogs/display-settings.cpp:979 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:57 +#, fuzzy +msgid "Steps" +msgstr "ዓይነት" + +#: ../../po/../src/dialogs/display-settings.cpp:982 +msgid "Arrow keys move by:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:983 +msgid "" +"Pressing an arrow key moves selected object(s) or node(s) by this distance " +"(in px units)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:984 +#: ../../po/../src/dialogs/display-settings.cpp:995 +#: ../../po/../src/dialogs/display-settings.cpp:1006 +#: ../../po/../src/helper/units.cpp:42 +msgid "px" +msgstr "px" + +#: ../../po/../src/dialogs/display-settings.cpp:993 +msgid "> and < scale by:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:994 +msgid "" +"Pressing > or < scales selection up or down by this increment (in px units)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1004 +msgid "Inset/Outset by:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1005 +msgid "" +"Inset and Outset commands displace the path by this distance (in px units)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1017 +msgid "Compass-like display of angles" +msgstr "" + +#. TRANSLATORS: "positive clockwise" means "increasing in clockwise direction" +#: ../../po/../src/dialogs/display-settings.cpp:1019 +msgid "" +"When on, angles are displayed with 0 at north, 0 to 360 range, positive " +"clockwise; otherwise with 0 at east, -180 to 180 range, positive " +"counterclockwise" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1026 +#, fuzzy +msgid "Zoom in/out by:" +msgstr "በቅርበት አሳይ" + +#: ../../po/../src/dialogs/display-settings.cpp:1027 +msgid "" +"Zoom tool click, +/- keys, and middle click zoom in and out by this " +"multiplier" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1028 +#: ../../po/../src/helper/units.cpp:44 +msgid "%" +msgstr "%" + +#. Tools +#: ../../po/../src/dialogs/display-settings.cpp:1037 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:58 +msgid "Tools" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1045 +#, fuzzy +msgid "Selector" +msgstr "ምርጡ" + +#: ../../po/../src/dialogs/display-settings.cpp:1056 +#, fuzzy +msgid "Node" +msgstr "ምንም" + +#: ../../po/../src/dialogs/display-settings.cpp:1064 +#: ../../po/../src/verbs.cpp:2073 +#: ../../po/../src/widgets/desktop-widget.cpp:277 +msgid "Zoom" +msgstr "በቅርበት አሳይ" + +#. The 4 shape tools +#: ../../po/../src/dialogs/display-settings.cpp:1071 +msgid "Shapes" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1079 +#: ../../po/../src/verbs.cpp:2055 +msgid "Rectangle" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1085 +#: ../../po/../src/verbs.cpp:2057 +msgid "Ellipse" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1091 +#: ../../po/../src/verbs.cpp:2059 +msgid "Star" +msgstr "ኮከብ" + +#: ../../po/../src/dialogs/display-settings.cpp:1097 +#: ../../po/../src/verbs.cpp:2061 +msgid "Spiral" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1111 +#: ../../po/../src/verbs.cpp:2063 +msgid "Pencil" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1114 +msgid "Tolerance:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1115 +msgid "" +"This value affects the amount of smoothing applied to freehand lines; lower " +"values produce more uneven paths with more nodes" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1131 +#: ../../po/../src/verbs.cpp:2065 +#, fuzzy +msgid "Pen" +msgstr "መቶኛ" + +#: ../../po/../src/dialogs/display-settings.cpp:1140 +#: ../../po/../src/verbs.cpp:2067 +msgid "Calligraphy" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1147 +#: ../../po/../src/dialogs/text-edit.cpp:353 +#: ../../po/../src/ui/dialog/text-properties.cpp:37 +#: ../../po/../src/verbs.cpp:2069 +msgid "Text" +msgstr "ጽሑፍ" + +#: ../../po/../src/dialogs/display-settings.cpp:1157 +#: ../../po/../src/verbs.cpp:2071 +#, fuzzy +msgid "Gradient" +msgstr "ኢላማ፦" + +#: ../../po/../src/dialogs/display-settings.cpp:1164 +#: ../../po/../src/verbs.cpp:2077 +#, fuzzy +msgid "Connector" +msgstr "ዝጋ" + +#: ../../po/../src/dialogs/display-settings.cpp:1171 +#: ../../po/../src/verbs.cpp:2075 +msgid "Dropper" +msgstr "" + +#. Windows +#: ../../po/../src/dialogs/display-settings.cpp:1183 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:59 +msgid "Windows" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1188 +#, fuzzy +msgid "Save window geometry" +msgstr "ሰነድ አስቀምት" + +#: ../../po/../src/dialogs/display-settings.cpp:1189 +msgid "" +"Save the window size and position with each document (only for Inkscape SVG " +"format)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1196 +msgid "Dialogs are hidden in taskbar" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1197 +msgid "Whether dialog windows are to be hidden in the window manager taskbar" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1204 +msgid "Zoom when window is resized" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1205 +msgid "" +"Zoom drawing when document window is resized, to keep the same area visible " +"(this is the default which can be changed in any window using the button " +"above the right scrollbar)" +msgstr "" + +#. Clones +#: ../../po/../src/dialogs/display-settings.cpp:1213 +#: ../../po/../src/dialogs/find.cpp:624 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:60 +#, fuzzy +msgid "Clones" +msgstr "ዝጋ" + +#: ../../po/../src/dialogs/display-settings.cpp:1217 +msgid "When the original moves, its clones and linked offsets:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1229 +msgid "Move in parallel" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1230 +msgid "Clones are translated by the same vector as their original." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1237 +msgid "Stay unmoved" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1238 +msgid "Clones preserve their positions when their original is moved." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1245 +msgid "Move according to transform" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1246 +msgid "" +"Each clone moves according to the value of its transform= attribute. For " +"example, a rotated clone will move in a different direction than its " +"original." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1255 +msgid "When the original is deleted, its clones:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1267 +msgid "Are unlinked" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1267 +msgid "Orphaned clones are converted to regular objects." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1273 +#, fuzzy +msgid "Are deleted" +msgstr "ምርጡ" + +#: ../../po/../src/dialogs/display-settings.cpp:1273 +msgid "Orphaned clones are deleted along with their original." +msgstr "" + +#. Transforms +#. TRANSLATORS: Noun, i.e. transformations. +#: ../../po/../src/dialogs/display-settings.cpp:1289 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:61 +msgid "Transforms" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1292 +msgid "Scale stroke width" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1293 +#: ../../po/../src/widgets/select-toolbar.cpp:568 +msgid "When scaling objects, scale the stroke width by the same proportion" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1300 +msgid "Scale rounded corners in rectangles" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1301 +#: ../../po/../src/widgets/select-toolbar.cpp:580 +msgid "When scaling rectangles, scale the radii of rounded corners" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1308 +msgid "Transform gradients" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1309 +#: ../../po/../src/widgets/select-toolbar.cpp:592 +msgid "Transform gradients (in fill or stroke) along with the objects" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1316 +#, fuzzy +msgid "Transform patterns" +msgstr "ንድፍ፦" + +#: ../../po/../src/dialogs/display-settings.cpp:1317 +#: ../../po/../src/widgets/select-toolbar.cpp:604 +msgid "Transform patterns (in fill or stroke) along with the objects" +msgstr "" + +#. TRANSLATORS: How to specify the affine transformation in the SVG file. +#: ../../po/../src/dialogs/display-settings.cpp:1327 +msgid "Store transformation:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1338 +msgid "Optimized" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1339 +msgid "" +"If possible, apply transformation to objects without adding a transform= " +"attribute" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1346 +msgid "Preserved" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1347 +msgid "Always store transformation as a transform= attribute on objects" +msgstr "" + +#. Selecting +#: ../../po/../src/dialogs/display-settings.cpp:1355 +#, fuzzy +msgid "Selecting" +msgstr "ምርጫ" + +#: ../../po/../src/dialogs/display-settings.cpp:1357 +msgid "Ctrl+A, Tab, Shift+Tab:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1366 +#, fuzzy +msgid "Select only within current layer" +msgstr "ምርጡ" + +#: ../../po/../src/dialogs/display-settings.cpp:1367 +msgid "" +"Uncheck this to make keyboard selection commands work on objects in all " +"layers" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1374 +msgid "Ignore hidden objects" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1375 +msgid "" +"Uncheck this to be able to select objects that are hidden (either by " +"themselves or by being in a hidden group or layer)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1382 +msgid "Ignore locked objects" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1383 +msgid "" +"Uncheck this to be able to select objects that are locked (either by " +"themselves or by being in a locked group or layer)" +msgstr "" + +#. To be broken into: Display, Save, Export, SVG, Commands +#: ../../po/../src/dialogs/display-settings.cpp:1391 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:62 +msgid "Misc" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1394 +msgid "Default export resolution:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1395 +msgid "Default bitmap resolution (in dots per inch) in the Export dialog" +msgstr "" + +#. FIXME: add "Used for new exports; once exported, documents remember this value on per-object basis" when implemented +#: ../../po/../src/dialogs/display-settings.cpp:1396 +#: ../../po/../src/dialogs/export.cpp:442 +msgid "dpi" +msgstr "dpi" + +#. TRANSLATORS: When on, an imported bitmap creates an element; otherwise it is a +#. * rectangle with bitmap fill. +#: ../../po/../src/dialogs/display-settings.cpp:1407 +msgid "Import bitmap as " +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1408 +msgid "" +"When on, an imported bitmap creates an element; otherwise it is a " +"rectangle with bitmap fill" +msgstr "" + +#. TRANSLATORS: When on, the print out (currently Postscript) will have +#. * a comment with the each object's label visible, marking the section +#. * of the printing commands that represent the given object. +#: ../../po/../src/dialogs/display-settings.cpp:1418 +msgid "Add label comments to printing output" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1419 +msgid "" +"When on, a comment will be added to the raw print output, marking the " +"rendered output for an object with its label" +msgstr "" + +#. TRANSLATORS: When on, enable the effects menu, default is off +#: ../../po/../src/dialogs/display-settings.cpp:1427 +msgid "Enable script effects (requires restart) - EXPERIMENTAL" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1428 +msgid "" +"When on, the effects menu is enabled, allowing external effect scripts to be " +"called, requires restart before effective - EXPERIMENTAL" +msgstr "" + +#. TRANSLATORS: The maximum length of the Open Recent list in the File menu. +#: ../../po/../src/dialogs/display-settings.cpp:1436 +#, fuzzy +msgid "Max recent documents:" +msgstr "ሰነዱ ይታተም" + +#: ../../po/../src/dialogs/display-settings.cpp:1437 +msgid "The maximum length of the Open Recent list in the File menu" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1447 +msgid "Simplification threshold:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1448 +msgid "" +"How strong is the Simplify command by default. If you invoke this command " +"several times in quick succession, it will act more and more aggressively; " +"invoking it again after a pause restores the default threshold." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1469 +msgid "Oversample bitmaps:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1488 +msgid "2x2" +msgstr "2በ2" + +#: ../../po/../src/dialogs/display-settings.cpp:1494 +msgid "4x4" +msgstr "4በ4" + +#: ../../po/../src/dialogs/display-settings.cpp:1500 +msgid "8x8" +msgstr "8በ8" + +#: ../../po/../src/dialogs/display-settings.cpp:1506 +msgid "16x16" +msgstr "16በ16" + +#. "view_icon_preview" +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2143 +#, fuzzy +msgid "_Page" +msgstr "ገጽ" + +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2147 +msgid "_Drawing" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2149 +#, fuzzy +msgid "_Selection" +msgstr "ምርጫ" + +#: ../../po/../src/dialogs/export.cpp:133 +#, fuzzy +msgid "_Custom" +msgstr "የተለየ" + +#: ../../po/../src/dialogs/export.cpp:254 +msgid "Export area" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:300 +#, fuzzy +msgid "_x0:" +msgstr "x0፦" + +#: ../../po/../src/dialogs/export.cpp:305 +#, fuzzy +msgid "x_1:" +msgstr "x1፦" + +#: ../../po/../src/dialogs/export.cpp:316 +#, fuzzy +msgid "_y0:" +msgstr "y0፦" + +#: ../../po/../src/dialogs/export.cpp:321 +#, fuzzy +msgid "y_1:" +msgstr "y1፦" + +#: ../../po/../src/dialogs/export.cpp:406 +msgid "Bitmap size" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:416 +#, fuzzy +msgid "_Width:" +msgstr "ስፋት፦" + +#: ../../po/../src/dialogs/export.cpp:416 +#: ../../po/../src/dialogs/export.cpp:431 +msgid "pixels at" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:426 +#, fuzzy +msgid "dp_i" +msgstr "dpi" + +#: ../../po/../src/dialogs/export.cpp:448 +#, fuzzy +msgid "_Filename" +msgstr "ፋይል" + +#: ../../po/../src/dialogs/export.cpp:512 +msgid "_Browse..." +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:539 +#, fuzzy +msgid " _Export " +msgstr "መቶኛዎች" + +#: ../../po/../src/dialogs/export.cpp:541 +msgid "Export the bitmap file with these settings" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:968 +msgid "You have to enter a filename" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:973 +msgid "The chosen area to be exported is invalid" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:982 +#, c-format +msgid "Directory %s does not exist or is not a directory.\n" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:998 +#, fuzzy +msgid "Export in progress" +msgstr "የpng ፋይል ላኩ" + +#: ../../po/../src/dialogs/export.cpp:1004 +#, fuzzy, c-format +msgid "Exporting %s (%d x %d)" +msgstr "ቀለም ምስል %d በ %d፦ %s" + +#: ../../po/../src/dialogs/export.cpp:1031 +#, c-format +msgid "Could not export to filename %s.\n" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:1137 +msgid "Select a filename for exporting" +msgstr "" + +#: ../../po/../src/dialogs/filedialog.cpp:367 +#, fuzzy +msgid "No preview" +msgstr "አዲስ ቅድመ ዕይታ" + +#: ../../po/../src/dialogs/filedialog.cpp:468 +msgid "too large for preview" +msgstr "" + +#: ../../po/../src/dialogs/filedialog.cpp:762 +#: ../../po/../src/dialogs/filedialog.cpp:763 +#, fuzzy +msgid "All Images" +msgstr "ምስል" + +#: ../../po/../src/dialogs/filedialog.cpp:767 +#: ../../po/../src/dialogs/filedialog.cpp:768 +msgid "All Files" +msgstr "" + +#: ../../po/../src/dialogs/filedialog.cpp:774 +#: ../../po/../src/dialogs/filedialog.cpp:775 +#, fuzzy +msgid "All Inkscape Files" +msgstr "ሶዲፖዲ" + +#: ../../po/../src/dialogs/filedialog.cpp:1176 +#, fuzzy +msgid "Guess from extension" +msgstr "አጥፉ" + +#. ###### Add the file types menu +#. createFilterMenu(); +#. ###### Do we want the .xxx extension automatically added? +#: ../../po/../src/dialogs/filedialog.cpp:1261 +msgid "Append filename extension automatically" +msgstr "" + +#. TRANSLATORS: "%s" is replaced with "exact" or "partial" when this string is displayed +#: ../../po/../src/dialogs/find.cpp:378 +#, c-format +msgid "%d object found (out of %d), %s match." +msgid_plural "%d objects found (out of %d), %s match." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/dialogs/find.cpp:381 +#, fuzzy +msgid "exact" +msgstr "ጽሑፍ" + +#: ../../po/../src/dialogs/find.cpp:381 +msgid "partial" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:388 +#, fuzzy +msgid "No objects found" +msgstr "ያልተሰየመ ሰነድ" + +#: ../../po/../src/dialogs/find.cpp:546 +#, fuzzy +msgid "T_ype: " +msgstr "ዓይነት፦" + +#: ../../po/../src/dialogs/find.cpp:553 +msgid "Search in all object types" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:553 +msgid "All types" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:564 +msgid "Search all shapes" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:564 +msgid "All shapes" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:581 +msgid "Search rectangles" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:581 +#, fuzzy +msgid "Rectangles" +msgstr "መቶኛዎች" + +#: ../../po/../src/dialogs/find.cpp:586 +msgid "Search ellipses, arcs, circles" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:586 +msgid "Ellipses" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:591 +msgid "Search stars and polygons" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:591 +#, fuzzy +msgid "Stars" +msgstr "ኮከብ" + +#: ../../po/../src/dialogs/find.cpp:596 +#, fuzzy +msgid "Search spirals" +msgstr "አያያዝ ፍጠር" + +#: ../../po/../src/dialogs/find.cpp:596 +msgid "Spirals" +msgstr "" + +#. TRANSLATORS: polyline is a set of connected straight line segments +#. http://www.w3.org/TR/SVG11/shapes.html#PolylineElement +#: ../../po/../src/dialogs/find.cpp:609 +msgid "Search paths, lines, polylines" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:609 +msgid "Paths" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:614 +msgid "Search text objects" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:614 +#, fuzzy +msgid "Texts" +msgstr "ጽሑፍ" + +#: ../../po/../src/dialogs/find.cpp:619 +msgid "Search groups" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:619 +#, fuzzy +msgid "Groups" +msgstr "መድረክ" + +#: ../../po/../src/dialogs/find.cpp:624 +msgid "Search clones" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:629 +msgid "Search images" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:629 +#, fuzzy +msgid "Images" +msgstr "ምስል" + +#: ../../po/../src/dialogs/find.cpp:634 +msgid "Search offset objects" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:634 +msgid "Offsets" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:694 +#, fuzzy +msgid "_Text: " +msgstr "ጽሑፍ" + +#: ../../po/../src/dialogs/find.cpp:694 +msgid "Find objects by their text content (exact or partial match)" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:695 +msgid "_ID: " +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:695 +msgid "Find objects by the value of the id attribute (exact or partial match)" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:696 +#, fuzzy +msgid "_Style: " +msgstr "ዓይነት" + +#: ../../po/../src/dialogs/find.cpp:696 +msgid "" +"Find objects by the value of the style attribute (exact or partial match)" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:697 +#, fuzzy +msgid "_Attribute: " +msgstr "ጠባየ-አንቀጽ" + +#: ../../po/../src/dialogs/find.cpp:697 +msgid "Find objects by the name of an attribute (exact or partial match)" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:711 +#, fuzzy +msgid "Search in s_election" +msgstr "ምርጫ" + +#: ../../po/../src/dialogs/find.cpp:715 +msgid "Limit search to the current selection" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:720 +#, fuzzy +msgid "Search in current _layer" +msgstr "ምርጡ" + +#: ../../po/../src/dialogs/find.cpp:724 +#, fuzzy +msgid "Limit search to the current layer" +msgstr "ምርጡ" + +#: ../../po/../src/dialogs/find.cpp:729 +msgid "Include _hidden" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:733 +msgid "Include hidden objects in search" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:738 +msgid "Include l_ocked" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:742 +msgid "Include locked objects in search" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:753 +#, fuzzy +msgid "Clear values" +msgstr "ሁሉንም ሰርዝ" + +#: ../../po/../src/dialogs/find.cpp:754 +#, fuzzy +msgid "_Find" +msgstr "ወደ ነበረበት መልስ" + +#: ../../po/../src/dialogs/find.cpp:754 +msgid "Select objects matching all of the fields you filled in" +msgstr "" + +#: ../../po/../src/dialogs/iconpreview.cpp:145 +#, c-format +msgid "%d x %d" +msgstr "" + +#: ../../po/../src/dialogs/iconpreview.cpp:193 +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:857 +#: ../../po/../src/widgets/desktop-widget.cpp:1069 +msgid "Selection" +msgstr "ምርጫ" + +#: ../../po/../src/dialogs/iconpreview.cpp:195 +#, fuzzy +msgid "Selection only or whole document" +msgstr "ምርጡ" + +#: ../../po/../src/dialogs/iconpreview.cpp:203 +msgid "Refresh the icons" +msgstr "" + +#. Create the label for the object id +#: ../../po/../src/dialogs/item-properties.cpp:126 +#: ../../po/../src/dialogs/item-properties.cpp:327 +#: ../../po/../src/dialogs/item-properties.cpp:396 +#: ../../po/../src/dialogs/item-properties.cpp:403 +msgid "_Id" +msgstr "" + +#: ../../po/../src/dialogs/item-properties.cpp:135 +msgid "" +"The id= attribute (only letters, digits, and the characters .-_: allowed)" +msgstr "" + +#. Button for setting the object's id, label, title and description. +#: ../../po/../src/dialogs/item-properties.cpp:149 +#, fuzzy +msgid "_Set" +msgstr "ምርጡ" + +#. Create the label for the object label +#: ../../po/../src/dialogs/item-properties.cpp:158 +#, fuzzy +msgid "_Label" +msgstr "ዝቅተኛ" + +#: ../../po/../src/dialogs/item-properties.cpp:167 +msgid "A freeform label for the object" +msgstr "" + +#. Create the label for the object title +#: ../../po/../src/dialogs/item-properties.cpp:179 +#: ../../po/../src/dialogs/rdf.cpp:243 +#, fuzzy +msgid "Title" +msgstr "አርእስት፦" + +#. Create the frame for the object description +#: ../../po/../src/dialogs/item-properties.cpp:196 +#: ../../po/../src/dialogs/rdf.cpp:287 +#, fuzzy +msgid "Description" +msgstr "ምርጫ" + +#. Hide +#: ../../po/../src/dialogs/item-properties.cpp:223 +#, fuzzy +msgid "_Hide" +msgstr "ወደ ነበረበት መልስ" + +#: ../../po/../src/dialogs/item-properties.cpp:224 +msgid "Check to make the object invisible" +msgstr "" + +#. Lock +#. TRANSLATORS: "Lock" is a verb here +#: ../../po/../src/dialogs/item-properties.cpp:233 +msgid "L_ock" +msgstr "" + +#: ../../po/../src/dialogs/item-properties.cpp:234 +msgid "Check to make the object insensitive (not selectable by mouse)" +msgstr "" + +#: ../../po/../src/dialogs/item-properties.cpp:310 +#: ../../po/../src/dialogs/item-properties.cpp:317 +msgid "Ref" +msgstr "" + +#: ../../po/../src/dialogs/item-properties.cpp:398 +msgid "Id invalid! " +msgstr "" + +#: ../../po/../src/dialogs/item-properties.cpp:400 +msgid "Id exists! " +msgstr "" + +#: ../../po/../src/dialogs/layer-properties.cpp:50 +msgid "Layer name:" +msgstr "" + +#: ../../po/../src/dialogs/layer-properties.cpp:133 +#, fuzzy +msgid "Rename Layer" +msgstr "ምርጡ" + +#: ../../po/../src/dialogs/layer-properties.cpp:136 +#, fuzzy +msgid "_Rename" +msgstr "ፋይል" + +#. TRANSLATORS: This means "The layer has been renamed" +#: ../../po/../src/dialogs/layer-properties.cpp:147 +#, fuzzy +msgid "Renamed layer" +msgstr "ምርጡ" + +#: ../../po/../src/dialogs/layer-properties.cpp:151 +#, fuzzy +msgid "Add Layer" +msgstr "ዝቅተኛ" + +#: ../../po/../src/dialogs/layer-properties.cpp:153 +#, fuzzy +msgid "_Add" +msgstr "ጨምር" + +#: ../../po/../src/dialogs/layer-properties.cpp:167 +msgid "New layer created." +msgstr "" + +#: ../../po/../src/dialogs/object-attributes.cpp:34 +msgid "Href:" +msgstr "Href፦" + +#: ../../po/../src/dialogs/object-attributes.cpp:35 +msgid "Target:" +msgstr "ኢላማ፦" + +#: ../../po/../src/dialogs/object-attributes.cpp:36 +msgid "Type:" +msgstr "ዓይነት፦" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkRoleAttribute +#. Identifies the type of the related resource with an absolute URI +#: ../../po/../src/dialogs/object-attributes.cpp:39 +msgid "Role:" +msgstr "" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkArcRoleAttribute +#. For situations where the nature/role alone isn't enough, this offers an additional URI defining the purpose of the link. +#: ../../po/../src/dialogs/object-attributes.cpp:42 +msgid "Arcrole:" +msgstr "" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkTitleAttribute +#: ../../po/../src/dialogs/object-attributes.cpp:44 +msgid "Title:" +msgstr "አርእስት፦" + +#: ../../po/../src/dialogs/object-attributes.cpp:45 +msgid "Show:" +msgstr "አሳይ፦" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkActuateAttribute +#: ../../po/../src/dialogs/object-attributes.cpp:47 +msgid "Actuate:" +msgstr "" + +#: ../../po/../src/dialogs/object-attributes.cpp:52 +msgid "URL:" +msgstr "URL፦" + +#: ../../po/../src/dialogs/object-attributes.cpp:53 +msgid "X:" +msgstr "X፦" + +#: ../../po/../src/dialogs/object-attributes.cpp:54 +msgid "Y:" +msgstr "Y፦" + +#: ../../po/../src/dialogs/object-attributes.cpp:98 +#, c-format +msgid "%s attributes" +msgstr "" + +#: ../../po/../src/dialogs/object-properties.cpp:158 +#, fuzzy +msgid "_Fill" +msgstr "ፋይል" + +#: ../../po/../src/dialogs/object-properties.cpp:165 +#, fuzzy +msgid "Stroke _paint" +msgstr "ለጥፍ" + +#: ../../po/../src/dialogs/object-properties.cpp:172 +#, fuzzy +msgid "Stroke st_yle" +msgstr "ለጥፍ" + +#: ../../po/../src/dialogs/object-properties.cpp:183 +msgid "Master _opacity" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:244 +msgid "Name by which this document is formally known." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:246 +#, fuzzy +msgid "Date" +msgstr "ለጥፍ" + +#: ../../po/../src/dialogs/rdf.cpp:247 +msgid "Date associated with the creation of this document (YYYY-MM-DD)." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:249 +msgid "Format" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:250 +msgid "The physical or digital manifestation of this document (MIME type)." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:252 +#, fuzzy +msgid "Type" +msgstr "ዓይነት፦" + +#: ../../po/../src/dialogs/rdf.cpp:253 +msgid "Type of document (DCMI Type)." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:256 +#, fuzzy +msgid "Creator" +msgstr "ፍጠር" + +#: ../../po/../src/dialogs/rdf.cpp:257 +msgid "" +"Name of entity primarily responsible for making the content of this document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:259 +#, fuzzy +msgid "Rights" +msgstr "እርዝማኔ፦" + +#: ../../po/../src/dialogs/rdf.cpp:260 +msgid "" +"Name of entity with rights to the Intellectual Property of this document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:262 +msgid "Publisher" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:263 +msgid "Name of entity responsible for making this document available." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:266 +#, fuzzy +msgid "Identifier" +msgstr "ሴንቲ ሜትር" + +#: ../../po/../src/dialogs/rdf.cpp:267 +msgid "Unique URI to reference this document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:269 +msgid "Source" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:270 +msgid "Unique URI to reference the source of this document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:272 +#, fuzzy +msgid "Relation" +msgstr "ምርጫ" + +#: ../../po/../src/dialogs/rdf.cpp:273 +#, fuzzy +msgid "Unique URI to a related document." +msgstr "ያልተሰየመ ሰነድ" + +#: ../../po/../src/dialogs/rdf.cpp:275 +msgid "Language" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:276 +msgid "" +"Two-letter language tag with optional subtags for the language of this " +"document. (e.g. 'en-GB')" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:278 +msgid "Keywords" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:279 +msgid "" +"The topic of this document as comma-separated key words, phrases, or " +"classifications." +msgstr "" + +#. TRANSLATORS: "Coverage": the spatial or temporal characteristics of the content. +#. For info, see Appendix D of http://www.w3.org/TR/1998/WD-rdf-schema-19980409/ +#: ../../po/../src/dialogs/rdf.cpp:283 +msgid "Coverage" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:284 +msgid "Extent or scope of this document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:288 +msgid "A short account of the content of this document." +msgstr "" + +#. FIXME: need to handle 1 agent per line of input +#: ../../po/../src/dialogs/rdf.cpp:292 +#, fuzzy +msgid "Contributors" +msgstr "ሴንቲ ሜትሮች" + +#: ../../po/../src/dialogs/rdf.cpp:293 +msgid "" +"Names of entities responsible for making contributions to the content of " +"this document." +msgstr "" + +#. TRANSLATORS: URL to a page that defines the license for the document +#: ../../po/../src/dialogs/rdf.cpp:297 +msgid "URI" +msgstr "" + +#. TRANSLATORS: this is where you put a URL to a page that defines the license +#: ../../po/../src/dialogs/rdf.cpp:299 +msgid "URI to this document's license's namespace definition." +msgstr "" + +#. TRANSLATORS: fragment of XML representing the license of the document +#: ../../po/../src/dialogs/rdf.cpp:303 +#, fuzzy +msgid "Fragment" +msgstr "ኢላማ፦" + +#: ../../po/../src/dialogs/rdf.cpp:304 +msgid "XML fragment for the RDF 'License' section." +msgstr "" + +#: ../../po/../src/dialogs/stroke-style.cpp:774 +#: ../../po/../src/widgets/gradient-vector.cpp:263 +#: ../../po/../src/widgets/paint-selector.cpp:751 +msgid "No document selected" +msgstr "" + +#: ../../po/../src/dialogs/stroke-style.cpp:992 +msgid "Stroke width" +msgstr "" + +#. Join type +#. TRANSLATORS: The line join style specifies the shape to be used at the +#. corners of paths. It can be "miter", "round" or "bevel". +#: ../../po/../src/dialogs/stroke-style.cpp:1015 +msgid "Join:" +msgstr "አገጣጥም፦" + +#. TRANSLATORS: Miter join: joining lines with a sharp (pointed) corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1027 +msgid "Miter join" +msgstr "" + +#. TRANSLATORS: Round join: joining lines with a rounded corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1035 +msgid "Round join" +msgstr "" + +#. TRANSLATORS: Bevel join: joining lines with a blunted (flattened) corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1043 +msgid "Bevel join" +msgstr "" + +#. Miterlimit +#. TRANSLATORS: Miter limit: only for "miter join", this limits the length +#. of the sharp "spike" when the lines connect at too sharp an angle. +#. When two line segments meet at a sharp angle, a miter join results in a +#. spike that extends well beyond the connection point. The purpose of the +#. miter limit is to cut off such spikes (i.e. convert them into bevels) +#. when they become too long. +#: ../../po/../src/dialogs/stroke-style.cpp:1054 +msgid "Miter limit:" +msgstr "" + +#: ../../po/../src/dialogs/stroke-style.cpp:1062 +msgid "Maximum length of the miter (in units of stroke width)" +msgstr "" + +#. Cap type +#. TRANSLATORS: cap type specifies the shape for the ends of lines +#: ../../po/../src/dialogs/stroke-style.cpp:1075 +msgid "Cap:" +msgstr "" + +#. TRANSLATORS: Butt cap: the line shape does not extend beyond the end point +#. of the line; the ends of the line are square +#: ../../po/../src/dialogs/stroke-style.cpp:1086 +msgid "Butt cap" +msgstr "" + +#. TRANSLATORS: Round cap: the line shape extends beyond the end point of the +#. line; the ends of the line are rounded +#: ../../po/../src/dialogs/stroke-style.cpp:1093 +msgid "Round cap" +msgstr "" + +#. TRANSLATORS: Square cap: the line shape extends beyond the end point of the +#. line; the ends of the line are square +#: ../../po/../src/dialogs/stroke-style.cpp:1100 +msgid "Square cap" +msgstr "" + +#. Dash +#: ../../po/../src/dialogs/stroke-style.cpp:1106 +msgid "Dashes:" +msgstr "" + +#. TRANSLATORS: Path markers are an SVG feature that allows you to attach arbitrary shapes +#. (arrowheads, bullets, faces, whatever) to the start, end, or middle nodes of a path. +#: ../../po/../src/dialogs/stroke-style.cpp:1127 +#, fuzzy +msgid "Start Markers:" +msgstr "የኮከብ ምርጫዎች" + +#: ../../po/../src/dialogs/stroke-style.cpp:1137 +msgid "Mid Markers:" +msgstr "" + +#: ../../po/../src/dialogs/stroke-style.cpp:1148 +msgid "End Markers:" +msgstr "" + +#: ../../po/../src/dialogs/swatches.cpp:424 +#, c-format +msgid "Palettes directory (%s) is unavailable." +msgstr "" + +#. TODO: Insert widgets +#: ../../po/../src/dialogs/text-edit.cpp:199 +#: ../../po/../src/ui/dialog/text-properties.cpp:36 +#, fuzzy +msgid "Font" +msgstr "ነጥብ" + +#: ../../po/../src/dialogs/text-edit.cpp:216 +msgid "Layout" +msgstr "እቅድ" + +#: ../../po/../src/dialogs/text-edit.cpp:229 +msgid "Align lines left" +msgstr "" + +#. TRANSLATORS: `Center' here is a verb. +#: ../../po/../src/dialogs/text-edit.cpp:243 +#, fuzzy +msgid "Center lines" +msgstr "መሀከል Y፦" + +#: ../../po/../src/dialogs/text-edit.cpp:256 +msgid "Align lines right" +msgstr "" + +#: ../../po/../src/dialogs/text-edit.cpp:278 +msgid "Horizontal text" +msgstr "" + +#: ../../po/../src/dialogs/text-edit.cpp:292 +msgid "Vertical text" +msgstr "" + +#: ../../po/../src/dialogs/text-edit.cpp:307 +#, fuzzy +msgid "Line spacing:" +msgstr "ክፍተት X፦" + +#: ../../po/../src/dialogs/text-edit.cpp:400 +msgid "Set as default" +msgstr "" + +#: ../../po/../src/dialogs/tiledialog.cpp:603 +#, fuzzy +msgid "Rows:" +msgstr "አሳይ፦" + +#: ../../po/../src/dialogs/tiledialog.cpp:613 +msgid "Number of rows" +msgstr "" + +#: ../../po/../src/dialogs/tiledialog.cpp:617 +#, fuzzy +msgid "Equal height" +msgstr "እርዝማኔ፦" + +#: ../../po/../src/dialogs/tiledialog.cpp:627 +msgid "If not set, each row has the height of the tallest object in it" +msgstr "" + +#. #### Radio buttons to control vertical alignment #### +#. #### Radio buttons to control horizontal alignment #### +#: ../../po/../src/dialogs/tiledialog.cpp:637 +#: ../../po/../src/dialogs/tiledialog.cpp:708 +#, fuzzy +msgid "Align:" +msgstr "ኩልኩል፦" + +#: ../../po/../src/dialogs/tiledialog.cpp:672 +msgid " X " +msgstr "" + +#. #### Number of columns #### +#: ../../po/../src/dialogs/tiledialog.cpp:678 +#, fuzzy +msgid "Columns:" +msgstr "ዝጋ" + +#: ../../po/../src/dialogs/tiledialog.cpp:688 +msgid "Number of columns" +msgstr "" + +#: ../../po/../src/dialogs/tiledialog.cpp:692 +#, fuzzy +msgid "Equal width" +msgstr "ስፋት፦" + +#: ../../po/../src/dialogs/tiledialog.cpp:701 +msgid "If not set, each column has the width of the widest object in it" +msgstr "" + +#. #### Radio buttons to control spacing manually or to fit selection bbox #### +#: ../../po/../src/dialogs/tiledialog.cpp:746 +#, fuzzy +msgid "Fit into selection box" +msgstr "ምርጫ" + +#: ../../po/../src/dialogs/tiledialog.cpp:753 +#, fuzzy +msgid "Set spacing:" +msgstr "ክፍተት Y፦" + +#. #### Y Padding #### +#: ../../po/../src/dialogs/tiledialog.cpp:777 +#, fuzzy +msgid "Row spacing: " +msgstr "ክፍተት X፦" + +#: ../../po/../src/dialogs/tiledialog.cpp:786 +msgid "Vertical spacing between rows" +msgstr "" + +#. #### X padding #### +#: ../../po/../src/dialogs/tiledialog.cpp:795 +#, fuzzy +msgid "Column spacing:" +msgstr "ክፍተት X፦" + +#: ../../po/../src/dialogs/tiledialog.cpp:804 +msgid "Horizontal spacing between columns" +msgstr "" + +#: ../../po/../src/dialogs/tiledialog.cpp:818 +#, fuzzy +msgid "Arrange selected objects" +msgstr "ምርጡ" + +#: ../../po/../src/dialogs/xml-tree.cpp:178 +msgid "Click to select nodes, drag to rearrange." +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:189 +msgid "Click attribute to edit." +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:193 +#, c-format +msgid "" +"Attribute %s selected. Press Ctrl+Enter when done editing to " +"commit changes." +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:284 +msgid "Drag to reorder nodes" +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:304 +msgid "New element node" +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:326 +msgid "New text node" +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:347 +msgid "Duplicate node" +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:368 +msgid "Delete node" +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:384 +msgid "Unindent node" +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:399 +msgid "Indent node" +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:411 +msgid "Raise node" +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:423 +msgid "Lower node" +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:468 +msgid "Delete attribute" +msgstr "" + +#. TRANSLATORS: "Attribute" is a noun here +#: ../../po/../src/dialogs/xml-tree.cpp:513 +msgid "Attribute name" +msgstr "" + +#. TRANSLATORS: "Set" is a verb here +#: ../../po/../src/dialogs/xml-tree.cpp:533 +msgid "Set attribute" +msgstr "" + +#. TRANSLATORS: "Set" is a verb here +#: ../../po/../src/dialogs/xml-tree.cpp:535 +#, fuzzy +msgid "Set" +msgstr "ምርጡ" + +#. TRANSLATORS: "Attribute" is a noun here +#: ../../po/../src/dialogs/xml-tree.cpp:558 +msgid "Attribute value" +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:1318 +msgid "New element node..." +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:1339 +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:100 +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:98 +msgid "Cancel" +msgstr "ተወው" + +#: ../../po/../src/dialogs/xml-tree.cpp:1345 +msgid "Create" +msgstr "ፍጠር" + +#: ../../po/../src/dialogs/xml-tree.cpp:1458 +#, c-format +msgid "" +"Cannot set %s: Another element with value %s already exists!" +msgstr "" + +#: ../../po/../src/document.cpp:369 +#, c-format +msgid "New document %d" +msgstr "አዲስ ሰነድ %d" + +#: ../../po/../src/document.cpp:401 +#, c-format +msgid "Memory document %d" +msgstr "" + +#: ../../po/../src/document.cpp:524 +#, c-format +msgid "Unnamed document %d" +msgstr "" + +#. We hit green anchor, closing Green-Blue-Red +#: ../../po/../src/draw-context.cpp:441 +msgid "Path is closed." +msgstr "" + +#. We hit bot start and end of single curve, closing paths +#: ../../po/../src/draw-context.cpp:456 +msgid "Closing path." +msgstr "" + +#. alpha of color under cursor, to show in the statusbar +#. locale-sensitive printf is OK, since this goes to the UI, not into SVG +#: ../../po/../src/dropper-context.cpp:354 +#, c-format +msgid " alpha %.3g" +msgstr "" + +#. where the color is picked, to show in the statusbar +#: ../../po/../src/dropper-context.cpp:356 +#, c-format +msgid ", averaged with radius %d" +msgstr "" + +#: ../../po/../src/dropper-context.cpp:356 +msgid " under cursor" +msgstr "" + +#. message, to show in the statusbar +#: ../../po/../src/dropper-context.cpp:358 +msgid "Release mouse to set color." +msgstr "" + +#: ../../po/../src/dropper-context.cpp:358 +#: ../../po/../src/tools-switch.cpp:207 +msgid "" +"Click to set fill, Shift+click to set stroke; drag to " +"average color in area; with Alt to pick inverse color; Ctrl+C " +"to copy the color under mouse to clipboard" +msgstr "" + +#: ../../po/../src/extension/dependency.cpp:244 +msgid "Dependency::" +msgstr "" + +#: ../../po/../src/extension/dependency.cpp:245 +#, fuzzy +msgid " type: " +msgstr "ዓይነት፦" + +#: ../../po/../src/extension/dependency.cpp:246 +#, fuzzy +msgid " location: " +msgstr "ምርጫ" + +#: ../../po/../src/extension/dependency.cpp:247 +msgid " string: " +msgstr "" + +#: ../../po/../src/extension/dependency.cpp:250 +#, fuzzy +msgid " description: " +msgstr "ምርጫ" + +#. static int i = 0; +#. std::cout << "Checking module[" << i++ << "]: " << name << std::endl; +#: ../../po/../src/extension/extension.cpp:244 +msgid "" +" This is caused by an improper .inx file for this extension. An improper ." +"inx file could have been caused by a faulty installation of Inkscape." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:247 +msgid "an ID was not defined for it." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:251 +msgid "there was no name defined for it." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:255 +msgid "the XML description of it got lost." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:259 +msgid "no implementation was defined for the extension." +msgstr "" + +#. std::cout << "Failed: " << *(_deps[i]) << std::endl; +#: ../../po/../src/extension/extension.cpp:266 +msgid "a dependency was not met." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:286 +msgid "Extension \"" +msgstr "" + +#: ../../po/../src/extension/extension.cpp:286 +msgid "\" failed to load because " +msgstr "" + +#: ../../po/../src/extension/extension.cpp:565 +#, c-format +msgid "Could not create extension error log file '%s'" +msgstr "" + +#. This is some filler text, needs to change before relase +#: ../../po/../src/extension/error-file.cpp:56 +msgid "" +"One or more extensions failed to load\n" +"\n" +"The failed extensions have been skipped. Inkscape will continue to run " +"normally but those extensions will be unavailable. For details to " +"troubleshoot this problem, please refer to the error log located at: " +msgstr "" + +#. This is some filler text, needs to change before relase +#: ../../po/../src/extension/error-file.cpp:65 +msgid "Show dialog on startup" +msgstr "" + +#: ../../po/../src/extension/implementation/script.cpp:845 +msgid "" +"Inkscape has received an error from the script that it called. The text " +"returned with the error is included below. Inkscape will continue working, " +"but the action you requested has been cancelled." +msgstr "" + +#: ../../po/../src/extension/implementation/script.cpp:858 +msgid "" +"Inkscape has received additional data from the script executed. The script " +"did not return an error, but this may indicate the results will not be as " +"expected." +msgstr "" + +#: ../../po/../src/extension/init.cpp:173 +msgid "Null external module directory name. Modules will not be loaded." +msgstr "" + +#: ../../po/../src/extension/init.cpp:187 +#, c-format +msgid "" +"Modules directory (%s) is unavailable. External modules in that directory " +"will not be loaded." +msgstr "" + +#: ../../po/../src/extension/internal/gnome.cpp:80 +msgid "Select printer" +msgstr "ማተሚያ ምረጥ" + +#: ../../po/../src/extension/internal/gnome.cpp:131 +#, fuzzy +msgid "Inkscape: Print Preview" +msgstr "ሶዲፖዲ (የሰነድ ስም %s..)፦ የቅድመ ህትመት ዕይታ" + +#: ../../po/../src/extension/internal/grid.cpp:213 +#, fuzzy +msgid "Line Width" +msgstr "ስፋት፦" + +#: ../../po/../src/extension/internal/grid.cpp:214 +msgid "Horizontal Spacing" +msgstr "" + +#: ../../po/../src/extension/internal/grid.cpp:215 +msgid "Vertical Spacing" +msgstr "" + +#: ../../po/../src/extension/internal/grid.cpp:216 +msgid "Horizontal Offset" +msgstr "" + +#: ../../po/../src/extension/internal/grid.cpp:217 +msgid "Vertical Offset" +msgstr "" + +#: ../../po/../src/extension/internal/ps.cpp:123 +#, fuzzy +msgid "Print Destination" +msgstr "አቀማመጥ፦" + +#. Print properties frame +#: ../../po/../src/extension/internal/ps.cpp:138 +#, fuzzy +msgid "Print properties" +msgstr "የአያያዝ ምርጫዎች" + +#: ../../po/../src/extension/internal/ps.cpp:145 +msgid "Print using PostScript operators" +msgstr "" + +#: ../../po/../src/extension/internal/ps.cpp:147 +msgid "" +"Use PostScript vector operators. The resulting image is usually smaller in " +"file size and can be arbitrarily scaled, but alpha transparency and patterns " +"will be lost." +msgstr "" + +#: ../../po/../src/extension/internal/ps.cpp:152 +msgid "Print as bitmap" +msgstr "" + +#: ../../po/../src/extension/internal/ps.cpp:154 +msgid "" +"Print everything as bitmap. The resulting image is usually larger in file " +"size and cannot be arbitrarily scaled without quality loss, but all objects " +"will be rendered exactly as displayed." +msgstr "" + +#: ../../po/../src/extension/internal/ps.cpp:168 +msgid "Preferred resolution (dots per inch) of bitmap" +msgstr "" + +#: ../../po/../src/extension/internal/ps.cpp:182 +#, fuzzy +msgid "Resolution:" +msgstr "ምርጫ" + +#. Print destination frame +#: ../../po/../src/extension/internal/ps.cpp:186 +msgid "Print destination" +msgstr "" + +#: ../../po/../src/extension/internal/ps.cpp:192 +msgid "" +"Use '> filename' to print to file.\n" +"Use '| prog arg...' to pipe to a program." +msgstr "" + +#: ../../po/../src/extension/internal/ps.cpp:1227 +msgid "write error occurred" +msgstr "" + +#: ../../po/../src/extension/prefdialog.cpp:21 +#, fuzzy +msgid " Preferences" +msgstr "ሶዲፖዲ" + +#. We can't call sp_ui_error_dialog because we may be +#. running from the console, in which case calling sp_ui +#. routines will cause a segfault. See bug 1000350 - bryce +#. sp_ui_error_dialog(_("Format autodetect failed. The file is being opened as SVG.")); +#: ../../po/../src/extension/system.cpp:105 +msgid "Format autodetect failed. The file is being opened as SVG." +msgstr "" + +#. TRANSLATORS: default.svg is localizable - this is the name of the default document +#. template. This way you can localize the default pagesize, translate the name of +#. the default layer, etc. If you wish to localize this file, please create a +#. localized share/templates/default.xx.svg file, where xx is your language code. +#: ../../po/../src/file.cpp:133 +#, fuzzy +msgid "default.svg" +msgstr "ነባሮች" + +#: ../../po/../src/file.cpp:215 ../../po/../src/file.cpp:900 +#, c-format +msgid "Failed to load the requested file %s" +msgstr "" + +#: ../../po/../src/file.cpp:240 +#, fuzzy +msgid "Document not saved yet. Cannot revert." +msgstr "የሰነድ ስም፦" + +#: ../../po/../src/file.cpp:246 +#, c-format +msgid "Changes will be lost! Are you sure you want to reload document %s?" +msgstr "" + +#: ../../po/../src/file.cpp:266 +#, fuzzy +msgid "Document reverted." +msgstr "የሰነድ ስም፦" + +#: ../../po/../src/file.cpp:268 +#, fuzzy +msgid "Document not reverted." +msgstr "የሰነድ ስም፦" + +#: ../../po/../src/file.cpp:382 +msgid "Select file to open" +msgstr "" + +#: ../../po/../src/file.cpp:518 +#, c-format +msgid "Removed %i unused definition in <defs>." +msgid_plural "Removed %i unused definitions in <defs>." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/file.cpp:523 +msgid "No unused definitions in <defs>." +msgstr "" + +#: ../../po/../src/file.cpp:548 +#, c-format +msgid "" +"No Inkscape extension found to save document (%s). This may have been " +"caused by an unknown filename extension." +msgstr "" + +#: ../../po/../src/file.cpp:549 ../../po/../src/file.cpp:557 +#, fuzzy +msgid "Document not saved." +msgstr "የሰነድ ስም፦" + +#: ../../po/../src/file.cpp:556 +#, c-format +msgid "File %s could not be saved." +msgstr "" + +#: ../../po/../src/file.cpp:566 +#, fuzzy +msgid "Document saved." +msgstr "የሰነድ ስም፦" + +#: ../../po/../src/file.cpp:614 +#, c-format +msgid "drawing%s" +msgstr "" + +#: ../../po/../src/file.cpp:620 +#, c-format +msgid "drawing-%d%s" +msgstr "" + +#: ../../po/../src/file.cpp:655 +#, fuzzy +msgid "Select file to save to" +msgstr "ማተሚያ ምረጥ" + +#: ../../po/../src/file.cpp:739 +msgid "No changes need to be saved." +msgstr "" + +#: ../../po/../src/file.cpp:926 +msgid "Select file to import" +msgstr "" + +#: ../../po/../src/gradient-context.cpp:263 +msgid "Ctrl: snap gradient angle" +msgstr "" + +#: ../../po/../src/gradient-context.cpp:264 +msgid "Shift: draw gradient around the starting point" +msgstr "" + +#. We did an undoable action, but sp_document_done will be called by the knot when released +#. status text; we do not track coords because this branch is run once, not all the time +#. during drag +#: ../../po/../src/gradient-context.cpp:462 +#, c-format +msgid "Gradient for %d objects; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/gradient-context.cpp:464 +msgid "Select objects on which to create gradient." +msgstr "" + +#: ../../po/../src/gradient-drag.cpp:65 +msgid "Linear gradient start" +msgstr "" + +#. POINT_LG_P1 +#: ../../po/../src/gradient-drag.cpp:66 +msgid "Linear gradient end" +msgstr "" + +#: ../../po/../src/gradient-drag.cpp:67 +msgid "Radial gradient center" +msgstr "" + +#: ../../po/../src/gradient-drag.cpp:68 ../../po/../src/gradient-drag.cpp:69 +msgid "Radial gradient radius" +msgstr "" + +#: ../../po/../src/gradient-drag.cpp:70 +msgid "Radial gradient focus" +msgstr "" + +#: ../../po/../src/gradient-drag.cpp:659 +#, c-format +msgid "" +"%s for: %s%s; drag with Ctrl to snap angle, with Ctrl+Alt to " +"preserve angle, with Ctrl+Shift to scale around center" +msgstr "" + +#: ../../po/../src/gradient-drag.cpp:662 +msgid " (stroke)" +msgstr "" + +#: ../../po/../src/gradient-drag.cpp:665 +msgid "" +"Radial gradient center and focus; drag with Shift to " +"separate focus" +msgstr "" + +#: ../../po/../src/gradient-drag.cpp:667 +#, c-format +msgid "" +"Gradient point shared by %d gradients; drag with Shift to " +"separate" +msgstr "" + +#: ../../po/../src/helper/units.cpp:40 +msgid "Unit" +msgstr "ክፍል" + +#: ../../po/../src/helper/units.cpp:40 +msgid "Units" +msgstr "ክፍሎች" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Point" +msgstr "ነጥብ" + +#: ../../po/../src/helper/units.cpp:41 +msgid "pt" +msgstr "ነጥብ" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Points" +msgstr "ነጥቦች" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Pt" +msgstr "ነጥብ" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Pixel" +msgstr "" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Pixels" +msgstr "" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Px" +msgstr "Px" + +#. You can add new elements from this point forward +#: ../../po/../src/helper/units.cpp:44 ../share/extensions/straightseg.inx.h:2 +msgid "Percent" +msgstr "መቶኛ" + +#: ../../po/../src/helper/units.cpp:44 +msgid "Percents" +msgstr "መቶኛዎች" + +#: ../../po/../src/helper/units.cpp:45 +msgid "Millimeter" +msgstr "ሚሊ ሜትር" + +#: ../../po/../src/helper/units.cpp:45 +msgid "mm" +msgstr "ሚ/ሜ" + +#: ../../po/../src/helper/units.cpp:45 +msgid "Millimeters" +msgstr "ሚሊ ሜትሮች" + +#: ../../po/../src/helper/units.cpp:46 +msgid "Centimeter" +msgstr "ሴንቲ ሜትር" + +#: ../../po/../src/helper/units.cpp:46 +msgid "cm" +msgstr "ሴ/ሜ" + +#: ../../po/../src/helper/units.cpp:46 +msgid "Centimeters" +msgstr "ሴንቲ ሜትሮች" + +#: ../../po/../src/helper/units.cpp:47 +msgid "Meter" +msgstr "ሜትር" + +#: ../../po/../src/helper/units.cpp:47 +msgid "m" +msgstr "ሜ" + +#: ../../po/../src/helper/units.cpp:47 +#, fuzzy +msgid "Meters" +msgstr "ሜትር" + +#. no svg_unit +#: ../../po/../src/helper/units.cpp:48 +msgid "Inch" +msgstr "ኢንች" + +#: ../../po/../src/helper/units.cpp:48 +msgid "in" +msgstr "ኢንቾች" + +#: ../../po/../src/helper/units.cpp:48 +msgid "Inches" +msgstr "ኢንቾች" + +#. Volatiles do not have default, so there are none here +#. TRANSLATORS: for info, see http://www.w3.org/TR/REC-CSS2/syndata.html#length-units +#: ../../po/../src/helper/units.cpp:51 +msgid "Em square" +msgstr "የEm አደባባይ" + +#: ../../po/../src/helper/units.cpp:51 +msgid "em" +msgstr "em" + +#: ../../po/../src/helper/units.cpp:51 +msgid "Em squares" +msgstr "የEm አደባባዮች" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/REC-CSS2/syndata.html#length-units +#: ../../po/../src/helper/units.cpp:53 +msgid "Ex square" +msgstr "የEx አደባባይ" + +#: ../../po/../src/helper/units.cpp:53 +msgid "ex" +msgstr "ex" + +#: ../../po/../src/helper/units.cpp:53 +msgid "Ex squares" +msgstr "የEx አደባባዮች" + +#: ../../po/../src/inkscape.cpp:468 +msgid "Untitled document" +msgstr "ያልተሰየመ ሰነድ" + +#. Show nice dialog box +#: ../../po/../src/inkscape.cpp:497 +msgid "Inkscape encountered an internal error and will close now.\n" +msgstr "" + +#: ../../po/../src/inkscape.cpp:498 +msgid "" +"Automatic backups of unsaved documents were done to the following " +"locations:\n" +msgstr "" + +#: ../../po/../src/inkscape.cpp:499 +msgid "Automatic backup of the following documents failed:\n" +msgstr "" + +#: ../../po/../src/inkscape.cpp:634 +#, c-format +msgid "" +"Cannot create directory %s.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:635 +#, c-format +msgid "" +"%s is not a valid directory.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:636 +#, c-format +msgid "" +"Cannot create file %s.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:637 +#, c-format +msgid "" +"Cannot write file %s.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:638 +msgid "" +"Although Inkscape will run, it will use default settings,\n" +"and any changes made in preferences will not be saved." +msgstr "" + +#: ../../po/../src/inkscape.cpp:708 +#, c-format +msgid "" +"%s is not a regular file.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:709 +#, c-format +msgid "" +"%s not a valid XML file, or\n" +"you don't have read permissions on it.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:711 +#, c-format +msgid "" +"%s is not a valid menus file.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:712 +msgid "" +"Inkscape will run with default menus.\n" +"New menus will not be saved." +msgstr "" + +#. sp_ui_menu_append_check_item_from_verb(m, view, _("_Menu"), _("Show or hide the menu bar"), "menu", +#. checkitem_toggled, checkitem_update, 0); +#: ../../po/../src/interface.cpp:753 +msgid "Commands Bar" +msgstr "" + +#: ../../po/../src/interface.cpp:753 +#, fuzzy +msgid "Show or hide the Commands bar (under the menu)" +msgstr "ወሰንን አሳይ" + +#: ../../po/../src/interface.cpp:755 +#, fuzzy +msgid "Tool Controls" +msgstr "የመስሪያውን ምርጫዎች" + +#: ../../po/../src/interface.cpp:755 +#, fuzzy +msgid "Show or hide the Tool Controls panel" +msgstr "ወሰንን አሳይ" + +#: ../../po/../src/interface.cpp:757 +msgid "_Toolbox" +msgstr "" + +#: ../../po/../src/interface.cpp:757 +msgid "Show or hide the main toolbox (on the left)" +msgstr "" + +#: ../../po/../src/interface.cpp:763 +msgid "_Statusbar" +msgstr "" + +#: ../../po/../src/interface.cpp:763 +msgid "Show or hide the statusbar (at the bottom of the window)" +msgstr "" + +#: ../../po/../src/interface.cpp:820 +#, c-format +msgid "Verb \"%s\" Unknown" +msgstr "" + +#. TRANSLATORS: #%s is the id of the group e.g. , not a number. +#: ../../po/../src/interface.cpp:930 +#, fuzzy, c-format +msgid "Enter group #%s" +msgstr "አስተካክል" + +#: ../../po/../src/interface.cpp:941 +msgid "Go to parent" +msgstr "" + +#: ../../po/../src/interface.cpp:972 +msgid "Could not parse SVG data" +msgstr "" + +#: ../../po/../src/interface.cpp:1135 +#, c-format +msgid "Overwrite %s" +msgstr "" + +#: ../../po/../src/interface.cpp:1153 +#, c-format +msgid "" +"The file %s already exists. Do you want to overwrite that file with the " +"current document?" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:59 +msgid "Jabber connection lost." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:72 +#, c-format +msgid "Sending message; %u message remaining in send queue." +msgid_plural "Sending message; %u messages remaining in send queue." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:78 +msgid "Receive queue empty." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:154 +#, c-format +msgid "Receiving change; %u change left to process." +msgid_plural "Receiving change; %u changes left to process." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:157 +#, c-format +msgid "%s has left the chatroom." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:221 +msgid "Nickname %1 is already in use. Please choose a different nickname." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:225 +msgid "An error was encountered while attempting to connect to the server." +msgstr "" + +#. Check to see if the user made any modifications to this document. If so, +#. we want to give them the option of (1) letting us clear their document or (2) +#. opening a new, blank document for the whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:131 +msgid "%1 has invited you to a whiteboard session." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:132 +msgid "Incoming whiteboard invitation from %1" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:135 +msgid "Do you wish to accept %1's whiteboard session invitation?" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:137 +msgid "" +"Would you like to accept %1's invitation in a new document window?\n" +"Accepting the invitation in your current window will discard unsaved changes." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:143 +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:198 +#, fuzzy +msgid "Accept invitation" +msgstr "ምርጫ" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:144 +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:199 +msgid "Decline invitation" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:145 +#, fuzzy +msgid "Accept invitation in new document window" +msgstr "ሰነድ አስቀምት" + +#. We could not create a new desktop; ask the user if she or he wants to +#. replace the current document and accept the invitation, or reject the invitation. +#. TRANSLATORS: %1 is a userid here +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:196 +msgid "" +"A new document window could not be opened for a whiteboard session with %" +"1" +msgstr "" + +#. TRANSLATORS: %1 is the peer whom refused our invitation. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:238 +msgid "" +"The user %1 has refused your " +"whiteboard invitation.\n" +"\n" +msgstr "" + +#. TRANSLATORS: %1 is the peer whom refused our invitation, %2 is our Jabber identity. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:241 +msgid "" +"You are still connected to a Jabber server as %2, and may send an " +"invitation to %1 again, or you may send an invitation to a different " +"user." +msgstr "" + +#. TRANSLATORS: %1 is the peer whom we tried to contact, but is already in a whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:252 +msgid "" +"The user %1 is already in a " +"whiteboard session.\n" +"\n" +msgstr "" + +#. TRANSLATORS: %1 is the peer whom we tried to contact, but is already in a whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:255 +msgid "" +"You are still connected to a Jabber server as %1, and may send an " +"invitation to a different user." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/invitation-confirm-dialog.cpp:26 +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:24 +msgid "_Write session file:" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/message-processors.cpp:145 +#, c-format +msgid "%s has joined the chatroom." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/message-queue.cpp:87 +#, c-format +msgid "%u change in receive queue." +msgid_plural "%u changes in receive queue." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/jabber_whiteboard/message-queue.cpp:117 +#, c-format +msgid "%u change in send queue." +msgid_plural "%u changes in send queue." +msgstr[0] "" +msgstr[1] "" + +#. if ID is NULL, then we have a real problem -- we were not able to find a key +#. nor generate one. The only thing we can really do here is abort, since we have +#. no way to let the other client(s) uniquely identify this object. +#. FIXME: If this indicates a programming bug, then don't request translation with +#. * _(...): it is most useful in untranslated form so that developers may search for +#. * it when someone reports it in a bug report (as we want users to do for all bugs, +#. * as indicated by it being a g_warning string). +#. * +#. * Otherwise, if it is not a programming bug but a network error or a bug in the +#. * remote peer (perhaps running different software) or whatever, then present it in +#. * an alert box, and avoid use of technical jargon `NULL'. +#. +#: ../../po/../src/jabber_whiteboard/message-utilities.cpp:171 +msgid "" +"ID for new object is NULL even after generation and lookup attempts: the new " +"object will NOT be sent, nor will any of its child objects!" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:60 +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:995 +msgid "Select a location and filename" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:62 +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:997 +#, fuzzy +msgid "Set filename" +msgstr "ፋይልን አስቀምጥ" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:301 +msgid "No SSL certificate was found." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:304 +msgid "The SSL certificate provided by the Jabber server is untrusted." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:307 +msgid "The SSL certificate provided by the Jabber server is expired." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:310 +msgid "" +"The SSL certificate provided by the Jabber server has not been activated." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:313 +msgid "" +"The SSL certificate provided by the Jabber server contains a hostname that " +"does not match the Jabber server's hostname." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:316 +msgid "" +"The SSL certificate provided by the Jabber server contains an invalid " +"fingerprint." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:319 +msgid "An unknown error occurred while setting up the SSL connection." +msgstr "" + +#. TRANSLATORS: %1 is the message that describes the specific error that occurred when +#. establishing the SSL connection. +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:325 +msgid "" +"%1\n" +"\n" +"Do you wish to continue connecting to the Jabber server?" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:328 +msgid "Continue connecting and ignore further errors" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:329 +msgid "Continue connecting, but warn me of further errors" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:330 +#, fuzzy +msgid "Cancel connection" +msgstr "ምርጫ" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:777 +#, c-format +msgid "Established whiteboard session with %s." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:785 +#, c-format +msgid "%s has left the whiteboard session." +msgstr "" + +#. Inform the user +#. TRANSLATORS: %1 is the name of the user that disconnected, %2 is the name of the user whom the disconnected user disconnected from. +#. This message is not used in a chatroom context. +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:790 +msgid "" +"The user %1 has left the " +"whiteboard session.\n" +"\n" +msgstr "" + +#. TRANSLATORS: %1 and %2 are userids +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:792 +msgid "" +"You are still connected to a Jabber server as %2, and may establish a " +"new session to %1 or a different user." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:988 +msgid "" +"Could not open file %1 for session recording.\n" +"The error encountered was: %2.\n" +"\n" +"You may select a different location to record the session, or you may opt to " +"not record this session." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:990 +msgid "Choose a different location" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:991 +msgid "Skip session recording" +msgstr "" + +#: ../../po/../src/knot.cpp:673 +msgid "Node or handle drag canceled." +msgstr "" + +#: ../../po/../src/libnrtype/FontFactory.cpp:358 +msgid "Ignoring font without family that will crash Pango" +msgstr "" + +#: ../../po/../src/main.cpp:395 +msgid "Print the Inkscape version number" +msgstr "" + +#: ../../po/../src/main.cpp:400 +msgid "Do not use X server (only process files from console)" +msgstr "" + +#: ../../po/../src/main.cpp:405 +msgid "Try to use X server (even if $DISPLAY is not set)" +msgstr "" + +#: ../../po/../src/main.cpp:410 +msgid "Open specified document(s) (option string may be excluded)" +msgstr "" + +#: ../../po/../src/main.cpp:411 ../../po/../src/main.cpp:416 +#: ../../po/../src/main.cpp:421 ../../po/../src/main.cpp:483 +#: ../../po/../src/main.cpp:488 ../../po/../src/main.cpp:493 +msgid "FILENAME" +msgstr "የፋይል ስም" + +#: ../../po/../src/main.cpp:415 +msgid "Print document(s) to specified output file (use '| program' for pipe)" +msgstr "" + +#: ../../po/../src/main.cpp:420 +msgid "Export document to a PNG file" +msgstr "" + +#: ../../po/../src/main.cpp:425 +msgid "The resolution used for exporting SVG into bitmap (default 90)" +msgstr "" + +#: ../../po/../src/main.cpp:426 +msgid "DPI" +msgstr "DPI" + +#: ../../po/../src/main.cpp:430 +msgid "" +"Exported area in SVG user units (default is the canvas; 0,0 is lower-left " +"corner)" +msgstr "" + +#: ../../po/../src/main.cpp:431 +msgid "x0:y0:x1:y1" +msgstr "x0:y0:x1:y1" + +#: ../../po/../src/main.cpp:435 +msgid "Exported area is the entire drawing (not canvas)" +msgstr "" + +#: ../../po/../src/main.cpp:440 +msgid "" +"Snap the bitmap export area outwards to the nearest integer values (in SVG " +"user units)" +msgstr "" + +#: ../../po/../src/main.cpp:445 +msgid "The width of exported bitmap in pixels (overrides export-dpi)" +msgstr "" + +#: ../../po/../src/main.cpp:446 +msgid "WIDTH" +msgstr "ስፋት" + +#: ../../po/../src/main.cpp:450 +msgid "The height of exported bitmap in pixels (overrides export-dpi)" +msgstr "" + +#: ../../po/../src/main.cpp:451 +msgid "HEIGHT" +msgstr "እርዝማኔ" + +#: ../../po/../src/main.cpp:455 +msgid "The ID of the object to export (overrides export-area)" +msgstr "" + +#: ../../po/../src/main.cpp:456 ../../po/../src/main.cpp:532 +msgid "ID" +msgstr "" + +#. TRANSLATORS: this means: "Only export the object whose id is given in --export-id". +#. See "man inkscape" for details. +#: ../../po/../src/main.cpp:462 +msgid "" +"Export just the object with export-id, hide all others (only with export-id)" +msgstr "" + +#: ../../po/../src/main.cpp:467 +msgid "Use stored filename and DPI hints when exporting (only with export-id)" +msgstr "" + +#: ../../po/../src/main.cpp:472 +msgid "Background color of exported bitmap (any SVG-supported color string)" +msgstr "" + +#: ../../po/../src/main.cpp:473 +msgid "COLOR" +msgstr "ቀለም" + +#: ../../po/../src/main.cpp:477 +msgid "Background opacity of exported bitmap (either 0.0 to 1.0, or 1 to 255)" +msgstr "" + +#: ../../po/../src/main.cpp:478 +msgid "VALUE" +msgstr "" + +#: ../../po/../src/main.cpp:482 +msgid "Export document to plain SVG file (no sodipodi or inkscape namespaces)" +msgstr "" + +#: ../../po/../src/main.cpp:487 +msgid "Export document to a PS file" +msgstr "" + +#: ../../po/../src/main.cpp:492 +msgid "Export document to an EPS file" +msgstr "" + +#: ../../po/../src/main.cpp:497 +msgid "Convert text object to paths on export (EPS)" +msgstr "" + +#: ../../po/../src/main.cpp:502 +msgid "Export files with the bounding box set to the page size (EPS)" +msgstr "" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:508 +msgid "" +"Query the X coordinate of the drawing or, if specified, of the object with --" +"query-id" +msgstr "" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:514 +msgid "" +"Query the Y coordinate of the drawing or, if specified, of the object with --" +"query-id" +msgstr "" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:520 +msgid "" +"Query the width of the drawing or, if specified, of the object with --query-" +"id" +msgstr "" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:526 +msgid "" +"Query the height of the drawing or, if specified, of the object with --query-" +"id" +msgstr "" + +#: ../../po/../src/main.cpp:531 +msgid "The ID of the object whose dimensions are queried" +msgstr "" + +#. TRANSLATORS: this option makes Inkscape print the name (path) of the extension directory +#: ../../po/../src/main.cpp:537 +msgid "Print out the extension directory and exit" +msgstr "" + +#: ../../po/../src/main.cpp:542 +msgid "Show given files one-by-one, switch to next on any key/mouse event" +msgstr "" + +#: ../../po/../src/main.cpp:547 +msgid "Use the new Gtkmm GUI interface" +msgstr "" + +#: ../../po/../src/main.cpp:552 +msgid "Remove unused definitions from the defs section(s) of the document" +msgstr "" + +#: ../../po/../src/main.cpp:741 +msgid "" +"[OPTIONS...] [FILE...]\n" +"\n" +"Available options:" +msgstr "" + +#: ../../po/../src/menus-skeleton.h:17 +#, fuzzy +msgid "_New" +msgstr "አዲስ" + +#: ../../po/../src/menus-skeleton.h:22 +#, fuzzy +msgid "Open _Recent" +msgstr "ክፈት" + +#: ../../po/../src/menus-skeleton.h:53 +#, fuzzy +msgid "_Edit" +msgstr "አስተካክል" + +#: ../../po/../src/menus-skeleton.h:84 +#, fuzzy +msgid "_View" +msgstr "ተመልከት" + +#: ../../po/../src/menus-skeleton.h:85 +#, fuzzy +msgid "_Zoom" +msgstr "በቅርበት አሳይ" + +#: ../../po/../src/menus-skeleton.h:102 +#, fuzzy +msgid "Show/Hide" +msgstr "ወደ ነበረበት መልስ" + +#: ../../po/../src/menus-skeleton.h:107 +#, fuzzy +msgid "_Display mode" +msgstr "የእስክሪን ምርጫዎች" + +#: ../../po/../src/menus-skeleton.h:126 +#, fuzzy +msgid "_Layer" +msgstr "ዝቅተኛ" + +#: ../../po/../src/menus-skeleton.h:143 +msgid "_Object" +msgstr "" + +#: ../../po/../src/menus-skeleton.h:165 +#, fuzzy +msgid "_Path" +msgstr "ለጥፍ" + +#: ../../po/../src/menus-skeleton.h:188 +#, fuzzy +msgid "_Text" +msgstr "ጽሑፍ" + +#: ../../po/../src/menus-skeleton.h:200 +msgid "Effects" +msgstr "" + +#: ../../po/../src/menus-skeleton.h:207 +msgid "Whiteboa_rd" +msgstr "" + +#: ../../po/../src/menus-skeleton.h:220 +#, fuzzy +msgid "_Help" +msgstr "ወደ ነበረበት መልስ" + +#: ../../po/../src/menus-skeleton.h:222 +msgid "Tutorials" +msgstr "" + +#: ../../po/../src/node-context.cpp:382 +msgid "" +"Ctrl: toggle node type, snap handle angle, move hor/vert; Ctrl" +"+Alt: move along handles" +msgstr "" + +#: ../../po/../src/node-context.cpp:383 +msgid "" +"Shift: toggle node selection, disable snapping, rotate both handles" +msgstr "" + +#: ../../po/../src/node-context.cpp:384 +msgid "Alt: lock handle length; Ctrl+Alt: move along handles" +msgstr "" + +#: ../../po/../src/nodepath.cpp:1399 ../../po/../src/nodepath.cpp:1411 +#: ../../po/../src/nodepath.cpp:1492 ../../po/../src/nodepath.cpp:1504 +msgid "To join, you must have two endnodes selected." +msgstr "" + +#: ../../po/../src/nodepath.cpp:1633 ../../po/../src/nodepath.cpp:1647 +msgid "" +"Select two non-endpoint nodes on a path between which to delete " +"segments." +msgstr "" + +#: ../../po/../src/nodepath.cpp:1743 +msgid "Cannot find path between nodes." +msgstr "" + +#: ../../po/../src/nodepath.cpp:2822 +#, c-format +msgid "" +"Node handle: angle %0.2f°, length %s; with Ctrl to snap " +"angle; with Alt to lock length; with Shift to rotate both " +"handles" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3351 +msgid "" +"Node: drag to edit the path; with Ctrl to snap to horizontal/" +"vertical; with Ctrl+Alt to snap to handles' directions" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3375 +msgid "" +"Node handle: drag to shape the curve; with Ctrl to snap angle; " +"with Alt to lock length; with Shift to rotate both handles" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3399 +msgid "" +"Node handle: drag to shape the curve; with Ctrl to snap angle; " +"with Alt to lock length; with Shift to rotate the opposite " +"handle in sync" +msgstr "" + +#. TRANSLATORS: "end" is an adjective here (NOT a verb) +#: ../../po/../src/nodepath.cpp:3591 +msgid "end node" +msgstr "" + +#. TRANSLATORS: "cusp" means "sharp" (cusp node); see also the Advanced Tutorial +#: ../../po/../src/nodepath.cpp:3596 +msgid "cusp" +msgstr "" + +#. TRANSLATORS: "smooth" is an adjective here +#: ../../po/../src/nodepath.cpp:3599 +msgid "smooth" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3601 +msgid "symmetric" +msgstr "" + +#. TRANSLATORS: "end" is an adjective here (NOT a verb) +#: ../../po/../src/nodepath.cpp:3607 +msgid "end node, handle retracted (drag with Shift to extend)" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3609 +msgid "one handle retracted (drag with Shift to extend)" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3612 +msgid "both handles retracted (drag with Shift to extend)" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3624 +msgid "Drag nodes or node handles; arrow keys to move nodes" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3625 +msgid "Drag the node or its handles; arrow keys to move the node" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3651 ../../po/../src/nodepath.cpp:3663 +msgid "Select a single object to edit its nodes or handles." +msgstr "" + +#: ../../po/../src/nodepath.cpp:3655 +#, c-format +msgid "" +"0 out of %i node selected. Click, Shift+click, " +"or drag around nodes to select." +msgid_plural "" +"0 out of %i nodes selected. Click, Shift+click, " +"or drag around nodes to select." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/nodepath.cpp:3661 +msgid "Drag the handles of the object to modify it." +msgstr "" + +#: ../../po/../src/nodepath.cpp:3669 +#, c-format +msgid "%i of %i node selected; %s. %s." +msgid_plural "%i of %i nodes selected; %s. %s." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/nodepath.cpp:3675 +#, c-format +msgid "%i of %i node selected. %s." +msgid_plural "%i of %i nodes selected. %s." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/object-edit.cpp:493 +msgid "" +"Adjust the horizontal rounding radius; with Ctrl to make the " +"vertical radius the same" +msgstr "" + +#: ../../po/../src/object-edit.cpp:499 +msgid "" +"Adjust the vertical rounding radius; with Ctrl to make the " +"horizontal radius the same" +msgstr "" + +#: ../../po/../src/object-edit.cpp:506 ../../po/../src/object-edit.cpp:513 +msgid "" +"Adjust the width and height of the rectangle; with Ctrl to " +"lock ratio or stretch in one dimension only" +msgstr "" + +#: ../../po/../src/object-edit.cpp:686 +msgid "Adjust ellipse width, with Ctrl to make circle" +msgstr "" + +#: ../../po/../src/object-edit.cpp:689 +msgid "Adjust ellipse height, with Ctrl to make circle" +msgstr "" + +#: ../../po/../src/object-edit.cpp:692 +msgid "" +"Position the start point of the arc or segment; with Ctrl to " +"snap angle; drag inside the ellipse for arc, outside for " +"segment" +msgstr "" + +#: ../../po/../src/object-edit.cpp:695 +msgid "" +"Position the end point of the arc or segment; with Ctrl to " +"snap angle; drag inside the ellipse for arc, outside for " +"segment" +msgstr "" + +#: ../../po/../src/object-edit.cpp:800 +msgid "" +"Adjust the tip radius of the star or polygon; with Shift to " +"round; with Alt to randomize" +msgstr "" + +#: ../../po/../src/object-edit.cpp:803 +msgid "" +"Adjust the base radius of the star; with Ctrl to keep star " +"rays radial (no skew); with Shift to round; with Alt to " +"randomize" +msgstr "" + +#: ../../po/../src/object-edit.cpp:967 +msgid "" +"Roll/unroll the spiral from inside; with Ctrl to snap angle; " +"with Alt to converge/diverge" +msgstr "" + +#: ../../po/../src/object-edit.cpp:969 +msgid "" +"Roll/unroll the spiral from outside; with Ctrl to snap angle; " +"with Shift to scale/rotate" +msgstr "" + +#: ../../po/../src/object-edit.cpp:1006 +msgid "Adjust the offset distance" +msgstr "" + +#. TRANSLATORS: This refers to the pattern that's inside the object +#: ../../po/../src/object-edit.cpp:1036 +msgid "Move the pattern fill inside the object" +msgstr "" + +#: ../../po/../src/object-edit.cpp:1038 +msgid "Scale the pattern fill uniformly" +msgstr "" + +#: ../../po/../src/object-edit.cpp:1040 +msgid "Rotate the pattern fill; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/object-edit.cpp:1065 +msgid "Drag to resize the flowed text frame" +msgstr "" + +#. Item dialog +#: ../../po/../src/object-ui.cpp:106 +#, fuzzy +msgid "Object _Properties" +msgstr "ዕቃ ምርጫዎች" + +#. Select item +#: ../../po/../src/object-ui.cpp:116 +#, fuzzy +msgid "_Select This" +msgstr "ምርጫ" + +#. Create link +#: ../../po/../src/object-ui.cpp:126 +#, fuzzy +msgid "_Create Link" +msgstr "አያያዝ ፍጠር" + +#. "Ungroup" +#: ../../po/../src/object-ui.cpp:199 ../../po/../src/verbs.cpp:1931 +#, fuzzy +msgid "_Ungroup" +msgstr "መድረክ" + +#. Link dialog +#: ../../po/../src/object-ui.cpp:239 +#, fuzzy +msgid "Link _Properties" +msgstr "የአያያዝ ምርጫዎች" + +#. Select item +#: ../../po/../src/object-ui.cpp:249 +msgid "_Follow Link" +msgstr "" + +#. Reset transformations +#: ../../po/../src/object-ui.cpp:254 +#, fuzzy +msgid "_Remove Link" +msgstr "አያያዝን አስወግድ" + +#. Link dialog +#: ../../po/../src/object-ui.cpp:303 +#, fuzzy +msgid "Image _Properties" +msgstr "የምስሉ ምርጫዎች" + +#. Item dialog +#: ../../po/../src/object-ui.cpp:344 +#, fuzzy +msgid "_Fill and Stroke" +msgstr "የእስክሪን ምርጫዎች" + +#: ../../po/../src/path-chemistry.cpp:58 +msgid "Select at least two objects to combine." +msgstr "" + +#: ../../po/../src/path-chemistry.cpp:65 +msgid "At least one of the objects is not a path, cannot combine." +msgstr "" + +#: ../../po/../src/path-chemistry.cpp:73 +msgid "" +"You cannot combine objects from different groups or layers." +msgstr "" + +#: ../../po/../src/path-chemistry.cpp:155 +msgid "Select path(s) to break apart." +msgstr "" + +#: ../../po/../src/path-chemistry.cpp:231 +msgid "No path(s) to break apart in the selection." +msgstr "" + +#: ../../po/../src/path-chemistry.cpp:252 +msgid "Select object(s) to convert to path." +msgstr "" + +#: ../../po/../src/path-chemistry.cpp:297 +msgid "No objects to convert to path in the selection." +msgstr "" + +#: ../../po/../src/path-chemistry.cpp:345 +msgid "Select path(s) to reverse." +msgstr "" + +#: ../../po/../src/path-chemistry.cpp:370 +msgid "No paths to reverse in the selection." +msgstr "" + +#: ../../po/../src/pen-context.cpp:379 ../../po/../src/pencil-context.cpp:233 +#, fuzzy +msgid "Continuing selected path" +msgstr "ምርጡ" + +#: ../../po/../src/pen-context.cpp:390 ../../po/../src/pencil-context.cpp:242 +#, fuzzy +msgid "Creating new path" +msgstr "ሰነድ አስቀምት" + +#: ../../po/../src/pen-context.cpp:394 ../../po/../src/pencil-context.cpp:246 +msgid "Appending to selected path" +msgstr "" + +#: ../../po/../src/pen-context.cpp:538 +msgid "Click or click and drag to close and finish the path." +msgstr "" + +#: ../../po/../src/pen-context.cpp:548 +msgid "" +"Click or click and drag to continue the path from this point." +msgstr "" + +#: ../../po/../src/pen-context.cpp:857 +#, c-format +msgid "" +"%s: angle %3.2f°, distance %s; with Ctrl to snap angle, " +"Enter to finish the path" +msgstr "" + +#: ../../po/../src/pen-context.cpp:882 +#, c-format +msgid "" +"Curve handle: angle %3.2f°, length %s; with Ctrl to snap " +"angle" +msgstr "" + +#: ../../po/../src/pen-context.cpp:912 +#, c-format +msgid "" +"%s: angle %3.2f°, length %s; with Ctrl to snap angle, " +"with Shift to move this handle only" +msgstr "" + +#: ../../po/../src/pen-context.cpp:946 +msgid "Finishing pen" +msgstr "" + +#: ../../po/../src/pencil-context.cpp:320 +msgid "Release here to close and finish the path." +msgstr "" + +#: ../../po/../src/pencil-context.cpp:326 +#, fuzzy +msgid "Drawing a freehand path" +msgstr "ሰነድ አስቀምት" + +#: ../../po/../src/pencil-context.cpp:331 +msgid "Drag to continue the path from this point." +msgstr "" + +#. Write curves to object +#: ../../po/../src/pencil-context.cpp:390 +msgid "Finishing freehand" +msgstr "" + +#: ../../po/../src/rect-context.cpp:387 +msgid "" +"Ctrl: make square or integer-ratio rect, lock a rounded corner " +"circular" +msgstr "" + +#: ../../po/../src/rect-context.cpp:549 +#, c-format +msgid "" +"Rectangle: %s × %s; with Ctrl to make square or integer-" +"ratio rectangle; with Shift to draw around the starting point" +msgstr "" + +#: ../../po/../src/select-context.cpp:243 +#, fuzzy +msgid "Move canceled." +msgstr "ምርጫ" + +#: ../../po/../src/select-context.cpp:252 +#, fuzzy +msgid "Selection canceled." +msgstr "ምርጫ" + +#: ../../po/../src/select-context.cpp:642 +msgid "Ctrl: select in groups, move hor/vert" +msgstr "" + +#: ../../po/../src/select-context.cpp:643 +msgid "Shift: toggle select, force rubberband, disable snapping" +msgstr "" + +#: ../../po/../src/select-context.cpp:644 +msgid "Alt: select under, move selected" +msgstr "" + +#: ../../po/../src/select-context.cpp:798 +msgid "Selected object is not a group. Cannot enter." +msgstr "" + +#: ../../po/../src/select-context.cpp:876 +#, c-format +msgid "" +"Move by %s, %s; with Ctrl to restrict to horizontal/vertical; " +"with Shift to disable snapping" +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:228 +msgid "Nothing was deleted." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:259 +msgid "Select object(s) to duplicate." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:420 +msgid "Select two or more objects to group." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:428 +msgid "Select at least two objects to group." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:513 +msgid "Select a group to ungroup." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:554 +msgid "No groups to ungroup in the selection." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:623 +msgid "Select objects to raise." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:629 +#: ../../po/../src/selection-chemistry.cpp:681 +#: ../../po/../src/selection-chemistry.cpp:715 +#: ../../po/../src/selection-chemistry.cpp:773 +msgid "" +"You cannot raise/lower objects from different groups or layers." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:673 +msgid "Select object(s) to raise to top." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:709 +msgid "Select object(s) to lower." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:765 +msgid "Select object(s) to lower to bottom." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:806 +msgid "Nothing to undo." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:813 +msgid "Nothing to redo." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:969 +msgid "Nothing was copied." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1051 +msgid "Current layer is hidden. Unhide it to be able to paste to it." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1055 +msgid "Current layer is locked. Unlock it to be able to paste to it." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1068 +#: ../../po/../src/selection-chemistry.cpp:1103 +msgid "Nothing on the clipboard." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1109 +msgid "Select object(s) to paste style to." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1128 +msgid "Select object(s) to move to the layer above." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1146 +#, fuzzy +msgid "No more layers above." +msgstr "የሰነድ ስም፦" + +#: ../../po/../src/selection-chemistry.cpp:1160 +msgid "Select object(s) to move to the layer below." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1178 +#, fuzzy +msgid "No more layers below." +msgstr "የሰነድ ስም፦" + +#: ../../po/../src/selection-chemistry.cpp:1811 +msgid "Select a clone to unlink." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1842 +msgid "No clones to unlink in the selection." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1859 +msgid "" +"Select a clone to go to its original. Select a linked offset " +"to go to its source. Select a text on path to go to the path. Select " +"a flowed text to go to its frame." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1882 +msgid "" +"Cannot find the object to select (orphaned clone, offset, textpath, " +"flowed text?)" +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1888 +msgid "" +"The object you're trying to select is not visible (it is in <" +"defs>)" +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1915 +msgid "Select object(s) to convert to pattern." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:2006 +msgid "Select an object with pattern fill to extract objects from." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:2059 +msgid "No pattern fills in the selection." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:2079 +msgid "Select object(s) to make a bitmap copy." +msgstr "" + +#: ../../po/../src/selection-describer.cpp:37 +msgid "Click selection to toggle scale/rotation handles" +msgstr "" + +#. no items +#: ../../po/../src/selection-describer.cpp:39 +msgid "" +"No objects selected. Click, Shift+click, or drag around objects to select." +msgstr "" + +#: ../../po/../src/selection-describer.cpp:51 +#, fuzzy, c-format +msgid " in layer %s" +msgstr "ምርጡ" + +#: ../../po/../src/selection-describer.cpp:54 +#, fuzzy, c-format +msgid " in layer %s" +msgstr "ምርጡ" + +#: ../../po/../src/selection-describer.cpp:66 +msgid "Use Shift+D to look up original" +msgstr "" + +#: ../../po/../src/selection-describer.cpp:70 +msgid "Use Shift+D to look up path" +msgstr "" + +#: ../../po/../src/selection-describer.cpp:74 +msgid "Use Shift+D to look up frame" +msgstr "" + +#: ../../po/../src/selection-describer.cpp:84 +#, c-format +msgid "%i object selected" +msgid_plural "%i objects selected" +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/selection-describer.cpp:90 +#, c-format +msgid "%s%s. %s." +msgstr "" + +#: ../../po/../src/selection-describer.cpp:94 +#, c-format +msgid "%s in %i layer. %s." +msgid_plural "%s in %i layers. %s." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/seltrans.cpp:498 +msgid "" +"Center of rotation and skewing: drag to reposition; scaling with " +"Shift also uses this center" +msgstr "" + +#: ../../po/../src/seltrans.cpp:514 +msgid "" +"Squeeze or stretch selection; with Ctrl to scale uniformly; " +"with Shift to scale around rotation center" +msgstr "" + +#: ../../po/../src/seltrans.cpp:515 +msgid "" +"Scale selection; with Ctrl to scale uniformly; with Shift to scale around rotation center" +msgstr "" + +#: ../../po/../src/seltrans.cpp:519 +msgid "" +"Skew selection; with Ctrl to snap angle; with Shift to " +"skew around the opposite side" +msgstr "" + +#: ../../po/../src/seltrans.cpp:520 +msgid "" +"Rotate selection; with Ctrl to snap angle; with Shift " +"to rotate around the opposite corner" +msgstr "" + +#: ../../po/../src/seltrans.cpp:829 ../../po/../src/seltrans.cpp:909 +#, c-format +msgid "Scale: %0.2f%% x %0.2f%%; with Ctrl to lock ratio" +msgstr "" + +#. TRANSLATORS: don't modify the first ";" (it will NOT be displayed as ";" - only the second one will be) +#: ../../po/../src/seltrans.cpp:984 +#, c-format +msgid "Skew: %0.2f°; with Ctrl to snap angle" +msgstr "" + +#. TRANSLATORS: don't modify the first ";" (it will NOT be displayed as ";" - only the second one will be) +#: ../../po/../src/seltrans.cpp:1035 +#, c-format +msgid "Rotate: %0.2f°; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/seltrans.cpp:1090 +#, fuzzy, c-format +msgid "Move center to %s, %s" +msgstr "መንቀሳቅስ" + +#: ../../po/../src/slideshow.cpp:90 +#, fuzzy +msgid "Inkscape slideshow" +msgstr "ሶዲፖዲ" + +#: ../../po/../src/sp-anchor.cpp:181 +#, c-format +msgid "Link to %s" +msgstr "" + +#: ../../po/../src/sp-anchor.cpp:185 +msgid "Link without URI" +msgstr "" + +#: ../../po/../src/sp-ellipse.cpp:438 ../../po/../src/sp-ellipse.cpp:870 +msgid "Ellipse" +msgstr "" + +#: ../../po/../src/sp-ellipse.cpp:583 +msgid "Circle" +msgstr "" + +#: ../../po/../src/sp-ellipse.cpp:865 +#, fuzzy +msgid "Segment" +msgstr "መቶኛዎች" + +#: ../../po/../src/sp-ellipse.cpp:867 +msgid "Arc" +msgstr "" + +#. TRANSLATORS: "Flow region" is an area where text is allowed to flow +#: ../../po/../src/sp-flowregion.cpp:276 +msgid "Flow region" +msgstr "" + +#. TRANSLATORS: A region "cut out of" a flow region; text is not allowed to flow inside the +#. * flow excluded region. flowRegionExclude in SVG 1.2: see +#. * http://www.w3.org/TR/2004/WD-SVG12-20041027/flow.html#flowRegion-elem and +#. * http://www.w3.org/TR/2004/WD-SVG12-20041027/flow.html#flowRegionExclude-elem. +#: ../../po/../src/sp-flowregion.cpp:493 +msgid "Flow excluded region" +msgstr "" + +#: ../../po/../src/sp-flowtext.cpp:355 +#, c-format +msgid "Flowed text (%d characters)" +msgstr "" + +#: ../../po/../src/sp-flowtext.cpp:357 +#, c-format +msgid "Linked flowed text (%d characters)" +msgstr "" + +#: ../../po/../src/sp-guide.cpp:290 +msgid "vertical guideline" +msgstr "" + +#: ../../po/../src/sp-guide.cpp:292 +msgid "horizontal guideline" +msgstr "" + +#: ../../po/../src/sp-image.cpp:835 +msgid "embedded" +msgstr "" + +#: ../../po/../src/sp-image.cpp:839 +msgid "(null_pointer)" +msgstr "" + +#: ../../po/../src/sp-image.cpp:843 +#, c-format +msgid "Image with bad reference: %s" +msgstr "" + +#: ../../po/../src/sp-image.cpp:844 +#, fuzzy, c-format +msgid "Image %d × %d: %s" +msgstr "ቀለም ምስል %d በ %d፦ %s" + +#: ../../po/../src/sp-item-group.cpp:390 +#, c-format +msgid "Group of %d object" +msgid_plural "Group of %d objects" +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/sp-item.cpp:720 +msgid "Object" +msgstr "" + +#: ../../po/../src/sp-line.cpp:202 +#, fuzzy +msgid "Line" +msgstr "መቶኛዎች" + +#. TRANSLATORS COMMENT: %s is either "outset" or "inset" depending on sign +#: ../../po/../src/sp-offset.cpp:433 +#, c-format +msgid "Linked offset, %s by %f pt" +msgstr "" + +#: ../../po/../src/sp-offset.cpp:434 ../../po/../src/sp-offset.cpp:438 +#, fuzzy +msgid "outset" +msgstr "መንቀሳቅስ" + +#: ../../po/../src/sp-offset.cpp:434 ../../po/../src/sp-offset.cpp:438 +#, fuzzy +msgid "inset" +msgstr "ነጥብ" + +#. TRANSLATORS COMMENT: %s is either "outset" or "inset" depending on sign +#: ../../po/../src/sp-offset.cpp:437 +#, c-format +msgid "Dynamic offset, %s by %f pt" +msgstr "" + +#: ../../po/../src/sp-path.cpp:127 +#, fuzzy, c-format +msgid "Path (%i node)" +msgid_plural "Path (%i nodes)" +msgstr[0] "መንቀሳቅስ" +msgstr[1] "መንቀሳቅስ" + +#: ../../po/../src/sp-polygon.cpp:216 +#, fuzzy +msgid "Polygon" +msgstr "መቶኛዎች" + +#: ../../po/../src/sp-polyline.cpp:179 +#, fuzzy +msgid "Polyline" +msgstr "መቶኛዎች" + +#: ../../po/../src/sp-rect.cpp:250 +#, fuzzy +msgid "Rectangle" +msgstr "መቶኛዎች" + +#. TRANSLATORS: since turn count isn't an integer, please adjust the +#. string as needed to deal with an localized plural forms. +#: ../../po/../src/sp-spiral.cpp:305 +#, c-format +msgid "Spiral with %3f turns" +msgstr "" + +#: ../../po/../src/sp-star.cpp:288 +#, c-format +msgid "Star with %d vertex" +msgid_plural "Star with %d vertices" +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/sp-star.cpp:292 +#, c-format +msgid "Polygon with %d vertex" +msgid_plural "Polygon with %d vertices" +msgstr[0] "" +msgstr[1] "" + +#. TRANSLATORS: For description of font with no name. +#: ../../po/../src/sp-text.cpp:420 +msgid "<no name found>" +msgstr "" + +#: ../../po/../src/sp-text.cpp:426 +#, fuzzy, c-format +msgid "Text on path (%s, %s)" +msgstr "መንቀሳቅስ" + +#: ../../po/../src/sp-text.cpp:427 +#, fuzzy, c-format +msgid "Text (%s, %s)" +msgstr "መንቀሳቅስ" + +#. TRANSLATORS: Used for statusbar description for long chains: +#. * "Clone of: Clone of: ... in Layer 1". +#: ../../po/../src/sp-use.cpp:317 +#, fuzzy +msgid "..." +msgstr "ክፈት" + +#: ../../po/../src/sp-use.cpp:325 +#, fuzzy, c-format +msgid "Clone of: %s" +msgstr "ቀለም ምስል %d በ %d፦ %s" + +#: ../../po/../src/sp-use.cpp:329 +msgid "Orphaned clone" +msgstr "" + +#: ../../po/../src/spiral-context.cpp:355 +msgid "Ctrl: snap angle" +msgstr "" + +#: ../../po/../src/spiral-context.cpp:357 +msgid "Alt: lock spiral radius" +msgstr "" + +#: ../../po/../src/spiral-context.cpp:469 +#, c-format +msgid "" +"Spiral: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/splivarot.cpp:106 +msgid "Select at least 2 paths to perform a boolean operation." +msgstr "" + +#: ../../po/../src/splivarot.cpp:112 +msgid "" +"Select exactly 2 paths to perform difference, XOR, division, or path " +"cut." +msgstr "" + +#: ../../po/../src/splivarot.cpp:129 ../../po/../src/splivarot.cpp:144 +msgid "" +"Unable to determine the z-order of the objects selected for " +"difference, XOR, division, or path cut." +msgstr "" + +#: ../../po/../src/splivarot.cpp:174 +msgid "" +"One of the objects is not a path, cannot perform boolean operation." +msgstr "" + +#. TRANSLATORS: "to outline" means "to convert stroke to path" +#: ../../po/../src/splivarot.cpp:554 +msgid "Select path(s) to outline." +msgstr "" + +#. TRANSLATORS: "to outline" means "to convert stroke to path" +#: ../../po/../src/splivarot.cpp:748 +msgid "No stroked paths to outline in the selection." +msgstr "" + +#: ../../po/../src/splivarot.cpp:832 +msgid "Selected object is not a path, cannot inset/outset." +msgstr "" + +#: ../../po/../src/splivarot.cpp:1040 +msgid "Select path(s) to inset/outset." +msgstr "" + +#: ../../po/../src/splivarot.cpp:1257 +msgid "No paths to inset/outset in the selection." +msgstr "" + +#: ../../po/../src/splivarot.cpp:1390 +msgid "Select path(s) to simplify." +msgstr "" + +#: ../../po/../src/splivarot.cpp:1417 +msgid "No paths to simplify in the selection." +msgstr "" + +#: ../../po/../src/star-context.cpp:362 +msgid "Ctrl: snap angle; keep rays radial" +msgstr "" + +#: ../../po/../src/star-context.cpp:470 +#, c-format +msgid "" +"Polygon: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/star-context.cpp:471 +#, c-format +msgid "Star: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/text-chemistry.cpp:90 +msgid "Select a text and a path to put text on path." +msgstr "" + +#: ../../po/../src/text-chemistry.cpp:95 +msgid "" +"This text object is already put to a path. Remove it from the path " +"first. Use Shift+D to look up its path." +msgstr "" + +#. rect is the only SPShape which is not yet, and thus SVG forbids us from putting text on it +#: ../../po/../src/text-chemistry.cpp:101 +msgid "" +"You cannot put text on a rectangle in this version. Convert rectangle to " +"path first." +msgstr "" + +#: ../../po/../src/text-chemistry.cpp:159 +msgid "Select a text on path to remove it from path." +msgstr "" + +#: ../../po/../src/text-chemistry.cpp:181 +msgid "No texts-on-paths in the selection." +msgstr "" + +#: ../../po/../src/text-chemistry.cpp:209 +#: ../../po/../src/text-chemistry.cpp:229 +msgid "Select text(s) to remove kerns from." +msgstr "" + +#: ../../po/../src/text-chemistry.cpp:250 +msgid "" +"Select a text and one or more paths or shapes to flow text " +"into frame." +msgstr "" + +#: ../../po/../src/text-chemistry.cpp:322 +msgid "Select a flowed text to unflow it." +msgstr "" + +#: ../../po/../src/text-context.cpp:463 +msgid "Click to edit the text, drag to select part of the text." +msgstr "" + +#: ../../po/../src/text-context.cpp:465 +msgid "" +"Click to edit the flowed text, drag to select part of the text." +msgstr "" + +#: ../../po/../src/text-context.cpp:540 +msgid "Non-printable character" +msgstr "" + +#: ../../po/../src/text-context.cpp:589 +#, fuzzy, c-format +msgid "Unicode: %s: %s" +msgstr "ሶዲፖዲ፦ %s፦ %s፦ %d" + +#: ../../po/../src/text-context.cpp:591 ../../po/../src/text-context.cpp:855 +msgid "Unicode: " +msgstr "" + +#: ../../po/../src/text-context.cpp:615 +msgid "Current layer is hidden. Unhide it to be able to add text." +msgstr "" + +#: ../../po/../src/text-context.cpp:619 +msgid "Current layer is locked. Unlock it to be able to add text." +msgstr "" + +#: ../../po/../src/text-context.cpp:673 +#, c-format +msgid "Flowed text frame: %s × %s" +msgstr "" + +#: ../../po/../src/text-context.cpp:708 ../../po/../src/text-context.cpp:1464 +msgid "Type text; Enter to start new line." +msgstr "" + +#: ../../po/../src/text-context.cpp:719 +msgid "Flowed text is created." +msgstr "" + +#: ../../po/../src/text-context.cpp:722 +msgid "" +"The frame is too small for the current font size. Flowed text not " +"created." +msgstr "" + +#: ../../po/../src/text-context.cpp:841 +msgid "No-break space" +msgstr "" + +#: ../../po/../src/text-context.cpp:1462 +msgid "Type flowed text; Enter to start new paragraph." +msgstr "" + +#: ../../po/../src/text-context.cpp:1472 ../../po/../src/tools-switch.cpp:189 +msgid "" +"Click to select or create text, drag to create flowed text; " +"then type." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:141 +msgid "" +"To edit a path, click, Shift+click, or drag around " +"nodes to select them, then drag nodes and handles. Click on an " +"object to select." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:147 +msgid "" +"Drag to create a rectangle. Drag controls to round corners and " +"resize. Click to select." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:153 +msgid "" +"Drag to create an ellipse. Drag controls to make an arc or " +"segment. Click to select." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:159 +msgid "" +"Drag to create a star. Drag controls to edit the star shape. " +"Click to select." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:165 +msgid "" +"Drag to create a spiral. Drag controls to edit the spiral " +"shape. Click to select." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:171 +msgid "" +"Drag to create a freehand line. Start drawing with Shift to " +"append to selected path." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:177 +msgid "" +"Click or click and drag to start a path; with Shift to " +"append to selected path." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:183 +msgid "" +"Drag to paint a calligraphic stroke. Left/right arrow " +"keys adjust width, up/down adjust angle." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:195 +msgid "" +"Drag or double click to create a gradient on selected objects, " +"drag handles to adjust gradients." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:201 +msgid "" +"Click or drag around an area to zoom in, Shift+click to " +"zoom out." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:213 +msgid "Click and drag between shapes to create a connector." +msgstr "" + +#: ../../po/../src/trace/potrace/inkscape-potrace.cpp:553 +#: ../../po/../src/trace/potrace/inkscape-potrace.cpp:654 +#, c-format +msgid "Trace: %d. %ld nodes" +msgstr "" + +#: ../../po/../src/trace/trace.cpp:53 ../../po/../src/trace/trace.cpp:62 +#: ../../po/../src/trace/trace.cpp:70 +msgid "Select an image to trace" +msgstr "" + +#: ../../po/../src/trace/trace.cpp:133 +#, fuzzy +msgid "Trace: No active document" +msgstr "ሰነድ አስቀምት" + +#: ../../po/../src/trace/trace.cpp:154 +msgid "Trace: Image has no bitmap data" +msgstr "" + +#: ../../po/../src/trace/trace.cpp:267 +#, c-format +msgid "Trace: Done. %ld nodes created" +msgstr "" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:59 ../../po/../src/verbs.cpp:2212 +msgid "About Inkscape" +msgstr "" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:66 +msgid "_Splash" +msgstr "" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:68 +msgid "_Authors" +msgstr "" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:69 +#, fuzzy +msgid "_Translators" +msgstr "ንድፍ፦" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:70 +#, fuzzy +msgid "_License" +msgstr "አያያዝ" + +#. TRANSLATORS: This is the filename of the `About Inkscape' picture in +#. the `screens' directory. Thus the translation of "about.svg" should be +#. the filename of its translated version, e.g. about.zh.svg for Chinese. +#. +#. N.B. about.svg changes once per release. (We should probably rename +#. the original to about-0.40.svg etc. as soon as we have a translation. +#. If we do so, then add an item to release-checklist saying that the +#. string here should be changed.) +#. FIXME? INKSCAPE_SCREENSDIR and "about.svg" are in UTF-8, not the +#. native filename encoding... and the filename passed to sp_document_new +#. should be in UTF-*8.. +#: ../../po/../src/ui/dialog/aboutbox.cpp:114 +msgid "about.svg" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:464 +msgid "Minimum horizontal gap (in px units) between bounding boxes" +msgstr "" + +#. TRANSLATORS: Horizontal gap +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:466 +#: ../../po/../src/widgets/toolbox.cpp:1556 +msgid "H:" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:474 +msgid "Minimum vertical gap (in px units) between bounding boxes" +msgstr "" + +#. TRANSLATORS: Vertical gap +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:476 +msgid "V:" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:734 +#, fuzzy +msgid "Align" +msgstr "ኩልኩል፦" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:735 +#, fuzzy +msgid "Distribute" +msgstr "ጠባየ-አንቀጽ" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:736 +msgid "Remove overlaps" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:737 +#, fuzzy +msgid "Nodes" +msgstr "ምንም" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:742 +#, fuzzy +msgid "Relative to: " +msgstr "ምርጫ" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:747 +msgid "Align right sides of objects to left side of anchor" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:750 +#, fuzzy +msgid "Align left sides" +msgstr "ኩልኩል፦" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:753 +msgid "Center on vertical axis" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:756 +#, fuzzy +msgid "Align right sides" +msgstr "ኩልኩል፦" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:759 +msgid "Align left sides of objects to right side of anchor" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:762 +msgid "Align bottoms of objects to top of anchor" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:765 +#, fuzzy +msgid "Align tops" +msgstr "ኩልኩል፦" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:768 +msgid "Center on horizontal axis" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:771 +#, fuzzy +msgid "Align bottoms" +msgstr "ኩልኩል፦" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:774 +msgid "Align tops of objects to bottom of anchor" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:779 +msgid "Align baseline anchors of texts vertically" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:782 +msgid "Align baseline anchors of texts horizontally" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:787 +msgid "Make horizontal gaps between objects equal" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:791 +msgid "Distribute left sides equidistantly" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:794 +msgid "Distribute centers equidistantly horizontally" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:797 +msgid "Distribute right sides equidistantly" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:801 +msgid "Make vertical gaps between objects equal" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:805 +msgid "Distribute tops equidistantly" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:808 +msgid "Distribute centers equidistantly vertically" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:811 +msgid "Distribute bottoms equidistantly" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:816 +msgid "Distribute baseline anchors of texts horizontally" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:819 +msgid "Distribute baseline anchors of texts vertically" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:824 +msgid "Randomize centers in both dimensions" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:827 +msgid "Unclump objects: try to equalize edge-to-edge distances" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:832 +msgid "" +"Move objects as little as possible so that their bounding boxes do not " +"overlap" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:837 +msgid "Align selected nodes horizontally" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:840 +msgid "Align selected nodes vertically" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:843 +msgid "Distribute selected nodes horizontally" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:846 +msgid "Distribute selected nodes vertically" +msgstr "" + +#. Rest of the widgetry +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:851 +msgid "Last selected" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:852 +msgid "First selected" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:853 +msgid "Biggest item" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:854 +msgid "Smallest item" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:856 +#: ../../po/../src/widgets/desktop-widget.cpp:1065 +msgid "Drawing" +msgstr "" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:91 +msgid "Metadata 1" +msgstr "" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:92 +msgid "Metadata 2" +msgstr "" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:187 +#, fuzzy +msgid "X coordinate of grid origin" +msgstr "ክፍተት X፦" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:189 +#, fuzzy +msgid "Y coordinate of grid origin" +msgstr "ክፍተት X፦" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:191 +msgid "Distance of vertical grid lines" +msgstr "" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:193 +msgid "Distance of horizontal grid lines" +msgstr "" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:197 +msgid "Max. snapping distance from grid" +msgstr "" + +#: ../../po/../src/ui/dialog/export.cpp:34 +msgid "Export" +msgstr "ላኩ" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:36 +#, fuzzy +msgid "Fill" +msgstr "ፋይል" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:37 +#, fuzzy +msgid "Stroke Paint" +msgstr "ለጥፍ" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:38 +#, fuzzy +msgid "Stroke Style" +msgstr "ለጥፍ" + +#: ../../po/../src/ui/dialog/find.cpp:34 +#, fuzzy +msgid "Find" +msgstr "ወደ ነበረበት መልስ" + +#: ../../po/../src/ui/dialog/memory.cpp:96 +msgid "Heap" +msgstr "" + +#: ../../po/../src/ui/dialog/memory.cpp:97 +#, fuzzy +msgid "In Use" +msgstr "ነጥብ" + +#. TRANSLATORS: "Slack" refers to memory which is in the heap but currently unused. +#. More typical usage is to call this memory "free" rather than "slack". +#: ../../po/../src/ui/dialog/memory.cpp:100 +#, fuzzy +msgid "Slack" +msgstr "ኮከብ" + +#: ../../po/../src/ui/dialog/memory.cpp:101 +#, fuzzy +msgid "Total" +msgstr "አርእስት፦" + +#: ../../po/../src/ui/dialog/memory.cpp:141 +#: ../../po/../src/ui/dialog/memory.cpp:147 +#: ../../po/../src/ui/dialog/memory.cpp:154 +#: ../../po/../src/ui/dialog/memory.cpp:186 +msgid "Unknown" +msgstr "ያልታወቀ" + +#: ../../po/../src/ui/dialog/memory.cpp:167 +msgid "Combined" +msgstr "" + +#: ../../po/../src/ui/dialog/memory.cpp:209 +msgid "Recalculate" +msgstr "" + +#: ../../po/../src/ui/dialog/messages.cpp:74 +#, fuzzy +msgid "Ready." +msgstr "ቀይ፦" + +#: ../../po/../src/ui/dialog/messages.cpp:75 +msgid "" +"Enable log display by setting dialogs.debug 'redirect' attribute to 1 in " +"preferences.xml" +msgstr "" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:184 +msgid "_Execute Python" +msgstr "" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:186 +msgid "_Execute Perl" +msgstr "" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:195 +msgid "Script" +msgstr "" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:205 +#, fuzzy +msgid "Output" +msgstr "ቁረጥ" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:215 +msgid "Errors" +msgstr "" + +#. Dialog organization +#: ../../po/../src/ui/dialog/session-player.cpp:73 +#, fuzzy +msgid "Session file" +msgstr "ፋይልን አስቀምጥ" + +#: ../../po/../src/ui/dialog/session-player.cpp:74 +#, fuzzy +msgid "Playback controls" +msgstr "የመስሪያውን ምርጫዎች" + +#: ../../po/../src/ui/dialog/session-player.cpp:75 +msgid "Message information" +msgstr "" + +#. Active session file display +#. fixme: Does this mean the active file for the session, or the file for the active session? +#. Please indicate which with a TRANSLATORS comment. +#: ../../po/../src/ui/dialog/session-player.cpp:85 +msgid "Active session file:" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:86 +msgid "Delay (milliseconds):" +msgstr "" + +#. Unload/load buttons +#: ../../po/../src/ui/dialog/session-player.cpp:94 +#, fuzzy +msgid "Close file" +msgstr "ዝጋ" + +#: ../../po/../src/ui/dialog/session-player.cpp:95 +msgid "Open new file" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:96 +msgid "Set delay" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:138 +#, fuzzy +msgid "Rewind" +msgstr "ቀይ፦" + +#: ../../po/../src/ui/dialog/session-player.cpp:139 +msgid "Go back one change" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:140 +#, fuzzy +msgid "Pause" +msgstr "ለጥፍ" + +#: ../../po/../src/ui/dialog/session-player.cpp:141 +msgid "Go forward one change" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:142 +msgid "Play" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:177 +#: ../../po/../src/verbs.cpp:1573 +msgid "Open session file" +msgstr "" + +#. ##Set up the Potrace panel +#. #### brightness #### +#. #### Multiple scanning#### +#. ----Hbox1 +#: ../../po/../src/ui/dialog/tracedialog.cpp:345 +#: ../../po/../src/ui/dialog/tracedialog.cpp:428 +#, fuzzy +msgid "Brightness" +msgstr "እርዝማኔ፦" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:348 +msgid "Trace by a given brightness level" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:355 +msgid "Brightness cutoff for black/white" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:362 +#, fuzzy +msgid "Image Brightness" +msgstr "የምስሉ ምርጫዎች" + +#. #### canny edge detection #### +#. TRANSLATORS: "Canny" is the name of the inventor of this edge detection method +#: ../../po/../src/ui/dialog/tracedialog.cpp:369 +msgid "Optimal Edge Detection (Canny)" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:372 +msgid "Trace with edge detection by J. Canny's algorithm" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:388 +msgid "Brightness cutoff for adjacent pixels (determines edge thickness)" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:395 +#, fuzzy +msgid "Edge Detection" +msgstr "ምርጫ" + +#. #### quantization #### +#. TRANSLATORS: Color Quantization: the process of reducing the number of colors +#. in an image by selecting an optimized set of representative colors and then +#. re-applying this reduced set to the original image. +#: ../../po/../src/ui/dialog/tracedialog.cpp:404 +msgid "Color Quantization" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:407 +msgid "Trace along the boundaries of reduced colors" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:414 +msgid "The number of reduced colors" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:416 +#, fuzzy +msgid "Colors:" +msgstr "ዝጋ" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:421 +msgid "Quantization / Reduction" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:431 +msgid "Trace the given number of brightness levels" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:438 +msgid "Scans:" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:440 +msgid "The desired number of scans" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:448 +msgid "Trace the given number of reduced colors" +msgstr "" + +#. ---Hbox3 +#: ../../po/../src/ui/dialog/tracedialog.cpp:454 +msgid "Monochrome" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:457 +msgid "Same as Color, but convert result to grayscale" +msgstr "" + +#. TRANSLATORS: "Stack" is a verb here +#: ../../po/../src/ui/dialog/tracedialog.cpp:460 +#, fuzzy +msgid "Stack" +msgstr "ኮከብ" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:463 +msgid "" +"Stack scans vertically (no gaps) or tile horizontally (usually with gaps)" +msgstr "" + +#. TRANSLATORS: "Smooth" is a verb here +#: ../../po/../src/ui/dialog/tracedialog.cpp:466 +msgid "Smooth" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:469 +msgid "Apply Gaussian blur to the bitmap before tracing" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:473 +msgid "Multiple Scanning" +msgstr "" + +#. #### Preview #### +#: ../../po/../src/ui/dialog/tracedialog.cpp:479 +#: ../../po/../src/ui/dialog/tracedialog.cpp:489 +#, fuzzy +msgid "Preview" +msgstr "አዲስ ቅድመ ዕይታ" + +#. do not expand +#: ../../po/../src/ui/dialog/tracedialog.cpp:483 +msgid "Preview the result without actual tracing" +msgstr "" + +#. #### swap black and white #### +#: ../../po/../src/ui/dialog/tracedialog.cpp:495 +msgid "Invert" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:499 +msgid "Invert black and white regions for single traces" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:503 +msgid "Thanks to Peter Selinger, http://potrace.sourceforge.net" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:506 +#, fuzzy +msgid "Credits" +msgstr "ፍጠር" + +#. done +#. TRANSLATORS: Potrace is an application for transforming bitmaps into +#. vector graphics (http://potrace.sourceforge.net/) +#: ../../po/../src/ui/dialog/tracedialog.cpp:514 +#, fuzzy +msgid "Potrace" +msgstr "ነጥብ" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:527 +#, fuzzy +msgid "Abort a trace in progress" +msgstr "የpng ፋይል ላኩ" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:531 +msgid "Execute the trace" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:80 +#: ../../po/../src/ui/dialog/transformation.cpp:90 +msgid "_Horizontal" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:80 +msgid "Horizontal displacement (relative) or position (absolute)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:82 +#: ../../po/../src/ui/dialog/transformation.cpp:92 +msgid "_Vertical" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:82 +msgid "Vertical displacement (relative) or position (absolute)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:84 +#, fuzzy +msgid "_Width" +msgstr "ስፋት፦" + +#: ../../po/../src/ui/dialog/transformation.cpp:84 +msgid "Horizontal size increment (absolute or percentage)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:86 +#, fuzzy +msgid "_Height" +msgstr "እርዝማኔ፦" + +#: ../../po/../src/ui/dialog/transformation.cpp:86 +msgid "Vertical size increment (absolute or percentage)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:88 +msgid "A_ngle" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:88 +msgid "Rotation angle (positive = counterclockwise)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:90 +msgid "" +"Horizontal skew angle (positive = counterclockwise), or absolute " +"displacement, or percentage displacement" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:92 +msgid "" +"Vertical skew angle (positive = counterclockwise), or absolute displacement, " +"or percentage displacement" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:95 +#, fuzzy +msgid "Transformation matrix element A" +msgstr "ንድፍ፦" + +#: ../../po/../src/ui/dialog/transformation.cpp:96 +#, fuzzy +msgid "Transformation matrix element B" +msgstr "ንድፍ፦" + +#: ../../po/../src/ui/dialog/transformation.cpp:97 +#, fuzzy +msgid "Transformation matrix element C" +msgstr "ንድፍ፦" + +#: ../../po/../src/ui/dialog/transformation.cpp:98 +#, fuzzy +msgid "Transformation matrix element D" +msgstr "ንድፍ፦" + +#: ../../po/../src/ui/dialog/transformation.cpp:99 +#, fuzzy +msgid "Transformation matrix element E" +msgstr "ንድፍ፦" + +#: ../../po/../src/ui/dialog/transformation.cpp:100 +#, fuzzy +msgid "Transformation matrix element F" +msgstr "ንድፍ፦" + +#: ../../po/../src/ui/dialog/transformation.cpp:102 +#, fuzzy +msgid "Rela_tive move" +msgstr "ምርጫ" + +#: ../../po/../src/ui/dialog/transformation.cpp:102 +msgid "" +"Add the specified relative displacement to the current position; otherwise, " +"edit the current absolute position directly" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:103 +msgid "Scale proportionally" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:103 +msgid "Preserve the width/height ratio of the scaled objects" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:104 +msgid "Apply to each _object separately" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:104 +msgid "" +"Apply the scale/rotate/skew to each selected object separately; otherwise, " +"transform the selection as a whole" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:105 +msgid "Edit c_urrent matrix" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:105 +msgid "" +"Edit the current transform= matrix; otherwise, post-multiply transform= by " +"this matrix" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:115 +#, fuzzy +msgid "_Move" +msgstr "መንቀሳቅስ" + +#: ../../po/../src/ui/dialog/transformation.cpp:118 +#, fuzzy +msgid "_Scale" +msgstr "መለኪያ" + +#: ../../po/../src/ui/dialog/transformation.cpp:121 +#, fuzzy +msgid "_Rotate" +msgstr "ያሽከርክሩ" + +#: ../../po/../src/ui/dialog/transformation.cpp:124 +#, fuzzy +msgid "Ske_w" +msgstr "ኮከብ" + +#: ../../po/../src/ui/dialog/transformation.cpp:127 +msgid "Matri_x" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:141 +msgid "Reset the values on the current tab to defaults" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:148 +msgid "Apply transformation to selection" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:43 +msgid "_Use SSL" +msgstr "" + +#. Construct dialog interface +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:68 +#, fuzzy +msgid "_Server:" +msgstr "ፋይል" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:69 +#, fuzzy +msgid "_Username:" +msgstr "ፋይል" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:70 +msgid "_Password:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:71 +msgid "P_ort:" +msgstr "" + +#. Buttons +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:99 +#, fuzzy +msgid "Connect" +msgstr "ዝጋ" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:126 +msgid "Establishing connection to Jabber server %1 as user %2" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:131 +msgid "Failed to establish connection to Jabber server %1" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:136 +msgid "Authentication failed on Jabber server %1 as %2" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:141 +msgid "SSL initialization failed when connecting to Jabber server %1" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:147 +msgid "Connected to Jabber server %1 as %2" +msgstr "" + +#. Construct labels +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:75 +msgid "Chatroom _name:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:76 +msgid "Chatroom _server:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:77 +msgid "Chatroom _password:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:78 +msgid "Chatroom _handle:" +msgstr "" + +#. Button setup and callback registration +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:97 +msgid "Connect to chatroom" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:132 +msgid "Synchronizing with chatroom %1@%2 using the handle %3" +msgstr "" + +#. Construct dialog interface +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:78 +msgid "_User's Jabber ID:" +msgstr "" + +#. Buttons +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:82 +msgid "_Invite user" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:83 +#, fuzzy +msgid "_Cancel" +msgstr "ተወው" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:94 +msgid "Buddy List" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:170 +msgid "Sending whiteboard invitation to %1" +msgstr "" + +#. FIXME: strings are replaced by placeholders, NOT to be translated until the code is enabled +#. See http://sourceforge.net/mailarchive/message.php?msg_id=11746016 for details +#. File menu +#. Edit menu +#. View menu +#. Layer menu +#. Object menu +#. Path menu +#. add(Gtk::StockItem(CLEANUP, _("PLACEHOLDER, do not translate"))); (using Gtk::Stock::CLEAR) +#. Text menu +#. About menu +#. Tools toolbox +#. Select Tool controls +#. Node Tool controls +#. Calligraphy Tool controls +#. Session playback controls +#: ../../po/../src/ui/stock-items.cpp:34 ../../po/../src/ui/stock-items.cpp:35 +#: ../../po/../src/ui/stock-items.cpp:36 ../../po/../src/ui/stock-items.cpp:37 +#: ../../po/../src/ui/stock-items.cpp:38 ../../po/../src/ui/stock-items.cpp:39 +#: ../../po/../src/ui/stock-items.cpp:40 ../../po/../src/ui/stock-items.cpp:41 +#: ../../po/../src/ui/stock-items.cpp:42 ../../po/../src/ui/stock-items.cpp:43 +#: ../../po/../src/ui/stock-items.cpp:46 ../../po/../src/ui/stock-items.cpp:47 +#: ../../po/../src/ui/stock-items.cpp:48 ../../po/../src/ui/stock-items.cpp:49 +#: ../../po/../src/ui/stock-items.cpp:50 ../../po/../src/ui/stock-items.cpp:51 +#: ../../po/../src/ui/stock-items.cpp:52 ../../po/../src/ui/stock-items.cpp:53 +#: ../../po/../src/ui/stock-items.cpp:54 ../../po/../src/ui/stock-items.cpp:55 +#: ../../po/../src/ui/stock-items.cpp:56 ../../po/../src/ui/stock-items.cpp:57 +#: ../../po/../src/ui/stock-items.cpp:58 ../../po/../src/ui/stock-items.cpp:59 +#: ../../po/../src/ui/stock-items.cpp:62 ../../po/../src/ui/stock-items.cpp:63 +#: ../../po/../src/ui/stock-items.cpp:64 ../../po/../src/ui/stock-items.cpp:65 +#: ../../po/../src/ui/stock-items.cpp:66 ../../po/../src/ui/stock-items.cpp:67 +#: ../../po/../src/ui/stock-items.cpp:68 ../../po/../src/ui/stock-items.cpp:69 +#: ../../po/../src/ui/stock-items.cpp:70 ../../po/../src/ui/stock-items.cpp:71 +#: ../../po/../src/ui/stock-items.cpp:72 ../../po/../src/ui/stock-items.cpp:73 +#: ../../po/../src/ui/stock-items.cpp:74 ../../po/../src/ui/stock-items.cpp:75 +#: ../../po/../src/ui/stock-items.cpp:76 ../../po/../src/ui/stock-items.cpp:77 +#: ../../po/../src/ui/stock-items.cpp:78 ../../po/../src/ui/stock-items.cpp:79 +#: ../../po/../src/ui/stock-items.cpp:80 ../../po/../src/ui/stock-items.cpp:81 +#: ../../po/../src/ui/stock-items.cpp:82 ../../po/../src/ui/stock-items.cpp:83 +#: ../../po/../src/ui/stock-items.cpp:84 ../../po/../src/ui/stock-items.cpp:85 +#: ../../po/../src/ui/stock-items.cpp:86 ../../po/../src/ui/stock-items.cpp:87 +#: ../../po/../src/ui/stock-items.cpp:88 ../../po/../src/ui/stock-items.cpp:89 +#: ../../po/../src/ui/stock-items.cpp:92 ../../po/../src/ui/stock-items.cpp:93 +#: ../../po/../src/ui/stock-items.cpp:94 ../../po/../src/ui/stock-items.cpp:95 +#: ../../po/../src/ui/stock-items.cpp:96 ../../po/../src/ui/stock-items.cpp:97 +#: ../../po/../src/ui/stock-items.cpp:98 ../../po/../src/ui/stock-items.cpp:99 +#: ../../po/../src/ui/stock-items.cpp:100 +#: ../../po/../src/ui/stock-items.cpp:101 +#: ../../po/../src/ui/stock-items.cpp:102 +#: ../../po/../src/ui/stock-items.cpp:103 +#: ../../po/../src/ui/stock-items.cpp:104 +#: ../../po/../src/ui/stock-items.cpp:105 +#: ../../po/../src/ui/stock-items.cpp:108 +#: ../../po/../src/ui/stock-items.cpp:109 +#: ../../po/../src/ui/stock-items.cpp:110 +#: ../../po/../src/ui/stock-items.cpp:111 +#: ../../po/../src/ui/stock-items.cpp:112 +#: ../../po/../src/ui/stock-items.cpp:113 +#: ../../po/../src/ui/stock-items.cpp:114 +#: ../../po/../src/ui/stock-items.cpp:115 +#: ../../po/../src/ui/stock-items.cpp:116 +#: ../../po/../src/ui/stock-items.cpp:117 +#: ../../po/../src/ui/stock-items.cpp:118 +#: ../../po/../src/ui/stock-items.cpp:119 +#: ../../po/../src/ui/stock-items.cpp:120 +#: ../../po/../src/ui/stock-items.cpp:121 +#: ../../po/../src/ui/stock-items.cpp:122 +#: ../../po/../src/ui/stock-items.cpp:123 +#: ../../po/../src/ui/stock-items.cpp:124 +#: ../../po/../src/ui/stock-items.cpp:125 +#: ../../po/../src/ui/stock-items.cpp:126 +#: ../../po/../src/ui/stock-items.cpp:127 +#: ../../po/../src/ui/stock-items.cpp:130 +#: ../../po/../src/ui/stock-items.cpp:131 +#: ../../po/../src/ui/stock-items.cpp:132 +#: ../../po/../src/ui/stock-items.cpp:133 +#: ../../po/../src/ui/stock-items.cpp:134 +#: ../../po/../src/ui/stock-items.cpp:135 +#: ../../po/../src/ui/stock-items.cpp:136 +#: ../../po/../src/ui/stock-items.cpp:137 +#: ../../po/../src/ui/stock-items.cpp:138 +#: ../../po/../src/ui/stock-items.cpp:139 +#: ../../po/../src/ui/stock-items.cpp:140 +#: ../../po/../src/ui/stock-items.cpp:141 +#: ../../po/../src/ui/stock-items.cpp:142 +#: ../../po/../src/ui/stock-items.cpp:143 +#: ../../po/../src/ui/stock-items.cpp:144 +#: ../../po/../src/ui/stock-items.cpp:145 +#: ../../po/../src/ui/stock-items.cpp:146 +#: ../../po/../src/ui/stock-items.cpp:150 +#: ../../po/../src/ui/stock-items.cpp:151 +#: ../../po/../src/ui/stock-items.cpp:152 +#: ../../po/../src/ui/stock-items.cpp:153 +#: ../../po/../src/ui/stock-items.cpp:156 +#: ../../po/../src/ui/stock-items.cpp:157 +#: ../../po/../src/ui/stock-items.cpp:158 +#: ../../po/../src/ui/stock-items.cpp:161 +#: ../../po/../src/ui/stock-items.cpp:162 +#: ../../po/../src/ui/stock-items.cpp:163 +#: ../../po/../src/ui/stock-items.cpp:164 +#: ../../po/../src/ui/stock-items.cpp:165 +#: ../../po/../src/ui/stock-items.cpp:166 +#: ../../po/../src/ui/stock-items.cpp:167 +#: ../../po/../src/ui/stock-items.cpp:168 +#: ../../po/../src/ui/stock-items.cpp:169 +#: ../../po/../src/ui/stock-items.cpp:170 +#: ../../po/../src/ui/stock-items.cpp:171 +#: ../../po/../src/ui/stock-items.cpp:172 +#: ../../po/../src/ui/stock-items.cpp:175 +#: ../../po/../src/ui/stock-items.cpp:176 +#: ../../po/../src/ui/stock-items.cpp:177 +#: ../../po/../src/ui/stock-items.cpp:178 +#: ../../po/../src/ui/stock-items.cpp:181 +#: ../../po/../src/ui/stock-items.cpp:182 +#: ../../po/../src/ui/stock-items.cpp:183 +#: ../../po/../src/ui/stock-items.cpp:184 +#: ../../po/../src/ui/stock-items.cpp:185 +#: ../../po/../src/ui/stock-items.cpp:186 +#: ../../po/../src/ui/stock-items.cpp:187 +#: ../../po/../src/ui/stock-items.cpp:188 +#: ../../po/../src/ui/stock-items.cpp:189 +#: ../../po/../src/ui/stock-items.cpp:190 +#: ../../po/../src/ui/stock-items.cpp:191 +#: ../../po/../src/ui/stock-items.cpp:194 +#: ../../po/../src/ui/stock-items.cpp:195 +#: ../../po/../src/ui/stock-items.cpp:198 +#: ../../po/../src/ui/stock-items.cpp:199 +#: ../../po/../src/ui/stock-items.cpp:200 +#: ../../po/../src/ui/stock-items.cpp:201 +#: ../../po/../src/ui/stock-items.cpp:202 +msgid "PLACEHOLDER, do not translate" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:88 +msgid "small" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:89 +msgid "medium" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:90 +#, fuzzy +msgid "large" +msgstr "ኢላማ፦" + +#: ../../po/../src/ui/widget/panel.cpp:91 +msgid "huge" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:106 +#, fuzzy +msgid "List" +msgstr "ነጥብ" + +#: ../../po/../src/ui/widget/selected-style.cpp:67 +msgid "F:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:68 +msgid "S:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:69 +msgid "O:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:95 +msgid "N/A" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:98 +#: ../../po/../src/ui/widget/selected-style.cpp:712 +#, fuzzy +msgid "Nothing selected" +msgstr "ምርጡ" + +#: ../../po/../src/ui/widget/selected-style.cpp:103 +msgid "No fill" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:103 +#, fuzzy +msgid "No stroke" +msgstr "ኮከብ" + +#: ../../po/../src/ui/widget/selected-style.cpp:105 +#: ../../po/../src/widgets/paint-selector.cpp:190 +#, fuzzy +msgid "Pattern" +msgstr "ንድፍ፦" + +#: ../../po/../src/ui/widget/selected-style.cpp:108 +#: ../../po/../src/widgets/paint-selector.cpp:885 +#, fuzzy +msgid "Pattern fill" +msgstr "ንድፍ፦" + +#: ../../po/../src/ui/widget/selected-style.cpp:108 +#, fuzzy +msgid "Pattern stroke" +msgstr "ንድፍ፦" + +#: ../../po/../src/ui/widget/selected-style.cpp:110 +#, fuzzy +msgid "L Gradient" +msgstr "ኢላማ፦" + +#: ../../po/../src/ui/widget/selected-style.cpp:113 +#, fuzzy +msgid "Linear gradient fill" +msgstr "ሰነድ አስቀምት" + +#: ../../po/../src/ui/widget/selected-style.cpp:113 +#, fuzzy +msgid "Linear gradient stroke" +msgstr "ሰነድ አስቀምት" + +#: ../../po/../src/ui/widget/selected-style.cpp:115 +#, fuzzy +msgid "R Gradient" +msgstr "ኢላማ፦" + +#: ../../po/../src/ui/widget/selected-style.cpp:118 +msgid "Radial gradient fill" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:118 +msgid "Radial gradient stroke" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:120 +#, fuzzy +msgid "Different" +msgstr "መቶኛ" + +#: ../../po/../src/ui/widget/selected-style.cpp:123 +msgid "Different fills" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:123 +msgid "Different strokes" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:125 +#, fuzzy +msgid "Unset" +msgstr "ነጥብ" + +#. TRANSLATORS COMMENT: unset is a verb here +#: ../../po/../src/ui/widget/selected-style.cpp:128 +#: ../../po/../src/ui/widget/selected-style.cpp:182 +#, fuzzy +msgid "Unset fill" +msgstr "ያልተሰየመ" + +#: ../../po/../src/ui/widget/selected-style.cpp:128 +#: ../../po/../src/ui/widget/selected-style.cpp:182 +msgid "Unset stroke" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:131 +#, fuzzy +msgid "Flat color fill" +msgstr "የመጨረሺያ ቀለም" + +#: ../../po/../src/ui/widget/selected-style.cpp:131 +#, fuzzy +msgid "Flat color stroke" +msgstr "የመጨረሺያ ቀለም" + +#. TRANSLATOR COMMENT: A means "Averaged" +#: ../../po/../src/ui/widget/selected-style.cpp:134 +msgid "A" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:137 +#, fuzzy +msgid "Fill is averaged over selected objects" +msgstr "ምርጡ" + +#: ../../po/../src/ui/widget/selected-style.cpp:137 +#, fuzzy +msgid "Stroke is averaged over selected objects" +msgstr "ምርጡ" + +#. TRANSLATOR COMMENT: M means "Multiple" +#: ../../po/../src/ui/widget/selected-style.cpp:140 +msgid "M" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:143 +#, fuzzy +msgid "Multiple selected objects have the same fill" +msgstr "ምርጡ" + +#: ../../po/../src/ui/widget/selected-style.cpp:143 +#, fuzzy +msgid "Multiple selected objects have the same stroke" +msgstr "ምርጡ" + +#: ../../po/../src/ui/widget/selected-style.cpp:145 +#, fuzzy +msgid "Edit fill..." +msgstr "አስተካክል" + +#: ../../po/../src/ui/widget/selected-style.cpp:145 +#, fuzzy +msgid "Edit stroke..." +msgstr "አስተካክል" + +#: ../../po/../src/ui/widget/selected-style.cpp:149 +#, fuzzy +msgid "Last set color" +msgstr "የመጨረሺያ ቀለም" + +#: ../../po/../src/ui/widget/selected-style.cpp:153 +#, fuzzy +msgid "Last selected color" +msgstr "ምርጡ" + +#: ../../po/../src/ui/widget/selected-style.cpp:157 +msgid "White" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:161 +#: ../../po/../src/widgets/sp-color-scales.cpp:461 +#: ../../po/../src/widgets/sp-color-scales.cpp:462 +#, fuzzy +msgid "Black" +msgstr "ጥቁር፦" + +#: ../../po/../src/ui/widget/selected-style.cpp:165 +#, fuzzy +msgid "Copy color" +msgstr "የመጀመሪያ ቀለም" + +#: ../../po/../src/ui/widget/selected-style.cpp:169 +#, fuzzy +msgid "Paste color" +msgstr "የመጨረሺያ ቀለም" + +#: ../../po/../src/ui/widget/selected-style.cpp:173 +#, fuzzy +msgid "Swap fill and stroke" +msgstr "የእስክሪን ምርጫዎች" + +#: ../../po/../src/ui/widget/selected-style.cpp:177 +msgid "Make fill opaque" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:177 +msgid "Make stroke opaque" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:186 +#, fuzzy +msgid "Remove fill" +msgstr "አያያዝን አስወግድ" + +#: ../../po/../src/ui/widget/selected-style.cpp:186 +#, fuzzy +msgid "Remove stroke" +msgstr "አያያዝን አስወግድ" + +#: ../../po/../src/ui/widget/selected-style.cpp:718 +msgid "Master opacity" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:744 +msgid "0 (transparent)" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:768 +msgid "1.0 (opaque)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1046 +msgid "Moved to next layer." +msgstr "" + +#: ../../po/../src/verbs.cpp:1048 +msgid "Cannot move past last layer." +msgstr "" + +#: ../../po/../src/verbs.cpp:1057 +msgid "Moved to previous layer." +msgstr "" + +#: ../../po/../src/verbs.cpp:1059 +msgid "Cannot move past first layer." +msgstr "" + +#: ../../po/../src/verbs.cpp:1076 ../../po/../src/verbs.cpp:1150 +#, fuzzy +msgid "No current layer." +msgstr "የሰነድ ስም፦" + +#: ../../po/../src/verbs.cpp:1105 +#, c-format +msgid "Raised layer %s." +msgstr "" + +#: ../../po/../src/verbs.cpp:1109 +#, fuzzy, c-format +msgid "Lowered layer %s." +msgstr "ምርጡ" + +#: ../../po/../src/verbs.cpp:1118 +msgid "Cannot move layer any further." +msgstr "" + +#. TRANSLATORS: this means "The layer has been deleted." +#: ../../po/../src/verbs.cpp:1148 +#, fuzzy +msgid "Deleted layer." +msgstr "ምርጡ" + +#: ../../po/../src/verbs.cpp:1544 +msgid "" +"You need to connect to a Jabber server before sharing a document with " +"another user." +msgstr "" + +#: ../../po/../src/verbs.cpp:1559 +msgid "" +"You need to connect to a Jabber server before sharing a document with a " +"chatroom." +msgstr "" + +#: ../../po/../src/verbs.cpp:1569 +msgid "XML node tracker has not been initialized; nothing to dump" +msgstr "" + +#. TRANSLATORS: If you have translated the keys.svg file to your language, then +#. translate this string as "keys.LANG.svg" (where LANG is your language code); +#. otherwise leave as "keys.svg". +#: ../../po/../src/verbs.cpp:1631 +msgid "keys.svg" +msgstr "" + +#. TRANSLATORS: If you have translated the tutorial-basic.svg file to your language, +#. then translate this string as "tutorial-basic.LANG.svg" (where LANG is your language +#. code); otherwise leave as "tutorial-basic.svg". +#: ../../po/../src/verbs.cpp:1667 +msgid "tutorial-basic.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1671 +msgid "tutorial-shapes.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1675 +msgid "tutorial-advanced.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1679 +msgid "tutorial-tracing.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1683 +msgid "tutorial-calligraphy.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1687 +msgid "tutorial-elements.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1691 +msgid "tutorial-tips.svg" +msgstr "" + +#: ../../po/../src/verbs.cpp:1842 +msgid "Does nothing" +msgstr "" + +#. File +#: ../../po/../src/verbs.cpp:1845 +#, fuzzy +msgid "Default" +msgstr "ነባሮች" + +#: ../../po/../src/verbs.cpp:1845 +#, fuzzy +msgid "Create new document from default template" +msgstr "ሰነድ አስቀምት" + +#: ../../po/../src/verbs.cpp:1847 +#, fuzzy +msgid "_Open..." +msgstr "ክፈት" + +#: ../../po/../src/verbs.cpp:1848 +#, fuzzy +msgid "Open existing document" +msgstr "ያልተሰየመ ሰነድ" + +#: ../../po/../src/verbs.cpp:1849 +msgid "Re_vert" +msgstr "" + +#: ../../po/../src/verbs.cpp:1850 +msgid "Revert to the last saved version of document (changes will be lost)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1851 +#, fuzzy +msgid "_Save" +msgstr "አስቀምጥ" + +#: ../../po/../src/verbs.cpp:1851 +msgid "Save document" +msgstr "ሰነድ አስቀምት" + +#: ../../po/../src/verbs.cpp:1853 +#, fuzzy +msgid "Save _As..." +msgstr "በሌላ ስም አስቀምጥ" + +#: ../../po/../src/verbs.cpp:1854 +msgid "Save document under new name" +msgstr "" + +#: ../../po/../src/verbs.cpp:1855 +#, fuzzy +msgid "_Print..." +msgstr "አትም" + +#: ../../po/../src/verbs.cpp:1855 +msgid "Print document" +msgstr "ሰነዱ ይታተም" + +#. TRANSLATORS: "Vacuum Defs" means "Clean up defs" (so as to remove unused definitions) +#: ../../po/../src/verbs.cpp:1858 +msgid "Vac_uum Defs" +msgstr "" + +#: ../../po/../src/verbs.cpp:1858 +msgid "Remove unused predefined items from the <defs> of the document" +msgstr "" + +#: ../../po/../src/verbs.cpp:1860 +#, fuzzy +msgid "Print _Direct" +msgstr "የአያያዝ ምርጫዎች" + +#: ../../po/../src/verbs.cpp:1861 +msgid "Print directly without prompting to a file or pipe" +msgstr "" + +#: ../../po/../src/verbs.cpp:1862 +#, fuzzy +msgid "Print Previe_w" +msgstr "የቅድመ ህትመት ዕይታ" + +#: ../../po/../src/verbs.cpp:1863 +msgid "Preview document printout" +msgstr "" + +#: ../../po/../src/verbs.cpp:1864 +#, fuzzy +msgid "_Import..." +msgstr "ከውጭ አስገባ" + +#: ../../po/../src/verbs.cpp:1865 +msgid "Import bitmap or SVG image into document" +msgstr "" + +#: ../../po/../src/verbs.cpp:1866 +#, fuzzy +msgid "_Export Bitmap..." +msgstr "ላኩ" + +#: ../../po/../src/verbs.cpp:1867 +msgid "Export document or selection as a bitmap image" +msgstr "" + +#: ../../po/../src/verbs.cpp:1868 +#, fuzzy +msgid "N_ext Window" +msgstr "አዲስ ዕይታ" + +#: ../../po/../src/verbs.cpp:1869 +msgid "Switch to the next document window" +msgstr "" + +#: ../../po/../src/verbs.cpp:1870 +#, fuzzy +msgid "P_revious Window" +msgstr "አዲስ ዕይታ" + +#: ../../po/../src/verbs.cpp:1871 +msgid "Switch to the previous document window" +msgstr "" + +#: ../../po/../src/verbs.cpp:1872 +#, fuzzy +msgid "_Close" +msgstr "ዝጋ" + +#: ../../po/../src/verbs.cpp:1873 +#, fuzzy +msgid "Close window" +msgstr "ዕይታ ዝጋ" + +#: ../../po/../src/verbs.cpp:1874 +msgid "_Quit" +msgstr "" + +#: ../../po/../src/verbs.cpp:1874 +#, fuzzy +msgid "Quit Inkscape" +msgstr "ሶዲፖዲ" + +#. Edit +#: ../../po/../src/verbs.cpp:1877 +#, fuzzy +msgid "_Undo" +msgstr "ወደ ነበረበት መልስ" + +#: ../../po/../src/verbs.cpp:1877 +msgid "Undo last action" +msgstr "" + +#: ../../po/../src/verbs.cpp:1879 +#, fuzzy +msgid "_Redo" +msgstr "እንደገና አድርግ" + +#: ../../po/../src/verbs.cpp:1880 +msgid "Do again last undone action" +msgstr "" + +#: ../../po/../src/verbs.cpp:1881 +#, fuzzy +msgid "Cu_t" +msgstr "ቁረጥ" + +#: ../../po/../src/verbs.cpp:1882 +msgid "Cut selection to clipboard" +msgstr "" + +#: ../../po/../src/verbs.cpp:1883 +#, fuzzy +msgid "_Copy" +msgstr "ቅጂ" + +#: ../../po/../src/verbs.cpp:1884 +msgid "Copy selection to clipboard" +msgstr "" + +#: ../../po/../src/verbs.cpp:1885 +#, fuzzy +msgid "_Paste" +msgstr "ለጥፍ" + +#: ../../po/../src/verbs.cpp:1886 +msgid "Paste objects from clipboard to mouse point" +msgstr "" + +#: ../../po/../src/verbs.cpp:1887 +#, fuzzy +msgid "Paste _Style" +msgstr "ለጥፍ" + +#: ../../po/../src/verbs.cpp:1888 +msgid "Apply style of the copied object to selection" +msgstr "" + +#: ../../po/../src/verbs.cpp:1889 +#, fuzzy +msgid "Paste _In Place" +msgstr "ለጥፍ" + +#: ../../po/../src/verbs.cpp:1890 +msgid "Paste objects from clipboard to the original location" +msgstr "" + +#: ../../po/../src/verbs.cpp:1891 +#, fuzzy +msgid "_Delete" +msgstr "አጥፉ" + +#: ../../po/../src/verbs.cpp:1892 +#, fuzzy +msgid "Delete selection" +msgstr "አጥፉ" + +#: ../../po/../src/verbs.cpp:1893 +#, fuzzy +msgid "Duplic_ate" +msgstr "አባዛ" + +#: ../../po/../src/verbs.cpp:1894 +#, fuzzy +msgid "Duplicate selected objects" +msgstr "ምርጡ" + +#: ../../po/../src/verbs.cpp:1895 +#, fuzzy +msgid "Clo_ne" +msgstr "ዝጋ" + +#: ../../po/../src/verbs.cpp:1896 +msgid "Create a clone of selected object (a copy linked to the original)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1897 +msgid "Unlin_k Clone" +msgstr "" + +#: ../../po/../src/verbs.cpp:1898 +msgid "Cut the clone's link to its original" +msgstr "" + +#: ../../po/../src/verbs.cpp:1899 +#, fuzzy +msgid "Select _Original" +msgstr "ምርጡ" + +#: ../../po/../src/verbs.cpp:1900 +msgid "Select the object to which the clone is linked" +msgstr "" + +#. TRANSLATORS: Convert selection to a rectangle with tiled pattern fill +#: ../../po/../src/verbs.cpp:1902 +msgid "O_bjects to Pattern" +msgstr "" + +#: ../../po/../src/verbs.cpp:1903 +msgid "Convert selection to a rectangle with tiled pattern fill" +msgstr "" + +#. TRANSLATORS: Extract objects from a tiled pattern fill +#: ../../po/../src/verbs.cpp:1905 +#, fuzzy +msgid "Pattern to Ob_jects" +msgstr "ንድፍ፦" + +#: ../../po/../src/verbs.cpp:1906 +msgid "Extract objects from a tiled pattern fill" +msgstr "" + +#: ../../po/../src/verbs.cpp:1907 +#, fuzzy +msgid "Clea_r All" +msgstr "ሁሉንም ሰርዝ" + +#: ../../po/../src/verbs.cpp:1908 +msgid "Delete all objects from document" +msgstr "" + +#: ../../po/../src/verbs.cpp:1909 +#, fuzzy +msgid "Select Al_l" +msgstr "ምርጡ" + +#: ../../po/../src/verbs.cpp:1910 +msgid "Select all objects or all nodes" +msgstr "" + +#: ../../po/../src/verbs.cpp:1911 +#, fuzzy +msgid "Select All in All La_yers" +msgstr "ምርጡ" + +#: ../../po/../src/verbs.cpp:1912 +msgid "Select all objects in all visible and unlocked layers" +msgstr "" + +#: ../../po/../src/verbs.cpp:1913 +#, fuzzy +msgid "In_vert Selection" +msgstr "ምርጫ" + +#: ../../po/../src/verbs.cpp:1914 +msgid "Invert selection (unselect what is selected and select everything else)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1915 +msgid "Invert in All Layers" +msgstr "" + +#: ../../po/../src/verbs.cpp:1916 +msgid "Invert selection in all visible and unlocked layers" +msgstr "" + +#: ../../po/../src/verbs.cpp:1917 +#, fuzzy +msgid "D_eselect" +msgstr "ምርጡ" + +#: ../../po/../src/verbs.cpp:1918 +msgid "Deselect any selected objects or nodes" +msgstr "" + +#. Selection +#: ../../po/../src/verbs.cpp:1921 +msgid "Raise to _Top" +msgstr "" + +#: ../../po/../src/verbs.cpp:1922 +msgid "Raise selection to top" +msgstr "" + +#: ../../po/../src/verbs.cpp:1923 +msgid "Lower to _Bottom" +msgstr "" + +#: ../../po/../src/verbs.cpp:1924 +msgid "Lower selection to bottom" +msgstr "" + +#: ../../po/../src/verbs.cpp:1925 +#, fuzzy +msgid "_Raise" +msgstr "አሳድግ" + +#: ../../po/../src/verbs.cpp:1926 +msgid "Raise selection one step" +msgstr "" + +#: ../../po/../src/verbs.cpp:1927 +#, fuzzy +msgid "_Lower" +msgstr "ዝቅተኛ" + +#: ../../po/../src/verbs.cpp:1928 +msgid "Lower selection one step" +msgstr "" + +#: ../../po/../src/verbs.cpp:1929 +#, fuzzy +msgid "_Group" +msgstr "መድረክ" + +#: ../../po/../src/verbs.cpp:1930 +msgid "Group selected objects" +msgstr "" + +#: ../../po/../src/verbs.cpp:1932 +msgid "Ungroup selected groups" +msgstr "" + +#: ../../po/../src/verbs.cpp:1934 +#, fuzzy +msgid "_Put on Path" +msgstr "ቁረጥ" + +#: ../../po/../src/verbs.cpp:1935 +msgid "Put text on path" +msgstr "" + +#: ../../po/../src/verbs.cpp:1936 +msgid "_Remove from Path" +msgstr "" + +#: ../../po/../src/verbs.cpp:1937 +msgid "Remove text from path" +msgstr "" + +#: ../../po/../src/verbs.cpp:1938 +msgid "Remove Manual _Kerns" +msgstr "" + +#. TRANSLATORS: "glyph": An image used in the visual representation of characters; +#. roughly speaking, how a character looks. A font is a set of glyphs. +#: ../../po/../src/verbs.cpp:1941 +msgid "Remove all manual kerns and glyph rotations from a text object" +msgstr "" + +#: ../../po/../src/verbs.cpp:1943 +#, fuzzy +msgid "_Union" +msgstr "ወደ ነበረበት መልስ" + +#: ../../po/../src/verbs.cpp:1944 +msgid "Union of selected objects" +msgstr "" + +#: ../../po/../src/verbs.cpp:1945 +#, fuzzy +msgid "_Intersection" +msgstr "ምርጫ" + +#: ../../po/../src/verbs.cpp:1946 +msgid "Intersection of selected objects" +msgstr "" + +#: ../../po/../src/verbs.cpp:1947 +msgid "_Difference" +msgstr "" + +#: ../../po/../src/verbs.cpp:1948 +msgid "Difference of selected objects (bottom minus top)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1949 +msgid "E_xclusion" +msgstr "" + +#: ../../po/../src/verbs.cpp:1950 +msgid "Exclusive OR of selected objects" +msgstr "" + +#: ../../po/../src/verbs.cpp:1951 +msgid "Di_vision" +msgstr "" + +#: ../../po/../src/verbs.cpp:1952 +msgid "Cut the bottom object into pieces" +msgstr "" + +#. TRANSLATORS: "to cut a path" is not the same as "to break a path apart" - see the +#. Advanced tutorial for more info +#: ../../po/../src/verbs.cpp:1955 +#, fuzzy +msgid "Cut _Path" +msgstr "ቁረጥ" + +#: ../../po/../src/verbs.cpp:1956 +msgid "Cut the bottom object's stroke into pieces, removing fill" +msgstr "" + +#. TRANSLATORS: "outset": expand a shape by offsetting the object's path, +#. i.e. by displacing it perpendicular to the path in each point. +#. See also the Advanced Tutorial for explanation. +#: ../../po/../src/verbs.cpp:1960 +#, fuzzy +msgid "Outs_et" +msgstr "መንቀሳቅስ" + +#: ../../po/../src/verbs.cpp:1961 +#, fuzzy +msgid "Outset selected paths" +msgstr "ምርጡ" + +#: ../../po/../src/verbs.cpp:1963 +msgid "O_utset Path by 1 px" +msgstr "" + +#: ../../po/../src/verbs.cpp:1964 +msgid "Outset selected paths by 1 px" +msgstr "" + +#: ../../po/../src/verbs.cpp:1966 +msgid "O_utset Path by 10 px" +msgstr "" + +#: ../../po/../src/verbs.cpp:1967 +msgid "Outset selected paths by 10 px" +msgstr "" + +#. TRANSLATORS: "inset": contract a shape by offsetting the object's path, +#. i.e. by displacing it perpendicular to the path in each point. +#. See also the Advanced Tutorial for explanation. +#: ../../po/../src/verbs.cpp:1971 +msgid "I_nset" +msgstr "" + +#: ../../po/../src/verbs.cpp:1972 +#, fuzzy +msgid "Inset selected paths" +msgstr "ምርጡ" + +#: ../../po/../src/verbs.cpp:1974 +msgid "I_nset Path by 1 px" +msgstr "" + +#: ../../po/../src/verbs.cpp:1975 +#, fuzzy +msgid "Inset selected paths by 1 px" +msgstr "ምርጡ" + +#: ../../po/../src/verbs.cpp:1977 +msgid "I_nset Path by 10 px" +msgstr "" + +#: ../../po/../src/verbs.cpp:1978 +#, fuzzy +msgid "Inset selected paths by 10 px" +msgstr "ምርጡ" + +#: ../../po/../src/verbs.cpp:1980 +msgid "D_ynamic Offset" +msgstr "" + +#: ../../po/../src/verbs.cpp:1980 +msgid "Create a dynamic offset object" +msgstr "" + +#: ../../po/../src/verbs.cpp:1982 +msgid "_Linked Offset" +msgstr "" + +#: ../../po/../src/verbs.cpp:1983 +msgid "Create a dynamic offset object linked to the original path" +msgstr "" + +#: ../../po/../src/verbs.cpp:1985 +msgid "_Stroke to Path" +msgstr "" + +#: ../../po/../src/verbs.cpp:1986 +#, fuzzy +msgid "Convert selected strokes to paths" +msgstr "ምርጡ" + +#: ../../po/../src/verbs.cpp:1987 +msgid "Si_mplify" +msgstr "" + +#: ../../po/../src/verbs.cpp:1988 +msgid "Simplify selected paths by removing extra nodes" +msgstr "" + +#: ../../po/../src/verbs.cpp:1989 +#, fuzzy +msgid "_Reverse" +msgstr "ፋይል" + +#: ../../po/../src/verbs.cpp:1990 +msgid "Reverses the direction of selected paths; useful for flipping markers" +msgstr "" + +#. TRANSLATORS: "to trace" means "to convert a bitmap to vector graphics" (to vectorize) +#: ../../po/../src/verbs.cpp:1992 +#, fuzzy +msgid "_Trace Bitmap" +msgstr "ላኩ" + +#: ../../po/../src/verbs.cpp:1993 +msgid "Convert bitmap object to paths" +msgstr "" + +#: ../../po/../src/verbs.cpp:1994 +msgid "_Make a Bitmap Copy" +msgstr "" + +#: ../../po/../src/verbs.cpp:1995 +msgid "Export selection to a bitmap and insert it into document" +msgstr "" + +#: ../../po/../src/verbs.cpp:1996 +msgid "_Combine" +msgstr "" + +#: ../../po/../src/verbs.cpp:1997 +msgid "Combine several paths into one" +msgstr "" + +#. TRANSLATORS: "to cut a path" is not the same as "to break a path apart" - see the +#. Advanced tutorial for more info +#: ../../po/../src/verbs.cpp:2000 +msgid "Break _Apart" +msgstr "" + +#: ../../po/../src/verbs.cpp:2001 +msgid "Break selected paths into subpaths" +msgstr "" + +#: ../../po/../src/verbs.cpp:2002 +msgid "Gri_d Arrange..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2003 +msgid "Arrange selection in grid pattern" +msgstr "" + +#. Layer +#: ../../po/../src/verbs.cpp:2005 +#, fuzzy +msgid "_Add Layer..." +msgstr "ዝቅተኛ" + +#: ../../po/../src/verbs.cpp:2006 +#, fuzzy +msgid "Create a new layer" +msgstr "ሰነድ አስቀምት" + +#: ../../po/../src/verbs.cpp:2007 +#, fuzzy +msgid "Re_name Layer..." +msgstr "ምርጡ" + +#: ../../po/../src/verbs.cpp:2008 +#, fuzzy +msgid "Rename the current layer" +msgstr "ምርጡ" + +#: ../../po/../src/verbs.cpp:2009 +msgid "Switch to Layer Abov_e" +msgstr "" + +#: ../../po/../src/verbs.cpp:2010 +msgid "Switch to the layer above the current" +msgstr "" + +#: ../../po/../src/verbs.cpp:2011 +msgid "Switch to Layer Belo_w" +msgstr "" + +#: ../../po/../src/verbs.cpp:2012 +msgid "Switch to the layer below the current" +msgstr "" + +#: ../../po/../src/verbs.cpp:2013 +#, fuzzy +msgid "Move Selection to Layer Abo_ve" +msgstr "ምርጡ" + +#: ../../po/../src/verbs.cpp:2014 +msgid "Move selection to the layer above the current" +msgstr "" + +#: ../../po/../src/verbs.cpp:2015 +#, fuzzy +msgid "Move Selection to Layer Bel_ow" +msgstr "ምርጡ" + +#: ../../po/../src/verbs.cpp:2016 +msgid "Move selection to the layer below the current" +msgstr "" + +#: ../../po/../src/verbs.cpp:2017 +msgid "Layer to _Top" +msgstr "" + +#: ../../po/../src/verbs.cpp:2018 +msgid "Raise the current layer to the top" +msgstr "" + +#: ../../po/../src/verbs.cpp:2019 +msgid "Layer to _Bottom" +msgstr "" + +#: ../../po/../src/verbs.cpp:2020 +msgid "Lower the current layer to the bottom" +msgstr "" + +#: ../../po/../src/verbs.cpp:2021 +#, fuzzy +msgid "_Raise Layer" +msgstr "አሳድግ" + +#: ../../po/../src/verbs.cpp:2022 +msgid "Raise the current layer" +msgstr "" + +#: ../../po/../src/verbs.cpp:2023 +#, fuzzy +msgid "_Lower Layer" +msgstr "ምርጡ" + +#: ../../po/../src/verbs.cpp:2024 +msgid "Lower the current layer" +msgstr "" + +#: ../../po/../src/verbs.cpp:2025 +#, fuzzy +msgid "_Delete Current Layer" +msgstr "ምርጡ" + +#: ../../po/../src/verbs.cpp:2026 +#, fuzzy +msgid "Delete the current layer" +msgstr "ምርጡ" + +#. Object +#: ../../po/../src/verbs.cpp:2029 +msgid "Rotate _90° CW" +msgstr "" + +#: ../../po/../src/verbs.cpp:2030 +msgid "Rotate selection 90° clockwise" +msgstr "" + +#: ../../po/../src/verbs.cpp:2031 +msgid "Rotate 9_0° CCW" +msgstr "" + +#: ../../po/../src/verbs.cpp:2032 +msgid "Rotate selection 90° counter-clockwise" +msgstr "" + +#: ../../po/../src/verbs.cpp:2033 +msgid "Remove _Transformations" +msgstr "" + +#: ../../po/../src/verbs.cpp:2034 +msgid "Remove transformations from object" +msgstr "" + +#: ../../po/../src/verbs.cpp:2035 +msgid "_Object to Path" +msgstr "" + +#: ../../po/../src/verbs.cpp:2036 +#, fuzzy +msgid "Convert selected objects to paths" +msgstr "ምርጡ" + +#: ../../po/../src/verbs.cpp:2037 +msgid "_Flow into Frame" +msgstr "" + +#: ../../po/../src/verbs.cpp:2038 +msgid "Put text into frames" +msgstr "" + +#: ../../po/../src/verbs.cpp:2039 +#, fuzzy +msgid "_Unflow" +msgstr "ወደ ነበረበት መልስ" + +#: ../../po/../src/verbs.cpp:2040 +msgid "Remove text from frame (creates a single-line text object)" +msgstr "" + +#: ../../po/../src/verbs.cpp:2041 +msgid "_Convert to Text" +msgstr "" + +#: ../../po/../src/verbs.cpp:2042 +msgid "Convert flowed text to regular text objects (preserves appearance)" +msgstr "" + +#: ../../po/../src/verbs.cpp:2044 +msgid "Flip _Horizontal" +msgstr "" + +#: ../../po/../src/verbs.cpp:2044 +msgid "Flips selected objects horizontally" +msgstr "" + +#: ../../po/../src/verbs.cpp:2047 +msgid "Flip _Vertical" +msgstr "" + +#: ../../po/../src/verbs.cpp:2047 +#, fuzzy +msgid "Flips selected objects vertically" +msgstr "ምርጡ" + +#. Tools +#: ../../po/../src/verbs.cpp:2051 +msgid "Select" +msgstr "ምርጡ" + +#: ../../po/../src/verbs.cpp:2052 +msgid "Select and transform objects" +msgstr "" + +#: ../../po/../src/verbs.cpp:2053 +#, fuzzy +msgid "Node Edit" +msgstr "አስተካክል" + +#: ../../po/../src/verbs.cpp:2054 +msgid "Edit path nodes or control handles" +msgstr "" + +#: ../../po/../src/verbs.cpp:2056 +msgid "Create rectangles and squares" +msgstr "" + +#: ../../po/../src/verbs.cpp:2058 +msgid "Create circles, ellipses, and arcs" +msgstr "" + +#: ../../po/../src/verbs.cpp:2060 +msgid "Create stars and polygons" +msgstr "" + +#: ../../po/../src/verbs.cpp:2062 +#, fuzzy +msgid "Create spirals" +msgstr "አያያዝ ፍጠር" + +#: ../../po/../src/verbs.cpp:2064 +msgid "Draw freehand lines" +msgstr "" + +#: ../../po/../src/verbs.cpp:2066 +msgid "Draw Bezier curves and straight lines" +msgstr "" + +#: ../../po/../src/verbs.cpp:2068 +msgid "Draw calligraphic lines" +msgstr "" + +#: ../../po/../src/verbs.cpp:2070 +#, fuzzy +msgid "Create and edit text objects" +msgstr "ጠባየ-አንቀጽ" + +#: ../../po/../src/verbs.cpp:2072 +#, fuzzy +msgid "Create and edit gradients" +msgstr "ጠባየ-አንቀጽ" + +#: ../../po/../src/verbs.cpp:2074 +#, fuzzy +msgid "Zoom in or out" +msgstr "በቅርበት አሳይ" + +#: ../../po/../src/verbs.cpp:2076 +msgid "Pick averaged colors from image" +msgstr "" + +#: ../../po/../src/verbs.cpp:2078 +#, fuzzy +msgid "Create connectors" +msgstr "ሰነድ አስቀምት" + +#. Tool prefs +#: ../../po/../src/verbs.cpp:2081 +msgid "Selector Preferences" +msgstr "" + +#: ../../po/../src/verbs.cpp:2082 +#, fuzzy +msgid "Open Preferences for the Selector tool" +msgstr "ሶዲፖዲ" + +#: ../../po/../src/verbs.cpp:2083 +msgid "Node Tool Preferences" +msgstr "" + +#: ../../po/../src/verbs.cpp:2084 +#, fuzzy +msgid "Open Preferences for the Node tool" +msgstr "ሶዲፖዲ" + +#: ../../po/../src/verbs.cpp:2085 +#, fuzzy +msgid "Rectangle Preferences" +msgstr "ዕቃ ምርጫዎች" + +#: ../../po/../src/verbs.cpp:2086 +#, fuzzy +msgid "Open Preferences for the Rectangle tool" +msgstr "ሶዲፖዲ" + +#: ../../po/../src/verbs.cpp:2087 +#, fuzzy +msgid "Ellipse Preferences" +msgstr "የእስክሪን ምርጫዎች" + +#: ../../po/../src/verbs.cpp:2088 +#, fuzzy +msgid "Open Preferences for the Ellipse tool" +msgstr "ሶዲፖዲ" + +#: ../../po/../src/verbs.cpp:2089 +#, fuzzy +msgid "Star Preferences" +msgstr "የኮከብ ምርጫዎች" + +#: ../../po/../src/verbs.cpp:2090 +#, fuzzy +msgid "Open Preferences for the Star tool" +msgstr "ሶዲፖዲ" + +#: ../../po/../src/verbs.cpp:2091 +#, fuzzy +msgid "Spiral Preferences" +msgstr "የኮከብ ምርጫዎች" + +#: ../../po/../src/verbs.cpp:2092 +#, fuzzy +msgid "Open Preferences for the Spiral tool" +msgstr "ሶዲፖዲ" + +#: ../../po/../src/verbs.cpp:2093 +#, fuzzy +msgid "Pencil Preferences" +msgstr "ሶዲፖዲ" + +#: ../../po/../src/verbs.cpp:2094 +#, fuzzy +msgid "Open Preferences for the Pencil tool" +msgstr "ሶዲፖዲ" + +#: ../../po/../src/verbs.cpp:2095 +#, fuzzy +msgid "Pen Preferences" +msgstr "ሶዲፖዲ" + +#: ../../po/../src/verbs.cpp:2096 +#, fuzzy +msgid "Open Preferences for the Pen tool" +msgstr "ሶዲፖዲ" + +#: ../../po/../src/verbs.cpp:2097 +msgid "Calligraphic Preferences" +msgstr "" + +#: ../../po/../src/verbs.cpp:2098 +#, fuzzy +msgid "Open Preferences for the Calligraphy tool" +msgstr "ሶዲፖዲ" + +#: ../../po/../src/verbs.cpp:2099 +#, fuzzy +msgid "Text Preferences" +msgstr "ሶዲፖዲ" + +#: ../../po/../src/verbs.cpp:2100 +#, fuzzy +msgid "Open Preferences for the Text tool" +msgstr "ሶዲፖዲ" + +#: ../../po/../src/verbs.cpp:2101 +#, fuzzy +msgid "Gradient Preferences" +msgstr "ሶዲፖዲ" + +#: ../../po/../src/verbs.cpp:2102 +#, fuzzy +msgid "Open Preferences for the Gradient tool" +msgstr "ሶዲፖዲ" + +#: ../../po/../src/verbs.cpp:2103 +#, fuzzy +msgid "Zoom Preferences" +msgstr "ሶዲፖዲ" + +#: ../../po/../src/verbs.cpp:2104 +#, fuzzy +msgid "Open Preferences for the Zoom tool" +msgstr "ሶዲፖዲ" + +#: ../../po/../src/verbs.cpp:2105 +#, fuzzy +msgid "Dropper Preferences" +msgstr "ሶዲፖዲ" + +#: ../../po/../src/verbs.cpp:2106 +#, fuzzy +msgid "Open Preferences for the Dropper tool" +msgstr "ሶዲፖዲ" + +#: ../../po/../src/verbs.cpp:2107 +#, fuzzy +msgid "Connector Preferences" +msgstr "የኮከብ ምርጫዎች" + +#: ../../po/../src/verbs.cpp:2108 +#, fuzzy +msgid "Open Preferences for the Connector tool" +msgstr "ሶዲፖዲ" + +#. Zoom/View +#: ../../po/../src/verbs.cpp:2111 +#, fuzzy +msgid "Zoom In" +msgstr "በቅርበት አሳይ" + +#: ../../po/../src/verbs.cpp:2111 +#, fuzzy +msgid "Zoom in" +msgstr "በቅርበት አሳይ" + +#: ../../po/../src/verbs.cpp:2112 +#, fuzzy +msgid "Zoom Out" +msgstr "በቅርበት አሳይ" + +#: ../../po/../src/verbs.cpp:2112 +#, fuzzy +msgid "Zoom out" +msgstr "በቅርበት አሳይ" + +#: ../../po/../src/verbs.cpp:2113 +#, fuzzy +msgid "_Rulers" +msgstr "ፋይል" + +#: ../../po/../src/verbs.cpp:2113 +#, fuzzy +msgid "Show or hide the canvas rulers" +msgstr "ወሰንን አሳይ" + +#: ../../po/../src/verbs.cpp:2114 +msgid "Scroll_bars" +msgstr "" + +#: ../../po/../src/verbs.cpp:2114 +msgid "Show or hide the canvas scrollbars" +msgstr "" + +#: ../../po/../src/verbs.cpp:2115 +msgid "_Grid" +msgstr "" + +#: ../../po/../src/verbs.cpp:2116 +msgid "G_uides" +msgstr "" + +#: ../../po/../src/verbs.cpp:2117 +msgid "Nex_t Zoom" +msgstr "" + +#: ../../po/../src/verbs.cpp:2117 +msgid "Next zoom (from the history of zooms)" +msgstr "" + +#: ../../po/../src/verbs.cpp:2119 +msgid "Pre_vious Zoom" +msgstr "" + +#: ../../po/../src/verbs.cpp:2119 +msgid "Previous zoom (from the history of zooms)" +msgstr "" + +#: ../../po/../src/verbs.cpp:2121 +#, fuzzy +msgid "Zoom 1:_1" +msgstr "በቅርበት አሳይ" + +#: ../../po/../src/verbs.cpp:2121 +msgid "Zoom to 1:1" +msgstr "" + +#: ../../po/../src/verbs.cpp:2123 +#, fuzzy +msgid "Zoom 1:_2" +msgstr "በቅርበት አሳይ" + +#: ../../po/../src/verbs.cpp:2123 +msgid "Zoom to 1:2" +msgstr "" + +#: ../../po/../src/verbs.cpp:2125 +#, fuzzy +msgid "_Zoom 2:1" +msgstr "በቅርበት አሳይ" + +#: ../../po/../src/verbs.cpp:2125 +msgid "Zoom to 2:1" +msgstr "" + +#: ../../po/../src/verbs.cpp:2128 +msgid "_Fullscreen" +msgstr "" + +#: ../../po/../src/verbs.cpp:2128 +msgid "Stretch this document window to full screen" +msgstr "" + +#: ../../po/../src/verbs.cpp:2131 +#, fuzzy +msgid "Duplic_ate Window" +msgstr "አባዛ" + +#: ../../po/../src/verbs.cpp:2131 +#, fuzzy +msgid "Open a new window with the same document" +msgstr "ያልተሰየመ ሰነድ" + +#: ../../po/../src/verbs.cpp:2133 +#, fuzzy +msgid "_New View Preview" +msgstr "አዲስ ቅድመ ዕይታ" + +#: ../../po/../src/verbs.cpp:2134 +#, fuzzy +msgid "New View Preview" +msgstr "አዲስ ቅድመ ዕይታ" + +#. "view_new_preview" +#: ../../po/../src/verbs.cpp:2136 +msgid "_Normal" +msgstr "" + +#: ../../po/../src/verbs.cpp:2137 +msgid "Switch to normal display mode" +msgstr "" + +#: ../../po/../src/verbs.cpp:2138 +#, fuzzy +msgid "_Outline" +msgstr "ዝጋ" + +#: ../../po/../src/verbs.cpp:2139 +msgid "Switch to outline (wireframe) display mode" +msgstr "" + +#: ../../po/../src/verbs.cpp:2141 +#, fuzzy +msgid "Ico_n Preview" +msgstr "አዲስ ቅድመ ዕይታ" + +#: ../../po/../src/verbs.cpp:2142 +msgid "Open a window to preview items at different icon resolutions" +msgstr "" + +#: ../../po/../src/verbs.cpp:2144 +msgid "Zoom to fit page in window" +msgstr "" + +#: ../../po/../src/verbs.cpp:2145 +msgid "Page _Width" +msgstr "" + +#: ../../po/../src/verbs.cpp:2146 +msgid "Zoom to fit page width in window" +msgstr "" + +#: ../../po/../src/verbs.cpp:2148 +msgid "Zoom to fit drawing in window" +msgstr "" + +#: ../../po/../src/verbs.cpp:2150 +msgid "Zoom to fit selection in window" +msgstr "" + +#. Dialogs +#: ../../po/../src/verbs.cpp:2153 +#, fuzzy +msgid "In_kscape Preferences..." +msgstr "ሶዲፖዲ" + +#: ../../po/../src/verbs.cpp:2154 +#, fuzzy +msgid "Global Inkscape preferences" +msgstr "የእስክሪን ምርጫዎች" + +#: ../../po/../src/verbs.cpp:2155 +msgid "_Document Preferences..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2156 +#, fuzzy +msgid "Preferences saved with the document" +msgstr "ያልተሰየመ ሰነድ" + +#: ../../po/../src/verbs.cpp:2157 +#, fuzzy +msgid "_Fill and Stroke..." +msgstr "የእስክሪን ምርጫዎች" + +#: ../../po/../src/verbs.cpp:2158 +#, fuzzy +msgid "Fill and Stroke dialog" +msgstr "የእስክሪን ምርጫዎች" + +#. TRANSLATORS: "Swatches" means: color samples +#: ../../po/../src/verbs.cpp:2160 +#, fuzzy +msgid "S_watches..." +msgstr "በሌላ ስም አስቀምጥ" + +#: ../../po/../src/verbs.cpp:2161 +msgid "View color swatches" +msgstr "" + +#: ../../po/../src/verbs.cpp:2162 +msgid "Transfor_m..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2163 +msgid "Transform dialog" +msgstr "" + +#: ../../po/../src/verbs.cpp:2164 +#, fuzzy +msgid "_Align and Distribute..." +msgstr "ጠባየ-አንቀጽ" + +#: ../../po/../src/verbs.cpp:2165 +#, fuzzy +msgid "Align and Distribute dialog" +msgstr "ጠባየ-አንቀጽ" + +#: ../../po/../src/verbs.cpp:2166 +#, fuzzy +msgid "_Text and Font..." +msgstr "ጽሑፍ እና የፊደል ቅርጽ" + +#: ../../po/../src/verbs.cpp:2167 +#, fuzzy +msgid "Text and Font dialog" +msgstr "ጽሑፍ እና የፊደል ቅርጽ" + +#: ../../po/../src/verbs.cpp:2168 +#, fuzzy +msgid "_XML Editor..." +msgstr "የXML ማቀናጃ" + +#: ../../po/../src/verbs.cpp:2169 +msgid "XML Editor" +msgstr "የXML ማቀናጃ" + +#: ../../po/../src/verbs.cpp:2170 +#, fuzzy +msgid "_Find..." +msgstr "አትም" + +#: ../../po/../src/verbs.cpp:2171 +#, fuzzy +msgid "Find objects in document" +msgstr "ያልተሰየመ ሰነድ" + +#: ../../po/../src/verbs.cpp:2172 +msgid "_Messages..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2173 +msgid "View debug messages" +msgstr "" + +#: ../../po/../src/verbs.cpp:2174 +#, fuzzy +msgid "S_cripts..." +msgstr "አትም" + +#: ../../po/../src/verbs.cpp:2175 +msgid "Run scripts" +msgstr "" + +#: ../../po/../src/verbs.cpp:2176 +#, fuzzy +msgid "Show/Hide D_ialogs" +msgstr "የእስክሪን ምርጫዎች" + +#: ../../po/../src/verbs.cpp:2177 +msgid "Show or hide all active dialogs" +msgstr "" + +#. TRANSLATORS: "Tile clones" means: "Create tiled clones" +#: ../../po/../src/verbs.cpp:2179 +msgid "Tile clones..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2180 +msgid "Create and arrange multiple clones of selection" +msgstr "" + +#: ../../po/../src/verbs.cpp:2181 +#, fuzzy +msgid "_Object Properties..." +msgstr "ዕቃ ምርጫዎች" + +#: ../../po/../src/verbs.cpp:2182 +#, fuzzy +msgid "Object Properties dialog" +msgstr "ዕቃ ምርጫዎች" + +#: ../../po/../src/verbs.cpp:2185 +msgid "_Connect to Jabber server..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2185 +msgid "Connect to a Jabber server" +msgstr "" + +#: ../../po/../src/verbs.cpp:2187 +#, fuzzy +msgid "Share with _user..." +msgstr "በሌላ ስም አስቀምጥ" + +#: ../../po/../src/verbs.cpp:2187 +msgid "Establish a whiteboard session with another Jabber user" +msgstr "" + +#: ../../po/../src/verbs.cpp:2189 +msgid "Share with _chatroom..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2189 +msgid "" +"Join a chatroom to start a new whiteboard session or join one in progress" +msgstr "" + +#: ../../po/../src/verbs.cpp:2191 +msgid "_Dump XML node tracker" +msgstr "" + +#: ../../po/../src/verbs.cpp:2191 +msgid "Dump the contents of the XML tracker to the console" +msgstr "" + +#: ../../po/../src/verbs.cpp:2193 +msgid "_Open session file..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2193 +msgid "Open and browse through records of past whiteboard sessions" +msgstr "" + +#: ../../po/../src/verbs.cpp:2195 +msgid "Session file playback" +msgstr "" + +#: ../../po/../src/verbs.cpp:2197 +msgid "_Disconnect from session" +msgstr "" + +#: ../../po/../src/verbs.cpp:2199 +msgid "Disconnect from _server" +msgstr "" + +#: ../../po/../src/verbs.cpp:2201 +msgid "_Input Devices..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2202 +msgid "Configure extended input devices" +msgstr "" + +#. Help +#: ../../po/../src/verbs.cpp:2205 +msgid "_Keys and Mouse" +msgstr "" + +#: ../../po/../src/verbs.cpp:2206 +msgid "Key and mouse shortcuts reference" +msgstr "" + +#: ../../po/../src/verbs.cpp:2207 +#, fuzzy +msgid "About E_xtensions" +msgstr "አጥፉ" + +#: ../../po/../src/verbs.cpp:2208 +#, fuzzy +msgid "About Extensions..." +msgstr "አጥፉ" + +#: ../../po/../src/verbs.cpp:2209 +#, fuzzy +msgid "About _Memory" +msgstr "አጥፉ" + +#: ../../po/../src/verbs.cpp:2210 +#, fuzzy +msgid "About Memory..." +msgstr "አጥፉ" + +#: ../../po/../src/verbs.cpp:2211 +msgid "_About Inkscape" +msgstr "" + +#. "help_about" +#. new HelpVerb(SP_VERB_SHOW_LICENSE, "ShowLicense", N_("Modifying or Redistributing Inkscape"), +#. N_("Show license to modify and/or redistribute Inkscape: GNU GPL"), NULL), +#. Tutorials +#: ../../po/../src/verbs.cpp:2217 +#, fuzzy +msgid "Inkscape: _Basic" +msgstr "ሶዲፖዲ" + +#: ../../po/../src/verbs.cpp:2218 +msgid "Getting started with Inkscape" +msgstr "" + +#. "tutorial_basic" +#: ../../po/../src/verbs.cpp:2219 +#, fuzzy +msgid "Inkscape: _Shapes" +msgstr "ሶዲፖዲ" + +#: ../../po/../src/verbs.cpp:2220 +msgid "Using shape tools to create and edit shapes" +msgstr "" + +#: ../../po/../src/verbs.cpp:2221 +#, fuzzy +msgid "Inkscape: _Advanced" +msgstr "ሶዲፖዲ" + +#: ../../po/../src/verbs.cpp:2222 +#, fuzzy +msgid "Advanced Inkscape topics" +msgstr "ሶዲፖዲ" + +#. "tutorial_advanced" +#. TRANSLATORS: "to trace" means "to convert a bitmap to vector graphics" (to vectorize) +#: ../../po/../src/verbs.cpp:2224 +#, fuzzy +msgid "Inkscape: T_racing" +msgstr "ሶዲፖዲ" + +#: ../../po/../src/verbs.cpp:2225 +msgid "Using bitmap tracing" +msgstr "" + +#. "tutorial_tracing" +#: ../../po/../src/verbs.cpp:2226 +#, fuzzy +msgid "Inkscape: _Calligraphy" +msgstr "ሶዲፖዲ" + +#: ../../po/../src/verbs.cpp:2227 +msgid "Using the Calligraphy pen tool" +msgstr "" + +#: ../../po/../src/verbs.cpp:2228 +msgid "_Elements of Design" +msgstr "" + +#: ../../po/../src/verbs.cpp:2229 +msgid "Principles of design in the tutorial form" +msgstr "" + +#. "tutorial_design" +#: ../../po/../src/verbs.cpp:2230 +msgid "_Tips and Tricks" +msgstr "" + +#: ../../po/../src/verbs.cpp:2231 +msgid "Miscellaneous tips and tricks" +msgstr "" + +#. "tutorial_tips" +#. Effect +#: ../../po/../src/verbs.cpp:2234 +msgid "Previous Effect" +msgstr "" + +#: ../../po/../src/verbs.cpp:2235 +msgid "Repeat the last effect with the same settings" +msgstr "" + +#. "tutorial_tips" +#: ../../po/../src/verbs.cpp:2236 +msgid "Previous Effect Settings..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2237 +msgid "Repeat the last effect with new settings" +msgstr "" + +#: ../../po/../src/widgets/dash-selector.cpp:106 +#, fuzzy +msgid "Dash pattern" +msgstr "ንድፍ፦" + +#: ../../po/../src/widgets/dash-selector.cpp:121 +#, fuzzy +msgid "Pattern offset" +msgstr "ንድፍ፦" + +#: ../../po/../src/widgets/desktop-widget.cpp:240 +msgid "Zoom drawing if window size changes" +msgstr "" + +#: ../../po/../src/widgets/desktop-widget.cpp:298 +msgid "Cursor coordinates" +msgstr "" + +#. display the initial welcome message in the statusbar +#: ../../po/../src/widgets/desktop-widget.cpp:324 +msgid "" +"Welcome to Inkscape! Use shape or freehand tools to create objects; " +"use selector (arrow) to move or transform them." +msgstr "" + +#: ../../po/../src/widgets/desktop-widget.cpp:372 +#, c-format +msgid "%s: %d - Inkscape" +msgstr "" + +#: ../../po/../src/widgets/desktop-widget.cpp:374 +#, c-format +msgid "%s - Inkscape" +msgstr "" + +#: ../../po/../src/widgets/desktop-widget.cpp:532 +#, c-format +msgid "" +"Save changes to document \"%s\" before " +"closing?\n" +"\n" +"If you close without saving, your changes will be discarded." +msgstr "" + +#: ../../po/../src/widgets/desktop-widget.cpp:548 +#: ../../po/../src/widgets/desktop-widget.cpp:612 +msgid "Close _without saving" +msgstr "" + +#: ../../po/../src/widgets/desktop-widget.cpp:595 +#, c-format +msgid "" +"The file \"%s\" was saved with a " +"format (%s) that may cause data loss!\n" +"\n" +"Do you want to save this file in another format?" +msgstr "" + +#. Family frame +#: ../../po/../src/widgets/font-selector.cpp:156 +msgid "Font family" +msgstr "የፊደል ቅርጽ ቤተሰብ" + +#. Style frame +#: ../../po/../src/widgets/font-selector.cpp:184 +msgid "Style" +msgstr "ዓይነት" + +#: ../../po/../src/widgets/font-selector.cpp:219 +msgid "Font size:" +msgstr "የፊደሉ ቅርጽ መጠን፦" + +#. TRANSLATORS: Test string used in text and font dialog (when no +#. * text has been entered) to get a preview of the font. Choose +#. * some representative characters that users of your locale will be +#. * interested in. +#: ../../po/../src/widgets/font-selector.cpp:554 +msgid "AaBbCcIiPpQq12368.;/()" +msgstr "AaBbCcIiPpQq12368.;/()" + +#: ../../po/../src/widgets/gradient-selector.cpp:137 +#: ../../po/../src/widgets/gradient-toolbar.cpp:524 +#, fuzzy +msgid "Duplicate" +msgstr "አባዛ" + +#: ../../po/../src/widgets/gradient-selector.cpp:142 +#: ../../po/../src/widgets/gradient-toolbar.cpp:535 +#, fuzzy +msgid "Edit..." +msgstr "አስተካክል" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/pservers.html#LinearGradientSpreadMethodAttribute +#: ../../po/../src/widgets/gradient-selector.cpp:159 +msgid "" +"Whether to fill with flat color beyond the ends of the gradient vector " +"(spreadMethod=\"pad\"), or repeat the gradient in the same direction " +"(spreadMethod=\"repeat\"), or repeat the gradient in alternating opposite " +"directions (spreadMethod=\"reflect\")" +msgstr "" + +#: ../../po/../src/widgets/gradient-selector.cpp:165 +#, fuzzy +msgid "none" +msgstr "ምንም" + +#: ../../po/../src/widgets/gradient-selector.cpp:169 +#, fuzzy +msgid "reflected" +msgstr "ምርጡ" + +#: ../../po/../src/widgets/gradient-selector.cpp:173 +#, fuzzy +msgid "direct" +msgstr "አስተካክል" + +#: ../../po/../src/widgets/gradient-selector.cpp:181 +msgid "Repeat:" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:217 +msgid "No gradients" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:226 +msgid "Nothing selected" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:237 +msgid "No gradients in selection" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:247 +msgid "Multiple gradients" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:525 +msgid "" +"If the gradient is used by more than one object, create a copy of it for the " +"selected object(s)" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:536 +msgid "Edit the stops of the gradient" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:593 +#: ../../po/../src/widgets/toolbox.cpp:1103 +#: ../../po/../src/widgets/toolbox.cpp:1192 +#: ../../po/../src/widgets/toolbox.cpp:1485 +#: ../../po/../src/widgets/toolbox.cpp:1534 +#: ../../po/../src/widgets/toolbox.cpp:1766 +#: ../../po/../src/widgets/toolbox.cpp:1801 +#: ../../po/../src/widgets/toolbox.cpp:2331 +#: ../../po/../src/widgets/toolbox.cpp:2370 +msgid "New:" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:606 +#, fuzzy +msgid "Create linear gradient" +msgstr "ሰነድ አስቀምት" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:620 +msgid "Create radial (elliptic or circular) gradient" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:635 +#, fuzzy +msgid "on" +msgstr "ምንም" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:648 +msgid "Create gradient in the fill" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:662 +msgid "Create gradient in the stroke" +msgstr "" + +#. FIXME: implement averaging of all parameters for multiple selected stars +#. gtk_label_set_markup(GTK_LABEL(l), _("Average:")); +#. FIXME: implement averaging of all parameters for multiple selected +#. gtk_label_set_markup(GTK_LABEL(l), _("Average:")); +#: ../../po/../src/widgets/gradient-toolbar.cpp:676 +#: ../../po/../src/widgets/toolbox.cpp:1105 +#: ../../po/../src/widgets/toolbox.cpp:1124 +#: ../../po/../src/widgets/toolbox.cpp:1493 +#: ../../po/../src/widgets/toolbox.cpp:1518 +#: ../../po/../src/widgets/toolbox.cpp:1768 +#: ../../po/../src/widgets/toolbox.cpp:1787 +#: ../../po/../src/widgets/toolbox.cpp:2334 +#: ../../po/../src/widgets/toolbox.cpp:2354 +msgid "Change:" +msgstr "" + +#: ../../po/../src/widgets/gradient-vector.cpp:269 +msgid "No gradients in document" +msgstr "" + +#: ../../po/../src/widgets/gradient-vector.cpp:275 +msgid "No gradient selected" +msgstr "" + +#: ../../po/../src/widgets/gradient-vector.cpp:532 +msgid "No stops in gradient" +msgstr "" + +#. TRANSLATORS: "Stop" means: a "phase" of a gradient +#: ../../po/../src/widgets/gradient-vector.cpp:794 +msgid "Add stop" +msgstr "" + +#: ../../po/../src/widgets/gradient-vector.cpp:797 +msgid "Add another control stop to gradient" +msgstr "" + +#: ../../po/../src/widgets/gradient-vector.cpp:799 +#, fuzzy +msgid "Delete stop" +msgstr "አጥፉ" + +#: ../../po/../src/widgets/gradient-vector.cpp:802 +msgid "Delete current control stop from gradient" +msgstr "" + +#. Label +#: ../../po/../src/widgets/gradient-vector.cpp:813 +msgid "Offset:" +msgstr "" + +#. TRANSLATORS: "Stop" means: a "phase" of a gradient +#: ../../po/../src/widgets/gradient-vector.cpp:858 +#, fuzzy +msgid "Stop Color" +msgstr "የመጀመሪያ ቀለም" + +#: ../../po/../src/widgets/gradient-vector.cpp:887 +msgid "Gradient editor" +msgstr "" + +#: ../../po/../src/widgets/layer-selector.cpp:119 +#, fuzzy +msgid "Toggle current layer visibility" +msgstr "የሰነድ ስም፦" + +#: ../../po/../src/widgets/layer-selector.cpp:139 +#, fuzzy +msgid "Lock or unlock current layer" +msgstr "የሰነድ ስም፦" + +#: ../../po/../src/widgets/layer-selector.cpp:142 +#, fuzzy +msgid "Current layer" +msgstr "የሰነድ ስም፦" + +#: ../../po/../src/widgets/layer-selector.cpp:553 +msgid "(root)" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:182 +#: ../../po/../src/widgets/paint-selector.cpp:561 +msgid "No paint" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:184 +#: ../../po/../src/widgets/paint-selector.cpp:629 +#, fuzzy +msgid "Flat color" +msgstr "የመጨረሺያ ቀለም" + +#: ../../po/../src/widgets/paint-selector.cpp:186 +#: ../../po/../src/widgets/paint-selector.cpp:696 +msgid "Linear gradient" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:188 +#: ../../po/../src/widgets/paint-selector.cpp:699 +msgid "Radial gradient" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:192 +msgid "Unset paint (make it undefined so it can be inherited)" +msgstr "" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/painting.html#FillRuleProperty +#: ../../po/../src/widgets/paint-selector.cpp:204 +msgid "" +"Any path self-intersections or subpaths create holes in the fill (fill-rule: " +"evenodd)" +msgstr "" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/painting.html#FillRuleProperty +#: ../../po/../src/widgets/paint-selector.cpp:215 +msgid "" +"Fill is solid unless a subpath is counterdirectional (fill-rule: nonzero)" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:528 +msgid "No objects" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:539 +msgid "Multiple styles" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:550 +msgid "Paint is undefined" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:757 +#, fuzzy +msgid "No patterns in document" +msgstr "ያልተሰየመ ሰነድ" + +#: ../../po/../src/widgets/paint-selector.cpp:872 +msgid "" +"Use Edit > Object(s) to Pattern to create a new pattern from " +"selection." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:426 +msgid "Now stroke width is scaled when objects are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:428 +msgid "Now stroke width is not scaled when objects are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:436 +msgid "" +"Now rounded rectangle corners are scaled when rectangles are " +"scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:438 +msgid "" +"Now rounded rectangle corners are not scaled when rectangles " +"are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:446 +msgid "" +"Now gradients are transformed along with their objects when " +"those are transformed (moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:448 +msgid "" +"Now gradients remain fixed when objects are transformed " +"(moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:456 +msgid "" +"Now patterns are transformed along with their objects when " +"those are transformed (moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:458 +msgid "" +"Now patterns remain fixed when objects are transformed (moved, " +"scaled, rotated, or skewed)." +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:506 +#, fuzzy +msgid "select_toolbar|X" +msgstr "ምርጡ" + +#: ../../po/../src/widgets/select-toolbar.cpp:506 +msgid "Horizontal coordinate of selection" +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:511 +#, fuzzy +msgid "select_toolbar|Y" +msgstr "ምርጡ" + +#: ../../po/../src/widgets/select-toolbar.cpp:511 +msgid "Vertical coordinate of selection" +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:517 +#, fuzzy +msgid "select_toolbar|W" +msgstr "ምርጡ" + +#: ../../po/../src/widgets/select-toolbar.cpp:517 +msgid "Width of selection" +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:525 +msgid "Change both width and height by the same proportion" +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:534 +#, fuzzy +msgid "select_toolbar|H" +msgstr "ምርጡ" + +#: ../../po/../src/widgets/select-toolbar.cpp:534 +msgid "Height of selection" +msgstr "" + +#: ../../po/../src/widgets/sp-color-gtkselector.cpp:62 +msgid "System" +msgstr "" + +#: ../../po/../src/widgets/sp-color-notebook.cpp:322 +#, fuzzy +msgid "RGBA_:" +msgstr "RGB" + +#: ../../po/../src/widgets/sp-color-notebook.cpp:330 +msgid "Hexadecimal RGBA value of the color" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "RGB" +msgstr "RGB" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +#, fuzzy +msgid "HSL" +msgstr "HSV" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "CMYK" +msgstr "CMYK" + +#: ../../po/../src/widgets/sp-color-scales.cpp:397 +msgid "_R" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:398 +#: ../../po/../src/widgets/sp-color-scales.cpp:399 +#, fuzzy +msgid "Red" +msgstr "ቀይ፦" + +#: ../../po/../src/widgets/sp-color-scales.cpp:400 +msgid "_G" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:401 +#: ../../po/../src/widgets/sp-color-scales.cpp:402 +#, fuzzy +msgid "Green" +msgstr "አረንጓዴ፦" + +#: ../../po/../src/widgets/sp-color-scales.cpp:403 +msgid "_B" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:404 +#: ../../po/../src/widgets/sp-color-scales.cpp:405 +#, fuzzy +msgid "Blue" +msgstr "ሰማያዊ፦" + +#. Label +#: ../../po/../src/widgets/sp-color-scales.cpp:406 +#: ../../po/../src/widgets/sp-color-scales.cpp:432 +#: ../../po/../src/widgets/sp-color-scales.cpp:463 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:141 +msgid "_A" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:407 +#: ../../po/../src/widgets/sp-color-scales.cpp:408 +#: ../../po/../src/widgets/sp-color-scales.cpp:433 +#: ../../po/../src/widgets/sp-color-scales.cpp:434 +#: ../../po/../src/widgets/sp-color-scales.cpp:464 +#: ../../po/../src/widgets/sp-color-scales.cpp:465 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:151 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:163 +msgid "Alpha (opacity)" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:423 +msgid "_H" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:424 +#: ../../po/../src/widgets/sp-color-scales.cpp:425 +#, fuzzy +msgid "Hue" +msgstr "Href፦" + +#: ../../po/../src/widgets/sp-color-scales.cpp:426 +msgid "_S" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:427 +#: ../../po/../src/widgets/sp-color-scales.cpp:428 +#, fuzzy +msgid "Saturation" +msgstr "አቀማመጥ፦" + +#: ../../po/../src/widgets/sp-color-scales.cpp:429 +msgid "_L" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:430 +#: ../../po/../src/widgets/sp-color-scales.cpp:431 +#, fuzzy +msgid "Lightness" +msgstr "እርዝማኔ፦" + +#: ../../po/../src/widgets/sp-color-scales.cpp:451 +msgid "_C" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:452 +#: ../../po/../src/widgets/sp-color-scales.cpp:453 +#, fuzzy +msgid "Cyan" +msgstr "ተወው" + +#: ../../po/../src/widgets/sp-color-scales.cpp:454 +msgid "_M" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:455 +#: ../../po/../src/widgets/sp-color-scales.cpp:456 +#, fuzzy +msgid "Magenta" +msgstr "ኢላማ፦" + +#: ../../po/../src/widgets/sp-color-scales.cpp:457 +msgid "_Y" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:458 +#: ../../po/../src/widgets/sp-color-scales.cpp:459 +#, fuzzy +msgid "Yellow" +msgstr "ብጫ፦" + +#: ../../po/../src/widgets/sp-color-scales.cpp:460 +msgid "_K" +msgstr "" + +#: ../../po/../src/widgets/sp-color-selector.cpp:71 +msgid "Unnamed" +msgstr "" + +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:68 +msgid "Wheel" +msgstr "" + +#: ../../po/../src/widgets/sp-xmlview-attr-list.cpp:53 +msgid "Attribute" +msgstr "ጠባየ-አንቀጽ" + +#: ../../po/../src/widgets/sp-xmlview-attr-list.cpp:54 +msgid "Value" +msgstr "ዕሴት" + +#: ../../po/../src/widgets/toolbox.cpp:424 +msgid "Insert new nodes into selected segments" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:426 +msgid "Delete selected nodes" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:431 +msgid "Join paths at selected nodes" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:433 +msgid "Join paths at selected nodes with new segment" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:436 +msgid "Split path between two non-endpoint nodes" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:439 +msgid "Break path at selected nodes" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:444 +msgid "Make selected nodes corner" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:447 +msgid "Make selected nodes smooth" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:450 +msgid "Make selected nodes symmetric" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:455 +msgid "Make selected segments lines" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:458 +msgid "Make selected segments curves" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1199 +msgid "Polygon" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1206 +msgid "Regular polygon (with one handle) instead of a star" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1218 +msgid "Corners:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1218 +msgid "Number of corners of a polygon or star" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1228 +#, fuzzy +msgid "Spoke ratio:" +msgstr "አቀማመጥ፦" + +#. TRANSLATORS: Tip radius of a star is the distance from the center to the farthest handle. +#. Base radius is the same for the closest handle. +#: ../../po/../src/widgets/toolbox.cpp:1231 +msgid "Base radius to tip radius ratio" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1246 +#, fuzzy +msgid "Rounded:" +msgstr "የአሠራሩ ዘዴ፦" + +#: ../../po/../src/widgets/toolbox.cpp:1246 +msgid "How much rounded are the corners (0 for sharp)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1256 +msgid "Randomized:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1256 +msgid "Scatter randomly the corners and angles" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1269 +#: ../../po/../src/widgets/toolbox.cpp:1838 +#: ../../po/../src/widgets/toolbox.cpp:2061 +msgid "Defaults" +msgstr "ነባሮች" + +#: ../../po/../src/widgets/toolbox.cpp:1270 +#: ../../po/../src/widgets/toolbox.cpp:1839 +#: ../../po/../src/widgets/toolbox.cpp:2062 +msgid "" +"Reset shape parameters to defaults (use Inkscape Preferences > Tools to " +"change defaults)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1544 +msgid "W:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1544 +msgid "Width of rectangle" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1556 +msgid "Height of rectangle" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1568 +#, fuzzy +msgid "Rx:" +msgstr "x0፦" + +#: ../../po/../src/widgets/toolbox.cpp:1568 +msgid "Horizontal radius of rounded corners" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1578 +#, fuzzy +msgid "Ry:" +msgstr "y0፦" + +#: ../../po/../src/widgets/toolbox.cpp:1578 +msgid "Vertical radius of rounded corners" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1594 +msgid "Not rounded" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1596 +msgid "Make corners sharp" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1805 +msgid "Turns:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1805 +msgid "Number of revolutions" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1815 +msgid "Divergence:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1815 +msgid "How much denser/sparser are outer revolutions; 1 = uniform" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1825 +msgid "Inner radius:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1825 +msgid "Radius of the innermost revolution (relative to the spiral size)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1957 +msgid "The width of the calligraphic pen (relative to the visible canvas area)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1967 +msgid "Thinning:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1967 +msgid "" +"How much velocity thins the stroke (> 0 makes fast strokes thinner, < 0 " +"makes them broader, 0 makes width independent of velocity)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1980 +msgid "Angle:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1980 +msgid "" +"The angle of the pen's nib (in degrees; 0 = horizontal; has no effect if " +"fixation = 0)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1990 +#, fuzzy +msgid "Fixation:" +msgstr "አቀማመጥ፦" + +#: ../../po/../src/widgets/toolbox.cpp:1990 +msgid "" +"How fixed is the pen angle (0 = always perpendicular to stroke direction, 1 " +"= fixed)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2003 +msgid "Mass:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2003 +msgid "How much inertia affects the movement of the pen" +msgstr "" + +#. TRANSLATORS: "drag" means "resistance" here +#: ../../po/../src/widgets/toolbox.cpp:2014 +msgid "Drag:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2014 +msgid "How much resistance affects the movement of the pen" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2034 +msgid "Use the pressure of the input device to alter the width of the pen" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2047 +msgid "Use the tilt of the input device to alter the angle of the pen's nib" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2374 +#, fuzzy +msgid "Start:" +msgstr "ኮከብ" + +#: ../../po/../src/widgets/toolbox.cpp:2374 +msgid "The angle (in degrees) from the horizontal to the arc's start point" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2384 +msgid "End:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2384 +msgid "The angle (in degrees) from the horizontal to the arc's end point" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2395 +#, fuzzy +msgid "Open arc" +msgstr "ክፈት" + +#: ../../po/../src/widgets/toolbox.cpp:2396 +msgid "" +"Switch between arc (unclosed shape) and segment (closed shape with two radii)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2415 +msgid "Make whole" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2417 +msgid "Make the shape a whole ellipse, not arc or segment" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2644 +msgid "" +"When pressed, picks visible color without alpha and when not pressed, picks " +"color including its alpha" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:3039 +msgid "Make connectors avoid selected objects" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:3043 +msgid "Make connectors ignore selected objects" +msgstr "" + +#. +#. 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 : +#: ../share/extensions/addnodes.inx.h:1 +#, fuzzy +msgid "Add Nodes" +msgstr "ምንም" + +#: ../share/extensions/addnodes.inx.h:2 +msgid "Maximum Segment Length" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:1 +#, fuzzy +msgid "AI Input" +msgstr "አስገባ" + +#: ../share/extensions/ai_input.inx.h:2 ../share/extensions/ai_output.inx.h:2 +msgid "Adobe Illustrator (*.ai)" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:3 +msgid "Open files saved with Adobe Illustrator" +msgstr "" + +#: ../share/extensions/ai_output.inx.h:1 +#, fuzzy +msgid "AI Output" +msgstr "ቁረጥ" + +#: ../share/extensions/ai_output.inx.h:3 +msgid "Write Adobe Illustrator" +msgstr "" + +#: ../share/extensions/dia.inx.h:1 +msgid "A diagram created with the program Dia" +msgstr "" + +#: ../share/extensions/dia.inx.h:2 +msgid "Dia Diagram (*.dia)" +msgstr "" + +#: ../share/extensions/dia.inx.h:3 +#, fuzzy +msgid "Dia Input" +msgstr "አስገባ" + +#: ../share/extensions/dia.inx.h:4 +msgid "" +"In order to import Dia files, Dia itself must be installed. You can get Dia " +"at http://www.gnome.org/projects/dia/" +msgstr "" + +#: ../share/extensions/dia.inx.h:5 +msgid "" +"The dia2svg.sh script should be installed with your Inkscape distribution. " +"If you do not have it, there is likely to be something wrong with your " +"Inkscape installation." +msgstr "" + +#: ../share/extensions/dots.inx.h:1 +#, fuzzy +msgid "Connect the Dots" +msgstr "ዝጋ" + +#: ../share/extensions/dots.inx.h:2 +#, fuzzy +msgid "Dot Size" +msgstr "የፊደሉ ቅርጽ መጠን፦" + +#: ../share/extensions/dots.inx.h:3 +#, fuzzy +msgid "Font Size" +msgstr "የፊደሉ ቅርጽ መጠን፦" + +#: ../share/extensions/dropshadow.inx.h:1 +#, fuzzy +msgid "Color of shadow" +msgstr "ወሰንን አሳይ" + +#: ../share/extensions/dropshadow.inx.h:2 +msgid "Dropshadow" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:1 +#: ../share/extensions/dxf_output.inx.h:1 +msgid "AutoCAD DXF (*.dxf)" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:2 +#, fuzzy +msgid "DXF Input" +msgstr "አስገባ" + +#: ../share/extensions/dxf_input.inx.h:3 +msgid "Import AutoCAD's Document Exchange Format" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:4 +msgid "" +"dxf2svg may come with Inkscape, but is also at http://dxf-svg-convert." +"sourceforge.net/" +msgstr "" + +#: ../share/extensions/dxf_output.inx.h:2 +#, fuzzy +msgid "DXF Output" +msgstr "ቁረጥ" + +#: ../share/extensions/dxf_output.inx.h:3 +msgid "DXF file written by pstoedit" +msgstr "" + +#: ../share/extensions/dxf_output.inx.h:4 +msgid "pstoedit must be installed to run see http://www.pstoedit.net/pstoedit" +msgstr "" + +#: ../share/extensions/embedimage.inx.h:1 +#, fuzzy +msgid "Embed Images" +msgstr "ምስል" + +#: ../share/extensions/eps_input.inx.h:1 +#, fuzzy +msgid "EPS Input" +msgstr "አስገባ" + +#: ../share/extensions/eps_input.inx.h:2 +msgid "Encapsulated Postscript" +msgstr "" + +#: ../share/extensions/eps_input.inx.h:3 +msgid "Encapsulated Postscript (*.eps)" +msgstr "" + +#: ../share/extensions/epsi_output.inx.h:1 +#, fuzzy +msgid "EPSI Output" +msgstr "ቁረጥ" + +#: ../share/extensions/epsi_output.inx.h:2 +msgid "Encapsulated Postscript Interchange (*.epsi)" +msgstr "" + +#: ../share/extensions/epsi_output.inx.h:3 +msgid "Encapsulated Postscript with a thumbnail" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:1 ../share/extensions/ffms.inx.h:1 +#: ../share/extensions/ffset.inx.h:1 ../share/extensions/ffss.inx.h:1 +#, fuzzy +msgid "Bridge Width" +msgstr "ስፋት፦" + +#: ../share/extensions/ffmet.inx.h:2 ../share/extensions/ffms.inx.h:2 +msgid "First String Length" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:3 +msgid "FretFind Multi Length ET" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:4 ../share/extensions/ffms.inx.h:4 +#: ../share/extensions/ffset.inx.h:3 ../share/extensions/ffss.inx.h:3 +msgid "Fretboard Edges" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:5 ../share/extensions/ffms.inx.h:5 +msgid "Last String Length" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:6 ../share/extensions/ffms.inx.h:6 +#: ../share/extensions/ffset.inx.h:4 ../share/extensions/ffss.inx.h:4 +msgid "Number of Frets" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:7 ../share/extensions/ffms.inx.h:7 +#: ../share/extensions/ffset.inx.h:5 ../share/extensions/ffss.inx.h:5 +msgid "Number of Strings" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:8 ../share/extensions/ffms.inx.h:8 +#: ../share/extensions/ffset.inx.h:6 ../share/extensions/ffss.inx.h:6 +#, fuzzy +msgid "Nut Width" +msgstr "ስፋት፦" + +#: ../share/extensions/ffmet.inx.h:9 ../share/extensions/ffms.inx.h:10 +msgid "Perpendicular Distance" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:10 ../share/extensions/ffset.inx.h:7 +msgid "Scale Base (2 for Octave)" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:11 ../share/extensions/ffset.inx.h:9 +msgid "Tones in Scale" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:12 ../share/extensions/ffms.inx.h:12 +#: ../share/extensions/ffset.inx.h:10 ../share/extensions/ffss.inx.h:10 +msgid "px per Unit" +msgstr "" + +#: ../share/extensions/ffms.inx.h:3 +msgid "FretFind Multi Length Scala" +msgstr "" + +#: ../share/extensions/ffms.inx.h:9 ../share/extensions/ffss.inx.h:7 +msgid "Path to Scala *.scl File" +msgstr "" + +#: ../share/extensions/ffms.inx.h:11 +msgid "Tuning (scale step for each string seperated by semicolons)" +msgstr "" + +#: ../share/extensions/ffset.inx.h:2 +msgid "FretFind Single Length ET" +msgstr "" + +#: ../share/extensions/ffset.inx.h:8 ../share/extensions/ffss.inx.h:8 +msgid "Scale Length" +msgstr "" + +#: ../share/extensions/ffss.inx.h:2 +msgid "FretFind Single Length Scala" +msgstr "" + +#: ../share/extensions/ffss.inx.h:9 +msgid "Tuning (Scale step for each string seperated by semicolons)" +msgstr "" + +#: ../share/extensions/handles.inx.h:1 +msgid "Draw Handles" +msgstr "" + +#: ../share/extensions/interp.inx.h:1 +#, fuzzy +msgid "Duplicate Endpaths" +msgstr "አባዛ" + +#: ../share/extensions/interp.inx.h:2 +#, fuzzy +msgid "Exponent" +msgstr "ላኩ" + +#: ../share/extensions/interp.inx.h:3 +msgid "Interpolate" +msgstr "" + +#: ../share/extensions/interp.inx.h:4 +msgid "Interpolate Style (Experimental)" +msgstr "" + +#: ../share/extensions/interp.inx.h:5 +msgid "Interpolation Method" +msgstr "" + +#: ../share/extensions/interp.inx.h:6 +msgid "Interpolation Steps" +msgstr "" + +#: ../share/extensions/kochify.inx.h:1 +msgid "Kochify" +msgstr "" + +#: ../share/extensions/kochify_load.inx.h:1 +msgid "Kochify (Load)" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:1 +msgid "Angle" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:2 +msgid "Axiom" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:3 +#, fuzzy +msgid "Lindenmayer" +msgstr "ምርጡ" + +#: ../share/extensions/lindenmayer.inx.h:4 +msgid "Order" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:5 +#, fuzzy +msgid "Rules" +msgstr "ፋይል" + +#: ../share/extensions/lindenmayer.inx.h:6 +#, fuzzy +msgid "Step" +msgstr "ዓይነት" + +#: ../share/extensions/motion.inx.h:1 +#, fuzzy +msgid "Direction" +msgstr "ምርጫ" + +#: ../share/extensions/motion.inx.h:2 +#, fuzzy +msgid "Magnitude" +msgstr "ኢላማ፦" + +#: ../share/extensions/motion.inx.h:3 +#, fuzzy +msgid "Motion" +msgstr "ምርጫ" + +#: ../share/extensions/pdf_output.inx.h:1 +msgid "Adobe PDF (*.pdf)" +msgstr "" + +#: ../share/extensions/pdf_output.inx.h:2 +msgid "Adobe Portable Document Format" +msgstr "" + +#: ../share/extensions/pdf_output.inx.h:3 +#, fuzzy +msgid "PDF Output" +msgstr "ቁረጥ" + +#: ../share/extensions/ps_input.inx.h:1 +#, fuzzy +msgid "Postscript" +msgstr "ነጥብ" + +#: ../share/extensions/ps_input.inx.h:2 +msgid "Postscript (*.ps)" +msgstr "" + +#: ../share/extensions/ps_input.inx.h:3 +msgid "Postscript Input" +msgstr "" + +#: ../share/extensions/radiusrand.inx.h:1 +#, fuzzy +msgid "Radius" +msgstr "አሳድግ" + +#: ../share/extensions/radiusrand.inx.h:2 +msgid "Radius Randomize" +msgstr "" + +#: ../share/extensions/radiusrand.inx.h:3 +msgid "Randomize Control Points" +msgstr "" + +#: ../share/extensions/radiusrand.inx.h:4 +msgid "Randomize Nodes" +msgstr "" + +#: ../share/extensions/rtree.inx.h:1 +msgid "Initial Size" +msgstr "" + +#: ../share/extensions/rtree.inx.h:2 +msgid "Minimum Size" +msgstr "" + +#: ../share/extensions/rtree.inx.h:3 +msgid "Random Tree" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:1 +msgid "A diagram created with the program Sketch" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:2 +msgid "Sketch Diagram (*.sk)" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:3 +msgid "Sketch Input" +msgstr "" + +#: ../share/extensions/straightseg.inx.h:1 +msgid "Behavior" +msgstr "" + +#: ../share/extensions/straightseg.inx.h:3 +msgid "Segment Straightener" +msgstr "" + +#: ../share/extensions/summersnight.inx.h:1 +msgid "Summer's Night" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:1 +#: ../share/extensions/svgz_output.inx.h:1 +msgid "Compressed Inkscape SVG (*.svgz)" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:2 +#: ../share/extensions/svgz_output.inx.h:2 +msgid "Inkscape's native file format compressed with GZip" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:3 +#, fuzzy +msgid "SVGZ Input" +msgstr "አስገባ" + +#: ../share/extensions/svgz_output.inx.h:3 +#, fuzzy +msgid "SVGZ Output" +msgstr "ቁረጥ" + +#: ../share/extensions/txt2svg.inx.h:1 +msgid "ASCII Text" +msgstr "" + +#: ../share/extensions/txt2svg.inx.h:2 +msgid "Text File (*.txt)" +msgstr "" + +#: ../share/extensions/txt2svg.inx.h:3 +#, fuzzy +msgid "Text Input" +msgstr "አስገባ" + +#: ../share/extensions/wavy.inx.h:1 +msgid "Calculate first derivative numerically" +msgstr "" + +#: ../share/extensions/wavy.inx.h:2 +msgid "First derivative" +msgstr "" + +#: ../share/extensions/wavy.inx.h:3 +msgid "Function" +msgstr "" + +#: ../share/extensions/wavy.inx.h:4 +msgid "Function Plotter" +msgstr "" + +#: ../share/extensions/wavy.inx.h:5 +msgid "Nodes per period" +msgstr "" + +#: ../share/extensions/wavy.inx.h:6 +msgid "Periods (2*Pi each)" +msgstr "" + +#: ../share/extensions/whirl.inx.h:1 +msgid "Amount of Whirl" +msgstr "" + +#: ../share/extensions/whirl.inx.h:2 +#, fuzzy +msgid "Center X" +msgstr "መሀከል X፦" + +#: ../share/extensions/whirl.inx.h:3 +#, fuzzy +msgid "Center Y" +msgstr "መሀከል Y፦" + +#: ../share/extensions/whirl.inx.h:4 +msgid "Direction of Rotation" +msgstr "" + +#: ../share/extensions/whirl.inx.h:5 +msgid "Whirl" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:1 +msgid "A popular graphics file format for clipart" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:2 +msgid "Windows Metafile (*.wmf)" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:3 +msgid "Windows Metafile Input" +msgstr "" + +#, fuzzy +#~ msgid "_Credits" +#~ msgstr "ፍጠር" + +#, fuzzy +#~ msgid "Canvas size:" +#~ msgstr "የፊደሉ ቅርጽ መጠን፦" + +#, fuzzy +#~ msgid "Custom canvas" +#~ msgstr "የተለመደው ወረቀት" + +#~ msgid "deg" +#~ msgstr "deg" + +#, fuzzy +#~ msgid "Acceleration" +#~ msgstr "ምርጫ" + +#, fuzzy +#~ msgid "Speed" +#~ msgstr "ቀይ፦" + +#, fuzzy +#~ msgid "Zoom in/out by" +#~ msgstr "በቅርበት አሳይ" + +#, fuzzy +#~ msgid "Transform" +#~ msgstr "ንድፍ፦" + +#~ msgid "Edit" +#~ msgstr "አስተካክል" + +#~ msgid "Add" +#~ msgstr "ጨምር" + +#, fuzzy +#~ msgid "C_reate" +#~ msgstr "ፍጠር" + +#, fuzzy +#~ msgid "Go to root" +#~ msgstr "አስተካክል" + +#, fuzzy +#~ msgid "X" +#~ msgstr "X፦" + +#, fuzzy +#~ msgid "Y" +#~ msgstr "Y፦" + +#~ msgid "R1:" +#~ msgstr "R1፦" + +#~ msgid "R2:" +#~ msgstr "R2፦" + +#~ msgid "ARG1:" +#~ msgstr "ARG1፦" + +#~ msgid "ARG2:" +#~ msgstr "ARG2፦" + +#, fuzzy +#~ msgid "Start Angle:" +#~ msgstr "ኮከብ" + +#, fuzzy +#~ msgid "Open:" +#~ msgstr "ክፈት" + +#, fuzzy +#~ msgid "Revolutions:" +#~ msgstr "ምርጫ" + +#~ msgid "T0:" +#~ msgstr "ወደ፦" + +#~ msgid "RX:" +#~ msgstr "RX፦" + +#~ msgid "RY:" +#~ msgstr "RY፦" + +#, fuzzy +#~ msgid "Rectangle _Properties" +#~ msgstr "ዕቃ ምርጫዎች" + +#, fuzzy +#~ msgid "Star _Properties" +#~ msgstr "የኮከብ ምርጫዎች" + +#, fuzzy +#~ msgid "Ellipse _Properties" +#~ msgstr "የአያያዝ ምርጫዎች" + +#, fuzzy +#~ msgid "Spiral _Properties" +#~ msgstr "የኮከብ ምርጫዎች" + +#, fuzzy +#~ msgid "Document Preferences" +#~ msgstr "ሶዲፖዲ" + +#, fuzzy +#~ msgid "Extensions Editor" +#~ msgstr "አጥፉ" + +#, fuzzy +#~ msgid "Preferences" +#~ msgstr "ሶዲፖዲ" + +#, fuzzy +#~ msgid "Layer Editor" +#~ msgstr "የXML ማቀናጃ" + +#, fuzzy +#~ msgid "Text Properties" +#~ msgstr "የጽሑፍ ምርጫዎች" + +#, fuzzy +#~ msgid "_Export..." +#~ msgstr "ከውጭ አስገባ" + +#, fuzzy +#~ msgid "_Document Properties" +#~ msgstr "የሰነድ ምርጫዎች" + +#, fuzzy +#~ msgid "In_kscape Preferences" +#~ msgstr "ሶዲፖዲ" + +#, fuzzy +#~ msgid "Select _Original Clone" +#~ msgstr "ምርጡ" + +#, fuzzy +#~ msgid "Tile" +#~ msgstr "አርእስት፦" + +#, fuzzy +#~ msgid "Select A_ll" +#~ msgstr "ምርጡ" + +#, fuzzy +#~ msgid "Select Non_e" +#~ msgstr "ምርጫ" + +#, fuzzy +#~ msgid "Zoom _In" +#~ msgstr "በቅርበት አሳይ" + +#, fuzzy +#~ msgid "Zoom _Out" +#~ msgstr "በቅርበት አሳይ" + +#, fuzzy +#~ msgid "Pre_vious" +#~ msgstr "አዲስ ዕይታ" + +#, fuzzy +#~ msgid "Nex_t" +#~ msgstr "ጽሑፍ" + +#, fuzzy +#~ msgid "Tool Co_ntrols bar" +#~ msgstr "የመስሪያውን ምርጫዎች" + +#, fuzzy +#~ msgid "D_uplicate Layer" +#~ msgstr "አባዛ" + +#, fuzzy +#~ msgid "_Anchor Layer" +#~ msgstr "ምርጡ" + +#, fuzzy +#~ msgid "_Delete Layer" +#~ msgstr "ምርጡ" + +#, fuzzy +#~ msgid "Select Ne_xt Layer" +#~ msgstr "ምርጡ" + +#, fuzzy +#~ msgid "Select Pre_vious Layer" +#~ msgstr "ማተሚያ ምረጥ" + +#, fuzzy +#~ msgid "Select To_p Layer" +#~ msgstr "ማተሚያ ምረጥ" + +#, fuzzy +#~ msgid "Move to Ne_w Layer" +#~ msgstr "ሰነድ አስቀምት" + +#, fuzzy +#~ msgid "_Trace Bitmap..." +#~ msgstr "ላኩ" + +#, fuzzy +#~ msgid "_Put Text on Path" +#~ msgstr "ቁረጥ" + +#, fuzzy +#~ msgid "Freehand" +#~ msgstr "አረንጓዴ፦" + +#, fuzzy +#~ msgid "Corners" +#~ msgstr "ዝጋ" + +#, fuzzy +#~ msgid "Delete" +#~ msgstr "አጥፉ" + +#, fuzzy +#~ msgid "Join" +#~ msgstr "አገጣጥም፦" + +#, fuzzy +#~ msgid "Delete Segment" +#~ msgstr "አጥፉ" + +#, fuzzy +#~ msgid "Break" +#~ msgstr "ጥቁር፦" + +#, fuzzy +#~ msgid "New" +#~ msgstr "አዲስ" + +#, fuzzy +#~ msgid "Save" +#~ msgstr "አስቀምጥ" + +#, fuzzy +#~ msgid "Save As..." +#~ msgstr "በሌላ ስም አስቀምጥ" + +#, fuzzy +#~ msgid "Import..." +#~ msgstr "ከውጭ አስገባ" + +#, fuzzy +#~ msgid "Export..." +#~ msgstr "ላኩ" + +#, fuzzy +#~ msgid "Print..." +#~ msgstr "አትም" + +#, fuzzy +#~ msgid "Global Inkscape preferences (Shift+Ctrl+P)" +#~ msgstr "የእስክሪን ምርጫዎች" + +#, fuzzy +#~ msgid "Undo" +#~ msgstr "ወደ ነበረበት መልስ" + +#, fuzzy +#~ msgid "Redo" +#~ msgstr "እንደገና አድርግ" + +#, fuzzy +#~ msgid "Cut" +#~ msgstr "ቁረጥ" + +#, fuzzy +#~ msgid "Copy" +#~ msgstr "ቅጂ" + +#, fuzzy +#~ msgid "Zoom in (+)" +#~ msgstr "በቅርበት አሳይ" + +#, fuzzy +#~ msgid "Zoom out (-)" +#~ msgstr "በቅርበት አሳይ" + +#, fuzzy +#~ msgid "Fill and Stroke dialog (Shift+Ctrl+F)" +#~ msgstr "የእስክሪን ምርጫዎች" + +#, fuzzy +#~ msgid "Align and Distribute dialog (Shift+Ctrl+A)" +#~ msgstr "ጠባየ-አንቀጽ" + +#, fuzzy +#~ msgid "Text and Font dialog (Shift+Ctrl+T)" +#~ msgstr "ጽሑፍ እና የፊደል ቅርጽ" + +#, fuzzy +#~ msgid "Node tool" +#~ msgstr "አስተካክል" + +#, fuzzy +#~ msgid "Zoom tool" +#~ msgstr "በቅርበት አሳይ" + +#, fuzzy +#~ msgid "Rectangle tool" +#~ msgstr "መቶኛዎች" + +#, fuzzy +#~ msgid "Arc tool" +#~ msgstr "የኮከብ መሣሪያ" + +#~ msgid "Star tool" +#~ msgstr "የኮከብ መሣሪያ" + +#, fuzzy +#~ msgid "Spiral tool" +#~ msgstr "የኮከብ መሣሪያ" + +#, fuzzy +#~ msgid "Text tool" +#~ msgstr "የኮከብ መሣሪያ" + +#, fuzzy +#~ msgid "URI:" +#~ msgstr "URL፦" + +#, fuzzy +#~ msgid "Select All in All Layers" +#~ msgstr "ምርጡ" + +#, fuzzy +#~ msgid "Invert Selection" +#~ msgstr "ምርጫ" + +#, fuzzy +#~ msgid "_Scripts..." +#~ msgstr "አትም" + +#, fuzzy +#~ msgid "Align and Distribute" +#~ msgstr "ጠባየ-አንቀጽ" + +#, fuzzy +#~ msgid "Align and Distribute Dialog" +#~ msgstr "ጠባየ-አንቀጽ" + +#, fuzzy +#~ msgid "Export Dialog" +#~ msgstr "የpng ፋይል ላኩ" + +#, fuzzy +#~ msgid "Fill and Stroke Dialog" +#~ msgstr "የእስክሪን ምርጫዎች" + +#, fuzzy +#~ msgid "Inkscape Preferences" +#~ msgstr "ሶዲፖዲ" + +#, fuzzy +#~ msgid "Inkscape Preferences Dialog" +#~ msgstr "ሶዲፖዲ" + +#, fuzzy +#~ msgid "Text Properties Dialog" +#~ msgstr "ዕቃ ምርጫዎች" + +#, fuzzy +#~ msgid "Tree Editor" +#~ msgstr "የXML ማቀናጃ" + +#, fuzzy +#~ msgid "XML Editor Dialog" +#~ msgstr "የXML ማቀናጃ" + +#, fuzzy +#~ msgid "Row height:" +#~ msgstr "እርዝማኔ፦" + +#, fuzzy +#~ msgid "Column width:" +#~ msgstr "ዝጋ" + +#, fuzzy +#~ msgid "EPS Output Settings" +#~ msgstr "የሰነድ ምርጫዎች" + +#, fuzzy +#~ msgid "Inkscape" +#~ msgstr "ሶዲፖዲ" + +#, fuzzy +#~ msgid "Alternate sign" +#~ msgstr "አቀማመጥ፦" + +#, fuzzy +#~ msgid "Grid emphasis color" +#~ msgstr "የመጨረሺያ ቀለም" + +#, fuzzy +#~ msgid "Background (also for export):" +#~ msgstr "የመጨረሺያ ቀለም" + +#, fuzzy +#~ msgid "Fill:" +#~ msgstr "ፋይል" + +#, fuzzy +#~ msgid "alternating" +#~ msgstr "አቀማመጥ፦" + +#, fuzzy +#~ msgid "Update Properties" +#~ msgstr "ዕቃ ምርጫዎች" + +#, fuzzy +#~ msgid "executable" +#~ msgstr "መቶኛዎች" + +#, fuzzy +#~ msgid "file" +#~ msgstr "ፋይል" + +#, fuzzy +#~ msgid "path" +#~ msgstr "ነጥብ" + +#, fuzzy +#~ msgid "absolute" +#~ msgstr "ዕሴት" + +#~ msgid "Plain SVG" +#~ msgstr "ቀላል SVG" + +#, fuzzy +#~ msgid "Layer Properties" +#~ msgstr "የኮከብ ምርጫዎች" + +#, fuzzy +#~ msgid "Apply" +#~ msgstr "ለ... አውል፦" + +#~ msgid "Untitled" +#~ msgstr "ያልተሰየመ" + +#~ msgid "Document Name:" +#~ msgstr "የሰነድ ስም፦" + +#~ msgid "Image URI:" +#~ msgstr "የምስል URI፦" + +#~ msgid "Visible" +#~ msgstr "የሚታይ" + +#, fuzzy +#~ msgid "Other" +#~ msgstr "ቅደም ተከተል" + +#~ msgid "Alignment:" +#~ msgstr "ኩልኩል፦" + +#~ msgid "Text and font" +#~ msgstr "ጽሑፍ እና የፊደል ቅርጽ" + +#, fuzzy +#~ msgid "Pattern Fill" +#~ msgstr "ንድፍ፦" + +#, fuzzy +#~ msgid "Rect" +#~ msgstr "አስተካክል" + +#~ msgid "meters" +#~ msgstr "ሜትሮች" + +#~ msgid "User" +#~ msgstr "ተጠቃሚ" + +#, fuzzy +#~ msgid "Ru_lers" +#~ msgstr "ፋይል" + +#~ msgid "Alpha:" +#~ msgstr "አልፋ፦" + +#~ msgid "Value:" +#~ msgstr "ዕሴት፦" + +#~ msgid "Item properties" +#~ msgstr "የዕቃ ምርጫዎች" + +#, fuzzy +#~ msgid "New View" +#~ msgstr "አዲስ ዕይታ" + +#, fuzzy +#~ msgid "Fill and stroke settings" +#~ msgstr "የእስክሪን ምርጫዎች" + +#, fuzzy +#~ msgid "Text editing and font settings" +#~ msgstr "ጽሑፍ እና የፊደል ቅርጽ" + +#~ msgid "Show content" +#~ msgstr "ይዞታ አሳይ" + +#, fuzzy +#~ msgid "Inkscape _Options" +#~ msgstr "ሶዲፖዲ" + +#, fuzzy +#~ msgid "Tool Optio_ns" +#~ msgstr "የመስሪያውን ምርጫዎች" + +#, fuzzy +#~ msgid "Object Size and Position" +#~ msgstr "መጠን እና ቦታ" + +#~ msgid "Size and Position" +#~ msgstr "መጠን እና ቦታ" + +#~ msgid "Item" +#~ msgstr "ዕቃ" + +#~ msgid "Group Properties" +#~ msgstr "የመድረክ ምርጫዎች" + +#, fuzzy +#~ msgid "In" +#~ msgstr "ኢንች" + +#~ msgid "1:1" +#~ msgstr "1:1" + +#~ msgid "1:2" +#~ msgstr "1:2" + +#~ msgid "2:1" +#~ msgstr "2:1" + +#, fuzzy +#~ msgid "Editing window properties" +#~ msgstr "የአያያዝ ምርጫዎች" + +#~ msgid "Sodipodi" +#~ msgstr "ሶዲፖዲ" + +#~ msgid "Desktop settings" +#~ msgstr "የሠሌዳ ምርጫዎች" + +#~ msgid "Display settings" +#~ msgstr "የእስክሪን ምርጫዎች" + +#~ msgid "Exit Program" +#~ msgstr "ከፕሮግራሙ ውጣ" + +#~ msgid "SVG with \"xmlns:sodipodi\" namespace" +#~ msgstr "SVG በ \"xmlns:sodipodi\" namespace" + +#~ msgid "Unknown item :-(" +#~ msgstr "ያልታወቀ ዕቃ :-(" + +#~ msgid "Document" +#~ msgstr "ሰነድ" + +#, fuzzy +#~ msgid "Document variant:" +#~ msgstr "የሰነድ ስም፦" + +#, fuzzy +#~ msgid "Save document as" +#~ msgstr "ሰነድ አስቀምት" + +#~ msgid "About sodipodi" +#~ msgstr "ስለ ሶዲፖዲ" + +#~ msgid "About Sodipodi" +#~ msgstr "ስለ ሶዲፖዲ" + +#~ msgid "Display Properties" +#~ msgstr "የእስክሪን ምርጫዎች" + +#~ msgid "Save as:" +#~ msgstr "በሌላ ስም አስቀምጥ" diff --git a/po/az.po b/po/az.po new file mode 100644 index 000000000..69d0854f2 --- /dev/null +++ b/po/az.po @@ -0,0 +1,10742 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR Free Software Foundation, Inc. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: sodipodi 0.28\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2005-12-04 11:51-0800\n" +"PO-Revision-Date: 2001-12-04 17:40GMT+0200\n" +"Last-Translator: Vasif Ä°smayıloğlu MD \n" +"Language-Team: Azerbaijani Turkic \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 0.9.5\n" + +#: ../inkscape.desktop.in.h:1 +msgid "Create and edit Scalable Vector Graphics images" +msgstr "" + +#: ../inkscape.desktop.in.h:2 +msgid "Inkscape SVG Vector Illustrator" +msgstr "" + +#: ../../po/../src/arc-context.cpp:350 +msgid "" +"Ctrl: make circle or integer-ratio ellipse, snap arc/segment angle" +msgstr "" + +#: ../../po/../src/arc-context.cpp:351 ../../po/../src/rect-context.cpp:388 +msgid "Shift: draw around the starting point" +msgstr "" + +#: ../../po/../src/arc-context.cpp:413 +#: ../../po/../src/connector-context.cpp:493 +#: ../../po/../src/dyna-draw-context.cpp:506 +#: ../../po/../src/pen-context.cpp:329 ../../po/../src/pencil-context.cpp:208 +#: ../../po/../src/rect-context.cpp:452 ../../po/../src/spiral-context.cpp:421 +#: ../../po/../src/star-context.cpp:427 +msgid "Current layer is hidden. Unhide it to be able to draw on it." +msgstr "" + +#: ../../po/../src/arc-context.cpp:417 +#: ../../po/../src/connector-context.cpp:497 +#: ../../po/../src/dyna-draw-context.cpp:510 +#: ../../po/../src/pen-context.cpp:336 ../../po/../src/pencil-context.cpp:212 +#: ../../po/../src/rect-context.cpp:456 ../../po/../src/spiral-context.cpp:426 +#: ../../po/../src/star-context.cpp:431 +msgid "Current layer is locked. Unlock it to be able to draw on it." +msgstr "" + +#: ../../po/../src/arc-context.cpp:496 +#, c-format +msgid "" +"Ellipse: %s × %s; with Ctrl to make circle or integer-" +"ratio ellipse; with Shift to draw around the starting point" +msgstr "" + +#: ../../po/../src/connector-context.cpp:518 +#, fuzzy +msgid "Creating new connector" +msgstr "Sənəd" + +#: ../../po/../src/connector-context.cpp:939 +#, fuzzy +msgid "Finishing connector" +msgstr "Freehand" + +#: ../../po/../src/connector-context.cpp:1108 +msgid "Connection point: click or drag to create a new connector" +msgstr "" + +#: ../../po/../src/connector-context.cpp:1185 +msgid "Connector endpoint: drag to reroute or connect to new shapes" +msgstr "" + +#: ../../po/../src/connector-context.cpp:1278 +#, fuzzy +msgid "Select at least one non-connector object." +msgstr "Seçili cismləri qruplaşdır" + +#: ../../po/../src/desktop-events.cpp:238 +#, c-format +msgid "%s at %s" +msgstr "" + +#. TRANSLATORS: This string appears when double-clicking on a guide. +#. This is the distance by which the guide is to be moved. +#: ../../po/../src/desktop-events.cpp:277 +#, fuzzy +msgid " relative by " +msgstr "şaquli hərəkət" + +#. TRANSLATORS: This string appears when double-clicking on a guide. +#. This is the target location where the guide is to be moved. +#: ../../po/../src/desktop-events.cpp:282 +#: ../../po/../src/desktop-events.cpp:395 +#, fuzzy +msgid " absolute to " +msgstr "mütləq" + +#. create dialog +#: ../../po/../src/desktop-events.cpp:348 +msgid "Guideline" +msgstr "" + +#: ../../po/../src/desktop-events.cpp:432 +#, fuzzy, c-format +msgid "Move %s" +msgstr "Daşı" + +#: ../../po/../src/desktop.cpp:678 +msgid "No previous zoom." +msgstr "" + +#: ../../po/../src/desktop.cpp:703 +msgid "No next zoom." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:182 +msgid "Nothing selected." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:188 +msgid "More than one object selected." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:195 +#, c-format +msgid "Object has %d tiled clones." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:200 +msgid "Object has no tiled clones." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:865 +#, fuzzy +msgid "Select one object whose tiled clones to unclump." +msgstr "Seçili bölmani ara yaddaşa al" + +#: ../../po/../src/dialogs/clonetiler.cpp:916 +#, fuzzy +msgid "Select one object whose tiled clones to remove." +msgstr "Seçili bölmani ara yaddaşa al" + +#: ../../po/../src/dialogs/clonetiler.cpp:984 +#: ../../po/../src/selection-chemistry.cpp:1774 +#, fuzzy +msgid "Select an object to clone." +msgstr "Seçili bölmani ara yaddaşa al" + +#: ../../po/../src/dialogs/clonetiler.cpp:990 +#: ../../po/../src/selection-chemistry.cpp:1780 +msgid "" +"If you want to clone several objects, group them and clone the " +"group." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1484 +msgid "Per row:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1497 +msgid "Per column:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1505 +msgid "Randomize:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1656 +#, fuzzy +msgid "_Symmetry" +msgstr "Asimetrik" + +#. TRANSLATORS: For the following 17 symmetry groups, see +#. * http://www.bib.ulb.ac.be/coursmath/doc/17.htm (visual examples); +#. * http://www.clarku.edu/~djoyce/wallpaper/seventeen.html (English vocabulary); or +#. * http://membres.lycos.fr/villemingerard/Geometri/Sym1D.htm (French vocabulary). +#. +#: ../../po/../src/dialogs/clonetiler.cpp:1664 +msgid "Select one of the 17 symmetry groups for the tiling" +msgstr "" + +#. TRANSLATORS: "translation" means "shift" / "displacement" here. +#: ../../po/../src/dialogs/clonetiler.cpp:1675 +msgid "P1: simple translation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1676 +msgid "P2: 180° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1677 +msgid "PM: reflection" +msgstr "" + +#. TRANSLATORS: "glide reflection" is a reflection and a translation combined. +#. For more info, see http://mathforum.org/sum95/suzanne/symsusan.html +#: ../../po/../src/dialogs/clonetiler.cpp:1680 +msgid "PG: glide reflection" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1681 +msgid "CM: reflection + glide reflection" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1682 +msgid "PMM: reflection + reflection" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1683 +msgid "PMG: reflection + 180° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1684 +msgid "PGG: glide reflection + 180° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1685 +msgid "CMM: reflection + reflection + 180° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1686 +msgid "P4: 90° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1687 +msgid "P4M: 90° rotation + 45° reflection" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1688 +msgid "P4G: 90° rotation + 90° reflection" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1689 +msgid "P3: 120° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1690 +msgid "P31M: reflection + 120° rotation, dense" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1691 +msgid "P3M1: reflection + 120° rotation, sparse" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1692 +msgid "P6: 60° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1693 +msgid "P6M: reflection + 60° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1721 +msgid "S_hift" +msgstr "" + +#. TRANSLATORS: "shift" means: the tiles will be shifted (offset) horizontally by this amount +#: ../../po/../src/dialogs/clonetiler.cpp:1731 +#, no-c-format +msgid "Shift X:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1739 +#, no-c-format +msgid "Horizontal shift per row (in % of tile width)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1747 +#, no-c-format +msgid "Horizontal shift per column (in % of tile width)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1754 +msgid "Randomize the horizontal shift by this percentage" +msgstr "" + +#. TRANSLATORS: "shift" means: the tiles will be shifted (offset) vertically by this amount +#: ../../po/../src/dialogs/clonetiler.cpp:1764 +#, no-c-format +msgid "Shift Y:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1772 +#, no-c-format +msgid "Vertical shift per row (in % of tile height)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1780 +#, no-c-format +msgid "Vertical shift per column (in % of tile height)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1787 +msgid "Randomize the vertical shift by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1795 +#, fuzzy +msgid "Exponent:" +msgstr "Elips" + +#: ../../po/../src/dialogs/clonetiler.cpp:1802 +msgid "Whether rows are spaced evenly (1), converge (<1) or diverge (>1)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1809 +msgid "Whether columns are spaced evenly (1), converge (<1) or diverge (>1)" +msgstr "" + +#. TRANSLATORS: "Alternate" is a verb here +#: ../../po/../src/dialogs/clonetiler.cpp:1817 +#: ../../po/../src/dialogs/clonetiler.cpp:1907 +#: ../../po/../src/dialogs/clonetiler.cpp:1966 +#: ../../po/../src/dialogs/clonetiler.cpp:2022 +#: ../../po/../src/dialogs/clonetiler.cpp:2153 +msgid "Alternate:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1823 +msgid "Alternate the sign of shifts for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1828 +msgid "Alternate the sign of shifts for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1837 +#, fuzzy +msgid "Sc_ale" +msgstr "Miqyas" + +#: ../../po/../src/dialogs/clonetiler.cpp:1845 +#, fuzzy +msgid "Scale X:" +msgstr "Düzbucaqlı Dördbucaq" + +#: ../../po/../src/dialogs/clonetiler.cpp:1853 +#, no-c-format +msgid "Horizontal scale per row (in % of tile width)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1861 +#, no-c-format +msgid "Horizontal scale per column (in % of tile width)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1868 +msgid "Randomize the horizontal scale by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1876 +#, fuzzy +msgid "Scale Y:" +msgstr "Düzbucaqlı Dördbucaq" + +#: ../../po/../src/dialogs/clonetiler.cpp:1884 +#, no-c-format +msgid "Vertical scale per row (in % of tile height)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1892 +#, no-c-format +msgid "Vertical scale per column (in % of tile height)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1899 +msgid "Randomize the vertical scale by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1913 +msgid "Alternate the sign of scales for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1918 +msgid "Alternate the sign of scales for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1927 +#, fuzzy +msgid "_Rotation" +msgstr "Seçki" + +#: ../../po/../src/dialogs/clonetiler.cpp:1935 +#, fuzzy +msgid "Angle:" +msgstr "Düzbucaqlı Dördbucaq" + +#: ../../po/../src/dialogs/clonetiler.cpp:1943 +#, no-c-format +msgid "Rotate tiles by this angle for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1951 +#, no-c-format +msgid "Rotate tiles by this angle for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1958 +msgid "Randomize the rotation angle by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1972 +msgid "Alternate the rotation direction for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1977 +msgid "Alternate the rotation direction for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1985 +#, fuzzy +msgid "_Opacity" +msgstr "Şəffaflıq:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1993 +msgid "Fade out:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2000 +msgid "Decrease tile opacity by this percentage for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2007 +msgid "Decrease tile opacity by this percentage for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2014 +msgid "Randomize the tile opacity by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2028 +msgid "Alternate the sign of opacity change for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2033 +msgid "Alternate the sign of opacity change for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2041 +#, fuzzy +msgid "Co_lor" +msgstr "Rəng:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2046 +#, fuzzy +msgid "Initial color: " +msgstr "Rəng seç" + +#: ../../po/../src/dialogs/clonetiler.cpp:2050 +msgid "Initial color of tiled clones" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2050 +msgid "" +"Initial color for clones (works only if the original has unset fill or " +"stroke)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2065 +#, fuzzy +msgid "H:" +msgstr "Elips" + +#: ../../po/../src/dialogs/clonetiler.cpp:2072 +msgid "Change the tile hue by this percentage for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2079 +msgid "Change the tile hue by this percentage for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2086 +msgid "Randomize the tile hue by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2095 +#, fuzzy +msgid "S:" +msgstr "Elips" + +#: ../../po/../src/dialogs/clonetiler.cpp:2102 +msgid "Change the color saturation by this percentage for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2109 +msgid "Change the color saturation by this percentage for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2116 +msgid "Randomize the color saturation by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2124 +#, fuzzy +msgid "L:" +msgstr "Elips" + +#: ../../po/../src/dialogs/clonetiler.cpp:2131 +msgid "Change the color lightness by this percentage for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2138 +msgid "Change the color lightness by this percentage for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2145 +msgid "Randomize the color lightness by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2159 +msgid "Alternate the sign of color changes for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2164 +msgid "Alternate the sign of color changes for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2172 +#, fuzzy +msgid "_Trace" +msgstr "Qırıq bit xəritəsi" + +#: ../../po/../src/dialogs/clonetiler.cpp:2179 +msgid "Trace the drawing under the tiles" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2183 +msgid "" +"For each clone, pick a value from the drawing in that clone's location and " +"apply it to the clone" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2197 +msgid "1. Pick from the drawing:" +msgstr "" + +#. ----Hbox2 +#: ../../po/../src/dialogs/clonetiler.cpp:2208 +#: ../../po/../src/dialogs/clonetiler.cpp:2355 +#: ../../po/../src/ui/dialog/tracedialog.cpp:445 +#, fuzzy +msgid "Color" +msgstr "Rəng:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2209 +msgid "Pick the visible color and opacity" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2216 +#: ../../po/../src/dialogs/clonetiler.cpp:2365 +#: ../share/extensions/dropshadow.inx.h:3 +#, fuzzy +msgid "Opacity" +msgstr "Şəffaflıq:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2217 +msgid "Pick the total accumulated opacity" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2224 +msgid "R" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2225 +msgid "Pick the Red component of the color" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2232 +msgid "G" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2233 +msgid "Pick the Green component of the color" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2240 +msgid "B" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2241 +msgid "Pick the Blue component of the color" +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2250 +msgid "clonetiler|H" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2251 +msgid "Pick the hue of the color" +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2260 +msgid "clonetiler|S" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2261 +msgid "Pick the saturation of the color" +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2270 +msgid "clonetiler|L" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2271 +msgid "Pick the lightness of the color" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2281 +msgid "2. Tweak the picked value:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2291 +msgid "Gamma-correct:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2296 +msgid "Shift the mid-range of the picked value upwards (>0) or downwards (<0)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2303 +msgid "Randomize:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2308 +msgid "Randomize the picked value by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2315 +#, fuzzy +msgid "Invert:" +msgstr "inç" + +#: ../../po/../src/dialogs/clonetiler.cpp:2319 +msgid "Invert the picked value" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2325 +msgid "3. Apply the value to the clones':" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2335 +#, fuzzy +msgid "Presence" +msgstr "Sodipodi" + +#: ../../po/../src/dialogs/clonetiler.cpp:2338 +msgid "" +"Each clone is created with the probability determined by the picked value in " +"that point" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2345 +msgid "Size" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2348 +msgid "Each clone's size is determined by the picked value in that point" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2358 +msgid "" +"Each clone is painted by the picked color (the original must have unset fill " +"or stroke)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2368 +msgid "Each clone's opacity is determined by the picked value in that point" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2395 +msgid "How many rows in the tiling" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2415 +msgid "How many columns in the tiling" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2445 +msgid "Width of the rectangle to be filled" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2470 +msgid "Height of the rectangle to be filled" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2485 +#, fuzzy +msgid "Rows, columns: " +msgstr "Elips" + +#: ../../po/../src/dialogs/clonetiler.cpp:2486 +msgid "Create the specified number of rows and columns" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2495 +#, fuzzy +msgid "Width, height: " +msgstr "Hündürlük: " + +#: ../../po/../src/dialogs/clonetiler.cpp:2496 +msgid "Fill the specified width and height with the tiling" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2512 +#, fuzzy +msgid "Use saved size and position of the tile" +msgstr "Yer" + +#: ../../po/../src/dialogs/clonetiler.cpp:2515 +msgid "" +"Pretend that the size and position of the tile are the same as the last time " +"you tiled it (if any), instead of using the current size" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2539 +#, fuzzy +msgid " _Create " +msgstr "Düzbucaqlı Dördbucaq" + +#: ../../po/../src/dialogs/clonetiler.cpp:2541 +msgid "Create and tile the clones of the selection" +msgstr "" + +#. TRANSLATORS: if a group of objects are "clumped" together, then they +#. are unevenly spread in the given amount of space - as shown in the +#. diagrams on the left in the following screenshot: +#. http://www.inkscape.org/screenshots/gallery/inkscape-0.42-CVS-tiles-unclump.png +#. So unclumping is the process of spreading a number of objects out more evenly. +#: ../../po/../src/dialogs/clonetiler.cpp:2556 +msgid " _Unclump " +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2557 +msgid "Spread out clones to reduce clumping; can be applied repeatedly" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2563 +#, fuzzy +msgid " Re_move " +msgstr "Körpünü sil" + +#: ../../po/../src/dialogs/clonetiler.cpp:2564 +msgid "Remove existing tiled clones of the selected object (siblings only)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2580 +#, fuzzy +msgid " R_eset " +msgstr "Körpünü sil" + +#. TRANSLATORS: "change" is a noun here +#: ../../po/../src/dialogs/clonetiler.cpp:2582 +msgid "" +"Reset all shifts, scales, rotates, opacity and color changes in the dialog " +"to zero" +msgstr "" + +#: ../../po/../src/dialogs/color-picker.cpp:280 +#, fuzzy +msgid "Close" +msgstr "Yeni Görünüş" + +#: ../../po/../src/dialogs/debugdialog.cpp:138 +msgid "Messages" +msgstr "" + +#. ## Add a menu for clear() +#: ../../po/../src/dialogs/debugdialog.cpp:144 +#: ../../po/../src/menus-skeleton.h:16 +#: ../../po/../src/ui/dialog/messages.cpp:56 +#: ../../po/../src/ui/dialog/scriptdialog.cpp:181 +msgid "_File" +msgstr "_Fayl" + +#. TRANSLATORS: "Clear" is a verb here +#: ../../po/../src/dialogs/debugdialog.cpp:145 +#: ../../po/../src/dialogs/find.cpp:753 +#: ../../po/../src/ui/dialog/messages.cpp:57 +#: ../../po/../src/ui/dialog/scriptdialog.cpp:182 +#, fuzzy +msgid "_Clear" +msgstr "Yeni Görünüş" + +#: ../../po/../src/dialogs/debugdialog.cpp:147 +#: ../../po/../src/ui/dialog/messages.cpp:59 +msgid "Capture log messages" +msgstr "" + +#: ../../po/../src/dialogs/debugdialog.cpp:149 +#: ../../po/../src/ui/dialog/messages.cpp:61 +msgid "Release log messages" +msgstr "" + +#. Notebook tab +#: ../../po/../src/dialogs/desktop-properties.cpp:909 +#: ../../po/../src/ui/dialog/document-preferences.cpp:89 +#: ../../po/../src/ui/widget/panel.cpp:107 +msgid "Grid" +msgstr "Qəfəs" + +#. Checkbuttons +#. / \todo FIXME: gray out snapping when grid is off +#. / \todo FIXME: gray out snapping when grid is off. +#. / Dissenting view: you want snapping without grid. +#: ../../po/../src/dialogs/desktop-properties.cpp:917 +#: ../../po/../src/ui/dialog/document-preferences.cpp:179 +msgid "Show grid" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:917 +#: ../../po/../src/ui/dialog/document-preferences.cpp:179 +#: ../../po/../src/verbs.cpp:2115 +#, fuzzy +msgid "Show or hide grid" +msgstr "Kənarları Aç" + +#: ../../po/../src/dialogs/desktop-properties.cpp:918 +#: ../../po/../src/ui/dialog/document-preferences.cpp:180 +#, fuzzy +msgid "Snap bounding boxes to grid" +msgstr "Kənarları Aç" + +#: ../../po/../src/dialogs/desktop-properties.cpp:918 +#: ../../po/../src/dialogs/desktop-properties.cpp:1001 +#: ../../po/../src/ui/dialog/document-preferences.cpp:181 +#: ../../po/../src/ui/dialog/document-preferences.cpp:236 +msgid "Snap the edges of the object bounding boxes" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:919 +#: ../../po/../src/ui/dialog/document-preferences.cpp:183 +#, fuzzy +msgid "Snap nodes to grid" +msgstr "Kənarları Aç" + +#: ../../po/../src/dialogs/desktop-properties.cpp:919 +#: ../../po/../src/dialogs/desktop-properties.cpp:1002 +#: ../../po/../src/ui/dialog/document-preferences.cpp:184 +#: ../../po/../src/ui/dialog/document-preferences.cpp:239 +msgid "Snap path nodes, text baselines, ellipse centers, etc." +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:937 +#: ../../po/../src/ui/dialog/document-preferences.cpp:186 +msgid "Grid units:" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:939 +#: ../../po/../src/ui/dialog/document-preferences.cpp:187 +msgid "Origin X:" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:942 +#: ../../po/../src/ui/dialog/document-preferences.cpp:189 +msgid "Origin Y:" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:945 +#: ../../po/../src/ui/dialog/document-preferences.cpp:191 +msgid "Spacing X:" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:948 +#: ../../po/../src/ui/dialog/document-preferences.cpp:193 +msgid "Spacing Y:" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:952 +#: ../../po/../src/dialogs/desktop-properties.cpp:1013 +#: ../../po/../src/ui/dialog/document-preferences.cpp:195 +#: ../../po/../src/ui/dialog/document-preferences.cpp:241 +msgid "Snap units:" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:955 +#: ../../po/../src/dialogs/desktop-properties.cpp:1016 +#: ../../po/../src/ui/dialog/document-preferences.cpp:196 +#: ../../po/../src/ui/dialog/document-preferences.cpp:242 +msgid "Snap distance:" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:958 +#: ../../po/../src/ui/dialog/document-preferences.cpp:199 +#, fuzzy +msgid "Grid line color:" +msgstr "Son rəngi" + +#: ../../po/../src/dialogs/desktop-properties.cpp:959 +#: ../../po/../src/ui/dialog/document-preferences.cpp:199 +#, fuzzy +msgid "Grid line color" +msgstr "Son rəngi" + +#: ../../po/../src/dialogs/desktop-properties.cpp:959 +#: ../../po/../src/ui/dialog/document-preferences.cpp:200 +msgid "Color of grid lines" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:961 +#: ../../po/../src/ui/dialog/document-preferences.cpp:201 +#, fuzzy +msgid "Major grid line color:" +msgstr "Son rəngi" + +#: ../../po/../src/dialogs/desktop-properties.cpp:962 +#: ../../po/../src/ui/dialog/document-preferences.cpp:201 +#, fuzzy +msgid "Major grid line color" +msgstr "Son rəngi" + +#: ../../po/../src/dialogs/desktop-properties.cpp:962 +#: ../../po/../src/ui/dialog/document-preferences.cpp:202 +msgid "Color of the major (highlighted) grid lines" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:965 +#: ../../po/../src/ui/dialog/document-preferences.cpp:204 +#, fuzzy +msgid "Major grid line every:" +msgstr "Son rəngi" + +#. TRANSLATORS: This belongs to the "Major grid line every:" string, +#. see grid settings in the "Document Preferences" dialog +#: ../../po/../src/dialogs/desktop-properties.cpp:977 +#: ../../po/../src/ui/dialog/document-preferences.cpp:204 +#, fuzzy +msgid "lines" +msgstr "Yeni Görünüş" + +#. Guidelines page +#: ../../po/../src/dialogs/desktop-properties.cpp:991 +#: ../../po/../src/ui/dialog/document-preferences.cpp:90 +msgid "Guides" +msgstr "" + +#. / \todo FIXME: gray out snapping when guides are off +#. / Dissenting view: you want snapping without guides. +#: ../../po/../src/dialogs/desktop-properties.cpp:1000 +#: ../../po/../src/ui/dialog/document-preferences.cpp:234 +msgid "Show guides" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1000 +#: ../../po/../src/ui/dialog/document-preferences.cpp:234 +#: ../../po/../src/verbs.cpp:2116 +#, fuzzy +msgid "Show or hide guides" +msgstr "Kənarları Aç" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1001 +#: ../../po/../src/ui/dialog/document-preferences.cpp:235 +#, fuzzy +msgid "Snap bounding boxes to guides" +msgstr "Kənarları Aç" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1002 +#: ../../po/../src/ui/dialog/document-preferences.cpp:238 +#, fuzzy +msgid "Snap points to guides" +msgstr "Kənarları Aç" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1020 +#: ../../po/../src/ui/dialog/document-preferences.cpp:243 +#, fuzzy +msgid "Guide color:" +msgstr "Son rəngi" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1021 +#: ../../po/../src/ui/dialog/document-preferences.cpp:243 +msgid "Guideline color" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1021 +#: ../../po/../src/ui/dialog/document-preferences.cpp:244 +#, fuzzy +msgid "Color of guidelines" +msgstr "üfüqi hərəkət" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1023 +#: ../../po/../src/ui/dialog/document-preferences.cpp:245 +msgid "Highlight color:" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1024 +#: ../../po/../src/ui/dialog/document-preferences.cpp:245 +msgid "Highlighted guideline color" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1024 +#: ../../po/../src/ui/dialog/document-preferences.cpp:246 +msgid "Color of a guideline when it is under mouse" +msgstr "" + +#. Page page +#: ../../po/../src/dialogs/desktop-properties.cpp:1029 +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:855 +#: ../../po/../src/ui/dialog/document-preferences.cpp:88 +#: ../../po/../src/widgets/desktop-widget.cpp:1061 +msgid "Page" +msgstr "Səhifə" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1039 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +#, fuzzy +msgid "Background:" +msgstr "Son rəngi" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1040 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +#, fuzzy +msgid "Background color" +msgstr "Son rəngi" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1041 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +msgid "" +"Color and transparency of the page background (also used for bitmap export)" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1045 +#: ../../po/../src/ui/dialog/document-preferences.cpp:147 +#, fuzzy +msgid "Show page border" +msgstr "Vasitə Qutusunu Göstər" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1049 +#: ../../po/../src/ui/dialog/document-preferences.cpp:148 +#, fuzzy +msgid "Border on top of drawing" +msgstr "Çəkilişə yaxınlaşdır" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1052 +#: ../../po/../src/ui/dialog/document-preferences.cpp:149 +#, fuzzy +msgid "Border color:" +msgstr "Son rəngi" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1053 +#: ../../po/../src/ui/dialog/document-preferences.cpp:149 +#, fuzzy +msgid "Page border color" +msgstr "Son rəngi" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1054 +#: ../../po/../src/ui/dialog/document-preferences.cpp:150 +#, fuzzy +msgid "Color of the page border" +msgstr "Vasitə Qutusunu Göstər" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1059 +#: ../../po/../src/ui/dialog/document-preferences.cpp:152 +msgid "Show page shadow" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1063 +#: ../../po/../src/ui/dialog/document-preferences.cpp:153 +#, fuzzy +msgid "Default units:" +msgstr "Sil" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1069 +msgid "Units for the tool controls, ruler, and the statusbar" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1086 +#: ../../po/../src/ui/widget/page-sizer.cpp:209 +#, fuzzy +msgid "Page size:" +msgstr "Kağız böyüklüyü:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1110 +#: ../../po/../src/ui/widget/page-sizer.cpp:219 +msgid "Custom" +msgstr "Xüsusi" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1121 +#: ../../po/../src/ui/widget/page-sizer.cpp:225 +#, fuzzy +msgid "Page orientation:" +msgstr "Doyğunluq:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1133 +#: ../../po/../src/ui/widget/page-sizer.cpp:232 +#, fuzzy +msgid "Landscape" +msgstr "Sodipodi" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1139 +#: ../../po/../src/ui/widget/page-sizer.cpp:234 +#, fuzzy +msgid "Portrait" +msgstr "Nöqtə" + +#. Custom paper frame +#: ../../po/../src/dialogs/desktop-properties.cpp:1148 +#: ../../po/../src/ui/widget/page-sizer.cpp:249 +#, fuzzy +msgid "Custom size" +msgstr "Xüsusi" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1160 +#: ../../po/../src/dialogs/export.cpp:269 +#: ../../po/../src/ui/widget/page-sizer.cpp:261 +msgid "Units:" +msgstr "" + +#. Stroke width +#: ../../po/../src/dialogs/desktop-properties.cpp:1162 +#: ../../po/../src/dialogs/export.cpp:310 +#: ../../po/../src/dialogs/object-attributes.cpp:55 +#: ../../po/../src/dialogs/stroke-style.cpp:985 +#: ../../po/../src/ui/widget/page-sizer.cpp:262 +#: ../../po/../src/widgets/toolbox.cpp:1957 +msgid "Width:" +msgstr "En:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1183 +#: ../../po/../src/dialogs/export.cpp:326 +#: ../../po/../src/dialogs/export.cpp:431 +#: ../../po/../src/dialogs/object-attributes.cpp:56 +#: ../../po/../src/ui/widget/page-sizer.cpp:263 +msgid "Height:" +msgstr "Hündürlük:" + +#. +#. * Ownership metadata tab +#. +#: ../../po/../src/dialogs/desktop-properties.cpp:1206 +msgid "Metadata" +msgstr "" + +#. add license selector pull-down +#: ../../po/../src/dialogs/desktop-properties.cpp:1225 +#, fuzzy +msgid "License" +msgstr "inç" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1255 +msgid "Proprietary" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:212 +#, fuzzy +msgid "When transforming, show:" +msgstr "Dönüşdürməni sıfırla" + +#: ../../po/../src/dialogs/display-settings.cpp:223 +#, fuzzy +msgid "Objects" +msgstr "Cism" + +#: ../../po/../src/dialogs/display-settings.cpp:224 +msgid "Show the actual objects when moving or transforming" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:231 +msgid "Box outline" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:232 +msgid "Show only a box outline of the objects when moving or transforming" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:238 +msgid "Per-object selection cue:" +msgstr "" + +#. sorationsnapsperpi == 0 means no snapping +#: ../../po/../src/dialogs/display-settings.cpp:249 +#: ../../po/../src/dialogs/display-settings.cpp:386 +#: ../../po/../src/dialogs/display-settings.cpp:441 +#: ../../po/../src/dialogs/display-settings.cpp:1482 +#: ../../po/../src/dialogs/stroke-style.cpp:791 +#: ../../po/../src/interface.cpp:741 +#: ../../po/../src/ui/widget/selected-style.cpp:100 +#: ../../po/../src/verbs.cpp:1842 +msgid "None" +msgstr "Heç biri" + +#: ../../po/../src/dialogs/display-settings.cpp:250 +msgid "No per-object selection indication" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:256 +msgid "Mark" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:257 +msgid "Each selected object has a diamond mark in the top left corner" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:264 +msgid "Box" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:265 +msgid "Each selected object displays its bounding box" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:270 +msgid "Default scale origin:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:281 +#, fuzzy +msgid "Opposite bounding box edge" +msgstr "Kənarları Aç" + +#: ../../po/../src/dialogs/display-settings.cpp:282 +msgid "Default scale origin will be on the bounding box of the item" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:288 +msgid "Farthest opposite node" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:289 +msgid "Default scale origin will be on the bounding box of the item's points" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:341 +#, fuzzy +msgid "degrees" +msgstr "dər" + +#: ../../po/../src/dialogs/display-settings.cpp:350 +msgid "" +"Rotating with Ctrl pressed snaps every that much degrees; also, pressing " +"[ or ] rotates by this amount" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:407 +msgid "Rotation snaps every:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:430 +msgid "" +"None: dialogs are treated as regular windows; Normal: dialogs stay on top of " +"document windows; Aggressive: same as Normal but may work better with some " +"window managers." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:451 +msgid "Normal" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:461 +msgid "Aggressive" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:475 +msgid "Dialogs on top:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:645 +#, fuzzy +msgid "Show selection cue" +msgstr "Seçkini bir lay alçalt" + +#: ../../po/../src/dialogs/display-settings.cpp:646 +msgid "" +"Whether selected objects display a selection cue (the same as in selector)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:657 +msgid "Enable gradient editing" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:658 +msgid "Whether selected objects display gradient editing controls" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:719 +#, fuzzy +msgid "No objects selected to take the style from." +msgstr "seçkini aşağıya çək" + +#: ../../po/../src/dialogs/display-settings.cpp:728 +msgid "" +"More than one object selected. Cannot take style from multiple " +"objects." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:767 +#, fuzzy +msgid "Create new objects with:" +msgstr "Atribut əlavə et" + +#: ../../po/../src/dialogs/display-settings.cpp:777 +#, fuzzy +msgid "Take from selection" +msgstr "Seçkini döndər" + +#: ../../po/../src/dialogs/display-settings.cpp:778 +msgid "Remember the style of the (first) selected object as this tool's style" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:782 +#, fuzzy +msgid "Last used style" +msgstr "Yapışdır" + +#: ../../po/../src/dialogs/display-settings.cpp:782 +msgid "Apply the style you last set on an object" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:790 +msgid "This tool's own style:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:790 +msgid "" +"Each tool may store its own style to apply to the newly created objects. Use " +"the button below to set it." +msgstr "" + +#. Mouse +#: ../../po/../src/dialogs/display-settings.cpp:877 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:55 +#, fuzzy +msgid "Mouse" +msgstr "Daşı" + +#. TRANSLATORS: "Grab" is a noun here. "Grab sensitivity" is intended to mean how +#. * close on the screen you need to be to an object to be able to grab it with mouse (in +#. * pixels). +#: ../../po/../src/dialogs/display-settings.cpp:883 +#, fuzzy +msgid "Grab sensitivity:" +msgstr "Hassaslaşdır" + +#: ../../po/../src/dialogs/display-settings.cpp:884 +msgid "" +"How close on the screen you need to be to an object to be able to grab it " +"with mouse (in screen pixels)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:885 +#: ../../po/../src/dialogs/display-settings.cpp:897 +#: ../../po/../src/dialogs/display-settings.cpp:912 +#: ../../po/../src/dialogs/display-settings.cpp:930 +#: ../../po/../src/dialogs/display-settings.cpp:970 +msgid "pixels" +msgstr "piksel" + +#: ../../po/../src/dialogs/display-settings.cpp:895 +msgid "Click/drag threshold:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:896 +msgid "" +"Maximum mouse drag (in screen pixels) which is considered a click, not a drag" +msgstr "" + +#. Scrolling +#: ../../po/../src/dialogs/display-settings.cpp:907 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:56 +msgid "Scrolling" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:910 +msgid "Mouse wheel scrolls by:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:911 +msgid "" +"One mouse wheel notch scrolls by this distance in screen pixels " +"(horizontally with Shift)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:920 +msgid "Ctrl+arrows" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:928 +msgid "Scroll by:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:929 +msgid "Pressing Ctrl+arrow key scrolls by this distance (in screen pixels)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:939 +#, fuzzy +msgid "Acceleration:" +msgstr "Seçki" + +#: ../../po/../src/dialogs/display-settings.cpp:940 +msgid "" +"Pressing and holding Ctrl+arrow will gradually speed up scrolling (0 for no " +"acceleration)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:949 +msgid "Autoscrolling" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:957 +#, fuzzy +msgid "Speed:" +msgstr "Qırmızı:" + +#: ../../po/../src/dialogs/display-settings.cpp:958 +msgid "" +"How fast the canvas autoscrolls when you drag beyond canvas edge (0 to turn " +"autoscroll off)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:968 +#: ../../po/../src/ui/dialog/tracedialog.cpp:357 +#: ../../po/../src/ui/dialog/tracedialog.cpp:390 +msgid "Threshold:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:969 +msgid "" +"How far (in screen pixels) you need to be from the canvas edge to trigger " +"autoscroll; positive is outside the canvas, negative is within the canvas" +msgstr "" + +#. Steps +#: ../../po/../src/dialogs/display-settings.cpp:979 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:57 +#, fuzzy +msgid "Steps" +msgstr "Miqyas" + +#: ../../po/../src/dialogs/display-settings.cpp:982 +msgid "Arrow keys move by:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:983 +msgid "" +"Pressing an arrow key moves selected object(s) or node(s) by this distance " +"(in px units)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:984 +#: ../../po/../src/dialogs/display-settings.cpp:995 +#: ../../po/../src/dialogs/display-settings.cpp:1006 +#: ../../po/../src/helper/units.cpp:42 +msgid "px" +msgstr "px" + +#: ../../po/../src/dialogs/display-settings.cpp:993 +msgid "> and < scale by:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:994 +msgid "" +"Pressing > or < scales selection up or down by this increment (in px units)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1004 +msgid "Inset/Outset by:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1005 +msgid "" +"Inset and Outset commands displace the path by this distance (in px units)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1017 +msgid "Compass-like display of angles" +msgstr "" + +#. TRANSLATORS: "positive clockwise" means "increasing in clockwise direction" +#: ../../po/../src/dialogs/display-settings.cpp:1019 +msgid "" +"When on, angles are displayed with 0 at north, 0 to 360 range, positive " +"clockwise; otherwise with 0 at east, -180 to 180 range, positive " +"counterclockwise" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1026 +#, fuzzy +msgid "Zoom in/out by:" +msgstr "Uzaqlaşdır" + +#: ../../po/../src/dialogs/display-settings.cpp:1027 +msgid "" +"Zoom tool click, +/- keys, and middle click zoom in and out by this " +"multiplier" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1028 +#: ../../po/../src/helper/units.cpp:44 +msgid "%" +msgstr "%" + +#. Tools +#: ../../po/../src/dialogs/display-settings.cpp:1037 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:58 +msgid "Tools" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1045 +#, fuzzy +msgid "Selector" +msgstr "Seç" + +#: ../../po/../src/dialogs/display-settings.cpp:1056 +#, fuzzy +msgid "Node" +msgstr "Düyün" + +#: ../../po/../src/dialogs/display-settings.cpp:1064 +#: ../../po/../src/verbs.cpp:2073 +#: ../../po/../src/widgets/desktop-widget.cpp:277 +msgid "Zoom" +msgstr "Yaxınlıq" + +#. The 4 shape tools +#: ../../po/../src/dialogs/display-settings.cpp:1071 +#, fuzzy +msgid "Shapes" +msgstr "Şəkil" + +#: ../../po/../src/dialogs/display-settings.cpp:1079 +#: ../../po/../src/verbs.cpp:2055 +msgid "Rectangle" +msgstr "Düzbucaqlı Dördbucaq" + +#: ../../po/../src/dialogs/display-settings.cpp:1085 +#: ../../po/../src/verbs.cpp:2057 +msgid "Ellipse" +msgstr "Elips" + +#: ../../po/../src/dialogs/display-settings.cpp:1091 +#: ../../po/../src/verbs.cpp:2059 +msgid "Star" +msgstr "Ulduz" + +#: ../../po/../src/dialogs/display-settings.cpp:1097 +#: ../../po/../src/verbs.cpp:2061 +msgid "Spiral" +msgstr "Spiral" + +#: ../../po/../src/dialogs/display-settings.cpp:1111 +#: ../../po/../src/verbs.cpp:2063 +msgid "Pencil" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1114 +msgid "Tolerance:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1115 +msgid "" +"This value affects the amount of smoothing applied to freehand lines; lower " +"values produce more uneven paths with more nodes" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1131 +#: ../../po/../src/verbs.cpp:2065 +#, fuzzy +msgid "Pen" +msgstr "Faiz" + +#: ../../po/../src/dialogs/display-settings.cpp:1140 +#: ../../po/../src/verbs.cpp:2067 +msgid "Calligraphy" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1147 +#: ../../po/../src/dialogs/text-edit.cpp:353 +#: ../../po/../src/ui/dialog/text-properties.cpp:37 +#: ../../po/../src/verbs.cpp:2069 +msgid "Text" +msgstr "Mətn" + +#: ../../po/../src/dialogs/display-settings.cpp:1157 +#: ../../po/../src/verbs.cpp:2071 +#, fuzzy +msgid "Gradient" +msgstr "Yaşıl:" + +#: ../../po/../src/dialogs/display-settings.cpp:1164 +#: ../../po/../src/verbs.cpp:2077 +#, fuzzy +msgid "Connector" +msgstr "Yeni Görünüş" + +#: ../../po/../src/dialogs/display-settings.cpp:1171 +#: ../../po/../src/verbs.cpp:2075 +msgid "Dropper" +msgstr "" + +#. Windows +#: ../../po/../src/dialogs/display-settings.cpp:1183 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:59 +#, fuzzy +msgid "Windows" +msgstr "pəncərə1" + +#: ../../po/../src/dialogs/display-settings.cpp:1188 +#, fuzzy +msgid "Save window geometry" +msgstr "Sənəd" + +#: ../../po/../src/dialogs/display-settings.cpp:1189 +msgid "" +"Save the window size and position with each document (only for Inkscape SVG " +"format)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1196 +msgid "Dialogs are hidden in taskbar" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1197 +msgid "Whether dialog windows are to be hidden in the window manager taskbar" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1204 +msgid "Zoom when window is resized" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1205 +msgid "" +"Zoom drawing when document window is resized, to keep the same area visible " +"(this is the default which can be changed in any window using the button " +"above the right scrollbar)" +msgstr "" + +#. Clones +#: ../../po/../src/dialogs/display-settings.cpp:1213 +#: ../../po/../src/dialogs/find.cpp:624 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:60 +#, fuzzy +msgid "Clones" +msgstr "Yeni Görünüş" + +#: ../../po/../src/dialogs/display-settings.cpp:1217 +msgid "When the original moves, its clones and linked offsets:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1229 +msgid "Move in parallel" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1230 +msgid "Clones are translated by the same vector as their original." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1237 +msgid "Stay unmoved" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1238 +msgid "Clones preserve their positions when their original is moved." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1245 +msgid "Move according to transform" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1246 +msgid "" +"Each clone moves according to the value of its transform= attribute. For " +"example, a rotated clone will move in a different direction than its " +"original." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1255 +msgid "When the original is deleted, its clones:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1267 +msgid "Are unlinked" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1267 +msgid "Orphaned clones are converted to regular objects." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1273 +#, fuzzy +msgid "Are deleted" +msgstr "Seç" + +#: ../../po/../src/dialogs/display-settings.cpp:1273 +msgid "Orphaned clones are deleted along with their original." +msgstr "" + +#. Transforms +#. TRANSLATORS: Noun, i.e. transformations. +#: ../../po/../src/dialogs/display-settings.cpp:1289 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:61 +#, fuzzy +msgid "Transforms" +msgstr "Dəyişdirmə" + +#: ../../po/../src/dialogs/display-settings.cpp:1292 +#, fuzzy +msgid "Scale stroke width" +msgstr "Nöqtə" + +#: ../../po/../src/dialogs/display-settings.cpp:1293 +#: ../../po/../src/widgets/select-toolbar.cpp:568 +msgid "When scaling objects, scale the stroke width by the same proportion" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1300 +msgid "Scale rounded corners in rectangles" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1301 +#: ../../po/../src/widgets/select-toolbar.cpp:580 +msgid "When scaling rectangles, scale the radii of rounded corners" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1308 +#, fuzzy +msgid "Transform gradients" +msgstr "Dəyişdirmə" + +#: ../../po/../src/dialogs/display-settings.cpp:1309 +#: ../../po/../src/widgets/select-toolbar.cpp:592 +msgid "Transform gradients (in fill or stroke) along with the objects" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1316 +#, fuzzy +msgid "Transform patterns" +msgstr "Dəyişdirmə" + +#: ../../po/../src/dialogs/display-settings.cpp:1317 +#: ../../po/../src/widgets/select-toolbar.cpp:604 +msgid "Transform patterns (in fill or stroke) along with the objects" +msgstr "" + +#. TRANSLATORS: How to specify the affine transformation in the SVG file. +#: ../../po/../src/dialogs/display-settings.cpp:1327 +#, fuzzy +msgid "Store transformation:" +msgstr "Dönüşdürməni sıfırla" + +#: ../../po/../src/dialogs/display-settings.cpp:1338 +msgid "Optimized" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1339 +msgid "" +"If possible, apply transformation to objects without adding a transform= " +"attribute" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1346 +msgid "Preserved" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1347 +msgid "Always store transformation as a transform= attribute on objects" +msgstr "" + +#. Selecting +#: ../../po/../src/dialogs/display-settings.cpp:1355 +#, fuzzy +msgid "Selecting" +msgstr "Seçki" + +#: ../../po/../src/dialogs/display-settings.cpp:1357 +msgid "Ctrl+A, Tab, Shift+Tab:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1366 +#, fuzzy +msgid "Select only within current layer" +msgstr "Seç" + +#: ../../po/../src/dialogs/display-settings.cpp:1367 +msgid "" +"Uncheck this to make keyboard selection commands work on objects in all " +"layers" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1374 +msgid "Ignore hidden objects" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1375 +msgid "" +"Uncheck this to be able to select objects that are hidden (either by " +"themselves or by being in a hidden group or layer)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1382 +#, fuzzy +msgid "Ignore locked objects" +msgstr "Seçili cismləri qruplaşdır" + +#: ../../po/../src/dialogs/display-settings.cpp:1383 +msgid "" +"Uncheck this to be able to select objects that are locked (either by " +"themselves or by being in a locked group or layer)" +msgstr "" + +#. To be broken into: Display, Save, Export, SVG, Commands +#: ../../po/../src/dialogs/display-settings.cpp:1391 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:62 +msgid "Misc" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1394 +msgid "Default export resolution:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1395 +msgid "Default bitmap resolution (in dots per inch) in the Export dialog" +msgstr "" + +#. FIXME: add "Used for new exports; once exported, documents remember this value on per-object basis" when implemented +#: ../../po/../src/dialogs/display-settings.cpp:1396 +#: ../../po/../src/dialogs/export.cpp:442 +msgid "dpi" +msgstr "dpi" + +#. TRANSLATORS: When on, an imported bitmap creates an element; otherwise it is a +#. * rectangle with bitmap fill. +#: ../../po/../src/dialogs/display-settings.cpp:1407 +msgid "Import bitmap as " +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1408 +msgid "" +"When on, an imported bitmap creates an element; otherwise it is a " +"rectangle with bitmap fill" +msgstr "" + +#. TRANSLATORS: When on, the print out (currently Postscript) will have +#. * a comment with the each object's label visible, marking the section +#. * of the printing commands that represent the given object. +#: ../../po/../src/dialogs/display-settings.cpp:1418 +msgid "Add label comments to printing output" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1419 +msgid "" +"When on, a comment will be added to the raw print output, marking the " +"rendered output for an object with its label" +msgstr "" + +#. TRANSLATORS: When on, enable the effects menu, default is off +#: ../../po/../src/dialogs/display-settings.cpp:1427 +msgid "Enable script effects (requires restart) - EXPERIMENTAL" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1428 +msgid "" +"When on, the effects menu is enabled, allowing external effect scripts to be " +"called, requires restart before effective - EXPERIMENTAL" +msgstr "" + +#. TRANSLATORS: The maximum length of the Open Recent list in the File menu. +#: ../../po/../src/dialogs/display-settings.cpp:1436 +#, fuzzy +msgid "Max recent documents:" +msgstr "Sənəd" + +#: ../../po/../src/dialogs/display-settings.cpp:1437 +msgid "The maximum length of the Open Recent list in the File menu" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1447 +msgid "Simplification threshold:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1448 +msgid "" +"How strong is the Simplify command by default. If you invoke this command " +"several times in quick succession, it will act more and more aggressively; " +"invoking it again after a pause restores the default threshold." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1469 +msgid "Oversample bitmaps:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1488 +msgid "2x2" +msgstr "2x2" + +#: ../../po/../src/dialogs/display-settings.cpp:1494 +msgid "4x4" +msgstr "4x4" + +#: ../../po/../src/dialogs/display-settings.cpp:1500 +msgid "8x8" +msgstr "8x8" + +#: ../../po/../src/dialogs/display-settings.cpp:1506 +msgid "16x16" +msgstr "16x16" + +#. "view_icon_preview" +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2143 +msgid "_Page" +msgstr "_Səhifə" + +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2147 +msgid "_Drawing" +msgstr "Çək_mə" + +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2149 +msgid "_Selection" +msgstr "_Seçki" + +#: ../../po/../src/dialogs/export.cpp:133 +#, fuzzy +msgid "_Custom" +msgstr "Xüsusi" + +#: ../../po/../src/dialogs/export.cpp:254 +#, fuzzy +msgid "Export area" +msgstr "Fayl ver" + +#: ../../po/../src/dialogs/export.cpp:300 +msgid "_x0:" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:305 +#, fuzzy +msgid "x_1:" +msgstr "1:1" + +#: ../../po/../src/dialogs/export.cpp:316 +msgid "_y0:" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:321 +#, fuzzy +msgid "y_1:" +msgstr "1:1" + +#: ../../po/../src/dialogs/export.cpp:406 +#, fuzzy +msgid "Bitmap size" +msgstr "Kağız böyüklüyü:" + +#: ../../po/../src/dialogs/export.cpp:416 +#, fuzzy +msgid "_Width:" +msgstr "En:" + +#: ../../po/../src/dialogs/export.cpp:416 +#: ../../po/../src/dialogs/export.cpp:431 +#, fuzzy +msgid "pixels at" +msgstr "piksel" + +#: ../../po/../src/dialogs/export.cpp:426 +#, fuzzy +msgid "dp_i" +msgstr "dpi" + +#: ../../po/../src/dialogs/export.cpp:448 +#, fuzzy +msgid "_Filename" +msgstr "Fayl adı:" + +#: ../../po/../src/dialogs/export.cpp:512 +msgid "_Browse..." +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:539 +#, fuzzy +msgid " _Export " +msgstr "Düzbucaqlı Dördbucaq" + +#: ../../po/../src/dialogs/export.cpp:541 +msgid "Export the bitmap file with these settings" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:968 +#, fuzzy +msgid "You have to enter a filename" +msgstr "Çəkilişi yeni ad altında qeyd et" + +#: ../../po/../src/dialogs/export.cpp:973 +msgid "The chosen area to be exported is invalid" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:982 +#, c-format +msgid "Directory %s does not exist or is not a directory.\n" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:998 +#, fuzzy +msgid "Export in progress" +msgstr "Fayl ver" + +#: ../../po/../src/dialogs/export.cpp:1004 +#, c-format +msgid "Exporting %s (%d x %d)" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:1031 +#, c-format +msgid "Could not export to filename %s.\n" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:1137 +#, fuzzy +msgid "Select a filename for exporting" +msgstr "Alınacaq faylı seç" + +#: ../../po/../src/dialogs/filedialog.cpp:367 +#, fuzzy +msgid "No preview" +msgstr "Yeni Nümayiş" + +#: ../../po/../src/dialogs/filedialog.cpp:468 +msgid "too large for preview" +msgstr "" + +#: ../../po/../src/dialogs/filedialog.cpp:762 +#: ../../po/../src/dialogs/filedialog.cpp:763 +#, fuzzy +msgid "All Images" +msgstr "Səhifə" + +#: ../../po/../src/dialogs/filedialog.cpp:767 +#: ../../po/../src/dialogs/filedialog.cpp:768 +#, fuzzy +msgid "All Files" +msgstr "Doldurma qurğuları" + +#: ../../po/../src/dialogs/filedialog.cpp:774 +#: ../../po/../src/dialogs/filedialog.cpp:775 +#, fuzzy +msgid "All Inkscape Files" +msgstr "Sodipodi" + +#: ../../po/../src/dialogs/filedialog.cpp:1176 +#, fuzzy +msgid "Guess from extension" +msgstr "Seçkini döndər" + +#. ###### Add the file types menu +#. createFilterMenu(); +#. ###### Do we want the .xxx extension automatically added? +#: ../../po/../src/dialogs/filedialog.cpp:1261 +msgid "Append filename extension automatically" +msgstr "" + +#. TRANSLATORS: "%s" is replaced with "exact" or "partial" when this string is displayed +#: ../../po/../src/dialogs/find.cpp:378 +#, fuzzy, c-format +msgid "%d object found (out of %d), %s match." +msgid_plural "%d objects found (out of %d), %s match." +msgstr[0] "Seçili cığırları kombinə et" +msgstr[1] "Seçili cığırları kombinə et" + +#: ../../po/../src/dialogs/find.cpp:381 +#, fuzzy +msgid "exact" +msgstr "Mətn" + +#: ../../po/../src/dialogs/find.cpp:381 +#, fuzzy +msgid "partial" +msgstr "Spiral" + +#: ../../po/../src/dialogs/find.cpp:388 +#, fuzzy +msgid "No objects found" +msgstr "Mətn cismi" + +#: ../../po/../src/dialogs/find.cpp:546 +msgid "T_ype: " +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:553 +msgid "Search in all object types" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:553 +#, fuzzy +msgid "All types" +msgstr "Doldurma qurğuları" + +#: ../../po/../src/dialogs/find.cpp:564 +msgid "Search all shapes" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:564 +msgid "All shapes" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:581 +#, fuzzy +msgid "Search rectangles" +msgstr "Düzbucaqlı Dördbucaq" + +#: ../../po/../src/dialogs/find.cpp:581 +#, fuzzy +msgid "Rectangles" +msgstr "Düzbucaqlı Dördbucaq" + +#: ../../po/../src/dialogs/find.cpp:586 +msgid "Search ellipses, arcs, circles" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:586 +#, fuzzy +msgid "Ellipses" +msgstr "Elips" + +#: ../../po/../src/dialogs/find.cpp:591 +msgid "Search stars and polygons" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:591 +#, fuzzy +msgid "Stars" +msgstr "Ulduz" + +#: ../../po/../src/dialogs/find.cpp:596 +#, fuzzy +msgid "Search spirals" +msgstr "Spiral çək" + +#: ../../po/../src/dialogs/find.cpp:596 +#, fuzzy +msgid "Spirals" +msgstr "Spiral" + +#. TRANSLATORS: polyline is a set of connected straight line segments +#. http://www.w3.org/TR/SVG11/shapes.html#PolylineElement +#: ../../po/../src/dialogs/find.cpp:609 +msgid "Search paths, lines, polylines" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:609 +msgid "Paths" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:614 +#, fuzzy +msgid "Search text objects" +msgstr "Seçili cismləri qruplaşdır" + +#: ../../po/../src/dialogs/find.cpp:614 +#, fuzzy +msgid "Texts" +msgstr "Mətn" + +#: ../../po/../src/dialogs/find.cpp:619 +msgid "Search groups" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:619 +#, fuzzy +msgid "Groups" +msgstr "Qrup" + +#: ../../po/../src/dialogs/find.cpp:624 +msgid "Search clones" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:629 +msgid "Search images" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:629 +#, fuzzy +msgid "Images" +msgstr "Səhifə" + +#: ../../po/../src/dialogs/find.cpp:634 +#, fuzzy +msgid "Search offset objects" +msgstr "Seçili cismləri qruplaşdır" + +#: ../../po/../src/dialogs/find.cpp:634 +msgid "Offsets" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:694 +#, fuzzy +msgid "_Text: " +msgstr "Mətn" + +#: ../../po/../src/dialogs/find.cpp:694 +msgid "Find objects by their text content (exact or partial match)" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:695 +msgid "_ID: " +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:695 +msgid "Find objects by the value of the id attribute (exact or partial match)" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:696 +#, fuzzy +msgid "_Style: " +msgstr "Miqyas" + +#: ../../po/../src/dialogs/find.cpp:696 +msgid "" +"Find objects by the value of the style attribute (exact or partial match)" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:697 +#, fuzzy +msgid "_Attribute: " +msgstr "Atribut:" + +#: ../../po/../src/dialogs/find.cpp:697 +msgid "Find objects by the name of an attribute (exact or partial match)" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:711 +#, fuzzy +msgid "Search in s_election" +msgstr "Seçkiyə yaxınlaşdır" + +#: ../../po/../src/dialogs/find.cpp:715 +msgid "Limit search to the current selection" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:720 +#, fuzzy +msgid "Search in current _layer" +msgstr "Seç" + +#: ../../po/../src/dialogs/find.cpp:724 +#, fuzzy +msgid "Limit search to the current layer" +msgstr "Seç" + +#: ../../po/../src/dialogs/find.cpp:729 +msgid "Include _hidden" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:733 +msgid "Include hidden objects in search" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:738 +msgid "Include l_ocked" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:742 +#, fuzzy +msgid "Include locked objects in search" +msgstr "Seçili cismləri qruplaşdır" + +#: ../../po/../src/dialogs/find.cpp:753 +msgid "Clear values" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:754 +#, fuzzy +msgid "_Find" +msgstr "Qəfəs" + +#: ../../po/../src/dialogs/find.cpp:754 +msgid "Select objects matching all of the fields you filled in" +msgstr "" + +#: ../../po/../src/dialogs/iconpreview.cpp:145 +#, c-format +msgid "%d x %d" +msgstr "" + +#: ../../po/../src/dialogs/iconpreview.cpp:193 +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:857 +#: ../../po/../src/widgets/desktop-widget.cpp:1069 +msgid "Selection" +msgstr "Seçki" + +#: ../../po/../src/dialogs/iconpreview.cpp:195 +#, fuzzy +msgid "Selection only or whole document" +msgstr "Seç" + +#: ../../po/../src/dialogs/iconpreview.cpp:203 +msgid "Refresh the icons" +msgstr "" + +#. Create the label for the object id +#: ../../po/../src/dialogs/item-properties.cpp:126 +#: ../../po/../src/dialogs/item-properties.cpp:327 +#: ../../po/../src/dialogs/item-properties.cpp:396 +#: ../../po/../src/dialogs/item-properties.cpp:403 +msgid "_Id" +msgstr "" + +#: ../../po/../src/dialogs/item-properties.cpp:135 +msgid "" +"The id= attribute (only letters, digits, and the characters .-_: allowed)" +msgstr "" + +#. Button for setting the object's id, label, title and description. +#: ../../po/../src/dialogs/item-properties.cpp:149 +#, fuzzy +msgid "_Set" +msgstr "Seç" + +#. Create the label for the object label +#: ../../po/../src/dialogs/item-properties.cpp:158 +#, fuzzy +msgid "_Label" +msgstr "Atributu sil" + +#: ../../po/../src/dialogs/item-properties.cpp:167 +msgid "A freeform label for the object" +msgstr "" + +#. Create the label for the object title +#: ../../po/../src/dialogs/item-properties.cpp:179 +#: ../../po/../src/dialogs/rdf.cpp:243 +#, fuzzy +msgid "Title" +msgstr "Fayl" + +#. Create the frame for the object description +#: ../../po/../src/dialogs/item-properties.cpp:196 +#: ../../po/../src/dialogs/rdf.cpp:287 +#, fuzzy +msgid "Description" +msgstr "Yer" + +#. Hide +#: ../../po/../src/dialogs/item-properties.cpp:223 +#, fuzzy +msgid "_Hide" +msgstr "Qəfəs" + +#: ../../po/../src/dialogs/item-properties.cpp:224 +msgid "Check to make the object invisible" +msgstr "" + +#. Lock +#. TRANSLATORS: "Lock" is a verb here +#: ../../po/../src/dialogs/item-properties.cpp:233 +msgid "L_ock" +msgstr "" + +#: ../../po/../src/dialogs/item-properties.cpp:234 +msgid "Check to make the object insensitive (not selectable by mouse)" +msgstr "" + +#: ../../po/../src/dialogs/item-properties.cpp:310 +#: ../../po/../src/dialogs/item-properties.cpp:317 +msgid "Ref" +msgstr "" + +#: ../../po/../src/dialogs/item-properties.cpp:398 +msgid "Id invalid! " +msgstr "" + +#: ../../po/../src/dialogs/item-properties.cpp:400 +msgid "Id exists! " +msgstr "" + +#: ../../po/../src/dialogs/layer-properties.cpp:50 +msgid "Layer name:" +msgstr "" + +#: ../../po/../src/dialogs/layer-properties.cpp:133 +#, fuzzy +msgid "Rename Layer" +msgstr "Sıfırla" + +#: ../../po/../src/dialogs/layer-properties.cpp:136 +#, fuzzy +msgid "_Rename" +msgstr "Fayl adı:" + +#. TRANSLATORS: This means "The layer has been renamed" +#: ../../po/../src/dialogs/layer-properties.cpp:147 +#, fuzzy +msgid "Renamed layer" +msgstr "Sıfırla" + +#: ../../po/../src/dialogs/layer-properties.cpp:151 +#, fuzzy +msgid "Add Layer" +msgstr "Seç" + +#: ../../po/../src/dialogs/layer-properties.cpp:153 +#, fuzzy +msgid "_Add" +msgstr "Əlavə Et" + +#: ../../po/../src/dialogs/layer-properties.cpp:167 +msgid "New layer created." +msgstr "" + +#: ../../po/../src/dialogs/object-attributes.cpp:34 +#, fuzzy +msgid "Href:" +msgstr "Çöhrə:" + +#: ../../po/../src/dialogs/object-attributes.cpp:35 +msgid "Target:" +msgstr "" + +#: ../../po/../src/dialogs/object-attributes.cpp:36 +msgid "Type:" +msgstr "" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkRoleAttribute +#. Identifies the type of the related resource with an absolute URI +#: ../../po/../src/dialogs/object-attributes.cpp:39 +#, fuzzy +msgid "Role:" +msgstr "Qırmızı:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkArcRoleAttribute +#. For situations where the nature/role alone isn't enough, this offers an additional URI defining the purpose of the link. +#: ../../po/../src/dialogs/object-attributes.cpp:42 +msgid "Arcrole:" +msgstr "" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkTitleAttribute +#: ../../po/../src/dialogs/object-attributes.cpp:44 +#, fuzzy +msgid "Title:" +msgstr "Fayl" + +#: ../../po/../src/dialogs/object-attributes.cpp:45 +msgid "Show:" +msgstr "" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkActuateAttribute +#: ../../po/../src/dialogs/object-attributes.cpp:47 +#, fuzzy +msgid "Actuate:" +msgstr "Atribut:" + +#: ../../po/../src/dialogs/object-attributes.cpp:52 +msgid "URL:" +msgstr "" + +#: ../../po/../src/dialogs/object-attributes.cpp:53 +msgid "X:" +msgstr "X:" + +#: ../../po/../src/dialogs/object-attributes.cpp:54 +msgid "Y:" +msgstr "Y:" + +#: ../../po/../src/dialogs/object-attributes.cpp:98 +#, fuzzy, c-format +msgid "%s attributes" +msgstr "Atributlar" + +#: ../../po/../src/dialogs/object-properties.cpp:158 +#, fuzzy +msgid "_Fill" +msgstr "Doldur" + +#: ../../po/../src/dialogs/object-properties.cpp:165 +#, fuzzy +msgid "Stroke _paint" +msgstr "Nöqtə" + +#: ../../po/../src/dialogs/object-properties.cpp:172 +#, fuzzy +msgid "Stroke st_yle" +msgstr "Doldurma qurğuları" + +#: ../../po/../src/dialogs/object-properties.cpp:183 +#, fuzzy +msgid "Master _opacity" +msgstr "Şəffaflıq:" + +#: ../../po/../src/dialogs/rdf.cpp:244 +msgid "Name by which this document is formally known." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:246 +#, fuzzy +msgid "Date" +msgstr "Mətn çək" + +#: ../../po/../src/dialogs/rdf.cpp:247 +msgid "Date associated with the creation of this document (YYYY-MM-DD)." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:249 +msgid "Format" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:250 +msgid "The physical or digital manifestation of this document (MIME type)." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:252 +msgid "Type" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:253 +msgid "Type of document (DCMI Type)." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:256 +#, fuzzy +msgid "Creator" +msgstr "Körpü yarat" + +#: ../../po/../src/dialogs/rdf.cpp:257 +msgid "" +"Name of entity primarily responsible for making the content of this document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:259 +#, fuzzy +msgid "Rights" +msgstr "Hündürlük" + +#: ../../po/../src/dialogs/rdf.cpp:260 +msgid "" +"Name of entity with rights to the Intellectual Property of this document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:262 +msgid "Publisher" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:263 +msgid "Name of entity responsible for making this document available." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:266 +#, fuzzy +msgid "Identifier" +msgstr "Orta" + +#: ../../po/../src/dialogs/rdf.cpp:267 +msgid "Unique URI to reference this document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:269 +msgid "Source" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:270 +msgid "Unique URI to reference the source of this document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:272 +#, fuzzy +msgid "Relation" +msgstr "Seçki" + +#: ../../po/../src/dialogs/rdf.cpp:273 +msgid "Unique URI to a related document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:275 +#, fuzzy +msgid "Language" +msgstr "bucaq" + +#: ../../po/../src/dialogs/rdf.cpp:276 +msgid "" +"Two-letter language tag with optional subtags for the language of this " +"document. (e.g. 'en-GB')" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:278 +msgid "Keywords" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:279 +msgid "" +"The topic of this document as comma-separated key words, phrases, or " +"classifications." +msgstr "" + +#. TRANSLATORS: "Coverage": the spatial or temporal characteristics of the content. +#. For info, see Appendix D of http://www.w3.org/TR/1998/WD-rdf-schema-19980409/ +#: ../../po/../src/dialogs/rdf.cpp:283 +msgid "Coverage" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:284 +msgid "Extent or scope of this document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:288 +msgid "A short account of the content of this document." +msgstr "" + +#. FIXME: need to handle 1 agent per line of input +#: ../../po/../src/dialogs/rdf.cpp:292 +#, fuzzy +msgid "Contributors" +msgstr "Sentimetr" + +#: ../../po/../src/dialogs/rdf.cpp:293 +msgid "" +"Names of entities responsible for making contributions to the content of " +"this document." +msgstr "" + +#. TRANSLATORS: URL to a page that defines the license for the document +#: ../../po/../src/dialogs/rdf.cpp:297 +msgid "URI" +msgstr "" + +#. TRANSLATORS: this is where you put a URL to a page that defines the license +#: ../../po/../src/dialogs/rdf.cpp:299 +msgid "URI to this document's license's namespace definition." +msgstr "" + +#. TRANSLATORS: fragment of XML representing the license of the document +#: ../../po/../src/dialogs/rdf.cpp:303 +msgid "Fragment" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:304 +msgid "XML fragment for the RDF 'License' section." +msgstr "" + +#: ../../po/../src/dialogs/stroke-style.cpp:774 +#: ../../po/../src/widgets/gradient-vector.cpp:263 +#: ../../po/../src/widgets/paint-selector.cpp:751 +msgid "No document selected" +msgstr "" + +#: ../../po/../src/dialogs/stroke-style.cpp:992 +#, fuzzy +msgid "Stroke width" +msgstr "Nöqtə" + +#. Join type +#. TRANSLATORS: The line join style specifies the shape to be used at the +#. corners of paths. It can be "miter", "round" or "bevel". +#: ../../po/../src/dialogs/stroke-style.cpp:1015 +msgid "Join:" +msgstr "" + +#. TRANSLATORS: Miter join: joining lines with a sharp (pointed) corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1027 +msgid "Miter join" +msgstr "" + +#. TRANSLATORS: Round join: joining lines with a rounded corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1035 +msgid "Round join" +msgstr "" + +#. TRANSLATORS: Bevel join: joining lines with a blunted (flattened) corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1043 +msgid "Bevel join" +msgstr "" + +#. Miterlimit +#. TRANSLATORS: Miter limit: only for "miter join", this limits the length +#. of the sharp "spike" when the lines connect at too sharp an angle. +#. When two line segments meet at a sharp angle, a miter join results in a +#. spike that extends well beyond the connection point. The purpose of the +#. miter limit is to cut off such spikes (i.e. convert them into bevels) +#. when they become too long. +#: ../../po/../src/dialogs/stroke-style.cpp:1054 +msgid "Miter limit:" +msgstr "" + +#: ../../po/../src/dialogs/stroke-style.cpp:1062 +msgid "Maximum length of the miter (in units of stroke width)" +msgstr "" + +#. Cap type +#. TRANSLATORS: cap type specifies the shape for the ends of lines +#: ../../po/../src/dialogs/stroke-style.cpp:1075 +msgid "Cap:" +msgstr "" + +#. TRANSLATORS: Butt cap: the line shape does not extend beyond the end point +#. of the line; the ends of the line are square +#: ../../po/../src/dialogs/stroke-style.cpp:1086 +msgid "Butt cap" +msgstr "" + +#. TRANSLATORS: Round cap: the line shape extends beyond the end point of the +#. line; the ends of the line are rounded +#: ../../po/../src/dialogs/stroke-style.cpp:1093 +msgid "Round cap" +msgstr "" + +#. TRANSLATORS: Square cap: the line shape extends beyond the end point of the +#. line; the ends of the line are square +#: ../../po/../src/dialogs/stroke-style.cpp:1100 +msgid "Square cap" +msgstr "" + +#. Dash +#: ../../po/../src/dialogs/stroke-style.cpp:1106 +msgid "Dashes:" +msgstr "" + +#. TRANSLATORS: Path markers are an SVG feature that allows you to attach arbitrary shapes +#. (arrowheads, bullets, faces, whatever) to the start, end, or middle nodes of a path. +#: ../../po/../src/dialogs/stroke-style.cpp:1127 +#, fuzzy +msgid "Start Markers:" +msgstr "Mətn Xassələri" + +#: ../../po/../src/dialogs/stroke-style.cpp:1137 +msgid "Mid Markers:" +msgstr "" + +#: ../../po/../src/dialogs/stroke-style.cpp:1148 +msgid "End Markers:" +msgstr "" + +#: ../../po/../src/dialogs/swatches.cpp:424 +#, c-format +msgid "Palettes directory (%s) is unavailable." +msgstr "" + +#. TODO: Insert widgets +#: ../../po/../src/dialogs/text-edit.cpp:199 +#: ../../po/../src/ui/dialog/text-properties.cpp:36 +#, fuzzy +msgid "Font" +msgstr "Nöqtə" + +#: ../../po/../src/dialogs/text-edit.cpp:216 +msgid "Layout" +msgstr "Düzülüş" + +#: ../../po/../src/dialogs/text-edit.cpp:229 +msgid "Align lines left" +msgstr "" + +#. TRANSLATORS: `Center' here is a verb. +#: ../../po/../src/dialogs/text-edit.cpp:243 +#, fuzzy +msgid "Center lines" +msgstr "Orta" + +#: ../../po/../src/dialogs/text-edit.cpp:256 +msgid "Align lines right" +msgstr "" + +#: ../../po/../src/dialogs/text-edit.cpp:278 +#, fuzzy +msgid "Horizontal text" +msgstr "üfüqi hərəkət" + +#: ../../po/../src/dialogs/text-edit.cpp:292 +msgid "Vertical text" +msgstr "" + +#: ../../po/../src/dialogs/text-edit.cpp:307 +msgid "Line spacing:" +msgstr "" + +#: ../../po/../src/dialogs/text-edit.cpp:400 +msgid "Set as default" +msgstr "" + +#: ../../po/../src/dialogs/tiledialog.cpp:603 +#, fuzzy +msgid "Rows:" +msgstr "Qırmızı:" + +#: ../../po/../src/dialogs/tiledialog.cpp:613 +msgid "Number of rows" +msgstr "" + +#: ../../po/../src/dialogs/tiledialog.cpp:617 +#, fuzzy +msgid "Equal height" +msgstr "Hündürlük: " + +#: ../../po/../src/dialogs/tiledialog.cpp:627 +msgid "If not set, each row has the height of the tallest object in it" +msgstr "" + +#. #### Radio buttons to control vertical alignment #### +#. #### Radio buttons to control horizontal alignment #### +#: ../../po/../src/dialogs/tiledialog.cpp:637 +#: ../../po/../src/dialogs/tiledialog.cpp:708 +#, fuzzy +msgid "Align:" +msgstr "Tərəflə" + +#: ../../po/../src/dialogs/tiledialog.cpp:672 +msgid " X " +msgstr "" + +#. #### Number of columns #### +#: ../../po/../src/dialogs/tiledialog.cpp:678 +#, fuzzy +msgid "Columns:" +msgstr "Elips" + +#: ../../po/../src/dialogs/tiledialog.cpp:688 +msgid "Number of columns" +msgstr "" + +#: ../../po/../src/dialogs/tiledialog.cpp:692 +#, fuzzy +msgid "Equal width" +msgstr "En:" + +#: ../../po/../src/dialogs/tiledialog.cpp:701 +msgid "If not set, each column has the width of the widest object in it" +msgstr "" + +#. #### Radio buttons to control spacing manually or to fit selection bbox #### +#: ../../po/../src/dialogs/tiledialog.cpp:746 +#, fuzzy +msgid "Fit into selection box" +msgstr "Seçkini kəs" + +#: ../../po/../src/dialogs/tiledialog.cpp:753 +#, fuzzy +msgid "Set spacing:" +msgstr "Nöqtə" + +#. #### Y Padding #### +#: ../../po/../src/dialogs/tiledialog.cpp:777 +#, fuzzy +msgid "Row spacing: " +msgstr "Nöqtə" + +#: ../../po/../src/dialogs/tiledialog.cpp:786 +#, fuzzy +msgid "Vertical spacing between rows" +msgstr "üfüqi hərəkət" + +#. #### X padding #### +#: ../../po/../src/dialogs/tiledialog.cpp:795 +msgid "Column spacing:" +msgstr "" + +#: ../../po/../src/dialogs/tiledialog.cpp:804 +#, fuzzy +msgid "Horizontal spacing between columns" +msgstr "üfüqi hərəkət" + +#: ../../po/../src/dialogs/tiledialog.cpp:818 +#, fuzzy +msgid "Arrange selected objects" +msgstr "Seçili cismləri qruplaşdır" + +#: ../../po/../src/dialogs/xml-tree.cpp:178 +msgid "Click to select nodes, drag to rearrange." +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:189 +msgid "Click attribute to edit." +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:193 +#, c-format +msgid "" +"Attribute %s selected. Press Ctrl+Enter when done editing to " +"commit changes." +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:284 +msgid "Drag to reorder nodes" +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:304 +#, fuzzy +msgid "New element node" +msgstr "Sənəd" + +#: ../../po/../src/dialogs/xml-tree.cpp:326 +msgid "New text node" +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:347 +#, fuzzy +msgid "Duplicate node" +msgstr "Cütləşdir" + +#: ../../po/../src/dialogs/xml-tree.cpp:368 +#, fuzzy +msgid "Delete node" +msgstr "Sil" + +#: ../../po/../src/dialogs/xml-tree.cpp:384 +#, fuzzy +msgid "Unindent node" +msgstr "Düyünləri düzəlt" + +#: ../../po/../src/dialogs/xml-tree.cpp:399 +#, fuzzy +msgid "Indent node" +msgstr "Düyünləri düzəlt" + +#: ../../po/../src/dialogs/xml-tree.cpp:411 +#, fuzzy +msgid "Raise node" +msgstr "Sıfırla" + +#: ../../po/../src/dialogs/xml-tree.cpp:423 +msgid "Lower node" +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:468 +msgid "Delete attribute" +msgstr "Atributu sil" + +#. TRANSLATORS: "Attribute" is a noun here +#: ../../po/../src/dialogs/xml-tree.cpp:513 +#, fuzzy +msgid "Attribute name" +msgstr "Atribut:" + +#. TRANSLATORS: "Set" is a verb here +#: ../../po/../src/dialogs/xml-tree.cpp:533 +#, fuzzy +msgid "Set attribute" +msgstr "Atributu sil" + +#. TRANSLATORS: "Set" is a verb here +#: ../../po/../src/dialogs/xml-tree.cpp:535 +#, fuzzy +msgid "Set" +msgstr "Seç" + +#. TRANSLATORS: "Attribute" is a noun here +#: ../../po/../src/dialogs/xml-tree.cpp:558 +#, fuzzy +msgid "Attribute value" +msgstr "Atributlar" + +#: ../../po/../src/dialogs/xml-tree.cpp:1318 +msgid "New element node..." +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:1339 +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:100 +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:98 +#, fuzzy +msgid "Cancel" +msgstr "Dəyişdir" + +#: ../../po/../src/dialogs/xml-tree.cpp:1345 +#, fuzzy +msgid "Create" +msgstr "Körpü yarat" + +#: ../../po/../src/dialogs/xml-tree.cpp:1458 +#, c-format +msgid "" +"Cannot set %s: Another element with value %s already exists!" +msgstr "" + +#: ../../po/../src/document.cpp:369 +#, fuzzy, c-format +msgid "New document %d" +msgstr "Sənəd" + +#: ../../po/../src/document.cpp:401 +#, c-format +msgid "Memory document %d" +msgstr "" + +#: ../../po/../src/document.cpp:524 +#, c-format +msgid "Unnamed document %d" +msgstr "" + +#. We hit green anchor, closing Green-Blue-Red +#: ../../po/../src/draw-context.cpp:441 +msgid "Path is closed." +msgstr "" + +#. We hit bot start and end of single curve, closing paths +#: ../../po/../src/draw-context.cpp:456 +msgid "Closing path." +msgstr "" + +#. alpha of color under cursor, to show in the statusbar +#. locale-sensitive printf is OK, since this goes to the UI, not into SVG +#: ../../po/../src/dropper-context.cpp:354 +#, c-format +msgid " alpha %.3g" +msgstr "" + +#. where the color is picked, to show in the statusbar +#: ../../po/../src/dropper-context.cpp:356 +#, c-format +msgid ", averaged with radius %d" +msgstr "" + +#: ../../po/../src/dropper-context.cpp:356 +msgid " under cursor" +msgstr "" + +#. message, to show in the statusbar +#: ../../po/../src/dropper-context.cpp:358 +msgid "Release mouse to set color." +msgstr "" + +#: ../../po/../src/dropper-context.cpp:358 +#: ../../po/../src/tools-switch.cpp:207 +msgid "" +"Click to set fill, Shift+click to set stroke; drag to " +"average color in area; with Alt to pick inverse color; Ctrl+C " +"to copy the color under mouse to clipboard" +msgstr "" + +#: ../../po/../src/extension/dependency.cpp:244 +msgid "Dependency::" +msgstr "" + +#: ../../po/../src/extension/dependency.cpp:245 +#, fuzzy +msgid " type: " +msgstr "Doldurma qurğuları" + +#: ../../po/../src/extension/dependency.cpp:246 +#, fuzzy +msgid " location: " +msgstr "Seçki" + +#: ../../po/../src/extension/dependency.cpp:247 +msgid " string: " +msgstr "" + +#: ../../po/../src/extension/dependency.cpp:250 +#, fuzzy +msgid " description: " +msgstr "Yer" + +#. static int i = 0; +#. std::cout << "Checking module[" << i++ << "]: " << name << std::endl; +#: ../../po/../src/extension/extension.cpp:244 +msgid "" +" This is caused by an improper .inx file for this extension. An improper ." +"inx file could have been caused by a faulty installation of Inkscape." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:247 +msgid "an ID was not defined for it." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:251 +msgid "there was no name defined for it." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:255 +msgid "the XML description of it got lost." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:259 +msgid "no implementation was defined for the extension." +msgstr "" + +#. std::cout << "Failed: " << *(_deps[i]) << std::endl; +#: ../../po/../src/extension/extension.cpp:266 +msgid "a dependency was not met." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:286 +msgid "Extension \"" +msgstr "" + +#: ../../po/../src/extension/extension.cpp:286 +msgid "\" failed to load because " +msgstr "" + +#: ../../po/../src/extension/extension.cpp:565 +#, c-format +msgid "Could not create extension error log file '%s'" +msgstr "" + +#. This is some filler text, needs to change before relase +#: ../../po/../src/extension/error-file.cpp:56 +msgid "" +"One or more extensions failed to load\n" +"\n" +"The failed extensions have been skipped. Inkscape will continue to run " +"normally but those extensions will be unavailable. For details to " +"troubleshoot this problem, please refer to the error log located at: " +msgstr "" + +#. This is some filler text, needs to change before relase +#: ../../po/../src/extension/error-file.cpp:65 +msgid "Show dialog on startup" +msgstr "" + +#: ../../po/../src/extension/implementation/script.cpp:845 +msgid "" +"Inkscape has received an error from the script that it called. The text " +"returned with the error is included below. Inkscape will continue working, " +"but the action you requested has been cancelled." +msgstr "" + +#: ../../po/../src/extension/implementation/script.cpp:858 +msgid "" +"Inkscape has received additional data from the script executed. The script " +"did not return an error, but this may indicate the results will not be as " +"expected." +msgstr "" + +#: ../../po/../src/extension/init.cpp:173 +msgid "Null external module directory name. Modules will not be loaded." +msgstr "" + +#: ../../po/../src/extension/init.cpp:187 +#, c-format +msgid "" +"Modules directory (%s) is unavailable. External modules in that directory " +"will not be loaded." +msgstr "" + +#: ../../po/../src/extension/internal/gnome.cpp:80 +#, fuzzy +msgid "Select printer" +msgstr "Seçki" + +#: ../../po/../src/extension/internal/gnome.cpp:131 +#, fuzzy +msgid "Inkscape: Print Preview" +msgstr "Yeni Nümayiş" + +#: ../../po/../src/extension/internal/grid.cpp:213 +#, fuzzy +msgid "Line Width" +msgstr "En" + +#: ../../po/../src/extension/internal/grid.cpp:214 +#, fuzzy +msgid "Horizontal Spacing" +msgstr "üfüqi hərəkət" + +#: ../../po/../src/extension/internal/grid.cpp:215 +msgid "Vertical Spacing" +msgstr "" + +#: ../../po/../src/extension/internal/grid.cpp:216 +#, fuzzy +msgid "Horizontal Offset" +msgstr "üfüqi hərəkət" + +#: ../../po/../src/extension/internal/grid.cpp:217 +msgid "Vertical Offset" +msgstr "" + +#: ../../po/../src/extension/internal/ps.cpp:123 +#, fuzzy +msgid "Print Destination" +msgstr "Çəkilişi çap et" + +#. Print properties frame +#: ../../po/../src/extension/internal/ps.cpp:138 +#, fuzzy +msgid "Print properties" +msgstr "Körpü Xassələri" + +#: ../../po/../src/extension/internal/ps.cpp:145 +msgid "Print using PostScript operators" +msgstr "" + +#: ../../po/../src/extension/internal/ps.cpp:147 +msgid "" +"Use PostScript vector operators. The resulting image is usually smaller in " +"file size and can be arbitrarily scaled, but alpha transparency and patterns " +"will be lost." +msgstr "" + +#: ../../po/../src/extension/internal/ps.cpp:152 +#, fuzzy +msgid "Print as bitmap" +msgstr "Fayl ver" + +#: ../../po/../src/extension/internal/ps.cpp:154 +msgid "" +"Print everything as bitmap. The resulting image is usually larger in file " +"size and cannot be arbitrarily scaled without quality loss, but all objects " +"will be rendered exactly as displayed." +msgstr "" + +#: ../../po/../src/extension/internal/ps.cpp:168 +msgid "Preferred resolution (dots per inch) of bitmap" +msgstr "" + +#: ../../po/../src/extension/internal/ps.cpp:182 +#, fuzzy +msgid "Resolution:" +msgstr "Seçki" + +#. Print destination frame +#: ../../po/../src/extension/internal/ps.cpp:186 +#, fuzzy +msgid "Print destination" +msgstr "Çəkilişi çap et" + +#: ../../po/../src/extension/internal/ps.cpp:192 +msgid "" +"Use '> filename' to print to file.\n" +"Use '| prog arg...' to pipe to a program." +msgstr "" + +#: ../../po/../src/extension/internal/ps.cpp:1227 +msgid "write error occurred" +msgstr "" + +#: ../../po/../src/extension/prefdialog.cpp:21 +#, fuzzy +msgid " Preferences" +msgstr "Sodipodi" + +#. We can't call sp_ui_error_dialog because we may be +#. running from the console, in which case calling sp_ui +#. routines will cause a segfault. See bug 1000350 - bryce +#. sp_ui_error_dialog(_("Format autodetect failed. The file is being opened as SVG.")); +#: ../../po/../src/extension/system.cpp:105 +msgid "Format autodetect failed. The file is being opened as SVG." +msgstr "" + +#. TRANSLATORS: default.svg is localizable - this is the name of the default document +#. template. This way you can localize the default pagesize, translate the name of +#. the default layer, etc. If you wish to localize this file, please create a +#. localized share/templates/default.xx.svg file, where xx is your language code. +#: ../../po/../src/file.cpp:133 +#, fuzzy +msgid "default.svg" +msgstr "Sil" + +#: ../../po/../src/file.cpp:215 ../../po/../src/file.cpp:900 +#, c-format +msgid "Failed to load the requested file %s" +msgstr "" + +#: ../../po/../src/file.cpp:240 +#, fuzzy +msgid "Document not saved yet. Cannot revert." +msgstr "Sənəd" + +#: ../../po/../src/file.cpp:246 +#, c-format +msgid "Changes will be lost! Are you sure you want to reload document %s?" +msgstr "" + +#: ../../po/../src/file.cpp:266 +#, fuzzy +msgid "Document reverted." +msgstr "Sənəd" + +#: ../../po/../src/file.cpp:268 +#, fuzzy +msgid "Document not reverted." +msgstr "Sənəd" + +#: ../../po/../src/file.cpp:382 +msgid "Select file to open" +msgstr "Açılacaq faylı seç" + +#: ../../po/../src/file.cpp:518 +#, c-format +msgid "Removed %i unused definition in <defs>." +msgid_plural "Removed %i unused definitions in <defs>." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/file.cpp:523 +msgid "No unused definitions in <defs>." +msgstr "" + +#: ../../po/../src/file.cpp:548 +#, c-format +msgid "" +"No Inkscape extension found to save document (%s). This may have been " +"caused by an unknown filename extension." +msgstr "" + +#: ../../po/../src/file.cpp:549 ../../po/../src/file.cpp:557 +#, fuzzy +msgid "Document not saved." +msgstr "Sənəd" + +#: ../../po/../src/file.cpp:556 +#, c-format +msgid "File %s could not be saved." +msgstr "" + +#: ../../po/../src/file.cpp:566 +#, fuzzy +msgid "Document saved." +msgstr "Sənəd" + +#: ../../po/../src/file.cpp:614 +#, fuzzy, c-format +msgid "drawing%s" +msgstr "Çək_mə" + +#: ../../po/../src/file.cpp:620 +#, fuzzy, c-format +msgid "drawing-%d%s" +msgstr "Yeni çəkiliş" + +#: ../../po/../src/file.cpp:655 +#, fuzzy +msgid "Select file to save to" +msgstr "Açılacaq faylı seç" + +#: ../../po/../src/file.cpp:739 +msgid "No changes need to be saved." +msgstr "" + +#: ../../po/../src/file.cpp:926 +msgid "Select file to import" +msgstr "Alınacaq faylı seç" + +#: ../../po/../src/gradient-context.cpp:263 +msgid "Ctrl: snap gradient angle" +msgstr "" + +#: ../../po/../src/gradient-context.cpp:264 +msgid "Shift: draw gradient around the starting point" +msgstr "" + +#. We did an undoable action, but sp_document_done will be called by the knot when released +#. status text; we do not track coords because this branch is run once, not all the time +#. during drag +#: ../../po/../src/gradient-context.cpp:462 +#, c-format +msgid "Gradient for %d objects; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/gradient-context.cpp:464 +#, fuzzy +msgid "Select objects on which to create gradient." +msgstr "Seçili bölmani ara yaddaşa al" + +#: ../../po/../src/gradient-drag.cpp:65 +msgid "Linear gradient start" +msgstr "" + +#. POINT_LG_P1 +#: ../../po/../src/gradient-drag.cpp:66 +msgid "Linear gradient end" +msgstr "" + +#: ../../po/../src/gradient-drag.cpp:67 +msgid "Radial gradient center" +msgstr "" + +#: ../../po/../src/gradient-drag.cpp:68 ../../po/../src/gradient-drag.cpp:69 +msgid "Radial gradient radius" +msgstr "" + +#: ../../po/../src/gradient-drag.cpp:70 +msgid "Radial gradient focus" +msgstr "" + +#: ../../po/../src/gradient-drag.cpp:659 +#, c-format +msgid "" +"%s for: %s%s; drag with Ctrl to snap angle, with Ctrl+Alt to " +"preserve angle, with Ctrl+Shift to scale around center" +msgstr "" + +#: ../../po/../src/gradient-drag.cpp:662 +msgid " (stroke)" +msgstr "" + +#: ../../po/../src/gradient-drag.cpp:665 +msgid "" +"Radial gradient center and focus; drag with Shift to " +"separate focus" +msgstr "" + +#: ../../po/../src/gradient-drag.cpp:667 +#, c-format +msgid "" +"Gradient point shared by %d gradients; drag with Shift to " +"separate" +msgstr "" + +#: ../../po/../src/helper/units.cpp:40 +msgid "Unit" +msgstr "" + +#: ../../po/../src/helper/units.cpp:40 +msgid "Units" +msgstr "" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Point" +msgstr "Nöqtə" + +#: ../../po/../src/helper/units.cpp:41 +msgid "pt" +msgstr "pt" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Points" +msgstr "Nöqtə" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Pt" +msgstr "" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Pixel" +msgstr "Bənək" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Pixels" +msgstr "Piksel" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Px" +msgstr "" + +#. You can add new elements from this point forward +#: ../../po/../src/helper/units.cpp:44 ../share/extensions/straightseg.inx.h:2 +msgid "Percent" +msgstr "Faiz" + +#: ../../po/../src/helper/units.cpp:44 +#, fuzzy +msgid "Percents" +msgstr "Faiz" + +#: ../../po/../src/helper/units.cpp:45 +msgid "Millimeter" +msgstr "Millimetr" + +#: ../../po/../src/helper/units.cpp:45 +msgid "mm" +msgstr "mm" + +#: ../../po/../src/helper/units.cpp:45 +msgid "Millimeters" +msgstr "Millimetr" + +#: ../../po/../src/helper/units.cpp:46 +msgid "Centimeter" +msgstr "Sentimetr" + +#: ../../po/../src/helper/units.cpp:46 +msgid "cm" +msgstr "cm" + +#: ../../po/../src/helper/units.cpp:46 +msgid "Centimeters" +msgstr "Sentimetr" + +#: ../../po/../src/helper/units.cpp:47 +#, fuzzy +msgid "Meter" +msgstr "Orta" + +#: ../../po/../src/helper/units.cpp:47 +#, fuzzy +msgid "m" +msgstr "cm" + +#: ../../po/../src/helper/units.cpp:47 +#, fuzzy +msgid "Meters" +msgstr "Orta" + +#. no svg_unit +#: ../../po/../src/helper/units.cpp:48 +msgid "Inch" +msgstr "Ä°nç" + +#: ../../po/../src/helper/units.cpp:48 +msgid "in" +msgstr "in" + +#: ../../po/../src/helper/units.cpp:48 +msgid "Inches" +msgstr "Inç" + +#. Volatiles do not have default, so there are none here +#. TRANSLATORS: for info, see http://www.w3.org/TR/REC-CSS2/syndata.html#length-units +#: ../../po/../src/helper/units.cpp:51 +msgid "Em square" +msgstr "" + +#: ../../po/../src/helper/units.cpp:51 +msgid "em" +msgstr "" + +#: ../../po/../src/helper/units.cpp:51 +msgid "Em squares" +msgstr "" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/REC-CSS2/syndata.html#length-units +#: ../../po/../src/helper/units.cpp:53 +msgid "Ex square" +msgstr "" + +#: ../../po/../src/helper/units.cpp:53 +msgid "ex" +msgstr "" + +#: ../../po/../src/helper/units.cpp:53 +msgid "Ex squares" +msgstr "" + +#: ../../po/../src/inkscape.cpp:468 +msgid "Untitled document" +msgstr "" + +#. Show nice dialog box +#: ../../po/../src/inkscape.cpp:497 +msgid "Inkscape encountered an internal error and will close now.\n" +msgstr "" + +#: ../../po/../src/inkscape.cpp:498 +msgid "" +"Automatic backups of unsaved documents were done to the following " +"locations:\n" +msgstr "" + +#: ../../po/../src/inkscape.cpp:499 +msgid "Automatic backup of the following documents failed:\n" +msgstr "" + +#: ../../po/../src/inkscape.cpp:634 +#, c-format +msgid "" +"Cannot create directory %s.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:635 +#, c-format +msgid "" +"%s is not a valid directory.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:636 +#, c-format +msgid "" +"Cannot create file %s.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:637 +#, c-format +msgid "" +"Cannot write file %s.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:638 +msgid "" +"Although Inkscape will run, it will use default settings,\n" +"and any changes made in preferences will not be saved." +msgstr "" + +#: ../../po/../src/inkscape.cpp:708 +#, c-format +msgid "" +"%s is not a regular file.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:709 +#, c-format +msgid "" +"%s not a valid XML file, or\n" +"you don't have read permissions on it.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:711 +#, c-format +msgid "" +"%s is not a valid menus file.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:712 +msgid "" +"Inkscape will run with default menus.\n" +"New menus will not be saved." +msgstr "" + +#. sp_ui_menu_append_check_item_from_verb(m, view, _("_Menu"), _("Show or hide the menu bar"), "menu", +#. checkitem_toggled, checkitem_update, 0); +#: ../../po/../src/interface.cpp:753 +msgid "Commands Bar" +msgstr "" + +#: ../../po/../src/interface.cpp:753 +#, fuzzy +msgid "Show or hide the Commands bar (under the menu)" +msgstr "Kənarları Aç" + +#: ../../po/../src/interface.cpp:755 +#, fuzzy +msgid "Tool Controls" +msgstr "Oaf seçənəkləri" + +#: ../../po/../src/interface.cpp:755 +#, fuzzy +msgid "Show or hide the Tool Controls panel" +msgstr "Kənarları Aç" + +#: ../../po/../src/interface.cpp:757 +msgid "_Toolbox" +msgstr "" + +#: ../../po/../src/interface.cpp:757 +msgid "Show or hide the main toolbox (on the left)" +msgstr "" + +#: ../../po/../src/interface.cpp:763 +msgid "_Statusbar" +msgstr "" + +#: ../../po/../src/interface.cpp:763 +msgid "Show or hide the statusbar (at the bottom of the window)" +msgstr "" + +#: ../../po/../src/interface.cpp:820 +#, c-format +msgid "Verb \"%s\" Unknown" +msgstr "" + +#. TRANSLATORS: #%s is the id of the group e.g. , not a number. +#: ../../po/../src/interface.cpp:930 +#, fuzzy, c-format +msgid "Enter group #%s" +msgstr "Düyünləri düzəlt" + +#: ../../po/../src/interface.cpp:941 +#, fuzzy +msgid "Go to parent" +msgstr "Nöqtə" + +#: ../../po/../src/interface.cpp:972 +msgid "Could not parse SVG data" +msgstr "" + +#: ../../po/../src/interface.cpp:1135 +#, c-format +msgid "Overwrite %s" +msgstr "" + +#: ../../po/../src/interface.cpp:1153 +#, c-format +msgid "" +"The file %s already exists. Do you want to overwrite that file with the " +"current document?" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:59 +msgid "Jabber connection lost." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:72 +#, c-format +msgid "Sending message; %u message remaining in send queue." +msgid_plural "Sending message; %u messages remaining in send queue." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:78 +msgid "Receive queue empty." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:154 +#, c-format +msgid "Receiving change; %u change left to process." +msgid_plural "Receiving change; %u changes left to process." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:157 +#, c-format +msgid "%s has left the chatroom." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:221 +msgid "Nickname %1 is already in use. Please choose a different nickname." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:225 +msgid "An error was encountered while attempting to connect to the server." +msgstr "" + +#. Check to see if the user made any modifications to this document. If so, +#. we want to give them the option of (1) letting us clear their document or (2) +#. opening a new, blank document for the whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:131 +msgid "%1 has invited you to a whiteboard session." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:132 +msgid "Incoming whiteboard invitation from %1" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:135 +msgid "Do you wish to accept %1's whiteboard session invitation?" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:137 +msgid "" +"Would you like to accept %1's invitation in a new document window?\n" +"Accepting the invitation in your current window will discard unsaved changes." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:143 +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:198 +#, fuzzy +msgid "Accept invitation" +msgstr "Seçki" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:144 +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:199 +msgid "Decline invitation" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:145 +#, fuzzy +msgid "Accept invitation in new document window" +msgstr "Sənəd" + +#. We could not create a new desktop; ask the user if she or he wants to +#. replace the current document and accept the invitation, or reject the invitation. +#. TRANSLATORS: %1 is a userid here +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:196 +msgid "" +"A new document window could not be opened for a whiteboard session with %" +"1" +msgstr "" + +#. TRANSLATORS: %1 is the peer whom refused our invitation. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:238 +msgid "" +"The user %1 has refused your " +"whiteboard invitation.\n" +"\n" +msgstr "" + +#. TRANSLATORS: %1 is the peer whom refused our invitation, %2 is our Jabber identity. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:241 +msgid "" +"You are still connected to a Jabber server as %2, and may send an " +"invitation to %1 again, or you may send an invitation to a different " +"user." +msgstr "" + +#. TRANSLATORS: %1 is the peer whom we tried to contact, but is already in a whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:252 +msgid "" +"The user %1 is already in a " +"whiteboard session.\n" +"\n" +msgstr "" + +#. TRANSLATORS: %1 is the peer whom we tried to contact, but is already in a whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:255 +msgid "" +"You are still connected to a Jabber server as %1, and may send an " +"invitation to a different user." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/invitation-confirm-dialog.cpp:26 +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:24 +msgid "_Write session file:" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/message-processors.cpp:145 +#, c-format +msgid "%s has joined the chatroom." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/message-queue.cpp:87 +#, c-format +msgid "%u change in receive queue." +msgid_plural "%u changes in receive queue." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/jabber_whiteboard/message-queue.cpp:117 +#, c-format +msgid "%u change in send queue." +msgid_plural "%u changes in send queue." +msgstr[0] "" +msgstr[1] "" + +#. if ID is NULL, then we have a real problem -- we were not able to find a key +#. nor generate one. The only thing we can really do here is abort, since we have +#. no way to let the other client(s) uniquely identify this object. +#. FIXME: If this indicates a programming bug, then don't request translation with +#. * _(...): it is most useful in untranslated form so that developers may search for +#. * it when someone reports it in a bug report (as we want users to do for all bugs, +#. * as indicated by it being a g_warning string). +#. * +#. * Otherwise, if it is not a programming bug but a network error or a bug in the +#. * remote peer (perhaps running different software) or whatever, then present it in +#. * an alert box, and avoid use of technical jargon `NULL'. +#. +#: ../../po/../src/jabber_whiteboard/message-utilities.cpp:171 +msgid "" +"ID for new object is NULL even after generation and lookup attempts: the new " +"object will NOT be sent, nor will any of its child objects!" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:60 +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:995 +msgid "Select a location and filename" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:62 +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:997 +#, fuzzy +msgid "Set filename" +msgstr "Faylı qeyd et" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:301 +msgid "No SSL certificate was found." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:304 +msgid "The SSL certificate provided by the Jabber server is untrusted." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:307 +msgid "The SSL certificate provided by the Jabber server is expired." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:310 +msgid "" +"The SSL certificate provided by the Jabber server has not been activated." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:313 +msgid "" +"The SSL certificate provided by the Jabber server contains a hostname that " +"does not match the Jabber server's hostname." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:316 +msgid "" +"The SSL certificate provided by the Jabber server contains an invalid " +"fingerprint." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:319 +msgid "An unknown error occurred while setting up the SSL connection." +msgstr "" + +#. TRANSLATORS: %1 is the message that describes the specific error that occurred when +#. establishing the SSL connection. +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:325 +msgid "" +"%1\n" +"\n" +"Do you wish to continue connecting to the Jabber server?" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:328 +msgid "Continue connecting and ignore further errors" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:329 +msgid "Continue connecting, but warn me of further errors" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:330 +#, fuzzy +msgid "Cancel connection" +msgstr "Seçki" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:777 +#, c-format +msgid "Established whiteboard session with %s." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:785 +#, c-format +msgid "%s has left the whiteboard session." +msgstr "" + +#. Inform the user +#. TRANSLATORS: %1 is the name of the user that disconnected, %2 is the name of the user whom the disconnected user disconnected from. +#. This message is not used in a chatroom context. +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:790 +msgid "" +"The user %1 has left the " +"whiteboard session.\n" +"\n" +msgstr "" + +#. TRANSLATORS: %1 and %2 are userids +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:792 +msgid "" +"You are still connected to a Jabber server as %2, and may establish a " +"new session to %1 or a different user." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:988 +msgid "" +"Could not open file %1 for session recording.\n" +"The error encountered was: %2.\n" +"\n" +"You may select a different location to record the session, or you may opt to " +"not record this session." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:990 +msgid "Choose a different location" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:991 +msgid "Skip session recording" +msgstr "" + +#: ../../po/../src/knot.cpp:673 +msgid "Node or handle drag canceled." +msgstr "" + +#: ../../po/../src/libnrtype/FontFactory.cpp:358 +msgid "Ignoring font without family that will crash Pango" +msgstr "" + +#: ../../po/../src/main.cpp:395 +msgid "Print the Inkscape version number" +msgstr "" + +#: ../../po/../src/main.cpp:400 +msgid "Do not use X server (only process files from console)" +msgstr "" + +#: ../../po/../src/main.cpp:405 +msgid "Try to use X server (even if $DISPLAY is not set)" +msgstr "" + +#: ../../po/../src/main.cpp:410 +msgid "Open specified document(s) (option string may be excluded)" +msgstr "" + +#: ../../po/../src/main.cpp:411 ../../po/../src/main.cpp:416 +#: ../../po/../src/main.cpp:421 ../../po/../src/main.cpp:483 +#: ../../po/../src/main.cpp:488 ../../po/../src/main.cpp:493 +msgid "FILENAME" +msgstr "FAYLADI" + +#: ../../po/../src/main.cpp:415 +msgid "Print document(s) to specified output file (use '| program' for pipe)" +msgstr "" + +#: ../../po/../src/main.cpp:420 +msgid "Export document to a PNG file" +msgstr "" + +#: ../../po/../src/main.cpp:425 +msgid "The resolution used for exporting SVG into bitmap (default 90)" +msgstr "" + +#: ../../po/../src/main.cpp:426 +msgid "DPI" +msgstr "" + +#: ../../po/../src/main.cpp:430 +msgid "" +"Exported area in SVG user units (default is the canvas; 0,0 is lower-left " +"corner)" +msgstr "" + +#: ../../po/../src/main.cpp:431 +msgid "x0:y0:x1:y1" +msgstr "" + +#: ../../po/../src/main.cpp:435 +msgid "Exported area is the entire drawing (not canvas)" +msgstr "" + +#: ../../po/../src/main.cpp:440 +msgid "" +"Snap the bitmap export area outwards to the nearest integer values (in SVG " +"user units)" +msgstr "" + +#: ../../po/../src/main.cpp:445 +msgid "The width of exported bitmap in pixels (overrides export-dpi)" +msgstr "" + +#: ../../po/../src/main.cpp:446 +msgid "WIDTH" +msgstr "" + +#: ../../po/../src/main.cpp:450 +msgid "The height of exported bitmap in pixels (overrides export-dpi)" +msgstr "" + +#: ../../po/../src/main.cpp:451 +msgid "HEIGHT" +msgstr "" + +#: ../../po/../src/main.cpp:455 +msgid "The ID of the object to export (overrides export-area)" +msgstr "" + +#: ../../po/../src/main.cpp:456 ../../po/../src/main.cpp:532 +msgid "ID" +msgstr "" + +#. TRANSLATORS: this means: "Only export the object whose id is given in --export-id". +#. See "man inkscape" for details. +#: ../../po/../src/main.cpp:462 +msgid "" +"Export just the object with export-id, hide all others (only with export-id)" +msgstr "" + +#: ../../po/../src/main.cpp:467 +msgid "Use stored filename and DPI hints when exporting (only with export-id)" +msgstr "" + +#: ../../po/../src/main.cpp:472 +msgid "Background color of exported bitmap (any SVG-supported color string)" +msgstr "" + +#: ../../po/../src/main.cpp:473 +msgid "COLOR" +msgstr "" + +#: ../../po/../src/main.cpp:477 +msgid "Background opacity of exported bitmap (either 0.0 to 1.0, or 1 to 255)" +msgstr "" + +#: ../../po/../src/main.cpp:478 +msgid "VALUE" +msgstr "" + +#: ../../po/../src/main.cpp:482 +msgid "Export document to plain SVG file (no sodipodi or inkscape namespaces)" +msgstr "" + +#: ../../po/../src/main.cpp:487 +#, fuzzy +msgid "Export document to a PS file" +msgstr "Fayl ver" + +#: ../../po/../src/main.cpp:492 +msgid "Export document to an EPS file" +msgstr "" + +#: ../../po/../src/main.cpp:497 +#, fuzzy +msgid "Convert text object to paths on export (EPS)" +msgstr "seçkini aşağıya çək" + +#: ../../po/../src/main.cpp:502 +msgid "Export files with the bounding box set to the page size (EPS)" +msgstr "" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:508 +msgid "" +"Query the X coordinate of the drawing or, if specified, of the object with --" +"query-id" +msgstr "" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:514 +msgid "" +"Query the Y coordinate of the drawing or, if specified, of the object with --" +"query-id" +msgstr "" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:520 +msgid "" +"Query the width of the drawing or, if specified, of the object with --query-" +"id" +msgstr "" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:526 +msgid "" +"Query the height of the drawing or, if specified, of the object with --query-" +"id" +msgstr "" + +#: ../../po/../src/main.cpp:531 +msgid "The ID of the object whose dimensions are queried" +msgstr "" + +#. TRANSLATORS: this option makes Inkscape print the name (path) of the extension directory +#: ../../po/../src/main.cpp:537 +msgid "Print out the extension directory and exit" +msgstr "" + +#: ../../po/../src/main.cpp:542 +msgid "Show given files one-by-one, switch to next on any key/mouse event" +msgstr "" + +#: ../../po/../src/main.cpp:547 +msgid "Use the new Gtkmm GUI interface" +msgstr "" + +#: ../../po/../src/main.cpp:552 +msgid "Remove unused definitions from the defs section(s) of the document" +msgstr "" + +#: ../../po/../src/main.cpp:741 +msgid "" +"[OPTIONS...] [FILE...]\n" +"\n" +"Available options:" +msgstr "" + +#: ../../po/../src/menus-skeleton.h:17 +msgid "_New" +msgstr "_Yeni" + +#: ../../po/../src/menus-skeleton.h:22 +#, fuzzy +msgid "Open _Recent" +msgstr "_Aç" + +#: ../../po/../src/menus-skeleton.h:53 +#, fuzzy +msgid "_Edit" +msgstr "Düzəlt" + +#: ../../po/../src/menus-skeleton.h:84 +#, fuzzy +msgid "_View" +msgstr "Yeni Görünüş" + +#: ../../po/../src/menus-skeleton.h:85 +#, fuzzy +msgid "_Zoom" +msgstr "Yaxınlıq" + +#: ../../po/../src/menus-skeleton.h:102 +#, fuzzy +msgid "Show/Hide" +msgstr "Qəfəs" + +#: ../../po/../src/menus-skeleton.h:107 +#, fuzzy +msgid "_Display mode" +msgstr "Ekran" + +#: ../../po/../src/menus-skeleton.h:126 +#, fuzzy +msgid "_Layer" +msgstr "Seç" + +#: ../../po/../src/menus-skeleton.h:143 +#, fuzzy +msgid "_Object" +msgstr "Cism" + +#: ../../po/../src/menus-skeleton.h:165 +#, fuzzy +msgid "_Path" +msgstr "Yapışdır" + +#: ../../po/../src/menus-skeleton.h:188 +#, fuzzy +msgid "_Text" +msgstr "Mətn" + +#: ../../po/../src/menus-skeleton.h:200 +#, fuzzy +msgid "Effects" +msgstr "Cism" + +#: ../../po/../src/menus-skeleton.h:207 +msgid "Whiteboa_rd" +msgstr "" + +#: ../../po/../src/menus-skeleton.h:220 +#, fuzzy +msgid "_Help" +msgstr "_Yardım" + +#: ../../po/../src/menus-skeleton.h:222 +msgid "Tutorials" +msgstr "" + +#: ../../po/../src/node-context.cpp:382 +msgid "" +"Ctrl: toggle node type, snap handle angle, move hor/vert; Ctrl" +"+Alt: move along handles" +msgstr "" + +#: ../../po/../src/node-context.cpp:383 +msgid "" +"Shift: toggle node selection, disable snapping, rotate both handles" +msgstr "" + +#: ../../po/../src/node-context.cpp:384 +msgid "Alt: lock handle length; Ctrl+Alt: move along handles" +msgstr "" + +#: ../../po/../src/nodepath.cpp:1399 ../../po/../src/nodepath.cpp:1411 +#: ../../po/../src/nodepath.cpp:1492 ../../po/../src/nodepath.cpp:1504 +msgid "To join, you must have two endnodes selected." +msgstr "" + +#: ../../po/../src/nodepath.cpp:1633 ../../po/../src/nodepath.cpp:1647 +msgid "" +"Select two non-endpoint nodes on a path between which to delete " +"segments." +msgstr "" + +#: ../../po/../src/nodepath.cpp:1743 +#, fuzzy +msgid "Cannot find path between nodes." +msgstr "Seçili cığırları kombinə et" + +#: ../../po/../src/nodepath.cpp:2822 +#, c-format +msgid "" +"Node handle: angle %0.2f°, length %s; with Ctrl to snap " +"angle; with Alt to lock length; with Shift to rotate both " +"handles" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3351 +msgid "" +"Node: drag to edit the path; with Ctrl to snap to horizontal/" +"vertical; with Ctrl+Alt to snap to handles' directions" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3375 +msgid "" +"Node handle: drag to shape the curve; with Ctrl to snap angle; " +"with Alt to lock length; with Shift to rotate both handles" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3399 +msgid "" +"Node handle: drag to shape the curve; with Ctrl to snap angle; " +"with Alt to lock length; with Shift to rotate the opposite " +"handle in sync" +msgstr "" + +#. TRANSLATORS: "end" is an adjective here (NOT a verb) +#: ../../po/../src/nodepath.cpp:3591 +#, fuzzy +msgid "end node" +msgstr "Düyünləri düzəlt" + +#. TRANSLATORS: "cusp" means "sharp" (cusp node); see also the Advanced Tutorial +#: ../../po/../src/nodepath.cpp:3596 +msgid "cusp" +msgstr "" + +#. TRANSLATORS: "smooth" is an adjective here +#: ../../po/../src/nodepath.cpp:3599 +msgid "smooth" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3601 +#, fuzzy +msgid "symmetric" +msgstr "Asimetrik" + +#. TRANSLATORS: "end" is an adjective here (NOT a verb) +#: ../../po/../src/nodepath.cpp:3607 +msgid "end node, handle retracted (drag with Shift to extend)" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3609 +msgid "one handle retracted (drag with Shift to extend)" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3612 +msgid "both handles retracted (drag with Shift to extend)" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3624 +msgid "Drag nodes or node handles; arrow keys to move nodes" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3625 +msgid "Drag the node or its handles; arrow keys to move the node" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3651 ../../po/../src/nodepath.cpp:3663 +#, fuzzy +msgid "Select a single object to edit its nodes or handles." +msgstr "Seçili cismləri qruplaşdır" + +#: ../../po/../src/nodepath.cpp:3655 +#, c-format +msgid "" +"0 out of %i node selected. Click, Shift+click, " +"or drag around nodes to select." +msgid_plural "" +"0 out of %i nodes selected. Click, Shift+click, " +"or drag around nodes to select." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/nodepath.cpp:3661 +msgid "Drag the handles of the object to modify it." +msgstr "" + +#: ../../po/../src/nodepath.cpp:3669 +#, fuzzy, c-format +msgid "%i of %i node selected; %s. %s." +msgid_plural "%i of %i nodes selected; %s. %s." +msgstr[0] "Seçili cığırları kombinə et" +msgstr[1] "Seçili cığırları kombinə et" + +#: ../../po/../src/nodepath.cpp:3675 +#, fuzzy, c-format +msgid "%i of %i node selected. %s." +msgid_plural "%i of %i nodes selected. %s." +msgstr[0] "Seçili cığırları kombinə et" +msgstr[1] "Seçili cığırları kombinə et" + +#: ../../po/../src/object-edit.cpp:493 +msgid "" +"Adjust the horizontal rounding radius; with Ctrl to make the " +"vertical radius the same" +msgstr "" + +#: ../../po/../src/object-edit.cpp:499 +msgid "" +"Adjust the vertical rounding radius; with Ctrl to make the " +"horizontal radius the same" +msgstr "" + +#: ../../po/../src/object-edit.cpp:506 ../../po/../src/object-edit.cpp:513 +msgid "" +"Adjust the width and height of the rectangle; with Ctrl to " +"lock ratio or stretch in one dimension only" +msgstr "" + +#: ../../po/../src/object-edit.cpp:686 +msgid "Adjust ellipse width, with Ctrl to make circle" +msgstr "" + +#: ../../po/../src/object-edit.cpp:689 +msgid "Adjust ellipse height, with Ctrl to make circle" +msgstr "" + +#: ../../po/../src/object-edit.cpp:692 +msgid "" +"Position the start point of the arc or segment; with Ctrl to " +"snap angle; drag inside the ellipse for arc, outside for " +"segment" +msgstr "" + +#: ../../po/../src/object-edit.cpp:695 +msgid "" +"Position the end point of the arc or segment; with Ctrl to " +"snap angle; drag inside the ellipse for arc, outside for " +"segment" +msgstr "" + +#: ../../po/../src/object-edit.cpp:800 +msgid "" +"Adjust the tip radius of the star or polygon; with Shift to " +"round; with Alt to randomize" +msgstr "" + +#: ../../po/../src/object-edit.cpp:803 +msgid "" +"Adjust the base radius of the star; with Ctrl to keep star " +"rays radial (no skew); with Shift to round; with Alt to " +"randomize" +msgstr "" + +#: ../../po/../src/object-edit.cpp:967 +msgid "" +"Roll/unroll the spiral from inside; with Ctrl to snap angle; " +"with Alt to converge/diverge" +msgstr "" + +#: ../../po/../src/object-edit.cpp:969 +msgid "" +"Roll/unroll the spiral from outside; with Ctrl to snap angle; " +"with Shift to scale/rotate" +msgstr "" + +#: ../../po/../src/object-edit.cpp:1006 +msgid "Adjust the offset distance" +msgstr "" + +#. TRANSLATORS: This refers to the pattern that's inside the object +#: ../../po/../src/object-edit.cpp:1036 +msgid "Move the pattern fill inside the object" +msgstr "" + +#: ../../po/../src/object-edit.cpp:1038 +#, fuzzy +msgid "Scale the pattern fill uniformly" +msgstr "Seçili bölmani ara yaddaşa al" + +#: ../../po/../src/object-edit.cpp:1040 +msgid "Rotate the pattern fill; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/object-edit.cpp:1065 +msgid "Drag to resize the flowed text frame" +msgstr "" + +#. Item dialog +#: ../../po/../src/object-ui.cpp:106 +#, fuzzy +msgid "Object _Properties" +msgstr "Mətn Xassələri" + +#. Select item +#: ../../po/../src/object-ui.cpp:116 +#, fuzzy +msgid "_Select This" +msgstr "Bunu seç" + +#. Create link +#: ../../po/../src/object-ui.cpp:126 +#, fuzzy +msgid "_Create Link" +msgstr "Körpü yarat" + +#. "Ungroup" +#: ../../po/../src/object-ui.cpp:199 ../../po/../src/verbs.cpp:1931 +msgid "_Ungroup" +msgstr "Qrupu q_aldır" + +#. Link dialog +#: ../../po/../src/object-ui.cpp:239 +#, fuzzy +msgid "Link _Properties" +msgstr "Körpü Xassələri" + +#. Select item +#: ../../po/../src/object-ui.cpp:249 +#, fuzzy +msgid "_Follow Link" +msgstr "Körpünü təqib et" + +#. Reset transformations +#: ../../po/../src/object-ui.cpp:254 +#, fuzzy +msgid "_Remove Link" +msgstr "Körpünü sil" + +#. Link dialog +#: ../../po/../src/object-ui.cpp:303 +#, fuzzy +msgid "Image _Properties" +msgstr "Üzv Xassələri" + +#. Item dialog +#: ../../po/../src/object-ui.cpp:344 +#, fuzzy +msgid "_Fill and Stroke" +msgstr "Doldurma qurğuları" + +#: ../../po/../src/path-chemistry.cpp:58 +#, fuzzy +msgid "Select at least two objects to combine." +msgstr "Seçili cismləri qruplaşdır" + +#: ../../po/../src/path-chemistry.cpp:65 +#, fuzzy +msgid "At least one of the objects is not a path, cannot combine." +msgstr "seçkini aşağıya çək" + +#: ../../po/../src/path-chemistry.cpp:73 +msgid "" +"You cannot combine objects from different groups or layers." +msgstr "" + +#: ../../po/../src/path-chemistry.cpp:155 +#, fuzzy +msgid "Select path(s) to break apart." +msgstr "Seçili bölmani ara yaddaşa al" + +#: ../../po/../src/path-chemistry.cpp:231 +msgid "No path(s) to break apart in the selection." +msgstr "" + +#: ../../po/../src/path-chemistry.cpp:252 +#, fuzzy +msgid "Select object(s) to convert to path." +msgstr "Seçili bölmani ara yaddaşa al" + +#: ../../po/../src/path-chemistry.cpp:297 +#, fuzzy +msgid "No objects to convert to path in the selection." +msgstr "Seçili bölmani ara yaddaşa al" + +#: ../../po/../src/path-chemistry.cpp:345 +#, fuzzy +msgid "Select path(s) to reverse." +msgstr "Seçkini yuxarıya çək" + +#: ../../po/../src/path-chemistry.cpp:370 +msgid "No paths to reverse in the selection." +msgstr "" + +#: ../../po/../src/pen-context.cpp:379 ../../po/../src/pencil-context.cpp:233 +#, fuzzy +msgid "Continuing selected path" +msgstr "Seçili cığırları kombinə et" + +#: ../../po/../src/pen-context.cpp:390 ../../po/../src/pencil-context.cpp:242 +#, fuzzy +msgid "Creating new path" +msgstr "Sənəd" + +#: ../../po/../src/pen-context.cpp:394 ../../po/../src/pencil-context.cpp:246 +#, fuzzy +msgid "Appending to selected path" +msgstr "Seçkiyə yaxınlaşdır" + +#: ../../po/../src/pen-context.cpp:538 +msgid "Click or click and drag to close and finish the path." +msgstr "" + +#: ../../po/../src/pen-context.cpp:548 +msgid "" +"Click or click and drag to continue the path from this point." +msgstr "" + +#: ../../po/../src/pen-context.cpp:857 +#, c-format +msgid "" +"%s: angle %3.2f°, distance %s; with Ctrl to snap angle, " +"Enter to finish the path" +msgstr "" + +#: ../../po/../src/pen-context.cpp:882 +#, c-format +msgid "" +"Curve handle: angle %3.2f°, length %s; with Ctrl to snap " +"angle" +msgstr "" + +#: ../../po/../src/pen-context.cpp:912 +#, c-format +msgid "" +"%s: angle %3.2f°, length %s; with Ctrl to snap angle, " +"with Shift to move this handle only" +msgstr "" + +#: ../../po/../src/pen-context.cpp:946 +#, fuzzy +msgid "Finishing pen" +msgstr "Freehand" + +#: ../../po/../src/pencil-context.cpp:320 +msgid "Release here to close and finish the path." +msgstr "" + +#: ../../po/../src/pencil-context.cpp:326 +#, fuzzy +msgid "Drawing a freehand path" +msgstr "Dynahand cızığı çək" + +#: ../../po/../src/pencil-context.cpp:331 +msgid "Drag to continue the path from this point." +msgstr "" + +#. Write curves to object +#: ../../po/../src/pencil-context.cpp:390 +#, fuzzy +msgid "Finishing freehand" +msgstr "Freehand" + +#: ../../po/../src/rect-context.cpp:387 +msgid "" +"Ctrl: make square or integer-ratio rect, lock a rounded corner " +"circular" +msgstr "" + +#: ../../po/../src/rect-context.cpp:549 +#, c-format +msgid "" +"Rectangle: %s × %s; with Ctrl to make square or integer-" +"ratio rectangle; with Shift to draw around the starting point" +msgstr "" + +#: ../../po/../src/select-context.cpp:243 +#, fuzzy +msgid "Move canceled." +msgstr "Seçki" + +#: ../../po/../src/select-context.cpp:252 +#, fuzzy +msgid "Selection canceled." +msgstr "Seçki" + +#: ../../po/../src/select-context.cpp:642 +msgid "Ctrl: select in groups, move hor/vert" +msgstr "" + +#: ../../po/../src/select-context.cpp:643 +msgid "Shift: toggle select, force rubberband, disable snapping" +msgstr "" + +#: ../../po/../src/select-context.cpp:644 +msgid "Alt: select under, move selected" +msgstr "" + +#: ../../po/../src/select-context.cpp:798 +#, fuzzy +msgid "Selected object is not a group. Cannot enter." +msgstr "seçkini aşağıya çək" + +#: ../../po/../src/select-context.cpp:876 +#, c-format +msgid "" +"Move by %s, %s; with Ctrl to restrict to horizontal/vertical; " +"with Shift to disable snapping" +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:228 +msgid "Nothing was deleted." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:259 +#, fuzzy +msgid "Select object(s) to duplicate." +msgstr "Seçili bölmani ara yaddaşa al" + +#: ../../po/../src/selection-chemistry.cpp:420 +#, fuzzy +msgid "Select two or more objects to group." +msgstr "Seçkini yuxarıya çək" + +#: ../../po/../src/selection-chemistry.cpp:428 +#, fuzzy +msgid "Select at least two objects to group." +msgstr "Seçili cismləri qruplaşdır" + +#: ../../po/../src/selection-chemistry.cpp:513 +#, fuzzy +msgid "Select a group to ungroup." +msgstr "Seçkini yuxarıya çək" + +#: ../../po/../src/selection-chemistry.cpp:554 +msgid "No groups to ungroup in the selection." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:623 +#, fuzzy +msgid "Select objects to raise." +msgstr "Seçili bölmani ara yaddaşa al" + +#: ../../po/../src/selection-chemistry.cpp:629 +#: ../../po/../src/selection-chemistry.cpp:681 +#: ../../po/../src/selection-chemistry.cpp:715 +#: ../../po/../src/selection-chemistry.cpp:773 +msgid "" +"You cannot raise/lower objects from different groups or layers." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:673 +#, fuzzy +msgid "Select object(s) to raise to top." +msgstr "seçkini aşağıya çək" + +#: ../../po/../src/selection-chemistry.cpp:709 +#, fuzzy +msgid "Select object(s) to lower." +msgstr "Seçili bölmani ara yaddaşa al" + +#: ../../po/../src/selection-chemistry.cpp:765 +#, fuzzy +msgid "Select object(s) to lower to bottom." +msgstr "Seçili bölmani ara yaddaşa al" + +#: ../../po/../src/selection-chemistry.cpp:806 +msgid "Nothing to undo." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:813 +msgid "Nothing to redo." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:969 +msgid "Nothing was copied." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1051 +msgid "Current layer is hidden. Unhide it to be able to paste to it." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1055 +msgid "Current layer is locked. Unlock it to be able to paste to it." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1068 +#: ../../po/../src/selection-chemistry.cpp:1103 +#, fuzzy +msgid "Nothing on the clipboard." +msgstr "Seçili bölmani ara yaddaşa al" + +#: ../../po/../src/selection-chemistry.cpp:1109 +#, fuzzy +msgid "Select object(s) to paste style to." +msgstr "seçkini aşağıya çək" + +#: ../../po/../src/selection-chemistry.cpp:1128 +#, fuzzy +msgid "Select object(s) to move to the layer above." +msgstr "Seçili bölmani ara yaddaşa al" + +#: ../../po/../src/selection-chemistry.cpp:1146 +#, fuzzy +msgid "No more layers above." +msgstr "Sənəd" + +#: ../../po/../src/selection-chemistry.cpp:1160 +#, fuzzy +msgid "Select object(s) to move to the layer below." +msgstr "Seçili bölmani ara yaddaşa al" + +#: ../../po/../src/selection-chemistry.cpp:1178 +#, fuzzy +msgid "No more layers below." +msgstr "Sənəd" + +#: ../../po/../src/selection-chemistry.cpp:1811 +#, fuzzy +msgid "Select a clone to unlink." +msgstr "Açılacaq faylı seç" + +#: ../../po/../src/selection-chemistry.cpp:1842 +msgid "No clones to unlink in the selection." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1859 +msgid "" +"Select a clone to go to its original. Select a linked offset " +"to go to its source. Select a text on path to go to the path. Select " +"a flowed text to go to its frame." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1882 +msgid "" +"Cannot find the object to select (orphaned clone, offset, textpath, " +"flowed text?)" +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1888 +msgid "" +"The object you're trying to select is not visible (it is in <" +"defs>)" +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1915 +#, fuzzy +msgid "Select object(s) to convert to pattern." +msgstr "Seçili bölmani ara yaddaşa al" + +#: ../../po/../src/selection-chemistry.cpp:2006 +#, fuzzy +msgid "Select an object with pattern fill to extract objects from." +msgstr "Seçili bölmani ara yaddaşa al" + +#: ../../po/../src/selection-chemistry.cpp:2059 +#, fuzzy +msgid "No pattern fills in the selection." +msgstr "Seçili bölmani ara yaddaşa al" + +#: ../../po/../src/selection-chemistry.cpp:2079 +#, fuzzy +msgid "Select object(s) to make a bitmap copy." +msgstr "seçkini aşağıya çək" + +#: ../../po/../src/selection-describer.cpp:37 +msgid "Click selection to toggle scale/rotation handles" +msgstr "" + +#. no items +#: ../../po/../src/selection-describer.cpp:39 +msgid "" +"No objects selected. Click, Shift+click, or drag around objects to select." +msgstr "" + +#: ../../po/../src/selection-describer.cpp:51 +#, fuzzy, c-format +msgid " in layer %s" +msgstr "Sıfırla" + +#: ../../po/../src/selection-describer.cpp:54 +#, fuzzy, c-format +msgid " in layer %s" +msgstr "Sıfırla" + +#: ../../po/../src/selection-describer.cpp:66 +msgid "Use Shift+D to look up original" +msgstr "" + +#: ../../po/../src/selection-describer.cpp:70 +msgid "Use Shift+D to look up path" +msgstr "" + +#: ../../po/../src/selection-describer.cpp:74 +msgid "Use Shift+D to look up frame" +msgstr "" + +#: ../../po/../src/selection-describer.cpp:84 +#, fuzzy, c-format +msgid "%i object selected" +msgid_plural "%i objects selected" +msgstr[0] "Seçili cığırları kombinə et" +msgstr[1] "Seçili cığırları kombinə et" + +#: ../../po/../src/selection-describer.cpp:90 +#, c-format +msgid "%s%s. %s." +msgstr "" + +#: ../../po/../src/selection-describer.cpp:94 +#, fuzzy, c-format +msgid "%s in %i layer. %s." +msgid_plural "%s in %i layers. %s." +msgstr[0] "Seçili cığırları kombinə et" +msgstr[1] "Seçili cığırları kombinə et" + +#: ../../po/../src/seltrans.cpp:498 +msgid "" +"Center of rotation and skewing: drag to reposition; scaling with " +"Shift also uses this center" +msgstr "" + +#: ../../po/../src/seltrans.cpp:514 +msgid "" +"Squeeze or stretch selection; with Ctrl to scale uniformly; " +"with Shift to scale around rotation center" +msgstr "" + +#: ../../po/../src/seltrans.cpp:515 +msgid "" +"Scale selection; with Ctrl to scale uniformly; with Shift to scale around rotation center" +msgstr "" + +#: ../../po/../src/seltrans.cpp:519 +msgid "" +"Skew selection; with Ctrl to snap angle; with Shift to " +"skew around the opposite side" +msgstr "" + +#: ../../po/../src/seltrans.cpp:520 +msgid "" +"Rotate selection; with Ctrl to snap angle; with Shift " +"to rotate around the opposite corner" +msgstr "" + +#: ../../po/../src/seltrans.cpp:829 ../../po/../src/seltrans.cpp:909 +#, c-format +msgid "Scale: %0.2f%% x %0.2f%%; with Ctrl to lock ratio" +msgstr "" + +#. TRANSLATORS: don't modify the first ";" (it will NOT be displayed as ";" - only the second one will be) +#: ../../po/../src/seltrans.cpp:984 +#, c-format +msgid "Skew: %0.2f°; with Ctrl to snap angle" +msgstr "" + +#. TRANSLATORS: don't modify the first ";" (it will NOT be displayed as ";" - only the second one will be) +#: ../../po/../src/seltrans.cpp:1035 +#, c-format +msgid "Rotate: %0.2f°; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/seltrans.cpp:1090 +#, fuzzy, c-format +msgid "Move center to %s, %s" +msgstr "%s ilə Körpülə" + +#: ../../po/../src/slideshow.cpp:90 +#, fuzzy +msgid "Inkscape slideshow" +msgstr "Sodipodi" + +#: ../../po/../src/sp-anchor.cpp:181 +#, fuzzy, c-format +msgid "Link to %s" +msgstr "%s ilə Körpülə" + +#: ../../po/../src/sp-anchor.cpp:185 +#, fuzzy +msgid "Link without URI" +msgstr "%s ilə Körpülə" + +#: ../../po/../src/sp-ellipse.cpp:438 ../../po/../src/sp-ellipse.cpp:870 +#, fuzzy +msgid "Ellipse" +msgstr "Elips" + +#: ../../po/../src/sp-ellipse.cpp:583 +msgid "Circle" +msgstr "" + +#: ../../po/../src/sp-ellipse.cpp:865 +#, fuzzy +msgid "Segment" +msgstr "Elips" + +#: ../../po/../src/sp-ellipse.cpp:867 +msgid "Arc" +msgstr "" + +#. TRANSLATORS: "Flow region" is an area where text is allowed to flow +#: ../../po/../src/sp-flowregion.cpp:276 +#, fuzzy +msgid "Flow region" +msgstr "Körpünü təqib et" + +#. TRANSLATORS: A region "cut out of" a flow region; text is not allowed to flow inside the +#. * flow excluded region. flowRegionExclude in SVG 1.2: see +#. * http://www.w3.org/TR/2004/WD-SVG12-20041027/flow.html#flowRegion-elem and +#. * http://www.w3.org/TR/2004/WD-SVG12-20041027/flow.html#flowRegionExclude-elem. +#: ../../po/../src/sp-flowregion.cpp:493 +msgid "Flow excluded region" +msgstr "" + +#: ../../po/../src/sp-flowtext.cpp:355 +#, c-format +msgid "Flowed text (%d characters)" +msgstr "" + +#: ../../po/../src/sp-flowtext.cpp:357 +#, c-format +msgid "Linked flowed text (%d characters)" +msgstr "" + +#: ../../po/../src/sp-guide.cpp:290 +msgid "vertical guideline" +msgstr "" + +#: ../../po/../src/sp-guide.cpp:292 +#, fuzzy +msgid "horizontal guideline" +msgstr "üfüqi hərəkət" + +#: ../../po/../src/sp-image.cpp:835 +msgid "embedded" +msgstr "" + +#: ../../po/../src/sp-image.cpp:839 +msgid "(null_pointer)" +msgstr "" + +#: ../../po/../src/sp-image.cpp:843 +#, c-format +msgid "Image with bad reference: %s" +msgstr "" + +#: ../../po/../src/sp-image.cpp:844 +#, c-format +msgid "Image %d × %d: %s" +msgstr "" + +#: ../../po/../src/sp-item-group.cpp:390 +#, fuzzy, c-format +msgid "Group of %d object" +msgid_plural "Group of %d objects" +msgstr[0] "%d cismin qrupu" +msgstr[1] "%d cismin qrupu" + +#: ../../po/../src/sp-item.cpp:720 +msgid "Object" +msgstr "Cism" + +#: ../../po/../src/sp-line.cpp:202 +#, fuzzy +msgid "Line" +msgstr "Elips" + +#. TRANSLATORS COMMENT: %s is either "outset" or "inset" depending on sign +#: ../../po/../src/sp-offset.cpp:433 +#, c-format +msgid "Linked offset, %s by %f pt" +msgstr "" + +#: ../../po/../src/sp-offset.cpp:434 ../../po/../src/sp-offset.cpp:438 +#, fuzzy +msgid "outset" +msgstr "Seçili cığırları kombinə et" + +#: ../../po/../src/sp-offset.cpp:434 ../../po/../src/sp-offset.cpp:438 +#, fuzzy +msgid "inset" +msgstr "inç" + +#. TRANSLATORS COMMENT: %s is either "outset" or "inset" depending on sign +#: ../../po/../src/sp-offset.cpp:437 +#, c-format +msgid "Dynamic offset, %s by %f pt" +msgstr "" + +#: ../../po/../src/sp-path.cpp:127 +#, fuzzy, c-format +msgid "Path (%i node)" +msgid_plural "Path (%i nodes)" +msgstr[0] "%s ilə Körpülə" +msgstr[1] "%s ilə Körpülə" + +#: ../../po/../src/sp-polygon.cpp:216 +#, fuzzy +msgid "Polygon" +msgstr "Elips" + +#: ../../po/../src/sp-polyline.cpp:179 +#, fuzzy +msgid "Polyline" +msgstr "Elips" + +#: ../../po/../src/sp-rect.cpp:250 +#, fuzzy +msgid "Rectangle" +msgstr "Düzbucaqlı Dördbucaq" + +#. TRANSLATORS: since turn count isn't an integer, please adjust the +#. string as needed to deal with an localized plural forms. +#: ../../po/../src/sp-spiral.cpp:305 +#, c-format +msgid "Spiral with %3f turns" +msgstr "" + +#: ../../po/../src/sp-star.cpp:288 +#, c-format +msgid "Star with %d vertex" +msgid_plural "Star with %d vertices" +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/sp-star.cpp:292 +#, c-format +msgid "Polygon with %d vertex" +msgid_plural "Polygon with %d vertices" +msgstr[0] "" +msgstr[1] "" + +#. TRANSLATORS: For description of font with no name. +#: ../../po/../src/sp-text.cpp:420 +msgid "<no name found>" +msgstr "" + +#: ../../po/../src/sp-text.cpp:426 +#, fuzzy, c-format +msgid "Text on path (%s, %s)" +msgstr "%s ilə Körpülə" + +#: ../../po/../src/sp-text.cpp:427 +#, fuzzy, c-format +msgid "Text (%s, %s)" +msgstr "%s ilə Körpülə" + +#. TRANSLATORS: Used for statusbar description for long chains: +#. * "Clone of: Clone of: ... in Layer 1". +#: ../../po/../src/sp-use.cpp:317 +#, fuzzy +msgid "..." +msgstr "_Aç" + +#: ../../po/../src/sp-use.cpp:325 +#, fuzzy, c-format +msgid "Clone of: %s" +msgstr "%s ilə Körpülə" + +#: ../../po/../src/sp-use.cpp:329 +msgid "Orphaned clone" +msgstr "" + +#: ../../po/../src/spiral-context.cpp:355 +msgid "Ctrl: snap angle" +msgstr "" + +#: ../../po/../src/spiral-context.cpp:357 +msgid "Alt: lock spiral radius" +msgstr "" + +#: ../../po/../src/spiral-context.cpp:469 +#, c-format +msgid "" +"Spiral: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/splivarot.cpp:106 +#, fuzzy +msgid "Select at least 2 paths to perform a boolean operation." +msgstr "Seçili cismləri qruplaşdır" + +#: ../../po/../src/splivarot.cpp:112 +msgid "" +"Select exactly 2 paths to perform difference, XOR, division, or path " +"cut." +msgstr "" + +#: ../../po/../src/splivarot.cpp:129 ../../po/../src/splivarot.cpp:144 +msgid "" +"Unable to determine the z-order of the objects selected for " +"difference, XOR, division, or path cut." +msgstr "" + +#: ../../po/../src/splivarot.cpp:174 +#, fuzzy +msgid "" +"One of the objects is not a path, cannot perform boolean operation." +msgstr "seçkini aşağıya çək" + +#. TRANSLATORS: "to outline" means "to convert stroke to path" +#: ../../po/../src/splivarot.cpp:554 +#, fuzzy +msgid "Select path(s) to outline." +msgstr "Seçili bölmani ara yaddaşa al" + +#. TRANSLATORS: "to outline" means "to convert stroke to path" +#: ../../po/../src/splivarot.cpp:748 +msgid "No stroked paths to outline in the selection." +msgstr "" + +#: ../../po/../src/splivarot.cpp:832 +#, fuzzy +msgid "Selected object is not a path, cannot inset/outset." +msgstr "seçkini aşağıya çək" + +#: ../../po/../src/splivarot.cpp:1040 +#, fuzzy +msgid "Select path(s) to inset/outset." +msgstr "Seçili bölmani ara yaddaşa al" + +#: ../../po/../src/splivarot.cpp:1257 +msgid "No paths to inset/outset in the selection." +msgstr "" + +#: ../../po/../src/splivarot.cpp:1390 +#, fuzzy +msgid "Select path(s) to simplify." +msgstr "Seçili bölmani ara yaddaşa al" + +#: ../../po/../src/splivarot.cpp:1417 +msgid "No paths to simplify in the selection." +msgstr "" + +#: ../../po/../src/star-context.cpp:362 +msgid "Ctrl: snap angle; keep rays radial" +msgstr "" + +#: ../../po/../src/star-context.cpp:470 +#, c-format +msgid "" +"Polygon: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/star-context.cpp:471 +#, c-format +msgid "Star: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/text-chemistry.cpp:90 +#, fuzzy +msgid "Select a text and a path to put text on path." +msgstr "Seçili cismləri qruplaşdır" + +#: ../../po/../src/text-chemistry.cpp:95 +msgid "" +"This text object is already put to a path. Remove it from the path " +"first. Use Shift+D to look up its path." +msgstr "" + +#. rect is the only SPShape which is not yet, and thus SVG forbids us from putting text on it +#: ../../po/../src/text-chemistry.cpp:101 +msgid "" +"You cannot put text on a rectangle in this version. Convert rectangle to " +"path first." +msgstr "" + +#: ../../po/../src/text-chemistry.cpp:159 +#, fuzzy +msgid "Select a text on path to remove it from path." +msgstr "Seçili cismləri qruplaşdır" + +#: ../../po/../src/text-chemistry.cpp:181 +#, fuzzy +msgid "No texts-on-paths in the selection." +msgstr "Seçili bölmani ara yaddaşa al" + +#: ../../po/../src/text-chemistry.cpp:209 +#: ../../po/../src/text-chemistry.cpp:229 +#, fuzzy +msgid "Select text(s) to remove kerns from." +msgstr "Seçkini yuxarıya çək" + +#: ../../po/../src/text-chemistry.cpp:250 +#, fuzzy +msgid "" +"Select a text and one or more paths or shapes to flow text " +"into frame." +msgstr "Seçili cismləri qruplaşdır" + +#: ../../po/../src/text-chemistry.cpp:322 +#, fuzzy +msgid "Select a flowed text to unflow it." +msgstr "Seçili bölmani ara yaddaşa al" + +#: ../../po/../src/text-context.cpp:463 +msgid "Click to edit the text, drag to select part of the text." +msgstr "" + +#: ../../po/../src/text-context.cpp:465 +msgid "" +"Click to edit the flowed text, drag to select part of the text." +msgstr "" + +#: ../../po/../src/text-context.cpp:540 +msgid "Non-printable character" +msgstr "" + +#: ../../po/../src/text-context.cpp:589 +#, c-format +msgid "Unicode: %s: %s" +msgstr "" + +#: ../../po/../src/text-context.cpp:591 ../../po/../src/text-context.cpp:855 +msgid "Unicode: " +msgstr "" + +#: ../../po/../src/text-context.cpp:615 +msgid "Current layer is hidden. Unhide it to be able to add text." +msgstr "" + +#: ../../po/../src/text-context.cpp:619 +msgid "Current layer is locked. Unlock it to be able to add text." +msgstr "" + +#: ../../po/../src/text-context.cpp:673 +#, c-format +msgid "Flowed text frame: %s × %s" +msgstr "" + +#: ../../po/../src/text-context.cpp:708 ../../po/../src/text-context.cpp:1464 +msgid "Type text; Enter to start new line." +msgstr "" + +#: ../../po/../src/text-context.cpp:719 +msgid "Flowed text is created." +msgstr "" + +#: ../../po/../src/text-context.cpp:722 +msgid "" +"The frame is too small for the current font size. Flowed text not " +"created." +msgstr "" + +#: ../../po/../src/text-context.cpp:841 +msgid "No-break space" +msgstr "" + +#: ../../po/../src/text-context.cpp:1462 +msgid "Type flowed text; Enter to start new paragraph." +msgstr "" + +#: ../../po/../src/text-context.cpp:1472 ../../po/../src/tools-switch.cpp:189 +msgid "" +"Click to select or create text, drag to create flowed text; " +"then type." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:141 +msgid "" +"To edit a path, click, Shift+click, or drag around " +"nodes to select them, then drag nodes and handles. Click on an " +"object to select." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:147 +msgid "" +"Drag to create a rectangle. Drag controls to round corners and " +"resize. Click to select." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:153 +msgid "" +"Drag to create an ellipse. Drag controls to make an arc or " +"segment. Click to select." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:159 +msgid "" +"Drag to create a star. Drag controls to edit the star shape. " +"Click to select." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:165 +msgid "" +"Drag to create a spiral. Drag controls to edit the spiral " +"shape. Click to select." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:171 +msgid "" +"Drag to create a freehand line. Start drawing with Shift to " +"append to selected path." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:177 +msgid "" +"Click or click and drag to start a path; with Shift to " +"append to selected path." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:183 +msgid "" +"Drag to paint a calligraphic stroke. Left/right arrow " +"keys adjust width, up/down adjust angle." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:195 +msgid "" +"Drag or double click to create a gradient on selected objects, " +"drag handles to adjust gradients." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:201 +msgid "" +"Click or drag around an area to zoom in, Shift+click to " +"zoom out." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:213 +msgid "Click and drag between shapes to create a connector." +msgstr "" + +#: ../../po/../src/trace/potrace/inkscape-potrace.cpp:553 +#: ../../po/../src/trace/potrace/inkscape-potrace.cpp:654 +#, c-format +msgid "Trace: %d. %ld nodes" +msgstr "" + +#: ../../po/../src/trace/trace.cpp:53 ../../po/../src/trace/trace.cpp:62 +#: ../../po/../src/trace/trace.cpp:70 +#, fuzzy +msgid "Select an image to trace" +msgstr "Seçili bölmani ara yaddaşa al" + +#: ../../po/../src/trace/trace.cpp:133 +#, fuzzy +msgid "Trace: No active document" +msgstr "Sənəd" + +#: ../../po/../src/trace/trace.cpp:154 +msgid "Trace: Image has no bitmap data" +msgstr "" + +#: ../../po/../src/trace/trace.cpp:267 +#, c-format +msgid "Trace: Done. %ld nodes created" +msgstr "" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:59 ../../po/../src/verbs.cpp:2212 +msgid "About Inkscape" +msgstr "" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:66 +msgid "_Splash" +msgstr "" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:68 +msgid "_Authors" +msgstr "" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:69 +#, fuzzy +msgid "_Translators" +msgstr "Dəyişdirmə" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:70 +#, fuzzy +msgid "_License" +msgstr "inç" + +#. TRANSLATORS: This is the filename of the `About Inkscape' picture in +#. the `screens' directory. Thus the translation of "about.svg" should be +#. the filename of its translated version, e.g. about.zh.svg for Chinese. +#. +#. N.B. about.svg changes once per release. (We should probably rename +#. the original to about-0.40.svg etc. as soon as we have a translation. +#. If we do so, then add an item to release-checklist saying that the +#. string here should be changed.) +#. FIXME? INKSCAPE_SCREENSDIR and "about.svg" are in UTF-8, not the +#. native filename encoding... and the filename passed to sp_document_new +#. should be in UTF-*8.. +#: ../../po/../src/ui/dialog/aboutbox.cpp:114 +msgid "about.svg" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:464 +msgid "Minimum horizontal gap (in px units) between bounding boxes" +msgstr "" + +#. TRANSLATORS: Horizontal gap +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:466 +#: ../../po/../src/widgets/toolbox.cpp:1556 +msgid "H:" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:474 +msgid "Minimum vertical gap (in px units) between bounding boxes" +msgstr "" + +#. TRANSLATORS: Vertical gap +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:476 +msgid "V:" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:734 +msgid "Align" +msgstr "Tərəflə" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:735 +#, fuzzy +msgid "Distribute" +msgstr "Atributlar" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:736 +msgid "Remove overlaps" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:737 +#, fuzzy +msgid "Nodes" +msgstr "Düyün" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:742 +#, fuzzy +msgid "Relative to: " +msgstr "şaquli hərəkət" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:747 +#, fuzzy +msgid "Align right sides of objects to left side of anchor" +msgstr "Seçili bölmani ara yaddaşa al" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:750 +#, fuzzy +msgid "Align left sides" +msgstr "Cism" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:753 +msgid "Center on vertical axis" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:756 +#, fuzzy +msgid "Align right sides" +msgstr "Cism" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:759 +#, fuzzy +msgid "Align left sides of objects to right side of anchor" +msgstr "Seçili bölmani ara yaddaşa al" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:762 +#, fuzzy +msgid "Align bottoms of objects to top of anchor" +msgstr "Seçili bölmani ara yaddaşa al" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:765 +#, fuzzy +msgid "Align tops" +msgstr "Cism" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:768 +#, fuzzy +msgid "Center on horizontal axis" +msgstr "Seçkini bir lay yüksəlt" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:771 +#, fuzzy +msgid "Align bottoms" +msgstr "Cism" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:774 +#, fuzzy +msgid "Align tops of objects to bottom of anchor" +msgstr "Seçili bölmani ara yaddaşa al" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:779 +#, fuzzy +msgid "Align baseline anchors of texts vertically" +msgstr "Seçkini bir lay yüksəlt" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:782 +#, fuzzy +msgid "Align baseline anchors of texts horizontally" +msgstr "Seçkini bir lay yüksəlt" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:787 +msgid "Make horizontal gaps between objects equal" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:791 +#, fuzzy +msgid "Distribute left sides equidistantly" +msgstr "Seçkini bir lay yüksəlt" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:794 +#, fuzzy +msgid "Distribute centers equidistantly horizontally" +msgstr "Seçkini bir lay yüksəlt" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:797 +#, fuzzy +msgid "Distribute right sides equidistantly" +msgstr "Seçkini bir lay yüksəlt" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:801 +msgid "Make vertical gaps between objects equal" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:805 +#, fuzzy +msgid "Distribute tops equidistantly" +msgstr "Seçkini bir lay yüksəlt" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:808 +#, fuzzy +msgid "Distribute centers equidistantly vertically" +msgstr "Seçkini bir lay yüksəlt" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:811 +msgid "Distribute bottoms equidistantly" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:816 +#, fuzzy +msgid "Distribute baseline anchors of texts horizontally" +msgstr "Seçkini bir lay yüksəlt" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:819 +#, fuzzy +msgid "Distribute baseline anchors of texts vertically" +msgstr "Seçkini bir lay yüksəlt" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:824 +msgid "Randomize centers in both dimensions" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:827 +msgid "Unclump objects: try to equalize edge-to-edge distances" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:832 +msgid "" +"Move objects as little as possible so that their bounding boxes do not " +"overlap" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:837 +#, fuzzy +msgid "Align selected nodes horizontally" +msgstr "Seçkini bir lay yüksəlt" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:840 +#, fuzzy +msgid "Align selected nodes vertically" +msgstr "Seçkini bir lay yüksəlt" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:843 +#, fuzzy +msgid "Distribute selected nodes horizontally" +msgstr "Seçkini bir lay yüksəlt" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:846 +#, fuzzy +msgid "Distribute selected nodes vertically" +msgstr "Seçkini bir lay yüksəlt" + +#. Rest of the widgetry +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:851 +msgid "Last selected" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:852 +msgid "First selected" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:853 +msgid "Biggest item" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:854 +msgid "Smallest item" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:856 +#: ../../po/../src/widgets/desktop-widget.cpp:1065 +msgid "Drawing" +msgstr "" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:91 +msgid "Metadata 1" +msgstr "" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:92 +msgid "Metadata 2" +msgstr "" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:187 +msgid "X coordinate of grid origin" +msgstr "" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:189 +msgid "Y coordinate of grid origin" +msgstr "" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:191 +msgid "Distance of vertical grid lines" +msgstr "" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:193 +#, fuzzy +msgid "Distance of horizontal grid lines" +msgstr "üfüqi hərəkət" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:197 +msgid "Max. snapping distance from grid" +msgstr "" + +#: ../../po/../src/ui/dialog/export.cpp:34 +msgid "Export" +msgstr "Ver" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:36 +msgid "Fill" +msgstr "Doldur" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:37 +#, fuzzy +msgid "Stroke Paint" +msgstr "Nöqtə" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:38 +#, fuzzy +msgid "Stroke Style" +msgstr "Doldurma qurğuları" + +#: ../../po/../src/ui/dialog/find.cpp:34 +#, fuzzy +msgid "Find" +msgstr "Qəfəs" + +#: ../../po/../src/ui/dialog/memory.cpp:96 +#, fuzzy +msgid "Heap" +msgstr "_Yardım" + +#: ../../po/../src/ui/dialog/memory.cpp:97 +#, fuzzy +msgid "In Use" +msgstr "inç" + +#. TRANSLATORS: "Slack" refers to memory which is in the heap but currently unused. +#. More typical usage is to call this memory "free" rather than "slack". +#: ../../po/../src/ui/dialog/memory.cpp:100 +#, fuzzy +msgid "Slack" +msgstr "Ulduz" + +#: ../../po/../src/ui/dialog/memory.cpp:101 +#, fuzzy +msgid "Total" +msgstr "Fayl" + +#: ../../po/../src/ui/dialog/memory.cpp:141 +#: ../../po/../src/ui/dialog/memory.cpp:147 +#: ../../po/../src/ui/dialog/memory.cpp:154 +#: ../../po/../src/ui/dialog/memory.cpp:186 +#, fuzzy +msgid "Unknown" +msgstr "Naməlum üzv :-(" + +#: ../../po/../src/ui/dialog/memory.cpp:167 +msgid "Combined" +msgstr "" + +#: ../../po/../src/ui/dialog/memory.cpp:209 +#, fuzzy +msgid "Recalculate" +msgstr "Düzbucaqlı Dördbucaq" + +#: ../../po/../src/ui/dialog/messages.cpp:74 +#, fuzzy +msgid "Ready." +msgstr "Qırmızı:" + +#: ../../po/../src/ui/dialog/messages.cpp:75 +msgid "" +"Enable log display by setting dialogs.debug 'redirect' attribute to 1 in " +"preferences.xml" +msgstr "" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:184 +msgid "_Execute Python" +msgstr "" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:186 +msgid "_Execute Perl" +msgstr "" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:195 +msgid "Script" +msgstr "" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:205 +#, fuzzy +msgid "Output" +msgstr "Kəs" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:215 +msgid "Errors" +msgstr "" + +#. Dialog organization +#: ../../po/../src/ui/dialog/session-player.cpp:73 +#, fuzzy +msgid "Session file" +msgstr "Faylı qeyd et" + +#: ../../po/../src/ui/dialog/session-player.cpp:74 +#, fuzzy +msgid "Playback controls" +msgstr "Oaf seçənəkləri" + +#: ../../po/../src/ui/dialog/session-player.cpp:75 +#, fuzzy +msgid "Message information" +msgstr "Dönüşdürməni sıfırla" + +#. Active session file display +#. fixme: Does this mean the active file for the session, or the file for the active session? +#. Please indicate which with a TRANSLATORS comment. +#: ../../po/../src/ui/dialog/session-player.cpp:85 +msgid "Active session file:" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:86 +msgid "Delay (milliseconds):" +msgstr "" + +#. Unload/load buttons +#: ../../po/../src/ui/dialog/session-player.cpp:94 +#, fuzzy +msgid "Close file" +msgstr "Yeni Görünüş" + +#: ../../po/../src/ui/dialog/session-player.cpp:95 +#, fuzzy +msgid "Open new file" +msgstr "Yeni çəkiliş aç" + +#: ../../po/../src/ui/dialog/session-player.cpp:96 +msgid "Set delay" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:138 +#, fuzzy +msgid "Rewind" +msgstr "Qırmızı:" + +#: ../../po/../src/ui/dialog/session-player.cpp:139 +msgid "Go back one change" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:140 +#, fuzzy +msgid "Pause" +msgstr "Yapışdır" + +#: ../../po/../src/ui/dialog/session-player.cpp:141 +msgid "Go forward one change" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:142 +msgid "Play" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:177 +#: ../../po/../src/verbs.cpp:1573 +msgid "Open session file" +msgstr "" + +#. ##Set up the Potrace panel +#. #### brightness #### +#. #### Multiple scanning#### +#. ----Hbox1 +#: ../../po/../src/ui/dialog/tracedialog.cpp:345 +#: ../../po/../src/ui/dialog/tracedialog.cpp:428 +#, fuzzy +msgid "Brightness" +msgstr "Hündürlük" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:348 +msgid "Trace by a given brightness level" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:355 +msgid "Brightness cutoff for black/white" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:362 +#, fuzzy +msgid "Image Brightness" +msgstr "Üzv Xassələri" + +#. #### canny edge detection #### +#. TRANSLATORS: "Canny" is the name of the inventor of this edge detection method +#: ../../po/../src/ui/dialog/tracedialog.cpp:369 +msgid "Optimal Edge Detection (Canny)" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:372 +msgid "Trace with edge detection by J. Canny's algorithm" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:388 +msgid "Brightness cutoff for adjacent pixels (determines edge thickness)" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:395 +#, fuzzy +msgid "Edge Detection" +msgstr "Seçki" + +#. #### quantization #### +#. TRANSLATORS: Color Quantization: the process of reducing the number of colors +#. in an image by selecting an optimized set of representative colors and then +#. re-applying this reduced set to the original image. +#: ../../po/../src/ui/dialog/tracedialog.cpp:404 +#, fuzzy +msgid "Color Quantization" +msgstr "Rəng bit xəritəsi" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:407 +msgid "Trace along the boundaries of reduced colors" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:414 +msgid "The number of reduced colors" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:416 +#, fuzzy +msgid "Colors:" +msgstr "Rəng:" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:421 +msgid "Quantization / Reduction" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:431 +msgid "Trace the given number of brightness levels" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:438 +msgid "Scans:" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:440 +msgid "The desired number of scans" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:448 +msgid "Trace the given number of reduced colors" +msgstr "" + +#. ---Hbox3 +#: ../../po/../src/ui/dialog/tracedialog.cpp:454 +msgid "Monochrome" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:457 +msgid "Same as Color, but convert result to grayscale" +msgstr "" + +#. TRANSLATORS: "Stack" is a verb here +#: ../../po/../src/ui/dialog/tracedialog.cpp:460 +#, fuzzy +msgid "Stack" +msgstr "Ulduz" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:463 +msgid "" +"Stack scans vertically (no gaps) or tile horizontally (usually with gaps)" +msgstr "" + +#. TRANSLATORS: "Smooth" is a verb here +#: ../../po/../src/ui/dialog/tracedialog.cpp:466 +msgid "Smooth" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:469 +msgid "Apply Gaussian blur to the bitmap before tracing" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:473 +msgid "Multiple Scanning" +msgstr "" + +#. #### Preview #### +#: ../../po/../src/ui/dialog/tracedialog.cpp:479 +#: ../../po/../src/ui/dialog/tracedialog.cpp:489 +#, fuzzy +msgid "Preview" +msgstr "Yeni Nümayiş" + +#. do not expand +#: ../../po/../src/ui/dialog/tracedialog.cpp:483 +msgid "Preview the result without actual tracing" +msgstr "" + +#. #### swap black and white #### +#: ../../po/../src/ui/dialog/tracedialog.cpp:495 +msgid "Invert" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:499 +msgid "Invert black and white regions for single traces" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:503 +msgid "Thanks to Peter Selinger, http://potrace.sourceforge.net" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:506 +#, fuzzy +msgid "Credits" +msgstr "Rəng bit xəritəsi" + +#. done +#. TRANSLATORS: Potrace is an application for transforming bitmaps into +#. vector graphics (http://potrace.sourceforge.net/) +#: ../../po/../src/ui/dialog/tracedialog.cpp:514 +#, fuzzy +msgid "Potrace" +msgstr "Nöqtə" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:527 +#, fuzzy +msgid "Abort a trace in progress" +msgstr "Fayl ver" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:531 +msgid "Execute the trace" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:80 +#: ../../po/../src/ui/dialog/transformation.cpp:90 +#, fuzzy +msgid "_Horizontal" +msgstr "üfüqi hərəkət" + +#: ../../po/../src/ui/dialog/transformation.cpp:80 +msgid "Horizontal displacement (relative) or position (absolute)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:82 +#: ../../po/../src/ui/dialog/transformation.cpp:92 +#, fuzzy +msgid "_Vertical" +msgstr "Seçkini bir lay yüksəlt" + +#: ../../po/../src/ui/dialog/transformation.cpp:82 +msgid "Vertical displacement (relative) or position (absolute)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:84 +#, fuzzy +msgid "_Width" +msgstr "En:" + +#: ../../po/../src/ui/dialog/transformation.cpp:84 +msgid "Horizontal size increment (absolute or percentage)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:86 +#, fuzzy +msgid "_Height" +msgstr "Hündürlük:" + +#: ../../po/../src/ui/dialog/transformation.cpp:86 +msgid "Vertical size increment (absolute or percentage)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:88 +#, fuzzy +msgid "A_ngle" +msgstr "bucaq" + +#: ../../po/../src/ui/dialog/transformation.cpp:88 +msgid "Rotation angle (positive = counterclockwise)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:90 +msgid "" +"Horizontal skew angle (positive = counterclockwise), or absolute " +"displacement, or percentage displacement" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:92 +msgid "" +"Vertical skew angle (positive = counterclockwise), or absolute displacement, " +"or percentage displacement" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:95 +#, fuzzy +msgid "Transformation matrix element A" +msgstr "Dəyişdirmə" + +#: ../../po/../src/ui/dialog/transformation.cpp:96 +#, fuzzy +msgid "Transformation matrix element B" +msgstr "Dəyişdirmə" + +#: ../../po/../src/ui/dialog/transformation.cpp:97 +#, fuzzy +msgid "Transformation matrix element C" +msgstr "Dəyişdirmə" + +#: ../../po/../src/ui/dialog/transformation.cpp:98 +#, fuzzy +msgid "Transformation matrix element D" +msgstr "Dəyişdirmə" + +#: ../../po/../src/ui/dialog/transformation.cpp:99 +#, fuzzy +msgid "Transformation matrix element E" +msgstr "Dəyişdirmə" + +#: ../../po/../src/ui/dialog/transformation.cpp:100 +#, fuzzy +msgid "Transformation matrix element F" +msgstr "Dəyişdirmə" + +#: ../../po/../src/ui/dialog/transformation.cpp:102 +#, fuzzy +msgid "Rela_tive move" +msgstr "şaquli hərəkət" + +#: ../../po/../src/ui/dialog/transformation.cpp:102 +msgid "" +"Add the specified relative displacement to the current position; otherwise, " +"edit the current absolute position directly" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:103 +msgid "Scale proportionally" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:103 +msgid "Preserve the width/height ratio of the scaled objects" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:104 +msgid "Apply to each _object separately" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:104 +msgid "" +"Apply the scale/rotate/skew to each selected object separately; otherwise, " +"transform the selection as a whole" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:105 +msgid "Edit c_urrent matrix" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:105 +msgid "" +"Edit the current transform= matrix; otherwise, post-multiply transform= by " +"this matrix" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:115 +#, fuzzy +msgid "_Move" +msgstr "Daşı" + +#: ../../po/../src/ui/dialog/transformation.cpp:118 +#, fuzzy +msgid "_Scale" +msgstr "Miqyas" + +#: ../../po/../src/ui/dialog/transformation.cpp:121 +#, fuzzy +msgid "_Rotate" +msgstr "Çevir" + +#: ../../po/../src/ui/dialog/transformation.cpp:124 +#, fuzzy +msgid "Ske_w" +msgstr "Nöqtə" + +#: ../../po/../src/ui/dialog/transformation.cpp:127 +msgid "Matri_x" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:141 +msgid "Reset the values on the current tab to defaults" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:148 +#, fuzzy +msgid "Apply transformation to selection" +msgstr "Seç və döndər" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:43 +msgid "_Use SSL" +msgstr "" + +#. Construct dialog interface +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:68 +#, fuzzy +msgid "_Server:" +msgstr "Fayl" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:69 +#, fuzzy +msgid "_Username:" +msgstr "Fayl adı:" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:70 +msgid "_Password:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:71 +msgid "P_ort:" +msgstr "" + +#. Buttons +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:99 +#, fuzzy +msgid "Connect" +msgstr "İçindəkilər" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:126 +msgid "Establishing connection to Jabber server %1 as user %2" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:131 +msgid "Failed to establish connection to Jabber server %1" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:136 +msgid "Authentication failed on Jabber server %1 as %2" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:141 +msgid "SSL initialization failed when connecting to Jabber server %1" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:147 +msgid "Connected to Jabber server %1 as %2" +msgstr "" + +#. Construct labels +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:75 +msgid "Chatroom _name:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:76 +msgid "Chatroom _server:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:77 +msgid "Chatroom _password:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:78 +msgid "Chatroom _handle:" +msgstr "" + +#. Button setup and callback registration +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:97 +msgid "Connect to chatroom" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:132 +msgid "Synchronizing with chatroom %1@%2 using the handle %3" +msgstr "" + +#. Construct dialog interface +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:78 +msgid "_User's Jabber ID:" +msgstr "" + +#. Buttons +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:82 +msgid "_Invite user" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:83 +#, fuzzy +msgid "_Cancel" +msgstr "Dəyişdir" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:94 +msgid "Buddy List" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:170 +msgid "Sending whiteboard invitation to %1" +msgstr "" + +#. FIXME: strings are replaced by placeholders, NOT to be translated until the code is enabled +#. See http://sourceforge.net/mailarchive/message.php?msg_id=11746016 for details +#. File menu +#. Edit menu +#. View menu +#. Layer menu +#. Object menu +#. Path menu +#. add(Gtk::StockItem(CLEANUP, _("PLACEHOLDER, do not translate"))); (using Gtk::Stock::CLEAR) +#. Text menu +#. About menu +#. Tools toolbox +#. Select Tool controls +#. Node Tool controls +#. Calligraphy Tool controls +#. Session playback controls +#: ../../po/../src/ui/stock-items.cpp:34 ../../po/../src/ui/stock-items.cpp:35 +#: ../../po/../src/ui/stock-items.cpp:36 ../../po/../src/ui/stock-items.cpp:37 +#: ../../po/../src/ui/stock-items.cpp:38 ../../po/../src/ui/stock-items.cpp:39 +#: ../../po/../src/ui/stock-items.cpp:40 ../../po/../src/ui/stock-items.cpp:41 +#: ../../po/../src/ui/stock-items.cpp:42 ../../po/../src/ui/stock-items.cpp:43 +#: ../../po/../src/ui/stock-items.cpp:46 ../../po/../src/ui/stock-items.cpp:47 +#: ../../po/../src/ui/stock-items.cpp:48 ../../po/../src/ui/stock-items.cpp:49 +#: ../../po/../src/ui/stock-items.cpp:50 ../../po/../src/ui/stock-items.cpp:51 +#: ../../po/../src/ui/stock-items.cpp:52 ../../po/../src/ui/stock-items.cpp:53 +#: ../../po/../src/ui/stock-items.cpp:54 ../../po/../src/ui/stock-items.cpp:55 +#: ../../po/../src/ui/stock-items.cpp:56 ../../po/../src/ui/stock-items.cpp:57 +#: ../../po/../src/ui/stock-items.cpp:58 ../../po/../src/ui/stock-items.cpp:59 +#: ../../po/../src/ui/stock-items.cpp:62 ../../po/../src/ui/stock-items.cpp:63 +#: ../../po/../src/ui/stock-items.cpp:64 ../../po/../src/ui/stock-items.cpp:65 +#: ../../po/../src/ui/stock-items.cpp:66 ../../po/../src/ui/stock-items.cpp:67 +#: ../../po/../src/ui/stock-items.cpp:68 ../../po/../src/ui/stock-items.cpp:69 +#: ../../po/../src/ui/stock-items.cpp:70 ../../po/../src/ui/stock-items.cpp:71 +#: ../../po/../src/ui/stock-items.cpp:72 ../../po/../src/ui/stock-items.cpp:73 +#: ../../po/../src/ui/stock-items.cpp:74 ../../po/../src/ui/stock-items.cpp:75 +#: ../../po/../src/ui/stock-items.cpp:76 ../../po/../src/ui/stock-items.cpp:77 +#: ../../po/../src/ui/stock-items.cpp:78 ../../po/../src/ui/stock-items.cpp:79 +#: ../../po/../src/ui/stock-items.cpp:80 ../../po/../src/ui/stock-items.cpp:81 +#: ../../po/../src/ui/stock-items.cpp:82 ../../po/../src/ui/stock-items.cpp:83 +#: ../../po/../src/ui/stock-items.cpp:84 ../../po/../src/ui/stock-items.cpp:85 +#: ../../po/../src/ui/stock-items.cpp:86 ../../po/../src/ui/stock-items.cpp:87 +#: ../../po/../src/ui/stock-items.cpp:88 ../../po/../src/ui/stock-items.cpp:89 +#: ../../po/../src/ui/stock-items.cpp:92 ../../po/../src/ui/stock-items.cpp:93 +#: ../../po/../src/ui/stock-items.cpp:94 ../../po/../src/ui/stock-items.cpp:95 +#: ../../po/../src/ui/stock-items.cpp:96 ../../po/../src/ui/stock-items.cpp:97 +#: ../../po/../src/ui/stock-items.cpp:98 ../../po/../src/ui/stock-items.cpp:99 +#: ../../po/../src/ui/stock-items.cpp:100 +#: ../../po/../src/ui/stock-items.cpp:101 +#: ../../po/../src/ui/stock-items.cpp:102 +#: ../../po/../src/ui/stock-items.cpp:103 +#: ../../po/../src/ui/stock-items.cpp:104 +#: ../../po/../src/ui/stock-items.cpp:105 +#: ../../po/../src/ui/stock-items.cpp:108 +#: ../../po/../src/ui/stock-items.cpp:109 +#: ../../po/../src/ui/stock-items.cpp:110 +#: ../../po/../src/ui/stock-items.cpp:111 +#: ../../po/../src/ui/stock-items.cpp:112 +#: ../../po/../src/ui/stock-items.cpp:113 +#: ../../po/../src/ui/stock-items.cpp:114 +#: ../../po/../src/ui/stock-items.cpp:115 +#: ../../po/../src/ui/stock-items.cpp:116 +#: ../../po/../src/ui/stock-items.cpp:117 +#: ../../po/../src/ui/stock-items.cpp:118 +#: ../../po/../src/ui/stock-items.cpp:119 +#: ../../po/../src/ui/stock-items.cpp:120 +#: ../../po/../src/ui/stock-items.cpp:121 +#: ../../po/../src/ui/stock-items.cpp:122 +#: ../../po/../src/ui/stock-items.cpp:123 +#: ../../po/../src/ui/stock-items.cpp:124 +#: ../../po/../src/ui/stock-items.cpp:125 +#: ../../po/../src/ui/stock-items.cpp:126 +#: ../../po/../src/ui/stock-items.cpp:127 +#: ../../po/../src/ui/stock-items.cpp:130 +#: ../../po/../src/ui/stock-items.cpp:131 +#: ../../po/../src/ui/stock-items.cpp:132 +#: ../../po/../src/ui/stock-items.cpp:133 +#: ../../po/../src/ui/stock-items.cpp:134 +#: ../../po/../src/ui/stock-items.cpp:135 +#: ../../po/../src/ui/stock-items.cpp:136 +#: ../../po/../src/ui/stock-items.cpp:137 +#: ../../po/../src/ui/stock-items.cpp:138 +#: ../../po/../src/ui/stock-items.cpp:139 +#: ../../po/../src/ui/stock-items.cpp:140 +#: ../../po/../src/ui/stock-items.cpp:141 +#: ../../po/../src/ui/stock-items.cpp:142 +#: ../../po/../src/ui/stock-items.cpp:143 +#: ../../po/../src/ui/stock-items.cpp:144 +#: ../../po/../src/ui/stock-items.cpp:145 +#: ../../po/../src/ui/stock-items.cpp:146 +#: ../../po/../src/ui/stock-items.cpp:150 +#: ../../po/../src/ui/stock-items.cpp:151 +#: ../../po/../src/ui/stock-items.cpp:152 +#: ../../po/../src/ui/stock-items.cpp:153 +#: ../../po/../src/ui/stock-items.cpp:156 +#: ../../po/../src/ui/stock-items.cpp:157 +#: ../../po/../src/ui/stock-items.cpp:158 +#: ../../po/../src/ui/stock-items.cpp:161 +#: ../../po/../src/ui/stock-items.cpp:162 +#: ../../po/../src/ui/stock-items.cpp:163 +#: ../../po/../src/ui/stock-items.cpp:164 +#: ../../po/../src/ui/stock-items.cpp:165 +#: ../../po/../src/ui/stock-items.cpp:166 +#: ../../po/../src/ui/stock-items.cpp:167 +#: ../../po/../src/ui/stock-items.cpp:168 +#: ../../po/../src/ui/stock-items.cpp:169 +#: ../../po/../src/ui/stock-items.cpp:170 +#: ../../po/../src/ui/stock-items.cpp:171 +#: ../../po/../src/ui/stock-items.cpp:172 +#: ../../po/../src/ui/stock-items.cpp:175 +#: ../../po/../src/ui/stock-items.cpp:176 +#: ../../po/../src/ui/stock-items.cpp:177 +#: ../../po/../src/ui/stock-items.cpp:178 +#: ../../po/../src/ui/stock-items.cpp:181 +#: ../../po/../src/ui/stock-items.cpp:182 +#: ../../po/../src/ui/stock-items.cpp:183 +#: ../../po/../src/ui/stock-items.cpp:184 +#: ../../po/../src/ui/stock-items.cpp:185 +#: ../../po/../src/ui/stock-items.cpp:186 +#: ../../po/../src/ui/stock-items.cpp:187 +#: ../../po/../src/ui/stock-items.cpp:188 +#: ../../po/../src/ui/stock-items.cpp:189 +#: ../../po/../src/ui/stock-items.cpp:190 +#: ../../po/../src/ui/stock-items.cpp:191 +#: ../../po/../src/ui/stock-items.cpp:194 +#: ../../po/../src/ui/stock-items.cpp:195 +#: ../../po/../src/ui/stock-items.cpp:198 +#: ../../po/../src/ui/stock-items.cpp:199 +#: ../../po/../src/ui/stock-items.cpp:200 +#: ../../po/../src/ui/stock-items.cpp:201 +#: ../../po/../src/ui/stock-items.cpp:202 +msgid "PLACEHOLDER, do not translate" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:88 +msgid "small" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:89 +msgid "medium" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:90 +#, fuzzy +msgid "large" +msgstr "Səhifə" + +#: ../../po/../src/ui/widget/panel.cpp:91 +msgid "huge" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:106 +#, fuzzy +msgid "List" +msgstr "inç" + +#: ../../po/../src/ui/widget/selected-style.cpp:67 +msgid "F:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:68 +msgid "S:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:69 +msgid "O:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:95 +msgid "N/A" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:98 +#: ../../po/../src/ui/widget/selected-style.cpp:712 +#, fuzzy +msgid "Nothing selected" +msgstr "Seçili cismləri qruplaşdır" + +#: ../../po/../src/ui/widget/selected-style.cpp:103 +msgid "No fill" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:103 +#, fuzzy +msgid "No stroke" +msgstr "Nöqtə" + +#: ../../po/../src/ui/widget/selected-style.cpp:105 +#: ../../po/../src/widgets/paint-selector.cpp:190 +#, fuzzy +msgid "Pattern" +msgstr "Yapışdır" + +#: ../../po/../src/ui/widget/selected-style.cpp:108 +#: ../../po/../src/widgets/paint-selector.cpp:885 +#, fuzzy +msgid "Pattern fill" +msgstr "Yapışdır" + +#: ../../po/../src/ui/widget/selected-style.cpp:108 +#, fuzzy +msgid "Pattern stroke" +msgstr "Seçili cismləri qruplaşdır" + +#: ../../po/../src/ui/widget/selected-style.cpp:110 +#, fuzzy +msgid "L Gradient" +msgstr "Yaşıl:" + +#: ../../po/../src/ui/widget/selected-style.cpp:113 +#, fuzzy +msgid "Linear gradient fill" +msgstr "Sənəd" + +#: ../../po/../src/ui/widget/selected-style.cpp:113 +#, fuzzy +msgid "Linear gradient stroke" +msgstr "Sənəd" + +#: ../../po/../src/ui/widget/selected-style.cpp:115 +#, fuzzy +msgid "R Gradient" +msgstr "Yaşıl:" + +#: ../../po/../src/ui/widget/selected-style.cpp:118 +msgid "Radial gradient fill" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:118 +msgid "Radial gradient stroke" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:120 +#, fuzzy +msgid "Different" +msgstr "Dərəcə" + +#: ../../po/../src/ui/widget/selected-style.cpp:123 +#, fuzzy +msgid "Different fills" +msgstr "Dərəcə" + +#: ../../po/../src/ui/widget/selected-style.cpp:123 +#, fuzzy +msgid "Different strokes" +msgstr "Dərəcə" + +#: ../../po/../src/ui/widget/selected-style.cpp:125 +#, fuzzy +msgid "Unset" +msgstr "inç" + +#. TRANSLATORS COMMENT: unset is a verb here +#: ../../po/../src/ui/widget/selected-style.cpp:128 +#: ../../po/../src/ui/widget/selected-style.cpp:182 +#, fuzzy +msgid "Unset fill" +msgstr "_Fayl" + +#: ../../po/../src/ui/widget/selected-style.cpp:128 +#: ../../po/../src/ui/widget/selected-style.cpp:182 +msgid "Unset stroke" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:131 +#, fuzzy +msgid "Flat color fill" +msgstr "rəng" + +#: ../../po/../src/ui/widget/selected-style.cpp:131 +#, fuzzy +msgid "Flat color stroke" +msgstr "rəng" + +#. TRANSLATOR COMMENT: A means "Averaged" +#: ../../po/../src/ui/widget/selected-style.cpp:134 +msgid "A" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:137 +#, fuzzy +msgid "Fill is averaged over selected objects" +msgstr "Seçili cismləri qruplaşdır" + +#: ../../po/../src/ui/widget/selected-style.cpp:137 +#, fuzzy +msgid "Stroke is averaged over selected objects" +msgstr "Seçili cismləri qruplaşdır" + +#. TRANSLATOR COMMENT: M means "Multiple" +#: ../../po/../src/ui/widget/selected-style.cpp:140 +msgid "M" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:143 +#, fuzzy +msgid "Multiple selected objects have the same fill" +msgstr "Seçkini bir lay yüksəlt" + +#: ../../po/../src/ui/widget/selected-style.cpp:143 +#, fuzzy +msgid "Multiple selected objects have the same stroke" +msgstr "Seçkini bir lay yüksəlt" + +#: ../../po/../src/ui/widget/selected-style.cpp:145 +#, fuzzy +msgid "Edit fill..." +msgstr "Düzəlt" + +#: ../../po/../src/ui/widget/selected-style.cpp:145 +#, fuzzy +msgid "Edit stroke..." +msgstr "Düzəlt" + +#: ../../po/../src/ui/widget/selected-style.cpp:149 +#, fuzzy +msgid "Last set color" +msgstr "rəng" + +#: ../../po/../src/ui/widget/selected-style.cpp:153 +#, fuzzy +msgid "Last selected color" +msgstr "Seçili cığırları kombinə et" + +#: ../../po/../src/ui/widget/selected-style.cpp:157 +msgid "White" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:161 +#: ../../po/../src/widgets/sp-color-scales.cpp:461 +#: ../../po/../src/widgets/sp-color-scales.cpp:462 +#, fuzzy +msgid "Black" +msgstr "Qara:" + +#: ../../po/../src/ui/widget/selected-style.cpp:165 +#, fuzzy +msgid "Copy color" +msgstr "Başlama rəngi" + +#: ../../po/../src/ui/widget/selected-style.cpp:169 +#, fuzzy +msgid "Paste color" +msgstr "rəng" + +#: ../../po/../src/ui/widget/selected-style.cpp:173 +#, fuzzy +msgid "Swap fill and stroke" +msgstr "Doldurma qurğuları" + +#: ../../po/../src/ui/widget/selected-style.cpp:177 +msgid "Make fill opaque" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:177 +msgid "Make stroke opaque" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:186 +#, fuzzy +msgid "Remove fill" +msgstr "Körpünü sil" + +#: ../../po/../src/ui/widget/selected-style.cpp:186 +#, fuzzy +msgid "Remove stroke" +msgstr "Körpünü sil" + +#: ../../po/../src/ui/widget/selected-style.cpp:718 +#, fuzzy +msgid "Master opacity" +msgstr "Şəffaflıq:" + +#: ../../po/../src/ui/widget/selected-style.cpp:744 +msgid "0 (transparent)" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:768 +msgid "1.0 (opaque)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1046 +msgid "Moved to next layer." +msgstr "" + +#: ../../po/../src/verbs.cpp:1048 +msgid "Cannot move past last layer." +msgstr "" + +#: ../../po/../src/verbs.cpp:1057 +msgid "Moved to previous layer." +msgstr "" + +#: ../../po/../src/verbs.cpp:1059 +msgid "Cannot move past first layer." +msgstr "" + +#: ../../po/../src/verbs.cpp:1076 ../../po/../src/verbs.cpp:1150 +#, fuzzy +msgid "No current layer." +msgstr "Sənəd" + +#: ../../po/../src/verbs.cpp:1105 +#, fuzzy, c-format +msgid "Raised layer %s." +msgstr "Sıfırla" + +#: ../../po/../src/verbs.cpp:1109 +#, fuzzy, c-format +msgid "Lowered layer %s." +msgstr "Seç" + +#: ../../po/../src/verbs.cpp:1118 +msgid "Cannot move layer any further." +msgstr "" + +#. TRANSLATORS: this means "The layer has been deleted." +#: ../../po/../src/verbs.cpp:1148 +#, fuzzy +msgid "Deleted layer." +msgstr "Seç" + +#: ../../po/../src/verbs.cpp:1544 +msgid "" +"You need to connect to a Jabber server before sharing a document with " +"another user." +msgstr "" + +#: ../../po/../src/verbs.cpp:1559 +msgid "" +"You need to connect to a Jabber server before sharing a document with a " +"chatroom." +msgstr "" + +#: ../../po/../src/verbs.cpp:1569 +msgid "XML node tracker has not been initialized; nothing to dump" +msgstr "" + +#. TRANSLATORS: If you have translated the keys.svg file to your language, then +#. translate this string as "keys.LANG.svg" (where LANG is your language code); +#. otherwise leave as "keys.svg". +#: ../../po/../src/verbs.cpp:1631 +msgid "keys.svg" +msgstr "" + +#. TRANSLATORS: If you have translated the tutorial-basic.svg file to your language, +#. then translate this string as "tutorial-basic.LANG.svg" (where LANG is your language +#. code); otherwise leave as "tutorial-basic.svg". +#: ../../po/../src/verbs.cpp:1667 +msgid "tutorial-basic.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1671 +msgid "tutorial-shapes.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1675 +msgid "tutorial-advanced.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1679 +msgid "tutorial-tracing.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1683 +msgid "tutorial-calligraphy.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1687 +msgid "tutorial-elements.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1691 +msgid "tutorial-tips.svg" +msgstr "" + +#: ../../po/../src/verbs.cpp:1842 +msgid "Does nothing" +msgstr "" + +#. File +#: ../../po/../src/verbs.cpp:1845 +#, fuzzy +msgid "Default" +msgstr "Sil" + +#: ../../po/../src/verbs.cpp:1845 +#, fuzzy +msgid "Create new document from default template" +msgstr "Sənəd" + +#: ../../po/../src/verbs.cpp:1847 +#, fuzzy +msgid "_Open..." +msgstr "_Aç" + +#: ../../po/../src/verbs.cpp:1848 +#, fuzzy +msgid "Open existing document" +msgstr "Sənəd" + +#: ../../po/../src/verbs.cpp:1849 +msgid "Re_vert" +msgstr "" + +#: ../../po/../src/verbs.cpp:1850 +msgid "Revert to the last saved version of document (changes will be lost)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1851 +#, fuzzy +msgid "_Save" +msgstr "Şəkil" + +#: ../../po/../src/verbs.cpp:1851 +#, fuzzy +msgid "Save document" +msgstr "Sənəd" + +#: ../../po/../src/verbs.cpp:1853 +#, fuzzy +msgid "Save _As..." +msgstr "Faylı qeyd et" + +#: ../../po/../src/verbs.cpp:1854 +#, fuzzy +msgid "Save document under new name" +msgstr "Çəkilişi yeni ad altında qeyd et" + +#: ../../po/../src/verbs.cpp:1855 +#, fuzzy +msgid "_Print..." +msgstr "Nöqtə" + +#: ../../po/../src/verbs.cpp:1855 +#, fuzzy +msgid "Print document" +msgstr "Sənəd" + +#. TRANSLATORS: "Vacuum Defs" means "Clean up defs" (so as to remove unused definitions) +#: ../../po/../src/verbs.cpp:1858 +msgid "Vac_uum Defs" +msgstr "" + +#: ../../po/../src/verbs.cpp:1858 +msgid "Remove unused predefined items from the <defs> of the document" +msgstr "" + +#: ../../po/../src/verbs.cpp:1860 +#, fuzzy +msgid "Print _Direct" +msgstr "Körpü Xassələri" + +#: ../../po/../src/verbs.cpp:1861 +msgid "Print directly without prompting to a file or pipe" +msgstr "" + +#: ../../po/../src/verbs.cpp:1862 +#, fuzzy +msgid "Print Previe_w" +msgstr "Yeni Nümayiş" + +#: ../../po/../src/verbs.cpp:1863 +#, fuzzy +msgid "Preview document printout" +msgstr "Çəkiliş çapını nümayiş et" + +#: ../../po/../src/verbs.cpp:1864 +#, fuzzy +msgid "_Import..." +msgstr "Al" + +#: ../../po/../src/verbs.cpp:1865 +msgid "Import bitmap or SVG image into document" +msgstr "" + +#: ../../po/../src/verbs.cpp:1866 +#, fuzzy +msgid "_Export Bitmap..." +msgstr "Fayl ver" + +#: ../../po/../src/verbs.cpp:1867 +#, fuzzy +msgid "Export document or selection as a bitmap image" +msgstr "Fayl ver" + +#: ../../po/../src/verbs.cpp:1868 +#, fuzzy +msgid "N_ext Window" +msgstr "pəncərə 2" + +#: ../../po/../src/verbs.cpp:1869 +msgid "Switch to the next document window" +msgstr "" + +#: ../../po/../src/verbs.cpp:1870 +#, fuzzy +msgid "P_revious Window" +msgstr "pəncərə 2" + +#: ../../po/../src/verbs.cpp:1871 +msgid "Switch to the previous document window" +msgstr "" + +#: ../../po/../src/verbs.cpp:1872 +#, fuzzy +msgid "_Close" +msgstr "Yeni Görünüş" + +#: ../../po/../src/verbs.cpp:1873 +#, fuzzy +msgid "Close window" +msgstr "Yeni Görünüş" + +#: ../../po/../src/verbs.cpp:1874 +#, fuzzy +msgid "_Quit" +msgstr "Çı_x" + +#: ../../po/../src/verbs.cpp:1874 +#, fuzzy +msgid "Quit Inkscape" +msgstr "Sodipodi" + +#. Edit +#: ../../po/../src/verbs.cpp:1877 +#, fuzzy +msgid "_Undo" +msgstr "Qaytar " + +#: ../../po/../src/verbs.cpp:1877 +#, fuzzy +msgid "Undo last action" +msgstr "Dönüşdürməni sıfırla" + +#: ../../po/../src/verbs.cpp:1879 +#, fuzzy +msgid "_Redo" +msgstr "Yenidən Et" + +#: ../../po/../src/verbs.cpp:1880 +msgid "Do again last undone action" +msgstr "" + +#: ../../po/../src/verbs.cpp:1881 +#, fuzzy +msgid "Cu_t" +msgstr "Kəs" + +#: ../../po/../src/verbs.cpp:1882 +#, fuzzy +msgid "Cut selection to clipboard" +msgstr "Seçili bölmani ara yaddaşa al" + +#: ../../po/../src/verbs.cpp:1883 +#, fuzzy +msgid "_Copy" +msgstr "Köçürt" + +#: ../../po/../src/verbs.cpp:1884 +#, fuzzy +msgid "Copy selection to clipboard" +msgstr "Seçili bölmani ara yaddaşa al" + +#: ../../po/../src/verbs.cpp:1885 +#, fuzzy +msgid "_Paste" +msgstr "Yapışdır" + +#: ../../po/../src/verbs.cpp:1886 +#, fuzzy +msgid "Paste objects from clipboard to mouse point" +msgstr "Ara yaddaşdan yapışdır" + +#: ../../po/../src/verbs.cpp:1887 +#, fuzzy +msgid "Paste _Style" +msgstr "Yapışdır" + +#: ../../po/../src/verbs.cpp:1888 +#, fuzzy +msgid "Apply style of the copied object to selection" +msgstr "Seçili bölmani ara yaddaşa al" + +#: ../../po/../src/verbs.cpp:1889 +#, fuzzy +msgid "Paste _In Place" +msgstr "Yapışdır" + +#: ../../po/../src/verbs.cpp:1890 +#, fuzzy +msgid "Paste objects from clipboard to the original location" +msgstr "Seçkini yuxarıya çək" + +#: ../../po/../src/verbs.cpp:1891 +#, fuzzy +msgid "_Delete" +msgstr "Sil" + +#: ../../po/../src/verbs.cpp:1892 +#, fuzzy +msgid "Delete selection" +msgstr "Seçkini cütləşdir" + +#: ../../po/../src/verbs.cpp:1893 +#, fuzzy +msgid "Duplic_ate" +msgstr "Cütləşdir" + +#: ../../po/../src/verbs.cpp:1894 +#, fuzzy +msgid "Duplicate selected objects" +msgstr "Seçili cismləri qruplaşdır" + +#: ../../po/../src/verbs.cpp:1895 +#, fuzzy +msgid "Clo_ne" +msgstr "Yeni Görünüş" + +#: ../../po/../src/verbs.cpp:1896 +msgid "Create a clone of selected object (a copy linked to the original)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1897 +msgid "Unlin_k Clone" +msgstr "" + +#: ../../po/../src/verbs.cpp:1898 +msgid "Cut the clone's link to its original" +msgstr "" + +#: ../../po/../src/verbs.cpp:1899 +#, fuzzy +msgid "Select _Original" +msgstr "Seç" + +#: ../../po/../src/verbs.cpp:1900 +#, fuzzy +msgid "Select the object to which the clone is linked" +msgstr "Seçili bölmani ara yaddaşa al" + +#. TRANSLATORS: Convert selection to a rectangle with tiled pattern fill +#: ../../po/../src/verbs.cpp:1902 +#, fuzzy +msgid "O_bjects to Pattern" +msgstr "Dönüşdürməni sıfırla" + +#: ../../po/../src/verbs.cpp:1903 +msgid "Convert selection to a rectangle with tiled pattern fill" +msgstr "" + +#. TRANSLATORS: Extract objects from a tiled pattern fill +#: ../../po/../src/verbs.cpp:1905 +#, fuzzy +msgid "Pattern to Ob_jects" +msgstr "Seçili cismləri qruplaşdır" + +#: ../../po/../src/verbs.cpp:1906 +msgid "Extract objects from a tiled pattern fill" +msgstr "" + +#: ../../po/../src/verbs.cpp:1907 +msgid "Clea_r All" +msgstr "" + +#: ../../po/../src/verbs.cpp:1908 +msgid "Delete all objects from document" +msgstr "" + +#: ../../po/../src/verbs.cpp:1909 +#, fuzzy +msgid "Select Al_l" +msgstr "Seç" + +#: ../../po/../src/verbs.cpp:1910 +#, fuzzy +msgid "Select all objects or all nodes" +msgstr "Seçili cismləri qruplaşdır" + +#: ../../po/../src/verbs.cpp:1911 +#, fuzzy +msgid "Select All in All La_yers" +msgstr "Seç" + +#: ../../po/../src/verbs.cpp:1912 +#, fuzzy +msgid "Select all objects in all visible and unlocked layers" +msgstr "Seçili cismləri qruplaşdır" + +#: ../../po/../src/verbs.cpp:1913 +#, fuzzy +msgid "In_vert Selection" +msgstr "Seçki" + +#: ../../po/../src/verbs.cpp:1914 +msgid "Invert selection (unselect what is selected and select everything else)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1915 +msgid "Invert in All Layers" +msgstr "" + +#: ../../po/../src/verbs.cpp:1916 +msgid "Invert selection in all visible and unlocked layers" +msgstr "" + +#: ../../po/../src/verbs.cpp:1917 +#, fuzzy +msgid "D_eselect" +msgstr "Seç" + +#: ../../po/../src/verbs.cpp:1918 +#, fuzzy +msgid "Deselect any selected objects or nodes" +msgstr "Seçili cismləri qruplaşdır" + +#. Selection +#: ../../po/../src/verbs.cpp:1921 +#, fuzzy +msgid "Raise to _Top" +msgstr "Seçkini yuxarıya çək" + +#: ../../po/../src/verbs.cpp:1922 +#, fuzzy +msgid "Raise selection to top" +msgstr "Seçkini yuxarıya çək" + +#: ../../po/../src/verbs.cpp:1923 +#, fuzzy +msgid "Lower to _Bottom" +msgstr "seçkini aşağıya çək" + +#: ../../po/../src/verbs.cpp:1924 +#, fuzzy +msgid "Lower selection to bottom" +msgstr "seçkini aşağıya çək" + +#: ../../po/../src/verbs.cpp:1925 +#, fuzzy +msgid "_Raise" +msgstr "Sıfırla" + +#: ../../po/../src/verbs.cpp:1926 +#, fuzzy +msgid "Raise selection one step" +msgstr "Seçkini bir lay yüksəlt" + +#: ../../po/../src/verbs.cpp:1927 +msgid "_Lower" +msgstr "" + +#: ../../po/../src/verbs.cpp:1928 +#, fuzzy +msgid "Lower selection one step" +msgstr "Seçkini bir lay alçalt" + +#: ../../po/../src/verbs.cpp:1929 +msgid "_Group" +msgstr "_Qrup" + +#: ../../po/../src/verbs.cpp:1930 +msgid "Group selected objects" +msgstr "Seçili cismləri qruplaşdır" + +#: ../../po/../src/verbs.cpp:1932 +#, fuzzy +msgid "Ungroup selected groups" +msgstr "Seçili cismləri qruplaşdır" + +#: ../../po/../src/verbs.cpp:1934 +#, fuzzy +msgid "_Put on Path" +msgstr "seçkini aşağıya çək" + +#: ../../po/../src/verbs.cpp:1935 +#, fuzzy +msgid "Put text on path" +msgstr "seçkini aşağıya çək" + +#: ../../po/../src/verbs.cpp:1936 +#, fuzzy +msgid "_Remove from Path" +msgstr "Dönüşdürməni sıfırla" + +#: ../../po/../src/verbs.cpp:1937 +#, fuzzy +msgid "Remove text from path" +msgstr "seçkini aşağıya çək" + +#: ../../po/../src/verbs.cpp:1938 +msgid "Remove Manual _Kerns" +msgstr "" + +#. TRANSLATORS: "glyph": An image used in the visual representation of characters; +#. roughly speaking, how a character looks. A font is a set of glyphs. +#: ../../po/../src/verbs.cpp:1941 +#, fuzzy +msgid "Remove all manual kerns and glyph rotations from a text object" +msgstr "Dönüşdürməni sıfırla" + +#: ../../po/../src/verbs.cpp:1943 +#, fuzzy +msgid "_Union" +msgstr "heç biri" + +#: ../../po/../src/verbs.cpp:1944 +#, fuzzy +msgid "Union of selected objects" +msgstr "Seçili cismləri qruplaşdır" + +#: ../../po/../src/verbs.cpp:1945 +#, fuzzy +msgid "_Intersection" +msgstr "_Qarşılıqlı" + +#: ../../po/../src/verbs.cpp:1946 +#, fuzzy +msgid "Intersection of selected objects" +msgstr "Seçili cismləri qruplaşdır" + +#: ../../po/../src/verbs.cpp:1947 +#, fuzzy +msgid "_Difference" +msgstr "Dərəcə" + +#: ../../po/../src/verbs.cpp:1948 +#, fuzzy +msgid "Difference of selected objects (bottom minus top)" +msgstr "Seçili cismləri qruplaşdır" + +#: ../../po/../src/verbs.cpp:1949 +msgid "E_xclusion" +msgstr "" + +#: ../../po/../src/verbs.cpp:1950 +#, fuzzy +msgid "Exclusive OR of selected objects" +msgstr "Seçili cismləri qruplaşdır" + +#: ../../po/../src/verbs.cpp:1951 +msgid "Di_vision" +msgstr "" + +#: ../../po/../src/verbs.cpp:1952 +msgid "Cut the bottom object into pieces" +msgstr "" + +#. TRANSLATORS: "to cut a path" is not the same as "to break a path apart" - see the +#. Advanced tutorial for more info +#: ../../po/../src/verbs.cpp:1955 +#, fuzzy +msgid "Cut _Path" +msgstr "Seçili cığırları kombinə et" + +#: ../../po/../src/verbs.cpp:1956 +msgid "Cut the bottom object's stroke into pieces, removing fill" +msgstr "" + +#. TRANSLATORS: "outset": expand a shape by offsetting the object's path, +#. i.e. by displacing it perpendicular to the path in each point. +#. See also the Advanced Tutorial for explanation. +#: ../../po/../src/verbs.cpp:1960 +#, fuzzy +msgid "Outs_et" +msgstr "Seçili cığırları kombinə et" + +#: ../../po/../src/verbs.cpp:1961 +#, fuzzy +msgid "Outset selected paths" +msgstr "Seçili cığırları kombinə et" + +#: ../../po/../src/verbs.cpp:1963 +#, fuzzy +msgid "O_utset Path by 1 px" +msgstr "Seçili cığırları kombinə et" + +#: ../../po/../src/verbs.cpp:1964 +#, fuzzy +msgid "Outset selected paths by 1 px" +msgstr "Seçili cığırları kombinə et" + +#: ../../po/../src/verbs.cpp:1966 +#, fuzzy +msgid "O_utset Path by 10 px" +msgstr "Seçili cığırları kombinə et" + +#: ../../po/../src/verbs.cpp:1967 +#, fuzzy +msgid "Outset selected paths by 10 px" +msgstr "Seçili cığırları kombinə et" + +#. TRANSLATORS: "inset": contract a shape by offsetting the object's path, +#. i.e. by displacing it perpendicular to the path in each point. +#. See also the Advanced Tutorial for explanation. +#: ../../po/../src/verbs.cpp:1971 +msgid "I_nset" +msgstr "" + +#: ../../po/../src/verbs.cpp:1972 +#, fuzzy +msgid "Inset selected paths" +msgstr "Seçili cığırları kombinə et" + +#: ../../po/../src/verbs.cpp:1974 +#, fuzzy +msgid "I_nset Path by 1 px" +msgstr "Seçili cığırları kombinə et" + +#: ../../po/../src/verbs.cpp:1975 +#, fuzzy +msgid "Inset selected paths by 1 px" +msgstr "Seçili cığırları kombinə et" + +#: ../../po/../src/verbs.cpp:1977 +#, fuzzy +msgid "I_nset Path by 10 px" +msgstr "Seçili cığırları kombinə et" + +#: ../../po/../src/verbs.cpp:1978 +#, fuzzy +msgid "Inset selected paths by 10 px" +msgstr "Seçili cığırları kombinə et" + +#: ../../po/../src/verbs.cpp:1980 +msgid "D_ynamic Offset" +msgstr "" + +#: ../../po/../src/verbs.cpp:1980 +msgid "Create a dynamic offset object" +msgstr "" + +#: ../../po/../src/verbs.cpp:1982 +msgid "_Linked Offset" +msgstr "" + +#: ../../po/../src/verbs.cpp:1983 +msgid "Create a dynamic offset object linked to the original path" +msgstr "" + +#: ../../po/../src/verbs.cpp:1985 +#, fuzzy +msgid "_Stroke to Path" +msgstr "Doldurma qurğuları" + +#: ../../po/../src/verbs.cpp:1986 +#, fuzzy +msgid "Convert selected strokes to paths" +msgstr "seçkini aşağıya çək" + +#: ../../po/../src/verbs.cpp:1987 +#, fuzzy +msgid "Si_mplify" +msgstr "Seçili cığırları kombinə et" + +#: ../../po/../src/verbs.cpp:1988 +#, fuzzy +msgid "Simplify selected paths by removing extra nodes" +msgstr "Seçili cığırları kombinə et" + +#: ../../po/../src/verbs.cpp:1989 +#, fuzzy +msgid "_Reverse" +msgstr "Fayl" + +#: ../../po/../src/verbs.cpp:1990 +#, fuzzy +msgid "Reverses the direction of selected paths; useful for flipping markers" +msgstr "Seçili cismləri qruplaşdır" + +#. TRANSLATORS: "to trace" means "to convert a bitmap to vector graphics" (to vectorize) +#: ../../po/../src/verbs.cpp:1992 +#, fuzzy +msgid "_Trace Bitmap" +msgstr "Qırıq bit xəritəsi" + +#: ../../po/../src/verbs.cpp:1993 +#, fuzzy +msgid "Convert bitmap object to paths" +msgstr "seçkini aşağıya çək" + +#: ../../po/../src/verbs.cpp:1994 +#, fuzzy +msgid "_Make a Bitmap Copy" +msgstr "Qırıq bit xəritəsi" + +#: ../../po/../src/verbs.cpp:1995 +msgid "Export selection to a bitmap and insert it into document" +msgstr "" + +#: ../../po/../src/verbs.cpp:1996 +msgid "_Combine" +msgstr "" + +#: ../../po/../src/verbs.cpp:1997 +msgid "Combine several paths into one" +msgstr "" + +#. TRANSLATORS: "to cut a path" is not the same as "to break a path apart" - see the +#. Advanced tutorial for more info +#: ../../po/../src/verbs.cpp:2000 +msgid "Break _Apart" +msgstr "" + +#: ../../po/../src/verbs.cpp:2001 +#, fuzzy +msgid "Break selected paths into subpaths" +msgstr "Seçili cığırları kombinə et" + +#: ../../po/../src/verbs.cpp:2002 +msgid "Gri_d Arrange..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2003 +msgid "Arrange selection in grid pattern" +msgstr "" + +#. Layer +#: ../../po/../src/verbs.cpp:2005 +#, fuzzy +msgid "_Add Layer..." +msgstr "Sıfırla" + +#: ../../po/../src/verbs.cpp:2006 +#, fuzzy +msgid "Create a new layer" +msgstr "Sənəd" + +#: ../../po/../src/verbs.cpp:2007 +#, fuzzy +msgid "Re_name Layer..." +msgstr "Sıfırla" + +#: ../../po/../src/verbs.cpp:2008 +#, fuzzy +msgid "Rename the current layer" +msgstr "Seç" + +#: ../../po/../src/verbs.cpp:2009 +#, fuzzy +msgid "Switch to Layer Abov_e" +msgstr "seçkini aşağıya çək" + +#: ../../po/../src/verbs.cpp:2010 +msgid "Switch to the layer above the current" +msgstr "" + +#: ../../po/../src/verbs.cpp:2011 +#, fuzzy +msgid "Switch to Layer Belo_w" +msgstr "Seçkini bir lay alçalt" + +#: ../../po/../src/verbs.cpp:2012 +msgid "Switch to the layer below the current" +msgstr "" + +#: ../../po/../src/verbs.cpp:2013 +#, fuzzy +msgid "Move Selection to Layer Abo_ve" +msgstr "seçkini aşağıya çək" + +#: ../../po/../src/verbs.cpp:2014 +msgid "Move selection to the layer above the current" +msgstr "" + +#: ../../po/../src/verbs.cpp:2015 +#, fuzzy +msgid "Move Selection to Layer Bel_ow" +msgstr "Seçkini bir lay alçalt" + +#: ../../po/../src/verbs.cpp:2016 +msgid "Move selection to the layer below the current" +msgstr "" + +#: ../../po/../src/verbs.cpp:2017 +#, fuzzy +msgid "Layer to _Top" +msgstr "Seçkini yuxarıya çək" + +#: ../../po/../src/verbs.cpp:2018 +#, fuzzy +msgid "Raise the current layer to the top" +msgstr "Seçkini yuxarıya çək" + +#: ../../po/../src/verbs.cpp:2019 +#, fuzzy +msgid "Layer to _Bottom" +msgstr "seçkini aşağıya çək" + +#: ../../po/../src/verbs.cpp:2020 +#, fuzzy +msgid "Lower the current layer to the bottom" +msgstr "seçkini aşağıya çək" + +#: ../../po/../src/verbs.cpp:2021 +#, fuzzy +msgid "_Raise Layer" +msgstr "Sıfırla" + +#: ../../po/../src/verbs.cpp:2022 +msgid "Raise the current layer" +msgstr "" + +#: ../../po/../src/verbs.cpp:2023 +#, fuzzy +msgid "_Lower Layer" +msgstr "Seç" + +#: ../../po/../src/verbs.cpp:2024 +msgid "Lower the current layer" +msgstr "" + +#: ../../po/../src/verbs.cpp:2025 +#, fuzzy +msgid "_Delete Current Layer" +msgstr "Seç" + +#: ../../po/../src/verbs.cpp:2026 +#, fuzzy +msgid "Delete the current layer" +msgstr "Seç" + +#. Object +#: ../../po/../src/verbs.cpp:2029 +msgid "Rotate _90° CW" +msgstr "" + +#: ../../po/../src/verbs.cpp:2030 +msgid "Rotate selection 90° clockwise" +msgstr "" + +#: ../../po/../src/verbs.cpp:2031 +msgid "Rotate 9_0° CCW" +msgstr "" + +#: ../../po/../src/verbs.cpp:2032 +msgid "Rotate selection 90° counter-clockwise" +msgstr "" + +#: ../../po/../src/verbs.cpp:2033 +#, fuzzy +msgid "Remove _Transformations" +msgstr "Dönüşdürməni sıfırla" + +#: ../../po/../src/verbs.cpp:2034 +#, fuzzy +msgid "Remove transformations from object" +msgstr "Dönüşdürməni sıfırla" + +#: ../../po/../src/verbs.cpp:2035 +#, fuzzy +msgid "_Object to Path" +msgstr "Dönüşdürməni sıfırla" + +#: ../../po/../src/verbs.cpp:2036 +#, fuzzy +msgid "Convert selected objects to paths" +msgstr "seçkini aşağıya çək" + +#: ../../po/../src/verbs.cpp:2037 +msgid "_Flow into Frame" +msgstr "" + +#: ../../po/../src/verbs.cpp:2038 +#, fuzzy +msgid "Put text into frames" +msgstr "seçkini aşağıya çək" + +#: ../../po/../src/verbs.cpp:2039 +#, fuzzy +msgid "_Unflow" +msgstr "Qaytar " + +#: ../../po/../src/verbs.cpp:2040 +msgid "Remove text from frame (creates a single-line text object)" +msgstr "" + +#: ../../po/../src/verbs.cpp:2041 +#, fuzzy +msgid "_Convert to Text" +msgstr "seçkini aşağıya çək" + +#: ../../po/../src/verbs.cpp:2042 +#, fuzzy +msgid "Convert flowed text to regular text objects (preserves appearance)" +msgstr "seçkini aşağıya çək" + +#: ../../po/../src/verbs.cpp:2044 +#, fuzzy +msgid "Flip _Horizontal" +msgstr "Seçkini bir lay yüksəlt" + +#: ../../po/../src/verbs.cpp:2044 +#, fuzzy +msgid "Flips selected objects horizontally" +msgstr "Seçkini bir lay yüksəlt" + +#: ../../po/../src/verbs.cpp:2047 +#, fuzzy +msgid "Flip _Vertical" +msgstr "Seçkini bir lay yüksəlt" + +#: ../../po/../src/verbs.cpp:2047 +#, fuzzy +msgid "Flips selected objects vertically" +msgstr "Seçkini bir lay yüksəlt" + +#. Tools +#: ../../po/../src/verbs.cpp:2051 +msgid "Select" +msgstr "Seç" + +#: ../../po/../src/verbs.cpp:2052 +#, fuzzy +msgid "Select and transform objects" +msgstr "Seç və döndər" + +#: ../../po/../src/verbs.cpp:2053 +#, fuzzy +msgid "Node Edit" +msgstr "Düyün" + +#: ../../po/../src/verbs.cpp:2054 +#, fuzzy +msgid "Edit path nodes or control handles" +msgstr "Seçili cismləri qruplaşdır" + +#: ../../po/../src/verbs.cpp:2056 +#, fuzzy +msgid "Create rectangles and squares" +msgstr "Düzbucaqlı dördbucaq çək" + +#: ../../po/../src/verbs.cpp:2058 +msgid "Create circles, ellipses, and arcs" +msgstr "" + +#: ../../po/../src/verbs.cpp:2060 +msgid "Create stars and polygons" +msgstr "" + +#: ../../po/../src/verbs.cpp:2062 +#, fuzzy +msgid "Create spirals" +msgstr "Spiral çək" + +#: ../../po/../src/verbs.cpp:2064 +#, fuzzy +msgid "Draw freehand lines" +msgstr "Dynahand cızığı çək" + +#: ../../po/../src/verbs.cpp:2066 +#, fuzzy +msgid "Draw Bezier curves and straight lines" +msgstr "Freehand cızığı çək" + +#: ../../po/../src/verbs.cpp:2068 +msgid "Draw calligraphic lines" +msgstr "" + +#: ../../po/../src/verbs.cpp:2070 +#, fuzzy +msgid "Create and edit text objects" +msgstr "Atribut əlavə et" + +#: ../../po/../src/verbs.cpp:2072 +#, fuzzy +msgid "Create and edit gradients" +msgstr "Atribut əlavə et" + +#: ../../po/../src/verbs.cpp:2074 +#, fuzzy +msgid "Zoom in or out" +msgstr "Uzaqlaşdır" + +#: ../../po/../src/verbs.cpp:2076 +msgid "Pick averaged colors from image" +msgstr "" + +#: ../../po/../src/verbs.cpp:2078 +#, fuzzy +msgid "Create connectors" +msgstr "Sənəd" + +#. Tool prefs +#: ../../po/../src/verbs.cpp:2081 +msgid "Selector Preferences" +msgstr "" + +#: ../../po/../src/verbs.cpp:2082 +#, fuzzy +msgid "Open Preferences for the Selector tool" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2083 +msgid "Node Tool Preferences" +msgstr "" + +#: ../../po/../src/verbs.cpp:2084 +#, fuzzy +msgid "Open Preferences for the Node tool" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2085 +#, fuzzy +msgid "Rectangle Preferences" +msgstr "Mətn Xassələri" + +#: ../../po/../src/verbs.cpp:2086 +#, fuzzy +msgid "Open Preferences for the Rectangle tool" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2087 +#, fuzzy +msgid "Ellipse Preferences" +msgstr "Doldurma qurğuları" + +#: ../../po/../src/verbs.cpp:2088 +#, fuzzy +msgid "Open Preferences for the Ellipse tool" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2089 +#, fuzzy +msgid "Star Preferences" +msgstr "Mətn Xassələri" + +#: ../../po/../src/verbs.cpp:2090 +#, fuzzy +msgid "Open Preferences for the Star tool" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2091 +#, fuzzy +msgid "Spiral Preferences" +msgstr "Körpü Xassələri" + +#: ../../po/../src/verbs.cpp:2092 +#, fuzzy +msgid "Open Preferences for the Spiral tool" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2093 +#, fuzzy +msgid "Pencil Preferences" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2094 +#, fuzzy +msgid "Open Preferences for the Pencil tool" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2095 +#, fuzzy +msgid "Pen Preferences" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2096 +#, fuzzy +msgid "Open Preferences for the Pen tool" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2097 +msgid "Calligraphic Preferences" +msgstr "" + +#: ../../po/../src/verbs.cpp:2098 +#, fuzzy +msgid "Open Preferences for the Calligraphy tool" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2099 +#, fuzzy +msgid "Text Preferences" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2100 +#, fuzzy +msgid "Open Preferences for the Text tool" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2101 +#, fuzzy +msgid "Gradient Preferences" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2102 +#, fuzzy +msgid "Open Preferences for the Gradient tool" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2103 +#, fuzzy +msgid "Zoom Preferences" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2104 +#, fuzzy +msgid "Open Preferences for the Zoom tool" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2105 +#, fuzzy +msgid "Dropper Preferences" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2106 +#, fuzzy +msgid "Open Preferences for the Dropper tool" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2107 +#, fuzzy +msgid "Connector Preferences" +msgstr "Mətn Xassələri" + +#: ../../po/../src/verbs.cpp:2108 +#, fuzzy +msgid "Open Preferences for the Connector tool" +msgstr "Sodipodi" + +#. Zoom/View +#: ../../po/../src/verbs.cpp:2111 +#, fuzzy +msgid "Zoom In" +msgstr "Yaxınlaşdır" + +#: ../../po/../src/verbs.cpp:2111 +msgid "Zoom in" +msgstr "Yaxınlaşdır" + +#: ../../po/../src/verbs.cpp:2112 +#, fuzzy +msgid "Zoom Out" +msgstr "Uzaqlaşdır" + +#: ../../po/../src/verbs.cpp:2112 +msgid "Zoom out" +msgstr "Uzaqlaşdır" + +#: ../../po/../src/verbs.cpp:2113 +#, fuzzy +msgid "_Rulers" +msgstr "Fayl" + +#: ../../po/../src/verbs.cpp:2113 +#, fuzzy +msgid "Show or hide the canvas rulers" +msgstr "Kənarları Aç" + +#: ../../po/../src/verbs.cpp:2114 +msgid "Scroll_bars" +msgstr "" + +#: ../../po/../src/verbs.cpp:2114 +#, fuzzy +msgid "Show or hide the canvas scrollbars" +msgstr "Kənarları Aç" + +#: ../../po/../src/verbs.cpp:2115 +#, fuzzy +msgid "_Grid" +msgstr "Qəfəs" + +#: ../../po/../src/verbs.cpp:2116 +msgid "G_uides" +msgstr "" + +#: ../../po/../src/verbs.cpp:2117 +msgid "Nex_t Zoom" +msgstr "" + +#: ../../po/../src/verbs.cpp:2117 +msgid "Next zoom (from the history of zooms)" +msgstr "" + +#: ../../po/../src/verbs.cpp:2119 +msgid "Pre_vious Zoom" +msgstr "" + +#: ../../po/../src/verbs.cpp:2119 +msgid "Previous zoom (from the history of zooms)" +msgstr "" + +#: ../../po/../src/verbs.cpp:2121 +#, fuzzy +msgid "Zoom 1:_1" +msgstr "1:1 qədər Yaxınlaşdır" + +#: ../../po/../src/verbs.cpp:2121 +msgid "Zoom to 1:1" +msgstr "1:1 qədər Yaxınlaşdır" + +#: ../../po/../src/verbs.cpp:2123 +#, fuzzy +msgid "Zoom 1:_2" +msgstr "1:2 qədər Yaxınlaşdır" + +#: ../../po/../src/verbs.cpp:2123 +msgid "Zoom to 1:2" +msgstr "1:2 qədər Yaxınlaşdır" + +#: ../../po/../src/verbs.cpp:2125 +#, fuzzy +msgid "_Zoom 2:1" +msgstr "2:1 qədər Yaxınlaşdır" + +#: ../../po/../src/verbs.cpp:2125 +msgid "Zoom to 2:1" +msgstr "2:1 qədər Yaxınlaşdır" + +#: ../../po/../src/verbs.cpp:2128 +msgid "_Fullscreen" +msgstr "" + +#: ../../po/../src/verbs.cpp:2128 +msgid "Stretch this document window to full screen" +msgstr "" + +#: ../../po/../src/verbs.cpp:2131 +#, fuzzy +msgid "Duplic_ate Window" +msgstr "Cütləşdir" + +#: ../../po/../src/verbs.cpp:2131 +#, fuzzy +msgid "Open a new window with the same document" +msgstr "Sənəd" + +#: ../../po/../src/verbs.cpp:2133 +#, fuzzy +msgid "_New View Preview" +msgstr "Yeni Nümayiş" + +#: ../../po/../src/verbs.cpp:2134 +#, fuzzy +msgid "New View Preview" +msgstr "Yeni Nümayiş" + +#. "view_new_preview" +#: ../../po/../src/verbs.cpp:2136 +msgid "_Normal" +msgstr "" + +#: ../../po/../src/verbs.cpp:2137 +msgid "Switch to normal display mode" +msgstr "" + +#: ../../po/../src/verbs.cpp:2138 +#, fuzzy +msgid "_Outline" +msgstr "Yeni Görünüş" + +#: ../../po/../src/verbs.cpp:2139 +msgid "Switch to outline (wireframe) display mode" +msgstr "" + +#: ../../po/../src/verbs.cpp:2141 +#, fuzzy +msgid "Ico_n Preview" +msgstr "Yeni Nümayiş" + +#: ../../po/../src/verbs.cpp:2142 +msgid "Open a window to preview items at different icon resolutions" +msgstr "" + +#: ../../po/../src/verbs.cpp:2144 +#, fuzzy +msgid "Zoom to fit page in window" +msgstr "Səhifəyə yaxınlaşdır" + +#: ../../po/../src/verbs.cpp:2145 +#, fuzzy +msgid "Page _Width" +msgstr "En" + +#: ../../po/../src/verbs.cpp:2146 +msgid "Zoom to fit page width in window" +msgstr "" + +#: ../../po/../src/verbs.cpp:2148 +#, fuzzy +msgid "Zoom to fit drawing in window" +msgstr "Çəkilişə yaxınlaşdır" + +#: ../../po/../src/verbs.cpp:2150 +#, fuzzy +msgid "Zoom to fit selection in window" +msgstr "Seçkini yuxarıya çək" + +#. Dialogs +#: ../../po/../src/verbs.cpp:2153 +#, fuzzy +msgid "In_kscape Preferences..." +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2154 +#, fuzzy +msgid "Global Inkscape preferences" +msgstr "Doldurma qurğuları" + +#: ../../po/../src/verbs.cpp:2155 +msgid "_Document Preferences..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2156 +#, fuzzy +msgid "Preferences saved with the document" +msgstr "Sənəd" + +#: ../../po/../src/verbs.cpp:2157 +#, fuzzy +msgid "_Fill and Stroke..." +msgstr "Doldurma qurğuları" + +#: ../../po/../src/verbs.cpp:2158 +#, fuzzy +msgid "Fill and Stroke dialog" +msgstr "Doldurma qurğuları" + +#. TRANSLATORS: "Swatches" means: color samples +#: ../../po/../src/verbs.cpp:2160 +#, fuzzy +msgid "S_watches..." +msgstr "Faylı qeyd et" + +#: ../../po/../src/verbs.cpp:2161 +msgid "View color swatches" +msgstr "" + +#: ../../po/../src/verbs.cpp:2162 +#, fuzzy +msgid "Transfor_m..." +msgstr "Dəyişdirmə" + +#: ../../po/../src/verbs.cpp:2163 +#, fuzzy +msgid "Transform dialog" +msgstr "Dəyişdirmə" + +#: ../../po/../src/verbs.cpp:2164 +#, fuzzy +msgid "_Align and Distribute..." +msgstr "Atributlar" + +#: ../../po/../src/verbs.cpp:2165 +#, fuzzy +msgid "Align and Distribute dialog" +msgstr "Atributlar" + +#: ../../po/../src/verbs.cpp:2166 +msgid "_Text and Font..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2167 +msgid "Text and Font dialog" +msgstr "" + +#: ../../po/../src/verbs.cpp:2168 +#, fuzzy +msgid "_XML Editor..." +msgstr "Düzəlt..." + +#: ../../po/../src/verbs.cpp:2169 +msgid "XML Editor" +msgstr "" + +#: ../../po/../src/verbs.cpp:2170 +#, fuzzy +msgid "_Find..." +msgstr "Nöqtə" + +#: ../../po/../src/verbs.cpp:2171 +#, fuzzy +msgid "Find objects in document" +msgstr "Sənəd" + +#: ../../po/../src/verbs.cpp:2172 +msgid "_Messages..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2173 +msgid "View debug messages" +msgstr "" + +#: ../../po/../src/verbs.cpp:2174 +#, fuzzy +msgid "S_cripts..." +msgstr "Nöqtə" + +#: ../../po/../src/verbs.cpp:2175 +msgid "Run scripts" +msgstr "" + +#: ../../po/../src/verbs.cpp:2176 +#, fuzzy +msgid "Show/Hide D_ialogs" +msgstr "Doldurma qurğuları" + +#: ../../po/../src/verbs.cpp:2177 +msgid "Show or hide all active dialogs" +msgstr "" + +#. TRANSLATORS: "Tile clones" means: "Create tiled clones" +#: ../../po/../src/verbs.cpp:2179 +msgid "Tile clones..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2180 +msgid "Create and arrange multiple clones of selection" +msgstr "" + +#: ../../po/../src/verbs.cpp:2181 +#, fuzzy +msgid "_Object Properties..." +msgstr "Mətn Xassələri" + +#: ../../po/../src/verbs.cpp:2182 +#, fuzzy +msgid "Object Properties dialog" +msgstr "Mətn Xassələri" + +#: ../../po/../src/verbs.cpp:2185 +msgid "_Connect to Jabber server..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2185 +msgid "Connect to a Jabber server" +msgstr "" + +#: ../../po/../src/verbs.cpp:2187 +#, fuzzy +msgid "Share with _user..." +msgstr "Faylı qeyd et" + +#: ../../po/../src/verbs.cpp:2187 +msgid "Establish a whiteboard session with another Jabber user" +msgstr "" + +#: ../../po/../src/verbs.cpp:2189 +msgid "Share with _chatroom..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2189 +msgid "" +"Join a chatroom to start a new whiteboard session or join one in progress" +msgstr "" + +#: ../../po/../src/verbs.cpp:2191 +msgid "_Dump XML node tracker" +msgstr "" + +#: ../../po/../src/verbs.cpp:2191 +msgid "Dump the contents of the XML tracker to the console" +msgstr "" + +#: ../../po/../src/verbs.cpp:2193 +msgid "_Open session file..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2193 +msgid "Open and browse through records of past whiteboard sessions" +msgstr "" + +#: ../../po/../src/verbs.cpp:2195 +msgid "Session file playback" +msgstr "" + +#: ../../po/../src/verbs.cpp:2197 +msgid "_Disconnect from session" +msgstr "" + +#: ../../po/../src/verbs.cpp:2199 +msgid "Disconnect from _server" +msgstr "" + +#: ../../po/../src/verbs.cpp:2201 +msgid "_Input Devices..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2202 +msgid "Configure extended input devices" +msgstr "" + +#. Help +#: ../../po/../src/verbs.cpp:2205 +msgid "_Keys and Mouse" +msgstr "" + +#: ../../po/../src/verbs.cpp:2206 +msgid "Key and mouse shortcuts reference" +msgstr "" + +#: ../../po/../src/verbs.cpp:2207 +#, fuzzy +msgid "About E_xtensions" +msgstr "Seçkini döndər" + +#: ../../po/../src/verbs.cpp:2208 +#, fuzzy +msgid "About Extensions..." +msgstr "Seçkini döndər" + +#: ../../po/../src/verbs.cpp:2209 +#, fuzzy +msgid "About _Memory" +msgstr "Seçkini döndər" + +#: ../../po/../src/verbs.cpp:2210 +#, fuzzy +msgid "About Memory..." +msgstr "_Haqqında ..." + +#: ../../po/../src/verbs.cpp:2211 +msgid "_About Inkscape" +msgstr "" + +#. "help_about" +#. new HelpVerb(SP_VERB_SHOW_LICENSE, "ShowLicense", N_("Modifying or Redistributing Inkscape"), +#. N_("Show license to modify and/or redistribute Inkscape: GNU GPL"), NULL), +#. Tutorials +#: ../../po/../src/verbs.cpp:2217 +#, fuzzy +msgid "Inkscape: _Basic" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2218 +msgid "Getting started with Inkscape" +msgstr "" + +#. "tutorial_basic" +#: ../../po/../src/verbs.cpp:2219 +#, fuzzy +msgid "Inkscape: _Shapes" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2220 +msgid "Using shape tools to create and edit shapes" +msgstr "" + +#: ../../po/../src/verbs.cpp:2221 +#, fuzzy +msgid "Inkscape: _Advanced" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2222 +#, fuzzy +msgid "Advanced Inkscape topics" +msgstr "Sodipodi" + +#. "tutorial_advanced" +#. TRANSLATORS: "to trace" means "to convert a bitmap to vector graphics" (to vectorize) +#: ../../po/../src/verbs.cpp:2224 +#, fuzzy +msgid "Inkscape: T_racing" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2225 +#, fuzzy +msgid "Using bitmap tracing" +msgstr "Kağız böyüklüyü:" + +#. "tutorial_tracing" +#: ../../po/../src/verbs.cpp:2226 +#, fuzzy +msgid "Inkscape: _Calligraphy" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2227 +msgid "Using the Calligraphy pen tool" +msgstr "" + +#: ../../po/../src/verbs.cpp:2228 +msgid "_Elements of Design" +msgstr "" + +#: ../../po/../src/verbs.cpp:2229 +msgid "Principles of design in the tutorial form" +msgstr "" + +#. "tutorial_design" +#: ../../po/../src/verbs.cpp:2230 +msgid "_Tips and Tricks" +msgstr "" + +#: ../../po/../src/verbs.cpp:2231 +msgid "Miscellaneous tips and tricks" +msgstr "" + +#. "tutorial_tips" +#. Effect +#: ../../po/../src/verbs.cpp:2234 +msgid "Previous Effect" +msgstr "" + +#: ../../po/../src/verbs.cpp:2235 +msgid "Repeat the last effect with the same settings" +msgstr "" + +#. "tutorial_tips" +#: ../../po/../src/verbs.cpp:2236 +msgid "Previous Effect Settings..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2237 +msgid "Repeat the last effect with new settings" +msgstr "" + +#: ../../po/../src/widgets/dash-selector.cpp:106 +#, fuzzy +msgid "Dash pattern" +msgstr "Nöqtə" + +#: ../../po/../src/widgets/dash-selector.cpp:121 +#, fuzzy +msgid "Pattern offset" +msgstr "Seçili cismləri qruplaşdır" + +#: ../../po/../src/widgets/desktop-widget.cpp:240 +#, fuzzy +msgid "Zoom drawing if window size changes" +msgstr "Çəkilişə yaxınlaşdır" + +#: ../../po/../src/widgets/desktop-widget.cpp:298 +msgid "Cursor coordinates" +msgstr "" + +#. display the initial welcome message in the statusbar +#: ../../po/../src/widgets/desktop-widget.cpp:324 +msgid "" +"Welcome to Inkscape! Use shape or freehand tools to create objects; " +"use selector (arrow) to move or transform them." +msgstr "" + +#: ../../po/../src/widgets/desktop-widget.cpp:372 +#, c-format +msgid "%s: %d - Inkscape" +msgstr "" + +#: ../../po/../src/widgets/desktop-widget.cpp:374 +#, c-format +msgid "%s - Inkscape" +msgstr "" + +#: ../../po/../src/widgets/desktop-widget.cpp:532 +#, c-format +msgid "" +"Save changes to document \"%s\" before " +"closing?\n" +"\n" +"If you close without saving, your changes will be discarded." +msgstr "" + +#: ../../po/../src/widgets/desktop-widget.cpp:548 +#: ../../po/../src/widgets/desktop-widget.cpp:612 +msgid "Close _without saving" +msgstr "" + +#: ../../po/../src/widgets/desktop-widget.cpp:595 +#, c-format +msgid "" +"The file \"%s\" was saved with a " +"format (%s) that may cause data loss!\n" +"\n" +"Do you want to save this file in another format?" +msgstr "" + +#. Family frame +#: ../../po/../src/widgets/font-selector.cpp:156 +msgid "Font family" +msgstr "" + +#. Style frame +#: ../../po/../src/widgets/font-selector.cpp:184 +#, fuzzy +msgid "Style" +msgstr "Miqyas" + +#: ../../po/../src/widgets/font-selector.cpp:219 +msgid "Font size:" +msgstr "" + +#. TRANSLATORS: Test string used in text and font dialog (when no +#. * text has been entered) to get a preview of the font. Choose +#. * some representative characters that users of your locale will be +#. * interested in. +#: ../../po/../src/widgets/font-selector.cpp:554 +msgid "AaBbCcIiPpQq12368.;/()" +msgstr "" + +#: ../../po/../src/widgets/gradient-selector.cpp:137 +#: ../../po/../src/widgets/gradient-toolbar.cpp:524 +#, fuzzy +msgid "Duplicate" +msgstr "Cütləşdir" + +#: ../../po/../src/widgets/gradient-selector.cpp:142 +#: ../../po/../src/widgets/gradient-toolbar.cpp:535 +#, fuzzy +msgid "Edit..." +msgstr "Düzəlt" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/pservers.html#LinearGradientSpreadMethodAttribute +#: ../../po/../src/widgets/gradient-selector.cpp:159 +msgid "" +"Whether to fill with flat color beyond the ends of the gradient vector " +"(spreadMethod=\"pad\"), or repeat the gradient in the same direction " +"(spreadMethod=\"repeat\"), or repeat the gradient in alternating opposite " +"directions (spreadMethod=\"reflect\")" +msgstr "" + +#: ../../po/../src/widgets/gradient-selector.cpp:165 +#, fuzzy +msgid "none" +msgstr "Heç biri" + +#: ../../po/../src/widgets/gradient-selector.cpp:169 +#, fuzzy +msgid "reflected" +msgstr "Seç" + +#: ../../po/../src/widgets/gradient-selector.cpp:173 +#, fuzzy +msgid "direct" +msgstr "Sıfırla" + +#: ../../po/../src/widgets/gradient-selector.cpp:181 +msgid "Repeat:" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:217 +msgid "No gradients" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:226 +msgid "Nothing selected" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:237 +msgid "No gradients in selection" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:247 +msgid "Multiple gradients" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:525 +msgid "" +"If the gradient is used by more than one object, create a copy of it for the " +"selected object(s)" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:536 +msgid "Edit the stops of the gradient" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:593 +#: ../../po/../src/widgets/toolbox.cpp:1103 +#: ../../po/../src/widgets/toolbox.cpp:1192 +#: ../../po/../src/widgets/toolbox.cpp:1485 +#: ../../po/../src/widgets/toolbox.cpp:1534 +#: ../../po/../src/widgets/toolbox.cpp:1766 +#: ../../po/../src/widgets/toolbox.cpp:1801 +#: ../../po/../src/widgets/toolbox.cpp:2331 +#: ../../po/../src/widgets/toolbox.cpp:2370 +msgid "New:" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:606 +#, fuzzy +msgid "Create linear gradient" +msgstr "Sənəd" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:620 +msgid "Create radial (elliptic or circular) gradient" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:635 +#, fuzzy +msgid "on" +msgstr "Heç biri" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:648 +msgid "Create gradient in the fill" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:662 +msgid "Create gradient in the stroke" +msgstr "" + +#. FIXME: implement averaging of all parameters for multiple selected stars +#. gtk_label_set_markup(GTK_LABEL(l), _("Average:")); +#. FIXME: implement averaging of all parameters for multiple selected +#. gtk_label_set_markup(GTK_LABEL(l), _("Average:")); +#: ../../po/../src/widgets/gradient-toolbar.cpp:676 +#: ../../po/../src/widgets/toolbox.cpp:1105 +#: ../../po/../src/widgets/toolbox.cpp:1124 +#: ../../po/../src/widgets/toolbox.cpp:1493 +#: ../../po/../src/widgets/toolbox.cpp:1518 +#: ../../po/../src/widgets/toolbox.cpp:1768 +#: ../../po/../src/widgets/toolbox.cpp:1787 +#: ../../po/../src/widgets/toolbox.cpp:2334 +#: ../../po/../src/widgets/toolbox.cpp:2354 +msgid "Change:" +msgstr "" + +#: ../../po/../src/widgets/gradient-vector.cpp:269 +msgid "No gradients in document" +msgstr "" + +#: ../../po/../src/widgets/gradient-vector.cpp:275 +msgid "No gradient selected" +msgstr "" + +#: ../../po/../src/widgets/gradient-vector.cpp:532 +msgid "No stops in gradient" +msgstr "" + +#. TRANSLATORS: "Stop" means: a "phase" of a gradient +#: ../../po/../src/widgets/gradient-vector.cpp:794 +#, fuzzy +msgid "Add stop" +msgstr "masa üstü" + +#: ../../po/../src/widgets/gradient-vector.cpp:797 +msgid "Add another control stop to gradient" +msgstr "" + +#: ../../po/../src/widgets/gradient-vector.cpp:799 +#, fuzzy +msgid "Delete stop" +msgstr "Seçkini sil" + +#: ../../po/../src/widgets/gradient-vector.cpp:802 +msgid "Delete current control stop from gradient" +msgstr "" + +#. Label +#: ../../po/../src/widgets/gradient-vector.cpp:813 +msgid "Offset:" +msgstr "" + +#. TRANSLATORS: "Stop" means: a "phase" of a gradient +#: ../../po/../src/widgets/gradient-vector.cpp:858 +#, fuzzy +msgid "Stop Color" +msgstr "Başlama rəngi" + +#: ../../po/../src/widgets/gradient-vector.cpp:887 +msgid "Gradient editor" +msgstr "" + +#: ../../po/../src/widgets/layer-selector.cpp:119 +#, fuzzy +msgid "Toggle current layer visibility" +msgstr "Sənəd" + +#: ../../po/../src/widgets/layer-selector.cpp:139 +#, fuzzy +msgid "Lock or unlock current layer" +msgstr "Sənəd" + +#: ../../po/../src/widgets/layer-selector.cpp:142 +#, fuzzy +msgid "Current layer" +msgstr "Sənəd" + +#: ../../po/../src/widgets/layer-selector.cpp:553 +msgid "(root)" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:182 +#: ../../po/../src/widgets/paint-selector.cpp:561 +#, fuzzy +msgid "No paint" +msgstr "Nöqtə" + +#: ../../po/../src/widgets/paint-selector.cpp:184 +#: ../../po/../src/widgets/paint-selector.cpp:629 +#, fuzzy +msgid "Flat color" +msgstr "rəng" + +#: ../../po/../src/widgets/paint-selector.cpp:186 +#: ../../po/../src/widgets/paint-selector.cpp:696 +msgid "Linear gradient" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:188 +#: ../../po/../src/widgets/paint-selector.cpp:699 +msgid "Radial gradient" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:192 +msgid "Unset paint (make it undefined so it can be inherited)" +msgstr "" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/painting.html#FillRuleProperty +#: ../../po/../src/widgets/paint-selector.cpp:204 +msgid "" +"Any path self-intersections or subpaths create holes in the fill (fill-rule: " +"evenodd)" +msgstr "" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/painting.html#FillRuleProperty +#: ../../po/../src/widgets/paint-selector.cpp:215 +msgid "" +"Fill is solid unless a subpath is counterdirectional (fill-rule: nonzero)" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:528 +#, fuzzy +msgid "No objects" +msgstr "Mətn cismi" + +#: ../../po/../src/widgets/paint-selector.cpp:539 +msgid "Multiple styles" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:550 +msgid "Paint is undefined" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:757 +#, fuzzy +msgid "No patterns in document" +msgstr "Sənəd" + +#: ../../po/../src/widgets/paint-selector.cpp:872 +msgid "" +"Use Edit > Object(s) to Pattern to create a new pattern from " +"selection." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:426 +msgid "Now stroke width is scaled when objects are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:428 +msgid "Now stroke width is not scaled when objects are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:436 +msgid "" +"Now rounded rectangle corners are scaled when rectangles are " +"scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:438 +msgid "" +"Now rounded rectangle corners are not scaled when rectangles " +"are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:446 +msgid "" +"Now gradients are transformed along with their objects when " +"those are transformed (moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:448 +msgid "" +"Now gradients remain fixed when objects are transformed " +"(moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:456 +msgid "" +"Now patterns are transformed along with their objects when " +"those are transformed (moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:458 +msgid "" +"Now patterns remain fixed when objects are transformed (moved, " +"scaled, rotated, or skewed)." +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:506 +#, fuzzy +msgid "select_toolbar|X" +msgstr "Seç" + +#: ../../po/../src/widgets/select-toolbar.cpp:506 +msgid "Horizontal coordinate of selection" +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:511 +#, fuzzy +msgid "select_toolbar|Y" +msgstr "Seç" + +#: ../../po/../src/widgets/select-toolbar.cpp:511 +msgid "Vertical coordinate of selection" +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:517 +#, fuzzy +msgid "select_toolbar|W" +msgstr "Seç" + +#: ../../po/../src/widgets/select-toolbar.cpp:517 +#, fuzzy +msgid "Width of selection" +msgstr "Seçkini kəs" + +#: ../../po/../src/widgets/select-toolbar.cpp:525 +msgid "Change both width and height by the same proportion" +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:534 +#, fuzzy +msgid "select_toolbar|H" +msgstr "Seç" + +#: ../../po/../src/widgets/select-toolbar.cpp:534 +#, fuzzy +msgid "Height of selection" +msgstr "Seçkiyə yaxınlaşdır" + +#: ../../po/../src/widgets/sp-color-gtkselector.cpp:62 +msgid "System" +msgstr "" + +#: ../../po/../src/widgets/sp-color-notebook.cpp:322 +msgid "RGBA_:" +msgstr "" + +#: ../../po/../src/widgets/sp-color-notebook.cpp:330 +msgid "Hexadecimal RGBA value of the color" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "RGB" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "HSL" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "CMYK" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:397 +msgid "_R" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:398 +#: ../../po/../src/widgets/sp-color-scales.cpp:399 +#, fuzzy +msgid "Red" +msgstr "Qırmızı:" + +#: ../../po/../src/widgets/sp-color-scales.cpp:400 +msgid "_G" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:401 +#: ../../po/../src/widgets/sp-color-scales.cpp:402 +#, fuzzy +msgid "Green" +msgstr "Yaşıl:" + +#: ../../po/../src/widgets/sp-color-scales.cpp:403 +msgid "_B" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:404 +#: ../../po/../src/widgets/sp-color-scales.cpp:405 +#, fuzzy +msgid "Blue" +msgstr "Göy:" + +#. Label +#: ../../po/../src/widgets/sp-color-scales.cpp:406 +#: ../../po/../src/widgets/sp-color-scales.cpp:432 +#: ../../po/../src/widgets/sp-color-scales.cpp:463 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:141 +msgid "_A" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:407 +#: ../../po/../src/widgets/sp-color-scales.cpp:408 +#: ../../po/../src/widgets/sp-color-scales.cpp:433 +#: ../../po/../src/widgets/sp-color-scales.cpp:434 +#: ../../po/../src/widgets/sp-color-scales.cpp:464 +#: ../../po/../src/widgets/sp-color-scales.cpp:465 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:151 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:163 +msgid "Alpha (opacity)" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:423 +msgid "_H" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:424 +#: ../../po/../src/widgets/sp-color-scales.cpp:425 +#, fuzzy +msgid "Hue" +msgstr "Çöhrə:" + +#: ../../po/../src/widgets/sp-color-scales.cpp:426 +msgid "_S" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:427 +#: ../../po/../src/widgets/sp-color-scales.cpp:428 +#, fuzzy +msgid "Saturation" +msgstr "Doyğunluq:" + +#: ../../po/../src/widgets/sp-color-scales.cpp:429 +msgid "_L" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:430 +#: ../../po/../src/widgets/sp-color-scales.cpp:431 +#, fuzzy +msgid "Lightness" +msgstr "Hündürlük" + +#: ../../po/../src/widgets/sp-color-scales.cpp:451 +msgid "_C" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:452 +#: ../../po/../src/widgets/sp-color-scales.cpp:453 +#, fuzzy +msgid "Cyan" +msgstr "Dəyişdir" + +#: ../../po/../src/widgets/sp-color-scales.cpp:454 +msgid "_M" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:455 +#: ../../po/../src/widgets/sp-color-scales.cpp:456 +msgid "Magenta" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:457 +msgid "_Y" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:458 +#: ../../po/../src/widgets/sp-color-scales.cpp:459 +#, fuzzy +msgid "Yellow" +msgstr "Sarı:" + +#: ../../po/../src/widgets/sp-color-scales.cpp:460 +msgid "_K" +msgstr "" + +#: ../../po/../src/widgets/sp-color-selector.cpp:71 +#, fuzzy +msgid "Unnamed" +msgstr "ad" + +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:68 +msgid "Wheel" +msgstr "" + +#: ../../po/../src/widgets/sp-xmlview-attr-list.cpp:53 +#, fuzzy +msgid "Attribute" +msgstr "Atributlar" + +#: ../../po/../src/widgets/sp-xmlview-attr-list.cpp:54 +msgid "Value" +msgstr "Qiymət" + +#: ../../po/../src/widgets/toolbox.cpp:424 +msgid "Insert new nodes into selected segments" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:426 +msgid "Delete selected nodes" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:431 +#, fuzzy +msgid "Join paths at selected nodes" +msgstr "Seçili cığırları kombinə et" + +#: ../../po/../src/widgets/toolbox.cpp:433 +#, fuzzy +msgid "Join paths at selected nodes with new segment" +msgstr "Seçili cığırları kombinə et" + +#: ../../po/../src/widgets/toolbox.cpp:436 +msgid "Split path between two non-endpoint nodes" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:439 +#, fuzzy +msgid "Break path at selected nodes" +msgstr "Seçili cığırları kombinə et" + +#: ../../po/../src/widgets/toolbox.cpp:444 +msgid "Make selected nodes corner" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:447 +msgid "Make selected nodes smooth" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:450 +msgid "Make selected nodes symmetric" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:455 +msgid "Make selected segments lines" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:458 +msgid "Make selected segments curves" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1199 +msgid "Polygon" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1206 +msgid "Regular polygon (with one handle) instead of a star" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1218 +msgid "Corners:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1218 +msgid "Number of corners of a polygon or star" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1228 +#, fuzzy +msgid "Spoke ratio:" +msgstr "Yer" + +#. TRANSLATORS: Tip radius of a star is the distance from the center to the farthest handle. +#. Base radius is the same for the closest handle. +#: ../../po/../src/widgets/toolbox.cpp:1231 +msgid "Base radius to tip radius ratio" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1246 +#, fuzzy +msgid "Rounded:" +msgstr "Qırmızı:" + +#: ../../po/../src/widgets/toolbox.cpp:1246 +msgid "How much rounded are the corners (0 for sharp)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1256 +msgid "Randomized:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1256 +msgid "Scatter randomly the corners and angles" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1269 +#: ../../po/../src/widgets/toolbox.cpp:1838 +#: ../../po/../src/widgets/toolbox.cpp:2061 +msgid "Defaults" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1270 +#: ../../po/../src/widgets/toolbox.cpp:1839 +#: ../../po/../src/widgets/toolbox.cpp:2062 +msgid "" +"Reset shape parameters to defaults (use Inkscape Preferences > Tools to " +"change defaults)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1544 +msgid "W:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1544 +#, fuzzy +msgid "Width of rectangle" +msgstr "Seçkini kəs" + +#: ../../po/../src/widgets/toolbox.cpp:1556 +#, fuzzy +msgid "Height of rectangle" +msgstr "Seçkiyə yaxınlaşdır" + +#: ../../po/../src/widgets/toolbox.cpp:1568 +#, fuzzy +msgid "Rx:" +msgstr "1:1" + +#: ../../po/../src/widgets/toolbox.cpp:1568 +msgid "Horizontal radius of rounded corners" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1578 +#, fuzzy +msgid "Ry:" +msgstr "1:1" + +#: ../../po/../src/widgets/toolbox.cpp:1578 +msgid "Vertical radius of rounded corners" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1594 +msgid "Not rounded" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1596 +msgid "Make corners sharp" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1805 +#, fuzzy +msgid "Turns:" +msgstr "Dəyişdirmə" + +#: ../../po/../src/widgets/toolbox.cpp:1805 +msgid "Number of revolutions" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1815 +#, fuzzy +msgid "Divergence:" +msgstr "Dərəcə" + +#: ../../po/../src/widgets/toolbox.cpp:1815 +msgid "How much denser/sparser are outer revolutions; 1 = uniform" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1825 +msgid "Inner radius:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1825 +msgid "Radius of the innermost revolution (relative to the spiral size)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1957 +msgid "The width of the calligraphic pen (relative to the visible canvas area)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1967 +#, fuzzy +msgid "Thinning:" +msgstr "Ä°cra edilir" + +#: ../../po/../src/widgets/toolbox.cpp:1967 +msgid "" +"How much velocity thins the stroke (> 0 makes fast strokes thinner, < 0 " +"makes them broader, 0 makes width independent of velocity)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1980 +#, fuzzy +msgid "Angle:" +msgstr "bucaq" + +#: ../../po/../src/widgets/toolbox.cpp:1980 +msgid "" +"The angle of the pen's nib (in degrees; 0 = horizontal; has no effect if " +"fixation = 0)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1990 +#, fuzzy +msgid "Fixation:" +msgstr "Doyğunluq:" + +#: ../../po/../src/widgets/toolbox.cpp:1990 +msgid "" +"How fixed is the pen angle (0 = always perpendicular to stroke direction, 1 " +"= fixed)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2003 +msgid "Mass:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2003 +msgid "How much inertia affects the movement of the pen" +msgstr "" + +#. TRANSLATORS: "drag" means "resistance" here +#: ../../po/../src/widgets/toolbox.cpp:2014 +#, fuzzy +msgid "Drag:" +msgstr "Çək" + +#: ../../po/../src/widgets/toolbox.cpp:2014 +msgid "How much resistance affects the movement of the pen" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2034 +msgid "Use the pressure of the input device to alter the width of the pen" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2047 +msgid "Use the tilt of the input device to alter the angle of the pen's nib" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2374 +#, fuzzy +msgid "Start:" +msgstr "Ulduz" + +#: ../../po/../src/widgets/toolbox.cpp:2374 +msgid "The angle (in degrees) from the horizontal to the arc's start point" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2384 +msgid "End:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2384 +msgid "The angle (in degrees) from the horizontal to the arc's end point" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2395 +#, fuzzy +msgid "Open arc" +msgstr "_Aç" + +#: ../../po/../src/widgets/toolbox.cpp:2396 +msgid "" +"Switch between arc (unclosed shape) and segment (closed shape with two radii)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2415 +msgid "Make whole" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2417 +msgid "Make the shape a whole ellipse, not arc or segment" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2644 +msgid "" +"When pressed, picks visible color without alpha and when not pressed, picks " +"color including its alpha" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:3039 +#, fuzzy +msgid "Make connectors avoid selected objects" +msgstr "Seçili cismləri qruplaşdır" + +#: ../../po/../src/widgets/toolbox.cpp:3043 +#, fuzzy +msgid "Make connectors ignore selected objects" +msgstr "Seçili cismləri qruplaşdır" + +#. +#. 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 : +#: ../share/extensions/addnodes.inx.h:1 +#, fuzzy +msgid "Add Nodes" +msgstr "Düyün" + +#: ../share/extensions/addnodes.inx.h:2 +msgid "Maximum Segment Length" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:1 +msgid "AI Input" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:2 ../share/extensions/ai_output.inx.h:2 +msgid "Adobe Illustrator (*.ai)" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:3 +msgid "Open files saved with Adobe Illustrator" +msgstr "" + +#: ../share/extensions/ai_output.inx.h:1 +#, fuzzy +msgid "AI Output" +msgstr "Kəs" + +#: ../share/extensions/ai_output.inx.h:3 +msgid "Write Adobe Illustrator" +msgstr "" + +#: ../share/extensions/dia.inx.h:1 +msgid "A diagram created with the program Dia" +msgstr "" + +#: ../share/extensions/dia.inx.h:2 +msgid "Dia Diagram (*.dia)" +msgstr "" + +#: ../share/extensions/dia.inx.h:3 +msgid "Dia Input" +msgstr "" + +#: ../share/extensions/dia.inx.h:4 +msgid "" +"In order to import Dia files, Dia itself must be installed. You can get Dia " +"at http://www.gnome.org/projects/dia/" +msgstr "" + +#: ../share/extensions/dia.inx.h:5 +msgid "" +"The dia2svg.sh script should be installed with your Inkscape distribution. " +"If you do not have it, there is likely to be something wrong with your " +"Inkscape installation." +msgstr "" + +#: ../share/extensions/dots.inx.h:1 +#, fuzzy +msgid "Connect the Dots" +msgstr "Yeni Görünüş" + +#: ../share/extensions/dots.inx.h:2 +msgid "Dot Size" +msgstr "" + +#: ../share/extensions/dots.inx.h:3 +#, fuzzy +msgid "Font Size" +msgstr "Nöqtə" + +#: ../share/extensions/dropshadow.inx.h:1 +#, fuzzy +msgid "Color of shadow" +msgstr "Vasitə Qutusunu Göstər" + +#: ../share/extensions/dropshadow.inx.h:2 +msgid "Dropshadow" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:1 +#: ../share/extensions/dxf_output.inx.h:1 +msgid "AutoCAD DXF (*.dxf)" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:2 +msgid "DXF Input" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:3 +msgid "Import AutoCAD's Document Exchange Format" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:4 +msgid "" +"dxf2svg may come with Inkscape, but is also at http://dxf-svg-convert." +"sourceforge.net/" +msgstr "" + +#: ../share/extensions/dxf_output.inx.h:2 +#, fuzzy +msgid "DXF Output" +msgstr "Kəs" + +#: ../share/extensions/dxf_output.inx.h:3 +msgid "DXF file written by pstoedit" +msgstr "" + +#: ../share/extensions/dxf_output.inx.h:4 +msgid "pstoedit must be installed to run see http://www.pstoedit.net/pstoedit" +msgstr "" + +#: ../share/extensions/embedimage.inx.h:1 +#, fuzzy +msgid "Embed Images" +msgstr "Səhifə" + +#: ../share/extensions/eps_input.inx.h:1 +msgid "EPS Input" +msgstr "" + +#: ../share/extensions/eps_input.inx.h:2 +msgid "Encapsulated Postscript" +msgstr "" + +#: ../share/extensions/eps_input.inx.h:3 +msgid "Encapsulated Postscript (*.eps)" +msgstr "" + +#: ../share/extensions/epsi_output.inx.h:1 +#, fuzzy +msgid "EPSI Output" +msgstr "Kəs" + +#: ../share/extensions/epsi_output.inx.h:2 +msgid "Encapsulated Postscript Interchange (*.epsi)" +msgstr "" + +#: ../share/extensions/epsi_output.inx.h:3 +msgid "Encapsulated Postscript with a thumbnail" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:1 ../share/extensions/ffms.inx.h:1 +#: ../share/extensions/ffset.inx.h:1 ../share/extensions/ffss.inx.h:1 +#, fuzzy +msgid "Bridge Width" +msgstr "En" + +#: ../share/extensions/ffmet.inx.h:2 ../share/extensions/ffms.inx.h:2 +msgid "First String Length" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:3 +msgid "FretFind Multi Length ET" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:4 ../share/extensions/ffms.inx.h:4 +#: ../share/extensions/ffset.inx.h:3 ../share/extensions/ffss.inx.h:3 +msgid "Fretboard Edges" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:5 ../share/extensions/ffms.inx.h:5 +msgid "Last String Length" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:6 ../share/extensions/ffms.inx.h:6 +#: ../share/extensions/ffset.inx.h:4 ../share/extensions/ffss.inx.h:4 +msgid "Number of Frets" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:7 ../share/extensions/ffms.inx.h:7 +#: ../share/extensions/ffset.inx.h:5 ../share/extensions/ffss.inx.h:5 +msgid "Number of Strings" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:8 ../share/extensions/ffms.inx.h:8 +#: ../share/extensions/ffset.inx.h:6 ../share/extensions/ffss.inx.h:6 +#, fuzzy +msgid "Nut Width" +msgstr "En:" + +#: ../share/extensions/ffmet.inx.h:9 ../share/extensions/ffms.inx.h:10 +msgid "Perpendicular Distance" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:10 ../share/extensions/ffset.inx.h:7 +msgid "Scale Base (2 for Octave)" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:11 ../share/extensions/ffset.inx.h:9 +msgid "Tones in Scale" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:12 ../share/extensions/ffms.inx.h:12 +#: ../share/extensions/ffset.inx.h:10 ../share/extensions/ffss.inx.h:10 +msgid "px per Unit" +msgstr "" + +#: ../share/extensions/ffms.inx.h:3 +msgid "FretFind Multi Length Scala" +msgstr "" + +#: ../share/extensions/ffms.inx.h:9 ../share/extensions/ffss.inx.h:7 +msgid "Path to Scala *.scl File" +msgstr "" + +#: ../share/extensions/ffms.inx.h:11 +msgid "Tuning (scale step for each string seperated by semicolons)" +msgstr "" + +#: ../share/extensions/ffset.inx.h:2 +msgid "FretFind Single Length ET" +msgstr "" + +#: ../share/extensions/ffset.inx.h:8 ../share/extensions/ffss.inx.h:8 +msgid "Scale Length" +msgstr "" + +#: ../share/extensions/ffss.inx.h:2 +msgid "FretFind Single Length Scala" +msgstr "" + +#: ../share/extensions/ffss.inx.h:9 +msgid "Tuning (Scale step for each string seperated by semicolons)" +msgstr "" + +#: ../share/extensions/handles.inx.h:1 +#, fuzzy +msgid "Draw Handles" +msgstr "Dynahand cızığı çək" + +#: ../share/extensions/interp.inx.h:1 +#, fuzzy +msgid "Duplicate Endpaths" +msgstr "Cütləşdir" + +#: ../share/extensions/interp.inx.h:2 +#, fuzzy +msgid "Exponent" +msgstr "Ver" + +#: ../share/extensions/interp.inx.h:3 +msgid "Interpolate" +msgstr "" + +#: ../share/extensions/interp.inx.h:4 +msgid "Interpolate Style (Experimental)" +msgstr "" + +#: ../share/extensions/interp.inx.h:5 +msgid "Interpolation Method" +msgstr "" + +#: ../share/extensions/interp.inx.h:6 +msgid "Interpolation Steps" +msgstr "" + +#: ../share/extensions/kochify.inx.h:1 +msgid "Kochify" +msgstr "" + +#: ../share/extensions/kochify_load.inx.h:1 +msgid "Kochify (Load)" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:1 +#, fuzzy +msgid "Angle" +msgstr "bucaq" + +#: ../share/extensions/lindenmayer.inx.h:2 +msgid "Axiom" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:3 +#, fuzzy +msgid "Lindenmayer" +msgstr "Sıfırla" + +#: ../share/extensions/lindenmayer.inx.h:4 +msgid "Order" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:5 +#, fuzzy +msgid "Rules" +msgstr "Fayl" + +#: ../share/extensions/lindenmayer.inx.h:6 +#, fuzzy +msgid "Step" +msgstr "Miqyas" + +#: ../share/extensions/motion.inx.h:1 +#, fuzzy +msgid "Direction" +msgstr "Yer" + +#: ../share/extensions/motion.inx.h:2 +msgid "Magnitude" +msgstr "" + +#: ../share/extensions/motion.inx.h:3 +#, fuzzy +msgid "Motion" +msgstr "Seçki" + +#: ../share/extensions/pdf_output.inx.h:1 +msgid "Adobe PDF (*.pdf)" +msgstr "" + +#: ../share/extensions/pdf_output.inx.h:2 +msgid "Adobe Portable Document Format" +msgstr "" + +#: ../share/extensions/pdf_output.inx.h:3 +#, fuzzy +msgid "PDF Output" +msgstr "Kəs" + +#: ../share/extensions/ps_input.inx.h:1 +#, fuzzy +msgid "Postscript" +msgstr "Nöqtə" + +#: ../share/extensions/ps_input.inx.h:2 +msgid "Postscript (*.ps)" +msgstr "" + +#: ../share/extensions/ps_input.inx.h:3 +msgid "Postscript Input" +msgstr "" + +#: ../share/extensions/radiusrand.inx.h:1 +#, fuzzy +msgid "Radius" +msgstr "Sıfırla" + +#: ../share/extensions/radiusrand.inx.h:2 +#, fuzzy +msgid "Radius Randomize" +msgstr "Sıfırla" + +#: ../share/extensions/radiusrand.inx.h:3 +msgid "Randomize Control Points" +msgstr "" + +#: ../share/extensions/radiusrand.inx.h:4 +#, fuzzy +msgid "Randomize Nodes" +msgstr "Sıfırla" + +#: ../share/extensions/rtree.inx.h:1 +#, fuzzy +msgid "Initial Size" +msgstr "Kağız böyüklüyü:" + +#: ../share/extensions/rtree.inx.h:2 +msgid "Minimum Size" +msgstr "" + +#: ../share/extensions/rtree.inx.h:3 +msgid "Random Tree" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:1 +msgid "A diagram created with the program Sketch" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:2 +msgid "Sketch Diagram (*.sk)" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:3 +msgid "Sketch Input" +msgstr "" + +#: ../share/extensions/straightseg.inx.h:1 +msgid "Behavior" +msgstr "" + +#: ../share/extensions/straightseg.inx.h:3 +msgid "Segment Straightener" +msgstr "" + +#: ../share/extensions/summersnight.inx.h:1 +msgid "Summer's Night" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:1 +#: ../share/extensions/svgz_output.inx.h:1 +msgid "Compressed Inkscape SVG (*.svgz)" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:2 +#: ../share/extensions/svgz_output.inx.h:2 +msgid "Inkscape's native file format compressed with GZip" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:3 +msgid "SVGZ Input" +msgstr "" + +#: ../share/extensions/svgz_output.inx.h:3 +#, fuzzy +msgid "SVGZ Output" +msgstr "Kəs" + +#: ../share/extensions/txt2svg.inx.h:1 +msgid "ASCII Text" +msgstr "" + +#: ../share/extensions/txt2svg.inx.h:2 +msgid "Text File (*.txt)" +msgstr "" + +#: ../share/extensions/txt2svg.inx.h:3 +#, fuzzy +msgid "Text Input" +msgstr "Başlama rəngi" + +#: ../share/extensions/wavy.inx.h:1 +msgid "Calculate first derivative numerically" +msgstr "" + +#: ../share/extensions/wavy.inx.h:2 +msgid "First derivative" +msgstr "" + +#: ../share/extensions/wavy.inx.h:3 +msgid "Function" +msgstr "" + +#: ../share/extensions/wavy.inx.h:4 +msgid "Function Plotter" +msgstr "" + +#: ../share/extensions/wavy.inx.h:5 +msgid "Nodes per period" +msgstr "" + +#: ../share/extensions/wavy.inx.h:6 +msgid "Periods (2*Pi each)" +msgstr "" + +#: ../share/extensions/whirl.inx.h:1 +msgid "Amount of Whirl" +msgstr "" + +#: ../share/extensions/whirl.inx.h:2 +#, fuzzy +msgid "Center X" +msgstr "Orta" + +#: ../share/extensions/whirl.inx.h:3 +#, fuzzy +msgid "Center Y" +msgstr "Orta" + +#: ../share/extensions/whirl.inx.h:4 +#, fuzzy +msgid "Direction of Rotation" +msgstr "seçkini aşağıya çək" + +#: ../share/extensions/whirl.inx.h:5 +msgid "Whirl" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:1 +msgid "A popular graphics file format for clipart" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:2 +msgid "Windows Metafile (*.wmf)" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:3 +msgid "Windows Metafile Input" +msgstr "" + +#, fuzzy +#~ msgid "_Credits" +#~ msgstr "Rəng bit xəritəsi" + +#, fuzzy +#~ msgid "Custom canvas" +#~ msgstr "Xüsusi" + +#, fuzzy +#~ msgid "Current style" +#~ msgstr "Doldurma qurğuları" + +#, fuzzy +#~ msgid "Arrange Objects" +#~ msgstr "Cism" + +#~ msgid "deg" +#~ msgstr "dər" + +#, fuzzy +#~ msgid "Grab sensitivity" +#~ msgstr "Hassaslaşdır" + +#, fuzzy +#~ msgid "Acceleration" +#~ msgstr "Seçki" + +#, fuzzy +#~ msgid "Speed" +#~ msgstr "Qırmızı:" + +#, fuzzy +#~ msgid "Zoom in/out by" +#~ msgstr "Uzaqlaşdır" + +#, fuzzy +#~ msgid "Transform" +#~ msgstr "Dəyişdirmə" + +#, fuzzy +#~ msgid "Flip selection horizontally" +#~ msgstr "Seçkini bir lay yüksəlt" + +#, fuzzy +#~ msgid "Flip selection vertically" +#~ msgstr "Seçkini bir lay yüksəlt" + +#~ msgid "Edit" +#~ msgstr "Düzəlt" + +#~ msgid "Add" +#~ msgstr "Əlavə Et" + +#, fuzzy +#~ msgid "C_reate" +#~ msgstr "Körpü yarat" + +#, fuzzy +#~ msgid "Automatically scale Rows to fit selected objects." +#~ msgstr "Seçili cismləri qruplaşdır" + +#, fuzzy +#~ msgid "Go to root" +#~ msgstr "Düyünləri düzəlt" + +#, fuzzy +#~ msgid "X" +#~ msgstr "X:" + +#, fuzzy +#~ msgid "Y" +#~ msgstr "Y:" + +#, fuzzy +#~ msgid "R1:" +#~ msgstr "1:1" + +#, fuzzy +#~ msgid "R2:" +#~ msgstr "2:1" + +#, fuzzy +#~ msgid "Start Angle:" +#~ msgstr "Ulduz" + +#, fuzzy +#~ msgid "End Angle:" +#~ msgstr "bucaq" + +#, fuzzy +#~ msgid "Open:" +#~ msgstr "_Aç" + +#, fuzzy +#~ msgid "Revolutions:" +#~ msgstr "Seçki" + +#, fuzzy +#~ msgid "RX:" +#~ msgstr "X:" + +#, fuzzy +#~ msgid "RY:" +#~ msgstr "Y:" + +#, fuzzy +#~ msgid "Rectangle _Properties" +#~ msgstr "Mətn Xassələri" + +#, fuzzy +#~ msgid "Star _Properties" +#~ msgstr "Mətn Xassələri" + +#, fuzzy +#~ msgid "Ellipse _Properties" +#~ msgstr "Körpü Xassələri" + +#, fuzzy +#~ msgid "Spiral _Properties" +#~ msgstr "Körpü Xassələri" + +#, fuzzy +#~ msgid "Document Preferences" +#~ msgstr "Sodipodi" + +#, fuzzy +#~ msgid "Extensions Editor" +#~ msgstr "Seçkini döndər" + +#, fuzzy +#~ msgid "Preferences" +#~ msgstr "Sodipodi" + +#, fuzzy +#~ msgid "Layer Editor" +#~ msgstr "Seçkini yuxarıya çək" + +#, fuzzy +#~ msgid "Text Properties" +#~ msgstr "Mətn Xassələri" + +#, fuzzy +#~ msgid "Transformation" +#~ msgstr "Dəyişdirmə" + +#, fuzzy +#~ msgid "_Export..." +#~ msgstr "Al" + +#, fuzzy +#~ msgid "_Document Properties" +#~ msgstr "Sənəd" + +#, fuzzy +#~ msgid "In_kscape Preferences" +#~ msgstr "Sodipodi" + +#, fuzzy +#~ msgid "Select _Original Clone" +#~ msgstr "Seç" + +#, fuzzy +#~ msgid "Tile" +#~ msgstr "Fayl" + +#, fuzzy +#~ msgid "Select A_ll" +#~ msgstr "Seç" + +#, fuzzy +#~ msgid "Select Non_e" +#~ msgstr "Seçki" + +#, fuzzy +#~ msgid "Zoom _In" +#~ msgstr "Yaxınlaşdır" + +#, fuzzy +#~ msgid "Zoom _Out" +#~ msgstr "Uzaqlaşdır" + +#, fuzzy +#~ msgid "Pre_vious" +#~ msgstr "pəncərə 2" + +#, fuzzy +#~ msgid "Nex_t" +#~ msgstr "Mətn" + +#, fuzzy +#~ msgid "Tool Co_ntrols bar" +#~ msgstr "Oaf seçənəkləri" + +#, fuzzy +#~ msgid "R_ename Layer..." +#~ msgstr "Sıfırla" + +#, fuzzy +#~ msgid "D_uplicate Layer" +#~ msgstr "Cütləşdir" + +#, fuzzy +#~ msgid "_Delete Layer" +#~ msgstr "Seç" + +#, fuzzy +#~ msgid "Select Ne_xt Layer" +#~ msgstr "Seç" + +#, fuzzy +#~ msgid "Select Pre_vious Layer" +#~ msgstr "Seçki" + +#, fuzzy +#~ msgid "Select To_p Layer" +#~ msgstr "Seçki" + +#, fuzzy +#~ msgid "Move to Ne_w Layer" +#~ msgstr "Sənəd" + +#, fuzzy +#~ msgid "Move to B_ottom Layer" +#~ msgstr "seçkini aşağıya çək" + +#, fuzzy +#~ msgid "_Trace Bitmap..." +#~ msgstr "Qırıq bit xəritəsi" + +#, fuzzy +#~ msgid "_Put Text on Path" +#~ msgstr "seçkini aşağıya çək" + +#, fuzzy +#~ msgid "_Remove Text from Path" +#~ msgstr "seçkini aşağıya çək" + +#, fuzzy +#~ msgid "Freehand" +#~ msgstr "Freehand" + +#, fuzzy +#~ msgid "DynaDraw" +#~ msgstr "Çək" + +#, fuzzy +#~ msgid "Corners" +#~ msgstr "Yeni Görünüş" + +#, fuzzy +#~ msgid "Delete" +#~ msgstr "Sil" + +#, fuzzy +#~ msgid "Join" +#~ msgstr "in" + +#, fuzzy +#~ msgid "Delete Segment" +#~ msgstr "Seçkini cütləşdir" + +#, fuzzy +#~ msgid "Break" +#~ msgstr "Qara:" + +#, fuzzy +#~ msgid "Symmetric" +#~ msgstr "Asimetrik" + +#, fuzzy +#~ msgid "Line" +#~ msgstr "Körpü" + +#~ msgid "New" +#~ msgstr "Yeni" + +#, fuzzy +#~ msgid "Save" +#~ msgstr "Şəkil" + +#, fuzzy +#~ msgid "Save As..." +#~ msgstr "Faylı qeyd et" + +#, fuzzy +#~ msgid "Import..." +#~ msgstr "Al" + +#, fuzzy +#~ msgid "Export..." +#~ msgstr "Ver" + +#, fuzzy +#~ msgid "Print..." +#~ msgstr "Nöqtə" + +#, fuzzy +#~ msgid "Global Inkscape preferences (Shift+Ctrl+P)" +#~ msgstr "Doldurma qurğuları" + +#, fuzzy +#~ msgid "Undo" +#~ msgstr "Qaytar " + +#, fuzzy +#~ msgid "Redo" +#~ msgstr "Yenidən Et" + +#, fuzzy +#~ msgid "Cut" +#~ msgstr "Kəs" + +#, fuzzy +#~ msgid "Copy" +#~ msgstr "Köçürt" + +#, fuzzy +#~ msgid "Duplicate selected object(s) (Ctrl+D)" +#~ msgstr "Seçili cismləri qruplaşdır" + +#, fuzzy +#~ msgid "Clone selected object (Alt+D)" +#~ msgstr "Seçili cismləri qruplaşdır" + +#, fuzzy +#~ msgid "Zoom in (+)" +#~ msgstr "Yaxınlaşdır" + +#, fuzzy +#~ msgid "Zoom out (-)" +#~ msgstr "Uzaqlaşdır" + +#, fuzzy +#~ msgid "Zoom to 1:1 (100%) (1)" +#~ msgstr "1:1 qədər Yaxınlaşdır" + +#, fuzzy +#~ msgid "Zoom to 1:2 (50%) (2)" +#~ msgstr "1:2 qədər Yaxınlaşdır" + +#, fuzzy +#~ msgid "Zoom to 2:1 (200%) (0)" +#~ msgstr "2:1 qədər Yaxınlaşdır" + +#, fuzzy +#~ msgid "Zoom to fit selection in window (3)" +#~ msgstr "Seçkini yuxarıya çək" + +#, fuzzy +#~ msgid "Zoom to fit drawing in window (4)" +#~ msgstr "Çəkilişə yaxınlaşdır" + +#, fuzzy +#~ msgid "Zoom to fit page in window (5)" +#~ msgstr "Səhifəyə yaxınlaşdır" + +#, fuzzy +#~ msgid "Zoom to fit page width in window (6)" +#~ msgstr "Səhifəyə yaxınlaşdır" + +#, fuzzy +#~ msgid "Fill and Stroke dialog (Shift+Ctrl+F)" +#~ msgstr "Doldurma qurğuları" + +#, fuzzy +#~ msgid "Group selected objects (Ctrl+G)" +#~ msgstr "Seçili cismləri qruplaşdır" + +#, fuzzy +#~ msgid "Ungroup selected group(s) (Ctrl+U)" +#~ msgstr "Seçili cismləri qruplaşdır" + +#, fuzzy +#~ msgid "Raise selection up one step (PgUp)" +#~ msgstr "Seçkini bir lay yüksəlt" + +#, fuzzy +#~ msgid "Lower selection down one step (PgDn)" +#~ msgstr "Seçkini bir lay alçalt" + +#, fuzzy +#~ msgid "Raise selection to top (Home)" +#~ msgstr "Seçkini yuxarıya çək" + +#, fuzzy +#~ msgid "Lower selection to bottom (End)" +#~ msgstr "seçkini aşağıya çək" + +#, fuzzy +#~ msgid "Move selection to new layer" +#~ msgstr "Seçkini bir lay alçalt" + +#, fuzzy +#~ msgid "Move selection to next layer" +#~ msgstr "Seçkini bir lay alçalt" + +#, fuzzy +#~ msgid "Move selection to previous layer" +#~ msgstr "Seçili bölmani ara yaddaşa al" + +#, fuzzy +#~ msgid "Move selection to top layer" +#~ msgstr "Seçkini yuxarıya çək" + +#, fuzzy +#~ msgid "Move selection to bottom layer" +#~ msgstr "seçkini aşağıya çək" + +#, fuzzy +#~ msgid "Flip selection horizontally (H)" +#~ msgstr "Seçkini bir lay yüksəlt" + +#, fuzzy +#~ msgid "Flip selection vertically (V)" +#~ msgstr "Seçkini bir lay yüksəlt" + +#, fuzzy +#~ msgid "Align and Distribute dialog (Shift+Ctrl+A)" +#~ msgstr "Atributlar" + +#, fuzzy +#~ msgid "Convert selected object(s) to path(s) (Shift+Ctrl+C)" +#~ msgstr "seçkini aşağıya çək" + +#, fuzzy +#~ msgid "Convert selected stroke(s) to path(s) (Ctrl+Alt+C)" +#~ msgstr "seçkini aşağıya çək" + +#, fuzzy +#~ msgid "Node tool" +#~ msgstr "Düyün" + +#, fuzzy +#~ msgid "Zoom tool" +#~ msgstr "Uzaqlaşdır" + +#, fuzzy +#~ msgid "Rectangle tool" +#~ msgstr "Düzbucaqlı Dördbucaq" + +#, fuzzy +#~ msgid "Arc tool" +#~ msgstr "Başlama rəngi" + +#, fuzzy +#~ msgid "Star tool" +#~ msgstr "Başlama rəngi" + +#, fuzzy +#~ msgid "Spiral tool" +#~ msgstr "Spiral" + +#, fuzzy +#~ msgid "Freehand tool" +#~ msgstr "Freehand" + +#, fuzzy +#~ msgid "Pen tool" +#~ msgstr "Düzbucaqlı Dördbucaq" + +#, fuzzy +#~ msgid "Dropper tool" +#~ msgstr "Spiral" + +#, fuzzy +#~ msgid "Delete segment between two nodes" +#~ msgstr "Seçili cismləri qruplaşdır" + +#, fuzzy +#~ msgid "Select All in All Layers" +#~ msgstr "Seç" + +#, fuzzy +#~ msgid "Invert Selection" +#~ msgstr "Seçki" + +#, fuzzy +#~ msgid "Clean up selected path(s)" +#~ msgstr "Seçili cığırları kombinə et" + +#, fuzzy +#~ msgid "_Scripts..." +#~ msgstr "Nöqtə" + +#, fuzzy +#~ msgid "Align and Distribute" +#~ msgstr "Atributlar" + +#, fuzzy +#~ msgid "Align and Distribute Dialog" +#~ msgstr "Atributlar" + +#, fuzzy +#~ msgid "Export Dialog" +#~ msgstr "Fayl ver" + +#, fuzzy +#~ msgid "Fill and Stroke Dialog" +#~ msgstr "Doldurma qurğuları" + +#, fuzzy +#~ msgid "Inkscape Preferences" +#~ msgstr "Sodipodi" + +#, fuzzy +#~ msgid "Inkscape Preferences Dialog" +#~ msgstr "Sodipodi" + +#, fuzzy +#~ msgid "Layer Editor Dialog" +#~ msgstr "Seçkini yuxarıya çək" + +#, fuzzy +#~ msgid "Text Properties Dialog" +#~ msgstr "Mətn Xassələri" + +#, fuzzy +#~ msgid "Transformation Dialog" +#~ msgstr "Dəyişdirmə" + +#, fuzzy +#~ msgid "Tree Editor" +#~ msgstr "Düyün" + +#, fuzzy +#~ msgid "XML Editor Dialog" +#~ msgstr "Düzəlt..." + +#, fuzzy +#~ msgid "Row height:" +#~ msgstr "Hündürlük:" + +#, fuzzy +#~ msgid "Column width:" +#~ msgstr "Elips" + +#, fuzzy +#~ msgid "Creating anchor at (%g,%g)" +#~ msgstr "Ulduz çək" + +#, fuzzy +#~ msgid "Inkscape" +#~ msgstr "Sodipodi" + +#, fuzzy +#~ msgid "Alternate sign" +#~ msgstr "Doyğunluq:" + +#, fuzzy +#~ msgid "Grid emphasis color" +#~ msgstr "Son rəngi" + +#, fuzzy +#~ msgid "Background (also for export):" +#~ msgstr "Son rəngi" + +#, fuzzy +#~ msgid "Fill style" +#~ msgstr "Doldurma qurğuları" + +#, fuzzy +#~ msgid "Fill:" +#~ msgstr "Doldur" + +#, fuzzy +#~ msgid "winding" +#~ msgstr "Ä°cra edilir" + +#, fuzzy +#~ msgid "alternating" +#~ msgstr "Doyğunluq:" + +#, fuzzy +#~ msgid "Update Properties" +#~ msgstr "Üzv Xassələri" + +#, fuzzy +#~ msgid "executable" +#~ msgstr "Düzbucaqlı Dördbucaq" + +#, fuzzy +#~ msgid "file" +#~ msgstr "_Fayl" + +#, fuzzy +#~ msgid "path" +#~ msgstr "pt" + +#, fuzzy +#~ msgid "absolute" +#~ msgstr "mütləq" + +#, fuzzy +#~ msgid "SVG Files" +#~ msgstr "Fayl" + +#, fuzzy +#~ msgid "Make s_ensitive" +#~ msgstr "Hassaslaşdır" + +#, fuzzy +#~ msgid "Make i_nsensitive" +#~ msgstr "Qeyri-həssaslaşdır" + +#, fuzzy +#~ msgid "Layer Properties" +#~ msgstr "Mətn Xassələri" + +#, fuzzy +#~ msgid "Select object(s) to tile." +#~ msgstr "Seçili bölmani ara yaddaşa al" + +#~ msgid "Sensitive" +#~ msgstr "Həssas" + +#~ msgid "Active" +#~ msgstr "Fəal" + +#, fuzzy +#~ msgid "Document Name:" +#~ msgstr "Sənəd" + +#~ msgid "Visible" +#~ msgstr "Görünə bilən" + +#, fuzzy +#~ msgid "Flatness:" +#~ msgstr "Şəkil" + +#, fuzzy +#~ msgid "Other" +#~ msgstr "Sıra" + +#, fuzzy +#~ msgid "Trace: Selected object is not an image" +#~ msgstr "Seçkini bir lay yüksəlt" + +#, fuzzy +#~ msgid "object" +#~ msgstr "Cism" + +#, fuzzy +#~ msgid "Coordinates:" +#~ msgstr "Rəng bit xəritəsi" + +#, fuzzy +#~ msgid "Alignment:" +#~ msgstr "Tərəflə" + +#, fuzzy +#~ msgid "Draw arc: %s x %s" +#~ msgstr "Ulduz çək" + +#, fuzzy +#~ msgid "Draw rectangle: %s x %s" +#~ msgstr "Düzbucaqlı dördbucaq çək" + +#, fuzzy +#~ msgid "Move by %s, %s" +#~ msgstr "Daşı" + +#, fuzzy +#~ msgid "Active group" +#~ msgstr "Fəal" + +#, fuzzy +#~ msgid "typeset object" +#~ msgstr "Mətn cismi" + +#, fuzzy +#~ msgid "Pattern Fill" +#~ msgstr "Yapışdır" + +#, fuzzy +#~ msgid "_Menu" +#~ msgstr "_Aç" + +#, fuzzy +#~ msgid "Snap points to the grid" +#~ msgstr "Kənarları Aç" + +#, fuzzy +#~ msgid "Rect" +#~ msgstr "Düzbucaqlı Dördbucaq" + +#, fuzzy +#~ msgid "meters" +#~ msgstr "Millimetr" + +#, fuzzy +#~ msgid "Ru_lers" +#~ msgstr "Fayl" + +#, fuzzy +#~ msgid "Show or hide rulers" +#~ msgstr "Kənarları Aç" + +#, fuzzy +#~ msgid "_New Window" +#~ msgstr "Yeni Görünüş" + +#, fuzzy +#~ msgid "Mode:" +#~ msgstr "Daşı" + +#~ msgid "Value:" +#~ msgstr "Qiymət:" + +#, fuzzy +#~ msgid "Stroke settings" +#~ msgstr "Doldurma qurğuları" + +#, fuzzy +#~ msgid "Quit" +#~ msgstr "Çı_x" + +#, fuzzy +#~ msgid "Combine multiple paths" +#~ msgstr "Seçili cığırları kombinə et" + +#, fuzzy +#~ msgid "New View" +#~ msgstr "Yeni Görünüş" + +#, fuzzy +#~ msgid "Fill and stroke settings" +#~ msgstr "Doldurma qurğuları" + +#, fuzzy +#~ msgid "Object transformations" +#~ msgstr "Dönüşdürməni sıfırla" + +#, fuzzy +#~ msgid "Fill Rule" +#~ msgstr "Doldur" + +#, fuzzy +#~ msgid "Tool has no options" +#~ msgstr "Oaf seçənəkləri" + +#, fuzzy +#~ msgid "Visual transformation" +#~ msgstr "Dönüşdürməni sıfırla" + +#, fuzzy +#~ msgid "Show content" +#~ msgstr "İçindəkilər" + +#, fuzzy +#~ msgid "Selected object has no curve, cannot outline." +#~ msgstr "Seçili bölmani ara yaddaşa al" + +#, fuzzy +#~ msgid "Inkscape _Options" +#~ msgstr "Sodipodi" + +#, fuzzy +#~ msgid "Tool Optio_ns" +#~ msgstr "Oaf seçənəkləri" + +#, fuzzy +#~ msgid "nonzero" +#~ msgstr "heç biri" + +#, fuzzy +#~ msgid "" +#~ "%s is not regular file.\n" +#~ "Although inkscape will run, you can\n" +#~ "neither load nor save preferences\n" +#~ msgstr "" +#~ "%s yaradıla bilmir.\n" +#~ "Sodipodi işləsə də siz\n" +#~ "xassələri yükləyə ya da\n" +#~ "qeyd edə bilməyəcəksiniz." + +#, fuzzy +#~ msgid "" +#~ "%s either is not valid xml file or\n" +#~ "you do not have read premissions on it.\n" +#~ "Although inkscape will run, you\n" +#~ "are neither able to load nor save\n" +#~ "preferences." +#~ msgstr "" +#~ "%s hökmlü sodipodi xassələr faylı deyildir.\n" +#~ "Sodipodi işləsə də siz\n" +#~ "xassələri yükləyə ya da\n" +#~ "qeyd edə bilməyəcəksiniz." + +#, fuzzy +#~ msgid "" +#~ "%s is not valid inkscape preferences file.\n" +#~ "Although inkscape will run, you\n" +#~ "are neither able to load nor save\n" +#~ "preferences." +#~ msgstr "" +#~ "%s hökmlü sodipodi xassələr faylı deyildir.\n" +#~ "Sodipodi işləsə də siz\n" +#~ "xassələri yükləyə ya da\n" +#~ "qeyd edə bilməyəcəksiniz." + +#, fuzzy +#~ msgid "" +#~ "Cannot create directory %s.\n" +#~ "Although inkscape will run, you\n" +#~ "are neither able to load nor save\n" +#~ "%s." +#~ msgstr "" +#~ "%s cərgəsi yaradıla bilmir.\n" +#~ "Sodipodi işləsə də siz\n" +#~ "xassələri yükləyə ya da\n" +#~ "qeyd edə bilməyəcəksiniz." + +#, fuzzy +#~ msgid "" +#~ "%s is not a valid directory.\n" +#~ "Although inkscape will run, you\n" +#~ "are neither able to load nor save\n" +#~ "preferences." +#~ msgstr "" +#~ "%s hökmlü cərgə deyildir.\n" +#~ "Sodipodi işləsə də siz\n" +#~ "xassələri yükləyə ya da\n" +#~ "qeyd edə bilməyəcəksiniz." + +#, fuzzy +#~ msgid "" +#~ "Cannot create file %s.\n" +#~ "Although inkscape will run, you\n" +#~ "are neither able to load nor save\n" +#~ "preferences." +#~ msgstr "" +#~ "%s yaradıla bilmir.\n" +#~ "Sodipodi işləsə də siz\n" +#~ "xassələri yükləyə ya da\n" +#~ "qeyd edə bilməyəcəksiniz." + +#, fuzzy +#~ msgid "" +#~ "Cannot write file %s.\n" +#~ "Although inkscape will run, you\n" +#~ "are neither able to load nor save\n" +#~ "preferences." +#~ msgstr "" +#~ "%s yazıla bilmir.\n" +#~ "Sodipodi işləsə də siz\n" +#~ "xassələri yükləyə ya da\n" +#~ "qeyd edə bilməyəcəksiniz." + +#~ msgid "End color" +#~ msgstr "Son rəngi" + +#, fuzzy +#~ msgid "Make sides flat" +#~ msgstr "Hassaslaşdır" + +#~ msgid "Bring to _Front" +#~ msgstr "_Qabağa Gətir" + +#~ msgid "Send to _Back" +#~ msgstr "Da_la apar" + +#, fuzzy +#~ msgid "Object Size and Position" +#~ msgstr "Yer" + +#, fuzzy +#~ msgid "Size and Position" +#~ msgstr "Yer" + +#, fuzzy +#~ msgid "Tool attributes" +#~ msgstr "Atributlar" + +#, fuzzy +#~ msgid "Proportion" +#~ msgstr "Yer" + +#~ msgid "Group Properties" +#~ msgstr "Qrup Xassələri" + +#~ msgid "Ungroup" +#~ msgstr "Qrupu Qaldır" + +#~ msgid "Fill settings" +#~ msgstr "Doldurma qurğuları" + +#, fuzzy +#~ msgid "Bring to Front" +#~ msgstr "_Qabağa Gətir" + +#, fuzzy +#~ msgid "Send to Back" +#~ msgstr "Da_la apar" + +#, fuzzy +#~ msgid "Lower selected objects to bottom" +#~ msgstr "seçkini aşağıya çək" + +#, fuzzy +#~ msgid "Lower selected objects one position" +#~ msgstr "seçkini aşağıya çək" + +#, fuzzy +#~ msgid "Draw freehand curves and straight lines" +#~ msgstr "Freehand cızığı çək" + +#, fuzzy +#~ msgid "In" +#~ msgstr "Ä°nç" + +#, fuzzy +#~ msgid "Toggle grid" +#~ msgstr "Kənarları Aç" + +#~ msgid "1:1" +#~ msgstr "1:1" + +#~ msgid "1:2" +#~ msgstr "1:2" + +#~ msgid "2:1" +#~ msgstr "2:1" + +#, fuzzy +#~ msgid "Editing window properties" +#~ msgstr "Körpü Xassələri" + +#, fuzzy +#~ msgid "Tool Attributes" +#~ msgstr "Atributlar" + +#~ msgid "Sodipodi" +#~ msgstr "Sodipodi" + +#, fuzzy +#~ msgid "Object style" +#~ msgstr "Cism" + +#, fuzzy +#~ msgid "New Docked Toolbox" +#~ msgstr "Vasitə Qutusunu Göstər" + +#, fuzzy +#~ msgid "Drawing Mode" +#~ msgstr "Məzmun çəkilir" + +#, fuzzy +#~ msgid "" +#~ "%s is not regular file.\n" +#~ "Although inkscape will run, you are\n" +#~ "not able to use extensions (plugins)\n" +#~ msgstr "" +#~ "%s yaradıla bilmir.\n" +#~ "Sodipodi işləsə də siz\n" +#~ "xassələri yükləyə ya da\n" +#~ "qeyd edə bilməyəcəksiniz." + +#, fuzzy +#~ msgid "" +#~ "%s either is not valid xml file or\n" +#~ "you do not have read premissions on it.\n" +#~ "Although inkscape will run, you are\n" +#~ "not able to use extensions (plugins)\n" +#~ msgstr "" +#~ "%s hökmlü sodipodi xassələr faylı deyildir.\n" +#~ "Sodipodi işləsə də siz\n" +#~ "xassələri yükləyə ya da\n" +#~ "qeyd edə bilməyəcəksiniz." + +#, fuzzy +#~ msgid "" +#~ "%s is not valid inkscape extensions file.\n" +#~ "Although inkscape will run, you are\n" +#~ "not able to use extensions (plugins)\n" +#~ msgstr "" +#~ "%s hökmlü sodipodi xassələr faylı deyildir.\n" +#~ "Sodipodi işləsə də siz\n" +#~ "xassələri yükləyə ya da\n" +#~ "qeyd edə bilməyəcəksiniz." + +#, fuzzy +#~ msgid "" +#~ "Cannot create directory %s.\n" +#~ "Although inkscape will run, you are\n" +#~ "not able to use extensions (plugins)\n" +#~ msgstr "" +#~ "%s cərgəsi yaradıla bilmir.\n" +#~ "Sodipodi işləsə də siz\n" +#~ "xassələri yükləyə ya da\n" +#~ "qeyd edə bilməyəcəksiniz." + +#, fuzzy +#~ msgid "" +#~ "%s is not a valid directory.\n" +#~ "Although inkscape will run, you are\n" +#~ "not able to use extensions (plugins)\n" +#~ msgstr "" +#~ "%s hökmlü cərgə deyildir.\n" +#~ "Sodipodi işləsə də siz\n" +#~ "xassələri yükləyə ya da\n" +#~ "qeyd edə bilməyəcəksiniz." + +#, fuzzy +#~ msgid "" +#~ "Cannot create file %s.\n" +#~ "Although inkscape will run, you are\n" +#~ "not able to use extensions (plugins)\n" +#~ msgstr "" +#~ "%s yaradıla bilmir.\n" +#~ "Sodipodi işləsə də siz\n" +#~ "xassələri yükləyə ya da\n" +#~ "qeyd edə bilməyəcəksiniz." + +#, fuzzy +#~ msgid "" +#~ "Cannot write file %s.\n" +#~ "Although inkscape will run, you are\n" +#~ "not able to use extensions (plugins)\n" +#~ msgstr "" +#~ "%s yazıla bilmir.\n" +#~ "Sodipodi işləsə də siz\n" +#~ "xassələri yükləyə ya da\n" +#~ "qeyd edə bilməyəcəksiniz." + +#~ msgid "Unknown item :-(" +#~ msgstr "Naməlum üzv :-(" + +#, fuzzy +#~ msgid "Zoom in drawing" +#~ msgstr "Çəkilişə yaxınlaşdır" + +#, fuzzy +#~ msgid "Set zoom factor to 1:1" +#~ msgstr "1:1 qədər Yaxınlaşdır" + +#, fuzzy +#~ msgid "Set zoom factor to 1:2" +#~ msgstr "1:2 qədər Yaxınlaşdır" + +#, fuzzy +#~ msgid "Set zoom factor to 2:1" +#~ msgstr "2:1 qədər Yaxınlaşdır" + +#~ msgid "Document" +#~ msgstr "Sənəd" + +#, fuzzy +#~ msgid "Save document as" +#~ msgstr "Sənəd" + +#, fuzzy +#~ msgid "About sodipodi" +#~ msgstr "Sodipodi" + +#, fuzzy +#~ msgid "About Sodipodi" +#~ msgstr "Sodipodi" + +#, fuzzy +#~ msgid "Position and size" +#~ msgstr "Yer" + +#~ msgid "Dynahand" +#~ msgstr "Dynahand" + +#, fuzzy +#~ msgid "Display Properties" +#~ msgstr "Körpü Xassələri" + +#, fuzzy +#~ msgid "Lower selected objects one level" +#~ msgstr "Seçkini bir lay alçalt" + +#, fuzzy +#~ msgid "Select tool - select and transform objects" +#~ msgstr "Seç və döndər" + +#~ msgid "centimeter" +#~ msgstr "santimetr" + +#~ msgid "millimeters" +#~ msgstr "millimetr" + +#~ msgid "points" +#~ msgstr "nöqtə" + +#~ msgid "Desktop" +#~ msgstr "Masa üstü" + +#~ msgid "Drawing Context" +#~ msgstr "Məzmun Çəkilir" + +#~ msgid "XML Tree" +#~ msgstr "XML Ağacı" + +#~ msgid "Drawing context" +#~ msgstr "Məzmun çəkilir" + +#~ msgid "Import " +#~ msgstr "Al" + +#~ msgid "Paste from clipboard" +#~ msgstr "Ara yaddaşdan yapışdır" + +#~ msgid "Preview print drawing" +#~ msgstr "Çəkiliş çapını nümayiş et" + +#~ msgid "Quit or not quit ?" +#~ msgstr "Çıxımmı yoxsa Çıxmayımmı?" + +#~ msgid "Save drawing " +#~ msgstr "Çkilişi qeyd et" + +#~ msgid "Orig. Width: " +#~ msgstr "Əsl En: " + +#~ msgid "Orig. X: " +#~ msgstr "Əsl X: " + +#~ msgid "Y: " +#~ msgstr "Y: " + +#~ msgid "select direction" +#~ msgstr "istiqaməti seç" + +#, fuzzy +#~ msgid "Change Content" +#~ msgstr "Məzmun Çəkilir" + +#~ msgid "Key" +#~ msgstr "Açar" + +#, fuzzy +#~ msgid "You can't delete 'id' attribute!" +#~ msgstr "Atributu sil" + +#, fuzzy +#~ msgid "Do you want to delete attribute %s?" +#~ msgstr "Atributu sil" + +#, fuzzy +#~ msgid "No" +#~ msgstr "Düyün" + +#~ msgid "Draw ellipse" +#~ msgstr "Elləps çək" + +#~ msgid "Could not initialize Bonobo" +#~ msgstr "Bonobonu başlada bilmədim" diff --git a/po/bad.po.test b/po/bad.po.test new file mode 100644 index 000000000..a3f5a42e7 --- /dev/null +++ b/po/bad.po.test @@ -0,0 +1,85 @@ +# A test case for check-markup. Contains 13 bad entries, 4 good entries. +msgid "" +msgstr "" + +msgid "bad1: odd number of quotes" +msgstr """ + +msgid "bad2: unclosed" +msgstr " + +msgid "bad3: no msgstr line" + +msgid "bad4: no msgstr value" +msgstr + +msgid "bad5: escaped backslash doesn't escape quote" +msgstr "\\"" + +msgid "VALID: quote is escaped" +msgstr "\"" + +msgid "bad6" +msgstr "x" + +msgid "bad7" +msgstr ">" + +msgid "bad8" +msgstr "a>" + +msgid "bad9" +msgstr "a" + +msgid "bad10" +msgstr "<" + +msgid "bad11" +msgstr "a<" + +msgid "bad12" +msgstr "a" + +msgid "bad13" +msgstr "a<>" + +msgid "bad14" +msgstr "a" + +msgid "bad15" +msgstr "a" + +msgid "bad16" +msgstr "aa" + +msgid "VALID" +msgstr "aa" + +msgid "VALID" +# some +# comments +msgstr "" + +msgid "VALID" +msgstr "" +# some +# comments + +#, fuzzy +#~ msgid "VALID" +#~ msgstr "dead string" + +msgid "bad17" +msgstr "hi" + +msgid "VALID" +msgstr "hi" + +msgid "bad18" +msgstr "hi" + +msgid "bad19: trailing whitespace" +msgstr "tabs etc. after string." diff --git a/po/bad.po.test.exp b/po/bad.po.test.exp new file mode 100644 index 000000000..3959bde70 --- /dev/null +++ b/po/bad.po.test.exp @@ -0,0 +1,74 @@ +bad.po.test: Mismatched quotes: +msgid "bad1: odd number of quotes" +msgstr """ + +bad.po.test: Mismatched quotes: +msgid "bad2: unclosed" +msgstr " + +bad.po.test: Not in msg format: +msgid "bad3: no msgstr line" + +bad.po.test: Mismatched quotes: +msgid "bad4: no msgstr value" +msgstr + +bad.po.test: Mismatched quotes: +msgid "bad5: escaped backslash doesn't escape quote" +msgstr "\\"" + +bad.po.test: unclosed : +msgid "bad6" +msgstr "x" + +bad.po.test: unclosed : +msgid "bad7" +msgstr ">" + +bad.po.test: unclosed : +msgid "bad8" +msgstr "a>" + +bad.po.test: unclosed : +msgid "bad9" +msgstr "a" + +bad.po.test: unclosed : +msgid "bad10" +msgstr "<" + +bad.po.test: unclosed : +msgid "bad11" +msgstr "a<" + +bad.po.test: unclosed : +msgid "bad12" +msgstr "a" + +bad.po.test: unclosed : +msgid "bad13" +msgstr "a<>" + +bad.po.test: unclosed : +msgid "bad14" +msgstr "a" + +bad.po.test: unclosed : +msgid "bad15" +msgstr "a" + +bad.po.test: unclosed : +msgid "bad16" +msgstr "a can't have attributes in Pango: +msgid "bad17" +msgstr "hi" + +bad.po.test: Unexpected attributes `fdsa="bold"': +msgid "bad18" +msgstr "hi" + +bad.po.test: Trailing whitespace: +msgid "bad19: trailing whitespace" +msgstr "tabs etc. after string." diff --git a/po/be.po b/po/be.po new file mode 100644 index 000000000..9296cc7b9 --- /dev/null +++ b/po/be.po @@ -0,0 +1,10986 @@ +# translation of be.po to Belarusian +# translation of sodipodi.HEAD.po to Belarusian +# This file is distributed under the same license as the PACKAGE package. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# Vital Khilko , 2003 +# +msgid "" +msgstr "" +"Project-Id-Version: be\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2005-12-04 11:51-0800\n" +"PO-Revision-Date: 2003-07-20 16:00+0300\n" +"Last-Translator: Vital Khilko \n" +"Language-Team: Belarusian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 1.0\n" + +#: ../inkscape.desktop.in.h:1 +#, fuzzy +msgid "Create and edit Scalable Vector Graphics images" +msgstr "Фармат здольнай маштабавацца вэктарнай графікі" + +#: ../inkscape.desktop.in.h:2 +#, fuzzy +msgid "Inkscape SVG Vector Illustrator" +msgstr "Рэдактар вэктарнае графікі" + +#: ../../po/../src/arc-context.cpp:350 +msgid "" +"Ctrl: make circle or integer-ratio ellipse, snap arc/segment angle" +msgstr "" + +#: ../../po/../src/arc-context.cpp:351 ../../po/../src/rect-context.cpp:388 +msgid "Shift: draw around the starting point" +msgstr "" + +#: ../../po/../src/arc-context.cpp:413 +#: ../../po/../src/connector-context.cpp:493 +#: ../../po/../src/dyna-draw-context.cpp:506 +#: ../../po/../src/pen-context.cpp:329 ../../po/../src/pencil-context.cpp:208 +#: ../../po/../src/rect-context.cpp:452 ../../po/../src/spiral-context.cpp:421 +#: ../../po/../src/star-context.cpp:427 +msgid "Current layer is hidden. Unhide it to be able to draw on it." +msgstr "" + +#: ../../po/../src/arc-context.cpp:417 +#: ../../po/../src/connector-context.cpp:497 +#: ../../po/../src/dyna-draw-context.cpp:510 +#: ../../po/../src/pen-context.cpp:336 ../../po/../src/pencil-context.cpp:212 +#: ../../po/../src/rect-context.cpp:456 ../../po/../src/spiral-context.cpp:426 +#: ../../po/../src/star-context.cpp:431 +msgid "Current layer is locked. Unlock it to be able to draw on it." +msgstr "" + +#: ../../po/../src/arc-context.cpp:496 +#, c-format +msgid "" +"Ellipse: %s × %s; with Ctrl to make circle or integer-" +"ratio ellipse; with Shift to draw around the starting point" +msgstr "" + +#: ../../po/../src/connector-context.cpp:518 +#, fuzzy +msgid "Creating new connector" +msgstr "Стварае новы дакумэнт SVG" + +#: ../../po/../src/connector-context.cpp:939 +#, fuzzy +msgid "Finishing connector" +msgstr "Вольная рыса" + +#: ../../po/../src/connector-context.cpp:1108 +msgid "Connection point: click or drag to create a new connector" +msgstr "" + +#: ../../po/../src/connector-context.cpp:1185 +msgid "Connector endpoint: drag to reroute or connect to new shapes" +msgstr "" + +#: ../../po/../src/connector-context.cpp:1278 +#, fuzzy +msgid "Select at least one non-connector object." +msgstr "Вылучае ўсе аб'екты ў дакумэнце" + +#: ../../po/../src/desktop-events.cpp:238 +#, c-format +msgid "%s at %s" +msgstr "" + +#. TRANSLATORS: This string appears when double-clicking on a guide. +#. This is the distance by which the guide is to be moved. +#: ../../po/../src/desktop-events.cpp:277 +#, fuzzy +msgid " relative by " +msgstr "Адноснае перамяшчэньне" + +#. TRANSLATORS: This string appears when double-clicking on a guide. +#. This is the target location where the guide is to be moved. +#: ../../po/../src/desktop-events.cpp:282 +#: ../../po/../src/desktop-events.cpp:395 +msgid " absolute to " +msgstr "" + +#. create dialog +#: ../../po/../src/desktop-events.cpp:348 +#, fuzzy +msgid "Guideline" +msgstr "Колер кіруючых рысаў" + +#: ../../po/../src/desktop-events.cpp:432 +#, fuzzy, c-format +msgid "Move %s" +msgstr "Перанесьці" + +#: ../../po/../src/desktop.cpp:678 +msgid "No previous zoom." +msgstr "" + +#: ../../po/../src/desktop.cpp:703 +msgid "No next zoom." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:182 +#, fuzzy +msgid "Nothing selected." +msgstr "Другі вылучаны" + +#: ../../po/../src/dialogs/clonetiler.cpp:188 +msgid "More than one object selected." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:195 +#, c-format +msgid "Object has %d tiled clones." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:200 +msgid "Object has no tiled clones." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:865 +#, fuzzy +msgid "Select one object whose tiled clones to unclump." +msgstr "Выразае вылучаныя аб'екты ў буфэр абмену" + +#: ../../po/../src/dialogs/clonetiler.cpp:916 +#, fuzzy +msgid "Select one object whose tiled clones to remove." +msgstr "Выразае вылучаныя аб'екты ў буфэр абмену" + +#: ../../po/../src/dialogs/clonetiler.cpp:984 +#: ../../po/../src/selection-chemistry.cpp:1774 +#, fuzzy +msgid "Select an object to clone." +msgstr "Выразае вылучаныя аб'екты ў буфэр абмену" + +#: ../../po/../src/dialogs/clonetiler.cpp:990 +#: ../../po/../src/selection-chemistry.cpp:1780 +msgid "" +"If you want to clone several objects, group them and clone the " +"group." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1484 +msgid "Per row:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1497 +#, fuzzy +msgid "Per column:" +msgstr "Градыент не вылучаны" + +#: ../../po/../src/dialogs/clonetiler.cpp:1505 +#, fuzzy +msgid "Randomize:" +msgstr "Другі вылучаны" + +#: ../../po/../src/dialogs/clonetiler.cpp:1656 +msgid "_Symmetry" +msgstr "" + +#. TRANSLATORS: For the following 17 symmetry groups, see +#. * http://www.bib.ulb.ac.be/coursmath/doc/17.htm (visual examples); +#. * http://www.clarku.edu/~djoyce/wallpaper/seventeen.html (English vocabulary); or +#. * http://membres.lycos.fr/villemingerard/Geometri/Sym1D.htm (French vocabulary). +#. +#: ../../po/../src/dialogs/clonetiler.cpp:1664 +msgid "Select one of the 17 symmetry groups for the tiling" +msgstr "" + +#. TRANSLATORS: "translation" means "shift" / "displacement" here. +#: ../../po/../src/dialogs/clonetiler.cpp:1675 +msgid "P1: simple translation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1676 +msgid "P2: 180° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1677 +msgid "PM: reflection" +msgstr "" + +#. TRANSLATORS: "glide reflection" is a reflection and a translation combined. +#. For more info, see http://mathforum.org/sum95/suzanne/symsusan.html +#: ../../po/../src/dialogs/clonetiler.cpp:1680 +msgid "PG: glide reflection" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1681 +msgid "CM: reflection + glide reflection" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1682 +msgid "PMM: reflection + reflection" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1683 +msgid "PMG: reflection + 180° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1684 +msgid "PGG: glide reflection + 180° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1685 +msgid "CMM: reflection + reflection + 180° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1686 +msgid "P4: 90° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1687 +msgid "P4M: 90° rotation + 45° reflection" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1688 +msgid "P4G: 90° rotation + 90° reflection" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1689 +msgid "P3: 120° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1690 +msgid "P31M: reflection + 120° rotation, dense" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1691 +msgid "P3M1: reflection + 120° rotation, sparse" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1692 +msgid "P6: 60° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1693 +msgid "P6M: reflection + 60° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1721 +msgid "S_hift" +msgstr "" + +#. TRANSLATORS: "shift" means: the tiles will be shifted (offset) horizontally by this amount +#: ../../po/../src/dialogs/clonetiler.cpp:1731 +#, no-c-format +msgid "Shift X:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1739 +#, no-c-format +msgid "Horizontal shift per row (in % of tile width)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1747 +#, no-c-format +msgid "Horizontal shift per column (in % of tile width)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1754 +msgid "Randomize the horizontal shift by this percentage" +msgstr "" + +#. TRANSLATORS: "shift" means: the tiles will be shifted (offset) vertically by this amount +#: ../../po/../src/dialogs/clonetiler.cpp:1764 +#, no-c-format +msgid "Shift Y:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1772 +#, no-c-format +msgid "Vertical shift per row (in % of tile height)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1780 +#, no-c-format +msgid "Vertical shift per column (in % of tile height)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1787 +msgid "Randomize the vertical shift by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1795 +#, fuzzy +msgid "Exponent:" +msgstr "Эліпс" + +#: ../../po/../src/dialogs/clonetiler.cpp:1802 +msgid "Whether rows are spaced evenly (1), converge (<1) or diverge (>1)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1809 +msgid "Whether columns are spaced evenly (1), converge (<1) or diverge (>1)" +msgstr "" + +#. TRANSLATORS: "Alternate" is a verb here +#: ../../po/../src/dialogs/clonetiler.cpp:1817 +#: ../../po/../src/dialogs/clonetiler.cpp:1907 +#: ../../po/../src/dialogs/clonetiler.cpp:1966 +#: ../../po/../src/dialogs/clonetiler.cpp:2022 +#: ../../po/../src/dialogs/clonetiler.cpp:2153 +msgid "Alternate:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1823 +msgid "Alternate the sign of shifts for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1828 +msgid "Alternate the sign of shifts for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1837 +#, fuzzy +msgid "Sc_ale" +msgstr "Маштаб" + +#: ../../po/../src/dialogs/clonetiler.cpp:1845 +#, fuzzy +msgid "Scale X:" +msgstr "Прамакутнік" + +#: ../../po/../src/dialogs/clonetiler.cpp:1853 +#, no-c-format +msgid "Horizontal scale per row (in % of tile width)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1861 +#, no-c-format +msgid "Horizontal scale per column (in % of tile width)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1868 +msgid "Randomize the horizontal scale by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1876 +#, fuzzy +msgid "Scale Y:" +msgstr "Прамакутнік" + +#: ../../po/../src/dialogs/clonetiler.cpp:1884 +#, no-c-format +msgid "Vertical scale per row (in % of tile height)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1892 +#, no-c-format +msgid "Vertical scale per column (in % of tile height)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1899 +msgid "Randomize the vertical scale by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1913 +msgid "Alternate the sign of scales for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1918 +msgid "Alternate the sign of scales for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1927 +#, fuzzy +msgid "_Rotation" +msgstr "Разрозьненьне:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1935 +#, fuzzy +msgid "Angle:" +msgstr "Прамакутнік" + +#: ../../po/../src/dialogs/clonetiler.cpp:1943 +#, no-c-format +msgid "Rotate tiles by this angle for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1951 +#, no-c-format +msgid "Rotate tiles by this angle for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1958 +msgid "Randomize the rotation angle by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1972 +msgid "Alternate the rotation direction for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1977 +msgid "Alternate the rotation direction for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1985 +#, fuzzy +msgid "_Opacity" +msgstr "Зацямненьне:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1993 +msgid "Fade out:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2000 +msgid "Decrease tile opacity by this percentage for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2007 +msgid "Decrease tile opacity by this percentage for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2014 +msgid "Randomize the tile opacity by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2028 +msgid "Alternate the sign of opacity change for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2033 +msgid "Alternate the sign of opacity change for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2041 +#, fuzzy +msgid "Co_lor" +msgstr "Закрыць" + +#: ../../po/../src/dialogs/clonetiler.cpp:2046 +#, fuzzy +msgid "Initial color: " +msgstr "Колер сеткі:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2050 +msgid "Initial color of tiled clones" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2050 +msgid "" +"Initial color for clones (works only if the original has unset fill or " +"stroke)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2065 +#, fuzzy +msgid "H:" +msgstr "Эліпс" + +#: ../../po/../src/dialogs/clonetiler.cpp:2072 +msgid "Change the tile hue by this percentage for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2079 +msgid "Change the tile hue by this percentage for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2086 +msgid "Randomize the tile hue by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2095 +#, fuzzy +msgid "S:" +msgstr "Эліпс" + +#: ../../po/../src/dialogs/clonetiler.cpp:2102 +msgid "Change the color saturation by this percentage for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2109 +msgid "Change the color saturation by this percentage for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2116 +msgid "Randomize the color saturation by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2124 +#, fuzzy +msgid "L:" +msgstr "Эліпс" + +#: ../../po/../src/dialogs/clonetiler.cpp:2131 +msgid "Change the color lightness by this percentage for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2138 +msgid "Change the color lightness by this percentage for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2145 +msgid "Randomize the color lightness by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2159 +msgid "Alternate the sign of color changes for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2164 +msgid "Alternate the sign of color changes for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2172 +#, fuzzy +msgid "_Trace" +msgstr "Трасыраваць" + +#: ../../po/../src/dialogs/clonetiler.cpp:2179 +msgid "Trace the drawing under the tiles" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2183 +msgid "" +"For each clone, pick a value from the drawing in that clone's location and " +"apply it to the clone" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2197 +msgid "1. Pick from the drawing:" +msgstr "" + +#. ----Hbox2 +#: ../../po/../src/dialogs/clonetiler.cpp:2208 +#: ../../po/../src/dialogs/clonetiler.cpp:2355 +#: ../../po/../src/ui/dialog/tracedialog.cpp:445 +#, fuzzy +msgid "Color" +msgstr "Закрыць" + +#: ../../po/../src/dialogs/clonetiler.cpp:2209 +msgid "Pick the visible color and opacity" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2216 +#: ../../po/../src/dialogs/clonetiler.cpp:2365 +#: ../share/extensions/dropshadow.inx.h:3 +#, fuzzy +msgid "Opacity" +msgstr "Зацямненьне:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2217 +msgid "Pick the total accumulated opacity" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2224 +msgid "R" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2225 +msgid "Pick the Red component of the color" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2232 +msgid "G" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2233 +msgid "Pick the Green component of the color" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2240 +msgid "B" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2241 +msgid "Pick the Blue component of the color" +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2250 +msgid "clonetiler|H" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2251 +msgid "Pick the hue of the color" +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2260 +msgid "clonetiler|S" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2261 +msgid "Pick the saturation of the color" +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2270 +msgid "clonetiler|L" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2271 +msgid "Pick the lightness of the color" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2281 +msgid "2. Tweak the picked value:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2291 +msgid "Gamma-correct:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2296 +msgid "Shift the mid-range of the picked value upwards (>0) or downwards (<0)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2303 +msgid "Randomize:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2308 +msgid "Randomize the picked value by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2315 +#, fuzzy +msgid "Invert:" +msgstr "Друкаваць" + +#: ../../po/../src/dialogs/clonetiler.cpp:2319 +msgid "Invert the picked value" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2325 +msgid "3. Apply the value to the clones':" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2335 +#, fuzzy +msgid "Presence" +msgstr "Зьберагчы" + +#: ../../po/../src/dialogs/clonetiler.cpp:2338 +msgid "" +"Each clone is created with the probability determined by the picked value in " +"that point" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2345 +#, fuzzy +msgid "Size" +msgstr "Бакі:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2348 +msgid "Each clone's size is determined by the picked value in that point" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2358 +msgid "" +"Each clone is painted by the picked color (the original must have unset fill " +"or stroke)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2368 +msgid "Each clone's opacity is determined by the picked value in that point" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2395 +msgid "How many rows in the tiling" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2415 +msgid "How many columns in the tiling" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2445 +msgid "Width of the rectangle to be filled" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2470 +msgid "Height of the rectangle to be filled" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2485 +#, fuzzy +msgid "Rows, columns: " +msgstr "Эліпс" + +#: ../../po/../src/dialogs/clonetiler.cpp:2486 +msgid "Create the specified number of rows and columns" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2495 +msgid "Width, height: " +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2496 +msgid "Fill the specified width and height with the tiling" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2512 +#, fuzzy +msgid "Use saved size and position of the tile" +msgstr "Памер і пазыцыя аб'екта" + +#: ../../po/../src/dialogs/clonetiler.cpp:2515 +msgid "" +"Pretend that the size and position of the tile are the same as the last time " +"you tiled it (if any), instead of using the current size" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2539 +#, fuzzy +msgid " _Create " +msgstr "Прамакутнік" + +#: ../../po/../src/dialogs/clonetiler.cpp:2541 +msgid "Create and tile the clones of the selection" +msgstr "" + +#. TRANSLATORS: if a group of objects are "clumped" together, then they +#. are unevenly spread in the given amount of space - as shown in the +#. diagrams on the left in the following screenshot: +#. http://www.inkscape.org/screenshots/gallery/inkscape-0.42-CVS-tiles-unclump.png +#. So unclumping is the process of spreading a number of objects out more evenly. +#: ../../po/../src/dialogs/clonetiler.cpp:2556 +msgid " _Unclump " +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2557 +msgid "Spread out clones to reduce clumping; can be applied repeatedly" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2563 +#, fuzzy +msgid " Re_move " +msgstr "Выдаліць лучыва" + +#: ../../po/../src/dialogs/clonetiler.cpp:2564 +msgid "Remove existing tiled clones of the selected object (siblings only)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2580 +#, fuzzy +msgid " R_eset " +msgstr "Выдаліць лучыва" + +#. TRANSLATORS: "change" is a noun here +#: ../../po/../src/dialogs/clonetiler.cpp:2582 +msgid "" +"Reset all shifts, scales, rotates, opacity and color changes in the dialog " +"to zero" +msgstr "" + +#: ../../po/../src/dialogs/color-picker.cpp:280 +msgid "Close" +msgstr "Закрыць" + +#: ../../po/../src/dialogs/debugdialog.cpp:138 +msgid "Messages" +msgstr "" + +#. ## Add a menu for clear() +#: ../../po/../src/dialogs/debugdialog.cpp:144 +#: ../../po/../src/menus-skeleton.h:16 +#: ../../po/../src/ui/dialog/messages.cpp:56 +#: ../../po/../src/ui/dialog/scriptdialog.cpp:181 +#, fuzzy +msgid "_File" +msgstr "Файл" + +#. TRANSLATORS: "Clear" is a verb here +#: ../../po/../src/dialogs/debugdialog.cpp:145 +#: ../../po/../src/dialogs/find.cpp:753 +#: ../../po/../src/ui/dialog/messages.cpp:57 +#: ../../po/../src/ui/dialog/scriptdialog.cpp:182 +#, fuzzy +msgid "_Clear" +msgstr "Закрыць" + +#: ../../po/../src/dialogs/debugdialog.cpp:147 +#: ../../po/../src/ui/dialog/messages.cpp:59 +msgid "Capture log messages" +msgstr "" + +#: ../../po/../src/dialogs/debugdialog.cpp:149 +#: ../../po/../src/ui/dialog/messages.cpp:61 +msgid "Release log messages" +msgstr "" + +#. Notebook tab +#: ../../po/../src/dialogs/desktop-properties.cpp:909 +#: ../../po/../src/ui/dialog/document-preferences.cpp:89 +#: ../../po/../src/ui/widget/panel.cpp:107 +msgid "Grid" +msgstr "Сетка" + +#. Checkbuttons +#. / \todo FIXME: gray out snapping when grid is off +#. / \todo FIXME: gray out snapping when grid is off. +#. / Dissenting view: you want snapping without grid. +#: ../../po/../src/dialogs/desktop-properties.cpp:917 +#: ../../po/../src/ui/dialog/document-preferences.cpp:179 +msgid "Show grid" +msgstr "Паказаць сетку" + +#: ../../po/../src/dialogs/desktop-properties.cpp:917 +#: ../../po/../src/ui/dialog/document-preferences.cpp:179 +#: ../../po/../src/verbs.cpp:2115 +#, fuzzy +msgid "Show or hide grid" +msgstr "Паказаць сетку" + +#: ../../po/../src/dialogs/desktop-properties.cpp:918 +#: ../../po/../src/ui/dialog/document-preferences.cpp:180 +#, fuzzy +msgid "Snap bounding boxes to grid" +msgstr "Раўнаць па сетке" + +#: ../../po/../src/dialogs/desktop-properties.cpp:918 +#: ../../po/../src/dialogs/desktop-properties.cpp:1001 +#: ../../po/../src/ui/dialog/document-preferences.cpp:181 +#: ../../po/../src/ui/dialog/document-preferences.cpp:236 +msgid "Snap the edges of the object bounding boxes" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:919 +#: ../../po/../src/ui/dialog/document-preferences.cpp:183 +#, fuzzy +msgid "Snap nodes to grid" +msgstr "Раўнаць па сетке" + +#: ../../po/../src/dialogs/desktop-properties.cpp:919 +#: ../../po/../src/dialogs/desktop-properties.cpp:1002 +#: ../../po/../src/ui/dialog/document-preferences.cpp:184 +#: ../../po/../src/ui/dialog/document-preferences.cpp:239 +msgid "Snap path nodes, text baselines, ellipse centers, etc." +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:937 +#: ../../po/../src/ui/dialog/document-preferences.cpp:186 +msgid "Grid units:" +msgstr "Адзінкі сеткі:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:939 +#: ../../po/../src/ui/dialog/document-preferences.cpp:187 +msgid "Origin X:" +msgstr "Зрух па Ð¥:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:942 +#: ../../po/../src/ui/dialog/document-preferences.cpp:189 +msgid "Origin Y:" +msgstr "Зрух па Y:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:945 +#: ../../po/../src/ui/dialog/document-preferences.cpp:191 +msgid "Spacing X:" +msgstr "Крок па Ð¥:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:948 +#: ../../po/../src/ui/dialog/document-preferences.cpp:193 +msgid "Spacing Y:" +msgstr "Крок па Y:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:952 +#: ../../po/../src/dialogs/desktop-properties.cpp:1013 +#: ../../po/../src/ui/dialog/document-preferences.cpp:195 +#: ../../po/../src/ui/dialog/document-preferences.cpp:241 +msgid "Snap units:" +msgstr "Адзінкі крокаў:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:955 +#: ../../po/../src/dialogs/desktop-properties.cpp:1016 +#: ../../po/../src/ui/dialog/document-preferences.cpp:196 +#: ../../po/../src/ui/dialog/document-preferences.cpp:242 +msgid "Snap distance:" +msgstr "Памер крокаў:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:958 +#: ../../po/../src/ui/dialog/document-preferences.cpp:199 +#, fuzzy +msgid "Grid line color:" +msgstr "Колер кіруючых рысаў" + +#: ../../po/../src/dialogs/desktop-properties.cpp:959 +#: ../../po/../src/ui/dialog/document-preferences.cpp:199 +#, fuzzy +msgid "Grid line color" +msgstr "Колер кіруючых рысаў" + +#: ../../po/../src/dialogs/desktop-properties.cpp:959 +#: ../../po/../src/ui/dialog/document-preferences.cpp:200 +#, fuzzy +msgid "Color of grid lines" +msgstr "Крок па Ð¥:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:961 +#: ../../po/../src/ui/dialog/document-preferences.cpp:201 +#, fuzzy +msgid "Major grid line color:" +msgstr "Колер кіруючых рысаў" + +#: ../../po/../src/dialogs/desktop-properties.cpp:962 +#: ../../po/../src/ui/dialog/document-preferences.cpp:201 +#, fuzzy +msgid "Major grid line color" +msgstr "Колер кіруючых рысаў" + +#: ../../po/../src/dialogs/desktop-properties.cpp:962 +#: ../../po/../src/ui/dialog/document-preferences.cpp:202 +msgid "Color of the major (highlighted) grid lines" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:965 +#: ../../po/../src/ui/dialog/document-preferences.cpp:204 +#, fuzzy +msgid "Major grid line every:" +msgstr "Колер кіруючых рысаў" + +#. TRANSLATORS: This belongs to the "Major grid line every:" string, +#. see grid settings in the "Document Preferences" dialog +#: ../../po/../src/dialogs/desktop-properties.cpp:977 +#: ../../po/../src/ui/dialog/document-preferences.cpp:204 +#, fuzzy +msgid "lines" +msgstr "Закрыць" + +#. Guidelines page +#: ../../po/../src/dialogs/desktop-properties.cpp:991 +#: ../../po/../src/ui/dialog/document-preferences.cpp:90 +msgid "Guides" +msgstr "Кіруючыя" + +#. / \todo FIXME: gray out snapping when guides are off +#. / Dissenting view: you want snapping without guides. +#: ../../po/../src/dialogs/desktop-properties.cpp:1000 +#: ../../po/../src/ui/dialog/document-preferences.cpp:234 +msgid "Show guides" +msgstr "Паказаць кіруючыя" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1000 +#: ../../po/../src/ui/dialog/document-preferences.cpp:234 +#: ../../po/../src/verbs.cpp:2116 +#, fuzzy +msgid "Show or hide guides" +msgstr "Паказаць кіруючыя" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1001 +#: ../../po/../src/ui/dialog/document-preferences.cpp:235 +#, fuzzy +msgid "Snap bounding boxes to guides" +msgstr "Раўнаць па кіруючых" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1002 +#: ../../po/../src/ui/dialog/document-preferences.cpp:238 +#, fuzzy +msgid "Snap points to guides" +msgstr "Раўнаць па сетке" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1020 +#: ../../po/../src/ui/dialog/document-preferences.cpp:243 +#, fuzzy +msgid "Guide color:" +msgstr "Колер кіруючых:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1021 +#: ../../po/../src/ui/dialog/document-preferences.cpp:243 +msgid "Guideline color" +msgstr "Колер кіруючых рысаў" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1021 +#: ../../po/../src/ui/dialog/document-preferences.cpp:244 +#, fuzzy +msgid "Color of guidelines" +msgstr "Адлюстраваць гарызантальна" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1023 +#: ../../po/../src/ui/dialog/document-preferences.cpp:245 +msgid "Highlight color:" +msgstr "Колер падсьвятленьня:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1024 +#: ../../po/../src/ui/dialog/document-preferences.cpp:245 +msgid "Highlighted guideline color" +msgstr "Колер падсьвятленьня кіруючых рысаў" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1024 +#: ../../po/../src/ui/dialog/document-preferences.cpp:246 +msgid "Color of a guideline when it is under mouse" +msgstr "" + +#. Page page +#: ../../po/../src/dialogs/desktop-properties.cpp:1029 +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:855 +#: ../../po/../src/ui/dialog/document-preferences.cpp:88 +#: ../../po/../src/widgets/desktop-widget.cpp:1061 +msgid "Page" +msgstr "Аркуш" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1039 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +#, fuzzy +msgid "Background:" +msgstr "Канчатковы колер" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1040 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +#, fuzzy +msgid "Background color" +msgstr "Канчатковы колер" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1041 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +msgid "" +"Color and transparency of the page background (also used for bitmap export)" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1045 +#: ../../po/../src/ui/dialog/document-preferences.cpp:147 +#, fuzzy +msgid "Show page border" +msgstr "Паказаць межы" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1049 +#: ../../po/../src/ui/dialog/document-preferences.cpp:148 +msgid "Border on top of drawing" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1052 +#: ../../po/../src/ui/dialog/document-preferences.cpp:149 +#, fuzzy +msgid "Border color:" +msgstr "Колер сеткі:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1053 +#: ../../po/../src/ui/dialog/document-preferences.cpp:149 +#, fuzzy +msgid "Page border color" +msgstr "Колер сеткі:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1054 +#: ../../po/../src/ui/dialog/document-preferences.cpp:150 +#, fuzzy +msgid "Color of the page border" +msgstr "Паказаць межы" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1059 +#: ../../po/../src/ui/dialog/document-preferences.cpp:152 +msgid "Show page shadow" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1063 +#: ../../po/../src/ui/dialog/document-preferences.cpp:153 +#, fuzzy +msgid "Default units:" +msgstr "Дапомнае" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1069 +msgid "Units for the tool controls, ruler, and the statusbar" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1086 +#: ../../po/../src/ui/widget/page-sizer.cpp:209 +#, fuzzy +msgid "Page size:" +msgstr "Памер паперы:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1110 +#: ../../po/../src/ui/widget/page-sizer.cpp:219 +msgid "Custom" +msgstr "Пазначае карыстальнік" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1121 +#: ../../po/../src/ui/widget/page-sizer.cpp:225 +#, fuzzy +msgid "Page orientation:" +msgstr "Арыентацыя:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1133 +#: ../../po/../src/ui/widget/page-sizer.cpp:232 +#, fuzzy +msgid "Landscape" +msgstr "Слайдшоў Sodipodi" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1139 +#: ../../po/../src/ui/widget/page-sizer.cpp:234 +#, fuzzy +msgid "Portrait" +msgstr "Пункт" + +#. Custom paper frame +#: ../../po/../src/dialogs/desktop-properties.cpp:1148 +#: ../../po/../src/ui/widget/page-sizer.cpp:249 +#, fuzzy +msgid "Custom size" +msgstr "Пазначае карыстальнік" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1160 +#: ../../po/../src/dialogs/export.cpp:269 +#: ../../po/../src/ui/widget/page-sizer.cpp:261 +msgid "Units:" +msgstr "Адзінкі:" + +#. Stroke width +#: ../../po/../src/dialogs/desktop-properties.cpp:1162 +#: ../../po/../src/dialogs/export.cpp:310 +#: ../../po/../src/dialogs/object-attributes.cpp:55 +#: ../../po/../src/dialogs/stroke-style.cpp:985 +#: ../../po/../src/ui/widget/page-sizer.cpp:262 +#: ../../po/../src/widgets/toolbox.cpp:1957 +msgid "Width:" +msgstr "Шырыня:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1183 +#: ../../po/../src/dialogs/export.cpp:326 +#: ../../po/../src/dialogs/export.cpp:431 +#: ../../po/../src/dialogs/object-attributes.cpp:56 +#: ../../po/../src/ui/widget/page-sizer.cpp:263 +msgid "Height:" +msgstr "Вышыня:" + +#. +#. * Ownership metadata tab +#. +#: ../../po/../src/dialogs/desktop-properties.cpp:1206 +msgid "Metadata" +msgstr "" + +#. add license selector pull-down +#: ../../po/../src/dialogs/desktop-properties.cpp:1225 +msgid "License" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1255 +msgid "Proprietary" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:212 +#, fuzzy +msgid "When transforming, show:" +msgstr "Трансфармуе аб'ект" + +#: ../../po/../src/dialogs/display-settings.cpp:223 +#, fuzzy +msgid "Objects" +msgstr "Аб'ект" + +#: ../../po/../src/dialogs/display-settings.cpp:224 +msgid "Show the actual objects when moving or transforming" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:231 +#, fuzzy +msgid "Box outline" +msgstr "Паказаць контур" + +#: ../../po/../src/dialogs/display-settings.cpp:232 +msgid "Show only a box outline of the objects when moving or transforming" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:238 +msgid "Per-object selection cue:" +msgstr "" + +#. sorationsnapsperpi == 0 means no snapping +#: ../../po/../src/dialogs/display-settings.cpp:249 +#: ../../po/../src/dialogs/display-settings.cpp:386 +#: ../../po/../src/dialogs/display-settings.cpp:441 +#: ../../po/../src/dialogs/display-settings.cpp:1482 +#: ../../po/../src/dialogs/stroke-style.cpp:791 +#: ../../po/../src/interface.cpp:741 +#: ../../po/../src/ui/widget/selected-style.cpp:100 +#: ../../po/../src/verbs.cpp:1842 +msgid "None" +msgstr "Няма" + +#: ../../po/../src/dialogs/display-settings.cpp:250 +msgid "No per-object selection indication" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:256 +msgid "Mark" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:257 +msgid "Each selected object has a diamond mark in the top left corner" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:264 +msgid "Box" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:265 +msgid "Each selected object displays its bounding box" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:270 +#, fuzzy +msgid "Default scale origin:" +msgstr "Дапомны допуск курсора:" + +#: ../../po/../src/dialogs/display-settings.cpp:281 +#, fuzzy +msgid "Opposite bounding box edge" +msgstr "Раўнаць па сетке" + +#: ../../po/../src/dialogs/display-settings.cpp:282 +msgid "Default scale origin will be on the bounding box of the item" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:288 +msgid "Farthest opposite node" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:289 +msgid "Default scale origin will be on the bounding box of the item's points" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:341 +#, fuzzy +msgid "degrees" +msgstr "град" + +#: ../../po/../src/dialogs/display-settings.cpp:350 +msgid "" +"Rotating with Ctrl pressed snaps every that much degrees; also, pressing " +"[ or ] rotates by this amount" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:407 +msgid "Rotation snaps every:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:430 +msgid "" +"None: dialogs are treated as regular windows; Normal: dialogs stay on top of " +"document windows; Aggressive: same as Normal but may work better with some " +"window managers." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:451 +msgid "Normal" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:461 +msgid "Aggressive" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:475 +#, fuzzy +msgid "Dialogs on top:" +msgstr "Дыялёгі" + +#: ../../po/../src/dialogs/display-settings.cpp:645 +#, fuzzy +msgid "Show selection cue" +msgstr "Апускае вылучаныя аб'екты на адзін узровень" + +#: ../../po/../src/dialogs/display-settings.cpp:646 +msgid "" +"Whether selected objects display a selection cue (the same as in selector)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:657 +#, fuzzy +msgid "Enable gradient editing" +msgstr "Вэктар градыента" + +#: ../../po/../src/dialogs/display-settings.cpp:658 +msgid "Whether selected objects display gradient editing controls" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:719 +#, fuzzy +msgid "No objects selected to take the style from." +msgstr "Апускае вылучаныя аб'екты на ніжні слой" + +#: ../../po/../src/dialogs/display-settings.cpp:728 +msgid "" +"More than one object selected. Cannot take style from multiple " +"objects." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:767 +#, fuzzy +msgid "Create new objects with:" +msgstr "Інструмэнт тэкста - стварае і рэдагуе тэкставыя аб'екты" + +#: ../../po/../src/dialogs/display-settings.cpp:777 +#, fuzzy +msgid "Take from selection" +msgstr "Трансфармаваньне вылучэньня" + +#: ../../po/../src/dialogs/display-settings.cpp:778 +msgid "Remember the style of the (first) selected object as this tool's style" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:782 +#, fuzzy +msgid "Last used style" +msgstr "Стыль штрыхоўкі" + +#: ../../po/../src/dialogs/display-settings.cpp:782 +msgid "Apply the style you last set on an object" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:790 +msgid "This tool's own style:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:790 +msgid "" +"Each tool may store its own style to apply to the newly created objects. Use " +"the button below to set it." +msgstr "" + +#. Mouse +#: ../../po/../src/dialogs/display-settings.cpp:877 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:55 +#, fuzzy +msgid "Mouse" +msgstr "Перанесьці" + +#. TRANSLATORS: "Grab" is a noun here. "Grab sensitivity" is intended to mean how +#. * close on the screen you need to be to an object to be able to grab it with mouse (in +#. * pixels). +#: ../../po/../src/dialogs/display-settings.cpp:883 +#, fuzzy +msgid "Grab sensitivity:" +msgstr "Зрабіць чулым" + +#: ../../po/../src/dialogs/display-settings.cpp:884 +msgid "" +"How close on the screen you need to be to an object to be able to grab it " +"with mouse (in screen pixels)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:885 +#: ../../po/../src/dialogs/display-settings.cpp:897 +#: ../../po/../src/dialogs/display-settings.cpp:912 +#: ../../po/../src/dialogs/display-settings.cpp:930 +#: ../../po/../src/dialogs/display-settings.cpp:970 +msgid "pixels" +msgstr "піксэлі" + +#: ../../po/../src/dialogs/display-settings.cpp:895 +msgid "Click/drag threshold:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:896 +msgid "" +"Maximum mouse drag (in screen pixels) which is considered a click, not a drag" +msgstr "" + +#. Scrolling +#: ../../po/../src/dialogs/display-settings.cpp:907 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:56 +msgid "Scrolling" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:910 +msgid "Mouse wheel scrolls by:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:911 +msgid "" +"One mouse wheel notch scrolls by this distance in screen pixels " +"(horizontally with Shift)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:920 +msgid "Ctrl+arrows" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:928 +msgid "Scroll by:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:929 +msgid "Pressing Ctrl+arrow key scrolls by this distance (in screen pixels)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:939 +#, fuzzy +msgid "Acceleration:" +msgstr "Вылучэньне" + +#: ../../po/../src/dialogs/display-settings.cpp:940 +msgid "" +"Pressing and holding Ctrl+arrow will gradually speed up scrolling (0 for no " +"acceleration)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:949 +msgid "Autoscrolling" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:957 +#, fuzzy +msgid "Speed:" +msgstr "Чырвоны:" + +#: ../../po/../src/dialogs/display-settings.cpp:958 +msgid "" +"How fast the canvas autoscrolls when you drag beyond canvas edge (0 to turn " +"autoscroll off)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:968 +#: ../../po/../src/ui/dialog/tracedialog.cpp:357 +#: ../../po/../src/ui/dialog/tracedialog.cpp:390 +msgid "Threshold:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:969 +msgid "" +"How far (in screen pixels) you need to be from the canvas edge to trigger " +"autoscroll; positive is outside the canvas, negative is within the canvas" +msgstr "" + +#. Steps +#: ../../po/../src/dialogs/display-settings.cpp:979 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:57 +#, fuzzy +msgid "Steps" +msgstr "Стыль" + +#: ../../po/../src/dialogs/display-settings.cpp:982 +msgid "Arrow keys move by:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:983 +msgid "" +"Pressing an arrow key moves selected object(s) or node(s) by this distance " +"(in px units)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:984 +#: ../../po/../src/dialogs/display-settings.cpp:995 +#: ../../po/../src/dialogs/display-settings.cpp:1006 +#: ../../po/../src/helper/units.cpp:42 +msgid "px" +msgstr "px" + +#: ../../po/../src/dialogs/display-settings.cpp:993 +msgid "> and < scale by:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:994 +msgid "" +"Pressing > or < scales selection up or down by this increment (in px units)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1004 +msgid "Inset/Outset by:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1005 +msgid "" +"Inset and Outset commands displace the path by this distance (in px units)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1017 +msgid "Compass-like display of angles" +msgstr "" + +#. TRANSLATORS: "positive clockwise" means "increasing in clockwise direction" +#: ../../po/../src/dialogs/display-settings.cpp:1019 +msgid "" +"When on, angles are displayed with 0 at north, 0 to 360 range, positive " +"clockwise; otherwise with 0 at east, -180 to 180 range, positive " +"counterclockwise" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1026 +#, fuzzy +msgid "Zoom in/out by:" +msgstr "Памяншае маштаб рысунка" + +#: ../../po/../src/dialogs/display-settings.cpp:1027 +msgid "" +"Zoom tool click, +/- keys, and middle click zoom in and out by this " +"multiplier" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1028 +#: ../../po/../src/helper/units.cpp:44 +msgid "%" +msgstr "%" + +#. Tools +#: ../../po/../src/dialogs/display-settings.cpp:1037 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:58 +msgid "Tools" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1045 +#, fuzzy +msgid "Selector" +msgstr "Вылучэньне" + +#: ../../po/../src/dialogs/display-settings.cpp:1056 +msgid "Node" +msgstr "Вузел" + +#: ../../po/../src/dialogs/display-settings.cpp:1064 +#: ../../po/../src/verbs.cpp:2073 +#: ../../po/../src/widgets/desktop-widget.cpp:277 +msgid "Zoom" +msgstr "Маштабаваньне" + +#. The 4 shape tools +#: ../../po/../src/dialogs/display-settings.cpp:1071 +#, fuzzy +msgid "Shapes" +msgstr "Фармаваньне" + +#: ../../po/../src/dialogs/display-settings.cpp:1079 +#: ../../po/../src/verbs.cpp:2055 +msgid "Rectangle" +msgstr "Прамакутнік" + +#: ../../po/../src/dialogs/display-settings.cpp:1085 +#: ../../po/../src/verbs.cpp:2057 +msgid "Ellipse" +msgstr "Эліпс" + +#: ../../po/../src/dialogs/display-settings.cpp:1091 +#: ../../po/../src/verbs.cpp:2059 +msgid "Star" +msgstr "Зорка" + +#: ../../po/../src/dialogs/display-settings.cpp:1097 +#: ../../po/../src/verbs.cpp:2061 +msgid "Spiral" +msgstr "Спіраль" + +#: ../../po/../src/dialogs/display-settings.cpp:1111 +#: ../../po/../src/verbs.cpp:2063 +msgid "Pencil" +msgstr "Аловак" + +#: ../../po/../src/dialogs/display-settings.cpp:1114 +#, fuzzy +msgid "Tolerance:" +msgstr "Трасыраваць" + +#: ../../po/../src/dialogs/display-settings.cpp:1115 +msgid "" +"This value affects the amount of smoothing applied to freehand lines; lower " +"values produce more uneven paths with more nodes" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1131 +#: ../../po/../src/verbs.cpp:2065 +msgid "Pen" +msgstr "Пяро" + +#: ../../po/../src/dialogs/display-settings.cpp:1140 +#: ../../po/../src/verbs.cpp:2067 +msgid "Calligraphy" +msgstr "Каліграфія" + +#: ../../po/../src/dialogs/display-settings.cpp:1147 +#: ../../po/../src/dialogs/text-edit.cpp:353 +#: ../../po/../src/ui/dialog/text-properties.cpp:37 +#: ../../po/../src/verbs.cpp:2069 +msgid "Text" +msgstr "Тэкст" + +#: ../../po/../src/dialogs/display-settings.cpp:1157 +#: ../../po/../src/verbs.cpp:2071 +#, fuzzy +msgid "Gradient" +msgstr "Вэктар градыента" + +#: ../../po/../src/dialogs/display-settings.cpp:1164 +#: ../../po/../src/verbs.cpp:2077 +#, fuzzy +msgid "Connector" +msgstr "Куты:" + +#: ../../po/../src/dialogs/display-settings.cpp:1171 +#: ../../po/../src/verbs.cpp:2075 +msgid "Dropper" +msgstr "Піпетка" + +#. Windows +#: ../../po/../src/dialogs/display-settings.cpp:1183 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:59 +msgid "Windows" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1188 +#, fuzzy +msgid "Save window geometry" +msgstr "Захоўвае дакумэнт" + +#: ../../po/../src/dialogs/display-settings.cpp:1189 +msgid "" +"Save the window size and position with each document (only for Inkscape SVG " +"format)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1196 +msgid "Dialogs are hidden in taskbar" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1197 +msgid "Whether dialog windows are to be hidden in the window manager taskbar" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1204 +#, fuzzy +msgid "Zoom when window is resized" +msgstr "Маштабаваць рысунак калі зьмяняецца памер акна" + +#: ../../po/../src/dialogs/display-settings.cpp:1205 +msgid "" +"Zoom drawing when document window is resized, to keep the same area visible " +"(this is the default which can be changed in any window using the button " +"above the right scrollbar)" +msgstr "" + +#. Clones +#: ../../po/../src/dialogs/display-settings.cpp:1213 +#: ../../po/../src/dialogs/find.cpp:624 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:60 +#, fuzzy +msgid "Clones" +msgstr "Закрыць" + +#: ../../po/../src/dialogs/display-settings.cpp:1217 +msgid "When the original moves, its clones and linked offsets:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1229 +msgid "Move in parallel" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1230 +msgid "Clones are translated by the same vector as their original." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1237 +msgid "Stay unmoved" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1238 +msgid "Clones preserve their positions when their original is moved." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1245 +msgid "Move according to transform" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1246 +msgid "" +"Each clone moves according to the value of its transform= attribute. For " +"example, a rotated clone will move in a different direction than its " +"original." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1255 +msgid "When the original is deleted, its clones:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1267 +msgid "Are unlinked" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1267 +msgid "Orphaned clones are converted to regular objects." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1273 +#, fuzzy +msgid "Are deleted" +msgstr "Першы вылучаны" + +#: ../../po/../src/dialogs/display-settings.cpp:1273 +msgid "Orphaned clones are deleted along with their original." +msgstr "" + +#. Transforms +#. TRANSLATORS: Noun, i.e. transformations. +#: ../../po/../src/dialogs/display-settings.cpp:1289 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:61 +#, fuzzy +msgid "Transforms" +msgstr "Трансфармаваньне:" + +#: ../../po/../src/dialogs/display-settings.cpp:1292 +#, fuzzy +msgid "Scale stroke width" +msgstr "Няма рафарбоўкі" + +#: ../../po/../src/dialogs/display-settings.cpp:1293 +#: ../../po/../src/widgets/select-toolbar.cpp:568 +msgid "When scaling objects, scale the stroke width by the same proportion" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1300 +msgid "Scale rounded corners in rectangles" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1301 +#: ../../po/../src/widgets/select-toolbar.cpp:580 +msgid "When scaling rectangles, scale the radii of rounded corners" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1308 +#, fuzzy +msgid "Transform gradients" +msgstr "Трансфармаваньне:" + +#: ../../po/../src/dialogs/display-settings.cpp:1309 +#: ../../po/../src/widgets/select-toolbar.cpp:592 +msgid "Transform gradients (in fill or stroke) along with the objects" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1316 +#, fuzzy +msgid "Transform patterns" +msgstr "Матрыца трансфармаваньня" + +#: ../../po/../src/dialogs/display-settings.cpp:1317 +#: ../../po/../src/widgets/select-toolbar.cpp:604 +msgid "Transform patterns (in fill or stroke) along with the objects" +msgstr "" + +#. TRANSLATORS: How to specify the affine transformation in the SVG file. +#: ../../po/../src/dialogs/display-settings.cpp:1327 +#, fuzzy +msgid "Store transformation:" +msgstr "Трансфармаваньне аб'екта" + +#: ../../po/../src/dialogs/display-settings.cpp:1338 +#, fuzzy +msgid "Optimized" +msgstr "Аптымізаваць" + +#: ../../po/../src/dialogs/display-settings.cpp:1339 +msgid "" +"If possible, apply transformation to objects without adding a transform= " +"attribute" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1346 +#, fuzzy +msgid "Preserved" +msgstr "Зьберагчы" + +#: ../../po/../src/dialogs/display-settings.cpp:1347 +msgid "Always store transformation as a transform= attribute on objects" +msgstr "" + +#. Selecting +#: ../../po/../src/dialogs/display-settings.cpp:1355 +#, fuzzy +msgid "Selecting" +msgstr "Вылучэньне" + +#: ../../po/../src/dialogs/display-settings.cpp:1357 +msgid "Ctrl+A, Tab, Shift+Tab:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1366 +#, fuzzy +msgid "Select only within current layer" +msgstr "Вылучэньне" + +#: ../../po/../src/dialogs/display-settings.cpp:1367 +msgid "" +"Uncheck this to make keyboard selection commands work on objects in all " +"layers" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1374 +msgid "Ignore hidden objects" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1375 +msgid "" +"Uncheck this to be able to select objects that are hidden (either by " +"themselves or by being in a hidden group or layer)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1382 +#, fuzzy +msgid "Ignore locked objects" +msgstr "Вылучаныя аб'екты" + +#: ../../po/../src/dialogs/display-settings.cpp:1383 +msgid "" +"Uncheck this to be able to select objects that are locked (either by " +"themselves or by being in a locked group or layer)" +msgstr "" + +#. To be broken into: Display, Save, Export, SVG, Commands +#: ../../po/../src/dialogs/display-settings.cpp:1391 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:62 +msgid "Misc" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1394 +msgid "Default export resolution:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1395 +msgid "Default bitmap resolution (in dots per inch) in the Export dialog" +msgstr "" + +#. FIXME: add "Used for new exports; once exported, documents remember this value on per-object basis" when implemented +#: ../../po/../src/dialogs/display-settings.cpp:1396 +#: ../../po/../src/dialogs/export.cpp:442 +msgid "dpi" +msgstr "dpi" + +#. TRANSLATORS: When on, an imported bitmap creates an element; otherwise it is a +#. * rectangle with bitmap fill. +#: ../../po/../src/dialogs/display-settings.cpp:1407 +#, fuzzy +msgid "Import bitmap as " +msgstr "Імпартуе кропкавы ці SVG відарыс у дакумэнт" + +#: ../../po/../src/dialogs/display-settings.cpp:1408 +msgid "" +"When on, an imported bitmap creates an element; otherwise it is a " +"rectangle with bitmap fill" +msgstr "" + +#. TRANSLATORS: When on, the print out (currently Postscript) will have +#. * a comment with the each object's label visible, marking the section +#. * of the printing commands that represent the given object. +#: ../../po/../src/dialogs/display-settings.cpp:1418 +msgid "Add label comments to printing output" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1419 +msgid "" +"When on, a comment will be added to the raw print output, marking the " +"rendered output for an object with its label" +msgstr "" + +#. TRANSLATORS: When on, enable the effects menu, default is off +#: ../../po/../src/dialogs/display-settings.cpp:1427 +msgid "Enable script effects (requires restart) - EXPERIMENTAL" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1428 +msgid "" +"When on, the effects menu is enabled, allowing external effect scripts to be " +"called, requires restart before effective - EXPERIMENTAL" +msgstr "" + +#. TRANSLATORS: The maximum length of the Open Recent list in the File menu. +#: ../../po/../src/dialogs/display-settings.cpp:1436 +#, fuzzy +msgid "Max recent documents:" +msgstr "Друкуе дакумэнт" + +#: ../../po/../src/dialogs/display-settings.cpp:1437 +msgid "The maximum length of the Open Recent list in the File menu" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1447 +msgid "Simplification threshold:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1448 +msgid "" +"How strong is the Simplify command by default. If you invoke this command " +"several times in quick succession, it will act more and more aggressively; " +"invoking it again after a pause restores the default threshold." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1469 +msgid "Oversample bitmaps:" +msgstr "Усярэджваць растр па кропках:" + +#: ../../po/../src/dialogs/display-settings.cpp:1488 +msgid "2x2" +msgstr "2x2" + +#: ../../po/../src/dialogs/display-settings.cpp:1494 +msgid "4x4" +msgstr "4x4" + +#: ../../po/../src/dialogs/display-settings.cpp:1500 +msgid "8x8" +msgstr "8x8" + +#: ../../po/../src/dialogs/display-settings.cpp:1506 +msgid "16x16" +msgstr "16x16" + +#. "view_icon_preview" +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2143 +#, fuzzy +msgid "_Page" +msgstr "Аркуш" + +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2147 +#, fuzzy +msgid "_Drawing" +msgstr "Рысаваньне" + +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2149 +#, fuzzy +msgid "_Selection" +msgstr "Вылучэньне" + +#: ../../po/../src/dialogs/export.cpp:133 +#, fuzzy +msgid "_Custom" +msgstr "Пазначае карыстальнік" + +#: ../../po/../src/dialogs/export.cpp:254 +msgid "Export area" +msgstr "Прастора экспартаваньня" + +#: ../../po/../src/dialogs/export.cpp:300 +#, fuzzy +msgid "_x0:" +msgstr "x0:" + +#: ../../po/../src/dialogs/export.cpp:305 +#, fuzzy +msgid "x_1:" +msgstr "x1:" + +#: ../../po/../src/dialogs/export.cpp:316 +#, fuzzy +msgid "_y0:" +msgstr "y0:" + +#: ../../po/../src/dialogs/export.cpp:321 +#, fuzzy +msgid "y_1:" +msgstr "y1:" + +#: ../../po/../src/dialogs/export.cpp:406 +msgid "Bitmap size" +msgstr "Памер кропкавага відарыса" + +#: ../../po/../src/dialogs/export.cpp:416 +#, fuzzy +msgid "_Width:" +msgstr "Шырыня:" + +#: ../../po/../src/dialogs/export.cpp:416 +#: ../../po/../src/dialogs/export.cpp:431 +#, fuzzy +msgid "pixels at" +msgstr "піксэлі" + +#: ../../po/../src/dialogs/export.cpp:426 +#, fuzzy +msgid "dp_i" +msgstr "dpi" + +#: ../../po/../src/dialogs/export.cpp:448 +#, fuzzy +msgid "_Filename" +msgstr "Файл" + +#: ../../po/../src/dialogs/export.cpp:512 +msgid "_Browse..." +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:539 +#, fuzzy +msgid " _Export " +msgstr "Прамакутнік" + +#: ../../po/../src/dialogs/export.cpp:541 +msgid "Export the bitmap file with these settings" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:968 +msgid "You have to enter a filename" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:973 +msgid "The chosen area to be exported is invalid" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:982 +#, c-format +msgid "Directory %s does not exist or is not a directory.\n" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:998 +#, fuzzy +msgid "Export in progress" +msgstr "Прастора экспартаваньня" + +#: ../../po/../src/dialogs/export.cpp:1004 +#, fuzzy, c-format +msgid "Exporting %s (%d x %d)" +msgstr "Каляровы відарыс %d x %d: %s" + +#: ../../po/../src/dialogs/export.cpp:1031 +#, c-format +msgid "Could not export to filename %s.\n" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:1137 +#, fuzzy +msgid "Select a filename for exporting" +msgstr "Выбярыце файл для імпартаваньня" + +#: ../../po/../src/dialogs/filedialog.cpp:367 +#, fuzzy +msgid "No preview" +msgstr "Стварыць папярэдні прагляд" + +#: ../../po/../src/dialogs/filedialog.cpp:468 +msgid "too large for preview" +msgstr "" + +#: ../../po/../src/dialogs/filedialog.cpp:762 +#: ../../po/../src/dialogs/filedialog.cpp:763 +#, fuzzy +msgid "All Images" +msgstr "Відарыс" + +#: ../../po/../src/dialogs/filedialog.cpp:767 +#: ../../po/../src/dialogs/filedialog.cpp:768 +#, fuzzy +msgid "All Files" +msgstr "Стыль запаўненьня" + +#: ../../po/../src/dialogs/filedialog.cpp:774 +#: ../../po/../src/dialogs/filedialog.cpp:775 +#, fuzzy +msgid "All Inkscape Files" +msgstr "Слайдшоў Sodipodi" + +#: ../../po/../src/dialogs/filedialog.cpp:1176 +#, fuzzy +msgid "Guess from extension" +msgstr "Трансфармаваньне вылучэньня" + +#. ###### Add the file types menu +#. createFilterMenu(); +#. ###### Do we want the .xxx extension automatically added? +#: ../../po/../src/dialogs/filedialog.cpp:1261 +msgid "Append filename extension automatically" +msgstr "" + +#. TRANSLATORS: "%s" is replaced with "exact" or "partial" when this string is displayed +#: ../../po/../src/dialogs/find.cpp:378 +#, fuzzy, c-format +msgid "%d object found (out of %d), %s match." +msgid_plural "%d objects found (out of %d), %s match." +msgstr[0] "Далучае рысы да вылучаных вузлоў" +msgstr[1] "Далучае рысы да вылучаных вузлоў" + +#: ../../po/../src/dialogs/find.cpp:381 +#, fuzzy +msgid "exact" +msgstr "Тэкст" + +#: ../../po/../src/dialogs/find.cpp:381 +#, fuzzy +msgid "partial" +msgstr "Спіраль" + +#: ../../po/../src/dialogs/find.cpp:388 +#, fuzzy +msgid "No objects found" +msgstr "Няма аб'ектаў" + +#: ../../po/../src/dialogs/find.cpp:546 +#, fuzzy +msgid "T_ype: " +msgstr "Тып:" + +#: ../../po/../src/dialogs/find.cpp:553 +msgid "Search in all object types" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:553 +#, fuzzy +msgid "All types" +msgstr "Стыль запаўненьня" + +#: ../../po/../src/dialogs/find.cpp:564 +msgid "Search all shapes" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:564 +#, fuzzy +msgid "All shapes" +msgstr "Усе інструмэнты формы" + +#: ../../po/../src/dialogs/find.cpp:581 +#, fuzzy +msgid "Search rectangles" +msgstr "Прамакутнік" + +#: ../../po/../src/dialogs/find.cpp:581 +#, fuzzy +msgid "Rectangles" +msgstr "Прамакутнік" + +#: ../../po/../src/dialogs/find.cpp:586 +msgid "Search ellipses, arcs, circles" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:586 +#, fuzzy +msgid "Ellipses" +msgstr "Эліпс" + +#: ../../po/../src/dialogs/find.cpp:591 +#, fuzzy +msgid "Search stars and polygons" +msgstr "Інструмэнт зоркі - стварае зоркі й палігоны" + +#: ../../po/../src/dialogs/find.cpp:591 +#, fuzzy +msgid "Stars" +msgstr "Зорка" + +#: ../../po/../src/dialogs/find.cpp:596 +#, fuzzy +msgid "Search spirals" +msgstr "Стварыць лучыва" + +#: ../../po/../src/dialogs/find.cpp:596 +#, fuzzy +msgid "Spirals" +msgstr "Спіраль" + +#. TRANSLATORS: polyline is a set of connected straight line segments +#. http://www.w3.org/TR/SVG11/shapes.html#PolylineElement +#: ../../po/../src/dialogs/find.cpp:609 +msgid "Search paths, lines, polylines" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:609 +msgid "Paths" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:614 +#, fuzzy +msgid "Search text objects" +msgstr "Вылучаныя аб'екты" + +#: ../../po/../src/dialogs/find.cpp:614 +#, fuzzy +msgid "Texts" +msgstr "Тэкст" + +#: ../../po/../src/dialogs/find.cpp:619 +msgid "Search groups" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:619 +#, fuzzy +msgid "Groups" +msgstr "Згрупаваць" + +#: ../../po/../src/dialogs/find.cpp:624 +msgid "Search clones" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:629 +msgid "Search images" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:629 +#, fuzzy +msgid "Images" +msgstr "Відарыс" + +#: ../../po/../src/dialogs/find.cpp:634 +#, fuzzy +msgid "Search offset objects" +msgstr "Інструмэнт тэкста - стварае і рэдагуе тэкставыя аб'екты" + +#: ../../po/../src/dialogs/find.cpp:634 +msgid "Offsets" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:694 +#, fuzzy +msgid "_Text: " +msgstr "Тэкст" + +#: ../../po/../src/dialogs/find.cpp:694 +msgid "Find objects by their text content (exact or partial match)" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:695 +msgid "_ID: " +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:695 +msgid "Find objects by the value of the id attribute (exact or partial match)" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:696 +#, fuzzy +msgid "_Style: " +msgstr "Стыль" + +#: ../../po/../src/dialogs/find.cpp:696 +msgid "" +"Find objects by the value of the style attribute (exact or partial match)" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:697 +#, fuzzy +msgid "_Attribute: " +msgstr "Атрыбут" + +#: ../../po/../src/dialogs/find.cpp:697 +msgid "Find objects by the name of an attribute (exact or partial match)" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:711 +#, fuzzy +msgid "Search in s_election" +msgstr "Вылучэньне" + +#: ../../po/../src/dialogs/find.cpp:715 +msgid "Limit search to the current selection" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:720 +#, fuzzy +msgid "Search in current _layer" +msgstr "Вылучэньне" + +#: ../../po/../src/dialogs/find.cpp:724 +#, fuzzy +msgid "Limit search to the current layer" +msgstr "Вылучэньне" + +#: ../../po/../src/dialogs/find.cpp:729 +msgid "Include _hidden" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:733 +msgid "Include hidden objects in search" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:738 +msgid "Include l_ocked" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:742 +#, fuzzy +msgid "Include locked objects in search" +msgstr "Вылучаныя аб'екты" + +#: ../../po/../src/dialogs/find.cpp:753 +#, fuzzy +msgid "Clear values" +msgstr "Ачысьціць усё" + +#: ../../po/../src/dialogs/find.cpp:754 +#, fuzzy +msgid "_Find" +msgstr "Сетка" + +#: ../../po/../src/dialogs/find.cpp:754 +msgid "Select objects matching all of the fields you filled in" +msgstr "" + +#: ../../po/../src/dialogs/iconpreview.cpp:145 +#, c-format +msgid "%d x %d" +msgstr "" + +#: ../../po/../src/dialogs/iconpreview.cpp:193 +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:857 +#: ../../po/../src/widgets/desktop-widget.cpp:1069 +msgid "Selection" +msgstr "Вылучэньне" + +#: ../../po/../src/dialogs/iconpreview.cpp:195 +#, fuzzy +msgid "Selection only or whole document" +msgstr "Вылучэньне" + +#: ../../po/../src/dialogs/iconpreview.cpp:203 +msgid "Refresh the icons" +msgstr "" + +#. Create the label for the object id +#: ../../po/../src/dialogs/item-properties.cpp:126 +#: ../../po/../src/dialogs/item-properties.cpp:327 +#: ../../po/../src/dialogs/item-properties.cpp:396 +#: ../../po/../src/dialogs/item-properties.cpp:403 +msgid "_Id" +msgstr "" + +#: ../../po/../src/dialogs/item-properties.cpp:135 +msgid "" +"The id= attribute (only letters, digits, and the characters .-_: allowed)" +msgstr "" + +#. Button for setting the object's id, label, title and description. +#: ../../po/../src/dialogs/item-properties.cpp:149 +#, fuzzy +msgid "_Set" +msgstr "Вылучэньне" + +#. Create the label for the object label +#: ../../po/../src/dialogs/item-properties.cpp:158 +#, fuzzy +msgid "_Label" +msgstr "Усталяваць атрыбут" + +#: ../../po/../src/dialogs/item-properties.cpp:167 +msgid "A freeform label for the object" +msgstr "" + +#. Create the label for the object title +#: ../../po/../src/dialogs/item-properties.cpp:179 +#: ../../po/../src/dialogs/rdf.cpp:243 +#, fuzzy +msgid "Title" +msgstr "Назва:" + +#. Create the frame for the object description +#: ../../po/../src/dialogs/item-properties.cpp:196 +#: ../../po/../src/dialogs/rdf.cpp:287 +#, fuzzy +msgid "Description" +msgstr "Вылучэньне" + +#. Hide +#: ../../po/../src/dialogs/item-properties.cpp:223 +#, fuzzy +msgid "_Hide" +msgstr "Бакі:" + +#: ../../po/../src/dialogs/item-properties.cpp:224 +msgid "Check to make the object invisible" +msgstr "" + +#. Lock +#. TRANSLATORS: "Lock" is a verb here +#: ../../po/../src/dialogs/item-properties.cpp:233 +msgid "L_ock" +msgstr "" + +#: ../../po/../src/dialogs/item-properties.cpp:234 +msgid "Check to make the object insensitive (not selectable by mouse)" +msgstr "" + +#: ../../po/../src/dialogs/item-properties.cpp:310 +#: ../../po/../src/dialogs/item-properties.cpp:317 +msgid "Ref" +msgstr "" + +#: ../../po/../src/dialogs/item-properties.cpp:398 +#, fuzzy +msgid "Id invalid! " +msgstr "Правільны ID" + +#: ../../po/../src/dialogs/item-properties.cpp:400 +msgid "Id exists! " +msgstr "" + +#: ../../po/../src/dialogs/layer-properties.cpp:50 +msgid "Layer name:" +msgstr "" + +#: ../../po/../src/dialogs/layer-properties.cpp:133 +#, fuzzy +msgid "Rename Layer" +msgstr "Падняць вузел" + +#: ../../po/../src/dialogs/layer-properties.cpp:136 +#, fuzzy +msgid "_Rename" +msgstr "Файл" + +#. TRANSLATORS: This means "The layer has been renamed" +#: ../../po/../src/dialogs/layer-properties.cpp:147 +#, fuzzy +msgid "Renamed layer" +msgstr "Падняць вузел" + +#: ../../po/../src/dialogs/layer-properties.cpp:151 +#, fuzzy +msgid "Add Layer" +msgstr "Апусьціць" + +#: ../../po/../src/dialogs/layer-properties.cpp:153 +#, fuzzy +msgid "_Add" +msgstr "Дадаць" + +#: ../../po/../src/dialogs/layer-properties.cpp:167 +msgid "New layer created." +msgstr "" + +#: ../../po/../src/dialogs/object-attributes.cpp:34 +msgid "Href:" +msgstr "Href:" + +#: ../../po/../src/dialogs/object-attributes.cpp:35 +msgid "Target:" +msgstr "Мэта:" + +#: ../../po/../src/dialogs/object-attributes.cpp:36 +msgid "Type:" +msgstr "Тып:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkRoleAttribute +#. Identifies the type of the related resource with an absolute URI +#: ../../po/../src/dialogs/object-attributes.cpp:39 +msgid "Role:" +msgstr "Роля:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkArcRoleAttribute +#. For situations where the nature/role alone isn't enough, this offers an additional URI defining the purpose of the link. +#: ../../po/../src/dialogs/object-attributes.cpp:42 +msgid "Arcrole:" +msgstr "" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkTitleAttribute +#: ../../po/../src/dialogs/object-attributes.cpp:44 +msgid "Title:" +msgstr "Назва:" + +#: ../../po/../src/dialogs/object-attributes.cpp:45 +msgid "Show:" +msgstr "Паказаць:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkActuateAttribute +#: ../../po/../src/dialogs/object-attributes.cpp:47 +msgid "Actuate:" +msgstr "Актывізаваць:" + +#: ../../po/../src/dialogs/object-attributes.cpp:52 +msgid "URL:" +msgstr "URL:" + +#: ../../po/../src/dialogs/object-attributes.cpp:53 +msgid "X:" +msgstr "X:" + +#: ../../po/../src/dialogs/object-attributes.cpp:54 +msgid "Y:" +msgstr "Y:" + +#: ../../po/../src/dialogs/object-attributes.cpp:98 +#, c-format +msgid "%s attributes" +msgstr "%s атрыбуты" + +#: ../../po/../src/dialogs/object-properties.cpp:158 +#, fuzzy +msgid "_Fill" +msgstr "Запаўненьне" + +#: ../../po/../src/dialogs/object-properties.cpp:165 +#, fuzzy +msgid "Stroke _paint" +msgstr "Няма рафарбоўкі" + +#: ../../po/../src/dialogs/object-properties.cpp:172 +#, fuzzy +msgid "Stroke st_yle" +msgstr "Наладкі штрыхоўкі" + +#: ../../po/../src/dialogs/object-properties.cpp:183 +#, fuzzy +msgid "Master _opacity" +msgstr "Зацямненьне:" + +#: ../../po/../src/dialogs/rdf.cpp:244 +msgid "Name by which this document is formally known." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:246 +#, fuzzy +msgid "Date" +msgstr "Уставіць" + +#: ../../po/../src/dialogs/rdf.cpp:247 +msgid "Date associated with the creation of this document (YYYY-MM-DD)." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:249 +msgid "Format" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:250 +msgid "The physical or digital manifestation of this document (MIME type)." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:252 +#, fuzzy +msgid "Type" +msgstr "Тып:" + +#: ../../po/../src/dialogs/rdf.cpp:253 +msgid "Type of document (DCMI Type)." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:256 +#, fuzzy +msgid "Creator" +msgstr "Стварыць" + +#: ../../po/../src/dialogs/rdf.cpp:257 +msgid "" +"Name of entity primarily responsible for making the content of this document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:259 +#, fuzzy +msgid "Rights" +msgstr "Вышыня:" + +#: ../../po/../src/dialogs/rdf.cpp:260 +msgid "" +"Name of entity with rights to the Intellectual Property of this document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:262 +msgid "Publisher" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:263 +msgid "Name of entity responsible for making this document available." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:266 +#, fuzzy +msgid "Identifier" +msgstr "Санцімэтар" + +#: ../../po/../src/dialogs/rdf.cpp:267 +msgid "Unique URI to reference this document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:269 +msgid "Source" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:270 +msgid "Unique URI to reference the source of this document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:272 +#, fuzzy +msgid "Relation" +msgstr "Разрозьненьне:" + +#: ../../po/../src/dialogs/rdf.cpp:273 +#, fuzzy +msgid "Unique URI to a related document." +msgstr "Дакумэнт бяз назвы" + +#: ../../po/../src/dialogs/rdf.cpp:275 +msgid "Language" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:276 +msgid "" +"Two-letter language tag with optional subtags for the language of this " +"document. (e.g. 'en-GB')" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:278 +msgid "Keywords" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:279 +msgid "" +"The topic of this document as comma-separated key words, phrases, or " +"classifications." +msgstr "" + +#. TRANSLATORS: "Coverage": the spatial or temporal characteristics of the content. +#. For info, see Appendix D of http://www.w3.org/TR/1998/WD-rdf-schema-19980409/ +#: ../../po/../src/dialogs/rdf.cpp:283 +msgid "Coverage" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:284 +msgid "Extent or scope of this document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:288 +msgid "A short account of the content of this document." +msgstr "" + +#. FIXME: need to handle 1 agent per line of input +#: ../../po/../src/dialogs/rdf.cpp:292 +#, fuzzy +msgid "Contributors" +msgstr "Сантымэтры" + +#: ../../po/../src/dialogs/rdf.cpp:293 +msgid "" +"Names of entities responsible for making contributions to the content of " +"this document." +msgstr "" + +#. TRANSLATORS: URL to a page that defines the license for the document +#: ../../po/../src/dialogs/rdf.cpp:297 +msgid "URI" +msgstr "" + +#. TRANSLATORS: this is where you put a URL to a page that defines the license +#: ../../po/../src/dialogs/rdf.cpp:299 +msgid "URI to this document's license's namespace definition." +msgstr "" + +#. TRANSLATORS: fragment of XML representing the license of the document +#: ../../po/../src/dialogs/rdf.cpp:303 +#, fuzzy +msgid "Fragment" +msgstr "Аргумэнт:" + +#: ../../po/../src/dialogs/rdf.cpp:304 +msgid "XML fragment for the RDF 'License' section." +msgstr "" + +#: ../../po/../src/dialogs/stroke-style.cpp:774 +#: ../../po/../src/widgets/gradient-vector.cpp:263 +#: ../../po/../src/widgets/paint-selector.cpp:751 +msgid "No document selected" +msgstr "Дакумэнт ня вылучаны" + +#: ../../po/../src/dialogs/stroke-style.cpp:992 +#, fuzzy +msgid "Stroke width" +msgstr "Няма рафарбоўкі" + +#. Join type +#. TRANSLATORS: The line join style specifies the shape to be used at the +#. corners of paths. It can be "miter", "round" or "bevel". +#: ../../po/../src/dialogs/stroke-style.cpp:1015 +msgid "Join:" +msgstr "Далучэньне:" + +#. TRANSLATORS: Miter join: joining lines with a sharp (pointed) corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1027 +msgid "Miter join" +msgstr "" + +#. TRANSLATORS: Round join: joining lines with a rounded corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1035 +msgid "Round join" +msgstr "" + +#. TRANSLATORS: Bevel join: joining lines with a blunted (flattened) corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1043 +msgid "Bevel join" +msgstr "" + +#. Miterlimit +#. TRANSLATORS: Miter limit: only for "miter join", this limits the length +#. of the sharp "spike" when the lines connect at too sharp an angle. +#. When two line segments meet at a sharp angle, a miter join results in a +#. spike that extends well beyond the connection point. The purpose of the +#. miter limit is to cut off such spikes (i.e. convert them into bevels) +#. when they become too long. +#: ../../po/../src/dialogs/stroke-style.cpp:1054 +msgid "Miter limit:" +msgstr "" + +#: ../../po/../src/dialogs/stroke-style.cpp:1062 +msgid "Maximum length of the miter (in units of stroke width)" +msgstr "" + +#. Cap type +#. TRANSLATORS: cap type specifies the shape for the ends of lines +#: ../../po/../src/dialogs/stroke-style.cpp:1075 +msgid "Cap:" +msgstr "Краі:" + +#. TRANSLATORS: Butt cap: the line shape does not extend beyond the end point +#. of the line; the ends of the line are square +#: ../../po/../src/dialogs/stroke-style.cpp:1086 +msgid "Butt cap" +msgstr "" + +#. TRANSLATORS: Round cap: the line shape extends beyond the end point of the +#. line; the ends of the line are rounded +#: ../../po/../src/dialogs/stroke-style.cpp:1093 +msgid "Round cap" +msgstr "" + +#. TRANSLATORS: Square cap: the line shape extends beyond the end point of the +#. line; the ends of the line are square +#: ../../po/../src/dialogs/stroke-style.cpp:1100 +msgid "Square cap" +msgstr "" + +#. Dash +#: ../../po/../src/dialogs/stroke-style.cpp:1106 +#, fuzzy +msgid "Dashes:" +msgstr "Маса:" + +#. TRANSLATORS: Path markers are an SVG feature that allows you to attach arbitrary shapes +#. (arrowheads, bullets, faces, whatever) to the start, end, or middle nodes of a path. +#: ../../po/../src/dialogs/stroke-style.cpp:1127 +#, fuzzy +msgid "Start Markers:" +msgstr "Уласьцівасьці зоркі" + +#: ../../po/../src/dialogs/stroke-style.cpp:1137 +msgid "Mid Markers:" +msgstr "" + +#: ../../po/../src/dialogs/stroke-style.cpp:1148 +msgid "End Markers:" +msgstr "" + +#: ../../po/../src/dialogs/swatches.cpp:424 +#, c-format +msgid "Palettes directory (%s) is unavailable." +msgstr "" + +#. TODO: Insert widgets +#: ../../po/../src/dialogs/text-edit.cpp:199 +#: ../../po/../src/ui/dialog/text-properties.cpp:36 +#, fuzzy +msgid "Font" +msgstr "Пункт" + +#: ../../po/../src/dialogs/text-edit.cpp:216 +msgid "Layout" +msgstr "Арыентацыя" + +#: ../../po/../src/dialogs/text-edit.cpp:229 +msgid "Align lines left" +msgstr "" + +#. TRANSLATORS: `Center' here is a verb. +#: ../../po/../src/dialogs/text-edit.cpp:243 +#, fuzzy +msgid "Center lines" +msgstr "Цэнтар Y:" + +#: ../../po/../src/dialogs/text-edit.cpp:256 +msgid "Align lines right" +msgstr "" + +#: ../../po/../src/dialogs/text-edit.cpp:278 +#, fuzzy +msgid "Horizontal text" +msgstr "Адлюстраваць гарызантальна" + +#: ../../po/../src/dialogs/text-edit.cpp:292 +#, fuzzy +msgid "Vertical text" +msgstr "Адлюстраваць вэртыкальна" + +#: ../../po/../src/dialogs/text-edit.cpp:307 +#, fuzzy +msgid "Line spacing:" +msgstr "Крок па Ð¥:" + +#: ../../po/../src/dialogs/text-edit.cpp:400 +msgid "Set as default" +msgstr "Усталяваць як дапомнае" + +#: ../../po/../src/dialogs/tiledialog.cpp:603 +#, fuzzy +msgid "Rows:" +msgstr "Паказаць:" + +#: ../../po/../src/dialogs/tiledialog.cpp:613 +msgid "Number of rows" +msgstr "" + +#: ../../po/../src/dialogs/tiledialog.cpp:617 +#, fuzzy +msgid "Equal height" +msgstr "Вышыня:" + +#: ../../po/../src/dialogs/tiledialog.cpp:627 +msgid "If not set, each row has the height of the tallest object in it" +msgstr "" + +#. #### Radio buttons to control vertical alignment #### +#. #### Radio buttons to control horizontal alignment #### +#: ../../po/../src/dialogs/tiledialog.cpp:637 +#: ../../po/../src/dialogs/tiledialog.cpp:708 +#, fuzzy +msgid "Align:" +msgstr "Раўнаньне" + +#: ../../po/../src/dialogs/tiledialog.cpp:672 +msgid " X " +msgstr "" + +#. #### Number of columns #### +#: ../../po/../src/dialogs/tiledialog.cpp:678 +#, fuzzy +msgid "Columns:" +msgstr "Эліпс" + +#: ../../po/../src/dialogs/tiledialog.cpp:688 +msgid "Number of columns" +msgstr "" + +#: ../../po/../src/dialogs/tiledialog.cpp:692 +#, fuzzy +msgid "Equal width" +msgstr "Шырыня:" + +#: ../../po/../src/dialogs/tiledialog.cpp:701 +msgid "If not set, each column has the width of the widest object in it" +msgstr "" + +#. #### Radio buttons to control spacing manually or to fit selection bbox #### +#: ../../po/../src/dialogs/tiledialog.cpp:746 +#, fuzzy +msgid "Fit into selection box" +msgstr "Вылучэньне" + +#: ../../po/../src/dialogs/tiledialog.cpp:753 +#, fuzzy +msgid "Set spacing:" +msgstr "Крок па Y:" + +#. #### Y Padding #### +#: ../../po/../src/dialogs/tiledialog.cpp:777 +#, fuzzy +msgid "Row spacing: " +msgstr "Крок па Ð¥:" + +#: ../../po/../src/dialogs/tiledialog.cpp:786 +#, fuzzy +msgid "Vertical spacing between rows" +msgstr "Адлюстраваць вэртыкальна" + +#. #### X padding #### +#: ../../po/../src/dialogs/tiledialog.cpp:795 +#, fuzzy +msgid "Column spacing:" +msgstr "Крок па Ð¥:" + +#: ../../po/../src/dialogs/tiledialog.cpp:804 +#, fuzzy +msgid "Horizontal spacing between columns" +msgstr "Адлюстраваць гарызантальна" + +#: ../../po/../src/dialogs/tiledialog.cpp:818 +#, fuzzy +msgid "Arrange selected objects" +msgstr "Групуе вылучаныя аб'екты" + +#: ../../po/../src/dialogs/xml-tree.cpp:178 +msgid "Click to select nodes, drag to rearrange." +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:189 +msgid "Click attribute to edit." +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:193 +#, c-format +msgid "" +"Attribute %s selected. Press Ctrl+Enter when done editing to " +"commit changes." +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:284 +msgid "Drag to reorder nodes" +msgstr "Перамясьціце для зьмены парадка вузлоў" + +#: ../../po/../src/dialogs/xml-tree.cpp:304 +msgid "New element node" +msgstr "Стварыць вузел элемэнта" + +#: ../../po/../src/dialogs/xml-tree.cpp:326 +msgid "New text node" +msgstr "Стварыць вузел тэкста" + +#: ../../po/../src/dialogs/xml-tree.cpp:347 +msgid "Duplicate node" +msgstr "Падвоіць вузел" + +#: ../../po/../src/dialogs/xml-tree.cpp:368 +msgid "Delete node" +msgstr "Выдаліць вузел" + +#: ../../po/../src/dialogs/xml-tree.cpp:384 +msgid "Unindent node" +msgstr "Прыбраць водступ вузла" + +#: ../../po/../src/dialogs/xml-tree.cpp:399 +msgid "Indent node" +msgstr "Дадаць водступ вузла" + +#: ../../po/../src/dialogs/xml-tree.cpp:411 +msgid "Raise node" +msgstr "Падняць вузел" + +#: ../../po/../src/dialogs/xml-tree.cpp:423 +msgid "Lower node" +msgstr "Апусьціць вузел" + +#: ../../po/../src/dialogs/xml-tree.cpp:468 +msgid "Delete attribute" +msgstr "Выдаліць атрыбут" + +#. TRANSLATORS: "Attribute" is a noun here +#: ../../po/../src/dialogs/xml-tree.cpp:513 +msgid "Attribute name" +msgstr "Назва атрыбута" + +#. TRANSLATORS: "Set" is a verb here +#: ../../po/../src/dialogs/xml-tree.cpp:533 +msgid "Set attribute" +msgstr "Усталяваць атрыбут" + +#. TRANSLATORS: "Set" is a verb here +#: ../../po/../src/dialogs/xml-tree.cpp:535 +#, fuzzy +msgid "Set" +msgstr "Вылучэньне" + +#. TRANSLATORS: "Attribute" is a noun here +#: ../../po/../src/dialogs/xml-tree.cpp:558 +msgid "Attribute value" +msgstr "Значэньне атрыбута" + +#: ../../po/../src/dialogs/xml-tree.cpp:1318 +msgid "New element node..." +msgstr "Стварыць вузел элемэнта..." + +#: ../../po/../src/dialogs/xml-tree.cpp:1339 +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:100 +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:98 +msgid "Cancel" +msgstr "Адмяніць" + +#: ../../po/../src/dialogs/xml-tree.cpp:1345 +msgid "Create" +msgstr "Стварыць" + +#: ../../po/../src/dialogs/xml-tree.cpp:1458 +#, c-format +msgid "" +"Cannot set %s: Another element with value %s already exists!" +msgstr "" + +#: ../../po/../src/document.cpp:369 +#, c-format +msgid "New document %d" +msgstr "Новы дакумэнт %d" + +#: ../../po/../src/document.cpp:401 +#, c-format +msgid "Memory document %d" +msgstr "Запомніць дакумэнт %d" + +#: ../../po/../src/document.cpp:524 +#, c-format +msgid "Unnamed document %d" +msgstr "Дакумэнт бяз назвы %d" + +#. We hit green anchor, closing Green-Blue-Red +#: ../../po/../src/draw-context.cpp:441 +msgid "Path is closed." +msgstr "" + +#. We hit bot start and end of single curve, closing paths +#: ../../po/../src/draw-context.cpp:456 +msgid "Closing path." +msgstr "" + +#. alpha of color under cursor, to show in the statusbar +#. locale-sensitive printf is OK, since this goes to the UI, not into SVG +#: ../../po/../src/dropper-context.cpp:354 +#, c-format +msgid " alpha %.3g" +msgstr "" + +#. where the color is picked, to show in the statusbar +#: ../../po/../src/dropper-context.cpp:356 +#, c-format +msgid ", averaged with radius %d" +msgstr "" + +#: ../../po/../src/dropper-context.cpp:356 +msgid " under cursor" +msgstr "" + +#. message, to show in the statusbar +#: ../../po/../src/dropper-context.cpp:358 +msgid "Release mouse to set color." +msgstr "" + +#: ../../po/../src/dropper-context.cpp:358 +#: ../../po/../src/tools-switch.cpp:207 +msgid "" +"Click to set fill, Shift+click to set stroke; drag to " +"average color in area; with Alt to pick inverse color; Ctrl+C " +"to copy the color under mouse to clipboard" +msgstr "" + +#: ../../po/../src/extension/dependency.cpp:244 +msgid "Dependency::" +msgstr "" + +#: ../../po/../src/extension/dependency.cpp:245 +#, fuzzy +msgid " type: " +msgstr "Тып файла:" + +#: ../../po/../src/extension/dependency.cpp:246 +#, fuzzy +msgid " location: " +msgstr "Разрозьненьне:" + +#: ../../po/../src/extension/dependency.cpp:247 +msgid " string: " +msgstr "" + +#: ../../po/../src/extension/dependency.cpp:250 +#, fuzzy +msgid " description: " +msgstr "Вылучэньне" + +#. static int i = 0; +#. std::cout << "Checking module[" << i++ << "]: " << name << std::endl; +#: ../../po/../src/extension/extension.cpp:244 +msgid "" +" This is caused by an improper .inx file for this extension. An improper ." +"inx file could have been caused by a faulty installation of Inkscape." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:247 +msgid "an ID was not defined for it." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:251 +msgid "there was no name defined for it." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:255 +msgid "the XML description of it got lost." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:259 +msgid "no implementation was defined for the extension." +msgstr "" + +#. std::cout << "Failed: " << *(_deps[i]) << std::endl; +#: ../../po/../src/extension/extension.cpp:266 +msgid "a dependency was not met." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:286 +#, fuzzy +msgid "Extension \"" +msgstr "Пашырэньне" + +#: ../../po/../src/extension/extension.cpp:286 +msgid "\" failed to load because " +msgstr "" + +#: ../../po/../src/extension/extension.cpp:565 +#, c-format +msgid "Could not create extension error log file '%s'" +msgstr "" + +#. This is some filler text, needs to change before relase +#: ../../po/../src/extension/error-file.cpp:56 +msgid "" +"One or more extensions failed to load\n" +"\n" +"The failed extensions have been skipped. Inkscape will continue to run " +"normally but those extensions will be unavailable. For details to " +"troubleshoot this problem, please refer to the error log located at: " +msgstr "" + +#. This is some filler text, needs to change before relase +#: ../../po/../src/extension/error-file.cpp:65 +msgid "Show dialog on startup" +msgstr "" + +#: ../../po/../src/extension/implementation/script.cpp:845 +msgid "" +"Inkscape has received an error from the script that it called. The text " +"returned with the error is included below. Inkscape will continue working, " +"but the action you requested has been cancelled." +msgstr "" + +#: ../../po/../src/extension/implementation/script.cpp:858 +msgid "" +"Inkscape has received additional data from the script executed. The script " +"did not return an error, but this may indicate the results will not be as " +"expected." +msgstr "" + +#: ../../po/../src/extension/init.cpp:173 +msgid "Null external module directory name. Modules will not be loaded." +msgstr "" + +#: ../../po/../src/extension/init.cpp:187 +#, c-format +msgid "" +"Modules directory (%s) is unavailable. External modules in that directory " +"will not be loaded." +msgstr "" + +#: ../../po/../src/extension/internal/gnome.cpp:80 +msgid "Select printer" +msgstr "Выбярыце друкарку" + +#: ../../po/../src/extension/internal/gnome.cpp:131 +#, fuzzy +msgid "Inkscape: Print Preview" +msgstr "Sodipodi (дакумэнт з назвай %s..): Папярэдні прагляд друку" + +#: ../../po/../src/extension/internal/grid.cpp:213 +#, fuzzy +msgid "Line Width" +msgstr "Шырыня:" + +#: ../../po/../src/extension/internal/grid.cpp:214 +#, fuzzy +msgid "Horizontal Spacing" +msgstr "Адлюстраваць гарызантальна" + +#: ../../po/../src/extension/internal/grid.cpp:215 +#, fuzzy +msgid "Vertical Spacing" +msgstr "Адлюстраваць вэртыкальна" + +#: ../../po/../src/extension/internal/grid.cpp:216 +#, fuzzy +msgid "Horizontal Offset" +msgstr "Адлюстраваць гарызантальна" + +#: ../../po/../src/extension/internal/grid.cpp:217 +#, fuzzy +msgid "Vertical Offset" +msgstr "Адлюстраваць вэртыкальна" + +#: ../../po/../src/extension/internal/ps.cpp:123 +#, fuzzy +msgid "Print Destination" +msgstr "Друк" + +#. Print properties frame +#: ../../po/../src/extension/internal/ps.cpp:138 +msgid "Print properties" +msgstr "Уласьцівасьці друку" + +#: ../../po/../src/extension/internal/ps.cpp:145 +msgid "Print using PostScript operators" +msgstr "Дроукаваць карыстаючыся апэратарамі PostScript" + +#: ../../po/../src/extension/internal/ps.cpp:147 +msgid "" +"Use PostScript vector operators. The resulting image is usually smaller in " +"file size and can be arbitrarily scaled, but alpha transparency and patterns " +"will be lost." +msgstr "" + +#: ../../po/../src/extension/internal/ps.cpp:152 +msgid "Print as bitmap" +msgstr "Друкаваць як кропкавы відарыс" + +#: ../../po/../src/extension/internal/ps.cpp:154 +msgid "" +"Print everything as bitmap. The resulting image is usually larger in file " +"size and cannot be arbitrarily scaled without quality loss, but all objects " +"will be rendered exactly as displayed." +msgstr "" + +#: ../../po/../src/extension/internal/ps.cpp:168 +msgid "Preferred resolution (dots per inch) of bitmap" +msgstr "" + +#: ../../po/../src/extension/internal/ps.cpp:182 +msgid "Resolution:" +msgstr "Разрозьненьне:" + +#. Print destination frame +#: ../../po/../src/extension/internal/ps.cpp:186 +msgid "Print destination" +msgstr "Друк" + +#: ../../po/../src/extension/internal/ps.cpp:192 +#, fuzzy +msgid "" +"Use '> filename' to print to file.\n" +"Use '| prog arg...' to pipe to a program." +msgstr "" +"Пазначце чаргу lpr.\n" +"Выкарыстоўвайце '> назва_файла' каб друкаваць у файл.\n" +"Выкарыстоўвайце '| праграма аргумэнты...' каб накіраваць праз канал у " +"праграму" + +#: ../../po/../src/extension/internal/ps.cpp:1227 +#, fuzzy +msgid "write error occurred" +msgstr "адбылася памылка запісу" + +#: ../../po/../src/extension/prefdialog.cpp:21 +#, fuzzy +msgid " Preferences" +msgstr "Элемэнт зьяўляецца спасылкай" + +#. We can't call sp_ui_error_dialog because we may be +#. running from the console, in which case calling sp_ui +#. routines will cause a segfault. See bug 1000350 - bryce +#. sp_ui_error_dialog(_("Format autodetect failed. The file is being opened as SVG.")); +#: ../../po/../src/extension/system.cpp:105 +msgid "Format autodetect failed. The file is being opened as SVG." +msgstr "" + +#. TRANSLATORS: default.svg is localizable - this is the name of the default document +#. template. This way you can localize the default pagesize, translate the name of +#. the default layer, etc. If you wish to localize this file, please create a +#. localized share/templates/default.xx.svg file, where xx is your language code. +#: ../../po/../src/file.cpp:133 +#, fuzzy +msgid "default.svg" +msgstr "Дапомнае" + +#: ../../po/../src/file.cpp:215 ../../po/../src/file.cpp:900 +#, c-format +msgid "Failed to load the requested file %s" +msgstr "" + +#: ../../po/../src/file.cpp:240 +#, fuzzy +msgid "Document not saved yet. Cannot revert." +msgstr "Назва дакумэнта:" + +#: ../../po/../src/file.cpp:246 +#, c-format +msgid "Changes will be lost! Are you sure you want to reload document %s?" +msgstr "" + +#: ../../po/../src/file.cpp:266 +#, fuzzy +msgid "Document reverted." +msgstr "Назва дакумэнта:" + +#: ../../po/../src/file.cpp:268 +#, fuzzy +msgid "Document not reverted." +msgstr "Назва дакумэнта:" + +#: ../../po/../src/file.cpp:382 +msgid "Select file to open" +msgstr "Выбярыце файл для адкрыцьця" + +#: ../../po/../src/file.cpp:518 +#, c-format +msgid "Removed %i unused definition in <defs>." +msgid_plural "Removed %i unused definitions in <defs>." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/file.cpp:523 +msgid "No unused definitions in <defs>." +msgstr "" + +#: ../../po/../src/file.cpp:548 +#, c-format +msgid "" +"No Inkscape extension found to save document (%s). This may have been " +"caused by an unknown filename extension." +msgstr "" + +#: ../../po/../src/file.cpp:549 ../../po/../src/file.cpp:557 +#, fuzzy +msgid "Document not saved." +msgstr "Назва дакумэнта:" + +#: ../../po/../src/file.cpp:556 +#, c-format +msgid "File %s could not be saved." +msgstr "" + +#: ../../po/../src/file.cpp:566 +#, fuzzy +msgid "Document saved." +msgstr "Назва дакумэнта:" + +#: ../../po/../src/file.cpp:614 +#, fuzzy, c-format +msgid "drawing%s" +msgstr "Рысаваньне" + +#: ../../po/../src/file.cpp:620 +#, fuzzy, c-format +msgid "drawing-%d%s" +msgstr "Рысаваньне" + +#: ../../po/../src/file.cpp:655 +#, fuzzy +msgid "Select file to save to" +msgstr "Выбярыце файл для адкрыцьця" + +#: ../../po/../src/file.cpp:739 +msgid "No changes need to be saved." +msgstr "" + +#: ../../po/../src/file.cpp:926 +msgid "Select file to import" +msgstr "Выбярыце файл для імпартаваньня" + +#: ../../po/../src/gradient-context.cpp:263 +msgid "Ctrl: snap gradient angle" +msgstr "" + +#: ../../po/../src/gradient-context.cpp:264 +msgid "Shift: draw gradient around the starting point" +msgstr "" + +#. We did an undoable action, but sp_document_done will be called by the knot when released +#. status text; we do not track coords because this branch is run once, not all the time +#. during drag +#: ../../po/../src/gradient-context.cpp:462 +#, c-format +msgid "Gradient for %d objects; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/gradient-context.cpp:464 +#, fuzzy +msgid "Select objects on which to create gradient." +msgstr "Выразае вылучаныя аб'екты ў буфэр абмену" + +#: ../../po/../src/gradient-drag.cpp:65 +#, fuzzy +msgid "Linear gradient start" +msgstr "Лінэйны градыент" + +#. POINT_LG_P1 +#: ../../po/../src/gradient-drag.cpp:66 +#, fuzzy +msgid "Linear gradient end" +msgstr "Лінэйны градыент" + +#: ../../po/../src/gradient-drag.cpp:67 +#, fuzzy +msgid "Radial gradient center" +msgstr "Кругавы градыент" + +#: ../../po/../src/gradient-drag.cpp:68 ../../po/../src/gradient-drag.cpp:69 +#, fuzzy +msgid "Radial gradient radius" +msgstr "Кругавы градыент" + +#: ../../po/../src/gradient-drag.cpp:70 +#, fuzzy +msgid "Radial gradient focus" +msgstr "Кругавы градыент" + +#: ../../po/../src/gradient-drag.cpp:659 +#, c-format +msgid "" +"%s for: %s%s; drag with Ctrl to snap angle, with Ctrl+Alt to " +"preserve angle, with Ctrl+Shift to scale around center" +msgstr "" + +#: ../../po/../src/gradient-drag.cpp:662 +msgid " (stroke)" +msgstr "" + +#: ../../po/../src/gradient-drag.cpp:665 +msgid "" +"Radial gradient center and focus; drag with Shift to " +"separate focus" +msgstr "" + +#: ../../po/../src/gradient-drag.cpp:667 +#, c-format +msgid "" +"Gradient point shared by %d gradients; drag with Shift to " +"separate" +msgstr "" + +#: ../../po/../src/helper/units.cpp:40 +msgid "Unit" +msgstr "Адзінка" + +#: ../../po/../src/helper/units.cpp:40 +msgid "Units" +msgstr "Адзінкі" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Point" +msgstr "Пункт" + +#: ../../po/../src/helper/units.cpp:41 +msgid "pt" +msgstr "pt" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Points" +msgstr "Пункты" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Pt" +msgstr "Pt" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Pixel" +msgstr "Піксэль" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Pixels" +msgstr "Піксэлі" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Px" +msgstr "Px" + +#. You can add new elements from this point forward +#: ../../po/../src/helper/units.cpp:44 ../share/extensions/straightseg.inx.h:2 +msgid "Percent" +msgstr "Адсотка" + +#: ../../po/../src/helper/units.cpp:44 +msgid "Percents" +msgstr "Адсоткі" + +#: ../../po/../src/helper/units.cpp:45 +msgid "Millimeter" +msgstr "Мілімэтар" + +#: ../../po/../src/helper/units.cpp:45 +msgid "mm" +msgstr "mm" + +#: ../../po/../src/helper/units.cpp:45 +msgid "Millimeters" +msgstr "Мілімэтры" + +#: ../../po/../src/helper/units.cpp:46 +msgid "Centimeter" +msgstr "Санцімэтар" + +#: ../../po/../src/helper/units.cpp:46 +msgid "cm" +msgstr "cm" + +#: ../../po/../src/helper/units.cpp:46 +msgid "Centimeters" +msgstr "Сантымэтры" + +#: ../../po/../src/helper/units.cpp:47 +msgid "Meter" +msgstr "Мэтар" + +#: ../../po/../src/helper/units.cpp:47 +msgid "m" +msgstr "m" + +#: ../../po/../src/helper/units.cpp:47 +#, fuzzy +msgid "Meters" +msgstr "Мэтар" + +#. no svg_unit +#: ../../po/../src/helper/units.cpp:48 +msgid "Inch" +msgstr "Цаля" + +#: ../../po/../src/helper/units.cpp:48 +msgid "in" +msgstr "in" + +#: ../../po/../src/helper/units.cpp:48 +msgid "Inches" +msgstr "Цалі" + +#. Volatiles do not have default, so there are none here +#. TRANSLATORS: for info, see http://www.w3.org/TR/REC-CSS2/syndata.html#length-units +#: ../../po/../src/helper/units.cpp:51 +msgid "Em square" +msgstr "М-квадрат" + +#: ../../po/../src/helper/units.cpp:51 +msgid "em" +msgstr "em" + +#: ../../po/../src/helper/units.cpp:51 +msgid "Em squares" +msgstr "М-квадрат" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/REC-CSS2/syndata.html#length-units +#: ../../po/../src/helper/units.cpp:53 +msgid "Ex square" +msgstr "X-квадрат" + +#: ../../po/../src/helper/units.cpp:53 +msgid "ex" +msgstr "ex" + +#: ../../po/../src/helper/units.cpp:53 +msgid "Ex squares" +msgstr "X-квадрат" + +#: ../../po/../src/inkscape.cpp:468 +msgid "Untitled document" +msgstr "Дакумэнт бяз назвы" + +#. Show nice dialog box +#: ../../po/../src/inkscape.cpp:497 +#, fuzzy +msgid "Inkscape encountered an internal error and will close now.\n" +msgstr "Sodipodi сустрэла памылку й будзе зараз закрыта.\n" + +#: ../../po/../src/inkscape.cpp:498 +#, fuzzy +msgid "" +"Automatic backups of unsaved documents were done to the following " +"locations:\n" +msgstr "" +"Азтаматычнае рэзэрваваньне незахаваных дакумэнтаў выканана ў наступныя " +"мейсцы:\n" + +#: ../../po/../src/inkscape.cpp:499 +#, fuzzy +msgid "Automatic backup of the following documents failed:\n" +msgstr "Збой аўтаматычнага рэзэрваваньня наступных дакумэнтаў:\n" + +#: ../../po/../src/inkscape.cpp:634 +#, c-format +msgid "" +"Cannot create directory %s.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:635 +#, c-format +msgid "" +"%s is not a valid directory.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:636 +#, c-format +msgid "" +"Cannot create file %s.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:637 +#, c-format +msgid "" +"Cannot write file %s.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:638 +msgid "" +"Although Inkscape will run, it will use default settings,\n" +"and any changes made in preferences will not be saved." +msgstr "" + +#: ../../po/../src/inkscape.cpp:708 +#, c-format +msgid "" +"%s is not a regular file.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:709 +#, c-format +msgid "" +"%s not a valid XML file, or\n" +"you don't have read permissions on it.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:711 +#, c-format +msgid "" +"%s is not a valid menus file.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:712 +msgid "" +"Inkscape will run with default menus.\n" +"New menus will not be saved." +msgstr "" + +#. sp_ui_menu_append_check_item_from_verb(m, view, _("_Menu"), _("Show or hide the menu bar"), "menu", +#. checkitem_toggled, checkitem_update, 0); +#: ../../po/../src/interface.cpp:753 +msgid "Commands Bar" +msgstr "" + +#: ../../po/../src/interface.cpp:753 +#, fuzzy +msgid "Show or hide the Commands bar (under the menu)" +msgstr "Паказаць кіруючыя" + +#: ../../po/../src/interface.cpp:755 +#, fuzzy +msgid "Tool Controls" +msgstr "Выбары інструмэнта" + +#: ../../po/../src/interface.cpp:755 +#, fuzzy +msgid "Show or hide the Tool Controls panel" +msgstr "Паказаць кіруючыя" + +#: ../../po/../src/interface.cpp:757 +msgid "_Toolbox" +msgstr "" + +#: ../../po/../src/interface.cpp:757 +msgid "Show or hide the main toolbox (on the left)" +msgstr "" + +#: ../../po/../src/interface.cpp:763 +msgid "_Statusbar" +msgstr "" + +#: ../../po/../src/interface.cpp:763 +msgid "Show or hide the statusbar (at the bottom of the window)" +msgstr "" + +#: ../../po/../src/interface.cpp:820 +#, c-format +msgid "Verb \"%s\" Unknown" +msgstr "" + +#. TRANSLATORS: #%s is the id of the group e.g. , not a number. +#: ../../po/../src/interface.cpp:930 +#, fuzzy, c-format +msgid "Enter group #%s" +msgstr "Рэдагаваньне" + +#: ../../po/../src/interface.cpp:941 +#, fuzzy +msgid "Go to parent" +msgstr "Няма рафарбоўкі" + +#: ../../po/../src/interface.cpp:972 +msgid "Could not parse SVG data" +msgstr "" + +#: ../../po/../src/interface.cpp:1135 +#, c-format +msgid "Overwrite %s" +msgstr "" + +#: ../../po/../src/interface.cpp:1153 +#, c-format +msgid "" +"The file %s already exists. Do you want to overwrite that file with the " +"current document?" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:59 +msgid "Jabber connection lost." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:72 +#, c-format +msgid "Sending message; %u message remaining in send queue." +msgid_plural "Sending message; %u messages remaining in send queue." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:78 +msgid "Receive queue empty." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:154 +#, c-format +msgid "Receiving change; %u change left to process." +msgid_plural "Receiving change; %u changes left to process." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:157 +#, c-format +msgid "%s has left the chatroom." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:221 +msgid "Nickname %1 is already in use. Please choose a different nickname." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:225 +msgid "An error was encountered while attempting to connect to the server." +msgstr "" + +#. Check to see if the user made any modifications to this document. If so, +#. we want to give them the option of (1) letting us clear their document or (2) +#. opening a new, blank document for the whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:131 +msgid "%1 has invited you to a whiteboard session." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:132 +msgid "Incoming whiteboard invitation from %1" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:135 +msgid "Do you wish to accept %1's whiteboard session invitation?" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:137 +msgid "" +"Would you like to accept %1's invitation in a new document window?\n" +"Accepting the invitation in your current window will discard unsaved changes." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:143 +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:198 +#, fuzzy +msgid "Accept invitation" +msgstr "Вылучэньне" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:144 +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:199 +msgid "Decline invitation" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:145 +#, fuzzy +msgid "Accept invitation in new document window" +msgstr "Стварае новы дакумэнт SVG" + +#. We could not create a new desktop; ask the user if she or he wants to +#. replace the current document and accept the invitation, or reject the invitation. +#. TRANSLATORS: %1 is a userid here +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:196 +msgid "" +"A new document window could not be opened for a whiteboard session with %" +"1" +msgstr "" + +#. TRANSLATORS: %1 is the peer whom refused our invitation. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:238 +msgid "" +"The user %1 has refused your " +"whiteboard invitation.\n" +"\n" +msgstr "" + +#. TRANSLATORS: %1 is the peer whom refused our invitation, %2 is our Jabber identity. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:241 +msgid "" +"You are still connected to a Jabber server as %2, and may send an " +"invitation to %1 again, or you may send an invitation to a different " +"user." +msgstr "" + +#. TRANSLATORS: %1 is the peer whom we tried to contact, but is already in a whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:252 +msgid "" +"The user %1 is already in a " +"whiteboard session.\n" +"\n" +msgstr "" + +#. TRANSLATORS: %1 is the peer whom we tried to contact, but is already in a whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:255 +msgid "" +"You are still connected to a Jabber server as %1, and may send an " +"invitation to a different user." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/invitation-confirm-dialog.cpp:26 +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:24 +msgid "_Write session file:" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/message-processors.cpp:145 +#, c-format +msgid "%s has joined the chatroom." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/message-queue.cpp:87 +#, c-format +msgid "%u change in receive queue." +msgid_plural "%u changes in receive queue." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/jabber_whiteboard/message-queue.cpp:117 +#, c-format +msgid "%u change in send queue." +msgid_plural "%u changes in send queue." +msgstr[0] "" +msgstr[1] "" + +#. if ID is NULL, then we have a real problem -- we were not able to find a key +#. nor generate one. The only thing we can really do here is abort, since we have +#. no way to let the other client(s) uniquely identify this object. +#. FIXME: If this indicates a programming bug, then don't request translation with +#. * _(...): it is most useful in untranslated form so that developers may search for +#. * it when someone reports it in a bug report (as we want users to do for all bugs, +#. * as indicated by it being a g_warning string). +#. * +#. * Otherwise, if it is not a programming bug but a network error or a bug in the +#. * remote peer (perhaps running different software) or whatever, then present it in +#. * an alert box, and avoid use of technical jargon `NULL'. +#. +#: ../../po/../src/jabber_whiteboard/message-utilities.cpp:171 +msgid "" +"ID for new object is NULL even after generation and lookup attempts: the new " +"object will NOT be sent, nor will any of its child objects!" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:60 +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:995 +msgid "Select a location and filename" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:62 +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:997 +#, fuzzy +msgid "Set filename" +msgstr "Захаваць файл" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:301 +msgid "No SSL certificate was found." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:304 +msgid "The SSL certificate provided by the Jabber server is untrusted." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:307 +msgid "The SSL certificate provided by the Jabber server is expired." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:310 +msgid "" +"The SSL certificate provided by the Jabber server has not been activated." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:313 +msgid "" +"The SSL certificate provided by the Jabber server contains a hostname that " +"does not match the Jabber server's hostname." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:316 +msgid "" +"The SSL certificate provided by the Jabber server contains an invalid " +"fingerprint." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:319 +msgid "An unknown error occurred while setting up the SSL connection." +msgstr "" + +#. TRANSLATORS: %1 is the message that describes the specific error that occurred when +#. establishing the SSL connection. +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:325 +msgid "" +"%1\n" +"\n" +"Do you wish to continue connecting to the Jabber server?" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:328 +msgid "Continue connecting and ignore further errors" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:329 +msgid "Continue connecting, but warn me of further errors" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:330 +#, fuzzy +msgid "Cancel connection" +msgstr "Вылучэньне" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:777 +#, c-format +msgid "Established whiteboard session with %s." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:785 +#, c-format +msgid "%s has left the whiteboard session." +msgstr "" + +#. Inform the user +#. TRANSLATORS: %1 is the name of the user that disconnected, %2 is the name of the user whom the disconnected user disconnected from. +#. This message is not used in a chatroom context. +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:790 +msgid "" +"The user %1 has left the " +"whiteboard session.\n" +"\n" +msgstr "" + +#. TRANSLATORS: %1 and %2 are userids +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:792 +msgid "" +"You are still connected to a Jabber server as %2, and may establish a " +"new session to %1 or a different user." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:988 +msgid "" +"Could not open file %1 for session recording.\n" +"The error encountered was: %2.\n" +"\n" +"You may select a different location to record the session, or you may opt to " +"not record this session." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:990 +msgid "Choose a different location" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:991 +msgid "Skip session recording" +msgstr "" + +#: ../../po/../src/knot.cpp:673 +msgid "Node or handle drag canceled." +msgstr "" + +#: ../../po/../src/libnrtype/FontFactory.cpp:358 +msgid "Ignoring font without family that will crash Pango" +msgstr "" + +#: ../../po/../src/main.cpp:395 +msgid "Print the Inkscape version number" +msgstr "" + +#: ../../po/../src/main.cpp:400 +msgid "Do not use X server (only process files from console)" +msgstr "Не выкарыстоўваць паслужнік Ð¥ (толькі апрацоўваць файл з кансолі)" + +#: ../../po/../src/main.cpp:405 +#, fuzzy +msgid "Try to use X server (even if $DISPLAY is not set)" +msgstr "" +"Працягваць спрабаваць выкарыстоўваць паслужнік Ð¥ калі $DISPLAY не ўсталявана)" + +#: ../../po/../src/main.cpp:410 +msgid "Open specified document(s) (option string may be excluded)" +msgstr "Адкрывае пазначаныя дакумэнты (выбар радка можа быць выключаны)" + +#: ../../po/../src/main.cpp:411 ../../po/../src/main.cpp:416 +#: ../../po/../src/main.cpp:421 ../../po/../src/main.cpp:483 +#: ../../po/../src/main.cpp:488 ../../po/../src/main.cpp:493 +msgid "FILENAME" +msgstr "Назва файла" + +#: ../../po/../src/main.cpp:415 +msgid "Print document(s) to specified output file (use '| program' for pipe)" +msgstr "" +"Друкуе дакумэнт(ы) у пазначаны выходны файл (выкарыстоўвайце '| праграма' " +"для стварэньня канала)" + +#: ../../po/../src/main.cpp:420 +#, fuzzy +msgid "Export document to a PNG file" +msgstr "Экспартаваць дакумэнт у файл png" + +#: ../../po/../src/main.cpp:425 +#, fuzzy +msgid "The resolution used for exporting SVG into bitmap (default 90)" +msgstr "Разрозьненьне для канвэртацыі SVG у растар (дапомна 72,0)" + +#: ../../po/../src/main.cpp:426 +msgid "DPI" +msgstr "DPI" + +#: ../../po/../src/main.cpp:430 +#, fuzzy +msgid "" +"Exported area in SVG user units (default is the canvas; 0,0 is lower-left " +"corner)" +msgstr "" +"Прастора экспартаваньня ў мілімэтрах (дапомна выбіраецца ўвесь дакумэнт, 0,0 " +"- левы ніжні кут)" + +#: ../../po/../src/main.cpp:431 +msgid "x0:y0:x1:y1" +msgstr "x0:y0:x1:y1" + +#: ../../po/../src/main.cpp:435 +msgid "Exported area is the entire drawing (not canvas)" +msgstr "" + +#: ../../po/../src/main.cpp:440 +msgid "" +"Snap the bitmap export area outwards to the nearest integer values (in SVG " +"user units)" +msgstr "" + +#: ../../po/../src/main.cpp:445 +#, fuzzy +msgid "The width of exported bitmap in pixels (overrides export-dpi)" +msgstr "Шырыня генераванага растра ў піксэлях (перазапіс dpi)" + +#: ../../po/../src/main.cpp:446 +msgid "WIDTH" +msgstr "ШЫРЫНЯ" + +#: ../../po/../src/main.cpp:450 +#, fuzzy +msgid "The height of exported bitmap in pixels (overrides export-dpi)" +msgstr "Вышыня генераванага растра ў піксэлях (перазапіс dpi)" + +#: ../../po/../src/main.cpp:451 +msgid "HEIGHT" +msgstr "ВЫШЫНЯ" + +#: ../../po/../src/main.cpp:455 +#, fuzzy +msgid "The ID of the object to export (overrides export-area)" +msgstr "Шырыня генераванага растра ў піксэлях (перазапіс dpi)" + +#: ../../po/../src/main.cpp:456 ../../po/../src/main.cpp:532 +msgid "ID" +msgstr "" + +#. TRANSLATORS: this means: "Only export the object whose id is given in --export-id". +#. See "man inkscape" for details. +#: ../../po/../src/main.cpp:462 +msgid "" +"Export just the object with export-id, hide all others (only with export-id)" +msgstr "" + +#: ../../po/../src/main.cpp:467 +msgid "Use stored filename and DPI hints when exporting (only with export-id)" +msgstr "" + +#: ../../po/../src/main.cpp:472 +#, fuzzy +msgid "Background color of exported bitmap (any SVG-supported color string)" +msgstr "" +"Колер тла экспартаванага растра (толькі радок колера, які падтрымлівае SVG)" + +#: ../../po/../src/main.cpp:473 +msgid "COLOR" +msgstr "КОЛЕР" + +#: ../../po/../src/main.cpp:477 +#, fuzzy +msgid "Background opacity of exported bitmap (either 0.0 to 1.0, or 1 to 255)" +msgstr "" +"Колер тла экспартаванага растра (толькі радок колера, які падтрымлівае SVG)" + +#: ../../po/../src/main.cpp:478 +msgid "VALUE" +msgstr "" + +#: ../../po/../src/main.cpp:482 +#, fuzzy +msgid "Export document to plain SVG file (no sodipodi or inkscape namespaces)" +msgstr "" +"Экспартаваньне дакумэнта ў звычайны файл SVG (без прасторы імёнаў \"xmlns:" +"sodipodi\")" + +#: ../../po/../src/main.cpp:487 +#, fuzzy +msgid "Export document to a PS file" +msgstr "Экспартаваць дакумэнт у файл png" + +#: ../../po/../src/main.cpp:492 +#, fuzzy +msgid "Export document to an EPS file" +msgstr "Экспартаваць дакумэнт у файл png" + +#: ../../po/../src/main.cpp:497 +#, fuzzy +msgid "Convert text object to paths on export (EPS)" +msgstr "Апускае вылучаныя аб'екты на ніжні слой" + +#: ../../po/../src/main.cpp:502 +msgid "Export files with the bounding box set to the page size (EPS)" +msgstr "" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:508 +msgid "" +"Query the X coordinate of the drawing or, if specified, of the object with --" +"query-id" +msgstr "" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:514 +msgid "" +"Query the Y coordinate of the drawing or, if specified, of the object with --" +"query-id" +msgstr "" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:520 +msgid "" +"Query the width of the drawing or, if specified, of the object with --query-" +"id" +msgstr "" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:526 +msgid "" +"Query the height of the drawing or, if specified, of the object with --query-" +"id" +msgstr "" + +#: ../../po/../src/main.cpp:531 +#, fuzzy +msgid "The ID of the object whose dimensions are queried" +msgstr "Шырыня генераванага растра ў піксэлях (перазапіс dpi)" + +#. TRANSLATORS: this option makes Inkscape print the name (path) of the extension directory +#: ../../po/../src/main.cpp:537 +msgid "Print out the extension directory and exit" +msgstr "" + +#: ../../po/../src/main.cpp:542 +msgid "Show given files one-by-one, switch to next on any key/mouse event" +msgstr "" +"Паказываць заданыя файлы адзін за адным, пераключацца на наступны па любой " +"падзеі мышы/клявіятуры" + +#: ../../po/../src/main.cpp:547 +msgid "Use the new Gtkmm GUI interface" +msgstr "" + +#: ../../po/../src/main.cpp:552 +msgid "Remove unused definitions from the defs section(s) of the document" +msgstr "" + +#: ../../po/../src/main.cpp:741 +msgid "" +"[OPTIONS...] [FILE...]\n" +"\n" +"Available options:" +msgstr "" + +#: ../../po/../src/menus-skeleton.h:17 +#, fuzzy +msgid "_New" +msgstr "Стварыць" + +#: ../../po/../src/menus-skeleton.h:22 +#, fuzzy +msgid "Open _Recent" +msgstr "Адкрыць" + +#: ../../po/../src/menus-skeleton.h:53 +#, fuzzy +msgid "_Edit" +msgstr "Рэдагаваньне" + +#: ../../po/../src/menus-skeleton.h:84 +#, fuzzy +msgid "_View" +msgstr "Выгляд" + +#: ../../po/../src/menus-skeleton.h:85 +#, fuzzy +msgid "_Zoom" +msgstr "Маштабаваньне" + +#: ../../po/../src/menus-skeleton.h:102 +#, fuzzy +msgid "Show/Hide" +msgstr "Паказаць кіруючыя" + +#: ../../po/../src/menus-skeleton.h:107 +#, fuzzy +msgid "_Display mode" +msgstr "Дысплэй" + +#: ../../po/../src/menus-skeleton.h:126 +#, fuzzy +msgid "_Layer" +msgstr "Апусьціць" + +#: ../../po/../src/menus-skeleton.h:143 +#, fuzzy +msgid "_Object" +msgstr "Аб'ект" + +#: ../../po/../src/menus-skeleton.h:165 +#, fuzzy +msgid "_Path" +msgstr "Уставіць" + +#: ../../po/../src/menus-skeleton.h:188 +#, fuzzy +msgid "_Text" +msgstr "Тэкст" + +#: ../../po/../src/menus-skeleton.h:200 +#, fuzzy +msgid "Effects" +msgstr "Аб'ект" + +#: ../../po/../src/menus-skeleton.h:207 +msgid "Whiteboa_rd" +msgstr "" + +#: ../../po/../src/menus-skeleton.h:220 +#, fuzzy +msgid "_Help" +msgstr "Бакі:" + +#: ../../po/../src/menus-skeleton.h:222 +msgid "Tutorials" +msgstr "" + +#: ../../po/../src/node-context.cpp:382 +msgid "" +"Ctrl: toggle node type, snap handle angle, move hor/vert; Ctrl" +"+Alt: move along handles" +msgstr "" + +#: ../../po/../src/node-context.cpp:383 +msgid "" +"Shift: toggle node selection, disable snapping, rotate both handles" +msgstr "" + +#: ../../po/../src/node-context.cpp:384 +msgid "Alt: lock handle length; Ctrl+Alt: move along handles" +msgstr "" + +#: ../../po/../src/nodepath.cpp:1399 ../../po/../src/nodepath.cpp:1411 +#: ../../po/../src/nodepath.cpp:1492 ../../po/../src/nodepath.cpp:1504 +msgid "To join, you must have two endnodes selected." +msgstr "" + +#: ../../po/../src/nodepath.cpp:1633 ../../po/../src/nodepath.cpp:1647 +msgid "" +"Select two non-endpoint nodes on a path between which to delete " +"segments." +msgstr "" + +#: ../../po/../src/nodepath.cpp:1743 +#, fuzzy +msgid "Cannot find path between nodes." +msgstr "Далучае рысы да вылучаных вузлоў" + +#: ../../po/../src/nodepath.cpp:2822 +#, c-format +msgid "" +"Node handle: angle %0.2f°, length %s; with Ctrl to snap " +"angle; with Alt to lock length; with Shift to rotate both " +"handles" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3351 +msgid "" +"Node: drag to edit the path; with Ctrl to snap to horizontal/" +"vertical; with Ctrl+Alt to snap to handles' directions" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3375 +msgid "" +"Node handle: drag to shape the curve; with Ctrl to snap angle; " +"with Alt to lock length; with Shift to rotate both handles" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3399 +msgid "" +"Node handle: drag to shape the curve; with Ctrl to snap angle; " +"with Alt to lock length; with Shift to rotate the opposite " +"handle in sync" +msgstr "" + +#. TRANSLATORS: "end" is an adjective here (NOT a verb) +#: ../../po/../src/nodepath.cpp:3591 +#, fuzzy +msgid "end node" +msgstr "Дадаць водступ вузла" + +#. TRANSLATORS: "cusp" means "sharp" (cusp node); see also the Advanced Tutorial +#: ../../po/../src/nodepath.cpp:3596 +msgid "cusp" +msgstr "" + +#. TRANSLATORS: "smooth" is an adjective here +#: ../../po/../src/nodepath.cpp:3599 +msgid "smooth" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3601 +msgid "symmetric" +msgstr "" + +#. TRANSLATORS: "end" is an adjective here (NOT a verb) +#: ../../po/../src/nodepath.cpp:3607 +msgid "end node, handle retracted (drag with Shift to extend)" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3609 +msgid "one handle retracted (drag with Shift to extend)" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3612 +msgid "both handles retracted (drag with Shift to extend)" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3624 +#, fuzzy +msgid "Drag nodes or node handles; arrow keys to move nodes" +msgstr "" +"Стварае новую дугу. Націсьніце '+' каб пераключыцца паміж \"Дадаць\" і " +"\"Стварыць\"." + +#: ../../po/../src/nodepath.cpp:3625 +#, fuzzy +msgid "Drag the node or its handles; arrow keys to move the node" +msgstr "" +"Стварае новую дугу. Націсьніце '+' каб пераключыцца паміж \"Дадаць\" і " +"\"Стварыць\"." + +#: ../../po/../src/nodepath.cpp:3651 ../../po/../src/nodepath.cpp:3663 +#, fuzzy +msgid "Select a single object to edit its nodes or handles." +msgstr "Вылучае ўсе аб'екты ў дакумэнце" + +#: ../../po/../src/nodepath.cpp:3655 +#, c-format +msgid "" +"0 out of %i node selected. Click, Shift+click, " +"or drag around nodes to select." +msgid_plural "" +"0 out of %i nodes selected. Click, Shift+click, " +"or drag around nodes to select." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/nodepath.cpp:3661 +msgid "Drag the handles of the object to modify it." +msgstr "" + +#: ../../po/../src/nodepath.cpp:3669 +#, fuzzy, c-format +msgid "%i of %i node selected; %s. %s." +msgid_plural "%i of %i nodes selected; %s. %s." +msgstr[0] "Далучае рысы да вылучаных вузлоў" +msgstr[1] "Далучае рысы да вылучаных вузлоў" + +#: ../../po/../src/nodepath.cpp:3675 +#, fuzzy, c-format +msgid "%i of %i node selected. %s." +msgid_plural "%i of %i nodes selected. %s." +msgstr[0] "Далучае рысы да вылучаных вузлоў" +msgstr[1] "Далучае рысы да вылучаных вузлоў" + +#: ../../po/../src/object-edit.cpp:493 +msgid "" +"Adjust the horizontal rounding radius; with Ctrl to make the " +"vertical radius the same" +msgstr "" + +#: ../../po/../src/object-edit.cpp:499 +msgid "" +"Adjust the vertical rounding radius; with Ctrl to make the " +"horizontal radius the same" +msgstr "" + +#: ../../po/../src/object-edit.cpp:506 ../../po/../src/object-edit.cpp:513 +msgid "" +"Adjust the width and height of the rectangle; with Ctrl to " +"lock ratio or stretch in one dimension only" +msgstr "" + +#: ../../po/../src/object-edit.cpp:686 +msgid "Adjust ellipse width, with Ctrl to make circle" +msgstr "" + +#: ../../po/../src/object-edit.cpp:689 +msgid "Adjust ellipse height, with Ctrl to make circle" +msgstr "" + +#: ../../po/../src/object-edit.cpp:692 +msgid "" +"Position the start point of the arc or segment; with Ctrl to " +"snap angle; drag inside the ellipse for arc, outside for " +"segment" +msgstr "" + +#: ../../po/../src/object-edit.cpp:695 +msgid "" +"Position the end point of the arc or segment; with Ctrl to " +"snap angle; drag inside the ellipse for arc, outside for " +"segment" +msgstr "" + +#: ../../po/../src/object-edit.cpp:800 +msgid "" +"Adjust the tip radius of the star or polygon; with Shift to " +"round; with Alt to randomize" +msgstr "" + +#: ../../po/../src/object-edit.cpp:803 +msgid "" +"Adjust the base radius of the star; with Ctrl to keep star " +"rays radial (no skew); with Shift to round; with Alt to " +"randomize" +msgstr "" + +#: ../../po/../src/object-edit.cpp:967 +msgid "" +"Roll/unroll the spiral from inside; with Ctrl to snap angle; " +"with Alt to converge/diverge" +msgstr "" + +#: ../../po/../src/object-edit.cpp:969 +msgid "" +"Roll/unroll the spiral from outside; with Ctrl to snap angle; " +"with Shift to scale/rotate" +msgstr "" + +#: ../../po/../src/object-edit.cpp:1006 +msgid "Adjust the offset distance" +msgstr "" + +#. TRANSLATORS: This refers to the pattern that's inside the object +#: ../../po/../src/object-edit.cpp:1036 +msgid "Move the pattern fill inside the object" +msgstr "" + +#: ../../po/../src/object-edit.cpp:1038 +#, fuzzy +msgid "Scale the pattern fill uniformly" +msgstr "Выразае вылучаныя аб'екты ў буфэр абмену" + +#: ../../po/../src/object-edit.cpp:1040 +msgid "Rotate the pattern fill; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/object-edit.cpp:1065 +msgid "Drag to resize the flowed text frame" +msgstr "" + +#. Item dialog +#: ../../po/../src/object-ui.cpp:106 +#, fuzzy +msgid "Object _Properties" +msgstr "Уласьцівасьці прамакутніка" + +#. Select item +#: ../../po/../src/object-ui.cpp:116 +#, fuzzy +msgid "_Select This" +msgstr "Вылучыць гэта" + +#. Create link +#: ../../po/../src/object-ui.cpp:126 +#, fuzzy +msgid "_Create Link" +msgstr "Стварыць лучыва" + +#. "Ungroup" +#: ../../po/../src/object-ui.cpp:199 ../../po/../src/verbs.cpp:1931 +#, fuzzy +msgid "_Ungroup" +msgstr "Разгрупаваць" + +#. Link dialog +#: ../../po/../src/object-ui.cpp:239 +#, fuzzy +msgid "Link _Properties" +msgstr "Уласьцівасьці лучыва" + +#. Select item +#: ../../po/../src/object-ui.cpp:249 +#, fuzzy +msgid "_Follow Link" +msgstr "Прасачыць лучыва" + +#. Reset transformations +#: ../../po/../src/object-ui.cpp:254 +#, fuzzy +msgid "_Remove Link" +msgstr "Выдаліць лучыва" + +#. Link dialog +#: ../../po/../src/object-ui.cpp:303 +#, fuzzy +msgid "Image _Properties" +msgstr "Уласьцівасьці відарыса" + +#. Item dialog +#: ../../po/../src/object-ui.cpp:344 +#, fuzzy +msgid "_Fill and Stroke" +msgstr "Запаўненьне й штрыхоўка" + +#: ../../po/../src/path-chemistry.cpp:58 +#, fuzzy +msgid "Select at least two objects to combine." +msgstr "Вылучае ўсе аб'екты ў дакумэнце" + +#: ../../po/../src/path-chemistry.cpp:65 +#, fuzzy +msgid "At least one of the objects is not a path, cannot combine." +msgstr "Апускае вылучаныя аб'екты на ніжні слой" + +#: ../../po/../src/path-chemistry.cpp:73 +msgid "" +"You cannot combine objects from different groups or layers." +msgstr "" + +#: ../../po/../src/path-chemistry.cpp:155 +#, fuzzy +msgid "Select path(s) to break apart." +msgstr "Выразае вылучаныя аб'екты ў буфэр абмену" + +#: ../../po/../src/path-chemistry.cpp:231 +msgid "No path(s) to break apart in the selection." +msgstr "" + +#: ../../po/../src/path-chemistry.cpp:252 +#, fuzzy +msgid "Select object(s) to convert to path." +msgstr "Выразае вылучаныя аб'екты ў буфэр абмену" + +#: ../../po/../src/path-chemistry.cpp:297 +#, fuzzy +msgid "No objects to convert to path in the selection." +msgstr "Выразае вылучаныя аб'екты ў буфэр абмену" + +#: ../../po/../src/path-chemistry.cpp:345 +#, fuzzy +msgid "Select path(s) to reverse." +msgstr "Падымае вылучаныя аб'екты на верхні слой" + +#: ../../po/../src/path-chemistry.cpp:370 +msgid "No paths to reverse in the selection." +msgstr "" + +#: ../../po/../src/pen-context.cpp:379 ../../po/../src/pencil-context.cpp:233 +#, fuzzy +msgid "Continuing selected path" +msgstr "Апускае вылучаныя аб'екты на ніжні слой" + +#: ../../po/../src/pen-context.cpp:390 ../../po/../src/pencil-context.cpp:242 +#, fuzzy +msgid "Creating new path" +msgstr "Стварае новы дакумэнт SVG" + +#: ../../po/../src/pen-context.cpp:394 ../../po/../src/pencil-context.cpp:246 +#, fuzzy +msgid "Appending to selected path" +msgstr "Апускае вылучаныя аб'екты на ніжні слой" + +#: ../../po/../src/pen-context.cpp:538 +msgid "Click or click and drag to close and finish the path." +msgstr "" + +#: ../../po/../src/pen-context.cpp:548 +msgid "" +"Click or click and drag to continue the path from this point." +msgstr "" + +#: ../../po/../src/pen-context.cpp:857 +#, c-format +msgid "" +"%s: angle %3.2f°, distance %s; with Ctrl to snap angle, " +"Enter to finish the path" +msgstr "" + +#: ../../po/../src/pen-context.cpp:882 +#, c-format +msgid "" +"Curve handle: angle %3.2f°, length %s; with Ctrl to snap " +"angle" +msgstr "" + +#: ../../po/../src/pen-context.cpp:912 +#, c-format +msgid "" +"%s: angle %3.2f°, length %s; with Ctrl to snap angle, " +"with Shift to move this handle only" +msgstr "" + +#: ../../po/../src/pen-context.cpp:946 +#, fuzzy +msgid "Finishing pen" +msgstr "Вольная рыса" + +#: ../../po/../src/pencil-context.cpp:320 +msgid "Release here to close and finish the path." +msgstr "" + +#: ../../po/../src/pencil-context.cpp:326 +#, fuzzy +msgid "Drawing a freehand path" +msgstr "Інструмэнт алоўка - рысуе вольныя дугі й простыя рысы" + +#: ../../po/../src/pencil-context.cpp:331 +msgid "Drag to continue the path from this point." +msgstr "" + +#. Write curves to object +#: ../../po/../src/pencil-context.cpp:390 +#, fuzzy +msgid "Finishing freehand" +msgstr "Вольная рыса" + +#: ../../po/../src/rect-context.cpp:387 +msgid "" +"Ctrl: make square or integer-ratio rect, lock a rounded corner " +"circular" +msgstr "" + +#: ../../po/../src/rect-context.cpp:549 +#, c-format +msgid "" +"Rectangle: %s × %s; with Ctrl to make square or integer-" +"ratio rectangle; with Shift to draw around the starting point" +msgstr "" + +#: ../../po/../src/select-context.cpp:243 +#, fuzzy +msgid "Move canceled." +msgstr "Вылучэньне" + +#: ../../po/../src/select-context.cpp:252 +#, fuzzy +msgid "Selection canceled." +msgstr "Вылучэньне" + +#: ../../po/../src/select-context.cpp:642 +msgid "Ctrl: select in groups, move hor/vert" +msgstr "" + +#: ../../po/../src/select-context.cpp:643 +msgid "Shift: toggle select, force rubberband, disable snapping" +msgstr "" + +#: ../../po/../src/select-context.cpp:644 +msgid "Alt: select under, move selected" +msgstr "" + +#: ../../po/../src/select-context.cpp:798 +#, fuzzy +msgid "Selected object is not a group. Cannot enter." +msgstr "Апускае вылучаныя аб'екты на ніжні слой" + +#: ../../po/../src/select-context.cpp:876 +#, c-format +msgid "" +"Move by %s, %s; with Ctrl to restrict to horizontal/vertical; " +"with Shift to disable snapping" +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:228 +msgid "Nothing was deleted." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:259 +#, fuzzy +msgid "Select object(s) to duplicate." +msgstr "Выразае вылучаныя аб'екты ў буфэр абмену" + +#: ../../po/../src/selection-chemistry.cpp:420 +#, fuzzy +msgid "Select two or more objects to group." +msgstr "Падымае вылучаныя аб'екты на верхні слой" + +#: ../../po/../src/selection-chemistry.cpp:428 +#, fuzzy +msgid "Select at least two objects to group." +msgstr "Вылучае ўсе аб'екты ў дакумэнце" + +#: ../../po/../src/selection-chemistry.cpp:513 +#, fuzzy +msgid "Select a group to ungroup." +msgstr "Падымае вылучаныя аб'екты на верхні слой" + +#: ../../po/../src/selection-chemistry.cpp:554 +msgid "No groups to ungroup in the selection." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:623 +#, fuzzy +msgid "Select objects to raise." +msgstr "Выразае вылучаныя аб'екты ў буфэр абмену" + +#: ../../po/../src/selection-chemistry.cpp:629 +#: ../../po/../src/selection-chemistry.cpp:681 +#: ../../po/../src/selection-chemistry.cpp:715 +#: ../../po/../src/selection-chemistry.cpp:773 +msgid "" +"You cannot raise/lower objects from different groups or layers." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:673 +#, fuzzy +msgid "Select object(s) to raise to top." +msgstr "Апускае вылучаныя аб'екты на ніжні слой" + +#: ../../po/../src/selection-chemistry.cpp:709 +#, fuzzy +msgid "Select object(s) to lower." +msgstr "Выразае вылучаныя аб'екты ў буфэр абмену" + +#: ../../po/../src/selection-chemistry.cpp:765 +#, fuzzy +msgid "Select object(s) to lower to bottom." +msgstr "Выразае вылучаныя аб'екты ў буфэр абмену" + +#: ../../po/../src/selection-chemistry.cpp:806 +msgid "Nothing to undo." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:813 +msgid "Nothing to redo." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:969 +msgid "Nothing was copied." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1051 +msgid "Current layer is hidden. Unhide it to be able to paste to it." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1055 +msgid "Current layer is locked. Unlock it to be able to paste to it." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1068 +#: ../../po/../src/selection-chemistry.cpp:1103 +#, fuzzy +msgid "Nothing on the clipboard." +msgstr "Капуе вылучаныя аб'екты ў буфэр абмену" + +#: ../../po/../src/selection-chemistry.cpp:1109 +#, fuzzy +msgid "Select object(s) to paste style to." +msgstr "Апускае вылучаныя аб'екты на ніжні слой" + +#: ../../po/../src/selection-chemistry.cpp:1128 +#, fuzzy +msgid "Select object(s) to move to the layer above." +msgstr "Выразае вылучаныя аб'екты ў буфэр абмену" + +#: ../../po/../src/selection-chemistry.cpp:1146 +#, fuzzy +msgid "No more layers above." +msgstr "Назва дакумэнта:" + +#: ../../po/../src/selection-chemistry.cpp:1160 +#, fuzzy +msgid "Select object(s) to move to the layer below." +msgstr "Выразае вылучаныя аб'екты ў буфэр абмену" + +#: ../../po/../src/selection-chemistry.cpp:1178 +#, fuzzy +msgid "No more layers below." +msgstr "Назва дакумэнта:" + +#: ../../po/../src/selection-chemistry.cpp:1811 +#, fuzzy +msgid "Select a clone to unlink." +msgstr "Выбярыце файл для адкрыцьця" + +#: ../../po/../src/selection-chemistry.cpp:1842 +msgid "No clones to unlink in the selection." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1859 +msgid "" +"Select a clone to go to its original. Select a linked offset " +"to go to its source. Select a text on path to go to the path. Select " +"a flowed text to go to its frame." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1882 +msgid "" +"Cannot find the object to select (orphaned clone, offset, textpath, " +"flowed text?)" +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1888 +msgid "" +"The object you're trying to select is not visible (it is in <" +"defs>)" +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1915 +#, fuzzy +msgid "Select object(s) to convert to pattern." +msgstr "Выразае вылучаныя аб'екты ў буфэр абмену" + +#: ../../po/../src/selection-chemistry.cpp:2006 +#, fuzzy +msgid "Select an object with pattern fill to extract objects from." +msgstr "Выразае вылучаныя аб'екты ў буфэр абмену" + +#: ../../po/../src/selection-chemistry.cpp:2059 +#, fuzzy +msgid "No pattern fills in the selection." +msgstr "Выразае вылучаныя аб'екты ў буфэр абмену" + +#: ../../po/../src/selection-chemistry.cpp:2079 +#, fuzzy +msgid "Select object(s) to make a bitmap copy." +msgstr "Апускае вылучаныя аб'екты на ніжні слой" + +#: ../../po/../src/selection-describer.cpp:37 +msgid "Click selection to toggle scale/rotation handles" +msgstr "" + +#. no items +#: ../../po/../src/selection-describer.cpp:39 +msgid "" +"No objects selected. Click, Shift+click, or drag around objects to select." +msgstr "" + +#: ../../po/../src/selection-describer.cpp:51 +#, fuzzy, c-format +msgid " in layer %s" +msgstr "Падняць вузел" + +#: ../../po/../src/selection-describer.cpp:54 +#, fuzzy, c-format +msgid " in layer %s" +msgstr "Падняць вузел" + +#: ../../po/../src/selection-describer.cpp:66 +msgid "Use Shift+D to look up original" +msgstr "" + +#: ../../po/../src/selection-describer.cpp:70 +msgid "Use Shift+D to look up path" +msgstr "" + +#: ../../po/../src/selection-describer.cpp:74 +msgid "Use Shift+D to look up frame" +msgstr "" + +#: ../../po/../src/selection-describer.cpp:84 +#, fuzzy, c-format +msgid "%i object selected" +msgid_plural "%i objects selected" +msgstr[0] "Далучае рысы да вылучаных вузлоў" +msgstr[1] "Далучае рысы да вылучаных вузлоў" + +#: ../../po/../src/selection-describer.cpp:90 +#, c-format +msgid "%s%s. %s." +msgstr "" + +#: ../../po/../src/selection-describer.cpp:94 +#, fuzzy, c-format +msgid "%s in %i layer. %s." +msgid_plural "%s in %i layers. %s." +msgstr[0] "Далучае рысы да вылучаных вузлоў" +msgstr[1] "Далучае рысы да вылучаных вузлоў" + +#: ../../po/../src/seltrans.cpp:498 +msgid "" +"Center of rotation and skewing: drag to reposition; scaling with " +"Shift also uses this center" +msgstr "" + +#: ../../po/../src/seltrans.cpp:514 +msgid "" +"Squeeze or stretch selection; with Ctrl to scale uniformly; " +"with Shift to scale around rotation center" +msgstr "" + +#: ../../po/../src/seltrans.cpp:515 +msgid "" +"Scale selection; with Ctrl to scale uniformly; with Shift to scale around rotation center" +msgstr "" + +#: ../../po/../src/seltrans.cpp:519 +msgid "" +"Skew selection; with Ctrl to snap angle; with Shift to " +"skew around the opposite side" +msgstr "" + +#: ../../po/../src/seltrans.cpp:520 +msgid "" +"Rotate selection; with Ctrl to snap angle; with Shift " +"to rotate around the opposite corner" +msgstr "" + +#: ../../po/../src/seltrans.cpp:829 ../../po/../src/seltrans.cpp:909 +#, c-format +msgid "Scale: %0.2f%% x %0.2f%%; with Ctrl to lock ratio" +msgstr "" + +#. TRANSLATORS: don't modify the first ";" (it will NOT be displayed as ";" - only the second one will be) +#: ../../po/../src/seltrans.cpp:984 +#, c-format +msgid "Skew: %0.2f°; with Ctrl to snap angle" +msgstr "" + +#. TRANSLATORS: don't modify the first ";" (it will NOT be displayed as ";" - only the second one will be) +#: ../../po/../src/seltrans.cpp:1035 +#, c-format +msgid "Rotate: %0.2f°; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/seltrans.cpp:1090 +#, fuzzy, c-format +msgid "Move center to %s, %s" +msgstr "Злучыць з %s" + +#: ../../po/../src/slideshow.cpp:90 +#, fuzzy +msgid "Inkscape slideshow" +msgstr "Слайдшоў Sodipodi" + +#: ../../po/../src/sp-anchor.cpp:181 +#, fuzzy, c-format +msgid "Link to %s" +msgstr "Злучыць з %s" + +#: ../../po/../src/sp-anchor.cpp:185 +#, fuzzy +msgid "Link without URI" +msgstr "Злучыць з %s" + +#: ../../po/../src/sp-ellipse.cpp:438 ../../po/../src/sp-ellipse.cpp:870 +#, fuzzy +msgid "Ellipse" +msgstr "Эліпс" + +#: ../../po/../src/sp-ellipse.cpp:583 +msgid "Circle" +msgstr "" + +#: ../../po/../src/sp-ellipse.cpp:865 +#, fuzzy +msgid "Segment" +msgstr "Эліпс" + +#: ../../po/../src/sp-ellipse.cpp:867 +msgid "Arc" +msgstr "" + +#. TRANSLATORS: "Flow region" is an area where text is allowed to flow +#: ../../po/../src/sp-flowregion.cpp:276 +#, fuzzy +msgid "Flow region" +msgstr "Прасачыць лучыва" + +#. TRANSLATORS: A region "cut out of" a flow region; text is not allowed to flow inside the +#. * flow excluded region. flowRegionExclude in SVG 1.2: see +#. * http://www.w3.org/TR/2004/WD-SVG12-20041027/flow.html#flowRegion-elem and +#. * http://www.w3.org/TR/2004/WD-SVG12-20041027/flow.html#flowRegionExclude-elem. +#: ../../po/../src/sp-flowregion.cpp:493 +msgid "Flow excluded region" +msgstr "" + +#: ../../po/../src/sp-flowtext.cpp:355 +#, c-format +msgid "Flowed text (%d characters)" +msgstr "" + +#: ../../po/../src/sp-flowtext.cpp:357 +#, c-format +msgid "Linked flowed text (%d characters)" +msgstr "" + +#: ../../po/../src/sp-guide.cpp:290 +#, fuzzy +msgid "vertical guideline" +msgstr "Адлюстраваць вэртыкальна" + +#: ../../po/../src/sp-guide.cpp:292 +#, fuzzy +msgid "horizontal guideline" +msgstr "Адлюстраваць гарызантальна" + +#: ../../po/../src/sp-image.cpp:835 +msgid "embedded" +msgstr "" + +#: ../../po/../src/sp-image.cpp:839 +msgid "(null_pointer)" +msgstr "" + +#: ../../po/../src/sp-image.cpp:843 +#, fuzzy, c-format +msgid "Image with bad reference: %s" +msgstr "Відарыс з кепскай спасылкай: %s" + +#: ../../po/../src/sp-image.cpp:844 +#, fuzzy, c-format +msgid "Image %d × %d: %s" +msgstr "Каляровы відарыс %d x %d: %s" + +#: ../../po/../src/sp-item-group.cpp:390 +#, fuzzy, c-format +msgid "Group of %d object" +msgid_plural "Group of %d objects" +msgstr[0] "Група з %d аб'ектаў" +msgstr[1] "Група з %d аб'ектаў" + +#: ../../po/../src/sp-item.cpp:720 +msgid "Object" +msgstr "Аб'ект" + +#: ../../po/../src/sp-line.cpp:202 +#, fuzzy +msgid "Line" +msgstr "Эліпс" + +#. TRANSLATORS COMMENT: %s is either "outset" or "inset" depending on sign +#: ../../po/../src/sp-offset.cpp:433 +#, c-format +msgid "Linked offset, %s by %f pt" +msgstr "" + +#: ../../po/../src/sp-offset.cpp:434 ../../po/../src/sp-offset.cpp:438 +#, fuzzy +msgid "outset" +msgstr "Другі вылучаны" + +#: ../../po/../src/sp-offset.cpp:434 ../../po/../src/sp-offset.cpp:438 +#, fuzzy +msgid "inset" +msgstr "Друкаваць" + +#. TRANSLATORS COMMENT: %s is either "outset" or "inset" depending on sign +#: ../../po/../src/sp-offset.cpp:437 +#, c-format +msgid "Dynamic offset, %s by %f pt" +msgstr "" + +#: ../../po/../src/sp-path.cpp:127 +#, fuzzy, c-format +msgid "Path (%i node)" +msgid_plural "Path (%i nodes)" +msgstr[0] "Злучыць з %s" +msgstr[1] "Злучыць з %s" + +#: ../../po/../src/sp-polygon.cpp:216 +#, fuzzy +msgid "Polygon" +msgstr "Эліпс" + +#: ../../po/../src/sp-polyline.cpp:179 +#, fuzzy +msgid "Polyline" +msgstr "Эліпс" + +#: ../../po/../src/sp-rect.cpp:250 +#, fuzzy +msgid "Rectangle" +msgstr "Прамакутнік" + +#. TRANSLATORS: since turn count isn't an integer, please adjust the +#. string as needed to deal with an localized plural forms. +#: ../../po/../src/sp-spiral.cpp:305 +#, c-format +msgid "Spiral with %3f turns" +msgstr "" + +#: ../../po/../src/sp-star.cpp:288 +#, c-format +msgid "Star with %d vertex" +msgid_plural "Star with %d vertices" +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/sp-star.cpp:292 +#, c-format +msgid "Polygon with %d vertex" +msgid_plural "Polygon with %d vertices" +msgstr[0] "" +msgstr[1] "" + +#. TRANSLATORS: For description of font with no name. +#: ../../po/../src/sp-text.cpp:420 +msgid "<no name found>" +msgstr "" + +#: ../../po/../src/sp-text.cpp:426 +#, fuzzy, c-format +msgid "Text on path (%s, %s)" +msgstr "Злучыць з %s" + +#: ../../po/../src/sp-text.cpp:427 +#, fuzzy, c-format +msgid "Text (%s, %s)" +msgstr "Злучыць з %s" + +#. TRANSLATORS: Used for statusbar description for long chains: +#. * "Clone of: Clone of: ... in Layer 1". +#: ../../po/../src/sp-use.cpp:317 +#, fuzzy +msgid "..." +msgstr "Адкрыць..." + +#: ../../po/../src/sp-use.cpp:325 +#, fuzzy, c-format +msgid "Clone of: %s" +msgstr "Злучыць з %s" + +#: ../../po/../src/sp-use.cpp:329 +msgid "Orphaned clone" +msgstr "" + +#: ../../po/../src/spiral-context.cpp:355 +msgid "Ctrl: snap angle" +msgstr "" + +#: ../../po/../src/spiral-context.cpp:357 +msgid "Alt: lock spiral radius" +msgstr "" + +#: ../../po/../src/spiral-context.cpp:469 +#, c-format +msgid "" +"Spiral: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/splivarot.cpp:106 +#, fuzzy +msgid "Select at least 2 paths to perform a boolean operation." +msgstr "Вылучае ўсе аб'екты ў дакумэнце" + +#: ../../po/../src/splivarot.cpp:112 +msgid "" +"Select exactly 2 paths to perform difference, XOR, division, or path " +"cut." +msgstr "" + +#: ../../po/../src/splivarot.cpp:129 ../../po/../src/splivarot.cpp:144 +msgid "" +"Unable to determine the z-order of the objects selected for " +"difference, XOR, division, or path cut." +msgstr "" + +#: ../../po/../src/splivarot.cpp:174 +#, fuzzy +msgid "" +"One of the objects is not a path, cannot perform boolean operation." +msgstr "Апускае вылучаныя аб'екты на ніжні слой" + +#. TRANSLATORS: "to outline" means "to convert stroke to path" +#: ../../po/../src/splivarot.cpp:554 +#, fuzzy +msgid "Select path(s) to outline." +msgstr "Выразае вылучаныя аб'екты ў буфэр абмену" + +#. TRANSLATORS: "to outline" means "to convert stroke to path" +#: ../../po/../src/splivarot.cpp:748 +msgid "No stroked paths to outline in the selection." +msgstr "" + +#: ../../po/../src/splivarot.cpp:832 +#, fuzzy +msgid "Selected object is not a path, cannot inset/outset." +msgstr "Апускае вылучаныя аб'екты на ніжні слой" + +#: ../../po/../src/splivarot.cpp:1040 +#, fuzzy +msgid "Select path(s) to inset/outset." +msgstr "Выразае вылучаныя аб'екты ў буфэр абмену" + +#: ../../po/../src/splivarot.cpp:1257 +msgid "No paths to inset/outset in the selection." +msgstr "" + +#: ../../po/../src/splivarot.cpp:1390 +#, fuzzy +msgid "Select path(s) to simplify." +msgstr "Выразае вылучаныя аб'екты ў буфэр абмену" + +#: ../../po/../src/splivarot.cpp:1417 +msgid "No paths to simplify in the selection." +msgstr "" + +#: ../../po/../src/star-context.cpp:362 +msgid "Ctrl: snap angle; keep rays radial" +msgstr "" + +#: ../../po/../src/star-context.cpp:470 +#, c-format +msgid "" +"Polygon: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/star-context.cpp:471 +#, c-format +msgid "Star: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/text-chemistry.cpp:90 +#, fuzzy +msgid "Select a text and a path to put text on path." +msgstr "Вылучае ўсе аб'екты ў дакумэнце" + +#: ../../po/../src/text-chemistry.cpp:95 +msgid "" +"This text object is already put to a path. Remove it from the path " +"first. Use Shift+D to look up its path." +msgstr "" + +#. rect is the only SPShape which is not yet, and thus SVG forbids us from putting text on it +#: ../../po/../src/text-chemistry.cpp:101 +msgid "" +"You cannot put text on a rectangle in this version. Convert rectangle to " +"path first." +msgstr "" + +#: ../../po/../src/text-chemistry.cpp:159 +#, fuzzy +msgid "Select a text on path to remove it from path." +msgstr "Вылучае ўсе аб'екты ў дакумэнце" + +#: ../../po/../src/text-chemistry.cpp:181 +#, fuzzy +msgid "No texts-on-paths in the selection." +msgstr "Выразае вылучаныя аб'екты ў буфэр абмену" + +#: ../../po/../src/text-chemistry.cpp:209 +#: ../../po/../src/text-chemistry.cpp:229 +#, fuzzy +msgid "Select text(s) to remove kerns from." +msgstr "Падымае вылучаныя аб'екты на верхні слой" + +#: ../../po/../src/text-chemistry.cpp:250 +#, fuzzy +msgid "" +"Select a text and one or more paths or shapes to flow text " +"into frame." +msgstr "Вылучае ўсе аб'екты ў дакумэнце" + +#: ../../po/../src/text-chemistry.cpp:322 +#, fuzzy +msgid "Select a flowed text to unflow it." +msgstr "Выразае вылучаныя аб'екты ў буфэр абмену" + +#: ../../po/../src/text-context.cpp:463 +msgid "Click to edit the text, drag to select part of the text." +msgstr "" + +#: ../../po/../src/text-context.cpp:465 +msgid "" +"Click to edit the flowed text, drag to select part of the text." +msgstr "" + +#: ../../po/../src/text-context.cpp:540 +msgid "Non-printable character" +msgstr "" + +#: ../../po/../src/text-context.cpp:589 +#, fuzzy, c-format +msgid "Unicode: %s: %s" +msgstr "Sodipodi: %s: %s: %d" + +#: ../../po/../src/text-context.cpp:591 ../../po/../src/text-context.cpp:855 +msgid "Unicode: " +msgstr "" + +#: ../../po/../src/text-context.cpp:615 +msgid "Current layer is hidden. Unhide it to be able to add text." +msgstr "" + +#: ../../po/../src/text-context.cpp:619 +msgid "Current layer is locked. Unlock it to be able to add text." +msgstr "" + +#: ../../po/../src/text-context.cpp:673 +#, c-format +msgid "Flowed text frame: %s × %s" +msgstr "" + +#: ../../po/../src/text-context.cpp:708 ../../po/../src/text-context.cpp:1464 +msgid "Type text; Enter to start new line." +msgstr "" + +#: ../../po/../src/text-context.cpp:719 +msgid "Flowed text is created." +msgstr "" + +#: ../../po/../src/text-context.cpp:722 +msgid "" +"The frame is too small for the current font size. Flowed text not " +"created." +msgstr "" + +#: ../../po/../src/text-context.cpp:841 +msgid "No-break space" +msgstr "" + +#: ../../po/../src/text-context.cpp:1462 +msgid "Type flowed text; Enter to start new paragraph." +msgstr "" + +#: ../../po/../src/text-context.cpp:1472 ../../po/../src/tools-switch.cpp:189 +msgid "" +"Click to select or create text, drag to create flowed text; " +"then type." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:141 +msgid "" +"To edit a path, click, Shift+click, or drag around " +"nodes to select them, then drag nodes and handles. Click on an " +"object to select." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:147 +#, fuzzy +msgid "" +"Drag to create a rectangle. Drag controls to round corners and " +"resize. Click to select." +msgstr "" +"Інструмэнт прамакутніка - стварае прамакутнікі й квадраты з магчымымі " +"закругленымі кутамі" + +#: ../../po/../src/tools-switch.cpp:153 +msgid "" +"Drag to create an ellipse. Drag controls to make an arc or " +"segment. Click to select." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:159 +msgid "" +"Drag to create a star. Drag controls to edit the star shape. " +"Click to select." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:165 +msgid "" +"Drag to create a spiral. Drag controls to edit the spiral " +"shape. Click to select." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:171 +#, fuzzy +msgid "" +"Drag to create a freehand line. Start drawing with Shift to " +"append to selected path." +msgstr "" +"Стварае новую дугу. Націсьніце '+' каб пераключыцца паміж \"Дадаць\" і " +"\"Стварыць\"." + +#: ../../po/../src/tools-switch.cpp:177 +#, fuzzy +msgid "" +"Click or click and drag to start a path; with Shift to " +"append to selected path." +msgstr "" +"Стварае новую дугу. Націсьніце '+' каб пераключыцца паміж \"Дадаць\" і " +"\"Стварыць\"." + +#: ../../po/../src/tools-switch.cpp:183 +msgid "" +"Drag to paint a calligraphic stroke. Left/right arrow " +"keys adjust width, up/down adjust angle." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:195 +#, fuzzy +msgid "" +"Drag or double click to create a gradient on selected objects, " +"drag handles to adjust gradients." +msgstr "" +"Стварае новую дугу. Націсьніце '+' каб пераключыцца паміж \"Дадаць\" і " +"\"Стварыць\"." + +#: ../../po/../src/tools-switch.cpp:201 +msgid "" +"Click or drag around an area to zoom in, Shift+click to " +"zoom out." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:213 +msgid "Click and drag between shapes to create a connector." +msgstr "" + +#: ../../po/../src/trace/potrace/inkscape-potrace.cpp:553 +#: ../../po/../src/trace/potrace/inkscape-potrace.cpp:654 +#, c-format +msgid "Trace: %d. %ld nodes" +msgstr "" + +#: ../../po/../src/trace/trace.cpp:53 ../../po/../src/trace/trace.cpp:62 +#: ../../po/../src/trace/trace.cpp:70 +#, fuzzy +msgid "Select an image to trace" +msgstr "Выразае вылучаныя аб'екты ў буфэр абмену" + +#: ../../po/../src/trace/trace.cpp:133 +#, fuzzy +msgid "Trace: No active document" +msgstr "Стварае новы дакумэнт SVG" + +#: ../../po/../src/trace/trace.cpp:154 +msgid "Trace: Image has no bitmap data" +msgstr "" + +#: ../../po/../src/trace/trace.cpp:267 +#, fuzzy, c-format +msgid "Trace: Done. %ld nodes created" +msgstr "Другі вылучаны" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:59 ../../po/../src/verbs.cpp:2212 +msgid "About Inkscape" +msgstr "" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:66 +msgid "_Splash" +msgstr "" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:68 +msgid "_Authors" +msgstr "" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:69 +#, fuzzy +msgid "_Translators" +msgstr "Трансфармаваньне:" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:70 +#, fuzzy +msgid "_License" +msgstr "Злучыць" + +#. TRANSLATORS: This is the filename of the `About Inkscape' picture in +#. the `screens' directory. Thus the translation of "about.svg" should be +#. the filename of its translated version, e.g. about.zh.svg for Chinese. +#. +#. N.B. about.svg changes once per release. (We should probably rename +#. the original to about-0.40.svg etc. as soon as we have a translation. +#. If we do so, then add an item to release-checklist saying that the +#. string here should be changed.) +#. FIXME? INKSCAPE_SCREENSDIR and "about.svg" are in UTF-8, not the +#. native filename encoding... and the filename passed to sp_document_new +#. should be in UTF-*8.. +#: ../../po/../src/ui/dialog/aboutbox.cpp:114 +msgid "about.svg" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:464 +msgid "Minimum horizontal gap (in px units) between bounding boxes" +msgstr "" + +#. TRANSLATORS: Horizontal gap +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:466 +#: ../../po/../src/widgets/toolbox.cpp:1556 +msgid "H:" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:474 +msgid "Minimum vertical gap (in px units) between bounding boxes" +msgstr "" + +#. TRANSLATORS: Vertical gap +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:476 +msgid "V:" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:734 +msgid "Align" +msgstr "Раўнаньне" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:735 +msgid "Distribute" +msgstr "Прадастаўленьне" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:736 +msgid "Remove overlaps" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:737 +msgid "Nodes" +msgstr "Вузлы" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:742 +#, fuzzy +msgid "Relative to: " +msgstr "Адноснае перамяшчэньне" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:747 +#, fuzzy +msgid "Align right sides of objects to left side of anchor" +msgstr "Правы бок аб'екта ў левы бок якара" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:750 +#, fuzzy +msgid "Align left sides" +msgstr "Раўнае аб'екты" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:753 +#, fuzzy +msgid "Center on vertical axis" +msgstr "Цэнтраваць па вэртыкалі" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:756 +#, fuzzy +msgid "Align right sides" +msgstr "Раўнае аб'екты" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:759 +#, fuzzy +msgid "Align left sides of objects to right side of anchor" +msgstr "Левы бок аб'екта ў правы бок якара" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:762 +#, fuzzy +msgid "Align bottoms of objects to top of anchor" +msgstr "Ніз аб'екта ў верх якара" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:765 +#, fuzzy +msgid "Align tops" +msgstr "Раўнае аб'екты" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:768 +#, fuzzy +msgid "Center on horizontal axis" +msgstr "Цэнтраваць па гарызанталі" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:771 +#, fuzzy +msgid "Align bottoms" +msgstr "Раўнае аб'екты" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:774 +#, fuzzy +msgid "Align tops of objects to bottom of anchor" +msgstr "Верх аб'екта ў верх якара" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:779 +#, fuzzy +msgid "Align baseline anchors of texts vertically" +msgstr "Адлюстроўвае вылучаныя аб'екты вэртыкальна" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:782 +#, fuzzy +msgid "Align baseline anchors of texts horizontally" +msgstr "Адлюстроўвае вылучаны аб'ект гарызантальна" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:787 +#, fuzzy +msgid "Make horizontal gaps between objects equal" +msgstr "Прадастаўляе гарызантальную адлегласьць між аднолькавымі аб'ектамі" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:791 +#, fuzzy +msgid "Distribute left sides equidistantly" +msgstr "Адлюстроўвае вылучаныя аб'екты вэртыкальна" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:794 +#, fuzzy +msgid "Distribute centers equidistantly horizontally" +msgstr "Адлюстроўвае вылучаны аб'ект гарызантальна" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:797 +#, fuzzy +msgid "Distribute right sides equidistantly" +msgstr "Адлюстроўвае вылучаныя аб'екты вэртыкальна" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:801 +#, fuzzy +msgid "Make vertical gaps between objects equal" +msgstr "Прадастаўляе гарызантальную адлегласьць між аднолькавымі аб'ектамі" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:805 +#, fuzzy +msgid "Distribute tops equidistantly" +msgstr "Адлюстроўвае вылучаныя аб'екты вэртыкальна" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:808 +#, fuzzy +msgid "Distribute centers equidistantly vertically" +msgstr "Адлюстроўвае вылучаныя аб'екты вэртыкальна" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:811 +msgid "Distribute bottoms equidistantly" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:816 +#, fuzzy +msgid "Distribute baseline anchors of texts horizontally" +msgstr "Адлюстроўвае вылучаны аб'ект гарызантальна" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:819 +#, fuzzy +msgid "Distribute baseline anchors of texts vertically" +msgstr "Адлюстроўвае вылучаныя аб'екты вэртыкальна" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:824 +msgid "Randomize centers in both dimensions" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:827 +msgid "Unclump objects: try to equalize edge-to-edge distances" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:832 +msgid "" +"Move objects as little as possible so that their bounding boxes do not " +"overlap" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:837 +#, fuzzy +msgid "Align selected nodes horizontally" +msgstr "Адлюстроўвае вылучаны аб'ект гарызантальна" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:840 +#, fuzzy +msgid "Align selected nodes vertically" +msgstr "Адлюстроўвае вылучаныя аб'екты вэртыкальна" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:843 +#, fuzzy +msgid "Distribute selected nodes horizontally" +msgstr "Адлюстроўвае вылучаны аб'ект гарызантальна" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:846 +#, fuzzy +msgid "Distribute selected nodes vertically" +msgstr "Адлюстроўвае вылучаныя аб'екты вэртыкальна" + +#. Rest of the widgetry +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:851 +msgid "Last selected" +msgstr "Другі вылучаны" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:852 +msgid "First selected" +msgstr "Першы вылучаны" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:853 +msgid "Biggest item" +msgstr "Большы элемэнт" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:854 +msgid "Smallest item" +msgstr "Меншы элемэнт" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:856 +#: ../../po/../src/widgets/desktop-widget.cpp:1065 +msgid "Drawing" +msgstr "Рысаваньне" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:91 +msgid "Metadata 1" +msgstr "" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:92 +msgid "Metadata 2" +msgstr "" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:187 +#, fuzzy +msgid "X coordinate of grid origin" +msgstr "Крок па Ð¥:" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:189 +#, fuzzy +msgid "Y coordinate of grid origin" +msgstr "Крок па Ð¥:" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:191 +#, fuzzy +msgid "Distance of vertical grid lines" +msgstr "Адлюстраваць вэртыкальна" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:193 +#, fuzzy +msgid "Distance of horizontal grid lines" +msgstr "Адлюстраваць гарызантальна" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:197 +msgid "Max. snapping distance from grid" +msgstr "" + +#: ../../po/../src/ui/dialog/export.cpp:34 +msgid "Export" +msgstr "Экспартаваць" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:36 +msgid "Fill" +msgstr "Запаўненьне" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:37 +#, fuzzy +msgid "Stroke Paint" +msgstr "Няма рафарбоўкі" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:38 +#, fuzzy +msgid "Stroke Style" +msgstr "Наладкі штрыхоўкі" + +#: ../../po/../src/ui/dialog/find.cpp:34 +#, fuzzy +msgid "Find" +msgstr "Сетка" + +#: ../../po/../src/ui/dialog/memory.cpp:96 +msgid "Heap" +msgstr "" + +#: ../../po/../src/ui/dialog/memory.cpp:97 +#, fuzzy +msgid "In Use" +msgstr "Друкаваць" + +#. TRANSLATORS: "Slack" refers to memory which is in the heap but currently unused. +#. More typical usage is to call this memory "free" rather than "slack". +#: ../../po/../src/ui/dialog/memory.cpp:100 +#, fuzzy +msgid "Slack" +msgstr "Зорка" + +#: ../../po/../src/ui/dialog/memory.cpp:101 +#, fuzzy +msgid "Total" +msgstr "Назва:" + +#: ../../po/../src/ui/dialog/memory.cpp:141 +#: ../../po/../src/ui/dialog/memory.cpp:147 +#: ../../po/../src/ui/dialog/memory.cpp:154 +#: ../../po/../src/ui/dialog/memory.cpp:186 +msgid "Unknown" +msgstr "Невядома" + +#: ../../po/../src/ui/dialog/memory.cpp:167 +#, fuzzy +msgid "Combined" +msgstr "Камбінаваць" + +#: ../../po/../src/ui/dialog/memory.cpp:209 +#, fuzzy +msgid "Recalculate" +msgstr "Прамакутнік" + +#: ../../po/../src/ui/dialog/messages.cpp:74 +#, fuzzy +msgid "Ready." +msgstr "Чырвоны:" + +#: ../../po/../src/ui/dialog/messages.cpp:75 +msgid "" +"Enable log display by setting dialogs.debug 'redirect' attribute to 1 in " +"preferences.xml" +msgstr "" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:184 +msgid "_Execute Python" +msgstr "" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:186 +msgid "_Execute Perl" +msgstr "" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:195 +msgid "Script" +msgstr "" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:205 +#, fuzzy +msgid "Output" +msgstr "-" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:215 +msgid "Errors" +msgstr "" + +#. Dialog organization +#: ../../po/../src/ui/dialog/session-player.cpp:73 +#, fuzzy +msgid "Session file" +msgstr "Захаваць файл" + +#: ../../po/../src/ui/dialog/session-player.cpp:74 +#, fuzzy +msgid "Playback controls" +msgstr "Выбары інструмэнта" + +#: ../../po/../src/ui/dialog/session-player.cpp:75 +#, fuzzy +msgid "Message information" +msgstr "Скінуць трансфармацыю" + +#. Active session file display +#. fixme: Does this mean the active file for the session, or the file for the active session? +#. Please indicate which with a TRANSLATORS comment. +#: ../../po/../src/ui/dialog/session-player.cpp:85 +msgid "Active session file:" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:86 +msgid "Delay (milliseconds):" +msgstr "" + +#. Unload/load buttons +#: ../../po/../src/ui/dialog/session-player.cpp:94 +#, fuzzy +msgid "Close file" +msgstr "Закрыць" + +#: ../../po/../src/ui/dialog/session-player.cpp:95 +msgid "Open new file" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:96 +#, fuzzy +msgid "Set delay" +msgstr "Усталяваць як дапомнае" + +#: ../../po/../src/ui/dialog/session-player.cpp:138 +#, fuzzy +msgid "Rewind" +msgstr "Чырвоны:" + +#: ../../po/../src/ui/dialog/session-player.cpp:139 +msgid "Go back one change" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:140 +#, fuzzy +msgid "Pause" +msgstr "Уставіць" + +#: ../../po/../src/ui/dialog/session-player.cpp:141 +msgid "Go forward one change" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:142 +msgid "Play" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:177 +#: ../../po/../src/verbs.cpp:1573 +msgid "Open session file" +msgstr "" + +#. ##Set up the Potrace panel +#. #### brightness #### +#. #### Multiple scanning#### +#. ----Hbox1 +#: ../../po/../src/ui/dialog/tracedialog.cpp:345 +#: ../../po/../src/ui/dialog/tracedialog.cpp:428 +#, fuzzy +msgid "Brightness" +msgstr "Вышыня:" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:348 +msgid "Trace by a given brightness level" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:355 +msgid "Brightness cutoff for black/white" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:362 +#, fuzzy +msgid "Image Brightness" +msgstr "Уласьцівасьці відарыса" + +#. #### canny edge detection #### +#. TRANSLATORS: "Canny" is the name of the inventor of this edge detection method +#: ../../po/../src/ui/dialog/tracedialog.cpp:369 +msgid "Optimal Edge Detection (Canny)" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:372 +msgid "Trace with edge detection by J. Canny's algorithm" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:388 +msgid "Brightness cutoff for adjacent pixels (determines edge thickness)" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:395 +#, fuzzy +msgid "Edge Detection" +msgstr "Вылучэньне" + +#. #### quantization #### +#. TRANSLATORS: Color Quantization: the process of reducing the number of colors +#. in an image by selecting an optimized set of representative colors and then +#. re-applying this reduced set to the original image. +#: ../../po/../src/ui/dialog/tracedialog.cpp:404 +#, fuzzy +msgid "Color Quantization" +msgstr "Фарбаваць" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:407 +msgid "Trace along the boundaries of reduced colors" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:414 +msgid "The number of reduced colors" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:416 +#, fuzzy +msgid "Colors:" +msgstr "Закрыць" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:421 +msgid "Quantization / Reduction" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:431 +msgid "Trace the given number of brightness levels" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:438 +#, fuzzy +msgid "Scans:" +msgstr "Фармаваньне" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:440 +msgid "The desired number of scans" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:448 +msgid "Trace the given number of reduced colors" +msgstr "" + +#. ---Hbox3 +#: ../../po/../src/ui/dialog/tracedialog.cpp:454 +msgid "Monochrome" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:457 +msgid "Same as Color, but convert result to grayscale" +msgstr "" + +#. TRANSLATORS: "Stack" is a verb here +#: ../../po/../src/ui/dialog/tracedialog.cpp:460 +#, fuzzy +msgid "Stack" +msgstr "Зорка" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:463 +msgid "" +"Stack scans vertically (no gaps) or tile horizontally (usually with gaps)" +msgstr "" + +#. TRANSLATORS: "Smooth" is a verb here +#: ../../po/../src/ui/dialog/tracedialog.cpp:466 +msgid "Smooth" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:469 +msgid "Apply Gaussian blur to the bitmap before tracing" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:473 +msgid "Multiple Scanning" +msgstr "" + +#. #### Preview #### +#: ../../po/../src/ui/dialog/tracedialog.cpp:479 +#: ../../po/../src/ui/dialog/tracedialog.cpp:489 +#, fuzzy +msgid "Preview" +msgstr "Стварыць папярэдні прагляд" + +#. do not expand +#: ../../po/../src/ui/dialog/tracedialog.cpp:483 +msgid "Preview the result without actual tracing" +msgstr "" + +#. #### swap black and white #### +#: ../../po/../src/ui/dialog/tracedialog.cpp:495 +msgid "Invert" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:499 +msgid "Invert black and white regions for single traces" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:503 +msgid "Thanks to Peter Selinger, http://potrace.sourceforge.net" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:506 +#, fuzzy +msgid "Credits" +msgstr "Куты:" + +#. done +#. TRANSLATORS: Potrace is an application for transforming bitmaps into +#. vector graphics (http://potrace.sourceforge.net/) +#: ../../po/../src/ui/dialog/tracedialog.cpp:514 +#, fuzzy +msgid "Potrace" +msgstr "Трасыраваць" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:527 +#, fuzzy +msgid "Abort a trace in progress" +msgstr "Прастора экспартаваньня" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:531 +msgid "Execute the trace" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:80 +#: ../../po/../src/ui/dialog/transformation.cpp:90 +#, fuzzy +msgid "_Horizontal" +msgstr "Адлюстраваць гарызантальна" + +#: ../../po/../src/ui/dialog/transformation.cpp:80 +msgid "Horizontal displacement (relative) or position (absolute)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:82 +#: ../../po/../src/ui/dialog/transformation.cpp:92 +#, fuzzy +msgid "_Vertical" +msgstr "Адлюстраваць вэртыкальна" + +#: ../../po/../src/ui/dialog/transformation.cpp:82 +msgid "Vertical displacement (relative) or position (absolute)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:84 +#, fuzzy +msgid "_Width" +msgstr "Шырыня:" + +#: ../../po/../src/ui/dialog/transformation.cpp:84 +msgid "Horizontal size increment (absolute or percentage)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:86 +#, fuzzy +msgid "_Height" +msgstr "Вышыня:" + +#: ../../po/../src/ui/dialog/transformation.cpp:86 +msgid "Vertical size increment (absolute or percentage)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:88 +#, fuzzy +msgid "A_ngle" +msgstr "Кут" + +#: ../../po/../src/ui/dialog/transformation.cpp:88 +#, fuzzy +msgid "Rotation angle (positive = counterclockwise)" +msgstr "Паварочвае аб'ект на 90° па сонцу" + +#: ../../po/../src/ui/dialog/transformation.cpp:90 +msgid "" +"Horizontal skew angle (positive = counterclockwise), or absolute " +"displacement, or percentage displacement" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:92 +msgid "" +"Vertical skew angle (positive = counterclockwise), or absolute displacement, " +"or percentage displacement" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:95 +#, fuzzy +msgid "Transformation matrix element A" +msgstr "Матрыца трансфармаваньня" + +#: ../../po/../src/ui/dialog/transformation.cpp:96 +#, fuzzy +msgid "Transformation matrix element B" +msgstr "Матрыца трансфармаваньня" + +#: ../../po/../src/ui/dialog/transformation.cpp:97 +#, fuzzy +msgid "Transformation matrix element C" +msgstr "Матрыца трансфармаваньня" + +#: ../../po/../src/ui/dialog/transformation.cpp:98 +#, fuzzy +msgid "Transformation matrix element D" +msgstr "Матрыца трансфармаваньня" + +#: ../../po/../src/ui/dialog/transformation.cpp:99 +#, fuzzy +msgid "Transformation matrix element E" +msgstr "Матрыца трансфармаваньня" + +#: ../../po/../src/ui/dialog/transformation.cpp:100 +#, fuzzy +msgid "Transformation matrix element F" +msgstr "Матрыца трансфармаваньня" + +#: ../../po/../src/ui/dialog/transformation.cpp:102 +#, fuzzy +msgid "Rela_tive move" +msgstr "Адноснае перамяшчэньне" + +#: ../../po/../src/ui/dialog/transformation.cpp:102 +msgid "" +"Add the specified relative displacement to the current position; otherwise, " +"edit the current absolute position directly" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:103 +msgid "Scale proportionally" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:103 +msgid "Preserve the width/height ratio of the scaled objects" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:104 +msgid "Apply to each _object separately" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:104 +msgid "" +"Apply the scale/rotate/skew to each selected object separately; otherwise, " +"transform the selection as a whole" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:105 +msgid "Edit c_urrent matrix" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:105 +msgid "" +"Edit the current transform= matrix; otherwise, post-multiply transform= by " +"this matrix" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:115 +#, fuzzy +msgid "_Move" +msgstr "Перанесьці" + +#: ../../po/../src/ui/dialog/transformation.cpp:118 +#, fuzzy +msgid "_Scale" +msgstr "Маштаб" + +#: ../../po/../src/ui/dialog/transformation.cpp:121 +#, fuzzy +msgid "_Rotate" +msgstr "Павярнуць" + +#: ../../po/../src/ui/dialog/transformation.cpp:124 +#, fuzzy +msgid "Ske_w" +msgstr "Няма рафарбоўкі" + +#: ../../po/../src/ui/dialog/transformation.cpp:127 +msgid "Matri_x" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:141 +msgid "Reset the values on the current tab to defaults" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:148 +#, fuzzy +msgid "Apply transformation to selection" +msgstr "Інструмэнт вылучэньня - вылучае й трансфармуе аб'екты" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:43 +msgid "_Use SSL" +msgstr "" + +#. Construct dialog interface +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:68 +#, fuzzy +msgid "_Server:" +msgstr "Фільтары" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:69 +#, fuzzy +msgid "_Username:" +msgstr "Файл" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:70 +msgid "_Password:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:71 +msgid "P_ort:" +msgstr "" + +#. Buttons +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:99 +#, fuzzy +msgid "Connect" +msgstr "Закрыць" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:126 +msgid "Establishing connection to Jabber server %1 as user %2" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:131 +msgid "Failed to establish connection to Jabber server %1" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:136 +msgid "Authentication failed on Jabber server %1 as %2" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:141 +msgid "SSL initialization failed when connecting to Jabber server %1" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:147 +msgid "Connected to Jabber server %1 as %2" +msgstr "" + +#. Construct labels +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:75 +msgid "Chatroom _name:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:76 +msgid "Chatroom _server:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:77 +msgid "Chatroom _password:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:78 +msgid "Chatroom _handle:" +msgstr "" + +#. Button setup and callback registration +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:97 +msgid "Connect to chatroom" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:132 +msgid "Synchronizing with chatroom %1@%2 using the handle %3" +msgstr "" + +#. Construct dialog interface +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:78 +msgid "_User's Jabber ID:" +msgstr "" + +#. Buttons +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:82 +msgid "_Invite user" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:83 +#, fuzzy +msgid "_Cancel" +msgstr "Адмяніць" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:94 +msgid "Buddy List" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:170 +msgid "Sending whiteboard invitation to %1" +msgstr "" + +#. FIXME: strings are replaced by placeholders, NOT to be translated until the code is enabled +#. See http://sourceforge.net/mailarchive/message.php?msg_id=11746016 for details +#. File menu +#. Edit menu +#. View menu +#. Layer menu +#. Object menu +#. Path menu +#. add(Gtk::StockItem(CLEANUP, _("PLACEHOLDER, do not translate"))); (using Gtk::Stock::CLEAR) +#. Text menu +#. About menu +#. Tools toolbox +#. Select Tool controls +#. Node Tool controls +#. Calligraphy Tool controls +#. Session playback controls +#: ../../po/../src/ui/stock-items.cpp:34 ../../po/../src/ui/stock-items.cpp:35 +#: ../../po/../src/ui/stock-items.cpp:36 ../../po/../src/ui/stock-items.cpp:37 +#: ../../po/../src/ui/stock-items.cpp:38 ../../po/../src/ui/stock-items.cpp:39 +#: ../../po/../src/ui/stock-items.cpp:40 ../../po/../src/ui/stock-items.cpp:41 +#: ../../po/../src/ui/stock-items.cpp:42 ../../po/../src/ui/stock-items.cpp:43 +#: ../../po/../src/ui/stock-items.cpp:46 ../../po/../src/ui/stock-items.cpp:47 +#: ../../po/../src/ui/stock-items.cpp:48 ../../po/../src/ui/stock-items.cpp:49 +#: ../../po/../src/ui/stock-items.cpp:50 ../../po/../src/ui/stock-items.cpp:51 +#: ../../po/../src/ui/stock-items.cpp:52 ../../po/../src/ui/stock-items.cpp:53 +#: ../../po/../src/ui/stock-items.cpp:54 ../../po/../src/ui/stock-items.cpp:55 +#: ../../po/../src/ui/stock-items.cpp:56 ../../po/../src/ui/stock-items.cpp:57 +#: ../../po/../src/ui/stock-items.cpp:58 ../../po/../src/ui/stock-items.cpp:59 +#: ../../po/../src/ui/stock-items.cpp:62 ../../po/../src/ui/stock-items.cpp:63 +#: ../../po/../src/ui/stock-items.cpp:64 ../../po/../src/ui/stock-items.cpp:65 +#: ../../po/../src/ui/stock-items.cpp:66 ../../po/../src/ui/stock-items.cpp:67 +#: ../../po/../src/ui/stock-items.cpp:68 ../../po/../src/ui/stock-items.cpp:69 +#: ../../po/../src/ui/stock-items.cpp:70 ../../po/../src/ui/stock-items.cpp:71 +#: ../../po/../src/ui/stock-items.cpp:72 ../../po/../src/ui/stock-items.cpp:73 +#: ../../po/../src/ui/stock-items.cpp:74 ../../po/../src/ui/stock-items.cpp:75 +#: ../../po/../src/ui/stock-items.cpp:76 ../../po/../src/ui/stock-items.cpp:77 +#: ../../po/../src/ui/stock-items.cpp:78 ../../po/../src/ui/stock-items.cpp:79 +#: ../../po/../src/ui/stock-items.cpp:80 ../../po/../src/ui/stock-items.cpp:81 +#: ../../po/../src/ui/stock-items.cpp:82 ../../po/../src/ui/stock-items.cpp:83 +#: ../../po/../src/ui/stock-items.cpp:84 ../../po/../src/ui/stock-items.cpp:85 +#: ../../po/../src/ui/stock-items.cpp:86 ../../po/../src/ui/stock-items.cpp:87 +#: ../../po/../src/ui/stock-items.cpp:88 ../../po/../src/ui/stock-items.cpp:89 +#: ../../po/../src/ui/stock-items.cpp:92 ../../po/../src/ui/stock-items.cpp:93 +#: ../../po/../src/ui/stock-items.cpp:94 ../../po/../src/ui/stock-items.cpp:95 +#: ../../po/../src/ui/stock-items.cpp:96 ../../po/../src/ui/stock-items.cpp:97 +#: ../../po/../src/ui/stock-items.cpp:98 ../../po/../src/ui/stock-items.cpp:99 +#: ../../po/../src/ui/stock-items.cpp:100 +#: ../../po/../src/ui/stock-items.cpp:101 +#: ../../po/../src/ui/stock-items.cpp:102 +#: ../../po/../src/ui/stock-items.cpp:103 +#: ../../po/../src/ui/stock-items.cpp:104 +#: ../../po/../src/ui/stock-items.cpp:105 +#: ../../po/../src/ui/stock-items.cpp:108 +#: ../../po/../src/ui/stock-items.cpp:109 +#: ../../po/../src/ui/stock-items.cpp:110 +#: ../../po/../src/ui/stock-items.cpp:111 +#: ../../po/../src/ui/stock-items.cpp:112 +#: ../../po/../src/ui/stock-items.cpp:113 +#: ../../po/../src/ui/stock-items.cpp:114 +#: ../../po/../src/ui/stock-items.cpp:115 +#: ../../po/../src/ui/stock-items.cpp:116 +#: ../../po/../src/ui/stock-items.cpp:117 +#: ../../po/../src/ui/stock-items.cpp:118 +#: ../../po/../src/ui/stock-items.cpp:119 +#: ../../po/../src/ui/stock-items.cpp:120 +#: ../../po/../src/ui/stock-items.cpp:121 +#: ../../po/../src/ui/stock-items.cpp:122 +#: ../../po/../src/ui/stock-items.cpp:123 +#: ../../po/../src/ui/stock-items.cpp:124 +#: ../../po/../src/ui/stock-items.cpp:125 +#: ../../po/../src/ui/stock-items.cpp:126 +#: ../../po/../src/ui/stock-items.cpp:127 +#: ../../po/../src/ui/stock-items.cpp:130 +#: ../../po/../src/ui/stock-items.cpp:131 +#: ../../po/../src/ui/stock-items.cpp:132 +#: ../../po/../src/ui/stock-items.cpp:133 +#: ../../po/../src/ui/stock-items.cpp:134 +#: ../../po/../src/ui/stock-items.cpp:135 +#: ../../po/../src/ui/stock-items.cpp:136 +#: ../../po/../src/ui/stock-items.cpp:137 +#: ../../po/../src/ui/stock-items.cpp:138 +#: ../../po/../src/ui/stock-items.cpp:139 +#: ../../po/../src/ui/stock-items.cpp:140 +#: ../../po/../src/ui/stock-items.cpp:141 +#: ../../po/../src/ui/stock-items.cpp:142 +#: ../../po/../src/ui/stock-items.cpp:143 +#: ../../po/../src/ui/stock-items.cpp:144 +#: ../../po/../src/ui/stock-items.cpp:145 +#: ../../po/../src/ui/stock-items.cpp:146 +#: ../../po/../src/ui/stock-items.cpp:150 +#: ../../po/../src/ui/stock-items.cpp:151 +#: ../../po/../src/ui/stock-items.cpp:152 +#: ../../po/../src/ui/stock-items.cpp:153 +#: ../../po/../src/ui/stock-items.cpp:156 +#: ../../po/../src/ui/stock-items.cpp:157 +#: ../../po/../src/ui/stock-items.cpp:158 +#: ../../po/../src/ui/stock-items.cpp:161 +#: ../../po/../src/ui/stock-items.cpp:162 +#: ../../po/../src/ui/stock-items.cpp:163 +#: ../../po/../src/ui/stock-items.cpp:164 +#: ../../po/../src/ui/stock-items.cpp:165 +#: ../../po/../src/ui/stock-items.cpp:166 +#: ../../po/../src/ui/stock-items.cpp:167 +#: ../../po/../src/ui/stock-items.cpp:168 +#: ../../po/../src/ui/stock-items.cpp:169 +#: ../../po/../src/ui/stock-items.cpp:170 +#: ../../po/../src/ui/stock-items.cpp:171 +#: ../../po/../src/ui/stock-items.cpp:172 +#: ../../po/../src/ui/stock-items.cpp:175 +#: ../../po/../src/ui/stock-items.cpp:176 +#: ../../po/../src/ui/stock-items.cpp:177 +#: ../../po/../src/ui/stock-items.cpp:178 +#: ../../po/../src/ui/stock-items.cpp:181 +#: ../../po/../src/ui/stock-items.cpp:182 +#: ../../po/../src/ui/stock-items.cpp:183 +#: ../../po/../src/ui/stock-items.cpp:184 +#: ../../po/../src/ui/stock-items.cpp:185 +#: ../../po/../src/ui/stock-items.cpp:186 +#: ../../po/../src/ui/stock-items.cpp:187 +#: ../../po/../src/ui/stock-items.cpp:188 +#: ../../po/../src/ui/stock-items.cpp:189 +#: ../../po/../src/ui/stock-items.cpp:190 +#: ../../po/../src/ui/stock-items.cpp:191 +#: ../../po/../src/ui/stock-items.cpp:194 +#: ../../po/../src/ui/stock-items.cpp:195 +#: ../../po/../src/ui/stock-items.cpp:198 +#: ../../po/../src/ui/stock-items.cpp:199 +#: ../../po/../src/ui/stock-items.cpp:200 +#: ../../po/../src/ui/stock-items.cpp:201 +#: ../../po/../src/ui/stock-items.cpp:202 +msgid "PLACEHOLDER, do not translate" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:88 +msgid "small" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:89 +msgid "medium" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:90 +#, fuzzy +msgid "large" +msgstr "Мэта:" + +#: ../../po/../src/ui/widget/panel.cpp:91 +msgid "huge" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:106 +#, fuzzy +msgid "List" +msgstr "Друкаваць" + +#: ../../po/../src/ui/widget/selected-style.cpp:67 +msgid "F:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:68 +msgid "S:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:69 +msgid "O:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:95 +msgid "N/A" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:98 +#: ../../po/../src/ui/widget/selected-style.cpp:712 +#, fuzzy +msgid "Nothing selected" +msgstr "Выдаляе вылучаныя аб'екты" + +#: ../../po/../src/ui/widget/selected-style.cpp:103 +msgid "No fill" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:103 +#, fuzzy +msgid "No stroke" +msgstr "Няма рафарбоўкі" + +#: ../../po/../src/ui/widget/selected-style.cpp:105 +#: ../../po/../src/widgets/paint-selector.cpp:190 +#, fuzzy +msgid "Pattern" +msgstr "Узор:" + +#: ../../po/../src/ui/widget/selected-style.cpp:108 +#: ../../po/../src/widgets/paint-selector.cpp:885 +#, fuzzy +msgid "Pattern fill" +msgstr "Узор:" + +#: ../../po/../src/ui/widget/selected-style.cpp:108 +#, fuzzy +msgid "Pattern stroke" +msgstr "Раўнае аб'ект" + +#: ../../po/../src/ui/widget/selected-style.cpp:110 +#, fuzzy +msgid "L Gradient" +msgstr "Вэктар градыента" + +#: ../../po/../src/ui/widget/selected-style.cpp:113 +#, fuzzy +msgid "Linear gradient fill" +msgstr "Лінэйны градыент" + +#: ../../po/../src/ui/widget/selected-style.cpp:113 +#, fuzzy +msgid "Linear gradient stroke" +msgstr "Лінэйны градыент" + +#: ../../po/../src/ui/widget/selected-style.cpp:115 +#, fuzzy +msgid "R Gradient" +msgstr "Вэктар градыента" + +#: ../../po/../src/ui/widget/selected-style.cpp:118 +#, fuzzy +msgid "Radial gradient fill" +msgstr "Кругавы градыент" + +#: ../../po/../src/ui/widget/selected-style.cpp:118 +#, fuzzy +msgid "Radial gradient stroke" +msgstr "Кругавы градыент" + +#: ../../po/../src/ui/widget/selected-style.cpp:120 +#, fuzzy +msgid "Different" +msgstr "Адсотка" + +#: ../../po/../src/ui/widget/selected-style.cpp:123 +msgid "Different fills" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:123 +msgid "Different strokes" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:125 +#, fuzzy +msgid "Unset" +msgstr "Друкаваць" + +#. TRANSLATORS COMMENT: unset is a verb here +#: ../../po/../src/ui/widget/selected-style.cpp:128 +#: ../../po/../src/ui/widget/selected-style.cpp:182 +#, fuzzy +msgid "Unset fill" +msgstr "Бяз назвы" + +#: ../../po/../src/ui/widget/selected-style.cpp:128 +#: ../../po/../src/ui/widget/selected-style.cpp:182 +msgid "Unset stroke" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:131 +#, fuzzy +msgid "Flat color fill" +msgstr "Канчатковы колер" + +#: ../../po/../src/ui/widget/selected-style.cpp:131 +#, fuzzy +msgid "Flat color stroke" +msgstr "Канчатковы колер" + +#. TRANSLATOR COMMENT: A means "Averaged" +#: ../../po/../src/ui/widget/selected-style.cpp:134 +msgid "A" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:137 +#, fuzzy +msgid "Fill is averaged over selected objects" +msgstr "Групуе вылучаныя аб'екты" + +#: ../../po/../src/ui/widget/selected-style.cpp:137 +#, fuzzy +msgid "Stroke is averaged over selected objects" +msgstr "Групуе вылучаныя аб'екты" + +#. TRANSLATOR COMMENT: M means "Multiple" +#: ../../po/../src/ui/widget/selected-style.cpp:140 +msgid "M" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:143 +#, fuzzy +msgid "Multiple selected objects have the same fill" +msgstr "Адлюстроўвае вылучаныя аб'екты вэртыкальна" + +#: ../../po/../src/ui/widget/selected-style.cpp:143 +#, fuzzy +msgid "Multiple selected objects have the same stroke" +msgstr "Адлюстроўвае вылучаныя аб'екты вэртыкальна" + +#: ../../po/../src/ui/widget/selected-style.cpp:145 +#, fuzzy +msgid "Edit fill..." +msgstr "Рэдагаваньне" + +#: ../../po/../src/ui/widget/selected-style.cpp:145 +#, fuzzy +msgid "Edit stroke..." +msgstr "Рэдагаваньне" + +#: ../../po/../src/ui/widget/selected-style.cpp:149 +#, fuzzy +msgid "Last set color" +msgstr "Канчатковы колер" + +#: ../../po/../src/ui/widget/selected-style.cpp:153 +#, fuzzy +msgid "Last selected color" +msgstr "Другі вылучаны" + +#: ../../po/../src/ui/widget/selected-style.cpp:157 +msgid "White" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:161 +#: ../../po/../src/widgets/sp-color-scales.cpp:461 +#: ../../po/../src/widgets/sp-color-scales.cpp:462 +#, fuzzy +msgid "Black" +msgstr "Чорны:" + +#: ../../po/../src/ui/widget/selected-style.cpp:165 +#, fuzzy +msgid "Copy color" +msgstr "Пачатковы колер" + +#: ../../po/../src/ui/widget/selected-style.cpp:169 +#, fuzzy +msgid "Paste color" +msgstr "Канчатковы колер" + +#: ../../po/../src/ui/widget/selected-style.cpp:173 +#, fuzzy +msgid "Swap fill and stroke" +msgstr "Запаўненьне й штрыхоўка" + +#: ../../po/../src/ui/widget/selected-style.cpp:177 +msgid "Make fill opaque" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:177 +msgid "Make stroke opaque" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:186 +#, fuzzy +msgid "Remove fill" +msgstr "Выдаліць лучыва" + +#: ../../po/../src/ui/widget/selected-style.cpp:186 +#, fuzzy +msgid "Remove stroke" +msgstr "Выдаліць лучыва" + +#: ../../po/../src/ui/widget/selected-style.cpp:718 +#, fuzzy +msgid "Master opacity" +msgstr "Зацямненьне:" + +#: ../../po/../src/ui/widget/selected-style.cpp:744 +msgid "0 (transparent)" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:768 +msgid "1.0 (opaque)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1046 +msgid "Moved to next layer." +msgstr "" + +#: ../../po/../src/verbs.cpp:1048 +msgid "Cannot move past last layer." +msgstr "" + +#: ../../po/../src/verbs.cpp:1057 +msgid "Moved to previous layer." +msgstr "" + +#: ../../po/../src/verbs.cpp:1059 +msgid "Cannot move past first layer." +msgstr "" + +#: ../../po/../src/verbs.cpp:1076 ../../po/../src/verbs.cpp:1150 +#, fuzzy +msgid "No current layer." +msgstr "Назва дакумэнта:" + +#: ../../po/../src/verbs.cpp:1105 +#, fuzzy, c-format +msgid "Raised layer %s." +msgstr "Падняць вузел" + +#: ../../po/../src/verbs.cpp:1109 +#, fuzzy, c-format +msgid "Lowered layer %s." +msgstr "Вылучэньне" + +#: ../../po/../src/verbs.cpp:1118 +msgid "Cannot move layer any further." +msgstr "" + +#. TRANSLATORS: this means "The layer has been deleted." +#: ../../po/../src/verbs.cpp:1148 +#, fuzzy +msgid "Deleted layer." +msgstr "Вылучэньне" + +#: ../../po/../src/verbs.cpp:1544 +msgid "" +"You need to connect to a Jabber server before sharing a document with " +"another user." +msgstr "" + +#: ../../po/../src/verbs.cpp:1559 +msgid "" +"You need to connect to a Jabber server before sharing a document with a " +"chatroom." +msgstr "" + +#: ../../po/../src/verbs.cpp:1569 +msgid "XML node tracker has not been initialized; nothing to dump" +msgstr "" + +#. TRANSLATORS: If you have translated the keys.svg file to your language, then +#. translate this string as "keys.LANG.svg" (where LANG is your language code); +#. otherwise leave as "keys.svg". +#: ../../po/../src/verbs.cpp:1631 +msgid "keys.svg" +msgstr "" + +#. TRANSLATORS: If you have translated the tutorial-basic.svg file to your language, +#. then translate this string as "tutorial-basic.LANG.svg" (where LANG is your language +#. code); otherwise leave as "tutorial-basic.svg". +#: ../../po/../src/verbs.cpp:1667 +msgid "tutorial-basic.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1671 +msgid "tutorial-shapes.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1675 +msgid "tutorial-advanced.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1679 +msgid "tutorial-tracing.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1683 +msgid "tutorial-calligraphy.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1687 +msgid "tutorial-elements.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1691 +msgid "tutorial-tips.svg" +msgstr "" + +#: ../../po/../src/verbs.cpp:1842 +msgid "Does nothing" +msgstr "Нічога" + +#. File +#: ../../po/../src/verbs.cpp:1845 +#, fuzzy +msgid "Default" +msgstr "Дапомнае" + +#: ../../po/../src/verbs.cpp:1845 +#, fuzzy +msgid "Create new document from default template" +msgstr "Стварае новы дакумэнт SVG" + +#: ../../po/../src/verbs.cpp:1847 +#, fuzzy +msgid "_Open..." +msgstr "Адкрыць..." + +#: ../../po/../src/verbs.cpp:1848 +#, fuzzy +msgid "Open existing document" +msgstr "Адкрывае існуючы дакумэнт SVG" + +#: ../../po/../src/verbs.cpp:1849 +msgid "Re_vert" +msgstr "" + +#: ../../po/../src/verbs.cpp:1850 +msgid "Revert to the last saved version of document (changes will be lost)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1851 +#, fuzzy +msgid "_Save" +msgstr "Захаваць" + +#: ../../po/../src/verbs.cpp:1851 +msgid "Save document" +msgstr "Захоўвае дакумэнт" + +#: ../../po/../src/verbs.cpp:1853 +#, fuzzy +msgid "Save _As..." +msgstr "Захаваць як" + +#: ../../po/../src/verbs.cpp:1854 +msgid "Save document under new name" +msgstr "Захоўвае дакумэнт пад новай назвай" + +#: ../../po/../src/verbs.cpp:1855 +#, fuzzy +msgid "_Print..." +msgstr "Друк..." + +#: ../../po/../src/verbs.cpp:1855 +msgid "Print document" +msgstr "Друкуе дакумэнт" + +#. TRANSLATORS: "Vacuum Defs" means "Clean up defs" (so as to remove unused definitions) +#: ../../po/../src/verbs.cpp:1858 +msgid "Vac_uum Defs" +msgstr "" + +#: ../../po/../src/verbs.cpp:1858 +msgid "Remove unused predefined items from the <defs> of the document" +msgstr "" + +#: ../../po/../src/verbs.cpp:1860 +#, fuzzy +msgid "Print _Direct" +msgstr "Друк наўпрост..." + +#: ../../po/../src/verbs.cpp:1861 +#, fuzzy +msgid "Print directly without prompting to a file or pipe" +msgstr "Друкуе наўпрост у файл ці канал" + +#: ../../po/../src/verbs.cpp:1862 +#, fuzzy +msgid "Print Previe_w" +msgstr "Перадпрагляд друку" + +#: ../../po/../src/verbs.cpp:1863 +msgid "Preview document printout" +msgstr "Папярэдні прагляд вываду дакумэнта на друк" + +#: ../../po/../src/verbs.cpp:1864 +#, fuzzy +msgid "_Import..." +msgstr "Імпартаваць" + +#: ../../po/../src/verbs.cpp:1865 +msgid "Import bitmap or SVG image into document" +msgstr "Імпартуе кропкавы ці SVG відарыс у дакумэнт" + +#: ../../po/../src/verbs.cpp:1866 +#, fuzzy +msgid "_Export Bitmap..." +msgstr "Экспартаваць кропкавы відарыс" + +#: ../../po/../src/verbs.cpp:1867 +#, fuzzy +msgid "Export document or selection as a bitmap image" +msgstr "Экспартуе дакумэнт як PNG відарыс" + +#: ../../po/../src/verbs.cpp:1868 +#, fuzzy +msgid "N_ext Window" +msgstr "Стварыць новае акно рэдагаваньня" + +#: ../../po/../src/verbs.cpp:1869 +msgid "Switch to the next document window" +msgstr "" + +#: ../../po/../src/verbs.cpp:1870 +#, fuzzy +msgid "P_revious Window" +msgstr "Стварыць новае акно рэдагаваньня" + +#: ../../po/../src/verbs.cpp:1871 +msgid "Switch to the previous document window" +msgstr "" + +#: ../../po/../src/verbs.cpp:1872 +#, fuzzy +msgid "_Close" +msgstr "Закрыць" + +#: ../../po/../src/verbs.cpp:1873 +#, fuzzy +msgid "Close window" +msgstr "Закрыць прагляд" + +#: ../../po/../src/verbs.cpp:1874 +msgid "_Quit" +msgstr "" + +#: ../../po/../src/verbs.cpp:1874 +#, fuzzy +msgid "Quit Inkscape" +msgstr "Слайдшоў Sodipodi" + +#. Edit +#: ../../po/../src/verbs.cpp:1877 +#, fuzzy +msgid "_Undo" +msgstr "Адкаціцца" + +#: ../../po/../src/verbs.cpp:1877 +#, fuzzy +msgid "Undo last action" +msgstr "Адмяняе апошняе дзеяньне" + +#: ../../po/../src/verbs.cpp:1879 +#, fuzzy +msgid "_Redo" +msgstr "Вярнуцца" + +#: ../../po/../src/verbs.cpp:1880 +#, fuzzy +msgid "Do again last undone action" +msgstr "Паўтарае незавершанае дзеяньне" + +#: ../../po/../src/verbs.cpp:1881 +#, fuzzy +msgid "Cu_t" +msgstr "Выразаць" + +#: ../../po/../src/verbs.cpp:1882 +#, fuzzy +msgid "Cut selection to clipboard" +msgstr "Выразае вылучаныя аб'екты ў буфэр абмену" + +#: ../../po/../src/verbs.cpp:1883 +#, fuzzy +msgid "_Copy" +msgstr "Капіяваць" + +#: ../../po/../src/verbs.cpp:1884 +#, fuzzy +msgid "Copy selection to clipboard" +msgstr "Капуе вылучаныя аб'екты ў буфэр абмену" + +#: ../../po/../src/verbs.cpp:1885 +#, fuzzy +msgid "_Paste" +msgstr "Уставіць" + +#: ../../po/../src/verbs.cpp:1886 +#, fuzzy +msgid "Paste objects from clipboard to mouse point" +msgstr "Устаўляе аб'екты з буфэра абмену" + +#: ../../po/../src/verbs.cpp:1887 +#, fuzzy +msgid "Paste _Style" +msgstr "Стыль штрыхоўкі" + +#: ../../po/../src/verbs.cpp:1888 +#, fuzzy +msgid "Apply style of the copied object to selection" +msgstr "Капуе вылучаныя аб'екты ў буфэр абмену" + +#: ../../po/../src/verbs.cpp:1889 +#, fuzzy +msgid "Paste _In Place" +msgstr "Стыль штрыхоўкі" + +#: ../../po/../src/verbs.cpp:1890 +#, fuzzy +msgid "Paste objects from clipboard to the original location" +msgstr "Падымае вылучаныя аб'екты на верхні слой" + +#: ../../po/../src/verbs.cpp:1891 +#, fuzzy +msgid "_Delete" +msgstr "Выдаліць" + +#: ../../po/../src/verbs.cpp:1892 +#, fuzzy +msgid "Delete selection" +msgstr "Выдаляе вылучаныя вузлы" + +#: ../../po/../src/verbs.cpp:1893 +#, fuzzy +msgid "Duplic_ate" +msgstr "Падвоіць" + +#: ../../po/../src/verbs.cpp:1894 +#, fuzzy +msgid "Duplicate selected objects" +msgstr "Падвойвае вылучаныя аб'екты" + +#: ../../po/../src/verbs.cpp:1895 +#, fuzzy +msgid "Clo_ne" +msgstr "Закрыць" + +#: ../../po/../src/verbs.cpp:1896 +msgid "Create a clone of selected object (a copy linked to the original)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1897 +msgid "Unlin_k Clone" +msgstr "" + +#: ../../po/../src/verbs.cpp:1898 +msgid "Cut the clone's link to its original" +msgstr "" + +#: ../../po/../src/verbs.cpp:1899 +#, fuzzy +msgid "Select _Original" +msgstr "Вылучыць усё" + +#: ../../po/../src/verbs.cpp:1900 +#, fuzzy +msgid "Select the object to which the clone is linked" +msgstr "Выразае вылучаныя аб'екты ў буфэр абмену" + +#. TRANSLATORS: Convert selection to a rectangle with tiled pattern fill +#: ../../po/../src/verbs.cpp:1902 +#, fuzzy +msgid "O_bjects to Pattern" +msgstr "Трансфармаваньне аб'екта" + +#: ../../po/../src/verbs.cpp:1903 +msgid "Convert selection to a rectangle with tiled pattern fill" +msgstr "" + +#. TRANSLATORS: Extract objects from a tiled pattern fill +#: ../../po/../src/verbs.cpp:1905 +#, fuzzy +msgid "Pattern to Ob_jects" +msgstr "Раўнае аб'ект" + +#: ../../po/../src/verbs.cpp:1906 +msgid "Extract objects from a tiled pattern fill" +msgstr "" + +#: ../../po/../src/verbs.cpp:1907 +#, fuzzy +msgid "Clea_r All" +msgstr "Ачысьціць усё" + +#: ../../po/../src/verbs.cpp:1908 +msgid "Delete all objects from document" +msgstr "Выдаляе ўсе аб'екты з дакумэнта" + +#: ../../po/../src/verbs.cpp:1909 +#, fuzzy +msgid "Select Al_l" +msgstr "Вылучыць усё" + +#: ../../po/../src/verbs.cpp:1910 +#, fuzzy +msgid "Select all objects or all nodes" +msgstr "Вылучае ўсе аб'екты ў дакумэнце" + +#: ../../po/../src/verbs.cpp:1911 +#, fuzzy +msgid "Select All in All La_yers" +msgstr "Вылучэньне" + +#: ../../po/../src/verbs.cpp:1912 +#, fuzzy +msgid "Select all objects in all visible and unlocked layers" +msgstr "Вылучае ўсе аб'екты ў дакумэнце" + +#: ../../po/../src/verbs.cpp:1913 +#, fuzzy +msgid "In_vert Selection" +msgstr "Вылучэньне" + +#: ../../po/../src/verbs.cpp:1914 +msgid "Invert selection (unselect what is selected and select everything else)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1915 +msgid "Invert in All Layers" +msgstr "" + +#: ../../po/../src/verbs.cpp:1916 +msgid "Invert selection in all visible and unlocked layers" +msgstr "" + +#: ../../po/../src/verbs.cpp:1917 +#, fuzzy +msgid "D_eselect" +msgstr "Вылучэньне" + +#: ../../po/../src/verbs.cpp:1918 +#, fuzzy +msgid "Deselect any selected objects or nodes" +msgstr "Выдаляе вылучаныя аб'екты" + +#. Selection +#: ../../po/../src/verbs.cpp:1921 +#, fuzzy +msgid "Raise to _Top" +msgstr "Падымае вылучаныя аб'екты на верхні слой" + +#: ../../po/../src/verbs.cpp:1922 +#, fuzzy +msgid "Raise selection to top" +msgstr "Падымае вылучаныя аб'екты на верхні слой" + +#: ../../po/../src/verbs.cpp:1923 +#, fuzzy +msgid "Lower to _Bottom" +msgstr "Апускае вылучаныя аб'екты на ніжні слой" + +#: ../../po/../src/verbs.cpp:1924 +#, fuzzy +msgid "Lower selection to bottom" +msgstr "Апускае вылучаныя аб'екты на ніжні слой" + +#: ../../po/../src/verbs.cpp:1925 +#, fuzzy +msgid "_Raise" +msgstr "Падняць" + +#: ../../po/../src/verbs.cpp:1926 +#, fuzzy +msgid "Raise selection one step" +msgstr "Падымае вылучаныя аб'екты на верхні слой" + +#: ../../po/../src/verbs.cpp:1927 +#, fuzzy +msgid "_Lower" +msgstr "Апусьціць" + +#: ../../po/../src/verbs.cpp:1928 +#, fuzzy +msgid "Lower selection one step" +msgstr "Апускае вылучаныя аб'екты на адзін узровень" + +#: ../../po/../src/verbs.cpp:1929 +#, fuzzy +msgid "_Group" +msgstr "Згрупаваць" + +#: ../../po/../src/verbs.cpp:1930 +msgid "Group selected objects" +msgstr "Групуе вылучаныя аб'екты" + +#: ../../po/../src/verbs.cpp:1932 +#, fuzzy +msgid "Ungroup selected groups" +msgstr "Разгрупоўвае вылучаныя аб'екты" + +#: ../../po/../src/verbs.cpp:1934 +#, fuzzy +msgid "_Put on Path" +msgstr "Апускае вылучаныя аб'екты на ніжні слой" + +#: ../../po/../src/verbs.cpp:1935 +#, fuzzy +msgid "Put text on path" +msgstr "Апускае вылучаныя аб'екты на ніжні слой" + +#: ../../po/../src/verbs.cpp:1936 +#, fuzzy +msgid "_Remove from Path" +msgstr "Выдаляе трансфармаваньні" + +#: ../../po/../src/verbs.cpp:1937 +#, fuzzy +msgid "Remove text from path" +msgstr "Апускае вылучаныя аб'екты на ніжні слой" + +#: ../../po/../src/verbs.cpp:1938 +msgid "Remove Manual _Kerns" +msgstr "" + +#. TRANSLATORS: "glyph": An image used in the visual representation of characters; +#. roughly speaking, how a character looks. A font is a set of glyphs. +#: ../../po/../src/verbs.cpp:1941 +#, fuzzy +msgid "Remove all manual kerns and glyph rotations from a text object" +msgstr "Выдаляе трансфармаваньне з аб'екта" + +#: ../../po/../src/verbs.cpp:1943 +#, fuzzy +msgid "_Union" +msgstr "Адкаціцца" + +#: ../../po/../src/verbs.cpp:1944 +#, fuzzy +msgid "Union of selected objects" +msgstr "Групуе вылучаныя аб'екты" + +#: ../../po/../src/verbs.cpp:1945 +#, fuzzy +msgid "_Intersection" +msgstr "Вылучэньне" + +#: ../../po/../src/verbs.cpp:1946 +#, fuzzy +msgid "Intersection of selected objects" +msgstr "Выдаляе вылучаныя аб'екты" + +#: ../../po/../src/verbs.cpp:1947 +msgid "_Difference" +msgstr "" + +#: ../../po/../src/verbs.cpp:1948 +#, fuzzy +msgid "Difference of selected objects (bottom minus top)" +msgstr "Выдаляе вылучаныя аб'екты" + +#: ../../po/../src/verbs.cpp:1949 +#, fuzzy +msgid "E_xclusion" +msgstr "Пашырэньне" + +#: ../../po/../src/verbs.cpp:1950 +#, fuzzy +msgid "Exclusive OR of selected objects" +msgstr "Выдаляе вылучаныя аб'екты" + +#: ../../po/../src/verbs.cpp:1951 +msgid "Di_vision" +msgstr "" + +#: ../../po/../src/verbs.cpp:1952 +msgid "Cut the bottom object into pieces" +msgstr "" + +#. TRANSLATORS: "to cut a path" is not the same as "to break a path apart" - see the +#. Advanced tutorial for more info +#: ../../po/../src/verbs.cpp:1955 +#, fuzzy +msgid "Cut _Path" +msgstr "Другі вылучаны" + +#: ../../po/../src/verbs.cpp:1956 +msgid "Cut the bottom object's stroke into pieces, removing fill" +msgstr "" + +#. TRANSLATORS: "outset": expand a shape by offsetting the object's path, +#. i.e. by displacing it perpendicular to the path in each point. +#. See also the Advanced Tutorial for explanation. +#: ../../po/../src/verbs.cpp:1960 +#, fuzzy +msgid "Outs_et" +msgstr "Другі вылучаны" + +#: ../../po/../src/verbs.cpp:1961 +#, fuzzy +msgid "Outset selected paths" +msgstr "Другі вылучаны" + +#: ../../po/../src/verbs.cpp:1963 +#, fuzzy +msgid "O_utset Path by 1 px" +msgstr "Другі вылучаны" + +#: ../../po/../src/verbs.cpp:1964 +#, fuzzy +msgid "Outset selected paths by 1 px" +msgstr "Другі вылучаны" + +#: ../../po/../src/verbs.cpp:1966 +#, fuzzy +msgid "O_utset Path by 10 px" +msgstr "Другі вылучаны" + +#: ../../po/../src/verbs.cpp:1967 +#, fuzzy +msgid "Outset selected paths by 10 px" +msgstr "Другі вылучаны" + +#. TRANSLATORS: "inset": contract a shape by offsetting the object's path, +#. i.e. by displacing it perpendicular to the path in each point. +#. See also the Advanced Tutorial for explanation. +#: ../../po/../src/verbs.cpp:1971 +msgid "I_nset" +msgstr "" + +#: ../../po/../src/verbs.cpp:1972 +#, fuzzy +msgid "Inset selected paths" +msgstr "Апускае вылучаныя аб'екты на ніжні слой" + +#: ../../po/../src/verbs.cpp:1974 +#, fuzzy +msgid "I_nset Path by 1 px" +msgstr "Другі вылучаны" + +#: ../../po/../src/verbs.cpp:1975 +#, fuzzy +msgid "Inset selected paths by 1 px" +msgstr "Апускае вылучаныя аб'екты на ніжні слой" + +#: ../../po/../src/verbs.cpp:1977 +#, fuzzy +msgid "I_nset Path by 10 px" +msgstr "Другі вылучаны" + +#: ../../po/../src/verbs.cpp:1978 +#, fuzzy +msgid "Inset selected paths by 10 px" +msgstr "Апускае вылучаныя аб'екты на ніжні слой" + +#: ../../po/../src/verbs.cpp:1980 +msgid "D_ynamic Offset" +msgstr "" + +#: ../../po/../src/verbs.cpp:1980 +#, fuzzy +msgid "Create a dynamic offset object" +msgstr "Інструмэнт тэкста - стварае і рэдагуе тэкставыя аб'екты" + +#: ../../po/../src/verbs.cpp:1982 +msgid "_Linked Offset" +msgstr "" + +#: ../../po/../src/verbs.cpp:1983 +msgid "Create a dynamic offset object linked to the original path" +msgstr "" + +#: ../../po/../src/verbs.cpp:1985 +#, fuzzy +msgid "_Stroke to Path" +msgstr "Рысаваньне штрыхоўкі" + +#: ../../po/../src/verbs.cpp:1986 +#, fuzzy +msgid "Convert selected strokes to paths" +msgstr "Апускае вылучаныя аб'екты на ніжні слой" + +#: ../../po/../src/verbs.cpp:1987 +msgid "Si_mplify" +msgstr "" + +#: ../../po/../src/verbs.cpp:1988 +msgid "Simplify selected paths by removing extra nodes" +msgstr "" + +#: ../../po/../src/verbs.cpp:1989 +#, fuzzy +msgid "_Reverse" +msgstr "Фільтары" + +#: ../../po/../src/verbs.cpp:1990 +#, fuzzy +msgid "Reverses the direction of selected paths; useful for flipping markers" +msgstr "Выдаляе вылучаныя аб'екты" + +#. TRANSLATORS: "to trace" means "to convert a bitmap to vector graphics" (to vectorize) +#: ../../po/../src/verbs.cpp:1992 +#, fuzzy +msgid "_Trace Bitmap" +msgstr "Друкаваць як кропкавы відарыс" + +#: ../../po/../src/verbs.cpp:1993 +#, fuzzy +msgid "Convert bitmap object to paths" +msgstr "Апускае вылучаныя аб'екты на ніжні слой" + +#: ../../po/../src/verbs.cpp:1994 +#, fuzzy +msgid "_Make a Bitmap Copy" +msgstr "Друкаваць як кропкавы відарыс" + +#: ../../po/../src/verbs.cpp:1995 +#, fuzzy +msgid "Export selection to a bitmap and insert it into document" +msgstr "Імпартуе кропкавы ці SVG відарыс у дакумэнт" + +#: ../../po/../src/verbs.cpp:1996 +#, fuzzy +msgid "_Combine" +msgstr "Камбінаваць" + +#: ../../po/../src/verbs.cpp:1997 +msgid "Combine several paths into one" +msgstr "" + +#. TRANSLATORS: "to cut a path" is not the same as "to break a path apart" - see the +#. Advanced tutorial for more info +#: ../../po/../src/verbs.cpp:2000 +#, fuzzy +msgid "Break _Apart" +msgstr "Адасобіць" + +#: ../../po/../src/verbs.cpp:2001 +#, fuzzy +msgid "Break selected paths into subpaths" +msgstr "Разлучае вылучаны шлях на падшляхі" + +#: ../../po/../src/verbs.cpp:2002 +msgid "Gri_d Arrange..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2003 +msgid "Arrange selection in grid pattern" +msgstr "" + +#. Layer +#: ../../po/../src/verbs.cpp:2005 +#, fuzzy +msgid "_Add Layer..." +msgstr "Апусьціць" + +#: ../../po/../src/verbs.cpp:2006 +#, fuzzy +msgid "Create a new layer" +msgstr "Стварае новы дакумэнт SVG" + +#: ../../po/../src/verbs.cpp:2007 +#, fuzzy +msgid "Re_name Layer..." +msgstr "Падняць вузел" + +#: ../../po/../src/verbs.cpp:2008 +#, fuzzy +msgid "Rename the current layer" +msgstr "Вылучэньне" + +#: ../../po/../src/verbs.cpp:2009 +#, fuzzy +msgid "Switch to Layer Abov_e" +msgstr "Апускае вылучаныя аб'екты на ніжні слой" + +#: ../../po/../src/verbs.cpp:2010 +msgid "Switch to the layer above the current" +msgstr "" + +#: ../../po/../src/verbs.cpp:2011 +#, fuzzy +msgid "Switch to Layer Belo_w" +msgstr "Апускае вылучаныя аб'екты на адзін узровень" + +#: ../../po/../src/verbs.cpp:2012 +msgid "Switch to the layer below the current" +msgstr "" + +#: ../../po/../src/verbs.cpp:2013 +#, fuzzy +msgid "Move Selection to Layer Abo_ve" +msgstr "Апускае вылучаныя аб'екты на ніжні слой" + +#: ../../po/../src/verbs.cpp:2014 +msgid "Move selection to the layer above the current" +msgstr "" + +#: ../../po/../src/verbs.cpp:2015 +#, fuzzy +msgid "Move Selection to Layer Bel_ow" +msgstr "Апускае вылучаныя аб'екты на адзін узровень" + +#: ../../po/../src/verbs.cpp:2016 +msgid "Move selection to the layer below the current" +msgstr "" + +#: ../../po/../src/verbs.cpp:2017 +#, fuzzy +msgid "Layer to _Top" +msgstr "Падымае вылучаныя аб'екты на верхні слой" + +#: ../../po/../src/verbs.cpp:2018 +#, fuzzy +msgid "Raise the current layer to the top" +msgstr "Падымае вылучаныя аб'екты на верхні слой" + +#: ../../po/../src/verbs.cpp:2019 +#, fuzzy +msgid "Layer to _Bottom" +msgstr "Апускае вылучаныя аб'екты на ніжні слой" + +#: ../../po/../src/verbs.cpp:2020 +#, fuzzy +msgid "Lower the current layer to the bottom" +msgstr "Апускае вылучаныя аб'екты на ніжні слой" + +#: ../../po/../src/verbs.cpp:2021 +#, fuzzy +msgid "_Raise Layer" +msgstr "Падняць вузел" + +#: ../../po/../src/verbs.cpp:2022 +msgid "Raise the current layer" +msgstr "" + +#: ../../po/../src/verbs.cpp:2023 +#, fuzzy +msgid "_Lower Layer" +msgstr "Апусьціць вузел" + +#: ../../po/../src/verbs.cpp:2024 +msgid "Lower the current layer" +msgstr "" + +#: ../../po/../src/verbs.cpp:2025 +#, fuzzy +msgid "_Delete Current Layer" +msgstr "Вылучэньне" + +#: ../../po/../src/verbs.cpp:2026 +#, fuzzy +msgid "Delete the current layer" +msgstr "Вылучэньне" + +#. Object +#: ../../po/../src/verbs.cpp:2029 +#, fuzzy +msgid "Rotate _90° CW" +msgstr "Павярнуць на 90°" + +#: ../../po/../src/verbs.cpp:2030 +#, fuzzy +msgid "Rotate selection 90° clockwise" +msgstr "Паварочвае аб'ект на 90° па сонцу" + +#: ../../po/../src/verbs.cpp:2031 +#, fuzzy +msgid "Rotate 9_0° CCW" +msgstr "Павярнуць на 90°" + +#: ../../po/../src/verbs.cpp:2032 +#, fuzzy +msgid "Rotate selection 90° counter-clockwise" +msgstr "Паварочвае аб'ект на 90° па сонцу" + +#: ../../po/../src/verbs.cpp:2033 +#, fuzzy +msgid "Remove _Transformations" +msgstr "Выдаляе трансфармаваньні" + +#: ../../po/../src/verbs.cpp:2034 +msgid "Remove transformations from object" +msgstr "Выдаляе трансфармаваньне з аб'екта" + +#: ../../po/../src/verbs.cpp:2035 +#, fuzzy +msgid "_Object to Path" +msgstr "Трансфармаваньне аб'екта" + +#: ../../po/../src/verbs.cpp:2036 +#, fuzzy +msgid "Convert selected objects to paths" +msgstr "Апускае вылучаныя аб'екты на ніжні слой" + +#: ../../po/../src/verbs.cpp:2037 +msgid "_Flow into Frame" +msgstr "" + +#: ../../po/../src/verbs.cpp:2038 +#, fuzzy +msgid "Put text into frames" +msgstr "Апускае вылучаныя аб'екты на ніжні слой" + +#: ../../po/../src/verbs.cpp:2039 +#, fuzzy +msgid "_Unflow" +msgstr "Адкаціцца" + +#: ../../po/../src/verbs.cpp:2040 +msgid "Remove text from frame (creates a single-line text object)" +msgstr "" + +#: ../../po/../src/verbs.cpp:2041 +#, fuzzy +msgid "_Convert to Text" +msgstr "Апускае вылучаныя аб'екты на ніжні слой" + +#: ../../po/../src/verbs.cpp:2042 +#, fuzzy +msgid "Convert flowed text to regular text objects (preserves appearance)" +msgstr "Апускае вылучаныя аб'екты на ніжні слой" + +#: ../../po/../src/verbs.cpp:2044 +#, fuzzy +msgid "Flip _Horizontal" +msgstr "Адлюстраваць гарызантальна" + +#: ../../po/../src/verbs.cpp:2044 +#, fuzzy +msgid "Flips selected objects horizontally" +msgstr "Адлюстроўвае вылучаны аб'ект гарызантальна" + +#: ../../po/../src/verbs.cpp:2047 +#, fuzzy +msgid "Flip _Vertical" +msgstr "Адлюстраваць вэртыкальна" + +#: ../../po/../src/verbs.cpp:2047 +#, fuzzy +msgid "Flips selected objects vertically" +msgstr "Адлюстроўвае вылучаныя аб'екты вэртыкальна" + +#. Tools +#: ../../po/../src/verbs.cpp:2051 +msgid "Select" +msgstr "Вылучэньне" + +#: ../../po/../src/verbs.cpp:2052 +#, fuzzy +msgid "Select and transform objects" +msgstr "Інструмэнт вылучэньня - вылучае й трансфармуе аб'екты" + +#: ../../po/../src/verbs.cpp:2053 +#, fuzzy +msgid "Node Edit" +msgstr "Рэдагаваць вузел" + +#: ../../po/../src/verbs.cpp:2054 +#, fuzzy +msgid "Edit path nodes or control handles" +msgstr "Падвойвае вылучаныя аб'екты" + +#: ../../po/../src/verbs.cpp:2056 +#, fuzzy +msgid "Create rectangles and squares" +msgstr "" +"Інструмэнт прамакутніка - стварае прамакутнікі й квадраты з магчымымі " +"закругленымі кутамі" + +#: ../../po/../src/verbs.cpp:2058 +#, fuzzy +msgid "Create circles, ellipses, and arcs" +msgstr "Інструмэнт дугі - стварае кругі, эліпсы й дугі" + +#: ../../po/../src/verbs.cpp:2060 +#, fuzzy +msgid "Create stars and polygons" +msgstr "Інструмэнт зоркі - стварае зоркі й палігоны" + +#: ../../po/../src/verbs.cpp:2062 +#, fuzzy +msgid "Create spirals" +msgstr "Стварыць лучыва" + +#: ../../po/../src/verbs.cpp:2064 +#, fuzzy +msgid "Draw freehand lines" +msgstr "Інструмэнт алоўка - рысуе вольныя дугі й простыя рысы" + +#: ../../po/../src/verbs.cpp:2066 +#, fuzzy +msgid "Draw Bezier curves and straight lines" +msgstr "Інструмэнт алоўка - рысуе вольныя дугі й простыя рысы" + +#: ../../po/../src/verbs.cpp:2068 +#, fuzzy +msgid "Draw calligraphic lines" +msgstr "Каліграфічная рыса" + +#: ../../po/../src/verbs.cpp:2070 +#, fuzzy +msgid "Create and edit text objects" +msgstr "Інструмэнт тэкста - стварае і рэдагуе тэкставыя аб'екты" + +#: ../../po/../src/verbs.cpp:2072 +#, fuzzy +msgid "Create and edit gradients" +msgstr "Інструмэнт тэкста - стварае і рэдагуе тэкставыя аб'екты" + +#: ../../po/../src/verbs.cpp:2074 +#, fuzzy +msgid "Zoom in or out" +msgstr "Памяншае маштаб рысунка" + +#: ../../po/../src/verbs.cpp:2076 +#, fuzzy +msgid "Pick averaged colors from image" +msgstr "Інструмэнт піпеткі - бярэ колер з відарыса" + +#: ../../po/../src/verbs.cpp:2078 +#, fuzzy +msgid "Create connectors" +msgstr "Стварае новы дакумэнт SVG" + +#. Tool prefs +#: ../../po/../src/verbs.cpp:2081 +msgid "Selector Preferences" +msgstr "" + +#: ../../po/../src/verbs.cpp:2082 +#, fuzzy +msgid "Open Preferences for the Selector tool" +msgstr "Слайдшоў Sodipodi" + +#: ../../po/../src/verbs.cpp:2083 +#, fuzzy +msgid "Node Tool Preferences" +msgstr "Перавагі адсутнага інструмэнта" + +#: ../../po/../src/verbs.cpp:2084 +#, fuzzy +msgid "Open Preferences for the Node tool" +msgstr "Слайдшоў Sodipodi" + +#: ../../po/../src/verbs.cpp:2085 +#, fuzzy +msgid "Rectangle Preferences" +msgstr "Уласьцівасьці прамакутніка" + +#: ../../po/../src/verbs.cpp:2086 +#, fuzzy +msgid "Open Preferences for the Rectangle tool" +msgstr "Слайдшоў Sodipodi" + +#: ../../po/../src/verbs.cpp:2087 +#, fuzzy +msgid "Ellipse Preferences" +msgstr "Элемэнт зьяўляецца спасылкай" + +#: ../../po/../src/verbs.cpp:2088 +#, fuzzy +msgid "Open Preferences for the Ellipse tool" +msgstr "Слайдшоў Sodipodi" + +#: ../../po/../src/verbs.cpp:2089 +#, fuzzy +msgid "Star Preferences" +msgstr "Уласьцівасьці зоркі" + +#: ../../po/../src/verbs.cpp:2090 +#, fuzzy +msgid "Open Preferences for the Star tool" +msgstr "Слайдшоў Sodipodi" + +#: ../../po/../src/verbs.cpp:2091 +#, fuzzy +msgid "Spiral Preferences" +msgstr "Уласьцівасьці сьпіралі" + +#: ../../po/../src/verbs.cpp:2092 +#, fuzzy +msgid "Open Preferences for the Spiral tool" +msgstr "Слайдшоў Sodipodi" + +#: ../../po/../src/verbs.cpp:2093 +#, fuzzy +msgid "Pencil Preferences" +msgstr "Элемэнт зьяўляецца спасылкай" + +#: ../../po/../src/verbs.cpp:2094 +#, fuzzy +msgid "Open Preferences for the Pencil tool" +msgstr "Слайдшоў Sodipodi" + +#: ../../po/../src/verbs.cpp:2095 +#, fuzzy +msgid "Pen Preferences" +msgstr "Элемэнт зьяўляецца спасылкай" + +#: ../../po/../src/verbs.cpp:2096 +#, fuzzy +msgid "Open Preferences for the Pen tool" +msgstr "Слайдшоў Sodipodi" + +#: ../../po/../src/verbs.cpp:2097 +#, fuzzy +msgid "Calligraphic Preferences" +msgstr "Каліграфічная рыса" + +#: ../../po/../src/verbs.cpp:2098 +#, fuzzy +msgid "Open Preferences for the Calligraphy tool" +msgstr "Слайдшоў Sodipodi" + +#: ../../po/../src/verbs.cpp:2099 +#, fuzzy +msgid "Text Preferences" +msgstr "Элемэнт зьяўляецца спасылкай" + +#: ../../po/../src/verbs.cpp:2100 +#, fuzzy +msgid "Open Preferences for the Text tool" +msgstr "Слайдшоў Sodipodi" + +#: ../../po/../src/verbs.cpp:2101 +#, fuzzy +msgid "Gradient Preferences" +msgstr "Элемэнт зьяўляецца спасылкай" + +#: ../../po/../src/verbs.cpp:2102 +#, fuzzy +msgid "Open Preferences for the Gradient tool" +msgstr "Слайдшоў Sodipodi" + +#: ../../po/../src/verbs.cpp:2103 +#, fuzzy +msgid "Zoom Preferences" +msgstr "Элемэнт зьяўляецца спасылкай" + +#: ../../po/../src/verbs.cpp:2104 +#, fuzzy +msgid "Open Preferences for the Zoom tool" +msgstr "Слайдшоў Sodipodi" + +#: ../../po/../src/verbs.cpp:2105 +#, fuzzy +msgid "Dropper Preferences" +msgstr "Слайдшоў Sodipodi" + +#: ../../po/../src/verbs.cpp:2106 +#, fuzzy +msgid "Open Preferences for the Dropper tool" +msgstr "Слайдшоў Sodipodi" + +#: ../../po/../src/verbs.cpp:2107 +#, fuzzy +msgid "Connector Preferences" +msgstr "Уласьцівасьці зоркі" + +#: ../../po/../src/verbs.cpp:2108 +#, fuzzy +msgid "Open Preferences for the Connector tool" +msgstr "Слайдшоў Sodipodi" + +#. Zoom/View +#: ../../po/../src/verbs.cpp:2111 +#, fuzzy +msgid "Zoom In" +msgstr "Маштабаваньне" + +#: ../../po/../src/verbs.cpp:2111 +#, fuzzy +msgid "Zoom in" +msgstr "Маштабаваньне" + +#: ../../po/../src/verbs.cpp:2112 +#, fuzzy +msgid "Zoom Out" +msgstr "Памяншае маштаб рысунка" + +#: ../../po/../src/verbs.cpp:2112 +#, fuzzy +msgid "Zoom out" +msgstr "Памяншае маштаб рысунка" + +#: ../../po/../src/verbs.cpp:2113 +#, fuzzy +msgid "_Rulers" +msgstr "Фільтары" + +#: ../../po/../src/verbs.cpp:2113 +#, fuzzy +msgid "Show or hide the canvas rulers" +msgstr "Паказаць кіруючыя" + +#: ../../po/../src/verbs.cpp:2114 +msgid "Scroll_bars" +msgstr "" + +#: ../../po/../src/verbs.cpp:2114 +#, fuzzy +msgid "Show or hide the canvas scrollbars" +msgstr "Паказаць кіруючыя" + +#: ../../po/../src/verbs.cpp:2115 +#, fuzzy +msgid "_Grid" +msgstr "Сетка" + +#: ../../po/../src/verbs.cpp:2116 +#, fuzzy +msgid "G_uides" +msgstr "Кіруючыя" + +#: ../../po/../src/verbs.cpp:2117 +msgid "Nex_t Zoom" +msgstr "" + +#: ../../po/../src/verbs.cpp:2117 +msgid "Next zoom (from the history of zooms)" +msgstr "" + +#: ../../po/../src/verbs.cpp:2119 +msgid "Pre_vious Zoom" +msgstr "" + +#: ../../po/../src/verbs.cpp:2119 +msgid "Previous zoom (from the history of zooms)" +msgstr "" + +#: ../../po/../src/verbs.cpp:2121 +#, fuzzy +msgid "Zoom 1:_1" +msgstr "Усталёўвае маштаб 1:1" + +#: ../../po/../src/verbs.cpp:2121 +#, fuzzy +msgid "Zoom to 1:1" +msgstr "Усталёўвае маштаб 1:1" + +#: ../../po/../src/verbs.cpp:2123 +#, fuzzy +msgid "Zoom 1:_2" +msgstr "Усталёўвае маштаб 2:1" + +#: ../../po/../src/verbs.cpp:2123 +#, fuzzy +msgid "Zoom to 1:2" +msgstr "Усталёўвае маштаб 2:1" + +#: ../../po/../src/verbs.cpp:2125 +#, fuzzy +msgid "_Zoom 2:1" +msgstr "Усталёўвае маштаб 2:1" + +#: ../../po/../src/verbs.cpp:2125 +#, fuzzy +msgid "Zoom to 2:1" +msgstr "Усталёўвае маштаб 2:1" + +#: ../../po/../src/verbs.cpp:2128 +msgid "_Fullscreen" +msgstr "" + +#: ../../po/../src/verbs.cpp:2128 +msgid "Stretch this document window to full screen" +msgstr "" + +#: ../../po/../src/verbs.cpp:2131 +#, fuzzy +msgid "Duplic_ate Window" +msgstr "Падвоіць вузел" + +#: ../../po/../src/verbs.cpp:2131 +#, fuzzy +msgid "Open a new window with the same document" +msgstr "Адкрывае існуючы дакумэнт SVG" + +#: ../../po/../src/verbs.cpp:2133 +#, fuzzy +msgid "_New View Preview" +msgstr "Стварыць папярэдні прагляд" + +#: ../../po/../src/verbs.cpp:2134 +#, fuzzy +msgid "New View Preview" +msgstr "Стварыць папярэдні прагляд" + +#. "view_new_preview" +#: ../../po/../src/verbs.cpp:2136 +msgid "_Normal" +msgstr "" + +#: ../../po/../src/verbs.cpp:2137 +msgid "Switch to normal display mode" +msgstr "" + +#: ../../po/../src/verbs.cpp:2138 +#, fuzzy +msgid "_Outline" +msgstr "Паказаць контур" + +#: ../../po/../src/verbs.cpp:2139 +msgid "Switch to outline (wireframe) display mode" +msgstr "" + +#: ../../po/../src/verbs.cpp:2141 +#, fuzzy +msgid "Ico_n Preview" +msgstr "Стварыць папярэдні прагляд" + +#: ../../po/../src/verbs.cpp:2142 +msgid "Open a window to preview items at different icon resolutions" +msgstr "" + +#: ../../po/../src/verbs.cpp:2144 +#, fuzzy +msgid "Zoom to fit page in window" +msgstr "Запаўняе акно усёй старонкай" + +#: ../../po/../src/verbs.cpp:2145 +msgid "Page _Width" +msgstr "" + +#: ../../po/../src/verbs.cpp:2146 +#, fuzzy +msgid "Zoom to fit page width in window" +msgstr "Запаўняе акно усёй старонкай" + +#: ../../po/../src/verbs.cpp:2148 +#, fuzzy +msgid "Zoom to fit drawing in window" +msgstr "Запаўняе рысаваньнем усё акно" + +#: ../../po/../src/verbs.cpp:2150 +#, fuzzy +msgid "Zoom to fit selection in window" +msgstr "Запаўняе вылучэньнем усё акно" + +#. Dialogs +#: ../../po/../src/verbs.cpp:2153 +#, fuzzy +msgid "In_kscape Preferences..." +msgstr "Слайдшоў Sodipodi" + +#: ../../po/../src/verbs.cpp:2154 +#, fuzzy +msgid "Global Inkscape preferences" +msgstr "Глябальныя наладкі дысплэя" + +#: ../../po/../src/verbs.cpp:2155 +msgid "_Document Preferences..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2156 +#, fuzzy +msgid "Preferences saved with the document" +msgstr "Адкрывае існуючы дакумэнт SVG" + +#: ../../po/../src/verbs.cpp:2157 +#, fuzzy +msgid "_Fill and Stroke..." +msgstr "Запаўненьне й штрыхоўка" + +#: ../../po/../src/verbs.cpp:2158 +#, fuzzy +msgid "Fill and Stroke dialog" +msgstr "Запаўненьне й штрыхоўка" + +#. TRANSLATORS: "Swatches" means: color samples +#: ../../po/../src/verbs.cpp:2160 +#, fuzzy +msgid "S_watches..." +msgstr "Захаваць як" + +#: ../../po/../src/verbs.cpp:2161 +msgid "View color swatches" +msgstr "" + +#: ../../po/../src/verbs.cpp:2162 +#, fuzzy +msgid "Transfor_m..." +msgstr "Трансфармаваньне:" + +#: ../../po/../src/verbs.cpp:2163 +#, fuzzy +msgid "Transform dialog" +msgstr "Трансфармаваньне вылучэньня" + +#: ../../po/../src/verbs.cpp:2164 +#, fuzzy +msgid "_Align and Distribute..." +msgstr "Раўнаньне й прадстаўленьне" + +#: ../../po/../src/verbs.cpp:2165 +#, fuzzy +msgid "Align and Distribute dialog" +msgstr "Раўнаньне й прадстаўленьне" + +#: ../../po/../src/verbs.cpp:2166 +#, fuzzy +msgid "_Text and Font..." +msgstr "Тэкст і шрыфт" + +#: ../../po/../src/verbs.cpp:2167 +#, fuzzy +msgid "Text and Font dialog" +msgstr "Тэкст і шрыфт" + +#: ../../po/../src/verbs.cpp:2168 +#, fuzzy +msgid "_XML Editor..." +msgstr "Рэдактар XML" + +#: ../../po/../src/verbs.cpp:2169 +msgid "XML Editor" +msgstr "Рэдактар XML" + +#: ../../po/../src/verbs.cpp:2170 +#, fuzzy +msgid "_Find..." +msgstr "Друк..." + +#: ../../po/../src/verbs.cpp:2171 +#, fuzzy +msgid "Find objects in document" +msgstr "Няма градыентнай заліўкі ў дакумэнце" + +#: ../../po/../src/verbs.cpp:2172 +msgid "_Messages..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2173 +msgid "View debug messages" +msgstr "" + +#: ../../po/../src/verbs.cpp:2174 +#, fuzzy +msgid "S_cripts..." +msgstr "Друк..." + +#: ../../po/../src/verbs.cpp:2175 +msgid "Run scripts" +msgstr "" + +#: ../../po/../src/verbs.cpp:2176 +#, fuzzy +msgid "Show/Hide D_ialogs" +msgstr "Паказаць кіруючыя" + +#: ../../po/../src/verbs.cpp:2177 +msgid "Show or hide all active dialogs" +msgstr "" + +#. TRANSLATORS: "Tile clones" means: "Create tiled clones" +#: ../../po/../src/verbs.cpp:2179 +msgid "Tile clones..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2180 +msgid "Create and arrange multiple clones of selection" +msgstr "" + +#: ../../po/../src/verbs.cpp:2181 +#, fuzzy +msgid "_Object Properties..." +msgstr "Уласьцівасьці прамакутніка" + +#: ../../po/../src/verbs.cpp:2182 +#, fuzzy +msgid "Object Properties dialog" +msgstr "Уласьцівасьці прамакутніка" + +#: ../../po/../src/verbs.cpp:2185 +msgid "_Connect to Jabber server..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2185 +msgid "Connect to a Jabber server" +msgstr "" + +#: ../../po/../src/verbs.cpp:2187 +#, fuzzy +msgid "Share with _user..." +msgstr "Захаваць як" + +#: ../../po/../src/verbs.cpp:2187 +msgid "Establish a whiteboard session with another Jabber user" +msgstr "" + +#: ../../po/../src/verbs.cpp:2189 +msgid "Share with _chatroom..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2189 +msgid "" +"Join a chatroom to start a new whiteboard session or join one in progress" +msgstr "" + +#: ../../po/../src/verbs.cpp:2191 +msgid "_Dump XML node tracker" +msgstr "" + +#: ../../po/../src/verbs.cpp:2191 +msgid "Dump the contents of the XML tracker to the console" +msgstr "" + +#: ../../po/../src/verbs.cpp:2193 +msgid "_Open session file..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2193 +msgid "Open and browse through records of past whiteboard sessions" +msgstr "" + +#: ../../po/../src/verbs.cpp:2195 +msgid "Session file playback" +msgstr "" + +#: ../../po/../src/verbs.cpp:2197 +msgid "_Disconnect from session" +msgstr "" + +#: ../../po/../src/verbs.cpp:2199 +msgid "Disconnect from _server" +msgstr "" + +#: ../../po/../src/verbs.cpp:2201 +msgid "_Input Devices..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2202 +msgid "Configure extended input devices" +msgstr "" + +#. Help +#: ../../po/../src/verbs.cpp:2205 +msgid "_Keys and Mouse" +msgstr "" + +#: ../../po/../src/verbs.cpp:2206 +msgid "Key and mouse shortcuts reference" +msgstr "" + +#: ../../po/../src/verbs.cpp:2207 +#, fuzzy +msgid "About E_xtensions" +msgstr "Пашырэньне" + +#: ../../po/../src/verbs.cpp:2208 +#, fuzzy +msgid "About Extensions..." +msgstr "Пашырэньне" + +#: ../../po/../src/verbs.cpp:2209 +#, fuzzy +msgid "About _Memory" +msgstr "Пра модулі" + +#: ../../po/../src/verbs.cpp:2210 +#, fuzzy +msgid "About Memory..." +msgstr "Пашырэньне" + +#: ../../po/../src/verbs.cpp:2211 +msgid "_About Inkscape" +msgstr "" + +#. "help_about" +#. new HelpVerb(SP_VERB_SHOW_LICENSE, "ShowLicense", N_("Modifying or Redistributing Inkscape"), +#. N_("Show license to modify and/or redistribute Inkscape: GNU GPL"), NULL), +#. Tutorials +#: ../../po/../src/verbs.cpp:2217 +#, fuzzy +msgid "Inkscape: _Basic" +msgstr "Слайдшоў Sodipodi" + +#: ../../po/../src/verbs.cpp:2218 +msgid "Getting started with Inkscape" +msgstr "" + +#. "tutorial_basic" +#: ../../po/../src/verbs.cpp:2219 +#, fuzzy +msgid "Inkscape: _Shapes" +msgstr "Слайдшоў Sodipodi" + +#: ../../po/../src/verbs.cpp:2220 +msgid "Using shape tools to create and edit shapes" +msgstr "" + +#: ../../po/../src/verbs.cpp:2221 +#, fuzzy +msgid "Inkscape: _Advanced" +msgstr "Слайдшоў Sodipodi" + +#: ../../po/../src/verbs.cpp:2222 +#, fuzzy +msgid "Advanced Inkscape topics" +msgstr "Слайдшоў Sodipodi" + +#. "tutorial_advanced" +#. TRANSLATORS: "to trace" means "to convert a bitmap to vector graphics" (to vectorize) +#: ../../po/../src/verbs.cpp:2224 +#, fuzzy +msgid "Inkscape: T_racing" +msgstr "Слайдшоў Sodipodi" + +#: ../../po/../src/verbs.cpp:2225 +#, fuzzy +msgid "Using bitmap tracing" +msgstr "Памер кропкавага відарыса" + +#. "tutorial_tracing" +#: ../../po/../src/verbs.cpp:2226 +#, fuzzy +msgid "Inkscape: _Calligraphy" +msgstr "Слайдшоў Sodipodi" + +#: ../../po/../src/verbs.cpp:2227 +msgid "Using the Calligraphy pen tool" +msgstr "" + +#: ../../po/../src/verbs.cpp:2228 +msgid "_Elements of Design" +msgstr "" + +#: ../../po/../src/verbs.cpp:2229 +msgid "Principles of design in the tutorial form" +msgstr "" + +#. "tutorial_design" +#: ../../po/../src/verbs.cpp:2230 +msgid "_Tips and Tricks" +msgstr "" + +#: ../../po/../src/verbs.cpp:2231 +msgid "Miscellaneous tips and tricks" +msgstr "" + +#. "tutorial_tips" +#. Effect +#: ../../po/../src/verbs.cpp:2234 +msgid "Previous Effect" +msgstr "" + +#: ../../po/../src/verbs.cpp:2235 +msgid "Repeat the last effect with the same settings" +msgstr "" + +#. "tutorial_tips" +#: ../../po/../src/verbs.cpp:2236 +msgid "Previous Effect Settings..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2237 +msgid "Repeat the last effect with new settings" +msgstr "" + +#: ../../po/../src/widgets/dash-selector.cpp:106 +#, fuzzy +msgid "Dash pattern" +msgstr "Няма рафарбоўкі" + +#: ../../po/../src/widgets/dash-selector.cpp:121 +#, fuzzy +msgid "Pattern offset" +msgstr "Раўнае аб'ект" + +#: ../../po/../src/widgets/desktop-widget.cpp:240 +#, fuzzy +msgid "Zoom drawing if window size changes" +msgstr "Запаўняе рысаваньнем усё акно" + +#: ../../po/../src/widgets/desktop-widget.cpp:298 +msgid "Cursor coordinates" +msgstr "" + +#. display the initial welcome message in the statusbar +#: ../../po/../src/widgets/desktop-widget.cpp:324 +msgid "" +"Welcome to Inkscape! Use shape or freehand tools to create objects; " +"use selector (arrow) to move or transform them." +msgstr "" + +#: ../../po/../src/widgets/desktop-widget.cpp:372 +#, c-format +msgid "%s: %d - Inkscape" +msgstr "" + +#: ../../po/../src/widgets/desktop-widget.cpp:374 +#, c-format +msgid "%s - Inkscape" +msgstr "" + +#: ../../po/../src/widgets/desktop-widget.cpp:532 +#, c-format +msgid "" +"Save changes to document \"%s\" before " +"closing?\n" +"\n" +"If you close without saving, your changes will be discarded." +msgstr "" + +#: ../../po/../src/widgets/desktop-widget.cpp:548 +#: ../../po/../src/widgets/desktop-widget.cpp:612 +msgid "Close _without saving" +msgstr "" + +#: ../../po/../src/widgets/desktop-widget.cpp:595 +#, c-format +msgid "" +"The file \"%s\" was saved with a " +"format (%s) that may cause data loss!\n" +"\n" +"Do you want to save this file in another format?" +msgstr "" + +#. Family frame +#: ../../po/../src/widgets/font-selector.cpp:156 +msgid "Font family" +msgstr "Сямейства шрыфта" + +#. Style frame +#: ../../po/../src/widgets/font-selector.cpp:184 +msgid "Style" +msgstr "Стыль" + +#: ../../po/../src/widgets/font-selector.cpp:219 +msgid "Font size:" +msgstr "Памер шрыфта:" + +#. TRANSLATORS: Test string used in text and font dialog (when no +#. * text has been entered) to get a preview of the font. Choose +#. * some representative characters that users of your locale will be +#. * interested in. +#: ../../po/../src/widgets/font-selector.cpp:554 +msgid "AaBbCcIiPpQq12368.;/()" +msgstr "ШшРрЫыФфТт1234568.;/(-)" + +#: ../../po/../src/widgets/gradient-selector.cpp:137 +#: ../../po/../src/widgets/gradient-toolbar.cpp:524 +#, fuzzy +msgid "Duplicate" +msgstr "Падвоіць" + +#: ../../po/../src/widgets/gradient-selector.cpp:142 +#: ../../po/../src/widgets/gradient-toolbar.cpp:535 +#, fuzzy +msgid "Edit..." +msgstr "Рэдагаваньне" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/pservers.html#LinearGradientSpreadMethodAttribute +#: ../../po/../src/widgets/gradient-selector.cpp:159 +msgid "" +"Whether to fill with flat color beyond the ends of the gradient vector " +"(spreadMethod=\"pad\"), or repeat the gradient in the same direction " +"(spreadMethod=\"repeat\"), or repeat the gradient in alternating opposite " +"directions (spreadMethod=\"reflect\")" +msgstr "" + +#: ../../po/../src/widgets/gradient-selector.cpp:165 +#, fuzzy +msgid "none" +msgstr "Няма" + +#: ../../po/../src/widgets/gradient-selector.cpp:169 +#, fuzzy +msgid "reflected" +msgstr "Першы вылучаны" + +#: ../../po/../src/widgets/gradient-selector.cpp:173 +#, fuzzy +msgid "direct" +msgstr "Прамакутнік" + +#: ../../po/../src/widgets/gradient-selector.cpp:181 +msgid "Repeat:" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:217 +msgid "No gradients" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:226 +#, fuzzy +msgid "Nothing selected" +msgstr "Другі вылучаны" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:237 +#, fuzzy +msgid "No gradients in selection" +msgstr "Градыент не вылучаны" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:247 +msgid "Multiple gradients" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:525 +msgid "" +"If the gradient is used by more than one object, create a copy of it for the " +"selected object(s)" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:536 +#, fuzzy +msgid "Edit the stops of the gradient" +msgstr "Лінэйны градыент" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:593 +#: ../../po/../src/widgets/toolbox.cpp:1103 +#: ../../po/../src/widgets/toolbox.cpp:1192 +#: ../../po/../src/widgets/toolbox.cpp:1485 +#: ../../po/../src/widgets/toolbox.cpp:1534 +#: ../../po/../src/widgets/toolbox.cpp:1766 +#: ../../po/../src/widgets/toolbox.cpp:1801 +#: ../../po/../src/widgets/toolbox.cpp:2331 +#: ../../po/../src/widgets/toolbox.cpp:2370 +msgid "New:" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:606 +#, fuzzy +msgid "Create linear gradient" +msgstr "Лінэйны градыент" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:620 +msgid "Create radial (elliptic or circular) gradient" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:635 +#, fuzzy +msgid "on" +msgstr "Няма" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:648 +#, fuzzy +msgid "Create gradient in the fill" +msgstr "Вэктар градыента" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:662 +msgid "Create gradient in the stroke" +msgstr "" + +#. FIXME: implement averaging of all parameters for multiple selected stars +#. gtk_label_set_markup(GTK_LABEL(l), _("Average:")); +#. FIXME: implement averaging of all parameters for multiple selected +#. gtk_label_set_markup(GTK_LABEL(l), _("Average:")); +#: ../../po/../src/widgets/gradient-toolbar.cpp:676 +#: ../../po/../src/widgets/toolbox.cpp:1105 +#: ../../po/../src/widgets/toolbox.cpp:1124 +#: ../../po/../src/widgets/toolbox.cpp:1493 +#: ../../po/../src/widgets/toolbox.cpp:1518 +#: ../../po/../src/widgets/toolbox.cpp:1768 +#: ../../po/../src/widgets/toolbox.cpp:1787 +#: ../../po/../src/widgets/toolbox.cpp:2334 +#: ../../po/../src/widgets/toolbox.cpp:2354 +msgid "Change:" +msgstr "" + +#: ../../po/../src/widgets/gradient-vector.cpp:269 +msgid "No gradients in document" +msgstr "Няма градыентнай заліўкі ў дакумэнце" + +#: ../../po/../src/widgets/gradient-vector.cpp:275 +msgid "No gradient selected" +msgstr "Градыент не вылучаны" + +#: ../../po/../src/widgets/gradient-vector.cpp:532 +#, fuzzy +msgid "No stops in gradient" +msgstr "Лінэйны градыент" + +#. TRANSLATORS: "Stop" means: a "phase" of a gradient +#: ../../po/../src/widgets/gradient-vector.cpp:794 +msgid "Add stop" +msgstr "" + +#: ../../po/../src/widgets/gradient-vector.cpp:797 +msgid "Add another control stop to gradient" +msgstr "" + +#: ../../po/../src/widgets/gradient-vector.cpp:799 +#, fuzzy +msgid "Delete stop" +msgstr "Выдаліць вузел" + +#: ../../po/../src/widgets/gradient-vector.cpp:802 +msgid "Delete current control stop from gradient" +msgstr "" + +#. Label +#: ../../po/../src/widgets/gradient-vector.cpp:813 +msgid "Offset:" +msgstr "" + +#. TRANSLATORS: "Stop" means: a "phase" of a gradient +#: ../../po/../src/widgets/gradient-vector.cpp:858 +#, fuzzy +msgid "Stop Color" +msgstr "Пачатковы колер" + +#: ../../po/../src/widgets/gradient-vector.cpp:887 +#, fuzzy +msgid "Gradient editor" +msgstr "Вэктар градыента" + +#: ../../po/../src/widgets/layer-selector.cpp:119 +#, fuzzy +msgid "Toggle current layer visibility" +msgstr "Назва дакумэнта:" + +#: ../../po/../src/widgets/layer-selector.cpp:139 +#, fuzzy +msgid "Lock or unlock current layer" +msgstr "Назва дакумэнта:" + +#: ../../po/../src/widgets/layer-selector.cpp:142 +#, fuzzy +msgid "Current layer" +msgstr "Назва дакумэнта:" + +#: ../../po/../src/widgets/layer-selector.cpp:553 +msgid "(root)" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:182 +#: ../../po/../src/widgets/paint-selector.cpp:561 +msgid "No paint" +msgstr "Няма рафарбоўкі" + +#: ../../po/../src/widgets/paint-selector.cpp:184 +#: ../../po/../src/widgets/paint-selector.cpp:629 +#, fuzzy +msgid "Flat color" +msgstr "Канчатковы колер" + +#: ../../po/../src/widgets/paint-selector.cpp:186 +#: ../../po/../src/widgets/paint-selector.cpp:696 +msgid "Linear gradient" +msgstr "Лінэйны градыент" + +#: ../../po/../src/widgets/paint-selector.cpp:188 +#: ../../po/../src/widgets/paint-selector.cpp:699 +msgid "Radial gradient" +msgstr "Кругавы градыент" + +#: ../../po/../src/widgets/paint-selector.cpp:192 +msgid "Unset paint (make it undefined so it can be inherited)" +msgstr "" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/painting.html#FillRuleProperty +#: ../../po/../src/widgets/paint-selector.cpp:204 +msgid "" +"Any path self-intersections or subpaths create holes in the fill (fill-rule: " +"evenodd)" +msgstr "" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/painting.html#FillRuleProperty +#: ../../po/../src/widgets/paint-selector.cpp:215 +msgid "" +"Fill is solid unless a subpath is counterdirectional (fill-rule: nonzero)" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:528 +msgid "No objects" +msgstr "Няма аб'ектаў" + +#: ../../po/../src/widgets/paint-selector.cpp:539 +msgid "Multiple styles" +msgstr "Шматлікія стылі" + +#: ../../po/../src/widgets/paint-selector.cpp:550 +msgid "Paint is undefined" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:757 +#, fuzzy +msgid "No patterns in document" +msgstr "Няма градыентнай заліўкі ў дакумэнце" + +#: ../../po/../src/widgets/paint-selector.cpp:872 +msgid "" +"Use Edit > Object(s) to Pattern to create a new pattern from " +"selection." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:426 +msgid "Now stroke width is scaled when objects are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:428 +msgid "Now stroke width is not scaled when objects are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:436 +msgid "" +"Now rounded rectangle corners are scaled when rectangles are " +"scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:438 +msgid "" +"Now rounded rectangle corners are not scaled when rectangles " +"are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:446 +msgid "" +"Now gradients are transformed along with their objects when " +"those are transformed (moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:448 +msgid "" +"Now gradients remain fixed when objects are transformed " +"(moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:456 +msgid "" +"Now patterns are transformed along with their objects when " +"those are transformed (moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:458 +msgid "" +"Now patterns remain fixed when objects are transformed (moved, " +"scaled, rotated, or skewed)." +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:506 +#, fuzzy +msgid "select_toolbar|X" +msgstr "Вылучэньне" + +#: ../../po/../src/widgets/select-toolbar.cpp:506 +msgid "Horizontal coordinate of selection" +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:511 +#, fuzzy +msgid "select_toolbar|Y" +msgstr "Вылучэньне" + +#: ../../po/../src/widgets/select-toolbar.cpp:511 +msgid "Vertical coordinate of selection" +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:517 +#, fuzzy +msgid "select_toolbar|W" +msgstr "Вылучэньне" + +#: ../../po/../src/widgets/select-toolbar.cpp:517 +msgid "Width of selection" +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:525 +msgid "Change both width and height by the same proportion" +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:534 +#, fuzzy +msgid "select_toolbar|H" +msgstr "Вылучэньне" + +#: ../../po/../src/widgets/select-toolbar.cpp:534 +msgid "Height of selection" +msgstr "" + +#: ../../po/../src/widgets/sp-color-gtkselector.cpp:62 +msgid "System" +msgstr "" + +#: ../../po/../src/widgets/sp-color-notebook.cpp:322 +#, fuzzy +msgid "RGBA_:" +msgstr "RGB" + +#: ../../po/../src/widgets/sp-color-notebook.cpp:330 +msgid "Hexadecimal RGBA value of the color" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "RGB" +msgstr "RGB" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +#, fuzzy +msgid "HSL" +msgstr "HSV" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "CMYK" +msgstr "CMYK" + +#: ../../po/../src/widgets/sp-color-scales.cpp:397 +msgid "_R" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:398 +#: ../../po/../src/widgets/sp-color-scales.cpp:399 +#, fuzzy +msgid "Red" +msgstr "Чырвоны:" + +#: ../../po/../src/widgets/sp-color-scales.cpp:400 +msgid "_G" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:401 +#: ../../po/../src/widgets/sp-color-scales.cpp:402 +#, fuzzy +msgid "Green" +msgstr "Зялёны:" + +#: ../../po/../src/widgets/sp-color-scales.cpp:403 +msgid "_B" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:404 +#: ../../po/../src/widgets/sp-color-scales.cpp:405 +#, fuzzy +msgid "Blue" +msgstr "Сіні:" + +#. Label +#: ../../po/../src/widgets/sp-color-scales.cpp:406 +#: ../../po/../src/widgets/sp-color-scales.cpp:432 +#: ../../po/../src/widgets/sp-color-scales.cpp:463 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:141 +msgid "_A" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:407 +#: ../../po/../src/widgets/sp-color-scales.cpp:408 +#: ../../po/../src/widgets/sp-color-scales.cpp:433 +#: ../../po/../src/widgets/sp-color-scales.cpp:434 +#: ../../po/../src/widgets/sp-color-scales.cpp:464 +#: ../../po/../src/widgets/sp-color-scales.cpp:465 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:151 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:163 +msgid "Alpha (opacity)" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:423 +msgid "_H" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:424 +#: ../../po/../src/widgets/sp-color-scales.cpp:425 +#, fuzzy +msgid "Hue" +msgstr "Тон:" + +#: ../../po/../src/widgets/sp-color-scales.cpp:426 +msgid "_S" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:427 +#: ../../po/../src/widgets/sp-color-scales.cpp:428 +#, fuzzy +msgid "Saturation" +msgstr "Насычанасьць:" + +#: ../../po/../src/widgets/sp-color-scales.cpp:429 +msgid "_L" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:430 +#: ../../po/../src/widgets/sp-color-scales.cpp:431 +#, fuzzy +msgid "Lightness" +msgstr "Вышыня:" + +#: ../../po/../src/widgets/sp-color-scales.cpp:451 +msgid "_C" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:452 +#: ../../po/../src/widgets/sp-color-scales.cpp:453 +#, fuzzy +msgid "Cyan" +msgstr "Блакітны:" + +#: ../../po/../src/widgets/sp-color-scales.cpp:454 +msgid "_M" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:455 +#: ../../po/../src/widgets/sp-color-scales.cpp:456 +#, fuzzy +msgid "Magenta" +msgstr "Малінавы:" + +#: ../../po/../src/widgets/sp-color-scales.cpp:457 +msgid "_Y" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:458 +#: ../../po/../src/widgets/sp-color-scales.cpp:459 +#, fuzzy +msgid "Yellow" +msgstr "Жоўты:" + +#: ../../po/../src/widgets/sp-color-scales.cpp:460 +msgid "_K" +msgstr "" + +#: ../../po/../src/widgets/sp-color-selector.cpp:71 +msgid "Unnamed" +msgstr "" + +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:68 +msgid "Wheel" +msgstr "" + +#: ../../po/../src/widgets/sp-xmlview-attr-list.cpp:53 +msgid "Attribute" +msgstr "Атрыбут" + +#: ../../po/../src/widgets/sp-xmlview-attr-list.cpp:54 +msgid "Value" +msgstr "Значэньне" + +#: ../../po/../src/widgets/toolbox.cpp:424 +msgid "Insert new nodes into selected segments" +msgstr "Устаўляе новыя вузлы ў вылучаныя сэгмэнты" + +#: ../../po/../src/widgets/toolbox.cpp:426 +msgid "Delete selected nodes" +msgstr "Выдаляе вылучаныя вузлы" + +#: ../../po/../src/widgets/toolbox.cpp:431 +#, fuzzy +msgid "Join paths at selected nodes" +msgstr "Далучае рысы да вылучаных вузлоў" + +#: ../../po/../src/widgets/toolbox.cpp:433 +#, fuzzy +msgid "Join paths at selected nodes with new segment" +msgstr "Далучае рысы да вылучаных вузлоў" + +#: ../../po/../src/widgets/toolbox.cpp:436 +msgid "Split path between two non-endpoint nodes" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:439 +#, fuzzy +msgid "Break path at selected nodes" +msgstr "Абрывае рысу на вылучаным вузьле" + +#: ../../po/../src/widgets/toolbox.cpp:444 +msgid "Make selected nodes corner" +msgstr "Робіць вылучаныя вузлы кутамі" + +#: ../../po/../src/widgets/toolbox.cpp:447 +msgid "Make selected nodes smooth" +msgstr "Робіць вылучаныя вузлы згладжанымі" + +#: ../../po/../src/widgets/toolbox.cpp:450 +#, fuzzy +msgid "Make selected nodes symmetric" +msgstr "Робіць вылучаныя вузлы згладжанымі" + +#: ../../po/../src/widgets/toolbox.cpp:455 +msgid "Make selected segments lines" +msgstr "Робіць вылучаныя сэгмэнты рысамі" + +#: ../../po/../src/widgets/toolbox.cpp:458 +msgid "Make selected segments curves" +msgstr "Робіць вылучаныя сэгмэнты дугамі" + +#: ../../po/../src/widgets/toolbox.cpp:1199 +msgid "Polygon" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1206 +msgid "Regular polygon (with one handle) instead of a star" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1218 +msgid "Corners:" +msgstr "Куты:" + +#: ../../po/../src/widgets/toolbox.cpp:1218 +msgid "Number of corners of a polygon or star" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1228 +#, fuzzy +msgid "Spoke ratio:" +msgstr "Прапорцыі:" + +#. TRANSLATORS: Tip radius of a star is the distance from the center to the farthest handle. +#. Base radius is the same for the closest handle. +#: ../../po/../src/widgets/toolbox.cpp:1231 +msgid "Base radius to tip radius ratio" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1246 +#, fuzzy +msgid "Rounded:" +msgstr "Роля:" + +#: ../../po/../src/widgets/toolbox.cpp:1246 +msgid "How much rounded are the corners (0 for sharp)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1256 +msgid "Randomized:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1256 +msgid "Scatter randomly the corners and angles" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1269 +#: ../../po/../src/widgets/toolbox.cpp:1838 +#: ../../po/../src/widgets/toolbox.cpp:2061 +msgid "Defaults" +msgstr "Дапомнае" + +#: ../../po/../src/widgets/toolbox.cpp:1270 +#: ../../po/../src/widgets/toolbox.cpp:1839 +#: ../../po/../src/widgets/toolbox.cpp:2062 +msgid "" +"Reset shape parameters to defaults (use Inkscape Preferences > Tools to " +"change defaults)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1544 +msgid "W:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1544 +#, fuzzy +msgid "Width of rectangle" +msgstr "Прамакутнік" + +#: ../../po/../src/widgets/toolbox.cpp:1556 +#, fuzzy +msgid "Height of rectangle" +msgstr "Прамакутнік" + +#: ../../po/../src/widgets/toolbox.cpp:1568 +#, fuzzy +msgid "Rx:" +msgstr "x0:" + +#: ../../po/../src/widgets/toolbox.cpp:1568 +msgid "Horizontal radius of rounded corners" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1578 +#, fuzzy +msgid "Ry:" +msgstr "y0:" + +#: ../../po/../src/widgets/toolbox.cpp:1578 +msgid "Vertical radius of rounded corners" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1594 +msgid "Not rounded" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1596 +msgid "Make corners sharp" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1805 +#, fuzzy +msgid "Turns:" +msgstr "Трансфармаваньне:" + +#: ../../po/../src/widgets/toolbox.cpp:1805 +msgid "Number of revolutions" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1815 +msgid "Divergence:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1815 +msgid "How much denser/sparser are outer revolutions; 1 = uniform" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1825 +msgid "Inner radius:" +msgstr "Нутраны радыюс:" + +#: ../../po/../src/widgets/toolbox.cpp:1825 +msgid "Radius of the innermost revolution (relative to the spiral size)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1957 +msgid "The width of the calligraphic pen (relative to the visible canvas area)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1967 +#, fuzzy +msgid "Thinning:" +msgstr "Вывад" + +#: ../../po/../src/widgets/toolbox.cpp:1967 +msgid "" +"How much velocity thins the stroke (> 0 makes fast strokes thinner, < 0 " +"makes them broader, 0 makes width independent of velocity)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1980 +msgid "Angle:" +msgstr "Кут:" + +#: ../../po/../src/widgets/toolbox.cpp:1980 +msgid "" +"The angle of the pen's nib (in degrees; 0 = horizontal; has no effect if " +"fixation = 0)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1990 +#, fuzzy +msgid "Fixation:" +msgstr "Арыентацыя:" + +#: ../../po/../src/widgets/toolbox.cpp:1990 +msgid "" +"How fixed is the pen angle (0 = always perpendicular to stroke direction, 1 " +"= fixed)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2003 +msgid "Mass:" +msgstr "Маса:" + +#: ../../po/../src/widgets/toolbox.cpp:2003 +msgid "How much inertia affects the movement of the pen" +msgstr "" + +#. TRANSLATORS: "drag" means "resistance" here +#: ../../po/../src/widgets/toolbox.cpp:2014 +msgid "Drag:" +msgstr "Градусы:" + +#: ../../po/../src/widgets/toolbox.cpp:2014 +msgid "How much resistance affects the movement of the pen" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2034 +msgid "Use the pressure of the input device to alter the width of the pen" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2047 +msgid "Use the tilt of the input device to alter the angle of the pen's nib" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2374 +#, fuzzy +msgid "Start:" +msgstr "Зорка" + +#: ../../po/../src/widgets/toolbox.cpp:2374 +msgid "The angle (in degrees) from the horizontal to the arc's start point" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2384 +msgid "End:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2384 +msgid "The angle (in degrees) from the horizontal to the arc's end point" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2395 +#, fuzzy +msgid "Open arc" +msgstr "Адкрыць" + +#: ../../po/../src/widgets/toolbox.cpp:2396 +msgid "" +"Switch between arc (unclosed shape) and segment (closed shape with two radii)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2415 +msgid "Make whole" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2417 +msgid "Make the shape a whole ellipse, not arc or segment" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2644 +msgid "" +"When pressed, picks visible color without alpha and when not pressed, picks " +"color including its alpha" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:3039 +#, fuzzy +msgid "Make connectors avoid selected objects" +msgstr "Выдаляе вылучаныя аб'екты" + +#: ../../po/../src/widgets/toolbox.cpp:3043 +#, fuzzy +msgid "Make connectors ignore selected objects" +msgstr "Выдаляе вылучаныя аб'екты" + +#. +#. 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 : +#: ../share/extensions/addnodes.inx.h:1 +#, fuzzy +msgid "Add Nodes" +msgstr "Вузлы" + +#: ../share/extensions/addnodes.inx.h:2 +msgid "Maximum Segment Length" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:1 +#, fuzzy +msgid "AI Input" +msgstr "Увод" + +#: ../share/extensions/ai_input.inx.h:2 ../share/extensions/ai_output.inx.h:2 +msgid "Adobe Illustrator (*.ai)" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:3 +msgid "Open files saved with Adobe Illustrator" +msgstr "" + +#: ../share/extensions/ai_output.inx.h:1 +#, fuzzy +msgid "AI Output" +msgstr "-" + +#: ../share/extensions/ai_output.inx.h:3 +#, fuzzy +msgid "Write Adobe Illustrator" +msgstr "Рэдактар вэктарнае графікі" + +#: ../share/extensions/dia.inx.h:1 +msgid "A diagram created with the program Dia" +msgstr "" + +#: ../share/extensions/dia.inx.h:2 +msgid "Dia Diagram (*.dia)" +msgstr "" + +#: ../share/extensions/dia.inx.h:3 +#, fuzzy +msgid "Dia Input" +msgstr "Увод" + +#: ../share/extensions/dia.inx.h:4 +msgid "" +"In order to import Dia files, Dia itself must be installed. You can get Dia " +"at http://www.gnome.org/projects/dia/" +msgstr "" + +#: ../share/extensions/dia.inx.h:5 +msgid "" +"The dia2svg.sh script should be installed with your Inkscape distribution. " +"If you do not have it, there is likely to be something wrong with your " +"Inkscape installation." +msgstr "" + +#: ../share/extensions/dots.inx.h:1 +#, fuzzy +msgid "Connect the Dots" +msgstr "Куты:" + +#: ../share/extensions/dots.inx.h:2 +#, fuzzy +msgid "Dot Size" +msgstr "Бакі:" + +#: ../share/extensions/dots.inx.h:3 +#, fuzzy +msgid "Font Size" +msgstr "Памер шрыфта:" + +#: ../share/extensions/dropshadow.inx.h:1 +#, fuzzy +msgid "Color of shadow" +msgstr "Паказаць межы" + +#: ../share/extensions/dropshadow.inx.h:2 +msgid "Dropshadow" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:1 +#: ../share/extensions/dxf_output.inx.h:1 +msgid "AutoCAD DXF (*.dxf)" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:2 +#, fuzzy +msgid "DXF Input" +msgstr "Увод" + +#: ../share/extensions/dxf_input.inx.h:3 +msgid "Import AutoCAD's Document Exchange Format" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:4 +msgid "" +"dxf2svg may come with Inkscape, but is also at http://dxf-svg-convert." +"sourceforge.net/" +msgstr "" + +#: ../share/extensions/dxf_output.inx.h:2 +#, fuzzy +msgid "DXF Output" +msgstr "-" + +#: ../share/extensions/dxf_output.inx.h:3 +msgid "DXF file written by pstoedit" +msgstr "" + +#: ../share/extensions/dxf_output.inx.h:4 +msgid "pstoedit must be installed to run see http://www.pstoedit.net/pstoedit" +msgstr "" + +#: ../share/extensions/embedimage.inx.h:1 +#, fuzzy +msgid "Embed Images" +msgstr "Відарыс" + +#: ../share/extensions/eps_input.inx.h:1 +#, fuzzy +msgid "EPS Input" +msgstr "Увод" + +#: ../share/extensions/eps_input.inx.h:2 +msgid "Encapsulated Postscript" +msgstr "" + +#: ../share/extensions/eps_input.inx.h:3 +msgid "Encapsulated Postscript (*.eps)" +msgstr "" + +#: ../share/extensions/epsi_output.inx.h:1 +#, fuzzy +msgid "EPSI Output" +msgstr "-" + +#: ../share/extensions/epsi_output.inx.h:2 +msgid "Encapsulated Postscript Interchange (*.epsi)" +msgstr "" + +#: ../share/extensions/epsi_output.inx.h:3 +msgid "Encapsulated Postscript with a thumbnail" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:1 ../share/extensions/ffms.inx.h:1 +#: ../share/extensions/ffset.inx.h:1 ../share/extensions/ffss.inx.h:1 +#, fuzzy +msgid "Bridge Width" +msgstr "Шырыня:" + +#: ../share/extensions/ffmet.inx.h:2 ../share/extensions/ffms.inx.h:2 +msgid "First String Length" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:3 +msgid "FretFind Multi Length ET" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:4 ../share/extensions/ffms.inx.h:4 +#: ../share/extensions/ffset.inx.h:3 ../share/extensions/ffss.inx.h:3 +msgid "Fretboard Edges" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:5 ../share/extensions/ffms.inx.h:5 +msgid "Last String Length" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:6 ../share/extensions/ffms.inx.h:6 +#: ../share/extensions/ffset.inx.h:4 ../share/extensions/ffss.inx.h:4 +msgid "Number of Frets" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:7 ../share/extensions/ffms.inx.h:7 +#: ../share/extensions/ffset.inx.h:5 ../share/extensions/ffss.inx.h:5 +msgid "Number of Strings" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:8 ../share/extensions/ffms.inx.h:8 +#: ../share/extensions/ffset.inx.h:6 ../share/extensions/ffss.inx.h:6 +#, fuzzy +msgid "Nut Width" +msgstr "Шырыня:" + +#: ../share/extensions/ffmet.inx.h:9 ../share/extensions/ffms.inx.h:10 +msgid "Perpendicular Distance" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:10 ../share/extensions/ffset.inx.h:7 +msgid "Scale Base (2 for Octave)" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:11 ../share/extensions/ffset.inx.h:9 +msgid "Tones in Scale" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:12 ../share/extensions/ffms.inx.h:12 +#: ../share/extensions/ffset.inx.h:10 ../share/extensions/ffss.inx.h:10 +msgid "px per Unit" +msgstr "" + +#: ../share/extensions/ffms.inx.h:3 +msgid "FretFind Multi Length Scala" +msgstr "" + +#: ../share/extensions/ffms.inx.h:9 ../share/extensions/ffss.inx.h:7 +msgid "Path to Scala *.scl File" +msgstr "" + +#: ../share/extensions/ffms.inx.h:11 +msgid "Tuning (scale step for each string seperated by semicolons)" +msgstr "" + +#: ../share/extensions/ffset.inx.h:2 +msgid "FretFind Single Length ET" +msgstr "" + +#: ../share/extensions/ffset.inx.h:8 ../share/extensions/ffss.inx.h:8 +msgid "Scale Length" +msgstr "" + +#: ../share/extensions/ffss.inx.h:2 +msgid "FretFind Single Length Scala" +msgstr "" + +#: ../share/extensions/ffss.inx.h:9 +msgid "Tuning (Scale step for each string seperated by semicolons)" +msgstr "" + +#: ../share/extensions/handles.inx.h:1 +#, fuzzy +msgid "Draw Handles" +msgstr "Інструмэнт алоўка - рысуе вольныя дугі й простыя рысы" + +#: ../share/extensions/interp.inx.h:1 +#, fuzzy +msgid "Duplicate Endpaths" +msgstr "Падвоіць вузел" + +#: ../share/extensions/interp.inx.h:2 +#, fuzzy +msgid "Exponent" +msgstr "Экспартаваць" + +#: ../share/extensions/interp.inx.h:3 +msgid "Interpolate" +msgstr "" + +#: ../share/extensions/interp.inx.h:4 +msgid "Interpolate Style (Experimental)" +msgstr "" + +#: ../share/extensions/interp.inx.h:5 +msgid "Interpolation Method" +msgstr "" + +#: ../share/extensions/interp.inx.h:6 +msgid "Interpolation Steps" +msgstr "" + +#: ../share/extensions/kochify.inx.h:1 +msgid "Kochify" +msgstr "" + +#: ../share/extensions/kochify_load.inx.h:1 +msgid "Kochify (Load)" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:1 +#, fuzzy +msgid "Angle" +msgstr "Кут" + +#: ../share/extensions/lindenmayer.inx.h:2 +msgid "Axiom" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:3 +#, fuzzy +msgid "Lindenmayer" +msgstr "Падняць вузел" + +#: ../share/extensions/lindenmayer.inx.h:4 +msgid "Order" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:5 +#, fuzzy +msgid "Rules" +msgstr "Фільтары" + +#: ../share/extensions/lindenmayer.inx.h:6 +#, fuzzy +msgid "Step" +msgstr "Стыль" + +#: ../share/extensions/motion.inx.h:1 +#, fuzzy +msgid "Direction" +msgstr "Вылучэньне" + +#: ../share/extensions/motion.inx.h:2 +#, fuzzy +msgid "Magnitude" +msgstr "Малінавы:" + +#: ../share/extensions/motion.inx.h:3 +#, fuzzy +msgid "Motion" +msgstr "Разрозьненьне:" + +#: ../share/extensions/pdf_output.inx.h:1 +msgid "Adobe PDF (*.pdf)" +msgstr "" + +#: ../share/extensions/pdf_output.inx.h:2 +msgid "Adobe Portable Document Format" +msgstr "" + +#: ../share/extensions/pdf_output.inx.h:3 +#, fuzzy +msgid "PDF Output" +msgstr "-" + +#: ../share/extensions/ps_input.inx.h:1 +#, fuzzy +msgid "Postscript" +msgstr "Пункт" + +#: ../share/extensions/ps_input.inx.h:2 +msgid "Postscript (*.ps)" +msgstr "" + +#: ../share/extensions/ps_input.inx.h:3 +msgid "Postscript Input" +msgstr "" + +#: ../share/extensions/radiusrand.inx.h:1 +#, fuzzy +msgid "Radius" +msgstr "Радыюс:" + +#: ../share/extensions/radiusrand.inx.h:2 +#, fuzzy +msgid "Radius Randomize" +msgstr "Падняць вузел" + +#: ../share/extensions/radiusrand.inx.h:3 +msgid "Randomize Control Points" +msgstr "" + +#: ../share/extensions/radiusrand.inx.h:4 +#, fuzzy +msgid "Randomize Nodes" +msgstr "Падняць вузел" + +#: ../share/extensions/rtree.inx.h:1 +#, fuzzy +msgid "Initial Size" +msgstr "Памер кропкавага відарыса" + +#: ../share/extensions/rtree.inx.h:2 +msgid "Minimum Size" +msgstr "" + +#: ../share/extensions/rtree.inx.h:3 +msgid "Random Tree" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:1 +msgid "A diagram created with the program Sketch" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:2 +msgid "Sketch Diagram (*.sk)" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:3 +msgid "Sketch Input" +msgstr "" + +#: ../share/extensions/straightseg.inx.h:1 +msgid "Behavior" +msgstr "" + +#: ../share/extensions/straightseg.inx.h:3 +msgid "Segment Straightener" +msgstr "" + +#: ../share/extensions/summersnight.inx.h:1 +msgid "Summer's Night" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:1 +#: ../share/extensions/svgz_output.inx.h:1 +msgid "Compressed Inkscape SVG (*.svgz)" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:2 +#: ../share/extensions/svgz_output.inx.h:2 +#, fuzzy +msgid "Inkscape's native file format compressed with GZip" +msgstr "Уласны фармат файлаў Sodipodi й стандарт W3C" + +#: ../share/extensions/svgz_input.inx.h:3 +#, fuzzy +msgid "SVGZ Input" +msgstr "Увод" + +#: ../share/extensions/svgz_output.inx.h:3 +#, fuzzy +msgid "SVGZ Output" +msgstr "-" + +#: ../share/extensions/txt2svg.inx.h:1 +msgid "ASCII Text" +msgstr "" + +#: ../share/extensions/txt2svg.inx.h:2 +msgid "Text File (*.txt)" +msgstr "" + +#: ../share/extensions/txt2svg.inx.h:3 +#, fuzzy +msgid "Text Input" +msgstr "Увод" + +#: ../share/extensions/wavy.inx.h:1 +msgid "Calculate first derivative numerically" +msgstr "" + +#: ../share/extensions/wavy.inx.h:2 +msgid "First derivative" +msgstr "" + +#: ../share/extensions/wavy.inx.h:3 +msgid "Function" +msgstr "" + +#: ../share/extensions/wavy.inx.h:4 +msgid "Function Plotter" +msgstr "" + +#: ../share/extensions/wavy.inx.h:5 +msgid "Nodes per period" +msgstr "" + +#: ../share/extensions/wavy.inx.h:6 +msgid "Periods (2*Pi each)" +msgstr "" + +#: ../share/extensions/whirl.inx.h:1 +msgid "Amount of Whirl" +msgstr "" + +#: ../share/extensions/whirl.inx.h:2 +#, fuzzy +msgid "Center X" +msgstr "Цэнтар X:" + +#: ../share/extensions/whirl.inx.h:3 +#, fuzzy +msgid "Center Y" +msgstr "Цэнтар Y:" + +#: ../share/extensions/whirl.inx.h:4 +#, fuzzy +msgid "Direction of Rotation" +msgstr "Апускае вылучаныя аб'екты на ніжні слой" + +#: ../share/extensions/whirl.inx.h:5 +msgid "Whirl" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:1 +msgid "A popular graphics file format for clipart" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:2 +msgid "Windows Metafile (*.wmf)" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:3 +msgid "Windows Metafile Input" +msgstr "" + +#, fuzzy +#~ msgid "_Credits" +#~ msgstr "Куты:" + +#, fuzzy +#~ msgid "Canvas size:" +#~ msgstr "Памер шрыфта:" + +#, fuzzy +#~ msgid "Custom canvas" +#~ msgstr "Папера карыстальніка" + +#, fuzzy +#~ msgid "Current style" +#~ msgstr "Наладкі штрыхоўкі" + +#, fuzzy +#~ msgid "Arrange Objects" +#~ msgstr "Раўнаньне аб'ектаў" + +#~ msgid "deg" +#~ msgstr "град" + +#, fuzzy +#~ msgid "Grab sensitivity" +#~ msgstr "Зрабіць чулым" + +#, fuzzy +#~ msgid "Acceleration" +#~ msgstr "Вылучэньне" + +#, fuzzy +#~ msgid "Speed" +#~ msgstr "Чырвоны:" + +#, fuzzy +#~ msgid "Zoom in/out by" +#~ msgstr "Памяншае маштаб рысунка" + +#, fuzzy +#~ msgid "Transform" +#~ msgstr "Трансфармаваньне:" + +#, fuzzy +#~ msgid "Rotate _90 deg CW" +#~ msgstr "Павярнуць на 90°" + +#, fuzzy +#~ msgid "Rotate 9_0 deg CCW" +#~ msgstr "Павярнуць на 90°" + +#, fuzzy +#~ msgid "Flip selection horizontally" +#~ msgstr "Адлюстроўвае вылучаны аб'ект гарызантальна" + +#, fuzzy +#~ msgid "Flip selection vertically" +#~ msgstr "Адлюстроўвае вылучаныя аб'екты вэртыкальна" + +#~ msgid "Edit" +#~ msgstr "Рэдагаваньне" + +#~ msgid "Add" +#~ msgstr "Дадаць" + +#, fuzzy +#~ msgid "C_reate" +#~ msgstr "Стварыць" + +#, fuzzy +#~ msgid "Automatically scale Rows to fit selected objects." +#~ msgstr "Выдаляе вылучаныя аб'екты" + +#, fuzzy +#~ msgid "Go to root" +#~ msgstr "Рэдагаваньне" + +#, fuzzy +#~ msgid "X" +#~ msgstr "X:" + +#, fuzzy +#~ msgid "Y" +#~ msgstr "Y:" + +#~ msgid "Sides:" +#~ msgstr "Бакі:" + +#~ msgid "R1:" +#~ msgstr "R1:" + +#~ msgid "R2:" +#~ msgstr "R2:" + +#~ msgid "ARG1:" +#~ msgstr "АРГ1:" + +#~ msgid "ARG2:" +#~ msgstr "АРГ2:" + +#, fuzzy +#~ msgid "Flatsides:" +#~ msgstr "Бакі:" + +#, fuzzy +#~ msgid "Radius X:" +#~ msgstr "Радыюс:" + +#, fuzzy +#~ msgid "Radius Y:" +#~ msgstr "Радыюс:" + +#, fuzzy +#~ msgid "Start Angle:" +#~ msgstr "Зорка" + +#, fuzzy +#~ msgid "End Angle:" +#~ msgstr "Кут:" + +#, fuzzy +#~ msgid "Open:" +#~ msgstr "Адкрыць" + +#~ msgid "Expansion:" +#~ msgstr "Пашырэньне:" + +#, fuzzy +#~ msgid "Revolutions:" +#~ msgstr "Абарот:" + +#~ msgid "Argument:" +#~ msgstr "Аргумэнт:" + +#~ msgid "T0:" +#~ msgstr "T0:" + +#~ msgid "RX:" +#~ msgstr "RX:" + +#~ msgid "RY:" +#~ msgstr "RY:" + +#, fuzzy +#~ msgid "Rectangle _Properties" +#~ msgstr "Уласьцівасьці прамакутніка" + +#, fuzzy +#~ msgid "Star _Properties" +#~ msgstr "Уласьцівасьці зоркі" + +#, fuzzy +#~ msgid "Ellipse _Properties" +#~ msgstr "Уласьцівасьці лучыва" + +#, fuzzy +#~ msgid "Spiral _Properties" +#~ msgstr "Уласьцівасьці сьпіралі" + +#, fuzzy +#~ msgid "Document Preferences" +#~ msgstr "Элемэнт зьяўляецца спасылкай" + +#, fuzzy +#~ msgid "Extensions Editor" +#~ msgstr "Пашырэньне" + +#, fuzzy +#~ msgid "Preferences" +#~ msgstr "Элемэнт зьяўляецца спасылкай" + +#, fuzzy +#~ msgid "Layer Editor" +#~ msgstr "Рэдактар XML" + +#, fuzzy +#~ msgid "Text Properties" +#~ msgstr "Уласьцівасьці тэкста" + +#, fuzzy +#~ msgid "Transformation" +#~ msgstr "Матрыца трансфармаваньня" + +#, fuzzy +#~ msgid "_Export..." +#~ msgstr "Імпартаваць" + +#, fuzzy +#~ msgid "_Document Properties" +#~ msgstr "Уласьцівасьці дакумэнта" + +#, fuzzy +#~ msgid "In_kscape Preferences" +#~ msgstr "Слайдшоў Sodipodi" + +#, fuzzy +#~ msgid "Select _Original Clone" +#~ msgstr "Вылучыць усё" + +#, fuzzy +#~ msgid "Tile" +#~ msgstr "Назва:" + +#, fuzzy +#~ msgid "Select A_ll" +#~ msgstr "Вылучыць усё" + +#, fuzzy +#~ msgid "Select Non_e" +#~ msgstr "Вылучэньне" + +#, fuzzy +#~ msgid "Zoom _In" +#~ msgstr "Маштабаваньне" + +#, fuzzy +#~ msgid "Zoom _Out" +#~ msgstr "Памяншае маштаб рысунка" + +#, fuzzy +#~ msgid "Pre_vious" +#~ msgstr "Стварыць новае акно рэдагаваньня" + +#, fuzzy +#~ msgid "Nex_t" +#~ msgstr "Тэкст" + +#, fuzzy +#~ msgid "Tool Co_ntrols bar" +#~ msgstr "Выбары інструмэнта" + +#, fuzzy +#~ msgid "R_ename Layer..." +#~ msgstr "Падняць вузел" + +#, fuzzy +#~ msgid "D_uplicate Layer" +#~ msgstr "Падвоіць вузел" + +#, fuzzy +#~ msgid "_Anchor Layer" +#~ msgstr "Апусьціць вузел" + +#, fuzzy +#~ msgid "_Delete Layer" +#~ msgstr "Вылучэньне" + +#, fuzzy +#~ msgid "Select Ne_xt Layer" +#~ msgstr "Вылучэньне" + +#, fuzzy +#~ msgid "Select Pre_vious Layer" +#~ msgstr "Выбярыце друкарку" + +#, fuzzy +#~ msgid "Select To_p Layer" +#~ msgstr "Выбярыце друкарку" + +#, fuzzy +#~ msgid "Move to Ne_w Layer" +#~ msgstr "Стварае новы дакумэнт SVG" + +#, fuzzy +#~ msgid "Move to B_ottom Layer" +#~ msgstr "Апускае вылучаныя аб'екты на ніжні слой" + +#, fuzzy +#~ msgid "_Trace Bitmap..." +#~ msgstr "Друкаваць як кропкавы відарыс" + +#, fuzzy +#~ msgid "_Put Text on Path" +#~ msgstr "Апускае вылучаныя аб'екты на ніжні слой" + +#, fuzzy +#~ msgid "_Remove Text from Path" +#~ msgstr "Апускае вылучаныя аб'екты на ніжні слой" + +#~ msgid "Arc" +#~ msgstr "Дуга" + +#, fuzzy +#~ msgid "Freehand" +#~ msgstr "Вольныя рысы й пяро" + +#, fuzzy +#~ msgid "DynaDraw" +#~ msgstr "Рысаваньне" + +#, fuzzy +#~ msgid "Corners" +#~ msgstr "Куты:" + +#, fuzzy +#~ msgid "Delete" +#~ msgstr "Выдаліць" + +#, fuzzy +#~ msgid "Join" +#~ msgstr "Далучэньне:" + +#, fuzzy +#~ msgid "Delete Segment" +#~ msgstr "Выдаляе вылучаныя вузлы" + +#, fuzzy +#~ msgid "Break" +#~ msgstr "Чорны:" + +#, fuzzy +#~ msgid "New" +#~ msgstr "Стварыць" + +#, fuzzy +#~ msgid "Revert to Saved" +#~ msgstr "Канвэртуе аб'ект у дугу" + +#, fuzzy +#~ msgid "Save" +#~ msgstr "Захаваць" + +#, fuzzy +#~ msgid "Save As..." +#~ msgstr "Захаваць як" + +#, fuzzy +#~ msgid "Import..." +#~ msgstr "Імпартаваць" + +#, fuzzy +#~ msgid "Export..." +#~ msgstr "Экспартаваць" + +#, fuzzy +#~ msgid "Print..." +#~ msgstr "Друк..." + +#, fuzzy +#~ msgid "Global Inkscape preferences (Shift+Ctrl+P)" +#~ msgstr "Глябальныя наладкі дысплэя" + +#, fuzzy +#~ msgid "Undo" +#~ msgstr "Адкаціцца" + +#, fuzzy +#~ msgid "Redo" +#~ msgstr "Вярнуцца" + +#, fuzzy +#~ msgid "Cut" +#~ msgstr "Выразаць" + +#, fuzzy +#~ msgid "Copy" +#~ msgstr "Капіяваць" + +#, fuzzy +#~ msgid "Duplicate selected object(s) (Ctrl+D)" +#~ msgstr "Падвойвае вылучаныя аб'екты" + +#, fuzzy +#~ msgid "Clone selected object (Alt+D)" +#~ msgstr "Падвойвае вылучаныя аб'екты" + +#, fuzzy +#~ msgid "Zoom in (+)" +#~ msgstr "Маштабаваньне" + +#, fuzzy +#~ msgid "Zoom out (-)" +#~ msgstr "Памяншае маштаб рысунка" + +#, fuzzy +#~ msgid "Zoom to 1:1 (100%) (1)" +#~ msgstr "Усталёўвае маштаб 1:1" + +#, fuzzy +#~ msgid "Zoom to 1:2 (50%) (2)" +#~ msgstr "Усталёўвае маштаб 2:1" + +#, fuzzy +#~ msgid "Zoom to 2:1 (200%) (0)" +#~ msgstr "Усталёўвае маштаб 2:1" + +#, fuzzy +#~ msgid "Zoom to fit selection in window (3)" +#~ msgstr "Запаўняе вылучэньнем усё акно" + +#, fuzzy +#~ msgid "Zoom to fit drawing in window (4)" +#~ msgstr "Запаўняе рысаваньнем усё акно" + +#, fuzzy +#~ msgid "Zoom to fit page in window (5)" +#~ msgstr "Запаўняе акно усёй старонкай" + +#, fuzzy +#~ msgid "Zoom to fit page width in window (6)" +#~ msgstr "Запаўняе акно усёй старонкай" + +#, fuzzy +#~ msgid "Fill and Stroke dialog (Shift+Ctrl+F)" +#~ msgstr "Запаўненьне й штрыхоўка" + +#, fuzzy +#~ msgid "Group selected objects (Ctrl+G)" +#~ msgstr "Групуе вылучаныя аб'екты" + +#, fuzzy +#~ msgid "Ungroup selected group(s) (Ctrl+U)" +#~ msgstr "Разгрупоўвае вылучаныя аб'екты" + +#, fuzzy +#~ msgid "Raise selection up one step (PgUp)" +#~ msgstr "Падымае вылучаныя аб'екты на верхні слой" + +#, fuzzy +#~ msgid "Lower selection down one step (PgDn)" +#~ msgstr "Апускае вылучаныя аб'екты на адзін узровень" + +#, fuzzy +#~ msgid "Raise selection to top (Home)" +#~ msgstr "Падымае вылучаныя аб'екты на верхні слой" + +#, fuzzy +#~ msgid "Lower selection to bottom (End)" +#~ msgstr "Апускае вылучаныя аб'екты на ніжні слой" + +#, fuzzy +#~ msgid "Move selection to new layer" +#~ msgstr "Апускае вылучаныя аб'екты на адзін узровень" + +#, fuzzy +#~ msgid "Move selection to next layer" +#~ msgstr "Апускае вылучаныя аб'екты на адзін узровень" + +#, fuzzy +#~ msgid "Move selection to previous layer" +#~ msgstr "Капуе вылучаныя аб'екты ў буфэр абмену" + +#, fuzzy +#~ msgid "Move selection to top layer" +#~ msgstr "Падымае вылучаныя аб'екты на верхні слой" + +#, fuzzy +#~ msgid "Move selection to bottom layer" +#~ msgstr "Апускае вылучаныя аб'екты на ніжні слой" + +#, fuzzy +#~ msgid "Rotate selection 90° clockwise (Shift+Ctrl+Right)" +#~ msgstr "Паварочвае аб'ект на 90° па сонцу" + +#, fuzzy +#~ msgid "Rotate selection 90° counter-clockwise (Shift+Ctrl+Left)" +#~ msgstr "Паварочвае аб'ект на 90° па сонцу" + +#, fuzzy +#~ msgid "Flip selection horizontally (H)" +#~ msgstr "Адлюстроўвае вылучаны аб'ект гарызантальна" + +#, fuzzy +#~ msgid "Flip selection vertically (V)" +#~ msgstr "Адлюстроўвае вылучаныя аб'екты вэртыкальна" + +#, fuzzy +#~ msgid "Align and Distribute dialog (Shift+Ctrl+A)" +#~ msgstr "Раўнаньне й прадстаўленьне" + +#, fuzzy +#~ msgid "Convert selected object(s) to path(s) (Shift+Ctrl+C)" +#~ msgstr "Апускае вылучаныя аб'екты на ніжні слой" + +#, fuzzy +#~ msgid "Convert selected stroke(s) to path(s) (Ctrl+Alt+C)" +#~ msgstr "Апускае вылучаныя аб'екты на ніжні слой" + +#, fuzzy +#~ msgid "Cl_eanup" +#~ msgstr "Ачысьціць" + +#, fuzzy +#~ msgid "Text and Font dialog (Shift+Ctrl+T)" +#~ msgstr "Тэкст і шрыфт" + +#, fuzzy +#~ msgid "Node tool" +#~ msgstr "Няма актыўных інструмэнтаў" + +#, fuzzy +#~ msgid "Zoom tool" +#~ msgstr "Памяншае маштаб рысунка" + +#~ msgid "Rectangle tool" +#~ msgstr "Інструмэнт прамакутніка" + +#~ msgid "Arc tool" +#~ msgstr "Інструмэнт дугі" + +#~ msgid "Star tool" +#~ msgstr "Інструмэнт зоркі" + +#~ msgid "Spiral tool" +#~ msgstr "Інструмэнт спіралі" + +#, fuzzy +#~ msgid "Freehand tool" +#~ msgstr "Вольныя рысы й пяро" + +#, fuzzy +#~ msgid "Pen tool" +#~ msgstr "Інструмэнт прамакутніка" + +#, fuzzy +#~ msgid "Calligraphy tool" +#~ msgstr "Каліграфія" + +#, fuzzy +#~ msgid "Text tool" +#~ msgstr "Інструмэнт зоркі" + +#, fuzzy +#~ msgid "Dropper tool" +#~ msgstr "Піпетка" + +#, fuzzy +#~ msgid "Delete segment between two nodes" +#~ msgstr "Выдаляе вылучаныя вузлы" + +#, fuzzy +#~ msgid "URI:" +#~ msgstr "URL:" + +#, fuzzy +#~ msgid "Select All in All Layers" +#~ msgstr "Вылучэньне" + +#, fuzzy +#~ msgid "Invert Selection" +#~ msgstr "Вылучэньне" + +#, fuzzy +#~ msgid "Clean up selected path(s)" +#~ msgstr "Апускае вылучаныя аб'екты на ніжні слой" + +#, fuzzy +#~ msgid "_Scripts..." +#~ msgstr "Друк..." + +#, fuzzy +#~ msgid "Align and Distribute" +#~ msgstr "Раўнаньне й прадстаўленьне" + +#, fuzzy +#~ msgid "Align and Distribute Dialog" +#~ msgstr "Раўнаньне й прадстаўленьне" + +#, fuzzy +#~ msgid "Export Dialog" +#~ msgstr "Прастора экспартаваньня" + +#, fuzzy +#~ msgid "Fill and Stroke Dialog" +#~ msgstr "Запаўненьне й штрыхоўка" + +#, fuzzy +#~ msgid "Find Dialog" +#~ msgstr "Запаўненьне й штрыхоўка" + +#, fuzzy +#~ msgid "Inkscape Preferences" +#~ msgstr "Слайдшоў Sodipodi" + +#, fuzzy +#~ msgid "Inkscape Preferences Dialog" +#~ msgstr "Слайдшоў Sodipodi" + +#, fuzzy +#~ msgid "Layer Editor Dialog" +#~ msgstr "Падымае вылучаныя аб'екты на верхні слой" + +#, fuzzy +#~ msgid "Text Properties Dialog" +#~ msgstr "Уласьцівасьці прамакутніка" + +#, fuzzy +#~ msgid "Transformation Dialog" +#~ msgstr "Трансфармаваньне вылучэньня" + +#, fuzzy +#~ msgid "Tree Editor" +#~ msgstr "Рэдактар XML" + +#, fuzzy +#~ msgid "XML Editor Dialog" +#~ msgstr "Рэдактар XML" + +#, fuzzy +#~ msgid "Row height:" +#~ msgstr "Вышыня:" + +#, fuzzy +#~ msgid "Column width:" +#~ msgstr "Эліпс" + +#, fuzzy +#~ msgid "EPS Output Settings" +#~ msgstr "Уласьцівасьці дакумэнта" + +#, fuzzy +#~ msgid "Inkscape" +#~ msgstr "Слайдшоў Sodipodi" + +#~ msgid "Left side of aligned objects to left side of anchor" +#~ msgstr "Левы бок аб'екта ў левы бок якара" + +#~ msgid "Right side of aligned objects to right side of anchor" +#~ msgstr "Правы бок аб'екта ў правы бок якара" + +#~ msgid "Top of aligned objects to top of anchor" +#~ msgstr "Верх аб'екта ў верх якара" + +#, fuzzy +#~ msgid "Alternate sign" +#~ msgstr "Насычанасьць:" + +#, fuzzy +#~ msgid "Minor grid line color:" +#~ msgstr "Колер кіруючых рысаў" + +#~ msgid "Grid color" +#~ msgstr "Колер сеткі" + +#, fuzzy +#~ msgid "Grid emphasis color" +#~ msgstr "Колер сеткі" + +#, fuzzy +#~ msgid "Background (also for export):" +#~ msgstr "Канчатковы колер" + +#, fuzzy +#~ msgid "Picking colors:" +#~ msgstr "Колер падсьвятленьня:" + +#~ msgid "Fill style" +#~ msgstr "Стыль запаўненьня" + +#, fuzzy +#~ msgid "Fill:" +#~ msgstr "Запаўненьне" + +#, fuzzy +#~ msgid "winding" +#~ msgstr "Вывад" + +#, fuzzy +#~ msgid "alternating" +#~ msgstr "Насычанасьць:" + +#, fuzzy +#~ msgid "Update Properties" +#~ msgstr "Уласьцівасьці элемэнта" + +#, fuzzy +#~ msgid "Label invalid" +#~ msgstr "Правільны ID" + +#, fuzzy +#~ msgid "executable" +#~ msgstr "Прамакутнік" + +#, fuzzy +#~ msgid "file" +#~ msgstr "Файл" + +#, fuzzy +#~ msgid "extension" +#~ msgstr "Пашырэньне" + +#, fuzzy +#~ msgid "path" +#~ msgstr "pt" + +#, fuzzy +#~ msgid "absolute" +#~ msgstr "Значэньне" + +#~ msgid "Could not create sodipodi-svg-doc factory" +#~ msgstr "Немагчыма стварыць вытворчасьць sodipodi-svg-doc" + +#~ msgid "Plain SVG" +#~ msgstr "Звычайны SVG" + +#, fuzzy +#~ msgid "Make s_ensitive" +#~ msgstr "Зрабіць чулым" + +#, fuzzy +#~ msgid "Make i_nsensitive" +#~ msgstr "Зрабіць нячулым" + +#, fuzzy +#~ msgid "Layer Properties" +#~ msgstr "Уласьцівасьці зоркі" + +#, fuzzy +#~ msgid "Select object(s) to tile." +#~ msgstr "Выразае вылучаныя аб'екты ў буфэр абмену" + +#, fuzzy +#~ msgid "Apply" +#~ msgstr "Ужыць да:" + +#~ msgid "Sensitive" +#~ msgstr "Чулы" + +#~ msgid "Active" +#~ msgstr "Актыўны" + +#~ msgid "Printable" +#~ msgstr "Здольны друкавацца" + +#~ msgid "Trace" +#~ msgstr "Трасыраваць" + +#, fuzzy +#~ msgid "Error writing %s: %s" +#~ msgstr "Памылка запісу %s: %s" + +#~ msgid "Untitled" +#~ msgstr "Бяз назвы" + +#~ msgid "Document Name:" +#~ msgstr "Назва дакумэнта:" + +#~ msgid "Image URI:" +#~ msgstr "URI відарыса:" + +#~ msgid "Visible" +#~ msgstr "Бачны" + +#, fuzzy +#~ msgid "Drag to paint a calligraphic stroke." +#~ msgstr "Каліграфічная рыса" + +#, fuzzy +#~ msgid "Flatness:" +#~ msgstr "Бакі:" + +#, fuzzy +#~ msgid "Other" +#~ msgstr "Парадак" + +#, fuzzy +#~ msgid "Trace: Selected object is not an image" +#~ msgstr "Падымае вылучаныя аб'екты на адзін узровень" + +#, fuzzy +#~ msgid "object" +#~ msgstr "Аб'ект" + +#, fuzzy +#~ msgid "user space" +#~ msgstr "Адзінка прасторы карыстальніка" + +#, fuzzy +#~ msgid "Coordinates:" +#~ msgstr "Куты:" + +#~ msgid "Alignment:" +#~ msgstr "Раўнаньне:" + +#~ msgid "Text and font" +#~ msgstr "Тэкст і шрыфт" + +#~ msgid "All shape tools" +#~ msgstr "Усе інструмэнты формы" + +#, fuzzy +#~ msgid "Move by %s, %s" +#~ msgstr "Перанесьці" + +#, fuzzy +#~ msgid "Active group" +#~ msgstr "Актыўны" + +#, fuzzy +#~ msgid "typeset object" +#~ msgstr "Аб'ект тэкста" + +#, fuzzy +#~ msgid "Pattern Fill" +#~ msgstr "Узор:" + +#~ msgid "Snap to grid" +#~ msgstr "Раўнаць па сетке" + +#~ msgid "Snap to guides" +#~ msgstr "Раўнаць па кіруючых" + +#, fuzzy +#~ msgid "_Menu" +#~ msgstr "Ачысьціць" + +#, fuzzy +#~ msgid "Snap points to the grid" +#~ msgstr "Раўнаць па сетке" + +#, fuzzy +#~ msgid "Rect" +#~ msgstr "Прамакутнік" + +#~ msgid "meters" +#~ msgstr "мэтры" + +#~ msgid "Userspace unit" +#~ msgstr "Адзінка прасторы карыстальніка" + +#~ msgid "User" +#~ msgstr "Карыстальнік" + +#~ msgid "Userspace units" +#~ msgstr "Адзінкі прасторы карыстальніка" + +#, fuzzy +#~ msgid "Ru_lers" +#~ msgstr "Фільтары" + +#, fuzzy +#~ msgid "Show or hide rulers" +#~ msgstr "Паказаць кіруючыя" + +#~ msgid "Mode:" +#~ msgstr "Рэжым:" + +#~ msgid "RGB Colorspace" +#~ msgstr "Каляровая прастора RGB" + +#, fuzzy +#~ msgid "CMYK Colorspace" +#~ msgstr "Каляровая прастора CMYK" + +#~ msgid "Get from dropper" +#~ msgstr "Атрымаць праз піпетку" + +#~ msgid "Alpha:" +#~ msgstr "Альфа:" + +#~ msgid "Value:" +#~ msgstr "Значэньне:" + +#~ msgid "Stroke settings" +#~ msgstr "Наладкі штрыхоўкі" + +#~ msgid "Item properties" +#~ msgstr "Уласьцівасьці элемэнта" + +#~ msgid "Combine multiple paths" +#~ msgstr "Камбінуе шмат шляхоў" + +#, fuzzy +#~ msgid "New View" +#~ msgstr "Стварыць новае акно рэдагаваньня" + +#~ msgid "Fill and stroke settings" +#~ msgstr "Усталёўкі запаўненьня й штрыхоўкі" + +#~ msgid "Object transformations" +#~ msgstr "Трансфармуе аб'ект" + +#, fuzzy +#~ msgid "Align and distribute objects" +#~ msgstr "Раўнаньне й прадстаўленьне" + +#~ msgid "Text editing and font settings" +#~ msgstr "Рэдагаваньне тэкста й наладкі шрыфта" + +#~ msgid "Fill Rule" +#~ msgstr "Правіла запаўненьня" + +#~ msgid "Tool has no options" +#~ msgstr "Інструмэнт ня мае выбараў" + +#~ msgid "Roundness ratio for x:" +#~ msgstr "Каэфіцэнт акругленьня для х:" + +#~ msgid "Roundness ratio for y:" +#~ msgstr "Каэфіцэнт акругленьня для y:" + +#~ msgid "Visual transformation" +#~ msgstr "Візуальная трансфармацыя" + +#~ msgid "Show content" +#~ msgstr "Паказаць зьмест" + +#, fuzzy +#~ msgid "Selected object has no curve, cannot outline." +#~ msgstr "Выразае вылучаныя аб'екты ў буфэр абмену" + +#, fuzzy +#~ msgid "Inkscape _Options" +#~ msgstr "Слайдшоў Sodipodi" + +#, fuzzy +#~ msgid "Tool Optio_ns" +#~ msgstr "Выбары інструмэнтаў" + +#~ msgid "gradientUnits" +#~ msgstr "Прастора градыента:" + +#~ msgid "gradientSpread" +#~ msgstr "Распаўсюд градыента:" + +#~ msgid "nonzero" +#~ msgstr "ненулявы" + +#~ msgid "evenodd" +#~ msgstr "не запаўняць" + +#, fuzzy +#~ msgid "" +#~ "%s is not regular file.\n" +#~ "Although inkscape will run, you can\n" +#~ "neither load nor save preferences\n" +#~ msgstr "" +#~ "%s незвычайны файл.\n" +#~ "Хаця sodipodi працуе, вы не \n" +#~ "здольныя загрузіць ці захаваць\n" +#~ "перавагі\n" + +#, fuzzy +#~ msgid "" +#~ "%s either is not valid xml file or\n" +#~ "you do not have read premissions on it.\n" +#~ "Although inkscape will run, you\n" +#~ "are neither able to load nor save\n" +#~ "preferences." +#~ msgstr "" +#~ "%s нерэчаісны файл xml ці вы\n" +#~ "не маеце правоў на чытаньне.\n" +#~ "Хаця sodipodi працуе, вы не \n" +#~ "здольныя загрузіць ці захаваць\n" +#~ "перавагі." + +#, fuzzy +#~ msgid "" +#~ "%s is not valid inkscape preferences file.\n" +#~ "Although inkscape will run, you\n" +#~ "are neither able to load nor save\n" +#~ "preferences." +#~ msgstr "" +#~ "%s нерэчаісны файл перавагаў\n" +#~ "sodipodi. Хаця sodipodi працуе,\n" +#~ "вы не здольныя загрузіць ці \n" +#~ "захаваць перавагі." + +#, fuzzy +#~ msgid "" +#~ "Cannot create directory %s.\n" +#~ "Although inkscape will run, you\n" +#~ "are neither able to load nor save\n" +#~ "%s." +#~ msgstr "" +#~ "Немагчыма стварыць тэчку %s.\n" +#~ "Хаця sodipodi працуе, вы не \n" +#~ "здольныя загрузіць ці захаваць\n" +#~ "%s." + +#, fuzzy +#~ msgid "" +#~ "%s is not a valid directory.\n" +#~ "Although inkscape will run, you\n" +#~ "are neither able to load nor save\n" +#~ "preferences." +#~ msgstr "" +#~ "%s нерэчаісная тэчка.\n" +#~ "Хаця sodipodi працуе, вы не \n" +#~ "здольныя загрузіць ці захаваць\n" +#~ "перавагі." + +#, fuzzy +#~ msgid "" +#~ "Cannot create file %s.\n" +#~ "Although inkscape will run, you\n" +#~ "are neither able to load nor save\n" +#~ "preferences." +#~ msgstr "" +#~ "Немагчыма стварыць файл %s.\n" +#~ "Хаця sodipodi працуе, вы не \n" +#~ "здольныя загрузіць ці захаваць\n" +#~ "перавагі." + +#, fuzzy +#~ msgid "" +#~ "Cannot write file %s.\n" +#~ "Although inkscape will run, you\n" +#~ "are neither able to load nor save\n" +#~ "preferences." +#~ msgstr "" +#~ "Немагчыма захаваць файл %s.\n" +#~ "Хаця sodipodi працуе, вы не \n" +#~ "здольныя загрузіць ці захаваць\n" +#~ "перавагі." + +#~ msgid "Make sides flat" +#~ msgstr "Рабіць бакі плоскімі" + +#, fuzzy +#~ msgid "Bring to _Front" +#~ msgstr "Даслаць угору" + +#, fuzzy +#~ msgid "Send to _Back" +#~ msgstr "Даслаць долу" + +#~ msgid "Toggle separate window and main toolbox placement" +#~ msgstr "Пераключыць падзеленае акно й разьмяшчэньне панэлі інструмэнтаў" + +#~ msgid "Document %s has unsaved changes, save them?" +#~ msgstr "Дакумэнт %s мае незахаваныя зьмены, захаваць іх?" + +#, fuzzy +#~ msgid "Object Size and Position" +#~ msgstr "Памер і пазыцыя аб'екта" + +#~ msgid "Size and Position" +#~ msgstr "Памер і пазыцыя" + +#~ msgid "Tool attributes" +#~ msgstr "Атрыбуты інструмэнта" + +#~ msgid "Inner radius" +#~ msgstr "Нутраны радыюс" + +#~ msgid "Proportion" +#~ msgstr "Прапорцыі" + +#~ msgid "Tool has no attributes" +#~ msgstr "Інструмэет ня мае атрыбутаў" + +#~ msgid "Item" +#~ msgstr "Элемэнт" + +#~ msgid "Group Properties" +#~ msgstr "Уласьцівасьці групы" + +#~ msgid "Fill settings" +#~ msgstr "Наладкі запаўненьня" + +#, fuzzy +#~ msgid "Lower selected objects one position" +#~ msgstr "Апускае вылучаныя аб'екты на ніжні слой" + +#, fuzzy +#~ msgid "Zoom into precisely selected area" +#~ msgstr "Павялічвае маштаб дакладна вылучанае прасторы" + +#~ msgid "In" +#~ msgstr "+" + +#, fuzzy +#~ msgid "Toggle grid" +#~ msgstr "Паказаць сетку" + +#, fuzzy +#~ msgid "Toggle guides" +#~ msgstr "Паказаць кіруючыя" + +#~ msgid "1:1" +#~ msgstr "1:1" + +#~ msgid "1:2" +#~ msgstr "1:2" + +#~ msgid "2:1" +#~ msgstr "2:1" + +#~ msgid "Editing Window" +#~ msgstr "Акно рэдагаваньня" + +#~ msgid "Editing window properties" +#~ msgstr "Уласьцівасьці акна рэдагаваньня" + +#~ msgid "Tool Attributes" +#~ msgstr "Атрыбуты інструмэнтаў" + +#~ msgid "Sodipodi" +#~ msgstr "Sodipodi" + +#~ msgid "Desktop settings" +#~ msgstr "Акно рэдагаваньня" + +#, fuzzy +#~ msgid "Iso grid" +#~ msgstr "Паказаць сетку" + +#~ msgid "Display settings" +#~ msgstr "Уласьцівасьці дысплэя" + +#~ msgid "Export png file" +#~ msgstr "Экспартуе файл png" + +#~ msgid "Object style" +#~ msgstr "Запаўненьне й штрыхоўка" + +#, fuzzy +#~ msgid "Inkscape: %s : XML View" +#~ msgstr "Sodipodi: %s : рэдактар XML" + +#, fuzzy +#~ msgid "Appending to selection. Press 'a' to toggle Append/New." +#~ msgstr "" +#~ "Дадае да вылучэньня. Націсьніце '+' каб пераключыцца паміж \"Дадаць\" і " +#~ "\"Стварыць\"." + +#~ msgid "Scalable Vector Graphic (SVG)" +#~ msgstr "Здольная маштабавацца вэктарная графіка (SVG)" + +#~ msgid "Exit Program" +#~ msgstr "Выйсьці з праграмы" + +#~ msgid "New Toplevel Toolbox" +#~ msgstr "Стварыць верхнюю панэлю інструмэнтаў" + +#~ msgid "New Docked Toolbox" +#~ msgstr "Стварыць прычэпленую панэлю інструмэнтаў" + +#~ msgid "Remove Docked Toolbox" +#~ msgstr "Выдаліць прычэпленую панэлю інструмэнта" + +#~ msgid "Drawing Mode" +#~ msgstr "Рэжым рысаваньня" + +#~ msgid "SVG with \"xmlns:sodipodi\" namespace" +#~ msgstr "SVG з прасторай імёнаў \"xmlns:sodipodi\"" + +#, fuzzy +#~ msgid "Scalable Vector Graphics format with inkscape extensions" +#~ msgstr "" +#~ "Фармат здольнай маштабавацца вэктарнае графікі з пашырэньнямі sodipodi" + +#, fuzzy +#~ msgid "" +#~ "%s is not regular file.\n" +#~ "Although inkscape will run, you are\n" +#~ "not able to use extensions (plugins)\n" +#~ msgstr "" +#~ "%s не зьяўляецца звычайным файлам.\n" +#~ "Хаця sodipodi і працуе, вы не\n" +#~ "можаце выкарыстоўваць дадаткі\n" + +#, fuzzy +#~ msgid "" +#~ "%s either is not valid xml file or\n" +#~ "you do not have read premissions on it.\n" +#~ "Although inkscape will run, you are\n" +#~ "not able to use extensions (plugins)\n" +#~ msgstr "" +#~ "%s нерэчаісны файл xml ці вы\n" +#~ "не маеце правоў на чытаньне.\n" +#~ "Хаця sodipodi і працуе, вы не\n" +#~ "можаце выкарыстоўваць дадаткі\n" + +#, fuzzy +#~ msgid "" +#~ "%s is not valid inkscape extensions file.\n" +#~ "Although inkscape will run, you are\n" +#~ "not able to use extensions (plugins)\n" +#~ msgstr "" +#~ "%s не зьяўляецца файлам пашырэньняў.\n" +#~ "Хаця sodipodi і працуе, вы не\n" +#~ "можаце выкарыстоўваць дадаткі\n" + +#, fuzzy +#~ msgid "" +#~ "Cannot create directory %s.\n" +#~ "Although inkscape will run, you are\n" +#~ "not able to use extensions (plugins)\n" +#~ msgstr "" +#~ "Немагчыма стварыць тэчку %s.\n" +#~ "Хаця sodipodi і працуе, вы не\n" +#~ "можаце выкарыстоўваць дадаткі\n" + +#, fuzzy +#~ msgid "" +#~ "%s is not a valid directory.\n" +#~ "Although inkscape will run, you are\n" +#~ "not able to use extensions (plugins)\n" +#~ msgstr "" +#~ "%s нерэчаісная тэчка.\n" +#~ "Хаця sodipodi і працуе, вы не\n" +#~ "можаце выкарыстоўваць дадаткі\n" + +#, fuzzy +#~ msgid "" +#~ "Cannot create file %s.\n" +#~ "Although inkscape will run, you are\n" +#~ "not able to use extensions (plugins)\n" +#~ msgstr "" +#~ "Немагчыма стварыць файл %s.\n" +#~ "Хаця sodipodi і працуе, вы не\n" +#~ "можаце выкарыстоўваць дадаткі\n" + +#, fuzzy +#~ msgid "" +#~ "Cannot write file %s.\n" +#~ "Although inkscape will run, you are\n" +#~ "not able to use extensions (plugins)\n" +#~ msgstr "" +#~ "Немагчыма запісаць файл %s.\n" +#~ "Хаця sodipodi і працуе, вы не\n" +#~ "можаце выкарыстоўваць дадаткі\n" + +#~ msgid "Unknown item :-(" +#~ msgstr "Невядомы элемэнт :-(" + +#~ msgid "Text and font settings" +#~ msgstr "Усталёўкі тэкста й шрыфта" + +#~ msgid "Modify existing objects by control nodes" +#~ msgstr "Зьмяняе існуючыя аб'екты праз кіруючыя вузлы" + +#, fuzzy +#~ msgid "Draw precisely positioned curved and straight lines" +#~ msgstr "Інструмэнт пера - рысуе дакладна спазыцыянаваныя дугі й прамыя рысы" + +#~ msgid "Zoom in drawing" +#~ msgstr "Павялічвае маштаб рысунка" + +#~ msgid "Document" +#~ msgstr "Уласьцівасьці дакумэнта" + +#~ msgid "Page layout" +#~ msgstr "Арыентацыя аркуша" + +#~ msgid "Document variant:" +#~ msgstr "Варыянт дакумэнта:" + +#~ msgid "" +#~ "*.svg *.svgz|SVG files\n" +#~ "*.xml|XML files\n" +#~ "*|All files" +#~ msgstr "" +#~ "*.svg *.svgz|SVG файлы\n" +#~ "*.xml|XML файлы\n" +#~ "*|Усе файлы" + +#~ msgid "Save document as" +#~ msgstr "Захаваць дакумэнт як" + +#~ msgid "About sodipodi" +#~ msgstr "Пра sodipodi" + +#~ msgid "About Sodipodi" +#~ msgstr "Пра Sodipodi" + +#~ msgid "The SVG ID of item" +#~ msgstr "SVG ID элемэнта" + +#~ msgid "The ID is not valid" +#~ msgstr "Недапушчальны ID" + +#~ msgid "The ID is already defined" +#~ msgstr "ID ужо вызначаны" + +#~ msgid "Object position and size" +#~ msgstr "Пазыцыя й памер аб'екта" + +#~ msgid "Position and size" +#~ msgstr "Пазыцыя й памер" + +#~ msgid "Save as:" +#~ msgstr "Захаваць як:" + +#~ msgid "Dynahand" +#~ msgstr "Стужка" + +#~ msgid "Text Editing" +#~ msgstr "Уласьцівасьці тэкста" + +#~ msgid "Display Properties" +#~ msgstr "Уласьцівасьці дысплэя" + +#~ msgid "Node tool - modify different aspects of existing objects" +#~ msgstr "Інструмэнт вузла - зьмяняе розныя асьпекты існуючых аб'ектаў" + +#~ msgid "Spiral tool - create spirals" +#~ msgstr "Інструмэнт сьпіралі - стварае сьпіралі" + +#~ msgid "Calligraphic tool - draw calligraphic lines" +#~ msgstr "Інструмэнт каліграфіі - рысуе каліграфічныя рысы" + +#~ msgid "Zoom tool - zoom into choosen area" +#~ msgstr "Інструмэнт маштабаваньня - маштабуе выбраную прастору" diff --git a/po/ca.po b/po/ca.po new file mode 100644 index 000000000..3a434c270 --- /dev/null +++ b/po/ca.po @@ -0,0 +1,9595 @@ +# Inkscape translation to Catalan. +# Copyright © 2000, 2003, 2004 Free Software Foundation, Inc. +# Quico Llach , 2000. Traducció sodipodi. +# Francesc Dorca , 2003. Traducció sodipodi. +# Xavier Conde Rueda , 2004, 2005 +# +msgid "" +msgstr "" +"Project-Id-Version: inkscape\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2005-12-04 11:51-0800\n" +"PO-Revision-Date: 2005-10-17 13:32+0200\n" +"Last-Translator: Xavier Conde Rueda \n" +"Language-Team: Catalan \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n!=1;\n" + +#: ../inkscape.desktop.in.h:1 +msgid "Create and edit Scalable Vector Graphics images" +msgstr "Creeu i editeu imatges de gràfics de vectors escalables" + +#: ../inkscape.desktop.in.h:2 +msgid "Inkscape SVG Vector Illustrator" +msgstr "Il·lustrador vectorial SVG Inkscape" + +#: ../../po/../src/arc-context.cpp:350 +msgid "" +"Ctrl: make circle or integer-ratio ellipse, snap arc/segment angle" +msgstr "" +"Control: fes un cercle o una el·lipse amb radi d'enter, ajusta " +"l'angle de l'arc o el segment" + +#: ../../po/../src/arc-context.cpp:351 ../../po/../src/rect-context.cpp:388 +msgid "Shift: draw around the starting point" +msgstr "Majúscules: dibuixa al voltant del punt d'inici" + +#: ../../po/../src/arc-context.cpp:413 +#: ../../po/../src/connector-context.cpp:493 +#: ../../po/../src/dyna-draw-context.cpp:506 +#: ../../po/../src/pen-context.cpp:329 ../../po/../src/pencil-context.cpp:208 +#: ../../po/../src/rect-context.cpp:452 ../../po/../src/spiral-context.cpp:421 +#: ../../po/../src/star-context.cpp:427 +msgid "Current layer is hidden. Unhide it to be able to draw on it." +msgstr "La capa actual està amagada. Mostreu-la per poder dibuixar-hi." + +#: ../../po/../src/arc-context.cpp:417 +#: ../../po/../src/connector-context.cpp:497 +#: ../../po/../src/dyna-draw-context.cpp:510 +#: ../../po/../src/pen-context.cpp:336 ../../po/../src/pencil-context.cpp:212 +#: ../../po/../src/rect-context.cpp:456 ../../po/../src/spiral-context.cpp:426 +#: ../../po/../src/star-context.cpp:431 +msgid "Current layer is locked. Unlock it to be able to draw on it." +msgstr "" +"La capa actual està blocada. Desbloqueu-la per poder dibuixar-hi." + +#: ../../po/../src/arc-context.cpp:496 +#, c-format +msgid "" +"Ellipse: %s × %s; with Ctrl to make circle or integer-" +"ratio ellipse; with Shift to draw around the starting point" +msgstr "" +"El·lipsi: %s × %s; amb Control per fer un cercle o una " +"el·lipse de radi enter; amb majúscules per dibuixar al voltant del " +"punt d'inici" + +#: ../../po/../src/connector-context.cpp:518 +msgid "Creating new connector" +msgstr "S'està creant un nou connector" + +#: ../../po/../src/connector-context.cpp:939 +msgid "Finishing connector" +msgstr "S'ha acabat el connector" + +#: ../../po/../src/connector-context.cpp:1108 +#, fuzzy +msgid "Connection point: click or drag to create a new connector" +msgstr "" +"Punt de connexió: cliqueu o arrossegueu per a crear un nou connector" + +#: ../../po/../src/connector-context.cpp:1185 +#, fuzzy +msgid "Connector endpoint: drag to reroute or connect to new shapes" +msgstr "" +"Punt final de connexió: arrossegueu per reencaminar o connectar a " +"noves formes" + +#: ../../po/../src/connector-context.cpp:1278 +msgid "Select at least one non-connector object." +msgstr "Seleccioneu almenys un objecte que no sigui connector." + +#: ../../po/../src/desktop-events.cpp:238 +#, c-format +msgid "%s at %s" +msgstr "%s a %s" + +#. TRANSLATORS: This string appears when double-clicking on a guide. +#. This is the distance by which the guide is to be moved. +#: ../../po/../src/desktop-events.cpp:277 +msgid " relative by " +msgstr " relatiu per " + +#. TRANSLATORS: This string appears when double-clicking on a guide. +#. This is the target location where the guide is to be moved. +#: ../../po/../src/desktop-events.cpp:282 +#: ../../po/../src/desktop-events.cpp:395 +msgid " absolute to " +msgstr " absolut a " + +#. create dialog +#: ../../po/../src/desktop-events.cpp:348 +msgid "Guideline" +msgstr "Línia guia" + +#: ../../po/../src/desktop-events.cpp:432 +#, c-format +msgid "Move %s" +msgstr "Mou %s" + +#: ../../po/../src/desktop.cpp:678 +msgid "No previous zoom." +msgstr "Cap ampliació anterior." + +#: ../../po/../src/desktop.cpp:703 +msgid "No next zoom." +msgstr "Cap ampliació següent." + +#: ../../po/../src/dialogs/clonetiler.cpp:182 +msgid "Nothing selected." +msgstr "No s'ha seleccionat res." + +#: ../../po/../src/dialogs/clonetiler.cpp:188 +msgid "More than one object selected." +msgstr "S'ha seleccionat més d'un objecte." + +#: ../../po/../src/dialogs/clonetiler.cpp:195 +#, c-format +msgid "Object has %d tiled clones." +msgstr "L'objecte té %d clons en mosaic." + +#: ../../po/../src/dialogs/clonetiler.cpp:200 +msgid "Object has no tiled clones." +msgstr "L'objecte no té cap clon en mosaic." + +#: ../../po/../src/dialogs/clonetiler.cpp:865 +msgid "Select one object whose tiled clones to unclump." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:916 +msgid "Select one object whose tiled clones to remove." +msgstr "Seleccioneu un objecte per esborrar els seus clons del mosaic." + +#: ../../po/../src/dialogs/clonetiler.cpp:984 +#: ../../po/../src/selection-chemistry.cpp:1774 +msgid "Select an object to clone." +msgstr "Seleccioneu un objecte per clonar-lo." + +#: ../../po/../src/dialogs/clonetiler.cpp:990 +#: ../../po/../src/selection-chemistry.cpp:1780 +msgid "" +"If you want to clone several objects, group them and clone the " +"group." +msgstr "" +"Per clonar un conjunt d'objectes, agrupeu-los i cloneu el grup." + +#: ../../po/../src/dialogs/clonetiler.cpp:1484 +msgid "Per row:" +msgstr "Per fila:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1497 +msgid "Per column:" +msgstr "Per columna:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1505 +msgid "Randomize:" +msgstr "Aleatoritza:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1656 +msgid "_Symmetry" +msgstr "_Simetria" + +#. TRANSLATORS: For the following 17 symmetry groups, see +#. * http://www.bib.ulb.ac.be/coursmath/doc/17.htm (visual examples); +#. * http://www.clarku.edu/~djoyce/wallpaper/seventeen.html (English vocabulary); or +#. * http://membres.lycos.fr/villemingerard/Geometri/Sym1D.htm (French vocabulary). +#. +#: ../../po/../src/dialogs/clonetiler.cpp:1664 +msgid "Select one of the 17 symmetry groups for the tiling" +msgstr "Seleccioneu un dels 17 grups de simetria per fer el mosaic" + +#. TRANSLATORS: "translation" means "shift" / "displacement" here. +#: ../../po/../src/dialogs/clonetiler.cpp:1675 +msgid "P1: simple translation" +msgstr "P1: desplaçament simple" + +#: ../../po/../src/dialogs/clonetiler.cpp:1676 +msgid "P2: 180° rotation" +msgstr "P2: rotació 180°" + +#: ../../po/../src/dialogs/clonetiler.cpp:1677 +msgid "PM: reflection" +msgstr "PM: reflexió" + +#. TRANSLATORS: "glide reflection" is a reflection and a translation combined. +#. For more info, see http://mathforum.org/sum95/suzanne/symsusan.html +#: ../../po/../src/dialogs/clonetiler.cpp:1680 +msgid "PG: glide reflection" +msgstr "PG: reflexió lleugera" + +#: ../../po/../src/dialogs/clonetiler.cpp:1681 +msgid "CM: reflection + glide reflection" +msgstr "CM: reflexió + reflexió lleugera" + +#: ../../po/../src/dialogs/clonetiler.cpp:1682 +msgid "PMM: reflection + reflection" +msgstr "PMM: reflexió + reflexió" + +#: ../../po/../src/dialogs/clonetiler.cpp:1683 +msgid "PMG: reflection + 180° rotation" +msgstr "PMG: reflexió + rotació 180°" + +#: ../../po/../src/dialogs/clonetiler.cpp:1684 +msgid "PGG: glide reflection + 180° rotation" +msgstr "PGG: reflexió lleugera + rotació 180°" + +#: ../../po/../src/dialogs/clonetiler.cpp:1685 +msgid "CMM: reflection + reflection + 180° rotation" +msgstr "CMM: reflexió + reflexió + rotació 180°" + +#: ../../po/../src/dialogs/clonetiler.cpp:1686 +msgid "P4: 90° rotation" +msgstr "P4: rotació 90°" + +#: ../../po/../src/dialogs/clonetiler.cpp:1687 +msgid "P4M: 90° rotation + 45° reflection" +msgstr "P4M: rotació 90° + reflexió 45°" + +#: ../../po/../src/dialogs/clonetiler.cpp:1688 +msgid "P4G: 90° rotation + 90° reflection" +msgstr "P4G: rotació 90° + reflexió 90°" + +#: ../../po/../src/dialogs/clonetiler.cpp:1689 +msgid "P3: 120° rotation" +msgstr "P3: rotació 120°" + +#: ../../po/../src/dialogs/clonetiler.cpp:1690 +msgid "P31M: reflection + 120° rotation, dense" +msgstr "P31M: reflexió + rotació 120°, dens" + +#: ../../po/../src/dialogs/clonetiler.cpp:1691 +msgid "P3M1: reflection + 120° rotation, sparse" +msgstr "P3M1: reflexió + rotació 120°, dispers" + +#: ../../po/../src/dialogs/clonetiler.cpp:1692 +msgid "P6: 60° rotation" +msgstr "P6: rotació 60°" + +#: ../../po/../src/dialogs/clonetiler.cpp:1693 +msgid "P6M: reflection + 60° rotation" +msgstr "P6M: reflexió + rotació 60°" + +#: ../../po/../src/dialogs/clonetiler.cpp:1721 +msgid "S_hift" +msgstr "Des_plaça" + +#. TRANSLATORS: "shift" means: the tiles will be shifted (offset) horizontally by this amount +#: ../../po/../src/dialogs/clonetiler.cpp:1731 +#, no-c-format +msgid "Shift X:" +msgstr "Desplaçament X:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1739 +#, no-c-format +msgid "Horizontal shift per row (in % of tile width)" +msgstr "Desplaçament horitzontal per cada fila (en % de l'amplada de mosaic)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1747 +#, no-c-format +msgid "Horizontal shift per column (in % of tile width)" +msgstr "" +"Desplaçament horitzontal per cada columna (en % de l'amplada de mosaic)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1754 +msgid "Randomize the horizontal shift by this percentage" +msgstr "Percentatge d'aleatorització del desplaçament horitzontal" + +#. TRANSLATORS: "shift" means: the tiles will be shifted (offset) vertically by this amount +#: ../../po/../src/dialogs/clonetiler.cpp:1764 +#, no-c-format +msgid "Shift Y:" +msgstr "Desplaçament Y:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1772 +#, no-c-format +msgid "Vertical shift per row (in % of tile height)" +msgstr "Desplaçament vertical per cada fila (en %%de l'alçada de mosaic)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1780 +#, no-c-format +msgid "Vertical shift per column (in % of tile height)" +msgstr "Desplaçament vertical per cada columna (en % de l'alçada de mosaic)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1787 +msgid "Randomize the vertical shift by this percentage" +msgstr "Percentatge d'aleatorització del desplaçament vertical" + +#: ../../po/../src/dialogs/clonetiler.cpp:1795 +msgid "Exponent:" +msgstr "Exponent:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1802 +msgid "Whether rows are spaced evenly (1), converge (<1) or diverge (>1)" +msgstr "" +"Si les files estan separades equitativament (1), convergeixen (<1) o " +"divergeixen (>1)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1809 +msgid "Whether columns are spaced evenly (1), converge (<1) or diverge (>1)" +msgstr "" +"Si les columnes estan separades equitativament (1), convergeixen (<1) o " +"divergeixen (>1)" + +#. TRANSLATORS: "Alternate" is a verb here +#: ../../po/../src/dialogs/clonetiler.cpp:1817 +#: ../../po/../src/dialogs/clonetiler.cpp:1907 +#: ../../po/../src/dialogs/clonetiler.cpp:1966 +#: ../../po/../src/dialogs/clonetiler.cpp:2022 +#: ../../po/../src/dialogs/clonetiler.cpp:2153 +msgid "Alternate:" +msgstr "Alterna:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1823 +msgid "Alternate the sign of shifts for each row" +msgstr "Alterna el signe dels desplaçaments per cada fila" + +#: ../../po/../src/dialogs/clonetiler.cpp:1828 +msgid "Alternate the sign of shifts for each column" +msgstr "Alterna el signe dels desplaçaments per cada columna" + +#: ../../po/../src/dialogs/clonetiler.cpp:1837 +msgid "Sc_ale" +msgstr "Esc_ala" + +#: ../../po/../src/dialogs/clonetiler.cpp:1845 +msgid "Scale X:" +msgstr "Escala d'X:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1853 +#, no-c-format +msgid "Horizontal scale per row (in % of tile width)" +msgstr "Escalat horitzontal per cada fila (en % de l'amplada de mosaic)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1861 +#, no-c-format +msgid "Horizontal scale per column (in % of tile width)" +msgstr "Escalat horitzontal per cada columna (en % de l'amplada de mosaic)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1868 +msgid "Randomize the horizontal scale by this percentage" +msgstr "Percentatge d'aleatorització d'escalat horitzontal" + +#: ../../po/../src/dialogs/clonetiler.cpp:1876 +msgid "Scale Y:" +msgstr "Escala d'Y:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1884 +#, no-c-format +msgid "Vertical scale per row (in % of tile height)" +msgstr "Desplaçament vertical per cada fila (en % de l'alçada de mosaic)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1892 +#, no-c-format +msgid "Vertical scale per column (in % of tile height)" +msgstr "Desplaçament vertical per cada columna (en % de l'alçada de mosaic)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1899 +msgid "Randomize the vertical scale by this percentage" +msgstr "Percentatge d'aleatorització d'escalat vertical" + +#: ../../po/../src/dialogs/clonetiler.cpp:1913 +msgid "Alternate the sign of scales for each row" +msgstr "Alterna el signe dels escalats per cada fila" + +#: ../../po/../src/dialogs/clonetiler.cpp:1918 +msgid "Alternate the sign of scales for each column" +msgstr "Alterna el signe dels escalats per cada columna" + +#: ../../po/../src/dialogs/clonetiler.cpp:1927 +msgid "_Rotation" +msgstr "_Rotació" + +#: ../../po/../src/dialogs/clonetiler.cpp:1935 +msgid "Angle:" +msgstr "Angle:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1943 +#, no-c-format +msgid "Rotate tiles by this angle for each row" +msgstr "Gira els mosaics aquest angle per cada fila" + +#: ../../po/../src/dialogs/clonetiler.cpp:1951 +#, no-c-format +msgid "Rotate tiles by this angle for each column" +msgstr "Gira els mosaics aquest angle per cada columna" + +#: ../../po/../src/dialogs/clonetiler.cpp:1958 +msgid "Randomize the rotation angle by this percentage" +msgstr "Percentatge d'aleatorització de l'angle" + +#: ../../po/../src/dialogs/clonetiler.cpp:1972 +msgid "Alternate the rotation direction for each row" +msgstr "Alterna la direcció de rotació per cada fila" + +#: ../../po/../src/dialogs/clonetiler.cpp:1977 +msgid "Alternate the rotation direction for each column" +msgstr "Alterna la direcció de rotació per cada columna" + +#: ../../po/../src/dialogs/clonetiler.cpp:1985 +msgid "_Opacity" +msgstr "_Opacitat" + +#: ../../po/../src/dialogs/clonetiler.cpp:1993 +msgid "Fade out:" +msgstr "Difuminació:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2000 +msgid "Decrease tile opacity by this percentage for each row" +msgstr "Redueix l'opacitat aquest percentatge per cada fila" + +#: ../../po/../src/dialogs/clonetiler.cpp:2007 +msgid "Decrease tile opacity by this percentage for each column" +msgstr "Redueix l'opacitat aquest percentatge per cada columna" + +#: ../../po/../src/dialogs/clonetiler.cpp:2014 +msgid "Randomize the tile opacity by this percentage" +msgstr "Percentatge d'aleatorització de l'opacitat del mosaic" + +#: ../../po/../src/dialogs/clonetiler.cpp:2028 +msgid "Alternate the sign of opacity change for each row" +msgstr "Alterna els signes dels canvis en l'opacitat per cada fila" + +#: ../../po/../src/dialogs/clonetiler.cpp:2033 +msgid "Alternate the sign of opacity change for each column" +msgstr "Alterna els signes dels canvis en l'opacitat per cada columna" + +#: ../../po/../src/dialogs/clonetiler.cpp:2041 +msgid "Co_lor" +msgstr "Co_lor" + +#: ../../po/../src/dialogs/clonetiler.cpp:2046 +msgid "Initial color: " +msgstr "Color inicial: " + +#: ../../po/../src/dialogs/clonetiler.cpp:2050 +msgid "Initial color of tiled clones" +msgstr "Color inicial dels clons de mosaic" + +#: ../../po/../src/dialogs/clonetiler.cpp:2050 +msgid "" +"Initial color for clones (works only if the original has unset fill or " +"stroke)" +msgstr "" +"Color inicial per als clons (només s'usa si l'original no té farciment ni " +"traç)" + +#: ../../po/../src/dialogs/clonetiler.cpp:2065 +msgid "H:" +msgstr "H:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2072 +msgid "Change the tile hue by this percentage for each row" +msgstr "Redueix el to del mosaic aquest percentatge per cada fila" + +#: ../../po/../src/dialogs/clonetiler.cpp:2079 +msgid "Change the tile hue by this percentage for each column" +msgstr "Redueix el to del mosaic aquest percentatge per cada columna" + +#: ../../po/../src/dialogs/clonetiler.cpp:2086 +msgid "Randomize the tile hue by this percentage" +msgstr "Percentatge d'aleatorització del to del mosaic" + +#: ../../po/../src/dialogs/clonetiler.cpp:2095 +msgid "S:" +msgstr "S:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2102 +msgid "Change the color saturation by this percentage for each row" +msgstr "Redueix la saturació del color aquest percentatge per cada fila" + +#: ../../po/../src/dialogs/clonetiler.cpp:2109 +msgid "Change the color saturation by this percentage for each column" +msgstr "Redueix la saturació del color aquest percentatge per cada columna" + +#: ../../po/../src/dialogs/clonetiler.cpp:2116 +msgid "Randomize the color saturation by this percentage" +msgstr "Percentatge d'aleatorització de la saturació del color" + +#: ../../po/../src/dialogs/clonetiler.cpp:2124 +msgid "L:" +msgstr "L:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2131 +msgid "Change the color lightness by this percentage for each row" +msgstr "Redueix la brillantor del color aquest percentatge per cada fila" + +#: ../../po/../src/dialogs/clonetiler.cpp:2138 +msgid "Change the color lightness by this percentage for each column" +msgstr "Redueix la saturació del color aquest percentatge per cada columna" + +#: ../../po/../src/dialogs/clonetiler.cpp:2145 +msgid "Randomize the color lightness by this percentage" +msgstr "Percentatge d'aleatorització de la brillantor del color" + +#: ../../po/../src/dialogs/clonetiler.cpp:2159 +msgid "Alternate the sign of color changes for each row" +msgstr "Alterna el signes dels canvis de color per cada fila" + +#: ../../po/../src/dialogs/clonetiler.cpp:2164 +msgid "Alternate the sign of color changes for each column" +msgstr "Alterna el signes dels canvis de color per cada columna" + +#: ../../po/../src/dialogs/clonetiler.cpp:2172 +msgid "_Trace" +msgstr "_Traça" + +#: ../../po/../src/dialogs/clonetiler.cpp:2179 +msgid "Trace the drawing under the tiles" +msgstr "Traça el dibuix dels clons" + +#: ../../po/../src/dialogs/clonetiler.cpp:2183 +msgid "" +"For each clone, pick a value from the drawing in that clone's location and " +"apply it to the clone" +msgstr "" +"Per cada clon, escolliu un valor del dibuix en l'ubicació del clon i " +"apliqueu-lo al clon" + +#: ../../po/../src/dialogs/clonetiler.cpp:2197 +msgid "1. Pick from the drawing:" +msgstr "1. Seleccioneu del dibuix:" + +#. ----Hbox2 +#: ../../po/../src/dialogs/clonetiler.cpp:2208 +#: ../../po/../src/dialogs/clonetiler.cpp:2355 +#: ../../po/../src/ui/dialog/tracedialog.cpp:445 +msgid "Color" +msgstr "Color" + +#: ../../po/../src/dialogs/clonetiler.cpp:2209 +msgid "Pick the visible color and opacity" +msgstr "Selecciona el color visible i l'opacitat" + +#: ../../po/../src/dialogs/clonetiler.cpp:2216 +#: ../../po/../src/dialogs/clonetiler.cpp:2365 +#: ../share/extensions/dropshadow.inx.h:3 +msgid "Opacity" +msgstr "Opacitat" + +#: ../../po/../src/dialogs/clonetiler.cpp:2217 +msgid "Pick the total accumulated opacity" +msgstr "Seleccioneu l'opacitat total acumulada" + +#: ../../po/../src/dialogs/clonetiler.cpp:2224 +msgid "R" +msgstr "R" + +#: ../../po/../src/dialogs/clonetiler.cpp:2225 +msgid "Pick the Red component of the color" +msgstr "Seleccioneu el component vermell del color" + +#: ../../po/../src/dialogs/clonetiler.cpp:2232 +msgid "G" +msgstr "G" + +#: ../../po/../src/dialogs/clonetiler.cpp:2233 +msgid "Pick the Green component of the color" +msgstr "Seleccioneu el component verd del color" + +#: ../../po/../src/dialogs/clonetiler.cpp:2240 +msgid "B" +msgstr "B" + +#: ../../po/../src/dialogs/clonetiler.cpp:2241 +msgid "Pick the Blue component of the color" +msgstr "Seleccioneu el component blau del color" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2250 +msgid "clonetiler|H" +msgstr "clonetiler|H" + +#: ../../po/../src/dialogs/clonetiler.cpp:2251 +msgid "Pick the hue of the color" +msgstr "Seleccioneu el to del color" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2260 +msgid "clonetiler|S" +msgstr "clonetiler|S" + +#: ../../po/../src/dialogs/clonetiler.cpp:2261 +msgid "Pick the saturation of the color" +msgstr "Seleccioneu la saturació del color" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2270 +msgid "clonetiler|L" +msgstr "clonetiler|L" + +#: ../../po/../src/dialogs/clonetiler.cpp:2271 +msgid "Pick the lightness of the color" +msgstr "Seleccioneu la brillantor del color" + +#: ../../po/../src/dialogs/clonetiler.cpp:2281 +msgid "2. Tweak the picked value:" +msgstr "2. Manipuleu el valor seleccionat:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2291 +msgid "Gamma-correct:" +msgstr "Correcció de gamma:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2296 +msgid "Shift the mid-range of the picked value upwards (>0) or downwards (<0)" +msgstr "" +"Desplaceu el rang mitjà del valor seleccionat cap amunt (>0) o cap abaix (<0)" + +#: ../../po/../src/dialogs/clonetiler.cpp:2303 +msgid "Randomize:" +msgstr "Aleatorització:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2308 +msgid "Randomize the picked value by this percentage" +msgstr "Percentatge d'aleatorització del valor" + +#: ../../po/../src/dialogs/clonetiler.cpp:2315 +msgid "Invert:" +msgstr "Inverteix:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2319 +msgid "Invert the picked value" +msgstr "Inverteix el valor seleccionat" + +#: ../../po/../src/dialogs/clonetiler.cpp:2325 +msgid "3. Apply the value to the clones':" +msgstr "3. Aplica el valor als clons:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2335 +msgid "Presence" +msgstr "Presència" + +#: ../../po/../src/dialogs/clonetiler.cpp:2338 +msgid "" +"Each clone is created with the probability determined by the picked value in " +"that point" +msgstr "" +"Cada clon es crea amb la probabilitat determinada pel valor seleccionat a " +"cada punt" + +#: ../../po/../src/dialogs/clonetiler.cpp:2345 +msgid "Size" +msgstr "Mida" + +#: ../../po/../src/dialogs/clonetiler.cpp:2348 +msgid "Each clone's size is determined by the picked value in that point" +msgstr "La mida de cada clon es determina pel valor seleccionat en aquell punt" + +#: ../../po/../src/dialogs/clonetiler.cpp:2358 +msgid "" +"Each clone is painted by the picked color (the original must have unset fill " +"or stroke)" +msgstr "" +"Cada clon es pinta amb el color seleccionat (l'original no ha de tenir " +"farciment ni traç)" + +#: ../../po/../src/dialogs/clonetiler.cpp:2368 +msgid "Each clone's opacity is determined by the picked value in that point" +msgstr "" +"L'opacitat de cada clon es determina pel valor seleccionat en aquest punt" + +#: ../../po/../src/dialogs/clonetiler.cpp:2395 +msgid "How many rows in the tiling" +msgstr "Quantes files en el mosaic" + +#: ../../po/../src/dialogs/clonetiler.cpp:2415 +msgid "How many columns in the tiling" +msgstr "Quantes columnes en el mosaic" + +#: ../../po/../src/dialogs/clonetiler.cpp:2445 +msgid "Width of the rectangle to be filled" +msgstr "Amplada del rectangle a omplir" + +#: ../../po/../src/dialogs/clonetiler.cpp:2470 +msgid "Height of the rectangle to be filled" +msgstr "Alçada del rectangle a omplir" + +#: ../../po/../src/dialogs/clonetiler.cpp:2485 +msgid "Rows, columns: " +msgstr "Files, columnes: " + +#: ../../po/../src/dialogs/clonetiler.cpp:2486 +msgid "Create the specified number of rows and columns" +msgstr "Crea el nombre de files i columnes especificat" + +#: ../../po/../src/dialogs/clonetiler.cpp:2495 +msgid "Width, height: " +msgstr "Amplada, alçada: " + +#: ../../po/../src/dialogs/clonetiler.cpp:2496 +msgid "Fill the specified width and height with the tiling" +msgstr "Omple l'alçada i l'amplada especificades amb el mosaic" + +#: ../../po/../src/dialogs/clonetiler.cpp:2512 +msgid "Use saved size and position of the tile" +msgstr "Usa la mida i la posició desades del mosaic" + +#: ../../po/../src/dialogs/clonetiler.cpp:2515 +msgid "" +"Pretend that the size and position of the tile are the same as the last time " +"you tiled it (if any), instead of using the current size" +msgstr "" +"Suposa que la mida i la posició del mosaic són les mateixes que la darrera " +"vegada que vau fer el mosaic, en comptes de fer servir la mida actual" + +#: ../../po/../src/dialogs/clonetiler.cpp:2539 +msgid " _Create " +msgstr " _Crea " + +#: ../../po/../src/dialogs/clonetiler.cpp:2541 +msgid "Create and tile the clones of the selection" +msgstr "Crea i fes un mosaic amb els clons de la selecció" + +#. TRANSLATORS: if a group of objects are "clumped" together, then they +#. are unevenly spread in the given amount of space - as shown in the +#. diagrams on the left in the following screenshot: +#. http://www.inkscape.org/screenshots/gallery/inkscape-0.42-CVS-tiles-unclump.png +#. So unclumping is the process of spreading a number of objects out more evenly. +#: ../../po/../src/dialogs/clonetiler.cpp:2556 +msgid " _Unclump " +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2557 +msgid "Spread out clones to reduce clumping; can be applied repeatedly" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2563 +msgid " Re_move " +msgstr " Supri_meix " + +#: ../../po/../src/dialogs/clonetiler.cpp:2564 +msgid "Remove existing tiled clones of the selected object (siblings only)" +msgstr "" +"Suprimeix els clons de mosaic existents de l'objecte seleccionat (germans " +"només)" + +#: ../../po/../src/dialogs/clonetiler.cpp:2580 +msgid " R_eset " +msgstr " R_einicia " + +#. TRANSLATORS: "change" is a noun here +#: ../../po/../src/dialogs/clonetiler.cpp:2582 +msgid "" +"Reset all shifts, scales, rotates, opacity and color changes in the dialog " +"to zero" +msgstr "" +"Reinicia tots els desplaçaments, escalats, girs i canvis d'opacitat en el " +"diàleg a zero" + +#: ../../po/../src/dialogs/color-picker.cpp:280 +msgid "Close" +msgstr "Tanca" + +#: ../../po/../src/dialogs/debugdialog.cpp:138 +msgid "Messages" +msgstr "Missatges" + +#. ## Add a menu for clear() +#: ../../po/../src/dialogs/debugdialog.cpp:144 +#: ../../po/../src/menus-skeleton.h:16 +#: ../../po/../src/ui/dialog/messages.cpp:56 +#: ../../po/../src/ui/dialog/scriptdialog.cpp:181 +msgid "_File" +msgstr "_Fitxer" + +#. TRANSLATORS: "Clear" is a verb here +#: ../../po/../src/dialogs/debugdialog.cpp:145 +#: ../../po/../src/dialogs/find.cpp:753 +#: ../../po/../src/ui/dialog/messages.cpp:57 +#: ../../po/../src/ui/dialog/scriptdialog.cpp:182 +msgid "_Clear" +msgstr "Nete_ja" + +#: ../../po/../src/dialogs/debugdialog.cpp:147 +#: ../../po/../src/ui/dialog/messages.cpp:59 +msgid "Capture log messages" +msgstr "Captura els missatges de registre" + +#: ../../po/../src/dialogs/debugdialog.cpp:149 +#: ../../po/../src/ui/dialog/messages.cpp:61 +msgid "Release log messages" +msgstr "Allibera els missatges de registre" + +#. Notebook tab +#: ../../po/../src/dialogs/desktop-properties.cpp:909 +#: ../../po/../src/ui/dialog/document-preferences.cpp:89 +#: ../../po/../src/ui/widget/panel.cpp:107 +msgid "Grid" +msgstr "Graella" + +#. Checkbuttons +#. / \todo FIXME: gray out snapping when grid is off +#. / \todo FIXME: gray out snapping when grid is off. +#. / Dissenting view: you want snapping without grid. +#: ../../po/../src/dialogs/desktop-properties.cpp:917 +#: ../../po/../src/ui/dialog/document-preferences.cpp:179 +msgid "Show grid" +msgstr "Mostra la graella" + +#: ../../po/../src/dialogs/desktop-properties.cpp:917 +#: ../../po/../src/ui/dialog/document-preferences.cpp:179 +#: ../../po/../src/verbs.cpp:2115 +msgid "Show or hide grid" +msgstr "Mostra/oculta la graella" + +#: ../../po/../src/dialogs/desktop-properties.cpp:918 +#: ../../po/../src/ui/dialog/document-preferences.cpp:180 +msgid "Snap bounding boxes to grid" +msgstr "Ajusta la caixa del voltant a la graella" + +#: ../../po/../src/dialogs/desktop-properties.cpp:918 +#: ../../po/../src/dialogs/desktop-properties.cpp:1001 +#: ../../po/../src/ui/dialog/document-preferences.cpp:181 +#: ../../po/../src/ui/dialog/document-preferences.cpp:236 +msgid "Snap the edges of the object bounding boxes" +msgstr "Ajusta les vores de la caixa al voltant de l'objecte" + +#: ../../po/../src/dialogs/desktop-properties.cpp:919 +#: ../../po/../src/ui/dialog/document-preferences.cpp:183 +msgid "Snap nodes to grid" +msgstr "Ajusta els nodes a la graella" + +#: ../../po/../src/dialogs/desktop-properties.cpp:919 +#: ../../po/../src/dialogs/desktop-properties.cpp:1002 +#: ../../po/../src/ui/dialog/document-preferences.cpp:184 +#: ../../po/../src/ui/dialog/document-preferences.cpp:239 +msgid "Snap path nodes, text baselines, ellipse centers, etc." +msgstr "Ajusta els nodes dels camins, les línies de base, els centres, etc." + +#: ../../po/../src/dialogs/desktop-properties.cpp:937 +#: ../../po/../src/ui/dialog/document-preferences.cpp:186 +msgid "Grid units:" +msgstr "Unitats de la graella:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:939 +#: ../../po/../src/ui/dialog/document-preferences.cpp:187 +msgid "Origin X:" +msgstr "Origen X:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:942 +#: ../../po/../src/ui/dialog/document-preferences.cpp:189 +msgid "Origin Y:" +msgstr "Origen Y:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:945 +#: ../../po/../src/ui/dialog/document-preferences.cpp:191 +msgid "Spacing X:" +msgstr "Espaiat X:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:948 +#: ../../po/../src/ui/dialog/document-preferences.cpp:193 +msgid "Spacing Y:" +msgstr "Espaiat Y:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:952 +#: ../../po/../src/dialogs/desktop-properties.cpp:1013 +#: ../../po/../src/ui/dialog/document-preferences.cpp:195 +#: ../../po/../src/ui/dialog/document-preferences.cpp:241 +msgid "Snap units:" +msgstr "Unitats d'ajust:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:955 +#: ../../po/../src/dialogs/desktop-properties.cpp:1016 +#: ../../po/../src/ui/dialog/document-preferences.cpp:196 +#: ../../po/../src/ui/dialog/document-preferences.cpp:242 +msgid "Snap distance:" +msgstr "Distància d'ajust:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:958 +#: ../../po/../src/ui/dialog/document-preferences.cpp:199 +msgid "Grid line color:" +msgstr "Color de la graella:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:959 +#: ../../po/../src/ui/dialog/document-preferences.cpp:199 +msgid "Grid line color" +msgstr "Color de la graella" + +#: ../../po/../src/dialogs/desktop-properties.cpp:959 +#: ../../po/../src/ui/dialog/document-preferences.cpp:200 +msgid "Color of grid lines" +msgstr "Color de la graella" + +#: ../../po/../src/dialogs/desktop-properties.cpp:961 +#: ../../po/../src/ui/dialog/document-preferences.cpp:201 +msgid "Major grid line color:" +msgstr "Color major de la graella:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:962 +#: ../../po/../src/ui/dialog/document-preferences.cpp:201 +msgid "Major grid line color" +msgstr "Color major de la graella" + +#: ../../po/../src/dialogs/desktop-properties.cpp:962 +#: ../../po/../src/ui/dialog/document-preferences.cpp:202 +msgid "Color of the major (highlighted) grid lines" +msgstr "Color de les línies ressaltades" + +#: ../../po/../src/dialogs/desktop-properties.cpp:965 +#: ../../po/../src/ui/dialog/document-preferences.cpp:204 +msgid "Major grid line every:" +msgstr "Color major de la graella cada:" + +#. TRANSLATORS: This belongs to the "Major grid line every:" string, +#. see grid settings in the "Document Preferences" dialog +#: ../../po/../src/dialogs/desktop-properties.cpp:977 +#: ../../po/../src/ui/dialog/document-preferences.cpp:204 +msgid "lines" +msgstr "línies" + +#. Guidelines page +#: ../../po/../src/dialogs/desktop-properties.cpp:991 +#: ../../po/../src/ui/dialog/document-preferences.cpp:90 +msgid "Guides" +msgstr "Guies" + +#. / \todo FIXME: gray out snapping when guides are off +#. / Dissenting view: you want snapping without guides. +#: ../../po/../src/dialogs/desktop-properties.cpp:1000 +#: ../../po/../src/ui/dialog/document-preferences.cpp:234 +msgid "Show guides" +msgstr "Mostra les guies" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1000 +#: ../../po/../src/ui/dialog/document-preferences.cpp:234 +#: ../../po/../src/verbs.cpp:2116 +msgid "Show or hide guides" +msgstr "Mostra/oculta les guies" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1001 +#: ../../po/../src/ui/dialog/document-preferences.cpp:235 +msgid "Snap bounding boxes to guides" +msgstr "Ajusta la caixa del voltant a les guies" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1002 +#: ../../po/../src/ui/dialog/document-preferences.cpp:238 +msgid "Snap points to guides" +msgstr "Ajusta els punts a les guies" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1020 +#: ../../po/../src/ui/dialog/document-preferences.cpp:243 +msgid "Guide color:" +msgstr "Color de la guia:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1021 +#: ../../po/../src/ui/dialog/document-preferences.cpp:243 +msgid "Guideline color" +msgstr "Color de la línia guia" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1021 +#: ../../po/../src/ui/dialog/document-preferences.cpp:244 +msgid "Color of guidelines" +msgstr "Color de la línia guia" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1023 +#: ../../po/../src/ui/dialog/document-preferences.cpp:245 +msgid "Highlight color:" +msgstr "Color del ressaltat:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1024 +#: ../../po/../src/ui/dialog/document-preferences.cpp:245 +msgid "Highlighted guideline color" +msgstr "Color de la línia guia ressaltada" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1024 +#: ../../po/../src/ui/dialog/document-preferences.cpp:246 +msgid "Color of a guideline when it is under mouse" +msgstr "Color d'una línia guia sota el ratolí" + +#. Page page +#: ../../po/../src/dialogs/desktop-properties.cpp:1029 +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:855 +#: ../../po/../src/ui/dialog/document-preferences.cpp:88 +#: ../../po/../src/widgets/desktop-widget.cpp:1061 +msgid "Page" +msgstr "Pàgina" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1039 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +msgid "Background:" +msgstr "Color de fons:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1040 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +msgid "Background color" +msgstr "Color de fons" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1041 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +msgid "" +"Color and transparency of the page background (also used for bitmap export)" +msgstr "" +"Color i transparència del fons de la pàgina (també s'usa en l'exportació a " +"mapa de bits)" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1045 +#: ../../po/../src/ui/dialog/document-preferences.cpp:147 +#, fuzzy +msgid "Show page border" +msgstr "Mostra la vora del llenç" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1049 +#: ../../po/../src/ui/dialog/document-preferences.cpp:148 +msgid "Border on top of drawing" +msgstr "Vora a dalt del dibuix" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1052 +#: ../../po/../src/ui/dialog/document-preferences.cpp:149 +msgid "Border color:" +msgstr "Color de la vora:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1053 +#: ../../po/../src/ui/dialog/document-preferences.cpp:149 +#, fuzzy +msgid "Page border color" +msgstr "Color de la vora del llenç" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1054 +#: ../../po/../src/ui/dialog/document-preferences.cpp:150 +#, fuzzy +msgid "Color of the page border" +msgstr "Color de la vora del llenç" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1059 +#: ../../po/../src/ui/dialog/document-preferences.cpp:152 +msgid "Show page shadow" +msgstr "Mostra l'ombra de la pàgina" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1063 +#: ../../po/../src/ui/dialog/document-preferences.cpp:153 +msgid "Default units:" +msgstr "Unitats per defecte:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1069 +msgid "Units for the tool controls, ruler, and the statusbar" +msgstr "Unitats per als controls d'eines, regla i barra d'estat" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1086 +#: ../../po/../src/ui/widget/page-sizer.cpp:209 +#, fuzzy +msgid "Page size:" +msgstr "Mida del llenç:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1110 +#: ../../po/../src/ui/widget/page-sizer.cpp:219 +msgid "Custom" +msgstr "A mida" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1121 +#: ../../po/../src/ui/widget/page-sizer.cpp:225 +#, fuzzy +msgid "Page orientation:" +msgstr "Orientació del llenç:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1133 +#: ../../po/../src/ui/widget/page-sizer.cpp:232 +msgid "Landscape" +msgstr "Horitzontal" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1139 +#: ../../po/../src/ui/widget/page-sizer.cpp:234 +msgid "Portrait" +msgstr "Vertical" + +#. Custom paper frame +#: ../../po/../src/dialogs/desktop-properties.cpp:1148 +#: ../../po/../src/ui/widget/page-sizer.cpp:249 +#, fuzzy +msgid "Custom size" +msgstr "A mida" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1160 +#: ../../po/../src/dialogs/export.cpp:269 +#: ../../po/../src/ui/widget/page-sizer.cpp:261 +msgid "Units:" +msgstr "Unitats:" + +#. Stroke width +#: ../../po/../src/dialogs/desktop-properties.cpp:1162 +#: ../../po/../src/dialogs/export.cpp:310 +#: ../../po/../src/dialogs/object-attributes.cpp:55 +#: ../../po/../src/dialogs/stroke-style.cpp:985 +#: ../../po/../src/ui/widget/page-sizer.cpp:262 +#: ../../po/../src/widgets/toolbox.cpp:1957 +msgid "Width:" +msgstr "Amplada:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1183 +#: ../../po/../src/dialogs/export.cpp:326 +#: ../../po/../src/dialogs/export.cpp:431 +#: ../../po/../src/dialogs/object-attributes.cpp:56 +#: ../../po/../src/ui/widget/page-sizer.cpp:263 +msgid "Height:" +msgstr "Alçada:" + +#. +#. * Ownership metadata tab +#. +#: ../../po/../src/dialogs/desktop-properties.cpp:1206 +msgid "Metadata" +msgstr "Metadades" + +#. add license selector pull-down +#: ../../po/../src/dialogs/desktop-properties.cpp:1225 +msgid "License" +msgstr "Llicència" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1255 +msgid "Proprietary" +msgstr "Propietari" + +#: ../../po/../src/dialogs/display-settings.cpp:212 +msgid "When transforming, show:" +msgstr "En transformar, mostra:" + +#: ../../po/../src/dialogs/display-settings.cpp:223 +msgid "Objects" +msgstr "Objectes" + +#: ../../po/../src/dialogs/display-settings.cpp:224 +msgid "Show the actual objects when moving or transforming" +msgstr "Mou els objectes en qüestió quan es mogui o es transformi" + +#: ../../po/../src/dialogs/display-settings.cpp:231 +msgid "Box outline" +msgstr "Caixa al voltant" + +#: ../../po/../src/dialogs/display-settings.cpp:232 +msgid "Show only a box outline of the objects when moving or transforming" +msgstr "" +"Mostra només una caixa al voltant dels objectes quan es mogui o es transformi" + +#: ../../po/../src/dialogs/display-settings.cpp:238 +msgid "Per-object selection cue:" +msgstr "Cua de selecció per objecte:" + +#. sorationsnapsperpi == 0 means no snapping +#: ../../po/../src/dialogs/display-settings.cpp:249 +#: ../../po/../src/dialogs/display-settings.cpp:386 +#: ../../po/../src/dialogs/display-settings.cpp:441 +#: ../../po/../src/dialogs/display-settings.cpp:1482 +#: ../../po/../src/dialogs/stroke-style.cpp:791 +#: ../../po/../src/interface.cpp:741 +#: ../../po/../src/ui/widget/selected-style.cpp:100 +#: ../../po/../src/verbs.cpp:1842 +msgid "None" +msgstr "Cap" + +#: ../../po/../src/dialogs/display-settings.cpp:250 +msgid "No per-object selection indication" +msgstr "Sense indicació de selecció per objecte" + +#: ../../po/../src/dialogs/display-settings.cpp:256 +msgid "Mark" +msgstr "Marca" + +#: ../../po/../src/dialogs/display-settings.cpp:257 +msgid "Each selected object has a diamond mark in the top left corner" +msgstr "" +"Cada objecte seleccionat té una marca de diamant en la cantonada superior " +"esquerra" + +#: ../../po/../src/dialogs/display-settings.cpp:264 +msgid "Box" +msgstr "Caixa" + +#: ../../po/../src/dialogs/display-settings.cpp:265 +msgid "Each selected object displays its bounding box" +msgstr "Cada objecte seleccionat mostra una caixa al voltant" + +#: ../../po/../src/dialogs/display-settings.cpp:270 +msgid "Default scale origin:" +msgstr "Origen d'escalat predeterminat:" + +#: ../../po/../src/dialogs/display-settings.cpp:281 +msgid "Opposite bounding box edge" +msgstr "Cantó oposat de la caixa al voltant" + +#: ../../po/../src/dialogs/display-settings.cpp:282 +msgid "Default scale origin will be on the bounding box of the item" +msgstr "" +"L'origen d'escalat predeterminat serà a la caixa al voltant de l'element" + +#: ../../po/../src/dialogs/display-settings.cpp:288 +msgid "Farthest opposite node" +msgstr "Node oposat més llunyà" + +#: ../../po/../src/dialogs/display-settings.cpp:289 +msgid "Default scale origin will be on the bounding box of the item's points" +msgstr "" +"L'origen predeterminat de l'escala estarà en la caixa al voltant dels punts " +"de l'element" + +#: ../../po/../src/dialogs/display-settings.cpp:341 +msgid "degrees" +msgstr "graus" + +#: ../../po/../src/dialogs/display-settings.cpp:350 +msgid "" +"Rotating with Ctrl pressed snaps every that much degrees; also, pressing " +"[ or ] rotates by this amount" +msgstr "" +"Quantitat de graus que es gira en moure amb la tecla de control premuda. " +"També en prémer [ o ] es gira aquesta quantitat" + +#: ../../po/../src/dialogs/display-settings.cpp:407 +msgid "Rotation snaps every:" +msgstr "Gira cada:" + +#: ../../po/../src/dialogs/display-settings.cpp:430 +msgid "" +"None: dialogs are treated as regular windows; Normal: dialogs stay on top of " +"document windows; Aggressive: same as Normal but may work better with some " +"window managers." +msgstr "" +"Cap: els diàlegs es tracten com a finestres normals; normal: el diàleg se " +"situa a sobre de les finestres de documents; agressiu: igual que normal, " +"però funciona millor amb alguns gestors de finestres." + +#: ../../po/../src/dialogs/display-settings.cpp:451 +msgid "Normal" +msgstr "Normal" + +#: ../../po/../src/dialogs/display-settings.cpp:461 +msgid "Aggressive" +msgstr "Agressiu" + +#: ../../po/../src/dialogs/display-settings.cpp:475 +msgid "Dialogs on top:" +msgstr "Diàlegs a sobre:" + +#: ../../po/../src/dialogs/display-settings.cpp:645 +msgid "Show selection cue" +msgstr "Mostra la cua de selecció" + +#: ../../po/../src/dialogs/display-settings.cpp:646 +msgid "" +"Whether selected objects display a selection cue (the same as in selector)" +msgstr "" +"Si els objectes seleccionats mostren una cua de selecció (la mateixa que al " +"selector)" + +#: ../../po/../src/dialogs/display-settings.cpp:657 +msgid "Enable gradient editing" +msgstr "Habilita l'edició de degradats" + +#: ../../po/../src/dialogs/display-settings.cpp:658 +msgid "Whether selected objects display gradient editing controls" +msgstr "Si els objectes seleccionats mostren controls d'edició de degradats" + +#: ../../po/../src/dialogs/display-settings.cpp:719 +msgid "No objects selected to take the style from." +msgstr "No s'ha seleccionat cap objecte d'on agafar l'estil." + +#: ../../po/../src/dialogs/display-settings.cpp:728 +msgid "" +"More than one object selected. Cannot take style from multiple " +"objects." +msgstr "" +"S'ha seleccionat més d'un objecte. No es pot agafar l'estil a partir " +"de múltiples objectes." + +#: ../../po/../src/dialogs/display-settings.cpp:767 +msgid "Create new objects with:" +msgstr "Crea nous objectes amb:" + +#: ../../po/../src/dialogs/display-settings.cpp:777 +msgid "Take from selection" +msgstr "Agafa de la selecció" + +#: ../../po/../src/dialogs/display-settings.cpp:778 +msgid "Remember the style of the (first) selected object as this tool's style" +msgstr "" +"Recorda l'estil del primer objecte seleccionat com a estil d'aquesta eina" + +#: ../../po/../src/dialogs/display-settings.cpp:782 +#, fuzzy +msgid "Last used style" +msgstr "Enganxa l'e_stil" + +#: ../../po/../src/dialogs/display-settings.cpp:782 +msgid "Apply the style you last set on an object" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:790 +msgid "This tool's own style:" +msgstr "L'estil propi d'aquesta eina:" + +#: ../../po/../src/dialogs/display-settings.cpp:790 +msgid "" +"Each tool may store its own style to apply to the newly created objects. Use " +"the button below to set it." +msgstr "" +"Cada eina pot emmagatzemar el seu propi estil per aplicar-lo als nous " +"objectes creats. Useu el botó de sota per establir-lo." + +#. Mouse +#: ../../po/../src/dialogs/display-settings.cpp:877 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:55 +msgid "Mouse" +msgstr "Ratolí" + +#. TRANSLATORS: "Grab" is a noun here. "Grab sensitivity" is intended to mean how +#. * close on the screen you need to be to an object to be able to grab it with mouse (in +#. * pixels). +#: ../../po/../src/dialogs/display-settings.cpp:883 +msgid "Grab sensitivity:" +msgstr "Proximitat per seleccionar:" + +#: ../../po/../src/dialogs/display-settings.cpp:884 +msgid "" +"How close on the screen you need to be to an object to be able to grab it " +"with mouse (in screen pixels)" +msgstr "" +"Quant s'ha d'apropar a un objecte per seleccionar-lo amb el ratolí (en " +"píxels de pantalla)" + +#: ../../po/../src/dialogs/display-settings.cpp:885 +#: ../../po/../src/dialogs/display-settings.cpp:897 +#: ../../po/../src/dialogs/display-settings.cpp:912 +#: ../../po/../src/dialogs/display-settings.cpp:930 +#: ../../po/../src/dialogs/display-settings.cpp:970 +msgid "pixels" +msgstr "píxels" + +#: ../../po/../src/dialogs/display-settings.cpp:895 +msgid "Click/drag threshold:" +msgstr "Llindar per clicar/arrossegar:" + +#: ../../po/../src/dialogs/display-settings.cpp:896 +msgid "" +"Maximum mouse drag (in screen pixels) which is considered a click, not a drag" +msgstr "" +"Arrossegament màxim del ratolí (en píxels) que es considera un clic, no un " +"arrossegament" + +#. Scrolling +#: ../../po/../src/dialogs/display-settings.cpp:907 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:56 +msgid "Scrolling" +msgstr "Desplaçament" + +#: ../../po/../src/dialogs/display-settings.cpp:910 +msgid "Mouse wheel scrolls by:" +msgstr "La roda del ratolí desplaça:" + +#: ../../po/../src/dialogs/display-settings.cpp:911 +msgid "" +"One mouse wheel notch scrolls by this distance in screen pixels " +"(horizontally with Shift)" +msgstr "" +"Un moviment de la roda del ratolí desplaça aquesta distància en píxels " +"(horitzontalment amb tecla de majúscula)" + +#: ../../po/../src/dialogs/display-settings.cpp:920 +msgid "Ctrl+arrows" +msgstr "Ctrl+fletxes" + +#: ../../po/../src/dialogs/display-settings.cpp:928 +msgid "Scroll by:" +msgstr "Desplaça:" + +#: ../../po/../src/dialogs/display-settings.cpp:929 +msgid "Pressing Ctrl+arrow key scrolls by this distance (in screen pixels)" +msgstr "" +"En prémer control i fletxa es desplaça aquesta distància (en píxels de " +"pantalla)" + +#: ../../po/../src/dialogs/display-settings.cpp:939 +msgid "Acceleration:" +msgstr "Acceleració:" + +#: ../../po/../src/dialogs/display-settings.cpp:940 +msgid "" +"Pressing and holding Ctrl+arrow will gradually speed up scrolling (0 for no " +"acceleration)" +msgstr "" +"En prémer i mantenir control i fletxa, gradualment accelerarà el " +"desplaçament (0 per a no accelerar)" + +#: ../../po/../src/dialogs/display-settings.cpp:949 +msgid "Autoscrolling" +msgstr "Desplaçament automàtic" + +#: ../../po/../src/dialogs/display-settings.cpp:957 +msgid "Speed:" +msgstr "Velocitat:" + +#: ../../po/../src/dialogs/display-settings.cpp:958 +msgid "" +"How fast the canvas autoscrolls when you drag beyond canvas edge (0 to turn " +"autoscroll off)" +msgstr "" +"A quina velocitat el llenç es desplaça automàticament més enllà del contorn " +"del llenç (0 per desactivar el desplaçament automàtic)" + +#: ../../po/../src/dialogs/display-settings.cpp:968 +#: ../../po/../src/ui/dialog/tracedialog.cpp:357 +#: ../../po/../src/ui/dialog/tracedialog.cpp:390 +msgid "Threshold:" +msgstr "Llindar:" + +#: ../../po/../src/dialogs/display-settings.cpp:969 +msgid "" +"How far (in screen pixels) you need to be from the canvas edge to trigger " +"autoscroll; positive is outside the canvas, negative is within the canvas" +msgstr "" +"A quina distància (en píxels de pantalla) heu d'estar del contorn del llenç " +"per a activar el desplaçament automàtic. Positiu és fora del llenç, negatiu " +"és dins" + +#. Steps +#: ../../po/../src/dialogs/display-settings.cpp:979 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:57 +msgid "Steps" +msgstr "Passos" + +#: ../../po/../src/dialogs/display-settings.cpp:982 +msgid "Arrow keys move by:" +msgstr "Les tecles de fletxa mouen:" + +#: ../../po/../src/dialogs/display-settings.cpp:983 +msgid "" +"Pressing an arrow key moves selected object(s) or node(s) by this distance " +"(in px units)" +msgstr "" +"En prémer una tecla de fletxa es mou els objectes seleccionats o els nodes " +"aquesta distància (en unitats de píxels)" + +#: ../../po/../src/dialogs/display-settings.cpp:984 +#: ../../po/../src/dialogs/display-settings.cpp:995 +#: ../../po/../src/dialogs/display-settings.cpp:1006 +#: ../../po/../src/helper/units.cpp:42 +msgid "px" +msgstr "px" + +#: ../../po/../src/dialogs/display-settings.cpp:993 +msgid "> and < scale by:" +msgstr "> i < escalen:" + +#: ../../po/../src/dialogs/display-settings.cpp:994 +msgid "" +"Pressing > or < scales selection up or down by this increment (in px units)" +msgstr "" +"En prémer > o < s'escala la selecció o es redueix en aquesta quantitat (en " +"unitats de píxel)" + +#: ../../po/../src/dialogs/display-settings.cpp:1004 +msgid "Inset/Outset by:" +msgstr "Contreu/expandeix:" + +#: ../../po/../src/dialogs/display-settings.cpp:1005 +msgid "" +"Inset and Outset commands displace the path by this distance (in px units)" +msgstr "" +"Les ordres d'expandir i contreure desplacen el camí aquesta distància (en " +"unitats de píxel)" + +#: ../../po/../src/dialogs/display-settings.cpp:1017 +msgid "Compass-like display of angles" +msgstr "Mostra els angles com en un compàs" + +#. TRANSLATORS: "positive clockwise" means "increasing in clockwise direction" +#: ../../po/../src/dialogs/display-settings.cpp:1019 +msgid "" +"When on, angles are displayed with 0 at north, 0 to 360 range, positive " +"clockwise; otherwise with 0 at east, -180 to 180 range, positive " +"counterclockwise" +msgstr "" +"Quan estigui activat, els angles es visualitzaen amb 0 al nort, de 0 a 360 " +"graus, positiu, en sentit horari; en cas contrari, 0 a l'est, de -180 a 180, " +"positiu, en sentit antihorari" + +#: ../../po/../src/dialogs/display-settings.cpp:1026 +msgid "Zoom in/out by:" +msgstr "Ampliació:" + +#: ../../po/../src/dialogs/display-settings.cpp:1027 +msgid "" +"Zoom tool click, +/- keys, and middle click zoom in and out by this " +"multiplier" +msgstr "" +"El clic de l'eina d'ampliació, les tecles +/- i el clic central amplien i " +"redueixen per aquesta quantitat" + +#: ../../po/../src/dialogs/display-settings.cpp:1028 +#: ../../po/../src/helper/units.cpp:44 +msgid "%" +msgstr "%" + +#. Tools +#: ../../po/../src/dialogs/display-settings.cpp:1037 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:58 +msgid "Tools" +msgstr "Eines" + +#: ../../po/../src/dialogs/display-settings.cpp:1045 +msgid "Selector" +msgstr "Seleccionador" + +#: ../../po/../src/dialogs/display-settings.cpp:1056 +msgid "Node" +msgstr "Node" + +#: ../../po/../src/dialogs/display-settings.cpp:1064 +#: ../../po/../src/verbs.cpp:2073 +#: ../../po/../src/widgets/desktop-widget.cpp:277 +msgid "Zoom" +msgstr "Ampliació" + +#. The 4 shape tools +#: ../../po/../src/dialogs/display-settings.cpp:1071 +msgid "Shapes" +msgstr "Formes" + +#: ../../po/../src/dialogs/display-settings.cpp:1079 +#: ../../po/../src/verbs.cpp:2055 +msgid "Rectangle" +msgstr "Rectangle" + +#: ../../po/../src/dialogs/display-settings.cpp:1085 +#: ../../po/../src/verbs.cpp:2057 +msgid "Ellipse" +msgstr "El·lipse" + +#: ../../po/../src/dialogs/display-settings.cpp:1091 +#: ../../po/../src/verbs.cpp:2059 +msgid "Star" +msgstr "Estel" + +#: ../../po/../src/dialogs/display-settings.cpp:1097 +#: ../../po/../src/verbs.cpp:2061 +msgid "Spiral" +msgstr "Espiral" + +#: ../../po/../src/dialogs/display-settings.cpp:1111 +#: ../../po/../src/verbs.cpp:2063 +msgid "Pencil" +msgstr "Llapis" + +#: ../../po/../src/dialogs/display-settings.cpp:1114 +msgid "Tolerance:" +msgstr "Tolerància:" + +#: ../../po/../src/dialogs/display-settings.cpp:1115 +msgid "" +"This value affects the amount of smoothing applied to freehand lines; lower " +"values produce more uneven paths with more nodes" +msgstr "" +"Aquest valor afecta la quantitat de suavitzat aplicat a les línies a mà " +"alçada; els valors més petits produeixen camins desiguals amb més nodes" + +#: ../../po/../src/dialogs/display-settings.cpp:1131 +#: ../../po/../src/verbs.cpp:2065 +msgid "Pen" +msgstr "Retolador" + +#: ../../po/../src/dialogs/display-settings.cpp:1140 +#: ../../po/../src/verbs.cpp:2067 +msgid "Calligraphy" +msgstr "Cal·ligrafia" + +#: ../../po/../src/dialogs/display-settings.cpp:1147 +#: ../../po/../src/dialogs/text-edit.cpp:353 +#: ../../po/../src/ui/dialog/text-properties.cpp:37 +#: ../../po/../src/verbs.cpp:2069 +msgid "Text" +msgstr "Text" + +#: ../../po/../src/dialogs/display-settings.cpp:1157 +#: ../../po/../src/verbs.cpp:2071 +msgid "Gradient" +msgstr "Degradat" + +#: ../../po/../src/dialogs/display-settings.cpp:1164 +#: ../../po/../src/verbs.cpp:2077 +msgid "Connector" +msgstr "Connector" + +#: ../../po/../src/dialogs/display-settings.cpp:1171 +#: ../../po/../src/verbs.cpp:2075 +msgid "Dropper" +msgstr "Comptagotes" + +#. Windows +#: ../../po/../src/dialogs/display-settings.cpp:1183 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:59 +msgid "Windows" +msgstr "Finestres" + +#: ../../po/../src/dialogs/display-settings.cpp:1188 +msgid "Save window geometry" +msgstr "Desa la geometria de la finestra" + +#: ../../po/../src/dialogs/display-settings.cpp:1189 +msgid "" +"Save the window size and position with each document (only for Inkscape SVG " +"format)" +msgstr "" +"Desa la mida de la finestra i la posició amb cada document (només per al " +"format SVG de l'Inkscape)" + +#: ../../po/../src/dialogs/display-settings.cpp:1196 +msgid "Dialogs are hidden in taskbar" +msgstr "Oculta els diàlegs a la barra de tasques" + +#: ../../po/../src/dialogs/display-settings.cpp:1197 +msgid "Whether dialog windows are to be hidden in the window manager taskbar" +msgstr "" +"Si s'ha d'ocultar les finestres a la barra de tasques del gestor de finestres" + +#: ../../po/../src/dialogs/display-settings.cpp:1204 +msgid "Zoom when window is resized" +msgstr "Apropa/allunya si canvia la mida de la finestra" + +#: ../../po/../src/dialogs/display-settings.cpp:1205 +msgid "" +"Zoom drawing when document window is resized, to keep the same area visible " +"(this is the default which can be changed in any window using the button " +"above the right scrollbar)" +msgstr "" +"Apropa el dibuix quan es canvia la mida de la finestra del document, per " +"mantenir la mateixa àrea visible (es pot canviar aquest valor predeterminat " +"fent servir el botó a sobre de la barra de desplaçament de la dreta)" + +#. Clones +#: ../../po/../src/dialogs/display-settings.cpp:1213 +#: ../../po/../src/dialogs/find.cpp:624 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:60 +msgid "Clones" +msgstr "Clons" + +#: ../../po/../src/dialogs/display-settings.cpp:1217 +msgid "When the original moves, its clones and linked offsets:" +msgstr "Quan l'original es mou, els seus clons i desplaçaments enllaçats:" + +#: ../../po/../src/dialogs/display-settings.cpp:1229 +msgid "Move in parallel" +msgstr "Es mouen en paral·lel" + +#: ../../po/../src/dialogs/display-settings.cpp:1230 +msgid "Clones are translated by the same vector as their original." +msgstr "Els clons es traslladen seguint el mateix vector que l'original." + +#: ../../po/../src/dialogs/display-settings.cpp:1237 +msgid "Stay unmoved" +msgstr "No es mouen" + +#: ../../po/../src/dialogs/display-settings.cpp:1238 +msgid "Clones preserve their positions when their original is moved." +msgstr "Els clons mantenen la seva posició quan es mou l'original." + +#: ../../po/../src/dialogs/display-settings.cpp:1245 +msgid "Move according to transform" +msgstr "Mou com la transformació" + +#: ../../po/../src/dialogs/display-settings.cpp:1246 +msgid "" +"Each clone moves according to the value of its transform= attribute. For " +"example, a rotated clone will move in a different direction than its " +"original." +msgstr "" +"Cada clon es mou segons el valor de l'atribut transform=. Per exemple, un " +"clon rotat es mourà en una direcció diferent que el seu original." + +#: ../../po/../src/dialogs/display-settings.cpp:1255 +msgid "When the original is deleted, its clones:" +msgstr "Quan l'original s'esborra, els seus clons:" + +#: ../../po/../src/dialogs/display-settings.cpp:1267 +msgid "Are unlinked" +msgstr "Es desenllacen" + +#: ../../po/../src/dialogs/display-settings.cpp:1267 +msgid "Orphaned clones are converted to regular objects." +msgstr "Els clons orfes es converteixen en objectes normals." + +#: ../../po/../src/dialogs/display-settings.cpp:1273 +msgid "Are deleted" +msgstr "Se suprimeixen" + +#: ../../po/../src/dialogs/display-settings.cpp:1273 +msgid "Orphaned clones are deleted along with their original." +msgstr "Els clons orfes se suprimeixen juntament amb l'original." + +#. Transforms +#. TRANSLATORS: Noun, i.e. transformations. +#: ../../po/../src/dialogs/display-settings.cpp:1289 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:61 +msgid "Transforms" +msgstr "Transformacions" + +#: ../../po/../src/dialogs/display-settings.cpp:1292 +msgid "Scale stroke width" +msgstr "Escala l'amplada del contorn" + +#: ../../po/../src/dialogs/display-settings.cpp:1293 +#: ../../po/../src/widgets/select-toolbar.cpp:568 +msgid "When scaling objects, scale the stroke width by the same proportion" +msgstr "En escalar objectes, escala l'amplada del contorn proporcionalment" + +#: ../../po/../src/dialogs/display-settings.cpp:1300 +msgid "Scale rounded corners in rectangles" +msgstr "Escala les cantonades arrodonides als rectangles" + +#: ../../po/../src/dialogs/display-settings.cpp:1301 +#: ../../po/../src/widgets/select-toolbar.cpp:580 +msgid "When scaling rectangles, scale the radii of rounded corners" +msgstr "" +"En escalar els rectangles, escala el radi de les cantonades arrodonides" + +#: ../../po/../src/dialogs/display-settings.cpp:1308 +msgid "Transform gradients" +msgstr "Transforma els degradats" + +#: ../../po/../src/dialogs/display-settings.cpp:1309 +#: ../../po/../src/widgets/select-toolbar.cpp:592 +msgid "Transform gradients (in fill or stroke) along with the objects" +msgstr "" +"Transforma els degradats (en omplir o contorn) juntament amb els objectes" + +#: ../../po/../src/dialogs/display-settings.cpp:1316 +msgid "Transform patterns" +msgstr "Transforma els patrons" + +#: ../../po/../src/dialogs/display-settings.cpp:1317 +#: ../../po/../src/widgets/select-toolbar.cpp:604 +msgid "Transform patterns (in fill or stroke) along with the objects" +msgstr "" +"Transforma els patrons (en omplir o contorn) juntament amb els objectes" + +#. TRANSLATORS: How to specify the affine transformation in the SVG file. +#: ../../po/../src/dialogs/display-settings.cpp:1327 +msgid "Store transformation:" +msgstr "Emmagatzema la transformació:" + +#: ../../po/../src/dialogs/display-settings.cpp:1338 +msgid "Optimized" +msgstr "Optimitzat" + +#: ../../po/../src/dialogs/display-settings.cpp:1339 +msgid "" +"If possible, apply transformation to objects without adding a transform= " +"attribute" +msgstr "" +"Quan sigui possible, aplica les transformacions als objectes sense afegir " +"l'atribut transform=" + +#: ../../po/../src/dialogs/display-settings.cpp:1346 +msgid "Preserved" +msgstr "Preservat" + +#: ../../po/../src/dialogs/display-settings.cpp:1347 +msgid "Always store transformation as a transform= attribute on objects" +msgstr "" +"Emmagatzema sempre les transformacions com a atribut transform= en els " +"objectes" + +#. Selecting +#: ../../po/../src/dialogs/display-settings.cpp:1355 +msgid "Selecting" +msgstr "Seleccionar" + +#: ../../po/../src/dialogs/display-settings.cpp:1357 +msgid "Ctrl+A, Tab, Shift+Tab:" +msgstr "Ctrl+a, tab., maj.+tab:" + +#: ../../po/../src/dialogs/display-settings.cpp:1366 +msgid "Select only within current layer" +msgstr "Selecciona només la capa actual" + +#: ../../po/../src/dialogs/display-settings.cpp:1367 +msgid "" +"Uncheck this to make keyboard selection commands work on objects in all " +"layers" +msgstr "" +"Inhabiliteu-lo per fer que les ordres de selecció de teclat funcionin en " +"objectes en totes les capes" + +#: ../../po/../src/dialogs/display-settings.cpp:1374 +msgid "Ignore hidden objects" +msgstr "Ignora els objectes amagats" + +#: ../../po/../src/dialogs/display-settings.cpp:1375 +msgid "" +"Uncheck this to be able to select objects that are hidden (either by " +"themselves or by being in a hidden group or layer)" +msgstr "" +"Inhabiliteu-lo per seleccionar objectes amagats (per estar amagats o per " +"estar en un grup o capa amagats)" + +#: ../../po/../src/dialogs/display-settings.cpp:1382 +msgid "Ignore locked objects" +msgstr "Ignora els objectes blocats" + +#: ../../po/../src/dialogs/display-settings.cpp:1383 +msgid "" +"Uncheck this to be able to select objects that are locked (either by " +"themselves or by being in a locked group or layer)" +msgstr "" +"Inhabiliteu-lo per seleccionar objectes blocats (per estar amagats o per " +"estar en un grup o capa blocats)" + +#. To be broken into: Display, Save, Export, SVG, Commands +#: ../../po/../src/dialogs/display-settings.cpp:1391 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:62 +msgid "Misc" +msgstr "Miscel·lània" + +#: ../../po/../src/dialogs/display-settings.cpp:1394 +msgid "Default export resolution:" +msgstr "Resolució per exportar predeterminada:" + +#: ../../po/../src/dialogs/display-settings.cpp:1395 +msgid "Default bitmap resolution (in dots per inch) in the Export dialog" +msgstr "" +"Resolució preferida (punts per polzada) del mapa de bits per al diàleg " +"d'exportar" + +#. FIXME: add "Used for new exports; once exported, documents remember this value on per-object basis" when implemented +#: ../../po/../src/dialogs/display-settings.cpp:1396 +#: ../../po/../src/dialogs/export.cpp:442 +msgid "dpi" +msgstr "ppp" + +#. TRANSLATORS: When on, an imported bitmap creates an element; otherwise it is a +#. * rectangle with bitmap fill. +#: ../../po/../src/dialogs/display-settings.cpp:1407 +msgid "Import bitmap as " +msgstr "Importa un mapa de bits com a " + +#: ../../po/../src/dialogs/display-settings.cpp:1408 +msgid "" +"When on, an imported bitmap creates an element; otherwise it is a " +"rectangle with bitmap fill" +msgstr "" +"Si està habilitat, en importar un mapa de bits es crea un element ; " +"en cas contrari és un rectangle amb un fons de mapa de bits" + +#. TRANSLATORS: When on, the print out (currently Postscript) will have +#. * a comment with the each object's label visible, marking the section +#. * of the printing commands that represent the given object. +#: ../../po/../src/dialogs/display-settings.cpp:1418 +msgid "Add label comments to printing output" +msgstr "Afegeix comentaris d'etiqueta a la sortida d'impressió" + +#: ../../po/../src/dialogs/display-settings.cpp:1419 +msgid "" +"When on, a comment will be added to the raw print output, marking the " +"rendered output for an object with its label" +msgstr "" +"Si està habilitat, s'afegirà un comentari a la sortida d'impressió, que " +"marqui la sortida generada per a un objecte amb la seva etiqueta" + +#. TRANSLATORS: When on, enable the effects menu, default is off +#: ../../po/../src/dialogs/display-settings.cpp:1427 +msgid "Enable script effects (requires restart) - EXPERIMENTAL" +msgstr "Habilita els efectes de fitxer d'ordres (cal reiniciar) - EXPERIMENTAL" + +#: ../../po/../src/dialogs/display-settings.cpp:1428 +msgid "" +"When on, the effects menu is enabled, allowing external effect scripts to be " +"called, requires restart before effective - EXPERIMENTAL" +msgstr "" +"Quan està activat, el menú d'efectes està habilitat i es permeten les " +"seqüències d'efectes externes. Es necessita reiniciar abans de ser efectiu - " +"EXPERIMENTAL" + +#. TRANSLATORS: The maximum length of the Open Recent list in the File menu. +#: ../../po/../src/dialogs/display-settings.cpp:1436 +msgid "Max recent documents:" +msgstr "Nombre màxim de documents:" + +#: ../../po/../src/dialogs/display-settings.cpp:1437 +msgid "The maximum length of the Open Recent list in the File menu" +msgstr "" +"La longitud màxima de la llista per obrir un fitxer recent en el menú Fitxer" + +#: ../../po/../src/dialogs/display-settings.cpp:1447 +msgid "Simplification threshold:" +msgstr "Llindar de simplificació:" + +#: ../../po/../src/dialogs/display-settings.cpp:1448 +msgid "" +"How strong is the Simplify command by default. If you invoke this command " +"several times in quick succession, it will act more and more aggressively; " +"invoking it again after a pause restores the default threshold." +msgstr "" +"La força predeterminada que tindrà l'ordre de simplificació. Si invoqueu de " +"forma successiva i ràpidament aquesta ordre, actuarà cada vegada més " +"agressivament. En invocar-la després d'una pausa es retorna al valor " +"predeterminat del llindar." + +#: ../../po/../src/dialogs/display-settings.cpp:1469 +msgid "Oversample bitmaps:" +msgstr "Sobremostreja els mapes de bits:" + +#: ../../po/../src/dialogs/display-settings.cpp:1488 +msgid "2x2" +msgstr "2x2" + +#: ../../po/../src/dialogs/display-settings.cpp:1494 +msgid "4x4" +msgstr "4x4" + +#: ../../po/../src/dialogs/display-settings.cpp:1500 +msgid "8x8" +msgstr "8x8" + +#: ../../po/../src/dialogs/display-settings.cpp:1506 +msgid "16x16" +msgstr "16x16" + +#. "view_icon_preview" +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2143 +msgid "_Page" +msgstr "_Pàgina" + +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2147 +msgid "_Drawing" +msgstr "_Dibuix" + +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2149 +msgid "_Selection" +msgstr "_Selecció" + +#: ../../po/../src/dialogs/export.cpp:133 +msgid "_Custom" +msgstr "_Personalitzat" + +#: ../../po/../src/dialogs/export.cpp:254 +msgid "Export area" +msgstr "Àrea d'exportació" + +#: ../../po/../src/dialogs/export.cpp:300 +msgid "_x0:" +msgstr "_x0:" + +#: ../../po/../src/dialogs/export.cpp:305 +msgid "x_1:" +msgstr "x_1:" + +#: ../../po/../src/dialogs/export.cpp:316 +msgid "_y0:" +msgstr "_y0:" + +#: ../../po/../src/dialogs/export.cpp:321 +msgid "y_1:" +msgstr "y_1:" + +#: ../../po/../src/dialogs/export.cpp:406 +msgid "Bitmap size" +msgstr "Mida del mapa de bits" + +#: ../../po/../src/dialogs/export.cpp:416 +msgid "_Width:" +msgstr "A_mplada:" + +#: ../../po/../src/dialogs/export.cpp:416 +#: ../../po/../src/dialogs/export.cpp:431 +msgid "pixels at" +msgstr "píxels a" + +#: ../../po/../src/dialogs/export.cpp:426 +msgid "dp_i" +msgstr "_ppp" + +#: ../../po/../src/dialogs/export.cpp:448 +msgid "_Filename" +msgstr "Nom del _fitxer" + +#: ../../po/../src/dialogs/export.cpp:512 +msgid "_Browse..." +msgstr "_Navega..." + +#: ../../po/../src/dialogs/export.cpp:539 +msgid " _Export " +msgstr " _Exporta " + +#: ../../po/../src/dialogs/export.cpp:541 +msgid "Export the bitmap file with these settings" +msgstr "Exporta el fitxer de mapa de bits amb aquests valors" + +#: ../../po/../src/dialogs/export.cpp:968 +msgid "You have to enter a filename" +msgstr "Heu d'introduir un nom de fitxer" + +#: ../../po/../src/dialogs/export.cpp:973 +msgid "The chosen area to be exported is invalid" +msgstr "L'àrea escollida per ser exportada no és vàlida" + +#: ../../po/../src/dialogs/export.cpp:982 +#, c-format +msgid "Directory %s does not exist or is not a directory.\n" +msgstr "El directori %s no existeix o no és un directori.\n" + +#: ../../po/../src/dialogs/export.cpp:998 +msgid "Export in progress" +msgstr "S'està exportant" + +#: ../../po/../src/dialogs/export.cpp:1004 +#, c-format +msgid "Exporting %s (%d x %d)" +msgstr "S'està exportant %s (%d x %d)" + +#: ../../po/../src/dialogs/export.cpp:1031 +#, c-format +msgid "Could not export to filename %s.\n" +msgstr "No s'ha pogut exportar al fitxer %s.\n" + +#: ../../po/../src/dialogs/export.cpp:1137 +msgid "Select a filename for exporting" +msgstr "Seleccioneu el nom de fitxer per exportar" + +#: ../../po/../src/dialogs/filedialog.cpp:367 +msgid "No preview" +msgstr "No previsualitzis" + +#: ../../po/../src/dialogs/filedialog.cpp:468 +msgid "too large for preview" +msgstr "massa gran per previsualitzar" + +#: ../../po/../src/dialogs/filedialog.cpp:762 +#: ../../po/../src/dialogs/filedialog.cpp:763 +msgid "All Images" +msgstr "Totes les imatges" + +#: ../../po/../src/dialogs/filedialog.cpp:767 +#: ../../po/../src/dialogs/filedialog.cpp:768 +msgid "All Files" +msgstr "Tots els fitxers" + +#: ../../po/../src/dialogs/filedialog.cpp:774 +#: ../../po/../src/dialogs/filedialog.cpp:775 +msgid "All Inkscape Files" +msgstr "Tots els fitxers de l'Inkscape" + +#: ../../po/../src/dialogs/filedialog.cpp:1176 +msgid "Guess from extension" +msgstr "Segons l'extensió" + +#. ###### Add the file types menu +#. createFilterMenu(); +#. ###### Do we want the .xxx extension automatically added? +#: ../../po/../src/dialogs/filedialog.cpp:1261 +msgid "Append filename extension automatically" +msgstr "Afegeix l'extensió al fitxer automàticament" + +#. TRANSLATORS: "%s" is replaced with "exact" or "partial" when this string is displayed +#: ../../po/../src/dialogs/find.cpp:378 +#, c-format +msgid "%d object found (out of %d), %s match." +msgid_plural "%d objects found (out of %d), %s match." +msgstr[0] "" +"S'han trobat %d objecte (d'un total de %d). La concordança és %s." +msgstr[1] "" +"S'han trobat %d objectes (d'un total de %d). La concordança és %s." + +#: ../../po/../src/dialogs/find.cpp:381 +msgid "exact" +msgstr "exacta" + +#: ../../po/../src/dialogs/find.cpp:381 +msgid "partial" +msgstr "parcial" + +#: ../../po/../src/dialogs/find.cpp:388 +msgid "No objects found" +msgstr "No s'ha trobat cap objecte" + +#: ../../po/../src/dialogs/find.cpp:546 +msgid "T_ype: " +msgstr "T_ipus: " + +#: ../../po/../src/dialogs/find.cpp:553 +msgid "Search in all object types" +msgstr "Cerca a tots els tipus d'objecte" + +#: ../../po/../src/dialogs/find.cpp:553 +msgid "All types" +msgstr "Tots els tipus" + +#: ../../po/../src/dialogs/find.cpp:564 +msgid "Search all shapes" +msgstr "Cerca totes les formes" + +#: ../../po/../src/dialogs/find.cpp:564 +msgid "All shapes" +msgstr "Totes les formes" + +#: ../../po/../src/dialogs/find.cpp:581 +msgid "Search rectangles" +msgstr "Cerca rectangles" + +#: ../../po/../src/dialogs/find.cpp:581 +msgid "Rectangles" +msgstr "Rectangles" + +#: ../../po/../src/dialogs/find.cpp:586 +msgid "Search ellipses, arcs, circles" +msgstr "Cerca el·lipses, arcs, cercles" + +#: ../../po/../src/dialogs/find.cpp:586 +msgid "Ellipses" +msgstr "El·lipses" + +#: ../../po/../src/dialogs/find.cpp:591 +msgid "Search stars and polygons" +msgstr "Cerca estels i polígons" + +#: ../../po/../src/dialogs/find.cpp:591 +msgid "Stars" +msgstr "Estels" + +#: ../../po/../src/dialogs/find.cpp:596 +msgid "Search spirals" +msgstr "Cerca espirals" + +#: ../../po/../src/dialogs/find.cpp:596 +msgid "Spirals" +msgstr "Espirals" + +#. TRANSLATORS: polyline is a set of connected straight line segments +#. http://www.w3.org/TR/SVG11/shapes.html#PolylineElement +#: ../../po/../src/dialogs/find.cpp:609 +msgid "Search paths, lines, polylines" +msgstr "Cerca camins, línies i polilínies" + +#: ../../po/../src/dialogs/find.cpp:609 +msgid "Paths" +msgstr "Camins" + +#: ../../po/../src/dialogs/find.cpp:614 +msgid "Search text objects" +msgstr "Cerca objectes de text" + +#: ../../po/../src/dialogs/find.cpp:614 +msgid "Texts" +msgstr "Texts" + +#: ../../po/../src/dialogs/find.cpp:619 +msgid "Search groups" +msgstr "Cerca grups" + +#: ../../po/../src/dialogs/find.cpp:619 +msgid "Groups" +msgstr "Grups" + +#: ../../po/../src/dialogs/find.cpp:624 +msgid "Search clones" +msgstr "Cerca clons" + +#: ../../po/../src/dialogs/find.cpp:629 +msgid "Search images" +msgstr "Cerca imatges" + +#: ../../po/../src/dialogs/find.cpp:629 +msgid "Images" +msgstr "Imatges" + +#: ../../po/../src/dialogs/find.cpp:634 +msgid "Search offset objects" +msgstr "Cerca objectes de desplaçament" + +#: ../../po/../src/dialogs/find.cpp:634 +msgid "Offsets" +msgstr "Desplaçaments" + +#: ../../po/../src/dialogs/find.cpp:694 +msgid "_Text: " +msgstr "_Text: " + +#: ../../po/../src/dialogs/find.cpp:694 +msgid "Find objects by their text content (exact or partial match)" +msgstr "" +"Cerca objectes segons el seu contingut de text (concordança exacta o parcial)" + +#: ../../po/../src/dialogs/find.cpp:695 +msgid "_ID: " +msgstr "_ID: " + +#: ../../po/../src/dialogs/find.cpp:695 +msgid "Find objects by the value of the id attribute (exact or partial match)" +msgstr "" +"Cerca objectes segons el valor de l'atribut id (concordança exacta o parcial)" + +#: ../../po/../src/dialogs/find.cpp:696 +msgid "_Style: " +msgstr "E_stil: " + +#: ../../po/../src/dialogs/find.cpp:696 +msgid "" +"Find objects by the value of the style attribute (exact or partial match)" +msgstr "" +"Cerca objectes segons el valor de l'atribut estil (concordança exacta o " +"parcial)" + +#: ../../po/../src/dialogs/find.cpp:697 +msgid "_Attribute: " +msgstr "_Atribut: " + +#: ../../po/../src/dialogs/find.cpp:697 +msgid "Find objects by the name of an attribute (exact or partial match)" +msgstr "Cerca objectes pel nom d'un atribut (concordança exacta o parcial)" + +#: ../../po/../src/dialogs/find.cpp:711 +msgid "Search in s_election" +msgstr "C_erca a la selecció" + +#: ../../po/../src/dialogs/find.cpp:715 +msgid "Limit search to the current selection" +msgstr "Limita la cerca a la selecció actual" + +#: ../../po/../src/dialogs/find.cpp:720 +msgid "Search in current _layer" +msgstr "Cerca a _la capa actual" + +#: ../../po/../src/dialogs/find.cpp:724 +msgid "Limit search to the current layer" +msgstr "Limita la cerca a la capa actual" + +#: ../../po/../src/dialogs/find.cpp:729 +msgid "Include _hidden" +msgstr "Inclou els ama_gats" + +#: ../../po/../src/dialogs/find.cpp:733 +msgid "Include hidden objects in search" +msgstr "Inclou els objectes amagats en la cerca" + +#: ../../po/../src/dialogs/find.cpp:738 +msgid "Include l_ocked" +msgstr "Incl_ou els blocats" + +#: ../../po/../src/dialogs/find.cpp:742 +msgid "Include locked objects in search" +msgstr "Inclou els objectes blocats en la cerca" + +#: ../../po/../src/dialogs/find.cpp:753 +msgid "Clear values" +msgstr "Neteja valors" + +#: ../../po/../src/dialogs/find.cpp:754 +msgid "_Find" +msgstr "_Cerca" + +#: ../../po/../src/dialogs/find.cpp:754 +msgid "Select objects matching all of the fields you filled in" +msgstr "Selecciona objectes que concorden amb els camps que heu emplenat" + +#: ../../po/../src/dialogs/iconpreview.cpp:145 +#, c-format +msgid "%d x %d" +msgstr "%d x %d" + +#: ../../po/../src/dialogs/iconpreview.cpp:193 +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:857 +#: ../../po/../src/widgets/desktop-widget.cpp:1069 +msgid "Selection" +msgstr "Selecció" + +#: ../../po/../src/dialogs/iconpreview.cpp:195 +msgid "Selection only or whole document" +msgstr "Només selecció o document sencer" + +#: ../../po/../src/dialogs/iconpreview.cpp:203 +msgid "Refresh the icons" +msgstr "Actualitza les icones" + +#. Create the label for the object id +#: ../../po/../src/dialogs/item-properties.cpp:126 +#: ../../po/../src/dialogs/item-properties.cpp:327 +#: ../../po/../src/dialogs/item-properties.cpp:396 +#: ../../po/../src/dialogs/item-properties.cpp:403 +msgid "_Id" +msgstr "_Id" + +#: ../../po/../src/dialogs/item-properties.cpp:135 +msgid "" +"The id= attribute (only letters, digits, and the characters .-_: allowed)" +msgstr "L'atribut id= (només lletres, nombres i els caràcters .-_: )" + +#. Button for setting the object's id, label, title and description. +#: ../../po/../src/dialogs/item-properties.cpp:149 +msgid "_Set" +msgstr "A_ssigna" + +#. Create the label for the object label +#: ../../po/../src/dialogs/item-properties.cpp:158 +msgid "_Label" +msgstr "E_tiqueta" + +#: ../../po/../src/dialogs/item-properties.cpp:167 +msgid "A freeform label for the object" +msgstr "Una etiqueta per a l'objecte" + +#. Create the label for the object title +#: ../../po/../src/dialogs/item-properties.cpp:179 +#: ../../po/../src/dialogs/rdf.cpp:243 +msgid "Title" +msgstr "Títol" + +#. Create the frame for the object description +#: ../../po/../src/dialogs/item-properties.cpp:196 +#: ../../po/../src/dialogs/rdf.cpp:287 +msgid "Description" +msgstr "Descripció" + +#. Hide +#: ../../po/../src/dialogs/item-properties.cpp:223 +msgid "_Hide" +msgstr "A_maga" + +#: ../../po/../src/dialogs/item-properties.cpp:224 +msgid "Check to make the object invisible" +msgstr "Habiliteu-lo per fer invisible l'objecte" + +#. Lock +#. TRANSLATORS: "Lock" is a verb here +#: ../../po/../src/dialogs/item-properties.cpp:233 +msgid "L_ock" +msgstr "Bl_oca" + +#: ../../po/../src/dialogs/item-properties.cpp:234 +msgid "Check to make the object insensitive (not selectable by mouse)" +msgstr "" +"Habiliteu-lo per fer que l'objecte no es pugui seleccionar amb el ratolí" + +#: ../../po/../src/dialogs/item-properties.cpp:310 +#: ../../po/../src/dialogs/item-properties.cpp:317 +msgid "Ref" +msgstr "Ref" + +#: ../../po/../src/dialogs/item-properties.cpp:398 +msgid "Id invalid! " +msgstr "L'identificador no és vàlid " + +#: ../../po/../src/dialogs/item-properties.cpp:400 +msgid "Id exists! " +msgstr "L'identificador existeix " + +#: ../../po/../src/dialogs/layer-properties.cpp:50 +msgid "Layer name:" +msgstr "Nom de la capa:" + +#: ../../po/../src/dialogs/layer-properties.cpp:133 +msgid "Rename Layer" +msgstr "Reanomena la capa" + +#: ../../po/../src/dialogs/layer-properties.cpp:136 +msgid "_Rename" +msgstr "_Reanomena" + +#. TRANSLATORS: This means "The layer has been renamed" +#: ../../po/../src/dialogs/layer-properties.cpp:147 +msgid "Renamed layer" +msgstr "Capa reanomenada" + +#: ../../po/../src/dialogs/layer-properties.cpp:151 +msgid "Add Layer" +msgstr "Afegeix capa" + +#: ../../po/../src/dialogs/layer-properties.cpp:153 +msgid "_Add" +msgstr "_Afegeix" + +#: ../../po/../src/dialogs/layer-properties.cpp:167 +msgid "New layer created." +msgstr "S'ha creat una nova capa." + +#: ../../po/../src/dialogs/object-attributes.cpp:34 +msgid "Href:" +msgstr "Href:" + +#: ../../po/../src/dialogs/object-attributes.cpp:35 +msgid "Target:" +msgstr "Destí:" + +#: ../../po/../src/dialogs/object-attributes.cpp:36 +msgid "Type:" +msgstr "Tipus:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkRoleAttribute +#. Identifies the type of the related resource with an absolute URI +#: ../../po/../src/dialogs/object-attributes.cpp:39 +msgid "Role:" +msgstr "Rol:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkArcRoleAttribute +#. For situations where the nature/role alone isn't enough, this offers an additional URI defining the purpose of the link. +#: ../../po/../src/dialogs/object-attributes.cpp:42 +msgid "Arcrole:" +msgstr "Arcrol:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkTitleAttribute +#: ../../po/../src/dialogs/object-attributes.cpp:44 +msgid "Title:" +msgstr "Títol:" + +#: ../../po/../src/dialogs/object-attributes.cpp:45 +msgid "Show:" +msgstr "Mostra:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkActuateAttribute +#: ../../po/../src/dialogs/object-attributes.cpp:47 +msgid "Actuate:" +msgstr "Actua:" + +#: ../../po/../src/dialogs/object-attributes.cpp:52 +msgid "URL:" +msgstr "URL:" + +#: ../../po/../src/dialogs/object-attributes.cpp:53 +msgid "X:" +msgstr "X:" + +#: ../../po/../src/dialogs/object-attributes.cpp:54 +msgid "Y:" +msgstr "Y:" + +#: ../../po/../src/dialogs/object-attributes.cpp:98 +#, c-format +msgid "%s attributes" +msgstr "Atributs de %s" + +#: ../../po/../src/dialogs/object-properties.cpp:158 +msgid "_Fill" +msgstr "_Omple" + +#: ../../po/../src/dialogs/object-properties.cpp:165 +msgid "Stroke _paint" +msgstr "_Pinta el contorn" + +#: ../../po/../src/dialogs/object-properties.cpp:172 +msgid "Stroke st_yle" +msgstr "Estil del co_ntorn" + +#: ../../po/../src/dialogs/object-properties.cpp:183 +msgid "Master _opacity" +msgstr "_Opacitat principal" + +#: ../../po/../src/dialogs/rdf.cpp:244 +msgid "Name by which this document is formally known." +msgstr "Nom pel qual es coneix formalment aquest document." + +#: ../../po/../src/dialogs/rdf.cpp:246 +msgid "Date" +msgstr "Data" + +#: ../../po/../src/dialogs/rdf.cpp:247 +msgid "Date associated with the creation of this document (YYYY-MM-DD)." +msgstr "Data associada amb la creació d'aquest document (AAAA-MM-DD)." + +#: ../../po/../src/dialogs/rdf.cpp:249 +msgid "Format" +msgstr "Format" + +#: ../../po/../src/dialogs/rdf.cpp:250 +msgid "The physical or digital manifestation of this document (MIME type)." +msgstr "La manifestació física o digital d'aquest document (tipus MIME)." + +#: ../../po/../src/dialogs/rdf.cpp:252 +msgid "Type" +msgstr "Tipus" + +#: ../../po/../src/dialogs/rdf.cpp:253 +msgid "Type of document (DCMI Type)." +msgstr "Tipus de document (tipus DCMI)." + +#: ../../po/../src/dialogs/rdf.cpp:256 +msgid "Creator" +msgstr "Creador" + +#: ../../po/../src/dialogs/rdf.cpp:257 +msgid "" +"Name of entity primarily responsible for making the content of this document." +msgstr "" +"Nom de l'entitat responsable principalment de fer el contingut d'aquest " +"document." + +#: ../../po/../src/dialogs/rdf.cpp:259 +msgid "Rights" +msgstr "Drets" + +#: ../../po/../src/dialogs/rdf.cpp:260 +msgid "" +"Name of entity with rights to the Intellectual Property of this document." +msgstr "" +"Nom de l'entitat amb drets a la propietat intel·lectual d'aquest document." + +#: ../../po/../src/dialogs/rdf.cpp:262 +msgid "Publisher" +msgstr "Editor" + +#: ../../po/../src/dialogs/rdf.cpp:263 +msgid "Name of entity responsible for making this document available." +msgstr "" +"Nom de l'entitat responsable de fer que aquest document estigui disponible." + +#: ../../po/../src/dialogs/rdf.cpp:266 +msgid "Identifier" +msgstr "Identificador" + +#: ../../po/../src/dialogs/rdf.cpp:267 +msgid "Unique URI to reference this document." +msgstr "URI única per referir aquest document." + +#: ../../po/../src/dialogs/rdf.cpp:269 +msgid "Source" +msgstr "Origen" + +#: ../../po/../src/dialogs/rdf.cpp:270 +msgid "Unique URI to reference the source of this document." +msgstr "URI única per referir l'origen d'aquest document." + +#: ../../po/../src/dialogs/rdf.cpp:272 +msgid "Relation" +msgstr "Relació" + +#: ../../po/../src/dialogs/rdf.cpp:273 +msgid "Unique URI to a related document." +msgstr "URI única a un element relacionat." + +#: ../../po/../src/dialogs/rdf.cpp:275 +msgid "Language" +msgstr "Idioma" + +#: ../../po/../src/dialogs/rdf.cpp:276 +msgid "" +"Two-letter language tag with optional subtags for the language of this " +"document. (e.g. 'en-GB')" +msgstr "" +"Etiqueta d'idioma de dues lletres amb subetiquetes opcionals per a l'idioma " +"d'aquest document. (p.e. ca_ES)" + +#: ../../po/../src/dialogs/rdf.cpp:278 +msgid "Keywords" +msgstr "Paraules clau" + +#: ../../po/../src/dialogs/rdf.cpp:279 +msgid "" +"The topic of this document as comma-separated key words, phrases, or " +"classifications." +msgstr "" +"El tema d'aquest document com a paraules clau, frases o classificacions, " +"separats per comes." + +#. TRANSLATORS: "Coverage": the spatial or temporal characteristics of the content. +#. For info, see Appendix D of http://www.w3.org/TR/1998/WD-rdf-schema-19980409/ +#: ../../po/../src/dialogs/rdf.cpp:283 +msgid "Coverage" +msgstr "Àmbit" + +#: ../../po/../src/dialogs/rdf.cpp:284 +msgid "Extent or scope of this document." +msgstr "Àmbit o abast d'aquest document." + +#: ../../po/../src/dialogs/rdf.cpp:288 +msgid "A short account of the content of this document." +msgstr "Un breu resum del contingut d'aquest document." + +#. FIXME: need to handle 1 agent per line of input +#: ../../po/../src/dialogs/rdf.cpp:292 +msgid "Contributors" +msgstr "Contribuïdors" + +#: ../../po/../src/dialogs/rdf.cpp:293 +msgid "" +"Names of entities responsible for making contributions to the content of " +"this document." +msgstr "" +"Noms d'entitats responsable per fer contribucions al contingut d'aquest " +"document." + +#. TRANSLATORS: URL to a page that defines the license for the document +#: ../../po/../src/dialogs/rdf.cpp:297 +msgid "URI" +msgstr "URI" + +#. TRANSLATORS: this is where you put a URL to a page that defines the license +#: ../../po/../src/dialogs/rdf.cpp:299 +msgid "URI to this document's license's namespace definition." +msgstr "URI a la definició de l'espai de noms de la llicència del document." + +#. TRANSLATORS: fragment of XML representing the license of the document +#: ../../po/../src/dialogs/rdf.cpp:303 +msgid "Fragment" +msgstr "Fragment" + +#: ../../po/../src/dialogs/rdf.cpp:304 +msgid "XML fragment for the RDF 'License' section." +msgstr "Fragment XML per a la secció 'Llicència' d'RDF." + +#: ../../po/../src/dialogs/stroke-style.cpp:774 +#: ../../po/../src/widgets/gradient-vector.cpp:263 +#: ../../po/../src/widgets/paint-selector.cpp:751 +msgid "No document selected" +msgstr "No s'ha seleccionat cap document" + +#: ../../po/../src/dialogs/stroke-style.cpp:992 +msgid "Stroke width" +msgstr "Amplada del contorn" + +#. Join type +#. TRANSLATORS: The line join style specifies the shape to be used at the +#. corners of paths. It can be "miter", "round" or "bevel". +#: ../../po/../src/dialogs/stroke-style.cpp:1015 +msgid "Join:" +msgstr "Cantonada:" + +#. TRANSLATORS: Miter join: joining lines with a sharp (pointed) corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1027 +msgid "Miter join" +msgstr "Punxeguda" + +#. TRANSLATORS: Round join: joining lines with a rounded corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1035 +msgid "Round join" +msgstr "Arrodonida" + +#. TRANSLATORS: Bevel join: joining lines with a blunted (flattened) corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1043 +msgid "Bevel join" +msgstr "Plana" + +#. Miterlimit +#. TRANSLATORS: Miter limit: only for "miter join", this limits the length +#. of the sharp "spike" when the lines connect at too sharp an angle. +#. When two line segments meet at a sharp angle, a miter join results in a +#. spike that extends well beyond the connection point. The purpose of the +#. miter limit is to cut off such spikes (i.e. convert them into bevels) +#. when they become too long. +#: ../../po/../src/dialogs/stroke-style.cpp:1054 +msgid "Miter limit:" +msgstr "Límit de la punxa:" + +#: ../../po/../src/dialogs/stroke-style.cpp:1062 +msgid "Maximum length of the miter (in units of stroke width)" +msgstr "Longitud màxima de la punxa (en unitats de l'amplada del contorn)" + +#. Cap type +#. TRANSLATORS: cap type specifies the shape for the ends of lines +#: ../../po/../src/dialogs/stroke-style.cpp:1075 +msgid "Cap:" +msgstr "Fi de les línies:" + +#. TRANSLATORS: Butt cap: the line shape does not extend beyond the end point +#. of the line; the ends of the line are square +#: ../../po/../src/dialogs/stroke-style.cpp:1086 +msgid "Butt cap" +msgstr "Quadrat" + +#. TRANSLATORS: Round cap: the line shape extends beyond the end point of the +#. line; the ends of the line are rounded +#: ../../po/../src/dialogs/stroke-style.cpp:1093 +msgid "Round cap" +msgstr "Arrodonit" + +#. TRANSLATORS: Square cap: the line shape extends beyond the end point of the +#. line; the ends of the line are square +#: ../../po/../src/dialogs/stroke-style.cpp:1100 +msgid "Square cap" +msgstr "Quadrat estès" + +#. Dash +#: ../../po/../src/dialogs/stroke-style.cpp:1106 +msgid "Dashes:" +msgstr "Ratlles:" + +#. TRANSLATORS: Path markers are an SVG feature that allows you to attach arbitrary shapes +#. (arrowheads, bullets, faces, whatever) to the start, end, or middle nodes of a path. +#: ../../po/../src/dialogs/stroke-style.cpp:1127 +msgid "Start Markers:" +msgstr "Marcadors inicials:" + +#: ../../po/../src/dialogs/stroke-style.cpp:1137 +msgid "Mid Markers:" +msgstr "Marcadors centrals:" + +#: ../../po/../src/dialogs/stroke-style.cpp:1148 +msgid "End Markers:" +msgstr "Marcadors finals:" + +#: ../../po/../src/dialogs/swatches.cpp:424 +#, c-format +msgid "Palettes directory (%s) is unavailable." +msgstr "El directori de les paletes (%s) no està disponible." + +#. TODO: Insert widgets +#: ../../po/../src/dialogs/text-edit.cpp:199 +#: ../../po/../src/ui/dialog/text-properties.cpp:36 +msgid "Font" +msgstr "Tipus de lletra" + +#: ../../po/../src/dialogs/text-edit.cpp:216 +msgid "Layout" +msgstr "Disposició" + +#: ../../po/../src/dialogs/text-edit.cpp:229 +msgid "Align lines left" +msgstr "Alinea les línies a l'esquerra" + +#. TRANSLATORS: `Center' here is a verb. +#: ../../po/../src/dialogs/text-edit.cpp:243 +msgid "Center lines" +msgstr "Centra les línies" + +#: ../../po/../src/dialogs/text-edit.cpp:256 +msgid "Align lines right" +msgstr "Alinea les línies a la dreta" + +#: ../../po/../src/dialogs/text-edit.cpp:278 +msgid "Horizontal text" +msgstr "Text horitzontal" + +#: ../../po/../src/dialogs/text-edit.cpp:292 +msgid "Vertical text" +msgstr "Text vertical" + +#: ../../po/../src/dialogs/text-edit.cpp:307 +msgid "Line spacing:" +msgstr "Espaiat entre línies:" + +#: ../../po/../src/dialogs/text-edit.cpp:400 +msgid "Set as default" +msgstr "Fes-lo predeterminat" + +#: ../../po/../src/dialogs/tiledialog.cpp:603 +msgid "Rows:" +msgstr "Files:" + +#: ../../po/../src/dialogs/tiledialog.cpp:613 +msgid "Number of rows" +msgstr "Nombre de files" + +#: ../../po/../src/dialogs/tiledialog.cpp:617 +msgid "Equal height" +msgstr "Alçada igual" + +#: ../../po/../src/dialogs/tiledialog.cpp:627 +msgid "If not set, each row has the height of the tallest object in it" +msgstr "Si no es defineix, cada fila té l'alçada de l'objecte més alt en ell" + +#. #### Radio buttons to control vertical alignment #### +#. #### Radio buttons to control horizontal alignment #### +#: ../../po/../src/dialogs/tiledialog.cpp:637 +#: ../../po/../src/dialogs/tiledialog.cpp:708 +msgid "Align:" +msgstr "Alinea:" + +#: ../../po/../src/dialogs/tiledialog.cpp:672 +msgid " X " +msgstr " X " + +#. #### Number of columns #### +#: ../../po/../src/dialogs/tiledialog.cpp:678 +msgid "Columns:" +msgstr "Columnes:" + +#: ../../po/../src/dialogs/tiledialog.cpp:688 +msgid "Number of columns" +msgstr "Nombre de columnes" + +#: ../../po/../src/dialogs/tiledialog.cpp:692 +msgid "Equal width" +msgstr "Amplada igual" + +#: ../../po/../src/dialogs/tiledialog.cpp:701 +msgid "If not set, each column has the width of the widest object in it" +msgstr "" +"Si no es defineix, cada columna té l'amplada de l'objecte més ample en ell" + +#. #### Radio buttons to control spacing manually or to fit selection bbox #### +#: ../../po/../src/dialogs/tiledialog.cpp:746 +msgid "Fit into selection box" +msgstr "Ajusta a la caixa de selecció" + +#: ../../po/../src/dialogs/tiledialog.cpp:753 +msgid "Set spacing:" +msgstr "Estableix l'espaiat:" + +#. #### Y Padding #### +#: ../../po/../src/dialogs/tiledialog.cpp:777 +msgid "Row spacing: " +msgstr "Espaiat entre files: " + +#: ../../po/../src/dialogs/tiledialog.cpp:786 +msgid "Vertical spacing between rows" +msgstr "Espaiat vertical entre files" + +#. #### X padding #### +#: ../../po/../src/dialogs/tiledialog.cpp:795 +msgid "Column spacing:" +msgstr "Espaiat entre columnes:" + +#: ../../po/../src/dialogs/tiledialog.cpp:804 +msgid "Horizontal spacing between columns" +msgstr "Espaiat horitzontal entre columnes" + +#: ../../po/../src/dialogs/tiledialog.cpp:818 +#, fuzzy +msgid "Arrange selected objects" +msgstr "Agrupa els objectes seleccionats" + +#: ../../po/../src/dialogs/xml-tree.cpp:178 +msgid "Click to select nodes, drag to rearrange." +msgstr "" +"Cliqueu per seleccionar nodes, i arrossegueu per reordenar." + +#: ../../po/../src/dialogs/xml-tree.cpp:189 +msgid "Click attribute to edit." +msgstr "Cliqueu l'atribut per editar." + +#: ../../po/../src/dialogs/xml-tree.cpp:193 +#, c-format +msgid "" +"Attribute %s selected. Press Ctrl+Enter when done editing to " +"commit changes." +msgstr "" +"S'ha seleccionat l'atribut %s. Premeu Ctrl+entrar en acabar " +"d'editar per confirmar els canvis." + +#: ../../po/../src/dialogs/xml-tree.cpp:284 +msgid "Drag to reorder nodes" +msgstr "Arrossegueu per reordenar els nodes" + +#: ../../po/../src/dialogs/xml-tree.cpp:304 +msgid "New element node" +msgstr "Nou node d'element" + +#: ../../po/../src/dialogs/xml-tree.cpp:326 +msgid "New text node" +msgstr "Nou node de text" + +#: ../../po/../src/dialogs/xml-tree.cpp:347 +msgid "Duplicate node" +msgstr "Duplica el node" + +#: ../../po/../src/dialogs/xml-tree.cpp:368 +msgid "Delete node" +msgstr "Suprimeix el node" + +#: ../../po/../src/dialogs/xml-tree.cpp:384 +msgid "Unindent node" +msgstr "Desfés sagnat de node" + +#: ../../po/../src/dialogs/xml-tree.cpp:399 +msgid "Indent node" +msgstr "Sagna el node" + +#: ../../po/../src/dialogs/xml-tree.cpp:411 +msgid "Raise node" +msgstr "Alça el node" + +#: ../../po/../src/dialogs/xml-tree.cpp:423 +msgid "Lower node" +msgstr "Baixa el node" + +#: ../../po/../src/dialogs/xml-tree.cpp:468 +msgid "Delete attribute" +msgstr "Suprimeix l'atribut" + +#. TRANSLATORS: "Attribute" is a noun here +#: ../../po/../src/dialogs/xml-tree.cpp:513 +msgid "Attribute name" +msgstr "Nom de l'atribut" + +#. TRANSLATORS: "Set" is a verb here +#: ../../po/../src/dialogs/xml-tree.cpp:533 +msgid "Set attribute" +msgstr "Defineix atribut" + +#. TRANSLATORS: "Set" is a verb here +#: ../../po/../src/dialogs/xml-tree.cpp:535 +msgid "Set" +msgstr "Assigna" + +#. TRANSLATORS: "Attribute" is a noun here +#: ../../po/../src/dialogs/xml-tree.cpp:558 +msgid "Attribute value" +msgstr "Valor d'atribut" + +#: ../../po/../src/dialogs/xml-tree.cpp:1318 +msgid "New element node..." +msgstr "Nou node d'element..." + +#: ../../po/../src/dialogs/xml-tree.cpp:1339 +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:100 +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:98 +msgid "Cancel" +msgstr "Cancel·la" + +#: ../../po/../src/dialogs/xml-tree.cpp:1345 +msgid "Create" +msgstr "Crea" + +#: ../../po/../src/dialogs/xml-tree.cpp:1458 +#, c-format +msgid "" +"Cannot set %s: Another element with value %s already exists!" +msgstr "No es pot assignar %s: existeix un element amb valor %s" + +#: ../../po/../src/document.cpp:369 +#, c-format +msgid "New document %d" +msgstr "Nou document %d" + +#: ../../po/../src/document.cpp:401 +#, c-format +msgid "Memory document %d" +msgstr "Document de memòria %d" + +#: ../../po/../src/document.cpp:524 +#, c-format +msgid "Unnamed document %d" +msgstr "Document sense nom %d" + +#. We hit green anchor, closing Green-Blue-Red +#: ../../po/../src/draw-context.cpp:441 +msgid "Path is closed." +msgstr "El camí està tancat." + +#. We hit bot start and end of single curve, closing paths +#: ../../po/../src/draw-context.cpp:456 +msgid "Closing path." +msgstr "S'està tancant el camí." + +#. alpha of color under cursor, to show in the statusbar +#. locale-sensitive printf is OK, since this goes to the UI, not into SVG +#: ../../po/../src/dropper-context.cpp:354 +#, c-format +msgid " alpha %.3g" +msgstr " transparència %.3g" + +#. where the color is picked, to show in the statusbar +#: ../../po/../src/dropper-context.cpp:356 +#, c-format +msgid ", averaged with radius %d" +msgstr ", amb mitja amb radi %d" + +#: ../../po/../src/dropper-context.cpp:356 +msgid " under cursor" +msgstr " sota el cursor" + +#. message, to show in the statusbar +#: ../../po/../src/dropper-context.cpp:358 +msgid "Release mouse to set color." +msgstr "Allibereu el ratolí per definir el color." + +#: ../../po/../src/dropper-context.cpp:358 +#: ../../po/../src/tools-switch.cpp:207 +msgid "" +"Click to set fill, Shift+click to set stroke; drag to " +"average color in area; with Alt to pick inverse color; Ctrl+C " +"to copy the color under mouse to clipboard" +msgstr "" +"Cliqueu per establir el farciment, maj+clic per establir el " +"contorn. arrossegueu per seleccionar el color mitjà d'una àrea; " +"alt per seleccionar el color invers; ctrl+c per copiar al " +"porta-retalls el color sota del ratolí." + +#: ../../po/../src/extension/dependency.cpp:244 +msgid "Dependency::" +msgstr "Dependència::" + +#: ../../po/../src/extension/dependency.cpp:245 +msgid " type: " +msgstr " tipus: " + +#: ../../po/../src/extension/dependency.cpp:246 +msgid " location: " +msgstr " ubicació: " + +#: ../../po/../src/extension/dependency.cpp:247 +msgid " string: " +msgstr " cadena: " + +#: ../../po/../src/extension/dependency.cpp:250 +msgid " description: " +msgstr " descripció: " + +#. static int i = 0; +#. std::cout << "Checking module[" << i++ << "]: " << name << std::endl; +#: ../../po/../src/extension/extension.cpp:244 +msgid "" +" This is caused by an improper .inx file for this extension. An improper ." +"inx file could have been caused by a faulty installation of Inkscape." +msgstr "" +" S'ha produït degut a un fiter .inx inadequat per a aquesta extensió. Un " +"fitxer .inx inadequat pot ser degut a una instal·lació de l'Inkscape amb " +"errors." + +#: ../../po/../src/extension/extension.cpp:247 +msgid "an ID was not defined for it." +msgstr "no se n'ha definit un ID." + +#: ../../po/../src/extension/extension.cpp:251 +msgid "there was no name defined for it." +msgstr "no tenia cap nom definit." + +#: ../../po/../src/extension/extension.cpp:255 +msgid "the XML description of it got lost." +msgstr "se n'ha perdut la descripció XML." + +#: ../../po/../src/extension/extension.cpp:259 +msgid "no implementation was defined for the extension." +msgstr "no s'ha definit la implementació per a l'extensió." + +#. std::cout << "Failed: " << *(_deps[i]) << std::endl; +#: ../../po/../src/extension/extension.cpp:266 +msgid "a dependency was not met." +msgstr "no s'ha arribat a cap dependència" + +#: ../../po/../src/extension/extension.cpp:286 +msgid "Extension \"" +msgstr "L'extensió \"" + +#: ../../po/../src/extension/extension.cpp:286 +msgid "\" failed to load because " +msgstr "\" ha fallat degut a " + +#: ../../po/../src/extension/extension.cpp:565 +#, c-format +msgid "Could not create extension error log file '%s'" +msgstr "No s'ha pogut crear el fitxer de registre d'error d'extensió '%s'" + +#. This is some filler text, needs to change before relase +#: ../../po/../src/extension/error-file.cpp:56 +msgid "" +"One or more extensions failed to load\n" +"\n" +"The failed extensions have been skipped. Inkscape will continue to run " +"normally but those extensions will be unavailable. For details to " +"troubleshoot this problem, please refer to the error log located at: " +msgstr "" +"Ha fallat alguna extensió\n" +"\n" +"S'han ignorat les extensions que han fallat. L'Inkscape continuarà executant-" +"se normalment, però les extensions no estaran disponibles. Per a detalls per " +"a resoldre aquest problema, llegiu el registre d'errors a: " + +#. This is some filler text, needs to change before relase +#: ../../po/../src/extension/error-file.cpp:65 +msgid "Show dialog on startup" +msgstr "Mostra el diàleg en iniciar" + +#: ../../po/../src/extension/implementation/script.cpp:845 +msgid "" +"Inkscape has received an error from the script that it called. The text " +"returned with the error is included below. Inkscape will continue working, " +"but the action you requested has been cancelled." +msgstr "" +"L'Inkscape ha rebut un error del fitxer de seqüència que ha cridat. El text " +"retornat amb l'error s'ha inclòs a sota. L'Inkscape continuarà treballant, " +"però s'ha cancel·lat l'acció que havíeu sol·licitat." + +#: ../../po/../src/extension/implementation/script.cpp:858 +msgid "" +"Inkscape has received additional data from the script executed. The script " +"did not return an error, but this may indicate the results will not be as " +"expected." +msgstr "" +"L'Inkscape ha rebut dades addicionals del fitxer de seqüència que ha " +"executat. El fitxer de seqüència no ha retornat un error, però pot indicar " +"que el resultat no és l'esperat." + +#: ../../po/../src/extension/init.cpp:173 +msgid "Null external module directory name. Modules will not be loaded." +msgstr "" +"El nom del directori de mòduls externs és nul. No es carregaran els mòduls." + +#: ../../po/../src/extension/init.cpp:187 +#, c-format +msgid "" +"Modules directory (%s) is unavailable. External modules in that directory " +"will not be loaded." +msgstr "" +"No està disponible el directori de mòduls (%s). No es carregaran els mòduls " +"externs d'aquest directori." + +#: ../../po/../src/extension/internal/gnome.cpp:80 +msgid "Select printer" +msgstr "Selecció d'impressora" + +#: ../../po/../src/extension/internal/gnome.cpp:131 +msgid "Inkscape: Print Preview" +msgstr "Inkscape: previsualització de la impressió" + +#: ../../po/../src/extension/internal/grid.cpp:213 +msgid "Line Width" +msgstr "Amplada de línia" + +#: ../../po/../src/extension/internal/grid.cpp:214 +msgid "Horizontal Spacing" +msgstr "Espaiat horitzontal" + +#: ../../po/../src/extension/internal/grid.cpp:215 +msgid "Vertical Spacing" +msgstr "Espaiat vertical" + +#: ../../po/../src/extension/internal/grid.cpp:216 +msgid "Horizontal Offset" +msgstr "Desplaçament horitzontal" + +#: ../../po/../src/extension/internal/grid.cpp:217 +msgid "Vertical Offset" +msgstr "Desplaçament vertical" + +#: ../../po/../src/extension/internal/ps.cpp:123 +msgid "Print Destination" +msgstr "Destí d'impressió" + +#. Print properties frame +#: ../../po/../src/extension/internal/ps.cpp:138 +msgid "Print properties" +msgstr "Propietats d'impressió" + +#: ../../po/../src/extension/internal/ps.cpp:145 +msgid "Print using PostScript operators" +msgstr "Imprimeix usant els operadors PostScript" + +#: ../../po/../src/extension/internal/ps.cpp:147 +msgid "" +"Use PostScript vector operators. The resulting image is usually smaller in " +"file size and can be arbitrarily scaled, but alpha transparency and patterns " +"will be lost." +msgstr "" +"Usa operadors de vector PostScript. La imatge resultant és normalment de " +"mida més petita i es pot escalar arbitràriament, però la transparència i els " +"patrons es perdran." + +#: ../../po/../src/extension/internal/ps.cpp:152 +msgid "Print as bitmap" +msgstr "Imprimeix com a mapa de bits" + +#: ../../po/../src/extension/internal/ps.cpp:154 +msgid "" +"Print everything as bitmap. The resulting image is usually larger in file " +"size and cannot be arbitrarily scaled without quality loss, but all objects " +"will be rendered exactly as displayed." +msgstr "" +"Imprimeix-ho tot com a mapa de bits. La imatge resultant és en general de " +"mida més gran, i no es podrà escalar sense pèrdua de qualitat, però tots els " +"objectes es dibuixaran exactament com es visualitzen." + +#: ../../po/../src/extension/internal/ps.cpp:168 +msgid "Preferred resolution (dots per inch) of bitmap" +msgstr "Resolució preferida (punts per polzada) del mapa de bits" + +#: ../../po/../src/extension/internal/ps.cpp:182 +msgid "Resolution:" +msgstr "Resolució:" + +#. Print destination frame +#: ../../po/../src/extension/internal/ps.cpp:186 +msgid "Print destination" +msgstr "Destí d'impressió" + +#: ../../po/../src/extension/internal/ps.cpp:192 +msgid "" +"Use '> filename' to print to file.\n" +"Use '| prog arg...' to pipe to a program." +msgstr "" +"Useu '> nomFitxer' per imprimir a un fitxer.\n" +"Useu '| prog arg...' per enviar la sortida al conducte d'un programa." + +#: ../../po/../src/extension/internal/ps.cpp:1227 +msgid "write error occurred" +msgstr "hi ha hagut un error d'escriptura" + +#: ../../po/../src/extension/prefdialog.cpp:21 +msgid " Preferences" +msgstr " Preferències" + +#. We can't call sp_ui_error_dialog because we may be +#. running from the console, in which case calling sp_ui +#. routines will cause a segfault. See bug 1000350 - bryce +#. sp_ui_error_dialog(_("Format autodetect failed. The file is being opened as SVG.")); +#: ../../po/../src/extension/system.cpp:105 +msgid "Format autodetect failed. The file is being opened as SVG." +msgstr "Ha fallat l'autodetecció de format. El fitxer s'obrirà com a SVG." + +#. TRANSLATORS: default.svg is localizable - this is the name of the default document +#. template. This way you can localize the default pagesize, translate the name of +#. the default layer, etc. If you wish to localize this file, please create a +#. localized share/templates/default.xx.svg file, where xx is your language code. +#: ../../po/../src/file.cpp:133 +msgid "default.svg" +msgstr "default.svg" + +#: ../../po/../src/file.cpp:215 ../../po/../src/file.cpp:900 +#, c-format +msgid "Failed to load the requested file %s" +msgstr "No s'ha pogut carregar el fitxer demanat %s" + +#: ../../po/../src/file.cpp:240 +msgid "Document not saved yet. Cannot revert." +msgstr "No s'ha desat el document. No es pot recuperar l'estat anterior." + +#: ../../po/../src/file.cpp:246 +#, c-format +msgid "Changes will be lost! Are you sure you want to reload document %s?" +msgstr "" +"Es perdran els canvis. Esteu segur que voleu tornar a carregar el document %" +"s?" + +#: ../../po/../src/file.cpp:266 +msgid "Document reverted." +msgstr "S'ha recuperat el document anterior." + +#: ../../po/../src/file.cpp:268 +msgid "Document not reverted." +msgstr "No s'ha recuperat el document anterior." + +#: ../../po/../src/file.cpp:382 +msgid "Select file to open" +msgstr "Seleccioneu el fitxer per obrir" + +#: ../../po/../src/file.cpp:518 +#, c-format +msgid "Removed %i unused definition in <defs>." +msgid_plural "Removed %i unused definitions in <defs>." +msgstr[0] "S'ha suprimit %i definició sense fer servir a <defs>." +msgstr[1] "" +"S'han suprimit %i definicions sense fer servir a <defs>." + +#: ../../po/../src/file.cpp:523 +msgid "No unused definitions in <defs>." +msgstr "No hi ha definicions sense fer servir a <defs>." + +#: ../../po/../src/file.cpp:548 +#, c-format +msgid "" +"No Inkscape extension found to save document (%s). This may have been " +"caused by an unknown filename extension." +msgstr "" +"No s'ha trobat cap extensió de l'Inkscape per desar el document (%s). És " +"possible que es desconegui l'extensió del fitxer." + +#: ../../po/../src/file.cpp:549 ../../po/../src/file.cpp:557 +msgid "Document not saved." +msgstr "No s'ha desat el document." + +#: ../../po/../src/file.cpp:556 +#, c-format +msgid "File %s could not be saved." +msgstr "No s'ha pogut desar el document %s." + +#: ../../po/../src/file.cpp:566 +msgid "Document saved." +msgstr "S'ha desat el document." + +#: ../../po/../src/file.cpp:614 +#, c-format +msgid "drawing%s" +msgstr "dibuix%s" + +#: ../../po/../src/file.cpp:620 +#, c-format +msgid "drawing-%d%s" +msgstr "dibuix-%d%s" + +#: ../../po/../src/file.cpp:655 +msgid "Select file to save to" +msgstr "Seleccioneu el fitxer per desar-hi" + +#: ../../po/../src/file.cpp:739 +msgid "No changes need to be saved." +msgstr "No hi ha cap canvi per desar." + +#: ../../po/../src/file.cpp:926 +msgid "Select file to import" +msgstr "Seleccioneu el fitxer per importar" + +#: ../../po/../src/gradient-context.cpp:263 +msgid "Ctrl: snap gradient angle" +msgstr "Control: ajusta l'angle del degradat" + +#: ../../po/../src/gradient-context.cpp:264 +msgid "Shift: draw gradient around the starting point" +msgstr "Majúscules: dibuixa el degradat al voltant del punt d'inici" + +#. We did an undoable action, but sp_document_done will be called by the knot when released +#. status text; we do not track coords because this branch is run once, not all the time +#. during drag +#: ../../po/../src/gradient-context.cpp:462 +#, c-format +msgid "Gradient for %d objects; with Ctrl to snap angle" +msgstr "" +"Degradat: per a %d objectes; amb ctrl per ajustar l'angle" + +#: ../../po/../src/gradient-context.cpp:464 +msgid "Select objects on which to create gradient." +msgstr "Seleccioneu alguns objectes per crear-hi degradats." + +#: ../../po/../src/gradient-drag.cpp:65 +msgid "Linear gradient start" +msgstr "Inici del degradat lineal" + +#. POINT_LG_P1 +#: ../../po/../src/gradient-drag.cpp:66 +msgid "Linear gradient end" +msgstr "Final del degradat lineal" + +#: ../../po/../src/gradient-drag.cpp:67 +msgid "Radial gradient center" +msgstr "Centre del degradat radial" + +#: ../../po/../src/gradient-drag.cpp:68 ../../po/../src/gradient-drag.cpp:69 +msgid "Radial gradient radius" +msgstr "Radi del degradat radial" + +#: ../../po/../src/gradient-drag.cpp:70 +msgid "Radial gradient focus" +msgstr "Focus del degradat radial" + +#: ../../po/../src/gradient-drag.cpp:659 +#, c-format +msgid "" +"%s for: %s%s; drag with Ctrl to snap angle, with Ctrl+Alt to " +"preserve angle, with Ctrl+Shift to scale around center" +msgstr "" +"%s per a: %s%s; arrossegueu amb ctrl per a ajustar l'angle, amb " +"ctrl+alt per conservar l'angle, amb ctrl+alt per escalar al " +"voltant del centre" + +#: ../../po/../src/gradient-drag.cpp:662 +msgid " (stroke)" +msgstr " (contorn)" + +#: ../../po/../src/gradient-drag.cpp:665 +msgid "" +"Radial gradient center and focus; drag with Shift to " +"separate focus" +msgstr "" +"Centre i focus del degradat radial; arrossegueu amb maj " +"per separar el focus" + +#: ../../po/../src/gradient-drag.cpp:667 +#, c-format +msgid "" +"Gradient point shared by %d gradients; drag with Shift to " +"separate" +msgstr "" +"Punt de degradat compartit per %d degradats; arrossegueu amb maj per a separar" + +#: ../../po/../src/helper/units.cpp:40 +msgid "Unit" +msgstr "Unitat" + +#: ../../po/../src/helper/units.cpp:40 +msgid "Units" +msgstr "Unitats" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Point" +msgstr "Punt" + +#: ../../po/../src/helper/units.cpp:41 +msgid "pt" +msgstr "pt" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Points" +msgstr "Punts" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Pt" +msgstr "Pt" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Pixel" +msgstr "Píxel" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Pixels" +msgstr "Píxels" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Px" +msgstr "Px" + +#. You can add new elements from this point forward +#: ../../po/../src/helper/units.cpp:44 ../share/extensions/straightseg.inx.h:2 +msgid "Percent" +msgstr "Percentatge" + +#: ../../po/../src/helper/units.cpp:44 +msgid "Percents" +msgstr "Percentatges" + +#: ../../po/../src/helper/units.cpp:45 +msgid "Millimeter" +msgstr "Mil·límetre" + +#: ../../po/../src/helper/units.cpp:45 +msgid "mm" +msgstr "mm" + +#: ../../po/../src/helper/units.cpp:45 +msgid "Millimeters" +msgstr "Mil·límetres" + +#: ../../po/../src/helper/units.cpp:46 +msgid "Centimeter" +msgstr "Centímetre" + +#: ../../po/../src/helper/units.cpp:46 +msgid "cm" +msgstr "cm" + +#: ../../po/../src/helper/units.cpp:46 +msgid "Centimeters" +msgstr "Centímetres" + +#: ../../po/../src/helper/units.cpp:47 +msgid "Meter" +msgstr "Metre" + +#: ../../po/../src/helper/units.cpp:47 +msgid "m" +msgstr "m" + +#: ../../po/../src/helper/units.cpp:47 +msgid "Meters" +msgstr "Metres" + +#. no svg_unit +#: ../../po/../src/helper/units.cpp:48 +msgid "Inch" +msgstr "Polzada" + +#: ../../po/../src/helper/units.cpp:48 +msgid "in" +msgstr "in" + +#: ../../po/../src/helper/units.cpp:48 +msgid "Inches" +msgstr "Polzades" + +#. Volatiles do not have default, so there are none here +#. TRANSLATORS: for info, see http://www.w3.org/TR/REC-CSS2/syndata.html#length-units +#: ../../po/../src/helper/units.cpp:51 +msgid "Em square" +msgstr "Em quadrada" + +#: ../../po/../src/helper/units.cpp:51 +msgid "em" +msgstr "em" + +#: ../../po/../src/helper/units.cpp:51 +msgid "Em squares" +msgstr "Em quadrades" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/REC-CSS2/syndata.html#length-units +#: ../../po/../src/helper/units.cpp:53 +msgid "Ex square" +msgstr "Ics quadrada" + +#: ../../po/../src/helper/units.cpp:53 +msgid "ex" +msgstr "ics" + +#: ../../po/../src/helper/units.cpp:53 +msgid "Ex squares" +msgstr "Ics quadrades" + +#: ../../po/../src/inkscape.cpp:468 +msgid "Untitled document" +msgstr "Document sense títol" + +#. Show nice dialog box +#: ../../po/../src/inkscape.cpp:497 +msgid "Inkscape encountered an internal error and will close now.\n" +msgstr "L'Inkscape ha trobat un error intern i es tancarà ara.\n" + +#: ../../po/../src/inkscape.cpp:498 +msgid "" +"Automatic backups of unsaved documents were done to the following " +"locations:\n" +msgstr "" +"S'han fet còpies de seguretat automàtiques dels documents sense desar a les " +"següents ubicacions:\n" + +#: ../../po/../src/inkscape.cpp:499 +msgid "Automatic backup of the following documents failed:\n" +msgstr "No s'ha pogut fer còpia de seguretat dels següents documents:\n" + +#: ../../po/../src/inkscape.cpp:634 +#, c-format +msgid "" +"Cannot create directory %s.\n" +"%s" +msgstr "" +"No s'ha pogut crear el directori %s.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:635 +#, c-format +msgid "" +"%s is not a valid directory.\n" +"%s" +msgstr "" +"%s no és un directori vàlid.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:636 +#, c-format +msgid "" +"Cannot create file %s.\n" +"%s" +msgstr "" +"No es pot crear el fitxer %s.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:637 +#, c-format +msgid "" +"Cannot write file %s.\n" +"%s" +msgstr "" +"No es pot escriure el fitxer %s.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:638 +msgid "" +"Although Inkscape will run, it will use default settings,\n" +"and any changes made in preferences will not be saved." +msgstr "" +"Tot i que l'Inkscape s'executarà, s'usarà la configuració predeterminada,\n" +"i no es desaran els canvis fets en les preferències." + +#: ../../po/../src/inkscape.cpp:708 +#, c-format +msgid "" +"%s is not a regular file.\n" +"%s" +msgstr "" +"%s no és un fitxer de dades.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:709 +#, c-format +msgid "" +"%s not a valid XML file, or\n" +"you don't have read permissions on it.\n" +"%s" +msgstr "" +"%s no és un fitxer XML vàlid, o\n" +"o no teniu permís de lectura.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:711 +#, c-format +msgid "" +"%s is not a valid menus file.\n" +"%s" +msgstr "" +"%s no és un fitxer de menús vàlid.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:712 +msgid "" +"Inkscape will run with default menus.\n" +"New menus will not be saved." +msgstr "" +"L'Inkscape s'executarà amb els menús predeterminats.\n" +"No es desaran els nous menús." + +#. sp_ui_menu_append_check_item_from_verb(m, view, _("_Menu"), _("Show or hide the menu bar"), "menu", +#. checkitem_toggled, checkitem_update, 0); +#: ../../po/../src/interface.cpp:753 +msgid "Commands Bar" +msgstr "Barra d'ordres" + +#: ../../po/../src/interface.cpp:753 +msgid "Show or hide the Commands bar (under the menu)" +msgstr "Mostra o amaga la barra d'ordres (sota el menú)" + +#: ../../po/../src/interface.cpp:755 +msgid "Tool Controls" +msgstr "Controls d'eina" + +#: ../../po/../src/interface.cpp:755 +msgid "Show or hide the Tool Controls panel" +msgstr "Mostra o amaga la subfinestra de les eines de control" + +#: ../../po/../src/interface.cpp:757 +msgid "_Toolbox" +msgstr "Cai_xa d'eines" + +#: ../../po/../src/interface.cpp:757 +msgid "Show or hide the main toolbox (on the left)" +msgstr "Mostra o amaga la caixa d'eines principal (a l'esquerra)" + +#: ../../po/../src/interface.cpp:763 +msgid "_Statusbar" +msgstr "Barra d'e_stat" + +#: ../../po/../src/interface.cpp:763 +msgid "Show or hide the statusbar (at the bottom of the window)" +msgstr "Mostra o amaga la barra d'estat (a la part inferior de la finestra)" + +#: ../../po/../src/interface.cpp:820 +#, c-format +msgid "Verb \"%s\" Unknown" +msgstr "No es coneix el verb \"%s\"" + +#. TRANSLATORS: #%s is the id of the group e.g. , not a number. +#: ../../po/../src/interface.cpp:930 +#, c-format +msgid "Enter group #%s" +msgstr "Introduïu el grup #%s" + +#: ../../po/../src/interface.cpp:941 +msgid "Go to parent" +msgstr "Vés al pare" + +#: ../../po/../src/interface.cpp:972 +msgid "Could not parse SVG data" +msgstr "No s'ha pogut analitzar les dades SVG" + +#: ../../po/../src/interface.cpp:1135 +#, c-format +msgid "Overwrite %s" +msgstr "Sobreescriu %s" + +#: ../../po/../src/interface.cpp:1153 +#, c-format +msgid "" +"The file %s already exists. Do you want to overwrite that file with the " +"current document?" +msgstr "" +"El fitxer %s existeix. Voleu sobreescriure el fitxer amb el document actual?" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:59 +msgid "Jabber connection lost." +msgstr "S'ha perdut la connexió amb el Jabber" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:72 +#, c-format +msgid "Sending message; %u message remaining in send queue." +msgid_plural "Sending message; %u messages remaining in send queue." +msgstr[0] "S'està enviant el missatge; queda %u missatge a la cua d'enviament." +msgstr[1] "" +"S'està enviant el missatge; queden %u missatges a la cua d'enviament." + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:78 +msgid "Receive queue empty." +msgstr "La cua de recepció està buida." + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:154 +#, c-format +msgid "Receiving change; %u change left to process." +msgid_plural "Receiving change; %u changes left to process." +msgstr[0] "S'està rebent el canvi; queda %u canvi per processar." +msgstr[1] "S'està rebent el canvi; queden %u canvis per processar." + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:157 +#, c-format +msgid "%s has left the chatroom." +msgstr "%s ha sortir de la sala." + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:221 +msgid "Nickname %1 is already in use. Please choose a different nickname." +msgstr "Ja s'està fent servir el sobrenom %1. Escolliu un sobrenom diferent." + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:225 +msgid "An error was encountered while attempting to connect to the server." +msgstr "S'ha trobat un error en intentar connectar amb el servidor." + +#. Check to see if the user made any modifications to this document. If so, +#. we want to give them the option of (1) letting us clear their document or (2) +#. opening a new, blank document for the whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:131 +msgid "%1 has invited you to a whiteboard session." +msgstr "En/na %1 us ha invitat a una sessió de pisarra col·laborativa." + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:132 +msgid "Incoming whiteboard invitation from %1" +msgstr "Arribada d'una invitació per a una pisarra col·laborativa d'en/na %1" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:135 +msgid "Do you wish to accept %1's whiteboard session invitation?" +msgstr "" +"Voleu acceptar la invitació per a una pisarra col·laborativa d'en/na %1?" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:137 +msgid "" +"Would you like to accept %1's invitation in a new document window?\n" +"Accepting the invitation in your current window will discard unsaved changes." +msgstr "" +"Voleu acceptar la invitació d'en %1 en una nova finestra de document?\n" +"Si accepteu la invitación en la vostra finestra actual, es descartaran els " +"canvis sense desar." + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:143 +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:198 +msgid "Accept invitation" +msgstr "Accepta la invitació" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:144 +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:199 +msgid "Decline invitation" +msgstr "Rebutja la invitació" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:145 +msgid "Accept invitation in new document window" +msgstr "Crea un nou document" + +#. We could not create a new desktop; ask the user if she or he wants to +#. replace the current document and accept the invitation, or reject the invitation. +#. TRANSLATORS: %1 is a userid here +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:196 +msgid "" +"A new document window could not be opened for a whiteboard session with %" +"1" +msgstr "" +"No s'ha pogut obrir una nova finestra de document per a la sessió de pisarra " +"col·laborativa amb en/na %1" + +#. TRANSLATORS: %1 is the peer whom refused our invitation. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:238 +msgid "" +"The user %1 has refused your " +"whiteboard invitation.\n" +"\n" +msgstr "" +"L'usuari %1 ha rebutjat la " +"vostra invitació per a una pisarra col·laborativa.\n" + +#. TRANSLATORS: %1 is the peer whom refused our invitation, %2 is our Jabber identity. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:241 +msgid "" +"You are still connected to a Jabber server as %2, and may send an " +"invitation to %1 again, or you may send an invitation to a different " +"user." +msgstr "" +"Encara esteu connectat a un servidor de Jabber com a %2, i podeu " +"enviar una invitació a %1 una altra vegada, o podeu enviar una " +"invitació a un usuari diferent." + +#. TRANSLATORS: %1 is the peer whom we tried to contact, but is already in a whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:252 +msgid "" +"The user %1 is already in a " +"whiteboard session.\n" +"\n" +msgstr "" +"L'usuari %1 ja es troba en una " +"sessió de pisarra col·laborativa.\n" +"\n" + +#. TRANSLATORS: %1 is the peer whom we tried to contact, but is already in a whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:255 +msgid "" +"You are still connected to a Jabber server as %1, and may send an " +"invitation to a different user." +msgstr "" +"Encara esteu connectat a un servidor de Jabber com a %1, i podeu " +"enviar una invitació a un usuari diferent." + +#: ../../po/../src/jabber_whiteboard/invitation-confirm-dialog.cpp:26 +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:24 +msgid "_Write session file:" +msgstr "_Escriu un fitxer de sessió:" + +#: ../../po/../src/jabber_whiteboard/message-processors.cpp:145 +#, c-format +msgid "%s has joined the chatroom." +msgstr "%s s'ha unit a la sala." + +#: ../../po/../src/jabber_whiteboard/message-queue.cpp:87 +#, c-format +msgid "%u change in receive queue." +msgid_plural "%u changes in receive queue." +msgstr[0] "%u canvi a la cua de recepció." +msgstr[1] "%u canvis a la cua de recepció." + +#: ../../po/../src/jabber_whiteboard/message-queue.cpp:117 +#, c-format +msgid "%u change in send queue." +msgid_plural "%u changes in send queue." +msgstr[0] "%u canvi a la cua d'enviament." +msgstr[1] "%u canvis a la cua d'enviament." + +#. if ID is NULL, then we have a real problem -- we were not able to find a key +#. nor generate one. The only thing we can really do here is abort, since we have +#. no way to let the other client(s) uniquely identify this object. +#. FIXME: If this indicates a programming bug, then don't request translation with +#. * _(...): it is most useful in untranslated form so that developers may search for +#. * it when someone reports it in a bug report (as we want users to do for all bugs, +#. * as indicated by it being a g_warning string). +#. * +#. * Otherwise, if it is not a programming bug but a network error or a bug in the +#. * remote peer (perhaps running different software) or whatever, then present it in +#. * an alert box, and avoid use of technical jargon `NULL'. +#. +#: ../../po/../src/jabber_whiteboard/message-utilities.cpp:171 +msgid "" +"ID for new object is NULL even after generation and lookup attempts: the new " +"object will NOT be sent, nor will any of its child objects!" +msgstr "" +"L'ID per al nou objecte és NULL, fins i tot després de la generació i de la " +"cerca: el nou objecte no s'enviarà, ni tampoc cap dels seus fills!" + +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:60 +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:995 +msgid "Select a location and filename" +msgstr "Seleccioneu una ubicació i un nom de fitxer" + +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:62 +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:997 +msgid "Set filename" +msgstr "Estableix el nom del fitxer" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:301 +msgid "No SSL certificate was found." +msgstr "No s'ha trobat cap certificat SSL." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:304 +msgid "The SSL certificate provided by the Jabber server is untrusted." +msgstr "El certificat SSL proveït pel servidor de Jabber no és verificat." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:307 +msgid "The SSL certificate provided by the Jabber server is expired." +msgstr "El certificat SSL proveït pel servidor de Jabber ha vençut." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:310 +msgid "" +"The SSL certificate provided by the Jabber server has not been activated." +msgstr "El certificat SSL proveït pel servidor de Jabber no s'ha activat." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:313 +msgid "" +"The SSL certificate provided by the Jabber server contains a hostname that " +"does not match the Jabber server's hostname." +msgstr "" +"El certificat SSL proveït pel servidor de Jabber conté un nom de màquina que " +"no concorda amb el nom de màquina del servidor de Jabber." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:316 +msgid "" +"The SSL certificate provided by the Jabber server contains an invalid " +"fingerprint." +msgstr "" +"El certificat SSL proveït pel servidor de Jabber conté una emprenta invàlida." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:319 +msgid "An unknown error occurred while setting up the SSL connection." +msgstr "S'ha produït un error desconegut en configurar la connexió SSL." + +#. TRANSLATORS: %1 is the message that describes the specific error that occurred when +#. establishing the SSL connection. +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:325 +msgid "" +"%1\n" +"\n" +"Do you wish to continue connecting to the Jabber server?" +msgstr "" +"%1\n" +"\n" +"Voleu seguir amb la connexió al servidor de Jabber?" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:328 +msgid "Continue connecting and ignore further errors" +msgstr "Continua amb la connexió i ignora els següents errors" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:329 +msgid "Continue connecting, but warn me of further errors" +msgstr "Continua amb la connexió, però avisa'm dels següents errors" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:330 +msgid "Cancel connection" +msgstr "Cancel·la la connexió" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:777 +#, c-format +msgid "Established whiteboard session with %s." +msgstr "" +"S'ha establert una sessió de pisarra col·laborativa amb en/na %s" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:785 +#, c-format +msgid "%s has left the whiteboard session." +msgstr "" +"En/na %s ha sortit de la sessió de pisarra col·laborativa." + +#. Inform the user +#. TRANSLATORS: %1 is the name of the user that disconnected, %2 is the name of the user whom the disconnected user disconnected from. +#. This message is not used in a chatroom context. +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:790 +msgid "" +"The user %1 has left the " +"whiteboard session.\n" +"\n" +msgstr "" +"En/na %s ha sortit de la " +"sessió de pisarra col·laborativa.\n" +"\n" + +#. TRANSLATORS: %1 and %2 are userids +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:792 +msgid "" +"You are still connected to a Jabber server as %2, and may establish a " +"new session to %1 or a different user." +msgstr "" +"Encara esteu connectats a un servidor de Jabber com a %2, i podeu " +"establir una nova sessió a %1 com a un usuari diferent." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:988 +msgid "" +"Could not open file %1 for session recording.\n" +"The error encountered was: %2.\n" +"\n" +"You may select a different location to record the session, or you may opt to " +"not record this session." +msgstr "" +"No es pot obrir el fitxer %1 per a desar la sessió.\n" +"L'error trobat és: %2.\n" +"\n" +"Podeu seleccionar una ubicació diferent per a desar la sessió, o podeu optar " +"per no desar la sessió." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:990 +msgid "Choose a different location" +msgstr "Escolliu una ubicació diferent" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:991 +msgid "Skip session recording" +msgstr "No es desarà la sessió" + +#: ../../po/../src/knot.cpp:673 +msgid "Node or handle drag canceled." +msgstr "S'ha cancel·lat l'arrossegament del node o el manejador." + +#: ../../po/../src/libnrtype/FontFactory.cpp:358 +msgid "Ignoring font without family that will crash Pango" +msgstr "" +"S'ha ignorat un tipus de lletra sense família que causaria un error en Pango" + +#: ../../po/../src/main.cpp:395 +msgid "Print the Inkscape version number" +msgstr "Escriu el nombre de versió de l'Inkscape" + +#: ../../po/../src/main.cpp:400 +msgid "Do not use X server (only process files from console)" +msgstr "No usis el servidor X (només processa fitxers des de la consola)" + +#: ../../po/../src/main.cpp:405 +msgid "Try to use X server (even if $DISPLAY is not set)" +msgstr "Prova d'usar el servidor X (encara que $DISPLAY no estigui definit)" + +#: ../../po/../src/main.cpp:410 +msgid "Open specified document(s) (option string may be excluded)" +msgstr "Obre els documents especificats (la cadena d'opcions es pot excloure)" + +#: ../../po/../src/main.cpp:411 ../../po/../src/main.cpp:416 +#: ../../po/../src/main.cpp:421 ../../po/../src/main.cpp:483 +#: ../../po/../src/main.cpp:488 ../../po/../src/main.cpp:493 +msgid "FILENAME" +msgstr "Nom del fitxer" + +#: ../../po/../src/main.cpp:415 +msgid "Print document(s) to specified output file (use '| program' for pipe)" +msgstr "" +"Imprimeix els documents al fitxer de sortida especificat (utilitzeu '| " +"programa' per al conducte)" + +#: ../../po/../src/main.cpp:420 +msgid "Export document to a PNG file" +msgstr "Exporta el document com a PNG" + +#: ../../po/../src/main.cpp:425 +msgid "The resolution used for exporting SVG into bitmap (default 90)" +msgstr "" +"La resolució emprada per exportar l'SVG en mapa de bits (per defecte 90)" + +#: ../../po/../src/main.cpp:426 +msgid "DPI" +msgstr "PPP" + +#: ../../po/../src/main.cpp:430 +msgid "" +"Exported area in SVG user units (default is the canvas; 0,0 is lower-left " +"corner)" +msgstr "" +"Àrea exportada en unitats d'usuari SVG (per defecte el llenç; 0,0 és la " +"cantonada inferior esquerra)" + +#: ../../po/../src/main.cpp:431 +msgid "x0:y0:x1:y1" +msgstr "x0:y0:x1:y1" + +#: ../../po/../src/main.cpp:435 +msgid "Exported area is the entire drawing (not canvas)" +msgstr "L'àrea exportada és el dibuix sencer (no el llenç)" + +#: ../../po/../src/main.cpp:440 +msgid "" +"Snap the bitmap export area outwards to the nearest integer values (in SVG " +"user units)" +msgstr "" + +#: ../../po/../src/main.cpp:445 +msgid "The width of exported bitmap in pixels (overrides export-dpi)" +msgstr "" +"L'amplada del mapa de bits exportat en píxels (s'ignora el valor d'export-" +"dpi)" + +#: ../../po/../src/main.cpp:446 +msgid "WIDTH" +msgstr "Amplada" + +#: ../../po/../src/main.cpp:450 +msgid "The height of exported bitmap in pixels (overrides export-dpi)" +msgstr "" +"L'alçada del mapa de bits exportat en píxels (s'ignora el valor d'export-dpi)" + +#: ../../po/../src/main.cpp:451 +msgid "HEIGHT" +msgstr "Alçada" + +#: ../../po/../src/main.cpp:455 +msgid "The ID of the object to export (overrides export-area)" +msgstr "L'id de l'objecte per exportar (s'ignora export-area)" + +#: ../../po/../src/main.cpp:456 ../../po/../src/main.cpp:532 +msgid "ID" +msgstr "Id." + +#. TRANSLATORS: this means: "Only export the object whose id is given in --export-id". +#. See "man inkscape" for details. +#: ../../po/../src/main.cpp:462 +msgid "" +"Export just the object with export-id, hide all others (only with export-id)" +msgstr "" +"Exporta només l'objecte amb l'export-id, amaga els altres (només amb export-" +"id)" + +#: ../../po/../src/main.cpp:467 +msgid "Use stored filename and DPI hints when exporting (only with export-id)" +msgstr "" +"Usa el nom de fitxer emmagatzemat i els PPP en exportar (només amb export-id)" + +#: ../../po/../src/main.cpp:472 +msgid "Background color of exported bitmap (any SVG-supported color string)" +msgstr "" +"Color de fons del mapa de bits exportat (qualsevol cadena de color admesa " +"per l'SVG)" + +#: ../../po/../src/main.cpp:473 +msgid "COLOR" +msgstr "Color" + +#: ../../po/../src/main.cpp:477 +msgid "Background opacity of exported bitmap (either 0.0 to 1.0, or 1 to 255)" +msgstr "" +"Opacitat del fons del mapa de bits exportat (de 0.0 a 1.0, o d'1 a 255)" + +#: ../../po/../src/main.cpp:478 +msgid "VALUE" +msgstr "Valor" + +#: ../../po/../src/main.cpp:482 +msgid "Export document to plain SVG file (no sodipodi or inkscape namespaces)" +msgstr "" +"Exporta el document en SVG simple (sense espai de noms de sodipodi o " +"inkscape)" + +#: ../../po/../src/main.cpp:487 +msgid "Export document to a PS file" +msgstr "Exporta el document a un fitxer PS" + +#: ../../po/../src/main.cpp:492 +msgid "Export document to an EPS file" +msgstr "Exporta el document a un fitxer EPS" + +#: ../../po/../src/main.cpp:497 +msgid "Convert text object to paths on export (EPS)" +msgstr "Converteix els objectes de text en camins per a exportar (EPS)" + +#: ../../po/../src/main.cpp:502 +msgid "Export files with the bounding box set to the page size (EPS)" +msgstr "" +"Exporta fitxers amb la caixa del voltant establerta a la mida de la página " +"(EPS)" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:508 +msgid "" +"Query the X coordinate of the drawing or, if specified, of the object with --" +"query-id" +msgstr "" +"Consulta la coordenada X del dibuix o, si s'especifica, de l'objecte amb --" +"query-id" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:514 +msgid "" +"Query the Y coordinate of the drawing or, if specified, of the object with --" +"query-id" +msgstr "" +"Consulta la coordenada Y del dibuix o, si s'especifica, de l'objecte amb --" +"query-id" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:520 +msgid "" +"Query the width of the drawing or, if specified, of the object with --query-" +"id" +msgstr "" +"Consulta l'amplada del dibuix o, si s'especifica, de l'objecte amb --query-id" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:526 +msgid "" +"Query the height of the drawing or, if specified, of the object with --query-" +"id" +msgstr "" +"Consulta l'alçada del dibuix o, si s'especifica, de l'objecte amb --query-id" + +#: ../../po/../src/main.cpp:531 +msgid "The ID of the object whose dimensions are queried" +msgstr "L'id de l'objecte les dimensions del qual es volen consultar" + +#. TRANSLATORS: this option makes Inkscape print the name (path) of the extension directory +#: ../../po/../src/main.cpp:537 +msgid "Print out the extension directory and exit" +msgstr "Escriu el directori d'extensions i surt" + +#: ../../po/../src/main.cpp:542 +msgid "Show given files one-by-one, switch to next on any key/mouse event" +msgstr "" +"Mostra els fitxers d'un en un. Commuta al següent amb un esdeveniment de " +"teclat o ratolí" + +#: ../../po/../src/main.cpp:547 +msgid "Use the new Gtkmm GUI interface" +msgstr "Usa la nova interfície Gtkmm" + +#: ../../po/../src/main.cpp:552 +msgid "Remove unused definitions from the defs section(s) of the document" +msgstr "" +"Suprimeix definicions sense fer servir de les seccions de definició del " +"document" + +#: ../../po/../src/main.cpp:741 +msgid "" +"[OPTIONS...] [FILE...]\n" +"\n" +"Available options:" +msgstr "" +"[OPCIONS...] [FITXER...]\n" +"\n" +"Opcions disponibles:" + +#: ../../po/../src/menus-skeleton.h:17 +msgid "_New" +msgstr "_Nou" + +#: ../../po/../src/menus-skeleton.h:22 +msgid "Open _Recent" +msgstr "Obre'n un de _recent" + +#: ../../po/../src/menus-skeleton.h:53 +msgid "_Edit" +msgstr "_Edita" + +#: ../../po/../src/menus-skeleton.h:84 +msgid "_View" +msgstr "_Visualitza" + +#: ../../po/../src/menus-skeleton.h:85 +#, fuzzy +msgid "_Zoom" +msgstr "Ampliació" + +#: ../../po/../src/menus-skeleton.h:102 +msgid "Show/Hide" +msgstr "Mostra/amaga" + +#: ../../po/../src/menus-skeleton.h:107 +msgid "_Display mode" +msgstr "" + +#: ../../po/../src/menus-skeleton.h:126 +msgid "_Layer" +msgstr "_Capa" + +#: ../../po/../src/menus-skeleton.h:143 +msgid "_Object" +msgstr "_Objecte" + +#: ../../po/../src/menus-skeleton.h:165 +msgid "_Path" +msgstr "Ca_mins" + +#: ../../po/../src/menus-skeleton.h:188 +msgid "_Text" +msgstr "_Text" + +#: ../../po/../src/menus-skeleton.h:200 +msgid "Effects" +msgstr "Efectes" + +#: ../../po/../src/menus-skeleton.h:207 +#, fuzzy +msgid "Whiteboa_rd" +msgstr "Pisarra col·laborativa" + +#: ../../po/../src/menus-skeleton.h:220 +msgid "_Help" +msgstr "_Ajuda" + +#: ../../po/../src/menus-skeleton.h:222 +msgid "Tutorials" +msgstr "Tutorials" + +#: ../../po/../src/node-context.cpp:382 +msgid "" +"Ctrl: toggle node type, snap handle angle, move hor/vert; Ctrl" +"+Alt: move along handles" +msgstr "" +"Control: commuta el tipus de node, ajusta l'angle de gir, mou hor/" +"vert; ctrl+alt: mou els manejadors" + +#: ../../po/../src/node-context.cpp:383 +msgid "" +"Shift: toggle node selection, disable snapping, rotate both handles" +msgstr "" +"Majúscules: commuta la selecció de nodes, inhabilita l'ajust, gira " +"els dos manejadors" + +#: ../../po/../src/node-context.cpp:384 +msgid "Alt: lock handle length; Ctrl+Alt: move along handles" +msgstr "" +"Alt: bloca la longitud del manejador; ctrl+alt: mou els " +"manejadors" + +#: ../../po/../src/nodepath.cpp:1399 ../../po/../src/nodepath.cpp:1411 +#: ../../po/../src/nodepath.cpp:1492 ../../po/../src/nodepath.cpp:1504 +msgid "To join, you must have two endnodes selected." +msgstr "Per unir, heu de seleccionar dos nodes finals." + +#: ../../po/../src/nodepath.cpp:1633 ../../po/../src/nodepath.cpp:1647 +msgid "" +"Select two non-endpoint nodes on a path between which to delete " +"segments." +msgstr "" +"Heu de seleccionar dos nodes que no siguin finals d'un camí entre els " +"quals se suprimiran els segments." + +#: ../../po/../src/nodepath.cpp:1743 +msgid "Cannot find path between nodes." +msgstr "No es pot trobar el camí entre els nodes." + +#: ../../po/../src/nodepath.cpp:2822 +#, c-format +msgid "" +"Node handle: angle %0.2f°, length %s; with Ctrl to snap " +"angle; with Alt to lock length; with Shift to rotate both " +"handles" +msgstr "" +"Manejador de node: a %0.2f°, longithd %s; amb ctrl " +"s'ajusta l'angle; amb alt es bloca la longitud; amb majúscules " +"es giren els dos manejadors" + +#: ../../po/../src/nodepath.cpp:3351 +msgid "" +"Node: drag to edit the path; with Ctrl to snap to horizontal/" +"vertical; with Ctrl+Alt to snap to handles' directions" +msgstr "" +"Node: arrossegueu per editar el camí; amb ctrl per ajustar a " +"hor./vert.; amb ctrl+alt per ajustar les direccions dels manejadors" + +#: ../../po/../src/nodepath.cpp:3375 +msgid "" +"Node handle: drag to shape the curve; with Ctrl to snap angle; " +"with Alt to lock length; with Shift to rotate both handles" +msgstr "" +"Manejador de node: arrossegueu per donar forma a la corba; amb " +"ctrl s'ajusta l'angle; amb alt es bloca la longitud; amb " +"majúscules es giren els dos manejadors" + +#: ../../po/../src/nodepath.cpp:3399 +msgid "" +"Node handle: drag to shape the curve; with Ctrl to snap angle; " +"with Alt to lock length; with Shift to rotate the opposite " +"handle in sync" +msgstr "" +"Manejador de node: arrossegueu per donar forma a la corba; amb " +"ctrl s'ajusta l'angle; amb alt es bloca la longitud; amb " +"majúscules es gira el manejador oposat a la vegada" + +#. TRANSLATORS: "end" is an adjective here (NOT a verb) +#: ../../po/../src/nodepath.cpp:3591 +msgid "end node" +msgstr "node final" + +#. TRANSLATORS: "cusp" means "sharp" (cusp node); see also the Advanced Tutorial +#: ../../po/../src/nodepath.cpp:3596 +msgid "cusp" +msgstr "afilat" + +#. TRANSLATORS: "smooth" is an adjective here +#: ../../po/../src/nodepath.cpp:3599 +msgid "smooth" +msgstr "suau" + +#: ../../po/../src/nodepath.cpp:3601 +msgid "symmetric" +msgstr "simètric" + +#. TRANSLATORS: "end" is an adjective here (NOT a verb) +#: ../../po/../src/nodepath.cpp:3607 +msgid "end node, handle retracted (drag with Shift to extend)" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3609 +msgid "one handle retracted (drag with Shift to extend)" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3612 +msgid "both handles retracted (drag with Shift to extend)" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3624 +msgid "Drag nodes or node handles; arrow keys to move nodes" +msgstr "" +"Arrossegueu nodes o manejadors; les fletxes de teclat mouen " +"els nodes" + +#: ../../po/../src/nodepath.cpp:3625 +msgid "Drag the node or its handles; arrow keys to move the node" +msgstr "" +"Arrossegueu el node o els seus manejadors; les fletxes de teclat mouen el node" + +#: ../../po/../src/nodepath.cpp:3651 ../../po/../src/nodepath.cpp:3663 +msgid "Select a single object to edit its nodes or handles." +msgstr "Seleccioneu un sol objecte per a editar els nodes o els manejadors." + +#: ../../po/../src/nodepath.cpp:3655 +#, c-format +msgid "" +"0 out of %i node selected. Click, Shift+click, " +"or drag around nodes to select." +msgid_plural "" +"0 out of %i nodes selected. Click, Shift+click, " +"or drag around nodes to select." +msgstr[0] "" +"No s'ha seleccionat cap node de %i seleccionat. Cliqueu, majúscula i clic o arrossegueu al voltant dels nodes per " +"seleccionar." +msgstr[1] "" +"No s'ha seleccionat cap node de %i seleccionats. Cliqueu, majúscula i clic o arrossegueu al voltant dels nodes per " +"seleccionar." + +#: ../../po/../src/nodepath.cpp:3661 +msgid "Drag the handles of the object to modify it." +msgstr "Arrossegueu els manejadors de l'objecte per modificar-lo." + +#: ../../po/../src/nodepath.cpp:3669 +#, c-format +msgid "%i of %i node selected; %s. %s." +msgid_plural "%i of %i nodes selected; %s. %s." +msgstr[0] "S'ha seleccionat %i node de %i; %s. %s." +msgstr[1] "S'han seleccionat %i nodes de %i; %s. %s." + +#: ../../po/../src/nodepath.cpp:3675 +#, c-format +msgid "%i of %i node selected. %s." +msgid_plural "%i of %i nodes selected. %s." +msgstr[0] "S'ha seleccionat %i node de %i. %s." +msgstr[1] "S'han seleccionat %i nodes de %i. %s." + +#: ../../po/../src/object-edit.cpp:493 +msgid "" +"Adjust the horizontal rounding radius; with Ctrl to make the " +"vertical radius the same" +msgstr "" +"Ajusta el radi de l'arrodoniment horitzontal; amb ctrl per fer " +"igual el radi vertical" + +#: ../../po/../src/object-edit.cpp:499 +msgid "" +"Adjust the vertical rounding radius; with Ctrl to make the " +"horizontal radius the same" +msgstr "" +"Ajusta el radi de l'arrodoniment vertical; amb ctrl per fer " +"igual el radi vertical" + +#: ../../po/../src/object-edit.cpp:506 ../../po/../src/object-edit.cpp:513 +msgid "" +"Adjust the width and height of the rectangle; with Ctrl to " +"lock ratio or stretch in one dimension only" +msgstr "" +"Ajusta l'amplada i l'alçada del rectangle; amb ctrl es bloca " +"la relació o s'ajusta només una dimensió" + +#: ../../po/../src/object-edit.cpp:686 +msgid "Adjust ellipse width, with Ctrl to make circle" +msgstr "" +"Ajusta l'amplada de l'el·lipse, amb control es fa un cercle" + +#: ../../po/../src/object-edit.cpp:689 +msgid "Adjust ellipse height, with Ctrl to make circle" +msgstr "" +"Ajusteu l'alçada de l'el·lipse, amb control es fa un cercle" + +#: ../../po/../src/object-edit.cpp:692 +msgid "" +"Position the start point of the arc or segment; with Ctrl to " +"snap angle; drag inside the ellipse for arc, outside for " +"segment" +msgstr "" +"Posicioneu el punt inicial de l'arc o segment; amb ctrl " +"s'ajusta l'angle; arrossegueu a dins l'el·lipse per a l'arc, a " +"fora per al segment" + +#: ../../po/../src/object-edit.cpp:695 +msgid "" +"Position the end point of the arc or segment; with Ctrl to " +"snap angle; drag inside the ellipse for arc, outside for " +"segment" +msgstr "" +"Posicioneu el punt final de l'arc o segment; amb ctrl s'ajusta " +"l'angle; arrossegueu a dins l'el·lipse per a l'arc, a fora per " +"al segment" + +#: ../../po/../src/object-edit.cpp:800 +msgid "" +"Adjust the tip radius of the star or polygon; with Shift to " +"round; with Alt to randomize" +msgstr "" +"Ajusteu la distància al centre de l'estel del polígon; amb maj " +"per a arrodonir; amb alt per a aleatoritzar" + +#: ../../po/../src/object-edit.cpp:803 +msgid "" +"Adjust the base radius of the star; with Ctrl to keep star " +"rays radial (no skew); with Shift to round; with Alt to " +"randomize" +msgstr "" +"Ajusteu el radi base de l'estel; amb ctrl per a mantenir els " +"raigs de l'estel radial (sense tòrcer); amb maj per a arrodonir; amb " +"alt per a aleatoritzar" + +#: ../../po/../src/object-edit.cpp:967 +msgid "" +"Roll/unroll the spiral from inside; with Ctrl to snap angle; " +"with Alt to converge/diverge" +msgstr "" +"Enrotlleu/desenrotlleu l'espiral des de dins; amb ctrl per " +"ajustar l'angle; amb alt per convergir/divergir" + +#: ../../po/../src/object-edit.cpp:969 +msgid "" +"Roll/unroll the spiral from outside; with Ctrl to snap angle; " +"with Shift to scale/rotate" +msgstr "" +"Enrotlleu/desenrotlleu l'espiral des de fora; amb ctrl per " +"ajustar l'angle; amb majúscules per escalar/girar" + +#: ../../po/../src/object-edit.cpp:1006 +msgid "Adjust the offset distance" +msgstr "Ajusteu la distància de desplaçament" + +#. TRANSLATORS: This refers to the pattern that's inside the object +#: ../../po/../src/object-edit.cpp:1036 +msgid "Move the pattern fill inside the object" +msgstr "Moveu el patró de farciment de l'interior de l'objecte" + +#: ../../po/../src/object-edit.cpp:1038 +msgid "Scale the pattern fill uniformly" +msgstr "Escaleu el patró de farciment uniformement" + +#: ../../po/../src/object-edit.cpp:1040 +msgid "Rotate the pattern fill; with Ctrl to snap angle" +msgstr "" +"Gireu el patró de farciment; amb ctrl per ajustar l'angle" + +#: ../../po/../src/object-edit.cpp:1065 +msgid "Drag to resize the flowed text frame" +msgstr "Arrossegueu per canviar la mida del marc de text flotant" + +#. Item dialog +#: ../../po/../src/object-ui.cpp:106 +msgid "Object _Properties" +msgstr "Pr_opietats de l'objecte" + +#. Select item +#: ../../po/../src/object-ui.cpp:116 +msgid "_Select This" +msgstr "_Selecciona això" + +#. Create link +#: ../../po/../src/object-ui.cpp:126 +msgid "_Create Link" +msgstr "_Crea un enllaç" + +#. "Ungroup" +#: ../../po/../src/object-ui.cpp:199 ../../po/../src/verbs.cpp:1931 +msgid "_Ungroup" +msgstr "Desagr_upa" + +#. Link dialog +#: ../../po/../src/object-ui.cpp:239 +msgid "Link _Properties" +msgstr "_Propietats de l'enllaç" + +#. Select item +#: ../../po/../src/object-ui.cpp:249 +msgid "_Follow Link" +msgstr "Se_gueix l'enllaç" + +#. Reset transformations +#: ../../po/../src/object-ui.cpp:254 +msgid "_Remove Link" +msgstr "Sup_rimeix l'enllaç" + +#. Link dialog +#: ../../po/../src/object-ui.cpp:303 +msgid "Image _Properties" +msgstr "_Propietats de la imatge" + +#. Item dialog +#: ../../po/../src/object-ui.cpp:344 +msgid "_Fill and Stroke" +msgstr "Far_ciment i contorn" + +#: ../../po/../src/path-chemistry.cpp:58 +msgid "Select at least two objects to combine." +msgstr "Seleccioneu almenys 2 objectes per combinar." + +#: ../../po/../src/path-chemistry.cpp:65 +msgid "At least one of the objects is not a path, cannot combine." +msgstr "Un dels objectes no és un camí. No es pot combinar." + +#: ../../po/../src/path-chemistry.cpp:73 +msgid "" +"You cannot combine objects from different groups or layers." +msgstr "No podeu combinar objectes de grups o capes diferents." + +#: ../../po/../src/path-chemistry.cpp:155 +msgid "Select path(s) to break apart." +msgstr "Seleccioneu els camins a separar." + +#: ../../po/../src/path-chemistry.cpp:231 +msgid "No path(s) to break apart in the selection." +msgstr "No hi ha camins a separar en la selecció." + +#: ../../po/../src/path-chemistry.cpp:252 +msgid "Select object(s) to convert to path." +msgstr "Seleccioneu objectes per convertir a camí." + +#: ../../po/../src/path-chemistry.cpp:297 +msgid "No objects to convert to path in the selection." +msgstr "No hi ha cap objecte per convertir en camí en la selecció." + +#: ../../po/../src/path-chemistry.cpp:345 +msgid "Select path(s) to reverse." +msgstr "Seleccioneu camins per invertir." + +#: ../../po/../src/path-chemistry.cpp:370 +msgid "No paths to reverse in the selection." +msgstr "No hi ha cap camí per invertir en la selecció." + +#: ../../po/../src/pen-context.cpp:379 ../../po/../src/pencil-context.cpp:233 +msgid "Continuing selected path" +msgstr "Continuar els camins seleccionats" + +#: ../../po/../src/pen-context.cpp:390 ../../po/../src/pencil-context.cpp:242 +msgid "Creating new path" +msgstr "S'està creant un nou camí" + +#: ../../po/../src/pen-context.cpp:394 ../../po/../src/pencil-context.cpp:246 +msgid "Appending to selected path" +msgstr "S'està afegint al camí seleccionat" + +#: ../../po/../src/pen-context.cpp:538 +msgid "Click or click and drag to close and finish the path." +msgstr "" +"Cliqueu o cliqueu i arrossegueu per tancar i acabar el camí." + +#: ../../po/../src/pen-context.cpp:548 +msgid "" +"Click or click and drag to continue the path from this point." +msgstr "" +"Cliqueu o cliqueu i arrossegueu per continuar el camí des " +"d'aquest punt." + +#: ../../po/../src/pen-context.cpp:857 +#, c-format +msgid "" +"%s: angle %3.2f°, distance %s; with Ctrl to snap angle, " +"Enter to finish the path" +msgstr "" +"%s: angle %3.2f°, distància %s; amb ctrl s'ajusta " +"l'angle; amb entrar s'acaba el camí" + +#: ../../po/../src/pen-context.cpp:882 +#, c-format +msgid "" +"Curve handle: angle %3.2f°, length %s; with Ctrl to snap " +"angle" +msgstr "" +"Manejador de corba: angle %3.2f°, longitud %s; amb ctrl " +"s'ajusta l'angle" + +#: ../../po/../src/pen-context.cpp:912 +#, c-format +msgid "" +"%s: angle %3.2f°, length %s; with Ctrl to snap angle, " +"with Shift to move this handle only" +msgstr "" +"%s: angle %3.2f°, longithd %s; amb ctrl s'ajusta l'angle; " +"amb majúscules es mou aquest manejador només" + +#: ../../po/../src/pen-context.cpp:946 +msgid "Finishing pen" +msgstr "Fi de la ploma" + +#: ../../po/../src/pencil-context.cpp:320 +msgid "Release here to close and finish the path." +msgstr "Allibereu aquí per tancar i acabar el camí." + +#: ../../po/../src/pencil-context.cpp:326 +msgid "Drawing a freehand path" +msgstr "S'està dibuixant un camí a mà alçada" + +#: ../../po/../src/pencil-context.cpp:331 +msgid "Drag to continue the path from this point." +msgstr "Arrossegueu per continuar el camí des d'aquest punt." + +#. Write curves to object +#: ../../po/../src/pencil-context.cpp:390 +msgid "Finishing freehand" +msgstr "Fi de la mà alçada" + +#: ../../po/../src/rect-context.cpp:387 +msgid "" +"Ctrl: make square or integer-ratio rect, lock a rounded corner " +"circular" +msgstr "" +"Ctrl: feu un quadrat o un rectangle de radi enter, bloqueu " +"circularment una cantonada rodona" + +#: ../../po/../src/rect-context.cpp:549 +#, c-format +msgid "" +"Rectangle: %s × %s; with Ctrl to make square or integer-" +"ratio rectangle; with Shift to draw around the starting point" +msgstr "" +"Rectangle: %s × %s; amb ctrl per fer un quadrat o un " +"rectangle de radi d'enter; amb majúscules per dibuixar al voltant del " +"punt d'inici" + +#: ../../po/../src/select-context.cpp:243 +msgid "Move canceled." +msgstr "No s'ha mogut." + +#: ../../po/../src/select-context.cpp:252 +msgid "Selection canceled." +msgstr "S'ha cancel·lat la selecció." + +#: ../../po/../src/select-context.cpp:642 +msgid "Ctrl: select in groups, move hor/vert" +msgstr "Ctrl: seleccioneu en grups, moveu hor/vert" + +#: ../../po/../src/select-context.cpp:643 +msgid "Shift: toggle select, force rubberband, disable snapping" +msgstr "" + +#: ../../po/../src/select-context.cpp:644 +msgid "Alt: select under, move selected" +msgstr "" + +#: ../../po/../src/select-context.cpp:798 +#, fuzzy +msgid "Selected object is not a group. Cannot enter." +msgstr "" +"L'objecte seleccionat no és un camí, no es pot contreure/expandir." + +#: ../../po/../src/select-context.cpp:876 +#, c-format +msgid "" +"Move by %s, %s; with Ctrl to restrict to horizontal/vertical; " +"with Shift to disable snapping" +msgstr "" +"Moveu a %s, %s; amb ctrl per restringir a horitzontal/" +"vertical; amb majúscules inhabilita l'ajustament" + +#: ../../po/../src/selection-chemistry.cpp:228 +msgid "Nothing was deleted." +msgstr "No s'ha suprimit res." + +#: ../../po/../src/selection-chemistry.cpp:259 +msgid "Select object(s) to duplicate." +msgstr "Seleccioneu objectes per duplicar-los." + +#: ../../po/../src/selection-chemistry.cpp:420 +msgid "Select two or more objects to group." +msgstr "Seleccioneu dos o més objectes per agrupar-los." + +#: ../../po/../src/selection-chemistry.cpp:428 +msgid "Select at least two objects to group." +msgstr "Seleccioneu almenys dos objectes per agrupar-los." + +#: ../../po/../src/selection-chemistry.cpp:513 +msgid "Select a group to ungroup." +msgstr "Seleccioneu un grup per desagrupar-lo." + +#: ../../po/../src/selection-chemistry.cpp:554 +msgid "No groups to ungroup in the selection." +msgstr "No hi ha cap grup en la selecció que es pugui desagrupar." + +#: ../../po/../src/selection-chemistry.cpp:623 +msgid "Select objects to raise." +msgstr "Seleccioneu alguns objectes per alçar-los." + +#: ../../po/../src/selection-chemistry.cpp:629 +#: ../../po/../src/selection-chemistry.cpp:681 +#: ../../po/../src/selection-chemistry.cpp:715 +#: ../../po/../src/selection-chemistry.cpp:773 +msgid "" +"You cannot raise/lower objects from different groups or layers." +msgstr "No podeu alçar/baixar objectes de grups o capes diferents." + +#: ../../po/../src/selection-chemistry.cpp:673 +msgid "Select object(s) to raise to top." +msgstr "Seleccioneu alguns objectes per alçar-los a dalt de tot." + +#: ../../po/../src/selection-chemistry.cpp:709 +msgid "Select object(s) to lower." +msgstr "Seleccioneu alguns objectes per baixar-los." + +#: ../../po/../src/selection-chemistry.cpp:765 +msgid "Select object(s) to lower to bottom." +msgstr "Seleccioneu alguns objectes per baixar-los a baix de tot." + +#: ../../po/../src/selection-chemistry.cpp:806 +msgid "Nothing to undo." +msgstr "No hi ha res per desfer." + +#: ../../po/../src/selection-chemistry.cpp:813 +msgid "Nothing to redo." +msgstr "No hi ha res per tornar a fer." + +#: ../../po/../src/selection-chemistry.cpp:969 +msgid "Nothing was copied." +msgstr "No s'ha copiat res." + +#: ../../po/../src/selection-chemistry.cpp:1051 +msgid "Current layer is hidden. Unhide it to be able to paste to it." +msgstr "La capa actual està amagada. Mostreu-la per poder-hi enganxar." + +#: ../../po/../src/selection-chemistry.cpp:1055 +msgid "Current layer is locked. Unlock it to be able to paste to it." +msgstr "" +"La capa actual està blocada. Desbloqueu-la per poder-hi enganxar." + +#: ../../po/../src/selection-chemistry.cpp:1068 +#: ../../po/../src/selection-chemistry.cpp:1103 +msgid "Nothing on the clipboard." +msgstr "No hi ha res al porta-retalls." + +#: ../../po/../src/selection-chemistry.cpp:1109 +msgid "Select object(s) to paste style to." +msgstr "Seleccioneu objectes per a enganxar-hi l'estil." + +#: ../../po/../src/selection-chemistry.cpp:1128 +msgid "Select object(s) to move to the layer above." +msgstr "Seleccioneu objectes per a moure a la capa de sobre." + +#: ../../po/../src/selection-chemistry.cpp:1146 +msgid "No more layers above." +msgstr "Cap capa per sobre" + +#: ../../po/../src/selection-chemistry.cpp:1160 +msgid "Select object(s) to move to the layer below." +msgstr "Seleccioneu objectes per a moure a la capa de sota." + +#: ../../po/../src/selection-chemistry.cpp:1178 +msgid "No more layers below." +msgstr "Cap capa per sota." + +#: ../../po/../src/selection-chemistry.cpp:1811 +msgid "Select a clone to unlink." +msgstr "Seleccioneu un clon per desenllaçar-lo." + +#: ../../po/../src/selection-chemistry.cpp:1842 +msgid "No clones to unlink in the selection." +msgstr "" +"No hi ha cap clon en la selecció que es pugui desenllaçar." + +#: ../../po/../src/selection-chemistry.cpp:1859 +msgid "" +"Select a clone to go to its original. Select a linked offset " +"to go to its source. Select a text on path to go to the path. Select " +"a flowed text to go to its frame." +msgstr "" +"Seleccioneu un clon per a anar al seu original. Seleccioneu un " +"desplaçament enllaçat per anar al seu origen. Seleccioneu text en " +"camí per anar al camí. Seleccioneu un text flotat per anar al seu " +"marc." + +#: ../../po/../src/selection-chemistry.cpp:1882 +msgid "" +"Cannot find the object to select (orphaned clone, offset, textpath, " +"flowed text?)" +msgstr "" +"No es pot trobar l'objecte per seleccionar (clon orfe, desplaçament, " +"camí de text o text flotat)" + +#: ../../po/../src/selection-chemistry.cpp:1888 +msgid "" +"The object you're trying to select is not visible (it is in <" +"defs>)" +msgstr "" +"L'objecte que esteu intentant seleccionar no és visible (està a <" +"defs>)" + +#: ../../po/../src/selection-chemistry.cpp:1915 +msgid "Select object(s) to convert to pattern." +msgstr "Seleccioneu objectes per convertir a patró." + +#: ../../po/../src/selection-chemistry.cpp:2006 +msgid "Select an object with pattern fill to extract objects from." +msgstr "" +"Seleccioneu un objecte amb patró de farciment per extreure'n objectes." + +#: ../../po/../src/selection-chemistry.cpp:2059 +msgid "No pattern fills in the selection." +msgstr "No hi ha patrons de farciment a la selecció." + +#: ../../po/../src/selection-chemistry.cpp:2079 +msgid "Select object(s) to make a bitmap copy." +msgstr "Seleccioneu alguns objectes per fer un còpia de mapa de bits." + +#: ../../po/../src/selection-describer.cpp:37 +msgid "Click selection to toggle scale/rotation handles" +msgstr "Cliqueu la selecció per commutar entre manejadors per rotar/escalar" + +#. no items +#: ../../po/../src/selection-describer.cpp:39 +msgid "" +"No objects selected. Click, Shift+click, or drag around objects to select." +msgstr "" +"No s'ha seleccionat cap objecte. Cliqueu, maj+clic, o arrossegueu al voltant " +"dels objectes per seleccionar." + +#: ../../po/../src/selection-describer.cpp:51 +#, c-format +msgid " in layer %s" +msgstr " a la capa %s" + +#: ../../po/../src/selection-describer.cpp:54 +#, c-format +msgid " in layer %s" +msgstr " a la capa %s" + +#: ../../po/../src/selection-describer.cpp:66 +msgid "Use Shift+D to look up original" +msgstr "Useu majúscula+d per cercar l'original" + +#: ../../po/../src/selection-describer.cpp:70 +msgid "Use Shift+D to look up path" +msgstr "Useu majúscula+d per cercar el camí" + +#: ../../po/../src/selection-describer.cpp:74 +msgid "Use Shift+D to look up frame" +msgstr "Useu majúscula+d per cercar el marc" + +#: ../../po/../src/selection-describer.cpp:84 +#, c-format +msgid "%i object selected" +msgid_plural "%i objects selected" +msgstr[0] "S'ha seleccionat %i objecte." +msgstr[1] "S'han seleccionat %i objectes." + +#: ../../po/../src/selection-describer.cpp:90 +#, c-format +msgid "%s%s. %s." +msgstr "%s%s. %s." + +#: ../../po/../src/selection-describer.cpp:94 +#, c-format +msgid "%s in %i layer. %s." +msgid_plural "%s in %i layers. %s." +msgstr[0] "%s a %i capa. %s" +msgstr[1] "%s a %i capes. %s." + +#: ../../po/../src/seltrans.cpp:498 +msgid "" +"Center of rotation and skewing: drag to reposition; scaling with " +"Shift also uses this center" +msgstr "" +"Centre de rotació i torsió; arrossegueu per a reposicionar; escalar " +"amb maj també usa aquest centre" + +#: ../../po/../src/seltrans.cpp:514 +msgid "" +"Squeeze or stretch selection; with Ctrl to scale uniformly; " +"with Shift to scale around rotation center" +msgstr "" +"Estireu o estrenyeu la selecció; amb ctrl per a escalar " +"uniformement; amb maj per a escalar al voltant del centre de rotació" + +#: ../../po/../src/seltrans.cpp:515 +msgid "" +"Scale selection; with Ctrl to scale uniformly; with Shift to scale around rotation center" +msgstr "" +"Escaleu la selecció; amb ctrl per escalar uniformement; amb " +"majúscules per escalar al voltant del centre de rotació" + +#: ../../po/../src/seltrans.cpp:519 +msgid "" +"Skew selection; with Ctrl to snap angle; with Shift to " +"skew around the opposite side" +msgstr "" +"Torceu la selecció; amb ctrl per ajustar l'angle; amb " +"majúscules per girar al voltant de la cantonada contrària" + +#: ../../po/../src/seltrans.cpp:520 +msgid "" +"Rotate selection; with Ctrl to snap angle; with Shift " +"to rotate around the opposite corner" +msgstr "" +"Gireu la selecció; amb ctrl per ajustar l'angle; amb " +"majúscules per girar al voltant de la cantonada contrària" + +#: ../../po/../src/seltrans.cpp:829 ../../po/../src/seltrans.cpp:909 +#, c-format +msgid "Scale: %0.2f%% x %0.2f%%; with Ctrl to lock ratio" +msgstr "" +"Escala: %0.2f%% x %0.2f%%; amb control per blocar el radi" + +#. TRANSLATORS: don't modify the first ";" (it will NOT be displayed as ";" - only the second one will be) +#: ../../po/../src/seltrans.cpp:984 +#, c-format +msgid "Skew: %0.2f°; with Ctrl to snap angle" +msgstr "Torceu: %0.2f°; amb ctrl per ajustar l'angle" + +#. TRANSLATORS: don't modify the first ";" (it will NOT be displayed as ";" - only the second one will be) +#: ../../po/../src/seltrans.cpp:1035 +#, c-format +msgid "Rotate: %0.2f°; with Ctrl to snap angle" +msgstr "Gira: %0.2f°; amb ctrl per ajustar l'angle" + +#: ../../po/../src/seltrans.cpp:1090 +#, c-format +msgid "Move center to %s, %s" +msgstr "Mou el centre a %s, %s" + +#: ../../po/../src/slideshow.cpp:90 +msgid "Inkscape slideshow" +msgstr "Diapositives de l'Inkscape" + +#: ../../po/../src/sp-anchor.cpp:181 +#, c-format +msgid "Link to %s" +msgstr "Enllaç a %s" + +#: ../../po/../src/sp-anchor.cpp:185 +msgid "Link without URI" +msgstr "Enllaç sense URI" + +#: ../../po/../src/sp-ellipse.cpp:438 ../../po/../src/sp-ellipse.cpp:870 +msgid "Ellipse" +msgstr "El·lipse" + +#: ../../po/../src/sp-ellipse.cpp:583 +msgid "Circle" +msgstr "Cercle" + +#: ../../po/../src/sp-ellipse.cpp:865 +msgid "Segment" +msgstr "Segment:" + +#: ../../po/../src/sp-ellipse.cpp:867 +msgid "Arc" +msgstr "Arc" + +#. TRANSLATORS: "Flow region" is an area where text is allowed to flow +#: ../../po/../src/sp-flowregion.cpp:276 +msgid "Flow region" +msgstr "Regió flotant" + +#. TRANSLATORS: A region "cut out of" a flow region; text is not allowed to flow inside the +#. * flow excluded region. flowRegionExclude in SVG 1.2: see +#. * http://www.w3.org/TR/2004/WD-SVG12-20041027/flow.html#flowRegion-elem and +#. * http://www.w3.org/TR/2004/WD-SVG12-20041027/flow.html#flowRegionExclude-elem. +#: ../../po/../src/sp-flowregion.cpp:493 +msgid "Flow excluded region" +msgstr "Flota la regió exclosa" + +#: ../../po/../src/sp-flowtext.cpp:355 +#, c-format +msgid "Flowed text (%d characters)" +msgstr "Text flotat (%d caràcters)" + +#: ../../po/../src/sp-flowtext.cpp:357 +#, c-format +msgid "Linked flowed text (%d characters)" +msgstr "Text flotat enllaçat (%d caràcters)" + +#: ../../po/../src/sp-guide.cpp:290 +msgid "vertical guideline" +msgstr "línia guia vertical" + +#: ../../po/../src/sp-guide.cpp:292 +msgid "horizontal guideline" +msgstr "línia guia horitzontal" + +#: ../../po/../src/sp-image.cpp:835 +msgid "embedded" +msgstr "inclòs" + +#: ../../po/../src/sp-image.cpp:839 +msgid "(null_pointer)" +msgstr "(punter_null)" + +#: ../../po/../src/sp-image.cpp:843 +#, c-format +msgid "Image with bad reference: %s" +msgstr "La imatge té una referència incorrecta: %s" + +#: ../../po/../src/sp-image.cpp:844 +#, c-format +msgid "Image %d × %d: %s" +msgstr "Imatge %d × %d: %s" + +#: ../../po/../src/sp-item-group.cpp:390 +#, c-format +msgid "Group of %d object" +msgid_plural "Group of %d objects" +msgstr[0] "Grup d'%d objecte" +msgstr[1] "Grup de %d objectes" + +#: ../../po/../src/sp-item.cpp:720 +msgid "Object" +msgstr "Objecte" + +#: ../../po/../src/sp-line.cpp:202 +msgid "Line" +msgstr "Línia" + +#. TRANSLATORS COMMENT: %s is either "outset" or "inset" depending on sign +#: ../../po/../src/sp-offset.cpp:433 +#, c-format +msgid "Linked offset, %s by %f pt" +msgstr "Desplaçament enllaçat, %s %f punts" + +#: ../../po/../src/sp-offset.cpp:434 ../../po/../src/sp-offset.cpp:438 +msgid "outset" +msgstr "expandeix" + +#: ../../po/../src/sp-offset.cpp:434 ../../po/../src/sp-offset.cpp:438 +msgid "inset" +msgstr "contreu" + +#. TRANSLATORS COMMENT: %s is either "outset" or "inset" depending on sign +#: ../../po/../src/sp-offset.cpp:437 +#, c-format +msgid "Dynamic offset, %s by %f pt" +msgstr "Desplaçament dinàmic, %s %f pt" + +#: ../../po/../src/sp-path.cpp:127 +#, c-format +msgid "Path (%i node)" +msgid_plural "Path (%i nodes)" +msgstr[0] "Camí (%i node)" +msgstr[1] "Camí (%i nodes)" + +#: ../../po/../src/sp-polygon.cpp:216 +msgid "Polygon" +msgstr "Polígon" + +#: ../../po/../src/sp-polyline.cpp:179 +msgid "Polyline" +msgstr "Polilínia" + +#: ../../po/../src/sp-rect.cpp:250 +msgid "Rectangle" +msgstr "Rectangle" + +#. TRANSLATORS: since turn count isn't an integer, please adjust the +#. string as needed to deal with an localized plural forms. +#: ../../po/../src/sp-spiral.cpp:305 +#, c-format +msgid "Spiral with %3f turns" +msgstr "Espiral amb %3f voltes" + +#: ../../po/../src/sp-star.cpp:288 +#, c-format +msgid "Star with %d vertex" +msgid_plural "Star with %d vertices" +msgstr[0] "Estel amb %d vèrtex" +msgstr[1] "Estel amb %d vèrtexs" + +#: ../../po/../src/sp-star.cpp:292 +#, c-format +msgid "Polygon with %d vertex" +msgid_plural "Polygon with %d vertices" +msgstr[0] "Polígon amb %d vèrtex" +msgstr[1] "Polígon amb %d vèrtexs" + +#. TRANSLATORS: For description of font with no name. +#: ../../po/../src/sp-text.cpp:420 +msgid "<no name found>" +msgstr "<no s'ha trobat el nom>" + +#: ../../po/../src/sp-text.cpp:426 +#, c-format +msgid "Text on path (%s, %s)" +msgstr "Text en camí (%s, %s)" + +#: ../../po/../src/sp-text.cpp:427 +#, c-format +msgid "Text (%s, %s)" +msgstr "Text (%s, %s)" + +#. TRANSLATORS: Used for statusbar description for long chains: +#. * "Clone of: Clone of: ... in Layer 1". +#: ../../po/../src/sp-use.cpp:317 +msgid "..." +msgstr "..." + +#: ../../po/../src/sp-use.cpp:325 +#, c-format +msgid "Clone of: %s" +msgstr "Clon de: %s" + +#: ../../po/../src/sp-use.cpp:329 +msgid "Orphaned clone" +msgstr "Clon orfe" + +#: ../../po/../src/spiral-context.cpp:355 +msgid "Ctrl: snap angle" +msgstr "Control: ajusta l'angle" + +#: ../../po/../src/spiral-context.cpp:357 +msgid "Alt: lock spiral radius" +msgstr "Alt: bloca el radi de l'espiral" + +#: ../../po/../src/spiral-context.cpp:469 +#, c-format +msgid "" +"Spiral: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" +"Espiral: radi %s, angle %5g°; amb ctrl per ajustar l'angle" + +#: ../../po/../src/splivarot.cpp:106 +msgid "Select at least 2 paths to perform a boolean operation." +msgstr "" +"Seleccioneu almenys 2 camins per realitzar una operació booleana." + +#: ../../po/../src/splivarot.cpp:112 +msgid "" +"Select exactly 2 paths to perform difference, XOR, division, or path " +"cut." +msgstr "" +"Seleccioneu només 2 camins per restar-los, aplicar l'O exclusiva o " +"tallar el camí." + +#: ../../po/../src/splivarot.cpp:129 ../../po/../src/splivarot.cpp:144 +msgid "" +"Unable to determine the z-order of the objects selected for " +"difference, XOR, division, or path cut." +msgstr "" +"No s'ha pogut determinar l'ordre de profunditat dels objectes " +"seleccionats per fer la resta, l'O exclusiva, la divisió o tallar el camí." + +#: ../../po/../src/splivarot.cpp:174 +msgid "" +"One of the objects is not a path, cannot perform boolean operation." +msgstr "" +"Un dels objectes no és un camí. No es pot realitzar l'operació " +"booleana." + +#. TRANSLATORS: "to outline" means "to convert stroke to path" +#: ../../po/../src/splivarot.cpp:554 +msgid "Select path(s) to outline." +msgstr "Seleccioneu més d'un camí per convertir de contorn a camí." + +#. TRANSLATORS: "to outline" means "to convert stroke to path" +#: ../../po/../src/splivarot.cpp:748 +msgid "No stroked paths to outline in the selection." +msgstr "No hi ha camins per convertir de contorn a camí" + +#: ../../po/../src/splivarot.cpp:832 +msgid "Selected object is not a path, cannot inset/outset." +msgstr "" +"L'objecte seleccionat no és un camí, no es pot contreure/expandir." + +#: ../../po/../src/splivarot.cpp:1040 +msgid "Select path(s) to inset/outset." +msgstr "Seleccioneu uns camins per contreure/expandir." + +#: ../../po/../src/splivarot.cpp:1257 +msgid "No paths to inset/outset in the selection." +msgstr "No hi ha cap camí per contreure/expandir a la selecció." + +#: ../../po/../src/splivarot.cpp:1390 +msgid "Select path(s) to simplify." +msgstr "Seleccioneu uns camins per simplificar-los." + +#: ../../po/../src/splivarot.cpp:1417 +msgid "No paths to simplify in the selection." +msgstr "No hi ha cap camí per simplificar a la selecció." + +#: ../../po/../src/star-context.cpp:362 +msgid "Ctrl: snap angle; keep rays radial" +msgstr "Control: ajusta l'angle, conserva els rajos radials" + +#: ../../po/../src/star-context.cpp:470 +#, c-format +msgid "" +"Polygon: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" +"Polígon: radi %s, angle %5g°; amb control per ajustar " +"l'angle" + +#: ../../po/../src/star-context.cpp:471 +#, c-format +msgid "Star: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" +"Estel: radi %s, angle %5g°; amb control per ajustar " +"l'angle" + +#: ../../po/../src/text-chemistry.cpp:90 +msgid "Select a text and a path to put text on path." +msgstr "Seleccioneu un text i un camí per posar el text en el camí" + +#: ../../po/../src/text-chemistry.cpp:95 +msgid "" +"This text object is already put to a path. Remove it from the path " +"first. Use Shift+D to look up its path." +msgstr "" +"Aquest objecte de text ja està en un camí. Suprimiu-lo del camí " +"primer. Useu majúscula+d per cercar el seu camí" + +#. rect is the only SPShape which is not yet, and thus SVG forbids us from putting text on it +#: ../../po/../src/text-chemistry.cpp:101 +msgid "" +"You cannot put text on a rectangle in this version. Convert rectangle to " +"path first." +msgstr "" +"No podeu posar text en un rectangle amb aquesta versió. Heu de convertir el " +"rectangle en camí primer." + +#: ../../po/../src/text-chemistry.cpp:159 +msgid "Select a text on path to remove it from path." +msgstr "Seleccioneu un text en el camí per suprimir-lo del camí." + +#: ../../po/../src/text-chemistry.cpp:181 +msgid "No texts-on-paths in the selection." +msgstr "No hi ha texts en camí a la selecció." + +#: ../../po/../src/text-chemistry.cpp:209 +#: ../../po/../src/text-chemistry.cpp:229 +msgid "Select text(s) to remove kerns from." +msgstr "" + +#: ../../po/../src/text-chemistry.cpp:250 +msgid "" +"Select a text and one or more paths or shapes to flow text " +"into frame." +msgstr "" +"Seleccioneu un text i un o més camins o formes per flotar el " +"text en el marc." + +#: ../../po/../src/text-chemistry.cpp:322 +msgid "Select a flowed text to unflow it." +msgstr "Seleccioneu un text flotant per desfer-ho." + +#: ../../po/../src/text-context.cpp:463 +msgid "Click to edit the text, drag to select part of the text." +msgstr "" +"Cliqueu per editar el text, arrossegueu per seleccionar part " +"del text." + +#: ../../po/../src/text-context.cpp:465 +msgid "" +"Click to edit the flowed text, drag to select part of the text." +msgstr "" +"Cliqueu per editar el text flotant, arrossegueu per " +"seleccionar part del text." + +#: ../../po/../src/text-context.cpp:540 +msgid "Non-printable character" +msgstr "Caràcter no imprimible" + +#: ../../po/../src/text-context.cpp:589 +#, c-format +msgid "Unicode: %s: %s" +msgstr "Unicode: %s: %s" + +#: ../../po/../src/text-context.cpp:591 ../../po/../src/text-context.cpp:855 +msgid "Unicode: " +msgstr "Unicode: " + +#: ../../po/../src/text-context.cpp:615 +msgid "Current layer is hidden. Unhide it to be able to add text." +msgstr "La capa actual està amagada. Mostreu-la per afegir-hi text." + +#: ../../po/../src/text-context.cpp:619 +msgid "Current layer is locked. Unlock it to be able to add text." +msgstr "La capa actual està blocada. Desbloqueu-la per afegir-hi text." + +#: ../../po/../src/text-context.cpp:673 +#, c-format +msgid "Flowed text frame: %s × %s" +msgstr "Marc del text flotat: %s × %s" + +#: ../../po/../src/text-context.cpp:708 ../../po/../src/text-context.cpp:1464 +msgid "Type text; Enter to start new line." +msgstr "Escriviu el text; comenceu noves línies amb tecla de retorn." + +#: ../../po/../src/text-context.cpp:719 +msgid "Flowed text is created." +msgstr "S'ha creat el text flotat." + +#: ../../po/../src/text-context.cpp:722 +msgid "" +"The frame is too small for the current font size. Flowed text not " +"created." +msgstr "" +"El marc és massa petit per a la mida del tipus de lletra actual. No " +"es pot crea el text flotat." + +#: ../../po/../src/text-context.cpp:841 +msgid "No-break space" +msgstr "Espai sense trencament" + +#: ../../po/../src/text-context.cpp:1462 +msgid "Type flowed text; Enter to start new paragraph." +msgstr "" +"Escriviu el text flotat; comenceu un nou paràgraf amb tecla de retorn." + +#: ../../po/../src/text-context.cpp:1472 ../../po/../src/tools-switch.cpp:189 +msgid "" +"Click to select or create text, drag to create flowed text; " +"then type." +msgstr "" +"Cliqueu per a seleccionar o crear text, arrossegueu per crear " +"un text flotat i escriviu-hi." + +#: ../../po/../src/tools-switch.cpp:141 +msgid "" +"To edit a path, click, Shift+click, or drag around " +"nodes to select them, then drag nodes and handles. Click on an " +"object to select." +msgstr "" +"Per editar un camí, cliqueu, maj+clic, arrossegueu al " +"voltant dels nodes per seleccionar-los, després arrossegueu els " +"nodes i els manejadors. Cliqueu en un objecte per seleccionar-lo." + +#: ../../po/../src/tools-switch.cpp:147 +msgid "" +"Drag to create a rectangle. Drag controls to round corners and " +"resize. Click to select." +msgstr "" +"Arrossegueu per crear un rectangle. Arrossegueu els controls " +"per arrodonir les cantonades. Cliqueu per seleccionar." + +#: ../../po/../src/tools-switch.cpp:153 +msgid "" +"Drag to create an ellipse. Drag controls to make an arc or " +"segment. Click to select." +msgstr "" +"Arrossegueu per crear una el·lipse. Arrossegueu els controls " +"per fer un arc o un segment. Cliqueu per seleccionar." + +#: ../../po/../src/tools-switch.cpp:159 +msgid "" +"Drag to create a star. Drag controls to edit the star shape. " +"Click to select." +msgstr "" +"Arrossegueu per crear un estel. Arrossegueu els controls per " +"editar la forma de l'estel. Cliqueu per seleccionar." + +#: ../../po/../src/tools-switch.cpp:165 +msgid "" +"Drag to create a spiral. Drag controls to edit the spiral " +"shape. Click to select." +msgstr "" +"Arrossegueu per crear una espiral. Arrossegueu els controls " +"per editar l'espiral. Cliqueu per seleccionar." + +#: ../../po/../src/tools-switch.cpp:171 +msgid "" +"Drag to create a freehand line. Start drawing with Shift to " +"append to selected path." +msgstr "" +"Arrossegueu per crear una línia a mà alçada. Comenceu a dibuixar amb " +"majúscules per afegir al camí seleccionat." + +#: ../../po/../src/tools-switch.cpp:177 +msgid "" +"Click or click and drag to start a path; with Shift to " +"append to selected path." +msgstr "" +"Cliqueu o cliqueu i arrossegueu per començar un camí; amb " +"majúscules per afegir al camí seleccionat." + +#: ../../po/../src/tools-switch.cpp:183 +msgid "" +"Drag to paint a calligraphic stroke. Left/right arrow " +"keys adjust width, up/down adjust angle." +msgstr "" +"Arrossegueu per pintar un contorn cal·ligràfic. La fletxa " +"esquerra/dreta ajusta l'amplada, amunt/abaix " +"ajusta l'angle." + +#: ../../po/../src/tools-switch.cpp:195 +msgid "" +"Drag or double click to create a gradient on selected objects, " +"drag handles to adjust gradients." +msgstr "" +"Arrossegueu o feu doble click per crear un degradat en els " +"objectes seleccionats, arrossegueu els manejadors per ajustar els " +"degradats." + +#: ../../po/../src/tools-switch.cpp:201 +msgid "" +"Click or drag around an area to zoom in, Shift+click to " +"zoom out." +msgstr "" +"Cliqueu o arrossegueu al voltant d'una àrea per ampliar-la, " +"maj+clic per reduir-la." + +#: ../../po/../src/tools-switch.cpp:213 +msgid "Click and drag between shapes to create a connector." +msgstr "Cliqueu i arrossegueu entre formes per a crear un connector." + +#: ../../po/../src/trace/potrace/inkscape-potrace.cpp:553 +#: ../../po/../src/trace/potrace/inkscape-potrace.cpp:654 +#, c-format +msgid "Trace: %d. %ld nodes" +msgstr "Vectoritza: %d. %ld nodes" + +#: ../../po/../src/trace/trace.cpp:53 ../../po/../src/trace/trace.cpp:62 +#: ../../po/../src/trace/trace.cpp:70 +msgid "Select an image to trace" +msgstr "Seleccioneu una imatge per vectoritzar" + +#: ../../po/../src/trace/trace.cpp:133 +msgid "Trace: No active document" +msgstr "Vectoritza: no hi ha cap document actiu" + +#: ../../po/../src/trace/trace.cpp:154 +msgid "Trace: Image has no bitmap data" +msgstr "Vectoritza: la imatge no té dades de mapa de bits" + +#: ../../po/../src/trace/trace.cpp:267 +#, c-format +msgid "Trace: Done. %ld nodes created" +msgstr "Vectoritza: s'han creat %ld nodes" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:59 ../../po/../src/verbs.cpp:2212 +msgid "About Inkscape" +msgstr "Quant a l'Inkscape" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:66 +msgid "_Splash" +msgstr "" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:68 +#, fuzzy +msgid "_Authors" +msgstr "Autors" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:69 +#, fuzzy +msgid "_Translators" +msgstr "Traductors" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:70 +msgid "_License" +msgstr "_Llicència" + +#. TRANSLATORS: This is the filename of the `About Inkscape' picture in +#. the `screens' directory. Thus the translation of "about.svg" should be +#. the filename of its translated version, e.g. about.zh.svg for Chinese. +#. +#. N.B. about.svg changes once per release. (We should probably rename +#. the original to about-0.40.svg etc. as soon as we have a translation. +#. If we do so, then add an item to release-checklist saying that the +#. string here should be changed.) +#. FIXME? INKSCAPE_SCREENSDIR and "about.svg" are in UTF-8, not the +#. native filename encoding... and the filename passed to sp_document_new +#. should be in UTF-*8.. +#: ../../po/../src/ui/dialog/aboutbox.cpp:114 +msgid "about.svg" +msgstr "about.svg" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:464 +msgid "Minimum horizontal gap (in px units) between bounding boxes" +msgstr "" + +#. TRANSLATORS: Horizontal gap +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:466 +#: ../../po/../src/widgets/toolbox.cpp:1556 +msgid "H:" +msgstr "A:" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:474 +msgid "Minimum vertical gap (in px units) between bounding boxes" +msgstr "" + +#. TRANSLATORS: Vertical gap +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:476 +msgid "V:" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:734 +msgid "Align" +msgstr "Alinea" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:735 +msgid "Distribute" +msgstr "Distribueix" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:736 +msgid "Remove overlaps" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:737 +msgid "Nodes" +msgstr "Nodes" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:742 +msgid "Relative to: " +msgstr "Relatiu a: " + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:747 +msgid "Align right sides of objects to left side of anchor" +msgstr "Alinea el costat dret dels objectes al costat esquerre de l'àncora" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:750 +msgid "Align left sides" +msgstr "Alinea els costats esquerres" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:753 +msgid "Center on vertical axis" +msgstr "Centra en l'eix vertical" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:756 +msgid "Align right sides" +msgstr "Alinea els costats drets" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:759 +msgid "Align left sides of objects to right side of anchor" +msgstr "Alinea el costat esquerre dels objectes al costat dret de l'àncora" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:762 +msgid "Align bottoms of objects to top of anchor" +msgstr "Alinea la part inferior dels objectes a la part superior de l'àncora" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:765 +msgid "Align tops" +msgstr "Alinea els superiors" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:768 +msgid "Center on horizontal axis" +msgstr "Centra a l'eix horitzontal" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:771 +msgid "Align bottoms" +msgstr "Alinea els inferiors" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:774 +msgid "Align tops of objects to bottom of anchor" +msgstr "Alinea la part superior dels objectes a la part inferior de l'àncora" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:779 +msgid "Align baseline anchors of texts vertically" +msgstr "Alinea verticalment la línia de base de les àncores" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:782 +msgid "Align baseline anchors of texts horizontally" +msgstr "Alinea horitzontalment la línia de base de les àncores" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:787 +msgid "Make horizontal gaps between objects equal" +msgstr "" +"Distribueix la distància horitzontal entre objectes de forma equitativa" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:791 +msgid "Distribute left sides equidistantly" +msgstr "Distribueix els costats esquerres dels objectes a distàncies iguals" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:794 +msgid "Distribute centers equidistantly horizontally" +msgstr "Distribueix els centres horitzontalment a distàncies iguals" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:797 +msgid "Distribute right sides equidistantly" +msgstr "Distribueix els costats drets a distàncies iguals" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:801 +msgid "Make vertical gaps between objects equal" +msgstr "Distribueix la distància vertical entre objectes de forma equitativa" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:805 +msgid "Distribute tops equidistantly" +msgstr "Distribueix els superiors a distàncies iguals" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:808 +msgid "Distribute centers equidistantly vertically" +msgstr "Distribueix els centres a distàncies iguals verticalment" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:811 +msgid "Distribute bottoms equidistantly" +msgstr "Distribueix els inferiors a distàncies iguals" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:816 +msgid "Distribute baseline anchors of texts horizontally" +msgstr "" +"Distribueix horitzontalment la línia de base de les àncores dels textos" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:819 +msgid "Distribute baseline anchors of texts vertically" +msgstr "Distribueix verticalment la línia de base de les àncores dels textos" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:824 +msgid "Randomize centers in both dimensions" +msgstr "Aleatoritza els centres en ambdues dimensions" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:827 +msgid "Unclump objects: try to equalize edge-to-edge distances" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:832 +msgid "" +"Move objects as little as possible so that their bounding boxes do not " +"overlap" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:837 +msgid "Align selected nodes horizontally" +msgstr "Alinea horitzontalment els nodes seleccionats" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:840 +msgid "Align selected nodes vertically" +msgstr "Alinea verticalment els nodes seleccionats" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:843 +msgid "Distribute selected nodes horizontally" +msgstr "Distribueix horitzontalment els nodes seleccionats" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:846 +msgid "Distribute selected nodes vertically" +msgstr "Distribueix verticalment els nodes seleccionats" + +#. Rest of the widgetry +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:851 +msgid "Last selected" +msgstr "Últim seleccionat" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:852 +msgid "First selected" +msgstr "El primer seleccionat" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:853 +msgid "Biggest item" +msgstr "L'element més gran" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:854 +msgid "Smallest item" +msgstr "L'element més petit" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:856 +#: ../../po/../src/widgets/desktop-widget.cpp:1065 +msgid "Drawing" +msgstr "Dibuix" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:91 +#, fuzzy +msgid "Metadata 1" +msgstr "Metadades" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:92 +#, fuzzy +msgid "Metadata 2" +msgstr "Metadades" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:187 +#, fuzzy +msgid "X coordinate of grid origin" +msgstr "Coordenada vertical de la selecció" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:189 +#, fuzzy +msgid "Y coordinate of grid origin" +msgstr "Coordenada vertical de la selecció" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:191 +#, fuzzy +msgid "Distance of vertical grid lines" +msgstr "línia guia vertical" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:193 +#, fuzzy +msgid "Distance of horizontal grid lines" +msgstr "línia guia horitzontal" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:197 +msgid "Max. snapping distance from grid" +msgstr "" + +#: ../../po/../src/ui/dialog/export.cpp:34 +msgid "Export" +msgstr "Exporta" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:36 +msgid "Fill" +msgstr "Farciment" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:37 +msgid "Stroke Paint" +msgstr "Pinta el contorn" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:38 +msgid "Stroke Style" +msgstr "Estil del contorn" + +#: ../../po/../src/ui/dialog/find.cpp:34 +msgid "Find" +msgstr "Cerca" + +#: ../../po/../src/ui/dialog/memory.cpp:96 +msgid "Heap" +msgstr "Memòria" + +#: ../../po/../src/ui/dialog/memory.cpp:97 +msgid "In Use" +msgstr "En ús" + +#. TRANSLATORS: "Slack" refers to memory which is in the heap but currently unused. +#. More typical usage is to call this memory "free" rather than "slack". +#: ../../po/../src/ui/dialog/memory.cpp:100 +msgid "Slack" +msgstr "Lliure" + +#: ../../po/../src/ui/dialog/memory.cpp:101 +msgid "Total" +msgstr "Total" + +#: ../../po/../src/ui/dialog/memory.cpp:141 +#: ../../po/../src/ui/dialog/memory.cpp:147 +#: ../../po/../src/ui/dialog/memory.cpp:154 +#: ../../po/../src/ui/dialog/memory.cpp:186 +msgid "Unknown" +msgstr "Desconegut" + +#: ../../po/../src/ui/dialog/memory.cpp:167 +msgid "Combined" +msgstr "Combinat" + +#: ../../po/../src/ui/dialog/memory.cpp:209 +msgid "Recalculate" +msgstr "Recalcula" + +#: ../../po/../src/ui/dialog/messages.cpp:74 +msgid "Ready." +msgstr "Llest." + +#: ../../po/../src/ui/dialog/messages.cpp:75 +msgid "" +"Enable log display by setting dialogs.debug 'redirect' attribute to 1 in " +"preferences.xml" +msgstr "" +"Permet la visualització del registre establint a 1 l'atribut 'redirect' a " +"dialogs.debug a preferences.xml" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:184 +msgid "_Execute Python" +msgstr "_Executa el Python" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:186 +msgid "_Execute Perl" +msgstr "_Executa el Perl" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:195 +msgid "Script" +msgstr "Seqüència" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:205 +msgid "Output" +msgstr "Sortida" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:215 +msgid "Errors" +msgstr "Errors" + +#. Dialog organization +#: ../../po/../src/ui/dialog/session-player.cpp:73 +msgid "Session file" +msgstr "Fitxer de sessió" + +#: ../../po/../src/ui/dialog/session-player.cpp:74 +msgid "Playback controls" +msgstr "Controls de reproducció" + +#: ../../po/../src/ui/dialog/session-player.cpp:75 +msgid "Message information" +msgstr "Informació del missatge" + +#. Active session file display +#. fixme: Does this mean the active file for the session, or the file for the active session? +#. Please indicate which with a TRANSLATORS comment. +#: ../../po/../src/ui/dialog/session-player.cpp:85 +msgid "Active session file:" +msgstr "Fitxer de sessió actiu:" + +#: ../../po/../src/ui/dialog/session-player.cpp:86 +msgid "Delay (milliseconds):" +msgstr "Retard (mil·lisegons):" + +#. Unload/load buttons +#: ../../po/../src/ui/dialog/session-player.cpp:94 +msgid "Close file" +msgstr "Tanca el fitxer" + +#: ../../po/../src/ui/dialog/session-player.cpp:95 +msgid "Open new file" +msgstr "Obre un nou fitxer" + +#: ../../po/../src/ui/dialog/session-player.cpp:96 +msgid "Set delay" +msgstr "Estableix el retard" + +#: ../../po/../src/ui/dialog/session-player.cpp:138 +msgid "Rewind" +msgstr "Rebobina" + +#: ../../po/../src/ui/dialog/session-player.cpp:139 +msgid "Go back one change" +msgstr "Vés un canvi endarrere" + +#: ../../po/../src/ui/dialog/session-player.cpp:140 +msgid "Pause" +msgstr "Pausa" + +#: ../../po/../src/ui/dialog/session-player.cpp:141 +msgid "Go forward one change" +msgstr "Vés un canvi endavant" + +#: ../../po/../src/ui/dialog/session-player.cpp:142 +msgid "Play" +msgstr "Reprodueix" + +#: ../../po/../src/ui/dialog/session-player.cpp:177 +#: ../../po/../src/verbs.cpp:1573 +msgid "Open session file" +msgstr "Obre el fitxer de sessió" + +#. ##Set up the Potrace panel +#. #### brightness #### +#. #### Multiple scanning#### +#. ----Hbox1 +#: ../../po/../src/ui/dialog/tracedialog.cpp:345 +#: ../../po/../src/ui/dialog/tracedialog.cpp:428 +msgid "Brightness" +msgstr "Brillantor" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:348 +msgid "Trace by a given brightness level" +msgstr "Vectoritza segons un nivell de brillantor" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:355 +msgid "Brightness cutoff for black/white" +msgstr "Tall de brillantor per a blanc/negre" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:362 +msgid "Image Brightness" +msgstr "Brillantor de la imatge" + +#. #### canny edge detection #### +#. TRANSLATORS: "Canny" is the name of the inventor of this edge detection method +#: ../../po/../src/ui/dialog/tracedialog.cpp:369 +msgid "Optimal Edge Detection (Canny)" +msgstr "Detecció de vores òptima (Canny)" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:372 +msgid "Trace with edge detection by J. Canny's algorithm" +msgstr "Vectoritza amb l'algorisme de detecció de vores de J. Canny" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:388 +msgid "Brightness cutoff for adjacent pixels (determines edge thickness)" +msgstr "" +"Tall de la brillantor per als píxels adjacents (determina el gruix de les " +"vores)" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:395 +msgid "Edge Detection" +msgstr "Detecció de vores" + +#. #### quantization #### +#. TRANSLATORS: Color Quantization: the process of reducing the number of colors +#. in an image by selecting an optimized set of representative colors and then +#. re-applying this reduced set to the original image. +#: ../../po/../src/ui/dialog/tracedialog.cpp:404 +msgid "Color Quantization" +msgstr "Reducció de colors" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:407 +msgid "Trace along the boundaries of reduced colors" +msgstr "Vectoritza sobre els límits dels colors reduïts" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:414 +msgid "The number of reduced colors" +msgstr "Nombre de colors reduïts" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:416 +msgid "Colors:" +msgstr "Colors:" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:421 +msgid "Quantization / Reduction" +msgstr "Reducció" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:431 +msgid "Trace the given number of brightness levels" +msgstr "Vectoritza el nombre de nivells de brillantor" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:438 +msgid "Scans:" +msgstr "Passades:" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:440 +msgid "The desired number of scans" +msgstr "El nombre de passades" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:448 +msgid "Trace the given number of reduced colors" +msgstr "Vectoritza el nombre donat de colors reduïts" + +#. ---Hbox3 +#: ../../po/../src/ui/dialog/tracedialog.cpp:454 +msgid "Monochrome" +msgstr "Monocrom" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:457 +msgid "Same as Color, but convert result to grayscale" +msgstr "" +"El mateix que 'Color', però el resultat es converteix a escala de grisos" + +#. TRANSLATORS: "Stack" is a verb here +#: ../../po/../src/ui/dialog/tracedialog.cpp:460 +msgid "Stack" +msgstr "Pila" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:463 +msgid "" +"Stack scans vertically (no gaps) or tile horizontally (usually with gaps)" +msgstr "" +"Apila verticalment les passades (sense buits) o en mosaics horitzontals " +"(normalment amb buits)" + +#. TRANSLATORS: "Smooth" is a verb here +#: ../../po/../src/ui/dialog/tracedialog.cpp:466 +msgid "Smooth" +msgstr "Suau" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:469 +msgid "Apply Gaussian blur to the bitmap before tracing" +msgstr "Aplica un difuminat gaussià al mapa de bits abans de vectoritzar" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:473 +msgid "Multiple Scanning" +msgstr "Múltiples passades" + +#. #### Preview #### +#: ../../po/../src/ui/dialog/tracedialog.cpp:479 +#: ../../po/../src/ui/dialog/tracedialog.cpp:489 +msgid "Preview" +msgstr "Previsualitza" + +#. do not expand +#: ../../po/../src/ui/dialog/tracedialog.cpp:483 +msgid "Preview the result without actual tracing" +msgstr "Previsualitza el resultat amb una vectorització real" + +#. #### swap black and white #### +#: ../../po/../src/ui/dialog/tracedialog.cpp:495 +msgid "Invert" +msgstr "Inverteix" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:499 +msgid "Invert black and white regions for single traces" +msgstr "Inverteix les regions blanques i negres per a vectoritzacions úniques" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:503 +msgid "Thanks to Peter Selinger, http://potrace.sourceforge.net" +msgstr "Gràcies a Peter Selinger, http://potrace.sourceforge.net" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:506 +msgid "Credits" +msgstr "Crèdits" + +#. done +#. TRANSLATORS: Potrace is an application for transforming bitmaps into +#. vector graphics (http://potrace.sourceforge.net/) +#: ../../po/../src/ui/dialog/tracedialog.cpp:514 +msgid "Potrace" +msgstr "Potrace" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:527 +msgid "Abort a trace in progress" +msgstr "Anul·la la vectorització en progrés" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:531 +msgid "Execute the trace" +msgstr "Executa la vectorització" + +#: ../../po/../src/ui/dialog/transformation.cpp:80 +#: ../../po/../src/ui/dialog/transformation.cpp:90 +#, fuzzy +msgid "_Horizontal" +msgstr "Horitzontal" + +#: ../../po/../src/ui/dialog/transformation.cpp:80 +msgid "Horizontal displacement (relative) or position (absolute)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:82 +#: ../../po/../src/ui/dialog/transformation.cpp:92 +#, fuzzy +msgid "_Vertical" +msgstr "Vertical" + +#: ../../po/../src/ui/dialog/transformation.cpp:82 +msgid "Vertical displacement (relative) or position (absolute)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:84 +#, fuzzy +msgid "_Width" +msgstr "A_mplada:" + +#: ../../po/../src/ui/dialog/transformation.cpp:84 +msgid "Horizontal size increment (absolute or percentage)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:86 +#, fuzzy +msgid "_Height" +msgstr "Alçada" + +#: ../../po/../src/ui/dialog/transformation.cpp:86 +msgid "Vertical size increment (absolute or percentage)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:88 +#, fuzzy +msgid "A_ngle" +msgstr "Angle:" + +#: ../../po/../src/ui/dialog/transformation.cpp:88 +#, fuzzy +msgid "Rotation angle (positive = counterclockwise)" +msgstr "Gira la selecció 90 graus en sentit antihorari" + +#: ../../po/../src/ui/dialog/transformation.cpp:90 +msgid "" +"Horizontal skew angle (positive = counterclockwise), or absolute " +"displacement, or percentage displacement" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:92 +msgid "" +"Vertical skew angle (positive = counterclockwise), or absolute displacement, " +"or percentage displacement" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:95 +#, fuzzy +msgid "Transformation matrix element A" +msgstr "Matriu de selecció" + +#: ../../po/../src/ui/dialog/transformation.cpp:96 +#, fuzzy +msgid "Transformation matrix element B" +msgstr "Matriu de selecció" + +#: ../../po/../src/ui/dialog/transformation.cpp:97 +#, fuzzy +msgid "Transformation matrix element C" +msgstr "Matriu de selecció" + +#: ../../po/../src/ui/dialog/transformation.cpp:98 +#, fuzzy +msgid "Transformation matrix element D" +msgstr "Matriu de selecció" + +#: ../../po/../src/ui/dialog/transformation.cpp:99 +#, fuzzy +msgid "Transformation matrix element E" +msgstr "Matriu de selecció" + +#: ../../po/../src/ui/dialog/transformation.cpp:100 +#, fuzzy +msgid "Transformation matrix element F" +msgstr "Matriu de selecció" + +#: ../../po/../src/ui/dialog/transformation.cpp:102 +#, fuzzy +msgid "Rela_tive move" +msgstr "Moviment relatiu" + +#: ../../po/../src/ui/dialog/transformation.cpp:102 +msgid "" +"Add the specified relative displacement to the current position; otherwise, " +"edit the current absolute position directly" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:103 +msgid "Scale proportionally" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:103 +msgid "Preserve the width/height ratio of the scaled objects" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:104 +msgid "Apply to each _object separately" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:104 +msgid "" +"Apply the scale/rotate/skew to each selected object separately; otherwise, " +"transform the selection as a whole" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:105 +#, fuzzy +msgid "Edit c_urrent matrix" +msgstr "Alça un nivell la capa actual" + +#: ../../po/../src/ui/dialog/transformation.cpp:105 +msgid "" +"Edit the current transform= matrix; otherwise, post-multiply transform= by " +"this matrix" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:115 +#, fuzzy +msgid "_Move" +msgstr "Mou" + +#: ../../po/../src/ui/dialog/transformation.cpp:118 +#, fuzzy +msgid "_Scale" +msgstr "Escala" + +#: ../../po/../src/ui/dialog/transformation.cpp:121 +#, fuzzy +msgid "_Rotate" +msgstr "Gira" + +#: ../../po/../src/ui/dialog/transformation.cpp:124 +#, fuzzy +msgid "Ske_w" +msgstr "Torça" + +#: ../../po/../src/ui/dialog/transformation.cpp:127 +msgid "Matri_x" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:141 +msgid "Reset the values on the current tab to defaults" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:148 +#, fuzzy +msgid "Apply transformation to selection" +msgstr "Aplica la transformació als objectes" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:43 +msgid "_Use SSL" +msgstr "_Usa SSL" + +#. Construct dialog interface +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:68 +msgid "_Server:" +msgstr "_Servidor:" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:69 +msgid "_Username:" +msgstr "Nom d'_usuari:" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:70 +msgid "_Password:" +msgstr "_Contrasenya:" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:71 +msgid "P_ort:" +msgstr "P_ort:" + +#. Buttons +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:99 +msgid "Connect" +msgstr "Connecta" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:126 +msgid "Establishing connection to Jabber server %1 as user %2" +msgstr "" +"S'està establint la connexió al servidor de Jabber %1 com a usuari " +"%2" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:131 +msgid "Failed to establish connection to Jabber server %1" +msgstr "No s'ha pogut establir la connexió al servidor de Jabber %1" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:136 +msgid "Authentication failed on Jabber server %1 as %2" +msgstr "" +"Ha fallat l'autenticació al servidor de Jabber %1 com a %2" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:141 +msgid "SSL initialization failed when connecting to Jabber server %1" +msgstr "" +"Ha fallat la inicialització en connectar amb el servidor de Jabber %1" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:147 +msgid "Connected to Jabber server %1 as %2" +msgstr "S'ha connectat al servidor de Jabber %1 com a %2" + +#. Construct labels +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:75 +msgid "Chatroom _name:" +msgstr "_Nom de la sala:" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:76 +msgid "Chatroom _server:" +msgstr "_Servidor de sales:" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:77 +msgid "Chatroom _password:" +msgstr "_Contrasenya de la sala" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:78 +msgid "Chatroom _handle:" +msgstr "_Gestor de la sala" + +#. Button setup and callback registration +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:97 +msgid "Connect to chatroom" +msgstr "Connecta a la sala" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:132 +msgid "Synchronizing with chatroom %1@%2 using the handle %3" +msgstr "" +"S'està sincronitzant amb la sala %1@%2 fent servir el gestor %3" + +#. Construct dialog interface +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:78 +msgid "_User's Jabber ID:" +msgstr "ID de l'_usuari de Jabber:" + +#. Buttons +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:82 +msgid "_Invite user" +msgstr "_Inviteu l'usuari" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:83 +msgid "_Cancel" +msgstr "_Cancel·la" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:94 +msgid "Buddy List" +msgstr "Llista d'amics" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:170 +msgid "Sending whiteboard invitation to %1" +msgstr "" +"S'està enviant una invitació per a una pisarra col·laborativa a %1" + +#. FIXME: strings are replaced by placeholders, NOT to be translated until the code is enabled +#. See http://sourceforge.net/mailarchive/message.php?msg_id=11746016 for details +#. File menu +#. Edit menu +#. View menu +#. Layer menu +#. Object menu +#. Path menu +#. add(Gtk::StockItem(CLEANUP, _("PLACEHOLDER, do not translate"))); (using Gtk::Stock::CLEAR) +#. Text menu +#. About menu +#. Tools toolbox +#. Select Tool controls +#. Node Tool controls +#. Calligraphy Tool controls +#. Session playback controls +#: ../../po/../src/ui/stock-items.cpp:34 ../../po/../src/ui/stock-items.cpp:35 +#: ../../po/../src/ui/stock-items.cpp:36 ../../po/../src/ui/stock-items.cpp:37 +#: ../../po/../src/ui/stock-items.cpp:38 ../../po/../src/ui/stock-items.cpp:39 +#: ../../po/../src/ui/stock-items.cpp:40 ../../po/../src/ui/stock-items.cpp:41 +#: ../../po/../src/ui/stock-items.cpp:42 ../../po/../src/ui/stock-items.cpp:43 +#: ../../po/../src/ui/stock-items.cpp:46 ../../po/../src/ui/stock-items.cpp:47 +#: ../../po/../src/ui/stock-items.cpp:48 ../../po/../src/ui/stock-items.cpp:49 +#: ../../po/../src/ui/stock-items.cpp:50 ../../po/../src/ui/stock-items.cpp:51 +#: ../../po/../src/ui/stock-items.cpp:52 ../../po/../src/ui/stock-items.cpp:53 +#: ../../po/../src/ui/stock-items.cpp:54 ../../po/../src/ui/stock-items.cpp:55 +#: ../../po/../src/ui/stock-items.cpp:56 ../../po/../src/ui/stock-items.cpp:57 +#: ../../po/../src/ui/stock-items.cpp:58 ../../po/../src/ui/stock-items.cpp:59 +#: ../../po/../src/ui/stock-items.cpp:62 ../../po/../src/ui/stock-items.cpp:63 +#: ../../po/../src/ui/stock-items.cpp:64 ../../po/../src/ui/stock-items.cpp:65 +#: ../../po/../src/ui/stock-items.cpp:66 ../../po/../src/ui/stock-items.cpp:67 +#: ../../po/../src/ui/stock-items.cpp:68 ../../po/../src/ui/stock-items.cpp:69 +#: ../../po/../src/ui/stock-items.cpp:70 ../../po/../src/ui/stock-items.cpp:71 +#: ../../po/../src/ui/stock-items.cpp:72 ../../po/../src/ui/stock-items.cpp:73 +#: ../../po/../src/ui/stock-items.cpp:74 ../../po/../src/ui/stock-items.cpp:75 +#: ../../po/../src/ui/stock-items.cpp:76 ../../po/../src/ui/stock-items.cpp:77 +#: ../../po/../src/ui/stock-items.cpp:78 ../../po/../src/ui/stock-items.cpp:79 +#: ../../po/../src/ui/stock-items.cpp:80 ../../po/../src/ui/stock-items.cpp:81 +#: ../../po/../src/ui/stock-items.cpp:82 ../../po/../src/ui/stock-items.cpp:83 +#: ../../po/../src/ui/stock-items.cpp:84 ../../po/../src/ui/stock-items.cpp:85 +#: ../../po/../src/ui/stock-items.cpp:86 ../../po/../src/ui/stock-items.cpp:87 +#: ../../po/../src/ui/stock-items.cpp:88 ../../po/../src/ui/stock-items.cpp:89 +#: ../../po/../src/ui/stock-items.cpp:92 ../../po/../src/ui/stock-items.cpp:93 +#: ../../po/../src/ui/stock-items.cpp:94 ../../po/../src/ui/stock-items.cpp:95 +#: ../../po/../src/ui/stock-items.cpp:96 ../../po/../src/ui/stock-items.cpp:97 +#: ../../po/../src/ui/stock-items.cpp:98 ../../po/../src/ui/stock-items.cpp:99 +#: ../../po/../src/ui/stock-items.cpp:100 +#: ../../po/../src/ui/stock-items.cpp:101 +#: ../../po/../src/ui/stock-items.cpp:102 +#: ../../po/../src/ui/stock-items.cpp:103 +#: ../../po/../src/ui/stock-items.cpp:104 +#: ../../po/../src/ui/stock-items.cpp:105 +#: ../../po/../src/ui/stock-items.cpp:108 +#: ../../po/../src/ui/stock-items.cpp:109 +#: ../../po/../src/ui/stock-items.cpp:110 +#: ../../po/../src/ui/stock-items.cpp:111 +#: ../../po/../src/ui/stock-items.cpp:112 +#: ../../po/../src/ui/stock-items.cpp:113 +#: ../../po/../src/ui/stock-items.cpp:114 +#: ../../po/../src/ui/stock-items.cpp:115 +#: ../../po/../src/ui/stock-items.cpp:116 +#: ../../po/../src/ui/stock-items.cpp:117 +#: ../../po/../src/ui/stock-items.cpp:118 +#: ../../po/../src/ui/stock-items.cpp:119 +#: ../../po/../src/ui/stock-items.cpp:120 +#: ../../po/../src/ui/stock-items.cpp:121 +#: ../../po/../src/ui/stock-items.cpp:122 +#: ../../po/../src/ui/stock-items.cpp:123 +#: ../../po/../src/ui/stock-items.cpp:124 +#: ../../po/../src/ui/stock-items.cpp:125 +#: ../../po/../src/ui/stock-items.cpp:126 +#: ../../po/../src/ui/stock-items.cpp:127 +#: ../../po/../src/ui/stock-items.cpp:130 +#: ../../po/../src/ui/stock-items.cpp:131 +#: ../../po/../src/ui/stock-items.cpp:132 +#: ../../po/../src/ui/stock-items.cpp:133 +#: ../../po/../src/ui/stock-items.cpp:134 +#: ../../po/../src/ui/stock-items.cpp:135 +#: ../../po/../src/ui/stock-items.cpp:136 +#: ../../po/../src/ui/stock-items.cpp:137 +#: ../../po/../src/ui/stock-items.cpp:138 +#: ../../po/../src/ui/stock-items.cpp:139 +#: ../../po/../src/ui/stock-items.cpp:140 +#: ../../po/../src/ui/stock-items.cpp:141 +#: ../../po/../src/ui/stock-items.cpp:142 +#: ../../po/../src/ui/stock-items.cpp:143 +#: ../../po/../src/ui/stock-items.cpp:144 +#: ../../po/../src/ui/stock-items.cpp:145 +#: ../../po/../src/ui/stock-items.cpp:146 +#: ../../po/../src/ui/stock-items.cpp:150 +#: ../../po/../src/ui/stock-items.cpp:151 +#: ../../po/../src/ui/stock-items.cpp:152 +#: ../../po/../src/ui/stock-items.cpp:153 +#: ../../po/../src/ui/stock-items.cpp:156 +#: ../../po/../src/ui/stock-items.cpp:157 +#: ../../po/../src/ui/stock-items.cpp:158 +#: ../../po/../src/ui/stock-items.cpp:161 +#: ../../po/../src/ui/stock-items.cpp:162 +#: ../../po/../src/ui/stock-items.cpp:163 +#: ../../po/../src/ui/stock-items.cpp:164 +#: ../../po/../src/ui/stock-items.cpp:165 +#: ../../po/../src/ui/stock-items.cpp:166 +#: ../../po/../src/ui/stock-items.cpp:167 +#: ../../po/../src/ui/stock-items.cpp:168 +#: ../../po/../src/ui/stock-items.cpp:169 +#: ../../po/../src/ui/stock-items.cpp:170 +#: ../../po/../src/ui/stock-items.cpp:171 +#: ../../po/../src/ui/stock-items.cpp:172 +#: ../../po/../src/ui/stock-items.cpp:175 +#: ../../po/../src/ui/stock-items.cpp:176 +#: ../../po/../src/ui/stock-items.cpp:177 +#: ../../po/../src/ui/stock-items.cpp:178 +#: ../../po/../src/ui/stock-items.cpp:181 +#: ../../po/../src/ui/stock-items.cpp:182 +#: ../../po/../src/ui/stock-items.cpp:183 +#: ../../po/../src/ui/stock-items.cpp:184 +#: ../../po/../src/ui/stock-items.cpp:185 +#: ../../po/../src/ui/stock-items.cpp:186 +#: ../../po/../src/ui/stock-items.cpp:187 +#: ../../po/../src/ui/stock-items.cpp:188 +#: ../../po/../src/ui/stock-items.cpp:189 +#: ../../po/../src/ui/stock-items.cpp:190 +#: ../../po/../src/ui/stock-items.cpp:191 +#: ../../po/../src/ui/stock-items.cpp:194 +#: ../../po/../src/ui/stock-items.cpp:195 +#: ../../po/../src/ui/stock-items.cpp:198 +#: ../../po/../src/ui/stock-items.cpp:199 +#: ../../po/../src/ui/stock-items.cpp:200 +#: ../../po/../src/ui/stock-items.cpp:201 +#: ../../po/../src/ui/stock-items.cpp:202 +msgid "PLACEHOLDER, do not translate" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:88 +msgid "small" +msgstr "petit" + +#: ../../po/../src/ui/widget/panel.cpp:89 +msgid "medium" +msgstr "mitjà" + +#: ../../po/../src/ui/widget/panel.cpp:90 +msgid "large" +msgstr "gran" + +#: ../../po/../src/ui/widget/panel.cpp:91 +msgid "huge" +msgstr "enorme" + +#: ../../po/../src/ui/widget/panel.cpp:106 +msgid "List" +msgstr "Llista" + +#: ../../po/../src/ui/widget/selected-style.cpp:67 +msgid "F:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:68 +msgid "S:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:69 +msgid "O:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:95 +msgid "N/A" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:98 +#: ../../po/../src/ui/widget/selected-style.cpp:712 +#, fuzzy +msgid "Nothing selected" +msgstr "No s'ha seleccionat cap degradat" + +#: ../../po/../src/ui/widget/selected-style.cpp:103 +msgid "No fill" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:103 +#, fuzzy +msgid "No stroke" +msgstr " (contorn)" + +#: ../../po/../src/ui/widget/selected-style.cpp:105 +#: ../../po/../src/widgets/paint-selector.cpp:190 +msgid "Pattern" +msgstr "Patró" + +#: ../../po/../src/ui/widget/selected-style.cpp:108 +#: ../../po/../src/widgets/paint-selector.cpp:885 +msgid "Pattern fill" +msgstr "Omple amb patró" + +#: ../../po/../src/ui/widget/selected-style.cpp:108 +#, fuzzy +msgid "Pattern stroke" +msgstr "Desplaçament de patró" + +#: ../../po/../src/ui/widget/selected-style.cpp:110 +#, fuzzy +msgid "L Gradient" +msgstr "Degradat" + +#: ../../po/../src/ui/widget/selected-style.cpp:113 +#, fuzzy +msgid "Linear gradient fill" +msgstr "Degradat lineal" + +#: ../../po/../src/ui/widget/selected-style.cpp:113 +#, fuzzy +msgid "Linear gradient stroke" +msgstr "Degradat lineal" + +#: ../../po/../src/ui/widget/selected-style.cpp:115 +#, fuzzy +msgid "R Gradient" +msgstr "Degradat" + +#: ../../po/../src/ui/widget/selected-style.cpp:118 +#, fuzzy +msgid "Radial gradient fill" +msgstr "Degradat radial" + +#: ../../po/../src/ui/widget/selected-style.cpp:118 +#, fuzzy +msgid "Radial gradient stroke" +msgstr "Degradat radial" + +#: ../../po/../src/ui/widget/selected-style.cpp:120 +#, fuzzy +msgid "Different" +msgstr "_Resta" + +#: ../../po/../src/ui/widget/selected-style.cpp:123 +#, fuzzy +msgid "Different fills" +msgstr "_Resta" + +#: ../../po/../src/ui/widget/selected-style.cpp:123 +#, fuzzy +msgid "Different strokes" +msgstr "_Resta" + +#: ../../po/../src/ui/widget/selected-style.cpp:125 +#, fuzzy +msgid "Unset" +msgstr "contreu" + +#. TRANSLATORS COMMENT: unset is a verb here +#: ../../po/../src/ui/widget/selected-style.cpp:128 +#: ../../po/../src/ui/widget/selected-style.cpp:182 +msgid "Unset fill" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:128 +#: ../../po/../src/ui/widget/selected-style.cpp:182 +#, fuzzy +msgid "Unset stroke" +msgstr " (contorn)" + +#: ../../po/../src/ui/widget/selected-style.cpp:131 +#, fuzzy +msgid "Flat color fill" +msgstr "Color" + +#: ../../po/../src/ui/widget/selected-style.cpp:131 +#, fuzzy +msgid "Flat color stroke" +msgstr "Color" + +#. TRANSLATOR COMMENT: A means "Averaged" +#: ../../po/../src/ui/widget/selected-style.cpp:134 +#, fuzzy +msgid "A" +msgstr "_A" + +#: ../../po/../src/ui/widget/selected-style.cpp:137 +#, fuzzy +msgid "Fill is averaged over selected objects" +msgstr "O exclusiva dels objectes seleccionats" + +#: ../../po/../src/ui/widget/selected-style.cpp:137 +#, fuzzy +msgid "Stroke is averaged over selected objects" +msgstr "Feu que els connectors evitin els objectes seleccionats" + +#. TRANSLATOR COMMENT: M means "Multiple" +#: ../../po/../src/ui/widget/selected-style.cpp:140 +#, fuzzy +msgid "M" +msgstr "_M" + +#: ../../po/../src/ui/widget/selected-style.cpp:143 +#, fuzzy +msgid "Multiple selected objects have the same fill" +msgstr "Alinea verticalment els nodes seleccionats" + +#: ../../po/../src/ui/widget/selected-style.cpp:143 +#, fuzzy +msgid "Multiple selected objects have the same stroke" +msgstr "Alinea verticalment els nodes seleccionats" + +#: ../../po/../src/ui/widget/selected-style.cpp:145 +#, fuzzy +msgid "Edit fill..." +msgstr "Edita..." + +#: ../../po/../src/ui/widget/selected-style.cpp:145 +#, fuzzy +msgid "Edit stroke..." +msgstr "Edita..." + +#: ../../po/../src/ui/widget/selected-style.cpp:149 +#, fuzzy +msgid "Last set color" +msgstr "Color" + +#: ../../po/../src/ui/widget/selected-style.cpp:153 +#, fuzzy +msgid "Last selected color" +msgstr "Últim seleccionat" + +#: ../../po/../src/ui/widget/selected-style.cpp:157 +#, fuzzy +msgid "White" +msgstr "Pisarra col·laborativa" + +#: ../../po/../src/ui/widget/selected-style.cpp:161 +#: ../../po/../src/widgets/sp-color-scales.cpp:461 +#: ../../po/../src/widgets/sp-color-scales.cpp:462 +msgid "Black" +msgstr "Negre" + +#: ../../po/../src/ui/widget/selected-style.cpp:165 +#, fuzzy +msgid "Copy color" +msgstr "Fase del color" + +#: ../../po/../src/ui/widget/selected-style.cpp:169 +#, fuzzy +msgid "Paste color" +msgstr "Color" + +#: ../../po/../src/ui/widget/selected-style.cpp:173 +#, fuzzy +msgid "Swap fill and stroke" +msgstr "Far_ciment i contorn" + +#: ../../po/../src/ui/widget/selected-style.cpp:177 +msgid "Make fill opaque" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:177 +msgid "Make stroke opaque" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:186 +#, fuzzy +msgid "Remove fill" +msgstr " Supri_meix " + +#: ../../po/../src/ui/widget/selected-style.cpp:186 +#, fuzzy +msgid "Remove stroke" +msgstr "Sup_rimeix l'enllaç" + +#: ../../po/../src/ui/widget/selected-style.cpp:718 +#, fuzzy +msgid "Master opacity" +msgstr "_Opacitat principal" + +#: ../../po/../src/ui/widget/selected-style.cpp:744 +msgid "0 (transparent)" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:768 +msgid "1.0 (opaque)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1046 +msgid "Moved to next layer." +msgstr "S'ha mogut a la capa següent." + +#: ../../po/../src/verbs.cpp:1048 +#, fuzzy +msgid "Cannot move past last layer." +msgstr "No es pot moure més enllà de la darrera capa." + +#: ../../po/../src/verbs.cpp:1057 +msgid "Moved to previous layer." +msgstr "S'ha mogut a la capa anterior." + +#: ../../po/../src/verbs.cpp:1059 +#, fuzzy +msgid "Cannot move past first layer." +msgstr "No es pot moure més enllà de la primera capa." + +#: ../../po/../src/verbs.cpp:1076 ../../po/../src/verbs.cpp:1150 +msgid "No current layer." +msgstr "Cap capa." + +#: ../../po/../src/verbs.cpp:1105 +#, c-format +msgid "Raised layer %s." +msgstr "S'ha alçat la capa %s." + +#: ../../po/../src/verbs.cpp:1109 +#, c-format +msgid "Lowered layer %s." +msgstr "S'ha baixat la capa %s." + +#: ../../po/../src/verbs.cpp:1118 +#, fuzzy +msgid "Cannot move layer any further." +msgstr "No es pot moure més la capa en aquesta direcció." + +#. TRANSLATORS: this means "The layer has been deleted." +#: ../../po/../src/verbs.cpp:1148 +msgid "Deleted layer." +msgstr "S'ha suprimit la capa." + +#: ../../po/../src/verbs.cpp:1544 +msgid "" +"You need to connect to a Jabber server before sharing a document with " +"another user." +msgstr "" +"Heu de connectar-vos a un servidor de Jabber abans de compartir un document " +"amb un altre usuari." + +#: ../../po/../src/verbs.cpp:1559 +msgid "" +"You need to connect to a Jabber server before sharing a document with a " +"chatroom." +msgstr "" +"Heu de connectar-vos a un servidor de Jabber abans de compartir un document " +"amb una sala." + +#: ../../po/../src/verbs.cpp:1569 +msgid "XML node tracker has not been initialized; nothing to dump" +msgstr "" +"Encara no s'ha inicialitzat el seguidor de nanse. No es pot bolcar res." + +#. TRANSLATORS: If you have translated the keys.svg file to your language, then +#. translate this string as "keys.LANG.svg" (where LANG is your language code); +#. otherwise leave as "keys.svg". +#: ../../po/../src/verbs.cpp:1631 +msgid "keys.svg" +msgstr "keys.svg" + +#. TRANSLATORS: If you have translated the tutorial-basic.svg file to your language, +#. then translate this string as "tutorial-basic.LANG.svg" (where LANG is your language +#. code); otherwise leave as "tutorial-basic.svg". +#: ../../po/../src/verbs.cpp:1667 +msgid "tutorial-basic.svg" +msgstr "tutorial-basic.ca.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1671 +msgid "tutorial-shapes.svg" +msgstr "tutorial-shapes.ca.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1675 +msgid "tutorial-advanced.svg" +msgstr "tutorial-advanced.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1679 +msgid "tutorial-tracing.svg" +msgstr "tutorial-tracing.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1683 +msgid "tutorial-calligraphy.svg" +msgstr "tutorial-calligraphy.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1687 +msgid "tutorial-elements.svg" +msgstr "tutorial-elements.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1691 +msgid "tutorial-tips.svg" +msgstr "tutorial-tips.svg" + +#: ../../po/../src/verbs.cpp:1842 +msgid "Does nothing" +msgstr "No fa res" + +#. File +#: ../../po/../src/verbs.cpp:1845 +msgid "Default" +msgstr "Predeterminat" + +#: ../../po/../src/verbs.cpp:1845 +msgid "Create new document from default template" +msgstr "Crea un nou document a partir d'una plantilla predeterminada" + +#: ../../po/../src/verbs.cpp:1847 +msgid "_Open..." +msgstr "_Obre..." + +#: ../../po/../src/verbs.cpp:1848 +msgid "Open existing document" +msgstr "Obre un document existent" + +#: ../../po/../src/verbs.cpp:1849 +msgid "Re_vert" +msgstr "Recu_pera" + +#: ../../po/../src/verbs.cpp:1850 +msgid "Revert to the last saved version of document (changes will be lost)" +msgstr "Recupera la darrera versió desada del document (es perdran els canvis)" + +#: ../../po/../src/verbs.cpp:1851 +msgid "_Save" +msgstr "De_sa" + +#: ../../po/../src/verbs.cpp:1851 +msgid "Save document" +msgstr "Desa el document" + +#: ../../po/../src/verbs.cpp:1853 +msgid "Save _As..." +msgstr "_Anomena i desa..." + +#: ../../po/../src/verbs.cpp:1854 +msgid "Save document under new name" +msgstr "Desa el document amb un nom nou" + +#: ../../po/../src/verbs.cpp:1855 +msgid "_Print..." +msgstr "Im_primeix..." + +#: ../../po/../src/verbs.cpp:1855 +msgid "Print document" +msgstr "Imprimeix document" + +#. TRANSLATORS: "Vacuum Defs" means "Clean up defs" (so as to remove unused definitions) +#: ../../po/../src/verbs.cpp:1858 +msgid "Vac_uum Defs" +msgstr "Nete_ja definicions" + +#: ../../po/../src/verbs.cpp:1858 +#, fuzzy +msgid "Remove unused predefined items from the <defs> of the document" +msgstr "Suprimeix elements sense usar de la secció <defs> del document" + +#: ../../po/../src/verbs.cpp:1860 +msgid "Print _Direct" +msgstr "Impressió _directa" + +#: ../../po/../src/verbs.cpp:1861 +#, fuzzy +msgid "Print directly without prompting to a file or pipe" +msgstr "Imprimeix directament a un fitxer o un conducte" + +#: ../../po/../src/verbs.cpp:1862 +msgid "Print Previe_w" +msgstr "Pre_visualització d'impressió" + +#: ../../po/../src/verbs.cpp:1863 +msgid "Preview document printout" +msgstr "Previsualitza la sortida de la impressió" + +#: ../../po/../src/verbs.cpp:1864 +msgid "_Import..." +msgstr "_Importa..." + +#: ../../po/../src/verbs.cpp:1865 +msgid "Import bitmap or SVG image into document" +msgstr "Importa una imatge de mapa de bits o un SVG en el document" + +#: ../../po/../src/verbs.cpp:1866 +msgid "_Export Bitmap..." +msgstr "_Exporta a mapa de bits..." + +#: ../../po/../src/verbs.cpp:1867 +#, fuzzy +msgid "Export document or selection as a bitmap image" +msgstr "Exporta el document o la selecció com a mapa de bits PNG" + +#: ../../po/../src/verbs.cpp:1868 +msgid "N_ext Window" +msgstr "S_egüent finestra" + +#: ../../po/../src/verbs.cpp:1869 +msgid "Switch to the next document window" +msgstr "Commuta a la finestra del document següent" + +#: ../../po/../src/verbs.cpp:1870 +msgid "P_revious Window" +msgstr "Anterior finest_ra" + +#: ../../po/../src/verbs.cpp:1871 +msgid "Switch to the previous document window" +msgstr "Commuta a la finestra del document anterior" + +#: ../../po/../src/verbs.cpp:1872 +msgid "_Close" +msgstr "Tan_ca" + +#: ../../po/../src/verbs.cpp:1873 +msgid "Close window" +msgstr "Tanca la finestra" + +#: ../../po/../src/verbs.cpp:1874 +msgid "_Quit" +msgstr "_Surt" + +#: ../../po/../src/verbs.cpp:1874 +msgid "Quit Inkscape" +msgstr "Surt de l'Inkscape" + +#. Edit +#: ../../po/../src/verbs.cpp:1877 +msgid "_Undo" +msgstr "_Desfés" + +#: ../../po/../src/verbs.cpp:1877 +msgid "Undo last action" +msgstr "Desfés l'ultima acció" + +#: ../../po/../src/verbs.cpp:1879 +msgid "_Redo" +msgstr "To_rna a fer" + +#: ../../po/../src/verbs.cpp:1880 +msgid "Do again last undone action" +msgstr "Torna a fer la darrera acció desfeta" + +#: ../../po/../src/verbs.cpp:1881 +msgid "Cu_t" +msgstr "Re_talla" + +#: ../../po/../src/verbs.cpp:1882 +msgid "Cut selection to clipboard" +msgstr "Retalla la selecció al porta-retalls" + +#: ../../po/../src/verbs.cpp:1883 +msgid "_Copy" +msgstr "_Copia" + +#: ../../po/../src/verbs.cpp:1884 +msgid "Copy selection to clipboard" +msgstr "Copia la selecció al porta-retalls" + +#: ../../po/../src/verbs.cpp:1885 +msgid "_Paste" +msgstr "_Enganxa" + +#: ../../po/../src/verbs.cpp:1886 +#, fuzzy +msgid "Paste objects from clipboard to mouse point" +msgstr "Enganxa els objectes del porta-retalls on sigui el ratolí" + +#: ../../po/../src/verbs.cpp:1887 +msgid "Paste _Style" +msgstr "Enganxa l'e_stil" + +#: ../../po/../src/verbs.cpp:1888 +msgid "Apply style of the copied object to selection" +msgstr "Aplica l'estil de l'objecte copiat a la selecció" + +#: ../../po/../src/verbs.cpp:1889 +msgid "Paste _In Place" +msgstr "En_ganxa en el lloc" + +#: ../../po/../src/verbs.cpp:1890 +#, fuzzy +msgid "Paste objects from clipboard to the original location" +msgstr "Enganxa els objectes del porta-retalls a la ubicació original" + +#: ../../po/../src/verbs.cpp:1891 +msgid "_Delete" +msgstr "_Suprimeix" + +#: ../../po/../src/verbs.cpp:1892 +msgid "Delete selection" +msgstr "Suprimeix la selecció" + +#: ../../po/../src/verbs.cpp:1893 +msgid "Duplic_ate" +msgstr "Duplic_a" + +#: ../../po/../src/verbs.cpp:1894 +#, fuzzy +msgid "Duplicate selected objects" +msgstr "Duplica els objectes seleccionats" + +#: ../../po/../src/verbs.cpp:1895 +msgid "Clo_ne" +msgstr "Clo_na" + +#: ../../po/../src/verbs.cpp:1896 +msgid "Create a clone of selected object (a copy linked to the original)" +msgstr "" +"Crea un clon de l'objecte seleccionat (una còpia enllaçada amb l'original)" + +#: ../../po/../src/verbs.cpp:1897 +msgid "Unlin_k Clone" +msgstr "Desen_llaça el clon" + +#: ../../po/../src/verbs.cpp:1898 +msgid "Cut the clone's link to its original" +msgstr "Retalla l'enllaç del clon a l'original" + +#: ../../po/../src/verbs.cpp:1899 +msgid "Select _Original" +msgstr "Selecci_ona l'original" + +#: ../../po/../src/verbs.cpp:1900 +msgid "Select the object to which the clone is linked" +msgstr "Selecciona l'objecte amb què s'ha enllaçat aquest clon" + +#. TRANSLATORS: Convert selection to a rectangle with tiled pattern fill +#: ../../po/../src/verbs.cpp:1902 +#, fuzzy +msgid "O_bjects to Pattern" +msgstr "Ob_jectes a patró" + +#: ../../po/../src/verbs.cpp:1903 +msgid "Convert selection to a rectangle with tiled pattern fill" +msgstr "" +"Converteix la selecció en un rectangle amb un farciment de patró de mosaic" + +#. TRANSLATORS: Extract objects from a tiled pattern fill +#: ../../po/../src/verbs.cpp:1905 +#, fuzzy +msgid "Pattern to Ob_jects" +msgstr "Patró a ob_jectes" + +#: ../../po/../src/verbs.cpp:1906 +msgid "Extract objects from a tiled pattern fill" +msgstr "Extreu objectes d'un farciment de patró de mosaic" + +#: ../../po/../src/verbs.cpp:1907 +msgid "Clea_r All" +msgstr "Ne_teja-ho tot" + +#: ../../po/../src/verbs.cpp:1908 +msgid "Delete all objects from document" +msgstr "Suprimeix tots els objectes del document" + +#: ../../po/../src/verbs.cpp:1909 +msgid "Select Al_l" +msgstr "Se_lecciona-ho tot" + +#: ../../po/../src/verbs.cpp:1910 +msgid "Select all objects or all nodes" +msgstr "Selecciona tots els objectes o els nodes" + +#: ../../po/../src/verbs.cpp:1911 +msgid "Select All in All La_yers" +msgstr "Selecciona-_ho tot en totes les capes" + +#: ../../po/../src/verbs.cpp:1912 +msgid "Select all objects in all visible and unlocked layers" +msgstr "Selecciona tots els objectes en totes les capes visibles i no blocades" + +#: ../../po/../src/verbs.cpp:1913 +msgid "In_vert Selection" +msgstr "In_verteix selecció" + +#: ../../po/../src/verbs.cpp:1914 +msgid "Invert selection (unselect what is selected and select everything else)" +msgstr "Selecciona tot allò que ara no està seleccionat" + +#: ../../po/../src/verbs.cpp:1915 +msgid "Invert in All Layers" +msgstr "Inverteix totes les capes" + +#: ../../po/../src/verbs.cpp:1916 +msgid "Invert selection in all visible and unlocked layers" +msgstr "Inverteix la selecció en totes les capes visibles i no blocades" + +#: ../../po/../src/verbs.cpp:1917 +msgid "D_eselect" +msgstr "D_esfés la selecció" + +#: ../../po/../src/verbs.cpp:1918 +msgid "Deselect any selected objects or nodes" +msgstr "Desfés la selecció dels objectes o els nodes" + +#. Selection +#: ../../po/../src/verbs.cpp:1921 +msgid "Raise to _Top" +msgstr "Alçat a dal_t" + +#: ../../po/../src/verbs.cpp:1922 +msgid "Raise selection to top" +msgstr "Alça la selecció a dalt" + +#: ../../po/../src/verbs.cpp:1923 +msgid "Lower to _Bottom" +msgstr "_Baixa a baix" + +#: ../../po/../src/verbs.cpp:1924 +msgid "Lower selection to bottom" +msgstr "Baixa la selecció a baix de tot" + +#: ../../po/../src/verbs.cpp:1925 +msgid "_Raise" +msgstr "A_lça" + +#: ../../po/../src/verbs.cpp:1926 +msgid "Raise selection one step" +msgstr "Alça la selecció una posició" + +#: ../../po/../src/verbs.cpp:1927 +msgid "_Lower" +msgstr "Bai_xa" + +#: ../../po/../src/verbs.cpp:1928 +msgid "Lower selection one step" +msgstr "Baixa la selecció una posició" + +#: ../../po/../src/verbs.cpp:1929 +msgid "_Group" +msgstr "A_grupa" + +#: ../../po/../src/verbs.cpp:1930 +msgid "Group selected objects" +msgstr "Agrupa els objectes seleccionats" + +#: ../../po/../src/verbs.cpp:1932 +#, fuzzy +msgid "Ungroup selected groups" +msgstr "Desagrupa els grups seleccionats" + +#: ../../po/../src/verbs.cpp:1934 +msgid "_Put on Path" +msgstr "_Posa en el camí" + +#: ../../po/../src/verbs.cpp:1935 +msgid "Put text on path" +msgstr "Posa el text en el camí" + +#: ../../po/../src/verbs.cpp:1936 +msgid "_Remove from Path" +msgstr "Sup_rimeix del camí" + +#: ../../po/../src/verbs.cpp:1937 +msgid "Remove text from path" +msgstr "Suprimeix el text del camí" + +#: ../../po/../src/verbs.cpp:1938 +msgid "Remove Manual _Kerns" +msgstr "" + +#. TRANSLATORS: "glyph": An image used in the visual representation of characters; +#. roughly speaking, how a character looks. A font is a set of glyphs. +#: ../../po/../src/verbs.cpp:1941 +msgid "Remove all manual kerns and glyph rotations from a text object" +msgstr "" + +#: ../../po/../src/verbs.cpp:1943 +msgid "_Union" +msgstr "_Unió" + +#: ../../po/../src/verbs.cpp:1944 +msgid "Union of selected objects" +msgstr "Unió dels objectes seleccionats" + +#: ../../po/../src/verbs.cpp:1945 +msgid "_Intersection" +msgstr "_Intersecció" + +#: ../../po/../src/verbs.cpp:1946 +msgid "Intersection of selected objects" +msgstr "Creua els objectes seleccionats" + +#: ../../po/../src/verbs.cpp:1947 +msgid "_Difference" +msgstr "_Resta" + +#: ../../po/../src/verbs.cpp:1948 +msgid "Difference of selected objects (bottom minus top)" +msgstr "Resta dels objectes seleccionats (inferior menys superior)" + +#: ../../po/../src/verbs.cpp:1949 +msgid "E_xclusion" +msgstr "E_xclusió" + +#: ../../po/../src/verbs.cpp:1950 +msgid "Exclusive OR of selected objects" +msgstr "O exclusiva dels objectes seleccionats" + +#: ../../po/../src/verbs.cpp:1951 +msgid "Di_vision" +msgstr "Di_visió" + +#: ../../po/../src/verbs.cpp:1952 +msgid "Cut the bottom object into pieces" +msgstr "Retalla l'objecte inferior en pedaços" + +#. TRANSLATORS: "to cut a path" is not the same as "to break a path apart" - see the +#. Advanced tutorial for more info +#: ../../po/../src/verbs.cpp:1955 +msgid "Cut _Path" +msgstr "Re_talla el camí" + +#: ../../po/../src/verbs.cpp:1956 +msgid "Cut the bottom object's stroke into pieces, removing fill" +msgstr "" +"Retalla el contorn de l'objecte inferior en pedaços i suprimeix el farciment" + +#. TRANSLATORS: "outset": expand a shape by offsetting the object's path, +#. i.e. by displacing it perpendicular to the path in each point. +#. See also the Advanced Tutorial for explanation. +#: ../../po/../src/verbs.cpp:1960 +msgid "Outs_et" +msgstr "_Expandeix" + +#: ../../po/../src/verbs.cpp:1961 +#, fuzzy +msgid "Outset selected paths" +msgstr "Expandeix els camins seleccionat" + +#: ../../po/../src/verbs.cpp:1963 +msgid "O_utset Path by 1 px" +msgstr "Ex_pandeix el camí 1px" + +#: ../../po/../src/verbs.cpp:1964 +#, fuzzy +msgid "Outset selected paths by 1 px" +msgstr "Expandeix els camins seleccionats 1 px" + +#: ../../po/../src/verbs.cpp:1966 +msgid "O_utset Path by 10 px" +msgstr "Expa_ndeix el camí 10 px" + +#: ../../po/../src/verbs.cpp:1967 +#, fuzzy +msgid "Outset selected paths by 10 px" +msgstr "Expandeix els camins seleccionats 10 px" + +#. TRANSLATORS: "inset": contract a shape by offsetting the object's path, +#. i.e. by displacing it perpendicular to the path in each point. +#. See also the Advanced Tutorial for explanation. +#: ../../po/../src/verbs.cpp:1971 +msgid "I_nset" +msgstr "Co_ntreu" + +#: ../../po/../src/verbs.cpp:1972 +#, fuzzy +msgid "Inset selected paths" +msgstr "Contreu els camins seleccionats" + +#: ../../po/../src/verbs.cpp:1974 +msgid "I_nset Path by 1 px" +msgstr "Co_ntreu el camí 1 px" + +#: ../../po/../src/verbs.cpp:1975 +#, fuzzy +msgid "Inset selected paths by 1 px" +msgstr "Contreu els camins seleccionats 1px" + +#: ../../po/../src/verbs.cpp:1977 +msgid "I_nset Path by 10 px" +msgstr "Co_ntreu el camí 10 px" + +#: ../../po/../src/verbs.cpp:1978 +#, fuzzy +msgid "Inset selected paths by 10 px" +msgstr "Contreu els camins seleccionats 10 px" + +#: ../../po/../src/verbs.cpp:1980 +msgid "D_ynamic Offset" +msgstr "Desplaçament d_inàmic" + +#: ../../po/../src/verbs.cpp:1980 +msgid "Create a dynamic offset object" +msgstr "Crea un objecte de desplaçament dinàmic" + +#: ../../po/../src/verbs.cpp:1982 +msgid "_Linked Offset" +msgstr "Desp_laçament enllaçat" + +#: ../../po/../src/verbs.cpp:1983 +msgid "Create a dynamic offset object linked to the original path" +msgstr "Crea un objecte de desplaçament dinàmic enllaçat al camí original" + +#: ../../po/../src/verbs.cpp:1985 +msgid "_Stroke to Path" +msgstr "_Contorn a camí" + +#: ../../po/../src/verbs.cpp:1986 +#, fuzzy +msgid "Convert selected strokes to paths" +msgstr "Converteix els contorns seleccionats en camins" + +#: ../../po/../src/verbs.cpp:1987 +msgid "Si_mplify" +msgstr "Si_mplifica" + +#: ../../po/../src/verbs.cpp:1988 +#, fuzzy +msgid "Simplify selected paths by removing extra nodes" +msgstr "Simplifica els camins seleccionats suprimint nodes addicionals" + +#: ../../po/../src/verbs.cpp:1989 +msgid "_Reverse" +msgstr "A l'in_revés" + +#: ../../po/../src/verbs.cpp:1990 +#, fuzzy +msgid "Reverses the direction of selected paths; useful for flipping markers" +msgstr "Inverteix la direcció dels camins seleccionats" + +#. TRANSLATORS: "to trace" means "to convert a bitmap to vector graphics" (to vectorize) +#: ../../po/../src/verbs.cpp:1992 +msgid "_Trace Bitmap" +msgstr "_Vectoritza un mapa de bits" + +#: ../../po/../src/verbs.cpp:1993 +msgid "Convert bitmap object to paths" +msgstr "Converteix el text en camí" + +#: ../../po/../src/verbs.cpp:1994 +msgid "_Make a Bitmap Copy" +msgstr "Fes una còpia de _mapa de bits" + +#: ../../po/../src/verbs.cpp:1995 +msgid "Export selection to a bitmap and insert it into document" +msgstr "Exporta la selecció a un mapa de bits i insereix-lo en el document" + +#: ../../po/../src/verbs.cpp:1996 +msgid "_Combine" +msgstr "_Combina" + +#: ../../po/../src/verbs.cpp:1997 +msgid "Combine several paths into one" +msgstr "Combina múltiples camins en un de sol" + +#. TRANSLATORS: "to cut a path" is not the same as "to break a path apart" - see the +#. Advanced tutorial for more info +#: ../../po/../src/verbs.cpp:2000 +msgid "Break _Apart" +msgstr "Sep_ara" + +#: ../../po/../src/verbs.cpp:2001 +#, fuzzy +msgid "Break selected paths into subpaths" +msgstr "Separa els camins seleccionats en subcamins" + +#: ../../po/../src/verbs.cpp:2002 +msgid "Gri_d Arrange..." +msgstr "Or_denació en graella..." + +#: ../../po/../src/verbs.cpp:2003 +msgid "Arrange selection in grid pattern" +msgstr "Ordena la selecció en patró de graella" + +#. Layer +#: ../../po/../src/verbs.cpp:2005 +msgid "_Add Layer..." +msgstr "_Afegeix capa..." + +#: ../../po/../src/verbs.cpp:2006 +msgid "Create a new layer" +msgstr "Crea una nova capa" + +#: ../../po/../src/verbs.cpp:2007 +msgid "Re_name Layer..." +msgstr "Rea_nomena la capa..." + +#: ../../po/../src/verbs.cpp:2008 +msgid "Rename the current layer" +msgstr "Reanomena la capa actual" + +#: ../../po/../src/verbs.cpp:2009 +msgid "Switch to Layer Abov_e" +msgstr "Commuta a la capa per so_bre" + +#: ../../po/../src/verbs.cpp:2010 +msgid "Switch to the layer above the current" +msgstr "Commuta a la capa per sobre de l'actual" + +#: ../../po/../src/verbs.cpp:2011 +msgid "Switch to Layer Belo_w" +msgstr "Commuta a la capa per so_ta" + +#: ../../po/../src/verbs.cpp:2012 +msgid "Switch to the layer below the current" +msgstr "Commuta a la capa per sota de l'actual" + +#: ../../po/../src/verbs.cpp:2013 +msgid "Move Selection to Layer Abo_ve" +msgstr "Mou la selecció a la capa de so_bre" + +#: ../../po/../src/verbs.cpp:2014 +msgid "Move selection to the layer above the current" +msgstr "Mou la selecció a la capa de sobre de l'actual" + +#: ../../po/../src/verbs.cpp:2015 +msgid "Move Selection to Layer Bel_ow" +msgstr "Mou la selecció a la capa de s_ota" + +#: ../../po/../src/verbs.cpp:2016 +msgid "Move selection to the layer below the current" +msgstr "Mou la selecció a la capa de sota de l'actual" + +#: ../../po/../src/verbs.cpp:2017 +msgid "Layer to _Top" +msgstr "a_lça la capa a dalt" + +#: ../../po/../src/verbs.cpp:2018 +msgid "Raise the current layer to the top" +msgstr "Alça la capa a dalt de tot" + +#: ../../po/../src/verbs.cpp:2019 +msgid "Layer to _Bottom" +msgstr "_Baixa la capa a sota" + +#: ../../po/../src/verbs.cpp:2020 +msgid "Lower the current layer to the bottom" +msgstr "Baixa la capa actual a sota de tot" + +#: ../../po/../src/verbs.cpp:2021 +msgid "_Raise Layer" +msgstr "Alça la _capa" + +#: ../../po/../src/verbs.cpp:2022 +msgid "Raise the current layer" +msgstr "Alça un nivell la capa actual" + +#: ../../po/../src/verbs.cpp:2023 +msgid "_Lower Layer" +msgstr "Baixa _la capa" + +#: ../../po/../src/verbs.cpp:2024 +msgid "Lower the current layer" +msgstr "Baixa un nivell la capa actual" + +#: ../../po/../src/verbs.cpp:2025 +msgid "_Delete Current Layer" +msgstr "_Suprimeix la capa" + +#: ../../po/../src/verbs.cpp:2026 +msgid "Delete the current layer" +msgstr "Suprimeix la capa actual" + +#. Object +#: ../../po/../src/verbs.cpp:2029 +#, fuzzy +msgid "Rotate _90° CW" +msgstr "Gira _90º sentit horari" + +#: ../../po/../src/verbs.cpp:2030 +#, fuzzy +msgid "Rotate selection 90° clockwise" +msgstr "Gira la selecció 90 graus en sentit horari" + +#: ../../po/../src/verbs.cpp:2031 +#, fuzzy +msgid "Rotate 9_0° CCW" +msgstr "Gira 9_0º sentit antihorari" + +#: ../../po/../src/verbs.cpp:2032 +#, fuzzy +msgid "Rotate selection 90° counter-clockwise" +msgstr "Gira la selecció 90 graus en sentit antihorari" + +#: ../../po/../src/verbs.cpp:2033 +msgid "Remove _Transformations" +msgstr "Suprimeix les _transformacions" + +#: ../../po/../src/verbs.cpp:2034 +msgid "Remove transformations from object" +msgstr "Suprimeix les transformacions de l'objecte" + +#: ../../po/../src/verbs.cpp:2035 +msgid "_Object to Path" +msgstr "_Objecte a camí" + +#: ../../po/../src/verbs.cpp:2036 +#, fuzzy +msgid "Convert selected objects to paths" +msgstr "Converteix els objectes seleccionats en camins" + +#: ../../po/../src/verbs.cpp:2037 +msgid "_Flow into Frame" +msgstr "_Flota en el marc" + +#: ../../po/../src/verbs.cpp:2038 +#, fuzzy +msgid "Put text into frames" +msgstr "Posa text en marcs" + +#: ../../po/../src/verbs.cpp:2039 +msgid "_Unflow" +msgstr "N_o ho flotis" + +#: ../../po/../src/verbs.cpp:2040 +msgid "Remove text from frame (creates a single-line text object)" +msgstr "Suprimeix el text del marc (crea un objecte de text d'una línia)" + +#: ../../po/../src/verbs.cpp:2041 +msgid "_Convert to Text" +msgstr "_Converteix a text" + +#: ../../po/../src/verbs.cpp:2042 +#, fuzzy +msgid "Convert flowed text to regular text objects (preserves appearance)" +msgstr "" +"Converteix els texts flotats en objectes normals (conserva'n l'aparença)" + +#: ../../po/../src/verbs.cpp:2044 +#, fuzzy +msgid "Flip _Horizontal" +msgstr "Volteja _horitzontalment" + +#: ../../po/../src/verbs.cpp:2044 +#, fuzzy +msgid "Flips selected objects horizontally" +msgstr "Alinea horitzontalment els nodes seleccionats" + +#: ../../po/../src/verbs.cpp:2047 +#, fuzzy +msgid "Flip _Vertical" +msgstr "_Volteja verticalment" + +#: ../../po/../src/verbs.cpp:2047 +#, fuzzy +msgid "Flips selected objects vertically" +msgstr "Alinea verticalment els nodes seleccionats" + +#. Tools +#: ../../po/../src/verbs.cpp:2051 +msgid "Select" +msgstr "Selecciona" + +#: ../../po/../src/verbs.cpp:2052 +msgid "Select and transform objects" +msgstr "Selecciona i transforma els objectes" + +#: ../../po/../src/verbs.cpp:2053 +msgid "Node Edit" +msgstr "Edició de node" + +#: ../../po/../src/verbs.cpp:2054 +msgid "Edit path nodes or control handles" +msgstr "Edita nodes del camí o manejadors de control" + +#: ../../po/../src/verbs.cpp:2056 +msgid "Create rectangles and squares" +msgstr "Crea rectangles i quadrats" + +#: ../../po/../src/verbs.cpp:2058 +msgid "Create circles, ellipses, and arcs" +msgstr "Crea cercles, el·lipses i arcs" + +#: ../../po/../src/verbs.cpp:2060 +msgid "Create stars and polygons" +msgstr "Crea estels i polígons" + +#: ../../po/../src/verbs.cpp:2062 +msgid "Create spirals" +msgstr "Crea espirals" + +#: ../../po/../src/verbs.cpp:2064 +msgid "Draw freehand lines" +msgstr "Dibuixa línies a mà alçada" + +#: ../../po/../src/verbs.cpp:2066 +msgid "Draw Bezier curves and straight lines" +msgstr "Dibuixa corbes Bezier i línies rectes" + +#: ../../po/../src/verbs.cpp:2068 +msgid "Draw calligraphic lines" +msgstr "Dibuixa línies de cal·ligrafia" + +#: ../../po/../src/verbs.cpp:2070 +msgid "Create and edit text objects" +msgstr "Crea i edita objectes de text" + +#: ../../po/../src/verbs.cpp:2072 +msgid "Create and edit gradients" +msgstr "Crea i edita els degradats" + +#: ../../po/../src/verbs.cpp:2074 +msgid "Zoom in or out" +msgstr "Apropa o allunya" + +#: ../../po/../src/verbs.cpp:2076 +msgid "Pick averaged colors from image" +msgstr "Agafa els colors mesclats de la imatge" + +#: ../../po/../src/verbs.cpp:2078 +msgid "Create connectors" +msgstr "Crea connectors" + +#. Tool prefs +#: ../../po/../src/verbs.cpp:2081 +msgid "Selector Preferences" +msgstr "Preferències del selector" + +#: ../../po/../src/verbs.cpp:2082 +#, fuzzy +msgid "Open Preferences for the Selector tool" +msgstr "Obre les preferències de l'Inkscape per a l'eina de selecció" + +#: ../../po/../src/verbs.cpp:2083 +msgid "Node Tool Preferences" +msgstr "Preferències de l'eina de nodes" + +#: ../../po/../src/verbs.cpp:2084 +#, fuzzy +msgid "Open Preferences for the Node tool" +msgstr "Obre les preferències de l'Inkscape per a l'eina de nodes" + +#: ../../po/../src/verbs.cpp:2085 +msgid "Rectangle Preferences" +msgstr "Preferències del rectangle" + +#: ../../po/../src/verbs.cpp:2086 +#, fuzzy +msgid "Open Preferences for the Rectangle tool" +msgstr "Obre les preferències de l'Inkscape per a l'eina de rectangle" + +#: ../../po/../src/verbs.cpp:2087 +msgid "Ellipse Preferences" +msgstr "Preferències de l'el·lipse" + +#: ../../po/../src/verbs.cpp:2088 +#, fuzzy +msgid "Open Preferences for the Ellipse tool" +msgstr "Obre les preferències de l'Inkscape per a l'eina d'el·lipse" + +#: ../../po/../src/verbs.cpp:2089 +msgid "Star Preferences" +msgstr "Preferències de l'estel" + +#: ../../po/../src/verbs.cpp:2090 +#, fuzzy +msgid "Open Preferences for the Star tool" +msgstr "Obre les preferències de l'Inkscape per a l'eina d'estel" + +#: ../../po/../src/verbs.cpp:2091 +msgid "Spiral Preferences" +msgstr "Preferències de l'espiral" + +#: ../../po/../src/verbs.cpp:2092 +#, fuzzy +msgid "Open Preferences for the Spiral tool" +msgstr "Obre les preferències de l'Inkscape per a l'eina d'espiral" + +#: ../../po/../src/verbs.cpp:2093 +msgid "Pencil Preferences" +msgstr "Preferències del llapis" + +#: ../../po/../src/verbs.cpp:2094 +#, fuzzy +msgid "Open Preferences for the Pencil tool" +msgstr "Obre les preferències de l'Inkscape per a l'eina del llapis" + +#: ../../po/../src/verbs.cpp:2095 +msgid "Pen Preferences" +msgstr "Preferències del rotulador" + +#: ../../po/../src/verbs.cpp:2096 +#, fuzzy +msgid "Open Preferences for the Pen tool" +msgstr "Obre les preferències de l'Inkscape per a l'eina de la ploma" + +#: ../../po/../src/verbs.cpp:2097 +msgid "Calligraphic Preferences" +msgstr "Preferències cal·ligràfiques" + +#: ../../po/../src/verbs.cpp:2098 +#, fuzzy +msgid "Open Preferences for the Calligraphy tool" +msgstr "Obre les preferències de l'Inkscape per a l'eina de cal·ligrafia" + +#: ../../po/../src/verbs.cpp:2099 +msgid "Text Preferences" +msgstr "Preferències de text" + +#: ../../po/../src/verbs.cpp:2100 +#, fuzzy +msgid "Open Preferences for the Text tool" +msgstr "Obre les preferències de l'Inkscape per a l'eina de text" + +#: ../../po/../src/verbs.cpp:2101 +msgid "Gradient Preferences" +msgstr "Preferències del degradat" + +#: ../../po/../src/verbs.cpp:2102 +#, fuzzy +msgid "Open Preferences for the Gradient tool" +msgstr "Obre les preferències de l'Inkscape per a l'eina del degradat" + +#: ../../po/../src/verbs.cpp:2103 +msgid "Zoom Preferences" +msgstr "Preferències de l'ampliació" + +#: ../../po/../src/verbs.cpp:2104 +#, fuzzy +msgid "Open Preferences for the Zoom tool" +msgstr "Obre les preferències de l'Inkscape per a l'eina d'ampliació" + +#: ../../po/../src/verbs.cpp:2105 +msgid "Dropper Preferences" +msgstr "Preferències del comptagotes" + +#: ../../po/../src/verbs.cpp:2106 +#, fuzzy +msgid "Open Preferences for the Dropper tool" +msgstr "Obre les preferències de l'Inkscape per a l'eina comptagotes" + +#: ../../po/../src/verbs.cpp:2107 +msgid "Connector Preferences" +msgstr "Preferències del connector" + +#: ../../po/../src/verbs.cpp:2108 +#, fuzzy +msgid "Open Preferences for the Connector tool" +msgstr "Obre les preferències de l'Inkscape per a l'eina del connector" + +#. Zoom/View +#: ../../po/../src/verbs.cpp:2111 +msgid "Zoom In" +msgstr "Apropa" + +#: ../../po/../src/verbs.cpp:2111 +msgid "Zoom in" +msgstr "Apropa" + +#: ../../po/../src/verbs.cpp:2112 +msgid "Zoom Out" +msgstr "Allunya" + +#: ../../po/../src/verbs.cpp:2112 +msgid "Zoom out" +msgstr "Allunya" + +#: ../../po/../src/verbs.cpp:2113 +msgid "_Rulers" +msgstr "_Regles" + +#: ../../po/../src/verbs.cpp:2113 +msgid "Show or hide the canvas rulers" +msgstr "Mostra o oculta els regles del llenç" + +#: ../../po/../src/verbs.cpp:2114 +msgid "Scroll_bars" +msgstr "_Barres de desplaçament" + +#: ../../po/../src/verbs.cpp:2114 +msgid "Show or hide the canvas scrollbars" +msgstr "Mostra o oculta les barres de desplaçament del llenç" + +#: ../../po/../src/verbs.cpp:2115 +msgid "_Grid" +msgstr "_Graella" + +#: ../../po/../src/verbs.cpp:2116 +msgid "G_uides" +msgstr "G_uies" + +#: ../../po/../src/verbs.cpp:2117 +msgid "Nex_t Zoom" +msgstr "Ampliació següen_t" + +#: ../../po/../src/verbs.cpp:2117 +msgid "Next zoom (from the history of zooms)" +msgstr "Ampliació següent (de l'historial d'ampliacions)" + +#: ../../po/../src/verbs.cpp:2119 +msgid "Pre_vious Zoom" +msgstr "Am_pliació anterior" + +#: ../../po/../src/verbs.cpp:2119 +msgid "Previous zoom (from the history of zooms)" +msgstr "Ampliació anterior (de l'historial d'ampliacions)" + +#: ../../po/../src/verbs.cpp:2121 +msgid "Zoom 1:_1" +msgstr "Ampliació _1:1" + +#: ../../po/../src/verbs.cpp:2121 +msgid "Zoom to 1:1" +msgstr "Ampliació a 1:1" + +#: ../../po/../src/verbs.cpp:2123 +msgid "Zoom 1:_2" +msgstr "Ampliació 1:_2" + +#: ../../po/../src/verbs.cpp:2123 +msgid "Zoom to 1:2" +msgstr "Ampliació a 1:2" + +#: ../../po/../src/verbs.cpp:2125 +msgid "_Zoom 2:1" +msgstr "Amplia_ció 2:1" + +#: ../../po/../src/verbs.cpp:2125 +msgid "Zoom to 2:1" +msgstr "Ampliació a 2:1" + +#: ../../po/../src/verbs.cpp:2128 +msgid "_Fullscreen" +msgstr "_Pantalla completa" + +#: ../../po/../src/verbs.cpp:2128 +msgid "Stretch this document window to full screen" +msgstr "Ajusta a la finestra del document a pantalla completa" + +#: ../../po/../src/verbs.cpp:2131 +msgid "Duplic_ate Window" +msgstr "Duplic_a la finestra" + +#: ../../po/../src/verbs.cpp:2131 +msgid "Open a new window with the same document" +msgstr "Obre una nova finestra amb el mateix document" + +#: ../../po/../src/verbs.cpp:2133 +msgid "_New View Preview" +msgstr "Previsualitza la _nova vista" + +#: ../../po/../src/verbs.cpp:2134 +msgid "New View Preview" +msgstr "Previsualitza la nova vista" + +#. "view_new_preview" +#: ../../po/../src/verbs.cpp:2136 +#, fuzzy +msgid "_Normal" +msgstr "Normal" + +#: ../../po/../src/verbs.cpp:2137 +msgid "Switch to normal display mode" +msgstr "" + +#: ../../po/../src/verbs.cpp:2138 +#, fuzzy +msgid "_Outline" +msgstr "Caixa al voltant" + +#: ../../po/../src/verbs.cpp:2139 +msgid "Switch to outline (wireframe) display mode" +msgstr "" + +#: ../../po/../src/verbs.cpp:2141 +msgid "Ico_n Preview" +msgstr "Previsualització d'ico_nes" + +#: ../../po/../src/verbs.cpp:2142 +msgid "Open a window to preview items at different icon resolutions" +msgstr "" +"Obre una nova finestra per previsualitzar elements a diferents resolucions" + +#: ../../po/../src/verbs.cpp:2144 +msgid "Zoom to fit page in window" +msgstr "Amplia per ajustar la pàgina a la finestra" + +#: ../../po/../src/verbs.cpp:2145 +msgid "Page _Width" +msgstr "Amplada de pà_gina" + +#: ../../po/../src/verbs.cpp:2146 +msgid "Zoom to fit page width in window" +msgstr "Amplia per ajustar l'amplada de pàgina a la finestra" + +#: ../../po/../src/verbs.cpp:2148 +msgid "Zoom to fit drawing in window" +msgstr "Amplia per ajustar el dibuix a la finestra" + +#: ../../po/../src/verbs.cpp:2150 +msgid "Zoom to fit selection in window" +msgstr "Amplia per ajustar la selecció a la finestra" + +#. Dialogs +#: ../../po/../src/verbs.cpp:2153 +msgid "In_kscape Preferences..." +msgstr "Preferències de l'In_kscape..." + +#: ../../po/../src/verbs.cpp:2154 +msgid "Global Inkscape preferences" +msgstr "Preferències globals de l'Inkscape" + +#: ../../po/../src/verbs.cpp:2155 +msgid "_Document Preferences..." +msgstr "Preferències _del document..." + +#: ../../po/../src/verbs.cpp:2156 +msgid "Preferences saved with the document" +msgstr "Preferències desades amb el document" + +#: ../../po/../src/verbs.cpp:2157 +msgid "_Fill and Stroke..." +msgstr "_Farciment i contorn..." + +#: ../../po/../src/verbs.cpp:2158 +msgid "Fill and Stroke dialog" +msgstr "Diàleg de farciment i contorn" + +#. TRANSLATORS: "Swatches" means: color samples +#: ../../po/../src/verbs.cpp:2160 +msgid "S_watches..." +msgstr "Mostres de _color..." + +#: ../../po/../src/verbs.cpp:2161 +msgid "View color swatches" +msgstr "Visualitza les mostres de color" + +#: ../../po/../src/verbs.cpp:2162 +msgid "Transfor_m..." +msgstr "Transfor_ma..." + +#: ../../po/../src/verbs.cpp:2163 +msgid "Transform dialog" +msgstr "Diàleg de transformacions" + +#: ../../po/../src/verbs.cpp:2164 +msgid "_Align and Distribute..." +msgstr "_Alinea i distribueix..." + +#: ../../po/../src/verbs.cpp:2165 +msgid "Align and Distribute dialog" +msgstr "Diàleg d'alineació i distribució" + +#: ../../po/../src/verbs.cpp:2166 +msgid "_Text and Font..." +msgstr "_Text i tipus de lletra..." + +#: ../../po/../src/verbs.cpp:2167 +msgid "Text and Font dialog" +msgstr "Diàleg de text i tipus de lletra" + +#: ../../po/../src/verbs.cpp:2168 +msgid "_XML Editor..." +msgstr "Editor _XML..." + +#: ../../po/../src/verbs.cpp:2169 +msgid "XML Editor" +msgstr "Editor XML" + +#: ../../po/../src/verbs.cpp:2170 +msgid "_Find..." +msgstr "_Cerca..." + +#: ../../po/../src/verbs.cpp:2171 +msgid "Find objects in document" +msgstr "Cerca objectes al document" + +#: ../../po/../src/verbs.cpp:2172 +msgid "_Messages..." +msgstr "_Missatges..." + +#: ../../po/../src/verbs.cpp:2173 +msgid "View debug messages" +msgstr "Mostra els missatges de depuració" + +#: ../../po/../src/verbs.cpp:2174 +msgid "S_cripts..." +msgstr "_Seqüències..." + +#: ../../po/../src/verbs.cpp:2175 +msgid "Run scripts" +msgstr "Executa les seqüències" + +#: ../../po/../src/verbs.cpp:2176 +msgid "Show/Hide D_ialogs" +msgstr "Mostra/amaga els d_iàlegs" + +#: ../../po/../src/verbs.cpp:2177 +msgid "Show or hide all active dialogs" +msgstr "Mostra o amaga tots els diàlegs actius" + +#. TRANSLATORS: "Tile clones" means: "Create tiled clones" +#: ../../po/../src/verbs.cpp:2179 +msgid "Tile clones..." +msgstr "Mosaic amb clons..." + +#: ../../po/../src/verbs.cpp:2180 +msgid "Create and arrange multiple clones of selection" +msgstr "Crea i ordena múltiples clons de la selecció" + +#: ../../po/../src/verbs.cpp:2181 +msgid "_Object Properties..." +msgstr "Pr_opietats de l'objecte..." + +#: ../../po/../src/verbs.cpp:2182 +msgid "Object Properties dialog" +msgstr "Diàleg de propietats de l'objecte" + +#: ../../po/../src/verbs.cpp:2185 +msgid "_Connect to Jabber server..." +msgstr "_Connecta al servidor de Jabber..." + +#: ../../po/../src/verbs.cpp:2185 +msgid "Connect to a Jabber server" +msgstr "Connecta al servidor de Jabber" + +#: ../../po/../src/verbs.cpp:2187 +msgid "Share with _user..." +msgstr "Comparteix amb un _usuari..." + +#: ../../po/../src/verbs.cpp:2187 +msgid "Establish a whiteboard session with another Jabber user" +msgstr "" +"Estableix una sessió de pisarra col·laborativa amb un altre usuari del Jabber" + +#: ../../po/../src/verbs.cpp:2189 +msgid "Share with _chatroom..." +msgstr "_Comparteix amb una sala..." + +#: ../../po/../src/verbs.cpp:2189 +msgid "" +"Join a chatroom to start a new whiteboard session or join one in progress" +msgstr "" +"Uniu-vos a una sala per començar una sessió de pisarra col·laborativa o uniu-" +"vos a una en progrés" + +#: ../../po/../src/verbs.cpp:2191 +msgid "_Dump XML node tracker" +msgstr "_Bolca el seguidor de nodes XML" + +#: ../../po/../src/verbs.cpp:2191 +msgid "Dump the contents of the XML tracker to the console" +msgstr "Bolca el contingut del seguidor XML a la consola" + +#: ../../po/../src/verbs.cpp:2193 +msgid "_Open session file..." +msgstr "_Obre el fitxer de sessió..." + +#: ../../po/../src/verbs.cpp:2193 +msgid "Open and browse through records of past whiteboard sessions" +msgstr "" +"Obre i navega pels registres de les sessions de pisarra col·laborativa " +"anteriors" + +#: ../../po/../src/verbs.cpp:2195 +msgid "Session file playback" +msgstr "Reproducció del fitxer de sessions" + +#: ../../po/../src/verbs.cpp:2197 +msgid "_Disconnect from session" +msgstr "_Desconnecteu de la sessió" + +#: ../../po/../src/verbs.cpp:2199 +msgid "Disconnect from _server" +msgstr "Desconnecteu del _servidor" + +#: ../../po/../src/verbs.cpp:2201 +msgid "_Input Devices..." +msgstr "D_ispositius d'entrada..." + +#: ../../po/../src/verbs.cpp:2202 +msgid "Configure extended input devices" +msgstr "Configureu els dispositius d'entrada extesos" + +#. Help +#: ../../po/../src/verbs.cpp:2205 +msgid "_Keys and Mouse" +msgstr "Te_cles i ratolí" + +#: ../../po/../src/verbs.cpp:2206 +msgid "Key and mouse shortcuts reference" +msgstr "Combinacions de teclat i ratolí" + +#: ../../po/../src/verbs.cpp:2207 +msgid "About E_xtensions" +msgstr "Quant a les e_xtensions" + +#: ../../po/../src/verbs.cpp:2208 +msgid "About Extensions..." +msgstr "Quant a les extensions..." + +#: ../../po/../src/verbs.cpp:2209 +msgid "About _Memory" +msgstr "Quant a la _memòria" + +#: ../../po/../src/verbs.cpp:2210 +msgid "About Memory..." +msgstr "Quant a la memòria..." + +#: ../../po/../src/verbs.cpp:2211 +msgid "_About Inkscape" +msgstr "Qu_ant a l'Inkscape" + +#. "help_about" +#. new HelpVerb(SP_VERB_SHOW_LICENSE, "ShowLicense", N_("Modifying or Redistributing Inkscape"), +#. N_("Show license to modify and/or redistribute Inkscape: GNU GPL"), NULL), +#. Tutorials +#: ../../po/../src/verbs.cpp:2217 +msgid "Inkscape: _Basic" +msgstr "Inkscape: _bàsic" + +#: ../../po/../src/verbs.cpp:2218 +msgid "Getting started with Inkscape" +msgstr "Començant amb l'Inkscape" + +#. "tutorial_basic" +#: ../../po/../src/verbs.cpp:2219 +msgid "Inkscape: _Shapes" +msgstr "Inkscape: forme_s" + +#: ../../po/../src/verbs.cpp:2220 +msgid "Using shape tools to create and edit shapes" +msgstr "Fent servir les eines de formes per crear i editar formes" + +#: ../../po/../src/verbs.cpp:2221 +msgid "Inkscape: _Advanced" +msgstr "Inksc_ape: avançat" + +#: ../../po/../src/verbs.cpp:2222 +msgid "Advanced Inkscape topics" +msgstr "Temes avançats de l'Inkscape" + +#. "tutorial_advanced" +#. TRANSLATORS: "to trace" means "to convert a bitmap to vector graphics" (to vectorize) +#: ../../po/../src/verbs.cpp:2224 +msgid "Inkscape: T_racing" +msgstr "Inkscape: _vectoritzar" + +#: ../../po/../src/verbs.cpp:2225 +msgid "Using bitmap tracing" +msgstr "Usar la vectorització de mapes de bits" + +#. "tutorial_tracing" +#: ../../po/../src/verbs.cpp:2226 +msgid "Inkscape: _Calligraphy" +msgstr "Inkscape: _cal·ligrafia" + +#: ../../po/../src/verbs.cpp:2227 +msgid "Using the Calligraphy pen tool" +msgstr "Usar l'eina de la ploma cal·ligràfica" + +#: ../../po/../src/verbs.cpp:2228 +msgid "_Elements of Design" +msgstr "_Elements de disseny" + +#: ../../po/../src/verbs.cpp:2229 +msgid "Principles of design in the tutorial form" +msgstr "Tutorial sobre principis del disseny" + +#. "tutorial_design" +#: ../../po/../src/verbs.cpp:2230 +msgid "_Tips and Tricks" +msgstr "Con_sells" + +#: ../../po/../src/verbs.cpp:2231 +msgid "Miscellaneous tips and tricks" +msgstr "Alguns consells" + +#. "tutorial_tips" +#. Effect +#: ../../po/../src/verbs.cpp:2234 +msgid "Previous Effect" +msgstr "Efecte anterior" + +#: ../../po/../src/verbs.cpp:2235 +msgid "Repeat the last effect with the same settings" +msgstr "Repeteix el darrer efecte amb els mateixos valors" + +#. "tutorial_tips" +#: ../../po/../src/verbs.cpp:2236 +msgid "Previous Effect Settings..." +msgstr "Configuració de l'efecte anterior..." + +#: ../../po/../src/verbs.cpp:2237 +msgid "Repeat the last effect with new settings" +msgstr "Repeteix el darrer efecte amb nous valors" + +#: ../../po/../src/widgets/dash-selector.cpp:106 +msgid "Dash pattern" +msgstr "Patró de ratlles" + +#: ../../po/../src/widgets/dash-selector.cpp:121 +msgid "Pattern offset" +msgstr "Desplaçament de patró" + +#: ../../po/../src/widgets/desktop-widget.cpp:240 +msgid "Zoom drawing if window size changes" +msgstr "Amplia el dibuix si canvia la mida de la finestra" + +#: ../../po/../src/widgets/desktop-widget.cpp:298 +msgid "Cursor coordinates" +msgstr "Coordenades del cursor" + +#. display the initial welcome message in the statusbar +#: ../../po/../src/widgets/desktop-widget.cpp:324 +msgid "" +"Welcome to Inkscape! Use shape or freehand tools to create objects; " +"use selector (arrow) to move or transform them." +msgstr "" +"Benvinguts a l'Inkscape! Useu l'eina de formes o la mà alçada per a " +"crear objectes; useu el selector (fletxa) per moure'ls o transformar-los." + +#: ../../po/../src/widgets/desktop-widget.cpp:372 +#, c-format +msgid "%s: %d - Inkscape" +msgstr "%s: %d - Inkscape" + +#: ../../po/../src/widgets/desktop-widget.cpp:374 +#, c-format +msgid "%s - Inkscape" +msgstr "%s - Inkscape" + +#: ../../po/../src/widgets/desktop-widget.cpp:532 +#, c-format +msgid "" +"Save changes to document \"%s\" before " +"closing?\n" +"\n" +"If you close without saving, your changes will be discarded." +msgstr "" +"Voleu desar el document \"%s\" abans " +"de tancar?\n" +"\n" +"Si tanqueu sense desar, els vostres canvis no s'aplicaran." + +#: ../../po/../src/widgets/desktop-widget.cpp:548 +#: ../../po/../src/widgets/desktop-widget.cpp:612 +msgid "Close _without saving" +msgstr "_Tanca sense desar" + +#: ../../po/../src/widgets/desktop-widget.cpp:595 +#, c-format +msgid "" +"The file \"%s\" was saved with a " +"format (%s) that may cause data loss!\n" +"\n" +"Do you want to save this file in another format?" +msgstr "" +"Es poden perdre dades del fitxer \"%s" +"\" degut al format (%s)\n" +"\n" +"Voleu desar aquest fitxer en un altre format?" + +#. Family frame +#: ../../po/../src/widgets/font-selector.cpp:156 +msgid "Font family" +msgstr "Tipus de lletra" + +#. Style frame +#: ../../po/../src/widgets/font-selector.cpp:184 +msgid "Style" +msgstr "Estil" + +#: ../../po/../src/widgets/font-selector.cpp:219 +msgid "Font size:" +msgstr "Mida de la lletra:" + +#. TRANSLATORS: Test string used in text and font dialog (when no +#. * text has been entered) to get a preview of the font. Choose +#. * some representative characters that users of your locale will be +#. * interested in. +#: ../../po/../src/widgets/font-selector.cpp:554 +msgid "AaBbCcIiPpQq12368.;/()" +msgstr "AaBbCcIiPpQq12368.;/()" + +#: ../../po/../src/widgets/gradient-selector.cpp:137 +#: ../../po/../src/widgets/gradient-toolbar.cpp:524 +msgid "Duplicate" +msgstr "Duplica" + +#: ../../po/../src/widgets/gradient-selector.cpp:142 +#: ../../po/../src/widgets/gradient-toolbar.cpp:535 +msgid "Edit..." +msgstr "Edita..." + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/pservers.html#LinearGradientSpreadMethodAttribute +#: ../../po/../src/widgets/gradient-selector.cpp:159 +msgid "" +"Whether to fill with flat color beyond the ends of the gradient vector " +"(spreadMethod=\"pad\"), or repeat the gradient in the same direction " +"(spreadMethod=\"repeat\"), or repeat the gradient in alternating opposite " +"directions (spreadMethod=\"reflect\")" +msgstr "" +"Si s'ha d'omplir amb un color simple més enllà del vector de degradat " +"(spreadMethod=\"pad\"), o repeteix el degradat en la mateixa direcció " +"(spreadMethod=\"repeat\"), o repeteix el degradat en direccions alternants " +"oposades (spreadMethod=\"reflect\")" + +#: ../../po/../src/widgets/gradient-selector.cpp:165 +msgid "none" +msgstr "cap" + +#: ../../po/../src/widgets/gradient-selector.cpp:169 +msgid "reflected" +msgstr "reflectit" + +#: ../../po/../src/widgets/gradient-selector.cpp:173 +msgid "direct" +msgstr "directe" + +#: ../../po/../src/widgets/gradient-selector.cpp:181 +msgid "Repeat:" +msgstr "Repeteix:" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:217 +msgid "No gradients" +msgstr "Cap degradat" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:226 +msgid "Nothing selected" +msgstr "Res seleccionat" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:237 +msgid "No gradients in selection" +msgstr "No hi ha degradats en la selecció" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:247 +msgid "Multiple gradients" +msgstr "Múltiples degradats" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:525 +msgid "" +"If the gradient is used by more than one object, create a copy of it for the " +"selected object(s)" +msgstr "" +"Si el degradat l'usa més d'un objecte, crea'n una còpia per a cada objecte " +"seleccionat" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:536 +msgid "Edit the stops of the gradient" +msgstr "Edita les fases del degradat" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:593 +#: ../../po/../src/widgets/toolbox.cpp:1103 +#: ../../po/../src/widgets/toolbox.cpp:1192 +#: ../../po/../src/widgets/toolbox.cpp:1485 +#: ../../po/../src/widgets/toolbox.cpp:1534 +#: ../../po/../src/widgets/toolbox.cpp:1766 +#: ../../po/../src/widgets/toolbox.cpp:1801 +#: ../../po/../src/widgets/toolbox.cpp:2331 +#: ../../po/../src/widgets/toolbox.cpp:2370 +msgid "New:" +msgstr "Nou:" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:606 +msgid "Create linear gradient" +msgstr "Crea un degradat lineal" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:620 +msgid "Create radial (elliptic or circular) gradient" +msgstr "Crea un degradat lineal (el·líptic o circular)" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:635 +msgid "on" +msgstr "a" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:648 +msgid "Create gradient in the fill" +msgstr "Crea el degradat en el farciment" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:662 +msgid "Create gradient in the stroke" +msgstr "Crea el degradat en el contorn" + +#. FIXME: implement averaging of all parameters for multiple selected stars +#. gtk_label_set_markup(GTK_LABEL(l), _("Average:")); +#. FIXME: implement averaging of all parameters for multiple selected +#. gtk_label_set_markup(GTK_LABEL(l), _("Average:")); +#: ../../po/../src/widgets/gradient-toolbar.cpp:676 +#: ../../po/../src/widgets/toolbox.cpp:1105 +#: ../../po/../src/widgets/toolbox.cpp:1124 +#: ../../po/../src/widgets/toolbox.cpp:1493 +#: ../../po/../src/widgets/toolbox.cpp:1518 +#: ../../po/../src/widgets/toolbox.cpp:1768 +#: ../../po/../src/widgets/toolbox.cpp:1787 +#: ../../po/../src/widgets/toolbox.cpp:2334 +#: ../../po/../src/widgets/toolbox.cpp:2354 +msgid "Change:" +msgstr "Canvi:" + +#: ../../po/../src/widgets/gradient-vector.cpp:269 +msgid "No gradients in document" +msgstr "No hi ha degradats al document" + +#: ../../po/../src/widgets/gradient-vector.cpp:275 +msgid "No gradient selected" +msgstr "No s'ha seleccionat cap degradat" + +#: ../../po/../src/widgets/gradient-vector.cpp:532 +msgid "No stops in gradient" +msgstr "No hi ha fases en el degradat" + +#. TRANSLATORS: "Stop" means: a "phase" of a gradient +#: ../../po/../src/widgets/gradient-vector.cpp:794 +msgid "Add stop" +msgstr "Afegeix una fase" + +#: ../../po/../src/widgets/gradient-vector.cpp:797 +msgid "Add another control stop to gradient" +msgstr "Afegeix una altra fase de control al degradat" + +#: ../../po/../src/widgets/gradient-vector.cpp:799 +msgid "Delete stop" +msgstr "Suprimeix la fase" + +#: ../../po/../src/widgets/gradient-vector.cpp:802 +msgid "Delete current control stop from gradient" +msgstr "Suprimeix la fase de control actual del degradat" + +#. Label +#: ../../po/../src/widgets/gradient-vector.cpp:813 +msgid "Offset:" +msgstr "Desplaçament:" + +#. TRANSLATORS: "Stop" means: a "phase" of a gradient +#: ../../po/../src/widgets/gradient-vector.cpp:858 +msgid "Stop Color" +msgstr "Fase del color" + +#: ../../po/../src/widgets/gradient-vector.cpp:887 +msgid "Gradient editor" +msgstr "Editor de degradats" + +#: ../../po/../src/widgets/layer-selector.cpp:119 +msgid "Toggle current layer visibility" +msgstr "Commuta la visibilitat de la capa actual" + +#: ../../po/../src/widgets/layer-selector.cpp:139 +msgid "Lock or unlock current layer" +msgstr "Bloca o desbloca la capa actual" + +#: ../../po/../src/widgets/layer-selector.cpp:142 +msgid "Current layer" +msgstr "Capa actual" + +#: ../../po/../src/widgets/layer-selector.cpp:553 +msgid "(root)" +msgstr "(arrel)" + +#: ../../po/../src/widgets/paint-selector.cpp:182 +#: ../../po/../src/widgets/paint-selector.cpp:561 +msgid "No paint" +msgstr "Sense pintar" + +#: ../../po/../src/widgets/paint-selector.cpp:184 +#: ../../po/../src/widgets/paint-selector.cpp:629 +msgid "Flat color" +msgstr "Color" + +#: ../../po/../src/widgets/paint-selector.cpp:186 +#: ../../po/../src/widgets/paint-selector.cpp:696 +msgid "Linear gradient" +msgstr "Degradat lineal" + +#: ../../po/../src/widgets/paint-selector.cpp:188 +#: ../../po/../src/widgets/paint-selector.cpp:699 +msgid "Radial gradient" +msgstr "Degradat radial" + +#: ../../po/../src/widgets/paint-selector.cpp:192 +msgid "Unset paint (make it undefined so it can be inherited)" +msgstr "Indefineix el color perquè es pugui heretar" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/painting.html#FillRuleProperty +#: ../../po/../src/widgets/paint-selector.cpp:204 +msgid "" +"Any path self-intersections or subpaths create holes in the fill (fill-rule: " +"evenodd)" +msgstr "" +"Qualsevol intersecció del camí o dels subcamins crea forats en omplir " +"(regla: evenodd)" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/painting.html#FillRuleProperty +#: ../../po/../src/widgets/paint-selector.cpp:215 +msgid "" +"Fill is solid unless a subpath is counterdirectional (fill-rule: nonzero)" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:528 +msgid "No objects" +msgstr "No hi ha objectes" + +#: ../../po/../src/widgets/paint-selector.cpp:539 +msgid "Multiple styles" +msgstr "Múltiples estils" + +#: ../../po/../src/widgets/paint-selector.cpp:550 +msgid "Paint is undefined" +msgstr "Sense definir" + +#: ../../po/../src/widgets/paint-selector.cpp:757 +msgid "No patterns in document" +msgstr "No hi ha patrons al document" + +#: ../../po/../src/widgets/paint-selector.cpp:872 +msgid "" +"Use Edit > Object(s) to Pattern to create a new pattern from " +"selection." +msgstr "" +"Useu Edita > Objectes a patró per a crear un nou patró de la " +"selecció." + +#: ../../po/../src/widgets/select-toolbar.cpp:426 +msgid "Now stroke width is scaled when objects are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:428 +msgid "Now stroke width is not scaled when objects are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:436 +msgid "" +"Now rounded rectangle corners are scaled when rectangles are " +"scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:438 +msgid "" +"Now rounded rectangle corners are not scaled when rectangles " +"are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:446 +msgid "" +"Now gradients are transformed along with their objects when " +"those are transformed (moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:448 +msgid "" +"Now gradients remain fixed when objects are transformed " +"(moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:456 +msgid "" +"Now patterns are transformed along with their objects when " +"those are transformed (moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:458 +msgid "" +"Now patterns remain fixed when objects are transformed (moved, " +"scaled, rotated, or skewed)." +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:506 +msgid "select_toolbar|X" +msgstr "barra_selecció|X" + +#: ../../po/../src/widgets/select-toolbar.cpp:506 +msgid "Horizontal coordinate of selection" +msgstr "Coordenada horitzontal de la selecció" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:511 +msgid "select_toolbar|Y" +msgstr "barra_selecció|Y" + +#: ../../po/../src/widgets/select-toolbar.cpp:511 +msgid "Vertical coordinate of selection" +msgstr "Coordenada vertical de la selecció" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:517 +msgid "select_toolbar|W" +msgstr "barra_selecció|A" + +#: ../../po/../src/widgets/select-toolbar.cpp:517 +msgid "Width of selection" +msgstr "Amplada de la selecció" + +#: ../../po/../src/widgets/select-toolbar.cpp:525 +msgid "Change both width and height by the same proportion" +msgstr "Canvia l'amplada i l'alçada amb la mateixa proporció" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:534 +msgid "select_toolbar|H" +msgstr "barra_selecció|A" + +#: ../../po/../src/widgets/select-toolbar.cpp:534 +msgid "Height of selection" +msgstr "Alçada de la selecció" + +#: ../../po/../src/widgets/sp-color-gtkselector.cpp:62 +msgid "System" +msgstr "Sistema" + +#: ../../po/../src/widgets/sp-color-notebook.cpp:322 +msgid "RGBA_:" +msgstr "RGBA_:" + +#: ../../po/../src/widgets/sp-color-notebook.cpp:330 +msgid "Hexadecimal RGBA value of the color" +msgstr "Valor RGBA hexadecimal del color" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "RGB" +msgstr "RGB" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "HSL" +msgstr "HSL" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "CMYK" +msgstr "CMYK" + +#: ../../po/../src/widgets/sp-color-scales.cpp:397 +msgid "_R" +msgstr "_R" + +#: ../../po/../src/widgets/sp-color-scales.cpp:398 +#: ../../po/../src/widgets/sp-color-scales.cpp:399 +msgid "Red" +msgstr "Vermell" + +#: ../../po/../src/widgets/sp-color-scales.cpp:400 +msgid "_G" +msgstr "_G" + +#: ../../po/../src/widgets/sp-color-scales.cpp:401 +#: ../../po/../src/widgets/sp-color-scales.cpp:402 +msgid "Green" +msgstr "Verd" + +#: ../../po/../src/widgets/sp-color-scales.cpp:403 +msgid "_B" +msgstr "_B" + +#: ../../po/../src/widgets/sp-color-scales.cpp:404 +#: ../../po/../src/widgets/sp-color-scales.cpp:405 +msgid "Blue" +msgstr "Blau" + +#. Label +#: ../../po/../src/widgets/sp-color-scales.cpp:406 +#: ../../po/../src/widgets/sp-color-scales.cpp:432 +#: ../../po/../src/widgets/sp-color-scales.cpp:463 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:141 +msgid "_A" +msgstr "_A" + +#: ../../po/../src/widgets/sp-color-scales.cpp:407 +#: ../../po/../src/widgets/sp-color-scales.cpp:408 +#: ../../po/../src/widgets/sp-color-scales.cpp:433 +#: ../../po/../src/widgets/sp-color-scales.cpp:434 +#: ../../po/../src/widgets/sp-color-scales.cpp:464 +#: ../../po/../src/widgets/sp-color-scales.cpp:465 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:151 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:163 +msgid "Alpha (opacity)" +msgstr "Opacitat" + +#: ../../po/../src/widgets/sp-color-scales.cpp:423 +msgid "_H" +msgstr "_H" + +#: ../../po/../src/widgets/sp-color-scales.cpp:424 +#: ../../po/../src/widgets/sp-color-scales.cpp:425 +msgid "Hue" +msgstr "Matís" + +#: ../../po/../src/widgets/sp-color-scales.cpp:426 +msgid "_S" +msgstr "_S" + +#: ../../po/../src/widgets/sp-color-scales.cpp:427 +#: ../../po/../src/widgets/sp-color-scales.cpp:428 +msgid "Saturation" +msgstr "Saturació" + +#: ../../po/../src/widgets/sp-color-scales.cpp:429 +msgid "_L" +msgstr "_L" + +#: ../../po/../src/widgets/sp-color-scales.cpp:430 +#: ../../po/../src/widgets/sp-color-scales.cpp:431 +msgid "Lightness" +msgstr "Brillantor" + +#: ../../po/../src/widgets/sp-color-scales.cpp:451 +msgid "_C" +msgstr "_C" + +#: ../../po/../src/widgets/sp-color-scales.cpp:452 +#: ../../po/../src/widgets/sp-color-scales.cpp:453 +msgid "Cyan" +msgstr "Cian" + +#: ../../po/../src/widgets/sp-color-scales.cpp:454 +msgid "_M" +msgstr "_M" + +#: ../../po/../src/widgets/sp-color-scales.cpp:455 +#: ../../po/../src/widgets/sp-color-scales.cpp:456 +msgid "Magenta" +msgstr "Magenta" + +#: ../../po/../src/widgets/sp-color-scales.cpp:457 +msgid "_Y" +msgstr "_Y" + +#: ../../po/../src/widgets/sp-color-scales.cpp:458 +#: ../../po/../src/widgets/sp-color-scales.cpp:459 +msgid "Yellow" +msgstr "Groc" + +#: ../../po/../src/widgets/sp-color-scales.cpp:460 +msgid "_K" +msgstr "_K" + +#: ../../po/../src/widgets/sp-color-selector.cpp:71 +msgid "Unnamed" +msgstr "Sense nom" + +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:68 +msgid "Wheel" +msgstr "Rodona" + +#: ../../po/../src/widgets/sp-xmlview-attr-list.cpp:53 +msgid "Attribute" +msgstr "Atribut" + +#: ../../po/../src/widgets/sp-xmlview-attr-list.cpp:54 +msgid "Value" +msgstr "Valor" + +#: ../../po/../src/widgets/toolbox.cpp:424 +msgid "Insert new nodes into selected segments" +msgstr "Insereix nous nodes en els segments seleccionats" + +#: ../../po/../src/widgets/toolbox.cpp:426 +msgid "Delete selected nodes" +msgstr "Suprimeix els nodes seleccionats" + +#: ../../po/../src/widgets/toolbox.cpp:431 +msgid "Join paths at selected nodes" +msgstr "Uneix els camins als nodes seleccionats" + +#: ../../po/../src/widgets/toolbox.cpp:433 +msgid "Join paths at selected nodes with new segment" +msgstr "Uneix els camins als nodes seleccionats amb un nou segment" + +#: ../../po/../src/widgets/toolbox.cpp:436 +msgid "Split path between two non-endpoint nodes" +msgstr "Separa el camí entre dos nodes no finals" + +#: ../../po/../src/widgets/toolbox.cpp:439 +msgid "Break path at selected nodes" +msgstr "Trenca el camí en els nodes seleccionats" + +#: ../../po/../src/widgets/toolbox.cpp:444 +msgid "Make selected nodes corner" +msgstr "Fes una cantonada amb els nodes seleccionats" + +#: ../../po/../src/widgets/toolbox.cpp:447 +msgid "Make selected nodes smooth" +msgstr "Suavitza els nodes seleccionats" + +#: ../../po/../src/widgets/toolbox.cpp:450 +msgid "Make selected nodes symmetric" +msgstr "Fes els nodes seleccionats simètrics" + +#: ../../po/../src/widgets/toolbox.cpp:455 +msgid "Make selected segments lines" +msgstr "Converteix els segments seleccionats en línies" + +#: ../../po/../src/widgets/toolbox.cpp:458 +msgid "Make selected segments curves" +msgstr "Converteix els segments seleccionats en corbes" + +#: ../../po/../src/widgets/toolbox.cpp:1199 +msgid "Polygon" +msgstr "Polígon" + +#: ../../po/../src/widgets/toolbox.cpp:1206 +msgid "Regular polygon (with one handle) instead of a star" +msgstr "Polígon regular (amb un manejador) en comptes d'un estel" + +#: ../../po/../src/widgets/toolbox.cpp:1218 +msgid "Corners:" +msgstr "Cantonades:" + +#: ../../po/../src/widgets/toolbox.cpp:1218 +msgid "Number of corners of a polygon or star" +msgstr "Nombre de cantonades d'un polígon o un estel" + +#: ../../po/../src/widgets/toolbox.cpp:1228 +msgid "Spoke ratio:" +msgstr "Radi de la punxa:" + +#. TRANSLATORS: Tip radius of a star is the distance from the center to the farthest handle. +#. Base radius is the same for the closest handle. +#: ../../po/../src/widgets/toolbox.cpp:1231 +msgid "Base radius to tip radius ratio" +msgstr "Distància al centre del manejador més llunyà" + +#: ../../po/../src/widgets/toolbox.cpp:1246 +msgid "Rounded:" +msgstr "Arrodoniment:" + +#: ../../po/../src/widgets/toolbox.cpp:1246 +msgid "How much rounded are the corners (0 for sharp)" +msgstr "Arrodoniment de les cantonades (0 per a fer-les punxagudes)" + +#: ../../po/../src/widgets/toolbox.cpp:1256 +msgid "Randomized:" +msgstr "Aleatorització:" + +#: ../../po/../src/widgets/toolbox.cpp:1256 +msgid "Scatter randomly the corners and angles" +msgstr "Distribueix a l'atzar les cantonades i els angles" + +#: ../../po/../src/widgets/toolbox.cpp:1269 +#: ../../po/../src/widgets/toolbox.cpp:1838 +#: ../../po/../src/widgets/toolbox.cpp:2061 +msgid "Defaults" +msgstr "Per defecte" + +#: ../../po/../src/widgets/toolbox.cpp:1270 +#: ../../po/../src/widgets/toolbox.cpp:1839 +#: ../../po/../src/widgets/toolbox.cpp:2062 +msgid "" +"Reset shape parameters to defaults (use Inkscape Preferences > Tools to " +"change defaults)" +msgstr "" +"Reinicialitza les opcions predeterminades de la forma (useu Preferències > " +"Eines per canviar els valors predeterminats)" + +#: ../../po/../src/widgets/toolbox.cpp:1544 +msgid "W:" +msgstr "A:" + +#: ../../po/../src/widgets/toolbox.cpp:1544 +msgid "Width of rectangle" +msgstr "Amplada del rectangle" + +#: ../../po/../src/widgets/toolbox.cpp:1556 +msgid "Height of rectangle" +msgstr "Alçada del rectangle" + +#: ../../po/../src/widgets/toolbox.cpp:1568 +msgid "Rx:" +msgstr "Rx:" + +#: ../../po/../src/widgets/toolbox.cpp:1568 +msgid "Horizontal radius of rounded corners" +msgstr "Radi horitzontal de les cantonades arrodonides" + +#: ../../po/../src/widgets/toolbox.cpp:1578 +msgid "Ry:" +msgstr "Ry:" + +#: ../../po/../src/widgets/toolbox.cpp:1578 +msgid "Vertical radius of rounded corners" +msgstr "Radi vertical de les cantonades arrodonides" + +#: ../../po/../src/widgets/toolbox.cpp:1594 +msgid "Not rounded" +msgstr "Sense arrodonir" + +#: ../../po/../src/widgets/toolbox.cpp:1596 +msgid "Make corners sharp" +msgstr "Fes cantonades afilades" + +#: ../../po/../src/widgets/toolbox.cpp:1805 +msgid "Turns:" +msgstr "Girs:" + +#: ../../po/../src/widgets/toolbox.cpp:1805 +msgid "Number of revolutions" +msgstr "Nombre de revolucions" + +#: ../../po/../src/widgets/toolbox.cpp:1815 +msgid "Divergence:" +msgstr "Divergència:" + +#: ../../po/../src/widgets/toolbox.cpp:1815 +msgid "How much denser/sparser are outer revolutions; 1 = uniform" +msgstr "" +"Quanta densitat han de tenir les revolucions externes. 1 vol dir uniformement" + +#: ../../po/../src/widgets/toolbox.cpp:1825 +msgid "Inner radius:" +msgstr "Radi intern:" + +#: ../../po/../src/widgets/toolbox.cpp:1825 +msgid "Radius of the innermost revolution (relative to the spiral size)" +msgstr "Radi de la revolució més interna (relatiu a la mida de l'espiral)" + +#: ../../po/../src/widgets/toolbox.cpp:1957 +msgid "The width of the calligraphic pen (relative to the visible canvas area)" +msgstr "" +"L'amplada de la ploma cal·ligràfica (relativa a l'àrea visible del llenç)" + +#: ../../po/../src/widgets/toolbox.cpp:1967 +msgid "Thinning:" +msgstr "Aprima:" + +#: ../../po/../src/widgets/toolbox.cpp:1967 +msgid "" +"How much velocity thins the stroke (> 0 makes fast strokes thinner, < 0 " +"makes them broader, 0 makes width independent of velocity)" +msgstr "" +"Com s'aprima el contorn segons la velocitat (>0 fa que el contorn sigui més " +"prim, <0 el fa més gruixut i amb 0 la velocitat no l'afecta)" + +#: ../../po/../src/widgets/toolbox.cpp:1980 +msgid "Angle:" +msgstr "Angle:" + +#: ../../po/../src/widgets/toolbox.cpp:1980 +msgid "" +"The angle of the pen's nib (in degrees; 0 = horizontal; has no effect if " +"fixation = 0)" +msgstr "" +"L'angle de la punta de la ploma (en graus; 0 = horitzontal; no té efecte si " +"la fixació és 0)" + +#: ../../po/../src/widgets/toolbox.cpp:1990 +msgid "Fixation:" +msgstr "Fixació:" + +#: ../../po/../src/widgets/toolbox.cpp:1990 +msgid "" +"How fixed is the pen angle (0 = always perpendicular to stroke direction, 1 " +"= fixed)" +msgstr "" +"Fixació de l'angle de la ploma (0 = sempre perpendicular a la direcció del " +"contorn, 1 = fix)" + +#: ../../po/../src/widgets/toolbox.cpp:2003 +msgid "Mass:" +msgstr "Cota:" + +#: ../../po/../src/widgets/toolbox.cpp:2003 +msgid "How much inertia affects the movement of the pen" +msgstr "Quanta inèrcia afecta el moviment de la ploma" + +#. TRANSLATORS: "drag" means "resistance" here +#: ../../po/../src/widgets/toolbox.cpp:2014 +msgid "Drag:" +msgstr "Ressistència:" + +#: ../../po/../src/widgets/toolbox.cpp:2014 +msgid "How much resistance affects the movement of the pen" +msgstr "Quanta resistència afecta el moviment de la ploma" + +#: ../../po/../src/widgets/toolbox.cpp:2034 +msgid "Use the pressure of the input device to alter the width of the pen" +msgstr "" +"Usa la pressió del dispositiu d'entrada per modificar l'amplada de la ploma" + +#: ../../po/../src/widgets/toolbox.cpp:2047 +msgid "Use the tilt of the input device to alter the angle of the pen's nib" +msgstr "" +"Usa la inclinació del dispositiu d'entrada per modificar l'angle de la ploma" + +#: ../../po/../src/widgets/toolbox.cpp:2374 +msgid "Start:" +msgstr "Inici:" + +#: ../../po/../src/widgets/toolbox.cpp:2374 +msgid "The angle (in degrees) from the horizontal to the arc's start point" +msgstr "L'angle (en graus) de l'horitzontal al punt d'inici de l'arc" + +#: ../../po/../src/widgets/toolbox.cpp:2384 +msgid "End:" +msgstr "Fi:" + +#: ../../po/../src/widgets/toolbox.cpp:2384 +msgid "The angle (in degrees) from the horizontal to the arc's end point" +msgstr "L'angle (en graus) de l'horitzontal al punt final de l'arc" + +#: ../../po/../src/widgets/toolbox.cpp:2395 +msgid "Open arc" +msgstr "Obre un arc" + +#: ../../po/../src/widgets/toolbox.cpp:2396 +msgid "" +"Switch between arc (unclosed shape) and segment (closed shape with two radii)" +msgstr "" +"Commuta entre un arc (forma sense tancar) i segment (forma tancada amb dos " +"radis)" + +#: ../../po/../src/widgets/toolbox.cpp:2415 +msgid "Make whole" +msgstr "Fes sencer" + +#: ../../po/../src/widgets/toolbox.cpp:2417 +msgid "Make the shape a whole ellipse, not arc or segment" +msgstr "Fes una forma sencera, ni un arc ni un segment" + +#: ../../po/../src/widgets/toolbox.cpp:2644 +msgid "" +"When pressed, picks visible color without alpha and when not pressed, picks " +"color including its alpha" +msgstr "" +"Quan estigui premut, selecciona el color visible sense opacitat i quan no ho " +"estigui, selecciona amb opacitat" + +#: ../../po/../src/widgets/toolbox.cpp:3039 +msgid "Make connectors avoid selected objects" +msgstr "Feu que els connectors evitin els objectes seleccionats" + +#: ../../po/../src/widgets/toolbox.cpp:3043 +msgid "Make connectors ignore selected objects" +msgstr "Feu que els connectors ignorin els objectes seleccionats" + +#. +#. 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 : +#: ../share/extensions/addnodes.inx.h:1 +#, fuzzy +msgid "Add Nodes" +msgstr "Nodes" + +#: ../share/extensions/addnodes.inx.h:2 +msgid "Maximum Segment Length" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:1 +msgid "AI Input" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:2 ../share/extensions/ai_output.inx.h:2 +msgid "Adobe Illustrator (*.ai)" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:3 +msgid "Open files saved with Adobe Illustrator" +msgstr "" + +#: ../share/extensions/ai_output.inx.h:1 +#, fuzzy +msgid "AI Output" +msgstr "Sortida" + +#: ../share/extensions/ai_output.inx.h:3 +msgid "Write Adobe Illustrator" +msgstr "" + +#: ../share/extensions/dia.inx.h:1 +msgid "A diagram created with the program Dia" +msgstr "" + +#: ../share/extensions/dia.inx.h:2 +msgid "Dia Diagram (*.dia)" +msgstr "" + +#: ../share/extensions/dia.inx.h:3 +msgid "Dia Input" +msgstr "" + +#: ../share/extensions/dia.inx.h:4 +msgid "" +"In order to import Dia files, Dia itself must be installed. You can get Dia " +"at http://www.gnome.org/projects/dia/" +msgstr "" + +#: ../share/extensions/dia.inx.h:5 +msgid "" +"The dia2svg.sh script should be installed with your Inkscape distribution. " +"If you do not have it, there is likely to be something wrong with your " +"Inkscape installation." +msgstr "" + +#: ../share/extensions/dots.inx.h:1 +#, fuzzy +msgid "Connect the Dots" +msgstr "Connector" + +#: ../share/extensions/dots.inx.h:2 +#, fuzzy +msgid "Dot Size" +msgstr "Mida" + +#: ../share/extensions/dots.inx.h:3 +#, fuzzy +msgid "Font Size" +msgstr "Mida de la lletra:" + +#: ../share/extensions/dropshadow.inx.h:1 +msgid "Color of shadow" +msgstr "" + +#: ../share/extensions/dropshadow.inx.h:2 +#, fuzzy +msgid "Dropshadow" +msgstr "Mostra l'ombra de la pàgina" + +#: ../share/extensions/dxf_input.inx.h:1 +#: ../share/extensions/dxf_output.inx.h:1 +msgid "AutoCAD DXF (*.dxf)" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:2 +msgid "DXF Input" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:3 +msgid "Import AutoCAD's Document Exchange Format" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:4 +msgid "" +"dxf2svg may come with Inkscape, but is also at http://dxf-svg-convert." +"sourceforge.net/" +msgstr "" + +#: ../share/extensions/dxf_output.inx.h:2 +#, fuzzy +msgid "DXF Output" +msgstr "Sortida" + +#: ../share/extensions/dxf_output.inx.h:3 +msgid "DXF file written by pstoedit" +msgstr "" + +#: ../share/extensions/dxf_output.inx.h:4 +msgid "pstoedit must be installed to run see http://www.pstoedit.net/pstoedit" +msgstr "" + +#: ../share/extensions/embedimage.inx.h:1 +#, fuzzy +msgid "Embed Images" +msgstr "Imatges" + +#: ../share/extensions/eps_input.inx.h:1 +msgid "EPS Input" +msgstr "" + +#: ../share/extensions/eps_input.inx.h:2 +msgid "Encapsulated Postscript" +msgstr "" + +#: ../share/extensions/eps_input.inx.h:3 +msgid "Encapsulated Postscript (*.eps)" +msgstr "" + +#: ../share/extensions/epsi_output.inx.h:1 +#, fuzzy +msgid "EPSI Output" +msgstr "Sortida" + +#: ../share/extensions/epsi_output.inx.h:2 +msgid "Encapsulated Postscript Interchange (*.epsi)" +msgstr "" + +#: ../share/extensions/epsi_output.inx.h:3 +msgid "Encapsulated Postscript with a thumbnail" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:1 ../share/extensions/ffms.inx.h:1 +#: ../share/extensions/ffset.inx.h:1 ../share/extensions/ffss.inx.h:1 +#, fuzzy +msgid "Bridge Width" +msgstr "Amplada de línia" + +#: ../share/extensions/ffmet.inx.h:2 ../share/extensions/ffms.inx.h:2 +msgid "First String Length" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:3 +msgid "FretFind Multi Length ET" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:4 ../share/extensions/ffms.inx.h:4 +#: ../share/extensions/ffset.inx.h:3 ../share/extensions/ffss.inx.h:3 +msgid "Fretboard Edges" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:5 ../share/extensions/ffms.inx.h:5 +msgid "Last String Length" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:6 ../share/extensions/ffms.inx.h:6 +#: ../share/extensions/ffset.inx.h:4 ../share/extensions/ffss.inx.h:4 +#, fuzzy +msgid "Number of Frets" +msgstr "Nombre de files" + +#: ../share/extensions/ffmet.inx.h:7 ../share/extensions/ffms.inx.h:7 +#: ../share/extensions/ffset.inx.h:5 ../share/extensions/ffss.inx.h:5 +#, fuzzy +msgid "Number of Strings" +msgstr "Nombre de files" + +#: ../share/extensions/ffmet.inx.h:8 ../share/extensions/ffms.inx.h:8 +#: ../share/extensions/ffset.inx.h:6 ../share/extensions/ffss.inx.h:6 +#, fuzzy +msgid "Nut Width" +msgstr "Amplada" + +#: ../share/extensions/ffmet.inx.h:9 ../share/extensions/ffms.inx.h:10 +msgid "Perpendicular Distance" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:10 ../share/extensions/ffset.inx.h:7 +msgid "Scale Base (2 for Octave)" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:11 ../share/extensions/ffset.inx.h:9 +msgid "Tones in Scale" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:12 ../share/extensions/ffms.inx.h:12 +#: ../share/extensions/ffset.inx.h:10 ../share/extensions/ffss.inx.h:10 +msgid "px per Unit" +msgstr "" + +#: ../share/extensions/ffms.inx.h:3 +msgid "FretFind Multi Length Scala" +msgstr "" + +#: ../share/extensions/ffms.inx.h:9 ../share/extensions/ffss.inx.h:7 +msgid "Path to Scala *.scl File" +msgstr "" + +#: ../share/extensions/ffms.inx.h:11 +msgid "Tuning (scale step for each string seperated by semicolons)" +msgstr "" + +#: ../share/extensions/ffset.inx.h:2 +msgid "FretFind Single Length ET" +msgstr "" + +#: ../share/extensions/ffset.inx.h:8 ../share/extensions/ffss.inx.h:8 +msgid "Scale Length" +msgstr "" + +#: ../share/extensions/ffss.inx.h:2 +msgid "FretFind Single Length Scala" +msgstr "" + +#: ../share/extensions/ffss.inx.h:9 +msgid "Tuning (Scale step for each string seperated by semicolons)" +msgstr "" + +#: ../share/extensions/handles.inx.h:1 +#, fuzzy +msgid "Draw Handles" +msgstr "Dibuixa línies a mà alçada" + +#: ../share/extensions/interp.inx.h:1 +#, fuzzy +msgid "Duplicate Endpaths" +msgstr "Duplica el node" + +#: ../share/extensions/interp.inx.h:2 +#, fuzzy +msgid "Exponent" +msgstr "Exporta" + +#: ../share/extensions/interp.inx.h:3 +msgid "Interpolate" +msgstr "" + +#: ../share/extensions/interp.inx.h:4 +msgid "Interpolate Style (Experimental)" +msgstr "" + +#: ../share/extensions/interp.inx.h:5 +msgid "Interpolation Method" +msgstr "" + +#: ../share/extensions/interp.inx.h:6 +msgid "Interpolation Steps" +msgstr "" + +#: ../share/extensions/kochify.inx.h:1 +msgid "Kochify" +msgstr "" + +#: ../share/extensions/kochify_load.inx.h:1 +msgid "Kochify (Load)" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:1 +#, fuzzy +msgid "Angle" +msgstr "Angle:" + +#: ../share/extensions/lindenmayer.inx.h:2 +msgid "Axiom" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:3 +#, fuzzy +msgid "Lindenmayer" +msgstr "Reanomena la capa" + +#: ../share/extensions/lindenmayer.inx.h:4 +msgid "Order" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:5 +#, fuzzy +msgid "Rules" +msgstr "_Regles" + +#: ../share/extensions/lindenmayer.inx.h:6 +#, fuzzy +msgid "Step" +msgstr "Passos" + +#: ../share/extensions/motion.inx.h:1 +#, fuzzy +msgid "Direction" +msgstr "Descripció" + +#: ../share/extensions/motion.inx.h:2 +#, fuzzy +msgid "Magnitude" +msgstr "Magenta" + +#: ../share/extensions/motion.inx.h:3 +#, fuzzy +msgid "Motion" +msgstr "_Rotació" + +#: ../share/extensions/pdf_output.inx.h:1 +msgid "Adobe PDF (*.pdf)" +msgstr "" + +#: ../share/extensions/pdf_output.inx.h:2 +msgid "Adobe Portable Document Format" +msgstr "" + +#: ../share/extensions/pdf_output.inx.h:3 +#, fuzzy +msgid "PDF Output" +msgstr "Sortida" + +#: ../share/extensions/ps_input.inx.h:1 +#, fuzzy +msgid "Postscript" +msgstr "Vertical" + +#: ../share/extensions/ps_input.inx.h:2 +msgid "Postscript (*.ps)" +msgstr "" + +#: ../share/extensions/ps_input.inx.h:3 +msgid "Postscript Input" +msgstr "" + +#: ../share/extensions/radiusrand.inx.h:1 +#, fuzzy +msgid "Radius" +msgstr "A_lça" + +#: ../share/extensions/radiusrand.inx.h:2 +#, fuzzy +msgid "Radius Randomize" +msgstr "Aleatorització:" + +#: ../share/extensions/radiusrand.inx.h:3 +msgid "Randomize Control Points" +msgstr "" + +#: ../share/extensions/radiusrand.inx.h:4 +#, fuzzy +msgid "Randomize Nodes" +msgstr "Aleatorització:" + +#: ../share/extensions/rtree.inx.h:1 +#, fuzzy +msgid "Initial Size" +msgstr "Mida del mapa de bits" + +#: ../share/extensions/rtree.inx.h:2 +msgid "Minimum Size" +msgstr "" + +#: ../share/extensions/rtree.inx.h:3 +#, fuzzy +msgid "Random Tree" +msgstr "Aleatorització:" + +#: ../share/extensions/sk_input.inx.h:1 +msgid "A diagram created with the program Sketch" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:2 +msgid "Sketch Diagram (*.sk)" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:3 +msgid "Sketch Input" +msgstr "" + +#: ../share/extensions/straightseg.inx.h:1 +msgid "Behavior" +msgstr "" + +#: ../share/extensions/straightseg.inx.h:3 +msgid "Segment Straightener" +msgstr "" + +#: ../share/extensions/summersnight.inx.h:1 +msgid "Summer's Night" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:1 +#: ../share/extensions/svgz_output.inx.h:1 +msgid "Compressed Inkscape SVG (*.svgz)" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:2 +#: ../share/extensions/svgz_output.inx.h:2 +msgid "Inkscape's native file format compressed with GZip" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:3 +msgid "SVGZ Input" +msgstr "" + +#: ../share/extensions/svgz_output.inx.h:3 +#, fuzzy +msgid "SVGZ Output" +msgstr "Sortida" + +#: ../share/extensions/txt2svg.inx.h:1 +msgid "ASCII Text" +msgstr "" + +#: ../share/extensions/txt2svg.inx.h:2 +msgid "Text File (*.txt)" +msgstr "" + +#: ../share/extensions/txt2svg.inx.h:3 +msgid "Text Input" +msgstr "" + +#: ../share/extensions/wavy.inx.h:1 +msgid "Calculate first derivative numerically" +msgstr "" + +#: ../share/extensions/wavy.inx.h:2 +msgid "First derivative" +msgstr "" + +#: ../share/extensions/wavy.inx.h:3 +msgid "Function" +msgstr "" + +#: ../share/extensions/wavy.inx.h:4 +msgid "Function Plotter" +msgstr "" + +#: ../share/extensions/wavy.inx.h:5 +msgid "Nodes per period" +msgstr "" + +#: ../share/extensions/wavy.inx.h:6 +msgid "Periods (2*Pi each)" +msgstr "" + +#: ../share/extensions/whirl.inx.h:1 +msgid "Amount of Whirl" +msgstr "" + +#: ../share/extensions/whirl.inx.h:2 +#, fuzzy +msgid "Center X" +msgstr "Centra les línies" + +#: ../share/extensions/whirl.inx.h:3 +#, fuzzy +msgid "Center Y" +msgstr "Centra les línies" + +#: ../share/extensions/whirl.inx.h:4 +#, fuzzy +msgid "Direction of Rotation" +msgstr "Rebutja la invitació" + +#: ../share/extensions/whirl.inx.h:5 +msgid "Whirl" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:1 +msgid "A popular graphics file format for clipart" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:2 +msgid "Windows Metafile (*.wmf)" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:3 +msgid "Windows Metafile Input" +msgstr "" + +#~ msgid "Custom canvas" +#~ msgstr "Llenç personalitzat" + +#~ msgid "Current style" +#~ msgstr "Estil actual" + +#~ msgid "" +#~ "Current style is updated every time you change the style of any object " +#~ "(its fill, stroke, transparency, etc.)" +#~ msgstr "" +#~ "L'estil actual s'actualitza cada vegada que canvieu l'estil de qualsevol " +#~ "objecte (farciment, contorn, transparència, etc.)" + +#~ msgid "Arrange Objects" +#~ msgstr "Ordena objectes" + +#~ msgid "deg" +#~ msgstr "graus" + +#~ msgid "" +#~ "%s is not a valid preferences file.\n" +#~ "%s" +#~ msgstr "" +#~ "%s no és un fitxer de preferències vàlid.\n" +#~ "%s" + +#~ msgid "" +#~ "Inkscape will run with default settings.\n" +#~ "New settings will not be saved." +#~ msgstr "" +#~ "L'Inkscape s'executarà amb la configuració predeterminada.\n" +#~ "No es desarà la nova configuració." + +#~ msgid "_Credits" +#~ msgstr "_Crèdits" + +#~ msgid "Grab sensitivity" +#~ msgstr "Proximitat per seleccionar" + +#~ msgid "Click/drag threshold" +#~ msgstr "Llindar per clicar/arrossegar" + +#~ msgid "Mouse wheel scrolls by" +#~ msgstr "La roda del ratolí desplaça" + +#~ msgid "Scroll by" +#~ msgstr "Desplaça" + +#~ msgid "Acceleration" +#~ msgstr "Acceleració" + +#~ msgid "Speed" +#~ msgstr "Velocitat" + +#~ msgid "Threshold" +#~ msgstr "Llindar" + +#~ msgid "Arrow keys move by" +#~ msgstr "Les tecles de fletxa mouen" + +#~ msgid "> and < scale by" +#~ msgstr "> i < escalen per" + +#~ msgid "Inset/Outset by" +#~ msgstr "Contreu/expandeix per" + +#~ msgid "Rotation snaps every" +#~ msgstr "Gira cada" + +#~ msgid "Zoom in/out by" +#~ msgstr "Ampliació per" + +#~ msgid "Transform" +#~ msgstr "Transforma" + +#~ msgid "Flip selection horizontally" +#~ msgstr "Volteja horitzontalment la selecció" + +#~ msgid "Flip selection vertically" +#~ msgstr "Volteja verticalment la selecció" diff --git a/po/check-markup b/po/check-markup new file mode 100755 index 000000000..6450e1fe3 --- /dev/null +++ b/po/check-markup @@ -0,0 +1,190 @@ +#! /usr/bin/perl -w +# Try to detect markup errors in translations. + +# Author: Peter Moulder +# Copyright (C) 2004 Monash University +# License: GNU GPL v2 or (at your option) any later version. + +# Initial egrep version: +#mydir=`dirname "$0"` +#egrep '[^<>]*(>|<([^/]|/([^b"]|b[^>])))' "$mydir"/*.po +# Somewhat simplified by use of negative lookahead in perl. +# (The egrep version as written can't detect problems that span a line, +# e.g. unterminated `'. One way of doing the s/"\n"//g thing would be with +# tr and sed, but that requires a sed that allows arbitrary line lengths, which +# many non-GNU seds don't.) + +use strict; + +my $com = qr/(?:\#[^\n]*\n)/; +my $str = qr/(?:"(?:[^"\\]|\\.)*")/; +my $attrsRE = qr/(?: +[^<>]*)?/; +my $span_attr = qr/(?:\ +(?:font_(?:desc|family)|face|size|style|weight|variant|stretch|(?:fore|back)ground|underline|rise|strikethrough|fallback|lang)\=\\\"[^\\\"]*\\\")/; + +my $rc = 0; + +sub po_error ($) { + my ($msg) = @_; + my $name = $ARGV; + $name =~ s,.*/,,; + print "$name: $msg:\n$_"; + $rc = 1; +} + +# Returns true iff successful. +sub check_str ($) { + my ($str) = @_; + + $str =~ s/\A"// or die "Bug: No leading `\"' in `$str'"; + $str =~ s/"\Z// or die "Bug: No trailing `\"' in `$str'"; + + if ($str =~ /\AProject-Id-Version:.*POT-Creation-Date/ + or $str =~ /\A<[^<>]*>\Z/) { + # Not a Pango string. + return 1; + } + + my $is_xml = 0; + + # Remove valid sequences. + while ($str =~ s{<([bisu]|big|su[bp]|small|tt|span)(${attrsRE})>[^<>]*}{}) { + $is_xml = 1; + my ($tag, $attrs) = ($1, $2); + if ($tag eq 'span') { + $attrs =~ s/${span_attr}*//g; + if ($attrs ne '') { + $attrs =~ s/\A *//; + $attrs =~ s/\\"/"/g; + po_error("Unexpected attributes `$attrs'"); + return 0; + } + } else { + if ($attrs !~ /\A *\Z/) { + po_error("<$tag> can't have attributes in Pango"); + return 0; + } + } + } + + # Check for attributes etc. in non- element. + if ($str =~ m{<([bisu]|big|su[bp]|small|tt)\b(?! *)>}) { + po_error("Unexpected characters in <$1> tag"); + return 0; + } + + if ($str =~ m{<([bisu]|big|su[bp]|small|span|tt)${attrsRE}>}) { + po_error("unclosed <$1>"); + return 0; + } + + if ($str =~ m{}) { + po_error("Unmatched closing "); + return 0; + } + + if (!$is_xml) { + $str =~ s/<(?:defs|image|rect|svg)>//g; + $str =~ s/<[ 01]//g; + $str =~ s/\A>+//; + $str =~ s/<+\Z//; + $str =~ s/\([<>][01]\)//g; + $str =~ s/ -> //g; + + # Quoting. + $str =~ s/\[[<>]\]//g; + $str =~ s/\\"[<>]\\"//g; + $str =~ s/\xe2\x80\x9e[<>]\xe2\x80\x9c//g; + $str =~ s/\xc2\xab[<>]\xc2\xbb//; + } + + $str =~ s/\A[^<>]*//; + $str =~ s/[^<>]*\Z//; + + if ($str =~ /\A([<>])\Z/) { + if ($is_xml) { + po_error("Unescaped `$1'"); + return 0; + } else { + return 1; + } + } + + if ($str ne '') { + po_error("parsing error for `$str'"); + return 0; + } + + return 1; +} + +sub check_strs (@) { + if ($#_ < 1) { + die "check_strs: expecting >= 2 strings"; + } + if ((($_[0] eq '""') && ($_[1] =~ /Project-Id-Version:.*POT-Creation-Date:/s)) + or ($_[0] eq '"> and < scale by:"')) { + # Not a Pango string. + return 1; + } + foreach my $str (@_) { + $str eq '""' or check_str($str) or return 0; + } + return 1; +} + +$/ = ''; + +# Reference for the markup language: +# http://developer.gnome.org/doc/API/2.0/pango/PangoMarkupFormat.html +# (though not all translation strings will be pango markup strings). +ENTRY: while(<>) { + if (m{\A${com}*\Z}) { + next ENTRY; + } + + s/"\n"//g; + + if (!m{\A${com}*msgid[^\n]*\n${com}*msgstr[^\n]*\n${com}*\Z} && + !m{\A${com}*msgid[^\n]*\n${com}*msgid_plural[^\n]*\n${com}*(msgstr\[[^\n]*\n${com}*)+\Z}) { + po_error('Not in msg format'); + next ENTRY; + } + if (!m{\A${com}*msgid ${str}\s*\n${com}*msgstr ${str}\s*\n${com}*\Z} && + !m{\A${com}*msgid ${str}\s*\n${com}*msgid_plural ${str}\s*\n${com}*(msgstr\[\d+\] ${str}\s*\n${com}*)+\Z}) { + po_error('Mismatched quotes'); + next ENTRY; + } + + if (m{\n\#,\ fuzzy}) { + # Fuzzy entries aren't used, so ignore them. + # (This prevents warnings about mismatching <>/ pattern.) + next ENTRY; + } + + if (m{\A${com}*msgid\ (${str})\n + ${com}*msgstr\ (${str})\n + ${com}*\Z}x) { + check_strs($1, $2) or next ENTRY; + } + elsif (m{\A${com}*msgid\ (${str})\n + ${com}*msgid_plural\ (${str})\n + ((?:${com}*msgstr\[\d+\]\ ${str}\n${com}*)+)\Z}x) { + my ($s1, $s2, $rest) = ($1, $2, $3); + my @strs = ($s1, $s2); + while ($rest =~ s/\A${com}*msgstr\[\d+\]\ (${str})\n${com}*//) { + push @strs, ($1); + } + $rest eq '' or die "BUG: unparsed plural entries `$rest'"; + check_strs(@strs) or next ENTRY; + } + elsif (m{$str[ \t]}) { + po_error('Trailing whitespace'); + next ENTRY; + } else { + po_error("parse error; may be a bug in po/check-markup"); + } +} + +# Some makefiles (currently the top-level Makefile.am) expect this script to +# exit 1 if any problems found. +exit $rc; diff --git a/po/cs.po b/po/cs.po new file mode 100644 index 000000000..197d20260 --- /dev/null +++ b/po/cs.po @@ -0,0 +1,9518 @@ +# Translation of Inkscape to Czech +# This file is distributed under the same license as the Inkscape package. +# Copyright (C) 2003 Free Software Foundation +# Josef Vybiral , 2005. +# +# +msgid "" +msgstr "" +"Project-Id-Version: Inkscape 0.41\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2005-12-04 11:51-0800\n" +"PO-Revision-Date: 2005-11-13 11:52+0100\n" +"Last-Translator: Josef Vybíral \n" +"Language-Team: Czech \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../inkscape.desktop.in.h:1 +msgid "Create and edit Scalable Vector Graphics images" +msgstr "Vytvářejte a upravujte vektorovou grafiku (SVG)" + +#: ../inkscape.desktop.in.h:2 +msgid "Inkscape SVG Vector Illustrator" +msgstr "Inkscape SVG Vektorový Ilustrátor" + +#: ../../po/../src/arc-context.cpp:350 +msgid "" +"Ctrl: make circle or integer-ratio ellipse, snap arc/segment angle" +msgstr "" +"Ctrl: udělá kružnici nebo elipsu s celočíselným poměrem stran, " +"způsobí skoky úhlu při tvorbě oblouků/segmentů" + +#: ../../po/../src/arc-context.cpp:351 ../../po/../src/rect-context.cpp:388 +msgid "Shift: draw around the starting point" +msgstr "Shift: kreslit kolem počátečního bodu" + +#: ../../po/../src/arc-context.cpp:413 +#: ../../po/../src/connector-context.cpp:493 +#: ../../po/../src/dyna-draw-context.cpp:506 +#: ../../po/../src/pen-context.cpp:329 ../../po/../src/pencil-context.cpp:208 +#: ../../po/../src/rect-context.cpp:452 ../../po/../src/spiral-context.cpp:421 +#: ../../po/../src/star-context.cpp:427 +msgid "Current layer is hidden. Unhide it to be able to draw on it." +msgstr "" +"Aktuální vrstva je skrytá. Zviditelněte ji aby jste do ní mohli " +"kreslit." + +#: ../../po/../src/arc-context.cpp:417 +#: ../../po/../src/connector-context.cpp:497 +#: ../../po/../src/dyna-draw-context.cpp:510 +#: ../../po/../src/pen-context.cpp:336 ../../po/../src/pencil-context.cpp:212 +#: ../../po/../src/rect-context.cpp:456 ../../po/../src/spiral-context.cpp:426 +#: ../../po/../src/star-context.cpp:431 +msgid "Current layer is locked. Unlock it to be able to draw on it." +msgstr "" +"Aktuální vrstva je uzamčena. Odemkněte ji aby jste do ní mohli " +"kreslit." + +#: ../../po/../src/arc-context.cpp:496 +#, c-format +msgid "" +"Ellipse: %s × %s; with Ctrl to make circle or integer-" +"ratio ellipse; with Shift to draw around the starting point" +msgstr "" +"Elipsa: %s × %s; s Ctrl se vytvoří kružnici nebo elipsu s " +"celočíselným poměrem stran; s Shift se vykreslí kolem počátku" + +#: ../../po/../src/connector-context.cpp:518 +msgid "Creating new connector" +msgstr "Vytvářím nový konektor" + +#: ../../po/../src/connector-context.cpp:939 +msgid "Finishing connector" +msgstr "Dokončuji konektor" + +#: ../../po/../src/connector-context.cpp:1108 +#, fuzzy +msgid "Connection point: click or drag to create a new connector" +msgstr "Bod napojení: kliknutím nebo tažením vytvoříte nový konektor" + +#: ../../po/../src/connector-context.cpp:1185 +#, fuzzy +msgid "Connector endpoint: drag to reroute or connect to new shapes" +msgstr "" +"Koncový bod konektoru: přetažením dojde k přesměrování nebo k " +"propojení nových tvarů" + +#: ../../po/../src/connector-context.cpp:1278 +msgid "Select at least one non-connector object." +msgstr "Vyberte nejméně jeden objekt, který není konektorem." + +#: ../../po/../src/desktop-events.cpp:238 +#, c-format +msgid "%s at %s" +msgstr "%s na %s" + +#. TRANSLATORS: This string appears when double-clicking on a guide. +#. This is the distance by which the guide is to be moved. +#: ../../po/../src/desktop-events.cpp:277 +msgid " relative by " +msgstr " relativně po " + +#. TRANSLATORS: This string appears when double-clicking on a guide. +#. This is the target location where the guide is to be moved. +#: ../../po/../src/desktop-events.cpp:282 +#: ../../po/../src/desktop-events.cpp:395 +msgid " absolute to " +msgstr " absolutně k " + +#. create dialog +#: ../../po/../src/desktop-events.cpp:348 +msgid "Guideline" +msgstr "Vodítko" + +#: ../../po/../src/desktop-events.cpp:432 +#, c-format +msgid "Move %s" +msgstr "Přesun %s" + +#: ../../po/../src/desktop.cpp:678 +msgid "No previous zoom." +msgstr "Žádné předchozí hodnoty přiblížení." + +#: ../../po/../src/desktop.cpp:703 +msgid "No next zoom." +msgstr "Žádné další hodnoty přiblížení." + +#: ../../po/../src/dialogs/clonetiler.cpp:182 +msgid "Nothing selected." +msgstr "Není nic vybráno." + +#: ../../po/../src/dialogs/clonetiler.cpp:188 +msgid "More than one object selected." +msgstr "Vybrán více než jeden objekt." + +#: ../../po/../src/dialogs/clonetiler.cpp:195 +#, c-format +msgid "Object has %d tiled clones." +msgstr "Objekt má %d dlážděných klonů." + +#: ../../po/../src/dialogs/clonetiler.cpp:200 +msgid "Object has no tiled clones." +msgstr "Objekt nemá dlážděné klony." + +#: ../../po/../src/dialogs/clonetiler.cpp:865 +msgid "Select one object whose tiled clones to unclump." +msgstr "Vyberte jeden objekt jehož dlážděné klony se mají rozházet." + +#: ../../po/../src/dialogs/clonetiler.cpp:916 +msgid "Select one object whose tiled clones to remove." +msgstr "Vyberte jeden objekt jehož dlaždicové klony se mají odstranit." + +#: ../../po/../src/dialogs/clonetiler.cpp:984 +#: ../../po/../src/selection-chemistry.cpp:1774 +msgid "Select an object to clone." +msgstr "Vyberte objekt ke klonování." + +#: ../../po/../src/dialogs/clonetiler.cpp:990 +#: ../../po/../src/selection-chemistry.cpp:1780 +msgid "" +"If you want to clone several objects, group them and clone the " +"group." +msgstr "" +"Pokud chcete klonovat několik objektů, seskupte je a klonujte " +"skupinu." + +#: ../../po/../src/dialogs/clonetiler.cpp:1484 +msgid "Per row:" +msgstr "Na řádek:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1497 +msgid "Per column:" +msgstr "Na sloupec:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1505 +msgid "Randomize:" +msgstr "Náhodně:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1656 +msgid "_Symmetry" +msgstr "_Symetrie" + +#. TRANSLATORS: For the following 17 symmetry groups, see +#. * http://www.bib.ulb.ac.be/coursmath/doc/17.htm (visual examples); +#. * http://www.clarku.edu/~djoyce/wallpaper/seventeen.html (English vocabulary); or +#. * http://membres.lycos.fr/villemingerard/Geometri/Sym1D.htm (French vocabulary). +#. +#: ../../po/../src/dialogs/clonetiler.cpp:1664 +msgid "Select one of the 17 symmetry groups for the tiling" +msgstr "Vyberte jednu ze 17 skupin symetrie pro dláždění" + +#. TRANSLATORS: "translation" means "shift" / "displacement" here. +#: ../../po/../src/dialogs/clonetiler.cpp:1675 +msgid "P1: simple translation" +msgstr "P1: jednoduchý posuv" + +#: ../../po/../src/dialogs/clonetiler.cpp:1676 +msgid "P2: 180° rotation" +msgstr "P2: rotace o 180°" + +#: ../../po/../src/dialogs/clonetiler.cpp:1677 +msgid "PM: reflection" +msgstr "PM: zrcadlení" + +#. TRANSLATORS: "glide reflection" is a reflection and a translation combined. +#. For more info, see http://mathforum.org/sum95/suzanne/symsusan.html +#: ../../po/../src/dialogs/clonetiler.cpp:1680 +msgid "PG: glide reflection" +msgstr "PG: posun zrcadlení" + +#: ../../po/../src/dialogs/clonetiler.cpp:1681 +msgid "CM: reflection + glide reflection" +msgstr "CM: zrcadlení + posun zrcadlení" + +#: ../../po/../src/dialogs/clonetiler.cpp:1682 +msgid "PMM: reflection + reflection" +msgstr "PMM: zrcadlení + zrcadlení" + +#: ../../po/../src/dialogs/clonetiler.cpp:1683 +msgid "PMG: reflection + 180° rotation" +msgstr "PMG: zrcadlení + rotace o 180°" + +#: ../../po/../src/dialogs/clonetiler.cpp:1684 +msgid "PGG: glide reflection + 180° rotation" +msgstr "PGG: posun zrcadlení + rotace o 180°" + +#: ../../po/../src/dialogs/clonetiler.cpp:1685 +msgid "CMM: reflection + reflection + 180° rotation" +msgstr "CMM: zrcadlení + zrcadlení + rotace o 180°" + +#: ../../po/../src/dialogs/clonetiler.cpp:1686 +msgid "P4: 90° rotation" +msgstr "P4: rotace o 90°" + +#: ../../po/../src/dialogs/clonetiler.cpp:1687 +msgid "P4M: 90° rotation + 45° reflection" +msgstr "P4M: rotace o 90° + 45° zrcadlení" + +#: ../../po/../src/dialogs/clonetiler.cpp:1688 +msgid "P4G: 90° rotation + 90° reflection" +msgstr "P4G: rotace o 90° + 90° zrcadlení" + +#: ../../po/../src/dialogs/clonetiler.cpp:1689 +msgid "P3: 120° rotation" +msgstr "P3: rotace o 120°" + +#: ../../po/../src/dialogs/clonetiler.cpp:1690 +msgid "P31M: reflection + 120° rotation, dense" +msgstr "P31M: zrcadlení + rotace o 120°, hustě" + +#: ../../po/../src/dialogs/clonetiler.cpp:1691 +msgid "P3M1: reflection + 120° rotation, sparse" +msgstr "P31M: zrcadlení + rotace o 120°, rozptýleně" + +#: ../../po/../src/dialogs/clonetiler.cpp:1692 +msgid "P6: 60° rotation" +msgstr "P6: rotace o 60°" + +#: ../../po/../src/dialogs/clonetiler.cpp:1693 +msgid "P6M: reflection + 60° rotation" +msgstr "P6M: zrcadlení + rotace o 60°" + +#: ../../po/../src/dialogs/clonetiler.cpp:1721 +msgid "S_hift" +msgstr "Posun" + +#. TRANSLATORS: "shift" means: the tiles will be shifted (offset) horizontally by this amount +#: ../../po/../src/dialogs/clonetiler.cpp:1731 +#, no-c-format +msgid "Shift X:" +msgstr "Posun X:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1739 +#, no-c-format +msgid "Horizontal shift per row (in % of tile width)" +msgstr "Vodorovný posun na řádek (v % šířky dlaždice)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1747 +#, no-c-format +msgid "Horizontal shift per column (in % of tile width)" +msgstr "Vodorovný posun na sloupec (v % šířky dlaždice)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1754 +msgid "Randomize the horizontal shift by this percentage" +msgstr "Provést náhodnou změnu vodorovného posunu o tato procenta" + +#. TRANSLATORS: "shift" means: the tiles will be shifted (offset) vertically by this amount +#: ../../po/../src/dialogs/clonetiler.cpp:1764 +#, no-c-format +msgid "Shift Y:" +msgstr "Posun Y:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1772 +#, no-c-format +msgid "Vertical shift per row (in % of tile height)" +msgstr "Svislý posun na řádek (v % šířky dlaždice)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1780 +#, no-c-format +msgid "Vertical shift per column (in % of tile height)" +msgstr "Svislý posun na sloupec (v % šířky dlaždice)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1787 +msgid "Randomize the vertical shift by this percentage" +msgstr "Provést náhodnou změnu svislého posunu o tato procenta" + +#: ../../po/../src/dialogs/clonetiler.cpp:1795 +msgid "Exponent:" +msgstr "Exponent:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1802 +msgid "Whether rows are spaced evenly (1), converge (<1) or diverge (>1)" +msgstr "" +"Zda budou mezery mezi řádky rovnoměrné (1), sbíhavé (<1) nebo rozbíhavé (>1)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1809 +msgid "Whether columns are spaced evenly (1), converge (<1) or diverge (>1)" +msgstr "" +"Zda budou mezery mezi sloupci rovnoměrné (1), sbíhavé (<1) nebo rozbíhavé " +"(>1)" + +#. TRANSLATORS: "Alternate" is a verb here +#: ../../po/../src/dialogs/clonetiler.cpp:1817 +#: ../../po/../src/dialogs/clonetiler.cpp:1907 +#: ../../po/../src/dialogs/clonetiler.cpp:1966 +#: ../../po/../src/dialogs/clonetiler.cpp:2022 +#: ../../po/../src/dialogs/clonetiler.cpp:2153 +msgid "Alternate:" +msgstr "Střídat:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1823 +msgid "Alternate the sign of shifts for each row" +msgstr "Měnit znaménko posunu v každém řádku" + +#: ../../po/../src/dialogs/clonetiler.cpp:1828 +msgid "Alternate the sign of shifts for each column" +msgstr "Měnit znaménko posunu v každém sloupci" + +#: ../../po/../src/dialogs/clonetiler.cpp:1837 +msgid "Sc_ale" +msgstr "Měřítko" + +#: ../../po/../src/dialogs/clonetiler.cpp:1845 +msgid "Scale X:" +msgstr "Měřítko X:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1853 +#, no-c-format +msgid "Horizontal scale per row (in % of tile width)" +msgstr "Vodorovná změna měřítka na řádek (v % šířky dlaždice)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1861 +#, no-c-format +msgid "Horizontal scale per column (in % of tile width)" +msgstr "Vodorovná změna měřítka na sloupec (v % šířky dlaždice)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1868 +msgid "Randomize the horizontal scale by this percentage" +msgstr "Provést náhodnou změnu vodorovného měřítka o tato procenta" + +#: ../../po/../src/dialogs/clonetiler.cpp:1876 +msgid "Scale Y:" +msgstr "Měřítko Y:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1884 +#, no-c-format +msgid "Vertical scale per row (in % of tile height)" +msgstr "Svislá změna měřítka na řádek (v % šířky dlaždice)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1892 +#, no-c-format +msgid "Vertical scale per column (in % of tile height)" +msgstr "Svislá změna měřítka na sloupec (v % šířky dlaždice)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1899 +msgid "Randomize the vertical scale by this percentage" +msgstr "Provést náhodnou změnu svislého měřítka o tato procenta" + +#: ../../po/../src/dialogs/clonetiler.cpp:1913 +msgid "Alternate the sign of scales for each row" +msgstr "Měnit znaménko změny měřítka v každém řádku" + +#: ../../po/../src/dialogs/clonetiler.cpp:1918 +msgid "Alternate the sign of scales for each column" +msgstr "Měnit znaménko změny měřítka v každém sloupci" + +#: ../../po/../src/dialogs/clonetiler.cpp:1927 +msgid "_Rotation" +msgstr "_Rotace" + +#: ../../po/../src/dialogs/clonetiler.cpp:1935 +msgid "Angle:" +msgstr "Úhel:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1943 +#, no-c-format +msgid "Rotate tiles by this angle for each row" +msgstr "Otáčet dlaždice o tento úhel v každé řadě" + +#: ../../po/../src/dialogs/clonetiler.cpp:1951 +#, no-c-format +msgid "Rotate tiles by this angle for each column" +msgstr "Otáčet dlaždice o tento úhel v každém sloupci" + +#: ../../po/../src/dialogs/clonetiler.cpp:1958 +msgid "Randomize the rotation angle by this percentage" +msgstr "Provést náhodnou změnu úhlu natočení o tato procenta" + +#: ../../po/../src/dialogs/clonetiler.cpp:1972 +msgid "Alternate the rotation direction for each row" +msgstr "Zaměnit směr otáčení pro každý řádek" + +#: ../../po/../src/dialogs/clonetiler.cpp:1977 +msgid "Alternate the rotation direction for each column" +msgstr "Zaměnit směr otáčení pro každý sloupec" + +#: ../../po/../src/dialogs/clonetiler.cpp:1985 +msgid "_Opacity" +msgstr "Krytí" + +#: ../../po/../src/dialogs/clonetiler.cpp:1993 +msgid "Fade out:" +msgstr "Blednutí:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2000 +msgid "Decrease tile opacity by this percentage for each row" +msgstr "Snížit krytí dlaždice o tato procenta na každý řádek" + +#: ../../po/../src/dialogs/clonetiler.cpp:2007 +msgid "Decrease tile opacity by this percentage for each column" +msgstr "Snížit krytí dlaždice o tato procenta na každý sloupec" + +#: ../../po/../src/dialogs/clonetiler.cpp:2014 +msgid "Randomize the tile opacity by this percentage" +msgstr "Provést náhodnou změnu krytí dlaždice o tato procenta" + +#: ../../po/../src/dialogs/clonetiler.cpp:2028 +msgid "Alternate the sign of opacity change for each row" +msgstr "Měnit znaménko změny průhlednosti v každém řádku" + +#: ../../po/../src/dialogs/clonetiler.cpp:2033 +msgid "Alternate the sign of opacity change for each column" +msgstr "Měnit znaménko změny průhlednosti v každém sloupci" + +#: ../../po/../src/dialogs/clonetiler.cpp:2041 +msgid "Co_lor" +msgstr "Barva" + +#: ../../po/../src/dialogs/clonetiler.cpp:2046 +msgid "Initial color: " +msgstr "Počáteční barva:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2050 +msgid "Initial color of tiled clones" +msgstr "Počáteční barva dlaždicových klonů" + +#: ../../po/../src/dialogs/clonetiler.cpp:2050 +msgid "" +"Initial color for clones (works only if the original has unset fill or " +"stroke)" +msgstr "" +"Počáteční barva pro klony (funguje pouze tehdy, nemá-li originál nastavenu " +"výplň nebo okraje)" + +#: ../../po/../src/dialogs/clonetiler.cpp:2065 +msgid "H:" +msgstr "H:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2072 +msgid "Change the tile hue by this percentage for each row" +msgstr "Změnit odstín barvy o tato procenta na každý řádek" + +#: ../../po/../src/dialogs/clonetiler.cpp:2079 +msgid "Change the tile hue by this percentage for each column" +msgstr "Změnit odstín barvy o tato procenta na každý sloupec" + +#: ../../po/../src/dialogs/clonetiler.cpp:2086 +msgid "Randomize the tile hue by this percentage" +msgstr "Provést náhodnou změnu odstínu dlaždice o tato procenta" + +#: ../../po/../src/dialogs/clonetiler.cpp:2095 +msgid "S:" +msgstr "S:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2102 +msgid "Change the color saturation by this percentage for each row" +msgstr "Změnit nasycení barvy o tato procenta na každý řádek" + +#: ../../po/../src/dialogs/clonetiler.cpp:2109 +msgid "Change the color saturation by this percentage for each column" +msgstr "Změnit nasycení barvy o tato procenta na každý sloupec" + +#: ../../po/../src/dialogs/clonetiler.cpp:2116 +msgid "Randomize the color saturation by this percentage" +msgstr "Provést náhodnou změnu nasycení barvy o tato procenta" + +#: ../../po/../src/dialogs/clonetiler.cpp:2124 +msgid "L:" +msgstr "L:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2131 +msgid "Change the color lightness by this percentage for each row" +msgstr "Změnit jas barvy o tato procenta na každý řádek" + +#: ../../po/../src/dialogs/clonetiler.cpp:2138 +msgid "Change the color lightness by this percentage for each column" +msgstr "Změnit jas barvy o tato procenta na každý sloupec" + +#: ../../po/../src/dialogs/clonetiler.cpp:2145 +msgid "Randomize the color lightness by this percentage" +msgstr "Provést náhodnou změnu jasu barvy o tato procenta" + +#: ../../po/../src/dialogs/clonetiler.cpp:2159 +msgid "Alternate the sign of color changes for each row" +msgstr "Měnit znaménko změny barvy v každém řádku" + +#: ../../po/../src/dialogs/clonetiler.cpp:2164 +msgid "Alternate the sign of color changes for each column" +msgstr "Měnit znaménko změny barvy v každém sloupci" + +#: ../../po/../src/dialogs/clonetiler.cpp:2172 +msgid "_Trace" +msgstr "_Trasování" + +#: ../../po/../src/dialogs/clonetiler.cpp:2179 +msgid "Trace the drawing under the tiles" +msgstr "Trasovat kresbu pod dlaždicemi" + +#: ../../po/../src/dialogs/clonetiler.cpp:2183 +msgid "" +"For each clone, pick a value from the drawing in that clone's location and " +"apply it to the clone" +msgstr "" +"Vybrat hodnotu z kresby pro každý klon v místě jeho umístění aplikovat na " +"klon" + +#: ../../po/../src/dialogs/clonetiler.cpp:2197 +msgid "1. Pick from the drawing:" +msgstr "1. Nabrat z kresby:" + +#. ----Hbox2 +#: ../../po/../src/dialogs/clonetiler.cpp:2208 +#: ../../po/../src/dialogs/clonetiler.cpp:2355 +#: ../../po/../src/ui/dialog/tracedialog.cpp:445 +msgid "Color" +msgstr "Barva" + +#: ../../po/../src/dialogs/clonetiler.cpp:2209 +msgid "Pick the visible color and opacity" +msgstr "Získat viditelnou barvu a krytí" + +#: ../../po/../src/dialogs/clonetiler.cpp:2216 +#: ../../po/../src/dialogs/clonetiler.cpp:2365 +#: ../share/extensions/dropshadow.inx.h:3 +msgid "Opacity" +msgstr "Krytí" + +#: ../../po/../src/dialogs/clonetiler.cpp:2217 +msgid "Pick the total accumulated opacity" +msgstr "Nabrat celkové nastřádané krytí" + +#: ../../po/../src/dialogs/clonetiler.cpp:2224 +msgid "R" +msgstr "R" + +#: ../../po/../src/dialogs/clonetiler.cpp:2225 +msgid "Pick the Red component of the color" +msgstr "Nabrat červenou složku barvy" + +#: ../../po/../src/dialogs/clonetiler.cpp:2232 +msgid "G" +msgstr "G" + +#: ../../po/../src/dialogs/clonetiler.cpp:2233 +msgid "Pick the Green component of the color" +msgstr "Nabrat zelenou složku barvy" + +#: ../../po/../src/dialogs/clonetiler.cpp:2240 +msgid "B" +msgstr "B" + +#: ../../po/../src/dialogs/clonetiler.cpp:2241 +msgid "Pick the Blue component of the color" +msgstr "Nabrat modrou složku barvy" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2250 +msgid "clonetiler|H" +msgstr "clonetiler|H" + +#: ../../po/../src/dialogs/clonetiler.cpp:2251 +msgid "Pick the hue of the color" +msgstr "Nabrat odstín barvy" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2260 +msgid "clonetiler|S" +msgstr "clonetiler|S" + +#: ../../po/../src/dialogs/clonetiler.cpp:2261 +msgid "Pick the saturation of the color" +msgstr "Nabrat sytost barvy" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2270 +msgid "clonetiler|L" +msgstr "clonetiler|L" + +#: ../../po/../src/dialogs/clonetiler.cpp:2271 +msgid "Pick the lightness of the color" +msgstr "Nabrat jas barvy" + +#: ../../po/../src/dialogs/clonetiler.cpp:2281 +msgid "2. Tweak the picked value:" +msgstr "2. Upravit nabranou hodnotu:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2291 +msgid "Gamma-correct:" +msgstr "Gamma-korekce:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2296 +msgid "Shift the mid-range of the picked value upwards (>0) or downwards (<0)" +msgstr "Posunout střední rozsah nabrané hodnoty nahoru (>0) nebo dolů (<0)" + +#: ../../po/../src/dialogs/clonetiler.cpp:2303 +msgid "Randomize:" +msgstr "Nepravidelnost:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2308 +msgid "Randomize the picked value by this percentage" +msgstr "Provést náhodnou nabrané hodnoty o tato procenta" + +#: ../../po/../src/dialogs/clonetiler.cpp:2315 +msgid "Invert:" +msgstr "Invertovat:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2319 +msgid "Invert the picked value" +msgstr "Invertovat získanou hodnotu" + +#: ../../po/../src/dialogs/clonetiler.cpp:2325 +msgid "3. Apply the value to the clones':" +msgstr "3. Aplikovat hodnotu na klony:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2335 +msgid "Presence" +msgstr "Umístění" + +#: ../../po/../src/dialogs/clonetiler.cpp:2338 +msgid "" +"Each clone is created with the probability determined by the picked value in " +"that point" +msgstr "" +"Každý klon je vytvořen s pravděpodobností zjiÅ¡těnou podle hodnoty nabrané v " +"daném bodě" + +#: ../../po/../src/dialogs/clonetiler.cpp:2345 +msgid "Size" +msgstr "Velikost" + +#: ../../po/../src/dialogs/clonetiler.cpp:2348 +msgid "Each clone's size is determined by the picked value in that point" +msgstr "Pozice každého klonu je určena hodnotou nabranou v daném bodě" + +#: ../../po/../src/dialogs/clonetiler.cpp:2358 +msgid "" +"Each clone is painted by the picked color (the original must have unset fill " +"or stroke)" +msgstr "" +"Každý klon je vybarven nabranou barvou (originál nesmí mít nastavenu výplň " +"nebo okraj)" + +#: ../../po/../src/dialogs/clonetiler.cpp:2368 +msgid "Each clone's opacity is determined by the picked value in that point" +msgstr "Stupeň krytí každého klonu je určen získanou hodnotou v daném bodě" + +#: ../../po/../src/dialogs/clonetiler.cpp:2395 +msgid "How many rows in the tiling" +msgstr "Kolik řádků dlaždic" + +#: ../../po/../src/dialogs/clonetiler.cpp:2415 +msgid "How many columns in the tiling" +msgstr "Kolik sloupců dlaždic" + +#: ../../po/../src/dialogs/clonetiler.cpp:2445 +msgid "Width of the rectangle to be filled" +msgstr "Šířka čtyřúhelníku k vyplnění" + +#: ../../po/../src/dialogs/clonetiler.cpp:2470 +msgid "Height of the rectangle to be filled" +msgstr "Výška čtyřúhelníku k vyplnění" + +#: ../../po/../src/dialogs/clonetiler.cpp:2485 +msgid "Rows, columns: " +msgstr "Řádky, sloupce:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2486 +msgid "Create the specified number of rows and columns" +msgstr "Vytvořit určený počet řádků a sloupců" + +#: ../../po/../src/dialogs/clonetiler.cpp:2495 +msgid "Width, height: " +msgstr "Šířka, výška:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2496 +msgid "Fill the specified width and height with the tiling" +msgstr "Vyplnit určenou šířku a výšku dlaždicemi" + +#: ../../po/../src/dialogs/clonetiler.cpp:2512 +msgid "Use saved size and position of the tile" +msgstr "Použít uloženou velikost a pozici dlaždice" + +#: ../../po/../src/dialogs/clonetiler.cpp:2515 +msgid "" +"Pretend that the size and position of the tile are the same as the last time " +"you tiled it (if any), instead of using the current size" +msgstr "" +"Předstírat, že velikost a pozice dlaždice jsou stejné jako při posledním " +"použití (pokud bylo), místo použití současných hodnot" + +#: ../../po/../src/dialogs/clonetiler.cpp:2539 +msgid " _Create " +msgstr " Vytvořit " + +#: ../../po/../src/dialogs/clonetiler.cpp:2541 +msgid "Create and tile the clones of the selection" +msgstr "Vytvořit a dláždit klony výběru" + +#. TRANSLATORS: if a group of objects are "clumped" together, then they +#. are unevenly spread in the given amount of space - as shown in the +#. diagrams on the left in the following screenshot: +#. http://www.inkscape.org/screenshots/gallery/inkscape-0.42-CVS-tiles-unclump.png +#. So unclumping is the process of spreading a number of objects out more evenly. +#: ../../po/../src/dialogs/clonetiler.cpp:2556 +msgid " _Unclump " +msgstr "Rozházet" + +#: ../../po/../src/dialogs/clonetiler.cpp:2557 +msgid "Spread out clones to reduce clumping; can be applied repeatedly" +msgstr "Rozptýlit klony a zmenÅ¡it tím jejich nakupení; Lze aplikovat opakovaně" + +#: ../../po/../src/dialogs/clonetiler.cpp:2563 +msgid " Re_move " +msgstr " Odstranit " + +#: ../../po/../src/dialogs/clonetiler.cpp:2564 +msgid "Remove existing tiled clones of the selected object (siblings only)" +msgstr "" +"Odstranit existující dlážděné klony vybraných objektů (pouze sourozence)" + +#: ../../po/../src/dialogs/clonetiler.cpp:2580 +msgid " R_eset " +msgstr " Obnovit " + +#. TRANSLATORS: "change" is a noun here +#: ../../po/../src/dialogs/clonetiler.cpp:2582 +msgid "" +"Reset all shifts, scales, rotates, opacity and color changes in the dialog " +"to zero" +msgstr "Vynulovat vÅ¡echny posuny, změny měřítka, otočení a změny průhlednosti" + +#: ../../po/../src/dialogs/color-picker.cpp:280 +msgid "Close" +msgstr "Zavřít" + +#: ../../po/../src/dialogs/debugdialog.cpp:138 +msgid "Messages" +msgstr "Zprávy" + +#. ## Add a menu for clear() +#: ../../po/../src/dialogs/debugdialog.cpp:144 +#: ../../po/../src/menus-skeleton.h:16 +#: ../../po/../src/ui/dialog/messages.cpp:56 +#: ../../po/../src/ui/dialog/scriptdialog.cpp:181 +msgid "_File" +msgstr "_Soubor" + +#. TRANSLATORS: "Clear" is a verb here +#: ../../po/../src/dialogs/debugdialog.cpp:145 +#: ../../po/../src/dialogs/find.cpp:753 +#: ../../po/../src/ui/dialog/messages.cpp:57 +#: ../../po/../src/ui/dialog/scriptdialog.cpp:182 +msgid "_Clear" +msgstr "Vyčistit" + +#: ../../po/../src/dialogs/debugdialog.cpp:147 +#: ../../po/../src/ui/dialog/messages.cpp:59 +msgid "Capture log messages" +msgstr "Zachytávat zprávy logu" + +#: ../../po/../src/dialogs/debugdialog.cpp:149 +#: ../../po/../src/ui/dialog/messages.cpp:61 +msgid "Release log messages" +msgstr "Zprávy záznamu o vydání" + +#. Notebook tab +#: ../../po/../src/dialogs/desktop-properties.cpp:909 +#: ../../po/../src/ui/dialog/document-preferences.cpp:89 +#: ../../po/../src/ui/widget/panel.cpp:107 +msgid "Grid" +msgstr "Mřížka" + +#. Checkbuttons +#. / \todo FIXME: gray out snapping when grid is off +#. / \todo FIXME: gray out snapping when grid is off. +#. / Dissenting view: you want snapping without grid. +#: ../../po/../src/dialogs/desktop-properties.cpp:917 +#: ../../po/../src/ui/dialog/document-preferences.cpp:179 +msgid "Show grid" +msgstr "Zobrazit mřížku" + +#: ../../po/../src/dialogs/desktop-properties.cpp:917 +#: ../../po/../src/ui/dialog/document-preferences.cpp:179 +#: ../../po/../src/verbs.cpp:2115 +msgid "Show or hide grid" +msgstr "Zobrazit nebo skrýt mřížku" + +#: ../../po/../src/dialogs/desktop-properties.cpp:918 +#: ../../po/../src/ui/dialog/document-preferences.cpp:180 +msgid "Snap bounding boxes to grid" +msgstr "Přichytávat hranice objektu na mřížku" + +#: ../../po/../src/dialogs/desktop-properties.cpp:918 +#: ../../po/../src/dialogs/desktop-properties.cpp:1001 +#: ../../po/../src/ui/dialog/document-preferences.cpp:181 +#: ../../po/../src/ui/dialog/document-preferences.cpp:236 +msgid "Snap the edges of the object bounding boxes" +msgstr "Přichytávat okraje hranic objektu" + +#: ../../po/../src/dialogs/desktop-properties.cpp:919 +#: ../../po/../src/ui/dialog/document-preferences.cpp:183 +msgid "Snap nodes to grid" +msgstr "Přichytávat uzly k mřížce" + +#: ../../po/../src/dialogs/desktop-properties.cpp:919 +#: ../../po/../src/dialogs/desktop-properties.cpp:1002 +#: ../../po/../src/ui/dialog/document-preferences.cpp:184 +#: ../../po/../src/ui/dialog/document-preferences.cpp:239 +msgid "Snap path nodes, text baselines, ellipse centers, etc." +msgstr "Přichytávat uzly křivek, základny textů, středy elips, atd." + +#: ../../po/../src/dialogs/desktop-properties.cpp:937 +#: ../../po/../src/ui/dialog/document-preferences.cpp:186 +msgid "Grid units:" +msgstr "Jednotky mřížky:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:939 +#: ../../po/../src/ui/dialog/document-preferences.cpp:187 +msgid "Origin X:" +msgstr "Počátek X:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:942 +#: ../../po/../src/ui/dialog/document-preferences.cpp:189 +msgid "Origin Y:" +msgstr "Počátek Y:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:945 +#: ../../po/../src/ui/dialog/document-preferences.cpp:191 +msgid "Spacing X:" +msgstr "Mezery X:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:948 +#: ../../po/../src/ui/dialog/document-preferences.cpp:193 +msgid "Spacing Y:" +msgstr "Mezery Y:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:952 +#: ../../po/../src/dialogs/desktop-properties.cpp:1013 +#: ../../po/../src/ui/dialog/document-preferences.cpp:195 +#: ../../po/../src/ui/dialog/document-preferences.cpp:241 +msgid "Snap units:" +msgstr "Jednotky uchycení:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:955 +#: ../../po/../src/dialogs/desktop-properties.cpp:1016 +#: ../../po/../src/ui/dialog/document-preferences.cpp:196 +#: ../../po/../src/ui/dialog/document-preferences.cpp:242 +msgid "Snap distance:" +msgstr "Vzdálenost uchycení:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:958 +#: ../../po/../src/ui/dialog/document-preferences.cpp:199 +msgid "Grid line color:" +msgstr "Barva čar mřížky:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:959 +#: ../../po/../src/ui/dialog/document-preferences.cpp:199 +msgid "Grid line color" +msgstr "Barva čar mřížky" + +#: ../../po/../src/dialogs/desktop-properties.cpp:959 +#: ../../po/../src/ui/dialog/document-preferences.cpp:200 +msgid "Color of grid lines" +msgstr "Barva čar mřížky" + +#: ../../po/../src/dialogs/desktop-properties.cpp:961 +#: ../../po/../src/ui/dialog/document-preferences.cpp:201 +msgid "Major grid line color:" +msgstr "Barva hlavní čáry mřížky:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:962 +#: ../../po/../src/ui/dialog/document-preferences.cpp:201 +msgid "Major grid line color" +msgstr "Barva hlavních čar mřížky" + +#: ../../po/../src/dialogs/desktop-properties.cpp:962 +#: ../../po/../src/ui/dialog/document-preferences.cpp:202 +msgid "Color of the major (highlighted) grid lines" +msgstr "Barva významné (zvýrazněné) čáry mřížky" + +#: ../../po/../src/dialogs/desktop-properties.cpp:965 +#: ../../po/../src/ui/dialog/document-preferences.cpp:204 +msgid "Major grid line every:" +msgstr "Hlavní čára mřížky každých: " + +#. TRANSLATORS: This belongs to the "Major grid line every:" string, +#. see grid settings in the "Document Preferences" dialog +#: ../../po/../src/dialogs/desktop-properties.cpp:977 +#: ../../po/../src/ui/dialog/document-preferences.cpp:204 +msgid "lines" +msgstr "čar" + +#. Guidelines page +#: ../../po/../src/dialogs/desktop-properties.cpp:991 +#: ../../po/../src/ui/dialog/document-preferences.cpp:90 +msgid "Guides" +msgstr "Vodítka" + +#. / \todo FIXME: gray out snapping when guides are off +#. / Dissenting view: you want snapping without guides. +#: ../../po/../src/dialogs/desktop-properties.cpp:1000 +#: ../../po/../src/ui/dialog/document-preferences.cpp:234 +msgid "Show guides" +msgstr "Zobrazovat vodítka" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1000 +#: ../../po/../src/ui/dialog/document-preferences.cpp:234 +#: ../../po/../src/verbs.cpp:2116 +msgid "Show or hide guides" +msgstr "Zobrazit nebo skrýt vodítka" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1001 +#: ../../po/../src/ui/dialog/document-preferences.cpp:235 +msgid "Snap bounding boxes to guides" +msgstr "Přichytávat hranice objektu na vodítka" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1002 +#: ../../po/../src/ui/dialog/document-preferences.cpp:238 +msgid "Snap points to guides" +msgstr "Přichytávat body k mřížce" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1020 +#: ../../po/../src/ui/dialog/document-preferences.cpp:243 +msgid "Guide color:" +msgstr "Barva vodítek:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1021 +#: ../../po/../src/ui/dialog/document-preferences.cpp:243 +msgid "Guideline color" +msgstr "Barva čáry vodítka" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1021 +#: ../../po/../src/ui/dialog/document-preferences.cpp:244 +msgid "Color of guidelines" +msgstr "Barva vodících čar" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1023 +#: ../../po/../src/ui/dialog/document-preferences.cpp:245 +msgid "Highlight color:" +msgstr "Barva zvýraznění:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1024 +#: ../../po/../src/ui/dialog/document-preferences.cpp:245 +msgid "Highlighted guideline color" +msgstr "Barva zvýrazněného vodítka" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1024 +#: ../../po/../src/ui/dialog/document-preferences.cpp:246 +msgid "Color of a guideline when it is under mouse" +msgstr "Barva vodítka pokud je nad ním myÅ¡" + +#. Page page +#: ../../po/../src/dialogs/desktop-properties.cpp:1029 +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:855 +#: ../../po/../src/ui/dialog/document-preferences.cpp:88 +#: ../../po/../src/widgets/desktop-widget.cpp:1061 +msgid "Page" +msgstr "Strana" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1039 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +msgid "Background:" +msgstr "Barva pozadí:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1040 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +msgid "Background color" +msgstr "Barva pozadí" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1041 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +msgid "" +"Color and transparency of the page background (also used for bitmap export)" +msgstr "Barva a průsvitnost pozadí stránky (platí také pro export do bitmapy)" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1045 +#: ../../po/../src/ui/dialog/document-preferences.cpp:147 +#, fuzzy +msgid "Show page border" +msgstr "Zobrazovat ohraničení plátna" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1049 +#: ../../po/../src/ui/dialog/document-preferences.cpp:148 +msgid "Border on top of drawing" +msgstr "Okraj na horní straně obrázku" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1052 +#: ../../po/../src/ui/dialog/document-preferences.cpp:149 +msgid "Border color:" +msgstr "Barva okraje:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1053 +#: ../../po/../src/ui/dialog/document-preferences.cpp:149 +#, fuzzy +msgid "Page border color" +msgstr "Barva okraje plátna" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1054 +#: ../../po/../src/ui/dialog/document-preferences.cpp:150 +#, fuzzy +msgid "Color of the page border" +msgstr "Barva okraje plátna" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1059 +#: ../../po/../src/ui/dialog/document-preferences.cpp:152 +msgid "Show page shadow" +msgstr "Zobrazit stín stránky" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1063 +#: ../../po/../src/ui/dialog/document-preferences.cpp:153 +msgid "Default units:" +msgstr "Výchozí jednotky:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1069 +msgid "Units for the tool controls, ruler, and the statusbar" +msgstr "Jednotky pro nástroje, pravítka a stavový řádek" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1086 +#: ../../po/../src/ui/widget/page-sizer.cpp:209 +#, fuzzy +msgid "Page size:" +msgstr "Velikost plátna:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1110 +#: ../../po/../src/ui/widget/page-sizer.cpp:219 +msgid "Custom" +msgstr "Vlastní" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1121 +#: ../../po/../src/ui/widget/page-sizer.cpp:225 +#, fuzzy +msgid "Page orientation:" +msgstr "Orientace plátna:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1133 +#: ../../po/../src/ui/widget/page-sizer.cpp:232 +msgid "Landscape" +msgstr "Krajina" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1139 +#: ../../po/../src/ui/widget/page-sizer.cpp:234 +msgid "Portrait" +msgstr "Portrét" + +#. Custom paper frame +#: ../../po/../src/dialogs/desktop-properties.cpp:1148 +#: ../../po/../src/ui/widget/page-sizer.cpp:249 +#, fuzzy +msgid "Custom size" +msgstr "Vlastní" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1160 +#: ../../po/../src/dialogs/export.cpp:269 +#: ../../po/../src/ui/widget/page-sizer.cpp:261 +msgid "Units:" +msgstr "Jednotky:" + +#. Stroke width +#: ../../po/../src/dialogs/desktop-properties.cpp:1162 +#: ../../po/../src/dialogs/export.cpp:310 +#: ../../po/../src/dialogs/object-attributes.cpp:55 +#: ../../po/../src/dialogs/stroke-style.cpp:985 +#: ../../po/../src/ui/widget/page-sizer.cpp:262 +#: ../../po/../src/widgets/toolbox.cpp:1957 +msgid "Width:" +msgstr "Šířka:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1183 +#: ../../po/../src/dialogs/export.cpp:326 +#: ../../po/../src/dialogs/export.cpp:431 +#: ../../po/../src/dialogs/object-attributes.cpp:56 +#: ../../po/../src/ui/widget/page-sizer.cpp:263 +msgid "Height:" +msgstr "Výška:" + +#. +#. * Ownership metadata tab +#. +#: ../../po/../src/dialogs/desktop-properties.cpp:1206 +msgid "Metadata" +msgstr "Metadata" + +#. add license selector pull-down +#: ../../po/../src/dialogs/desktop-properties.cpp:1225 +msgid "License" +msgstr "Licence" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1255 +msgid "Proprietary" +msgstr "Proprietární" + +#: ../../po/../src/dialogs/display-settings.cpp:212 +msgid "When transforming, show:" +msgstr "Při transformaci objektu ukazovat:" + +#: ../../po/../src/dialogs/display-settings.cpp:223 +msgid "Objects" +msgstr "Objekty" + +#: ../../po/../src/dialogs/display-settings.cpp:224 +msgid "Show the actual objects when moving or transforming" +msgstr "Ukazovat objekty při přesunech či transformacích" + +#: ../../po/../src/dialogs/display-settings.cpp:231 +msgid "Box outline" +msgstr "Zobrazit kontury" + +#: ../../po/../src/dialogs/display-settings.cpp:232 +msgid "Show only a box outline of the objects when moving or transforming" +msgstr "Ukazovat pouze hranice objektu při přesunu nebo transformaci" + +#: ../../po/../src/dialogs/display-settings.cpp:238 +msgid "Per-object selection cue:" +msgstr "Označení vybraného objektu:" + +#. sorationsnapsperpi == 0 means no snapping +#: ../../po/../src/dialogs/display-settings.cpp:249 +#: ../../po/../src/dialogs/display-settings.cpp:386 +#: ../../po/../src/dialogs/display-settings.cpp:441 +#: ../../po/../src/dialogs/display-settings.cpp:1482 +#: ../../po/../src/dialogs/stroke-style.cpp:791 +#: ../../po/../src/interface.cpp:741 +#: ../../po/../src/ui/widget/selected-style.cpp:100 +#: ../../po/../src/verbs.cpp:1842 +msgid "None" +msgstr "Žádné" + +#: ../../po/../src/dialogs/display-settings.cpp:250 +msgid "No per-object selection indication" +msgstr "Nezobrazovat výběr u jednotlivých objektů" + +#: ../../po/../src/dialogs/display-settings.cpp:256 +msgid "Mark" +msgstr "Značky" + +#: ../../po/../src/dialogs/display-settings.cpp:257 +msgid "Each selected object has a diamond mark in the top left corner" +msgstr "Každý vybraný objekt má značku diamantu v levém horním rohu" + +#: ../../po/../src/dialogs/display-settings.cpp:264 +msgid "Box" +msgstr "Box" + +#: ../../po/../src/dialogs/display-settings.cpp:265 +msgid "Each selected object displays its bounding box" +msgstr "Každý vybraný objekt zobrazuje vlastní obrys" + +#: ../../po/../src/dialogs/display-settings.cpp:270 +msgid "Default scale origin:" +msgstr "Výchozí počátek měřítka:" + +#: ../../po/../src/dialogs/display-settings.cpp:281 +msgid "Opposite bounding box edge" +msgstr "Protilehlé okraje hranic objektu" + +#: ../../po/../src/dialogs/display-settings.cpp:282 +msgid "Default scale origin will be on the bounding box of the item" +msgstr "Výchozí bod měřítka bude na ohraničení položky" + +#: ../../po/../src/dialogs/display-settings.cpp:288 +msgid "Farthest opposite node" +msgstr "Nejvzdálenější protější uzel" + +#: ../../po/../src/dialogs/display-settings.cpp:289 +msgid "Default scale origin will be on the bounding box of the item's points" +msgstr "Výchozí bod měřítka bude na ohraničení bodů položky" + +#: ../../po/../src/dialogs/display-settings.cpp:341 +msgid "degrees" +msgstr "stupnů" + +#: ../../po/../src/dialogs/display-settings.cpp:350 +msgid "" +"Rotating with Ctrl pressed snaps every that much degrees; also, pressing " +"[ or ] rotates by this amount" +msgstr "" +"Stisknutím Ctrl se rotace omezí na skoky po daných stupních; Také stisk " +"[ nebo ] bude otáčet o daný počet stupňů." + +#: ../../po/../src/dialogs/display-settings.cpp:407 +msgid "Rotation snaps every:" +msgstr "Přichytávání při rotaci každých:" + +#: ../../po/../src/dialogs/display-settings.cpp:430 +msgid "" +"None: dialogs are treated as regular windows; Normal: dialogs stay on top of " +"document windows; Aggressive: same as Normal but may work better with some " +"window managers." +msgstr "" +"Poznámka: dialogy se chovají jako obyčejná okna. Normální: dialogy zůstávají " +"stále nad okny dokumentu; Agresivní: totéž jako Normální, s tím rozdílem, že " +"může pracovat lépe s některými správci oken" + +#: ../../po/../src/dialogs/display-settings.cpp:451 +msgid "Normal" +msgstr "Normální" + +#: ../../po/../src/dialogs/display-settings.cpp:461 +msgid "Aggressive" +msgstr "Agresivní" + +#: ../../po/../src/dialogs/display-settings.cpp:475 +msgid "Dialogs on top:" +msgstr "Dialogy vždy nahoře:" + +#: ../../po/../src/dialogs/display-settings.cpp:645 +msgid "Show selection cue" +msgstr "Ukázat označení výběru" + +#: ../../po/../src/dialogs/display-settings.cpp:646 +msgid "" +"Whether selected objects display a selection cue (the same as in selector)" +msgstr "" +"Zda u vybraných objektů zobrazovat znak výběru (stejné jak pro nástroj Výběr)" + +#: ../../po/../src/dialogs/display-settings.cpp:657 +msgid "Enable gradient editing" +msgstr "Povolit úpravu barevného přechodu" + +#: ../../po/../src/dialogs/display-settings.cpp:658 +msgid "Whether selected objects display gradient editing controls" +msgstr "" +"Zda zobrazovat ovládací prvky pro úpravu barevných přechodů u vybraných " +"objektů" + +#: ../../po/../src/dialogs/display-settings.cpp:719 +msgid "No objects selected to take the style from." +msgstr "Nejsou vybrány žádné objekty, ze kterých je možné použít styl." + +#: ../../po/../src/dialogs/display-settings.cpp:728 +msgid "" +"More than one object selected. Cannot take style from multiple " +"objects." +msgstr "" +"Vybrán více než jeden objekt. Nelze použít styl z více objektů." + +#: ../../po/../src/dialogs/display-settings.cpp:767 +msgid "Create new objects with:" +msgstr "Vytvořit nový objekt s:" + +#: ../../po/../src/dialogs/display-settings.cpp:777 +msgid "Take from selection" +msgstr "Vzít z výběru" + +#: ../../po/../src/dialogs/display-settings.cpp:778 +msgid "Remember the style of the (first) selected object as this tool's style" +msgstr "" +"Zapamatuj si styl (prvního) vybraného objektu jako styl tohoto nástroje" + +#: ../../po/../src/dialogs/display-settings.cpp:782 +#, fuzzy +msgid "Last used style" +msgstr "Vložit _Styl" + +#: ../../po/../src/dialogs/display-settings.cpp:782 +msgid "Apply the style you last set on an object" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:790 +msgid "This tool's own style:" +msgstr "Vlastní styl nástroje:" + +#: ../../po/../src/dialogs/display-settings.cpp:790 +msgid "" +"Each tool may store its own style to apply to the newly created objects. Use " +"the button below to set it." +msgstr "" +"Každý nástroj si může uchovat vlastní nastavení stylu a ten aplikovat na " +"nově vytvářené objekty. Použijte tlačítko níže k nastavení." + +#. Mouse +#: ../../po/../src/dialogs/display-settings.cpp:877 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:55 +msgid "Mouse" +msgstr "MyÅ¡" + +#. TRANSLATORS: "Grab" is a noun here. "Grab sensitivity" is intended to mean how +#. * close on the screen you need to be to an object to be able to grab it with mouse (in +#. * pixels). +#: ../../po/../src/dialogs/display-settings.cpp:883 +msgid "Grab sensitivity:" +msgstr "Citlivost při výběru:" + +#: ../../po/../src/dialogs/display-settings.cpp:884 +msgid "" +"How close on the screen you need to be to an object to be able to grab it " +"with mouse (in screen pixels)" +msgstr "" +"Jak blízko k objektu na obrazovce musíte být, aby jste byli schopní zachytit " +"jej myší (v pixelech)" + +#: ../../po/../src/dialogs/display-settings.cpp:885 +#: ../../po/../src/dialogs/display-settings.cpp:897 +#: ../../po/../src/dialogs/display-settings.cpp:912 +#: ../../po/../src/dialogs/display-settings.cpp:930 +#: ../../po/../src/dialogs/display-settings.cpp:970 +msgid "pixels" +msgstr "pixelů" + +#: ../../po/../src/dialogs/display-settings.cpp:895 +msgid "Click/drag threshold:" +msgstr "Práh mezi kliknutím a tažením:" + +#: ../../po/../src/dialogs/display-settings.cpp:896 +msgid "" +"Maximum mouse drag (in screen pixels) which is considered a click, not a drag" +msgstr "" +"Maximální tažení myší považované za kliknutí, nikoliv tažení (v pixelech)" + +#. Scrolling +#: ../../po/../src/dialogs/display-settings.cpp:907 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:56 +msgid "Scrolling" +msgstr "Posun" + +#: ../../po/../src/dialogs/display-settings.cpp:910 +msgid "Mouse wheel scrolls by:" +msgstr "Kolečko myÅ¡i posunuje po:" + +#: ../../po/../src/dialogs/display-settings.cpp:911 +msgid "" +"One mouse wheel notch scrolls by this distance in screen pixels " +"(horizontally with Shift)" +msgstr "" +"O tuto hodnotu(v pixelech) posune obraz jedno pootočení kolečka myÅ¡i " +"(vodorovný posun s Shift)." + +#: ../../po/../src/dialogs/display-settings.cpp:920 +msgid "Ctrl+arrows" +msgstr "Ctrl+Å¡ipky" + +#: ../../po/../src/dialogs/display-settings.cpp:928 +msgid "Scroll by:" +msgstr "Posunout o:" + +#: ../../po/../src/dialogs/display-settings.cpp:929 +msgid "Pressing Ctrl+arrow key scrolls by this distance (in screen pixels)" +msgstr "Stiskem Ctrl+Å¡ipky dojde k posunu o danou vzdálenost (v pixelech)" + +#: ../../po/../src/dialogs/display-settings.cpp:939 +msgid "Acceleration:" +msgstr "Zrychlení:" + +#: ../../po/../src/dialogs/display-settings.cpp:940 +msgid "" +"Pressing and holding Ctrl+arrow will gradually speed up scrolling (0 for no " +"acceleration)" +msgstr "" +"Stiskem a držením Ctrl+Å¡ipky pozvolna zvýšíte rychlost posuvu (0 znamená " +"žádné zrychlení)" + +#: ../../po/../src/dialogs/display-settings.cpp:949 +msgid "Autoscrolling" +msgstr "Automatický posun" + +#: ../../po/../src/dialogs/display-settings.cpp:957 +msgid "Speed:" +msgstr "Rychlost:" + +#: ../../po/../src/dialogs/display-settings.cpp:958 +msgid "" +"How fast the canvas autoscrolls when you drag beyond canvas edge (0 to turn " +"autoscroll off)" +msgstr "" +"Jak rychle se bude automaticky posouvat plátno, když potáhnete myší mimo " +"plátno (0 vypíná autoposuv)" + +#: ../../po/../src/dialogs/display-settings.cpp:968 +#: ../../po/../src/ui/dialog/tracedialog.cpp:357 +#: ../../po/../src/ui/dialog/tracedialog.cpp:390 +msgid "Threshold:" +msgstr "Práh:" + +#: ../../po/../src/dialogs/display-settings.cpp:969 +msgid "" +"How far (in screen pixels) you need to be from the canvas edge to trigger " +"autoscroll; positive is outside the canvas, negative is within the canvas" +msgstr "" +"Jak daleko (v pixelech) musíte být od plátna aby se aktivoval autoposuv; " +"kladná hodnota znamená mimo plátno, záporná uvnitř plátna" + +#. Steps +#: ../../po/../src/dialogs/display-settings.cpp:979 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:57 +msgid "Steps" +msgstr "Kroky" + +#: ../../po/../src/dialogs/display-settings.cpp:982 +msgid "Arrow keys move by:" +msgstr "Å ipky přesunují po:" + +#: ../../po/../src/dialogs/display-settings.cpp:983 +msgid "" +"Pressing an arrow key moves selected object(s) or node(s) by this distance " +"(in px units)" +msgstr "" +"Stiskem Å¡ipek přesunete vybrané objekty nebo uzly o tuto vzdálenost (v " +"pixelech)" + +#: ../../po/../src/dialogs/display-settings.cpp:984 +#: ../../po/../src/dialogs/display-settings.cpp:995 +#: ../../po/../src/dialogs/display-settings.cpp:1006 +#: ../../po/../src/helper/units.cpp:42 +msgid "px" +msgstr "px" + +#: ../../po/../src/dialogs/display-settings.cpp:993 +msgid "> and < scale by:" +msgstr "> a < mění měřítko po:" + +#: ../../po/../src/dialogs/display-settings.cpp:994 +msgid "" +"Pressing > or < scales selection up or down by this increment (in px units)" +msgstr "" +"Stiskem > nebo < se změní měřítko výběru nahoru nebo dolů o tuto hodnotu (v " +"pixelech)" + +#: ../../po/../src/dialogs/display-settings.cpp:1004 +msgid "Inset/Outset by:" +msgstr "SmrÅ¡tit/Rozšířit o:" + +#: ../../po/../src/dialogs/display-settings.cpp:1005 +msgid "" +"Inset and Outset commands displace the path by this distance (in px units)" +msgstr "" +"Příkazy SmrÅ¡tit a Rozšířit deformují křivku o tuto vzdálenost (v pixelech)" + +#: ../../po/../src/dialogs/display-settings.cpp:1017 +msgid "Compass-like display of angles" +msgstr "Zobrazení úhlů jako na kompasu" + +#. TRANSLATORS: "positive clockwise" means "increasing in clockwise direction" +#: ../../po/../src/dialogs/display-settings.cpp:1019 +msgid "" +"When on, angles are displayed with 0 at north, 0 to 360 range, positive " +"clockwise; otherwise with 0 at east, -180 to 180 range, positive " +"counterclockwise" +msgstr "" +"V zapnutém stavu jsou úhly zobrazovány v rozmezí 0 až 360 stupňů kde 0 je " +"sever, kladný směr otáčení po směru hodinových ručiček; jinak je 0 na " +"východě a rozmezí úhlů je -180 až 180 stupňů, kladný směr proti směru " +"otáčení hodinových ručiček" + +#: ../../po/../src/dialogs/display-settings.cpp:1026 +msgid "Zoom in/out by:" +msgstr "Přiblížit/oddálit o:" + +#: ../../po/../src/dialogs/display-settings.cpp:1027 +msgid "" +"Zoom tool click, +/- keys, and middle click zoom in and out by this " +"multiplier" +msgstr "" +"Kliknutí nástrojem Lupa, klávesy +/-, a kliknutí prostředním tlačítkem " +"přiblíží a oddálí o násobek této hodnoty" + +#: ../../po/../src/dialogs/display-settings.cpp:1028 +#: ../../po/../src/helper/units.cpp:44 +msgid "%" +msgstr "%" + +#. Tools +#: ../../po/../src/dialogs/display-settings.cpp:1037 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:58 +msgid "Tools" +msgstr "Nástroje" + +#: ../../po/../src/dialogs/display-settings.cpp:1045 +msgid "Selector" +msgstr "Výběr" + +#: ../../po/../src/dialogs/display-settings.cpp:1056 +msgid "Node" +msgstr "Uzly" + +#: ../../po/../src/dialogs/display-settings.cpp:1064 +#: ../../po/../src/verbs.cpp:2073 +#: ../../po/../src/widgets/desktop-widget.cpp:277 +msgid "Zoom" +msgstr "Lupa" + +#. The 4 shape tools +#: ../../po/../src/dialogs/display-settings.cpp:1071 +msgid "Shapes" +msgstr "Tvary" + +#: ../../po/../src/dialogs/display-settings.cpp:1079 +#: ../../po/../src/verbs.cpp:2055 +msgid "Rectangle" +msgstr "Čtyřúhelník" + +#: ../../po/../src/dialogs/display-settings.cpp:1085 +#: ../../po/../src/verbs.cpp:2057 +msgid "Ellipse" +msgstr "Elipsa" + +#: ../../po/../src/dialogs/display-settings.cpp:1091 +#: ../../po/../src/verbs.cpp:2059 +msgid "Star" +msgstr "Hvězda" + +#: ../../po/../src/dialogs/display-settings.cpp:1097 +#: ../../po/../src/verbs.cpp:2061 +msgid "Spiral" +msgstr "Spirála" + +#: ../../po/../src/dialogs/display-settings.cpp:1111 +#: ../../po/../src/verbs.cpp:2063 +msgid "Pencil" +msgstr "Tužka" + +#: ../../po/../src/dialogs/display-settings.cpp:1114 +msgid "Tolerance:" +msgstr "Tolerance:" + +#: ../../po/../src/dialogs/display-settings.cpp:1115 +msgid "" +"This value affects the amount of smoothing applied to freehand lines; lower " +"values produce more uneven paths with more nodes" +msgstr "" +"Tato hodnota ovlivňuje stupeň vyhlazení aplikovanou na křivky kreslené od " +"ruky; nižší hodnoty dávají kostrbatější křivky s více uzly." + +#: ../../po/../src/dialogs/display-settings.cpp:1131 +#: ../../po/../src/verbs.cpp:2065 +msgid "Pen" +msgstr "Pero" + +#: ../../po/../src/dialogs/display-settings.cpp:1140 +#: ../../po/../src/verbs.cpp:2067 +msgid "Calligraphy" +msgstr "Kaligrafická linka" + +#: ../../po/../src/dialogs/display-settings.cpp:1147 +#: ../../po/../src/dialogs/text-edit.cpp:353 +#: ../../po/../src/ui/dialog/text-properties.cpp:37 +#: ../../po/../src/verbs.cpp:2069 +msgid "Text" +msgstr "Text" + +#: ../../po/../src/dialogs/display-settings.cpp:1157 +#: ../../po/../src/verbs.cpp:2071 +msgid "Gradient" +msgstr "Barevný přechod" + +#: ../../po/../src/dialogs/display-settings.cpp:1164 +#: ../../po/../src/verbs.cpp:2077 +msgid "Connector" +msgstr "Konektor" + +#: ../../po/../src/dialogs/display-settings.cpp:1171 +#: ../../po/../src/verbs.cpp:2075 +msgid "Dropper" +msgstr "Pipeta" + +#. Windows +#: ../../po/../src/dialogs/display-settings.cpp:1183 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:59 +msgid "Windows" +msgstr "Okna" + +#: ../../po/../src/dialogs/display-settings.cpp:1188 +msgid "Save window geometry" +msgstr "Uložit rozměry okna" + +#: ../../po/../src/dialogs/display-settings.cpp:1189 +msgid "" +"Save the window size and position with each document (only for Inkscape SVG " +"format)" +msgstr "" +"Uložit rozměry a pozici okna pro každý dokument (pouze pro formát Inkscape " +"SVG)" + +#: ../../po/../src/dialogs/display-settings.cpp:1196 +msgid "Dialogs are hidden in taskbar" +msgstr "Skrýt dialogová okna z liÅ¡ty úloh" + +#: ../../po/../src/dialogs/display-settings.cpp:1197 +msgid "Whether dialog windows are to be hidden in the window manager taskbar" +msgstr "Zda mají být dialogová okna skryta v pruhu úloh správce oken" + +#: ../../po/../src/dialogs/display-settings.cpp:1204 +msgid "Zoom when window is resized" +msgstr "ZvětÅ¡it či zmenÅ¡it kresbu při změně velikosti okna" + +#: ../../po/../src/dialogs/display-settings.cpp:1205 +msgid "" +"Zoom drawing when document window is resized, to keep the same area visible " +"(this is the default which can be changed in any window using the button " +"above the right scrollbar)" +msgstr "" +"Přiblížit kresbu při změně velikosti okna pro zachování viditelné oblasti " +"(toto výchozí chování lze změnit pro libovolné okno pomocí tlačítka nahoře " +"napravo nad posuvníky)" + +#. Clones +#: ../../po/../src/dialogs/display-settings.cpp:1213 +#: ../../po/../src/dialogs/find.cpp:624 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:60 +msgid "Clones" +msgstr "Klony" + +#: ../../po/../src/dialogs/display-settings.cpp:1217 +msgid "When the original moves, its clones and linked offsets:" +msgstr "Při přesunu originálu se jeho klony a připojené objekty:" + +#: ../../po/../src/dialogs/display-settings.cpp:1229 +msgid "Move in parallel" +msgstr "Přesunout paralelně" + +#: ../../po/../src/dialogs/display-settings.cpp:1230 +msgid "Clones are translated by the same vector as their original." +msgstr "Klony se přesunují stejným směrem jako jejich originál." + +#: ../../po/../src/dialogs/display-settings.cpp:1237 +msgid "Stay unmoved" +msgstr "Zůstane nepřesunut" + +#: ../../po/../src/dialogs/display-settings.cpp:1238 +msgid "Clones preserve their positions when their original is moved." +msgstr "Klony zůstávají na své pozici při přesunu originálu." + +#: ../../po/../src/dialogs/display-settings.cpp:1245 +msgid "Move according to transform" +msgstr "Přesun podle transformace" + +#: ../../po/../src/dialogs/display-settings.cpp:1246 +msgid "" +"Each clone moves according to the value of its transform= attribute. For " +"example, a rotated clone will move in a different direction than its " +"original." +msgstr "" +"Každý klon se přesunuje podle hodnoty jeho vlastnosti transform= . Například " +"otočený klon se přesune jiným směrem než jeho originál." + +#: ../../po/../src/dialogs/display-settings.cpp:1255 +msgid "When the original is deleted, its clones:" +msgstr "Když je originál vymazán, jeho klony:" + +#: ../../po/../src/dialogs/display-settings.cpp:1267 +msgid "Are unlinked" +msgstr "Jsou rozpojeny" + +#: ../../po/../src/dialogs/display-settings.cpp:1267 +msgid "Orphaned clones are converted to regular objects." +msgstr "Osiřelé klony jsou konvertovány na samostatné objekty." + +#: ../../po/../src/dialogs/display-settings.cpp:1273 +msgid "Are deleted" +msgstr "Jsou vymazány" + +#: ../../po/../src/dialogs/display-settings.cpp:1273 +msgid "Orphaned clones are deleted along with their original." +msgstr "Osiřelé klony jsou smazány stejně jako jejich originál." + +#. Transforms +#. TRANSLATORS: Noun, i.e. transformations. +#: ../../po/../src/dialogs/display-settings.cpp:1289 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:61 +msgid "Transforms" +msgstr "Transformace" + +#: ../../po/../src/dialogs/display-settings.cpp:1292 +msgid "Scale stroke width" +msgstr "Měnit šířku okraje při změně měřítka" + +#: ../../po/../src/dialogs/display-settings.cpp:1293 +#: ../../po/../src/widgets/select-toolbar.cpp:568 +msgid "When scaling objects, scale the stroke width by the same proportion" +msgstr "Při změně velikosti objektů, změň šířku okraje dle stejných proporcí" + +#: ../../po/../src/dialogs/display-settings.cpp:1300 +msgid "Scale rounded corners in rectangles" +msgstr "Měnit velikost zaoblených rohů čtyřúhelníků" + +#: ../../po/../src/dialogs/display-settings.cpp:1301 +#: ../../po/../src/widgets/select-toolbar.cpp:580 +msgid "When scaling rectangles, scale the radii of rounded corners" +msgstr "Při změně velikosti čtyřúhelníků, měnit i poloměr zaoblení rohů" + +#: ../../po/../src/dialogs/display-settings.cpp:1308 +msgid "Transform gradients" +msgstr "Transformovat barevné přechody" + +#: ../../po/../src/dialogs/display-settings.cpp:1309 +#: ../../po/../src/widgets/select-toolbar.cpp:592 +msgid "Transform gradients (in fill or stroke) along with the objects" +msgstr "Transformovat barevné přechody (ve výplni i okrajích) podle objektů" + +#: ../../po/../src/dialogs/display-settings.cpp:1316 +msgid "Transform patterns" +msgstr "Transformovat vzory" + +#: ../../po/../src/dialogs/display-settings.cpp:1317 +#: ../../po/../src/widgets/select-toolbar.cpp:604 +msgid "Transform patterns (in fill or stroke) along with the objects" +msgstr "Transformovat vzory (ve výplni i okrajích) podle objektů" + +#. TRANSLATORS: How to specify the affine transformation in the SVG file. +#: ../../po/../src/dialogs/display-settings.cpp:1327 +msgid "Store transformation:" +msgstr "Uložit transformaci:" + +#: ../../po/../src/dialogs/display-settings.cpp:1338 +msgid "Optimized" +msgstr "Optimalizovat" + +#: ../../po/../src/dialogs/display-settings.cpp:1339 +msgid "" +"If possible, apply transformation to objects without adding a transform= " +"attribute" +msgstr "" +"Je-li to možné, aplikovat transformaci na objekty bez přidání atributu " +"transform=" + +#: ../../po/../src/dialogs/display-settings.cpp:1346 +msgid "Preserved" +msgstr "Zachovat" + +#: ../../po/../src/dialogs/display-settings.cpp:1347 +msgid "Always store transformation as a transform= attribute on objects" +msgstr "Vždy ukládat transformace jako transform= atribut u objektu" + +#. Selecting +#: ../../po/../src/dialogs/display-settings.cpp:1355 +msgid "Selecting" +msgstr "Výběry" + +#: ../../po/../src/dialogs/display-settings.cpp:1357 +msgid "Ctrl+A, Tab, Shift+Tab:" +msgstr "Ctrl+A, Tab, Shift+Tab:" + +#: ../../po/../src/dialogs/display-settings.cpp:1366 +msgid "Select only within current layer" +msgstr "Vybírat pouze v aktuální vrstvě" + +#: ../../po/../src/dialogs/display-settings.cpp:1367 +msgid "" +"Uncheck this to make keyboard selection commands work on objects in all " +"layers" +msgstr "" +"OdÅ¡krtněte pro povolení aby klávesové příkazy výběru mohly pracovat s " +"objekty na vÅ¡ech vrstvách" + +#: ../../po/../src/dialogs/display-settings.cpp:1374 +msgid "Ignore hidden objects" +msgstr "Ignorovat skryté objekty" + +#: ../../po/../src/dialogs/display-settings.cpp:1375 +msgid "" +"Uncheck this to be able to select objects that are hidden (either by " +"themselves or by being in a hidden group or layer)" +msgstr "" +"Odznačte tuto volbu a budete moci vybírat i objekty které jsou skryté " +"(jejich výběrem nebo výběrem skupiny, nebo vrstvy ve které jsou)" + +#: ../../po/../src/dialogs/display-settings.cpp:1382 +msgid "Ignore locked objects" +msgstr "Ignorovat zamčené objekty" + +#: ../../po/../src/dialogs/display-settings.cpp:1383 +msgid "" +"Uncheck this to be able to select objects that are locked (either by " +"themselves or by being in a locked group or layer)" +msgstr "" +"Odznačte tuto volbu a budete moci vybírat i objekty které jsou uzamčeny " +"(jejich výběrem nebo výběrem skupiny, nebo vrstvy ve které jsou)" + +#. To be broken into: Display, Save, Export, SVG, Commands +#: ../../po/../src/dialogs/display-settings.cpp:1391 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:62 +msgid "Misc" +msgstr "Různé" + +#: ../../po/../src/dialogs/display-settings.cpp:1394 +msgid "Default export resolution:" +msgstr "Výchozí rozliÅ¡ení pro export:" + +#: ../../po/../src/dialogs/display-settings.cpp:1395 +msgid "Default bitmap resolution (in dots per inch) in the Export dialog" +msgstr "Výchozí rozliÅ¡ení bitové mapy (v bodech na palec) pro Exportní dialog" + +#. FIXME: add "Used for new exports; once exported, documents remember this value on per-object basis" when implemented +#: ../../po/../src/dialogs/display-settings.cpp:1396 +#: ../../po/../src/dialogs/export.cpp:442 +msgid "dpi" +msgstr "dpi" + +#. TRANSLATORS: When on, an imported bitmap creates an element; otherwise it is a +#. * rectangle with bitmap fill. +#: ../../po/../src/dialogs/display-settings.cpp:1407 +msgid "Import bitmap as " +msgstr "Importovat obrázek jako " + +#: ../../po/../src/dialogs/display-settings.cpp:1408 +msgid "" +"When on, an imported bitmap creates an element; otherwise it is a " +"rectangle with bitmap fill" +msgstr "" +"Pokud je zapnuto, bude vytvořen element pro importované bitmapy; " +"jinak bude obrázek vložen jako obdélník s bitmapovou výplní" + +#. TRANSLATORS: When on, the print out (currently Postscript) will have +#. * a comment with the each object's label visible, marking the section +#. * of the printing commands that represent the given object. +#: ../../po/../src/dialogs/display-settings.cpp:1418 +msgid "Add label comments to printing output" +msgstr "Přidat komentáře k tiÅ¡těnému výstupu" + +#: ../../po/../src/dialogs/display-settings.cpp:1419 +msgid "" +"When on, a comment will be added to the raw print output, marking the " +"rendered output for an object with its label" +msgstr "Pokud je zapnuto, pak se k výtisku přidá komentář s jménem objektu" + +#. TRANSLATORS: When on, enable the effects menu, default is off +#: ../../po/../src/dialogs/display-settings.cpp:1427 +msgid "Enable script effects (requires restart) - EXPERIMENTAL" +msgstr "Povolit skripty s efekty (vyžaduje restart) - EXPERIMENTÁLNÍ" + +#: ../../po/../src/dialogs/display-settings.cpp:1428 +msgid "" +"When on, the effects menu is enabled, allowing external effect scripts to be " +"called, requires restart before effective - EXPERIMENTAL" +msgstr "" +"Po zapnutí zpřístupní menu Efekty obsahující externí skripty vytvářející " +"různé efekty, vyžaduje restart aplikace - EXPERIMENTÁLNÍ" + +#. TRANSLATORS: The maximum length of the Open Recent list in the File menu. +#: ../../po/../src/dialogs/display-settings.cpp:1436 +msgid "Max recent documents:" +msgstr "Max. počet posledních otevřených dokumentů:" + +#: ../../po/../src/dialogs/display-settings.cpp:1437 +msgid "The maximum length of the Open Recent list in the File menu" +msgstr "Maximální délka seznamu posledně otevřených dokumentů v menu Soubor" + +#: ../../po/../src/dialogs/display-settings.cpp:1447 +msgid "Simplification threshold:" +msgstr "Práh zjednoduÅ¡ení:" + +#: ../../po/../src/dialogs/display-settings.cpp:1448 +msgid "" +"How strong is the Simplify command by default. If you invoke this command " +"several times in quick succession, it will act more and more aggressively; " +"invoking it again after a pause restores the default threshold." +msgstr "" +"Jak výrazný bude vliv příkazu ZjednoduÅ¡it. Pokud tento příkaz použijete " +"několikrát po sobě, bude působit čím dál více agresivněji; Opětovnou " +"aplikací po pauze obnoví výchozí nastavení prahu." + +#: ../../po/../src/dialogs/display-settings.cpp:1469 +msgid "Oversample bitmaps:" +msgstr "Převzorkovat bitmapy:" + +#: ../../po/../src/dialogs/display-settings.cpp:1488 +msgid "2x2" +msgstr "2×2" + +#: ../../po/../src/dialogs/display-settings.cpp:1494 +msgid "4x4" +msgstr "4×4" + +#: ../../po/../src/dialogs/display-settings.cpp:1500 +msgid "8x8" +msgstr "8×8" + +#: ../../po/../src/dialogs/display-settings.cpp:1506 +msgid "16x16" +msgstr "16×16" + +#. "view_icon_preview" +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2143 +msgid "_Page" +msgstr "_Strana" + +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2147 +msgid "_Drawing" +msgstr "_Kresba" + +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2149 +msgid "_Selection" +msgstr "_Výběr" + +#: ../../po/../src/dialogs/export.cpp:133 +msgid "_Custom" +msgstr "V_lastní" + +#: ../../po/../src/dialogs/export.cpp:254 +msgid "Export area" +msgstr "Exportovaná oblast" + +#: ../../po/../src/dialogs/export.cpp:300 +msgid "_x0:" +msgstr "_x0:" + +#: ../../po/../src/dialogs/export.cpp:305 +msgid "x_1:" +msgstr "x_1:" + +#: ../../po/../src/dialogs/export.cpp:316 +msgid "_y0:" +msgstr "_y0:" + +#: ../../po/../src/dialogs/export.cpp:321 +msgid "y_1:" +msgstr "y_1:" + +#: ../../po/../src/dialogs/export.cpp:406 +msgid "Bitmap size" +msgstr "Velikost bitmapy" + +#: ../../po/../src/dialogs/export.cpp:416 +msgid "_Width:" +msgstr "Šířka:" + +#: ../../po/../src/dialogs/export.cpp:416 +#: ../../po/../src/dialogs/export.cpp:431 +msgid "pixels at" +msgstr "pixelů při" + +#: ../../po/../src/dialogs/export.cpp:426 +msgid "dp_i" +msgstr "dp_i" + +#: ../../po/../src/dialogs/export.cpp:448 +msgid "_Filename" +msgstr "Jméno souboru" + +#: ../../po/../src/dialogs/export.cpp:512 +msgid "_Browse..." +msgstr "Procházet..." + +#: ../../po/../src/dialogs/export.cpp:539 +msgid " _Export " +msgstr " _Export " + +#: ../../po/../src/dialogs/export.cpp:541 +msgid "Export the bitmap file with these settings" +msgstr "Exportovat bitmapu s tímto nastavením" + +#: ../../po/../src/dialogs/export.cpp:968 +msgid "You have to enter a filename" +msgstr "Musíte zadat název souboru" + +#: ../../po/../src/dialogs/export.cpp:973 +msgid "The chosen area to be exported is invalid" +msgstr "Vybraná oblast pro export je neplatná" + +#: ../../po/../src/dialogs/export.cpp:982 +#, c-format +msgid "Directory %s does not exist or is not a directory.\n" +msgstr "Adresář %s neexistuje nebo není adresářem.\n" + +#: ../../po/../src/dialogs/export.cpp:998 +msgid "Export in progress" +msgstr "Probíhá export" + +#: ../../po/../src/dialogs/export.cpp:1004 +#, c-format +msgid "Exporting %s (%d x %d)" +msgstr "Exportuji %s (%d × %d)" + +#: ../../po/../src/dialogs/export.cpp:1031 +#, c-format +msgid "Could not export to filename %s.\n" +msgstr "Nelze exportovat do souboru s názvem %s.\n" + +#: ../../po/../src/dialogs/export.cpp:1137 +msgid "Select a filename for exporting" +msgstr "Vyberte jméno souboru pro export" + +#: ../../po/../src/dialogs/filedialog.cpp:367 +msgid "No preview" +msgstr "Bez náhledu" + +#: ../../po/../src/dialogs/filedialog.cpp:468 +msgid "too large for preview" +msgstr "příliÅ¡ velké pro náhled" + +#: ../../po/../src/dialogs/filedialog.cpp:762 +#: ../../po/../src/dialogs/filedialog.cpp:763 +msgid "All Images" +msgstr "VÅ¡echny obrázky" + +#: ../../po/../src/dialogs/filedialog.cpp:767 +#: ../../po/../src/dialogs/filedialog.cpp:768 +msgid "All Files" +msgstr "VÅ¡echny soubory" + +#: ../../po/../src/dialogs/filedialog.cpp:774 +#: ../../po/../src/dialogs/filedialog.cpp:775 +msgid "All Inkscape Files" +msgstr "VÅ¡echny soubory Inkscape" + +#: ../../po/../src/dialogs/filedialog.cpp:1176 +msgid "Guess from extension" +msgstr "Určit dle přípony" + +#. ###### Add the file types menu +#. createFilterMenu(); +#. ###### Do we want the .xxx extension automatically added? +#: ../../po/../src/dialogs/filedialog.cpp:1261 +msgid "Append filename extension automatically" +msgstr "Automaticky přidat ke jménu souboru příponu" + +#. TRANSLATORS: "%s" is replaced with "exact" or "partial" when this string is displayed +#: ../../po/../src/dialogs/find.cpp:378 +#, fuzzy, c-format +msgid "%d object found (out of %d), %s match." +msgid_plural "%d objects found (out of %d), %s match." +msgstr[0] "%d objekt nalezen (z %d), %s shoda." +msgstr[1] "%d objektů nalezeno (z %d), %s shoda." + +#: ../../po/../src/dialogs/find.cpp:381 +msgid "exact" +msgstr "přesný" + +#: ../../po/../src/dialogs/find.cpp:381 +msgid "partial" +msgstr "částečný" + +#: ../../po/../src/dialogs/find.cpp:388 +msgid "No objects found" +msgstr "Nebyly nalezeny žádné objekty" + +#: ../../po/../src/dialogs/find.cpp:546 +msgid "T_ype: " +msgstr "Typ: " + +#: ../../po/../src/dialogs/find.cpp:553 +msgid "Search in all object types" +msgstr "Hledat objekty vÅ¡ech typů" + +#: ../../po/../src/dialogs/find.cpp:553 +msgid "All types" +msgstr "VÅ¡echny typy" + +#: ../../po/../src/dialogs/find.cpp:564 +msgid "Search all shapes" +msgstr "Vyhledat vÅ¡echny tvary" + +#: ../../po/../src/dialogs/find.cpp:564 +msgid "All shapes" +msgstr "VÅ¡echny tvary" + +#: ../../po/../src/dialogs/find.cpp:581 +msgid "Search rectangles" +msgstr "Hledat čtyřúhelníky" + +#: ../../po/../src/dialogs/find.cpp:581 +msgid "Rectangles" +msgstr "Čtyřúhelníky" + +#: ../../po/../src/dialogs/find.cpp:586 +msgid "Search ellipses, arcs, circles" +msgstr "Hledat elipsy, oblouky a kružnice" + +#: ../../po/../src/dialogs/find.cpp:586 +msgid "Ellipses" +msgstr "Elipsy" + +#: ../../po/../src/dialogs/find.cpp:591 +msgid "Search stars and polygons" +msgstr "Hledat hvězdy a mnohoúhelníky" + +#: ../../po/../src/dialogs/find.cpp:591 +msgid "Stars" +msgstr "Hvězdy" + +#: ../../po/../src/dialogs/find.cpp:596 +msgid "Search spirals" +msgstr "Hledat spirály" + +#: ../../po/../src/dialogs/find.cpp:596 +msgid "Spirals" +msgstr "Spirály" + +#. TRANSLATORS: polyline is a set of connected straight line segments +#. http://www.w3.org/TR/SVG11/shapes.html#PolylineElement +#: ../../po/../src/dialogs/find.cpp:609 +msgid "Search paths, lines, polylines" +msgstr "Hledat křivky, přímky, lomené čáry" + +#: ../../po/../src/dialogs/find.cpp:609 +msgid "Paths" +msgstr "Křivky" + +#: ../../po/../src/dialogs/find.cpp:614 +msgid "Search text objects" +msgstr "Hledat textové objekty" + +#: ../../po/../src/dialogs/find.cpp:614 +msgid "Texts" +msgstr "Text" + +#: ../../po/../src/dialogs/find.cpp:619 +msgid "Search groups" +msgstr "Prohledat skupiny" + +#: ../../po/../src/dialogs/find.cpp:619 +msgid "Groups" +msgstr "Seskupení" + +#: ../../po/../src/dialogs/find.cpp:624 +msgid "Search clones" +msgstr "Prohledat klony" + +#: ../../po/../src/dialogs/find.cpp:629 +msgid "Search images" +msgstr "Prohledat obrázky" + +#: ../../po/../src/dialogs/find.cpp:629 +msgid "Images" +msgstr "Obrázky" + +#: ../../po/../src/dialogs/find.cpp:634 +msgid "Search offset objects" +msgstr "Hledat objekty s posunem" + +#: ../../po/../src/dialogs/find.cpp:634 +msgid "Offsets" +msgstr "Posuny" + +#: ../../po/../src/dialogs/find.cpp:694 +msgid "_Text: " +msgstr "_Text:" + +#: ../../po/../src/dialogs/find.cpp:694 +msgid "Find objects by their text content (exact or partial match)" +msgstr "Hledat objekty podle textu v nich (přesná nebo částečná shoda)" + +#: ../../po/../src/dialogs/find.cpp:695 +msgid "_ID: " +msgstr "_ID: " + +#: ../../po/../src/dialogs/find.cpp:695 +msgid "Find objects by the value of the id attribute (exact or partial match)" +msgstr "Hledat objekty podle ID atributu stylu (přesná nebo částečná shoda)" + +#: ../../po/../src/dialogs/find.cpp:696 +msgid "_Style: " +msgstr "_Styl:" + +#: ../../po/../src/dialogs/find.cpp:696 +msgid "" +"Find objects by the value of the style attribute (exact or partial match)" +msgstr "" +"Hledat objekty podle hodnoty některého z atributů stylu (přesná nebo " +"částečná shoda)" + +#: ../../po/../src/dialogs/find.cpp:697 +msgid "_Attribute: " +msgstr "_Atribut:" + +#: ../../po/../src/dialogs/find.cpp:697 +msgid "Find objects by the name of an attribute (exact or partial match)" +msgstr "Hledat objekty podle jména atributu (přesná nebo částečná shoda)" + +#: ../../po/../src/dialogs/find.cpp:711 +msgid "Search in s_election" +msgstr "Hledat ve výběru" + +#: ../../po/../src/dialogs/find.cpp:715 +msgid "Limit search to the current selection" +msgstr "Omezit hledání na aktuální výběr" + +#: ../../po/../src/dialogs/find.cpp:720 +msgid "Search in current _layer" +msgstr "Hledat v aktuální vrstvě" + +#: ../../po/../src/dialogs/find.cpp:724 +msgid "Limit search to the current layer" +msgstr "Omezit výběr na aktuální vrstvu" + +#: ../../po/../src/dialogs/find.cpp:729 +msgid "Include _hidden" +msgstr "Zahrnout _skryté" + +#: ../../po/../src/dialogs/find.cpp:733 +msgid "Include hidden objects in search" +msgstr "Zahrnout skryté objekty do vyhledávání" + +#: ../../po/../src/dialogs/find.cpp:738 +msgid "Include l_ocked" +msgstr "Zahrnout uzamčené" + +#: ../../po/../src/dialogs/find.cpp:742 +msgid "Include locked objects in search" +msgstr "Zahrnout zamčené objekty do hledání" + +#: ../../po/../src/dialogs/find.cpp:753 +msgid "Clear values" +msgstr "Vyčistit hodnoty" + +#: ../../po/../src/dialogs/find.cpp:754 +msgid "_Find" +msgstr "Hledat" + +#: ../../po/../src/dialogs/find.cpp:754 +msgid "Select objects matching all of the fields you filled in" +msgstr "Vybrat objekty vyhovující vÅ¡em zadaným kritériím" + +#: ../../po/../src/dialogs/iconpreview.cpp:145 +#, c-format +msgid "%d x %d" +msgstr "%d x %d" + +#: ../../po/../src/dialogs/iconpreview.cpp:193 +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:857 +#: ../../po/../src/widgets/desktop-widget.cpp:1069 +msgid "Selection" +msgstr "Výběr" + +#: ../../po/../src/dialogs/iconpreview.cpp:195 +msgid "Selection only or whole document" +msgstr "Pouze výbrané objekty nebo celý dokument" + +#: ../../po/../src/dialogs/iconpreview.cpp:203 +msgid "Refresh the icons" +msgstr "Obnovit ikony" + +#. Create the label for the object id +#: ../../po/../src/dialogs/item-properties.cpp:126 +#: ../../po/../src/dialogs/item-properties.cpp:327 +#: ../../po/../src/dialogs/item-properties.cpp:396 +#: ../../po/../src/dialogs/item-properties.cpp:403 +msgid "_Id" +msgstr "_Id" + +#: ../../po/../src/dialogs/item-properties.cpp:135 +msgid "" +"The id= attribute (only letters, digits, and the characters .-_: allowed)" +msgstr "id= atribut (pouze písmena, číslice a znaky .-_: jsou povoleny)" + +#. Button for setting the object's id, label, title and description. +#: ../../po/../src/dialogs/item-properties.cpp:149 +msgid "_Set" +msgstr "Na_stavit" + +#. Create the label for the object label +#: ../../po/../src/dialogs/item-properties.cpp:158 +msgid "_Label" +msgstr "Jmenovka" + +#: ../../po/../src/dialogs/item-properties.cpp:167 +msgid "A freeform label for the object" +msgstr "Libovolný název objektu" + +#. Create the label for the object title +#: ../../po/../src/dialogs/item-properties.cpp:179 +#: ../../po/../src/dialogs/rdf.cpp:243 +msgid "Title" +msgstr "Titulek" + +#. Create the frame for the object description +#: ../../po/../src/dialogs/item-properties.cpp:196 +#: ../../po/../src/dialogs/rdf.cpp:287 +msgid "Description" +msgstr "Popis" + +#. Hide +#: ../../po/../src/dialogs/item-properties.cpp:223 +msgid "_Hide" +msgstr "Skrýt" + +#: ../../po/../src/dialogs/item-properties.cpp:224 +msgid "Check to make the object invisible" +msgstr "ZaÅ¡krtněte aby byl objekt neviditelný" + +#. Lock +#. TRANSLATORS: "Lock" is a verb here +#: ../../po/../src/dialogs/item-properties.cpp:233 +msgid "L_ock" +msgstr "Zamkn_out" + +#: ../../po/../src/dialogs/item-properties.cpp:234 +msgid "Check to make the object insensitive (not selectable by mouse)" +msgstr "ZaÅ¡krtněte a objekt bude necitlivý (nepůjde vybrat myší)" + +#: ../../po/../src/dialogs/item-properties.cpp:310 +#: ../../po/../src/dialogs/item-properties.cpp:317 +msgid "Ref" +msgstr "Ref" + +#: ../../po/../src/dialogs/item-properties.cpp:398 +msgid "Id invalid! " +msgstr "Id je neplatné!" + +#: ../../po/../src/dialogs/item-properties.cpp:400 +msgid "Id exists! " +msgstr "Id existuje!" + +#: ../../po/../src/dialogs/layer-properties.cpp:50 +msgid "Layer name:" +msgstr "Jméno vrstvy:" + +#: ../../po/../src/dialogs/layer-properties.cpp:133 +msgid "Rename Layer" +msgstr "Přejmenovat vrstvu" + +#: ../../po/../src/dialogs/layer-properties.cpp:136 +msgid "_Rename" +msgstr "Přejmenovat" + +#. TRANSLATORS: This means "The layer has been renamed" +#: ../../po/../src/dialogs/layer-properties.cpp:147 +msgid "Renamed layer" +msgstr "Přejmenovaná vrstva" + +#: ../../po/../src/dialogs/layer-properties.cpp:151 +msgid "Add Layer" +msgstr "Přidat Vrstvu" + +#: ../../po/../src/dialogs/layer-properties.cpp:153 +msgid "_Add" +msgstr "Přid_at" + +#: ../../po/../src/dialogs/layer-properties.cpp:167 +msgid "New layer created." +msgstr "Vytvořena nová vrstva" + +#: ../../po/../src/dialogs/object-attributes.cpp:34 +msgid "Href:" +msgstr "Href:" + +#: ../../po/../src/dialogs/object-attributes.cpp:35 +msgid "Target:" +msgstr "Cíl:" + +#: ../../po/../src/dialogs/object-attributes.cpp:36 +msgid "Type:" +msgstr "Typ:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkRoleAttribute +#. Identifies the type of the related resource with an absolute URI +#: ../../po/../src/dialogs/object-attributes.cpp:39 +msgid "Role:" +msgstr "Role:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkArcRoleAttribute +#. For situations where the nature/role alone isn't enough, this offers an additional URI defining the purpose of the link. +#: ../../po/../src/dialogs/object-attributes.cpp:42 +msgid "Arcrole:" +msgstr "Arcrole:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkTitleAttribute +#: ../../po/../src/dialogs/object-attributes.cpp:44 +msgid "Title:" +msgstr "Titulek:" + +#: ../../po/../src/dialogs/object-attributes.cpp:45 +msgid "Show:" +msgstr "Zobrazovat:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkActuateAttribute +#: ../../po/../src/dialogs/object-attributes.cpp:47 +msgid "Actuate:" +msgstr "SpouÅ¡tět:" + +#: ../../po/../src/dialogs/object-attributes.cpp:52 +msgid "URL:" +msgstr "URL:" + +#: ../../po/../src/dialogs/object-attributes.cpp:53 +msgid "X:" +msgstr "X:" + +#: ../../po/../src/dialogs/object-attributes.cpp:54 +msgid "Y:" +msgstr "Y:" + +#: ../../po/../src/dialogs/object-attributes.cpp:98 +#, c-format +msgid "%s attributes" +msgstr "Atributy %s" + +#: ../../po/../src/dialogs/object-properties.cpp:158 +msgid "_Fill" +msgstr "Výplň" + +#: ../../po/../src/dialogs/object-properties.cpp:165 +msgid "Stroke _paint" +msgstr "Vykreslení čáry" + +#: ../../po/../src/dialogs/object-properties.cpp:172 +msgid "Stroke st_yle" +msgstr "Styl čár_y" + +#: ../../po/../src/dialogs/object-properties.cpp:183 +msgid "Master _opacity" +msgstr "Celkové krytí" + +#: ../../po/../src/dialogs/rdf.cpp:244 +msgid "Name by which this document is formally known." +msgstr "Jméno, pod kterým je tento dokument formálně známý." + +#: ../../po/../src/dialogs/rdf.cpp:246 +msgid "Date" +msgstr "Datum" + +#: ../../po/../src/dialogs/rdf.cpp:247 +msgid "Date associated with the creation of this document (YYYY-MM-DD)." +msgstr "Datum spojené s vytvořením tohoto dokumentu (RRRR-MM-DD)" + +#: ../../po/../src/dialogs/rdf.cpp:249 +msgid "Format" +msgstr "Formát" + +#: ../../po/../src/dialogs/rdf.cpp:250 +msgid "The physical or digital manifestation of this document (MIME type)." +msgstr "Fyzický nebo číslicový projev dokumentu (MIME typ)" + +#: ../../po/../src/dialogs/rdf.cpp:252 +msgid "Type" +msgstr "Typ" + +#: ../../po/../src/dialogs/rdf.cpp:253 +msgid "Type of document (DCMI Type)." +msgstr "Typ dokumentu (DCMI Typ)" + +#: ../../po/../src/dialogs/rdf.cpp:256 +msgid "Creator" +msgstr "Tvůrce" + +#: ../../po/../src/dialogs/rdf.cpp:257 +msgid "" +"Name of entity primarily responsible for making the content of this document." +msgstr "Jméno entity přímo odpovědné za vytváření obsahu tohoto dokumentu." + +#: ../../po/../src/dialogs/rdf.cpp:259 +msgid "Rights" +msgstr "Práva" + +#: ../../po/../src/dialogs/rdf.cpp:260 +msgid "" +"Name of entity with rights to the Intellectual Property of this document." +msgstr "Jméno entity s právy k Intelektuálnímu Vlastnictví tohoto dokumentu." + +#: ../../po/../src/dialogs/rdf.cpp:262 +msgid "Publisher" +msgstr "Vydavatel" + +#: ../../po/../src/dialogs/rdf.cpp:263 +msgid "Name of entity responsible for making this document available." +msgstr "Jméno entity zodpovědné za zpřístupnění tohoto dokumentu" + +#: ../../po/../src/dialogs/rdf.cpp:266 +msgid "Identifier" +msgstr "Identifikátor" + +#: ../../po/../src/dialogs/rdf.cpp:267 +msgid "Unique URI to reference this document." +msgstr "Unikátní URI odkazující na tento dokument." + +#: ../../po/../src/dialogs/rdf.cpp:269 +msgid "Source" +msgstr "Zdroj" + +#: ../../po/../src/dialogs/rdf.cpp:270 +msgid "Unique URI to reference the source of this document." +msgstr "Unikátní URI odkazující na zdroj tohoto dokumentu." + +#: ../../po/../src/dialogs/rdf.cpp:272 +msgid "Relation" +msgstr "Vztah" + +#: ../../po/../src/dialogs/rdf.cpp:273 +msgid "Unique URI to a related document." +msgstr "Unikátní URI k souvisejícímu dokumentu." + +#: ../../po/../src/dialogs/rdf.cpp:275 +msgid "Language" +msgstr "Jazyk" + +#: ../../po/../src/dialogs/rdf.cpp:276 +msgid "" +"Two-letter language tag with optional subtags for the language of this " +"document. (e.g. 'en-GB')" +msgstr "" +"Dvou-písmenné označení jazyku s volitelným pod-označením jazyka dokumentu. " +"(např. 'cs-CZ')" + +#: ../../po/../src/dialogs/rdf.cpp:278 +msgid "Keywords" +msgstr "Klíčová slova" + +#: ../../po/../src/dialogs/rdf.cpp:279 +msgid "" +"The topic of this document as comma-separated key words, phrases, or " +"classifications." +msgstr "" +"Téma dokumentu jako čárkami oddělená klíčová slova, fráze nebo hodnocení." + +#. TRANSLATORS: "Coverage": the spatial or temporal characteristics of the content. +#. For info, see Appendix D of http://www.w3.org/TR/1998/WD-rdf-schema-19980409/ +#: ../../po/../src/dialogs/rdf.cpp:283 +msgid "Coverage" +msgstr "Pokrytí" + +#: ../../po/../src/dialogs/rdf.cpp:284 +msgid "Extent or scope of this document." +msgstr "Velikost nebo rozsah tohoto dokumentu." + +#: ../../po/../src/dialogs/rdf.cpp:288 +msgid "A short account of the content of this document." +msgstr "Krátký popis obsahu tohoto dokumentu." + +#. FIXME: need to handle 1 agent per line of input +#: ../../po/../src/dialogs/rdf.cpp:292 +msgid "Contributors" +msgstr "Přispěvatelé" + +#: ../../po/../src/dialogs/rdf.cpp:293 +msgid "" +"Names of entities responsible for making contributions to the content of " +"this document." +msgstr "Jména entit zodpovědných za příspěvky k obsahu tohoto dokumentu." + +#. TRANSLATORS: URL to a page that defines the license for the document +#: ../../po/../src/dialogs/rdf.cpp:297 +msgid "URI" +msgstr "URI" + +#. TRANSLATORS: this is where you put a URL to a page that defines the license +#: ../../po/../src/dialogs/rdf.cpp:299 +msgid "URI to this document's license's namespace definition." +msgstr "URI na definici prostoru jmen licence tohoto dokumentu." + +#. TRANSLATORS: fragment of XML representing the license of the document +#: ../../po/../src/dialogs/rdf.cpp:303 +msgid "Fragment" +msgstr "Fragment" + +#: ../../po/../src/dialogs/rdf.cpp:304 +msgid "XML fragment for the RDF 'License' section." +msgstr "XML fragment pro část RDF 'License'." + +#: ../../po/../src/dialogs/stroke-style.cpp:774 +#: ../../po/../src/widgets/gradient-vector.cpp:263 +#: ../../po/../src/widgets/paint-selector.cpp:751 +msgid "No document selected" +msgstr "Není vybrán žádný dokument" + +#: ../../po/../src/dialogs/stroke-style.cpp:992 +msgid "Stroke width" +msgstr "Šířka čáry" + +#. Join type +#. TRANSLATORS: The line join style specifies the shape to be used at the +#. corners of paths. It can be "miter", "round" or "bevel". +#: ../../po/../src/dialogs/stroke-style.cpp:1015 +msgid "Join:" +msgstr "Rohy a spoje:" + +#. TRANSLATORS: Miter join: joining lines with a sharp (pointed) corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1027 +msgid "Miter join" +msgstr "Ostrý roh" + +#. TRANSLATORS: Round join: joining lines with a rounded corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1035 +msgid "Round join" +msgstr "Kulatý spoj" + +#. TRANSLATORS: Bevel join: joining lines with a blunted (flattened) corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1043 +msgid "Bevel join" +msgstr "Sražená hrana spoje" + +#. Miterlimit +#. TRANSLATORS: Miter limit: only for "miter join", this limits the length +#. of the sharp "spike" when the lines connect at too sharp an angle. +#. When two line segments meet at a sharp angle, a miter join results in a +#. spike that extends well beyond the connection point. The purpose of the +#. miter limit is to cut off such spikes (i.e. convert them into bevels) +#. when they become too long. +#: ../../po/../src/dialogs/stroke-style.cpp:1054 +msgid "Miter limit:" +msgstr "Limit rohu" + +#: ../../po/../src/dialogs/stroke-style.cpp:1062 +msgid "Maximum length of the miter (in units of stroke width)" +msgstr "Maximální délka rohu (v jednotkách šířky čáry)" + +#. Cap type +#. TRANSLATORS: cap type specifies the shape for the ends of lines +#: ../../po/../src/dialogs/stroke-style.cpp:1075 +msgid "Cap:" +msgstr "Konec čáry:" + +#. TRANSLATORS: Butt cap: the line shape does not extend beyond the end point +#. of the line; the ends of the line are square +#: ../../po/../src/dialogs/stroke-style.cpp:1086 +msgid "Butt cap" +msgstr "Rovný konec" + +#. TRANSLATORS: Round cap: the line shape extends beyond the end point of the +#. line; the ends of the line are rounded +#: ../../po/../src/dialogs/stroke-style.cpp:1093 +msgid "Round cap" +msgstr "Kulatý konec" + +#. TRANSLATORS: Square cap: the line shape extends beyond the end point of the +#. line; the ends of the line are square +#: ../../po/../src/dialogs/stroke-style.cpp:1100 +msgid "Square cap" +msgstr "Čtvercový konec" + +#. Dash +#: ../../po/../src/dialogs/stroke-style.cpp:1106 +msgid "Dashes:" +msgstr "Typ čáry:" + +#. TRANSLATORS: Path markers are an SVG feature that allows you to attach arbitrary shapes +#. (arrowheads, bullets, faces, whatever) to the start, end, or middle nodes of a path. +#: ../../po/../src/dialogs/stroke-style.cpp:1127 +msgid "Start Markers:" +msgstr "Značka začátku čáry:" + +#: ../../po/../src/dialogs/stroke-style.cpp:1137 +msgid "Mid Markers:" +msgstr "Značka středu čáry:" + +#: ../../po/../src/dialogs/stroke-style.cpp:1148 +msgid "End Markers:" +msgstr "Značka konce čáry:" + +#: ../../po/../src/dialogs/swatches.cpp:424 +#, c-format +msgid "Palettes directory (%s) is unavailable." +msgstr "Adresář pro palety (%s) je nedostupný" + +#. TODO: Insert widgets +#: ../../po/../src/dialogs/text-edit.cpp:199 +#: ../../po/../src/ui/dialog/text-properties.cpp:36 +msgid "Font" +msgstr "Font" + +#: ../../po/../src/dialogs/text-edit.cpp:216 +msgid "Layout" +msgstr "Rozložení" + +#: ../../po/../src/dialogs/text-edit.cpp:229 +msgid "Align lines left" +msgstr "Zarovnání vlevo" + +#. TRANSLATORS: `Center' here is a verb. +#: ../../po/../src/dialogs/text-edit.cpp:243 +msgid "Center lines" +msgstr "Zarovnání na střed" + +#: ../../po/../src/dialogs/text-edit.cpp:256 +msgid "Align lines right" +msgstr "Zarovnání vpravo" + +#: ../../po/../src/dialogs/text-edit.cpp:278 +msgid "Horizontal text" +msgstr "Vodorovný text" + +#: ../../po/../src/dialogs/text-edit.cpp:292 +msgid "Vertical text" +msgstr "Svislý text" + +#: ../../po/../src/dialogs/text-edit.cpp:307 +msgid "Line spacing:" +msgstr "Mezery mezi řádky:" + +#: ../../po/../src/dialogs/text-edit.cpp:400 +msgid "Set as default" +msgstr "Nastavit jako výchozí" + +#: ../../po/../src/dialogs/tiledialog.cpp:603 +msgid "Rows:" +msgstr "Řádky:" + +#: ../../po/../src/dialogs/tiledialog.cpp:613 +msgid "Number of rows" +msgstr "Počet řádků" + +#: ../../po/../src/dialogs/tiledialog.cpp:617 +msgid "Equal height" +msgstr "Rovnoměrná výška" + +#: ../../po/../src/dialogs/tiledialog.cpp:627 +msgid "If not set, each row has the height of the tallest object in it" +msgstr "Pokud není nastaveno pak má každý řádek výšku jejího nejvyššího prvku" + +#. #### Radio buttons to control vertical alignment #### +#. #### Radio buttons to control horizontal alignment #### +#: ../../po/../src/dialogs/tiledialog.cpp:637 +#: ../../po/../src/dialogs/tiledialog.cpp:708 +msgid "Align:" +msgstr "Zarovnat:" + +#: ../../po/../src/dialogs/tiledialog.cpp:672 +msgid " X " +msgstr " X " + +#. #### Number of columns #### +#: ../../po/../src/dialogs/tiledialog.cpp:678 +msgid "Columns:" +msgstr "Sloupce:" + +#: ../../po/../src/dialogs/tiledialog.cpp:688 +msgid "Number of columns" +msgstr "Počet sloupců" + +#: ../../po/../src/dialogs/tiledialog.cpp:692 +msgid "Equal width" +msgstr "Rovnoměrná šřka" + +#: ../../po/../src/dialogs/tiledialog.cpp:701 +msgid "If not set, each column has the width of the widest object in it" +msgstr "" +"Pokud není nastaveno pak má každý sloupec šířku jejího nejÅ¡iršího prvku" + +#. #### Radio buttons to control spacing manually or to fit selection bbox #### +#: ../../po/../src/dialogs/tiledialog.cpp:746 +msgid "Fit into selection box" +msgstr "Přizpůsobit hranicím výběru" + +#: ../../po/../src/dialogs/tiledialog.cpp:753 +msgid "Set spacing:" +msgstr "Nastavit rozestupy:" + +#. #### Y Padding #### +#: ../../po/../src/dialogs/tiledialog.cpp:777 +msgid "Row spacing: " +msgstr "Mezera mezi řádky:" + +#: ../../po/../src/dialogs/tiledialog.cpp:786 +msgid "Vertical spacing between rows" +msgstr "Svislé mezery mezi řádky" + +#. #### X padding #### +#: ../../po/../src/dialogs/tiledialog.cpp:795 +msgid "Column spacing:" +msgstr "Mezery mezi sloupci:" + +#: ../../po/../src/dialogs/tiledialog.cpp:804 +msgid "Horizontal spacing between columns" +msgstr "Vodorovné mezery mezi sloupci" + +#: ../../po/../src/dialogs/tiledialog.cpp:818 +#, fuzzy +msgid "Arrange selected objects" +msgstr "Seskupit vybrané objekty" + +#: ../../po/../src/dialogs/xml-tree.cpp:178 +msgid "Click to select nodes, drag to rearrange." +msgstr "Kliknutím vyberete uzly, tažením je upravíte." + +#: ../../po/../src/dialogs/xml-tree.cpp:189 +msgid "Click attribute to edit." +msgstr "Kliknutím upravíte atribut." + +#: ../../po/../src/dialogs/xml-tree.cpp:193 +#, c-format +msgid "" +"Attribute %s selected. Press Ctrl+Enter when done editing to " +"commit changes." +msgstr "Vybrán atribut %s. Stiskem Ctrl+Enter uložíte změny." + +#: ../../po/../src/dialogs/xml-tree.cpp:284 +msgid "Drag to reorder nodes" +msgstr "Táhnutím změňte pořadí uzlů" + +#: ../../po/../src/dialogs/xml-tree.cpp:304 +msgid "New element node" +msgstr "Nový uzel prvku" + +#: ../../po/../src/dialogs/xml-tree.cpp:326 +msgid "New text node" +msgstr "Nový textový uzel" + +#: ../../po/../src/dialogs/xml-tree.cpp:347 +msgid "Duplicate node" +msgstr "Duplikovat uzel" + +#: ../../po/../src/dialogs/xml-tree.cpp:368 +msgid "Delete node" +msgstr "Odstranit uzel" + +#: ../../po/../src/dialogs/xml-tree.cpp:384 +msgid "Unindent node" +msgstr "Odsadit zpět uzel" + +#: ../../po/../src/dialogs/xml-tree.cpp:399 +msgid "Indent node" +msgstr "Odsadit uzel" + +#: ../../po/../src/dialogs/xml-tree.cpp:411 +msgid "Raise node" +msgstr "Zvýšit uzel" + +#: ../../po/../src/dialogs/xml-tree.cpp:423 +msgid "Lower node" +msgstr "Snížit uzel" + +#: ../../po/../src/dialogs/xml-tree.cpp:468 +msgid "Delete attribute" +msgstr "Odstranit atribut" + +#. TRANSLATORS: "Attribute" is a noun here +#: ../../po/../src/dialogs/xml-tree.cpp:513 +msgid "Attribute name" +msgstr "Název atributu" + +#. TRANSLATORS: "Set" is a verb here +#: ../../po/../src/dialogs/xml-tree.cpp:533 +msgid "Set attribute" +msgstr "Nastavit atribut" + +#. TRANSLATORS: "Set" is a verb here +#: ../../po/../src/dialogs/xml-tree.cpp:535 +msgid "Set" +msgstr "Nastavit" + +#. TRANSLATORS: "Attribute" is a noun here +#: ../../po/../src/dialogs/xml-tree.cpp:558 +msgid "Attribute value" +msgstr "Hodnota atributu" + +#: ../../po/../src/dialogs/xml-tree.cpp:1318 +msgid "New element node..." +msgstr "Nový uzel prvku..." + +#: ../../po/../src/dialogs/xml-tree.cpp:1339 +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:100 +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:98 +msgid "Cancel" +msgstr "ZruÅ¡it" + +#: ../../po/../src/dialogs/xml-tree.cpp:1345 +msgid "Create" +msgstr "Vytvořit" + +#: ../../po/../src/dialogs/xml-tree.cpp:1458 +#, c-format +msgid "" +"Cannot set %s: Another element with value %s already exists!" +msgstr "Nelze nastavit %s: Existuje jiný prvek s hodnotou %s!" + +#: ../../po/../src/document.cpp:369 +#, c-format +msgid "New document %d" +msgstr "Nový dokument %d" + +#: ../../po/../src/document.cpp:401 +#, c-format +msgid "Memory document %d" +msgstr "Dokument v paměti %d" + +#: ../../po/../src/document.cpp:524 +#, c-format +msgid "Unnamed document %d" +msgstr "Nepojmenovaný dokument %d" + +#. We hit green anchor, closing Green-Blue-Red +#: ../../po/../src/draw-context.cpp:441 +msgid "Path is closed." +msgstr "Křivka uzavřena" + +#. We hit bot start and end of single curve, closing paths +#: ../../po/../src/draw-context.cpp:456 +msgid "Closing path." +msgstr "Uzavírám křivku." + +#. alpha of color under cursor, to show in the statusbar +#. locale-sensitive printf is OK, since this goes to the UI, not into SVG +#: ../../po/../src/dropper-context.cpp:354 +#, c-format +msgid " alpha %.3g" +msgstr " alfa %.3g" + +#. where the color is picked, to show in the statusbar +#: ../../po/../src/dropper-context.cpp:356 +#, c-format +msgid ", averaged with radius %d" +msgstr ", zprůměrováno s poloměrem %d" + +#: ../../po/../src/dropper-context.cpp:356 +msgid " under cursor" +msgstr " pod kurzorem" + +#. message, to show in the statusbar +#: ../../po/../src/dropper-context.cpp:358 +msgid "Release mouse to set color." +msgstr "Uvolněte myÅ¡ k nastavení barvy." + +#: ../../po/../src/dropper-context.cpp:358 +#: ../../po/../src/tools-switch.cpp:207 +msgid "" +"Click to set fill, Shift+click to set stroke; drag to " +"average color in area; with Alt to pick inverse color; Ctrl+C " +"to copy the color under mouse to clipboard" +msgstr "" +"Kliknutí nastaví barvu výplně, Shift+kliknutí nastaví barvu " +"okraje.Kliknutí a tažení vybere průměrnou barvu oblasti. Ctrl+C zkopíruje barvu pod kurzorem myÅ¡i do schránky." + +#: ../../po/../src/extension/dependency.cpp:244 +msgid "Dependency::" +msgstr "Závislost:" + +#: ../../po/../src/extension/dependency.cpp:245 +msgid " type: " +msgstr " typ: " + +#: ../../po/../src/extension/dependency.cpp:246 +msgid " location: " +msgstr " umístění: " + +#: ../../po/../src/extension/dependency.cpp:247 +msgid " string: " +msgstr " řetězec: " + +#: ../../po/../src/extension/dependency.cpp:250 +msgid " description: " +msgstr " popis: " + +#. static int i = 0; +#. std::cout << "Checking module[" << i++ << "]: " << name << std::endl; +#: ../../po/../src/extension/extension.cpp:244 +msgid "" +" This is caused by an improper .inx file for this extension. An improper ." +"inx file could have been caused by a faulty installation of Inkscape." +msgstr "" +" Toto je způsobeno nesprávným .inx souborem pro toto rozšíření. Nesprávný ." +"inx soubor může být způsoben Å¡patnou instalací Inkscape." + +#: ../../po/../src/extension/extension.cpp:247 +msgid "an ID was not defined for it." +msgstr "pro toto nebylo definováno ID." + +#: ../../po/../src/extension/extension.cpp:251 +msgid "there was no name defined for it." +msgstr "žádné jméno nebylo definováno." + +#: ../../po/../src/extension/extension.cpp:255 +msgid "the XML description of it got lost." +msgstr "XML popis nebo jej ztratilo." + +#: ../../po/../src/extension/extension.cpp:259 +msgid "no implementation was defined for the extension." +msgstr "pro rozšíření nebyla definována žádná implementace" + +#. std::cout << "Failed: " << *(_deps[i]) << std::endl; +#: ../../po/../src/extension/extension.cpp:266 +msgid "a dependency was not met." +msgstr "závislost nebyla splněna." + +#: ../../po/../src/extension/extension.cpp:286 +msgid "Extension \"" +msgstr "Rozšíření \"" + +#: ../../po/../src/extension/extension.cpp:286 +msgid "\" failed to load because " +msgstr "\" se nepodařilo nahrát kvůli " + +#: ../../po/../src/extension/extension.cpp:565 +#, c-format +msgid "Could not create extension error log file '%s'" +msgstr "Nebylo možné nahrát soubor chyb rozšíření '%s'" + +#. This is some filler text, needs to change before relase +#: ../../po/../src/extension/error-file.cpp:56 +msgid "" +"One or more extensions failed to load\n" +"\n" +"The failed extensions have been skipped. Inkscape will continue to run " +"normally but those extensions will be unavailable. For details to " +"troubleshoot this problem, please refer to the error log located at: " +msgstr "" +"Jedno nebo více rozšíření se " +"nepodařilo nahrát\n" +"\n" +"Tato rozšíření budou přeskočena. Inkscape poběží jako obvykle, pouze tato " +"rozšíření nebudou k dispozici. Pro detaily potřebné k vyřeÅ¡ení tohoto " +"problému se prosím podívejte do záznamu chyby uloženém do:" + +#. This is some filler text, needs to change before relase +#: ../../po/../src/extension/error-file.cpp:65 +msgid "Show dialog on startup" +msgstr "Ukázat dialog při startu" + +#: ../../po/../src/extension/implementation/script.cpp:845 +msgid "" +"Inkscape has received an error from the script that it called. The text " +"returned with the error is included below. Inkscape will continue working, " +"but the action you requested has been cancelled." +msgstr "" +"Inkscape obdržel od volaného skriptu chybové hlášení. Text chyby je přiložen " +"níže. Inkscape bude pracovat nadále, pouze Vámi požadovaná akce byla zruÅ¡ena." + +#: ../../po/../src/extension/implementation/script.cpp:858 +msgid "" +"Inkscape has received additional data from the script executed. The script " +"did not return an error, but this may indicate the results will not be as " +"expected." +msgstr "" +"Inkscape obdržel od spuÅ¡těného skriptu dodatečná data. Skript nevrátil " +"chybu, avÅ¡ak tato informace může znamenat, že výsledek nemusí vypadat dle " +"očekávání." + +#: ../../po/../src/extension/init.cpp:173 +msgid "Null external module directory name. Modules will not be loaded." +msgstr "Prázdné jméno adresáře vnějšího modulu. Moduly nebudou nahrány." + +#: ../../po/../src/extension/init.cpp:187 +#, c-format +msgid "" +"Modules directory (%s) is unavailable. External modules in that directory " +"will not be loaded." +msgstr "" +"Adresář s moduly (%s) je nedostupný. Externí moduly v tomto adresáři nebudou " +"načteny." + +#: ../../po/../src/extension/internal/gnome.cpp:80 +msgid "Select printer" +msgstr "Vyberte tiskárnu" + +#: ../../po/../src/extension/internal/gnome.cpp:131 +msgid "Inkscape: Print Preview" +msgstr "Inkscape: Náhled tisku" + +#: ../../po/../src/extension/internal/grid.cpp:213 +msgid "Line Width" +msgstr "Šířka čáry" + +#: ../../po/../src/extension/internal/grid.cpp:214 +msgid "Horizontal Spacing" +msgstr "Vodorovné mezery" + +#: ../../po/../src/extension/internal/grid.cpp:215 +msgid "Vertical Spacing" +msgstr "Svislé mezery" + +#: ../../po/../src/extension/internal/grid.cpp:216 +msgid "Horizontal Offset" +msgstr "Vodorovný posun" + +#: ../../po/../src/extension/internal/grid.cpp:217 +msgid "Vertical Offset" +msgstr "Svislý posun" + +#: ../../po/../src/extension/internal/ps.cpp:123 +msgid "Print Destination" +msgstr "Cíl tisku" + +#. Print properties frame +#: ../../po/../src/extension/internal/ps.cpp:138 +msgid "Print properties" +msgstr "Vlastnosti tisku" + +#: ../../po/../src/extension/internal/ps.cpp:145 +msgid "Print using PostScript operators" +msgstr "Tisknout pomocí operátorů PostScript" + +#: ../../po/../src/extension/internal/ps.cpp:147 +msgid "" +"Use PostScript vector operators. The resulting image is usually smaller in " +"file size and can be arbitrarily scaled, but alpha transparency and patterns " +"will be lost." +msgstr "" +"Používat vektorové operátory PostScriptu. Velikost souboru s výsledným " +"obrázkem je obvykle menší a obrázek lze libovolně zmenÅ¡ovat či zvětÅ¡ovat, " +"ztratí se vÅ¡ak alfa průhlednost, značky a vzory." + +#: ../../po/../src/extension/internal/ps.cpp:152 +msgid "Print as bitmap" +msgstr "Tisknout jako bitovou mapu" + +#: ../../po/../src/extension/internal/ps.cpp:154 +msgid "" +"Print everything as bitmap. The resulting image is usually larger in file " +"size and cannot be arbitrarily scaled without quality loss, but all objects " +"will be rendered exactly as displayed." +msgstr "" +"Tisknout vÅ¡e jako bitovou mapu. Výsledný obrázek bude (zpravidla) větší a " +"jeho kvalita bude záviset na úrovni zvětÅ¡ení, budou vÅ¡ak vykresleny vÅ¡echny " +"grafické prvky tak, jak jsou zobrazeny" + +#: ../../po/../src/extension/internal/ps.cpp:168 +msgid "Preferred resolution (dots per inch) of bitmap" +msgstr "Upřednostněné rozliÅ¡ení (v bodech na palec) bitové mapy" + +#: ../../po/../src/extension/internal/ps.cpp:182 +msgid "Resolution:" +msgstr "RozliÅ¡ení:" + +#. Print destination frame +#: ../../po/../src/extension/internal/ps.cpp:186 +msgid "Print destination" +msgstr "Cíl tisku" + +#: ../../po/../src/extension/internal/ps.cpp:192 +msgid "" +"Use '> filename' to print to file.\n" +"Use '| prog arg...' to pipe to a program." +msgstr "" +"Použijte '> soubor', chcete-li tisk do souboru.\n" +"Použijte '| prog arg...', chcete-li směrovat tisk do programu" + +#: ../../po/../src/extension/internal/ps.cpp:1227 +msgid "write error occurred" +msgstr "vyskytla se chyba při zápisu" + +#: ../../po/../src/extension/prefdialog.cpp:21 +msgid " Preferences" +msgstr " Nastavení" + +#. We can't call sp_ui_error_dialog because we may be +#. running from the console, in which case calling sp_ui +#. routines will cause a segfault. See bug 1000350 - bryce +#. sp_ui_error_dialog(_("Format autodetect failed. The file is being opened as SVG.")); +#: ../../po/../src/extension/system.cpp:105 +msgid "Format autodetect failed. The file is being opened as SVG." +msgstr "Autodetekce formátu selhala. Soubor bude otevřen jako SVG." + +#. TRANSLATORS: default.svg is localizable - this is the name of the default document +#. template. This way you can localize the default pagesize, translate the name of +#. the default layer, etc. If you wish to localize this file, please create a +#. localized share/templates/default.xx.svg file, where xx is your language code. +#: ../../po/../src/file.cpp:133 +msgid "default.svg" +msgstr "default.cs.svg" + +#: ../../po/../src/file.cpp:215 ../../po/../src/file.cpp:900 +#, c-format +msgid "Failed to load the requested file %s" +msgstr "Selhalo načtení požadovaného souboru %s" + +#: ../../po/../src/file.cpp:240 +msgid "Document not saved yet. Cannot revert." +msgstr "Dokument jeÅ¡tě nebyl uložen. Nelze se vrátit." + +#: ../../po/../src/file.cpp:246 +#, c-format +msgid "Changes will be lost! Are you sure you want to reload document %s?" +msgstr "Změny budou ztraceny! Jste si jisti že chcete obnovit dokument %s?" + +#: ../../po/../src/file.cpp:266 +msgid "Document reverted." +msgstr "Stav dokumentu byl navrácen do uloženého stavu." + +#: ../../po/../src/file.cpp:268 +msgid "Document not reverted." +msgstr "Stav dokumentu nebyl navrácen do uloženého stavu." + +#: ../../po/../src/file.cpp:382 +msgid "Select file to open" +msgstr "Vyberte soubor pro otevření" + +#: ../../po/../src/file.cpp:518 +#, fuzzy, c-format +msgid "Removed %i unused definition in <defs>." +msgid_plural "Removed %i unused definitions in <defs>." +msgstr[0] "Z <defs> bylo odstraněno %i nepoužitých definic." +msgstr[1] "Z <defs> bylo odstraněno %i nepoužitých definic." + +#: ../../po/../src/file.cpp:523 +msgid "No unused definitions in <defs>." +msgstr "Žádné nepoužité položky v <defs>." + +#: ../../po/../src/file.cpp:548 +#, c-format +msgid "" +"No Inkscape extension found to save document (%s). This may have been " +"caused by an unknown filename extension." +msgstr "" +"Nenalezeno žádné rozšíření Inkscape pro uložení dokumentu (%s). Mohlo to " +"být způsobeno neznámou příponou souboru." + +#: ../../po/../src/file.cpp:549 ../../po/../src/file.cpp:557 +msgid "Document not saved." +msgstr "Dokument nebyl uložen." + +#: ../../po/../src/file.cpp:556 +#, c-format +msgid "File %s could not be saved." +msgstr "Soubor %s nemohl být uložen." + +#: ../../po/../src/file.cpp:566 +msgid "Document saved." +msgstr "Dokument uložen." + +#: ../../po/../src/file.cpp:614 +#, c-format +msgid "drawing%s" +msgstr "kresba%s" + +#: ../../po/../src/file.cpp:620 +#, c-format +msgid "drawing-%d%s" +msgstr "kresba-%d%s" + +#: ../../po/../src/file.cpp:655 +msgid "Select file to save to" +msgstr "Vyberte soubor, do kterého se má ukládat" + +#: ../../po/../src/file.cpp:739 +msgid "No changes need to be saved." +msgstr "Nebylo nutné uložit žádné změny." + +#: ../../po/../src/file.cpp:926 +msgid "Select file to import" +msgstr "Vyberte soubor pro import" + +#: ../../po/../src/gradient-context.cpp:263 +msgid "Ctrl: snap gradient angle" +msgstr "Ctrl: přichytávání přechodu k úhlu" + +#: ../../po/../src/gradient-context.cpp:264 +msgid "Shift: draw gradient around the starting point" +msgstr "Shift: kreslit barevný přechod kolem počátečního bodu" + +#. We did an undoable action, but sp_document_done will be called by the knot when released +#. status text; we do not track coords because this branch is run once, not all the time +#. during drag +#: ../../po/../src/gradient-context.cpp:462 +#, c-format +msgid "Gradient for %d objects; with Ctrl to snap angle" +msgstr "Barevný přechodpro %d objektů; s Ctrl přichytává na úhel" + +#: ../../po/../src/gradient-context.cpp:464 +msgid "Select objects on which to create gradient." +msgstr "Vyberte objekty, ve kterých chcete vytvořit barevný přechod" + +#: ../../po/../src/gradient-drag.cpp:65 +msgid "Linear gradient start" +msgstr "Začátek lineárního přechodu" + +#. POINT_LG_P1 +#: ../../po/../src/gradient-drag.cpp:66 +msgid "Linear gradient end" +msgstr "Konec lineárního přechodu" + +#: ../../po/../src/gradient-drag.cpp:67 +msgid "Radial gradient center" +msgstr "Kruhový přechod: střed" + +#: ../../po/../src/gradient-drag.cpp:68 ../../po/../src/gradient-drag.cpp:69 +msgid "Radial gradient radius" +msgstr "Kruhový přechod: poloměr" + +#: ../../po/../src/gradient-drag.cpp:70 +msgid "Radial gradient focus" +msgstr "Kruhový přechod: zaostření" + +#: ../../po/../src/gradient-drag.cpp:659 +#, c-format +msgid "" +"%s for: %s%s; drag with Ctrl to snap angle, with Ctrl+Alt to " +"preserve angle, with Ctrl+Shift to scale around center" +msgstr "" +"%s pro: %s%s; Tažením s Ctrl přichytává na úhly, s Ctrl+Alt " +"zachovává úhel, s Ctrl+Shift mění měřítko kolem středu" + +#: ../../po/../src/gradient-drag.cpp:662 +msgid " (stroke)" +msgstr " (okraj)" + +#: ../../po/../src/gradient-drag.cpp:665 +msgid "" +"Radial gradient center and focus; drag with Shift to " +"separate focus" +msgstr "" +"Kruhový přechod střed a těžiÅ¡tě; tažením s Shift lze " +"těžiÅ¡tě oddělit" + +#: ../../po/../src/gradient-drag.cpp:667 +#, c-format +msgid "" +"Gradient point shared by %d gradients; drag with Shift to " +"separate" +msgstr "" +"Bod přechodu je sdílen s dalšími %d barevnými přechody; přesunem za " +"držení Shift jej oddělíte" + +#: ../../po/../src/helper/units.cpp:40 +msgid "Unit" +msgstr "Jednotka" + +#: ../../po/../src/helper/units.cpp:40 +msgid "Units" +msgstr "Jednotky" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Point" +msgstr "Bod" + +#: ../../po/../src/helper/units.cpp:41 +msgid "pt" +msgstr "pt" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Points" +msgstr "Body" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Pt" +msgstr "Pt" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Pixel" +msgstr "Pixel" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Pixels" +msgstr "Pixely" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Px" +msgstr "Px" + +#. You can add new elements from this point forward +#: ../../po/../src/helper/units.cpp:44 ../share/extensions/straightseg.inx.h:2 +msgid "Percent" +msgstr "Procento" + +#: ../../po/../src/helper/units.cpp:44 +msgid "Percents" +msgstr "Procenta" + +#: ../../po/../src/helper/units.cpp:45 +msgid "Millimeter" +msgstr "Milimetr" + +#: ../../po/../src/helper/units.cpp:45 +msgid "mm" +msgstr "mm" + +#: ../../po/../src/helper/units.cpp:45 +msgid "Millimeters" +msgstr "Milimetry" + +#: ../../po/../src/helper/units.cpp:46 +msgid "Centimeter" +msgstr "Centimetr" + +#: ../../po/../src/helper/units.cpp:46 +msgid "cm" +msgstr "cm" + +#: ../../po/../src/helper/units.cpp:46 +msgid "Centimeters" +msgstr "Centimetry" + +#: ../../po/../src/helper/units.cpp:47 +msgid "Meter" +msgstr "Metr" + +#: ../../po/../src/helper/units.cpp:47 +msgid "m" +msgstr "m" + +#: ../../po/../src/helper/units.cpp:47 +msgid "Meters" +msgstr "Metrů" + +#. no svg_unit +#: ../../po/../src/helper/units.cpp:48 +msgid "Inch" +msgstr "Palec" + +#: ../../po/../src/helper/units.cpp:48 +msgid "in" +msgstr "in" + +#: ../../po/../src/helper/units.cpp:48 +msgid "Inches" +msgstr "Palců" + +#. Volatiles do not have default, so there are none here +#. TRANSLATORS: for info, see http://www.w3.org/TR/REC-CSS2/syndata.html#length-units +#: ../../po/../src/helper/units.cpp:51 +msgid "Em square" +msgstr "Čtverčík" + +#: ../../po/../src/helper/units.cpp:51 +msgid "em" +msgstr "em" + +#: ../../po/../src/helper/units.cpp:51 +msgid "Em squares" +msgstr "Čtverčíky" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/REC-CSS2/syndata.html#length-units +#: ../../po/../src/helper/units.cpp:53 +msgid "Ex square" +msgstr "Čtverčík ex" + +#: ../../po/../src/helper/units.cpp:53 +msgid "ex" +msgstr "ex" + +#: ../../po/../src/helper/units.cpp:53 +msgid "Ex squares" +msgstr "Čtverčíky ex" + +#: ../../po/../src/inkscape.cpp:468 +msgid "Untitled document" +msgstr "Nepojmenovaný dokument" + +#. Show nice dialog box +#: ../../po/../src/inkscape.cpp:497 +msgid "Inkscape encountered an internal error and will close now.\n" +msgstr "V aplikaci Inkscape doÅ¡lo k vnitřní chybě a bude nyní uzavřena.\n" + +#: ../../po/../src/inkscape.cpp:498 +msgid "" +"Automatic backups of unsaved documents were done to the following " +"locations:\n" +msgstr "Automatické zálohy neuložených dokumentů byly uloženy do:\n" + +#: ../../po/../src/inkscape.cpp:499 +msgid "Automatic backup of the following documents failed:\n" +msgstr "Automatické zálohy následujících dokumentů selhaly:\n" + +#: ../../po/../src/inkscape.cpp:634 +#, c-format +msgid "" +"Cannot create directory %s.\n" +"%s" +msgstr "" +"Nelze vytvořit adresář %s.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:635 +#, c-format +msgid "" +"%s is not a valid directory.\n" +"%s" +msgstr "" +"%s není skutečný adresář.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:636 +#, c-format +msgid "" +"Cannot create file %s.\n" +"%s" +msgstr "" +"Nelze vytvořit soubor %s.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:637 +#, c-format +msgid "" +"Cannot write file %s.\n" +"%s" +msgstr "" +"Nelze zapsat soubor %s.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:638 +msgid "" +"Although Inkscape will run, it will use default settings,\n" +"and any changes made in preferences will not be saved." +msgstr "" +"I když Inkscape poběží, bude využívat výchozí nastavení,\n" +"a žádná změna v nastavení se neuloží." + +#: ../../po/../src/inkscape.cpp:708 +#, c-format +msgid "" +"%s is not a regular file.\n" +"%s" +msgstr "" +"%s není skutečný soubor.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:709 +#, c-format +msgid "" +"%s not a valid XML file, or\n" +"you don't have read permissions on it.\n" +"%s" +msgstr "" +"%s není platný XML soubor, nebo\n" +"nemáte práva k jeho čtení.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:711 +#, c-format +msgid "" +"%s is not a valid menus file.\n" +"%s" +msgstr "" +"%s není platný soubor s menu.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:712 +msgid "" +"Inkscape will run with default menus.\n" +"New menus will not be saved." +msgstr "" +"Inkscape se spustí s výchozími menu\n" +"Nová menu nebudou uložena." + +#. sp_ui_menu_append_check_item_from_verb(m, view, _("_Menu"), _("Show or hide the menu bar"), "menu", +#. checkitem_toggled, checkitem_update, 0); +#: ../../po/../src/interface.cpp:753 +msgid "Commands Bar" +msgstr "Panel příkazů" + +#: ../../po/../src/interface.cpp:753 +msgid "Show or hide the Commands bar (under the menu)" +msgstr "Zobrazit/Skrýt panel Příkazů (pod menu)" + +#: ../../po/../src/interface.cpp:755 +msgid "Tool Controls" +msgstr "Ovládací prvky nástroje" + +#: ../../po/../src/interface.cpp:755 +msgid "Show or hide the Tool Controls panel" +msgstr "Zobrazit nebo skrýt panel s ovládacími prvky nástroje" + +#: ../../po/../src/interface.cpp:757 +msgid "_Toolbox" +msgstr "Nás_troje" + +#: ../../po/../src/interface.cpp:757 +msgid "Show or hide the main toolbox (on the left)" +msgstr "Ukázat nebo skrýt hlavní panel nástrojů (vlevo)" + +#: ../../po/../src/interface.cpp:763 +msgid "_Statusbar" +msgstr "_Stavový řádek" + +#: ../../po/../src/interface.cpp:763 +msgid "Show or hide the statusbar (at the bottom of the window)" +msgstr "Ukázat/Skrýt stavový řádek (vespod okna)" + +#: ../../po/../src/interface.cpp:820 +#, c-format +msgid "Verb \"%s\" Unknown" +msgstr "Příkaz \"%s\" Je Neznámý" + +#. TRANSLATORS: #%s is the id of the group e.g. , not a number. +#: ../../po/../src/interface.cpp:930 +#, c-format +msgid "Enter group #%s" +msgstr "Vstoupit do skupiny #%s" + +#: ../../po/../src/interface.cpp:941 +msgid "Go to parent" +msgstr "Jít na rodičovský prvek" + +#: ../../po/../src/interface.cpp:972 +msgid "Could not parse SVG data" +msgstr "Nebylo možné parsovat SVG data" + +#: ../../po/../src/interface.cpp:1135 +#, c-format +msgid "Overwrite %s" +msgstr "Přepsat %s" + +#: ../../po/../src/interface.cpp:1153 +#, c-format +msgid "" +"The file %s already exists. Do you want to overwrite that file with the " +"current document?" +msgstr "Soubor %s již existuje. Chcete jej přepsat aktuálním dokumentem?" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:59 +msgid "Jabber connection lost." +msgstr "Ztraceno spojení s Jabberem" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:72 +#, fuzzy, c-format +msgid "Sending message; %u message remaining in send queue." +msgid_plural "Sending message; %u messages remaining in send queue." +msgstr[0] "Odesílám zprávu; %u zpráv zbývá ve frontě k odeslání" +msgstr[1] "Odesílám zprávu; %u zpráv zbývá ve frontě k odeslání" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:78 +msgid "Receive queue empty." +msgstr "Fronta na příjmu je prázdná." + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:154 +#, fuzzy, c-format +msgid "Receiving change; %u change left to process." +msgid_plural "Receiving change; %u changes left to process." +msgstr[0] "Příjem změn; %u změn ke zpracování" +msgstr[1] "Příjem změn; %u změn ke zpracování" + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:157 +#, c-format +msgid "%s has left the chatroom." +msgstr "%s opustil místnost." + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:221 +msgid "Nickname %1 is already in use. Please choose a different nickname." +msgstr "Přezdívka %1 je již používána. Prosím zvolte si jinou." + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:225 +msgid "An error was encountered while attempting to connect to the server." +msgstr "Během pokusu o připojení k serveru nastala chyba." + +#. Check to see if the user made any modifications to this document. If so, +#. we want to give them the option of (1) letting us clear their document or (2) +#. opening a new, blank document for the whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:131 +msgid "%1 has invited you to a whiteboard session." +msgstr "%1 Vás pozval do whiteboard sezení." + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:132 +msgid "Incoming whiteboard invitation from %1" +msgstr "Příchozí pozvánka k whiteboard od %1" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:135 +msgid "Do you wish to accept %1's whiteboard session invitation?" +msgstr "Přejete si potvrdit pozvánku k whiteboard od %1?" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:137 +msgid "" +"Would you like to accept %1's invitation in a new document window?\n" +"Accepting the invitation in your current window will discard unsaved changes." +msgstr "" +"Chcete přimout pozvánku od %1 v okně nového dokumentu?\n" +"Akceptováním pozvánky v současném okně dojde k odstranění neuložených změn." + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:143 +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:198 +msgid "Accept invitation" +msgstr "Přijmout pozvání" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:144 +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:199 +msgid "Decline invitation" +msgstr "Odmítnout pozvánku" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:145 +msgid "Accept invitation in new document window" +msgstr "Přimout pozvání v novém okně dokumentu" + +#. We could not create a new desktop; ask the user if she or he wants to +#. replace the current document and accept the invitation, or reject the invitation. +#. TRANSLATORS: %1 is a userid here +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:196 +msgid "" +"A new document window could not be opened for a whiteboard session with %" +"1" +msgstr "" +"Nebylo možné otevřít nové okno dokumentu pro sezení whiteboard %1" + +#. TRANSLATORS: %1 is the peer whom refused our invitation. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:238 +msgid "" +"The user %1 has refused your " +"whiteboard invitation.\n" +"\n" +msgstr "" +"Uživatel %1 odmítl vaÅ¡e " +"pozvání k whiteboard sezení.\n" +"\n" + +#. TRANSLATORS: %1 is the peer whom refused our invitation, %2 is our Jabber identity. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:241 +msgid "" +"You are still connected to a Jabber server as %2, and may send an " +"invitation to %1 again, or you may send an invitation to a different " +"user." +msgstr "" +"Jste stále připojeni k Jabber serveru jako %2 a můžete odeslat znovu " +"pozvánku pro %1 a nebo jinému uživateli." + +#. TRANSLATORS: %1 is the peer whom we tried to contact, but is already in a whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:252 +msgid "" +"The user %1 is already in a " +"whiteboard session.\n" +"\n" +msgstr "" +"Uživatel %1 je již ve " +"whiteboard sezení.\n" +"\n" + +#. TRANSLATORS: %1 is the peer whom we tried to contact, but is already in a whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:255 +msgid "" +"You are still connected to a Jabber server as %1, and may send an " +"invitation to a different user." +msgstr "" +"Jste stále připojen k Jabber serveru jako %1 a můžete odeslat " +"pozvánku jinému uživateli." + +#: ../../po/../src/jabber_whiteboard/invitation-confirm-dialog.cpp:26 +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:24 +msgid "_Write session file:" +msgstr "Zap_sat soubor sezení:" + +#: ../../po/../src/jabber_whiteboard/message-processors.cpp:145 +#, c-format +msgid "%s has joined the chatroom." +msgstr "%s vstoupil do místnosti." + +#: ../../po/../src/jabber_whiteboard/message-queue.cpp:87 +#, fuzzy, c-format +msgid "%u change in receive queue." +msgid_plural "%u changes in receive queue." +msgstr[0] "Nebylo nutné uložit žádné změny." +msgstr[1] "Nebylo nutné uložit žádné změny." + +#: ../../po/../src/jabber_whiteboard/message-queue.cpp:117 +#, fuzzy, c-format +msgid "%u change in send queue." +msgid_plural "%u changes in send queue." +msgstr[0] "Nebylo nutné uložit žádné změny." +msgstr[1] "Nebylo nutné uložit žádné změny." + +#. if ID is NULL, then we have a real problem -- we were not able to find a key +#. nor generate one. The only thing we can really do here is abort, since we have +#. no way to let the other client(s) uniquely identify this object. +#. FIXME: If this indicates a programming bug, then don't request translation with +#. * _(...): it is most useful in untranslated form so that developers may search for +#. * it when someone reports it in a bug report (as we want users to do for all bugs, +#. * as indicated by it being a g_warning string). +#. * +#. * Otherwise, if it is not a programming bug but a network error or a bug in the +#. * remote peer (perhaps running different software) or whatever, then present it in +#. * an alert box, and avoid use of technical jargon `NULL'. +#. +#: ../../po/../src/jabber_whiteboard/message-utilities.cpp:171 +msgid "" +"ID for new object is NULL even after generation and lookup attempts: the new " +"object will NOT be sent, nor will any of its child objects!" +msgstr "" +"ID nového objektu je NULL dokonce i po opětovném vygenerování a pokusech o " +"vyhledání: nový objekt NEBUDE odeslán a ani žádný z jeho potomků!" + +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:60 +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:995 +msgid "Select a location and filename" +msgstr "Vyberte umístění a jméno souboru" + +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:62 +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:997 +msgid "Set filename" +msgstr "Nastavit jméno souboru" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:301 +msgid "No SSL certificate was found." +msgstr "SSL certifikát nebyl nalezen" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:304 +msgid "The SSL certificate provided by the Jabber server is untrusted." +msgstr "SSL certifikát poskytnutý Jabber serverem není důvěryhodný" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:307 +msgid "The SSL certificate provided by the Jabber server is expired." +msgstr "SSL certifikát poskytnutý Jabber serverem vyprÅ¡el" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:310 +msgid "" +"The SSL certificate provided by the Jabber server has not been activated." +msgstr "SSL certifikát poskytnutý Jabber serverem nebyl aktivován" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:313 +msgid "" +"The SSL certificate provided by the Jabber server contains a hostname that " +"does not match the Jabber server's hostname." +msgstr "" +"SSL certifikát poskytnutý Jabber serverem obsahuje jméno hostitele, které " +"nesouhlasí se jménem Jabber serveru." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:316 +msgid "" +"The SSL certificate provided by the Jabber server contains an invalid " +"fingerprint." +msgstr "SSL certifikát poskytnutý Jabber serverem obsahuje neplatný otisk." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:319 +msgid "An unknown error occurred while setting up the SSL connection." +msgstr "Nastala neznámá chyba při sestavování SSL spojení." + +#. TRANSLATORS: %1 is the message that describes the specific error that occurred when +#. establishing the SSL connection. +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:325 +msgid "" +"%1\n" +"\n" +"Do you wish to continue connecting to the Jabber server?" +msgstr "" +"%1\n" +"\n" +"Chcete pokračovat v připojování k Jabber serveru?" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:328 +msgid "Continue connecting and ignore further errors" +msgstr "Pokračovat v připojování a ignorovat další chyby" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:329 +msgid "Continue connecting, but warn me of further errors" +msgstr "Pokračovat v připojování, ale varovat při dalších chybách" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:330 +msgid "Cancel connection" +msgstr "ZruÅ¡it spojení" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:777 +#, c-format +msgid "Established whiteboard session with %s." +msgstr "Vytvořeno whiteboard sezení s %s." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:785 +#, c-format +msgid "%s has left the whiteboard session." +msgstr "%s právě opustil sezení whiteboard." + +#. Inform the user +#. TRANSLATORS: %1 is the name of the user that disconnected, %2 is the name of the user whom the disconnected user disconnected from. +#. This message is not used in a chatroom context. +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:790 +msgid "" +"The user %1 has left the " +"whiteboard session.\n" +"\n" +msgstr "" +"Uživatel %1 opustil whiteboard " +"sezení.\n" +"\n" + +#. TRANSLATORS: %1 and %2 are userids +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:792 +msgid "" +"You are still connected to a Jabber server as %2, and may establish a " +"new session to %1 or a different user." +msgstr "" +"Stále jste připojeni k Jabber serveru jako %2 a můžete vytvořit nové " +"sezení s %1 nebo jiným uživatelem." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:988 +msgid "" +"Could not open file %1 for session recording.\n" +"The error encountered was: %2.\n" +"\n" +"You may select a different location to record the session, or you may opt to " +"not record this session." +msgstr "" +"nelze otevřít soubor %1 pro ukládání sezení.\n" +"Chyba: %2.\n" +"\n" +"Můžete vybrat jiné místo pro uložení sezení a nebo zvolit možnost neukládat " +"sezení." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:990 +msgid "Choose a different location" +msgstr "Vyberte jiné umístění" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:991 +msgid "Skip session recording" +msgstr "Přeskočit nahrávání sezení" + +#: ../../po/../src/knot.cpp:673 +msgid "Node or handle drag canceled." +msgstr "Přesun uzlu nebo ovládacího bodu zruÅ¡en." + +#: ../../po/../src/libnrtype/FontFactory.cpp:358 +msgid "Ignoring font without family that will crash Pango" +msgstr "Ignoruji font bez rodiny, který by způsobil pád Panga" + +#: ../../po/../src/main.cpp:395 +msgid "Print the Inkscape version number" +msgstr "Vypsat číslo verze Inkscape" + +#: ../../po/../src/main.cpp:400 +msgid "Do not use X server (only process files from console)" +msgstr "Nepoužívat X server (pouze zpracovat soubory z konzole)" + +#: ../../po/../src/main.cpp:405 +msgid "Try to use X server (even if $DISPLAY is not set)" +msgstr "Pokusit se použít X server i pokud není nastavena proměnná $DISPLAY" + +#: ../../po/../src/main.cpp:410 +msgid "Open specified document(s) (option string may be excluded)" +msgstr "Otevřít zadané dokumenty (řetězce s volbami lze vypustit)" + +#: ../../po/../src/main.cpp:411 ../../po/../src/main.cpp:416 +#: ../../po/../src/main.cpp:421 ../../po/../src/main.cpp:483 +#: ../../po/../src/main.cpp:488 ../../po/../src/main.cpp:493 +msgid "FILENAME" +msgstr "SOUBOR" + +#: ../../po/../src/main.cpp:415 +msgid "Print document(s) to specified output file (use '| program' for pipe)" +msgstr "" +"Tisknout dokumenty do zadaného výstupního souboru (pro rouru použijte '| " +"program')" + +#: ../../po/../src/main.cpp:420 +msgid "Export document to a PNG file" +msgstr "Export dokumentu do souboru PNG" + +#: ../../po/../src/main.cpp:425 +msgid "The resolution used for exporting SVG into bitmap (default 90)" +msgstr "RozliÅ¡ení použité pro převod SVG do bitmapy (výchozí je 90)" + +#: ../../po/../src/main.cpp:426 +msgid "DPI" +msgstr "DPI" + +#: ../../po/../src/main.cpp:430 +msgid "" +"Exported area in SVG user units (default is the canvas; 0,0 is lower-left " +"corner)" +msgstr "" +"Exportovaná oblast v SVG uživatelem definovaných jednotkách (výchozí je " +"plátno; 0,0 je levý spodní roh)" + +#: ../../po/../src/main.cpp:431 +msgid "x0:y0:x1:y1" +msgstr "x0:y0:x1:y1" + +#: ../../po/../src/main.cpp:435 +msgid "Exported area is the entire drawing (not canvas)" +msgstr "Exportovaná oblast je celá kresba (ne plátno)" + +#: ../../po/../src/main.cpp:440 +msgid "" +"Snap the bitmap export area outwards to the nearest integer values (in SVG " +"user units)" +msgstr "" +"Přichytit oblast exportu bitmapy vně k nejbližší celočíselné hodnotě (v " +"uživatelem zvolených jednotkách SVG)" + +#: ../../po/../src/main.cpp:445 +msgid "The width of exported bitmap in pixels (overrides export-dpi)" +msgstr "Šířka generované bitmapy v pixelech (přebijí nastavené dpi)" + +#: ../../po/../src/main.cpp:446 +msgid "WIDTH" +msgstr "ŠÍŘKA" + +#: ../../po/../src/main.cpp:450 +msgid "The height of exported bitmap in pixels (overrides export-dpi)" +msgstr "Výška generované bitmapy v pixelech (přebíjí nastavené dpi)" + +#: ../../po/../src/main.cpp:451 +msgid "HEIGHT" +msgstr "VÝŠKA" + +#: ../../po/../src/main.cpp:455 +msgid "The ID of the object to export (overrides export-area)" +msgstr "ID objektu pro export (přebíjí oblast exportu)" + +#: ../../po/../src/main.cpp:456 ../../po/../src/main.cpp:532 +msgid "ID" +msgstr "ID" + +#. TRANSLATORS: this means: "Only export the object whose id is given in --export-id". +#. See "man inkscape" for details. +#: ../../po/../src/main.cpp:462 +msgid "" +"Export just the object with export-id, hide all others (only with export-id)" +msgstr "" +"Exportovat pouze objekt s id k exportu, skryj vÅ¡echny ostatní (pouze s " +"export-id)" + +#: ../../po/../src/main.cpp:467 +msgid "Use stored filename and DPI hints when exporting (only with export-id)" +msgstr "Použít uložený název souboru a DPI při exportu (pouze s export-id)" + +#: ../../po/../src/main.cpp:472 +msgid "Background color of exported bitmap (any SVG-supported color string)" +msgstr "" +"Barva pozadí exportované bitmapy (jakýkoli řetězec s barvou podporovaný SVG)" + +#: ../../po/../src/main.cpp:473 +msgid "COLOR" +msgstr "BARVA" + +#: ../../po/../src/main.cpp:477 +msgid "Background opacity of exported bitmap (either 0.0 to 1.0, or 1 to 255)" +msgstr "" +"Průsvitnost pozadí exportované bitmapy (od 0.0 do 1.0, nebo od 1 do 255)" + +#: ../../po/../src/main.cpp:478 +msgid "VALUE" +msgstr "HODNOTA" + +#: ../../po/../src/main.cpp:482 +msgid "Export document to plain SVG file (no sodipodi or inkscape namespaces)" +msgstr "" +"Export dokumentu do prostého SVG (bez jmenného prostoru inkscape nebo " +"sodipodi)" + +#: ../../po/../src/main.cpp:487 +msgid "Export document to a PS file" +msgstr "Export dokumentu do souboru PS" + +#: ../../po/../src/main.cpp:492 +msgid "Export document to an EPS file" +msgstr "Export dokumentu do souboru EPS" + +#: ../../po/../src/main.cpp:497 +msgid "Convert text object to paths on export (EPS)" +msgstr "Převést textové objekty na křivky při exportu (EPS)" + +#: ../../po/../src/main.cpp:502 +msgid "Export files with the bounding box set to the page size (EPS)" +msgstr "Exportovat soubory s okrajem nastaveným na velikost strany (EPS)" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:508 +msgid "" +"Query the X coordinate of the drawing or, if specified, of the object with --" +"query-id" +msgstr "" +"Dotázat se na X souřadnici kresby, nebo pokud je určeno, objektu s --query-id" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:514 +msgid "" +"Query the Y coordinate of the drawing or, if specified, of the object with --" +"query-id" +msgstr "" +"Dotázat se na Y souřadnici kresby, nebo pokud je určeno, objektu s --query-id" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:520 +msgid "" +"Query the width of the drawing or, if specified, of the object with --query-" +"id" +msgstr "Dotázat se na šířku kresby, nebo pokud je určeno, objektu s --query-id" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:526 +msgid "" +"Query the height of the drawing or, if specified, of the object with --query-" +"id" +msgstr "Dotázat se na výšku kresby, nebo pokud je určeno, objektu s --query-id" + +#: ../../po/../src/main.cpp:531 +msgid "The ID of the object whose dimensions are queried" +msgstr "ID objektu jehož rozměry jsou hledány" + +#. TRANSLATORS: this option makes Inkscape print the name (path) of the extension directory +#: ../../po/../src/main.cpp:537 +msgid "Print out the extension directory and exit" +msgstr "Vytisknout adresář s rozšířeními a skončit" + +#: ../../po/../src/main.cpp:542 +msgid "Show given files one-by-one, switch to next on any key/mouse event" +msgstr "" +"Zobrazit zadané soubory jeden po druhém, přepnout na další při jakékoli " +"události myÅ¡i nebo klávesnice" + +#: ../../po/../src/main.cpp:547 +msgid "Use the new Gtkmm GUI interface" +msgstr "Použije nové GUI využívající Gtkmm" + +#: ../../po/../src/main.cpp:552 +msgid "Remove unused definitions from the defs section(s) of the document" +msgstr "Odstranit nepoužívané definice z defs sekce(í) dokumentu" + +#: ../../po/../src/main.cpp:741 +msgid "" +"[OPTIONS...] [FILE...]\n" +"\n" +"Available options:" +msgstr "" +"[VOLBY...] [SOUBOR...]\n" +"\n" +"Dostupné volby:" + +#: ../../po/../src/menus-skeleton.h:17 +msgid "_New" +msgstr "_Nový" + +#: ../../po/../src/menus-skeleton.h:22 +msgid "Open _Recent" +msgstr "Otevřít nedávné" + +#: ../../po/../src/menus-skeleton.h:53 +msgid "_Edit" +msgstr "Úpravy" + +#: ../../po/../src/menus-skeleton.h:84 +msgid "_View" +msgstr "_Zobrazení" + +#: ../../po/../src/menus-skeleton.h:85 +#, fuzzy +msgid "_Zoom" +msgstr "Lupa" + +#: ../../po/../src/menus-skeleton.h:102 +msgid "Show/Hide" +msgstr "Zobrazit/Skrýt" + +#: ../../po/../src/menus-skeleton.h:107 +msgid "_Display mode" +msgstr "" + +#: ../../po/../src/menus-skeleton.h:126 +msgid "_Layer" +msgstr "_Vrstva" + +#: ../../po/../src/menus-skeleton.h:143 +msgid "_Object" +msgstr "_Objekt" + +#: ../../po/../src/menus-skeleton.h:165 +msgid "_Path" +msgstr "_Křivka" + +#: ../../po/../src/menus-skeleton.h:188 +msgid "_Text" +msgstr "_Text" + +#: ../../po/../src/menus-skeleton.h:200 +msgid "Effects" +msgstr "Efekty" + +#: ../../po/../src/menus-skeleton.h:207 +msgid "Whiteboa_rd" +msgstr "Whiteboa_rd" + +#: ../../po/../src/menus-skeleton.h:220 +msgid "_Help" +msgstr "_Nápověda" + +#: ../../po/../src/menus-skeleton.h:222 +msgid "Tutorials" +msgstr "Návody" + +#: ../../po/../src/node-context.cpp:382 +msgid "" +"Ctrl: toggle node type, snap handle angle, move hor/vert; Ctrl" +"+Alt: move along handles" +msgstr "" +"Ctrl přepne typ uzlu, přichytává ovládací bod, přesunuje svisle/" +"vodorovně;Ctrl+Alt: posunuje podél ovládacích bodů" + +#: ../../po/../src/node-context.cpp:383 +msgid "" +"Shift: toggle node selection, disable snapping, rotate both handles" +msgstr "" +"Shift: přidá uzel k vybraným, vypíná přichytávání, otáčí oběma úchyty" + +#: ../../po/../src/node-context.cpp:384 +msgid "Alt: lock handle length; Ctrl+Alt: move along handles" +msgstr "" +"Alt: zamkne délku ovl. prvku; Ctrl+Alt: přesun podél ovl. prvků" + +#: ../../po/../src/nodepath.cpp:1399 ../../po/../src/nodepath.cpp:1411 +#: ../../po/../src/nodepath.cpp:1492 ../../po/../src/nodepath.cpp:1504 +msgid "To join, you must have two endnodes selected." +msgstr "Pro spojení je nutné vybrat dva koncové uzly." + +#: ../../po/../src/nodepath.cpp:1633 ../../po/../src/nodepath.cpp:1647 +msgid "" +"Select two non-endpoint nodes on a path between which to delete " +"segments." +msgstr "" +"Vyberte dva ne-koncové body na křivce mezi kterými chcete vymazat " +"segmenty." + +#: ../../po/../src/nodepath.cpp:1743 +msgid "Cannot find path between nodes." +msgstr "Nemohu nalézt křivku mezi uzly" + +#: ../../po/../src/nodepath.cpp:2822 +#, c-format +msgid "" +"Node handle: angle %0.2f°, length %s; with Ctrl to snap " +"angle; with Alt to lock length; with Shift to rotate both " +"handles" +msgstr "" +"Ovládací bod uzlu: na %0.2f° délka %s; s Ctrl přichytává " +"k úhlu; s Alt se uzamkne délka; s Shift se otáčí oba ovládací " +"prvky." + +#: ../../po/../src/nodepath.cpp:3351 +msgid "" +"Node: drag to edit the path; with Ctrl to snap to horizontal/" +"vertical; with Ctrl+Alt to snap to handles' directions" +msgstr "" +"Uzel: tažením upraví křivku; s Ctrl přichytává s svislé/" +"vodorovné ose; s Ctrl+Alt přichytává k směru kontrolních přímek." + +#: ../../po/../src/nodepath.cpp:3375 +msgid "" +"Node handle: drag to shape the curve; with Ctrl to snap angle; " +"with Alt to lock length; with Shift to rotate both handles" +msgstr "" +"Ovládací bod uzlu: tažením lze tvarovat křivku; s Ctrl " +"přichytává k úhlu; s Alt se uzamkne délka; s Shift se otáčí " +"oba ovládací body." + +#: ../../po/../src/nodepath.cpp:3399 +msgid "" +"Node handle: drag to shape the curve; with Ctrl to snap angle; " +"with Alt to lock length; with Shift to rotate the opposite " +"handle in sync" +msgstr "" +"Ovládací bod uzlu: tažením lze tvarovat křivku; s Ctrl " +"přichytává k úhlu; s Alt se uzamkne délka; s Shift se otáčí " +"protější ovl. bod." + +#. TRANSLATORS: "end" is an adjective here (NOT a verb) +#: ../../po/../src/nodepath.cpp:3591 +msgid "end node" +msgstr "koncový uzel" + +#. TRANSLATORS: "cusp" means "sharp" (cusp node); see also the Advanced Tutorial +#: ../../po/../src/nodepath.cpp:3596 +msgid "cusp" +msgstr "hrot" + +#. TRANSLATORS: "smooth" is an adjective here +#: ../../po/../src/nodepath.cpp:3599 +msgid "smooth" +msgstr "hladké" + +#: ../../po/../src/nodepath.cpp:3601 +msgid "symmetric" +msgstr "symetrické" + +#. TRANSLATORS: "end" is an adjective here (NOT a verb) +#: ../../po/../src/nodepath.cpp:3607 +msgid "end node, handle retracted (drag with Shift to extend)" +msgstr "" +"ukončovací uzel, ovládací bod byl stažen (tažením s Shift jej opět " +"vytáhnete)" + +#: ../../po/../src/nodepath.cpp:3609 +msgid "one handle retracted (drag with Shift to extend)" +msgstr "" +"jeden ovládací bod byl stažen (tažením s Shift jej opět vytáhnete)" + +#: ../../po/../src/nodepath.cpp:3612 +msgid "both handles retracted (drag with Shift to extend)" +msgstr "" +"oba ovládací body byly staženy (tažením s Shift jej opět vytáhnete)" + +#: ../../po/../src/nodepath.cpp:3624 +msgid "Drag nodes or node handles; arrow keys to move nodes" +msgstr "" +"Posunujte uzly nebo ovládacími body pro úpravu křivky; Å¡ipkami " +"posunujete uzly" + +#: ../../po/../src/nodepath.cpp:3625 +msgid "Drag the node or its handles; arrow keys to move the node" +msgstr "" +"Tažení za uzel nebo jeho ovládací prvky; Å¡ipky posunou uzlem" + +#: ../../po/../src/nodepath.cpp:3651 ../../po/../src/nodepath.cpp:3663 +msgid "Select a single object to edit its nodes or handles." +msgstr "Vyberte jeden z objektů pro úpravu jeho uzlů či táhel" + +#: ../../po/../src/nodepath.cpp:3655 +#, fuzzy, c-format +msgid "" +"0 out of %i node selected. Click, Shift+click, " +"or drag around nodes to select." +msgid_plural "" +"0 out of %i nodes selected. Click, Shift+click, " +"or drag around nodes to select." +msgstr[0] "" +"Žádný z %i uzlu nebyl vybrán. kliknutím, Shift" +"+kliknutím, nebo tažením kolem uzlů je vyberete." +msgstr[1] "" +"Žádné z %i uzlů nebyly vybrány. kliknutím, Shift" +"+kliknutím, nebo tažením kolem uzlů je vyberete." + +#: ../../po/../src/nodepath.cpp:3661 +msgid "Drag the handles of the object to modify it." +msgstr "Tažením za táhla objekt změníte." + +#: ../../po/../src/nodepath.cpp:3669 +#, fuzzy, c-format +msgid "%i of %i node selected; %s. %s." +msgid_plural "%i of %i nodes selected; %s. %s." +msgstr[0] "Je vybrán %i ze %i uzlů; %s. %s." +msgstr[1] "Je vybrán %i ze %i uzlů; %s. %s." + +#: ../../po/../src/nodepath.cpp:3675 +#, fuzzy, c-format +msgid "%i of %i node selected. %s." +msgid_plural "%i of %i nodes selected. %s." +msgstr[0] "Je vybrán %i z %i uzlů; %s." +msgstr[1] "Je vybrán %i z %i uzlů; %s." + +#: ../../po/../src/object-edit.cpp:493 +msgid "" +"Adjust the horizontal rounding radius; with Ctrl to make the " +"vertical radius the same" +msgstr "" +"Upraví poloměr vodorovného zaoblení; s Ctrl bude poloměr " +"svislého zaoblení stejné" + +#: ../../po/../src/object-edit.cpp:499 +msgid "" +"Adjust the vertical rounding radius; with Ctrl to make the " +"horizontal radius the same" +msgstr "" +"Upraví poloměr svislého zaoblení; s Ctrl bude poloměr " +"vodorovného zaoblení stejné" + +#: ../../po/../src/object-edit.cpp:506 ../../po/../src/object-edit.cpp:513 +msgid "" +"Adjust the width and height of the rectangle; with Ctrl to " +"lock ratio or stretch in one dimension only" +msgstr "" +"Upraví šířku a výšku čtyřúhelníku; Ctrl uzamkne poměr stran " +"nebo změní pouze jeden rozměr" + +#: ../../po/../src/object-edit.cpp:686 +msgid "Adjust ellipse width, with Ctrl to make circle" +msgstr "Upravit šířku elipsy, s Ctrl vytvoří kružnici" + +#: ../../po/../src/object-edit.cpp:689 +msgid "Adjust ellipse height, with Ctrl to make circle" +msgstr "Upravit výšku elipsy, with Ctrl to make circle" + +#: ../../po/../src/object-edit.cpp:692 +msgid "" +"Position the start point of the arc or segment; with Ctrl to " +"snap angle; drag inside the ellipse for arc, outside for " +"segment" +msgstr "" +"Umístěte počáteční bod oblouku nebo segmentu; s Ctrl " +"přichytává k úhlu; tažením uvnitř elipsy získáte oblouk, zvenčí elipsy kruhový segment" + +#: ../../po/../src/object-edit.cpp:695 +msgid "" +"Position the end point of the arc or segment; with Ctrl to " +"snap angle; drag inside the ellipse for arc, outside for " +"segment" +msgstr "" +"Umístěte koncový bod oblouku nebo segmentu; s Ctrl přichytává " +"k úhlu; tažením uvnitř elipsy získáte oblouk, zvenčí elipsy " +"kruhový segment" + +#: ../../po/../src/object-edit.cpp:800 +msgid "" +"Adjust the tip radius of the star or polygon; with Shift to " +"round; with Alt to randomize" +msgstr "" +"Upraví poloměr hrotu hvězdy nebo mnohoúhelníku; Shift " +"zaobluje; s Alt náhodně" + +#: ../../po/../src/object-edit.cpp:803 +msgid "" +"Adjust the base radius of the star; with Ctrl to keep star " +"rays radial (no skew); with Shift to round; with Alt to " +"randomize" +msgstr "" +"Upraví poloměr základny hvězdy nebo mnohoúhelníku; Ctrl udrží " +"paprsky hvězdy v kruhu (bez zkosení) Shift zaobluje; s Alt " +"náhodně" + +#: ../../po/../src/object-edit.cpp:967 +msgid "" +"Roll/unroll the spiral from inside; with Ctrl to snap angle; " +"with Alt to converge/diverge" +msgstr "" +"Zavinout/Rozvinout spirálu zevnitř; Ctrl přichytává na úhel;" +"Alt ovládá sbíhavost/rozbíhavost" + +#: ../../po/../src/object-edit.cpp:969 +msgid "" +"Roll/unroll the spiral from outside; with Ctrl to snap angle; " +"with Shift to scale/rotate" +msgstr "" +"Zavinout/Rozvinout spirálu zvenčí; Ctrl přichytává na úhel;" +"Shift mění velikost/rotaci" + +#: ../../po/../src/object-edit.cpp:1006 +msgid "Adjust the offset distance" +msgstr "Upravit vzdálenost posunu" + +#. TRANSLATORS: This refers to the pattern that's inside the object +#: ../../po/../src/object-edit.cpp:1036 +msgid "Move the pattern fill inside the object" +msgstr "Přesunout vzorek výplně uvnitř objektu" + +#: ../../po/../src/object-edit.cpp:1038 +msgid "Scale the pattern fill uniformly" +msgstr "Měnit měřítko výplně stejnoměrně" + +#: ../../po/../src/object-edit.cpp:1040 +msgid "Rotate the pattern fill; with Ctrl to snap angle" +msgstr "Rotovat výplň vzorkem; Ctrl přichytává k úhlům" + +#: ../../po/../src/object-edit.cpp:1065 +msgid "Drag to resize the flowed text frame" +msgstr "Tažením změníte velikost rámu pro vlitý text" + +#. Item dialog +#: ../../po/../src/object-ui.cpp:106 +msgid "Object _Properties" +msgstr "Vlastnosti Objektu" + +#. Select item +#: ../../po/../src/object-ui.cpp:116 +msgid "_Select This" +msgstr "Vybrat toto" + +#. Create link +#: ../../po/../src/object-ui.cpp:126 +msgid "_Create Link" +msgstr "Vytvořit odkaz" + +#. "Ungroup" +#: ../../po/../src/object-ui.cpp:199 ../../po/../src/verbs.cpp:1931 +msgid "_Ungroup" +msgstr "ZruÅ¡it seskupení" + +#. Link dialog +#: ../../po/../src/object-ui.cpp:239 +msgid "Link _Properties" +msgstr "Vlastnosti odkazu" + +#. Select item +#: ../../po/../src/object-ui.cpp:249 +msgid "_Follow Link" +msgstr "Následovat odkaz" + +#. Reset transformations +#: ../../po/../src/object-ui.cpp:254 +msgid "_Remove Link" +msgstr "Odstranit odkaz" + +#. Link dialog +#: ../../po/../src/object-ui.cpp:303 +msgid "Image _Properties" +msgstr "Vlastnosti obrázku" + +#. Item dialog +#: ../../po/../src/object-ui.cpp:344 +msgid "_Fill and Stroke" +msgstr "Výplň a čáry" + +#: ../../po/../src/path-chemistry.cpp:58 +msgid "Select at least two objects to combine." +msgstr "Vyberte nejméně dva objekty pro kombinaci." + +#: ../../po/../src/path-chemistry.cpp:65 +msgid "At least one of the objects is not a path, cannot combine." +msgstr "Nejméně jeden z objektů není křivkou, nelze kombinovat." + +#: ../../po/../src/path-chemistry.cpp:73 +msgid "" +"You cannot combine objects from different groups or layers." +msgstr "Nelze kombinovat objekty z různých skupin nebo vrstev." + +#: ../../po/../src/path-chemistry.cpp:155 +msgid "Select path(s) to break apart." +msgstr "Vyberte křivku(y) k rozdělení." + +#: ../../po/../src/path-chemistry.cpp:231 +msgid "No path(s) to break apart in the selection." +msgstr "Žádné křivky na rozbití nebyly vybrány." + +#: ../../po/../src/path-chemistry.cpp:252 +msgid "Select object(s) to convert to path." +msgstr "Vyberte objekt(y) k převodu na křivku." + +#: ../../po/../src/path-chemistry.cpp:297 +msgid "No objects to convert to path in the selection." +msgstr "Ve výběru nejsou žádné objekty k převodu na křivku." + +#: ../../po/../src/path-chemistry.cpp:345 +msgid "Select path(s) to reverse." +msgstr "Vyberte křivky k převrácení." + +#: ../../po/../src/path-chemistry.cpp:370 +msgid "No paths to reverse in the selection." +msgstr "Žádné křivky k převrácení nebyly vybrány." + +#: ../../po/../src/pen-context.cpp:379 ../../po/../src/pencil-context.cpp:233 +msgid "Continuing selected path" +msgstr "Pokračuje ve vybrané křivce" + +#: ../../po/../src/pen-context.cpp:390 ../../po/../src/pencil-context.cpp:242 +msgid "Creating new path" +msgstr "Vytvářím novou křivku" + +#: ../../po/../src/pen-context.cpp:394 ../../po/../src/pencil-context.cpp:246 +msgid "Appending to selected path" +msgstr "Připojuje k vybrané křivce" + +#: ../../po/../src/pen-context.cpp:538 +msgid "Click or click and drag to close and finish the path." +msgstr "" +"Kliknutím nebo cliknutím a tažením uzavřete a ukončete křivku." + +#: ../../po/../src/pen-context.cpp:548 +msgid "" +"Click or click and drag to continue the path from this point." +msgstr "" +"Kliknutím nebo cliknutím a tažením pokračujte v křivce z " +"tohoto bodu." + +#: ../../po/../src/pen-context.cpp:857 +#, c-format +msgid "" +"%s: angle %3.2f°, distance %s; with Ctrl to snap angle, " +"Enter to finish the path" +msgstr "" +"%s: ůhel %3.2f° vzdálenost %s; s Ctrl přichytává k úhlu; " +"s Enter ukončí křivku" + +#: ../../po/../src/pen-context.cpp:882 +#, c-format +msgid "" +"Curve handle: angle %3.2f°, length %s; with Ctrl to snap " +"angle" +msgstr "" +"Ovládací prvek křivky: ůhel %3.2f°, délka %s; Ctrl " +"přichytává k úhlům" + +#: ../../po/../src/pen-context.cpp:912 +#, c-format +msgid "" +"%s: angle %3.2f°, length %s; with Ctrl to snap angle, " +"with Shift to move this handle only" +msgstr "" +"%s: ůhel %3.2f° délka %s; s Ctrl přichytává k úhlu; s " +"Shift přesune pouze zvolený ovládací prvek" + +#: ../../po/../src/pen-context.cpp:946 +msgid "Finishing pen" +msgstr "Dokončování kreslení perem" + +#: ../../po/../src/pencil-context.cpp:320 +msgid "Release here to close and finish the path." +msgstr "Uvolněte zde pro uzavření a ukončení křivky." + +#: ../../po/../src/pencil-context.cpp:326 +msgid "Drawing a freehand path" +msgstr "Kresba od ruky" + +#: ../../po/../src/pencil-context.cpp:331 +msgid "Drag to continue the path from this point." +msgstr "Tažením pokračujte v křivce z tohoto bodu." + +#. Write curves to object +#: ../../po/../src/pencil-context.cpp:390 +msgid "Finishing freehand" +msgstr "Dokončování kreslení od ruky" + +#: ../../po/../src/rect-context.cpp:387 +msgid "" +"Ctrl: make square or integer-ratio rect, lock a rounded corner " +"circular" +msgstr "" +"Ctrl: vytvoří čtverec nebo obdélník s celočíselným poměrem stran, " +"udrží zaoblené rohy kruhovými" + +#: ../../po/../src/rect-context.cpp:549 +#, c-format +msgid "" +"Rectangle: %s × %s; with Ctrl to make square or integer-" +"ratio rectangle; with Shift to draw around the starting point" +msgstr "" +"Obdélník: %s × %s; s Ctrl se vytvoří čtverec nebo " +"obdélník s celočíselným poměrem stran; s Shift se vykreslí kolem " +"počátečního bodu" + +#: ../../po/../src/select-context.cpp:243 +msgid "Move canceled." +msgstr "Přesun zruÅ¡en." + +#: ../../po/../src/select-context.cpp:252 +msgid "Selection canceled." +msgstr "Výběr zruÅ¡en." + +#: ../../po/../src/select-context.cpp:642 +msgid "Ctrl: select in groups, move hor/vert" +msgstr "Ctrl: výběr ve skupinách, přesun vodorovně/svisle" + +#: ../../po/../src/select-context.cpp:643 +msgid "Shift: toggle select, force rubberband, disable snapping" +msgstr "" +"Shift: přepíná stav vybrání, vynutí gumovitost, vypíná přichytávání" + +#: ../../po/../src/select-context.cpp:644 +msgid "Alt: select under, move selected" +msgstr "Alt: vybrat pod, přesun vybraného" + +#: ../../po/../src/select-context.cpp:798 +#, fuzzy +msgid "Selected object is not a group. Cannot enter." +msgstr "Vybraný objekt není křivka, nelze jej smrÅ¡tit/rozšířit." + +#: ../../po/../src/select-context.cpp:876 +#, c-format +msgid "" +"Move by %s, %s; with Ctrl to restrict to horizontal/vertical; " +"with Shift to disable snapping" +msgstr "" +"Přesun o %s, %s; Ctrl zakáže posun v jedné z os; Shift " +"vypne přichytávání" + +#: ../../po/../src/selection-chemistry.cpp:228 +msgid "Nothing was deleted." +msgstr "Nebylo nic vymazáno." + +#: ../../po/../src/selection-chemistry.cpp:259 +msgid "Select object(s) to duplicate." +msgstr "Vyberte objekt(y) k duplikaci." + +#: ../../po/../src/selection-chemistry.cpp:420 +msgid "Select two or more objects to group." +msgstr "Vyberte dva nebo více objektů pro seskupení." + +#: ../../po/../src/selection-chemistry.cpp:428 +msgid "Select at least two objects to group." +msgstr "Vyberte nejméně dva objekty pro seskupení" + +#: ../../po/../src/selection-chemistry.cpp:513 +msgid "Select a group to ungroup." +msgstr "Vyberte skupinu k zruÅ¡ení seskupení" + +#: ../../po/../src/selection-chemistry.cpp:554 +msgid "No groups to ungroup in the selection." +msgstr "Žádné skupiny ke zruÅ¡ení seskupení ve výběru." + +#: ../../po/../src/selection-chemistry.cpp:623 +msgid "Select objects to raise." +msgstr "Vyberte objekty k přesunu výš" + +#: ../../po/../src/selection-chemistry.cpp:629 +#: ../../po/../src/selection-chemistry.cpp:681 +#: ../../po/../src/selection-chemistry.cpp:715 +#: ../../po/../src/selection-chemistry.cpp:773 +msgid "" +"You cannot raise/lower objects from different groups or layers." +msgstr "" +"Nelze přesunout objekty výš či níž z různých skupin nebo vrstev." + +#: ../../po/../src/selection-chemistry.cpp:673 +msgid "Select object(s) to raise to top." +msgstr "Vyberte objekty k přesunu úplně nahoru" + +#: ../../po/../src/selection-chemistry.cpp:709 +msgid "Select object(s) to lower." +msgstr "Vyberte objekty k přesunu níž" + +#: ../../po/../src/selection-chemistry.cpp:765 +msgid "Select object(s) to lower to bottom." +msgstr "Vyberte objekty k přesunu úplně dolů" + +#: ../../po/../src/selection-chemistry.cpp:806 +msgid "Nothing to undo." +msgstr "Nic pro Zpět" + +#: ../../po/../src/selection-chemistry.cpp:813 +msgid "Nothing to redo." +msgstr "Nic pro Opakovat" + +#: ../../po/../src/selection-chemistry.cpp:969 +msgid "Nothing was copied." +msgstr "Nebylo nic kopírováno." + +#: ../../po/../src/selection-chemistry.cpp:1051 +msgid "Current layer is hidden. Unhide it to be able to paste to it." +msgstr "" +"Aktuální vrstva je skrytá. Odkryjte ji aby jste do ní mohli vkládat." + +#: ../../po/../src/selection-chemistry.cpp:1055 +msgid "Current layer is locked. Unlock it to be able to paste to it." +msgstr "" +"Aktuální vrstva je uzamčena. Aby jste na ni mohli vložit objekt, " +"musíte ji odemknout." + +#: ../../po/../src/selection-chemistry.cpp:1068 +#: ../../po/../src/selection-chemistry.cpp:1103 +msgid "Nothing on the clipboard." +msgstr "Schránka je prázdná." + +#: ../../po/../src/selection-chemistry.cpp:1109 +msgid "Select object(s) to paste style to." +msgstr "Vyberte objekty na které aplikovat styl." + +#: ../../po/../src/selection-chemistry.cpp:1128 +msgid "Select object(s) to move to the layer above." +msgstr "Vyberte objekty k přesunu o vrstvu výš." + +#: ../../po/../src/selection-chemistry.cpp:1146 +msgid "No more layers above." +msgstr "Výš nejsou žádné další vrstvy." + +#: ../../po/../src/selection-chemistry.cpp:1160 +msgid "Select object(s) to move to the layer below." +msgstr "Vyberte objekty k přesunu o vrstvu níž." + +#: ../../po/../src/selection-chemistry.cpp:1178 +msgid "No more layers below." +msgstr "Vespod již nejsou žádné další vrstvy" + +#: ../../po/../src/selection-chemistry.cpp:1811 +msgid "Select a clone to unlink." +msgstr "Vyberte klon k odpojení." + +#: ../../po/../src/selection-chemistry.cpp:1842 +msgid "No clones to unlink in the selection." +msgstr "Žádné klony k odpojení ve výběru." + +#: ../../po/../src/selection-chemistry.cpp:1859 +msgid "" +"Select a clone to go to its original. Select a linked offset " +"to go to its source. Select a text on path to go to the path. Select " +"a flowed text to go to its frame." +msgstr "" +"Vyberte klon a dostanete se na jeho originál. Vyberte propojený " +"posun a dostanete se na jeho zdroj. Vyberte text na křivce a " +"získáte jeho křivku. Vyberte vlitý text a dostanete jeho rámec." + +#: ../../po/../src/selection-chemistry.cpp:1882 +msgid "" +"Cannot find the object to select (orphaned clone, offset, textpath, " +"flowed text?)" +msgstr "" +"Nemohu nalézt objekt k výběru (osiřelý klon, posuv, text na křivce " +"nebo vlitý text?)" + +#: ../../po/../src/selection-chemistry.cpp:1888 +msgid "" +"The object you're trying to select is not visible (it is in <" +"defs>)" +msgstr "" +"Objekt který se snažíte vybrat je neviditelný (je v <defs>)" + +#: ../../po/../src/selection-chemistry.cpp:1915 +msgid "Select object(s) to convert to pattern." +msgstr "Vyberte objekty ke konverzi na vzorek." + +#: ../../po/../src/selection-chemistry.cpp:2006 +msgid "Select an object with pattern fill to extract objects from." +msgstr "" +"Vyberte objekt s výplní vzorkem ze kterého se bude extrahovat objekt." + +#: ../../po/../src/selection-chemistry.cpp:2059 +msgid "No pattern fills in the selection." +msgstr "Ve výběru nejsou žádné výplňové vzorky." + +#: ../../po/../src/selection-chemistry.cpp:2079 +msgid "Select object(s) to make a bitmap copy." +msgstr "Vyberte objekt(y) ze kterých chcete vytvořit bitmapovou kopii." + +#: ../../po/../src/selection-describer.cpp:37 +msgid "Click selection to toggle scale/rotation handles" +msgstr "" +"Kliknutím na výběr přepnete ovládací prvky ze změny měřítka na rotaci a " +"naopak" + +#. no items +#: ../../po/../src/selection-describer.cpp:39 +msgid "" +"No objects selected. Click, Shift+click, or drag around objects to select." +msgstr "" +"Žádné objekty nebyly vybrány. Kliknutím, Shift+kliknutím, nebo tažením myší " +"kolem objektů je vyberete." + +#: ../../po/../src/selection-describer.cpp:51 +#, c-format +msgid " in layer %s" +msgstr " ve vrstvě %s" + +#: ../../po/../src/selection-describer.cpp:54 +#, c-format +msgid " in layer %s" +msgstr " ve vrstvě %s" + +#: ../../po/../src/selection-describer.cpp:66 +msgid "Use Shift+D to look up original" +msgstr "Použijte Shift+D k vyhledání originálu" + +#: ../../po/../src/selection-describer.cpp:70 +msgid "Use Shift+D to look up path" +msgstr "Použijte Shift+D k vyhledání křivky" + +#: ../../po/../src/selection-describer.cpp:74 +msgid "Use Shift+D to look up frame" +msgstr "Použijte Shift+D k vyhledání rámce" + +#: ../../po/../src/selection-describer.cpp:84 +#, fuzzy, c-format +msgid "%i object selected" +msgid_plural "%i objects selected" +msgstr[0] "Vybrán objekt %i" +msgstr[1] "Vybrán objekt %i" + +#: ../../po/../src/selection-describer.cpp:90 +#, c-format +msgid "%s%s. %s." +msgstr "%s%s. %s." + +#: ../../po/../src/selection-describer.cpp:94 +#, fuzzy, c-format +msgid "%s in %i layer. %s." +msgid_plural "%s in %i layers. %s." +msgstr[0] "%s v %i vrstvě. %s." +msgstr[1] "%s v %i vrstvě. %s." + +#: ../../po/../src/seltrans.cpp:498 +msgid "" +"Center of rotation and skewing: drag to reposition; scaling with " +"Shift also uses this center" +msgstr "" +"Střed otáčení a naklánění; tažením změníte jeho pozici; Změna " +"velikosti za stisknutého Shift též využívá tento střed." + +#: ../../po/../src/seltrans.cpp:514 +msgid "" +"Squeeze or stretch selection; with Ctrl to scale uniformly; " +"with Shift to scale around rotation center" +msgstr "" +"Zmáčknout nebo natáhnout výběr; Ctrl uzamkne poměr stran; " +"Shift mění velikost kolem středu otáčení" + +#: ../../po/../src/seltrans.cpp:515 +msgid "" +"Scale selection; with Ctrl to scale uniformly; with Shift to scale around rotation center" +msgstr "" +"Změna velikosti výběru; Ctrl uzamkne poměr stran;s Shift se mění velikost kolem středu otáčení" + +#: ../../po/../src/seltrans.cpp:519 +msgid "" +"Skew selection; with Ctrl to snap angle; with Shift to " +"skew around the opposite side" +msgstr "" +"Zkosit výběr; Ctrl přichytává na ůhly; Shift kosí kolem " +"protějšího rohu" + +#: ../../po/../src/seltrans.cpp:520 +msgid "" +"Rotate selection; with Ctrl to snap angle; with Shift " +"to rotate around the opposite corner" +msgstr "" +"Otáčet výběrem; Ctrl přichytává na ůhly; Shift otáčí " +"kolem protějšího rohu" + +#: ../../po/../src/seltrans.cpp:829 ../../po/../src/seltrans.cpp:909 +#, c-format +msgid "Scale: %0.2f%% x %0.2f%%; with Ctrl to lock ratio" +msgstr "Změna měřítka: %0.2f%% × %0.2f%%; s Ctrl zachovává poměr" + +#. TRANSLATORS: don't modify the first ";" (it will NOT be displayed as ";" - only the second one will be) +#: ../../po/../src/seltrans.cpp:984 +#, c-format +msgid "Skew: %0.2f°; with Ctrl to snap angle" +msgstr "Zkosení: %0.2f°; Ctrl přichytává k úhlům" + +#. TRANSLATORS: don't modify the first ";" (it will NOT be displayed as ";" - only the second one will be) +#: ../../po/../src/seltrans.cpp:1035 +#, c-format +msgid "Rotate: %0.2f°; with Ctrl to snap angle" +msgstr "Rotace: %0.2f°; Ctrl přichytává k úhlům" + +#: ../../po/../src/seltrans.cpp:1090 +#, c-format +msgid "Move center to %s, %s" +msgstr "Přesuň střed na %s, %s" + +#: ../../po/../src/slideshow.cpp:90 +msgid "Inkscape slideshow" +msgstr "Promítání snímků" + +#: ../../po/../src/sp-anchor.cpp:181 +#, c-format +msgid "Link to %s" +msgstr "Odkaz na %s" + +#: ../../po/../src/sp-anchor.cpp:185 +msgid "Link without URI" +msgstr "Odkaz bez URI" + +#: ../../po/../src/sp-ellipse.cpp:438 ../../po/../src/sp-ellipse.cpp:870 +msgid "Ellipse" +msgstr "Elipsa" + +#: ../../po/../src/sp-ellipse.cpp:583 +msgid "Circle" +msgstr "Kružnice" + +#: ../../po/../src/sp-ellipse.cpp:865 +msgid "Segment" +msgstr "Segment:" + +#: ../../po/../src/sp-ellipse.cpp:867 +msgid "Arc" +msgstr "Oblouk" + +#. TRANSLATORS: "Flow region" is an area where text is allowed to flow +#: ../../po/../src/sp-flowregion.cpp:276 +msgid "Flow region" +msgstr "Oblast vlití" + +#. TRANSLATORS: A region "cut out of" a flow region; text is not allowed to flow inside the +#. * flow excluded region. flowRegionExclude in SVG 1.2: see +#. * http://www.w3.org/TR/2004/WD-SVG12-20041027/flow.html#flowRegion-elem and +#. * http://www.w3.org/TR/2004/WD-SVG12-20041027/flow.html#flowRegionExclude-elem. +#: ../../po/../src/sp-flowregion.cpp:493 +msgid "Flow excluded region" +msgstr "Výjimka z oblasti vtečení" + +#: ../../po/../src/sp-flowtext.cpp:355 +#, c-format +msgid "Flowed text (%d characters)" +msgstr "Vlitý text (%d znaků)" + +#: ../../po/../src/sp-flowtext.cpp:357 +#, c-format +msgid "Linked flowed text (%d characters)" +msgstr "Propojený vlitý text (%d znaků)" + +#: ../../po/../src/sp-guide.cpp:290 +msgid "vertical guideline" +msgstr "svislá vodící čára" + +#: ../../po/../src/sp-guide.cpp:292 +msgid "horizontal guideline" +msgstr "vodorovná vodící čára" + +#: ../../po/../src/sp-image.cpp:835 +msgid "embedded" +msgstr "vložený" + +#: ../../po/../src/sp-image.cpp:839 +msgid "(null_pointer)" +msgstr "(null_pointer)" + +#: ../../po/../src/sp-image.cpp:843 +#, c-format +msgid "Image with bad reference: %s" +msgstr "Obrázek s chybným odkazem: %s" + +#: ../../po/../src/sp-image.cpp:844 +#, c-format +msgid "Image %d × %d: %s" +msgstr "Obrázek %d × %d: %s" + +#: ../../po/../src/sp-item-group.cpp:390 +#, fuzzy, c-format +msgid "Group of %d object" +msgid_plural "Group of %d objects" +msgstr[0] "Skupina %d objektů" +msgstr[1] "Skupina %d objektů" + +#: ../../po/../src/sp-item.cpp:720 +msgid "Object" +msgstr "Objekt" + +#: ../../po/../src/sp-line.cpp:202 +msgid "Line" +msgstr "Čára:" + +#. TRANSLATORS COMMENT: %s is either "outset" or "inset" depending on sign +#: ../../po/../src/sp-offset.cpp:433 +#, c-format +msgid "Linked offset, %s by %f pt" +msgstr "Propojené rozšíření, %s o %f pt" + +#: ../../po/../src/sp-offset.cpp:434 ../../po/../src/sp-offset.cpp:438 +msgid "outset" +msgstr "rozšířit" + +#: ../../po/../src/sp-offset.cpp:434 ../../po/../src/sp-offset.cpp:438 +msgid "inset" +msgstr "smrÅ¡tit" + +#. TRANSLATORS COMMENT: %s is either "outset" or "inset" depending on sign +#: ../../po/../src/sp-offset.cpp:437 +#, c-format +msgid "Dynamic offset, %s by %f pt" +msgstr "Dynamické vytlačení, %s o %f pt" + +#: ../../po/../src/sp-path.cpp:127 +#, fuzzy, c-format +msgid "Path (%i node)" +msgid_plural "Path (%i nodes)" +msgstr[0] "Křivka (%i uzel)" +msgstr[1] "Křivka (%i uzel)" + +#: ../../po/../src/sp-polygon.cpp:216 +msgid "Polygon" +msgstr "Mnohoúhelník" + +#: ../../po/../src/sp-polyline.cpp:179 +msgid "Polyline" +msgstr "Lomená čára" + +#: ../../po/../src/sp-rect.cpp:250 +msgid "Rectangle" +msgstr "Čtyřúhelník" + +#. TRANSLATORS: since turn count isn't an integer, please adjust the +#. string as needed to deal with an localized plural forms. +#: ../../po/../src/sp-spiral.cpp:305 +#, c-format +msgid "Spiral with %3f turns" +msgstr "Spirála s %3f otočkami" + +#: ../../po/../src/sp-star.cpp:288 +#, fuzzy, c-format +msgid "Star with %d vertex" +msgid_plural "Star with %d vertices" +msgstr[0] "Hvězda s %d vrcholy" +msgstr[1] "Hvězda s %d vrcholy" + +#: ../../po/../src/sp-star.cpp:292 +#, fuzzy, c-format +msgid "Polygon with %d vertex" +msgid_plural "Polygon with %d vertices" +msgstr[0] "Mnohoúhelník s %d vrcholy" +msgstr[1] "Mnohoúhelník s %d vrcholy" + +#. TRANSLATORS: For description of font with no name. +#: ../../po/../src/sp-text.cpp:420 +msgid "<no name found>" +msgstr "<nebylo nalezeno jméno>" + +#: ../../po/../src/sp-text.cpp:426 +#, c-format +msgid "Text on path (%s, %s)" +msgstr "Text na křivce (%s, %s)" + +#: ../../po/../src/sp-text.cpp:427 +#, c-format +msgid "Text (%s, %s)" +msgstr "Text (%s, %s)" + +#. TRANSLATORS: Used for statusbar description for long chains: +#. * "Clone of: Clone of: ... in Layer 1". +#: ../../po/../src/sp-use.cpp:317 +msgid "..." +msgstr "..." + +#: ../../po/../src/sp-use.cpp:325 +#, c-format +msgid "Clone of: %s" +msgstr "Klon: %s" + +#: ../../po/../src/sp-use.cpp:329 +msgid "Orphaned clone" +msgstr "Osiřelý klon" + +#: ../../po/../src/spiral-context.cpp:355 +msgid "Ctrl: snap angle" +msgstr "Ctrl: přichytávání úhlu" + +#: ../../po/../src/spiral-context.cpp:357 +msgid "Alt: lock spiral radius" +msgstr "Alt: zamkne poloměr spirály" + +#: ../../po/../src/spiral-context.cpp:469 +#, c-format +msgid "" +"Spiral: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" +"Spirála: poloměr %s, úhel %5g°; s Ctrl přichytává úhel" + +#: ../../po/../src/splivarot.cpp:106 +msgid "Select at least 2 paths to perform a boolean operation." +msgstr "Vyberte nejméně 2 křivky pro provedení logické operace" + +#: ../../po/../src/splivarot.cpp:112 +msgid "" +"Select exactly 2 paths to perform difference, XOR, division, or path " +"cut." +msgstr "" +"Vyberte přesně 2 křivky k provedení rozdílu, XOR, dělení nebo ořezu " +"křivek" + +#: ../../po/../src/splivarot.cpp:129 ../../po/../src/splivarot.cpp:144 +msgid "" +"Unable to determine the z-order of the objects selected for " +"difference, XOR, division, or path cut." +msgstr "" +"Nelze určit pořadí vybraných objektů pro rozdíl, XOR, dělení, nebo " +"ořez cestou." + +#: ../../po/../src/splivarot.cpp:174 +msgid "" +"One of the objects is not a path, cannot perform boolean operation." +msgstr "Jeden z objektů není křivkou, nemohu provést logickou operaci." + +#. TRANSLATORS: "to outline" means "to convert stroke to path" +#: ../../po/../src/splivarot.cpp:554 +msgid "Select path(s) to outline." +msgstr "Vyberte křivky k převodu na obrys" + +#. TRANSLATORS: "to outline" means "to convert stroke to path" +#: ../../po/../src/splivarot.cpp:748 +msgid "No stroked paths to outline in the selection." +msgstr "Žádné křivky s obrysy na převod na obrys ve výběru." + +#: ../../po/../src/splivarot.cpp:832 +msgid "Selected object is not a path, cannot inset/outset." +msgstr "Vybraný objekt není křivka, nelze jej smrÅ¡tit/rozšířit." + +#: ../../po/../src/splivarot.cpp:1040 +msgid "Select path(s) to inset/outset." +msgstr "Vyberte křivky k smrÅ¡tění/rozšíření." + +#: ../../po/../src/splivarot.cpp:1257 +msgid "No paths to inset/outset in the selection." +msgstr "Žádné křivky k smrÅ¡tění/rozšíření nebyly vybrány." + +#: ../../po/../src/splivarot.cpp:1390 +msgid "Select path(s) to simplify." +msgstr "Vyberte křivku(y) k zjednoduÅ¡ení" + +#: ../../po/../src/splivarot.cpp:1417 +msgid "No paths to simplify in the selection." +msgstr "Žádné křivky k zjednoduÅ¡ení nebyly vybrány." + +#: ../../po/../src/star-context.cpp:362 +msgid "Ctrl: snap angle; keep rays radial" +msgstr "Ctrl: přichytává k úhlům; udržuje paprsky kruhovými" + +#: ../../po/../src/star-context.cpp:470 +#, c-format +msgid "" +"Polygon: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" +"Mnohoúhelník: poloměr %s, úhel %5g°; Ctrl skoky úhlů" + +#: ../../po/../src/star-context.cpp:471 +#, c-format +msgid "Star: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" +"Hvězda: poloměr %s, úhel %5g°; s Ctrl přichytávání úhlu" + +#: ../../po/../src/text-chemistry.cpp:90 +msgid "Select a text and a path to put text on path." +msgstr "Vyberte text a křivku k umístění textu na křivku." + +#: ../../po/../src/text-chemistry.cpp:95 +msgid "" +"This text object is already put to a path. Remove it from the path " +"first. Use Shift+D to look up its path." +msgstr "" +"Tento text již je umístěn na křivku. Nejdříve jej z křivky odstraňte. " +"PomocíShift+D tuto křivku naleznete." + +#. rect is the only SPShape which is not yet, and thus SVG forbids us from putting text on it +#: ../../po/../src/text-chemistry.cpp:101 +msgid "" +"You cannot put text on a rectangle in this version. Convert rectangle to " +"path first." +msgstr "" +"V této verzi jeÅ¡tě nelze umístit text na čtyřúhelník. Převeďte čtyřúhelník " +"nejdřív na křivku." + +#: ../../po/../src/text-chemistry.cpp:159 +msgid "Select a text on path to remove it from path." +msgstr "Vyberte text na křivce, který chcete odstranit z křivky." + +#: ../../po/../src/text-chemistry.cpp:181 +msgid "No texts-on-paths in the selection." +msgstr "Ve výběru nejsou žádné texty na křivkách." + +#: ../../po/../src/text-chemistry.cpp:209 +#: ../../po/../src/text-chemistry.cpp:229 +msgid "Select text(s) to remove kerns from." +msgstr "Vyberte texty ze kterých se má odstranit kerning" + +#: ../../po/../src/text-chemistry.cpp:250 +msgid "" +"Select a text and one or more paths or shapes to flow text " +"into frame." +msgstr "" +"Vyberte a text a jednu nebo více křivek či tvarů a text vteče " +"do orámování." + +#: ../../po/../src/text-chemistry.cpp:322 +msgid "Select a flowed text to unflow it." +msgstr "Vyberte vlitý text, u kterého chcete zruÅ¡it vtečení." + +#: ../../po/../src/text-context.cpp:463 +msgid "Click to edit the text, drag to select part of the text." +msgstr "Kliknutím upravíte text, tažením vyberete část textu." + +#: ../../po/../src/text-context.cpp:465 +msgid "" +"Click to edit the flowed text, drag to select part of the text." +msgstr "" +"Kliknutím upravíte vlitý text, tažením vyberete jeho část." + +#: ../../po/../src/text-context.cpp:540 +msgid "Non-printable character" +msgstr "Netisknutelný znak" + +#: ../../po/../src/text-context.cpp:589 +#, c-format +msgid "Unicode: %s: %s" +msgstr "Unicode: %s: %s" + +#: ../../po/../src/text-context.cpp:591 ../../po/../src/text-context.cpp:855 +msgid "Unicode: " +msgstr "Unicode: " + +#: ../../po/../src/text-context.cpp:615 +msgid "Current layer is hidden. Unhide it to be able to add text." +msgstr "" +"Aktuální vrstva je skrytá. Musíte ji zobrazit aby jste do ní mohli " +"přidat text." + +#: ../../po/../src/text-context.cpp:619 +msgid "Current layer is locked. Unlock it to be able to add text." +msgstr "" +"Aktuální vrstva je zamčena. Musíte ji odemknout aby jste do ní mohli " +"přidat text." + +#: ../../po/../src/text-context.cpp:673 +#, c-format +msgid "Flowed text frame: %s × %s" +msgstr "Rám vlitého textu: %s × %s" + +#: ../../po/../src/text-context.cpp:708 ../../po/../src/text-context.cpp:1464 +msgid "Type text; Enter to start new line." +msgstr "PiÅ¡te text; Enter vytvoří nový řádek" + +#: ../../po/../src/text-context.cpp:719 +msgid "Flowed text is created." +msgstr "Vlitý text vytvořen" + +#: ../../po/../src/text-context.cpp:722 +msgid "" +"The frame is too small for the current font size. Flowed text not " +"created." +msgstr "" +"Rám je příliÅ¡ malý pro písmo o současné velikosti. Vlitý text nebyl " +"vytvořen." + +#: ../../po/../src/text-context.cpp:841 +msgid "No-break space" +msgstr "Nezalomitelná mezera" + +#: ../../po/../src/text-context.cpp:1462 +msgid "Type flowed text; Enter to start new paragraph." +msgstr "PiÅ¡te vlitý text; Enter vytvoří nový odstavec." + +#: ../../po/../src/text-context.cpp:1472 ../../po/../src/tools-switch.cpp:189 +msgid "" +"Click to select or create text, drag to create flowed text; " +"then type." +msgstr "" +"Kliknutím vyberete nebo vytvoříte text, tažením vytvoříte " +"vlitý text; pak začněte psát." + +#: ../../po/../src/tools-switch.cpp:141 +msgid "" +"To edit a path, click, Shift+click, or drag around " +"nodes to select them, then drag nodes and handles. Click on an " +"object to select." +msgstr "" +"Pro úpravu křivky vyberte uzly pomocí kliknutí, Shift+kliknutí " +"nebo tažením kolem bodů. Pak potažením za uzly nebo řídící body " +"křivku změníte. Kliknutí na objekt jej vybere." + +#: ../../po/../src/tools-switch.cpp:147 +msgid "" +"Drag to create a rectangle. Drag controls to round corners and " +"resize. Click to select." +msgstr "" +"Tahem vytvoříte obdélník. Tahem za ovládací body zaoblíte rohy " +"a změníte velikost. Kliknutím vyberete." + +#: ../../po/../src/tools-switch.cpp:153 +msgid "" +"Drag to create an ellipse. Drag controls to make an arc or " +"segment. Click to select." +msgstr "" +"Tažením vytvoříte elipsu. Tažením ovládacích bodů vytvoříte " +"oblouk nebo výseč/úseč. Kliknutím vyberete." + +#: ../../po/../src/tools-switch.cpp:159 +msgid "" +"Drag to create a star. Drag controls to edit the star shape. " +"Click to select." +msgstr "" +"Tažením vytvoříte hvězdu. Tažením ovládacích bodů upravíte " +"tvar hvězdy. Kliknutím vyberete." + +#: ../../po/../src/tools-switch.cpp:165 +msgid "" +"Drag to create a spiral. Drag controls to edit the spiral " +"shape. Click to select." +msgstr "" +"Tažením vytvoříte spirálu. Tažením ovládacích bodů upravíte " +"tvar spirály. Kliknutím vyberete." + +#: ../../po/../src/tools-switch.cpp:171 +msgid "" +"Drag to create a freehand line. Start drawing with Shift to " +"append to selected path." +msgstr "" +"Tahem vytvoříte křivku od ruky. Začněte kreslit se stisknutým " +"Shift a kreslená křivka se připojí k vybrané." + +#: ../../po/../src/tools-switch.cpp:177 +msgid "" +"Click or click and drag to start a path; with Shift to " +"append to selected path." +msgstr "" +"Kliknutím nebo kliknutím a tažení začnete kreslit křivku; s " +"klávesou Shift připojíte křivku k vybrané křivce." + +#: ../../po/../src/tools-switch.cpp:183 +msgid "" +"Drag to paint a calligraphic stroke. Left/right arrow " +"keys adjust width, up/down adjust angle." +msgstr "" +"Tažením vytvoříte kaligrafickou linii. Levá/pravá Å¡ipka " +"upraví šířku. Å ipky nahoru/dolů upraví úhel." + +#: ../../po/../src/tools-switch.cpp:195 +msgid "" +"Drag or double click to create a gradient on selected objects, " +"drag handles to adjust gradients." +msgstr "" +"Tahem nebo dvojitým kliknutím vytvoříte barevný přechod ve " +"vybraných objektech, manipulací s táhly jej upravíte." + +#: ../../po/../src/tools-switch.cpp:201 +msgid "" +"Click or drag around an area to zoom in, Shift+click to " +"zoom out." +msgstr "" +"Kliknutím nebo tažením kolem oblasti objekt přiblížíte, " +"Shift+kliknutí provede oddálení." + +#: ../../po/../src/tools-switch.cpp:213 +msgid "Click and drag between shapes to create a connector." +msgstr "Kliknutím a tažením mezi tvary vytvoříte konektor." + +#: ../../po/../src/trace/potrace/inkscape-potrace.cpp:553 +#: ../../po/../src/trace/potrace/inkscape-potrace.cpp:654 +#, c-format +msgid "Trace: %d. %ld nodes" +msgstr "Trasování: %d. %ld uzlů" + +#: ../../po/../src/trace/trace.cpp:53 ../../po/../src/trace/trace.cpp:62 +#: ../../po/../src/trace/trace.cpp:70 +msgid "Select an image to trace" +msgstr "Vyberte obrázek k převodu na vektory" + +#: ../../po/../src/trace/trace.cpp:133 +msgid "Trace: No active document" +msgstr "Trasování: Není aktivní žádný dokument" + +#: ../../po/../src/trace/trace.cpp:154 +msgid "Trace: Image has no bitmap data" +msgstr "Trasování: V obrázku nejsou bitmapová data" + +#: ../../po/../src/trace/trace.cpp:267 +#, c-format +msgid "Trace: Done. %ld nodes created" +msgstr "Trasování: Dokončeno. %ld uzlů vytvořeno" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:59 ../../po/../src/verbs.cpp:2212 +msgid "About Inkscape" +msgstr "O Inkscape" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:66 +msgid "_Splash" +msgstr "" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:68 +#, fuzzy +msgid "_Authors" +msgstr "Autoři" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:69 +#, fuzzy +msgid "_Translators" +msgstr "Překladatelé" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:70 +msgid "_License" +msgstr "_Licence" + +#. TRANSLATORS: This is the filename of the `About Inkscape' picture in +#. the `screens' directory. Thus the translation of "about.svg" should be +#. the filename of its translated version, e.g. about.zh.svg for Chinese. +#. +#. N.B. about.svg changes once per release. (We should probably rename +#. the original to about-0.40.svg etc. as soon as we have a translation. +#. If we do so, then add an item to release-checklist saying that the +#. string here should be changed.) +#. FIXME? INKSCAPE_SCREENSDIR and "about.svg" are in UTF-8, not the +#. native filename encoding... and the filename passed to sp_document_new +#. should be in UTF-*8.. +#: ../../po/../src/ui/dialog/aboutbox.cpp:114 +msgid "about.svg" +msgstr "about.svg" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:464 +msgid "Minimum horizontal gap (in px units) between bounding boxes" +msgstr "" + +#. TRANSLATORS: Horizontal gap +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:466 +#: ../../po/../src/widgets/toolbox.cpp:1556 +msgid "H:" +msgstr "V:" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:474 +msgid "Minimum vertical gap (in px units) between bounding boxes" +msgstr "" + +#. TRANSLATORS: Vertical gap +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:476 +msgid "V:" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:734 +msgid "Align" +msgstr "Zarovnat" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:735 +msgid "Distribute" +msgstr "Rozmístit" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:736 +msgid "Remove overlaps" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:737 +msgid "Nodes" +msgstr "Uzly" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:742 +msgid "Relative to: " +msgstr "Relativní přesun:" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:747 +msgid "Align right sides of objects to left side of anchor" +msgstr "Zarovnat pravou stranu objektů k levé straně ukotvení" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:750 +msgid "Align left sides" +msgstr "Zarovnat levé strany" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:753 +msgid "Center on vertical axis" +msgstr "Zarovnat na střed svisle" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:756 +msgid "Align right sides" +msgstr "Zarovnat pravé strany" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:759 +msgid "Align left sides of objects to right side of anchor" +msgstr "Zarovnat levou stranu objektů k pravé straně ukotvení" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:762 +msgid "Align bottoms of objects to top of anchor" +msgstr "Zarovnat spodní strany objektů k horním ukotvením" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:765 +msgid "Align tops" +msgstr "Zarovnat horní strany" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:768 +msgid "Center on horizontal axis" +msgstr "Zarovnat na střed vodorovně" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:771 +msgid "Align bottoms" +msgstr "Zarovnat spodní strany" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:774 +msgid "Align tops of objects to bottom of anchor" +msgstr "Zarovnat horní strany objektů ke spodní straně ukotvení" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:779 +msgid "Align baseline anchors of texts vertically" +msgstr "Zarovnat základny textu svisle" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:782 +msgid "Align baseline anchors of texts horizontally" +msgstr "Zarovnat základny textu vodorovně" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:787 +msgid "Make horizontal gaps between objects equal" +msgstr "Rozdělit vodorovné mezery mezi objekty rovnoměrně" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:791 +msgid "Distribute left sides equidistantly" +msgstr "Rozmístit levé strany objektů rovnoměrně vzdálené" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:794 +msgid "Distribute centers equidistantly horizontally" +msgstr "Rozmístit středy objektů vodorovně a v rovnoměrné vzdálenosti" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:797 +msgid "Distribute right sides equidistantly" +msgstr "Rozmístit pravé strany objektů rovnoměrně vzdálené" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:801 +msgid "Make vertical gaps between objects equal" +msgstr "Rozdělit svislou vzdálenost mezi objekty rovnoměrně" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:805 +msgid "Distribute tops equidistantly" +msgstr "Rozmístit horní strany objektů rovnoměrně vzdálené" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:808 +msgid "Distribute centers equidistantly vertically" +msgstr "Rozmístit středy objektů svisle a v rovnoměrné vzdálenosti" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:811 +msgid "Distribute bottoms equidistantly" +msgstr "Rozmístit dolní strany objektů rovnoměrně vzdálené" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:816 +msgid "Distribute baseline anchors of texts horizontally" +msgstr "Rozmístit základny textu vodorovně" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:819 +msgid "Distribute baseline anchors of texts vertically" +msgstr "Rozmístit základny textu svisle" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:824 +msgid "Randomize centers in both dimensions" +msgstr "Náhodně rozmístit středy v obou rozměrech" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:827 +msgid "Unclump objects: try to equalize edge-to-edge distances" +msgstr "Rozhodit objekty: vzdálenosti okraj-okraj by měly být rovnoměrné" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:832 +msgid "" +"Move objects as little as possible so that their bounding boxes do not " +"overlap" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:837 +msgid "Align selected nodes horizontally" +msgstr "Zarovnat vybrané uzly vodorovně" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:840 +msgid "Align selected nodes vertically" +msgstr "Zarovnat vybrané uzly svisle" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:843 +msgid "Distribute selected nodes horizontally" +msgstr "Rozmístit vybrané uzly vodorovně" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:846 +msgid "Distribute selected nodes vertically" +msgstr "Rozmístit vybrané uzly svisle" + +#. Rest of the widgetry +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:851 +msgid "Last selected" +msgstr "Poslední vybraný" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:852 +msgid "First selected" +msgstr "První vybraný" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:853 +msgid "Biggest item" +msgstr "Největší položka" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:854 +msgid "Smallest item" +msgstr "Nejmenší položka" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:856 +#: ../../po/../src/widgets/desktop-widget.cpp:1065 +msgid "Drawing" +msgstr "Kresba" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:91 +#, fuzzy +msgid "Metadata 1" +msgstr "Metadata" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:92 +#, fuzzy +msgid "Metadata 2" +msgstr "Metadata" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:187 +#, fuzzy +msgid "X coordinate of grid origin" +msgstr "Svislá souřadnice výběru" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:189 +#, fuzzy +msgid "Y coordinate of grid origin" +msgstr "Svislá souřadnice výběru" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:191 +#, fuzzy +msgid "Distance of vertical grid lines" +msgstr "svislá vodící čára" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:193 +#, fuzzy +msgid "Distance of horizontal grid lines" +msgstr "vodorovná vodící čára" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:197 +msgid "Max. snapping distance from grid" +msgstr "" + +#: ../../po/../src/ui/dialog/export.cpp:34 +msgid "Export" +msgstr "Export" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:36 +msgid "Fill" +msgstr "Výplň" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:37 +msgid "Stroke Paint" +msgstr "Vykreslení čáry" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:38 +msgid "Stroke Style" +msgstr "Styl obrysu" + +#: ../../po/../src/ui/dialog/find.cpp:34 +msgid "Find" +msgstr "Hledat" + +#: ../../po/../src/ui/dialog/memory.cpp:96 +msgid "Heap" +msgstr "Hromada" + +#: ../../po/../src/ui/dialog/memory.cpp:97 +msgid "In Use" +msgstr "Používáno" + +#. TRANSLATORS: "Slack" refers to memory which is in the heap but currently unused. +#. More typical usage is to call this memory "free" rather than "slack". +#: ../../po/../src/ui/dialog/memory.cpp:100 +#, fuzzy +msgid "Slack" +msgstr "Alokováno ale nevyužito" + +#: ../../po/../src/ui/dialog/memory.cpp:101 +msgid "Total" +msgstr "Celkem" + +#: ../../po/../src/ui/dialog/memory.cpp:141 +#: ../../po/../src/ui/dialog/memory.cpp:147 +#: ../../po/../src/ui/dialog/memory.cpp:154 +#: ../../po/../src/ui/dialog/memory.cpp:186 +msgid "Unknown" +msgstr "Neznámé" + +#: ../../po/../src/ui/dialog/memory.cpp:167 +msgid "Combined" +msgstr "Kombinace" + +#: ../../po/../src/ui/dialog/memory.cpp:209 +msgid "Recalculate" +msgstr "Přepočítat" + +#: ../../po/../src/ui/dialog/messages.cpp:74 +msgid "Ready." +msgstr "Připraven." + +#: ../../po/../src/ui/dialog/messages.cpp:75 +msgid "" +"Enable log display by setting dialogs.debug 'redirect' attribute to 1 in " +"preferences.xml" +msgstr "" +"Okno logu zapnete nastavením atributu dialogs.debug 'redirect' na 1 v " +"preferences.xml" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:184 +msgid "_Execute Python" +msgstr "_Spustit Python" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:186 +msgid "_Execute Perl" +msgstr "_Spustit Perl" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:195 +msgid "Script" +msgstr "Skript" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:205 +msgid "Output" +msgstr "Výstup" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:215 +msgid "Errors" +msgstr "Chyby" + +#. Dialog organization +#: ../../po/../src/ui/dialog/session-player.cpp:73 +msgid "Session file" +msgstr "Soubor se sezením" + +#: ../../po/../src/ui/dialog/session-player.cpp:74 +msgid "Playback controls" +msgstr "Ovládací prvky přehrávače" + +#: ../../po/../src/ui/dialog/session-player.cpp:75 +msgid "Message information" +msgstr "Informace zprávy" + +#. Active session file display +#. fixme: Does this mean the active file for the session, or the file for the active session? +#. Please indicate which with a TRANSLATORS comment. +#: ../../po/../src/ui/dialog/session-player.cpp:85 +msgid "Active session file:" +msgstr "Soubor aktivního sezení:" + +#: ../../po/../src/ui/dialog/session-player.cpp:86 +msgid "Delay (milliseconds):" +msgstr "Prodleva (milisekundy):" + +#. Unload/load buttons +#: ../../po/../src/ui/dialog/session-player.cpp:94 +msgid "Close file" +msgstr "Zavřít soubor" + +#: ../../po/../src/ui/dialog/session-player.cpp:95 +msgid "Open new file" +msgstr "Otevřít nový soubor" + +#: ../../po/../src/ui/dialog/session-player.cpp:96 +msgid "Set delay" +msgstr "Nastavit prodlevu" + +#: ../../po/../src/ui/dialog/session-player.cpp:138 +msgid "Rewind" +msgstr "Přetočit" + +#: ../../po/../src/ui/dialog/session-player.cpp:139 +msgid "Go back one change" +msgstr "O jednu změnu zpět" + +#: ../../po/../src/ui/dialog/session-player.cpp:140 +msgid "Pause" +msgstr "Pauza" + +#: ../../po/../src/ui/dialog/session-player.cpp:141 +msgid "Go forward one change" +msgstr "O jednu změnu vpřed" + +#: ../../po/../src/ui/dialog/session-player.cpp:142 +msgid "Play" +msgstr "Přehrát" + +#: ../../po/../src/ui/dialog/session-player.cpp:177 +#: ../../po/../src/verbs.cpp:1573 +msgid "Open session file" +msgstr "Otevřít soubor se sezením" + +#. ##Set up the Potrace panel +#. #### brightness #### +#. #### Multiple scanning#### +#. ----Hbox1 +#: ../../po/../src/ui/dialog/tracedialog.cpp:345 +#: ../../po/../src/ui/dialog/tracedialog.cpp:428 +msgid "Brightness" +msgstr "Jas" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:348 +msgid "Trace by a given brightness level" +msgstr "Trasovat danou hodnotou jasu" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:355 +msgid "Brightness cutoff for black/white" +msgstr "Rozdíl v jasu mezi černou a bílou" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:362 +msgid "Image Brightness" +msgstr "Jas obrázku" + +#. #### canny edge detection #### +#. TRANSLATORS: "Canny" is the name of the inventor of this edge detection method +#: ../../po/../src/ui/dialog/tracedialog.cpp:369 +msgid "Optimal Edge Detection (Canny)" +msgstr "Optimální detekce hran (Canny)" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:372 +msgid "Trace with edge detection by J. Canny's algorithm" +msgstr "Trasovat algoritmem J. Cannyho detekce hran" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:388 +msgid "Brightness cutoff for adjacent pixels (determines edge thickness)" +msgstr "Rozdíl jasu pro detekci hrany" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:395 +msgid "Edge Detection" +msgstr "Detekce hran" + +#. #### quantization #### +#. TRANSLATORS: Color Quantization: the process of reducing the number of colors +#. in an image by selecting an optimized set of representative colors and then +#. re-applying this reduced set to the original image. +#: ../../po/../src/ui/dialog/tracedialog.cpp:404 +msgid "Color Quantization" +msgstr "Kvantizace barvy" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:407 +msgid "Trace along the boundaries of reduced colors" +msgstr "Trasovat podél hranic redukovaných barev" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:414 +msgid "The number of reduced colors" +msgstr "Počet redukovaných barev" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:416 +msgid "Colors:" +msgstr "Barvy:" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:421 +msgid "Quantization / Reduction" +msgstr "Kvantizace / Redukce" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:431 +msgid "Trace the given number of brightness levels" +msgstr "Trasovat danou hodnotu úrovní jasu" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:438 +msgid "Scans:" +msgstr "Počet skenování:" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:440 +msgid "The desired number of scans" +msgstr "Požadovaný počet skenování" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:448 +msgid "Trace the given number of reduced colors" +msgstr "Trasovat daný počet redukovaných barev" + +#. ---Hbox3 +#: ../../po/../src/ui/dialog/tracedialog.cpp:454 +msgid "Monochrome" +msgstr "Černobíle" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:457 +msgid "Same as Color, but convert result to grayscale" +msgstr "Totéž jako Barva, ale výsledek bude zkonvertován do odstínů Å¡edi" + +#. TRANSLATORS: "Stack" is a verb here +#: ../../po/../src/ui/dialog/tracedialog.cpp:460 +msgid "Stack" +msgstr "Zásobník" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:463 +msgid "" +"Stack scans vertically (no gaps) or tile horizontally (usually with gaps)" +msgstr "" +"NavrÅ¡it skenované plochy (bez mezer) nebo dláždit vedle sebe (obvykle s " +"mezerami)" + +#. TRANSLATORS: "Smooth" is a verb here +#: ../../po/../src/ui/dialog/tracedialog.cpp:466 +msgid "Smooth" +msgstr "Vyhladit" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:469 +msgid "Apply Gaussian blur to the bitmap before tracing" +msgstr "Aplikovat Gaussovo rozostření na bitmapu před trasováním" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:473 +msgid "Multiple Scanning" +msgstr "Vícenásobné skenování" + +#. #### Preview #### +#: ../../po/../src/ui/dialog/tracedialog.cpp:479 +#: ../../po/../src/ui/dialog/tracedialog.cpp:489 +msgid "Preview" +msgstr "Náhled" + +#. do not expand +#: ../../po/../src/ui/dialog/tracedialog.cpp:483 +msgid "Preview the result without actual tracing" +msgstr "Náhled výsledku bez současného trasování" + +#. #### swap black and white #### +#: ../../po/../src/ui/dialog/tracedialog.cpp:495 +msgid "Invert" +msgstr "Invertovat" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:499 +msgid "Invert black and white regions for single traces" +msgstr "Invertovat černé a bílé oblasti pro jednotlivá trasování" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:503 +msgid "Thanks to Peter Selinger, http://potrace.sourceforge.net" +msgstr "Díky patří Peteru Selingerovi, http://potrace.sourceforge.net" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:506 +msgid "Credits" +msgstr "Kredity" + +#. done +#. TRANSLATORS: Potrace is an application for transforming bitmaps into +#. vector graphics (http://potrace.sourceforge.net/) +#: ../../po/../src/ui/dialog/tracedialog.cpp:514 +msgid "Potrace" +msgstr "Potrace" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:527 +msgid "Abort a trace in progress" +msgstr "ZruÅ¡it proces trasování" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:531 +msgid "Execute the trace" +msgstr "Spustit trasování" + +#: ../../po/../src/ui/dialog/transformation.cpp:80 +#: ../../po/../src/ui/dialog/transformation.cpp:90 +#, fuzzy +msgid "_Horizontal" +msgstr "Vodorovně" + +#: ../../po/../src/ui/dialog/transformation.cpp:80 +msgid "Horizontal displacement (relative) or position (absolute)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:82 +#: ../../po/../src/ui/dialog/transformation.cpp:92 +#, fuzzy +msgid "_Vertical" +msgstr "Svisle" + +#: ../../po/../src/ui/dialog/transformation.cpp:82 +msgid "Vertical displacement (relative) or position (absolute)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:84 +#, fuzzy +msgid "_Width" +msgstr "Šířka:" + +#: ../../po/../src/ui/dialog/transformation.cpp:84 +msgid "Horizontal size increment (absolute or percentage)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:86 +#, fuzzy +msgid "_Height" +msgstr "Výška" + +#: ../../po/../src/ui/dialog/transformation.cpp:86 +msgid "Vertical size increment (absolute or percentage)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:88 +#, fuzzy +msgid "A_ngle" +msgstr "Úhel:" + +#: ../../po/../src/ui/dialog/transformation.cpp:88 +#, fuzzy +msgid "Rotation angle (positive = counterclockwise)" +msgstr "Otočit výběr o 90° po směru hodinových ručiček" + +#: ../../po/../src/ui/dialog/transformation.cpp:90 +msgid "" +"Horizontal skew angle (positive = counterclockwise), or absolute " +"displacement, or percentage displacement" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:92 +msgid "" +"Vertical skew angle (positive = counterclockwise), or absolute displacement, " +"or percentage displacement" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:95 +#, fuzzy +msgid "Transformation matrix element A" +msgstr "Transformační matice" + +#: ../../po/../src/ui/dialog/transformation.cpp:96 +#, fuzzy +msgid "Transformation matrix element B" +msgstr "Transformační matice" + +#: ../../po/../src/ui/dialog/transformation.cpp:97 +#, fuzzy +msgid "Transformation matrix element C" +msgstr "Transformační matice" + +#: ../../po/../src/ui/dialog/transformation.cpp:98 +#, fuzzy +msgid "Transformation matrix element D" +msgstr "Transformační matice" + +#: ../../po/../src/ui/dialog/transformation.cpp:99 +#, fuzzy +msgid "Transformation matrix element E" +msgstr "Transformační matice" + +#: ../../po/../src/ui/dialog/transformation.cpp:100 +#, fuzzy +msgid "Transformation matrix element F" +msgstr "Transformační matice" + +#: ../../po/../src/ui/dialog/transformation.cpp:102 +#, fuzzy +msgid "Rela_tive move" +msgstr "Relativní přesun" + +#: ../../po/../src/ui/dialog/transformation.cpp:102 +msgid "" +"Add the specified relative displacement to the current position; otherwise, " +"edit the current absolute position directly" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:103 +msgid "Scale proportionally" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:103 +msgid "Preserve the width/height ratio of the scaled objects" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:104 +msgid "Apply to each _object separately" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:104 +msgid "" +"Apply the scale/rotate/skew to each selected object separately; otherwise, " +"transform the selection as a whole" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:105 +#, fuzzy +msgid "Edit c_urrent matrix" +msgstr "Přesunout vrstvu níž" + +#: ../../po/../src/ui/dialog/transformation.cpp:105 +msgid "" +"Edit the current transform= matrix; otherwise, post-multiply transform= by " +"this matrix" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:115 +#, fuzzy +msgid "_Move" +msgstr "Přesun" + +#: ../../po/../src/ui/dialog/transformation.cpp:118 +#, fuzzy +msgid "_Scale" +msgstr "Změnit velikost" + +#: ../../po/../src/ui/dialog/transformation.cpp:121 +#, fuzzy +msgid "_Rotate" +msgstr "Otočit" + +#: ../../po/../src/ui/dialog/transformation.cpp:124 +#, fuzzy +msgid "Ske_w" +msgstr "Zkosení" + +#: ../../po/../src/ui/dialog/transformation.cpp:127 +msgid "Matri_x" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:141 +msgid "Reset the values on the current tab to defaults" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:148 +#, fuzzy +msgid "Apply transformation to selection" +msgstr "Aplikovat transformaci na objekt" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:43 +msgid "_Use SSL" +msgstr "Po_užít SSL" + +#. Construct dialog interface +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:68 +msgid "_Server:" +msgstr "_Server:" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:69 +msgid "_Username:" +msgstr "_Uživatelské jméno:" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:70 +msgid "_Password:" +msgstr "_Heslo:" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:71 +msgid "P_ort:" +msgstr "P_ort:" + +#. Buttons +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:99 +msgid "Connect" +msgstr "Připojit" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:126 +msgid "Establishing connection to Jabber server %1 as user %2" +msgstr "Vytvářím spojení s Jabber serverem %1 jako uživatel %2" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:131 +msgid "Failed to establish connection to Jabber server %1" +msgstr "Spojení s Jabber serverem %1 se nepodařilo sestavit" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:136 +msgid "Authentication failed on Jabber server %1 as %2" +msgstr "Přihlášení k Jabber serveru %1 jako %1 selhalo" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:141 +msgid "SSL initialization failed when connecting to Jabber server %1" +msgstr "Inicializace SSL selhala během připojování k Jabber serveru %1" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:147 +msgid "Connected to Jabber server %1 as %2" +msgstr "Připojen k Jabber serveru %1 jako %2" + +#. Construct labels +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:75 +msgid "Chatroom _name:" +msgstr "Jmé_no místnosti:" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:76 +msgid "Chatroom _server:" +msgstr "_Server pro místnost:" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:77 +msgid "Chatroom _password:" +msgstr "_Heslo pro místnost:" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:78 +msgid "Chatroom _handle:" +msgstr "_Handle místnosti:" + +#. Button setup and callback registration +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:97 +msgid "Connect to chatroom" +msgstr "Připojit se do místnosti" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:132 +msgid "Synchronizing with chatroom %1@%2 using the handle %3" +msgstr "Synchronizuji s místností %1@%2 za použití handle %3" + +#. Construct dialog interface +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:78 +msgid "_User's Jabber ID:" +msgstr "Uživatelovo Jabber ID:" + +#. Buttons +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:82 +msgid "_Invite user" +msgstr "Pozvat uživatele" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:83 +msgid "_Cancel" +msgstr "ZruÅ¡it" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:94 +msgid "Buddy List" +msgstr "Seznam Kamarádů" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:170 +msgid "Sending whiteboard invitation to %1" +msgstr "Odesílám pozvánku k inkboard pro %1" + +#. FIXME: strings are replaced by placeholders, NOT to be translated until the code is enabled +#. See http://sourceforge.net/mailarchive/message.php?msg_id=11746016 for details +#. File menu +#. Edit menu +#. View menu +#. Layer menu +#. Object menu +#. Path menu +#. add(Gtk::StockItem(CLEANUP, _("PLACEHOLDER, do not translate"))); (using Gtk::Stock::CLEAR) +#. Text menu +#. About menu +#. Tools toolbox +#. Select Tool controls +#. Node Tool controls +#. Calligraphy Tool controls +#. Session playback controls +#: ../../po/../src/ui/stock-items.cpp:34 ../../po/../src/ui/stock-items.cpp:35 +#: ../../po/../src/ui/stock-items.cpp:36 ../../po/../src/ui/stock-items.cpp:37 +#: ../../po/../src/ui/stock-items.cpp:38 ../../po/../src/ui/stock-items.cpp:39 +#: ../../po/../src/ui/stock-items.cpp:40 ../../po/../src/ui/stock-items.cpp:41 +#: ../../po/../src/ui/stock-items.cpp:42 ../../po/../src/ui/stock-items.cpp:43 +#: ../../po/../src/ui/stock-items.cpp:46 ../../po/../src/ui/stock-items.cpp:47 +#: ../../po/../src/ui/stock-items.cpp:48 ../../po/../src/ui/stock-items.cpp:49 +#: ../../po/../src/ui/stock-items.cpp:50 ../../po/../src/ui/stock-items.cpp:51 +#: ../../po/../src/ui/stock-items.cpp:52 ../../po/../src/ui/stock-items.cpp:53 +#: ../../po/../src/ui/stock-items.cpp:54 ../../po/../src/ui/stock-items.cpp:55 +#: ../../po/../src/ui/stock-items.cpp:56 ../../po/../src/ui/stock-items.cpp:57 +#: ../../po/../src/ui/stock-items.cpp:58 ../../po/../src/ui/stock-items.cpp:59 +#: ../../po/../src/ui/stock-items.cpp:62 ../../po/../src/ui/stock-items.cpp:63 +#: ../../po/../src/ui/stock-items.cpp:64 ../../po/../src/ui/stock-items.cpp:65 +#: ../../po/../src/ui/stock-items.cpp:66 ../../po/../src/ui/stock-items.cpp:67 +#: ../../po/../src/ui/stock-items.cpp:68 ../../po/../src/ui/stock-items.cpp:69 +#: ../../po/../src/ui/stock-items.cpp:70 ../../po/../src/ui/stock-items.cpp:71 +#: ../../po/../src/ui/stock-items.cpp:72 ../../po/../src/ui/stock-items.cpp:73 +#: ../../po/../src/ui/stock-items.cpp:74 ../../po/../src/ui/stock-items.cpp:75 +#: ../../po/../src/ui/stock-items.cpp:76 ../../po/../src/ui/stock-items.cpp:77 +#: ../../po/../src/ui/stock-items.cpp:78 ../../po/../src/ui/stock-items.cpp:79 +#: ../../po/../src/ui/stock-items.cpp:80 ../../po/../src/ui/stock-items.cpp:81 +#: ../../po/../src/ui/stock-items.cpp:82 ../../po/../src/ui/stock-items.cpp:83 +#: ../../po/../src/ui/stock-items.cpp:84 ../../po/../src/ui/stock-items.cpp:85 +#: ../../po/../src/ui/stock-items.cpp:86 ../../po/../src/ui/stock-items.cpp:87 +#: ../../po/../src/ui/stock-items.cpp:88 ../../po/../src/ui/stock-items.cpp:89 +#: ../../po/../src/ui/stock-items.cpp:92 ../../po/../src/ui/stock-items.cpp:93 +#: ../../po/../src/ui/stock-items.cpp:94 ../../po/../src/ui/stock-items.cpp:95 +#: ../../po/../src/ui/stock-items.cpp:96 ../../po/../src/ui/stock-items.cpp:97 +#: ../../po/../src/ui/stock-items.cpp:98 ../../po/../src/ui/stock-items.cpp:99 +#: ../../po/../src/ui/stock-items.cpp:100 +#: ../../po/../src/ui/stock-items.cpp:101 +#: ../../po/../src/ui/stock-items.cpp:102 +#: ../../po/../src/ui/stock-items.cpp:103 +#: ../../po/../src/ui/stock-items.cpp:104 +#: ../../po/../src/ui/stock-items.cpp:105 +#: ../../po/../src/ui/stock-items.cpp:108 +#: ../../po/../src/ui/stock-items.cpp:109 +#: ../../po/../src/ui/stock-items.cpp:110 +#: ../../po/../src/ui/stock-items.cpp:111 +#: ../../po/../src/ui/stock-items.cpp:112 +#: ../../po/../src/ui/stock-items.cpp:113 +#: ../../po/../src/ui/stock-items.cpp:114 +#: ../../po/../src/ui/stock-items.cpp:115 +#: ../../po/../src/ui/stock-items.cpp:116 +#: ../../po/../src/ui/stock-items.cpp:117 +#: ../../po/../src/ui/stock-items.cpp:118 +#: ../../po/../src/ui/stock-items.cpp:119 +#: ../../po/../src/ui/stock-items.cpp:120 +#: ../../po/../src/ui/stock-items.cpp:121 +#: ../../po/../src/ui/stock-items.cpp:122 +#: ../../po/../src/ui/stock-items.cpp:123 +#: ../../po/../src/ui/stock-items.cpp:124 +#: ../../po/../src/ui/stock-items.cpp:125 +#: ../../po/../src/ui/stock-items.cpp:126 +#: ../../po/../src/ui/stock-items.cpp:127 +#: ../../po/../src/ui/stock-items.cpp:130 +#: ../../po/../src/ui/stock-items.cpp:131 +#: ../../po/../src/ui/stock-items.cpp:132 +#: ../../po/../src/ui/stock-items.cpp:133 +#: ../../po/../src/ui/stock-items.cpp:134 +#: ../../po/../src/ui/stock-items.cpp:135 +#: ../../po/../src/ui/stock-items.cpp:136 +#: ../../po/../src/ui/stock-items.cpp:137 +#: ../../po/../src/ui/stock-items.cpp:138 +#: ../../po/../src/ui/stock-items.cpp:139 +#: ../../po/../src/ui/stock-items.cpp:140 +#: ../../po/../src/ui/stock-items.cpp:141 +#: ../../po/../src/ui/stock-items.cpp:142 +#: ../../po/../src/ui/stock-items.cpp:143 +#: ../../po/../src/ui/stock-items.cpp:144 +#: ../../po/../src/ui/stock-items.cpp:145 +#: ../../po/../src/ui/stock-items.cpp:146 +#: ../../po/../src/ui/stock-items.cpp:150 +#: ../../po/../src/ui/stock-items.cpp:151 +#: ../../po/../src/ui/stock-items.cpp:152 +#: ../../po/../src/ui/stock-items.cpp:153 +#: ../../po/../src/ui/stock-items.cpp:156 +#: ../../po/../src/ui/stock-items.cpp:157 +#: ../../po/../src/ui/stock-items.cpp:158 +#: ../../po/../src/ui/stock-items.cpp:161 +#: ../../po/../src/ui/stock-items.cpp:162 +#: ../../po/../src/ui/stock-items.cpp:163 +#: ../../po/../src/ui/stock-items.cpp:164 +#: ../../po/../src/ui/stock-items.cpp:165 +#: ../../po/../src/ui/stock-items.cpp:166 +#: ../../po/../src/ui/stock-items.cpp:167 +#: ../../po/../src/ui/stock-items.cpp:168 +#: ../../po/../src/ui/stock-items.cpp:169 +#: ../../po/../src/ui/stock-items.cpp:170 +#: ../../po/../src/ui/stock-items.cpp:171 +#: ../../po/../src/ui/stock-items.cpp:172 +#: ../../po/../src/ui/stock-items.cpp:175 +#: ../../po/../src/ui/stock-items.cpp:176 +#: ../../po/../src/ui/stock-items.cpp:177 +#: ../../po/../src/ui/stock-items.cpp:178 +#: ../../po/../src/ui/stock-items.cpp:181 +#: ../../po/../src/ui/stock-items.cpp:182 +#: ../../po/../src/ui/stock-items.cpp:183 +#: ../../po/../src/ui/stock-items.cpp:184 +#: ../../po/../src/ui/stock-items.cpp:185 +#: ../../po/../src/ui/stock-items.cpp:186 +#: ../../po/../src/ui/stock-items.cpp:187 +#: ../../po/../src/ui/stock-items.cpp:188 +#: ../../po/../src/ui/stock-items.cpp:189 +#: ../../po/../src/ui/stock-items.cpp:190 +#: ../../po/../src/ui/stock-items.cpp:191 +#: ../../po/../src/ui/stock-items.cpp:194 +#: ../../po/../src/ui/stock-items.cpp:195 +#: ../../po/../src/ui/stock-items.cpp:198 +#: ../../po/../src/ui/stock-items.cpp:199 +#: ../../po/../src/ui/stock-items.cpp:200 +#: ../../po/../src/ui/stock-items.cpp:201 +#: ../../po/../src/ui/stock-items.cpp:202 +msgid "PLACEHOLDER, do not translate" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:88 +msgid "small" +msgstr "malý" + +#: ../../po/../src/ui/widget/panel.cpp:89 +msgid "medium" +msgstr "střední" + +#: ../../po/../src/ui/widget/panel.cpp:90 +msgid "large" +msgstr "větší" + +#: ../../po/../src/ui/widget/panel.cpp:91 +msgid "huge" +msgstr "velký" + +#: ../../po/../src/ui/widget/panel.cpp:106 +msgid "List" +msgstr "Seznam" + +#: ../../po/../src/ui/widget/selected-style.cpp:67 +msgid "F:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:68 +msgid "S:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:69 +msgid "O:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:95 +msgid "N/A" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:98 +#: ../../po/../src/ui/widget/selected-style.cpp:712 +#, fuzzy +msgid "Nothing selected" +msgstr "Nejsou vybrány žádné přechody" + +#: ../../po/../src/ui/widget/selected-style.cpp:103 +msgid "No fill" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:103 +#, fuzzy +msgid "No stroke" +msgstr " (okraj)" + +#: ../../po/../src/ui/widget/selected-style.cpp:105 +#: ../../po/../src/widgets/paint-selector.cpp:190 +msgid "Pattern" +msgstr "Vzorek" + +#: ../../po/../src/ui/widget/selected-style.cpp:108 +#: ../../po/../src/widgets/paint-selector.cpp:885 +msgid "Pattern fill" +msgstr "Vzorek výplně" + +#: ../../po/../src/ui/widget/selected-style.cpp:108 +#, fuzzy +msgid "Pattern stroke" +msgstr "Posun vzorku" + +#: ../../po/../src/ui/widget/selected-style.cpp:110 +#, fuzzy +msgid "L Gradient" +msgstr "Barevný přechod" + +#: ../../po/../src/ui/widget/selected-style.cpp:113 +#, fuzzy +msgid "Linear gradient fill" +msgstr "Lineární přechod" + +#: ../../po/../src/ui/widget/selected-style.cpp:113 +#, fuzzy +msgid "Linear gradient stroke" +msgstr "Lineární přechod" + +#: ../../po/../src/ui/widget/selected-style.cpp:115 +#, fuzzy +msgid "R Gradient" +msgstr "Barevný přechod" + +#: ../../po/../src/ui/widget/selected-style.cpp:118 +#, fuzzy +msgid "Radial gradient fill" +msgstr "Kruhový přechod" + +#: ../../po/../src/ui/widget/selected-style.cpp:118 +#, fuzzy +msgid "Radial gradient stroke" +msgstr "Kruhový přechod" + +#: ../../po/../src/ui/widget/selected-style.cpp:120 +#, fuzzy +msgid "Different" +msgstr "Roz_díl" + +#: ../../po/../src/ui/widget/selected-style.cpp:123 +#, fuzzy +msgid "Different fills" +msgstr "Roz_díl" + +#: ../../po/../src/ui/widget/selected-style.cpp:123 +#, fuzzy +msgid "Different strokes" +msgstr "Roz_díl" + +#: ../../po/../src/ui/widget/selected-style.cpp:125 +#, fuzzy +msgid "Unset" +msgstr "smrÅ¡tit" + +#. TRANSLATORS COMMENT: unset is a verb here +#: ../../po/../src/ui/widget/selected-style.cpp:128 +#: ../../po/../src/ui/widget/selected-style.cpp:182 +msgid "Unset fill" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:128 +#: ../../po/../src/ui/widget/selected-style.cpp:182 +#, fuzzy +msgid "Unset stroke" +msgstr " (okraj)" + +#: ../../po/../src/ui/widget/selected-style.cpp:131 +#, fuzzy +msgid "Flat color fill" +msgstr "Jedna barva" + +#: ../../po/../src/ui/widget/selected-style.cpp:131 +#, fuzzy +msgid "Flat color stroke" +msgstr "Jedna barva" + +#. TRANSLATOR COMMENT: A means "Averaged" +#: ../../po/../src/ui/widget/selected-style.cpp:134 +#, fuzzy +msgid "A" +msgstr "_A" + +#: ../../po/../src/ui/widget/selected-style.cpp:137 +#, fuzzy +msgid "Fill is averaged over selected objects" +msgstr "XOR vybraných objektů" + +#: ../../po/../src/ui/widget/selected-style.cpp:137 +#, fuzzy +msgid "Stroke is averaged over selected objects" +msgstr "Přinutit konektory vyhýbat se vybraným objektům" + +#. TRANSLATOR COMMENT: M means "Multiple" +#: ../../po/../src/ui/widget/selected-style.cpp:140 +#, fuzzy +msgid "M" +msgstr "_M" + +#: ../../po/../src/ui/widget/selected-style.cpp:143 +msgid "Multiple selected objects have the same fill" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:143 +msgid "Multiple selected objects have the same stroke" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:145 +#, fuzzy +msgid "Edit fill..." +msgstr "Úpravy..." + +#: ../../po/../src/ui/widget/selected-style.cpp:145 +#, fuzzy +msgid "Edit stroke..." +msgstr "Úpravy..." + +#: ../../po/../src/ui/widget/selected-style.cpp:149 +#, fuzzy +msgid "Last set color" +msgstr "Jedna barva" + +#: ../../po/../src/ui/widget/selected-style.cpp:153 +#, fuzzy +msgid "Last selected color" +msgstr "Poslední vybraný" + +#: ../../po/../src/ui/widget/selected-style.cpp:157 +#, fuzzy +msgid "White" +msgstr "Whiteboa_rd" + +#: ../../po/../src/ui/widget/selected-style.cpp:161 +#: ../../po/../src/widgets/sp-color-scales.cpp:461 +#: ../../po/../src/widgets/sp-color-scales.cpp:462 +msgid "Black" +msgstr "Černá" + +#: ../../po/../src/ui/widget/selected-style.cpp:165 +#, fuzzy +msgid "Copy color" +msgstr "Barva zařážky" + +#: ../../po/../src/ui/widget/selected-style.cpp:169 +#, fuzzy +msgid "Paste color" +msgstr "Jedna barva" + +#: ../../po/../src/ui/widget/selected-style.cpp:173 +#, fuzzy +msgid "Swap fill and stroke" +msgstr "Výplň a čáry" + +#: ../../po/../src/ui/widget/selected-style.cpp:177 +msgid "Make fill opaque" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:177 +msgid "Make stroke opaque" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:186 +#, fuzzy +msgid "Remove fill" +msgstr " Odstranit " + +#: ../../po/../src/ui/widget/selected-style.cpp:186 +#, fuzzy +msgid "Remove stroke" +msgstr "Odstranit odkaz" + +#: ../../po/../src/ui/widget/selected-style.cpp:718 +#, fuzzy +msgid "Master opacity" +msgstr "Celkové krytí" + +#: ../../po/../src/ui/widget/selected-style.cpp:744 +msgid "0 (transparent)" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:768 +msgid "1.0 (opaque)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1046 +msgid "Moved to next layer." +msgstr "Přesunuto do následující vrstvy." + +#: ../../po/../src/verbs.cpp:1048 +#, fuzzy +msgid "Cannot move past last layer." +msgstr "Nelze přesunout minulou poslední vrstvu" + +#: ../../po/../src/verbs.cpp:1057 +msgid "Moved to previous layer." +msgstr "Přesunuto do předchozí vrstvy" + +#: ../../po/../src/verbs.cpp:1059 +#, fuzzy +msgid "Cannot move past first layer." +msgstr "Nelze přesunout minulou první vrstvu" + +#: ../../po/../src/verbs.cpp:1076 ../../po/../src/verbs.cpp:1150 +msgid "No current layer." +msgstr "Žádná vrstva není aktuální." + +#: ../../po/../src/verbs.cpp:1105 +#, c-format +msgid "Raised layer %s." +msgstr "Přesunout vrstvu %s výš." + +#: ../../po/../src/verbs.cpp:1109 +#, c-format +msgid "Lowered layer %s." +msgstr "Přesunout vrstvu %s níž." + +#: ../../po/../src/verbs.cpp:1118 +#, fuzzy +msgid "Cannot move layer any further." +msgstr "Nelze dále přesouvat vrstvu." + +#. TRANSLATORS: this means "The layer has been deleted." +#: ../../po/../src/verbs.cpp:1148 +msgid "Deleted layer." +msgstr "Vymazat vrstvu." + +#: ../../po/../src/verbs.cpp:1544 +msgid "" +"You need to connect to a Jabber server before sharing a document with " +"another user." +msgstr "" +"Před sdílením dokumentu s dalším uživatelem se musíte připojit k Jabber " +"serveru." + +#: ../../po/../src/verbs.cpp:1559 +msgid "" +"You need to connect to a Jabber server before sharing a document with a " +"chatroom." +msgstr "" +"Před sdílením dokumentu s místností se musíte připojit k Jabber serveru." + +#: ../../po/../src/verbs.cpp:1569 +msgid "XML node tracker has not been initialized; nothing to dump" +msgstr "Trasování XML uzlů nebylo inicializováno; není co vypsat" + +#. TRANSLATORS: If you have translated the keys.svg file to your language, then +#. translate this string as "keys.LANG.svg" (where LANG is your language code); +#. otherwise leave as "keys.svg". +#: ../../po/../src/verbs.cpp:1631 +msgid "keys.svg" +msgstr "keys.svg" + +#. TRANSLATORS: If you have translated the tutorial-basic.svg file to your language, +#. then translate this string as "tutorial-basic.LANG.svg" (where LANG is your language +#. code); otherwise leave as "tutorial-basic.svg". +#: ../../po/../src/verbs.cpp:1667 +msgid "tutorial-basic.svg" +msgstr "tutorial-basic.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1671 +msgid "tutorial-shapes.svg" +msgstr "tutorial-shapes.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1675 +msgid "tutorial-advanced.svg" +msgstr "tutorial-advanced.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1679 +msgid "tutorial-tracing.svg" +msgstr "tutorial-tracing.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1683 +msgid "tutorial-calligraphy.svg" +msgstr "tutorial-calligraphy.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1687 +msgid "tutorial-elements.svg" +msgstr "tutorial-elements.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1691 +msgid "tutorial-tips.svg" +msgstr "tutorial-tips.svg" + +#: ../../po/../src/verbs.cpp:1842 +msgid "Does nothing" +msgstr "Nedělá nic" + +#. File +#: ../../po/../src/verbs.cpp:1845 +msgid "Default" +msgstr "Výchozí" + +#: ../../po/../src/verbs.cpp:1845 +msgid "Create new document from default template" +msgstr "Vytvořit nový dokument z výchozí Å¡ablony" + +#: ../../po/../src/verbs.cpp:1847 +msgid "_Open..." +msgstr "Otevřít..." + +#: ../../po/../src/verbs.cpp:1848 +msgid "Open existing document" +msgstr "Otevřít existující dokument" + +#: ../../po/../src/verbs.cpp:1849 +msgid "Re_vert" +msgstr "Na_vrátit" + +#: ../../po/../src/verbs.cpp:1850 +msgid "Revert to the last saved version of document (changes will be lost)" +msgstr "Vrátit se k poslední uložené verzi dokumentu (změny budou ztraceny)" + +#: ../../po/../src/verbs.cpp:1851 +msgid "_Save" +msgstr "Uložit" + +#: ../../po/../src/verbs.cpp:1851 +msgid "Save document" +msgstr "Uložit dokument" + +#: ../../po/../src/verbs.cpp:1853 +msgid "Save _As..." +msgstr "Uložit j_ako..." + +#: ../../po/../src/verbs.cpp:1854 +msgid "Save document under new name" +msgstr "Uložit dokument pod novým názvem" + +#: ../../po/../src/verbs.cpp:1855 +msgid "_Print..." +msgstr "Tisk..." + +#: ../../po/../src/verbs.cpp:1855 +msgid "Print document" +msgstr "Tisknout dokument" + +#. TRANSLATORS: "Vacuum Defs" means "Clean up defs" (so as to remove unused definitions) +#: ../../po/../src/verbs.cpp:1858 +msgid "Vac_uum Defs" +msgstr "Vyčistit definice" + +#: ../../po/../src/verbs.cpp:1858 +#, fuzzy +msgid "Remove unused predefined items from the <defs> of the document" +msgstr "Odstranit nepoužívané položky z <defs> dokumentu" + +#: ../../po/../src/verbs.cpp:1860 +msgid "Print _Direct" +msgstr "Tisknout přímo" + +#: ../../po/../src/verbs.cpp:1861 +#, fuzzy +msgid "Print directly without prompting to a file or pipe" +msgstr "Tisk přímo do souboru nebo roury" + +#: ../../po/../src/verbs.cpp:1862 +msgid "Print Previe_w" +msgstr "Náhled tisku" + +#: ../../po/../src/verbs.cpp:1863 +msgid "Preview document printout" +msgstr "Náhled na dokument k vytiÅ¡tění" + +#: ../../po/../src/verbs.cpp:1864 +msgid "_Import..." +msgstr "_Import..." + +#: ../../po/../src/verbs.cpp:1865 +msgid "Import bitmap or SVG image into document" +msgstr "Import bitmapy nebo obrázku SVG do dokumentu" + +#: ../../po/../src/verbs.cpp:1866 +msgid "_Export Bitmap..." +msgstr "Exportovat bitmapu" + +#: ../../po/../src/verbs.cpp:1867 +#, fuzzy +msgid "Export document or selection as a bitmap image" +msgstr "Export dokumentu nebo výběru jako bitmapy PNG" + +#: ../../po/../src/verbs.cpp:1868 +msgid "N_ext Window" +msgstr "Následující okno" + +#: ../../po/../src/verbs.cpp:1869 +msgid "Switch to the next document window" +msgstr "Přepnout do dalšího okna dokumentu" + +#: ../../po/../src/verbs.cpp:1870 +msgid "P_revious Window" +msgstr "Předchozí okno" + +#: ../../po/../src/verbs.cpp:1871 +msgid "Switch to the previous document window" +msgstr "Přepnout do okna předchozího dokumentu" + +#: ../../po/../src/verbs.cpp:1872 +msgid "_Close" +msgstr "Zavřít" + +#: ../../po/../src/verbs.cpp:1873 +msgid "Close window" +msgstr "Zavřít okno" + +#: ../../po/../src/verbs.cpp:1874 +msgid "_Quit" +msgstr "Ukončit" + +#: ../../po/../src/verbs.cpp:1874 +msgid "Quit Inkscape" +msgstr "Ukončit Inkscape" + +#. Edit +#: ../../po/../src/verbs.cpp:1877 +msgid "_Undo" +msgstr "Zpět" + +#: ../../po/../src/verbs.cpp:1877 +msgid "Undo last action" +msgstr "Vrátit zpět poslední akci" + +#: ../../po/../src/verbs.cpp:1879 +msgid "_Redo" +msgstr "Znovu" + +#: ../../po/../src/verbs.cpp:1880 +msgid "Do again last undone action" +msgstr "Znovu provést vrácenou akci" + +#: ../../po/../src/verbs.cpp:1881 +msgid "Cu_t" +msgstr "Vyjmout" + +#: ../../po/../src/verbs.cpp:1882 +msgid "Cut selection to clipboard" +msgstr "Vyjmout vybrané objekty do schránky" + +#: ../../po/../src/verbs.cpp:1883 +msgid "_Copy" +msgstr "Kopírovat" + +#: ../../po/../src/verbs.cpp:1884 +msgid "Copy selection to clipboard" +msgstr "Kopírovat vybrané objekty do schránky" + +#: ../../po/../src/verbs.cpp:1885 +msgid "_Paste" +msgstr "Vložit" + +#: ../../po/../src/verbs.cpp:1886 +#, fuzzy +msgid "Paste objects from clipboard to mouse point" +msgstr "Vložit objekty ze schránky" + +#: ../../po/../src/verbs.cpp:1887 +msgid "Paste _Style" +msgstr "Vložit _Styl" + +#: ../../po/../src/verbs.cpp:1888 +msgid "Apply style of the copied object to selection" +msgstr "Aplikovat styl z kopírovaného objektu na výběr" + +#: ../../po/../src/verbs.cpp:1889 +msgid "Paste _In Place" +msgstr "Vložit v místě" + +#: ../../po/../src/verbs.cpp:1890 +#, fuzzy +msgid "Paste objects from clipboard to the original location" +msgstr "Vložit objekt(y) ze schránky na původní umístění" + +#: ../../po/../src/verbs.cpp:1891 +msgid "_Delete" +msgstr "Odstranit" + +#: ../../po/../src/verbs.cpp:1892 +msgid "Delete selection" +msgstr "Odstranit výběr" + +#: ../../po/../src/verbs.cpp:1893 +msgid "Duplic_ate" +msgstr "Duplikovat" + +#: ../../po/../src/verbs.cpp:1894 +#, fuzzy +msgid "Duplicate selected objects" +msgstr "Duplikovat vybrané objekty" + +#: ../../po/../src/verbs.cpp:1895 +msgid "Clo_ne" +msgstr "Klo_novat" + +#: ../../po/../src/verbs.cpp:1896 +msgid "Create a clone of selected object (a copy linked to the original)" +msgstr "Vytvořit klon vybraného objektu (kopie propojená s originálem)" + +#: ../../po/../src/verbs.cpp:1897 +msgid "Unlin_k Clone" +msgstr "Odpojit klon" + +#: ../../po/../src/verbs.cpp:1898 +msgid "Cut the clone's link to its original" +msgstr "Odstranit propojení klonu s originálem" + +#: ../../po/../src/verbs.cpp:1899 +msgid "Select _Original" +msgstr "Vybrat originál" + +#: ../../po/../src/verbs.cpp:1900 +msgid "Select the object to which the clone is linked" +msgstr "Vybere objekt, se kterým je klon spojen" + +#. TRANSLATORS: Convert selection to a rectangle with tiled pattern fill +#: ../../po/../src/verbs.cpp:1902 +#, fuzzy +msgid "O_bjects to Pattern" +msgstr "Objekt(y) na vzorek" + +#: ../../po/../src/verbs.cpp:1903 +msgid "Convert selection to a rectangle with tiled pattern fill" +msgstr "Převést výběr na obdélník s dlaždicovou výplní" + +#. TRANSLATORS: Extract objects from a tiled pattern fill +#: ../../po/../src/verbs.cpp:1905 +#, fuzzy +msgid "Pattern to Ob_jects" +msgstr "Vzorek na objekt(y)" + +#: ../../po/../src/verbs.cpp:1906 +msgid "Extract objects from a tiled pattern fill" +msgstr "Extrahovat objekty z dlaždicového vzoru výplně" + +#: ../../po/../src/verbs.cpp:1907 +msgid "Clea_r All" +msgstr "Vymazat vÅ¡e" + +#: ../../po/../src/verbs.cpp:1908 +msgid "Delete all objects from document" +msgstr "Odstranit vÅ¡echny objekty z dokumentu" + +#: ../../po/../src/verbs.cpp:1909 +msgid "Select Al_l" +msgstr "Vybrat vÅ¡e" + +#: ../../po/../src/verbs.cpp:1910 +msgid "Select all objects or all nodes" +msgstr "Vybere vÅ¡echny objekty nebo vÅ¡echny uzly" + +#: ../../po/../src/verbs.cpp:1911 +msgid "Select All in All La_yers" +msgstr "Vybrat vÅ¡e ve vÅ¡ech vrstvách" + +#: ../../po/../src/verbs.cpp:1912 +msgid "Select all objects in all visible and unlocked layers" +msgstr "Vybere vÅ¡echny objekty ve vÅ¡ech viditelných a odemčených vrstvách" + +#: ../../po/../src/verbs.cpp:1913 +msgid "In_vert Selection" +msgstr "Invertovat výběr" + +#: ../../po/../src/verbs.cpp:1914 +msgid "Invert selection (unselect what is selected and select everything else)" +msgstr "Invertovat výběr (odznačit co je vybrané a označit vÅ¡e ostatní)" + +#: ../../po/../src/verbs.cpp:1915 +msgid "Invert in All Layers" +msgstr "Invertovat ve vÅ¡ech vrstvách" + +#: ../../po/../src/verbs.cpp:1916 +msgid "Invert selection in all visible and unlocked layers" +msgstr "Invertovat výběr ve vÅ¡ech viditelných a odemčených vrstvách" + +#: ../../po/../src/verbs.cpp:1917 +msgid "D_eselect" +msgstr "ZruÅ¡it výběr" + +#: ../../po/../src/verbs.cpp:1918 +msgid "Deselect any selected objects or nodes" +msgstr "ZruÅ¡it výběr jakýchkoliv vybraných objektů nebo uzlů" + +#. Selection +#: ../../po/../src/verbs.cpp:1921 +msgid "Raise to _Top" +msgstr "Přesunout úplně nahoru" + +#: ../../po/../src/verbs.cpp:1922 +msgid "Raise selection to top" +msgstr "Přesunout výběr úplně nahoru" + +#: ../../po/../src/verbs.cpp:1923 +msgid "Lower to _Bottom" +msgstr "Přesunout dospod" + +#: ../../po/../src/verbs.cpp:1924 +msgid "Lower selection to bottom" +msgstr "Přesunout výběr úplně dolů" + +#: ../../po/../src/verbs.cpp:1925 +msgid "_Raise" +msgstr "Posunout výš" + +#: ../../po/../src/verbs.cpp:1926 +msgid "Raise selection one step" +msgstr "Přesunout výběr o úroveň výš" + +#: ../../po/../src/verbs.cpp:1927 +msgid "_Lower" +msgstr "Posunout níž" + +#: ../../po/../src/verbs.cpp:1928 +msgid "Lower selection one step" +msgstr "Přesunout výběr o úroveň níž" + +#: ../../po/../src/verbs.cpp:1929 +msgid "_Group" +msgstr "Seskupit" + +#: ../../po/../src/verbs.cpp:1930 +msgid "Group selected objects" +msgstr "Seskupit vybrané objekty" + +#: ../../po/../src/verbs.cpp:1932 +#, fuzzy +msgid "Ungroup selected groups" +msgstr "ZruÅ¡it seskupení vybrané skupiny" + +#: ../../po/../src/verbs.cpp:1934 +msgid "_Put on Path" +msgstr "_Umístit na křivku" + +#: ../../po/../src/verbs.cpp:1935 +msgid "Put text on path" +msgstr "Položit text na křivku" + +#: ../../po/../src/verbs.cpp:1936 +msgid "_Remove from Path" +msgstr "Odstranit z křivky" + +#: ../../po/../src/verbs.cpp:1937 +msgid "Remove text from path" +msgstr "Odstranit text z křivky" + +#: ../../po/../src/verbs.cpp:1938 +msgid "Remove Manual _Kerns" +msgstr "Odstranit manuální _kerning" + +#. TRANSLATORS: "glyph": An image used in the visual representation of characters; +#. roughly speaking, how a character looks. A font is a set of glyphs. +#: ../../po/../src/verbs.cpp:1941 +msgid "Remove all manual kerns and glyph rotations from a text object" +msgstr "Odstranit vÅ¡echen manuální kerning a rotace znaků z textového objektu" + +#: ../../po/../src/verbs.cpp:1943 +msgid "_Union" +msgstr "_Sjednocení" + +#: ../../po/../src/verbs.cpp:1944 +msgid "Union of selected objects" +msgstr "Sjednocení vybraných objektů" + +#: ../../po/../src/verbs.cpp:1945 +msgid "_Intersection" +msgstr "Průn_ik" + +#: ../../po/../src/verbs.cpp:1946 +msgid "Intersection of selected objects" +msgstr "Průnik vybraných objektů" + +#: ../../po/../src/verbs.cpp:1947 +msgid "_Difference" +msgstr "Roz_díl" + +#: ../../po/../src/verbs.cpp:1948 +msgid "Difference of selected objects (bottom minus top)" +msgstr "Rozdíl vybraných objektů (spodní mínus horní)" + +#: ../../po/../src/verbs.cpp:1949 +msgid "E_xclusion" +msgstr "Non-Ekvivalence (XOR)" + +#: ../../po/../src/verbs.cpp:1950 +msgid "Exclusive OR of selected objects" +msgstr "XOR vybraných objektů" + +#: ../../po/../src/verbs.cpp:1951 +msgid "Di_vision" +msgstr "Dělení" + +#: ../../po/../src/verbs.cpp:1952 +msgid "Cut the bottom object into pieces" +msgstr "Rozřezat spodní objekt na kousky" + +#. TRANSLATORS: "to cut a path" is not the same as "to break a path apart" - see the +#. Advanced tutorial for more info +#: ../../po/../src/verbs.cpp:1955 +msgid "Cut _Path" +msgstr "Oříznout křivku" + +#: ../../po/../src/verbs.cpp:1956 +msgid "Cut the bottom object's stroke into pieces, removing fill" +msgstr "Rozřezat obrys spodního objektu na kousky, odstraní výplň" + +#. TRANSLATORS: "outset": expand a shape by offsetting the object's path, +#. i.e. by displacing it perpendicular to the path in each point. +#. See also the Advanced Tutorial for explanation. +#: ../../po/../src/verbs.cpp:1960 +msgid "Outs_et" +msgstr "Rozšířit" + +#: ../../po/../src/verbs.cpp:1961 +#, fuzzy +msgid "Outset selected paths" +msgstr "Rozšířit vybrané křivky" + +#: ../../po/../src/verbs.cpp:1963 +msgid "O_utset Path by 1 px" +msgstr "Rozšířit Křivku o 1px" + +#: ../../po/../src/verbs.cpp:1964 +#, fuzzy +msgid "Outset selected paths by 1 px" +msgstr "Rozšířit vybrané křivky o 1px" + +#: ../../po/../src/verbs.cpp:1966 +msgid "O_utset Path by 10 px" +msgstr "Rozšířit Křivku o 10px" + +#: ../../po/../src/verbs.cpp:1967 +#, fuzzy +msgid "Outset selected paths by 10 px" +msgstr "Rozšířit vybrané křivky o 10px" + +#. TRANSLATORS: "inset": contract a shape by offsetting the object's path, +#. i.e. by displacing it perpendicular to the path in each point. +#. See also the Advanced Tutorial for explanation. +#: ../../po/../src/verbs.cpp:1971 +msgid "I_nset" +msgstr "SmrÅ¡tit" + +#: ../../po/../src/verbs.cpp:1972 +#, fuzzy +msgid "Inset selected paths" +msgstr "SmrÅ¡tit vybrané křivky" + +#: ../../po/../src/verbs.cpp:1974 +msgid "I_nset Path by 1 px" +msgstr "SmrÅ¡tit Křivku o 1px" + +#: ../../po/../src/verbs.cpp:1975 +#, fuzzy +msgid "Inset selected paths by 1 px" +msgstr "SmrÅ¡tit vybrané křivky o 1px" + +#: ../../po/../src/verbs.cpp:1977 +msgid "I_nset Path by 10 px" +msgstr "SmrÅ¡tit Křivku o 10px" + +#: ../../po/../src/verbs.cpp:1978 +#, fuzzy +msgid "Inset selected paths by 10 px" +msgstr "SmrÅ¡tit vybrané křivky o 10px" + +#: ../../po/../src/verbs.cpp:1980 +msgid "D_ynamic Offset" +msgstr "D_ynamické rozšíření" + +#: ../../po/../src/verbs.cpp:1980 +msgid "Create a dynamic offset object" +msgstr "Vytvořit objekt s dynamickým okrajem" + +#: ../../po/../src/verbs.cpp:1982 +msgid "_Linked Offset" +msgstr "Propojené rozšíření" + +#: ../../po/../src/verbs.cpp:1983 +msgid "Create a dynamic offset object linked to the original path" +msgstr "Vytvořit dynamicky rozÅ¡iřovaný objekt propojený s původní křivkou" + +#: ../../po/../src/verbs.cpp:1985 +msgid "_Stroke to Path" +msgstr "Obry_s na křivku" + +#: ../../po/../src/verbs.cpp:1986 +#, fuzzy +msgid "Convert selected strokes to paths" +msgstr "Převést vybrané obrysy na křivky" + +#: ../../po/../src/verbs.cpp:1987 +msgid "Si_mplify" +msgstr "ZjednoduÅ¡it" + +#: ../../po/../src/verbs.cpp:1988 +#, fuzzy +msgid "Simplify selected paths by removing extra nodes" +msgstr "ZjednoduÅ¡it vybrané křivky odstraněním nadbytečných uzlů" + +#: ../../po/../src/verbs.cpp:1989 +msgid "_Reverse" +msgstr "Přev_rátit" + +#: ../../po/../src/verbs.cpp:1990 +#, fuzzy +msgid "Reverses the direction of selected paths; useful for flipping markers" +msgstr "" +"Převrátí směr vybraných křivek; užitečné pro prohození značek začátku a konce" + +#. TRANSLATORS: "to trace" means "to convert a bitmap to vector graphics" (to vectorize) +#: ../../po/../src/verbs.cpp:1992 +msgid "_Trace Bitmap" +msgstr "Převés_t bitmapu" + +#: ../../po/../src/verbs.cpp:1993 +msgid "Convert bitmap object to paths" +msgstr "Převést bitmapové objekty na cesty" + +#: ../../po/../src/verbs.cpp:1994 +msgid "_Make a Bitmap Copy" +msgstr "Vytvořit bitmapovou kopii" + +#: ../../po/../src/verbs.cpp:1995 +msgid "Export selection to a bitmap and insert it into document" +msgstr "Exportovat výběr do bitmapy a vložit do dokumentu" + +#: ../../po/../src/verbs.cpp:1996 +msgid "_Combine" +msgstr "Kombinace" + +#: ../../po/../src/verbs.cpp:1997 +msgid "Combine several paths into one" +msgstr "Kombinovat několik křivek do jedné" + +#. TRANSLATORS: "to cut a path" is not the same as "to break a path apart" - see the +#. Advanced tutorial for more info +#: ../../po/../src/verbs.cpp:2000 +msgid "Break _Apart" +msgstr "Rozdělit na části" + +#: ../../po/../src/verbs.cpp:2001 +#, fuzzy +msgid "Break selected paths into subpaths" +msgstr "Rozdělit vybrané křivky na podkřivky" + +#: ../../po/../src/verbs.cpp:2002 +msgid "Gri_d Arrange..." +msgstr "Uspořádat do mřížky..." + +#: ../../po/../src/verbs.cpp:2003 +msgid "Arrange selection in grid pattern" +msgstr "Uspořádat výběr do mřížky" + +#. Layer +#: ../../po/../src/verbs.cpp:2005 +msgid "_Add Layer..." +msgstr "Přid_at vrstvu..." + +#: ../../po/../src/verbs.cpp:2006 +msgid "Create a new layer" +msgstr "Vytvořit novou vrstvu" + +#: ../../po/../src/verbs.cpp:2007 +msgid "Re_name Layer..." +msgstr "Přejme_novat vrstvu..." + +#: ../../po/../src/verbs.cpp:2008 +msgid "Rename the current layer" +msgstr "Přejmenovat aktuální vrstvu" + +#: ../../po/../src/verbs.cpp:2009 +msgid "Switch to Layer Abov_e" +msgstr "Přepnout O Vrstvu Výš" + +#: ../../po/../src/verbs.cpp:2010 +msgid "Switch to the layer above the current" +msgstr "Přepnout na vrstvu nad současnou" + +#: ../../po/../src/verbs.cpp:2011 +msgid "Switch to Layer Belo_w" +msgstr "Přepnout O Vrstvu Níž" + +#: ../../po/../src/verbs.cpp:2012 +msgid "Switch to the layer below the current" +msgstr "Přepnout na vrstvu pod současnou" + +#: ../../po/../src/verbs.cpp:2013 +msgid "Move Selection to Layer Abo_ve" +msgstr "Přesunout Výběr o Vrstvu Výš" + +#: ../../po/../src/verbs.cpp:2014 +msgid "Move selection to the layer above the current" +msgstr "Přesunou výběr do vrstvy nad současnou" + +#: ../../po/../src/verbs.cpp:2015 +msgid "Move Selection to Layer Bel_ow" +msgstr "Přesunout Výběr o Vrstvu Níž" + +#: ../../po/../src/verbs.cpp:2016 +msgid "Move selection to the layer below the current" +msgstr "Přesunou výběr do vrstvy pod současnou" + +#: ../../po/../src/verbs.cpp:2017 +msgid "Layer to _Top" +msgstr "Vrstvu úplně nahoru" + +#: ../../po/../src/verbs.cpp:2018 +msgid "Raise the current layer to the top" +msgstr "Přesunout aktuální vrstvu úplně nahoru" + +#: ../../po/../src/verbs.cpp:2019 +msgid "Layer to _Bottom" +msgstr "Vrstvu úplně dolů" + +#: ../../po/../src/verbs.cpp:2020 +msgid "Lower the current layer to the bottom" +msgstr "Přesunout aktuální vrstvy úplně naspod" + +#: ../../po/../src/verbs.cpp:2021 +msgid "_Raise Layer" +msgstr "Posunout vrstvu výš" + +#: ../../po/../src/verbs.cpp:2022 +msgid "Raise the current layer" +msgstr "Přesunout vrstvu níž" + +#: ../../po/../src/verbs.cpp:2023 +msgid "_Lower Layer" +msgstr "Posunout vrstvu níž" + +#: ../../po/../src/verbs.cpp:2024 +msgid "Lower the current layer" +msgstr "Přesunout vrstvu výš" + +#: ../../po/../src/verbs.cpp:2025 +msgid "_Delete Current Layer" +msgstr "_Vymazat aktuální vrstvu" + +#: ../../po/../src/verbs.cpp:2026 +msgid "Delete the current layer" +msgstr "Vymazat aktuální vrstvu" + +#. Object +#: ../../po/../src/verbs.cpp:2029 +#, fuzzy +msgid "Rotate _90° CW" +msgstr "Otočit o _90° vpravo" + +#: ../../po/../src/verbs.cpp:2030 +#, fuzzy +msgid "Rotate selection 90° clockwise" +msgstr "Otočit výběr o 90° po směru hodinových ručiček" + +#: ../../po/../src/verbs.cpp:2031 +#, fuzzy +msgid "Rotate 9_0° CCW" +msgstr "Otočit o 9_0° vlevo" + +#: ../../po/../src/verbs.cpp:2032 +#, fuzzy +msgid "Rotate selection 90° counter-clockwise" +msgstr "Otočit výběr o 90° po směru hodinových ručiček" + +#: ../../po/../src/verbs.cpp:2033 +msgid "Remove _Transformations" +msgstr "Odstranit _transformaci" + +#: ../../po/../src/verbs.cpp:2034 +msgid "Remove transformations from object" +msgstr "Odstranit transformace z objektu" + +#: ../../po/../src/verbs.cpp:2035 +msgid "_Object to Path" +msgstr "_Objekt na Křivku" + +#: ../../po/../src/verbs.cpp:2036 +#, fuzzy +msgid "Convert selected objects to paths" +msgstr "Převést vybraný objekt na křivku" + +#: ../../po/../src/verbs.cpp:2037 +msgid "_Flow into Frame" +msgstr "_Vlít text do rámce" + +#: ../../po/../src/verbs.cpp:2038 +#, fuzzy +msgid "Put text into frames" +msgstr "Vložit text do rámce(rámců)" + +#: ../../po/../src/verbs.cpp:2039 +msgid "_Unflow" +msgstr "ZruÅ¡it Vlití textu" + +#: ../../po/../src/verbs.cpp:2040 +msgid "Remove text from frame (creates a single-line text object)" +msgstr "Odstranit text z rámu (vytvoří jednořádkový textový objekt)" + +#: ../../po/../src/verbs.cpp:2041 +msgid "_Convert to Text" +msgstr "Převést na Text" + +#: ../../po/../src/verbs.cpp:2042 +#, fuzzy +msgid "Convert flowed text to regular text objects (preserves appearance)" +msgstr "" +"Převést vybraný vlitý text na obyčejný textový objekt (se zachováním vzhledu)" + +#: ../../po/../src/verbs.cpp:2044 +#, fuzzy +msgid "Flip _Horizontal" +msgstr "Obrátit vodorovně" + +#: ../../po/../src/verbs.cpp:2044 +#, fuzzy +msgid "Flips selected objects horizontally" +msgstr "Zarovnat vybrané uzly vodorovně" + +#: ../../po/../src/verbs.cpp:2047 +#, fuzzy +msgid "Flip _Vertical" +msgstr "Obrátit svisle" + +#: ../../po/../src/verbs.cpp:2047 +#, fuzzy +msgid "Flips selected objects vertically" +msgstr "Zarovnat vybrané uzly svisle" + +#. Tools +#: ../../po/../src/verbs.cpp:2051 +msgid "Select" +msgstr "Vybrat" + +#: ../../po/../src/verbs.cpp:2052 +msgid "Select and transform objects" +msgstr "Výběr a transformace objektů" + +#: ../../po/../src/verbs.cpp:2053 +msgid "Node Edit" +msgstr "Úpravy uzlů" + +#: ../../po/../src/verbs.cpp:2054 +msgid "Edit path nodes or control handles" +msgstr "Upravit uzly křivek nebo jejich ovládací táhla" + +#: ../../po/../src/verbs.cpp:2056 +msgid "Create rectangles and squares" +msgstr "Tvorba obdélníků a čtverců" + +#: ../../po/../src/verbs.cpp:2058 +msgid "Create circles, ellipses, and arcs" +msgstr "Tvorba kruhů, elips a oblouků" + +#: ../../po/../src/verbs.cpp:2060 +msgid "Create stars and polygons" +msgstr "Tvorba hvězd a polygonů" + +#: ../../po/../src/verbs.cpp:2062 +msgid "Create spirals" +msgstr "Tvorba spirál" + +#: ../../po/../src/verbs.cpp:2064 +msgid "Draw freehand lines" +msgstr "Kresba od ruky" + +#: ../../po/../src/verbs.cpp:2066 +msgid "Draw Bezier curves and straight lines" +msgstr "Kresba Bezierových křivek a přímých čar" + +#: ../../po/../src/verbs.cpp:2068 +msgid "Draw calligraphic lines" +msgstr "Kresba kaligrafických linek" + +#: ../../po/../src/verbs.cpp:2070 +msgid "Create and edit text objects" +msgstr "Tvorba a úprava textových objektů" + +#: ../../po/../src/verbs.cpp:2072 +msgid "Create and edit gradients" +msgstr "Tvorba a úpravy barevných přechodů" + +#: ../../po/../src/verbs.cpp:2074 +msgid "Zoom in or out" +msgstr "Přiblížení/oddálení obrázku" + +#: ../../po/../src/verbs.cpp:2076 +msgid "Pick averaged colors from image" +msgstr "Výběr průměrných barev z obrázku" + +#: ../../po/../src/verbs.cpp:2078 +msgid "Create connectors" +msgstr "Vytvořit konektory" + +#. Tool prefs +#: ../../po/../src/verbs.cpp:2081 +msgid "Selector Preferences" +msgstr "Vlastnosti nástroje pro výběr" + +#: ../../po/../src/verbs.cpp:2082 +#, fuzzy +msgid "Open Preferences for the Selector tool" +msgstr "Otevře nastavení Inkscape pro Nástroj výběru" + +#: ../../po/../src/verbs.cpp:2083 +msgid "Node Tool Preferences" +msgstr "Vlastnosti nástroje editace uzlů" + +#: ../../po/../src/verbs.cpp:2084 +#, fuzzy +msgid "Open Preferences for the Node tool" +msgstr "Otevře nastavení Inkscape pro Nástroj úpravy uzlů" + +#: ../../po/../src/verbs.cpp:2085 +msgid "Rectangle Preferences" +msgstr "Vlastnosti čtyřúhelníku" + +#: ../../po/../src/verbs.cpp:2086 +#, fuzzy +msgid "Open Preferences for the Rectangle tool" +msgstr "Otevře nastavení Inkscape pro Čtyřúhelníky" + +#: ../../po/../src/verbs.cpp:2087 +msgid "Ellipse Preferences" +msgstr "Vlastnosti elipsy" + +#: ../../po/../src/verbs.cpp:2088 +#, fuzzy +msgid "Open Preferences for the Ellipse tool" +msgstr "Otevře nastavení Inkscape pro Elipsu" + +#: ../../po/../src/verbs.cpp:2089 +msgid "Star Preferences" +msgstr "Vlastnosti hvězdy" + +#: ../../po/../src/verbs.cpp:2090 +#, fuzzy +msgid "Open Preferences for the Star tool" +msgstr "Otevře nastavení Inkscape pro Hvězdu" + +#: ../../po/../src/verbs.cpp:2091 +msgid "Spiral Preferences" +msgstr "Vlastnosti spirály" + +#: ../../po/../src/verbs.cpp:2092 +#, fuzzy +msgid "Open Preferences for the Spiral tool" +msgstr "Otevře nastavení Inkscape pro Spirálu" + +#: ../../po/../src/verbs.cpp:2093 +msgid "Pencil Preferences" +msgstr "Vlastnosti tužky" + +#: ../../po/../src/verbs.cpp:2094 +#, fuzzy +msgid "Open Preferences for the Pencil tool" +msgstr "Otevře nastavení Inkscape pro Tužku" + +#: ../../po/../src/verbs.cpp:2095 +msgid "Pen Preferences" +msgstr "Vlastnosti pera" + +#: ../../po/../src/verbs.cpp:2096 +#, fuzzy +msgid "Open Preferences for the Pen tool" +msgstr "Otevře vlastnosti pro nástroj Pero" + +#: ../../po/../src/verbs.cpp:2097 +msgid "Calligraphic Preferences" +msgstr "Vlastnosti kaligrafické linie" + +#: ../../po/../src/verbs.cpp:2098 +#, fuzzy +msgid "Open Preferences for the Calligraphy tool" +msgstr "Otevře nastavení Inkscape pro Kaligrafické pero" + +#: ../../po/../src/verbs.cpp:2099 +msgid "Text Preferences" +msgstr "Vlastnosti textu" + +#: ../../po/../src/verbs.cpp:2100 +#, fuzzy +msgid "Open Preferences for the Text tool" +msgstr "Otevře nastavení Inkscape pro Text" + +#: ../../po/../src/verbs.cpp:2101 +msgid "Gradient Preferences" +msgstr "Vlastnosti Barevného přechodu" + +#: ../../po/../src/verbs.cpp:2102 +#, fuzzy +msgid "Open Preferences for the Gradient tool" +msgstr "Otevře Nastavení Inkscape pro nástroj Barevný přechod" + +#: ../../po/../src/verbs.cpp:2103 +msgid "Zoom Preferences" +msgstr "Vlastnosti lupy" + +#: ../../po/../src/verbs.cpp:2104 +#, fuzzy +msgid "Open Preferences for the Zoom tool" +msgstr "Otevře nastavení Inkscape pro Lupu" + +#: ../../po/../src/verbs.cpp:2105 +msgid "Dropper Preferences" +msgstr "Vlastnosti pipety" + +#: ../../po/../src/verbs.cpp:2106 +#, fuzzy +msgid "Open Preferences for the Dropper tool" +msgstr "Otevře nastavení Inkscape pro Pipetu" + +#: ../../po/../src/verbs.cpp:2107 +msgid "Connector Preferences" +msgstr "Předvolby Konektorů" + +#: ../../po/../src/verbs.cpp:2108 +#, fuzzy +msgid "Open Preferences for the Connector tool" +msgstr "Otevře nastavení Inkscape pro Nástroj Konektory" + +#. Zoom/View +#: ../../po/../src/verbs.cpp:2111 +msgid "Zoom In" +msgstr "Přiblížit" + +#: ../../po/../src/verbs.cpp:2111 +msgid "Zoom in" +msgstr "Přiblížit" + +#: ../../po/../src/verbs.cpp:2112 +msgid "Zoom Out" +msgstr "Oddálit" + +#: ../../po/../src/verbs.cpp:2112 +msgid "Zoom out" +msgstr "Oddálit" + +#: ../../po/../src/verbs.cpp:2113 +msgid "_Rulers" +msgstr "P_ravítka" + +#: ../../po/../src/verbs.cpp:2113 +msgid "Show or hide the canvas rulers" +msgstr "Zobrazit/Skrýt pravítka" + +#: ../../po/../src/verbs.cpp:2114 +msgid "Scroll_bars" +msgstr "Posuvníky" + +#: ../../po/../src/verbs.cpp:2114 +msgid "Show or hide the canvas scrollbars" +msgstr "Zobrazit/Skrýt posuvníky" + +#: ../../po/../src/verbs.cpp:2115 +msgid "_Grid" +msgstr "Mřížka" + +#: ../../po/../src/verbs.cpp:2116 +msgid "G_uides" +msgstr "Vodítka" + +#: ../../po/../src/verbs.cpp:2117 +msgid "Nex_t Zoom" +msgstr "Následující přiblížení" + +#: ../../po/../src/verbs.cpp:2117 +msgid "Next zoom (from the history of zooms)" +msgstr "Následující přiblížení(z historie přiblížení)" + +#: ../../po/../src/verbs.cpp:2119 +msgid "Pre_vious Zoom" +msgstr "Předchozí přiblížení" + +#: ../../po/../src/verbs.cpp:2119 +msgid "Previous zoom (from the history of zooms)" +msgstr "Předchozí přiblížení(z historie přiblížení)" + +#: ../../po/../src/verbs.cpp:2121 +msgid "Zoom 1:_1" +msgstr "Nastavit poměr zvětÅ¡ení na 1:_1" + +#: ../../po/../src/verbs.cpp:2121 +msgid "Zoom to 1:1" +msgstr "Nastavit poměr zvětÅ¡ení na 1:1" + +#: ../../po/../src/verbs.cpp:2123 +msgid "Zoom 1:_2" +msgstr "Nastavit poměr zvětÅ¡ení na 1:_2" + +#: ../../po/../src/verbs.cpp:2123 +msgid "Zoom to 1:2" +msgstr "Nastavit poměr zvětÅ¡ení na 1:2" + +#: ../../po/../src/verbs.cpp:2125 +msgid "_Zoom 2:1" +msgstr "Nastavit poměr zvětÅ¡ení na 2:1" + +#: ../../po/../src/verbs.cpp:2125 +msgid "Zoom to 2:1" +msgstr "Nastavit poměr zvětÅ¡ení na 2:1" + +#: ../../po/../src/verbs.cpp:2128 +msgid "_Fullscreen" +msgstr "Celá obrazovka" + +#: ../../po/../src/verbs.cpp:2128 +msgid "Stretch this document window to full screen" +msgstr "Přepne velikost okna dokumentu na celou obrazovku" + +#: ../../po/../src/verbs.cpp:2131 +msgid "Duplic_ate Window" +msgstr "Duplikov_at okno" + +#: ../../po/../src/verbs.cpp:2131 +msgid "Open a new window with the same document" +msgstr "Otevřít nové okno se stávajícím dokumentem" + +#: ../../po/../src/verbs.cpp:2133 +msgid "_New View Preview" +msgstr "_Nový náhledový pohled" + +#: ../../po/../src/verbs.cpp:2134 +msgid "New View Preview" +msgstr "Nový náhledový pohled" + +#. "view_new_preview" +#: ../../po/../src/verbs.cpp:2136 +#, fuzzy +msgid "_Normal" +msgstr "Normální" + +#: ../../po/../src/verbs.cpp:2137 +msgid "Switch to normal display mode" +msgstr "" + +#: ../../po/../src/verbs.cpp:2138 +#, fuzzy +msgid "_Outline" +msgstr "Zobrazit kontury" + +#: ../../po/../src/verbs.cpp:2139 +msgid "Switch to outline (wireframe) display mode" +msgstr "" + +#: ../../po/../src/verbs.cpp:2141 +msgid "Ico_n Preview" +msgstr "Náhled _Ikony" + +#: ../../po/../src/verbs.cpp:2142 +msgid "Open a window to preview items at different icon resolutions" +msgstr "Otevře okno s náhledem na ikonu v různých rozliÅ¡eních" + +#: ../../po/../src/verbs.cpp:2144 +msgid "Zoom to fit page in window" +msgstr "Přizpůsobit stránku oknu" + +#: ../../po/../src/verbs.cpp:2145 +msgid "Page _Width" +msgstr "Šířka strany" + +#: ../../po/../src/verbs.cpp:2146 +msgid "Zoom to fit page width in window" +msgstr "Přizpůsobit šířku stránky oknu" + +#: ../../po/../src/verbs.cpp:2148 +msgid "Zoom to fit drawing in window" +msgstr "Přizpůsobit kresbu oknu" + +#: ../../po/../src/verbs.cpp:2150 +msgid "Zoom to fit selection in window" +msgstr "Přizpůsobit výběr oknu" + +#. Dialogs +#: ../../po/../src/verbs.cpp:2153 +msgid "In_kscape Preferences..." +msgstr "Nastavení In_kscape..." + +#: ../../po/../src/verbs.cpp:2154 +msgid "Global Inkscape preferences" +msgstr "Globální nastavení Inkscape" + +#: ../../po/../src/verbs.cpp:2155 +msgid "_Document Preferences..." +msgstr "Vlastnosti _Dokumentu..." + +#: ../../po/../src/verbs.cpp:2156 +msgid "Preferences saved with the document" +msgstr "Nastavení uložená s dokumentem" + +#: ../../po/../src/verbs.cpp:2157 +msgid "_Fill and Stroke..." +msgstr "Výplň a obrys..." + +#: ../../po/../src/verbs.cpp:2158 +msgid "Fill and Stroke dialog" +msgstr "Výplň a obrys" + +#. TRANSLATORS: "Swatches" means: color samples +#: ../../po/../src/verbs.cpp:2160 +msgid "S_watches..." +msgstr "Vzorníky barev..." + +#: ../../po/../src/verbs.cpp:2161 +msgid "View color swatches" +msgstr "Zobrazit vzorníky barev" + +#: ../../po/../src/verbs.cpp:2162 +msgid "Transfor_m..." +msgstr "Transformace..." + +#: ../../po/../src/verbs.cpp:2163 +msgid "Transform dialog" +msgstr "Transformace" + +#: ../../po/../src/verbs.cpp:2164 +msgid "_Align and Distribute..." +msgstr "Z_arovnat a rozmístit..." + +#: ../../po/../src/verbs.cpp:2165 +msgid "Align and Distribute dialog" +msgstr "Zarovnání a rozmístění" + +#: ../../po/../src/verbs.cpp:2166 +msgid "_Text and Font..." +msgstr "_Text a písmo..." + +#: ../../po/../src/verbs.cpp:2167 +msgid "Text and Font dialog" +msgstr "Dialog Text a písmo" + +#: ../../po/../src/verbs.cpp:2168 +msgid "_XML Editor..." +msgstr "Editor _XML..." + +#: ../../po/../src/verbs.cpp:2169 +msgid "XML Editor" +msgstr "Editor XML" + +#: ../../po/../src/verbs.cpp:2170 +msgid "_Find..." +msgstr "Hledat..." + +#: ../../po/../src/verbs.cpp:2171 +msgid "Find objects in document" +msgstr "Nalézt objekty v dokumentu" + +#: ../../po/../src/verbs.cpp:2172 +msgid "_Messages..." +msgstr "Zprávy..." + +#: ../../po/../src/verbs.cpp:2173 +msgid "View debug messages" +msgstr "Zobrazit ladící informace" + +#: ../../po/../src/verbs.cpp:2174 +msgid "S_cripts..." +msgstr "Skripty..." + +#: ../../po/../src/verbs.cpp:2175 +msgid "Run scripts" +msgstr "Spustit skripty" + +#: ../../po/../src/verbs.cpp:2176 +msgid "Show/Hide D_ialogs" +msgstr "Zobrazit/Skrýt Dialogová okna" + +#: ../../po/../src/verbs.cpp:2177 +msgid "Show or hide all active dialogs" +msgstr "Ukázat nebo skrýt vÅ¡echny aktivní dialogy" + +#. TRANSLATORS: "Tile clones" means: "Create tiled clones" +#: ../../po/../src/verbs.cpp:2179 +msgid "Tile clones..." +msgstr "Dláždit pomocí klonů..." + +#: ../../po/../src/verbs.cpp:2180 +msgid "Create and arrange multiple clones of selection" +msgstr "Vytvořit a rozmístit klony výběru" + +#: ../../po/../src/verbs.cpp:2181 +msgid "_Object Properties..." +msgstr "Vlastnosti _objektu..." + +#: ../../po/../src/verbs.cpp:2182 +msgid "Object Properties dialog" +msgstr "Dialog Vlastnosti objektu" + +#: ../../po/../src/verbs.cpp:2185 +msgid "_Connect to Jabber server..." +msgstr "Připojit k Jabber serveru..." + +#: ../../po/../src/verbs.cpp:2185 +msgid "Connect to a Jabber server" +msgstr "Připojit k Jabber serveru" + +#: ../../po/../src/verbs.cpp:2187 +msgid "Share with _user..." +msgstr "Sdílet s _uživatelem..." + +#: ../../po/../src/verbs.cpp:2187 +msgid "Establish a whiteboard session with another Jabber user" +msgstr "Vytvořit whiteboard sezení s jiným uživatelem sítě Jabber" + +#: ../../po/../src/verbs.cpp:2189 +msgid "Share with _chatroom..." +msgstr "Sdílet s místností..." + +#: ../../po/../src/verbs.cpp:2189 +msgid "" +"Join a chatroom to start a new whiteboard session or join one in progress" +msgstr "" +"Vstupem do místnosti vytvoříte nové sezení whiteboard nebo se připojíte k " +"již probíhajícímu" + +#: ../../po/../src/verbs.cpp:2191 +msgid "_Dump XML node tracker" +msgstr "Vypsat trasování XML uzlů" + +#: ../../po/../src/verbs.cpp:2191 +msgid "Dump the contents of the XML tracker to the console" +msgstr "Vypsat obsah XML trackeru do konzoly" + +#: ../../po/../src/verbs.cpp:2193 +msgid "_Open session file..." +msgstr "_Otevřít soubor sezení..." + +#: ../../po/../src/verbs.cpp:2193 +msgid "Open and browse through records of past whiteboard sessions" +msgstr "Otevřít a procházet záznamy minulých whiteboard sezení" + +#: ../../po/../src/verbs.cpp:2195 +msgid "Session file playback" +msgstr "Přehrát soubor se sezením" + +#: ../../po/../src/verbs.cpp:2197 +msgid "_Disconnect from session" +msgstr "O_dpojit od sezení" + +#: ../../po/../src/verbs.cpp:2199 +msgid "Disconnect from _server" +msgstr "Odpojit od _serveru" + +#: ../../po/../src/verbs.cpp:2201 +msgid "_Input Devices..." +msgstr "Vstupní Zařízení..." + +#: ../../po/../src/verbs.cpp:2202 +msgid "Configure extended input devices" +msgstr "Konfigurovat rozšířená vstupní zařízení" + +#. Help +#: ../../po/../src/verbs.cpp:2205 +msgid "_Keys and Mouse" +msgstr "_Klávesy a MyÅ¡" + +#: ../../po/../src/verbs.cpp:2206 +msgid "Key and mouse shortcuts reference" +msgstr "Seznam klávesových zkratek a příkazů myÅ¡i" + +#: ../../po/../src/verbs.cpp:2207 +msgid "About E_xtensions" +msgstr "O Rozšířeních" + +#: ../../po/../src/verbs.cpp:2208 +msgid "About Extensions..." +msgstr "O Rozšířeních..." + +#: ../../po/../src/verbs.cpp:2209 +msgid "About _Memory" +msgstr "O Pa_měti" + +#: ../../po/../src/verbs.cpp:2210 +msgid "About Memory..." +msgstr "O Paměti..." + +#: ../../po/../src/verbs.cpp:2211 +msgid "_About Inkscape" +msgstr "O Inksc_ape" + +#. "help_about" +#. new HelpVerb(SP_VERB_SHOW_LICENSE, "ShowLicense", N_("Modifying or Redistributing Inkscape"), +#. N_("Show license to modify and/or redistribute Inkscape: GNU GPL"), NULL), +#. Tutorials +#: ../../po/../src/verbs.cpp:2217 +msgid "Inkscape: _Basic" +msgstr "Inkscape: Základy" + +#: ../../po/../src/verbs.cpp:2218 +msgid "Getting started with Inkscape" +msgstr "Začínáme s Inkscape" + +#. "tutorial_basic" +#: ../../po/../src/verbs.cpp:2219 +msgid "Inkscape: _Shapes" +msgstr "Inkscape: Tvary" + +#: ../../po/../src/verbs.cpp:2220 +msgid "Using shape tools to create and edit shapes" +msgstr "Používáte nástroje tvaru pro tvorbu a úpravu tvarů" + +#: ../../po/../src/verbs.cpp:2221 +msgid "Inkscape: _Advanced" +msgstr "Inkscape: Pokročilé" + +#: ../../po/../src/verbs.cpp:2222 +msgid "Advanced Inkscape topics" +msgstr "Pokročilá témata" + +#. "tutorial_advanced" +#. TRANSLATORS: "to trace" means "to convert a bitmap to vector graphics" (to vectorize) +#: ../../po/../src/verbs.cpp:2224 +msgid "Inkscape: T_racing" +msgstr "Inkscape: Trasování" + +#: ../../po/../src/verbs.cpp:2225 +msgid "Using bitmap tracing" +msgstr "Používám trasování bitové mapy" + +#. "tutorial_tracing" +#: ../../po/../src/verbs.cpp:2226 +msgid "Inkscape: _Calligraphy" +msgstr "Inkscape: Kaligrafie" + +#: ../../po/../src/verbs.cpp:2227 +msgid "Using the Calligraphy pen tool" +msgstr "Používáte Kaligrafické pero" + +#: ../../po/../src/verbs.cpp:2228 +msgid "_Elements of Design" +msgstr "Elements of Design" + +#: ../../po/../src/verbs.cpp:2229 +msgid "Principles of design in the tutorial form" +msgstr "Principy designu v podobě tutorialu" + +#. "tutorial_design" +#: ../../po/../src/verbs.cpp:2230 +msgid "_Tips and Tricks" +msgstr "_Tipy a triky" + +#: ../../po/../src/verbs.cpp:2231 +msgid "Miscellaneous tips and tricks" +msgstr "Různé tipy a triky" + +#. "tutorial_tips" +#. Effect +#: ../../po/../src/verbs.cpp:2234 +msgid "Previous Effect" +msgstr "Předchozí efekt" + +#: ../../po/../src/verbs.cpp:2235 +msgid "Repeat the last effect with the same settings" +msgstr "Opakovat poslední efekt se stejným nastavením" + +#. "tutorial_tips" +#: ../../po/../src/verbs.cpp:2236 +msgid "Previous Effect Settings..." +msgstr "Předchozí Nastavení Efektu..." + +#: ../../po/../src/verbs.cpp:2237 +msgid "Repeat the last effect with new settings" +msgstr "Opakovat poslední efekt s novým nastavením" + +#: ../../po/../src/widgets/dash-selector.cpp:106 +msgid "Dash pattern" +msgstr "Å rafování" + +#: ../../po/../src/widgets/dash-selector.cpp:121 +msgid "Pattern offset" +msgstr "Posun vzorku" + +#: ../../po/../src/widgets/desktop-widget.cpp:240 +msgid "Zoom drawing if window size changes" +msgstr "Měnit přiblížení podle velikosti okna" + +#: ../../po/../src/widgets/desktop-widget.cpp:298 +msgid "Cursor coordinates" +msgstr "Souřadnice kurzoru" + +#. display the initial welcome message in the statusbar +#: ../../po/../src/widgets/desktop-widget.cpp:324 +msgid "" +"Welcome to Inkscape! Use shape or freehand tools to create objects; " +"use selector (arrow) to move or transform them." +msgstr "" +"Vítejte v Inkscape! Použijte nástroje pro tvary nebo kreslení k " +"vytvoření objektů; případně nástroj výběru(Å¡ipka) k jejich přesunu nebo " +"transformaci." + +#: ../../po/../src/widgets/desktop-widget.cpp:372 +#, c-format +msgid "%s: %d - Inkscape" +msgstr "%s: %d - Inkscape" + +#: ../../po/../src/widgets/desktop-widget.cpp:374 +#, c-format +msgid "%s - Inkscape" +msgstr "%s - Inkscape" + +#: ../../po/../src/widgets/desktop-widget.cpp:532 +#, c-format +msgid "" +"Save changes to document \"%s\" before " +"closing?\n" +"\n" +"If you close without saving, your changes will be discarded." +msgstr "" +"Uložit změny v dokumentu \"%s\" před " +"uzavřením?\n" +"\n" +"Pokud jej zavřete bez uložení, změny budou ztraceny." + +#: ../../po/../src/widgets/desktop-widget.cpp:548 +#: ../../po/../src/widgets/desktop-widget.cpp:612 +msgid "Close _without saving" +msgstr "Zavřít _bez uložení" + +#: ../../po/../src/widgets/desktop-widget.cpp:595 +#, c-format +msgid "" +"The file \"%s\" was saved with a " +"format (%s) that may cause data loss!\n" +"\n" +"Do you want to save this file in another format?" +msgstr "" +"Soubor \"%s\" byl uložen ve formátu (%" +"s) který může způsobit ztrátu dat!\n" +"\n" +"Nechcete jej uložit v jiném formátu?" + +#. Family frame +#: ../../po/../src/widgets/font-selector.cpp:156 +msgid "Font family" +msgstr "Rodina písma" + +#. Style frame +#: ../../po/../src/widgets/font-selector.cpp:184 +msgid "Style" +msgstr "Styl" + +#: ../../po/../src/widgets/font-selector.cpp:219 +msgid "Font size:" +msgstr "Velikost písma:" + +#. TRANSLATORS: Test string used in text and font dialog (when no +#. * text has been entered) to get a preview of the font. Choose +#. * some representative characters that users of your locale will be +#. * interested in. +#: ../../po/../src/widgets/font-selector.cpp:554 +msgid "AaBbCcIiPpQq12368.;/()" +msgstr "AaBbCcIiPpQqÁáČ芚řŘžŽ12368.;/()" + +#: ../../po/../src/widgets/gradient-selector.cpp:137 +#: ../../po/../src/widgets/gradient-toolbar.cpp:524 +msgid "Duplicate" +msgstr "Duplikovat" + +#: ../../po/../src/widgets/gradient-selector.cpp:142 +#: ../../po/../src/widgets/gradient-toolbar.cpp:535 +msgid "Edit..." +msgstr "Úpravy..." + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/pservers.html#LinearGradientSpreadMethodAttribute +#: ../../po/../src/widgets/gradient-selector.cpp:159 +msgid "" +"Whether to fill with flat color beyond the ends of the gradient vector " +"(spreadMethod=\"pad\"), or repeat the gradient in the same direction " +"(spreadMethod=\"repeat\"), or repeat the gradient in alternating opposite " +"directions (spreadMethod=\"reflect\")" +msgstr "" +"Zda po ukončení výplně barevným přechodem vyplňovat plnou barvou" +"(spreadMethod=\"pad\"), opakovat barevný přechod stejným směrem vykreslení " +"(spreadMethod=\"repeat\") nebo opakovat barevný přechod se střídáním směru " +"vykreslení (spreadMethod=\"reflect\")" + +#: ../../po/../src/widgets/gradient-selector.cpp:165 +msgid "none" +msgstr "žádné" + +#: ../../po/../src/widgets/gradient-selector.cpp:169 +msgid "reflected" +msgstr "zrcadlící" + +#: ../../po/../src/widgets/gradient-selector.cpp:173 +msgid "direct" +msgstr "přímý" + +#: ../../po/../src/widgets/gradient-selector.cpp:181 +msgid "Repeat:" +msgstr "Opakuj:" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:217 +msgid "No gradients" +msgstr "Bez přechodů" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:226 +msgid "Nothing selected" +msgstr "Nic není vybráno" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:237 +msgid "No gradients in selection" +msgstr "Ve výběru nejsou žádné barevné přechody" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:247 +msgid "Multiple gradients" +msgstr "Vícenásobné přechody" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:525 +msgid "" +"If the gradient is used by more than one object, create a copy of it for the " +"selected object(s)" +msgstr "" +"Jestliže je barevný přechod použit u více než jednoho objektu, vytvoří se " +"jeho kopie pro každý vybraný objekt." + +#: ../../po/../src/widgets/gradient-toolbar.cpp:536 +msgid "Edit the stops of the gradient" +msgstr "Upravit zarážky barevného přechodu" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:593 +#: ../../po/../src/widgets/toolbox.cpp:1103 +#: ../../po/../src/widgets/toolbox.cpp:1192 +#: ../../po/../src/widgets/toolbox.cpp:1485 +#: ../../po/../src/widgets/toolbox.cpp:1534 +#: ../../po/../src/widgets/toolbox.cpp:1766 +#: ../../po/../src/widgets/toolbox.cpp:1801 +#: ../../po/../src/widgets/toolbox.cpp:2331 +#: ../../po/../src/widgets/toolbox.cpp:2370 +msgid "New:" +msgstr "Nový:" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:606 +msgid "Create linear gradient" +msgstr "Vytvořit lineární přechod" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:620 +msgid "Create radial (elliptic or circular) gradient" +msgstr "Vytvořit radiální (eliptický nebo kruhový) barevný přechod" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:635 +msgid "on" +msgstr "pro " + +#: ../../po/../src/widgets/gradient-toolbar.cpp:648 +msgid "Create gradient in the fill" +msgstr "Vytvořit barevný přechod ve výplni" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:662 +msgid "Create gradient in the stroke" +msgstr "Vytvořit barevný přechod v obrysu" + +#. FIXME: implement averaging of all parameters for multiple selected stars +#. gtk_label_set_markup(GTK_LABEL(l), _("Average:")); +#. FIXME: implement averaging of all parameters for multiple selected +#. gtk_label_set_markup(GTK_LABEL(l), _("Average:")); +#: ../../po/../src/widgets/gradient-toolbar.cpp:676 +#: ../../po/../src/widgets/toolbox.cpp:1105 +#: ../../po/../src/widgets/toolbox.cpp:1124 +#: ../../po/../src/widgets/toolbox.cpp:1493 +#: ../../po/../src/widgets/toolbox.cpp:1518 +#: ../../po/../src/widgets/toolbox.cpp:1768 +#: ../../po/../src/widgets/toolbox.cpp:1787 +#: ../../po/../src/widgets/toolbox.cpp:2334 +#: ../../po/../src/widgets/toolbox.cpp:2354 +msgid "Change:" +msgstr "Změnit:" + +#: ../../po/../src/widgets/gradient-vector.cpp:269 +msgid "No gradients in document" +msgstr "V dokumentu nejsou žádné přechody" + +#: ../../po/../src/widgets/gradient-vector.cpp:275 +msgid "No gradient selected" +msgstr "Nejsou vybrány žádné přechody" + +#: ../../po/../src/widgets/gradient-vector.cpp:532 +msgid "No stops in gradient" +msgstr "Lineární přechod" + +#. TRANSLATORS: "Stop" means: a "phase" of a gradient +#: ../../po/../src/widgets/gradient-vector.cpp:794 +msgid "Add stop" +msgstr "Přidat zarážku" + +#: ../../po/../src/widgets/gradient-vector.cpp:797 +msgid "Add another control stop to gradient" +msgstr "Přidat další zarážku do barevného přechodu" + +#: ../../po/../src/widgets/gradient-vector.cpp:799 +msgid "Delete stop" +msgstr "Odstranit zařážku" + +#: ../../po/../src/widgets/gradient-vector.cpp:802 +msgid "Delete current control stop from gradient" +msgstr "Odstranit zarážku z barevného přechodu" + +#. Label +#: ../../po/../src/widgets/gradient-vector.cpp:813 +msgid "Offset:" +msgstr "Posun:" + +#. TRANSLATORS: "Stop" means: a "phase" of a gradient +#: ../../po/../src/widgets/gradient-vector.cpp:858 +msgid "Stop Color" +msgstr "Barva zařážky" + +#: ../../po/../src/widgets/gradient-vector.cpp:887 +msgid "Gradient editor" +msgstr "Editor barevných přechodů" + +#: ../../po/../src/widgets/layer-selector.cpp:119 +msgid "Toggle current layer visibility" +msgstr "Přepne viditelnost aktuální vrstvy" + +#: ../../po/../src/widgets/layer-selector.cpp:139 +msgid "Lock or unlock current layer" +msgstr "Zamkne nebo odemkne aktuální vrstvu" + +#: ../../po/../src/widgets/layer-selector.cpp:142 +msgid "Current layer" +msgstr "Aktuální vrstva" + +#: ../../po/../src/widgets/layer-selector.cpp:553 +msgid "(root)" +msgstr "(kořen)" + +#: ../../po/../src/widgets/paint-selector.cpp:182 +#: ../../po/../src/widgets/paint-selector.cpp:561 +msgid "No paint" +msgstr "Bez barvy" + +#: ../../po/../src/widgets/paint-selector.cpp:184 +#: ../../po/../src/widgets/paint-selector.cpp:629 +msgid "Flat color" +msgstr "Jedna barva" + +#: ../../po/../src/widgets/paint-selector.cpp:186 +#: ../../po/../src/widgets/paint-selector.cpp:696 +msgid "Linear gradient" +msgstr "Lineární přechod" + +#: ../../po/../src/widgets/paint-selector.cpp:188 +#: ../../po/../src/widgets/paint-selector.cpp:699 +msgid "Radial gradient" +msgstr "Kruhový přechod" + +#: ../../po/../src/widgets/paint-selector.cpp:192 +msgid "Unset paint (make it undefined so it can be inherited)" +msgstr "ZruÅ¡it vybarvení (vybarvení nebude definováno, může tedy být zděděno)" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/painting.html#FillRuleProperty +#: ../../po/../src/widgets/paint-selector.cpp:204 +msgid "" +"Any path self-intersections or subpaths create holes in the fill (fill-rule: " +"evenodd)" +msgstr "" +"Jakékoliv průsečík křivky samy se sebou, ale také pod-křivky, vytváří ve " +"výplni díry(fill-rule: evenodd)" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/painting.html#FillRuleProperty +#: ../../po/../src/widgets/paint-selector.cpp:215 +msgid "" +"Fill is solid unless a subpath is counterdirectional (fill-rule: nonzero)" +msgstr "" +"Výplň je jednolitá dokud křivka neprochází opačným směrem (fill-rule: " +"nenulové)" + +#: ../../po/../src/widgets/paint-selector.cpp:528 +msgid "No objects" +msgstr "Žádné objekty" + +#: ../../po/../src/widgets/paint-selector.cpp:539 +msgid "Multiple styles" +msgstr "Vícenásobný styl" + +#: ../../po/../src/widgets/paint-selector.cpp:550 +msgid "Paint is undefined" +msgstr "Barva není definována" + +#: ../../po/../src/widgets/paint-selector.cpp:757 +msgid "No patterns in document" +msgstr "V dokumentu nejsou žádné vzory" + +#: ../../po/../src/widgets/paint-selector.cpp:872 +msgid "" +"Use Edit > Object(s) to Pattern to create a new pattern from " +"selection." +msgstr "" +"Použijte Úpravy > Objekt(y) na Vzorek k vytvoření nového vzorku z " +"výběru." + +#: ../../po/../src/widgets/select-toolbar.cpp:426 +msgid "Now stroke width is scaled when objects are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:428 +msgid "Now stroke width is not scaled when objects are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:436 +msgid "" +"Now rounded rectangle corners are scaled when rectangles are " +"scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:438 +msgid "" +"Now rounded rectangle corners are not scaled when rectangles " +"are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:446 +msgid "" +"Now gradients are transformed along with their objects when " +"those are transformed (moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:448 +msgid "" +"Now gradients remain fixed when objects are transformed " +"(moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:456 +msgid "" +"Now patterns are transformed along with their objects when " +"those are transformed (moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:458 +msgid "" +"Now patterns remain fixed when objects are transformed (moved, " +"scaled, rotated, or skewed)." +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:506 +msgid "select_toolbar|X" +msgstr "select_toolbar|X" + +#: ../../po/../src/widgets/select-toolbar.cpp:506 +msgid "Horizontal coordinate of selection" +msgstr "Vodorovná souřadnice výběru" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:511 +msgid "select_toolbar|Y" +msgstr "select_toolbar|Y" + +#: ../../po/../src/widgets/select-toolbar.cpp:511 +msgid "Vertical coordinate of selection" +msgstr "Svislá souřadnice výběru" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:517 +msgid "select_toolbar|W" +msgstr "select_toolbar|Å " + +#: ../../po/../src/widgets/select-toolbar.cpp:517 +msgid "Width of selection" +msgstr "Šířka výběru" + +#: ../../po/../src/widgets/select-toolbar.cpp:525 +msgid "Change both width and height by the same proportion" +msgstr "Změnit šířku a výšku ve stejném poměru" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:534 +msgid "select_toolbar|H" +msgstr "select_toolbar|V" + +#: ../../po/../src/widgets/select-toolbar.cpp:534 +msgid "Height of selection" +msgstr "Výška výběru" + +#: ../../po/../src/widgets/sp-color-gtkselector.cpp:62 +msgid "System" +msgstr "Systém" + +#: ../../po/../src/widgets/sp-color-notebook.cpp:322 +msgid "RGBA_:" +msgstr "RGBA_:" + +#: ../../po/../src/widgets/sp-color-notebook.cpp:330 +msgid "Hexadecimal RGBA value of the color" +msgstr "RGBA hodnota barvy v Å¡estnáctkové soustavě" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "RGB" +msgstr "RGB" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "HSL" +msgstr "HSL" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "CMYK" +msgstr "CMYK" + +#: ../../po/../src/widgets/sp-color-scales.cpp:397 +msgid "_R" +msgstr "_R" + +#: ../../po/../src/widgets/sp-color-scales.cpp:398 +#: ../../po/../src/widgets/sp-color-scales.cpp:399 +msgid "Red" +msgstr "Červená" + +#: ../../po/../src/widgets/sp-color-scales.cpp:400 +msgid "_G" +msgstr "_G" + +#: ../../po/../src/widgets/sp-color-scales.cpp:401 +#: ../../po/../src/widgets/sp-color-scales.cpp:402 +msgid "Green" +msgstr "Zelená" + +#: ../../po/../src/widgets/sp-color-scales.cpp:403 +msgid "_B" +msgstr "_B" + +#: ../../po/../src/widgets/sp-color-scales.cpp:404 +#: ../../po/../src/widgets/sp-color-scales.cpp:405 +msgid "Blue" +msgstr "Modrá" + +#. Label +#: ../../po/../src/widgets/sp-color-scales.cpp:406 +#: ../../po/../src/widgets/sp-color-scales.cpp:432 +#: ../../po/../src/widgets/sp-color-scales.cpp:463 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:141 +msgid "_A" +msgstr "_A" + +#: ../../po/../src/widgets/sp-color-scales.cpp:407 +#: ../../po/../src/widgets/sp-color-scales.cpp:408 +#: ../../po/../src/widgets/sp-color-scales.cpp:433 +#: ../../po/../src/widgets/sp-color-scales.cpp:434 +#: ../../po/../src/widgets/sp-color-scales.cpp:464 +#: ../../po/../src/widgets/sp-color-scales.cpp:465 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:151 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:163 +msgid "Alpha (opacity)" +msgstr "Alfa (průsvitnost)" + +#: ../../po/../src/widgets/sp-color-scales.cpp:423 +msgid "_H" +msgstr "_H" + +#: ../../po/../src/widgets/sp-color-scales.cpp:424 +#: ../../po/../src/widgets/sp-color-scales.cpp:425 +msgid "Hue" +msgstr "Odstín" + +#: ../../po/../src/widgets/sp-color-scales.cpp:426 +msgid "_S" +msgstr "_S" + +#: ../../po/../src/widgets/sp-color-scales.cpp:427 +#: ../../po/../src/widgets/sp-color-scales.cpp:428 +msgid "Saturation" +msgstr "Sytost" + +#: ../../po/../src/widgets/sp-color-scales.cpp:429 +msgid "_L" +msgstr "_L" + +#: ../../po/../src/widgets/sp-color-scales.cpp:430 +#: ../../po/../src/widgets/sp-color-scales.cpp:431 +msgid "Lightness" +msgstr "Jas" + +#: ../../po/../src/widgets/sp-color-scales.cpp:451 +msgid "_C" +msgstr "_C" + +#: ../../po/../src/widgets/sp-color-scales.cpp:452 +#: ../../po/../src/widgets/sp-color-scales.cpp:453 +msgid "Cyan" +msgstr "Azurová" + +#: ../../po/../src/widgets/sp-color-scales.cpp:454 +msgid "_M" +msgstr "_M" + +#: ../../po/../src/widgets/sp-color-scales.cpp:455 +#: ../../po/../src/widgets/sp-color-scales.cpp:456 +msgid "Magenta" +msgstr "Růžová" + +#: ../../po/../src/widgets/sp-color-scales.cpp:457 +msgid "_Y" +msgstr "_Y" + +#: ../../po/../src/widgets/sp-color-scales.cpp:458 +#: ../../po/../src/widgets/sp-color-scales.cpp:459 +msgid "Yellow" +msgstr "Žlutá" + +#: ../../po/../src/widgets/sp-color-scales.cpp:460 +msgid "_K" +msgstr "_K" + +#: ../../po/../src/widgets/sp-color-selector.cpp:71 +msgid "Unnamed" +msgstr "Nepojmenovaný" + +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:68 +msgid "Wheel" +msgstr "Barevný kruh" + +#: ../../po/../src/widgets/sp-xmlview-attr-list.cpp:53 +msgid "Attribute" +msgstr "Atribut" + +#: ../../po/../src/widgets/sp-xmlview-attr-list.cpp:54 +msgid "Value" +msgstr "Hodnota" + +#: ../../po/../src/widgets/toolbox.cpp:424 +msgid "Insert new nodes into selected segments" +msgstr "Vložit nové uzly do zvolených segmentů" + +#: ../../po/../src/widgets/toolbox.cpp:426 +msgid "Delete selected nodes" +msgstr "Odstranit vybrané uzly" + +#: ../../po/../src/widgets/toolbox.cpp:431 +msgid "Join paths at selected nodes" +msgstr "Spojit čáry ve vybraných uzlech" + +#: ../../po/../src/widgets/toolbox.cpp:433 +msgid "Join paths at selected nodes with new segment" +msgstr "Spojit čáry ve vybraných uzlech s vytvořením nového segmentu" + +#: ../../po/../src/widgets/toolbox.cpp:436 +msgid "Split path between two non-endpoint nodes" +msgstr "Rozdělit křivku mezi dvěma vnitřními body" + +#: ../../po/../src/widgets/toolbox.cpp:439 +msgid "Break path at selected nodes" +msgstr "Zlomit čáru ve vybraných uzlech" + +#: ../../po/../src/widgets/toolbox.cpp:444 +msgid "Make selected nodes corner" +msgstr "Vytvořit z vybraných uzlů roh" + +#: ../../po/../src/widgets/toolbox.cpp:447 +msgid "Make selected nodes smooth" +msgstr "Učinit vybrané uzly hladké" + +#: ../../po/../src/widgets/toolbox.cpp:450 +msgid "Make selected nodes symmetric" +msgstr "Učinit vybrané uzly symetrické" + +#: ../../po/../src/widgets/toolbox.cpp:455 +msgid "Make selected segments lines" +msgstr "Vytvořit z vybraných segmentů čáru" + +#: ../../po/../src/widgets/toolbox.cpp:458 +msgid "Make selected segments curves" +msgstr "Učinit z vybraných segmentů křivky" + +#: ../../po/../src/widgets/toolbox.cpp:1199 +msgid "Polygon" +msgstr "Mnohoúhelník" + +#: ../../po/../src/widgets/toolbox.cpp:1206 +msgid "Regular polygon (with one handle) instead of a star" +msgstr "Pravidelný mnohoúhelník (s jedním ovl. táhlem) místo hvězdy" + +#: ../../po/../src/widgets/toolbox.cpp:1218 +msgid "Corners:" +msgstr "Rohy:" + +#: ../../po/../src/widgets/toolbox.cpp:1218 +msgid "Number of corners of a polygon or star" +msgstr "Počet rohů mnohoúhelníku nebo hvězdy" + +#: ../../po/../src/widgets/toolbox.cpp:1228 +msgid "Spoke ratio:" +msgstr "Poměr paprsku:" + +#. TRANSLATORS: Tip radius of a star is the distance from the center to the farthest handle. +#. Base radius is the same for the closest handle. +#: ../../po/../src/widgets/toolbox.cpp:1231 +msgid "Base radius to tip radius ratio" +msgstr "Poloměr základny mnohoúhelníku" + +#: ../../po/../src/widgets/toolbox.cpp:1246 +msgid "Rounded:" +msgstr "Zaoblení:" + +#: ../../po/../src/widgets/toolbox.cpp:1246 +msgid "How much rounded are the corners (0 for sharp)" +msgstr "Jak moc jsou rohy zakulaceny (0 znamená ostré rohy)" + +#: ../../po/../src/widgets/toolbox.cpp:1256 +msgid "Randomized:" +msgstr "Náhodné:" + +#: ../../po/../src/widgets/toolbox.cpp:1256 +msgid "Scatter randomly the corners and angles" +msgstr "Náhodně rozptýlit rohy a úhly" + +#: ../../po/../src/widgets/toolbox.cpp:1269 +#: ../../po/../src/widgets/toolbox.cpp:1838 +#: ../../po/../src/widgets/toolbox.cpp:2061 +msgid "Defaults" +msgstr "Výchozí" + +#: ../../po/../src/widgets/toolbox.cpp:1270 +#: ../../po/../src/widgets/toolbox.cpp:1839 +#: ../../po/../src/widgets/toolbox.cpp:2062 +msgid "" +"Reset shape parameters to defaults (use Inkscape Preferences > Tools to " +"change defaults)" +msgstr "" +"Obnovit parametry tvaru na výchozí hodnoty (ke změně výchozích hodnot " +"využijte Nastavení Inkscape > Nástroje)" + +#: ../../po/../src/widgets/toolbox.cpp:1544 +msgid "W:" +msgstr "Å :" + +#: ../../po/../src/widgets/toolbox.cpp:1544 +msgid "Width of rectangle" +msgstr "Šířka obdélníku" + +#: ../../po/../src/widgets/toolbox.cpp:1556 +msgid "Height of rectangle" +msgstr "Výška obdélníku" + +#: ../../po/../src/widgets/toolbox.cpp:1568 +msgid "Rx:" +msgstr "Rx:" + +#: ../../po/../src/widgets/toolbox.cpp:1568 +msgid "Horizontal radius of rounded corners" +msgstr "Vodorovný poloměr zaoblených rohů" + +#: ../../po/../src/widgets/toolbox.cpp:1578 +msgid "Ry:" +msgstr "Ry:" + +#: ../../po/../src/widgets/toolbox.cpp:1578 +msgid "Vertical radius of rounded corners" +msgstr "Svislý poloměr zaoblených rohů" + +#: ../../po/../src/widgets/toolbox.cpp:1594 +msgid "Not rounded" +msgstr "Nezaobleno" + +#: ../../po/../src/widgets/toolbox.cpp:1596 +msgid "Make corners sharp" +msgstr "Udělá rohy ostré" + +#: ../../po/../src/widgets/toolbox.cpp:1805 +msgid "Turns:" +msgstr "Otočky:" + +#: ../../po/../src/widgets/toolbox.cpp:1805 +msgid "Number of revolutions" +msgstr "Počet revolucí" + +#: ../../po/../src/widgets/toolbox.cpp:1815 +msgid "Divergence:" +msgstr "Soustřednost:" + +#: ../../po/../src/widgets/toolbox.cpp:1815 +msgid "How much denser/sparser are outer revolutions; 1 = uniform" +msgstr "Jak moc husté/řídké jsou venkovní obrátky; 1 = rovnoměrné" + +#: ../../po/../src/widgets/toolbox.cpp:1825 +msgid "Inner radius:" +msgstr "Vnitřní poloměr:" + +#: ../../po/../src/widgets/toolbox.cpp:1825 +msgid "Radius of the innermost revolution (relative to the spiral size)" +msgstr "Poloměr nejvnitřnější otočky (relativně k velikosti spirály)" + +#: ../../po/../src/widgets/toolbox.cpp:1957 +msgid "The width of the calligraphic pen (relative to the visible canvas area)" +msgstr "Šířka kaligrafického pera (relativní vůči viditelné oblasti plátna)" + +#: ../../po/../src/widgets/toolbox.cpp:1967 +msgid "Thinning:" +msgstr "Ztenčování:" + +#: ../../po/../src/widgets/toolbox.cpp:1967 +msgid "" +"How much velocity thins the stroke (> 0 makes fast strokes thinner, < 0 " +"makes them broader, 0 makes width independent of velocity)" +msgstr "" +"Jak moc zužuje rychlost šířku čáry (> 0: rychlejší = tenčí čára, < 0: " +"rychlejší = Å¡irší čára, 0 pro šířku nezávislou na rychlosti)" + +#: ../../po/../src/widgets/toolbox.cpp:1980 +msgid "Angle:" +msgstr "Úhel:" + +#: ../../po/../src/widgets/toolbox.cpp:1980 +msgid "" +"The angle of the pen's nib (in degrees; 0 = horizontal; has no effect if " +"fixation = 0)" +msgstr "" +"Úhel hrotu pera (ve stupních; 0 = vodorovné; je bez efektu když je fixace " +"nastavena na 0)" + +#: ../../po/../src/widgets/toolbox.cpp:1990 +msgid "Fixation:" +msgstr "Fixace:" + +#: ../../po/../src/widgets/toolbox.cpp:1990 +msgid "" +"How fixed is the pen angle (0 = always perpendicular to stroke direction, 1 " +"= fixed)" +msgstr "Jak je úhel pera ukončen (0 = vždy kolmo na směr tahu, 1 = fixováno )" + +#: ../../po/../src/widgets/toolbox.cpp:2003 +msgid "Mass:" +msgstr "Hmota:" + +#: ../../po/../src/widgets/toolbox.cpp:2003 +msgid "How much inertia affects the movement of the pen" +msgstr "Jak moc ovlivňuje setrvačnost pohyb pera" + +#. TRANSLATORS: "drag" means "resistance" here +#: ../../po/../src/widgets/toolbox.cpp:2014 +msgid "Drag:" +msgstr "Táhnutí:" + +#: ../../po/../src/widgets/toolbox.cpp:2014 +msgid "How much resistance affects the movement of the pen" +msgstr "Jak velký odpor je kladen pohybu pera" + +#: ../../po/../src/widgets/toolbox.cpp:2034 +msgid "Use the pressure of the input device to alter the width of the pen" +msgstr "Měnit šířku pera dle přítlaku na vstupní zařízení" + +#: ../../po/../src/widgets/toolbox.cpp:2047 +msgid "Use the tilt of the input device to alter the angle of the pen's nib" +msgstr "Měnit úhel hrotu pera dle sklonu vstupního zařízení" + +#: ../../po/../src/widgets/toolbox.cpp:2374 +msgid "Start:" +msgstr "Start:" + +#: ../../po/../src/widgets/toolbox.cpp:2374 +msgid "The angle (in degrees) from the horizontal to the arc's start point" +msgstr "Úhel (ve stupních) od vodorovné linky k prvnímu bodu oblouku" + +#: ../../po/../src/widgets/toolbox.cpp:2384 +msgid "End:" +msgstr "Konec:" + +#: ../../po/../src/widgets/toolbox.cpp:2384 +msgid "The angle (in degrees) from the horizontal to the arc's end point" +msgstr "Úhel (ve stupních) od vodorovné linky k poslednímu bodu oblouku" + +#: ../../po/../src/widgets/toolbox.cpp:2395 +msgid "Open arc" +msgstr "Otevřený oblouk" + +#: ../../po/../src/widgets/toolbox.cpp:2396 +msgid "" +"Switch between arc (unclosed shape) and segment (closed shape with two radii)" +msgstr "Přepnout mezi obloukem (neuzavřený tvar) a výsečí (uzavřený tvar)" + +#: ../../po/../src/widgets/toolbox.cpp:2415 +msgid "Make whole" +msgstr "Udělat celým" + +#: ../../po/../src/widgets/toolbox.cpp:2417 +msgid "Make the shape a whole ellipse, not arc or segment" +msgstr "Udělá z tvaru celou elipsu, ne oblouk nebo výseč" + +#: ../../po/../src/widgets/toolbox.cpp:2644 +msgid "" +"When pressed, picks visible color without alpha and when not pressed, picks " +"color including its alpha" +msgstr "" +"Při stisknutí nabere viditelnou barvu bez alfa průhlednosti. Pokud není " +"stisknuto, nabere barvu včetně alfy" + +#: ../../po/../src/widgets/toolbox.cpp:3039 +msgid "Make connectors avoid selected objects" +msgstr "Přinutit konektory vyhýbat se vybraným objektům" + +#: ../../po/../src/widgets/toolbox.cpp:3043 +msgid "Make connectors ignore selected objects" +msgstr "Přinutit konektory ignorovat vybrané objekty" + +#. +#. 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 : +#: ../share/extensions/addnodes.inx.h:1 +#, fuzzy +msgid "Add Nodes" +msgstr "Uzly" + +#: ../share/extensions/addnodes.inx.h:2 +msgid "Maximum Segment Length" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:1 +msgid "AI Input" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:2 ../share/extensions/ai_output.inx.h:2 +msgid "Adobe Illustrator (*.ai)" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:3 +msgid "Open files saved with Adobe Illustrator" +msgstr "" + +#: ../share/extensions/ai_output.inx.h:1 +#, fuzzy +msgid "AI Output" +msgstr "Výstup" + +#: ../share/extensions/ai_output.inx.h:3 +msgid "Write Adobe Illustrator" +msgstr "" + +#: ../share/extensions/dia.inx.h:1 +msgid "A diagram created with the program Dia" +msgstr "" + +#: ../share/extensions/dia.inx.h:2 +msgid "Dia Diagram (*.dia)" +msgstr "" + +#: ../share/extensions/dia.inx.h:3 +msgid "Dia Input" +msgstr "" + +#: ../share/extensions/dia.inx.h:4 +msgid "" +"In order to import Dia files, Dia itself must be installed. You can get Dia " +"at http://www.gnome.org/projects/dia/" +msgstr "" + +#: ../share/extensions/dia.inx.h:5 +msgid "" +"The dia2svg.sh script should be installed with your Inkscape distribution. " +"If you do not have it, there is likely to be something wrong with your " +"Inkscape installation." +msgstr "" + +#: ../share/extensions/dots.inx.h:1 +#, fuzzy +msgid "Connect the Dots" +msgstr "Konektor" + +#: ../share/extensions/dots.inx.h:2 +#, fuzzy +msgid "Dot Size" +msgstr "Velikost" + +#: ../share/extensions/dots.inx.h:3 +#, fuzzy +msgid "Font Size" +msgstr "Velikost písma:" + +#: ../share/extensions/dropshadow.inx.h:1 +msgid "Color of shadow" +msgstr "" + +#: ../share/extensions/dropshadow.inx.h:2 +#, fuzzy +msgid "Dropshadow" +msgstr "Zobrazit stín stránky" + +#: ../share/extensions/dxf_input.inx.h:1 +#: ../share/extensions/dxf_output.inx.h:1 +msgid "AutoCAD DXF (*.dxf)" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:2 +msgid "DXF Input" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:3 +msgid "Import AutoCAD's Document Exchange Format" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:4 +msgid "" +"dxf2svg may come with Inkscape, but is also at http://dxf-svg-convert." +"sourceforge.net/" +msgstr "" + +#: ../share/extensions/dxf_output.inx.h:2 +#, fuzzy +msgid "DXF Output" +msgstr "Výstup" + +#: ../share/extensions/dxf_output.inx.h:3 +msgid "DXF file written by pstoedit" +msgstr "" + +#: ../share/extensions/dxf_output.inx.h:4 +msgid "pstoedit must be installed to run see http://www.pstoedit.net/pstoedit" +msgstr "" + +#: ../share/extensions/embedimage.inx.h:1 +#, fuzzy +msgid "Embed Images" +msgstr "Obrázky" + +#: ../share/extensions/eps_input.inx.h:1 +msgid "EPS Input" +msgstr "" + +#: ../share/extensions/eps_input.inx.h:2 +msgid "Encapsulated Postscript" +msgstr "" + +#: ../share/extensions/eps_input.inx.h:3 +msgid "Encapsulated Postscript (*.eps)" +msgstr "" + +#: ../share/extensions/epsi_output.inx.h:1 +#, fuzzy +msgid "EPSI Output" +msgstr "Výstup" + +#: ../share/extensions/epsi_output.inx.h:2 +msgid "Encapsulated Postscript Interchange (*.epsi)" +msgstr "" + +#: ../share/extensions/epsi_output.inx.h:3 +msgid "Encapsulated Postscript with a thumbnail" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:1 ../share/extensions/ffms.inx.h:1 +#: ../share/extensions/ffset.inx.h:1 ../share/extensions/ffss.inx.h:1 +#, fuzzy +msgid "Bridge Width" +msgstr "Šířka čáry" + +#: ../share/extensions/ffmet.inx.h:2 ../share/extensions/ffms.inx.h:2 +msgid "First String Length" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:3 +msgid "FretFind Multi Length ET" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:4 ../share/extensions/ffms.inx.h:4 +#: ../share/extensions/ffset.inx.h:3 ../share/extensions/ffss.inx.h:3 +msgid "Fretboard Edges" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:5 ../share/extensions/ffms.inx.h:5 +msgid "Last String Length" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:6 ../share/extensions/ffms.inx.h:6 +#: ../share/extensions/ffset.inx.h:4 ../share/extensions/ffss.inx.h:4 +#, fuzzy +msgid "Number of Frets" +msgstr "Počet řádků" + +#: ../share/extensions/ffmet.inx.h:7 ../share/extensions/ffms.inx.h:7 +#: ../share/extensions/ffset.inx.h:5 ../share/extensions/ffss.inx.h:5 +#, fuzzy +msgid "Number of Strings" +msgstr "Počet řádků" + +#: ../share/extensions/ffmet.inx.h:8 ../share/extensions/ffms.inx.h:8 +#: ../share/extensions/ffset.inx.h:6 ../share/extensions/ffss.inx.h:6 +#, fuzzy +msgid "Nut Width" +msgstr "Šířka" + +#: ../share/extensions/ffmet.inx.h:9 ../share/extensions/ffms.inx.h:10 +msgid "Perpendicular Distance" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:10 ../share/extensions/ffset.inx.h:7 +msgid "Scale Base (2 for Octave)" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:11 ../share/extensions/ffset.inx.h:9 +msgid "Tones in Scale" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:12 ../share/extensions/ffms.inx.h:12 +#: ../share/extensions/ffset.inx.h:10 ../share/extensions/ffss.inx.h:10 +msgid "px per Unit" +msgstr "" + +#: ../share/extensions/ffms.inx.h:3 +msgid "FretFind Multi Length Scala" +msgstr "" + +#: ../share/extensions/ffms.inx.h:9 ../share/extensions/ffss.inx.h:7 +msgid "Path to Scala *.scl File" +msgstr "" + +#: ../share/extensions/ffms.inx.h:11 +msgid "Tuning (scale step for each string seperated by semicolons)" +msgstr "" + +#: ../share/extensions/ffset.inx.h:2 +msgid "FretFind Single Length ET" +msgstr "" + +#: ../share/extensions/ffset.inx.h:8 ../share/extensions/ffss.inx.h:8 +msgid "Scale Length" +msgstr "" + +#: ../share/extensions/ffss.inx.h:2 +msgid "FretFind Single Length Scala" +msgstr "" + +#: ../share/extensions/ffss.inx.h:9 +msgid "Tuning (Scale step for each string seperated by semicolons)" +msgstr "" + +#: ../share/extensions/handles.inx.h:1 +#, fuzzy +msgid "Draw Handles" +msgstr "Kresba od ruky" + +#: ../share/extensions/interp.inx.h:1 +#, fuzzy +msgid "Duplicate Endpaths" +msgstr "Duplikovat uzel" + +#: ../share/extensions/interp.inx.h:2 +#, fuzzy +msgid "Exponent" +msgstr "Export" + +#: ../share/extensions/interp.inx.h:3 +msgid "Interpolate" +msgstr "" + +#: ../share/extensions/interp.inx.h:4 +msgid "Interpolate Style (Experimental)" +msgstr "" + +#: ../share/extensions/interp.inx.h:5 +msgid "Interpolation Method" +msgstr "" + +#: ../share/extensions/interp.inx.h:6 +msgid "Interpolation Steps" +msgstr "" + +#: ../share/extensions/kochify.inx.h:1 +msgid "Kochify" +msgstr "" + +#: ../share/extensions/kochify_load.inx.h:1 +msgid "Kochify (Load)" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:1 +#, fuzzy +msgid "Angle" +msgstr "Úhel:" + +#: ../share/extensions/lindenmayer.inx.h:2 +msgid "Axiom" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:3 +#, fuzzy +msgid "Lindenmayer" +msgstr "Přejmenovat vrstvu" + +#: ../share/extensions/lindenmayer.inx.h:4 +msgid "Order" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:5 +#, fuzzy +msgid "Rules" +msgstr "P_ravítka" + +#: ../share/extensions/lindenmayer.inx.h:6 +#, fuzzy +msgid "Step" +msgstr "Kroky" + +#: ../share/extensions/motion.inx.h:1 +#, fuzzy +msgid "Direction" +msgstr "Popis" + +#: ../share/extensions/motion.inx.h:2 +#, fuzzy +msgid "Magnitude" +msgstr "Růžová" + +#: ../share/extensions/motion.inx.h:3 +#, fuzzy +msgid "Motion" +msgstr "_Rotace" + +#: ../share/extensions/pdf_output.inx.h:1 +msgid "Adobe PDF (*.pdf)" +msgstr "" + +#: ../share/extensions/pdf_output.inx.h:2 +msgid "Adobe Portable Document Format" +msgstr "" + +#: ../share/extensions/pdf_output.inx.h:3 +#, fuzzy +msgid "PDF Output" +msgstr "Výstup" + +#: ../share/extensions/ps_input.inx.h:1 +#, fuzzy +msgid "Postscript" +msgstr "Portrét" + +#: ../share/extensions/ps_input.inx.h:2 +msgid "Postscript (*.ps)" +msgstr "" + +#: ../share/extensions/ps_input.inx.h:3 +msgid "Postscript Input" +msgstr "" + +#: ../share/extensions/radiusrand.inx.h:1 +#, fuzzy +msgid "Radius" +msgstr "Posunout výš" + +#: ../share/extensions/radiusrand.inx.h:2 +#, fuzzy +msgid "Radius Randomize" +msgstr "Nepravidelnost:" + +#: ../share/extensions/radiusrand.inx.h:3 +msgid "Randomize Control Points" +msgstr "" + +#: ../share/extensions/radiusrand.inx.h:4 +#, fuzzy +msgid "Randomize Nodes" +msgstr "Náhodné:" + +#: ../share/extensions/rtree.inx.h:1 +#, fuzzy +msgid "Initial Size" +msgstr "Velikost bitmapy" + +#: ../share/extensions/rtree.inx.h:2 +msgid "Minimum Size" +msgstr "" + +#: ../share/extensions/rtree.inx.h:3 +#, fuzzy +msgid "Random Tree" +msgstr "Nepravidelnost:" + +#: ../share/extensions/sk_input.inx.h:1 +msgid "A diagram created with the program Sketch" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:2 +msgid "Sketch Diagram (*.sk)" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:3 +msgid "Sketch Input" +msgstr "" + +#: ../share/extensions/straightseg.inx.h:1 +msgid "Behavior" +msgstr "" + +#: ../share/extensions/straightseg.inx.h:3 +msgid "Segment Straightener" +msgstr "" + +#: ../share/extensions/summersnight.inx.h:1 +msgid "Summer's Night" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:1 +#: ../share/extensions/svgz_output.inx.h:1 +msgid "Compressed Inkscape SVG (*.svgz)" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:2 +#: ../share/extensions/svgz_output.inx.h:2 +msgid "Inkscape's native file format compressed with GZip" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:3 +msgid "SVGZ Input" +msgstr "" + +#: ../share/extensions/svgz_output.inx.h:3 +#, fuzzy +msgid "SVGZ Output" +msgstr "Výstup" + +#: ../share/extensions/txt2svg.inx.h:1 +msgid "ASCII Text" +msgstr "" + +#: ../share/extensions/txt2svg.inx.h:2 +msgid "Text File (*.txt)" +msgstr "" + +#: ../share/extensions/txt2svg.inx.h:3 +msgid "Text Input" +msgstr "" + +#: ../share/extensions/wavy.inx.h:1 +msgid "Calculate first derivative numerically" +msgstr "" + +#: ../share/extensions/wavy.inx.h:2 +msgid "First derivative" +msgstr "" + +#: ../share/extensions/wavy.inx.h:3 +msgid "Function" +msgstr "" + +#: ../share/extensions/wavy.inx.h:4 +msgid "Function Plotter" +msgstr "" + +#: ../share/extensions/wavy.inx.h:5 +msgid "Nodes per period" +msgstr "" + +#: ../share/extensions/wavy.inx.h:6 +msgid "Periods (2*Pi each)" +msgstr "" + +#: ../share/extensions/whirl.inx.h:1 +msgid "Amount of Whirl" +msgstr "" + +#: ../share/extensions/whirl.inx.h:2 +#, fuzzy +msgid "Center X" +msgstr "Zarovnání na střed" + +#: ../share/extensions/whirl.inx.h:3 +#, fuzzy +msgid "Center Y" +msgstr "Zarovnání na střed" + +#: ../share/extensions/whirl.inx.h:4 +#, fuzzy +msgid "Direction of Rotation" +msgstr "Odmítnout pozvánku" + +#: ../share/extensions/whirl.inx.h:5 +msgid "Whirl" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:1 +msgid "A popular graphics file format for clipart" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:2 +msgid "Windows Metafile (*.wmf)" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:3 +msgid "Windows Metafile Input" +msgstr "" + +#~ msgid "Custom canvas" +#~ msgstr "Vlastní plátno" + +#~ msgid "Current style" +#~ msgstr "Aktuální styl" + +#~ msgid "" +#~ "Current style is updated every time you change the style of any object " +#~ "(its fill, stroke, transparency, etc.)" +#~ msgstr "" +#~ "Aktuální styl je aktualizován pokaždé když změníte styl objektu( jeho " +#~ "výplň, okraje, průhlednost, atd.)" + +#~ msgid "Arrange Objects" +#~ msgstr "Zarovnat objekty" + +#~ msgid "deg" +#~ msgstr "deg" + +#~ msgid "" +#~ "%s is not a valid preferences file.\n" +#~ "%s" +#~ msgstr "" +#~ "%s není skutečný soubor s nastavením.\n" +#~ "%s" + +#~ msgid "" +#~ "Inkscape will run with default settings.\n" +#~ "New settings will not be saved." +#~ msgstr "" +#~ "Inkscape se spustí ve výchozím nastavení\n" +#~ "Nová nastavení nebudou uložena." + +#~ msgid "_Credits" +#~ msgstr "Kredity" + +#~ msgid "Grab sensitivity" +#~ msgstr "Citlivost na výběr" + +#~ msgid "Click/drag threshold" +#~ msgstr "Práh kliknutí/tažení" + +#~ msgid "Mouse wheel scrolls by" +#~ msgstr "Kolečko myÅ¡i posune o" + +#~ msgid "Scroll by" +#~ msgstr "Posun o" + +#~ msgid "Acceleration" +#~ msgstr "Zrychlení" + +#~ msgid "Speed" +#~ msgstr "Rychlost" + +#~ msgid "Threshold" +#~ msgstr "Práh" + +#~ msgid "Arrow keys move by" +#~ msgstr "Å ipky přesunují po" + +#~ msgid "> and < scale by" +#~ msgstr "> a < mění měřítko po" + +#~ msgid "Inset/Outset by" +#~ msgstr "SmrÅ¡tit/Rozšířit o" + +#~ msgid "Rotation snaps every" +#~ msgstr "Přichytávat při otáčení každých" + +#~ msgid "Zoom in/out by" +#~ msgstr "Přiblížit/Oddálit po" + +#~ msgid "Transform" +#~ msgstr "Transformace" + +#~ msgid "Flip selection horizontally" +#~ msgstr "Obrátit vybrané objekty vodorovně" + +#~ msgid "Flip selection vertically" +#~ msgstr "Obrátit vybrané objekty svisle" + +#, fuzzy +#~ msgid "Could not read next message due to I/O error (error: %s)!" +#~ msgstr "Nebylo možné nahrát soubor chyb rozšíření '%s'" + +#~ msgid "Open one of the recently visited documents" +#~ msgstr "Otevřít jeden z posledně zobrazených dokumentů" + +#~ msgid "" +#~ "Show or hide parts of the document window (differently for normal and " +#~ "fullscreen modes)" +#~ msgstr "" +#~ "Ukázat nebo skrýt části okna dokumentu (Jinak než v normálním a " +#~ "celoobrazovkovém módu)" + +#~ msgid "Interactive Inkscape tutorials" +#~ msgstr "Interaktivní návody pro Inkscape" + +#~ msgid "gpl-2.svg" +#~ msgstr "gpl-2.svg" + +#~ msgid "Modifying or Redistributing Inkscape" +#~ msgstr "Úpravy nebo Šíření Inkscape" + +#~ msgid "Show license to modify and/or redistribute Inkscape: GNU GPL" +#~ msgstr "Ukaž licenci na změny a/nebo šíření Inkscape: GNU GPL" + +#, fuzzy +#~ msgid "" +#~ "0 out of %i node selected. Click, Shift+click, or drag around nodes to select.0 out of %i nodes " +#~ "selected. Click, Shift+click, or drag around nodes " +#~ "to select." +#~ msgstr "" +#~ "Žádné objekty nevybrány. Click, Shift+kliknutí, nebo tažením myší kolem " +#~ "objektů je vyberete.Žádné objekty nevybrány. Click, Shift+kliknutí, nebo " +#~ "tažením myší kolem objektů je vyberete." diff --git a/po/da.po b/po/da.po new file mode 100644 index 000000000..e88841c4a --- /dev/null +++ b/po/da.po @@ -0,0 +1,11342 @@ +# Danish translation of sodipodi +# Copyright (C) 2000 Free Software Foundation, Inc. +# Keld Simonsen , 2000-2001. +# Kjartan Maraas , 2000. +# +msgid "" +msgstr "" +"Project-Id-Version: sodipodi\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2005-12-04 11:51-0800\n" +"PO-Revision-Date: 2002-01-15 13:30+0100\n" +"Last-Translator: Keld Simonsen \n" +"Language-Team: Danish \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../inkscape.desktop.in.h:1 +msgid "Create and edit Scalable Vector Graphics images" +msgstr "" + +#: ../inkscape.desktop.in.h:2 +#, fuzzy +msgid "Inkscape SVG Vector Illustrator" +msgstr "Vektor-illustrator" + +#: ../../po/../src/arc-context.cpp:350 +msgid "" +"Ctrl: make circle or integer-ratio ellipse, snap arc/segment angle" +msgstr "" + +#: ../../po/../src/arc-context.cpp:351 ../../po/../src/rect-context.cpp:388 +msgid "Shift: draw around the starting point" +msgstr "" + +#: ../../po/../src/arc-context.cpp:413 +#: ../../po/../src/connector-context.cpp:493 +#: ../../po/../src/dyna-draw-context.cpp:506 +#: ../../po/../src/pen-context.cpp:329 ../../po/../src/pencil-context.cpp:208 +#: ../../po/../src/rect-context.cpp:452 ../../po/../src/spiral-context.cpp:421 +#: ../../po/../src/star-context.cpp:427 +msgid "Current layer is hidden. Unhide it to be able to draw on it." +msgstr "" + +#: ../../po/../src/arc-context.cpp:417 +#: ../../po/../src/connector-context.cpp:497 +#: ../../po/../src/dyna-draw-context.cpp:510 +#: ../../po/../src/pen-context.cpp:336 ../../po/../src/pencil-context.cpp:212 +#: ../../po/../src/rect-context.cpp:456 ../../po/../src/spiral-context.cpp:426 +#: ../../po/../src/star-context.cpp:431 +msgid "Current layer is locked. Unlock it to be able to draw on it." +msgstr "" + +#: ../../po/../src/arc-context.cpp:496 +#, c-format +msgid "" +"Ellipse: %s × %s; with Ctrl to make circle or integer-" +"ratio ellipse; with Shift to draw around the starting point" +msgstr "" + +#: ../../po/../src/connector-context.cpp:518 +#, fuzzy +msgid "Creating new connector" +msgstr "Lagret dokument %d" + +#: ../../po/../src/connector-context.cpp:939 +#, fuzzy +msgid "Finishing connector" +msgstr "FrihÃ¥nd" + +#: ../../po/../src/connector-context.cpp:1108 +msgid "Connection point: click or drag to create a new connector" +msgstr "" + +#: ../../po/../src/connector-context.cpp:1185 +msgid "Connector endpoint: drag to reroute or connect to new shapes" +msgstr "" + +#: ../../po/../src/connector-context.cpp:1278 +#, fuzzy +msgid "Select at least one non-connector object." +msgstr "Vend valgte ting" + +#: ../../po/../src/desktop-events.cpp:238 +#, c-format +msgid "%s at %s" +msgstr "" + +#. TRANSLATORS: This string appears when double-clicking on a guide. +#. This is the distance by which the guide is to be moved. +#: ../../po/../src/desktop-events.cpp:277 +#, fuzzy +msgid " relative by " +msgstr "lodret flytning" + +#. TRANSLATORS: This string appears when double-clicking on a guide. +#. This is the target location where the guide is to be moved. +#: ../../po/../src/desktop-events.cpp:282 +#: ../../po/../src/desktop-events.cpp:395 +#, fuzzy +msgid " absolute to " +msgstr "absolut" + +#. create dialog +#: ../../po/../src/desktop-events.cpp:348 +#, fuzzy +msgid "Guideline" +msgstr "Farver for hjælpelinier" + +#: ../../po/../src/desktop-events.cpp:432 +#, fuzzy, c-format +msgid "Move %s" +msgstr "Flyt" + +#: ../../po/../src/desktop.cpp:678 +msgid "No previous zoom." +msgstr "" + +#: ../../po/../src/desktop.cpp:703 +msgid "No next zoom." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:182 +#, fuzzy +msgid "Nothing selected." +msgstr "Sidste valgt" + +#: ../../po/../src/dialogs/clonetiler.cpp:188 +msgid "More than one object selected." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:195 +#, c-format +msgid "Object has %d tiled clones." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:200 +msgid "Object has no tiled clones." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:865 +#, fuzzy +msgid "Select one object whose tiled clones to unclump." +msgstr "Omform valgte ting til kurver" + +#: ../../po/../src/dialogs/clonetiler.cpp:916 +#, fuzzy +msgid "Select one object whose tiled clones to remove." +msgstr "Omform valgte ting til kurver" + +#: ../../po/../src/dialogs/clonetiler.cpp:984 +#: ../../po/../src/selection-chemistry.cpp:1774 +#, fuzzy +msgid "Select an object to clone." +msgstr "Omform valgte ting til kurver" + +#: ../../po/../src/dialogs/clonetiler.cpp:990 +#: ../../po/../src/selection-chemistry.cpp:1780 +msgid "" +"If you want to clone several objects, group them and clone the " +"group." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1484 +msgid "Per row:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1497 +#, fuzzy +msgid "Per column:" +msgstr "Sidste valgt" + +#: ../../po/../src/dialogs/clonetiler.cpp:1505 +#, fuzzy +msgid "Randomize:" +msgstr "Sidste valgt" + +#: ../../po/../src/dialogs/clonetiler.cpp:1656 +#, fuzzy +msgid "_Symmetry" +msgstr "Symmetrisk" + +#. TRANSLATORS: For the following 17 symmetry groups, see +#. * http://www.bib.ulb.ac.be/coursmath/doc/17.htm (visual examples); +#. * http://www.clarku.edu/~djoyce/wallpaper/seventeen.html (English vocabulary); or +#. * http://membres.lycos.fr/villemingerard/Geometri/Sym1D.htm (French vocabulary). +#. +#: ../../po/../src/dialogs/clonetiler.cpp:1664 +msgid "Select one of the 17 symmetry groups for the tiling" +msgstr "" + +#. TRANSLATORS: "translation" means "shift" / "displacement" here. +#: ../../po/../src/dialogs/clonetiler.cpp:1675 +msgid "P1: simple translation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1676 +msgid "P2: 180° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1677 +msgid "PM: reflection" +msgstr "" + +#. TRANSLATORS: "glide reflection" is a reflection and a translation combined. +#. For more info, see http://mathforum.org/sum95/suzanne/symsusan.html +#: ../../po/../src/dialogs/clonetiler.cpp:1680 +msgid "PG: glide reflection" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1681 +msgid "CM: reflection + glide reflection" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1682 +msgid "PMM: reflection + reflection" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1683 +msgid "PMG: reflection + 180° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1684 +msgid "PGG: glide reflection + 180° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1685 +msgid "CMM: reflection + reflection + 180° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1686 +msgid "P4: 90° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1687 +msgid "P4M: 90° rotation + 45° reflection" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1688 +msgid "P4G: 90° rotation + 90° reflection" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1689 +msgid "P3: 120° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1690 +msgid "P31M: reflection + 120° rotation, dense" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1691 +msgid "P3M1: reflection + 120° rotation, sparse" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1692 +msgid "P6: 60° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1693 +msgid "P6M: reflection + 60° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1721 +msgid "S_hift" +msgstr "" + +#. TRANSLATORS: "shift" means: the tiles will be shifted (offset) horizontally by this amount +#: ../../po/../src/dialogs/clonetiler.cpp:1731 +#, fuzzy, no-c-format +msgid "Shift X:" +msgstr "Ændr" + +#: ../../po/../src/dialogs/clonetiler.cpp:1739 +#, no-c-format +msgid "Horizontal shift per row (in % of tile width)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1747 +#, no-c-format +msgid "Horizontal shift per column (in % of tile width)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1754 +msgid "Randomize the horizontal shift by this percentage" +msgstr "" + +#. TRANSLATORS: "shift" means: the tiles will be shifted (offset) vertically by this amount +#: ../../po/../src/dialogs/clonetiler.cpp:1764 +#, fuzzy, no-c-format +msgid "Shift Y:" +msgstr "Ændr" + +#: ../../po/../src/dialogs/clonetiler.cpp:1772 +#, no-c-format +msgid "Vertical shift per row (in % of tile height)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1780 +#, no-c-format +msgid "Vertical shift per column (in % of tile height)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1787 +msgid "Randomize the vertical shift by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1795 +#, fuzzy +msgid "Exponent:" +msgstr "Ændr" + +#: ../../po/../src/dialogs/clonetiler.cpp:1802 +msgid "Whether rows are spaced evenly (1), converge (<1) or diverge (>1)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1809 +msgid "Whether columns are spaced evenly (1), converge (<1) or diverge (>1)" +msgstr "" + +#. TRANSLATORS: "Alternate" is a verb here +#: ../../po/../src/dialogs/clonetiler.cpp:1817 +#: ../../po/../src/dialogs/clonetiler.cpp:1907 +#: ../../po/../src/dialogs/clonetiler.cpp:1966 +#: ../../po/../src/dialogs/clonetiler.cpp:2022 +#: ../../po/../src/dialogs/clonetiler.cpp:2153 +msgid "Alternate:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1823 +msgid "Alternate the sign of shifts for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1828 +msgid "Alternate the sign of shifts for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1837 +#, fuzzy +msgid "Sc_ale" +msgstr "Skalér" + +#: ../../po/../src/dialogs/clonetiler.cpp:1845 +#, fuzzy +msgid "Scale X:" +msgstr "Ændr" + +#: ../../po/../src/dialogs/clonetiler.cpp:1853 +#, fuzzy, no-c-format +msgid "Horizontal scale per row (in % of tile width)" +msgstr "vandret skalaværdi" + +#: ../../po/../src/dialogs/clonetiler.cpp:1861 +#, fuzzy, no-c-format +msgid "Horizontal scale per column (in % of tile width)" +msgstr "vandret skalaværdi" + +#: ../../po/../src/dialogs/clonetiler.cpp:1868 +msgid "Randomize the horizontal scale by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1876 +#, fuzzy +msgid "Scale Y:" +msgstr "Ændr" + +#: ../../po/../src/dialogs/clonetiler.cpp:1884 +#, fuzzy, no-c-format +msgid "Vertical scale per row (in % of tile height)" +msgstr "lodret skalaværdi" + +#: ../../po/../src/dialogs/clonetiler.cpp:1892 +#, fuzzy, no-c-format +msgid "Vertical scale per column (in % of tile height)" +msgstr "lodret skalaværdi" + +#: ../../po/../src/dialogs/clonetiler.cpp:1899 +msgid "Randomize the vertical scale by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1913 +#, fuzzy +msgid "Alternate the sign of scales for each row" +msgstr "lodret skalaværdi" + +#: ../../po/../src/dialogs/clonetiler.cpp:1918 +#, fuzzy +msgid "Alternate the sign of scales for each column" +msgstr "lodret skalaværdi" + +#: ../../po/../src/dialogs/clonetiler.cpp:1927 +#, fuzzy +msgid "_Rotation" +msgstr "Omdrejning:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1935 +#, fuzzy +msgid "Angle:" +msgstr "Ændr" + +#: ../../po/../src/dialogs/clonetiler.cpp:1943 +#, no-c-format +msgid "Rotate tiles by this angle for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1951 +#, no-c-format +msgid "Rotate tiles by this angle for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1958 +msgid "Randomize the rotation angle by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1972 +msgid "Alternate the rotation direction for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1977 +msgid "Alternate the rotation direction for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1985 +#, fuzzy +msgid "_Opacity" +msgstr "Uigennemskuelighed:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1993 +#, fuzzy +msgid "Fade out:" +msgstr "Ændr" + +#: ../../po/../src/dialogs/clonetiler.cpp:2000 +msgid "Decrease tile opacity by this percentage for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2007 +msgid "Decrease tile opacity by this percentage for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2014 +msgid "Randomize the tile opacity by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2028 +msgid "Alternate the sign of opacity change for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2033 +msgid "Alternate the sign of opacity change for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2041 +#, fuzzy +msgid "Co_lor" +msgstr "Farve:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2046 +#, fuzzy +msgid "Initial color: " +msgstr "Gitterfarve:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2050 +msgid "Initial color of tiled clones" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2050 +msgid "" +"Initial color for clones (works only if the original has unset fill or " +"stroke)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2065 +#, fuzzy +msgid "H:" +msgstr "Ændr" + +#: ../../po/../src/dialogs/clonetiler.cpp:2072 +msgid "Change the tile hue by this percentage for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2079 +msgid "Change the tile hue by this percentage for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2086 +msgid "Randomize the tile hue by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2095 +#, fuzzy +msgid "S:" +msgstr "Ændr" + +#: ../../po/../src/dialogs/clonetiler.cpp:2102 +msgid "Change the color saturation by this percentage for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2109 +msgid "Change the color saturation by this percentage for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2116 +msgid "Randomize the color saturation by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2124 +#, fuzzy +msgid "L:" +msgstr "Ændr" + +#: ../../po/../src/dialogs/clonetiler.cpp:2131 +msgid "Change the color lightness by this percentage for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2138 +msgid "Change the color lightness by this percentage for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2145 +msgid "Randomize the color lightness by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2159 +msgid "Alternate the sign of color changes for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2164 +msgid "Alternate the sign of color changes for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2172 +#, fuzzy +msgid "_Trace" +msgstr "Beskadiget bitmap" + +#: ../../po/../src/dialogs/clonetiler.cpp:2179 +msgid "Trace the drawing under the tiles" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2183 +msgid "" +"For each clone, pick a value from the drawing in that clone's location and " +"apply it to the clone" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2197 +msgid "1. Pick from the drawing:" +msgstr "" + +#. ----Hbox2 +#: ../../po/../src/dialogs/clonetiler.cpp:2208 +#: ../../po/../src/dialogs/clonetiler.cpp:2355 +#: ../../po/../src/ui/dialog/tracedialog.cpp:445 +#, fuzzy +msgid "Color" +msgstr "Farve:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2209 +msgid "Pick the visible color and opacity" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2216 +#: ../../po/../src/dialogs/clonetiler.cpp:2365 +#: ../share/extensions/dropshadow.inx.h:3 +#, fuzzy +msgid "Opacity" +msgstr "Uigennemskuelighed:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2217 +msgid "Pick the total accumulated opacity" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2224 +msgid "R" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2225 +msgid "Pick the Red component of the color" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2232 +msgid "G" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2233 +msgid "Pick the Green component of the color" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2240 +msgid "B" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2241 +msgid "Pick the Blue component of the color" +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2250 +msgid "clonetiler|H" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2251 +#, fuzzy +msgid "Pick the hue of the color" +msgstr "Vælg en farve for streger" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2260 +msgid "clonetiler|S" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2261 +#, fuzzy +msgid "Pick the saturation of the color" +msgstr "Vælg en farve for streger" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2270 +msgid "clonetiler|L" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2271 +msgid "Pick the lightness of the color" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2281 +msgid "2. Tweak the picked value:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2291 +msgid "Gamma-correct:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2296 +msgid "Shift the mid-range of the picked value upwards (>0) or downwards (<0)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2303 +msgid "Randomize:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2308 +msgid "Randomize the picked value by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2315 +#, fuzzy +msgid "Invert:" +msgstr "Nulstil" + +#: ../../po/../src/dialogs/clonetiler.cpp:2319 +msgid "Invert the picked value" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2325 +msgid "3. Apply the value to the clones':" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2335 +#, fuzzy +msgid "Presence" +msgstr "Element er en reference" + +#: ../../po/../src/dialogs/clonetiler.cpp:2338 +msgid "" +"Each clone is created with the probability determined by the picked value in " +"that point" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2345 +#, fuzzy +msgid "Size" +msgstr "Sider:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2348 +msgid "Each clone's size is determined by the picked value in that point" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2358 +msgid "" +"Each clone is painted by the picked color (the original must have unset fill " +"or stroke)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2368 +msgid "Each clone's opacity is determined by the picked value in that point" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2395 +msgid "How many rows in the tiling" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2415 +msgid "How many columns in the tiling" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2445 +msgid "Width of the rectangle to be filled" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2470 +msgid "Height of the rectangle to be filled" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2485 +#, fuzzy +msgid "Rows, columns: " +msgstr "Ændr" + +#: ../../po/../src/dialogs/clonetiler.cpp:2486 +msgid "Create the specified number of rows and columns" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2495 +#, fuzzy +msgid "Width, height: " +msgstr "Højde: " + +#: ../../po/../src/dialogs/clonetiler.cpp:2496 +msgid "Fill the specified width and height with the tiling" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2512 +#, fuzzy +msgid "Use saved size and position of the tile" +msgstr "Position" + +#: ../../po/../src/dialogs/clonetiler.cpp:2515 +msgid "" +"Pretend that the size and position of the tile are the same as the last time " +"you tiled it (if any), instead of using the current size" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2539 +#, fuzzy +msgid " _Create " +msgstr "Ændr" + +#: ../../po/../src/dialogs/clonetiler.cpp:2541 +msgid "Create and tile the clones of the selection" +msgstr "" + +#. TRANSLATORS: if a group of objects are "clumped" together, then they +#. are unevenly spread in the given amount of space - as shown in the +#. diagrams on the left in the following screenshot: +#. http://www.inkscape.org/screenshots/gallery/inkscape-0.42-CVS-tiles-unclump.png +#. So unclumping is the process of spreading a number of objects out more evenly. +#: ../../po/../src/dialogs/clonetiler.cpp:2556 +msgid " _Unclump " +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2557 +msgid "Spread out clones to reduce clumping; can be applied repeatedly" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2563 +#, fuzzy +msgid " Re_move " +msgstr "Fjern lænke" + +#: ../../po/../src/dialogs/clonetiler.cpp:2564 +msgid "Remove existing tiled clones of the selected object (siblings only)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2580 +#, fuzzy +msgid " R_eset " +msgstr "Fjern lænke" + +#. TRANSLATORS: "change" is a noun here +#: ../../po/../src/dialogs/clonetiler.cpp:2582 +msgid "" +"Reset all shifts, scales, rotates, opacity and color changes in the dialog " +"to zero" +msgstr "" + +#: ../../po/../src/dialogs/color-picker.cpp:280 +#, fuzzy +msgid "Close" +msgstr "Luk vindue" + +#: ../../po/../src/dialogs/debugdialog.cpp:138 +msgid "Messages" +msgstr "" + +#. ## Add a menu for clear() +#: ../../po/../src/dialogs/debugdialog.cpp:144 +#: ../../po/../src/menus-skeleton.h:16 +#: ../../po/../src/ui/dialog/messages.cpp:56 +#: ../../po/../src/ui/dialog/scriptdialog.cpp:181 +msgid "_File" +msgstr "_Fil" + +#. TRANSLATORS: "Clear" is a verb here +#: ../../po/../src/dialogs/debugdialog.cpp:145 +#: ../../po/../src/dialogs/find.cpp:753 +#: ../../po/../src/ui/dialog/messages.cpp:57 +#: ../../po/../src/ui/dialog/scriptdialog.cpp:182 +#, fuzzy +msgid "_Clear" +msgstr "Luk vindue" + +#: ../../po/../src/dialogs/debugdialog.cpp:147 +#: ../../po/../src/ui/dialog/messages.cpp:59 +msgid "Capture log messages" +msgstr "" + +#: ../../po/../src/dialogs/debugdialog.cpp:149 +#: ../../po/../src/ui/dialog/messages.cpp:61 +msgid "Release log messages" +msgstr "" + +#. Notebook tab +#: ../../po/../src/dialogs/desktop-properties.cpp:909 +#: ../../po/../src/ui/dialog/document-preferences.cpp:89 +#: ../../po/../src/ui/widget/panel.cpp:107 +msgid "Grid" +msgstr "Gitter" + +#. Checkbuttons +#. / \todo FIXME: gray out snapping when grid is off +#. / \todo FIXME: gray out snapping when grid is off. +#. / Dissenting view: you want snapping without grid. +#: ../../po/../src/dialogs/desktop-properties.cpp:917 +#: ../../po/../src/ui/dialog/document-preferences.cpp:179 +msgid "Show grid" +msgstr "Vis gitter" + +#: ../../po/../src/dialogs/desktop-properties.cpp:917 +#: ../../po/../src/ui/dialog/document-preferences.cpp:179 +#: ../../po/../src/verbs.cpp:2115 +#, fuzzy +msgid "Show or hide grid" +msgstr "Vis gitter" + +#: ../../po/../src/dialogs/desktop-properties.cpp:918 +#: ../../po/../src/ui/dialog/document-preferences.cpp:180 +#, fuzzy +msgid "Snap bounding boxes to grid" +msgstr "Fastsæt til gitter" + +#: ../../po/../src/dialogs/desktop-properties.cpp:918 +#: ../../po/../src/dialogs/desktop-properties.cpp:1001 +#: ../../po/../src/ui/dialog/document-preferences.cpp:181 +#: ../../po/../src/ui/dialog/document-preferences.cpp:236 +msgid "Snap the edges of the object bounding boxes" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:919 +#: ../../po/../src/ui/dialog/document-preferences.cpp:183 +#, fuzzy +msgid "Snap nodes to grid" +msgstr "Fastsæt til gitter" + +#: ../../po/../src/dialogs/desktop-properties.cpp:919 +#: ../../po/../src/dialogs/desktop-properties.cpp:1002 +#: ../../po/../src/ui/dialog/document-preferences.cpp:184 +#: ../../po/../src/ui/dialog/document-preferences.cpp:239 +msgid "Snap path nodes, text baselines, ellipse centers, etc." +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:937 +#: ../../po/../src/ui/dialog/document-preferences.cpp:186 +msgid "Grid units:" +msgstr "Enheder for gitter:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:939 +#: ../../po/../src/ui/dialog/document-preferences.cpp:187 +msgid "Origin X:" +msgstr "Udgangspunkt X:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:942 +#: ../../po/../src/ui/dialog/document-preferences.cpp:189 +msgid "Origin Y:" +msgstr "Udgangspunkt Y:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:945 +#: ../../po/../src/ui/dialog/document-preferences.cpp:191 +msgid "Spacing X:" +msgstr "Afstand X:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:948 +#: ../../po/../src/ui/dialog/document-preferences.cpp:193 +msgid "Spacing Y:" +msgstr "Afstand Y:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:952 +#: ../../po/../src/dialogs/desktop-properties.cpp:1013 +#: ../../po/../src/ui/dialog/document-preferences.cpp:195 +#: ../../po/../src/ui/dialog/document-preferences.cpp:241 +msgid "Snap units:" +msgstr "Fastsætnings enheder:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:955 +#: ../../po/../src/dialogs/desktop-properties.cpp:1016 +#: ../../po/../src/ui/dialog/document-preferences.cpp:196 +#: ../../po/../src/ui/dialog/document-preferences.cpp:242 +msgid "Snap distance:" +msgstr "Fastgørelsesafstand" + +#: ../../po/../src/dialogs/desktop-properties.cpp:958 +#: ../../po/../src/ui/dialog/document-preferences.cpp:199 +#, fuzzy +msgid "Grid line color:" +msgstr "Farver for hjælpelinier" + +#: ../../po/../src/dialogs/desktop-properties.cpp:959 +#: ../../po/../src/ui/dialog/document-preferences.cpp:199 +#, fuzzy +msgid "Grid line color" +msgstr "Farver for hjælpelinier" + +#: ../../po/../src/dialogs/desktop-properties.cpp:959 +#: ../../po/../src/ui/dialog/document-preferences.cpp:200 +#, fuzzy +msgid "Color of grid lines" +msgstr "Vælg farve for hjælpelinjer" + +#: ../../po/../src/dialogs/desktop-properties.cpp:961 +#: ../../po/../src/ui/dialog/document-preferences.cpp:201 +#, fuzzy +msgid "Major grid line color:" +msgstr "Farver for hjælpelinier" + +#: ../../po/../src/dialogs/desktop-properties.cpp:962 +#: ../../po/../src/ui/dialog/document-preferences.cpp:201 +#, fuzzy +msgid "Major grid line color" +msgstr "Farver for hjælpelinier" + +#: ../../po/../src/dialogs/desktop-properties.cpp:962 +#: ../../po/../src/ui/dialog/document-preferences.cpp:202 +#, fuzzy +msgid "Color of the major (highlighted) grid lines" +msgstr "Vælg farve for fremhævede hjælpelinjer" + +#: ../../po/../src/dialogs/desktop-properties.cpp:965 +#: ../../po/../src/ui/dialog/document-preferences.cpp:204 +#, fuzzy +msgid "Major grid line every:" +msgstr "Farver for hjælpelinier" + +#. TRANSLATORS: This belongs to the "Major grid line every:" string, +#. see grid settings in the "Document Preferences" dialog +#: ../../po/../src/dialogs/desktop-properties.cpp:977 +#: ../../po/../src/ui/dialog/document-preferences.cpp:204 +#, fuzzy +msgid "lines" +msgstr "Luk vindue" + +#. Guidelines page +#: ../../po/../src/dialogs/desktop-properties.cpp:991 +#: ../../po/../src/ui/dialog/document-preferences.cpp:90 +msgid "Guides" +msgstr "Hjælpelinjer" + +#. / \todo FIXME: gray out snapping when guides are off +#. / Dissenting view: you want snapping without guides. +#: ../../po/../src/dialogs/desktop-properties.cpp:1000 +#: ../../po/../src/ui/dialog/document-preferences.cpp:234 +msgid "Show guides" +msgstr "Vis hjælpelinier" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1000 +#: ../../po/../src/ui/dialog/document-preferences.cpp:234 +#: ../../po/../src/verbs.cpp:2116 +#, fuzzy +msgid "Show or hide guides" +msgstr "Vis hjælpelinier" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1001 +#: ../../po/../src/ui/dialog/document-preferences.cpp:235 +#, fuzzy +msgid "Snap bounding boxes to guides" +msgstr "Fastsæt til hjælpelinier" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1002 +#: ../../po/../src/ui/dialog/document-preferences.cpp:238 +#, fuzzy +msgid "Snap points to guides" +msgstr "Fastsæt til gitter" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1020 +#: ../../po/../src/ui/dialog/document-preferences.cpp:243 +#, fuzzy +msgid "Guide color:" +msgstr "Farve for hjælpelinjer:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1021 +#: ../../po/../src/ui/dialog/document-preferences.cpp:243 +msgid "Guideline color" +msgstr "Farver for hjælpelinier" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1021 +#: ../../po/../src/ui/dialog/document-preferences.cpp:244 +#, fuzzy +msgid "Color of guidelines" +msgstr "Vælg farve for hjælpelinjer" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1023 +#: ../../po/../src/ui/dialog/document-preferences.cpp:245 +msgid "Highlight color:" +msgstr "Farve for fremhævning:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1024 +#: ../../po/../src/ui/dialog/document-preferences.cpp:245 +#, fuzzy +msgid "Highlighted guideline color" +msgstr "Farve for fremhævede hjælpelinjer" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1024 +#: ../../po/../src/ui/dialog/document-preferences.cpp:246 +msgid "Color of a guideline when it is under mouse" +msgstr "" + +#. Page page +#: ../../po/../src/dialogs/desktop-properties.cpp:1029 +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:855 +#: ../../po/../src/ui/dialog/document-preferences.cpp:88 +#: ../../po/../src/widgets/desktop-widget.cpp:1061 +msgid "Page" +msgstr "Side" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1039 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +#, fuzzy +msgid "Background:" +msgstr "Slutfarve" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1040 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +#, fuzzy +msgid "Background color" +msgstr "Slutfarve" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1041 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +msgid "" +"Color and transparency of the page background (also used for bitmap export)" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1045 +#: ../../po/../src/ui/dialog/document-preferences.cpp:147 +#, fuzzy +msgid "Show page border" +msgstr "Vis gitter" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1049 +#: ../../po/../src/ui/dialog/document-preferences.cpp:148 +#, fuzzy +msgid "Border on top of drawing" +msgstr "Zoom til tegning" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1052 +#: ../../po/../src/ui/dialog/document-preferences.cpp:149 +#, fuzzy +msgid "Border color:" +msgstr "Gitterfarve:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1053 +#: ../../po/../src/ui/dialog/document-preferences.cpp:149 +#, fuzzy +msgid "Page border color" +msgstr "Gitterfarve:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1054 +#: ../../po/../src/ui/dialog/document-preferences.cpp:150 +#, fuzzy +msgid "Color of the page border" +msgstr "Vis gitter" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1059 +#: ../../po/../src/ui/dialog/document-preferences.cpp:152 +msgid "Show page shadow" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1063 +#: ../../po/../src/ui/dialog/document-preferences.cpp:153 +#, fuzzy +msgid "Default units:" +msgstr "Slet" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1069 +msgid "Units for the tool controls, ruler, and the statusbar" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1086 +#: ../../po/../src/ui/widget/page-sizer.cpp:209 +#, fuzzy +msgid "Page size:" +msgstr "Papirstørrelse:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1110 +#: ../../po/../src/ui/widget/page-sizer.cpp:219 +msgid "Custom" +msgstr "Tilpas" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1121 +#: ../../po/../src/ui/widget/page-sizer.cpp:225 +#, fuzzy +msgid "Page orientation:" +msgstr "Mætning:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1133 +#: ../../po/../src/ui/widget/page-sizer.cpp:232 +#, fuzzy +msgid "Landscape" +msgstr "Sodipodi: %s: %s: %d" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1139 +#: ../../po/../src/ui/widget/page-sizer.cpp:234 +#, fuzzy +msgid "Portrait" +msgstr "Punkt" + +#. Custom paper frame +#: ../../po/../src/dialogs/desktop-properties.cpp:1148 +#: ../../po/../src/ui/widget/page-sizer.cpp:249 +#, fuzzy +msgid "Custom size" +msgstr "Tilpas" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1160 +#: ../../po/../src/dialogs/export.cpp:269 +#: ../../po/../src/ui/widget/page-sizer.cpp:261 +msgid "Units:" +msgstr "Enheder:" + +#. Stroke width +#: ../../po/../src/dialogs/desktop-properties.cpp:1162 +#: ../../po/../src/dialogs/export.cpp:310 +#: ../../po/../src/dialogs/object-attributes.cpp:55 +#: ../../po/../src/dialogs/stroke-style.cpp:985 +#: ../../po/../src/ui/widget/page-sizer.cpp:262 +#: ../../po/../src/widgets/toolbox.cpp:1957 +msgid "Width:" +msgstr "Bredde:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1183 +#: ../../po/../src/dialogs/export.cpp:326 +#: ../../po/../src/dialogs/export.cpp:431 +#: ../../po/../src/dialogs/object-attributes.cpp:56 +#: ../../po/../src/ui/widget/page-sizer.cpp:263 +msgid "Height:" +msgstr "Højde:" + +#. +#. * Ownership metadata tab +#. +#: ../../po/../src/dialogs/desktop-properties.cpp:1206 +msgid "Metadata" +msgstr "" + +#. add license selector pull-down +#: ../../po/../src/dialogs/desktop-properties.cpp:1225 +#, fuzzy +msgid "License" +msgstr "tommer" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1255 +msgid "Proprietary" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:212 +#, fuzzy +msgid "When transforming, show:" +msgstr "Nulstil transformation" + +#: ../../po/../src/dialogs/display-settings.cpp:223 +#, fuzzy +msgid "Objects" +msgstr "Ting" + +#: ../../po/../src/dialogs/display-settings.cpp:224 +msgid "Show the actual objects when moving or transforming" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:231 +#, fuzzy +msgid "Box outline" +msgstr "Vis hjælpelinier" + +#: ../../po/../src/dialogs/display-settings.cpp:232 +msgid "Show only a box outline of the objects when moving or transforming" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:238 +#, fuzzy +msgid "Per-object selection cue:" +msgstr "Omform valgte ting til kurver" + +#. sorationsnapsperpi == 0 means no snapping +#: ../../po/../src/dialogs/display-settings.cpp:249 +#: ../../po/../src/dialogs/display-settings.cpp:386 +#: ../../po/../src/dialogs/display-settings.cpp:441 +#: ../../po/../src/dialogs/display-settings.cpp:1482 +#: ../../po/../src/dialogs/stroke-style.cpp:791 +#: ../../po/../src/interface.cpp:741 +#: ../../po/../src/ui/widget/selected-style.cpp:100 +#: ../../po/../src/verbs.cpp:1842 +msgid "None" +msgstr "Ingen" + +#: ../../po/../src/dialogs/display-settings.cpp:250 +msgid "No per-object selection indication" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:256 +msgid "Mark" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:257 +msgid "Each selected object has a diamond mark in the top left corner" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:264 +msgid "Box" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:265 +msgid "Each selected object displays its bounding box" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:270 +msgid "Default scale origin:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:281 +#, fuzzy +msgid "Opposite bounding box edge" +msgstr "Fastsæt til gitter" + +#: ../../po/../src/dialogs/display-settings.cpp:282 +msgid "Default scale origin will be on the bounding box of the item" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:288 +msgid "Farthest opposite node" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:289 +msgid "Default scale origin will be on the bounding box of the item's points" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:341 +#, fuzzy +msgid "degrees" +msgstr "grad" + +#: ../../po/../src/dialogs/display-settings.cpp:350 +msgid "" +"Rotating with Ctrl pressed snaps every that much degrees; also, pressing " +"[ or ] rotates by this amount" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:407 +msgid "Rotation snaps every:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:430 +msgid "" +"None: dialogs are treated as regular windows; Normal: dialogs stay on top of " +"document windows; Aggressive: same as Normal but may work better with some " +"window managers." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:451 +msgid "Normal" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:461 +msgid "Aggressive" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:475 +msgid "Dialogs on top:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:645 +#, fuzzy +msgid "Show selection cue" +msgstr "Omform valgte ting til kurver" + +#: ../../po/../src/dialogs/display-settings.cpp:646 +msgid "" +"Whether selected objects display a selection cue (the same as in selector)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:657 +#, fuzzy +msgid "Enable gradient editing" +msgstr "Gradientvektor" + +#: ../../po/../src/dialogs/display-settings.cpp:658 +msgid "Whether selected objects display gradient editing controls" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:719 +#, fuzzy +msgid "No objects selected to take the style from." +msgstr "Omform valgte ting til kurver" + +#: ../../po/../src/dialogs/display-settings.cpp:728 +msgid "" +"More than one object selected. Cannot take style from multiple " +"objects." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:767 +#, fuzzy +msgid "Create new objects with:" +msgstr "Tilføj attribut" + +#: ../../po/../src/dialogs/display-settings.cpp:777 +#, fuzzy +msgid "Take from selection" +msgstr "Omform valg" + +#: ../../po/../src/dialogs/display-settings.cpp:778 +msgid "Remember the style of the (first) selected object as this tool's style" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:782 +#, fuzzy +msgid "Last used style" +msgstr "Bredde pÃ¥ strøg" + +#: ../../po/../src/dialogs/display-settings.cpp:782 +msgid "Apply the style you last set on an object" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:790 +msgid "This tool's own style:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:790 +msgid "" +"Each tool may store its own style to apply to the newly created objects. Use " +"the button below to set it." +msgstr "" + +#. Mouse +#: ../../po/../src/dialogs/display-settings.cpp:877 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:55 +#, fuzzy +msgid "Mouse" +msgstr "Flyt" + +#. TRANSLATORS: "Grab" is a noun here. "Grab sensitivity" is intended to mean how +#. * close on the screen you need to be to an object to be able to grab it with mouse (in +#. * pixels). +#: ../../po/../src/dialogs/display-settings.cpp:883 +#, fuzzy +msgid "Grab sensitivity:" +msgstr "Gør følsom" + +#: ../../po/../src/dialogs/display-settings.cpp:884 +msgid "" +"How close on the screen you need to be to an object to be able to grab it " +"with mouse (in screen pixels)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:885 +#: ../../po/../src/dialogs/display-settings.cpp:897 +#: ../../po/../src/dialogs/display-settings.cpp:912 +#: ../../po/../src/dialogs/display-settings.cpp:930 +#: ../../po/../src/dialogs/display-settings.cpp:970 +msgid "pixels" +msgstr "piksler" + +#: ../../po/../src/dialogs/display-settings.cpp:895 +msgid "Click/drag threshold:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:896 +msgid "" +"Maximum mouse drag (in screen pixels) which is considered a click, not a drag" +msgstr "" + +#. Scrolling +#: ../../po/../src/dialogs/display-settings.cpp:907 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:56 +msgid "Scrolling" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:910 +msgid "Mouse wheel scrolls by:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:911 +msgid "" +"One mouse wheel notch scrolls by this distance in screen pixels " +"(horizontally with Shift)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:920 +msgid "Ctrl+arrows" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:928 +msgid "Scroll by:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:929 +msgid "Pressing Ctrl+arrow key scrolls by this distance (in screen pixels)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:939 +#, fuzzy +msgid "Acceleration:" +msgstr "Valg" + +#: ../../po/../src/dialogs/display-settings.cpp:940 +msgid "" +"Pressing and holding Ctrl+arrow will gradually speed up scrolling (0 for no " +"acceleration)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:949 +msgid "Autoscrolling" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:957 +#, fuzzy +msgid "Speed:" +msgstr "Rød:" + +#: ../../po/../src/dialogs/display-settings.cpp:958 +msgid "" +"How fast the canvas autoscrolls when you drag beyond canvas edge (0 to turn " +"autoscroll off)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:968 +#: ../../po/../src/ui/dialog/tracedialog.cpp:357 +#: ../../po/../src/ui/dialog/tracedialog.cpp:390 +msgid "Threshold:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:969 +msgid "" +"How far (in screen pixels) you need to be from the canvas edge to trigger " +"autoscroll; positive is outside the canvas, negative is within the canvas" +msgstr "" + +#. Steps +#: ../../po/../src/dialogs/display-settings.cpp:979 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:57 +#, fuzzy +msgid "Steps" +msgstr " Stíl " + +#: ../../po/../src/dialogs/display-settings.cpp:982 +msgid "Arrow keys move by:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:983 +msgid "" +"Pressing an arrow key moves selected object(s) or node(s) by this distance " +"(in px units)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:984 +#: ../../po/../src/dialogs/display-settings.cpp:995 +#: ../../po/../src/dialogs/display-settings.cpp:1006 +#: ../../po/../src/helper/units.cpp:42 +msgid "px" +msgstr "px" + +#: ../../po/../src/dialogs/display-settings.cpp:993 +msgid "> and < scale by:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:994 +msgid "" +"Pressing > or < scales selection up or down by this increment (in px units)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1004 +msgid "Inset/Outset by:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1005 +msgid "" +"Inset and Outset commands displace the path by this distance (in px units)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1017 +msgid "Compass-like display of angles" +msgstr "" + +#. TRANSLATORS: "positive clockwise" means "increasing in clockwise direction" +#: ../../po/../src/dialogs/display-settings.cpp:1019 +msgid "" +"When on, angles are displayed with 0 at north, 0 to 360 range, positive " +"clockwise; otherwise with 0 at east, -180 to 180 range, positive " +"counterclockwise" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1026 +#, fuzzy +msgid "Zoom in/out by:" +msgstr "Zoom ud" + +#: ../../po/../src/dialogs/display-settings.cpp:1027 +msgid "" +"Zoom tool click, +/- keys, and middle click zoom in and out by this " +"multiplier" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1028 +#: ../../po/../src/helper/units.cpp:44 +msgid "%" +msgstr "%" + +#. Tools +#: ../../po/../src/dialogs/display-settings.cpp:1037 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:58 +msgid "Tools" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1045 +#, fuzzy +msgid "Selector" +msgstr "Vælg" + +#: ../../po/../src/dialogs/display-settings.cpp:1056 +msgid "Node" +msgstr "Node" + +#: ../../po/../src/dialogs/display-settings.cpp:1064 +#: ../../po/../src/verbs.cpp:2073 +#: ../../po/../src/widgets/desktop-widget.cpp:277 +msgid "Zoom" +msgstr "Zoom" + +#. The 4 shape tools +#: ../../po/../src/dialogs/display-settings.cpp:1071 +#, fuzzy +msgid "Shapes" +msgstr "Form" + +#: ../../po/../src/dialogs/display-settings.cpp:1079 +#: ../../po/../src/verbs.cpp:2055 +msgid "Rectangle" +msgstr "Firkant" + +#: ../../po/../src/dialogs/display-settings.cpp:1085 +#: ../../po/../src/verbs.cpp:2057 +msgid "Ellipse" +msgstr "Elipse" + +#: ../../po/../src/dialogs/display-settings.cpp:1091 +#: ../../po/../src/verbs.cpp:2059 +msgid "Star" +msgstr "Stjerne" + +#: ../../po/../src/dialogs/display-settings.cpp:1097 +#: ../../po/../src/verbs.cpp:2061 +msgid "Spiral" +msgstr "Spiral" + +#: ../../po/../src/dialogs/display-settings.cpp:1111 +#: ../../po/../src/verbs.cpp:2063 +msgid "Pencil" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1114 +msgid "Tolerance:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1115 +msgid "" +"This value affects the amount of smoothing applied to freehand lines; lower " +"values produce more uneven paths with more nodes" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1131 +#: ../../po/../src/verbs.cpp:2065 +#, fuzzy +msgid "Pen" +msgstr "Procent" + +#: ../../po/../src/dialogs/display-settings.cpp:1140 +#: ../../po/../src/verbs.cpp:2067 +msgid "Calligraphy" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1147 +#: ../../po/../src/dialogs/text-edit.cpp:353 +#: ../../po/../src/ui/dialog/text-properties.cpp:37 +#: ../../po/../src/verbs.cpp:2069 +msgid "Text" +msgstr "Tekst" + +#: ../../po/../src/dialogs/display-settings.cpp:1157 +#: ../../po/../src/verbs.cpp:2071 +#, fuzzy +msgid "Gradient" +msgstr "Gradient fyld" + +#: ../../po/../src/dialogs/display-settings.cpp:1164 +#: ../../po/../src/verbs.cpp:2077 +#, fuzzy +msgid "Connector" +msgstr "Luk vindue" + +#: ../../po/../src/dialogs/display-settings.cpp:1171 +#: ../../po/../src/verbs.cpp:2075 +msgid "Dropper" +msgstr "" + +#. Windows +#: ../../po/../src/dialogs/display-settings.cpp:1183 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:59 +msgid "Windows" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1188 +#, fuzzy +msgid "Save window geometry" +msgstr "Lagret dokument %d" + +#: ../../po/../src/dialogs/display-settings.cpp:1189 +msgid "" +"Save the window size and position with each document (only for Inkscape SVG " +"format)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1196 +msgid "Dialogs are hidden in taskbar" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1197 +msgid "Whether dialog windows are to be hidden in the window manager taskbar" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1204 +msgid "Zoom when window is resized" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1205 +msgid "" +"Zoom drawing when document window is resized, to keep the same area visible " +"(this is the default which can be changed in any window using the button " +"above the right scrollbar)" +msgstr "" + +#. Clones +#: ../../po/../src/dialogs/display-settings.cpp:1213 +#: ../../po/../src/dialogs/find.cpp:624 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:60 +#, fuzzy +msgid "Clones" +msgstr "Luk vindue" + +#: ../../po/../src/dialogs/display-settings.cpp:1217 +msgid "When the original moves, its clones and linked offsets:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1229 +msgid "Move in parallel" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1230 +msgid "Clones are translated by the same vector as their original." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1237 +msgid "Stay unmoved" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1238 +msgid "Clones preserve their positions when their original is moved." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1245 +msgid "Move according to transform" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1246 +msgid "" +"Each clone moves according to the value of its transform= attribute. For " +"example, a rotated clone will move in a different direction than its " +"original." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1255 +msgid "When the original is deleted, its clones:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1267 +msgid "Are unlinked" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1267 +msgid "Orphaned clones are converted to regular objects." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1273 +#, fuzzy +msgid "Are deleted" +msgstr "Første valgt" + +#: ../../po/../src/dialogs/display-settings.cpp:1273 +msgid "Orphaned clones are deleted along with their original." +msgstr "" + +#. Transforms +#. TRANSLATORS: Noun, i.e. transformations. +#: ../../po/../src/dialogs/display-settings.cpp:1289 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:61 +#, fuzzy +msgid "Transforms" +msgstr "Transformation" + +#: ../../po/../src/dialogs/display-settings.cpp:1292 +#, fuzzy +msgid "Scale stroke width" +msgstr "Bredde pÃ¥ strøg" + +#: ../../po/../src/dialogs/display-settings.cpp:1293 +#: ../../po/../src/widgets/select-toolbar.cpp:568 +msgid "When scaling objects, scale the stroke width by the same proportion" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1300 +msgid "Scale rounded corners in rectangles" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1301 +#: ../../po/../src/widgets/select-toolbar.cpp:580 +msgid "When scaling rectangles, scale the radii of rounded corners" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1308 +#, fuzzy +msgid "Transform gradients" +msgstr "Transformation" + +#: ../../po/../src/dialogs/display-settings.cpp:1309 +#: ../../po/../src/widgets/select-toolbar.cpp:592 +msgid "Transform gradients (in fill or stroke) along with the objects" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1316 +#, fuzzy +msgid "Transform patterns" +msgstr "Transformation" + +#: ../../po/../src/dialogs/display-settings.cpp:1317 +#: ../../po/../src/widgets/select-toolbar.cpp:604 +msgid "Transform patterns (in fill or stroke) along with the objects" +msgstr "" + +#. TRANSLATORS: How to specify the affine transformation in the SVG file. +#: ../../po/../src/dialogs/display-settings.cpp:1327 +#, fuzzy +msgid "Store transformation:" +msgstr "Nulstil transformation" + +#: ../../po/../src/dialogs/display-settings.cpp:1338 +msgid "Optimized" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1339 +msgid "" +"If possible, apply transformation to objects without adding a transform= " +"attribute" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1346 +msgid "Preserved" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1347 +msgid "Always store transformation as a transform= attribute on objects" +msgstr "" + +#. Selecting +#: ../../po/../src/dialogs/display-settings.cpp:1355 +#, fuzzy +msgid "Selecting" +msgstr "Valg" + +#: ../../po/../src/dialogs/display-settings.cpp:1357 +msgid "Ctrl+A, Tab, Shift+Tab:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1366 +#, fuzzy +msgid "Select only within current layer" +msgstr "Vælg" + +#: ../../po/../src/dialogs/display-settings.cpp:1367 +msgid "" +"Uncheck this to make keyboard selection commands work on objects in all " +"layers" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1374 +msgid "Ignore hidden objects" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1375 +msgid "" +"Uncheck this to be able to select objects that are hidden (either by " +"themselves or by being in a hidden group or layer)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1382 +#, fuzzy +msgid "Ignore locked objects" +msgstr "Vend valgte ting" + +#: ../../po/../src/dialogs/display-settings.cpp:1383 +msgid "" +"Uncheck this to be able to select objects that are locked (either by " +"themselves or by being in a locked group or layer)" +msgstr "" + +#. To be broken into: Display, Save, Export, SVG, Commands +#: ../../po/../src/dialogs/display-settings.cpp:1391 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:62 +msgid "Misc" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1394 +msgid "Default export resolution:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1395 +msgid "Default bitmap resolution (in dots per inch) in the Export dialog" +msgstr "" + +#. FIXME: add "Used for new exports; once exported, documents remember this value on per-object basis" when implemented +#: ../../po/../src/dialogs/display-settings.cpp:1396 +#: ../../po/../src/dialogs/export.cpp:442 +msgid "dpi" +msgstr "dpi" + +#. TRANSLATORS: When on, an imported bitmap creates an element; otherwise it is a +#. * rectangle with bitmap fill. +#: ../../po/../src/dialogs/display-settings.cpp:1407 +msgid "Import bitmap as " +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1408 +msgid "" +"When on, an imported bitmap creates an element; otherwise it is a " +"rectangle with bitmap fill" +msgstr "" + +#. TRANSLATORS: When on, the print out (currently Postscript) will have +#. * a comment with the each object's label visible, marking the section +#. * of the printing commands that represent the given object. +#: ../../po/../src/dialogs/display-settings.cpp:1418 +msgid "Add label comments to printing output" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1419 +msgid "" +"When on, a comment will be added to the raw print output, marking the " +"rendered output for an object with its label" +msgstr "" + +#. TRANSLATORS: When on, enable the effects menu, default is off +#: ../../po/../src/dialogs/display-settings.cpp:1427 +msgid "Enable script effects (requires restart) - EXPERIMENTAL" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1428 +msgid "" +"When on, the effects menu is enabled, allowing external effect scripts to be " +"called, requires restart before effective - EXPERIMENTAL" +msgstr "" + +#. TRANSLATORS: The maximum length of the Open Recent list in the File menu. +#: ../../po/../src/dialogs/display-settings.cpp:1436 +#, fuzzy +msgid "Max recent documents:" +msgstr "Unavngivet dokument %d" + +#: ../../po/../src/dialogs/display-settings.cpp:1437 +msgid "The maximum length of the Open Recent list in the File menu" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1447 +msgid "Simplification threshold:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1448 +msgid "" +"How strong is the Simplify command by default. If you invoke this command " +"several times in quick succession, it will act more and more aggressively; " +"invoking it again after a pause restores the default threshold." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1469 +msgid "Oversample bitmaps:" +msgstr "Flere tilfælde af bitmap:" + +#: ../../po/../src/dialogs/display-settings.cpp:1488 +msgid "2x2" +msgstr "2x2" + +#: ../../po/../src/dialogs/display-settings.cpp:1494 +msgid "4x4" +msgstr "4x4" + +#: ../../po/../src/dialogs/display-settings.cpp:1500 +msgid "8x8" +msgstr "8x8" + +#: ../../po/../src/dialogs/display-settings.cpp:1506 +msgid "16x16" +msgstr "16x16" + +#. "view_icon_preview" +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2143 +msgid "_Page" +msgstr "_Side" + +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2147 +msgid "_Drawing" +msgstr "_Tegning" + +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2149 +msgid "_Selection" +msgstr "_Udvalg" + +#: ../../po/../src/dialogs/export.cpp:133 +#, fuzzy +msgid "_Custom" +msgstr "Tilpas" + +#: ../../po/../src/dialogs/export.cpp:254 +#, fuzzy +msgid "Export area" +msgstr "Eksporteret som" + +#: ../../po/../src/dialogs/export.cpp:300 +#, fuzzy +msgid "_x0:" +msgstr "T0:" + +#: ../../po/../src/dialogs/export.cpp:305 +#, fuzzy +msgid "x_1:" +msgstr "R1:" + +#: ../../po/../src/dialogs/export.cpp:316 +#, fuzzy +msgid "_y0:" +msgstr "T0:" + +#: ../../po/../src/dialogs/export.cpp:321 +#, fuzzy +msgid "y_1:" +msgstr "R1:" + +#: ../../po/../src/dialogs/export.cpp:406 +#, fuzzy +msgid "Bitmap size" +msgstr "Billedstørrelse" + +#: ../../po/../src/dialogs/export.cpp:416 +#, fuzzy +msgid "_Width:" +msgstr "Bredde:" + +#: ../../po/../src/dialogs/export.cpp:416 +#: ../../po/../src/dialogs/export.cpp:431 +#, fuzzy +msgid "pixels at" +msgstr "piksler" + +#: ../../po/../src/dialogs/export.cpp:426 +#, fuzzy +msgid "dp_i" +msgstr "dpi" + +#: ../../po/../src/dialogs/export.cpp:448 +#, fuzzy +msgid "_Filename" +msgstr "Filnavn:" + +#: ../../po/../src/dialogs/export.cpp:512 +msgid "_Browse..." +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:539 +#, fuzzy +msgid " _Export " +msgstr "Ændr" + +#: ../../po/../src/dialogs/export.cpp:541 +msgid "Export the bitmap file with these settings" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:968 +#, fuzzy +msgid "You have to enter a filename" +msgstr "Gem tegning under nyt filnavn" + +#: ../../po/../src/dialogs/export.cpp:973 +msgid "The chosen area to be exported is invalid" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:982 +#, c-format +msgid "Directory %s does not exist or is not a directory.\n" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:998 +#, fuzzy +msgid "Export in progress" +msgstr "Eksporteret som" + +#: ../../po/../src/dialogs/export.cpp:1004 +#, c-format +msgid "Exporting %s (%d x %d)" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:1031 +#, c-format +msgid "Could not export to filename %s.\n" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:1137 +#, fuzzy +msgid "Select a filename for exporting" +msgstr "Vælg fil der skal importeres" + +#: ../../po/../src/dialogs/filedialog.cpp:367 +#, fuzzy +msgid "No preview" +msgstr "Nyt smugkig" + +#: ../../po/../src/dialogs/filedialog.cpp:468 +msgid "too large for preview" +msgstr "" + +#: ../../po/../src/dialogs/filedialog.cpp:762 +#: ../../po/../src/dialogs/filedialog.cpp:763 +#, fuzzy +msgid "All Images" +msgstr "Billede" + +#: ../../po/../src/dialogs/filedialog.cpp:767 +#: ../../po/../src/dialogs/filedialog.cpp:768 +#, fuzzy +msgid "All Files" +msgstr "Stíl for fyld" + +#: ../../po/../src/dialogs/filedialog.cpp:774 +#: ../../po/../src/dialogs/filedialog.cpp:775 +#, fuzzy +msgid "All Inkscape Files" +msgstr "Sodipodi: %s: %s: %d" + +#: ../../po/../src/dialogs/filedialog.cpp:1176 +#, fuzzy +msgid "Guess from extension" +msgstr "Omform valg" + +#. ###### Add the file types menu +#. createFilterMenu(); +#. ###### Do we want the .xxx extension automatically added? +#: ../../po/../src/dialogs/filedialog.cpp:1261 +msgid "Append filename extension automatically" +msgstr "" + +#. TRANSLATORS: "%s" is replaced with "exact" or "partial" when this string is displayed +#: ../../po/../src/dialogs/find.cpp:378 +#, fuzzy, c-format +msgid "%d object found (out of %d), %s match." +msgid_plural "%d objects found (out of %d), %s match." +msgstr[0] "Udjævn linje ved valgte knuder" +msgstr[1] "Udjævn linje ved valgte knuder" + +#: ../../po/../src/dialogs/find.cpp:381 +#, fuzzy +msgid "exact" +msgstr "Tekst" + +#: ../../po/../src/dialogs/find.cpp:381 +#, fuzzy +msgid "partial" +msgstr "Spiral" + +#: ../../po/../src/dialogs/find.cpp:388 +#, fuzzy +msgid "No objects found" +msgstr "Tekstobjekt" + +#: ../../po/../src/dialogs/find.cpp:546 +#, fuzzy +msgid "T_ype: " +msgstr "Type:" + +#: ../../po/../src/dialogs/find.cpp:553 +msgid "Search in all object types" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:553 +#, fuzzy +msgid "All types" +msgstr "Stíl for fyld" + +#: ../../po/../src/dialogs/find.cpp:564 +msgid "Search all shapes" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:564 +msgid "All shapes" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:581 +#, fuzzy +msgid "Search rectangles" +msgstr "Firkant" + +#: ../../po/../src/dialogs/find.cpp:581 +#, fuzzy +msgid "Rectangles" +msgstr "Firkant" + +#: ../../po/../src/dialogs/find.cpp:586 +msgid "Search ellipses, arcs, circles" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:586 +#, fuzzy +msgid "Ellipses" +msgstr "Elipse" + +#: ../../po/../src/dialogs/find.cpp:591 +msgid "Search stars and polygons" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:591 +#, fuzzy +msgid "Stars" +msgstr "Stjerne" + +#: ../../po/../src/dialogs/find.cpp:596 +#, fuzzy +msgid "Search spirals" +msgstr "Tegn spiral" + +#: ../../po/../src/dialogs/find.cpp:596 +#, fuzzy +msgid "Spirals" +msgstr "Spiral" + +#. TRANSLATORS: polyline is a set of connected straight line segments +#. http://www.w3.org/TR/SVG11/shapes.html#PolylineElement +#: ../../po/../src/dialogs/find.cpp:609 +msgid "Search paths, lines, polylines" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:609 +msgid "Paths" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:614 +#, fuzzy +msgid "Search text objects" +msgstr "Vend valgte ting" + +#: ../../po/../src/dialogs/find.cpp:614 +#, fuzzy +msgid "Texts" +msgstr "Tekst" + +#: ../../po/../src/dialogs/find.cpp:619 +msgid "Search groups" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:619 +#, fuzzy +msgid "Groups" +msgstr "Gruppér" + +#: ../../po/../src/dialogs/find.cpp:624 +msgid "Search clones" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:629 +msgid "Search images" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:629 +#, fuzzy +msgid "Images" +msgstr "Billede" + +#: ../../po/../src/dialogs/find.cpp:634 +#, fuzzy +msgid "Search offset objects" +msgstr "Vend valgte ting" + +#: ../../po/../src/dialogs/find.cpp:634 +msgid "Offsets" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:694 +#, fuzzy +msgid "_Text: " +msgstr "Tekst" + +#: ../../po/../src/dialogs/find.cpp:694 +msgid "Find objects by their text content (exact or partial match)" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:695 +msgid "_ID: " +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:695 +msgid "Find objects by the value of the id attribute (exact or partial match)" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:696 +#, fuzzy +msgid "_Style: " +msgstr " Stíl " + +#: ../../po/../src/dialogs/find.cpp:696 +msgid "" +"Find objects by the value of the style attribute (exact or partial match)" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:697 +#, fuzzy +msgid "_Attribute: " +msgstr "Attribut:" + +#: ../../po/../src/dialogs/find.cpp:697 +msgid "Find objects by the name of an attribute (exact or partial match)" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:711 +#, fuzzy +msgid "Search in s_election" +msgstr "Zoom til valg" + +#: ../../po/../src/dialogs/find.cpp:715 +msgid "Limit search to the current selection" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:720 +#, fuzzy +msgid "Search in current _layer" +msgstr "Vælg" + +#: ../../po/../src/dialogs/find.cpp:724 +#, fuzzy +msgid "Limit search to the current layer" +msgstr "Vælg" + +#: ../../po/../src/dialogs/find.cpp:729 +msgid "Include _hidden" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:733 +msgid "Include hidden objects in search" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:738 +msgid "Include l_ocked" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:742 +#, fuzzy +msgid "Include locked objects in search" +msgstr "Vend valgte ting" + +#: ../../po/../src/dialogs/find.cpp:753 +#, fuzzy +msgid "Clear values" +msgstr "Farvefyld" + +#: ../../po/../src/dialogs/find.cpp:754 +#, fuzzy +msgid "_Find" +msgstr "Gitter" + +#: ../../po/../src/dialogs/find.cpp:754 +msgid "Select objects matching all of the fields you filled in" +msgstr "" + +#: ../../po/../src/dialogs/iconpreview.cpp:145 +#, c-format +msgid "%d x %d" +msgstr "" + +#: ../../po/../src/dialogs/iconpreview.cpp:193 +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:857 +#: ../../po/../src/widgets/desktop-widget.cpp:1069 +msgid "Selection" +msgstr "Valg" + +#: ../../po/../src/dialogs/iconpreview.cpp:195 +#, fuzzy +msgid "Selection only or whole document" +msgstr "Vælg" + +#: ../../po/../src/dialogs/iconpreview.cpp:203 +msgid "Refresh the icons" +msgstr "" + +#. Create the label for the object id +#: ../../po/../src/dialogs/item-properties.cpp:126 +#: ../../po/../src/dialogs/item-properties.cpp:327 +#: ../../po/../src/dialogs/item-properties.cpp:396 +#: ../../po/../src/dialogs/item-properties.cpp:403 +msgid "_Id" +msgstr "" + +#: ../../po/../src/dialogs/item-properties.cpp:135 +msgid "" +"The id= attribute (only letters, digits, and the characters .-_: allowed)" +msgstr "" + +#. Button for setting the object's id, label, title and description. +#: ../../po/../src/dialogs/item-properties.cpp:149 +#, fuzzy +msgid "_Set" +msgstr "Vælg" + +#. Create the label for the object label +#: ../../po/../src/dialogs/item-properties.cpp:158 +#, fuzzy +msgid "_Label" +msgstr "Slet attribut" + +#: ../../po/../src/dialogs/item-properties.cpp:167 +msgid "A freeform label for the object" +msgstr "" + +#. Create the label for the object title +#: ../../po/../src/dialogs/item-properties.cpp:179 +#: ../../po/../src/dialogs/rdf.cpp:243 +#, fuzzy +msgid "Title" +msgstr "Titel:" + +#. Create the frame for the object description +#: ../../po/../src/dialogs/item-properties.cpp:196 +#: ../../po/../src/dialogs/rdf.cpp:287 +#, fuzzy +msgid "Description" +msgstr "Position" + +#. Hide +#: ../../po/../src/dialogs/item-properties.cpp:223 +#, fuzzy +msgid "_Hide" +msgstr "Sider:" + +#: ../../po/../src/dialogs/item-properties.cpp:224 +msgid "Check to make the object invisible" +msgstr "" + +#. Lock +#. TRANSLATORS: "Lock" is a verb here +#: ../../po/../src/dialogs/item-properties.cpp:233 +msgid "L_ock" +msgstr "" + +#: ../../po/../src/dialogs/item-properties.cpp:234 +msgid "Check to make the object insensitive (not selectable by mouse)" +msgstr "" + +#: ../../po/../src/dialogs/item-properties.cpp:310 +#: ../../po/../src/dialogs/item-properties.cpp:317 +msgid "Ref" +msgstr "" + +#: ../../po/../src/dialogs/item-properties.cpp:398 +#, fuzzy +msgid "Id invalid! " +msgstr "ID er gyldig" + +#: ../../po/../src/dialogs/item-properties.cpp:400 +msgid "Id exists! " +msgstr "" + +#: ../../po/../src/dialogs/layer-properties.cpp:50 +msgid "Layer name:" +msgstr "" + +#: ../../po/../src/dialogs/layer-properties.cpp:133 +#, fuzzy +msgid "Rename Layer" +msgstr "Radius:" + +#: ../../po/../src/dialogs/layer-properties.cpp:136 +#, fuzzy +msgid "_Rename" +msgstr "Filnavn:" + +#. TRANSLATORS: This means "The layer has been renamed" +#: ../../po/../src/dialogs/layer-properties.cpp:147 +#, fuzzy +msgid "Renamed layer" +msgstr "Radius:" + +#: ../../po/../src/dialogs/layer-properties.cpp:151 +#, fuzzy +msgid "Add Layer" +msgstr "Vælg" + +#: ../../po/../src/dialogs/layer-properties.cpp:153 +#, fuzzy +msgid "_Add" +msgstr "Tilføj" + +#: ../../po/../src/dialogs/layer-properties.cpp:167 +msgid "New layer created." +msgstr "" + +#: ../../po/../src/dialogs/object-attributes.cpp:34 +msgid "Href:" +msgstr "Href:" + +#: ../../po/../src/dialogs/object-attributes.cpp:35 +msgid "Target:" +msgstr "MÃ¥l:" + +#: ../../po/../src/dialogs/object-attributes.cpp:36 +msgid "Type:" +msgstr "Type:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkRoleAttribute +#. Identifies the type of the related resource with an absolute URI +#: ../../po/../src/dialogs/object-attributes.cpp:39 +msgid "Role:" +msgstr "Rolle:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkArcRoleAttribute +#. For situations where the nature/role alone isn't enough, this offers an additional URI defining the purpose of the link. +#: ../../po/../src/dialogs/object-attributes.cpp:42 +msgid "Arcrole:" +msgstr "Ærkerolle:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkTitleAttribute +#: ../../po/../src/dialogs/object-attributes.cpp:44 +msgid "Title:" +msgstr "Titel:" + +#: ../../po/../src/dialogs/object-attributes.cpp:45 +msgid "Show:" +msgstr "Vis:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkActuateAttribute +#: ../../po/../src/dialogs/object-attributes.cpp:47 +msgid "Actuate:" +msgstr "Igangsæt:" + +#: ../../po/../src/dialogs/object-attributes.cpp:52 +msgid "URL:" +msgstr "URL:" + +#: ../../po/../src/dialogs/object-attributes.cpp:53 +msgid "X:" +msgstr "X:" + +#: ../../po/../src/dialogs/object-attributes.cpp:54 +msgid "Y:" +msgstr "Y:" + +#: ../../po/../src/dialogs/object-attributes.cpp:98 +#, c-format +msgid "%s attributes" +msgstr "%s attributter" + +#: ../../po/../src/dialogs/object-properties.cpp:158 +#, fuzzy +msgid "_Fill" +msgstr "Fyld" + +#: ../../po/../src/dialogs/object-properties.cpp:165 +#, fuzzy +msgid "Stroke _paint" +msgstr "Bredde pÃ¥ strøg" + +#: ../../po/../src/dialogs/object-properties.cpp:172 +#, fuzzy +msgid "Stroke st_yle" +msgstr "Skrivebordets indstilinger" + +#: ../../po/../src/dialogs/object-properties.cpp:183 +#, fuzzy +msgid "Master _opacity" +msgstr "Uigennemskuelighed:" + +#: ../../po/../src/dialogs/rdf.cpp:244 +msgid "Name by which this document is formally known." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:246 +#, fuzzy +msgid "Date" +msgstr "Tegn tekst" + +#: ../../po/../src/dialogs/rdf.cpp:247 +msgid "Date associated with the creation of this document (YYYY-MM-DD)." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:249 +msgid "Format" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:250 +msgid "The physical or digital manifestation of this document (MIME type)." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:252 +#, fuzzy +msgid "Type" +msgstr "Type:" + +#: ../../po/../src/dialogs/rdf.cpp:253 +msgid "Type of document (DCMI Type)." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:256 +#, fuzzy +msgid "Creator" +msgstr "Opret lænke" + +#: ../../po/../src/dialogs/rdf.cpp:257 +msgid "" +"Name of entity primarily responsible for making the content of this document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:259 +#, fuzzy +msgid "Rights" +msgstr "Højde" + +#: ../../po/../src/dialogs/rdf.cpp:260 +msgid "" +"Name of entity with rights to the Intellectual Property of this document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:262 +msgid "Publisher" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:263 +msgid "Name of entity responsible for making this document available." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:266 +#, fuzzy +msgid "Identifier" +msgstr "Centrér" + +#: ../../po/../src/dialogs/rdf.cpp:267 +msgid "Unique URI to reference this document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:269 +msgid "Source" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:270 +msgid "Unique URI to reference the source of this document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:272 +#, fuzzy +msgid "Relation" +msgstr "Omdrejning:" + +#: ../../po/../src/dialogs/rdf.cpp:273 +#, fuzzy +msgid "Unique URI to a related document." +msgstr "Unavngivet dokument %d" + +#: ../../po/../src/dialogs/rdf.cpp:275 +#, fuzzy +msgid "Language" +msgstr "vinkel" + +#: ../../po/../src/dialogs/rdf.cpp:276 +msgid "" +"Two-letter language tag with optional subtags for the language of this " +"document. (e.g. 'en-GB')" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:278 +msgid "Keywords" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:279 +msgid "" +"The topic of this document as comma-separated key words, phrases, or " +"classifications." +msgstr "" + +#. TRANSLATORS: "Coverage": the spatial or temporal characteristics of the content. +#. For info, see Appendix D of http://www.w3.org/TR/1998/WD-rdf-schema-19980409/ +#: ../../po/../src/dialogs/rdf.cpp:283 +msgid "Coverage" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:284 +msgid "Extent or scope of this document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:288 +msgid "A short account of the content of this document." +msgstr "" + +#. FIXME: need to handle 1 agent per line of input +#: ../../po/../src/dialogs/rdf.cpp:292 +#, fuzzy +msgid "Contributors" +msgstr "Centimeter" + +#: ../../po/../src/dialogs/rdf.cpp:293 +msgid "" +"Names of entities responsible for making contributions to the content of " +"this document." +msgstr "" + +#. TRANSLATORS: URL to a page that defines the license for the document +#: ../../po/../src/dialogs/rdf.cpp:297 +msgid "URI" +msgstr "" + +#. TRANSLATORS: this is where you put a URL to a page that defines the license +#: ../../po/../src/dialogs/rdf.cpp:299 +msgid "URI to this document's license's namespace definition." +msgstr "" + +#. TRANSLATORS: fragment of XML representing the license of the document +#: ../../po/../src/dialogs/rdf.cpp:303 +#, fuzzy +msgid "Fragment" +msgstr "Argument:" + +#: ../../po/../src/dialogs/rdf.cpp:304 +msgid "XML fragment for the RDF 'License' section." +msgstr "" + +#: ../../po/../src/dialogs/stroke-style.cpp:774 +#: ../../po/../src/widgets/gradient-vector.cpp:263 +#: ../../po/../src/widgets/paint-selector.cpp:751 +#, fuzzy +msgid "No document selected" +msgstr "Lagret dokument %d" + +#: ../../po/../src/dialogs/stroke-style.cpp:992 +#, fuzzy +msgid "Stroke width" +msgstr "Bredde pÃ¥ strøg" + +#. Join type +#. TRANSLATORS: The line join style specifies the shape to be used at the +#. corners of paths. It can be "miter", "round" or "bevel". +#: ../../po/../src/dialogs/stroke-style.cpp:1015 +msgid "Join:" +msgstr "Sammenlæg:" + +#. TRANSLATORS: Miter join: joining lines with a sharp (pointed) corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1027 +#, fuzzy +msgid "Miter join" +msgstr "Mitter sammenlægning" + +#. TRANSLATORS: Round join: joining lines with a rounded corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1035 +msgid "Round join" +msgstr "Rund sammenlægning" + +#. TRANSLATORS: Bevel join: joining lines with a blunted (flattened) corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1043 +msgid "Bevel join" +msgstr "Kantet sammenlægning" + +#. Miterlimit +#. TRANSLATORS: Miter limit: only for "miter join", this limits the length +#. of the sharp "spike" when the lines connect at too sharp an angle. +#. When two line segments meet at a sharp angle, a miter join results in a +#. spike that extends well beyond the connection point. The purpose of the +#. miter limit is to cut off such spikes (i.e. convert them into bevels) +#. when they become too long. +#: ../../po/../src/dialogs/stroke-style.cpp:1054 +#, fuzzy +msgid "Miter limit:" +msgstr "Mitter sammenlægning" + +#: ../../po/../src/dialogs/stroke-style.cpp:1062 +msgid "Maximum length of the miter (in units of stroke width)" +msgstr "" + +#. Cap type +#. TRANSLATORS: cap type specifies the shape for the ends of lines +#: ../../po/../src/dialogs/stroke-style.cpp:1075 +#, fuzzy +msgid "Cap:" +msgstr "Cyan:" + +#. TRANSLATORS: Butt cap: the line shape does not extend beyond the end point +#. of the line; the ends of the line are square +#: ../../po/../src/dialogs/stroke-style.cpp:1086 +msgid "Butt cap" +msgstr "" + +#. TRANSLATORS: Round cap: the line shape extends beyond the end point of the +#. line; the ends of the line are rounded +#: ../../po/../src/dialogs/stroke-style.cpp:1093 +#, fuzzy +msgid "Round cap" +msgstr "Rund sammenlægning" + +#. TRANSLATORS: Square cap: the line shape extends beyond the end point of the +#. line; the ends of the line are square +#: ../../po/../src/dialogs/stroke-style.cpp:1100 +#, fuzzy +msgid "Square cap" +msgstr "Kantede endepunkter" + +#. Dash +#: ../../po/../src/dialogs/stroke-style.cpp:1106 +msgid "Dashes:" +msgstr "" + +#. TRANSLATORS: Path markers are an SVG feature that allows you to attach arbitrary shapes +#. (arrowheads, bullets, faces, whatever) to the start, end, or middle nodes of a path. +#: ../../po/../src/dialogs/stroke-style.cpp:1127 +#, fuzzy +msgid "Start Markers:" +msgstr "Egenskaber for stjerne" + +#: ../../po/../src/dialogs/stroke-style.cpp:1137 +msgid "Mid Markers:" +msgstr "" + +#: ../../po/../src/dialogs/stroke-style.cpp:1148 +msgid "End Markers:" +msgstr "" + +#: ../../po/../src/dialogs/swatches.cpp:424 +#, c-format +msgid "Palettes directory (%s) is unavailable." +msgstr "" + +#. TODO: Insert widgets +#: ../../po/../src/dialogs/text-edit.cpp:199 +#: ../../po/../src/ui/dialog/text-properties.cpp:36 +#, fuzzy +msgid "Font" +msgstr "Punkt" + +#: ../../po/../src/dialogs/text-edit.cpp:216 +msgid "Layout" +msgstr "Udformning" + +#: ../../po/../src/dialogs/text-edit.cpp:229 +#, fuzzy +msgid "Align lines left" +msgstr "Justér til øverst til venstre" + +#. TRANSLATORS: `Center' here is a verb. +#: ../../po/../src/dialogs/text-edit.cpp:243 +#, fuzzy +msgid "Center lines" +msgstr "Centrér Y:" + +#: ../../po/../src/dialogs/text-edit.cpp:256 +#, fuzzy +msgid "Align lines right" +msgstr "Justér til øverst til højre" + +#: ../../po/../src/dialogs/text-edit.cpp:278 +#, fuzzy +msgid "Horizontal text" +msgstr "vandret flytning" + +#: ../../po/../src/dialogs/text-edit.cpp:292 +#, fuzzy +msgid "Vertical text" +msgstr "Lodret centreringsværdi" + +#: ../../po/../src/dialogs/text-edit.cpp:307 +#, fuzzy +msgid "Line spacing:" +msgstr "Afstand X:" + +#: ../../po/../src/dialogs/text-edit.cpp:400 +msgid "Set as default" +msgstr "" + +#: ../../po/../src/dialogs/tiledialog.cpp:603 +#, fuzzy +msgid "Rows:" +msgstr "Vis:" + +#: ../../po/../src/dialogs/tiledialog.cpp:613 +msgid "Number of rows" +msgstr "" + +#: ../../po/../src/dialogs/tiledialog.cpp:617 +#, fuzzy +msgid "Equal height" +msgstr "Højde: " + +#: ../../po/../src/dialogs/tiledialog.cpp:627 +msgid "If not set, each row has the height of the tallest object in it" +msgstr "" + +#. #### Radio buttons to control vertical alignment #### +#. #### Radio buttons to control horizontal alignment #### +#: ../../po/../src/dialogs/tiledialog.cpp:637 +#: ../../po/../src/dialogs/tiledialog.cpp:708 +#, fuzzy +msgid "Align:" +msgstr "Justér" + +#: ../../po/../src/dialogs/tiledialog.cpp:672 +#, fuzzy +msgid " X " +msgstr "X +" + +#. #### Number of columns #### +#: ../../po/../src/dialogs/tiledialog.cpp:678 +#, fuzzy +msgid "Columns:" +msgstr "Ændr" + +#: ../../po/../src/dialogs/tiledialog.cpp:688 +msgid "Number of columns" +msgstr "" + +#: ../../po/../src/dialogs/tiledialog.cpp:692 +#, fuzzy +msgid "Equal width" +msgstr "Bredde:" + +#: ../../po/../src/dialogs/tiledialog.cpp:701 +msgid "If not set, each column has the width of the widest object in it" +msgstr "" + +#. #### Radio buttons to control spacing manually or to fit selection bbox #### +#: ../../po/../src/dialogs/tiledialog.cpp:746 +#, fuzzy +msgid "Fit into selection box" +msgstr "Klip det markerede" + +#: ../../po/../src/dialogs/tiledialog.cpp:753 +#, fuzzy +msgid "Set spacing:" +msgstr "Afstand Y:" + +#. #### Y Padding #### +#: ../../po/../src/dialogs/tiledialog.cpp:777 +#, fuzzy +msgid "Row spacing: " +msgstr "Afstand X:" + +#: ../../po/../src/dialogs/tiledialog.cpp:786 +#, fuzzy +msgid "Vertical spacing between rows" +msgstr "Lodret centreringsværdi" + +#. #### X padding #### +#: ../../po/../src/dialogs/tiledialog.cpp:795 +#, fuzzy +msgid "Column spacing:" +msgstr "Afstand X:" + +#: ../../po/../src/dialogs/tiledialog.cpp:804 +#, fuzzy +msgid "Horizontal spacing between columns" +msgstr "vandret skalaværdi" + +#: ../../po/../src/dialogs/tiledialog.cpp:818 +#, fuzzy +msgid "Arrange selected objects" +msgstr "Gruppér valgte ting" + +#: ../../po/../src/dialogs/xml-tree.cpp:178 +msgid "Click to select nodes, drag to rearrange." +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:189 +msgid "Click attribute to edit." +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:193 +#, c-format +msgid "" +"Attribute %s selected. Press Ctrl+Enter when done editing to " +"commit changes." +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:284 +msgid "Drag to reorder nodes" +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:304 +#, fuzzy +msgid "New element node" +msgstr "Lagret dokument %d" + +#: ../../po/../src/dialogs/xml-tree.cpp:326 +msgid "New text node" +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:347 +#, fuzzy +msgid "Duplicate node" +msgstr "Duplikér" + +#: ../../po/../src/dialogs/xml-tree.cpp:368 +#, fuzzy +msgid "Delete node" +msgstr "Slet" + +#: ../../po/../src/dialogs/xml-tree.cpp:384 +#, fuzzy +msgid "Unindent node" +msgstr "Redigér noder" + +#: ../../po/../src/dialogs/xml-tree.cpp:399 +#, fuzzy +msgid "Indent node" +msgstr "Redigér noder" + +#: ../../po/../src/dialogs/xml-tree.cpp:411 +#, fuzzy +msgid "Raise node" +msgstr "Radius:" + +#: ../../po/../src/dialogs/xml-tree.cpp:423 +msgid "Lower node" +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:468 +msgid "Delete attribute" +msgstr "Slet attribut" + +#. TRANSLATORS: "Attribute" is a noun here +#: ../../po/../src/dialogs/xml-tree.cpp:513 +#, fuzzy +msgid "Attribute name" +msgstr "Attribut:" + +#. TRANSLATORS: "Set" is a verb here +#: ../../po/../src/dialogs/xml-tree.cpp:533 +#, fuzzy +msgid "Set attribute" +msgstr "Slet attribut" + +#. TRANSLATORS: "Set" is a verb here +#: ../../po/../src/dialogs/xml-tree.cpp:535 +#, fuzzy +msgid "Set" +msgstr "Vælg" + +#. TRANSLATORS: "Attribute" is a noun here +#: ../../po/../src/dialogs/xml-tree.cpp:558 +#, fuzzy +msgid "Attribute value" +msgstr "Attributter" + +#: ../../po/../src/dialogs/xml-tree.cpp:1318 +msgid "New element node..." +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:1339 +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:100 +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:98 +#, fuzzy +msgid "Cancel" +msgstr "Ændr" + +#: ../../po/../src/dialogs/xml-tree.cpp:1345 +#, fuzzy +msgid "Create" +msgstr "Opret lænke" + +#: ../../po/../src/dialogs/xml-tree.cpp:1458 +#, c-format +msgid "" +"Cannot set %s: Another element with value %s already exists!" +msgstr "" + +#: ../../po/../src/document.cpp:369 +#, fuzzy, c-format +msgid "New document %d" +msgstr "Lagret dokument %d" + +#: ../../po/../src/document.cpp:401 +#, c-format +msgid "Memory document %d" +msgstr "Lagret dokument %d" + +#: ../../po/../src/document.cpp:524 +#, c-format +msgid "Unnamed document %d" +msgstr "Unavngivet dokument %d" + +#. We hit green anchor, closing Green-Blue-Red +#: ../../po/../src/draw-context.cpp:441 +msgid "Path is closed." +msgstr "" + +#. We hit bot start and end of single curve, closing paths +#: ../../po/../src/draw-context.cpp:456 +msgid "Closing path." +msgstr "" + +#. alpha of color under cursor, to show in the statusbar +#. locale-sensitive printf is OK, since this goes to the UI, not into SVG +#: ../../po/../src/dropper-context.cpp:354 +#, c-format +msgid " alpha %.3g" +msgstr "" + +#. where the color is picked, to show in the statusbar +#: ../../po/../src/dropper-context.cpp:356 +#, c-format +msgid ", averaged with radius %d" +msgstr "" + +#: ../../po/../src/dropper-context.cpp:356 +msgid " under cursor" +msgstr "" + +#. message, to show in the statusbar +#: ../../po/../src/dropper-context.cpp:358 +msgid "Release mouse to set color." +msgstr "" + +#: ../../po/../src/dropper-context.cpp:358 +#: ../../po/../src/tools-switch.cpp:207 +msgid "" +"Click to set fill, Shift+click to set stroke; drag to " +"average color in area; with Alt to pick inverse color; Ctrl+C " +"to copy the color under mouse to clipboard" +msgstr "" + +#: ../../po/../src/extension/dependency.cpp:244 +msgid "Dependency::" +msgstr "" + +#: ../../po/../src/extension/dependency.cpp:245 +#, fuzzy +msgid " type: " +msgstr "Stíl for fyld" + +#: ../../po/../src/extension/dependency.cpp:246 +#, fuzzy +msgid " location: " +msgstr "Omdrejning:" + +#: ../../po/../src/extension/dependency.cpp:247 +msgid " string: " +msgstr "" + +#: ../../po/../src/extension/dependency.cpp:250 +#, fuzzy +msgid " description: " +msgstr "Position" + +#. static int i = 0; +#. std::cout << "Checking module[" << i++ << "]: " << name << std::endl; +#: ../../po/../src/extension/extension.cpp:244 +msgid "" +" This is caused by an improper .inx file for this extension. An improper ." +"inx file could have been caused by a faulty installation of Inkscape." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:247 +msgid "an ID was not defined for it." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:251 +msgid "there was no name defined for it." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:255 +msgid "the XML description of it got lost." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:259 +msgid "no implementation was defined for the extension." +msgstr "" + +#. std::cout << "Failed: " << *(_deps[i]) << std::endl; +#: ../../po/../src/extension/extension.cpp:266 +msgid "a dependency was not met." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:286 +#, fuzzy +msgid "Extension \"" +msgstr "Ekspansion:" + +#: ../../po/../src/extension/extension.cpp:286 +msgid "\" failed to load because " +msgstr "" + +#: ../../po/../src/extension/extension.cpp:565 +#, c-format +msgid "Could not create extension error log file '%s'" +msgstr "" + +#. This is some filler text, needs to change before relase +#: ../../po/../src/extension/error-file.cpp:56 +msgid "" +"One or more extensions failed to load\n" +"\n" +"The failed extensions have been skipped. Inkscape will continue to run " +"normally but those extensions will be unavailable. For details to " +"troubleshoot this problem, please refer to the error log located at: " +msgstr "" + +#. This is some filler text, needs to change before relase +#: ../../po/../src/extension/error-file.cpp:65 +msgid "Show dialog on startup" +msgstr "" + +#: ../../po/../src/extension/implementation/script.cpp:845 +msgid "" +"Inkscape has received an error from the script that it called. The text " +"returned with the error is included below. Inkscape will continue working, " +"but the action you requested has been cancelled." +msgstr "" + +#: ../../po/../src/extension/implementation/script.cpp:858 +msgid "" +"Inkscape has received additional data from the script executed. The script " +"did not return an error, but this may indicate the results will not be as " +"expected." +msgstr "" + +#: ../../po/../src/extension/init.cpp:173 +msgid "Null external module directory name. Modules will not be loaded." +msgstr "" + +#: ../../po/../src/extension/init.cpp:187 +#, c-format +msgid "" +"Modules directory (%s) is unavailable. External modules in that directory " +"will not be loaded." +msgstr "" + +#: ../../po/../src/extension/internal/gnome.cpp:80 +#, fuzzy +msgid "Select printer" +msgstr "Valg" + +#: ../../po/../src/extension/internal/gnome.cpp:131 +#, fuzzy +msgid "Inkscape: Print Preview" +msgstr "Sodipodi (dokumentnavn %s..): Udskriv forhÃ¥ndsvisning" + +#: ../../po/../src/extension/internal/grid.cpp:213 +#, fuzzy +msgid "Line Width" +msgstr "Bredde" + +#: ../../po/../src/extension/internal/grid.cpp:214 +#, fuzzy +msgid "Horizontal Spacing" +msgstr "vandret flytning" + +#: ../../po/../src/extension/internal/grid.cpp:215 +#, fuzzy +msgid "Vertical Spacing" +msgstr "Lodret centreringsværdi" + +#: ../../po/../src/extension/internal/grid.cpp:216 +#, fuzzy +msgid "Horizontal Offset" +msgstr "vandret flytning" + +#: ../../po/../src/extension/internal/grid.cpp:217 +#, fuzzy +msgid "Vertical Offset" +msgstr "Lodret centreringsværdi" + +#: ../../po/../src/extension/internal/ps.cpp:123 +#, fuzzy +msgid "Print Destination" +msgstr "Udskriv tegning" + +#. Print properties frame +#: ../../po/../src/extension/internal/ps.cpp:138 +#, fuzzy +msgid "Print properties" +msgstr "Egenskaber for lænke" + +#: ../../po/../src/extension/internal/ps.cpp:145 +msgid "Print using PostScript operators" +msgstr "" + +#: ../../po/../src/extension/internal/ps.cpp:147 +msgid "" +"Use PostScript vector operators. The resulting image is usually smaller in " +"file size and can be arbitrarily scaled, but alpha transparency and patterns " +"will be lost." +msgstr "" + +#: ../../po/../src/extension/internal/ps.cpp:152 +#, fuzzy +msgid "Print as bitmap" +msgstr "Eksportér fil" + +#: ../../po/../src/extension/internal/ps.cpp:154 +msgid "" +"Print everything as bitmap. The resulting image is usually larger in file " +"size and cannot be arbitrarily scaled without quality loss, but all objects " +"will be rendered exactly as displayed." +msgstr "" + +#: ../../po/../src/extension/internal/ps.cpp:168 +msgid "Preferred resolution (dots per inch) of bitmap" +msgstr "" + +#: ../../po/../src/extension/internal/ps.cpp:182 +#, fuzzy +msgid "Resolution:" +msgstr "Omdrejning:" + +#. Print destination frame +#: ../../po/../src/extension/internal/ps.cpp:186 +#, fuzzy +msgid "Print destination" +msgstr "Udskriv tegning" + +#: ../../po/../src/extension/internal/ps.cpp:192 +msgid "" +"Use '> filename' to print to file.\n" +"Use '| prog arg...' to pipe to a program." +msgstr "" + +#: ../../po/../src/extension/internal/ps.cpp:1227 +msgid "write error occurred" +msgstr "" + +#: ../../po/../src/extension/prefdialog.cpp:21 +#, fuzzy +msgid " Preferences" +msgstr "Element er en reference" + +#. We can't call sp_ui_error_dialog because we may be +#. running from the console, in which case calling sp_ui +#. routines will cause a segfault. See bug 1000350 - bryce +#. sp_ui_error_dialog(_("Format autodetect failed. The file is being opened as SVG.")); +#: ../../po/../src/extension/system.cpp:105 +msgid "Format autodetect failed. The file is being opened as SVG." +msgstr "" + +#. TRANSLATORS: default.svg is localizable - this is the name of the default document +#. template. This way you can localize the default pagesize, translate the name of +#. the default layer, etc. If you wish to localize this file, please create a +#. localized share/templates/default.xx.svg file, where xx is your language code. +#: ../../po/../src/file.cpp:133 +#, fuzzy +msgid "default.svg" +msgstr "Slet" + +#: ../../po/../src/file.cpp:215 ../../po/../src/file.cpp:900 +#, c-format +msgid "Failed to load the requested file %s" +msgstr "" + +#: ../../po/../src/file.cpp:240 +#, fuzzy +msgid "Document not saved yet. Cannot revert." +msgstr "Dokument" + +#: ../../po/../src/file.cpp:246 +#, c-format +msgid "Changes will be lost! Are you sure you want to reload document %s?" +msgstr "" + +#: ../../po/../src/file.cpp:266 +#, fuzzy +msgid "Document reverted." +msgstr "Dokument" + +#: ../../po/../src/file.cpp:268 +#, fuzzy +msgid "Document not reverted." +msgstr "Dokument" + +#: ../../po/../src/file.cpp:382 +msgid "Select file to open" +msgstr "Vælg fil der skal Ã¥bnes" + +#: ../../po/../src/file.cpp:518 +#, c-format +msgid "Removed %i unused definition in <defs>." +msgid_plural "Removed %i unused definitions in <defs>." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/file.cpp:523 +msgid "No unused definitions in <defs>." +msgstr "" + +#: ../../po/../src/file.cpp:548 +#, c-format +msgid "" +"No Inkscape extension found to save document (%s). This may have been " +"caused by an unknown filename extension." +msgstr "" + +#: ../../po/../src/file.cpp:549 ../../po/../src/file.cpp:557 +#, fuzzy +msgid "Document not saved." +msgstr "Dokument" + +#: ../../po/../src/file.cpp:556 +#, c-format +msgid "File %s could not be saved." +msgstr "" + +#: ../../po/../src/file.cpp:566 +#, fuzzy +msgid "Document saved." +msgstr "Dokument" + +#: ../../po/../src/file.cpp:614 +#, fuzzy, c-format +msgid "drawing%s" +msgstr "Tegning" + +#: ../../po/../src/file.cpp:620 +#, fuzzy, c-format +msgid "drawing-%d%s" +msgstr "Tegning" + +#: ../../po/../src/file.cpp:655 +#, fuzzy +msgid "Select file to save to" +msgstr "Vælg fil der skal Ã¥bnes" + +#: ../../po/../src/file.cpp:739 +msgid "No changes need to be saved." +msgstr "" + +#: ../../po/../src/file.cpp:926 +msgid "Select file to import" +msgstr "Vælg fil der skal importeres" + +#: ../../po/../src/gradient-context.cpp:263 +msgid "Ctrl: snap gradient angle" +msgstr "" + +#: ../../po/../src/gradient-context.cpp:264 +msgid "Shift: draw gradient around the starting point" +msgstr "" + +#. We did an undoable action, but sp_document_done will be called by the knot when released +#. status text; we do not track coords because this branch is run once, not all the time +#. during drag +#: ../../po/../src/gradient-context.cpp:462 +#, c-format +msgid "Gradient for %d objects; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/gradient-context.cpp:464 +#, fuzzy +msgid "Select objects on which to create gradient." +msgstr "Omform valgte ting til kurver" + +#: ../../po/../src/gradient-drag.cpp:65 +#, fuzzy +msgid "Linear gradient start" +msgstr "Tilføj ny farveovergang" + +#. POINT_LG_P1 +#: ../../po/../src/gradient-drag.cpp:66 +#, fuzzy +msgid "Linear gradient end" +msgstr "Tilføj ny farveovergang" + +#: ../../po/../src/gradient-drag.cpp:67 +#, fuzzy +msgid "Radial gradient center" +msgstr "Tilføj ny farveovergang" + +#: ../../po/../src/gradient-drag.cpp:68 ../../po/../src/gradient-drag.cpp:69 +#, fuzzy +msgid "Radial gradient radius" +msgstr "Tilføj ny farveovergang" + +#: ../../po/../src/gradient-drag.cpp:70 +#, fuzzy +msgid "Radial gradient focus" +msgstr "Tilføj ny farveovergang" + +#: ../../po/../src/gradient-drag.cpp:659 +#, c-format +msgid "" +"%s for: %s%s; drag with Ctrl to snap angle, with Ctrl+Alt to " +"preserve angle, with Ctrl+Shift to scale around center" +msgstr "" + +#: ../../po/../src/gradient-drag.cpp:662 +#, fuzzy +msgid " (stroke)" +msgstr "Er skraveret" + +#: ../../po/../src/gradient-drag.cpp:665 +msgid "" +"Radial gradient center and focus; drag with Shift to " +"separate focus" +msgstr "" + +#: ../../po/../src/gradient-drag.cpp:667 +#, c-format +msgid "" +"Gradient point shared by %d gradients; drag with Shift to " +"separate" +msgstr "" + +#: ../../po/../src/helper/units.cpp:40 +#, fuzzy +msgid "Unit" +msgstr "Enheder:" + +#: ../../po/../src/helper/units.cpp:40 +#, fuzzy +msgid "Units" +msgstr "Enheder:" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Point" +msgstr "Punkt" + +#: ../../po/../src/helper/units.cpp:41 +msgid "pt" +msgstr "pt" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Points" +msgstr "Punkter" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Pt" +msgstr "" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Pixel" +msgstr "Pixel" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Pixels" +msgstr "Piksler" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Px" +msgstr "" + +#. You can add new elements from this point forward +#: ../../po/../src/helper/units.cpp:44 ../share/extensions/straightseg.inx.h:2 +msgid "Percent" +msgstr "Procent" + +#: ../../po/../src/helper/units.cpp:44 +#, fuzzy +msgid "Percents" +msgstr "Procent" + +#: ../../po/../src/helper/units.cpp:45 +msgid "Millimeter" +msgstr "Millimeter" + +#: ../../po/../src/helper/units.cpp:45 +msgid "mm" +msgstr "mm" + +#: ../../po/../src/helper/units.cpp:45 +msgid "Millimeters" +msgstr "Millimeter" + +#: ../../po/../src/helper/units.cpp:46 +msgid "Centimeter" +msgstr "Centimeter" + +#: ../../po/../src/helper/units.cpp:46 +msgid "cm" +msgstr "cm" + +#: ../../po/../src/helper/units.cpp:46 +msgid "Centimeters" +msgstr "Centimeter" + +#: ../../po/../src/helper/units.cpp:47 +#, fuzzy +msgid "Meter" +msgstr "Centrér" + +#: ../../po/../src/helper/units.cpp:47 +#, fuzzy +msgid "m" +msgstr "em" + +#: ../../po/../src/helper/units.cpp:47 +#, fuzzy +msgid "Meters" +msgstr "Centrér" + +#. no svg_unit +#: ../../po/../src/helper/units.cpp:48 +msgid "Inch" +msgstr "Tommer" + +#: ../../po/../src/helper/units.cpp:48 +msgid "in" +msgstr "\"" + +#: ../../po/../src/helper/units.cpp:48 +msgid "Inches" +msgstr "Tommer" + +#. Volatiles do not have default, so there are none here +#. TRANSLATORS: for info, see http://www.w3.org/TR/REC-CSS2/syndata.html#length-units +#: ../../po/../src/helper/units.cpp:51 +msgid "Em square" +msgstr "Em-firkant" + +#: ../../po/../src/helper/units.cpp:51 +msgid "em" +msgstr "em" + +#: ../../po/../src/helper/units.cpp:51 +msgid "Em squares" +msgstr "Em-firkanter" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/REC-CSS2/syndata.html#length-units +#: ../../po/../src/helper/units.cpp:53 +msgid "Ex square" +msgstr "Ex-firkant" + +#: ../../po/../src/helper/units.cpp:53 +msgid "ex" +msgstr "ex" + +#: ../../po/../src/helper/units.cpp:53 +msgid "Ex squares" +msgstr "Ex-firkanter" + +#: ../../po/../src/inkscape.cpp:468 +#, fuzzy +msgid "Untitled document" +msgstr "Unavngivet dokument %d" + +#. Show nice dialog box +#: ../../po/../src/inkscape.cpp:497 +msgid "Inkscape encountered an internal error and will close now.\n" +msgstr "" + +#: ../../po/../src/inkscape.cpp:498 +msgid "" +"Automatic backups of unsaved documents were done to the following " +"locations:\n" +msgstr "" + +#: ../../po/../src/inkscape.cpp:499 +msgid "Automatic backup of the following documents failed:\n" +msgstr "" + +#: ../../po/../src/inkscape.cpp:634 +#, c-format +msgid "" +"Cannot create directory %s.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:635 +#, c-format +msgid "" +"%s is not a valid directory.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:636 +#, c-format +msgid "" +"Cannot create file %s.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:637 +#, c-format +msgid "" +"Cannot write file %s.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:638 +msgid "" +"Although Inkscape will run, it will use default settings,\n" +"and any changes made in preferences will not be saved." +msgstr "" + +#: ../../po/../src/inkscape.cpp:708 +#, c-format +msgid "" +"%s is not a regular file.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:709 +#, c-format +msgid "" +"%s not a valid XML file, or\n" +"you don't have read permissions on it.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:711 +#, c-format +msgid "" +"%s is not a valid menus file.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:712 +msgid "" +"Inkscape will run with default menus.\n" +"New menus will not be saved." +msgstr "" + +#. sp_ui_menu_append_check_item_from_verb(m, view, _("_Menu"), _("Show or hide the menu bar"), "menu", +#. checkitem_toggled, checkitem_update, 0); +#: ../../po/../src/interface.cpp:753 +msgid "Commands Bar" +msgstr "" + +#: ../../po/../src/interface.cpp:753 +#, fuzzy +msgid "Show or hide the Commands bar (under the menu)" +msgstr "Vis hjælpelinier" + +#: ../../po/../src/interface.cpp:755 +#, fuzzy +msgid "Tool Controls" +msgstr "Oaf valg" + +#: ../../po/../src/interface.cpp:755 +#, fuzzy +msgid "Show or hide the Tool Controls panel" +msgstr "Vis hjælpelinier" + +#: ../../po/../src/interface.cpp:757 +msgid "_Toolbox" +msgstr "" + +#: ../../po/../src/interface.cpp:757 +msgid "Show or hide the main toolbox (on the left)" +msgstr "" + +#: ../../po/../src/interface.cpp:763 +msgid "_Statusbar" +msgstr "" + +#: ../../po/../src/interface.cpp:763 +msgid "Show or hide the statusbar (at the bottom of the window)" +msgstr "" + +#: ../../po/../src/interface.cpp:820 +#, c-format +msgid "Verb \"%s\" Unknown" +msgstr "" + +#. TRANSLATORS: #%s is the id of the group e.g. , not a number. +#: ../../po/../src/interface.cpp:930 +#, fuzzy, c-format +msgid "Enter group #%s" +msgstr "Redigér noder" + +#: ../../po/../src/interface.cpp:941 +#, fuzzy +msgid "Go to parent" +msgstr "Zoom til side" + +#: ../../po/../src/interface.cpp:972 +msgid "Could not parse SVG data" +msgstr "" + +#: ../../po/../src/interface.cpp:1135 +#, c-format +msgid "Overwrite %s" +msgstr "" + +#: ../../po/../src/interface.cpp:1153 +#, c-format +msgid "" +"The file %s already exists. Do you want to overwrite that file with the " +"current document?" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:59 +msgid "Jabber connection lost." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:72 +#, c-format +msgid "Sending message; %u message remaining in send queue." +msgid_plural "Sending message; %u messages remaining in send queue." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:78 +msgid "Receive queue empty." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:154 +#, c-format +msgid "Receiving change; %u change left to process." +msgid_plural "Receiving change; %u changes left to process." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:157 +#, c-format +msgid "%s has left the chatroom." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:221 +msgid "Nickname %1 is already in use. Please choose a different nickname." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:225 +msgid "An error was encountered while attempting to connect to the server." +msgstr "" + +#. Check to see if the user made any modifications to this document. If so, +#. we want to give them the option of (1) letting us clear their document or (2) +#. opening a new, blank document for the whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:131 +msgid "%1 has invited you to a whiteboard session." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:132 +msgid "Incoming whiteboard invitation from %1" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:135 +msgid "Do you wish to accept %1's whiteboard session invitation?" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:137 +msgid "" +"Would you like to accept %1's invitation in a new document window?\n" +"Accepting the invitation in your current window will discard unsaved changes." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:143 +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:198 +#, fuzzy +msgid "Accept invitation" +msgstr "Valg" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:144 +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:199 +msgid "Decline invitation" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:145 +#, fuzzy +msgid "Accept invitation in new document window" +msgstr "Lagret dokument %d" + +#. We could not create a new desktop; ask the user if she or he wants to +#. replace the current document and accept the invitation, or reject the invitation. +#. TRANSLATORS: %1 is a userid here +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:196 +msgid "" +"A new document window could not be opened for a whiteboard session with %" +"1" +msgstr "" + +#. TRANSLATORS: %1 is the peer whom refused our invitation. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:238 +msgid "" +"The user %1 has refused your " +"whiteboard invitation.\n" +"\n" +msgstr "" + +#. TRANSLATORS: %1 is the peer whom refused our invitation, %2 is our Jabber identity. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:241 +msgid "" +"You are still connected to a Jabber server as %2, and may send an " +"invitation to %1 again, or you may send an invitation to a different " +"user." +msgstr "" + +#. TRANSLATORS: %1 is the peer whom we tried to contact, but is already in a whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:252 +msgid "" +"The user %1 is already in a " +"whiteboard session.\n" +"\n" +msgstr "" + +#. TRANSLATORS: %1 is the peer whom we tried to contact, but is already in a whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:255 +msgid "" +"You are still connected to a Jabber server as %1, and may send an " +"invitation to a different user." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/invitation-confirm-dialog.cpp:26 +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:24 +msgid "_Write session file:" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/message-processors.cpp:145 +#, c-format +msgid "%s has joined the chatroom." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/message-queue.cpp:87 +#, c-format +msgid "%u change in receive queue." +msgid_plural "%u changes in receive queue." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/jabber_whiteboard/message-queue.cpp:117 +#, c-format +msgid "%u change in send queue." +msgid_plural "%u changes in send queue." +msgstr[0] "" +msgstr[1] "" + +#. if ID is NULL, then we have a real problem -- we were not able to find a key +#. nor generate one. The only thing we can really do here is abort, since we have +#. no way to let the other client(s) uniquely identify this object. +#. FIXME: If this indicates a programming bug, then don't request translation with +#. * _(...): it is most useful in untranslated form so that developers may search for +#. * it when someone reports it in a bug report (as we want users to do for all bugs, +#. * as indicated by it being a g_warning string). +#. * +#. * Otherwise, if it is not a programming bug but a network error or a bug in the +#. * remote peer (perhaps running different software) or whatever, then present it in +#. * an alert box, and avoid use of technical jargon `NULL'. +#. +#: ../../po/../src/jabber_whiteboard/message-utilities.cpp:171 +msgid "" +"ID for new object is NULL even after generation and lookup attempts: the new " +"object will NOT be sent, nor will any of its child objects!" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:60 +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:995 +msgid "Select a location and filename" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:62 +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:997 +#, fuzzy +msgid "Set filename" +msgstr "Png filnavn" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:301 +msgid "No SSL certificate was found." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:304 +msgid "The SSL certificate provided by the Jabber server is untrusted." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:307 +msgid "The SSL certificate provided by the Jabber server is expired." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:310 +msgid "" +"The SSL certificate provided by the Jabber server has not been activated." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:313 +msgid "" +"The SSL certificate provided by the Jabber server contains a hostname that " +"does not match the Jabber server's hostname." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:316 +msgid "" +"The SSL certificate provided by the Jabber server contains an invalid " +"fingerprint." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:319 +msgid "An unknown error occurred while setting up the SSL connection." +msgstr "" + +#. TRANSLATORS: %1 is the message that describes the specific error that occurred when +#. establishing the SSL connection. +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:325 +msgid "" +"%1\n" +"\n" +"Do you wish to continue connecting to the Jabber server?" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:328 +msgid "Continue connecting and ignore further errors" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:329 +msgid "Continue connecting, but warn me of further errors" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:330 +#, fuzzy +msgid "Cancel connection" +msgstr "Valg" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:777 +#, c-format +msgid "Established whiteboard session with %s." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:785 +#, c-format +msgid "%s has left the whiteboard session." +msgstr "" + +#. Inform the user +#. TRANSLATORS: %1 is the name of the user that disconnected, %2 is the name of the user whom the disconnected user disconnected from. +#. This message is not used in a chatroom context. +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:790 +msgid "" +"The user %1 has left the " +"whiteboard session.\n" +"\n" +msgstr "" + +#. TRANSLATORS: %1 and %2 are userids +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:792 +msgid "" +"You are still connected to a Jabber server as %2, and may establish a " +"new session to %1 or a different user." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:988 +msgid "" +"Could not open file %1 for session recording.\n" +"The error encountered was: %2.\n" +"\n" +"You may select a different location to record the session, or you may opt to " +"not record this session." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:990 +msgid "Choose a different location" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:991 +msgid "Skip session recording" +msgstr "" + +#: ../../po/../src/knot.cpp:673 +msgid "Node or handle drag canceled." +msgstr "" + +#: ../../po/../src/libnrtype/FontFactory.cpp:358 +msgid "Ignoring font without family that will crash Pango" +msgstr "" + +#: ../../po/../src/main.cpp:395 +msgid "Print the Inkscape version number" +msgstr "" + +#: ../../po/../src/main.cpp:400 +msgid "Do not use X server (only process files from console)" +msgstr "" + +#: ../../po/../src/main.cpp:405 +msgid "Try to use X server (even if $DISPLAY is not set)" +msgstr "" + +#: ../../po/../src/main.cpp:410 +#, fuzzy +msgid "Open specified document(s) (option string may be excluded)" +msgstr "Åbn specificeret fil (streng med alternativer kan udelukkes)" + +#: ../../po/../src/main.cpp:411 ../../po/../src/main.cpp:416 +#: ../../po/../src/main.cpp:421 ../../po/../src/main.cpp:483 +#: ../../po/../src/main.cpp:488 ../../po/../src/main.cpp:493 +msgid "FILENAME" +msgstr "FILNAVN" + +#: ../../po/../src/main.cpp:415 +#, fuzzy +msgid "Print document(s) to specified output file (use '| program' for pipe)" +msgstr "Udskriv filer til specificeret uddatafil (brug '| program' for rør)" + +#: ../../po/../src/main.cpp:420 +#, fuzzy +msgid "Export document to a PNG file" +msgstr "Eksportér billede til png" + +#: ../../po/../src/main.cpp:425 +msgid "The resolution used for exporting SVG into bitmap (default 90)" +msgstr "" + +#: ../../po/../src/main.cpp:426 +msgid "DPI" +msgstr "" + +#: ../../po/../src/main.cpp:430 +msgid "" +"Exported area in SVG user units (default is the canvas; 0,0 is lower-left " +"corner)" +msgstr "" + +#: ../../po/../src/main.cpp:431 +msgid "x0:y0:x1:y1" +msgstr "" + +#: ../../po/../src/main.cpp:435 +msgid "Exported area is the entire drawing (not canvas)" +msgstr "" + +#: ../../po/../src/main.cpp:440 +msgid "" +"Snap the bitmap export area outwards to the nearest integer values (in SVG " +"user units)" +msgstr "" + +#: ../../po/../src/main.cpp:445 +msgid "The width of exported bitmap in pixels (overrides export-dpi)" +msgstr "" + +#: ../../po/../src/main.cpp:446 +msgid "WIDTH" +msgstr "" + +#: ../../po/../src/main.cpp:450 +msgid "The height of exported bitmap in pixels (overrides export-dpi)" +msgstr "" + +#: ../../po/../src/main.cpp:451 +msgid "HEIGHT" +msgstr "" + +#: ../../po/../src/main.cpp:455 +msgid "The ID of the object to export (overrides export-area)" +msgstr "" + +#: ../../po/../src/main.cpp:456 ../../po/../src/main.cpp:532 +#, fuzzy +msgid "ID" +msgstr "ID:" + +#. TRANSLATORS: this means: "Only export the object whose id is given in --export-id". +#. See "man inkscape" for details. +#: ../../po/../src/main.cpp:462 +msgid "" +"Export just the object with export-id, hide all others (only with export-id)" +msgstr "" + +#: ../../po/../src/main.cpp:467 +msgid "Use stored filename and DPI hints when exporting (only with export-id)" +msgstr "" + +#: ../../po/../src/main.cpp:472 +msgid "Background color of exported bitmap (any SVG-supported color string)" +msgstr "" + +#: ../../po/../src/main.cpp:473 +msgid "COLOR" +msgstr "" + +#: ../../po/../src/main.cpp:477 +msgid "Background opacity of exported bitmap (either 0.0 to 1.0, or 1 to 255)" +msgstr "" + +#: ../../po/../src/main.cpp:478 +msgid "VALUE" +msgstr "" + +#: ../../po/../src/main.cpp:482 +msgid "Export document to plain SVG file (no sodipodi or inkscape namespaces)" +msgstr "" + +#: ../../po/../src/main.cpp:487 +#, fuzzy +msgid "Export document to a PS file" +msgstr "Eksportér billede til png" + +#: ../../po/../src/main.cpp:492 +#, fuzzy +msgid "Export document to an EPS file" +msgstr "Eksportér billede til png" + +#: ../../po/../src/main.cpp:497 +#, fuzzy +msgid "Convert text object to paths on export (EPS)" +msgstr "Omform valgte ting til kurver" + +#: ../../po/../src/main.cpp:502 +msgid "Export files with the bounding box set to the page size (EPS)" +msgstr "" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:508 +msgid "" +"Query the X coordinate of the drawing or, if specified, of the object with --" +"query-id" +msgstr "" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:514 +msgid "" +"Query the Y coordinate of the drawing or, if specified, of the object with --" +"query-id" +msgstr "" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:520 +msgid "" +"Query the width of the drawing or, if specified, of the object with --query-" +"id" +msgstr "" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:526 +msgid "" +"Query the height of the drawing or, if specified, of the object with --query-" +"id" +msgstr "" + +#: ../../po/../src/main.cpp:531 +msgid "The ID of the object whose dimensions are queried" +msgstr "" + +#. TRANSLATORS: this option makes Inkscape print the name (path) of the extension directory +#: ../../po/../src/main.cpp:537 +msgid "Print out the extension directory and exit" +msgstr "" + +#: ../../po/../src/main.cpp:542 +msgid "Show given files one-by-one, switch to next on any key/mouse event" +msgstr "" +"Vis givne filer en-efter-en, skift til næste ved enhver taste/muse-hændelse" + +#: ../../po/../src/main.cpp:547 +msgid "Use the new Gtkmm GUI interface" +msgstr "" + +#: ../../po/../src/main.cpp:552 +msgid "Remove unused definitions from the defs section(s) of the document" +msgstr "" + +#: ../../po/../src/main.cpp:741 +msgid "" +"[OPTIONS...] [FILE...]\n" +"\n" +"Available options:" +msgstr "" + +#: ../../po/../src/menus-skeleton.h:17 +msgid "_New" +msgstr "_Ny" + +#: ../../po/../src/menus-skeleton.h:22 +#, fuzzy +msgid "Open _Recent" +msgstr "_Åbn" + +#: ../../po/../src/menus-skeleton.h:53 +#, fuzzy +msgid "_Edit" +msgstr "Redigering" + +#: ../../po/../src/menus-skeleton.h:84 +#, fuzzy +msgid "_View" +msgstr "Ny visning" + +#: ../../po/../src/menus-skeleton.h:85 +#, fuzzy +msgid "_Zoom" +msgstr "Zoom" + +#: ../../po/../src/menus-skeleton.h:102 +#, fuzzy +msgid "Show/Hide" +msgstr "Vis hjælpelinier" + +#: ../../po/../src/menus-skeleton.h:107 +#, fuzzy +msgid "_Display mode" +msgstr "Skærm" + +#: ../../po/../src/menus-skeleton.h:126 +#, fuzzy +msgid "_Layer" +msgstr "Vælg" + +#: ../../po/../src/menus-skeleton.h:143 +#, fuzzy +msgid "_Object" +msgstr "Ting" + +#: ../../po/../src/menus-skeleton.h:165 +#, fuzzy +msgid "_Path" +msgstr "Indsæt" + +#: ../../po/../src/menus-skeleton.h:188 +#, fuzzy +msgid "_Text" +msgstr "Tekst" + +#: ../../po/../src/menus-skeleton.h:200 +#, fuzzy +msgid "Effects" +msgstr "Ting" + +#: ../../po/../src/menus-skeleton.h:207 +msgid "Whiteboa_rd" +msgstr "" + +#: ../../po/../src/menus-skeleton.h:220 +#, fuzzy +msgid "_Help" +msgstr "_Hjælp" + +#: ../../po/../src/menus-skeleton.h:222 +msgid "Tutorials" +msgstr "" + +#: ../../po/../src/node-context.cpp:382 +msgid "" +"Ctrl: toggle node type, snap handle angle, move hor/vert; Ctrl" +"+Alt: move along handles" +msgstr "" + +#: ../../po/../src/node-context.cpp:383 +msgid "" +"Shift: toggle node selection, disable snapping, rotate both handles" +msgstr "" + +#: ../../po/../src/node-context.cpp:384 +msgid "Alt: lock handle length; Ctrl+Alt: move along handles" +msgstr "" + +#: ../../po/../src/nodepath.cpp:1399 ../../po/../src/nodepath.cpp:1411 +#: ../../po/../src/nodepath.cpp:1492 ../../po/../src/nodepath.cpp:1504 +msgid "To join, you must have two endnodes selected." +msgstr "" + +#: ../../po/../src/nodepath.cpp:1633 ../../po/../src/nodepath.cpp:1647 +msgid "" +"Select two non-endpoint nodes on a path between which to delete " +"segments." +msgstr "" + +#: ../../po/../src/nodepath.cpp:1743 +#, fuzzy +msgid "Cannot find path between nodes." +msgstr "Udjævn linje ved valgte knuder" + +#: ../../po/../src/nodepath.cpp:2822 +#, c-format +msgid "" +"Node handle: angle %0.2f°, length %s; with Ctrl to snap " +"angle; with Alt to lock length; with Shift to rotate both " +"handles" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3351 +msgid "" +"Node: drag to edit the path; with Ctrl to snap to horizontal/" +"vertical; with Ctrl+Alt to snap to handles' directions" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3375 +msgid "" +"Node handle: drag to shape the curve; with Ctrl to snap angle; " +"with Alt to lock length; with Shift to rotate both handles" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3399 +msgid "" +"Node handle: drag to shape the curve; with Ctrl to snap angle; " +"with Alt to lock length; with Shift to rotate the opposite " +"handle in sync" +msgstr "" + +#. TRANSLATORS: "end" is an adjective here (NOT a verb) +#: ../../po/../src/nodepath.cpp:3591 +#, fuzzy +msgid "end node" +msgstr "Redigér noder" + +#. TRANSLATORS: "cusp" means "sharp" (cusp node); see also the Advanced Tutorial +#: ../../po/../src/nodepath.cpp:3596 +#, fuzzy +msgid "cusp" +msgstr "us" + +#. TRANSLATORS: "smooth" is an adjective here +#: ../../po/../src/nodepath.cpp:3599 +msgid "smooth" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3601 +#, fuzzy +msgid "symmetric" +msgstr "Usymmetrisk" + +#. TRANSLATORS: "end" is an adjective here (NOT a verb) +#: ../../po/../src/nodepath.cpp:3607 +msgid "end node, handle retracted (drag with Shift to extend)" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3609 +msgid "one handle retracted (drag with Shift to extend)" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3612 +msgid "both handles retracted (drag with Shift to extend)" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3624 +msgid "Drag nodes or node handles; arrow keys to move nodes" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3625 +msgid "Drag the node or its handles; arrow keys to move the node" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3651 ../../po/../src/nodepath.cpp:3663 +#, fuzzy +msgid "Select a single object to edit its nodes or handles." +msgstr "Vend valgte ting" + +#: ../../po/../src/nodepath.cpp:3655 +#, c-format +msgid "" +"0 out of %i node selected. Click, Shift+click, " +"or drag around nodes to select." +msgid_plural "" +"0 out of %i nodes selected. Click, Shift+click, " +"or drag around nodes to select." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/nodepath.cpp:3661 +msgid "Drag the handles of the object to modify it." +msgstr "" + +#: ../../po/../src/nodepath.cpp:3669 +#, fuzzy, c-format +msgid "%i of %i node selected; %s. %s." +msgid_plural "%i of %i nodes selected; %s. %s." +msgstr[0] "Udjævn linje ved valgte knuder" +msgstr[1] "Udjævn linje ved valgte knuder" + +#: ../../po/../src/nodepath.cpp:3675 +#, fuzzy, c-format +msgid "%i of %i node selected. %s." +msgid_plural "%i of %i nodes selected. %s." +msgstr[0] "Udjævn linje ved valgte knuder" +msgstr[1] "Udjævn linje ved valgte knuder" + +#: ../../po/../src/object-edit.cpp:493 +msgid "" +"Adjust the horizontal rounding radius; with Ctrl to make the " +"vertical radius the same" +msgstr "" + +#: ../../po/../src/object-edit.cpp:499 +msgid "" +"Adjust the vertical rounding radius; with Ctrl to make the " +"horizontal radius the same" +msgstr "" + +#: ../../po/../src/object-edit.cpp:506 ../../po/../src/object-edit.cpp:513 +msgid "" +"Adjust the width and height of the rectangle; with Ctrl to " +"lock ratio or stretch in one dimension only" +msgstr "" + +#: ../../po/../src/object-edit.cpp:686 +msgid "Adjust ellipse width, with Ctrl to make circle" +msgstr "" + +#: ../../po/../src/object-edit.cpp:689 +msgid "Adjust ellipse height, with Ctrl to make circle" +msgstr "" + +#: ../../po/../src/object-edit.cpp:692 +msgid "" +"Position the start point of the arc or segment; with Ctrl to " +"snap angle; drag inside the ellipse for arc, outside for " +"segment" +msgstr "" + +#: ../../po/../src/object-edit.cpp:695 +msgid "" +"Position the end point of the arc or segment; with Ctrl to " +"snap angle; drag inside the ellipse for arc, outside for " +"segment" +msgstr "" + +#: ../../po/../src/object-edit.cpp:800 +msgid "" +"Adjust the tip radius of the star or polygon; with Shift to " +"round; with Alt to randomize" +msgstr "" + +#: ../../po/../src/object-edit.cpp:803 +msgid "" +"Adjust the base radius of the star; with Ctrl to keep star " +"rays radial (no skew); with Shift to round; with Alt to " +"randomize" +msgstr "" + +#: ../../po/../src/object-edit.cpp:967 +msgid "" +"Roll/unroll the spiral from inside; with Ctrl to snap angle; " +"with Alt to converge/diverge" +msgstr "" + +#: ../../po/../src/object-edit.cpp:969 +msgid "" +"Roll/unroll the spiral from outside; with Ctrl to snap angle; " +"with Shift to scale/rotate" +msgstr "" + +#: ../../po/../src/object-edit.cpp:1006 +msgid "Adjust the offset distance" +msgstr "" + +#. TRANSLATORS: This refers to the pattern that's inside the object +#: ../../po/../src/object-edit.cpp:1036 +msgid "Move the pattern fill inside the object" +msgstr "" + +#: ../../po/../src/object-edit.cpp:1038 +#, fuzzy +msgid "Scale the pattern fill uniformly" +msgstr "Omform valgte ting til kurver" + +#: ../../po/../src/object-edit.cpp:1040 +msgid "Rotate the pattern fill; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/object-edit.cpp:1065 +msgid "Drag to resize the flowed text frame" +msgstr "" + +#. Item dialog +#: ../../po/../src/object-ui.cpp:106 +#, fuzzy +msgid "Object _Properties" +msgstr "egenskaber for objekt" + +#. Select item +#: ../../po/../src/object-ui.cpp:116 +#, fuzzy +msgid "_Select This" +msgstr "Vælg dette" + +#. Create link +#: ../../po/../src/object-ui.cpp:126 +#, fuzzy +msgid "_Create Link" +msgstr "Opret lænke" + +#. "Ungroup" +#: ../../po/../src/object-ui.cpp:199 ../../po/../src/verbs.cpp:1931 +msgid "_Ungroup" +msgstr "_Opdel gruppe" + +#. Link dialog +#: ../../po/../src/object-ui.cpp:239 +#, fuzzy +msgid "Link _Properties" +msgstr "Egenskaber for lænke" + +#. Select item +#: ../../po/../src/object-ui.cpp:249 +#, fuzzy +msgid "_Follow Link" +msgstr "Følg lænke" + +#. Reset transformations +#: ../../po/../src/object-ui.cpp:254 +#, fuzzy +msgid "_Remove Link" +msgstr "Fjern lænke" + +#. Link dialog +#: ../../po/../src/object-ui.cpp:303 +#, fuzzy +msgid "Image _Properties" +msgstr "Egenskaber for billede" + +#. Item dialog +#: ../../po/../src/object-ui.cpp:344 +#, fuzzy +msgid "_Fill and Stroke" +msgstr "Skrivebordets indstilinger" + +#: ../../po/../src/path-chemistry.cpp:58 +#, fuzzy +msgid "Select at least two objects to combine." +msgstr "Vend valgte ting" + +#: ../../po/../src/path-chemistry.cpp:65 +#, fuzzy +msgid "At least one of the objects is not a path, cannot combine." +msgstr "Omform valgte ting til kurver" + +#: ../../po/../src/path-chemistry.cpp:73 +msgid "" +"You cannot combine objects from different groups or layers." +msgstr "" + +#: ../../po/../src/path-chemistry.cpp:155 +#, fuzzy +msgid "Select path(s) to break apart." +msgstr "Omform valgte ting til kurver" + +#: ../../po/../src/path-chemistry.cpp:231 +msgid "No path(s) to break apart in the selection." +msgstr "" + +#: ../../po/../src/path-chemistry.cpp:252 +#, fuzzy +msgid "Select object(s) to convert to path." +msgstr "Omform valgte ting til kurver" + +#: ../../po/../src/path-chemistry.cpp:297 +#, fuzzy +msgid "No objects to convert to path in the selection." +msgstr "Omform valgte ting til kurver" + +#: ../../po/../src/path-chemistry.cpp:345 +#, fuzzy +msgid "Select path(s) to reverse." +msgstr "Hæv det valgte op til toppen" + +#: ../../po/../src/path-chemistry.cpp:370 +msgid "No paths to reverse in the selection." +msgstr "" + +#: ../../po/../src/pen-context.cpp:379 ../../po/../src/pencil-context.cpp:233 +#, fuzzy +msgid "Continuing selected path" +msgstr "Forbind valgte stier" + +#: ../../po/../src/pen-context.cpp:390 ../../po/../src/pencil-context.cpp:242 +#, fuzzy +msgid "Creating new path" +msgstr "Lagret dokument %d" + +#: ../../po/../src/pen-context.cpp:394 ../../po/../src/pencil-context.cpp:246 +#, fuzzy +msgid "Appending to selected path" +msgstr "Zoom til valg" + +#: ../../po/../src/pen-context.cpp:538 +msgid "Click or click and drag to close and finish the path." +msgstr "" + +#: ../../po/../src/pen-context.cpp:548 +msgid "" +"Click or click and drag to continue the path from this point." +msgstr "" + +#: ../../po/../src/pen-context.cpp:857 +#, c-format +msgid "" +"%s: angle %3.2f°, distance %s; with Ctrl to snap angle, " +"Enter to finish the path" +msgstr "" + +#: ../../po/../src/pen-context.cpp:882 +#, c-format +msgid "" +"Curve handle: angle %3.2f°, length %s; with Ctrl to snap " +"angle" +msgstr "" + +#: ../../po/../src/pen-context.cpp:912 +#, c-format +msgid "" +"%s: angle %3.2f°, length %s; with Ctrl to snap angle, " +"with Shift to move this handle only" +msgstr "" + +#: ../../po/../src/pen-context.cpp:946 +#, fuzzy +msgid "Finishing pen" +msgstr "FrihÃ¥nd" + +#: ../../po/../src/pencil-context.cpp:320 +msgid "Release here to close and finish the path." +msgstr "" + +#: ../../po/../src/pencil-context.cpp:326 +#, fuzzy +msgid "Drawing a freehand path" +msgstr "Tegn frihÃ¥ndslinje" + +#: ../../po/../src/pencil-context.cpp:331 +msgid "Drag to continue the path from this point." +msgstr "" + +#. Write curves to object +#: ../../po/../src/pencil-context.cpp:390 +#, fuzzy +msgid "Finishing freehand" +msgstr "FrihÃ¥nd" + +#: ../../po/../src/rect-context.cpp:387 +msgid "" +"Ctrl: make square or integer-ratio rect, lock a rounded corner " +"circular" +msgstr "" + +#: ../../po/../src/rect-context.cpp:549 +#, c-format +msgid "" +"Rectangle: %s × %s; with Ctrl to make square or integer-" +"ratio rectangle; with Shift to draw around the starting point" +msgstr "" + +#: ../../po/../src/select-context.cpp:243 +#, fuzzy +msgid "Move canceled." +msgstr "Valg" + +#: ../../po/../src/select-context.cpp:252 +#, fuzzy +msgid "Selection canceled." +msgstr "Valg" + +#: ../../po/../src/select-context.cpp:642 +msgid "Ctrl: select in groups, move hor/vert" +msgstr "" + +#: ../../po/../src/select-context.cpp:643 +msgid "Shift: toggle select, force rubberband, disable snapping" +msgstr "" + +#: ../../po/../src/select-context.cpp:644 +msgid "Alt: select under, move selected" +msgstr "" + +#: ../../po/../src/select-context.cpp:798 +#, fuzzy +msgid "Selected object is not a group. Cannot enter." +msgstr "Omform valgte ting til kurver" + +#: ../../po/../src/select-context.cpp:876 +#, c-format +msgid "" +"Move by %s, %s; with Ctrl to restrict to horizontal/vertical; " +"with Shift to disable snapping" +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:228 +msgid "Nothing was deleted." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:259 +#, fuzzy +msgid "Select object(s) to duplicate." +msgstr "Omform valgte ting til kurver" + +#: ../../po/../src/selection-chemistry.cpp:420 +#, fuzzy +msgid "Select two or more objects to group." +msgstr "Hæv det valgte op til toppen" + +#: ../../po/../src/selection-chemistry.cpp:428 +#, fuzzy +msgid "Select at least two objects to group." +msgstr "Vend valgte ting" + +#: ../../po/../src/selection-chemistry.cpp:513 +#, fuzzy +msgid "Select a group to ungroup." +msgstr "Hæv det valgte op til toppen" + +#: ../../po/../src/selection-chemistry.cpp:554 +msgid "No groups to ungroup in the selection." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:623 +#, fuzzy +msgid "Select objects to raise." +msgstr "Omform valgte ting til kurver" + +#: ../../po/../src/selection-chemistry.cpp:629 +#: ../../po/../src/selection-chemistry.cpp:681 +#: ../../po/../src/selection-chemistry.cpp:715 +#: ../../po/../src/selection-chemistry.cpp:773 +msgid "" +"You cannot raise/lower objects from different groups or layers." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:673 +#, fuzzy +msgid "Select object(s) to raise to top." +msgstr "Omform valgte ting til kurver" + +#: ../../po/../src/selection-chemistry.cpp:709 +#, fuzzy +msgid "Select object(s) to lower." +msgstr "Omform valgte ting til kurver" + +#: ../../po/../src/selection-chemistry.cpp:765 +#, fuzzy +msgid "Select object(s) to lower to bottom." +msgstr "Omform valgte ting til kurver" + +#: ../../po/../src/selection-chemistry.cpp:806 +msgid "Nothing to undo." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:813 +msgid "Nothing to redo." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:969 +msgid "Nothing was copied." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1051 +msgid "Current layer is hidden. Unhide it to be able to paste to it." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1055 +msgid "Current layer is locked. Unlock it to be able to paste to it." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1068 +#: ../../po/../src/selection-chemistry.cpp:1103 +#, fuzzy +msgid "Nothing on the clipboard." +msgstr "Kopiér det markerede til klippebord" + +#: ../../po/../src/selection-chemistry.cpp:1109 +#, fuzzy +msgid "Select object(s) to paste style to." +msgstr "Omform valgte ting til kurver" + +#: ../../po/../src/selection-chemistry.cpp:1128 +#, fuzzy +msgid "Select object(s) to move to the layer above." +msgstr "Omform valgte ting til kurver" + +#: ../../po/../src/selection-chemistry.cpp:1146 +#, fuzzy +msgid "No more layers above." +msgstr "Dokument" + +#: ../../po/../src/selection-chemistry.cpp:1160 +#, fuzzy +msgid "Select object(s) to move to the layer below." +msgstr "Omform valgte ting til kurver" + +#: ../../po/../src/selection-chemistry.cpp:1178 +#, fuzzy +msgid "No more layers below." +msgstr "Dokument" + +#: ../../po/../src/selection-chemistry.cpp:1811 +#, fuzzy +msgid "Select a clone to unlink." +msgstr "Vælg fil der skal Ã¥bnes" + +#: ../../po/../src/selection-chemistry.cpp:1842 +msgid "No clones to unlink in the selection." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1859 +msgid "" +"Select a clone to go to its original. Select a linked offset " +"to go to its source. Select a text on path to go to the path. Select " +"a flowed text to go to its frame." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1882 +msgid "" +"Cannot find the object to select (orphaned clone, offset, textpath, " +"flowed text?)" +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1888 +msgid "" +"The object you're trying to select is not visible (it is in <" +"defs>)" +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1915 +#, fuzzy +msgid "Select object(s) to convert to pattern." +msgstr "Omform valgte ting til kurver" + +#: ../../po/../src/selection-chemistry.cpp:2006 +#, fuzzy +msgid "Select an object with pattern fill to extract objects from." +msgstr "Omform valgte ting til kurver" + +#: ../../po/../src/selection-chemistry.cpp:2059 +#, fuzzy +msgid "No pattern fills in the selection." +msgstr "Omform valgte ting til kurver" + +#: ../../po/../src/selection-chemistry.cpp:2079 +#, fuzzy +msgid "Select object(s) to make a bitmap copy." +msgstr "Omform valgte ting til kurver" + +#: ../../po/../src/selection-describer.cpp:37 +msgid "Click selection to toggle scale/rotation handles" +msgstr "" + +#. no items +#: ../../po/../src/selection-describer.cpp:39 +msgid "" +"No objects selected. Click, Shift+click, or drag around objects to select." +msgstr "" + +#: ../../po/../src/selection-describer.cpp:51 +#, fuzzy, c-format +msgid " in layer %s" +msgstr "Radius:" + +#: ../../po/../src/selection-describer.cpp:54 +#, fuzzy, c-format +msgid " in layer %s" +msgstr "Radius:" + +#: ../../po/../src/selection-describer.cpp:66 +msgid "Use Shift+D to look up original" +msgstr "" + +#: ../../po/../src/selection-describer.cpp:70 +msgid "Use Shift+D to look up path" +msgstr "" + +#: ../../po/../src/selection-describer.cpp:74 +msgid "Use Shift+D to look up frame" +msgstr "" + +#: ../../po/../src/selection-describer.cpp:84 +#, fuzzy, c-format +msgid "%i object selected" +msgid_plural "%i objects selected" +msgstr[0] "Udjævn linje ved valgte knuder" +msgstr[1] "Udjævn linje ved valgte knuder" + +#: ../../po/../src/selection-describer.cpp:90 +#, c-format +msgid "%s%s. %s." +msgstr "" + +#: ../../po/../src/selection-describer.cpp:94 +#, fuzzy, c-format +msgid "%s in %i layer. %s." +msgid_plural "%s in %i layers. %s." +msgstr[0] "Udjævn linje ved valgte knuder" +msgstr[1] "Udjævn linje ved valgte knuder" + +#: ../../po/../src/seltrans.cpp:498 +msgid "" +"Center of rotation and skewing: drag to reposition; scaling with " +"Shift also uses this center" +msgstr "" + +#: ../../po/../src/seltrans.cpp:514 +msgid "" +"Squeeze or stretch selection; with Ctrl to scale uniformly; " +"with Shift to scale around rotation center" +msgstr "" + +#: ../../po/../src/seltrans.cpp:515 +msgid "" +"Scale selection; with Ctrl to scale uniformly; with Shift to scale around rotation center" +msgstr "" + +#: ../../po/../src/seltrans.cpp:519 +msgid "" +"Skew selection; with Ctrl to snap angle; with Shift to " +"skew around the opposite side" +msgstr "" + +#: ../../po/../src/seltrans.cpp:520 +msgid "" +"Rotate selection; with Ctrl to snap angle; with Shift " +"to rotate around the opposite corner" +msgstr "" + +#: ../../po/../src/seltrans.cpp:829 ../../po/../src/seltrans.cpp:909 +#, c-format +msgid "Scale: %0.2f%% x %0.2f%%; with Ctrl to lock ratio" +msgstr "" + +#. TRANSLATORS: don't modify the first ";" (it will NOT be displayed as ";" - only the second one will be) +#: ../../po/../src/seltrans.cpp:984 +#, c-format +msgid "Skew: %0.2f°; with Ctrl to snap angle" +msgstr "" + +#. TRANSLATORS: don't modify the first ";" (it will NOT be displayed as ";" - only the second one will be) +#: ../../po/../src/seltrans.cpp:1035 +#, c-format +msgid "Rotate: %0.2f°; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/seltrans.cpp:1090 +#, fuzzy, c-format +msgid "Move center to %s, %s" +msgstr "Lænke til %s" + +#: ../../po/../src/slideshow.cpp:90 +#, fuzzy +msgid "Inkscape slideshow" +msgstr "Sodipodi: %s: %s: %d" + +#: ../../po/../src/sp-anchor.cpp:181 +#, fuzzy, c-format +msgid "Link to %s" +msgstr "Lænke til %s" + +#: ../../po/../src/sp-anchor.cpp:185 +#, fuzzy +msgid "Link without URI" +msgstr "Lænke til %s" + +#: ../../po/../src/sp-ellipse.cpp:438 ../../po/../src/sp-ellipse.cpp:870 +#, fuzzy +msgid "Ellipse" +msgstr "Elipse" + +#: ../../po/../src/sp-ellipse.cpp:583 +#, fuzzy +msgid "Circle" +msgstr "Ændr" + +#: ../../po/../src/sp-ellipse.cpp:865 +#, fuzzy +msgid "Segment" +msgstr "Ændr" + +#: ../../po/../src/sp-ellipse.cpp:867 +msgid "Arc" +msgstr "" + +#. TRANSLATORS: "Flow region" is an area where text is allowed to flow +#: ../../po/../src/sp-flowregion.cpp:276 +#, fuzzy +msgid "Flow region" +msgstr "Følg lænke" + +#. TRANSLATORS: A region "cut out of" a flow region; text is not allowed to flow inside the +#. * flow excluded region. flowRegionExclude in SVG 1.2: see +#. * http://www.w3.org/TR/2004/WD-SVG12-20041027/flow.html#flowRegion-elem and +#. * http://www.w3.org/TR/2004/WD-SVG12-20041027/flow.html#flowRegionExclude-elem. +#: ../../po/../src/sp-flowregion.cpp:493 +msgid "Flow excluded region" +msgstr "" + +#: ../../po/../src/sp-flowtext.cpp:355 +#, c-format +msgid "Flowed text (%d characters)" +msgstr "" + +#: ../../po/../src/sp-flowtext.cpp:357 +#, c-format +msgid "Linked flowed text (%d characters)" +msgstr "" + +#: ../../po/../src/sp-guide.cpp:290 +#, fuzzy +msgid "vertical guideline" +msgstr "Lodret centreringsværdi" + +#: ../../po/../src/sp-guide.cpp:292 +#, fuzzy +msgid "horizontal guideline" +msgstr "vandret flytning" + +#: ../../po/../src/sp-image.cpp:835 +msgid "embedded" +msgstr "" + +#: ../../po/../src/sp-image.cpp:839 +msgid "(null_pointer)" +msgstr "" + +#: ../../po/../src/sp-image.cpp:843 +#, fuzzy, c-format +msgid "Image with bad reference: %s" +msgstr "Element er en reference" + +#: ../../po/../src/sp-image.cpp:844 +#, c-format +msgid "Image %d × %d: %s" +msgstr "" + +#: ../../po/../src/sp-item-group.cpp:390 +#, fuzzy, c-format +msgid "Group of %d object" +msgid_plural "Group of %d objects" +msgstr[0] "Gruppe med %d ting" +msgstr[1] "Gruppe med %d ting" + +#: ../../po/../src/sp-item.cpp:720 +msgid "Object" +msgstr "Ting" + +#: ../../po/../src/sp-line.cpp:202 +#, fuzzy +msgid "Line" +msgstr "Ændr" + +#. TRANSLATORS COMMENT: %s is either "outset" or "inset" depending on sign +#: ../../po/../src/sp-offset.cpp:433 +#, c-format +msgid "Linked offset, %s by %f pt" +msgstr "" + +#: ../../po/../src/sp-offset.cpp:434 ../../po/../src/sp-offset.cpp:438 +#, fuzzy +msgid "outset" +msgstr "Forbind valgte stier" + +#: ../../po/../src/sp-offset.cpp:434 ../../po/../src/sp-offset.cpp:438 +#, fuzzy +msgid "inset" +msgstr "tommer" + +#. TRANSLATORS COMMENT: %s is either "outset" or "inset" depending on sign +#: ../../po/../src/sp-offset.cpp:437 +#, c-format +msgid "Dynamic offset, %s by %f pt" +msgstr "" + +#: ../../po/../src/sp-path.cpp:127 +#, fuzzy, c-format +msgid "Path (%i node)" +msgid_plural "Path (%i nodes)" +msgstr[0] "Lænke til %s" +msgstr[1] "Lænke til %s" + +#: ../../po/../src/sp-polygon.cpp:216 +#, fuzzy +msgid "Polygon" +msgstr "Ændr" + +#: ../../po/../src/sp-polyline.cpp:179 +#, fuzzy +msgid "Polyline" +msgstr "Elipse" + +#: ../../po/../src/sp-rect.cpp:250 +#, fuzzy +msgid "Rectangle" +msgstr "Ændr" + +#. TRANSLATORS: since turn count isn't an integer, please adjust the +#. string as needed to deal with an localized plural forms. +#: ../../po/../src/sp-spiral.cpp:305 +#, c-format +msgid "Spiral with %3f turns" +msgstr "" + +#: ../../po/../src/sp-star.cpp:288 +#, c-format +msgid "Star with %d vertex" +msgid_plural "Star with %d vertices" +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/sp-star.cpp:292 +#, c-format +msgid "Polygon with %d vertex" +msgid_plural "Polygon with %d vertices" +msgstr[0] "" +msgstr[1] "" + +#. TRANSLATORS: For description of font with no name. +#: ../../po/../src/sp-text.cpp:420 +msgid "<no name found>" +msgstr "" + +#: ../../po/../src/sp-text.cpp:426 +#, fuzzy, c-format +msgid "Text on path (%s, %s)" +msgstr "Lænke til %s" + +#: ../../po/../src/sp-text.cpp:427 +#, fuzzy, c-format +msgid "Text (%s, %s)" +msgstr "Lænke til %s" + +#. TRANSLATORS: Used for statusbar description for long chains: +#. * "Clone of: Clone of: ... in Layer 1". +#: ../../po/../src/sp-use.cpp:317 +#, fuzzy +msgid "..." +msgstr "_Åbn" + +#: ../../po/../src/sp-use.cpp:325 +#, fuzzy, c-format +msgid "Clone of: %s" +msgstr "Lænke til %s" + +#: ../../po/../src/sp-use.cpp:329 +#, fuzzy +msgid "Orphaned clone" +msgstr "Ændr" + +#: ../../po/../src/spiral-context.cpp:355 +msgid "Ctrl: snap angle" +msgstr "" + +#: ../../po/../src/spiral-context.cpp:357 +msgid "Alt: lock spiral radius" +msgstr "" + +#: ../../po/../src/spiral-context.cpp:469 +#, c-format +msgid "" +"Spiral: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/splivarot.cpp:106 +#, fuzzy +msgid "Select at least 2 paths to perform a boolean operation." +msgstr "Vend valgte ting" + +#: ../../po/../src/splivarot.cpp:112 +msgid "" +"Select exactly 2 paths to perform difference, XOR, division, or path " +"cut." +msgstr "" + +#: ../../po/../src/splivarot.cpp:129 ../../po/../src/splivarot.cpp:144 +msgid "" +"Unable to determine the z-order of the objects selected for " +"difference, XOR, division, or path cut." +msgstr "" + +#: ../../po/../src/splivarot.cpp:174 +#, fuzzy +msgid "" +"One of the objects is not a path, cannot perform boolean operation." +msgstr "Omform valgte ting til kurver" + +#. TRANSLATORS: "to outline" means "to convert stroke to path" +#: ../../po/../src/splivarot.cpp:554 +#, fuzzy +msgid "Select path(s) to outline." +msgstr "Omform valgte ting til kurver" + +#. TRANSLATORS: "to outline" means "to convert stroke to path" +#: ../../po/../src/splivarot.cpp:748 +msgid "No stroked paths to outline in the selection." +msgstr "" + +#: ../../po/../src/splivarot.cpp:832 +#, fuzzy +msgid "Selected object is not a path, cannot inset/outset." +msgstr "Omform valgte ting til kurver" + +#: ../../po/../src/splivarot.cpp:1040 +#, fuzzy +msgid "Select path(s) to inset/outset." +msgstr "Omform valgte ting til kurver" + +#: ../../po/../src/splivarot.cpp:1257 +msgid "No paths to inset/outset in the selection." +msgstr "" + +#: ../../po/../src/splivarot.cpp:1390 +#, fuzzy +msgid "Select path(s) to simplify." +msgstr "Omform valgte ting til kurver" + +#: ../../po/../src/splivarot.cpp:1417 +msgid "No paths to simplify in the selection." +msgstr "" + +#: ../../po/../src/star-context.cpp:362 +msgid "Ctrl: snap angle; keep rays radial" +msgstr "" + +#: ../../po/../src/star-context.cpp:470 +#, c-format +msgid "" +"Polygon: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/star-context.cpp:471 +#, c-format +msgid "Star: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/text-chemistry.cpp:90 +#, fuzzy +msgid "Select a text and a path to put text on path." +msgstr "Vend valgte ting" + +#: ../../po/../src/text-chemistry.cpp:95 +msgid "" +"This text object is already put to a path. Remove it from the path " +"first. Use Shift+D to look up its path." +msgstr "" + +#. rect is the only SPShape which is not yet, and thus SVG forbids us from putting text on it +#: ../../po/../src/text-chemistry.cpp:101 +msgid "" +"You cannot put text on a rectangle in this version. Convert rectangle to " +"path first." +msgstr "" + +#: ../../po/../src/text-chemistry.cpp:159 +#, fuzzy +msgid "Select a text on path to remove it from path." +msgstr "Vend valgte ting" + +#: ../../po/../src/text-chemistry.cpp:181 +#, fuzzy +msgid "No texts-on-paths in the selection." +msgstr "Omform valgte ting til kurver" + +#: ../../po/../src/text-chemistry.cpp:209 +#: ../../po/../src/text-chemistry.cpp:229 +#, fuzzy +msgid "Select text(s) to remove kerns from." +msgstr "Hæv det valgte op til toppen" + +#: ../../po/../src/text-chemistry.cpp:250 +#, fuzzy +msgid "" +"Select a text and one or more paths or shapes to flow text " +"into frame." +msgstr "Vend valgte ting" + +#: ../../po/../src/text-chemistry.cpp:322 +#, fuzzy +msgid "Select a flowed text to unflow it." +msgstr "Omform valgte ting til kurver" + +#: ../../po/../src/text-context.cpp:463 +msgid "Click to edit the text, drag to select part of the text." +msgstr "" + +#: ../../po/../src/text-context.cpp:465 +msgid "" +"Click to edit the flowed text, drag to select part of the text." +msgstr "" + +#: ../../po/../src/text-context.cpp:540 +msgid "Non-printable character" +msgstr "" + +#: ../../po/../src/text-context.cpp:589 +#, fuzzy, c-format +msgid "Unicode: %s: %s" +msgstr "Sodipodi: %s: %s: %d" + +#: ../../po/../src/text-context.cpp:591 ../../po/../src/text-context.cpp:855 +msgid "Unicode: " +msgstr "" + +#: ../../po/../src/text-context.cpp:615 +msgid "Current layer is hidden. Unhide it to be able to add text." +msgstr "" + +#: ../../po/../src/text-context.cpp:619 +msgid "Current layer is locked. Unlock it to be able to add text." +msgstr "" + +#: ../../po/../src/text-context.cpp:673 +#, c-format +msgid "Flowed text frame: %s × %s" +msgstr "" + +#: ../../po/../src/text-context.cpp:708 ../../po/../src/text-context.cpp:1464 +msgid "Type text; Enter to start new line." +msgstr "" + +#: ../../po/../src/text-context.cpp:719 +msgid "Flowed text is created." +msgstr "" + +#: ../../po/../src/text-context.cpp:722 +msgid "" +"The frame is too small for the current font size. Flowed text not " +"created." +msgstr "" + +#: ../../po/../src/text-context.cpp:841 +msgid "No-break space" +msgstr "" + +#: ../../po/../src/text-context.cpp:1462 +msgid "Type flowed text; Enter to start new paragraph." +msgstr "" + +#: ../../po/../src/text-context.cpp:1472 ../../po/../src/tools-switch.cpp:189 +msgid "" +"Click to select or create text, drag to create flowed text; " +"then type." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:141 +msgid "" +"To edit a path, click, Shift+click, or drag around " +"nodes to select them, then drag nodes and handles. Click on an " +"object to select." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:147 +msgid "" +"Drag to create a rectangle. Drag controls to round corners and " +"resize. Click to select." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:153 +msgid "" +"Drag to create an ellipse. Drag controls to make an arc or " +"segment. Click to select." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:159 +msgid "" +"Drag to create a star. Drag controls to edit the star shape. " +"Click to select." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:165 +msgid "" +"Drag to create a spiral. Drag controls to edit the spiral " +"shape. Click to select." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:171 +msgid "" +"Drag to create a freehand line. Start drawing with Shift to " +"append to selected path." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:177 +msgid "" +"Click or click and drag to start a path; with Shift to " +"append to selected path." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:183 +msgid "" +"Drag to paint a calligraphic stroke. Left/right arrow " +"keys adjust width, up/down adjust angle." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:195 +msgid "" +"Drag or double click to create a gradient on selected objects, " +"drag handles to adjust gradients." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:201 +msgid "" +"Click or drag around an area to zoom in, Shift+click to " +"zoom out." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:213 +msgid "Click and drag between shapes to create a connector." +msgstr "" + +#: ../../po/../src/trace/potrace/inkscape-potrace.cpp:553 +#: ../../po/../src/trace/potrace/inkscape-potrace.cpp:654 +#, c-format +msgid "Trace: %d. %ld nodes" +msgstr "" + +#: ../../po/../src/trace/trace.cpp:53 ../../po/../src/trace/trace.cpp:62 +#: ../../po/../src/trace/trace.cpp:70 +#, fuzzy +msgid "Select an image to trace" +msgstr "Omform valgte ting til kurver" + +#: ../../po/../src/trace/trace.cpp:133 +#, fuzzy +msgid "Trace: No active document" +msgstr "Lagret dokument %d" + +#: ../../po/../src/trace/trace.cpp:154 +msgid "Trace: Image has no bitmap data" +msgstr "" + +#: ../../po/../src/trace/trace.cpp:267 +#, fuzzy, c-format +msgid "Trace: Done. %ld nodes created" +msgstr "Sidste valgt" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:59 ../../po/../src/verbs.cpp:2212 +msgid "About Inkscape" +msgstr "" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:66 +msgid "_Splash" +msgstr "" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:68 +msgid "_Authors" +msgstr "" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:69 +#, fuzzy +msgid "_Translators" +msgstr "Transformation" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:70 +#, fuzzy +msgid "_License" +msgstr "tommer" + +#. TRANSLATORS: This is the filename of the `About Inkscape' picture in +#. the `screens' directory. Thus the translation of "about.svg" should be +#. the filename of its translated version, e.g. about.zh.svg for Chinese. +#. +#. N.B. about.svg changes once per release. (We should probably rename +#. the original to about-0.40.svg etc. as soon as we have a translation. +#. If we do so, then add an item to release-checklist saying that the +#. string here should be changed.) +#. FIXME? INKSCAPE_SCREENSDIR and "about.svg" are in UTF-8, not the +#. native filename encoding... and the filename passed to sp_document_new +#. should be in UTF-*8.. +#: ../../po/../src/ui/dialog/aboutbox.cpp:114 +msgid "about.svg" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:464 +msgid "Minimum horizontal gap (in px units) between bounding boxes" +msgstr "" + +#. TRANSLATORS: Horizontal gap +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:466 +#: ../../po/../src/widgets/toolbox.cpp:1556 +msgid "H:" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:474 +msgid "Minimum vertical gap (in px units) between bounding boxes" +msgstr "" + +#. TRANSLATORS: Vertical gap +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:476 +msgid "V:" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:734 +msgid "Align" +msgstr "Justér" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:735 +#, fuzzy +msgid "Distribute" +msgstr "Attributter" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:736 +msgid "Remove overlaps" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:737 +msgid "Nodes" +msgstr "Noder" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:742 +#, fuzzy +msgid "Relative to: " +msgstr "lodret flytning" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:747 +#, fuzzy +msgid "Align right sides of objects to left side of anchor" +msgstr "Justér indre objekt til venstre kant" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:750 +#, fuzzy +msgid "Align left sides" +msgstr "Justér til venstre for midte" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:753 +#, fuzzy +msgid "Center on vertical axis" +msgstr "vend lodret" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:756 +#, fuzzy +msgid "Align right sides" +msgstr "Justér til højre midte" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:759 +#, fuzzy +msgid "Align left sides of objects to right side of anchor" +msgstr "Justér indre objekt til højre kant" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:762 +#, fuzzy +msgid "Align bottoms of objects to top of anchor" +msgstr "Justér indre objekt til bundkant" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:765 +#, fuzzy +msgid "Align tops" +msgstr "Ting" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:768 +#, fuzzy +msgid "Center on horizontal axis" +msgstr "vend vandret" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:771 +#, fuzzy +msgid "Align bottoms" +msgstr "Justér til nederst til venstre" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:774 +#, fuzzy +msgid "Align tops of objects to bottom of anchor" +msgstr "Justér indre objekt til topkant" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:779 +#, fuzzy +msgid "Align baseline anchors of texts vertically" +msgstr "Vend valgte ting" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:782 +#, fuzzy +msgid "Align baseline anchors of texts horizontally" +msgstr "Vend valgte ting" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:787 +msgid "Make horizontal gaps between objects equal" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:791 +#, fuzzy +msgid "Distribute left sides equidistantly" +msgstr "Vend valgte ting" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:794 +#, fuzzy +msgid "Distribute centers equidistantly horizontally" +msgstr "Vend valgte ting" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:797 +#, fuzzy +msgid "Distribute right sides equidistantly" +msgstr "Vend valgte ting" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:801 +msgid "Make vertical gaps between objects equal" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:805 +#, fuzzy +msgid "Distribute tops equidistantly" +msgstr "Vend valgte ting" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:808 +#, fuzzy +msgid "Distribute centers equidistantly vertically" +msgstr "Vend valgte ting" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:811 +msgid "Distribute bottoms equidistantly" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:816 +#, fuzzy +msgid "Distribute baseline anchors of texts horizontally" +msgstr "Vend valgte ting" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:819 +#, fuzzy +msgid "Distribute baseline anchors of texts vertically" +msgstr "Vend valgte ting" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:824 +msgid "Randomize centers in both dimensions" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:827 +msgid "Unclump objects: try to equalize edge-to-edge distances" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:832 +msgid "" +"Move objects as little as possible so that their bounding boxes do not " +"overlap" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:837 +#, fuzzy +msgid "Align selected nodes horizontally" +msgstr "Vend valgte ting" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:840 +#, fuzzy +msgid "Align selected nodes vertically" +msgstr "Vend valgte ting" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:843 +#, fuzzy +msgid "Distribute selected nodes horizontally" +msgstr "Vend valgte ting" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:846 +#, fuzzy +msgid "Distribute selected nodes vertically" +msgstr "Vend valgte ting" + +#. Rest of the widgetry +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:851 +msgid "Last selected" +msgstr "Sidste valgt" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:852 +msgid "First selected" +msgstr "Første valgt" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:853 +msgid "Biggest item" +msgstr "Største element" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:854 +msgid "Smallest item" +msgstr "Mindste element" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:856 +#: ../../po/../src/widgets/desktop-widget.cpp:1065 +msgid "Drawing" +msgstr "Tegning" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:91 +msgid "Metadata 1" +msgstr "" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:92 +msgid "Metadata 2" +msgstr "" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:187 +#, fuzzy +msgid "X coordinate of grid origin" +msgstr "Vælg farve for hjælpelinjer" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:189 +#, fuzzy +msgid "Y coordinate of grid origin" +msgstr "Vælg farve for hjælpelinjer" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:191 +#, fuzzy +msgid "Distance of vertical grid lines" +msgstr "Sæt afstanden mellem lodrette gitterlinjer" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:193 +#, fuzzy +msgid "Distance of horizontal grid lines" +msgstr "Sæt afstanden mellem vandrette gitterlinjer" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:197 +msgid "Max. snapping distance from grid" +msgstr "" + +#: ../../po/../src/ui/dialog/export.cpp:34 +msgid "Export" +msgstr "Eksportér" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:36 +msgid "Fill" +msgstr "Fyld" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:37 +#, fuzzy +msgid "Stroke Paint" +msgstr "Bredde pÃ¥ strøg" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:38 +#, fuzzy +msgid "Stroke Style" +msgstr "Skrivebordets indstilinger" + +#: ../../po/../src/ui/dialog/find.cpp:34 +#, fuzzy +msgid "Find" +msgstr "Gitter" + +#: ../../po/../src/ui/dialog/memory.cpp:96 +#, fuzzy +msgid "Heap" +msgstr "_Hjælp" + +#: ../../po/../src/ui/dialog/memory.cpp:97 +#, fuzzy +msgid "In Use" +msgstr "Nulstil" + +#. TRANSLATORS: "Slack" refers to memory which is in the heap but currently unused. +#. More typical usage is to call this memory "free" rather than "slack". +#: ../../po/../src/ui/dialog/memory.cpp:100 +#, fuzzy +msgid "Slack" +msgstr "Stjerne" + +#: ../../po/../src/ui/dialog/memory.cpp:101 +#, fuzzy +msgid "Total" +msgstr "Titel:" + +#: ../../po/../src/ui/dialog/memory.cpp:141 +#: ../../po/../src/ui/dialog/memory.cpp:147 +#: ../../po/../src/ui/dialog/memory.cpp:154 +#: ../../po/../src/ui/dialog/memory.cpp:186 +#, fuzzy +msgid "Unknown" +msgstr "Ukendt element :-(" + +#: ../../po/../src/ui/dialog/memory.cpp:167 +#, fuzzy +msgid "Combined" +msgstr "_Kombinér" + +#: ../../po/../src/ui/dialog/memory.cpp:209 +#, fuzzy +msgid "Recalculate" +msgstr "Firkant" + +#: ../../po/../src/ui/dialog/messages.cpp:74 +#, fuzzy +msgid "Ready." +msgstr "Genlæs" + +#: ../../po/../src/ui/dialog/messages.cpp:75 +msgid "" +"Enable log display by setting dialogs.debug 'redirect' attribute to 1 in " +"preferences.xml" +msgstr "" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:184 +msgid "_Execute Python" +msgstr "" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:186 +msgid "_Execute Perl" +msgstr "" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:195 +msgid "Script" +msgstr "" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:205 +#, fuzzy +msgid "Output" +msgstr "Klip" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:215 +msgid "Errors" +msgstr "" + +#. Dialog organization +#: ../../po/../src/ui/dialog/session-player.cpp:73 +#, fuzzy +msgid "Session file" +msgstr "Gem fil" + +#: ../../po/../src/ui/dialog/session-player.cpp:74 +#, fuzzy +msgid "Playback controls" +msgstr "Oaf valg" + +#: ../../po/../src/ui/dialog/session-player.cpp:75 +#, fuzzy +msgid "Message information" +msgstr "Nulstil transformation" + +#. Active session file display +#. fixme: Does this mean the active file for the session, or the file for the active session? +#. Please indicate which with a TRANSLATORS comment. +#: ../../po/../src/ui/dialog/session-player.cpp:85 +msgid "Active session file:" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:86 +msgid "Delay (milliseconds):" +msgstr "" + +#. Unload/load buttons +#: ../../po/../src/ui/dialog/session-player.cpp:94 +#, fuzzy +msgid "Close file" +msgstr "Farvefyld" + +#: ../../po/../src/ui/dialog/session-player.cpp:95 +#, fuzzy +msgid "Open new file" +msgstr "Åben ny tegning" + +#: ../../po/../src/ui/dialog/session-player.cpp:96 +msgid "Set delay" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:138 +#, fuzzy +msgid "Rewind" +msgstr "Rød:" + +#: ../../po/../src/ui/dialog/session-player.cpp:139 +msgid "Go back one change" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:140 +#, fuzzy +msgid "Pause" +msgstr "Indsæt" + +#: ../../po/../src/ui/dialog/session-player.cpp:141 +msgid "Go forward one change" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:142 +msgid "Play" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:177 +#: ../../po/../src/verbs.cpp:1573 +msgid "Open session file" +msgstr "" + +#. ##Set up the Potrace panel +#. #### brightness #### +#. #### Multiple scanning#### +#. ----Hbox1 +#: ../../po/../src/ui/dialog/tracedialog.cpp:345 +#: ../../po/../src/ui/dialog/tracedialog.cpp:428 +#, fuzzy +msgid "Brightness" +msgstr "Højde" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:348 +msgid "Trace by a given brightness level" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:355 +msgid "Brightness cutoff for black/white" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:362 +#, fuzzy +msgid "Image Brightness" +msgstr "Billedstørrelse" + +#. #### canny edge detection #### +#. TRANSLATORS: "Canny" is the name of the inventor of this edge detection method +#: ../../po/../src/ui/dialog/tracedialog.cpp:369 +msgid "Optimal Edge Detection (Canny)" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:372 +msgid "Trace with edge detection by J. Canny's algorithm" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:388 +msgid "Brightness cutoff for adjacent pixels (determines edge thickness)" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:395 +#, fuzzy +msgid "Edge Detection" +msgstr "Valg" + +#. #### quantization #### +#. TRANSLATORS: Color Quantization: the process of reducing the number of colors +#. in an image by selecting an optimized set of representative colors and then +#. re-applying this reduced set to the original image. +#: ../../po/../src/ui/dialog/tracedialog.cpp:404 +#, fuzzy +msgid "Color Quantization" +msgstr "Farve-bitmap" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:407 +msgid "Trace along the boundaries of reduced colors" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:414 +msgid "The number of reduced colors" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:416 +#, fuzzy +msgid "Colors:" +msgstr "Farve:" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:421 +msgid "Quantization / Reduction" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:431 +msgid "Trace the given number of brightness levels" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:438 +#, fuzzy +msgid "Scans:" +msgstr "Form" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:440 +msgid "The desired number of scans" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:448 +msgid "Trace the given number of reduced colors" +msgstr "" + +#. ---Hbox3 +#: ../../po/../src/ui/dialog/tracedialog.cpp:454 +msgid "Monochrome" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:457 +msgid "Same as Color, but convert result to grayscale" +msgstr "" + +#. TRANSLATORS: "Stack" is a verb here +#: ../../po/../src/ui/dialog/tracedialog.cpp:460 +#, fuzzy +msgid "Stack" +msgstr "Stjerne" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:463 +msgid "" +"Stack scans vertically (no gaps) or tile horizontally (usually with gaps)" +msgstr "" + +#. TRANSLATORS: "Smooth" is a verb here +#: ../../po/../src/ui/dialog/tracedialog.cpp:466 +msgid "Smooth" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:469 +msgid "Apply Gaussian blur to the bitmap before tracing" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:473 +msgid "Multiple Scanning" +msgstr "" + +#. #### Preview #### +#: ../../po/../src/ui/dialog/tracedialog.cpp:479 +#: ../../po/../src/ui/dialog/tracedialog.cpp:489 +#, fuzzy +msgid "Preview" +msgstr "Nyt smugkig" + +#. do not expand +#: ../../po/../src/ui/dialog/tracedialog.cpp:483 +msgid "Preview the result without actual tracing" +msgstr "" + +#. #### swap black and white #### +#: ../../po/../src/ui/dialog/tracedialog.cpp:495 +#, fuzzy +msgid "Invert" +msgstr "Nulstil" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:499 +msgid "Invert black and white regions for single traces" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:503 +msgid "Thanks to Peter Selinger, http://potrace.sourceforge.net" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:506 +#, fuzzy +msgid "Credits" +msgstr "Farve-bitmap" + +#. done +#. TRANSLATORS: Potrace is an application for transforming bitmaps into +#. vector graphics (http://potrace.sourceforge.net/) +#: ../../po/../src/ui/dialog/tracedialog.cpp:514 +#, fuzzy +msgid "Potrace" +msgstr "Punkt" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:527 +#, fuzzy +msgid "Abort a trace in progress" +msgstr "Eksporteret som" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:531 +msgid "Execute the trace" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:80 +#: ../../po/../src/ui/dialog/transformation.cpp:90 +#, fuzzy +msgid "_Horizontal" +msgstr "vandret flytning" + +#: ../../po/../src/ui/dialog/transformation.cpp:80 +msgid "Horizontal displacement (relative) or position (absolute)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:82 +#: ../../po/../src/ui/dialog/transformation.cpp:92 +#, fuzzy +msgid "_Vertical" +msgstr "Lodret centreringsværdi" + +#: ../../po/../src/ui/dialog/transformation.cpp:82 +msgid "Vertical displacement (relative) or position (absolute)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:84 +#, fuzzy +msgid "_Width" +msgstr "Bredde:" + +#: ../../po/../src/ui/dialog/transformation.cpp:84 +msgid "Horizontal size increment (absolute or percentage)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:86 +#, fuzzy +msgid "_Height" +msgstr "Højde:" + +#: ../../po/../src/ui/dialog/transformation.cpp:86 +msgid "Vertical size increment (absolute or percentage)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:88 +#, fuzzy +msgid "A_ngle" +msgstr "vinkel" + +#: ../../po/../src/ui/dialog/transformation.cpp:88 +#, fuzzy +msgid "Rotation angle (positive = counterclockwise)" +msgstr "Drej valgte ting 90° med uret" + +#: ../../po/../src/ui/dialog/transformation.cpp:90 +msgid "" +"Horizontal skew angle (positive = counterclockwise), or absolute " +"displacement, or percentage displacement" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:92 +msgid "" +"Vertical skew angle (positive = counterclockwise), or absolute displacement, " +"or percentage displacement" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:95 +#, fuzzy +msgid "Transformation matrix element A" +msgstr "Transformation" + +#: ../../po/../src/ui/dialog/transformation.cpp:96 +#, fuzzy +msgid "Transformation matrix element B" +msgstr "Transformation" + +#: ../../po/../src/ui/dialog/transformation.cpp:97 +#, fuzzy +msgid "Transformation matrix element C" +msgstr "Transformation" + +#: ../../po/../src/ui/dialog/transformation.cpp:98 +#, fuzzy +msgid "Transformation matrix element D" +msgstr "Transformation" + +#: ../../po/../src/ui/dialog/transformation.cpp:99 +#, fuzzy +msgid "Transformation matrix element E" +msgstr "Transformation" + +#: ../../po/../src/ui/dialog/transformation.cpp:100 +#, fuzzy +msgid "Transformation matrix element F" +msgstr "Transformation" + +#: ../../po/../src/ui/dialog/transformation.cpp:102 +#, fuzzy +msgid "Rela_tive move" +msgstr "lodret flytning" + +#: ../../po/../src/ui/dialog/transformation.cpp:102 +msgid "" +"Add the specified relative displacement to the current position; otherwise, " +"edit the current absolute position directly" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:103 +msgid "Scale proportionally" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:103 +msgid "Preserve the width/height ratio of the scaled objects" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:104 +msgid "Apply to each _object separately" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:104 +msgid "" +"Apply the scale/rotate/skew to each selected object separately; otherwise, " +"transform the selection as a whole" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:105 +msgid "Edit c_urrent matrix" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:105 +msgid "" +"Edit the current transform= matrix; otherwise, post-multiply transform= by " +"this matrix" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:115 +#, fuzzy +msgid "_Move" +msgstr "Flyt" + +#: ../../po/../src/ui/dialog/transformation.cpp:118 +#, fuzzy +msgid "_Scale" +msgstr "Skalér" + +#: ../../po/../src/ui/dialog/transformation.cpp:121 +#, fuzzy +msgid "_Rotate" +msgstr "Rotér" + +#: ../../po/../src/ui/dialog/transformation.cpp:124 +#, fuzzy +msgid "Ske_w" +msgstr "Drej" + +#: ../../po/../src/ui/dialog/transformation.cpp:127 +msgid "Matri_x" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:141 +#, fuzzy +msgid "Reset the values on the current tab to defaults" +msgstr "Gensæt dialog til standard - ctrl+r" + +#: ../../po/../src/ui/dialog/transformation.cpp:148 +#, fuzzy +msgid "Apply transformation to selection" +msgstr "Anvend transformation ved kopiering - ctrl+m" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:43 +msgid "_Use SSL" +msgstr "" + +#. Construct dialog interface +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:68 +#, fuzzy +msgid "_Server:" +msgstr "Fil" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:69 +#, fuzzy +msgid "_Username:" +msgstr "Filnavn:" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:70 +msgid "_Password:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:71 +msgid "P_ort:" +msgstr "" + +#. Buttons +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:99 +#, fuzzy +msgid "Connect" +msgstr "Indhold" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:126 +msgid "Establishing connection to Jabber server %1 as user %2" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:131 +msgid "Failed to establish connection to Jabber server %1" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:136 +msgid "Authentication failed on Jabber server %1 as %2" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:141 +msgid "SSL initialization failed when connecting to Jabber server %1" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:147 +msgid "Connected to Jabber server %1 as %2" +msgstr "" + +#. Construct labels +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:75 +msgid "Chatroom _name:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:76 +msgid "Chatroom _server:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:77 +msgid "Chatroom _password:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:78 +msgid "Chatroom _handle:" +msgstr "" + +#. Button setup and callback registration +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:97 +msgid "Connect to chatroom" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:132 +msgid "Synchronizing with chatroom %1@%2 using the handle %3" +msgstr "" + +#. Construct dialog interface +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:78 +msgid "_User's Jabber ID:" +msgstr "" + +#. Buttons +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:82 +msgid "_Invite user" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:83 +#, fuzzy +msgid "_Cancel" +msgstr "Ændr" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:94 +msgid "Buddy List" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:170 +msgid "Sending whiteboard invitation to %1" +msgstr "" + +#. FIXME: strings are replaced by placeholders, NOT to be translated until the code is enabled +#. See http://sourceforge.net/mailarchive/message.php?msg_id=11746016 for details +#. File menu +#. Edit menu +#. View menu +#. Layer menu +#. Object menu +#. Path menu +#. add(Gtk::StockItem(CLEANUP, _("PLACEHOLDER, do not translate"))); (using Gtk::Stock::CLEAR) +#. Text menu +#. About menu +#. Tools toolbox +#. Select Tool controls +#. Node Tool controls +#. Calligraphy Tool controls +#. Session playback controls +#: ../../po/../src/ui/stock-items.cpp:34 ../../po/../src/ui/stock-items.cpp:35 +#: ../../po/../src/ui/stock-items.cpp:36 ../../po/../src/ui/stock-items.cpp:37 +#: ../../po/../src/ui/stock-items.cpp:38 ../../po/../src/ui/stock-items.cpp:39 +#: ../../po/../src/ui/stock-items.cpp:40 ../../po/../src/ui/stock-items.cpp:41 +#: ../../po/../src/ui/stock-items.cpp:42 ../../po/../src/ui/stock-items.cpp:43 +#: ../../po/../src/ui/stock-items.cpp:46 ../../po/../src/ui/stock-items.cpp:47 +#: ../../po/../src/ui/stock-items.cpp:48 ../../po/../src/ui/stock-items.cpp:49 +#: ../../po/../src/ui/stock-items.cpp:50 ../../po/../src/ui/stock-items.cpp:51 +#: ../../po/../src/ui/stock-items.cpp:52 ../../po/../src/ui/stock-items.cpp:53 +#: ../../po/../src/ui/stock-items.cpp:54 ../../po/../src/ui/stock-items.cpp:55 +#: ../../po/../src/ui/stock-items.cpp:56 ../../po/../src/ui/stock-items.cpp:57 +#: ../../po/../src/ui/stock-items.cpp:58 ../../po/../src/ui/stock-items.cpp:59 +#: ../../po/../src/ui/stock-items.cpp:62 ../../po/../src/ui/stock-items.cpp:63 +#: ../../po/../src/ui/stock-items.cpp:64 ../../po/../src/ui/stock-items.cpp:65 +#: ../../po/../src/ui/stock-items.cpp:66 ../../po/../src/ui/stock-items.cpp:67 +#: ../../po/../src/ui/stock-items.cpp:68 ../../po/../src/ui/stock-items.cpp:69 +#: ../../po/../src/ui/stock-items.cpp:70 ../../po/../src/ui/stock-items.cpp:71 +#: ../../po/../src/ui/stock-items.cpp:72 ../../po/../src/ui/stock-items.cpp:73 +#: ../../po/../src/ui/stock-items.cpp:74 ../../po/../src/ui/stock-items.cpp:75 +#: ../../po/../src/ui/stock-items.cpp:76 ../../po/../src/ui/stock-items.cpp:77 +#: ../../po/../src/ui/stock-items.cpp:78 ../../po/../src/ui/stock-items.cpp:79 +#: ../../po/../src/ui/stock-items.cpp:80 ../../po/../src/ui/stock-items.cpp:81 +#: ../../po/../src/ui/stock-items.cpp:82 ../../po/../src/ui/stock-items.cpp:83 +#: ../../po/../src/ui/stock-items.cpp:84 ../../po/../src/ui/stock-items.cpp:85 +#: ../../po/../src/ui/stock-items.cpp:86 ../../po/../src/ui/stock-items.cpp:87 +#: ../../po/../src/ui/stock-items.cpp:88 ../../po/../src/ui/stock-items.cpp:89 +#: ../../po/../src/ui/stock-items.cpp:92 ../../po/../src/ui/stock-items.cpp:93 +#: ../../po/../src/ui/stock-items.cpp:94 ../../po/../src/ui/stock-items.cpp:95 +#: ../../po/../src/ui/stock-items.cpp:96 ../../po/../src/ui/stock-items.cpp:97 +#: ../../po/../src/ui/stock-items.cpp:98 ../../po/../src/ui/stock-items.cpp:99 +#: ../../po/../src/ui/stock-items.cpp:100 +#: ../../po/../src/ui/stock-items.cpp:101 +#: ../../po/../src/ui/stock-items.cpp:102 +#: ../../po/../src/ui/stock-items.cpp:103 +#: ../../po/../src/ui/stock-items.cpp:104 +#: ../../po/../src/ui/stock-items.cpp:105 +#: ../../po/../src/ui/stock-items.cpp:108 +#: ../../po/../src/ui/stock-items.cpp:109 +#: ../../po/../src/ui/stock-items.cpp:110 +#: ../../po/../src/ui/stock-items.cpp:111 +#: ../../po/../src/ui/stock-items.cpp:112 +#: ../../po/../src/ui/stock-items.cpp:113 +#: ../../po/../src/ui/stock-items.cpp:114 +#: ../../po/../src/ui/stock-items.cpp:115 +#: ../../po/../src/ui/stock-items.cpp:116 +#: ../../po/../src/ui/stock-items.cpp:117 +#: ../../po/../src/ui/stock-items.cpp:118 +#: ../../po/../src/ui/stock-items.cpp:119 +#: ../../po/../src/ui/stock-items.cpp:120 +#: ../../po/../src/ui/stock-items.cpp:121 +#: ../../po/../src/ui/stock-items.cpp:122 +#: ../../po/../src/ui/stock-items.cpp:123 +#: ../../po/../src/ui/stock-items.cpp:124 +#: ../../po/../src/ui/stock-items.cpp:125 +#: ../../po/../src/ui/stock-items.cpp:126 +#: ../../po/../src/ui/stock-items.cpp:127 +#: ../../po/../src/ui/stock-items.cpp:130 +#: ../../po/../src/ui/stock-items.cpp:131 +#: ../../po/../src/ui/stock-items.cpp:132 +#: ../../po/../src/ui/stock-items.cpp:133 +#: ../../po/../src/ui/stock-items.cpp:134 +#: ../../po/../src/ui/stock-items.cpp:135 +#: ../../po/../src/ui/stock-items.cpp:136 +#: ../../po/../src/ui/stock-items.cpp:137 +#: ../../po/../src/ui/stock-items.cpp:138 +#: ../../po/../src/ui/stock-items.cpp:139 +#: ../../po/../src/ui/stock-items.cpp:140 +#: ../../po/../src/ui/stock-items.cpp:141 +#: ../../po/../src/ui/stock-items.cpp:142 +#: ../../po/../src/ui/stock-items.cpp:143 +#: ../../po/../src/ui/stock-items.cpp:144 +#: ../../po/../src/ui/stock-items.cpp:145 +#: ../../po/../src/ui/stock-items.cpp:146 +#: ../../po/../src/ui/stock-items.cpp:150 +#: ../../po/../src/ui/stock-items.cpp:151 +#: ../../po/../src/ui/stock-items.cpp:152 +#: ../../po/../src/ui/stock-items.cpp:153 +#: ../../po/../src/ui/stock-items.cpp:156 +#: ../../po/../src/ui/stock-items.cpp:157 +#: ../../po/../src/ui/stock-items.cpp:158 +#: ../../po/../src/ui/stock-items.cpp:161 +#: ../../po/../src/ui/stock-items.cpp:162 +#: ../../po/../src/ui/stock-items.cpp:163 +#: ../../po/../src/ui/stock-items.cpp:164 +#: ../../po/../src/ui/stock-items.cpp:165 +#: ../../po/../src/ui/stock-items.cpp:166 +#: ../../po/../src/ui/stock-items.cpp:167 +#: ../../po/../src/ui/stock-items.cpp:168 +#: ../../po/../src/ui/stock-items.cpp:169 +#: ../../po/../src/ui/stock-items.cpp:170 +#: ../../po/../src/ui/stock-items.cpp:171 +#: ../../po/../src/ui/stock-items.cpp:172 +#: ../../po/../src/ui/stock-items.cpp:175 +#: ../../po/../src/ui/stock-items.cpp:176 +#: ../../po/../src/ui/stock-items.cpp:177 +#: ../../po/../src/ui/stock-items.cpp:178 +#: ../../po/../src/ui/stock-items.cpp:181 +#: ../../po/../src/ui/stock-items.cpp:182 +#: ../../po/../src/ui/stock-items.cpp:183 +#: ../../po/../src/ui/stock-items.cpp:184 +#: ../../po/../src/ui/stock-items.cpp:185 +#: ../../po/../src/ui/stock-items.cpp:186 +#: ../../po/../src/ui/stock-items.cpp:187 +#: ../../po/../src/ui/stock-items.cpp:188 +#: ../../po/../src/ui/stock-items.cpp:189 +#: ../../po/../src/ui/stock-items.cpp:190 +#: ../../po/../src/ui/stock-items.cpp:191 +#: ../../po/../src/ui/stock-items.cpp:194 +#: ../../po/../src/ui/stock-items.cpp:195 +#: ../../po/../src/ui/stock-items.cpp:198 +#: ../../po/../src/ui/stock-items.cpp:199 +#: ../../po/../src/ui/stock-items.cpp:200 +#: ../../po/../src/ui/stock-items.cpp:201 +#: ../../po/../src/ui/stock-items.cpp:202 +msgid "PLACEHOLDER, do not translate" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:88 +msgid "small" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:89 +msgid "medium" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:90 +#, fuzzy +msgid "large" +msgstr "MÃ¥l:" + +#: ../../po/../src/ui/widget/panel.cpp:91 +msgid "huge" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:106 +#, fuzzy +msgid "List" +msgstr "tommer" + +#: ../../po/../src/ui/widget/selected-style.cpp:67 +msgid "F:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:68 +msgid "S:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:69 +msgid "O:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:95 +msgid "N/A" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:98 +#: ../../po/../src/ui/widget/selected-style.cpp:712 +#, fuzzy +msgid "Nothing selected" +msgstr "Slet valgte knuder" + +#: ../../po/../src/ui/widget/selected-style.cpp:103 +msgid "No fill" +msgstr "Uden fyld" + +#: ../../po/../src/ui/widget/selected-style.cpp:103 +#, fuzzy +msgid "No stroke" +msgstr "Er skraveret" + +#: ../../po/../src/ui/widget/selected-style.cpp:105 +#: ../../po/../src/widgets/paint-selector.cpp:190 +#, fuzzy +msgid "Pattern" +msgstr "Mønsterfyld" + +#: ../../po/../src/ui/widget/selected-style.cpp:108 +#: ../../po/../src/widgets/paint-selector.cpp:885 +#, fuzzy +msgid "Pattern fill" +msgstr "Mønsterfyld" + +#: ../../po/../src/ui/widget/selected-style.cpp:108 +#, fuzzy +msgid "Pattern stroke" +msgstr "Mønsterfyld" + +#: ../../po/../src/ui/widget/selected-style.cpp:110 +#, fuzzy +msgid "L Gradient" +msgstr "Gradient fyld" + +#: ../../po/../src/ui/widget/selected-style.cpp:113 +#, fuzzy +msgid "Linear gradient fill" +msgstr "Tilføj ny farveovergang" + +#: ../../po/../src/ui/widget/selected-style.cpp:113 +#, fuzzy +msgid "Linear gradient stroke" +msgstr "Tilføj ny farveovergang" + +#: ../../po/../src/ui/widget/selected-style.cpp:115 +#, fuzzy +msgid "R Gradient" +msgstr "Gradient fyld" + +#: ../../po/../src/ui/widget/selected-style.cpp:118 +#, fuzzy +msgid "Radial gradient fill" +msgstr "Tilføj ny farveovergang" + +#: ../../po/../src/ui/widget/selected-style.cpp:118 +#, fuzzy +msgid "Radial gradient stroke" +msgstr "Tilføj ny farveovergang" + +#: ../../po/../src/ui/widget/selected-style.cpp:120 +#, fuzzy +msgid "Different" +msgstr "Drad" + +#: ../../po/../src/ui/widget/selected-style.cpp:123 +#, fuzzy +msgid "Different fills" +msgstr "Drad" + +#: ../../po/../src/ui/widget/selected-style.cpp:123 +#, fuzzy +msgid "Different strokes" +msgstr "Drad" + +#: ../../po/../src/ui/widget/selected-style.cpp:125 +#, fuzzy +msgid "Unset" +msgstr "tommer" + +#. TRANSLATORS COMMENT: unset is a verb here +#: ../../po/../src/ui/widget/selected-style.cpp:128 +#: ../../po/../src/ui/widget/selected-style.cpp:182 +#, fuzzy +msgid "Unset fill" +msgstr "_Fil" + +#: ../../po/../src/ui/widget/selected-style.cpp:128 +#: ../../po/../src/ui/widget/selected-style.cpp:182 +#, fuzzy +msgid "Unset stroke" +msgstr "Er skraveret" + +#: ../../po/../src/ui/widget/selected-style.cpp:131 +#, fuzzy +msgid "Flat color fill" +msgstr "Ensfarvet" + +#: ../../po/../src/ui/widget/selected-style.cpp:131 +#, fuzzy +msgid "Flat color stroke" +msgstr "Ensfarvet" + +#. TRANSLATOR COMMENT: A means "Averaged" +#: ../../po/../src/ui/widget/selected-style.cpp:134 +#, fuzzy +msgid "A" +msgstr "A4" + +#: ../../po/../src/ui/widget/selected-style.cpp:137 +#, fuzzy +msgid "Fill is averaged over selected objects" +msgstr "Redigér udformning for valgte ting" + +#: ../../po/../src/ui/widget/selected-style.cpp:137 +#, fuzzy +msgid "Stroke is averaged over selected objects" +msgstr "Redigér stregningsstil for valgte ting" + +#. TRANSLATOR COMMENT: M means "Multiple" +#: ../../po/../src/ui/widget/selected-style.cpp:140 +msgid "M" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:143 +#, fuzzy +msgid "Multiple selected objects have the same fill" +msgstr "Vend valgte ting" + +#: ../../po/../src/ui/widget/selected-style.cpp:143 +#, fuzzy +msgid "Multiple selected objects have the same stroke" +msgstr "Vend valgte ting" + +#: ../../po/../src/ui/widget/selected-style.cpp:145 +#, fuzzy +msgid "Edit fill..." +msgstr "Redigering" + +#: ../../po/../src/ui/widget/selected-style.cpp:145 +#, fuzzy +msgid "Edit stroke..." +msgstr "Redigering" + +#: ../../po/../src/ui/widget/selected-style.cpp:149 +#, fuzzy +msgid "Last set color" +msgstr "Ensfarvet" + +#: ../../po/../src/ui/widget/selected-style.cpp:153 +#, fuzzy +msgid "Last selected color" +msgstr "Sidste valgt" + +#: ../../po/../src/ui/widget/selected-style.cpp:157 +msgid "White" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:161 +#: ../../po/../src/widgets/sp-color-scales.cpp:461 +#: ../../po/../src/widgets/sp-color-scales.cpp:462 +#, fuzzy +msgid "Black" +msgstr "Sort:" + +#: ../../po/../src/ui/widget/selected-style.cpp:165 +#, fuzzy +msgid "Copy color" +msgstr "Startfarve" + +#: ../../po/../src/ui/widget/selected-style.cpp:169 +#, fuzzy +msgid "Paste color" +msgstr "Ensfarvet" + +#: ../../po/../src/ui/widget/selected-style.cpp:173 +#, fuzzy +msgid "Swap fill and stroke" +msgstr "Skrivebordets indstilinger" + +#: ../../po/../src/ui/widget/selected-style.cpp:177 +msgid "Make fill opaque" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:177 +msgid "Make stroke opaque" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:186 +#, fuzzy +msgid "Remove fill" +msgstr "Fjern lænke" + +#: ../../po/../src/ui/widget/selected-style.cpp:186 +#, fuzzy +msgid "Remove stroke" +msgstr "Fjern lænke" + +#: ../../po/../src/ui/widget/selected-style.cpp:718 +#, fuzzy +msgid "Master opacity" +msgstr "Uigennemskuelighed:" + +#: ../../po/../src/ui/widget/selected-style.cpp:744 +msgid "0 (transparent)" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:768 +msgid "1.0 (opaque)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1046 +msgid "Moved to next layer." +msgstr "" + +#: ../../po/../src/verbs.cpp:1048 +msgid "Cannot move past last layer." +msgstr "" + +#: ../../po/../src/verbs.cpp:1057 +msgid "Moved to previous layer." +msgstr "" + +#: ../../po/../src/verbs.cpp:1059 +msgid "Cannot move past first layer." +msgstr "" + +#: ../../po/../src/verbs.cpp:1076 ../../po/../src/verbs.cpp:1150 +#, fuzzy +msgid "No current layer." +msgstr "Dokument" + +#: ../../po/../src/verbs.cpp:1105 +#, fuzzy, c-format +msgid "Raised layer %s." +msgstr "Radius:" + +#: ../../po/../src/verbs.cpp:1109 +#, fuzzy, c-format +msgid "Lowered layer %s." +msgstr "Vælg" + +#: ../../po/../src/verbs.cpp:1118 +msgid "Cannot move layer any further." +msgstr "" + +#. TRANSLATORS: this means "The layer has been deleted." +#: ../../po/../src/verbs.cpp:1148 +#, fuzzy +msgid "Deleted layer." +msgstr "Vælg" + +#: ../../po/../src/verbs.cpp:1544 +msgid "" +"You need to connect to a Jabber server before sharing a document with " +"another user." +msgstr "" + +#: ../../po/../src/verbs.cpp:1559 +msgid "" +"You need to connect to a Jabber server before sharing a document with a " +"chatroom." +msgstr "" + +#: ../../po/../src/verbs.cpp:1569 +msgid "XML node tracker has not been initialized; nothing to dump" +msgstr "" + +#. TRANSLATORS: If you have translated the keys.svg file to your language, then +#. translate this string as "keys.LANG.svg" (where LANG is your language code); +#. otherwise leave as "keys.svg". +#: ../../po/../src/verbs.cpp:1631 +msgid "keys.svg" +msgstr "" + +#. TRANSLATORS: If you have translated the tutorial-basic.svg file to your language, +#. then translate this string as "tutorial-basic.LANG.svg" (where LANG is your language +#. code); otherwise leave as "tutorial-basic.svg". +#: ../../po/../src/verbs.cpp:1667 +msgid "tutorial-basic.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1671 +msgid "tutorial-shapes.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1675 +msgid "tutorial-advanced.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1679 +msgid "tutorial-tracing.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1683 +msgid "tutorial-calligraphy.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1687 +msgid "tutorial-elements.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1691 +msgid "tutorial-tips.svg" +msgstr "" + +#: ../../po/../src/verbs.cpp:1842 +msgid "Does nothing" +msgstr "" + +#. File +#: ../../po/../src/verbs.cpp:1845 +#, fuzzy +msgid "Default" +msgstr "Slet" + +#: ../../po/../src/verbs.cpp:1845 +#, fuzzy +msgid "Create new document from default template" +msgstr "Lagret dokument %d" + +#: ../../po/../src/verbs.cpp:1847 +#, fuzzy +msgid "_Open..." +msgstr "_Åbn" + +#: ../../po/../src/verbs.cpp:1848 +#, fuzzy +msgid "Open existing document" +msgstr "Unavngivet dokument %d" + +#: ../../po/../src/verbs.cpp:1849 +#, fuzzy +msgid "Re_vert" +msgstr "Nulstil" + +#: ../../po/../src/verbs.cpp:1850 +msgid "Revert to the last saved version of document (changes will be lost)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1851 +#, fuzzy +msgid "_Save" +msgstr "Gem" + +#: ../../po/../src/verbs.cpp:1851 +#, fuzzy +msgid "Save document" +msgstr "Lagret dokument %d" + +#: ../../po/../src/verbs.cpp:1853 +#, fuzzy +msgid "Save _As..." +msgstr "Gem" + +#: ../../po/../src/verbs.cpp:1854 +#, fuzzy +msgid "Save document under new name" +msgstr "Gem tegning under nyt filnavn" + +#: ../../po/../src/verbs.cpp:1855 +#, fuzzy +msgid "_Print..." +msgstr "Punkt" + +#: ../../po/../src/verbs.cpp:1855 +#, fuzzy +msgid "Print document" +msgstr "Unavngivet dokument %d" + +#. TRANSLATORS: "Vacuum Defs" means "Clean up defs" (so as to remove unused definitions) +#: ../../po/../src/verbs.cpp:1858 +msgid "Vac_uum Defs" +msgstr "" + +#: ../../po/../src/verbs.cpp:1858 +msgid "Remove unused predefined items from the <defs> of the document" +msgstr "" + +#: ../../po/../src/verbs.cpp:1860 +#, fuzzy +msgid "Print _Direct" +msgstr "Egenskaber for lænke" + +#: ../../po/../src/verbs.cpp:1861 +msgid "Print directly without prompting to a file or pipe" +msgstr "" + +#: ../../po/../src/verbs.cpp:1862 +#, fuzzy +msgid "Print Previe_w" +msgstr "Nyt smugkig" + +#: ../../po/../src/verbs.cpp:1863 +#, fuzzy +msgid "Preview document printout" +msgstr "Smugkig udskriftstegning" + +#: ../../po/../src/verbs.cpp:1864 +#, fuzzy +msgid "_Import..." +msgstr "Importér" + +#: ../../po/../src/verbs.cpp:1865 +msgid "Import bitmap or SVG image into document" +msgstr "" + +#: ../../po/../src/verbs.cpp:1866 +#, fuzzy +msgid "_Export Bitmap..." +msgstr "Eksportér fil" + +#: ../../po/../src/verbs.cpp:1867 +#, fuzzy +msgid "Export document or selection as a bitmap image" +msgstr "Eksportér billede til png" + +#: ../../po/../src/verbs.cpp:1868 +#, fuzzy +msgid "N_ext Window" +msgstr "Luk vindue" + +#: ../../po/../src/verbs.cpp:1869 +msgid "Switch to the next document window" +msgstr "" + +#: ../../po/../src/verbs.cpp:1870 +#, fuzzy +msgid "P_revious Window" +msgstr "Luk vindue" + +#: ../../po/../src/verbs.cpp:1871 +msgid "Switch to the previous document window" +msgstr "" + +#: ../../po/../src/verbs.cpp:1872 +#, fuzzy +msgid "_Close" +msgstr "Luk vindue" + +#: ../../po/../src/verbs.cpp:1873 +#, fuzzy +msgid "Close window" +msgstr "Luk vindue" + +#: ../../po/../src/verbs.cpp:1874 +#, fuzzy +msgid "_Quit" +msgstr "_Afslut" + +#: ../../po/../src/verbs.cpp:1874 +#, fuzzy +msgid "Quit Inkscape" +msgstr "Sodipodi: %s: %s: %d" + +#. Edit +#: ../../po/../src/verbs.cpp:1877 +#, fuzzy +msgid "_Undo" +msgstr "Fortryd " + +#: ../../po/../src/verbs.cpp:1877 +#, fuzzy +msgid "Undo last action" +msgstr "Nulstil transformation" + +#: ../../po/../src/verbs.cpp:1879 +#, fuzzy +msgid "_Redo" +msgstr "Genopret" + +#: ../../po/../src/verbs.cpp:1880 +msgid "Do again last undone action" +msgstr "" + +#: ../../po/../src/verbs.cpp:1881 +#, fuzzy +msgid "Cu_t" +msgstr "Klip" + +#: ../../po/../src/verbs.cpp:1882 +#, fuzzy +msgid "Cut selection to clipboard" +msgstr "Omform valgte ting til kurver" + +#: ../../po/../src/verbs.cpp:1883 +#, fuzzy +msgid "_Copy" +msgstr "Kopiér" + +#: ../../po/../src/verbs.cpp:1884 +#, fuzzy +msgid "Copy selection to clipboard" +msgstr "Kopiér det markerede til klippebord" + +#: ../../po/../src/verbs.cpp:1885 +#, fuzzy +msgid "_Paste" +msgstr "Indsæt" + +#: ../../po/../src/verbs.cpp:1886 +#, fuzzy +msgid "Paste objects from clipboard to mouse point" +msgstr "Indsæt fra klippebord" + +#: ../../po/../src/verbs.cpp:1887 +#, fuzzy +msgid "Paste _Style" +msgstr "Bredde pÃ¥ strøg" + +#: ../../po/../src/verbs.cpp:1888 +#, fuzzy +msgid "Apply style of the copied object to selection" +msgstr "Kopiér det markerede til klippebord" + +#: ../../po/../src/verbs.cpp:1889 +#, fuzzy +msgid "Paste _In Place" +msgstr "Bredde pÃ¥ strøg" + +#: ../../po/../src/verbs.cpp:1890 +#, fuzzy +msgid "Paste objects from clipboard to the original location" +msgstr "Justér objekter til vandret midte" + +#: ../../po/../src/verbs.cpp:1891 +#, fuzzy +msgid "_Delete" +msgstr "Slet" + +#: ../../po/../src/verbs.cpp:1892 +#, fuzzy +msgid "Delete selection" +msgstr "Duplikér det markerede" + +#: ../../po/../src/verbs.cpp:1893 +#, fuzzy +msgid "Duplic_ate" +msgstr "Duplikér" + +#: ../../po/../src/verbs.cpp:1894 +#, fuzzy +msgid "Duplicate selected objects" +msgstr "Vend valgte ting" + +#: ../../po/../src/verbs.cpp:1895 +#, fuzzy +msgid "Clo_ne" +msgstr "Luk vindue" + +#: ../../po/../src/verbs.cpp:1896 +msgid "Create a clone of selected object (a copy linked to the original)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1897 +msgid "Unlin_k Clone" +msgstr "" + +#: ../../po/../src/verbs.cpp:1898 +msgid "Cut the clone's link to its original" +msgstr "" + +#: ../../po/../src/verbs.cpp:1899 +#, fuzzy +msgid "Select _Original" +msgstr "Vælg" + +#: ../../po/../src/verbs.cpp:1900 +#, fuzzy +msgid "Select the object to which the clone is linked" +msgstr "Omform valgte ting til kurver" + +#. TRANSLATORS: Convert selection to a rectangle with tiled pattern fill +#: ../../po/../src/verbs.cpp:1902 +#, fuzzy +msgid "O_bjects to Pattern" +msgstr "Nulstil transformation" + +#: ../../po/../src/verbs.cpp:1903 +msgid "Convert selection to a rectangle with tiled pattern fill" +msgstr "" + +#. TRANSLATORS: Extract objects from a tiled pattern fill +#: ../../po/../src/verbs.cpp:1905 +#, fuzzy +msgid "Pattern to Ob_jects" +msgstr "Vend valgte ting" + +#: ../../po/../src/verbs.cpp:1906 +msgid "Extract objects from a tiled pattern fill" +msgstr "" + +#: ../../po/../src/verbs.cpp:1907 +#, fuzzy +msgid "Clea_r All" +msgstr "Farvefyld" + +#: ../../po/../src/verbs.cpp:1908 +msgid "Delete all objects from document" +msgstr "" + +#: ../../po/../src/verbs.cpp:1909 +#, fuzzy +msgid "Select Al_l" +msgstr "Vælg" + +#: ../../po/../src/verbs.cpp:1910 +#, fuzzy +msgid "Select all objects or all nodes" +msgstr "Vend valgte ting" + +#: ../../po/../src/verbs.cpp:1911 +#, fuzzy +msgid "Select All in All La_yers" +msgstr "Vælg" + +#: ../../po/../src/verbs.cpp:1912 +#, fuzzy +msgid "Select all objects in all visible and unlocked layers" +msgstr "Vend valgte ting" + +#: ../../po/../src/verbs.cpp:1913 +#, fuzzy +msgid "In_vert Selection" +msgstr "Valg" + +#: ../../po/../src/verbs.cpp:1914 +msgid "Invert selection (unselect what is selected and select everything else)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1915 +msgid "Invert in All Layers" +msgstr "" + +#: ../../po/../src/verbs.cpp:1916 +msgid "Invert selection in all visible and unlocked layers" +msgstr "" + +#: ../../po/../src/verbs.cpp:1917 +#, fuzzy +msgid "D_eselect" +msgstr "Vælg" + +#: ../../po/../src/verbs.cpp:1918 +#, fuzzy +msgid "Deselect any selected objects or nodes" +msgstr "Slet valgte knuder" + +#. Selection +#: ../../po/../src/verbs.cpp:1921 +#, fuzzy +msgid "Raise to _Top" +msgstr "Hæv det valgte op til toppen" + +#: ../../po/../src/verbs.cpp:1922 +#, fuzzy +msgid "Raise selection to top" +msgstr "Hæv det valgte op til toppen" + +#: ../../po/../src/verbs.cpp:1923 +#, fuzzy +msgid "Lower to _Bottom" +msgstr "Sænk det valgte til bunden" + +#: ../../po/../src/verbs.cpp:1924 +#, fuzzy +msgid "Lower selection to bottom" +msgstr "Sænk det valgte til bunden" + +#: ../../po/../src/verbs.cpp:1925 +#, fuzzy +msgid "_Raise" +msgstr "Radius:" + +#: ../../po/../src/verbs.cpp:1926 +#, fuzzy +msgid "Raise selection one step" +msgstr "Hæv det valgte op ét lag" + +#: ../../po/../src/verbs.cpp:1927 +msgid "_Lower" +msgstr "" + +#: ../../po/../src/verbs.cpp:1928 +#, fuzzy +msgid "Lower selection one step" +msgstr "Sænk det valgte ét lag" + +#: ../../po/../src/verbs.cpp:1929 +msgid "_Group" +msgstr "_Gruppér" + +#: ../../po/../src/verbs.cpp:1930 +msgid "Group selected objects" +msgstr "Gruppér valgte ting" + +#: ../../po/../src/verbs.cpp:1932 +#, fuzzy +msgid "Ungroup selected groups" +msgstr "Deler valgte ting op" + +#: ../../po/../src/verbs.cpp:1934 +#, fuzzy +msgid "_Put on Path" +msgstr "Omform valgte ting til kurver" + +#: ../../po/../src/verbs.cpp:1935 +#, fuzzy +msgid "Put text on path" +msgstr "Omform valgte ting til kurver" + +#: ../../po/../src/verbs.cpp:1936 +#, fuzzy +msgid "_Remove from Path" +msgstr "Fjern transformation" + +#: ../../po/../src/verbs.cpp:1937 +#, fuzzy +msgid "Remove text from path" +msgstr "Omform valgte ting til kurver" + +#: ../../po/../src/verbs.cpp:1938 +msgid "Remove Manual _Kerns" +msgstr "" + +#. TRANSLATORS: "glyph": An image used in the visual representation of characters; +#. roughly speaking, how a character looks. A font is a set of glyphs. +#: ../../po/../src/verbs.cpp:1941 +#, fuzzy +msgid "Remove all manual kerns and glyph rotations from a text object" +msgstr "Fjern transformation" + +#: ../../po/../src/verbs.cpp:1943 +#, fuzzy +msgid "_Union" +msgstr "ingen" + +#: ../../po/../src/verbs.cpp:1944 +#, fuzzy +msgid "Union of selected objects" +msgstr "Deler valgte ting op" + +#: ../../po/../src/verbs.cpp:1945 +#, fuzzy +msgid "_Intersection" +msgstr "_Interaktiv" + +#: ../../po/../src/verbs.cpp:1946 +#, fuzzy +msgid "Intersection of selected objects" +msgstr "Slet valgte knuder" + +#: ../../po/../src/verbs.cpp:1947 +#, fuzzy +msgid "_Difference" +msgstr "Drad" + +#: ../../po/../src/verbs.cpp:1948 +#, fuzzy +msgid "Difference of selected objects (bottom minus top)" +msgstr "Slet valgte knuder" + +#: ../../po/../src/verbs.cpp:1949 +#, fuzzy +msgid "E_xclusion" +msgstr "Ekspansion:" + +#: ../../po/../src/verbs.cpp:1950 +#, fuzzy +msgid "Exclusive OR of selected objects" +msgstr "Redigér udformning for valgte ting" + +#: ../../po/../src/verbs.cpp:1951 +#, fuzzy +msgid "Di_vision" +msgstr "Dimension" + +#: ../../po/../src/verbs.cpp:1952 +msgid "Cut the bottom object into pieces" +msgstr "" + +#. TRANSLATORS: "to cut a path" is not the same as "to break a path apart" - see the +#. Advanced tutorial for more info +#: ../../po/../src/verbs.cpp:1955 +#, fuzzy +msgid "Cut _Path" +msgstr "Forbind valgte stier" + +#: ../../po/../src/verbs.cpp:1956 +msgid "Cut the bottom object's stroke into pieces, removing fill" +msgstr "" + +#. TRANSLATORS: "outset": expand a shape by offsetting the object's path, +#. i.e. by displacing it perpendicular to the path in each point. +#. See also the Advanced Tutorial for explanation. +#: ../../po/../src/verbs.cpp:1960 +#, fuzzy +msgid "Outs_et" +msgstr "Forbind valgte stier" + +#: ../../po/../src/verbs.cpp:1961 +#, fuzzy +msgid "Outset selected paths" +msgstr "Forbind valgte stier" + +#: ../../po/../src/verbs.cpp:1963 +#, fuzzy +msgid "O_utset Path by 1 px" +msgstr "Forbind valgte stier" + +#: ../../po/../src/verbs.cpp:1964 +#, fuzzy +msgid "Outset selected paths by 1 px" +msgstr "Forbind valgte stier" + +#: ../../po/../src/verbs.cpp:1966 +#, fuzzy +msgid "O_utset Path by 10 px" +msgstr "Forbind valgte stier" + +#: ../../po/../src/verbs.cpp:1967 +#, fuzzy +msgid "Outset selected paths by 10 px" +msgstr "Forbind valgte stier" + +#. TRANSLATORS: "inset": contract a shape by offsetting the object's path, +#. i.e. by displacing it perpendicular to the path in each point. +#. See also the Advanced Tutorial for explanation. +#: ../../po/../src/verbs.cpp:1971 +msgid "I_nset" +msgstr "" + +#: ../../po/../src/verbs.cpp:1972 +#, fuzzy +msgid "Inset selected paths" +msgstr "Forbind valgte stier" + +#: ../../po/../src/verbs.cpp:1974 +#, fuzzy +msgid "I_nset Path by 1 px" +msgstr "Forbind valgte stier" + +#: ../../po/../src/verbs.cpp:1975 +#, fuzzy +msgid "Inset selected paths by 1 px" +msgstr "Forbind valgte stier" + +#: ../../po/../src/verbs.cpp:1977 +#, fuzzy +msgid "I_nset Path by 10 px" +msgstr "Forbind valgte stier" + +#: ../../po/../src/verbs.cpp:1978 +#, fuzzy +msgid "Inset selected paths by 10 px" +msgstr "Forbind valgte stier" + +#: ../../po/../src/verbs.cpp:1980 +#, fuzzy +msgid "D_ynamic Offset" +msgstr "Dynamisk udfyldning" + +#: ../../po/../src/verbs.cpp:1980 +msgid "Create a dynamic offset object" +msgstr "" + +#: ../../po/../src/verbs.cpp:1982 +msgid "_Linked Offset" +msgstr "" + +#: ../../po/../src/verbs.cpp:1983 +msgid "Create a dynamic offset object linked to the original path" +msgstr "" + +#: ../../po/../src/verbs.cpp:1985 +#, fuzzy +msgid "_Stroke to Path" +msgstr "Bredde pÃ¥ strøg" + +#: ../../po/../src/verbs.cpp:1986 +#, fuzzy +msgid "Convert selected strokes to paths" +msgstr "Omform valgte ting til kurver" + +#: ../../po/../src/verbs.cpp:1987 +#, fuzzy +msgid "Si_mplify" +msgstr "Forbind valgte stier" + +#: ../../po/../src/verbs.cpp:1988 +#, fuzzy +msgid "Simplify selected paths by removing extra nodes" +msgstr "Forbind valgte stier" + +#: ../../po/../src/verbs.cpp:1989 +#, fuzzy +msgid "_Reverse" +msgstr "Fil" + +#: ../../po/../src/verbs.cpp:1990 +#, fuzzy +msgid "Reverses the direction of selected paths; useful for flipping markers" +msgstr "Slet valgte knuder" + +#. TRANSLATORS: "to trace" means "to convert a bitmap to vector graphics" (to vectorize) +#: ../../po/../src/verbs.cpp:1992 +#, fuzzy +msgid "_Trace Bitmap" +msgstr "Beskadiget bitmap" + +#: ../../po/../src/verbs.cpp:1993 +#, fuzzy +msgid "Convert bitmap object to paths" +msgstr "Omform valgte ting til kurver" + +#: ../../po/../src/verbs.cpp:1994 +#, fuzzy +msgid "_Make a Bitmap Copy" +msgstr "Beskadiget bitmap" + +#: ../../po/../src/verbs.cpp:1995 +msgid "Export selection to a bitmap and insert it into document" +msgstr "" + +#: ../../po/../src/verbs.cpp:1996 +msgid "_Combine" +msgstr "_Kombinér" + +#: ../../po/../src/verbs.cpp:1997 +msgid "Combine several paths into one" +msgstr "" + +#. TRANSLATORS: "to cut a path" is not the same as "to break a path apart" - see the +#. Advanced tutorial for more info +#: ../../po/../src/verbs.cpp:2000 +#, fuzzy +msgid "Break _Apart" +msgstr "_Bryd op" + +#: ../../po/../src/verbs.cpp:2001 +#, fuzzy +msgid "Break selected paths into subpaths" +msgstr "Opbryd valgte knude" + +#: ../../po/../src/verbs.cpp:2002 +msgid "Gri_d Arrange..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2003 +msgid "Arrange selection in grid pattern" +msgstr "" + +#. Layer +#: ../../po/../src/verbs.cpp:2005 +#, fuzzy +msgid "_Add Layer..." +msgstr "Radius:" + +#: ../../po/../src/verbs.cpp:2006 +#, fuzzy +msgid "Create a new layer" +msgstr "Lagret dokument %d" + +#: ../../po/../src/verbs.cpp:2007 +#, fuzzy +msgid "Re_name Layer..." +msgstr "Radius:" + +#: ../../po/../src/verbs.cpp:2008 +#, fuzzy +msgid "Rename the current layer" +msgstr "Vælg" + +#: ../../po/../src/verbs.cpp:2009 +#, fuzzy +msgid "Switch to Layer Abov_e" +msgstr "Sænk det valgte til bunden" + +#: ../../po/../src/verbs.cpp:2010 +msgid "Switch to the layer above the current" +msgstr "" + +#: ../../po/../src/verbs.cpp:2011 +#, fuzzy +msgid "Switch to Layer Belo_w" +msgstr "Sænk det valgte ét lag" + +#: ../../po/../src/verbs.cpp:2012 +msgid "Switch to the layer below the current" +msgstr "" + +#: ../../po/../src/verbs.cpp:2013 +#, fuzzy +msgid "Move Selection to Layer Abo_ve" +msgstr "Sænk det valgte til bunden" + +#: ../../po/../src/verbs.cpp:2014 +msgid "Move selection to the layer above the current" +msgstr "" + +#: ../../po/../src/verbs.cpp:2015 +#, fuzzy +msgid "Move Selection to Layer Bel_ow" +msgstr "Sænk det valgte ét lag" + +#: ../../po/../src/verbs.cpp:2016 +msgid "Move selection to the layer below the current" +msgstr "" + +#: ../../po/../src/verbs.cpp:2017 +#, fuzzy +msgid "Layer to _Top" +msgstr "Hæv det valgte op til toppen" + +#: ../../po/../src/verbs.cpp:2018 +#, fuzzy +msgid "Raise the current layer to the top" +msgstr "Hæv det valgte op til toppen" + +#: ../../po/../src/verbs.cpp:2019 +#, fuzzy +msgid "Layer to _Bottom" +msgstr "Sænk det valgte til bunden" + +#: ../../po/../src/verbs.cpp:2020 +#, fuzzy +msgid "Lower the current layer to the bottom" +msgstr "Sænk det valgte til bunden" + +#: ../../po/../src/verbs.cpp:2021 +#, fuzzy +msgid "_Raise Layer" +msgstr "Radius:" + +#: ../../po/../src/verbs.cpp:2022 +msgid "Raise the current layer" +msgstr "" + +#: ../../po/../src/verbs.cpp:2023 +#, fuzzy +msgid "_Lower Layer" +msgstr "Vælg" + +#: ../../po/../src/verbs.cpp:2024 +msgid "Lower the current layer" +msgstr "" + +#: ../../po/../src/verbs.cpp:2025 +#, fuzzy +msgid "_Delete Current Layer" +msgstr "Vælg" + +#: ../../po/../src/verbs.cpp:2026 +#, fuzzy +msgid "Delete the current layer" +msgstr "Vælg" + +#. Object +#: ../../po/../src/verbs.cpp:2029 +#, fuzzy +msgid "Rotate _90° CW" +msgstr "Sæt vinkel til 90°" + +#: ../../po/../src/verbs.cpp:2030 +#, fuzzy +msgid "Rotate selection 90° clockwise" +msgstr "Drej valgte ting 90° med uret" + +#: ../../po/../src/verbs.cpp:2031 +#, fuzzy +msgid "Rotate 9_0° CCW" +msgstr "Sæt vinkel til 90°" + +#: ../../po/../src/verbs.cpp:2032 +#, fuzzy +msgid "Rotate selection 90° counter-clockwise" +msgstr "Drej valgte ting 90° med uret" + +#: ../../po/../src/verbs.cpp:2033 +#, fuzzy +msgid "Remove _Transformations" +msgstr "Fjern transformation" + +#: ../../po/../src/verbs.cpp:2034 +#, fuzzy +msgid "Remove transformations from object" +msgstr "Fjern transformation" + +#: ../../po/../src/verbs.cpp:2035 +#, fuzzy +msgid "_Object to Path" +msgstr "Nulstil transformation" + +#: ../../po/../src/verbs.cpp:2036 +#, fuzzy +msgid "Convert selected objects to paths" +msgstr "Omform valgte ting til kurver" + +#: ../../po/../src/verbs.cpp:2037 +msgid "_Flow into Frame" +msgstr "" + +#: ../../po/../src/verbs.cpp:2038 +#, fuzzy +msgid "Put text into frames" +msgstr "Omform valgte ting til kurver" + +#: ../../po/../src/verbs.cpp:2039 +#, fuzzy +msgid "_Unflow" +msgstr "Fortryd " + +#: ../../po/../src/verbs.cpp:2040 +msgid "Remove text from frame (creates a single-line text object)" +msgstr "" + +#: ../../po/../src/verbs.cpp:2041 +#, fuzzy +msgid "_Convert to Text" +msgstr "Omform valgte ting til kurver" + +#: ../../po/../src/verbs.cpp:2042 +#, fuzzy +msgid "Convert flowed text to regular text objects (preserves appearance)" +msgstr "Konvertér valgte segmenter til linier" + +#: ../../po/../src/verbs.cpp:2044 +#, fuzzy +msgid "Flip _Horizontal" +msgstr "vend vandret" + +#: ../../po/../src/verbs.cpp:2044 +#, fuzzy +msgid "Flips selected objects horizontally" +msgstr "Vend valgte ting" + +#: ../../po/../src/verbs.cpp:2047 +#, fuzzy +msgid "Flip _Vertical" +msgstr "vend lodret" + +#: ../../po/../src/verbs.cpp:2047 +#, fuzzy +msgid "Flips selected objects vertically" +msgstr "Vend valgte ting" + +#. Tools +#: ../../po/../src/verbs.cpp:2051 +msgid "Select" +msgstr "Vælg" + +#: ../../po/../src/verbs.cpp:2052 +#, fuzzy +msgid "Select and transform objects" +msgstr "Vælg og transformér" + +#: ../../po/../src/verbs.cpp:2053 +#, fuzzy +msgid "Node Edit" +msgstr "Noderedigering" + +#: ../../po/../src/verbs.cpp:2054 +#, fuzzy +msgid "Edit path nodes or control handles" +msgstr "Redigér udformning for valgte ting" + +#: ../../po/../src/verbs.cpp:2056 +#, fuzzy +msgid "Create rectangles and squares" +msgstr "Tegn firkant" + +#: ../../po/../src/verbs.cpp:2058 +msgid "Create circles, ellipses, and arcs" +msgstr "" + +#: ../../po/../src/verbs.cpp:2060 +msgid "Create stars and polygons" +msgstr "" + +#: ../../po/../src/verbs.cpp:2062 +#, fuzzy +msgid "Create spirals" +msgstr "Tegn spiral" + +#: ../../po/../src/verbs.cpp:2064 +#, fuzzy +msgid "Draw freehand lines" +msgstr "Tegn frihÃ¥ndslinje" + +#: ../../po/../src/verbs.cpp:2066 +#, fuzzy +msgid "Draw Bezier curves and straight lines" +msgstr "Tegn frihÃ¥ndslinje" + +#: ../../po/../src/verbs.cpp:2068 +msgid "Draw calligraphic lines" +msgstr "" + +#: ../../po/../src/verbs.cpp:2070 +#, fuzzy +msgid "Create and edit text objects" +msgstr "Tilføj attribut" + +#: ../../po/../src/verbs.cpp:2072 +#, fuzzy +msgid "Create and edit gradients" +msgstr "Tilføj attribut" + +#: ../../po/../src/verbs.cpp:2074 +#, fuzzy +msgid "Zoom in or out" +msgstr "Zoom ud" + +#: ../../po/../src/verbs.cpp:2076 +msgid "Pick averaged colors from image" +msgstr "" + +#: ../../po/../src/verbs.cpp:2078 +#, fuzzy +msgid "Create connectors" +msgstr "Lagret dokument %d" + +#. Tool prefs +#: ../../po/../src/verbs.cpp:2081 +msgid "Selector Preferences" +msgstr "" + +#: ../../po/../src/verbs.cpp:2082 +#, fuzzy +msgid "Open Preferences for the Selector tool" +msgstr "Sodipodi: %s: %s: %d" + +#: ../../po/../src/verbs.cpp:2083 +#, fuzzy +msgid "Node Tool Preferences" +msgstr "Element er en reference" + +#: ../../po/../src/verbs.cpp:2084 +#, fuzzy +msgid "Open Preferences for the Node tool" +msgstr "Sodipodi: %s: %s: %d" + +#: ../../po/../src/verbs.cpp:2085 +#, fuzzy +msgid "Rectangle Preferences" +msgstr "Egenskaber for firkant" + +#: ../../po/../src/verbs.cpp:2086 +#, fuzzy +msgid "Open Preferences for the Rectangle tool" +msgstr "Sodipodi: %s: %s: %d" + +#: ../../po/../src/verbs.cpp:2087 +#, fuzzy +msgid "Ellipse Preferences" +msgstr "Element er en reference" + +#: ../../po/../src/verbs.cpp:2088 +#, fuzzy +msgid "Open Preferences for the Ellipse tool" +msgstr "Sodipodi: %s: %s: %d" + +#: ../../po/../src/verbs.cpp:2089 +#, fuzzy +msgid "Star Preferences" +msgstr "Egenskaber for stjerne" + +#: ../../po/../src/verbs.cpp:2090 +#, fuzzy +msgid "Open Preferences for the Star tool" +msgstr "Sodipodi: %s: %s: %d" + +#: ../../po/../src/verbs.cpp:2091 +#, fuzzy +msgid "Spiral Preferences" +msgstr "Egenskaber for spiral" + +#: ../../po/../src/verbs.cpp:2092 +#, fuzzy +msgid "Open Preferences for the Spiral tool" +msgstr "Sodipodi: %s: %s: %d" + +#: ../../po/../src/verbs.cpp:2093 +#, fuzzy +msgid "Pencil Preferences" +msgstr "Element er en reference" + +#: ../../po/../src/verbs.cpp:2094 +#, fuzzy +msgid "Open Preferences for the Pencil tool" +msgstr "Sodipodi: %s: %s: %d" + +#: ../../po/../src/verbs.cpp:2095 +#, fuzzy +msgid "Pen Preferences" +msgstr "Element er en reference" + +#: ../../po/../src/verbs.cpp:2096 +#, fuzzy +msgid "Open Preferences for the Pen tool" +msgstr "Sodipodi: %s: %s: %d" + +#: ../../po/../src/verbs.cpp:2097 +msgid "Calligraphic Preferences" +msgstr "" + +#: ../../po/../src/verbs.cpp:2098 +#, fuzzy +msgid "Open Preferences for the Calligraphy tool" +msgstr "Sodipodi: %s: %s: %d" + +#: ../../po/../src/verbs.cpp:2099 +#, fuzzy +msgid "Text Preferences" +msgstr "Element er en reference" + +#: ../../po/../src/verbs.cpp:2100 +#, fuzzy +msgid "Open Preferences for the Text tool" +msgstr "Sodipodi: %s: %s: %d" + +#: ../../po/../src/verbs.cpp:2101 +#, fuzzy +msgid "Gradient Preferences" +msgstr "Element er en reference" + +#: ../../po/../src/verbs.cpp:2102 +#, fuzzy +msgid "Open Preferences for the Gradient tool" +msgstr "Sodipodi: %s: %s: %d" + +#: ../../po/../src/verbs.cpp:2103 +#, fuzzy +msgid "Zoom Preferences" +msgstr "Element er en reference" + +#: ../../po/../src/verbs.cpp:2104 +#, fuzzy +msgid "Open Preferences for the Zoom tool" +msgstr "Sodipodi: %s: %s: %d" + +#: ../../po/../src/verbs.cpp:2105 +#, fuzzy +msgid "Dropper Preferences" +msgstr "Sodipodi: %s: %s: %d" + +#: ../../po/../src/verbs.cpp:2106 +#, fuzzy +msgid "Open Preferences for the Dropper tool" +msgstr "Sodipodi: %s: %s: %d" + +#: ../../po/../src/verbs.cpp:2107 +#, fuzzy +msgid "Connector Preferences" +msgstr "Egenskaber for stjerne" + +#: ../../po/../src/verbs.cpp:2108 +#, fuzzy +msgid "Open Preferences for the Connector tool" +msgstr "Sodipodi: %s: %s: %d" + +#. Zoom/View +#: ../../po/../src/verbs.cpp:2111 +#, fuzzy +msgid "Zoom In" +msgstr "Zoom ind" + +#: ../../po/../src/verbs.cpp:2111 +msgid "Zoom in" +msgstr "Zoom ind" + +#: ../../po/../src/verbs.cpp:2112 +#, fuzzy +msgid "Zoom Out" +msgstr "Zoom ud" + +#: ../../po/../src/verbs.cpp:2112 +msgid "Zoom out" +msgstr "Zoom ud" + +#: ../../po/../src/verbs.cpp:2113 +#, fuzzy +msgid "_Rulers" +msgstr "Fil" + +#: ../../po/../src/verbs.cpp:2113 +#, fuzzy +msgid "Show or hide the canvas rulers" +msgstr "Vis hjælpelinier" + +#: ../../po/../src/verbs.cpp:2114 +msgid "Scroll_bars" +msgstr "" + +#: ../../po/../src/verbs.cpp:2114 +#, fuzzy +msgid "Show or hide the canvas scrollbars" +msgstr "Vis hjælpelinier" + +#: ../../po/../src/verbs.cpp:2115 +#, fuzzy +msgid "_Grid" +msgstr "Gitter" + +#: ../../po/../src/verbs.cpp:2116 +#, fuzzy +msgid "G_uides" +msgstr "Hjælpelinjer" + +#: ../../po/../src/verbs.cpp:2117 +msgid "Nex_t Zoom" +msgstr "" + +#: ../../po/../src/verbs.cpp:2117 +msgid "Next zoom (from the history of zooms)" +msgstr "" + +#: ../../po/../src/verbs.cpp:2119 +msgid "Pre_vious Zoom" +msgstr "" + +#: ../../po/../src/verbs.cpp:2119 +msgid "Previous zoom (from the history of zooms)" +msgstr "" + +#: ../../po/../src/verbs.cpp:2121 +#, fuzzy +msgid "Zoom 1:_1" +msgstr "Zoom til 1:1" + +#: ../../po/../src/verbs.cpp:2121 +msgid "Zoom to 1:1" +msgstr "Zoom til 1:1" + +#: ../../po/../src/verbs.cpp:2123 +#, fuzzy +msgid "Zoom 1:_2" +msgstr "Zoom til 1:2" + +#: ../../po/../src/verbs.cpp:2123 +msgid "Zoom to 1:2" +msgstr "Zoom til 1:2" + +#: ../../po/../src/verbs.cpp:2125 +#, fuzzy +msgid "_Zoom 2:1" +msgstr "Zoom til 2:1" + +#: ../../po/../src/verbs.cpp:2125 +msgid "Zoom to 2:1" +msgstr "Zoom til 2:1" + +#: ../../po/../src/verbs.cpp:2128 +msgid "_Fullscreen" +msgstr "" + +#: ../../po/../src/verbs.cpp:2128 +msgid "Stretch this document window to full screen" +msgstr "" + +#: ../../po/../src/verbs.cpp:2131 +#, fuzzy +msgid "Duplic_ate Window" +msgstr "Duplikér" + +#: ../../po/../src/verbs.cpp:2131 +#, fuzzy +msgid "Open a new window with the same document" +msgstr "Unavngivet dokument %d" + +#: ../../po/../src/verbs.cpp:2133 +#, fuzzy +msgid "_New View Preview" +msgstr "Nyt smugkig" + +#: ../../po/../src/verbs.cpp:2134 +#, fuzzy +msgid "New View Preview" +msgstr "Nyt smugkig" + +#. "view_new_preview" +#: ../../po/../src/verbs.cpp:2136 +msgid "_Normal" +msgstr "" + +#: ../../po/../src/verbs.cpp:2137 +msgid "Switch to normal display mode" +msgstr "" + +#: ../../po/../src/verbs.cpp:2138 +#, fuzzy +msgid "_Outline" +msgstr "Vis hjælpelinier" + +#: ../../po/../src/verbs.cpp:2139 +msgid "Switch to outline (wireframe) display mode" +msgstr "" + +#: ../../po/../src/verbs.cpp:2141 +#, fuzzy +msgid "Ico_n Preview" +msgstr "Nyt smugkig" + +#: ../../po/../src/verbs.cpp:2142 +msgid "Open a window to preview items at different icon resolutions" +msgstr "" + +#: ../../po/../src/verbs.cpp:2144 +#, fuzzy +msgid "Zoom to fit page in window" +msgstr "Sæt sidebredde" + +#: ../../po/../src/verbs.cpp:2145 +#, fuzzy +msgid "Page _Width" +msgstr "Sæt sidebredde" + +#: ../../po/../src/verbs.cpp:2146 +#, fuzzy +msgid "Zoom to fit page width in window" +msgstr "Sæt sidebredde" + +#: ../../po/../src/verbs.cpp:2148 +#, fuzzy +msgid "Zoom to fit drawing in window" +msgstr "Zoom til tegning" + +#: ../../po/../src/verbs.cpp:2150 +#, fuzzy +msgid "Zoom to fit selection in window" +msgstr "Hæv det valgte op til toppen" + +#. Dialogs +#: ../../po/../src/verbs.cpp:2153 +#, fuzzy +msgid "In_kscape Preferences..." +msgstr "Sodipodi: %s: %s: %d" + +#: ../../po/../src/verbs.cpp:2154 +#, fuzzy +msgid "Global Inkscape preferences" +msgstr "Indstillinger for skærm" + +#: ../../po/../src/verbs.cpp:2155 +msgid "_Document Preferences..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2156 +#, fuzzy +msgid "Preferences saved with the document" +msgstr "Unavngivet dokument %d" + +#: ../../po/../src/verbs.cpp:2157 +#, fuzzy +msgid "_Fill and Stroke..." +msgstr "Skrivebordets indstilinger" + +#: ../../po/../src/verbs.cpp:2158 +#, fuzzy +msgid "Fill and Stroke dialog" +msgstr "Skrivebordets indstilinger" + +#. TRANSLATORS: "Swatches" means: color samples +#: ../../po/../src/verbs.cpp:2160 +#, fuzzy +msgid "S_watches..." +msgstr "Gem" + +#: ../../po/../src/verbs.cpp:2161 +msgid "View color swatches" +msgstr "" + +#: ../../po/../src/verbs.cpp:2162 +#, fuzzy +msgid "Transfor_m..." +msgstr "Transformation" + +#: ../../po/../src/verbs.cpp:2163 +#, fuzzy +msgid "Transform dialog" +msgstr "Transformationsdialog" + +#: ../../po/../src/verbs.cpp:2164 +#, fuzzy +msgid "_Align and Distribute..." +msgstr "Attributter" + +#: ../../po/../src/verbs.cpp:2165 +#, fuzzy +msgid "Align and Distribute dialog" +msgstr "Attributter" + +#: ../../po/../src/verbs.cpp:2166 +#, fuzzy +msgid "_Text and Font..." +msgstr "Skrivebordets indstilinger" + +#: ../../po/../src/verbs.cpp:2167 +#, fuzzy +msgid "Text and Font dialog" +msgstr "Skrivebordets indstilinger" + +#: ../../po/../src/verbs.cpp:2168 +#, fuzzy +msgid "_XML Editor..." +msgstr "Redigering..." + +#: ../../po/../src/verbs.cpp:2169 +msgid "XML Editor" +msgstr "" + +#: ../../po/../src/verbs.cpp:2170 +#, fuzzy +msgid "_Find..." +msgstr "Punkt" + +#: ../../po/../src/verbs.cpp:2171 +#, fuzzy +msgid "Find objects in document" +msgstr "Unavngivet dokument %d" + +#: ../../po/../src/verbs.cpp:2172 +msgid "_Messages..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2173 +msgid "View debug messages" +msgstr "" + +#: ../../po/../src/verbs.cpp:2174 +#, fuzzy +msgid "S_cripts..." +msgstr "Punkt" + +#: ../../po/../src/verbs.cpp:2175 +#, fuzzy +msgid "Run scripts" +msgstr "Rund sammenlægning" + +#: ../../po/../src/verbs.cpp:2176 +#, fuzzy +msgid "Show/Hide D_ialogs" +msgstr "Luk dialog" + +#: ../../po/../src/verbs.cpp:2177 +msgid "Show or hide all active dialogs" +msgstr "" + +#. TRANSLATORS: "Tile clones" means: "Create tiled clones" +#: ../../po/../src/verbs.cpp:2179 +msgid "Tile clones..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2180 +msgid "Create and arrange multiple clones of selection" +msgstr "" + +#: ../../po/../src/verbs.cpp:2181 +#, fuzzy +msgid "_Object Properties..." +msgstr "egenskaber for objekt" + +#: ../../po/../src/verbs.cpp:2182 +#, fuzzy +msgid "Object Properties dialog" +msgstr "egenskaber for objekt" + +#: ../../po/../src/verbs.cpp:2185 +msgid "_Connect to Jabber server..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2185 +msgid "Connect to a Jabber server" +msgstr "" + +#: ../../po/../src/verbs.cpp:2187 +#, fuzzy +msgid "Share with _user..." +msgstr "Gem" + +#: ../../po/../src/verbs.cpp:2187 +msgid "Establish a whiteboard session with another Jabber user" +msgstr "" + +#: ../../po/../src/verbs.cpp:2189 +msgid "Share with _chatroom..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2189 +msgid "" +"Join a chatroom to start a new whiteboard session or join one in progress" +msgstr "" + +#: ../../po/../src/verbs.cpp:2191 +msgid "_Dump XML node tracker" +msgstr "" + +#: ../../po/../src/verbs.cpp:2191 +msgid "Dump the contents of the XML tracker to the console" +msgstr "" + +#: ../../po/../src/verbs.cpp:2193 +msgid "_Open session file..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2193 +msgid "Open and browse through records of past whiteboard sessions" +msgstr "" + +#: ../../po/../src/verbs.cpp:2195 +msgid "Session file playback" +msgstr "" + +#: ../../po/../src/verbs.cpp:2197 +msgid "_Disconnect from session" +msgstr "" + +#: ../../po/../src/verbs.cpp:2199 +msgid "Disconnect from _server" +msgstr "" + +#: ../../po/../src/verbs.cpp:2201 +msgid "_Input Devices..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2202 +msgid "Configure extended input devices" +msgstr "" + +#. Help +#: ../../po/../src/verbs.cpp:2205 +msgid "_Keys and Mouse" +msgstr "" + +#: ../../po/../src/verbs.cpp:2206 +msgid "Key and mouse shortcuts reference" +msgstr "" + +#: ../../po/../src/verbs.cpp:2207 +#, fuzzy +msgid "About E_xtensions" +msgstr "Ekspansion:" + +#: ../../po/../src/verbs.cpp:2208 +#, fuzzy +msgid "About Extensions..." +msgstr "Ekspansion:" + +#: ../../po/../src/verbs.cpp:2209 +#, fuzzy +msgid "About _Memory" +msgstr "Ekspansion:" + +#: ../../po/../src/verbs.cpp:2210 +#, fuzzy +msgid "About Memory..." +msgstr "_Om ..." + +#: ../../po/../src/verbs.cpp:2211 +msgid "_About Inkscape" +msgstr "" + +#. "help_about" +#. new HelpVerb(SP_VERB_SHOW_LICENSE, "ShowLicense", N_("Modifying or Redistributing Inkscape"), +#. N_("Show license to modify and/or redistribute Inkscape: GNU GPL"), NULL), +#. Tutorials +#: ../../po/../src/verbs.cpp:2217 +#, fuzzy +msgid "Inkscape: _Basic" +msgstr "Sodipodi: %s: %s: %d" + +#: ../../po/../src/verbs.cpp:2218 +msgid "Getting started with Inkscape" +msgstr "" + +#. "tutorial_basic" +#: ../../po/../src/verbs.cpp:2219 +#, fuzzy +msgid "Inkscape: _Shapes" +msgstr "Sodipodi: %s: %s: %d" + +#: ../../po/../src/verbs.cpp:2220 +msgid "Using shape tools to create and edit shapes" +msgstr "" + +#: ../../po/../src/verbs.cpp:2221 +#, fuzzy +msgid "Inkscape: _Advanced" +msgstr "Sodipodi: %s: %s: %d" + +#: ../../po/../src/verbs.cpp:2222 +#, fuzzy +msgid "Advanced Inkscape topics" +msgstr "Sodipodi: %s: %s: %d" + +#. "tutorial_advanced" +#. TRANSLATORS: "to trace" means "to convert a bitmap to vector graphics" (to vectorize) +#: ../../po/../src/verbs.cpp:2224 +#, fuzzy +msgid "Inkscape: T_racing" +msgstr "Sodipodi: %s: %s: %d" + +#: ../../po/../src/verbs.cpp:2225 +#, fuzzy +msgid "Using bitmap tracing" +msgstr "Billedstørrelse" + +#. "tutorial_tracing" +#: ../../po/../src/verbs.cpp:2226 +#, fuzzy +msgid "Inkscape: _Calligraphy" +msgstr "Sodipodi: %s: %s: %d" + +#: ../../po/../src/verbs.cpp:2227 +msgid "Using the Calligraphy pen tool" +msgstr "" + +#: ../../po/../src/verbs.cpp:2228 +msgid "_Elements of Design" +msgstr "" + +#: ../../po/../src/verbs.cpp:2229 +msgid "Principles of design in the tutorial form" +msgstr "" + +#. "tutorial_design" +#: ../../po/../src/verbs.cpp:2230 +msgid "_Tips and Tricks" +msgstr "" + +#: ../../po/../src/verbs.cpp:2231 +msgid "Miscellaneous tips and tricks" +msgstr "" + +#. "tutorial_tips" +#. Effect +#: ../../po/../src/verbs.cpp:2234 +msgid "Previous Effect" +msgstr "" + +#: ../../po/../src/verbs.cpp:2235 +msgid "Repeat the last effect with the same settings" +msgstr "" + +#. "tutorial_tips" +#: ../../po/../src/verbs.cpp:2236 +msgid "Previous Effect Settings..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2237 +msgid "Repeat the last effect with new settings" +msgstr "" + +#: ../../po/../src/widgets/dash-selector.cpp:106 +#, fuzzy +msgid "Dash pattern" +msgstr "Bredde pÃ¥ strøg" + +#: ../../po/../src/widgets/dash-selector.cpp:121 +#, fuzzy +msgid "Pattern offset" +msgstr "Mønsterfyld" + +#: ../../po/../src/widgets/desktop-widget.cpp:240 +#, fuzzy +msgid "Zoom drawing if window size changes" +msgstr "Zoom til tegning" + +#: ../../po/../src/widgets/desktop-widget.cpp:298 +msgid "Cursor coordinates" +msgstr "" + +#. display the initial welcome message in the statusbar +#: ../../po/../src/widgets/desktop-widget.cpp:324 +msgid "" +"Welcome to Inkscape! Use shape or freehand tools to create objects; " +"use selector (arrow) to move or transform them." +msgstr "" + +#: ../../po/../src/widgets/desktop-widget.cpp:372 +#, c-format +msgid "%s: %d - Inkscape" +msgstr "" + +#: ../../po/../src/widgets/desktop-widget.cpp:374 +#, c-format +msgid "%s - Inkscape" +msgstr "" + +#: ../../po/../src/widgets/desktop-widget.cpp:532 +#, c-format +msgid "" +"Save changes to document \"%s\" before " +"closing?\n" +"\n" +"If you close without saving, your changes will be discarded." +msgstr "" + +#: ../../po/../src/widgets/desktop-widget.cpp:548 +#: ../../po/../src/widgets/desktop-widget.cpp:612 +msgid "Close _without saving" +msgstr "" + +#: ../../po/../src/widgets/desktop-widget.cpp:595 +#, c-format +msgid "" +"The file \"%s\" was saved with a " +"format (%s) that may cause data loss!\n" +"\n" +"Do you want to save this file in another format?" +msgstr "" + +#. Family frame +#: ../../po/../src/widgets/font-selector.cpp:156 +msgid "Font family" +msgstr "" + +#. Style frame +#: ../../po/../src/widgets/font-selector.cpp:184 +#, fuzzy +msgid "Style" +msgstr " Stíl " + +#: ../../po/../src/widgets/font-selector.cpp:219 +#, fuzzy +msgid "Font size:" +msgstr "Gem ikke" + +#. TRANSLATORS: Test string used in text and font dialog (when no +#. * text has been entered) to get a preview of the font. Choose +#. * some representative characters that users of your locale will be +#. * interested in. +#: ../../po/../src/widgets/font-selector.cpp:554 +msgid "AaBbCcIiPpQq12368.;/()" +msgstr "" + +#: ../../po/../src/widgets/gradient-selector.cpp:137 +#: ../../po/../src/widgets/gradient-toolbar.cpp:524 +#, fuzzy +msgid "Duplicate" +msgstr "Duplikér" + +#: ../../po/../src/widgets/gradient-selector.cpp:142 +#: ../../po/../src/widgets/gradient-toolbar.cpp:535 +#, fuzzy +msgid "Edit..." +msgstr "Redigering" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/pservers.html#LinearGradientSpreadMethodAttribute +#: ../../po/../src/widgets/gradient-selector.cpp:159 +msgid "" +"Whether to fill with flat color beyond the ends of the gradient vector " +"(spreadMethod=\"pad\"), or repeat the gradient in the same direction " +"(spreadMethod=\"repeat\"), or repeat the gradient in alternating opposite " +"directions (spreadMethod=\"reflect\")" +msgstr "" + +#: ../../po/../src/widgets/gradient-selector.cpp:165 +#, fuzzy +msgid "none" +msgstr "Ingen" + +#: ../../po/../src/widgets/gradient-selector.cpp:169 +#, fuzzy +msgid "reflected" +msgstr "Første valgt" + +#: ../../po/../src/widgets/gradient-selector.cpp:173 +#, fuzzy +msgid "direct" +msgstr "Firkant" + +#: ../../po/../src/widgets/gradient-selector.cpp:181 +#, fuzzy +msgid "Repeat:" +msgstr "Nulstil" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:217 +msgid "No gradients" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:226 +#, fuzzy +msgid "Nothing selected" +msgstr "Sidste valgt" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:237 +#, fuzzy +msgid "No gradients in selection" +msgstr "Sidste valgt" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:247 +msgid "Multiple gradients" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:525 +msgid "" +"If the gradient is used by more than one object, create a copy of it for the " +"selected object(s)" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:536 +#, fuzzy +msgid "Edit the stops of the gradient" +msgstr "Tilføj ny farveovergang" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:593 +#: ../../po/../src/widgets/toolbox.cpp:1103 +#: ../../po/../src/widgets/toolbox.cpp:1192 +#: ../../po/../src/widgets/toolbox.cpp:1485 +#: ../../po/../src/widgets/toolbox.cpp:1534 +#: ../../po/../src/widgets/toolbox.cpp:1766 +#: ../../po/../src/widgets/toolbox.cpp:1801 +#: ../../po/../src/widgets/toolbox.cpp:2331 +#: ../../po/../src/widgets/toolbox.cpp:2370 +msgid "New:" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:606 +#, fuzzy +msgid "Create linear gradient" +msgstr "Tilføj ny farveovergang" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:620 +msgid "Create radial (elliptic or circular) gradient" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:635 +#, fuzzy +msgid "on" +msgstr "Ingen" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:648 +#, fuzzy +msgid "Create gradient in the fill" +msgstr "Gradientvektor" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:662 +msgid "Create gradient in the stroke" +msgstr "" + +#. FIXME: implement averaging of all parameters for multiple selected stars +#. gtk_label_set_markup(GTK_LABEL(l), _("Average:")); +#. FIXME: implement averaging of all parameters for multiple selected +#. gtk_label_set_markup(GTK_LABEL(l), _("Average:")); +#: ../../po/../src/widgets/gradient-toolbar.cpp:676 +#: ../../po/../src/widgets/toolbox.cpp:1105 +#: ../../po/../src/widgets/toolbox.cpp:1124 +#: ../../po/../src/widgets/toolbox.cpp:1493 +#: ../../po/../src/widgets/toolbox.cpp:1518 +#: ../../po/../src/widgets/toolbox.cpp:1768 +#: ../../po/../src/widgets/toolbox.cpp:1787 +#: ../../po/../src/widgets/toolbox.cpp:2334 +#: ../../po/../src/widgets/toolbox.cpp:2354 +#, fuzzy +msgid "Change:" +msgstr "Ændr" + +#: ../../po/../src/widgets/gradient-vector.cpp:269 +msgid "No gradients in document" +msgstr "" + +#: ../../po/../src/widgets/gradient-vector.cpp:275 +#, fuzzy +msgid "No gradient selected" +msgstr "Sidste valgt" + +#: ../../po/../src/widgets/gradient-vector.cpp:532 +#, fuzzy +msgid "No stops in gradient" +msgstr "Tilføj ny farveovergang" + +#. TRANSLATORS: "Stop" means: a "phase" of a gradient +#: ../../po/../src/widgets/gradient-vector.cpp:794 +#, fuzzy +msgid "Add stop" +msgstr "skrivebord" + +#: ../../po/../src/widgets/gradient-vector.cpp:797 +msgid "Add another control stop to gradient" +msgstr "" + +#: ../../po/../src/widgets/gradient-vector.cpp:799 +#, fuzzy +msgid "Delete stop" +msgstr "Slet det valgte" + +#: ../../po/../src/widgets/gradient-vector.cpp:802 +msgid "Delete current control stop from gradient" +msgstr "" + +#. Label +#: ../../po/../src/widgets/gradient-vector.cpp:813 +msgid "Offset:" +msgstr "" + +#. TRANSLATORS: "Stop" means: a "phase" of a gradient +#: ../../po/../src/widgets/gradient-vector.cpp:858 +#, fuzzy +msgid "Stop Color" +msgstr "Startfarve" + +#: ../../po/../src/widgets/gradient-vector.cpp:887 +#, fuzzy +msgid "Gradient editor" +msgstr "Gradientvektor" + +#: ../../po/../src/widgets/layer-selector.cpp:119 +#, fuzzy +msgid "Toggle current layer visibility" +msgstr "Dokument" + +#: ../../po/../src/widgets/layer-selector.cpp:139 +#, fuzzy +msgid "Lock or unlock current layer" +msgstr "Dokument" + +#: ../../po/../src/widgets/layer-selector.cpp:142 +#, fuzzy +msgid "Current layer" +msgstr "Dokument" + +#: ../../po/../src/widgets/layer-selector.cpp:553 +msgid "(root)" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:182 +#: ../../po/../src/widgets/paint-selector.cpp:561 +#, fuzzy +msgid "No paint" +msgstr "Punkt" + +#: ../../po/../src/widgets/paint-selector.cpp:184 +#: ../../po/../src/widgets/paint-selector.cpp:629 +#, fuzzy +msgid "Flat color" +msgstr "Ensfarvet" + +#: ../../po/../src/widgets/paint-selector.cpp:186 +#: ../../po/../src/widgets/paint-selector.cpp:696 +#, fuzzy +msgid "Linear gradient" +msgstr "Tilføj ny farveovergang" + +#: ../../po/../src/widgets/paint-selector.cpp:188 +#: ../../po/../src/widgets/paint-selector.cpp:699 +#, fuzzy +msgid "Radial gradient" +msgstr "Tilføj ny farveovergang" + +#: ../../po/../src/widgets/paint-selector.cpp:192 +msgid "Unset paint (make it undefined so it can be inherited)" +msgstr "" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/painting.html#FillRuleProperty +#: ../../po/../src/widgets/paint-selector.cpp:204 +msgid "" +"Any path self-intersections or subpaths create holes in the fill (fill-rule: " +"evenodd)" +msgstr "" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/painting.html#FillRuleProperty +#: ../../po/../src/widgets/paint-selector.cpp:215 +msgid "" +"Fill is solid unless a subpath is counterdirectional (fill-rule: nonzero)" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:528 +#, fuzzy +msgid "No objects" +msgstr "Tekstobjekt" + +#: ../../po/../src/widgets/paint-selector.cpp:539 +#, fuzzy +msgid "Multiple styles" +msgstr "Stíl for fyld" + +#: ../../po/../src/widgets/paint-selector.cpp:550 +msgid "Paint is undefined" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:757 +#, fuzzy +msgid "No patterns in document" +msgstr "Unavngivet dokument %d" + +#: ../../po/../src/widgets/paint-selector.cpp:872 +msgid "" +"Use Edit > Object(s) to Pattern to create a new pattern from " +"selection." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:426 +msgid "Now stroke width is scaled when objects are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:428 +msgid "Now stroke width is not scaled when objects are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:436 +msgid "" +"Now rounded rectangle corners are scaled when rectangles are " +"scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:438 +msgid "" +"Now rounded rectangle corners are not scaled when rectangles " +"are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:446 +msgid "" +"Now gradients are transformed along with their objects when " +"those are transformed (moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:448 +msgid "" +"Now gradients remain fixed when objects are transformed " +"(moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:456 +msgid "" +"Now patterns are transformed along with their objects when " +"those are transformed (moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:458 +msgid "" +"Now patterns remain fixed when objects are transformed (moved, " +"scaled, rotated, or skewed)." +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:506 +#, fuzzy +msgid "select_toolbar|X" +msgstr "Vælg" + +#: ../../po/../src/widgets/select-toolbar.cpp:506 +#, fuzzy +msgid "Horizontal coordinate of selection" +msgstr "Vandret centreringsværdi" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:511 +#, fuzzy +msgid "select_toolbar|Y" +msgstr "Vælg" + +#: ../../po/../src/widgets/select-toolbar.cpp:511 +msgid "Vertical coordinate of selection" +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:517 +#, fuzzy +msgid "select_toolbar|W" +msgstr "Vælg" + +#: ../../po/../src/widgets/select-toolbar.cpp:517 +#, fuzzy +msgid "Width of selection" +msgstr "Klip det markerede" + +#: ../../po/../src/widgets/select-toolbar.cpp:525 +msgid "Change both width and height by the same proportion" +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:534 +#, fuzzy +msgid "select_toolbar|H" +msgstr "Vælg" + +#: ../../po/../src/widgets/select-toolbar.cpp:534 +#, fuzzy +msgid "Height of selection" +msgstr "Zoom til valg" + +#: ../../po/../src/widgets/sp-color-gtkselector.cpp:62 +msgid "System" +msgstr "" + +#: ../../po/../src/widgets/sp-color-notebook.cpp:322 +#, fuzzy +msgid "RGBA_:" +msgstr "RGB" + +#: ../../po/../src/widgets/sp-color-notebook.cpp:330 +msgid "Hexadecimal RGBA value of the color" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "RGB" +msgstr "RGB" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +#, fuzzy +msgid "HSL" +msgstr "HSV" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "CMYK" +msgstr "CMYK" + +#: ../../po/../src/widgets/sp-color-scales.cpp:397 +msgid "_R" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:398 +#: ../../po/../src/widgets/sp-color-scales.cpp:399 +#, fuzzy +msgid "Red" +msgstr "Rød:" + +#: ../../po/../src/widgets/sp-color-scales.cpp:400 +msgid "_G" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:401 +#: ../../po/../src/widgets/sp-color-scales.cpp:402 +#, fuzzy +msgid "Green" +msgstr "Grøn:" + +#: ../../po/../src/widgets/sp-color-scales.cpp:403 +msgid "_B" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:404 +#: ../../po/../src/widgets/sp-color-scales.cpp:405 +#, fuzzy +msgid "Blue" +msgstr "BlÃ¥:" + +#. Label +#: ../../po/../src/widgets/sp-color-scales.cpp:406 +#: ../../po/../src/widgets/sp-color-scales.cpp:432 +#: ../../po/../src/widgets/sp-color-scales.cpp:463 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:141 +msgid "_A" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:407 +#: ../../po/../src/widgets/sp-color-scales.cpp:408 +#: ../../po/../src/widgets/sp-color-scales.cpp:433 +#: ../../po/../src/widgets/sp-color-scales.cpp:434 +#: ../../po/../src/widgets/sp-color-scales.cpp:464 +#: ../../po/../src/widgets/sp-color-scales.cpp:465 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:151 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:163 +msgid "Alpha (opacity)" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:423 +msgid "_H" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:424 +#: ../../po/../src/widgets/sp-color-scales.cpp:425 +#, fuzzy +msgid "Hue" +msgstr "Glød:" + +#: ../../po/../src/widgets/sp-color-scales.cpp:426 +msgid "_S" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:427 +#: ../../po/../src/widgets/sp-color-scales.cpp:428 +#, fuzzy +msgid "Saturation" +msgstr "Mætning:" + +#: ../../po/../src/widgets/sp-color-scales.cpp:429 +msgid "_L" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:430 +#: ../../po/../src/widgets/sp-color-scales.cpp:431 +#, fuzzy +msgid "Lightness" +msgstr "Højde" + +#: ../../po/../src/widgets/sp-color-scales.cpp:451 +msgid "_C" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:452 +#: ../../po/../src/widgets/sp-color-scales.cpp:453 +#, fuzzy +msgid "Cyan" +msgstr "Cyan:" + +#: ../../po/../src/widgets/sp-color-scales.cpp:454 +msgid "_M" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:455 +#: ../../po/../src/widgets/sp-color-scales.cpp:456 +#, fuzzy +msgid "Magenta" +msgstr "Magenta:" + +#: ../../po/../src/widgets/sp-color-scales.cpp:457 +msgid "_Y" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:458 +#: ../../po/../src/widgets/sp-color-scales.cpp:459 +#, fuzzy +msgid "Yellow" +msgstr "Gul:" + +#: ../../po/../src/widgets/sp-color-scales.cpp:460 +msgid "_K" +msgstr "" + +#: ../../po/../src/widgets/sp-color-selector.cpp:71 +#, fuzzy +msgid "Unnamed" +msgstr "navn" + +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:68 +msgid "Wheel" +msgstr "" + +#: ../../po/../src/widgets/sp-xmlview-attr-list.cpp:53 +#, fuzzy +msgid "Attribute" +msgstr "Attributter" + +#: ../../po/../src/widgets/sp-xmlview-attr-list.cpp:54 +msgid "Value" +msgstr "Værdi" + +#: ../../po/../src/widgets/toolbox.cpp:424 +#, fuzzy +msgid "Insert new nodes into selected segments" +msgstr "Inkludér en knude i valgte segmenter" + +#: ../../po/../src/widgets/toolbox.cpp:426 +msgid "Delete selected nodes" +msgstr "Slet valgte knuder" + +#: ../../po/../src/widgets/toolbox.cpp:431 +#, fuzzy +msgid "Join paths at selected nodes" +msgstr "Udjævn linje ved valgte knuder" + +#: ../../po/../src/widgets/toolbox.cpp:433 +#, fuzzy +msgid "Join paths at selected nodes with new segment" +msgstr "Udjævn linje ved valgte knuder" + +#: ../../po/../src/widgets/toolbox.cpp:436 +msgid "Split path between two non-endpoint nodes" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:439 +#, fuzzy +msgid "Break path at selected nodes" +msgstr "Opbryd valgte knude" + +#: ../../po/../src/widgets/toolbox.cpp:444 +#, fuzzy +msgid "Make selected nodes corner" +msgstr "Slet valgte knuder" + +#: ../../po/../src/widgets/toolbox.cpp:447 +#, fuzzy +msgid "Make selected nodes smooth" +msgstr "Slet valgte knuder" + +#: ../../po/../src/widgets/toolbox.cpp:450 +#, fuzzy +msgid "Make selected nodes symmetric" +msgstr "Slet valgte knuder" + +#: ../../po/../src/widgets/toolbox.cpp:455 +#, fuzzy +msgid "Make selected segments lines" +msgstr "Konvertér valgte segmenter til linier" + +#: ../../po/../src/widgets/toolbox.cpp:458 +#, fuzzy +msgid "Make selected segments curves" +msgstr "Konvertér valgte segmenter til kurver" + +#: ../../po/../src/widgets/toolbox.cpp:1199 +msgid "Polygon" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1206 +msgid "Regular polygon (with one handle) instead of a star" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1218 +msgid "Corners:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1218 +msgid "Number of corners of a polygon or star" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1228 +#, fuzzy +msgid "Spoke ratio:" +msgstr "LÃ¥s aspektraten" + +#. TRANSLATORS: Tip radius of a star is the distance from the center to the farthest handle. +#. Base radius is the same for the closest handle. +#: ../../po/../src/widgets/toolbox.cpp:1231 +msgid "Base radius to tip radius ratio" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1246 +#, fuzzy +msgid "Rounded:" +msgstr "Runde endepunkter" + +#: ../../po/../src/widgets/toolbox.cpp:1246 +msgid "How much rounded are the corners (0 for sharp)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1256 +msgid "Randomized:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1256 +msgid "Scatter randomly the corners and angles" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1269 +#: ../../po/../src/widgets/toolbox.cpp:1838 +#: ../../po/../src/widgets/toolbox.cpp:2061 +msgid "Defaults" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1270 +#: ../../po/../src/widgets/toolbox.cpp:1839 +#: ../../po/../src/widgets/toolbox.cpp:2062 +msgid "" +"Reset shape parameters to defaults (use Inkscape Preferences > Tools to " +"change defaults)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1544 +msgid "W:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1544 +#, fuzzy +msgid "Width of rectangle" +msgstr "Klip det markerede" + +#: ../../po/../src/widgets/toolbox.cpp:1556 +#, fuzzy +msgid "Height of rectangle" +msgstr "Zoom til valg" + +#: ../../po/../src/widgets/toolbox.cpp:1568 +#, fuzzy +msgid "Rx:" +msgstr "T0:" + +#: ../../po/../src/widgets/toolbox.cpp:1568 +#, fuzzy +msgid "Horizontal radius of rounded corners" +msgstr "Vandret centreringsværdi" + +#: ../../po/../src/widgets/toolbox.cpp:1578 +#, fuzzy +msgid "Ry:" +msgstr "T0:" + +#: ../../po/../src/widgets/toolbox.cpp:1578 +#, fuzzy +msgid "Vertical radius of rounded corners" +msgstr "Vandret centreringsværdi" + +#: ../../po/../src/widgets/toolbox.cpp:1594 +msgid "Not rounded" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1596 +msgid "Make corners sharp" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1805 +#, fuzzy +msgid "Turns:" +msgstr "Transformation" + +#: ../../po/../src/widgets/toolbox.cpp:1805 +msgid "Number of revolutions" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1815 +#, fuzzy +msgid "Divergence:" +msgstr "Drad" + +#: ../../po/../src/widgets/toolbox.cpp:1815 +msgid "How much denser/sparser are outer revolutions; 1 = uniform" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1825 +#, fuzzy +msgid "Inner radius:" +msgstr "Radius:" + +#: ../../po/../src/widgets/toolbox.cpp:1825 +msgid "Radius of the innermost revolution (relative to the spiral size)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1957 +msgid "The width of the calligraphic pen (relative to the visible canvas area)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1967 +#, fuzzy +msgid "Thinning:" +msgstr "Tegning" + +#: ../../po/../src/widgets/toolbox.cpp:1967 +msgid "" +"How much velocity thins the stroke (> 0 makes fast strokes thinner, < 0 " +"makes them broader, 0 makes width independent of velocity)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1980 +#, fuzzy +msgid "Angle:" +msgstr "vinkel" + +#: ../../po/../src/widgets/toolbox.cpp:1980 +msgid "" +"The angle of the pen's nib (in degrees; 0 = horizontal; has no effect if " +"fixation = 0)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1990 +#, fuzzy +msgid "Fixation:" +msgstr "Mætning:" + +#: ../../po/../src/widgets/toolbox.cpp:1990 +msgid "" +"How fixed is the pen angle (0 = always perpendicular to stroke direction, 1 " +"= fixed)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2003 +msgid "Mass:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2003 +msgid "How much inertia affects the movement of the pen" +msgstr "" + +#. TRANSLATORS: "drag" means "resistance" here +#: ../../po/../src/widgets/toolbox.cpp:2014 +#, fuzzy +msgid "Drag:" +msgstr "Tegn" + +#: ../../po/../src/widgets/toolbox.cpp:2014 +msgid "How much resistance affects the movement of the pen" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2034 +msgid "Use the pressure of the input device to alter the width of the pen" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2047 +msgid "Use the tilt of the input device to alter the angle of the pen's nib" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2374 +#, fuzzy +msgid "Start:" +msgstr "Stjerne" + +#: ../../po/../src/widgets/toolbox.cpp:2374 +msgid "The angle (in degrees) from the horizontal to the arc's start point" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2384 +msgid "End:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2384 +msgid "The angle (in degrees) from the horizontal to the arc's end point" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2395 +#, fuzzy +msgid "Open arc" +msgstr "_Åbn" + +#: ../../po/../src/widgets/toolbox.cpp:2396 +msgid "" +"Switch between arc (unclosed shape) and segment (closed shape with two radii)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2415 +msgid "Make whole" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2417 +msgid "Make the shape a whole ellipse, not arc or segment" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2644 +msgid "" +"When pressed, picks visible color without alpha and when not pressed, picks " +"color including its alpha" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:3039 +#, fuzzy +msgid "Make connectors avoid selected objects" +msgstr "Slet valgte knuder" + +#: ../../po/../src/widgets/toolbox.cpp:3043 +#, fuzzy +msgid "Make connectors ignore selected objects" +msgstr "Slet valgte knuder" + +#. +#. 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 : +#: ../share/extensions/addnodes.inx.h:1 +#, fuzzy +msgid "Add Nodes" +msgstr "Noder" + +#: ../share/extensions/addnodes.inx.h:2 +msgid "Maximum Segment Length" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:1 +msgid "AI Input" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:2 ../share/extensions/ai_output.inx.h:2 +msgid "Adobe Illustrator (*.ai)" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:3 +msgid "Open files saved with Adobe Illustrator" +msgstr "" + +#: ../share/extensions/ai_output.inx.h:1 +#, fuzzy +msgid "AI Output" +msgstr "Klip" + +#: ../share/extensions/ai_output.inx.h:3 +#, fuzzy +msgid "Write Adobe Illustrator" +msgstr "Vektor-illustrator" + +#: ../share/extensions/dia.inx.h:1 +msgid "A diagram created with the program Dia" +msgstr "" + +#: ../share/extensions/dia.inx.h:2 +msgid "Dia Diagram (*.dia)" +msgstr "" + +#: ../share/extensions/dia.inx.h:3 +msgid "Dia Input" +msgstr "" + +#: ../share/extensions/dia.inx.h:4 +msgid "" +"In order to import Dia files, Dia itself must be installed. You can get Dia " +"at http://www.gnome.org/projects/dia/" +msgstr "" + +#: ../share/extensions/dia.inx.h:5 +msgid "" +"The dia2svg.sh script should be installed with your Inkscape distribution. " +"If you do not have it, there is likely to be something wrong with your " +"Inkscape installation." +msgstr "" + +#: ../share/extensions/dots.inx.h:1 +#, fuzzy +msgid "Connect the Dots" +msgstr "Luk vindue" + +#: ../share/extensions/dots.inx.h:2 +#, fuzzy +msgid "Dot Size" +msgstr "Sider:" + +#: ../share/extensions/dots.inx.h:3 +#, fuzzy +msgid "Font Size" +msgstr "Gem ikke" + +#: ../share/extensions/dropshadow.inx.h:1 +msgid "Color of shadow" +msgstr "" + +#: ../share/extensions/dropshadow.inx.h:2 +msgid "Dropshadow" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:1 +#: ../share/extensions/dxf_output.inx.h:1 +msgid "AutoCAD DXF (*.dxf)" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:2 +msgid "DXF Input" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:3 +msgid "Import AutoCAD's Document Exchange Format" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:4 +msgid "" +"dxf2svg may come with Inkscape, but is also at http://dxf-svg-convert." +"sourceforge.net/" +msgstr "" + +#: ../share/extensions/dxf_output.inx.h:2 +#, fuzzy +msgid "DXF Output" +msgstr "Klip" + +#: ../share/extensions/dxf_output.inx.h:3 +msgid "DXF file written by pstoedit" +msgstr "" + +#: ../share/extensions/dxf_output.inx.h:4 +msgid "pstoedit must be installed to run see http://www.pstoedit.net/pstoedit" +msgstr "" + +#: ../share/extensions/embedimage.inx.h:1 +#, fuzzy +msgid "Embed Images" +msgstr "Billede" + +#: ../share/extensions/eps_input.inx.h:1 +msgid "EPS Input" +msgstr "" + +#: ../share/extensions/eps_input.inx.h:2 +msgid "Encapsulated Postscript" +msgstr "" + +#: ../share/extensions/eps_input.inx.h:3 +msgid "Encapsulated Postscript (*.eps)" +msgstr "" + +#: ../share/extensions/epsi_output.inx.h:1 +#, fuzzy +msgid "EPSI Output" +msgstr "Klip" + +#: ../share/extensions/epsi_output.inx.h:2 +msgid "Encapsulated Postscript Interchange (*.epsi)" +msgstr "" + +#: ../share/extensions/epsi_output.inx.h:3 +msgid "Encapsulated Postscript with a thumbnail" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:1 ../share/extensions/ffms.inx.h:1 +#: ../share/extensions/ffset.inx.h:1 ../share/extensions/ffss.inx.h:1 +#, fuzzy +msgid "Bridge Width" +msgstr "Bredde" + +#: ../share/extensions/ffmet.inx.h:2 ../share/extensions/ffms.inx.h:2 +msgid "First String Length" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:3 +msgid "FretFind Multi Length ET" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:4 ../share/extensions/ffms.inx.h:4 +#: ../share/extensions/ffset.inx.h:3 ../share/extensions/ffss.inx.h:3 +msgid "Fretboard Edges" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:5 ../share/extensions/ffms.inx.h:5 +msgid "Last String Length" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:6 ../share/extensions/ffms.inx.h:6 +#: ../share/extensions/ffset.inx.h:4 ../share/extensions/ffss.inx.h:4 +msgid "Number of Frets" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:7 ../share/extensions/ffms.inx.h:7 +#: ../share/extensions/ffset.inx.h:5 ../share/extensions/ffss.inx.h:5 +msgid "Number of Strings" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:8 ../share/extensions/ffms.inx.h:8 +#: ../share/extensions/ffset.inx.h:6 ../share/extensions/ffss.inx.h:6 +#, fuzzy +msgid "Nut Width" +msgstr "Bredde:" + +#: ../share/extensions/ffmet.inx.h:9 ../share/extensions/ffms.inx.h:10 +msgid "Perpendicular Distance" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:10 ../share/extensions/ffset.inx.h:7 +msgid "Scale Base (2 for Octave)" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:11 ../share/extensions/ffset.inx.h:9 +msgid "Tones in Scale" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:12 ../share/extensions/ffms.inx.h:12 +#: ../share/extensions/ffset.inx.h:10 ../share/extensions/ffss.inx.h:10 +msgid "px per Unit" +msgstr "" + +#: ../share/extensions/ffms.inx.h:3 +msgid "FretFind Multi Length Scala" +msgstr "" + +#: ../share/extensions/ffms.inx.h:9 ../share/extensions/ffss.inx.h:7 +msgid "Path to Scala *.scl File" +msgstr "" + +#: ../share/extensions/ffms.inx.h:11 +msgid "Tuning (scale step for each string seperated by semicolons)" +msgstr "" + +#: ../share/extensions/ffset.inx.h:2 +msgid "FretFind Single Length ET" +msgstr "" + +#: ../share/extensions/ffset.inx.h:8 ../share/extensions/ffss.inx.h:8 +msgid "Scale Length" +msgstr "" + +#: ../share/extensions/ffss.inx.h:2 +msgid "FretFind Single Length Scala" +msgstr "" + +#: ../share/extensions/ffss.inx.h:9 +msgid "Tuning (Scale step for each string seperated by semicolons)" +msgstr "" + +#: ../share/extensions/handles.inx.h:1 +#, fuzzy +msgid "Draw Handles" +msgstr "Tegn frihÃ¥ndslinje" + +#: ../share/extensions/interp.inx.h:1 +#, fuzzy +msgid "Duplicate Endpaths" +msgstr "Duplikér" + +#: ../share/extensions/interp.inx.h:2 +#, fuzzy +msgid "Exponent" +msgstr "Eksportér" + +#: ../share/extensions/interp.inx.h:3 +msgid "Interpolate" +msgstr "" + +#: ../share/extensions/interp.inx.h:4 +msgid "Interpolate Style (Experimental)" +msgstr "" + +#: ../share/extensions/interp.inx.h:5 +msgid "Interpolation Method" +msgstr "" + +#: ../share/extensions/interp.inx.h:6 +msgid "Interpolation Steps" +msgstr "" + +#: ../share/extensions/kochify.inx.h:1 +msgid "Kochify" +msgstr "" + +#: ../share/extensions/kochify_load.inx.h:1 +msgid "Kochify (Load)" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:1 +#, fuzzy +msgid "Angle" +msgstr "vinkel" + +#: ../share/extensions/lindenmayer.inx.h:2 +msgid "Axiom" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:3 +#, fuzzy +msgid "Lindenmayer" +msgstr "Radius:" + +#: ../share/extensions/lindenmayer.inx.h:4 +msgid "Order" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:5 +#, fuzzy +msgid "Rules" +msgstr "Fil" + +#: ../share/extensions/lindenmayer.inx.h:6 +#, fuzzy +msgid "Step" +msgstr " Stíl " + +#: ../share/extensions/motion.inx.h:1 +#, fuzzy +msgid "Direction" +msgstr "Position" + +#: ../share/extensions/motion.inx.h:2 +#, fuzzy +msgid "Magnitude" +msgstr "Magenta:" + +#: ../share/extensions/motion.inx.h:3 +#, fuzzy +msgid "Motion" +msgstr "Omdrejning:" + +#: ../share/extensions/pdf_output.inx.h:1 +msgid "Adobe PDF (*.pdf)" +msgstr "" + +#: ../share/extensions/pdf_output.inx.h:2 +msgid "Adobe Portable Document Format" +msgstr "" + +#: ../share/extensions/pdf_output.inx.h:3 +#, fuzzy +msgid "PDF Output" +msgstr "Klip" + +#: ../share/extensions/ps_input.inx.h:1 +#, fuzzy +msgid "Postscript" +msgstr "Punkt" + +#: ../share/extensions/ps_input.inx.h:2 +msgid "Postscript (*.ps)" +msgstr "" + +#: ../share/extensions/ps_input.inx.h:3 +msgid "Postscript Input" +msgstr "" + +#: ../share/extensions/radiusrand.inx.h:1 +#, fuzzy +msgid "Radius" +msgstr "Radius:" + +#: ../share/extensions/radiusrand.inx.h:2 +#, fuzzy +msgid "Radius Randomize" +msgstr "Radius:" + +#: ../share/extensions/radiusrand.inx.h:3 +msgid "Randomize Control Points" +msgstr "" + +#: ../share/extensions/radiusrand.inx.h:4 +#, fuzzy +msgid "Randomize Nodes" +msgstr "Radius:" + +#: ../share/extensions/rtree.inx.h:1 +#, fuzzy +msgid "Initial Size" +msgstr "Billedstørrelse" + +#: ../share/extensions/rtree.inx.h:2 +msgid "Minimum Size" +msgstr "" + +#: ../share/extensions/rtree.inx.h:3 +msgid "Random Tree" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:1 +msgid "A diagram created with the program Sketch" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:2 +msgid "Sketch Diagram (*.sk)" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:3 +msgid "Sketch Input" +msgstr "" + +#: ../share/extensions/straightseg.inx.h:1 +msgid "Behavior" +msgstr "" + +#: ../share/extensions/straightseg.inx.h:3 +msgid "Segment Straightener" +msgstr "" + +#: ../share/extensions/summersnight.inx.h:1 +msgid "Summer's Night" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:1 +#: ../share/extensions/svgz_output.inx.h:1 +#, fuzzy +msgid "Compressed Inkscape SVG (*.svgz)" +msgstr "Ukomprimeret filstørrelse:" + +#: ../share/extensions/svgz_input.inx.h:2 +#: ../share/extensions/svgz_output.inx.h:2 +msgid "Inkscape's native file format compressed with GZip" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:3 +msgid "SVGZ Input" +msgstr "" + +#: ../share/extensions/svgz_output.inx.h:3 +#, fuzzy +msgid "SVGZ Output" +msgstr "Klip" + +#: ../share/extensions/txt2svg.inx.h:1 +msgid "ASCII Text" +msgstr "" + +#: ../share/extensions/txt2svg.inx.h:2 +msgid "Text File (*.txt)" +msgstr "" + +#: ../share/extensions/txt2svg.inx.h:3 +#, fuzzy +msgid "Text Input" +msgstr "Startfarve" + +#: ../share/extensions/wavy.inx.h:1 +msgid "Calculate first derivative numerically" +msgstr "" + +#: ../share/extensions/wavy.inx.h:2 +msgid "First derivative" +msgstr "" + +#: ../share/extensions/wavy.inx.h:3 +msgid "Function" +msgstr "" + +#: ../share/extensions/wavy.inx.h:4 +msgid "Function Plotter" +msgstr "" + +#: ../share/extensions/wavy.inx.h:5 +msgid "Nodes per period" +msgstr "" + +#: ../share/extensions/wavy.inx.h:6 +msgid "Periods (2*Pi each)" +msgstr "" + +#: ../share/extensions/whirl.inx.h:1 +msgid "Amount of Whirl" +msgstr "" + +#: ../share/extensions/whirl.inx.h:2 +#, fuzzy +msgid "Center X" +msgstr "Centrér X:" + +#: ../share/extensions/whirl.inx.h:3 +#, fuzzy +msgid "Center Y" +msgstr "Centrér Y:" + +#: ../share/extensions/whirl.inx.h:4 +#, fuzzy +msgid "Direction of Rotation" +msgstr "Sænk det valgte til bunden" + +#: ../share/extensions/whirl.inx.h:5 +msgid "Whirl" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:1 +msgid "A popular graphics file format for clipart" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:2 +msgid "Windows Metafile (*.wmf)" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:3 +msgid "Windows Metafile Input" +msgstr "" + +#, fuzzy +#~ msgid "Canvas size:" +#~ msgstr "Gem ikke" + +#, fuzzy +#~ msgid "Custom canvas" +#~ msgstr "Tilpasset papir" + +#, fuzzy +#~ msgid "Current style" +#~ msgstr "Skrivebordets indstilinger" + +#, fuzzy +#~ msgid "Arrange Objects" +#~ msgstr "Ting" + +#~ msgid "deg" +#~ msgstr "grad" + +#, fuzzy +#~ msgid "_Credits" +#~ msgstr "Farve-bitmap" + +#, fuzzy +#~ msgid "Grab sensitivity" +#~ msgstr "Gør følsom" + +#, fuzzy +#~ msgid "Acceleration" +#~ msgstr "Valg" + +#, fuzzy +#~ msgid "Speed" +#~ msgstr "Rød:" + +#, fuzzy +#~ msgid "Zoom in/out by" +#~ msgstr "Zoom ud" + +#, fuzzy +#~ msgid "Transform" +#~ msgstr "Transformation" + +#, fuzzy +#~ msgid "Rotate _90 deg CW" +#~ msgstr "Sæt vinkel til 90°" + +#, fuzzy +#~ msgid "Rotate 9_0 deg CCW" +#~ msgstr "Sæt vinkel til 90°" + +#, fuzzy +#~ msgid "Flip selection horizontally" +#~ msgstr "Vend valgte ting" + +#, fuzzy +#~ msgid "Flip selection vertically" +#~ msgstr "Vend valgte ting" + +#~ msgid "Edit" +#~ msgstr "Redigering" + +#~ msgid "Add" +#~ msgstr "Tilføj" + +#, fuzzy +#~ msgid "C_reate" +#~ msgstr "Opret lænke" + +#, fuzzy +#~ msgid "Automatically scale Rows to fit selected objects." +#~ msgstr "Redigér udfyldningsstil for valgte ting" + +#, fuzzy +#~ msgid "Automatically scale Columns to fit selected objects." +#~ msgstr "Redigér udfyldningsstil for valgte ting" + +#, fuzzy +#~ msgid "Go to root" +#~ msgstr "Redigér noder" + +#, fuzzy +#~ msgid "X" +#~ msgstr "X1" + +#, fuzzy +#~ msgid "Y" +#~ msgstr "Y1" + +#, fuzzy +#~ msgid " " +#~ msgstr "X +" + +#~ msgid "Sides:" +#~ msgstr "Sider:" + +#~ msgid "R1:" +#~ msgstr "R1:" + +#~ msgid "R2:" +#~ msgstr "R2:" + +#~ msgid "ARG1:" +#~ msgstr "ARG1:" + +#~ msgid "ARG2:" +#~ msgstr "ARG2:" + +#, fuzzy +#~ msgid "Flatsides:" +#~ msgstr "Sider:" + +#, fuzzy +#~ msgid "Radius X:" +#~ msgstr "Radius:" + +#, fuzzy +#~ msgid "Radius Y:" +#~ msgstr "Radius:" + +#, fuzzy +#~ msgid "Start Angle:" +#~ msgstr "Stjerne" + +#, fuzzy +#~ msgid "End Angle:" +#~ msgstr "vinkel" + +#, fuzzy +#~ msgid "Open:" +#~ msgstr "_Åbn" + +#~ msgid "Expansion:" +#~ msgstr "Ekspansion:" + +#, fuzzy +#~ msgid "Revolutions:" +#~ msgstr "Omdrejning:" + +#~ msgid "Argument:" +#~ msgstr "Argument:" + +#~ msgid "T0:" +#~ msgstr "T0:" + +#~ msgid "RX:" +#~ msgstr "RX:" + +#~ msgid "RY:" +#~ msgstr "RY:" + +#, fuzzy +#~ msgid "Rectangle _Properties" +#~ msgstr "Egenskaber for firkant" + +#, fuzzy +#~ msgid "Star _Properties" +#~ msgstr "Egenskaber for stjerne" + +#, fuzzy +#~ msgid "Ellipse _Properties" +#~ msgstr "Egenskaber for lænke" + +#, fuzzy +#~ msgid "Spiral _Properties" +#~ msgstr "Egenskaber for spiral" + +#, fuzzy +#~ msgid "Document Preferences" +#~ msgstr "Element er en reference" + +#, fuzzy +#~ msgid "Extensions Editor" +#~ msgstr "Ekspansion:" + +#, fuzzy +#~ msgid "Preferences" +#~ msgstr "Element er en reference" + +#, fuzzy +#~ msgid "Layer Editor" +#~ msgstr "Hæv det valgte op til toppen" + +#, fuzzy +#~ msgid "Text Properties" +#~ msgstr "Egenskaber for tekst" + +#, fuzzy +#~ msgid "Transformation" +#~ msgstr "Transformation" + +#, fuzzy +#~ msgid "_Export..." +#~ msgstr "Importér" + +#, fuzzy +#~ msgid "_Document Properties" +#~ msgstr "Indstillinger for dokument" + +#, fuzzy +#~ msgid "In_kscape Preferences" +#~ msgstr "Sodipodi: %s: %s: %d" + +#, fuzzy +#~ msgid "Select _Original Clone" +#~ msgstr "Vælg" + +#, fuzzy +#~ msgid "Tile" +#~ msgstr "Titel:" + +#, fuzzy +#~ msgid "Select A_ll" +#~ msgstr "Vælg" + +#, fuzzy +#~ msgid "Select Non_e" +#~ msgstr "Valg" + +#, fuzzy +#~ msgid "Zoom _In" +#~ msgstr "Zoom ind" + +#, fuzzy +#~ msgid "Zoom _Out" +#~ msgstr "Zoom ud" + +#, fuzzy +#~ msgid "Pre_vious" +#~ msgstr "Luk vindue" + +#, fuzzy +#~ msgid "Nex_t" +#~ msgstr "Tekst" + +#, fuzzy +#~ msgid "Tool Co_ntrols bar" +#~ msgstr "Oaf valg" + +#, fuzzy +#~ msgid "R_ename Layer..." +#~ msgstr "Radius:" + +#, fuzzy +#~ msgid "D_uplicate Layer" +#~ msgstr "Duplikér" + +#, fuzzy +#~ msgid "_Delete Layer" +#~ msgstr "Vælg" + +#, fuzzy +#~ msgid "Select Ne_xt Layer" +#~ msgstr "Vælg" + +#, fuzzy +#~ msgid "Select Pre_vious Layer" +#~ msgstr "Valg" + +#, fuzzy +#~ msgid "Select To_p Layer" +#~ msgstr "Valg" + +#, fuzzy +#~ msgid "Move to Ne_w Layer" +#~ msgstr "Lagret dokument %d" + +#, fuzzy +#~ msgid "Move to B_ottom Layer" +#~ msgstr "Sænk det valgte til bunden" + +#, fuzzy +#~ msgid "_Trace Bitmap..." +#~ msgstr "Beskadiget bitmap" + +#, fuzzy +#~ msgid "_Put Text on Path" +#~ msgstr "Omform valgte ting til kurver" + +#, fuzzy +#~ msgid "_Remove Text from Path" +#~ msgstr "Omform valgte ting til kurver" + +#, fuzzy +#~ msgid "Freehand" +#~ msgstr "FrihÃ¥nd" + +#, fuzzy +#~ msgid "DynaDraw" +#~ msgstr "Tegn" + +#~ msgid "Stroke" +#~ msgstr "Skravering" + +#, fuzzy +#~ msgid "Corners" +#~ msgstr "Luk vindue" + +#, fuzzy +#~ msgid "Delete" +#~ msgstr "Slet" + +#, fuzzy +#~ msgid "Join" +#~ msgstr "Sammenlæg:" + +#, fuzzy +#~ msgid "Delete Segment" +#~ msgstr "Duplikér det markerede" + +#, fuzzy +#~ msgid "Break" +#~ msgstr "_Bryd op" + +#, fuzzy +#~ msgid "Symmetric" +#~ msgstr "Usymmetrisk" + +#, fuzzy +#~ msgid "Line" +#~ msgstr "Lænke" + +#~ msgid "New" +#~ msgstr "Ny" + +#, fuzzy +#~ msgid "Revert to Saved" +#~ msgstr "Konvertér til ku_rver" + +#, fuzzy +#~ msgid "Save" +#~ msgstr "Gem" + +#, fuzzy +#~ msgid "Save As..." +#~ msgstr "Gem" + +#, fuzzy +#~ msgid "Import..." +#~ msgstr "Importér" + +#, fuzzy +#~ msgid "Export..." +#~ msgstr "Eksportér" + +#, fuzzy +#~ msgid "Print..." +#~ msgstr "Punkt" + +#, fuzzy +#~ msgid "Global Inkscape preferences (Shift+Ctrl+P)" +#~ msgstr "Indstillinger for skærm" + +#, fuzzy +#~ msgid "Undo" +#~ msgstr "Fortryd " + +#, fuzzy +#~ msgid "Redo" +#~ msgstr "Genopret" + +#, fuzzy +#~ msgid "Cut" +#~ msgstr "Klip" + +#, fuzzy +#~ msgid "Copy" +#~ msgstr "Kopiér" + +#, fuzzy +#~ msgid "Duplicate selected object(s) (Ctrl+D)" +#~ msgstr "Vend valgte ting" + +#, fuzzy +#~ msgid "Clone selected object (Alt+D)" +#~ msgstr "Vend valgte ting" + +#, fuzzy +#~ msgid "Zoom in (+)" +#~ msgstr "Zoom ind" + +#, fuzzy +#~ msgid "Zoom out (-)" +#~ msgstr "Zoom ud" + +#, fuzzy +#~ msgid "Zoom to 1:1 (100%) (1)" +#~ msgstr "Zoom til 1:1" + +#, fuzzy +#~ msgid "Zoom to 1:2 (50%) (2)" +#~ msgstr "Zoom til 1:2" + +#, fuzzy +#~ msgid "Zoom to 2:1 (200%) (0)" +#~ msgstr "Zoom til 2:1" + +#, fuzzy +#~ msgid "Zoom to fit selection in window (3)" +#~ msgstr "Hæv det valgte op til toppen" + +#, fuzzy +#~ msgid "Zoom to fit drawing in window (4)" +#~ msgstr "Zoom til tegning" + +#, fuzzy +#~ msgid "Zoom to fit page in window (5)" +#~ msgstr "Sæt sidebredde" + +#, fuzzy +#~ msgid "Zoom to fit page width in window (6)" +#~ msgstr "Sæt sidebredde" + +#, fuzzy +#~ msgid "Fill and Stroke dialog (Shift+Ctrl+F)" +#~ msgstr "Skrivebordets indstilinger" + +#, fuzzy +#~ msgid "Group selected objects (Ctrl+G)" +#~ msgstr "Gruppér valgte ting" + +#, fuzzy +#~ msgid "Ungroup selected group(s) (Ctrl+U)" +#~ msgstr "Deler valgte ting op" + +#, fuzzy +#~ msgid "Raise selection up one step (PgUp)" +#~ msgstr "Hæv det valgte op ét lag" + +#, fuzzy +#~ msgid "Lower selection down one step (PgDn)" +#~ msgstr "Sænk det valgte ét lag" + +#, fuzzy +#~ msgid "Raise selection to top (Home)" +#~ msgstr "Hæv det valgte op til toppen" + +#, fuzzy +#~ msgid "Lower selection to bottom (End)" +#~ msgstr "Sænk det valgte til bunden" + +#, fuzzy +#~ msgid "Move selection to new layer" +#~ msgstr "Sænk det valgte ét lag" + +#, fuzzy +#~ msgid "Move selection to next layer" +#~ msgstr "Sænk det valgte ét lag" + +#, fuzzy +#~ msgid "Move selection to previous layer" +#~ msgstr "Kopiér det markerede til klippebord" + +#, fuzzy +#~ msgid "Move selection to top layer" +#~ msgstr "Hæv det valgte op til toppen" + +#, fuzzy +#~ msgid "Move selection to bottom layer" +#~ msgstr "Sænk det valgte til bunden" + +#, fuzzy +#~ msgid "Rotate selection 90° clockwise (Shift+Ctrl+Right)" +#~ msgstr "Drej valgte ting 90° med uret" + +#, fuzzy +#~ msgid "Rotate selection 90° counter-clockwise (Shift+Ctrl+Left)" +#~ msgstr "Drej valgte ting 90° med uret" + +#, fuzzy +#~ msgid "Flip selection horizontally (H)" +#~ msgstr "Vend valgte ting" + +#, fuzzy +#~ msgid "Flip selection vertically (V)" +#~ msgstr "Vend valgte ting" + +#, fuzzy +#~ msgid "Align and Distribute dialog (Shift+Ctrl+A)" +#~ msgstr "Attributter" + +#, fuzzy +#~ msgid "Convert selected object(s) to path(s) (Shift+Ctrl+C)" +#~ msgstr "Omform valgte ting til kurver" + +#, fuzzy +#~ msgid "Convert selected stroke(s) to path(s) (Ctrl+Alt+C)" +#~ msgstr "Omform valgte ting til kurver" + +#, fuzzy +#~ msgid "Text and Font dialog (Shift+Ctrl+T)" +#~ msgstr "Skrivebordets indstilinger" + +#, fuzzy +#~ msgid "Node tool" +#~ msgstr "Noderedigering" + +#, fuzzy +#~ msgid "Zoom tool" +#~ msgstr "Zoom ud" + +#, fuzzy +#~ msgid "Rectangle tool" +#~ msgstr "Firkant" + +#, fuzzy +#~ msgid "Arc tool" +#~ msgstr "Ærkerolle:" + +#, fuzzy +#~ msgid "Star tool" +#~ msgstr "Startfarve" + +#, fuzzy +#~ msgid "Spiral tool" +#~ msgstr "Spiral" + +#, fuzzy +#~ msgid "Freehand tool" +#~ msgstr "FrihÃ¥nd" + +#, fuzzy +#~ msgid "Pen tool" +#~ msgstr "Firkant" + +#, fuzzy +#~ msgid "Dropper tool" +#~ msgstr "Spiral" + +#, fuzzy +#~ msgid "When scaling rectangles, scale radii of rounded corners" +#~ msgstr "Vandret centreringsværdi" + +#, fuzzy +#~ msgid "Delete segment between two nodes" +#~ msgstr "Slet valgte knuder" + +#, fuzzy +#~ msgid "URI:" +#~ msgstr "URL:" + +#, fuzzy +#~ msgid "Select All in All Layers" +#~ msgstr "Vælg" + +#, fuzzy +#~ msgid "Invert Selection" +#~ msgstr "Valg" + +#, fuzzy +#~ msgid "Clean up selected path(s)" +#~ msgstr "Forbind valgte stier" + +#, fuzzy +#~ msgid "_Scripts..." +#~ msgstr "Punkt" + +#, fuzzy +#~ msgid "Align and Distribute" +#~ msgstr "Attributter" + +#, fuzzy +#~ msgid "Align and Distribute Dialog" +#~ msgstr "Attributter" + +#, fuzzy +#~ msgid "Export Dialog" +#~ msgstr "Eksporteret som" + +#, fuzzy +#~ msgid "Fill and Stroke Dialog" +#~ msgstr "Skrivebordets indstilinger" + +#, fuzzy +#~ msgid "Find Dialog" +#~ msgstr "Justér dialog" + +#, fuzzy +#~ msgid "Inkscape Preferences" +#~ msgstr "Sodipodi: %s: %s: %d" + +#, fuzzy +#~ msgid "Inkscape Preferences Dialog" +#~ msgstr "Sodipodi: %s: %s: %d" + +#, fuzzy +#~ msgid "Layer Editor Dialog" +#~ msgstr "Hæv det valgte op til toppen" + +#, fuzzy +#~ msgid "Text Properties Dialog" +#~ msgstr "egenskaber for objekt" + +#, fuzzy +#~ msgid "Transformation Dialog" +#~ msgstr "Transformationsdialog" + +#, fuzzy +#~ msgid "Tree Editor" +#~ msgstr "Gradientvektor" + +#, fuzzy +#~ msgid "XML Editor Dialog" +#~ msgstr "Redigering..." + +#, fuzzy +#~ msgid "Row height:" +#~ msgstr "Højde:" + +#, fuzzy +#~ msgid "Column width:" +#~ msgstr "Ændr" + +#, fuzzy +#~ msgid "Creating anchor at (%g,%g)" +#~ msgstr "Tegn stjerne" + +#, fuzzy +#~ msgid "EPS Output Settings" +#~ msgstr "Indstillinger for dokument" + +#, fuzzy +#~ msgid "Inkscape" +#~ msgstr "Sodipodi: %s: %s: %d" + +#, fuzzy +#~ msgid "Top of aligned objects to top of anchor" +#~ msgstr "Justér indre objekt til topkant" + +#, fuzzy +#~ msgid "Alternate sign" +#~ msgstr "Mætning:" + +#, fuzzy +#~ msgid "Rows:" +#~ msgstr "Elipse" + +#, fuzzy +#~ msgid "Minor grid line color:" +#~ msgstr "Farver for hjælpelinier" + +#~ msgid "Grid color" +#~ msgstr "Hjælpelinjefarve" + +#, fuzzy +#~ msgid "Grid emphasis color" +#~ msgstr "Hjælpelinjefarve" + +#, fuzzy +#~ msgid "Major grid line spacing:" +#~ msgstr "Afstand X:" + +#, fuzzy +#~ msgid "Background (also for export):" +#~ msgstr "Slutfarve" + +#, fuzzy +#~ msgid "Picking colors:" +#~ msgstr "Vælg en farve" + +#~ msgid "Fill style" +#~ msgstr "Stíl for fyld" + +#, fuzzy +#~ msgid "Fill:" +#~ msgstr "Fyld" + +#, fuzzy +#~ msgid "winding" +#~ msgstr "Tegning" + +#, fuzzy +#~ msgid "alternating" +#~ msgstr "Mætning:" + +#, fuzzy +#~ msgid "Update Properties" +#~ msgstr "Egenskaber for element" + +#, fuzzy +#~ msgid "Label invalid" +#~ msgstr "ID er gyldig" + +#, fuzzy +#~ msgid "executable" +#~ msgstr "Firkant" + +#, fuzzy +#~ msgid "file" +#~ msgstr "_Fil" + +#, fuzzy +#~ msgid "extension" +#~ msgstr "Ekspansion:" + +#, fuzzy +#~ msgid "path" +#~ msgstr "pt" + +#, fuzzy +#~ msgid "absolute" +#~ msgstr "absolut" + +#~ msgid "Could not create sodipodi-svg-doc factory" +#~ msgstr "Kunne ikke oprette sodipodi-svg-doc fabrik" + +#, fuzzy +#~ msgid "SVG Files" +#~ msgstr "Fil" + +#, fuzzy +#~ msgid "Make s_ensitive" +#~ msgstr "Gør følsom" + +#, fuzzy +#~ msgid "Make i_nsensitive" +#~ msgstr "Gør ufølsom" + +#, fuzzy +#~ msgid "Layer Properties" +#~ msgstr "Egenskaber for stjerne" + +#, fuzzy +#~ msgid "Select object(s) to tile." +#~ msgstr "Omform valgte ting til kurver" + +#~ msgid "Sensitive" +#~ msgstr "følsom" + +#~ msgid "Active" +#~ msgstr "Aktiv" + +#~ msgid "Printable" +#~ msgstr "Udskrivelig" + +#, fuzzy +#~ msgid "Document Name:" +#~ msgstr "Dokument" + +#, fuzzy +#~ msgid "Image URI:" +#~ msgstr "Billede" + +#~ msgid "Visible" +#~ msgstr "Synlig" + +#, fuzzy +#~ msgid "Flatness:" +#~ msgstr "Sider:" + +#, fuzzy +#~ msgid "Other" +#~ msgstr "Rækkefølge" + +#, fuzzy +#~ msgid "Trace: Selected object is not an image" +#~ msgstr "Drej valgte ting 90° med uret" + +#, fuzzy +#~ msgid "object" +#~ msgstr "Ting" + +#, fuzzy +#~ msgid "user space" +#~ msgstr "Brugervalgt" + +#, fuzzy +#~ msgid "Coordinates:" +#~ msgstr "Farve-bitmap" + +#, fuzzy +#~ msgid "Alignment:" +#~ msgstr "Basis for justering" + +#, fuzzy +#~ msgid "Draw arc: %s x %s" +#~ msgstr "Tegn stjerne" + +#, fuzzy +#~ msgid "Draw rectangle: %s x %s" +#~ msgstr "Tegn firkant" + +#, fuzzy +#~ msgid "Move by %s, %s" +#~ msgstr "Flyt" + +#, fuzzy +#~ msgid "Active group" +#~ msgstr "Aktiv" + +#, fuzzy +#~ msgid "typeset object" +#~ msgstr "Tekstobjekt" + +#, fuzzy +#~ msgid "Pattern Fill" +#~ msgstr "Mønsterfyld" + +#~ msgid "Snap to grid" +#~ msgstr "Fastsæt til gitter" + +#~ msgid "Snap to guides" +#~ msgstr "Fastsæt til hjælpelinier" + +#, fuzzy +#~ msgid "_Menu" +#~ msgstr "_Åbn" + +#, fuzzy +#~ msgid "Snap points to the grid" +#~ msgstr "Fastsæt til gitter" + +#, fuzzy +#~ msgid "Rect" +#~ msgstr "Firkant" + +#, fuzzy +#~ msgid "meters" +#~ msgstr "Millimeter" + +#, fuzzy +#~ msgid "Userspace unit" +#~ msgstr "Brugervalgt" + +#, fuzzy +#~ msgid "User" +#~ msgstr "Brugervalgt" + +#, fuzzy +#~ msgid "Userspace units" +#~ msgstr "Brugervalgt" + +#, fuzzy +#~ msgid "Ru_lers" +#~ msgstr "Fil" + +#, fuzzy +#~ msgid "Show or hide rulers" +#~ msgstr "Vis hjælpelinier" + +#, fuzzy +#~ msgid "_New Window" +#~ msgstr "Ny visning" + +#~ msgid "Mode:" +#~ msgstr "Tilstand:" + +#~ msgid "Alpha:" +#~ msgstr "Alfa:" + +#~ msgid "Value:" +#~ msgstr "Værdi:" + +#, fuzzy +#~ msgid "Stroke settings" +#~ msgstr "Skrivebordets indstilinger" + +#~ msgid "Item properties" +#~ msgstr "Egenskaber for element" + +#, fuzzy +#~ msgid "Quit" +#~ msgstr "_Afslut" + +#, fuzzy +#~ msgid "Combine multiple paths" +#~ msgstr "Forbind valgte stier" + +#, fuzzy +#~ msgid "New View" +#~ msgstr "Ny visning" + +#, fuzzy +#~ msgid "Fill and stroke settings" +#~ msgstr "Skrivebordets indstilinger" + +#, fuzzy +#~ msgid "Object transformations" +#~ msgstr "Nulstil transformation" + +#, fuzzy +#~ msgid "Text editing and font settings" +#~ msgstr "Skrivebordets indstilinger" + +#, fuzzy +#~ msgid "Fill Rule" +#~ msgstr "Stíl for fyld" + +#, fuzzy +#~ msgid "Tool has no options" +#~ msgstr "Oaf valg" + +#, fuzzy +#~ msgid "Visual transformation" +#~ msgstr "Nulstil transformation" + +#, fuzzy +#~ msgid "Show content" +#~ msgstr "Indhold" + +#, fuzzy +#~ msgid "Selected object has no curve, cannot outline." +#~ msgstr "Omform valgte ting til kurver" + +#, fuzzy +#~ msgid "Proportion:" +#~ msgstr "Position" + +#, fuzzy +#~ msgid "Inkscape _Options" +#~ msgstr "Sodipodi: %s: %s: %d" + +#, fuzzy +#~ msgid "Tool Optio_ns" +#~ msgstr "Oaf valg" + +#, fuzzy +#~ msgid "gradientUnits" +#~ msgstr "Gradient" + +#, fuzzy +#~ msgid "gradientSpread" +#~ msgstr "Gradient" + +#, fuzzy +#~ msgid "nonzero" +#~ msgstr "ingen" + +#, fuzzy +#~ msgid "" +#~ "%s is not regular file.\n" +#~ "Although inkscape will run, you can\n" +#~ "neither load nor save preferences\n" +#~ msgstr "" +#~ "%s er ikke en almindelig fil.\n" +#~ "Selvom sodipodi vil køre, kan du\n" +#~ "hverken indlæse eller gemme indstillinger\n" + +#, fuzzy +#~ msgid "" +#~ "%s either is not valid xml file or\n" +#~ "you do not have read premissions on it.\n" +#~ "Although inkscape will run, you\n" +#~ "are neither able to load nor save\n" +#~ "preferences." +#~ msgstr "" +#~ "%s er ikke en gyldig xml-fil eller\n" +#~ "du har ikke læserettigheder til den.\n" +#~ "Selvom sodipodi vil køre, kan du\n" +#~ "hverken indlæse eller gemme indstillinger." + +#, fuzzy +#~ msgid "" +#~ "%s is not valid inkscape preferences file.\n" +#~ "Although inkscape will run, you\n" +#~ "are neither able to load nor save\n" +#~ "preferences." +#~ msgstr "" +#~ "%s er ikke en gyldig sodipodi-indstillingsfil.\n" +#~ "Selvom sodipodi vil køre, kan du\n" +#~ "hverken indlæse eller gemme indstillinger." + +#, fuzzy +#~ msgid "" +#~ "Cannot create directory %s.\n" +#~ "Although inkscape will run, you\n" +#~ "are neither able to load nor save\n" +#~ "%s." +#~ msgstr "" +#~ "Kan ikke oprette kataloget %s.\n" +#~ "Selvom sodipodi vil køre, kan du\n" +#~ "hverken indlæse eller gemme indstillinger." + +#, fuzzy +#~ msgid "" +#~ "%s is not a valid directory.\n" +#~ "Although inkscape will run, you\n" +#~ "are neither able to load nor save\n" +#~ "preferences." +#~ msgstr "" +#~ "%s er ikke et gyldigt katalog.\n" +#~ "Selvom sodipodi vil køre, kan du\n" +#~ "hverken indlæse eller gemme indstillinger." + +#, fuzzy +#~ msgid "" +#~ "Cannot create file %s.\n" +#~ "Although inkscape will run, you\n" +#~ "are neither able to load nor save\n" +#~ "preferences." +#~ msgstr "" +#~ "Kan ikke oprette fil %s.\n" +#~ "Selvom sodipodi vil køre, kan du\n" +#~ "hverken indlæse eller gemme indstillinger." + +#, fuzzy +#~ msgid "" +#~ "Cannot write file %s.\n" +#~ "Although inkscape will run, you\n" +#~ "are neither able to load nor save\n" +#~ "preferences." +#~ msgstr "" +#~ "Kan ikke skrive fil %s.\n" +#~ "Selvom sodipodi vil køre, kan du\n" +#~ "hverken indlæse eller gemme indstillinger." + +#~ msgid "End color" +#~ msgstr "Slutfarve" + +#, fuzzy +#~ msgid "Make sides flat" +#~ msgstr "Gør følsom" + +#~ msgid "Bring to _Front" +#~ msgstr "Hent til _front" + +#~ msgid "Send to _Back" +#~ msgstr "Send til _baggrund" + +#~ msgid "Document %s has unsaved changes, save them?" +#~ msgstr "Dokument %s har ugemte ændringer, skal de gemmes?" + +#, fuzzy +#~ msgid "Object Size and Position" +#~ msgstr "Position" + +#, fuzzy +#~ msgid "Size and Position" +#~ msgstr "Position" + +#, fuzzy +#~ msgid "Tool attributes" +#~ msgstr "%s attributter" + +#, fuzzy +#~ msgid "Proportion" +#~ msgstr "Position" + +#, fuzzy +#~ msgid "Tool has no attributes" +#~ msgstr "%s attributter" + +#~ msgid "Item" +#~ msgstr "Element" + +#~ msgid "Group Properties" +#~ msgstr "Egenskaber for gruppe" + +#~ msgid "Ungroup" +#~ msgstr "Opdel gruppe" + +#~ msgid "Fill settings" +#~ msgstr "Indstillinger for fyld" + +#, fuzzy +#~ msgid "Break line at selected nodes" +#~ msgstr "Krøl linje ved valgte knuder" + +#, fuzzy +#~ msgid "Bring to Front" +#~ msgstr "Hent til _front" + +#, fuzzy +#~ msgid "Send to Back" +#~ msgstr "Send til _baggrund" + +#, fuzzy +#~ msgid "Lower selected objects to bottom" +#~ msgstr "Sænk det valgte til bunden" + +#, fuzzy +#~ msgid "Raise selected objects one position" +#~ msgstr "Hæv det valgte op til toppen" + +#, fuzzy +#~ msgid "Lower selected objects one position" +#~ msgstr "Sænk det valgte til bunden" + +#, fuzzy +#~ msgid "Draw freehand curves and straight lines" +#~ msgstr "Tegn frihÃ¥ndslinje" + +#, fuzzy +#~ msgid "In" +#~ msgstr "Tommer" + +#, fuzzy +#~ msgid "Toggle grid" +#~ msgstr "Skift kanter" + +#, fuzzy +#~ msgid "Toggle guides" +#~ msgstr "Skift kanter" + +#~ msgid "1:1" +#~ msgstr "1:1" + +#~ msgid "1:2" +#~ msgstr "1:2" + +#~ msgid "2:1" +#~ msgstr "2:1" + +#, fuzzy +#~ msgid "Editing window properties" +#~ msgstr "Egenskaber for lænke" + +#, fuzzy +#~ msgid "Tool Attributes" +#~ msgstr "Attributter" + +#~ msgid "Sodipodi" +#~ msgstr "Sodipodi" + +#~ msgid "Desktop settings" +#~ msgstr "Skrivebordets indstilinger" + +#, fuzzy +#~ msgid "Iso grid" +#~ msgstr "Vis gitter" + +#~ msgid "Display settings" +#~ msgstr "Indstillinger for skærm" + +#, fuzzy +#~ msgid "Export png file" +#~ msgstr "Eksportér fil" + +#, fuzzy +#~ msgid "Object style" +#~ msgstr "Ting" + +#, fuzzy +#~ msgid "Inkscape: %s : XML View" +#~ msgstr "Sodipodi: %s: %s: %d" + +#, fuzzy +#~ msgid "New Docked Toolbox" +#~ msgstr "Vis Værktøjskasse" + +#, fuzzy +#~ msgid "Drawing Mode" +#~ msgstr "Tegnesammenhæng" + +#, fuzzy +#~ msgid "" +#~ "%s is not regular file.\n" +#~ "Although inkscape will run, you are\n" +#~ "not able to use extensions (plugins)\n" +#~ msgstr "" +#~ "%s er ikke en almindelig fil.\n" +#~ "Selvom sodipodi vil køre, kan du\n" +#~ "hverken indlæse eller gemme indstillinger\n" + +#, fuzzy +#~ msgid "" +#~ "%s either is not valid xml file or\n" +#~ "you do not have read premissions on it.\n" +#~ "Although inkscape will run, you are\n" +#~ "not able to use extensions (plugins)\n" +#~ msgstr "" +#~ "%s er ikke en gyldig xml-fil eller\n" +#~ "du har ikke læserettigheder til den.\n" +#~ "Selvom sodipodi vil køre, kan du\n" +#~ "hverken indlæse eller gemme indstillinger." + +#, fuzzy +#~ msgid "" +#~ "%s is not valid inkscape extensions file.\n" +#~ "Although inkscape will run, you are\n" +#~ "not able to use extensions (plugins)\n" +#~ msgstr "" +#~ "%s er ikke en gyldig sodipodi-indstillingsfil.\n" +#~ "Selvom sodipodi vil køre, kan du\n" +#~ "hverken indlæse eller gemme indstillinger." + +#, fuzzy +#~ msgid "" +#~ "Cannot create directory %s.\n" +#~ "Although inkscape will run, you are\n" +#~ "not able to use extensions (plugins)\n" +#~ msgstr "" +#~ "Kan ikke oprette kataloget %s.\n" +#~ "Selvom sodipodi vil køre, kan du\n" +#~ "hverken indlæse eller gemme indstillinger." + +#, fuzzy +#~ msgid "" +#~ "%s is not a valid directory.\n" +#~ "Although inkscape will run, you are\n" +#~ "not able to use extensions (plugins)\n" +#~ msgstr "" +#~ "%s er ikke et gyldigt katalog.\n" +#~ "Selvom sodipodi vil køre, kan du\n" +#~ "hverken indlæse eller gemme indstillinger." + +#, fuzzy +#~ msgid "" +#~ "Cannot create file %s.\n" +#~ "Although inkscape will run, you are\n" +#~ "not able to use extensions (plugins)\n" +#~ msgstr "" +#~ "Kan ikke oprette fil %s.\n" +#~ "Selvom sodipodi vil køre, kan du\n" +#~ "hverken indlæse eller gemme indstillinger." + +#, fuzzy +#~ msgid "" +#~ "Cannot write file %s.\n" +#~ "Although inkscape will run, you are\n" +#~ "not able to use extensions (plugins)\n" +#~ msgstr "" +#~ "Kan ikke skrive fil %s.\n" +#~ "Selvom sodipodi vil køre, kan du\n" +#~ "hverken indlæse eller gemme indstillinger." + +#~ msgid "Unknown item :-(" +#~ msgstr "Ukendt element :-(" + +#, fuzzy +#~ msgid "Zoom in drawing" +#~ msgstr "Zoom til tegning" + +#, fuzzy +#~ msgid "Set zoom factor to 1:1" +#~ msgstr "Zoom til 1:1" + +#, fuzzy +#~ msgid "Set zoom factor to 1:2" +#~ msgstr "Zoom til 1:2" + +#, fuzzy +#~ msgid "Set zoom factor to 2:1" +#~ msgstr "Zoom til 2:1" + +#~ msgid "Document" +#~ msgstr "Dokument" + +#, fuzzy +#~ msgid "Document variant:" +#~ msgstr "Dokument" + +#, fuzzy +#~ msgid "Save document as" +#~ msgstr "Lagret dokument %d" + +#~ msgid "About sodipodi" +#~ msgstr "Om Sodipodi" + +#, fuzzy +#~ msgid "About Sodipodi" +#~ msgstr "Om Sodipodi" + +#~ msgid "The SVG ID of item" +#~ msgstr "SWG ID for element" + +#~ msgid "The ID is not valid" +#~ msgstr "ID er ikke gyldig" + +#~ msgid "The ID is already defined" +#~ msgstr "ID er allerede defineret" + +#, fuzzy +#~ msgid "Position and size" +#~ msgstr "Position" + +#~ msgid "Dynahand" +#~ msgstr "Dynamisk frihÃ¥nd" + +#, fuzzy +#~ msgid "Display Properties" +#~ msgstr "Egenskaber for spiral" + +#, fuzzy +#~ msgid "Lower selected objects one level" +#~ msgstr "Omform valgte ting til kurver" + +#, fuzzy +#~ msgid "Select tool - select and transform objects" +#~ msgstr "Vælg og transformér" + +#, fuzzy +#~ msgid "Save as:" +#~ msgstr "Gem" + +#~ msgid "A path - whatever it means" +#~ msgstr "En sti - hvad det sÃ¥ end betyder" + +#~ msgid "Welcome !" +#~ msgstr "Velkommen!" + +#~ msgid "Sodipodi SVG Document" +#~ msgstr "Sodipodi SVG-dokument" + +#~ msgid "Sodipodi SVG Document factory" +#~ msgstr "Sodipodi SVG-dokument fabrik" + +#~ msgid "Align objects to vertical mid" +#~ msgstr "Justér objekter til lodret midte" + +#~ msgid "Align outside object to bottom border" +#~ msgstr "Justér ydre objekt til bundkant" + +#~ msgid "Align outside object to left border" +#~ msgstr "Justér ydre objekt til venstre kant" + +#~ msgid "Align outside object to right border" +#~ msgstr "Justér ydre objekt til højre kant" + +#~ msgid "Align outside object to top border" +#~ msgstr "Justér ydre objekt til topkant" + +#~ msgid "Alignment base" +#~ msgstr "Basis for justering" + +#~ msgid "Choose align type" +#~ msgstr "Vælg justeringstype" + +#~ msgid "Parent X =" +#~ msgstr "Forælder X =" + +#~ msgid "Parent Y =" +#~ msgstr "Forælder Y =" + +#~ msgid "Y +" +#~ msgstr "Y +" + +#~ msgid " Color fill " +#~ msgstr " Udfyld med farve " + +#~ msgid " General " +#~ msgstr " Generelt " + +#~ msgid "Add new gradient" +#~ msgstr "Tilføj ny farveovergang" + +#~ msgid "Behind fill" +#~ msgstr "Baggrundsfyld" + +#~ msgid "Butt endpoints" +#~ msgstr "Afstumpede endepunkter" + +#~ msgid "Choose fill color" +#~ msgstr "Vælg farve for udfyldning" + +#~ msgid "Choose stroke color" +#~ msgstr "Vælg farve for strøg" + +#~ msgid "Endpoints:" +#~ msgstr "Endepunkter:" + +#~ msgid "Fill Color:" +#~ msgstr "Udfyldningsfarve:" + +#~ msgid "Fractal fill" +#~ msgstr "Fraktalfyld" + +#~ msgid "Pick fill color" +#~ msgstr "Vælg farve for udfyldning" + +#~ msgid "Scale with object" +#~ msgstr "Skalér med objekt" + +#~ msgid "centimeter" +#~ msgstr "centimeter" + +#~ msgid "color" +#~ msgstr "farve" + +#~ msgid "millimeters" +#~ msgstr "millimeter" + +#~ msgid "points" +#~ msgstr "punkter" + +#~ msgid "1.0MB" +#~ msgstr "1.0Mb" + +#~ msgid "Back One" +#~ msgstr "Et niveau tilbage" + +#~ msgid "Convert selected segments to curves" +#~ msgstr "Konvertér valgte segmenter til kurver" + +#~ msgid "Cusp line at selected nodes" +#~ msgstr "Krøl linje ved valgte knuder" + +#~ msgid "Desktop" +#~ msgstr "Skrivebord" + +#~ msgid "Drawing Context" +#~ msgstr "Tegnesammenhæng" + +#~ msgid "Export picture to png" +#~ msgstr "Eksportér billede til png" + +#~ msgid "Forward One" +#~ msgstr "Et niveau frem" + +#~ msgid "Include one node into selected segments" +#~ msgstr "Inkludér en knude i valgte segmenter" + +#~ msgid "Join 2 selected endpoints" +#~ msgstr "Forbind 2 valgte endepunkter" + +#~ msgid "Set dimensions" +#~ msgstr "Sæt dimensioner" + +#~ msgid "Smooth line at selected nodes" +#~ msgstr "Udjævn linje ved valgte knuder" + +#~ msgid "Where to export" +#~ msgstr "EksportmÃ¥l" + +#~ msgid "X0" +#~ msgstr "X0" + +#~ msgid "XML Tree" +#~ msgstr "XML-træ" + +#~ msgid "Y0" +#~ msgstr "Y0" + +#~ msgid "_Align" +#~ msgstr "_Justér" + +#~ msgid "Break apart selected paths" +#~ msgstr "Opbryd valgte knude" + +#~ msgid "Drawing context" +#~ msgstr "Tegnesammenhæng" + +#~ msgid "Edit font style of selected objects" +#~ msgstr "Redigér skriftsnitstil for valgte ting" + +#~ msgid "Import " +#~ msgstr "Importér " + +#~ msgid "New drawing" +#~ msgstr "Ny tegning" + +#~ msgid "No I'd rather do some more cool vector drawing with sodipodi." +#~ msgstr "Nej jeg vil hellere lave nogle flere fede tegninger med Sodipodi." + +#~ msgid "Nope !" +#~ msgstr "Niks!" + +#~ msgid "Paste from clipboard" +#~ msgstr "Indsæt fra klippebord" + +#~ msgid "Preview print drawing" +#~ msgstr "Smugkig udskriftstegning" + +#~ msgid "Quit or not quit ?" +#~ msgstr "Afslut eller ej?" + +#~ msgid "Really wanna quit sodipodi ?" +#~ msgstr "Vil du virkelig afslutte Sodipodi?" + +#, fuzzy +#~ msgid "Rotate selected objects 90deg clockwise" +#~ msgstr "Drej valgte ting 90° med uret" + +#~ msgid "Save drawing " +#~ msgstr "Gem tegning " + +#~ msgid "Yep !" +#~ msgstr "Jahh!" + +#~ msgid "Yes quick! I want to leave sodipodi and come back later." +#~ msgstr "" +#~ "Ja, hurtigt! Jeg ønsker at forlade Sodipodi og komme tilbage senere." + +#~ msgid "Align to bottom middle" +#~ msgstr "Justér til nederst for midten" + +#~ msgid "Align to bottom right" +#~ msgstr "Justér til nederst til højre" + +#~ msgid "Align to center" +#~ msgstr "Justér til center" + +#~ msgid "Align to top middle" +#~ msgstr "Justér til øverst pÃ¥ midten" + +#~ msgid "Choose metric for center" +#~ msgstr "Vælg mÃ¥leenhed for centrering" + +#~ msgid "Close dialog - Ctl+c" +#~ msgstr "Luk dialog - ctrl+c" + +#~ msgid "Expand dialog - Ctl+e" +#~ msgstr "Udvid dialog - ctrl+e" + +#~ msgid "Keep height of selection during transformation" +#~ msgstr "Behold højde pÃ¥ det valgte under transformering" + +#~ msgid "Keep width of selection during transformation" +#~ msgstr "Behold bredde pÃ¥ det valgte under transformering" + +#~ msgid "Orig. Width: " +#~ msgstr "Oprindelig bredde: " + +#~ msgid "Orig. X: " +#~ msgstr "Udgangspunkt X: " + +#~ msgid "Set angle to 0 degrees" +#~ msgstr "Sæt vinkel til 0°" + +#~ msgid "Set angle to 180 degrees" +#~ msgstr "Sæt vinkel til 180°" + +#~ msgid "Set angle to 270 degrees" +#~ msgstr "Sæt vinkel til 270°" + +#~ msgid "Start transformation - Ctl+a" +#~ msgstr "Start transformering - ctrl+a" + +#~ msgid "Toggle center given in selection/desktop coordiantes" +#~ msgstr "Skift centrum givet ved valg/skrivebords-koordinater" + +#~ msgid "Use alignment during transformation" +#~ msgstr "Brug justering ved transformation" + +#~ msgid "Use center as transformation fixpoint" +#~ msgstr "Brug centrum som omdrejningspunkt for transformation" + +#~ msgid "Y: " +#~ msgstr "Y: " + +#~ msgid "keep aspect" +#~ msgstr "behold aspekt" + +#~ msgid "lock/unlock horizontal and vertical scale" +#~ msgstr "lÃ¥s/Ã¥bn vandret og lodret skala" + +#~ msgid "select direction" +#~ msgstr "vælg retning" + +#~ msgid "select direction (horizontal/vertical skew)" +#~ msgstr "vælg retning (vandret/lodret drejning)" + +#~ msgid "select metric for scale" +#~ msgstr "vælg mÃ¥leenged for skala" + +#~ msgid "select metric for values" +#~ msgstr "vælg mÃ¥leenhed for værdier" + +#~ msgid "skew" +#~ msgstr "drej" + +#~ msgid "toggle absolute/relative move" +#~ msgstr "skift mellem absolut/relativ flytning" + +#~ msgid "toggle absolute/relative scale" +#~ msgstr "skift mellem absolut/relativ skala" + +#~ msgid "Change Attribute" +#~ msgstr "Ændr attribut" + +#, fuzzy +#~ msgid "Change Content" +#~ msgstr "Tegnesammenhæng" + +#~ msgid "Do you want to delete attribute?" +#~ msgstr "Ønsker du at slette attributten?" + +#~ msgid "Hierarchy" +#~ msgstr "Hierarki" + +#~ msgid "Key" +#~ msgstr "Nøgle" + +#~ msgid "Don't save" +#~ msgstr "Gem ikke" + +#, fuzzy +#~ msgid "You can't delete 'id' attribute!" +#~ msgstr "Ønsker du at slette attributten?" + +#, fuzzy +#~ msgid "Do you want to delete attribute %s?" +#~ msgstr "Ønsker du at slette attributten?" + +#, fuzzy +#~ msgid "No" +#~ msgstr "Node" + +#, fuzzy +#~ msgid "Do you want to delete element %s?" +#~ msgstr "Ønsker du at slette attributten?" + +#~ msgid "\"" +#~ msgstr "\"" + +#~ msgid "Choose base unit system for grid" +#~ msgstr "Vælg basismÃ¥leenhed for gitter" + +#~ msgid "Choose color for grid" +#~ msgstr "Vælg farve for gitter" + +#~ msgid "Choose unit system for grid snapping" +#~ msgstr "Vælg mÃ¥leenhed for fastgørelse til gitter" + +#~ msgid "Choose unit system for guideline snapping" +#~ msgstr "Vælg mÃ¥leenhed for fastgørelse til hjælpelinjer" + +#~ msgid "Set maximum distance for grid snapping" +#~ msgstr "Sæt største afstand for pÃ¥sættelse til gitter" + +#~ msgid "Set maximum distance for guideline snapping" +#~ msgstr "Vælg største afstand for fastgørelse til hjælpelinjer" + +#~ msgid "Set origin of page coordinate system" +#~ msgstr "Sæt udgangspunkt for koordinatsystem for siden" + +#~ msgid "Choose paper size" +#~ msgstr "Vælg papirstørrelse" + +#~ msgid "Choose unit system" +#~ msgstr "Vælg mÃ¥leenhed" + +#~ msgid "Set page height" +#~ msgstr "Sæt sidehøjde" + +#~ msgid "Draw ellipse" +#~ msgstr "Tegn ellipse" + +#~ msgid "Dup" +#~ msgstr "Dup" + +#~ msgid "Empty" +#~ msgstr "Tom" + +#~ msgid "Do not use GUI. NB! if exist, should be FIRST argument!" +#~ msgstr "Brug ikke GUI. NB! hvis det angives bør dette være FØRSTE argument!" + +#~ msgid "Could not initialize Bonobo" +#~ msgstr "Kunne ikke initialisere Bonobo" diff --git a/po/de.po b/po/de.po new file mode 100644 index 000000000..3fb4b809a --- /dev/null +++ b/po/de.po @@ -0,0 +1,10519 @@ +# German translation for Inkscape. +# Copyright (C) 2000-2003 Free Software Foundation, Inc. +# Kai Lahmann , 2000 +# Benedikt Roth , 2000 +# Christian Meyer , 2000-2002. +# Christian Neumair , 2002, 2003. +# Colin Marquardt , 2004, 2005. +# Adib Taraben , 2004. +# Jörg Müller , 2005. +# +msgid "" +msgstr "" +"Project-Id-Version: inkscape 0.43\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2005-12-04 11:51-0800\n" +"PO-Revision-Date: 2005-11-07 00:33+0100\n" +"Last-Translator: Colin Marquardt \n" +"Language-Team: German \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: ../inkscape.desktop.in.h:1 +msgid "Create and edit Scalable Vector Graphics images" +msgstr "Skalierbare Vektorgrafiken (SVG) erzeugen und bearbeiten" + +#: ../inkscape.desktop.in.h:2 +msgid "Inkscape SVG Vector Illustrator" +msgstr "Inkscape SVG-Vektorillustrator" + +#: ../../po/../src/arc-context.cpp:350 +msgid "" +"Ctrl: make circle or integer-ratio ellipse, snap arc/segment angle" +msgstr "" +"Strg: Erzeuge Kreis oder Ellipse mit ganzzahligem Höhen-/" +"Breitenverhältnis, Winkel vom Bogen/Kreissegment einrasten" + +#: ../../po/../src/arc-context.cpp:351 ../../po/../src/rect-context.cpp:388 +msgid "Shift: draw around the starting point" +msgstr "Umschalt: Ausgehend vom Mittelpunkt zeichnen" + +#: ../../po/../src/arc-context.cpp:413 +#: ../../po/../src/connector-context.cpp:493 +#: ../../po/../src/dyna-draw-context.cpp:506 +#: ../../po/../src/pen-context.cpp:329 ../../po/../src/pencil-context.cpp:208 +#: ../../po/../src/rect-context.cpp:452 ../../po/../src/spiral-context.cpp:421 +#: ../../po/../src/star-context.cpp:427 +msgid "Current layer is hidden. Unhide it to be able to draw on it." +msgstr "" +"Aktuelle Ebene ist verborgen. Sichtbar schalten, um darauf zu " +"zeichnen." + +#: ../../po/../src/arc-context.cpp:417 +#: ../../po/../src/connector-context.cpp:497 +#: ../../po/../src/dyna-draw-context.cpp:510 +#: ../../po/../src/pen-context.cpp:336 ../../po/../src/pencil-context.cpp:212 +#: ../../po/../src/rect-context.cpp:456 ../../po/../src/spiral-context.cpp:426 +#: ../../po/../src/star-context.cpp:431 +msgid "Current layer is locked. Unlock it to be able to draw on it." +msgstr "Aktuelle Ebene ist gesperrt. Entsperren, um darauf zu zeichnen." + +#: ../../po/../src/arc-context.cpp:496 +#, c-format +msgid "" +"Ellipse: %s × %s; with Ctrl to make circle or integer-" +"ratio ellipse; with Shift to draw around the starting point" +msgstr "" +"Ellipse: %s × %s; Strg drücken für ganzzahlige Verhältnisse " +"der Radien; Umschalt zeichnet Ellipse/Kreis konzentrisch vom Zeiger " +"aus" + +#: ../../po/../src/connector-context.cpp:518 +msgid "Creating new connector" +msgstr "Einen neuen Objektverbinder erzeugen" + +# !!! +#: ../../po/../src/connector-context.cpp:939 +msgid "Finishing connector" +msgstr "Fertig mit Objektverbinder" + +#: ../../po/../src/connector-context.cpp:1108 +msgid "Connection point: click or drag to create a new connector" +msgstr "" +"Verbindungspunkt: klicken oder ziehen, um einen neuen Objektverbinder " +"zu erzeugen" + +#: ../../po/../src/connector-context.cpp:1185 +msgid "Connector endpoint: drag to reroute or connect to new shapes" +msgstr "" +"Objektverbinder-Endpunkt: ziehen, um neu zu verlegen oder mit neuen " +"Formen zu verbinden" + +#: ../../po/../src/connector-context.cpp:1278 +msgid "Select at least one non-connector object." +msgstr "Mindestens 1 Objekt auswählen, das kein Objektverbinder ist." + +#: ../../po/../src/desktop-events.cpp:238 +#, c-format +msgid "%s at %s" +msgstr "%s um %s" + +#. TRANSLATORS: This string appears when double-clicking on a guide. +#. This is the distance by which the guide is to be moved. +#: ../../po/../src/desktop-events.cpp:277 +msgid " relative by " +msgstr " relativ um " + +#. TRANSLATORS: This string appears when double-clicking on a guide. +#. This is the target location where the guide is to be moved. +#: ../../po/../src/desktop-events.cpp:282 +#: ../../po/../src/desktop-events.cpp:395 +msgid " absolute to " +msgstr " absolut zu " + +#. create dialog +#: ../../po/../src/desktop-events.cpp:348 +msgid "Guideline" +msgstr "Führungslinie" + +#: ../../po/../src/desktop-events.cpp:432 +#, c-format +msgid "Move %s" +msgstr "Verschiebe %s" + +#: ../../po/../src/desktop.cpp:678 +msgid "No previous zoom." +msgstr "Kein vorheriger Zoomfaktor." + +#: ../../po/../src/desktop.cpp:703 +msgid "No next zoom." +msgstr "Kein nächster Zoomfaktor." + +#: ../../po/../src/dialogs/clonetiler.cpp:182 +msgid "Nothing selected." +msgstr "Es wurde nichts ausgewählt." + +#: ../../po/../src/dialogs/clonetiler.cpp:188 +msgid "More than one object selected." +msgstr "Mehr als ein Objekt ausgewählt." + +#: ../../po/../src/dialogs/clonetiler.cpp:195 +#, c-format +msgid "Object has %d tiled clones." +msgstr "Das Objekt hat %d gekachelte Klone." + +#: ../../po/../src/dialogs/clonetiler.cpp:200 +msgid "Object has no tiled clones." +msgstr "Das Object hat keine gekachelten Klone." + +#: ../../po/../src/dialogs/clonetiler.cpp:865 +msgid "Select one object whose tiled clones to unclump." +msgstr "Ein Objekt auswählen, dessen gekachelte Klone entklumpt werden." + +#: ../../po/../src/dialogs/clonetiler.cpp:916 +msgid "Select one object whose tiled clones to remove." +msgstr "Ein Objekt auswählen, dessen gekachelte Klone entfernt werden." + +#: ../../po/../src/dialogs/clonetiler.cpp:984 +#: ../../po/../src/selection-chemistry.cpp:1774 +msgid "Select an object to clone." +msgstr "Zu klonendes Objekt auswählen." + +#: ../../po/../src/dialogs/clonetiler.cpp:990 +#: ../../po/../src/selection-chemistry.cpp:1780 +msgid "" +"If you want to clone several objects, group them and clone the " +"group." +msgstr "" +"Wenn mehrere Objekte geklont werden sollen, sollten sie gruppiert und " +"dann als Gruppe geklont werden." + +#: ../../po/../src/dialogs/clonetiler.cpp:1484 +msgid "Per row:" +msgstr "Pro Reihe:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1497 +msgid "Per column:" +msgstr "Pro Spalte" + +#: ../../po/../src/dialogs/clonetiler.cpp:1505 +msgid "Randomize:" +msgstr "Zufallsfaktor:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1656 +msgid "_Symmetry" +msgstr "Symmetrie" + +#. TRANSLATORS: For the following 17 symmetry groups, see +#. * http://www.bib.ulb.ac.be/coursmath/doc/17.htm (visual examples); +#. * http://www.clarku.edu/~djoyce/wallpaper/seventeen.html (English vocabulary); or +#. * http://membres.lycos.fr/villemingerard/Geometri/Sym1D.htm (French vocabulary). +#. +#: ../../po/../src/dialogs/clonetiler.cpp:1664 +msgid "Select one of the 17 symmetry groups for the tiling" +msgstr "Eine der 17 Symmetrie-Gruppen zum Kacheln auswählen" + +#. TRANSLATORS: "translation" means "shift" / "displacement" here. +#: ../../po/../src/dialogs/clonetiler.cpp:1675 +msgid "P1: simple translation" +msgstr "P1: einfache Verschiebung" + +#: ../../po/../src/dialogs/clonetiler.cpp:1676 +msgid "P2: 180° rotation" +msgstr "P2: 180° Rotation" + +#: ../../po/../src/dialogs/clonetiler.cpp:1677 +msgid "PM: reflection" +msgstr "PM: Reflektion" + +#. TRANSLATORS: "glide reflection" is a reflection and a translation combined. +#. For more info, see http://mathforum.org/sum95/suzanne/symsusan.html +#: ../../po/../src/dialogs/clonetiler.cpp:1680 +msgid "PG: glide reflection" +msgstr "PG: gleitende Reflektion" + +#: ../../po/../src/dialogs/clonetiler.cpp:1681 +msgid "CM: reflection + glide reflection" +msgstr "CM: Reflektion + gleitende Reflektion" + +#: ../../po/../src/dialogs/clonetiler.cpp:1682 +msgid "PMM: reflection + reflection" +msgstr "PMM: Reflektion + Reflektion" + +#: ../../po/../src/dialogs/clonetiler.cpp:1683 +msgid "PMG: reflection + 180° rotation" +msgstr "PMG: Reflektion + 180° Rotation" + +#: ../../po/../src/dialogs/clonetiler.cpp:1684 +msgid "PGG: glide reflection + 180° rotation" +msgstr "PGG: gleitende Reflektion + 180° Rotation" + +#: ../../po/../src/dialogs/clonetiler.cpp:1685 +msgid "CMM: reflection + reflection + 180° rotation" +msgstr "CMM: Reflektion + Reflektion + 180° Rotation" + +#: ../../po/../src/dialogs/clonetiler.cpp:1686 +msgid "P4: 90° rotation" +msgstr "P4: 90° Rotation" + +#: ../../po/../src/dialogs/clonetiler.cpp:1687 +msgid "P4M: 90° rotation + 45° reflection" +msgstr "P4M: 90° Rotation + 45° Reflektion" + +#: ../../po/../src/dialogs/clonetiler.cpp:1688 +msgid "P4G: 90° rotation + 90° reflection" +msgstr "P4G: 90° Rotation + 90° Reflektion" + +#: ../../po/../src/dialogs/clonetiler.cpp:1689 +msgid "P3: 120° rotation" +msgstr "P3: 120° Rotation" + +#: ../../po/../src/dialogs/clonetiler.cpp:1690 +msgid "P31M: reflection + 120° rotation, dense" +msgstr "P31M: Reflektion + 120° Rotation, dicht" + +#: ../../po/../src/dialogs/clonetiler.cpp:1691 +msgid "P3M1: reflection + 120° rotation, sparse" +msgstr "P3M1: Reflektion + 120° Rotation, spärlich" + +#: ../../po/../src/dialogs/clonetiler.cpp:1692 +msgid "P6: 60° rotation" +msgstr "P6: 60° Rotation" + +#: ../../po/../src/dialogs/clonetiler.cpp:1693 +msgid "P6M: reflection + 60° rotation" +msgstr "P6M: Reflektion + 60° Rotation" + +#: ../../po/../src/dialogs/clonetiler.cpp:1721 +msgid "S_hift" +msgstr "Umschalt" + +#. TRANSLATORS: "shift" means: the tiles will be shifted (offset) horizontally by this amount +#: ../../po/../src/dialogs/clonetiler.cpp:1731 +#, no-c-format +msgid "Shift X:" +msgstr "X-Verschiebung:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1739 +#, no-c-format +msgid "Horizontal shift per row (in % of tile width)" +msgstr "Horizontale Verschiebung pro Reihe (in % der Kachelbreite)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1747 +#, no-c-format +msgid "Horizontal shift per column (in % of tile width)" +msgstr "Horizontale Verschiebung pro Spalte (in % der Kachelbreite)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1754 +msgid "Randomize the horizontal shift by this percentage" +msgstr "Zufällige horizontale Verschiebung um diesen Prozentsatz" + +#. TRANSLATORS: "shift" means: the tiles will be shifted (offset) vertically by this amount +#: ../../po/../src/dialogs/clonetiler.cpp:1764 +#, no-c-format +msgid "Shift Y:" +msgstr "Y-Verschiebung:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1772 +#, no-c-format +msgid "Vertical shift per row (in % of tile height)" +msgstr "Vertikale Verschiebung pro Reihe (in % der Kachelhöhe)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1780 +#, no-c-format +msgid "Vertical shift per column (in % of tile height)" +msgstr "Vertikale Verschiebung pro Spalte (in % der Kachelhöhe)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1787 +msgid "Randomize the vertical shift by this percentage" +msgstr "Zufällige vertikale Verschiebung um diesen Prozentsatz" + +#: ../../po/../src/dialogs/clonetiler.cpp:1795 +msgid "Exponent:" +msgstr "Exponent:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1802 +msgid "Whether rows are spaced evenly (1), converge (<1) or diverge (>1)" +msgstr "" +"Reihenabstände bleiben gleich (1), laufen zusammen (<1) oder vergrößen sich " +"(>1)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1809 +msgid "Whether columns are spaced evenly (1), converge (<1) or diverge (>1)" +msgstr "" +"Spaltenabstände bleiben gleich (1), laufen zusammen (<1) oder vergrößen sich " +"(>1)" + +#. TRANSLATORS: "Alternate" is a verb here +#: ../../po/../src/dialogs/clonetiler.cpp:1817 +#: ../../po/../src/dialogs/clonetiler.cpp:1907 +#: ../../po/../src/dialogs/clonetiler.cpp:1966 +#: ../../po/../src/dialogs/clonetiler.cpp:2022 +#: ../../po/../src/dialogs/clonetiler.cpp:2153 +msgid "Alternate:" +msgstr "Abwechseln:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1823 +msgid "Alternate the sign of shifts for each row" +msgstr "Vorzeichenumkehrung der Verschiebungen für jede Reihe" + +#: ../../po/../src/dialogs/clonetiler.cpp:1828 +msgid "Alternate the sign of shifts for each column" +msgstr "Vorzeichenumkehrung bei der Verschiebungen für jede Spalte" + +#: ../../po/../src/dialogs/clonetiler.cpp:1837 +msgid "Sc_ale" +msgstr "Maßstab" + +#: ../../po/../src/dialogs/clonetiler.cpp:1845 +msgid "Scale X:" +msgstr "X-Skalierung:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1853 +#, no-c-format +msgid "Horizontal scale per row (in % of tile width)" +msgstr "Horizontale Verschiebung pro Reihe (in % der Kachelbreite)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1861 +#, no-c-format +msgid "Horizontal scale per column (in % of tile width)" +msgstr "Horizontale Skalierung pro Spalte (in % der Kachelbreite)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1868 +msgid "Randomize the horizontal scale by this percentage" +msgstr "Horizontale Skalierung um diesen Prozentsatz zufällig verändern" + +#: ../../po/../src/dialogs/clonetiler.cpp:1876 +msgid "Scale Y:" +msgstr "Y-Skalierung:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1884 +#, no-c-format +msgid "Vertical scale per row (in % of tile height)" +msgstr "Vertikale Verschiebung pro Reihe (in % der Kachelhöhe)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1892 +#, no-c-format +msgid "Vertical scale per column (in % of tile height)" +msgstr "Vertikale Verschiebung pro Spalte (in % der Kachelhöhe)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1899 +msgid "Randomize the vertical scale by this percentage" +msgstr "Vertikale Skalierung um diesen Prozentsatz zufällig verändern" + +#: ../../po/../src/dialogs/clonetiler.cpp:1913 +msgid "Alternate the sign of scales for each row" +msgstr "Vorzeichen der Verschiebungen für jede Reihe umkehren" + +#: ../../po/../src/dialogs/clonetiler.cpp:1918 +msgid "Alternate the sign of scales for each column" +msgstr "Vorzeichen der Verschiebungen für jede Spalte umkehren" + +#: ../../po/../src/dialogs/clonetiler.cpp:1927 +msgid "_Rotation" +msgstr "_Rotation" + +#: ../../po/../src/dialogs/clonetiler.cpp:1935 +msgid "Angle:" +msgstr "Winkel:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1943 +#, no-c-format +msgid "Rotate tiles by this angle for each row" +msgstr "Kacheln um diesen Winkel für jede Reihe drehen" + +#: ../../po/../src/dialogs/clonetiler.cpp:1951 +#, no-c-format +msgid "Rotate tiles by this angle for each column" +msgstr "Kacheln um diesen Winkel für jede Spalte drehen" + +#: ../../po/../src/dialogs/clonetiler.cpp:1958 +msgid "Randomize the rotation angle by this percentage" +msgstr "Rotationswinkel um diesen Prozentsatz zufällig verändern" + +#: ../../po/../src/dialogs/clonetiler.cpp:1972 +msgid "Alternate the rotation direction for each row" +msgstr "Vorzeichenumkehrung des Rotationsfaktors bei jeder Reihe" + +#: ../../po/../src/dialogs/clonetiler.cpp:1977 +msgid "Alternate the rotation direction for each column" +msgstr "Vorzeichenumkehrung des Rotationsfaktors bei jeder Spalte" + +#: ../../po/../src/dialogs/clonetiler.cpp:1985 +msgid "_Opacity" +msgstr "_Deckkraft" + +#: ../../po/../src/dialogs/clonetiler.cpp:1993 +msgid "Fade out:" +msgstr "Ausblenden:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2000 +msgid "Decrease tile opacity by this percentage for each row" +msgstr "Deckkraft der Kacheln um diesen Prozentsatz für jede Reihe verringern" + +#: ../../po/../src/dialogs/clonetiler.cpp:2007 +msgid "Decrease tile opacity by this percentage for each column" +msgstr "Deckkraft der Kacheln um diesen Prozentsatz für jede Spalte verringern" + +#: ../../po/../src/dialogs/clonetiler.cpp:2014 +msgid "Randomize the tile opacity by this percentage" +msgstr "Deckkraft der Kacheln um diesen Prozentsatz zufällig verändern" + +#: ../../po/../src/dialogs/clonetiler.cpp:2028 +msgid "Alternate the sign of opacity change for each row" +msgstr "Vorzeichen des Transparenzfaktors bei jeder Reihe umkehren" + +#: ../../po/../src/dialogs/clonetiler.cpp:2033 +msgid "Alternate the sign of opacity change for each column" +msgstr "Vorzeichen des Transparenzfaktors bei jeder Spalte umkehren" + +#: ../../po/../src/dialogs/clonetiler.cpp:2041 +msgid "Co_lor" +msgstr "Farbe" + +#: ../../po/../src/dialogs/clonetiler.cpp:2046 +msgid "Initial color: " +msgstr "Ursprüngliche Farbe: " + +#: ../../po/../src/dialogs/clonetiler.cpp:2050 +msgid "Initial color of tiled clones" +msgstr "Ursprüngliche Farbe der gekachelten Klone" + +#: ../../po/../src/dialogs/clonetiler.cpp:2050 +msgid "" +"Initial color for clones (works only if the original has unset fill or " +"stroke)" +msgstr "" +"Ursprüngliche Farbe der Klone (Füllung oder Kontur des Originals dürfen " +"nicht gesetzt sein )" + +#: ../../po/../src/dialogs/clonetiler.cpp:2065 +msgid "H:" +msgstr "H:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2072 +msgid "Change the tile hue by this percentage for each row" +msgstr "Farbton der Kacheln um diesen Prozentsatz für jede Reihe verändern" + +#: ../../po/../src/dialogs/clonetiler.cpp:2079 +msgid "Change the tile hue by this percentage for each column" +msgstr "Farbton der Kacheln um diesen Prozentsatz für jede Spalte verändern" + +#: ../../po/../src/dialogs/clonetiler.cpp:2086 +msgid "Randomize the tile hue by this percentage" +msgstr "Farbton der Kachel zufällig um diesen Prozentsatz verändern" + +#: ../../po/../src/dialogs/clonetiler.cpp:2095 +msgid "S:" +msgstr "S:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2102 +msgid "Change the color saturation by this percentage for each row" +msgstr "" +"Farbsättigung der Kacheln um diesen Prozentsatz für jede Reihe verändern" + +#: ../../po/../src/dialogs/clonetiler.cpp:2109 +msgid "Change the color saturation by this percentage for each column" +msgstr "" +"Farbsättigung der Kacheln um diesen Prozentsatz für jede Spalte verändern" + +#: ../../po/../src/dialogs/clonetiler.cpp:2116 +msgid "Randomize the color saturation by this percentage" +msgstr "Farbsättigung um diesen Prozentsatz zufällig verändern" + +#: ../../po/../src/dialogs/clonetiler.cpp:2124 +msgid "L:" +msgstr "L:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2131 +msgid "Change the color lightness by this percentage for each row" +msgstr "Helligkeit der Kacheln um diesen Prozentsatz für jede Reihe verändern" + +#: ../../po/../src/dialogs/clonetiler.cpp:2138 +msgid "Change the color lightness by this percentage for each column" +msgstr "Helligkeit der Kacheln um diesen Prozentsatz für jede Spalte verändern" + +#: ../../po/../src/dialogs/clonetiler.cpp:2145 +msgid "Randomize the color lightness by this percentage" +msgstr "Helligkeitsanteil der Farbe zufällig um diesen Prozentsatz verändern" + +#: ../../po/../src/dialogs/clonetiler.cpp:2159 +msgid "Alternate the sign of color changes for each row" +msgstr "Vorzeichen der Farbänderungen bei jeder Reihe umkehren" + +#: ../../po/../src/dialogs/clonetiler.cpp:2164 +msgid "Alternate the sign of color changes for each column" +msgstr "Vorzeichen der Farbänderungen bei jeder Spalte umkehren" + +#: ../../po/../src/dialogs/clonetiler.cpp:2172 +msgid "_Trace" +msgstr "Bild _vektorisieren" + +#: ../../po/../src/dialogs/clonetiler.cpp:2179 +msgid "Trace the drawing under the tiles" +msgstr "Zeichnung unter den Kacheln vektorisieren" + +#: ../../po/../src/dialogs/clonetiler.cpp:2183 +msgid "" +"For each clone, pick a value from the drawing in that clone's location and " +"apply it to the clone" +msgstr "" +"Für jeden Klon den entsprechenden Wert an dieser Stelle aus der Zeichnung " +"anwenden" + +#: ../../po/../src/dialogs/clonetiler.cpp:2197 +msgid "1. Pick from the drawing:" +msgstr "1. Von der Zeichnung übernehmen:" + +#. ----Hbox2 +#: ../../po/../src/dialogs/clonetiler.cpp:2208 +#: ../../po/../src/dialogs/clonetiler.cpp:2355 +#: ../../po/../src/ui/dialog/tracedialog.cpp:445 +msgid "Color" +msgstr "Farbe" + +#: ../../po/../src/dialogs/clonetiler.cpp:2209 +msgid "Pick the visible color and opacity" +msgstr "Sichtbare Farbe und Deckkraft aufnehmen" + +#: ../../po/../src/dialogs/clonetiler.cpp:2216 +#: ../../po/../src/dialogs/clonetiler.cpp:2365 +#: ../share/extensions/dropshadow.inx.h:3 +msgid "Opacity" +msgstr "Deckkraft" + +#: ../../po/../src/dialogs/clonetiler.cpp:2217 +msgid "Pick the total accumulated opacity" +msgstr "Zusammengerechnete Deckkraft übernehmen" + +#: ../../po/../src/dialogs/clonetiler.cpp:2224 +msgid "R" +msgstr "R" + +#: ../../po/../src/dialogs/clonetiler.cpp:2225 +msgid "Pick the Red component of the color" +msgstr "Rotanteil der Farbe übernehmen" + +#: ../../po/../src/dialogs/clonetiler.cpp:2232 +msgid "G" +msgstr "G" + +#: ../../po/../src/dialogs/clonetiler.cpp:2233 +msgid "Pick the Green component of the color" +msgstr "Grünanteil des Farbwertes wählen" + +#: ../../po/../src/dialogs/clonetiler.cpp:2240 +msgid "B" +msgstr "B" + +#: ../../po/../src/dialogs/clonetiler.cpp:2241 +msgid "Pick the Blue component of the color" +msgstr "Blauanteil des Farbwertes wählen" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2250 +msgid "clonetiler|H" +msgstr "H" + +#: ../../po/../src/dialogs/clonetiler.cpp:2251 +msgid "Pick the hue of the color" +msgstr "Farbton des Farbwertes wählen" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2260 +msgid "clonetiler|S" +msgstr "S" + +#: ../../po/../src/dialogs/clonetiler.cpp:2261 +msgid "Pick the saturation of the color" +msgstr "Sättigung des Farbwertes auswählen" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2270 +msgid "clonetiler|L" +msgstr "L" + +#: ../../po/../src/dialogs/clonetiler.cpp:2271 +msgid "Pick the lightness of the color" +msgstr "Helligkeit des Farbwertes auswählen" + +#: ../../po/../src/dialogs/clonetiler.cpp:2281 +msgid "2. Tweak the picked value:" +msgstr "2. übernommenen Wert feinjustieren:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2291 +msgid "Gamma-correct:" +msgstr "Gammakorrektur:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2296 +msgid "Shift the mid-range of the picked value upwards (>0) or downwards (<0)" +msgstr "" +"Mittenbereich des gewählten Wertes verschieben; nach oben (>0) oder unten " +"(<0)" + +#: ../../po/../src/dialogs/clonetiler.cpp:2303 +msgid "Randomize:" +msgstr "Zufallsänderung:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2308 +msgid "Randomize the picked value by this percentage" +msgstr "Gewählten Wert um diesen Prozentsatz zufällig verändern" + +#: ../../po/../src/dialogs/clonetiler.cpp:2315 +msgid "Invert:" +msgstr "Invertieren:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2319 +msgid "Invert the picked value" +msgstr "Gewählten Wert invertieren" + +#: ../../po/../src/dialogs/clonetiler.cpp:2325 +msgid "3. Apply the value to the clones':" +msgstr "3. Wert auf die Klone anwenden:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2335 +msgid "Presence" +msgstr "Anwesenheit" + +#: ../../po/../src/dialogs/clonetiler.cpp:2338 +msgid "" +"Each clone is created with the probability determined by the picked value in " +"that point" +msgstr "" +"Jeder Klon wird mit der Wahrscheinlichkeit erzeugt, welche sich aus dem " +"übernommenen Wert an dieser Stelle ergibt" + +#: ../../po/../src/dialogs/clonetiler.cpp:2345 +msgid "Size" +msgstr "Größe" + +#: ../../po/../src/dialogs/clonetiler.cpp:2348 +msgid "Each clone's size is determined by the picked value in that point" +msgstr "" +"Jeweillige Größen der Klone hängen ab vom übernommenen Wert an dem Punkt" + +#: ../../po/../src/dialogs/clonetiler.cpp:2358 +msgid "" +"Each clone is painted by the picked color (the original must have unset fill " +"or stroke)" +msgstr "" +"Jeder Klon wird in der gewählten Farbe gezeichnet (Füllung oder Kontur des " +"Originals dürfen nicht gesetzt sein)" + +#: ../../po/../src/dialogs/clonetiler.cpp:2368 +msgid "Each clone's opacity is determined by the picked value in that point" +msgstr "" +"Die Transparenz jedes Klons wird durch den übernommenen Wert an dieser " +"Stelle bestimmt" + +#: ../../po/../src/dialogs/clonetiler.cpp:2395 +msgid "How many rows in the tiling" +msgstr "Anzahl der Reihen beim Kacheln" + +#: ../../po/../src/dialogs/clonetiler.cpp:2415 +msgid "How many columns in the tiling" +msgstr "Anzahl der Spalten beim Kacheln" + +#: ../../po/../src/dialogs/clonetiler.cpp:2445 +msgid "Width of the rectangle to be filled" +msgstr "Breite des zu füllenden Rechtecks" + +#: ../../po/../src/dialogs/clonetiler.cpp:2470 +msgid "Height of the rectangle to be filled" +msgstr "Höhe des zu füllenden Rechtecks" + +#: ../../po/../src/dialogs/clonetiler.cpp:2485 +msgid "Rows, columns: " +msgstr "Reihen, Spalten: " + +#: ../../po/../src/dialogs/clonetiler.cpp:2486 +msgid "Create the specified number of rows and columns" +msgstr "Angegeben Anzahl von Reihen und Spalten erzeugen" + +#: ../../po/../src/dialogs/clonetiler.cpp:2495 +msgid "Width, height: " +msgstr "Breite, Höhe: " + +#: ../../po/../src/dialogs/clonetiler.cpp:2496 +msgid "Fill the specified width and height with the tiling" +msgstr "Durch Höhe und Breite angegeben Bereich mit Füllmuster versehen" + +#: ../../po/../src/dialogs/clonetiler.cpp:2512 +msgid "Use saved size and position of the tile" +msgstr "Gespeicherte Größe und Position der Kachel verwenden" + +#: ../../po/../src/dialogs/clonetiler.cpp:2515 +msgid "" +"Pretend that the size and position of the tile are the same as the last time " +"you tiled it (if any), instead of using the current size" +msgstr "" +"Anstelle der aktuellen Größe die letzte Position und Größe der Kachel/" +"Musterfüllung vorgeben" + +#: ../../po/../src/dialogs/clonetiler.cpp:2539 +msgid " _Create " +msgstr " Erzeugen " + +#: ../../po/../src/dialogs/clonetiler.cpp:2541 +msgid "Create and tile the clones of the selection" +msgstr "Klone der Auswahl erzeugen und kacheln" + +#. TRANSLATORS: if a group of objects are "clumped" together, then they +#. are unevenly spread in the given amount of space - as shown in the +#. diagrams on the left in the following screenshot: +#. http://www.inkscape.org/screenshots/gallery/inkscape-0.42-CVS-tiles-unclump.png +#. So unclumping is the process of spreading a number of objects out more evenly. +#: ../../po/../src/dialogs/clonetiler.cpp:2556 +msgid " _Unclump " +msgstr " Entkl_umpen" + +#: ../../po/../src/dialogs/clonetiler.cpp:2557 +msgid "Spread out clones to reduce clumping; can be applied repeatedly" +msgstr "" +"Klone gleichmäßiger verteilen, um das Verklumpen zu verringern; mehrmals " +"anwendbar" + +#: ../../po/../src/dialogs/clonetiler.cpp:2563 +msgid " Re_move " +msgstr " Entfernen" + +#: ../../po/../src/dialogs/clonetiler.cpp:2564 +msgid "Remove existing tiled clones of the selected object (siblings only)" +msgstr "" +"Vorhandene gekachelte Klone des ausgewählten Objektes entfernen (nur " +"Verwandte)" + +#: ../../po/../src/dialogs/clonetiler.cpp:2580 +msgid " R_eset " +msgstr " Zurücksetzen " + +#. TRANSLATORS: "change" is a noun here +#: ../../po/../src/dialogs/clonetiler.cpp:2582 +msgid "" +"Reset all shifts, scales, rotates, opacity and color changes in the dialog " +"to zero" +msgstr "" +"Rücksetzen aller Verschiebungen, Skalierungen, Rotationen und Deckkraft- und " +"Farbanpassungen im Dialogfenster" + +#: ../../po/../src/dialogs/color-picker.cpp:280 +msgid "Close" +msgstr "Schließen" + +#: ../../po/../src/dialogs/debugdialog.cpp:138 +msgid "Messages" +msgstr "Meldungen" + +#. ## Add a menu for clear() +#: ../../po/../src/dialogs/debugdialog.cpp:144 +#: ../../po/../src/menus-skeleton.h:16 +#: ../../po/../src/ui/dialog/messages.cpp:56 +#: ../../po/../src/ui/dialog/scriptdialog.cpp:181 +msgid "_File" +msgstr "_Datei" + +#. TRANSLATORS: "Clear" is a verb here +#: ../../po/../src/dialogs/debugdialog.cpp:145 +#: ../../po/../src/dialogs/find.cpp:753 +#: ../../po/../src/ui/dialog/messages.cpp:57 +#: ../../po/../src/ui/dialog/scriptdialog.cpp:182 +msgid "_Clear" +msgstr "_Leeren" + +#: ../../po/../src/dialogs/debugdialog.cpp:147 +#: ../../po/../src/ui/dialog/messages.cpp:59 +msgid "Capture log messages" +msgstr "Nachrichten zur Fehlersuche protokollieren" + +#: ../../po/../src/dialogs/debugdialog.cpp:149 +#: ../../po/../src/ui/dialog/messages.cpp:61 +msgid "Release log messages" +msgstr "Nachrichten zur Fehlersuche nicht protokollieren" + +#. Notebook tab +#: ../../po/../src/dialogs/desktop-properties.cpp:909 +#: ../../po/../src/ui/dialog/document-preferences.cpp:89 +#: ../../po/../src/ui/widget/panel.cpp:107 +msgid "Grid" +msgstr "Gitter" + +#. Checkbuttons +#. / \todo FIXME: gray out snapping when grid is off +#. / \todo FIXME: gray out snapping when grid is off. +#. / Dissenting view: you want snapping without grid. +#: ../../po/../src/dialogs/desktop-properties.cpp:917 +#: ../../po/../src/ui/dialog/document-preferences.cpp:179 +msgid "Show grid" +msgstr "Gitter anzeigen" + +#: ../../po/../src/dialogs/desktop-properties.cpp:917 +#: ../../po/../src/ui/dialog/document-preferences.cpp:179 +#: ../../po/../src/verbs.cpp:2115 +msgid "Show or hide grid" +msgstr "Gitter anzeigen oder ausblenden" + +#: ../../po/../src/dialogs/desktop-properties.cpp:918 +#: ../../po/../src/ui/dialog/document-preferences.cpp:180 +msgid "Snap bounding boxes to grid" +msgstr "Umrandungsbox am Gitter einrasten" + +#: ../../po/../src/dialogs/desktop-properties.cpp:918 +#: ../../po/../src/dialogs/desktop-properties.cpp:1001 +#: ../../po/../src/ui/dialog/document-preferences.cpp:181 +#: ../../po/../src/ui/dialog/document-preferences.cpp:236 +msgid "Snap the edges of the object bounding boxes" +msgstr "Kanten der Umrandungsbox des Objektes einrasten" + +#: ../../po/../src/dialogs/desktop-properties.cpp:919 +#: ../../po/../src/ui/dialog/document-preferences.cpp:183 +msgid "Snap nodes to grid" +msgstr "Knoten am Gitter einrasten" + +#: ../../po/../src/dialogs/desktop-properties.cpp:919 +#: ../../po/../src/dialogs/desktop-properties.cpp:1002 +#: ../../po/../src/ui/dialog/document-preferences.cpp:184 +#: ../../po/../src/ui/dialog/document-preferences.cpp:239 +msgid "Snap path nodes, text baselines, ellipse centers, etc." +msgstr "" +"Einrasten von Knoten, Grundlinien von Texten, Ellipsenmittelpunkten, etc." + +#: ../../po/../src/dialogs/desktop-properties.cpp:937 +#: ../../po/../src/ui/dialog/document-preferences.cpp:186 +msgid "Grid units:" +msgstr "Gitter-Rastereinheiten:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:939 +#: ../../po/../src/ui/dialog/document-preferences.cpp:187 +msgid "Origin X:" +msgstr "Ursprung X:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:942 +#: ../../po/../src/ui/dialog/document-preferences.cpp:189 +msgid "Origin Y:" +msgstr "Ursprung Y:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:945 +#: ../../po/../src/ui/dialog/document-preferences.cpp:191 +msgid "Spacing X:" +msgstr "Abstand X:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:948 +#: ../../po/../src/ui/dialog/document-preferences.cpp:193 +msgid "Spacing Y:" +msgstr "Abstand Y:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:952 +#: ../../po/../src/dialogs/desktop-properties.cpp:1013 +#: ../../po/../src/ui/dialog/document-preferences.cpp:195 +#: ../../po/../src/ui/dialog/document-preferences.cpp:241 +msgid "Snap units:" +msgstr "Einrasteinheiten:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:955 +#: ../../po/../src/dialogs/desktop-properties.cpp:1016 +#: ../../po/../src/ui/dialog/document-preferences.cpp:196 +#: ../../po/../src/ui/dialog/document-preferences.cpp:242 +msgid "Snap distance:" +msgstr "Einrastabstand:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:958 +#: ../../po/../src/ui/dialog/document-preferences.cpp:199 +msgid "Grid line color:" +msgstr "Farbe der Gitterlinien:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:959 +#: ../../po/../src/ui/dialog/document-preferences.cpp:199 +msgid "Grid line color" +msgstr "Farbe der Gitterlinien" + +#: ../../po/../src/dialogs/desktop-properties.cpp:959 +#: ../../po/../src/ui/dialog/document-preferences.cpp:200 +msgid "Color of grid lines" +msgstr "Farbe der Gitterlinien" + +#: ../../po/../src/dialogs/desktop-properties.cpp:961 +#: ../../po/../src/ui/dialog/document-preferences.cpp:201 +msgid "Major grid line color:" +msgstr "Farbe der dicken Gitterlinien:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:962 +#: ../../po/../src/ui/dialog/document-preferences.cpp:201 +msgid "Major grid line color" +msgstr "Farbe der dicken Gitterlinien" + +#: ../../po/../src/dialogs/desktop-properties.cpp:962 +#: ../../po/../src/ui/dialog/document-preferences.cpp:202 +msgid "Color of the major (highlighted) grid lines" +msgstr "Farbe der dicken (hervorgehobenen) Gitterlinien" + +#: ../../po/../src/dialogs/desktop-properties.cpp:965 +#: ../../po/../src/ui/dialog/document-preferences.cpp:204 +msgid "Major grid line every:" +msgstr "Dicke Gitterlinien alle:" + +#. TRANSLATORS: This belongs to the "Major grid line every:" string, +#. see grid settings in the "Document Preferences" dialog +#: ../../po/../src/dialogs/desktop-properties.cpp:977 +#: ../../po/../src/ui/dialog/document-preferences.cpp:204 +msgid "lines" +msgstr "Linien" + +#. Guidelines page +#: ../../po/../src/dialogs/desktop-properties.cpp:991 +#: ../../po/../src/ui/dialog/document-preferences.cpp:90 +msgid "Guides" +msgstr "Führungslinien" + +#. / \todo FIXME: gray out snapping when guides are off +#. / Dissenting view: you want snapping without guides. +#: ../../po/../src/dialogs/desktop-properties.cpp:1000 +#: ../../po/../src/ui/dialog/document-preferences.cpp:234 +msgid "Show guides" +msgstr "Führungslinien anzeigen" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1000 +#: ../../po/../src/ui/dialog/document-preferences.cpp:234 +#: ../../po/../src/verbs.cpp:2116 +msgid "Show or hide guides" +msgstr "Führungslinien anzeigen oder ausblenden" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1001 +#: ../../po/../src/ui/dialog/document-preferences.cpp:235 +msgid "Snap bounding boxes to guides" +msgstr "Umrandungsbox an Führungslinien einrasten" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1002 +#: ../../po/../src/ui/dialog/document-preferences.cpp:238 +msgid "Snap points to guides" +msgstr "Knoten (Punkte) an Führungslinien einrasten" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1020 +#: ../../po/../src/ui/dialog/document-preferences.cpp:243 +msgid "Guide color:" +msgstr "Farbe der Führungslinien:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1021 +#: ../../po/../src/ui/dialog/document-preferences.cpp:243 +msgid "Guideline color" +msgstr "Farbe der Führungslinien" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1021 +#: ../../po/../src/ui/dialog/document-preferences.cpp:244 +msgid "Color of guidelines" +msgstr "Farbe der Führunglinien" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1023 +#: ../../po/../src/ui/dialog/document-preferences.cpp:245 +msgid "Highlight color:" +msgstr "Hervorhebungsfarbe:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1024 +#: ../../po/../src/ui/dialog/document-preferences.cpp:245 +msgid "Highlighted guideline color" +msgstr "Farbe der hervorgehobenen Führungslinien" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1024 +#: ../../po/../src/ui/dialog/document-preferences.cpp:246 +msgid "Color of a guideline when it is under mouse" +msgstr "Farbe der Führungslinie unter dem Mauszeiger" + +#. Page page +#: ../../po/../src/dialogs/desktop-properties.cpp:1029 +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:855 +#: ../../po/../src/ui/dialog/document-preferences.cpp:88 +#: ../../po/../src/widgets/desktop-widget.cpp:1061 +msgid "Page" +msgstr "Seite" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1039 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +msgid "Background:" +msgstr "Hintergrundfarbe:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1040 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +msgid "Background color" +msgstr "Hintergrundfarbe" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1041 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +msgid "" +"Color and transparency of the page background (also used for bitmap export)" +msgstr "" +"Farbe und Transparenz der Zeichenfläche (wird auch beim Exportieren " +"verwendet)" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1045 +#: ../../po/../src/ui/dialog/document-preferences.cpp:147 +#, fuzzy +msgid "Show page border" +msgstr "Rand der Zeichenfläche anzeigen" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1049 +#: ../../po/../src/ui/dialog/document-preferences.cpp:148 +msgid "Border on top of drawing" +msgstr "Rand im Vordergrund anzeigen" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1052 +#: ../../po/../src/ui/dialog/document-preferences.cpp:149 +msgid "Border color:" +msgstr "Randfarbe:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1053 +#: ../../po/../src/ui/dialog/document-preferences.cpp:149 +#, fuzzy +msgid "Page border color" +msgstr "Randfarbe der Zeichenfläche" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1054 +#: ../../po/../src/ui/dialog/document-preferences.cpp:150 +#, fuzzy +msgid "Color of the page border" +msgstr "Randfarbe der Zeichenfläche" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1059 +#: ../../po/../src/ui/dialog/document-preferences.cpp:152 +msgid "Show page shadow" +msgstr "Schatten der Zeichenfläche anzeigen" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1063 +#: ../../po/../src/ui/dialog/document-preferences.cpp:153 +msgid "Default units:" +msgstr "Standard-Einheiten:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1069 +msgid "Units for the tool controls, ruler, and the statusbar" +msgstr "Einheiten für die Werkzeugeinstellungen, Lineale und Statusleiste" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1086 +#: ../../po/../src/ui/widget/page-sizer.cpp:209 +#, fuzzy +msgid "Page size:" +msgstr "Größe der Zeichenfläche:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1110 +#: ../../po/../src/ui/widget/page-sizer.cpp:219 +msgid "Custom" +msgstr "Benutzerdefiniert" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1121 +#: ../../po/../src/ui/widget/page-sizer.cpp:225 +#, fuzzy +msgid "Page orientation:" +msgstr "Ausrichtung der Zeichenfläche:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1133 +#: ../../po/../src/ui/widget/page-sizer.cpp:232 +msgid "Landscape" +msgstr "Querformat" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1139 +#: ../../po/../src/ui/widget/page-sizer.cpp:234 +msgid "Portrait" +msgstr "Hochformat" + +#. Custom paper frame +#: ../../po/../src/dialogs/desktop-properties.cpp:1148 +#: ../../po/../src/ui/widget/page-sizer.cpp:249 +#, fuzzy +msgid "Custom size" +msgstr "Benutzerdefiniert" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1160 +#: ../../po/../src/dialogs/export.cpp:269 +#: ../../po/../src/ui/widget/page-sizer.cpp:261 +msgid "Units:" +msgstr "Einheit:" + +#. Stroke width +#: ../../po/../src/dialogs/desktop-properties.cpp:1162 +#: ../../po/../src/dialogs/export.cpp:310 +#: ../../po/../src/dialogs/object-attributes.cpp:55 +#: ../../po/../src/dialogs/stroke-style.cpp:985 +#: ../../po/../src/ui/widget/page-sizer.cpp:262 +#: ../../po/../src/widgets/toolbox.cpp:1957 +msgid "Width:" +msgstr "Breite:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1183 +#: ../../po/../src/dialogs/export.cpp:326 +#: ../../po/../src/dialogs/export.cpp:431 +#: ../../po/../src/dialogs/object-attributes.cpp:56 +#: ../../po/../src/ui/widget/page-sizer.cpp:263 +msgid "Height:" +msgstr "Höhe:" + +#. +#. * Ownership metadata tab +#. +#: ../../po/../src/dialogs/desktop-properties.cpp:1206 +msgid "Metadata" +msgstr "Metadaten" + +#. add license selector pull-down +#: ../../po/../src/dialogs/desktop-properties.cpp:1225 +msgid "License" +msgstr "Nutzungsbedingungen - Lizenz" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1255 +msgid "Proprietary" +msgstr "Proprietär" + +#: ../../po/../src/dialogs/display-settings.cpp:212 +msgid "When transforming, show:" +msgstr "Zeige beim Verändern:" + +#: ../../po/../src/dialogs/display-settings.cpp:223 +msgid "Objects" +msgstr "Objekte" + +#: ../../po/../src/dialogs/display-settings.cpp:224 +msgid "Show the actual objects when moving or transforming" +msgstr "Zeige Objekte mit Inhalt beim Verschieben oder Verändern" + +#: ../../po/../src/dialogs/display-settings.cpp:231 +msgid "Box outline" +msgstr "Objektumriss" + +#: ../../po/../src/dialogs/display-settings.cpp:232 +msgid "Show only a box outline of the objects when moving or transforming" +msgstr "Zeige rechteckige Objektumrisse beim Verschieben oder Verändern" + +#: ../../po/../src/dialogs/display-settings.cpp:238 +msgid "Per-object selection cue:" +msgstr "Visuelle Auswahlmarkierung für Objekte:" + +# CHECK +#. sorationsnapsperpi == 0 means no snapping +#: ../../po/../src/dialogs/display-settings.cpp:249 +#: ../../po/../src/dialogs/display-settings.cpp:386 +#: ../../po/../src/dialogs/display-settings.cpp:441 +#: ../../po/../src/dialogs/display-settings.cpp:1482 +#: ../../po/../src/dialogs/stroke-style.cpp:791 +#: ../../po/../src/interface.cpp:741 +#: ../../po/../src/ui/widget/selected-style.cpp:100 +#: ../../po/../src/verbs.cpp:1842 +msgid "None" +msgstr "Deaktiviert" + +#: ../../po/../src/dialogs/display-settings.cpp:250 +msgid "No per-object selection indication" +msgstr "Keine Auswahlmarkierung für Objekte" + +#: ../../po/../src/dialogs/display-settings.cpp:256 +msgid "Mark" +msgstr "Markierung" + +#: ../../po/../src/dialogs/display-settings.cpp:257 +msgid "Each selected object has a diamond mark in the top left corner" +msgstr "" +"Jedes ausgewählte Objekt hat eine diamantförmige Markierung in der linken " +"oberen Ecke" + +#: ../../po/../src/dialogs/display-settings.cpp:264 +msgid "Box" +msgstr "Umschließendes Rechteck" + +#: ../../po/../src/dialogs/display-settings.cpp:265 +msgid "Each selected object displays its bounding box" +msgstr "" +"Jedes gewählte Objekt zeigt sein umschließendes Rechteck (Umrandungsbox)" + +#: ../../po/../src/dialogs/display-settings.cpp:270 +msgid "Default scale origin:" +msgstr "Voreingestellter Linealursprung:" + +#: ../../po/../src/dialogs/display-settings.cpp:281 +msgid "Opposite bounding box edge" +msgstr "Gegenüberliegende Kante der Umrandungsbox" + +#: ../../po/../src/dialogs/display-settings.cpp:282 +msgid "Default scale origin will be on the bounding box of the item" +msgstr "" +"Vorgegebener Ursprung beim Skalieren liegt auf der Umrandungsbox des Objektes" + +#: ../../po/../src/dialogs/display-settings.cpp:288 +msgid "Farthest opposite node" +msgstr "Am weitesten entfernter Knoten" + +#: ../../po/../src/dialogs/display-settings.cpp:289 +msgid "Default scale origin will be on the bounding box of the item's points" +msgstr "" +"Vorgegebener Ursprung beim Skalieren liegt auf der Umrandungsbox der Knoten " +"des Objektes" + +#: ../../po/../src/dialogs/display-settings.cpp:341 +msgid "degrees" +msgstr "Grad" + +#: ../../po/../src/dialogs/display-settings.cpp:350 +msgid "" +"Rotating with Ctrl pressed snaps every that much degrees; also, pressing " +"[ or ] rotates by this amount" +msgstr "" +"Rotation mit gedrückter Strg-Taste lässt das Objekt mit dieser Gradrastung " +"einrasten; die Tasten [ oder ] haben den gleichen Effekt" + +# !!! need %s +#: ../../po/../src/dialogs/display-settings.cpp:407 +msgid "Rotation snaps every:" +msgstr "Rotation rastet ein alle:" + +#: ../../po/../src/dialogs/display-settings.cpp:430 +msgid "" +"None: dialogs are treated as regular windows; Normal: dialogs stay on top of " +"document windows; Aggressive: same as Normal but may work better with some " +"window managers." +msgstr "" +"Deaktiviert: Dialoge verhalten sich wie gewöhnliche Fenster; Normal: Dialoge " +"bleiben immer über dem Dokument; Aggressiv: wie bei der Einstellung " +"»Normal«, aber besser an bestimmte Fenstermanager angepasst." + +#: ../../po/../src/dialogs/display-settings.cpp:451 +msgid "Normal" +msgstr "Normal" + +#: ../../po/../src/dialogs/display-settings.cpp:461 +msgid "Aggressive" +msgstr "Aggressiv" + +#: ../../po/../src/dialogs/display-settings.cpp:475 +msgid "Dialogs on top:" +msgstr "Dialoge im Vordergrund:" + +#: ../../po/../src/dialogs/display-settings.cpp:645 +msgid "Show selection cue" +msgstr "Auswahlmarkierung anzeigen" + +# !!! Frage? Passiv formulieren? +#: ../../po/../src/dialogs/display-settings.cpp:646 +msgid "" +"Whether selected objects display a selection cue (the same as in selector)" +msgstr "" +"Sind die ausgewählten Objekte visuell hervorgehoben (wie beim " +"Auswahlwerkzeug) " + +#: ../../po/../src/dialogs/display-settings.cpp:657 +msgid "Enable gradient editing" +msgstr "Farbverlaufs-Editor aktiviert" + +# !!! Frage? Passiv formulieren? +#: ../../po/../src/dialogs/display-settings.cpp:658 +msgid "Whether selected objects display gradient editing controls" +msgstr "" +"Anzeige der Farbverlaufs-Anfasser für die ausgewählten Objekte aktiviert?" + +#: ../../po/../src/dialogs/display-settings.cpp:719 +msgid "No objects selected to take the style from." +msgstr "Objekte auswählen, um Stil zu übernehmen." + +#: ../../po/../src/dialogs/display-settings.cpp:728 +msgid "" +"More than one object selected. Cannot take style from multiple " +"objects." +msgstr "" +"Mehr alsein Objektausgewählt. Mehrere Stile können nicht auf einmal " +"übernommen werden" + +#: ../../po/../src/dialogs/display-settings.cpp:767 +msgid "Create new objects with:" +msgstr "Objekte erstellen mit:" + +#: ../../po/../src/dialogs/display-settings.cpp:777 +msgid "Take from selection" +msgstr "Von der Auswahl übernehmen" + +#: ../../po/../src/dialogs/display-settings.cpp:778 +msgid "Remember the style of the (first) selected object as this tool's style" +msgstr "" +"Stil des ersten ausgewählten Objektes zur Vorgabe für dieses Werkzeug machen" + +#: ../../po/../src/dialogs/display-settings.cpp:782 +#, fuzzy +msgid "Last used style" +msgstr "Stil an_wenden" + +#: ../../po/../src/dialogs/display-settings.cpp:782 +msgid "Apply the style you last set on an object" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:790 +msgid "This tool's own style:" +msgstr "Stilvorgaben für dieses Werkzeug:" + +#: ../../po/../src/dialogs/display-settings.cpp:790 +msgid "" +"Each tool may store its own style to apply to the newly created objects. Use " +"the button below to set it." +msgstr "" +"Werkzeuge können eigene Stilvorgaben behalten, die auf neu erzeugte Objekte " +"angewendet werden. Stilvorgabe mit dem unteren Knopf festlegen." + +#. Mouse +#: ../../po/../src/dialogs/display-settings.cpp:877 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:55 +msgid "Mouse" +msgstr "Maus" + +#. TRANSLATORS: "Grab" is a noun here. "Grab sensitivity" is intended to mean how +#. * close on the screen you need to be to an object to be able to grab it with mouse (in +#. * pixels). +#: ../../po/../src/dialogs/display-settings.cpp:883 +msgid "Grab sensitivity:" +msgstr "Entfernung zum Erfassen:" + +#: ../../po/../src/dialogs/display-settings.cpp:884 +msgid "" +"How close on the screen you need to be to an object to be able to grab it " +"with mouse (in screen pixels)" +msgstr "" +"Mindestentfernung des Mauszeigers zu einem Objekt, um es zu erfassen (in " +"Pixeln)" + +#: ../../po/../src/dialogs/display-settings.cpp:885 +#: ../../po/../src/dialogs/display-settings.cpp:897 +#: ../../po/../src/dialogs/display-settings.cpp:912 +#: ../../po/../src/dialogs/display-settings.cpp:930 +#: ../../po/../src/dialogs/display-settings.cpp:970 +msgid "pixels" +msgstr "Pixel" + +#: ../../po/../src/dialogs/display-settings.cpp:895 +msgid "Click/drag threshold:" +msgstr "Schwellwert für Klicken/Ziehen:" + +#: ../../po/../src/dialogs/display-settings.cpp:896 +msgid "" +"Maximum mouse drag (in screen pixels) which is considered a click, not a drag" +msgstr "" +"Maximale Bewegung des Zeigers (in Pixeln), bei der noch Klicken statt Ziehen " +"interpretiert wird" + +#. Scrolling +#: ../../po/../src/dialogs/display-settings.cpp:907 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:56 +msgid "Scrolling" +msgstr "Rollen" + +#: ../../po/../src/dialogs/display-settings.cpp:910 +msgid "Mouse wheel scrolls by:" +msgstr "Mausrad rollt um:" + +#: ../../po/../src/dialogs/display-settings.cpp:911 +msgid "" +"One mouse wheel notch scrolls by this distance in screen pixels " +"(horizontally with Shift)" +msgstr "" +"Eine Stufe des Maus-Rades rollt um die angegebene Distanz in Pixeln " +"(horizontal mit Umschalttaste)" + +#: ../../po/../src/dialogs/display-settings.cpp:920 +msgid "Ctrl+arrows" +msgstr "Strg+Pfeile" + +#: ../../po/../src/dialogs/display-settings.cpp:928 +msgid "Scroll by:" +msgstr "Rolle um:" + +#: ../../po/../src/dialogs/display-settings.cpp:929 +msgid "Pressing Ctrl+arrow key scrolls by this distance (in screen pixels)" +msgstr "Strg+Pfeiltasten rollen um diese Distanz (in Pixeln)" + +#: ../../po/../src/dialogs/display-settings.cpp:939 +msgid "Acceleration:" +msgstr "Beschleunigung:" + +#: ../../po/../src/dialogs/display-settings.cpp:940 +msgid "" +"Pressing and holding Ctrl+arrow will gradually speed up scrolling (0 for no " +"acceleration)" +msgstr "" +"Drücken von Strg+Pfeiltaste erhöht zunehmend die Rollgeschwindigkeit (0 " +"bedeutet »keine Beschleunigung«)" + +#: ../../po/../src/dialogs/display-settings.cpp:949 +msgid "Autoscrolling" +msgstr "Automatisches Rollen" + +#: ../../po/../src/dialogs/display-settings.cpp:957 +msgid "Speed:" +msgstr "Geschwindigkeit:" + +#: ../../po/../src/dialogs/display-settings.cpp:958 +msgid "" +"How fast the canvas autoscrolls when you drag beyond canvas edge (0 to turn " +"autoscroll off)" +msgstr "" +"Geschwindigkeit mit der die Arbeitsfläche verschoben wird, wenn der Zeiger " +"ihren Rand überschreitet (0: Autorollen ist deaktiviert)" + +#: ../../po/../src/dialogs/display-settings.cpp:968 +#: ../../po/../src/ui/dialog/tracedialog.cpp:357 +#: ../../po/../src/ui/dialog/tracedialog.cpp:390 +msgid "Threshold:" +msgstr "Schwellwert:" + +#: ../../po/../src/dialogs/display-settings.cpp:969 +msgid "" +"How far (in screen pixels) you need to be from the canvas edge to trigger " +"autoscroll; positive is outside the canvas, negative is within the canvas" +msgstr "" +"Pixelabstand des Mauszeigers zum Rand der Arbeitsfläche, bei der das " +"Autorollen aktiv ist: positive Werte liegen außerhalb, negative Werte " +"innerhalb der Arbeitsfläche" + +#. Steps +#: ../../po/../src/dialogs/display-settings.cpp:979 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:57 +msgid "Steps" +msgstr "Schritte" + +#: ../../po/../src/dialogs/display-settings.cpp:982 +msgid "Arrow keys move by:" +msgstr "Pfeiltasten bewegen um:" + +#: ../../po/../src/dialogs/display-settings.cpp:983 +msgid "" +"Pressing an arrow key moves selected object(s) or node(s) by this distance " +"(in px units)" +msgstr "" +"Drücken einer Pfeiltaste verschiebt die ausgewählten Elemente (Objekte oder " +"Knoten) um diese Entfernung (in SVG-Pixeln)" + +#: ../../po/../src/dialogs/display-settings.cpp:984 +#: ../../po/../src/dialogs/display-settings.cpp:995 +#: ../../po/../src/dialogs/display-settings.cpp:1006 +#: ../../po/../src/helper/units.cpp:42 +msgid "px" +msgstr "Px" + +#: ../../po/../src/dialogs/display-settings.cpp:993 +msgid "> and < scale by:" +msgstr "> und < skalieren um:" + +#: ../../po/../src/dialogs/display-settings.cpp:994 +msgid "" +"Pressing > or < scales selection up or down by this increment (in px units)" +msgstr "" +"Drücken von > oder < skaliert die ausgewählten Elemente um diesen Wert " +"größer oder kleiner (in SVG-Pixeln) " + +#: ../../po/../src/dialogs/display-settings.cpp:1004 +msgid "Inset/Outset by:" +msgstr "Schrumpfen/Ausweiten um:" + +#: ../../po/../src/dialogs/display-settings.cpp:1005 +msgid "" +"Inset and Outset commands displace the path by this distance (in px units)" +msgstr "" +"Schrumpfungs- und Ausweitungsbefehle verändern den Pfad um diese Distanz (in " +"SVG-Pixeln)" + +#: ../../po/../src/dialogs/display-settings.cpp:1017 +msgid "Compass-like display of angles" +msgstr "Anzeige von Winkeln wie bei einem Kompaß" + +#. TRANSLATORS: "positive clockwise" means "increasing in clockwise direction" +#: ../../po/../src/dialogs/display-settings.cpp:1019 +msgid "" +"When on, angles are displayed with 0 at north, 0 to 360 range, positive " +"clockwise; otherwise with 0 at east, -180 to 180 range, positive " +"counterclockwise" +msgstr "" +"Aktiviert bedeutet, dass Winkel mit 0 für Norden dargestellt werden, Bereich " +"0 bis 360, positiv im Uhrzeigersinn; anderenfalls mit 0 für Osten, Bereich -" +"180 bis 180, positiv entgegen dem Uhrzeigersinn" + +#: ../../po/../src/dialogs/display-settings.cpp:1026 +msgid "Zoom in/out by:" +msgstr "Zoomfaktor vergrößern/verringern um:" + +#: ../../po/../src/dialogs/display-settings.cpp:1027 +msgid "" +"Zoom tool click, +/- keys, and middle click zoom in and out by this " +"multiplier" +msgstr "" +"Mit dem Zoomwerkzeug klicken, die + oder - Taste drücken, oder die mittlere " +"Maustaste betätigen, damit sich die Zoomgröße um diesen Faktor ändert" + +#: ../../po/../src/dialogs/display-settings.cpp:1028 +#: ../../po/../src/helper/units.cpp:44 +msgid "%" +msgstr "%" + +#. Tools +#: ../../po/../src/dialogs/display-settings.cpp:1037 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:58 +msgid "Tools" +msgstr "Werkzeuge" + +#: ../../po/../src/dialogs/display-settings.cpp:1045 +msgid "Selector" +msgstr "Auswahlwerkzeug" + +#: ../../po/../src/dialogs/display-settings.cpp:1056 +msgid "Node" +msgstr "Knoten" + +#: ../../po/../src/dialogs/display-settings.cpp:1064 +#: ../../po/../src/verbs.cpp:2073 +#: ../../po/../src/widgets/desktop-widget.cpp:277 +msgid "Zoom" +msgstr "Zoomfaktor" + +#. The 4 shape tools +#: ../../po/../src/dialogs/display-settings.cpp:1071 +msgid "Shapes" +msgstr "Formen" + +#: ../../po/../src/dialogs/display-settings.cpp:1079 +#: ../../po/../src/verbs.cpp:2055 +msgid "Rectangle" +msgstr "Rechteck" + +#: ../../po/../src/dialogs/display-settings.cpp:1085 +#: ../../po/../src/verbs.cpp:2057 +msgid "Ellipse" +msgstr "Ellipse" + +#: ../../po/../src/dialogs/display-settings.cpp:1091 +#: ../../po/../src/verbs.cpp:2059 +msgid "Star" +msgstr "Stern" + +#: ../../po/../src/dialogs/display-settings.cpp:1097 +#: ../../po/../src/verbs.cpp:2061 +msgid "Spiral" +msgstr "Spirale" + +#: ../../po/../src/dialogs/display-settings.cpp:1111 +#: ../../po/../src/verbs.cpp:2063 +msgid "Pencil" +msgstr "Malwerkzeug (Freihand)" + +# CHECK +#: ../../po/../src/dialogs/display-settings.cpp:1114 +msgid "Tolerance:" +msgstr "Toleranz:" + +#: ../../po/../src/dialogs/display-settings.cpp:1115 +msgid "" +"This value affects the amount of smoothing applied to freehand lines; lower " +"values produce more uneven paths with more nodes" +msgstr "" +"Dieser Wert bestimmt den Grad der Glättung auf Freihand-Linien; niedrige " +"Werte erzeugen Pfade mit höherer Anzahl von Knoten" + +#: ../../po/../src/dialogs/display-settings.cpp:1131 +#: ../../po/../src/verbs.cpp:2065 +msgid "Pen" +msgstr "Zeichenwerkzeug (Linien & Bézierkurven)" + +#: ../../po/../src/dialogs/display-settings.cpp:1140 +#: ../../po/../src/verbs.cpp:2067 +msgid "Calligraphy" +msgstr "Kalligraphie" + +#: ../../po/../src/dialogs/display-settings.cpp:1147 +#: ../../po/../src/dialogs/text-edit.cpp:353 +#: ../../po/../src/ui/dialog/text-properties.cpp:37 +#: ../../po/../src/verbs.cpp:2069 +msgid "Text" +msgstr "Text" + +#: ../../po/../src/dialogs/display-settings.cpp:1157 +#: ../../po/../src/verbs.cpp:2071 +msgid "Gradient" +msgstr "Farbverlauf" + +#: ../../po/../src/dialogs/display-settings.cpp:1164 +#: ../../po/../src/verbs.cpp:2077 +msgid "Connector" +msgstr "Objektverbinder" + +#: ../../po/../src/dialogs/display-settings.cpp:1171 +#: ../../po/../src/verbs.cpp:2075 +msgid "Dropper" +msgstr "Farbpipette" + +#. Windows +#: ../../po/../src/dialogs/display-settings.cpp:1183 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:59 +msgid "Windows" +msgstr "Fenster" + +#: ../../po/../src/dialogs/display-settings.cpp:1188 +msgid "Save window geometry" +msgstr "Fenstergeometrie speichern" + +#: ../../po/../src/dialogs/display-settings.cpp:1189 +msgid "" +"Save the window size and position with each document (only for Inkscape SVG " +"format)" +msgstr "" +"Die Fenstergrößen und Positionen in jedem Dokument speichern (nur von " +"Inkscapes SVG-Format unterstützt)" + +#: ../../po/../src/dialogs/display-settings.cpp:1196 +msgid "Dialogs are hidden in taskbar" +msgstr "Dialoge werden in der Fensterliste nicht angezeigt" + +#: ../../po/../src/dialogs/display-settings.cpp:1197 +msgid "Whether dialog windows are to be hidden in the window manager taskbar" +msgstr "Sollen Dialogfenster in der Fensterliste nicht angezeigt werden?" + +#: ../../po/../src/dialogs/display-settings.cpp:1204 +msgid "Zoom when window is resized" +msgstr "Zeichnungsgröße ändern, sobald die Fenstergröße verändert wird" + +#: ../../po/../src/dialogs/display-settings.cpp:1205 +msgid "" +"Zoom drawing when document window is resized, to keep the same area visible " +"(this is the default which can be changed in any window using the button " +"above the right scrollbar)" +msgstr "" +"Darstellungsgröße des Dokuments anpassen, wenn sich die Fenstergröße ändert " +"- der selbe Bereich bleibt sichtbar (Vorgabe, die in jedem Fenster mit dem " +"Knopf über dem rechten Rollbalken geändert wird)" + +#. Clones +#: ../../po/../src/dialogs/display-settings.cpp:1213 +#: ../../po/../src/dialogs/find.cpp:624 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:60 +msgid "Clones" +msgstr "Klone" + +#: ../../po/../src/dialogs/display-settings.cpp:1217 +msgid "When the original moves, its clones and linked offsets:" +msgstr "" +"Wenn das Original verschoben wird, werden die Klone und Versatz-Objekte:" + +#: ../../po/../src/dialogs/display-settings.cpp:1229 +msgid "Move in parallel" +msgstr "parallel verschoben" + +#: ../../po/../src/dialogs/display-settings.cpp:1230 +msgid "Clones are translated by the same vector as their original." +msgstr "Klone werden mit demselben Vektor wie das Original verschoben." + +#: ../../po/../src/dialogs/display-settings.cpp:1237 +msgid "Stay unmoved" +msgstr "unbewegt bleiben" + +#: ../../po/../src/dialogs/display-settings.cpp:1238 +msgid "Clones preserve their positions when their original is moved." +msgstr "" +"Klone bleiben an ihren Positionen, während das Original verschoben wird." + +#: ../../po/../src/dialogs/display-settings.cpp:1245 +msgid "Move according to transform" +msgstr "sich entsprechend des transform=-Attributs bewegen" + +#: ../../po/../src/dialogs/display-settings.cpp:1246 +msgid "" +"Each clone moves according to the value of its transform= attribute. For " +"example, a rotated clone will move in a different direction than its " +"original." +msgstr "" +"Jeder Klon verschiebt sich entsprechend des Wertes seines transform=-" +"Attributs. Ein rotierter Klon wird sich zum Beispiel in eine andere Richtung " +"als das Original drehen." + +#: ../../po/../src/dialogs/display-settings.cpp:1255 +msgid "When the original is deleted, its clones:" +msgstr "Wenn das Original gelöscht wird, werden die Klone:" + +#: ../../po/../src/dialogs/display-settings.cpp:1267 +msgid "Are unlinked" +msgstr "ihre Verbindung zum Original verlieren" + +#: ../../po/../src/dialogs/display-settings.cpp:1267 +msgid "Orphaned clones are converted to regular objects." +msgstr "Klone ohne Original werden zu regulären Objekten umgewandelt." + +#: ../../po/../src/dialogs/display-settings.cpp:1273 +msgid "Are deleted" +msgstr "ebenso gelöscht" + +#: ../../po/../src/dialogs/display-settings.cpp:1273 +msgid "Orphaned clones are deleted along with their original." +msgstr "Klone werden zusammen mit ihrem Original gelöscht." + +#. Transforms +#. TRANSLATORS: Noun, i.e. transformations. +#: ../../po/../src/dialogs/display-settings.cpp:1289 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:61 +msgid "Transforms" +msgstr "Transformationen" + +#: ../../po/../src/dialogs/display-settings.cpp:1292 +msgid "Scale stroke width" +msgstr "Breite der Konturlinie mitskalieren" + +#: ../../po/../src/dialogs/display-settings.cpp:1293 +#: ../../po/../src/widgets/select-toolbar.cpp:568 +msgid "When scaling objects, scale the stroke width by the same proportion" +msgstr "" +"Wenn Objekte skaliert werden, dann wird die Breite der Konturlinie ebenso " +"mitskaliert." + +#: ../../po/../src/dialogs/display-settings.cpp:1300 +msgid "Scale rounded corners in rectangles" +msgstr "Abgerundete Ecken in Rechtecken mitskalieren" + +#: ../../po/../src/dialogs/display-settings.cpp:1301 +#: ../../po/../src/widgets/select-toolbar.cpp:580 +msgid "When scaling rectangles, scale the radii of rounded corners" +msgstr "" +"Wenn Rechtecke skaliert werden, dann werden die Radien von abgerundeten " +"Ecken ebenso mitskaliert." + +#: ../../po/../src/dialogs/display-settings.cpp:1308 +msgid "Transform gradients" +msgstr "Farbverläufe transformieren" + +#: ../../po/../src/dialogs/display-settings.cpp:1309 +#: ../../po/../src/widgets/select-toolbar.cpp:592 +msgid "Transform gradients (in fill or stroke) along with the objects" +msgstr "" +"Farbverläufe (in Füllung oder Konturlinie) zusammen mit den Objekten " +"transformieren" + +#: ../../po/../src/dialogs/display-settings.cpp:1316 +msgid "Transform patterns" +msgstr "Füllmuster transformieren" + +#: ../../po/../src/dialogs/display-settings.cpp:1317 +#: ../../po/../src/widgets/select-toolbar.cpp:604 +msgid "Transform patterns (in fill or stroke) along with the objects" +msgstr "" +"Muster (in Füllung oder Konturlinie) zusammen mit den Objekten transformieren" + +#. TRANSLATORS: How to specify the affine transformation in the SVG file. +#: ../../po/../src/dialogs/display-settings.cpp:1327 +msgid "Store transformation:" +msgstr "Transformation speichern:" + +#: ../../po/../src/dialogs/display-settings.cpp:1338 +msgid "Optimized" +msgstr "Optimiert" + +#: ../../po/../src/dialogs/display-settings.cpp:1339 +msgid "" +"If possible, apply transformation to objects without adding a transform= " +"attribute" +msgstr "" +"Wenn möglich, dann werden Transformationen auf Objekte angewendet, ohne ein " +"transform=-Attribut hinzuzufügen." + +#: ../../po/../src/dialogs/display-settings.cpp:1346 +msgid "Preserved" +msgstr "Beibehalten" + +#: ../../po/../src/dialogs/display-settings.cpp:1347 +msgid "Always store transformation as a transform= attribute on objects" +msgstr "Transformationen immer als transform=-Attribute speichern." + +#. Selecting +#: ../../po/../src/dialogs/display-settings.cpp:1355 +msgid "Selecting" +msgstr "Auswählen" + +#: ../../po/../src/dialogs/display-settings.cpp:1357 +msgid "Ctrl+A, Tab, Shift+Tab:" +msgstr "Strg+A, Tabulator, Umschalt+Tabulator:" + +#: ../../po/../src/dialogs/display-settings.cpp:1366 +msgid "Select only within current layer" +msgstr "Nur innerhalb der aktuellen Ebene auswählen" + +#: ../../po/../src/dialogs/display-settings.cpp:1367 +msgid "" +"Uncheck this to make keyboard selection commands work on objects in all " +"layers" +msgstr "" +"Dieses abwählen damit Tastaturkommandos zur Auswahl auf Objekten aller " +"Ebenen wirken" + +#: ../../po/../src/dialogs/display-settings.cpp:1374 +msgid "Ignore hidden objects" +msgstr "Verborgene Objekte auslassen" + +#: ../../po/../src/dialogs/display-settings.cpp:1375 +msgid "" +"Uncheck this to be able to select objects that are hidden (either by " +"themselves or by being in a hidden group or layer)" +msgstr "" +"Dieses abwählen, damit verborgene Objekte ausgewählt werden können (gilt " +"auch für Objekte in verborgenen Ebenen/Gruppierungen)" + +#: ../../po/../src/dialogs/display-settings.cpp:1382 +msgid "Ignore locked objects" +msgstr "Gesperrte Objekte auslassen" + +#: ../../po/../src/dialogs/display-settings.cpp:1383 +msgid "" +"Uncheck this to be able to select objects that are locked (either by " +"themselves or by being in a locked group or layer)" +msgstr "" +"Dieses abwählen damit gesperrte Objekte ausgewählt werden können (gilt auch " +"für Objekte in gesperrten Ebenen/Gruppierungen)" + +#. To be broken into: Display, Save, Export, SVG, Commands +#: ../../po/../src/dialogs/display-settings.cpp:1391 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:62 +msgid "Misc" +msgstr "Sonstiges" + +#: ../../po/../src/dialogs/display-settings.cpp:1394 +msgid "Default export resolution:" +msgstr "Bevorzugte Auflösung für das Exportieren:" + +#: ../../po/../src/dialogs/display-settings.cpp:1395 +msgid "Default bitmap resolution (in dots per inch) in the Export dialog" +msgstr "" +"Bevorzugte Auflösung der Bitmap (Punkte pro Zoll) im Exportieren-Dialog" + +#. FIXME: add "Used for new exports; once exported, documents remember this value on per-object basis" when implemented +#: ../../po/../src/dialogs/display-settings.cpp:1396 +#: ../../po/../src/dialogs/export.cpp:442 +msgid "dpi" +msgstr "dpi" + +# !!! correct translation? +#. TRANSLATORS: When on, an imported bitmap creates an element; otherwise it is a +#. * rectangle with bitmap fill. +#: ../../po/../src/dialogs/display-settings.cpp:1407 +msgid "Import bitmap as " +msgstr "Bitmap als importieren" + +#: ../../po/../src/dialogs/display-settings.cpp:1408 +msgid "" +"When on, an imported bitmap creates an element; otherwise it is a " +"rectangle with bitmap fill" +msgstr "" +"Aktiviert bedeutet, dass ein -Element für eine importierte Bitmap " +"erzeugt wird. Inaktiv bedeutet, dass ein Rechteck mit einer Bitmap-Füllung " +"versehen wird" + +#. TRANSLATORS: When on, the print out (currently Postscript) will have +#. * a comment with the each object's label visible, marking the section +#. * of the printing commands that represent the given object. +#: ../../po/../src/dialogs/display-settings.cpp:1418 +msgid "Add label comments to printing output" +msgstr "Beim Ausdruck Bezeichnerkommentare mitdrucken" + +#: ../../po/../src/dialogs/display-settings.cpp:1419 +msgid "" +"When on, a comment will be added to the raw print output, marking the " +"rendered output for an object with its label" +msgstr "" +"Diese Option fügt der unbehandelten Druckausgabe einen Kommentar hinzu.\n" +"Das zu druckende Objekt wird mit einem Bezeichner markiert." + +#. TRANSLATORS: When on, enable the effects menu, default is off +#: ../../po/../src/dialogs/display-settings.cpp:1427 +msgid "Enable script effects (requires restart) - EXPERIMENTAL" +msgstr "" +"Skripteffekte ermöglichen (Neustart von Inkscape notwendig) - EXPERIMENTELL" + +#: ../../po/../src/dialogs/display-settings.cpp:1428 +msgid "" +"When on, the effects menu is enabled, allowing external effect scripts to be " +"called, requires restart before effective - EXPERIMENTAL" +msgstr "" +"Bei Aktivierung, ist das Effektmenu zugreifbar mit dem externe Skripte " +"ausgeführt werden. Neustart von Inkscape erforderlich - EXPERIMENTELL" + +#. TRANSLATORS: The maximum length of the Open Recent list in the File menu. +#: ../../po/../src/dialogs/display-settings.cpp:1436 +msgid "Max recent documents:" +msgstr "Maximale Länge der Liste zuletzt geöffneter Dokumente:" + +#: ../../po/../src/dialogs/display-settings.cpp:1437 +msgid "The maximum length of the Open Recent list in the File menu" +msgstr "" +"Die maximale Länge der Liste zuletzt geöffneter Dokumente im Menü »Datei«." + +#: ../../po/../src/dialogs/display-settings.cpp:1447 +msgid "Simplification threshold:" +msgstr "Schwellwert für Vereinfachungen:" + +#: ../../po/../src/dialogs/display-settings.cpp:1448 +msgid "" +"How strong is the Simplify command by default. If you invoke this command " +"several times in quick succession, it will act more and more aggressively; " +"invoking it again after a pause restores the default threshold." +msgstr "" +"Vorgabestärke der Vereinfachung. Wird diese Operation mehrmals schnell " +"hintereinander ausgeführt, erhöht sich die Stärke; kurze Pause dazwischen " +"setzt die Stärke wieder zurück." + +# CHECK +#: ../../po/../src/dialogs/display-settings.cpp:1469 +msgid "Oversample bitmaps:" +msgstr "Oversampling von Bitmaps:" + +#: ../../po/../src/dialogs/display-settings.cpp:1488 +msgid "2x2" +msgstr "2×2" + +#: ../../po/../src/dialogs/display-settings.cpp:1494 +msgid "4x4" +msgstr "4×4" + +#: ../../po/../src/dialogs/display-settings.cpp:1500 +msgid "8x8" +msgstr "8×8" + +#: ../../po/../src/dialogs/display-settings.cpp:1506 +msgid "16x16" +msgstr "16×16" + +#. "view_icon_preview" +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2143 +msgid "_Page" +msgstr "_Seite" + +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2147 +msgid "_Drawing" +msgstr "_Zeichnung" + +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2149 +msgid "_Selection" +msgstr "_Auswahl" + +#: ../../po/../src/dialogs/export.cpp:133 +msgid "_Custom" +msgstr "Benutzerdefiniert" + +#: ../../po/../src/dialogs/export.cpp:254 +msgid "Export area" +msgstr "Bereich exportieren" + +#: ../../po/../src/dialogs/export.cpp:300 +msgid "_x0:" +msgstr "_x0:" + +#: ../../po/../src/dialogs/export.cpp:305 +msgid "x_1:" +msgstr "x_1:" + +#: ../../po/../src/dialogs/export.cpp:316 +msgid "_y0:" +msgstr "_y0:" + +#: ../../po/../src/dialogs/export.cpp:321 +msgid "y_1:" +msgstr "y_1:" + +#: ../../po/../src/dialogs/export.cpp:406 +msgid "Bitmap size" +msgstr "Bitmap-Größe" + +#: ../../po/../src/dialogs/export.cpp:416 +msgid "_Width:" +msgstr "_Breite:" + +#: ../../po/../src/dialogs/export.cpp:416 +#: ../../po/../src/dialogs/export.cpp:431 +msgid "pixels at" +msgstr "Pixel bei" + +#: ../../po/../src/dialogs/export.cpp:426 +msgid "dp_i" +msgstr "dp_i" + +#: ../../po/../src/dialogs/export.cpp:448 +msgid "_Filename" +msgstr "_Dateiname" + +#: ../../po/../src/dialogs/export.cpp:512 +msgid "_Browse..." +msgstr "_Auswählen..." + +#: ../../po/../src/dialogs/export.cpp:539 +msgid " _Export " +msgstr " _Exportieren " + +#: ../../po/../src/dialogs/export.cpp:541 +msgid "Export the bitmap file with these settings" +msgstr "Bitmapdatei mit diesen Einstellungen exportieren" + +#: ../../po/../src/dialogs/export.cpp:968 +msgid "You have to enter a filename" +msgstr "Sie müssen einen Dateinamen angeben" + +#: ../../po/../src/dialogs/export.cpp:973 +msgid "The chosen area to be exported is invalid" +msgstr "Der zum Exportieren gewählte Bereich ist ungültig" + +#: ../../po/../src/dialogs/export.cpp:982 +#, c-format +msgid "Directory %s does not exist or is not a directory.\n" +msgstr "Das Verzeichnis %s existiert nicht oder ist kein Verzeichnis.\n" + +#: ../../po/../src/dialogs/export.cpp:998 +msgid "Export in progress" +msgstr "Exportieren läuft" + +#: ../../po/../src/dialogs/export.cpp:1004 +#, c-format +msgid "Exporting %s (%d x %d)" +msgstr "Exportiere %s (%d × %d)" + +#: ../../po/../src/dialogs/export.cpp:1031 +#, c-format +msgid "Could not export to filename %s.\n" +msgstr "Konnte nicht als Datei %s exportieren.\n" + +#: ../../po/../src/dialogs/export.cpp:1137 +msgid "Select a filename for exporting" +msgstr "Wählen Sie einen Namen für die zu exportierende Datei" + +#: ../../po/../src/dialogs/filedialog.cpp:367 +msgid "No preview" +msgstr "Keine Vorschau" + +#: ../../po/../src/dialogs/filedialog.cpp:468 +msgid "too large for preview" +msgstr "Zu groß für Vorschau" + +#: ../../po/../src/dialogs/filedialog.cpp:762 +#: ../../po/../src/dialogs/filedialog.cpp:763 +msgid "All Images" +msgstr "Alle Bilder" + +#: ../../po/../src/dialogs/filedialog.cpp:767 +#: ../../po/../src/dialogs/filedialog.cpp:768 +msgid "All Files" +msgstr "Alle Dateien" + +#: ../../po/../src/dialogs/filedialog.cpp:774 +#: ../../po/../src/dialogs/filedialog.cpp:775 +msgid "All Inkscape Files" +msgstr "Alle Inkscape-Dateien" + +#: ../../po/../src/dialogs/filedialog.cpp:1176 +msgid "Guess from extension" +msgstr "Aus der Dateinamenserweiterung schließen" + +#. ###### Add the file types menu +#. createFilterMenu(); +#. ###### Do we want the .xxx extension automatically added? +#: ../../po/../src/dialogs/filedialog.cpp:1261 +msgid "Append filename extension automatically" +msgstr "Automatisch einen Suffix für Dateinamen anhängen" + +#. TRANSLATORS: "%s" is replaced with "exact" or "partial" when this string is displayed +#: ../../po/../src/dialogs/find.cpp:378 +#, c-format +msgid "%d object found (out of %d), %s match." +msgid_plural "%d objects found (out of %d), %s match." +msgstr[0] "%d (von %d) Objekt gefunden, %s passend." +msgstr[1] "%d (von %d) Objekten gefunden, %s passend." + +#: ../../po/../src/dialogs/find.cpp:381 +msgid "exact" +msgstr "exakt" + +#: ../../po/../src/dialogs/find.cpp:381 +msgid "partial" +msgstr "teilweise" + +#: ../../po/../src/dialogs/find.cpp:388 +msgid "No objects found" +msgstr "Keine Objekte gefunden" + +#: ../../po/../src/dialogs/find.cpp:546 +msgid "T_ype: " +msgstr "T_yp: " + +#: ../../po/../src/dialogs/find.cpp:553 +msgid "Search in all object types" +msgstr "Alle Objekttypen durchsuchen" + +#: ../../po/../src/dialogs/find.cpp:553 +msgid "All types" +msgstr "Alle Typen" + +#: ../../po/../src/dialogs/find.cpp:564 +msgid "Search all shapes" +msgstr "Alle Formen durchsuchen" + +#: ../../po/../src/dialogs/find.cpp:564 +msgid "All shapes" +msgstr "Alle Formen" + +#: ../../po/../src/dialogs/find.cpp:581 +msgid "Search rectangles" +msgstr "Rechtecke durchsuchen" + +#: ../../po/../src/dialogs/find.cpp:581 +msgid "Rectangles" +msgstr "Rechtecke" + +#: ../../po/../src/dialogs/find.cpp:586 +msgid "Search ellipses, arcs, circles" +msgstr "Ellipsen, Bögen und Kreise durchsuchen" + +#: ../../po/../src/dialogs/find.cpp:586 +msgid "Ellipses" +msgstr "Ellipsen" + +#: ../../po/../src/dialogs/find.cpp:591 +msgid "Search stars and polygons" +msgstr "Sterne und Polygone durchsuchen" + +#: ../../po/../src/dialogs/find.cpp:591 +msgid "Stars" +msgstr "Sterne" + +#: ../../po/../src/dialogs/find.cpp:596 +msgid "Search spirals" +msgstr "Spiralen durchsuchen" + +#: ../../po/../src/dialogs/find.cpp:596 +msgid "Spirals" +msgstr "Spiralen" + +#. TRANSLATORS: polyline is a set of connected straight line segments +#. http://www.w3.org/TR/SVG11/shapes.html#PolylineElement +#: ../../po/../src/dialogs/find.cpp:609 +msgid "Search paths, lines, polylines" +msgstr "Pfade, Linien oder Polylinien suchen" + +#: ../../po/../src/dialogs/find.cpp:609 +msgid "Paths" +msgstr "Pfade" + +#: ../../po/../src/dialogs/find.cpp:614 +msgid "Search text objects" +msgstr "Textobjekte durchsuchen" + +#: ../../po/../src/dialogs/find.cpp:614 +msgid "Texts" +msgstr "Texte" + +#: ../../po/../src/dialogs/find.cpp:619 +msgid "Search groups" +msgstr "Gruppen durchsuchen" + +#: ../../po/../src/dialogs/find.cpp:619 +msgid "Groups" +msgstr "Gruppen" + +#: ../../po/../src/dialogs/find.cpp:624 +msgid "Search clones" +msgstr "Klone durchsuchen" + +#: ../../po/../src/dialogs/find.cpp:629 +msgid "Search images" +msgstr "Bilder durchsuchen" + +#: ../../po/../src/dialogs/find.cpp:629 +msgid "Images" +msgstr "Bilder" + +#: ../../po/../src/dialogs/find.cpp:634 +msgid "Search offset objects" +msgstr "Objekte mit Versatz finden" + +#: ../../po/../src/dialogs/find.cpp:634 +msgid "Offsets" +msgstr "Versatz" + +#: ../../po/../src/dialogs/find.cpp:694 +msgid "_Text: " +msgstr "_Text: " + +#: ../../po/../src/dialogs/find.cpp:694 +msgid "Find objects by their text content (exact or partial match)" +msgstr "" +"Objekte nach ihrem Textinhalt finden (exakte oder partielle Übereinstimmung)" + +#: ../../po/../src/dialogs/find.cpp:695 +msgid "_ID: " +msgstr "_Kennung: " + +#: ../../po/../src/dialogs/find.cpp:695 +msgid "Find objects by the value of the id attribute (exact or partial match)" +msgstr "" +"Objekte nach dem Wert ihres id-Attributs finden (exakte oder partielle " +"Übereinstimmung)" + +#: ../../po/../src/dialogs/find.cpp:696 +msgid "_Style: " +msgstr "_Stil: " + +#: ../../po/../src/dialogs/find.cpp:696 +msgid "" +"Find objects by the value of the style attribute (exact or partial match)" +msgstr "" +"Objekte nach ihren Stilen finden (exakte oder partielle Übereinstimmung)" + +#: ../../po/../src/dialogs/find.cpp:697 +msgid "_Attribute: " +msgstr "_Attribut: " + +#: ../../po/../src/dialogs/find.cpp:697 +msgid "Find objects by the name of an attribute (exact or partial match)" +msgstr "" +"Objekte nach einem Attributnamen finden (exakte oder partielle " +"Übereinstimmung)" + +#: ../../po/../src/dialogs/find.cpp:711 +msgid "Search in s_election" +msgstr "_Auswahl durchsuchen" + +#: ../../po/../src/dialogs/find.cpp:715 +msgid "Limit search to the current selection" +msgstr "Suche auf aktuelle Auswahl beschränken" + +#: ../../po/../src/dialogs/find.cpp:720 +msgid "Search in current _layer" +msgstr "In aktueller Ebene suchen" + +#: ../../po/../src/dialogs/find.cpp:724 +msgid "Limit search to the current layer" +msgstr "Suche auf aktuelle Ebene beschränken" + +#: ../../po/../src/dialogs/find.cpp:729 +msgid "Include _hidden" +msgstr "einschließlich Verborgene" + +#: ../../po/../src/dialogs/find.cpp:733 +msgid "Include hidden objects in search" +msgstr "Verborgene Objekte bei Suche berücksichtigen" + +#: ../../po/../src/dialogs/find.cpp:738 +msgid "Include l_ocked" +msgstr "einschließlich Gesperrte" + +#: ../../po/../src/dialogs/find.cpp:742 +msgid "Include locked objects in search" +msgstr "Gesperrte Objekte bei Suche berücksichtigen" + +#: ../../po/../src/dialogs/find.cpp:753 +msgid "Clear values" +msgstr "Werte leeren" + +#: ../../po/../src/dialogs/find.cpp:754 +msgid "_Find" +msgstr "_Suchen" + +#: ../../po/../src/dialogs/find.cpp:754 +msgid "Select objects matching all of the fields you filled in" +msgstr "Wähle Objekte aus, die zu allen angegebene Feldern passen" + +#: ../../po/../src/dialogs/iconpreview.cpp:145 +#, c-format +msgid "%d x %d" +msgstr "%d × %d" + +#: ../../po/../src/dialogs/iconpreview.cpp:193 +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:857 +#: ../../po/../src/widgets/desktop-widget.cpp:1069 +msgid "Selection" +msgstr "Auswahl" + +#: ../../po/../src/dialogs/iconpreview.cpp:195 +msgid "Selection only or whole document" +msgstr "Nur Auswahl oder ganzes Dokument" + +#: ../../po/../src/dialogs/iconpreview.cpp:203 +msgid "Refresh the icons" +msgstr "Icons aktualisieren" + +#. Create the label for the object id +#: ../../po/../src/dialogs/item-properties.cpp:126 +#: ../../po/../src/dialogs/item-properties.cpp:327 +#: ../../po/../src/dialogs/item-properties.cpp:396 +#: ../../po/../src/dialogs/item-properties.cpp:403 +msgid "_Id" +msgstr "_ID-Kennung" + +#: ../../po/../src/dialogs/item-properties.cpp:135 +msgid "" +"The id= attribute (only letters, digits, and the characters .-_: allowed)" +msgstr "" +"Das Kennungsattribut »id=« (nur Buchstaben, Ziffern und die Zeichen ».-_:« " +"zulässig)" + +#. Button for setting the object's id, label, title and description. +#: ../../po/../src/dialogs/item-properties.cpp:149 +msgid "_Set" +msgstr "_Setzen" + +#. Create the label for the object label +#: ../../po/../src/dialogs/item-properties.cpp:158 +msgid "_Label" +msgstr "_Bezeichner" + +#: ../../po/../src/dialogs/item-properties.cpp:167 +msgid "A freeform label for the object" +msgstr "Freiform-Bezeichner des Objektes" + +#. Create the label for the object title +#: ../../po/../src/dialogs/item-properties.cpp:179 +#: ../../po/../src/dialogs/rdf.cpp:243 +msgid "Title" +msgstr "Titel" + +#. Create the frame for the object description +#: ../../po/../src/dialogs/item-properties.cpp:196 +#: ../../po/../src/dialogs/rdf.cpp:287 +msgid "Description" +msgstr "Beschreibung" + +#. Hide +#: ../../po/../src/dialogs/item-properties.cpp:223 +msgid "_Hide" +msgstr "_Ausblenden" + +#: ../../po/../src/dialogs/item-properties.cpp:224 +msgid "Check to make the object invisible" +msgstr "Aktivieren macht das Objekt unsichtbar" + +#. Lock +#. TRANSLATORS: "Lock" is a verb here +#: ../../po/../src/dialogs/item-properties.cpp:233 +msgid "L_ock" +msgstr "_Sperren" + +#: ../../po/../src/dialogs/item-properties.cpp:234 +msgid "Check to make the object insensitive (not selectable by mouse)" +msgstr "Aktivieren macht das Objekt unempfindlich (nicht durch Maus anwählbar)" + +#: ../../po/../src/dialogs/item-properties.cpp:310 +#: ../../po/../src/dialogs/item-properties.cpp:317 +msgid "Ref" +msgstr "Ref" + +#: ../../po/../src/dialogs/item-properties.cpp:398 +msgid "Id invalid! " +msgstr "ID-Kennung ist ungültig" + +#: ../../po/../src/dialogs/item-properties.cpp:400 +msgid "Id exists! " +msgstr "ID-Kennung existiert" + +#: ../../po/../src/dialogs/layer-properties.cpp:50 +msgid "Layer name:" +msgstr "Ebenenname:" + +#: ../../po/../src/dialogs/layer-properties.cpp:133 +msgid "Rename Layer" +msgstr "Ebene umbenennen" + +#: ../../po/../src/dialogs/layer-properties.cpp:136 +msgid "_Rename" +msgstr "Umbenennen" + +#. TRANSLATORS: This means "The layer has been renamed" +#: ../../po/../src/dialogs/layer-properties.cpp:147 +msgid "Renamed layer" +msgstr "Ebene umbenannt" + +#: ../../po/../src/dialogs/layer-properties.cpp:151 +msgid "Add Layer" +msgstr "Ebene hinzufügen" + +#: ../../po/../src/dialogs/layer-properties.cpp:153 +msgid "_Add" +msgstr "Hinzufügen" + +#: ../../po/../src/dialogs/layer-properties.cpp:167 +msgid "New layer created." +msgstr "Neue Ebene angelegt." + +#: ../../po/../src/dialogs/object-attributes.cpp:34 +msgid "Href:" +msgstr "" + +#: ../../po/../src/dialogs/object-attributes.cpp:35 +msgid "Target:" +msgstr "" + +#: ../../po/../src/dialogs/object-attributes.cpp:36 +msgid "Type:" +msgstr "" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkRoleAttribute +#. Identifies the type of the related resource with an absolute URI +#: ../../po/../src/dialogs/object-attributes.cpp:39 +msgid "Role:" +msgstr "" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkArcRoleAttribute +#. For situations where the nature/role alone isn't enough, this offers an additional URI defining the purpose of the link. +#: ../../po/../src/dialogs/object-attributes.cpp:42 +msgid "Arcrole:" +msgstr "" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkTitleAttribute +#: ../../po/../src/dialogs/object-attributes.cpp:44 +msgid "Title:" +msgstr "" + +#: ../../po/../src/dialogs/object-attributes.cpp:45 +msgid "Show:" +msgstr "" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkActuateAttribute +#: ../../po/../src/dialogs/object-attributes.cpp:47 +msgid "Actuate:" +msgstr "" + +#: ../../po/../src/dialogs/object-attributes.cpp:52 +msgid "URL:" +msgstr "" + +#: ../../po/../src/dialogs/object-attributes.cpp:53 +msgid "X:" +msgstr "X:" + +#: ../../po/../src/dialogs/object-attributes.cpp:54 +msgid "Y:" +msgstr "Y:" + +#: ../../po/../src/dialogs/object-attributes.cpp:98 +#, c-format +msgid "%s attributes" +msgstr "%s-Attribute" + +#: ../../po/../src/dialogs/object-properties.cpp:158 +msgid "_Fill" +msgstr "_Füllung" + +#: ../../po/../src/dialogs/object-properties.cpp:165 +msgid "Stroke _paint" +msgstr "_Farbe der Konturlinie" + +#: ../../po/../src/dialogs/object-properties.cpp:172 +msgid "Stroke st_yle" +msgstr "_Muster der Konturlinie" + +#: ../../po/../src/dialogs/object-properties.cpp:183 +msgid "Master _opacity" +msgstr "Gesamtdeckkraft" + +#: ../../po/../src/dialogs/rdf.cpp:244 +msgid "Name by which this document is formally known." +msgstr "Name, unter dem dieses Dokument formal bekannt ist." + +#: ../../po/../src/dialogs/rdf.cpp:246 +msgid "Date" +msgstr "Datum" + +#: ../../po/../src/dialogs/rdf.cpp:247 +msgid "Date associated with the creation of this document (YYYY-MM-DD)." +msgstr "" +"Datum, das mit der Erstellung dieses Dokuments assoziiert ist (JJJJ-MM-TT)." + +#: ../../po/../src/dialogs/rdf.cpp:249 +msgid "Format" +msgstr "Format" + +#: ../../po/../src/dialogs/rdf.cpp:250 +msgid "The physical or digital manifestation of this document (MIME type)." +msgstr "" +"Die physische oder digitale Erscheinungsform dieses Dokuments (MIME-Typ)." + +#: ../../po/../src/dialogs/rdf.cpp:252 +msgid "Type" +msgstr "Typ" + +#: ../../po/../src/dialogs/rdf.cpp:253 +msgid "Type of document (DCMI Type)." +msgstr "Typ des Dokuments (DCMI-Typ)." + +# !!! Urheber? +#: ../../po/../src/dialogs/rdf.cpp:256 +msgid "Creator" +msgstr "Autor/Urheber" + +#: ../../po/../src/dialogs/rdf.cpp:257 +msgid "" +"Name of entity primarily responsible for making the content of this document." +msgstr "" +"Name der Person oder Organisation, die hauptsächlich für die Erstellung des " +"Dokumenteninhalts verantwortlich ist." + +#: ../../po/../src/dialogs/rdf.cpp:259 +msgid "Rights" +msgstr "Rechte" + +#: ../../po/../src/dialogs/rdf.cpp:260 +msgid "" +"Name of entity with rights to the Intellectual Property of this document." +msgstr "" +"Name der Person oder Organisation, welche die Urheberrechte (Intellectual " +"Property) an diesem Dokument hält." + +#: ../../po/../src/dialogs/rdf.cpp:262 +msgid "Publisher" +msgstr "Herausgeber" + +#: ../../po/../src/dialogs/rdf.cpp:263 +msgid "Name of entity responsible for making this document available." +msgstr "" +"Name der Person oder Organisation, die für die Verfügbarmachung des " +"Dokuments verantwortlich ist." + +#: ../../po/../src/dialogs/rdf.cpp:266 +msgid "Identifier" +msgstr "Identifikator" + +#: ../../po/../src/dialogs/rdf.cpp:267 +msgid "Unique URI to reference this document." +msgstr "Eindeutige URI, um dieses Dokument zu referenzieren." + +#: ../../po/../src/dialogs/rdf.cpp:269 +msgid "Source" +msgstr "Quelle" + +#: ../../po/../src/dialogs/rdf.cpp:270 +msgid "Unique URI to reference the source of this document." +msgstr "Eindeutige URI, um die Quelle dieses Dokuments zu referenzieren." + +#: ../../po/../src/dialogs/rdf.cpp:272 +msgid "Relation" +msgstr "Beziehung" + +#: ../../po/../src/dialogs/rdf.cpp:273 +msgid "Unique URI to a related document." +msgstr "Eindeutige URI zu einem verwandten Dokument." + +#: ../../po/../src/dialogs/rdf.cpp:275 +msgid "Language" +msgstr "Sprache" + +#: ../../po/../src/dialogs/rdf.cpp:276 +msgid "" +"Two-letter language tag with optional subtags for the language of this " +"document. (e.g. 'en-GB')" +msgstr "" +"Zweibuchstabiges Sprachsymbol mit optionalen Untersymbolen für die Sprache " +"dieses Dokuments (z.B. »de-CH«)" + +#: ../../po/../src/dialogs/rdf.cpp:278 +msgid "Keywords" +msgstr "Schlagworte" + +#: ../../po/../src/dialogs/rdf.cpp:279 +msgid "" +"The topic of this document as comma-separated key words, phrases, or " +"classifications." +msgstr "" +"Das Thema dieses Dokuments als Schlagworte, Phrasen oder Klassifikation." + +# !!! not the best translation +#. TRANSLATORS: "Coverage": the spatial or temporal characteristics of the content. +#. For info, see Appendix D of http://www.w3.org/TR/1998/WD-rdf-schema-19980409/ +#: ../../po/../src/dialogs/rdf.cpp:283 +msgid "Coverage" +msgstr "Abdeckung" + +#: ../../po/../src/dialogs/rdf.cpp:284 +msgid "Extent or scope of this document." +msgstr "Umfang oder Abdeckungsbereich dieses Dokuments." + +#: ../../po/../src/dialogs/rdf.cpp:288 +msgid "A short account of the content of this document." +msgstr "Kurzer Abriß des Inhalts dieses Dokuments." + +#. FIXME: need to handle 1 agent per line of input +#: ../../po/../src/dialogs/rdf.cpp:292 +msgid "Contributors" +msgstr "Mitwirkende" + +#: ../../po/../src/dialogs/rdf.cpp:293 +msgid "" +"Names of entities responsible for making contributions to the content of " +"this document." +msgstr "" +"Namen von Personen oder Organisationen, die am Inhalt dieses Dokuments " +"mitgewirkt haben." + +#. TRANSLATORS: URL to a page that defines the license for the document +#: ../../po/../src/dialogs/rdf.cpp:297 +msgid "URI" +msgstr "URI" + +#. TRANSLATORS: this is where you put a URL to a page that defines the license +#: ../../po/../src/dialogs/rdf.cpp:299 +msgid "URI to this document's license's namespace definition." +msgstr "" +"URI, unter dem die Lizenzdefinition (license namespace) dieses Dokuments zu " +"finden ist." + +#. TRANSLATORS: fragment of XML representing the license of the document +#: ../../po/../src/dialogs/rdf.cpp:303 +msgid "Fragment" +msgstr "Fragment" + +#: ../../po/../src/dialogs/rdf.cpp:304 +msgid "XML fragment for the RDF 'License' section." +msgstr "XML-Fragment für den RDF-Abschnitt »Lizenz«." + +#: ../../po/../src/dialogs/stroke-style.cpp:774 +#: ../../po/../src/widgets/gradient-vector.cpp:263 +#: ../../po/../src/widgets/paint-selector.cpp:751 +msgid "No document selected" +msgstr "Kein Dokument gewählt" + +#: ../../po/../src/dialogs/stroke-style.cpp:992 +msgid "Stroke width" +msgstr "Breite der Konturlinie" + +#. Join type +#. TRANSLATORS: The line join style specifies the shape to be used at the +#. corners of paths. It can be "miter", "round" or "bevel". +#: ../../po/../src/dialogs/stroke-style.cpp:1015 +msgid "Join:" +msgstr "Verbindungsart:" + +#. TRANSLATORS: Miter join: joining lines with a sharp (pointed) corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1027 +msgid "Miter join" +msgstr "Spitze Verbindung" + +#. TRANSLATORS: Round join: joining lines with a rounded corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1035 +msgid "Round join" +msgstr "Abgerundete Verbindung" + +#. TRANSLATORS: Bevel join: joining lines with a blunted (flattened) corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1043 +msgid "Bevel join" +msgstr "Abgeschrägte Verbindung" + +#. Miterlimit +#. TRANSLATORS: Miter limit: only for "miter join", this limits the length +#. of the sharp "spike" when the lines connect at too sharp an angle. +#. When two line segments meet at a sharp angle, a miter join results in a +#. spike that extends well beyond the connection point. The purpose of the +#. miter limit is to cut off such spikes (i.e. convert them into bevels) +#. when they become too long. +#: ../../po/../src/dialogs/stroke-style.cpp:1054 +msgid "Miter limit:" +msgstr "Maximale Länge der Spitze:" + +#: ../../po/../src/dialogs/stroke-style.cpp:1062 +msgid "Maximum length of the miter (in units of stroke width)" +msgstr "Maximale Länge der Spitze (in Vielfachen der Linienbreite)" + +#. Cap type +#. TRANSLATORS: cap type specifies the shape for the ends of lines +#: ../../po/../src/dialogs/stroke-style.cpp:1075 +msgid "Cap:" +msgstr "Linienende:" + +#. TRANSLATORS: Butt cap: the line shape does not extend beyond the end point +#. of the line; the ends of the line are square +#: ../../po/../src/dialogs/stroke-style.cpp:1086 +msgid "Butt cap" +msgstr "Nicht überstehendes Ende" + +#. TRANSLATORS: Round cap: the line shape extends beyond the end point of the +#. line; the ends of the line are rounded +#: ../../po/../src/dialogs/stroke-style.cpp:1093 +msgid "Round cap" +msgstr "Abgerundetes Ende" + +#. TRANSLATORS: Square cap: the line shape extends beyond the end point of the +#. line; the ends of the line are square +#: ../../po/../src/dialogs/stroke-style.cpp:1100 +msgid "Square cap" +msgstr "Quadratisches Ende" + +#. Dash +#: ../../po/../src/dialogs/stroke-style.cpp:1106 +msgid "Dashes:" +msgstr "Strichlinien:" + +#. TRANSLATORS: Path markers are an SVG feature that allows you to attach arbitrary shapes +#. (arrowheads, bullets, faces, whatever) to the start, end, or middle nodes of a path. +#: ../../po/../src/dialogs/stroke-style.cpp:1127 +msgid "Start Markers:" +msgstr "Anfangsmarkierung:" + +#: ../../po/../src/dialogs/stroke-style.cpp:1137 +msgid "Mid Markers:" +msgstr "Markierungen dazwischen:" + +#: ../../po/../src/dialogs/stroke-style.cpp:1148 +msgid "End Markers:" +msgstr "Endmarkierungen" + +# !!! palettes, not swatches? +#: ../../po/../src/dialogs/swatches.cpp:424 +#, c-format +msgid "Palettes directory (%s) is unavailable." +msgstr "Palettenverzeichnis (%s) nicht auffindbar" + +#. TODO: Insert widgets +#: ../../po/../src/dialogs/text-edit.cpp:199 +#: ../../po/../src/ui/dialog/text-properties.cpp:36 +msgid "Font" +msgstr "Schrift" + +#: ../../po/../src/dialogs/text-edit.cpp:216 +msgid "Layout" +msgstr "Ausrichtung" + +#: ../../po/../src/dialogs/text-edit.cpp:229 +msgid "Align lines left" +msgstr "Zeilen links ausrichten" + +#. TRANSLATORS: `Center' here is a verb. +#: ../../po/../src/dialogs/text-edit.cpp:243 +msgid "Center lines" +msgstr "Zeilen zentrieren" + +#: ../../po/../src/dialogs/text-edit.cpp:256 +msgid "Align lines right" +msgstr "Zeilen rechts ausrichten" + +#: ../../po/../src/dialogs/text-edit.cpp:278 +msgid "Horizontal text" +msgstr "Horizontale Textausrichtung" + +#: ../../po/../src/dialogs/text-edit.cpp:292 +msgid "Vertical text" +msgstr "Vertikale Textausrichtung" + +#: ../../po/../src/dialogs/text-edit.cpp:307 +msgid "Line spacing:" +msgstr "Zeilenabstand:" + +#: ../../po/../src/dialogs/text-edit.cpp:400 +msgid "Set as default" +msgstr "Zur Vorgabe machen" + +#: ../../po/../src/dialogs/tiledialog.cpp:603 +msgid "Rows:" +msgstr "Reihen:" + +#: ../../po/../src/dialogs/tiledialog.cpp:613 +msgid "Number of rows" +msgstr "Anzahl der Zeilen" + +#: ../../po/../src/dialogs/tiledialog.cpp:617 +msgid "Equal height" +msgstr "Gleiche Höhe" + +#: ../../po/../src/dialogs/tiledialog.cpp:627 +msgid "If not set, each row has the height of the tallest object in it" +msgstr "" +"Wenn nicht gesetzt, dann hat jede Zeile die Höhe seines größten Objektes" + +#. #### Radio buttons to control vertical alignment #### +#. #### Radio buttons to control horizontal alignment #### +#: ../../po/../src/dialogs/tiledialog.cpp:637 +#: ../../po/../src/dialogs/tiledialog.cpp:708 +msgid "Align:" +msgstr "Ausrichten" + +#: ../../po/../src/dialogs/tiledialog.cpp:672 +msgid " X " +msgstr " X " + +#. #### Number of columns #### +#: ../../po/../src/dialogs/tiledialog.cpp:678 +msgid "Columns:" +msgstr "Spalten:" + +#: ../../po/../src/dialogs/tiledialog.cpp:688 +msgid "Number of columns" +msgstr "Anzahl der Spalten" + +#: ../../po/../src/dialogs/tiledialog.cpp:692 +msgid "Equal width" +msgstr "Gleiche Breite" + +#: ../../po/../src/dialogs/tiledialog.cpp:701 +msgid "If not set, each column has the width of the widest object in it" +msgstr "" +"Wenn nicht gesetzt, dann hat jede Spalte die Breite seines größten Objektes" + +#. #### Radio buttons to control spacing manually or to fit selection bbox #### +#: ../../po/../src/dialogs/tiledialog.cpp:746 +msgid "Fit into selection box" +msgstr "In den Auswahlrahmen einpassen" + +#: ../../po/../src/dialogs/tiledialog.cpp:753 +msgid "Set spacing:" +msgstr "Abstand setzen:" + +#. #### Y Padding #### +#: ../../po/../src/dialogs/tiledialog.cpp:777 +msgid "Row spacing: " +msgstr "Abstand der Reihen:" + +#: ../../po/../src/dialogs/tiledialog.cpp:786 +msgid "Vertical spacing between rows" +msgstr "Vertikale Abstände zwischen einzelnen Reihen" + +#. #### X padding #### +#: ../../po/../src/dialogs/tiledialog.cpp:795 +msgid "Column spacing:" +msgstr "Spaltenabstand:" + +#: ../../po/../src/dialogs/tiledialog.cpp:804 +msgid "Horizontal spacing between columns" +msgstr "Horizontale Abstände für jede Spalte" + +#: ../../po/../src/dialogs/tiledialog.cpp:818 +#, fuzzy +msgid "Arrange selected objects" +msgstr "Die gewählten Objekte gruppieren" + +#: ../../po/../src/dialogs/xml-tree.cpp:178 +msgid "Click to select nodes, drag to rearrange." +msgstr "Klicken wählt Knoten aus, Ziehen zur neuen Anordnung." + +#: ../../po/../src/dialogs/xml-tree.cpp:189 +msgid "Click attribute to edit." +msgstr "Klicken auf Attribut zum Bearbeiten" + +#: ../../po/../src/dialogs/xml-tree.cpp:193 +#, c-format +msgid "" +"Attribute %s selected. Press Ctrl+Enter when done editing to " +"commit changes." +msgstr "" +"Attribut %s ausgewählt. Strg+Eingabe schließt ab und übernimmt " +"Änderungen." + +#: ../../po/../src/dialogs/xml-tree.cpp:284 +msgid "Drag to reorder nodes" +msgstr "Ablegen, um die Knoten neu zu sortieren" + +#: ../../po/../src/dialogs/xml-tree.cpp:304 +msgid "New element node" +msgstr "Neuer Elementknoten" + +#: ../../po/../src/dialogs/xml-tree.cpp:326 +msgid "New text node" +msgstr "Neuer Textknoten" + +#: ../../po/../src/dialogs/xml-tree.cpp:347 +msgid "Duplicate node" +msgstr "Knoten duplizieren" + +#: ../../po/../src/dialogs/xml-tree.cpp:368 +msgid "Delete node" +msgstr "Knoten löschen" + +#: ../../po/../src/dialogs/xml-tree.cpp:384 +msgid "Unindent node" +msgstr "Einrückung des Knotens verringern" + +#: ../../po/../src/dialogs/xml-tree.cpp:399 +msgid "Indent node" +msgstr "Knoten einrücken" + +#: ../../po/../src/dialogs/xml-tree.cpp:411 +msgid "Raise node" +msgstr "Knoten anheben" + +#: ../../po/../src/dialogs/xml-tree.cpp:423 +msgid "Lower node" +msgstr "Knoten absenken" + +#: ../../po/../src/dialogs/xml-tree.cpp:468 +msgid "Delete attribute" +msgstr "Attribut löschen" + +#. TRANSLATORS: "Attribute" is a noun here +#: ../../po/../src/dialogs/xml-tree.cpp:513 +msgid "Attribute name" +msgstr "Attributname" + +#. TRANSLATORS: "Set" is a verb here +#: ../../po/../src/dialogs/xml-tree.cpp:533 +msgid "Set attribute" +msgstr "Attribut festlegen" + +#. TRANSLATORS: "Set" is a verb here +#: ../../po/../src/dialogs/xml-tree.cpp:535 +msgid "Set" +msgstr "Setzen" + +#. TRANSLATORS: "Attribute" is a noun here +#: ../../po/../src/dialogs/xml-tree.cpp:558 +msgid "Attribute value" +msgstr "Attributwert" + +#: ../../po/../src/dialogs/xml-tree.cpp:1318 +msgid "New element node..." +msgstr "Neuer Elementknoten..." + +#: ../../po/../src/dialogs/xml-tree.cpp:1339 +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:100 +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:98 +msgid "Cancel" +msgstr "Abbrechen" + +#: ../../po/../src/dialogs/xml-tree.cpp:1345 +msgid "Create" +msgstr "Erstellen" + +#: ../../po/../src/dialogs/xml-tree.cpp:1458 +#, c-format +msgid "" +"Cannot set %s: Another element with value %s already exists!" +msgstr "" +"Konnte %s nicht übernehmen: Ein anderes Element mit dem Wert %s existiert bereits!" + +#: ../../po/../src/document.cpp:369 +#, c-format +msgid "New document %d" +msgstr "Neues Dokument %d" + +#: ../../po/../src/document.cpp:401 +#, c-format +msgid "Memory document %d" +msgstr "Speicherdokument %d" + +#: ../../po/../src/document.cpp:524 +#, c-format +msgid "Unnamed document %d" +msgstr "Unbenanntes Dokument %d" + +#. We hit green anchor, closing Green-Blue-Red +#: ../../po/../src/draw-context.cpp:441 +msgid "Path is closed." +msgstr "Pfad ist geschlossen." + +#. We hit bot start and end of single curve, closing paths +#: ../../po/../src/draw-context.cpp:456 +msgid "Closing path." +msgstr "Geschlossener Pfad." + +#. alpha of color under cursor, to show in the statusbar +#. locale-sensitive printf is OK, since this goes to the UI, not into SVG +#: ../../po/../src/dropper-context.cpp:354 +#, c-format +msgid " alpha %.3g" +msgstr " Alpha %.3g" + +#. where the color is picked, to show in the statusbar +#: ../../po/../src/dropper-context.cpp:356 +#, c-format +msgid ", averaged with radius %d" +msgstr ", gemittelt mit Radius %d" + +#: ../../po/../src/dropper-context.cpp:356 +msgid " under cursor" +msgstr " unter Zeiger" + +#. message, to show in the statusbar +#: ../../po/../src/dropper-context.cpp:358 +msgid "Release mouse to set color." +msgstr "Maustaste loslassen, um die Farbe zu übernehmen." + +#: ../../po/../src/dropper-context.cpp:358 +#: ../../po/../src/tools-switch.cpp:207 +msgid "" +"Click to set fill, Shift+click to set stroke; drag to " +"average color in area; with Alt to pick inverse color; Ctrl+C " +"to copy the color under mouse to clipboard" +msgstr "" +"Klick setzt Füllfarbe, Umschalt+Klick setzt Linienfarbe; " +"Ziehen - Durchschnittsfarbe im Gebiet. Strg+C - Farbe nach " +"Zwischenablage" + +#: ../../po/../src/extension/dependency.cpp:244 +msgid "Dependency::" +msgstr "Abhängigkeit::" + +#: ../../po/../src/extension/dependency.cpp:245 +msgid " type: " +msgstr " Typ: " + +#: ../../po/../src/extension/dependency.cpp:246 +msgid " location: " +msgstr " Speicherort: " + +#: ../../po/../src/extension/dependency.cpp:247 +msgid " string: " +msgstr " Zeichenkette: " + +#: ../../po/../src/extension/dependency.cpp:250 +msgid " description: " +msgstr " Beschreibung: " + +#. static int i = 0; +#. std::cout << "Checking module[" << i++ << "]: " << name << std::endl; +#: ../../po/../src/extension/extension.cpp:244 +msgid "" +" This is caused by an improper .inx file for this extension. An improper ." +"inx file could have been caused by a faulty installation of Inkscape." +msgstr "" +" Dies wurde durch eine fehlerhafte .inx Datei der Erweiterung verursacht. " +"Eine fehlerhafte .inx Datei kann Folge einer Fehlinstallation von Inkscape " +"sein." + +#: ../../po/../src/extension/extension.cpp:247 +msgid "an ID was not defined for it." +msgstr "es wurde hierfür keine ID definiert." + +#: ../../po/../src/extension/extension.cpp:251 +msgid "there was no name defined for it." +msgstr "hierfür wurde kein Name definiert." + +#: ../../po/../src/extension/extension.cpp:255 +msgid "the XML description of it got lost." +msgstr "Zugehörige XML-Beschreibung ist nicht auffindbar." + +#: ../../po/../src/extension/extension.cpp:259 +msgid "no implementation was defined for the extension." +msgstr "Für diese Erweiterung existiert keine Implementierung." + +#. std::cout << "Failed: " << *(_deps[i]) << std::endl; +#: ../../po/../src/extension/extension.cpp:266 +msgid "a dependency was not met." +msgstr "die Abhängigkeiten nicht aufgelöst werden konnten." + +#: ../../po/../src/extension/extension.cpp:286 +msgid "Extension \"" +msgstr "Erweiterung \"" + +#: ../../po/../src/extension/extension.cpp:286 +msgid "\" failed to load because " +msgstr "\": Laden fehlgeschlagen, da " + +#: ../../po/../src/extension/extension.cpp:565 +#, c-format +msgid "Could not create extension error log file '%s'" +msgstr "Fehlerprotokolldatei konnte nicht erweitert oder erzeugt werden »%s«." + +#. This is some filler text, needs to change before relase +#: ../../po/../src/extension/error-file.cpp:56 +msgid "" +"One or more extensions failed to load\n" +"\n" +"The failed extensions have been skipped. Inkscape will continue to run " +"normally but those extensions will be unavailable. For details to " +"troubleshoot this problem, please refer to the error log located at: " +msgstr "" +"Eine oder mehrere Erweiterungen " +"konnten nicht geladen werden.\n" +"\n" +"Nicht verfügbare Eweiterungen wurden ausgelassen. Inkscape setzt seinen " +"normalen Ablauf fort, doch diese Erweiterungen sind nicht anwendbar. Details " +"zum Beheben des Problems finden sich in der Logdatei unter:" + +#. This is some filler text, needs to change before relase +#: ../../po/../src/extension/error-file.cpp:65 +msgid "Show dialog on startup" +msgstr "Dialog beim Starten des Programmes anzeigen" + +#: ../../po/../src/extension/implementation/script.cpp:845 +msgid "" +"Inkscape has received an error from the script that it called. The text " +"returned with the error is included below. Inkscape will continue working, " +"but the action you requested has been cancelled." +msgstr "" +"Inkscape hat eine Fehlermeldung des ausgeführten Skripts erhalten. Der " +"Textinhalt der Fehlermeldung wird unten angezeigt. Inkscape läuft ohne " +"Störung weiter, die letzte Aktion wurde jedoch abgebrochen." + +#: ../../po/../src/extension/implementation/script.cpp:858 +msgid "" +"Inkscape has received additional data from the script executed. The script " +"did not return an error, but this may indicate the results will not be as " +"expected." +msgstr "" +"Das aufgerufene Skript hat zusätzliche Daten an Inkscape übergeben. Es wurde " +"keine Fehlermeldung vom Skript zurückgegeben, doch das Resultat der Aktion " +"ist möglicherweise unbrauchbar." + +#: ../../po/../src/extension/init.cpp:173 +msgid "Null external module directory name. Modules will not be loaded." +msgstr "" +"Modulverzeichnis ist nicht verfügbar. Module in diesem Verzeichnis werden " +"nicht geladen." + +#: ../../po/../src/extension/init.cpp:187 +#, c-format +msgid "" +"Modules directory (%s) is unavailable. External modules in that directory " +"will not be loaded." +msgstr "" +"Das Modulverzeichnis (%s) ist nicht verfügbar. Externe Module in diesem " +"Verzeichnis werden nicht geladen." + +#: ../../po/../src/extension/internal/gnome.cpp:80 +msgid "Select printer" +msgstr "Drucker wählen" + +#: ../../po/../src/extension/internal/gnome.cpp:131 +msgid "Inkscape: Print Preview" +msgstr "Inkscape: Druckvorschau" + +#: ../../po/../src/extension/internal/grid.cpp:213 +msgid "Line Width" +msgstr "Linienstärke" + +#: ../../po/../src/extension/internal/grid.cpp:214 +msgid "Horizontal Spacing" +msgstr "Horizontale Abstände" + +#: ../../po/../src/extension/internal/grid.cpp:215 +msgid "Vertical Spacing" +msgstr "Vertikale Abstände" + +#: ../../po/../src/extension/internal/grid.cpp:216 +msgid "Horizontal Offset" +msgstr "Horizontaler Versatz" + +#: ../../po/../src/extension/internal/grid.cpp:217 +msgid "Vertical Offset" +msgstr "Vertikaler Versatz" + +#: ../../po/../src/extension/internal/ps.cpp:123 +msgid "Print Destination" +msgstr "Druckziel" + +#. Print properties frame +#: ../../po/../src/extension/internal/ps.cpp:138 +msgid "Print properties" +msgstr "Druckeigenschaften" + +#: ../../po/../src/extension/internal/ps.cpp:145 +msgid "Print using PostScript operators" +msgstr "Unter Verwendung von PostScript-Operatoren drucken" + +#: ../../po/../src/extension/internal/ps.cpp:147 +msgid "" +"Use PostScript vector operators. The resulting image is usually smaller in " +"file size and can be arbitrarily scaled, but alpha transparency and patterns " +"will be lost." +msgstr "" +"PostScript-Vektoroperatoren verwenden. Das resultierende Bild ist " +"(normalerweise) kleiner und kann beliebig skaliert werden, Alpha-" +"Transparenz, Farbverläufe und Muster gehen jedoch verloren." + +#: ../../po/../src/extension/internal/ps.cpp:152 +msgid "Print as bitmap" +msgstr "Als Bitmap drucken" + +#: ../../po/../src/extension/internal/ps.cpp:154 +msgid "" +"Print everything as bitmap. The resulting image is usually larger in file " +"size and cannot be arbitrarily scaled without quality loss, but all objects " +"will be rendered exactly as displayed." +msgstr "" +"Alles als Bitmap ausdrucken. Das resultierende Bild ist (normalerweise) " +"größer und die Qualität hängt vom Zoomfaktor ab, die Zeichnung wird jedoch " +"identisch zur angezeigten ausgegeben." + +#: ../../po/../src/extension/internal/ps.cpp:168 +msgid "Preferred resolution (dots per inch) of bitmap" +msgstr "Bevorzugte Auflösung der Bitmap (Punkte pro Zoll)" + +#: ../../po/../src/extension/internal/ps.cpp:182 +msgid "Resolution:" +msgstr "Auflösung:" + +#. Print destination frame +#: ../../po/../src/extension/internal/ps.cpp:186 +msgid "Print destination" +msgstr "Druckziel" + +#: ../../po/../src/extension/internal/ps.cpp:192 +msgid "" +"Use '> filename' to print to file.\n" +"Use '| prog arg...' to pipe to a program." +msgstr "" +"Verwenden Sie »> Dateiname« zum Drucken in eine Datei.\n" +"Verwenden Sie »| Prog. Arg. ...« zur Weiterleitung an ein Programm." + +#: ../../po/../src/extension/internal/ps.cpp:1227 +msgid "write error occurred" +msgstr "Schreibfehler aufgetreten" + +#: ../../po/../src/extension/prefdialog.cpp:21 +msgid " Preferences" +msgstr "-Einstellungen" + +#. We can't call sp_ui_error_dialog because we may be +#. running from the console, in which case calling sp_ui +#. routines will cause a segfault. See bug 1000350 - bryce +#. sp_ui_error_dialog(_("Format autodetect failed. The file is being opened as SVG.")); +#: ../../po/../src/extension/system.cpp:105 +msgid "Format autodetect failed. The file is being opened as SVG." +msgstr "" +"Die automatische Ermittlung des Formats ist fehlgeschlagen. Die Datei wird " +"als SVG-Dokument geöffnet." + +#. TRANSLATORS: default.svg is localizable - this is the name of the default document +#. template. This way you can localize the default pagesize, translate the name of +#. the default layer, etc. If you wish to localize this file, please create a +#. localized share/templates/default.xx.svg file, where xx is your language code. +#: ../../po/../src/file.cpp:133 +msgid "default.svg" +msgstr "default.de.svg" + +#: ../../po/../src/file.cpp:215 ../../po/../src/file.cpp:900 +#, c-format +msgid "Failed to load the requested file %s" +msgstr "Laden der gewünschten Datei %s fehlgeschlagen" + +#: ../../po/../src/file.cpp:240 +msgid "Document not saved yet. Cannot revert." +msgstr "Dokument noch nicht gespeichtert. Kann nicht zurücksetzen." + +#: ../../po/../src/file.cpp:246 +#, c-format +msgid "Changes will be lost! Are you sure you want to reload document %s?" +msgstr "" +"Änderungen gehen verloren! Sind Sie sicher, dass Sie das Dokument %s erneut " +"laden möchten?" + +#: ../../po/../src/file.cpp:266 +msgid "Document reverted." +msgstr "Dokument zurückgesetzt." + +#: ../../po/../src/file.cpp:268 +msgid "Document not reverted." +msgstr "Dokument nicht zurückgesetzt." + +#: ../../po/../src/file.cpp:382 +msgid "Select file to open" +msgstr "Wählen Sie die zu öffnende Datei" + +#: ../../po/../src/file.cpp:518 +#, c-format +msgid "Removed %i unused definition in <defs>." +msgid_plural "Removed %i unused definitions in <defs>." +msgstr[0] "%i überflüssiges Element aus <defs> entfernt." +msgstr[1] "%i überflüssige Elemente aus <defs> entfernt." + +#: ../../po/../src/file.cpp:523 +msgid "No unused definitions in <defs>." +msgstr "Keine überflüssigen Elemente in <defs>." + +#: ../../po/../src/file.cpp:548 +#, c-format +msgid "" +"No Inkscape extension found to save document (%s). This may have been " +"caused by an unknown filename extension." +msgstr "" +"Keine vorhandene Erweiterung von Inkscape kann das Dokument (%s) sichern. " +"Dies ist möglicherweise durch ein unbekannte Dateinamenendung verursacht." + +#: ../../po/../src/file.cpp:549 ../../po/../src/file.cpp:557 +msgid "Document not saved." +msgstr "Dokument wurde nicht gespeichert." + +#: ../../po/../src/file.cpp:556 +#, c-format +msgid "File %s could not be saved." +msgstr "Datei %s konnte nicht gespeichert werden." + +#: ../../po/../src/file.cpp:566 +msgid "Document saved." +msgstr "Dokument wurde gespeichert." + +#: ../../po/../src/file.cpp:614 +#, c-format +msgid "drawing%s" +msgstr "Zeichnung%s" + +#: ../../po/../src/file.cpp:620 +#, c-format +msgid "drawing-%d%s" +msgstr "Zeichnung-%d%s" + +#: ../../po/../src/file.cpp:655 +msgid "Select file to save to" +msgstr "Wählen Sie die zu speichernde Datei" + +#: ../../po/../src/file.cpp:739 +msgid "No changes need to be saved." +msgstr "Es müssen keine Änderungen gespeichert werden." + +#: ../../po/../src/file.cpp:926 +msgid "Select file to import" +msgstr "Wählen Sie die zu importierende Datei" + +#: ../../po/../src/gradient-context.cpp:263 +msgid "Ctrl: snap gradient angle" +msgstr "Strg: Winkel des Farbverlaufs einrasten" + +#: ../../po/../src/gradient-context.cpp:264 +msgid "Shift: draw gradient around the starting point" +msgstr "Umschalt: Farbverlauf ausgehend vom Mittelpunkt zeichnen" + +#. We did an undoable action, but sp_document_done will be called by the knot when released +#. status text; we do not track coords because this branch is run once, not all the time +#. during drag +#: ../../po/../src/gradient-context.cpp:462 +#, c-format +msgid "Gradient for %d objects; with Ctrl to snap angle" +msgstr "Farbverlauf für %d Objekte; mit Strg Winkel einrasten" + +#: ../../po/../src/gradient-context.cpp:464 +msgid "Select objects on which to create gradient." +msgstr "Objekte auswählen, für die ein Farbverlauf erzeugt werden soll." + +#: ../../po/../src/gradient-drag.cpp:65 +msgid "Linear gradient start" +msgstr "Linearer Farbverlauf Anfang" + +#. POINT_LG_P1 +#: ../../po/../src/gradient-drag.cpp:66 +msgid "Linear gradient end" +msgstr "Ende des linearen Farbverlaufs" + +#: ../../po/../src/gradient-drag.cpp:67 +msgid "Radial gradient center" +msgstr "Zentrum des radialen Farbverlaufs" + +#: ../../po/../src/gradient-drag.cpp:68 ../../po/../src/gradient-drag.cpp:69 +msgid "Radial gradient radius" +msgstr "Radius des radialen Farbverlaufs" + +#: ../../po/../src/gradient-drag.cpp:70 +msgid "Radial gradient focus" +msgstr "Fokus des radialen Farbverlaufs" + +#: ../../po/../src/gradient-drag.cpp:659 +#, c-format +msgid "" +"%s for: %s%s; drag with Ctrl to snap angle, with Ctrl+Alt to " +"preserve angle, with Ctrl+Shift to scale around center" +msgstr "" +"%s für %s%s; Ziehen mit Strg rastet Winkel ein, Ziehen mit Strg" +"+Alt behält Winkel bei" + +#: ../../po/../src/gradient-drag.cpp:662 +msgid " (stroke)" +msgstr " (Konturlinie)" + +#: ../../po/../src/gradient-drag.cpp:665 +msgid "" +"Radial gradient center and focus; drag with Shift to " +"separate focus" +msgstr "" +"Zentrum und Fokus des radialen Farbverlaufs; Umschalt" +"+Ziehen, um den Fokus einzeln zu bewegen" + +#: ../../po/../src/gradient-drag.cpp:667 +#, c-format +msgid "" +"Gradient point shared by %d gradients; drag with Shift to " +"separate" +msgstr "" +"Farbverlaufspunkt ist %d weiteren Farbverläufen zugewiesen. Ziehen " +"mit Umschalt trennt die Zuweisung" + +#: ../../po/../src/helper/units.cpp:40 +msgid "Unit" +msgstr "Einheit" + +#: ../../po/../src/helper/units.cpp:40 +msgid "Units" +msgstr "Einheit" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Point" +msgstr "Punkt" + +#: ../../po/../src/helper/units.cpp:41 +msgid "pt" +msgstr "pt" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Points" +msgstr "Punkt" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Pt" +msgstr "Pkt" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Pixel" +msgstr "Pixel" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Pixels" +msgstr "Pixel" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Px" +msgstr "Px" + +#. You can add new elements from this point forward +#: ../../po/../src/helper/units.cpp:44 ../share/extensions/straightseg.inx.h:2 +msgid "Percent" +msgstr "Prozent" + +#: ../../po/../src/helper/units.cpp:44 +msgid "Percents" +msgstr "Prozent" + +#: ../../po/../src/helper/units.cpp:45 +msgid "Millimeter" +msgstr "Millimeter" + +#: ../../po/../src/helper/units.cpp:45 +msgid "mm" +msgstr "mm" + +#: ../../po/../src/helper/units.cpp:45 +msgid "Millimeters" +msgstr "Millimeter" + +#: ../../po/../src/helper/units.cpp:46 +msgid "Centimeter" +msgstr "Zentimeter" + +#: ../../po/../src/helper/units.cpp:46 +msgid "cm" +msgstr "cm" + +#: ../../po/../src/helper/units.cpp:46 +msgid "Centimeters" +msgstr "Zentimeter" + +#: ../../po/../src/helper/units.cpp:47 +msgid "Meter" +msgstr "Meter" + +#: ../../po/../src/helper/units.cpp:47 +msgid "m" +msgstr "m" + +#: ../../po/../src/helper/units.cpp:47 +msgid "Meters" +msgstr "Meter" + +#. no svg_unit +#: ../../po/../src/helper/units.cpp:48 +msgid "Inch" +msgstr "Zoll" + +#: ../../po/../src/helper/units.cpp:48 +msgid "in" +msgstr "In" + +#: ../../po/../src/helper/units.cpp:48 +msgid "Inches" +msgstr "Zoll" + +#. Volatiles do not have default, so there are none here +#. TRANSLATORS: for info, see http://www.w3.org/TR/REC-CSS2/syndata.html#length-units +#: ../../po/../src/helper/units.cpp:51 +msgid "Em square" +msgstr "Em-Quadrat" + +#: ../../po/../src/helper/units.cpp:51 +msgid "em" +msgstr "em" + +#: ../../po/../src/helper/units.cpp:51 +msgid "Em squares" +msgstr "Em-Quadrate" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/REC-CSS2/syndata.html#length-units +#: ../../po/../src/helper/units.cpp:53 +msgid "Ex square" +msgstr "Ix-Quadrat" + +#: ../../po/../src/helper/units.cpp:53 +msgid "ex" +msgstr "ex" + +#: ../../po/../src/helper/units.cpp:53 +msgid "Ex squares" +msgstr "Ix-Quadrate" + +#: ../../po/../src/inkscape.cpp:468 +msgid "Untitled document" +msgstr "Unbenanntes Dokument" + +#. Show nice dialog box +#: ../../po/../src/inkscape.cpp:497 +msgid "Inkscape encountered an internal error and will close now.\n" +msgstr "" +"Inkscape ist auf einen internen Fehler gestoßen und wird nun geschlossen.\n" + +#: ../../po/../src/inkscape.cpp:498 +msgid "" +"Automatic backups of unsaved documents were done to the following " +"locations:\n" +msgstr "" +"Unter folgenden Speicherorten wurden automatische Sicherungskopien nicht " +"gespeicherter Dokumente angelegt:\n" + +#: ../../po/../src/inkscape.cpp:499 +msgid "Automatic backup of the following documents failed:\n" +msgstr "" +"Anlegen von automatischen Sicherungskopien folgender Dokumente " +"fehlgeschlagen:\n" + +#: ../../po/../src/inkscape.cpp:634 +#, c-format +msgid "" +"Cannot create directory %s.\n" +"%s" +msgstr "" +"Kann Verzeichnis %s nicht anlegen.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:635 +#, c-format +msgid "" +"%s is not a valid directory.\n" +"%s" +msgstr "" +"%s ist kein gültiges Verzeichnis.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:636 +#, c-format +msgid "" +"Cannot create file %s.\n" +"%s" +msgstr "" +"Kann Datei %s nicht anlegen.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:637 +#, c-format +msgid "" +"Cannot write file %s.\n" +"%s" +msgstr "" +"Kann Datei %s nicht schreiben.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:638 +msgid "" +"Although Inkscape will run, it will use default settings,\n" +"and any changes made in preferences will not be saved." +msgstr "" +"Inkscape wird zwar ausgeführt, es werden jedoch die Standard-Einstellungen " +"verwendet,\n" +"und keine Änderung der Benutzereinstellungen wird gespeichert." + +#: ../../po/../src/inkscape.cpp:708 +#, c-format +msgid "" +"%s is not a regular file.\n" +"%s" +msgstr "" +"%s ist keine reguläre Datei.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:709 +#, c-format +msgid "" +"%s not a valid XML file, or\n" +"you don't have read permissions on it.\n" +"%s" +msgstr "" +"%s ist keine gültige XML-Datei, oder\n" +"Sie haben keine Leseberechtigung dafür.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:711 +#, c-format +msgid "" +"%s is not a valid menus file.\n" +"%s" +msgstr "" +"%s ist keine gültige Menübeschreibungsdatei.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:712 +msgid "" +"Inkscape will run with default menus.\n" +"New menus will not be saved." +msgstr "" +"Inkscape läuft mit den Vorgabemenüs.\n" +"Neue Menüs werden nicht gespeichert." + +#. sp_ui_menu_append_check_item_from_verb(m, view, _("_Menu"), _("Show or hide the menu bar"), "menu", +#. checkitem_toggled, checkitem_update, 0); +#: ../../po/../src/interface.cpp:753 +msgid "Commands Bar" +msgstr "Befehlsleiste" + +#: ../../po/../src/interface.cpp:753 +msgid "Show or hide the Commands bar (under the menu)" +msgstr "Befehlsleiste anzeigen oder ausblenden (Leiste unter dem Hauptmenü)" + +#: ../../po/../src/interface.cpp:755 +msgid "Tool Controls" +msgstr "Werkzeugeinstellungen" + +#: ../../po/../src/interface.cpp:755 +msgid "Show or hide the Tool Controls panel" +msgstr "Einstellungen für das Werkzeug ein-/ausblenden" + +#: ../../po/../src/interface.cpp:757 +msgid "_Toolbox" +msgstr "Werkzeugleis_te" + +#: ../../po/../src/interface.cpp:757 +msgid "Show or hide the main toolbox (on the left)" +msgstr "Werkzeugleiste (auf der linken Seite) an- oder abschalten" + +#: ../../po/../src/interface.cpp:763 +msgid "_Statusbar" +msgstr "_Statuszeile" + +#: ../../po/../src/interface.cpp:763 +msgid "Show or hide the statusbar (at the bottom of the window)" +msgstr "Statusleiste an- oder abschalten (am unteren Ende des Fensters)" + +#: ../../po/../src/interface.cpp:820 +#, c-format +msgid "Verb \"%s\" Unknown" +msgstr "Verb \"%s\" unbekannt" + +#. TRANSLATORS: #%s is the id of the group e.g. , not a number. +#: ../../po/../src/interface.cpp:930 +#, c-format +msgid "Enter group #%s" +msgstr "Gruppe #%s bearbeiten" + +#: ../../po/../src/interface.cpp:941 +msgid "Go to parent" +msgstr "Zum übergeordneten Objekt gehen" + +#: ../../po/../src/interface.cpp:972 +msgid "Could not parse SVG data" +msgstr "SVG Daten konnten nicht gelesen werden" + +#: ../../po/../src/interface.cpp:1135 +#, c-format +msgid "Overwrite %s" +msgstr "Überschreibe %s" + +#: ../../po/../src/interface.cpp:1153 +#, c-format +msgid "" +"The file %s already exists. Do you want to overwrite that file with the " +"current document?" +msgstr "" +"Die Datei %s existiert bereits. Wollen Sie diese Datei mit dem aktuellen " +"Dokument überschreiben?" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:59 +msgid "Jabber connection lost." +msgstr "Verbindung mit Jabber verloren." + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:72 +#, c-format +msgid "Sending message; %u message remaining in send queue." +msgid_plural "Sending message; %u messages remaining in send queue." +msgstr[0] "Sende Meldung; %u Meldung verbleibt in der Sendewarteschlange." +msgstr[1] "Sende Meldung; %u Meldungen verbleiben in der Sendewarteschlange." + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:78 +msgid "Receive queue empty." +msgstr "Empfangswarteschlange leer." + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:154 +#, c-format +msgid "Receiving change; %u change left to process." +msgid_plural "Receiving change; %u changes left to process." +msgstr[0] "Erhalte Änderung; %u Änderung noch zu Verarbeiten." +msgstr[1] "Erhalte Änderung; %u Änderungen noch zu Verarbeiten." + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:157 +#, c-format +msgid "%s has left the chatroom." +msgstr "%s hat den Chat-Raum verlassen." + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:221 +msgid "Nickname %1 is already in use. Please choose a different nickname." +msgstr "" +"Chat-Spitzname »%1« ist bereits belegt. Bitte wählen Sie einen anderen " +"Spitznamen." + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:225 +msgid "An error was encountered while attempting to connect to the server." +msgstr "Fehler beim Versuch, zum Server zu verbinden." + +#. Check to see if the user made any modifications to this document. If so, +#. we want to give them the option of (1) letting us clear their document or (2) +#. opening a new, blank document for the whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:131 +msgid "%1 has invited you to a whiteboard session." +msgstr "%1 hat Sie zu einer Whiteboard-Sitzung eingeladen." + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:132 +msgid "Incoming whiteboard invitation from %1" +msgstr "Eingehende Einladung zum gemeinsamen Whiteboard von %1" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:135 +msgid "Do you wish to accept %1's whiteboard session invitation?" +msgstr "" +"Möchten Sie die Einladung von %1 zu einer gemeinsamen Whiteboard-" +"Sitzung annehmen?" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:137 +msgid "" +"Would you like to accept %1's invitation in a new document window?\n" +"Accepting the invitation in your current window will discard unsaved changes." +msgstr "" +"Möchten Sie die Einladung von %1 in ein neues Dokumentenfenster annehmen?\n" +"Wenn Sie die Einladung in das aktuelle Fenster annehmen, dann gehen " +"ungespeicherte Änderungen verloren." + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:143 +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:198 +msgid "Accept invitation" +msgstr "Einladung annehmen" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:144 +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:199 +msgid "Decline invitation" +msgstr "Einladung ablehnen" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:145 +msgid "Accept invitation in new document window" +msgstr "Einladung zu einem neuen Dokumentenfenster annehmen" + +#. We could not create a new desktop; ask the user if she or he wants to +#. replace the current document and accept the invitation, or reject the invitation. +#. TRANSLATORS: %1 is a userid here +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:196 +msgid "" +"A new document window could not be opened for a whiteboard session with %" +"1" +msgstr "" +"Konnte kein neues Dokumentenfenster für eine Whiteboard-Sitzung mit %1 öffnen" + +#. TRANSLATORS: %1 is the peer whom refused our invitation. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:238 +msgid "" +"The user %1 has refused your " +"whiteboard invitation.\n" +"\n" +msgstr "" +"Der Benutzer %1 hat Ihre " +"Einladung abgelehnt.\n" +"\n" + +#. TRANSLATORS: %1 is the peer whom refused our invitation, %2 is our Jabber identity. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:241 +msgid "" +"You are still connected to a Jabber server as %2, and may send an " +"invitation to %1 again, or you may send an invitation to a different " +"user." +msgstr "" +"Sie sind weiterhin als %2 mit einem Jabber-Server verbunden und " +"können %1 erneut einladen, oder auch eine Einladung an einen anderen " +"Benutzer senden." + +#. TRANSLATORS: %1 is the peer whom we tried to contact, but is already in a whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:252 +msgid "" +"The user %1 is already in a " +"whiteboard session.\n" +"\n" +msgstr "" +"Der Benutzer %1 nimmt bereits " +"in einer Whiteboard-Sitzung teil.\n" +"\n" + +#. TRANSLATORS: %1 is the peer whom we tried to contact, but is already in a whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:255 +msgid "" +"You are still connected to a Jabber server as %1, and may send an " +"invitation to a different user." +msgstr "" +"Sie sind weiterhin als %1 mit einem Jabber-Server verbunden und " +"können eine Einladung an einen anderen Benutzer senden." + +#: ../../po/../src/jabber_whiteboard/invitation-confirm-dialog.cpp:26 +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:24 +msgid "_Write session file:" +msgstr "Sitzungsdatei _schreiben:" + +#: ../../po/../src/jabber_whiteboard/message-processors.cpp:145 +#, c-format +msgid "%s has joined the chatroom." +msgstr "%s hat den Chat-Raum betreten." + +#: ../../po/../src/jabber_whiteboard/message-queue.cpp:87 +#, c-format +msgid "%u change in receive queue." +msgid_plural "%u changes in receive queue." +msgstr[0] "%u Änderung in der Empfangswarteschlange." +msgstr[1] "%u Änderungen in der Empfangswarteschlange." + +#: ../../po/../src/jabber_whiteboard/message-queue.cpp:117 +#, c-format +msgid "%u change in send queue." +msgid_plural "%u changes in send queue." +msgstr[0] "%u Änderung in der Sendewarteschlange." +msgstr[1] "%u Änderungen in der Sendewarteschlange." + +#. if ID is NULL, then we have a real problem -- we were not able to find a key +#. nor generate one. The only thing we can really do here is abort, since we have +#. no way to let the other client(s) uniquely identify this object. +#. FIXME: If this indicates a programming bug, then don't request translation with +#. * _(...): it is most useful in untranslated form so that developers may search for +#. * it when someone reports it in a bug report (as we want users to do for all bugs, +#. * as indicated by it being a g_warning string). +#. * +#. * Otherwise, if it is not a programming bug but a network error or a bug in the +#. * remote peer (perhaps running different software) or whatever, then present it in +#. * an alert box, and avoid use of technical jargon `NULL'. +#. +#: ../../po/../src/jabber_whiteboard/message-utilities.cpp:171 +msgid "" +"ID for new object is NULL even after generation and lookup attempts: the new " +"object will NOT be sent, nor will any of its child objects!" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:60 +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:995 +msgid "Select a location and filename" +msgstr "Wählen Sie einen Ort und einen Dateinamen" + +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:62 +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:997 +msgid "Set filename" +msgstr "Dateiname setzen" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:301 +msgid "No SSL certificate was found." +msgstr "Kein SSL-Zertifikat gefunden." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:304 +msgid "The SSL certificate provided by the Jabber server is untrusted." +msgstr "" +"Das SSL-Zertifikat des Jabber-Servers ist nicht als vertrauenswürdig " +"eingestuft." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:307 +msgid "The SSL certificate provided by the Jabber server is expired." +msgstr "Das SSL-Zertifikat des Jabber-Servers ist abgelaufen." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:310 +msgid "" +"The SSL certificate provided by the Jabber server has not been activated." +msgstr "Das SSL-Zertifikat des Jabber-Servers ist nicht aktiviert worden." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:313 +msgid "" +"The SSL certificate provided by the Jabber server contains a hostname that " +"does not match the Jabber server's hostname." +msgstr "" +"Das SSL-Zertifikat des Jabber-Servers enthält einen Hostnamen, der nicht dem " +"Hostnamen des Jabber-Servers entspricht." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:316 +msgid "" +"The SSL certificate provided by the Jabber server contains an invalid " +"fingerprint." +msgstr "" +"Das SSL-Zertifikat des Jabber-Servers enthält einen ungültigen Fingerabdruck." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:319 +msgid "An unknown error occurred while setting up the SSL connection." +msgstr "" +"Ein unbekannter Fehler trat während des Einrichtens der SSL-Verbindung auf." + +# !!! span +#. TRANSLATORS: %1 is the message that describes the specific error that occurred when +#. establishing the SSL connection. +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:325 +msgid "" +"%1\n" +"\n" +"Do you wish to continue connecting to the Jabber server?" +msgstr "" +"%1\n" +"\n" +"Möchten Sie mit der Verbindung zum Jabber-Server fortfahren?" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:328 +msgid "Continue connecting and ignore further errors" +msgstr "Mit Verbinden fortfahren und weitere Fehler ignorieren" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:329 +msgid "Continue connecting, but warn me of further errors" +msgstr "Mit Verbinden fortfahren und bei weiteren Fehlern warnen" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:330 +msgid "Cancel connection" +msgstr "Verbindung abbrechen" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:777 +#, c-format +msgid "Established whiteboard session with %s." +msgstr "Whiteboard-Sitzung mit %s aufgebaut." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:785 +#, c-format +msgid "%s has left the whiteboard session." +msgstr "%s hat die Whiteboard-Sitzung verlassen." + +#. Inform the user +#. TRANSLATORS: %1 is the name of the user that disconnected, %2 is the name of the user whom the disconnected user disconnected from. +#. This message is not used in a chatroom context. +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:790 +msgid "" +"The user %1 has left the " +"whiteboard session.\n" +"\n" +msgstr "" +"Der Benutzer %1 hat die " +"Whiteboard-Sitzung verlassen.\n" +"\n" + +#. TRANSLATORS: %1 and %2 are userids +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:792 +msgid "" +"You are still connected to a Jabber server as %2, and may establish a " +"new session to %1 or a different user." +msgstr "" +"Sie sind weiterhin als %2 mit einem Jabber-Server verbunden und " +"können eine neue Sitzung mit %1 oder einem anderen Benutzer aufbauen." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:988 +msgid "" +"Could not open file %1 for session recording.\n" +"The error encountered was: %2.\n" +"\n" +"You may select a different location to record the session, or you may opt to " +"not record this session." +msgstr "" +"Konnte Datei %1 nicht für das Aufzeichnen der Sitzung öffnen.\n" +"Der Fehler war: %2.\n" +"\n" +"Sie können einen anderen Ort für die Aufzeichnung wählen, oder Sie können " +"die Sitzung ohne Aufzeichnung durchführen." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:990 +msgid "Choose a different location" +msgstr "Einen anderen Ort wählen" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:991 +msgid "Skip session recording" +msgstr "Aufzeichnen der Sitzung überspringen" + +#: ../../po/../src/knot.cpp:673 +msgid "Node or handle drag canceled." +msgstr "Verschieben von Knoten oder Knotenanfassern abgebrochen." + +#: ../../po/../src/libnrtype/FontFactory.cpp:358 +msgid "Ignoring font without family that will crash Pango" +msgstr "" +"Schrift ohne zugehörige Schriftfamilie wird ignoriert, damit Pango nicht " +"abstürzt" + +#: ../../po/../src/main.cpp:395 +msgid "Print the Inkscape version number" +msgstr "Versionsnummer von Inkscape ausgeben" + +#: ../../po/../src/main.cpp:400 +msgid "Do not use X server (only process files from console)" +msgstr "X-Server nicht verwenden (Dateien nur mittels Konsole verarbeiten)" + +#: ../../po/../src/main.cpp:405 +msgid "Try to use X server (even if $DISPLAY is not set)" +msgstr "" +"Versuchen, den X-Server zu verwenden (sogar wenn die Umgebungsvariable " +"»$DISPLAY« nicht gesetzt wurde)" + +#: ../../po/../src/main.cpp:410 +msgid "Open specified document(s) (option string may be excluded)" +msgstr "" +"Angegebene Dokumente öffnen (Optionszeichenkette muss nicht übergeben werden)" + +#: ../../po/../src/main.cpp:411 ../../po/../src/main.cpp:416 +#: ../../po/../src/main.cpp:421 ../../po/../src/main.cpp:483 +#: ../../po/../src/main.cpp:488 ../../po/../src/main.cpp:493 +msgid "FILENAME" +msgstr "DATEINAME" + +#: ../../po/../src/main.cpp:415 +msgid "Print document(s) to specified output file (use '| program' for pipe)" +msgstr "" +"Dokumente in angegebene Ausgabedatei drucken (verwenden Sie »| Programm« zur " +"Weiterleitung)" + +#: ../../po/../src/main.cpp:420 +msgid "Export document to a PNG file" +msgstr "Das Dokument in eine PNG-Datei exportieren" + +#: ../../po/../src/main.cpp:425 +msgid "The resolution used for exporting SVG into bitmap (default 90)" +msgstr "Verwendete Auflösung beim Umwandeln von SVG nach Bitmap (Vorgabe: 90)" + +#: ../../po/../src/main.cpp:426 +msgid "DPI" +msgstr "DPI" + +#: ../../po/../src/main.cpp:430 +msgid "" +"Exported area in SVG user units (default is the canvas; 0,0 is lower-left " +"corner)" +msgstr "" +"Exportierter Bereich in SVG-Benutzereinheiten (Vorgabe: gesamte " +"Zeichenfläche, »0,0« ist die untere linke Ecke)" + +#: ../../po/../src/main.cpp:431 +msgid "x0:y0:x1:y1" +msgstr "X0:Y0:X1:Y1" + +#: ../../po/../src/main.cpp:435 +msgid "Exported area is the entire drawing (not canvas)" +msgstr "" +"Exportierter Bereich ist die gesamte Zeichnung, nicht die Zeichenfläche" + +#: ../../po/../src/main.cpp:440 +msgid "" +"Snap the bitmap export area outwards to the nearest integer values (in SVG " +"user units)" +msgstr "" +"Die Fläche für den Export einer Bitmap nach außen auf die nächsten " +"Ganzzahlen aufrunden (in SVG-Benutzereinheiten)" + +#: ../../po/../src/main.cpp:445 +msgid "The width of exported bitmap in pixels (overrides export-dpi)" +msgstr "Breite der erzeugten Bitmap in Pixeln (überschreibt Export-dpi)" + +#: ../../po/../src/main.cpp:446 +msgid "WIDTH" +msgstr "BREITE" + +#: ../../po/../src/main.cpp:450 +msgid "The height of exported bitmap in pixels (overrides export-dpi)" +msgstr "Höhe der erzeugten Bitmap in Pixeln (überschreibt Export-dpi)" + +#: ../../po/../src/main.cpp:451 +msgid "HEIGHT" +msgstr "HÖHE" + +#: ../../po/../src/main.cpp:455 +msgid "The ID of the object to export (overrides export-area)" +msgstr "" +"ID des zu exportierenden Objektes (hat Vorrang gegenüber Export-Bereich)" + +#: ../../po/../src/main.cpp:456 ../../po/../src/main.cpp:532 +msgid "ID" +msgstr "Kennung" + +#. TRANSLATORS: this means: "Only export the object whose id is given in --export-id". +#. See "man inkscape" for details. +#: ../../po/../src/main.cpp:462 +msgid "" +"Export just the object with export-id, hide all others (only with export-id)" +msgstr "" +"Nur das Objekt mit der angegebenen export-id exportieren, alle anderen " +"auslassen" + +#: ../../po/../src/main.cpp:467 +msgid "Use stored filename and DPI hints when exporting (only with export-id)" +msgstr "" +"Verwende gespeicherten Dateinamen und DPI-Hinweise zum Exportieren (nur mit " +"export-id)" + +#: ../../po/../src/main.cpp:472 +msgid "Background color of exported bitmap (any SVG-supported color string)" +msgstr "" +"Hintergrundfarbe der exportierten Bitmap (jede von SVG unterstützte " +"Farbzeichenkette)" + +#: ../../po/../src/main.cpp:473 +msgid "COLOR" +msgstr "FARBE" + +#: ../../po/../src/main.cpp:477 +msgid "Background opacity of exported bitmap (either 0.0 to 1.0, or 1 to 255)" +msgstr "" +"Hintergrundtransparenz der exportierten Bitmap (0,0 bis 1,0 oder 1 bis 255)" + +#: ../../po/../src/main.cpp:478 +msgid "VALUE" +msgstr "WERT" + +#: ../../po/../src/main.cpp:482 +msgid "Export document to plain SVG file (no sodipodi or inkscape namespaces)" +msgstr "" +"Dokument in einfache SVG-Datei exportieren (keine sodipodi- oder inkscape-" +"Namensräume)" + +#: ../../po/../src/main.cpp:487 +msgid "Export document to a PS file" +msgstr "Das Dokument in eine PS-Datei exportieren" + +#: ../../po/../src/main.cpp:492 +msgid "Export document to an EPS file" +msgstr "Das Dokument in eine EPS-Datei exportieren" + +#: ../../po/../src/main.cpp:497 +msgid "Convert text object to paths on export (EPS)" +msgstr "Textelemente beim EPS-Export in Pfade umwandeln " + +#: ../../po/../src/main.cpp:502 +msgid "Export files with the bounding box set to the page size (EPS)" +msgstr "Exportiere EPS-Dateien mit den Seitengrößen als Umrandungsbox" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:508 +msgid "" +"Query the X coordinate of the drawing or, if specified, of the object with --" +"query-id" +msgstr "" +"Abfragen der X-Koordinate der Zeichnung oder des mit --query-id angegebenen " +"Objektes" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:514 +msgid "" +"Query the Y coordinate of the drawing or, if specified, of the object with --" +"query-id" +msgstr "" +"Abfragen der Y-Koordinate der Zeichnung oder des mit --query-id angegebenen " +"Objektes" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:520 +msgid "" +"Query the width of the drawing or, if specified, of the object with --query-" +"id" +msgstr "" +"Abfragen der Breite der Zeichnung oder des mit --query-id angegebenen " +"Objektes" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:526 +msgid "" +"Query the height of the drawing or, if specified, of the object with --query-" +"id" +msgstr "" +"Abfragen der Höhe der Zeichnung oder des mit --query-id angegebenen Objektes" + +#: ../../po/../src/main.cpp:531 +msgid "The ID of the object whose dimensions are queried" +msgstr "Objekt-ID-Kennung, dessen Abmaße abgefragt werden" + +#. TRANSLATORS: this option makes Inkscape print the name (path) of the extension directory +#: ../../po/../src/main.cpp:537 +msgid "Print out the extension directory and exit" +msgstr "Erweiterungsverzeichnis ausgeben und beenden" + +#: ../../po/../src/main.cpp:542 +msgid "Show given files one-by-one, switch to next on any key/mouse event" +msgstr "" +"Eine angegebene Datei nach der anderen anzeigen, mit beliebigem Tastatur-/" +"Mausereignis weiterschalten" + +#: ../../po/../src/main.cpp:547 +msgid "Use the new Gtkmm GUI interface" +msgstr "Die neue Gtkmm GUI verwenden" + +#: ../../po/../src/main.cpp:552 +msgid "Remove unused definitions from the defs section(s) of the document" +msgstr "Unbenutzte Elemente aus den <defs> des Dokuments entfernen" + +#: ../../po/../src/main.cpp:741 +msgid "" +"[OPTIONS...] [FILE...]\n" +"\n" +"Available options:" +msgstr "" +"[OPTIONEN...] [DATEI...]\n" +"\n" +"Verfügbare Optionen:" + +#: ../../po/../src/menus-skeleton.h:17 +msgid "_New" +msgstr "_Neu" + +#: ../../po/../src/menus-skeleton.h:22 +msgid "Open _Recent" +msgstr "Zuletzt _geöffnete Dateien" + +#: ../../po/../src/menus-skeleton.h:53 +msgid "_Edit" +msgstr "_Bearbeiten" + +#: ../../po/../src/menus-skeleton.h:84 +msgid "_View" +msgstr "_Ansicht" + +#: ../../po/../src/menus-skeleton.h:85 +msgid "_Zoom" +msgstr "Größenfaktor" + +#: ../../po/../src/menus-skeleton.h:102 +msgid "Show/Hide" +msgstr "Anzeigen/Ausblenden" + +#: ../../po/../src/menus-skeleton.h:107 +msgid "_Display mode" +msgstr "" + +#: ../../po/../src/menus-skeleton.h:126 +msgid "_Layer" +msgstr "_Ebene" + +#: ../../po/../src/menus-skeleton.h:143 +msgid "_Object" +msgstr "_Objekt" + +#: ../../po/../src/menus-skeleton.h:165 +msgid "_Path" +msgstr "_Pfad" + +#: ../../po/../src/menus-skeleton.h:188 +msgid "_Text" +msgstr "_Text" + +#: ../../po/../src/menus-skeleton.h:200 +msgid "Effects" +msgstr "Effekte" + +#: ../../po/../src/menus-skeleton.h:207 +msgid "Whiteboa_rd" +msgstr "Whiteboa_rd" + +#: ../../po/../src/menus-skeleton.h:220 +msgid "_Help" +msgstr "_Hilfe" + +#: ../../po/../src/menus-skeleton.h:222 +msgid "Tutorials" +msgstr "Einführungen" + +#: ../../po/../src/node-context.cpp:382 +msgid "" +"Ctrl: toggle node type, snap handle angle, move hor/vert; Ctrl" +"+Alt: move along handles" +msgstr "" +"Strg: Art des Knotens umschalten, Winkel der Anfasser einrasten, nur " +"horizontale/vertikale Verschiebung;Strg+Alt: entlang der Anfasser " +"verschieben" + +#: ../../po/../src/node-context.cpp:383 +msgid "" +"Shift: toggle node selection, disable snapping, rotate both handles" +msgstr "" +"Umschalt: Knotenauswahl umschalten, Einrasten deaktivieren, beide " +"Anfasser rotieren" + +#: ../../po/../src/node-context.cpp:384 +msgid "Alt: lock handle length; Ctrl+Alt: move along handles" +msgstr "" +"Alt: Anfasserlänge fixieren; Strg+Alt: Entlang den Anfassern " +"verschieben\"" + +#: ../../po/../src/nodepath.cpp:1399 ../../po/../src/nodepath.cpp:1411 +#: ../../po/../src/nodepath.cpp:1492 ../../po/../src/nodepath.cpp:1504 +msgid "To join, you must have two endnodes selected." +msgstr "" +"Zum Verbinden der Pfade müssen zwei Endpunkte (Knoten) angewählt sein." + +#: ../../po/../src/nodepath.cpp:1633 ../../po/../src/nodepath.cpp:1647 +msgid "" +"Select two non-endpoint nodes on a path between which to delete " +"segments." +msgstr "" +"Zwei Knoten kein Knoten am Anfang oder Ende müssen auf dem Pfad " +"ausgewählt sein, deren Zwischenraum zu löschen ist." + +#: ../../po/../src/nodepath.cpp:1743 +msgid "Cannot find path between nodes." +msgstr "Kein Pfad zwischen den Knoten." + +#: ../../po/../src/nodepath.cpp:2822 +#, c-format +msgid "" +"Node handle: angle %0.2f°, length %s; with Ctrl to snap " +"angle; with Alt to lock length; with Shift to rotate both " +"handles" +msgstr "" +"Knotenanfasser: Winkel %0.2f°, Länge %s; Strg rastet den " +"Winkel ein; Alt behält den Abstand zum Knoten bei; Umschalt " +"rotiert beide Anfasser" + +#: ../../po/../src/nodepath.cpp:3351 +msgid "" +"Node: drag to edit the path; with Ctrl to snap to horizontal/" +"vertical; with Ctrl+Alt to snap to handles' directions" +msgstr "" +"Knotenanfasser. Ziehen verändert den Kurvenverlauf; Strg " +"rastet horizontal/vertikal ein; Strg+Alt rastet die Anfasser ein" + +#: ../../po/../src/nodepath.cpp:3375 +msgid "" +"Node handle: drag to shape the curve; with Ctrl to snap angle; " +"with Alt to lock length; with Shift to rotate both handles" +msgstr "" +"Knotenanfasser. Ziehen verändert den Kurvenverlauf; Strg " +"rastet den Winkel ein; Alt behält den Abstand zum Knoten bei; " +"Umschalt rotiert beide Anfasser symmetrisch" + +#: ../../po/../src/nodepath.cpp:3399 +msgid "" +"Node handle: drag to shape the curve; with Ctrl to snap angle; " +"with Alt to lock length; with Shift to rotate the opposite " +"handle in sync" +msgstr "" +"Knotenanfasser. Ziehen verändert den Kurvenverlauf; Strg " +"rastet den Winkel ein; Alt behält den Abstand zum Knoten bei; " +"Umschalt rotort beide Anfasser symmetrisch" + +#. TRANSLATORS: "end" is an adjective here (NOT a verb) +#: ../../po/../src/nodepath.cpp:3591 +msgid "end node" +msgstr "Endknoten" + +#. TRANSLATORS: "cusp" means "sharp" (cusp node); see also the Advanced Tutorial +#: ../../po/../src/nodepath.cpp:3596 +msgid "cusp" +msgstr "mit Spitze" + +#. TRANSLATORS: "smooth" is an adjective here +#: ../../po/../src/nodepath.cpp:3599 +msgid "smooth" +msgstr "glatt" + +#: ../../po/../src/nodepath.cpp:3601 +msgid "symmetric" +msgstr "symmetrisch" + +#. TRANSLATORS: "end" is an adjective here (NOT a verb) +#: ../../po/../src/nodepath.cpp:3607 +msgid "end node, handle retracted (drag with Shift to extend)" +msgstr "" +"Anfasser des Endknotens sind eingezogen (Ziehen+Umschalt zieht sie " +"heraus)" + +#: ../../po/../src/nodepath.cpp:3609 +msgid "one handle retracted (drag with Shift to extend)" +msgstr "" +"Ein Anfasser des Endknotens ist eingezogen (Ziehen+Umschalt zieht ihn " +"heraus)" + +#: ../../po/../src/nodepath.cpp:3612 +msgid "both handles retracted (drag with Shift to extend)" +msgstr "" +"Beide Anfasser des Endknotens sind eingezogen (Ziehen+Umschalt zieht " +"sie heraus)" + +#: ../../po/../src/nodepath.cpp:3624 +msgid "Drag nodes or node handles; arrow keys to move nodes" +msgstr "" +"Knoten oder Anfasser ziehen; Pfeiltasten verschieben die Knoten" + +#: ../../po/../src/nodepath.cpp:3625 +msgid "Drag the node or its handles; arrow keys to move the node" +msgstr "" +"Knoten oder seine Anfasser ziehen; Pfeiltasten verschieben den " +"Knoten" + +#: ../../po/../src/nodepath.cpp:3651 ../../po/../src/nodepath.cpp:3663 +msgid "Select a single object to edit its nodes or handles." +msgstr "Einzelnes Objekt zum Bearbeiten der Knoten und Anfasser auswählen." + +#: ../../po/../src/nodepath.cpp:3655 +#, c-format +msgid "" +"0 out of %i node selected. Click, Shift+click, " +"or drag around nodes to select." +msgid_plural "" +"0 out of %i nodes selected. Click, Shift+click, " +"or drag around nodes to select." +msgstr[0] "" +"0 von %i Knoten ausgewählt. Klick, Umschalt+Klick, oder Ziehen wählt Knoten aus." +msgstr[1] "" +"0 von %i Knoten ausgewählt. Klick, Umschalt+Klick, oder Ziehen wählt Knoten aus." + +#: ../../po/../src/nodepath.cpp:3661 +msgid "Drag the handles of the object to modify it." +msgstr "Anfasser des Objektes zum Bearbeiten ziehen" + +#: ../../po/../src/nodepath.cpp:3669 +#, c-format +msgid "%i of %i node selected; %s. %s." +msgid_plural "%i of %i nodes selected; %s. %s." +msgstr[0] "%i von %i Knoten ausgewählt; %s. %s." +msgstr[1] "%i von %i Knoten ausgewählt; %s. %s." + +#: ../../po/../src/nodepath.cpp:3675 +#, c-format +msgid "%i of %i node selected. %s." +msgid_plural "%i of %i nodes selected. %s." +msgstr[0] "%i von %i Knoten ausgewählt. %s." +msgstr[1] "%i von %i Knoten ausgewählt. %s." + +#: ../../po/../src/object-edit.cpp:493 +msgid "" +"Adjust the horizontal rounding radius; with Ctrl to make the " +"vertical radius the same" +msgstr "" +"Radius der horizontalen Rundung anpassen; Strg setzt vertikale " +"und horizontale Rundung gleich" + +#: ../../po/../src/object-edit.cpp:499 +msgid "" +"Adjust the vertical rounding radius; with Ctrl to make the " +"horizontal radius the same" +msgstr "" +"Radius der vertikalen Rundung anpassen; Strg setzt vertikale " +"und horizontale Rundung gleich" + +#: ../../po/../src/object-edit.cpp:506 ../../po/../src/object-edit.cpp:513 +msgid "" +"Adjust the width and height of the rectangle; with Ctrl to " +"lock ratio or stretch in one dimension only" +msgstr "" +"Höhe/Breite des Rechtecks anpassen; Strg behält " +"Seitenverhältnis bei" + +#: ../../po/../src/object-edit.cpp:686 +msgid "Adjust ellipse width, with Ctrl to make circle" +msgstr "" +"Höhe/Breite der Ellipse anpassen; Strg erzeugt einen Kreis" + +#: ../../po/../src/object-edit.cpp:689 +msgid "Adjust ellipse height, with Ctrl to make circle" +msgstr "Höhe der Ellipse anpassen; Strg erzeugt einen Kreis" + +#: ../../po/../src/object-edit.cpp:692 +msgid "" +"Position the start point of the arc or segment; with Ctrl to " +"snap angle; drag inside the ellipse for arc, outside for " +"segment" +msgstr "" +"Anfangspunkt der Bogens oder Kreissegmentes setzen; Strg " +"rastet den Winkel ein; ziehen Innerhalb der Ellipse erzeugt einen " +"Kreisbogen - außerhalb für Kreissegment" + +#: ../../po/../src/object-edit.cpp:695 +msgid "" +"Position the end point of the arc or segment; with Ctrl to " +"snap angle; drag inside the ellipse for arc, outside for " +"segment" +msgstr "" +"Endpunkt des Bogens/Kreissegments setzen; Strg rastet Winkel " +"ein; Ziehen innerhalb der Ellipse erzeugt einen Kreisbogen - " +"außerhalb ein Kreissegment" + +#: ../../po/../src/object-edit.cpp:800 +msgid "" +"Adjust the tip radius of the star or polygon; with Shift to " +"round; with Alt to randomize" +msgstr "" +"Spitzen des Sterns oder Polygons anpassen; Umschalt rundet ab; " +"Alt verändert nach Zufall" + +#: ../../po/../src/object-edit.cpp:803 +msgid "" +"Adjust the base radius of the star; with Ctrl to keep star " +"rays radial (no skew); with Shift to round; with Alt to " +"randomize" +msgstr "" +"Innenradius des Sterns anpassen; Strg erhält radiale " +"Ausrichtung der Spitzen; Umschalt rundet; Alt verändert " +"zufällig" + +#: ../../po/../src/object-edit.cpp:967 +msgid "" +"Roll/unroll the spiral from inside; with Ctrl to snap angle; " +"with Alt to converge/diverge" +msgstr "" +"Spirale von innen einrollen/ausrollen; Winkel mit Strg " +"einrasten; Alt konvergiert/divergiert" + +#: ../../po/../src/object-edit.cpp:969 +msgid "" +"Roll/unroll the spiral from outside; with Ctrl to snap angle; " +"with Shift to scale/rotate" +msgstr "" +"Spirale von außen ausrollen/einrollen; Winkel mit Strg " +"einrasten; Umschalt rotiert/skaliert" + +#: ../../po/../src/object-edit.cpp:1006 +msgid "Adjust the offset distance" +msgstr "Versatz-Abstand anpassen" + +#. TRANSLATORS: This refers to the pattern that's inside the object +#: ../../po/../src/object-edit.cpp:1036 +msgid "Move the pattern fill inside the object" +msgstr "Bewegen des Füllmusters innerhalb des Objektes" + +#: ../../po/../src/object-edit.cpp:1038 +msgid "Scale the pattern fill uniformly" +msgstr "Einheitliches Skalieren des Füllmusters" + +#: ../../po/../src/object-edit.cpp:1040 +msgid "Rotate the pattern fill; with Ctrl to snap angle" +msgstr "Drehen des Füllmusters; Strg rastet Winkel ein" + +#: ../../po/../src/object-edit.cpp:1065 +msgid "Drag to resize the flowed text frame" +msgstr "Ziehen, um die Größe des Fließtext-Rahmens zu ändern" + +#. Item dialog +#: ../../po/../src/object-ui.cpp:106 +msgid "Object _Properties" +msgstr "_Objekteigenschaften..." + +#. Select item +#: ../../po/../src/object-ui.cpp:116 +msgid "_Select This" +msgstr "_Dies auswählen" + +#. Create link +#: ../../po/../src/object-ui.cpp:126 +msgid "_Create Link" +msgstr "Verknüpfung erzeugen" + +#. "Ungroup" +#: ../../po/../src/object-ui.cpp:199 ../../po/../src/verbs.cpp:1931 +msgid "_Ungroup" +msgstr "Gruppierung _aufheben" + +#. Link dialog +#: ../../po/../src/object-ui.cpp:239 +msgid "Link _Properties" +msgstr "Verknüpfungseigenschaften" + +#. Select item +#: ../../po/../src/object-ui.cpp:249 +msgid "_Follow Link" +msgstr "Verknüpfung folgen" + +#. Reset transformations +#: ../../po/../src/object-ui.cpp:254 +msgid "_Remove Link" +msgstr "Verknüpfung entfernen" + +#. Link dialog +#: ../../po/../src/object-ui.cpp:303 +msgid "Image _Properties" +msgstr "Bildeigenschaften" + +#. Item dialog +#: ../../po/../src/object-ui.cpp:344 +msgid "_Fill and Stroke" +msgstr "_Füllung und Kontur" + +#: ../../po/../src/path-chemistry.cpp:58 +msgid "Select at least two objects to combine." +msgstr "Mindestens 2 Objekte zum Kombinieren auswählen." + +#: ../../po/../src/path-chemistry.cpp:65 +msgid "At least one of the objects is not a path, cannot combine." +msgstr "" +"Eines der ausgewählten Objekte ist kein Pfad. Objekte werden nicht " +"kombiniert." + +#: ../../po/../src/path-chemistry.cpp:73 +msgid "" +"You cannot combine objects from different groups or layers." +msgstr "" +"Objekte aus unterschiedlichen Gruppen oder Ebenen können nicht " +"verbunden werden." + +#: ../../po/../src/path-chemistry.cpp:155 +msgid "Select path(s) to break apart." +msgstr "Pfadmuss zum Zerlegen ausgewählt sein." + +#: ../../po/../src/path-chemistry.cpp:231 +msgid "No path(s) to break apart in the selection." +msgstr "Kein Pfad ausgewählt, der zerlegt werden könnte." + +#: ../../po/../src/path-chemistry.cpp:252 +msgid "Select object(s) to convert to path." +msgstr "Objekte auswählen, die zum Pfad umgewandelt werden sollen." + +#: ../../po/../src/path-chemistry.cpp:297 +msgid "No objects to convert to path in the selection." +msgstr "" +"Keine Objekte ausgewählt, die in einen Pfad umgewandelt werden " +"könnten." + +#: ../../po/../src/path-chemistry.cpp:345 +msgid "Select path(s) to reverse." +msgstr "Mindestens einen Pfad zum Umkehren auswählen." + +#: ../../po/../src/path-chemistry.cpp:370 +msgid "No paths to reverse in the selection." +msgstr "Die Auswahl enthält keine Pfade zum Umkehren." + +# !!! make singular and plural forms +#: ../../po/../src/pen-context.cpp:379 ../../po/../src/pencil-context.cpp:233 +msgid "Continuing selected path" +msgstr "Gewählten Pfad verlängern" + +#: ../../po/../src/pen-context.cpp:390 ../../po/../src/pencil-context.cpp:242 +msgid "Creating new path" +msgstr "Erzeuge neue Kurve" + +#: ../../po/../src/pen-context.cpp:394 ../../po/../src/pencil-context.cpp:246 +msgid "Appending to selected path" +msgstr "Zu ausgewähltem Pfad hinzufügen" + +#: ../../po/../src/pen-context.cpp:538 +msgid "Click or click and drag to close and finish the path." +msgstr "" +"Klicken oder Klicken und Ziehen, um den Pfad abzuschließen." + +#: ../../po/../src/pen-context.cpp:548 +msgid "" +"Click or click and drag to continue the path from this point." +msgstr "" +"Klicken oder Klicken und Ziehen, um den Pfad von diesem Punkt " +"aus fortzusetzen." + +#: ../../po/../src/pen-context.cpp:857 +#, c-format +msgid "" +"%s: angle %3.2f°, distance %s; with Ctrl to snap angle, " +"Enter to finish the path" +msgstr "" +"%s: Winkel %3.2f°, Abstand %s; Strg rastet den Winkel " +"ein; Eingabe schließt den Pfad ab" + +#: ../../po/../src/pen-context.cpp:882 +#, c-format +msgid "" +"Curve handle: angle %3.2f°, length %s; with Ctrl to snap " +"angle" +msgstr "" +"Kurvenanfasser: Winkel %3.2f°; Länge %s; Winkel mit Strg " +"einrasten" + +#: ../../po/../src/pen-context.cpp:912 +#, c-format +msgid "" +"%s: angle %3.2f°, length %s; with Ctrl to snap angle, " +"with Shift to move this handle only" +msgstr "" +"%s: Winkel %3.2f°, Länge %s; Strg rastet den Winkel ein; " +"Umschalt bewegt nur diesen Anfasser" + +# !!! +#: ../../po/../src/pen-context.cpp:946 +msgid "Finishing pen" +msgstr "Fertig mit Linienwerkzeug" + +#: ../../po/../src/pencil-context.cpp:320 +msgid "Release here to close and finish the path." +msgstr "Hier loslassen, um den Pfad zu schließen und beenden." + +#: ../../po/../src/pencil-context.cpp:326 +msgid "Drawing a freehand path" +msgstr "Freihandlinien zeichnen" + +#: ../../po/../src/pencil-context.cpp:331 +msgid "Drag to continue the path from this point." +msgstr "Ziehen, um den Pfad von diesem Punkt aus fortzusetzen." + +# !!! +#. Write curves to object +#: ../../po/../src/pencil-context.cpp:390 +msgid "Finishing freehand" +msgstr "Fertig mit Freihandlinien" + +#: ../../po/../src/rect-context.cpp:387 +msgid "" +"Ctrl: make square or integer-ratio rect, lock a rounded corner " +"circular" +msgstr "" +"Strg: Quadrat oder Rechteck mit ganzzahligem Kantenlängenverhältnis, " +"abgerundete Kanten mit einheitlichen Radien" + +#: ../../po/../src/rect-context.cpp:549 +#, c-format +msgid "" +"Rectangle: %s × %s; with Ctrl to make square or integer-" +"ratio rectangle; with Shift to draw around the starting point" +msgstr "" +"Rechteck: %s × %s; Strg erzeugt Quadrat oder ganzzahliges " +"Höhen/Breitenverhältnis; Umschalt - Rechteck vom Zentrum aus zeichnen" + +#: ../../po/../src/select-context.cpp:243 +msgid "Move canceled." +msgstr "Verschieben abgebrochen." + +#: ../../po/../src/select-context.cpp:252 +msgid "Selection canceled." +msgstr "Auswahl abgebrochen." + +#: ../../po/../src/select-context.cpp:642 +msgid "Ctrl: select in groups, move hor/vert" +msgstr "" +"Strg Objekt aus einer Gruppierung auswählen; nur horizontale/" +"vertikale Bewegungen" + +#: ../../po/../src/select-context.cpp:643 +msgid "Shift: toggle select, force rubberband, disable snapping" +msgstr "" +"Umschalt: Auswahl aktivieren/deaktivieren, Gummiband erzwingen, " +"Einrasten ausschalten" + +#: ../../po/../src/select-context.cpp:644 +msgid "Alt: select under, move selected" +msgstr "" +"Alt: Verdeckte Objekte auswählen. Ausgewähltes Objekt verschieben" + +#: ../../po/../src/select-context.cpp:798 +#, fuzzy +msgid "Selected object is not a group. Cannot enter." +msgstr "" +"Ausgewähltes Objekt ist kein Pfad - kann es nicht schrumpfen/" +"ausweiten." + +#: ../../po/../src/select-context.cpp:876 +#, c-format +msgid "" +"Move by %s, %s; with Ctrl to restrict to horizontal/vertical; " +"with Shift to disable snapping" +msgstr "" +"Verschieben um %s, %s; mit Strg nur horizontale/vertikale " +"Verschiebung; Umschalt deaktiviert Einrasten." + +#: ../../po/../src/selection-chemistry.cpp:228 +msgid "Nothing was deleted." +msgstr "Es wurde nichts gelöscht." + +#: ../../po/../src/selection-chemistry.cpp:259 +msgid "Select object(s) to duplicate." +msgstr "Objekte zum Duplizieren auswählen." + +#: ../../po/../src/selection-chemistry.cpp:420 +msgid "Select two or more objects to group." +msgstr "Mindestens 2 Objekte zum Gruppieren auswählen." + +#: ../../po/../src/selection-chemistry.cpp:428 +msgid "Select at least two objects to group." +msgstr "Mindestens 2 Objekte zum Gruppieren auswählen." + +#: ../../po/../src/selection-chemistry.cpp:513 +msgid "Select a group to ungroup." +msgstr "Eine Gruppe auswählen, um die Gruppierung aufzuheben." + +#: ../../po/../src/selection-chemistry.cpp:554 +msgid "No groups to ungroup in the selection." +msgstr "Keine Gruppe zum Aufheben in dieser Auswahl." + +#: ../../po/../src/selection-chemistry.cpp:623 +msgid "Select objects to raise." +msgstr "Objekte zum Anheben auswählen." + +#: ../../po/../src/selection-chemistry.cpp:629 +#: ../../po/../src/selection-chemistry.cpp:681 +#: ../../po/../src/selection-chemistry.cpp:715 +#: ../../po/../src/selection-chemistry.cpp:773 +msgid "" +"You cannot raise/lower objects from different groups or layers." +msgstr "" +"Objekte aus verschiedenen Gruppen oder Ebenen können nicht " +"angehoben oder abgesenkt werden." + +#: ../../po/../src/selection-chemistry.cpp:673 +msgid "Select object(s) to raise to top." +msgstr "" +"Objekte auswählen, die in den Vordergrund angehoben werden sollen." + +#: ../../po/../src/selection-chemistry.cpp:709 +msgid "Select object(s) to lower." +msgstr "Objekte zum Absenken auswählen." + +#: ../../po/../src/selection-chemistry.cpp:765 +msgid "Select object(s) to lower to bottom." +msgstr "" +"Objekte auswählen, die ganz in den Hintergrund abgesenkt werden " +"sollen." + +# !!! just make the menu item insensitive +#: ../../po/../src/selection-chemistry.cpp:806 +msgid "Nothing to undo." +msgstr "Es gibt nichts rückgängig zu machen." + +# # !!! just make the menu item insensitive +#: ../../po/../src/selection-chemistry.cpp:813 +msgid "Nothing to redo." +msgstr "Es gibt nichts wiederherzustellen." + +#: ../../po/../src/selection-chemistry.cpp:969 +msgid "Nothing was copied." +msgstr "Es wurde nichts kopiert." + +#: ../../po/../src/selection-chemistry.cpp:1051 +msgid "Current layer is hidden. Unhide it to be able to paste to it." +msgstr "" +"Aktuelle Ebene ist ausgeblendet. Sichtbar schalten, um dort " +"einzufügen." + +#: ../../po/../src/selection-chemistry.cpp:1055 +msgid "Current layer is locked. Unlock it to be able to paste to it." +msgstr "Aktuelle Ebene ist gesperrt. Entsperren, um dort einzufügen." + +#: ../../po/../src/selection-chemistry.cpp:1068 +#: ../../po/../src/selection-chemistry.cpp:1103 +msgid "Nothing on the clipboard." +msgstr "Es ist nichts in der Zwischenablage." + +#: ../../po/../src/selection-chemistry.cpp:1109 +msgid "Select object(s) to paste style to." +msgstr "Objekte auswählen, um Stil darauf anzuwenden." + +#: ../../po/../src/selection-chemistry.cpp:1128 +msgid "Select object(s) to move to the layer above." +msgstr "" +"Objekte auswählen, welche eine Ebene weiter oben verschoben werden " +"sollen." + +#: ../../po/../src/selection-chemistry.cpp:1146 +msgid "No more layers above." +msgstr "Keine weiteren Ebenen über dieser." + +#: ../../po/../src/selection-chemistry.cpp:1160 +msgid "Select object(s) to move to the layer below." +msgstr "" +"Objekte auswählen, welche in die Ebene darunter verschoben werden " +"sollen." + +#: ../../po/../src/selection-chemistry.cpp:1178 +msgid "No more layers below." +msgstr "Keine weiteren Ebenen unter dieser." + +#: ../../po/../src/selection-chemistry.cpp:1811 +msgid "Select a clone to unlink." +msgstr "Klon auswählen, dessen Verknüpfung aufgehoben wird." + +#: ../../po/../src/selection-chemistry.cpp:1842 +msgid "No clones to unlink in the selection." +msgstr "" +"Keine Klone in der Auswahl, deren Verknüpfung aufgehoben werden kann." + +#: ../../po/../src/selection-chemistry.cpp:1859 +msgid "" +"Select a clone to go to its original. Select a linked offset " +"to go to its source. Select a text on path to go to the path. Select " +"a flowed text to go to its frame." +msgstr "" +"Klon auswählen, um das Original zu finden. Verbundenen Versatz " +"auswählen, um das Ausgangsobjekt zu finden. Textpfad auswählen, um " +"den Ausgangspfad zu finden. Fließtextpfad auswählen, um seinen Rahmen " +"zu finden." + +#: ../../po/../src/selection-chemistry.cpp:1882 +msgid "" +"Cannot find the object to select (orphaned clone, offset, textpath, " +"flowed text?)" +msgstr "" +"Gesuchtes Objekt nicht gefunden - vielleicht ist der Klon, der " +"verbundene Versatz, der Textpfad oder der Fließtext verwaist?" + +#: ../../po/../src/selection-chemistry.cpp:1888 +msgid "" +"The object you're trying to select is not visible (it is in <" +"defs>)" +msgstr "" +"Dieses Objekt kann nicht ausgewählt werden - es ist unsichtbar und " +"befindet sich in <defs>" + +#: ../../po/../src/selection-chemistry.cpp:1915 +msgid "Select object(s) to convert to pattern." +msgstr "" +"Objekte auswählen, die zum Füllmuster umgewandelt werden sollen." + +#: ../../po/../src/selection-chemistry.cpp:2006 +msgid "Select an object with pattern fill to extract objects from." +msgstr "" +"Ein Objekt mit Musterfüllung auswählen, um die Füllung zu extrahieren." + +#: ../../po/../src/selection-chemistry.cpp:2059 +msgid "No pattern fills in the selection." +msgstr "Die Auswahl enthält keine Musterfüllung zum Aufheben." + +#: ../../po/../src/selection-chemistry.cpp:2079 +msgid "Select object(s) to make a bitmap copy." +msgstr "Objekt(e) auswählen, um die Bitmap-Kopie zu erstellen." + +#: ../../po/../src/selection-describer.cpp:37 +msgid "Click selection to toggle scale/rotation handles" +msgstr "" +"Klicken Sie auf die Auswahl, um zwischen Skalieren und Rotieren umzuschalten" + +#. no items +#: ../../po/../src/selection-describer.cpp:39 +msgid "" +"No objects selected. Click, Shift+click, or drag around objects to select." +msgstr "" +"Keine Objekte ausgewählt. Klick, Umschalt+Klick, oder Ziehen um Objekte " +"auszuwählen." + +#: ../../po/../src/selection-describer.cpp:51 +#, c-format +msgid " in layer %s" +msgstr " in Ebene %s" + +#: ../../po/../src/selection-describer.cpp:54 +#, c-format +msgid " in layer %s" +msgstr " in Ebene %s" + +#: ../../po/../src/selection-describer.cpp:66 +msgid "Use Shift+D to look up original" +msgstr "Umschalt+D zum Finden des Originals" + +#: ../../po/../src/selection-describer.cpp:70 +msgid "Use Shift+D to look up path" +msgstr "Umschalt+D zum Finden des Pfades" + +#: ../../po/../src/selection-describer.cpp:74 +msgid "Use Shift+D to look up frame" +msgstr "Umschalt+D zum Finden des Rahmens" + +#: ../../po/../src/selection-describer.cpp:84 +#, c-format +msgid "%i object selected" +msgid_plural "%i objects selected" +msgstr[0] "%i Objekt ausgewählt" +msgstr[1] "%i Objekte ausgewählt" + +#: ../../po/../src/selection-describer.cpp:90 +#, c-format +msgid "%s%s. %s." +msgstr "%s%s. %s." + +#: ../../po/../src/selection-describer.cpp:94 +#, c-format +msgid "%s in %i layer. %s." +msgid_plural "%s in %i layers. %s." +msgstr[0] "%s in %i Ebene. %s." +msgstr[1] "%s in %i Ebenen. %s." + +#: ../../po/../src/seltrans.cpp:498 +msgid "" +"Center of rotation and skewing: drag to reposition; scaling with " +"Shift also uses this center" +msgstr "" +"Mittelpunkt fürs Drehen und Verzerren: Ziehen verschiebt den " +"Mittelpunkt; Skalieren mit Umschalt verwendt diesen Mittelpunkt" + +#: ../../po/../src/seltrans.cpp:514 +msgid "" +"Squeeze or stretch selection; with Ctrl to scale uniformly; " +"with Shift to scale around rotation center" +msgstr "" +"Verzerren der Auswahl; Strg hält Höhen-/Breitenverhältnis " +"konstant; Umschalt skaliert um den Rotationsmittelpunkt" + +#: ../../po/../src/seltrans.cpp:515 +msgid "" +"Scale selection; with Ctrl to scale uniformly; with Shift to scale around rotation center" +msgstr "" +"Skalieren der Auswahl; Strg hält Höhen-/Breitenverhältnis " +"konstant; Umschalt skaliert um den Rotationsmittelpunkt" + +#: ../../po/../src/seltrans.cpp:519 +msgid "" +"Skew selection; with Ctrl to snap angle; with Shift to " +"skew around the opposite side" +msgstr "" +"Scheren der Auswahl; Winkel mit Strg einrasten; Umschalt schert entlang der gegenüberliegenden Seite" + +#: ../../po/../src/seltrans.cpp:520 +msgid "" +"Rotate selection; with Ctrl to snap angle; with Shift " +"to rotate around the opposite corner" +msgstr "" +"Drehen der Auswahl; Winkel mit Strg einrasten; Umschalt " +"dreht entlang der gegenüberliegenden Seite" + +#: ../../po/../src/seltrans.cpp:829 ../../po/../src/seltrans.cpp:909 +#, c-format +msgid "Scale: %0.2f%% x %0.2f%%; with Ctrl to lock ratio" +msgstr "" +"Skalierung: %0.2f%% × %0.2f%%; Höhen-/Breitenverhältnis mit Strg beibehalten" + +#. TRANSLATORS: don't modify the first ";" (it will NOT be displayed as ";" - only the second one will be) +#: ../../po/../src/seltrans.cpp:984 +#, c-format +msgid "Skew: %0.2f°; with Ctrl to snap angle" +msgstr "Scheren: %0.2f °; Winkel mit Strg einrasten" + +#. TRANSLATORS: don't modify the first ";" (it will NOT be displayed as ";" - only the second one will be) +#: ../../po/../src/seltrans.cpp:1035 +#, c-format +msgid "Rotate: %0.2f°; with Ctrl to snap angle" +msgstr "Drehen: %0.2f°; Winkel mit Strg einrasten" + +#: ../../po/../src/seltrans.cpp:1090 +#, c-format +msgid "Move center to %s, %s" +msgstr "Mittelpunkt verschieben nach %s, %s" + +#: ../../po/../src/slideshow.cpp:90 +msgid "Inkscape slideshow" +msgstr "Inkscape-Diashow" + +#: ../../po/../src/sp-anchor.cpp:181 +#, c-format +msgid "Link to %s" +msgstr "Mit %s verknüpfen" + +#: ../../po/../src/sp-anchor.cpp:185 +msgid "Link without URI" +msgstr "Verknüpfung ohne URI" + +#: ../../po/../src/sp-ellipse.cpp:438 ../../po/../src/sp-ellipse.cpp:870 +msgid "Ellipse" +msgstr "Ellipse" + +#: ../../po/../src/sp-ellipse.cpp:583 +msgid "Circle" +msgstr "Kreis" + +#: ../../po/../src/sp-ellipse.cpp:865 +msgid "Segment" +msgstr "Segment" + +#: ../../po/../src/sp-ellipse.cpp:867 +msgid "Arc" +msgstr "Kreisbogen" + +#. TRANSLATORS: "Flow region" is an area where text is allowed to flow +#: ../../po/../src/sp-flowregion.cpp:276 +msgid "Flow region" +msgstr "Textfluß-Bereich" + +#. TRANSLATORS: A region "cut out of" a flow region; text is not allowed to flow inside the +#. * flow excluded region. flowRegionExclude in SVG 1.2: see +#. * http://www.w3.org/TR/2004/WD-SVG12-20041027/flow.html#flowRegion-elem and +#. * http://www.w3.org/TR/2004/WD-SVG12-20041027/flow.html#flowRegionExclude-elem. +#: ../../po/../src/sp-flowregion.cpp:493 +msgid "Flow excluded region" +msgstr "Ausgeschlossenen Bereich umfließen" + +#: ../../po/../src/sp-flowtext.cpp:355 +#, c-format +msgid "Flowed text (%d characters)" +msgstr "Fließtext (%d Zeichen)" + +#: ../../po/../src/sp-flowtext.cpp:357 +#, c-format +msgid "Linked flowed text (%d characters)" +msgstr "Verknüpfter Textfluß (%d Zeichen)" + +#: ../../po/../src/sp-guide.cpp:290 +msgid "vertical guideline" +msgstr "Vertikale Führungslinie" + +#: ../../po/../src/sp-guide.cpp:292 +msgid "horizontal guideline" +msgstr "Horizontale Führungslinie" + +#: ../../po/../src/sp-image.cpp:835 +msgid "embedded" +msgstr "eingebettet" + +#: ../../po/../src/sp-image.cpp:839 +msgid "(null_pointer)" +msgstr "(null_zeiger)" + +#: ../../po/../src/sp-image.cpp:843 +#, c-format +msgid "Image with bad reference: %s" +msgstr "Bild-Objekt mit fehlerhaftem Bezug: %s" + +#: ../../po/../src/sp-image.cpp:844 +#, c-format +msgid "Image %d × %d: %s" +msgstr "Farbbild %d × %d: %s" + +#: ../../po/../src/sp-item-group.cpp:390 +#, c-format +msgid "Group of %d object" +msgid_plural "Group of %d objects" +msgstr[0] "Gruppe von %d Objekt" +msgstr[1] "Gruppe von %d Objekten" + +#: ../../po/../src/sp-item.cpp:720 +msgid "Object" +msgstr "Objekt" + +#: ../../po/../src/sp-line.cpp:202 +msgid "Line" +msgstr "Linie" + +#. TRANSLATORS COMMENT: %s is either "outset" or "inset" depending on sign +#: ../../po/../src/sp-offset.cpp:433 +#, c-format +msgid "Linked offset, %s by %f pt" +msgstr "Verbundener Versatz, %s um %f pt" + +#: ../../po/../src/sp-offset.cpp:434 ../../po/../src/sp-offset.cpp:438 +msgid "outset" +msgstr "ausgeweitet" + +#: ../../po/../src/sp-offset.cpp:434 ../../po/../src/sp-offset.cpp:438 +msgid "inset" +msgstr "geschrumpft" + +#. TRANSLATORS COMMENT: %s is either "outset" or "inset" depending on sign +#: ../../po/../src/sp-offset.cpp:437 +#, c-format +msgid "Dynamic offset, %s by %f pt" +msgstr "Dynamischer Versatz, %s um %f pt" + +#: ../../po/../src/sp-path.cpp:127 +#, c-format +msgid "Path (%i node)" +msgid_plural "Path (%i nodes)" +msgstr[0] "Pfad (%i Knoten)" +msgstr[1] "Pfad (%i Knoten) " + +#: ../../po/../src/sp-polygon.cpp:216 +msgid "Polygon" +msgstr "Polygon:" + +#: ../../po/../src/sp-polyline.cpp:179 +msgid "Polyline" +msgstr "Polylinie" + +#: ../../po/../src/sp-rect.cpp:250 +msgid "Rectangle" +msgstr "Rechteck" + +#. TRANSLATORS: since turn count isn't an integer, please adjust the +#. string as needed to deal with an localized plural forms. +#: ../../po/../src/sp-spiral.cpp:305 +#, c-format +msgid "Spiral with %3f turns" +msgstr "Spirale mit %3f Windung(en)" + +#: ../../po/../src/sp-star.cpp:288 +#, c-format +msgid "Star with %d vertex" +msgid_plural "Star with %d vertices" +msgstr[0] "Stern mit %d Eckpunkt" +msgstr[1] "Stern mit %d Eckpunkten" + +#: ../../po/../src/sp-star.cpp:292 +#, c-format +msgid "Polygon with %d vertex" +msgid_plural "Polygon with %d vertices" +msgstr[0] "Polygon mit %d Eckpunkt" +msgstr[1] "Polygon mit %d Eckpunkten" + +#. TRANSLATORS: For description of font with no name. +#: ../../po/../src/sp-text.cpp:420 +msgid "<no name found>" +msgstr "<kein Name gefunden>" + +#: ../../po/../src/sp-text.cpp:426 +#, c-format +msgid "Text on path (%s, %s)" +msgstr "Text auf Pfad (%s, %s)" + +#: ../../po/../src/sp-text.cpp:427 +#, c-format +msgid "Text (%s, %s)" +msgstr "Text (%s, %s)" + +#. TRANSLATORS: Used for statusbar description for long chains: +#. * "Clone of: Clone of: ... in Layer 1". +#: ../../po/../src/sp-use.cpp:317 +msgid "..." +msgstr "..." + +#: ../../po/../src/sp-use.cpp:325 +#, c-format +msgid "Clone of: %s" +msgstr "Klon von: %s" + +#: ../../po/../src/sp-use.cpp:329 +msgid "Orphaned clone" +msgstr "Verwaister Klon" + +#: ../../po/../src/spiral-context.cpp:355 +msgid "Ctrl: snap angle" +msgstr "Strg: Winkel einrasten" + +#: ../../po/../src/spiral-context.cpp:357 +msgid "Alt: lock spiral radius" +msgstr "Alt: Radius der Spirale einrasten" + +#: ../../po/../src/spiral-context.cpp:469 +#, c-format +msgid "" +"Spiral: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" +"Spirale: Radius %s, Winkel %5g°; Winkel mit Strg einrasten" + +#: ../../po/../src/splivarot.cpp:106 +msgid "Select at least 2 paths to perform a boolean operation." +msgstr "" +"Wählen Sie mindestens 2 Pfade aus, um eine boolesche Operation " +"auszuführen." + +#: ../../po/../src/splivarot.cpp:112 +msgid "" +"Select exactly 2 paths to perform difference, XOR, division, or path " +"cut." +msgstr "" +"Wählen Sie genau 2 Pfade aus, um eine Differenz-, XOR-, Dvisions- " +"oder Pfadbeschneidungsoperation auszuführen." + +#: ../../po/../src/splivarot.cpp:129 ../../po/../src/splivarot.cpp:144 +msgid "" +"Unable to determine the z-order of the objects selected for " +"difference, XOR, division, or path cut." +msgstr "" +"Die Z-Tiefe der ausgewählten Objekte konnte nicht für die Differenz-, " +"XOR-, Division- oder Pfadbeschneidungsoperation ermittelt werden." + +#: ../../po/../src/splivarot.cpp:174 +msgid "" +"One of the objects is not a path, cannot perform boolean operation." +msgstr "" +"Eines der ausgewählten Objekte ist kein Pfad. Boolesche Operation " +"wird nicht ausgeführt." + +#. TRANSLATORS: "to outline" means "to convert stroke to path" +#: ../../po/../src/splivarot.cpp:554 +msgid "Select path(s) to outline." +msgstr "Kontur zum Umwandeln in Pfade auswählen" + +#. TRANSLATORS: "to outline" means "to convert stroke to path" +#: ../../po/../src/splivarot.cpp:748 +msgid "No stroked paths to outline in the selection." +msgstr "" +"In der Auswahl befindet sich keine Kontur, die in einen Pfad " +"umgewandelt werden kann." + +#: ../../po/../src/splivarot.cpp:832 +msgid "Selected object is not a path, cannot inset/outset." +msgstr "" +"Ausgewähltes Objekt ist kein Pfad - kann es nicht schrumpfen/" +"ausweiten." + +#: ../../po/../src/splivarot.cpp:1040 +msgid "Select path(s) to inset/outset." +msgstr "Pfad zum Schrumpfen/Ausweiten auswählen." + +#: ../../po/../src/splivarot.cpp:1257 +msgid "No paths to inset/outset in the selection." +msgstr "Die Auswahl enthält keine Pfade zum Schrumpfen/Vergrößern." + +#: ../../po/../src/splivarot.cpp:1390 +msgid "Select path(s) to simplify." +msgstr "Pfad zum Vereinfachen auswählen." + +#: ../../po/../src/splivarot.cpp:1417 +msgid "No paths to simplify in the selection." +msgstr "Die Auswahl enthält keine Pfade zum Vereinfachen." + +#: ../../po/../src/star-context.cpp:362 +msgid "Ctrl: snap angle; keep rays radial" +msgstr "Strg: Winkel einrasten; Strahlen bleiben radial ausgerichtet" + +#: ../../po/../src/star-context.cpp:470 +#, c-format +msgid "" +"Polygon: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" +"Polygon: Radius %s, Winkel %5g°; Winkel mit Strg einrasten" + +#: ../../po/../src/star-context.cpp:471 +#, c-format +msgid "Star: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "Stern: Radius %s, Winkel %5g°; Winkel mit Strg einrasten" + +#: ../../po/../src/text-chemistry.cpp:90 +msgid "Select a text and a path to put text on path." +msgstr "Einen Text und Pfad zum Erzeugen eines Textpfades auswählen" + +#: ../../po/../src/text-chemistry.cpp:95 +msgid "" +"This text object is already put to a path. Remove it from the path " +"first. Use Shift+D to look up its path." +msgstr "" +"Dieses Textobjekt ist schon einem Pfad zugewiesen. Erst vom Pfad trennen. " +"Umschalt+D zeigt den Pfad an." + +#. rect is the only SPShape which is not yet, and thus SVG forbids us from putting text on it +#: ../../po/../src/text-chemistry.cpp:101 +msgid "" +"You cannot put text on a rectangle in this version. Convert rectangle to " +"path first." +msgstr "" +"Textfluß auf einem Rechteck in dieser Version noch nicht unterstützt. " +"Rechteck vorerst in einen Pfad umwandeln." + +#: ../../po/../src/text-chemistry.cpp:159 +msgid "Select a text on path to remove it from path." +msgstr "Einen Text-Pfad zum Trennen vom Pfad auswählen." + +#: ../../po/../src/text-chemistry.cpp:181 +msgid "No texts-on-paths in the selection." +msgstr "Kein Text-Pfad in der Selektion vorhanden." + +#: ../../po/../src/text-chemistry.cpp:209 +#: ../../po/../src/text-chemistry.cpp:229 +msgid "Select text(s) to remove kerns from." +msgstr "Selektiere Text zum Trennen vom Pfad" + +#: ../../po/../src/text-chemistry.cpp:250 +msgid "" +"Select a text and one or more paths or shapes to flow text " +"into frame." +msgstr "" +"Einen Text und Pfad oder Form zum Erzeugen eines " +"Textflusses auswählen." + +#: ../../po/../src/text-chemistry.cpp:322 +msgid "Select a flowed text to unflow it." +msgstr "Textfluß zum Aufheben auswählen." + +#: ../../po/../src/text-context.cpp:463 +msgid "Click to edit the text, drag to select part of the text." +msgstr "" +"Klicken zum Ändern des Textes, Ziehen, um einen Teil des " +"Textes zu ändern." + +#: ../../po/../src/text-context.cpp:465 +msgid "" +"Click to edit the flowed text, drag to select part of the text." +msgstr "" +"Klicken zum Ändern des Fließtextes, Ziehen, um einen Teil des " +"Textes zu ändern." + +#: ../../po/../src/text-context.cpp:540 +msgid "Non-printable character" +msgstr "Nicht druckbares Zeichen" + +#: ../../po/../src/text-context.cpp:589 +#, c-format +msgid "Unicode: %s: %s" +msgstr "Unicode: %s: %s" + +#: ../../po/../src/text-context.cpp:591 ../../po/../src/text-context.cpp:855 +msgid "Unicode: " +msgstr "Unicode: " + +#: ../../po/../src/text-context.cpp:615 +msgid "Current layer is hidden. Unhide it to be able to add text." +msgstr "" +"Aktuelle Ebene ist verborgen. Sichtbar machen, um Text hinzuzufügen." + +#: ../../po/../src/text-context.cpp:619 +msgid "Current layer is locked. Unlock it to be able to add text." +msgstr "Aktuelle Ebene ist gesperrt. Entsperren, um Text hinzuzufügen." + +#: ../../po/../src/text-context.cpp:673 +#, c-format +msgid "Flowed text frame: %s × %s" +msgstr "Fließtext-Rahmen: %s × %s" + +#: ../../po/../src/text-context.cpp:708 ../../po/../src/text-context.cpp:1464 +msgid "Type text; Enter to start new line." +msgstr "Text schreiben; Eingabe, um eine neue Zeile zu beginnen." + +#: ../../po/../src/text-context.cpp:719 +msgid "Flowed text is created." +msgstr "Fließtext wird erzeugt." + +#: ../../po/../src/text-context.cpp:722 +msgid "" +"The frame is too small for the current font size. Flowed text not " +"created." +msgstr "" +"Der Rahmen ist zu klein für die aktuelle Schriftgröße. Der Fließtext " +"wurde nicht erzeugt." + +#: ../../po/../src/text-context.cpp:841 +msgid "No-break space" +msgstr "Untrennbares Leerzeichen" + +#: ../../po/../src/text-context.cpp:1462 +msgid "Type flowed text; Enter to start new paragraph." +msgstr "" +"Fließtext schreiben; Eingabe, um einen neuen Absatz zu beginnen." + +#: ../../po/../src/text-context.cpp:1472 ../../po/../src/tools-switch.cpp:189 +msgid "" +"Click to select or create text, drag to create flowed text; " +"then type." +msgstr "" +"Zum Auswählen oder Erstellen eines Textobjekts klicken, Ziehen " +"um Fließtext zu erstellen; anschließend schreiben." + +#: ../../po/../src/tools-switch.cpp:141 +msgid "" +"To edit a path, click, Shift+click, or drag around " +"nodes to select them, then drag nodes and handles. Click on an " +"object to select." +msgstr "" +"Um einen Pfad zu bearbeiten auf Knoten Klicken, Umschalt+Klick " +"oder Ziehen. Ein ganzes Objekt wird mit den Kontrollanfassern " +"bearbeitet." + +#: ../../po/../src/tools-switch.cpp:147 +msgid "" +"Drag to create a rectangle. Drag controls to round corners and " +"resize. Click to select." +msgstr "" +"Ziehen erstellt ein Rechteck. Anfasser ziehen rundet Ecken ab " +"und ändert Größe. Klick wählt aus." + +#: ../../po/../src/tools-switch.cpp:153 +msgid "" +"Drag to create an ellipse. Drag controls to make an arc or " +"segment. Click to select." +msgstr "" +"Ziehen erstellt eine Ellipse. Anfasser ziehen erzeugt Bogen " +"oder Kreissegment. Klicken wählt aus." + +#: ../../po/../src/tools-switch.cpp:159 +msgid "" +"Drag to create a star. Drag controls to edit the star shape. " +"Click to select." +msgstr "" +"Ziehen erstellt einen Stern. Anfasser ziehen bearbeitet Form. " +"Klicken wählt aus." + +#: ../../po/../src/tools-switch.cpp:165 +msgid "" +"Drag to create a spiral. Drag controls to edit the spiral " +"shape. Click to select." +msgstr "" +"Ziehen erstellt eine Spirale. Anfasser ziehen bearbeitet die " +"Form. Klicken wählt aus." + +#: ../../po/../src/tools-switch.cpp:171 +msgid "" +"Drag to create a freehand line. Start drawing with Shift to " +"append to selected path." +msgstr "" +"Ziehen erzeugt eine Freihandlinie. Umschalt, um den " +"ausgewählten Pfad weiterzuzeichnen." + +#: ../../po/../src/tools-switch.cpp:177 +msgid "" +"Click or click and drag to start a path; with Shift to " +"append to selected path." +msgstr "" +"Klicken oder Klicken und Ziehen, beginnt einen Pfad; " +"Umschalt, um den ausgewählten Pfad weiterzuzeichnen." + +#: ../../po/../src/tools-switch.cpp:183 +msgid "" +"Drag to paint a calligraphic stroke. Left/right arrow " +"keys adjust width, up/down adjust angle." +msgstr "" +"Ziehen, um kalligraphische Linien zu zeichnen. Pfeiltasten links/rechts verändern die Breite, hoch/runter verändern " +"Winkel." + +#: ../../po/../src/tools-switch.cpp:195 +msgid "" +"Drag or double click to create a gradient on selected objects, " +"drag handles to adjust gradients." +msgstr "" +"Ziehen oder Doppelklicken erzeugt Farbverlauf für gewählte " +"Objekte, Anfasser ziehen verändert Farbverlauf." + +#: ../../po/../src/tools-switch.cpp:201 +msgid "" +"Click or drag around an area to zoom in, Shift+click to " +"zoom out." +msgstr "" +"Klicken oder Rechteck aufziehen vergrößert die Ansicht, " +"Umschalt+Klick verkleinert." + +#: ../../po/../src/tools-switch.cpp:213 +msgid "Click and drag between shapes to create a connector." +msgstr "" +"Klicken und Ziehen zwischen Formen erzeugt einen Objektverbinder." + +#: ../../po/../src/trace/potrace/inkscape-potrace.cpp:553 +#: ../../po/../src/trace/potrace/inkscape-potrace.cpp:654 +#, c-format +msgid "Trace: %d. %ld nodes" +msgstr "Vektorisieren: %d. %ld Knoten" + +#: ../../po/../src/trace/trace.cpp:53 ../../po/../src/trace/trace.cpp:62 +#: ../../po/../src/trace/trace.cpp:70 +msgid "Select an image to trace" +msgstr "Bild zum Vektorisieren auswählen." + +#: ../../po/../src/trace/trace.cpp:133 +msgid "Trace: No active document" +msgstr "Vektorisieren: Kein Dokument aktiv" + +#: ../../po/../src/trace/trace.cpp:154 +msgid "Trace: Image has no bitmap data" +msgstr "Vektorisieren: Bild enthält keine Pixelinformation" + +#: ../../po/../src/trace/trace.cpp:267 +#, c-format +msgid "Trace: Done. %ld nodes created" +msgstr "Vektorisieren abgeschlossen: %ld Knoten erzeugt" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:59 ../../po/../src/verbs.cpp:2212 +msgid "About Inkscape" +msgstr "Informationen über Inkscape" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:66 +msgid "_Splash" +msgstr "" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:68 +#, fuzzy +msgid "_Authors" +msgstr "Autoren" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:69 +#, fuzzy +msgid "_Translators" +msgstr "Übersetzer" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:70 +msgid "_License" +msgstr "Nutzungsbedingungen - _Lizenz" + +#. TRANSLATORS: This is the filename of the `About Inkscape' picture in +#. the `screens' directory. Thus the translation of "about.svg" should be +#. the filename of its translated version, e.g. about.zh.svg for Chinese. +#. +#. N.B. about.svg changes once per release. (We should probably rename +#. the original to about-0.40.svg etc. as soon as we have a translation. +#. If we do so, then add an item to release-checklist saying that the +#. string here should be changed.) +#. FIXME? INKSCAPE_SCREENSDIR and "about.svg" are in UTF-8, not the +#. native filename encoding... and the filename passed to sp_document_new +#. should be in UTF-*8.. +#: ../../po/../src/ui/dialog/aboutbox.cpp:114 +msgid "about.svg" +msgstr "about.svg" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:464 +msgid "Minimum horizontal gap (in px units) between bounding boxes" +msgstr "" + +#. TRANSLATORS: Horizontal gap +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:466 +#: ../../po/../src/widgets/toolbox.cpp:1556 +msgid "H:" +msgstr "H:" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:474 +msgid "Minimum vertical gap (in px units) between bounding boxes" +msgstr "" + +#. TRANSLATORS: Vertical gap +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:476 +msgid "V:" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:734 +msgid "Align" +msgstr "Ausrichten" + +# CHECK +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:735 +msgid "Distribute" +msgstr "Abstände ausgleichen" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:736 +msgid "Remove overlaps" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:737 +msgid "Nodes" +msgstr "Knoten" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:742 +msgid "Relative to: " +msgstr "Relativ zu: " + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:747 +msgid "Align right sides of objects to left side of anchor" +msgstr "" +"Rechte Seite der ausgerichteten Objekte an linker Seite der Verankerung" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:750 +msgid "Align left sides" +msgstr "Linksbündig ausrichten" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:753 +msgid "Center on vertical axis" +msgstr "Vertikal zentrieren" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:756 +msgid "Align right sides" +msgstr "Rechtsbündig ausrichten" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:759 +msgid "Align left sides of objects to right side of anchor" +msgstr "" +"Linke Kanten der Objekte an der rechten Seite der Verankerung ausrichten" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:762 +msgid "Align bottoms of objects to top of anchor" +msgstr "Unterseiten der Objekte an Oberseite der Verankerung ausrichten" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:765 +msgid "Align tops" +msgstr "An Oberkanten ausrichten" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:768 +msgid "Center on horizontal axis" +msgstr "Horizontal zentrieren" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:771 +msgid "Align bottoms" +msgstr "An Unterkante ausrichten" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:774 +msgid "Align tops of objects to bottom of anchor" +msgstr "Oberseiten der Objekte an Unterseite der Verankerung ausrichten" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:779 +msgid "Align baseline anchors of texts vertically" +msgstr "Grundlinien der Textelemente vertikal ausrichten" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:782 +msgid "Align baseline anchors of texts horizontally" +msgstr "Grundlinien der Textelemente horizontal ausrichten" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:787 +msgid "Make horizontal gaps between objects equal" +msgstr "Horizontale Abstände zwischen Objekten ausgleichen" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:791 +msgid "Distribute left sides equidistantly" +msgstr "Abstände zwischen linken Seiten der Objekte ausgleichen" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:794 +msgid "Distribute centers equidistantly horizontally" +msgstr "Horizontale Abstände zwischen Objektmittelpunkten ausgleichen" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:797 +msgid "Distribute right sides equidistantly" +msgstr "Abstände zwischen rechten Seiten der Objekte ausgleichen" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:801 +msgid "Make vertical gaps between objects equal" +msgstr "Vertikale Abstände zwischen Objekten ausgleichen" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:805 +msgid "Distribute tops equidistantly" +msgstr "Oberkanten der Objekte gleichmäßig anordnen" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:808 +msgid "Distribute centers equidistantly vertically" +msgstr "Vertikale Abstände zwischen Objektmittelpunkten ausgleichen" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:811 +msgid "Distribute bottoms equidistantly" +msgstr "Abstände zwischen Unterkanten ausgleichen" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:816 +msgid "Distribute baseline anchors of texts horizontally" +msgstr "Grundlinien von Textelementen horizontal gleichmässig anordnen" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:819 +msgid "Distribute baseline anchors of texts vertically" +msgstr "Grundlinien von Textelementen vertikal gleichmässig anordnen" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:824 +msgid "Randomize centers in both dimensions" +msgstr "Mittelpunkte von Objekten zufällig horizontal und vertikal verteilen" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:827 +msgid "Unclump objects: try to equalize edge-to-edge distances" +msgstr "Objekte entklumpen: Versuche die Zwischenabstände anzugleichen" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:832 +msgid "" +"Move objects as little as possible so that their bounding boxes do not " +"overlap" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:837 +msgid "Align selected nodes horizontally" +msgstr "Ausgewählte Knoten horizontal ausrichten" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:840 +msgid "Align selected nodes vertically" +msgstr "Ausgewählte Knoten vertikal ausrichten" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:843 +msgid "Distribute selected nodes horizontally" +msgstr "Ausgewählte Knoten horizontal gleichmässig anordnen" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:846 +msgid "Distribute selected nodes vertically" +msgstr "Ausgewählte Knoten vertikal gleichmässig anordnen" + +#. Rest of the widgetry +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:851 +msgid "Last selected" +msgstr "Zuletzt gewählt" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:852 +msgid "First selected" +msgstr "Zuerst gewählt" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:853 +msgid "Biggest item" +msgstr "Größtes Objekt" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:854 +msgid "Smallest item" +msgstr "Kleinstes Objekt" + +# not sure here -cm- +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:856 +#: ../../po/../src/widgets/desktop-widget.cpp:1065 +msgid "Drawing" +msgstr "Zeichnung" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:91 +#, fuzzy +msgid "Metadata 1" +msgstr "Metadaten" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:92 +#, fuzzy +msgid "Metadata 2" +msgstr "Metadaten" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:187 +#, fuzzy +msgid "X coordinate of grid origin" +msgstr "Vertikale Coordinate der Auswahl " + +#: ../../po/../src/ui/dialog/document-preferences.cpp:189 +#, fuzzy +msgid "Y coordinate of grid origin" +msgstr "Vertikale Coordinate der Auswahl " + +#: ../../po/../src/ui/dialog/document-preferences.cpp:191 +#, fuzzy +msgid "Distance of vertical grid lines" +msgstr "Vertikale Führungslinie" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:193 +#, fuzzy +msgid "Distance of horizontal grid lines" +msgstr "Horizontale Führungslinie" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:197 +msgid "Max. snapping distance from grid" +msgstr "" + +#: ../../po/../src/ui/dialog/export.cpp:34 +msgid "Export" +msgstr "Exportieren" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:36 +msgid "Fill" +msgstr "Füllung" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:37 +msgid "Stroke Paint" +msgstr "Farbe der Konturlinie" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:38 +msgid "Stroke Style" +msgstr "Muster der Konturlinie" + +#: ../../po/../src/ui/dialog/find.cpp:34 +msgid "Find" +msgstr "_Suchen" + +#: ../../po/../src/ui/dialog/memory.cpp:96 +msgid "Heap" +msgstr "Heap" + +#: ../../po/../src/ui/dialog/memory.cpp:97 +msgid "In Use" +msgstr "Benutzt" + +#. TRANSLATORS: "Slack" refers to memory which is in the heap but currently unused. +#. More typical usage is to call this memory "free" rather than "slack". +#: ../../po/../src/ui/dialog/memory.cpp:100 +msgid "Slack" +msgstr "Ungenutzt; reserviert" + +#: ../../po/../src/ui/dialog/memory.cpp:101 +msgid "Total" +msgstr "Gesamt" + +#: ../../po/../src/ui/dialog/memory.cpp:141 +#: ../../po/../src/ui/dialog/memory.cpp:147 +#: ../../po/../src/ui/dialog/memory.cpp:154 +#: ../../po/../src/ui/dialog/memory.cpp:186 +msgid "Unknown" +msgstr "Unbekannt" + +#: ../../po/../src/ui/dialog/memory.cpp:167 +msgid "Combined" +msgstr "Kombiniert" + +#: ../../po/../src/ui/dialog/memory.cpp:209 +msgid "Recalculate" +msgstr "Neu berechnen" + +#: ../../po/../src/ui/dialog/messages.cpp:74 +msgid "Ready." +msgstr "Bereit" + +#: ../../po/../src/ui/dialog/messages.cpp:75 +msgid "" +"Enable log display by setting dialogs.debug 'redirect' attribute to 1 in " +"preferences.xml" +msgstr "" +"Log-Anzeige ermöglichen durchs Setzen des Attributes redirect von " +"dialogs.debug auf 1 in preferences.xml" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:184 +msgid "_Execute Python" +msgstr "Python ausführen" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:186 +msgid "_Execute Perl" +msgstr "Perl ausführen" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:195 +msgid "Script" +msgstr "Skript" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:205 +msgid "Output" +msgstr "Ausgabe" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:215 +msgid "Errors" +msgstr "Fehler" + +#. Dialog organization +#: ../../po/../src/ui/dialog/session-player.cpp:73 +msgid "Session file" +msgstr "Sitzungsdatei" + +#: ../../po/../src/ui/dialog/session-player.cpp:74 +msgid "Playback controls" +msgstr "Wiedergabesteuerung" + +#: ../../po/../src/ui/dialog/session-player.cpp:75 +msgid "Message information" +msgstr "Meldungsinformation" + +#. Active session file display +#. fixme: Does this mean the active file for the session, or the file for the active session? +#. Please indicate which with a TRANSLATORS comment. +#: ../../po/../src/ui/dialog/session-player.cpp:85 +msgid "Active session file:" +msgstr "Aktive Sitzungsdatei:" + +#: ../../po/../src/ui/dialog/session-player.cpp:86 +msgid "Delay (milliseconds):" +msgstr "Verzögerung (Millisekunden):" + +#. Unload/load buttons +#: ../../po/../src/ui/dialog/session-player.cpp:94 +msgid "Close file" +msgstr "Datei schließen" + +#: ../../po/../src/ui/dialog/session-player.cpp:95 +msgid "Open new file" +msgstr "Neue Datei öffnen" + +#: ../../po/../src/ui/dialog/session-player.cpp:96 +msgid "Set delay" +msgstr "Verzögerung setzen" + +#: ../../po/../src/ui/dialog/session-player.cpp:138 +msgid "Rewind" +msgstr "Zurückspulen" + +#: ../../po/../src/ui/dialog/session-player.cpp:139 +msgid "Go back one change" +msgstr "Eine Änderung zurück" + +#: ../../po/../src/ui/dialog/session-player.cpp:140 +msgid "Pause" +msgstr "Pause" + +#: ../../po/../src/ui/dialog/session-player.cpp:141 +msgid "Go forward one change" +msgstr "Eine Änderung vor" + +#: ../../po/../src/ui/dialog/session-player.cpp:142 +msgid "Play" +msgstr "Abspielen" + +#: ../../po/../src/ui/dialog/session-player.cpp:177 +#: ../../po/../src/verbs.cpp:1573 +msgid "Open session file" +msgstr "Sitzungsdatei öffnen" + +#. ##Set up the Potrace panel +#. #### brightness #### +#. #### Multiple scanning#### +#. ----Hbox1 +#: ../../po/../src/ui/dialog/tracedialog.cpp:345 +#: ../../po/../src/ui/dialog/tracedialog.cpp:428 +msgid "Brightness" +msgstr "Helligkeitswert" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:348 +msgid "Trace by a given brightness level" +msgstr "Abhängig vom angegebenen Helligkeitswert Nachzeichnen" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:355 +msgid "Brightness cutoff for black/white" +msgstr "Helligkeitsschwellwerte für Scharz/Weiß" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:362 +msgid "Image Brightness" +msgstr "Bildhelligkeit" + +#. #### canny edge detection #### +#. TRANSLATORS: "Canny" is the name of the inventor of this edge detection method +#: ../../po/../src/ui/dialog/tracedialog.cpp:369 +msgid "Optimal Edge Detection (Canny)" +msgstr "Optimierte Kantenerkennung (Canny)" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:372 +msgid "Trace with edge detection by J. Canny's algorithm" +msgstr "Mit Kantenerkennung nachzeichnen (Algorithmus von J. Canny)" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:388 +msgid "Brightness cutoff for adjacent pixels (determines edge thickness)" +msgstr "" +"Schwellwert des Helligkeitswerts bei angrenzenden Pixeln (bestimmt " +"Kantenbreite)" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:395 +msgid "Edge Detection" +msgstr "Kantenerkennung" + +#. #### quantization #### +#. TRANSLATORS: Color Quantization: the process of reducing the number of colors +#. in an image by selecting an optimized set of representative colors and then +#. re-applying this reduced set to the original image. +#: ../../po/../src/ui/dialog/tracedialog.cpp:404 +msgid "Color Quantization" +msgstr "Farbquantisierung" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:407 +msgid "Trace along the boundaries of reduced colors" +msgstr "Nachzeichnen entlang der reduzierten Farbbegrenzungen" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:414 +msgid "The number of reduced colors" +msgstr "Anzahl der reduzierten Farben" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:416 +msgid "Colors:" +msgstr "Farben" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:421 +msgid "Quantization / Reduction" +msgstr "Quantisierung/Reduktion" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:431 +msgid "Trace the given number of brightness levels" +msgstr "Angegebene Anzahl von Helligkeitsstufen nachzeichnen" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:438 +msgid "Scans:" +msgstr "Scandurchgänge:" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:440 +msgid "The desired number of scans" +msgstr "Gewünschte Anzahl der Scandurchgänge" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:448 +msgid "Trace the given number of reduced colors" +msgstr "Nachzeichnen auf diese Anzahl Farben beschränken" + +#. ---Hbox3 +#: ../../po/../src/ui/dialog/tracedialog.cpp:454 +msgid "Monochrome" +msgstr "Monochrom" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:457 +msgid "Same as Color, but convert result to grayscale" +msgstr "Gleicher Farbwert, aber Ergebnis nach Graustufen konvertieren" + +#. TRANSLATORS: "Stack" is a verb here +#: ../../po/../src/ui/dialog/tracedialog.cpp:460 +msgid "Stack" +msgstr "Stapeln" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:463 +msgid "" +"Stack scans vertically (no gaps) or tile horizontally (usually with gaps)" +msgstr "" +"Scans vertikal (ohne Zwischenräume) oder horizontal (mit Zwischenräumen) " +"kacheln" + +#. TRANSLATORS: "Smooth" is a verb here +#: ../../po/../src/ui/dialog/tracedialog.cpp:466 +msgid "Smooth" +msgstr "Glätten" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:469 +msgid "Apply Gaussian blur to the bitmap before tracing" +msgstr "Gaußschen Weichzeichner vor dem Nachzeichnen anwenden" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:473 +msgid "Multiple Scanning" +msgstr "Mehrfaches Scannen" + +#. #### Preview #### +#: ../../po/../src/ui/dialog/tracedialog.cpp:479 +#: ../../po/../src/ui/dialog/tracedialog.cpp:489 +msgid "Preview" +msgstr "Vorschau" + +#. do not expand +#: ../../po/../src/ui/dialog/tracedialog.cpp:483 +msgid "Preview the result without actual tracing" +msgstr "Vorschau des Ergebnisses ohne Nachzeichnen" + +#. #### swap black and white #### +#: ../../po/../src/ui/dialog/tracedialog.cpp:495 +msgid "Invert" +msgstr "Invertieren" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:499 +msgid "Invert black and white regions for single traces" +msgstr "Schwarz/Weiße Bereiche beim einfachen Nachzeichnen invertieren" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:503 +msgid "Thanks to Peter Selinger, http://potrace.sourceforge.net" +msgstr "Dank an Peter Selinger, http://potrace.sourceforge.net" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:506 +msgid "Credits" +msgstr "Mitwirkende" + +# CHECK +#. done +#. TRANSLATORS: Potrace is an application for transforming bitmaps into +#. vector graphics (http://potrace.sourceforge.net/) +#: ../../po/../src/ui/dialog/tracedialog.cpp:514 +msgid "Potrace" +msgstr "Potrace: Vektorisieren" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:527 +msgid "Abort a trace in progress" +msgstr "Nachzeichnen abbrechen" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:531 +msgid "Execute the trace" +msgstr "Nachzeichnen ausführen" + +#: ../../po/../src/ui/dialog/transformation.cpp:80 +#: ../../po/../src/ui/dialog/transformation.cpp:90 +#, fuzzy +msgid "_Horizontal" +msgstr "Horizontal" + +#: ../../po/../src/ui/dialog/transformation.cpp:80 +msgid "Horizontal displacement (relative) or position (absolute)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:82 +#: ../../po/../src/ui/dialog/transformation.cpp:92 +#, fuzzy +msgid "_Vertical" +msgstr "Vertikal" + +#: ../../po/../src/ui/dialog/transformation.cpp:82 +msgid "Vertical displacement (relative) or position (absolute)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:84 +#, fuzzy +msgid "_Width" +msgstr "_Breite:" + +#: ../../po/../src/ui/dialog/transformation.cpp:84 +msgid "Horizontal size increment (absolute or percentage)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:86 +#, fuzzy +msgid "_Height" +msgstr "Höhe" + +#: ../../po/../src/ui/dialog/transformation.cpp:86 +msgid "Vertical size increment (absolute or percentage)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:88 +#, fuzzy +msgid "A_ngle" +msgstr "Winkel:" + +#: ../../po/../src/ui/dialog/transformation.cpp:88 +#, fuzzy +msgid "Rotation angle (positive = counterclockwise)" +msgstr "Die gewählten Objekte um 90 Grad gegen den Uhrzeigersinn drehen" + +#: ../../po/../src/ui/dialog/transformation.cpp:90 +msgid "" +"Horizontal skew angle (positive = counterclockwise), or absolute " +"displacement, or percentage displacement" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:92 +msgid "" +"Vertical skew angle (positive = counterclockwise), or absolute displacement, " +"or percentage displacement" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:95 +#, fuzzy +msgid "Transformation matrix element A" +msgstr "Abbildungsmatrix" + +#: ../../po/../src/ui/dialog/transformation.cpp:96 +#, fuzzy +msgid "Transformation matrix element B" +msgstr "Abbildungsmatrix" + +#: ../../po/../src/ui/dialog/transformation.cpp:97 +#, fuzzy +msgid "Transformation matrix element C" +msgstr "Abbildungsmatrix" + +#: ../../po/../src/ui/dialog/transformation.cpp:98 +#, fuzzy +msgid "Transformation matrix element D" +msgstr "Abbildungsmatrix" + +#: ../../po/../src/ui/dialog/transformation.cpp:99 +#, fuzzy +msgid "Transformation matrix element E" +msgstr "Abbildungsmatrix" + +#: ../../po/../src/ui/dialog/transformation.cpp:100 +#, fuzzy +msgid "Transformation matrix element F" +msgstr "Abbildungsmatrix" + +#: ../../po/../src/ui/dialog/transformation.cpp:102 +#, fuzzy +msgid "Rela_tive move" +msgstr "Relative Bewegung" + +#: ../../po/../src/ui/dialog/transformation.cpp:102 +msgid "" +"Add the specified relative displacement to the current position; otherwise, " +"edit the current absolute position directly" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:103 +msgid "Scale proportionally" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:103 +msgid "Preserve the width/height ratio of the scaled objects" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:104 +msgid "Apply to each _object separately" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:104 +msgid "" +"Apply the scale/rotate/skew to each selected object separately; otherwise, " +"transform the selection as a whole" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:105 +#, fuzzy +msgid "Edit c_urrent matrix" +msgstr "Die aktuelle Ebene anheben" + +#: ../../po/../src/ui/dialog/transformation.cpp:105 +msgid "" +"Edit the current transform= matrix; otherwise, post-multiply transform= by " +"this matrix" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:115 +#, fuzzy +msgid "_Move" +msgstr "Verschieben" + +#: ../../po/../src/ui/dialog/transformation.cpp:118 +#, fuzzy +msgid "_Scale" +msgstr "Maßstab" + +#: ../../po/../src/ui/dialog/transformation.cpp:121 +#, fuzzy +msgid "_Rotate" +msgstr "Drehen" + +#: ../../po/../src/ui/dialog/transformation.cpp:124 +#, fuzzy +msgid "Ske_w" +msgstr "Scheren" + +#: ../../po/../src/ui/dialog/transformation.cpp:127 +msgid "Matri_x" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:141 +msgid "Reset the values on the current tab to defaults" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:148 +#, fuzzy +msgid "Apply transformation to selection" +msgstr "Transformation auf Objekt anwenden" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:43 +msgid "_Use SSL" +msgstr "SSL _verwenden" + +#. Construct dialog interface +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:68 +msgid "_Server:" +msgstr "_Server:" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:69 +msgid "_Username:" +msgstr "_Benutzername:" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:70 +msgid "_Password:" +msgstr "_Passwort:" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:71 +msgid "P_ort:" +msgstr "P_ort:" + +#. Buttons +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:99 +msgid "Connect" +msgstr "Verbinden" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:126 +msgid "Establishing connection to Jabber server %1 as user %2" +msgstr "Verbindung zu Jabber-Server %1 als Benutzer %2 aufbauen" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:131 +msgid "Failed to establish connection to Jabber server %1" +msgstr "Verbindung zu Jabber-Server %1 fehlgeschlagen" + +# http://de.wikipedia.org/wiki/Authentisierung +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:136 +msgid "Authentication failed on Jabber server %1 as %2" +msgstr "" +"Authentifizierung gegenüber Jabber-Server %1 als %2 " +"fehlgeschlagen" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:141 +msgid "SSL initialization failed when connecting to Jabber server %1" +msgstr "" +"Bei der Verbindung zu Jabber-Server %1 ist die SSL-Initialisierung " +"fehlgeschlagen" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:147 +msgid "Connected to Jabber server %1 as %2" +msgstr "Mit Jabber-Server %1 als %2 verbunden" + +#. Construct labels +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:75 +msgid "Chatroom _name:" +msgstr "_Name des Chat-Raums:" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:76 +msgid "Chatroom _server:" +msgstr "Chat-Raum-_Server:" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:77 +msgid "Chatroom _password:" +msgstr "Chat-Raum-_Passwort:" + +# !!! what is a "handle" here? +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:78 +msgid "Chatroom _handle:" +msgstr "Sp_itzname im Chat-Raum:" + +#. Button setup and callback registration +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:97 +msgid "Connect to chatroom" +msgstr "Mit Chat-Raum verbinden" + +# !!! +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:132 +msgid "Synchronizing with chatroom %1@%2 using the handle %3" +msgstr "Synchronisiere mit Chat-Raum %1@%2 mit Spitznamen %3" + +#. Construct dialog interface +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:78 +msgid "_User's Jabber ID:" +msgstr "Jabber-ID des _Benutzers:" + +#. Buttons +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:82 +msgid "_Invite user" +msgstr "Benutzer _einladen" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:83 +msgid "_Cancel" +msgstr "_Abbrechen" + +# !!! check +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:94 +msgid "Buddy List" +msgstr "Liste Ihrer Freunde" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:170 +msgid "Sending whiteboard invitation to %1" +msgstr "Sende Whiteboard-Einladung zu %1" + +#. FIXME: strings are replaced by placeholders, NOT to be translated until the code is enabled +#. See http://sourceforge.net/mailarchive/message.php?msg_id=11746016 for details +#. File menu +#. Edit menu +#. View menu +#. Layer menu +#. Object menu +#. Path menu +#. add(Gtk::StockItem(CLEANUP, _("PLACEHOLDER, do not translate"))); (using Gtk::Stock::CLEAR) +#. Text menu +#. About menu +#. Tools toolbox +#. Select Tool controls +#. Node Tool controls +#. Calligraphy Tool controls +#. Session playback controls +#: ../../po/../src/ui/stock-items.cpp:34 ../../po/../src/ui/stock-items.cpp:35 +#: ../../po/../src/ui/stock-items.cpp:36 ../../po/../src/ui/stock-items.cpp:37 +#: ../../po/../src/ui/stock-items.cpp:38 ../../po/../src/ui/stock-items.cpp:39 +#: ../../po/../src/ui/stock-items.cpp:40 ../../po/../src/ui/stock-items.cpp:41 +#: ../../po/../src/ui/stock-items.cpp:42 ../../po/../src/ui/stock-items.cpp:43 +#: ../../po/../src/ui/stock-items.cpp:46 ../../po/../src/ui/stock-items.cpp:47 +#: ../../po/../src/ui/stock-items.cpp:48 ../../po/../src/ui/stock-items.cpp:49 +#: ../../po/../src/ui/stock-items.cpp:50 ../../po/../src/ui/stock-items.cpp:51 +#: ../../po/../src/ui/stock-items.cpp:52 ../../po/../src/ui/stock-items.cpp:53 +#: ../../po/../src/ui/stock-items.cpp:54 ../../po/../src/ui/stock-items.cpp:55 +#: ../../po/../src/ui/stock-items.cpp:56 ../../po/../src/ui/stock-items.cpp:57 +#: ../../po/../src/ui/stock-items.cpp:58 ../../po/../src/ui/stock-items.cpp:59 +#: ../../po/../src/ui/stock-items.cpp:62 ../../po/../src/ui/stock-items.cpp:63 +#: ../../po/../src/ui/stock-items.cpp:64 ../../po/../src/ui/stock-items.cpp:65 +#: ../../po/../src/ui/stock-items.cpp:66 ../../po/../src/ui/stock-items.cpp:67 +#: ../../po/../src/ui/stock-items.cpp:68 ../../po/../src/ui/stock-items.cpp:69 +#: ../../po/../src/ui/stock-items.cpp:70 ../../po/../src/ui/stock-items.cpp:71 +#: ../../po/../src/ui/stock-items.cpp:72 ../../po/../src/ui/stock-items.cpp:73 +#: ../../po/../src/ui/stock-items.cpp:74 ../../po/../src/ui/stock-items.cpp:75 +#: ../../po/../src/ui/stock-items.cpp:76 ../../po/../src/ui/stock-items.cpp:77 +#: ../../po/../src/ui/stock-items.cpp:78 ../../po/../src/ui/stock-items.cpp:79 +#: ../../po/../src/ui/stock-items.cpp:80 ../../po/../src/ui/stock-items.cpp:81 +#: ../../po/../src/ui/stock-items.cpp:82 ../../po/../src/ui/stock-items.cpp:83 +#: ../../po/../src/ui/stock-items.cpp:84 ../../po/../src/ui/stock-items.cpp:85 +#: ../../po/../src/ui/stock-items.cpp:86 ../../po/../src/ui/stock-items.cpp:87 +#: ../../po/../src/ui/stock-items.cpp:88 ../../po/../src/ui/stock-items.cpp:89 +#: ../../po/../src/ui/stock-items.cpp:92 ../../po/../src/ui/stock-items.cpp:93 +#: ../../po/../src/ui/stock-items.cpp:94 ../../po/../src/ui/stock-items.cpp:95 +#: ../../po/../src/ui/stock-items.cpp:96 ../../po/../src/ui/stock-items.cpp:97 +#: ../../po/../src/ui/stock-items.cpp:98 ../../po/../src/ui/stock-items.cpp:99 +#: ../../po/../src/ui/stock-items.cpp:100 +#: ../../po/../src/ui/stock-items.cpp:101 +#: ../../po/../src/ui/stock-items.cpp:102 +#: ../../po/../src/ui/stock-items.cpp:103 +#: ../../po/../src/ui/stock-items.cpp:104 +#: ../../po/../src/ui/stock-items.cpp:105 +#: ../../po/../src/ui/stock-items.cpp:108 +#: ../../po/../src/ui/stock-items.cpp:109 +#: ../../po/../src/ui/stock-items.cpp:110 +#: ../../po/../src/ui/stock-items.cpp:111 +#: ../../po/../src/ui/stock-items.cpp:112 +#: ../../po/../src/ui/stock-items.cpp:113 +#: ../../po/../src/ui/stock-items.cpp:114 +#: ../../po/../src/ui/stock-items.cpp:115 +#: ../../po/../src/ui/stock-items.cpp:116 +#: ../../po/../src/ui/stock-items.cpp:117 +#: ../../po/../src/ui/stock-items.cpp:118 +#: ../../po/../src/ui/stock-items.cpp:119 +#: ../../po/../src/ui/stock-items.cpp:120 +#: ../../po/../src/ui/stock-items.cpp:121 +#: ../../po/../src/ui/stock-items.cpp:122 +#: ../../po/../src/ui/stock-items.cpp:123 +#: ../../po/../src/ui/stock-items.cpp:124 +#: ../../po/../src/ui/stock-items.cpp:125 +#: ../../po/../src/ui/stock-items.cpp:126 +#: ../../po/../src/ui/stock-items.cpp:127 +#: ../../po/../src/ui/stock-items.cpp:130 +#: ../../po/../src/ui/stock-items.cpp:131 +#: ../../po/../src/ui/stock-items.cpp:132 +#: ../../po/../src/ui/stock-items.cpp:133 +#: ../../po/../src/ui/stock-items.cpp:134 +#: ../../po/../src/ui/stock-items.cpp:135 +#: ../../po/../src/ui/stock-items.cpp:136 +#: ../../po/../src/ui/stock-items.cpp:137 +#: ../../po/../src/ui/stock-items.cpp:138 +#: ../../po/../src/ui/stock-items.cpp:139 +#: ../../po/../src/ui/stock-items.cpp:140 +#: ../../po/../src/ui/stock-items.cpp:141 +#: ../../po/../src/ui/stock-items.cpp:142 +#: ../../po/../src/ui/stock-items.cpp:143 +#: ../../po/../src/ui/stock-items.cpp:144 +#: ../../po/../src/ui/stock-items.cpp:145 +#: ../../po/../src/ui/stock-items.cpp:146 +#: ../../po/../src/ui/stock-items.cpp:150 +#: ../../po/../src/ui/stock-items.cpp:151 +#: ../../po/../src/ui/stock-items.cpp:152 +#: ../../po/../src/ui/stock-items.cpp:153 +#: ../../po/../src/ui/stock-items.cpp:156 +#: ../../po/../src/ui/stock-items.cpp:157 +#: ../../po/../src/ui/stock-items.cpp:158 +#: ../../po/../src/ui/stock-items.cpp:161 +#: ../../po/../src/ui/stock-items.cpp:162 +#: ../../po/../src/ui/stock-items.cpp:163 +#: ../../po/../src/ui/stock-items.cpp:164 +#: ../../po/../src/ui/stock-items.cpp:165 +#: ../../po/../src/ui/stock-items.cpp:166 +#: ../../po/../src/ui/stock-items.cpp:167 +#: ../../po/../src/ui/stock-items.cpp:168 +#: ../../po/../src/ui/stock-items.cpp:169 +#: ../../po/../src/ui/stock-items.cpp:170 +#: ../../po/../src/ui/stock-items.cpp:171 +#: ../../po/../src/ui/stock-items.cpp:172 +#: ../../po/../src/ui/stock-items.cpp:175 +#: ../../po/../src/ui/stock-items.cpp:176 +#: ../../po/../src/ui/stock-items.cpp:177 +#: ../../po/../src/ui/stock-items.cpp:178 +#: ../../po/../src/ui/stock-items.cpp:181 +#: ../../po/../src/ui/stock-items.cpp:182 +#: ../../po/../src/ui/stock-items.cpp:183 +#: ../../po/../src/ui/stock-items.cpp:184 +#: ../../po/../src/ui/stock-items.cpp:185 +#: ../../po/../src/ui/stock-items.cpp:186 +#: ../../po/../src/ui/stock-items.cpp:187 +#: ../../po/../src/ui/stock-items.cpp:188 +#: ../../po/../src/ui/stock-items.cpp:189 +#: ../../po/../src/ui/stock-items.cpp:190 +#: ../../po/../src/ui/stock-items.cpp:191 +#: ../../po/../src/ui/stock-items.cpp:194 +#: ../../po/../src/ui/stock-items.cpp:195 +#: ../../po/../src/ui/stock-items.cpp:198 +#: ../../po/../src/ui/stock-items.cpp:199 +#: ../../po/../src/ui/stock-items.cpp:200 +#: ../../po/../src/ui/stock-items.cpp:201 +#: ../../po/../src/ui/stock-items.cpp:202 +msgid "PLACEHOLDER, do not translate" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:88 +msgid "small" +msgstr "klein" + +#: ../../po/../src/ui/widget/panel.cpp:89 +msgid "medium" +msgstr "mittel" + +#: ../../po/../src/ui/widget/panel.cpp:90 +msgid "large" +msgstr "groß" + +#: ../../po/../src/ui/widget/panel.cpp:91 +msgid "huge" +msgstr "sehr groß" + +#: ../../po/../src/ui/widget/panel.cpp:106 +msgid "List" +msgstr "Liste" + +#: ../../po/../src/ui/widget/selected-style.cpp:67 +msgid "F:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:68 +#, fuzzy +msgid "S:" +msgstr "_S" + +#: ../../po/../src/ui/widget/selected-style.cpp:69 +msgid "O:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:95 +msgid "N/A" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:98 +#: ../../po/../src/ui/widget/selected-style.cpp:712 +#, fuzzy +msgid "Nothing selected" +msgstr "Ausgewähltes Objekt ist ein Klon" + +#: ../../po/../src/ui/widget/selected-style.cpp:103 +msgid "No fill" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:103 +#, fuzzy +msgid "No stroke" +msgstr " (Konturlinie)" + +#: ../../po/../src/ui/widget/selected-style.cpp:105 +#: ../../po/../src/widgets/paint-selector.cpp:190 +msgid "Pattern" +msgstr "Muster" + +#: ../../po/../src/ui/widget/selected-style.cpp:108 +#: ../../po/../src/widgets/paint-selector.cpp:885 +msgid "Pattern fill" +msgstr "Füllmuster" + +#: ../../po/../src/ui/widget/selected-style.cpp:108 +#, fuzzy +msgid "Pattern stroke" +msgstr "Versatz des Musters" + +#: ../../po/../src/ui/widget/selected-style.cpp:110 +#, fuzzy +msgid "L Gradient" +msgstr "Farbverlauf" + +#: ../../po/../src/ui/widget/selected-style.cpp:113 +#, fuzzy +msgid "Linear gradient fill" +msgstr "Linearer Farbverlauf" + +#: ../../po/../src/ui/widget/selected-style.cpp:113 +#, fuzzy +msgid "Linear gradient stroke" +msgstr "Linearer Farbverlauf" + +#: ../../po/../src/ui/widget/selected-style.cpp:115 +#, fuzzy +msgid "R Gradient" +msgstr "Farbverlauf" + +#: ../../po/../src/ui/widget/selected-style.cpp:118 +#, fuzzy +msgid "Radial gradient fill" +msgstr "Radialer Farbverlauf" + +#: ../../po/../src/ui/widget/selected-style.cpp:118 +#, fuzzy +msgid "Radial gradient stroke" +msgstr "Radialer Farbverlauf" + +#: ../../po/../src/ui/widget/selected-style.cpp:120 +#, fuzzy +msgid "Different" +msgstr "_Differenz" + +#: ../../po/../src/ui/widget/selected-style.cpp:123 +#, fuzzy +msgid "Different fills" +msgstr "_Differenz" + +#: ../../po/../src/ui/widget/selected-style.cpp:123 +#, fuzzy +msgid "Different strokes" +msgstr "_Differenz" + +#: ../../po/../src/ui/widget/selected-style.cpp:125 +#, fuzzy +msgid "Unset" +msgstr "geschrumpft" + +#. TRANSLATORS COMMENT: unset is a verb here +#: ../../po/../src/ui/widget/selected-style.cpp:128 +#: ../../po/../src/ui/widget/selected-style.cpp:182 +#, fuzzy +msgid "Unset fill" +msgstr "Kachelung aufheben" + +#: ../../po/../src/ui/widget/selected-style.cpp:128 +#: ../../po/../src/ui/widget/selected-style.cpp:182 +#, fuzzy +msgid "Unset stroke" +msgstr " (Konturlinie)" + +#: ../../po/../src/ui/widget/selected-style.cpp:131 +#, fuzzy +msgid "Flat color fill" +msgstr "Einfache Farbe" + +#: ../../po/../src/ui/widget/selected-style.cpp:131 +#, fuzzy +msgid "Flat color stroke" +msgstr "Einfache Farbe" + +#. TRANSLATOR COMMENT: A means "Averaged" +#: ../../po/../src/ui/widget/selected-style.cpp:134 +#, fuzzy +msgid "A" +msgstr "_A" + +#: ../../po/../src/ui/widget/selected-style.cpp:137 +#, fuzzy +msgid "Fill is averaged over selected objects" +msgstr "Exklusiv-Oder-Operation auf gewählte Objekte" + +#: ../../po/../src/ui/widget/selected-style.cpp:137 +#, fuzzy +msgid "Stroke is averaged over selected objects" +msgstr "Objektverbinder weichen den ausgewählten Objekten aus" + +#. TRANSLATOR COMMENT: M means "Multiple" +#: ../../po/../src/ui/widget/selected-style.cpp:140 +#, fuzzy +msgid "M" +msgstr "_M" + +#: ../../po/../src/ui/widget/selected-style.cpp:143 +#, fuzzy +msgid "Multiple selected objects have the same fill" +msgstr "Ausgewählte Objekte vertikal umkehren" + +#: ../../po/../src/ui/widget/selected-style.cpp:143 +#, fuzzy +msgid "Multiple selected objects have the same stroke" +msgstr "Ausgewählte Objekte vertikal umkehren" + +#: ../../po/../src/ui/widget/selected-style.cpp:145 +#, fuzzy +msgid "Edit fill..." +msgstr "Bearbeiten..." + +#: ../../po/../src/ui/widget/selected-style.cpp:145 +#, fuzzy +msgid "Edit stroke..." +msgstr "Bearbeiten..." + +#: ../../po/../src/ui/widget/selected-style.cpp:149 +#, fuzzy +msgid "Last set color" +msgstr "Einfache Farbe" + +#: ../../po/../src/ui/widget/selected-style.cpp:153 +#, fuzzy +msgid "Last selected color" +msgstr "Zuletzt gewählt" + +#: ../../po/../src/ui/widget/selected-style.cpp:157 +#, fuzzy +msgid "White" +msgstr "Whiteboa_rd" + +#: ../../po/../src/ui/widget/selected-style.cpp:161 +#: ../../po/../src/widgets/sp-color-scales.cpp:461 +#: ../../po/../src/widgets/sp-color-scales.cpp:462 +msgid "Black" +msgstr "Schwarz" + +#: ../../po/../src/ui/widget/selected-style.cpp:165 +#, fuzzy +msgid "Copy color" +msgstr "Zwischenfarbe" + +#: ../../po/../src/ui/widget/selected-style.cpp:169 +#, fuzzy +msgid "Paste color" +msgstr "Einfache Farbe" + +#: ../../po/../src/ui/widget/selected-style.cpp:173 +#, fuzzy +msgid "Swap fill and stroke" +msgstr "_Füllung und Linie" + +#: ../../po/../src/ui/widget/selected-style.cpp:177 +msgid "Make fill opaque" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:177 +msgid "Make stroke opaque" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:186 +#, fuzzy +msgid "Remove fill" +msgstr " Entfernen" + +#: ../../po/../src/ui/widget/selected-style.cpp:186 +#, fuzzy +msgid "Remove stroke" +msgstr "Verknüpfung entfernen" + +#: ../../po/../src/ui/widget/selected-style.cpp:718 +#, fuzzy +msgid "Master opacity" +msgstr "Gesamtdeckkraft" + +#: ../../po/../src/ui/widget/selected-style.cpp:744 +msgid "0 (transparent)" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:768 +msgid "1.0 (opaque)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1046 +msgid "Moved to next layer." +msgstr "Auf nächste Ebene verschoben." + +#: ../../po/../src/verbs.cpp:1048 +msgid "Cannot move past last layer." +msgstr "Kann nicht hinter letzte Ebene verschieben." + +#: ../../po/../src/verbs.cpp:1057 +msgid "Moved to previous layer." +msgstr "Zur vorherigen Ebene verschoben" + +#: ../../po/../src/verbs.cpp:1059 +msgid "Cannot move past first layer." +msgstr "Kann nicht vor erste Ebene verschieben." + +#: ../../po/../src/verbs.cpp:1076 ../../po/../src/verbs.cpp:1150 +msgid "No current layer." +msgstr "Keine aktuelle Ebene." + +#: ../../po/../src/verbs.cpp:1105 +#, c-format +msgid "Raised layer %s." +msgstr "Ebene %s angehoben." + +#: ../../po/../src/verbs.cpp:1109 +#, c-format +msgid "Lowered layer %s." +msgstr "Ebene %s abgesenkt." + +#: ../../po/../src/verbs.cpp:1118 +msgid "Cannot move layer any further." +msgstr "Kann Ebene nicht weiter verschieben." + +#. TRANSLATORS: this means "The layer has been deleted." +#: ../../po/../src/verbs.cpp:1148 +msgid "Deleted layer." +msgstr "Ebene wurde gelöscht." + +#: ../../po/../src/verbs.cpp:1544 +msgid "" +"You need to connect to a Jabber server before sharing a document with " +"another user." +msgstr "" +"Sie müssen sich mit einem Jabber-Server verbinden, bevor Sie ein Dokument " +"gemeinsam mit einem anderen Benutzer bearbeiten können." + +#: ../../po/../src/verbs.cpp:1559 +msgid "" +"You need to connect to a Jabber server before sharing a document with a " +"chatroom." +msgstr "" +"Sie müssen sich mit einem Jabber-Server verbinden, bevor Sie ein Dokument " +"gemeinsam in einem Chat-Raum bearbeiten können." + +#: ../../po/../src/verbs.cpp:1569 +msgid "XML node tracker has not been initialized; nothing to dump" +msgstr "" +"Das XML-Knotenprotokoll war nicht initialisiert; nichts zum Ausgeben " +"vorhanden" + +#. TRANSLATORS: If you have translated the keys.svg file to your language, then +#. translate this string as "keys.LANG.svg" (where LANG is your language code); +#. otherwise leave as "keys.svg". +#: ../../po/../src/verbs.cpp:1631 +msgid "keys.svg" +msgstr "" + +#. TRANSLATORS: If you have translated the tutorial-basic.svg file to your language, +#. then translate this string as "tutorial-basic.LANG.svg" (where LANG is your language +#. code); otherwise leave as "tutorial-basic.svg". +#: ../../po/../src/verbs.cpp:1667 +msgid "tutorial-basic.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1671 +msgid "tutorial-shapes.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1675 +msgid "tutorial-advanced.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1679 +msgid "tutorial-tracing.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1683 +msgid "tutorial-calligraphy.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1687 +msgid "tutorial-elements.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1691 +msgid "tutorial-tips.svg" +msgstr "" + +#: ../../po/../src/verbs.cpp:1842 +msgid "Does nothing" +msgstr "Hat keine Funktion" + +#. File +#: ../../po/../src/verbs.cpp:1845 +msgid "Default" +msgstr "Vorgabe" + +#: ../../po/../src/verbs.cpp:1845 +msgid "Create new document from default template" +msgstr "Ein neues Dokument nach der Standardvorlage anlegen" + +#: ../../po/../src/verbs.cpp:1847 +msgid "_Open..." +msgstr "Ö_ffnen..." + +#: ../../po/../src/verbs.cpp:1848 +msgid "Open existing document" +msgstr "Ein bestehendes Dokument öffnen" + +#: ../../po/../src/verbs.cpp:1849 +msgid "Re_vert" +msgstr "_Zurücksetzen" + +#: ../../po/../src/verbs.cpp:1850 +msgid "Revert to the last saved version of document (changes will be lost)" +msgstr "" +"Das Dokument auf die zuletzt gespeicherte Version zurücksetzen (Änderungen " +"gehen verloren)" + +#: ../../po/../src/verbs.cpp:1851 +msgid "_Save" +msgstr "_Speichern" + +#: ../../po/../src/verbs.cpp:1851 +msgid "Save document" +msgstr "Das Dokument speichern" + +#: ../../po/../src/verbs.cpp:1853 +msgid "Save _As..." +msgstr "Speichern _unter..." + +#: ../../po/../src/verbs.cpp:1854 +msgid "Save document under new name" +msgstr "Das momentan geöffnete Dokument unter einem anderen Namen speichern" + +#: ../../po/../src/verbs.cpp:1855 +msgid "_Print..." +msgstr "_Drucken..." + +#: ../../po/../src/verbs.cpp:1855 +msgid "Print document" +msgstr "Das Dokument drucken" + +#. TRANSLATORS: "Vacuum Defs" means "Clean up defs" (so as to remove unused definitions) +#: ../../po/../src/verbs.cpp:1858 +msgid "Vac_uum Defs" +msgstr "Leere Defs aufräumen" + +#: ../../po/../src/verbs.cpp:1858 +msgid "Remove unused predefined items from the <defs> of the document" +msgstr "" +"Unbenutzte vordefinierte Elemente aus den <defs> des Dokuments " +"entfernen" + +#: ../../po/../src/verbs.cpp:1860 +msgid "Print _Direct" +msgstr "D_irekt drucken..." + +#: ../../po/../src/verbs.cpp:1861 +msgid "Print directly without prompting to a file or pipe" +msgstr "Ohne Rückfrage direkt in eine Datei oder Weiterleitung drucken" + +#: ../../po/../src/verbs.cpp:1862 +msgid "Print Previe_w" +msgstr "Druck_vorschau" + +#: ../../po/../src/verbs.cpp:1863 +msgid "Preview document printout" +msgstr "Vorschau auf Dokumentenausdruck" + +#: ../../po/../src/verbs.cpp:1864 +msgid "_Import..." +msgstr "_Importieren..." + +#: ../../po/../src/verbs.cpp:1865 +msgid "Import bitmap or SVG image into document" +msgstr "Eine Bitmap oder SVG-Bild in das Dokument importieren" + +#: ../../po/../src/verbs.cpp:1866 +msgid "_Export Bitmap..." +msgstr "Bitmap _exportieren..." + +#: ../../po/../src/verbs.cpp:1867 +msgid "Export document or selection as a bitmap image" +msgstr "Das Dokument oder die Auswahl als Bitmap exportieren" + +#: ../../po/../src/verbs.cpp:1868 +msgid "N_ext Window" +msgstr "Nä_chstes Fenster" + +#: ../../po/../src/verbs.cpp:1869 +msgid "Switch to the next document window" +msgstr "Zum nächsten Dokumentenfenster umschalten" + +#: ../../po/../src/verbs.cpp:1870 +msgid "P_revious Window" +msgstr "Vor_heriges Fenster" + +#: ../../po/../src/verbs.cpp:1871 +msgid "Switch to the previous document window" +msgstr "Zum vorherigen Dokumentenfenster umschalten" + +#: ../../po/../src/verbs.cpp:1872 +msgid "_Close" +msgstr "S_chließen" + +#: ../../po/../src/verbs.cpp:1873 +msgid "Close window" +msgstr "Fenster schließen" + +#: ../../po/../src/verbs.cpp:1874 +msgid "_Quit" +msgstr "_Beenden" + +#: ../../po/../src/verbs.cpp:1874 +msgid "Quit Inkscape" +msgstr "Inkscape verlassen" + +#. Edit +#: ../../po/../src/verbs.cpp:1877 +msgid "_Undo" +msgstr "_Rückgängig" + +#: ../../po/../src/verbs.cpp:1877 +msgid "Undo last action" +msgstr "Die letzte Bearbeitung rückgängig machen" + +# !!! "Wiederholen" wird evtl. spaeter fuer "repeat" gebraucht +#: ../../po/../src/verbs.cpp:1879 +msgid "_Redo" +msgstr "_Wiederherstellen" + +# !!! Abiword just says "Letzten Befehl wiederholen" +#: ../../po/../src/verbs.cpp:1880 +msgid "Do again last undone action" +msgstr "Eine rückgängig gemachte Bearbeitung erneut durchführen" + +#: ../../po/../src/verbs.cpp:1881 +msgid "Cu_t" +msgstr "A_usschneiden" + +#: ../../po/../src/verbs.cpp:1882 +msgid "Cut selection to clipboard" +msgstr "Die gewählten Objekte in die Zwischenablage verschieben" + +#: ../../po/../src/verbs.cpp:1883 +msgid "_Copy" +msgstr "_Kopieren" + +#: ../../po/../src/verbs.cpp:1884 +msgid "Copy selection to clipboard" +msgstr "Die gewählten Objekte in die Zwischenablage kopieren" + +#: ../../po/../src/verbs.cpp:1885 +msgid "_Paste" +msgstr "E_infügen" + +#: ../../po/../src/verbs.cpp:1886 +msgid "Paste objects from clipboard to mouse point" +msgstr "Objekte aus der Zwischenablage an der Mausposition einfügen" + +#: ../../po/../src/verbs.cpp:1887 +msgid "Paste _Style" +msgstr "Stil an_wenden" + +#: ../../po/../src/verbs.cpp:1888 +msgid "Apply style of the copied object to selection" +msgstr "Stil des kopierten Objekts auf Auswahl anwenden" + +# !!! translation is a bit clumsy... +#: ../../po/../src/verbs.cpp:1889 +msgid "Paste _In Place" +msgstr "An Ori_ginalposition einfügen" + +#: ../../po/../src/verbs.cpp:1890 +msgid "Paste objects from clipboard to the original location" +msgstr "Objekte aus der Zwischenablage an ihrer Originalposition einfügen" + +#: ../../po/../src/verbs.cpp:1891 +msgid "_Delete" +msgstr "_Löschen" + +#: ../../po/../src/verbs.cpp:1892 +msgid "Delete selection" +msgstr "Auswahl löschen" + +#: ../../po/../src/verbs.cpp:1893 +msgid "Duplic_ate" +msgstr "Dupli_zieren" + +#: ../../po/../src/verbs.cpp:1894 +msgid "Duplicate selected objects" +msgstr "Gewählte Objekte duplizieren" + +#: ../../po/../src/verbs.cpp:1895 +msgid "Clo_ne" +msgstr "_Klonen" + +#: ../../po/../src/verbs.cpp:1896 +msgid "Create a clone of selected object (a copy linked to the original)" +msgstr "" +"Einen Klon des gewählten Objekts erstellen (eine Kopie, die mit dem Original " +"verbunden ist)" + +#: ../../po/../src/verbs.cpp:1897 +msgid "Unlin_k Clone" +msgstr "Klonverbindung auf_trennen" + +#: ../../po/../src/verbs.cpp:1898 +msgid "Cut the clone's link to its original" +msgstr "Die Verbindung des Klons zu seinem Original auftrennen" + +#: ../../po/../src/verbs.cpp:1899 +msgid "Select _Original" +msgstr "_Original auswählen" + +#: ../../po/../src/verbs.cpp:1900 +msgid "Select the object to which the clone is linked" +msgstr "Objekt auswählen, mit dem der Klon verbunden ist" + +#. TRANSLATORS: Convert selection to a rectangle with tiled pattern fill +#: ../../po/../src/verbs.cpp:1902 +msgid "O_bjects to Pattern" +msgstr "_Objekte in Füllmuster umwandeln" + +#: ../../po/../src/verbs.cpp:1903 +msgid "Convert selection to a rectangle with tiled pattern fill" +msgstr "Die Auswahl zu einem Rechteck mit gekacheltem Füllmuster umwandeln" + +#. TRANSLATORS: Extract objects from a tiled pattern fill +#: ../../po/../src/verbs.cpp:1905 +msgid "Pattern to Ob_jects" +msgstr "Füllmuster in Ob_jekte umwandeln" + +#: ../../po/../src/verbs.cpp:1906 +msgid "Extract objects from a tiled pattern fill" +msgstr "Objekte aus einem gekacheltem Füllmuster extrahieren" + +#: ../../po/../src/verbs.cpp:1907 +msgid "Clea_r All" +msgstr "Alles l_eeren" + +#: ../../po/../src/verbs.cpp:1908 +msgid "Delete all objects from document" +msgstr "Alle Objekte aus dem Dokument löschen" + +#: ../../po/../src/verbs.cpp:1909 +msgid "Select Al_l" +msgstr "_Alles auswählen" + +#: ../../po/../src/verbs.cpp:1910 +msgid "Select all objects or all nodes" +msgstr "Alle Objekte oder alle Knoten im Dokument auswählen" + +#: ../../po/../src/verbs.cpp:1911 +msgid "Select All in All La_yers" +msgstr "Alles in allen Ebenen auswählen" + +#: ../../po/../src/verbs.cpp:1912 +msgid "Select all objects in all visible and unlocked layers" +msgstr "Alle Objekte in allen sichtbaren entsperrten Ebenen auswählen" + +#: ../../po/../src/verbs.cpp:1913 +msgid "In_vert Selection" +msgstr "Auswahl umkehren" + +#: ../../po/../src/verbs.cpp:1914 +msgid "Invert selection (unselect what is selected and select everything else)" +msgstr "" +"Auswahl invertieren (alle ausgewählten Objekte deselektieren und alle " +"anderen auswählen)" + +#: ../../po/../src/verbs.cpp:1915 +msgid "Invert in All Layers" +msgstr "In allen Ebenen invertieren" + +#: ../../po/../src/verbs.cpp:1916 +msgid "Invert selection in all visible and unlocked layers" +msgstr "Auswahl in allen sichtbaren entsperrten Ebenen invertieren" + +#: ../../po/../src/verbs.cpp:1917 +msgid "D_eselect" +msgstr "Auswahl auf_heben" + +#: ../../po/../src/verbs.cpp:1918 +msgid "Deselect any selected objects or nodes" +msgstr "Die Auswahl von Objekten oder Knoten aufheben" + +#. Selection +#: ../../po/../src/verbs.cpp:1921 +msgid "Raise to _Top" +msgstr "Nach ganz _oben anheben" + +#: ../../po/../src/verbs.cpp:1922 +msgid "Raise selection to top" +msgstr "Die gewählten Objekte nach ganz oben anheben" + +#: ../../po/../src/verbs.cpp:1923 +msgid "Lower to _Bottom" +msgstr "Nach ganz _unten absenken" + +#: ../../po/../src/verbs.cpp:1924 +msgid "Lower selection to bottom" +msgstr "Die gewählten Objekte nach ganz unten absenken" + +#: ../../po/../src/verbs.cpp:1925 +msgid "_Raise" +msgstr "An_heben" + +#: ../../po/../src/verbs.cpp:1926 +msgid "Raise selection one step" +msgstr "Die gewählten Objekte eine Stufe nach oben anheben" + +#: ../../po/../src/verbs.cpp:1927 +msgid "_Lower" +msgstr "Ab_senken" + +#: ../../po/../src/verbs.cpp:1928 +msgid "Lower selection one step" +msgstr "Die gewählten Objekte eine Stufe nach unten absenken" + +#: ../../po/../src/verbs.cpp:1929 +msgid "_Group" +msgstr "_Gruppieren" + +#: ../../po/../src/verbs.cpp:1930 +msgid "Group selected objects" +msgstr "Die gewählten Objekte gruppieren" + +#: ../../po/../src/verbs.cpp:1932 +msgid "Ungroup selected groups" +msgstr "Gruppierung markierter Gruppen aufheben" + +#: ../../po/../src/verbs.cpp:1934 +msgid "_Put on Path" +msgstr "Text an _Pfad ausrichten" + +#: ../../po/../src/verbs.cpp:1935 +msgid "Put text on path" +msgstr "Text an Pfad ausrichten" + +#: ../../po/../src/verbs.cpp:1936 +msgid "_Remove from Path" +msgstr "Text von Pfad _trennen" + +#: ../../po/../src/verbs.cpp:1937 +msgid "Remove text from path" +msgstr "Text wird von Pfad getrennt" + +#: ../../po/../src/verbs.cpp:1938 +msgid "Remove Manual _Kerns" +msgstr "Manuelle _Unterschneidungen entfernen" + +#. TRANSLATORS: "glyph": An image used in the visual representation of characters; +#. roughly speaking, how a character looks. A font is a set of glyphs. +#: ../../po/../src/verbs.cpp:1941 +msgid "Remove all manual kerns and glyph rotations from a text object" +msgstr "" +"Alle manuellen Unterschneidungen und Rotationen von einem Textobjekt " +"entfernen" + +#: ../../po/../src/verbs.cpp:1943 +msgid "_Union" +msgstr "_Vereinigung" + +#: ../../po/../src/verbs.cpp:1944 +msgid "Union of selected objects" +msgstr "Die gewählten Objekte vereinigen" + +#: ../../po/../src/verbs.cpp:1945 +msgid "_Intersection" +msgstr "_Intersektion" + +#: ../../po/../src/verbs.cpp:1946 +msgid "Intersection of selected objects" +msgstr "Überschneidung der gewählten Objekte" + +#: ../../po/../src/verbs.cpp:1947 +msgid "_Difference" +msgstr "_Differenz" + +#: ../../po/../src/verbs.cpp:1948 +msgid "Difference of selected objects (bottom minus top)" +msgstr "Differenz der gewählten Objekte (Unteres minus Oberes)" + +#: ../../po/../src/verbs.cpp:1949 +msgid "E_xclusion" +msgstr "E_xklusiv-Oder (Ausschließen)" + +#: ../../po/../src/verbs.cpp:1950 +msgid "Exclusive OR of selected objects" +msgstr "Exklusiv-Oder-Operation auf gewählte Objekte" + +#: ../../po/../src/verbs.cpp:1951 +msgid "Di_vision" +msgstr "Divi_sion" + +#: ../../po/../src/verbs.cpp:1952 +msgid "Cut the bottom object into pieces" +msgstr "Untenliegendes Objekt in Teile zerschneiden" + +#. TRANSLATORS: "to cut a path" is not the same as "to break a path apart" - see the +#. Advanced tutorial for more info +#: ../../po/../src/verbs.cpp:1955 +msgid "Cut _Path" +msgstr "Pfad _zerschneiden" + +#: ../../po/../src/verbs.cpp:1956 +msgid "Cut the bottom object's stroke into pieces, removing fill" +msgstr "" +"Kontur des untenliegenden Objekts in Teile zerschneiden, Füllung wird " +"entfernt" + +#. TRANSLATORS: "outset": expand a shape by offsetting the object's path, +#. i.e. by displacing it perpendicular to the path in each point. +#. See also the Advanced Tutorial for explanation. +#: ../../po/../src/verbs.cpp:1960 +msgid "Outs_et" +msgstr "Aus_weiten (Vergrößern)" + +#: ../../po/../src/verbs.cpp:1961 +msgid "Outset selected paths" +msgstr "Gewählte Pfade ausweiten (vergrößern)" + +#: ../../po/../src/verbs.cpp:1963 +msgid "O_utset Path by 1 px" +msgstr "Pfad um 1 px ausweiten (vergrößern)" + +#: ../../po/../src/verbs.cpp:1964 +msgid "Outset selected paths by 1 px" +msgstr "Gewählte Pfade um 1 px ausweiten (vergrößern)" + +#: ../../po/../src/verbs.cpp:1966 +msgid "O_utset Path by 10 px" +msgstr "Pfad um 10 px ausweiten (vergrößern)" + +#: ../../po/../src/verbs.cpp:1967 +msgid "Outset selected paths by 10 px" +msgstr "Gewählte Pfade um 10 px ausweiten (vergrößern)" + +#. TRANSLATORS: "inset": contract a shape by offsetting the object's path, +#. i.e. by displacing it perpendicular to the path in each point. +#. See also the Advanced Tutorial for explanation. +#: ../../po/../src/verbs.cpp:1971 +msgid "I_nset" +msgstr "Schrum_pfen" + +# !!! make singular and plural forms +#: ../../po/../src/verbs.cpp:1972 +msgid "Inset selected paths" +msgstr "Gewählte Pfade schrumpfen" + +#: ../../po/../src/verbs.cpp:1974 +msgid "I_nset Path by 1 px" +msgstr "Pfad um _1 px schrumpfen" + +#: ../../po/../src/verbs.cpp:1975 +msgid "Inset selected paths by 1 px" +msgstr "Die ausgewählten Pfade um 1 px schrumpfen" + +#: ../../po/../src/verbs.cpp:1977 +msgid "I_nset Path by 10 px" +msgstr "Pfad um 1_0 px schrumpfen" + +#: ../../po/../src/verbs.cpp:1978 +msgid "Inset selected paths by 10 px" +msgstr "Die ausgewählten Pfade um 10 px schrumpfen" + +#: ../../po/../src/verbs.cpp:1980 +msgid "D_ynamic Offset" +msgstr "D_ynamischer Versatz" + +#: ../../po/../src/verbs.cpp:1980 +msgid "Create a dynamic offset object" +msgstr "Ein Objekt mit dynamischem Versatz erstellen" + +#: ../../po/../src/verbs.cpp:1982 +msgid "_Linked Offset" +msgstr "Ver_bundener Versatz" + +#: ../../po/../src/verbs.cpp:1983 +msgid "Create a dynamic offset object linked to the original path" +msgstr "" +"Dynamischen Versatz am Objekt erstellen. Verknüpfung zum originalen Pfad " +"bleibt bestehen." + +#: ../../po/../src/verbs.cpp:1985 +msgid "_Stroke to Path" +msgstr "_Kontur in Pfad umwandeln" + +#: ../../po/../src/verbs.cpp:1986 +msgid "Convert selected strokes to paths" +msgstr "Die ausgewählten Konturen in Pfade umwandeln" + +#: ../../po/../src/verbs.cpp:1987 +msgid "Si_mplify" +msgstr "Ver_einfachen" + +#: ../../po/../src/verbs.cpp:1988 +msgid "Simplify selected paths by removing extra nodes" +msgstr "Pfade vereinfachen - unnötige Punkte werden entfernt" + +#: ../../po/../src/verbs.cpp:1989 +msgid "_Reverse" +msgstr "_Richtung umkehren" + +#: ../../po/../src/verbs.cpp:1990 +msgid "Reverses the direction of selected paths; useful for flipping markers" +msgstr "" +"Richtung der gewählten Pfade umkehren; nützlich, um Markierungen umzukehren" + +#. TRANSLATORS: "to trace" means "to convert a bitmap to vector graphics" (to vectorize) +#: ../../po/../src/verbs.cpp:1992 +msgid "_Trace Bitmap" +msgstr "Bitmap _vektorisieren" + +#: ../../po/../src/verbs.cpp:1993 +msgid "Convert bitmap object to paths" +msgstr "Bitmaps in Pfade umwandeln" + +#: ../../po/../src/verbs.cpp:1994 +msgid "_Make a Bitmap Copy" +msgstr "Kopie als Bit_map" + +#: ../../po/../src/verbs.cpp:1995 +msgid "Export selection to a bitmap and insert it into document" +msgstr "Auswahl als Bitmap exportieren und in das Dokument re-importieren" + +#: ../../po/../src/verbs.cpp:1996 +msgid "_Combine" +msgstr "_Kombinieren" + +#: ../../po/../src/verbs.cpp:1997 +msgid "Combine several paths into one" +msgstr "Mehrere Pfade zu einem kombinieren" + +#. TRANSLATORS: "to cut a path" is not the same as "to break a path apart" - see the +#. Advanced tutorial for more info +#: ../../po/../src/verbs.cpp:2000 +msgid "Break _Apart" +msgstr "_Zerlegen" + +#: ../../po/../src/verbs.cpp:2001 +msgid "Break selected paths into subpaths" +msgstr "Die markierten Pfade in Unterpfade zerlegen" + +#: ../../po/../src/verbs.cpp:2002 +msgid "Gri_d Arrange..." +msgstr "Anordnen im Raster..." + +#: ../../po/../src/verbs.cpp:2003 +msgid "Arrange selection in grid pattern" +msgstr "Auswahl im Raster anordnen" + +#. Layer +#: ../../po/../src/verbs.cpp:2005 +msgid "_Add Layer..." +msgstr "Ebene hinzufügen..." + +#: ../../po/../src/verbs.cpp:2006 +msgid "Create a new layer" +msgstr "Eine neue Ebene anlegen" + +#: ../../po/../src/verbs.cpp:2007 +msgid "Re_name Layer..." +msgstr "Ebene umbe_nennen" + +#: ../../po/../src/verbs.cpp:2008 +msgid "Rename the current layer" +msgstr "Aktuelle Ebene umbenennen" + +#: ../../po/../src/verbs.cpp:2009 +msgid "Switch to Layer Abov_e" +msgstr "Zur darüberliegenden Ebene umschalten" + +#: ../../po/../src/verbs.cpp:2010 +msgid "Switch to the layer above the current" +msgstr "Zur darüberliegenden Ebene im Dokument umschalten" + +#: ../../po/../src/verbs.cpp:2011 +msgid "Switch to Layer Belo_w" +msgstr "Zur darunterliegenden Ebene umschalten" + +#: ../../po/../src/verbs.cpp:2012 +msgid "Switch to the layer below the current" +msgstr "Zur darunterliegenden Ebene im Dokument umschalten" + +#: ../../po/../src/verbs.cpp:2013 +msgid "Move Selection to Layer Abo_ve" +msgstr "Auswahl zur darüberliegenden Ebene verschieben" + +#: ../../po/../src/verbs.cpp:2014 +msgid "Move selection to the layer above the current" +msgstr "Die Auswahl auf die darüberliegende Ebene verschieben" + +#: ../../po/../src/verbs.cpp:2015 +msgid "Move Selection to Layer Bel_ow" +msgstr "Auswahl zur darunterliegenden Ebene verschieben" + +#: ../../po/../src/verbs.cpp:2016 +msgid "Move selection to the layer below the current" +msgstr "Die Auswahl auf die darunterliegende Ebene verschieben" + +#: ../../po/../src/verbs.cpp:2017 +msgid "Layer to _Top" +msgstr "Ebene nach ganz _oben" + +#: ../../po/../src/verbs.cpp:2018 +msgid "Raise the current layer to the top" +msgstr "Die aktuelle Ebene nach ganz oben anheben" + +#: ../../po/../src/verbs.cpp:2019 +msgid "Layer to _Bottom" +msgstr "Ebene nach ganz _unten" + +#: ../../po/../src/verbs.cpp:2020 +msgid "Lower the current layer to the bottom" +msgstr "Die aktuelle Ebene nach ganz unten absenken" + +#: ../../po/../src/verbs.cpp:2021 +msgid "_Raise Layer" +msgstr "Ebene an_heben" + +#: ../../po/../src/verbs.cpp:2022 +msgid "Raise the current layer" +msgstr "Die aktuelle Ebene anheben" + +#: ../../po/../src/verbs.cpp:2023 +msgid "_Lower Layer" +msgstr "Ebene ab_senken" + +#: ../../po/../src/verbs.cpp:2024 +msgid "Lower the current layer" +msgstr "Die aktuelle Ebene absenken" + +#: ../../po/../src/verbs.cpp:2025 +msgid "_Delete Current Layer" +msgstr "Aktuelle Ebene _löschen" + +#: ../../po/../src/verbs.cpp:2026 +msgid "Delete the current layer" +msgstr "Die aktuelle Ebene löschen" + +#. Object +#: ../../po/../src/verbs.cpp:2029 +#, fuzzy +msgid "Rotate _90° CW" +msgstr "Um 90 Grad _rechtsherum drehen" + +#: ../../po/../src/verbs.cpp:2030 +#, fuzzy +msgid "Rotate selection 90° clockwise" +msgstr "Die gewählten Objekte um 90 Grad im Uhrzeigersinn drehen" + +#: ../../po/../src/verbs.cpp:2031 +#, fuzzy +msgid "Rotate 9_0° CCW" +msgstr "Um 90 Grad _linksherum drehen" + +#: ../../po/../src/verbs.cpp:2032 +#, fuzzy +msgid "Rotate selection 90° counter-clockwise" +msgstr "Die gewählten Objekte um 90 Grad gegen den Uhrzeigersinn drehen" + +#: ../../po/../src/verbs.cpp:2033 +msgid "Remove _Transformations" +msgstr "Veränderungen _zurücksetzen" + +#: ../../po/../src/verbs.cpp:2034 +msgid "Remove transformations from object" +msgstr "Veränderungen des Objekts rückgängig machen" + +#: ../../po/../src/verbs.cpp:2035 +msgid "_Object to Path" +msgstr "_Objekt in Pfad umwandeln" + +#: ../../po/../src/verbs.cpp:2036 +msgid "Convert selected objects to paths" +msgstr "Die gewählten Objekte in Pfade umwandeln" + +# !!! Frame, not form? +#: ../../po/../src/verbs.cpp:2037 +msgid "_Flow into Frame" +msgstr "Umbruch an Form anpassen" + +#: ../../po/../src/verbs.cpp:2038 +msgid "Put text into frames" +msgstr "Text in Formen fließen lassen" + +#: ../../po/../src/verbs.cpp:2039 +msgid "_Unflow" +msgstr "Textfluß _aufheben" + +#: ../../po/../src/verbs.cpp:2040 +msgid "Remove text from frame (creates a single-line text object)" +msgstr "Text von der Form trennen (erzeugt einzeiliges Textobjekt)" + +#: ../../po/../src/verbs.cpp:2041 +msgid "_Convert to Text" +msgstr "In normalen Text um_wandeln" + +#: ../../po/../src/verbs.cpp:2042 +msgid "Convert flowed text to regular text objects (preserves appearance)" +msgstr "" +"Ausgewählte Fließtexte in gewöhnliche Textobjekte umwandeln (behält Aussehen " +"bei)" + +#: ../../po/../src/verbs.cpp:2044 +msgid "Flip _Horizontal" +msgstr "_Horizontal umkehren" + +#: ../../po/../src/verbs.cpp:2044 +msgid "Flips selected objects horizontally" +msgstr "Ausgewählte Objekte horizontal umkehren" + +#: ../../po/../src/verbs.cpp:2047 +msgid "Flip _Vertical" +msgstr "_Vertikal umkehren" + +#: ../../po/../src/verbs.cpp:2047 +msgid "Flips selected objects vertically" +msgstr "Ausgewählte Objekte vertikal umkehren" + +#. Tools +#: ../../po/../src/verbs.cpp:2051 +msgid "Select" +msgstr "Auswählen" + +#: ../../po/../src/verbs.cpp:2052 +msgid "Select and transform objects" +msgstr "Objekte auswählen und verändern" + +#: ../../po/../src/verbs.cpp:2053 +msgid "Node Edit" +msgstr "Knoten bearbeiten" + +#: ../../po/../src/verbs.cpp:2054 +msgid "Edit path nodes or control handles" +msgstr "Bearbeiten der Knoten oder der Anfasser eines Pfades" + +#: ../../po/../src/verbs.cpp:2056 +msgid "Create rectangles and squares" +msgstr "Rechtecke und Quadrate erstellen" + +#: ../../po/../src/verbs.cpp:2058 +msgid "Create circles, ellipses, and arcs" +msgstr "Kreise, Ellipsen und Bögen erstellen" + +#: ../../po/../src/verbs.cpp:2060 +msgid "Create stars and polygons" +msgstr "Sterne und Polygone erstellen" + +#: ../../po/../src/verbs.cpp:2062 +msgid "Create spirals" +msgstr "Spiralen erstellen" + +#: ../../po/../src/verbs.cpp:2064 +msgid "Draw freehand lines" +msgstr "Freihandlinien zeichnen" + +#: ../../po/../src/verbs.cpp:2066 +msgid "Draw Bezier curves and straight lines" +msgstr "Kurven und gerade Linien zeichnen" + +#: ../../po/../src/verbs.cpp:2068 +msgid "Draw calligraphic lines" +msgstr "Kalligraphische Linien zeichnen" + +#: ../../po/../src/verbs.cpp:2070 +msgid "Create and edit text objects" +msgstr "Textobjekte erstellen und bearbeiten" + +#: ../../po/../src/verbs.cpp:2072 +msgid "Create and edit gradients" +msgstr "Erstellen und Bearbeiten von Farbverläufen" + +#: ../../po/../src/verbs.cpp:2074 +msgid "Zoom in or out" +msgstr "Zoomfaktor vergrößern oder verringern" + +#: ../../po/../src/verbs.cpp:2076 +msgid "Pick averaged colors from image" +msgstr "Gemittelte Farben aus dem Bild auswählen" + +#: ../../po/../src/verbs.cpp:2078 +msgid "Create connectors" +msgstr "Objektverbinder erzeugen" + +#. Tool prefs +#: ../../po/../src/verbs.cpp:2081 +msgid "Selector Preferences" +msgstr "Einstellungen für das Auswahlwerkzeug" + +#: ../../po/../src/verbs.cpp:2082 +msgid "Open Preferences for the Selector tool" +msgstr "Einstellungen für das Auswahlwerkzeug öffnen" + +#: ../../po/../src/verbs.cpp:2083 +msgid "Node Tool Preferences" +msgstr "Einstellungen für das Knotenwerkzeug" + +#: ../../po/../src/verbs.cpp:2084 +msgid "Open Preferences for the Node tool" +msgstr "Einstellungen für das Knotenwerkzeug öffnen" + +#: ../../po/../src/verbs.cpp:2085 +msgid "Rectangle Preferences" +msgstr "Eigenschaften für das Rechteckwerkzeug" + +#: ../../po/../src/verbs.cpp:2086 +msgid "Open Preferences for the Rectangle tool" +msgstr "Einstellungen für das Rechteckwerkzeug öffnen" + +#: ../../po/../src/verbs.cpp:2087 +msgid "Ellipse Preferences" +msgstr "Einstellungen für das Ellipsenwerkzeug" + +#: ../../po/../src/verbs.cpp:2088 +msgid "Open Preferences for the Ellipse tool" +msgstr "Einstellungen für das Ellipsenwerkzeug öffnen" + +#: ../../po/../src/verbs.cpp:2089 +msgid "Star Preferences" +msgstr "Einstellungen für das Sternwerkzeug" + +#: ../../po/../src/verbs.cpp:2090 +msgid "Open Preferences for the Star tool" +msgstr "Eigenschaften für das Sternwerkzeug öffnen" + +#: ../../po/../src/verbs.cpp:2091 +msgid "Spiral Preferences" +msgstr "Einstellungen für das Spiralwerkzeug" + +#: ../../po/../src/verbs.cpp:2092 +msgid "Open Preferences for the Spiral tool" +msgstr "Eigenschaften für das Spiralenwerkzeug öffnen" + +#: ../../po/../src/verbs.cpp:2093 +msgid "Pencil Preferences" +msgstr "Einstellungen für das Malwerkzeug" + +#: ../../po/../src/verbs.cpp:2094 +msgid "Open Preferences for the Pencil tool" +msgstr "Eigenschaften für das Malwerkzeug öffnen" + +#: ../../po/../src/verbs.cpp:2095 +msgid "Pen Preferences" +msgstr "Einstellungen für das Zeichenwerkzeug" + +#: ../../po/../src/verbs.cpp:2096 +msgid "Open Preferences for the Pen tool" +msgstr "Eigenschaften für das Zeichenwerkzeug öffnen" + +#: ../../po/../src/verbs.cpp:2097 +msgid "Calligraphic Preferences" +msgstr "Einstellungen für das Kalligraphiewerkzeug" + +#: ../../po/../src/verbs.cpp:2098 +msgid "Open Preferences for the Calligraphy tool" +msgstr "Eigenschaften für das Kalligraphiewerkzeug öffnen" + +#: ../../po/../src/verbs.cpp:2099 +msgid "Text Preferences" +msgstr "Einstellungen für das Textwerkzeug" + +#: ../../po/../src/verbs.cpp:2100 +msgid "Open Preferences for the Text tool" +msgstr "Eigenschaften für das Textwerkzeug öffnen" + +#: ../../po/../src/verbs.cpp:2101 +msgid "Gradient Preferences" +msgstr "Einstellungen für Farbverläufe" + +#: ../../po/../src/verbs.cpp:2102 +msgid "Open Preferences for the Gradient tool" +msgstr "Eigenschaften für Farbverläufe öffnen" + +#: ../../po/../src/verbs.cpp:2103 +msgid "Zoom Preferences" +msgstr "Einstellungen für das Zoomwerkzeug" + +#: ../../po/../src/verbs.cpp:2104 +msgid "Open Preferences for the Zoom tool" +msgstr "Eigenschaften für das Zoomwerkzeug öffnen" + +#: ../../po/../src/verbs.cpp:2105 +msgid "Dropper Preferences" +msgstr "Einstellungen für die Farbpipette" + +#: ../../po/../src/verbs.cpp:2106 +msgid "Open Preferences for the Dropper tool" +msgstr "Eigenschaften für die Farbpipette öffnen" + +#: ../../po/../src/verbs.cpp:2107 +msgid "Connector Preferences" +msgstr "Einstellungen für Objektverbinder" + +#: ../../po/../src/verbs.cpp:2108 +msgid "Open Preferences for the Connector tool" +msgstr "Eigenschaften für das Objektverbinder-Werkzeug öffnen" + +#. Zoom/View +#: ../../po/../src/verbs.cpp:2111 +msgid "Zoom In" +msgstr "Heranzoomen" + +#: ../../po/../src/verbs.cpp:2111 +msgid "Zoom in" +msgstr "Ansicht vergrößern" + +#: ../../po/../src/verbs.cpp:2112 +msgid "Zoom Out" +msgstr "Wegzoomen" + +#: ../../po/../src/verbs.cpp:2112 +msgid "Zoom out" +msgstr "Ansicht verkleinern" + +#: ../../po/../src/verbs.cpp:2113 +msgid "_Rulers" +msgstr "_Lineale" + +#: ../../po/../src/verbs.cpp:2113 +msgid "Show or hide the canvas rulers" +msgstr "Zeichnungslineale anzeigen oder ausblenden" + +#: ../../po/../src/verbs.cpp:2114 +msgid "Scroll_bars" +msgstr "Roll_balken" + +#: ../../po/../src/verbs.cpp:2114 +msgid "Show or hide the canvas scrollbars" +msgstr "Rollbalken anzeigen oder ausblenden" + +#: ../../po/../src/verbs.cpp:2115 +msgid "_Grid" +msgstr "_Gitter" + +#: ../../po/../src/verbs.cpp:2116 +msgid "G_uides" +msgstr "_Führungslinien" + +#: ../../po/../src/verbs.cpp:2117 +msgid "Nex_t Zoom" +msgstr "_Nächster Zoomfaktor" + +#: ../../po/../src/verbs.cpp:2117 +msgid "Next zoom (from the history of zooms)" +msgstr "Den nächsten Zoomfaktor einstellen (aus der Liste bisheriger Faktoren)" + +#: ../../po/../src/verbs.cpp:2119 +msgid "Pre_vious Zoom" +msgstr "_Vorheriger Zoomfaktor" + +#: ../../po/../src/verbs.cpp:2119 +msgid "Previous zoom (from the history of zooms)" +msgstr "" +"Den vorherigen Zoomfaktor einstellen (aus der Liste bisheriger Faktoren)" + +#: ../../po/../src/verbs.cpp:2121 +msgid "Zoom 1:_1" +msgstr "Zoomfaktor 1:_1" + +#: ../../po/../src/verbs.cpp:2121 +msgid "Zoom to 1:1" +msgstr "Den Zoomfaktor auf 1:1 setzen" + +#: ../../po/../src/verbs.cpp:2123 +msgid "Zoom 1:_2" +msgstr "Zoomfaktor 1:_2" + +#: ../../po/../src/verbs.cpp:2123 +msgid "Zoom to 1:2" +msgstr "Den Zoomfaktor auf 1:2 setzen" + +#: ../../po/../src/verbs.cpp:2125 +msgid "_Zoom 2:1" +msgstr "_Zoomfaktor 2:1" + +#: ../../po/../src/verbs.cpp:2125 +msgid "Zoom to 2:1" +msgstr "Den Zoomfaktor auf 2:1 setzen" + +#: ../../po/../src/verbs.cpp:2128 +msgid "_Fullscreen" +msgstr "Voll_bild" + +#: ../../po/../src/verbs.cpp:2128 +msgid "Stretch this document window to full screen" +msgstr "Dieses Dokumentenfenster auf Vollbild aufziehen" + +#: ../../po/../src/verbs.cpp:2131 +msgid "Duplic_ate Window" +msgstr "Fenster d_uplizieren" + +#: ../../po/../src/verbs.cpp:2131 +msgid "Open a new window with the same document" +msgstr "Das momentan geöffnete Dokument in einem neuen Fenster darstellen" + +#: ../../po/../src/verbs.cpp:2133 +msgid "_New View Preview" +msgstr "Neue Vorschau" + +#: ../../po/../src/verbs.cpp:2134 +msgid "New View Preview" +msgstr "Neue Vorschau" + +#. "view_new_preview" +#: ../../po/../src/verbs.cpp:2136 +#, fuzzy +msgid "_Normal" +msgstr "Normal" + +#: ../../po/../src/verbs.cpp:2137 +msgid "Switch to normal display mode" +msgstr "" + +#: ../../po/../src/verbs.cpp:2138 +#, fuzzy +msgid "_Outline" +msgstr "Objektumriss" + +#: ../../po/../src/verbs.cpp:2139 +msgid "Switch to outline (wireframe) display mode" +msgstr "" + +#: ../../po/../src/verbs.cpp:2141 +msgid "Ico_n Preview" +msgstr "Icon-Vorschaufenster" + +#: ../../po/../src/verbs.cpp:2142 +msgid "Open a window to preview items at different icon resolutions" +msgstr "" +"Vorschaufenster öffnen, um Elemente bei verschiedenen Icon-Auflösungsstufen " +"zu sehen" + +#: ../../po/../src/verbs.cpp:2144 +msgid "Zoom to fit page in window" +msgstr "Die Seite in das Fenster einpassen" + +#: ../../po/../src/verbs.cpp:2145 +msgid "Page _Width" +msgstr "Seiten_breite" + +#: ../../po/../src/verbs.cpp:2146 +msgid "Zoom to fit page width in window" +msgstr "Die Seitenbreite in das Fenster einpassen" + +#: ../../po/../src/verbs.cpp:2148 +msgid "Zoom to fit drawing in window" +msgstr "Die Zeichnung in das Fenster einpassen" + +#: ../../po/../src/verbs.cpp:2150 +msgid "Zoom to fit selection in window" +msgstr "Die Auswahl in das Fenster einpassen" + +#. Dialogs +#: ../../po/../src/verbs.cpp:2153 +msgid "In_kscape Preferences..." +msgstr "In_kscape-Einstellungen..." + +#: ../../po/../src/verbs.cpp:2154 +msgid "Global Inkscape preferences" +msgstr "Globale Einstellungen für Inkscape" + +#: ../../po/../src/verbs.cpp:2155 +msgid "_Document Preferences..." +msgstr "D_okumenteneinstellungen..." + +#: ../../po/../src/verbs.cpp:2156 +msgid "Preferences saved with the document" +msgstr "Einstellungen, die mit dem Dokument gespeichert werden" + +#: ../../po/../src/verbs.cpp:2157 +msgid "_Fill and Stroke..." +msgstr "_Füllung und Kontur..." + +#: ../../po/../src/verbs.cpp:2158 +msgid "Fill and Stroke dialog" +msgstr "Dialog für Füllung und Kontur" + +#. TRANSLATORS: "Swatches" means: color samples +#: ../../po/../src/verbs.cpp:2160 +msgid "S_watches..." +msgstr "Farbfelder-Palette..." + +#: ../../po/../src/verbs.cpp:2161 +msgid "View color swatches" +msgstr "Farbfelder-Palette anzeigen" + +#: ../../po/../src/verbs.cpp:2162 +msgid "Transfor_m..." +msgstr "_Verändern..." + +#: ../../po/../src/verbs.cpp:2163 +msgid "Transform dialog" +msgstr "Verändern" + +#: ../../po/../src/verbs.cpp:2164 +msgid "_Align and Distribute..." +msgstr "_Anordnen und Abstände ausgleichen..." + +#: ../../po/../src/verbs.cpp:2165 +msgid "Align and Distribute dialog" +msgstr "Anordnen und Abstände ausgleichen" + +#: ../../po/../src/verbs.cpp:2166 +msgid "_Text and Font..." +msgstr "_Schrift und Text..." + +#: ../../po/../src/verbs.cpp:2167 +msgid "Text and Font dialog" +msgstr "Dialog für Schrift und Text" + +#: ../../po/../src/verbs.cpp:2168 +msgid "_XML Editor..." +msgstr "_XML-Editor..." + +#: ../../po/../src/verbs.cpp:2169 +msgid "XML Editor" +msgstr "XML-Editor" + +#: ../../po/../src/verbs.cpp:2170 +msgid "_Find..." +msgstr "_Suchen..." + +#: ../../po/../src/verbs.cpp:2171 +msgid "Find objects in document" +msgstr "Objekte im Dokument suchen" + +#: ../../po/../src/verbs.cpp:2172 +msgid "_Messages..." +msgstr "Nachrichten..." + +#: ../../po/../src/verbs.cpp:2173 +msgid "View debug messages" +msgstr "Nachrichten zur Fehlersuche anzeigen" + +#: ../../po/../src/verbs.cpp:2174 +msgid "S_cripts..." +msgstr "_Skripte..." + +#: ../../po/../src/verbs.cpp:2175 +msgid "Run scripts" +msgstr "Skripte ausführen" + +#: ../../po/../src/verbs.cpp:2176 +msgid "Show/Hide D_ialogs" +msgstr "_Dialoge anzeigen oder ausblenden" + +#: ../../po/../src/verbs.cpp:2177 +msgid "Show or hide all active dialogs" +msgstr "Alle aktiven Dialoge zeigen oder ausblenden" + +#. TRANSLATORS: "Tile clones" means: "Create tiled clones" +#: ../../po/../src/verbs.cpp:2179 +msgid "Tile clones..." +msgstr "Klone kacheln..." + +#: ../../po/../src/verbs.cpp:2180 +msgid "Create and arrange multiple clones of selection" +msgstr "Erzeugen und Anordnen mehrfacher Klone von einer Auswahl" + +#: ../../po/../src/verbs.cpp:2181 +msgid "_Object Properties..." +msgstr "_Objekteigenschaften..." + +#: ../../po/../src/verbs.cpp:2182 +msgid "Object Properties dialog" +msgstr "Objekteigenschaften" + +#: ../../po/../src/verbs.cpp:2185 +msgid "_Connect to Jabber server..." +msgstr "Mit Jabber-Server _verbinden..." + +#: ../../po/../src/verbs.cpp:2185 +msgid "Connect to a Jabber server" +msgstr "Mit einem Jabber-Server verbinden" + +#: ../../po/../src/verbs.cpp:2187 +msgid "Share with _user..." +msgstr "Whiteboard mit anderem _Benutzer..." + +#: ../../po/../src/verbs.cpp:2187 +msgid "Establish a whiteboard session with another Jabber user" +msgstr "" +"Eine gemeinsame Whiteboard-Sitzung mit einem anderen Jabber-Benutzer aufbauen" + +#: ../../po/../src/verbs.cpp:2189 +msgid "Share with _chatroom..." +msgstr "Whiteboard mit _Chat-Raum..." + +# !!! 2x join +#: ../../po/../src/verbs.cpp:2189 +msgid "" +"Join a chatroom to start a new whiteboard session or join one in progress" +msgstr "" +"Einen Chat-Raum betreten, um eine neue Whiteboard-Sitzung zu beginnen oder " +"an einer laufenden Sitzung teilzunehmen" + +#: ../../po/../src/verbs.cpp:2191 +msgid "_Dump XML node tracker" +msgstr "XML-Knotenprotokoll _ausgeben" + +#: ../../po/../src/verbs.cpp:2191 +msgid "Dump the contents of the XML tracker to the console" +msgstr "Das XML-Knotenprotokoll auf die Konsole ausgeben" + +#: ../../po/../src/verbs.cpp:2193 +msgid "_Open session file..." +msgstr "Sitzungsdatei _öffnen..." + +#: ../../po/../src/verbs.cpp:2193 +msgid "Open and browse through records of past whiteboard sessions" +msgstr "Aufzeichnungen von früheren Whiteboard-Sitzungen öffnen" + +#: ../../po/../src/verbs.cpp:2195 +msgid "Session file playback" +msgstr "Wiedergabe der Sitzungsdatei" + +#: ../../po/../src/verbs.cpp:2197 +msgid "_Disconnect from session" +msgstr "Von Sitzung _trennen" + +#: ../../po/../src/verbs.cpp:2199 +msgid "Disconnect from _server" +msgstr "Von _Server trennen" + +#: ../../po/../src/verbs.cpp:2201 +msgid "_Input Devices..." +msgstr "_Eingabegeräte..." + +#: ../../po/../src/verbs.cpp:2202 +msgid "Configure extended input devices" +msgstr "Erweiterte Eingabegeräte konfigurieren" + +#. Help +#: ../../po/../src/verbs.cpp:2205 +msgid "_Keys and Mouse" +msgstr "_Tasten und Maus" + +# !!! "Abkuerzungen"? +#: ../../po/../src/verbs.cpp:2206 +msgid "Key and mouse shortcuts reference" +msgstr "Referenz der Tasten- und Maus-Abkürzungen" + +#: ../../po/../src/verbs.cpp:2207 +msgid "About E_xtensions" +msgstr "Über Erweiterungen" + +#: ../../po/../src/verbs.cpp:2208 +msgid "About Extensions..." +msgstr "Über Erweiterungen..." + +#: ../../po/../src/verbs.cpp:2209 +msgid "About _Memory" +msgstr "_Speichernutzung" + +#: ../../po/../src/verbs.cpp:2210 +msgid "About Memory..." +msgstr "Speichernutzung von Inkscape" + +#: ../../po/../src/verbs.cpp:2211 +msgid "_About Inkscape" +msgstr "Ü_ber Inkscape" + +#. "help_about" +#. new HelpVerb(SP_VERB_SHOW_LICENSE, "ShowLicense", N_("Modifying or Redistributing Inkscape"), +#. N_("Show license to modify and/or redistribute Inkscape: GNU GPL"), NULL), +#. Tutorials +#: ../../po/../src/verbs.cpp:2217 +msgid "Inkscape: _Basic" +msgstr "Inkscape: _Grundlagen" + +#: ../../po/../src/verbs.cpp:2218 +msgid "Getting started with Inkscape" +msgstr "Erste Schritte mit Inkscape" + +#. "tutorial_basic" +#: ../../po/../src/verbs.cpp:2219 +msgid "Inkscape: _Shapes" +msgstr "Inkscape: _Grundformen" + +#: ../../po/../src/verbs.cpp:2220 +msgid "Using shape tools to create and edit shapes" +msgstr "Benutzung der Formen-Werkzeuge zum Erzeugen und Verändern von Formen" + +#: ../../po/../src/verbs.cpp:2221 +msgid "Inkscape: _Advanced" +msgstr "Inkscape: _Fortgeschrittene Benutzung" + +#: ../../po/../src/verbs.cpp:2222 +msgid "Advanced Inkscape topics" +msgstr "Fortgeschrittene Themen bei der Benutzung von Inkscape" + +#. "tutorial_advanced" +#. TRANSLATORS: "to trace" means "to convert a bitmap to vector graphics" (to vectorize) +#: ../../po/../src/verbs.cpp:2224 +msgid "Inkscape: T_racing" +msgstr "Inkscape: _Vektorisieren" + +#: ../../po/../src/verbs.cpp:2225 +msgid "Using bitmap tracing" +msgstr "Verwendung der Bitmap-Vektorisierung" + +#. "tutorial_tracing" +#: ../../po/../src/verbs.cpp:2226 +msgid "Inkscape: _Calligraphy" +msgstr "Inkscape: _Kalligraphie" + +#: ../../po/../src/verbs.cpp:2227 +msgid "Using the Calligraphy pen tool" +msgstr "Verwendung des kalligraphischen Füllers" + +#: ../../po/../src/verbs.cpp:2228 +msgid "_Elements of Design" +msgstr "_Elemente des Designs" + +#: ../../po/../src/verbs.cpp:2229 +msgid "Principles of design in the tutorial form" +msgstr "Gestaltungsprinzipen" + +#. "tutorial_design" +#: ../../po/../src/verbs.cpp:2230 +msgid "_Tips and Tricks" +msgstr "_Tipps und Tricks" + +#: ../../po/../src/verbs.cpp:2231 +msgid "Miscellaneous tips and tricks" +msgstr "Verschiedene Tipps und Tricks" + +#. "tutorial_tips" +#. Effect +#: ../../po/../src/verbs.cpp:2234 +msgid "Previous Effect" +msgstr "Vorheriger Effekt" + +#: ../../po/../src/verbs.cpp:2235 +msgid "Repeat the last effect with the same settings" +msgstr "Letzten Effekt mit den gleichen Einstellungen anwenden" + +#. "tutorial_tips" +#: ../../po/../src/verbs.cpp:2236 +msgid "Previous Effect Settings..." +msgstr "Einstellungen des vorherigen Effekts..." + +#: ../../po/../src/verbs.cpp:2237 +msgid "Repeat the last effect with new settings" +msgstr "Letzten Effekt mit anderen Einstellungen wiederholen" + +#: ../../po/../src/widgets/dash-selector.cpp:106 +msgid "Dash pattern" +msgstr "Muster der Strichlinien" + +#: ../../po/../src/widgets/dash-selector.cpp:121 +msgid "Pattern offset" +msgstr "Versatz des Musters" + +#: ../../po/../src/widgets/desktop-widget.cpp:240 +msgid "Zoom drawing if window size changes" +msgstr "Zeichnungsgröße ändern, sobald die Fenstergröße verändert wird" + +#: ../../po/../src/widgets/desktop-widget.cpp:298 +msgid "Cursor coordinates" +msgstr "Zeigerkoordinaten" + +#. display the initial welcome message in the statusbar +#: ../../po/../src/widgets/desktop-widget.cpp:324 +msgid "" +"Welcome to Inkscape! Use shape or freehand tools to create objects; " +"use selector (arrow) to move or transform them." +msgstr "" +"Willkommen zu Inkscape! Formen- und Freihandwerkzeuge erstellen " +"Objekte; das Auswahlwerkzeug (Pfeil) verschiebt und bearbeitet." + +#: ../../po/../src/widgets/desktop-widget.cpp:372 +#, c-format +msgid "%s: %d - Inkscape" +msgstr "%s: %d - Inkscape" + +#: ../../po/../src/widgets/desktop-widget.cpp:374 +#, c-format +msgid "%s - Inkscape" +msgstr "%s - Inkscape" + +#: ../../po/../src/widgets/desktop-widget.cpp:532 +#, c-format +msgid "" +"Save changes to document \"%s\" before " +"closing?\n" +"\n" +"If you close without saving, your changes will be discarded." +msgstr "" +"Änderungen an Dokument »%s« vor dem " +"Schließen speichern?\n" +"\n" +"Wenn Sie schließen, ohne zu speichern, dann gehen Ihre Änderungen verloren." + +#: ../../po/../src/widgets/desktop-widget.cpp:548 +#: ../../po/../src/widgets/desktop-widget.cpp:612 +msgid "Close _without saving" +msgstr "Schließen, _ohne zu speichern" + +#: ../../po/../src/widgets/desktop-widget.cpp:595 +#, c-format +msgid "" +"The file \"%s\" was saved with a " +"format (%s) that may cause data loss!\n" +"\n" +"Do you want to save this file in another format?" +msgstr "" +"Das Dokument \"%s\" wurde in einem " +"möglicherweise verlustbehafteten Format (%s) gespeichert!\n" +"\n" +"Möchten Sie das Dokument noch in einem anderen Format speichern?" + +#. Family frame +#: ../../po/../src/widgets/font-selector.cpp:156 +msgid "Font family" +msgstr "Familie" + +#. Style frame +#: ../../po/../src/widgets/font-selector.cpp:184 +msgid "Style" +msgstr "Stil" + +#: ../../po/../src/widgets/font-selector.cpp:219 +msgid "Font size:" +msgstr "Größe:" + +#. TRANSLATORS: Test string used in text and font dialog (when no +#. * text has been entered) to get a preview of the font. Choose +#. * some representative characters that users of your locale will be +#. * interested in. +#: ../../po/../src/widgets/font-selector.cpp:554 +msgid "AaBbCcIiPpQq12368.;/()" +msgstr "AaBbCcIiPpQqÄäÖöÜüß012369€¢?&.;/|()„“»«" + +#: ../../po/../src/widgets/gradient-selector.cpp:137 +#: ../../po/../src/widgets/gradient-toolbar.cpp:524 +msgid "Duplicate" +msgstr "Duplizieren" + +#: ../../po/../src/widgets/gradient-selector.cpp:142 +#: ../../po/../src/widgets/gradient-toolbar.cpp:535 +msgid "Edit..." +msgstr "Bearbeiten..." + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/pservers.html#LinearGradientSpreadMethodAttribute +#: ../../po/../src/widgets/gradient-selector.cpp:159 +msgid "" +"Whether to fill with flat color beyond the ends of the gradient vector " +"(spreadMethod=\"pad\"), or repeat the gradient in the same direction " +"(spreadMethod=\"repeat\"), or repeat the gradient in alternating opposite " +"directions (spreadMethod=\"reflect\")" +msgstr "" +"Füllung entweder mit einfacher Farbe außerhalb des Farbverlaufsvektors " +"(spreadMethod=\"pad\"), mit Wiederholung des Farbverlaufs in die gleiche " +"Richtung (spreadMethod=\"repeat\"), oder Wiederholung in abwechselnd " +"entgegengesetzte Richtungen (spreadMethod=\"repeat\")" + +# CHECK +#: ../../po/../src/widgets/gradient-selector.cpp:165 +msgid "none" +msgstr "deaktiviert" + +#: ../../po/../src/widgets/gradient-selector.cpp:169 +msgid "reflected" +msgstr "alternierend" + +#: ../../po/../src/widgets/gradient-selector.cpp:173 +msgid "direct" +msgstr "direkt" + +#: ../../po/../src/widgets/gradient-selector.cpp:181 +msgid "Repeat:" +msgstr "Wiederholung:" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:217 +msgid "No gradients" +msgstr " Keine Farbverläufe" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:226 +msgid "Nothing selected" +msgstr " Nichts ausgewählt" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:237 +msgid "No gradients in selection" +msgstr "Kein Farbverlauf in der Auswahl" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:247 +msgid "Multiple gradients" +msgstr "Mehrere Farbverläufe" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:525 +msgid "" +"If the gradient is used by more than one object, create a copy of it for the " +"selected object(s)" +msgstr "" +"Von mehr als einem Objekt verwendete Farbverläufe werden als Kopie für die " +"ausgewählten Objekte angelegt" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:536 +msgid "Edit the stops of the gradient" +msgstr "Zwischenfarbe des Farbverlaufs bearbeiten" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:593 +#: ../../po/../src/widgets/toolbox.cpp:1103 +#: ../../po/../src/widgets/toolbox.cpp:1192 +#: ../../po/../src/widgets/toolbox.cpp:1485 +#: ../../po/../src/widgets/toolbox.cpp:1534 +#: ../../po/../src/widgets/toolbox.cpp:1766 +#: ../../po/../src/widgets/toolbox.cpp:1801 +#: ../../po/../src/widgets/toolbox.cpp:2331 +#: ../../po/../src/widgets/toolbox.cpp:2370 +msgid "New:" +msgstr "Neu:" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:606 +msgid "Create linear gradient" +msgstr "Linearen Farbverlauf erzeugen" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:620 +msgid "Create radial (elliptic or circular) gradient" +msgstr "Radialen (elliptischen oder kreisförmigen) Farbverlauf erzeugen" + +# CHECK +#: ../../po/../src/widgets/gradient-toolbar.cpp:635 +msgid "on" +msgstr "aktiv" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:648 +msgid "Create gradient in the fill" +msgstr "Farbverlauf für die Füllung erzeugen" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:662 +msgid "Create gradient in the stroke" +msgstr "Farbverlauf für die Kontur erzeugen" + +#. FIXME: implement averaging of all parameters for multiple selected stars +#. gtk_label_set_markup(GTK_LABEL(l), _("Average:")); +#. FIXME: implement averaging of all parameters for multiple selected +#. gtk_label_set_markup(GTK_LABEL(l), _("Average:")); +#: ../../po/../src/widgets/gradient-toolbar.cpp:676 +#: ../../po/../src/widgets/toolbox.cpp:1105 +#: ../../po/../src/widgets/toolbox.cpp:1124 +#: ../../po/../src/widgets/toolbox.cpp:1493 +#: ../../po/../src/widgets/toolbox.cpp:1518 +#: ../../po/../src/widgets/toolbox.cpp:1768 +#: ../../po/../src/widgets/toolbox.cpp:1787 +#: ../../po/../src/widgets/toolbox.cpp:2334 +#: ../../po/../src/widgets/toolbox.cpp:2354 +msgid "Change:" +msgstr "Ändern:" + +#: ../../po/../src/widgets/gradient-vector.cpp:269 +msgid "No gradients in document" +msgstr "Keine Farbverläufe im Dokument" + +#: ../../po/../src/widgets/gradient-vector.cpp:275 +msgid "No gradient selected" +msgstr "Kein Farbverlauf markiert" + +#: ../../po/../src/widgets/gradient-vector.cpp:532 +msgid "No stops in gradient" +msgstr "Keine Zwischenfarben im Farbverlauf" + +#. TRANSLATORS: "Stop" means: a "phase" of a gradient +#: ../../po/../src/widgets/gradient-vector.cpp:794 +msgid "Add stop" +msgstr "Zwischenfarbe hinzufügen" + +#: ../../po/../src/widgets/gradient-vector.cpp:797 +msgid "Add another control stop to gradient" +msgstr "Weitere Zwischenfarbe zum Verlauf hinzufügen" + +#: ../../po/../src/widgets/gradient-vector.cpp:799 +msgid "Delete stop" +msgstr "Zwischenfarbe löschen" + +#: ../../po/../src/widgets/gradient-vector.cpp:802 +msgid "Delete current control stop from gradient" +msgstr "Aktuelle Zwischenfarbe aus dem Farbverlauf löschen" + +#. Label +#: ../../po/../src/widgets/gradient-vector.cpp:813 +msgid "Offset:" +msgstr "Versatz:" + +#. TRANSLATORS: "Stop" means: a "phase" of a gradient +#: ../../po/../src/widgets/gradient-vector.cpp:858 +msgid "Stop Color" +msgstr "Zwischenfarbe" + +#: ../../po/../src/widgets/gradient-vector.cpp:887 +msgid "Gradient editor" +msgstr "Farbverlaufs-Editor" + +#: ../../po/../src/widgets/layer-selector.cpp:119 +msgid "Toggle current layer visibility" +msgstr "Sichbarkeit der aktuellen Ebene umschalten" + +#: ../../po/../src/widgets/layer-selector.cpp:139 +msgid "Lock or unlock current layer" +msgstr "Sperren oder Entsperren der aktuellen Ebene" + +#: ../../po/../src/widgets/layer-selector.cpp:142 +msgid "Current layer" +msgstr "Aktuelle Ebene" + +#: ../../po/../src/widgets/layer-selector.cpp:553 +msgid "(root)" +msgstr "(Wurzel)" + +#: ../../po/../src/widgets/paint-selector.cpp:182 +#: ../../po/../src/widgets/paint-selector.cpp:561 +msgid "No paint" +msgstr "Nicht zeichnen" + +#: ../../po/../src/widgets/paint-selector.cpp:184 +#: ../../po/../src/widgets/paint-selector.cpp:629 +msgid "Flat color" +msgstr "Einfache Farbe" + +#: ../../po/../src/widgets/paint-selector.cpp:186 +#: ../../po/../src/widgets/paint-selector.cpp:696 +msgid "Linear gradient" +msgstr "Linearer Farbverlauf" + +#: ../../po/../src/widgets/paint-selector.cpp:188 +#: ../../po/../src/widgets/paint-selector.cpp:699 +msgid "Radial gradient" +msgstr "Radialer Farbverlauf" + +#: ../../po/../src/widgets/paint-selector.cpp:192 +msgid "Unset paint (make it undefined so it can be inherited)" +msgstr "Farbe nicht setzen (damit sie nicht übernommen/vererbt werden kann)" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/painting.html#FillRuleProperty +#: ../../po/../src/widgets/paint-selector.cpp:204 +msgid "" +"Any path self-intersections or subpaths create holes in the fill (fill-rule: " +"evenodd)" +msgstr "" +"Überschneidungen desselben Pfades oder mit eingefügten Pfaden erzeugen " +"Löcher (Füllregel: evenodd)" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/painting.html#FillRuleProperty +#: ../../po/../src/widgets/paint-selector.cpp:215 +msgid "" +"Fill is solid unless a subpath is counterdirectional (fill-rule: nonzero)" +msgstr "" +"Vollständiges Füllen, außer ein eingefügter Pfad läuft entgegengesetzt " +"(Füllregel: nonzero)" + +#: ../../po/../src/widgets/paint-selector.cpp:528 +msgid "No objects" +msgstr "Keine Objekte" + +#: ../../po/../src/widgets/paint-selector.cpp:539 +msgid "Multiple styles" +msgstr "Mehrfachstile" + +#: ../../po/../src/widgets/paint-selector.cpp:550 +msgid "Paint is undefined" +msgstr "Farbe ist undefiniert" + +#: ../../po/../src/widgets/paint-selector.cpp:757 +msgid "No patterns in document" +msgstr "Keine Füllmuster im Dokument" + +#: ../../po/../src/widgets/paint-selector.cpp:872 +msgid "" +"Use Edit > Object(s) to Pattern to create a new pattern from " +"selection." +msgstr "" +"Benutze Bearbeiten » Objekte in Füllmuster umwandeln, um ein neues " +"Füllmuster vom selektierten Objekt zu erzeugen." + +#: ../../po/../src/widgets/select-toolbar.cpp:426 +msgid "Now stroke width is scaled when objects are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:428 +msgid "Now stroke width is not scaled when objects are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:436 +msgid "" +"Now rounded rectangle corners are scaled when rectangles are " +"scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:438 +msgid "" +"Now rounded rectangle corners are not scaled when rectangles " +"are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:446 +msgid "" +"Now gradients are transformed along with their objects when " +"those are transformed (moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:448 +msgid "" +"Now gradients remain fixed when objects are transformed " +"(moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:456 +msgid "" +"Now patterns are transformed along with their objects when " +"those are transformed (moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:458 +msgid "" +"Now patterns remain fixed when objects are transformed (moved, " +"scaled, rotated, or skewed)." +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:506 +msgid "select_toolbar|X" +msgstr "X" + +#: ../../po/../src/widgets/select-toolbar.cpp:506 +msgid "Horizontal coordinate of selection" +msgstr "Horizontale Coordinate der Auswahl" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:511 +msgid "select_toolbar|Y" +msgstr "Y" + +#: ../../po/../src/widgets/select-toolbar.cpp:511 +msgid "Vertical coordinate of selection" +msgstr "Vertikale Coordinate der Auswahl " + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:517 +msgid "select_toolbar|W" +msgstr "W" + +#: ../../po/../src/widgets/select-toolbar.cpp:517 +msgid "Width of selection" +msgstr "Breite der Auswahl" + +#: ../../po/../src/widgets/select-toolbar.cpp:525 +msgid "Change both width and height by the same proportion" +msgstr "Höhen- und Breitenverhältnis beibehalten" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:534 +msgid "select_toolbar|H" +msgstr "H" + +#: ../../po/../src/widgets/select-toolbar.cpp:534 +msgid "Height of selection" +msgstr "Höhe der Auswahl" + +#: ../../po/../src/widgets/sp-color-gtkselector.cpp:62 +msgid "System" +msgstr "System" + +#: ../../po/../src/widgets/sp-color-notebook.cpp:322 +msgid "RGBA_:" +msgstr "RGBA_:" + +#: ../../po/../src/widgets/sp-color-notebook.cpp:330 +msgid "Hexadecimal RGBA value of the color" +msgstr "Hexadezimaler RGBA-Wert der Farbe" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "RGB" +msgstr "RGB" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "HSL" +msgstr "HSL" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "CMYK" +msgstr "CMYK" + +#: ../../po/../src/widgets/sp-color-scales.cpp:397 +msgid "_R" +msgstr "_R" + +#: ../../po/../src/widgets/sp-color-scales.cpp:398 +#: ../../po/../src/widgets/sp-color-scales.cpp:399 +msgid "Red" +msgstr "Rot" + +#: ../../po/../src/widgets/sp-color-scales.cpp:400 +msgid "_G" +msgstr "_G" + +#: ../../po/../src/widgets/sp-color-scales.cpp:401 +#: ../../po/../src/widgets/sp-color-scales.cpp:402 +msgid "Green" +msgstr "Grün" + +#: ../../po/../src/widgets/sp-color-scales.cpp:403 +msgid "_B" +msgstr "_B" + +#: ../../po/../src/widgets/sp-color-scales.cpp:404 +#: ../../po/../src/widgets/sp-color-scales.cpp:405 +msgid "Blue" +msgstr "Blau" + +#. Label +#: ../../po/../src/widgets/sp-color-scales.cpp:406 +#: ../../po/../src/widgets/sp-color-scales.cpp:432 +#: ../../po/../src/widgets/sp-color-scales.cpp:463 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:141 +msgid "_A" +msgstr "_A" + +#: ../../po/../src/widgets/sp-color-scales.cpp:407 +#: ../../po/../src/widgets/sp-color-scales.cpp:408 +#: ../../po/../src/widgets/sp-color-scales.cpp:433 +#: ../../po/../src/widgets/sp-color-scales.cpp:434 +#: ../../po/../src/widgets/sp-color-scales.cpp:464 +#: ../../po/../src/widgets/sp-color-scales.cpp:465 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:151 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:163 +msgid "Alpha (opacity)" +msgstr "Alpha (Transparenz)" + +#: ../../po/../src/widgets/sp-color-scales.cpp:423 +msgid "_H" +msgstr "_H" + +#: ../../po/../src/widgets/sp-color-scales.cpp:424 +#: ../../po/../src/widgets/sp-color-scales.cpp:425 +msgid "Hue" +msgstr "Farbton" + +#: ../../po/../src/widgets/sp-color-scales.cpp:426 +msgid "_S" +msgstr "_S" + +#: ../../po/../src/widgets/sp-color-scales.cpp:427 +#: ../../po/../src/widgets/sp-color-scales.cpp:428 +msgid "Saturation" +msgstr "Sättigung" + +#: ../../po/../src/widgets/sp-color-scales.cpp:429 +msgid "_L" +msgstr "_L" + +#: ../../po/../src/widgets/sp-color-scales.cpp:430 +#: ../../po/../src/widgets/sp-color-scales.cpp:431 +msgid "Lightness" +msgstr "Helligkeit" + +#: ../../po/../src/widgets/sp-color-scales.cpp:451 +msgid "_C" +msgstr "_C" + +#: ../../po/../src/widgets/sp-color-scales.cpp:452 +#: ../../po/../src/widgets/sp-color-scales.cpp:453 +msgid "Cyan" +msgstr "Zyan" + +#: ../../po/../src/widgets/sp-color-scales.cpp:454 +msgid "_M" +msgstr "_M" + +#: ../../po/../src/widgets/sp-color-scales.cpp:455 +#: ../../po/../src/widgets/sp-color-scales.cpp:456 +msgid "Magenta" +msgstr "Magenta" + +#: ../../po/../src/widgets/sp-color-scales.cpp:457 +msgid "_Y" +msgstr "_Y" + +#: ../../po/../src/widgets/sp-color-scales.cpp:458 +#: ../../po/../src/widgets/sp-color-scales.cpp:459 +msgid "Yellow" +msgstr "Gelb" + +#: ../../po/../src/widgets/sp-color-scales.cpp:460 +msgid "_K" +msgstr "_K" + +#: ../../po/../src/widgets/sp-color-selector.cpp:71 +msgid "Unnamed" +msgstr "Unbenannt" + +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:68 +msgid "Wheel" +msgstr "Farbrad" + +#: ../../po/../src/widgets/sp-xmlview-attr-list.cpp:53 +msgid "Attribute" +msgstr "Attribut" + +#: ../../po/../src/widgets/sp-xmlview-attr-list.cpp:54 +msgid "Value" +msgstr "Wert" + +#: ../../po/../src/widgets/toolbox.cpp:424 +msgid "Insert new nodes into selected segments" +msgstr "Neue Knoten in den gewählten Segmenten einfügen" + +#: ../../po/../src/widgets/toolbox.cpp:426 +msgid "Delete selected nodes" +msgstr "Die gewählten Knoten löschen" + +#: ../../po/../src/widgets/toolbox.cpp:431 +msgid "Join paths at selected nodes" +msgstr "Pfade an den gewählten Knoten verbinden" + +#: ../../po/../src/widgets/toolbox.cpp:433 +msgid "Join paths at selected nodes with new segment" +msgstr "Pfade an den gewählten Knoten mit neuem Segment verbinden" + +# !!! +#: ../../po/../src/widgets/toolbox.cpp:436 +msgid "Split path between two non-endpoint nodes" +msgstr "Pfad zwischen zwei nicht Endpunkt-Knoten auftrennen" + +# !!! difference to "split"? +#: ../../po/../src/widgets/toolbox.cpp:439 +msgid "Break path at selected nodes" +msgstr "Pfad an den gewählten Knoten auftrennen" + +#: ../../po/../src/widgets/toolbox.cpp:444 +msgid "Make selected nodes corner" +msgstr "Die gewählten Knoten in Ecken umwandeln" + +#: ../../po/../src/widgets/toolbox.cpp:447 +msgid "Make selected nodes smooth" +msgstr "Die gewählten Knoten glätten" + +#: ../../po/../src/widgets/toolbox.cpp:450 +msgid "Make selected nodes symmetric" +msgstr "Die gewählten Knoten symmetrisch machen" + +#: ../../po/../src/widgets/toolbox.cpp:455 +msgid "Make selected segments lines" +msgstr "Die gewählten Abschnitte in Linien umwandeln" + +#: ../../po/../src/widgets/toolbox.cpp:458 +msgid "Make selected segments curves" +msgstr "Die gewählten Abschnitte in Kurven umwandeln" + +#: ../../po/../src/widgets/toolbox.cpp:1199 +msgid "Polygon" +msgstr "Polygon" + +#: ../../po/../src/widgets/toolbox.cpp:1206 +msgid "Regular polygon (with one handle) instead of a star" +msgstr "Gewöhnliches Vieleck (Polygon mit einem Anfasser) statt eines Sterns" + +#: ../../po/../src/widgets/toolbox.cpp:1218 +msgid "Corners:" +msgstr "Ecken:" + +#: ../../po/../src/widgets/toolbox.cpp:1218 +msgid "Number of corners of a polygon or star" +msgstr "Zahl der Ecken eines Polygons oder Sterns" + +#: ../../po/../src/widgets/toolbox.cpp:1228 +msgid "Spoke ratio:" +msgstr "Spitzenverhältnis:" + +#. TRANSLATORS: Tip radius of a star is the distance from the center to the farthest handle. +#. Base radius is the same for the closest handle. +#: ../../po/../src/widgets/toolbox.cpp:1231 +msgid "Base radius to tip radius ratio" +msgstr "Verhältnis vom Radius des Grundkörpers zum Radius der Spitzen" + +#: ../../po/../src/widgets/toolbox.cpp:1246 +msgid "Rounded:" +msgstr "Abrundung:" + +#: ../../po/../src/widgets/toolbox.cpp:1246 +msgid "How much rounded are the corners (0 for sharp)" +msgstr "Wie stark werden die Ecken abgerundet (0 für harte Kante)" + +#: ../../po/../src/widgets/toolbox.cpp:1256 +msgid "Randomized:" +msgstr "Zufallsänderung:" + +#: ../../po/../src/widgets/toolbox.cpp:1256 +msgid "Scatter randomly the corners and angles" +msgstr "Zufällige Variationen der Ecken und Winkel" + +#: ../../po/../src/widgets/toolbox.cpp:1269 +#: ../../po/../src/widgets/toolbox.cpp:1838 +#: ../../po/../src/widgets/toolbox.cpp:2061 +msgid "Defaults" +msgstr "Vorgaben" + +#: ../../po/../src/widgets/toolbox.cpp:1270 +#: ../../po/../src/widgets/toolbox.cpp:1839 +#: ../../po/../src/widgets/toolbox.cpp:2062 +msgid "" +"Reset shape parameters to defaults (use Inkscape Preferences > Tools to " +"change defaults)" +msgstr "" +"Die Parameter der Formen auf Standard zurücksetzen (Menü Datei » Inkscape-" +"Einstellungen » Werkzeuge, um die Vorgabeeinstellungen zu ändern)" + +#: ../../po/../src/widgets/toolbox.cpp:1544 +msgid "W:" +msgstr "W:" + +#: ../../po/../src/widgets/toolbox.cpp:1544 +msgid "Width of rectangle" +msgstr "Breite des Rechtecks" + +#: ../../po/../src/widgets/toolbox.cpp:1556 +msgid "Height of rectangle" +msgstr "Höhe des Rechtecks" + +#: ../../po/../src/widgets/toolbox.cpp:1568 +msgid "Rx:" +msgstr "Rx:" + +#: ../../po/../src/widgets/toolbox.cpp:1568 +msgid "Horizontal radius of rounded corners" +msgstr "Horizontaler Radius einer abgerundeten Ecke" + +#: ../../po/../src/widgets/toolbox.cpp:1578 +msgid "Ry:" +msgstr "Ry:" + +#: ../../po/../src/widgets/toolbox.cpp:1578 +msgid "Vertical radius of rounded corners" +msgstr "Vertikaler Radius einer abgerundeten Ecke" + +#: ../../po/../src/widgets/toolbox.cpp:1594 +msgid "Not rounded" +msgstr "Nicht abgerundet" + +#: ../../po/../src/widgets/toolbox.cpp:1596 +msgid "Make corners sharp" +msgstr "Spitze Ecken" + +#: ../../po/../src/widgets/toolbox.cpp:1805 +msgid "Turns:" +msgstr "Umdrehungen:" + +#: ../../po/../src/widgets/toolbox.cpp:1805 +msgid "Number of revolutions" +msgstr "Anzahl der Umdrehungen" + +#: ../../po/../src/widgets/toolbox.cpp:1815 +msgid "Divergence:" +msgstr "Abweichung:" + +#: ../../po/../src/widgets/toolbox.cpp:1815 +msgid "How much denser/sparser are outer revolutions; 1 = uniform" +msgstr "Dichte der äußeren Umdrehungen; 1 = gleichförmig" + +#: ../../po/../src/widgets/toolbox.cpp:1825 +msgid "Inner radius:" +msgstr "Innerer Radius:" + +#: ../../po/../src/widgets/toolbox.cpp:1825 +msgid "Radius of the innermost revolution (relative to the spiral size)" +msgstr "Radius der innersten Umdrehung (relativ zur Gesamtgröße der Spirale)" + +#: ../../po/../src/widgets/toolbox.cpp:1957 +msgid "The width of the calligraphic pen (relative to the visible canvas area)" +msgstr "" +"Breite des kalligraphischen Füllers (relativ zum sichtbaren " +"Dokumentausschnitt)" + +#: ../../po/../src/widgets/toolbox.cpp:1967 +msgid "Thinning:" +msgstr "Ausdünnung:" + +#: ../../po/../src/widgets/toolbox.cpp:1967 +msgid "" +"How much velocity thins the stroke (> 0 makes fast strokes thinner, < 0 " +"makes them broader, 0 makes width independent of velocity)" +msgstr "" +"Einfluß der Strichgeschwindigkeit auf die Linienbreite (> 0 macht schnelle " +"Strichzüge dünner, < 0 breiter, 0 unabhängig von der Geschwindigkeit)" + +#: ../../po/../src/widgets/toolbox.cpp:1980 +msgid "Angle:" +msgstr "Winkel:" + +#: ../../po/../src/widgets/toolbox.cpp:1980 +msgid "" +"The angle of the pen's nib (in degrees; 0 = horizontal; has no effect if " +"fixation = 0)" +msgstr "" +"Winkel der Stiftspitze (in Grad; 0 = horizontal; kein Einfluß, wenn " +"Fixierung: 0)" + +#: ../../po/../src/widgets/toolbox.cpp:1990 +msgid "Fixation:" +msgstr "Fixierung:" + +#: ../../po/../src/widgets/toolbox.cpp:1990 +msgid "" +"How fixed is the pen angle (0 = always perpendicular to stroke direction, 1 " +"= fixed)" +msgstr "" +"Fixierung des Stiftwinkels (0 = immer senkrecht zur Strichrichtung, 1 = fest)" + +#: ../../po/../src/widgets/toolbox.cpp:2003 +msgid "Mass:" +msgstr "Masse:" + +#: ../../po/../src/widgets/toolbox.cpp:2003 +msgid "How much inertia affects the movement of the pen" +msgstr "Größe der Trägheit, die den Stift beeinflußt" + +#. TRANSLATORS: "drag" means "resistance" here +#: ../../po/../src/widgets/toolbox.cpp:2014 +msgid "Drag:" +msgstr "Widerstand:" + +#: ../../po/../src/widgets/toolbox.cpp:2014 +msgid "How much resistance affects the movement of the pen" +msgstr "Größe des Widerstands, der den Stift beeinflußt" + +#: ../../po/../src/widgets/toolbox.cpp:2034 +msgid "Use the pressure of the input device to alter the width of the pen" +msgstr "" +"Druckempfindlichkeit des Eingabegeräts benutzen, um die Strichbreite des " +"Füllers zu beeinflussen" + +#: ../../po/../src/widgets/toolbox.cpp:2047 +msgid "Use the tilt of the input device to alter the angle of the pen's nib" +msgstr "" +"Neigungsempfindlichkeit des Eingabegeräts benutzen, um den Winkel der " +"Füllerspitze zu beeinflussen" + +#: ../../po/../src/widgets/toolbox.cpp:2374 +msgid "Start:" +msgstr "Anfang:" + +#: ../../po/../src/widgets/toolbox.cpp:2374 +msgid "The angle (in degrees) from the horizontal to the arc's start point" +msgstr "" +"Der Winkel (in Grad) von der Horizontalen bis zum Startpunkt des Bogens" + +#: ../../po/../src/widgets/toolbox.cpp:2384 +msgid "End:" +msgstr "Ende:" + +#: ../../po/../src/widgets/toolbox.cpp:2384 +msgid "The angle (in degrees) from the horizontal to the arc's end point" +msgstr "Der Winkel (in Grad) von der Horizontalen bis zum Endpunkt des Bogens" + +#: ../../po/../src/widgets/toolbox.cpp:2395 +msgid "Open arc" +msgstr "Offener Bogen" + +#: ../../po/../src/widgets/toolbox.cpp:2396 +msgid "" +"Switch between arc (unclosed shape) and segment (closed shape with two radii)" +msgstr "" +"Zwischen Bogen (ungeschlossene Form) und Segment (geschlossene Form mit zwei " +"Radien) umschalten" + +#: ../../po/../src/widgets/toolbox.cpp:2415 +msgid "Make whole" +msgstr "Schließen" + +#: ../../po/../src/widgets/toolbox.cpp:2417 +msgid "Make the shape a whole ellipse, not arc or segment" +msgstr "Die Form zur ganzen Ellipse anstelle eines Bogens oder Segments machen" + +#: ../../po/../src/widgets/toolbox.cpp:2644 +msgid "" +"When pressed, picks visible color without alpha and when not pressed, picks " +"color including its alpha" +msgstr "" +"Drücken übernimmt sichtbare Farbe mit Transparenz. Nicht drücken, um nur den " +"Farbwert ohne Transparenz zu übernehmen" + +#: ../../po/../src/widgets/toolbox.cpp:3039 +msgid "Make connectors avoid selected objects" +msgstr "Objektverbinder weichen den ausgewählten Objekten aus" + +#: ../../po/../src/widgets/toolbox.cpp:3043 +msgid "Make connectors ignore selected objects" +msgstr "Objektverbinder ignorieren die ausgewählten Objekte" + +#. +#. 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 : +#: ../share/extensions/addnodes.inx.h:1 +#, fuzzy +msgid "Add Nodes" +msgstr "Knoten" + +#: ../share/extensions/addnodes.inx.h:2 +msgid "Maximum Segment Length" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:1 +msgid "AI Input" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:2 ../share/extensions/ai_output.inx.h:2 +msgid "Adobe Illustrator (*.ai)" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:3 +msgid "Open files saved with Adobe Illustrator" +msgstr "" + +#: ../share/extensions/ai_output.inx.h:1 +#, fuzzy +msgid "AI Output" +msgstr "Ausgabe" + +#: ../share/extensions/ai_output.inx.h:3 +#, fuzzy +msgid "Write Adobe Illustrator" +msgstr "SVG-Vektorillustrator" + +#: ../share/extensions/dia.inx.h:1 +msgid "A diagram created with the program Dia" +msgstr "" + +#: ../share/extensions/dia.inx.h:2 +msgid "Dia Diagram (*.dia)" +msgstr "" + +#: ../share/extensions/dia.inx.h:3 +msgid "Dia Input" +msgstr "" + +#: ../share/extensions/dia.inx.h:4 +msgid "" +"In order to import Dia files, Dia itself must be installed. You can get Dia " +"at http://www.gnome.org/projects/dia/" +msgstr "" + +#: ../share/extensions/dia.inx.h:5 +msgid "" +"The dia2svg.sh script should be installed with your Inkscape distribution. " +"If you do not have it, there is likely to be something wrong with your " +"Inkscape installation." +msgstr "" + +#: ../share/extensions/dots.inx.h:1 +#, fuzzy +msgid "Connect the Dots" +msgstr "Objektverbinder" + +#: ../share/extensions/dots.inx.h:2 +#, fuzzy +msgid "Dot Size" +msgstr "Größe" + +#: ../share/extensions/dots.inx.h:3 +#, fuzzy +msgid "Font Size" +msgstr "Größe:" + +#: ../share/extensions/dropshadow.inx.h:1 +msgid "Color of shadow" +msgstr "" + +#: ../share/extensions/dropshadow.inx.h:2 +#, fuzzy +msgid "Dropshadow" +msgstr "Schatten der Zeichenfläche anzeigen" + +#: ../share/extensions/dxf_input.inx.h:1 +#: ../share/extensions/dxf_output.inx.h:1 +msgid "AutoCAD DXF (*.dxf)" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:2 +msgid "DXF Input" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:3 +msgid "Import AutoCAD's Document Exchange Format" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:4 +msgid "" +"dxf2svg may come with Inkscape, but is also at http://dxf-svg-convert." +"sourceforge.net/" +msgstr "" + +#: ../share/extensions/dxf_output.inx.h:2 +#, fuzzy +msgid "DXF Output" +msgstr "Ausgabe" + +#: ../share/extensions/dxf_output.inx.h:3 +msgid "DXF file written by pstoedit" +msgstr "" + +#: ../share/extensions/dxf_output.inx.h:4 +msgid "pstoedit must be installed to run see http://www.pstoedit.net/pstoedit" +msgstr "" + +#: ../share/extensions/embedimage.inx.h:1 +#, fuzzy +msgid "Embed Images" +msgstr "Bilder" + +#: ../share/extensions/eps_input.inx.h:1 +msgid "EPS Input" +msgstr "" + +#: ../share/extensions/eps_input.inx.h:2 +msgid "Encapsulated Postscript" +msgstr "" + +#: ../share/extensions/eps_input.inx.h:3 +msgid "Encapsulated Postscript (*.eps)" +msgstr "" + +#: ../share/extensions/epsi_output.inx.h:1 +#, fuzzy +msgid "EPSI Output" +msgstr "Ausgabe" + +#: ../share/extensions/epsi_output.inx.h:2 +msgid "Encapsulated Postscript Interchange (*.epsi)" +msgstr "" + +#: ../share/extensions/epsi_output.inx.h:3 +msgid "Encapsulated Postscript with a thumbnail" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:1 ../share/extensions/ffms.inx.h:1 +#: ../share/extensions/ffset.inx.h:1 ../share/extensions/ffss.inx.h:1 +#, fuzzy +msgid "Bridge Width" +msgstr "Linienstärke" + +#: ../share/extensions/ffmet.inx.h:2 ../share/extensions/ffms.inx.h:2 +msgid "First String Length" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:3 +msgid "FretFind Multi Length ET" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:4 ../share/extensions/ffms.inx.h:4 +#: ../share/extensions/ffset.inx.h:3 ../share/extensions/ffss.inx.h:3 +msgid "Fretboard Edges" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:5 ../share/extensions/ffms.inx.h:5 +msgid "Last String Length" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:6 ../share/extensions/ffms.inx.h:6 +#: ../share/extensions/ffset.inx.h:4 ../share/extensions/ffss.inx.h:4 +#, fuzzy +msgid "Number of Frets" +msgstr "Anzahl der Zeilen" + +#: ../share/extensions/ffmet.inx.h:7 ../share/extensions/ffms.inx.h:7 +#: ../share/extensions/ffset.inx.h:5 ../share/extensions/ffss.inx.h:5 +#, fuzzy +msgid "Number of Strings" +msgstr "Anzahl der Zeilen" + +#: ../share/extensions/ffmet.inx.h:8 ../share/extensions/ffms.inx.h:8 +#: ../share/extensions/ffset.inx.h:6 ../share/extensions/ffss.inx.h:6 +#, fuzzy +msgid "Nut Width" +msgstr "Breite" + +#: ../share/extensions/ffmet.inx.h:9 ../share/extensions/ffms.inx.h:10 +msgid "Perpendicular Distance" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:10 ../share/extensions/ffset.inx.h:7 +msgid "Scale Base (2 for Octave)" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:11 ../share/extensions/ffset.inx.h:9 +msgid "Tones in Scale" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:12 ../share/extensions/ffms.inx.h:12 +#: ../share/extensions/ffset.inx.h:10 ../share/extensions/ffss.inx.h:10 +msgid "px per Unit" +msgstr "" + +#: ../share/extensions/ffms.inx.h:3 +msgid "FretFind Multi Length Scala" +msgstr "" + +#: ../share/extensions/ffms.inx.h:9 ../share/extensions/ffss.inx.h:7 +msgid "Path to Scala *.scl File" +msgstr "" + +#: ../share/extensions/ffms.inx.h:11 +msgid "Tuning (scale step for each string seperated by semicolons)" +msgstr "" + +#: ../share/extensions/ffset.inx.h:2 +msgid "FretFind Single Length ET" +msgstr "" + +#: ../share/extensions/ffset.inx.h:8 ../share/extensions/ffss.inx.h:8 +msgid "Scale Length" +msgstr "" + +#: ../share/extensions/ffss.inx.h:2 +msgid "FretFind Single Length Scala" +msgstr "" + +#: ../share/extensions/ffss.inx.h:9 +msgid "Tuning (Scale step for each string seperated by semicolons)" +msgstr "" + +#: ../share/extensions/handles.inx.h:1 +#, fuzzy +msgid "Draw Handles" +msgstr "Freihandlinien zeichnen" + +#: ../share/extensions/interp.inx.h:1 +#, fuzzy +msgid "Duplicate Endpaths" +msgstr "Knoten duplizieren" + +#: ../share/extensions/interp.inx.h:2 +#, fuzzy +msgid "Exponent" +msgstr "Exportieren" + +#: ../share/extensions/interp.inx.h:3 +msgid "Interpolate" +msgstr "" + +#: ../share/extensions/interp.inx.h:4 +msgid "Interpolate Style (Experimental)" +msgstr "" + +#: ../share/extensions/interp.inx.h:5 +msgid "Interpolation Method" +msgstr "" + +#: ../share/extensions/interp.inx.h:6 +msgid "Interpolation Steps" +msgstr "" + +#: ../share/extensions/kochify.inx.h:1 +msgid "Kochify" +msgstr "" + +#: ../share/extensions/kochify_load.inx.h:1 +msgid "Kochify (Load)" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:1 +#, fuzzy +msgid "Angle" +msgstr "Winkel:" + +#: ../share/extensions/lindenmayer.inx.h:2 +msgid "Axiom" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:3 +#, fuzzy +msgid "Lindenmayer" +msgstr "Ebene umbenennen" + +#: ../share/extensions/lindenmayer.inx.h:4 +msgid "Order" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:5 +#, fuzzy +msgid "Rules" +msgstr "_Lineale" + +#: ../share/extensions/lindenmayer.inx.h:6 +#, fuzzy +msgid "Step" +msgstr "Schritte" + +#: ../share/extensions/motion.inx.h:1 +#, fuzzy +msgid "Direction" +msgstr "Beschreibung" + +#: ../share/extensions/motion.inx.h:2 +#, fuzzy +msgid "Magnitude" +msgstr "Magenta" + +#: ../share/extensions/motion.inx.h:3 +#, fuzzy +msgid "Motion" +msgstr "_Rotation" + +#: ../share/extensions/pdf_output.inx.h:1 +msgid "Adobe PDF (*.pdf)" +msgstr "" + +#: ../share/extensions/pdf_output.inx.h:2 +msgid "Adobe Portable Document Format" +msgstr "" + +#: ../share/extensions/pdf_output.inx.h:3 +#, fuzzy +msgid "PDF Output" +msgstr "Ausgabe" + +#: ../share/extensions/ps_input.inx.h:1 +#, fuzzy +msgid "Postscript" +msgstr "Hochformat" + +#: ../share/extensions/ps_input.inx.h:2 +msgid "Postscript (*.ps)" +msgstr "" + +#: ../share/extensions/ps_input.inx.h:3 +msgid "Postscript Input" +msgstr "" + +#: ../share/extensions/radiusrand.inx.h:1 +#, fuzzy +msgid "Radius" +msgstr "Radius:" + +#: ../share/extensions/radiusrand.inx.h:2 +#, fuzzy +msgid "Radius Randomize" +msgstr "Zufallsänderung:" + +#: ../share/extensions/radiusrand.inx.h:3 +msgid "Randomize Control Points" +msgstr "" + +#: ../share/extensions/radiusrand.inx.h:4 +#, fuzzy +msgid "Randomize Nodes" +msgstr "Zufallsänderung:" + +#: ../share/extensions/rtree.inx.h:1 +#, fuzzy +msgid "Initial Size" +msgstr "Bitmap-Größe" + +#: ../share/extensions/rtree.inx.h:2 +msgid "Minimum Size" +msgstr "" + +#: ../share/extensions/rtree.inx.h:3 +#, fuzzy +msgid "Random Tree" +msgstr "Zufallsänderung:" + +#: ../share/extensions/sk_input.inx.h:1 +msgid "A diagram created with the program Sketch" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:2 +msgid "Sketch Diagram (*.sk)" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:3 +msgid "Sketch Input" +msgstr "" + +#: ../share/extensions/straightseg.inx.h:1 +msgid "Behavior" +msgstr "" + +#: ../share/extensions/straightseg.inx.h:3 +msgid "Segment Straightener" +msgstr "" + +#: ../share/extensions/summersnight.inx.h:1 +msgid "Summer's Night" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:1 +#: ../share/extensions/svgz_output.inx.h:1 +#, fuzzy +msgid "Compressed Inkscape SVG (*.svgz)" +msgstr "Komprimierte SVG Dateien" + +#: ../share/extensions/svgz_input.inx.h:2 +#: ../share/extensions/svgz_output.inx.h:2 +msgid "Inkscape's native file format compressed with GZip" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:3 +msgid "SVGZ Input" +msgstr "" + +#: ../share/extensions/svgz_output.inx.h:3 +#, fuzzy +msgid "SVGZ Output" +msgstr "Ausgabe" + +#: ../share/extensions/txt2svg.inx.h:1 +msgid "ASCII Text" +msgstr "" + +#: ../share/extensions/txt2svg.inx.h:2 +msgid "Text File (*.txt)" +msgstr "" + +#: ../share/extensions/txt2svg.inx.h:3 +#, fuzzy +msgid "Text Input" +msgstr "Text" + +#: ../share/extensions/wavy.inx.h:1 +msgid "Calculate first derivative numerically" +msgstr "" + +#: ../share/extensions/wavy.inx.h:2 +msgid "First derivative" +msgstr "" + +#: ../share/extensions/wavy.inx.h:3 +msgid "Function" +msgstr "" + +#: ../share/extensions/wavy.inx.h:4 +msgid "Function Plotter" +msgstr "" + +#: ../share/extensions/wavy.inx.h:5 +msgid "Nodes per period" +msgstr "" + +#: ../share/extensions/wavy.inx.h:6 +msgid "Periods (2*Pi each)" +msgstr "" + +#: ../share/extensions/whirl.inx.h:1 +msgid "Amount of Whirl" +msgstr "" + +#: ../share/extensions/whirl.inx.h:2 +#, fuzzy +msgid "Center X" +msgstr "Zentrum X:" + +#: ../share/extensions/whirl.inx.h:3 +#, fuzzy +msgid "Center Y" +msgstr "Zentrum Y:" + +#: ../share/extensions/whirl.inx.h:4 +#, fuzzy +msgid "Direction of Rotation" +msgstr "Einladung ablehnen" + +#: ../share/extensions/whirl.inx.h:5 +msgid "Whirl" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:1 +msgid "A popular graphics file format for clipart" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:2 +msgid "Windows Metafile (*.wmf)" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:3 +msgid "Windows Metafile Input" +msgstr "" + +#~ msgid "Custom canvas" +#~ msgstr "Benutzerdefinierte Zeichenfläche" + +#~ msgid "Current style" +#~ msgstr "Aktueller Stil" + +#~ msgid "" +#~ "Current style is updated every time you change the style of any object " +#~ "(its fill, stroke, transparency, etc.)" +#~ msgstr "" +#~ "Der aktuelle Stil wird immer aktualisiert, wenn die sich Eigenschaften " +#~ "eines Objektes ändern (Füllung, Kontur, Transparenz, etc)" + +#~ msgid "Arrange Objects" +#~ msgstr "Objekte Anordnen" + +#~ msgid "deg" +#~ msgstr "Grad" + +#~ msgid "" +#~ "%s is not a valid preferences file.\n" +#~ "%s" +#~ msgstr "" +#~ "%s ist keine gültige Einstellungsdatei.\n" +#~ "%s" + +#~ msgid "" +#~ "Inkscape will run with default settings.\n" +#~ "New settings will not be saved." +#~ msgstr "" +#~ "Inkscape läuft mit den Vorgabeeinstellungen.\n" +#~ "Neue Einstellungen werden nicht gespeichert." + +#~ msgid "_Credits" +#~ msgstr "_Mitwirkende" + +#~ msgid "Grab sensitivity" +#~ msgstr "Entfernung zum Erfassen" + +#~ msgid "Click/drag threshold" +#~ msgstr "Schwellwert für Klicken/Ziehen:" + +#~ msgid "Mouse wheel scrolls by" +#~ msgstr "Mausrad rollt um" + +#~ msgid "Scroll by" +#~ msgstr "Rolle um" + +#~ msgid "Acceleration" +#~ msgstr "Beschleunigung" + +#~ msgid "Speed" +#~ msgstr "Geschwindigkeit" + +#~ msgid "Threshold" +#~ msgstr "Schwellwert" + +#~ msgid "Arrow keys move by" +#~ msgstr "Pfeiltasten bewegen um" + +#~ msgid "> and < scale by" +#~ msgstr "> und < skalieren um" + +#~ msgid "Inset/Outset by" +#~ msgstr "Schrumpfen/Ausweiten um:" + +# !!! need %s +#~ msgid "Rotation snaps every" +#~ msgstr "Rotation rastet ein alle" + +#~ msgid "Zoom in/out by" +#~ msgstr "Zoomfaktor vergrößern/verringern um" + +#~ msgid "Transform" +#~ msgstr "Transformation" + +#~ msgid "Rotate _90 deg CW" +#~ msgstr "Um 90 Grad nach _rechts drehen" + +#~ msgid "Rotate 9_0 deg CCW" +#~ msgstr "Um 90 Grad nach _links drehen" + +#~ msgid "Flip selection horizontally" +#~ msgstr "Die gewählten Objekte horizontal spiegeln" + +#~ msgid "Flip selection vertically" +#~ msgstr "Die gewählten Objekte vertikal spiegeln" + +# !!! span outside of translatable string! +#~ msgid "" +#~ "%1 has invited you to a " +#~ "whiteboard session.\n" +#~ "\n" +#~ msgstr "" +#~ "%1 hat Sie zu einer " +#~ "Whiteboard-Sitzung eingeladen.\n" +#~ "\n" + +#~ msgid "" +#~ "Accepting the invitation in the active document will cause your current " +#~ "changes to be lost. Would you like to accept %1's invitation in " +#~ "the active document, or would you like to accept the invitation in a new " +#~ "document?" +#~ msgstr "" +#~ "Wenn Sie die Einladung für das aktive Dokument annehmen, dann gehen Ihre " +#~ "aktuellen Änderungen verloren. Möchten Sie die Einladung von %1 " +#~ "für das aktive Dokument annehmen, oder möchten Sie die Einladung zu einem " +#~ "neuen Dokument annehmen?" + +# !!! remove span +# !!! is "Desktop" correct? Not "Document"? +#, fuzzy +#~ msgid "" +#~ "A new desktop could not be opened " +#~ "for a whiteboard session with %1.\n" +#~ "\n" +#~ "Would you like to accept the whiteboard connection in the active document " +#~ "or refuse the invitation?" +#~ msgstr "" +#~ "Neuer Desktop konnte nicht für eine " +#~ "Whiteboard-Sitzung mit %1 erzeugt werden.\n" +#~ "\n" +#~ "Möchten Sie die Einladung für das aktive Dokument annehmen oder ablehnen?" + +#~ msgid "" +#~ "Node %p (name %s) is a special node, but it could not be found in the " +#~ "node tracker (possible unexpected duplicate?) Generating unique ID " +#~ "anyway." +#~ msgstr "" +#~ "Knoten %p (Name %s) ist ein spezieller Knoten, aber er konnte nicht im " +#~ "Knotenprotokoll gefunden werden - möglicherweise ein unerwartetes " +#~ "Duplikat? Generiere trotzdem eindeutige ID." + +#~ msgid "Could not read next message due to I/O error (error: %s)!" +#~ msgstr "" +#~ "Nächste Meldung konnte wegen E/A-Fehler (Fehler: %s) nicht gelesen werden!" + +#~ msgid "" +#~ "Could not read next message due to charset conversion error (error: %s)!" +#~ msgstr "" +#~ "Nächste Meldung konnte wegen Fehler beim Umwandeln des Zeichensatzes " +#~ "(Fehler: %s) nicht gelesen werden!" + +#~ msgid "Open one of the recently visited documents" +#~ msgstr "Eines der zuletzt geöffneten Dokumente öffnen" + +#~ msgid "" +#~ "Show or hide parts of the document window (differently for normal and " +#~ "fullscreen modes)" +#~ msgstr "" +#~ "Gesamtes Dokumentfenster oder Teile davon verbergen (unterschiedlich im " +#~ "normalen und bildfüllenden Modus)" + +#~ msgid "Interactive Inkscape tutorials" +#~ msgstr "Interaktive Inkscape Tutorien" + +#~ msgid "Modifying or Redistributing Inkscape" +#~ msgstr "Inkscape modifizieren oder weiterverbreiten" + +#~ msgid "Show license to modify and/or redistribute Inkscape: GNU GPL" +#~ msgstr "" +#~ "Zeige Lizenz, unter der Inkscape modifiziert und/oder weiterverbreitet " +#~ "werden darf: GNU GPL" + +#~ msgid "Edit" +#~ msgstr "Bearbeiten" + +#~ msgid "Add" +#~ msgstr "Hinzufügen" + +#~ msgid "" +#~ "Select one path object with selector first, then switch back to node tool." +#~ msgstr "" +#~ "Zuerst einen Pfad auswählen (F1), dann auf das Knotenwerkzeug (F2) " +#~ "umstellen." + +#~ msgid "C_reate" +#~ msgstr "Erstellen" + +#~ msgid "Exporting [%d × %d] %s" +#~ msgstr "Exportiere [%d × %d] %s" + +#~ msgid "Go to root" +#~ msgstr "Zur Dokumentenwurzel wechseln" + +#~ msgid "L" +#~ msgstr "L" + +#~ msgid "X" +#~ msgstr "X" + +#~ msgid "Y" +#~ msgstr "Y" + +#~ msgid "2×2" +#~ msgstr "2×2" + +#~ msgid "4×4" +#~ msgstr "4×4" + +#~ msgid "8×8" +#~ msgstr "8×8" + +#~ msgid "No of Rows" +#~ msgstr "Anzahl der Reihen" + +#~ msgid "Automatically scale Rows to fit selected objects." +#~ msgstr "" +#~ "Reihen automatisch auf die notwendige Größe für die gewählten Objekte " +#~ "skalieren." + +#~ msgid "Automatically scale Columns to fit selected objects." +#~ msgstr "" +#~ "Spalten automatisch auf die notwendige Größe für die gewählten Objekte " +#~ "skalieren" + +#~ msgid "points" +#~ msgstr "Punkte" + +#~ msgid "Unicode: %c%c%c%c" +#~ msgstr "Unicode: %c%c%c%c" + +#~ msgid " " +#~ msgstr " " + +#~ msgid "Sides:" +#~ msgstr "Seiten:" + +#~ msgid "R1:" +#~ msgstr "R1:" + +#~ msgid "R2:" +#~ msgstr "R2:" + +#~ msgid "ARG1:" +#~ msgstr "ARG1:" + +#~ msgid "ARG2:" +#~ msgstr "ARG2:" + +#~ msgid "Flatsides:" +#~ msgstr "Flachseiten:" + +#~ msgid "Radius X:" +#~ msgstr "Radius X:" + +#~ msgid "Radius Y:" +#~ msgstr "Radius Y:" + +#~ msgid "Start Angle:" +#~ msgstr "Anfangswinkel:" + +#~ msgid "End Angle:" +#~ msgstr "Endwinkel:" + +#~ msgid "Open:" +#~ msgstr "Öffnen:" + +#~ msgid "Expansion:" +#~ msgstr "Ausdehnung:" + +# CHECK +#~ msgid "Revolutions:" +#~ msgstr "Umdrehungen:" + +#~ msgid "Argument:" +#~ msgstr "Argument:" + +#~ msgid "T0:" +#~ msgstr "T0:" + +#~ msgid "RX:" +#~ msgstr "RX:" + +#~ msgid "RY:" +#~ msgstr "RY:" + +#~ msgid "Rectangle _Properties" +#~ msgstr "Rechteckseigenschaften" + +#~ msgid "Star _Properties" +#~ msgstr "Sterneigenschaften" + +#~ msgid "Ellipse _Properties" +#~ msgstr "Ellipsen-Eigenschaften" + +#~ msgid "Spiral _Properties" +#~ msgstr "Spiraleigenschaften" + +#~ msgid "Document Preferences" +#~ msgstr "D_okumenteneinstellungen..." + +#~ msgid "Extensions Editor" +#~ msgstr "Erweiterungseditor" + +#~ msgid "Preferences" +#~ msgstr " Einstellungen" + +#~ msgid "Layer Editor" +#~ msgstr "Ebeneneditor" + +#~ msgid "Text Properties" +#~ msgstr "Texteigenschaften" + +#~ msgid "Transformation" +#~ msgstr "Abbildungsmatrix" + +#~ msgid "_Export..." +#~ msgstr "_Exportieren..." + +#~ msgid "_Document Properties" +#~ msgstr "Dokumenteigenschaften" + +#~ msgid "In_kscape Preferences" +#~ msgstr "In_kscape-Einstellungen" + +#~ msgid "Select _Original Clone" +#~ msgstr "_Original Klon auswählen" + +#~ msgid "Tile" +#~ msgstr "Kachel" + +#~ msgid "Select A_ll" +#~ msgstr "_Alles auswählen" + +#~ msgid "Select Non_e" +#~ msgstr "Auswahl aufheben" + +#~ msgid "Zoom _In" +#~ msgstr "Ansichtsvergrößerung" + +#~ msgid "Zoom _Out" +#~ msgstr "Ansichtsverkleinerung" + +#~ msgid "1:_1 (100%)" +#~ msgstr "1:_1 (100%)" + +#~ msgid "1:_2 (50%)" +#~ msgstr "1:_2 (50%)" + +#~ msgid "2:1 (2_00%)" +#~ msgstr "2:1 (2_00%)" + +#~ msgid "Pre_vious" +#~ msgstr "_Vorheriger" + +#~ msgid "Nex_t" +#~ msgstr "_Nächster" + +#~ msgid "_Commands bar" +#~ msgstr "Befehlsleiste" + +#~ msgid "Tool Co_ntrols bar" +#~ msgstr "Werkzeugoptionsleiste" + +#~ msgid "_Tools bar" +#~ msgstr "Werkzeugleis_te" + +#~ msgid "R_ename Layer..." +#~ msgstr "Ebene umbenennen" + +#~ msgid "D_uplicate Layer" +#~ msgstr "Ebene duplizieren" + +#~ msgid "_Anchor Layer" +#~ msgstr "Ebene verankern" + +#~ msgid "Merge Do_wn" +#~ msgstr "Mit darunterliegender vereinen" + +#~ msgid "_Delete Layer" +#~ msgstr "Ebene löschen" + +#~ msgid "Select Ne_xt Layer" +#~ msgstr "Zur nächsten Ebene umschalten" + +#~ msgid "Select Pre_vious Layer" +#~ msgstr "Zur vorherigen Ebene umschalten" + +#~ msgid "Select To_p Layer" +#~ msgstr "Oberste Ebene wählen" + +#~ msgid "Select Botto_m Layer" +#~ msgstr "Unterste Ebene auswählen" + +#~ msgid "Move to Ne_w Layer" +#~ msgstr "Auf neue Ebene verschieben" + +#~ msgid "Move to Ne_xt Layer" +#~ msgstr "Auf nächste Ebene verschieben" + +#~ msgid "Move to Pre_vious Layer" +#~ msgstr "Zur vorherigen Ebene verschieben" + +#~ msgid "Move to To_p Layer" +#~ msgstr "Auf oberste Ebene verschieben" + +#~ msgid "Move to B_ottom Layer" +#~ msgstr "Auf unterste Ebene verschieben" + +#~ msgid "_Trace Bitmap..." +#~ msgstr "Bitmap _vektorisieren" + +#~ msgid "_Put Text on Path" +#~ msgstr "Text an Pfad ausrichten" + +#~ msgid "_Remove Text from Path" +#~ msgstr "Trenne Text von Pfad" + +#~ msgid "Arc" +#~ msgstr "Bogen" + +# !!! +#~ msgid "Freehand" +#~ msgstr "Freihandlinien" + +#~ msgid "Stroke" +#~ msgstr "Linienbreite" + +#~ msgid "Corners" +#~ msgstr "Ecken" + +#~ msgid "Delete" +#~ msgstr "_Löschen" + +#~ msgid "Join" +#~ msgstr "Verbinden" + +#~ msgid "Join Segment" +#~ msgstr "Segment verbinden" + +#~ msgid "Delete Segment" +#~ msgstr "Segment löschen" + +#~ msgid "Break" +#~ msgstr "Unterbrechen" + +#~ msgid "Symmetric" +#~ msgstr "symmetrisch" + +#~ msgid "Line" +#~ msgstr "Linie" + +#~ msgid "Curve" +#~ msgstr "Kurve" + +#~ msgid "New" +#~ msgstr "_Neu" + +#~ msgid "Revert to Saved" +#~ msgstr "Dokument zurücksetzen" + +#~ msgid "Save" +#~ msgstr "_Speichern" + +#~ msgid "Save As..." +#~ msgstr "Speichern _unter..." + +#~ msgid "Import..." +#~ msgstr "_Importieren..." + +#~ msgid "Export..." +#~ msgstr "Exportieren" + +#~ msgid "Print..." +#~ msgstr "_Drucken..." + +#~ msgid "Document properties (Shift+Ctrl+D)" +#~ msgstr "Dokumenteigenschaften (Umschalt+Strg+D)" + +#~ msgid "Global Inkscape preferences (Shift+Ctrl+P)" +#~ msgstr "Globale Einstellungen für Inkscape (Umschalt+Strg+P)" + +#~ msgid "Undo" +#~ msgstr "_Rückgängig" + +# !!! "Wiederherstellen" war Original, "Wiederholen" ist aus Abiword +#~ msgid "Redo" +#~ msgstr "_Wiederherstellen" + +#~ msgid "Cut" +#~ msgstr "A_usschneiden" + +#~ msgid "Copy" +#~ msgstr "_Kopieren" + +#~ msgid "Duplicate selected object(s) (Ctrl+D)" +#~ msgstr "Die gewählten Objekte duplizieren (Strg+D)" + +#~ msgid "Clone selected object (Alt+D)" +#~ msgstr "Die gewählten Objekte klonen (Alt+D)" + +#~ msgid "Unlink clone from its original (Shift+Alt+D)" +#~ msgstr "Verknüpfung des Klons zum Original entfernen (Umschalt+Alt+D)" + +#~ msgid "XML Editor dialog (Shift+Ctrl+X)" +#~ msgstr "XML Editor Dialog (Umschalt+Strg+X)" + +#~ msgid "Zoom in (+)" +#~ msgstr "Ansicht vergrößern (+)" + +#~ msgid "Zoom out (-)" +#~ msgstr "Ansicht verkleinern (-)" + +#~ msgid "Zoom to 1:1 (100%) (1)" +#~ msgstr "Größenfaktor auf 1:1 (100%) setzen (1)" + +#~ msgid "Zoom to 1:2 (50%) (2)" +#~ msgstr "Größenfaktor auf 1:2 (50%) setzen (2)" + +#~ msgid "Zoom to 2:1 (200%) (0)" +#~ msgstr "Größenfaktor auf 2:1 (200%) setzen (0)" + +#~ msgid "Zoom to fit selection in window (3)" +#~ msgstr "Größenfaktor der Auswahl ans Fenster anpassen (3)" + +#~ msgid "Zoom to fit drawing in window (4)" +#~ msgstr "Größenfaktor der Zeichnung ans Fenster anpassen (4)" + +#~ msgid "Zoom to fit page in window (5)" +#~ msgstr "Größenfaktor der Seite ans Fenster anpassen" + +#~ msgid "Zoom to fit page width in window (6)" +#~ msgstr "Größenfaktor der Seitenbreite ans Fenster anpassen" + +#~ msgid "Previous zoom (from history of zooms) (`)" +#~ msgstr "" +#~ "Vorherigen Größenfaktor einstellen - aus der Liste früherer Faktoren (`)" + +#~ msgid "Next zoom (from history of zooms) (Shift+`)" +#~ msgstr "" +#~ "Nächsten Größenfaktor einstellen - aus der Liste früherer Faktoren " +#~ "(Umschalt+`)" + +#~ msgid "Fill and Stroke dialog (Shift+Ctrl+F)" +#~ msgstr "Füllungs- und Liniendialog (Shift+Strg+F)" + +#~ msgid "Group selected objects (Ctrl+G)" +#~ msgstr "Gewählte Objekte gruppieren (Strg+G)" + +#~ msgid "Ungroup selected group(s) (Ctrl+U)" +#~ msgstr "Gruppierung ausgewählter Gruppe(n) aufheben (Strg+U)" + +#~ msgid "Raise selection up one step (PgUp)" +#~ msgstr "Ausgewählte Objekte eine Stufe nach oben anheben (BildHoch)" + +#~ msgid "Lower selection down one step (PgDn)" +#~ msgstr "Ausgewählte Objekte eine Stufe nach unten absenken (BildRunter)" + +#~ msgid "Raise selection to top (Home)" +#~ msgstr "Ausgewählte Objekte nach ganz oben anheben (POS1)" + +#~ msgid "Lower selection to bottom (End)" +#~ msgstr "Ausgewählte Objekte nach ganz unten absenken (ENDE)" + +#~ msgid "Move selection to new layer" +#~ msgstr "Ausgewählte Objekte einer neuen Ebene zuweisen" + +#~ msgid "Move selection to next layer" +#~ msgstr "Auswahl in die nächste Ebene verschieben" + +#~ msgid "Move selection to previous layer" +#~ msgstr "Auswahl in die vorherige Ebene verschieben" + +#~ msgid "Move selection to top layer" +#~ msgstr "Auswahl in die oberste Ebene verschieben" + +#~ msgid "Move selection to bottom layer" +#~ msgstr "Auswahl in die unterste Ebene verschieben" + +#~ msgid "Rotate selection 90° clockwise (Shift+Ctrl+Right)" +#~ msgstr "" +#~ "Ausgewählte Objekte um 90 Grad im Uhrzeigersinn drehen (Umschalt+Strg" +#~ "+RECHTS)" + +#~ msgid "Rotate selection 90° counter-clockwise (Shift+Ctrl+Left)" +#~ msgstr "" +#~ "Ausgewählte Objekte um 90 Grad gegen Uhrzeigersinn drehen (Umschalt+Strg" +#~ "+LINKS)" + +#~ msgid "Flip selection horizontally (H)" +#~ msgstr "Auswahl horizontal spiegeln (H)" + +#~ msgid "Flip selection vertically (V)" +#~ msgstr "Auswahl vertikal spiegeln (V)" + +#~ msgid "Align and Distribute dialog (Shift+Ctrl+A)" +#~ msgstr "Anordnen- und Abstände-Dialog (Umschalt+Strg+A)" + +#~ msgid "Convert selected object(s) to path(s) (Shift+Ctrl+C)" +#~ msgstr "Ausgewählte Objekte in Pfade umwandeln (Strg+Alt+C)" + +#~ msgid "Convert selected stroke(s) to path(s) (Ctrl+Alt+C)" +#~ msgstr "Ausgewählte Linien in Pfade umwandeln (Strg+Alt+C)" + +#~ msgid "Cl_eanup" +#~ msgstr "_Säubern" + +#~ msgid "Text and Font dialog (Shift+Ctrl+T)" +#~ msgstr "Text- und Schrift-Dialog (Umschalt+Strg+T)" + +#~ msgid "Node tool" +#~ msgstr "Knoten bearbeiten" + +#~ msgid "Zoom tool" +#~ msgstr "Größenfaktor" + +#~ msgid "Rectangle tool" +#~ msgstr "Rechteck" + +#~ msgid "Arc tool" +#~ msgstr "Bogen" + +#~ msgid "Star tool" +#~ msgstr "Größenfaktor" + +#~ msgid "Spiral tool" +#~ msgstr "Spirale" + +#~ msgid "Freehand tool" +#~ msgstr "Freihandlinie" + +#~ msgid "Pen tool" +#~ msgstr "Füller" + +#~ msgid "Calligraphy tool" +#~ msgstr "Kalligraphie" + +#~ msgid "Dropper tool" +#~ msgstr "Ableger" + +#~ msgid "When scaling objects, scale stroke width by same proportion" +#~ msgstr "" +#~ "Wenn Objekte skaliert werden, dann wird die Linienbreite ebenso " +#~ "mitskaliert." + +#~ msgid "When scaling rectangles, scale radii of rounded corners" +#~ msgstr "" +#~ "Wenn Rechtecke skaliert werden, dann werden die Radien von abgerundeten " +#~ "Ecken ebenso mitskaliert." + +#~ msgid "Transform gradients (in fill or stroke) along with objects" +#~ msgstr "" +#~ "Gradienten (in Füllung oder Linie) zusammen mit den Objekten " +#~ "transformieren" + +#~ msgid "Transform patterns (in fill or stroke) along with objects" +#~ msgstr "" +#~ "Muster (in Füllung oder Linie) zusammen mit den Objekten transformieren" + +#~ msgid "Delete segment between two nodes" +#~ msgstr "Abschnitt zwischen zwei Knoten löschen" + +#~ msgid "URI:" +#~ msgstr "URI" + +#~ msgid "Select All in All Layers" +#~ msgstr "Alles in allen Ebenen auswählen" + +#~ msgid "Invert Selection" +#~ msgstr "Auswahl umkehren" + +#~ msgid "Clean up selected path(s)" +#~ msgstr "Ausgewählte Pfade säubern" + +#~ msgid "_Scripts..." +#~ msgstr "_Skripte..." + +#~ msgid "Align and Distribute" +#~ msgstr "_Anordnen und Abstände ausgleichen..." + +#~ msgid "Align and Distribute Dialog" +#~ msgstr "Anordnen- und Abstände-Dialog" + +#~ msgid "Export Dialog" +#~ msgstr "Exportieren-Dialog" + +#~ msgid "Extension Editor Dialog" +#~ msgstr "Erweiterungseditor Dialog" + +#~ msgid "Fill and Stroke Dialog" +#~ msgstr "Füllung- und Liniendialog" + +#~ msgid "Find Dialog" +#~ msgstr "Suchen-Dialog" + +#~ msgid "Inkscape Preferences" +#~ msgstr "In_kscape-Einstellungen..." + +#~ msgid "Inkscape Preferences Dialog" +#~ msgstr "IInkscape-Einstellungsdialog" + +#~ msgid "Layer Editor Dialog" +#~ msgstr "Ebeneneditor-Dialog" + +#~ msgid "Text Properties Dialog" +#~ msgstr "Texteigenschaften-Dialog" + +#~ msgid "Transformation Dialog" +#~ msgstr "Transformationsdialog" + +#~ msgid "Tree Editor" +#~ msgstr "Baumeditor" + +#~ msgid "XML Editor Dialog" +#~ msgstr "XML-Editor-Dialog" + +#~ msgid "Row height:" +#~ msgstr "Höhe der Reihe:" + +#~ msgid "Column width:" +#~ msgstr "Spaltenbreite:" + +#~ msgid "Creating anchor at (%g,%g)" +#~ msgstr "Erzeuge Verankerung bei (%g,%g)" + +#~ msgid "" +#~ "Click to pick fill color, Shift+click to pick stroke color. " +#~ "Drag to pick the average color of an area." +#~ msgstr "" +#~ "Klicken nimmt die Füllfarbe auf, Umschalt+Klick nimmt " +#~ "Umrißfarbe auf. Ziehen wählt die Durchschnittsfarbe innerhalb des " +#~ "Radius." + +#~ msgid "EPS Output Settings" +#~ msgstr "EPS-Ausgabe-Einstellungen" + +#~ msgid "Make bounding box around full page" +#~ msgstr "Ziehe Umrandungsbox um die gesamte Seite" + +#~ msgid "" +#~ "Skew selection; with Shift to skew around the opposite side" +#~ msgstr "" +#~ "Verzerren der Auswahl; Umschalt verzerrt entlang der " +#~ "gegenüberliegenden Seite" + +# !!! +#~ msgid "Skew: %0.2f%% x %0.2f%%" +#~ msgstr "Verzerren %0.2f%% × %0.2f%%" + +#~ msgid "Inkscape" +#~ msgstr "Inkscape" + +#~ msgid "Left side of aligned objects to left side of anchor" +#~ msgstr "" +#~ "Linke Seite der ausgerichteten Objekte an rechter Seite der Verankerung" + +#~ msgid "Right side of aligned objects to right side of anchor" +#~ msgstr "" +#~ "Rechte Seiten der ausgerichteten Objekte an rechter Seite der Verankerung" + +#~ msgid "Top of aligned objects to top of anchor" +#~ msgstr "Oberseiten der ausgerichteten Objekte an Oberseite der Verankerung" + +#~ msgid "Bottom of aligned objects to bottom of anchor" +#~ msgstr "" +#~ "Unterseiten der ausgerichteten Objekte an Unterseite der Verankerung" + +#~ msgid "Distribute top sides of objects at even distances" +#~ msgstr "Abstand zwischen Objektoberseiten ausgleichen" + +#~ msgid "Per row:" +#~ msgstr "Pro Reihe:" + +#~ msgid "Per column:" +#~ msgstr "Pro Spalte:" + +#~ msgid "Alternate sign" +#~ msgstr "alternierendes Vorzeichen" + +#~ msgid "How much to randomize tile positions" +#~ msgstr "Stärke der Zufallsänderung bei der Kachelpositionierung" + +#~ msgid "Horizontal scale per each row" +#~ msgstr "Horizontale Skalierung für jede Reihe" + +#~ msgid "Vertical scale per each row" +#~ msgstr "Vertikale Skalierung pro Reihe" + +#~ msgid "Horizontal scale per each column" +#~ msgstr "Horizontale Skalierung für jede Spalte" + +#~ msgid "Vertical scale per each column" +#~ msgstr "Vertikale Skalierung pro Spalte" + +#~ msgid "Alternate the sign of the scale increment for each row or column" +#~ msgstr "" +#~ "Vorzeichen des Skalierungsfaktors bei jeder Reihe oder Spalte umkehren" + +#~ msgid "How much to randomize tile sizes" +#~ msgstr "Stärke der Zufallsänderung der Kachelgrößen" + +#~ msgid "How much to randomize tile rotation" +#~ msgstr "Stärke der Zufallsänderung der Rotation von Kacheln" + +#~ msgid "Dissolve:" +#~ msgstr "Auflösen:" + +#~ msgid "How much to randomize tile opacity" +#~ msgstr "Stärke der Zufallsänderung der Deckkraft von Kacheln" + +#~ msgid "Rows:" +#~ msgstr "Reihen:" + +#~ msgid "Minor grid line color:" +#~ msgstr "Farbe der Rasterlinien" + +#~ msgid "Grid color" +#~ msgstr "Rasterfarbe" + +#~ msgid "Grid emphasis color" +#~ msgstr "Rasterfarbe" + +#~ msgid "Background (also for export):" +#~ msgstr "Hintergrund (auch für das Exportieren)" + +#~ msgid "" +#~ "Pick the visible color under cursor, taking into account the page " +#~ "background and disregarding the transparency of objects" +#~ msgstr "" +#~ "Nehme die sichbare Farbe unter dem Cursor, die Hintergrundfarbe wird " +#~ "berücksichtigt und die Transparenz der Objekte ignoriert" + +#~ msgid "Pick objects' color (including alpha)" +#~ msgstr "Objektfarbe aufnehmen (inklusive Transparenz)" + +#~ msgid "" +#~ "Pick the actual color of object(s) under cursor, including their " +#~ "accumulated transparency" +#~ msgstr "" +#~ "Nehme die wirkliche Farbe der Objekte unter dem Cursor, ihre Transparenz " +#~ "wird zusammengerechnet " + +#~ msgid "Fill style" +#~ msgstr "Füllstil" + +#~ msgid "Fill:" +#~ msgstr "Füllung:" + +#~ msgid "" +#~ "Specifies the method of filling overlapping areas when an object " +#~ "intersects itself. With the \"winding fill\" method (fill-rule:nonzero), " +#~ "all overlapping areas are filled; with the \"alternating fill\" method " +#~ "(fill-rule:evenodd), every other of them is filled." +#~ msgstr "" +#~ "Gibt die Füll-Methode von Objekten an, dessen Pfade sich überschneiden. " +#~ "Die \"Gewundene\" Methode (fill-rule:nonzero) füllt alle Flächen. Bei der " +#~ "\"Alternierenden\" Methode (fill-rule:evenodd) bleiben überlappende " +#~ "Flächen leer." + +#~ msgid "winding" +#~ msgstr "gewunden" + +#~ msgid "alternating" +#~ msgstr "alternierend" + +#~ msgid "Update Properties" +#~ msgstr "Eigenschaften aktualisieren" + +#~ msgid "Label invalid" +#~ msgstr "Kennung ist ungültig" + +#~ msgid "" +#~ "You cannot group objects from different groups or layers." +#~ msgstr "" +#~ "Objekte aus unterschiedlichen Gruppen oder Ebenen können " +#~ "nicht gruppiert werden." + +#~ msgid "Messages Dialog" +#~ msgstr "Meldungen" + +#~ msgid "_V" +#~ msgstr "_V" + +#~ msgid "Value (brightness)" +#~ msgstr "Wert (Helligkeit)" + +#~ msgid "Switch to the previous layer in the document" +#~ msgstr "Zur vorherigen Ebene im Dokument umschalten" + +#~ msgid "executable" +#~ msgstr "ausführbare Datei" + +#~ msgid "extension" +#~ msgstr "Erweiterung" + +#~ msgid "plugin" +#~ msgstr "Plugin" + +#~ msgid "path" +#~ msgstr "Dateipfad" + +#~ msgid "absolute" +#~ msgstr " absolut zu " + +#~ msgid "" +#~ "0 out of %i node selected. Click, Shift+click, or drag " +#~ "around nodes to select.0 out of %i nodes selected. Click, " +#~ "Shift+click, or drag around nodes to select." +#~ msgstr "" +#~ "0 von %i Knoten ausgewählt. Klick, Umsch+Klick oder Ziehen, " +#~ "um Knoten auszuwählen.0 von %i Knoten ausgewählt. Klick, " +#~ "Umsch+Klick oder Ziehen, um Knoten auszuwählen." + +#~ msgid "Could not create sodipodi-svg-doc factory" +#~ msgstr "Die sodipodi-svg-doc-Fabrik konnte nicht erstellt werden" + +#~ msgid "SVG Files" +#~ msgstr "SVG Dateien" + +#~ msgid "Plain SVG" +#~ msgstr "Standard SVG" + +#~ msgid "Autodetect" +#~ msgstr "Automatisch erkennen" + +#~ msgid "Document not modified. No need to revert." +#~ msgstr "Dokument nicht verändert. Muss nicht zurücksetzen." + +#~ msgid "Make s_ensitive" +#~ msgstr "Empfindlich machen" + +#~ msgid "Make i_nsensitive" +#~ msgstr "U_nempfindlich machen" + +#~ msgid "" +#~ "Linked offset, %s by %f pt. Use Shift+D to look up original" +#~ msgstr "" +#~ "Verbundener Versatz, %s um %f pt. Umsch+D findet das " +#~ "Original" + +#~ msgid "" +#~ "Text on path (%s, %.5gpt). Use Shift+D to look up the path" +#~ msgstr "" +#~ "Text-Pfad (%s, %.5gpt). Ausgangspfad mit Umschalt finden" diff --git a/po/el.po b/po/el.po new file mode 100644 index 000000000..04d163bb0 --- /dev/null +++ b/po/el.po @@ -0,0 +1,11553 @@ +# Greek translation for sodipodi. +# Copyright (C) 2001 Free Software Foundation. +# Simos Xenitellis , 2001. +# +msgid "" +msgstr "" +"Project-Id-Version: sodipodi 0.25\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2005-12-04 11:51-0800\n" +"PO-Revision-Date: 2001-12-28 21:07+0000\n" +"Last-Translator: Simos Xenitellis \n" +"Language-Team: Greek \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../inkscape.desktop.in.h:1 +msgid "Create and edit Scalable Vector Graphics images" +msgstr "" + +#: ../inkscape.desktop.in.h:2 +msgid "Inkscape SVG Vector Illustrator" +msgstr "" + +#: ../../po/../src/arc-context.cpp:350 +msgid "" +"Ctrl: make circle or integer-ratio ellipse, snap arc/segment angle" +msgstr "" + +#: ../../po/../src/arc-context.cpp:351 ../../po/../src/rect-context.cpp:388 +msgid "Shift: draw around the starting point" +msgstr "" + +#: ../../po/../src/arc-context.cpp:413 +#: ../../po/../src/connector-context.cpp:493 +#: ../../po/../src/dyna-draw-context.cpp:506 +#: ../../po/../src/pen-context.cpp:329 ../../po/../src/pencil-context.cpp:208 +#: ../../po/../src/rect-context.cpp:452 ../../po/../src/spiral-context.cpp:421 +#: ../../po/../src/star-context.cpp:427 +msgid "Current layer is hidden. Unhide it to be able to draw on it." +msgstr "" + +#: ../../po/../src/arc-context.cpp:417 +#: ../../po/../src/connector-context.cpp:497 +#: ../../po/../src/dyna-draw-context.cpp:510 +#: ../../po/../src/pen-context.cpp:336 ../../po/../src/pencil-context.cpp:212 +#: ../../po/../src/rect-context.cpp:456 ../../po/../src/spiral-context.cpp:426 +#: ../../po/../src/star-context.cpp:431 +msgid "Current layer is locked. Unlock it to be able to draw on it." +msgstr "" + +#: ../../po/../src/arc-context.cpp:496 +#, c-format +msgid "" +"Ellipse: %s × %s; with Ctrl to make circle or integer-" +"ratio ellipse; with Shift to draw around the starting point" +msgstr "" + +#: ../../po/../src/connector-context.cpp:518 +#, fuzzy +msgid "Creating new connector" +msgstr "Έγγραφο" + +#: ../../po/../src/connector-context.cpp:939 +#, fuzzy +msgid "Finishing connector" +msgstr "Γροιλανδία" + +#: ../../po/../src/connector-context.cpp:1108 +msgid "Connection point: click or drag to create a new connector" +msgstr "" + +#: ../../po/../src/connector-context.cpp:1185 +msgid "Connector endpoint: drag to reroute or connect to new shapes" +msgstr "" + +#: ../../po/../src/connector-context.cpp:1278 +#, fuzzy +msgid "Select at least one non-connector object." +msgstr "Διαγραφή επιλεγμένων αντικειμένων" + +#: ../../po/../src/desktop-events.cpp:238 +#, c-format +msgid "%s at %s" +msgstr "" + +#. TRANSLATORS: This string appears when double-clicking on a guide. +#. This is the distance by which the guide is to be moved. +#: ../../po/../src/desktop-events.cpp:277 +#, fuzzy +msgid " relative by " +msgstr "κάθετο" + +#. TRANSLATORS: This string appears when double-clicking on a guide. +#. This is the target location where the guide is to be moved. +#: ../../po/../src/desktop-events.cpp:282 +#: ../../po/../src/desktop-events.cpp:395 +#, fuzzy +msgid " absolute to " +msgstr "Εκτός χρήσης" + +#. create dialog +#: ../../po/../src/desktop-events.cpp:348 +#, fuzzy +msgid "Guideline" +msgstr "Επιλογή χρώματος" + +#: ../../po/../src/desktop-events.cpp:432 +#, fuzzy, c-format +msgid "Move %s" +msgstr "Μετακίνηση" + +#: ../../po/../src/desktop.cpp:678 +msgid "No previous zoom." +msgstr "" + +#: ../../po/../src/desktop.cpp:703 +msgid "No next zoom." +msgstr "" + +# +#: ../../po/../src/dialogs/clonetiler.cpp:182 +#, fuzzy +msgid "Nothing selected." +msgstr "Επιλέχθησαν \"%s\"" + +#: ../../po/../src/dialogs/clonetiler.cpp:188 +msgid "More than one object selected." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:195 +#, c-format +msgid "Object has %d tiled clones." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:200 +msgid "Object has no tiled clones." +msgstr "" + +# +#: ../../po/../src/dialogs/clonetiler.cpp:865 +#, fuzzy +msgid "Select one object whose tiled clones to unclump." +msgstr "Διαγραφή επιλεγμένου αντικειμένου" + +# +#: ../../po/../src/dialogs/clonetiler.cpp:916 +#, fuzzy +msgid "Select one object whose tiled clones to remove." +msgstr "Διαγραφή επιλεγμένου αντικειμένου" + +# +#: ../../po/../src/dialogs/clonetiler.cpp:984 +#: ../../po/../src/selection-chemistry.cpp:1774 +#, fuzzy +msgid "Select an object to clone." +msgstr "Διαγραφή επιλεγμένου αντικειμένου" + +#: ../../po/../src/dialogs/clonetiler.cpp:990 +#: ../../po/../src/selection-chemistry.cpp:1780 +msgid "" +"If you want to clone several objects, group them and clone the " +"group." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1484 +msgid "Per row:" +msgstr "" + +# +#: ../../po/../src/dialogs/clonetiler.cpp:1497 +#, fuzzy +msgid "Per column:" +msgstr "Επιλέχθησαν \"%s\"" + +# +#: ../../po/../src/dialogs/clonetiler.cpp:1505 +#, fuzzy +msgid "Randomize:" +msgstr "Επιλέχθησαν \"%s\"" + +#: ../../po/../src/dialogs/clonetiler.cpp:1656 +#, fuzzy +msgid "_Symmetry" +msgstr "Χρήση Μετρικού Συστήματος" + +#. TRANSLATORS: For the following 17 symmetry groups, see +#. * http://www.bib.ulb.ac.be/coursmath/doc/17.htm (visual examples); +#. * http://www.clarku.edu/~djoyce/wallpaper/seventeen.html (English vocabulary); or +#. * http://membres.lycos.fr/villemingerard/Geometri/Sym1D.htm (French vocabulary). +#. +#: ../../po/../src/dialogs/clonetiler.cpp:1664 +msgid "Select one of the 17 symmetry groups for the tiling" +msgstr "" + +#. TRANSLATORS: "translation" means "shift" / "displacement" here. +#: ../../po/../src/dialogs/clonetiler.cpp:1675 +msgid "P1: simple translation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1676 +msgid "P2: 180° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1677 +msgid "PM: reflection" +msgstr "" + +#. TRANSLATORS: "glide reflection" is a reflection and a translation combined. +#. For more info, see http://mathforum.org/sum95/suzanne/symsusan.html +#: ../../po/../src/dialogs/clonetiler.cpp:1680 +msgid "PG: glide reflection" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1681 +msgid "CM: reflection + glide reflection" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1682 +msgid "PMM: reflection + reflection" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1683 +msgid "PMG: reflection + 180° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1684 +msgid "PGG: glide reflection + 180° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1685 +msgid "CMM: reflection + reflection + 180° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1686 +msgid "P4: 90° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1687 +msgid "P4M: 90° rotation + 45° reflection" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1688 +msgid "P4G: 90° rotation + 90° reflection" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1689 +msgid "P3: 120° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1690 +msgid "P31M: reflection + 120° rotation, dense" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1691 +msgid "P3M1: reflection + 120° rotation, sparse" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1692 +msgid "P6: 60° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1693 +msgid "P6M: reflection + 60° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1721 +msgid "S_hift" +msgstr "" + +# +#. TRANSLATORS: "shift" means: the tiles will be shifted (offset) horizontally by this amount +#: ../../po/../src/dialogs/clonetiler.cpp:1731 +#, fuzzy, no-c-format +msgid "Shift X:" +msgstr "Αλλαγή" + +#: ../../po/../src/dialogs/clonetiler.cpp:1739 +#, no-c-format +msgid "Horizontal shift per row (in % of tile width)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1747 +#, no-c-format +msgid "Horizontal shift per column (in % of tile width)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1754 +msgid "Randomize the horizontal shift by this percentage" +msgstr "" + +# +#. TRANSLATORS: "shift" means: the tiles will be shifted (offset) vertically by this amount +#: ../../po/../src/dialogs/clonetiler.cpp:1764 +#, fuzzy, no-c-format +msgid "Shift Y:" +msgstr "Αλλαγή" + +#: ../../po/../src/dialogs/clonetiler.cpp:1772 +#, no-c-format +msgid "Vertical shift per row (in % of tile height)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1780 +#, no-c-format +msgid "Vertical shift per column (in % of tile height)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1787 +msgid "Randomize the vertical shift by this percentage" +msgstr "" + +# +#: ../../po/../src/dialogs/clonetiler.cpp:1795 +#, fuzzy +msgid "Exponent:" +msgstr "Αλλαγή" + +#: ../../po/../src/dialogs/clonetiler.cpp:1802 +msgid "Whether rows are spaced evenly (1), converge (<1) or diverge (>1)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1809 +msgid "Whether columns are spaced evenly (1), converge (<1) or diverge (>1)" +msgstr "" + +#. TRANSLATORS: "Alternate" is a verb here +#: ../../po/../src/dialogs/clonetiler.cpp:1817 +#: ../../po/../src/dialogs/clonetiler.cpp:1907 +#: ../../po/../src/dialogs/clonetiler.cpp:1966 +#: ../../po/../src/dialogs/clonetiler.cpp:2022 +#: ../../po/../src/dialogs/clonetiler.cpp:2153 +msgid "Alternate:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1823 +msgid "Alternate the sign of shifts for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1828 +msgid "Alternate the sign of shifts for each column" +msgstr "" + +# +#: ../../po/../src/dialogs/clonetiler.cpp:1837 +#, fuzzy +msgid "Sc_ale" +msgstr "Κλιμάκωση" + +# +#: ../../po/../src/dialogs/clonetiler.cpp:1845 +#, fuzzy +msgid "Scale X:" +msgstr "Αλλαγή" + +#: ../../po/../src/dialogs/clonetiler.cpp:1853 +#, fuzzy, no-c-format +msgid "Horizontal scale per row (in % of tile width)" +msgstr "οριζόντιο" + +#: ../../po/../src/dialogs/clonetiler.cpp:1861 +#, fuzzy, no-c-format +msgid "Horizontal scale per column (in % of tile width)" +msgstr "οριζόντιο" + +#: ../../po/../src/dialogs/clonetiler.cpp:1868 +msgid "Randomize the horizontal scale by this percentage" +msgstr "" + +# +#: ../../po/../src/dialogs/clonetiler.cpp:1876 +#, fuzzy +msgid "Scale Y:" +msgstr "Αλλαγή" + +#: ../../po/../src/dialogs/clonetiler.cpp:1884 +#, fuzzy, no-c-format +msgid "Vertical scale per row (in % of tile height)" +msgstr "Μερικό μικρό χαλάζι" + +#: ../../po/../src/dialogs/clonetiler.cpp:1892 +#, fuzzy, no-c-format +msgid "Vertical scale per column (in % of tile height)" +msgstr "Μερικό μικρό χαλάζι" + +#: ../../po/../src/dialogs/clonetiler.cpp:1899 +msgid "Randomize the vertical scale by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1913 +#, fuzzy +msgid "Alternate the sign of scales for each row" +msgstr "Μερικό μικρό χαλάζι" + +#: ../../po/../src/dialogs/clonetiler.cpp:1918 +#, fuzzy +msgid "Alternate the sign of scales for each column" +msgstr "Μερικό μικρό χαλάζι" + +#: ../../po/../src/dialogs/clonetiler.cpp:1927 +#, fuzzy +msgid "_Rotation" +msgstr "Επιλογή" + +# +#: ../../po/../src/dialogs/clonetiler.cpp:1935 +#, fuzzy +msgid "Angle:" +msgstr "Αλλαγή" + +#: ../../po/../src/dialogs/clonetiler.cpp:1943 +#, no-c-format +msgid "Rotate tiles by this angle for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1951 +#, no-c-format +msgid "Rotate tiles by this angle for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1958 +msgid "Randomize the rotation angle by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1972 +msgid "Alternate the rotation direction for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1977 +msgid "Alternate the rotation direction for each column" +msgstr "" + +# +#: ../../po/../src/dialogs/clonetiler.cpp:1985 +#, fuzzy +msgid "_Opacity" +msgstr "Διαφάνεια:" + +# +#: ../../po/../src/dialogs/clonetiler.cpp:1993 +#, fuzzy +msgid "Fade out:" +msgstr "Αλλαγή" + +#: ../../po/../src/dialogs/clonetiler.cpp:2000 +msgid "Decrease tile opacity by this percentage for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2007 +msgid "Decrease tile opacity by this percentage for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2014 +msgid "Randomize the tile opacity by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2028 +msgid "Alternate the sign of opacity change for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2033 +msgid "Alternate the sign of opacity change for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2041 +#, fuzzy +msgid "Co_lor" +msgstr "Χρώμα:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2046 +#, fuzzy +msgid "Initial color: " +msgstr " χρώμα" + +#: ../../po/../src/dialogs/clonetiler.cpp:2050 +msgid "Initial color of tiled clones" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2050 +msgid "" +"Initial color for clones (works only if the original has unset fill or " +"stroke)" +msgstr "" + +# +#: ../../po/../src/dialogs/clonetiler.cpp:2065 +#, fuzzy +msgid "H:" +msgstr "Αλλαγή" + +#: ../../po/../src/dialogs/clonetiler.cpp:2072 +msgid "Change the tile hue by this percentage for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2079 +msgid "Change the tile hue by this percentage for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2086 +msgid "Randomize the tile hue by this percentage" +msgstr "" + +# +#: ../../po/../src/dialogs/clonetiler.cpp:2095 +#, fuzzy +msgid "S:" +msgstr "Αλλαγή" + +#: ../../po/../src/dialogs/clonetiler.cpp:2102 +msgid "Change the color saturation by this percentage for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2109 +msgid "Change the color saturation by this percentage for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2116 +msgid "Randomize the color saturation by this percentage" +msgstr "" + +# +#: ../../po/../src/dialogs/clonetiler.cpp:2124 +#, fuzzy +msgid "L:" +msgstr "Αλλαγή" + +#: ../../po/../src/dialogs/clonetiler.cpp:2131 +msgid "Change the color lightness by this percentage for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2138 +msgid "Change the color lightness by this percentage for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2145 +msgid "Randomize the color lightness by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2159 +msgid "Alternate the sign of color changes for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2164 +msgid "Alternate the sign of color changes for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2172 +#, fuzzy +msgid "_Trace" +msgstr "Διακοπείσα σωλήνωση" + +#: ../../po/../src/dialogs/clonetiler.cpp:2179 +msgid "Trace the drawing under the tiles" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2183 +msgid "" +"For each clone, pick a value from the drawing in that clone's location and " +"apply it to the clone" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2197 +msgid "1. Pick from the drawing:" +msgstr "" + +#. ----Hbox2 +#: ../../po/../src/dialogs/clonetiler.cpp:2208 +#: ../../po/../src/dialogs/clonetiler.cpp:2355 +#: ../../po/../src/ui/dialog/tracedialog.cpp:445 +#, fuzzy +msgid "Color" +msgstr "Χρώμα:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2209 +msgid "Pick the visible color and opacity" +msgstr "" + +# +#: ../../po/../src/dialogs/clonetiler.cpp:2216 +#: ../../po/../src/dialogs/clonetiler.cpp:2365 +#: ../share/extensions/dropshadow.inx.h:3 +#, fuzzy +msgid "Opacity" +msgstr "Διαφάνεια:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2217 +msgid "Pick the total accumulated opacity" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2224 +msgid "R" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2225 +msgid "Pick the Red component of the color" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2232 +msgid "G" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2233 +msgid "Pick the Green component of the color" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2240 +msgid "B" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2241 +msgid "Pick the Blue component of the color" +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2250 +msgid "clonetiler|H" +msgstr "" + +# +#: ../../po/../src/dialogs/clonetiler.cpp:2251 +#, fuzzy +msgid "Pick the hue of the color" +msgstr "Διαλέξτε χρώμα" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2260 +msgid "clonetiler|S" +msgstr "" + +# +#: ../../po/../src/dialogs/clonetiler.cpp:2261 +#, fuzzy +msgid "Pick the saturation of the color" +msgstr "Διαλέξτε χρώμα" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2270 +msgid "clonetiler|L" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2271 +msgid "Pick the lightness of the color" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2281 +msgid "2. Tweak the picked value:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2291 +msgid "Gamma-correct:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2296 +msgid "Shift the mid-range of the picked value upwards (>0) or downwards (<0)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2303 +msgid "Randomize:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2308 +msgid "Randomize the picked value by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2315 +#, fuzzy +msgid "Invert:" +msgstr "ίντσα" + +#: ../../po/../src/dialogs/clonetiler.cpp:2319 +msgid "Invert the picked value" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2325 +msgid "3. Apply the value to the clones':" +msgstr "" + +# +#: ../../po/../src/dialogs/clonetiler.cpp:2335 +#, fuzzy +msgid "Presence" +msgstr "Προτιμίσεις Ναυτίλου" + +#: ../../po/../src/dialogs/clonetiler.cpp:2338 +msgid "" +"Each clone is created with the probability determined by the picked value in " +"that point" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2345 +#, fuzzy +msgid "Size" +msgstr "Γουϊνέα" + +#: ../../po/../src/dialogs/clonetiler.cpp:2348 +msgid "Each clone's size is determined by the picked value in that point" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2358 +msgid "" +"Each clone is painted by the picked color (the original must have unset fill " +"or stroke)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2368 +msgid "Each clone's opacity is determined by the picked value in that point" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2395 +msgid "How many rows in the tiling" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2415 +msgid "How many columns in the tiling" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2445 +msgid "Width of the rectangle to be filled" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2470 +msgid "Height of the rectangle to be filled" +msgstr "" + +# +#: ../../po/../src/dialogs/clonetiler.cpp:2485 +#, fuzzy +msgid "Rows, columns: " +msgstr "Αλλαγή" + +#: ../../po/../src/dialogs/clonetiler.cpp:2486 +msgid "Create the specified number of rows and columns" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2495 +#, fuzzy +msgid "Width, height: " +msgstr "Ύψος: " + +#: ../../po/../src/dialogs/clonetiler.cpp:2496 +msgid "Fill the specified width and height with the tiling" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2512 +#, fuzzy +msgid "Use saved size and position of the tile" +msgstr "Θέση" + +#: ../../po/../src/dialogs/clonetiler.cpp:2515 +msgid "" +"Pretend that the size and position of the tile are the same as the last time " +"you tiled it (if any), instead of using the current size" +msgstr "" + +# +#: ../../po/../src/dialogs/clonetiler.cpp:2539 +#, fuzzy +msgid " _Create " +msgstr "Αλλαγή" + +#: ../../po/../src/dialogs/clonetiler.cpp:2541 +msgid "Create and tile the clones of the selection" +msgstr "" + +#. TRANSLATORS: if a group of objects are "clumped" together, then they +#. are unevenly spread in the given amount of space - as shown in the +#. diagrams on the left in the following screenshot: +#. http://www.inkscape.org/screenshots/gallery/inkscape-0.42-CVS-tiles-unclump.png +#. So unclumping is the process of spreading a number of objects out more evenly. +#: ../../po/../src/dialogs/clonetiler.cpp:2556 +msgid " _Unclump " +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2557 +msgid "Spread out clones to reduce clumping; can be applied repeatedly" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2563 +#, fuzzy +msgid " Re_move " +msgstr "Διαγραφή συνδέσμου" + +#: ../../po/../src/dialogs/clonetiler.cpp:2564 +msgid "Remove existing tiled clones of the selected object (siblings only)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2580 +#, fuzzy +msgid " R_eset " +msgstr "Διαγραφή συνδέσμου" + +#. TRANSLATORS: "change" is a noun here +#: ../../po/../src/dialogs/clonetiler.cpp:2582 +msgid "" +"Reset all shifts, scales, rotates, opacity and color changes in the dialog " +"to zero" +msgstr "" + +#: ../../po/../src/dialogs/color-picker.cpp:280 +#, fuzzy +msgid "Close" +msgstr "Νέα Προβολή" + +#: ../../po/../src/dialogs/debugdialog.cpp:138 +msgid "Messages" +msgstr "" + +# +#. ## Add a menu for clear() +#: ../../po/../src/dialogs/debugdialog.cpp:144 +#: ../../po/../src/menus-skeleton.h:16 +#: ../../po/../src/ui/dialog/messages.cpp:56 +#: ../../po/../src/ui/dialog/scriptdialog.cpp:181 +msgid "_File" +msgstr "_Αρχείο" + +#. TRANSLATORS: "Clear" is a verb here +#: ../../po/../src/dialogs/debugdialog.cpp:145 +#: ../../po/../src/dialogs/find.cpp:753 +#: ../../po/../src/ui/dialog/messages.cpp:57 +#: ../../po/../src/ui/dialog/scriptdialog.cpp:182 +#, fuzzy +msgid "_Clear" +msgstr "Νέα Προβολή" + +#: ../../po/../src/dialogs/debugdialog.cpp:147 +#: ../../po/../src/ui/dialog/messages.cpp:59 +msgid "Capture log messages" +msgstr "" + +#: ../../po/../src/dialogs/debugdialog.cpp:149 +#: ../../po/../src/ui/dialog/messages.cpp:61 +msgid "Release log messages" +msgstr "" + +#. Notebook tab +#: ../../po/../src/dialogs/desktop-properties.cpp:909 +#: ../../po/../src/ui/dialog/document-preferences.cpp:89 +#: ../../po/../src/ui/widget/panel.cpp:107 +msgid "Grid" +msgstr "Πλέγμα" + +#. Checkbuttons +#. / \todo FIXME: gray out snapping when grid is off +#. / \todo FIXME: gray out snapping when grid is off. +#. / Dissenting view: you want snapping without grid. +#: ../../po/../src/dialogs/desktop-properties.cpp:917 +#: ../../po/../src/ui/dialog/document-preferences.cpp:179 +msgid "Show grid" +msgstr "Εμφάνιση πλέγματος" + +#: ../../po/../src/dialogs/desktop-properties.cpp:917 +#: ../../po/../src/ui/dialog/document-preferences.cpp:179 +#: ../../po/../src/verbs.cpp:2115 +#, fuzzy +msgid "Show or hide grid" +msgstr "Εμφάνιση πλέγματος" + +#: ../../po/../src/dialogs/desktop-properties.cpp:918 +#: ../../po/../src/ui/dialog/document-preferences.cpp:180 +#, fuzzy +msgid "Snap bounding boxes to grid" +msgstr "Τοπο_θέτηση Σε Πλέγμα" + +#: ../../po/../src/dialogs/desktop-properties.cpp:918 +#: ../../po/../src/dialogs/desktop-properties.cpp:1001 +#: ../../po/../src/ui/dialog/document-preferences.cpp:181 +#: ../../po/../src/ui/dialog/document-preferences.cpp:236 +msgid "Snap the edges of the object bounding boxes" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:919 +#: ../../po/../src/ui/dialog/document-preferences.cpp:183 +#, fuzzy +msgid "Snap nodes to grid" +msgstr "Τοπο_θέτηση Σε Πλέγμα" + +#: ../../po/../src/dialogs/desktop-properties.cpp:919 +#: ../../po/../src/dialogs/desktop-properties.cpp:1002 +#: ../../po/../src/ui/dialog/document-preferences.cpp:184 +#: ../../po/../src/ui/dialog/document-preferences.cpp:239 +msgid "Snap path nodes, text baselines, ellipse centers, etc." +msgstr "" + +# +#: ../../po/../src/dialogs/desktop-properties.cpp:937 +#: ../../po/../src/ui/dialog/document-preferences.cpp:186 +#, fuzzy +msgid "Grid units:" +msgstr "Γραμματοσειρά Πλέγματος" + +#: ../../po/../src/dialogs/desktop-properties.cpp:939 +#: ../../po/../src/ui/dialog/document-preferences.cpp:187 +#, fuzzy +msgid "Origin X:" +msgstr "Προέλευση:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:942 +#: ../../po/../src/ui/dialog/document-preferences.cpp:189 +#, fuzzy +msgid "Origin Y:" +msgstr "Προέλευση:" + +# +#: ../../po/../src/dialogs/desktop-properties.cpp:945 +#: ../../po/../src/ui/dialog/document-preferences.cpp:191 +#, fuzzy +msgid "Spacing X:" +msgstr "Διάστιχο:" + +# +#: ../../po/../src/dialogs/desktop-properties.cpp:948 +#: ../../po/../src/ui/dialog/document-preferences.cpp:193 +#, fuzzy +msgid "Spacing Y:" +msgstr "Διάστιχο:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:952 +#: ../../po/../src/dialogs/desktop-properties.cpp:1013 +#: ../../po/../src/ui/dialog/document-preferences.cpp:195 +#: ../../po/../src/ui/dialog/document-preferences.cpp:241 +#, fuzzy +msgid "Snap units:" +msgstr "Τοποθέτηση σε:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:955 +#: ../../po/../src/dialogs/desktop-properties.cpp:1016 +#: ../../po/../src/ui/dialog/document-preferences.cpp:196 +#: ../../po/../src/ui/dialog/document-preferences.cpp:242 +#, fuzzy +msgid "Snap distance:" +msgstr "Ίσες Αποστάσεις" + +#: ../../po/../src/dialogs/desktop-properties.cpp:958 +#: ../../po/../src/ui/dialog/document-preferences.cpp:199 +#, fuzzy +msgid "Grid line color:" +msgstr "Επιλογή χρώματος" + +#: ../../po/../src/dialogs/desktop-properties.cpp:959 +#: ../../po/../src/ui/dialog/document-preferences.cpp:199 +#, fuzzy +msgid "Grid line color" +msgstr "Επιλογή χρώματος" + +#: ../../po/../src/dialogs/desktop-properties.cpp:959 +#: ../../po/../src/ui/dialog/document-preferences.cpp:200 +#, fuzzy +msgid "Color of grid lines" +msgstr "Επιλογή χρώματος οθόνης για το Abiword" + +#: ../../po/../src/dialogs/desktop-properties.cpp:961 +#: ../../po/../src/ui/dialog/document-preferences.cpp:201 +#, fuzzy +msgid "Major grid line color:" +msgstr "Επιλογή χρώματος" + +#: ../../po/../src/dialogs/desktop-properties.cpp:962 +#: ../../po/../src/ui/dialog/document-preferences.cpp:201 +#, fuzzy +msgid "Major grid line color" +msgstr "Επιλογή χρώματος" + +#: ../../po/../src/dialogs/desktop-properties.cpp:962 +#: ../../po/../src/ui/dialog/document-preferences.cpp:202 +msgid "Color of the major (highlighted) grid lines" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:965 +#: ../../po/../src/ui/dialog/document-preferences.cpp:204 +#, fuzzy +msgid "Major grid line every:" +msgstr "Επιλογή χρώματος" + +#. TRANSLATORS: This belongs to the "Major grid line every:" string, +#. see grid settings in the "Document Preferences" dialog +#: ../../po/../src/dialogs/desktop-properties.cpp:977 +#: ../../po/../src/ui/dialog/document-preferences.cpp:204 +#, fuzzy +msgid "lines" +msgstr "Νέα Προβολή" + +#. Guidelines page +#: ../../po/../src/dialogs/desktop-properties.cpp:991 +#: ../../po/../src/ui/dialog/document-preferences.cpp:90 +#, fuzzy +msgid "Guides" +msgstr "Γουϊνέα" + +# +#. / \todo FIXME: gray out snapping when guides are off +#. / Dissenting view: you want snapping without guides. +#: ../../po/../src/dialogs/desktop-properties.cpp:1000 +#: ../../po/../src/ui/dialog/document-preferences.cpp:234 +#, fuzzy +msgid "Show guides" +msgstr "Εμφάνιση κόμβων-δ" + +# +#: ../../po/../src/dialogs/desktop-properties.cpp:1000 +#: ../../po/../src/ui/dialog/document-preferences.cpp:234 +#: ../../po/../src/verbs.cpp:2116 +#, fuzzy +msgid "Show or hide guides" +msgstr "Εμφάνιση κόμβων-δ" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1001 +#: ../../po/../src/ui/dialog/document-preferences.cpp:235 +#, fuzzy +msgid "Snap bounding boxes to guides" +msgstr "Τοπο_θέτηση Σε Πλέγμα" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1002 +#: ../../po/../src/ui/dialog/document-preferences.cpp:238 +#, fuzzy +msgid "Snap points to guides" +msgstr "Τοπο_θέτηση Σε Πλέγμα" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1020 +#: ../../po/../src/ui/dialog/document-preferences.cpp:243 +#, fuzzy +msgid "Guide color:" +msgstr "Χρώμα μη-ολοκληρωμένων εγγραφών:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1021 +#: ../../po/../src/ui/dialog/document-preferences.cpp:243 +#, fuzzy +msgid "Guideline color" +msgstr "Επιλογή χρώματος" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1021 +#: ../../po/../src/ui/dialog/document-preferences.cpp:244 +#, fuzzy +msgid "Color of guidelines" +msgstr "Επιλογή χρώματος οθόνης για το Abiword" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1023 +#: ../../po/../src/ui/dialog/document-preferences.cpp:245 +#, fuzzy +msgid "Highlight color:" +msgstr "Χρώμα Μαρκαρίσματος" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1024 +#: ../../po/../src/ui/dialog/document-preferences.cpp:245 +#, fuzzy +msgid "Highlighted guideline color" +msgstr "Χρώμα Ψευδωνύμου σε Έμφαση" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1024 +#: ../../po/../src/ui/dialog/document-preferences.cpp:246 +msgid "Color of a guideline when it is under mouse" +msgstr "" + +#. Page page +#: ../../po/../src/dialogs/desktop-properties.cpp:1029 +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:855 +#: ../../po/../src/ui/dialog/document-preferences.cpp:88 +#: ../../po/../src/widgets/desktop-widget.cpp:1061 +msgid "Page" +msgstr "Σελίδα" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1039 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +#, fuzzy +msgid "Background:" +msgstr " χρώμα" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1040 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +#, fuzzy +msgid "Background color" +msgstr " χρώμα" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1041 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +msgid "" +"Color and transparency of the page background (also used for bitmap export)" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1045 +#: ../../po/../src/ui/dialog/document-preferences.cpp:147 +#, fuzzy +msgid "Show page border" +msgstr "Εμφάνιση πλέγματος" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1049 +#: ../../po/../src/ui/dialog/document-preferences.cpp:148 +#, fuzzy +msgid "Border on top of drawing" +msgstr "Αλλαγή κλίμακας για _ταίριασμα" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1052 +#: ../../po/../src/ui/dialog/document-preferences.cpp:149 +#, fuzzy +msgid "Border color:" +msgstr " χρώμα" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1053 +#: ../../po/../src/ui/dialog/document-preferences.cpp:149 +#, fuzzy +msgid "Page border color" +msgstr " χρώμα" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1054 +#: ../../po/../src/ui/dialog/document-preferences.cpp:150 +#, fuzzy +msgid "Color of the page border" +msgstr "Εμφάνιση πλέγματος" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1059 +#: ../../po/../src/ui/dialog/document-preferences.cpp:152 +msgid "Show page shadow" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1063 +#: ../../po/../src/ui/dialog/document-preferences.cpp:153 +#, fuzzy +msgid "Default units:" +msgstr "Διαγρ." + +#: ../../po/../src/dialogs/desktop-properties.cpp:1069 +msgid "Units for the tool controls, ruler, and the statusbar" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1086 +#: ../../po/../src/ui/widget/page-sizer.cpp:209 +#, fuzzy +msgid "Page size:" +msgstr "Μέγ. _χαρτιού:" + +# Translation of "custom" sucks! ("kata paraggelia"??? nah!) +#: ../../po/../src/dialogs/desktop-properties.cpp:1110 +#: ../../po/../src/ui/widget/page-sizer.cpp:219 +msgid "Custom" +msgstr "Προσαρμοσμένο" + +# +#: ../../po/../src/dialogs/desktop-properties.cpp:1121 +#: ../../po/../src/ui/widget/page-sizer.cpp:225 +#, fuzzy +msgid "Page orientation:" +msgstr "Κορεσμός:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1133 +#: ../../po/../src/ui/widget/page-sizer.cpp:232 +#, fuzzy +msgid "Landscape" +msgstr "Συμπαγές" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1139 +#: ../../po/../src/ui/widget/page-sizer.cpp:234 +#, fuzzy +msgid "Portrait" +msgstr "Σημείο" + +# Translation of "custom" sucks! ("kata paraggelia"??? nah!) +#. Custom paper frame +#: ../../po/../src/dialogs/desktop-properties.cpp:1148 +#: ../../po/../src/ui/widget/page-sizer.cpp:249 +#, fuzzy +msgid "Custom size" +msgstr "Προσαρμοσμένο" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1160 +#: ../../po/../src/dialogs/export.cpp:269 +#: ../../po/../src/ui/widget/page-sizer.cpp:261 +#, fuzzy +msgid "Units:" +msgstr "&Μονάδες:" + +#. Stroke width +#: ../../po/../src/dialogs/desktop-properties.cpp:1162 +#: ../../po/../src/dialogs/export.cpp:310 +#: ../../po/../src/dialogs/object-attributes.cpp:55 +#: ../../po/../src/dialogs/stroke-style.cpp:985 +#: ../../po/../src/ui/widget/page-sizer.cpp:262 +#: ../../po/../src/widgets/toolbox.cpp:1957 +msgid "Width:" +msgstr "Πλάτος:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1183 +#: ../../po/../src/dialogs/export.cpp:326 +#: ../../po/../src/dialogs/export.cpp:431 +#: ../../po/../src/dialogs/object-attributes.cpp:56 +#: ../../po/../src/ui/widget/page-sizer.cpp:263 +msgid "Height:" +msgstr "Ύψος:" + +#. +#. * Ownership metadata tab +#. +#: ../../po/../src/dialogs/desktop-properties.cpp:1206 +msgid "Metadata" +msgstr "" + +#. add license selector pull-down +#: ../../po/../src/dialogs/desktop-properties.cpp:1225 +#, fuzzy +msgid "License" +msgstr "ίντσα" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1255 +msgid "Proprietary" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:212 +#, fuzzy +msgid "When transforming, show:" +msgstr "Μετασχηματισμός" + +# +#: ../../po/../src/dialogs/display-settings.cpp:223 +#, fuzzy +msgid "Objects" +msgstr "Αντικείμενο" + +#: ../../po/../src/dialogs/display-settings.cpp:224 +msgid "Show the actual objects when moving or transforming" +msgstr "" + +# +#: ../../po/../src/dialogs/display-settings.cpp:231 +#, fuzzy +msgid "Box outline" +msgstr "Εμφάνιση κόμβων-δ" + +#: ../../po/../src/dialogs/display-settings.cpp:232 +msgid "Show only a box outline of the objects when moving or transforming" +msgstr "" + +# +#: ../../po/../src/dialogs/display-settings.cpp:238 +#, fuzzy +msgid "Per-object selection cue:" +msgstr "Διαγραφή επιλεγμένου αντικειμένου" + +# +#. sorationsnapsperpi == 0 means no snapping +#: ../../po/../src/dialogs/display-settings.cpp:249 +#: ../../po/../src/dialogs/display-settings.cpp:386 +#: ../../po/../src/dialogs/display-settings.cpp:441 +#: ../../po/../src/dialogs/display-settings.cpp:1482 +#: ../../po/../src/dialogs/stroke-style.cpp:791 +#: ../../po/../src/interface.cpp:741 +#: ../../po/../src/ui/widget/selected-style.cpp:100 +#: ../../po/../src/verbs.cpp:1842 +msgid "None" +msgstr "Κανένα" + +#: ../../po/../src/dialogs/display-settings.cpp:250 +msgid "No per-object selection indication" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:256 +msgid "Mark" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:257 +msgid "Each selected object has a diamond mark in the top left corner" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:264 +msgid "Box" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:265 +msgid "Each selected object displays its bounding box" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:270 +msgid "Default scale origin:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:281 +#, fuzzy +msgid "Opposite bounding box edge" +msgstr "Τοπο_θέτηση Σε Πλέγμα" + +#: ../../po/../src/dialogs/display-settings.cpp:282 +msgid "Default scale origin will be on the bounding box of the item" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:288 +msgid "Farthest opposite node" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:289 +msgid "Default scale origin will be on the bounding box of the item's points" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:341 +#, fuzzy +msgid "degrees" +msgstr "dec" + +#: ../../po/../src/dialogs/display-settings.cpp:350 +msgid "" +"Rotating with Ctrl pressed snaps every that much degrees; also, pressing " +"[ or ] rotates by this amount" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:407 +msgid "Rotation snaps every:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:430 +msgid "" +"None: dialogs are treated as regular windows; Normal: dialogs stay on top of " +"document windows; Aggressive: same as Normal but may work better with some " +"window managers." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:451 +msgid "Normal" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:461 +msgid "Aggressive" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:475 +msgid "Dialogs on top:" +msgstr "" + +# +#: ../../po/../src/dialogs/display-settings.cpp:645 +#, fuzzy +msgid "Show selection cue" +msgstr "Διαγραφή επιλεγμένου αντικειμένου" + +#: ../../po/../src/dialogs/display-settings.cpp:646 +msgid "" +"Whether selected objects display a selection cue (the same as in selector)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:657 +#, fuzzy +msgid "Enable gradient editing" +msgstr "Βαθμίδα" + +#: ../../po/../src/dialogs/display-settings.cpp:658 +msgid "Whether selected objects display gradient editing controls" +msgstr "" + +# +#: ../../po/../src/dialogs/display-settings.cpp:719 +#, fuzzy +msgid "No objects selected to take the style from." +msgstr "Διαγραφή επιλεγμένου αντικειμένου" + +#: ../../po/../src/dialogs/display-settings.cpp:728 +msgid "" +"More than one object selected. Cannot take style from multiple " +"objects." +msgstr "" + +# +#: ../../po/../src/dialogs/display-settings.cpp:767 +#, fuzzy +msgid "Create new objects with:" +msgstr "Ιδιότητα" + +#: ../../po/../src/dialogs/display-settings.cpp:777 +#, fuzzy +msgid "Take from selection" +msgstr "Μετασχηματισμός" + +#: ../../po/../src/dialogs/display-settings.cpp:778 +msgid "Remember the style of the (first) selected object as this tool's style" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:782 +#, fuzzy +msgid "Last used style" +msgstr "Καπνός με άνεμο" + +#: ../../po/../src/dialogs/display-settings.cpp:782 +msgid "Apply the style you last set on an object" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:790 +msgid "This tool's own style:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:790 +msgid "" +"Each tool may store its own style to apply to the newly created objects. Use " +"the button below to set it." +msgstr "" + +#. Mouse +#: ../../po/../src/dialogs/display-settings.cpp:877 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:55 +#, fuzzy +msgid "Mouse" +msgstr "Μετακίνηση" + +#. TRANSLATORS: "Grab" is a noun here. "Grab sensitivity" is intended to mean how +#. * close on the screen you need to be to an object to be able to grab it with mouse (in +#. * pixels). +#: ../../po/../src/dialogs/display-settings.cpp:883 +#, fuzzy +msgid "Grab sensitivity:" +msgstr "Πεζά/κεφαλαία διαφέρουν" + +#: ../../po/../src/dialogs/display-settings.cpp:884 +msgid "" +"How close on the screen you need to be to an object to be able to grab it " +"with mouse (in screen pixels)" +msgstr "" + +# +#: ../../po/../src/dialogs/display-settings.cpp:885 +#: ../../po/../src/dialogs/display-settings.cpp:897 +#: ../../po/../src/dialogs/display-settings.cpp:912 +#: ../../po/../src/dialogs/display-settings.cpp:930 +#: ../../po/../src/dialogs/display-settings.cpp:970 +#, fuzzy +msgid "pixels" +msgstr "Εικονοστοιχεία" + +#: ../../po/../src/dialogs/display-settings.cpp:895 +msgid "Click/drag threshold:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:896 +msgid "" +"Maximum mouse drag (in screen pixels) which is considered a click, not a drag" +msgstr "" + +#. Scrolling +#: ../../po/../src/dialogs/display-settings.cpp:907 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:56 +msgid "Scrolling" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:910 +msgid "Mouse wheel scrolls by:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:911 +msgid "" +"One mouse wheel notch scrolls by this distance in screen pixels " +"(horizontally with Shift)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:920 +msgid "Ctrl+arrows" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:928 +msgid "Scroll by:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:929 +msgid "Pressing Ctrl+arrow key scrolls by this distance (in screen pixels)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:939 +#, fuzzy +msgid "Acceleration:" +msgstr "Επιλογή" + +#: ../../po/../src/dialogs/display-settings.cpp:940 +msgid "" +"Pressing and holding Ctrl+arrow will gradually speed up scrolling (0 for no " +"acceleration)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:949 +msgid "Autoscrolling" +msgstr "" + +# +#: ../../po/../src/dialogs/display-settings.cpp:957 +#, fuzzy +msgid "Speed:" +msgstr "Κόκκινο:" + +#: ../../po/../src/dialogs/display-settings.cpp:958 +msgid "" +"How fast the canvas autoscrolls when you drag beyond canvas edge (0 to turn " +"autoscroll off)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:968 +#: ../../po/../src/ui/dialog/tracedialog.cpp:357 +#: ../../po/../src/ui/dialog/tracedialog.cpp:390 +msgid "Threshold:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:969 +msgid "" +"How far (in screen pixels) you need to be from the canvas edge to trigger " +"autoscroll; positive is outside the canvas, negative is within the canvas" +msgstr "" + +#. Steps +#: ../../po/../src/dialogs/display-settings.cpp:979 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:57 +#, fuzzy +msgid "Steps" +msgstr "Στυλ: " + +#: ../../po/../src/dialogs/display-settings.cpp:982 +msgid "Arrow keys move by:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:983 +msgid "" +"Pressing an arrow key moves selected object(s) or node(s) by this distance " +"(in px units)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:984 +#: ../../po/../src/dialogs/display-settings.cpp:995 +#: ../../po/../src/dialogs/display-settings.cpp:1006 +#: ../../po/../src/helper/units.cpp:42 +msgid "px" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:993 +msgid "> and < scale by:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:994 +msgid "" +"Pressing > or < scales selection up or down by this increment (in px units)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1004 +msgid "Inset/Outset by:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1005 +msgid "" +"Inset and Outset commands displace the path by this distance (in px units)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1017 +msgid "Compass-like display of angles" +msgstr "" + +#. TRANSLATORS: "positive clockwise" means "increasing in clockwise direction" +#: ../../po/../src/dialogs/display-settings.cpp:1019 +msgid "" +"When on, angles are displayed with 0 at north, 0 to 360 range, positive " +"clockwise; otherwise with 0 at east, -180 to 180 range, positive " +"counterclockwise" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1026 +#, fuzzy +msgid "Zoom in/out by:" +msgstr "Σμίκρυνση" + +#: ../../po/../src/dialogs/display-settings.cpp:1027 +msgid "" +"Zoom tool click, +/- keys, and middle click zoom in and out by this " +"multiplier" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1028 +#: ../../po/../src/helper/units.cpp:44 +msgid "%" +msgstr "%" + +#. Tools +#: ../../po/../src/dialogs/display-settings.cpp:1037 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:58 +msgid "Tools" +msgstr "" + +# +#: ../../po/../src/dialogs/display-settings.cpp:1045 +#, fuzzy +msgid "Selector" +msgstr "Επιλογή" + +# +#: ../../po/../src/dialogs/display-settings.cpp:1056 +#, fuzzy +msgid "Node" +msgstr "Κανένα" + +#: ../../po/../src/dialogs/display-settings.cpp:1064 +#: ../../po/../src/verbs.cpp:2073 +#: ../../po/../src/widgets/desktop-widget.cpp:277 +msgid "Zoom" +msgstr "Εστίαση" + +#. The 4 shape tools +#: ../../po/../src/dialogs/display-settings.cpp:1071 +#, fuzzy +msgid "Shapes" +msgstr "Σκίαση" + +#: ../../po/../src/dialogs/display-settings.cpp:1079 +#: ../../po/../src/verbs.cpp:2055 +msgid "Rectangle" +msgstr "Ορθογώνιο" + +# +#: ../../po/../src/dialogs/display-settings.cpp:1085 +#: ../../po/../src/verbs.cpp:2057 +msgid "Ellipse" +msgstr "Έλλειψη" + +#: ../../po/../src/dialogs/display-settings.cpp:1091 +#: ../../po/../src/verbs.cpp:2059 +msgid "Star" +msgstr "Αστερίσκος" + +#: ../../po/../src/dialogs/display-settings.cpp:1097 +#: ../../po/../src/verbs.cpp:2061 +#, fuzzy +msgid "Spiral" +msgstr "Ειδικό" + +#: ../../po/../src/dialogs/display-settings.cpp:1111 +#: ../../po/../src/verbs.cpp:2063 +msgid "Pencil" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1114 +msgid "Tolerance:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1115 +msgid "" +"This value affects the amount of smoothing applied to freehand lines; lower " +"values produce more uneven paths with more nodes" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1131 +#: ../../po/../src/verbs.cpp:2065 +#, fuzzy +msgid "Pen" +msgstr "Ποσοστό" + +#: ../../po/../src/dialogs/display-settings.cpp:1140 +#: ../../po/../src/verbs.cpp:2067 +msgid "Calligraphy" +msgstr "" + +# +#: ../../po/../src/dialogs/display-settings.cpp:1147 +#: ../../po/../src/dialogs/text-edit.cpp:353 +#: ../../po/../src/ui/dialog/text-properties.cpp:37 +#: ../../po/../src/verbs.cpp:2069 +msgid "Text" +msgstr "Κείμενο" + +#: ../../po/../src/dialogs/display-settings.cpp:1157 +#: ../../po/../src/verbs.cpp:2071 +#, fuzzy +msgid "Gradient" +msgstr "Βαθμίδα" + +#: ../../po/../src/dialogs/display-settings.cpp:1164 +#: ../../po/../src/verbs.cpp:2077 +#, fuzzy +msgid "Connector" +msgstr "Νέα Προβολή" + +#: ../../po/../src/dialogs/display-settings.cpp:1171 +#: ../../po/../src/verbs.cpp:2075 +msgid "Dropper" +msgstr "" + +#. Windows +#: ../../po/../src/dialogs/display-settings.cpp:1183 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:59 +#, fuzzy +msgid "Windows" +msgstr "window1" + +#: ../../po/../src/dialogs/display-settings.cpp:1188 +#, fuzzy +msgid "Save window geometry" +msgstr "Έγγραφο" + +#: ../../po/../src/dialogs/display-settings.cpp:1189 +msgid "" +"Save the window size and position with each document (only for Inkscape SVG " +"format)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1196 +msgid "Dialogs are hidden in taskbar" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1197 +msgid "Whether dialog windows are to be hidden in the window manager taskbar" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1204 +msgid "Zoom when window is resized" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1205 +msgid "" +"Zoom drawing when document window is resized, to keep the same area visible " +"(this is the default which can be changed in any window using the button " +"above the right scrollbar)" +msgstr "" + +#. Clones +#: ../../po/../src/dialogs/display-settings.cpp:1213 +#: ../../po/../src/dialogs/find.cpp:624 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:60 +#, fuzzy +msgid "Clones" +msgstr "Νέα Προβολή" + +#: ../../po/../src/dialogs/display-settings.cpp:1217 +msgid "When the original moves, its clones and linked offsets:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1229 +msgid "Move in parallel" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1230 +msgid "Clones are translated by the same vector as their original." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1237 +msgid "Stay unmoved" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1238 +msgid "Clones preserve their positions when their original is moved." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1245 +msgid "Move according to transform" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1246 +msgid "" +"Each clone moves according to the value of its transform= attribute. For " +"example, a rotated clone will move in a different direction than its " +"original." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1255 +msgid "When the original is deleted, its clones:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1267 +msgid "Are unlinked" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1267 +msgid "Orphaned clones are converted to regular objects." +msgstr "" + +# +#: ../../po/../src/dialogs/display-settings.cpp:1273 +#, fuzzy +msgid "Are deleted" +msgstr "Επιλέχθησαν \"%s\"" + +#: ../../po/../src/dialogs/display-settings.cpp:1273 +msgid "Orphaned clones are deleted along with their original." +msgstr "" + +#. Transforms +#. TRANSLATORS: Noun, i.e. transformations. +#: ../../po/../src/dialogs/display-settings.cpp:1289 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:61 +#, fuzzy +msgid "Transforms" +msgstr "Μετασχηματισμός" + +#: ../../po/../src/dialogs/display-settings.cpp:1292 +#, fuzzy +msgid "Scale stroke width" +msgstr "Καπνός με άνεμο" + +#: ../../po/../src/dialogs/display-settings.cpp:1293 +#: ../../po/../src/widgets/select-toolbar.cpp:568 +msgid "When scaling objects, scale the stroke width by the same proportion" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1300 +msgid "Scale rounded corners in rectangles" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1301 +#: ../../po/../src/widgets/select-toolbar.cpp:580 +msgid "When scaling rectangles, scale the radii of rounded corners" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1308 +#, fuzzy +msgid "Transform gradients" +msgstr "Μετασχηματισμός" + +#: ../../po/../src/dialogs/display-settings.cpp:1309 +#: ../../po/../src/widgets/select-toolbar.cpp:592 +msgid "Transform gradients (in fill or stroke) along with the objects" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1316 +#, fuzzy +msgid "Transform patterns" +msgstr "Μετασχηματισμός" + +#: ../../po/../src/dialogs/display-settings.cpp:1317 +#: ../../po/../src/widgets/select-toolbar.cpp:604 +msgid "Transform patterns (in fill or stroke) along with the objects" +msgstr "" + +#. TRANSLATORS: How to specify the affine transformation in the SVG file. +#: ../../po/../src/dialogs/display-settings.cpp:1327 +#, fuzzy +msgid "Store transformation:" +msgstr "Μετασχηματισμός" + +#: ../../po/../src/dialogs/display-settings.cpp:1338 +msgid "Optimized" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1339 +msgid "" +"If possible, apply transformation to objects without adding a transform= " +"attribute" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1346 +msgid "Preserved" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1347 +msgid "Always store transformation as a transform= attribute on objects" +msgstr "" + +#. Selecting +#: ../../po/../src/dialogs/display-settings.cpp:1355 +#, fuzzy +msgid "Selecting" +msgstr "Επιλογή" + +#: ../../po/../src/dialogs/display-settings.cpp:1357 +msgid "Ctrl+A, Tab, Shift+Tab:" +msgstr "" + +# +#: ../../po/../src/dialogs/display-settings.cpp:1366 +#, fuzzy +msgid "Select only within current layer" +msgstr "Επιλογή" + +#: ../../po/../src/dialogs/display-settings.cpp:1367 +msgid "" +"Uncheck this to make keyboard selection commands work on objects in all " +"layers" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1374 +msgid "Ignore hidden objects" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1375 +msgid "" +"Uncheck this to be able to select objects that are hidden (either by " +"themselves or by being in a hidden group or layer)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1382 +#, fuzzy +msgid "Ignore locked objects" +msgstr "Διαγραφή επιλεγμένων αντικειμένων" + +#: ../../po/../src/dialogs/display-settings.cpp:1383 +msgid "" +"Uncheck this to be able to select objects that are locked (either by " +"themselves or by being in a locked group or layer)" +msgstr "" + +#. To be broken into: Display, Save, Export, SVG, Commands +#: ../../po/../src/dialogs/display-settings.cpp:1391 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:62 +msgid "Misc" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1394 +msgid "Default export resolution:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1395 +msgid "Default bitmap resolution (in dots per inch) in the Export dialog" +msgstr "" + +#. FIXME: add "Used for new exports; once exported, documents remember this value on per-object basis" when implemented +#: ../../po/../src/dialogs/display-settings.cpp:1396 +#: ../../po/../src/dialogs/export.cpp:442 +msgid "dpi" +msgstr "" + +#. TRANSLATORS: When on, an imported bitmap creates an element; otherwise it is a +#. * rectangle with bitmap fill. +#: ../../po/../src/dialogs/display-settings.cpp:1407 +msgid "Import bitmap as " +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1408 +msgid "" +"When on, an imported bitmap creates an element; otherwise it is a " +"rectangle with bitmap fill" +msgstr "" + +#. TRANSLATORS: When on, the print out (currently Postscript) will have +#. * a comment with the each object's label visible, marking the section +#. * of the printing commands that represent the given object. +#: ../../po/../src/dialogs/display-settings.cpp:1418 +msgid "Add label comments to printing output" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1419 +msgid "" +"When on, a comment will be added to the raw print output, marking the " +"rendered output for an object with its label" +msgstr "" + +#. TRANSLATORS: When on, enable the effects menu, default is off +#: ../../po/../src/dialogs/display-settings.cpp:1427 +msgid "Enable script effects (requires restart) - EXPERIMENTAL" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1428 +msgid "" +"When on, the effects menu is enabled, allowing external effect scripts to be " +"called, requires restart before effective - EXPERIMENTAL" +msgstr "" + +#. TRANSLATORS: The maximum length of the Open Recent list in the File menu. +#: ../../po/../src/dialogs/display-settings.cpp:1436 +#, fuzzy +msgid "Max recent documents:" +msgstr "Έγγραφο" + +#: ../../po/../src/dialogs/display-settings.cpp:1437 +msgid "The maximum length of the Open Recent list in the File menu" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1447 +msgid "Simplification threshold:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1448 +msgid "" +"How strong is the Simplify command by default. If you invoke this command " +"several times in quick succession, it will act more and more aggressively; " +"invoking it again after a pause restores the default threshold." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1469 +msgid "Oversample bitmaps:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1488 +msgid "2x2" +msgstr "2x2" + +#: ../../po/../src/dialogs/display-settings.cpp:1494 +msgid "4x4" +msgstr "4x4" + +#: ../../po/../src/dialogs/display-settings.cpp:1500 +msgid "8x8" +msgstr "8x8" + +#: ../../po/../src/dialogs/display-settings.cpp:1506 +msgid "16x16" +msgstr "16x16" + +#. "view_icon_preview" +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2143 +msgid "_Page" +msgstr "_Σελίδα" + +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2147 +#, fuzzy +msgid "_Drawing" +msgstr "Σχεδίαση" + +# +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2149 +msgid "_Selection" +msgstr "_Επιλογή" + +# Translation of "custom" sucks! ("kata paraggelia"??? nah!) +#: ../../po/../src/dialogs/export.cpp:133 +#, fuzzy +msgid "_Custom" +msgstr "Προσαρμοσμένο" + +#: ../../po/../src/dialogs/export.cpp:254 +#, fuzzy +msgid "Export area" +msgstr "Το %s εισήχθη" + +#: ../../po/../src/dialogs/export.cpp:300 +msgid "_x0:" +msgstr "" + +# +#: ../../po/../src/dialogs/export.cpp:305 +#, fuzzy +msgid "x_1:" +msgstr "1:1" + +#: ../../po/../src/dialogs/export.cpp:316 +msgid "_y0:" +msgstr "" + +# +#: ../../po/../src/dialogs/export.cpp:321 +#, fuzzy +msgid "y_1:" +msgstr "1:1" + +#: ../../po/../src/dialogs/export.cpp:406 +#, fuzzy +msgid "Bitmap size" +msgstr "Μέγεθος Εικόνας:" + +#: ../../po/../src/dialogs/export.cpp:416 +#, fuzzy +msgid "_Width:" +msgstr "Πλάτος:" + +# +#: ../../po/../src/dialogs/export.cpp:416 +#: ../../po/../src/dialogs/export.cpp:431 +#, fuzzy +msgid "pixels at" +msgstr "Εικονοστοιχεία" + +#: ../../po/../src/dialogs/export.cpp:426 +msgid "dp_i" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:448 +#, fuzzy +msgid "_Filename" +msgstr "Όνομα Αρχείου:" + +#: ../../po/../src/dialogs/export.cpp:512 +msgid "_Browse..." +msgstr "" + +# +#: ../../po/../src/dialogs/export.cpp:539 +#, fuzzy +msgid " _Export " +msgstr "Αλλαγή" + +#: ../../po/../src/dialogs/export.cpp:541 +msgid "Export the bitmap file with these settings" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:968 +#, fuzzy +msgid "You have to enter a filename" +msgstr "Αποθήκευση ως γνήσιο όνομα αρχείου" + +#: ../../po/../src/dialogs/export.cpp:973 +msgid "The chosen area to be exported is invalid" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:982 +#, c-format +msgid "Directory %s does not exist or is not a directory.\n" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:998 +#, fuzzy +msgid "Export in progress" +msgstr "Το %s εισήχθη" + +#: ../../po/../src/dialogs/export.cpp:1004 +#, c-format +msgid "Exporting %s (%d x %d)" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:1031 +#, c-format +msgid "Could not export to filename %s.\n" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:1137 +#, fuzzy +msgid "Select a filename for exporting" +msgstr "Επιλογή αρχείου για φόρτωση" + +#: ../../po/../src/dialogs/filedialog.cpp:367 +#, fuzzy +msgid "No preview" +msgstr "Χρήση Προεπισκόπησης" + +#: ../../po/../src/dialogs/filedialog.cpp:468 +msgid "too large for preview" +msgstr "" + +# +#: ../../po/../src/dialogs/filedialog.cpp:762 +#: ../../po/../src/dialogs/filedialog.cpp:763 +#, fuzzy +msgid "All Images" +msgstr "Εικόνα" + +#: ../../po/../src/dialogs/filedialog.cpp:767 +#: ../../po/../src/dialogs/filedialog.cpp:768 +#, fuzzy +msgid "All Files" +msgstr "Όλες οι ρυθμίσεις" + +#: ../../po/../src/dialogs/filedialog.cpp:774 +#: ../../po/../src/dialogs/filedialog.cpp:775 +#, fuzzy +msgid "All Inkscape Files" +msgstr "Συμπαγές" + +#: ../../po/../src/dialogs/filedialog.cpp:1176 +#, fuzzy +msgid "Guess from extension" +msgstr "Μετασχηματισμός" + +#. ###### Add the file types menu +#. createFilterMenu(); +#. ###### Do we want the .xxx extension automatically added? +#: ../../po/../src/dialogs/filedialog.cpp:1261 +msgid "Append filename extension automatically" +msgstr "" + +# +#. TRANSLATORS: "%s" is replaced with "exact" or "partial" when this string is displayed +#: ../../po/../src/dialogs/find.cpp:378 +#, fuzzy, c-format +msgid "%d object found (out of %d), %s match." +msgid_plural "%d objects found (out of %d), %s match." +msgstr[0] "Εκκίνηση επιλεγμένου παροχέα" +msgstr[1] "Εκκίνηση επιλεγμένου παροχέα" + +# +#: ../../po/../src/dialogs/find.cpp:381 +#, fuzzy +msgid "exact" +msgstr "Κείμενο" + +#: ../../po/../src/dialogs/find.cpp:381 +#, fuzzy +msgid "partial" +msgstr "Ειδικό" + +#: ../../po/../src/dialogs/find.cpp:388 +#, fuzzy +msgid "No objects found" +msgstr "Επιλέξτε αντικείμενο" + +#: ../../po/../src/dialogs/find.cpp:546 +msgid "T_ype: " +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:553 +msgid "Search in all object types" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:553 +#, fuzzy +msgid "All types" +msgstr "Όλες οι ρυθμίσεις" + +#: ../../po/../src/dialogs/find.cpp:564 +msgid "Search all shapes" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:564 +msgid "All shapes" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:581 +#, fuzzy +msgid "Search rectangles" +msgstr "Ορθογώνιο" + +#: ../../po/../src/dialogs/find.cpp:581 +#, fuzzy +msgid "Rectangles" +msgstr "Ορθογώνιο" + +#: ../../po/../src/dialogs/find.cpp:586 +msgid "Search ellipses, arcs, circles" +msgstr "" + +# +#: ../../po/../src/dialogs/find.cpp:586 +#, fuzzy +msgid "Ellipses" +msgstr "Έλλειψη" + +#: ../../po/../src/dialogs/find.cpp:591 +msgid "Search stars and polygons" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:591 +#, fuzzy +msgid "Stars" +msgstr "Αστερίσκος" + +# +#: ../../po/../src/dialogs/find.cpp:596 +#, fuzzy +msgid "Search spirals" +msgstr "Δημιουργία γραμμής" + +#: ../../po/../src/dialogs/find.cpp:596 +#, fuzzy +msgid "Spirals" +msgstr "Ειδικό" + +#. TRANSLATORS: polyline is a set of connected straight line segments +#. http://www.w3.org/TR/SVG11/shapes.html#PolylineElement +#: ../../po/../src/dialogs/find.cpp:609 +msgid "Search paths, lines, polylines" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:609 +msgid "Paths" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:614 +#, fuzzy +msgid "Search text objects" +msgstr "Διαγραφή επιλεγμένων αντικειμένων" + +# +#: ../../po/../src/dialogs/find.cpp:614 +#, fuzzy +msgid "Texts" +msgstr "Κείμενο" + +#: ../../po/../src/dialogs/find.cpp:619 +msgid "Search groups" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:619 +#, fuzzy +msgid "Groups" +msgstr "Ομάδα" + +#: ../../po/../src/dialogs/find.cpp:624 +msgid "Search clones" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:629 +msgid "Search images" +msgstr "" + +# +#: ../../po/../src/dialogs/find.cpp:629 +#, fuzzy +msgid "Images" +msgstr "Εικόνα" + +#: ../../po/../src/dialogs/find.cpp:634 +#, fuzzy +msgid "Search offset objects" +msgstr "Διαγραφή επιλεγμένων αντικειμένων" + +#: ../../po/../src/dialogs/find.cpp:634 +msgid "Offsets" +msgstr "" + +# +#: ../../po/../src/dialogs/find.cpp:694 +#, fuzzy +msgid "_Text: " +msgstr "Κείμενο" + +#: ../../po/../src/dialogs/find.cpp:694 +msgid "Find objects by their text content (exact or partial match)" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:695 +msgid "_ID: " +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:695 +msgid "Find objects by the value of the id attribute (exact or partial match)" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:696 +#, fuzzy +msgid "_Style: " +msgstr "Στυλ: " + +#: ../../po/../src/dialogs/find.cpp:696 +msgid "" +"Find objects by the value of the style attribute (exact or partial match)" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:697 +#, fuzzy +msgid "_Attribute: " +msgstr "Ιδιότητα:" + +#: ../../po/../src/dialogs/find.cpp:697 +msgid "Find objects by the name of an attribute (exact or partial match)" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:711 +#, fuzzy +msgid "Search in s_election" +msgstr "Αντιγραφή ώρας στο επιλεγμένο" + +#: ../../po/../src/dialogs/find.cpp:715 +msgid "Limit search to the current selection" +msgstr "" + +# +#: ../../po/../src/dialogs/find.cpp:720 +#, fuzzy +msgid "Search in current _layer" +msgstr "Επιλογή" + +# +#: ../../po/../src/dialogs/find.cpp:724 +#, fuzzy +msgid "Limit search to the current layer" +msgstr "Επιλογή" + +#: ../../po/../src/dialogs/find.cpp:729 +msgid "Include _hidden" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:733 +msgid "Include hidden objects in search" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:738 +msgid "Include l_ocked" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:742 +#, fuzzy +msgid "Include locked objects in search" +msgstr "Διαγραφή επιλεγμένων αντικειμένων" + +# +#: ../../po/../src/dialogs/find.cpp:753 +#, fuzzy +msgid "Clear values" +msgstr "Αρχείο core" + +#: ../../po/../src/dialogs/find.cpp:754 +#, fuzzy +msgid "_Find" +msgstr "Πλέγμα" + +#: ../../po/../src/dialogs/find.cpp:754 +msgid "Select objects matching all of the fields you filled in" +msgstr "" + +#: ../../po/../src/dialogs/iconpreview.cpp:145 +#, c-format +msgid "%d x %d" +msgstr "" + +#: ../../po/../src/dialogs/iconpreview.cpp:193 +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:857 +#: ../../po/../src/widgets/desktop-widget.cpp:1069 +msgid "Selection" +msgstr "Επιλογή" + +# +#: ../../po/../src/dialogs/iconpreview.cpp:195 +#, fuzzy +msgid "Selection only or whole document" +msgstr "Επιλογή" + +#: ../../po/../src/dialogs/iconpreview.cpp:203 +msgid "Refresh the icons" +msgstr "" + +#. Create the label for the object id +#: ../../po/../src/dialogs/item-properties.cpp:126 +#: ../../po/../src/dialogs/item-properties.cpp:327 +#: ../../po/../src/dialogs/item-properties.cpp:396 +#: ../../po/../src/dialogs/item-properties.cpp:403 +msgid "_Id" +msgstr "" + +#: ../../po/../src/dialogs/item-properties.cpp:135 +msgid "" +"The id= attribute (only letters, digits, and the characters .-_: allowed)" +msgstr "" + +# +#. Button for setting the object's id, label, title and description. +#: ../../po/../src/dialogs/item-properties.cpp:149 +#, fuzzy +msgid "_Set" +msgstr "Επιλογή" + +#. Create the label for the object label +#: ../../po/../src/dialogs/item-properties.cpp:158 +#, fuzzy +msgid "_Label" +msgstr "εμφάνιση ιδιοτήτων" + +#: ../../po/../src/dialogs/item-properties.cpp:167 +msgid "A freeform label for the object" +msgstr "" + +# +#. Create the label for the object title +#: ../../po/../src/dialogs/item-properties.cpp:179 +#: ../../po/../src/dialogs/rdf.cpp:243 +#, fuzzy +msgid "Title" +msgstr "Αρχείο" + +#. Create the frame for the object description +#: ../../po/../src/dialogs/item-properties.cpp:196 +#: ../../po/../src/dialogs/rdf.cpp:287 +#, fuzzy +msgid "Description" +msgstr "Θέση" + +#. Hide +#: ../../po/../src/dialogs/item-properties.cpp:223 +#, fuzzy +msgid "_Hide" +msgstr "Γουϊνέα" + +#: ../../po/../src/dialogs/item-properties.cpp:224 +msgid "Check to make the object invisible" +msgstr "" + +#. Lock +#. TRANSLATORS: "Lock" is a verb here +#: ../../po/../src/dialogs/item-properties.cpp:233 +msgid "L_ock" +msgstr "" + +#: ../../po/../src/dialogs/item-properties.cpp:234 +msgid "Check to make the object insensitive (not selectable by mouse)" +msgstr "" + +#: ../../po/../src/dialogs/item-properties.cpp:310 +#: ../../po/../src/dialogs/item-properties.cpp:317 +msgid "Ref" +msgstr "" + +#: ../../po/../src/dialogs/item-properties.cpp:398 +#, fuzzy +msgid "Id invalid! " +msgstr "Άκυρη κίνηση." + +#: ../../po/../src/dialogs/item-properties.cpp:400 +msgid "Id exists! " +msgstr "" + +#: ../../po/../src/dialogs/layer-properties.cpp:50 +msgid "Layer name:" +msgstr "" + +#: ../../po/../src/dialogs/layer-properties.cpp:133 +#, fuzzy +msgid "Rename Layer" +msgstr "Αρχικοποίηση" + +#: ../../po/../src/dialogs/layer-properties.cpp:136 +#, fuzzy +msgid "_Rename" +msgstr "Όνομα Αρχείου:" + +#. TRANSLATORS: This means "The layer has been renamed" +#: ../../po/../src/dialogs/layer-properties.cpp:147 +#, fuzzy +msgid "Renamed layer" +msgstr "Αρχικοποίηση" + +# +#: ../../po/../src/dialogs/layer-properties.cpp:151 +#, fuzzy +msgid "Add Layer" +msgstr "Επιλογή" + +# +#: ../../po/../src/dialogs/layer-properties.cpp:153 +#, fuzzy +msgid "_Add" +msgstr "Προσθήκη" + +#: ../../po/../src/dialogs/layer-properties.cpp:167 +msgid "New layer created." +msgstr "" + +# +#: ../../po/../src/dialogs/object-attributes.cpp:34 +#, fuzzy +msgid "Href:" +msgstr "Απόχρωση:" + +#: ../../po/../src/dialogs/object-attributes.cpp:35 +#, fuzzy +msgid "Target:" +msgstr "μώβ" + +#: ../../po/../src/dialogs/object-attributes.cpp:36 +msgid "Type:" +msgstr "" + +# +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkRoleAttribute +#. Identifies the type of the related resource with an absolute URI +#: ../../po/../src/dialogs/object-attributes.cpp:39 +#, fuzzy +msgid "Role:" +msgstr "Κόκκινο:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkArcRoleAttribute +#. For situations where the nature/role alone isn't enough, this offers an additional URI defining the purpose of the link. +#: ../../po/../src/dialogs/object-attributes.cpp:42 +msgid "Arcrole:" +msgstr "" + +# +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkTitleAttribute +#: ../../po/../src/dialogs/object-attributes.cpp:44 +#, fuzzy +msgid "Title:" +msgstr "Αρχείο" + +#: ../../po/../src/dialogs/object-attributes.cpp:45 +msgid "Show:" +msgstr "" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkActuateAttribute +#: ../../po/../src/dialogs/object-attributes.cpp:47 +#, fuzzy +msgid "Actuate:" +msgstr "Ιδιότητα:" + +#: ../../po/../src/dialogs/object-attributes.cpp:52 +msgid "URL:" +msgstr "" + +#: ../../po/../src/dialogs/object-attributes.cpp:53 +msgid "X:" +msgstr "Χ:" + +#: ../../po/../src/dialogs/object-attributes.cpp:54 +msgid "Y:" +msgstr "Ψ:" + +#: ../../po/../src/dialogs/object-attributes.cpp:98 +#, fuzzy, c-format +msgid "%s attributes" +msgstr "Ιδιότητες" + +#: ../../po/../src/dialogs/object-properties.cpp:158 +#, fuzzy +msgid "_Fill" +msgstr "Γέμισμα" + +#: ../../po/../src/dialogs/object-properties.cpp:165 +#, fuzzy +msgid "Stroke _paint" +msgstr "Καπνός με άνεμο" + +#: ../../po/../src/dialogs/object-properties.cpp:172 +#, fuzzy +msgid "Stroke st_yle" +msgstr "Ρυθμίσεις επιφάνειας εργασίας" + +# +#: ../../po/../src/dialogs/object-properties.cpp:183 +#, fuzzy +msgid "Master _opacity" +msgstr "Διαφάνεια:" + +#: ../../po/../src/dialogs/rdf.cpp:244 +msgid "Name by which this document is formally known." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:246 +#, fuzzy +msgid "Date" +msgstr "Αλλα_γή γραμμής" + +#: ../../po/../src/dialogs/rdf.cpp:247 +msgid "Date associated with the creation of this document (YYYY-MM-DD)." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:249 +msgid "Format" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:250 +msgid "The physical or digital manifestation of this document (MIME type)." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:252 +msgid "Type" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:253 +msgid "Type of document (DCMI Type)." +msgstr "" + +# +#: ../../po/../src/dialogs/rdf.cpp:256 +#, fuzzy +msgid "Creator" +msgstr "Δημιουργία γραμμής" + +#: ../../po/../src/dialogs/rdf.cpp:257 +msgid "" +"Name of entity primarily responsible for making the content of this document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:259 +#, fuzzy +msgid "Rights" +msgstr "Ύψος" + +#: ../../po/../src/dialogs/rdf.cpp:260 +msgid "" +"Name of entity with rights to the Intellectual Property of this document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:262 +msgid "Publisher" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:263 +msgid "Name of entity responsible for making this document available." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:266 +#, fuzzy +msgid "Identifier" +msgstr "Κέντρο" + +#: ../../po/../src/dialogs/rdf.cpp:267 +msgid "Unique URI to reference this document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:269 +msgid "Source" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:270 +msgid "Unique URI to reference the source of this document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:272 +#, fuzzy +msgid "Relation" +msgstr "Επιλογή" + +#: ../../po/../src/dialogs/rdf.cpp:273 +msgid "Unique URI to a related document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:275 +#, fuzzy +msgid "Language" +msgstr "Διάστημα" + +#: ../../po/../src/dialogs/rdf.cpp:276 +msgid "" +"Two-letter language tag with optional subtags for the language of this " +"document. (e.g. 'en-GB')" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:278 +msgid "Keywords" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:279 +msgid "" +"The topic of this document as comma-separated key words, phrases, or " +"classifications." +msgstr "" + +#. TRANSLATORS: "Coverage": the spatial or temporal characteristics of the content. +#. For info, see Appendix D of http://www.w3.org/TR/1998/WD-rdf-schema-19980409/ +#: ../../po/../src/dialogs/rdf.cpp:283 +msgid "Coverage" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:284 +msgid "Extent or scope of this document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:288 +msgid "A short account of the content of this document." +msgstr "" + +#. FIXME: need to handle 1 agent per line of input +#: ../../po/../src/dialogs/rdf.cpp:292 +#, fuzzy +msgid "Contributors" +msgstr "εκατοστά" + +#: ../../po/../src/dialogs/rdf.cpp:293 +msgid "" +"Names of entities responsible for making contributions to the content of " +"this document." +msgstr "" + +#. TRANSLATORS: URL to a page that defines the license for the document +#: ../../po/../src/dialogs/rdf.cpp:297 +msgid "URI" +msgstr "" + +#. TRANSLATORS: this is where you put a URL to a page that defines the license +#: ../../po/../src/dialogs/rdf.cpp:299 +msgid "URI to this document's license's namespace definition." +msgstr "" + +#. TRANSLATORS: fragment of XML representing the license of the document +#: ../../po/../src/dialogs/rdf.cpp:303 +#, fuzzy +msgid "Fragment" +msgstr "μώβ" + +#: ../../po/../src/dialogs/rdf.cpp:304 +msgid "XML fragment for the RDF 'License' section." +msgstr "" + +# +#: ../../po/../src/dialogs/stroke-style.cpp:774 +#: ../../po/../src/widgets/gradient-vector.cpp:263 +#: ../../po/../src/widgets/paint-selector.cpp:751 +#, fuzzy +msgid "No document selected" +msgstr "Επιλέχθησαν \"%s\"" + +#: ../../po/../src/dialogs/stroke-style.cpp:992 +#, fuzzy +msgid "Stroke width" +msgstr "Καπνός με άνεμο" + +# +#. Join type +#. TRANSLATORS: The line join style specifies the shape to be used at the +#. corners of paths. It can be "miter", "round" or "bevel". +#: ../../po/../src/dialogs/stroke-style.cpp:1015 +#, fuzzy +msgid "Join:" +msgstr "Όνομα χρήστη:" + +#. TRANSLATORS: Miter join: joining lines with a sharp (pointed) corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1027 +#, fuzzy +msgid "Miter join" +msgstr "Πρωτεύον Μονοφωνικό" + +# +#. TRANSLATORS: Round join: joining lines with a rounded corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1035 +#, fuzzy +msgid "Round join" +msgstr "Εκτέλεση σε:" + +#. TRANSLATORS: Bevel join: joining lines with a blunted (flattened) corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1043 +#, fuzzy +msgid "Bevel join" +msgstr "Πρώτο επίπεδο" + +#. Miterlimit +#. TRANSLATORS: Miter limit: only for "miter join", this limits the length +#. of the sharp "spike" when the lines connect at too sharp an angle. +#. When two line segments meet at a sharp angle, a miter join results in a +#. spike that extends well beyond the connection point. The purpose of the +#. miter limit is to cut off such spikes (i.e. convert them into bevels) +#. when they become too long. +#: ../../po/../src/dialogs/stroke-style.cpp:1054 +#, fuzzy +msgid "Miter limit:" +msgstr "Πρωτεύον Μονοφωνικό" + +#: ../../po/../src/dialogs/stroke-style.cpp:1062 +msgid "Maximum length of the miter (in units of stroke width)" +msgstr "" + +#. Cap type +#. TRANSLATORS: cap type specifies the shape for the ends of lines +#: ../../po/../src/dialogs/stroke-style.cpp:1075 +#, fuzzy +msgid "Cap:" +msgstr "Κυανό" + +#. TRANSLATORS: Butt cap: the line shape does not extend beyond the end point +#. of the line; the ends of the line are square +#: ../../po/../src/dialogs/stroke-style.cpp:1086 +msgid "Butt cap" +msgstr "" + +# +#. TRANSLATORS: Round cap: the line shape extends beyond the end point of the +#. line; the ends of the line are rounded +#: ../../po/../src/dialogs/stroke-style.cpp:1093 +#, fuzzy +msgid "Round cap" +msgstr "Εκτέλεση σε:" + +#. TRANSLATORS: Square cap: the line shape extends beyond the end point of the +#. line; the ends of the line are square +#: ../../po/../src/dialogs/stroke-style.cpp:1100 +#, fuzzy +msgid "Square cap" +msgstr "Λίστα Τετραγώνων" + +#. Dash +#: ../../po/../src/dialogs/stroke-style.cpp:1106 +msgid "Dashes:" +msgstr "" + +#. TRANSLATORS: Path markers are an SVG feature that allows you to attach arbitrary shapes +#. (arrowheads, bullets, faces, whatever) to the start, end, or middle nodes of a path. +#: ../../po/../src/dialogs/stroke-style.cpp:1127 +#, fuzzy +msgid "Start Markers:" +msgstr " Ιδιότητες" + +#: ../../po/../src/dialogs/stroke-style.cpp:1137 +msgid "Mid Markers:" +msgstr "" + +#: ../../po/../src/dialogs/stroke-style.cpp:1148 +msgid "End Markers:" +msgstr "" + +#: ../../po/../src/dialogs/swatches.cpp:424 +#, c-format +msgid "Palettes directory (%s) is unavailable." +msgstr "" + +#. TODO: Insert widgets +#: ../../po/../src/dialogs/text-edit.cpp:199 +#: ../../po/../src/ui/dialog/text-properties.cpp:36 +#, fuzzy +msgid "Font" +msgstr "Σημείο" + +#: ../../po/../src/dialogs/text-edit.cpp:216 +msgid "Layout" +msgstr "Διάταξη" + +#: ../../po/../src/dialogs/text-edit.cpp:229 +#, fuzzy +msgid "Align lines left" +msgstr "Δεξιά προς αριστερά" + +#. TRANSLATORS: `Center' here is a verb. +#: ../../po/../src/dialogs/text-edit.cpp:243 +#, fuzzy +msgid "Center lines" +msgstr "Κέντρο" + +#: ../../po/../src/dialogs/text-edit.cpp:256 +#, fuzzy +msgid "Align lines right" +msgstr "Κύλιση από αριστερά προς δεξιά" + +#: ../../po/../src/dialogs/text-edit.cpp:278 +#, fuzzy +msgid "Horizontal text" +msgstr "οριζόντιο" + +#: ../../po/../src/dialogs/text-edit.cpp:292 +#, fuzzy +msgid "Vertical text" +msgstr "Κατακόρυφες Ρίγες" + +# +#: ../../po/../src/dialogs/text-edit.cpp:307 +#, fuzzy +msgid "Line spacing:" +msgstr "Διάστιχο:" + +#: ../../po/../src/dialogs/text-edit.cpp:400 +msgid "Set as default" +msgstr "" + +# +#: ../../po/../src/dialogs/tiledialog.cpp:603 +#, fuzzy +msgid "Rows:" +msgstr "Κόκκινο:" + +#: ../../po/../src/dialogs/tiledialog.cpp:613 +msgid "Number of rows" +msgstr "" + +#: ../../po/../src/dialogs/tiledialog.cpp:617 +#, fuzzy +msgid "Equal height" +msgstr "Ύψος: " + +#: ../../po/../src/dialogs/tiledialog.cpp:627 +msgid "If not set, each row has the height of the tallest object in it" +msgstr "" + +#. #### Radio buttons to control vertical alignment #### +#. #### Radio buttons to control horizontal alignment #### +#: ../../po/../src/dialogs/tiledialog.cpp:637 +#: ../../po/../src/dialogs/tiledialog.cpp:708 +#, fuzzy +msgid "Align:" +msgstr "Στοίχιση" + +#: ../../po/../src/dialogs/tiledialog.cpp:672 +msgid " X " +msgstr "" + +# +#. #### Number of columns #### +#: ../../po/../src/dialogs/tiledialog.cpp:678 +#, fuzzy +msgid "Columns:" +msgstr "Αλλαγή" + +#: ../../po/../src/dialogs/tiledialog.cpp:688 +msgid "Number of columns" +msgstr "" + +#: ../../po/../src/dialogs/tiledialog.cpp:692 +#, fuzzy +msgid "Equal width" +msgstr "Πλάτος:" + +#: ../../po/../src/dialogs/tiledialog.cpp:701 +msgid "If not set, each column has the width of the widest object in it" +msgstr "" + +# +#. #### Radio buttons to control spacing manually or to fit selection bbox #### +#: ../../po/../src/dialogs/tiledialog.cpp:746 +#, fuzzy +msgid "Fit into selection box" +msgstr "Αποκοπή της επιλογής" + +# +#: ../../po/../src/dialogs/tiledialog.cpp:753 +#, fuzzy +msgid "Set spacing:" +msgstr "Διάστιχο:" + +# +#. #### Y Padding #### +#: ../../po/../src/dialogs/tiledialog.cpp:777 +#, fuzzy +msgid "Row spacing: " +msgstr "Διάστιχο:" + +#: ../../po/../src/dialogs/tiledialog.cpp:786 +#, fuzzy +msgid "Vertical spacing between rows" +msgstr "Κατακόρυφες Ρίγες" + +# +#. #### X padding #### +#: ../../po/../src/dialogs/tiledialog.cpp:795 +#, fuzzy +msgid "Column spacing:" +msgstr "Διάστιχο:" + +#: ../../po/../src/dialogs/tiledialog.cpp:804 +#, fuzzy +msgid "Horizontal spacing between columns" +msgstr "οριζόντιο" + +# +#: ../../po/../src/dialogs/tiledialog.cpp:818 +#, fuzzy +msgid "Arrange selected objects" +msgstr "Διαγραφή επιλεγμένου αντικειμένου" + +#: ../../po/../src/dialogs/xml-tree.cpp:178 +msgid "Click to select nodes, drag to rearrange." +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:189 +msgid "Click attribute to edit." +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:193 +#, c-format +msgid "" +"Attribute %s selected. Press Ctrl+Enter when done editing to " +"commit changes." +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:284 +msgid "Drag to reorder nodes" +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:304 +#, fuzzy +msgid "New element node" +msgstr "Έγγραφο" + +#: ../../po/../src/dialogs/xml-tree.cpp:326 +msgid "New text node" +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:347 +#, fuzzy +msgid "Duplicate node" +msgstr "Δημιουργία αντιγράφου" + +# +#: ../../po/../src/dialogs/xml-tree.cpp:368 +#, fuzzy +msgid "Delete node" +msgstr "Διαγραφή" + +#: ../../po/../src/dialogs/xml-tree.cpp:384 +#, fuzzy +msgid "Unindent node" +msgstr "Επεξεργασία Φακέλων" + +#: ../../po/../src/dialogs/xml-tree.cpp:399 +#, fuzzy +msgid "Indent node" +msgstr "Επεξεργασία Φακέλων" + +#: ../../po/../src/dialogs/xml-tree.cpp:411 +#, fuzzy +msgid "Raise node" +msgstr "Αρχικοποίηση" + +#: ../../po/../src/dialogs/xml-tree.cpp:423 +msgid "Lower node" +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:468 +#, fuzzy +msgid "Delete attribute" +msgstr "εμφάνιση ιδιοτήτων" + +#. TRANSLATORS: "Attribute" is a noun here +#: ../../po/../src/dialogs/xml-tree.cpp:513 +#, fuzzy +msgid "Attribute name" +msgstr "Ιδιότητα:" + +#. TRANSLATORS: "Set" is a verb here +#: ../../po/../src/dialogs/xml-tree.cpp:533 +#, fuzzy +msgid "Set attribute" +msgstr "εμφάνιση ιδιοτήτων" + +# +#. TRANSLATORS: "Set" is a verb here +#: ../../po/../src/dialogs/xml-tree.cpp:535 +#, fuzzy +msgid "Set" +msgstr "Επιλογή" + +#. TRANSLATORS: "Attribute" is a noun here +#: ../../po/../src/dialogs/xml-tree.cpp:558 +#, fuzzy +msgid "Attribute value" +msgstr "Ιδιότητες" + +#: ../../po/../src/dialogs/xml-tree.cpp:1318 +msgid "New element node..." +msgstr "" + +# +#: ../../po/../src/dialogs/xml-tree.cpp:1339 +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:100 +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:98 +#, fuzzy +msgid "Cancel" +msgstr "Αλλαγή" + +# +#: ../../po/../src/dialogs/xml-tree.cpp:1345 +#, fuzzy +msgid "Create" +msgstr "Δημιουργία γραμμής" + +#: ../../po/../src/dialogs/xml-tree.cpp:1458 +#, c-format +msgid "" +"Cannot set %s: Another element with value %s already exists!" +msgstr "" + +#: ../../po/../src/document.cpp:369 +#, fuzzy, c-format +msgid "New document %d" +msgstr "Έγγραφο" + +#: ../../po/../src/document.cpp:401 +#, c-format +msgid "Memory document %d" +msgstr "" + +#: ../../po/../src/document.cpp:524 +#, c-format +msgid "Unnamed document %d" +msgstr "" + +#. We hit green anchor, closing Green-Blue-Red +#: ../../po/../src/draw-context.cpp:441 +msgid "Path is closed." +msgstr "" + +#. We hit bot start and end of single curve, closing paths +#: ../../po/../src/draw-context.cpp:456 +msgid "Closing path." +msgstr "" + +#. alpha of color under cursor, to show in the statusbar +#. locale-sensitive printf is OK, since this goes to the UI, not into SVG +#: ../../po/../src/dropper-context.cpp:354 +#, c-format +msgid " alpha %.3g" +msgstr "" + +#. where the color is picked, to show in the statusbar +#: ../../po/../src/dropper-context.cpp:356 +#, c-format +msgid ", averaged with radius %d" +msgstr "" + +#: ../../po/../src/dropper-context.cpp:356 +msgid " under cursor" +msgstr "" + +#. message, to show in the statusbar +#: ../../po/../src/dropper-context.cpp:358 +msgid "Release mouse to set color." +msgstr "" + +#: ../../po/../src/dropper-context.cpp:358 +#: ../../po/../src/tools-switch.cpp:207 +msgid "" +"Click to set fill, Shift+click to set stroke; drag to " +"average color in area; with Alt to pick inverse color; Ctrl+C " +"to copy the color under mouse to clipboard" +msgstr "" + +#: ../../po/../src/extension/dependency.cpp:244 +msgid "Dependency::" +msgstr "" + +#: ../../po/../src/extension/dependency.cpp:245 +#, fuzzy +msgid " type: " +msgstr "Όλες οι ρυθμίσεις" + +#: ../../po/../src/extension/dependency.cpp:246 +#, fuzzy +msgid " location: " +msgstr "Επιλογή" + +#: ../../po/../src/extension/dependency.cpp:247 +msgid " string: " +msgstr "" + +#: ../../po/../src/extension/dependency.cpp:250 +#, fuzzy +msgid " description: " +msgstr "Θέση" + +#. static int i = 0; +#. std::cout << "Checking module[" << i++ << "]: " << name << std::endl; +#: ../../po/../src/extension/extension.cpp:244 +msgid "" +" This is caused by an improper .inx file for this extension. An improper ." +"inx file could have been caused by a faulty installation of Inkscape." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:247 +msgid "an ID was not defined for it." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:251 +msgid "there was no name defined for it." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:255 +msgid "the XML description of it got lost." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:259 +msgid "no implementation was defined for the extension." +msgstr "" + +#. std::cout << "Failed: " << *(_deps[i]) << std::endl; +#: ../../po/../src/extension/extension.cpp:266 +msgid "a dependency was not met." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:286 +msgid "Extension \"" +msgstr "" + +#: ../../po/../src/extension/extension.cpp:286 +msgid "\" failed to load because " +msgstr "" + +#: ../../po/../src/extension/extension.cpp:565 +#, c-format +msgid "Could not create extension error log file '%s'" +msgstr "" + +#. This is some filler text, needs to change before relase +#: ../../po/../src/extension/error-file.cpp:56 +msgid "" +"One or more extensions failed to load\n" +"\n" +"The failed extensions have been skipped. Inkscape will continue to run " +"normally but those extensions will be unavailable. For details to " +"troubleshoot this problem, please refer to the error log located at: " +msgstr "" + +#. This is some filler text, needs to change before relase +#: ../../po/../src/extension/error-file.cpp:65 +msgid "Show dialog on startup" +msgstr "" + +#: ../../po/../src/extension/implementation/script.cpp:845 +msgid "" +"Inkscape has received an error from the script that it called. The text " +"returned with the error is included below. Inkscape will continue working, " +"but the action you requested has been cancelled." +msgstr "" + +#: ../../po/../src/extension/implementation/script.cpp:858 +msgid "" +"Inkscape has received additional data from the script executed. The script " +"did not return an error, but this may indicate the results will not be as " +"expected." +msgstr "" + +#: ../../po/../src/extension/init.cpp:173 +msgid "Null external module directory name. Modules will not be loaded." +msgstr "" + +#: ../../po/../src/extension/init.cpp:187 +#, c-format +msgid "" +"Modules directory (%s) is unavailable. External modules in that directory " +"will not be loaded." +msgstr "" + +#: ../../po/../src/extension/internal/gnome.cpp:80 +#, fuzzy +msgid "Select printer" +msgstr "Επιλογή" + +#: ../../po/../src/extension/internal/gnome.cpp:131 +#, fuzzy +msgid "Inkscape: Print Preview" +msgstr "GHex (%s): Προεπισκόπηση Εκτύπωσης" + +#: ../../po/../src/extension/internal/grid.cpp:213 +#, fuzzy +msgid "Line Width" +msgstr "Πλάτος" + +#: ../../po/../src/extension/internal/grid.cpp:214 +#, fuzzy +msgid "Horizontal Spacing" +msgstr "οριζόντιο" + +#: ../../po/../src/extension/internal/grid.cpp:215 +#, fuzzy +msgid "Vertical Spacing" +msgstr "Κατακόρυφες Ρίγες" + +#: ../../po/../src/extension/internal/grid.cpp:216 +#, fuzzy +msgid "Horizontal Offset" +msgstr "οριζόντιο" + +#: ../../po/../src/extension/internal/grid.cpp:217 +#, fuzzy +msgid "Vertical Offset" +msgstr "Κατακόρυφες Ρίγες" + +# +#: ../../po/../src/extension/internal/ps.cpp:123 +#, fuzzy +msgid "Print Destination" +msgstr "Σε εκτύπωση" + +#. Print properties frame +#: ../../po/../src/extension/internal/ps.cpp:138 +#, fuzzy +msgid "Print properties" +msgstr " Ιδιότητες" + +#: ../../po/../src/extension/internal/ps.cpp:145 +msgid "Print using PostScript operators" +msgstr "" + +#: ../../po/../src/extension/internal/ps.cpp:147 +msgid "" +"Use PostScript vector operators. The resulting image is usually smaller in " +"file size and can be arbitrarily scaled, but alpha transparency and patterns " +"will be lost." +msgstr "" + +#: ../../po/../src/extension/internal/ps.cpp:152 +#, fuzzy +msgid "Print as bitmap" +msgstr "Εξαγωγή Αρχείου" + +#: ../../po/../src/extension/internal/ps.cpp:154 +msgid "" +"Print everything as bitmap. The resulting image is usually larger in file " +"size and cannot be arbitrarily scaled without quality loss, but all objects " +"will be rendered exactly as displayed." +msgstr "" + +#: ../../po/../src/extension/internal/ps.cpp:168 +msgid "Preferred resolution (dots per inch) of bitmap" +msgstr "" + +#: ../../po/../src/extension/internal/ps.cpp:182 +#, fuzzy +msgid "Resolution:" +msgstr "Επιλογή" + +# +#. Print destination frame +#: ../../po/../src/extension/internal/ps.cpp:186 +#, fuzzy +msgid "Print destination" +msgstr "Σε εκτύπωση" + +#: ../../po/../src/extension/internal/ps.cpp:192 +msgid "" +"Use '> filename' to print to file.\n" +"Use '| prog arg...' to pipe to a program." +msgstr "" + +#: ../../po/../src/extension/internal/ps.cpp:1227 +msgid "write error occurred" +msgstr "" + +# +#: ../../po/../src/extension/prefdialog.cpp:21 +#, fuzzy +msgid " Preferences" +msgstr "Προτιμίσεις Ναυτίλου" + +#. We can't call sp_ui_error_dialog because we may be +#. running from the console, in which case calling sp_ui +#. routines will cause a segfault. See bug 1000350 - bryce +#. sp_ui_error_dialog(_("Format autodetect failed. The file is being opened as SVG.")); +#: ../../po/../src/extension/system.cpp:105 +msgid "Format autodetect failed. The file is being opened as SVG." +msgstr "" + +#. TRANSLATORS: default.svg is localizable - this is the name of the default document +#. template. This way you can localize the default pagesize, translate the name of +#. the default layer, etc. If you wish to localize this file, please create a +#. localized share/templates/default.xx.svg file, where xx is your language code. +#: ../../po/../src/file.cpp:133 +#, fuzzy +msgid "default.svg" +msgstr "Διαγρ." + +#: ../../po/../src/file.cpp:215 ../../po/../src/file.cpp:900 +#, c-format +msgid "Failed to load the requested file %s" +msgstr "" + +#: ../../po/../src/file.cpp:240 +#, fuzzy +msgid "Document not saved yet. Cannot revert." +msgstr "Έγγραφο" + +#: ../../po/../src/file.cpp:246 +#, c-format +msgid "Changes will be lost! Are you sure you want to reload document %s?" +msgstr "" + +#: ../../po/../src/file.cpp:266 +#, fuzzy +msgid "Document reverted." +msgstr "Έγγραφο" + +#: ../../po/../src/file.cpp:268 +#, fuzzy +msgid "Document not reverted." +msgstr "Έγγραφο" + +#: ../../po/../src/file.cpp:382 +#, fuzzy +msgid "Select file to open" +msgstr "Επιλογή αρχείου προς ανάγνωση" + +#: ../../po/../src/file.cpp:518 +#, c-format +msgid "Removed %i unused definition in <defs>." +msgid_plural "Removed %i unused definitions in <defs>." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/file.cpp:523 +msgid "No unused definitions in <defs>." +msgstr "" + +#: ../../po/../src/file.cpp:548 +#, c-format +msgid "" +"No Inkscape extension found to save document (%s). This may have been " +"caused by an unknown filename extension." +msgstr "" + +#: ../../po/../src/file.cpp:549 ../../po/../src/file.cpp:557 +#, fuzzy +msgid "Document not saved." +msgstr "Έγγραφο" + +#: ../../po/../src/file.cpp:556 +#, c-format +msgid "File %s could not be saved." +msgstr "" + +#: ../../po/../src/file.cpp:566 +#, fuzzy +msgid "Document saved." +msgstr "Έγγραφο" + +#: ../../po/../src/file.cpp:614 +#, fuzzy, c-format +msgid "drawing%s" +msgstr "Σχεδίαση" + +#: ../../po/../src/file.cpp:620 +#, fuzzy, c-format +msgid "drawing-%d%s" +msgstr "Σχεδίαση" + +#: ../../po/../src/file.cpp:655 +#, fuzzy +msgid "Select file to save to" +msgstr "Επιλογή αρχείου προς ανάγνωση" + +#: ../../po/../src/file.cpp:739 +msgid "No changes need to be saved." +msgstr "" + +#: ../../po/../src/file.cpp:926 +#, fuzzy +msgid "Select file to import" +msgstr "Επιλογή αρχείου για φόρτωση" + +#: ../../po/../src/gradient-context.cpp:263 +msgid "Ctrl: snap gradient angle" +msgstr "" + +#: ../../po/../src/gradient-context.cpp:264 +msgid "Shift: draw gradient around the starting point" +msgstr "" + +#. We did an undoable action, but sp_document_done will be called by the knot when released +#. status text; we do not track coords because this branch is run once, not all the time +#. during drag +#: ../../po/../src/gradient-context.cpp:462 +#, c-format +msgid "Gradient for %d objects; with Ctrl to snap angle" +msgstr "" + +# +#: ../../po/../src/gradient-context.cpp:464 +#, fuzzy +msgid "Select objects on which to create gradient." +msgstr "Διαγραφή επιλεγμένου αντικειμένου" + +# +#: ../../po/../src/gradient-drag.cpp:65 +#, fuzzy +msgid "Linear gradient start" +msgstr "Προσθήκη νέου παροχέα" + +# +#. POINT_LG_P1 +#: ../../po/../src/gradient-drag.cpp:66 +#, fuzzy +msgid "Linear gradient end" +msgstr "Προσθήκη νέου παροχέα" + +# +#: ../../po/../src/gradient-drag.cpp:67 +#, fuzzy +msgid "Radial gradient center" +msgstr "Προσθήκη νέου παροχέα" + +# +#: ../../po/../src/gradient-drag.cpp:68 ../../po/../src/gradient-drag.cpp:69 +#, fuzzy +msgid "Radial gradient radius" +msgstr "Προσθήκη νέου παροχέα" + +# +#: ../../po/../src/gradient-drag.cpp:70 +#, fuzzy +msgid "Radial gradient focus" +msgstr "Προσθήκη νέου παροχέα" + +#: ../../po/../src/gradient-drag.cpp:659 +#, c-format +msgid "" +"%s for: %s%s; drag with Ctrl to snap angle, with Ctrl+Alt to " +"preserve angle, with Ctrl+Shift to scale around center" +msgstr "" + +# +#: ../../po/../src/gradient-drag.cpp:662 +#, fuzzy +msgid " (stroke)" +msgstr "ε χρήση" + +#: ../../po/../src/gradient-drag.cpp:665 +msgid "" +"Radial gradient center and focus; drag with Shift to " +"separate focus" +msgstr "" + +#: ../../po/../src/gradient-drag.cpp:667 +#, c-format +msgid "" +"Gradient point shared by %d gradients; drag with Shift to " +"separate" +msgstr "" + +#: ../../po/../src/helper/units.cpp:40 +#, fuzzy +msgid "Unit" +msgstr "&Μονάδες:" + +#: ../../po/../src/helper/units.cpp:40 +#, fuzzy +msgid "Units" +msgstr "&Μονάδες:" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Point" +msgstr "Σημείο" + +#: ../../po/../src/helper/units.cpp:41 +#, fuzzy +msgid "pt" +msgstr "στιγ." + +# +#: ../../po/../src/helper/units.cpp:41 +msgid "Points" +msgstr "Στιγμές" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Pt" +msgstr "" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Pixel" +msgstr "Εικονοστοιχείο" + +# +#: ../../po/../src/helper/units.cpp:42 +msgid "Pixels" +msgstr "Εικονοστοιχεία" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Px" +msgstr "" + +#. You can add new elements from this point forward +#: ../../po/../src/helper/units.cpp:44 ../share/extensions/straightseg.inx.h:2 +msgid "Percent" +msgstr "Ποσοστό" + +#: ../../po/../src/helper/units.cpp:44 +#, fuzzy +msgid "Percents" +msgstr "Ποσοστό" + +#: ../../po/../src/helper/units.cpp:45 +#, fuzzy +msgid "Millimeter" +msgstr "χιλιοστά" + +#: ../../po/../src/helper/units.cpp:45 +msgid "mm" +msgstr "mm" + +#: ../../po/../src/helper/units.cpp:45 +#, fuzzy +msgid "Millimeters" +msgstr "χιλιοστά" + +#: ../../po/../src/helper/units.cpp:46 +#, fuzzy +msgid "Centimeter" +msgstr "εκατοστά" + +#: ../../po/../src/helper/units.cpp:46 +msgid "cm" +msgstr "cm" + +#: ../../po/../src/helper/units.cpp:46 +#, fuzzy +msgid "Centimeters" +msgstr "εκατοστά" + +#: ../../po/../src/helper/units.cpp:47 +#, fuzzy +msgid "Meter" +msgstr "Κέντρο" + +#: ../../po/../src/helper/units.cpp:47 +#, fuzzy +msgid "m" +msgstr "Δείγμα" + +#: ../../po/../src/helper/units.cpp:47 +#, fuzzy +msgid "Meters" +msgstr "Κέντρο" + +#. no svg_unit +#: ../../po/../src/helper/units.cpp:48 +#, fuzzy +msgid "Inch" +msgstr "ίντσα" + +# +#: ../../po/../src/helper/units.cpp:48 +#, fuzzy +msgid "in" +msgstr "ημ" + +#: ../../po/../src/helper/units.cpp:48 +#, fuzzy +msgid "Inches" +msgstr "Αύξηση" + +#. Volatiles do not have default, so there are none here +#. TRANSLATORS: for info, see http://www.w3.org/TR/REC-CSS2/syndata.html#length-units +#: ../../po/../src/helper/units.cpp:51 +#, fuzzy +msgid "Em square" +msgstr "Τετράγωνο" + +#: ../../po/../src/helper/units.cpp:51 +#, fuzzy +msgid "em" +msgstr "Δείγμα" + +#: ../../po/../src/helper/units.cpp:51 +#, fuzzy +msgid "Em squares" +msgstr "Τετράγωνο" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/REC-CSS2/syndata.html#length-units +#: ../../po/../src/helper/units.cpp:53 +#, fuzzy +msgid "Ex square" +msgstr "Τετράγωνο" + +#: ../../po/../src/helper/units.cpp:53 +#, fuzzy +msgid "ex" +msgstr "Δεκαεξαδικό" + +#: ../../po/../src/helper/units.cpp:53 +#, fuzzy +msgid "Ex squares" +msgstr "Τετράγωνο" + +#: ../../po/../src/inkscape.cpp:468 +msgid "Untitled document" +msgstr "" + +#. Show nice dialog box +#: ../../po/../src/inkscape.cpp:497 +msgid "Inkscape encountered an internal error and will close now.\n" +msgstr "" + +#: ../../po/../src/inkscape.cpp:498 +msgid "" +"Automatic backups of unsaved documents were done to the following " +"locations:\n" +msgstr "" + +#: ../../po/../src/inkscape.cpp:499 +msgid "Automatic backup of the following documents failed:\n" +msgstr "" + +#: ../../po/../src/inkscape.cpp:634 +#, c-format +msgid "" +"Cannot create directory %s.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:635 +#, c-format +msgid "" +"%s is not a valid directory.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:636 +#, c-format +msgid "" +"Cannot create file %s.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:637 +#, c-format +msgid "" +"Cannot write file %s.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:638 +msgid "" +"Although Inkscape will run, it will use default settings,\n" +"and any changes made in preferences will not be saved." +msgstr "" + +#: ../../po/../src/inkscape.cpp:708 +#, c-format +msgid "" +"%s is not a regular file.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:709 +#, c-format +msgid "" +"%s not a valid XML file, or\n" +"you don't have read permissions on it.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:711 +#, c-format +msgid "" +"%s is not a valid menus file.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:712 +msgid "" +"Inkscape will run with default menus.\n" +"New menus will not be saved." +msgstr "" + +#. sp_ui_menu_append_check_item_from_verb(m, view, _("_Menu"), _("Show or hide the menu bar"), "menu", +#. checkitem_toggled, checkitem_update, 0); +#: ../../po/../src/interface.cpp:753 +msgid "Commands Bar" +msgstr "" + +# +#: ../../po/../src/interface.cpp:753 +#, fuzzy +msgid "Show or hide the Commands bar (under the menu)" +msgstr "Εμφάνιση κόμβων-δ" + +#: ../../po/../src/interface.cpp:755 +#, fuzzy +msgid "Tool Controls" +msgstr "Επιλογές Oaf" + +# +#: ../../po/../src/interface.cpp:755 +#, fuzzy +msgid "Show or hide the Tool Controls panel" +msgstr "Εμφάνιση κόμβων-δ" + +#: ../../po/../src/interface.cpp:757 +msgid "_Toolbox" +msgstr "" + +#: ../../po/../src/interface.cpp:757 +msgid "Show or hide the main toolbox (on the left)" +msgstr "" + +#: ../../po/../src/interface.cpp:763 +msgid "_Statusbar" +msgstr "" + +#: ../../po/../src/interface.cpp:763 +msgid "Show or hide the statusbar (at the bottom of the window)" +msgstr "" + +#: ../../po/../src/interface.cpp:820 +#, c-format +msgid "Verb \"%s\" Unknown" +msgstr "" + +#. TRANSLATORS: #%s is the id of the group e.g. , not a number. +#: ../../po/../src/interface.cpp:930 +#, fuzzy, c-format +msgid "Enter group #%s" +msgstr "Επεξεργασία Φακέλων" + +#: ../../po/../src/interface.cpp:941 +#, fuzzy +msgid "Go to parent" +msgstr "Αλλαγή κλίμακας ώστε να ταιριάξει η σελίδα" + +#: ../../po/../src/interface.cpp:972 +msgid "Could not parse SVG data" +msgstr "" + +#: ../../po/../src/interface.cpp:1135 +#, c-format +msgid "Overwrite %s" +msgstr "" + +#: ../../po/../src/interface.cpp:1153 +#, c-format +msgid "" +"The file %s already exists. Do you want to overwrite that file with the " +"current document?" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:59 +msgid "Jabber connection lost." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:72 +#, c-format +msgid "Sending message; %u message remaining in send queue." +msgid_plural "Sending message; %u messages remaining in send queue." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:78 +msgid "Receive queue empty." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:154 +#, c-format +msgid "Receiving change; %u change left to process." +msgid_plural "Receiving change; %u changes left to process." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:157 +#, c-format +msgid "%s has left the chatroom." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:221 +msgid "Nickname %1 is already in use. Please choose a different nickname." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:225 +msgid "An error was encountered while attempting to connect to the server." +msgstr "" + +#. Check to see if the user made any modifications to this document. If so, +#. we want to give them the option of (1) letting us clear their document or (2) +#. opening a new, blank document for the whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:131 +msgid "%1 has invited you to a whiteboard session." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:132 +msgid "Incoming whiteboard invitation from %1" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:135 +msgid "Do you wish to accept %1's whiteboard session invitation?" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:137 +msgid "" +"Would you like to accept %1's invitation in a new document window?\n" +"Accepting the invitation in your current window will discard unsaved changes." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:143 +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:198 +#, fuzzy +msgid "Accept invitation" +msgstr "Επιλογή" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:144 +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:199 +msgid "Decline invitation" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:145 +#, fuzzy +msgid "Accept invitation in new document window" +msgstr "Έγγραφο" + +#. We could not create a new desktop; ask the user if she or he wants to +#. replace the current document and accept the invitation, or reject the invitation. +#. TRANSLATORS: %1 is a userid here +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:196 +msgid "" +"A new document window could not be opened for a whiteboard session with %" +"1" +msgstr "" + +#. TRANSLATORS: %1 is the peer whom refused our invitation. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:238 +msgid "" +"The user %1 has refused your " +"whiteboard invitation.\n" +"\n" +msgstr "" + +#. TRANSLATORS: %1 is the peer whom refused our invitation, %2 is our Jabber identity. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:241 +msgid "" +"You are still connected to a Jabber server as %2, and may send an " +"invitation to %1 again, or you may send an invitation to a different " +"user." +msgstr "" + +#. TRANSLATORS: %1 is the peer whom we tried to contact, but is already in a whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:252 +msgid "" +"The user %1 is already in a " +"whiteboard session.\n" +"\n" +msgstr "" + +#. TRANSLATORS: %1 is the peer whom we tried to contact, but is already in a whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:255 +msgid "" +"You are still connected to a Jabber server as %1, and may send an " +"invitation to a different user." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/invitation-confirm-dialog.cpp:26 +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:24 +msgid "_Write session file:" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/message-processors.cpp:145 +#, c-format +msgid "%s has joined the chatroom." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/message-queue.cpp:87 +#, c-format +msgid "%u change in receive queue." +msgid_plural "%u changes in receive queue." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/jabber_whiteboard/message-queue.cpp:117 +#, c-format +msgid "%u change in send queue." +msgid_plural "%u changes in send queue." +msgstr[0] "" +msgstr[1] "" + +#. if ID is NULL, then we have a real problem -- we were not able to find a key +#. nor generate one. The only thing we can really do here is abort, since we have +#. no way to let the other client(s) uniquely identify this object. +#. FIXME: If this indicates a programming bug, then don't request translation with +#. * _(...): it is most useful in untranslated form so that developers may search for +#. * it when someone reports it in a bug report (as we want users to do for all bugs, +#. * as indicated by it being a g_warning string). +#. * +#. * Otherwise, if it is not a programming bug but a network error or a bug in the +#. * remote peer (perhaps running different software) or whatever, then present it in +#. * an alert box, and avoid use of technical jargon `NULL'. +#. +#: ../../po/../src/jabber_whiteboard/message-utilities.cpp:171 +msgid "" +"ID for new object is NULL even after generation and lookup attempts: the new " +"object will NOT be sent, nor will any of its child objects!" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:60 +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:995 +msgid "Select a location and filename" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:62 +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:997 +#, fuzzy +msgid "Set filename" +msgstr "όνομα αρχείου" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:301 +msgid "No SSL certificate was found." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:304 +msgid "The SSL certificate provided by the Jabber server is untrusted." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:307 +msgid "The SSL certificate provided by the Jabber server is expired." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:310 +msgid "" +"The SSL certificate provided by the Jabber server has not been activated." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:313 +msgid "" +"The SSL certificate provided by the Jabber server contains a hostname that " +"does not match the Jabber server's hostname." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:316 +msgid "" +"The SSL certificate provided by the Jabber server contains an invalid " +"fingerprint." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:319 +msgid "An unknown error occurred while setting up the SSL connection." +msgstr "" + +#. TRANSLATORS: %1 is the message that describes the specific error that occurred when +#. establishing the SSL connection. +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:325 +msgid "" +"%1\n" +"\n" +"Do you wish to continue connecting to the Jabber server?" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:328 +msgid "Continue connecting and ignore further errors" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:329 +msgid "Continue connecting, but warn me of further errors" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:330 +#, fuzzy +msgid "Cancel connection" +msgstr "Επιλογή" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:777 +#, c-format +msgid "Established whiteboard session with %s." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:785 +#, c-format +msgid "%s has left the whiteboard session." +msgstr "" + +#. Inform the user +#. TRANSLATORS: %1 is the name of the user that disconnected, %2 is the name of the user whom the disconnected user disconnected from. +#. This message is not used in a chatroom context. +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:790 +msgid "" +"The user %1 has left the " +"whiteboard session.\n" +"\n" +msgstr "" + +#. TRANSLATORS: %1 and %2 are userids +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:792 +msgid "" +"You are still connected to a Jabber server as %2, and may establish a " +"new session to %1 or a different user." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:988 +msgid "" +"Could not open file %1 for session recording.\n" +"The error encountered was: %2.\n" +"\n" +"You may select a different location to record the session, or you may opt to " +"not record this session." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:990 +msgid "Choose a different location" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:991 +msgid "Skip session recording" +msgstr "" + +#: ../../po/../src/knot.cpp:673 +msgid "Node or handle drag canceled." +msgstr "" + +#: ../../po/../src/libnrtype/FontFactory.cpp:358 +msgid "Ignoring font without family that will crash Pango" +msgstr "" + +#: ../../po/../src/main.cpp:395 +msgid "Print the Inkscape version number" +msgstr "" + +#: ../../po/../src/main.cpp:400 +msgid "Do not use X server (only process files from console)" +msgstr "" + +#: ../../po/../src/main.cpp:405 +msgid "Try to use X server (even if $DISPLAY is not set)" +msgstr "" + +#: ../../po/../src/main.cpp:410 +msgid "Open specified document(s) (option string may be excluded)" +msgstr "" + +# gconf/gconftool.c:219 +#: ../../po/../src/main.cpp:411 ../../po/../src/main.cpp:416 +#: ../../po/../src/main.cpp:421 ../../po/../src/main.cpp:483 +#: ../../po/../src/main.cpp:488 ../../po/../src/main.cpp:493 +msgid "FILENAME" +msgstr "ΟΝΟΜΑ ΑΡΧΕΙΟΥ" + +#: ../../po/../src/main.cpp:415 +msgid "Print document(s) to specified output file (use '| program' for pipe)" +msgstr "" + +#: ../../po/../src/main.cpp:420 +msgid "Export document to a PNG file" +msgstr "" + +#: ../../po/../src/main.cpp:425 +msgid "The resolution used for exporting SVG into bitmap (default 90)" +msgstr "" + +#: ../../po/../src/main.cpp:426 +msgid "DPI" +msgstr "" + +#: ../../po/../src/main.cpp:430 +msgid "" +"Exported area in SVG user units (default is the canvas; 0,0 is lower-left " +"corner)" +msgstr "" + +#: ../../po/../src/main.cpp:431 +msgid "x0:y0:x1:y1" +msgstr "" + +#: ../../po/../src/main.cpp:435 +msgid "Exported area is the entire drawing (not canvas)" +msgstr "" + +#: ../../po/../src/main.cpp:440 +msgid "" +"Snap the bitmap export area outwards to the nearest integer values (in SVG " +"user units)" +msgstr "" + +#: ../../po/../src/main.cpp:445 +msgid "The width of exported bitmap in pixels (overrides export-dpi)" +msgstr "" + +#: ../../po/../src/main.cpp:446 +msgid "WIDTH" +msgstr "" + +#: ../../po/../src/main.cpp:450 +msgid "The height of exported bitmap in pixels (overrides export-dpi)" +msgstr "" + +#: ../../po/../src/main.cpp:451 +msgid "HEIGHT" +msgstr "" + +#: ../../po/../src/main.cpp:455 +msgid "The ID of the object to export (overrides export-area)" +msgstr "" + +# +#: ../../po/../src/main.cpp:456 ../../po/../src/main.cpp:532 +#, fuzzy +msgid "ID" +msgstr "ID" + +#. TRANSLATORS: this means: "Only export the object whose id is given in --export-id". +#. See "man inkscape" for details. +#: ../../po/../src/main.cpp:462 +msgid "" +"Export just the object with export-id, hide all others (only with export-id)" +msgstr "" + +#: ../../po/../src/main.cpp:467 +msgid "Use stored filename and DPI hints when exporting (only with export-id)" +msgstr "" + +#: ../../po/../src/main.cpp:472 +msgid "Background color of exported bitmap (any SVG-supported color string)" +msgstr "" + +#: ../../po/../src/main.cpp:473 +msgid "COLOR" +msgstr "" + +#: ../../po/../src/main.cpp:477 +msgid "Background opacity of exported bitmap (either 0.0 to 1.0, or 1 to 255)" +msgstr "" + +#: ../../po/../src/main.cpp:478 +msgid "VALUE" +msgstr "" + +#: ../../po/../src/main.cpp:482 +msgid "Export document to plain SVG file (no sodipodi or inkscape namespaces)" +msgstr "" + +#: ../../po/../src/main.cpp:487 +#, fuzzy +msgid "Export document to a PS file" +msgstr "Εξαγωγή Αρχείου" + +#: ../../po/../src/main.cpp:492 +msgid "Export document to an EPS file" +msgstr "" + +# +#: ../../po/../src/main.cpp:497 +#, fuzzy +msgid "Convert text object to paths on export (EPS)" +msgstr "Διαγραφή επιλεγμένου αντικειμένου" + +#: ../../po/../src/main.cpp:502 +msgid "Export files with the bounding box set to the page size (EPS)" +msgstr "" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:508 +msgid "" +"Query the X coordinate of the drawing or, if specified, of the object with --" +"query-id" +msgstr "" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:514 +msgid "" +"Query the Y coordinate of the drawing or, if specified, of the object with --" +"query-id" +msgstr "" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:520 +msgid "" +"Query the width of the drawing or, if specified, of the object with --query-" +"id" +msgstr "" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:526 +msgid "" +"Query the height of the drawing or, if specified, of the object with --query-" +"id" +msgstr "" + +#: ../../po/../src/main.cpp:531 +msgid "The ID of the object whose dimensions are queried" +msgstr "" + +#. TRANSLATORS: this option makes Inkscape print the name (path) of the extension directory +#: ../../po/../src/main.cpp:537 +msgid "Print out the extension directory and exit" +msgstr "" + +#: ../../po/../src/main.cpp:542 +msgid "Show given files one-by-one, switch to next on any key/mouse event" +msgstr "" + +#: ../../po/../src/main.cpp:547 +msgid "Use the new Gtkmm GUI interface" +msgstr "" + +#: ../../po/../src/main.cpp:552 +msgid "Remove unused definitions from the defs section(s) of the document" +msgstr "" + +#: ../../po/../src/main.cpp:741 +msgid "" +"[OPTIONS...] [FILE...]\n" +"\n" +"Available options:" +msgstr "" + +# +#: ../../po/../src/menus-skeleton.h:17 +msgid "_New" +msgstr "_Νέο" + +# +#: ../../po/../src/menus-skeleton.h:22 +#, fuzzy +msgid "Open _Recent" +msgstr "_Άνοιγμα" + +# +#: ../../po/../src/menus-skeleton.h:53 +#, fuzzy +msgid "_Edit" +msgstr "Επεξεργασία" + +#: ../../po/../src/menus-skeleton.h:84 +#, fuzzy +msgid "_View" +msgstr "Νέα Προβολή" + +#: ../../po/../src/menus-skeleton.h:85 +#, fuzzy +msgid "_Zoom" +msgstr "Εστίαση" + +# +#: ../../po/../src/menus-skeleton.h:102 +#, fuzzy +msgid "Show/Hide" +msgstr "Εμφάνιση κόμβων-δ" + +# +#: ../../po/../src/menus-skeleton.h:107 +#, fuzzy +msgid "_Display mode" +msgstr "Εμφάνιση" + +# +#: ../../po/../src/menus-skeleton.h:126 +#, fuzzy +msgid "_Layer" +msgstr "Επιλογή" + +# +#: ../../po/../src/menus-skeleton.h:143 +#, fuzzy +msgid "_Object" +msgstr "Αντικείμενο" + +# +#: ../../po/../src/menus-skeleton.h:165 +#, fuzzy +msgid "_Path" +msgstr "Επικόλληση" + +# +#: ../../po/../src/menus-skeleton.h:188 +#, fuzzy +msgid "_Text" +msgstr "Κείμενο" + +# +#: ../../po/../src/menus-skeleton.h:200 +#, fuzzy +msgid "Effects" +msgstr "Αντικείμενο" + +#: ../../po/../src/menus-skeleton.h:207 +msgid "Whiteboa_rd" +msgstr "" + +# +#: ../../po/../src/menus-skeleton.h:220 +#, fuzzy +msgid "_Help" +msgstr "_Βοήθεια" + +#: ../../po/../src/menus-skeleton.h:222 +msgid "Tutorials" +msgstr "" + +#: ../../po/../src/node-context.cpp:382 +msgid "" +"Ctrl: toggle node type, snap handle angle, move hor/vert; Ctrl" +"+Alt: move along handles" +msgstr "" + +#: ../../po/../src/node-context.cpp:383 +msgid "" +"Shift: toggle node selection, disable snapping, rotate both handles" +msgstr "" + +#: ../../po/../src/node-context.cpp:384 +msgid "Alt: lock handle length; Ctrl+Alt: move along handles" +msgstr "" + +#: ../../po/../src/nodepath.cpp:1399 ../../po/../src/nodepath.cpp:1411 +#: ../../po/../src/nodepath.cpp:1492 ../../po/../src/nodepath.cpp:1504 +msgid "To join, you must have two endnodes selected." +msgstr "" + +#: ../../po/../src/nodepath.cpp:1633 ../../po/../src/nodepath.cpp:1647 +msgid "" +"Select two non-endpoint nodes on a path between which to delete " +"segments." +msgstr "" + +# +#: ../../po/../src/nodepath.cpp:1743 +#, fuzzy +msgid "Cannot find path between nodes." +msgstr "Εκκίνηση επιλεγμένου παροχέα" + +#: ../../po/../src/nodepath.cpp:2822 +#, c-format +msgid "" +"Node handle: angle %0.2f°, length %s; with Ctrl to snap " +"angle; with Alt to lock length; with Shift to rotate both " +"handles" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3351 +msgid "" +"Node: drag to edit the path; with Ctrl to snap to horizontal/" +"vertical; with Ctrl+Alt to snap to handles' directions" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3375 +msgid "" +"Node handle: drag to shape the curve; with Ctrl to snap angle; " +"with Alt to lock length; with Shift to rotate both handles" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3399 +msgid "" +"Node handle: drag to shape the curve; with Ctrl to snap angle; " +"with Alt to lock length; with Shift to rotate the opposite " +"handle in sync" +msgstr "" + +#. TRANSLATORS: "end" is an adjective here (NOT a verb) +#: ../../po/../src/nodepath.cpp:3591 +#, fuzzy +msgid "end node" +msgstr "Επεξεργασία Φακέλων" + +#. TRANSLATORS: "cusp" means "sharp" (cusp node); see also the Advanced Tutorial +#: ../../po/../src/nodepath.cpp:3596 +#, fuzzy +msgid "cusp" +msgstr "Εργ." + +#. TRANSLATORS: "smooth" is an adjective here +#: ../../po/../src/nodepath.cpp:3599 +msgid "smooth" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3601 +#, fuzzy +msgid "symmetric" +msgstr "Χρήση Μετρικού Συστήματος" + +#. TRANSLATORS: "end" is an adjective here (NOT a verb) +#: ../../po/../src/nodepath.cpp:3607 +msgid "end node, handle retracted (drag with Shift to extend)" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3609 +msgid "one handle retracted (drag with Shift to extend)" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3612 +msgid "both handles retracted (drag with Shift to extend)" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3624 +msgid "Drag nodes or node handles; arrow keys to move nodes" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3625 +msgid "Drag the node or its handles; arrow keys to move the node" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3651 ../../po/../src/nodepath.cpp:3663 +#, fuzzy +msgid "Select a single object to edit its nodes or handles." +msgstr "Διαγραφή επιλεγμένων αντικειμένων" + +#: ../../po/../src/nodepath.cpp:3655 +#, c-format +msgid "" +"0 out of %i node selected. Click, Shift+click, " +"or drag around nodes to select." +msgid_plural "" +"0 out of %i nodes selected. Click, Shift+click, " +"or drag around nodes to select." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/nodepath.cpp:3661 +msgid "Drag the handles of the object to modify it." +msgstr "" + +# +#: ../../po/../src/nodepath.cpp:3669 +#, fuzzy, c-format +msgid "%i of %i node selected; %s. %s." +msgid_plural "%i of %i nodes selected; %s. %s." +msgstr[0] "Εκκίνηση επιλεγμένου παροχέα" +msgstr[1] "Εκκίνηση επιλεγμένου παροχέα" + +# +#: ../../po/../src/nodepath.cpp:3675 +#, fuzzy, c-format +msgid "%i of %i node selected. %s." +msgid_plural "%i of %i nodes selected. %s." +msgstr[0] "Εκκίνηση επιλεγμένου παροχέα" +msgstr[1] "Εκκίνηση επιλεγμένου παροχέα" + +#: ../../po/../src/object-edit.cpp:493 +msgid "" +"Adjust the horizontal rounding radius; with Ctrl to make the " +"vertical radius the same" +msgstr "" + +#: ../../po/../src/object-edit.cpp:499 +msgid "" +"Adjust the vertical rounding radius; with Ctrl to make the " +"horizontal radius the same" +msgstr "" + +#: ../../po/../src/object-edit.cpp:506 ../../po/../src/object-edit.cpp:513 +msgid "" +"Adjust the width and height of the rectangle; with Ctrl to " +"lock ratio or stretch in one dimension only" +msgstr "" + +#: ../../po/../src/object-edit.cpp:686 +msgid "Adjust ellipse width, with Ctrl to make circle" +msgstr "" + +#: ../../po/../src/object-edit.cpp:689 +msgid "Adjust ellipse height, with Ctrl to make circle" +msgstr "" + +#: ../../po/../src/object-edit.cpp:692 +msgid "" +"Position the start point of the arc or segment; with Ctrl to " +"snap angle; drag inside the ellipse for arc, outside for " +"segment" +msgstr "" + +#: ../../po/../src/object-edit.cpp:695 +msgid "" +"Position the end point of the arc or segment; with Ctrl to " +"snap angle; drag inside the ellipse for arc, outside for " +"segment" +msgstr "" + +#: ../../po/../src/object-edit.cpp:800 +msgid "" +"Adjust the tip radius of the star or polygon; with Shift to " +"round; with Alt to randomize" +msgstr "" + +#: ../../po/../src/object-edit.cpp:803 +msgid "" +"Adjust the base radius of the star; with Ctrl to keep star " +"rays radial (no skew); with Shift to round; with Alt to " +"randomize" +msgstr "" + +#: ../../po/../src/object-edit.cpp:967 +msgid "" +"Roll/unroll the spiral from inside; with Ctrl to snap angle; " +"with Alt to converge/diverge" +msgstr "" + +#: ../../po/../src/object-edit.cpp:969 +msgid "" +"Roll/unroll the spiral from outside; with Ctrl to snap angle; " +"with Shift to scale/rotate" +msgstr "" + +#: ../../po/../src/object-edit.cpp:1006 +msgid "Adjust the offset distance" +msgstr "" + +#. TRANSLATORS: This refers to the pattern that's inside the object +#: ../../po/../src/object-edit.cpp:1036 +msgid "Move the pattern fill inside the object" +msgstr "" + +# +#: ../../po/../src/object-edit.cpp:1038 +#, fuzzy +msgid "Scale the pattern fill uniformly" +msgstr "Διαγραφή επιλεγμένου αντικειμένου" + +#: ../../po/../src/object-edit.cpp:1040 +msgid "Rotate the pattern fill; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/object-edit.cpp:1065 +msgid "Drag to resize the flowed text frame" +msgstr "" + +# +#. Item dialog +#: ../../po/../src/object-ui.cpp:106 +#, fuzzy +msgid "Object _Properties" +msgstr "Ιδιότητες αντικειμένου" + +#. Select item +#: ../../po/../src/object-ui.cpp:116 +#, fuzzy +msgid "_Select This" +msgstr "Επιλογή θέματος:" + +# +#. Create link +#: ../../po/../src/object-ui.cpp:126 +#, fuzzy +msgid "_Create Link" +msgstr "Δημιουργία γραμμής" + +#. "Ungroup" +#: ../../po/../src/object-ui.cpp:199 ../../po/../src/verbs.cpp:1931 +msgid "_Ungroup" +msgstr "_Απομαδοποίηση" + +#. Link dialog +#: ../../po/../src/object-ui.cpp:239 +#, fuzzy +msgid "Link _Properties" +msgstr " Ιδιότητες" + +#. Select item +#: ../../po/../src/object-ui.cpp:249 +#, fuzzy +msgid "_Follow Link" +msgstr "Ακολούθηση συμβολικών συνδέσμων" + +#. Reset transformations +#: ../../po/../src/object-ui.cpp:254 +#, fuzzy +msgid "_Remove Link" +msgstr "Διαγραφή συνδέσμου" + +#. Link dialog +#: ../../po/../src/object-ui.cpp:303 +#, fuzzy +msgid "Image _Properties" +msgstr "Ιδιότητες Εικόνας" + +#. Item dialog +#: ../../po/../src/object-ui.cpp:344 +#, fuzzy +msgid "_Fill and Stroke" +msgstr "Ρυθμίσεις επιφάνειας εργασίας" + +#: ../../po/../src/path-chemistry.cpp:58 +#, fuzzy +msgid "Select at least two objects to combine." +msgstr "Διαγραφή επιλεγμένων αντικειμένων" + +# +#: ../../po/../src/path-chemistry.cpp:65 +#, fuzzy +msgid "At least one of the objects is not a path, cannot combine." +msgstr "Διαγραφή επιλεγμένου αντικειμένου" + +#: ../../po/../src/path-chemistry.cpp:73 +msgid "" +"You cannot combine objects from different groups or layers." +msgstr "" + +# +#: ../../po/../src/path-chemistry.cpp:155 +#, fuzzy +msgid "Select path(s) to break apart." +msgstr "Διαγραφή επιλεγμένου αντικειμένου" + +#: ../../po/../src/path-chemistry.cpp:231 +msgid "No path(s) to break apart in the selection." +msgstr "" + +# +#: ../../po/../src/path-chemistry.cpp:252 +#, fuzzy +msgid "Select object(s) to convert to path." +msgstr "Διαγραφή επιλεγμένου αντικειμένου" + +# +#: ../../po/../src/path-chemistry.cpp:297 +#, fuzzy +msgid "No objects to convert to path in the selection." +msgstr "Διαγραφή επιλεγμένου αντικειμένου" + +#: ../../po/../src/path-chemistry.cpp:345 +#, fuzzy +msgid "Select path(s) to reverse." +msgstr "Αποθήκευση επιλογής" + +#: ../../po/../src/path-chemistry.cpp:370 +msgid "No paths to reverse in the selection." +msgstr "" + +#: ../../po/../src/pen-context.cpp:379 ../../po/../src/pencil-context.cpp:233 +#, fuzzy +msgid "Continuing selected path" +msgstr "Αντιγραφή επιλεγμένης εργασίας" + +#: ../../po/../src/pen-context.cpp:390 ../../po/../src/pencil-context.cpp:242 +#, fuzzy +msgid "Creating new path" +msgstr "Έγγραφο" + +#: ../../po/../src/pen-context.cpp:394 ../../po/../src/pencil-context.cpp:246 +#, fuzzy +msgid "Appending to selected path" +msgstr "Αντιγραφή ώρας στο επιλεγμένο" + +#: ../../po/../src/pen-context.cpp:538 +msgid "Click or click and drag to close and finish the path." +msgstr "" + +#: ../../po/../src/pen-context.cpp:548 +msgid "" +"Click or click and drag to continue the path from this point." +msgstr "" + +#: ../../po/../src/pen-context.cpp:857 +#, c-format +msgid "" +"%s: angle %3.2f°, distance %s; with Ctrl to snap angle, " +"Enter to finish the path" +msgstr "" + +#: ../../po/../src/pen-context.cpp:882 +#, c-format +msgid "" +"Curve handle: angle %3.2f°, length %s; with Ctrl to snap " +"angle" +msgstr "" + +#: ../../po/../src/pen-context.cpp:912 +#, c-format +msgid "" +"%s: angle %3.2f°, length %s; with Ctrl to snap angle, " +"with Shift to move this handle only" +msgstr "" + +#: ../../po/../src/pen-context.cpp:946 +#, fuzzy +msgid "Finishing pen" +msgstr "Γροιλανδία" + +#: ../../po/../src/pencil-context.cpp:320 +msgid "Release here to close and finish the path." +msgstr "" + +#: ../../po/../src/pencil-context.cpp:326 +#, fuzzy +msgid "Drawing a freehand path" +msgstr "Λαβή συρταριού" + +#: ../../po/../src/pencil-context.cpp:331 +msgid "Drag to continue the path from this point." +msgstr "" + +#. Write curves to object +#: ../../po/../src/pencil-context.cpp:390 +#, fuzzy +msgid "Finishing freehand" +msgstr "Γροιλανδία" + +#: ../../po/../src/rect-context.cpp:387 +msgid "" +"Ctrl: make square or integer-ratio rect, lock a rounded corner " +"circular" +msgstr "" + +#: ../../po/../src/rect-context.cpp:549 +#, c-format +msgid "" +"Rectangle: %s × %s; with Ctrl to make square or integer-" +"ratio rectangle; with Shift to draw around the starting point" +msgstr "" + +#: ../../po/../src/select-context.cpp:243 +#, fuzzy +msgid "Move canceled." +msgstr "Επιλογή" + +#: ../../po/../src/select-context.cpp:252 +#, fuzzy +msgid "Selection canceled." +msgstr "Επιλογή" + +#: ../../po/../src/select-context.cpp:642 +msgid "Ctrl: select in groups, move hor/vert" +msgstr "" + +#: ../../po/../src/select-context.cpp:643 +msgid "Shift: toggle select, force rubberband, disable snapping" +msgstr "" + +#: ../../po/../src/select-context.cpp:644 +msgid "Alt: select under, move selected" +msgstr "" + +# +#: ../../po/../src/select-context.cpp:798 +#, fuzzy +msgid "Selected object is not a group. Cannot enter." +msgstr "Διαγραφή επιλεγμένου αντικειμένου" + +#: ../../po/../src/select-context.cpp:876 +#, c-format +msgid "" +"Move by %s, %s; with Ctrl to restrict to horizontal/vertical; " +"with Shift to disable snapping" +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:228 +msgid "Nothing was deleted." +msgstr "" + +# +#: ../../po/../src/selection-chemistry.cpp:259 +#, fuzzy +msgid "Select object(s) to duplicate." +msgstr "Διαγραφή επιλεγμένου αντικειμένου" + +#: ../../po/../src/selection-chemistry.cpp:420 +#, fuzzy +msgid "Select two or more objects to group." +msgstr "Αποθήκευση επιλογής" + +#: ../../po/../src/selection-chemistry.cpp:428 +#, fuzzy +msgid "Select at least two objects to group." +msgstr "Διαγραφή επιλεγμένων αντικειμένων" + +#: ../../po/../src/selection-chemistry.cpp:513 +#, fuzzy +msgid "Select a group to ungroup." +msgstr "Αποθήκευση επιλογής" + +#: ../../po/../src/selection-chemistry.cpp:554 +msgid "No groups to ungroup in the selection." +msgstr "" + +# +#: ../../po/../src/selection-chemistry.cpp:623 +#, fuzzy +msgid "Select objects to raise." +msgstr "Διαγραφή επιλεγμένου αντικειμένου" + +#: ../../po/../src/selection-chemistry.cpp:629 +#: ../../po/../src/selection-chemistry.cpp:681 +#: ../../po/../src/selection-chemistry.cpp:715 +#: ../../po/../src/selection-chemistry.cpp:773 +msgid "" +"You cannot raise/lower objects from different groups or layers." +msgstr "" + +# +#: ../../po/../src/selection-chemistry.cpp:673 +#, fuzzy +msgid "Select object(s) to raise to top." +msgstr "Διαγραφή επιλεγμένου αντικειμένου" + +# +#: ../../po/../src/selection-chemistry.cpp:709 +#, fuzzy +msgid "Select object(s) to lower." +msgstr "Διαγραφή επιλεγμένου αντικειμένου" + +# +#: ../../po/../src/selection-chemistry.cpp:765 +#, fuzzy +msgid "Select object(s) to lower to bottom." +msgstr "Διαγραφή επιλεγμένου αντικειμένου" + +#: ../../po/../src/selection-chemistry.cpp:806 +msgid "Nothing to undo." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:813 +msgid "Nothing to redo." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:969 +msgid "Nothing was copied." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1051 +msgid "Current layer is hidden. Unhide it to be able to paste to it." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1055 +msgid "Current layer is locked. Unlock it to be able to paste to it." +msgstr "" + +# +#: ../../po/../src/selection-chemistry.cpp:1068 +#: ../../po/../src/selection-chemistry.cpp:1103 +#, fuzzy +msgid "Nothing on the clipboard." +msgstr "Αντιγραφή επιλογής στο τεμάχιο" + +# +#: ../../po/../src/selection-chemistry.cpp:1109 +#, fuzzy +msgid "Select object(s) to paste style to." +msgstr "Διαγραφή επιλεγμένου αντικειμένου" + +# +#: ../../po/../src/selection-chemistry.cpp:1128 +#, fuzzy +msgid "Select object(s) to move to the layer above." +msgstr "Διαγραφή επιλεγμένου αντικειμένου" + +#: ../../po/../src/selection-chemistry.cpp:1146 +#, fuzzy +msgid "No more layers above." +msgstr "Έγγραφο" + +# +#: ../../po/../src/selection-chemistry.cpp:1160 +#, fuzzy +msgid "Select object(s) to move to the layer below." +msgstr "Διαγραφή επιλεγμένου αντικειμένου" + +#: ../../po/../src/selection-chemistry.cpp:1178 +#, fuzzy +msgid "No more layers below." +msgstr "Έγγραφο" + +#: ../../po/../src/selection-chemistry.cpp:1811 +#, fuzzy +msgid "Select a clone to unlink." +msgstr "Επιλογή αρχείου προς ανάγνωση" + +#: ../../po/../src/selection-chemistry.cpp:1842 +msgid "No clones to unlink in the selection." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1859 +msgid "" +"Select a clone to go to its original. Select a linked offset " +"to go to its source. Select a text on path to go to the path. Select " +"a flowed text to go to its frame." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1882 +msgid "" +"Cannot find the object to select (orphaned clone, offset, textpath, " +"flowed text?)" +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1888 +msgid "" +"The object you're trying to select is not visible (it is in <" +"defs>)" +msgstr "" + +# +#: ../../po/../src/selection-chemistry.cpp:1915 +#, fuzzy +msgid "Select object(s) to convert to pattern." +msgstr "Διαγραφή επιλεγμένου αντικειμένου" + +# +#: ../../po/../src/selection-chemistry.cpp:2006 +#, fuzzy +msgid "Select an object with pattern fill to extract objects from." +msgstr "Διαγραφή επιλεγμένου αντικειμένου" + +# +#: ../../po/../src/selection-chemistry.cpp:2059 +#, fuzzy +msgid "No pattern fills in the selection." +msgstr "Διαγραφή επιλεγμένου αντικειμένου" + +# +#: ../../po/../src/selection-chemistry.cpp:2079 +#, fuzzy +msgid "Select object(s) to make a bitmap copy." +msgstr "Διαγραφή επιλεγμένου αντικειμένου" + +#: ../../po/../src/selection-describer.cpp:37 +msgid "Click selection to toggle scale/rotation handles" +msgstr "" + +#. no items +#: ../../po/../src/selection-describer.cpp:39 +msgid "" +"No objects selected. Click, Shift+click, or drag around objects to select." +msgstr "" + +#: ../../po/../src/selection-describer.cpp:51 +#, fuzzy, c-format +msgid " in layer %s" +msgstr "Αρχικοποίηση" + +#: ../../po/../src/selection-describer.cpp:54 +#, fuzzy, c-format +msgid " in layer %s" +msgstr "Αρχικοποίηση" + +#: ../../po/../src/selection-describer.cpp:66 +msgid "Use Shift+D to look up original" +msgstr "" + +#: ../../po/../src/selection-describer.cpp:70 +msgid "Use Shift+D to look up path" +msgstr "" + +#: ../../po/../src/selection-describer.cpp:74 +msgid "Use Shift+D to look up frame" +msgstr "" + +# +#: ../../po/../src/selection-describer.cpp:84 +#, fuzzy, c-format +msgid "%i object selected" +msgid_plural "%i objects selected" +msgstr[0] "Εκκίνηση επιλεγμένου παροχέα" +msgstr[1] "Εκκίνηση επιλεγμένου παροχέα" + +#: ../../po/../src/selection-describer.cpp:90 +#, c-format +msgid "%s%s. %s." +msgstr "" + +# +#: ../../po/../src/selection-describer.cpp:94 +#, fuzzy, c-format +msgid "%s in %i layer. %s." +msgid_plural "%s in %i layers. %s." +msgstr[0] "Εκκίνηση επιλεγμένου παροχέα" +msgstr[1] "Εκκίνηση επιλεγμένου παροχέα" + +#: ../../po/../src/seltrans.cpp:498 +msgid "" +"Center of rotation and skewing: drag to reposition; scaling with " +"Shift also uses this center" +msgstr "" + +#: ../../po/../src/seltrans.cpp:514 +msgid "" +"Squeeze or stretch selection; with Ctrl to scale uniformly; " +"with Shift to scale around rotation center" +msgstr "" + +#: ../../po/../src/seltrans.cpp:515 +msgid "" +"Scale selection; with Ctrl to scale uniformly; with Shift to scale around rotation center" +msgstr "" + +#: ../../po/../src/seltrans.cpp:519 +msgid "" +"Skew selection; with Ctrl to snap angle; with Shift to " +"skew around the opposite side" +msgstr "" + +#: ../../po/../src/seltrans.cpp:520 +msgid "" +"Rotate selection; with Ctrl to snap angle; with Shift " +"to rotate around the opposite corner" +msgstr "" + +#: ../../po/../src/seltrans.cpp:829 ../../po/../src/seltrans.cpp:909 +#, c-format +msgid "Scale: %0.2f%% x %0.2f%%; with Ctrl to lock ratio" +msgstr "" + +#. TRANSLATORS: don't modify the first ";" (it will NOT be displayed as ";" - only the second one will be) +#: ../../po/../src/seltrans.cpp:984 +#, c-format +msgid "Skew: %0.2f°; with Ctrl to snap angle" +msgstr "" + +#. TRANSLATORS: don't modify the first ";" (it will NOT be displayed as ";" - only the second one will be) +#: ../../po/../src/seltrans.cpp:1035 +#, c-format +msgid "Rotate: %0.2f°; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/seltrans.cpp:1090 +#, fuzzy, c-format +msgid "Move center to %s, %s" +msgstr "σύνδεσμος στο %s" + +#: ../../po/../src/slideshow.cpp:90 +#, fuzzy +msgid "Inkscape slideshow" +msgstr "Συμπαγές" + +#: ../../po/../src/sp-anchor.cpp:181 +#, fuzzy, c-format +msgid "Link to %s" +msgstr "σύνδεσμος στο %s" + +#: ../../po/../src/sp-anchor.cpp:185 +#, fuzzy +msgid "Link without URI" +msgstr "σύνδεσμος στο %s" + +# +#: ../../po/../src/sp-ellipse.cpp:438 ../../po/../src/sp-ellipse.cpp:870 +#, fuzzy +msgid "Ellipse" +msgstr "Έλλειψη" + +# +#: ../../po/../src/sp-ellipse.cpp:583 +#, fuzzy +msgid "Circle" +msgstr "Αλλαγή" + +# +#: ../../po/../src/sp-ellipse.cpp:865 +#, fuzzy +msgid "Segment" +msgstr "Αλλαγή" + +#: ../../po/../src/sp-ellipse.cpp:867 +msgid "Arc" +msgstr "" + +#. TRANSLATORS: "Flow region" is an area where text is allowed to flow +#: ../../po/../src/sp-flowregion.cpp:276 +#, fuzzy +msgid "Flow region" +msgstr "Ακολούθηση συμβολικών συνδέσμων" + +#. TRANSLATORS: A region "cut out of" a flow region; text is not allowed to flow inside the +#. * flow excluded region. flowRegionExclude in SVG 1.2: see +#. * http://www.w3.org/TR/2004/WD-SVG12-20041027/flow.html#flowRegion-elem and +#. * http://www.w3.org/TR/2004/WD-SVG12-20041027/flow.html#flowRegionExclude-elem. +#: ../../po/../src/sp-flowregion.cpp:493 +msgid "Flow excluded region" +msgstr "" + +#: ../../po/../src/sp-flowtext.cpp:355 +#, c-format +msgid "Flowed text (%d characters)" +msgstr "" + +#: ../../po/../src/sp-flowtext.cpp:357 +#, c-format +msgid "Linked flowed text (%d characters)" +msgstr "" + +#: ../../po/../src/sp-guide.cpp:290 +#, fuzzy +msgid "vertical guideline" +msgstr "Κατακόρυφες Ρίγες" + +#: ../../po/../src/sp-guide.cpp:292 +#, fuzzy +msgid "horizontal guideline" +msgstr "οριζόντιο" + +#: ../../po/../src/sp-image.cpp:835 +msgid "embedded" +msgstr "" + +#: ../../po/../src/sp-image.cpp:839 +msgid "(null_pointer)" +msgstr "" + +# +#: ../../po/../src/sp-image.cpp:843 +#, fuzzy, c-format +msgid "Image with bad reference: %s" +msgstr "Προτιμίσεις Ναυτίλου" + +#: ../../po/../src/sp-image.cpp:844 +#, c-format +msgid "Image %d × %d: %s" +msgstr "" + +# +#: ../../po/../src/sp-item-group.cpp:390 +#, fuzzy, c-format +msgid "Group of %d object" +msgid_plural "Group of %d objects" +msgstr[0] "Εισαγωγή αντικειμένων" +msgstr[1] "Εισαγωγή αντικειμένων" + +# +#: ../../po/../src/sp-item.cpp:720 +msgid "Object" +msgstr "Αντικείμενο" + +# +#: ../../po/../src/sp-line.cpp:202 +#, fuzzy +msgid "Line" +msgstr "Αλλαγή" + +#. TRANSLATORS COMMENT: %s is either "outset" or "inset" depending on sign +#: ../../po/../src/sp-offset.cpp:433 +#, c-format +msgid "Linked offset, %s by %f pt" +msgstr "" + +#: ../../po/../src/sp-offset.cpp:434 ../../po/../src/sp-offset.cpp:438 +#, fuzzy +msgid "outset" +msgstr "Αντιγραφή επιλεγμένης εργασίας" + +#: ../../po/../src/sp-offset.cpp:434 ../../po/../src/sp-offset.cpp:438 +#, fuzzy +msgid "inset" +msgstr "ίντσα" + +#. TRANSLATORS COMMENT: %s is either "outset" or "inset" depending on sign +#: ../../po/../src/sp-offset.cpp:437 +#, c-format +msgid "Dynamic offset, %s by %f pt" +msgstr "" + +#: ../../po/../src/sp-path.cpp:127 +#, fuzzy, c-format +msgid "Path (%i node)" +msgid_plural "Path (%i nodes)" +msgstr[0] "σύνδεσμος στο %s" +msgstr[1] "σύνδεσμος στο %s" + +# +#: ../../po/../src/sp-polygon.cpp:216 +#, fuzzy +msgid "Polygon" +msgstr "Αλλαγή" + +# +#: ../../po/../src/sp-polyline.cpp:179 +#, fuzzy +msgid "Polyline" +msgstr "Έλλειψη" + +# +#: ../../po/../src/sp-rect.cpp:250 +#, fuzzy +msgid "Rectangle" +msgstr "Αλλαγή" + +#. TRANSLATORS: since turn count isn't an integer, please adjust the +#. string as needed to deal with an localized plural forms. +#: ../../po/../src/sp-spiral.cpp:305 +#, c-format +msgid "Spiral with %3f turns" +msgstr "" + +#: ../../po/../src/sp-star.cpp:288 +#, c-format +msgid "Star with %d vertex" +msgid_plural "Star with %d vertices" +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/sp-star.cpp:292 +#, c-format +msgid "Polygon with %d vertex" +msgid_plural "Polygon with %d vertices" +msgstr[0] "" +msgstr[1] "" + +#. TRANSLATORS: For description of font with no name. +#: ../../po/../src/sp-text.cpp:420 +msgid "<no name found>" +msgstr "" + +#: ../../po/../src/sp-text.cpp:426 +#, fuzzy, c-format +msgid "Text on path (%s, %s)" +msgstr "σύνδεσμος στο %s" + +#: ../../po/../src/sp-text.cpp:427 +#, fuzzy, c-format +msgid "Text (%s, %s)" +msgstr "σύνδεσμος στο %s" + +# +#. TRANSLATORS: Used for statusbar description for long chains: +#. * "Clone of: Clone of: ... in Layer 1". +#: ../../po/../src/sp-use.cpp:317 +#, fuzzy +msgid "..." +msgstr "_Άνοιγμα" + +#: ../../po/../src/sp-use.cpp:325 +#, fuzzy, c-format +msgid "Clone of: %s" +msgstr "σύνδεσμος στο %s" + +# +#: ../../po/../src/sp-use.cpp:329 +#, fuzzy +msgid "Orphaned clone" +msgstr "Αλλαγή" + +#: ../../po/../src/spiral-context.cpp:355 +msgid "Ctrl: snap angle" +msgstr "" + +#: ../../po/../src/spiral-context.cpp:357 +msgid "Alt: lock spiral radius" +msgstr "" + +#: ../../po/../src/spiral-context.cpp:469 +#, c-format +msgid "" +"Spiral: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/splivarot.cpp:106 +#, fuzzy +msgid "Select at least 2 paths to perform a boolean operation." +msgstr "Διαγραφή επιλεγμένων αντικειμένων" + +#: ../../po/../src/splivarot.cpp:112 +msgid "" +"Select exactly 2 paths to perform difference, XOR, division, or path " +"cut." +msgstr "" + +#: ../../po/../src/splivarot.cpp:129 ../../po/../src/splivarot.cpp:144 +msgid "" +"Unable to determine the z-order of the objects selected for " +"difference, XOR, division, or path cut." +msgstr "" + +# +#: ../../po/../src/splivarot.cpp:174 +#, fuzzy +msgid "" +"One of the objects is not a path, cannot perform boolean operation." +msgstr "Διαγραφή επιλεγμένου αντικειμένου" + +# +#. TRANSLATORS: "to outline" means "to convert stroke to path" +#: ../../po/../src/splivarot.cpp:554 +#, fuzzy +msgid "Select path(s) to outline." +msgstr "Διαγραφή επιλεγμένου αντικειμένου" + +#. TRANSLATORS: "to outline" means "to convert stroke to path" +#: ../../po/../src/splivarot.cpp:748 +msgid "No stroked paths to outline in the selection." +msgstr "" + +# +#: ../../po/../src/splivarot.cpp:832 +#, fuzzy +msgid "Selected object is not a path, cannot inset/outset." +msgstr "Διαγραφή επιλεγμένου αντικειμένου" + +# +#: ../../po/../src/splivarot.cpp:1040 +#, fuzzy +msgid "Select path(s) to inset/outset." +msgstr "Διαγραφή επιλεγμένου αντικειμένου" + +#: ../../po/../src/splivarot.cpp:1257 +msgid "No paths to inset/outset in the selection." +msgstr "" + +# +#: ../../po/../src/splivarot.cpp:1390 +#, fuzzy +msgid "Select path(s) to simplify." +msgstr "Διαγραφή επιλεγμένου αντικειμένου" + +#: ../../po/../src/splivarot.cpp:1417 +msgid "No paths to simplify in the selection." +msgstr "" + +#: ../../po/../src/star-context.cpp:362 +msgid "Ctrl: snap angle; keep rays radial" +msgstr "" + +#: ../../po/../src/star-context.cpp:470 +#, c-format +msgid "" +"Polygon: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/star-context.cpp:471 +#, c-format +msgid "Star: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/text-chemistry.cpp:90 +#, fuzzy +msgid "Select a text and a path to put text on path." +msgstr "Διαγραφή επιλεγμένων αντικειμένων" + +#: ../../po/../src/text-chemistry.cpp:95 +msgid "" +"This text object is already put to a path. Remove it from the path " +"first. Use Shift+D to look up its path." +msgstr "" + +#. rect is the only SPShape which is not yet, and thus SVG forbids us from putting text on it +#: ../../po/../src/text-chemistry.cpp:101 +msgid "" +"You cannot put text on a rectangle in this version. Convert rectangle to " +"path first." +msgstr "" + +#: ../../po/../src/text-chemistry.cpp:159 +#, fuzzy +msgid "Select a text on path to remove it from path." +msgstr "Διαγραφή επιλεγμένων αντικειμένων" + +# +#: ../../po/../src/text-chemistry.cpp:181 +#, fuzzy +msgid "No texts-on-paths in the selection." +msgstr "Διαγραφή επιλεγμένου αντικειμένου" + +#: ../../po/../src/text-chemistry.cpp:209 +#: ../../po/../src/text-chemistry.cpp:229 +#, fuzzy +msgid "Select text(s) to remove kerns from." +msgstr "Αποθήκευση επιλογής" + +#: ../../po/../src/text-chemistry.cpp:250 +#, fuzzy +msgid "" +"Select a text and one or more paths or shapes to flow text " +"into frame." +msgstr "Διαγραφή επιλεγμένων αντικειμένων" + +# +#: ../../po/../src/text-chemistry.cpp:322 +#, fuzzy +msgid "Select a flowed text to unflow it." +msgstr "Διαγραφή επιλεγμένου αντικειμένου" + +#: ../../po/../src/text-context.cpp:463 +msgid "Click to edit the text, drag to select part of the text." +msgstr "" + +#: ../../po/../src/text-context.cpp:465 +msgid "" +"Click to edit the flowed text, drag to select part of the text." +msgstr "" + +#: ../../po/../src/text-context.cpp:540 +msgid "Non-printable character" +msgstr "" + +#: ../../po/../src/text-context.cpp:589 +#, c-format +msgid "Unicode: %s: %s" +msgstr "" + +#: ../../po/../src/text-context.cpp:591 ../../po/../src/text-context.cpp:855 +msgid "Unicode: " +msgstr "" + +#: ../../po/../src/text-context.cpp:615 +msgid "Current layer is hidden. Unhide it to be able to add text." +msgstr "" + +#: ../../po/../src/text-context.cpp:619 +msgid "Current layer is locked. Unlock it to be able to add text." +msgstr "" + +#: ../../po/../src/text-context.cpp:673 +#, c-format +msgid "Flowed text frame: %s × %s" +msgstr "" + +#: ../../po/../src/text-context.cpp:708 ../../po/../src/text-context.cpp:1464 +msgid "Type text; Enter to start new line." +msgstr "" + +#: ../../po/../src/text-context.cpp:719 +msgid "Flowed text is created." +msgstr "" + +#: ../../po/../src/text-context.cpp:722 +msgid "" +"The frame is too small for the current font size. Flowed text not " +"created." +msgstr "" + +#: ../../po/../src/text-context.cpp:841 +msgid "No-break space" +msgstr "" + +#: ../../po/../src/text-context.cpp:1462 +msgid "Type flowed text; Enter to start new paragraph." +msgstr "" + +#: ../../po/../src/text-context.cpp:1472 ../../po/../src/tools-switch.cpp:189 +msgid "" +"Click to select or create text, drag to create flowed text; " +"then type." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:141 +msgid "" +"To edit a path, click, Shift+click, or drag around " +"nodes to select them, then drag nodes and handles. Click on an " +"object to select." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:147 +msgid "" +"Drag to create a rectangle. Drag controls to round corners and " +"resize. Click to select." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:153 +msgid "" +"Drag to create an ellipse. Drag controls to make an arc or " +"segment. Click to select." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:159 +msgid "" +"Drag to create a star. Drag controls to edit the star shape. " +"Click to select." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:165 +msgid "" +"Drag to create a spiral. Drag controls to edit the spiral " +"shape. Click to select." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:171 +msgid "" +"Drag to create a freehand line. Start drawing with Shift to " +"append to selected path." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:177 +msgid "" +"Click or click and drag to start a path; with Shift to " +"append to selected path." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:183 +msgid "" +"Drag to paint a calligraphic stroke. Left/right arrow " +"keys adjust width, up/down adjust angle." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:195 +msgid "" +"Drag or double click to create a gradient on selected objects, " +"drag handles to adjust gradients." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:201 +msgid "" +"Click or drag around an area to zoom in, Shift+click to " +"zoom out." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:213 +msgid "Click and drag between shapes to create a connector." +msgstr "" + +#: ../../po/../src/trace/potrace/inkscape-potrace.cpp:553 +#: ../../po/../src/trace/potrace/inkscape-potrace.cpp:654 +#, c-format +msgid "Trace: %d. %ld nodes" +msgstr "" + +# +#: ../../po/../src/trace/trace.cpp:53 ../../po/../src/trace/trace.cpp:62 +#: ../../po/../src/trace/trace.cpp:70 +#, fuzzy +msgid "Select an image to trace" +msgstr "Διαγραφή επιλεγμένου αντικειμένου" + +#: ../../po/../src/trace/trace.cpp:133 +#, fuzzy +msgid "Trace: No active document" +msgstr "Έγγραφο" + +#: ../../po/../src/trace/trace.cpp:154 +msgid "Trace: Image has no bitmap data" +msgstr "" + +# +#: ../../po/../src/trace/trace.cpp:267 +#, fuzzy, c-format +msgid "Trace: Done. %ld nodes created" +msgstr "Επιλέχθησαν \"%s\"" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:59 ../../po/../src/verbs.cpp:2212 +msgid "About Inkscape" +msgstr "" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:66 +msgid "_Splash" +msgstr "" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:68 +msgid "_Authors" +msgstr "" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:69 +#, fuzzy +msgid "_Translators" +msgstr "Μετασχηματισμός" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:70 +#, fuzzy +msgid "_License" +msgstr "ίντσα" + +#. TRANSLATORS: This is the filename of the `About Inkscape' picture in +#. the `screens' directory. Thus the translation of "about.svg" should be +#. the filename of its translated version, e.g. about.zh.svg for Chinese. +#. +#. N.B. about.svg changes once per release. (We should probably rename +#. the original to about-0.40.svg etc. as soon as we have a translation. +#. If we do so, then add an item to release-checklist saying that the +#. string here should be changed.) +#. FIXME? INKSCAPE_SCREENSDIR and "about.svg" are in UTF-8, not the +#. native filename encoding... and the filename passed to sp_document_new +#. should be in UTF-*8.. +#: ../../po/../src/ui/dialog/aboutbox.cpp:114 +msgid "about.svg" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:464 +msgid "Minimum horizontal gap (in px units) between bounding boxes" +msgstr "" + +#. TRANSLATORS: Horizontal gap +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:466 +#: ../../po/../src/widgets/toolbox.cpp:1556 +msgid "H:" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:474 +msgid "Minimum vertical gap (in px units) between bounding boxes" +msgstr "" + +#. TRANSLATORS: Vertical gap +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:476 +msgid "V:" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:734 +msgid "Align" +msgstr "Στοίχιση" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:735 +#, fuzzy +msgid "Distribute" +msgstr "Ιδιότητες" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:736 +msgid "Remove overlaps" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:737 +#, fuzzy +msgid "Nodes" +msgstr "Σημειώσεις" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:742 +#, fuzzy +msgid "Relative to: " +msgstr "κάθετο" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:747 +#, fuzzy +msgid "Align right sides of objects to left side of anchor" +msgstr "Προσθήκη νέου αντικειμένου στη βάση" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:750 +#, fuzzy +msgid "Align left sides" +msgstr "Εκτύπωση σε αρχείο" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:753 +#, fuzzy +msgid "Center on vertical axis" +msgstr "Κατακόρυφη αντιστροφή" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:756 +#, fuzzy +msgid "Align right sides" +msgstr "Κύλιση από αριστερά προς δεξιά" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:759 +#, fuzzy +msgid "Align left sides of objects to right side of anchor" +msgstr "Προσθήκη νέου αντικειμένου στη βάση" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:762 +#, fuzzy +msgid "Align bottoms of objects to top of anchor" +msgstr "Προσθήκη νέου αντικειμένου στη βάση" + +# +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:765 +#, fuzzy +msgid "Align tops" +msgstr "Αντικείμενο" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:768 +#, fuzzy +msgid "Center on horizontal axis" +msgstr "Οριζόντια αντιστροφή" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:771 +#, fuzzy +msgid "Align bottoms" +msgstr "άδεια θέση στον πάτο" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:774 +#, fuzzy +msgid "Align tops of objects to bottom of anchor" +msgstr "Προσθήκη νέου αντικειμένου στη βάση" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:779 +#, fuzzy +msgid "Align baseline anchors of texts vertically" +msgstr "Διαγραφή επιλεγμένων αντικειμένων" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:782 +#, fuzzy +msgid "Align baseline anchors of texts horizontally" +msgstr "Διαγραφή επιλεγμένων αντικειμένων" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:787 +msgid "Make horizontal gaps between objects equal" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:791 +#, fuzzy +msgid "Distribute left sides equidistantly" +msgstr "Διαγραφή επιλεγμένων αντικειμένων" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:794 +#, fuzzy +msgid "Distribute centers equidistantly horizontally" +msgstr "Διαγραφή επιλεγμένων αντικειμένων" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:797 +#, fuzzy +msgid "Distribute right sides equidistantly" +msgstr "Διαγραφή επιλεγμένων αντικειμένων" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:801 +msgid "Make vertical gaps between objects equal" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:805 +#, fuzzy +msgid "Distribute tops equidistantly" +msgstr "Διαγραφή επιλεγμένων αντικειμένων" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:808 +#, fuzzy +msgid "Distribute centers equidistantly vertically" +msgstr "Διαγραφή επιλεγμένων αντικειμένων" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:811 +msgid "Distribute bottoms equidistantly" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:816 +#, fuzzy +msgid "Distribute baseline anchors of texts horizontally" +msgstr "Διαγραφή επιλεγμένων αντικειμένων" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:819 +#, fuzzy +msgid "Distribute baseline anchors of texts vertically" +msgstr "Διαγραφή επιλεγμένων αντικειμένων" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:824 +msgid "Randomize centers in both dimensions" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:827 +msgid "Unclump objects: try to equalize edge-to-edge distances" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:832 +msgid "" +"Move objects as little as possible so that their bounding boxes do not " +"overlap" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:837 +#, fuzzy +msgid "Align selected nodes horizontally" +msgstr "Διαγραφή επιλεγμένων αντικειμένων" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:840 +#, fuzzy +msgid "Align selected nodes vertically" +msgstr "Διαγραφή επιλεγμένων αντικειμένων" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:843 +#, fuzzy +msgid "Distribute selected nodes horizontally" +msgstr "Διαγραφή επιλεγμένων αντικειμένων" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:846 +#, fuzzy +msgid "Distribute selected nodes vertically" +msgstr "Διαγραφή επιλεγμένων αντικειμένων" + +# +#. Rest of the widgetry +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:851 +#, fuzzy +msgid "Last selected" +msgstr "Επιλέχθησαν \"%s\"" + +# +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:852 +#, fuzzy +msgid "First selected" +msgstr "Επιλέχθησαν \"%s\"" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:853 +#, fuzzy +msgid "Biggest item" +msgstr "Ρυθμός bit" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:854 +#, fuzzy +msgid "Smallest item" +msgstr "Μικρή καταιγίδα με χαλάζι" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:856 +#: ../../po/../src/widgets/desktop-widget.cpp:1065 +msgid "Drawing" +msgstr "Σχεδίαση" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:91 +msgid "Metadata 1" +msgstr "" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:92 +msgid "Metadata 2" +msgstr "" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:187 +#, fuzzy +msgid "X coordinate of grid origin" +msgstr "Επιλογή χρώματος οθόνης για το Abiword" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:189 +#, fuzzy +msgid "Y coordinate of grid origin" +msgstr "Επιλογή χρώματος οθόνης για το Abiword" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:191 +#, fuzzy +msgid "Distance of vertical grid lines" +msgstr "η απόσταση μεταξύ των %1 και %2" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:193 +#, fuzzy +msgid "Distance of horizontal grid lines" +msgstr "η απόσταση μεταξύ των %1 και %2" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:197 +msgid "Max. snapping distance from grid" +msgstr "" + +# +#: ../../po/../src/ui/dialog/export.cpp:34 +msgid "Export" +msgstr "Εξαγωγή" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:36 +msgid "Fill" +msgstr "Γέμισμα" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:37 +#, fuzzy +msgid "Stroke Paint" +msgstr "Καπνός με άνεμο" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:38 +#, fuzzy +msgid "Stroke Style" +msgstr "Ρυθμίσεις επιφάνειας εργασίας" + +#: ../../po/../src/ui/dialog/find.cpp:34 +#, fuzzy +msgid "Find" +msgstr "Πλέγμα" + +# +#: ../../po/../src/ui/dialog/memory.cpp:96 +#, fuzzy +msgid "Heap" +msgstr "_Βοήθεια" + +#: ../../po/../src/ui/dialog/memory.cpp:97 +#, fuzzy +msgid "In Use" +msgstr "ίντσα" + +#. TRANSLATORS: "Slack" refers to memory which is in the heap but currently unused. +#. More typical usage is to call this memory "free" rather than "slack". +#: ../../po/../src/ui/dialog/memory.cpp:100 +#, fuzzy +msgid "Slack" +msgstr "Αστερίσκος" + +# +#: ../../po/../src/ui/dialog/memory.cpp:101 +#, fuzzy +msgid "Total" +msgstr "Αρχείο" + +#: ../../po/../src/ui/dialog/memory.cpp:141 +#: ../../po/../src/ui/dialog/memory.cpp:147 +#: ../../po/../src/ui/dialog/memory.cpp:154 +#: ../../po/../src/ui/dialog/memory.cpp:186 +#, fuzzy +msgid "Unknown" +msgstr "Άγνωστο σύστημα" + +#: ../../po/../src/ui/dialog/memory.cpp:167 +#, fuzzy +msgid "Combined" +msgstr "_Μεταγλώττιση" + +#: ../../po/../src/ui/dialog/memory.cpp:209 +#, fuzzy +msgid "Recalculate" +msgstr "Ορθογώνιο" + +# +#: ../../po/../src/ui/dialog/messages.cpp:74 +#, fuzzy +msgid "Ready." +msgstr "Κόκκινο:" + +#: ../../po/../src/ui/dialog/messages.cpp:75 +msgid "" +"Enable log display by setting dialogs.debug 'redirect' attribute to 1 in " +"preferences.xml" +msgstr "" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:184 +msgid "_Execute Python" +msgstr "" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:186 +msgid "_Execute Perl" +msgstr "" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:195 +msgid "Script" +msgstr "" + +# +#: ../../po/../src/ui/dialog/scriptdialog.cpp:205 +#, fuzzy +msgid "Output" +msgstr "Αποκοπή" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:215 +msgid "Errors" +msgstr "" + +#. Dialog organization +#: ../../po/../src/ui/dialog/session-player.cpp:73 +#, fuzzy +msgid "Session file" +msgstr "Αποθήκευση αρχείου" + +#: ../../po/../src/ui/dialog/session-player.cpp:74 +#, fuzzy +msgid "Playback controls" +msgstr "Επιλογές Oaf" + +#: ../../po/../src/ui/dialog/session-player.cpp:75 +#, fuzzy +msgid "Message information" +msgstr "Μετασχηματισμός" + +#. Active session file display +#. fixme: Does this mean the active file for the session, or the file for the active session? +#. Please indicate which with a TRANSLATORS comment. +#: ../../po/../src/ui/dialog/session-player.cpp:85 +msgid "Active session file:" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:86 +msgid "Delay (milliseconds):" +msgstr "" + +# +#. Unload/load buttons +#: ../../po/../src/ui/dialog/session-player.cpp:94 +#, fuzzy +msgid "Close file" +msgstr "Αρχείο core" + +#: ../../po/../src/ui/dialog/session-player.cpp:95 +#, fuzzy +msgid "Open new file" +msgstr "Άνοιγμα νέου παραθύρου" + +#: ../../po/../src/ui/dialog/session-player.cpp:96 +msgid "Set delay" +msgstr "" + +# +#: ../../po/../src/ui/dialog/session-player.cpp:138 +#, fuzzy +msgid "Rewind" +msgstr "Κόκκινο:" + +#: ../../po/../src/ui/dialog/session-player.cpp:139 +msgid "Go back one change" +msgstr "" + +# +#: ../../po/../src/ui/dialog/session-player.cpp:140 +#, fuzzy +msgid "Pause" +msgstr "Επικόλληση" + +#: ../../po/../src/ui/dialog/session-player.cpp:141 +msgid "Go forward one change" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:142 +msgid "Play" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:177 +#: ../../po/../src/verbs.cpp:1573 +msgid "Open session file" +msgstr "" + +#. ##Set up the Potrace panel +#. #### brightness #### +#. #### Multiple scanning#### +#. ----Hbox1 +#: ../../po/../src/ui/dialog/tracedialog.cpp:345 +#: ../../po/../src/ui/dialog/tracedialog.cpp:428 +#, fuzzy +msgid "Brightness" +msgstr "Ύψος" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:348 +msgid "Trace by a given brightness level" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:355 +msgid "Brightness cutoff for black/white" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:362 +#, fuzzy +msgid "Image Brightness" +msgstr "Μέγεθος Εικόνας:" + +#. #### canny edge detection #### +#. TRANSLATORS: "Canny" is the name of the inventor of this edge detection method +#: ../../po/../src/ui/dialog/tracedialog.cpp:369 +msgid "Optimal Edge Detection (Canny)" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:372 +msgid "Trace with edge detection by J. Canny's algorithm" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:388 +msgid "Brightness cutoff for adjacent pixels (determines edge thickness)" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:395 +#, fuzzy +msgid "Edge Detection" +msgstr "Επιλογή" + +#. #### quantization #### +#. TRANSLATORS: Color Quantization: the process of reducing the number of colors +#. in an image by selecting an optimized set of representative colors and then +#. re-applying this reduced set to the original image. +#: ../../po/../src/ui/dialog/tracedialog.cpp:404 +#, fuzzy +msgid "Color Quantization" +msgstr "Κολομβία" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:407 +msgid "Trace along the boundaries of reduced colors" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:414 +msgid "The number of reduced colors" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:416 +#, fuzzy +msgid "Colors:" +msgstr "Χρώμα:" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:421 +msgid "Quantization / Reduction" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:431 +msgid "Trace the given number of brightness levels" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:438 +#, fuzzy +msgid "Scans:" +msgstr "Σκίαση" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:440 +msgid "The desired number of scans" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:448 +msgid "Trace the given number of reduced colors" +msgstr "" + +#. ---Hbox3 +#: ../../po/../src/ui/dialog/tracedialog.cpp:454 +msgid "Monochrome" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:457 +msgid "Same as Color, but convert result to grayscale" +msgstr "" + +#. TRANSLATORS: "Stack" is a verb here +#: ../../po/../src/ui/dialog/tracedialog.cpp:460 +#, fuzzy +msgid "Stack" +msgstr "Αστερίσκος" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:463 +msgid "" +"Stack scans vertically (no gaps) or tile horizontally (usually with gaps)" +msgstr "" + +#. TRANSLATORS: "Smooth" is a verb here +#: ../../po/../src/ui/dialog/tracedialog.cpp:466 +msgid "Smooth" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:469 +msgid "Apply Gaussian blur to the bitmap before tracing" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:473 +msgid "Multiple Scanning" +msgstr "" + +#. #### Preview #### +#: ../../po/../src/ui/dialog/tracedialog.cpp:479 +#: ../../po/../src/ui/dialog/tracedialog.cpp:489 +#, fuzzy +msgid "Preview" +msgstr "Χρήση Προεπισκόπησης" + +#. do not expand +#: ../../po/../src/ui/dialog/tracedialog.cpp:483 +msgid "Preview the result without actual tracing" +msgstr "" + +#. #### swap black and white #### +#: ../../po/../src/ui/dialog/tracedialog.cpp:495 +msgid "Invert" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:499 +msgid "Invert black and white regions for single traces" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:503 +msgid "Thanks to Peter Selinger, http://potrace.sourceforge.net" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:506 +#, fuzzy +msgid "Credits" +msgstr "Κολομβία" + +#. done +#. TRANSLATORS: Potrace is an application for transforming bitmaps into +#. vector graphics (http://potrace.sourceforge.net/) +#: ../../po/../src/ui/dialog/tracedialog.cpp:514 +#, fuzzy +msgid "Potrace" +msgstr "Σημείο" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:527 +#, fuzzy +msgid "Abort a trace in progress" +msgstr "Το %s εισήχθη" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:531 +msgid "Execute the trace" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:80 +#: ../../po/../src/ui/dialog/transformation.cpp:90 +#, fuzzy +msgid "_Horizontal" +msgstr "οριζόντιο" + +#: ../../po/../src/ui/dialog/transformation.cpp:80 +msgid "Horizontal displacement (relative) or position (absolute)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:82 +#: ../../po/../src/ui/dialog/transformation.cpp:92 +#, fuzzy +msgid "_Vertical" +msgstr "Κατακόρυφες Ρίγες" + +#: ../../po/../src/ui/dialog/transformation.cpp:82 +msgid "Vertical displacement (relative) or position (absolute)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:84 +#, fuzzy +msgid "_Width" +msgstr "Πλάτος:" + +#: ../../po/../src/ui/dialog/transformation.cpp:84 +msgid "Horizontal size increment (absolute or percentage)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:86 +#, fuzzy +msgid "_Height" +msgstr "Ύψος:" + +#: ../../po/../src/ui/dialog/transformation.cpp:86 +msgid "Vertical size increment (absolute or percentage)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:88 +#, fuzzy +msgid "A_ngle" +msgstr "Διάστημα" + +# +#: ../../po/../src/ui/dialog/transformation.cpp:88 +#, fuzzy +msgid "Rotation angle (positive = counterclockwise)" +msgstr "Διαγραφή επιλεγμένου αντικειμένου" + +#: ../../po/../src/ui/dialog/transformation.cpp:90 +msgid "" +"Horizontal skew angle (positive = counterclockwise), or absolute " +"displacement, or percentage displacement" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:92 +msgid "" +"Vertical skew angle (positive = counterclockwise), or absolute displacement, " +"or percentage displacement" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:95 +#, fuzzy +msgid "Transformation matrix element A" +msgstr "Μετασχηματισμός" + +#: ../../po/../src/ui/dialog/transformation.cpp:96 +#, fuzzy +msgid "Transformation matrix element B" +msgstr "Μετασχηματισμός" + +#: ../../po/../src/ui/dialog/transformation.cpp:97 +#, fuzzy +msgid "Transformation matrix element C" +msgstr "Μετασχηματισμός" + +#: ../../po/../src/ui/dialog/transformation.cpp:98 +#, fuzzy +msgid "Transformation matrix element D" +msgstr "Μετασχηματισμός" + +#: ../../po/../src/ui/dialog/transformation.cpp:99 +#, fuzzy +msgid "Transformation matrix element E" +msgstr "Μετασχηματισμός" + +#: ../../po/../src/ui/dialog/transformation.cpp:100 +#, fuzzy +msgid "Transformation matrix element F" +msgstr "Μετασχηματισμός" + +#: ../../po/../src/ui/dialog/transformation.cpp:102 +#, fuzzy +msgid "Rela_tive move" +msgstr "κάθετο" + +#: ../../po/../src/ui/dialog/transformation.cpp:102 +msgid "" +"Add the specified relative displacement to the current position; otherwise, " +"edit the current absolute position directly" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:103 +msgid "Scale proportionally" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:103 +msgid "Preserve the width/height ratio of the scaled objects" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:104 +msgid "Apply to each _object separately" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:104 +msgid "" +"Apply the scale/rotate/skew to each selected object separately; otherwise, " +"transform the selection as a whole" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:105 +msgid "Edit c_urrent matrix" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:105 +msgid "" +"Edit the current transform= matrix; otherwise, post-multiply transform= by " +"this matrix" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:115 +#, fuzzy +msgid "_Move" +msgstr "Μετακίνηση" + +# +#: ../../po/../src/ui/dialog/transformation.cpp:118 +#, fuzzy +msgid "_Scale" +msgstr "Κλιμάκωση" + +#: ../../po/../src/ui/dialog/transformation.cpp:121 +#, fuzzy +msgid "_Rotate" +msgstr "Περιστροφή" + +#: ../../po/../src/ui/dialog/transformation.cpp:124 +#, fuzzy +msgid "Ske_w" +msgstr "Καπνός" + +#: ../../po/../src/ui/dialog/transformation.cpp:127 +msgid "Matri_x" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:141 +msgid "Reset the values on the current tab to defaults" +msgstr "" + +# +#: ../../po/../src/ui/dialog/transformation.cpp:148 +#, fuzzy +msgid "Apply transformation to selection" +msgstr "Επιλέξτε ενέργεια" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:43 +msgid "_Use SSL" +msgstr "" + +# +#. Construct dialog interface +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:68 +#, fuzzy +msgid "_Server:" +msgstr "Αρχείο" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:69 +#, fuzzy +msgid "_Username:" +msgstr "Όνομα Αρχείου:" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:70 +msgid "_Password:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:71 +msgid "P_ort:" +msgstr "" + +#. Buttons +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:99 +#, fuzzy +msgid "Connect" +msgstr "Περιεχόμενο" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:126 +msgid "Establishing connection to Jabber server %1 as user %2" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:131 +msgid "Failed to establish connection to Jabber server %1" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:136 +msgid "Authentication failed on Jabber server %1 as %2" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:141 +msgid "SSL initialization failed when connecting to Jabber server %1" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:147 +msgid "Connected to Jabber server %1 as %2" +msgstr "" + +#. Construct labels +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:75 +msgid "Chatroom _name:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:76 +msgid "Chatroom _server:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:77 +msgid "Chatroom _password:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:78 +msgid "Chatroom _handle:" +msgstr "" + +#. Button setup and callback registration +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:97 +msgid "Connect to chatroom" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:132 +msgid "Synchronizing with chatroom %1@%2 using the handle %3" +msgstr "" + +#. Construct dialog interface +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:78 +msgid "_User's Jabber ID:" +msgstr "" + +#. Buttons +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:82 +msgid "_Invite user" +msgstr "" + +# +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:83 +#, fuzzy +msgid "_Cancel" +msgstr "Αλλαγή" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:94 +msgid "Buddy List" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:170 +msgid "Sending whiteboard invitation to %1" +msgstr "" + +#. FIXME: strings are replaced by placeholders, NOT to be translated until the code is enabled +#. See http://sourceforge.net/mailarchive/message.php?msg_id=11746016 for details +#. File menu +#. Edit menu +#. View menu +#. Layer menu +#. Object menu +#. Path menu +#. add(Gtk::StockItem(CLEANUP, _("PLACEHOLDER, do not translate"))); (using Gtk::Stock::CLEAR) +#. Text menu +#. About menu +#. Tools toolbox +#. Select Tool controls +#. Node Tool controls +#. Calligraphy Tool controls +#. Session playback controls +#: ../../po/../src/ui/stock-items.cpp:34 ../../po/../src/ui/stock-items.cpp:35 +#: ../../po/../src/ui/stock-items.cpp:36 ../../po/../src/ui/stock-items.cpp:37 +#: ../../po/../src/ui/stock-items.cpp:38 ../../po/../src/ui/stock-items.cpp:39 +#: ../../po/../src/ui/stock-items.cpp:40 ../../po/../src/ui/stock-items.cpp:41 +#: ../../po/../src/ui/stock-items.cpp:42 ../../po/../src/ui/stock-items.cpp:43 +#: ../../po/../src/ui/stock-items.cpp:46 ../../po/../src/ui/stock-items.cpp:47 +#: ../../po/../src/ui/stock-items.cpp:48 ../../po/../src/ui/stock-items.cpp:49 +#: ../../po/../src/ui/stock-items.cpp:50 ../../po/../src/ui/stock-items.cpp:51 +#: ../../po/../src/ui/stock-items.cpp:52 ../../po/../src/ui/stock-items.cpp:53 +#: ../../po/../src/ui/stock-items.cpp:54 ../../po/../src/ui/stock-items.cpp:55 +#: ../../po/../src/ui/stock-items.cpp:56 ../../po/../src/ui/stock-items.cpp:57 +#: ../../po/../src/ui/stock-items.cpp:58 ../../po/../src/ui/stock-items.cpp:59 +#: ../../po/../src/ui/stock-items.cpp:62 ../../po/../src/ui/stock-items.cpp:63 +#: ../../po/../src/ui/stock-items.cpp:64 ../../po/../src/ui/stock-items.cpp:65 +#: ../../po/../src/ui/stock-items.cpp:66 ../../po/../src/ui/stock-items.cpp:67 +#: ../../po/../src/ui/stock-items.cpp:68 ../../po/../src/ui/stock-items.cpp:69 +#: ../../po/../src/ui/stock-items.cpp:70 ../../po/../src/ui/stock-items.cpp:71 +#: ../../po/../src/ui/stock-items.cpp:72 ../../po/../src/ui/stock-items.cpp:73 +#: ../../po/../src/ui/stock-items.cpp:74 ../../po/../src/ui/stock-items.cpp:75 +#: ../../po/../src/ui/stock-items.cpp:76 ../../po/../src/ui/stock-items.cpp:77 +#: ../../po/../src/ui/stock-items.cpp:78 ../../po/../src/ui/stock-items.cpp:79 +#: ../../po/../src/ui/stock-items.cpp:80 ../../po/../src/ui/stock-items.cpp:81 +#: ../../po/../src/ui/stock-items.cpp:82 ../../po/../src/ui/stock-items.cpp:83 +#: ../../po/../src/ui/stock-items.cpp:84 ../../po/../src/ui/stock-items.cpp:85 +#: ../../po/../src/ui/stock-items.cpp:86 ../../po/../src/ui/stock-items.cpp:87 +#: ../../po/../src/ui/stock-items.cpp:88 ../../po/../src/ui/stock-items.cpp:89 +#: ../../po/../src/ui/stock-items.cpp:92 ../../po/../src/ui/stock-items.cpp:93 +#: ../../po/../src/ui/stock-items.cpp:94 ../../po/../src/ui/stock-items.cpp:95 +#: ../../po/../src/ui/stock-items.cpp:96 ../../po/../src/ui/stock-items.cpp:97 +#: ../../po/../src/ui/stock-items.cpp:98 ../../po/../src/ui/stock-items.cpp:99 +#: ../../po/../src/ui/stock-items.cpp:100 +#: ../../po/../src/ui/stock-items.cpp:101 +#: ../../po/../src/ui/stock-items.cpp:102 +#: ../../po/../src/ui/stock-items.cpp:103 +#: ../../po/../src/ui/stock-items.cpp:104 +#: ../../po/../src/ui/stock-items.cpp:105 +#: ../../po/../src/ui/stock-items.cpp:108 +#: ../../po/../src/ui/stock-items.cpp:109 +#: ../../po/../src/ui/stock-items.cpp:110 +#: ../../po/../src/ui/stock-items.cpp:111 +#: ../../po/../src/ui/stock-items.cpp:112 +#: ../../po/../src/ui/stock-items.cpp:113 +#: ../../po/../src/ui/stock-items.cpp:114 +#: ../../po/../src/ui/stock-items.cpp:115 +#: ../../po/../src/ui/stock-items.cpp:116 +#: ../../po/../src/ui/stock-items.cpp:117 +#: ../../po/../src/ui/stock-items.cpp:118 +#: ../../po/../src/ui/stock-items.cpp:119 +#: ../../po/../src/ui/stock-items.cpp:120 +#: ../../po/../src/ui/stock-items.cpp:121 +#: ../../po/../src/ui/stock-items.cpp:122 +#: ../../po/../src/ui/stock-items.cpp:123 +#: ../../po/../src/ui/stock-items.cpp:124 +#: ../../po/../src/ui/stock-items.cpp:125 +#: ../../po/../src/ui/stock-items.cpp:126 +#: ../../po/../src/ui/stock-items.cpp:127 +#: ../../po/../src/ui/stock-items.cpp:130 +#: ../../po/../src/ui/stock-items.cpp:131 +#: ../../po/../src/ui/stock-items.cpp:132 +#: ../../po/../src/ui/stock-items.cpp:133 +#: ../../po/../src/ui/stock-items.cpp:134 +#: ../../po/../src/ui/stock-items.cpp:135 +#: ../../po/../src/ui/stock-items.cpp:136 +#: ../../po/../src/ui/stock-items.cpp:137 +#: ../../po/../src/ui/stock-items.cpp:138 +#: ../../po/../src/ui/stock-items.cpp:139 +#: ../../po/../src/ui/stock-items.cpp:140 +#: ../../po/../src/ui/stock-items.cpp:141 +#: ../../po/../src/ui/stock-items.cpp:142 +#: ../../po/../src/ui/stock-items.cpp:143 +#: ../../po/../src/ui/stock-items.cpp:144 +#: ../../po/../src/ui/stock-items.cpp:145 +#: ../../po/../src/ui/stock-items.cpp:146 +#: ../../po/../src/ui/stock-items.cpp:150 +#: ../../po/../src/ui/stock-items.cpp:151 +#: ../../po/../src/ui/stock-items.cpp:152 +#: ../../po/../src/ui/stock-items.cpp:153 +#: ../../po/../src/ui/stock-items.cpp:156 +#: ../../po/../src/ui/stock-items.cpp:157 +#: ../../po/../src/ui/stock-items.cpp:158 +#: ../../po/../src/ui/stock-items.cpp:161 +#: ../../po/../src/ui/stock-items.cpp:162 +#: ../../po/../src/ui/stock-items.cpp:163 +#: ../../po/../src/ui/stock-items.cpp:164 +#: ../../po/../src/ui/stock-items.cpp:165 +#: ../../po/../src/ui/stock-items.cpp:166 +#: ../../po/../src/ui/stock-items.cpp:167 +#: ../../po/../src/ui/stock-items.cpp:168 +#: ../../po/../src/ui/stock-items.cpp:169 +#: ../../po/../src/ui/stock-items.cpp:170 +#: ../../po/../src/ui/stock-items.cpp:171 +#: ../../po/../src/ui/stock-items.cpp:172 +#: ../../po/../src/ui/stock-items.cpp:175 +#: ../../po/../src/ui/stock-items.cpp:176 +#: ../../po/../src/ui/stock-items.cpp:177 +#: ../../po/../src/ui/stock-items.cpp:178 +#: ../../po/../src/ui/stock-items.cpp:181 +#: ../../po/../src/ui/stock-items.cpp:182 +#: ../../po/../src/ui/stock-items.cpp:183 +#: ../../po/../src/ui/stock-items.cpp:184 +#: ../../po/../src/ui/stock-items.cpp:185 +#: ../../po/../src/ui/stock-items.cpp:186 +#: ../../po/../src/ui/stock-items.cpp:187 +#: ../../po/../src/ui/stock-items.cpp:188 +#: ../../po/../src/ui/stock-items.cpp:189 +#: ../../po/../src/ui/stock-items.cpp:190 +#: ../../po/../src/ui/stock-items.cpp:191 +#: ../../po/../src/ui/stock-items.cpp:194 +#: ../../po/../src/ui/stock-items.cpp:195 +#: ../../po/../src/ui/stock-items.cpp:198 +#: ../../po/../src/ui/stock-items.cpp:199 +#: ../../po/../src/ui/stock-items.cpp:200 +#: ../../po/../src/ui/stock-items.cpp:201 +#: ../../po/../src/ui/stock-items.cpp:202 +msgid "PLACEHOLDER, do not translate" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:88 +msgid "small" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:89 +msgid "medium" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:90 +#, fuzzy +msgid "large" +msgstr "μώβ" + +#: ../../po/../src/ui/widget/panel.cpp:91 +msgid "huge" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:106 +#, fuzzy +msgid "List" +msgstr "ίντσα" + +#: ../../po/../src/ui/widget/selected-style.cpp:67 +msgid "F:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:68 +msgid "S:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:69 +msgid "O:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:95 +msgid "N/A" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:98 +#: ../../po/../src/ui/widget/selected-style.cpp:712 +#, fuzzy +msgid "Nothing selected" +msgstr "Διαγραφή επιλογής" + +#: ../../po/../src/ui/widget/selected-style.cpp:103 +#, fuzzy +msgid "No fill" +msgstr "Χωρίς Αρχείο" + +# +#: ../../po/../src/ui/widget/selected-style.cpp:103 +#, fuzzy +msgid "No stroke" +msgstr "ε χρήση" + +#: ../../po/../src/ui/widget/selected-style.cpp:105 +#: ../../po/../src/widgets/paint-selector.cpp:190 +#, fuzzy +msgid "Pattern" +msgstr "Σχέδιο" + +#: ../../po/../src/ui/widget/selected-style.cpp:108 +#: ../../po/../src/widgets/paint-selector.cpp:885 +#, fuzzy +msgid "Pattern fill" +msgstr "Σχέδιο" + +#: ../../po/../src/ui/widget/selected-style.cpp:108 +#, fuzzy +msgid "Pattern stroke" +msgstr "Σχέδιο" + +#: ../../po/../src/ui/widget/selected-style.cpp:110 +#, fuzzy +msgid "L Gradient" +msgstr "Βαθμίδα" + +# +#: ../../po/../src/ui/widget/selected-style.cpp:113 +#, fuzzy +msgid "Linear gradient fill" +msgstr "Προσθήκη νέου παροχέα" + +# +#: ../../po/../src/ui/widget/selected-style.cpp:113 +#, fuzzy +msgid "Linear gradient stroke" +msgstr "Προσθήκη νέου παροχέα" + +#: ../../po/../src/ui/widget/selected-style.cpp:115 +#, fuzzy +msgid "R Gradient" +msgstr "Βαθμίδα" + +# +#: ../../po/../src/ui/widget/selected-style.cpp:118 +#, fuzzy +msgid "Radial gradient fill" +msgstr "Προσθήκη νέου παροχέα" + +# +#: ../../po/../src/ui/widget/selected-style.cpp:118 +#, fuzzy +msgid "Radial gradient stroke" +msgstr "Προσθήκη νέου παροχέα" + +#: ../../po/../src/ui/widget/selected-style.cpp:120 +#, fuzzy +msgid "Different" +msgstr "πράσινο" + +#: ../../po/../src/ui/widget/selected-style.cpp:123 +#, fuzzy +msgid "Different fills" +msgstr "πράσινο" + +#: ../../po/../src/ui/widget/selected-style.cpp:123 +#, fuzzy +msgid "Different strokes" +msgstr "πράσινο" + +#: ../../po/../src/ui/widget/selected-style.cpp:125 +#, fuzzy +msgid "Unset" +msgstr "ίντσα" + +# +#. TRANSLATORS COMMENT: unset is a verb here +#: ../../po/../src/ui/widget/selected-style.cpp:128 +#: ../../po/../src/ui/widget/selected-style.cpp:182 +#, fuzzy +msgid "Unset fill" +msgstr "_Αρχείο" + +# +#: ../../po/../src/ui/widget/selected-style.cpp:128 +#: ../../po/../src/ui/widget/selected-style.cpp:182 +#, fuzzy +msgid "Unset stroke" +msgstr "ε χρήση" + +#: ../../po/../src/ui/widget/selected-style.cpp:131 +#, fuzzy +msgid "Flat color fill" +msgstr " χρώμα" + +#: ../../po/../src/ui/widget/selected-style.cpp:131 +#, fuzzy +msgid "Flat color stroke" +msgstr " χρώμα" + +#. TRANSLATOR COMMENT: A means "Averaged" +#: ../../po/../src/ui/widget/selected-style.cpp:134 +msgid "A" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:137 +#, fuzzy +msgid "Fill is averaged over selected objects" +msgstr "Διαγραφή επιλεγμένων αντικειμένων" + +#: ../../po/../src/ui/widget/selected-style.cpp:137 +#, fuzzy +msgid "Stroke is averaged over selected objects" +msgstr "Διαγραφή επιλεγμένων αντικειμένων" + +#. TRANSLATOR COMMENT: M means "Multiple" +#: ../../po/../src/ui/widget/selected-style.cpp:140 +msgid "M" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:143 +#, fuzzy +msgid "Multiple selected objects have the same fill" +msgstr "Διαγραφή επιλεγμένων αντικειμένων" + +#: ../../po/../src/ui/widget/selected-style.cpp:143 +#, fuzzy +msgid "Multiple selected objects have the same stroke" +msgstr "Διαγραφή επιλεγμένων αντικειμένων" + +# +#: ../../po/../src/ui/widget/selected-style.cpp:145 +#, fuzzy +msgid "Edit fill..." +msgstr "Επεξεργασία" + +# +#: ../../po/../src/ui/widget/selected-style.cpp:145 +#, fuzzy +msgid "Edit stroke..." +msgstr "Επεξεργασία" + +#: ../../po/../src/ui/widget/selected-style.cpp:149 +#, fuzzy +msgid "Last set color" +msgstr " χρώμα" + +# +#: ../../po/../src/ui/widget/selected-style.cpp:153 +#, fuzzy +msgid "Last selected color" +msgstr "Επιλέχθησαν \"%s\"" + +#: ../../po/../src/ui/widget/selected-style.cpp:157 +msgid "White" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:161 +#: ../../po/../src/widgets/sp-color-scales.cpp:461 +#: ../../po/../src/widgets/sp-color-scales.cpp:462 +#, fuzzy +msgid "Black" +msgstr "Μαύρο:" + +#: ../../po/../src/ui/widget/selected-style.cpp:165 +#, fuzzy +msgid "Copy color" +msgstr " χρώμα" + +#: ../../po/../src/ui/widget/selected-style.cpp:169 +#, fuzzy +msgid "Paste color" +msgstr " χρώμα" + +#: ../../po/../src/ui/widget/selected-style.cpp:173 +#, fuzzy +msgid "Swap fill and stroke" +msgstr "Ρυθμίσεις επιφάνειας εργασίας" + +#: ../../po/../src/ui/widget/selected-style.cpp:177 +msgid "Make fill opaque" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:177 +msgid "Make stroke opaque" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:186 +#, fuzzy +msgid "Remove fill" +msgstr "Διαγραφή συνδέσμου" + +#: ../../po/../src/ui/widget/selected-style.cpp:186 +#, fuzzy +msgid "Remove stroke" +msgstr "Διαγραφή συνδέσμου" + +# +#: ../../po/../src/ui/widget/selected-style.cpp:718 +#, fuzzy +msgid "Master opacity" +msgstr "Διαφάνεια:" + +#: ../../po/../src/ui/widget/selected-style.cpp:744 +msgid "0 (transparent)" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:768 +msgid "1.0 (opaque)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1046 +msgid "Moved to next layer." +msgstr "" + +#: ../../po/../src/verbs.cpp:1048 +msgid "Cannot move past last layer." +msgstr "" + +#: ../../po/../src/verbs.cpp:1057 +msgid "Moved to previous layer." +msgstr "" + +#: ../../po/../src/verbs.cpp:1059 +msgid "Cannot move past first layer." +msgstr "" + +#: ../../po/../src/verbs.cpp:1076 ../../po/../src/verbs.cpp:1150 +#, fuzzy +msgid "No current layer." +msgstr "Έγγραφο" + +#: ../../po/../src/verbs.cpp:1105 +#, fuzzy, c-format +msgid "Raised layer %s." +msgstr "Αρχικοποίηση" + +# +#: ../../po/../src/verbs.cpp:1109 +#, fuzzy, c-format +msgid "Lowered layer %s." +msgstr "Επιλογή" + +#: ../../po/../src/verbs.cpp:1118 +msgid "Cannot move layer any further." +msgstr "" + +# +#. TRANSLATORS: this means "The layer has been deleted." +#: ../../po/../src/verbs.cpp:1148 +#, fuzzy +msgid "Deleted layer." +msgstr "Επιλογή" + +#: ../../po/../src/verbs.cpp:1544 +msgid "" +"You need to connect to a Jabber server before sharing a document with " +"another user." +msgstr "" + +#: ../../po/../src/verbs.cpp:1559 +msgid "" +"You need to connect to a Jabber server before sharing a document with a " +"chatroom." +msgstr "" + +#: ../../po/../src/verbs.cpp:1569 +msgid "XML node tracker has not been initialized; nothing to dump" +msgstr "" + +#. TRANSLATORS: If you have translated the keys.svg file to your language, then +#. translate this string as "keys.LANG.svg" (where LANG is your language code); +#. otherwise leave as "keys.svg". +#: ../../po/../src/verbs.cpp:1631 +msgid "keys.svg" +msgstr "" + +#. TRANSLATORS: If you have translated the tutorial-basic.svg file to your language, +#. then translate this string as "tutorial-basic.LANG.svg" (where LANG is your language +#. code); otherwise leave as "tutorial-basic.svg". +#: ../../po/../src/verbs.cpp:1667 +msgid "tutorial-basic.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1671 +msgid "tutorial-shapes.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1675 +msgid "tutorial-advanced.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1679 +msgid "tutorial-tracing.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1683 +msgid "tutorial-calligraphy.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1687 +msgid "tutorial-elements.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1691 +msgid "tutorial-tips.svg" +msgstr "" + +#: ../../po/../src/verbs.cpp:1842 +msgid "Does nothing" +msgstr "" + +#. File +#: ../../po/../src/verbs.cpp:1845 +#, fuzzy +msgid "Default" +msgstr "Διαγρ." + +#: ../../po/../src/verbs.cpp:1845 +#, fuzzy +msgid "Create new document from default template" +msgstr "Έγγραφο" + +# +#: ../../po/../src/verbs.cpp:1847 +#, fuzzy +msgid "_Open..." +msgstr "_Άνοιγμα" + +#: ../../po/../src/verbs.cpp:1848 +#, fuzzy +msgid "Open existing document" +msgstr "Έγγραφο" + +#: ../../po/../src/verbs.cpp:1849 +msgid "Re_vert" +msgstr "" + +#: ../../po/../src/verbs.cpp:1850 +msgid "Revert to the last saved version of document (changes will be lost)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1851 +#, fuzzy +msgid "_Save" +msgstr "Σκίαση" + +#: ../../po/../src/verbs.cpp:1851 +#, fuzzy +msgid "Save document" +msgstr "Έγγραφο" + +#: ../../po/../src/verbs.cpp:1853 +#, fuzzy +msgid "Save _As..." +msgstr "Αποθήκευση αρχείου" + +#: ../../po/../src/verbs.cpp:1854 +#, fuzzy +msgid "Save document under new name" +msgstr "Αποθήκευση ως γνήσιο όνομα αρχείου" + +#: ../../po/../src/verbs.cpp:1855 +#, fuzzy +msgid "_Print..." +msgstr "Σημείο" + +#: ../../po/../src/verbs.cpp:1855 +#, fuzzy +msgid "Print document" +msgstr "Έγγραφο" + +#. TRANSLATORS: "Vacuum Defs" means "Clean up defs" (so as to remove unused definitions) +#: ../../po/../src/verbs.cpp:1858 +msgid "Vac_uum Defs" +msgstr "" + +#: ../../po/../src/verbs.cpp:1858 +msgid "Remove unused predefined items from the <defs> of the document" +msgstr "" + +#: ../../po/../src/verbs.cpp:1860 +#, fuzzy +msgid "Print _Direct" +msgstr " Ιδιότητες" + +#: ../../po/../src/verbs.cpp:1861 +msgid "Print directly without prompting to a file or pipe" +msgstr "" + +#: ../../po/../src/verbs.cpp:1862 +#, fuzzy +msgid "Print Previe_w" +msgstr "Χρήση Προεπισκόπησης" + +#: ../../po/../src/verbs.cpp:1863 +#, fuzzy +msgid "Preview document printout" +msgstr "Προεπισκόπηση δεδομένων προς εκτύπωση" + +# +#: ../../po/../src/verbs.cpp:1864 +#, fuzzy +msgid "_Import..." +msgstr "Εισαγωγή" + +#: ../../po/../src/verbs.cpp:1865 +msgid "Import bitmap or SVG image into document" +msgstr "" + +#: ../../po/../src/verbs.cpp:1866 +#, fuzzy +msgid "_Export Bitmap..." +msgstr "Εξαγωγή Αρχείου" + +#: ../../po/../src/verbs.cpp:1867 +#, fuzzy +msgid "Export document or selection as a bitmap image" +msgstr "Εξαγωγή Αρχείου" + +#: ../../po/../src/verbs.cpp:1868 +#, fuzzy +msgid "N_ext Window" +msgstr "Κλείσιμο καταγραφών" + +#: ../../po/../src/verbs.cpp:1869 +msgid "Switch to the next document window" +msgstr "" + +#: ../../po/../src/verbs.cpp:1870 +#, fuzzy +msgid "P_revious Window" +msgstr "Κλείσιμο καταγραφών" + +#: ../../po/../src/verbs.cpp:1871 +msgid "Switch to the previous document window" +msgstr "" + +#: ../../po/../src/verbs.cpp:1872 +#, fuzzy +msgid "_Close" +msgstr "Νέα Προβολή" + +#: ../../po/../src/verbs.cpp:1873 +#, fuzzy +msgid "Close window" +msgstr "Νέα Προβολή" + +#: ../../po/../src/verbs.cpp:1874 +#, fuzzy +msgid "_Quit" +msgstr "_Τέλος" + +#: ../../po/../src/verbs.cpp:1874 +#, fuzzy +msgid "Quit Inkscape" +msgstr "Συμπαγές" + +# +#. Edit +#: ../../po/../src/verbs.cpp:1877 +#, fuzzy +msgid "_Undo" +msgstr "Ακύρωση" + +#: ../../po/../src/verbs.cpp:1877 +#, fuzzy +msgid "Undo last action" +msgstr "Μετασχηματισμός" + +# +#: ../../po/../src/verbs.cpp:1879 +#, fuzzy +msgid "_Redo" +msgstr "Επανεκτέλεση" + +#: ../../po/../src/verbs.cpp:1880 +msgid "Do again last undone action" +msgstr "" + +# +#: ../../po/../src/verbs.cpp:1881 +#, fuzzy +msgid "Cu_t" +msgstr "Αποκοπή" + +# +#: ../../po/../src/verbs.cpp:1882 +#, fuzzy +msgid "Cut selection to clipboard" +msgstr "Διαγραφή επιλεγμένου αντικειμένου" + +# +#: ../../po/../src/verbs.cpp:1883 +#, fuzzy +msgid "_Copy" +msgstr "Αντιγραφή" + +# +#: ../../po/../src/verbs.cpp:1884 +#, fuzzy +msgid "Copy selection to clipboard" +msgstr "Αντιγραφή επιλογής στο τεμάχιο" + +# +#: ../../po/../src/verbs.cpp:1885 +#, fuzzy +msgid "_Paste" +msgstr "Επικόλληση" + +# +#: ../../po/../src/verbs.cpp:1886 +#, fuzzy +msgid "Paste objects from clipboard to mouse point" +msgstr "Επικόλληση από το τεμάχιο" + +#: ../../po/../src/verbs.cpp:1887 +#, fuzzy +msgid "Paste _Style" +msgstr "Καπνός με άνεμο" + +# +#: ../../po/../src/verbs.cpp:1888 +#, fuzzy +msgid "Apply style of the copied object to selection" +msgstr "Αντιγραφή επιλογής στο τεμάχιο" + +#: ../../po/../src/verbs.cpp:1889 +#, fuzzy +msgid "Paste _In Place" +msgstr "Καπνός με άνεμο" + +#: ../../po/../src/verbs.cpp:1890 +#, fuzzy +msgid "Paste objects from clipboard to the original location" +msgstr "Ορι_ζόντια Στοίχιση" + +# +#: ../../po/../src/verbs.cpp:1891 +#, fuzzy +msgid "_Delete" +msgstr "Διαγραφή" + +# +#: ../../po/../src/verbs.cpp:1892 +#, fuzzy +msgid "Delete selection" +msgstr "Καθαρισμός της επιλογής" + +#: ../../po/../src/verbs.cpp:1893 +#, fuzzy +msgid "Duplic_ate" +msgstr "Δημιουργία αντιγράφου" + +#: ../../po/../src/verbs.cpp:1894 +#, fuzzy +msgid "Duplicate selected objects" +msgstr "Διαγραφή επιλεγμένων αντικειμένων" + +#: ../../po/../src/verbs.cpp:1895 +#, fuzzy +msgid "Clo_ne" +msgstr "Νέα Προβολή" + +#: ../../po/../src/verbs.cpp:1896 +msgid "Create a clone of selected object (a copy linked to the original)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1897 +msgid "Unlin_k Clone" +msgstr "" + +#: ../../po/../src/verbs.cpp:1898 +msgid "Cut the clone's link to its original" +msgstr "" + +# +#: ../../po/../src/verbs.cpp:1899 +#, fuzzy +msgid "Select _Original" +msgstr "Επιλογή" + +# +#: ../../po/../src/verbs.cpp:1900 +#, fuzzy +msgid "Select the object to which the clone is linked" +msgstr "Διαγραφή επιλεγμένου αντικειμένου" + +#. TRANSLATORS: Convert selection to a rectangle with tiled pattern fill +#: ../../po/../src/verbs.cpp:1902 +#, fuzzy +msgid "O_bjects to Pattern" +msgstr "Μετασχηματισμός" + +#: ../../po/../src/verbs.cpp:1903 +msgid "Convert selection to a rectangle with tiled pattern fill" +msgstr "" + +#. TRANSLATORS: Extract objects from a tiled pattern fill +#: ../../po/../src/verbs.cpp:1905 +#, fuzzy +msgid "Pattern to Ob_jects" +msgstr "Διαγραφή επιλεγμένων αντικειμένων" + +#: ../../po/../src/verbs.cpp:1906 +msgid "Extract objects from a tiled pattern fill" +msgstr "" + +# +#: ../../po/../src/verbs.cpp:1907 +#, fuzzy +msgid "Clea_r All" +msgstr "Αρχείο core" + +#: ../../po/../src/verbs.cpp:1908 +msgid "Delete all objects from document" +msgstr "" + +# +#: ../../po/../src/verbs.cpp:1909 +#, fuzzy +msgid "Select Al_l" +msgstr "Επιλογή" + +#: ../../po/../src/verbs.cpp:1910 +#, fuzzy +msgid "Select all objects or all nodes" +msgstr "Διαγραφή επιλεγμένων αντικειμένων" + +# +#: ../../po/../src/verbs.cpp:1911 +#, fuzzy +msgid "Select All in All La_yers" +msgstr "Επιλογή" + +#: ../../po/../src/verbs.cpp:1912 +#, fuzzy +msgid "Select all objects in all visible and unlocked layers" +msgstr "Διαγραφή επιλεγμένων αντικειμένων" + +#: ../../po/../src/verbs.cpp:1913 +#, fuzzy +msgid "In_vert Selection" +msgstr "Επιλογή" + +#: ../../po/../src/verbs.cpp:1914 +msgid "Invert selection (unselect what is selected and select everything else)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1915 +msgid "Invert in All Layers" +msgstr "" + +#: ../../po/../src/verbs.cpp:1916 +msgid "Invert selection in all visible and unlocked layers" +msgstr "" + +# +#: ../../po/../src/verbs.cpp:1917 +#, fuzzy +msgid "D_eselect" +msgstr "Επιλογή" + +#: ../../po/../src/verbs.cpp:1918 +#, fuzzy +msgid "Deselect any selected objects or nodes" +msgstr "Διαγραφή επιλογής" + +#. Selection +#: ../../po/../src/verbs.cpp:1921 +#, fuzzy +msgid "Raise to _Top" +msgstr "Αποθήκευση επιλογής" + +#: ../../po/../src/verbs.cpp:1922 +#, fuzzy +msgid "Raise selection to top" +msgstr "Αποθήκευση επιλογής" + +# +#: ../../po/../src/verbs.cpp:1923 +#, fuzzy +msgid "Lower to _Bottom" +msgstr "Αντιγραφή επιλογής στο τεμάχιο" + +# +#: ../../po/../src/verbs.cpp:1924 +#, fuzzy +msgid "Lower selection to bottom" +msgstr "Αντιγραφή επιλογής στο τεμάχιο" + +#: ../../po/../src/verbs.cpp:1925 +#, fuzzy +msgid "_Raise" +msgstr "Αρχικοποίηση" + +#: ../../po/../src/verbs.cpp:1926 +#, fuzzy +msgid "Raise selection one step" +msgstr "Μόνον επιλογή" + +#: ../../po/../src/verbs.cpp:1927 +msgid "_Lower" +msgstr "" + +#: ../../po/../src/verbs.cpp:1928 +#, fuzzy +msgid "Lower selection one step" +msgstr "Δεν έγινε επιλογή" + +#: ../../po/../src/verbs.cpp:1929 +msgid "_Group" +msgstr "_Ομαδοποίηση" + +# +#: ../../po/../src/verbs.cpp:1930 +#, fuzzy +msgid "Group selected objects" +msgstr "Διαγραφή επιλεγμένου αντικειμένου" + +#: ../../po/../src/verbs.cpp:1932 +#, fuzzy +msgid "Ungroup selected groups" +msgstr "Διαγραφή επιλεγμένων αντικειμένων" + +# +#: ../../po/../src/verbs.cpp:1934 +#, fuzzy +msgid "_Put on Path" +msgstr "Διαγραφή επιλεγμένου αντικειμένου" + +# +#: ../../po/../src/verbs.cpp:1935 +#, fuzzy +msgid "Put text on path" +msgstr "Διαγραφή επιλεγμένου αντικειμένου" + +#: ../../po/../src/verbs.cpp:1936 +#, fuzzy +msgid "_Remove from Path" +msgstr "Μετασχηματισμός" + +# +#: ../../po/../src/verbs.cpp:1937 +#, fuzzy +msgid "Remove text from path" +msgstr "Διαγραφή επιλεγμένου αντικειμένου" + +#: ../../po/../src/verbs.cpp:1938 +msgid "Remove Manual _Kerns" +msgstr "" + +#. TRANSLATORS: "glyph": An image used in the visual representation of characters; +#. roughly speaking, how a character looks. A font is a set of glyphs. +#: ../../po/../src/verbs.cpp:1941 +#, fuzzy +msgid "Remove all manual kerns and glyph rotations from a text object" +msgstr "Μετασχηματισμός" + +# +#: ../../po/../src/verbs.cpp:1943 +#, fuzzy +msgid "_Union" +msgstr "κανένα" + +#: ../../po/../src/verbs.cpp:1944 +#, fuzzy +msgid "Union of selected objects" +msgstr "Διαγραφή επιλεγμένων αντικειμένων" + +#: ../../po/../src/verbs.cpp:1945 +#, fuzzy +msgid "_Intersection" +msgstr "Δ_ιεπιφάνεια" + +#: ../../po/../src/verbs.cpp:1946 +#, fuzzy +msgid "Intersection of selected objects" +msgstr "Διαγραφή επιλογής" + +#: ../../po/../src/verbs.cpp:1947 +#, fuzzy +msgid "_Difference" +msgstr "πράσινο" + +#: ../../po/../src/verbs.cpp:1948 +#, fuzzy +msgid "Difference of selected objects (bottom minus top)" +msgstr "Διαγραφή επιλογής" + +#: ../../po/../src/verbs.cpp:1949 +#, fuzzy +msgid "E_xclusion" +msgstr "Διάσταση" + +#: ../../po/../src/verbs.cpp:1950 +#, fuzzy +msgid "Exclusive OR of selected objects" +msgstr "Διαγραφή επιλεγμένων αντικειμένων" + +#: ../../po/../src/verbs.cpp:1951 +msgid "Di_vision" +msgstr "" + +#: ../../po/../src/verbs.cpp:1952 +msgid "Cut the bottom object into pieces" +msgstr "" + +#. TRANSLATORS: "to cut a path" is not the same as "to break a path apart" - see the +#. Advanced tutorial for more info +#: ../../po/../src/verbs.cpp:1955 +#, fuzzy +msgid "Cut _Path" +msgstr "Αντιγραφή επιλεγμένης εργασίας" + +#: ../../po/../src/verbs.cpp:1956 +msgid "Cut the bottom object's stroke into pieces, removing fill" +msgstr "" + +#. TRANSLATORS: "outset": expand a shape by offsetting the object's path, +#. i.e. by displacing it perpendicular to the path in each point. +#. See also the Advanced Tutorial for explanation. +#: ../../po/../src/verbs.cpp:1960 +#, fuzzy +msgid "Outs_et" +msgstr "Αντιγραφή επιλεγμένης εργασίας" + +#: ../../po/../src/verbs.cpp:1961 +#, fuzzy +msgid "Outset selected paths" +msgstr "Αντιγραφή επιλεγμένης εργασίας" + +#: ../../po/../src/verbs.cpp:1963 +#, fuzzy +msgid "O_utset Path by 1 px" +msgstr "Αντιγραφή επιλεγμένης εργασίας" + +#: ../../po/../src/verbs.cpp:1964 +#, fuzzy +msgid "Outset selected paths by 1 px" +msgstr "Αντιγραφή επιλεγμένης εργασίας" + +#: ../../po/../src/verbs.cpp:1966 +#, fuzzy +msgid "O_utset Path by 10 px" +msgstr "Αντιγραφή επιλεγμένης εργασίας" + +#: ../../po/../src/verbs.cpp:1967 +#, fuzzy +msgid "Outset selected paths by 10 px" +msgstr "Αντιγραφή επιλεγμένης εργασίας" + +#. TRANSLATORS: "inset": contract a shape by offsetting the object's path, +#. i.e. by displacing it perpendicular to the path in each point. +#. See also the Advanced Tutorial for explanation. +#: ../../po/../src/verbs.cpp:1971 +msgid "I_nset" +msgstr "" + +#: ../../po/../src/verbs.cpp:1972 +#, fuzzy +msgid "Inset selected paths" +msgstr "Αντιγραφή επιλεγμένης εργασίας" + +#: ../../po/../src/verbs.cpp:1974 +#, fuzzy +msgid "I_nset Path by 1 px" +msgstr "Αντιγραφή επιλεγμένης εργασίας" + +#: ../../po/../src/verbs.cpp:1975 +#, fuzzy +msgid "Inset selected paths by 1 px" +msgstr "Αντιγραφή επιλεγμένης εργασίας" + +#: ../../po/../src/verbs.cpp:1977 +#, fuzzy +msgid "I_nset Path by 10 px" +msgstr "Αντιγραφή επιλεγμένης εργασίας" + +#: ../../po/../src/verbs.cpp:1978 +#, fuzzy +msgid "Inset selected paths by 10 px" +msgstr "Αντιγραφή επιλεγμένης εργασίας" + +#: ../../po/../src/verbs.cpp:1980 +msgid "D_ynamic Offset" +msgstr "" + +#: ../../po/../src/verbs.cpp:1980 +msgid "Create a dynamic offset object" +msgstr "" + +#: ../../po/../src/verbs.cpp:1982 +msgid "_Linked Offset" +msgstr "" + +#: ../../po/../src/verbs.cpp:1983 +msgid "Create a dynamic offset object linked to the original path" +msgstr "" + +#: ../../po/../src/verbs.cpp:1985 +#, fuzzy +msgid "_Stroke to Path" +msgstr "Καπνός με άνεμο" + +# +#: ../../po/../src/verbs.cpp:1986 +#, fuzzy +msgid "Convert selected strokes to paths" +msgstr "Διαγραφή επιλεγμένου αντικειμένου" + +#: ../../po/../src/verbs.cpp:1987 +#, fuzzy +msgid "Si_mplify" +msgstr "Αντιγραφή επιλεγμένης εργασίας" + +#: ../../po/../src/verbs.cpp:1988 +#, fuzzy +msgid "Simplify selected paths by removing extra nodes" +msgstr "Αντιγραφή επιλεγμένης εργασίας" + +# +#: ../../po/../src/verbs.cpp:1989 +#, fuzzy +msgid "_Reverse" +msgstr "Αρχείο" + +#: ../../po/../src/verbs.cpp:1990 +#, fuzzy +msgid "Reverses the direction of selected paths; useful for flipping markers" +msgstr "Διαγραφή επιλογής" + +#. TRANSLATORS: "to trace" means "to convert a bitmap to vector graphics" (to vectorize) +#: ../../po/../src/verbs.cpp:1992 +#, fuzzy +msgid "_Trace Bitmap" +msgstr "Διακοπείσα σωλήνωση" + +# +#: ../../po/../src/verbs.cpp:1993 +#, fuzzy +msgid "Convert bitmap object to paths" +msgstr "Διαγραφή επιλεγμένου αντικειμένου" + +#: ../../po/../src/verbs.cpp:1994 +#, fuzzy +msgid "_Make a Bitmap Copy" +msgstr "Διακοπείσα σωλήνωση" + +#: ../../po/../src/verbs.cpp:1995 +msgid "Export selection to a bitmap and insert it into document" +msgstr "" + +#: ../../po/../src/verbs.cpp:1996 +#, fuzzy +msgid "_Combine" +msgstr "_Μεταγλώττιση" + +#: ../../po/../src/verbs.cpp:1997 +msgid "Combine several paths into one" +msgstr "" + +#. TRANSLATORS: "to cut a path" is not the same as "to break a path apart" - see the +#. Advanced tutorial for more info +#: ../../po/../src/verbs.cpp:2000 +#, fuzzy +msgid "Break _Apart" +msgstr "πραγματική διαδρομή" + +#: ../../po/../src/verbs.cpp:2001 +#, fuzzy +msgid "Break selected paths into subpaths" +msgstr "Επανεκκίνηση επιλεγμένων αρχείων" + +#: ../../po/../src/verbs.cpp:2002 +msgid "Gri_d Arrange..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2003 +msgid "Arrange selection in grid pattern" +msgstr "" + +#. Layer +#: ../../po/../src/verbs.cpp:2005 +#, fuzzy +msgid "_Add Layer..." +msgstr "Αρχικοποίηση" + +#: ../../po/../src/verbs.cpp:2006 +#, fuzzy +msgid "Create a new layer" +msgstr "Έγγραφο" + +#: ../../po/../src/verbs.cpp:2007 +#, fuzzy +msgid "Re_name Layer..." +msgstr "Αρχικοποίηση" + +# +#: ../../po/../src/verbs.cpp:2008 +#, fuzzy +msgid "Rename the current layer" +msgstr "Επιλογή" + +# +#: ../../po/../src/verbs.cpp:2009 +#, fuzzy +msgid "Switch to Layer Abov_e" +msgstr "Αντιγραφή επιλογής στο τεμάχιο" + +#: ../../po/../src/verbs.cpp:2010 +msgid "Switch to the layer above the current" +msgstr "" + +#: ../../po/../src/verbs.cpp:2011 +#, fuzzy +msgid "Switch to Layer Belo_w" +msgstr "Δεν έγινε επιλογή" + +#: ../../po/../src/verbs.cpp:2012 +msgid "Switch to the layer below the current" +msgstr "" + +# +#: ../../po/../src/verbs.cpp:2013 +#, fuzzy +msgid "Move Selection to Layer Abo_ve" +msgstr "Αντιγραφή επιλογής στο τεμάχιο" + +#: ../../po/../src/verbs.cpp:2014 +msgid "Move selection to the layer above the current" +msgstr "" + +#: ../../po/../src/verbs.cpp:2015 +#, fuzzy +msgid "Move Selection to Layer Bel_ow" +msgstr "Δεν έγινε επιλογή" + +#: ../../po/../src/verbs.cpp:2016 +msgid "Move selection to the layer below the current" +msgstr "" + +#: ../../po/../src/verbs.cpp:2017 +#, fuzzy +msgid "Layer to _Top" +msgstr "Αποθήκευση επιλογής" + +#: ../../po/../src/verbs.cpp:2018 +#, fuzzy +msgid "Raise the current layer to the top" +msgstr "Αποθήκευση επιλογής" + +# +#: ../../po/../src/verbs.cpp:2019 +#, fuzzy +msgid "Layer to _Bottom" +msgstr "Αντιγραφή επιλογής στο τεμάχιο" + +# +#: ../../po/../src/verbs.cpp:2020 +#, fuzzy +msgid "Lower the current layer to the bottom" +msgstr "Αντιγραφή επιλογής στο τεμάχιο" + +#: ../../po/../src/verbs.cpp:2021 +#, fuzzy +msgid "_Raise Layer" +msgstr "Αρχικοποίηση" + +#: ../../po/../src/verbs.cpp:2022 +msgid "Raise the current layer" +msgstr "" + +# +#: ../../po/../src/verbs.cpp:2023 +#, fuzzy +msgid "_Lower Layer" +msgstr "Επιλογή" + +#: ../../po/../src/verbs.cpp:2024 +msgid "Lower the current layer" +msgstr "" + +# +#: ../../po/../src/verbs.cpp:2025 +#, fuzzy +msgid "_Delete Current Layer" +msgstr "Επιλογή" + +# +#: ../../po/../src/verbs.cpp:2026 +#, fuzzy +msgid "Delete the current layer" +msgstr "Επιλογή" + +# +#. Object +#: ../../po/../src/verbs.cpp:2029 +#, fuzzy +msgid "Rotate _90° CW" +msgstr "Διαγραφή επιλεγμένου αντικειμένου" + +# +#: ../../po/../src/verbs.cpp:2030 +#, fuzzy +msgid "Rotate selection 90° clockwise" +msgstr "Διαγραφή επιλεγμένου αντικειμένου" + +# +#: ../../po/../src/verbs.cpp:2031 +#, fuzzy +msgid "Rotate 9_0° CCW" +msgstr "Διαγραφή επιλεγμένου αντικειμένου" + +# +#: ../../po/../src/verbs.cpp:2032 +#, fuzzy +msgid "Rotate selection 90° counter-clockwise" +msgstr "Διαγραφή επιλεγμένου αντικειμένου" + +#: ../../po/../src/verbs.cpp:2033 +#, fuzzy +msgid "Remove _Transformations" +msgstr "Μετασχηματισμός" + +#: ../../po/../src/verbs.cpp:2034 +#, fuzzy +msgid "Remove transformations from object" +msgstr "Μετασχηματισμός" + +#: ../../po/../src/verbs.cpp:2035 +#, fuzzy +msgid "_Object to Path" +msgstr "Μετασχηματισμός" + +# +#: ../../po/../src/verbs.cpp:2036 +#, fuzzy +msgid "Convert selected objects to paths" +msgstr "Διαγραφή επιλεγμένου αντικειμένου" + +#: ../../po/../src/verbs.cpp:2037 +msgid "_Flow into Frame" +msgstr "" + +# +#: ../../po/../src/verbs.cpp:2038 +#, fuzzy +msgid "Put text into frames" +msgstr "Διαγραφή επιλεγμένου αντικειμένου" + +# +#: ../../po/../src/verbs.cpp:2039 +#, fuzzy +msgid "_Unflow" +msgstr "Ακύρωση" + +#: ../../po/../src/verbs.cpp:2040 +msgid "Remove text from frame (creates a single-line text object)" +msgstr "" + +# +#: ../../po/../src/verbs.cpp:2041 +#, fuzzy +msgid "_Convert to Text" +msgstr "Διαγραφή επιλεγμένου αντικειμένου" + +#: ../../po/../src/verbs.cpp:2042 +#, fuzzy +msgid "Convert flowed text to regular text objects (preserves appearance)" +msgstr "Μετακίνιση επιλεγμένου μενού πρός τα κάτω" + +#: ../../po/../src/verbs.cpp:2044 +#, fuzzy +msgid "Flip _Horizontal" +msgstr "Οριζόντια αντιστροφή" + +#: ../../po/../src/verbs.cpp:2044 +#, fuzzy +msgid "Flips selected objects horizontally" +msgstr "Διαγραφή επιλεγμένων αντικειμένων" + +#: ../../po/../src/verbs.cpp:2047 +#, fuzzy +msgid "Flip _Vertical" +msgstr "Κατακόρυφη αντιστροφή" + +#: ../../po/../src/verbs.cpp:2047 +#, fuzzy +msgid "Flips selected objects vertically" +msgstr "Διαγραφή επιλεγμένων αντικειμένων" + +# +#. Tools +#: ../../po/../src/verbs.cpp:2051 +msgid "Select" +msgstr "Επιλογή" + +# +#: ../../po/../src/verbs.cpp:2052 +#, fuzzy +msgid "Select and transform objects" +msgstr "Επιλέξτε ενέργεια" + +#: ../../po/../src/verbs.cpp:2053 +#, fuzzy +msgid "Node Edit" +msgstr " Επεξεργασία " + +#: ../../po/../src/verbs.cpp:2054 +#, fuzzy +msgid "Edit path nodes or control handles" +msgstr "Διαγραφή επιλεγμένων αντικειμένων" + +# +#: ../../po/../src/verbs.cpp:2056 +#, fuzzy +msgid "Create rectangles and squares" +msgstr "Δημιουργία ορθογωνίου" + +#: ../../po/../src/verbs.cpp:2058 +msgid "Create circles, ellipses, and arcs" +msgstr "" + +#: ../../po/../src/verbs.cpp:2060 +msgid "Create stars and polygons" +msgstr "" + +# +#: ../../po/../src/verbs.cpp:2062 +#, fuzzy +msgid "Create spirals" +msgstr "Δημιουργία γραμμής" + +#: ../../po/../src/verbs.cpp:2064 +#, fuzzy +msgid "Draw freehand lines" +msgstr "Λαβή συρταριού" + +#: ../../po/../src/verbs.cpp:2066 +#, fuzzy +msgid "Draw Bezier curves and straight lines" +msgstr "Λαβή συρταριού" + +#: ../../po/../src/verbs.cpp:2068 +msgid "Draw calligraphic lines" +msgstr "" + +# +#: ../../po/../src/verbs.cpp:2070 +#, fuzzy +msgid "Create and edit text objects" +msgstr "Ιδιότητα" + +# +#: ../../po/../src/verbs.cpp:2072 +#, fuzzy +msgid "Create and edit gradients" +msgstr "Ιδιότητα" + +#: ../../po/../src/verbs.cpp:2074 +#, fuzzy +msgid "Zoom in or out" +msgstr "Σμίκρυνση" + +#: ../../po/../src/verbs.cpp:2076 +msgid "Pick averaged colors from image" +msgstr "" + +#: ../../po/../src/verbs.cpp:2078 +#, fuzzy +msgid "Create connectors" +msgstr "Έγγραφο" + +#. Tool prefs +#: ../../po/../src/verbs.cpp:2081 +msgid "Selector Preferences" +msgstr "" + +#: ../../po/../src/verbs.cpp:2082 +#, fuzzy +msgid "Open Preferences for the Selector tool" +msgstr "Συμπαγές" + +# +#: ../../po/../src/verbs.cpp:2083 +#, fuzzy +msgid "Node Tool Preferences" +msgstr "Προτιμίσεις Ναυτίλου" + +#: ../../po/../src/verbs.cpp:2084 +#, fuzzy +msgid "Open Preferences for the Node tool" +msgstr "Συμπαγές" + +#: ../../po/../src/verbs.cpp:2085 +#, fuzzy +msgid "Rectangle Preferences" +msgstr " Ιδιότητες" + +#: ../../po/../src/verbs.cpp:2086 +#, fuzzy +msgid "Open Preferences for the Rectangle tool" +msgstr "Συμπαγές" + +# +#: ../../po/../src/verbs.cpp:2087 +#, fuzzy +msgid "Ellipse Preferences" +msgstr "Προτιμίσεις Ναυτίλου" + +#: ../../po/../src/verbs.cpp:2088 +#, fuzzy +msgid "Open Preferences for the Ellipse tool" +msgstr "Συμπαγές" + +#: ../../po/../src/verbs.cpp:2089 +#, fuzzy +msgid "Star Preferences" +msgstr " Ιδιότητες" + +#: ../../po/../src/verbs.cpp:2090 +#, fuzzy +msgid "Open Preferences for the Star tool" +msgstr "Συμπαγές" + +#: ../../po/../src/verbs.cpp:2091 +#, fuzzy +msgid "Spiral Preferences" +msgstr " Ιδιότητες" + +#: ../../po/../src/verbs.cpp:2092 +#, fuzzy +msgid "Open Preferences for the Spiral tool" +msgstr "Συμπαγές" + +# +#: ../../po/../src/verbs.cpp:2093 +#, fuzzy +msgid "Pencil Preferences" +msgstr "Προτιμίσεις Ναυτίλου" + +#: ../../po/../src/verbs.cpp:2094 +#, fuzzy +msgid "Open Preferences for the Pencil tool" +msgstr "Συμπαγές" + +# +#: ../../po/../src/verbs.cpp:2095 +#, fuzzy +msgid "Pen Preferences" +msgstr "Προτιμίσεις Ναυτίλου" + +#: ../../po/../src/verbs.cpp:2096 +#, fuzzy +msgid "Open Preferences for the Pen tool" +msgstr "Συμπαγές" + +#: ../../po/../src/verbs.cpp:2097 +msgid "Calligraphic Preferences" +msgstr "" + +#: ../../po/../src/verbs.cpp:2098 +#, fuzzy +msgid "Open Preferences for the Calligraphy tool" +msgstr "Συμπαγές" + +# +#: ../../po/../src/verbs.cpp:2099 +#, fuzzy +msgid "Text Preferences" +msgstr "Προτιμίσεις Ναυτίλου" + +#: ../../po/../src/verbs.cpp:2100 +#, fuzzy +msgid "Open Preferences for the Text tool" +msgstr "Συμπαγές" + +# +#: ../../po/../src/verbs.cpp:2101 +#, fuzzy +msgid "Gradient Preferences" +msgstr "Προτιμίσεις Ναυτίλου" + +#: ../../po/../src/verbs.cpp:2102 +#, fuzzy +msgid "Open Preferences for the Gradient tool" +msgstr "Συμπαγές" + +# +#: ../../po/../src/verbs.cpp:2103 +#, fuzzy +msgid "Zoom Preferences" +msgstr "Προτιμίσεις Ναυτίλου" + +#: ../../po/../src/verbs.cpp:2104 +#, fuzzy +msgid "Open Preferences for the Zoom tool" +msgstr "Συμπαγές" + +#: ../../po/../src/verbs.cpp:2105 +#, fuzzy +msgid "Dropper Preferences" +msgstr "Συμπαγές" + +#: ../../po/../src/verbs.cpp:2106 +#, fuzzy +msgid "Open Preferences for the Dropper tool" +msgstr "Συμπαγές" + +#: ../../po/../src/verbs.cpp:2107 +#, fuzzy +msgid "Connector Preferences" +msgstr " Ιδιότητες" + +#: ../../po/../src/verbs.cpp:2108 +#, fuzzy +msgid "Open Preferences for the Connector tool" +msgstr "Συμπαγές" + +#. Zoom/View +#: ../../po/../src/verbs.cpp:2111 +#, fuzzy +msgid "Zoom In" +msgstr "Μεγέθυνση" + +#: ../../po/../src/verbs.cpp:2111 +msgid "Zoom in" +msgstr "Μεγέθυνση" + +#: ../../po/../src/verbs.cpp:2112 +#, fuzzy +msgid "Zoom Out" +msgstr "Σμίκρυνση" + +#: ../../po/../src/verbs.cpp:2112 +msgid "Zoom out" +msgstr "Σμίκρυνση" + +# +#: ../../po/../src/verbs.cpp:2113 +#, fuzzy +msgid "_Rulers" +msgstr "Αρχείο" + +# +#: ../../po/../src/verbs.cpp:2113 +#, fuzzy +msgid "Show or hide the canvas rulers" +msgstr "Εμφάνιση κόμβων-δ" + +#: ../../po/../src/verbs.cpp:2114 +msgid "Scroll_bars" +msgstr "" + +# +#: ../../po/../src/verbs.cpp:2114 +#, fuzzy +msgid "Show or hide the canvas scrollbars" +msgstr "Εμφάνιση κόμβων-δ" + +#: ../../po/../src/verbs.cpp:2115 +#, fuzzy +msgid "_Grid" +msgstr "Πλέγμα" + +#: ../../po/../src/verbs.cpp:2116 +#, fuzzy +msgid "G_uides" +msgstr "Γουϊνέα" + +#: ../../po/../src/verbs.cpp:2117 +msgid "Nex_t Zoom" +msgstr "" + +#: ../../po/../src/verbs.cpp:2117 +msgid "Next zoom (from the history of zooms)" +msgstr "" + +#: ../../po/../src/verbs.cpp:2119 +msgid "Pre_vious Zoom" +msgstr "" + +#: ../../po/../src/verbs.cpp:2119 +msgid "Previous zoom (from the history of zooms)" +msgstr "" + +# +#: ../../po/../src/verbs.cpp:2121 +#, fuzzy +msgid "Zoom 1:_1" +msgstr "Μεγέθυνση _1:1" + +# +#: ../../po/../src/verbs.cpp:2121 +#, fuzzy +msgid "Zoom to 1:1" +msgstr "Μεγέθυνση _1:1" + +#: ../../po/../src/verbs.cpp:2123 +#, fuzzy +msgid "Zoom 1:_2" +msgstr "Κλίμακα 125%" + +#: ../../po/../src/verbs.cpp:2123 +#, fuzzy +msgid "Zoom to 1:2" +msgstr "Κλίμακα 125%" + +#: ../../po/../src/verbs.cpp:2125 +#, fuzzy +msgid "_Zoom 2:1" +msgstr "Κλίμακα 25%" + +#: ../../po/../src/verbs.cpp:2125 +#, fuzzy +msgid "Zoom to 2:1" +msgstr "Κλίμακα 25%" + +#: ../../po/../src/verbs.cpp:2128 +msgid "_Fullscreen" +msgstr "" + +#: ../../po/../src/verbs.cpp:2128 +msgid "Stretch this document window to full screen" +msgstr "" + +#: ../../po/../src/verbs.cpp:2131 +#, fuzzy +msgid "Duplic_ate Window" +msgstr "Δημιουργία αντιγράφου" + +#: ../../po/../src/verbs.cpp:2131 +#, fuzzy +msgid "Open a new window with the same document" +msgstr "Έγγραφο" + +#: ../../po/../src/verbs.cpp:2133 +#, fuzzy +msgid "_New View Preview" +msgstr "Χρήση Προεπισκόπησης" + +#: ../../po/../src/verbs.cpp:2134 +#, fuzzy +msgid "New View Preview" +msgstr "Χρήση Προεπισκόπησης" + +#. "view_new_preview" +#: ../../po/../src/verbs.cpp:2136 +msgid "_Normal" +msgstr "" + +#: ../../po/../src/verbs.cpp:2137 +msgid "Switch to normal display mode" +msgstr "" + +# +#: ../../po/../src/verbs.cpp:2138 +#, fuzzy +msgid "_Outline" +msgstr "Εμφάνιση κόμβων-δ" + +#: ../../po/../src/verbs.cpp:2139 +msgid "Switch to outline (wireframe) display mode" +msgstr "" + +#: ../../po/../src/verbs.cpp:2141 +#, fuzzy +msgid "Ico_n Preview" +msgstr "Χρήση Προεπισκόπησης" + +#: ../../po/../src/verbs.cpp:2142 +msgid "Open a window to preview items at different icon resolutions" +msgstr "" + +#: ../../po/../src/verbs.cpp:2144 +#, fuzzy +msgid "Zoom to fit page in window" +msgstr "Πλάτος &Σελίδας" + +#: ../../po/../src/verbs.cpp:2145 +#, fuzzy +msgid "Page _Width" +msgstr "Πλάτος &Σελίδας" + +#: ../../po/../src/verbs.cpp:2146 +#, fuzzy +msgid "Zoom to fit page width in window" +msgstr "Πλάτος &Σελίδας" + +#: ../../po/../src/verbs.cpp:2148 +#, fuzzy +msgid "Zoom to fit drawing in window" +msgstr "Αλλαγή κλίμακας για _ταίριασμα" + +#: ../../po/../src/verbs.cpp:2150 +#, fuzzy +msgid "Zoom to fit selection in window" +msgstr "Αποθήκευση επιλογής" + +#. Dialogs +#: ../../po/../src/verbs.cpp:2153 +#, fuzzy +msgid "In_kscape Preferences..." +msgstr "Συμπαγές" + +#: ../../po/../src/verbs.cpp:2154 +#, fuzzy +msgid "Global Inkscape preferences" +msgstr "Εμφάνιση Σταθμών:" + +#: ../../po/../src/verbs.cpp:2155 +msgid "_Document Preferences..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2156 +#, fuzzy +msgid "Preferences saved with the document" +msgstr "Έγγραφο" + +#: ../../po/../src/verbs.cpp:2157 +#, fuzzy +msgid "_Fill and Stroke..." +msgstr "Ρυθμίσεις επιφάνειας εργασίας" + +#: ../../po/../src/verbs.cpp:2158 +#, fuzzy +msgid "Fill and Stroke dialog" +msgstr "Ρυθμίσεις επιφάνειας εργασίας" + +#. TRANSLATORS: "Swatches" means: color samples +#: ../../po/../src/verbs.cpp:2160 +#, fuzzy +msgid "S_watches..." +msgstr "Αποθήκευση αρχείου" + +#: ../../po/../src/verbs.cpp:2161 +msgid "View color swatches" +msgstr "" + +#: ../../po/../src/verbs.cpp:2162 +#, fuzzy +msgid "Transfor_m..." +msgstr "Μετασχηματισμός" + +#: ../../po/../src/verbs.cpp:2163 +#, fuzzy +msgid "Transform dialog" +msgstr "Μετασχηματισμός" + +#: ../../po/../src/verbs.cpp:2164 +#, fuzzy +msgid "_Align and Distribute..." +msgstr "Ιδιότητες" + +#: ../../po/../src/verbs.cpp:2165 +#, fuzzy +msgid "Align and Distribute dialog" +msgstr "Ιδιότητες" + +#: ../../po/../src/verbs.cpp:2166 +#, fuzzy +msgid "_Text and Font..." +msgstr "Ρυθμίσεις επιφάνειας εργασίας" + +#: ../../po/../src/verbs.cpp:2167 +#, fuzzy +msgid "Text and Font dialog" +msgstr "Ρυθμίσεις επιφάνειας εργασίας" + +#: ../../po/../src/verbs.cpp:2168 +#, fuzzy +msgid "_XML Editor..." +msgstr "Επεξεργασία..." + +#: ../../po/../src/verbs.cpp:2169 +msgid "XML Editor" +msgstr "" + +#: ../../po/../src/verbs.cpp:2170 +#, fuzzy +msgid "_Find..." +msgstr "Σημείο" + +#: ../../po/../src/verbs.cpp:2171 +#, fuzzy +msgid "Find objects in document" +msgstr "Έγγραφο" + +#: ../../po/../src/verbs.cpp:2172 +msgid "_Messages..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2173 +msgid "View debug messages" +msgstr "" + +#: ../../po/../src/verbs.cpp:2174 +#, fuzzy +msgid "S_cripts..." +msgstr "Σημείο" + +# +#: ../../po/../src/verbs.cpp:2175 +#, fuzzy +msgid "Run scripts" +msgstr "Εκτέλεση σε:" + +#: ../../po/../src/verbs.cpp:2176 +#, fuzzy +msgid "Show/Hide D_ialogs" +msgstr "Κλείσιμο καταγραφών" + +#: ../../po/../src/verbs.cpp:2177 +msgid "Show or hide all active dialogs" +msgstr "" + +#. TRANSLATORS: "Tile clones" means: "Create tiled clones" +#: ../../po/../src/verbs.cpp:2179 +msgid "Tile clones..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2180 +msgid "Create and arrange multiple clones of selection" +msgstr "" + +# +#: ../../po/../src/verbs.cpp:2181 +#, fuzzy +msgid "_Object Properties..." +msgstr "Ιδιότητες αντικειμένου" + +# +#: ../../po/../src/verbs.cpp:2182 +#, fuzzy +msgid "Object Properties dialog" +msgstr "Ιδιότητες αντικειμένου" + +#: ../../po/../src/verbs.cpp:2185 +msgid "_Connect to Jabber server..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2185 +msgid "Connect to a Jabber server" +msgstr "" + +#: ../../po/../src/verbs.cpp:2187 +#, fuzzy +msgid "Share with _user..." +msgstr "Αποθήκευση αρχείου" + +#: ../../po/../src/verbs.cpp:2187 +msgid "Establish a whiteboard session with another Jabber user" +msgstr "" + +#: ../../po/../src/verbs.cpp:2189 +msgid "Share with _chatroom..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2189 +msgid "" +"Join a chatroom to start a new whiteboard session or join one in progress" +msgstr "" + +#: ../../po/../src/verbs.cpp:2191 +msgid "_Dump XML node tracker" +msgstr "" + +#: ../../po/../src/verbs.cpp:2191 +msgid "Dump the contents of the XML tracker to the console" +msgstr "" + +#: ../../po/../src/verbs.cpp:2193 +msgid "_Open session file..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2193 +msgid "Open and browse through records of past whiteboard sessions" +msgstr "" + +#: ../../po/../src/verbs.cpp:2195 +msgid "Session file playback" +msgstr "" + +#: ../../po/../src/verbs.cpp:2197 +msgid "_Disconnect from session" +msgstr "" + +#: ../../po/../src/verbs.cpp:2199 +msgid "Disconnect from _server" +msgstr "" + +#: ../../po/../src/verbs.cpp:2201 +msgid "_Input Devices..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2202 +msgid "Configure extended input devices" +msgstr "" + +#. Help +#: ../../po/../src/verbs.cpp:2205 +msgid "_Keys and Mouse" +msgstr "" + +#: ../../po/../src/verbs.cpp:2206 +msgid "Key and mouse shortcuts reference" +msgstr "" + +#: ../../po/../src/verbs.cpp:2207 +#, fuzzy +msgid "About E_xtensions" +msgstr "Διαστάσεις:" + +#: ../../po/../src/verbs.cpp:2208 +#, fuzzy +msgid "About Extensions..." +msgstr "Διαστάσεις:" + +#: ../../po/../src/verbs.cpp:2209 +#, fuzzy +msgid "About _Memory" +msgstr "Διαστάσεις:" + +# +#: ../../po/../src/verbs.cpp:2210 +#, fuzzy +msgid "About Memory..." +msgstr "_Περί ..." + +#: ../../po/../src/verbs.cpp:2211 +msgid "_About Inkscape" +msgstr "" + +#. "help_about" +#. new HelpVerb(SP_VERB_SHOW_LICENSE, "ShowLicense", N_("Modifying or Redistributing Inkscape"), +#. N_("Show license to modify and/or redistribute Inkscape: GNU GPL"), NULL), +#. Tutorials +#: ../../po/../src/verbs.cpp:2217 +#, fuzzy +msgid "Inkscape: _Basic" +msgstr "Συμπαγές" + +#: ../../po/../src/verbs.cpp:2218 +msgid "Getting started with Inkscape" +msgstr "" + +#. "tutorial_basic" +#: ../../po/../src/verbs.cpp:2219 +#, fuzzy +msgid "Inkscape: _Shapes" +msgstr "Συμπαγές" + +#: ../../po/../src/verbs.cpp:2220 +msgid "Using shape tools to create and edit shapes" +msgstr "" + +#: ../../po/../src/verbs.cpp:2221 +#, fuzzy +msgid "Inkscape: _Advanced" +msgstr "Συμπαγές" + +#: ../../po/../src/verbs.cpp:2222 +#, fuzzy +msgid "Advanced Inkscape topics" +msgstr "Συμπαγές" + +#. "tutorial_advanced" +#. TRANSLATORS: "to trace" means "to convert a bitmap to vector graphics" (to vectorize) +#: ../../po/../src/verbs.cpp:2224 +#, fuzzy +msgid "Inkscape: T_racing" +msgstr "Συμπαγές" + +#: ../../po/../src/verbs.cpp:2225 +#, fuzzy +msgid "Using bitmap tracing" +msgstr "Μέγεθος Εικόνας:" + +#. "tutorial_tracing" +#: ../../po/../src/verbs.cpp:2226 +#, fuzzy +msgid "Inkscape: _Calligraphy" +msgstr "Συμπαγές" + +#: ../../po/../src/verbs.cpp:2227 +msgid "Using the Calligraphy pen tool" +msgstr "" + +#: ../../po/../src/verbs.cpp:2228 +msgid "_Elements of Design" +msgstr "" + +#: ../../po/../src/verbs.cpp:2229 +msgid "Principles of design in the tutorial form" +msgstr "" + +#. "tutorial_design" +#: ../../po/../src/verbs.cpp:2230 +msgid "_Tips and Tricks" +msgstr "" + +#: ../../po/../src/verbs.cpp:2231 +msgid "Miscellaneous tips and tricks" +msgstr "" + +#. "tutorial_tips" +#. Effect +#: ../../po/../src/verbs.cpp:2234 +msgid "Previous Effect" +msgstr "" + +#: ../../po/../src/verbs.cpp:2235 +msgid "Repeat the last effect with the same settings" +msgstr "" + +#. "tutorial_tips" +#: ../../po/../src/verbs.cpp:2236 +msgid "Previous Effect Settings..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2237 +msgid "Repeat the last effect with new settings" +msgstr "" + +#: ../../po/../src/widgets/dash-selector.cpp:106 +#, fuzzy +msgid "Dash pattern" +msgstr "Καπνός με άνεμο" + +#: ../../po/../src/widgets/dash-selector.cpp:121 +#, fuzzy +msgid "Pattern offset" +msgstr "Σχέδιο" + +#: ../../po/../src/widgets/desktop-widget.cpp:240 +#, fuzzy +msgid "Zoom drawing if window size changes" +msgstr "Αλλαγή κλίμακας για _ταίριασμα" + +#: ../../po/../src/widgets/desktop-widget.cpp:298 +msgid "Cursor coordinates" +msgstr "" + +#. display the initial welcome message in the statusbar +#: ../../po/../src/widgets/desktop-widget.cpp:324 +msgid "" +"Welcome to Inkscape! Use shape or freehand tools to create objects; " +"use selector (arrow) to move or transform them." +msgstr "" + +#: ../../po/../src/widgets/desktop-widget.cpp:372 +#, c-format +msgid "%s: %d - Inkscape" +msgstr "" + +#: ../../po/../src/widgets/desktop-widget.cpp:374 +#, c-format +msgid "%s - Inkscape" +msgstr "" + +#: ../../po/../src/widgets/desktop-widget.cpp:532 +#, c-format +msgid "" +"Save changes to document \"%s\" before " +"closing?\n" +"\n" +"If you close without saving, your changes will be discarded." +msgstr "" + +#: ../../po/../src/widgets/desktop-widget.cpp:548 +#: ../../po/../src/widgets/desktop-widget.cpp:612 +msgid "Close _without saving" +msgstr "" + +#: ../../po/../src/widgets/desktop-widget.cpp:595 +#, c-format +msgid "" +"The file \"%s\" was saved with a " +"format (%s) that may cause data loss!\n" +"\n" +"Do you want to save this file in another format?" +msgstr "" + +#. Family frame +#: ../../po/../src/widgets/font-selector.cpp:156 +msgid "Font family" +msgstr "" + +#. Style frame +#: ../../po/../src/widgets/font-selector.cpp:184 +#, fuzzy +msgid "Style" +msgstr "Στυλ: " + +#: ../../po/../src/widgets/font-selector.cpp:219 +msgid "Font size:" +msgstr "" + +#. TRANSLATORS: Test string used in text and font dialog (when no +#. * text has been entered) to get a preview of the font. Choose +#. * some representative characters that users of your locale will be +#. * interested in. +#: ../../po/../src/widgets/font-selector.cpp:554 +msgid "AaBbCcIiPpQq12368.;/()" +msgstr "" + +#: ../../po/../src/widgets/gradient-selector.cpp:137 +#: ../../po/../src/widgets/gradient-toolbar.cpp:524 +#, fuzzy +msgid "Duplicate" +msgstr "Δημιουργία αντιγράφου" + +# +#: ../../po/../src/widgets/gradient-selector.cpp:142 +#: ../../po/../src/widgets/gradient-toolbar.cpp:535 +#, fuzzy +msgid "Edit..." +msgstr "Επεξεργασία" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/pservers.html#LinearGradientSpreadMethodAttribute +#: ../../po/../src/widgets/gradient-selector.cpp:159 +msgid "" +"Whether to fill with flat color beyond the ends of the gradient vector " +"(spreadMethod=\"pad\"), or repeat the gradient in the same direction " +"(spreadMethod=\"repeat\"), or repeat the gradient in alternating opposite " +"directions (spreadMethod=\"reflect\")" +msgstr "" + +# +#: ../../po/../src/widgets/gradient-selector.cpp:165 +#, fuzzy +msgid "none" +msgstr "Κανένα" + +# +#: ../../po/../src/widgets/gradient-selector.cpp:169 +#, fuzzy +msgid "reflected" +msgstr "Επιλέχθησαν \"%s\"" + +# +#: ../../po/../src/widgets/gradient-selector.cpp:173 +#, fuzzy +msgid "direct" +msgstr "Ορθογ." + +#: ../../po/../src/widgets/gradient-selector.cpp:181 +#, fuzzy +msgid "Repeat:" +msgstr "Αναγνωσμένα" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:217 +msgid "No gradients" +msgstr "" + +# +#: ../../po/../src/widgets/gradient-toolbar.cpp:226 +#, fuzzy +msgid "Nothing selected" +msgstr "Επιλέχθησαν \"%s\"" + +# +#: ../../po/../src/widgets/gradient-toolbar.cpp:237 +#, fuzzy +msgid "No gradients in selection" +msgstr "Επιλέχθησαν \"%s\"" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:247 +msgid "Multiple gradients" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:525 +msgid "" +"If the gradient is used by more than one object, create a copy of it for the " +"selected object(s)" +msgstr "" + +# +#: ../../po/../src/widgets/gradient-toolbar.cpp:536 +#, fuzzy +msgid "Edit the stops of the gradient" +msgstr "Προσθήκη νέου παροχέα" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:593 +#: ../../po/../src/widgets/toolbox.cpp:1103 +#: ../../po/../src/widgets/toolbox.cpp:1192 +#: ../../po/../src/widgets/toolbox.cpp:1485 +#: ../../po/../src/widgets/toolbox.cpp:1534 +#: ../../po/../src/widgets/toolbox.cpp:1766 +#: ../../po/../src/widgets/toolbox.cpp:1801 +#: ../../po/../src/widgets/toolbox.cpp:2331 +#: ../../po/../src/widgets/toolbox.cpp:2370 +msgid "New:" +msgstr "" + +# +#: ../../po/../src/widgets/gradient-toolbar.cpp:606 +#, fuzzy +msgid "Create linear gradient" +msgstr "Προσθήκη νέου παροχέα" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:620 +msgid "Create radial (elliptic or circular) gradient" +msgstr "" + +# +#: ../../po/../src/widgets/gradient-toolbar.cpp:635 +#, fuzzy +msgid "on" +msgstr "Κανένα" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:648 +#, fuzzy +msgid "Create gradient in the fill" +msgstr "Βαθμίδα" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:662 +msgid "Create gradient in the stroke" +msgstr "" + +# +#. FIXME: implement averaging of all parameters for multiple selected stars +#. gtk_label_set_markup(GTK_LABEL(l), _("Average:")); +#. FIXME: implement averaging of all parameters for multiple selected +#. gtk_label_set_markup(GTK_LABEL(l), _("Average:")); +#: ../../po/../src/widgets/gradient-toolbar.cpp:676 +#: ../../po/../src/widgets/toolbox.cpp:1105 +#: ../../po/../src/widgets/toolbox.cpp:1124 +#: ../../po/../src/widgets/toolbox.cpp:1493 +#: ../../po/../src/widgets/toolbox.cpp:1518 +#: ../../po/../src/widgets/toolbox.cpp:1768 +#: ../../po/../src/widgets/toolbox.cpp:1787 +#: ../../po/../src/widgets/toolbox.cpp:2334 +#: ../../po/../src/widgets/toolbox.cpp:2354 +#, fuzzy +msgid "Change:" +msgstr "Αλλαγή" + +#: ../../po/../src/widgets/gradient-vector.cpp:269 +msgid "No gradients in document" +msgstr "" + +# +#: ../../po/../src/widgets/gradient-vector.cpp:275 +#, fuzzy +msgid "No gradient selected" +msgstr "Επιλέχθησαν \"%s\"" + +# +#: ../../po/../src/widgets/gradient-vector.cpp:532 +#, fuzzy +msgid "No stops in gradient" +msgstr "Προσθήκη νέου παροχέα" + +# +#. TRANSLATORS: "Stop" means: a "phase" of a gradient +#: ../../po/../src/widgets/gradient-vector.cpp:794 +#, fuzzy +msgid "Add stop" +msgstr "Επιφάνεια εργασίας" + +#: ../../po/../src/widgets/gradient-vector.cpp:797 +msgid "Add another control stop to gradient" +msgstr "" + +#: ../../po/../src/widgets/gradient-vector.cpp:799 +#, fuzzy +msgid "Delete stop" +msgstr "Διαγραφή επιλογής" + +#: ../../po/../src/widgets/gradient-vector.cpp:802 +msgid "Delete current control stop from gradient" +msgstr "" + +#. Label +#: ../../po/../src/widgets/gradient-vector.cpp:813 +msgid "Offset:" +msgstr "" + +#. TRANSLATORS: "Stop" means: a "phase" of a gradient +#: ../../po/../src/widgets/gradient-vector.cpp:858 +#, fuzzy +msgid "Stop Color" +msgstr " χρώμα" + +#: ../../po/../src/widgets/gradient-vector.cpp:887 +#, fuzzy +msgid "Gradient editor" +msgstr "Βαθμίδα" + +#: ../../po/../src/widgets/layer-selector.cpp:119 +#, fuzzy +msgid "Toggle current layer visibility" +msgstr "Έγγραφο" + +#: ../../po/../src/widgets/layer-selector.cpp:139 +#, fuzzy +msgid "Lock or unlock current layer" +msgstr "Έγγραφο" + +#: ../../po/../src/widgets/layer-selector.cpp:142 +#, fuzzy +msgid "Current layer" +msgstr "Έγγραφο" + +#: ../../po/../src/widgets/layer-selector.cpp:553 +msgid "(root)" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:182 +#: ../../po/../src/widgets/paint-selector.cpp:561 +#, fuzzy +msgid "No paint" +msgstr "Σημείο" + +#: ../../po/../src/widgets/paint-selector.cpp:184 +#: ../../po/../src/widgets/paint-selector.cpp:629 +#, fuzzy +msgid "Flat color" +msgstr " χρώμα" + +# +#: ../../po/../src/widgets/paint-selector.cpp:186 +#: ../../po/../src/widgets/paint-selector.cpp:696 +#, fuzzy +msgid "Linear gradient" +msgstr "Προσθήκη νέου παροχέα" + +# +#: ../../po/../src/widgets/paint-selector.cpp:188 +#: ../../po/../src/widgets/paint-selector.cpp:699 +#, fuzzy +msgid "Radial gradient" +msgstr "Προσθήκη νέου παροχέα" + +#: ../../po/../src/widgets/paint-selector.cpp:192 +msgid "Unset paint (make it undefined so it can be inherited)" +msgstr "" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/painting.html#FillRuleProperty +#: ../../po/../src/widgets/paint-selector.cpp:204 +msgid "" +"Any path self-intersections or subpaths create holes in the fill (fill-rule: " +"evenodd)" +msgstr "" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/painting.html#FillRuleProperty +#: ../../po/../src/widgets/paint-selector.cpp:215 +msgid "" +"Fill is solid unless a subpath is counterdirectional (fill-rule: nonzero)" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:528 +#, fuzzy +msgid "No objects" +msgstr "Επιλέξτε αντικείμενο" + +#: ../../po/../src/widgets/paint-selector.cpp:539 +msgid "Multiple styles" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:550 +msgid "Paint is undefined" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:757 +#, fuzzy +msgid "No patterns in document" +msgstr "Έγγραφο" + +#: ../../po/../src/widgets/paint-selector.cpp:872 +msgid "" +"Use Edit > Object(s) to Pattern to create a new pattern from " +"selection." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:426 +msgid "Now stroke width is scaled when objects are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:428 +msgid "Now stroke width is not scaled when objects are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:436 +msgid "" +"Now rounded rectangle corners are scaled when rectangles are " +"scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:438 +msgid "" +"Now rounded rectangle corners are not scaled when rectangles " +"are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:446 +msgid "" +"Now gradients are transformed along with their objects when " +"those are transformed (moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:448 +msgid "" +"Now gradients remain fixed when objects are transformed " +"(moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:456 +msgid "" +"Now patterns are transformed along with their objects when " +"those are transformed (moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:458 +msgid "" +"Now patterns remain fixed when objects are transformed (moved, " +"scaled, rotated, or skewed)." +msgstr "" + +# +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:506 +#, fuzzy +msgid "select_toolbar|X" +msgstr "Επιλογή" + +#: ../../po/../src/widgets/select-toolbar.cpp:506 +#, fuzzy +msgid "Horizontal coordinate of selection" +msgstr "Οριζόντιες Ρίγες" + +# +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:511 +#, fuzzy +msgid "select_toolbar|Y" +msgstr "Επιλογή" + +#: ../../po/../src/widgets/select-toolbar.cpp:511 +msgid "Vertical coordinate of selection" +msgstr "" + +# +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:517 +#, fuzzy +msgid "select_toolbar|W" +msgstr "Επιλογή" + +# +#: ../../po/../src/widgets/select-toolbar.cpp:517 +#, fuzzy +msgid "Width of selection" +msgstr "Αποκοπή της επιλογής" + +#: ../../po/../src/widgets/select-toolbar.cpp:525 +msgid "Change both width and height by the same proportion" +msgstr "" + +# +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:534 +#, fuzzy +msgid "select_toolbar|H" +msgstr "Επιλογή" + +#: ../../po/../src/widgets/select-toolbar.cpp:534 +#, fuzzy +msgid "Height of selection" +msgstr "Αντιγραφή ώρας στο επιλεγμένο" + +#: ../../po/../src/widgets/sp-color-gtkselector.cpp:62 +msgid "System" +msgstr "" + +#: ../../po/../src/widgets/sp-color-notebook.cpp:322 +msgid "RGBA_:" +msgstr "" + +#: ../../po/../src/widgets/sp-color-notebook.cpp:330 +msgid "Hexadecimal RGBA value of the color" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "RGB" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "HSL" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "CMYK" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:397 +msgid "_R" +msgstr "" + +# +#: ../../po/../src/widgets/sp-color-scales.cpp:398 +#: ../../po/../src/widgets/sp-color-scales.cpp:399 +#, fuzzy +msgid "Red" +msgstr "Κόκκινο:" + +#: ../../po/../src/widgets/sp-color-scales.cpp:400 +msgid "_G" +msgstr "" + +# +#: ../../po/../src/widgets/sp-color-scales.cpp:401 +#: ../../po/../src/widgets/sp-color-scales.cpp:402 +#, fuzzy +msgid "Green" +msgstr "Πράσινο:" + +#: ../../po/../src/widgets/sp-color-scales.cpp:403 +msgid "_B" +msgstr "" + +# +#: ../../po/../src/widgets/sp-color-scales.cpp:404 +#: ../../po/../src/widgets/sp-color-scales.cpp:405 +#, fuzzy +msgid "Blue" +msgstr "Μπλε:" + +#. Label +#: ../../po/../src/widgets/sp-color-scales.cpp:406 +#: ../../po/../src/widgets/sp-color-scales.cpp:432 +#: ../../po/../src/widgets/sp-color-scales.cpp:463 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:141 +msgid "_A" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:407 +#: ../../po/../src/widgets/sp-color-scales.cpp:408 +#: ../../po/../src/widgets/sp-color-scales.cpp:433 +#: ../../po/../src/widgets/sp-color-scales.cpp:434 +#: ../../po/../src/widgets/sp-color-scales.cpp:464 +#: ../../po/../src/widgets/sp-color-scales.cpp:465 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:151 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:163 +msgid "Alpha (opacity)" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:423 +msgid "_H" +msgstr "" + +# +#: ../../po/../src/widgets/sp-color-scales.cpp:424 +#: ../../po/../src/widgets/sp-color-scales.cpp:425 +#, fuzzy +msgid "Hue" +msgstr "Απόχρωση:" + +#: ../../po/../src/widgets/sp-color-scales.cpp:426 +msgid "_S" +msgstr "" + +# +#: ../../po/../src/widgets/sp-color-scales.cpp:427 +#: ../../po/../src/widgets/sp-color-scales.cpp:428 +#, fuzzy +msgid "Saturation" +msgstr "Κορεσμός:" + +#: ../../po/../src/widgets/sp-color-scales.cpp:429 +msgid "_L" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:430 +#: ../../po/../src/widgets/sp-color-scales.cpp:431 +#, fuzzy +msgid "Lightness" +msgstr "Ύψος" + +#: ../../po/../src/widgets/sp-color-scales.cpp:451 +msgid "_C" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:452 +#: ../../po/../src/widgets/sp-color-scales.cpp:453 +#, fuzzy +msgid "Cyan" +msgstr "Κυανό" + +#: ../../po/../src/widgets/sp-color-scales.cpp:454 +msgid "_M" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:455 +#: ../../po/../src/widgets/sp-color-scales.cpp:456 +#, fuzzy +msgid "Magenta" +msgstr "μώβ" + +#: ../../po/../src/widgets/sp-color-scales.cpp:457 +msgid "_Y" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:458 +#: ../../po/../src/widgets/sp-color-scales.cpp:459 +#, fuzzy +msgid "Yellow" +msgstr "Κίτρινο" + +#: ../../po/../src/widgets/sp-color-scales.cpp:460 +msgid "_K" +msgstr "" + +# +#: ../../po/../src/widgets/sp-color-selector.cpp:71 +#, fuzzy +msgid "Unnamed" +msgstr "όνομα" + +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:68 +msgid "Wheel" +msgstr "" + +#: ../../po/../src/widgets/sp-xmlview-attr-list.cpp:53 +#, fuzzy +msgid "Attribute" +msgstr "Ιδιότητες" + +# +#: ../../po/../src/widgets/sp-xmlview-attr-list.cpp:54 +msgid "Value" +msgstr "Τιμή" + +#: ../../po/../src/widgets/toolbox.cpp:424 +#, fuzzy +msgid "Insert new nodes into selected segments" +msgstr "Ξε-διαγραφή των επιλεγμένων μηνυμάτων" + +#: ../../po/../src/widgets/toolbox.cpp:426 +#, fuzzy +msgid "Delete selected nodes" +msgstr "Διαγραφή επιλογής" + +# +#: ../../po/../src/widgets/toolbox.cpp:431 +#, fuzzy +msgid "Join paths at selected nodes" +msgstr "Εκκίνηση επιλεγμένου παροχέα" + +# +#: ../../po/../src/widgets/toolbox.cpp:433 +#, fuzzy +msgid "Join paths at selected nodes with new segment" +msgstr "Εκκίνηση επιλεγμένου παροχέα" + +#: ../../po/../src/widgets/toolbox.cpp:436 +msgid "Split path between two non-endpoint nodes" +msgstr "" + +# +#: ../../po/../src/widgets/toolbox.cpp:439 +#, fuzzy +msgid "Break path at selected nodes" +msgstr "Εκκίνηση επιλεγμένου παροχέα" + +#: ../../po/../src/widgets/toolbox.cpp:444 +#, fuzzy +msgid "Make selected nodes corner" +msgstr "Διαγραφή επιλογής" + +#: ../../po/../src/widgets/toolbox.cpp:447 +#, fuzzy +msgid "Make selected nodes smooth" +msgstr "Διαγραφή επιλογής" + +#: ../../po/../src/widgets/toolbox.cpp:450 +#, fuzzy +msgid "Make selected nodes symmetric" +msgstr "Διαγραφή επιλογής" + +#: ../../po/../src/widgets/toolbox.cpp:455 +#, fuzzy +msgid "Make selected segments lines" +msgstr "Μετακίνιση επιλεγμένου μενού πρός τα κάτω" + +#: ../../po/../src/widgets/toolbox.cpp:458 +#, fuzzy +msgid "Make selected segments curves" +msgstr "Μετακίνηση επιλεγμένου μενού πρoς τα επάνω" + +#: ../../po/../src/widgets/toolbox.cpp:1199 +msgid "Polygon" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1206 +msgid "Regular polygon (with one handle) instead of a star" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1218 +msgid "Corners:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1218 +msgid "Number of corners of a polygon or star" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1228 +#, fuzzy +msgid "Spoke ratio:" +msgstr "Διατήρηση αναλογιών" + +#. TRANSLATORS: Tip radius of a star is the distance from the center to the farthest handle. +#. Base radius is the same for the closest handle. +#: ../../po/../src/widgets/toolbox.cpp:1231 +msgid "Base radius to tip radius ratio" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1246 +#, fuzzy +msgid "Rounded:" +msgstr "Σημείο προσάρτησης" + +#: ../../po/../src/widgets/toolbox.cpp:1246 +msgid "How much rounded are the corners (0 for sharp)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1256 +msgid "Randomized:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1256 +msgid "Scatter randomly the corners and angles" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1269 +#: ../../po/../src/widgets/toolbox.cpp:1838 +#: ../../po/../src/widgets/toolbox.cpp:2061 +msgid "Defaults" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1270 +#: ../../po/../src/widgets/toolbox.cpp:1839 +#: ../../po/../src/widgets/toolbox.cpp:2062 +msgid "" +"Reset shape parameters to defaults (use Inkscape Preferences > Tools to " +"change defaults)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1544 +msgid "W:" +msgstr "" + +# +#: ../../po/../src/widgets/toolbox.cpp:1544 +#, fuzzy +msgid "Width of rectangle" +msgstr "Αποκοπή της επιλογής" + +#: ../../po/../src/widgets/toolbox.cpp:1556 +#, fuzzy +msgid "Height of rectangle" +msgstr "Αντιγραφή ώρας στο επιλεγμένο" + +# +#: ../../po/../src/widgets/toolbox.cpp:1568 +#, fuzzy +msgid "Rx:" +msgstr "1:1" + +#: ../../po/../src/widgets/toolbox.cpp:1568 +#, fuzzy +msgid "Horizontal radius of rounded corners" +msgstr "Οριζόντιες Ρίγες" + +# +#: ../../po/../src/widgets/toolbox.cpp:1578 +#, fuzzy +msgid "Ry:" +msgstr "1:1" + +#: ../../po/../src/widgets/toolbox.cpp:1578 +#, fuzzy +msgid "Vertical radius of rounded corners" +msgstr "Οριζόντιες Ρίγες" + +#: ../../po/../src/widgets/toolbox.cpp:1594 +msgid "Not rounded" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1596 +msgid "Make corners sharp" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1805 +#, fuzzy +msgid "Turns:" +msgstr "Μετασχηματισμός" + +#: ../../po/../src/widgets/toolbox.cpp:1805 +msgid "Number of revolutions" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1815 +#, fuzzy +msgid "Divergence:" +msgstr "πράσινο" + +#: ../../po/../src/widgets/toolbox.cpp:1815 +msgid "How much denser/sparser are outer revolutions; 1 = uniform" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1825 +msgid "Inner radius:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1825 +msgid "Radius of the innermost revolution (relative to the spiral size)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1957 +msgid "The width of the calligraphic pen (relative to the visible canvas area)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1967 +#, fuzzy +msgid "Thinning:" +msgstr "3D Rendering" + +#: ../../po/../src/widgets/toolbox.cpp:1967 +msgid "" +"How much velocity thins the stroke (> 0 makes fast strokes thinner, < 0 " +"makes them broader, 0 makes width independent of velocity)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1980 +#, fuzzy +msgid "Angle:" +msgstr "Διάστημα" + +#: ../../po/../src/widgets/toolbox.cpp:1980 +msgid "" +"The angle of the pen's nib (in degrees; 0 = horizontal; has no effect if " +"fixation = 0)" +msgstr "" + +# +#: ../../po/../src/widgets/toolbox.cpp:1990 +#, fuzzy +msgid "Fixation:" +msgstr "Κορεσμός:" + +#: ../../po/../src/widgets/toolbox.cpp:1990 +msgid "" +"How fixed is the pen angle (0 = always perpendicular to stroke direction, 1 " +"= fixed)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2003 +msgid "Mass:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2003 +msgid "How much inertia affects the movement of the pen" +msgstr "" + +#. TRANSLATORS: "drag" means "resistance" here +#: ../../po/../src/widgets/toolbox.cpp:2014 +#, fuzzy +msgid "Drag:" +msgstr "Συρτάρι" + +#: ../../po/../src/widgets/toolbox.cpp:2014 +msgid "How much resistance affects the movement of the pen" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2034 +msgid "Use the pressure of the input device to alter the width of the pen" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2047 +msgid "Use the tilt of the input device to alter the angle of the pen's nib" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2374 +#, fuzzy +msgid "Start:" +msgstr "Αστερίσκος" + +#: ../../po/../src/widgets/toolbox.cpp:2374 +msgid "The angle (in degrees) from the horizontal to the arc's start point" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2384 +msgid "End:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2384 +msgid "The angle (in degrees) from the horizontal to the arc's end point" +msgstr "" + +# +#: ../../po/../src/widgets/toolbox.cpp:2395 +#, fuzzy +msgid "Open arc" +msgstr "_Άνοιγμα" + +#: ../../po/../src/widgets/toolbox.cpp:2396 +msgid "" +"Switch between arc (unclosed shape) and segment (closed shape with two radii)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2415 +msgid "Make whole" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2417 +msgid "Make the shape a whole ellipse, not arc or segment" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2644 +msgid "" +"When pressed, picks visible color without alpha and when not pressed, picks " +"color including its alpha" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:3039 +#, fuzzy +msgid "Make connectors avoid selected objects" +msgstr "Διαγραφή επιλογής" + +#: ../../po/../src/widgets/toolbox.cpp:3043 +#, fuzzy +msgid "Make connectors ignore selected objects" +msgstr "Διαγραφή επιλογής" + +#. +#. 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 : +#: ../share/extensions/addnodes.inx.h:1 +#, fuzzy +msgid "Add Nodes" +msgstr "Σημειώσεις" + +#: ../share/extensions/addnodes.inx.h:2 +msgid "Maximum Segment Length" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:1 +msgid "AI Input" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:2 ../share/extensions/ai_output.inx.h:2 +msgid "Adobe Illustrator (*.ai)" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:3 +msgid "Open files saved with Adobe Illustrator" +msgstr "" + +# +#: ../share/extensions/ai_output.inx.h:1 +#, fuzzy +msgid "AI Output" +msgstr "Αποκοπή" + +#: ../share/extensions/ai_output.inx.h:3 +msgid "Write Adobe Illustrator" +msgstr "" + +#: ../share/extensions/dia.inx.h:1 +msgid "A diagram created with the program Dia" +msgstr "" + +#: ../share/extensions/dia.inx.h:2 +msgid "Dia Diagram (*.dia)" +msgstr "" + +#: ../share/extensions/dia.inx.h:3 +msgid "Dia Input" +msgstr "" + +#: ../share/extensions/dia.inx.h:4 +msgid "" +"In order to import Dia files, Dia itself must be installed. You can get Dia " +"at http://www.gnome.org/projects/dia/" +msgstr "" + +#: ../share/extensions/dia.inx.h:5 +msgid "" +"The dia2svg.sh script should be installed with your Inkscape distribution. " +"If you do not have it, there is likely to be something wrong with your " +"Inkscape installation." +msgstr "" + +#: ../share/extensions/dots.inx.h:1 +#, fuzzy +msgid "Connect the Dots" +msgstr "Νέα Προβολή" + +#: ../share/extensions/dots.inx.h:2 +#, fuzzy +msgid "Dot Size" +msgstr "Γουϊνέα" + +#: ../share/extensions/dots.inx.h:3 +#, fuzzy +msgid "Font Size" +msgstr "Γουϊνέα" + +#: ../share/extensions/dropshadow.inx.h:1 +msgid "Color of shadow" +msgstr "" + +#: ../share/extensions/dropshadow.inx.h:2 +msgid "Dropshadow" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:1 +#: ../share/extensions/dxf_output.inx.h:1 +msgid "AutoCAD DXF (*.dxf)" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:2 +msgid "DXF Input" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:3 +msgid "Import AutoCAD's Document Exchange Format" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:4 +msgid "" +"dxf2svg may come with Inkscape, but is also at http://dxf-svg-convert." +"sourceforge.net/" +msgstr "" + +# +#: ../share/extensions/dxf_output.inx.h:2 +#, fuzzy +msgid "DXF Output" +msgstr "Αποκοπή" + +#: ../share/extensions/dxf_output.inx.h:3 +msgid "DXF file written by pstoedit" +msgstr "" + +#: ../share/extensions/dxf_output.inx.h:4 +msgid "pstoedit must be installed to run see http://www.pstoedit.net/pstoedit" +msgstr "" + +# +#: ../share/extensions/embedimage.inx.h:1 +#, fuzzy +msgid "Embed Images" +msgstr "Εικόνα" + +#: ../share/extensions/eps_input.inx.h:1 +msgid "EPS Input" +msgstr "" + +#: ../share/extensions/eps_input.inx.h:2 +msgid "Encapsulated Postscript" +msgstr "" + +#: ../share/extensions/eps_input.inx.h:3 +msgid "Encapsulated Postscript (*.eps)" +msgstr "" + +# +#: ../share/extensions/epsi_output.inx.h:1 +#, fuzzy +msgid "EPSI Output" +msgstr "Αποκοπή" + +#: ../share/extensions/epsi_output.inx.h:2 +msgid "Encapsulated Postscript Interchange (*.epsi)" +msgstr "" + +#: ../share/extensions/epsi_output.inx.h:3 +msgid "Encapsulated Postscript with a thumbnail" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:1 ../share/extensions/ffms.inx.h:1 +#: ../share/extensions/ffset.inx.h:1 ../share/extensions/ffss.inx.h:1 +#, fuzzy +msgid "Bridge Width" +msgstr "Πλάτος" + +#: ../share/extensions/ffmet.inx.h:2 ../share/extensions/ffms.inx.h:2 +msgid "First String Length" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:3 +msgid "FretFind Multi Length ET" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:4 ../share/extensions/ffms.inx.h:4 +#: ../share/extensions/ffset.inx.h:3 ../share/extensions/ffss.inx.h:3 +msgid "Fretboard Edges" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:5 ../share/extensions/ffms.inx.h:5 +msgid "Last String Length" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:6 ../share/extensions/ffms.inx.h:6 +#: ../share/extensions/ffset.inx.h:4 ../share/extensions/ffss.inx.h:4 +msgid "Number of Frets" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:7 ../share/extensions/ffms.inx.h:7 +#: ../share/extensions/ffset.inx.h:5 ../share/extensions/ffss.inx.h:5 +msgid "Number of Strings" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:8 ../share/extensions/ffms.inx.h:8 +#: ../share/extensions/ffset.inx.h:6 ../share/extensions/ffss.inx.h:6 +#, fuzzy +msgid "Nut Width" +msgstr "Πλάτος:" + +#: ../share/extensions/ffmet.inx.h:9 ../share/extensions/ffms.inx.h:10 +msgid "Perpendicular Distance" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:10 ../share/extensions/ffset.inx.h:7 +msgid "Scale Base (2 for Octave)" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:11 ../share/extensions/ffset.inx.h:9 +msgid "Tones in Scale" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:12 ../share/extensions/ffms.inx.h:12 +#: ../share/extensions/ffset.inx.h:10 ../share/extensions/ffss.inx.h:10 +msgid "px per Unit" +msgstr "" + +#: ../share/extensions/ffms.inx.h:3 +msgid "FretFind Multi Length Scala" +msgstr "" + +#: ../share/extensions/ffms.inx.h:9 ../share/extensions/ffss.inx.h:7 +msgid "Path to Scala *.scl File" +msgstr "" + +#: ../share/extensions/ffms.inx.h:11 +msgid "Tuning (scale step for each string seperated by semicolons)" +msgstr "" + +#: ../share/extensions/ffset.inx.h:2 +msgid "FretFind Single Length ET" +msgstr "" + +#: ../share/extensions/ffset.inx.h:8 ../share/extensions/ffss.inx.h:8 +msgid "Scale Length" +msgstr "" + +#: ../share/extensions/ffss.inx.h:2 +msgid "FretFind Single Length Scala" +msgstr "" + +#: ../share/extensions/ffss.inx.h:9 +msgid "Tuning (Scale step for each string seperated by semicolons)" +msgstr "" + +#: ../share/extensions/handles.inx.h:1 +#, fuzzy +msgid "Draw Handles" +msgstr "Λαβή συρταριού" + +#: ../share/extensions/interp.inx.h:1 +#, fuzzy +msgid "Duplicate Endpaths" +msgstr "Δημιουργία αντιγράφου" + +# +#: ../share/extensions/interp.inx.h:2 +#, fuzzy +msgid "Exponent" +msgstr "Εξαγωγή" + +#: ../share/extensions/interp.inx.h:3 +msgid "Interpolate" +msgstr "" + +#: ../share/extensions/interp.inx.h:4 +msgid "Interpolate Style (Experimental)" +msgstr "" + +#: ../share/extensions/interp.inx.h:5 +msgid "Interpolation Method" +msgstr "" + +#: ../share/extensions/interp.inx.h:6 +msgid "Interpolation Steps" +msgstr "" + +#: ../share/extensions/kochify.inx.h:1 +msgid "Kochify" +msgstr "" + +#: ../share/extensions/kochify_load.inx.h:1 +msgid "Kochify (Load)" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:1 +#, fuzzy +msgid "Angle" +msgstr "Διάστημα" + +#: ../share/extensions/lindenmayer.inx.h:2 +msgid "Axiom" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:3 +#, fuzzy +msgid "Lindenmayer" +msgstr "Αρχικοποίηση" + +#: ../share/extensions/lindenmayer.inx.h:4 +msgid "Order" +msgstr "" + +# +#: ../share/extensions/lindenmayer.inx.h:5 +#, fuzzy +msgid "Rules" +msgstr "Αρχείο" + +#: ../share/extensions/lindenmayer.inx.h:6 +#, fuzzy +msgid "Step" +msgstr "Στυλ: " + +#: ../share/extensions/motion.inx.h:1 +#, fuzzy +msgid "Direction" +msgstr "Θέση" + +#: ../share/extensions/motion.inx.h:2 +#, fuzzy +msgid "Magnitude" +msgstr "μώβ" + +#: ../share/extensions/motion.inx.h:3 +#, fuzzy +msgid "Motion" +msgstr "Επιλογή" + +#: ../share/extensions/pdf_output.inx.h:1 +msgid "Adobe PDF (*.pdf)" +msgstr "" + +#: ../share/extensions/pdf_output.inx.h:2 +msgid "Adobe Portable Document Format" +msgstr "" + +# +#: ../share/extensions/pdf_output.inx.h:3 +#, fuzzy +msgid "PDF Output" +msgstr "Αποκοπή" + +#: ../share/extensions/ps_input.inx.h:1 +#, fuzzy +msgid "Postscript" +msgstr "Σημείο" + +#: ../share/extensions/ps_input.inx.h:2 +msgid "Postscript (*.ps)" +msgstr "" + +#: ../share/extensions/ps_input.inx.h:3 +msgid "Postscript Input" +msgstr "" + +#: ../share/extensions/radiusrand.inx.h:1 +#, fuzzy +msgid "Radius" +msgstr "Αρχικοποίηση" + +#: ../share/extensions/radiusrand.inx.h:2 +#, fuzzy +msgid "Radius Randomize" +msgstr "Αρχικοποίηση" + +#: ../share/extensions/radiusrand.inx.h:3 +msgid "Randomize Control Points" +msgstr "" + +#: ../share/extensions/radiusrand.inx.h:4 +#, fuzzy +msgid "Randomize Nodes" +msgstr "Αρχικοποίηση" + +#: ../share/extensions/rtree.inx.h:1 +#, fuzzy +msgid "Initial Size" +msgstr "Μέγεθος Εικόνας:" + +#: ../share/extensions/rtree.inx.h:2 +msgid "Minimum Size" +msgstr "" + +#: ../share/extensions/rtree.inx.h:3 +msgid "Random Tree" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:1 +msgid "A diagram created with the program Sketch" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:2 +msgid "Sketch Diagram (*.sk)" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:3 +msgid "Sketch Input" +msgstr "" + +#: ../share/extensions/straightseg.inx.h:1 +msgid "Behavior" +msgstr "" + +#: ../share/extensions/straightseg.inx.h:3 +msgid "Segment Straightener" +msgstr "" + +#: ../share/extensions/summersnight.inx.h:1 +msgid "Summer's Night" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:1 +#: ../share/extensions/svgz_output.inx.h:1 +#, fuzzy +msgid "Compressed Inkscape SVG (*.svgz)" +msgstr "Συμπίεση αρχείων:" + +#: ../share/extensions/svgz_input.inx.h:2 +#: ../share/extensions/svgz_output.inx.h:2 +msgid "Inkscape's native file format compressed with GZip" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:3 +msgid "SVGZ Input" +msgstr "" + +# +#: ../share/extensions/svgz_output.inx.h:3 +#, fuzzy +msgid "SVGZ Output" +msgstr "Αποκοπή" + +#: ../share/extensions/txt2svg.inx.h:1 +msgid "ASCII Text" +msgstr "" + +#: ../share/extensions/txt2svg.inx.h:2 +msgid "Text File (*.txt)" +msgstr "" + +#: ../share/extensions/txt2svg.inx.h:3 +#, fuzzy +msgid "Text Input" +msgstr " χρώμα" + +#: ../share/extensions/wavy.inx.h:1 +msgid "Calculate first derivative numerically" +msgstr "" + +#: ../share/extensions/wavy.inx.h:2 +msgid "First derivative" +msgstr "" + +#: ../share/extensions/wavy.inx.h:3 +msgid "Function" +msgstr "" + +#: ../share/extensions/wavy.inx.h:4 +msgid "Function Plotter" +msgstr "" + +#: ../share/extensions/wavy.inx.h:5 +msgid "Nodes per period" +msgstr "" + +#: ../share/extensions/wavy.inx.h:6 +msgid "Periods (2*Pi each)" +msgstr "" + +#: ../share/extensions/whirl.inx.h:1 +msgid "Amount of Whirl" +msgstr "" + +#: ../share/extensions/whirl.inx.h:2 +#, fuzzy +msgid "Center X" +msgstr "Κέντρο" + +#: ../share/extensions/whirl.inx.h:3 +#, fuzzy +msgid "Center Y" +msgstr "Κέντρο" + +# +#: ../share/extensions/whirl.inx.h:4 +#, fuzzy +msgid "Direction of Rotation" +msgstr "Αντιγραφή επιλογής στο τεμάχιο" + +#: ../share/extensions/whirl.inx.h:5 +msgid "Whirl" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:1 +msgid "A popular graphics file format for clipart" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:2 +msgid "Windows Metafile (*.wmf)" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:3 +msgid "Windows Metafile Input" +msgstr "" + +#, fuzzy +#~ msgid "Custom canvas" +#~ msgstr "Διαστάσεις" + +#, fuzzy +#~ msgid "Current style" +#~ msgstr "Ρυθμίσεις επιφάνειας εργασίας" + +# +#, fuzzy +#~ msgid "Arrange Objects" +#~ msgstr "Αντικείμενο" + +#, fuzzy +#~ msgid "deg" +#~ msgstr "dec" + +#, fuzzy +#~ msgid "_Credits" +#~ msgstr "Κολομβία" + +#, fuzzy +#~ msgid "Grab sensitivity" +#~ msgstr "Πεζά/κεφαλαία διαφέρουν" + +#, fuzzy +#~ msgid "Acceleration" +#~ msgstr "Επιλογή" + +# +#, fuzzy +#~ msgid "Speed" +#~ msgstr "Κόκκινο:" + +#, fuzzy +#~ msgid "Zoom in/out by" +#~ msgstr "Σμίκρυνση" + +#, fuzzy +#~ msgid "Transform" +#~ msgstr "Μετασχηματισμός" + +# +#, fuzzy +#~ msgid "Rotate _90 deg CW" +#~ msgstr "Διαγραφή επιλεγμένου αντικειμένου" + +# +#, fuzzy +#~ msgid "Rotate 9_0 deg CCW" +#~ msgstr "Διαγραφή επιλεγμένου αντικειμένου" + +#, fuzzy +#~ msgid "Flip selection horizontally" +#~ msgstr "Διαγραφή επιλεγμένων αντικειμένων" + +#, fuzzy +#~ msgid "Flip selection vertically" +#~ msgstr "Διαγραφή επιλεγμένων αντικειμένων" + +# +#~ msgid "Edit" +#~ msgstr "Επεξεργασία" + +# +#~ msgid "Add" +#~ msgstr "Προσθήκη" + +# +#, fuzzy +#~ msgid "C_reate" +#~ msgstr "Δημιουργία γραμμής" + +#, fuzzy +#~ msgid "Automatically scale Rows to fit selected objects." +#~ msgstr "Διαγραφή επιλεγμένων αντικειμένων" + +#, fuzzy +#~ msgid "Automatically scale Columns to fit selected objects." +#~ msgstr "Διαγραφή επιλεγμένων αντικειμένων" + +#, fuzzy +#~ msgid "Go to root" +#~ msgstr "Επεξεργασία Φακέλων" + +#, fuzzy +#~ msgid "X" +#~ msgstr "X509" + +#, fuzzy +#~ msgid "Y" +#~ msgstr "0" + +#, fuzzy +#~ msgid "Sides:" +#~ msgstr "Γουϊνέα" + +# +#, fuzzy +#~ msgid "R1:" +#~ msgstr "1:1" + +# +#, fuzzy +#~ msgid "R2:" +#~ msgstr "2:1" + +#, fuzzy +#~ msgid "Flatsides:" +#~ msgstr "Γουϊνέα" + +#, fuzzy +#~ msgid "Start Angle:" +#~ msgstr "Αστερίσκος" + +#, fuzzy +#~ msgid "End Angle:" +#~ msgstr "Διάστημα" + +# +#, fuzzy +#~ msgid "Open:" +#~ msgstr "_Άνοιγμα" + +#, fuzzy +#~ msgid "Revolutions:" +#~ msgstr "Επιλογή" + +#, fuzzy +#~ msgid "RX:" +#~ msgstr "Χ:" + +#, fuzzy +#~ msgid "RY:" +#~ msgstr "Ψ:" + +#, fuzzy +#~ msgid "Rectangle _Properties" +#~ msgstr " Ιδιότητες" + +#, fuzzy +#~ msgid "Star _Properties" +#~ msgstr " Ιδιότητες" + +#, fuzzy +#~ msgid "Ellipse _Properties" +#~ msgstr " Ιδιότητες" + +#, fuzzy +#~ msgid "Spiral _Properties" +#~ msgstr " Ιδιότητες" + +# +#, fuzzy +#~ msgid "Document Preferences" +#~ msgstr "Προτιμίσεις Ναυτίλου" + +#, fuzzy +#~ msgid "Extensions Editor" +#~ msgstr "Διαστάσεις:" + +# +#, fuzzy +#~ msgid "Preferences" +#~ msgstr "Προτιμίσεις Ναυτίλου" + +#, fuzzy +#~ msgid "Layer Editor" +#~ msgstr "Αποθήκευση επιλογής" + +#, fuzzy +#~ msgid "Text Properties" +#~ msgstr " Ιδιότητες" + +#, fuzzy +#~ msgid "Transformation" +#~ msgstr "Μετασχηματισμός" + +# +#, fuzzy +#~ msgid "_Export..." +#~ msgstr "Εισαγωγή" + +#, fuzzy +#~ msgid "_Document Properties" +#~ msgstr "Δοκιμή ρυθμίσεων" + +#, fuzzy +#~ msgid "In_kscape Preferences" +#~ msgstr "Συμπαγές" + +# +#, fuzzy +#~ msgid "Select _Original Clone" +#~ msgstr "Επιλογή" + +# +#, fuzzy +#~ msgid "Tile" +#~ msgstr "Αρχείο" + +# +#, fuzzy +#~ msgid "Select A_ll" +#~ msgstr "Επιλογή" + +#, fuzzy +#~ msgid "Select Non_e" +#~ msgstr "Επιλογή" + +#, fuzzy +#~ msgid "Zoom _In" +#~ msgstr "Μεγέθυνση" + +#, fuzzy +#~ msgid "Zoom _Out" +#~ msgstr "Σμίκρυνση" + +#, fuzzy +#~ msgid "Pre_vious" +#~ msgstr "Κλείσιμο καταγραφών" + +# +#, fuzzy +#~ msgid "Nex_t" +#~ msgstr "Κείμενο" + +#, fuzzy +#~ msgid "Tool Co_ntrols bar" +#~ msgstr "Επιλογές Oaf" + +#, fuzzy +#~ msgid "R_ename Layer..." +#~ msgstr "Αρχικοποίηση" + +#, fuzzy +#~ msgid "D_uplicate Layer" +#~ msgstr "Δημιουργία αντιγράφου" + +# +#, fuzzy +#~ msgid "_Delete Layer" +#~ msgstr "Επιλογή" + +# +#, fuzzy +#~ msgid "Select Ne_xt Layer" +#~ msgstr "Επιλογή" + +#, fuzzy +#~ msgid "Select Pre_vious Layer" +#~ msgstr "Επιλογή" + +#, fuzzy +#~ msgid "Select To_p Layer" +#~ msgstr "Επιλογή" + +#, fuzzy +#~ msgid "Move to Ne_w Layer" +#~ msgstr "Έγγραφο" + +# +#, fuzzy +#~ msgid "Move to B_ottom Layer" +#~ msgstr "Αντιγραφή επιλογής στο τεμάχιο" + +#, fuzzy +#~ msgid "_Trace Bitmap..." +#~ msgstr "Διακοπείσα σωλήνωση" + +# +#, fuzzy +#~ msgid "_Put Text on Path" +#~ msgstr "Διαγραφή επιλεγμένου αντικειμένου" + +# +#, fuzzy +#~ msgid "_Remove Text from Path" +#~ msgstr "Διαγραφή επιλεγμένου αντικειμένου" + +#, fuzzy +#~ msgid "Freehand" +#~ msgstr "Γροιλανδία" + +#, fuzzy +#~ msgid "DynaDraw" +#~ msgstr "Συρτάρι" + +#, fuzzy +#~ msgid "Stroke" +#~ msgstr "Καπνός" + +#, fuzzy +#~ msgid "Corners" +#~ msgstr "Νέα Προβολή" + +# +#, fuzzy +#~ msgid "Delete" +#~ msgstr "Διαγραφή" + +# +#, fuzzy +#~ msgid "Join" +#~ msgstr "Όνομα χρήστη:" + +# +#, fuzzy +#~ msgid "Delete Segment" +#~ msgstr "Καθαρισμός της επιλογής" + +#, fuzzy +#~ msgid "Break" +#~ msgstr "πραγματική διαδρομή" + +#, fuzzy +#~ msgid "Symmetric" +#~ msgstr "Χρήση Μετρικού Συστήματος" + +# +#, fuzzy +#~ msgid "Line" +#~ msgstr "Σύνδεση" + +# +#~ msgid "New" +#~ msgstr "Νέο" + +#, fuzzy +#~ msgid "Revert to Saved" +#~ msgstr "Σύνδεση με %s" + +#, fuzzy +#~ msgid "Save" +#~ msgstr "Σκίαση" + +#, fuzzy +#~ msgid "Save As..." +#~ msgstr "Αποθήκευση αρχείου" + +# +#, fuzzy +#~ msgid "Import..." +#~ msgstr "Εισαγωγή" + +# +#, fuzzy +#~ msgid "Export..." +#~ msgstr "Εξαγωγή" + +#, fuzzy +#~ msgid "Print..." +#~ msgstr "Σημείο" + +#, fuzzy +#~ msgid "Global Inkscape preferences (Shift+Ctrl+P)" +#~ msgstr "Εμφάνιση Σταθμών:" + +# +#, fuzzy +#~ msgid "Undo" +#~ msgstr "Ακύρωση" + +# +#, fuzzy +#~ msgid "Redo" +#~ msgstr "Επανεκτέλεση" + +# +#, fuzzy +#~ msgid "Cut" +#~ msgstr "Αποκοπή" + +# +#, fuzzy +#~ msgid "Copy" +#~ msgstr "Αντιγραφή" + +#, fuzzy +#~ msgid "Duplicate selected object(s) (Ctrl+D)" +#~ msgstr "Διαγραφή επιλεγμένων αντικειμένων" + +#, fuzzy +#~ msgid "Clone selected object (Alt+D)" +#~ msgstr "Διαγραφή επιλεγμένων αντικειμένων" + +#, fuzzy +#~ msgid "Zoom in (+)" +#~ msgstr "Μεγέθυνση" + +#, fuzzy +#~ msgid "Zoom out (-)" +#~ msgstr "Σμίκρυνση" + +# +#, fuzzy +#~ msgid "Zoom to 1:1 (100%) (1)" +#~ msgstr "Μεγέθυνση _1:1" + +#, fuzzy +#~ msgid "Zoom to 1:2 (50%) (2)" +#~ msgstr "Κλίμακα 125%" + +#, fuzzy +#~ msgid "Zoom to 2:1 (200%) (0)" +#~ msgstr "Κλίμακα 25%" + +#, fuzzy +#~ msgid "Zoom to fit selection in window (3)" +#~ msgstr "Αποθήκευση επιλογής" + +#, fuzzy +#~ msgid "Zoom to fit drawing in window (4)" +#~ msgstr "Αλλαγή κλίμακας για _ταίριασμα" + +#, fuzzy +#~ msgid "Zoom to fit page in window (5)" +#~ msgstr "Πλάτος &Σελίδας" + +#, fuzzy +#~ msgid "Zoom to fit page width in window (6)" +#~ msgstr "Πλάτος &Σελίδας" + +#, fuzzy +#~ msgid "Fill and Stroke dialog (Shift+Ctrl+F)" +#~ msgstr "Ρυθμίσεις επιφάνειας εργασίας" + +# +#, fuzzy +#~ msgid "Group selected objects (Ctrl+G)" +#~ msgstr "Διαγραφή επιλεγμένου αντικειμένου" + +#, fuzzy +#~ msgid "Ungroup selected group(s) (Ctrl+U)" +#~ msgstr "Διαγραφή επιλεγμένων αντικειμένων" + +#, fuzzy +#~ msgid "Raise selection up one step (PgUp)" +#~ msgstr "Μόνον επιλογή" + +#, fuzzy +#~ msgid "Lower selection down one step (PgDn)" +#~ msgstr "Δεν έγινε επιλογή" + +#, fuzzy +#~ msgid "Raise selection to top (Home)" +#~ msgstr "Αποθήκευση επιλογής" + +# +#, fuzzy +#~ msgid "Lower selection to bottom (End)" +#~ msgstr "Αντιγραφή επιλογής στο τεμάχιο" + +#, fuzzy +#~ msgid "Move selection to new layer" +#~ msgstr "Δεν έγινε επιλογή" + +#, fuzzy +#~ msgid "Move selection to next layer" +#~ msgstr "Δεν έγινε επιλογή" + +# +#, fuzzy +#~ msgid "Move selection to previous layer" +#~ msgstr "Αντιγραφή επιλογής στο τεμάχιο" + +#, fuzzy +#~ msgid "Move selection to top layer" +#~ msgstr "Αποθήκευση επιλογής" + +# +#, fuzzy +#~ msgid "Move selection to bottom layer" +#~ msgstr "Αντιγραφή επιλογής στο τεμάχιο" + +# +#, fuzzy +#~ msgid "Rotate selection 90° clockwise (Shift+Ctrl+Right)" +#~ msgstr "Διαγραφή επιλεγμένου αντικειμένου" + +# +#, fuzzy +#~ msgid "Rotate selection 90° counter-clockwise (Shift+Ctrl+Left)" +#~ msgstr "Διαγραφή επιλεγμένου αντικειμένου" + +#, fuzzy +#~ msgid "Flip selection horizontally (H)" +#~ msgstr "Διαγραφή επιλεγμένων αντικειμένων" + +#, fuzzy +#~ msgid "Flip selection vertically (V)" +#~ msgstr "Διαγραφή επιλεγμένων αντικειμένων" + +#, fuzzy +#~ msgid "Align and Distribute dialog (Shift+Ctrl+A)" +#~ msgstr "Ιδιότητες" + +# +#, fuzzy +#~ msgid "Convert selected object(s) to path(s) (Shift+Ctrl+C)" +#~ msgstr "Διαγραφή επιλεγμένου αντικειμένου" + +# +#, fuzzy +#~ msgid "Convert selected stroke(s) to path(s) (Ctrl+Alt+C)" +#~ msgstr "Διαγραφή επιλεγμένου αντικειμένου" + +#, fuzzy +#~ msgid "Text and Font dialog (Shift+Ctrl+T)" +#~ msgstr "Ρυθμίσεις επιφάνειας εργασίας" + +#, fuzzy +#~ msgid "Node tool" +#~ msgstr " Επεξεργασία " + +#, fuzzy +#~ msgid "Zoom tool" +#~ msgstr "Σμίκρυνση" + +#, fuzzy +#~ msgid "Rectangle tool" +#~ msgstr "Ορθογώνιο" + +#, fuzzy +#~ msgid "Arc tool" +#~ msgstr " χρώμα" + +#, fuzzy +#~ msgid "Star tool" +#~ msgstr " χρώμα" + +#, fuzzy +#~ msgid "Spiral tool" +#~ msgstr "Ειδικό" + +#, fuzzy +#~ msgid "Freehand tool" +#~ msgstr "Γροιλανδία" + +#, fuzzy +#~ msgid "Pen tool" +#~ msgstr "Ορθογώνιο" + +#, fuzzy +#~ msgid "Dropper tool" +#~ msgstr "Ειδικό" + +#, fuzzy +#~ msgid "When scaling rectangles, scale radii of rounded corners" +#~ msgstr "Οριζόντιες Ρίγες" + +#, fuzzy +#~ msgid "Delete segment between two nodes" +#~ msgstr "Διαγραφή επιλογής" + +# +#, fuzzy +#~ msgid "Select All in All Layers" +#~ msgstr "Επιλογή" + +#, fuzzy +#~ msgid "Invert Selection" +#~ msgstr "Επιλογή" + +#, fuzzy +#~ msgid "Clean up selected path(s)" +#~ msgstr "Αντιγραφή επιλεγμένης εργασίας" + +#, fuzzy +#~ msgid "_Scripts..." +#~ msgstr "Σημείο" + +#, fuzzy +#~ msgid "Align and Distribute" +#~ msgstr "Ιδιότητες" + +#, fuzzy +#~ msgid "Align and Distribute Dialog" +#~ msgstr "Ιδιότητες" + +#, fuzzy +#~ msgid "Export Dialog" +#~ msgstr "Το %s εισήχθη" + +#, fuzzy +#~ msgid "Fill and Stroke Dialog" +#~ msgstr "Ρυθμίσεις επιφάνειας εργασίας" + +#, fuzzy +#~ msgid "Find Dialog" +#~ msgstr "Κατακόρυ_φη Στοίχιση" + +#, fuzzy +#~ msgid "Inkscape Preferences" +#~ msgstr "Συμπαγές" + +#, fuzzy +#~ msgid "Inkscape Preferences Dialog" +#~ msgstr "Συμπαγές" + +#, fuzzy +#~ msgid "Layer Editor Dialog" +#~ msgstr "Αποθήκευση επιλογής" + +# +#, fuzzy +#~ msgid "Text Properties Dialog" +#~ msgstr "Ιδιότητες αντικειμένου" + +#, fuzzy +#~ msgid "Transformation Dialog" +#~ msgstr "Μετασχηματισμός" + +#, fuzzy +#~ msgid "Tree Editor" +#~ msgstr "Βαθμίδα" + +#, fuzzy +#~ msgid "XML Editor Dialog" +#~ msgstr "Επεξεργασία..." + +#, fuzzy +#~ msgid "Row height:" +#~ msgstr "Ύψος:" + +# +#, fuzzy +#~ msgid "Column width:" +#~ msgstr "Αλλαγή" + +#, fuzzy +#~ msgid "Creating anchor at (%g,%g)" +#~ msgstr "Ημέρα έναρξης:" + +#, fuzzy +#~ msgid "EPS Output Settings" +#~ msgstr "Δοκιμή ρυθμίσεων" + +#, fuzzy +#~ msgid "Inkscape" +#~ msgstr "Συμπαγές" + +# +#, fuzzy +#~ msgid "Alternate sign" +#~ msgstr "Κορεσμός:" + +# +#, fuzzy +#~ msgid "Rows:" +#~ msgstr "Έλλειψη" + +#, fuzzy +#~ msgid "Minor grid line color:" +#~ msgstr "Επιλογή χρώματος" + +#, fuzzy +#~ msgid "Grid color" +#~ msgstr " χρώμα" + +#, fuzzy +#~ msgid "Grid emphasis color" +#~ msgstr " χρώμα" + +# +#, fuzzy +#~ msgid "Major grid line spacing:" +#~ msgstr "Διάστιχο:" + +#, fuzzy +#~ msgid "Background (also for export):" +#~ msgstr " χρώμα" + +# +#, fuzzy +#~ msgid "Picking colors:" +#~ msgstr "Διαλέξτε χρώμα" + +#, fuzzy +#~ msgid "Fill style" +#~ msgstr "Όλες οι ρυθμίσεις" + +#, fuzzy +#~ msgid "Fill:" +#~ msgstr "Γέμισμα" + +#, fuzzy +#~ msgid "winding" +#~ msgstr "3D Rendering" + +# +#, fuzzy +#~ msgid "alternating" +#~ msgstr "Κορεσμός:" + +#, fuzzy +#~ msgid "Update Properties" +#~ msgstr " Ιδιότητες" + +#, fuzzy +#~ msgid "Label invalid" +#~ msgstr "Άκυρη κίνηση." + +#, fuzzy +#~ msgid "executable" +#~ msgstr "Ορθογώνιο" + +# +#, fuzzy +#~ msgid "file" +#~ msgstr "_Αρχείο" + +#, fuzzy +#~ msgid "path" +#~ msgstr "στιγ." + +#, fuzzy +#~ msgid "absolute" +#~ msgstr "Εκτός χρήσης" + +#, fuzzy +#~ msgid "Could not create sodipodi-svg-doc factory" +#~ msgstr "" +#~ "Δεν ήταν δυνατή η δημιουργία του εργοστασίου επεξεργασίας συστατικού" + +# +#, fuzzy +#~ msgid "SVG Files" +#~ msgstr "Αρχείο" + +#, fuzzy +#~ msgid "Make s_ensitive" +#~ msgstr "Πεζά/κεφαλαία διαφέρουν" + +#, fuzzy +#~ msgid "Make i_nsensitive" +#~ msgstr "Πεζά/κεφαλαία διαφέρουν" + +#, fuzzy +#~ msgid "Layer Properties" +#~ msgstr " Ιδιότητες" + +# +#, fuzzy +#~ msgid "Select object(s) to tile." +#~ msgstr "Διαγραφή επιλεγμένου αντικειμένου" + +#~ msgid "Sensitive" +#~ msgstr "Ευαίσθητο" + +# +#~ msgid "Active" +#~ msgstr "Ενεργό" + +#, fuzzy +#~ msgid "Printable" +#~ msgstr "Εγγράψιμο" + +#, fuzzy +#~ msgid "Document Name:" +#~ msgstr "Έγγραφο" + +# +#, fuzzy +#~ msgid "Image URI:" +#~ msgstr "Εικόνα" + +#~ msgid "Visible" +#~ msgstr "Ορατό" + +#, fuzzy +#~ msgid "Flatness:" +#~ msgstr "Γουϊνέα" + +#, fuzzy +#~ msgid "Other" +#~ msgstr "Διάταξη" + +# +#, fuzzy +#~ msgid "Trace: Selected object is not an image" +#~ msgstr "Διαγραφή επιλεγμένου αντικειμένου" + +# +#, fuzzy +#~ msgid "object" +#~ msgstr "Αντικείμενο" + +#, fuzzy +#~ msgid "user space" +#~ msgstr "Κατειλλημένος χώρος" + +#, fuzzy +#~ msgid "Coordinates:" +#~ msgstr "Κολομβία" + +#, fuzzy +#~ msgid "Alignment:" +#~ msgstr "Στοίχιση" + +#, fuzzy +#~ msgid "Draw arc: %s x %s" +#~ msgstr "Ημέρα έναρξης:" + +# +#, fuzzy +#~ msgid "Draw rectangle: %s x %s" +#~ msgstr "Δημιουργία ορθογωνίου" + +#, fuzzy +#~ msgid "Move by %s, %s" +#~ msgstr "Μετακίνηση" + +# +#, fuzzy +#~ msgid "Active group" +#~ msgstr "Ενεργό" + +#, fuzzy +#~ msgid "typeset object" +#~ msgstr "Επιλέξτε αντικείμενο" + +#, fuzzy +#~ msgid "Pattern Fill" +#~ msgstr "Σχέδιο" + +#, fuzzy +#~ msgid "Snap to grid" +#~ msgstr "Τοπο_θέτηση Σε Πλέγμα" + +#, fuzzy +#~ msgid "Snap to guides" +#~ msgstr "Τοπο_θέτηση Σε Πλέγμα" + +# +#, fuzzy +#~ msgid "_Menu" +#~ msgstr "_Άνοιγμα" + +#, fuzzy +#~ msgid "Snap points to the grid" +#~ msgstr "Τοπο_θέτηση Σε Πλέγμα" + +#, fuzzy +#~ msgid "Rect" +#~ msgstr "Ορθογώνιο" + +#, fuzzy +#~ msgid "meters" +#~ msgstr "χιλιοστά" + +#, fuzzy +#~ msgid "Userspace unit" +#~ msgstr "Κατειλλημένος χώρος" + +#, fuzzy +#~ msgid "User" +#~ msgstr "Κατειλλημένος χώρος" + +#, fuzzy +#~ msgid "Userspace units" +#~ msgstr "Κατειλλημένος χώρος" + +# +#, fuzzy +#~ msgid "Ru_lers" +#~ msgstr "Αρχείο" + +# +#, fuzzy +#~ msgid "Show or hide rulers" +#~ msgstr "Εμφάνιση κόμβων-δ" + +#, fuzzy +#~ msgid "_New Window" +#~ msgstr "Νέα Προβολή" + +#, fuzzy +#~ msgid "Mode:" +#~ msgstr "Μετακίνηση" + +#~ msgid "Alpha:" +#~ msgstr "Άλφα:" + +# +#~ msgid "Value:" +#~ msgstr "Τιμή:" + +#, fuzzy +#~ msgid "Stroke settings" +#~ msgstr "Ρυθμίσεις επιφάνειας εργασίας" + +#, fuzzy +#~ msgid "Item properties" +#~ msgstr "Ιδιότητες μενού" + +#, fuzzy +#~ msgid "Quit" +#~ msgstr "_Τέλος" + +#, fuzzy +#~ msgid "Combine multiple paths" +#~ msgstr "Αντιγραφή επιλεγμένης εργασίας" + +#, fuzzy +#~ msgid "New View" +#~ msgstr "Νέα Προβολή" + +#, fuzzy +#~ msgid "Fill and stroke settings" +#~ msgstr "Ρυθμίσεις επιφάνειας εργασίας" + +#, fuzzy +#~ msgid "Object transformations" +#~ msgstr "Μετασχηματισμός" + +#, fuzzy +#~ msgid "Text editing and font settings" +#~ msgstr "Ρυθμίσεις επιφάνειας εργασίας" + +#, fuzzy +#~ msgid "Fill Rule" +#~ msgstr "Γέμισμα" + +#, fuzzy +#~ msgid "Tool has no options" +#~ msgstr "Επιλογές Oaf" + +#, fuzzy +#~ msgid "Visual transformation" +#~ msgstr "Μετασχηματισμός" + +#, fuzzy +#~ msgid "Show content" +#~ msgstr "Περιεχόμενο" + +# +#, fuzzy +#~ msgid "Selected object has no curve, cannot outline." +#~ msgstr "Διαγραφή επιλεγμένου αντικειμένου" + +#, fuzzy +#~ msgid "Proportion:" +#~ msgstr "Θέση" + +#, fuzzy +#~ msgid "Inkscape _Options" +#~ msgstr "Συμπαγές" + +#, fuzzy +#~ msgid "Tool Optio_ns" +#~ msgstr "Επιλογές Oaf" + +#, fuzzy +#~ msgid "gradientUnits" +#~ msgstr "Βαθμίδα" + +# +#, fuzzy +#~ msgid "nonzero" +#~ msgstr "κανένα" + +#, fuzzy +#~ msgid "End color" +#~ msgstr " χρώμα" + +#, fuzzy +#~ msgid "Make sides flat" +#~ msgstr "Πεζά/κεφαλαία διαφέρουν" + +#~ msgid "Bring to _Front" +#~ msgstr "Ανύ_ψωση" + +# # FIX?? (see above) +#~ msgid "Send to _Back" +#~ msgstr "_Βύθιση" + +#, fuzzy +#~ msgid "Document %s has unsaved changes, save them?" +#~ msgstr "Το βιβλίο %s έχει μη αποθηκευμένες αλλαγές, αποθήκευση;" + +#, fuzzy +#~ msgid "Object Size and Position" +#~ msgstr "Θέση" + +#, fuzzy +#~ msgid "Size and Position" +#~ msgstr "Θέση" + +#, fuzzy +#~ msgid "Tool attributes" +#~ msgstr "Ιδιότητες" + +#, fuzzy +#~ msgid "Proportion" +#~ msgstr "Θέση" + +# +#, fuzzy +#~ msgid "Tool has no attributes" +#~ msgstr "Ιδιότητα" + +#, fuzzy +#~ msgid "Item" +#~ msgstr "Επιλογή ένα" + +#, fuzzy +#~ msgid "Group Properties" +#~ msgstr " Ιδιότητες" + +#, fuzzy +#~ msgid "Ungroup" +#~ msgstr "_Απομαδοποίηση" + +#, fuzzy +#~ msgid "Fill settings" +#~ msgstr "Όλες οι ρυθμίσεις" + +# +#, fuzzy +#~ msgid "Break line at selected nodes" +#~ msgstr "Καθαρισμός όλων των επιλεγμένων γραμμών" + +#, fuzzy +#~ msgid "Bring to Front" +#~ msgstr "Ανύ_ψωση" + +# # FIX?? (see above) +#, fuzzy +#~ msgid "Send to Back" +#~ msgstr "_Βύθιση" + +# +#, fuzzy +#~ msgid "Lower selected objects to bottom" +#~ msgstr "Αντιγραφή επιλογής στο τεμάχιο" + +#, fuzzy +#~ msgid "Raise selected objects one position" +#~ msgstr "Αποθήκευση επιλογής" + +# +#, fuzzy +#~ msgid "Lower selected objects one position" +#~ msgstr "Αντιγραφή επιλογής στο τεμάχιο" + +#, fuzzy +#~ msgid "Draw freehand curves and straight lines" +#~ msgstr "Λαβή συρταριού" + +#, fuzzy +#~ msgid "In" +#~ msgstr "ίντσα" + +# +#, fuzzy +#~ msgid "Toggle grid" +#~ msgstr "Πλαίσιο Πίνακα" + +# +#, fuzzy +#~ msgid "Toggle guides" +#~ msgstr "Πλαίσιο Πίνακα" + +# +#~ msgid "1:1" +#~ msgstr "1:1" + +# +#~ msgid "1:2" +#~ msgstr "1:2" + +# +#~ msgid "2:1" +#~ msgstr "2:1" + +#, fuzzy +#~ msgid "Editing window properties" +#~ msgstr " Ιδιότητες" + +#, fuzzy +#~ msgid "Tool Attributes" +#~ msgstr "Ιδιότητες" + +#, fuzzy +#~ msgid "Sodipodi" +#~ msgstr "Συμπαγές" + +#, fuzzy +#~ msgid "Desktop settings" +#~ msgstr "Ρυθμίσεις επιφάνειας εργασίας" + +#, fuzzy +#~ msgid "Iso grid" +#~ msgstr "Εμφάνιση πλέγματος" + +#, fuzzy +#~ msgid "Display settings" +#~ msgstr "Εμφάνιση Σταθμών:" + +# +#, fuzzy +#~ msgid "Object style" +#~ msgstr "Αντικείμενο" + +#, fuzzy +#~ msgid "New Docked Toolbox" +#~ msgstr "Εμφάνιση _Εργαλειοθήκης" + +# +#, fuzzy +#~ msgid "Drawing Mode" +#~ msgstr "Εκτύπωση περιεχομένων πλέγματος" + +#, fuzzy +#~ msgid "Unknown item :-(" +#~ msgstr "Άγνωστο σύστημα" + +#, fuzzy +#~ msgid "Zoom in drawing" +#~ msgstr "Αλλαγή κλίμακας για _ταίριασμα" + +# +#, fuzzy +#~ msgid "Set zoom factor to 1:1" +#~ msgstr "Μεγέθυνση _1:1" + +#, fuzzy +#~ msgid "Set zoom factor to 1:2" +#~ msgstr "Κλίμακα 125%" + +#, fuzzy +#~ msgid "Set zoom factor to 2:1" +#~ msgstr "Κλίμακα 25%" + +#~ msgid "Document" +#~ msgstr "Έγγραφο" + +#, fuzzy +#~ msgid "Document variant:" +#~ msgstr "Έγγραφο" + +#, fuzzy +#~ msgid "Save document as" +#~ msgstr "Έγγραφο" + +#, fuzzy +#~ msgid "About sodipodi" +#~ msgstr "Συμπαγές" + +#, fuzzy +#~ msgid "About Sodipodi" +#~ msgstr "Συμπαγές" + +#, fuzzy +#~ msgid "The SVG ID of item" +#~ msgstr "Το Παιχνίδι της Ζωής" + +#, fuzzy +#~ msgid "The ID is not valid" +#~ msgstr "Ένα iid με τιμή NULL δεν είναι έγκυρο" + +# +#, fuzzy +#~ msgid "The ID is already defined" +#~ msgstr "To %s είναι ήδη εγκατεστημένο" + +#, fuzzy +#~ msgid "Position and size" +#~ msgstr "Θέση" + +#, fuzzy +#~ msgid "Display Properties" +#~ msgstr " Ιδιότητες" + +# +#, fuzzy +#~ msgid "Lower selected objects one level" +#~ msgstr "Διαγραφή επιλεγμένου αντικειμένου" + +# +#, fuzzy +#~ msgid "Select tool - select and transform objects" +#~ msgstr "Επιλέξτε ενέργεια" + +#, fuzzy +#~ msgid "Alignment base" +#~ msgstr "Στοίχιση" + +#, fuzzy +#~ msgid "Choose align type" +#~ msgstr "Επιλογή Τρέχουσας Συνεδρίας" + +#, fuzzy +#~ msgid "Parent X =" +#~ msgstr "Πατρική Ομάδα" + +#, fuzzy +#~ msgid "Parent Y =" +#~ msgstr "Πατρική Ομάδα" + +# +#, fuzzy +#~ msgid " Color fill " +#~ msgstr "Αρχείο core" + +# +#~ msgid " General " +#~ msgstr " Γενικά " + +# +#, fuzzy +#~ msgid "Add new gradient" +#~ msgstr "Προσθήκη νέου παροχέα" + +# +#, fuzzy +#~ msgid "Behind fill" +#~ msgstr "Δυαδικό αρχείο" + +#, fuzzy +#~ msgid "Butt endpoints" +#~ msgstr "Kουμπιά" + +#, fuzzy +#~ msgid "Choose fill color" +#~ msgstr "Επιλέξτε Πιλότου" + +#, fuzzy +#~ msgid "Choose stroke color" +#~ msgstr "Επιλογή Ειδικού Χρώματος" + +#, fuzzy +#~ msgid "Endpoints:" +#~ msgstr "σημεία" + +#, fuzzy +#~ msgid "Fill Color:" +#~ msgstr "Με Χρώμα" + +#, fuzzy +#~ msgid "Fractal fill" +#~ msgstr "Τοπικά αρχεία" + +# +#, fuzzy +#~ msgid "Pick fill color" +#~ msgstr "Διαλέξτε χρώμα" + +# +#, fuzzy +#~ msgid "Scale with object" +#~ msgstr "Αποθήκευση με περιεχόμενα" + +#~ msgid "centimeter" +#~ msgstr "εκατοστά" + +#, fuzzy +#~ msgid "millimeters" +#~ msgstr "χιλιοστά" + +#~ msgid "points" +#~ msgstr "σημεία" + +#~ msgid "1.0MB" +#~ msgstr "1.0MB" + +# +#, fuzzy +#~ msgid "Back One" +#~ msgstr "Πίσω" + +#, fuzzy +#~ msgid "Convert selected segments to curves" +#~ msgstr "Μετακίνηση επιλεγμένου μενού πρoς τα επάνω" + +# +#, fuzzy +#~ msgid "Cusp line at selected nodes" +#~ msgstr "Καθαρισμός όλων των επιλεγμένων γραμμών" + +# +#~ msgid "Desktop" +#~ msgstr "Επιφάνεια εργασίας" + +#, fuzzy +#~ msgid "Drawing Context" +#~ msgstr "Σχεδίαση" + +# +#, fuzzy +#~ msgid "Forward One" +#~ msgstr "Προώθηση" + +#, fuzzy +#~ msgid "Include one node into selected segments" +#~ msgstr "Ξε-διαγραφή των επιλεγμένων μηνυμάτων" + +#, fuzzy +#~ msgid "Join 2 selected endpoints" +#~ msgstr "Εκτύπωση επιλεγμένων επαφών" + +# +#, fuzzy +#~ msgid "Smooth line at selected nodes" +#~ msgstr "Εκκίνηση επιλεγμένου παροχέα" + +#, fuzzy +#~ msgid "Where to export" +#~ msgstr "Συγχώνευση στο πιλότο" + +#, fuzzy +#~ msgid "XML Tree" +#~ msgstr "Δένδρο" + +#, fuzzy +#~ msgid "_Align" +#~ msgstr "Στοίχιση" + +#, fuzzy +#~ msgid "Break apart selected paths" +#~ msgstr "Επανεκκίνηση επιλεγμένων αρχείων" + +# +#, fuzzy +#~ msgid "Drawing context" +#~ msgstr "Εκτύπωση περιεχομένων πλέγματος" + +#, fuzzy +#~ msgid "Edit font style of selected objects" +#~ msgstr "Διαγραφή επιλεγμένων αντικειμένων" + +# +#, fuzzy +#~ msgid "Import " +#~ msgstr "Εισαγωγή" + +# +#, fuzzy +#~ msgid "New drawing" +#~ msgstr "Νέο επίθημα:" + +#, fuzzy +#~ msgid "Nope !" +#~ msgstr "Σημειώματα GNOME!" + +# +#~ msgid "Paste from clipboard" +#~ msgstr "Επικόλληση από το τεμάχιο" + +#, fuzzy +#~ msgid "Preview print drawing" +#~ msgstr "Προεπισκόπηση δεδομένων προς εκτύπωση" + +# +#, fuzzy +#~ msgid "Rotate selected objects 90deg clockwise" +#~ msgstr "Διαγραφή επιλεγμένου αντικειμένου" + +#, fuzzy +#~ msgid "Save drawing " +#~ msgstr "Αποθήκευση τροποποιήσεων" + +#, fuzzy +#~ msgid "Yep !" +#~ msgstr " Ναι " + +#, fuzzy +#~ msgid "Align to bottom middle" +#~ msgstr "Χρώμα δεξιά ή κάτω" + +#, fuzzy +#~ msgid "Align to bottom right" +#~ msgstr "Χρώμα δεξιά ή κάτω" + +#, fuzzy +#~ msgid "Align to center" +#~ msgstr "Στοίχιση" + +#, fuzzy +#~ msgid "Align to top middle" +#~ msgstr "Εκτύπωση σε αρχείο" + +#, fuzzy +#~ msgid "Choose metric for center" +#~ msgstr "Επιλέξτε γραμματοσειρά" + +#, fuzzy +#~ msgid "Close dialog - Ctl+c" +#~ msgstr "Κλείσιμο διαλόγου" + +#, fuzzy +#~ msgid "Orig. Width: " +#~ msgstr "Πλάτος: " + +#, fuzzy +#~ msgid "Orig. X: " +#~ msgstr "" +#~ "\n" +#~ "Οργ: " + +#, fuzzy +#~ msgid "Start transformation - Ctl+a" +#~ msgstr "Μετασχηματισμός" + +#, fuzzy +#~ msgid "Toggle center given in selection/desktop coordiantes" +#~ msgstr "Σημείο βάσει των συντεταγμένων του" + +#, fuzzy +#~ msgid "Use alignment during transformation" +#~ msgstr "Πληροφορίες Συνάντησης" + +#, fuzzy +#~ msgid "Y: " +#~ msgstr "Î¥:" + +#, fuzzy +#~ msgid "keep aspect" +#~ msgstr "Διατήρηση αναλογιών" + +# +#, fuzzy +#~ msgid "select direction" +#~ msgstr "Επιλογή λεξικού" + +#, fuzzy +#~ msgid "select metric for scale" +#~ msgstr "Επιλογή τοπικών ρυθμίσεων" + +#, fuzzy +#~ msgid "select metric for values" +#~ msgstr "Επιλογή εικονιδίου για προσαρτημένο" + +#, fuzzy +#~ msgid "skew" +#~ msgstr "υποδοχή" + +# +#, fuzzy +#~ msgid "Change Attribute" +#~ msgstr "Ιδιότητα" + +#, fuzzy +#~ msgid "Change Content" +#~ msgstr "Σχεδίαση" + +#, fuzzy +#~ msgid "Do you want to delete attribute?" +#~ msgstr "Εάν θέλετε αποσφαλμάτωση των ιδιοτήτων εγγραφών" + +#, fuzzy +#~ msgid "Hierarchy" +#~ msgstr "ιεραρχία" + +#~ msgid "Key" +#~ msgstr "Πλήκτρο" + +#, fuzzy +#~ msgid "You can't delete 'id' attribute!" +#~ msgstr "Εάν θέλετε αποσφαλμάτωση των ιδιοτήτων εγγραφών" + +#, fuzzy +#~ msgid "Do you want to delete attribute %s?" +#~ msgstr "Εάν θέλετε αποσφαλμάτωση των ιδιοτήτων εγγραφών" + +# +#, fuzzy +#~ msgid "No" +#~ msgstr "Κανένα" + +#, fuzzy +#~ msgid "Do you want to delete element %s?" +#~ msgstr "Εάν θέλετε αποσφαλμάτωση των ιδιοτήτων εγγραφών" + +#~ msgid "\"" +#~ msgstr "\"" + +#, fuzzy +#~ msgid "Millimeters\n" +#~ msgstr "χιλιοστά" + +#, fuzzy +#~ msgid "Choose color for grid" +#~ msgstr "Επιλογή χρώματος οθόνης για το Abiword" + +# +#, fuzzy +#~ msgid "Pixels\n" +#~ msgstr "Εικονοστοιχεία" + +#, fuzzy +#~ msgid "Choose paper size" +#~ msgstr "Το μέγεθος σελίδας" + +# +#~ msgid "A4\n" +#~ msgstr "Διαστάσεις Α4\n" + +# +#, fuzzy +#~ msgid "Set page height" +#~ msgstr "Επιπλέον ύψος:" + +#~ msgid "window2" +#~ msgstr "window2" + +#, fuzzy +#~ msgid "Draw ellipse" +#~ msgstr "Νέα Έλλειψη" + +#, fuzzy +#~ msgid "Dup" +#~ msgstr "Τμήμ." + +#~ msgid "Could not initialize Bonobo" +#~ msgstr "Αδύνατη η αρχικοποίηση του Bonobo" diff --git a/po/es.po b/po/es.po new file mode 100644 index 000000000..27c937977 --- /dev/null +++ b/po/es.po @@ -0,0 +1,9641 @@ +# translation of es.po to +# translation of es.po to Español +# translation of Inkscape to spanish +# Copyright (C) 2000,2003, 2005 Free Software Foundation, Inc. +# Traducido por Jose Antonio Salgueiro . +# Agradecimientos: zert, softcatala, 2002-2003 +# Jose Antonio Salgueiro Aquino , 2003. +# Francisco Javier F. Serrador , 2003. +# Lucas Vieites Fariña, 2003-2005. +# +# +msgid "" +msgstr "" +"Project-Id-Version: es\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2005-12-04 11:51-0800\n" +"PO-Revision-Date: 2005-11-10 12:20+0100\n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);X-Generator: KBabel 1.10.2\n" +"X-Generator: KBabel 1.10.2\n" + +#: ../inkscape.desktop.in.h:1 +msgid "Create and edit Scalable Vector Graphics images" +msgstr "Cree y edite Gráficos Vectoriales Escalables (SVG)" + +#: ../inkscape.desktop.in.h:2 +msgid "Inkscape SVG Vector Illustrator" +msgstr "Inkscape, ilustrador vectorial SVG" + +#: ../../po/../src/arc-context.cpp:350 +msgid "" +"Ctrl: make circle or integer-ratio ellipse, snap arc/segment angle" +msgstr "" +"Ctrl: crear un círculo o elipse de proporción entera, ajustar el " +"ángulo del arco/segmento" + +#: ../../po/../src/arc-context.cpp:351 ../../po/../src/rect-context.cpp:388 +msgid "Shift: draw around the starting point" +msgstr "Mayús: dibujar alrededor del punto inicial" + +#: ../../po/../src/arc-context.cpp:413 +#: ../../po/../src/connector-context.cpp:493 +#: ../../po/../src/dyna-draw-context.cpp:506 +#: ../../po/../src/pen-context.cpp:329 ../../po/../src/pencil-context.cpp:208 +#: ../../po/../src/rect-context.cpp:452 ../../po/../src/spiral-context.cpp:421 +#: ../../po/../src/star-context.cpp:427 +msgid "Current layer is hidden. Unhide it to be able to draw on it." +msgstr "" +"La capa actual está oculta, debe estar visible para poder dibujar en " +"ella." + +#: ../../po/../src/arc-context.cpp:417 +#: ../../po/../src/connector-context.cpp:497 +#: ../../po/../src/dyna-draw-context.cpp:510 +#: ../../po/../src/pen-context.cpp:336 ../../po/../src/pencil-context.cpp:212 +#: ../../po/../src/rect-context.cpp:456 ../../po/../src/spiral-context.cpp:426 +#: ../../po/../src/star-context.cpp:431 +msgid "Current layer is locked. Unlock it to be able to draw on it." +msgstr "" +"La capa actual está bloqueada, debe desbloquearla para poder dibujar " +"en ella." + +#: ../../po/../src/arc-context.cpp:496 +#, c-format +msgid "" +"Ellipse: %s × %s; with Ctrl to make circle or integer-" +"ratio ellipse; with Shift to draw around the starting point" +msgstr "" +"Elipse: %s × %s; con Ctrl para crear círculo o elipse de " +"radio entero; con Mayús para dibujar alrededor del punto inicial" + +#: ../../po/../src/connector-context.cpp:518 +msgid "Creating new connector" +msgstr "Crear un conector nuevo" + +#: ../../po/../src/connector-context.cpp:939 +msgid "Finishing connector" +msgstr "Conector final" + +#: ../../po/../src/connector-context.cpp:1108 +msgid "Connection point: click or drag to create a new connector" +msgstr "" +"Punto de conexión: pulse o arrastre para crear un conector nuevo" + +#: ../../po/../src/connector-context.cpp:1185 +msgid "Connector endpoint: drag to reroute or connect to new shapes" +msgstr "" +"Fin de conector: arrastre para redirigir o conectar a formas nuevas" + +#: ../../po/../src/connector-context.cpp:1278 +msgid "Select at least one non-connector object." +msgstr "Seleccione por lo menos un objeto que no sea un conector." + +#: ../../po/../src/desktop-events.cpp:238 +#, c-format +msgid "%s at %s" +msgstr "%s en %s" + +# TRANSLATORS: This string appears when double-clicking on a guide. +# This is the distance by which the guide is to be moved. +#. TRANSLATORS: This string appears when double-clicking on a guide. +#. This is the distance by which the guide is to be moved. +#: ../../po/../src/desktop-events.cpp:277 +msgid " relative by " +msgstr " relativo " + +# TRANSLATORS: This string appears when double-clicking on a guide. +# This is the target location where the guide is to be moved. +#. TRANSLATORS: This string appears when double-clicking on a guide. +#. This is the target location where the guide is to be moved. +#: ../../po/../src/desktop-events.cpp:282 +#: ../../po/../src/desktop-events.cpp:395 +msgid " absolute to " +msgstr " absoluto " + +# create dialog +#. create dialog +#: ../../po/../src/desktop-events.cpp:348 +msgid "Guideline" +msgstr "Línea guía" + +#: ../../po/../src/desktop-events.cpp:432 +#, c-format +msgid "Move %s" +msgstr "Mover %s" + +#: ../../po/../src/desktop.cpp:678 +msgid "No previous zoom." +msgstr "No hay menos zoom." + +#: ../../po/../src/desktop.cpp:703 +msgid "No next zoom." +msgstr "No hay más zoom." + +#: ../../po/../src/dialogs/clonetiler.cpp:182 +msgid "Nothing selected." +msgstr "No se ha seleccionado nada." + +#: ../../po/../src/dialogs/clonetiler.cpp:188 +msgid "More than one object selected." +msgstr "Ha seleccionado más de un objeto." + +#: ../../po/../src/dialogs/clonetiler.cpp:195 +#, c-format +msgid "Object has %d tiled clones." +msgstr "El objeto tiene %d clones en mosaico." + +#: ../../po/../src/dialogs/clonetiler.cpp:200 +msgid "Object has no tiled clones." +msgstr "El objeto no tiene clones en mosaico." + +#: ../../po/../src/dialogs/clonetiler.cpp:865 +msgid "Select one object whose tiled clones to unclump." +msgstr "Seleccione un objeto cuyos clones desea desaglomerar." + +#: ../../po/../src/dialogs/clonetiler.cpp:916 +msgid "Select one object whose tiled clones to remove." +msgstr "Seleccione el objeto cuyos clones desea eliminar." + +#: ../../po/../src/dialogs/clonetiler.cpp:984 +#: ../../po/../src/selection-chemistry.cpp:1774 +msgid "Select an object to clone." +msgstr "Seleccione el objeto que desea clonar." + +#: ../../po/../src/dialogs/clonetiler.cpp:990 +#: ../../po/../src/selection-chemistry.cpp:1780 +msgid "" +"If you want to clone several objects, group them and clone the " +"group." +msgstr "" +"Si quiere clonar varios objetos, agrúpelos y clone el grupo." + +#: ../../po/../src/dialogs/clonetiler.cpp:1484 +msgid "Per row:" +msgstr "Por fila:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1497 +msgid "Per column:" +msgstr "Por columna:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1505 +msgid "Randomize:" +msgstr "Aleatorizar:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1656 +msgid "_Symmetry" +msgstr "_Simetría" + +#. TRANSLATORS: For the following 17 symmetry groups, see +#. * http://www.bib.ulb.ac.be/coursmath/doc/17.htm (visual examples); +#. * http://www.clarku.edu/~djoyce/wallpaper/seventeen.html (English vocabulary); or +#. * http://membres.lycos.fr/villemingerard/Geometri/Sym1D.htm (French vocabulary). +#. +#: ../../po/../src/dialogs/clonetiler.cpp:1664 +msgid "Select one of the 17 symmetry groups for the tiling" +msgstr "Seleccione uno de los 17 grupos de simetría para el mosaico" + +#. TRANSLATORS: "translation" means "shift" / "displacement" here. +#: ../../po/../src/dialogs/clonetiler.cpp:1675 +msgid "P1: simple translation" +msgstr "P1: traslación simple" + +#: ../../po/../src/dialogs/clonetiler.cpp:1676 +msgid "P2: 180° rotation" +msgstr "P2: rotación de 180°" + +#: ../../po/../src/dialogs/clonetiler.cpp:1677 +msgid "PM: reflection" +msgstr "PM: reflexión" + +#. TRANSLATORS: "glide reflection" is a reflection and a translation combined. +#. For more info, see http://mathforum.org/sum95/suzanne/symsusan.html +#: ../../po/../src/dialogs/clonetiler.cpp:1680 +msgid "PG: glide reflection" +msgstr "PG: reflexión por deslizamiento" + +#: ../../po/../src/dialogs/clonetiler.cpp:1681 +msgid "CM: reflection + glide reflection" +msgstr "CM: reflexión + reflexión por deslizamiento" + +#: ../../po/../src/dialogs/clonetiler.cpp:1682 +msgid "PMM: reflection + reflection" +msgstr "PMM: reflexión + reflexión" + +#: ../../po/../src/dialogs/clonetiler.cpp:1683 +msgid "PMG: reflection + 180° rotation" +msgstr "PMG: reflexión + rotación de 180°" + +#: ../../po/../src/dialogs/clonetiler.cpp:1684 +msgid "PGG: glide reflection + 180° rotation" +msgstr "PGG: reflexión por desplazamiento + rotación de 180°" + +#: ../../po/../src/dialogs/clonetiler.cpp:1685 +msgid "CMM: reflection + reflection + 180° rotation" +msgstr "CMM: reflexión + reflexión + rotación de 180°" + +#: ../../po/../src/dialogs/clonetiler.cpp:1686 +msgid "P4: 90° rotation" +msgstr "P4: rotación de 90°" + +#: ../../po/../src/dialogs/clonetiler.cpp:1687 +msgid "P4M: 90° rotation + 45° reflection" +msgstr "P4M: rotación de 90° + reflexión de 45°" + +#: ../../po/../src/dialogs/clonetiler.cpp:1688 +msgid "P4G: 90° rotation + 90° reflection" +msgstr "P4G: rotación de 90° + reflexión de 90°" + +#: ../../po/../src/dialogs/clonetiler.cpp:1689 +msgid "P3: 120° rotation" +msgstr "P3: rotación de 120°" + +#: ../../po/../src/dialogs/clonetiler.cpp:1690 +msgid "P31M: reflection + 120° rotation, dense" +msgstr "P31M: reflexión + rotación de 120°, densa" + +#: ../../po/../src/dialogs/clonetiler.cpp:1691 +msgid "P3M1: reflection + 120° rotation, sparse" +msgstr "P3M1: reflexión + rotación de 120°, escasa" + +#: ../../po/../src/dialogs/clonetiler.cpp:1692 +msgid "P6: 60° rotation" +msgstr "P6: rotación de 60°" + +#: ../../po/../src/dialogs/clonetiler.cpp:1693 +msgid "P6M: reflection + 60° rotation" +msgstr "P6M: reflexión + rotación de 60°" + +#: ../../po/../src/dialogs/clonetiler.cpp:1721 +msgid "S_hift" +msgstr "Des_plazamiento" + +# FIXME: implement averaging of all parameters for multiple selected stars +# gtk_label_set_markup (GTK_LABEL(l), _("Average:")); +# FIXME: implement averaging of all parameters for multiple selected +# gtk_label_set_markup (GTK_LABEL(l), _("Average:")); +#. TRANSLATORS: "shift" means: the tiles will be shifted (offset) horizontally by this amount +#: ../../po/../src/dialogs/clonetiler.cpp:1731 +#, no-c-format +msgid "Shift X:" +msgstr "Desplazar X:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1739 +#, no-c-format +msgid "Horizontal shift per row (in % of tile width)" +msgstr "Desplazamiento horizontal por cada fila (en % del ancho de la tesela)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1747 +#, no-c-format +msgid "Horizontal shift per column (in % of tile width)" +msgstr "" +"Desplazamiento horizontal por cada columna (en % del ancho de la tesela)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1754 +msgid "Randomize the horizontal shift by this percentage" +msgstr "Aleatorizar el desplazamiento horizontal este porcentaje" + +# FIXME: implement averaging of all parameters for multiple selected stars +# gtk_label_set_markup (GTK_LABEL(l), _("Average:")); +# FIXME: implement averaging of all parameters for multiple selected +# gtk_label_set_markup (GTK_LABEL(l), _("Average:")); +#. TRANSLATORS: "shift" means: the tiles will be shifted (offset) vertically by this amount +#: ../../po/../src/dialogs/clonetiler.cpp:1764 +#, no-c-format +msgid "Shift Y:" +msgstr "Desplazar Y:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1772 +#, no-c-format +msgid "Vertical shift per row (in % of tile height)" +msgstr "Desplazamiento vertical por cada fila (en % de la altura de la tesela)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1780 +#, no-c-format +msgid "Vertical shift per column (in % of tile height)" +msgstr "" +"Desplazamiento vertical por cada columna (en % de la altura de la tesela)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1787 +msgid "Randomize the vertical shift by this percentage" +msgstr "Aleatorizar el desplazamiento vertical este porcentaje" + +# FIXME: implement averaging of all parameters for multiple selected stars +# gtk_label_set_markup (GTK_LABEL(l), _("Average:")); +# FIXME: implement averaging of all parameters for multiple selected +# gtk_label_set_markup (GTK_LABEL(l), _("Average:")); +#: ../../po/../src/dialogs/clonetiler.cpp:1795 +msgid "Exponent:" +msgstr "Exponente:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1802 +msgid "Whether rows are spaced evenly (1), converge (<1) or diverge (>1)" +msgstr "" +"Indica si las filas mantienen su distancia (1), convergen (<1) o divergen " +"(>1)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1809 +msgid "Whether columns are spaced evenly (1), converge (<1) or diverge (>1)" +msgstr "" +"Indica si las columnas mantienen su distancia (1), convergen (<1) o divergen " +"(>1)" + +#. TRANSLATORS: "Alternate" is a verb here +#: ../../po/../src/dialogs/clonetiler.cpp:1817 +#: ../../po/../src/dialogs/clonetiler.cpp:1907 +#: ../../po/../src/dialogs/clonetiler.cpp:1966 +#: ../../po/../src/dialogs/clonetiler.cpp:2022 +#: ../../po/../src/dialogs/clonetiler.cpp:2153 +msgid "Alternate:" +msgstr "Alternar:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1823 +msgid "Alternate the sign of shifts for each row" +msgstr "Alternar el signo de los desplazamientos para cada fila" + +#: ../../po/../src/dialogs/clonetiler.cpp:1828 +msgid "Alternate the sign of shifts for each column" +msgstr "Alternar el signo de los desplazamientos para cada columna" + +#: ../../po/../src/dialogs/clonetiler.cpp:1837 +msgid "Sc_ale" +msgstr "Esc_ala" + +# FIXME: implement averaging of all parameters for multiple selected stars +# gtk_label_set_markup (GTK_LABEL(l), _("Average:")); +# FIXME: implement averaging of all parameters for multiple selected +# gtk_label_set_markup (GTK_LABEL(l), _("Average:")); +#: ../../po/../src/dialogs/clonetiler.cpp:1845 +msgid "Scale X:" +msgstr "Escalar X:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1853 +#, no-c-format +msgid "Horizontal scale per row (in % of tile width)" +msgstr "Escala horizontal por cada fila (en % del ancho de la tesela)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1861 +#, no-c-format +msgid "Horizontal scale per column (in % of tile width)" +msgstr "Escala horizontal por cada columna (en % del ancho de la tesela)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1868 +msgid "Randomize the horizontal scale by this percentage" +msgstr "Aleatorizar la escala horizontal este porcentaje" + +# FIXME: implement averaging of all parameters for multiple selected stars +# gtk_label_set_markup (GTK_LABEL(l), _("Average:")); +# FIXME: implement averaging of all parameters for multiple selected +# gtk_label_set_markup (GTK_LABEL(l), _("Average:")); +#: ../../po/../src/dialogs/clonetiler.cpp:1876 +msgid "Scale Y:" +msgstr "Escalar Y:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1884 +#, no-c-format +msgid "Vertical scale per row (in % of tile height)" +msgstr "Escala vertical por cada fila (en % de la altura de la tesela)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1892 +#, no-c-format +msgid "Vertical scale per column (in % of tile height)" +msgstr "Escala vertical por cada columna (en % de la altura de la tesela)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1899 +msgid "Randomize the vertical scale by this percentage" +msgstr "Aleatorizar la escala vertical este porcentaje" + +#: ../../po/../src/dialogs/clonetiler.cpp:1913 +msgid "Alternate the sign of scales for each row" +msgstr "Alternar el signo de la escala para cada fila" + +#: ../../po/../src/dialogs/clonetiler.cpp:1918 +msgid "Alternate the sign of scales for each column" +msgstr "Alternar el signo de la escala para cada columna" + +#: ../../po/../src/dialogs/clonetiler.cpp:1927 +msgid "_Rotation" +msgstr "_Rotación" + +# FIXME: implement averaging of all parameters for multiple selected stars +# gtk_label_set_markup (GTK_LABEL(l), _("Average:")); +# FIXME: implement averaging of all parameters for multiple selected +# gtk_label_set_markup (GTK_LABEL(l), _("Average:")); +#: ../../po/../src/dialogs/clonetiler.cpp:1935 +msgid "Angle:" +msgstr "Ángulo:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1943 +#, no-c-format +msgid "Rotate tiles by this angle for each row" +msgstr "Rotar las teselas por este ángulo para cada fila" + +#: ../../po/../src/dialogs/clonetiler.cpp:1951 +#, no-c-format +msgid "Rotate tiles by this angle for each column" +msgstr "Rotar las teselas por este ángulo para cada columna" + +#: ../../po/../src/dialogs/clonetiler.cpp:1958 +msgid "Randomize the rotation angle by this percentage" +msgstr "Aleatorizar el ángulo de rotación este porcentaje" + +#: ../../po/../src/dialogs/clonetiler.cpp:1972 +msgid "Alternate the rotation direction for each row" +msgstr "Alternar la dirección de la rotación para cada fila" + +#: ../../po/../src/dialogs/clonetiler.cpp:1977 +msgid "Alternate the rotation direction for each column" +msgstr "Alternar la dirección de la rotación para cada columna" + +#: ../../po/../src/dialogs/clonetiler.cpp:1985 +msgid "_Opacity" +msgstr "_Opacidad" + +# FIXME: implement averaging of all parameters for multiple selected stars +# gtk_label_set_markup (GTK_LABEL(l), _("Average:")); +# FIXME: implement averaging of all parameters for multiple selected +# gtk_label_set_markup (GTK_LABEL(l), _("Average:")); +#: ../../po/../src/dialogs/clonetiler.cpp:1993 +msgid "Fade out:" +msgstr "Desvanecer:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2000 +msgid "Decrease tile opacity by this percentage for each row" +msgstr "Disminuir la opacidad de la tesela este porcentaje para cada fila" + +#: ../../po/../src/dialogs/clonetiler.cpp:2007 +msgid "Decrease tile opacity by this percentage for each column" +msgstr "Disminuir la opacidad de la tesela este porcentaje para cada columna" + +#: ../../po/../src/dialogs/clonetiler.cpp:2014 +msgid "Randomize the tile opacity by this percentage" +msgstr "Aleatorizar la opacidad de la tesela este porcentaje" + +#: ../../po/../src/dialogs/clonetiler.cpp:2028 +msgid "Alternate the sign of opacity change for each row" +msgstr "Alternar el signo de los cambios de opacidad para cada fila" + +#: ../../po/../src/dialogs/clonetiler.cpp:2033 +msgid "Alternate the sign of opacity change for each column" +msgstr "Alternar el signo de los cambios de opacidad para cada columna" + +#: ../../po/../src/dialogs/clonetiler.cpp:2041 +msgid "Co_lor" +msgstr "Co_lor" + +#: ../../po/../src/dialogs/clonetiler.cpp:2046 +msgid "Initial color: " +msgstr "Color inicial: " + +#: ../../po/../src/dialogs/clonetiler.cpp:2050 +msgid "Initial color of tiled clones" +msgstr "Color inicial de los clones en mosaico" + +#: ../../po/../src/dialogs/clonetiler.cpp:2050 +msgid "" +"Initial color for clones (works only if the original has unset fill or " +"stroke)" +msgstr "" +"Color inicial para los clones (solamente funciona si el original no tiene " +"relleno o trazo)" + +#: ../../po/../src/dialogs/clonetiler.cpp:2065 +msgid "H:" +msgstr "H:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2072 +msgid "Change the tile hue by this percentage for each row" +msgstr "Cambiar el tono de la tesela este porcentaje para cada fila" + +#: ../../po/../src/dialogs/clonetiler.cpp:2079 +msgid "Change the tile hue by this percentage for each column" +msgstr "Cambiar el tono de la tesela este porcentaje para cada columna" + +#: ../../po/../src/dialogs/clonetiler.cpp:2086 +msgid "Randomize the tile hue by this percentage" +msgstr "Aleatorizar el tono de la tesela este porcentaje" + +#: ../../po/../src/dialogs/clonetiler.cpp:2095 +msgid "S:" +msgstr "S:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2102 +msgid "Change the color saturation by this percentage for each row" +msgstr "Cambiar la saturación de color este porcentaje para cada fila" + +#: ../../po/../src/dialogs/clonetiler.cpp:2109 +msgid "Change the color saturation by this percentage for each column" +msgstr "Cambiar la saturación de color este porcentaje para cada columna" + +#: ../../po/../src/dialogs/clonetiler.cpp:2116 +msgid "Randomize the color saturation by this percentage" +msgstr "Aleatorizar la saturación de color este porcentaje" + +#: ../../po/../src/dialogs/clonetiler.cpp:2124 +msgid "L:" +msgstr "L:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2131 +msgid "Change the color lightness by this percentage for each row" +msgstr "Cambiar la claridad de color este porcentaje para cada fila" + +#: ../../po/../src/dialogs/clonetiler.cpp:2138 +msgid "Change the color lightness by this percentage for each column" +msgstr "Cambiar la claridad de color este porcentaje para cada columna" + +#: ../../po/../src/dialogs/clonetiler.cpp:2145 +msgid "Randomize the color lightness by this percentage" +msgstr "Aleatorizar la claridad del color este porcentaje" + +#: ../../po/../src/dialogs/clonetiler.cpp:2159 +msgid "Alternate the sign of color changes for each row" +msgstr "Alternar el signo de los cambios de color para cada fila" + +#: ../../po/../src/dialogs/clonetiler.cpp:2164 +msgid "Alternate the sign of color changes for each column" +msgstr "Alternar el signo de los cambios de color para cada columna" + +#: ../../po/../src/dialogs/clonetiler.cpp:2172 +msgid "_Trace" +msgstr "Vec_torizar" + +#: ../../po/../src/dialogs/clonetiler.cpp:2179 +msgid "Trace the drawing under the tiles" +msgstr "Vectorizar el dibujo debajo de las teselas" + +#: ../../po/../src/dialogs/clonetiler.cpp:2183 +msgid "" +"For each clone, pick a value from the drawing in that clone's location and " +"apply it to the clone" +msgstr "" +"Para cada clon, seleccionar un valor del dibujo en la localización de ese " +"clon y aplicarlo a ese clon" + +#: ../../po/../src/dialogs/clonetiler.cpp:2197 +msgid "1. Pick from the drawing:" +msgstr "1. Seleccionar del dibujo:" + +#. ----Hbox2 +#: ../../po/../src/dialogs/clonetiler.cpp:2208 +#: ../../po/../src/dialogs/clonetiler.cpp:2355 +#: ../../po/../src/ui/dialog/tracedialog.cpp:445 +msgid "Color" +msgstr "Color" + +#: ../../po/../src/dialogs/clonetiler.cpp:2209 +msgid "Pick the visible color and opacity" +msgstr "Seleccionar el color y la opacidad visibles" + +#: ../../po/../src/dialogs/clonetiler.cpp:2216 +#: ../../po/../src/dialogs/clonetiler.cpp:2365 +#: ../share/extensions/dropshadow.inx.h:3 +msgid "Opacity" +msgstr "Opacidad" + +#: ../../po/../src/dialogs/clonetiler.cpp:2217 +msgid "Pick the total accumulated opacity" +msgstr "Seleccionar la opacidad total acumulada" + +#: ../../po/../src/dialogs/clonetiler.cpp:2224 +msgid "R" +msgstr "R" + +#: ../../po/../src/dialogs/clonetiler.cpp:2225 +msgid "Pick the Red component of the color" +msgstr "Seleccionar el componente rojo del color" + +#: ../../po/../src/dialogs/clonetiler.cpp:2232 +msgid "G" +msgstr "G" + +#: ../../po/../src/dialogs/clonetiler.cpp:2233 +msgid "Pick the Green component of the color" +msgstr "Seleccionar el componente verde del color" + +#: ../../po/../src/dialogs/clonetiler.cpp:2240 +msgid "B" +msgstr "B" + +#: ../../po/../src/dialogs/clonetiler.cpp:2241 +msgid "Pick the Blue component of the color" +msgstr "Seleccionar el componente azul del color" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2250 +msgid "clonetiler|H" +msgstr "clonetiler|H" + +#: ../../po/../src/dialogs/clonetiler.cpp:2251 +msgid "Pick the hue of the color" +msgstr "Seleccionar el tono del color" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2260 +msgid "clonetiler|S" +msgstr "clonetiler|S" + +#: ../../po/../src/dialogs/clonetiler.cpp:2261 +msgid "Pick the saturation of the color" +msgstr "Seleccionar la saturación del color" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2270 +msgid "clonetiler|L" +msgstr "clonetiler|L" + +#: ../../po/../src/dialogs/clonetiler.cpp:2271 +msgid "Pick the lightness of the color" +msgstr "Seleccionar la claridad del color" + +#: ../../po/../src/dialogs/clonetiler.cpp:2281 +msgid "2. Tweak the picked value:" +msgstr "2. Ajustar el valor seleccionado" + +#: ../../po/../src/dialogs/clonetiler.cpp:2291 +msgid "Gamma-correct:" +msgstr "Corrección de gamma:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2296 +msgid "Shift the mid-range of the picked value upwards (>0) or downwards (<0)" +msgstr "" +"Mover el rango medio del valor seleccionado hacia arriba (>0) o hacia abajo " +"(<0)" + +#: ../../po/../src/dialogs/clonetiler.cpp:2303 +msgid "Randomize:" +msgstr "Aleatorizar:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2308 +msgid "Randomize the picked value by this percentage" +msgstr "Aleatorizar el valor seleccionado este porcentaje" + +#: ../../po/../src/dialogs/clonetiler.cpp:2315 +msgid "Invert:" +msgstr "Invertir:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2319 +msgid "Invert the picked value" +msgstr "Invertir el valor seleccionado" + +#: ../../po/../src/dialogs/clonetiler.cpp:2325 +msgid "3. Apply the value to the clones':" +msgstr "3. Aplicar el valor a esta característica de los clones:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2335 +msgid "Presence" +msgstr "Presencia" + +#: ../../po/../src/dialogs/clonetiler.cpp:2338 +msgid "" +"Each clone is created with the probability determined by the picked value in " +"that point" +msgstr "" +"Se crea a cada clon con la probabilidad determinada por el valor " +"seleccionado en ese punto" + +#: ../../po/../src/dialogs/clonetiler.cpp:2345 +msgid "Size" +msgstr "Tamaño" + +#: ../../po/../src/dialogs/clonetiler.cpp:2348 +msgid "Each clone's size is determined by the picked value in that point" +msgstr "" +"Se determina el tamaño de cada clon por el valor seleccionado en ese punto" + +#: ../../po/../src/dialogs/clonetiler.cpp:2358 +msgid "" +"Each clone is painted by the picked color (the original must have unset fill " +"or stroke)" +msgstr "" +"Se pinta cada clon con el color seleccionado (el original debe carecer de " +"relleno y borde)" + +#: ../../po/../src/dialogs/clonetiler.cpp:2368 +msgid "Each clone's opacity is determined by the picked value in that point" +msgstr "" +"Se determina la opacidad de cada clon por el valor seleccionado en ese punto" + +#: ../../po/../src/dialogs/clonetiler.cpp:2395 +msgid "How many rows in the tiling" +msgstr "La cantidad de filas en el mosaico" + +#: ../../po/../src/dialogs/clonetiler.cpp:2415 +msgid "How many columns in the tiling" +msgstr "La cantidad de columnas en el mosaico" + +#: ../../po/../src/dialogs/clonetiler.cpp:2445 +msgid "Width of the rectangle to be filled" +msgstr "Anchura del rectángulo que se rellenará" + +#: ../../po/../src/dialogs/clonetiler.cpp:2470 +msgid "Height of the rectangle to be filled" +msgstr "Altura del rectángulo que se rellenará" + +#: ../../po/../src/dialogs/clonetiler.cpp:2485 +msgid "Rows, columns: " +msgstr "Filas, columnas: " + +#: ../../po/../src/dialogs/clonetiler.cpp:2486 +msgid "Create the specified number of rows and columns" +msgstr "Crear el número de filas y columnas indicado" + +#: ../../po/../src/dialogs/clonetiler.cpp:2495 +msgid "Width, height: " +msgstr "Altura, anchura: " + +#: ../../po/../src/dialogs/clonetiler.cpp:2496 +msgid "Fill the specified width and height with the tiling" +msgstr "Rellenar la anchura y altura indicada con las teselas" + +#: ../../po/../src/dialogs/clonetiler.cpp:2512 +msgid "Use saved size and position of the tile" +msgstr "Usar el tamaño y posición de la tesela previamente guardados" + +#: ../../po/../src/dialogs/clonetiler.cpp:2515 +msgid "" +"Pretend that the size and position of the tile are the same as the last time " +"you tiled it (if any), instead of using the current size" +msgstr "" +"Simular que el tamaño y la posición de la tesela son los mismos que la " +"última vez que lo usó (en su caso), en vez de usar el tamaño actual" + +# FIXME: implement averaging of all parameters for multiple selected stars +# gtk_label_set_markup (GTK_LABEL(l), _("Average:")); +# FIXME: implement averaging of all parameters for multiple selected +# gtk_label_set_markup (GTK_LABEL(l), _("Average:")); +#: ../../po/../src/dialogs/clonetiler.cpp:2539 +msgid " _Create " +msgstr " _Crear " + +#: ../../po/../src/dialogs/clonetiler.cpp:2541 +msgid "Create and tile the clones of the selection" +msgstr "Crear y colocar los clones de la selección" + +#. TRANSLATORS: if a group of objects are "clumped" together, then they +#. are unevenly spread in the given amount of space - as shown in the +#. diagrams on the left in the following screenshot: +#. http://www.inkscape.org/screenshots/gallery/inkscape-0.42-CVS-tiles-unclump.png +#. So unclumping is the process of spreading a number of objects out more evenly. +#: ../../po/../src/dialogs/clonetiler.cpp:2556 +msgid " _Unclump " +msgstr " Desa_aglomerar " + +#: ../../po/../src/dialogs/clonetiler.cpp:2557 +msgid "Spread out clones to reduce clumping; can be applied repeatedly" +msgstr "" +"Esparcir los clones para reducir la aglomeración; se puede aplicar " +"repetidamente" + +#: ../../po/../src/dialogs/clonetiler.cpp:2563 +msgid " Re_move " +msgstr " El_minar " + +#: ../../po/../src/dialogs/clonetiler.cpp:2564 +msgid "Remove existing tiled clones of the selected object (siblings only)" +msgstr "Eliminar las teselas clonadas del objeto seleccionado (solo hermanos)" + +#: ../../po/../src/dialogs/clonetiler.cpp:2580 +msgid " R_eset " +msgstr " R_reiniciar " + +#. TRANSLATORS: "change" is a noun here +#: ../../po/../src/dialogs/clonetiler.cpp:2582 +msgid "" +"Reset all shifts, scales, rotates, opacity and color changes in the dialog " +"to zero" +msgstr "" +"Reiniciar todos los cambios de movimiento, escala, rotación, opacidad y " +"color del diálogo a cero" + +#: ../../po/../src/dialogs/color-picker.cpp:280 +msgid "Close" +msgstr "Cerrar" + +#: ../../po/../src/dialogs/debugdialog.cpp:138 +msgid "Messages" +msgstr "Mensajes" + +#. ## Add a menu for clear() +#: ../../po/../src/dialogs/debugdialog.cpp:144 +#: ../../po/../src/menus-skeleton.h:16 +#: ../../po/../src/ui/dialog/messages.cpp:56 +#: ../../po/../src/ui/dialog/scriptdialog.cpp:181 +msgid "_File" +msgstr "_Archivo" + +#. TRANSLATORS: "Clear" is a verb here +#: ../../po/../src/dialogs/debugdialog.cpp:145 +#: ../../po/../src/dialogs/find.cpp:753 +#: ../../po/../src/ui/dialog/messages.cpp:57 +#: ../../po/../src/ui/dialog/scriptdialog.cpp:182 +msgid "_Clear" +msgstr "_Limpiar" + +#: ../../po/../src/dialogs/debugdialog.cpp:147 +#: ../../po/../src/ui/dialog/messages.cpp:59 +msgid "Capture log messages" +msgstr "Capturar los mensajes de registro" + +#: ../../po/../src/dialogs/debugdialog.cpp:149 +#: ../../po/../src/ui/dialog/messages.cpp:61 +msgid "Release log messages" +msgstr "Dejar de capturar los mensajes de registro" + +#. Notebook tab +#: ../../po/../src/dialogs/desktop-properties.cpp:909 +#: ../../po/../src/ui/dialog/document-preferences.cpp:89 +#: ../../po/../src/ui/widget/panel.cpp:107 +msgid "Grid" +msgstr "Rejilla" + +#. Checkbuttons +#. / \todo FIXME: gray out snapping when grid is off +#. / \todo FIXME: gray out snapping when grid is off. +#. / Dissenting view: you want snapping without grid. +#: ../../po/../src/dialogs/desktop-properties.cpp:917 +#: ../../po/../src/ui/dialog/document-preferences.cpp:179 +msgid "Show grid" +msgstr "Mostrar la rejilla" + +#: ../../po/../src/dialogs/desktop-properties.cpp:917 +#: ../../po/../src/ui/dialog/document-preferences.cpp:179 +#: ../../po/../src/verbs.cpp:2115 +msgid "Show or hide grid" +msgstr "Mostrar/ocultar la rejilla" + +#: ../../po/../src/dialogs/desktop-properties.cpp:918 +#: ../../po/../src/ui/dialog/document-preferences.cpp:180 +msgid "Snap bounding boxes to grid" +msgstr "Ajustar cajas de contorno a la rejilla" + +#: ../../po/../src/dialogs/desktop-properties.cpp:918 +#: ../../po/../src/dialogs/desktop-properties.cpp:1001 +#: ../../po/../src/ui/dialog/document-preferences.cpp:181 +#: ../../po/../src/ui/dialog/document-preferences.cpp:236 +msgid "Snap the edges of the object bounding boxes" +msgstr "Ajustar los bordes de las cajas de contorno de los objetos" + +#: ../../po/../src/dialogs/desktop-properties.cpp:919 +#: ../../po/../src/ui/dialog/document-preferences.cpp:183 +msgid "Snap nodes to grid" +msgstr "Ajustar los nodos a la rejilla" + +#: ../../po/../src/dialogs/desktop-properties.cpp:919 +#: ../../po/../src/dialogs/desktop-properties.cpp:1002 +#: ../../po/../src/ui/dialog/document-preferences.cpp:184 +#: ../../po/../src/ui/dialog/document-preferences.cpp:239 +msgid "Snap path nodes, text baselines, ellipse centers, etc." +msgstr "" +"Ajustar los nodos de los trazos, las líneas de base de los textos, los " +"centros de las elipses, etc." + +#: ../../po/../src/dialogs/desktop-properties.cpp:937 +#: ../../po/../src/ui/dialog/document-preferences.cpp:186 +msgid "Grid units:" +msgstr "Unidades de la rejilla:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:939 +#: ../../po/../src/ui/dialog/document-preferences.cpp:187 +msgid "Origin X:" +msgstr "Origen X:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:942 +#: ../../po/../src/ui/dialog/document-preferences.cpp:189 +msgid "Origin Y:" +msgstr "Origen Y:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:945 +#: ../../po/../src/ui/dialog/document-preferences.cpp:191 +msgid "Spacing X:" +msgstr "Espaciado X:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:948 +#: ../../po/../src/ui/dialog/document-preferences.cpp:193 +msgid "Spacing Y:" +msgstr "Espaciado Y:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:952 +#: ../../po/../src/dialogs/desktop-properties.cpp:1013 +#: ../../po/../src/ui/dialog/document-preferences.cpp:195 +#: ../../po/../src/ui/dialog/document-preferences.cpp:241 +msgid "Snap units:" +msgstr "Unidades para el ajuste:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:955 +#: ../../po/../src/dialogs/desktop-properties.cpp:1016 +#: ../../po/../src/ui/dialog/document-preferences.cpp:196 +#: ../../po/../src/ui/dialog/document-preferences.cpp:242 +msgid "Snap distance:" +msgstr "Distancia de ajuste:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:958 +#: ../../po/../src/ui/dialog/document-preferences.cpp:199 +msgid "Grid line color:" +msgstr "Color de la rejilla:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:959 +#: ../../po/../src/ui/dialog/document-preferences.cpp:199 +msgid "Grid line color" +msgstr "Color de la rejilla" + +#: ../../po/../src/dialogs/desktop-properties.cpp:959 +#: ../../po/../src/ui/dialog/document-preferences.cpp:200 +msgid "Color of grid lines" +msgstr "Color de las líneas de la rejilla" + +#: ../../po/../src/dialogs/desktop-properties.cpp:961 +#: ../../po/../src/ui/dialog/document-preferences.cpp:201 +msgid "Major grid line color:" +msgstr "Color de las líneas primarias:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:962 +#: ../../po/../src/ui/dialog/document-preferences.cpp:201 +msgid "Major grid line color" +msgstr "Color de las líneas primarias de la rejilla" + +#: ../../po/../src/dialogs/desktop-properties.cpp:962 +#: ../../po/../src/ui/dialog/document-preferences.cpp:202 +msgid "Color of the major (highlighted) grid lines" +msgstr "Color de las líneas primarias (resaltadas) de la rejilla" + +#: ../../po/../src/dialogs/desktop-properties.cpp:965 +#: ../../po/../src/ui/dialog/document-preferences.cpp:204 +msgid "Major grid line every:" +msgstr "Línea primaria cada:" + +#. TRANSLATORS: This belongs to the "Major grid line every:" string, +#. see grid settings in the "Document Preferences" dialog +#: ../../po/../src/dialogs/desktop-properties.cpp:977 +#: ../../po/../src/ui/dialog/document-preferences.cpp:204 +msgid "lines" +msgstr "líneas" + +#. Guidelines page +#: ../../po/../src/dialogs/desktop-properties.cpp:991 +#: ../../po/../src/ui/dialog/document-preferences.cpp:90 +msgid "Guides" +msgstr "Guías" + +#. / \todo FIXME: gray out snapping when guides are off +#. / Dissenting view: you want snapping without guides. +#: ../../po/../src/dialogs/desktop-properties.cpp:1000 +#: ../../po/../src/ui/dialog/document-preferences.cpp:234 +msgid "Show guides" +msgstr "Mostrar las guías" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1000 +#: ../../po/../src/ui/dialog/document-preferences.cpp:234 +#: ../../po/../src/verbs.cpp:2116 +msgid "Show or hide guides" +msgstr "Mostrar/ocultar las guías" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1001 +#: ../../po/../src/ui/dialog/document-preferences.cpp:235 +msgid "Snap bounding boxes to guides" +msgstr "Ajustar las cajas de contorno a las guías" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1002 +#: ../../po/../src/ui/dialog/document-preferences.cpp:238 +msgid "Snap points to guides" +msgstr "Ajustar los puntos a las guías" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1020 +#: ../../po/../src/ui/dialog/document-preferences.cpp:243 +msgid "Guide color:" +msgstr "Color de la guía:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1021 +#: ../../po/../src/ui/dialog/document-preferences.cpp:243 +msgid "Guideline color" +msgstr "Color de las líneas guía" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1021 +#: ../../po/../src/ui/dialog/document-preferences.cpp:244 +msgid "Color of guidelines" +msgstr "Color de las líneas guía" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1023 +#: ../../po/../src/ui/dialog/document-preferences.cpp:245 +msgid "Highlight color:" +msgstr "Color del resaltado:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1024 +#: ../../po/../src/ui/dialog/document-preferences.cpp:245 +msgid "Highlighted guideline color" +msgstr "Color de resaltado de las líneas guías" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1024 +#: ../../po/../src/ui/dialog/document-preferences.cpp:246 +msgid "Color of a guideline when it is under mouse" +msgstr "Color de la guía cuando está debajo del ratón" + +#. Page page +#: ../../po/../src/dialogs/desktop-properties.cpp:1029 +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:855 +#: ../../po/../src/ui/dialog/document-preferences.cpp:88 +#: ../../po/../src/widgets/desktop-widget.cpp:1061 +msgid "Page" +msgstr "Página" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1039 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +msgid "Background:" +msgstr "Color de fondo:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1040 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +msgid "Background color" +msgstr "Color de fondo" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1041 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +msgid "" +"Color and transparency of the page background (also used for bitmap export)" +msgstr "" +"Color y transparencia del fondo de la página (también se utiliza para la " +"exportación a mapa de bits)" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1045 +#: ../../po/../src/ui/dialog/document-preferences.cpp:147 +#, fuzzy +msgid "Show page border" +msgstr "Mostrar borde del papel" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1049 +#: ../../po/../src/ui/dialog/document-preferences.cpp:148 +msgid "Border on top of drawing" +msgstr "Borde encima del dibujo" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1052 +#: ../../po/../src/ui/dialog/document-preferences.cpp:149 +msgid "Border color:" +msgstr "Color del borde:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1053 +#: ../../po/../src/ui/dialog/document-preferences.cpp:149 +#, fuzzy +msgid "Page border color" +msgstr "Color de borde del papel" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1054 +#: ../../po/../src/ui/dialog/document-preferences.cpp:150 +#, fuzzy +msgid "Color of the page border" +msgstr "Color del borde del papel" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1059 +#: ../../po/../src/ui/dialog/document-preferences.cpp:152 +msgid "Show page shadow" +msgstr "Mostrar sombra del papel" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1063 +#: ../../po/../src/ui/dialog/document-preferences.cpp:153 +msgid "Default units:" +msgstr "Unidades predet.:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1069 +msgid "Units for the tool controls, ruler, and the statusbar" +msgstr "" +"Unidades para los controles de herramientas, regla y la barra de estado" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1086 +#: ../../po/../src/ui/widget/page-sizer.cpp:209 +#, fuzzy +msgid "Page size:" +msgstr "Tamaño del papel:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1110 +#: ../../po/../src/ui/widget/page-sizer.cpp:219 +msgid "Custom" +msgstr "Personalizar" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1121 +#: ../../po/../src/ui/widget/page-sizer.cpp:225 +#, fuzzy +msgid "Page orientation:" +msgstr "Orientación del papel:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1133 +#: ../../po/../src/ui/widget/page-sizer.cpp:232 +msgid "Landscape" +msgstr "Horizontal" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1139 +#: ../../po/../src/ui/widget/page-sizer.cpp:234 +msgid "Portrait" +msgstr "Vertical" + +#. Custom paper frame +#: ../../po/../src/dialogs/desktop-properties.cpp:1148 +#: ../../po/../src/ui/widget/page-sizer.cpp:249 +#, fuzzy +msgid "Custom size" +msgstr "Personalizar" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1160 +#: ../../po/../src/dialogs/export.cpp:269 +#: ../../po/../src/ui/widget/page-sizer.cpp:261 +msgid "Units:" +msgstr "Unidades:" + +#. Stroke width +#: ../../po/../src/dialogs/desktop-properties.cpp:1162 +#: ../../po/../src/dialogs/export.cpp:310 +#: ../../po/../src/dialogs/object-attributes.cpp:55 +#: ../../po/../src/dialogs/stroke-style.cpp:985 +#: ../../po/../src/ui/widget/page-sizer.cpp:262 +#: ../../po/../src/widgets/toolbox.cpp:1957 +msgid "Width:" +msgstr "Ancho:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1183 +#: ../../po/../src/dialogs/export.cpp:326 +#: ../../po/../src/dialogs/export.cpp:431 +#: ../../po/../src/dialogs/object-attributes.cpp:56 +#: ../../po/../src/ui/widget/page-sizer.cpp:263 +msgid "Height:" +msgstr "Alto:" + +#. +#. * Ownership metadata tab +#. +#: ../../po/../src/dialogs/desktop-properties.cpp:1206 +msgid "Metadata" +msgstr "Metadatos" + +#. add license selector pull-down +#: ../../po/../src/dialogs/desktop-properties.cpp:1225 +msgid "License" +msgstr "Licencia" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1255 +msgid "Proprietary" +msgstr "Propietaria" + +#: ../../po/../src/dialogs/display-settings.cpp:212 +msgid "When transforming, show:" +msgstr "Al transformar mostrar:" + +#: ../../po/../src/dialogs/display-settings.cpp:223 +msgid "Objects" +msgstr "Objetos" + +#: ../../po/../src/dialogs/display-settings.cpp:224 +msgid "Show the actual objects when moving or transforming" +msgstr "Mostrar los objetos al mover o transformar" + +#: ../../po/../src/dialogs/display-settings.cpp:231 +msgid "Box outline" +msgstr "Caja de contorno" + +#: ../../po/../src/dialogs/display-settings.cpp:232 +msgid "Show only a box outline of the objects when moving or transforming" +msgstr "" +"Solamente mostrar una caja de contorno del objeto al mover o transformar" + +#: ../../po/../src/dialogs/display-settings.cpp:238 +msgid "Per-object selection cue:" +msgstr "Marca de de selección por cada objeto:" + +#. sorationsnapsperpi == 0 means no snapping +#: ../../po/../src/dialogs/display-settings.cpp:249 +#: ../../po/../src/dialogs/display-settings.cpp:386 +#: ../../po/../src/dialogs/display-settings.cpp:441 +#: ../../po/../src/dialogs/display-settings.cpp:1482 +#: ../../po/../src/dialogs/stroke-style.cpp:791 +#: ../../po/../src/interface.cpp:741 +#: ../../po/../src/ui/widget/selected-style.cpp:100 +#: ../../po/../src/verbs.cpp:1842 +msgid "None" +msgstr "Ninguno" + +#: ../../po/../src/dialogs/display-settings.cpp:250 +msgid "No per-object selection indication" +msgstr "Sin indicación de selección por objeto" + +#: ../../po/../src/dialogs/display-settings.cpp:256 +msgid "Mark" +msgstr "Marca" + +#: ../../po/../src/dialogs/display-settings.cpp:257 +msgid "Each selected object has a diamond mark in the top left corner" +msgstr "" +"Cada objeto seleccionado tiene una marca en forma de rombo en su esquina " +"superior izquierda" + +#: ../../po/../src/dialogs/display-settings.cpp:264 +msgid "Box" +msgstr "Caja" + +#: ../../po/../src/dialogs/display-settings.cpp:265 +msgid "Each selected object displays its bounding box" +msgstr "Cada objeto seleccionado muestra su caja de contorno" + +#: ../../po/../src/dialogs/display-settings.cpp:270 +msgid "Default scale origin:" +msgstr "Origen de escalado predeterminado:" + +#: ../../po/../src/dialogs/display-settings.cpp:281 +msgid "Opposite bounding box edge" +msgstr "Borde opuesto de la caja del contorno" + +#: ../../po/../src/dialogs/display-settings.cpp:282 +msgid "Default scale origin will be on the bounding box of the item" +msgstr "" +"El origen de predeterminado del escalado estará en la caja de controno del " +"elemento" + +#: ../../po/../src/dialogs/display-settings.cpp:288 +msgid "Farthest opposite node" +msgstr "Nodo opuesto más lejano" + +#: ../../po/../src/dialogs/display-settings.cpp:289 +msgid "Default scale origin will be on the bounding box of the item's points" +msgstr "" +"El origen predeterminado del escalado estará en la caja de contorno de los " +"puntos del elemento" + +#: ../../po/../src/dialogs/display-settings.cpp:341 +msgid "degrees" +msgstr "grados" + +#: ../../po/../src/dialogs/display-settings.cpp:350 +msgid "" +"Rotating with Ctrl pressed snaps every that much degrees; also, pressing " +"[ or ] rotates by this amount" +msgstr "" +"Rotar con Ctrl pulsado ajusta cada tantos grados; pulsando «[» ó «]» también " +"rota esta cantidad." + +#: ../../po/../src/dialogs/display-settings.cpp:407 +msgid "Rotation snaps every:" +msgstr "Rotación se ajusta cada:" + +#: ../../po/../src/dialogs/display-settings.cpp:430 +msgid "" +"None: dialogs are treated as regular windows; Normal: dialogs stay on top of " +"document windows; Aggressive: same as Normal but may work better with some " +"window managers." +msgstr "" +"Ninguno: se trata a los diálogos como ventanas normales; Normal: los " +"diálogos permanecen encima de las ventanas de documento; Agresivo: igual que " +"Normal pero puede funcionar mejor con algunos gestores de ventanas." + +#: ../../po/../src/dialogs/display-settings.cpp:451 +msgid "Normal" +msgstr "Normal" + +#: ../../po/../src/dialogs/display-settings.cpp:461 +msgid "Aggressive" +msgstr "Agresivo" + +#: ../../po/../src/dialogs/display-settings.cpp:475 +msgid "Dialogs on top:" +msgstr "Diálogos encima:" + +#: ../../po/../src/dialogs/display-settings.cpp:645 +msgid "Show selection cue" +msgstr "Mostrar marca de selección" + +#: ../../po/../src/dialogs/display-settings.cpp:646 +msgid "" +"Whether selected objects display a selection cue (the same as in selector)" +msgstr "" +"Indica si los objetos seleccionados muestran una marca de selección (igual " +"que en el selector)" + +#: ../../po/../src/dialogs/display-settings.cpp:657 +msgid "Enable gradient editing" +msgstr "Activar edición de gradientes" + +#: ../../po/../src/dialogs/display-settings.cpp:658 +msgid "Whether selected objects display gradient editing controls" +msgstr "" +"Indica si los objetos seleccionados muestran los controles de edición de " +"gradientes" + +#: ../../po/../src/dialogs/display-settings.cpp:719 +msgid "No objects selected to take the style from." +msgstr "No se han seleccionado objetos de los que tomar el estilo." + +#: ../../po/../src/dialogs/display-settings.cpp:728 +msgid "" +"More than one object selected. Cannot take style from multiple " +"objects." +msgstr "" +"Ha seleccionado más de un objeto. No se puede tomar el estilo de " +"varios objetos." + +#: ../../po/../src/dialogs/display-settings.cpp:767 +msgid "Create new objects with:" +msgstr "Crear objetos nuevos con:" + +#: ../../po/../src/dialogs/display-settings.cpp:777 +msgid "Take from selection" +msgstr "Tomar de la selección" + +#: ../../po/../src/dialogs/display-settings.cpp:778 +msgid "Remember the style of the (first) selected object as this tool's style" +msgstr "" +"Recordar el estilo del (primer) objeto seleccionado como el estilo de esta " +"herramienta" + +#: ../../po/../src/dialogs/display-settings.cpp:782 +#, fuzzy +msgid "Last used style" +msgstr "Pegar e_stilo" + +#: ../../po/../src/dialogs/display-settings.cpp:782 +msgid "Apply the style you last set on an object" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:790 +msgid "This tool's own style:" +msgstr "El estilo propio de esta herramienta:" + +#: ../../po/../src/dialogs/display-settings.cpp:790 +msgid "" +"Each tool may store its own style to apply to the newly created objects. Use " +"the button below to set it." +msgstr "" +"Cada herramienta puede guardar su propio estilo para aplicarlo a los nuevos " +"objetos creados. Utilice el botón inferior para ajustarlo." + +#. Mouse +#: ../../po/../src/dialogs/display-settings.cpp:877 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:55 +msgid "Mouse" +msgstr "Ratón" + +#. TRANSLATORS: "Grab" is a noun here. "Grab sensitivity" is intended to mean how +#. * close on the screen you need to be to an object to be able to grab it with mouse (in +#. * pixels). +#: ../../po/../src/dialogs/display-settings.cpp:883 +msgid "Grab sensitivity:" +msgstr "Sensibilidad de agarre:" + +#: ../../po/../src/dialogs/display-settings.cpp:884 +msgid "" +"How close on the screen you need to be to an object to be able to grab it " +"with mouse (in screen pixels)" +msgstr "" +"Lo cerca que hay que estar de un objeto en pantalla para poder agarrarlo con " +"el ratón (en píxeles de pantalla)" + +#: ../../po/../src/dialogs/display-settings.cpp:885 +#: ../../po/../src/dialogs/display-settings.cpp:897 +#: ../../po/../src/dialogs/display-settings.cpp:912 +#: ../../po/../src/dialogs/display-settings.cpp:930 +#: ../../po/../src/dialogs/display-settings.cpp:970 +msgid "pixels" +msgstr "píxeles" + +#: ../../po/../src/dialogs/display-settings.cpp:895 +msgid "Click/drag threshold:" +msgstr "Umbral de clic/arrastre:" + +#: ../../po/../src/dialogs/display-settings.cpp:896 +msgid "" +"Maximum mouse drag (in screen pixels) which is considered a click, not a drag" +msgstr "" +"Arrastre máximo de ratón (en píxeles) que se considera un clic y no un " +"arrastre" + +#. Scrolling +#: ../../po/../src/dialogs/display-settings.cpp:907 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:56 +msgid "Scrolling" +msgstr "Desplazamiento" + +#: ../../po/../src/dialogs/display-settings.cpp:910 +msgid "Mouse wheel scrolls by:" +msgstr "La rueda del ratón desplaza:" + +#: ../../po/../src/dialogs/display-settings.cpp:911 +msgid "" +"One mouse wheel notch scrolls by this distance in screen pixels " +"(horizontally with Shift)" +msgstr "" +"Un punto de la rueda desplaza esta distancia en píxeles (en horizontal con " +"Mayús)" + +#: ../../po/../src/dialogs/display-settings.cpp:920 +msgid "Ctrl+arrows" +msgstr "Ctrl+flechas" + +#: ../../po/../src/dialogs/display-settings.cpp:928 +msgid "Scroll by:" +msgstr "Desplazar:" + +#: ../../po/../src/dialogs/display-settings.cpp:929 +msgid "Pressing Ctrl+arrow key scrolls by this distance (in screen pixels)" +msgstr "" +"Pulsación de Ctrl+flecha desplaza esta distancia (en píxeles de pantalla)" + +#: ../../po/../src/dialogs/display-settings.cpp:939 +msgid "Acceleration:" +msgstr "Aceleración:" + +#: ../../po/../src/dialogs/display-settings.cpp:940 +msgid "" +"Pressing and holding Ctrl+arrow will gradually speed up scrolling (0 for no " +"acceleration)" +msgstr "" +"Al mantener pulsado Ctrl+flecha gradualmente de incrementará la velocidad de " +"desplazamiento (0 = sin aceleración)" + +#: ../../po/../src/dialogs/display-settings.cpp:949 +msgid "Autoscrolling" +msgstr "Autodesplazamiento" + +#: ../../po/../src/dialogs/display-settings.cpp:957 +msgid "Speed:" +msgstr "Velocidad:" + +#: ../../po/../src/dialogs/display-settings.cpp:958 +msgid "" +"How fast the canvas autoscrolls when you drag beyond canvas edge (0 to turn " +"autoscroll off)" +msgstr "" +"La velocidad con la que el lienzo se desplaza cuando arrastra más allá del " +"borde (0 desactiva el autodesplazamiento)" + +#: ../../po/../src/dialogs/display-settings.cpp:968 +#: ../../po/../src/ui/dialog/tracedialog.cpp:357 +#: ../../po/../src/ui/dialog/tracedialog.cpp:390 +msgid "Threshold:" +msgstr "Umbral:" + +#: ../../po/../src/dialogs/display-settings.cpp:969 +msgid "" +"How far (in screen pixels) you need to be from the canvas edge to trigger " +"autoscroll; positive is outside the canvas, negative is within the canvas" +msgstr "" +"La distancia (en píxeles de pantalla) a la que hay que estar del borde del " +"lienzo para activar el autodesplazamiento; positivo es fuera del lienzo, " +"negativo es dentro del lienzo" + +#. Steps +#: ../../po/../src/dialogs/display-settings.cpp:979 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:57 +msgid "Steps" +msgstr "Pasos" + +#: ../../po/../src/dialogs/display-settings.cpp:982 +msgid "Arrow keys move by:" +msgstr "Las flechas mueven:" + +#: ../../po/../src/dialogs/display-settings.cpp:983 +msgid "" +"Pressing an arrow key moves selected object(s) or node(s) by this distance " +"(in px units)" +msgstr "" +"Al pulsar una tecla de flecha los objetos o nodos se mueven esta distancia " +"(en unidades px)." + +#: ../../po/../src/dialogs/display-settings.cpp:984 +#: ../../po/../src/dialogs/display-settings.cpp:995 +#: ../../po/../src/dialogs/display-settings.cpp:1006 +#: ../../po/../src/helper/units.cpp:42 +msgid "px" +msgstr "px" + +#: ../../po/../src/dialogs/display-settings.cpp:993 +msgid "> and < scale by:" +msgstr "> y < escalan:" + +#: ../../po/../src/dialogs/display-settings.cpp:994 +msgid "" +"Pressing > or < scales selection up or down by this increment (in px units)" +msgstr "" +"Al pulsar > ó < se aumenta o disminuye la selección en esta cantidad (en " +"unidades px)" + +#: ../../po/../src/dialogs/display-settings.cpp:1004 +msgid "Inset/Outset by:" +msgstr "Reducir/ampliar:" + +#: ../../po/../src/dialogs/display-settings.cpp:1005 +msgid "" +"Inset and Outset commands displace the path by this distance (in px units)" +msgstr "" +"Los comandos «Reducir» y «Ampliar» desplazan el trazo esta distancia (en " +"unidades px)" + +#: ../../po/../src/dialogs/display-settings.cpp:1017 +msgid "Compass-like display of angles" +msgstr "Mostrar los ángulos como en una brújula" + +#. TRANSLATORS: "positive clockwise" means "increasing in clockwise direction" +#: ../../po/../src/dialogs/display-settings.cpp:1019 +msgid "" +"When on, angles are displayed with 0 at north, 0 to 360 range, positive " +"clockwise; otherwise with 0 at east, -180 to 180 range, positive " +"counterclockwise" +msgstr "" +"Si está activo se muestran los ángulos de modo que 0 es el norte, desde 0 a " +"360, positivo hacia la derecha, de lo contrario el 0 está en oeste, con " +"rango de -180 hasta 180, positivo hacia la izquierda" + +#: ../../po/../src/dialogs/display-settings.cpp:1026 +msgid "Zoom in/out by:" +msgstr "Alejar/acercar:" + +#: ../../po/../src/dialogs/display-settings.cpp:1027 +msgid "" +"Zoom tool click, +/- keys, and middle click zoom in and out by this " +"multiplier" +msgstr "" +"Un clic de la herramienta Zoom, teclas +/-, y clic central amplían y reducen " +"por este múltiplo." + +#: ../../po/../src/dialogs/display-settings.cpp:1028 +#: ../../po/../src/helper/units.cpp:44 +msgid "%" +msgstr "%" + +#. Tools +#: ../../po/../src/dialogs/display-settings.cpp:1037 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:58 +msgid "Tools" +msgstr "Herramientas" + +#: ../../po/../src/dialogs/display-settings.cpp:1045 +msgid "Selector" +msgstr "Selector" + +#: ../../po/../src/dialogs/display-settings.cpp:1056 +msgid "Node" +msgstr "Nodo" + +#: ../../po/../src/dialogs/display-settings.cpp:1064 +#: ../../po/../src/verbs.cpp:2073 +#: ../../po/../src/widgets/desktop-widget.cpp:277 +msgid "Zoom" +msgstr "Zoom" + +#. The 4 shape tools +#: ../../po/../src/dialogs/display-settings.cpp:1071 +msgid "Shapes" +msgstr "Formas" + +#: ../../po/../src/dialogs/display-settings.cpp:1079 +#: ../../po/../src/verbs.cpp:2055 +msgid "Rectangle" +msgstr "Rectángulo" + +#: ../../po/../src/dialogs/display-settings.cpp:1085 +#: ../../po/../src/verbs.cpp:2057 +msgid "Ellipse" +msgstr "Elipse" + +#: ../../po/../src/dialogs/display-settings.cpp:1091 +#: ../../po/../src/verbs.cpp:2059 +msgid "Star" +msgstr "Estrella" + +#: ../../po/../src/dialogs/display-settings.cpp:1097 +#: ../../po/../src/verbs.cpp:2061 +msgid "Spiral" +msgstr "Espiral" + +#: ../../po/../src/dialogs/display-settings.cpp:1111 +#: ../../po/../src/verbs.cpp:2063 +msgid "Pencil" +msgstr "Lápiz" + +#: ../../po/../src/dialogs/display-settings.cpp:1114 +msgid "Tolerance:" +msgstr "Tolerancia:" + +#: ../../po/../src/dialogs/display-settings.cpp:1115 +msgid "" +"This value affects the amount of smoothing applied to freehand lines; lower " +"values produce more uneven paths with more nodes" +msgstr "" +"Este valor afecta al suavizado aplicado a líneas a mano alzada, valores " +"menores producen trazos más irregulares con más nodos." + +#: ../../po/../src/dialogs/display-settings.cpp:1131 +#: ../../po/../src/verbs.cpp:2065 +msgid "Pen" +msgstr "Pluma" + +#: ../../po/../src/dialogs/display-settings.cpp:1140 +#: ../../po/../src/verbs.cpp:2067 +msgid "Calligraphy" +msgstr "Caligrafía" + +#: ../../po/../src/dialogs/display-settings.cpp:1147 +#: ../../po/../src/dialogs/text-edit.cpp:353 +#: ../../po/../src/ui/dialog/text-properties.cpp:37 +#: ../../po/../src/verbs.cpp:2069 +msgid "Text" +msgstr "Texto" + +#: ../../po/../src/dialogs/display-settings.cpp:1157 +#: ../../po/../src/verbs.cpp:2071 +msgid "Gradient" +msgstr "Gradiente" + +#: ../../po/../src/dialogs/display-settings.cpp:1164 +#: ../../po/../src/verbs.cpp:2077 +msgid "Connector" +msgstr "Conector" + +#: ../../po/../src/dialogs/display-settings.cpp:1171 +#: ../../po/../src/verbs.cpp:2075 +msgid "Dropper" +msgstr "Cuentagotas" + +#. Windows +#: ../../po/../src/dialogs/display-settings.cpp:1183 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:59 +msgid "Windows" +msgstr "Ventanas" + +#: ../../po/../src/dialogs/display-settings.cpp:1188 +msgid "Save window geometry" +msgstr "Guardar geometría de las ventanas" + +#: ../../po/../src/dialogs/display-settings.cpp:1189 +msgid "" +"Save the window size and position with each document (only for Inkscape SVG " +"format)" +msgstr "" +"Guarda el tamaño y posición de la ventana para cada documento (solamente " +"para el formato SVG de Inkscape)" + +#: ../../po/../src/dialogs/display-settings.cpp:1196 +msgid "Dialogs are hidden in taskbar" +msgstr "Ocultar los diálogos en la barra de tareas." + +#: ../../po/../src/dialogs/display-settings.cpp:1197 +msgid "Whether dialog windows are to be hidden in the window manager taskbar" +msgstr "" +"Indica si se muestran o no las ventanas de diálogo en la barra de tareas del " +"gestor de ventanas." + +#: ../../po/../src/dialogs/display-settings.cpp:1204 +msgid "Zoom when window is resized" +msgstr "Ajustar el dibujo si cambia el tamaño de la ventana" + +#: ../../po/../src/dialogs/display-settings.cpp:1205 +msgid "" +"Zoom drawing when document window is resized, to keep the same area visible " +"(this is the default which can be changed in any window using the button " +"above the right scrollbar)" +msgstr "" +"Hacer zoom en el dibujo cuando se cambia el tamaño de la ventana para " +"mantener visible el mismo área (esto es el modo predeterminado que se puede " +"modificar en cualquier ventana con el botón encima de la barra de " +"desplazamiento de la derecha)." + +#. Clones +#: ../../po/../src/dialogs/display-settings.cpp:1213 +#: ../../po/../src/dialogs/find.cpp:624 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:60 +msgid "Clones" +msgstr "Clones" + +#: ../../po/../src/dialogs/display-settings.cpp:1217 +msgid "When the original moves, its clones and linked offsets:" +msgstr "Cuando se mueve el original, sus clones y desvíos enlazados:" + +#: ../../po/../src/dialogs/display-settings.cpp:1229 +msgid "Move in parallel" +msgstr "Se mueven en paralelo" + +#: ../../po/../src/dialogs/display-settings.cpp:1230 +msgid "Clones are translated by the same vector as their original." +msgstr "Los clones se trasladan por el mismo vector que su original." + +#: ../../po/../src/dialogs/display-settings.cpp:1237 +msgid "Stay unmoved" +msgstr "Permanecen inmóviles" + +#: ../../po/../src/dialogs/display-settings.cpp:1238 +msgid "Clones preserve their positions when their original is moved." +msgstr "Los clones conservan sus posiciones cuando se mueve su original." + +#: ../../po/../src/dialogs/display-settings.cpp:1245 +msgid "Move according to transform" +msgstr "Se mueven de acuerdo con la transformación" + +#: ../../po/../src/dialogs/display-settings.cpp:1246 +msgid "" +"Each clone moves according to the value of its transform= attribute. For " +"example, a rotated clone will move in a different direction than its " +"original." +msgstr "" +"Cada clon se mueve de acuerdo con el valor de su atributo «transform=». Por " +"ejemplo, un clon rotado se moverá en una dirección distinta a su original." + +#: ../../po/../src/dialogs/display-settings.cpp:1255 +msgid "When the original is deleted, its clones:" +msgstr "Cuando se borra el original, sus clones:" + +#: ../../po/../src/dialogs/display-settings.cpp:1267 +msgid "Are unlinked" +msgstr "Se desconectan" + +#: ../../po/../src/dialogs/display-settings.cpp:1267 +msgid "Orphaned clones are converted to regular objects." +msgstr "Los clones huérfanos se convierten en objetos normales." + +#: ../../po/../src/dialogs/display-settings.cpp:1273 +msgid "Are deleted" +msgstr "Se borran" + +#: ../../po/../src/dialogs/display-settings.cpp:1273 +msgid "Orphaned clones are deleted along with their original." +msgstr "Los clones huérfanos se borran junto con su original." + +#. Transforms +#. TRANSLATORS: Noun, i.e. transformations. +#: ../../po/../src/dialogs/display-settings.cpp:1289 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:61 +msgid "Transforms" +msgstr "Transformaciones" + +#: ../../po/../src/dialogs/display-settings.cpp:1292 +msgid "Scale stroke width" +msgstr "Escalar ancho de trazo" + +#: ../../po/../src/dialogs/display-settings.cpp:1293 +#: ../../po/../src/widgets/select-toolbar.cpp:568 +msgid "When scaling objects, scale the stroke width by the same proportion" +msgstr "Al escalar objetos, escalar el ancho del trazo en la misma proporción" + +#: ../../po/../src/dialogs/display-settings.cpp:1300 +msgid "Scale rounded corners in rectangles" +msgstr "Escalar los ángulos redondeados en los rectángulos" + +#: ../../po/../src/dialogs/display-settings.cpp:1301 +#: ../../po/../src/widgets/select-toolbar.cpp:580 +msgid "When scaling rectangles, scale the radii of rounded corners" +msgstr "Al escalar rectángulos, escalar los radios de los ángulos redondeados" + +#: ../../po/../src/dialogs/display-settings.cpp:1308 +msgid "Transform gradients" +msgstr "Transformar gradientes" + +#: ../../po/../src/dialogs/display-settings.cpp:1309 +#: ../../po/../src/widgets/select-toolbar.cpp:592 +msgid "Transform gradients (in fill or stroke) along with the objects" +msgstr "Transformar los gradientes (en relleno o borde) junto con los objetos" + +#: ../../po/../src/dialogs/display-settings.cpp:1316 +msgid "Transform patterns" +msgstr "Transformar patrones" + +#: ../../po/../src/dialogs/display-settings.cpp:1317 +#: ../../po/../src/widgets/select-toolbar.cpp:604 +msgid "Transform patterns (in fill or stroke) along with the objects" +msgstr "Transformar los patrones (en relleno o borde) junto con los objetos" + +#. TRANSLATORS: How to specify the affine transformation in the SVG file. +#: ../../po/../src/dialogs/display-settings.cpp:1327 +msgid "Store transformation:" +msgstr "Guardar transformación:" + +#: ../../po/../src/dialogs/display-settings.cpp:1338 +msgid "Optimized" +msgstr "Optimizado" + +#: ../../po/../src/dialogs/display-settings.cpp:1339 +msgid "" +"If possible, apply transformation to objects without adding a transform= " +"attribute" +msgstr "" +"Aplicar la transformación a los objetos sin añadir un atributo «transform=» " +"cuando sea posible." + +#: ../../po/../src/dialogs/display-settings.cpp:1346 +msgid "Preserved" +msgstr "Conservado" + +#: ../../po/../src/dialogs/display-settings.cpp:1347 +msgid "Always store transformation as a transform= attribute on objects" +msgstr "" +"Siempre guardar una transformación como un atributo «transform=» en los " +"objetos." + +#. Selecting +#: ../../po/../src/dialogs/display-settings.cpp:1355 +msgid "Selecting" +msgstr "Selección" + +#: ../../po/../src/dialogs/display-settings.cpp:1357 +msgid "Ctrl+A, Tab, Shift+Tab:" +msgstr "Ctrl+A, Tab, Mayús+Tab:" + +#: ../../po/../src/dialogs/display-settings.cpp:1366 +msgid "Select only within current layer" +msgstr "Solamente seleccionar dentro de la capa actual" + +#: ../../po/../src/dialogs/display-settings.cpp:1367 +msgid "" +"Uncheck this to make keyboard selection commands work on objects in all " +"layers" +msgstr "" +"Desmarque esto para que los comandos de selección del teclado funcionen en " +"objetos de todas las capas." + +#: ../../po/../src/dialogs/display-settings.cpp:1374 +msgid "Ignore hidden objects" +msgstr "Ignorar objetos ocultos" + +#: ../../po/../src/dialogs/display-settings.cpp:1375 +msgid "" +"Uncheck this to be able to select objects that are hidden (either by " +"themselves or by being in a hidden group or layer)" +msgstr "" +"Desmarque esto para poder seleccionar objetos ocultos (tanto por sí mismos " +"como por estar en un grupo o capa ocultos)" + +#: ../../po/../src/dialogs/display-settings.cpp:1382 +msgid "Ignore locked objects" +msgstr "Ignorar objetos bloqueados" + +#: ../../po/../src/dialogs/display-settings.cpp:1383 +msgid "" +"Uncheck this to be able to select objects that are locked (either by " +"themselves or by being in a locked group or layer)" +msgstr "" +"Desmarque esto para poder seleccionar objetos bloqueados (tanto por sí " +"mismos como por estar en un grupo o capa bloqueados)" + +#. To be broken into: Display, Save, Export, SVG, Commands +#: ../../po/../src/dialogs/display-settings.cpp:1391 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:62 +msgid "Misc" +msgstr "Misc" + +#: ../../po/../src/dialogs/display-settings.cpp:1394 +msgid "Default export resolution:" +msgstr "Resolución de exportación predeterminada:" + +#: ../../po/../src/dialogs/display-settings.cpp:1395 +msgid "Default bitmap resolution (in dots per inch) in the Export dialog" +msgstr "" +"Resolución predeterminada (en puntos por pulgada) de mapa de bits en el " +"diálogo de exportación" + +#. FIXME: add "Used for new exports; once exported, documents remember this value on per-object basis" when implemented +#: ../../po/../src/dialogs/display-settings.cpp:1396 +#: ../../po/../src/dialogs/export.cpp:442 +msgid "dpi" +msgstr "ppp" + +#. TRANSLATORS: When on, an imported bitmap creates an element; otherwise it is a +#. * rectangle with bitmap fill. +#: ../../po/../src/dialogs/display-settings.cpp:1407 +msgid "Import bitmap as " +msgstr "Importar mapa de bits como " + +#: ../../po/../src/dialogs/display-settings.cpp:1408 +msgid "" +"When on, an imported bitmap creates an element; otherwise it is a " +"rectangle with bitmap fill" +msgstr "" +"Activo: un mapa de bits importado crea un elemento , de lo contrario " +"es un rectángulo con relleno de mapa de bits." + +#. TRANSLATORS: When on, the print out (currently Postscript) will have +#. * a comment with the each object's label visible, marking the section +#. * of the printing commands that represent the given object. +#: ../../po/../src/dialogs/display-settings.cpp:1418 +msgid "Add label comments to printing output" +msgstr "Añadir comentarios de etiqueta a la salida de impresión" + +#: ../../po/../src/dialogs/display-settings.cpp:1419 +msgid "" +"When on, a comment will be added to the raw print output, marking the " +"rendered output for an object with its label" +msgstr "" +"Si se activa, se añadirá un comentario a la salida de impresión, marcando la " +"salida generada para un objeto con su etiqueta" + +#. TRANSLATORS: When on, enable the effects menu, default is off +#: ../../po/../src/dialogs/display-settings.cpp:1427 +msgid "Enable script effects (requires restart) - EXPERIMENTAL" +msgstr "Activar efectos de script (necesita reiniciar) - EXPERIMENTAL" + +#: ../../po/../src/dialogs/display-settings.cpp:1428 +msgid "" +"When on, the effects menu is enabled, allowing external effect scripts to be " +"called, requires restart before effective - EXPERIMENTAL" +msgstr "" +"Si se activa se mostrará el menú «Efectos», lo que permitirá la ejecución de " +"guiones externos. Necesita que se reinicie el programa para que tenga " +"efecto. - EXPERIMENTAL" + +#. TRANSLATORS: The maximum length of the Open Recent list in the File menu. +#: ../../po/../src/dialogs/display-settings.cpp:1436 +msgid "Max recent documents:" +msgstr "Máximo de documentos recientes" + +#: ../../po/../src/dialogs/display-settings.cpp:1437 +msgid "The maximum length of the Open Recent list in the File menu" +msgstr "" +"La longitud máxima de la lista de «Abrir recientes» en el menú «Archivo»" + +#: ../../po/../src/dialogs/display-settings.cpp:1447 +msgid "Simplification threshold:" +msgstr "Umbral de simplificación:" + +#: ../../po/../src/dialogs/display-settings.cpp:1448 +msgid "" +"How strong is the Simplify command by default. If you invoke this command " +"several times in quick succession, it will act more and more aggressively; " +"invoking it again after a pause restores the default threshold." +msgstr "" +"La fuerza predeterminada del comando «Simplificar». Al ejecutar este comando " +"varias veces sucesivas, actuará más y más agresivamente; al ejecutarlo " +"después de una pausa volverá al umbral predeterminado." + +#: ../../po/../src/dialogs/display-settings.cpp:1469 +msgid "Oversample bitmaps:" +msgstr "Bitmaps de sobremuestreo:" + +#: ../../po/../src/dialogs/display-settings.cpp:1488 +msgid "2x2" +msgstr "2x2" + +#: ../../po/../src/dialogs/display-settings.cpp:1494 +msgid "4x4" +msgstr "4x4" + +#: ../../po/../src/dialogs/display-settings.cpp:1500 +msgid "8x8" +msgstr "8x8" + +#: ../../po/../src/dialogs/display-settings.cpp:1506 +msgid "16x16" +msgstr "16x16" + +#. "view_icon_preview" +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2143 +msgid "_Page" +msgstr "_Página" + +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2147 +msgid "_Drawing" +msgstr "_Dibujo" + +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2149 +msgid "_Selection" +msgstr "_Selección" + +#: ../../po/../src/dialogs/export.cpp:133 +msgid "_Custom" +msgstr "_Personalizado" + +#: ../../po/../src/dialogs/export.cpp:254 +msgid "Export area" +msgstr "Área exportada" + +#: ../../po/../src/dialogs/export.cpp:300 +msgid "_x0:" +msgstr "_x0:" + +#: ../../po/../src/dialogs/export.cpp:305 +msgid "x_1:" +msgstr "x_1:" + +#: ../../po/../src/dialogs/export.cpp:316 +msgid "_y0:" +msgstr "_y0:" + +#: ../../po/../src/dialogs/export.cpp:321 +msgid "y_1:" +msgstr "y_1:" + +#: ../../po/../src/dialogs/export.cpp:406 +msgid "Bitmap size" +msgstr "Tamaño del mapa de bits" + +#: ../../po/../src/dialogs/export.cpp:416 +msgid "_Width:" +msgstr "A_ncho:" + +#: ../../po/../src/dialogs/export.cpp:416 +#: ../../po/../src/dialogs/export.cpp:431 +msgid "pixels at" +msgstr "píxeles a" + +#: ../../po/../src/dialogs/export.cpp:426 +msgid "dp_i" +msgstr "_ppp" + +#: ../../po/../src/dialogs/export.cpp:448 +msgid "_Filename" +msgstr "Nombre de _archivo" + +#: ../../po/../src/dialogs/export.cpp:512 +msgid "_Browse..." +msgstr "E_xaminar..." + +# FIXME: implement averaging of all parameters for multiple selected stars +# gtk_label_set_markup (GTK_LABEL(l), _("Average:")); +# FIXME: implement averaging of all parameters for multiple selected +# gtk_label_set_markup (GTK_LABEL(l), _("Average:")); +#: ../../po/../src/dialogs/export.cpp:539 +msgid " _Export " +msgstr " _Exportar " + +#: ../../po/../src/dialogs/export.cpp:541 +msgid "Export the bitmap file with these settings" +msgstr "Exportar el archivo de mapa de bits con estos ajustes" + +#: ../../po/../src/dialogs/export.cpp:968 +msgid "You have to enter a filename" +msgstr "Debe indicar un nombre de archivo" + +#: ../../po/../src/dialogs/export.cpp:973 +msgid "The chosen area to be exported is invalid" +msgstr "El área seleccionada para exportación no es válida." + +#: ../../po/../src/dialogs/export.cpp:982 +#, c-format +msgid "Directory %s does not exist or is not a directory.\n" +msgstr "El directorio %s no existe o no es un directorio.\n" + +#: ../../po/../src/dialogs/export.cpp:998 +msgid "Export in progress" +msgstr "Realizando exportación..." + +#: ../../po/../src/dialogs/export.cpp:1004 +#, c-format +msgid "Exporting %s (%d x %d)" +msgstr "Exportando %s (%d x %d)" + +#: ../../po/../src/dialogs/export.cpp:1031 +#, c-format +msgid "Could not export to filename %s.\n" +msgstr "No se ha podido exportar al archivo %s.\n" + +#: ../../po/../src/dialogs/export.cpp:1137 +msgid "Select a filename for exporting" +msgstr "Seleccione un nombre de archivo para exportar" + +#: ../../po/../src/dialogs/filedialog.cpp:367 +msgid "No preview" +msgstr "Sin vista preliminar" + +#: ../../po/../src/dialogs/filedialog.cpp:468 +msgid "too large for preview" +msgstr "demasiado grande para previsualizar" + +#: ../../po/../src/dialogs/filedialog.cpp:762 +#: ../../po/../src/dialogs/filedialog.cpp:763 +msgid "All Images" +msgstr "Todas las imágenes" + +#: ../../po/../src/dialogs/filedialog.cpp:767 +#: ../../po/../src/dialogs/filedialog.cpp:768 +msgid "All Files" +msgstr "Todos los archivos" + +#: ../../po/../src/dialogs/filedialog.cpp:774 +#: ../../po/../src/dialogs/filedialog.cpp:775 +msgid "All Inkscape Files" +msgstr "Todos los archivos Inkscape" + +#: ../../po/../src/dialogs/filedialog.cpp:1176 +msgid "Guess from extension" +msgstr "Adivinar por la extensión" + +#. ###### Add the file types menu +#. createFilterMenu(); +#. ###### Do we want the .xxx extension automatically added? +#: ../../po/../src/dialogs/filedialog.cpp:1261 +msgid "Append filename extension automatically" +msgstr "Añadir la extensión del archivo automáticamente" + +#. TRANSLATORS: "%s" is replaced with "exact" or "partial" when this string is displayed +#: ../../po/../src/dialogs/find.cpp:378 +#, c-format +msgid "%d object found (out of %d), %s match." +msgid_plural "%d objects found (out of %d), %s match." +msgstr[0] "%d objeto encontrado (de %d), coincidencia %s." +msgstr[1] "%d objetos encontrados (de %d), coincidencia %s." + +#: ../../po/../src/dialogs/find.cpp:381 +msgid "exact" +msgstr "exacta" + +#: ../../po/../src/dialogs/find.cpp:381 +msgid "partial" +msgstr "parcial" + +#: ../../po/../src/dialogs/find.cpp:388 +msgid "No objects found" +msgstr "No se han encontrado objetos" + +#: ../../po/../src/dialogs/find.cpp:546 +msgid "T_ype: " +msgstr "T_ipo: " + +#: ../../po/../src/dialogs/find.cpp:553 +msgid "Search in all object types" +msgstr "Buscar en todos los tipos de objeto" + +#: ../../po/../src/dialogs/find.cpp:553 +msgid "All types" +msgstr "Todos los tipos" + +#: ../../po/../src/dialogs/find.cpp:564 +msgid "Search all shapes" +msgstr "Buscar en todas las formas" + +#: ../../po/../src/dialogs/find.cpp:564 +msgid "All shapes" +msgstr "Todas las formas" + +#: ../../po/../src/dialogs/find.cpp:581 +msgid "Search rectangles" +msgstr "Buscar rectángulos" + +#: ../../po/../src/dialogs/find.cpp:581 +msgid "Rectangles" +msgstr "Rectángulos" + +#: ../../po/../src/dialogs/find.cpp:586 +msgid "Search ellipses, arcs, circles" +msgstr "Buscar en elipses, arcos, círculos." + +#: ../../po/../src/dialogs/find.cpp:586 +msgid "Ellipses" +msgstr "Elipses" + +#: ../../po/../src/dialogs/find.cpp:591 +msgid "Search stars and polygons" +msgstr "Buscar estrellas y polígonos" + +#: ../../po/../src/dialogs/find.cpp:591 +msgid "Stars" +msgstr "Estrellas" + +#: ../../po/../src/dialogs/find.cpp:596 +msgid "Search spirals" +msgstr "Buscar espirales" + +#: ../../po/../src/dialogs/find.cpp:596 +msgid "Spirals" +msgstr "Espirales" + +#. TRANSLATORS: polyline is a set of connected straight line segments +#. http://www.w3.org/TR/SVG11/shapes.html#PolylineElement +#: ../../po/../src/dialogs/find.cpp:609 +msgid "Search paths, lines, polylines" +msgstr "Buscar en trazos, líneas, polilíneas." + +#: ../../po/../src/dialogs/find.cpp:609 +msgid "Paths" +msgstr "Trazos" + +#: ../../po/../src/dialogs/find.cpp:614 +msgid "Search text objects" +msgstr "Buscar objetos de texto" + +#: ../../po/../src/dialogs/find.cpp:614 +msgid "Texts" +msgstr "Textos" + +#: ../../po/../src/dialogs/find.cpp:619 +msgid "Search groups" +msgstr "Buscar en grupos." + +#: ../../po/../src/dialogs/find.cpp:619 +msgid "Groups" +msgstr "Grupos" + +#: ../../po/../src/dialogs/find.cpp:624 +msgid "Search clones" +msgstr "Buscar en clones" + +#: ../../po/../src/dialogs/find.cpp:629 +msgid "Search images" +msgstr "Buscar en imágenes" + +#: ../../po/../src/dialogs/find.cpp:629 +msgid "Images" +msgstr "Imágenes" + +#: ../../po/../src/dialogs/find.cpp:634 +msgid "Search offset objects" +msgstr "Buscar objetos desviados" + +#: ../../po/../src/dialogs/find.cpp:634 +msgid "Offsets" +msgstr "Desvíos" + +#: ../../po/../src/dialogs/find.cpp:694 +msgid "_Text: " +msgstr "_Texto:" + +#: ../../po/../src/dialogs/find.cpp:694 +msgid "Find objects by their text content (exact or partial match)" +msgstr "" +"Buscar objetos por su contenido de texto (coincidencia exacta o parcial)" + +#: ../../po/../src/dialogs/find.cpp:695 +msgid "_ID: " +msgstr "_ID: " + +#: ../../po/../src/dialogs/find.cpp:695 +msgid "Find objects by the value of the id attribute (exact or partial match)" +msgstr "" +"Buscar objetos por el valor del atributo «id» (coincidencia exacta o parcial)" + +#: ../../po/../src/dialogs/find.cpp:696 +msgid "_Style: " +msgstr "E_stilo:" + +#: ../../po/../src/dialogs/find.cpp:696 +msgid "" +"Find objects by the value of the style attribute (exact or partial match)" +msgstr "" +"Buscar objetos por el valor del atributo «style» (coincidencia exacta o " +"parcial)" + +#: ../../po/../src/dialogs/find.cpp:697 +msgid "_Attribute: " +msgstr "_Atributo:" + +#: ../../po/../src/dialogs/find.cpp:697 +msgid "Find objects by the name of an attribute (exact or partial match)" +msgstr "" +"Buscar objetos por el nombre de un atributo (coincidencia exacta o parcial)" + +#: ../../po/../src/dialogs/find.cpp:711 +msgid "Search in s_election" +msgstr "Buscar en la s_elección" + +#: ../../po/../src/dialogs/find.cpp:715 +msgid "Limit search to the current selection" +msgstr "Limitar la búsqueda a la selección actual" + +#: ../../po/../src/dialogs/find.cpp:720 +msgid "Search in current _layer" +msgstr "Buscar en la capa actua_l" + +#: ../../po/../src/dialogs/find.cpp:724 +msgid "Limit search to the current layer" +msgstr "Limitar la búsqueda a la capa actual" + +#: ../../po/../src/dialogs/find.cpp:729 +msgid "Include _hidden" +msgstr "Incluir _ocultas" + +#: ../../po/../src/dialogs/find.cpp:733 +msgid "Include hidden objects in search" +msgstr "Incluir objetos ocultos en la búsqueda" + +#: ../../po/../src/dialogs/find.cpp:738 +msgid "Include l_ocked" +msgstr "Incluir b_loqueadas" + +#: ../../po/../src/dialogs/find.cpp:742 +msgid "Include locked objects in search" +msgstr "Incluir objetos bloqueados en la búsqueda" + +#: ../../po/../src/dialogs/find.cpp:753 +msgid "Clear values" +msgstr "Limpiar valores" + +#: ../../po/../src/dialogs/find.cpp:754 +msgid "_Find" +msgstr "_Buscar" + +#: ../../po/../src/dialogs/find.cpp:754 +msgid "Select objects matching all of the fields you filled in" +msgstr "Seleccionar los objetos que coincidan con todos los campos rellenados" + +#: ../../po/../src/dialogs/iconpreview.cpp:145 +#, c-format +msgid "%d x %d" +msgstr "%d x %d" + +#: ../../po/../src/dialogs/iconpreview.cpp:193 +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:857 +#: ../../po/../src/widgets/desktop-widget.cpp:1069 +msgid "Selection" +msgstr "Selección" + +#: ../../po/../src/dialogs/iconpreview.cpp:195 +msgid "Selection only or whole document" +msgstr "Solamente la selección o el documento entero" + +#: ../../po/../src/dialogs/iconpreview.cpp:203 +msgid "Refresh the icons" +msgstr "Actualizar los iconos" + +#. Create the label for the object id +#: ../../po/../src/dialogs/item-properties.cpp:126 +#: ../../po/../src/dialogs/item-properties.cpp:327 +#: ../../po/../src/dialogs/item-properties.cpp:396 +#: ../../po/../src/dialogs/item-properties.cpp:403 +msgid "_Id" +msgstr "_Id" + +#: ../../po/../src/dialogs/item-properties.cpp:135 +msgid "" +"The id= attribute (only letters, digits, and the characters .-_: allowed)" +msgstr "" +"El atributo «id=» (solamente se permiten letras, dígitos y los caracteres «.-" +"_:»)" + +#. Button for setting the object's id, label, title and description. +#: ../../po/../src/dialogs/item-properties.cpp:149 +msgid "_Set" +msgstr "_Aplicar" + +#. Create the label for the object label +#: ../../po/../src/dialogs/item-properties.cpp:158 +msgid "_Label" +msgstr "_Etiqueta" + +#: ../../po/../src/dialogs/item-properties.cpp:167 +msgid "A freeform label for the object" +msgstr "Una etiqueta libre para el objeto" + +#. Create the label for the object title +#: ../../po/../src/dialogs/item-properties.cpp:179 +#: ../../po/../src/dialogs/rdf.cpp:243 +msgid "Title" +msgstr "Título" + +#. Create the frame for the object description +#: ../../po/../src/dialogs/item-properties.cpp:196 +#: ../../po/../src/dialogs/rdf.cpp:287 +msgid "Description" +msgstr "Descripción" + +#. Hide +#: ../../po/../src/dialogs/item-properties.cpp:223 +msgid "_Hide" +msgstr "_Ocultar" + +#: ../../po/../src/dialogs/item-properties.cpp:224 +msgid "Check to make the object invisible" +msgstr "Marcar para hacer el objeto invisible" + +#. Lock +#. TRANSLATORS: "Lock" is a verb here +#: ../../po/../src/dialogs/item-properties.cpp:233 +msgid "L_ock" +msgstr "B_loquear" + +#: ../../po/../src/dialogs/item-properties.cpp:234 +msgid "Check to make the object insensitive (not selectable by mouse)" +msgstr "" +"Marcar para hacer el objeto insensible (no se puedo seleccionar con el ratón)" + +#: ../../po/../src/dialogs/item-properties.cpp:310 +#: ../../po/../src/dialogs/item-properties.cpp:317 +msgid "Ref" +msgstr "Ref" + +#: ../../po/../src/dialogs/item-properties.cpp:398 +msgid "Id invalid! " +msgstr "ID no válido " + +#: ../../po/../src/dialogs/item-properties.cpp:400 +msgid "Id exists! " +msgstr "El ID existe " + +#: ../../po/../src/dialogs/layer-properties.cpp:50 +msgid "Layer name:" +msgstr "Nombre de la capa:" + +#: ../../po/../src/dialogs/layer-properties.cpp:133 +msgid "Rename Layer" +msgstr "Renombrar capa" + +#: ../../po/../src/dialogs/layer-properties.cpp:136 +msgid "_Rename" +msgstr "_Renombrar" + +#. TRANSLATORS: This means "The layer has been renamed" +#: ../../po/../src/dialogs/layer-properties.cpp:147 +msgid "Renamed layer" +msgstr "Capa renombrada" + +#: ../../po/../src/dialogs/layer-properties.cpp:151 +msgid "Add Layer" +msgstr "Añadir capa" + +#: ../../po/../src/dialogs/layer-properties.cpp:153 +msgid "_Add" +msgstr "_Añadir" + +#: ../../po/../src/dialogs/layer-properties.cpp:167 +msgid "New layer created." +msgstr "Se ha creado una capa nueva." + +#: ../../po/../src/dialogs/object-attributes.cpp:34 +msgid "Href:" +msgstr "Href:" + +#: ../../po/../src/dialogs/object-attributes.cpp:35 +msgid "Target:" +msgstr "Objetivo:" + +#: ../../po/../src/dialogs/object-attributes.cpp:36 +msgid "Type:" +msgstr "Tipo:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkRoleAttribute +#. Identifies the type of the related resource with an absolute URI +#: ../../po/../src/dialogs/object-attributes.cpp:39 +msgid "Role:" +msgstr "Rol:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkArcRoleAttribute +#. For situations where the nature/role alone isn't enough, this offers an additional URI defining the purpose of the link. +#: ../../po/../src/dialogs/object-attributes.cpp:42 +msgid "Arcrole:" +msgstr "Arcrole:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkTitleAttribute +#: ../../po/../src/dialogs/object-attributes.cpp:44 +msgid "Title:" +msgstr "Título:" + +#: ../../po/../src/dialogs/object-attributes.cpp:45 +msgid "Show:" +msgstr "Mostrar:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkActuateAttribute +#: ../../po/../src/dialogs/object-attributes.cpp:47 +msgid "Actuate:" +msgstr "Actuar:" + +#: ../../po/../src/dialogs/object-attributes.cpp:52 +msgid "URL:" +msgstr "URL:" + +#: ../../po/../src/dialogs/object-attributes.cpp:53 +msgid "X:" +msgstr "X:" + +#: ../../po/../src/dialogs/object-attributes.cpp:54 +msgid "Y:" +msgstr "Y:" + +#: ../../po/../src/dialogs/object-attributes.cpp:98 +#, c-format +msgid "%s attributes" +msgstr "%s atributos" + +#: ../../po/../src/dialogs/object-properties.cpp:158 +msgid "_Fill" +msgstr "_Relleno" + +#: ../../po/../src/dialogs/object-properties.cpp:165 +msgid "Stroke _paint" +msgstr "Color de _trazo" + +#: ../../po/../src/dialogs/object-properties.cpp:172 +msgid "Stroke st_yle" +msgstr "Est_ilo de trazo" + +#: ../../po/../src/dialogs/object-properties.cpp:183 +msgid "Master _opacity" +msgstr "_Opacidad maestra" + +#: ../../po/../src/dialogs/rdf.cpp:244 +msgid "Name by which this document is formally known." +msgstr "Nombre por el que se conoce este documento formalmente" + +#: ../../po/../src/dialogs/rdf.cpp:246 +msgid "Date" +msgstr "Fecha" + +#: ../../po/../src/dialogs/rdf.cpp:247 +msgid "Date associated with the creation of this document (YYYY-MM-DD)." +msgstr "Fecha asociada a la creación de este documento (AAAA-MM-DD)" + +#: ../../po/../src/dialogs/rdf.cpp:249 +msgid "Format" +msgstr "Formato" + +#: ../../po/../src/dialogs/rdf.cpp:250 +msgid "The physical or digital manifestation of this document (MIME type)." +msgstr "La manifestación física o digital de este documento (tipo MIME)" + +#: ../../po/../src/dialogs/rdf.cpp:252 +msgid "Type" +msgstr "Tipo" + +#: ../../po/../src/dialogs/rdf.cpp:253 +msgid "Type of document (DCMI Type)." +msgstr "Tipo de documento (tipo DCMI)" + +#: ../../po/../src/dialogs/rdf.cpp:256 +msgid "Creator" +msgstr "Creador" + +#: ../../po/../src/dialogs/rdf.cpp:257 +msgid "" +"Name of entity primarily responsible for making the content of this document." +msgstr "" +"Nombre de la entidad responsable en primera instancia de la creación del " +"contenido de este documento." + +#: ../../po/../src/dialogs/rdf.cpp:259 +msgid "Rights" +msgstr "Derechos" + +#: ../../po/../src/dialogs/rdf.cpp:260 +msgid "" +"Name of entity with rights to the Intellectual Property of this document." +msgstr "" +"Nombre de la entidad con derechos a la propiedad intelectual de este " +"documento" + +#: ../../po/../src/dialogs/rdf.cpp:262 +msgid "Publisher" +msgstr "Editor" + +#: ../../po/../src/dialogs/rdf.cpp:263 +msgid "Name of entity responsible for making this document available." +msgstr "Nombre de la entidad responsable de hacer este documento público" + +#: ../../po/../src/dialogs/rdf.cpp:266 +msgid "Identifier" +msgstr "Identificador" + +#: ../../po/../src/dialogs/rdf.cpp:267 +msgid "Unique URI to reference this document." +msgstr "URI único para referenciar este documento" + +#: ../../po/../src/dialogs/rdf.cpp:269 +msgid "Source" +msgstr "Fuente" + +#: ../../po/../src/dialogs/rdf.cpp:270 +msgid "Unique URI to reference the source of this document." +msgstr "URI única para referenciar la fuente de este documento" + +#: ../../po/../src/dialogs/rdf.cpp:272 +msgid "Relation" +msgstr "Relación" + +#: ../../po/../src/dialogs/rdf.cpp:273 +msgid "Unique URI to a related document." +msgstr "URI única a un documento relacionado." + +#: ../../po/../src/dialogs/rdf.cpp:275 +msgid "Language" +msgstr "Idioma" + +#: ../../po/../src/dialogs/rdf.cpp:276 +msgid "" +"Two-letter language tag with optional subtags for the language of this " +"document. (e.g. 'en-GB')" +msgstr "" +"Abreviatura de dos letras del idioma, con la abreviatura opcional de este " +"documento (por ejemplo: «es-ES»)" + +#: ../../po/../src/dialogs/rdf.cpp:278 +msgid "Keywords" +msgstr "Palabras clave" + +#: ../../po/../src/dialogs/rdf.cpp:279 +msgid "" +"The topic of this document as comma-separated key words, phrases, or " +"classifications." +msgstr "" +"El tema de este documento en formato de palabras clave, frases o " +"clasificaciones separados por coma." + +#. TRANSLATORS: "Coverage": the spatial or temporal characteristics of the content. +#. For info, see Appendix D of http://www.w3.org/TR/1998/WD-rdf-schema-19980409/ +#: ../../po/../src/dialogs/rdf.cpp:283 +msgid "Coverage" +msgstr "Cobertura" + +#: ../../po/../src/dialogs/rdf.cpp:284 +msgid "Extent or scope of this document." +msgstr "Extensión o ámbito de este documento" + +#: ../../po/../src/dialogs/rdf.cpp:288 +msgid "A short account of the content of this document." +msgstr "Una breve descripción del documento actual." + +#. FIXME: need to handle 1 agent per line of input +#: ../../po/../src/dialogs/rdf.cpp:292 +msgid "Contributors" +msgstr "Colaboradores" + +#: ../../po/../src/dialogs/rdf.cpp:293 +msgid "" +"Names of entities responsible for making contributions to the content of " +"this document." +msgstr "" +"Nombres de las entidades responsables de las colaboraciones al contenido de " +"este documento" + +#. TRANSLATORS: URL to a page that defines the license for the document +#: ../../po/../src/dialogs/rdf.cpp:297 +msgid "URI" +msgstr "URI" + +#. TRANSLATORS: this is where you put a URL to a page that defines the license +#: ../../po/../src/dialogs/rdf.cpp:299 +msgid "URI to this document's license's namespace definition." +msgstr "" +"URI a la definición del espacio de nombre de la licencia de este documento" + +#. TRANSLATORS: fragment of XML representing the license of the document +#: ../../po/../src/dialogs/rdf.cpp:303 +msgid "Fragment" +msgstr "Fragmento" + +#: ../../po/../src/dialogs/rdf.cpp:304 +msgid "XML fragment for the RDF 'License' section." +msgstr "Fragmento XML para la sección RDF «Licencia»." + +#: ../../po/../src/dialogs/stroke-style.cpp:774 +#: ../../po/../src/widgets/gradient-vector.cpp:263 +#: ../../po/../src/widgets/paint-selector.cpp:751 +msgid "No document selected" +msgstr "Sin documentos seleccionados" + +#: ../../po/../src/dialogs/stroke-style.cpp:992 +msgid "Stroke width" +msgstr "Ancho de trazo" + +#. Join type +#. TRANSLATORS: The line join style specifies the shape to be used at the +#. corners of paths. It can be "miter", "round" or "bevel". +#: ../../po/../src/dialogs/stroke-style.cpp:1015 +msgid "Join:" +msgstr "Unión:" + +#. TRANSLATORS: Miter join: joining lines with a sharp (pointed) corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1027 +msgid "Miter join" +msgstr "Unión de tipo inglete" + +#. TRANSLATORS: Round join: joining lines with a rounded corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1035 +msgid "Round join" +msgstr "Unión redonda" + +#. TRANSLATORS: Bevel join: joining lines with a blunted (flattened) corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1043 +msgid "Bevel join" +msgstr "Unión biselada" + +#. Miterlimit +#. TRANSLATORS: Miter limit: only for "miter join", this limits the length +#. of the sharp "spike" when the lines connect at too sharp an angle. +#. When two line segments meet at a sharp angle, a miter join results in a +#. spike that extends well beyond the connection point. The purpose of the +#. miter limit is to cut off such spikes (i.e. convert them into bevels) +#. when they become too long. +#: ../../po/../src/dialogs/stroke-style.cpp:1054 +msgid "Miter limit:" +msgstr "Límite de inglete:" + +#: ../../po/../src/dialogs/stroke-style.cpp:1062 +msgid "Maximum length of the miter (in units of stroke width)" +msgstr "Longitud máxima del inglete (en unidades de ancho de trazo)" + +#. Cap type +#. TRANSLATORS: cap type specifies the shape for the ends of lines +#: ../../po/../src/dialogs/stroke-style.cpp:1075 +msgid "Cap:" +msgstr "Punta:" + +#. TRANSLATORS: Butt cap: the line shape does not extend beyond the end point +#. of the line; the ends of the line are square +#: ../../po/../src/dialogs/stroke-style.cpp:1086 +msgid "Butt cap" +msgstr "Tope embutido" + +#. TRANSLATORS: Round cap: the line shape extends beyond the end point of the +#. line; the ends of the line are rounded +#: ../../po/../src/dialogs/stroke-style.cpp:1093 +msgid "Round cap" +msgstr "Tope redondo" + +#. TRANSLATORS: Square cap: the line shape extends beyond the end point of the +#. line; the ends of the line are square +#: ../../po/../src/dialogs/stroke-style.cpp:1100 +msgid "Square cap" +msgstr "Tope cuadrado" + +#. Dash +#: ../../po/../src/dialogs/stroke-style.cpp:1106 +msgid "Dashes:" +msgstr "Guiones:" + +#. TRANSLATORS: Path markers are an SVG feature that allows you to attach arbitrary shapes +#. (arrowheads, bullets, faces, whatever) to the start, end, or middle nodes of a path. +#: ../../po/../src/dialogs/stroke-style.cpp:1127 +msgid "Start Markers:" +msgstr "Marcas de inicio:" + +#: ../../po/../src/dialogs/stroke-style.cpp:1137 +msgid "Mid Markers:" +msgstr "Marcadores medios:" + +#: ../../po/../src/dialogs/stroke-style.cpp:1148 +msgid "End Markers:" +msgstr "Marcadores finales:" + +#: ../../po/../src/dialogs/swatches.cpp:424 +#, c-format +msgid "Palettes directory (%s) is unavailable." +msgstr "No está disponible el directorio de paletas (%s)." + +#. TODO: Insert widgets +#: ../../po/../src/dialogs/text-edit.cpp:199 +#: ../../po/../src/ui/dialog/text-properties.cpp:36 +msgid "Font" +msgstr "Tipografía" + +#: ../../po/../src/dialogs/text-edit.cpp:216 +msgid "Layout" +msgstr "Formato" + +#: ../../po/../src/dialogs/text-edit.cpp:229 +msgid "Align lines left" +msgstr "Alinear líneas a la izquierda" + +#. TRANSLATORS: `Center' here is a verb. +#: ../../po/../src/dialogs/text-edit.cpp:243 +msgid "Center lines" +msgstr "Centrar líneas" + +#: ../../po/../src/dialogs/text-edit.cpp:256 +msgid "Align lines right" +msgstr "Alinear líneas a la derecha" + +#: ../../po/../src/dialogs/text-edit.cpp:278 +msgid "Horizontal text" +msgstr "Texto horizontal" + +#: ../../po/../src/dialogs/text-edit.cpp:292 +msgid "Vertical text" +msgstr "Texto vertical" + +#: ../../po/../src/dialogs/text-edit.cpp:307 +msgid "Line spacing:" +msgstr "Espaciado de líneas:" + +#: ../../po/../src/dialogs/text-edit.cpp:400 +msgid "Set as default" +msgstr "Definir como predeterminado" + +#: ../../po/../src/dialogs/tiledialog.cpp:603 +msgid "Rows:" +msgstr "Filas:" + +#: ../../po/../src/dialogs/tiledialog.cpp:613 +msgid "Number of rows" +msgstr "Número de filas" + +#: ../../po/../src/dialogs/tiledialog.cpp:617 +msgid "Equal height" +msgstr "Altura igual" + +#: ../../po/../src/dialogs/tiledialog.cpp:627 +msgid "If not set, each row has the height of the tallest object in it" +msgstr "Si no se indica, cada fila tendrá la altura del objeto más alto" + +#. #### Radio buttons to control vertical alignment #### +#. #### Radio buttons to control horizontal alignment #### +#: ../../po/../src/dialogs/tiledialog.cpp:637 +#: ../../po/../src/dialogs/tiledialog.cpp:708 +msgid "Align:" +msgstr "Alinear:" + +#: ../../po/../src/dialogs/tiledialog.cpp:672 +msgid " X " +msgstr " X " + +# FIXME: implement averaging of all parameters for multiple selected stars +# gtk_label_set_markup (GTK_LABEL(l), _("Average:")); +# FIXME: implement averaging of all parameters for multiple selected +# gtk_label_set_markup (GTK_LABEL(l), _("Average:")); +#. #### Number of columns #### +#: ../../po/../src/dialogs/tiledialog.cpp:678 +msgid "Columns:" +msgstr "Columnas:" + +#: ../../po/../src/dialogs/tiledialog.cpp:688 +msgid "Number of columns" +msgstr "Número de columnas" + +#: ../../po/../src/dialogs/tiledialog.cpp:692 +msgid "Equal width" +msgstr "Anchura igual" + +#: ../../po/../src/dialogs/tiledialog.cpp:701 +msgid "If not set, each column has the width of the widest object in it" +msgstr "Si no se indica, cada fila tendrá la anchura del objeto más ancho" + +#. #### Radio buttons to control spacing manually or to fit selection bbox #### +#: ../../po/../src/dialogs/tiledialog.cpp:746 +msgid "Fit into selection box" +msgstr "Encajar en la caja de selección" + +#: ../../po/../src/dialogs/tiledialog.cpp:753 +msgid "Set spacing:" +msgstr "Ajustar espaciado:" + +#. #### Y Padding #### +#: ../../po/../src/dialogs/tiledialog.cpp:777 +msgid "Row spacing: " +msgstr "Espaciado de líneas: " + +#: ../../po/../src/dialogs/tiledialog.cpp:786 +msgid "Vertical spacing between rows" +msgstr "Espaciado vertical entre líneas" + +#. #### X padding #### +#: ../../po/../src/dialogs/tiledialog.cpp:795 +msgid "Column spacing:" +msgstr "Espaciado de columnas:" + +#: ../../po/../src/dialogs/tiledialog.cpp:804 +msgid "Horizontal spacing between columns" +msgstr "Espacio horizontal por entre columnas" + +#: ../../po/../src/dialogs/tiledialog.cpp:818 +#, fuzzy +msgid "Arrange selected objects" +msgstr "Agrupar los objetos seleccionados" + +#: ../../po/../src/dialogs/xml-tree.cpp:178 +msgid "Click to select nodes, drag to rearrange." +msgstr "" +"Haga clic para seleccionar nodos, arrastre para reordenar." + +#: ../../po/../src/dialogs/xml-tree.cpp:189 +msgid "Click attribute to edit." +msgstr "Haga clic en el atributo para editarlo." + +#: ../../po/../src/dialogs/xml-tree.cpp:193 +#, c-format +msgid "" +"Attribute %s selected. Press Ctrl+Enter when done editing to " +"commit changes." +msgstr "" +"Ha seleccionado el atributo %s. Cuando termine, pulse Ctrl+Enter para guardar los cambios." + +#: ../../po/../src/dialogs/xml-tree.cpp:284 +msgid "Drag to reorder nodes" +msgstr "Arrastrar para reordenar nodos" + +#: ../../po/../src/dialogs/xml-tree.cpp:304 +msgid "New element node" +msgstr "Nuevo nodo de elemento" + +#: ../../po/../src/dialogs/xml-tree.cpp:326 +msgid "New text node" +msgstr "Nuevo nodo de texto" + +#: ../../po/../src/dialogs/xml-tree.cpp:347 +msgid "Duplicate node" +msgstr "Duplicar nodo" + +#: ../../po/../src/dialogs/xml-tree.cpp:368 +msgid "Delete node" +msgstr "Borrar nodo" + +#: ../../po/../src/dialogs/xml-tree.cpp:384 +msgid "Unindent node" +msgstr "Desangrar nodo" + +#: ../../po/../src/dialogs/xml-tree.cpp:399 +msgid "Indent node" +msgstr "Sangrar nodos" + +#: ../../po/../src/dialogs/xml-tree.cpp:411 +msgid "Raise node" +msgstr "Elevar nodo" + +#: ../../po/../src/dialogs/xml-tree.cpp:423 +msgid "Lower node" +msgstr "Bajar nodo" + +#: ../../po/../src/dialogs/xml-tree.cpp:468 +msgid "Delete attribute" +msgstr "Borrar atributo" + +#. TRANSLATORS: "Attribute" is a noun here +#: ../../po/../src/dialogs/xml-tree.cpp:513 +msgid "Attribute name" +msgstr "Nombre de atributo" + +#. TRANSLATORS: "Set" is a verb here +#: ../../po/../src/dialogs/xml-tree.cpp:533 +msgid "Set attribute" +msgstr "Definir atributo" + +#. TRANSLATORS: "Set" is a verb here +#: ../../po/../src/dialogs/xml-tree.cpp:535 +msgid "Set" +msgstr "Aceptar" + +#. TRANSLATORS: "Attribute" is a noun here +#: ../../po/../src/dialogs/xml-tree.cpp:558 +msgid "Attribute value" +msgstr "Valor del atributo" + +#: ../../po/../src/dialogs/xml-tree.cpp:1318 +msgid "New element node..." +msgstr "Nuevo nodo de elemento..." + +#: ../../po/../src/dialogs/xml-tree.cpp:1339 +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:100 +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:98 +msgid "Cancel" +msgstr "Cancelar" + +#: ../../po/../src/dialogs/xml-tree.cpp:1345 +msgid "Create" +msgstr "Crear" + +#: ../../po/../src/dialogs/xml-tree.cpp:1458 +#, c-format +msgid "" +"Cannot set %s: Another element with value %s already exists!" +msgstr "" +"No se puede ajustar %s: Ya existe otro elemento con el valor %s." + +#: ../../po/../src/document.cpp:369 +#, c-format +msgid "New document %d" +msgstr "Documento nuevo %d" + +#: ../../po/../src/document.cpp:401 +#, c-format +msgid "Memory document %d" +msgstr "Documento de memoria %d" + +#: ../../po/../src/document.cpp:524 +#, c-format +msgid "Unnamed document %d" +msgstr "Documento sin nombre %d" + +#. We hit green anchor, closing Green-Blue-Red +#: ../../po/../src/draw-context.cpp:441 +msgid "Path is closed." +msgstr "Trazo cerrado" + +#. We hit bot start and end of single curve, closing paths +#: ../../po/../src/draw-context.cpp:456 +msgid "Closing path." +msgstr "Cerrar trazo." + +#. alpha of color under cursor, to show in the statusbar +#. locale-sensitive printf is OK, since this goes to the UI, not into SVG +#: ../../po/../src/dropper-context.cpp:354 +#, c-format +msgid " alpha %.3g" +msgstr " alfa %.3g" + +#. where the color is picked, to show in the statusbar +#: ../../po/../src/dropper-context.cpp:356 +#, c-format +msgid ", averaged with radius %d" +msgstr ", media con radio %d" + +#: ../../po/../src/dropper-context.cpp:356 +msgid " under cursor" +msgstr " bajo el cursor" + +#. message, to show in the statusbar +#: ../../po/../src/dropper-context.cpp:358 +msgid "Release mouse to set color." +msgstr "Suelte el ratón para fijar el color." + +#: ../../po/../src/dropper-context.cpp:358 +#: ../../po/../src/tools-switch.cpp:207 +msgid "" +"Click to set fill, Shift+click to set stroke; drag to " +"average color in area; with Alt to pick inverse color; Ctrl+C " +"to copy the color under mouse to clipboard" +msgstr "" +"Haga clic para seleccionar el color de relleno, Mayús+clic " +"para el color del trazo, arrastre para seleccionar la media de color " +"de un área., con Alt para el color inverso, Ctrl+C para copiar " +"el color de debajo del ratón al portapapeles." + +#: ../../po/../src/extension/dependency.cpp:244 +msgid "Dependency::" +msgstr "Dependencia:" + +#: ../../po/../src/extension/dependency.cpp:245 +msgid " type: " +msgstr " tipo: " + +#: ../../po/../src/extension/dependency.cpp:246 +msgid " location: " +msgstr " localización: " + +#: ../../po/../src/extension/dependency.cpp:247 +msgid " string: " +msgstr " cadena: " + +#: ../../po/../src/extension/dependency.cpp:250 +msgid " description: " +msgstr " descripción: " + +#. static int i = 0; +#. std::cout << "Checking module[" << i++ << "]: " << name << std::endl; +#: ../../po/../src/extension/extension.cpp:244 +msgid "" +" This is caused by an improper .inx file for this extension. An improper ." +"inx file could have been caused by a faulty installation of Inkscape." +msgstr "" +" La causa de esto es un archivo .inx incorrecto para esta extensión. Un " +"archivo inx incorrecto puede ser el resultado de una instalación defectuosa " +"de Inkscape." + +#: ../../po/../src/extension/extension.cpp:247 +msgid "an ID was not defined for it." +msgstr "no se le definió un ID." + +#: ../../po/../src/extension/extension.cpp:251 +msgid "there was no name defined for it." +msgstr "no se le definió un nombre." + +#: ../../po/../src/extension/extension.cpp:255 +msgid "the XML description of it got lost." +msgstr "se perdió su descripción XML." + +#: ../../po/../src/extension/extension.cpp:259 +msgid "no implementation was defined for the extension." +msgstr "no se definió una implementación correcta para la extensión." + +#. std::cout << "Failed: " << *(_deps[i]) << std::endl; +#: ../../po/../src/extension/extension.cpp:266 +msgid "a dependency was not met." +msgstr "no se cumplió una dependencia." + +#: ../../po/../src/extension/extension.cpp:286 +msgid "Extension \"" +msgstr "La extensión «" + +#: ../../po/../src/extension/extension.cpp:286 +msgid "\" failed to load because " +msgstr "» no se ha cargado porque " + +#: ../../po/../src/extension/extension.cpp:565 +#, c-format +msgid "Could not create extension error log file '%s'" +msgstr "" +"No se pudo crear el archivo de registro de errores de las extensiones «%s»." + +#. This is some filler text, needs to change before relase +#: ../../po/../src/extension/error-file.cpp:56 +msgid "" +"One or more extensions failed to load\n" +"\n" +"The failed extensions have been skipped. Inkscape will continue to run " +"normally but those extensions will be unavailable. For details to " +"troubleshoot this problem, please refer to the error log located at: " +msgstr "" +"No se cargaron una o más extensiones.\n" +"\n" +"Se han omitido las extensiones erróneas. Inkscape seguirá su ejecución con " +"normalidad, pero esas extensiones no estarán disponibles. Para obtener más " +"detalles para solucionar este problema, acuda al archivo de registro en: " + +#. This is some filler text, needs to change before relase +#: ../../po/../src/extension/error-file.cpp:65 +msgid "Show dialog on startup" +msgstr "Mostrar diálogo al inicio" + +#: ../../po/../src/extension/implementation/script.cpp:845 +msgid "" +"Inkscape has received an error from the script that it called. The text " +"returned with the error is included below. Inkscape will continue working, " +"but the action you requested has been cancelled." +msgstr "" +"Inkscape ha recibido un error de un script que ha llamado. El texto " +"producido por el error está incluido más abajo. Inkscape seguirá funcionando " +"pero la acción que ha realizado ha sido cancelada." + +#: ../../po/../src/extension/implementation/script.cpp:858 +msgid "" +"Inkscape has received additional data from the script executed. The script " +"did not return an error, but this may indicate the results will not be as " +"expected." +msgstr "" +"Inkscape ha recibido información adicional del script ejecutado. El script " +"no ha devuelto un error, pero esto puede indicar que el resultado no será el " +"esperado." + +#: ../../po/../src/extension/init.cpp:173 +msgid "Null external module directory name. Modules will not be loaded." +msgstr "" +"Nombre de directorio de módulos externos nulo. No se cargarán los módulos." + +#: ../../po/../src/extension/init.cpp:187 +#, c-format +msgid "" +"Modules directory (%s) is unavailable. External modules in that directory " +"will not be loaded." +msgstr "" +"El directorio de módulos (%s) no está disponible. No se cargarán los módulos " +"externos de ese directorio." + +#: ../../po/../src/extension/internal/gnome.cpp:80 +msgid "Select printer" +msgstr "Seleccionar impresora" + +#: ../../po/../src/extension/internal/gnome.cpp:131 +msgid "Inkscape: Print Preview" +msgstr "Inkscape: Presentación preliminar" + +#: ../../po/../src/extension/internal/grid.cpp:213 +msgid "Line Width" +msgstr "Ancho de línea" + +#: ../../po/../src/extension/internal/grid.cpp:214 +msgid "Horizontal Spacing" +msgstr "Espaciado horizontal" + +#: ../../po/../src/extension/internal/grid.cpp:215 +msgid "Vertical Spacing" +msgstr "Espaciado vertical" + +#: ../../po/../src/extension/internal/grid.cpp:216 +msgid "Horizontal Offset" +msgstr "Desvío horizontal" + +#: ../../po/../src/extension/internal/grid.cpp:217 +msgid "Vertical Offset" +msgstr "Desvío vertical" + +#: ../../po/../src/extension/internal/ps.cpp:123 +msgid "Print Destination" +msgstr "Destino de impresión" + +#. Print properties frame +#: ../../po/../src/extension/internal/ps.cpp:138 +msgid "Print properties" +msgstr "Propiedades de impresión" + +#: ../../po/../src/extension/internal/ps.cpp:145 +msgid "Print using PostScript operators" +msgstr "Imprimir usando operadores PostScript" + +#: ../../po/../src/extension/internal/ps.cpp:147 +msgid "" +"Use PostScript vector operators. The resulting image is usually smaller in " +"file size and can be arbitrarily scaled, but alpha transparency and patterns " +"will be lost." +msgstr "" +"Usar operadores PostScript vectoriales. La imagen resultante normalmente " +"será menor en tamaño de archivo y puede ser escalada arbitrariamente, pero " +"se perderán la transparencia alfa y los patrones." + +#: ../../po/../src/extension/internal/ps.cpp:152 +msgid "Print as bitmap" +msgstr "Imprimir como mapa de bits" + +#: ../../po/../src/extension/internal/ps.cpp:154 +msgid "" +"Print everything as bitmap. The resulting image is usually larger in file " +"size and cannot be arbitrarily scaled without quality loss, but all objects " +"will be rendered exactly as displayed." +msgstr "" +"Imprimir todo como mapa de bits. La imagen resultante normalmente será mayor " +"y la calidad dependerá del factor de ampliación, pero todos los gráficos " +"serán renderizados idénticos a la pantalla" + +#: ../../po/../src/extension/internal/ps.cpp:168 +msgid "Preferred resolution (dots per inch) of bitmap" +msgstr "Resolución preferida (puntos por pulgada) de mapa de bits" + +#: ../../po/../src/extension/internal/ps.cpp:182 +msgid "Resolution:" +msgstr "Resolución:" + +#. Print destination frame +#: ../../po/../src/extension/internal/ps.cpp:186 +msgid "Print destination" +msgstr "Destino de impresión" + +#: ../../po/../src/extension/internal/ps.cpp:192 +msgid "" +"Use '> filename' to print to file.\n" +"Use '| prog arg...' to pipe to a program." +msgstr "" +"Utilice «> archivo» para imprimir en un archivo.\n" +"Utilice «| prog arg...» para enviar a un programa." + +#: ../../po/../src/extension/internal/ps.cpp:1227 +msgid "write error occurred" +msgstr "ha ocurrido un error de escritura" + +#: ../../po/../src/extension/prefdialog.cpp:21 +msgid " Preferences" +msgstr " Preferencias" + +#. We can't call sp_ui_error_dialog because we may be +#. running from the console, in which case calling sp_ui +#. routines will cause a segfault. See bug 1000350 - bryce +#. sp_ui_error_dialog(_("Format autodetect failed. The file is being opened as SVG.")); +#: ../../po/../src/extension/system.cpp:105 +msgid "Format autodetect failed. The file is being opened as SVG." +msgstr "" +"Ha fallado la detección automática de formato. Se abrirá el archivo como SVG." + +#. TRANSLATORS: default.svg is localizable - this is the name of the default document +#. template. This way you can localize the default pagesize, translate the name of +#. the default layer, etc. If you wish to localize this file, please create a +#. localized share/templates/default.xx.svg file, where xx is your language code. +#: ../../po/../src/file.cpp:133 +msgid "default.svg" +msgstr "default.es.svg" + +#: ../../po/../src/file.cpp:215 ../../po/../src/file.cpp:900 +#, c-format +msgid "Failed to load the requested file %s" +msgstr "Error al cargar el archivo pedido %s" + +#: ../../po/../src/file.cpp:240 +msgid "Document not saved yet. Cannot revert." +msgstr "Todavía no se ha guardado el documento. No se puede revertir." + +#: ../../po/../src/file.cpp:246 +#, c-format +msgid "Changes will be lost! Are you sure you want to reload document %s?" +msgstr "" +"Se perderán los cambios. ¿Está seguro de querer recargar el documento %s?" + +#: ../../po/../src/file.cpp:266 +msgid "Document reverted." +msgstr "Documento revertido." + +#: ../../po/../src/file.cpp:268 +msgid "Document not reverted." +msgstr "No se ha revertido el documento." + +#: ../../po/../src/file.cpp:382 +msgid "Select file to open" +msgstr "Seleccione el archivo que desea abrir" + +#: ../../po/../src/file.cpp:518 +#, c-format +msgid "Removed %i unused definition in <defs>." +msgid_plural "Removed %i unused definitions in <defs>." +msgstr[0] "Se ha eliminado %i definición no usada en <defs>." +msgstr[1] "Se han eliminado %i definiciones no usadas en <defs>." + +#: ../../po/../src/file.cpp:523 +msgid "No unused definitions in <defs>." +msgstr "No hay definiciones sin usar en <defs>." + +#: ../../po/../src/file.cpp:548 +#, c-format +msgid "" +"No Inkscape extension found to save document (%s). This may have been " +"caused by an unknown filename extension." +msgstr "" +"No se ha encontrado una extensión de inkscape para guardar el documento (%" +"s). Esto pudo ser causado por una extensión de archivo desconocida." + +#: ../../po/../src/file.cpp:549 ../../po/../src/file.cpp:557 +msgid "Document not saved." +msgstr "No se ha guardado el documento." + +#: ../../po/../src/file.cpp:556 +#, c-format +msgid "File %s could not be saved." +msgstr "No se ha podido guardar el archivo %s." + +#: ../../po/../src/file.cpp:566 +msgid "Document saved." +msgstr "Documento guardado." + +#: ../../po/../src/file.cpp:614 +#, c-format +msgid "drawing%s" +msgstr "dibujo%s" + +#: ../../po/../src/file.cpp:620 +#, c-format +msgid "drawing-%d%s" +msgstr "dibujo-%d%s" + +#: ../../po/../src/file.cpp:655 +msgid "Select file to save to" +msgstr "Seleccione el archivo en el que se guardará" + +#: ../../po/../src/file.cpp:739 +msgid "No changes need to be saved." +msgstr "No hay cambios que necesiten ser guardados." + +#: ../../po/../src/file.cpp:926 +msgid "Select file to import" +msgstr "Seleccionar el archivo a importar" + +#: ../../po/../src/gradient-context.cpp:263 +msgid "Ctrl: snap gradient angle" +msgstr "Ctrl: ajusta el ángulo del gradiente" + +#: ../../po/../src/gradient-context.cpp:264 +msgid "Shift: draw gradient around the starting point" +msgstr "Mayús: dibuja el gradiente alrededor del punto inicial" + +#. We did an undoable action, but sp_document_done will be called by the knot when released +#. status text; we do not track coords because this branch is run once, not all the time +#. during drag +#: ../../po/../src/gradient-context.cpp:462 +#, c-format +msgid "Gradient for %d objects; with Ctrl to snap angle" +msgstr "" +"Gradiente para %d objetos; con Ctrl para ajustar el ángulo" + +#: ../../po/../src/gradient-context.cpp:464 +msgid "Select objects on which to create gradient." +msgstr "Seleccione los objetos en los que crear un gradiente." + +#: ../../po/../src/gradient-drag.cpp:65 +msgid "Linear gradient start" +msgstr "Inicio del gradiente lineal" + +#. POINT_LG_P1 +#: ../../po/../src/gradient-drag.cpp:66 +msgid "Linear gradient end" +msgstr "Fin del gradiente lineal" + +#: ../../po/../src/gradient-drag.cpp:67 +msgid "Radial gradient center" +msgstr "Centro del gradiente radial" + +#: ../../po/../src/gradient-drag.cpp:68 ../../po/../src/gradient-drag.cpp:69 +msgid "Radial gradient radius" +msgstr "Radio del gradiente radial" + +#: ../../po/../src/gradient-drag.cpp:70 +msgid "Radial gradient focus" +msgstr "Foco del gradiente radial" + +# fixme: CTRL SNAP!!! remove "skew and scale" +#: ../../po/../src/gradient-drag.cpp:659 +#, c-format +msgid "" +"%s for: %s%s; drag with Ctrl to snap angle, with Ctrl+Alt to " +"preserve angle, with Ctrl+Shift to scale around center" +msgstr "" +"%s para: %s%s; arrastre con Ctrl para ajustar el ángulo, con Ctrl" +"+Alt para preservar el ángulo, con Ctrl+Mayús para escalar " +"alrededor del centro" + +#: ../../po/../src/gradient-drag.cpp:662 +msgid " (stroke)" +msgstr " (trazo)" + +#: ../../po/../src/gradient-drag.cpp:665 +msgid "" +"Radial gradient center and focus; drag with Shift to " +"separate focus" +msgstr "" +"Centro y foco del gradiente radial; arrastre con Mayús " +"para separar el foco" + +#: ../../po/../src/gradient-drag.cpp:667 +#, c-format +msgid "" +"Gradient point shared by %d gradients; drag with Shift to " +"separate" +msgstr "" +"Punto de gradiente compartido por %d gradientes, arrastre con " +"Mayús para separar" + +#: ../../po/../src/helper/units.cpp:40 +msgid "Unit" +msgstr "Unidad" + +#: ../../po/../src/helper/units.cpp:40 +msgid "Units" +msgstr "Unidades" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Point" +msgstr "Punto" + +#: ../../po/../src/helper/units.cpp:41 +msgid "pt" +msgstr "pt" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Points" +msgstr "Puntos" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Pt" +msgstr "Pt" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Pixel" +msgstr "Pixel" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Pixels" +msgstr "Píxeles" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Px" +msgstr "Px" + +#. You can add new elements from this point forward +#: ../../po/../src/helper/units.cpp:44 ../share/extensions/straightseg.inx.h:2 +msgid "Percent" +msgstr "Porcentaje" + +#: ../../po/../src/helper/units.cpp:44 +msgid "Percents" +msgstr "Porcentajes" + +#: ../../po/../src/helper/units.cpp:45 +msgid "Millimeter" +msgstr "Milímetro" + +#: ../../po/../src/helper/units.cpp:45 +msgid "mm" +msgstr "mm" + +#: ../../po/../src/helper/units.cpp:45 +msgid "Millimeters" +msgstr "Milímetros" + +#: ../../po/../src/helper/units.cpp:46 +msgid "Centimeter" +msgstr "Centímetro" + +#: ../../po/../src/helper/units.cpp:46 +msgid "cm" +msgstr "cm" + +#: ../../po/../src/helper/units.cpp:46 +msgid "Centimeters" +msgstr "Centímetros" + +#: ../../po/../src/helper/units.cpp:47 +msgid "Meter" +msgstr "Metro" + +#: ../../po/../src/helper/units.cpp:47 +msgid "m" +msgstr "m" + +#: ../../po/../src/helper/units.cpp:47 +msgid "Meters" +msgstr "Metros" + +#. no svg_unit +#: ../../po/../src/helper/units.cpp:48 +msgid "Inch" +msgstr "Pulgadas" + +#: ../../po/../src/helper/units.cpp:48 +msgid "in" +msgstr "pulgadas" + +#: ../../po/../src/helper/units.cpp:48 +msgid "Inches" +msgstr "Pulgadas" + +#. Volatiles do not have default, so there are none here +#. TRANSLATORS: for info, see http://www.w3.org/TR/REC-CSS2/syndata.html#length-units +#: ../../po/../src/helper/units.cpp:51 +msgid "Em square" +msgstr "Em cuadrado" + +#: ../../po/../src/helper/units.cpp:51 +msgid "em" +msgstr "em" + +#: ../../po/../src/helper/units.cpp:51 +msgid "Em squares" +msgstr "Em cuadrados" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/REC-CSS2/syndata.html#length-units +#: ../../po/../src/helper/units.cpp:53 +msgid "Ex square" +msgstr "Ex cuadrado" + +#: ../../po/../src/helper/units.cpp:53 +msgid "ex" +msgstr "ex" + +#: ../../po/../src/helper/units.cpp:53 +msgid "Ex squares" +msgstr "Ex cuadrados" + +#: ../../po/../src/inkscape.cpp:468 +msgid "Untitled document" +msgstr "Documento sin nombre" + +#. Show nice dialog box +#: ../../po/../src/inkscape.cpp:497 +msgid "Inkscape encountered an internal error and will close now.\n" +msgstr "Inkscape ha encontrado un error interno y se cerrará.\n" + +#: ../../po/../src/inkscape.cpp:498 +msgid "" +"Automatic backups of unsaved documents were done to the following " +"locations:\n" +msgstr "" +"Las copias de seguridad automáticas se realizaron en los siguientes " +"lugares:\n" + +#: ../../po/../src/inkscape.cpp:499 +msgid "Automatic backup of the following documents failed:\n" +msgstr "Ha fallado la copia de seguridad de los siguientes documentos:\n" + +#: ../../po/../src/inkscape.cpp:634 +#, c-format +msgid "" +"Cannot create directory %s.\n" +"%s" +msgstr "" +"No se puede crear el directorio %s.\n" +"%s" + +# dld: src/inkscape.cpp:1201 +#: ../../po/../src/inkscape.cpp:635 +#, c-format +msgid "" +"%s is not a valid directory.\n" +"%s" +msgstr "" +"%s no es un directorio válido.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:636 +#, c-format +msgid "" +"Cannot create file %s.\n" +"%s" +msgstr "" +"No se puede crear el archivo %s.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:637 +#, c-format +msgid "" +"Cannot write file %s.\n" +"%s" +msgstr "" +"No se puede escribir el archivo %s.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:638 +msgid "" +"Although Inkscape will run, it will use default settings,\n" +"and any changes made in preferences will not be saved." +msgstr "" +"Aunque Inkscape se ejecutará, usará la configuración predeterminada\n" +"y no se guardarán los cambios que se realicen en las preferencias." + +#: ../../po/../src/inkscape.cpp:708 +#, c-format +msgid "" +"%s is not a regular file.\n" +"%s" +msgstr "" +"%s no es un archivo normal.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:709 +#, c-format +msgid "" +"%s not a valid XML file, or\n" +"you don't have read permissions on it.\n" +"%s" +msgstr "" +"%s no es un archivo XML válido, o\n" +"no tiene permisos de lectura.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:711 +#, c-format +msgid "" +"%s is not a valid menus file.\n" +"%s" +msgstr "" +"%s no es un archivo de menús válido.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:712 +msgid "" +"Inkscape will run with default menus.\n" +"New menus will not be saved." +msgstr "" +"Se ejecutará Inkscape con los menús predeterminados.\n" +"No se guardarán nuevos menús." + +#. sp_ui_menu_append_check_item_from_verb(m, view, _("_Menu"), _("Show or hide the menu bar"), "menu", +#. checkitem_toggled, checkitem_update, 0); +#: ../../po/../src/interface.cpp:753 +msgid "Commands Bar" +msgstr "Barra de comandos" + +#: ../../po/../src/interface.cpp:753 +msgid "Show or hide the Commands bar (under the menu)" +msgstr "Mostrar u ocultar la barra de comandos (bajo el menú)" + +#: ../../po/../src/interface.cpp:755 +msgid "Tool Controls" +msgstr "Controles de herramienta" + +#: ../../po/../src/interface.cpp:755 +msgid "Show or hide the Tool Controls panel" +msgstr "Mostrar u ocultar la barra de controles" + +#: ../../po/../src/interface.cpp:757 +msgid "_Toolbox" +msgstr "Caja de herramien_tas" + +#: ../../po/../src/interface.cpp:757 +msgid "Show or hide the main toolbox (on the left)" +msgstr "Mostrar u ocultar la caja de herramientas principal (a la izquierda)" + +#: ../../po/../src/interface.cpp:763 +msgid "_Statusbar" +msgstr "Barra de e_stado" + +#: ../../po/../src/interface.cpp:763 +msgid "Show or hide the statusbar (at the bottom of the window)" +msgstr "Mostrar u ocultar la barra de estado (abajo en la ventana)" + +#: ../../po/../src/interface.cpp:820 +#, c-format +msgid "Verb \"%s\" Unknown" +msgstr "Verbo «%s» desconocido" + +#. TRANSLATORS: #%s is the id of the group e.g. , not a number. +#: ../../po/../src/interface.cpp:930 +#, c-format +msgid "Enter group #%s" +msgstr "Entrar en el grupo #%s" + +#: ../../po/../src/interface.cpp:941 +msgid "Go to parent" +msgstr "Ir al padre" + +#: ../../po/../src/interface.cpp:972 +msgid "Could not parse SVG data" +msgstr "No se pudieron interpretar los datos SVG" + +#: ../../po/../src/interface.cpp:1135 +#, c-format +msgid "Overwrite %s" +msgstr "Sobrescribir %s" + +#: ../../po/../src/interface.cpp:1153 +#, c-format +msgid "" +"The file %s already exists. Do you want to overwrite that file with the " +"current document?" +msgstr "" +"El archivo %s ya existe. ¿Desea sobrescribir ese archivo con el documento " +"actual?" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:59 +msgid "Jabber connection lost." +msgstr "Se ha perdido la conexión Jabber." + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:72 +#, c-format +msgid "Sending message; %u message remaining in send queue." +msgid_plural "Sending message; %u messages remaining in send queue." +msgstr[0] "Enviando mensaje; %u mensaje pendiente en la cola de envío." +msgstr[1] "Enviando mensaje; %u mensajes pendientes en la cola de envío." + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:78 +msgid "Receive queue empty." +msgstr "Cola de recepción vacía." + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:154 +#, c-format +msgid "Receiving change; %u change left to process." +msgid_plural "Receiving change; %u changes left to process." +msgstr[0] "Recibiendo cambio; %u cambio pendiente de procesar." +msgstr[1] "Recibiendo cambio; %u cambios pendientes de procesar." + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:157 +#, c-format +msgid "%s has left the chatroom." +msgstr "%s ha dejado la sala." + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:221 +msgid "Nickname %1 is already in use. Please choose a different nickname." +msgstr "El apodo %1 ya está siendo utilizado. Elija un apodo distinto." + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:225 +msgid "An error was encountered while attempting to connect to the server." +msgstr "Se ha producido un error durante el intento de conexión al servidor." + +#. Check to see if the user made any modifications to this document. If so, +#. we want to give them the option of (1) letting us clear their document or (2) +#. opening a new, blank document for the whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:131 +msgid "%1 has invited you to a whiteboard session." +msgstr "%1 le ha invitado a una sesión de pizarra blanca." + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:132 +msgid "Incoming whiteboard invitation from %1" +msgstr "Invitación de pizarra blanca entrante de %1" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:135 +msgid "Do you wish to accept %1's whiteboard session invitation?" +msgstr "" +"¿Desea aceptar la invitación a la sesión de pizarra blanca de %1?" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:137 +msgid "" +"Would you like to accept %1's invitation in a new document window?\n" +"Accepting the invitation in your current window will discard unsaved changes." +msgstr "" +"¿Desea aceptar la invitación de %1 en una ventana de documento nuevo?\n" +"Si acepta la invitación en su ventana actual perderá los cambios que no ha " +"guardado." + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:143 +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:198 +msgid "Accept invitation" +msgstr "Aceptar invitación" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:144 +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:199 +msgid "Decline invitation" +msgstr "Rechazar invitación" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:145 +msgid "Accept invitation in new document window" +msgstr "Aceptar la invitación en una ventana de documento nuevo" + +#. We could not create a new desktop; ask the user if she or he wants to +#. replace the current document and accept the invitation, or reject the invitation. +#. TRANSLATORS: %1 is a userid here +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:196 +msgid "" +"A new document window could not be opened for a whiteboard session with %" +"1" +msgstr "" +"No se ha podido abrir una ventana de documento nuevo para una sesión de " +"pizarra blanca con %1" + +#. TRANSLATORS: %1 is the peer whom refused our invitation. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:238 +msgid "" +"The user %1 has refused your " +"whiteboard invitation.\n" +"\n" +msgstr "" +"El usuario %1 ha rechazado su " +"invitación de pizarra blanca.\n" +"\n" + +#. TRANSLATORS: %1 is the peer whom refused our invitation, %2 is our Jabber identity. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:241 +msgid "" +"You are still connected to a Jabber server as %2, and may send an " +"invitation to %1 again, or you may send an invitation to a different " +"user." +msgstr "" +"Todavía está conectado al servidor Jabber como %2 y puede volver a " +"enviar una invitación a %1, también puede enviar una invitación a un " +"usuario distinto." + +#. TRANSLATORS: %1 is the peer whom we tried to contact, but is already in a whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:252 +msgid "" +"The user %1 is already in a " +"whiteboard session.\n" +"\n" +msgstr "" +"El usuario %1 ya está en una " +"sesión de pizarra blanca.\n" +"\n" + +#. TRANSLATORS: %1 is the peer whom we tried to contact, but is already in a whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:255 +msgid "" +"You are still connected to a Jabber server as %1, and may send an " +"invitation to a different user." +msgstr "" +"Todavía está conectado a un servidor Jabber como %1 y puede enviar " +"una invitación a otro usuario." + +#: ../../po/../src/jabber_whiteboard/invitation-confirm-dialog.cpp:26 +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:24 +msgid "_Write session file:" +msgstr "_Guardar archivo de sesión:" + +#: ../../po/../src/jabber_whiteboard/message-processors.cpp:145 +#, c-format +msgid "%s has joined the chatroom." +msgstr "%s se ha unido a la sala de chat." + +#: ../../po/../src/jabber_whiteboard/message-queue.cpp:87 +#, c-format +msgid "%u change in receive queue." +msgid_plural "%u changes in receive queue." +msgstr[0] "%u cambio en la cola de recepción." +msgstr[1] "%u cambios en la cola de recepción." + +#: ../../po/../src/jabber_whiteboard/message-queue.cpp:117 +#, c-format +msgid "%u change in send queue." +msgid_plural "%u changes in send queue." +msgstr[0] "%u cambio en la lista de envíos." +msgstr[1] "%u cambios en la lista de envíos." + +#. if ID is NULL, then we have a real problem -- we were not able to find a key +#. nor generate one. The only thing we can really do here is abort, since we have +#. no way to let the other client(s) uniquely identify this object. +#. FIXME: If this indicates a programming bug, then don't request translation with +#. * _(...): it is most useful in untranslated form so that developers may search for +#. * it when someone reports it in a bug report (as we want users to do for all bugs, +#. * as indicated by it being a g_warning string). +#. * +#. * Otherwise, if it is not a programming bug but a network error or a bug in the +#. * remote peer (perhaps running different software) or whatever, then present it in +#. * an alert box, and avoid use of technical jargon `NULL'. +#. +#: ../../po/../src/jabber_whiteboard/message-utilities.cpp:171 +msgid "" +"ID for new object is NULL even after generation and lookup attempts: the new " +"object will NOT be sent, nor will any of its child objects!" +msgstr "" +"El ID para el objeto nuevo es NULL aún después de los intentos de " +"localización y generación: el objeto nuevo NO se enviará, ni tampoco ninguno " +"de sus objetos hijo." + +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:60 +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:995 +msgid "Select a location and filename" +msgstr "Seleccione una localización y nombre de archivo" + +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:62 +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:997 +msgid "Set filename" +msgstr "Ajustar el nombre de archivo" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:301 +msgid "No SSL certificate was found." +msgstr "No se ha encontrado ningún certificado SSL." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:304 +msgid "The SSL certificate provided by the Jabber server is untrusted." +msgstr "El certificado SSL proporcionado por el servidor Jabber no es fiable." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:307 +msgid "The SSL certificate provided by the Jabber server is expired." +msgstr "El certificado SSL proporcionado por el servidor Jabber está caducado." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:310 +msgid "" +"The SSL certificate provided by the Jabber server has not been activated." +msgstr "" +"El certificado SSL proporcionado por el servidor Jabber no ha sido activado." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:313 +msgid "" +"The SSL certificate provided by the Jabber server contains a hostname that " +"does not match the Jabber server's hostname." +msgstr "" +"El certificado SSL proporcionado por el servidor Jabber contiene un nombre " +"de host que no se corresponde con el nombre del servidor Jabber." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:316 +msgid "" +"The SSL certificate provided by the Jabber server contains an invalid " +"fingerprint." +msgstr "" +"El certificado SSL proporcionado por el servidor Jabber contiene una huella " +"inválida." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:319 +msgid "An unknown error occurred while setting up the SSL connection." +msgstr "Ha ocurrido un error desconocido al configurar la conexión SSL." + +#. TRANSLATORS: %1 is the message that describes the specific error that occurred when +#. establishing the SSL connection. +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:325 +msgid "" +"%1\n" +"\n" +"Do you wish to continue connecting to the Jabber server?" +msgstr "" +"%1\n" +"\n" +"¿Desea seguir con la conexión al servidor Jabber?" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:328 +msgid "Continue connecting and ignore further errors" +msgstr "Continuar la conexión e ignorar errores futuros" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:329 +msgid "Continue connecting, but warn me of further errors" +msgstr "Continuar la conexión, pero avisarme de los errores" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:330 +msgid "Cancel connection" +msgstr "Cancelar la conexión" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:777 +#, c-format +msgid "Established whiteboard session with %s." +msgstr "Se ha establecido una sesión de pizarra blanca con %s." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:785 +#, c-format +msgid "%s has left the whiteboard session." +msgstr "%s ha abandonado la sesión de pizarra blanca." + +#. Inform the user +#. TRANSLATORS: %1 is the name of the user that disconnected, %2 is the name of the user whom the disconnected user disconnected from. +#. This message is not used in a chatroom context. +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:790 +msgid "" +"The user %1 has left the " +"whiteboard session.\n" +"\n" +msgstr "" +"El usuario %1 ha abandonado la " +"sesión de pizarra blanca.\n" +"\n" + +#. TRANSLATORS: %1 and %2 are userids +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:792 +msgid "" +"You are still connected to a Jabber server as %2, and may establish a " +"new session to %1 or a different user." +msgstr "" +"Todavía está conectado un servidor Jabber como %2 y puede establecer " +"una nueva sesión con %1 u otro usuario." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:988 +msgid "" +"Could not open file %1 for session recording.\n" +"The error encountered was: %2.\n" +"\n" +"You may select a different location to record the session, or you may opt to " +"not record this session." +msgstr "" +"No se puede abrir el archivo %1 para el registro de la sesión.\n" +"Se ha encontrado el siguiente error: %s.\n" +"\n" +"Puede elegir un lugar distinto para registrar la sesión o puede elegir no " +"registrar esta sesión." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:990 +msgid "Choose a different location" +msgstr "Seleccionar un lugar distinto" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:991 +msgid "Skip session recording" +msgstr "No registrar la sesión" + +#: ../../po/../src/knot.cpp:673 +msgid "Node or handle drag canceled." +msgstr "Se ha cancelado el arrastre de nodo o tirador." + +#: ../../po/../src/libnrtype/FontFactory.cpp:358 +msgid "Ignoring font without family that will crash Pango" +msgstr "Se ignorará una familia de tipografías que detendría a Pango." + +#: ../../po/../src/main.cpp:395 +msgid "Print the Inkscape version number" +msgstr "Mostrar el número de versión de Inkscape" + +#: ../../po/../src/main.cpp:400 +msgid "Do not use X server (only process files from console)" +msgstr "No utilizar el servidor X (sólo procesa archivos desde la consola)" + +#: ../../po/../src/main.cpp:405 +msgid "Try to use X server (even if $DISPLAY is not set)" +msgstr "Intentar utilizar el servidor X aunque no se haya definido $DISPLAY" + +#: ../../po/../src/main.cpp:410 +msgid "Open specified document(s) (option string may be excluded)" +msgstr "" +"Abrir los documentos especificados (se pueden excluir las opciones de cadena)" + +#: ../../po/../src/main.cpp:411 ../../po/../src/main.cpp:416 +#: ../../po/../src/main.cpp:421 ../../po/../src/main.cpp:483 +#: ../../po/../src/main.cpp:488 ../../po/../src/main.cpp:493 +msgid "FILENAME" +msgstr "NOMBRE DE ARCHIVO" + +#: ../../po/../src/main.cpp:415 +msgid "Print document(s) to specified output file (use '| program' for pipe)" +msgstr "" +"Imprimir documentos en el archivo de salida especificado (utilice «| " +"programa» para el filtro)" + +#: ../../po/../src/main.cpp:420 +msgid "Export document to a PNG file" +msgstr "Exportar el documento como archivo png" + +#: ../../po/../src/main.cpp:425 +msgid "The resolution used for exporting SVG into bitmap (default 90)" +msgstr "" +"La resolución utilizada para exportar de SVG a mapa de bits (predeterminado " +"90)" + +#: ../../po/../src/main.cpp:426 +msgid "DPI" +msgstr "PPP" + +#: ../../po/../src/main.cpp:430 +msgid "" +"Exported area in SVG user units (default is the canvas; 0,0 is lower-left " +"corner)" +msgstr "" +"El área exportada en unidades de usuario SVG (por defecto es el lienzo " +"completo, 0,0 es la esquina inferior izquierda)" + +#: ../../po/../src/main.cpp:431 +msgid "x0:y0:x1:y1" +msgstr "x0:y0:x1:y1" + +#: ../../po/../src/main.cpp:435 +msgid "Exported area is the entire drawing (not canvas)" +msgstr "El área exportada es el dibujo completo (no el lienzo)" + +#: ../../po/../src/main.cpp:440 +msgid "" +"Snap the bitmap export area outwards to the nearest integer values (in SVG " +"user units)" +msgstr "" +"Ajustar el área de exportación del mapa de bits hacia afuera hasta los " +"valores enteros más próximos (en unidades de usuario SVG)" + +#: ../../po/../src/main.cpp:445 +msgid "The width of exported bitmap in pixels (overrides export-dpi)" +msgstr "" +"El ancho del mapa de bits generado en píxeles (sobreescribe ppp de " +"exportación)" + +#: ../../po/../src/main.cpp:446 +msgid "WIDTH" +msgstr "ANCHO" + +#: ../../po/../src/main.cpp:450 +msgid "The height of exported bitmap in pixels (overrides export-dpi)" +msgstr "" +"La altura del mapa de bits generado en píxeles (sobreescribe ppp de " +"exportación)" + +#: ../../po/../src/main.cpp:451 +msgid "HEIGHT" +msgstr "ALTO" + +#: ../../po/../src/main.cpp:455 +msgid "The ID of the object to export (overrides export-area)" +msgstr "El ID del objeto que se exportará (sobreescribe área de exportación)" + +#: ../../po/../src/main.cpp:456 ../../po/../src/main.cpp:532 +msgid "ID" +msgstr "ID" + +#. TRANSLATORS: this means: "Only export the object whose id is given in --export-id". +#. See "man inkscape" for details. +#: ../../po/../src/main.cpp:462 +msgid "" +"Export just the object with export-id, hide all others (only with export-id)" +msgstr "" +"Exportar solamente el objeto con el export-id, ocultar todos los demás " +"(solamente con export-id)" + +#: ../../po/../src/main.cpp:467 +msgid "Use stored filename and DPI hints when exporting (only with export-id)" +msgstr "" +"Usar el nombre del archivo y pistas de DPI al exportar (solamente con export-" +"id)" + +#: ../../po/../src/main.cpp:472 +msgid "Background color of exported bitmap (any SVG-supported color string)" +msgstr "" +"Color de fondo del mapa de bits exportado (cualquier cadena de color " +"admitida por SVG)" + +#: ../../po/../src/main.cpp:473 +msgid "COLOR" +msgstr "COLOR" + +#: ../../po/../src/main.cpp:477 +msgid "Background opacity of exported bitmap (either 0.0 to 1.0, or 1 to 255)" +msgstr "" +"Opacidad de fondo del mapa de bits exportado (entre 0.0 y 1.0, ó entre 1 y " +"255)" + +#: ../../po/../src/main.cpp:478 +msgid "VALUE" +msgstr "VALOR" + +#: ../../po/../src/main.cpp:482 +msgid "Export document to plain SVG file (no sodipodi or inkscape namespaces)" +msgstr "" +"Exportar el documento a un archivo SVG plano (sin nombre de espacio sodipodi " +"o inkscape)" + +#: ../../po/../src/main.cpp:487 +msgid "Export document to a PS file" +msgstr "Exportar el documento a un archivo PS" + +#: ../../po/../src/main.cpp:492 +msgid "Export document to an EPS file" +msgstr "Exportar el documento a un archivo EPS" + +#: ../../po/../src/main.cpp:497 +msgid "Convert text object to paths on export (EPS)" +msgstr "Convertir el texto a trazos al exportar (EPS)" + +#: ../../po/../src/main.cpp:502 +msgid "Export files with the bounding box set to the page size (EPS)" +msgstr "" +"Exportar los archivos con la caja de contorno al tamaño de la página (EPS)" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:508 +msgid "" +"Query the X coordinate of the drawing or, if specified, of the object with --" +"query-id" +msgstr "" +"Consultar la coordenada X del dibujo o, si se indica, del objeto con «--" +"query-id»" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:514 +msgid "" +"Query the Y coordinate of the drawing or, if specified, of the object with --" +"query-id" +msgstr "" +"Consultar la coordenada Y del dibujo o, si se indica, del objeto con «--" +"query-id»" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:520 +msgid "" +"Query the width of the drawing or, if specified, of the object with --query-" +"id" +msgstr "" +"Consultar la anchura del dibujo o, si se indica, del objeto con «--query-id»" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:526 +msgid "" +"Query the height of the drawing or, if specified, of the object with --query-" +"id" +msgstr "" +"Consultar la altura del dibujo o, si se indica, del objeto con «--query-id»" + +#: ../../po/../src/main.cpp:531 +msgid "The ID of the object whose dimensions are queried" +msgstr "El ID del objeto cuyas dimensiones se consultan" + +#. TRANSLATORS: this option makes Inkscape print the name (path) of the extension directory +#: ../../po/../src/main.cpp:537 +msgid "Print out the extension directory and exit" +msgstr "Mostrar el directorio de extensiones y terminar" + +#: ../../po/../src/main.cpp:542 +msgid "Show given files one-by-one, switch to next on any key/mouse event" +msgstr "" +"Mostrar los archivos uno por uno, cambiar al siguiente al pulsar una tecla o " +"el ratón" + +#: ../../po/../src/main.cpp:547 +msgid "Use the new Gtkmm GUI interface" +msgstr "Usar la nueva interfaz GUI Gtkmm" + +#: ../../po/../src/main.cpp:552 +msgid "Remove unused definitions from the defs section(s) of the document" +msgstr "" +"Eliminar definiciones no utilizadas de las secciones «defs» del documento" + +#: ../../po/../src/main.cpp:741 +msgid "" +"[OPTIONS...] [FILE...]\n" +"\n" +"Available options:" +msgstr "" +"[OPTIONS...] [FILE...]\n" +"\n" +"Opciones disponibles:" + +#: ../../po/../src/menus-skeleton.h:17 +msgid "_New" +msgstr "_Nuevo" + +#: ../../po/../src/menus-skeleton.h:22 +msgid "Open _Recent" +msgstr "Abrir _reciente" + +#: ../../po/../src/menus-skeleton.h:53 +msgid "_Edit" +msgstr "_Edición" + +#: ../../po/../src/menus-skeleton.h:84 +msgid "_View" +msgstr "_Ver" + +#: ../../po/../src/menus-skeleton.h:85 +#, fuzzy +msgid "_Zoom" +msgstr "Zoom" + +#: ../../po/../src/menus-skeleton.h:102 +msgid "Show/Hide" +msgstr "Mostrar/ocultar" + +#: ../../po/../src/menus-skeleton.h:107 +msgid "_Display mode" +msgstr "" + +#: ../../po/../src/menus-skeleton.h:126 +msgid "_Layer" +msgstr "_Capa" + +#: ../../po/../src/menus-skeleton.h:143 +msgid "_Object" +msgstr "_Objeto" + +#: ../../po/../src/menus-skeleton.h:165 +msgid "_Path" +msgstr "_Trazo" + +#: ../../po/../src/menus-skeleton.h:188 +msgid "_Text" +msgstr "_Texto" + +#: ../../po/../src/menus-skeleton.h:200 +msgid "Effects" +msgstr "Efectos" + +#: ../../po/../src/menus-skeleton.h:207 +msgid "Whiteboa_rd" +msgstr "Piza_rra blanca" + +#: ../../po/../src/menus-skeleton.h:220 +msgid "_Help" +msgstr "A_yuda" + +#: ../../po/../src/menus-skeleton.h:222 +msgid "Tutorials" +msgstr "Tutoriales" + +#: ../../po/../src/node-context.cpp:382 +msgid "" +"Ctrl: toggle node type, snap handle angle, move hor/vert; Ctrl" +"+Alt: move along handles" +msgstr "" +"Ctrl: conmutar el tipo de nodo, ajustar el ángulo del tirador, mover " +"hor/vert; Ctrl+Alt: mover a lo largo de los tiradores" + +#: ../../po/../src/node-context.cpp:383 +msgid "" +"Shift: toggle node selection, disable snapping, rotate both handles" +msgstr "" +"Mayús: para conmutar a selección de nodos, desactivar ajuste, rotar " +"ambos tiradores." + +#: ../../po/../src/node-context.cpp:384 +msgid "Alt: lock handle length; Ctrl+Alt: move along handles" +msgstr "" +"Alt: bloquear longitud de tirador; Ctrl+Alt: mover a lo largo " +"del tirador" + +#: ../../po/../src/nodepath.cpp:1399 ../../po/../src/nodepath.cpp:1411 +#: ../../po/../src/nodepath.cpp:1492 ../../po/../src/nodepath.cpp:1504 +msgid "To join, you must have two endnodes selected." +msgstr "Debe seleccionar dos nodos finales para unirlos." + +#: ../../po/../src/nodepath.cpp:1633 ../../po/../src/nodepath.cpp:1647 +msgid "" +"Select two non-endpoint nodes on a path between which to delete " +"segments." +msgstr "" +"Debe seleccionar dos nodos no finales entre los que eliminar " +"segmentos." + +#: ../../po/../src/nodepath.cpp:1743 +msgid "Cannot find path between nodes." +msgstr "No se ha encontrado un trazo entre los nodos." + +#: ../../po/../src/nodepath.cpp:2822 +#, c-format +msgid "" +"Node handle: angle %0.2f°, length %s; with Ctrl to snap " +"angle; with Alt to lock length; with Shift to rotate both " +"handles" +msgstr "" +"Tirador de nodo: ángulo %0.2f°, longitud %s; con Ctrl " +"para ajustar al ángulo; con Alt para bloquear la longitud, con " +"Mayús para girar ambos tiradores" + +#: ../../po/../src/nodepath.cpp:3351 +msgid "" +"Node: drag to edit the path; with Ctrl to snap to horizontal/" +"vertical; with Ctrl+Alt to snap to handles' directions" +msgstr "" +"Nodo: arrastre para editar el trazo; con Ctrl para ajustar a " +"la horizontal/vertical; con Ctrl+Alt para ajustar a las direcciones " +"de los tiradores" + +#: ../../po/../src/nodepath.cpp:3375 +msgid "" +"Node handle: drag to shape the curve; with Ctrl to snap angle; " +"with Alt to lock length; with Shift to rotate both handles" +msgstr "" +"Tirador de nodo: arrastre para dar forma a la curva; con Ctrl " +"para ajustar al ángulo; con Alt para mantener la longitud, con " +"Mayús para girar ambos tiradores" + +#: ../../po/../src/nodepath.cpp:3399 +msgid "" +"Node handle: drag to shape the curve; with Ctrl to snap angle; " +"with Alt to lock length; with Shift to rotate the opposite " +"handle in sync" +msgstr "" +"Tirador de nodo: arrastre para dar forma a la curva; con Ctrl " +"para ajustar al ángulo; con Alt para bloquear la longitud, con " +"Mayús para sincronizar la rotación el tirador opuesto" + +#. TRANSLATORS: "end" is an adjective here (NOT a verb) +#: ../../po/../src/nodepath.cpp:3591 +msgid "end node" +msgstr "nodo final" + +#. TRANSLATORS: "cusp" means "sharp" (cusp node); see also the Advanced Tutorial +#: ../../po/../src/nodepath.cpp:3596 +msgid "cusp" +msgstr "agudo" + +#. TRANSLATORS: "smooth" is an adjective here +#: ../../po/../src/nodepath.cpp:3599 +msgid "smooth" +msgstr "suave" + +#: ../../po/../src/nodepath.cpp:3601 +msgid "symmetric" +msgstr "simétrico" + +#. TRANSLATORS: "end" is an adjective here (NOT a verb) +#: ../../po/../src/nodepath.cpp:3607 +msgid "end node, handle retracted (drag with Shift to extend)" +msgstr "" +"nodo final, tirador retraído (arrastre con Mayús para extenderlo)" + +#: ../../po/../src/nodepath.cpp:3609 +msgid "one handle retracted (drag with Shift to extend)" +msgstr "un tirador retraído (arrastre con Mayús para extenderlo)" + +#: ../../po/../src/nodepath.cpp:3612 +msgid "both handles retracted (drag with Shift to extend)" +msgstr "ambos tiradores retraídos (arrastre con Mayús para extenderlos)" + +#: ../../po/../src/nodepath.cpp:3624 +msgid "Drag nodes or node handles; arrow keys to move nodes" +msgstr "" +"Arrastre los nodos o tiradores del nodo; use las teclas de flecha para moverlos" + +#: ../../po/../src/nodepath.cpp:3625 +msgid "Drag the node or its handles; arrow keys to move the node" +msgstr "" +"Arrastre el nodo o sus tiradores, use las teclas de flecha " +"para moverlo" + +#: ../../po/../src/nodepath.cpp:3651 ../../po/../src/nodepath.cpp:3663 +msgid "Select a single object to edit its nodes or handles." +msgstr "Seleccione un objeto para editar sus nodos o tiradores." + +#: ../../po/../src/nodepath.cpp:3655 +#, c-format +msgid "" +"0 out of %i node selected. Click, Shift+click, " +"or drag around nodes to select." +msgid_plural "" +"0 out of %i nodes selected. Click, Shift+click, " +"or drag around nodes to select." +msgstr[0] "" +"Seleccionados 0 de %i nodo. Clic, Mayús+clic o " +"arrastre alrededor de nodos para seleccionarlos." +msgstr[1] "" +"Seleccionados 0 de %i nodos. Clic, Mayús+clic o " +"arrastre alrededor de nodos para seleccionarlos." + +#: ../../po/../src/nodepath.cpp:3661 +msgid "Drag the handles of the object to modify it." +msgstr "Arrastre los tiradores del objeto para modificarlo." + +#: ../../po/../src/nodepath.cpp:3669 +#, c-format +msgid "%i of %i node selected; %s. %s." +msgid_plural "%i of %i nodes selected; %s. %s." +msgstr[0] "%i de %i nodo seleccionado; %s. %s." +msgstr[1] "%i de %i nodos seleccionados; %s. %s." + +#: ../../po/../src/nodepath.cpp:3675 +#, c-format +msgid "%i of %i node selected. %s." +msgid_plural "%i of %i nodes selected. %s." +msgstr[0] "%i de %i nodo seleccionado. %s." +msgstr[1] "%i de %i nodos seleccionados. %s." + +#: ../../po/../src/object-edit.cpp:493 +msgid "" +"Adjust the horizontal rounding radius; with Ctrl to make the " +"vertical radius the same" +msgstr "" +"Ajustar el radio de redondeo horizontal; con Ctrl para " +"coordinar con el radio vertical" + +#: ../../po/../src/object-edit.cpp:499 +msgid "" +"Adjust the vertical rounding radius; with Ctrl to make the " +"horizontal radius the same" +msgstr "" +"Ajustar el radio de redondeo vertical; con Ctrl para coordinar " +"con el radio horizontal" + +#: ../../po/../src/object-edit.cpp:506 ../../po/../src/object-edit.cpp:513 +msgid "" +"Adjust the width and height of the rectangle; with Ctrl to " +"lock ratio or stretch in one dimension only" +msgstr "" +"Ajustar el alto y el ancho del rectángulo; con Ctrl para " +"bloquear la proporción o estirar en una sola dirección" + +#: ../../po/../src/object-edit.cpp:686 +msgid "Adjust ellipse width, with Ctrl to make circle" +msgstr "" +"Ajustar el ancho de la elipse; con Ctrl para hacer un círculo" + +#: ../../po/../src/object-edit.cpp:689 +msgid "Adjust ellipse height, with Ctrl to make circle" +msgstr "" +"Ajustar el alto y el ancho del rectángulo; con Ctrl para " +"bloquear la proporción" + +#: ../../po/../src/object-edit.cpp:692 +msgid "" +"Position the start point of the arc or segment; with Ctrl to " +"snap angle; drag inside the ellipse for arc, outside for " +"segment" +msgstr "" +"Sitúe el punto de inicio del arco o segmento; con Ctrl para " +"ajustar el ángulo; arrastre por dentro para obtener la elipse del " +"arco, por fuera para el segmento" + +#: ../../po/../src/object-edit.cpp:695 +msgid "" +"Position the end point of the arc or segment; with Ctrl to " +"snap angle; drag inside the ellipse for arc, outside for " +"segment" +msgstr "" +"Sitúe el punto final del arco o segmento; con Ctrl para " +"ajustar el ángulo; arrastre por dentro para obtener la elipse del " +"arco, por fuera para el segmento" + +#: ../../po/../src/object-edit.cpp:800 +msgid "" +"Adjust the tip radius of the star or polygon; with Shift to " +"round; with Alt to randomize" +msgstr "" +"Ajusta el radio base de la estrella o polígono; con Ctrl para " +"redondear; con Alt para aleatorizar" + +#: ../../po/../src/object-edit.cpp:803 +msgid "" +"Adjust the base radius of the star; with Ctrl to keep star " +"rays radial (no skew); with Shift to round; with Alt to " +"randomize" +msgstr "" +"Ajusta el radio base de la estrella; con Ctrl para mantener " +"los rayos de la estrella radiales (sin inclinación); con Mayús para " +"redondear, con Alt para aleatorizar" + +# fixme: CTRL SNAP!!! remove "skew and scale" +#: ../../po/../src/object-edit.cpp:967 +msgid "" +"Roll/unroll the spiral from inside; with Ctrl to snap angle; " +"with Alt to converge/diverge" +msgstr "" +"Enrollar/desenrollar la espiral desde dentro; con Ctrl para " +"ajustar al ángulo; con Alt para converger/divergir" + +# fixme: CTRL SNAP!!! remove "skew and scale" +#: ../../po/../src/object-edit.cpp:969 +msgid "" +"Roll/unroll the spiral from outside; with Ctrl to snap angle; " +"with Shift to scale/rotate" +msgstr "" +"Enrollar/desenrollar la espiral desde fuera; con Ctrl para " +"ajustar al ángulo; con Mayús para escalar/rotar" + +#: ../../po/../src/object-edit.cpp:1006 +msgid "Adjust the offset distance" +msgstr "Ajustar la distancia de desvío" + +#. TRANSLATORS: This refers to the pattern that's inside the object +#: ../../po/../src/object-edit.cpp:1036 +msgid "Move the pattern fill inside the object" +msgstr "Mover el relleno de mosaico dentro del objeto" + +#: ../../po/../src/object-edit.cpp:1038 +msgid "Scale the pattern fill uniformly" +msgstr "Escalar el relleno de mosaico uniformemente" + +#: ../../po/../src/object-edit.cpp:1040 +msgid "Rotate the pattern fill; with Ctrl to snap angle" +msgstr "" +"Rotar el relleno de mosaico; con Ctrl para ajustar el ángulo" + +#: ../../po/../src/object-edit.cpp:1065 +msgid "Drag to resize the flowed text frame" +msgstr "Arrastre para redimensionar el marco de texto fluido" + +#. Item dialog +#: ../../po/../src/object-ui.cpp:106 +msgid "Object _Properties" +msgstr "_Propiedades del objeto" + +#. Select item +#: ../../po/../src/object-ui.cpp:116 +msgid "_Select This" +msgstr "_Seleccionar esto" + +#. Create link +#: ../../po/../src/object-ui.cpp:126 +msgid "_Create Link" +msgstr "_Crear enlace" + +#. "Ungroup" +#: ../../po/../src/object-ui.cpp:199 ../../po/../src/verbs.cpp:1931 +msgid "_Ungroup" +msgstr "Desagr_upar" + +#. Link dialog +#: ../../po/../src/object-ui.cpp:239 +msgid "Link _Properties" +msgstr "_Propiedades del enlace" + +#. Select item +#: ../../po/../src/object-ui.cpp:249 +msgid "_Follow Link" +msgstr "Se_guir enlace" + +#. Reset transformations +#: ../../po/../src/object-ui.cpp:254 +msgid "_Remove Link" +msgstr "_Eliminar enlace" + +#. Link dialog +#: ../../po/../src/object-ui.cpp:303 +msgid "Image _Properties" +msgstr "_Propiedades de la imagen" + +#. Item dialog +#: ../../po/../src/object-ui.cpp:344 +msgid "_Fill and Stroke" +msgstr "_Relleno y borde" + +#: ../../po/../src/path-chemistry.cpp:58 +msgid "Select at least two objects to combine." +msgstr "Seleccione por lo menos dos objetos para combinarlos." + +#: ../../po/../src/path-chemistry.cpp:65 +msgid "At least one of the objects is not a path, cannot combine." +msgstr "Uno de los objetos no es un trazo, no se pueden combinar." + +#: ../../po/../src/path-chemistry.cpp:73 +msgid "" +"You cannot combine objects from different groups or layers." +msgstr "No puede combinar objetos de diferentes grupos o capas." + +#: ../../po/../src/path-chemistry.cpp:155 +msgid "Select path(s) to break apart." +msgstr "Seleccione lostrazos que desea descombinar." + +#: ../../po/../src/path-chemistry.cpp:231 +msgid "No path(s) to break apart in the selection." +msgstr "No hay trazos descombinables en la selección." + +#: ../../po/../src/path-chemistry.cpp:252 +msgid "Select object(s) to convert to path." +msgstr "Seleccione los objetos que desea convertir en trazos." + +#: ../../po/../src/path-chemistry.cpp:297 +msgid "No objects to convert to path in the selection." +msgstr "" +"No hay objetos que se puedan convertir en trazos en la selección." + +#: ../../po/../src/path-chemistry.cpp:345 +msgid "Select path(s) to reverse." +msgstr "Seleccione los trazos que desea revertir." + +#: ../../po/../src/path-chemistry.cpp:370 +msgid "No paths to reverse in the selection." +msgstr "No hay trazos reversibles en la selección." + +#: ../../po/../src/pen-context.cpp:379 ../../po/../src/pencil-context.cpp:233 +msgid "Continuing selected path" +msgstr "Continuar el trazo seleccionado" + +#: ../../po/../src/pen-context.cpp:390 ../../po/../src/pencil-context.cpp:242 +msgid "Creating new path" +msgstr "Crear un trazo nuevo" + +#: ../../po/../src/pen-context.cpp:394 ../../po/../src/pencil-context.cpp:246 +msgid "Appending to selected path" +msgstr "Añadir al trazo seleccionado" + +#: ../../po/../src/pen-context.cpp:538 +msgid "Click or click and drag to close and finish the path." +msgstr "Haga clic o arrastre para cerrar y terminar el trazo." + +#: ../../po/../src/pen-context.cpp:548 +msgid "" +"Click or click and drag to continue the path from this point." +msgstr "" +"Haga clic o arrastre para continuar el trazo desde este punto." + +#: ../../po/../src/pen-context.cpp:857 +#, c-format +msgid "" +"%s: angle %3.2f°, distance %s; with Ctrl to snap angle, " +"Enter to finish the path" +msgstr "" +"%s: ángulo de %3.2f°,distancia %s; con Ctrl para ajustar " +"al ángulo; Enter para terminar el trazo" + +#: ../../po/../src/pen-context.cpp:882 +#, c-format +msgid "" +"Curve handle: angle %3.2f°, length %s; with Ctrl to snap " +"angle" +msgstr "" +"Tirador de curva: ángulo %3.2f°, longitud %s; con Ctrl " +"para ajustar el ángulo" + +#: ../../po/../src/pen-context.cpp:912 +#, c-format +msgid "" +"%s: angle %3.2f°, length %s; with Ctrl to snap angle, " +"with Shift to move this handle only" +msgstr "" +"%s: ángulo %3.2f°, longitud %s; con Ctrl para ajustar al " +"ángulo, con Mayús para mover solamente este tirador" + +#: ../../po/../src/pen-context.cpp:946 +msgid "Finishing pen" +msgstr "Terminando trazo" + +#: ../../po/../src/pencil-context.cpp:320 +msgid "Release here to close and finish the path." +msgstr "Suelte aquí para cerrar y terminar el trazo." + +#: ../../po/../src/pencil-context.cpp:326 +msgid "Drawing a freehand path" +msgstr "Dibujando una línea a mano alzada" + +#: ../../po/../src/pencil-context.cpp:331 +msgid "Drag to continue the path from this point." +msgstr "Arrastre para continuar el trazo desde este punto." + +#. Write curves to object +#: ../../po/../src/pencil-context.cpp:390 +msgid "Finishing freehand" +msgstr "Terminando mano alzada" + +#: ../../po/../src/rect-context.cpp:387 +msgid "" +"Ctrl: make square or integer-ratio rect, lock a rounded corner " +"circular" +msgstr "" +"Ctrl: crear cuadrado o rectángulo de proporción entera, bloquear una " +"esquina redondeada a circular" + +# fixme: CTRL SNAP!!! remove "skew and scale" +#: ../../po/../src/rect-context.cpp:549 +#, c-format +msgid "" +"Rectangle: %s × %s; with Ctrl to make square or integer-" +"ratio rectangle; with Shift to draw around the starting point" +msgstr "" +"Rectángulo: %s× %s; con Ctrl crear un cuadrado o un " +"rectángulo de proporción entera; con Mayús para dibujar alrededor del " +"punto inicial" + +#: ../../po/../src/select-context.cpp:243 +msgid "Move canceled." +msgstr "Movimiento cancelado." + +#: ../../po/../src/select-context.cpp:252 +msgid "Selection canceled." +msgstr "Selección cancelada." + +#: ../../po/../src/select-context.cpp:642 +msgid "Ctrl: select in groups, move hor/vert" +msgstr "Ctrl: seleccionar en grupos, mover hor/vert" + +#: ../../po/../src/select-context.cpp:643 +msgid "Shift: toggle select, force rubberband, disable snapping" +msgstr "" +"Mayús: intercambiar selección, forzar elástico, desactivar ajuste" + +#: ../../po/../src/select-context.cpp:644 +msgid "Alt: select under, move selected" +msgstr "Alt: seleccionar debajo, mover selección" + +#: ../../po/../src/select-context.cpp:798 +#, fuzzy +msgid "Selected object is not a group. Cannot enter." +msgstr "" +"El objeto seleccionado no es un trazo, no se puede reducir/ampliar." + +#: ../../po/../src/select-context.cpp:876 +#, c-format +msgid "" +"Move by %s, %s; with Ctrl to restrict to horizontal/vertical; " +"with Shift to disable snapping" +msgstr "" +"Mover: %s, %s; con Ctrl para restringir a la horizontal/" +"vertical; con Mayús para desactivar el ajuste" + +#: ../../po/../src/selection-chemistry.cpp:228 +msgid "Nothing was deleted." +msgstr "No se ha borrado nada." + +#: ../../po/../src/selection-chemistry.cpp:259 +msgid "Select object(s) to duplicate." +msgstr "Seleccione los objetos para duplicar." + +#: ../../po/../src/selection-chemistry.cpp:420 +msgid "Select two or more objects to group." +msgstr "Seleccione dos o más objetos para agrupar." + +#: ../../po/../src/selection-chemistry.cpp:428 +msgid "Select at least two objects to group." +msgstr "Seleccione por lo menos dos objetos para agrupar." + +#: ../../po/../src/selection-chemistry.cpp:513 +msgid "Select a group to ungroup." +msgstr "Seleccione un grupo para desagrupar." + +#: ../../po/../src/selection-chemistry.cpp:554 +msgid "No groups to ungroup in the selection." +msgstr "No hay grupos desagrupables en la selección." + +#: ../../po/../src/selection-chemistry.cpp:623 +msgid "Select objects to raise." +msgstr "Seleccione los objetos para elevar." + +#: ../../po/../src/selection-chemistry.cpp:629 +#: ../../po/../src/selection-chemistry.cpp:681 +#: ../../po/../src/selection-chemistry.cpp:715 +#: ../../po/../src/selection-chemistry.cpp:773 +msgid "" +"You cannot raise/lower objects from different groups or layers." +msgstr "" +"No puede elevar/bajar objetos de diferentes grupos o capas." + +#: ../../po/../src/selection-chemistry.cpp:673 +msgid "Select object(s) to raise to top." +msgstr "Seleccione los objetos que desea traer al frente." + +#: ../../po/../src/selection-chemistry.cpp:709 +msgid "Select object(s) to lower." +msgstr "Seleccione los objetos que desea enviar al fondo." + +#: ../../po/../src/selection-chemistry.cpp:765 +msgid "Select object(s) to lower to bottom." +msgstr "Seleccione los objetos para enviar al fondo." + +#: ../../po/../src/selection-chemistry.cpp:806 +msgid "Nothing to undo." +msgstr "Nada para deshacer." + +#: ../../po/../src/selection-chemistry.cpp:813 +msgid "Nothing to redo." +msgstr "Nada para rehacer." + +#: ../../po/../src/selection-chemistry.cpp:969 +msgid "Nothing was copied." +msgstr "No se ha copiado nada." + +#: ../../po/../src/selection-chemistry.cpp:1051 +msgid "Current layer is hidden. Unhide it to be able to paste to it." +msgstr "" +"La capa actual está oculta. Debe hacerla visible para poder pegar en " +"ella." + +#: ../../po/../src/selection-chemistry.cpp:1055 +msgid "Current layer is locked. Unlock it to be able to paste to it." +msgstr "" +"La capa actual está bloqueada. Debe desbloquearla antes de poder " +"pegar en ella." + +#: ../../po/../src/selection-chemistry.cpp:1068 +#: ../../po/../src/selection-chemistry.cpp:1103 +msgid "Nothing on the clipboard." +msgstr "No hay nada en el portapapeles." + +#: ../../po/../src/selection-chemistry.cpp:1109 +msgid "Select object(s) to paste style to." +msgstr "Seleccione los objetos a los que pegar el estilo." + +#: ../../po/../src/selection-chemistry.cpp:1128 +msgid "Select object(s) to move to the layer above." +msgstr "Seleccione los objetos que desea mover a la capa superior." + +#: ../../po/../src/selection-chemistry.cpp:1146 +msgid "No more layers above." +msgstr "No hay capas superiores." + +#: ../../po/../src/selection-chemistry.cpp:1160 +msgid "Select object(s) to move to the layer below." +msgstr "Seleccione los objetos que desea mover a la capa inferior." + +#: ../../po/../src/selection-chemistry.cpp:1178 +msgid "No more layers below." +msgstr "No hay capas inferiores." + +#: ../../po/../src/selection-chemistry.cpp:1811 +msgid "Select a clone to unlink." +msgstr "Seleccione el clon que desea desconectar." + +#: ../../po/../src/selection-chemistry.cpp:1842 +msgid "No clones to unlink in the selection." +msgstr "No hay clones desconectables en la selección." + +#: ../../po/../src/selection-chemistry.cpp:1859 +msgid "" +"Select a clone to go to its original. Select a linked offset " +"to go to its source. Select a text on path to go to the path. Select " +"a flowed text to go to its frame." +msgstr "" +"Seleccione un clon para ir a su original. Seleccione undesvío " +"enlazado para ir a su origen. Seleccione un texto en trayecto " +"para ir al trayecto. Seleccione un texto fluido para ir a su marco." + +#: ../../po/../src/selection-chemistry.cpp:1882 +msgid "" +"Cannot find the object to select (orphaned clone, offset, textpath, " +"flowed text?)" +msgstr "" +"No se pudo encontrar el objeto que quiere seleccionar (¿clon " +"huérfano, desvío, trayecto de un texto o texto fluido?)" + +#: ../../po/../src/selection-chemistry.cpp:1888 +msgid "" +"The object you're trying to select is not visible (it is in <" +"defs>)" +msgstr "" +"El objeto que desea seleccionar no es visible (está en <defs>)" + +#: ../../po/../src/selection-chemistry.cpp:1915 +msgid "Select object(s) to convert to pattern." +msgstr "Seleccione los objetos que desea convertir en patrón." + +#: ../../po/../src/selection-chemistry.cpp:2006 +msgid "Select an object with pattern fill to extract objects from." +msgstr "" +"Seleccione un objeto con relleno de mosaico del que extraer objetos." + +#: ../../po/../src/selection-chemistry.cpp:2059 +msgid "No pattern fills in the selection." +msgstr "No hay rellenos de mosaico en la selección." + +#: ../../po/../src/selection-chemistry.cpp:2079 +msgid "Select object(s) to make a bitmap copy." +msgstr "" +"Seleccione los objetos de los que desea hacer una copia en mapa de " +"bits." + +#: ../../po/../src/selection-describer.cpp:37 +msgid "Click selection to toggle scale/rotation handles" +msgstr "Pulse en la selección para conmutar los tiradores de escalado/rotación" + +#. no items +#: ../../po/../src/selection-describer.cpp:39 +msgid "" +"No objects selected. Click, Shift+click, or drag around objects to select." +msgstr "" +"No se han seleccionado objetos. Haga clic, Mayús+clic o arrastre para " +"seleccionar los objetos." + +#: ../../po/../src/selection-describer.cpp:51 +#, c-format +msgid " in layer %s" +msgstr " en la capa %s" + +#: ../../po/../src/selection-describer.cpp:54 +#, c-format +msgid " in layer %s" +msgstr " en la capa %s" + +#: ../../po/../src/selection-describer.cpp:66 +msgid "Use Shift+D to look up original" +msgstr "Utilice Mayús+D para buscar el original." + +#: ../../po/../src/selection-describer.cpp:70 +msgid "Use Shift+D to look up path" +msgstr "Utilice Mayús+D para buscar el trazo" + +#: ../../po/../src/selection-describer.cpp:74 +msgid "Use Shift+D to look up frame" +msgstr "Utilice Mayús+D para buscar el marco" + +#: ../../po/../src/selection-describer.cpp:84 +#, c-format +msgid "%i object selected" +msgid_plural "%i objects selected" +msgstr[0] "%i objeto seleccionado" +msgstr[1] "%i objetos seleccionados" + +#: ../../po/../src/selection-describer.cpp:90 +#, c-format +msgid "%s%s. %s." +msgstr "%s%s. %s." + +#: ../../po/../src/selection-describer.cpp:94 +#, c-format +msgid "%s in %i layer. %s." +msgid_plural "%s in %i layers. %s." +msgstr[0] "%s en %i capa. %s." +msgstr[1] "%s en %i capas. %s." + +#: ../../po/../src/seltrans.cpp:498 +msgid "" +"Center of rotation and skewing: drag to reposition; scaling with " +"Shift also uses this center" +msgstr "" +"Centro de rotación e inclinación: arrastre para reposicionar; escalar " +"con Mayús también utiliza este centro" + +#: ../../po/../src/seltrans.cpp:514 +msgid "" +"Squeeze or stretch selection; with Ctrl to scale uniformly; " +"with Shift to scale around rotation center" +msgstr "" +"Apretar o estirar selección; con Ctrl para escalado uniforme; " +"con Mayús para escalar alrededor del centro de rotación" + +#: ../../po/../src/seltrans.cpp:515 +msgid "" +"Scale selection; with Ctrl to scale uniformly; with Shift to scale around rotation center" +msgstr "" +"Escalar selección; con Ctrl para escalado uniforme; con " +"Mayús para escalar alrededor del centro de rotación" + +# fixme: CTRL SNAP!!! remove "skew and scale" +#: ../../po/../src/seltrans.cpp:519 +msgid "" +"Skew selection; with Ctrl to snap angle; with Shift to " +"skew around the opposite side" +msgstr "" +"Inclinar la selección; con Ctrl para ajustar al ángulo; con " +"Mayús para inclinar alrededor del lado opuesto" + +# fixme: CTRL SNAP!!! remove "skew and scale" +#: ../../po/../src/seltrans.cpp:520 +msgid "" +"Rotate selection; with Ctrl to snap angle; with Shift " +"to rotate around the opposite corner" +msgstr "" +"Rotar selección; con Ctrl para ajustar al ángulo; con " +"Mayús para rotar alrededor de la esquina opuesta" + +#: ../../po/../src/seltrans.cpp:829 ../../po/../src/seltrans.cpp:909 +#, c-format +msgid "Scale: %0.2f%% x %0.2f%%; with Ctrl to lock ratio" +msgstr "" +"Escala: %0.2f%% x %0.2f%%; con Ctrl para bloquear proporción" + +#. TRANSLATORS: don't modify the first ";" (it will NOT be displayed as ";" - only the second one will be) +#: ../../po/../src/seltrans.cpp:984 +#, c-format +msgid "Skew: %0.2f°; with Ctrl to snap angle" +msgstr "Inclinar: %0.2f°; con Ctrl para fijar el ángulo" + +#. TRANSLATORS: don't modify the first ";" (it will NOT be displayed as ";" - only the second one will be) +#: ../../po/../src/seltrans.cpp:1035 +#, c-format +msgid "Rotate: %0.2f°; with Ctrl to snap angle" +msgstr "Rotar: %0.2f°; con Ctrl para fijar el ángulo" + +#: ../../po/../src/seltrans.cpp:1090 +#, c-format +msgid "Move center to %s, %s" +msgstr "Mover el centro a %s, %s" + +#: ../../po/../src/slideshow.cpp:90 +msgid "Inkscape slideshow" +msgstr "Muestra de diapositivas Inkscape" + +#: ../../po/../src/sp-anchor.cpp:181 +#, c-format +msgid "Link to %s" +msgstr "Enlazar a %s" + +#: ../../po/../src/sp-anchor.cpp:185 +msgid "Link without URI" +msgstr "Enlace sin URI" + +#: ../../po/../src/sp-ellipse.cpp:438 ../../po/../src/sp-ellipse.cpp:870 +msgid "Ellipse" +msgstr "Elipse" + +# FIXME: implement averaging of all parameters for multiple selected stars +# gtk_label_set_markup (GTK_LABEL(l), _("Average:")); +# FIXME: implement averaging of all parameters for multiple selected +# gtk_label_set_markup (GTK_LABEL(l), _("Average:")); +#: ../../po/../src/sp-ellipse.cpp:583 +msgid "Circle" +msgstr "Círculo" + +#: ../../po/../src/sp-ellipse.cpp:865 +msgid "Segment" +msgstr "Segmento" + +#: ../../po/../src/sp-ellipse.cpp:867 +msgid "Arc" +msgstr "Arco" + +#. TRANSLATORS: "Flow region" is an area where text is allowed to flow +#: ../../po/../src/sp-flowregion.cpp:276 +msgid "Flow region" +msgstr "Región de flujo" + +#. TRANSLATORS: A region "cut out of" a flow region; text is not allowed to flow inside the +#. * flow excluded region. flowRegionExclude in SVG 1.2: see +#. * http://www.w3.org/TR/2004/WD-SVG12-20041027/flow.html#flowRegion-elem and +#. * http://www.w3.org/TR/2004/WD-SVG12-20041027/flow.html#flowRegionExclude-elem. +#: ../../po/../src/sp-flowregion.cpp:493 +msgid "Flow excluded region" +msgstr "Región excluida de flujo" + +#: ../../po/../src/sp-flowtext.cpp:355 +#, c-format +msgid "Flowed text (%d characters)" +msgstr "Texto fluido (%d caracteres)" + +#: ../../po/../src/sp-flowtext.cpp:357 +#, c-format +msgid "Linked flowed text (%d characters)" +msgstr "Texto fluido enlazado (%d caracteres)" + +#: ../../po/../src/sp-guide.cpp:290 +msgid "vertical guideline" +msgstr "guía vertical" + +#: ../../po/../src/sp-guide.cpp:292 +msgid "horizontal guideline" +msgstr "guía horizontal" + +#: ../../po/../src/sp-image.cpp:835 +msgid "embedded" +msgstr "incrustado" + +#: ../../po/../src/sp-image.cpp:839 +msgid "(null_pointer)" +msgstr "(null_pointer)" + +#: ../../po/../src/sp-image.cpp:843 +#, c-format +msgid "Image with bad reference: %s" +msgstr "Imagen con referencia incorrecta: %s" + +#: ../../po/../src/sp-image.cpp:844 +#, c-format +msgid "Image %d × %d: %s" +msgstr "Imagen %d × %d : %s" + +#: ../../po/../src/sp-item-group.cpp:390 +#, c-format +msgid "Group of %d object" +msgid_plural "Group of %d objects" +msgstr[0] "Grupo de %d objeto" +msgstr[1] "Grupo de %d objetos" + +#: ../../po/../src/sp-item.cpp:720 +msgid "Object" +msgstr "Objeto" + +#: ../../po/../src/sp-line.cpp:202 +msgid "Line" +msgstr "Línea" + +#. TRANSLATORS COMMENT: %s is either "outset" or "inset" depending on sign +#: ../../po/../src/sp-offset.cpp:433 +#, c-format +msgid "Linked offset, %s by %f pt" +msgstr "Desvío enlazado, %s por %f pt" + +#: ../../po/../src/sp-offset.cpp:434 ../../po/../src/sp-offset.cpp:438 +msgid "outset" +msgstr "ampliar" + +#: ../../po/../src/sp-offset.cpp:434 ../../po/../src/sp-offset.cpp:438 +msgid "inset" +msgstr "reducir" + +#. TRANSLATORS COMMENT: %s is either "outset" or "inset" depending on sign +#: ../../po/../src/sp-offset.cpp:437 +#, c-format +msgid "Dynamic offset, %s by %f pt" +msgstr "Desvío dinámico, %s por %f pt" + +#: ../../po/../src/sp-path.cpp:127 +#, c-format +msgid "Path (%i node)" +msgid_plural "Path (%i nodes)" +msgstr[0] "Trazo (%i nodo)" +msgstr[1] "Trazo (%i nodos)" + +#: ../../po/../src/sp-polygon.cpp:216 +msgid "Polygon" +msgstr "Polígono" + +#: ../../po/../src/sp-polyline.cpp:179 +msgid "Polyline" +msgstr "Polilínea" + +# FIXME: implement averaging of all parameters for multiple selected stars +# gtk_label_set_markup (GTK_LABEL(l), _("Average:")); +# FIXME: implement averaging of all parameters for multiple selected +# gtk_label_set_markup (GTK_LABEL(l), _("Average:")); +#: ../../po/../src/sp-rect.cpp:250 +msgid "Rectangle" +msgstr "Rectángulo" + +#. TRANSLATORS: since turn count isn't an integer, please adjust the +#. string as needed to deal with an localized plural forms. +#: ../../po/../src/sp-spiral.cpp:305 +#, c-format +msgid "Spiral with %3f turns" +msgstr "Espiral con %3f vueltas" + +#: ../../po/../src/sp-star.cpp:288 +#, c-format +msgid "Star with %d vertex" +msgid_plural "Star with %d vertices" +msgstr[0] "Estrella de %d vértice" +msgstr[1] "Estrella de %d vértices" + +#: ../../po/../src/sp-star.cpp:292 +#, c-format +msgid "Polygon with %d vertex" +msgid_plural "Polygon with %d vertices" +msgstr[0] "Polígono de %d vértice" +msgstr[1] "Polígono de %d vértices" + +#. TRANSLATORS: For description of font with no name. +#: ../../po/../src/sp-text.cpp:420 +msgid "<no name found>" +msgstr "<no hay nombre>" + +#: ../../po/../src/sp-text.cpp:426 +#, c-format +msgid "Text on path (%s, %s)" +msgstr "Texto en trayecto (%s, %s)" + +#: ../../po/../src/sp-text.cpp:427 +#, c-format +msgid "Text (%s, %s)" +msgstr "Texto (%s, %s)" + +#. TRANSLATORS: Used for statusbar description for long chains: +#. * "Clone of: Clone of: ... in Layer 1". +#: ../../po/../src/sp-use.cpp:317 +msgid "..." +msgstr "..." + +#: ../../po/../src/sp-use.cpp:325 +#, c-format +msgid "Clone of: %s" +msgstr "Clon de: %s" + +#: ../../po/../src/sp-use.cpp:329 +msgid "Orphaned clone" +msgstr "Clon huérfano" + +#: ../../po/../src/spiral-context.cpp:355 +msgid "Ctrl: snap angle" +msgstr "Ctrl: ajuste al ángulo" + +#: ../../po/../src/spiral-context.cpp:357 +msgid "Alt: lock spiral radius" +msgstr "Alt: bloquear radio de la espiral" + +#: ../../po/../src/spiral-context.cpp:469 +#, c-format +msgid "" +"Spiral: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" +"Espiral: radio %s, ángulo %5g°; con Ctrl para ajustar al " +"ángulo" + +#: ../../po/../src/splivarot.cpp:106 +msgid "Select at least 2 paths to perform a boolean operation." +msgstr "" +"Debe seleccionar al menos dos trazos para realizar una operación " +"booleana." + +#: ../../po/../src/splivarot.cpp:112 +msgid "" +"Select exactly 2 paths to perform difference, XOR, division, or path " +"cut." +msgstr "" +"Seleccione exactamente dos trazos para realizar diferencia, XOR, " +"división o corte de trazo." + +#: ../../po/../src/splivarot.cpp:129 ../../po/../src/splivarot.cpp:144 +msgid "" +"Unable to determine the z-order of the objects selected for " +"difference, XOR, division, or path cut." +msgstr "" +"No se pudo determinar el orden-z de los objetos seleccionados para la " +"diferencia, XOR, división o corte de trazo." + +#: ../../po/../src/splivarot.cpp:174 +msgid "" +"One of the objects is not a path, cannot perform boolean operation." +msgstr "" +"Uno de los objetos no es un trazo, no se puede realizar una operación " +"booleana." + +#. TRANSLATORS: "to outline" means "to convert stroke to path" +#: ../../po/../src/splivarot.cpp:554 +msgid "Select path(s) to outline." +msgstr "Seleccione uno o más trazos para contornear." + +#. TRANSLATORS: "to outline" means "to convert stroke to path" +#: ../../po/../src/splivarot.cpp:748 +msgid "No stroked paths to outline in the selection." +msgstr "No hay trazos para contornear en la selección." + +#: ../../po/../src/splivarot.cpp:832 +msgid "Selected object is not a path, cannot inset/outset." +msgstr "" +"El objeto seleccionado no es un trazo, no se puede reducir/ampliar." + +#: ../../po/../src/splivarot.cpp:1040 +msgid "Select path(s) to inset/outset." +msgstr "Seleccione trazos para reducir/ampliar." + +#: ../../po/../src/splivarot.cpp:1257 +msgid "No paths to inset/outset in the selection." +msgstr "No hay trazos para reducir/ampliar en la selección." + +#: ../../po/../src/splivarot.cpp:1390 +msgid "Select path(s) to simplify." +msgstr "Seleccione trazos para simplificar." + +#: ../../po/../src/splivarot.cpp:1417 +msgid "No paths to simplify in the selection." +msgstr "No hay trazos simplificables en la selección." + +#: ../../po/../src/star-context.cpp:362 +msgid "Ctrl: snap angle; keep rays radial" +msgstr "Ctrl: ajustar al ángulo; mantiene los rayos radiales" + +#: ../../po/../src/star-context.cpp:470 +#, c-format +msgid "" +"Polygon: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" +"Polígono: radio %s, ángulo %5g°; con Ctrl para ajustar al " +"ángulo" + +#: ../../po/../src/star-context.cpp:471 +#, c-format +msgid "Star: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" +"Estrella: radio %s, ángulo %5g°; con Ctrl para ajustar al " +"ángulo" + +#: ../../po/../src/text-chemistry.cpp:90 +msgid "Select a text and a path to put text on path." +msgstr "" +"Debe seleccionar un texto y un trazo para poner un texto en trayecto." + +#: ../../po/../src/text-chemistry.cpp:95 +msgid "" +"This text object is already put to a path. Remove it from the path " +"first. Use Shift+D to look up its path." +msgstr "" +"Este objeto de texto ya está en un trayecto. Primero quítelo del " +"trayecto.Utilice Mayús+D para buscar su trayecto." + +#. rect is the only SPShape which is not yet, and thus SVG forbids us from putting text on it +#: ../../po/../src/text-chemistry.cpp:101 +msgid "" +"You cannot put text on a rectangle in this version. Convert rectangle to " +"path first." +msgstr "" +"No puede poner texto en un rectángulo en esta versión. Primero convierta el " +"rectángulo en trazo." + +#: ../../po/../src/text-chemistry.cpp:159 +msgid "Select a text on path to remove it from path." +msgstr "Seleccione un texto en trayecto para quitarlo del trayecto." + +#: ../../po/../src/text-chemistry.cpp:181 +msgid "No texts-on-paths in the selection." +msgstr "No hay trazos en trayecto en la selección." + +#: ../../po/../src/text-chemistry.cpp:209 +#: ../../po/../src/text-chemistry.cpp:229 +msgid "Select text(s) to remove kerns from." +msgstr "Seleccione los textos de los que desea eliminar los kerns." + +#: ../../po/../src/text-chemistry.cpp:250 +msgid "" +"Select a text and one or more paths or shapes to flow text " +"into frame." +msgstr "" +"Seleccione un texto y uno o más trazos o formas para fluir un " +"texto en un marco." + +#: ../../po/../src/text-chemistry.cpp:322 +msgid "Select a flowed text to unflow it." +msgstr "Seleccione una texto fluido para desactivar el flujo." + +#: ../../po/../src/text-context.cpp:463 +msgid "Click to edit the text, drag to select part of the text." +msgstr "" +"Haga clic para editar el texto, arrastre para seleccionar " +"parte del texto." + +#: ../../po/../src/text-context.cpp:465 +msgid "" +"Click to edit the flowed text, drag to select part of the text." +msgstr "" +"Haga clic para editar el texto fluido, arrastre para " +"seleccionar parte del texto." + +#: ../../po/../src/text-context.cpp:540 +msgid "Non-printable character" +msgstr "Carácter no imprimible" + +#: ../../po/../src/text-context.cpp:589 +#, c-format +msgid "Unicode: %s: %s" +msgstr "Unicode: %s: %s" + +#: ../../po/../src/text-context.cpp:591 ../../po/../src/text-context.cpp:855 +msgid "Unicode: " +msgstr "Unicode: " + +#: ../../po/../src/text-context.cpp:615 +msgid "Current layer is hidden. Unhide it to be able to add text." +msgstr "" +"La capa actual está oculta. Debe hacerla visible para poder añadir " +"texto." + +#: ../../po/../src/text-context.cpp:619 +msgid "Current layer is locked. Unlock it to be able to add text." +msgstr "" +"La capa actual está bloqueada. Debe desbloquearla para poder añadir " +"texto." + +#: ../../po/../src/text-context.cpp:673 +#, c-format +msgid "Flowed text frame: %s × %s" +msgstr "Marco de texto fluido: %s × %s" + +#: ../../po/../src/text-context.cpp:708 ../../po/../src/text-context.cpp:1464 +msgid "Type text; Enter to start new line." +msgstr "Escriba un texto; pulse Enter para saltar de línea." + +#: ../../po/../src/text-context.cpp:719 +msgid "Flowed text is created." +msgstr "Se ha creado un texto fluido." + +#: ../../po/../src/text-context.cpp:722 +msgid "" +"The frame is too small for the current font size. Flowed text not " +"created." +msgstr "" +"El marco es demasiado pequeño para el tamaño de tipografía actual. No " +"se ha creado el texto fluido." + +#: ../../po/../src/text-context.cpp:841 +msgid "No-break space" +msgstr "Espacio sin retorno" + +#: ../../po/../src/text-context.cpp:1462 +msgid "Type flowed text; Enter to start new paragraph." +msgstr "" +"Escriba un texto fluido; pulse Enter para iniciar un párrafo nuevo." + +#: ../../po/../src/text-context.cpp:1472 ../../po/../src/tools-switch.cpp:189 +msgid "" +"Click to select or create text, drag to create flowed text; " +"then type." +msgstr "" +"Haga clic para seleccionar o crear un texto, arrastre para " +"crear un texto fluido; luego escriba." + +#: ../../po/../src/tools-switch.cpp:141 +msgid "" +"To edit a path, click, Shift+click, or drag around " +"nodes to select them, then drag nodes and handles. Click on an " +"object to select." +msgstr "" +"Para editar un trazo haga clic, Mayús+clic o arrastre " +"alrededor de los nodos para seleccionarlos, después arrastre los " +"nodos y los tiradores. Haga clic en un objeto para seleccionarlo." + +#: ../../po/../src/tools-switch.cpp:147 +msgid "" +"Drag to create a rectangle. Drag controls to round corners and " +"resize. Click to select." +msgstr "" +"Arrastre para crear un rectángulo. Arrastre los controles para " +"redondear las esquinas y redimensionar. Haga clic para seleccionar." + +#: ../../po/../src/tools-switch.cpp:153 +msgid "" +"Drag to create an ellipse. Drag controls to make an arc or " +"segment. Click to select." +msgstr "" +"Arrastre para crear una elipse. Arrastre los controles para " +"crear un arco o un segmento. Haga clic para seleccionar." + +#: ../../po/../src/tools-switch.cpp:159 +msgid "" +"Drag to create a star. Drag controls to edit the star shape. " +"Click to select." +msgstr "" +"Arrastre para crear una estrella. Arrastre los controles para " +"editar la forma de la estrella. Haga clic para seleccionar." + +#: ../../po/../src/tools-switch.cpp:165 +msgid "" +"Drag to create a spiral. Drag controls to edit the spiral " +"shape. Click to select." +msgstr "" +"Arrastre para crear una espiral. Arrastre los nodos para " +"editar la forma de la espiral. Haga clic para seleccionar." + +#: ../../po/../src/tools-switch.cpp:171 +msgid "" +"Drag to create a freehand line. Start drawing with Shift to " +"append to selected path." +msgstr "" +"Arrastre para crear una línea a mano alzada. Comience a dibujar con " +"Mayús pulsado para añadir al trazo seleccionado." + +#: ../../po/../src/tools-switch.cpp:177 +msgid "" +"Click or click and drag to start a path; with Shift to " +"append to selected path." +msgstr "" +"Pulse o pulse y arrastre para iniciar un trazo, con Mayús pulsado para añadir al trazo seleccionado." + +#: ../../po/../src/tools-switch.cpp:183 +msgid "" +"Drag to paint a calligraphic stroke. Left/right arrow " +"keys adjust width, up/down adjust angle." +msgstr "" +"Arrastre para dibujar un trazo caligráfico. Las flechas izquierda/derecha ajustan el ancho, arriba/abajo ajustan el " +"ángulo." + +#: ../../po/../src/tools-switch.cpp:195 +msgid "" +"Drag or double click to create a gradient on selected objects, " +"drag handles to adjust gradients." +msgstr "" +"Arrastre o haga doble clic para crear un gradiente en los " +"objetos seleccionados, arrastre los tiradores para ajustar los " +"gradientes." + +#: ../../po/../src/tools-switch.cpp:201 +msgid "" +"Click or drag around an area to zoom in, Shift+click to " +"zoom out." +msgstr "" +"Haga clic o arrastre alrededor de un área para hacer zoom, " +"Mayús+clic para alejar." + +#: ../../po/../src/tools-switch.cpp:213 +msgid "Click and drag between shapes to create a connector." +msgstr "Pulse y arrastre entre formas para crear un conector." + +#: ../../po/../src/trace/potrace/inkscape-potrace.cpp:553 +#: ../../po/../src/trace/potrace/inkscape-potrace.cpp:654 +#, c-format +msgid "Trace: %d. %ld nodes" +msgstr "Vectorizar: %d. %ld nodos" + +#: ../../po/../src/trace/trace.cpp:53 ../../po/../src/trace/trace.cpp:62 +#: ../../po/../src/trace/trace.cpp:70 +msgid "Select an image to trace" +msgstr "Seleccione una imagen para vectorizar" + +#: ../../po/../src/trace/trace.cpp:133 +msgid "Trace: No active document" +msgstr "Vectorizar: No hay documento activo" + +#: ../../po/../src/trace/trace.cpp:154 +msgid "Trace: Image has no bitmap data" +msgstr "Vectorizar: La imagen no tiene datos de mapa de bits" + +#: ../../po/../src/trace/trace.cpp:267 +#, c-format +msgid "Trace: Done. %ld nodes created" +msgstr "Vectorizar: Terminado. Se han creado %ld nodos." + +#: ../../po/../src/ui/dialog/aboutbox.cpp:59 ../../po/../src/verbs.cpp:2212 +msgid "About Inkscape" +msgstr "Acerca de Inkscape" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:66 +msgid "_Splash" +msgstr "" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:68 +#, fuzzy +msgid "_Authors" +msgstr "Autores" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:69 +#, fuzzy +msgid "_Translators" +msgstr "Traductores" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:70 +msgid "_License" +msgstr "_Licencia" + +#. TRANSLATORS: This is the filename of the `About Inkscape' picture in +#. the `screens' directory. Thus the translation of "about.svg" should be +#. the filename of its translated version, e.g. about.zh.svg for Chinese. +#. +#. N.B. about.svg changes once per release. (We should probably rename +#. the original to about-0.40.svg etc. as soon as we have a translation. +#. If we do so, then add an item to release-checklist saying that the +#. string here should be changed.) +#. FIXME? INKSCAPE_SCREENSDIR and "about.svg" are in UTF-8, not the +#. native filename encoding... and the filename passed to sp_document_new +#. should be in UTF-*8.. +#: ../../po/../src/ui/dialog/aboutbox.cpp:114 +msgid "about.svg" +msgstr "about.svg" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:464 +msgid "Minimum horizontal gap (in px units) between bounding boxes" +msgstr "" + +#. TRANSLATORS: Horizontal gap +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:466 +#: ../../po/../src/widgets/toolbox.cpp:1556 +msgid "H:" +msgstr "H:" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:474 +msgid "Minimum vertical gap (in px units) between bounding boxes" +msgstr "" + +#. TRANSLATORS: Vertical gap +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:476 +msgid "V:" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:734 +msgid "Align" +msgstr "Alinear" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:735 +msgid "Distribute" +msgstr "Distribuir" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:736 +msgid "Remove overlaps" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:737 +msgid "Nodes" +msgstr "Nodos" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:742 +msgid "Relative to: " +msgstr "Relativo a: " + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:747 +msgid "Align right sides of objects to left side of anchor" +msgstr "Alinear el lado derecho de los objetos a la izquierda del ancla" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:750 +msgid "Align left sides" +msgstr "Alinear lados derechos" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:753 +msgid "Center on vertical axis" +msgstr "Centrar en el eje vertical" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:756 +msgid "Align right sides" +msgstr "Alinear lados izquierdos" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:759 +msgid "Align left sides of objects to right side of anchor" +msgstr "Alinear el lado izquierdo de los objetos a la derecha del ancla" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:762 +msgid "Align bottoms of objects to top of anchor" +msgstr "Alinear el lado inferior de los objetos por encima del ancla" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:765 +msgid "Align tops" +msgstr "Alinear los bordes superiores" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:768 +msgid "Center on horizontal axis" +msgstr "Centrar en el eje horizontal" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:771 +msgid "Align bottoms" +msgstr "Alinear los bordes inferiores" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:774 +msgid "Align tops of objects to bottom of anchor" +msgstr "Alinear el lado superior de los objetos al fondo del ancla" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:779 +msgid "Align baseline anchors of texts vertically" +msgstr "Alinear las anclas de la línea base de los textos verticalmente" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:782 +msgid "Align baseline anchors of texts horizontally" +msgstr "Alinear las anclas de la línea base de los textos horizontalmente" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:787 +msgid "Make horizontal gaps between objects equal" +msgstr "Igualar los huecos horizontales entre los objetos" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:791 +msgid "Distribute left sides equidistantly" +msgstr "Distribuir los lados izquierdos a distancias iguales" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:794 +msgid "Distribute centers equidistantly horizontally" +msgstr "Distribuir los centros horizontalmente a distancias iguales" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:797 +msgid "Distribute right sides equidistantly" +msgstr "Distribuir los lados derechos a distancias iguales" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:801 +msgid "Make vertical gaps between objects equal" +msgstr "Igualar los huecos verticales entre los objetos" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:805 +msgid "Distribute tops equidistantly" +msgstr "Distribuir los bordes superiores a distancias iguales" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:808 +msgid "Distribute centers equidistantly vertically" +msgstr "Distribuir los centros verticalmente a distancias iguales" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:811 +msgid "Distribute bottoms equidistantly" +msgstr "Distribuir los lados inferiores a distancias iguales" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:816 +msgid "Distribute baseline anchors of texts horizontally" +msgstr "Distribuir las anclas de la línea base de los textos horizontalmente" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:819 +msgid "Distribute baseline anchors of texts vertically" +msgstr "Distribuir las anclas de la línea base de los textos verticalmente" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:824 +msgid "Randomize centers in both dimensions" +msgstr "Aleatorizar los centros en ambas dimensiones" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:827 +msgid "Unclump objects: try to equalize edge-to-edge distances" +msgstr "Desaglomerar objetos: intentar igualar las distancias entre bordes" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:832 +msgid "" +"Move objects as little as possible so that their bounding boxes do not " +"overlap" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:837 +msgid "Align selected nodes horizontally" +msgstr "Alinear los nodos seleccionados horizontalmente" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:840 +msgid "Align selected nodes vertically" +msgstr "Alinear los nodos seleccionados verticalmente" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:843 +msgid "Distribute selected nodes horizontally" +msgstr "Distribuir los nodos seleccionados horizontalmente" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:846 +msgid "Distribute selected nodes vertically" +msgstr "Distribuir los nodos seleccionados verticalmente" + +#. Rest of the widgetry +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:851 +msgid "Last selected" +msgstr "Último seleccionado" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:852 +msgid "First selected" +msgstr "Primero seleccionado" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:853 +msgid "Biggest item" +msgstr "Elemento mayor" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:854 +msgid "Smallest item" +msgstr "Elemento menor" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:856 +#: ../../po/../src/widgets/desktop-widget.cpp:1065 +msgid "Drawing" +msgstr "Dibujo" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:91 +#, fuzzy +msgid "Metadata 1" +msgstr "Metadatos" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:92 +#, fuzzy +msgid "Metadata 2" +msgstr "Metadatos" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:187 +#, fuzzy +msgid "X coordinate of grid origin" +msgstr "Coordenada vertical de la selección" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:189 +#, fuzzy +msgid "Y coordinate of grid origin" +msgstr "Coordenada vertical de la selección" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:191 +#, fuzzy +msgid "Distance of vertical grid lines" +msgstr "guía vertical" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:193 +#, fuzzy +msgid "Distance of horizontal grid lines" +msgstr "guía horizontal" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:197 +msgid "Max. snapping distance from grid" +msgstr "" + +#: ../../po/../src/ui/dialog/export.cpp:34 +msgid "Export" +msgstr "Exportar" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:36 +msgid "Fill" +msgstr "Relleno" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:37 +msgid "Stroke Paint" +msgstr "Color de trazo" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:38 +msgid "Stroke Style" +msgstr "Estilo de trazo" + +#: ../../po/../src/ui/dialog/find.cpp:34 +msgid "Find" +msgstr "Buscar" + +#: ../../po/../src/ui/dialog/memory.cpp:96 +msgid "Heap" +msgstr "Montón" + +#: ../../po/../src/ui/dialog/memory.cpp:97 +msgid "In Use" +msgstr "En uso" + +#. TRANSLATORS: "Slack" refers to memory which is in the heap but currently unused. +#. More typical usage is to call this memory "free" rather than "slack". +#: ../../po/../src/ui/dialog/memory.cpp:100 +msgid "Slack" +msgstr "Slack" + +#: ../../po/../src/ui/dialog/memory.cpp:101 +msgid "Total" +msgstr "Total" + +#: ../../po/../src/ui/dialog/memory.cpp:141 +#: ../../po/../src/ui/dialog/memory.cpp:147 +#: ../../po/../src/ui/dialog/memory.cpp:154 +#: ../../po/../src/ui/dialog/memory.cpp:186 +msgid "Unknown" +msgstr "Desconocido" + +#: ../../po/../src/ui/dialog/memory.cpp:167 +msgid "Combined" +msgstr "Combinada" + +#: ../../po/../src/ui/dialog/memory.cpp:209 +msgid "Recalculate" +msgstr "Recalcular" + +#: ../../po/../src/ui/dialog/messages.cpp:74 +msgid "Ready." +msgstr "Listo." + +#: ../../po/../src/ui/dialog/messages.cpp:75 +msgid "" +"Enable log display by setting dialogs.debug 'redirect' attribute to 1 in " +"preferences.xml" +msgstr "Activar el registro ajustando el atributo «dialogs.debug» a 1" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:184 +msgid "_Execute Python" +msgstr "_Ejecutar Python" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:186 +msgid "_Execute Perl" +msgstr "_Ejecutar Perl" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:195 +msgid "Script" +msgstr "Script" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:205 +msgid "Output" +msgstr "Salida" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:215 +msgid "Errors" +msgstr "Errores" + +#. Dialog organization +#: ../../po/../src/ui/dialog/session-player.cpp:73 +msgid "Session file" +msgstr "Archivo de sesión" + +#: ../../po/../src/ui/dialog/session-player.cpp:74 +msgid "Playback controls" +msgstr "Controles de reproducción" + +#: ../../po/../src/ui/dialog/session-player.cpp:75 +msgid "Message information" +msgstr "Información del mensaje" + +#. Active session file display +#. fixme: Does this mean the active file for the session, or the file for the active session? +#. Please indicate which with a TRANSLATORS comment. +#: ../../po/../src/ui/dialog/session-player.cpp:85 +msgid "Active session file:" +msgstr "Archivo de sesión activo:" + +#: ../../po/../src/ui/dialog/session-player.cpp:86 +msgid "Delay (milliseconds):" +msgstr "Retardo (milisegundos):" + +#. Unload/load buttons +#: ../../po/../src/ui/dialog/session-player.cpp:94 +msgid "Close file" +msgstr "Cerrar archivo" + +#: ../../po/../src/ui/dialog/session-player.cpp:95 +msgid "Open new file" +msgstr "Abrir un archivo nuevo" + +#: ../../po/../src/ui/dialog/session-player.cpp:96 +msgid "Set delay" +msgstr "Ajustar retardo" + +#: ../../po/../src/ui/dialog/session-player.cpp:138 +msgid "Rewind" +msgstr "Rebobinar" + +#: ../../po/../src/ui/dialog/session-player.cpp:139 +msgid "Go back one change" +msgstr "Atrasar un cambio" + +#: ../../po/../src/ui/dialog/session-player.cpp:140 +msgid "Pause" +msgstr "Pausa" + +#: ../../po/../src/ui/dialog/session-player.cpp:141 +msgid "Go forward one change" +msgstr "Adelantar un cambio" + +#: ../../po/../src/ui/dialog/session-player.cpp:142 +msgid "Play" +msgstr "Reproducir" + +#: ../../po/../src/ui/dialog/session-player.cpp:177 +#: ../../po/../src/verbs.cpp:1573 +msgid "Open session file" +msgstr "Abrir archivo de sesión" + +#. ##Set up the Potrace panel +#. #### brightness #### +#. #### Multiple scanning#### +#. ----Hbox1 +#: ../../po/../src/ui/dialog/tracedialog.cpp:345 +#: ../../po/../src/ui/dialog/tracedialog.cpp:428 +msgid "Brightness" +msgstr "Luminosidad" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:348 +msgid "Trace by a given brightness level" +msgstr "Vectorizar por un nivel de luminosidad dado" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:355 +msgid "Brightness cutoff for black/white" +msgstr "Límite de luminosidad para blanco/negro" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:362 +msgid "Image Brightness" +msgstr "Luminosidad de la imagen" + +#. #### canny edge detection #### +#. TRANSLATORS: "Canny" is the name of the inventor of this edge detection method +#: ../../po/../src/ui/dialog/tracedialog.cpp:369 +msgid "Optimal Edge Detection (Canny)" +msgstr "Detección de bordes óptima (Canny)" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:372 +msgid "Trace with edge detection by J. Canny's algorithm" +msgstr "Vectorizar con detección de bordes según el algoritmo de J. Canny" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:388 +msgid "Brightness cutoff for adjacent pixels (determines edge thickness)" +msgstr "" +"Límite de luminosidad para píxeles adyacentes (determina el grosor del borde)" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:395 +msgid "Edge Detection" +msgstr "Detección de bordes" + +#. #### quantization #### +#. TRANSLATORS: Color Quantization: the process of reducing the number of colors +#. in an image by selecting an optimized set of representative colors and then +#. re-applying this reduced set to the original image. +#: ../../po/../src/ui/dialog/tracedialog.cpp:404 +msgid "Color Quantization" +msgstr "Reducción de colores" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:407 +msgid "Trace along the boundaries of reduced colors" +msgstr "Vectorizar por los límites de colores reducidos" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:414 +msgid "The number of reduced colors" +msgstr "El número de colores reducidos" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:416 +msgid "Colors:" +msgstr "Colores:" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:421 +msgid "Quantization / Reduction" +msgstr "Reducción" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:431 +msgid "Trace the given number of brightness levels" +msgstr "Vectorizar por el número de niveles de luminosidad datos" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:438 +msgid "Scans:" +msgstr "Pasadas:" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:440 +msgid "The desired number of scans" +msgstr "El número de pasadas deseado" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:448 +msgid "Trace the given number of reduced colors" +msgstr "Vectorizar el número de colores reducidos" + +#. ---Hbox3 +#: ../../po/../src/ui/dialog/tracedialog.cpp:454 +msgid "Monochrome" +msgstr "Monocromo" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:457 +msgid "Same as Color, but convert result to grayscale" +msgstr "Igual que «Color» pero convierte el resultado a escala de grises" + +#. TRANSLATORS: "Stack" is a verb here +#: ../../po/../src/ui/dialog/tracedialog.cpp:460 +msgid "Stack" +msgstr "Apilar" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:463 +msgid "" +"Stack scans vertically (no gaps) or tile horizontally (usually with gaps)" +msgstr "" +"Apilar las pasadas verticalmente (sin separación) o en mosaico horizontal " +"(normalmente con separaciones)" + +#. TRANSLATORS: "Smooth" is a verb here +#: ../../po/../src/ui/dialog/tracedialog.cpp:466 +msgid "Smooth" +msgstr "Suave" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:469 +msgid "Apply Gaussian blur to the bitmap before tracing" +msgstr "Aplicar un desenfoque gaussiano al mapa de bits antes de vectorizar" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:473 +msgid "Multiple Scanning" +msgstr "Pasadas múltiples" + +#. #### Preview #### +#: ../../po/../src/ui/dialog/tracedialog.cpp:479 +#: ../../po/../src/ui/dialog/tracedialog.cpp:489 +msgid "Preview" +msgstr "Vista preliminar" + +#. do not expand +#: ../../po/../src/ui/dialog/tracedialog.cpp:483 +msgid "Preview the result without actual tracing" +msgstr "Realizar una vista preliminar sin realizar la vectorización" + +#. #### swap black and white #### +#: ../../po/../src/ui/dialog/tracedialog.cpp:495 +msgid "Invert" +msgstr "Invertir" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:499 +msgid "Invert black and white regions for single traces" +msgstr "Invertir las zonas blancas y negras para vectorizaciones simples" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:503 +msgid "Thanks to Peter Selinger, http://potrace.sourceforge.net" +msgstr "Gracias a Peter Selinger, http://potrace.sourceforge.net" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:506 +msgid "Credits" +msgstr "Créditos" + +#. done +#. TRANSLATORS: Potrace is an application for transforming bitmaps into +#. vector graphics (http://potrace.sourceforge.net/) +#: ../../po/../src/ui/dialog/tracedialog.cpp:514 +msgid "Potrace" +msgstr "Potrace" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:527 +msgid "Abort a trace in progress" +msgstr "Detener una vectorización en progreso" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:531 +msgid "Execute the trace" +msgstr "Ejecutar la vectorización" + +#: ../../po/../src/ui/dialog/transformation.cpp:80 +#: ../../po/../src/ui/dialog/transformation.cpp:90 +#, fuzzy +msgid "_Horizontal" +msgstr "Horizontal" + +#: ../../po/../src/ui/dialog/transformation.cpp:80 +msgid "Horizontal displacement (relative) or position (absolute)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:82 +#: ../../po/../src/ui/dialog/transformation.cpp:92 +#, fuzzy +msgid "_Vertical" +msgstr "Vertical" + +#: ../../po/../src/ui/dialog/transformation.cpp:82 +msgid "Vertical displacement (relative) or position (absolute)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:84 +#, fuzzy +msgid "_Width" +msgstr "A_ncho:" + +#: ../../po/../src/ui/dialog/transformation.cpp:84 +msgid "Horizontal size increment (absolute or percentage)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:86 +#, fuzzy +msgid "_Height" +msgstr "Alto" + +#: ../../po/../src/ui/dialog/transformation.cpp:86 +msgid "Vertical size increment (absolute or percentage)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:88 +#, fuzzy +msgid "A_ngle" +msgstr "Ángulo:" + +#: ../../po/../src/ui/dialog/transformation.cpp:88 +#, fuzzy +msgid "Rotation angle (positive = counterclockwise)" +msgstr "Rotar la selección 90 grados a la izquierda" + +#: ../../po/../src/ui/dialog/transformation.cpp:90 +msgid "" +"Horizontal skew angle (positive = counterclockwise), or absolute " +"displacement, or percentage displacement" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:92 +msgid "" +"Vertical skew angle (positive = counterclockwise), or absolute displacement, " +"or percentage displacement" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:95 +#, fuzzy +msgid "Transformation matrix element A" +msgstr "Matriz de transformación" + +#: ../../po/../src/ui/dialog/transformation.cpp:96 +#, fuzzy +msgid "Transformation matrix element B" +msgstr "Matriz de transformación" + +#: ../../po/../src/ui/dialog/transformation.cpp:97 +#, fuzzy +msgid "Transformation matrix element C" +msgstr "Matriz de transformación" + +#: ../../po/../src/ui/dialog/transformation.cpp:98 +#, fuzzy +msgid "Transformation matrix element D" +msgstr "Matriz de transformación" + +#: ../../po/../src/ui/dialog/transformation.cpp:99 +#, fuzzy +msgid "Transformation matrix element E" +msgstr "Matriz de transformación" + +#: ../../po/../src/ui/dialog/transformation.cpp:100 +#, fuzzy +msgid "Transformation matrix element F" +msgstr "Matriz de transformación" + +#: ../../po/../src/ui/dialog/transformation.cpp:102 +#, fuzzy +msgid "Rela_tive move" +msgstr "Movimiento relativo" + +#: ../../po/../src/ui/dialog/transformation.cpp:102 +msgid "" +"Add the specified relative displacement to the current position; otherwise, " +"edit the current absolute position directly" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:103 +msgid "Scale proportionally" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:103 +msgid "Preserve the width/height ratio of the scaled objects" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:104 +msgid "Apply to each _object separately" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:104 +msgid "" +"Apply the scale/rotate/skew to each selected object separately; otherwise, " +"transform the selection as a whole" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:105 +#, fuzzy +msgid "Edit c_urrent matrix" +msgstr "Elevar la capa actual" + +#: ../../po/../src/ui/dialog/transformation.cpp:105 +msgid "" +"Edit the current transform= matrix; otherwise, post-multiply transform= by " +"this matrix" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:115 +#, fuzzy +msgid "_Move" +msgstr "Mover" + +#: ../../po/../src/ui/dialog/transformation.cpp:118 +#, fuzzy +msgid "_Scale" +msgstr "Escalar" + +#: ../../po/../src/ui/dialog/transformation.cpp:121 +#, fuzzy +msgid "_Rotate" +msgstr "Rotar" + +#: ../../po/../src/ui/dialog/transformation.cpp:124 +#, fuzzy +msgid "Ske_w" +msgstr "Inclinar" + +#: ../../po/../src/ui/dialog/transformation.cpp:127 +msgid "Matri_x" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:141 +msgid "Reset the values on the current tab to defaults" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:148 +#, fuzzy +msgid "Apply transformation to selection" +msgstr "Aplicar transformación al objeto" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:43 +msgid "_Use SSL" +msgstr "_Usar SSL" + +#. Construct dialog interface +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:68 +msgid "_Server:" +msgstr "_Servidor:" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:69 +msgid "_Username:" +msgstr "Nombre de _usuario:" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:70 +msgid "_Password:" +msgstr "_Contraseña:" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:71 +msgid "P_ort:" +msgstr "P_uerto:" + +#. Buttons +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:99 +msgid "Connect" +msgstr "Conectar" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:126 +msgid "Establishing connection to Jabber server %1 as user %2" +msgstr "" +"Estableciendo conexión con el servidor Jabber %1 como usuario %2" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:131 +msgid "Failed to establish connection to Jabber server %1" +msgstr "No se ha podido establecer conexión con el servidor Jabber %1" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:136 +msgid "Authentication failed on Jabber server %1 as %2" +msgstr "" +"Ha fallado la autenticación en el servidor Jabber %1 como %s" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:141 +msgid "SSL initialization failed when connecting to Jabber server %1" +msgstr "" +"Ha fallado la inicialización SSL al conectarse al servidor Jabber %1" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:147 +msgid "Connected to Jabber server %1 as %2" +msgstr "Conectado al servidor Jabber %1 como %2" + +#. Construct labels +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:75 +msgid "Chatroom _name:" +msgstr "_Nombre de la sala:" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:76 +msgid "Chatroom _server:" +msgstr "_Servidor de chat:" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:77 +msgid "Chatroom _password:" +msgstr "Contraseña de _sala:" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:78 +msgid "Chatroom _handle:" +msgstr "A_lias de la sala:" + +#. Button setup and callback registration +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:97 +msgid "Connect to chatroom" +msgstr "Conectar a la sala" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:132 +msgid "Synchronizing with chatroom %1@%2 using the handle %3" +msgstr "Sincronizando con la sala %1@%2 con el alias %3" + +#. Construct dialog interface +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:78 +msgid "_User's Jabber ID:" +msgstr "ID Jabber del _usuario:" + +#. Buttons +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:82 +msgid "_Invite user" +msgstr "_Invitar usuario" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:83 +msgid "_Cancel" +msgstr "_Cancelar" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:94 +msgid "Buddy List" +msgstr "Lista de amigos" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:170 +msgid "Sending whiteboard invitation to %1" +msgstr "Enviando invitación de pizarra blanca a %1" + +#. FIXME: strings are replaced by placeholders, NOT to be translated until the code is enabled +#. See http://sourceforge.net/mailarchive/message.php?msg_id=11746016 for details +#. File menu +#. Edit menu +#. View menu +#. Layer menu +#. Object menu +#. Path menu +#. add(Gtk::StockItem(CLEANUP, _("PLACEHOLDER, do not translate"))); (using Gtk::Stock::CLEAR) +#. Text menu +#. About menu +#. Tools toolbox +#. Select Tool controls +#. Node Tool controls +#. Calligraphy Tool controls +#. Session playback controls +#: ../../po/../src/ui/stock-items.cpp:34 ../../po/../src/ui/stock-items.cpp:35 +#: ../../po/../src/ui/stock-items.cpp:36 ../../po/../src/ui/stock-items.cpp:37 +#: ../../po/../src/ui/stock-items.cpp:38 ../../po/../src/ui/stock-items.cpp:39 +#: ../../po/../src/ui/stock-items.cpp:40 ../../po/../src/ui/stock-items.cpp:41 +#: ../../po/../src/ui/stock-items.cpp:42 ../../po/../src/ui/stock-items.cpp:43 +#: ../../po/../src/ui/stock-items.cpp:46 ../../po/../src/ui/stock-items.cpp:47 +#: ../../po/../src/ui/stock-items.cpp:48 ../../po/../src/ui/stock-items.cpp:49 +#: ../../po/../src/ui/stock-items.cpp:50 ../../po/../src/ui/stock-items.cpp:51 +#: ../../po/../src/ui/stock-items.cpp:52 ../../po/../src/ui/stock-items.cpp:53 +#: ../../po/../src/ui/stock-items.cpp:54 ../../po/../src/ui/stock-items.cpp:55 +#: ../../po/../src/ui/stock-items.cpp:56 ../../po/../src/ui/stock-items.cpp:57 +#: ../../po/../src/ui/stock-items.cpp:58 ../../po/../src/ui/stock-items.cpp:59 +#: ../../po/../src/ui/stock-items.cpp:62 ../../po/../src/ui/stock-items.cpp:63 +#: ../../po/../src/ui/stock-items.cpp:64 ../../po/../src/ui/stock-items.cpp:65 +#: ../../po/../src/ui/stock-items.cpp:66 ../../po/../src/ui/stock-items.cpp:67 +#: ../../po/../src/ui/stock-items.cpp:68 ../../po/../src/ui/stock-items.cpp:69 +#: ../../po/../src/ui/stock-items.cpp:70 ../../po/../src/ui/stock-items.cpp:71 +#: ../../po/../src/ui/stock-items.cpp:72 ../../po/../src/ui/stock-items.cpp:73 +#: ../../po/../src/ui/stock-items.cpp:74 ../../po/../src/ui/stock-items.cpp:75 +#: ../../po/../src/ui/stock-items.cpp:76 ../../po/../src/ui/stock-items.cpp:77 +#: ../../po/../src/ui/stock-items.cpp:78 ../../po/../src/ui/stock-items.cpp:79 +#: ../../po/../src/ui/stock-items.cpp:80 ../../po/../src/ui/stock-items.cpp:81 +#: ../../po/../src/ui/stock-items.cpp:82 ../../po/../src/ui/stock-items.cpp:83 +#: ../../po/../src/ui/stock-items.cpp:84 ../../po/../src/ui/stock-items.cpp:85 +#: ../../po/../src/ui/stock-items.cpp:86 ../../po/../src/ui/stock-items.cpp:87 +#: ../../po/../src/ui/stock-items.cpp:88 ../../po/../src/ui/stock-items.cpp:89 +#: ../../po/../src/ui/stock-items.cpp:92 ../../po/../src/ui/stock-items.cpp:93 +#: ../../po/../src/ui/stock-items.cpp:94 ../../po/../src/ui/stock-items.cpp:95 +#: ../../po/../src/ui/stock-items.cpp:96 ../../po/../src/ui/stock-items.cpp:97 +#: ../../po/../src/ui/stock-items.cpp:98 ../../po/../src/ui/stock-items.cpp:99 +#: ../../po/../src/ui/stock-items.cpp:100 +#: ../../po/../src/ui/stock-items.cpp:101 +#: ../../po/../src/ui/stock-items.cpp:102 +#: ../../po/../src/ui/stock-items.cpp:103 +#: ../../po/../src/ui/stock-items.cpp:104 +#: ../../po/../src/ui/stock-items.cpp:105 +#: ../../po/../src/ui/stock-items.cpp:108 +#: ../../po/../src/ui/stock-items.cpp:109 +#: ../../po/../src/ui/stock-items.cpp:110 +#: ../../po/../src/ui/stock-items.cpp:111 +#: ../../po/../src/ui/stock-items.cpp:112 +#: ../../po/../src/ui/stock-items.cpp:113 +#: ../../po/../src/ui/stock-items.cpp:114 +#: ../../po/../src/ui/stock-items.cpp:115 +#: ../../po/../src/ui/stock-items.cpp:116 +#: ../../po/../src/ui/stock-items.cpp:117 +#: ../../po/../src/ui/stock-items.cpp:118 +#: ../../po/../src/ui/stock-items.cpp:119 +#: ../../po/../src/ui/stock-items.cpp:120 +#: ../../po/../src/ui/stock-items.cpp:121 +#: ../../po/../src/ui/stock-items.cpp:122 +#: ../../po/../src/ui/stock-items.cpp:123 +#: ../../po/../src/ui/stock-items.cpp:124 +#: ../../po/../src/ui/stock-items.cpp:125 +#: ../../po/../src/ui/stock-items.cpp:126 +#: ../../po/../src/ui/stock-items.cpp:127 +#: ../../po/../src/ui/stock-items.cpp:130 +#: ../../po/../src/ui/stock-items.cpp:131 +#: ../../po/../src/ui/stock-items.cpp:132 +#: ../../po/../src/ui/stock-items.cpp:133 +#: ../../po/../src/ui/stock-items.cpp:134 +#: ../../po/../src/ui/stock-items.cpp:135 +#: ../../po/../src/ui/stock-items.cpp:136 +#: ../../po/../src/ui/stock-items.cpp:137 +#: ../../po/../src/ui/stock-items.cpp:138 +#: ../../po/../src/ui/stock-items.cpp:139 +#: ../../po/../src/ui/stock-items.cpp:140 +#: ../../po/../src/ui/stock-items.cpp:141 +#: ../../po/../src/ui/stock-items.cpp:142 +#: ../../po/../src/ui/stock-items.cpp:143 +#: ../../po/../src/ui/stock-items.cpp:144 +#: ../../po/../src/ui/stock-items.cpp:145 +#: ../../po/../src/ui/stock-items.cpp:146 +#: ../../po/../src/ui/stock-items.cpp:150 +#: ../../po/../src/ui/stock-items.cpp:151 +#: ../../po/../src/ui/stock-items.cpp:152 +#: ../../po/../src/ui/stock-items.cpp:153 +#: ../../po/../src/ui/stock-items.cpp:156 +#: ../../po/../src/ui/stock-items.cpp:157 +#: ../../po/../src/ui/stock-items.cpp:158 +#: ../../po/../src/ui/stock-items.cpp:161 +#: ../../po/../src/ui/stock-items.cpp:162 +#: ../../po/../src/ui/stock-items.cpp:163 +#: ../../po/../src/ui/stock-items.cpp:164 +#: ../../po/../src/ui/stock-items.cpp:165 +#: ../../po/../src/ui/stock-items.cpp:166 +#: ../../po/../src/ui/stock-items.cpp:167 +#: ../../po/../src/ui/stock-items.cpp:168 +#: ../../po/../src/ui/stock-items.cpp:169 +#: ../../po/../src/ui/stock-items.cpp:170 +#: ../../po/../src/ui/stock-items.cpp:171 +#: ../../po/../src/ui/stock-items.cpp:172 +#: ../../po/../src/ui/stock-items.cpp:175 +#: ../../po/../src/ui/stock-items.cpp:176 +#: ../../po/../src/ui/stock-items.cpp:177 +#: ../../po/../src/ui/stock-items.cpp:178 +#: ../../po/../src/ui/stock-items.cpp:181 +#: ../../po/../src/ui/stock-items.cpp:182 +#: ../../po/../src/ui/stock-items.cpp:183 +#: ../../po/../src/ui/stock-items.cpp:184 +#: ../../po/../src/ui/stock-items.cpp:185 +#: ../../po/../src/ui/stock-items.cpp:186 +#: ../../po/../src/ui/stock-items.cpp:187 +#: ../../po/../src/ui/stock-items.cpp:188 +#: ../../po/../src/ui/stock-items.cpp:189 +#: ../../po/../src/ui/stock-items.cpp:190 +#: ../../po/../src/ui/stock-items.cpp:191 +#: ../../po/../src/ui/stock-items.cpp:194 +#: ../../po/../src/ui/stock-items.cpp:195 +#: ../../po/../src/ui/stock-items.cpp:198 +#: ../../po/../src/ui/stock-items.cpp:199 +#: ../../po/../src/ui/stock-items.cpp:200 +#: ../../po/../src/ui/stock-items.cpp:201 +#: ../../po/../src/ui/stock-items.cpp:202 +msgid "PLACEHOLDER, do not translate" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:88 +msgid "small" +msgstr "pequeño" + +#: ../../po/../src/ui/widget/panel.cpp:89 +msgid "medium" +msgstr "mediano" + +#: ../../po/../src/ui/widget/panel.cpp:90 +msgid "large" +msgstr "grande" + +#: ../../po/../src/ui/widget/panel.cpp:91 +msgid "huge" +msgstr "enorme" + +#: ../../po/../src/ui/widget/panel.cpp:106 +msgid "List" +msgstr "Lista" + +#: ../../po/../src/ui/widget/selected-style.cpp:67 +msgid "F:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:68 +msgid "S:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:69 +msgid "O:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:95 +msgid "N/A" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:98 +#: ../../po/../src/ui/widget/selected-style.cpp:712 +#, fuzzy +msgid "Nothing selected" +msgstr "Sin gradiente seleccionado" + +#: ../../po/../src/ui/widget/selected-style.cpp:103 +msgid "No fill" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:103 +#, fuzzy +msgid "No stroke" +msgstr " (trazo)" + +#: ../../po/../src/ui/widget/selected-style.cpp:105 +#: ../../po/../src/widgets/paint-selector.cpp:190 +msgid "Pattern" +msgstr "Patrón" + +#: ../../po/../src/ui/widget/selected-style.cpp:108 +#: ../../po/../src/widgets/paint-selector.cpp:885 +msgid "Pattern fill" +msgstr "Relleno de mosaico" + +#: ../../po/../src/ui/widget/selected-style.cpp:108 +#, fuzzy +msgid "Pattern stroke" +msgstr "Desvío del patrón" + +#: ../../po/../src/ui/widget/selected-style.cpp:110 +#, fuzzy +msgid "L Gradient" +msgstr "Gradiente" + +#: ../../po/../src/ui/widget/selected-style.cpp:113 +#, fuzzy +msgid "Linear gradient fill" +msgstr "Gradiente lineal" + +#: ../../po/../src/ui/widget/selected-style.cpp:113 +#, fuzzy +msgid "Linear gradient stroke" +msgstr "Gradiente lineal" + +#: ../../po/../src/ui/widget/selected-style.cpp:115 +#, fuzzy +msgid "R Gradient" +msgstr "Gradiente" + +#: ../../po/../src/ui/widget/selected-style.cpp:118 +#, fuzzy +msgid "Radial gradient fill" +msgstr "Gradiente radial" + +#: ../../po/../src/ui/widget/selected-style.cpp:118 +#, fuzzy +msgid "Radial gradient stroke" +msgstr "Gradiente radial" + +#: ../../po/../src/ui/widget/selected-style.cpp:120 +#, fuzzy +msgid "Different" +msgstr "_Diferencia" + +#: ../../po/../src/ui/widget/selected-style.cpp:123 +#, fuzzy +msgid "Different fills" +msgstr "_Diferencia" + +#: ../../po/../src/ui/widget/selected-style.cpp:123 +#, fuzzy +msgid "Different strokes" +msgstr "_Diferencia" + +#: ../../po/../src/ui/widget/selected-style.cpp:125 +#, fuzzy +msgid "Unset" +msgstr "reducir" + +#. TRANSLATORS COMMENT: unset is a verb here +#: ../../po/../src/ui/widget/selected-style.cpp:128 +#: ../../po/../src/ui/widget/selected-style.cpp:182 +msgid "Unset fill" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:128 +#: ../../po/../src/ui/widget/selected-style.cpp:182 +#, fuzzy +msgid "Unset stroke" +msgstr " (trazo)" + +#: ../../po/../src/ui/widget/selected-style.cpp:131 +#, fuzzy +msgid "Flat color fill" +msgstr "Color uniforme" + +#: ../../po/../src/ui/widget/selected-style.cpp:131 +#, fuzzy +msgid "Flat color stroke" +msgstr "Color uniforme" + +#. TRANSLATOR COMMENT: A means "Averaged" +#: ../../po/../src/ui/widget/selected-style.cpp:134 +#, fuzzy +msgid "A" +msgstr "_A" + +#: ../../po/../src/ui/widget/selected-style.cpp:137 +#, fuzzy +msgid "Fill is averaged over selected objects" +msgstr "OR exclusivo de objetos seleccionados" + +#: ../../po/../src/ui/widget/selected-style.cpp:137 +#, fuzzy +msgid "Stroke is averaged over selected objects" +msgstr "Hacer que los conectores eviten los objetos seleccionados" + +#. TRANSLATOR COMMENT: M means "Multiple" +#: ../../po/../src/ui/widget/selected-style.cpp:140 +#, fuzzy +msgid "M" +msgstr "_M" + +#: ../../po/../src/ui/widget/selected-style.cpp:143 +#, fuzzy +msgid "Multiple selected objects have the same fill" +msgstr "Refleja los objetos seleccionados verticalmente" + +#: ../../po/../src/ui/widget/selected-style.cpp:143 +#, fuzzy +msgid "Multiple selected objects have the same stroke" +msgstr "Refleja los objetos seleccionados verticalmente" + +#: ../../po/../src/ui/widget/selected-style.cpp:145 +#, fuzzy +msgid "Edit fill..." +msgstr "Editar..." + +#: ../../po/../src/ui/widget/selected-style.cpp:145 +#, fuzzy +msgid "Edit stroke..." +msgstr "Editar..." + +#: ../../po/../src/ui/widget/selected-style.cpp:149 +#, fuzzy +msgid "Last set color" +msgstr "Color uniforme" + +#: ../../po/../src/ui/widget/selected-style.cpp:153 +#, fuzzy +msgid "Last selected color" +msgstr "Último seleccionado" + +#: ../../po/../src/ui/widget/selected-style.cpp:157 +#, fuzzy +msgid "White" +msgstr "Piza_rra blanca" + +#: ../../po/../src/ui/widget/selected-style.cpp:161 +#: ../../po/../src/widgets/sp-color-scales.cpp:461 +#: ../../po/../src/widgets/sp-color-scales.cpp:462 +msgid "Black" +msgstr "Negro" + +#: ../../po/../src/ui/widget/selected-style.cpp:165 +#, fuzzy +msgid "Copy color" +msgstr "Color de parada" + +#: ../../po/../src/ui/widget/selected-style.cpp:169 +#, fuzzy +msgid "Paste color" +msgstr "Color uniforme" + +#: ../../po/../src/ui/widget/selected-style.cpp:173 +#, fuzzy +msgid "Swap fill and stroke" +msgstr "_Relleno y borde" + +#: ../../po/../src/ui/widget/selected-style.cpp:177 +msgid "Make fill opaque" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:177 +msgid "Make stroke opaque" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:186 +#, fuzzy +msgid "Remove fill" +msgstr " El_minar " + +#: ../../po/../src/ui/widget/selected-style.cpp:186 +#, fuzzy +msgid "Remove stroke" +msgstr "_Eliminar enlace" + +#: ../../po/../src/ui/widget/selected-style.cpp:718 +#, fuzzy +msgid "Master opacity" +msgstr "_Opacidad maestra" + +#: ../../po/../src/ui/widget/selected-style.cpp:744 +msgid "0 (transparent)" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:768 +msgid "1.0 (opaque)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1046 +msgid "Moved to next layer." +msgstr "Movido a la siguiente capa." + +#: ../../po/../src/verbs.cpp:1048 +msgid "Cannot move past last layer." +msgstr "No se puede mover más allá de la última capa." + +#: ../../po/../src/verbs.cpp:1057 +msgid "Moved to previous layer." +msgstr "Movido a la capa anterior" + +#: ../../po/../src/verbs.cpp:1059 +msgid "Cannot move past first layer." +msgstr "No se puede mover más allá de la primera capa." + +#: ../../po/../src/verbs.cpp:1076 ../../po/../src/verbs.cpp:1150 +msgid "No current layer." +msgstr "No hay capa actual." + +#: ../../po/../src/verbs.cpp:1105 +#, c-format +msgid "Raised layer %s." +msgstr "Capa elevada %s." + +#: ../../po/../src/verbs.cpp:1109 +#, c-format +msgid "Lowered layer %s." +msgstr "Capa enviada al fondo·%s." + +#: ../../po/../src/verbs.cpp:1118 +msgid "Cannot move layer any further." +msgstr "No se puede mover más la capa." + +#. TRANSLATORS: this means "The layer has been deleted." +#: ../../po/../src/verbs.cpp:1148 +msgid "Deleted layer." +msgstr "Capa eliminada." + +#: ../../po/../src/verbs.cpp:1544 +msgid "" +"You need to connect to a Jabber server before sharing a document with " +"another user." +msgstr "" +"Necesita conectarse a un servidor Jabber antes de compartir un documento con " +"otro usuario." + +#: ../../po/../src/verbs.cpp:1559 +msgid "" +"You need to connect to a Jabber server before sharing a document with a " +"chatroom." +msgstr "" +"Necesita conectarse a un servidor Jabber antes de compartir un documento con " +"una sala." + +#: ../../po/../src/verbs.cpp:1569 +msgid "XML node tracker has not been initialized; nothing to dump" +msgstr "" +"No se ha inicializado el explorador de nodos XML; no hay nada que volcar." + +#. TRANSLATORS: If you have translated the keys.svg file to your language, then +#. translate this string as "keys.LANG.svg" (where LANG is your language code); +#. otherwise leave as "keys.svg". +#: ../../po/../src/verbs.cpp:1631 +msgid "keys.svg" +msgstr "keys.svg" + +#. TRANSLATORS: If you have translated the tutorial-basic.svg file to your language, +#. then translate this string as "tutorial-basic.LANG.svg" (where LANG is your language +#. code); otherwise leave as "tutorial-basic.svg". +#: ../../po/../src/verbs.cpp:1667 +msgid "tutorial-basic.svg" +msgstr "tutorial-basic.es.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1671 +msgid "tutorial-shapes.svg" +msgstr "tutorial-shapes.es.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1675 +msgid "tutorial-advanced.svg" +msgstr "tutorial-advanced.es.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1679 +msgid "tutorial-tracing.svg" +msgstr "tutorial-tracing.es.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1683 +msgid "tutorial-calligraphy.svg" +msgstr "tutorial-calligraphy.es.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1687 +msgid "tutorial-elements.svg" +msgstr "tutorial-elements.es.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1691 +msgid "tutorial-tips.svg" +msgstr "tutorial-tips.es.svg" + +#: ../../po/../src/verbs.cpp:1842 +msgid "Does nothing" +msgstr "No hacer nada" + +# File +#. File +#: ../../po/../src/verbs.cpp:1845 +msgid "Default" +msgstr "Predeterminado" + +#: ../../po/../src/verbs.cpp:1845 +msgid "Create new document from default template" +msgstr "Crear un documento nuevo de la plantilla predeterminada" + +#: ../../po/../src/verbs.cpp:1847 +msgid "_Open..." +msgstr "_Abrir..." + +#: ../../po/../src/verbs.cpp:1848 +msgid "Open existing document" +msgstr "Abrir un documento existente" + +#: ../../po/../src/verbs.cpp:1849 +msgid "Re_vert" +msgstr "Re_vertir" + +#: ../../po/../src/verbs.cpp:1850 +msgid "Revert to the last saved version of document (changes will be lost)" +msgstr "" +"Revertir a la última versión guardada del documento (se perderán los cambios)" + +#: ../../po/../src/verbs.cpp:1851 +msgid "_Save" +msgstr "_Guardar" + +#: ../../po/../src/verbs.cpp:1851 +msgid "Save document" +msgstr "Guardar documento" + +#: ../../po/../src/verbs.cpp:1853 +msgid "Save _As..." +msgstr "G_uardar como..." + +#: ../../po/../src/verbs.cpp:1854 +msgid "Save document under new name" +msgstr "Guardar documento con un nombre nuevo" + +#: ../../po/../src/verbs.cpp:1855 +msgid "_Print..." +msgstr "_Imprimir" + +#: ../../po/../src/verbs.cpp:1855 +msgid "Print document" +msgstr "Imprimir documento" + +#. TRANSLATORS: "Vacuum Defs" means "Clean up defs" (so as to remove unused definitions) +#: ../../po/../src/verbs.cpp:1858 +msgid "Vac_uum Defs" +msgstr "Eliminar defs" + +#: ../../po/../src/verbs.cpp:1858 +msgid "Remove unused predefined items from the <defs> of the document" +msgstr "Eliminar lo que no se utiliza de las <defs> del documento" + +#: ../../po/../src/verbs.cpp:1860 +msgid "Print _Direct" +msgstr "Impresión _directa" + +#: ../../po/../src/verbs.cpp:1861 +msgid "Print directly without prompting to a file or pipe" +msgstr "Imprimir directamente a un archivo o tubería" + +#: ../../po/../src/verbs.cpp:1862 +msgid "Print Previe_w" +msgstr "_Vista preliminar" + +#: ../../po/../src/verbs.cpp:1863 +msgid "Preview document printout" +msgstr "Vista preliminar de impresión" + +#: ../../po/../src/verbs.cpp:1864 +msgid "_Import..." +msgstr "_Importar..." + +#: ../../po/../src/verbs.cpp:1865 +msgid "Import bitmap or SVG image into document" +msgstr "Importar mapa de bits o imagen SVG al documento" + +#: ../../po/../src/verbs.cpp:1866 +msgid "_Export Bitmap..." +msgstr "_Exportar mapa de bits..." + +#: ../../po/../src/verbs.cpp:1867 +msgid "Export document or selection as a bitmap image" +msgstr "Exportar documento o selección como imagen mapa de bits" + +#: ../../po/../src/verbs.cpp:1868 +msgid "N_ext Window" +msgstr "Ventana sigui_ente" + +#: ../../po/../src/verbs.cpp:1869 +msgid "Switch to the next document window" +msgstr "Cambiar a la ventana de documento siguiente" + +#: ../../po/../src/verbs.cpp:1870 +msgid "P_revious Window" +msgstr "Ventana ante_rior" + +#: ../../po/../src/verbs.cpp:1871 +msgid "Switch to the previous document window" +msgstr "Cambiar a la ventana de documento anterior" + +#: ../../po/../src/verbs.cpp:1872 +msgid "_Close" +msgstr "_Cerrar" + +#: ../../po/../src/verbs.cpp:1873 +msgid "Close window" +msgstr "Cerrar ventana" + +#: ../../po/../src/verbs.cpp:1874 +msgid "_Quit" +msgstr "_Salir" + +#: ../../po/../src/verbs.cpp:1874 +msgid "Quit Inkscape" +msgstr "Salir de Inkscape" + +#. Edit +#: ../../po/../src/verbs.cpp:1877 +msgid "_Undo" +msgstr "_Deshacer" + +#: ../../po/../src/verbs.cpp:1877 +msgid "Undo last action" +msgstr "Deshacer la última acción" + +#: ../../po/../src/verbs.cpp:1879 +msgid "_Redo" +msgstr "_Rehacer" + +#: ../../po/../src/verbs.cpp:1880 +msgid "Do again last undone action" +msgstr "Ejecutar nuevamente la acción deshecha" + +#: ../../po/../src/verbs.cpp:1881 +msgid "Cu_t" +msgstr "Cor_tar" + +#: ../../po/../src/verbs.cpp:1882 +msgid "Cut selection to clipboard" +msgstr "Cortar la selección al portapapeles" + +#: ../../po/../src/verbs.cpp:1883 +msgid "_Copy" +msgstr "_Copiar" + +#: ../../po/../src/verbs.cpp:1884 +msgid "Copy selection to clipboard" +msgstr "Copiar la selección al portapapeles" + +#: ../../po/../src/verbs.cpp:1885 +msgid "_Paste" +msgstr "_Pegar" + +#: ../../po/../src/verbs.cpp:1886 +msgid "Paste objects from clipboard to mouse point" +msgstr "Pegar los objetos desde el portapapeles al puntero del ratón." + +#: ../../po/../src/verbs.cpp:1887 +msgid "Paste _Style" +msgstr "Pegar e_stilo" + +#: ../../po/../src/verbs.cpp:1888 +msgid "Apply style of the copied object to selection" +msgstr "Aplicar el estilo del objeto copiado a la selección" + +#: ../../po/../src/verbs.cpp:1889 +msgid "Paste _In Place" +msgstr "Pegar en el s_itio" + +#: ../../po/../src/verbs.cpp:1890 +msgid "Paste objects from clipboard to the original location" +msgstr "Pegar los objetos del portapapeles en el lugar original." + +#: ../../po/../src/verbs.cpp:1891 +msgid "_Delete" +msgstr "_Eliminar" + +#: ../../po/../src/verbs.cpp:1892 +msgid "Delete selection" +msgstr "Borrar selección" + +#: ../../po/../src/verbs.cpp:1893 +msgid "Duplic_ate" +msgstr "Duplic_ar" + +#: ../../po/../src/verbs.cpp:1894 +msgid "Duplicate selected objects" +msgstr "Duplicar los objetos seleccionados" + +#: ../../po/../src/verbs.cpp:1895 +msgid "Clo_ne" +msgstr "Clo_nar" + +#: ../../po/../src/verbs.cpp:1896 +msgid "Create a clone of selected object (a copy linked to the original)" +msgstr "" +"Crear un clon del objeto seleccionado (una copia conectada al original)" + +#: ../../po/../src/verbs.cpp:1897 +msgid "Unlin_k Clone" +msgstr "Des_conectar clon" + +#: ../../po/../src/verbs.cpp:1898 +msgid "Cut the clone's link to its original" +msgstr "Cortar la conexión del clon a su original" + +#: ../../po/../src/verbs.cpp:1899 +msgid "Select _Original" +msgstr "Seleccionar _original" + +#: ../../po/../src/verbs.cpp:1900 +msgid "Select the object to which the clone is linked" +msgstr "Seleccione el objeto al que está conectado el clon." + +#. TRANSLATORS: Convert selection to a rectangle with tiled pattern fill +#: ../../po/../src/verbs.cpp:1902 +msgid "O_bjects to Pattern" +msgstr "O_bjetos a patrón" + +#: ../../po/../src/verbs.cpp:1903 +msgid "Convert selection to a rectangle with tiled pattern fill" +msgstr "Convertir la selección a un rectángulo con un relleno de mosaico" + +#. TRANSLATORS: Extract objects from a tiled pattern fill +#: ../../po/../src/verbs.cpp:1905 +msgid "Pattern to Ob_jects" +msgstr "Patrón a ob_jetos" + +#: ../../po/../src/verbs.cpp:1906 +msgid "Extract objects from a tiled pattern fill" +msgstr "Extraer los objetos de un relleno de mosaico" + +#: ../../po/../src/verbs.cpp:1907 +msgid "Clea_r All" +msgstr "Limpia_r todo" + +#: ../../po/../src/verbs.cpp:1908 +msgid "Delete all objects from document" +msgstr "Borrar todos los objetos del documento" + +#: ../../po/../src/verbs.cpp:1909 +msgid "Select Al_l" +msgstr "Se_leccionar todo" + +#: ../../po/../src/verbs.cpp:1910 +msgid "Select all objects or all nodes" +msgstr "Seleccionar todos los objetos o todos los nodos" + +#: ../../po/../src/verbs.cpp:1911 +msgid "Select All in All La_yers" +msgstr "Seleccionar todo de todas las ca_pas" + +#: ../../po/../src/verbs.cpp:1912 +msgid "Select all objects in all visible and unlocked layers" +msgstr "" +"Seleccionar todos los objetos en todas las capas visibles y desbloqueadas" + +#: ../../po/../src/verbs.cpp:1913 +msgid "In_vert Selection" +msgstr "In_vertir selección" + +#: ../../po/../src/verbs.cpp:1914 +msgid "Invert selection (unselect what is selected and select everything else)" +msgstr "" +"Invertir selección (deseleccionar lo que está seleccionado y seleccionar lo " +"demás)" + +#: ../../po/../src/verbs.cpp:1915 +msgid "Invert in All Layers" +msgstr "Invertir en todas las capas" + +#: ../../po/../src/verbs.cpp:1916 +msgid "Invert selection in all visible and unlocked layers" +msgstr "Invertir la selección en todas las capas visibles y desbloqueadas" + +#: ../../po/../src/verbs.cpp:1917 +msgid "D_eselect" +msgstr "D_eseleccionar" + +#: ../../po/../src/verbs.cpp:1918 +msgid "Deselect any selected objects or nodes" +msgstr "Deseleccionar los objetos o nodos seleccionados." + +#. Selection +#: ../../po/../src/verbs.cpp:1921 +msgid "Raise to _Top" +msgstr "Traer al fren_te" + +#: ../../po/../src/verbs.cpp:1922 +msgid "Raise selection to top" +msgstr "Elevar los objetos a primer plano" + +#: ../../po/../src/verbs.cpp:1923 +msgid "Lower to _Bottom" +msgstr "_Bajar al fondo" + +#: ../../po/../src/verbs.cpp:1924 +msgid "Lower selection to bottom" +msgstr "Bajar la selección al fondo" + +#: ../../po/../src/verbs.cpp:1925 +msgid "_Raise" +msgstr "Eleva_r" + +#: ../../po/../src/verbs.cpp:1926 +msgid "Raise selection one step" +msgstr "Elevar la selección un nivel" + +#: ../../po/../src/verbs.cpp:1927 +msgid "_Lower" +msgstr "_Bajar" + +#: ../../po/../src/verbs.cpp:1928 +msgid "Lower selection one step" +msgstr "Bajar la selección un nivel" + +#: ../../po/../src/verbs.cpp:1929 +msgid "_Group" +msgstr "A_grupar" + +#: ../../po/../src/verbs.cpp:1930 +msgid "Group selected objects" +msgstr "Agrupar los objetos seleccionados" + +#: ../../po/../src/verbs.cpp:1932 +msgid "Ungroup selected groups" +msgstr "Desagrupar grupos seleccionados" + +#: ../../po/../src/verbs.cpp:1934 +msgid "_Put on Path" +msgstr "_Poner en trayecto" + +#: ../../po/../src/verbs.cpp:1935 +msgid "Put text on path" +msgstr "Poner texto en trayecto" + +#: ../../po/../src/verbs.cpp:1936 +msgid "_Remove from Path" +msgstr "_Retirar del trayecto" + +#: ../../po/../src/verbs.cpp:1937 +msgid "Remove text from path" +msgstr "Retirar texto de trayecto" + +#: ../../po/../src/verbs.cpp:1938 +msgid "Remove Manual _Kerns" +msgstr "Eliminar todos los _kerns manuales" + +#. TRANSLATORS: "glyph": An image used in the visual representation of characters; +#. roughly speaking, how a character looks. A font is a set of glyphs. +#: ../../po/../src/verbs.cpp:1941 +msgid "Remove all manual kerns and glyph rotations from a text object" +msgstr "" +"Eliminar todos los kerns manuales y rotaciones de glifo de un objeto de texto" + +#: ../../po/../src/verbs.cpp:1943 +msgid "_Union" +msgstr "_Unión" + +#: ../../po/../src/verbs.cpp:1944 +msgid "Union of selected objects" +msgstr "Unión de objetos seleccionados" + +#: ../../po/../src/verbs.cpp:1945 +msgid "_Intersection" +msgstr "_Intersección" + +#: ../../po/../src/verbs.cpp:1946 +msgid "Intersection of selected objects" +msgstr "Intersección de objetos seleccionados" + +#: ../../po/../src/verbs.cpp:1947 +msgid "_Difference" +msgstr "_Diferencia" + +#: ../../po/../src/verbs.cpp:1948 +msgid "Difference of selected objects (bottom minus top)" +msgstr "Diferencia de los objetos seleccionados (abajo menos arriba)" + +#: ../../po/../src/verbs.cpp:1949 +msgid "E_xclusion" +msgstr "E_xclusión" + +#: ../../po/../src/verbs.cpp:1950 +msgid "Exclusive OR of selected objects" +msgstr "OR exclusivo de objetos seleccionados" + +#: ../../po/../src/verbs.cpp:1951 +msgid "Di_vision" +msgstr "Di_visión" + +#: ../../po/../src/verbs.cpp:1952 +msgid "Cut the bottom object into pieces" +msgstr "Cortar el objeto del fondo en pedazos" + +#. TRANSLATORS: "to cut a path" is not the same as "to break a path apart" - see the +#. Advanced tutorial for more info +#: ../../po/../src/verbs.cpp:1955 +msgid "Cut _Path" +msgstr "Cor_tar trazo" + +#: ../../po/../src/verbs.cpp:1956 +msgid "Cut the bottom object's stroke into pieces, removing fill" +msgstr "Cortar el objeto del fondo en pedazos, eliminando el relleno" + +#. TRANSLATORS: "outset": expand a shape by offsetting the object's path, +#. i.e. by displacing it perpendicular to the path in each point. +#. See also the Advanced Tutorial for explanation. +#: ../../po/../src/verbs.cpp:1960 +msgid "Outs_et" +msgstr "A_mpliar" + +#: ../../po/../src/verbs.cpp:1961 +msgid "Outset selected paths" +msgstr "Ampliar los trazos seleccionados" + +#: ../../po/../src/verbs.cpp:1963 +msgid "O_utset Path by 1 px" +msgstr "A_mpliar trazo 1 px" + +#: ../../po/../src/verbs.cpp:1964 +msgid "Outset selected paths by 1 px" +msgstr "Ampliar los trazos seleccionados 1 px" + +#: ../../po/../src/verbs.cpp:1966 +msgid "O_utset Path by 10 px" +msgstr "A_mpliar trazo 10 px" + +#: ../../po/../src/verbs.cpp:1967 +msgid "Outset selected paths by 10 px" +msgstr "Ampliar los trazos seleccionados 10 px" + +#. TRANSLATORS: "inset": contract a shape by offsetting the object's path, +#. i.e. by displacing it perpendicular to the path in each point. +#. See also the Advanced Tutorial for explanation. +#: ../../po/../src/verbs.cpp:1971 +msgid "I_nset" +msgstr "Re_ducir" + +#: ../../po/../src/verbs.cpp:1972 +msgid "Inset selected paths" +msgstr "Reducir los trazos seleccionados" + +#: ../../po/../src/verbs.cpp:1974 +msgid "I_nset Path by 1 px" +msgstr "Re_ducir trazo 1 px" + +#: ../../po/../src/verbs.cpp:1975 +msgid "Inset selected paths by 1 px" +msgstr "Reducir los trazos seleccionados 1 px" + +#: ../../po/../src/verbs.cpp:1977 +msgid "I_nset Path by 10 px" +msgstr "Re_ducir trazo 10 px" + +#: ../../po/../src/verbs.cpp:1978 +msgid "Inset selected paths by 10 px" +msgstr "Reducir los trazos seleccionados 10 px" + +#: ../../po/../src/verbs.cpp:1980 +msgid "D_ynamic Offset" +msgstr "Desvío d_inámico" + +#: ../../po/../src/verbs.cpp:1980 +msgid "Create a dynamic offset object" +msgstr "Crear un objeto de desvió dinámico" + +#: ../../po/../src/verbs.cpp:1982 +msgid "_Linked Offset" +msgstr "Desvío en_lazado" + +#: ../../po/../src/verbs.cpp:1983 +msgid "Create a dynamic offset object linked to the original path" +msgstr "Crear un objeto de desvío dinámico enlazado al trazo original" + +#: ../../po/../src/verbs.cpp:1985 +msgid "_Stroke to Path" +msgstr "_Borde a trazo" + +#: ../../po/../src/verbs.cpp:1986 +msgid "Convert selected strokes to paths" +msgstr "Convierte los bordes seleccionados en trazos" + +#: ../../po/../src/verbs.cpp:1987 +msgid "Si_mplify" +msgstr "Si_mplificar" + +#: ../../po/../src/verbs.cpp:1988 +msgid "Simplify selected paths by removing extra nodes" +msgstr "Simplifica el trazo seleccionado eliminando nodos" + +#: ../../po/../src/verbs.cpp:1989 +msgid "_Reverse" +msgstr "_Revertir" + +#: ../../po/../src/verbs.cpp:1990 +msgid "Reverses the direction of selected paths; useful for flipping markers" +msgstr "" +"Invierte la dirección de los trazos seleccionados, útil para girar marcadores" + +#. TRANSLATORS: "to trace" means "to convert a bitmap to vector graphics" (to vectorize) +#: ../../po/../src/verbs.cpp:1992 +msgid "_Trace Bitmap" +msgstr "Vec_torizar un mapa de bits" + +#: ../../po/../src/verbs.cpp:1993 +msgid "Convert bitmap object to paths" +msgstr "Convierte el objeto mapa de bits en trazos" + +#: ../../po/../src/verbs.cpp:1994 +msgid "_Make a Bitmap Copy" +msgstr "Crear copia en _mapa de bits" + +#: ../../po/../src/verbs.cpp:1995 +msgid "Export selection to a bitmap and insert it into document" +msgstr "Exportar la selección a mapa de bits e insertarlo en el documento" + +#: ../../po/../src/verbs.cpp:1996 +msgid "_Combine" +msgstr "_Combinar" + +#: ../../po/../src/verbs.cpp:1997 +msgid "Combine several paths into one" +msgstr "Combinar varios trazos en uno" + +#. TRANSLATORS: "to cut a path" is not the same as "to break a path apart" - see the +#. Advanced tutorial for more info +#: ../../po/../src/verbs.cpp:2000 +msgid "Break _Apart" +msgstr "Descombin_ar" + +#: ../../po/../src/verbs.cpp:2001 +msgid "Break selected paths into subpaths" +msgstr "Separar los trazos seleccionados en subtrazos" + +#: ../../po/../src/verbs.cpp:2002 +msgid "Gri_d Arrange..." +msgstr "Ordenar en re_jilla..." + +#: ../../po/../src/verbs.cpp:2003 +msgid "Arrange selection in grid pattern" +msgstr "Ordenar la selección en patrón de rejilla" + +#. Layer +#: ../../po/../src/verbs.cpp:2005 +msgid "_Add Layer..." +msgstr "_Añadir capa..." + +#: ../../po/../src/verbs.cpp:2006 +msgid "Create a new layer" +msgstr "Crear una capa nueva" + +#: ../../po/../src/verbs.cpp:2007 +msgid "Re_name Layer..." +msgstr "Re_nombrar capa..." + +#: ../../po/../src/verbs.cpp:2008 +msgid "Rename the current layer" +msgstr "Cambiar nombre a la capa actual" + +#: ../../po/../src/verbs.cpp:2009 +msgid "Switch to Layer Abov_e" +msgstr "Ir a la capa sup_erior" + +#: ../../po/../src/verbs.cpp:2010 +msgid "Switch to the layer above the current" +msgstr "Cambiar a la siguiente capa encima de la actual" + +#: ../../po/../src/verbs.cpp:2011 +msgid "Switch to Layer Belo_w" +msgstr "Ir a la capa infe_rior" + +#: ../../po/../src/verbs.cpp:2012 +msgid "Switch to the layer below the current" +msgstr "Cambiar a la siguiente capa debajo de la actual" + +#: ../../po/../src/verbs.cpp:2013 +msgid "Move Selection to Layer Abo_ve" +msgstr "Mover la selección a la capa superior a la actual" + +#: ../../po/../src/verbs.cpp:2014 +msgid "Move selection to the layer above the current" +msgstr "Mover la selección a la capa superior a la actual" + +#: ../../po/../src/verbs.cpp:2015 +msgid "Move Selection to Layer Bel_ow" +msgstr "Mover la selección a la capa inferior a la actual" + +#: ../../po/../src/verbs.cpp:2016 +msgid "Move selection to the layer below the current" +msgstr "Mover la selección a la capa inferior a la actual" + +#: ../../po/../src/verbs.cpp:2017 +msgid "Layer to _Top" +msgstr "Traer la capa al fren_te" + +#: ../../po/../src/verbs.cpp:2018 +msgid "Raise the current layer to the top" +msgstr "Elevar la capa actual a primer plano" + +#: ../../po/../src/verbs.cpp:2019 +msgid "Layer to _Bottom" +msgstr "Bajar capa al _fondo" + +#: ../../po/../src/verbs.cpp:2020 +msgid "Lower the current layer to the bottom" +msgstr "Bajar la capa actual al fondo" + +#: ../../po/../src/verbs.cpp:2021 +msgid "_Raise Layer" +msgstr "Eleva_r capa" + +#: ../../po/../src/verbs.cpp:2022 +msgid "Raise the current layer" +msgstr "Elevar la capa actual" + +#: ../../po/../src/verbs.cpp:2023 +msgid "_Lower Layer" +msgstr "Ba_jar capa" + +#: ../../po/../src/verbs.cpp:2024 +msgid "Lower the current layer" +msgstr "Enviar la capa actual hacia abajo" + +#: ../../po/../src/verbs.cpp:2025 +msgid "_Delete Current Layer" +msgstr "_Borrar la capa actual" + +#: ../../po/../src/verbs.cpp:2026 +msgid "Delete the current layer" +msgstr "Eliminar la capa actual" + +#. Object +#: ../../po/../src/verbs.cpp:2029 +#, fuzzy +msgid "Rotate _90° CW" +msgstr "Rotar _90 grados a la derecha" + +#: ../../po/../src/verbs.cpp:2030 +#, fuzzy +msgid "Rotate selection 90° clockwise" +msgstr "Rotar la selección 90 grados a la derecha" + +#: ../../po/../src/verbs.cpp:2031 +#, fuzzy +msgid "Rotate 9_0° CCW" +msgstr "Rotar 9_0 grados a la izquierda" + +#: ../../po/../src/verbs.cpp:2032 +#, fuzzy +msgid "Rotate selection 90° counter-clockwise" +msgstr "Rotar la selección 90 grados a la izquierda" + +#: ../../po/../src/verbs.cpp:2033 +msgid "Remove _Transformations" +msgstr "Deshacer _transformaciones" + +#: ../../po/../src/verbs.cpp:2034 +msgid "Remove transformations from object" +msgstr "Eliminar transformaciones del objeto" + +#: ../../po/../src/verbs.cpp:2035 +msgid "_Object to Path" +msgstr "_Objeto a trazo" + +#: ../../po/../src/verbs.cpp:2036 +msgid "Convert selected objects to paths" +msgstr "Convierte el objeto seleccionado en trazos" + +#: ../../po/../src/verbs.cpp:2037 +msgid "_Flow into Frame" +msgstr "_Fluir en el marco" + +#: ../../po/../src/verbs.cpp:2038 +msgid "Put text into frames" +msgstr "Poner texto en marcos" + +#: ../../po/../src/verbs.cpp:2039 +msgid "_Unflow" +msgstr "Deshacer fl_ujo" + +#: ../../po/../src/verbs.cpp:2040 +msgid "Remove text from frame (creates a single-line text object)" +msgstr "" +"Eliminar el texto del marco (crea un objeto de texto de una sola línea)" + +#: ../../po/../src/verbs.cpp:2041 +msgid "_Convert to Text" +msgstr "_Convertir a texto" + +#: ../../po/../src/verbs.cpp:2042 +msgid "Convert flowed text to regular text objects (preserves appearance)" +msgstr "" +"Convertir el texto fluido seleccionado a objetos de texto (mantiene el " +"aspecto)" + +#: ../../po/../src/verbs.cpp:2044 +msgid "Flip _Horizontal" +msgstr "Reflejo _horizontal" + +#: ../../po/../src/verbs.cpp:2044 +msgid "Flips selected objects horizontally" +msgstr "Refleja los objetos seleccionados horizontalmente" + +#: ../../po/../src/verbs.cpp:2047 +msgid "Flip _Vertical" +msgstr "Reflejo _vertical" + +#: ../../po/../src/verbs.cpp:2047 +msgid "Flips selected objects vertically" +msgstr "Refleja los objetos seleccionados verticalmente" + +#. Tools +#: ../../po/../src/verbs.cpp:2051 +msgid "Select" +msgstr "Seleccionar" + +#: ../../po/../src/verbs.cpp:2052 +msgid "Select and transform objects" +msgstr "Seleccionar y transformar objetos" + +#: ../../po/../src/verbs.cpp:2053 +msgid "Node Edit" +msgstr "Edición de nodos" + +#: ../../po/../src/verbs.cpp:2054 +msgid "Edit path nodes or control handles" +msgstr "Editar nodos de trazo o tiradores de control" + +#: ../../po/../src/verbs.cpp:2056 +msgid "Create rectangles and squares" +msgstr "Crear rectángulos y cuadrados" + +#: ../../po/../src/verbs.cpp:2058 +msgid "Create circles, ellipses, and arcs" +msgstr "Crear círculos, elipses y arcos" + +#: ../../po/../src/verbs.cpp:2060 +msgid "Create stars and polygons" +msgstr "Crear estrellas y polígonos" + +#: ../../po/../src/verbs.cpp:2062 +msgid "Create spirals" +msgstr "Crear espirales" + +#: ../../po/../src/verbs.cpp:2064 +msgid "Draw freehand lines" +msgstr "Dibujar líneas a mano alzada" + +#: ../../po/../src/verbs.cpp:2066 +msgid "Draw Bezier curves and straight lines" +msgstr "Dibujar curvas Bézier y líneas rectas" + +#: ../../po/../src/verbs.cpp:2068 +msgid "Draw calligraphic lines" +msgstr "Dibujar líneas caligráficas" + +#: ../../po/../src/verbs.cpp:2070 +msgid "Create and edit text objects" +msgstr "Crear y editar objetos de texto" + +#: ../../po/../src/verbs.cpp:2072 +msgid "Create and edit gradients" +msgstr "Crear y editar gradientes" + +#: ../../po/../src/verbs.cpp:2074 +msgid "Zoom in or out" +msgstr "Acercar o alejar" + +#: ../../po/../src/verbs.cpp:2076 +msgid "Pick averaged colors from image" +msgstr "Seleccionar colores medios de la imagen" + +#: ../../po/../src/verbs.cpp:2078 +msgid "Create connectors" +msgstr "Crear conectores" + +#. Tool prefs +#: ../../po/../src/verbs.cpp:2081 +msgid "Selector Preferences" +msgstr "Preferencias del selector" + +#: ../../po/../src/verbs.cpp:2082 +msgid "Open Preferences for the Selector tool" +msgstr "Abrir las preferencias para la herramienta Selector" + +#: ../../po/../src/verbs.cpp:2083 +msgid "Node Tool Preferences" +msgstr "Preferencias de la herramienta nodo" + +#: ../../po/../src/verbs.cpp:2084 +msgid "Open Preferences for the Node tool" +msgstr "Abrir las preferencias para la herramienta Nodo" + +#: ../../po/../src/verbs.cpp:2085 +msgid "Rectangle Preferences" +msgstr "Preferencias de rectángulo" + +#: ../../po/../src/verbs.cpp:2086 +msgid "Open Preferences for the Rectangle tool" +msgstr "Abrir las preferencias para la herramienta Rectángulo" + +#: ../../po/../src/verbs.cpp:2087 +msgid "Ellipse Preferences" +msgstr "Preferencias de elipse" + +#: ../../po/../src/verbs.cpp:2088 +msgid "Open Preferences for the Ellipse tool" +msgstr "Abrir las preferencias para la herramienta Elipse" + +#: ../../po/../src/verbs.cpp:2089 +msgid "Star Preferences" +msgstr "Preferencias de estrella" + +#: ../../po/../src/verbs.cpp:2090 +msgid "Open Preferences for the Star tool" +msgstr "Abrir las preferencias para la herramienta Estrella" + +#: ../../po/../src/verbs.cpp:2091 +msgid "Spiral Preferences" +msgstr "Preferencias de espiral" + +#: ../../po/../src/verbs.cpp:2092 +msgid "Open Preferences for the Spiral tool" +msgstr "Abrir las preferencias para la herramienta Espiral" + +#: ../../po/../src/verbs.cpp:2093 +msgid "Pencil Preferences" +msgstr "Preferencias del lápiz" + +#: ../../po/../src/verbs.cpp:2094 +msgid "Open Preferences for the Pencil tool" +msgstr "Abrir las preferencias para la herramienta Lápiz" + +#: ../../po/../src/verbs.cpp:2095 +msgid "Pen Preferences" +msgstr "Preferencias de bolígrafo" + +#: ../../po/../src/verbs.cpp:2096 +msgid "Open Preferences for the Pen tool" +msgstr "Abrir las preferencias para la herramienta Bolígrafo" + +#: ../../po/../src/verbs.cpp:2097 +msgid "Calligraphic Preferences" +msgstr "Preferencias de línea caligráfica" + +#: ../../po/../src/verbs.cpp:2098 +msgid "Open Preferences for the Calligraphy tool" +msgstr "Abrir las preferencias para la herramienta Caligrafía" + +#: ../../po/../src/verbs.cpp:2099 +msgid "Text Preferences" +msgstr "Preferencias de texto" + +#: ../../po/../src/verbs.cpp:2100 +msgid "Open Preferences for the Text tool" +msgstr "Abrir las preferencias para la herramienta Texto" + +#: ../../po/../src/verbs.cpp:2101 +msgid "Gradient Preferences" +msgstr "Preferencias de gradiente" + +#: ../../po/../src/verbs.cpp:2102 +msgid "Open Preferences for the Gradient tool" +msgstr "Abrir las preferencias para la herramienta Gradiente" + +#: ../../po/../src/verbs.cpp:2103 +msgid "Zoom Preferences" +msgstr "Preferencias de zoom" + +#: ../../po/../src/verbs.cpp:2104 +msgid "Open Preferences for the Zoom tool" +msgstr "Abrir las preferencias para la herramienta Zoom" + +#: ../../po/../src/verbs.cpp:2105 +msgid "Dropper Preferences" +msgstr "Preferencias de gotero" + +#: ../../po/../src/verbs.cpp:2106 +msgid "Open Preferences for the Dropper tool" +msgstr "Abrir las preferencias para la herramienta Gotero" + +#: ../../po/../src/verbs.cpp:2107 +msgid "Connector Preferences" +msgstr "Preferencias del conector" + +#: ../../po/../src/verbs.cpp:2108 +msgid "Open Preferences for the Connector tool" +msgstr "Abrir las preferencias para la herramienta Conector" + +#. Zoom/View +#: ../../po/../src/verbs.cpp:2111 +msgid "Zoom In" +msgstr "Acercar" + +#: ../../po/../src/verbs.cpp:2111 +msgid "Zoom in" +msgstr "Acercar" + +#: ../../po/../src/verbs.cpp:2112 +msgid "Zoom Out" +msgstr "Alejar" + +#: ../../po/../src/verbs.cpp:2112 +msgid "Zoom out" +msgstr "Alejar" + +#: ../../po/../src/verbs.cpp:2113 +msgid "_Rulers" +msgstr "_Reglas" + +#: ../../po/../src/verbs.cpp:2113 +msgid "Show or hide the canvas rulers" +msgstr "Mostrar/ocultar las reglas del lienzo" + +#: ../../po/../src/verbs.cpp:2114 +msgid "Scroll_bars" +msgstr "_Barras de desplazamiento" + +#: ../../po/../src/verbs.cpp:2114 +msgid "Show or hide the canvas scrollbars" +msgstr "Mostrar/ocultar las barras de desplazamiento del lienzo" + +#: ../../po/../src/verbs.cpp:2115 +msgid "_Grid" +msgstr "Re_jilla" + +#: ../../po/../src/verbs.cpp:2116 +msgid "G_uides" +msgstr "G_uías" + +#: ../../po/../src/verbs.cpp:2117 +msgid "Nex_t Zoom" +msgstr "Zoom siguien_te" + +#: ../../po/../src/verbs.cpp:2117 +msgid "Next zoom (from the history of zooms)" +msgstr "Siguiente zoom (del historial de zooms)" + +#: ../../po/../src/verbs.cpp:2119 +msgid "Pre_vious Zoom" +msgstr "Zoom a_nterior" + +#: ../../po/../src/verbs.cpp:2119 +msgid "Previous zoom (from the history of zooms)" +msgstr "Zoom previo (del historial de zooms)" + +#: ../../po/../src/verbs.cpp:2121 +msgid "Zoom 1:_1" +msgstr "Zoom 1:_1" + +#: ../../po/../src/verbs.cpp:2121 +msgid "Zoom to 1:1" +msgstr "Zoom a 1:1" + +#: ../../po/../src/verbs.cpp:2123 +msgid "Zoom 1:_2" +msgstr "Zoom 1:2" + +#: ../../po/../src/verbs.cpp:2123 +msgid "Zoom to 1:2" +msgstr "Zoom a 1:2" + +#: ../../po/../src/verbs.cpp:2125 +msgid "_Zoom 2:1" +msgstr "_Zoom 2:1" + +#: ../../po/../src/verbs.cpp:2125 +msgid "Zoom to 2:1" +msgstr "_Zoom a 2:1" + +#: ../../po/../src/verbs.cpp:2128 +msgid "_Fullscreen" +msgstr "_Pantalla completa" + +#: ../../po/../src/verbs.cpp:2128 +msgid "Stretch this document window to full screen" +msgstr "Ampliar esta ventana al tamaño de la pantalla" + +#: ../../po/../src/verbs.cpp:2131 +msgid "Duplic_ate Window" +msgstr "Duplic_ar ventana" + +#: ../../po/../src/verbs.cpp:2131 +msgid "Open a new window with the same document" +msgstr "Abre una nueva ventana con el mismo documento" + +#: ../../po/../src/verbs.cpp:2133 +msgid "_New View Preview" +msgstr "_Nueva vista preliminar" + +#: ../../po/../src/verbs.cpp:2134 +msgid "New View Preview" +msgstr "Nueva vista preliminar" + +#. "view_new_preview" +#: ../../po/../src/verbs.cpp:2136 +#, fuzzy +msgid "_Normal" +msgstr "Normal" + +#: ../../po/../src/verbs.cpp:2137 +msgid "Switch to normal display mode" +msgstr "" + +#: ../../po/../src/verbs.cpp:2138 +#, fuzzy +msgid "_Outline" +msgstr "Caja de contorno" + +#: ../../po/../src/verbs.cpp:2139 +msgid "Switch to outline (wireframe) display mode" +msgstr "" + +#: ../../po/../src/verbs.cpp:2141 +msgid "Ico_n Preview" +msgstr "Vista de ico_no" + +#: ../../po/../src/verbs.cpp:2142 +msgid "Open a window to preview items at different icon resolutions" +msgstr "" +"Abrir una ventana para ver elementos en diferentes resoluciones de icono" + +#: ../../po/../src/verbs.cpp:2144 +msgid "Zoom to fit page in window" +msgstr "Ajustar la página a la ventana" + +#: ../../po/../src/verbs.cpp:2145 +msgid "Page _Width" +msgstr "An_cho de página" + +#: ../../po/../src/verbs.cpp:2146 +msgid "Zoom to fit page width in window" +msgstr "Ajustar la anchura de la página a la ventana" + +#: ../../po/../src/verbs.cpp:2148 +msgid "Zoom to fit drawing in window" +msgstr "Ajustar el dibujo a la ventana" + +#: ../../po/../src/verbs.cpp:2150 +msgid "Zoom to fit selection in window" +msgstr "Ajustar la selección a la ventana" + +#. Dialogs +#: ../../po/../src/verbs.cpp:2153 +msgid "In_kscape Preferences..." +msgstr "Preferencias de In_kscape..." + +#: ../../po/../src/verbs.cpp:2154 +msgid "Global Inkscape preferences" +msgstr "Preferencias globales de Inkscape" + +#: ../../po/../src/verbs.cpp:2155 +msgid "_Document Preferences..." +msgstr "Preferencias del _documento..." + +#: ../../po/../src/verbs.cpp:2156 +msgid "Preferences saved with the document" +msgstr "Opciones guardadas con el documento" + +#: ../../po/../src/verbs.cpp:2157 +msgid "_Fill and Stroke..." +msgstr "_Relleno y borde..." + +#: ../../po/../src/verbs.cpp:2158 +msgid "Fill and Stroke dialog" +msgstr "Diálogo de relleno y borde" + +#. TRANSLATORS: "Swatches" means: color samples +#: ../../po/../src/verbs.cpp:2160 +msgid "S_watches..." +msgstr "M_uestras..." + +#: ../../po/../src/verbs.cpp:2161 +msgid "View color swatches" +msgstr "Ver muestras de color" + +#: ../../po/../src/verbs.cpp:2162 +msgid "Transfor_m..." +msgstr "Transfor_mar..." + +#: ../../po/../src/verbs.cpp:2163 +msgid "Transform dialog" +msgstr "Diálogo de transformación" + +#: ../../po/../src/verbs.cpp:2164 +msgid "_Align and Distribute..." +msgstr "_Alinear y distribuir..." + +#: ../../po/../src/verbs.cpp:2165 +msgid "Align and Distribute dialog" +msgstr "Diálogo de alineación y distribución" + +#: ../../po/../src/verbs.cpp:2166 +msgid "_Text and Font..." +msgstr "_Texto y tipografía..." + +#: ../../po/../src/verbs.cpp:2167 +msgid "Text and Font dialog" +msgstr "Diálogo de texto y tipografía" + +#: ../../po/../src/verbs.cpp:2168 +msgid "_XML Editor..." +msgstr "Editor _XML..." + +#: ../../po/../src/verbs.cpp:2169 +msgid "XML Editor" +msgstr "Editor XML" + +#: ../../po/../src/verbs.cpp:2170 +msgid "_Find..." +msgstr "_Buscar..." + +#: ../../po/../src/verbs.cpp:2171 +msgid "Find objects in document" +msgstr "Buscar objetos en el documento" + +#: ../../po/../src/verbs.cpp:2172 +msgid "_Messages..." +msgstr "_Mensajes..." + +#: ../../po/../src/verbs.cpp:2173 +msgid "View debug messages" +msgstr "Ver los mensajes de depuración" + +#: ../../po/../src/verbs.cpp:2174 +msgid "S_cripts..." +msgstr "S_cripts..." + +#: ../../po/../src/verbs.cpp:2175 +msgid "Run scripts" +msgstr "Ejecutar scripts" + +#: ../../po/../src/verbs.cpp:2176 +msgid "Show/Hide D_ialogs" +msgstr "Mostrar/ocultar d_iálogos" + +#: ../../po/../src/verbs.cpp:2177 +msgid "Show or hide all active dialogs" +msgstr "Mostrar/ocultar todos los diálogos activos" + +#. TRANSLATORS: "Tile clones" means: "Create tiled clones" +#: ../../po/../src/verbs.cpp:2179 +msgid "Tile clones..." +msgstr "Clones en mosaico..." + +#: ../../po/../src/verbs.cpp:2180 +msgid "Create and arrange multiple clones of selection" +msgstr "Crear y ordenar varios clones de la selección" + +#: ../../po/../src/verbs.cpp:2181 +msgid "_Object Properties..." +msgstr "Propiedades del _objeto..." + +#: ../../po/../src/verbs.cpp:2182 +msgid "Object Properties dialog" +msgstr "Diálogo de propiedades del objeto" + +#: ../../po/../src/verbs.cpp:2185 +msgid "_Connect to Jabber server..." +msgstr "_Conectar al servidor Jabber..." + +#: ../../po/../src/verbs.cpp:2185 +msgid "Connect to a Jabber server" +msgstr "Conectar a un servidor Jabber" + +#: ../../po/../src/verbs.cpp:2187 +msgid "Share with _user..." +msgstr "Compartir con _usuario..." + +#: ../../po/../src/verbs.cpp:2187 +msgid "Establish a whiteboard session with another Jabber user" +msgstr "Establecer una sesión de pizarra blanca con otro usuario Jabber" + +#: ../../po/../src/verbs.cpp:2189 +msgid "Share with _chatroom..." +msgstr "_Compartir con una sala..." + +#: ../../po/../src/verbs.cpp:2189 +msgid "" +"Join a chatroom to start a new whiteboard session or join one in progress" +msgstr "" +"Unirse a una sala de chat para iniciar una nueva sesión de pizarra blanca o " +"unirse a una en ejecución" + +#: ../../po/../src/verbs.cpp:2191 +msgid "_Dump XML node tracker" +msgstr "_Volcar el explorador de nodos XML" + +#: ../../po/../src/verbs.cpp:2191 +msgid "Dump the contents of the XML tracker to the console" +msgstr "Volcar el explorador de nodos XML a la consola" + +#: ../../po/../src/verbs.cpp:2193 +msgid "_Open session file..." +msgstr "_Abrir un archivo de sesión..." + +#: ../../po/../src/verbs.cpp:2193 +msgid "Open and browse through records of past whiteboard sessions" +msgstr "" +"Abrir y explorar los registros de sesiones de pizarra blanca anteriores" + +#: ../../po/../src/verbs.cpp:2195 +msgid "Session file playback" +msgstr "Reproducción del archivo de sesión" + +#: ../../po/../src/verbs.cpp:2197 +msgid "_Disconnect from session" +msgstr "_Desconectar de la sesión" + +#: ../../po/../src/verbs.cpp:2199 +msgid "Disconnect from _server" +msgstr "Desconectar del _servidor" + +#: ../../po/../src/verbs.cpp:2201 +msgid "_Input Devices..." +msgstr "Dispositivos de _entrada..." + +#: ../../po/../src/verbs.cpp:2202 +msgid "Configure extended input devices" +msgstr "Configurar dispositivos de entrada extendidos" + +#. Help +#: ../../po/../src/verbs.cpp:2205 +msgid "_Keys and Mouse" +msgstr "_Teclas y ratón" + +#: ../../po/../src/verbs.cpp:2206 +msgid "Key and mouse shortcuts reference" +msgstr "Referencia de atajos de teclado y ratón" + +#: ../../po/../src/verbs.cpp:2207 +msgid "About E_xtensions" +msgstr "Acerca de e_xtensiones" + +#: ../../po/../src/verbs.cpp:2208 +msgid "About Extensions..." +msgstr "Acerca de e_xtensiones..." + +#: ../../po/../src/verbs.cpp:2209 +msgid "About _Memory" +msgstr "Acerca de _memoria" + +#: ../../po/../src/verbs.cpp:2210 +msgid "About Memory..." +msgstr "Acerca de _memoria..." + +#: ../../po/../src/verbs.cpp:2211 +msgid "_About Inkscape" +msgstr "_Acerca de Inkscape" + +#. "help_about" +#. new HelpVerb(SP_VERB_SHOW_LICENSE, "ShowLicense", N_("Modifying or Redistributing Inkscape"), +#. N_("Show license to modify and/or redistribute Inkscape: GNU GPL"), NULL), +#. Tutorials +#: ../../po/../src/verbs.cpp:2217 +msgid "Inkscape: _Basic" +msgstr "Inkscape: _Básico" + +#: ../../po/../src/verbs.cpp:2218 +msgid "Getting started with Inkscape" +msgstr "Introducción a Inkscape" + +#. "tutorial_basic" +#: ../../po/../src/verbs.cpp:2219 +msgid "Inkscape: _Shapes" +msgstr "Inkscape: _Formas" + +#: ../../po/../src/verbs.cpp:2220 +msgid "Using shape tools to create and edit shapes" +msgstr "Cómo usar las herramientas de forma para crear y editar formas" + +#: ../../po/../src/verbs.cpp:2221 +msgid "Inkscape: _Advanced" +msgstr "Inkscape: _Avanzado" + +#: ../../po/../src/verbs.cpp:2222 +msgid "Advanced Inkscape topics" +msgstr "Temas avanzados de Inkscape" + +#. "tutorial_advanced" +#. TRANSLATORS: "to trace" means "to convert a bitmap to vector graphics" (to vectorize) +#: ../../po/../src/verbs.cpp:2224 +msgid "Inkscape: T_racing" +msgstr "Inkscape: Vecto_rizar" + +#: ../../po/../src/verbs.cpp:2225 +msgid "Using bitmap tracing" +msgstr "Usar trazado de mapa de bits" + +#. "tutorial_tracing" +#: ../../po/../src/verbs.cpp:2226 +msgid "Inkscape: _Calligraphy" +msgstr "Inkscape: _Caligrafía" + +#: ../../po/../src/verbs.cpp:2227 +msgid "Using the Calligraphy pen tool" +msgstr "Cómo usar la herramienta de pluma caligráfica" + +#: ../../po/../src/verbs.cpp:2228 +msgid "_Elements of Design" +msgstr "_Elementos de diseño" + +#: ../../po/../src/verbs.cpp:2229 +msgid "Principles of design in the tutorial form" +msgstr "Principios de diseño en forma de tutorial" + +#. "tutorial_design" +#: ../../po/../src/verbs.cpp:2230 +msgid "_Tips and Tricks" +msgstr "_Trucos y consejos" + +#: ../../po/../src/verbs.cpp:2231 +msgid "Miscellaneous tips and tricks" +msgstr "Trucos y consejos varios" + +#. "tutorial_tips" +#. Effect +#: ../../po/../src/verbs.cpp:2234 +msgid "Previous Effect" +msgstr "Efecto anterior" + +#: ../../po/../src/verbs.cpp:2235 +msgid "Repeat the last effect with the same settings" +msgstr "Repetir el último efecto con los mismos ajustes" + +#. "tutorial_tips" +#: ../../po/../src/verbs.cpp:2236 +msgid "Previous Effect Settings..." +msgstr "Ajustes del efecto anterior..." + +#: ../../po/../src/verbs.cpp:2237 +msgid "Repeat the last effect with new settings" +msgstr "Repetir el último efecto con ajustes nuevos" + +#: ../../po/../src/widgets/dash-selector.cpp:106 +msgid "Dash pattern" +msgstr "Patrón de rayas" + +#: ../../po/../src/widgets/dash-selector.cpp:121 +msgid "Pattern offset" +msgstr "Desvío del patrón" + +#: ../../po/../src/widgets/desktop-widget.cpp:240 +msgid "Zoom drawing if window size changes" +msgstr "Ajustar el dibujo a la ventana si cambia el tamaño de ésta" + +#: ../../po/../src/widgets/desktop-widget.cpp:298 +msgid "Cursor coordinates" +msgstr "Coordenadas del cursor" + +# display the initial welcome message in the statusbar +#. display the initial welcome message in the statusbar +#: ../../po/../src/widgets/desktop-widget.cpp:324 +msgid "" +"Welcome to Inkscape! Use shape or freehand tools to create objects; " +"use selector (arrow) to move or transform them." +msgstr "" +"Bienvenido a Inkscape. Utilice las herramientas de forma o mano " +"alzada para crear objetos; utilice el selector (flecha) para moverlos o " +"transformarlos." + +#: ../../po/../src/widgets/desktop-widget.cpp:372 +#, c-format +msgid "%s: %d - Inkscape" +msgstr "%s: %d - Inkscape" + +#: ../../po/../src/widgets/desktop-widget.cpp:374 +#, c-format +msgid "%s - Inkscape" +msgstr "%s - Inkscape" + +#: ../../po/../src/widgets/desktop-widget.cpp:532 +#, c-format +msgid "" +"Save changes to document \"%s\" before " +"closing?\n" +"\n" +"If you close without saving, your changes will be discarded." +msgstr "" +"¿Desea guardar los cambios en el " +"documento «%s» antes de cerrar?\n" +"\n" +"Si cierra sin guardar se perderán los cambios realizados." + +#: ../../po/../src/widgets/desktop-widget.cpp:548 +#: ../../po/../src/widgets/desktop-widget.cpp:612 +msgid "Close _without saving" +msgstr "Cerrar _sin guardar" + +#: ../../po/../src/widgets/desktop-widget.cpp:595 +#, c-format +msgid "" +"The file \"%s\" was saved with a " +"format (%s) that may cause data loss!\n" +"\n" +"Do you want to save this file in another format?" +msgstr "" +"Se guardó el archivo \"%s\" con un " +"formato (%s) que puede causar pérdida de datos.\n" +"\n" +"¿Desea guardar el archivo en otro formato?" + +#. Family frame +#: ../../po/../src/widgets/font-selector.cpp:156 +msgid "Font family" +msgstr "Familia de tipografías" + +#. Style frame +#: ../../po/../src/widgets/font-selector.cpp:184 +msgid "Style" +msgstr "Estilo" + +#: ../../po/../src/widgets/font-selector.cpp:219 +msgid "Font size:" +msgstr "Tamaño de tipografía:" + +#. TRANSLATORS: Test string used in text and font dialog (when no +#. * text has been entered) to get a preview of the font. Choose +#. * some representative characters that users of your locale will be +#. * interested in. +#: ../../po/../src/widgets/font-selector.cpp:554 +msgid "AaBbCcIiPpQq12368.;/()" +msgstr "AaBbCcIiÁáÑñPpQq12368.;/()" + +#: ../../po/../src/widgets/gradient-selector.cpp:137 +#: ../../po/../src/widgets/gradient-toolbar.cpp:524 +msgid "Duplicate" +msgstr "Duplicar" + +#: ../../po/../src/widgets/gradient-selector.cpp:142 +#: ../../po/../src/widgets/gradient-toolbar.cpp:535 +msgid "Edit..." +msgstr "Editar..." + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/pservers.html#LinearGradientSpreadMethodAttribute +#: ../../po/../src/widgets/gradient-selector.cpp:159 +msgid "" +"Whether to fill with flat color beyond the ends of the gradient vector " +"(spreadMethod=\"pad\"), or repeat the gradient in the same direction " +"(spreadMethod=\"repeat\"), or repeat the gradient in alternating opposite " +"directions (spreadMethod=\"reflect\")" +msgstr "" +"Indica si se rellena con color uniforme más allá de los fines del vector de " +"gradiente (spreadMethod=\"pad\"), se repite el gradiente en la misma " +"dirección (spreadMethod=\"repeat\"), o se repite el gradiente en direcciones " +"opuestas alternativas (spreadMethod=\"reflect\")" + +#: ../../po/../src/widgets/gradient-selector.cpp:165 +msgid "none" +msgstr "ninguno" + +#: ../../po/../src/widgets/gradient-selector.cpp:169 +msgid "reflected" +msgstr "reflejado" + +#: ../../po/../src/widgets/gradient-selector.cpp:173 +msgid "direct" +msgstr "directo" + +#: ../../po/../src/widgets/gradient-selector.cpp:181 +msgid "Repeat:" +msgstr "Repetir:" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:217 +msgid "No gradients" +msgstr "Sin gradientes" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:226 +msgid "Nothing selected" +msgstr "Sin selección" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:237 +msgid "No gradients in selection" +msgstr "No hay gradientes en la selección" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:247 +msgid "Multiple gradients" +msgstr "Varios gradientes" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:525 +msgid "" +"If the gradient is used by more than one object, create a copy of it for the " +"selected object(s)" +msgstr "" +"Si más de un objeto usa el gradiente, crear una copia para el objeto " +"seleccionado" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:536 +msgid "Edit the stops of the gradient" +msgstr "Editar las paradas del gradiente" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:593 +#: ../../po/../src/widgets/toolbox.cpp:1103 +#: ../../po/../src/widgets/toolbox.cpp:1192 +#: ../../po/../src/widgets/toolbox.cpp:1485 +#: ../../po/../src/widgets/toolbox.cpp:1534 +#: ../../po/../src/widgets/toolbox.cpp:1766 +#: ../../po/../src/widgets/toolbox.cpp:1801 +#: ../../po/../src/widgets/toolbox.cpp:2331 +#: ../../po/../src/widgets/toolbox.cpp:2370 +msgid "New:" +msgstr "Nuevo:" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:606 +msgid "Create linear gradient" +msgstr "Crear gradiente lineal" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:620 +msgid "Create radial (elliptic or circular) gradient" +msgstr "Crear gradiente radial (elíptico o circular)" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:635 +msgid "on" +msgstr "en" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:648 +msgid "Create gradient in the fill" +msgstr "Crear gradiente en el relleno" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:662 +msgid "Create gradient in the stroke" +msgstr "Crear gradiente en el trazo" + +# FIXME: implement averaging of all parameters for multiple selected stars +# gtk_label_set_markup (GTK_LABEL(l), _("Average:")); +# FIXME: implement averaging of all parameters for multiple selected +# gtk_label_set_markup (GTK_LABEL(l), _("Average:")); +#. FIXME: implement averaging of all parameters for multiple selected stars +#. gtk_label_set_markup(GTK_LABEL(l), _("Average:")); +#. FIXME: implement averaging of all parameters for multiple selected +#. gtk_label_set_markup(GTK_LABEL(l), _("Average:")); +#: ../../po/../src/widgets/gradient-toolbar.cpp:676 +#: ../../po/../src/widgets/toolbox.cpp:1105 +#: ../../po/../src/widgets/toolbox.cpp:1124 +#: ../../po/../src/widgets/toolbox.cpp:1493 +#: ../../po/../src/widgets/toolbox.cpp:1518 +#: ../../po/../src/widgets/toolbox.cpp:1768 +#: ../../po/../src/widgets/toolbox.cpp:1787 +#: ../../po/../src/widgets/toolbox.cpp:2334 +#: ../../po/../src/widgets/toolbox.cpp:2354 +msgid "Change:" +msgstr "Cambio:" + +#: ../../po/../src/widgets/gradient-vector.cpp:269 +msgid "No gradients in document" +msgstr "Sin gradientes en el documento" + +#: ../../po/../src/widgets/gradient-vector.cpp:275 +msgid "No gradient selected" +msgstr "Sin gradiente seleccionado" + +#: ../../po/../src/widgets/gradient-vector.cpp:532 +msgid "No stops in gradient" +msgstr "Gradiente sin paradas" + +#. TRANSLATORS: "Stop" means: a "phase" of a gradient +#: ../../po/../src/widgets/gradient-vector.cpp:794 +msgid "Add stop" +msgstr "Añadir parada" + +#: ../../po/../src/widgets/gradient-vector.cpp:797 +msgid "Add another control stop to gradient" +msgstr "Añadir otro control de parada al gradiente" + +#: ../../po/../src/widgets/gradient-vector.cpp:799 +msgid "Delete stop" +msgstr "Borrar parada" + +#: ../../po/../src/widgets/gradient-vector.cpp:802 +msgid "Delete current control stop from gradient" +msgstr "Eliminar el control de parada actual" + +#. Label +#: ../../po/../src/widgets/gradient-vector.cpp:813 +msgid "Offset:" +msgstr "Desvío:" + +#. TRANSLATORS: "Stop" means: a "phase" of a gradient +#: ../../po/../src/widgets/gradient-vector.cpp:858 +msgid "Stop Color" +msgstr "Color de parada" + +#: ../../po/../src/widgets/gradient-vector.cpp:887 +msgid "Gradient editor" +msgstr "Editor de gradiente" + +#: ../../po/../src/widgets/layer-selector.cpp:119 +msgid "Toggle current layer visibility" +msgstr "Intercambiar la visibilidad de la capa actual" + +#: ../../po/../src/widgets/layer-selector.cpp:139 +msgid "Lock or unlock current layer" +msgstr "Bloquear o desbloquear la capa actual" + +#: ../../po/../src/widgets/layer-selector.cpp:142 +msgid "Current layer" +msgstr "Capa actual" + +#: ../../po/../src/widgets/layer-selector.cpp:553 +msgid "(root)" +msgstr "(raíz)" + +#: ../../po/../src/widgets/paint-selector.cpp:182 +#: ../../po/../src/widgets/paint-selector.cpp:561 +msgid "No paint" +msgstr "Sin relleno" + +#: ../../po/../src/widgets/paint-selector.cpp:184 +#: ../../po/../src/widgets/paint-selector.cpp:629 +msgid "Flat color" +msgstr "Color uniforme" + +#: ../../po/../src/widgets/paint-selector.cpp:186 +#: ../../po/../src/widgets/paint-selector.cpp:696 +msgid "Linear gradient" +msgstr "Gradiente lineal" + +#: ../../po/../src/widgets/paint-selector.cpp:188 +#: ../../po/../src/widgets/paint-selector.cpp:699 +msgid "Radial gradient" +msgstr "Gradiente radial" + +#: ../../po/../src/widgets/paint-selector.cpp:192 +msgid "Unset paint (make it undefined so it can be inherited)" +msgstr "Desajustar color (hacerlo indefinido para que no pueda ser heredado)" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/painting.html#FillRuleProperty +#: ../../po/../src/widgets/paint-selector.cpp:204 +msgid "" +"Any path self-intersections or subpaths create holes in the fill (fill-rule: " +"evenodd)" +msgstr "" +"Cualquier autointersección de un trazo o subtrazo crea agujeros en el " +"relleno (regla de relleno: parimpar)" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/painting.html#FillRuleProperty +#: ../../po/../src/widgets/paint-selector.cpp:215 +msgid "" +"Fill is solid unless a subpath is counterdirectional (fill-rule: nonzero)" +msgstr "" +"El relleno es sólido a no ser que un subtrazo sea contradireccional (regla " +"de relleno: no-cero)" + +#: ../../po/../src/widgets/paint-selector.cpp:528 +msgid "No objects" +msgstr "Sin objetos" + +#: ../../po/../src/widgets/paint-selector.cpp:539 +msgid "Multiple styles" +msgstr "Múltiples estilos" + +#: ../../po/../src/widgets/paint-selector.cpp:550 +msgid "Paint is undefined" +msgstr "El color es indefinido" + +#: ../../po/../src/widgets/paint-selector.cpp:757 +msgid "No patterns in document" +msgstr "Sin patrones en el documento" + +#: ../../po/../src/widgets/paint-selector.cpp:872 +msgid "" +"Use Edit > Object(s) to Pattern to create a new pattern from " +"selection." +msgstr "" +"Utilice Edición > Objetos a patrón para crear un patrón de mosaico " +"desde la selección." + +#: ../../po/../src/widgets/select-toolbar.cpp:426 +msgid "Now stroke width is scaled when objects are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:428 +msgid "Now stroke width is not scaled when objects are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:436 +msgid "" +"Now rounded rectangle corners are scaled when rectangles are " +"scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:438 +msgid "" +"Now rounded rectangle corners are not scaled when rectangles " +"are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:446 +msgid "" +"Now gradients are transformed along with their objects when " +"those are transformed (moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:448 +msgid "" +"Now gradients remain fixed when objects are transformed " +"(moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:456 +msgid "" +"Now patterns are transformed along with their objects when " +"those are transformed (moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:458 +msgid "" +"Now patterns remain fixed when objects are transformed (moved, " +"scaled, rotated, or skewed)." +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:506 +msgid "select_toolbar|X" +msgstr "select_toolbar|X" + +#: ../../po/../src/widgets/select-toolbar.cpp:506 +msgid "Horizontal coordinate of selection" +msgstr "Coordenada horizontal de la selección" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:511 +msgid "select_toolbar|Y" +msgstr "select_toolbar|Y" + +#: ../../po/../src/widgets/select-toolbar.cpp:511 +msgid "Vertical coordinate of selection" +msgstr "Coordenada vertical de la selección" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:517 +msgid "select_toolbar|W" +msgstr "select_toolbar|W" + +#: ../../po/../src/widgets/select-toolbar.cpp:517 +msgid "Width of selection" +msgstr "Ancho de la selección" + +#: ../../po/../src/widgets/select-toolbar.cpp:525 +msgid "Change both width and height by the same proportion" +msgstr "Cambiar tanto el alto como el ancho en la misma proporción" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:534 +msgid "select_toolbar|H" +msgstr "select_toolbar|H" + +#: ../../po/../src/widgets/select-toolbar.cpp:534 +msgid "Height of selection" +msgstr "Altura de la selección" + +#: ../../po/../src/widgets/sp-color-gtkselector.cpp:62 +msgid "System" +msgstr "Sistema" + +#: ../../po/../src/widgets/sp-color-notebook.cpp:322 +msgid "RGBA_:" +msgstr "RGBA_:" + +#: ../../po/../src/widgets/sp-color-notebook.cpp:330 +msgid "Hexadecimal RGBA value of the color" +msgstr "Valor hexadecimal RGBA del color" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "RGB" +msgstr "RGB" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "HSL" +msgstr "HSL" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "CMYK" +msgstr "CMYK" + +#: ../../po/../src/widgets/sp-color-scales.cpp:397 +msgid "_R" +msgstr "_R" + +#: ../../po/../src/widgets/sp-color-scales.cpp:398 +#: ../../po/../src/widgets/sp-color-scales.cpp:399 +msgid "Red" +msgstr "Rojo" + +#: ../../po/../src/widgets/sp-color-scales.cpp:400 +msgid "_G" +msgstr "_G" + +#: ../../po/../src/widgets/sp-color-scales.cpp:401 +#: ../../po/../src/widgets/sp-color-scales.cpp:402 +msgid "Green" +msgstr "Verde" + +#: ../../po/../src/widgets/sp-color-scales.cpp:403 +msgid "_B" +msgstr "_B" + +#: ../../po/../src/widgets/sp-color-scales.cpp:404 +#: ../../po/../src/widgets/sp-color-scales.cpp:405 +msgid "Blue" +msgstr "Azul" + +#. Label +#: ../../po/../src/widgets/sp-color-scales.cpp:406 +#: ../../po/../src/widgets/sp-color-scales.cpp:432 +#: ../../po/../src/widgets/sp-color-scales.cpp:463 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:141 +msgid "_A" +msgstr "_A" + +#: ../../po/../src/widgets/sp-color-scales.cpp:407 +#: ../../po/../src/widgets/sp-color-scales.cpp:408 +#: ../../po/../src/widgets/sp-color-scales.cpp:433 +#: ../../po/../src/widgets/sp-color-scales.cpp:434 +#: ../../po/../src/widgets/sp-color-scales.cpp:464 +#: ../../po/../src/widgets/sp-color-scales.cpp:465 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:151 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:163 +msgid "Alpha (opacity)" +msgstr "Alfa (opacidad)" + +#: ../../po/../src/widgets/sp-color-scales.cpp:423 +msgid "_H" +msgstr "_H" + +#: ../../po/../src/widgets/sp-color-scales.cpp:424 +#: ../../po/../src/widgets/sp-color-scales.cpp:425 +msgid "Hue" +msgstr "Tono" + +#: ../../po/../src/widgets/sp-color-scales.cpp:426 +msgid "_S" +msgstr "_S" + +#: ../../po/../src/widgets/sp-color-scales.cpp:427 +#: ../../po/../src/widgets/sp-color-scales.cpp:428 +msgid "Saturation" +msgstr "Saturación" + +#: ../../po/../src/widgets/sp-color-scales.cpp:429 +msgid "_L" +msgstr "_L" + +#: ../../po/../src/widgets/sp-color-scales.cpp:430 +#: ../../po/../src/widgets/sp-color-scales.cpp:431 +msgid "Lightness" +msgstr "Claridad" + +#: ../../po/../src/widgets/sp-color-scales.cpp:451 +msgid "_C" +msgstr "_C" + +#: ../../po/../src/widgets/sp-color-scales.cpp:452 +#: ../../po/../src/widgets/sp-color-scales.cpp:453 +msgid "Cyan" +msgstr "Cian" + +#: ../../po/../src/widgets/sp-color-scales.cpp:454 +msgid "_M" +msgstr "_M" + +#: ../../po/../src/widgets/sp-color-scales.cpp:455 +#: ../../po/../src/widgets/sp-color-scales.cpp:456 +msgid "Magenta" +msgstr "Magenta" + +#: ../../po/../src/widgets/sp-color-scales.cpp:457 +msgid "_Y" +msgstr "_Y" + +#: ../../po/../src/widgets/sp-color-scales.cpp:458 +#: ../../po/../src/widgets/sp-color-scales.cpp:459 +msgid "Yellow" +msgstr "Amarillo" + +#: ../../po/../src/widgets/sp-color-scales.cpp:460 +msgid "_K" +msgstr "_K" + +#: ../../po/../src/widgets/sp-color-selector.cpp:71 +msgid "Unnamed" +msgstr "Sin nombre" + +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:68 +msgid "Wheel" +msgstr "Rueda" + +#: ../../po/../src/widgets/sp-xmlview-attr-list.cpp:53 +msgid "Attribute" +msgstr "Atributo" + +#: ../../po/../src/widgets/sp-xmlview-attr-list.cpp:54 +msgid "Value" +msgstr "Valor" + +#: ../../po/../src/widgets/toolbox.cpp:424 +msgid "Insert new nodes into selected segments" +msgstr "Insertar los nuevos nodos entre los segmentos seleccionados" + +#: ../../po/../src/widgets/toolbox.cpp:426 +msgid "Delete selected nodes" +msgstr "Suprimir los nodos seleccionados" + +#: ../../po/../src/widgets/toolbox.cpp:431 +msgid "Join paths at selected nodes" +msgstr "Unir los trazos en los nodos seleccionados." + +#: ../../po/../src/widgets/toolbox.cpp:433 +msgid "Join paths at selected nodes with new segment" +msgstr "Unir los trazos en los nodos seleccionados con un segmento nuevo" + +#: ../../po/../src/widgets/toolbox.cpp:436 +msgid "Split path between two non-endpoint nodes" +msgstr "Separar el trazo entre dos nodos." + +#: ../../po/../src/widgets/toolbox.cpp:439 +msgid "Break path at selected nodes" +msgstr "Romper el trazo en los nodos seleccionados" + +#: ../../po/../src/widgets/toolbox.cpp:444 +msgid "Make selected nodes corner" +msgstr "Convertir en esquina los nodos seleccionados" + +#: ../../po/../src/widgets/toolbox.cpp:447 +msgid "Make selected nodes smooth" +msgstr "Suavizar los nodos seleccionados" + +#: ../../po/../src/widgets/toolbox.cpp:450 +msgid "Make selected nodes symmetric" +msgstr "Hacer simétricos los nodos seleccionados." + +#: ../../po/../src/widgets/toolbox.cpp:455 +msgid "Make selected segments lines" +msgstr "Convertir los segmentos seleccionados en líneas" + +#: ../../po/../src/widgets/toolbox.cpp:458 +msgid "Make selected segments curves" +msgstr "Convertir los segmentos seleccionados a curvas" + +#: ../../po/../src/widgets/toolbox.cpp:1199 +msgid "Polygon" +msgstr "Polígono" + +#: ../../po/../src/widgets/toolbox.cpp:1206 +msgid "Regular polygon (with one handle) instead of a star" +msgstr "Crear polígonos (con un tirador) en vez de estrellas" + +#: ../../po/../src/widgets/toolbox.cpp:1218 +msgid "Corners:" +msgstr "Esquinas:" + +#: ../../po/../src/widgets/toolbox.cpp:1218 +msgid "Number of corners of a polygon or star" +msgstr "Número de esquinas de un polígono o estrella" + +#: ../../po/../src/widgets/toolbox.cpp:1228 +msgid "Spoke ratio:" +msgstr "longitud del radio:" + +#. TRANSLATORS: Tip radius of a star is the distance from the center to the farthest handle. +#. Base radius is the same for the closest handle. +#: ../../po/../src/widgets/toolbox.cpp:1231 +msgid "Base radius to tip radius ratio" +msgstr "Relación entre el radio base y el radio de la punta" + +#: ../../po/../src/widgets/toolbox.cpp:1246 +msgid "Rounded:" +msgstr "Redondez:" + +#: ../../po/../src/widgets/toolbox.cpp:1246 +msgid "How much rounded are the corners (0 for sharp)" +msgstr "Lo redondos que son las esquinas (0 para agudo)" + +#: ../../po/../src/widgets/toolbox.cpp:1256 +msgid "Randomized:" +msgstr "Aleatorio:" + +#: ../../po/../src/widgets/toolbox.cpp:1256 +msgid "Scatter randomly the corners and angles" +msgstr "Esparcir las esquinas y ángulos aleatoriamente" + +#: ../../po/../src/widgets/toolbox.cpp:1269 +#: ../../po/../src/widgets/toolbox.cpp:1838 +#: ../../po/../src/widgets/toolbox.cpp:2061 +msgid "Defaults" +msgstr "Predeterminados" + +#: ../../po/../src/widgets/toolbox.cpp:1270 +#: ../../po/../src/widgets/toolbox.cpp:1839 +#: ../../po/../src/widgets/toolbox.cpp:2062 +msgid "" +"Reset shape parameters to defaults (use Inkscape Preferences > Tools to " +"change defaults)" +msgstr "" +"Reiniciar los parámetros de las formas a predeterminados (use «Preferencias " +"> Herramientas» para cambiar los predeterminados)" + +#: ../../po/../src/widgets/toolbox.cpp:1544 +msgid "W:" +msgstr "W:" + +#: ../../po/../src/widgets/toolbox.cpp:1544 +msgid "Width of rectangle" +msgstr "Ancho del rectángulo" + +#: ../../po/../src/widgets/toolbox.cpp:1556 +msgid "Height of rectangle" +msgstr "Altura del rectángulo" + +#: ../../po/../src/widgets/toolbox.cpp:1568 +msgid "Rx:" +msgstr "Rx:" + +#: ../../po/../src/widgets/toolbox.cpp:1568 +msgid "Horizontal radius of rounded corners" +msgstr "Radio horizontal de las esquinas redondeadas" + +#: ../../po/../src/widgets/toolbox.cpp:1578 +msgid "Ry:" +msgstr "Ry:" + +#: ../../po/../src/widgets/toolbox.cpp:1578 +msgid "Vertical radius of rounded corners" +msgstr "Radio vertical de la esquinas redondeadas" + +#: ../../po/../src/widgets/toolbox.cpp:1594 +msgid "Not rounded" +msgstr "No redondeado" + +#: ../../po/../src/widgets/toolbox.cpp:1596 +msgid "Make corners sharp" +msgstr "Afilar las esquinas" + +#: ../../po/../src/widgets/toolbox.cpp:1805 +msgid "Turns:" +msgstr "Vueltas:" + +#: ../../po/../src/widgets/toolbox.cpp:1805 +msgid "Number of revolutions" +msgstr "Número de revoluciones" + +#: ../../po/../src/widgets/toolbox.cpp:1815 +msgid "Divergence:" +msgstr "Divergencia:" + +#: ../../po/../src/widgets/toolbox.cpp:1815 +msgid "How much denser/sparser are outer revolutions; 1 = uniform" +msgstr "" +"Cuánto más densas/difusas son las revoluciones exteriores; 1 = uniforme" + +#: ../../po/../src/widgets/toolbox.cpp:1825 +msgid "Inner radius:" +msgstr "Radio interior:" + +#: ../../po/../src/widgets/toolbox.cpp:1825 +msgid "Radius of the innermost revolution (relative to the spiral size)" +msgstr "Radio de la revolución más interior (relativa al tamaño de la espiral)" + +#: ../../po/../src/widgets/toolbox.cpp:1957 +msgid "The width of the calligraphic pen (relative to the visible canvas area)" +msgstr "" +"El ancho de la pluma caligráfica (relativo al tamaño visible del lienzo)" + +#: ../../po/../src/widgets/toolbox.cpp:1967 +msgid "Thinning:" +msgstr "Estrechar:" + +#: ../../po/../src/widgets/toolbox.cpp:1967 +msgid "" +"How much velocity thins the stroke (> 0 makes fast strokes thinner, < 0 " +"makes them broader, 0 makes width independent of velocity)" +msgstr "" +"A qué velocidad se hace más fino el trazo (> 0 hace los trazos rápidos más " +"finos, < 0 los hace más anchos, 0 hace el ancho independiente de la " +"velocidad)" + +#: ../../po/../src/widgets/toolbox.cpp:1980 +msgid "Angle:" +msgstr "Ángulo:" + +#: ../../po/../src/widgets/toolbox.cpp:1980 +msgid "" +"The angle of the pen's nib (in degrees; 0 = horizontal; has no effect if " +"fixation = 0)" +msgstr "" +"El ángulo de la plumilla (en grados; 0 = horizontal; no tiene efecto si la " +"fijación = 0)" + +#: ../../po/../src/widgets/toolbox.cpp:1990 +msgid "Fixation:" +msgstr "Fijación:" + +#: ../../po/../src/widgets/toolbox.cpp:1990 +msgid "" +"How fixed is the pen angle (0 = always perpendicular to stroke direction, 1 " +"= fixed)" +msgstr "" +"Nivel de fijación de la pluma (0 = siempre perpendicular a la dirección del " +"trazo, 1 = fijado)" + +#: ../../po/../src/widgets/toolbox.cpp:2003 +msgid "Mass:" +msgstr "Masa:" + +#: ../../po/../src/widgets/toolbox.cpp:2003 +msgid "How much inertia affects the movement of the pen" +msgstr "Cuánta inercia afecta al movimiento de la pluma" + +#. TRANSLATORS: "drag" means "resistance" here +#: ../../po/../src/widgets/toolbox.cpp:2014 +msgid "Drag:" +msgstr "Resistencia:" + +#: ../../po/../src/widgets/toolbox.cpp:2014 +msgid "How much resistance affects the movement of the pen" +msgstr "Cuánta resistencia afecta al movimiento de la pluma" + +#: ../../po/../src/widgets/toolbox.cpp:2034 +msgid "Use the pressure of the input device to alter the width of the pen" +msgstr "Usar la presión del dispositivo para alterar la anchura de la pluma" + +#: ../../po/../src/widgets/toolbox.cpp:2047 +msgid "Use the tilt of the input device to alter the angle of the pen's nib" +msgstr "Usar el ángulo del dispositivo para alterar el ángulo de la plumilla" + +#: ../../po/../src/widgets/toolbox.cpp:2374 +msgid "Start:" +msgstr "Inicio:" + +#: ../../po/../src/widgets/toolbox.cpp:2374 +msgid "The angle (in degrees) from the horizontal to the arc's start point" +msgstr "El ángulo (en grados) desde la horizontal al punto inicial del arco" + +#: ../../po/../src/widgets/toolbox.cpp:2384 +msgid "End:" +msgstr "Fin:" + +#: ../../po/../src/widgets/toolbox.cpp:2384 +msgid "The angle (in degrees) from the horizontal to the arc's end point" +msgstr "" +"El ángulo (en grados) desde la horizontal hasta el punto final del arco" + +#: ../../po/../src/widgets/toolbox.cpp:2395 +msgid "Open arc" +msgstr "Arco abierto" + +#: ../../po/../src/widgets/toolbox.cpp:2396 +msgid "" +"Switch between arc (unclosed shape) and segment (closed shape with two radii)" +msgstr "" +"Cambiar entre arco (forma abierta) y segmento (forma cerrada con dos radios)" + +#: ../../po/../src/widgets/toolbox.cpp:2415 +msgid "Make whole" +msgstr "Completar" + +#: ../../po/../src/widgets/toolbox.cpp:2417 +msgid "Make the shape a whole ellipse, not arc or segment" +msgstr "Hacer una elipse completa, no un arco o segmento" + +#: ../../po/../src/widgets/toolbox.cpp:2644 +msgid "" +"When pressed, picks visible color without alpha and when not pressed, picks " +"color including its alpha" +msgstr "" +"Si está pulsado selecciona el color visible con alfa, si no lo está " +"selecciona el color con el valor alfa" + +#: ../../po/../src/widgets/toolbox.cpp:3039 +msgid "Make connectors avoid selected objects" +msgstr "Hacer que los conectores eviten los objetos seleccionados" + +#: ../../po/../src/widgets/toolbox.cpp:3043 +msgid "Make connectors ignore selected objects" +msgstr "Hacer que los conectores ignoren los objetos seleccionados" + +#. +#. 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 : +#: ../share/extensions/addnodes.inx.h:1 +#, fuzzy +msgid "Add Nodes" +msgstr "Nodos" + +#: ../share/extensions/addnodes.inx.h:2 +msgid "Maximum Segment Length" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:1 +msgid "AI Input" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:2 ../share/extensions/ai_output.inx.h:2 +msgid "Adobe Illustrator (*.ai)" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:3 +msgid "Open files saved with Adobe Illustrator" +msgstr "" + +#: ../share/extensions/ai_output.inx.h:1 +#, fuzzy +msgid "AI Output" +msgstr "Salida" + +#: ../share/extensions/ai_output.inx.h:3 +msgid "Write Adobe Illustrator" +msgstr "" + +#: ../share/extensions/dia.inx.h:1 +msgid "A diagram created with the program Dia" +msgstr "" + +#: ../share/extensions/dia.inx.h:2 +msgid "Dia Diagram (*.dia)" +msgstr "" + +#: ../share/extensions/dia.inx.h:3 +msgid "Dia Input" +msgstr "" + +#: ../share/extensions/dia.inx.h:4 +msgid "" +"In order to import Dia files, Dia itself must be installed. You can get Dia " +"at http://www.gnome.org/projects/dia/" +msgstr "" + +#: ../share/extensions/dia.inx.h:5 +msgid "" +"The dia2svg.sh script should be installed with your Inkscape distribution. " +"If you do not have it, there is likely to be something wrong with your " +"Inkscape installation." +msgstr "" + +#: ../share/extensions/dots.inx.h:1 +#, fuzzy +msgid "Connect the Dots" +msgstr "Conector" + +#: ../share/extensions/dots.inx.h:2 +#, fuzzy +msgid "Dot Size" +msgstr "Tamaño" + +#: ../share/extensions/dots.inx.h:3 +#, fuzzy +msgid "Font Size" +msgstr "Tamaño de tipografía:" + +#: ../share/extensions/dropshadow.inx.h:1 +msgid "Color of shadow" +msgstr "" + +#: ../share/extensions/dropshadow.inx.h:2 +#, fuzzy +msgid "Dropshadow" +msgstr "Mostrar sombra del papel" + +#: ../share/extensions/dxf_input.inx.h:1 +#: ../share/extensions/dxf_output.inx.h:1 +msgid "AutoCAD DXF (*.dxf)" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:2 +msgid "DXF Input" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:3 +msgid "Import AutoCAD's Document Exchange Format" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:4 +msgid "" +"dxf2svg may come with Inkscape, but is also at http://dxf-svg-convert." +"sourceforge.net/" +msgstr "" + +#: ../share/extensions/dxf_output.inx.h:2 +#, fuzzy +msgid "DXF Output" +msgstr "Salida" + +#: ../share/extensions/dxf_output.inx.h:3 +msgid "DXF file written by pstoedit" +msgstr "" + +#: ../share/extensions/dxf_output.inx.h:4 +msgid "pstoedit must be installed to run see http://www.pstoedit.net/pstoedit" +msgstr "" + +#: ../share/extensions/embedimage.inx.h:1 +#, fuzzy +msgid "Embed Images" +msgstr "Imágenes" + +#: ../share/extensions/eps_input.inx.h:1 +msgid "EPS Input" +msgstr "" + +#: ../share/extensions/eps_input.inx.h:2 +msgid "Encapsulated Postscript" +msgstr "" + +#: ../share/extensions/eps_input.inx.h:3 +msgid "Encapsulated Postscript (*.eps)" +msgstr "" + +#: ../share/extensions/epsi_output.inx.h:1 +#, fuzzy +msgid "EPSI Output" +msgstr "Salida" + +#: ../share/extensions/epsi_output.inx.h:2 +msgid "Encapsulated Postscript Interchange (*.epsi)" +msgstr "" + +#: ../share/extensions/epsi_output.inx.h:3 +msgid "Encapsulated Postscript with a thumbnail" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:1 ../share/extensions/ffms.inx.h:1 +#: ../share/extensions/ffset.inx.h:1 ../share/extensions/ffss.inx.h:1 +#, fuzzy +msgid "Bridge Width" +msgstr "Ancho de línea" + +#: ../share/extensions/ffmet.inx.h:2 ../share/extensions/ffms.inx.h:2 +msgid "First String Length" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:3 +msgid "FretFind Multi Length ET" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:4 ../share/extensions/ffms.inx.h:4 +#: ../share/extensions/ffset.inx.h:3 ../share/extensions/ffss.inx.h:3 +msgid "Fretboard Edges" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:5 ../share/extensions/ffms.inx.h:5 +msgid "Last String Length" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:6 ../share/extensions/ffms.inx.h:6 +#: ../share/extensions/ffset.inx.h:4 ../share/extensions/ffss.inx.h:4 +#, fuzzy +msgid "Number of Frets" +msgstr "Número de filas" + +#: ../share/extensions/ffmet.inx.h:7 ../share/extensions/ffms.inx.h:7 +#: ../share/extensions/ffset.inx.h:5 ../share/extensions/ffss.inx.h:5 +#, fuzzy +msgid "Number of Strings" +msgstr "Número de filas" + +#: ../share/extensions/ffmet.inx.h:8 ../share/extensions/ffms.inx.h:8 +#: ../share/extensions/ffset.inx.h:6 ../share/extensions/ffss.inx.h:6 +#, fuzzy +msgid "Nut Width" +msgstr "Ancho" + +#: ../share/extensions/ffmet.inx.h:9 ../share/extensions/ffms.inx.h:10 +msgid "Perpendicular Distance" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:10 ../share/extensions/ffset.inx.h:7 +msgid "Scale Base (2 for Octave)" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:11 ../share/extensions/ffset.inx.h:9 +msgid "Tones in Scale" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:12 ../share/extensions/ffms.inx.h:12 +#: ../share/extensions/ffset.inx.h:10 ../share/extensions/ffss.inx.h:10 +msgid "px per Unit" +msgstr "" + +#: ../share/extensions/ffms.inx.h:3 +msgid "FretFind Multi Length Scala" +msgstr "" + +#: ../share/extensions/ffms.inx.h:9 ../share/extensions/ffss.inx.h:7 +msgid "Path to Scala *.scl File" +msgstr "" + +#: ../share/extensions/ffms.inx.h:11 +msgid "Tuning (scale step for each string seperated by semicolons)" +msgstr "" + +#: ../share/extensions/ffset.inx.h:2 +msgid "FretFind Single Length ET" +msgstr "" + +#: ../share/extensions/ffset.inx.h:8 ../share/extensions/ffss.inx.h:8 +msgid "Scale Length" +msgstr "" + +#: ../share/extensions/ffss.inx.h:2 +msgid "FretFind Single Length Scala" +msgstr "" + +#: ../share/extensions/ffss.inx.h:9 +msgid "Tuning (Scale step for each string seperated by semicolons)" +msgstr "" + +#: ../share/extensions/handles.inx.h:1 +#, fuzzy +msgid "Draw Handles" +msgstr "Dibujar líneas a mano alzada" + +#: ../share/extensions/interp.inx.h:1 +#, fuzzy +msgid "Duplicate Endpaths" +msgstr "Duplicar nodo" + +#: ../share/extensions/interp.inx.h:2 +#, fuzzy +msgid "Exponent" +msgstr "Exportar" + +#: ../share/extensions/interp.inx.h:3 +msgid "Interpolate" +msgstr "" + +#: ../share/extensions/interp.inx.h:4 +msgid "Interpolate Style (Experimental)" +msgstr "" + +#: ../share/extensions/interp.inx.h:5 +msgid "Interpolation Method" +msgstr "" + +#: ../share/extensions/interp.inx.h:6 +msgid "Interpolation Steps" +msgstr "" + +#: ../share/extensions/kochify.inx.h:1 +msgid "Kochify" +msgstr "" + +#: ../share/extensions/kochify_load.inx.h:1 +msgid "Kochify (Load)" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:1 +#, fuzzy +msgid "Angle" +msgstr "Ángulo:" + +#: ../share/extensions/lindenmayer.inx.h:2 +msgid "Axiom" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:3 +#, fuzzy +msgid "Lindenmayer" +msgstr "Renombrar capa" + +#: ../share/extensions/lindenmayer.inx.h:4 +msgid "Order" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:5 +#, fuzzy +msgid "Rules" +msgstr "_Reglas" + +#: ../share/extensions/lindenmayer.inx.h:6 +#, fuzzy +msgid "Step" +msgstr "Pasos" + +#: ../share/extensions/motion.inx.h:1 +#, fuzzy +msgid "Direction" +msgstr "Descripción" + +#: ../share/extensions/motion.inx.h:2 +#, fuzzy +msgid "Magnitude" +msgstr "Magenta" + +#: ../share/extensions/motion.inx.h:3 +#, fuzzy +msgid "Motion" +msgstr "_Rotación" + +#: ../share/extensions/pdf_output.inx.h:1 +msgid "Adobe PDF (*.pdf)" +msgstr "" + +#: ../share/extensions/pdf_output.inx.h:2 +msgid "Adobe Portable Document Format" +msgstr "" + +#: ../share/extensions/pdf_output.inx.h:3 +#, fuzzy +msgid "PDF Output" +msgstr "Salida" + +#: ../share/extensions/ps_input.inx.h:1 +#, fuzzy +msgid "Postscript" +msgstr "Vertical" + +#: ../share/extensions/ps_input.inx.h:2 +msgid "Postscript (*.ps)" +msgstr "" + +#: ../share/extensions/ps_input.inx.h:3 +msgid "Postscript Input" +msgstr "" + +#: ../share/extensions/radiusrand.inx.h:1 +#, fuzzy +msgid "Radius" +msgstr "Eleva_r" + +#: ../share/extensions/radiusrand.inx.h:2 +#, fuzzy +msgid "Radius Randomize" +msgstr "Aleatorizar:" + +#: ../share/extensions/radiusrand.inx.h:3 +msgid "Randomize Control Points" +msgstr "" + +#: ../share/extensions/radiusrand.inx.h:4 +#, fuzzy +msgid "Randomize Nodes" +msgstr "Aleatorio:" + +#: ../share/extensions/rtree.inx.h:1 +#, fuzzy +msgid "Initial Size" +msgstr "Tamaño del mapa de bits" + +#: ../share/extensions/rtree.inx.h:2 +msgid "Minimum Size" +msgstr "" + +#: ../share/extensions/rtree.inx.h:3 +#, fuzzy +msgid "Random Tree" +msgstr "Aleatorizar:" + +#: ../share/extensions/sk_input.inx.h:1 +msgid "A diagram created with the program Sketch" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:2 +msgid "Sketch Diagram (*.sk)" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:3 +msgid "Sketch Input" +msgstr "" + +#: ../share/extensions/straightseg.inx.h:1 +msgid "Behavior" +msgstr "" + +#: ../share/extensions/straightseg.inx.h:3 +msgid "Segment Straightener" +msgstr "" + +#: ../share/extensions/summersnight.inx.h:1 +msgid "Summer's Night" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:1 +#: ../share/extensions/svgz_output.inx.h:1 +msgid "Compressed Inkscape SVG (*.svgz)" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:2 +#: ../share/extensions/svgz_output.inx.h:2 +msgid "Inkscape's native file format compressed with GZip" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:3 +msgid "SVGZ Input" +msgstr "" + +#: ../share/extensions/svgz_output.inx.h:3 +#, fuzzy +msgid "SVGZ Output" +msgstr "Salida" + +#: ../share/extensions/txt2svg.inx.h:1 +msgid "ASCII Text" +msgstr "" + +#: ../share/extensions/txt2svg.inx.h:2 +msgid "Text File (*.txt)" +msgstr "" + +#: ../share/extensions/txt2svg.inx.h:3 +msgid "Text Input" +msgstr "" + +#: ../share/extensions/wavy.inx.h:1 +msgid "Calculate first derivative numerically" +msgstr "" + +#: ../share/extensions/wavy.inx.h:2 +msgid "First derivative" +msgstr "" + +#: ../share/extensions/wavy.inx.h:3 +msgid "Function" +msgstr "" + +#: ../share/extensions/wavy.inx.h:4 +msgid "Function Plotter" +msgstr "" + +#: ../share/extensions/wavy.inx.h:5 +msgid "Nodes per period" +msgstr "" + +#: ../share/extensions/wavy.inx.h:6 +msgid "Periods (2*Pi each)" +msgstr "" + +#: ../share/extensions/whirl.inx.h:1 +msgid "Amount of Whirl" +msgstr "" + +#: ../share/extensions/whirl.inx.h:2 +#, fuzzy +msgid "Center X" +msgstr "Centrar líneas" + +#: ../share/extensions/whirl.inx.h:3 +#, fuzzy +msgid "Center Y" +msgstr "Centrar líneas" + +#: ../share/extensions/whirl.inx.h:4 +#, fuzzy +msgid "Direction of Rotation" +msgstr "Rechazar invitación" + +#: ../share/extensions/whirl.inx.h:5 +msgid "Whirl" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:1 +msgid "A popular graphics file format for clipart" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:2 +msgid "Windows Metafile (*.wmf)" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:3 +msgid "Windows Metafile Input" +msgstr "" + +#~ msgid "Custom canvas" +#~ msgstr "Personalizar papel" + +#~ msgid "Current style" +#~ msgstr "Estilo actual" + +#~ msgid "" +#~ "Current style is updated every time you change the style of any object " +#~ "(its fill, stroke, transparency, etc.)" +#~ msgstr "" +#~ "El estilo actual se actualiza cada vez que cambia el estilo de cualquier " +#~ "objeto (su relleno, trazo, transparencia, etc.)" + +#~ msgid "Arrange Objects" +#~ msgstr "Ordenar objetos" + +#~ msgid "deg" +#~ msgstr "grados" + +#~ msgid "" +#~ "%s is not a valid preferences file.\n" +#~ "%s" +#~ msgstr "" +#~ "%s no es un archivo de preferencias válido.\n" +#~ "%s" + +#~ msgid "" +#~ "Inkscape will run with default settings.\n" +#~ "New settings will not be saved." +#~ msgstr "" +#~ "Se ejecutará Inkscape con la configuración predeterminada.\n" +#~ "No se guardarán nuevos ajustes." + +#~ msgid "_Credits" +#~ msgstr "_Créditos" + +#~ msgid "Grab sensitivity" +#~ msgstr "Sensibilidad de agarre" + +#~ msgid "Click/drag threshold" +#~ msgstr "Umbral de clic/arrastre" + +#~ msgid "Mouse wheel scrolls by" +#~ msgstr "La rueda del ratón desplaza" + +#~ msgid "Scroll by" +#~ msgstr "Desplazarse" + +#~ msgid "Acceleration" +#~ msgstr "Aceleración" + +#~ msgid "Speed" +#~ msgstr "Velocidad" + +#~ msgid "Threshold" +#~ msgstr "Umbral" + +#~ msgid "Arrow keys move by" +#~ msgstr "Las flechas mueven" + +#~ msgid "> and < scale by" +#~ msgstr "> y < escalan" + +#~ msgid "Inset/Outset by" +#~ msgstr "Reducir/ampliar" + +#~ msgid "Rotation snaps every" +#~ msgstr "Rotación se ajusta cada" + +#~ msgid "Zoom in/out by" +#~ msgstr "Alejar/acercar" + +#~ msgid "Transform" +#~ msgstr "Transformación" diff --git a/po/es_MX.po b/po/es_MX.po new file mode 100644 index 000000000..5d8c42d8b --- /dev/null +++ b/po/es_MX.po @@ -0,0 +1,10812 @@ +# translation of inkscape to Spanish +# Copyright (C) 2000,2003,2004 Free Software Foundation, Inc. +# Traducido por Jose Antonio Salgueiro . Agradecimientos: zert, softcatala +# 2002-2003 +# Jose Antonio Salgueiro Aquino , 2003 +# Francisco Javier F. Serrador , 2003 +# Lucas Vieites , 2003 +# Daniel Díaz , 2004 +# +msgid "" +msgstr "" +"Project-Id-Version: inkscape.HEAD.es\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2005-12-04 11:51-0800\n" +"PO-Revision-Date: 2004-04-05 01:29-0600\n" +"Last-Translator: Daniel Díaz \n" +"Language-Team: none \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../inkscape.desktop.in.h:1 +msgid "Create and edit Scalable Vector Graphics images" +msgstr "" + +#: ../inkscape.desktop.in.h:2 +#, fuzzy +msgid "Inkscape SVG Vector Illustrator" +msgstr "Ilustrador vectorial SVG" + +#: ../../po/../src/arc-context.cpp:350 +msgid "" +"Ctrl: make circle or integer-ratio ellipse, snap arc/segment angle" +msgstr "" + +#: ../../po/../src/arc-context.cpp:351 ../../po/../src/rect-context.cpp:388 +msgid "Shift: draw around the starting point" +msgstr "" + +#: ../../po/../src/arc-context.cpp:413 +#: ../../po/../src/connector-context.cpp:493 +#: ../../po/../src/dyna-draw-context.cpp:506 +#: ../../po/../src/pen-context.cpp:329 ../../po/../src/pencil-context.cpp:208 +#: ../../po/../src/rect-context.cpp:452 ../../po/../src/spiral-context.cpp:421 +#: ../../po/../src/star-context.cpp:427 +msgid "Current layer is hidden. Unhide it to be able to draw on it." +msgstr "" + +#: ../../po/../src/arc-context.cpp:417 +#: ../../po/../src/connector-context.cpp:497 +#: ../../po/../src/dyna-draw-context.cpp:510 +#: ../../po/../src/pen-context.cpp:336 ../../po/../src/pencil-context.cpp:212 +#: ../../po/../src/rect-context.cpp:456 ../../po/../src/spiral-context.cpp:426 +#: ../../po/../src/star-context.cpp:431 +msgid "Current layer is locked. Unlock it to be able to draw on it." +msgstr "" + +#: ../../po/../src/arc-context.cpp:496 +#, c-format +msgid "" +"Ellipse: %s × %s; with Ctrl to make circle or integer-" +"ratio ellipse; with Shift to draw around the starting point" +msgstr "" + +#: ../../po/../src/connector-context.cpp:518 +#, fuzzy +msgid "Creating new connector" +msgstr "Creando curva nueva" + +#: ../../po/../src/connector-context.cpp:939 +#, fuzzy +msgid "Finishing connector" +msgstr "Terminar pluma" + +#: ../../po/../src/connector-context.cpp:1108 +msgid "Connection point: click or drag to create a new connector" +msgstr "" + +#: ../../po/../src/connector-context.cpp:1185 +msgid "Connector endpoint: drag to reroute or connect to new shapes" +msgstr "" + +#: ../../po/../src/connector-context.cpp:1278 +#, fuzzy +msgid "Select at least one non-connector object." +msgstr "Seleccione por lo menos dos objetos para agrupar." + +#: ../../po/../src/desktop-events.cpp:238 +#, c-format +msgid "%s at %s" +msgstr "%s en %s" + +#. TRANSLATORS: This string appears when double-clicking on a guide. +#. This is the distance by which the guide is to be moved. +#: ../../po/../src/desktop-events.cpp:277 +#, fuzzy +msgid " relative by " +msgstr "Movimiento relativo" + +#. TRANSLATORS: This string appears when double-clicking on a guide. +#. This is the target location where the guide is to be moved. +#: ../../po/../src/desktop-events.cpp:282 +#: ../../po/../src/desktop-events.cpp:395 +msgid " absolute to " +msgstr "" + +#. create dialog +#: ../../po/../src/desktop-events.cpp:348 +#, fuzzy +msgid "Guideline" +msgstr "Color de las líneas guía" + +#: ../../po/../src/desktop-events.cpp:432 +#, c-format +msgid "Move %s" +msgstr "Mover %s" + +#: ../../po/../src/desktop.cpp:678 +msgid "No previous zoom." +msgstr "No hay menos zoom." + +#: ../../po/../src/desktop.cpp:703 +msgid "No next zoom." +msgstr "No hay más zoom." + +#: ../../po/../src/dialogs/clonetiler.cpp:182 +#, fuzzy +msgid "Nothing selected." +msgstr "Último seleccionado" + +#: ../../po/../src/dialogs/clonetiler.cpp:188 +msgid "More than one object selected." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:195 +#, c-format +msgid "Object has %d tiled clones." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:200 +msgid "Object has no tiled clones." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:865 +#, fuzzy +msgid "Select one object whose tiled clones to unclump." +msgstr "Seleccione objetos para bajar." + +#: ../../po/../src/dialogs/clonetiler.cpp:916 +#, fuzzy +msgid "Select one object whose tiled clones to remove." +msgstr "Seleccione objetos para bajar." + +#: ../../po/../src/dialogs/clonetiler.cpp:984 +#: ../../po/../src/selection-chemistry.cpp:1774 +#, fuzzy +msgid "Select an object to clone." +msgstr "Seleccione objetos para bajar." + +#: ../../po/../src/dialogs/clonetiler.cpp:990 +#: ../../po/../src/selection-chemistry.cpp:1780 +msgid "" +"If you want to clone several objects, group them and clone the " +"group." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1484 +msgid "Per row:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1497 +#, fuzzy +msgid "Per column:" +msgstr "Sin gradiente seleccionado" + +#: ../../po/../src/dialogs/clonetiler.cpp:1505 +#, fuzzy +msgid "Randomize:" +msgstr "Último seleccionado" + +#: ../../po/../src/dialogs/clonetiler.cpp:1656 +#, fuzzy +msgid "_Symmetry" +msgstr "simétrico" + +#. TRANSLATORS: For the following 17 symmetry groups, see +#. * http://www.bib.ulb.ac.be/coursmath/doc/17.htm (visual examples); +#. * http://www.clarku.edu/~djoyce/wallpaper/seventeen.html (English vocabulary); or +#. * http://membres.lycos.fr/villemingerard/Geometri/Sym1D.htm (French vocabulary). +#. +#: ../../po/../src/dialogs/clonetiler.cpp:1664 +msgid "Select one of the 17 symmetry groups for the tiling" +msgstr "" + +#. TRANSLATORS: "translation" means "shift" / "displacement" here. +#: ../../po/../src/dialogs/clonetiler.cpp:1675 +msgid "P1: simple translation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1676 +msgid "P2: 180° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1677 +msgid "PM: reflection" +msgstr "" + +#. TRANSLATORS: "glide reflection" is a reflection and a translation combined. +#. For more info, see http://mathforum.org/sum95/suzanne/symsusan.html +#: ../../po/../src/dialogs/clonetiler.cpp:1680 +msgid "PG: glide reflection" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1681 +msgid "CM: reflection + glide reflection" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1682 +msgid "PMM: reflection + reflection" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1683 +msgid "PMG: reflection + 180° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1684 +msgid "PGG: glide reflection + 180° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1685 +msgid "CMM: reflection + reflection + 180° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1686 +msgid "P4: 90° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1687 +msgid "P4M: 90° rotation + 45° reflection" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1688 +msgid "P4G: 90° rotation + 90° reflection" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1689 +msgid "P3: 120° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1690 +msgid "P31M: reflection + 120° rotation, dense" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1691 +msgid "P3M1: reflection + 120° rotation, sparse" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1692 +msgid "P6: 60° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1693 +msgid "P6M: reflection + 60° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1721 +msgid "S_hift" +msgstr "" + +#. TRANSLATORS: "shift" means: the tiles will be shifted (offset) horizontally by this amount +#: ../../po/../src/dialogs/clonetiler.cpp:1731 +#, no-c-format +msgid "Shift X:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1739 +#, no-c-format +msgid "Horizontal shift per row (in % of tile width)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1747 +#, no-c-format +msgid "Horizontal shift per column (in % of tile width)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1754 +msgid "Randomize the horizontal shift by this percentage" +msgstr "" + +#. TRANSLATORS: "shift" means: the tiles will be shifted (offset) vertically by this amount +#: ../../po/../src/dialogs/clonetiler.cpp:1764 +#, no-c-format +msgid "Shift Y:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1772 +#, no-c-format +msgid "Vertical shift per row (in % of tile height)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1780 +#, no-c-format +msgid "Vertical shift per column (in % of tile height)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1787 +msgid "Randomize the vertical shift by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1795 +#, fuzzy +msgid "Exponent:" +msgstr "Elipse" + +#: ../../po/../src/dialogs/clonetiler.cpp:1802 +msgid "Whether rows are spaced evenly (1), converge (<1) or diverge (>1)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1809 +msgid "Whether columns are spaced evenly (1), converge (<1) or diverge (>1)" +msgstr "" + +#. TRANSLATORS: "Alternate" is a verb here +#: ../../po/../src/dialogs/clonetiler.cpp:1817 +#: ../../po/../src/dialogs/clonetiler.cpp:1907 +#: ../../po/../src/dialogs/clonetiler.cpp:1966 +#: ../../po/../src/dialogs/clonetiler.cpp:2022 +#: ../../po/../src/dialogs/clonetiler.cpp:2153 +msgid "Alternate:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1823 +msgid "Alternate the sign of shifts for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1828 +msgid "Alternate the sign of shifts for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1837 +#, fuzzy +msgid "Sc_ale" +msgstr "Escalar" + +#: ../../po/../src/dialogs/clonetiler.cpp:1845 +#, fuzzy +msgid "Scale X:" +msgstr "Círculo" + +#: ../../po/../src/dialogs/clonetiler.cpp:1853 +#, fuzzy, no-c-format +msgid "Horizontal scale per row (in % of tile width)" +msgstr "Coordenada horizontal de la selección" + +#: ../../po/../src/dialogs/clonetiler.cpp:1861 +#, fuzzy, no-c-format +msgid "Horizontal scale per column (in % of tile width)" +msgstr "Coordenada horizontal de la selección" + +#: ../../po/../src/dialogs/clonetiler.cpp:1868 +msgid "Randomize the horizontal scale by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1876 +#, fuzzy +msgid "Scale Y:" +msgstr "Círculo" + +#: ../../po/../src/dialogs/clonetiler.cpp:1884 +#, no-c-format +msgid "Vertical scale per row (in % of tile height)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1892 +#, no-c-format +msgid "Vertical scale per column (in % of tile height)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1899 +msgid "Randomize the vertical scale by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1913 +msgid "Alternate the sign of scales for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1918 +#, fuzzy +msgid "Alternate the sign of scales for each column" +msgstr "Coordenada horizontal de la selección" + +#: ../../po/../src/dialogs/clonetiler.cpp:1927 +#, fuzzy +msgid "_Rotation" +msgstr "Resolución:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1935 +#, fuzzy +msgid "Angle:" +msgstr "Rectángulo" + +#: ../../po/../src/dialogs/clonetiler.cpp:1943 +#, no-c-format +msgid "Rotate tiles by this angle for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1951 +#, no-c-format +msgid "Rotate tiles by this angle for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1958 +msgid "Randomize the rotation angle by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1972 +msgid "Alternate the rotation direction for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1977 +msgid "Alternate the rotation direction for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1985 +#, fuzzy +msgid "_Opacity" +msgstr "Opacidad:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1993 +msgid "Fade out:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2000 +msgid "Decrease tile opacity by this percentage for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2007 +msgid "Decrease tile opacity by this percentage for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2014 +msgid "Randomize the tile opacity by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2028 +msgid "Alternate the sign of opacity change for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2033 +msgid "Alternate the sign of opacity change for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2041 +#, fuzzy +msgid "Co_lor" +msgstr "Cerrar" + +#: ../../po/../src/dialogs/clonetiler.cpp:2046 +#, fuzzy +msgid "Initial color: " +msgstr "Color de la rejilla:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2050 +msgid "Initial color of tiled clones" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2050 +msgid "" +"Initial color for clones (works only if the original has unset fill or " +"stroke)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2065 +#, fuzzy +msgid "H:" +msgstr "Elipse" + +#: ../../po/../src/dialogs/clonetiler.cpp:2072 +msgid "Change the tile hue by this percentage for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2079 +msgid "Change the tile hue by this percentage for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2086 +msgid "Randomize the tile hue by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2095 +#, fuzzy +msgid "S:" +msgstr "Elipse" + +#: ../../po/../src/dialogs/clonetiler.cpp:2102 +msgid "Change the color saturation by this percentage for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2109 +msgid "Change the color saturation by this percentage for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2116 +msgid "Randomize the color saturation by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2124 +#, fuzzy +msgid "L:" +msgstr "Elipse" + +#: ../../po/../src/dialogs/clonetiler.cpp:2131 +msgid "Change the color lightness by this percentage for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2138 +msgid "Change the color lightness by this percentage for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2145 +msgid "Randomize the color lightness by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2159 +msgid "Alternate the sign of color changes for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2164 +msgid "Alternate the sign of color changes for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2172 +msgid "_Trace" +msgstr "_Trazar" + +#: ../../po/../src/dialogs/clonetiler.cpp:2179 +msgid "Trace the drawing under the tiles" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2183 +msgid "" +"For each clone, pick a value from the drawing in that clone's location and " +"apply it to the clone" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2197 +msgid "1. Pick from the drawing:" +msgstr "" + +#. ----Hbox2 +#: ../../po/../src/dialogs/clonetiler.cpp:2208 +#: ../../po/../src/dialogs/clonetiler.cpp:2355 +#: ../../po/../src/ui/dialog/tracedialog.cpp:445 +#, fuzzy +msgid "Color" +msgstr "Cerrar" + +#: ../../po/../src/dialogs/clonetiler.cpp:2209 +msgid "Pick the visible color and opacity" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2216 +#: ../../po/../src/dialogs/clonetiler.cpp:2365 +#: ../share/extensions/dropshadow.inx.h:3 +#, fuzzy +msgid "Opacity" +msgstr "Opacidad:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2217 +msgid "Pick the total accumulated opacity" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2224 +msgid "R" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2225 +msgid "Pick the Red component of the color" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2232 +msgid "G" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2233 +msgid "Pick the Green component of the color" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2240 +msgid "B" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2241 +msgid "Pick the Blue component of the color" +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2250 +msgid "clonetiler|H" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2251 +#, fuzzy +msgid "Pick the hue of the color" +msgstr "Número de revoluciones" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2260 +msgid "clonetiler|S" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2261 +msgid "Pick the saturation of the color" +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2270 +msgid "clonetiler|L" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2271 +msgid "Pick the lightness of the color" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2281 +msgid "2. Tweak the picked value:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2291 +msgid "Gamma-correct:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2296 +msgid "Shift the mid-range of the picked value upwards (>0) or downwards (<0)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2303 +msgid "Randomize:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2308 +msgid "Randomize the picked value by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2315 +#, fuzzy +msgid "Invert:" +msgstr "Re_ducir" + +#: ../../po/../src/dialogs/clonetiler.cpp:2319 +msgid "Invert the picked value" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2325 +msgid "3. Apply the value to the clones':" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2335 +#, fuzzy +msgid "Presence" +msgstr "Conservar" + +#: ../../po/../src/dialogs/clonetiler.cpp:2338 +msgid "" +"Each clone is created with the probability determined by the picked value in " +"that point" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2345 +#, fuzzy +msgid "Size" +msgstr "Caras:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2348 +msgid "Each clone's size is determined by the picked value in that point" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2358 +msgid "" +"Each clone is painted by the picked color (the original must have unset fill " +"or stroke)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2368 +msgid "Each clone's opacity is determined by the picked value in that point" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2395 +msgid "How many rows in the tiling" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2415 +msgid "How many columns in the tiling" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2445 +msgid "Width of the rectangle to be filled" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2470 +msgid "Height of the rectangle to be filled" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2485 +#, fuzzy +msgid "Rows, columns: " +msgstr "Círculo" + +#: ../../po/../src/dialogs/clonetiler.cpp:2486 +msgid "Create the specified number of rows and columns" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2495 +msgid "Width, height: " +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2496 +msgid "Fill the specified width and height with the tiling" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2512 +msgid "Use saved size and position of the tile" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2515 +msgid "" +"Pretend that the size and position of the tile are the same as the last time " +"you tiled it (if any), instead of using the current size" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2539 +#, fuzzy +msgid " _Create " +msgstr "Círculo" + +#: ../../po/../src/dialogs/clonetiler.cpp:2541 +msgid "Create and tile the clones of the selection" +msgstr "" + +#. TRANSLATORS: if a group of objects are "clumped" together, then they +#. are unevenly spread in the given amount of space - as shown in the +#. diagrams on the left in the following screenshot: +#. http://www.inkscape.org/screenshots/gallery/inkscape-0.42-CVS-tiles-unclump.png +#. So unclumping is the process of spreading a number of objects out more evenly. +#: ../../po/../src/dialogs/clonetiler.cpp:2556 +msgid " _Unclump " +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2557 +msgid "Spread out clones to reduce clumping; can be applied repeatedly" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2563 +#, fuzzy +msgid " Re_move " +msgstr "_Eliminar enlace" + +#: ../../po/../src/dialogs/clonetiler.cpp:2564 +msgid "Remove existing tiled clones of the selected object (siblings only)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2580 +#, fuzzy +msgid " R_eset " +msgstr "_Eliminar enlace" + +#. TRANSLATORS: "change" is a noun here +#: ../../po/../src/dialogs/clonetiler.cpp:2582 +msgid "" +"Reset all shifts, scales, rotates, opacity and color changes in the dialog " +"to zero" +msgstr "" + +#: ../../po/../src/dialogs/color-picker.cpp:280 +msgid "Close" +msgstr "Cerrar" + +#: ../../po/../src/dialogs/debugdialog.cpp:138 +msgid "Messages" +msgstr "" + +#. ## Add a menu for clear() +#: ../../po/../src/dialogs/debugdialog.cpp:144 +#: ../../po/../src/menus-skeleton.h:16 +#: ../../po/../src/ui/dialog/messages.cpp:56 +#: ../../po/../src/ui/dialog/scriptdialog.cpp:181 +msgid "_File" +msgstr "_Archivo" + +#. TRANSLATORS: "Clear" is a verb here +#: ../../po/../src/dialogs/debugdialog.cpp:145 +#: ../../po/../src/dialogs/find.cpp:753 +#: ../../po/../src/ui/dialog/messages.cpp:57 +#: ../../po/../src/ui/dialog/scriptdialog.cpp:182 +#, fuzzy +msgid "_Clear" +msgstr "Cerrar" + +#: ../../po/../src/dialogs/debugdialog.cpp:147 +#: ../../po/../src/ui/dialog/messages.cpp:59 +msgid "Capture log messages" +msgstr "" + +#: ../../po/../src/dialogs/debugdialog.cpp:149 +#: ../../po/../src/ui/dialog/messages.cpp:61 +msgid "Release log messages" +msgstr "" + +#. Notebook tab +#: ../../po/../src/dialogs/desktop-properties.cpp:909 +#: ../../po/../src/ui/dialog/document-preferences.cpp:89 +#: ../../po/../src/ui/widget/panel.cpp:107 +msgid "Grid" +msgstr "Rejilla" + +#. Checkbuttons +#. / \todo FIXME: gray out snapping when grid is off +#. / \todo FIXME: gray out snapping when grid is off. +#. / Dissenting view: you want snapping without grid. +#: ../../po/../src/dialogs/desktop-properties.cpp:917 +#: ../../po/../src/ui/dialog/document-preferences.cpp:179 +msgid "Show grid" +msgstr "Mostrar la rejilla" + +#: ../../po/../src/dialogs/desktop-properties.cpp:917 +#: ../../po/../src/ui/dialog/document-preferences.cpp:179 +#: ../../po/../src/verbs.cpp:2115 +#, fuzzy +msgid "Show or hide grid" +msgstr "Mostrar/ocultar la rejilla" + +#: ../../po/../src/dialogs/desktop-properties.cpp:918 +#: ../../po/../src/ui/dialog/document-preferences.cpp:180 +#, fuzzy +msgid "Snap bounding boxes to grid" +msgstr "Ajustar a la rejilla" + +#: ../../po/../src/dialogs/desktop-properties.cpp:918 +#: ../../po/../src/dialogs/desktop-properties.cpp:1001 +#: ../../po/../src/ui/dialog/document-preferences.cpp:181 +#: ../../po/../src/ui/dialog/document-preferences.cpp:236 +msgid "Snap the edges of the object bounding boxes" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:919 +#: ../../po/../src/ui/dialog/document-preferences.cpp:183 +#, fuzzy +msgid "Snap nodes to grid" +msgstr "Ajustar a la rejilla" + +#: ../../po/../src/dialogs/desktop-properties.cpp:919 +#: ../../po/../src/dialogs/desktop-properties.cpp:1002 +#: ../../po/../src/ui/dialog/document-preferences.cpp:184 +#: ../../po/../src/ui/dialog/document-preferences.cpp:239 +msgid "Snap path nodes, text baselines, ellipse centers, etc." +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:937 +#: ../../po/../src/ui/dialog/document-preferences.cpp:186 +msgid "Grid units:" +msgstr "Unidades de la rejilla:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:939 +#: ../../po/../src/ui/dialog/document-preferences.cpp:187 +msgid "Origin X:" +msgstr "Origen X:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:942 +#: ../../po/../src/ui/dialog/document-preferences.cpp:189 +msgid "Origin Y:" +msgstr "Origen Y:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:945 +#: ../../po/../src/ui/dialog/document-preferences.cpp:191 +msgid "Spacing X:" +msgstr "Espaciado X:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:948 +#: ../../po/../src/ui/dialog/document-preferences.cpp:193 +msgid "Spacing Y:" +msgstr "Espaciado Y:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:952 +#: ../../po/../src/dialogs/desktop-properties.cpp:1013 +#: ../../po/../src/ui/dialog/document-preferences.cpp:195 +#: ../../po/../src/ui/dialog/document-preferences.cpp:241 +msgid "Snap units:" +msgstr "Unidades para el autoajuste:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:955 +#: ../../po/../src/dialogs/desktop-properties.cpp:1016 +#: ../../po/../src/ui/dialog/document-preferences.cpp:196 +#: ../../po/../src/ui/dialog/document-preferences.cpp:242 +msgid "Snap distance:" +msgstr "Distancia de autoajuste:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:958 +#: ../../po/../src/ui/dialog/document-preferences.cpp:199 +#, fuzzy +msgid "Grid line color:" +msgstr "Color de las líneas guía" + +#: ../../po/../src/dialogs/desktop-properties.cpp:959 +#: ../../po/../src/ui/dialog/document-preferences.cpp:199 +#, fuzzy +msgid "Grid line color" +msgstr "Color de las líneas guía" + +#: ../../po/../src/dialogs/desktop-properties.cpp:959 +#: ../../po/../src/ui/dialog/document-preferences.cpp:200 +#, fuzzy +msgid "Color of grid lines" +msgstr "Espaciado de líneas:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:961 +#: ../../po/../src/ui/dialog/document-preferences.cpp:201 +#, fuzzy +msgid "Major grid line color:" +msgstr "Color de las líneas guía" + +#: ../../po/../src/dialogs/desktop-properties.cpp:962 +#: ../../po/../src/ui/dialog/document-preferences.cpp:201 +#, fuzzy +msgid "Major grid line color" +msgstr "Color de las líneas guía" + +#: ../../po/../src/dialogs/desktop-properties.cpp:962 +#: ../../po/../src/ui/dialog/document-preferences.cpp:202 +msgid "Color of the major (highlighted) grid lines" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:965 +#: ../../po/../src/ui/dialog/document-preferences.cpp:204 +#, fuzzy +msgid "Major grid line every:" +msgstr "Color de las líneas guía" + +#. TRANSLATORS: This belongs to the "Major grid line every:" string, +#. see grid settings in the "Document Preferences" dialog +#: ../../po/../src/dialogs/desktop-properties.cpp:977 +#: ../../po/../src/ui/dialog/document-preferences.cpp:204 +#, fuzzy +msgid "lines" +msgstr "Cerrar" + +#. Guidelines page +#: ../../po/../src/dialogs/desktop-properties.cpp:991 +#: ../../po/../src/ui/dialog/document-preferences.cpp:90 +msgid "Guides" +msgstr "Guías" + +#. / \todo FIXME: gray out snapping when guides are off +#. / Dissenting view: you want snapping without guides. +#: ../../po/../src/dialogs/desktop-properties.cpp:1000 +#: ../../po/../src/ui/dialog/document-preferences.cpp:234 +msgid "Show guides" +msgstr "Mostrar las guías" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1000 +#: ../../po/../src/ui/dialog/document-preferences.cpp:234 +#: ../../po/../src/verbs.cpp:2116 +#, fuzzy +msgid "Show or hide guides" +msgstr "Mostrar/ocultar guías" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1001 +#: ../../po/../src/ui/dialog/document-preferences.cpp:235 +#, fuzzy +msgid "Snap bounding boxes to guides" +msgstr "Ajustar a las guías" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1002 +#: ../../po/../src/ui/dialog/document-preferences.cpp:238 +#, fuzzy +msgid "Snap points to guides" +msgstr "Ajustar a la rejilla" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1020 +#: ../../po/../src/ui/dialog/document-preferences.cpp:243 +#, fuzzy +msgid "Guide color:" +msgstr "Color de las guías:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1021 +#: ../../po/../src/ui/dialog/document-preferences.cpp:243 +msgid "Guideline color" +msgstr "Color de las líneas guía" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1021 +#: ../../po/../src/ui/dialog/document-preferences.cpp:244 +#, fuzzy +msgid "Color of guidelines" +msgstr "guía horizontal" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1023 +#: ../../po/../src/ui/dialog/document-preferences.cpp:245 +msgid "Highlight color:" +msgstr "Color del resaltado:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1024 +#: ../../po/../src/ui/dialog/document-preferences.cpp:245 +msgid "Highlighted guideline color" +msgstr "Color de resaltado de las líneas guías" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1024 +#: ../../po/../src/ui/dialog/document-preferences.cpp:246 +msgid "Color of a guideline when it is under mouse" +msgstr "" + +#. Page page +#: ../../po/../src/dialogs/desktop-properties.cpp:1029 +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:855 +#: ../../po/../src/ui/dialog/document-preferences.cpp:88 +#: ../../po/../src/widgets/desktop-widget.cpp:1061 +msgid "Page" +msgstr "Página" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1039 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +#, fuzzy +msgid "Background:" +msgstr "Color de fondo" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1040 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +msgid "Background color" +msgstr "Color de fondo" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1041 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +msgid "" +"Color and transparency of the page background (also used for bitmap export)" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1045 +#: ../../po/../src/ui/dialog/document-preferences.cpp:147 +#, fuzzy +msgid "Show page border" +msgstr "Mostrar contorno del papel" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1049 +#: ../../po/../src/ui/dialog/document-preferences.cpp:148 +msgid "Border on top of drawing" +msgstr "Contorno encima del dibujo" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1052 +#: ../../po/../src/ui/dialog/document-preferences.cpp:149 +#, fuzzy +msgid "Border color:" +msgstr "Color del contorno:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1053 +#: ../../po/../src/ui/dialog/document-preferences.cpp:149 +#, fuzzy +msgid "Page border color" +msgstr "Color del contorno del papel" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1054 +#: ../../po/../src/ui/dialog/document-preferences.cpp:150 +#, fuzzy +msgid "Color of the page border" +msgstr "Mostrar contorno del papel" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1059 +#: ../../po/../src/ui/dialog/document-preferences.cpp:152 +msgid "Show page shadow" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1063 +#: ../../po/../src/ui/dialog/document-preferences.cpp:153 +#, fuzzy +msgid "Default units:" +msgstr "Predeterminados" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1069 +msgid "Units for the tool controls, ruler, and the statusbar" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1086 +#: ../../po/../src/ui/widget/page-sizer.cpp:209 +#, fuzzy +msgid "Page size:" +msgstr "Tamaño del papel:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1110 +#: ../../po/../src/ui/widget/page-sizer.cpp:219 +msgid "Custom" +msgstr "Personalizar" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1121 +#: ../../po/../src/ui/widget/page-sizer.cpp:225 +#, fuzzy +msgid "Page orientation:" +msgstr "Orientación:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1133 +#: ../../po/../src/ui/widget/page-sizer.cpp:232 +#, fuzzy +msgid "Landscape" +msgstr "Inkscape" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1139 +#: ../../po/../src/ui/widget/page-sizer.cpp:234 +#, fuzzy +msgid "Portrait" +msgstr "Punto" + +#. Custom paper frame +#: ../../po/../src/dialogs/desktop-properties.cpp:1148 +#: ../../po/../src/ui/widget/page-sizer.cpp:249 +#, fuzzy +msgid "Custom size" +msgstr "Personalizar" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1160 +#: ../../po/../src/dialogs/export.cpp:269 +#: ../../po/../src/ui/widget/page-sizer.cpp:261 +msgid "Units:" +msgstr "Unidades:" + +#. Stroke width +#: ../../po/../src/dialogs/desktop-properties.cpp:1162 +#: ../../po/../src/dialogs/export.cpp:310 +#: ../../po/../src/dialogs/object-attributes.cpp:55 +#: ../../po/../src/dialogs/stroke-style.cpp:985 +#: ../../po/../src/ui/widget/page-sizer.cpp:262 +#: ../../po/../src/widgets/toolbox.cpp:1957 +msgid "Width:" +msgstr "Ancho:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1183 +#: ../../po/../src/dialogs/export.cpp:326 +#: ../../po/../src/dialogs/export.cpp:431 +#: ../../po/../src/dialogs/object-attributes.cpp:56 +#: ../../po/../src/ui/widget/page-sizer.cpp:263 +msgid "Height:" +msgstr "Alto:" + +#. +#. * Ownership metadata tab +#. +#: ../../po/../src/dialogs/desktop-properties.cpp:1206 +msgid "Metadata" +msgstr "" + +#. add license selector pull-down +#: ../../po/../src/dialogs/desktop-properties.cpp:1225 +msgid "License" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1255 +msgid "Proprietary" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:212 +#, fuzzy +msgid "When transforming, show:" +msgstr "Transformaciones de objeto" + +#: ../../po/../src/dialogs/display-settings.cpp:223 +#, fuzzy +msgid "Objects" +msgstr "Objeto" + +#: ../../po/../src/dialogs/display-settings.cpp:224 +msgid "Show the actual objects when moving or transforming" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:231 +#, fuzzy +msgid "Box outline" +msgstr "Mostrar el boceto" + +#: ../../po/../src/dialogs/display-settings.cpp:232 +msgid "Show only a box outline of the objects when moving or transforming" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:238 +msgid "Per-object selection cue:" +msgstr "" + +#. sorationsnapsperpi == 0 means no snapping +#: ../../po/../src/dialogs/display-settings.cpp:249 +#: ../../po/../src/dialogs/display-settings.cpp:386 +#: ../../po/../src/dialogs/display-settings.cpp:441 +#: ../../po/../src/dialogs/display-settings.cpp:1482 +#: ../../po/../src/dialogs/stroke-style.cpp:791 +#: ../../po/../src/interface.cpp:741 +#: ../../po/../src/ui/widget/selected-style.cpp:100 +#: ../../po/../src/verbs.cpp:1842 +msgid "None" +msgstr "Ninguno" + +#: ../../po/../src/dialogs/display-settings.cpp:250 +msgid "No per-object selection indication" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:256 +msgid "Mark" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:257 +msgid "Each selected object has a diamond mark in the top left corner" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:264 +msgid "Box" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:265 +msgid "Each selected object displays its bounding box" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:270 +#, fuzzy +msgid "Default scale origin:" +msgstr "Tolerancia por omisión del cursor:" + +#: ../../po/../src/dialogs/display-settings.cpp:281 +#, fuzzy +msgid "Opposite bounding box edge" +msgstr "Ajustar a la rejilla" + +#: ../../po/../src/dialogs/display-settings.cpp:282 +msgid "Default scale origin will be on the bounding box of the item" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:288 +msgid "Farthest opposite node" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:289 +msgid "Default scale origin will be on the bounding box of the item's points" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:341 +#, fuzzy +msgid "degrees" +msgstr "grados" + +#: ../../po/../src/dialogs/display-settings.cpp:350 +msgid "" +"Rotating with Ctrl pressed snaps every that much degrees; also, pressing " +"[ or ] rotates by this amount" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:407 +msgid "Rotation snaps every:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:430 +msgid "" +"None: dialogs are treated as regular windows; Normal: dialogs stay on top of " +"document windows; Aggressive: same as Normal but may work better with some " +"window managers." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:451 +msgid "Normal" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:461 +msgid "Aggressive" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:475 +#, fuzzy +msgid "Dialogs on top:" +msgstr "_Diálogos" + +#: ../../po/../src/dialogs/display-settings.cpp:645 +#, fuzzy +msgid "Show selection cue" +msgstr "Bajar la selección un nivel" + +#: ../../po/../src/dialogs/display-settings.cpp:646 +msgid "" +"Whether selected objects display a selection cue (the same as in selector)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:657 +#, fuzzy +msgid "Enable gradient editing" +msgstr "Editor de gradiente" + +#: ../../po/../src/dialogs/display-settings.cpp:658 +msgid "Whether selected objects display gradient editing controls" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:719 +#, fuzzy +msgid "No objects selected to take the style from." +msgstr "Seleccione los objetos a los que quiera pegarle el estilo." + +#: ../../po/../src/dialogs/display-settings.cpp:728 +msgid "" +"More than one object selected. Cannot take style from multiple " +"objects." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:767 +#, fuzzy +msgid "Create new objects with:" +msgstr "Crear y editar objetos de texto (F8)" + +#: ../../po/../src/dialogs/display-settings.cpp:777 +#, fuzzy +msgid "Take from selection" +msgstr "Altura de la selección" + +#: ../../po/../src/dialogs/display-settings.cpp:778 +msgid "Remember the style of the (first) selected object as this tool's style" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:782 +#, fuzzy +msgid "Last used style" +msgstr "Pegar e_stilo" + +#: ../../po/../src/dialogs/display-settings.cpp:782 +msgid "Apply the style you last set on an object" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:790 +msgid "This tool's own style:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:790 +msgid "" +"Each tool may store its own style to apply to the newly created objects. Use " +"the button below to set it." +msgstr "" + +#. Mouse +#: ../../po/../src/dialogs/display-settings.cpp:877 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:55 +#, fuzzy +msgid "Mouse" +msgstr "Mover" + +#. TRANSLATORS: "Grab" is a noun here. "Grab sensitivity" is intended to mean how +#. * close on the screen you need to be to an object to be able to grab it with mouse (in +#. * pixels). +#: ../../po/../src/dialogs/display-settings.cpp:883 +#, fuzzy +msgid "Grab sensitivity:" +msgstr "Definir como s_ensible" + +#: ../../po/../src/dialogs/display-settings.cpp:884 +msgid "" +"How close on the screen you need to be to an object to be able to grab it " +"with mouse (in screen pixels)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:885 +#: ../../po/../src/dialogs/display-settings.cpp:897 +#: ../../po/../src/dialogs/display-settings.cpp:912 +#: ../../po/../src/dialogs/display-settings.cpp:930 +#: ../../po/../src/dialogs/display-settings.cpp:970 +msgid "pixels" +msgstr "pixeles" + +#: ../../po/../src/dialogs/display-settings.cpp:895 +msgid "Click/drag threshold:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:896 +msgid "" +"Maximum mouse drag (in screen pixels) which is considered a click, not a drag" +msgstr "" + +#. Scrolling +#: ../../po/../src/dialogs/display-settings.cpp:907 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:56 +#, fuzzy +msgid "Scrolling" +msgstr "Barras de desplazamiento" + +#: ../../po/../src/dialogs/display-settings.cpp:910 +msgid "Mouse wheel scrolls by:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:911 +msgid "" +"One mouse wheel notch scrolls by this distance in screen pixels " +"(horizontally with Shift)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:920 +msgid "Ctrl+arrows" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:928 +#, fuzzy +msgid "Scroll by:" +msgstr "Barras de desplazamiento" + +#: ../../po/../src/dialogs/display-settings.cpp:929 +msgid "Pressing Ctrl+arrow key scrolls by this distance (in screen pixels)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:939 +#, fuzzy +msgid "Acceleration:" +msgstr "Selección" + +#: ../../po/../src/dialogs/display-settings.cpp:940 +msgid "" +"Pressing and holding Ctrl+arrow will gradually speed up scrolling (0 for no " +"acceleration)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:949 +msgid "Autoscrolling" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:957 +#, fuzzy +msgid "Speed:" +msgstr "Rojo:" + +#: ../../po/../src/dialogs/display-settings.cpp:958 +msgid "" +"How fast the canvas autoscrolls when you drag beyond canvas edge (0 to turn " +"autoscroll off)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:968 +#: ../../po/../src/ui/dialog/tracedialog.cpp:357 +#: ../../po/../src/ui/dialog/tracedialog.cpp:390 +msgid "Threshold:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:969 +msgid "" +"How far (in screen pixels) you need to be from the canvas edge to trigger " +"autoscroll; positive is outside the canvas, negative is within the canvas" +msgstr "" + +#. Steps +#: ../../po/../src/dialogs/display-settings.cpp:979 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:57 +#, fuzzy +msgid "Steps" +msgstr "Estilo" + +#: ../../po/../src/dialogs/display-settings.cpp:982 +msgid "Arrow keys move by:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:983 +msgid "" +"Pressing an arrow key moves selected object(s) or node(s) by this distance " +"(in px units)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:984 +#: ../../po/../src/dialogs/display-settings.cpp:995 +#: ../../po/../src/dialogs/display-settings.cpp:1006 +#: ../../po/../src/helper/units.cpp:42 +msgid "px" +msgstr "px" + +#: ../../po/../src/dialogs/display-settings.cpp:993 +msgid "> and < scale by:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:994 +msgid "" +"Pressing > or < scales selection up or down by this increment (in px units)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1004 +msgid "Inset/Outset by:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1005 +msgid "" +"Inset and Outset commands displace the path by this distance (in px units)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1017 +msgid "Compass-like display of angles" +msgstr "" + +#. TRANSLATORS: "positive clockwise" means "increasing in clockwise direction" +#: ../../po/../src/dialogs/display-settings.cpp:1019 +msgid "" +"When on, angles are displayed with 0 at north, 0 to 360 range, positive " +"clockwise; otherwise with 0 at east, -180 to 180 range, positive " +"counterclockwise" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1026 +#, fuzzy +msgid "Zoom in/out by:" +msgstr "Alejar" + +#: ../../po/../src/dialogs/display-settings.cpp:1027 +msgid "" +"Zoom tool click, +/- keys, and middle click zoom in and out by this " +"multiplier" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1028 +#: ../../po/../src/helper/units.cpp:44 +msgid "%" +msgstr "%" + +#. Tools +#: ../../po/../src/dialogs/display-settings.cpp:1037 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:58 +msgid "Tools" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1045 +#, fuzzy +msgid "Selector" +msgstr "Seleccionar" + +#: ../../po/../src/dialogs/display-settings.cpp:1056 +#, fuzzy +msgid "Node" +msgstr "Ninguno" + +#: ../../po/../src/dialogs/display-settings.cpp:1064 +#: ../../po/../src/verbs.cpp:2073 +#: ../../po/../src/widgets/desktop-widget.cpp:277 +msgid "Zoom" +msgstr "Aumentar" + +#. The 4 shape tools +#: ../../po/../src/dialogs/display-settings.cpp:1071 +#, fuzzy +msgid "Shapes" +msgstr "Agudeza:" + +#: ../../po/../src/dialogs/display-settings.cpp:1079 +#: ../../po/../src/verbs.cpp:2055 +msgid "Rectangle" +msgstr "Rectángulo" + +#: ../../po/../src/dialogs/display-settings.cpp:1085 +#: ../../po/../src/verbs.cpp:2057 +msgid "Ellipse" +msgstr "Elipse" + +#: ../../po/../src/dialogs/display-settings.cpp:1091 +#: ../../po/../src/verbs.cpp:2059 +msgid "Star" +msgstr "Estrella" + +#: ../../po/../src/dialogs/display-settings.cpp:1097 +#: ../../po/../src/verbs.cpp:2061 +msgid "Spiral" +msgstr "Espiral" + +#: ../../po/../src/dialogs/display-settings.cpp:1111 +#: ../../po/../src/verbs.cpp:2063 +msgid "Pencil" +msgstr "Lápiz" + +#: ../../po/../src/dialogs/display-settings.cpp:1114 +#, fuzzy +msgid "Tolerance:" +msgstr "Traza" + +#: ../../po/../src/dialogs/display-settings.cpp:1115 +msgid "" +"This value affects the amount of smoothing applied to freehand lines; lower " +"values produce more uneven paths with more nodes" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1131 +#: ../../po/../src/verbs.cpp:2065 +msgid "Pen" +msgstr "Pluma" + +#: ../../po/../src/dialogs/display-settings.cpp:1140 +#: ../../po/../src/verbs.cpp:2067 +msgid "Calligraphy" +msgstr "Caligrafía" + +#: ../../po/../src/dialogs/display-settings.cpp:1147 +#: ../../po/../src/dialogs/text-edit.cpp:353 +#: ../../po/../src/ui/dialog/text-properties.cpp:37 +#: ../../po/../src/verbs.cpp:2069 +msgid "Text" +msgstr "Texto" + +#: ../../po/../src/dialogs/display-settings.cpp:1157 +#: ../../po/../src/verbs.cpp:2071 +#, fuzzy +msgid "Gradient" +msgstr "Editor de gradiente" + +#: ../../po/../src/dialogs/display-settings.cpp:1164 +#: ../../po/../src/verbs.cpp:2077 +#, fuzzy +msgid "Connector" +msgstr "Esquinas:" + +#: ../../po/../src/dialogs/display-settings.cpp:1171 +#: ../../po/../src/verbs.cpp:2075 +msgid "Dropper" +msgstr "Cuentagotas" + +#. Windows +#: ../../po/../src/dialogs/display-settings.cpp:1183 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:59 +msgid "Windows" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1188 +#, fuzzy +msgid "Save window geometry" +msgstr "Guardar documento" + +#: ../../po/../src/dialogs/display-settings.cpp:1189 +msgid "" +"Save the window size and position with each document (only for Inkscape SVG " +"format)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1196 +msgid "Dialogs are hidden in taskbar" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1197 +msgid "Whether dialog windows are to be hidden in the window manager taskbar" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1204 +#, fuzzy +msgid "Zoom when window is resized" +msgstr "Ampliar el dibujo si cambia el tamaño de la ventana" + +#: ../../po/../src/dialogs/display-settings.cpp:1205 +msgid "" +"Zoom drawing when document window is resized, to keep the same area visible " +"(this is the default which can be changed in any window using the button " +"above the right scrollbar)" +msgstr "" + +#. Clones +#: ../../po/../src/dialogs/display-settings.cpp:1213 +#: ../../po/../src/dialogs/find.cpp:624 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:60 +#, fuzzy +msgid "Clones" +msgstr "Cerrar" + +#: ../../po/../src/dialogs/display-settings.cpp:1217 +msgid "When the original moves, its clones and linked offsets:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1229 +msgid "Move in parallel" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1230 +msgid "Clones are translated by the same vector as their original." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1237 +msgid "Stay unmoved" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1238 +msgid "Clones preserve their positions when their original is moved." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1245 +msgid "Move according to transform" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1246 +msgid "" +"Each clone moves according to the value of its transform= attribute. For " +"example, a rotated clone will move in a different direction than its " +"original." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1255 +msgid "When the original is deleted, its clones:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1267 +msgid "Are unlinked" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1267 +msgid "Orphaned clones are converted to regular objects." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1273 +#, fuzzy +msgid "Are deleted" +msgstr "Primero seleccionado" + +#: ../../po/../src/dialogs/display-settings.cpp:1273 +msgid "Orphaned clones are deleted along with their original." +msgstr "" + +#. Transforms +#. TRANSLATORS: Noun, i.e. transformations. +#: ../../po/../src/dialogs/display-settings.cpp:1289 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:61 +#, fuzzy +msgid "Transforms" +msgstr "Transfor_mar" + +#: ../../po/../src/dialogs/display-settings.cpp:1292 +#, fuzzy +msgid "Scale stroke width" +msgstr "Contorno" + +#: ../../po/../src/dialogs/display-settings.cpp:1293 +#: ../../po/../src/widgets/select-toolbar.cpp:568 +msgid "When scaling objects, scale the stroke width by the same proportion" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1300 +msgid "Scale rounded corners in rectangles" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1301 +#: ../../po/../src/widgets/select-toolbar.cpp:580 +msgid "When scaling rectangles, scale the radii of rounded corners" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1308 +#, fuzzy +msgid "Transform gradients" +msgstr "Transfor_mar" + +#: ../../po/../src/dialogs/display-settings.cpp:1309 +#: ../../po/../src/widgets/select-toolbar.cpp:592 +msgid "Transform gradients (in fill or stroke) along with the objects" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1316 +#, fuzzy +msgid "Transform patterns" +msgstr "Matriz de transformación" + +#: ../../po/../src/dialogs/display-settings.cpp:1317 +#: ../../po/../src/widgets/select-toolbar.cpp:604 +msgid "Transform patterns (in fill or stroke) along with the objects" +msgstr "" + +#. TRANSLATORS: How to specify the affine transformation in the SVG file. +#: ../../po/../src/dialogs/display-settings.cpp:1327 +#, fuzzy +msgid "Store transformation:" +msgstr "Transformación de objeto" + +#: ../../po/../src/dialogs/display-settings.cpp:1338 +#, fuzzy +msgid "Optimized" +msgstr "Optimizar" + +#: ../../po/../src/dialogs/display-settings.cpp:1339 +msgid "" +"If possible, apply transformation to objects without adding a transform= " +"attribute" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1346 +#, fuzzy +msgid "Preserved" +msgstr "Conservar" + +#: ../../po/../src/dialogs/display-settings.cpp:1347 +msgid "Always store transformation as a transform= attribute on objects" +msgstr "" + +#. Selecting +#: ../../po/../src/dialogs/display-settings.cpp:1355 +#, fuzzy +msgid "Selecting" +msgstr "Selección" + +#: ../../po/../src/dialogs/display-settings.cpp:1357 +msgid "Ctrl+A, Tab, Shift+Tab:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1366 +#, fuzzy +msgid "Select only within current layer" +msgstr "Seleccionar" + +#: ../../po/../src/dialogs/display-settings.cpp:1367 +msgid "" +"Uncheck this to make keyboard selection commands work on objects in all " +"layers" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1374 +msgid "Ignore hidden objects" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1375 +msgid "" +"Uncheck this to be able to select objects that are hidden (either by " +"themselves or by being in a hidden group or layer)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1382 +#, fuzzy +msgid "Ignore locked objects" +msgstr "Objetos seleccionados" + +#: ../../po/../src/dialogs/display-settings.cpp:1383 +msgid "" +"Uncheck this to be able to select objects that are locked (either by " +"themselves or by being in a locked group or layer)" +msgstr "" + +#. To be broken into: Display, Save, Export, SVG, Commands +#: ../../po/../src/dialogs/display-settings.cpp:1391 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:62 +msgid "Misc" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1394 +msgid "Default export resolution:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1395 +#, fuzzy +msgid "Default bitmap resolution (in dots per inch) in the Export dialog" +msgstr "Resolución preferida (puntos por pulgada) de mapa de bits" + +#. FIXME: add "Used for new exports; once exported, documents remember this value on per-object basis" when implemented +#: ../../po/../src/dialogs/display-settings.cpp:1396 +#: ../../po/../src/dialogs/export.cpp:442 +msgid "dpi" +msgstr "dpi" + +#. TRANSLATORS: When on, an imported bitmap creates an element; otherwise it is a +#. * rectangle with bitmap fill. +#: ../../po/../src/dialogs/display-settings.cpp:1407 +#, fuzzy +msgid "Import bitmap as " +msgstr "Importar mapa de bits o imagen SVG al documento" + +#: ../../po/../src/dialogs/display-settings.cpp:1408 +msgid "" +"When on, an imported bitmap creates an element; otherwise it is a " +"rectangle with bitmap fill" +msgstr "" + +#. TRANSLATORS: When on, the print out (currently Postscript) will have +#. * a comment with the each object's label visible, marking the section +#. * of the printing commands that represent the given object. +#: ../../po/../src/dialogs/display-settings.cpp:1418 +msgid "Add label comments to printing output" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1419 +msgid "" +"When on, a comment will be added to the raw print output, marking the " +"rendered output for an object with its label" +msgstr "" + +#. TRANSLATORS: When on, enable the effects menu, default is off +#: ../../po/../src/dialogs/display-settings.cpp:1427 +msgid "Enable script effects (requires restart) - EXPERIMENTAL" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1428 +msgid "" +"When on, the effects menu is enabled, allowing external effect scripts to be " +"called, requires restart before effective - EXPERIMENTAL" +msgstr "" + +#. TRANSLATORS: The maximum length of the Open Recent list in the File menu. +#: ../../po/../src/dialogs/display-settings.cpp:1436 +#, fuzzy +msgid "Max recent documents:" +msgstr "Imprimir documento" + +#: ../../po/../src/dialogs/display-settings.cpp:1437 +msgid "The maximum length of the Open Recent list in the File menu" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1447 +msgid "Simplification threshold:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1448 +msgid "" +"How strong is the Simplify command by default. If you invoke this command " +"several times in quick succession, it will act more and more aggressively; " +"invoking it again after a pause restores the default threshold." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1469 +msgid "Oversample bitmaps:" +msgstr "Bitmaps de sobremuestreo:" + +#: ../../po/../src/dialogs/display-settings.cpp:1488 +msgid "2x2" +msgstr "2x2" + +#: ../../po/../src/dialogs/display-settings.cpp:1494 +msgid "4x4" +msgstr "4x4" + +#: ../../po/../src/dialogs/display-settings.cpp:1500 +msgid "8x8" +msgstr "8x8" + +#: ../../po/../src/dialogs/display-settings.cpp:1506 +msgid "16x16" +msgstr "16x16" + +#. "view_icon_preview" +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2143 +msgid "_Page" +msgstr "_Página" + +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2147 +msgid "_Drawing" +msgstr "_Dibujo" + +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2149 +msgid "_Selection" +msgstr "_Selección" + +#: ../../po/../src/dialogs/export.cpp:133 +#, fuzzy +msgid "_Custom" +msgstr "Personalizar" + +#: ../../po/../src/dialogs/export.cpp:254 +msgid "Export area" +msgstr "Exportar área" + +#: ../../po/../src/dialogs/export.cpp:300 +#, fuzzy +msgid "_x0:" +msgstr "x0:" + +#: ../../po/../src/dialogs/export.cpp:305 +#, fuzzy +msgid "x_1:" +msgstr "x1:" + +#: ../../po/../src/dialogs/export.cpp:316 +#, fuzzy +msgid "_y0:" +msgstr "y0:" + +#: ../../po/../src/dialogs/export.cpp:321 +#, fuzzy +msgid "y_1:" +msgstr "y1:" + +#: ../../po/../src/dialogs/export.cpp:406 +msgid "Bitmap size" +msgstr "Tamaño de mapa de bits" + +#: ../../po/../src/dialogs/export.cpp:416 +#, fuzzy +msgid "_Width:" +msgstr "Ancho:" + +#: ../../po/../src/dialogs/export.cpp:416 +#: ../../po/../src/dialogs/export.cpp:431 +#, fuzzy +msgid "pixels at" +msgstr "pixeles" + +#: ../../po/../src/dialogs/export.cpp:426 +#, fuzzy +msgid "dp_i" +msgstr "dpi" + +#: ../../po/../src/dialogs/export.cpp:448 +#, fuzzy +msgid "_Filename" +msgstr "Nombre de archivo" + +#: ../../po/../src/dialogs/export.cpp:512 +#, fuzzy +msgid "_Browse..." +msgstr "Examinar..." + +#: ../../po/../src/dialogs/export.cpp:539 +#, fuzzy +msgid " _Export " +msgstr "Círculo" + +#: ../../po/../src/dialogs/export.cpp:541 +msgid "Export the bitmap file with these settings" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:968 +msgid "You have to enter a filename" +msgstr "Debe indicar un nombre de archivo" + +#: ../../po/../src/dialogs/export.cpp:973 +msgid "The chosen area to be exported is invalid" +msgstr "El área que se ha seleccionado para exportar no es válida." + +#: ../../po/../src/dialogs/export.cpp:982 +#, c-format +msgid "Directory %s does not exist or is not a directory.\n" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:998 +msgid "Export in progress" +msgstr "Realizando exportación..." + +#: ../../po/../src/dialogs/export.cpp:1004 +#, fuzzy, c-format +msgid "Exporting %s (%d x %d)" +msgstr "Exportando [%d x %d] %s" + +#: ../../po/../src/dialogs/export.cpp:1031 +#, c-format +msgid "Could not export to filename %s.\n" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:1137 +msgid "Select a filename for exporting" +msgstr "Seleccione un nombre de archivo para exportar" + +#: ../../po/../src/dialogs/filedialog.cpp:367 +#, fuzzy +msgid "No preview" +msgstr "_Nueva vista" + +#: ../../po/../src/dialogs/filedialog.cpp:468 +msgid "too large for preview" +msgstr "" + +#: ../../po/../src/dialogs/filedialog.cpp:762 +#: ../../po/../src/dialogs/filedialog.cpp:763 +#, fuzzy +msgid "All Images" +msgstr "URI de la imagen:" + +#: ../../po/../src/dialogs/filedialog.cpp:767 +#: ../../po/../src/dialogs/filedialog.cpp:768 +#, fuzzy +msgid "All Files" +msgstr "Estilo de relleno" + +#: ../../po/../src/dialogs/filedialog.cpp:774 +#: ../../po/../src/dialogs/filedialog.cpp:775 +#, fuzzy +msgid "All Inkscape Files" +msgstr "Muestra de diapositivas Inkscape" + +#: ../../po/../src/dialogs/filedialog.cpp:1176 +#, fuzzy +msgid "Guess from extension" +msgstr "Altura de la selección" + +#. ###### Add the file types menu +#. createFilterMenu(); +#. ###### Do we want the .xxx extension automatically added? +#: ../../po/../src/dialogs/filedialog.cpp:1261 +msgid "Append filename extension automatically" +msgstr "Añadir extensión al nombre de archivo automáticamente" + +#. TRANSLATORS: "%s" is replaced with "exact" or "partial" when this string is displayed +#: ../../po/../src/dialogs/find.cpp:378 +#, fuzzy, c-format +msgid "%d object found (out of %d), %s match." +msgid_plural "%d objects found (out of %d), %s match." +msgstr[0] "%i objetos seleccionados. %s." +msgstr[1] "%i objetos seleccionados. %s." + +#: ../../po/../src/dialogs/find.cpp:381 +#, fuzzy +msgid "exact" +msgstr "Texto" + +#: ../../po/../src/dialogs/find.cpp:381 +#, fuzzy +msgid "partial" +msgstr "Espiral" + +#: ../../po/../src/dialogs/find.cpp:388 +#, fuzzy +msgid "No objects found" +msgstr "Sin objetos" + +#: ../../po/../src/dialogs/find.cpp:546 +#, fuzzy +msgid "T_ype: " +msgstr "Tipo:" + +#: ../../po/../src/dialogs/find.cpp:553 +msgid "Search in all object types" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:553 +#, fuzzy +msgid "All types" +msgstr "Estilo de relleno" + +#: ../../po/../src/dialogs/find.cpp:564 +msgid "Search all shapes" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:564 +#, fuzzy +msgid "All shapes" +msgstr "Todas las herramientas de formas" + +#: ../../po/../src/dialogs/find.cpp:581 +#, fuzzy +msgid "Search rectangles" +msgstr "Rectángulo" + +#: ../../po/../src/dialogs/find.cpp:581 +#, fuzzy +msgid "Rectangles" +msgstr "Rectángulo" + +#: ../../po/../src/dialogs/find.cpp:586 +msgid "Search ellipses, arcs, circles" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:586 +#, fuzzy +msgid "Ellipses" +msgstr "Elipse" + +#: ../../po/../src/dialogs/find.cpp:591 +#, fuzzy +msgid "Search stars and polygons" +msgstr "Crear estrellas y polígonos (*)" + +#: ../../po/../src/dialogs/find.cpp:591 +#, fuzzy +msgid "Stars" +msgstr "Estrella" + +#: ../../po/../src/dialogs/find.cpp:596 +#, fuzzy +msgid "Search spirals" +msgstr "Crear espirales (F9)" + +#: ../../po/../src/dialogs/find.cpp:596 +#, fuzzy +msgid "Spirals" +msgstr "Espiral" + +#. TRANSLATORS: polyline is a set of connected straight line segments +#. http://www.w3.org/TR/SVG11/shapes.html#PolylineElement +#: ../../po/../src/dialogs/find.cpp:609 +msgid "Search paths, lines, polylines" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:609 +#, fuzzy +msgid "Paths" +msgstr "T_razo" + +#: ../../po/../src/dialogs/find.cpp:614 +#, fuzzy +msgid "Search text objects" +msgstr "Objetos seleccionados" + +#: ../../po/../src/dialogs/find.cpp:614 +#, fuzzy +msgid "Texts" +msgstr "Texto" + +#: ../../po/../src/dialogs/find.cpp:619 +msgid "Search groups" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:619 +#, fuzzy +msgid "Groups" +msgstr "A_grupar" + +#: ../../po/../src/dialogs/find.cpp:624 +msgid "Search clones" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:629 +msgid "Search images" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:629 +#, fuzzy +msgid "Images" +msgstr "URI de la imagen:" + +#: ../../po/../src/dialogs/find.cpp:634 +#, fuzzy +msgid "Search offset objects" +msgstr "Crear un objeto de offset dinámico" + +#: ../../po/../src/dialogs/find.cpp:634 +#, fuzzy +msgid "Offsets" +msgstr "Offset:" + +#: ../../po/../src/dialogs/find.cpp:694 +#, fuzzy +msgid "_Text: " +msgstr "Texto" + +#: ../../po/../src/dialogs/find.cpp:694 +msgid "Find objects by their text content (exact or partial match)" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:695 +msgid "_ID: " +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:695 +msgid "Find objects by the value of the id attribute (exact or partial match)" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:696 +#, fuzzy +msgid "_Style: " +msgstr "Estilo" + +#: ../../po/../src/dialogs/find.cpp:696 +msgid "" +"Find objects by the value of the style attribute (exact or partial match)" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:697 +#, fuzzy +msgid "_Attribute: " +msgstr "Atributo" + +#: ../../po/../src/dialogs/find.cpp:697 +msgid "Find objects by the name of an attribute (exact or partial match)" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:711 +#, fuzzy +msgid "Search in s_election" +msgstr "Altura de la selección" + +#: ../../po/../src/dialogs/find.cpp:715 +msgid "Limit search to the current selection" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:720 +#, fuzzy +msgid "Search in current _layer" +msgstr "Seleccionar" + +#: ../../po/../src/dialogs/find.cpp:724 +#, fuzzy +msgid "Limit search to the current layer" +msgstr "Seleccionar" + +#: ../../po/../src/dialogs/find.cpp:729 +msgid "Include _hidden" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:733 +msgid "Include hidden objects in search" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:738 +msgid "Include l_ocked" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:742 +#, fuzzy +msgid "Include locked objects in search" +msgstr "Objetos seleccionados" + +#: ../../po/../src/dialogs/find.cpp:753 +#, fuzzy +msgid "Clear values" +msgstr "Limpia_r todo" + +#: ../../po/../src/dialogs/find.cpp:754 +#, fuzzy +msgid "_Find" +msgstr "Rejilla" + +#: ../../po/../src/dialogs/find.cpp:754 +msgid "Select objects matching all of the fields you filled in" +msgstr "" + +#: ../../po/../src/dialogs/iconpreview.cpp:145 +#, c-format +msgid "%d x %d" +msgstr "" + +#: ../../po/../src/dialogs/iconpreview.cpp:193 +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:857 +#: ../../po/../src/widgets/desktop-widget.cpp:1069 +msgid "Selection" +msgstr "Selección" + +#: ../../po/../src/dialogs/iconpreview.cpp:195 +#, fuzzy +msgid "Selection only or whole document" +msgstr "Seleccionar" + +#: ../../po/../src/dialogs/iconpreview.cpp:203 +msgid "Refresh the icons" +msgstr "" + +#. Create the label for the object id +#: ../../po/../src/dialogs/item-properties.cpp:126 +#: ../../po/../src/dialogs/item-properties.cpp:327 +#: ../../po/../src/dialogs/item-properties.cpp:396 +#: ../../po/../src/dialogs/item-properties.cpp:403 +msgid "_Id" +msgstr "" + +#: ../../po/../src/dialogs/item-properties.cpp:135 +msgid "" +"The id= attribute (only letters, digits, and the characters .-_: allowed)" +msgstr "" + +#. Button for setting the object's id, label, title and description. +#: ../../po/../src/dialogs/item-properties.cpp:149 +#, fuzzy +msgid "_Set" +msgstr "Ajustar ID" + +#. Create the label for the object label +#: ../../po/../src/dialogs/item-properties.cpp:158 +#, fuzzy +msgid "_Label" +msgstr "Definir atributo" + +#: ../../po/../src/dialogs/item-properties.cpp:167 +msgid "A freeform label for the object" +msgstr "" + +#. Create the label for the object title +#: ../../po/../src/dialogs/item-properties.cpp:179 +#: ../../po/../src/dialogs/rdf.cpp:243 +#, fuzzy +msgid "Title" +msgstr "Título:" + +#. Create the frame for the object description +#: ../../po/../src/dialogs/item-properties.cpp:196 +#: ../../po/../src/dialogs/rdf.cpp:287 +#, fuzzy +msgid "Description" +msgstr "Selección" + +#. Hide +#: ../../po/../src/dialogs/item-properties.cpp:223 +#, fuzzy +msgid "_Hide" +msgstr "Caras:" + +#: ../../po/../src/dialogs/item-properties.cpp:224 +msgid "Check to make the object invisible" +msgstr "" + +#. Lock +#. TRANSLATORS: "Lock" is a verb here +#: ../../po/../src/dialogs/item-properties.cpp:233 +msgid "L_ock" +msgstr "" + +#: ../../po/../src/dialogs/item-properties.cpp:234 +msgid "Check to make the object insensitive (not selectable by mouse)" +msgstr "" + +#: ../../po/../src/dialogs/item-properties.cpp:310 +#: ../../po/../src/dialogs/item-properties.cpp:317 +msgid "Ref" +msgstr "Ref" + +#: ../../po/../src/dialogs/item-properties.cpp:398 +#, fuzzy +msgid "Id invalid! " +msgstr "El ID no es válido" + +#: ../../po/../src/dialogs/item-properties.cpp:400 +#, fuzzy +msgid "Id exists! " +msgstr "El ID existe" + +#: ../../po/../src/dialogs/layer-properties.cpp:50 +msgid "Layer name:" +msgstr "" + +#: ../../po/../src/dialogs/layer-properties.cpp:133 +#, fuzzy +msgid "Rename Layer" +msgstr "Elevar nodo" + +#: ../../po/../src/dialogs/layer-properties.cpp:136 +#, fuzzy +msgid "_Rename" +msgstr "Nombre de archivo" + +#. TRANSLATORS: This means "The layer has been renamed" +#: ../../po/../src/dialogs/layer-properties.cpp:147 +#, fuzzy +msgid "Renamed layer" +msgstr "Elevar nodo" + +#: ../../po/../src/dialogs/layer-properties.cpp:151 +#, fuzzy +msgid "Add Layer" +msgstr "_Bajar" + +#: ../../po/../src/dialogs/layer-properties.cpp:153 +#, fuzzy +msgid "_Add" +msgstr "Añadir" + +#: ../../po/../src/dialogs/layer-properties.cpp:167 +msgid "New layer created." +msgstr "" + +#: ../../po/../src/dialogs/object-attributes.cpp:34 +msgid "Href:" +msgstr "Href:" + +#: ../../po/../src/dialogs/object-attributes.cpp:35 +msgid "Target:" +msgstr "Objetivo:" + +#: ../../po/../src/dialogs/object-attributes.cpp:36 +msgid "Type:" +msgstr "Tipo:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkRoleAttribute +#. Identifies the type of the related resource with an absolute URI +#: ../../po/../src/dialogs/object-attributes.cpp:39 +msgid "Role:" +msgstr "Rol:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkArcRoleAttribute +#. For situations where the nature/role alone isn't enough, this offers an additional URI defining the purpose of the link. +#: ../../po/../src/dialogs/object-attributes.cpp:42 +msgid "Arcrole:" +msgstr "Arcrole:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkTitleAttribute +#: ../../po/../src/dialogs/object-attributes.cpp:44 +msgid "Title:" +msgstr "Título:" + +#: ../../po/../src/dialogs/object-attributes.cpp:45 +msgid "Show:" +msgstr "Mostrar:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkActuateAttribute +#: ../../po/../src/dialogs/object-attributes.cpp:47 +msgid "Actuate:" +msgstr "Actuar:" + +#: ../../po/../src/dialogs/object-attributes.cpp:52 +msgid "URL:" +msgstr "URL:" + +#: ../../po/../src/dialogs/object-attributes.cpp:53 +msgid "X:" +msgstr "X:" + +#: ../../po/../src/dialogs/object-attributes.cpp:54 +msgid "Y:" +msgstr "Y:" + +#: ../../po/../src/dialogs/object-attributes.cpp:98 +#, c-format +msgid "%s attributes" +msgstr "%s atributos" + +#: ../../po/../src/dialogs/object-properties.cpp:158 +#, fuzzy +msgid "_Fill" +msgstr "Relleno" + +#: ../../po/../src/dialogs/object-properties.cpp:165 +#, fuzzy +msgid "Stroke _paint" +msgstr "Contorno" + +#: ../../po/../src/dialogs/object-properties.cpp:172 +#, fuzzy +msgid "Stroke st_yle" +msgstr "Estilo de contorno" + +#: ../../po/../src/dialogs/object-properties.cpp:183 +#, fuzzy +msgid "Master _opacity" +msgstr "Opacidad:" + +#: ../../po/../src/dialogs/rdf.cpp:244 +msgid "Name by which this document is formally known." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:246 +#, fuzzy +msgid "Date" +msgstr "_Pegar" + +#: ../../po/../src/dialogs/rdf.cpp:247 +msgid "Date associated with the creation of this document (YYYY-MM-DD)." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:249 +msgid "Format" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:250 +msgid "The physical or digital manifestation of this document (MIME type)." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:252 +#, fuzzy +msgid "Type" +msgstr "Tipo:" + +#: ../../po/../src/dialogs/rdf.cpp:253 +msgid "Type of document (DCMI Type)." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:256 +#, fuzzy +msgid "Creator" +msgstr "Crear" + +#: ../../po/../src/dialogs/rdf.cpp:257 +msgid "" +"Name of entity primarily responsible for making the content of this document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:259 +#, fuzzy +msgid "Rights" +msgstr "Alto:" + +#: ../../po/../src/dialogs/rdf.cpp:260 +msgid "" +"Name of entity with rights to the Intellectual Property of this document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:262 +msgid "Publisher" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:263 +msgid "Name of entity responsible for making this document available." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:266 +#, fuzzy +msgid "Identifier" +msgstr "Centímetro" + +#: ../../po/../src/dialogs/rdf.cpp:267 +msgid "Unique URI to reference this document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:269 +msgid "Source" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:270 +msgid "Unique URI to reference the source of this document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:272 +#, fuzzy +msgid "Relation" +msgstr "Resolución:" + +#: ../../po/../src/dialogs/rdf.cpp:273 +#, fuzzy +msgid "Unique URI to a related document." +msgstr "Documento sin nombre" + +#: ../../po/../src/dialogs/rdf.cpp:275 +msgid "Language" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:276 +msgid "" +"Two-letter language tag with optional subtags for the language of this " +"document. (e.g. 'en-GB')" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:278 +msgid "Keywords" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:279 +msgid "" +"The topic of this document as comma-separated key words, phrases, or " +"classifications." +msgstr "" + +#. TRANSLATORS: "Coverage": the spatial or temporal characteristics of the content. +#. For info, see Appendix D of http://www.w3.org/TR/1998/WD-rdf-schema-19980409/ +#: ../../po/../src/dialogs/rdf.cpp:283 +msgid "Coverage" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:284 +msgid "Extent or scope of this document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:288 +msgid "A short account of the content of this document." +msgstr "" + +#. FIXME: need to handle 1 agent per line of input +#: ../../po/../src/dialogs/rdf.cpp:292 +#, fuzzy +msgid "Contributors" +msgstr "Centímetros" + +#: ../../po/../src/dialogs/rdf.cpp:293 +msgid "" +"Names of entities responsible for making contributions to the content of " +"this document." +msgstr "" + +#. TRANSLATORS: URL to a page that defines the license for the document +#: ../../po/../src/dialogs/rdf.cpp:297 +msgid "URI" +msgstr "" + +#. TRANSLATORS: this is where you put a URL to a page that defines the license +#: ../../po/../src/dialogs/rdf.cpp:299 +msgid "URI to this document's license's namespace definition." +msgstr "" + +#. TRANSLATORS: fragment of XML representing the license of the document +#: ../../po/../src/dialogs/rdf.cpp:303 +#, fuzzy +msgid "Fragment" +msgstr "Argumento:" + +#: ../../po/../src/dialogs/rdf.cpp:304 +msgid "XML fragment for the RDF 'License' section." +msgstr "" + +#: ../../po/../src/dialogs/stroke-style.cpp:774 +#: ../../po/../src/widgets/gradient-vector.cpp:263 +#: ../../po/../src/widgets/paint-selector.cpp:751 +msgid "No document selected" +msgstr "Sin documentos seleccionados" + +#: ../../po/../src/dialogs/stroke-style.cpp:992 +#, fuzzy +msgid "Stroke width" +msgstr "Contorno" + +#. Join type +#. TRANSLATORS: The line join style specifies the shape to be used at the +#. corners of paths. It can be "miter", "round" or "bevel". +#: ../../po/../src/dialogs/stroke-style.cpp:1015 +msgid "Join:" +msgstr "Unión:" + +#. TRANSLATORS: Miter join: joining lines with a sharp (pointed) corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1027 +msgid "Miter join" +msgstr "" + +#. TRANSLATORS: Round join: joining lines with a rounded corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1035 +msgid "Round join" +msgstr "" + +#. TRANSLATORS: Bevel join: joining lines with a blunted (flattened) corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1043 +msgid "Bevel join" +msgstr "" + +#. Miterlimit +#. TRANSLATORS: Miter limit: only for "miter join", this limits the length +#. of the sharp "spike" when the lines connect at too sharp an angle. +#. When two line segments meet at a sharp angle, a miter join results in a +#. spike that extends well beyond the connection point. The purpose of the +#. miter limit is to cut off such spikes (i.e. convert them into bevels) +#. when they become too long. +#: ../../po/../src/dialogs/stroke-style.cpp:1054 +msgid "Miter limit:" +msgstr "" + +#: ../../po/../src/dialogs/stroke-style.cpp:1062 +msgid "Maximum length of the miter (in units of stroke width)" +msgstr "" + +#. Cap type +#. TRANSLATORS: cap type specifies the shape for the ends of lines +#: ../../po/../src/dialogs/stroke-style.cpp:1075 +msgid "Cap:" +msgstr "Punta:" + +#. TRANSLATORS: Butt cap: the line shape does not extend beyond the end point +#. of the line; the ends of the line are square +#: ../../po/../src/dialogs/stroke-style.cpp:1086 +msgid "Butt cap" +msgstr "" + +#. TRANSLATORS: Round cap: the line shape extends beyond the end point of the +#. line; the ends of the line are rounded +#: ../../po/../src/dialogs/stroke-style.cpp:1093 +msgid "Round cap" +msgstr "" + +#. TRANSLATORS: Square cap: the line shape extends beyond the end point of the +#. line; the ends of the line are square +#: ../../po/../src/dialogs/stroke-style.cpp:1100 +msgid "Square cap" +msgstr "" + +#. Dash +#: ../../po/../src/dialogs/stroke-style.cpp:1106 +#, fuzzy +msgid "Dashes:" +msgstr "Masa:" + +#. TRANSLATORS: Path markers are an SVG feature that allows you to attach arbitrary shapes +#. (arrowheads, bullets, faces, whatever) to the start, end, or middle nodes of a path. +#: ../../po/../src/dialogs/stroke-style.cpp:1127 +msgid "Start Markers:" +msgstr "Marcas de inicio:" + +#: ../../po/../src/dialogs/stroke-style.cpp:1137 +msgid "Mid Markers:" +msgstr "Marcadores medios:" + +#: ../../po/../src/dialogs/stroke-style.cpp:1148 +msgid "End Markers:" +msgstr "Marcadores finales:" + +#: ../../po/../src/dialogs/swatches.cpp:424 +#, c-format +msgid "Palettes directory (%s) is unavailable." +msgstr "" + +#. TODO: Insert widgets +#: ../../po/../src/dialogs/text-edit.cpp:199 +#: ../../po/../src/ui/dialog/text-properties.cpp:36 +#, fuzzy +msgid "Font" +msgstr "Punto" + +#: ../../po/../src/dialogs/text-edit.cpp:216 +msgid "Layout" +msgstr "Formato" + +#: ../../po/../src/dialogs/text-edit.cpp:229 +msgid "Align lines left" +msgstr "" + +#. TRANSLATORS: `Center' here is a verb. +#: ../../po/../src/dialogs/text-edit.cpp:243 +#, fuzzy +msgid "Center lines" +msgstr "Centro Y:" + +#: ../../po/../src/dialogs/text-edit.cpp:256 +msgid "Align lines right" +msgstr "" + +#: ../../po/../src/dialogs/text-edit.cpp:278 +#, fuzzy +msgid "Horizontal text" +msgstr "Líneas horizontales" + +#: ../../po/../src/dialogs/text-edit.cpp:292 +#, fuzzy +msgid "Vertical text" +msgstr "Líneas verticales" + +#: ../../po/../src/dialogs/text-edit.cpp:307 +msgid "Line spacing:" +msgstr "Espaciado de líneas:" + +#: ../../po/../src/dialogs/text-edit.cpp:400 +msgid "Set as default" +msgstr "Definir como predeterminado" + +#: ../../po/../src/dialogs/tiledialog.cpp:603 +#, fuzzy +msgid "Rows:" +msgstr "Mostrar:" + +#: ../../po/../src/dialogs/tiledialog.cpp:613 +#, fuzzy +msgid "Number of rows" +msgstr "Número de revoluciones" + +#: ../../po/../src/dialogs/tiledialog.cpp:617 +#, fuzzy +msgid "Equal height" +msgstr "Alto:" + +#: ../../po/../src/dialogs/tiledialog.cpp:627 +msgid "If not set, each row has the height of the tallest object in it" +msgstr "" + +#. #### Radio buttons to control vertical alignment #### +#. #### Radio buttons to control horizontal alignment #### +#: ../../po/../src/dialogs/tiledialog.cpp:637 +#: ../../po/../src/dialogs/tiledialog.cpp:708 +#, fuzzy +msgid "Align:" +msgstr "Alinear" + +#: ../../po/../src/dialogs/tiledialog.cpp:672 +msgid " X " +msgstr "" + +#. #### Number of columns #### +#: ../../po/../src/dialogs/tiledialog.cpp:678 +#, fuzzy +msgid "Columns:" +msgstr "Círculo" + +#: ../../po/../src/dialogs/tiledialog.cpp:688 +#, fuzzy +msgid "Number of columns" +msgstr "Número de revoluciones" + +#: ../../po/../src/dialogs/tiledialog.cpp:692 +#, fuzzy +msgid "Equal width" +msgstr "Ancho:" + +#: ../../po/../src/dialogs/tiledialog.cpp:701 +msgid "If not set, each column has the width of the widest object in it" +msgstr "" + +#. #### Radio buttons to control spacing manually or to fit selection bbox #### +#: ../../po/../src/dialogs/tiledialog.cpp:746 +#, fuzzy +msgid "Fit into selection box" +msgstr "Ancho de la selección" + +#: ../../po/../src/dialogs/tiledialog.cpp:753 +#, fuzzy +msgid "Set spacing:" +msgstr "Espaciado Y:" + +#. #### Y Padding #### +#: ../../po/../src/dialogs/tiledialog.cpp:777 +#, fuzzy +msgid "Row spacing: " +msgstr "Espaciado de líneas:" + +#: ../../po/../src/dialogs/tiledialog.cpp:786 +#, fuzzy +msgid "Vertical spacing between rows" +msgstr "Líneas verticales" + +#. #### X padding #### +#: ../../po/../src/dialogs/tiledialog.cpp:795 +#, fuzzy +msgid "Column spacing:" +msgstr "Espaciado de líneas:" + +#: ../../po/../src/dialogs/tiledialog.cpp:804 +#, fuzzy +msgid "Horizontal spacing between columns" +msgstr "Coordenada horizontal de la selección" + +#: ../../po/../src/dialogs/tiledialog.cpp:818 +#, fuzzy +msgid "Arrange selected objects" +msgstr "Agrupar los objetos seleccionados" + +#: ../../po/../src/dialogs/xml-tree.cpp:178 +#, fuzzy +msgid "Click to select nodes, drag to rearrange." +msgstr "Haga clic para seleccionar o crear un objeto de texto, luego escriba." + +#: ../../po/../src/dialogs/xml-tree.cpp:189 +msgid "Click attribute to edit." +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:193 +#, c-format +msgid "" +"Attribute %s selected. Press Ctrl+Enter when done editing to " +"commit changes." +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:284 +msgid "Drag to reorder nodes" +msgstr "Arrastrar para reordenar nodos" + +#: ../../po/../src/dialogs/xml-tree.cpp:304 +msgid "New element node" +msgstr "Nuevo nodo elemento" + +#: ../../po/../src/dialogs/xml-tree.cpp:326 +msgid "New text node" +msgstr "Siguiente nodo de texto" + +#: ../../po/../src/dialogs/xml-tree.cpp:347 +msgid "Duplicate node" +msgstr "Duplicar nodo" + +#: ../../po/../src/dialogs/xml-tree.cpp:368 +msgid "Delete node" +msgstr "Borrar nodo" + +#: ../../po/../src/dialogs/xml-tree.cpp:384 +msgid "Unindent node" +msgstr "Desangrar nodo" + +#: ../../po/../src/dialogs/xml-tree.cpp:399 +msgid "Indent node" +msgstr "Sangrar nodos" + +#: ../../po/../src/dialogs/xml-tree.cpp:411 +msgid "Raise node" +msgstr "Elevar nodo" + +#: ../../po/../src/dialogs/xml-tree.cpp:423 +msgid "Lower node" +msgstr "Bajar nodo" + +#: ../../po/../src/dialogs/xml-tree.cpp:468 +msgid "Delete attribute" +msgstr "Borrar atributo" + +#. TRANSLATORS: "Attribute" is a noun here +#: ../../po/../src/dialogs/xml-tree.cpp:513 +msgid "Attribute name" +msgstr "Nombre de atributo" + +#. TRANSLATORS: "Set" is a verb here +#: ../../po/../src/dialogs/xml-tree.cpp:533 +msgid "Set attribute" +msgstr "Definir atributo" + +#. TRANSLATORS: "Set" is a verb here +#: ../../po/../src/dialogs/xml-tree.cpp:535 +#, fuzzy +msgid "Set" +msgstr "Ajustar ID" + +#. TRANSLATORS: "Attribute" is a noun here +#: ../../po/../src/dialogs/xml-tree.cpp:558 +msgid "Attribute value" +msgstr "Valor del atributo" + +#: ../../po/../src/dialogs/xml-tree.cpp:1318 +msgid "New element node..." +msgstr "Nuevo nodo elemento..." + +#: ../../po/../src/dialogs/xml-tree.cpp:1339 +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:100 +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:98 +msgid "Cancel" +msgstr "Cancelar" + +#: ../../po/../src/dialogs/xml-tree.cpp:1345 +msgid "Create" +msgstr "Crear" + +#: ../../po/../src/dialogs/xml-tree.cpp:1458 +#, c-format +msgid "" +"Cannot set %s: Another element with value %s already exists!" +msgstr "" + +#: ../../po/../src/document.cpp:369 +#, c-format +msgid "New document %d" +msgstr "Nuevo documento %d" + +#: ../../po/../src/document.cpp:401 +#, c-format +msgid "Memory document %d" +msgstr "Documento memoria %d" + +#: ../../po/../src/document.cpp:524 +#, c-format +msgid "Unnamed document %d" +msgstr "Documento sin nombre %d" + +#. We hit green anchor, closing Green-Blue-Red +#: ../../po/../src/draw-context.cpp:441 +#, fuzzy +msgid "Path is closed." +msgstr "Trazo (%i nodos)" + +#. We hit bot start and end of single curve, closing paths +#: ../../po/../src/draw-context.cpp:456 +msgid "Closing path." +msgstr "" + +#. alpha of color under cursor, to show in the statusbar +#. locale-sensitive printf is OK, since this goes to the UI, not into SVG +#: ../../po/../src/dropper-context.cpp:354 +#, c-format +msgid " alpha %.3g" +msgstr "" + +#. where the color is picked, to show in the statusbar +#: ../../po/../src/dropper-context.cpp:356 +#, c-format +msgid ", averaged with radius %d" +msgstr "" + +#: ../../po/../src/dropper-context.cpp:356 +msgid " under cursor" +msgstr "" + +#. message, to show in the statusbar +#: ../../po/../src/dropper-context.cpp:358 +msgid "Release mouse to set color." +msgstr "" + +#: ../../po/../src/dropper-context.cpp:358 +#: ../../po/../src/tools-switch.cpp:207 +#, fuzzy +msgid "" +"Click to set fill, Shift+click to set stroke; drag to " +"average color in area; with Alt to pick inverse color; Ctrl+C " +"to copy the color under mouse to clipboard" +msgstr "" +"Haga clic para seleccionar un color, clic y arrastre para seleccionar la " +"media de color de un área." + +#: ../../po/../src/extension/dependency.cpp:244 +msgid "Dependency::" +msgstr "" + +#: ../../po/../src/extension/dependency.cpp:245 +#, fuzzy +msgid " type: " +msgstr "Estilo de relleno" + +#: ../../po/../src/extension/dependency.cpp:246 +#, fuzzy +msgid " location: " +msgstr "Resolución:" + +#: ../../po/../src/extension/dependency.cpp:247 +msgid " string: " +msgstr "" + +#: ../../po/../src/extension/dependency.cpp:250 +#, fuzzy +msgid " description: " +msgstr "Selección" + +#. static int i = 0; +#. std::cout << "Checking module[" << i++ << "]: " << name << std::endl; +#: ../../po/../src/extension/extension.cpp:244 +msgid "" +" This is caused by an improper .inx file for this extension. An improper ." +"inx file could have been caused by a faulty installation of Inkscape." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:247 +msgid "an ID was not defined for it." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:251 +msgid "there was no name defined for it." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:255 +msgid "the XML description of it got lost." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:259 +msgid "no implementation was defined for the extension." +msgstr "" + +#. std::cout << "Failed: " << *(_deps[i]) << std::endl; +#: ../../po/../src/extension/extension.cpp:266 +msgid "a dependency was not met." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:286 +#, fuzzy +msgid "Extension \"" +msgstr "Expansión:" + +#: ../../po/../src/extension/extension.cpp:286 +#, fuzzy +msgid "\" failed to load because " +msgstr "Error al cargar el archivo %s" + +#: ../../po/../src/extension/extension.cpp:565 +#, c-format +msgid "Could not create extension error log file '%s'" +msgstr "" + +#. This is some filler text, needs to change before relase +#: ../../po/../src/extension/error-file.cpp:56 +msgid "" +"One or more extensions failed to load\n" +"\n" +"The failed extensions have been skipped. Inkscape will continue to run " +"normally but those extensions will be unavailable. For details to " +"troubleshoot this problem, please refer to the error log located at: " +msgstr "" + +#. This is some filler text, needs to change before relase +#: ../../po/../src/extension/error-file.cpp:65 +msgid "Show dialog on startup" +msgstr "" + +#: ../../po/../src/extension/implementation/script.cpp:845 +msgid "" +"Inkscape has received an error from the script that it called. The text " +"returned with the error is included below. Inkscape will continue working, " +"but the action you requested has been cancelled." +msgstr "" + +#: ../../po/../src/extension/implementation/script.cpp:858 +msgid "" +"Inkscape has received additional data from the script executed. The script " +"did not return an error, but this may indicate the results will not be as " +"expected." +msgstr "" + +#: ../../po/../src/extension/init.cpp:173 +#, fuzzy +msgid "Null external module directory name. Modules will not be loaded." +msgstr "" +"El directorio de módulos (%s) no está disponible. No se cargarán los módulos " +"externos de ese directorio." + +#: ../../po/../src/extension/init.cpp:187 +#, fuzzy, c-format +msgid "" +"Modules directory (%s) is unavailable. External modules in that directory " +"will not be loaded." +msgstr "" +"El directorio de módulos (%s) no está disponible. No se cargarán los módulos " +"externos de ese directorio." + +#: ../../po/../src/extension/internal/gnome.cpp:80 +msgid "Select printer" +msgstr "Seleccionar impresora" + +#: ../../po/../src/extension/internal/gnome.cpp:131 +#, fuzzy +msgid "Inkscape: Print Preview" +msgstr "Inkscape (nombre documento %s..): Presentación preliminar" + +#: ../../po/../src/extension/internal/grid.cpp:213 +#, fuzzy +msgid "Line Width" +msgstr "An_cho de página" + +#: ../../po/../src/extension/internal/grid.cpp:214 +#, fuzzy +msgid "Horizontal Spacing" +msgstr "Líneas horizontales" + +#: ../../po/../src/extension/internal/grid.cpp:215 +#, fuzzy +msgid "Vertical Spacing" +msgstr "Líneas verticales" + +#: ../../po/../src/extension/internal/grid.cpp:216 +#, fuzzy +msgid "Horizontal Offset" +msgstr "Líneas horizontales" + +#: ../../po/../src/extension/internal/grid.cpp:217 +#, fuzzy +msgid "Vertical Offset" +msgstr "Líneas verticales" + +#: ../../po/../src/extension/internal/ps.cpp:123 +msgid "Print Destination" +msgstr "Destino de impresión" + +#. Print properties frame +#: ../../po/../src/extension/internal/ps.cpp:138 +msgid "Print properties" +msgstr "Propiedades de impresión" + +#: ../../po/../src/extension/internal/ps.cpp:145 +msgid "Print using PostScript operators" +msgstr "Imprimir usando operadores PostScript" + +#: ../../po/../src/extension/internal/ps.cpp:147 +#, fuzzy +msgid "" +"Use PostScript vector operators. The resulting image is usually smaller in " +"file size and can be arbitrarily scaled, but alpha transparency and patterns " +"will be lost." +msgstr "" +"Usar operadores PostScript vectoriales. La imagen resultante normalmente " +"será menor y puede ser escalada arbitrariamente, pero la transparencia alfa, " +"los gradientes, los marcadores y los patrones se perderán." + +#: ../../po/../src/extension/internal/ps.cpp:152 +msgid "Print as bitmap" +msgstr "Imprimir como mapa de bits" + +#: ../../po/../src/extension/internal/ps.cpp:154 +msgid "" +"Print everything as bitmap. The resulting image is usually larger in file " +"size and cannot be arbitrarily scaled without quality loss, but all objects " +"will be rendered exactly as displayed." +msgstr "" +"Imprimir todo como mapa de bits. La imagen resultante normalmente será mayor " +"y la calidad dependerá del factor de ampliación, pero todos los objetos " +"serán renderizados idénticos a lo que ve en pantalla." + +#: ../../po/../src/extension/internal/ps.cpp:168 +msgid "Preferred resolution (dots per inch) of bitmap" +msgstr "Resolución preferida (puntos por pulgada) de mapa de bits" + +#: ../../po/../src/extension/internal/ps.cpp:182 +msgid "Resolution:" +msgstr "Resolución:" + +#. Print destination frame +#: ../../po/../src/extension/internal/ps.cpp:186 +msgid "Print destination" +msgstr "Destino de impresión" + +#: ../../po/../src/extension/internal/ps.cpp:192 +msgid "" +"Use '> filename' to print to file.\n" +"Use '| prog arg...' to pipe to a program." +msgstr "" +"Utilice '> archivo' para imprimir a un archivo.\n" +"Utilice '| prog arg...' para enviarlo a un programa." + +#: ../../po/../src/extension/internal/ps.cpp:1227 +msgid "write error occurred" +msgstr "ocurrió un error de escritura" + +#: ../../po/../src/extension/prefdialog.cpp:21 +#, fuzzy +msgid " Preferences" +msgstr "Inkscape: _Avanzado" + +#. We can't call sp_ui_error_dialog because we may be +#. running from the console, in which case calling sp_ui +#. routines will cause a segfault. See bug 1000350 - bryce +#. sp_ui_error_dialog(_("Format autodetect failed. The file is being opened as SVG.")); +#: ../../po/../src/extension/system.cpp:105 +msgid "Format autodetect failed. The file is being opened as SVG." +msgstr "La autodetección de formato falló. El archivo se abrirá como SVG." + +#. TRANSLATORS: default.svg is localizable - this is the name of the default document +#. template. This way you can localize the default pagesize, translate the name of +#. the default layer, etc. If you wish to localize this file, please create a +#. localized share/templates/default.xx.svg file, where xx is your language code. +#: ../../po/../src/file.cpp:133 +#, fuzzy +msgid "default.svg" +msgstr "Predeterminados" + +#: ../../po/../src/file.cpp:215 ../../po/../src/file.cpp:900 +#, c-format +msgid "Failed to load the requested file %s" +msgstr "Error al cargar el archivo %s" + +#: ../../po/../src/file.cpp:240 +#, fuzzy +msgid "Document not saved yet. Cannot revert." +msgstr "Documento no guardado." + +#: ../../po/../src/file.cpp:246 +#, c-format +msgid "Changes will be lost! Are you sure you want to reload document %s?" +msgstr "" + +#: ../../po/../src/file.cpp:266 +#, fuzzy +msgid "Document reverted." +msgstr "Documento guardado." + +#: ../../po/../src/file.cpp:268 +#, fuzzy +msgid "Document not reverted." +msgstr "Documento no guardado." + +#: ../../po/../src/file.cpp:382 +msgid "Select file to open" +msgstr "Seleccione el archivo a abrir" + +#: ../../po/../src/file.cpp:518 +#, c-format +msgid "Removed %i unused definition in <defs>." +msgid_plural "Removed %i unused definitions in <defs>." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/file.cpp:523 +msgid "No unused definitions in <defs>." +msgstr "" + +#: ../../po/../src/file.cpp:548 +#, c-format +msgid "" +"No Inkscape extension found to save document (%s). This may have been " +"caused by an unknown filename extension." +msgstr "" +"No se ha encontrado una extensión de Inkscape que pueda guardar el documento " +"(%s). Esto pudo ser causado por una extensión de archivo desconocida." + +#: ../../po/../src/file.cpp:549 ../../po/../src/file.cpp:557 +msgid "Document not saved." +msgstr "Documento no guardado." + +#: ../../po/../src/file.cpp:556 +#, c-format +msgid "File %s could not be saved." +msgstr "No se pudo guardar el archivo %s." + +#: ../../po/../src/file.cpp:566 +msgid "Document saved." +msgstr "Documento guardado." + +#: ../../po/../src/file.cpp:614 +#, fuzzy, c-format +msgid "drawing%s" +msgstr "Dibujo" + +#: ../../po/../src/file.cpp:620 +#, fuzzy, c-format +msgid "drawing-%d%s" +msgstr "Dibujo" + +#: ../../po/../src/file.cpp:655 +#, fuzzy +msgid "Select file to save to" +msgstr "Seleccionar el archivo a guardar" + +#: ../../po/../src/file.cpp:739 +msgid "No changes need to be saved." +msgstr "No hay cambios que guardar." + +#: ../../po/../src/file.cpp:926 +msgid "Select file to import" +msgstr "Seleccionar el archivo a importar" + +#: ../../po/../src/gradient-context.cpp:263 +msgid "Ctrl: snap gradient angle" +msgstr "" + +#: ../../po/../src/gradient-context.cpp:264 +msgid "Shift: draw gradient around the starting point" +msgstr "" + +#. We did an undoable action, but sp_document_done will be called by the knot when released +#. status text; we do not track coords because this branch is run once, not all the time +#. during drag +#: ../../po/../src/gradient-context.cpp:462 +#, c-format +msgid "Gradient for %d objects; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/gradient-context.cpp:464 +#, fuzzy +msgid "Select objects on which to create gradient." +msgstr "Seleccione objetos para elevar." + +#: ../../po/../src/gradient-drag.cpp:65 +#, fuzzy +msgid "Linear gradient start" +msgstr "Gradiente lineal" + +#. POINT_LG_P1 +#: ../../po/../src/gradient-drag.cpp:66 +#, fuzzy +msgid "Linear gradient end" +msgstr "Gradiente lineal" + +#: ../../po/../src/gradient-drag.cpp:67 +#, fuzzy +msgid "Radial gradient center" +msgstr "Gradiente radial" + +#: ../../po/../src/gradient-drag.cpp:68 ../../po/../src/gradient-drag.cpp:69 +#, fuzzy +msgid "Radial gradient radius" +msgstr "Gradiente radial" + +#: ../../po/../src/gradient-drag.cpp:70 +#, fuzzy +msgid "Radial gradient focus" +msgstr "Gradiente radial" + +#: ../../po/../src/gradient-drag.cpp:659 +#, c-format +msgid "" +"%s for: %s%s; drag with Ctrl to snap angle, with Ctrl+Alt to " +"preserve angle, with Ctrl+Shift to scale around center" +msgstr "" + +#: ../../po/../src/gradient-drag.cpp:662 +msgid " (stroke)" +msgstr "" + +#: ../../po/../src/gradient-drag.cpp:665 +msgid "" +"Radial gradient center and focus; drag with Shift to " +"separate focus" +msgstr "" + +#: ../../po/../src/gradient-drag.cpp:667 +#, c-format +msgid "" +"Gradient point shared by %d gradients; drag with Shift to " +"separate" +msgstr "" + +#: ../../po/../src/helper/units.cpp:40 +msgid "Unit" +msgstr "Unidad" + +#: ../../po/../src/helper/units.cpp:40 +msgid "Units" +msgstr "Unidades" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Point" +msgstr "Punto" + +#: ../../po/../src/helper/units.cpp:41 +msgid "pt" +msgstr "pt" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Points" +msgstr "Puntos" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Pt" +msgstr "Pt" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Pixel" +msgstr "Pixel" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Pixels" +msgstr "Pixeles" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Px" +msgstr "Px" + +#. You can add new elements from this point forward +#: ../../po/../src/helper/units.cpp:44 ../share/extensions/straightseg.inx.h:2 +msgid "Percent" +msgstr "Porcentaje" + +#: ../../po/../src/helper/units.cpp:44 +msgid "Percents" +msgstr "Porcentajes" + +#: ../../po/../src/helper/units.cpp:45 +msgid "Millimeter" +msgstr "Milímetro" + +#: ../../po/../src/helper/units.cpp:45 +msgid "mm" +msgstr "mm" + +#: ../../po/../src/helper/units.cpp:45 +msgid "Millimeters" +msgstr "Milímetros" + +#: ../../po/../src/helper/units.cpp:46 +msgid "Centimeter" +msgstr "Centímetro" + +#: ../../po/../src/helper/units.cpp:46 +msgid "cm" +msgstr "cm" + +#: ../../po/../src/helper/units.cpp:46 +msgid "Centimeters" +msgstr "Centímetros" + +#: ../../po/../src/helper/units.cpp:47 +msgid "Meter" +msgstr "Metro" + +#: ../../po/../src/helper/units.cpp:47 +msgid "m" +msgstr "m" + +#: ../../po/../src/helper/units.cpp:47 +#, fuzzy +msgid "Meters" +msgstr "Metro" + +#. no svg_unit +#: ../../po/../src/helper/units.cpp:48 +msgid "Inch" +msgstr "Pulgada" + +#: ../../po/../src/helper/units.cpp:48 +msgid "in" +msgstr "in" + +#: ../../po/../src/helper/units.cpp:48 +msgid "Inches" +msgstr "Pulgadas" + +#. Volatiles do not have default, so there are none here +#. TRANSLATORS: for info, see http://www.w3.org/TR/REC-CSS2/syndata.html#length-units +#: ../../po/../src/helper/units.cpp:51 +msgid "Em square" +msgstr "Em cuadrado" + +#: ../../po/../src/helper/units.cpp:51 +msgid "em" +msgstr "em" + +#: ../../po/../src/helper/units.cpp:51 +msgid "Em squares" +msgstr "Em cuadrados" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/REC-CSS2/syndata.html#length-units +#: ../../po/../src/helper/units.cpp:53 +msgid "Ex square" +msgstr "Ex cuadrado" + +#: ../../po/../src/helper/units.cpp:53 +msgid "ex" +msgstr "ex" + +#: ../../po/../src/helper/units.cpp:53 +msgid "Ex squares" +msgstr "Ex cuadrados" + +#: ../../po/../src/inkscape.cpp:468 +msgid "Untitled document" +msgstr "Documento sin nombre" + +#. Show nice dialog box +#: ../../po/../src/inkscape.cpp:497 +msgid "Inkscape encountered an internal error and will close now.\n" +msgstr "Inkscape ha encontrado un error interno y se cerrará.\n" + +#: ../../po/../src/inkscape.cpp:498 +#, fuzzy +msgid "" +"Automatic backups of unsaved documents were done to the following " +"locations:\n" +msgstr "" +"Las copias de seguridad automáticas se realizaron en los siguientes " +"directorios:\n" + +#: ../../po/../src/inkscape.cpp:499 +#, fuzzy +msgid "Automatic backup of the following documents failed:\n" +msgstr "La copia de seguridad de los siguientes documentos falló:\n" + +#: ../../po/../src/inkscape.cpp:634 +#, c-format +msgid "" +"Cannot create directory %s.\n" +"%s" +msgstr "" +"No se puede crear el directorio %s.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:635 +#, c-format +msgid "" +"%s is not a valid directory.\n" +"%s" +msgstr "" +"%s no es un directorio válido.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:636 +#, c-format +msgid "" +"Cannot create file %s.\n" +"%s" +msgstr "" +"No se puede crear el archivo %s.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:637 +#, c-format +msgid "" +"Cannot write file %s.\n" +"%s" +msgstr "" +"No se puede escribir el archivo %s.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:638 +msgid "" +"Although Inkscape will run, it will use default settings,\n" +"and any changes made in preferences will not be saved." +msgstr "" +"Aunque Inkscape se ejecutará, se usará la configuración predeterminada\n" +"y no se guardarán los cambios hechos en las preferencias." + +#: ../../po/../src/inkscape.cpp:708 +#, c-format +msgid "" +"%s is not a regular file.\n" +"%s" +msgstr "" +"%s no es un archivo normal.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:709 +#, c-format +msgid "" +"%s not a valid XML file, or\n" +"you don't have read permissions on it.\n" +"%s" +msgstr "" +"%s no es un archivo XML válido o\n" +"no tiene permiso de lectura para él.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:711 +#, fuzzy, c-format +msgid "" +"%s is not a valid menus file.\n" +"%s" +msgstr "" +"%s no es un archivo de preferencias válido.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:712 +#, fuzzy +msgid "" +"Inkscape will run with default menus.\n" +"New menus will not be saved." +msgstr "" +"Inkscape se ejecutará con la configuración predeterminada.\n" +"No se guardarán ajustes nuevos." + +#. sp_ui_menu_append_check_item_from_verb(m, view, _("_Menu"), _("Show or hide the menu bar"), "menu", +#. checkitem_toggled, checkitem_update, 0); +#: ../../po/../src/interface.cpp:753 +msgid "Commands Bar" +msgstr "" + +#: ../../po/../src/interface.cpp:753 +#, fuzzy +msgid "Show or hide the Commands bar (under the menu)" +msgstr "Mostrar/ocultar reglas" + +#: ../../po/../src/interface.cpp:755 +#, fuzzy +msgid "Tool Controls" +msgstr "Opciones de la herramienta" + +#: ../../po/../src/interface.cpp:755 +#, fuzzy +msgid "Show or hide the Tool Controls panel" +msgstr "Mostrar/ocultar reglas" + +#: ../../po/../src/interface.cpp:757 +msgid "_Toolbox" +msgstr "" + +#: ../../po/../src/interface.cpp:757 +msgid "Show or hide the main toolbox (on the left)" +msgstr "" + +#: ../../po/../src/interface.cpp:763 +msgid "_Statusbar" +msgstr "" + +#: ../../po/../src/interface.cpp:763 +msgid "Show or hide the statusbar (at the bottom of the window)" +msgstr "" + +#: ../../po/../src/interface.cpp:820 +#, c-format +msgid "Verb \"%s\" Unknown" +msgstr "" + +#. TRANSLATORS: #%s is the id of the group e.g. , not a number. +#: ../../po/../src/interface.cpp:930 +#, fuzzy, c-format +msgid "Enter group #%s" +msgstr "Editar" + +#: ../../po/../src/interface.cpp:941 +#, fuzzy +msgid "Go to parent" +msgstr "Sin pintura" + +#: ../../po/../src/interface.cpp:972 +msgid "Could not parse SVG data" +msgstr "No se pudieron interpretar los datos SVG" + +#: ../../po/../src/interface.cpp:1135 +#, c-format +msgid "Overwrite %s" +msgstr "Sobrescribir %s" + +#: ../../po/../src/interface.cpp:1153 +#, c-format +msgid "" +"The file %s already exists. Do you want to overwrite that file with the " +"current document?" +msgstr "" +"El archivo %s ya existe. ¿Desea sobrescribir ese archivo con el documento " +"actual?" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:59 +msgid "Jabber connection lost." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:72 +#, c-format +msgid "Sending message; %u message remaining in send queue." +msgid_plural "Sending message; %u messages remaining in send queue." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:78 +msgid "Receive queue empty." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:154 +#, c-format +msgid "Receiving change; %u change left to process." +msgid_plural "Receiving change; %u changes left to process." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:157 +#, c-format +msgid "%s has left the chatroom." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:221 +msgid "Nickname %1 is already in use. Please choose a different nickname." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:225 +msgid "An error was encountered while attempting to connect to the server." +msgstr "" + +#. Check to see if the user made any modifications to this document. If so, +#. we want to give them the option of (1) letting us clear their document or (2) +#. opening a new, blank document for the whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:131 +msgid "%1 has invited you to a whiteboard session." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:132 +msgid "Incoming whiteboard invitation from %1" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:135 +msgid "Do you wish to accept %1's whiteboard session invitation?" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:137 +msgid "" +"Would you like to accept %1's invitation in a new document window?\n" +"Accepting the invitation in your current window will discard unsaved changes." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:143 +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:198 +#, fuzzy +msgid "Accept invitation" +msgstr "Selección" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:144 +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:199 +msgid "Decline invitation" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:145 +#, fuzzy +msgid "Accept invitation in new document window" +msgstr "Crear un documento nuevo" + +#. We could not create a new desktop; ask the user if she or he wants to +#. replace the current document and accept the invitation, or reject the invitation. +#. TRANSLATORS: %1 is a userid here +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:196 +msgid "" +"A new document window could not be opened for a whiteboard session with %" +"1" +msgstr "" + +#. TRANSLATORS: %1 is the peer whom refused our invitation. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:238 +msgid "" +"The user %1 has refused your " +"whiteboard invitation.\n" +"\n" +msgstr "" + +#. TRANSLATORS: %1 is the peer whom refused our invitation, %2 is our Jabber identity. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:241 +msgid "" +"You are still connected to a Jabber server as %2, and may send an " +"invitation to %1 again, or you may send an invitation to a different " +"user." +msgstr "" + +#. TRANSLATORS: %1 is the peer whom we tried to contact, but is already in a whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:252 +msgid "" +"The user %1 is already in a " +"whiteboard session.\n" +"\n" +msgstr "" + +#. TRANSLATORS: %1 is the peer whom we tried to contact, but is already in a whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:255 +msgid "" +"You are still connected to a Jabber server as %1, and may send an " +"invitation to a different user." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/invitation-confirm-dialog.cpp:26 +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:24 +msgid "_Write session file:" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/message-processors.cpp:145 +#, c-format +msgid "%s has joined the chatroom." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/message-queue.cpp:87 +#, fuzzy, c-format +msgid "%u change in receive queue." +msgid_plural "%u changes in receive queue." +msgstr[0] "No hay cambios que guardar." +msgstr[1] "No hay cambios que guardar." + +#: ../../po/../src/jabber_whiteboard/message-queue.cpp:117 +#, fuzzy, c-format +msgid "%u change in send queue." +msgid_plural "%u changes in send queue." +msgstr[0] "No hay cambios que guardar." +msgstr[1] "No hay cambios que guardar." + +#. if ID is NULL, then we have a real problem -- we were not able to find a key +#. nor generate one. The only thing we can really do here is abort, since we have +#. no way to let the other client(s) uniquely identify this object. +#. FIXME: If this indicates a programming bug, then don't request translation with +#. * _(...): it is most useful in untranslated form so that developers may search for +#. * it when someone reports it in a bug report (as we want users to do for all bugs, +#. * as indicated by it being a g_warning string). +#. * +#. * Otherwise, if it is not a programming bug but a network error or a bug in the +#. * remote peer (perhaps running different software) or whatever, then present it in +#. * an alert box, and avoid use of technical jargon `NULL'. +#. +#: ../../po/../src/jabber_whiteboard/message-utilities.cpp:171 +msgid "" +"ID for new object is NULL even after generation and lookup attempts: the new " +"object will NOT be sent, nor will any of its child objects!" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:60 +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:995 +msgid "Select a location and filename" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:62 +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:997 +#, fuzzy +msgid "Set filename" +msgstr "Nombre de archivo" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:301 +msgid "No SSL certificate was found." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:304 +msgid "The SSL certificate provided by the Jabber server is untrusted." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:307 +msgid "The SSL certificate provided by the Jabber server is expired." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:310 +msgid "" +"The SSL certificate provided by the Jabber server has not been activated." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:313 +msgid "" +"The SSL certificate provided by the Jabber server contains a hostname that " +"does not match the Jabber server's hostname." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:316 +msgid "" +"The SSL certificate provided by the Jabber server contains an invalid " +"fingerprint." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:319 +msgid "An unknown error occurred while setting up the SSL connection." +msgstr "" + +#. TRANSLATORS: %1 is the message that describes the specific error that occurred when +#. establishing the SSL connection. +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:325 +msgid "" +"%1\n" +"\n" +"Do you wish to continue connecting to the Jabber server?" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:328 +msgid "Continue connecting and ignore further errors" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:329 +msgid "Continue connecting, but warn me of further errors" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:330 +#, fuzzy +msgid "Cancel connection" +msgstr "Selección" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:777 +#, c-format +msgid "Established whiteboard session with %s." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:785 +#, c-format +msgid "%s has left the whiteboard session." +msgstr "" + +#. Inform the user +#. TRANSLATORS: %1 is the name of the user that disconnected, %2 is the name of the user whom the disconnected user disconnected from. +#. This message is not used in a chatroom context. +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:790 +msgid "" +"The user %1 has left the " +"whiteboard session.\n" +"\n" +msgstr "" + +#. TRANSLATORS: %1 and %2 are userids +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:792 +msgid "" +"You are still connected to a Jabber server as %2, and may establish a " +"new session to %1 or a different user." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:988 +msgid "" +"Could not open file %1 for session recording.\n" +"The error encountered was: %2.\n" +"\n" +"You may select a different location to record the session, or you may opt to " +"not record this session." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:990 +msgid "Choose a different location" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:991 +msgid "Skip session recording" +msgstr "" + +#: ../../po/../src/knot.cpp:673 +#, fuzzy +msgid "Node or handle drag canceled." +msgstr "Se ha cancelado el arrastre del nodo." + +#: ../../po/../src/libnrtype/FontFactory.cpp:358 +msgid "Ignoring font without family that will crash Pango" +msgstr "" + +#: ../../po/../src/main.cpp:395 +msgid "Print the Inkscape version number" +msgstr "" + +#: ../../po/../src/main.cpp:400 +msgid "Do not use X server (only process files from console)" +msgstr "No utilizar el servidor X (sólo procesar archivos desde la consola)" + +#: ../../po/../src/main.cpp:405 +msgid "Try to use X server (even if $DISPLAY is not set)" +msgstr "Intentar utilizar el servidor X (aunque no se haya definido $DISPLAY)" + +#: ../../po/../src/main.cpp:410 +msgid "Open specified document(s) (option string may be excluded)" +msgstr "" +"Abrir el(los) documento(s) especificado(s) (se pueden excluir las opciones " +"de cadena)" + +#: ../../po/../src/main.cpp:411 ../../po/../src/main.cpp:416 +#: ../../po/../src/main.cpp:421 ../../po/../src/main.cpp:483 +#: ../../po/../src/main.cpp:488 ../../po/../src/main.cpp:493 +msgid "FILENAME" +msgstr "NOMBRE DE ARCHIVO" + +#: ../../po/../src/main.cpp:415 +msgid "Print document(s) to specified output file (use '| program' for pipe)" +msgstr "" +"Imprimir documento(s) al archivo de salida especificado (use '| programa' " +"para el filtro)" + +#: ../../po/../src/main.cpp:420 +#, fuzzy +msgid "Export document to a PNG file" +msgstr "Exportar documento a archivo PNG" + +#: ../../po/../src/main.cpp:425 +#, fuzzy +msgid "The resolution used for exporting SVG into bitmap (default 90)" +msgstr "" +"La resolución utilizada para convertir SVG en mapa de bits (por omisión 72.0)" + +#: ../../po/../src/main.cpp:426 +msgid "DPI" +msgstr "DPI" + +#: ../../po/../src/main.cpp:430 +#, fuzzy +msgid "" +"Exported area in SVG user units (default is the canvas; 0,0 is lower-left " +"corner)" +msgstr "" +"Área exportada en milímetros (por omisión es el documento completo, 0,0 es " +"la esquina inferior izquierda)" + +#: ../../po/../src/main.cpp:431 +msgid "x0:y0:x1:y1" +msgstr "x0:y0:x1:y1" + +#: ../../po/../src/main.cpp:435 +msgid "Exported area is the entire drawing (not canvas)" +msgstr "" + +#: ../../po/../src/main.cpp:440 +msgid "" +"Snap the bitmap export area outwards to the nearest integer values (in SVG " +"user units)" +msgstr "" + +#: ../../po/../src/main.cpp:445 +#, fuzzy +msgid "The width of exported bitmap in pixels (overrides export-dpi)" +msgstr "El ancho del mapa de bits generado en pixeles (sobreescribe ppp)" + +#: ../../po/../src/main.cpp:446 +msgid "WIDTH" +msgstr "ANCHO" + +#: ../../po/../src/main.cpp:450 +#, fuzzy +msgid "The height of exported bitmap in pixels (overrides export-dpi)" +msgstr "El alto del mapa de bits generado en pixeles (sobreescribe ppp)" + +#: ../../po/../src/main.cpp:451 +msgid "HEIGHT" +msgstr "ALTO" + +#: ../../po/../src/main.cpp:455 +#, fuzzy +msgid "The ID of the object to export (overrides export-area)" +msgstr "El ancho del mapa de bits generado en pixeles (sobreescribe ppp)" + +#: ../../po/../src/main.cpp:456 ../../po/../src/main.cpp:532 +msgid "ID" +msgstr "ID" + +#. TRANSLATORS: this means: "Only export the object whose id is given in --export-id". +#. See "man inkscape" for details. +#: ../../po/../src/main.cpp:462 +msgid "" +"Export just the object with export-id, hide all others (only with export-id)" +msgstr "" + +#: ../../po/../src/main.cpp:467 +msgid "Use stored filename and DPI hints when exporting (only with export-id)" +msgstr "" + +#: ../../po/../src/main.cpp:472 +#, fuzzy +msgid "Background color of exported bitmap (any SVG-supported color string)" +msgstr "" +"Color de fondo para el mapa de bits exportado (cualquier cadena de color " +"admitida por SVG)" + +#: ../../po/../src/main.cpp:473 +msgid "COLOR" +msgstr "COLOR" + +#: ../../po/../src/main.cpp:477 +#, fuzzy +msgid "Background opacity of exported bitmap (either 0.0 to 1.0, or 1 to 255)" +msgstr "" +"Color de fondo para el mapa de bits exportado (cualquier cadena de color " +"admitida por SVG)" + +#: ../../po/../src/main.cpp:478 +msgid "VALUE" +msgstr "" + +#: ../../po/../src/main.cpp:482 +msgid "Export document to plain SVG file (no sodipodi or inkscape namespaces)" +msgstr "" +"Exportar documento a archivo SVG plano (sin las características especiales " +"de Inkscape o Sodipodi)" + +#: ../../po/../src/main.cpp:487 +#, fuzzy +msgid "Export document to a PS file" +msgstr "Exportar documento a archivo PNG" + +#: ../../po/../src/main.cpp:492 +#, fuzzy +msgid "Export document to an EPS file" +msgstr "Exportar documento a archivo PNG" + +#: ../../po/../src/main.cpp:497 +#, fuzzy +msgid "Convert text object to paths on export (EPS)" +msgstr "Convierte el contorno seleccionado en trazo" + +#: ../../po/../src/main.cpp:502 +msgid "Export files with the bounding box set to the page size (EPS)" +msgstr "" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:508 +msgid "" +"Query the X coordinate of the drawing or, if specified, of the object with --" +"query-id" +msgstr "" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:514 +msgid "" +"Query the Y coordinate of the drawing or, if specified, of the object with --" +"query-id" +msgstr "" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:520 +msgid "" +"Query the width of the drawing or, if specified, of the object with --query-" +"id" +msgstr "" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:526 +msgid "" +"Query the height of the drawing or, if specified, of the object with --query-" +"id" +msgstr "" + +#: ../../po/../src/main.cpp:531 +#, fuzzy +msgid "The ID of the object whose dimensions are queried" +msgstr "El ancho del mapa de bits generado en pixeles (sobreescribe ppp)" + +#. TRANSLATORS: this option makes Inkscape print the name (path) of the extension directory +#: ../../po/../src/main.cpp:537 +msgid "Print out the extension directory and exit" +msgstr "" + +#: ../../po/../src/main.cpp:542 +msgid "Show given files one-by-one, switch to next on any key/mouse event" +msgstr "" +"Mostrar los archivos uno por uno, cambiar al siguiente al pulsar una tecla o " +"el ratón" + +#: ../../po/../src/main.cpp:547 +msgid "Use the new Gtkmm GUI interface" +msgstr "" + +#: ../../po/../src/main.cpp:552 +msgid "Remove unused definitions from the defs section(s) of the document" +msgstr "" + +#: ../../po/../src/main.cpp:741 +msgid "" +"[OPTIONS...] [FILE...]\n" +"\n" +"Available options:" +msgstr "" + +#: ../../po/../src/menus-skeleton.h:17 +msgid "_New" +msgstr "_Nuevo" + +#: ../../po/../src/menus-skeleton.h:22 +msgid "Open _Recent" +msgstr "Abrir _reciente" + +#: ../../po/../src/menus-skeleton.h:53 +msgid "_Edit" +msgstr "_Edición" + +#: ../../po/../src/menus-skeleton.h:84 +msgid "_View" +msgstr "_Ver" + +#: ../../po/../src/menus-skeleton.h:85 +#, fuzzy +msgid "_Zoom" +msgstr "Aumentar" + +#: ../../po/../src/menus-skeleton.h:102 +#, fuzzy +msgid "Show/Hide" +msgstr "Mostrar las guías" + +#: ../../po/../src/menus-skeleton.h:107 +msgid "_Display mode" +msgstr "" + +#: ../../po/../src/menus-skeleton.h:126 +#, fuzzy +msgid "_Layer" +msgstr "_Bajar" + +#: ../../po/../src/menus-skeleton.h:143 +msgid "_Object" +msgstr "_Objeto" + +#: ../../po/../src/menus-skeleton.h:165 +msgid "_Path" +msgstr "T_razo" + +#: ../../po/../src/menus-skeleton.h:188 +#, fuzzy +msgid "_Text" +msgstr "Texto" + +#: ../../po/../src/menus-skeleton.h:200 +#, fuzzy +msgid "Effects" +msgstr "Offset:" + +#: ../../po/../src/menus-skeleton.h:207 +msgid "Whiteboa_rd" +msgstr "" + +#: ../../po/../src/menus-skeleton.h:220 +msgid "_Help" +msgstr "A_yuda" + +#: ../../po/../src/menus-skeleton.h:222 +#, fuzzy +msgid "Tutorials" +msgstr "_Tutoriales" + +#: ../../po/../src/node-context.cpp:382 +msgid "" +"Ctrl: toggle node type, snap handle angle, move hor/vert; Ctrl" +"+Alt: move along handles" +msgstr "" + +#: ../../po/../src/node-context.cpp:383 +msgid "" +"Shift: toggle node selection, disable snapping, rotate both handles" +msgstr "" + +#: ../../po/../src/node-context.cpp:384 +msgid "Alt: lock handle length; Ctrl+Alt: move along handles" +msgstr "" + +#: ../../po/../src/nodepath.cpp:1399 ../../po/../src/nodepath.cpp:1411 +#: ../../po/../src/nodepath.cpp:1492 ../../po/../src/nodepath.cpp:1504 +#, fuzzy +msgid "To join, you must have two endnodes selected." +msgstr "Para unir debe seleccionar dos nodos finales." + +#: ../../po/../src/nodepath.cpp:1633 ../../po/../src/nodepath.cpp:1647 +#, fuzzy +msgid "" +"Select two non-endpoint nodes on a path between which to delete " +"segments." +msgstr "" +"Debe seleccionar dos nodos no finales de un trazo al que quiera eliminarle " +"segmentos." + +#: ../../po/../src/nodepath.cpp:1743 +msgid "Cannot find path between nodes." +msgstr "No se puede encontrar el trazo entre los nodos." + +#: ../../po/../src/nodepath.cpp:2822 +#, c-format +msgid "" +"Node handle: angle %0.2f°, length %s; with Ctrl to snap " +"angle; with Alt to lock length; with Shift to rotate both " +"handles" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3351 +msgid "" +"Node: drag to edit the path; with Ctrl to snap to horizontal/" +"vertical; with Ctrl+Alt to snap to handles' directions" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3375 +msgid "" +"Node handle: drag to shape the curve; with Ctrl to snap angle; " +"with Alt to lock length; with Shift to rotate both handles" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3399 +msgid "" +"Node handle: drag to shape the curve; with Ctrl to snap angle; " +"with Alt to lock length; with Shift to rotate the opposite " +"handle in sync" +msgstr "" + +#. TRANSLATORS: "end" is an adjective here (NOT a verb) +#: ../../po/../src/nodepath.cpp:3591 +#, fuzzy +msgid "end node" +msgstr "Sangrar nodos" + +#. TRANSLATORS: "cusp" means "sharp" (cusp node); see also the Advanced Tutorial +#: ../../po/../src/nodepath.cpp:3596 +msgid "cusp" +msgstr "agudo" + +#. TRANSLATORS: "smooth" is an adjective here +#: ../../po/../src/nodepath.cpp:3599 +msgid "smooth" +msgstr "suave" + +#: ../../po/../src/nodepath.cpp:3601 +msgid "symmetric" +msgstr "simétrico" + +#. TRANSLATORS: "end" is an adjective here (NOT a verb) +#: ../../po/../src/nodepath.cpp:3607 +msgid "end node, handle retracted (drag with Shift to extend)" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3609 +msgid "one handle retracted (drag with Shift to extend)" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3612 +msgid "both handles retracted (drag with Shift to extend)" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3624 +#, fuzzy +msgid "Drag nodes or node handles; arrow keys to move nodes" +msgstr "Arrastre los nodos o puntos de control para editar el trazo" + +#: ../../po/../src/nodepath.cpp:3625 +#, fuzzy +msgid "Drag the node or its handles; arrow keys to move the node" +msgstr "" +"Arrastre para crear una línea a mano alzada. Presione 'a' para conmutar " +"Añadir/Nuevo." + +#: ../../po/../src/nodepath.cpp:3651 ../../po/../src/nodepath.cpp:3663 +#, fuzzy +msgid "Select a single object to edit its nodes or handles." +msgstr "Seleccionar todos los objetos o todos los nodos" + +#: ../../po/../src/nodepath.cpp:3655 +#, fuzzy, c-format +msgid "" +"0 out of %i node selected. Click, Shift+click, " +"or drag around nodes to select." +msgid_plural "" +"0 out of %i nodes selected. Click, Shift+click, " +"or drag around nodes to select." +msgstr[0] "" +"Se han seleccionado 0 de %i nodos. Haga clic, Mayús+clic o arrastre el ratón " +"alrededor de los nodos para seleccionarlos." +msgstr[1] "" +"Se han seleccionado 0 de %i nodos. Haga clic, Mayús+clic o arrastre el ratón " +"alrededor de los nodos para seleccionarlos." + +#: ../../po/../src/nodepath.cpp:3661 +msgid "Drag the handles of the object to modify it." +msgstr "" + +#: ../../po/../src/nodepath.cpp:3669 +#, fuzzy, c-format +msgid "%i of %i node selected; %s. %s." +msgid_plural "%i of %i nodes selected; %s. %s." +msgstr[0] "%i de %i nodos seleccionados; %s. %s." +msgstr[1] "%i de %i nodos seleccionados; %s. %s." + +#: ../../po/../src/nodepath.cpp:3675 +#, fuzzy, c-format +msgid "%i of %i node selected. %s." +msgid_plural "%i of %i nodes selected. %s." +msgstr[0] "%i de %i nodos seleccionados. %s." +msgstr[1] "%i de %i nodos seleccionados. %s." + +#: ../../po/../src/object-edit.cpp:493 +msgid "" +"Adjust the horizontal rounding radius; with Ctrl to make the " +"vertical radius the same" +msgstr "" + +#: ../../po/../src/object-edit.cpp:499 +msgid "" +"Adjust the vertical rounding radius; with Ctrl to make the " +"horizontal radius the same" +msgstr "" + +#: ../../po/../src/object-edit.cpp:506 ../../po/../src/object-edit.cpp:513 +msgid "" +"Adjust the width and height of the rectangle; with Ctrl to " +"lock ratio or stretch in one dimension only" +msgstr "" + +#: ../../po/../src/object-edit.cpp:686 +msgid "Adjust ellipse width, with Ctrl to make circle" +msgstr "" + +#: ../../po/../src/object-edit.cpp:689 +msgid "Adjust ellipse height, with Ctrl to make circle" +msgstr "" + +#: ../../po/../src/object-edit.cpp:692 +msgid "" +"Position the start point of the arc or segment; with Ctrl to " +"snap angle; drag inside the ellipse for arc, outside for " +"segment" +msgstr "" + +#: ../../po/../src/object-edit.cpp:695 +msgid "" +"Position the end point of the arc or segment; with Ctrl to " +"snap angle; drag inside the ellipse for arc, outside for " +"segment" +msgstr "" + +#: ../../po/../src/object-edit.cpp:800 +msgid "" +"Adjust the tip radius of the star or polygon; with Shift to " +"round; with Alt to randomize" +msgstr "" + +#: ../../po/../src/object-edit.cpp:803 +msgid "" +"Adjust the base radius of the star; with Ctrl to keep star " +"rays radial (no skew); with Shift to round; with Alt to " +"randomize" +msgstr "" + +#: ../../po/../src/object-edit.cpp:967 +msgid "" +"Roll/unroll the spiral from inside; with Ctrl to snap angle; " +"with Alt to converge/diverge" +msgstr "" + +#: ../../po/../src/object-edit.cpp:969 +msgid "" +"Roll/unroll the spiral from outside; with Ctrl to snap angle; " +"with Shift to scale/rotate" +msgstr "" + +#: ../../po/../src/object-edit.cpp:1006 +msgid "Adjust the offset distance" +msgstr "" + +#. TRANSLATORS: This refers to the pattern that's inside the object +#: ../../po/../src/object-edit.cpp:1036 +msgid "Move the pattern fill inside the object" +msgstr "" + +#: ../../po/../src/object-edit.cpp:1038 +#, fuzzy +msgid "Scale the pattern fill uniformly" +msgstr "Seleccione objetos para bajar." + +#: ../../po/../src/object-edit.cpp:1040 +msgid "Rotate the pattern fill; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/object-edit.cpp:1065 +msgid "Drag to resize the flowed text frame" +msgstr "" + +#. Item dialog +#: ../../po/../src/object-ui.cpp:106 +#, fuzzy +msgid "Object _Properties" +msgstr "_Propiedades del rectángulo" + +#. Select item +#: ../../po/../src/object-ui.cpp:116 +msgid "_Select This" +msgstr "_Seleccionar esto" + +#. Create link +#: ../../po/../src/object-ui.cpp:126 +msgid "_Create Link" +msgstr "_Crear enlace" + +#. "Ungroup" +#: ../../po/../src/object-ui.cpp:199 ../../po/../src/verbs.cpp:1931 +msgid "_Ungroup" +msgstr "Desagr_upar" + +#. Link dialog +#: ../../po/../src/object-ui.cpp:239 +msgid "Link _Properties" +msgstr "_Propiedades del enlace" + +#. Select item +#: ../../po/../src/object-ui.cpp:249 +msgid "_Follow Link" +msgstr "Se_guir enlace" + +#. Reset transformations +#: ../../po/../src/object-ui.cpp:254 +msgid "_Remove Link" +msgstr "_Eliminar enlace" + +#. Link dialog +#: ../../po/../src/object-ui.cpp:303 +msgid "Image _Properties" +msgstr "_Propiedades de la imagen" + +#. Item dialog +#: ../../po/../src/object-ui.cpp:344 +msgid "_Fill and Stroke" +msgstr "_Relleno y contorno" + +#: ../../po/../src/path-chemistry.cpp:58 +#, fuzzy +msgid "Select at least two objects to combine." +msgstr "Seleccione por lo menos dos objetos para combinar." + +#: ../../po/../src/path-chemistry.cpp:65 +#, fuzzy +msgid "At least one of the objects is not a path, cannot combine." +msgstr "Uno de los objetos no es un trazo, no se puede combinar." + +#: ../../po/../src/path-chemistry.cpp:73 +#, fuzzy +msgid "" +"You cannot combine objects from different groups or layers." +msgstr "No puede combinar objetos de diferentes grupos o capas." + +#: ../../po/../src/path-chemistry.cpp:155 +#, fuzzy +msgid "Select path(s) to break apart." +msgstr "Seleccione trazos para descombinar." + +#: ../../po/../src/path-chemistry.cpp:231 +#, fuzzy +msgid "No path(s) to break apart in the selection." +msgstr "No hay grupos descombinables en la selección." + +#: ../../po/../src/path-chemistry.cpp:252 +#, fuzzy +msgid "Select object(s) to convert to path." +msgstr "Seleccione objetos para bajar al fondo." + +#: ../../po/../src/path-chemistry.cpp:297 +#, fuzzy +msgid "No objects to convert to path in the selection." +msgstr "No hay grupos desagrupables en la selección." + +#: ../../po/../src/path-chemistry.cpp:345 +#, fuzzy +msgid "Select path(s) to reverse." +msgstr "Seleccione dos o más objetos para agrupar." + +#: ../../po/../src/path-chemistry.cpp:370 +#, fuzzy +msgid "No paths to reverse in the selection." +msgstr "No hay grupos descombinables en la selección." + +#: ../../po/../src/pen-context.cpp:379 ../../po/../src/pencil-context.cpp:233 +#, fuzzy +msgid "Continuing selected path" +msgstr "Reducir los trazos seleccionados" + +#: ../../po/../src/pen-context.cpp:390 ../../po/../src/pencil-context.cpp:242 +#, fuzzy +msgid "Creating new path" +msgstr "Creando curva nueva" + +#: ../../po/../src/pen-context.cpp:394 ../../po/../src/pencil-context.cpp:246 +#, fuzzy +msgid "Appending to selected path" +msgstr "Añadiendo a selección" + +#: ../../po/../src/pen-context.cpp:538 +#, fuzzy +msgid "Click or click and drag to close and finish the path." +msgstr "Haga clic para seleccionar o crear un objeto de texto, luego escriba." + +#: ../../po/../src/pen-context.cpp:548 +#, fuzzy +msgid "" +"Click or click and drag to continue the path from this point." +msgstr "Haga clic para seleccionar o crear un objeto de texto, luego escriba." + +#: ../../po/../src/pen-context.cpp:857 +#, c-format +msgid "" +"%s: angle %3.2f°, distance %s; with Ctrl to snap angle, " +"Enter to finish the path" +msgstr "" + +#: ../../po/../src/pen-context.cpp:882 +#, c-format +msgid "" +"Curve handle: angle %3.2f°, length %s; with Ctrl to snap " +"angle" +msgstr "" + +#: ../../po/../src/pen-context.cpp:912 +#, c-format +msgid "" +"%s: angle %3.2f°, length %s; with Ctrl to snap angle, " +"with Shift to move this handle only" +msgstr "" + +#: ../../po/../src/pen-context.cpp:946 +msgid "Finishing pen" +msgstr "Terminar pluma" + +#: ../../po/../src/pencil-context.cpp:320 +msgid "Release here to close and finish the path." +msgstr "" + +#: ../../po/../src/pencil-context.cpp:326 +#, fuzzy +msgid "Drawing a freehand path" +msgstr "Dibujar líneas a mano alzada (F6)" + +#: ../../po/../src/pencil-context.cpp:331 +msgid "Drag to continue the path from this point." +msgstr "" + +#. Write curves to object +#: ../../po/../src/pencil-context.cpp:390 +msgid "Finishing freehand" +msgstr "Terminar mano alzada" + +#: ../../po/../src/rect-context.cpp:387 +msgid "" +"Ctrl: make square or integer-ratio rect, lock a rounded corner " +"circular" +msgstr "" + +#: ../../po/../src/rect-context.cpp:549 +#, c-format +msgid "" +"Rectangle: %s × %s; with Ctrl to make square or integer-" +"ratio rectangle; with Shift to draw around the starting point" +msgstr "" + +#: ../../po/../src/select-context.cpp:243 +#, fuzzy +msgid "Move canceled." +msgstr "Movimiento cancelado." + +#: ../../po/../src/select-context.cpp:252 +#, fuzzy +msgid "Selection canceled." +msgstr "Selección cancelada." + +#: ../../po/../src/select-context.cpp:642 +msgid "Ctrl: select in groups, move hor/vert" +msgstr "" + +#: ../../po/../src/select-context.cpp:643 +msgid "Shift: toggle select, force rubberband, disable snapping" +msgstr "" + +#: ../../po/../src/select-context.cpp:644 +msgid "Alt: select under, move selected" +msgstr "" + +#: ../../po/../src/select-context.cpp:798 +#, fuzzy +msgid "Selected object is not a group. Cannot enter." +msgstr "El objeto seleccionado no tiene contorno, no se puede perfilar." + +#: ../../po/../src/select-context.cpp:876 +#, c-format +msgid "" +"Move by %s, %s; with Ctrl to restrict to horizontal/vertical; " +"with Shift to disable snapping" +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:228 +#, fuzzy +msgid "Nothing was deleted." +msgstr "No se ha borrado nada." + +#: ../../po/../src/selection-chemistry.cpp:259 +#, fuzzy +msgid "Select object(s) to duplicate." +msgstr "Seleccione objetos para duplicar." + +#: ../../po/../src/selection-chemistry.cpp:420 +#, fuzzy +msgid "Select two or more objects to group." +msgstr "Seleccione dos o más objetos para agrupar." + +#: ../../po/../src/selection-chemistry.cpp:428 +#, fuzzy +msgid "Select at least two objects to group." +msgstr "Seleccione por lo menos dos objetos para agrupar." + +#: ../../po/../src/selection-chemistry.cpp:513 +#, fuzzy +msgid "Select a group to ungroup." +msgstr "Seleccione un grupo para desagrupar." + +#: ../../po/../src/selection-chemistry.cpp:554 +#, fuzzy +msgid "No groups to ungroup in the selection." +msgstr "No hay grupos desagrupables en la selección." + +#: ../../po/../src/selection-chemistry.cpp:623 +#, fuzzy +msgid "Select objects to raise." +msgstr "Seleccione objetos para elevar." + +#: ../../po/../src/selection-chemistry.cpp:629 +#: ../../po/../src/selection-chemistry.cpp:681 +#: ../../po/../src/selection-chemistry.cpp:715 +#: ../../po/../src/selection-chemistry.cpp:773 +#, fuzzy +msgid "" +"You cannot raise/lower objects from different groups or layers." +msgstr "No puede elevar/bajar objetos de diferentes grupos o capas." + +#: ../../po/../src/selection-chemistry.cpp:673 +#, fuzzy +msgid "Select object(s) to raise to top." +msgstr "Seleccione los objetos para poner al frente." + +#: ../../po/../src/selection-chemistry.cpp:709 +#, fuzzy +msgid "Select object(s) to lower." +msgstr "Seleccione objetos para bajar." + +#: ../../po/../src/selection-chemistry.cpp:765 +#, fuzzy +msgid "Select object(s) to lower to bottom." +msgstr "Seleccione objetos para bajar al fondo." + +#: ../../po/../src/selection-chemistry.cpp:806 +msgid "Nothing to undo." +msgstr "Nada que deshacer." + +#: ../../po/../src/selection-chemistry.cpp:813 +msgid "Nothing to redo." +msgstr "Nada que rehacer." + +#: ../../po/../src/selection-chemistry.cpp:969 +msgid "Nothing was copied." +msgstr "No se ha copiado nada." + +#: ../../po/../src/selection-chemistry.cpp:1051 +msgid "Current layer is hidden. Unhide it to be able to paste to it." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1055 +msgid "Current layer is locked. Unlock it to be able to paste to it." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1068 +#: ../../po/../src/selection-chemistry.cpp:1103 +#, fuzzy +msgid "Nothing on the clipboard." +msgstr "No hay nada en el portapapeles." + +#: ../../po/../src/selection-chemistry.cpp:1109 +#, fuzzy +msgid "Select object(s) to paste style to." +msgstr "Seleccione los objetos a los que quiera pegarle el estilo." + +#: ../../po/../src/selection-chemistry.cpp:1128 +#, fuzzy +msgid "Select object(s) to move to the layer above." +msgstr "Seleccione objetos para bajar al fondo." + +#: ../../po/../src/selection-chemistry.cpp:1146 +#, fuzzy +msgid "No more layers above." +msgstr "Documento guardado." + +#: ../../po/../src/selection-chemistry.cpp:1160 +#, fuzzy +msgid "Select object(s) to move to the layer below." +msgstr "Seleccione objetos para bajar al fondo." + +#: ../../po/../src/selection-chemistry.cpp:1178 +#, fuzzy +msgid "No more layers below." +msgstr "Documento guardado." + +#: ../../po/../src/selection-chemistry.cpp:1811 +#, fuzzy +msgid "Select a clone to unlink." +msgstr "Seleccione un grupo para desagrupar." + +#: ../../po/../src/selection-chemistry.cpp:1842 +#, fuzzy +msgid "No clones to unlink in the selection." +msgstr "No hay grupos desagrupables en la selección." + +#: ../../po/../src/selection-chemistry.cpp:1859 +msgid "" +"Select a clone to go to its original. Select a linked offset " +"to go to its source. Select a text on path to go to the path. Select " +"a flowed text to go to its frame." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1882 +msgid "" +"Cannot find the object to select (orphaned clone, offset, textpath, " +"flowed text?)" +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1888 +msgid "" +"The object you're trying to select is not visible (it is in <" +"defs>)" +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1915 +#, fuzzy +msgid "Select object(s) to convert to pattern." +msgstr "Seleccione objetos para bajar al fondo." + +#: ../../po/../src/selection-chemistry.cpp:2006 +#, fuzzy +msgid "Select an object with pattern fill to extract objects from." +msgstr "Seleccione objetos para bajar." + +#: ../../po/../src/selection-chemistry.cpp:2059 +#, fuzzy +msgid "No pattern fills in the selection." +msgstr "No hay grupos para reducir/ampliar en la selección." + +#: ../../po/../src/selection-chemistry.cpp:2079 +#, fuzzy +msgid "Select object(s) to make a bitmap copy." +msgstr "Seleccione los objetos para poner al frente." + +#: ../../po/../src/selection-describer.cpp:37 +msgid "Click selection to toggle scale/rotation handles" +msgstr "" +"Haga clic en la selección para conmutar los tiradores de escalado/rotación" + +#. no items +#: ../../po/../src/selection-describer.cpp:39 +#, fuzzy +msgid "" +"No objects selected. Click, Shift+click, or drag around objects to select." +msgstr "" +"No se han seleccionado objetos. Haga clic, Mayús+clic o arrastre para " +"seleccionar los objetos." + +#: ../../po/../src/selection-describer.cpp:51 +#, fuzzy, c-format +msgid " in layer %s" +msgstr "Elevar nodo" + +#: ../../po/../src/selection-describer.cpp:54 +#, fuzzy, c-format +msgid " in layer %s" +msgstr "Elevar nodo" + +#: ../../po/../src/selection-describer.cpp:66 +msgid "Use Shift+D to look up original" +msgstr "" + +#: ../../po/../src/selection-describer.cpp:70 +msgid "Use Shift+D to look up path" +msgstr "" + +#: ../../po/../src/selection-describer.cpp:74 +msgid "Use Shift+D to look up frame" +msgstr "" + +#: ../../po/../src/selection-describer.cpp:84 +#, fuzzy, c-format +msgid "%i object selected" +msgid_plural "%i objects selected" +msgstr[0] "%i objetos seleccionados. %s." +msgstr[1] "%i objetos seleccionados. %s." + +#: ../../po/../src/selection-describer.cpp:90 +#, c-format +msgid "%s%s. %s." +msgstr "" + +#: ../../po/../src/selection-describer.cpp:94 +#, fuzzy, c-format +msgid "%s in %i layer. %s." +msgid_plural "%s in %i layers. %s." +msgstr[0] "%i objetos seleccionados. %s." +msgstr[1] "%i objetos seleccionados. %s." + +#: ../../po/../src/seltrans.cpp:498 +msgid "" +"Center of rotation and skewing: drag to reposition; scaling with " +"Shift also uses this center" +msgstr "" + +#: ../../po/../src/seltrans.cpp:514 +msgid "" +"Squeeze or stretch selection; with Ctrl to scale uniformly; " +"with Shift to scale around rotation center" +msgstr "" + +#: ../../po/../src/seltrans.cpp:515 +msgid "" +"Scale selection; with Ctrl to scale uniformly; with Shift to scale around rotation center" +msgstr "" + +#: ../../po/../src/seltrans.cpp:519 +msgid "" +"Skew selection; with Ctrl to snap angle; with Shift to " +"skew around the opposite side" +msgstr "" + +#: ../../po/../src/seltrans.cpp:520 +msgid "" +"Rotate selection; with Ctrl to snap angle; with Shift " +"to rotate around the opposite corner" +msgstr "" + +#: ../../po/../src/seltrans.cpp:829 ../../po/../src/seltrans.cpp:909 +#, c-format +msgid "Scale: %0.2f%% x %0.2f%%; with Ctrl to lock ratio" +msgstr "" + +#. TRANSLATORS: don't modify the first ";" (it will NOT be displayed as ";" - only the second one will be) +#: ../../po/../src/seltrans.cpp:984 +#, c-format +msgid "Skew: %0.2f°; with Ctrl to snap angle" +msgstr "" + +#. TRANSLATORS: don't modify the first ";" (it will NOT be displayed as ";" - only the second one will be) +#: ../../po/../src/seltrans.cpp:1035 +#, c-format +msgid "Rotate: %0.2f°; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/seltrans.cpp:1090 +#, fuzzy, c-format +msgid "Move center to %s, %s" +msgstr "Enlazar a %s" + +#: ../../po/../src/slideshow.cpp:90 +msgid "Inkscape slideshow" +msgstr "Muestra de diapositivas Inkscape" + +#: ../../po/../src/sp-anchor.cpp:181 +#, fuzzy, c-format +msgid "Link to %s" +msgstr "Enlazar a %s" + +#: ../../po/../src/sp-anchor.cpp:185 +#, fuzzy +msgid "Link without URI" +msgstr "Enlazar a %s" + +#: ../../po/../src/sp-ellipse.cpp:438 ../../po/../src/sp-ellipse.cpp:870 +#, fuzzy +msgid "Ellipse" +msgstr "Elipse" + +#: ../../po/../src/sp-ellipse.cpp:583 +#, fuzzy +msgid "Circle" +msgstr "Círculo" + +#: ../../po/../src/sp-ellipse.cpp:865 +#, fuzzy +msgid "Segment" +msgstr "Elipse" + +#: ../../po/../src/sp-ellipse.cpp:867 +msgid "Arc" +msgstr "" + +#. TRANSLATORS: "Flow region" is an area where text is allowed to flow +#: ../../po/../src/sp-flowregion.cpp:276 +#, fuzzy +msgid "Flow region" +msgstr "Se_guir enlace" + +#. TRANSLATORS: A region "cut out of" a flow region; text is not allowed to flow inside the +#. * flow excluded region. flowRegionExclude in SVG 1.2: see +#. * http://www.w3.org/TR/2004/WD-SVG12-20041027/flow.html#flowRegion-elem and +#. * http://www.w3.org/TR/2004/WD-SVG12-20041027/flow.html#flowRegionExclude-elem. +#: ../../po/../src/sp-flowregion.cpp:493 +msgid "Flow excluded region" +msgstr "" + +#: ../../po/../src/sp-flowtext.cpp:355 +#, c-format +msgid "Flowed text (%d characters)" +msgstr "" + +#: ../../po/../src/sp-flowtext.cpp:357 +#, c-format +msgid "Linked flowed text (%d characters)" +msgstr "" + +#: ../../po/../src/sp-guide.cpp:290 +msgid "vertical guideline" +msgstr "guía vertical" + +#: ../../po/../src/sp-guide.cpp:292 +msgid "horizontal guideline" +msgstr "guía horizontal" + +#: ../../po/../src/sp-image.cpp:835 +msgid "embedded" +msgstr "" + +#: ../../po/../src/sp-image.cpp:839 +msgid "(null_pointer)" +msgstr "" + +#: ../../po/../src/sp-image.cpp:843 +#, fuzzy, c-format +msgid "Image with bad reference: %s" +msgstr "Imagen con referencia incorrecta: %s" + +#: ../../po/../src/sp-image.cpp:844 +#, fuzzy, c-format +msgid "Image %d × %d: %s" +msgstr "Imagen de color %d x %d : %s" + +#: ../../po/../src/sp-item-group.cpp:390 +#, fuzzy, c-format +msgid "Group of %d object" +msgid_plural "Group of %d objects" +msgstr[0] "Grupo de %d objetos" +msgstr[1] "Grupo de %d objetos" + +#: ../../po/../src/sp-item.cpp:720 +msgid "Object" +msgstr "Objeto" + +#: ../../po/../src/sp-line.cpp:202 +#, fuzzy +msgid "Line" +msgstr "Elipse" + +#. TRANSLATORS COMMENT: %s is either "outset" or "inset" depending on sign +#: ../../po/../src/sp-offset.cpp:433 +#, c-format +msgid "Linked offset, %s by %f pt" +msgstr "" + +#: ../../po/../src/sp-offset.cpp:434 ../../po/../src/sp-offset.cpp:438 +#, fuzzy +msgid "outset" +msgstr "A_mpliar" + +#: ../../po/../src/sp-offset.cpp:434 ../../po/../src/sp-offset.cpp:438 +#, fuzzy +msgid "inset" +msgstr "Re_ducir" + +#. TRANSLATORS COMMENT: %s is either "outset" or "inset" depending on sign +#: ../../po/../src/sp-offset.cpp:437 +#, c-format +msgid "Dynamic offset, %s by %f pt" +msgstr "" + +#: ../../po/../src/sp-path.cpp:127 +#, fuzzy, c-format +msgid "Path (%i node)" +msgid_plural "Path (%i nodes)" +msgstr[0] "Trazo (%i nodos)" +msgstr[1] "Trazo (%i nodos)" + +#: ../../po/../src/sp-polygon.cpp:216 +#, fuzzy +msgid "Polygon" +msgstr "Círculo" + +#: ../../po/../src/sp-polyline.cpp:179 +#, fuzzy +msgid "Polyline" +msgstr "Elipse" + +#: ../../po/../src/sp-rect.cpp:250 +#, fuzzy +msgid "Rectangle" +msgstr "Rectángulo" + +#. TRANSLATORS: since turn count isn't an integer, please adjust the +#. string as needed to deal with an localized plural forms. +#: ../../po/../src/sp-spiral.cpp:305 +#, c-format +msgid "Spiral with %3f turns" +msgstr "" + +#: ../../po/../src/sp-star.cpp:288 +#, fuzzy, c-format +msgid "Star with %d vertex" +msgid_plural "Star with %d vertices" +msgstr[0] "Estrella de %d lados" +msgstr[1] "Estrella de %d lados" + +#: ../../po/../src/sp-star.cpp:292 +#, fuzzy, c-format +msgid "Polygon with %d vertex" +msgid_plural "Polygon with %d vertices" +msgstr[0] "Polígono de %d lados" +msgstr[1] "Polígono de %d lados" + +#. TRANSLATORS: For description of font with no name. +#: ../../po/../src/sp-text.cpp:420 +msgid "<no name found>" +msgstr "" + +#: ../../po/../src/sp-text.cpp:426 +#, fuzzy, c-format +msgid "Text on path (%s, %s)" +msgstr "Texto (%s, %.5gpt)" + +#: ../../po/../src/sp-text.cpp:427 +#, fuzzy, c-format +msgid "Text (%s, %s)" +msgstr "Texto (%s, %.5gpt)" + +#. TRANSLATORS: Used for statusbar description for long chains: +#. * "Clone of: Clone of: ... in Layer 1". +#: ../../po/../src/sp-use.cpp:317 +#, fuzzy +msgid "..." +msgstr "_Abrir..." + +#: ../../po/../src/sp-use.cpp:325 +#, fuzzy, c-format +msgid "Clone of: %s" +msgstr "Enlazar a %s" + +#: ../../po/../src/sp-use.cpp:329 +msgid "Orphaned clone" +msgstr "" + +#: ../../po/../src/spiral-context.cpp:355 +msgid "Ctrl: snap angle" +msgstr "" + +#: ../../po/../src/spiral-context.cpp:357 +msgid "Alt: lock spiral radius" +msgstr "" + +#: ../../po/../src/spiral-context.cpp:469 +#, c-format +msgid "" +"Spiral: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/splivarot.cpp:106 +#, fuzzy +msgid "Select at least 2 paths to perform a boolean operation." +msgstr "" +"Debe seleccionar al menos dos trazos para realizar una operación booleana." + +#: ../../po/../src/splivarot.cpp:112 +#, fuzzy +msgid "" +"Select exactly 2 paths to perform difference, XOR, division, or path " +"cut." +msgstr "Seleccione solamente dos trazos para realizar diferencia o XOR." + +#: ../../po/../src/splivarot.cpp:129 ../../po/../src/splivarot.cpp:144 +#, fuzzy +msgid "" +"Unable to determine the z-order of the objects selected for " +"difference, XOR, division, or path cut." +msgstr "" +"No se pudo determinar el orden Z de los objetos seleccionados para la " +"diferencia." + +#: ../../po/../src/splivarot.cpp:174 +#, fuzzy +msgid "" +"One of the objects is not a path, cannot perform boolean operation." +msgstr "" +"Uno de los objetos no es un trazo, no se puede realizar una operación " +"booleana." + +#. TRANSLATORS: "to outline" means "to convert stroke to path" +#: ../../po/../src/splivarot.cpp:554 +#, fuzzy +msgid "Select path(s) to outline." +msgstr "Seleccione trazos para reducir/ampliar." + +#. TRANSLATORS: "to outline" means "to convert stroke to path" +#: ../../po/../src/splivarot.cpp:748 +#, fuzzy +msgid "No stroked paths to outline in the selection." +msgstr "No hay grupos para reducir/ampliar en la selección." + +#: ../../po/../src/splivarot.cpp:832 +#, fuzzy +msgid "Selected object is not a path, cannot inset/outset." +msgstr "El objeto seleccionado no es un trazo, no se puede reducir/ampliar." + +#: ../../po/../src/splivarot.cpp:1040 +#, fuzzy +msgid "Select path(s) to inset/outset." +msgstr "Seleccione trazos para reducir/ampliar." + +#: ../../po/../src/splivarot.cpp:1257 +#, fuzzy +msgid "No paths to inset/outset in the selection." +msgstr "No hay grupos para reducir/ampliar en la selección." + +#: ../../po/../src/splivarot.cpp:1390 +#, fuzzy +msgid "Select path(s) to simplify." +msgstr "Seleccione objetos para simplificar." + +#: ../../po/../src/splivarot.cpp:1417 +#, fuzzy +msgid "No paths to simplify in the selection." +msgstr "No hay grupos simplificables en la selección." + +#: ../../po/../src/star-context.cpp:362 +msgid "Ctrl: snap angle; keep rays radial" +msgstr "" + +#: ../../po/../src/star-context.cpp:470 +#, c-format +msgid "" +"Polygon: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/star-context.cpp:471 +#, c-format +msgid "Star: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/text-chemistry.cpp:90 +#, fuzzy +msgid "Select a text and a path to put text on path." +msgstr "" +"Debe seleccionar al menos dos trazos para realizar una operación booleana." + +#: ../../po/../src/text-chemistry.cpp:95 +msgid "" +"This text object is already put to a path. Remove it from the path " +"first. Use Shift+D to look up its path." +msgstr "" + +#. rect is the only SPShape which is not yet, and thus SVG forbids us from putting text on it +#: ../../po/../src/text-chemistry.cpp:101 +msgid "" +"You cannot put text on a rectangle in this version. Convert rectangle to " +"path first." +msgstr "" + +#: ../../po/../src/text-chemistry.cpp:159 +#, fuzzy +msgid "Select a text on path to remove it from path." +msgstr "" +"Debe seleccionar al menos dos trazos para realizar una operación booleana." + +#: ../../po/../src/text-chemistry.cpp:181 +#, fuzzy +msgid "No texts-on-paths in the selection." +msgstr "No hay grupos descombinables en la selección." + +#: ../../po/../src/text-chemistry.cpp:209 +#: ../../po/../src/text-chemistry.cpp:229 +#, fuzzy +msgid "Select text(s) to remove kerns from." +msgstr "Seleccione dos o más objetos para agrupar." + +#: ../../po/../src/text-chemistry.cpp:250 +#, fuzzy +msgid "" +"Select a text and one or more paths or shapes to flow text " +"into frame." +msgstr "" +"Debe seleccionar al menos dos trazos para realizar una operación booleana." + +#: ../../po/../src/text-chemistry.cpp:322 +#, fuzzy +msgid "Select a flowed text to unflow it." +msgstr "Seleccione trazos para reducir/ampliar." + +#: ../../po/../src/text-context.cpp:463 +#, fuzzy +msgid "Click to edit the text, drag to select part of the text." +msgstr "Haga clic para seleccionar o crear un objeto de texto, luego escriba." + +#: ../../po/../src/text-context.cpp:465 +#, fuzzy +msgid "" +"Click to edit the flowed text, drag to select part of the text." +msgstr "Haga clic para seleccionar o crear un objeto de texto, luego escriba." + +#: ../../po/../src/text-context.cpp:540 +msgid "Non-printable character" +msgstr "" + +#: ../../po/../src/text-context.cpp:589 +#, c-format +msgid "Unicode: %s: %s" +msgstr "" + +#: ../../po/../src/text-context.cpp:591 ../../po/../src/text-context.cpp:855 +msgid "Unicode: " +msgstr "" + +#: ../../po/../src/text-context.cpp:615 +msgid "Current layer is hidden. Unhide it to be able to add text." +msgstr "" + +#: ../../po/../src/text-context.cpp:619 +msgid "Current layer is locked. Unlock it to be able to add text." +msgstr "" + +#: ../../po/../src/text-context.cpp:673 +#, c-format +msgid "Flowed text frame: %s × %s" +msgstr "" + +#: ../../po/../src/text-context.cpp:708 ../../po/../src/text-context.cpp:1464 +msgid "Type text; Enter to start new line." +msgstr "" + +#: ../../po/../src/text-context.cpp:719 +msgid "Flowed text is created." +msgstr "" + +#: ../../po/../src/text-context.cpp:722 +msgid "" +"The frame is too small for the current font size. Flowed text not " +"created." +msgstr "" + +#: ../../po/../src/text-context.cpp:841 +msgid "No-break space" +msgstr "" + +#: ../../po/../src/text-context.cpp:1462 +msgid "Type flowed text; Enter to start new paragraph." +msgstr "" + +#: ../../po/../src/text-context.cpp:1472 ../../po/../src/tools-switch.cpp:189 +#, fuzzy +msgid "" +"Click to select or create text, drag to create flowed text; " +"then type." +msgstr "Haga clic para seleccionar o crear un objeto de texto, luego escriba." + +#: ../../po/../src/tools-switch.cpp:141 +#, fuzzy +msgid "" +"To edit a path, click, Shift+click, or drag around " +"nodes to select them, then drag nodes and handles. Click on an " +"object to select." +msgstr "" +"Para editar un trazo haga clic, Mayús+clic o arrastre alrededor de los nodos " +"para seleccionarlos. Para editar una forma, arrastre sus nodos." + +#: ../../po/../src/tools-switch.cpp:147 +#, fuzzy +msgid "" +"Drag to create a rectangle. Drag controls to round corners and " +"resize. Click to select." +msgstr "" +"Arrastre para crear un rectángulo. Utilice la herramienta de nodos para " +"redondear las esquinas." + +#: ../../po/../src/tools-switch.cpp:153 +#, fuzzy +msgid "" +"Drag to create an ellipse. Drag controls to make an arc or " +"segment. Click to select." +msgstr "" +"Arrastre para crear una elipse. Utilice la herramienta de nodos para crear " +"un arco o un segmento." + +#: ../../po/../src/tools-switch.cpp:159 +#, fuzzy +msgid "" +"Drag to create a star. Drag controls to edit the star shape. " +"Click to select." +msgstr "" +"Arrastre para crear una estrella. Utilice la herramienta de nodos para " +"editar la forma de la estrella." + +#: ../../po/../src/tools-switch.cpp:165 +#, fuzzy +msgid "" +"Drag to create a spiral. Drag controls to edit the spiral " +"shape. Click to select." +msgstr "" +"Arrastre para crear una espiral. Utilice la herramienta de nodos para editar " +"la forma de la espiral." + +#: ../../po/../src/tools-switch.cpp:171 +#, fuzzy +msgid "" +"Drag to create a freehand line. Start drawing with Shift to " +"append to selected path." +msgstr "" +"Arrastre para crear una línea a mano alzada. Presione 'a' para conmutar " +"Añadir/Nuevo." + +#: ../../po/../src/tools-switch.cpp:177 +#, fuzzy +msgid "" +"Click or click and drag to start a path; with Shift to " +"append to selected path." +msgstr "" +"Haga click para crear un nodo, arrastre para crear un nodo suave. Presione " +"'a' para conmutar Añadir/Nuevo." + +#: ../../po/../src/tools-switch.cpp:183 +msgid "" +"Drag to paint a calligraphic stroke. Left/right arrow " +"keys adjust width, up/down adjust angle." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:195 +#, fuzzy +msgid "" +"Drag or double click to create a gradient on selected objects, " +"drag handles to adjust gradients." +msgstr "" +"Arrastre para crear una línea a mano alzada. Presione 'a' para conmutar " +"Añadir/Nuevo." + +#: ../../po/../src/tools-switch.cpp:201 +#, fuzzy +msgid "" +"Click or drag around an area to zoom in, Shift+click to " +"zoom out." +msgstr "" +"Haga clic para acercar, Mayús+clic para alejar, arrastre en un área para " +"acercar." + +#: ../../po/../src/tools-switch.cpp:213 +msgid "Click and drag between shapes to create a connector." +msgstr "" + +#: ../../po/../src/trace/potrace/inkscape-potrace.cpp:553 +#: ../../po/../src/trace/potrace/inkscape-potrace.cpp:654 +#, c-format +msgid "Trace: %d. %ld nodes" +msgstr "" + +#: ../../po/../src/trace/trace.cpp:53 ../../po/../src/trace/trace.cpp:62 +#: ../../po/../src/trace/trace.cpp:70 +#, fuzzy +msgid "Select an image to trace" +msgstr "Seleccione objetos para bajar." + +#: ../../po/../src/trace/trace.cpp:133 +#, fuzzy +msgid "Trace: No active document" +msgstr "Crear un documento nuevo" + +#: ../../po/../src/trace/trace.cpp:154 +msgid "Trace: Image has no bitmap data" +msgstr "" + +#: ../../po/../src/trace/trace.cpp:267 +#, fuzzy, c-format +msgid "Trace: Done. %ld nodes created" +msgstr "Último seleccionado" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:59 ../../po/../src/verbs.cpp:2212 +msgid "About Inkscape" +msgstr "Acerca de Inkscape" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:66 +msgid "_Splash" +msgstr "" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:68 +msgid "_Authors" +msgstr "" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:69 +#, fuzzy +msgid "_Translators" +msgstr "Transfor_mar" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:70 +#, fuzzy +msgid "_License" +msgstr "Re_ducir" + +#. TRANSLATORS: This is the filename of the `About Inkscape' picture in +#. the `screens' directory. Thus the translation of "about.svg" should be +#. the filename of its translated version, e.g. about.zh.svg for Chinese. +#. +#. N.B. about.svg changes once per release. (We should probably rename +#. the original to about-0.40.svg etc. as soon as we have a translation. +#. If we do so, then add an item to release-checklist saying that the +#. string here should be changed.) +#. FIXME? INKSCAPE_SCREENSDIR and "about.svg" are in UTF-8, not the +#. native filename encoding... and the filename passed to sp_document_new +#. should be in UTF-*8.. +#: ../../po/../src/ui/dialog/aboutbox.cpp:114 +msgid "about.svg" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:464 +msgid "Minimum horizontal gap (in px units) between bounding boxes" +msgstr "" + +#. TRANSLATORS: Horizontal gap +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:466 +#: ../../po/../src/widgets/toolbox.cpp:1556 +msgid "H:" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:474 +msgid "Minimum vertical gap (in px units) between bounding boxes" +msgstr "" + +#. TRANSLATORS: Vertical gap +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:476 +msgid "V:" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:734 +msgid "Align" +msgstr "Alinear" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:735 +msgid "Distribute" +msgstr "Distribuir" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:736 +msgid "Remove overlaps" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:737 +#, fuzzy +msgid "Nodes" +msgstr "Ninguno" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:742 +#, fuzzy +msgid "Relative to: " +msgstr "Movimiento relativo" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:747 +#, fuzzy +msgid "Align right sides of objects to left side of anchor" +msgstr "Lado derecho de los objetos alineados a la izquierda del ancla" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:750 +#, fuzzy +msgid "Align left sides" +msgstr "Alinear" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:753 +#, fuzzy +msgid "Center on vertical axis" +msgstr "Centrar verticalmente" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:756 +#, fuzzy +msgid "Align right sides" +msgstr "Alinear" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:759 +#, fuzzy +msgid "Align left sides of objects to right side of anchor" +msgstr "Lado izquierdo de los objetos alineados a la derecha del ancla" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:762 +#, fuzzy +msgid "Align bottoms of objects to top of anchor" +msgstr "Lado inferior de los objetos alineados por encima del ancla" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:765 +#, fuzzy +msgid "Align tops" +msgstr "Alinear" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:768 +#, fuzzy +msgid "Center on horizontal axis" +msgstr "Centrar horizontalmente" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:771 +#, fuzzy +msgid "Align bottoms" +msgstr "Alinear" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:774 +#, fuzzy +msgid "Align tops of objects to bottom of anchor" +msgstr "Lado superior de los objetos alineados al fondo del ancla" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:779 +#, fuzzy +msgid "Align baseline anchors of texts vertically" +msgstr "Reflejar los objetos seleccionados verticalmente" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:782 +#, fuzzy +msgid "Align baseline anchors of texts horizontally" +msgstr "Reflejar los objetos seleccionados horizontalmente" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:787 +#, fuzzy +msgid "Make horizontal gaps between objects equal" +msgstr "Distribuir la distancia horizontal entre los objetos igualmente" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:791 +#, fuzzy +msgid "Distribute left sides equidistantly" +msgstr "Distribuir el lado izquierdo de los objetos a distancias equivalentes" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:794 +#, fuzzy +msgid "Distribute centers equidistantly horizontally" +msgstr "" +"Distribuir el centro de los objetos a distancias horizontales equivalentes" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:797 +#, fuzzy +msgid "Distribute right sides equidistantly" +msgstr "Distribuir los lados derechos de los objetos a distancias equivalentes" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:801 +#, fuzzy +msgid "Make vertical gaps between objects equal" +msgstr "Distribuir la distancia vertical entre los objetos igualmente" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:805 +#, fuzzy +msgid "Distribute tops equidistantly" +msgstr "" +"Distribuir los centros de los objetos a distancias iguales verticalmente" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:808 +#, fuzzy +msgid "Distribute centers equidistantly vertically" +msgstr "" +"Distribuir los centros de los objetos a distancias iguales verticalmente" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:811 +#, fuzzy +msgid "Distribute bottoms equidistantly" +msgstr "Distribuir los lados inferiores de los objetos a la misma distancia" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:816 +#, fuzzy +msgid "Distribute baseline anchors of texts horizontally" +msgstr "Reflejar los objetos seleccionados horizontalmente" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:819 +#, fuzzy +msgid "Distribute baseline anchors of texts vertically" +msgstr "" +"Distribuir los centros de los objetos a distancias iguales verticalmente" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:824 +msgid "Randomize centers in both dimensions" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:827 +msgid "Unclump objects: try to equalize edge-to-edge distances" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:832 +msgid "" +"Move objects as little as possible so that their bounding boxes do not " +"overlap" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:837 +#, fuzzy +msgid "Align selected nodes horizontally" +msgstr "Reflejar los objetos seleccionados horizontalmente" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:840 +#, fuzzy +msgid "Align selected nodes vertically" +msgstr "Reflejar los objetos seleccionados verticalmente" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:843 +#, fuzzy +msgid "Distribute selected nodes horizontally" +msgstr "Reflejar los objetos seleccionados horizontalmente" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:846 +#, fuzzy +msgid "Distribute selected nodes vertically" +msgstr "" +"Distribuir los centros de los objetos a distancias iguales verticalmente" + +#. Rest of the widgetry +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:851 +msgid "Last selected" +msgstr "Último seleccionado" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:852 +msgid "First selected" +msgstr "Primero seleccionado" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:853 +msgid "Biggest item" +msgstr "Elemento mayor" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:854 +msgid "Smallest item" +msgstr "Elemento menor" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:856 +#: ../../po/../src/widgets/desktop-widget.cpp:1065 +msgid "Drawing" +msgstr "Dibujo" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:91 +msgid "Metadata 1" +msgstr "" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:92 +msgid "Metadata 2" +msgstr "" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:187 +#, fuzzy +msgid "X coordinate of grid origin" +msgstr "Coordenada vertical de la selección" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:189 +#, fuzzy +msgid "Y coordinate of grid origin" +msgstr "Coordenada vertical de la selección" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:191 +#, fuzzy +msgid "Distance of vertical grid lines" +msgstr "guía vertical" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:193 +#, fuzzy +msgid "Distance of horizontal grid lines" +msgstr "guía horizontal" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:197 +msgid "Max. snapping distance from grid" +msgstr "" + +#: ../../po/../src/ui/dialog/export.cpp:34 +msgid "Export" +msgstr "Exportar" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:36 +msgid "Fill" +msgstr "Relleno" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:37 +#, fuzzy +msgid "Stroke Paint" +msgstr "Contorno" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:38 +#, fuzzy +msgid "Stroke Style" +msgstr "Estilo de contorno" + +#: ../../po/../src/ui/dialog/find.cpp:34 +#, fuzzy +msgid "Find" +msgstr "Rejilla" + +#: ../../po/../src/ui/dialog/memory.cpp:96 +#, fuzzy +msgid "Heap" +msgstr "A_yuda" + +#: ../../po/../src/ui/dialog/memory.cpp:97 +#, fuzzy +msgid "In Use" +msgstr "Re_ducir" + +#. TRANSLATORS: "Slack" refers to memory which is in the heap but currently unused. +#. More typical usage is to call this memory "free" rather than "slack". +#: ../../po/../src/ui/dialog/memory.cpp:100 +#, fuzzy +msgid "Slack" +msgstr "Estrella" + +#: ../../po/../src/ui/dialog/memory.cpp:101 +#, fuzzy +msgid "Total" +msgstr "Título:" + +#: ../../po/../src/ui/dialog/memory.cpp:141 +#: ../../po/../src/ui/dialog/memory.cpp:147 +#: ../../po/../src/ui/dialog/memory.cpp:154 +#: ../../po/../src/ui/dialog/memory.cpp:186 +msgid "Unknown" +msgstr "Desconocido" + +#: ../../po/../src/ui/dialog/memory.cpp:167 +#, fuzzy +msgid "Combined" +msgstr "_Combinar" + +#: ../../po/../src/ui/dialog/memory.cpp:209 +#, fuzzy +msgid "Recalculate" +msgstr "Rectángulo" + +#: ../../po/../src/ui/dialog/messages.cpp:74 +#, fuzzy +msgid "Ready." +msgstr "Rojo:" + +#: ../../po/../src/ui/dialog/messages.cpp:75 +msgid "" +"Enable log display by setting dialogs.debug 'redirect' attribute to 1 in " +"preferences.xml" +msgstr "" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:184 +msgid "_Execute Python" +msgstr "" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:186 +msgid "_Execute Perl" +msgstr "" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:195 +msgid "Script" +msgstr "" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:205 +#, fuzzy +msgid "Output" +msgstr "A_mpliar" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:215 +msgid "Errors" +msgstr "" + +#. Dialog organization +#: ../../po/../src/ui/dialog/session-player.cpp:73 +msgid "Session file" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:74 +#, fuzzy +msgid "Playback controls" +msgstr "Opciones de la herramienta" + +#: ../../po/../src/ui/dialog/session-player.cpp:75 +#, fuzzy +msgid "Message information" +msgstr "Reiniciar _transformación" + +#. Active session file display +#. fixme: Does this mean the active file for the session, or the file for the active session? +#. Please indicate which with a TRANSLATORS comment. +#: ../../po/../src/ui/dialog/session-player.cpp:85 +msgid "Active session file:" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:86 +msgid "Delay (milliseconds):" +msgstr "" + +#. Unload/load buttons +#: ../../po/../src/ui/dialog/session-player.cpp:94 +#, fuzzy +msgid "Close file" +msgstr "Cerrar" + +#: ../../po/../src/ui/dialog/session-player.cpp:95 +msgid "Open new file" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:96 +#, fuzzy +msgid "Set delay" +msgstr "Definir como predeterminado" + +#: ../../po/../src/ui/dialog/session-player.cpp:138 +#, fuzzy +msgid "Rewind" +msgstr "Rojo:" + +#: ../../po/../src/ui/dialog/session-player.cpp:139 +msgid "Go back one change" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:140 +#, fuzzy +msgid "Pause" +msgstr "_Pegar" + +#: ../../po/../src/ui/dialog/session-player.cpp:141 +msgid "Go forward one change" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:142 +msgid "Play" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:177 +#: ../../po/../src/verbs.cpp:1573 +msgid "Open session file" +msgstr "" + +#. ##Set up the Potrace panel +#. #### brightness #### +#. #### Multiple scanning#### +#. ----Hbox1 +#: ../../po/../src/ui/dialog/tracedialog.cpp:345 +#: ../../po/../src/ui/dialog/tracedialog.cpp:428 +#, fuzzy +msgid "Brightness" +msgstr "Alto:" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:348 +msgid "Trace by a given brightness level" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:355 +msgid "Brightness cutoff for black/white" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:362 +#, fuzzy +msgid "Image Brightness" +msgstr "_Propiedades de la imagen" + +#. #### canny edge detection #### +#. TRANSLATORS: "Canny" is the name of the inventor of this edge detection method +#: ../../po/../src/ui/dialog/tracedialog.cpp:369 +msgid "Optimal Edge Detection (Canny)" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:372 +msgid "Trace with edge detection by J. Canny's algorithm" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:388 +msgid "Brightness cutoff for adjacent pixels (determines edge thickness)" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:395 +#, fuzzy +msgid "Edge Detection" +msgstr "Selección" + +#. #### quantization #### +#. TRANSLATORS: Color Quantization: the process of reducing the number of colors +#. in an image by selecting an optimized set of representative colors and then +#. re-applying this reduced set to the original image. +#: ../../po/../src/ui/dialog/tracedialog.cpp:404 +#, fuzzy +msgid "Color Quantization" +msgstr "Color de la pintura" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:407 +msgid "Trace along the boundaries of reduced colors" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:414 +#, fuzzy +msgid "The number of reduced colors" +msgstr "Número de revoluciones" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:416 +#, fuzzy +msgid "Colors:" +msgstr "Cerrar" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:421 +msgid "Quantization / Reduction" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:431 +msgid "Trace the given number of brightness levels" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:438 +#, fuzzy +msgid "Scans:" +msgstr "Agudeza:" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:440 +msgid "The desired number of scans" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:448 +msgid "Trace the given number of reduced colors" +msgstr "" + +#. ---Hbox3 +#: ../../po/../src/ui/dialog/tracedialog.cpp:454 +msgid "Monochrome" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:457 +msgid "Same as Color, but convert result to grayscale" +msgstr "" + +#. TRANSLATORS: "Stack" is a verb here +#: ../../po/../src/ui/dialog/tracedialog.cpp:460 +#, fuzzy +msgid "Stack" +msgstr "Estrella" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:463 +msgid "" +"Stack scans vertically (no gaps) or tile horizontally (usually with gaps)" +msgstr "" + +#. TRANSLATORS: "Smooth" is a verb here +#: ../../po/../src/ui/dialog/tracedialog.cpp:466 +#, fuzzy +msgid "Smooth" +msgstr "suave" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:469 +msgid "Apply Gaussian blur to the bitmap before tracing" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:473 +msgid "Multiple Scanning" +msgstr "" + +#. #### Preview #### +#: ../../po/../src/ui/dialog/tracedialog.cpp:479 +#: ../../po/../src/ui/dialog/tracedialog.cpp:489 +#, fuzzy +msgid "Preview" +msgstr "_Nueva vista" + +#. do not expand +#: ../../po/../src/ui/dialog/tracedialog.cpp:483 +msgid "Preview the result without actual tracing" +msgstr "" + +#. #### swap black and white #### +#: ../../po/../src/ui/dialog/tracedialog.cpp:495 +#, fuzzy +msgid "Invert" +msgstr "Re_ducir" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:499 +msgid "Invert black and white regions for single traces" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:503 +msgid "Thanks to Peter Selinger, http://potrace.sourceforge.net" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:506 +#, fuzzy +msgid "Credits" +msgstr "Coordenadas del cursor" + +#. done +#. TRANSLATORS: Potrace is an application for transforming bitmaps into +#. vector graphics (http://potrace.sourceforge.net/) +#: ../../po/../src/ui/dialog/tracedialog.cpp:514 +#, fuzzy +msgid "Potrace" +msgstr "Traza" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:527 +#, fuzzy +msgid "Abort a trace in progress" +msgstr "Realizando exportación..." + +#: ../../po/../src/ui/dialog/tracedialog.cpp:531 +msgid "Execute the trace" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:80 +#: ../../po/../src/ui/dialog/transformation.cpp:90 +#, fuzzy +msgid "_Horizontal" +msgstr "Líneas horizontales" + +#: ../../po/../src/ui/dialog/transformation.cpp:80 +msgid "Horizontal displacement (relative) or position (absolute)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:82 +#: ../../po/../src/ui/dialog/transformation.cpp:92 +#, fuzzy +msgid "_Vertical" +msgstr "Líneas verticales" + +#: ../../po/../src/ui/dialog/transformation.cpp:82 +msgid "Vertical displacement (relative) or position (absolute)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:84 +#, fuzzy +msgid "_Width" +msgstr "Ancho:" + +#: ../../po/../src/ui/dialog/transformation.cpp:84 +msgid "Horizontal size increment (absolute or percentage)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:86 +#, fuzzy +msgid "_Height" +msgstr "Alto:" + +#: ../../po/../src/ui/dialog/transformation.cpp:86 +msgid "Vertical size increment (absolute or percentage)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:88 +#, fuzzy +msgid "A_ngle" +msgstr "Ángulo:" + +#: ../../po/../src/ui/dialog/transformation.cpp:88 +#, fuzzy +msgid "Rotation angle (positive = counterclockwise)" +msgstr "Rotar el objeto 90 grados a la izquierda" + +#: ../../po/../src/ui/dialog/transformation.cpp:90 +msgid "" +"Horizontal skew angle (positive = counterclockwise), or absolute " +"displacement, or percentage displacement" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:92 +msgid "" +"Vertical skew angle (positive = counterclockwise), or absolute displacement, " +"or percentage displacement" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:95 +#, fuzzy +msgid "Transformation matrix element A" +msgstr "Matriz de transformación" + +#: ../../po/../src/ui/dialog/transformation.cpp:96 +#, fuzzy +msgid "Transformation matrix element B" +msgstr "Matriz de transformación" + +#: ../../po/../src/ui/dialog/transformation.cpp:97 +#, fuzzy +msgid "Transformation matrix element C" +msgstr "Matriz de transformación" + +#: ../../po/../src/ui/dialog/transformation.cpp:98 +#, fuzzy +msgid "Transformation matrix element D" +msgstr "Matriz de transformación" + +#: ../../po/../src/ui/dialog/transformation.cpp:99 +#, fuzzy +msgid "Transformation matrix element E" +msgstr "Matriz de transformación" + +#: ../../po/../src/ui/dialog/transformation.cpp:100 +#, fuzzy +msgid "Transformation matrix element F" +msgstr "Matriz de transformación" + +#: ../../po/../src/ui/dialog/transformation.cpp:102 +#, fuzzy +msgid "Rela_tive move" +msgstr "Movimiento relativo" + +#: ../../po/../src/ui/dialog/transformation.cpp:102 +msgid "" +"Add the specified relative displacement to the current position; otherwise, " +"edit the current absolute position directly" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:103 +msgid "Scale proportionally" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:103 +msgid "Preserve the width/height ratio of the scaled objects" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:104 +msgid "Apply to each _object separately" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:104 +msgid "" +"Apply the scale/rotate/skew to each selected object separately; otherwise, " +"transform the selection as a whole" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:105 +msgid "Edit c_urrent matrix" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:105 +msgid "" +"Edit the current transform= matrix; otherwise, post-multiply transform= by " +"this matrix" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:115 +#, fuzzy +msgid "_Move" +msgstr "Mover" + +#: ../../po/../src/ui/dialog/transformation.cpp:118 +#, fuzzy +msgid "_Scale" +msgstr "Escalar" + +#: ../../po/../src/ui/dialog/transformation.cpp:121 +#, fuzzy +msgid "_Rotate" +msgstr "Girar" + +#: ../../po/../src/ui/dialog/transformation.cpp:124 +#, fuzzy +msgid "Ske_w" +msgstr "Contorno" + +#: ../../po/../src/ui/dialog/transformation.cpp:127 +msgid "Matri_x" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:141 +#, fuzzy +msgid "Reset the values on the current tab to defaults" +msgstr "Ajustar la herramienta a opciones predeterminadas" + +#: ../../po/../src/ui/dialog/transformation.cpp:148 +#, fuzzy +msgid "Apply transformation to selection" +msgstr "Seleccionar y transformar objetos (F1)" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:43 +msgid "_Use SSL" +msgstr "" + +#. Construct dialog interface +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:68 +#, fuzzy +msgid "_Server:" +msgstr "Reglas" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:69 +#, fuzzy +msgid "_Username:" +msgstr "Nombre de archivo" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:70 +msgid "_Password:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:71 +msgid "P_ort:" +msgstr "" + +#. Buttons +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:99 +#, fuzzy +msgid "Connect" +msgstr "Cerrar" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:126 +msgid "Establishing connection to Jabber server %1 as user %2" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:131 +msgid "Failed to establish connection to Jabber server %1" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:136 +msgid "Authentication failed on Jabber server %1 as %2" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:141 +msgid "SSL initialization failed when connecting to Jabber server %1" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:147 +msgid "Connected to Jabber server %1 as %2" +msgstr "" + +#. Construct labels +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:75 +msgid "Chatroom _name:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:76 +msgid "Chatroom _server:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:77 +msgid "Chatroom _password:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:78 +msgid "Chatroom _handle:" +msgstr "" + +#. Button setup and callback registration +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:97 +msgid "Connect to chatroom" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:132 +msgid "Synchronizing with chatroom %1@%2 using the handle %3" +msgstr "" + +#. Construct dialog interface +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:78 +msgid "_User's Jabber ID:" +msgstr "" + +#. Buttons +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:82 +msgid "_Invite user" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:83 +#, fuzzy +msgid "_Cancel" +msgstr "Cancelar" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:94 +msgid "Buddy List" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:170 +msgid "Sending whiteboard invitation to %1" +msgstr "" + +#. FIXME: strings are replaced by placeholders, NOT to be translated until the code is enabled +#. See http://sourceforge.net/mailarchive/message.php?msg_id=11746016 for details +#. File menu +#. Edit menu +#. View menu +#. Layer menu +#. Object menu +#. Path menu +#. add(Gtk::StockItem(CLEANUP, _("PLACEHOLDER, do not translate"))); (using Gtk::Stock::CLEAR) +#. Text menu +#. About menu +#. Tools toolbox +#. Select Tool controls +#. Node Tool controls +#. Calligraphy Tool controls +#. Session playback controls +#: ../../po/../src/ui/stock-items.cpp:34 ../../po/../src/ui/stock-items.cpp:35 +#: ../../po/../src/ui/stock-items.cpp:36 ../../po/../src/ui/stock-items.cpp:37 +#: ../../po/../src/ui/stock-items.cpp:38 ../../po/../src/ui/stock-items.cpp:39 +#: ../../po/../src/ui/stock-items.cpp:40 ../../po/../src/ui/stock-items.cpp:41 +#: ../../po/../src/ui/stock-items.cpp:42 ../../po/../src/ui/stock-items.cpp:43 +#: ../../po/../src/ui/stock-items.cpp:46 ../../po/../src/ui/stock-items.cpp:47 +#: ../../po/../src/ui/stock-items.cpp:48 ../../po/../src/ui/stock-items.cpp:49 +#: ../../po/../src/ui/stock-items.cpp:50 ../../po/../src/ui/stock-items.cpp:51 +#: ../../po/../src/ui/stock-items.cpp:52 ../../po/../src/ui/stock-items.cpp:53 +#: ../../po/../src/ui/stock-items.cpp:54 ../../po/../src/ui/stock-items.cpp:55 +#: ../../po/../src/ui/stock-items.cpp:56 ../../po/../src/ui/stock-items.cpp:57 +#: ../../po/../src/ui/stock-items.cpp:58 ../../po/../src/ui/stock-items.cpp:59 +#: ../../po/../src/ui/stock-items.cpp:62 ../../po/../src/ui/stock-items.cpp:63 +#: ../../po/../src/ui/stock-items.cpp:64 ../../po/../src/ui/stock-items.cpp:65 +#: ../../po/../src/ui/stock-items.cpp:66 ../../po/../src/ui/stock-items.cpp:67 +#: ../../po/../src/ui/stock-items.cpp:68 ../../po/../src/ui/stock-items.cpp:69 +#: ../../po/../src/ui/stock-items.cpp:70 ../../po/../src/ui/stock-items.cpp:71 +#: ../../po/../src/ui/stock-items.cpp:72 ../../po/../src/ui/stock-items.cpp:73 +#: ../../po/../src/ui/stock-items.cpp:74 ../../po/../src/ui/stock-items.cpp:75 +#: ../../po/../src/ui/stock-items.cpp:76 ../../po/../src/ui/stock-items.cpp:77 +#: ../../po/../src/ui/stock-items.cpp:78 ../../po/../src/ui/stock-items.cpp:79 +#: ../../po/../src/ui/stock-items.cpp:80 ../../po/../src/ui/stock-items.cpp:81 +#: ../../po/../src/ui/stock-items.cpp:82 ../../po/../src/ui/stock-items.cpp:83 +#: ../../po/../src/ui/stock-items.cpp:84 ../../po/../src/ui/stock-items.cpp:85 +#: ../../po/../src/ui/stock-items.cpp:86 ../../po/../src/ui/stock-items.cpp:87 +#: ../../po/../src/ui/stock-items.cpp:88 ../../po/../src/ui/stock-items.cpp:89 +#: ../../po/../src/ui/stock-items.cpp:92 ../../po/../src/ui/stock-items.cpp:93 +#: ../../po/../src/ui/stock-items.cpp:94 ../../po/../src/ui/stock-items.cpp:95 +#: ../../po/../src/ui/stock-items.cpp:96 ../../po/../src/ui/stock-items.cpp:97 +#: ../../po/../src/ui/stock-items.cpp:98 ../../po/../src/ui/stock-items.cpp:99 +#: ../../po/../src/ui/stock-items.cpp:100 +#: ../../po/../src/ui/stock-items.cpp:101 +#: ../../po/../src/ui/stock-items.cpp:102 +#: ../../po/../src/ui/stock-items.cpp:103 +#: ../../po/../src/ui/stock-items.cpp:104 +#: ../../po/../src/ui/stock-items.cpp:105 +#: ../../po/../src/ui/stock-items.cpp:108 +#: ../../po/../src/ui/stock-items.cpp:109 +#: ../../po/../src/ui/stock-items.cpp:110 +#: ../../po/../src/ui/stock-items.cpp:111 +#: ../../po/../src/ui/stock-items.cpp:112 +#: ../../po/../src/ui/stock-items.cpp:113 +#: ../../po/../src/ui/stock-items.cpp:114 +#: ../../po/../src/ui/stock-items.cpp:115 +#: ../../po/../src/ui/stock-items.cpp:116 +#: ../../po/../src/ui/stock-items.cpp:117 +#: ../../po/../src/ui/stock-items.cpp:118 +#: ../../po/../src/ui/stock-items.cpp:119 +#: ../../po/../src/ui/stock-items.cpp:120 +#: ../../po/../src/ui/stock-items.cpp:121 +#: ../../po/../src/ui/stock-items.cpp:122 +#: ../../po/../src/ui/stock-items.cpp:123 +#: ../../po/../src/ui/stock-items.cpp:124 +#: ../../po/../src/ui/stock-items.cpp:125 +#: ../../po/../src/ui/stock-items.cpp:126 +#: ../../po/../src/ui/stock-items.cpp:127 +#: ../../po/../src/ui/stock-items.cpp:130 +#: ../../po/../src/ui/stock-items.cpp:131 +#: ../../po/../src/ui/stock-items.cpp:132 +#: ../../po/../src/ui/stock-items.cpp:133 +#: ../../po/../src/ui/stock-items.cpp:134 +#: ../../po/../src/ui/stock-items.cpp:135 +#: ../../po/../src/ui/stock-items.cpp:136 +#: ../../po/../src/ui/stock-items.cpp:137 +#: ../../po/../src/ui/stock-items.cpp:138 +#: ../../po/../src/ui/stock-items.cpp:139 +#: ../../po/../src/ui/stock-items.cpp:140 +#: ../../po/../src/ui/stock-items.cpp:141 +#: ../../po/../src/ui/stock-items.cpp:142 +#: ../../po/../src/ui/stock-items.cpp:143 +#: ../../po/../src/ui/stock-items.cpp:144 +#: ../../po/../src/ui/stock-items.cpp:145 +#: ../../po/../src/ui/stock-items.cpp:146 +#: ../../po/../src/ui/stock-items.cpp:150 +#: ../../po/../src/ui/stock-items.cpp:151 +#: ../../po/../src/ui/stock-items.cpp:152 +#: ../../po/../src/ui/stock-items.cpp:153 +#: ../../po/../src/ui/stock-items.cpp:156 +#: ../../po/../src/ui/stock-items.cpp:157 +#: ../../po/../src/ui/stock-items.cpp:158 +#: ../../po/../src/ui/stock-items.cpp:161 +#: ../../po/../src/ui/stock-items.cpp:162 +#: ../../po/../src/ui/stock-items.cpp:163 +#: ../../po/../src/ui/stock-items.cpp:164 +#: ../../po/../src/ui/stock-items.cpp:165 +#: ../../po/../src/ui/stock-items.cpp:166 +#: ../../po/../src/ui/stock-items.cpp:167 +#: ../../po/../src/ui/stock-items.cpp:168 +#: ../../po/../src/ui/stock-items.cpp:169 +#: ../../po/../src/ui/stock-items.cpp:170 +#: ../../po/../src/ui/stock-items.cpp:171 +#: ../../po/../src/ui/stock-items.cpp:172 +#: ../../po/../src/ui/stock-items.cpp:175 +#: ../../po/../src/ui/stock-items.cpp:176 +#: ../../po/../src/ui/stock-items.cpp:177 +#: ../../po/../src/ui/stock-items.cpp:178 +#: ../../po/../src/ui/stock-items.cpp:181 +#: ../../po/../src/ui/stock-items.cpp:182 +#: ../../po/../src/ui/stock-items.cpp:183 +#: ../../po/../src/ui/stock-items.cpp:184 +#: ../../po/../src/ui/stock-items.cpp:185 +#: ../../po/../src/ui/stock-items.cpp:186 +#: ../../po/../src/ui/stock-items.cpp:187 +#: ../../po/../src/ui/stock-items.cpp:188 +#: ../../po/../src/ui/stock-items.cpp:189 +#: ../../po/../src/ui/stock-items.cpp:190 +#: ../../po/../src/ui/stock-items.cpp:191 +#: ../../po/../src/ui/stock-items.cpp:194 +#: ../../po/../src/ui/stock-items.cpp:195 +#: ../../po/../src/ui/stock-items.cpp:198 +#: ../../po/../src/ui/stock-items.cpp:199 +#: ../../po/../src/ui/stock-items.cpp:200 +#: ../../po/../src/ui/stock-items.cpp:201 +#: ../../po/../src/ui/stock-items.cpp:202 +msgid "PLACEHOLDER, do not translate" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:88 +msgid "small" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:89 +msgid "medium" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:90 +#, fuzzy +msgid "large" +msgstr "Objetivo:" + +#: ../../po/../src/ui/widget/panel.cpp:91 +msgid "huge" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:106 +#, fuzzy +msgid "List" +msgstr "Re_ducir" + +#: ../../po/../src/ui/widget/selected-style.cpp:67 +msgid "F:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:68 +msgid "S:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:69 +msgid "O:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:95 +msgid "N/A" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:98 +#: ../../po/../src/ui/widget/selected-style.cpp:712 +#, fuzzy +msgid "Nothing selected" +msgstr "Suprimir los nodos seleccionados" + +#: ../../po/../src/ui/widget/selected-style.cpp:103 +msgid "No fill" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:103 +#, fuzzy +msgid "No stroke" +msgstr "Contorno" + +#: ../../po/../src/ui/widget/selected-style.cpp:105 +#: ../../po/../src/widgets/paint-selector.cpp:190 +#, fuzzy +msgid "Pattern" +msgstr "Patrón:" + +#: ../../po/../src/ui/widget/selected-style.cpp:108 +#: ../../po/../src/widgets/paint-selector.cpp:885 +#, fuzzy +msgid "Pattern fill" +msgstr "Patrón:" + +#: ../../po/../src/ui/widget/selected-style.cpp:108 +#, fuzzy +msgid "Pattern stroke" +msgstr "Patrón:" + +#: ../../po/../src/ui/widget/selected-style.cpp:110 +#, fuzzy +msgid "L Gradient" +msgstr "Editor de gradiente" + +#: ../../po/../src/ui/widget/selected-style.cpp:113 +#, fuzzy +msgid "Linear gradient fill" +msgstr "Gradiente lineal" + +#: ../../po/../src/ui/widget/selected-style.cpp:113 +#, fuzzy +msgid "Linear gradient stroke" +msgstr "Gradiente lineal" + +#: ../../po/../src/ui/widget/selected-style.cpp:115 +#, fuzzy +msgid "R Gradient" +msgstr "Editor de gradiente" + +#: ../../po/../src/ui/widget/selected-style.cpp:118 +#, fuzzy +msgid "Radial gradient fill" +msgstr "Gradiente radial" + +#: ../../po/../src/ui/widget/selected-style.cpp:118 +#, fuzzy +msgid "Radial gradient stroke" +msgstr "Gradiente radial" + +#: ../../po/../src/ui/widget/selected-style.cpp:120 +#, fuzzy +msgid "Different" +msgstr "_Diferencia" + +#: ../../po/../src/ui/widget/selected-style.cpp:123 +#, fuzzy +msgid "Different fills" +msgstr "_Diferencia" + +#: ../../po/../src/ui/widget/selected-style.cpp:123 +#, fuzzy +msgid "Different strokes" +msgstr "_Diferencia" + +#: ../../po/../src/ui/widget/selected-style.cpp:125 +#, fuzzy +msgid "Unset" +msgstr "Re_ducir" + +#. TRANSLATORS COMMENT: unset is a verb here +#: ../../po/../src/ui/widget/selected-style.cpp:128 +#: ../../po/../src/ui/widget/selected-style.cpp:182 +#, fuzzy +msgid "Unset fill" +msgstr "Sin título" + +#: ../../po/../src/ui/widget/selected-style.cpp:128 +#: ../../po/../src/ui/widget/selected-style.cpp:182 +msgid "Unset stroke" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:131 +#, fuzzy +msgid "Flat color fill" +msgstr "Color del resaltado:" + +#: ../../po/../src/ui/widget/selected-style.cpp:131 +#, fuzzy +msgid "Flat color stroke" +msgstr "Color del resaltado:" + +#. TRANSLATOR COMMENT: A means "Averaged" +#: ../../po/../src/ui/widget/selected-style.cpp:134 +msgid "A" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:137 +#, fuzzy +msgid "Fill is averaged over selected objects" +msgstr "OR exclusivo de objetos seleccionados" + +#: ../../po/../src/ui/widget/selected-style.cpp:137 +#, fuzzy +msgid "Stroke is averaged over selected objects" +msgstr "Intersección de objetos seleccionados" + +#. TRANSLATOR COMMENT: M means "Multiple" +#: ../../po/../src/ui/widget/selected-style.cpp:140 +msgid "M" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:143 +#, fuzzy +msgid "Multiple selected objects have the same fill" +msgstr "Reflejar los objetos seleccionados verticalmente" + +#: ../../po/../src/ui/widget/selected-style.cpp:143 +#, fuzzy +msgid "Multiple selected objects have the same stroke" +msgstr "Reflejar los objetos seleccionados verticalmente" + +#: ../../po/../src/ui/widget/selected-style.cpp:145 +#, fuzzy +msgid "Edit fill..." +msgstr "Editar" + +#: ../../po/../src/ui/widget/selected-style.cpp:145 +#, fuzzy +msgid "Edit stroke..." +msgstr "Editar" + +#: ../../po/../src/ui/widget/selected-style.cpp:149 +#, fuzzy +msgid "Last set color" +msgstr "Color del resaltado:" + +#: ../../po/../src/ui/widget/selected-style.cpp:153 +#, fuzzy +msgid "Last selected color" +msgstr "Último seleccionado" + +#: ../../po/../src/ui/widget/selected-style.cpp:157 +msgid "White" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:161 +#: ../../po/../src/widgets/sp-color-scales.cpp:461 +#: ../../po/../src/widgets/sp-color-scales.cpp:462 +#, fuzzy +msgid "Black" +msgstr "Negro:" + +#: ../../po/../src/ui/widget/selected-style.cpp:165 +#, fuzzy +msgid "Copy color" +msgstr "Color de parada" + +#: ../../po/../src/ui/widget/selected-style.cpp:169 +#, fuzzy +msgid "Paste color" +msgstr "Color del resaltado:" + +#: ../../po/../src/ui/widget/selected-style.cpp:173 +#, fuzzy +msgid "Swap fill and stroke" +msgstr "_Relleno y contorno" + +#: ../../po/../src/ui/widget/selected-style.cpp:177 +msgid "Make fill opaque" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:177 +msgid "Make stroke opaque" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:186 +#, fuzzy +msgid "Remove fill" +msgstr "_Eliminar enlace" + +#: ../../po/../src/ui/widget/selected-style.cpp:186 +#, fuzzy +msgid "Remove stroke" +msgstr "_Eliminar enlace" + +#: ../../po/../src/ui/widget/selected-style.cpp:718 +#, fuzzy +msgid "Master opacity" +msgstr "Opacidad:" + +#: ../../po/../src/ui/widget/selected-style.cpp:744 +msgid "0 (transparent)" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:768 +msgid "1.0 (opaque)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1046 +msgid "Moved to next layer." +msgstr "" + +#: ../../po/../src/verbs.cpp:1048 +msgid "Cannot move past last layer." +msgstr "" + +#: ../../po/../src/verbs.cpp:1057 +#, fuzzy +msgid "Moved to previous layer." +msgstr "Cambiar a la ventana de documento anterior" + +#: ../../po/../src/verbs.cpp:1059 +msgid "Cannot move past first layer." +msgstr "" + +#: ../../po/../src/verbs.cpp:1076 ../../po/../src/verbs.cpp:1150 +#, fuzzy +msgid "No current layer." +msgstr "Documento guardado." + +#: ../../po/../src/verbs.cpp:1105 +#, fuzzy, c-format +msgid "Raised layer %s." +msgstr "Elevar nodo" + +#: ../../po/../src/verbs.cpp:1109 +#, fuzzy, c-format +msgid "Lowered layer %s." +msgstr "Seleccionar" + +#: ../../po/../src/verbs.cpp:1118 +msgid "Cannot move layer any further." +msgstr "" + +#. TRANSLATORS: this means "The layer has been deleted." +#: ../../po/../src/verbs.cpp:1148 +#, fuzzy +msgid "Deleted layer." +msgstr "Seleccionar" + +#: ../../po/../src/verbs.cpp:1544 +msgid "" +"You need to connect to a Jabber server before sharing a document with " +"another user." +msgstr "" + +#: ../../po/../src/verbs.cpp:1559 +msgid "" +"You need to connect to a Jabber server before sharing a document with a " +"chatroom." +msgstr "" + +#: ../../po/../src/verbs.cpp:1569 +msgid "XML node tracker has not been initialized; nothing to dump" +msgstr "" + +#. TRANSLATORS: If you have translated the keys.svg file to your language, then +#. translate this string as "keys.LANG.svg" (where LANG is your language code); +#. otherwise leave as "keys.svg". +#: ../../po/../src/verbs.cpp:1631 +msgid "keys.svg" +msgstr "keys.svg" + +#. TRANSLATORS: If you have translated the tutorial-basic.svg file to your language, +#. then translate this string as "tutorial-basic.LANG.svg" (where LANG is your language +#. code); otherwise leave as "tutorial-basic.svg". +#: ../../po/../src/verbs.cpp:1667 +msgid "tutorial-basic.svg" +msgstr "tutorial-basic.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1671 +#, fuzzy +msgid "tutorial-shapes.svg" +msgstr "tutorial-basic.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1675 +#, fuzzy +msgid "tutorial-advanced.svg" +msgstr "tutorial-basic.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1679 +#, fuzzy +msgid "tutorial-tracing.svg" +msgstr "tutorial-basic.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1683 +#, fuzzy +msgid "tutorial-calligraphy.svg" +msgstr "tutorial-basic.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1687 +#, fuzzy +msgid "tutorial-elements.svg" +msgstr "tutorial-basic.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1691 +#, fuzzy +msgid "tutorial-tips.svg" +msgstr "tutorial-basic.svg" + +#: ../../po/../src/verbs.cpp:1842 +msgid "Does nothing" +msgstr "No hacer nada" + +#. File +#: ../../po/../src/verbs.cpp:1845 +#, fuzzy +msgid "Default" +msgstr "Predeterminados" + +#: ../../po/../src/verbs.cpp:1845 +#, fuzzy +msgid "Create new document from default template" +msgstr "Crear un documento nuevo" + +#: ../../po/../src/verbs.cpp:1847 +msgid "_Open..." +msgstr "_Abrir..." + +#: ../../po/../src/verbs.cpp:1848 +msgid "Open existing document" +msgstr "Abrir un documento existente" + +#: ../../po/../src/verbs.cpp:1849 +msgid "Re_vert" +msgstr "" + +#: ../../po/../src/verbs.cpp:1850 +msgid "Revert to the last saved version of document (changes will be lost)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1851 +msgid "_Save" +msgstr "_Guardar" + +#: ../../po/../src/verbs.cpp:1851 +msgid "Save document" +msgstr "Guardar documento" + +#: ../../po/../src/verbs.cpp:1853 +msgid "Save _As..." +msgstr "G_uardar como..." + +#: ../../po/../src/verbs.cpp:1854 +msgid "Save document under new name" +msgstr "Guardar documento con un nombre nuevo" + +#: ../../po/../src/verbs.cpp:1855 +msgid "_Print..." +msgstr "_Imprimir" + +#: ../../po/../src/verbs.cpp:1855 +msgid "Print document" +msgstr "Imprimir documento" + +#. TRANSLATORS: "Vacuum Defs" means "Clean up defs" (so as to remove unused definitions) +#: ../../po/../src/verbs.cpp:1858 +msgid "Vac_uum Defs" +msgstr "" + +#: ../../po/../src/verbs.cpp:1858 +msgid "Remove unused predefined items from the <defs> of the document" +msgstr "" + +#: ../../po/../src/verbs.cpp:1860 +msgid "Print _Direct" +msgstr "Impresión _directa" + +#: ../../po/../src/verbs.cpp:1861 +#, fuzzy +msgid "Print directly without prompting to a file or pipe" +msgstr "Imprimir directamente a un archivo o pipe" + +#: ../../po/../src/verbs.cpp:1862 +msgid "Print Previe_w" +msgstr "_Vista preliminar" + +#: ../../po/../src/verbs.cpp:1863 +msgid "Preview document printout" +msgstr "Vista preliminar de impresión" + +#: ../../po/../src/verbs.cpp:1864 +msgid "_Import..." +msgstr "_Importar..." + +#: ../../po/../src/verbs.cpp:1865 +msgid "Import bitmap or SVG image into document" +msgstr "Importar mapa de bits o imagen SVG al documento" + +#: ../../po/../src/verbs.cpp:1866 +msgid "_Export Bitmap..." +msgstr "_Exportar mapa de bits..." + +#: ../../po/../src/verbs.cpp:1867 +#, fuzzy +msgid "Export document or selection as a bitmap image" +msgstr "Exportar documento como mapa de bits PNG" + +#: ../../po/../src/verbs.cpp:1868 +#, fuzzy +msgid "N_ext Window" +msgstr "Ventana sigui_ente" + +#: ../../po/../src/verbs.cpp:1869 +msgid "Switch to the next document window" +msgstr "Cambiar a la ventana de documento siguiente" + +#: ../../po/../src/verbs.cpp:1870 +#, fuzzy +msgid "P_revious Window" +msgstr "Ventana anter_ior" + +#: ../../po/../src/verbs.cpp:1871 +msgid "Switch to the previous document window" +msgstr "Cambiar a la ventana de documento anterior" + +#: ../../po/../src/verbs.cpp:1872 +#, fuzzy +msgid "_Close" +msgstr "Cerrar" + +#: ../../po/../src/verbs.cpp:1873 +#, fuzzy +msgid "Close window" +msgstr "Cerrar vista" + +#: ../../po/../src/verbs.cpp:1874 +msgid "_Quit" +msgstr "_Salir" + +#: ../../po/../src/verbs.cpp:1874 +#, fuzzy +msgid "Quit Inkscape" +msgstr "Acerca de Inkscape" + +#. Edit +#: ../../po/../src/verbs.cpp:1877 +msgid "_Undo" +msgstr "_Deshacer" + +#: ../../po/../src/verbs.cpp:1877 +msgid "Undo last action" +msgstr "Deshacer la última acción" + +#: ../../po/../src/verbs.cpp:1879 +msgid "_Redo" +msgstr "_Rehacer" + +#: ../../po/../src/verbs.cpp:1880 +msgid "Do again last undone action" +msgstr "Rehacer la acción deshecha" + +#: ../../po/../src/verbs.cpp:1881 +msgid "Cu_t" +msgstr "Cor_tar" + +#: ../../po/../src/verbs.cpp:1882 +#, fuzzy +msgid "Cut selection to clipboard" +msgstr "Cortar los objetos seleccionados y llevarlos al portapapeles" + +#: ../../po/../src/verbs.cpp:1883 +msgid "_Copy" +msgstr "_Copiar" + +#: ../../po/../src/verbs.cpp:1884 +#, fuzzy +msgid "Copy selection to clipboard" +msgstr "Copiar los objetos seleccionados al portapapeles" + +#: ../../po/../src/verbs.cpp:1885 +msgid "_Paste" +msgstr "_Pegar" + +#: ../../po/../src/verbs.cpp:1886 +#, fuzzy +msgid "Paste objects from clipboard to mouse point" +msgstr "Pegar los objetos desde el portapapeles" + +#: ../../po/../src/verbs.cpp:1887 +msgid "Paste _Style" +msgstr "Pegar e_stilo" + +#: ../../po/../src/verbs.cpp:1888 +#, fuzzy +msgid "Apply style of the copied object to selection" +msgstr "Aplicar el estilo del objeto copiado a la selección" + +#: ../../po/../src/verbs.cpp:1889 +msgid "Paste _In Place" +msgstr "Pegar en el s_itio" + +#: ../../po/../src/verbs.cpp:1890 +#, fuzzy +msgid "Paste objects from clipboard to the original location" +msgstr "Pegar los objetos en el lugar original." + +#: ../../po/../src/verbs.cpp:1891 +msgid "_Delete" +msgstr "_Eliminar" + +#: ../../po/../src/verbs.cpp:1892 +#, fuzzy +msgid "Delete selection" +msgstr "Suprimir los nodos seleccionados" + +#: ../../po/../src/verbs.cpp:1893 +#, fuzzy +msgid "Duplic_ate" +msgstr "D_uplicar" + +#: ../../po/../src/verbs.cpp:1894 +#, fuzzy +msgid "Duplicate selected objects" +msgstr "Duplicar los objetos seleccionados" + +#: ../../po/../src/verbs.cpp:1895 +#, fuzzy +msgid "Clo_ne" +msgstr "Cerrar" + +#: ../../po/../src/verbs.cpp:1896 +#, fuzzy +msgid "Create a clone of selected object (a copy linked to the original)" +msgstr "Crear un objeto de offset dinámico enlazado al trazo original" + +#: ../../po/../src/verbs.cpp:1897 +msgid "Unlin_k Clone" +msgstr "" + +#: ../../po/../src/verbs.cpp:1898 +msgid "Cut the clone's link to its original" +msgstr "" + +#: ../../po/../src/verbs.cpp:1899 +#, fuzzy +msgid "Select _Original" +msgstr "Seleccion_ar todo" + +#: ../../po/../src/verbs.cpp:1900 +#, fuzzy +msgid "Select the object to which the clone is linked" +msgstr "Seleccione objetos para bajar." + +#. TRANSLATORS: Convert selection to a rectangle with tiled pattern fill +#: ../../po/../src/verbs.cpp:1902 +#, fuzzy +msgid "O_bjects to Pattern" +msgstr "_Objeto a trazo" + +#: ../../po/../src/verbs.cpp:1903 +msgid "Convert selection to a rectangle with tiled pattern fill" +msgstr "" + +#. TRANSLATORS: Extract objects from a tiled pattern fill +#: ../../po/../src/verbs.cpp:1905 +#, fuzzy +msgid "Pattern to Ob_jects" +msgstr "Patrón:" + +#: ../../po/../src/verbs.cpp:1906 +msgid "Extract objects from a tiled pattern fill" +msgstr "" + +#: ../../po/../src/verbs.cpp:1907 +msgid "Clea_r All" +msgstr "Limpia_r todo" + +#: ../../po/../src/verbs.cpp:1908 +msgid "Delete all objects from document" +msgstr "Borrar todos los objetos del documento" + +#: ../../po/../src/verbs.cpp:1909 +#, fuzzy +msgid "Select Al_l" +msgstr "Seleccion_ar todo" + +#: ../../po/../src/verbs.cpp:1910 +msgid "Select all objects or all nodes" +msgstr "Seleccionar todos los objetos o todos los nodos" + +#: ../../po/../src/verbs.cpp:1911 +#, fuzzy +msgid "Select All in All La_yers" +msgstr "Seleccionar" + +#: ../../po/../src/verbs.cpp:1912 +#, fuzzy +msgid "Select all objects in all visible and unlocked layers" +msgstr "Seleccionar todos los objetos o todos los nodos" + +#: ../../po/../src/verbs.cpp:1913 +#, fuzzy +msgid "In_vert Selection" +msgstr "Selección" + +#: ../../po/../src/verbs.cpp:1914 +msgid "Invert selection (unselect what is selected and select everything else)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1915 +msgid "Invert in All Layers" +msgstr "" + +#: ../../po/../src/verbs.cpp:1916 +msgid "Invert selection in all visible and unlocked layers" +msgstr "" + +#: ../../po/../src/verbs.cpp:1917 +msgid "D_eselect" +msgstr "D_eseleccionar" + +#: ../../po/../src/verbs.cpp:1918 +msgid "Deselect any selected objects or nodes" +msgstr "Deseleccionar los objetos o nodos seleccionados." + +#. Selection +#: ../../po/../src/verbs.cpp:1921 +msgid "Raise to _Top" +msgstr "Poner al fren_te" + +#: ../../po/../src/verbs.cpp:1922 +msgid "Raise selection to top" +msgstr "Poner la selección al frente" + +#: ../../po/../src/verbs.cpp:1923 +msgid "Lower to _Bottom" +msgstr "_Bajar al fondo" + +#: ../../po/../src/verbs.cpp:1924 +msgid "Lower selection to bottom" +msgstr "Bajar la selección al fondo" + +#: ../../po/../src/verbs.cpp:1925 +msgid "_Raise" +msgstr "Eleva_r" + +#: ../../po/../src/verbs.cpp:1926 +msgid "Raise selection one step" +msgstr "Elevar la selección un nivel" + +#: ../../po/../src/verbs.cpp:1927 +msgid "_Lower" +msgstr "_Bajar" + +#: ../../po/../src/verbs.cpp:1928 +msgid "Lower selection one step" +msgstr "Bajar la selección un nivel" + +#: ../../po/../src/verbs.cpp:1929 +msgid "_Group" +msgstr "A_grupar" + +#: ../../po/../src/verbs.cpp:1930 +msgid "Group selected objects" +msgstr "Agrupar los objetos seleccionados" + +#: ../../po/../src/verbs.cpp:1932 +#, fuzzy +msgid "Ungroup selected groups" +msgstr "Desagrupar grupo(s) seleccionado(s)" + +#: ../../po/../src/verbs.cpp:1934 +#, fuzzy +msgid "_Put on Path" +msgstr "Convierte el contorno seleccionado en trazo" + +#: ../../po/../src/verbs.cpp:1935 +#, fuzzy +msgid "Put text on path" +msgstr "Convierte el contorno seleccionado en trazo" + +#: ../../po/../src/verbs.cpp:1936 +#, fuzzy +msgid "_Remove from Path" +msgstr "Deshacer _transformaciones" + +#: ../../po/../src/verbs.cpp:1937 +#, fuzzy +msgid "Remove text from path" +msgstr "Convierte el contorno seleccionado en trazo" + +#: ../../po/../src/verbs.cpp:1938 +msgid "Remove Manual _Kerns" +msgstr "" + +#. TRANSLATORS: "glyph": An image used in the visual representation of characters; +#. roughly speaking, how a character looks. A font is a set of glyphs. +#: ../../po/../src/verbs.cpp:1941 +#, fuzzy +msgid "Remove all manual kerns and glyph rotations from a text object" +msgstr "Eliminar transformaciones del objeto" + +#: ../../po/../src/verbs.cpp:1943 +msgid "_Union" +msgstr "_Unión" + +#: ../../po/../src/verbs.cpp:1944 +msgid "Union of selected objects" +msgstr "Unión de objetos seleccionados" + +#: ../../po/../src/verbs.cpp:1945 +msgid "_Intersection" +msgstr "_Intersección" + +#: ../../po/../src/verbs.cpp:1946 +msgid "Intersection of selected objects" +msgstr "Intersección de objetos seleccionados" + +#: ../../po/../src/verbs.cpp:1947 +msgid "_Difference" +msgstr "_Diferencia" + +#: ../../po/../src/verbs.cpp:1948 +#, fuzzy +msgid "Difference of selected objects (bottom minus top)" +msgstr "Diferencia de objetos seleccionados" + +#: ../../po/../src/verbs.cpp:1949 +msgid "E_xclusion" +msgstr "E_xclusión" + +#: ../../po/../src/verbs.cpp:1950 +msgid "Exclusive OR of selected objects" +msgstr "OR exclusivo de objetos seleccionados" + +#: ../../po/../src/verbs.cpp:1951 +msgid "Di_vision" +msgstr "Di_visión" + +#: ../../po/../src/verbs.cpp:1952 +msgid "Cut the bottom object into pieces" +msgstr "Cortar el objeto del fondo en pedazos" + +#. TRANSLATORS: "to cut a path" is not the same as "to break a path apart" - see the +#. Advanced tutorial for more info +#: ../../po/../src/verbs.cpp:1955 +msgid "Cut _Path" +msgstr "Cortar trazo" + +#: ../../po/../src/verbs.cpp:1956 +#, fuzzy +msgid "Cut the bottom object's stroke into pieces, removing fill" +msgstr "Cortar el objeto del fondo en pedazos" + +#. TRANSLATORS: "outset": expand a shape by offsetting the object's path, +#. i.e. by displacing it perpendicular to the path in each point. +#. See also the Advanced Tutorial for explanation. +#: ../../po/../src/verbs.cpp:1960 +#, fuzzy +msgid "Outs_et" +msgstr "A_mpliar" + +#: ../../po/../src/verbs.cpp:1961 +#, fuzzy +msgid "Outset selected paths" +msgstr "Ampliar los trazos seleccionados" + +#: ../../po/../src/verbs.cpp:1963 +#, fuzzy +msgid "O_utset Path by 1 px" +msgstr "A_mpliar trazo 1 px" + +#: ../../po/../src/verbs.cpp:1964 +#, fuzzy +msgid "Outset selected paths by 1 px" +msgstr "Ampliar los trazos seleccionados 1 px" + +#: ../../po/../src/verbs.cpp:1966 +#, fuzzy +msgid "O_utset Path by 10 px" +msgstr "Re_ducir trazo 10 px" + +#: ../../po/../src/verbs.cpp:1967 +#, fuzzy +msgid "Outset selected paths by 10 px" +msgstr "Ampliar los trazos seleccionados 10 px" + +#. TRANSLATORS: "inset": contract a shape by offsetting the object's path, +#. i.e. by displacing it perpendicular to the path in each point. +#. See also the Advanced Tutorial for explanation. +#: ../../po/../src/verbs.cpp:1971 +msgid "I_nset" +msgstr "Re_ducir" + +#: ../../po/../src/verbs.cpp:1972 +#, fuzzy +msgid "Inset selected paths" +msgstr "Reducir los trazos seleccionados" + +#: ../../po/../src/verbs.cpp:1974 +#, fuzzy +msgid "I_nset Path by 1 px" +msgstr "Re_ducir trazo 1 px" + +#: ../../po/../src/verbs.cpp:1975 +#, fuzzy +msgid "Inset selected paths by 1 px" +msgstr "Reducir los trazos seleccionados 1 px" + +#: ../../po/../src/verbs.cpp:1977 +#, fuzzy +msgid "I_nset Path by 10 px" +msgstr "Re_ducir trazo 10 px" + +#: ../../po/../src/verbs.cpp:1978 +#, fuzzy +msgid "Inset selected paths by 10 px" +msgstr "Reducir los trazos seleccionados 10 px" + +#: ../../po/../src/verbs.cpp:1980 +msgid "D_ynamic Offset" +msgstr "Offset d_inámico" + +#: ../../po/../src/verbs.cpp:1980 +msgid "Create a dynamic offset object" +msgstr "Crear un objeto de offset dinámico" + +#: ../../po/../src/verbs.cpp:1982 +msgid "_Linked Offset" +msgstr "Offset en_lazado" + +#: ../../po/../src/verbs.cpp:1983 +msgid "Create a dynamic offset object linked to the original path" +msgstr "Crear un objeto de offset dinámico enlazado al trazo original" + +#: ../../po/../src/verbs.cpp:1985 +msgid "_Stroke to Path" +msgstr "Con_torno a trazo" + +#: ../../po/../src/verbs.cpp:1986 +#, fuzzy +msgid "Convert selected strokes to paths" +msgstr "Convierte el contorno seleccionado en trazo" + +#: ../../po/../src/verbs.cpp:1987 +msgid "Si_mplify" +msgstr "Simp_lificar" + +#: ../../po/../src/verbs.cpp:1988 +#, fuzzy +msgid "Simplify selected paths by removing extra nodes" +msgstr "Simplifica el trazo seleccionado" + +#: ../../po/../src/verbs.cpp:1989 +#, fuzzy +msgid "_Reverse" +msgstr "Reglas" + +#: ../../po/../src/verbs.cpp:1990 +#, fuzzy +msgid "Reverses the direction of selected paths; useful for flipping markers" +msgstr "Intersección de objetos seleccionados" + +#. TRANSLATORS: "to trace" means "to convert a bitmap to vector graphics" (to vectorize) +#: ../../po/../src/verbs.cpp:1992 +#, fuzzy +msgid "_Trace Bitmap" +msgstr "Imprimir como mapa de bits" + +#: ../../po/../src/verbs.cpp:1993 +#, fuzzy +msgid "Convert bitmap object to paths" +msgstr "Convierte el contorno seleccionado en trazo" + +#: ../../po/../src/verbs.cpp:1994 +#, fuzzy +msgid "_Make a Bitmap Copy" +msgstr "Imprimir como mapa de bits" + +#: ../../po/../src/verbs.cpp:1995 +#, fuzzy +msgid "Export selection to a bitmap and insert it into document" +msgstr "Importar mapa de bits o imagen SVG al documento" + +#: ../../po/../src/verbs.cpp:1996 +msgid "_Combine" +msgstr "_Combinar" + +#: ../../po/../src/verbs.cpp:1997 +msgid "Combine several paths into one" +msgstr "" + +#. TRANSLATORS: "to cut a path" is not the same as "to break a path apart" - see the +#. Advanced tutorial for more info +#: ../../po/../src/verbs.cpp:2000 +msgid "Break _Apart" +msgstr "Descombin_ar" + +#: ../../po/../src/verbs.cpp:2001 +#, fuzzy +msgid "Break selected paths into subpaths" +msgstr "Separar los trazos seleccionados en subtrazos" + +#: ../../po/../src/verbs.cpp:2002 +msgid "Gri_d Arrange..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2003 +msgid "Arrange selection in grid pattern" +msgstr "" + +#. Layer +#: ../../po/../src/verbs.cpp:2005 +#, fuzzy +msgid "_Add Layer..." +msgstr "_Bajar" + +#: ../../po/../src/verbs.cpp:2006 +#, fuzzy +msgid "Create a new layer" +msgstr "Crear un documento nuevo" + +#: ../../po/../src/verbs.cpp:2007 +#, fuzzy +msgid "Re_name Layer..." +msgstr "Elevar nodo" + +#: ../../po/../src/verbs.cpp:2008 +#, fuzzy +msgid "Rename the current layer" +msgstr "Seleccionar" + +#: ../../po/../src/verbs.cpp:2009 +#, fuzzy +msgid "Switch to Layer Abov_e" +msgstr "Cambiar a la ventana de documento siguiente" + +#: ../../po/../src/verbs.cpp:2010 +#, fuzzy +msgid "Switch to the layer above the current" +msgstr "Cambiar a la ventana de documento siguiente" + +#: ../../po/../src/verbs.cpp:2011 +#, fuzzy +msgid "Switch to Layer Belo_w" +msgstr "Cambiar a la ventana de documento siguiente" + +#: ../../po/../src/verbs.cpp:2012 +#, fuzzy +msgid "Switch to the layer below the current" +msgstr "Cambiar a la ventana de documento siguiente" + +#: ../../po/../src/verbs.cpp:2013 +#, fuzzy +msgid "Move Selection to Layer Abo_ve" +msgstr "Bajar la selección al fondo" + +#: ../../po/../src/verbs.cpp:2014 +msgid "Move selection to the layer above the current" +msgstr "" + +#: ../../po/../src/verbs.cpp:2015 +#, fuzzy +msgid "Move Selection to Layer Bel_ow" +msgstr "Bajar la selección un nivel" + +#: ../../po/../src/verbs.cpp:2016 +msgid "Move selection to the layer below the current" +msgstr "" + +#: ../../po/../src/verbs.cpp:2017 +#, fuzzy +msgid "Layer to _Top" +msgstr "Poner al fren_te" + +#: ../../po/../src/verbs.cpp:2018 +#, fuzzy +msgid "Raise the current layer to the top" +msgstr "Poner la selección al frente" + +#: ../../po/../src/verbs.cpp:2019 +#, fuzzy +msgid "Layer to _Bottom" +msgstr "_Bajar al fondo" + +#: ../../po/../src/verbs.cpp:2020 +#, fuzzy +msgid "Lower the current layer to the bottom" +msgstr "Bajar la selección al fondo" + +#: ../../po/../src/verbs.cpp:2021 +#, fuzzy +msgid "_Raise Layer" +msgstr "Elevar nodo" + +#: ../../po/../src/verbs.cpp:2022 +msgid "Raise the current layer" +msgstr "" + +#: ../../po/../src/verbs.cpp:2023 +#, fuzzy +msgid "_Lower Layer" +msgstr "Bajar nodo" + +#: ../../po/../src/verbs.cpp:2024 +msgid "Lower the current layer" +msgstr "" + +#: ../../po/../src/verbs.cpp:2025 +#, fuzzy +msgid "_Delete Current Layer" +msgstr "Seleccionar" + +#: ../../po/../src/verbs.cpp:2026 +#, fuzzy +msgid "Delete the current layer" +msgstr "Seleccionar" + +#. Object +#: ../../po/../src/verbs.cpp:2029 +#, fuzzy +msgid "Rotate _90° CW" +msgstr "Rotar _90 grados a la derecha" + +#: ../../po/../src/verbs.cpp:2030 +#, fuzzy +msgid "Rotate selection 90° clockwise" +msgstr "Rotar el objeto 90 grados a la derecha" + +#: ../../po/../src/verbs.cpp:2031 +#, fuzzy +msgid "Rotate 9_0° CCW" +msgstr "Rotar 9_0 grados a la izquierda" + +#: ../../po/../src/verbs.cpp:2032 +#, fuzzy +msgid "Rotate selection 90° counter-clockwise" +msgstr "Rotar el objeto 90 grados a la izquierda" + +#: ../../po/../src/verbs.cpp:2033 +msgid "Remove _Transformations" +msgstr "Deshacer _transformaciones" + +#: ../../po/../src/verbs.cpp:2034 +msgid "Remove transformations from object" +msgstr "Eliminar transformaciones del objeto" + +#: ../../po/../src/verbs.cpp:2035 +msgid "_Object to Path" +msgstr "_Objeto a trazo" + +#: ../../po/../src/verbs.cpp:2036 +#, fuzzy +msgid "Convert selected objects to paths" +msgstr "Convierte el objeto seleccionado en trazos" + +#: ../../po/../src/verbs.cpp:2037 +msgid "_Flow into Frame" +msgstr "" + +#: ../../po/../src/verbs.cpp:2038 +#, fuzzy +msgid "Put text into frames" +msgstr "Convierte el contorno seleccionado en trazo" + +#: ../../po/../src/verbs.cpp:2039 +#, fuzzy +msgid "_Unflow" +msgstr "_Deshacer" + +#: ../../po/../src/verbs.cpp:2040 +msgid "Remove text from frame (creates a single-line text object)" +msgstr "" + +#: ../../po/../src/verbs.cpp:2041 +#, fuzzy +msgid "_Convert to Text" +msgstr "Convierte el contorno seleccionado en trazo" + +#: ../../po/../src/verbs.cpp:2042 +#, fuzzy +msgid "Convert flowed text to regular text objects (preserves appearance)" +msgstr "Convierte el objeto seleccionado en trazos" + +#: ../../po/../src/verbs.cpp:2044 +#, fuzzy +msgid "Flip _Horizontal" +msgstr "Reflejo _horizontal" + +#: ../../po/../src/verbs.cpp:2044 +#, fuzzy +msgid "Flips selected objects horizontally" +msgstr "Reflejar los objetos seleccionados horizontalmente" + +#: ../../po/../src/verbs.cpp:2047 +#, fuzzy +msgid "Flip _Vertical" +msgstr "Reflejo _vertical" + +#: ../../po/../src/verbs.cpp:2047 +#, fuzzy +msgid "Flips selected objects vertically" +msgstr "Reflejar los objetos seleccionados verticalmente" + +#. Tools +#: ../../po/../src/verbs.cpp:2051 +msgid "Select" +msgstr "Seleccionar" + +#: ../../po/../src/verbs.cpp:2052 +#, fuzzy +msgid "Select and transform objects" +msgstr "Seleccionar y transformar objetos (F1)" + +#: ../../po/../src/verbs.cpp:2053 +msgid "Node Edit" +msgstr "Edición de nodos" + +#: ../../po/../src/verbs.cpp:2054 +#, fuzzy +msgid "Edit path nodes or control handles" +msgstr "Editar trazo o tiradores de control (F2)" + +#: ../../po/../src/verbs.cpp:2056 +#, fuzzy +msgid "Create rectangles and squares" +msgstr "Crear rectángulos y cuadrados (F4)" + +#: ../../po/../src/verbs.cpp:2058 +#, fuzzy +msgid "Create circles, ellipses, and arcs" +msgstr "Crear círculos, elipses y arcos (F5)" + +#: ../../po/../src/verbs.cpp:2060 +#, fuzzy +msgid "Create stars and polygons" +msgstr "Crear estrellas y polígonos (*)" + +#: ../../po/../src/verbs.cpp:2062 +#, fuzzy +msgid "Create spirals" +msgstr "Crear espirales (F9)" + +#: ../../po/../src/verbs.cpp:2064 +#, fuzzy +msgid "Draw freehand lines" +msgstr "Dibujar líneas a mano alzada (F6)" + +#: ../../po/../src/verbs.cpp:2066 +#, fuzzy +msgid "Draw Bezier curves and straight lines" +msgstr "Dibujar curvas Bézier y líneas rectas (Mayús+F6)" + +#: ../../po/../src/verbs.cpp:2068 +#, fuzzy +msgid "Draw calligraphic lines" +msgstr "Dibujar líneas caligráficas (Ctrl+F6)" + +#: ../../po/../src/verbs.cpp:2070 +#, fuzzy +msgid "Create and edit text objects" +msgstr "Crear y editar objetos de texto (F8)" + +#: ../../po/../src/verbs.cpp:2072 +#, fuzzy +msgid "Create and edit gradients" +msgstr "Crear y editar objetos de texto (F8)" + +#: ../../po/../src/verbs.cpp:2074 +#, fuzzy +msgid "Zoom in or out" +msgstr "Acercar o alejar (F3)" + +#: ../../po/../src/verbs.cpp:2076 +#, fuzzy +msgid "Pick averaged colors from image" +msgstr "Seleccionar colores de la imagen (F7)" + +#: ../../po/../src/verbs.cpp:2078 +#, fuzzy +msgid "Create connectors" +msgstr "Crear un documento nuevo" + +#. Tool prefs +#: ../../po/../src/verbs.cpp:2081 +msgid "Selector Preferences" +msgstr "" + +#: ../../po/../src/verbs.cpp:2082 +#, fuzzy +msgid "Open Preferences for the Selector tool" +msgstr "Inkscape: _Avanzado" + +#: ../../po/../src/verbs.cpp:2083 +msgid "Node Tool Preferences" +msgstr "" + +#: ../../po/../src/verbs.cpp:2084 +#, fuzzy +msgid "Open Preferences for the Node tool" +msgstr "Inkscape: _Avanzado" + +#: ../../po/../src/verbs.cpp:2085 +#, fuzzy +msgid "Rectangle Preferences" +msgstr "_Propiedades del rectángulo" + +#: ../../po/../src/verbs.cpp:2086 +#, fuzzy +msgid "Open Preferences for the Rectangle tool" +msgstr "Inkscape: _Avanzado" + +#: ../../po/../src/verbs.cpp:2087 +#, fuzzy +msgid "Ellipse Preferences" +msgstr "Opciones globales de Inkscape" + +#: ../../po/../src/verbs.cpp:2088 +#, fuzzy +msgid "Open Preferences for the Ellipse tool" +msgstr "Inkscape: _Avanzado" + +#: ../../po/../src/verbs.cpp:2089 +#, fuzzy +msgid "Star Preferences" +msgstr "_Propiedades de la estrella" + +#: ../../po/../src/verbs.cpp:2090 +#, fuzzy +msgid "Open Preferences for the Star tool" +msgstr "Inkscape: _Avanzado" + +#: ../../po/../src/verbs.cpp:2091 +#, fuzzy +msgid "Spiral Preferences" +msgstr "_Propiedades de la espiral" + +#: ../../po/../src/verbs.cpp:2092 +#, fuzzy +msgid "Open Preferences for the Spiral tool" +msgstr "Inkscape: _Avanzado" + +#: ../../po/../src/verbs.cpp:2093 +#, fuzzy +msgid "Pencil Preferences" +msgstr "Inkscape: _Avanzado" + +#: ../../po/../src/verbs.cpp:2094 +#, fuzzy +msgid "Open Preferences for the Pencil tool" +msgstr "Inkscape: _Avanzado" + +#: ../../po/../src/verbs.cpp:2095 +#, fuzzy +msgid "Pen Preferences" +msgstr "Inkscape: _Avanzado" + +#: ../../po/../src/verbs.cpp:2096 +#, fuzzy +msgid "Open Preferences for the Pen tool" +msgstr "Inkscape: _Avanzado" + +#: ../../po/../src/verbs.cpp:2097 +#, fuzzy +msgid "Calligraphic Preferences" +msgstr "Línea caligráfica" + +#: ../../po/../src/verbs.cpp:2098 +#, fuzzy +msgid "Open Preferences for the Calligraphy tool" +msgstr "Inkscape: _Avanzado" + +#: ../../po/../src/verbs.cpp:2099 +#, fuzzy +msgid "Text Preferences" +msgstr "Inkscape: _Avanzado" + +#: ../../po/../src/verbs.cpp:2100 +#, fuzzy +msgid "Open Preferences for the Text tool" +msgstr "Inkscape: _Avanzado" + +#: ../../po/../src/verbs.cpp:2101 +#, fuzzy +msgid "Gradient Preferences" +msgstr "Inkscape: _Avanzado" + +#: ../../po/../src/verbs.cpp:2102 +#, fuzzy +msgid "Open Preferences for the Gradient tool" +msgstr "Inkscape: _Avanzado" + +#: ../../po/../src/verbs.cpp:2103 +#, fuzzy +msgid "Zoom Preferences" +msgstr "Inkscape: _Avanzado" + +#: ../../po/../src/verbs.cpp:2104 +#, fuzzy +msgid "Open Preferences for the Zoom tool" +msgstr "Inkscape: _Avanzado" + +#: ../../po/../src/verbs.cpp:2105 +#, fuzzy +msgid "Dropper Preferences" +msgstr "Inkscape: _Avanzado" + +#: ../../po/../src/verbs.cpp:2106 +#, fuzzy +msgid "Open Preferences for the Dropper tool" +msgstr "Inkscape: _Avanzado" + +#: ../../po/../src/verbs.cpp:2107 +#, fuzzy +msgid "Connector Preferences" +msgstr "_Propiedades de la estrella" + +#: ../../po/../src/verbs.cpp:2108 +#, fuzzy +msgid "Open Preferences for the Connector tool" +msgstr "Inkscape: _Avanzado" + +#. Zoom/View +#: ../../po/../src/verbs.cpp:2111 +msgid "Zoom In" +msgstr "Aumentar" + +#: ../../po/../src/verbs.cpp:2111 +msgid "Zoom in" +msgstr "Aumentar" + +#: ../../po/../src/verbs.cpp:2112 +msgid "Zoom Out" +msgstr "Alejar" + +#: ../../po/../src/verbs.cpp:2112 +msgid "Zoom out" +msgstr "Alejar" + +#: ../../po/../src/verbs.cpp:2113 +#, fuzzy +msgid "_Rulers" +msgstr "Reglas" + +#: ../../po/../src/verbs.cpp:2113 +#, fuzzy +msgid "Show or hide the canvas rulers" +msgstr "Mostrar/ocultar reglas" + +#: ../../po/../src/verbs.cpp:2114 +#, fuzzy +msgid "Scroll_bars" +msgstr "Barras de desplazamiento" + +#: ../../po/../src/verbs.cpp:2114 +#, fuzzy +msgid "Show or hide the canvas scrollbars" +msgstr "Mostrar/ocultar barras de desplazamiento" + +#: ../../po/../src/verbs.cpp:2115 +#, fuzzy +msgid "_Grid" +msgstr "Rejilla" + +#: ../../po/../src/verbs.cpp:2116 +#, fuzzy +msgid "G_uides" +msgstr "Guías" + +#: ../../po/../src/verbs.cpp:2117 +#, fuzzy +msgid "Nex_t Zoom" +msgstr "Zoom siguien_te" + +#: ../../po/../src/verbs.cpp:2117 +msgid "Next zoom (from the history of zooms)" +msgstr "" + +#: ../../po/../src/verbs.cpp:2119 +#, fuzzy +msgid "Pre_vious Zoom" +msgstr "Zoom anterior" + +#: ../../po/../src/verbs.cpp:2119 +msgid "Previous zoom (from the history of zooms)" +msgstr "" + +#: ../../po/../src/verbs.cpp:2121 +msgid "Zoom 1:_1" +msgstr "Zoom 1:_1" + +#: ../../po/../src/verbs.cpp:2121 +msgid "Zoom to 1:1" +msgstr "Zoom a 1:1" + +#: ../../po/../src/verbs.cpp:2123 +msgid "Zoom 1:_2" +msgstr "Zoom 1:2" + +#: ../../po/../src/verbs.cpp:2123 +msgid "Zoom to 1:2" +msgstr "Zoom a 1:2" + +#: ../../po/../src/verbs.cpp:2125 +msgid "_Zoom 2:1" +msgstr "_Zoom 2:1" + +#: ../../po/../src/verbs.cpp:2125 +msgid "Zoom to 2:1" +msgstr "_Zoom a 2:1" + +#: ../../po/../src/verbs.cpp:2128 +msgid "_Fullscreen" +msgstr "_Pantalla completa" + +#: ../../po/../src/verbs.cpp:2128 +#, fuzzy +msgid "Stretch this document window to full screen" +msgstr "Cambiar a la ventana de documento anterior" + +#: ../../po/../src/verbs.cpp:2131 +#, fuzzy +msgid "Duplic_ate Window" +msgstr "Duplicar nodo" + +#: ../../po/../src/verbs.cpp:2131 +#, fuzzy +msgid "Open a new window with the same document" +msgstr "Opciones guardadas con el documento" + +#: ../../po/../src/verbs.cpp:2133 +#, fuzzy +msgid "_New View Preview" +msgstr "_Nueva vista" + +#: ../../po/../src/verbs.cpp:2134 +#, fuzzy +msgid "New View Preview" +msgstr "_Nueva vista" + +#. "view_new_preview" +#: ../../po/../src/verbs.cpp:2136 +msgid "_Normal" +msgstr "" + +#: ../../po/../src/verbs.cpp:2137 +msgid "Switch to normal display mode" +msgstr "" + +#: ../../po/../src/verbs.cpp:2138 +#, fuzzy +msgid "_Outline" +msgstr "Mostrar el boceto" + +#: ../../po/../src/verbs.cpp:2139 +msgid "Switch to outline (wireframe) display mode" +msgstr "" + +#: ../../po/../src/verbs.cpp:2141 +#, fuzzy +msgid "Ico_n Preview" +msgstr "_Nueva vista" + +#: ../../po/../src/verbs.cpp:2142 +msgid "Open a window to preview items at different icon resolutions" +msgstr "" + +#: ../../po/../src/verbs.cpp:2144 +#, fuzzy +msgid "Zoom to fit page in window" +msgstr "Ajustar la página a la ventana" + +#: ../../po/../src/verbs.cpp:2145 +msgid "Page _Width" +msgstr "An_cho de página" + +#: ../../po/../src/verbs.cpp:2146 +#, fuzzy +msgid "Zoom to fit page width in window" +msgstr "Ajustar la anchura de la página a la ventana" + +#: ../../po/../src/verbs.cpp:2148 +#, fuzzy +msgid "Zoom to fit drawing in window" +msgstr "Ajustar el dibujo a la ventana" + +#: ../../po/../src/verbs.cpp:2150 +#, fuzzy +msgid "Zoom to fit selection in window" +msgstr "Ajustar la selección a la ventana" + +#. Dialogs +#: ../../po/../src/verbs.cpp:2153 +#, fuzzy +msgid "In_kscape Preferences..." +msgstr "Inkscape: _Avanzado" + +#: ../../po/../src/verbs.cpp:2154 +#, fuzzy +msgid "Global Inkscape preferences" +msgstr "Opciones globales de Inkscape" + +#: ../../po/../src/verbs.cpp:2155 +msgid "_Document Preferences..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2156 +#, fuzzy +msgid "Preferences saved with the document" +msgstr "Opciones guardadas con el documento" + +#: ../../po/../src/verbs.cpp:2157 +#, fuzzy +msgid "_Fill and Stroke..." +msgstr "_Relleno y contorno" + +#: ../../po/../src/verbs.cpp:2158 +#, fuzzy +msgid "Fill and Stroke dialog" +msgstr "_Relleno y contorno" + +#. TRANSLATORS: "Swatches" means: color samples +#: ../../po/../src/verbs.cpp:2160 +#, fuzzy +msgid "S_watches..." +msgstr "G_uardar como..." + +#: ../../po/../src/verbs.cpp:2161 +msgid "View color swatches" +msgstr "" + +#: ../../po/../src/verbs.cpp:2162 +#, fuzzy +msgid "Transfor_m..." +msgstr "Transfor_mar" + +#: ../../po/../src/verbs.cpp:2163 +#, fuzzy +msgid "Transform dialog" +msgstr "Transfor_mar" + +#: ../../po/../src/verbs.cpp:2164 +#, fuzzy +msgid "_Align and Distribute..." +msgstr "_Alinear y distribuir" + +#: ../../po/../src/verbs.cpp:2165 +#, fuzzy +msgid "Align and Distribute dialog" +msgstr "_Alinear y distribuir" + +#: ../../po/../src/verbs.cpp:2166 +#, fuzzy +msgid "_Text and Font..." +msgstr "_Texto y tipografía" + +#: ../../po/../src/verbs.cpp:2167 +#, fuzzy +msgid "Text and Font dialog" +msgstr "Texto y tipografía" + +#: ../../po/../src/verbs.cpp:2168 +#, fuzzy +msgid "_XML Editor..." +msgstr "Editor _XML" + +#: ../../po/../src/verbs.cpp:2169 +msgid "XML Editor" +msgstr "Editor XML" + +#: ../../po/../src/verbs.cpp:2170 +#, fuzzy +msgid "_Find..." +msgstr "_Imprimir" + +#: ../../po/../src/verbs.cpp:2171 +#, fuzzy +msgid "Find objects in document" +msgstr "Sin gradientes en el documento" + +#: ../../po/../src/verbs.cpp:2172 +msgid "_Messages..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2173 +msgid "View debug messages" +msgstr "" + +#: ../../po/../src/verbs.cpp:2174 +#, fuzzy +msgid "S_cripts..." +msgstr "_Imprimir" + +#: ../../po/../src/verbs.cpp:2175 +msgid "Run scripts" +msgstr "" + +#: ../../po/../src/verbs.cpp:2176 +#, fuzzy +msgid "Show/Hide D_ialogs" +msgstr "_Mostar/ocultar ventanas de diálogo" + +#: ../../po/../src/verbs.cpp:2177 +#, fuzzy +msgid "Show or hide all active dialogs" +msgstr "Conmutar la visibilidad de los diálogos activos" + +#. TRANSLATORS: "Tile clones" means: "Create tiled clones" +#: ../../po/../src/verbs.cpp:2179 +msgid "Tile clones..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2180 +msgid "Create and arrange multiple clones of selection" +msgstr "" + +#: ../../po/../src/verbs.cpp:2181 +#, fuzzy +msgid "_Object Properties..." +msgstr "_Propiedades del rectángulo" + +#: ../../po/../src/verbs.cpp:2182 +#, fuzzy +msgid "Object Properties dialog" +msgstr "_Propiedades del rectángulo" + +#: ../../po/../src/verbs.cpp:2185 +msgid "_Connect to Jabber server..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2185 +msgid "Connect to a Jabber server" +msgstr "" + +#: ../../po/../src/verbs.cpp:2187 +#, fuzzy +msgid "Share with _user..." +msgstr "G_uardar como..." + +#: ../../po/../src/verbs.cpp:2187 +msgid "Establish a whiteboard session with another Jabber user" +msgstr "" + +#: ../../po/../src/verbs.cpp:2189 +msgid "Share with _chatroom..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2189 +msgid "" +"Join a chatroom to start a new whiteboard session or join one in progress" +msgstr "" + +#: ../../po/../src/verbs.cpp:2191 +msgid "_Dump XML node tracker" +msgstr "" + +#: ../../po/../src/verbs.cpp:2191 +msgid "Dump the contents of the XML tracker to the console" +msgstr "" + +#: ../../po/../src/verbs.cpp:2193 +msgid "_Open session file..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2193 +msgid "Open and browse through records of past whiteboard sessions" +msgstr "" + +#: ../../po/../src/verbs.cpp:2195 +msgid "Session file playback" +msgstr "" + +#: ../../po/../src/verbs.cpp:2197 +msgid "_Disconnect from session" +msgstr "" + +#: ../../po/../src/verbs.cpp:2199 +msgid "Disconnect from _server" +msgstr "" + +#: ../../po/../src/verbs.cpp:2201 +msgid "_Input Devices..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2202 +msgid "Configure extended input devices" +msgstr "" + +#. Help +#: ../../po/../src/verbs.cpp:2205 +msgid "_Keys and Mouse" +msgstr "_Teclado y ratón" + +#: ../../po/../src/verbs.cpp:2206 +msgid "Key and mouse shortcuts reference" +msgstr "" + +#: ../../po/../src/verbs.cpp:2207 +#, fuzzy +msgid "About E_xtensions" +msgstr "Expansión:" + +#: ../../po/../src/verbs.cpp:2208 +#, fuzzy +msgid "About Extensions..." +msgstr "Expansión:" + +#: ../../po/../src/verbs.cpp:2209 +#, fuzzy +msgid "About _Memory" +msgstr "Expansión:" + +#: ../../po/../src/verbs.cpp:2210 +#, fuzzy +msgid "About Memory..." +msgstr "Expansión:" + +#: ../../po/../src/verbs.cpp:2211 +msgid "_About Inkscape" +msgstr "_Acerca de Inkscape" + +#. "help_about" +#. new HelpVerb(SP_VERB_SHOW_LICENSE, "ShowLicense", N_("Modifying or Redistributing Inkscape"), +#. N_("Show license to modify and/or redistribute Inkscape: GNU GPL"), NULL), +#. Tutorials +#: ../../po/../src/verbs.cpp:2217 +msgid "Inkscape: _Basic" +msgstr "Inkscape: _Básico" + +#: ../../po/../src/verbs.cpp:2218 +msgid "Getting started with Inkscape" +msgstr "" + +#. "tutorial_basic" +#: ../../po/../src/verbs.cpp:2219 +#, fuzzy +msgid "Inkscape: _Shapes" +msgstr "Inkscape: _Básico" + +#: ../../po/../src/verbs.cpp:2220 +msgid "Using shape tools to create and edit shapes" +msgstr "" + +#: ../../po/../src/verbs.cpp:2221 +msgid "Inkscape: _Advanced" +msgstr "Inkscape: _Avanzado" + +#: ../../po/../src/verbs.cpp:2222 +#, fuzzy +msgid "Advanced Inkscape topics" +msgstr "Muestra de diapositivas Inkscape" + +#. "tutorial_advanced" +#. TRANSLATORS: "to trace" means "to convert a bitmap to vector graphics" (to vectorize) +#: ../../po/../src/verbs.cpp:2224 +#, fuzzy +msgid "Inkscape: T_racing" +msgstr "Inkscape: _Básico" + +#: ../../po/../src/verbs.cpp:2225 +#, fuzzy +msgid "Using bitmap tracing" +msgstr "Tamaño de mapa de bits" + +#. "tutorial_tracing" +#: ../../po/../src/verbs.cpp:2226 +#, fuzzy +msgid "Inkscape: _Calligraphy" +msgstr "Inkscape: _Básico" + +#: ../../po/../src/verbs.cpp:2227 +msgid "Using the Calligraphy pen tool" +msgstr "" + +#: ../../po/../src/verbs.cpp:2228 +msgid "_Elements of Design" +msgstr "_Elementos de diseño" + +#: ../../po/../src/verbs.cpp:2229 +#, fuzzy +msgid "Principles of design in the tutorial form" +msgstr "_Elementos de diseño" + +#. "tutorial_design" +#: ../../po/../src/verbs.cpp:2230 +msgid "_Tips and Tricks" +msgstr "_Trucos y consejos" + +#: ../../po/../src/verbs.cpp:2231 +#, fuzzy +msgid "Miscellaneous tips and tricks" +msgstr "_Trucos y consejos" + +#. "tutorial_tips" +#. Effect +#: ../../po/../src/verbs.cpp:2234 +#, fuzzy +msgid "Previous Effect" +msgstr "Zoom anterior" + +#: ../../po/../src/verbs.cpp:2235 +msgid "Repeat the last effect with the same settings" +msgstr "" + +#. "tutorial_tips" +#: ../../po/../src/verbs.cpp:2236 +#, fuzzy +msgid "Previous Effect Settings..." +msgstr "Zoom anterior" + +#: ../../po/../src/verbs.cpp:2237 +msgid "Repeat the last effect with new settings" +msgstr "" + +#: ../../po/../src/widgets/dash-selector.cpp:106 +#, fuzzy +msgid "Dash pattern" +msgstr "Contorno" + +#: ../../po/../src/widgets/dash-selector.cpp:121 +#, fuzzy +msgid "Pattern offset" +msgstr "Patrón:" + +#: ../../po/../src/widgets/desktop-widget.cpp:240 +#, fuzzy +msgid "Zoom drawing if window size changes" +msgstr "Ajustar el dibujo a la ventana" + +#: ../../po/../src/widgets/desktop-widget.cpp:298 +msgid "Cursor coordinates" +msgstr "Coordenadas del cursor" + +#. display the initial welcome message in the statusbar +#: ../../po/../src/widgets/desktop-widget.cpp:324 +#, fuzzy +msgid "" +"Welcome to Inkscape! Use shape or freehand tools to create objects; " +"use selector (arrow) to move or transform them." +msgstr "" +"Bienvenido a Inkscape. Utilice las herramientas de forma o mano alzada para " +"crear objetos; utilice el selector (flecha) para moverlos o transformarlos." + +#: ../../po/../src/widgets/desktop-widget.cpp:372 +#, c-format +msgid "%s: %d - Inkscape" +msgstr "%s: %d - Inkscape" + +#: ../../po/../src/widgets/desktop-widget.cpp:374 +#, c-format +msgid "%s - Inkscape" +msgstr "%s - Inkscape" + +#: ../../po/../src/widgets/desktop-widget.cpp:532 +#, c-format +msgid "" +"Save changes to document \"%s\" before " +"closing?\n" +"\n" +"If you close without saving, your changes will be discarded." +msgstr "" +"¿Desea guardar los cambios en el " +"documento \"%s\" antes de cerrar?\n" +"\n" +"Si cierra sin guardar se perderán los cambios realizados." + +#: ../../po/../src/widgets/desktop-widget.cpp:548 +#: ../../po/../src/widgets/desktop-widget.cpp:612 +msgid "Close _without saving" +msgstr "Cerrar _sin guardar" + +#: ../../po/../src/widgets/desktop-widget.cpp:595 +#, c-format +msgid "" +"The file \"%s\" was saved with a " +"format (%s) that may cause data loss!\n" +"\n" +"Do you want to save this file in another format?" +msgstr "" +"El archivo \"%s\" fue guardado con un " +"formato (%s) del que no se puede recuperar toda la información.\n" +"\n" +"¿Quiere guardar el archivo con otro formato?" + +#. Family frame +#: ../../po/../src/widgets/font-selector.cpp:156 +msgid "Font family" +msgstr "Familia de tipografías" + +#. Style frame +#: ../../po/../src/widgets/font-selector.cpp:184 +msgid "Style" +msgstr "Estilo" + +#: ../../po/../src/widgets/font-selector.cpp:219 +msgid "Font size:" +msgstr "Tamaño de tipografía:" + +#. TRANSLATORS: Test string used in text and font dialog (when no +#. * text has been entered) to get a preview of the font. Choose +#. * some representative characters that users of your locale will be +#. * interested in. +#: ../../po/../src/widgets/font-selector.cpp:554 +msgid "AaBbCcIiPpQq12368.;/()" +msgstr "AaBbCcIiPpQq12368.;/()" + +#: ../../po/../src/widgets/gradient-selector.cpp:137 +#: ../../po/../src/widgets/gradient-toolbar.cpp:524 +#, fuzzy +msgid "Duplicate" +msgstr "D_uplicar" + +#: ../../po/../src/widgets/gradient-selector.cpp:142 +#: ../../po/../src/widgets/gradient-toolbar.cpp:535 +#, fuzzy +msgid "Edit..." +msgstr "Editar" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/pservers.html#LinearGradientSpreadMethodAttribute +#: ../../po/../src/widgets/gradient-selector.cpp:159 +msgid "" +"Whether to fill with flat color beyond the ends of the gradient vector " +"(spreadMethod=\"pad\"), or repeat the gradient in the same direction " +"(spreadMethod=\"repeat\"), or repeat the gradient in alternating opposite " +"directions (spreadMethod=\"reflect\")" +msgstr "" + +#: ../../po/../src/widgets/gradient-selector.cpp:165 +#, fuzzy +msgid "none" +msgstr "Ninguno" + +#: ../../po/../src/widgets/gradient-selector.cpp:169 +#, fuzzy +msgid "reflected" +msgstr "Primero seleccionado" + +#: ../../po/../src/widgets/gradient-selector.cpp:173 +#, fuzzy +msgid "direct" +msgstr "Editar" + +#: ../../po/../src/widgets/gradient-selector.cpp:181 +msgid "Repeat:" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:217 +msgid "No gradients" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:226 +#, fuzzy +msgid "Nothing selected" +msgstr "Último seleccionado" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:237 +#, fuzzy +msgid "No gradients in selection" +msgstr "Sin gradiente seleccionado" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:247 +msgid "Multiple gradients" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:525 +msgid "" +"If the gradient is used by more than one object, create a copy of it for the " +"selected object(s)" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:536 +#, fuzzy +msgid "Edit the stops of the gradient" +msgstr "Gradiente sin paradas" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:593 +#: ../../po/../src/widgets/toolbox.cpp:1103 +#: ../../po/../src/widgets/toolbox.cpp:1192 +#: ../../po/../src/widgets/toolbox.cpp:1485 +#: ../../po/../src/widgets/toolbox.cpp:1534 +#: ../../po/../src/widgets/toolbox.cpp:1766 +#: ../../po/../src/widgets/toolbox.cpp:1801 +#: ../../po/../src/widgets/toolbox.cpp:2331 +#: ../../po/../src/widgets/toolbox.cpp:2370 +msgid "New:" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:606 +#, fuzzy +msgid "Create linear gradient" +msgstr "Gradiente lineal" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:620 +msgid "Create radial (elliptic or circular) gradient" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:635 +#, fuzzy +msgid "on" +msgstr "Ninguno" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:648 +#, fuzzy +msgid "Create gradient in the fill" +msgstr "Editor de gradiente" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:662 +msgid "Create gradient in the stroke" +msgstr "" + +#. FIXME: implement averaging of all parameters for multiple selected stars +#. gtk_label_set_markup(GTK_LABEL(l), _("Average:")); +#. FIXME: implement averaging of all parameters for multiple selected +#. gtk_label_set_markup(GTK_LABEL(l), _("Average:")); +#: ../../po/../src/widgets/gradient-toolbar.cpp:676 +#: ../../po/../src/widgets/toolbox.cpp:1105 +#: ../../po/../src/widgets/toolbox.cpp:1124 +#: ../../po/../src/widgets/toolbox.cpp:1493 +#: ../../po/../src/widgets/toolbox.cpp:1518 +#: ../../po/../src/widgets/toolbox.cpp:1768 +#: ../../po/../src/widgets/toolbox.cpp:1787 +#: ../../po/../src/widgets/toolbox.cpp:2334 +#: ../../po/../src/widgets/toolbox.cpp:2354 +msgid "Change:" +msgstr "" + +#: ../../po/../src/widgets/gradient-vector.cpp:269 +msgid "No gradients in document" +msgstr "Sin gradientes en el documento" + +#: ../../po/../src/widgets/gradient-vector.cpp:275 +msgid "No gradient selected" +msgstr "Sin gradiente seleccionado" + +#: ../../po/../src/widgets/gradient-vector.cpp:532 +msgid "No stops in gradient" +msgstr "Gradiente sin paradas" + +#. TRANSLATORS: "Stop" means: a "phase" of a gradient +#: ../../po/../src/widgets/gradient-vector.cpp:794 +msgid "Add stop" +msgstr "Añadir parada" + +#: ../../po/../src/widgets/gradient-vector.cpp:797 +msgid "Add another control stop to gradient" +msgstr "Añadir otro control de parada al gradiente" + +#: ../../po/../src/widgets/gradient-vector.cpp:799 +msgid "Delete stop" +msgstr "Borrar parada" + +#: ../../po/../src/widgets/gradient-vector.cpp:802 +msgid "Delete current control stop from gradient" +msgstr "Eliminar el control de parada actual" + +#. Label +#: ../../po/../src/widgets/gradient-vector.cpp:813 +msgid "Offset:" +msgstr "Offset:" + +#. TRANSLATORS: "Stop" means: a "phase" of a gradient +#: ../../po/../src/widgets/gradient-vector.cpp:858 +msgid "Stop Color" +msgstr "Color de parada" + +#: ../../po/../src/widgets/gradient-vector.cpp:887 +msgid "Gradient editor" +msgstr "Editor de gradiente" + +#: ../../po/../src/widgets/layer-selector.cpp:119 +#, fuzzy +msgid "Toggle current layer visibility" +msgstr "Documento guardado." + +#: ../../po/../src/widgets/layer-selector.cpp:139 +#, fuzzy +msgid "Lock or unlock current layer" +msgstr "Documento guardado." + +#: ../../po/../src/widgets/layer-selector.cpp:142 +#, fuzzy +msgid "Current layer" +msgstr "Documento guardado." + +#: ../../po/../src/widgets/layer-selector.cpp:553 +msgid "(root)" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:182 +#: ../../po/../src/widgets/paint-selector.cpp:561 +msgid "No paint" +msgstr "Sin pintura" + +#: ../../po/../src/widgets/paint-selector.cpp:184 +#: ../../po/../src/widgets/paint-selector.cpp:629 +#, fuzzy +msgid "Flat color" +msgstr "Color del resaltado:" + +#: ../../po/../src/widgets/paint-selector.cpp:186 +#: ../../po/../src/widgets/paint-selector.cpp:696 +msgid "Linear gradient" +msgstr "Gradiente lineal" + +#: ../../po/../src/widgets/paint-selector.cpp:188 +#: ../../po/../src/widgets/paint-selector.cpp:699 +msgid "Radial gradient" +msgstr "Gradiente radial" + +#: ../../po/../src/widgets/paint-selector.cpp:192 +msgid "Unset paint (make it undefined so it can be inherited)" +msgstr "" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/painting.html#FillRuleProperty +#: ../../po/../src/widgets/paint-selector.cpp:204 +msgid "" +"Any path self-intersections or subpaths create holes in the fill (fill-rule: " +"evenodd)" +msgstr "" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/painting.html#FillRuleProperty +#: ../../po/../src/widgets/paint-selector.cpp:215 +msgid "" +"Fill is solid unless a subpath is counterdirectional (fill-rule: nonzero)" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:528 +msgid "No objects" +msgstr "Sin objetos" + +#: ../../po/../src/widgets/paint-selector.cpp:539 +msgid "Multiple styles" +msgstr "Estilos múltiples" + +#: ../../po/../src/widgets/paint-selector.cpp:550 +msgid "Paint is undefined" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:757 +#, fuzzy +msgid "No patterns in document" +msgstr "Sin gradientes en el documento" + +#: ../../po/../src/widgets/paint-selector.cpp:872 +msgid "" +"Use Edit > Object(s) to Pattern to create a new pattern from " +"selection." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:426 +msgid "Now stroke width is scaled when objects are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:428 +msgid "Now stroke width is not scaled when objects are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:436 +msgid "" +"Now rounded rectangle corners are scaled when rectangles are " +"scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:438 +msgid "" +"Now rounded rectangle corners are not scaled when rectangles " +"are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:446 +msgid "" +"Now gradients are transformed along with their objects when " +"those are transformed (moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:448 +msgid "" +"Now gradients remain fixed when objects are transformed " +"(moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:456 +msgid "" +"Now patterns are transformed along with their objects when " +"those are transformed (moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:458 +msgid "" +"Now patterns remain fixed when objects are transformed (moved, " +"scaled, rotated, or skewed)." +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:506 +#, fuzzy +msgid "select_toolbar|X" +msgstr "Seleccionar" + +#: ../../po/../src/widgets/select-toolbar.cpp:506 +msgid "Horizontal coordinate of selection" +msgstr "Coordenada horizontal de la selección" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:511 +#, fuzzy +msgid "select_toolbar|Y" +msgstr "Seleccionar" + +#: ../../po/../src/widgets/select-toolbar.cpp:511 +msgid "Vertical coordinate of selection" +msgstr "Coordenada vertical de la selección" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:517 +#, fuzzy +msgid "select_toolbar|W" +msgstr "Seleccionar" + +#: ../../po/../src/widgets/select-toolbar.cpp:517 +msgid "Width of selection" +msgstr "Ancho de la selección" + +#: ../../po/../src/widgets/select-toolbar.cpp:525 +msgid "Change both width and height by the same proportion" +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:534 +#, fuzzy +msgid "select_toolbar|H" +msgstr "Seleccionar" + +#: ../../po/../src/widgets/select-toolbar.cpp:534 +msgid "Height of selection" +msgstr "Altura de la selección" + +#: ../../po/../src/widgets/sp-color-gtkselector.cpp:62 +msgid "System" +msgstr "Sistema" + +#: ../../po/../src/widgets/sp-color-notebook.cpp:322 +#, fuzzy +msgid "RGBA_:" +msgstr "RGB" + +#: ../../po/../src/widgets/sp-color-notebook.cpp:330 +msgid "Hexadecimal RGBA value of the color" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "RGB" +msgstr "RGB" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +#, fuzzy +msgid "HSL" +msgstr "HSV" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "CMYK" +msgstr "CMYK" + +#: ../../po/../src/widgets/sp-color-scales.cpp:397 +msgid "_R" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:398 +#: ../../po/../src/widgets/sp-color-scales.cpp:399 +#, fuzzy +msgid "Red" +msgstr "Rojo:" + +#: ../../po/../src/widgets/sp-color-scales.cpp:400 +msgid "_G" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:401 +#: ../../po/../src/widgets/sp-color-scales.cpp:402 +#, fuzzy +msgid "Green" +msgstr "Verde:" + +#: ../../po/../src/widgets/sp-color-scales.cpp:403 +msgid "_B" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:404 +#: ../../po/../src/widgets/sp-color-scales.cpp:405 +#, fuzzy +msgid "Blue" +msgstr "Azul:" + +#. Label +#: ../../po/../src/widgets/sp-color-scales.cpp:406 +#: ../../po/../src/widgets/sp-color-scales.cpp:432 +#: ../../po/../src/widgets/sp-color-scales.cpp:463 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:141 +msgid "_A" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:407 +#: ../../po/../src/widgets/sp-color-scales.cpp:408 +#: ../../po/../src/widgets/sp-color-scales.cpp:433 +#: ../../po/../src/widgets/sp-color-scales.cpp:434 +#: ../../po/../src/widgets/sp-color-scales.cpp:464 +#: ../../po/../src/widgets/sp-color-scales.cpp:465 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:151 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:163 +msgid "Alpha (opacity)" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:423 +msgid "_H" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:424 +#: ../../po/../src/widgets/sp-color-scales.cpp:425 +#, fuzzy +msgid "Hue" +msgstr "Tono:" + +#: ../../po/../src/widgets/sp-color-scales.cpp:426 +msgid "_S" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:427 +#: ../../po/../src/widgets/sp-color-scales.cpp:428 +#, fuzzy +msgid "Saturation" +msgstr "Saturación:" + +#: ../../po/../src/widgets/sp-color-scales.cpp:429 +msgid "_L" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:430 +#: ../../po/../src/widgets/sp-color-scales.cpp:431 +#, fuzzy +msgid "Lightness" +msgstr "Alto:" + +#: ../../po/../src/widgets/sp-color-scales.cpp:451 +msgid "_C" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:452 +#: ../../po/../src/widgets/sp-color-scales.cpp:453 +#, fuzzy +msgid "Cyan" +msgstr "Cian:" + +#: ../../po/../src/widgets/sp-color-scales.cpp:454 +msgid "_M" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:455 +#: ../../po/../src/widgets/sp-color-scales.cpp:456 +#, fuzzy +msgid "Magenta" +msgstr "Magenta:" + +#: ../../po/../src/widgets/sp-color-scales.cpp:457 +msgid "_Y" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:458 +#: ../../po/../src/widgets/sp-color-scales.cpp:459 +#, fuzzy +msgid "Yellow" +msgstr "Amarillo:" + +#: ../../po/../src/widgets/sp-color-scales.cpp:460 +msgid "_K" +msgstr "" + +#: ../../po/../src/widgets/sp-color-selector.cpp:71 +msgid "Unnamed" +msgstr "Sin nombre" + +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:68 +msgid "Wheel" +msgstr "Rueda" + +#: ../../po/../src/widgets/sp-xmlview-attr-list.cpp:53 +msgid "Attribute" +msgstr "Atributo" + +#: ../../po/../src/widgets/sp-xmlview-attr-list.cpp:54 +msgid "Value" +msgstr "Valor" + +#: ../../po/../src/widgets/toolbox.cpp:424 +msgid "Insert new nodes into selected segments" +msgstr "Insertar los nuevos nodos entre los segmentos seleccionados" + +#: ../../po/../src/widgets/toolbox.cpp:426 +msgid "Delete selected nodes" +msgstr "Suprimir los nodos seleccionados" + +#: ../../po/../src/widgets/toolbox.cpp:431 +msgid "Join paths at selected nodes" +msgstr "Unir los trazos en los nodos seleccionados." + +#: ../../po/../src/widgets/toolbox.cpp:433 +msgid "Join paths at selected nodes with new segment" +msgstr "Unir los trazos en los nodos seleccionados con un segmento nuevo" + +#: ../../po/../src/widgets/toolbox.cpp:436 +msgid "Split path between two non-endpoint nodes" +msgstr "Separar el trazo entre dos nodos." + +#: ../../po/../src/widgets/toolbox.cpp:439 +msgid "Break path at selected nodes" +msgstr "Romper el trazo en los nodos seleccionados" + +#: ../../po/../src/widgets/toolbox.cpp:444 +msgid "Make selected nodes corner" +msgstr "Convertir en esquina los nodos seleccionados" + +#: ../../po/../src/widgets/toolbox.cpp:447 +msgid "Make selected nodes smooth" +msgstr "Suavizar los nodos seleccionados" + +#: ../../po/../src/widgets/toolbox.cpp:450 +msgid "Make selected nodes symmetric" +msgstr "Hacer simétricos los nodos seleccionados." + +#: ../../po/../src/widgets/toolbox.cpp:455 +msgid "Make selected segments lines" +msgstr "Convertir los segmentos seleccionados en líneas" + +#: ../../po/../src/widgets/toolbox.cpp:458 +msgid "Make selected segments curves" +msgstr "Convertir los segmentos seleccionados a curvas" + +#: ../../po/../src/widgets/toolbox.cpp:1199 +msgid "Polygon" +msgstr "Polígono" + +#: ../../po/../src/widgets/toolbox.cpp:1206 +#, fuzzy +msgid "Regular polygon (with one handle) instead of a star" +msgstr "Crear polígonos en vez de estrellas" + +#: ../../po/../src/widgets/toolbox.cpp:1218 +msgid "Corners:" +msgstr "Esquinas:" + +#: ../../po/../src/widgets/toolbox.cpp:1218 +msgid "Number of corners of a polygon or star" +msgstr "Número de esquinas de un polígono o estrella" + +#: ../../po/../src/widgets/toolbox.cpp:1228 +#, fuzzy +msgid "Spoke ratio:" +msgstr "Proporción:" + +#. TRANSLATORS: Tip radius of a star is the distance from the center to the farthest handle. +#. Base radius is the same for the closest handle. +#: ../../po/../src/widgets/toolbox.cpp:1231 +msgid "Base radius to tip radius ratio" +msgstr "Relación entre el radio base y el radio de la punta" + +#: ../../po/../src/widgets/toolbox.cpp:1246 +#, fuzzy +msgid "Rounded:" +msgstr "No redondeado" + +#: ../../po/../src/widgets/toolbox.cpp:1246 +msgid "How much rounded are the corners (0 for sharp)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1256 +msgid "Randomized:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1256 +msgid "Scatter randomly the corners and angles" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1269 +#: ../../po/../src/widgets/toolbox.cpp:1838 +#: ../../po/../src/widgets/toolbox.cpp:2061 +msgid "Defaults" +msgstr "Predeterminados" + +#: ../../po/../src/widgets/toolbox.cpp:1270 +#: ../../po/../src/widgets/toolbox.cpp:1839 +#: ../../po/../src/widgets/toolbox.cpp:2062 +msgid "" +"Reset shape parameters to defaults (use Inkscape Preferences > Tools to " +"change defaults)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1544 +msgid "W:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1544 +#, fuzzy +msgid "Width of rectangle" +msgstr "Ancho de la selección" + +#: ../../po/../src/widgets/toolbox.cpp:1556 +#, fuzzy +msgid "Height of rectangle" +msgstr "Altura de la selección" + +#: ../../po/../src/widgets/toolbox.cpp:1568 +msgid "Rx:" +msgstr "Rx:" + +#: ../../po/../src/widgets/toolbox.cpp:1568 +#, fuzzy +msgid "Horizontal radius of rounded corners" +msgstr "Coordenada horizontal de la selección" + +#: ../../po/../src/widgets/toolbox.cpp:1578 +msgid "Ry:" +msgstr "Ry:" + +#: ../../po/../src/widgets/toolbox.cpp:1578 +#, fuzzy +msgid "Vertical radius of rounded corners" +msgstr "Coordenada vertical de la selección" + +#: ../../po/../src/widgets/toolbox.cpp:1594 +msgid "Not rounded" +msgstr "No redondeado" + +#: ../../po/../src/widgets/toolbox.cpp:1596 +msgid "Make corners sharp" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1805 +msgid "Turns:" +msgstr "Vueltas:" + +#: ../../po/../src/widgets/toolbox.cpp:1805 +msgid "Number of revolutions" +msgstr "Número de revoluciones" + +#: ../../po/../src/widgets/toolbox.cpp:1815 +msgid "Divergence:" +msgstr "Divergencia:" + +#: ../../po/../src/widgets/toolbox.cpp:1815 +msgid "How much denser/sparser are outer revolutions; 1 = uniform" +msgstr "" +"Cuánto más densas/difusas son las revoluciones exteriores; 1 = uniforme " + +#: ../../po/../src/widgets/toolbox.cpp:1825 +msgid "Inner radius:" +msgstr "Radio interior:" + +#: ../../po/../src/widgets/toolbox.cpp:1825 +#, fuzzy +msgid "Radius of the innermost revolution (relative to the spiral size)" +msgstr "Radio de la revolución más interior" + +#: ../../po/../src/widgets/toolbox.cpp:1957 +msgid "The width of the calligraphic pen (relative to the visible canvas area)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1967 +#, fuzzy +msgid "Thinning:" +msgstr "Renderizado" + +#: ../../po/../src/widgets/toolbox.cpp:1967 +msgid "" +"How much velocity thins the stroke (> 0 makes fast strokes thinner, < 0 " +"makes them broader, 0 makes width independent of velocity)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1980 +msgid "Angle:" +msgstr "Ángulo:" + +#: ../../po/../src/widgets/toolbox.cpp:1980 +msgid "" +"The angle of the pen's nib (in degrees; 0 = horizontal; has no effect if " +"fixation = 0)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1990 +#, fuzzy +msgid "Fixation:" +msgstr "Orientación:" + +#: ../../po/../src/widgets/toolbox.cpp:1990 +msgid "" +"How fixed is the pen angle (0 = always perpendicular to stroke direction, 1 " +"= fixed)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2003 +msgid "Mass:" +msgstr "Masa:" + +#: ../../po/../src/widgets/toolbox.cpp:2003 +msgid "How much inertia affects the movement of the pen" +msgstr "" + +#. TRANSLATORS: "drag" means "resistance" here +#: ../../po/../src/widgets/toolbox.cpp:2014 +msgid "Drag:" +msgstr "Arrastrar:" + +#: ../../po/../src/widgets/toolbox.cpp:2014 +msgid "How much resistance affects the movement of the pen" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2034 +msgid "Use the pressure of the input device to alter the width of the pen" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2047 +msgid "Use the tilt of the input device to alter the angle of the pen's nib" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2374 +#, fuzzy +msgid "Start:" +msgstr "Estrella" + +#: ../../po/../src/widgets/toolbox.cpp:2374 +msgid "The angle (in degrees) from the horizontal to the arc's start point" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2384 +msgid "End:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2384 +msgid "The angle (in degrees) from the horizontal to the arc's end point" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2395 +#, fuzzy +msgid "Open arc" +msgstr "Abrir _reciente" + +#: ../../po/../src/widgets/toolbox.cpp:2396 +msgid "" +"Switch between arc (unclosed shape) and segment (closed shape with two radii)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2415 +msgid "Make whole" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2417 +msgid "Make the shape a whole ellipse, not arc or segment" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2644 +msgid "" +"When pressed, picks visible color without alpha and when not pressed, picks " +"color including its alpha" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:3039 +#, fuzzy +msgid "Make connectors avoid selected objects" +msgstr "Intersección de objetos seleccionados" + +#: ../../po/../src/widgets/toolbox.cpp:3043 +#, fuzzy +msgid "Make connectors ignore selected objects" +msgstr "Suprimir los nodos seleccionados" + +#. +#. 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 : +#: ../share/extensions/addnodes.inx.h:1 +#, fuzzy +msgid "Add Nodes" +msgstr "Ninguno" + +#: ../share/extensions/addnodes.inx.h:2 +msgid "Maximum Segment Length" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:1 +#, fuzzy +msgid "AI Input" +msgstr "Entrada" + +#: ../share/extensions/ai_input.inx.h:2 ../share/extensions/ai_output.inx.h:2 +msgid "Adobe Illustrator (*.ai)" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:3 +msgid "Open files saved with Adobe Illustrator" +msgstr "" + +#: ../share/extensions/ai_output.inx.h:1 +#, fuzzy +msgid "AI Output" +msgstr "A_mpliar" + +#: ../share/extensions/ai_output.inx.h:3 +#, fuzzy +msgid "Write Adobe Illustrator" +msgstr "Ilustrador vectorial SVG" + +#: ../share/extensions/dia.inx.h:1 +msgid "A diagram created with the program Dia" +msgstr "" + +#: ../share/extensions/dia.inx.h:2 +msgid "Dia Diagram (*.dia)" +msgstr "" + +#: ../share/extensions/dia.inx.h:3 +#, fuzzy +msgid "Dia Input" +msgstr "Entrada" + +#: ../share/extensions/dia.inx.h:4 +msgid "" +"In order to import Dia files, Dia itself must be installed. You can get Dia " +"at http://www.gnome.org/projects/dia/" +msgstr "" + +#: ../share/extensions/dia.inx.h:5 +msgid "" +"The dia2svg.sh script should be installed with your Inkscape distribution. " +"If you do not have it, there is likely to be something wrong with your " +"Inkscape installation." +msgstr "" + +#: ../share/extensions/dots.inx.h:1 +#, fuzzy +msgid "Connect the Dots" +msgstr "Esquinas:" + +#: ../share/extensions/dots.inx.h:2 +#, fuzzy +msgid "Dot Size" +msgstr "Caras:" + +#: ../share/extensions/dots.inx.h:3 +#, fuzzy +msgid "Font Size" +msgstr "Tamaño de tipografía:" + +#: ../share/extensions/dropshadow.inx.h:1 +msgid "Color of shadow" +msgstr "" + +#: ../share/extensions/dropshadow.inx.h:2 +msgid "Dropshadow" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:1 +#: ../share/extensions/dxf_output.inx.h:1 +msgid "AutoCAD DXF (*.dxf)" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:2 +#, fuzzy +msgid "DXF Input" +msgstr "Entrada" + +#: ../share/extensions/dxf_input.inx.h:3 +msgid "Import AutoCAD's Document Exchange Format" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:4 +msgid "" +"dxf2svg may come with Inkscape, but is also at http://dxf-svg-convert." +"sourceforge.net/" +msgstr "" + +#: ../share/extensions/dxf_output.inx.h:2 +#, fuzzy +msgid "DXF Output" +msgstr "A_mpliar" + +#: ../share/extensions/dxf_output.inx.h:3 +msgid "DXF file written by pstoedit" +msgstr "" + +#: ../share/extensions/dxf_output.inx.h:4 +msgid "pstoedit must be installed to run see http://www.pstoedit.net/pstoedit" +msgstr "" + +#: ../share/extensions/embedimage.inx.h:1 +#, fuzzy +msgid "Embed Images" +msgstr "URI de la imagen:" + +#: ../share/extensions/eps_input.inx.h:1 +#, fuzzy +msgid "EPS Input" +msgstr "Entrada" + +#: ../share/extensions/eps_input.inx.h:2 +msgid "Encapsulated Postscript" +msgstr "" + +#: ../share/extensions/eps_input.inx.h:3 +msgid "Encapsulated Postscript (*.eps)" +msgstr "" + +#: ../share/extensions/epsi_output.inx.h:1 +#, fuzzy +msgid "EPSI Output" +msgstr "A_mpliar" + +#: ../share/extensions/epsi_output.inx.h:2 +msgid "Encapsulated Postscript Interchange (*.epsi)" +msgstr "" + +#: ../share/extensions/epsi_output.inx.h:3 +msgid "Encapsulated Postscript with a thumbnail" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:1 ../share/extensions/ffms.inx.h:1 +#: ../share/extensions/ffset.inx.h:1 ../share/extensions/ffss.inx.h:1 +#, fuzzy +msgid "Bridge Width" +msgstr "An_cho de página" + +#: ../share/extensions/ffmet.inx.h:2 ../share/extensions/ffms.inx.h:2 +msgid "First String Length" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:3 +msgid "FretFind Multi Length ET" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:4 ../share/extensions/ffms.inx.h:4 +#: ../share/extensions/ffset.inx.h:3 ../share/extensions/ffss.inx.h:3 +msgid "Fretboard Edges" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:5 ../share/extensions/ffms.inx.h:5 +msgid "Last String Length" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:6 ../share/extensions/ffms.inx.h:6 +#: ../share/extensions/ffset.inx.h:4 ../share/extensions/ffss.inx.h:4 +#, fuzzy +msgid "Number of Frets" +msgstr "Número de revoluciones" + +#: ../share/extensions/ffmet.inx.h:7 ../share/extensions/ffms.inx.h:7 +#: ../share/extensions/ffset.inx.h:5 ../share/extensions/ffss.inx.h:5 +#, fuzzy +msgid "Number of Strings" +msgstr "Número de revoluciones" + +#: ../share/extensions/ffmet.inx.h:8 ../share/extensions/ffms.inx.h:8 +#: ../share/extensions/ffset.inx.h:6 ../share/extensions/ffss.inx.h:6 +#, fuzzy +msgid "Nut Width" +msgstr "Ancho:" + +#: ../share/extensions/ffmet.inx.h:9 ../share/extensions/ffms.inx.h:10 +msgid "Perpendicular Distance" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:10 ../share/extensions/ffset.inx.h:7 +msgid "Scale Base (2 for Octave)" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:11 ../share/extensions/ffset.inx.h:9 +msgid "Tones in Scale" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:12 ../share/extensions/ffms.inx.h:12 +#: ../share/extensions/ffset.inx.h:10 ../share/extensions/ffss.inx.h:10 +msgid "px per Unit" +msgstr "" + +#: ../share/extensions/ffms.inx.h:3 +msgid "FretFind Multi Length Scala" +msgstr "" + +#: ../share/extensions/ffms.inx.h:9 ../share/extensions/ffss.inx.h:7 +msgid "Path to Scala *.scl File" +msgstr "" + +#: ../share/extensions/ffms.inx.h:11 +msgid "Tuning (scale step for each string seperated by semicolons)" +msgstr "" + +#: ../share/extensions/ffset.inx.h:2 +msgid "FretFind Single Length ET" +msgstr "" + +#: ../share/extensions/ffset.inx.h:8 ../share/extensions/ffss.inx.h:8 +msgid "Scale Length" +msgstr "" + +#: ../share/extensions/ffss.inx.h:2 +msgid "FretFind Single Length Scala" +msgstr "" + +#: ../share/extensions/ffss.inx.h:9 +msgid "Tuning (Scale step for each string seperated by semicolons)" +msgstr "" + +#: ../share/extensions/handles.inx.h:1 +#, fuzzy +msgid "Draw Handles" +msgstr "Dibujar líneas a mano alzada (F6)" + +#: ../share/extensions/interp.inx.h:1 +#, fuzzy +msgid "Duplicate Endpaths" +msgstr "Duplicar nodo" + +#: ../share/extensions/interp.inx.h:2 +#, fuzzy +msgid "Exponent" +msgstr "Exportar" + +#: ../share/extensions/interp.inx.h:3 +msgid "Interpolate" +msgstr "" + +#: ../share/extensions/interp.inx.h:4 +msgid "Interpolate Style (Experimental)" +msgstr "" + +#: ../share/extensions/interp.inx.h:5 +msgid "Interpolation Method" +msgstr "" + +#: ../share/extensions/interp.inx.h:6 +msgid "Interpolation Steps" +msgstr "" + +#: ../share/extensions/kochify.inx.h:1 +msgid "Kochify" +msgstr "" + +#: ../share/extensions/kochify_load.inx.h:1 +msgid "Kochify (Load)" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:1 +#, fuzzy +msgid "Angle" +msgstr "Ángulo:" + +#: ../share/extensions/lindenmayer.inx.h:2 +msgid "Axiom" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:3 +#, fuzzy +msgid "Lindenmayer" +msgstr "Elevar nodo" + +#: ../share/extensions/lindenmayer.inx.h:4 +msgid "Order" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:5 +#, fuzzy +msgid "Rules" +msgstr "Reglas" + +#: ../share/extensions/lindenmayer.inx.h:6 +#, fuzzy +msgid "Step" +msgstr "Estilo" + +#: ../share/extensions/motion.inx.h:1 +#, fuzzy +msgid "Direction" +msgstr "Selección" + +#: ../share/extensions/motion.inx.h:2 +#, fuzzy +msgid "Magnitude" +msgstr "Magenta:" + +#: ../share/extensions/motion.inx.h:3 +#, fuzzy +msgid "Motion" +msgstr "Resolución:" + +#: ../share/extensions/pdf_output.inx.h:1 +msgid "Adobe PDF (*.pdf)" +msgstr "" + +#: ../share/extensions/pdf_output.inx.h:2 +msgid "Adobe Portable Document Format" +msgstr "" + +#: ../share/extensions/pdf_output.inx.h:3 +#, fuzzy +msgid "PDF Output" +msgstr "A_mpliar" + +#: ../share/extensions/ps_input.inx.h:1 +#, fuzzy +msgid "Postscript" +msgstr "Punto" + +#: ../share/extensions/ps_input.inx.h:2 +msgid "Postscript (*.ps)" +msgstr "" + +#: ../share/extensions/ps_input.inx.h:3 +msgid "Postscript Input" +msgstr "" + +#: ../share/extensions/radiusrand.inx.h:1 +#, fuzzy +msgid "Radius" +msgstr "Radio:" + +#: ../share/extensions/radiusrand.inx.h:2 +#, fuzzy +msgid "Radius Randomize" +msgstr "Elevar nodo" + +#: ../share/extensions/radiusrand.inx.h:3 +msgid "Randomize Control Points" +msgstr "" + +#: ../share/extensions/radiusrand.inx.h:4 +#, fuzzy +msgid "Randomize Nodes" +msgstr "Elevar nodo" + +#: ../share/extensions/rtree.inx.h:1 +#, fuzzy +msgid "Initial Size" +msgstr "Tamaño de mapa de bits" + +#: ../share/extensions/rtree.inx.h:2 +msgid "Minimum Size" +msgstr "" + +#: ../share/extensions/rtree.inx.h:3 +msgid "Random Tree" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:1 +msgid "A diagram created with the program Sketch" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:2 +msgid "Sketch Diagram (*.sk)" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:3 +msgid "Sketch Input" +msgstr "" + +#: ../share/extensions/straightseg.inx.h:1 +msgid "Behavior" +msgstr "" + +#: ../share/extensions/straightseg.inx.h:3 +msgid "Segment Straightener" +msgstr "" + +#: ../share/extensions/summersnight.inx.h:1 +msgid "Summer's Night" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:1 +#: ../share/extensions/svgz_output.inx.h:1 +msgid "Compressed Inkscape SVG (*.svgz)" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:2 +#: ../share/extensions/svgz_output.inx.h:2 +msgid "Inkscape's native file format compressed with GZip" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:3 +#, fuzzy +msgid "SVGZ Input" +msgstr "Entrada" + +#: ../share/extensions/svgz_output.inx.h:3 +#, fuzzy +msgid "SVGZ Output" +msgstr "A_mpliar" + +#: ../share/extensions/txt2svg.inx.h:1 +msgid "ASCII Text" +msgstr "" + +#: ../share/extensions/txt2svg.inx.h:2 +msgid "Text File (*.txt)" +msgstr "" + +#: ../share/extensions/txt2svg.inx.h:3 +#, fuzzy +msgid "Text Input" +msgstr "Entrada" + +#: ../share/extensions/wavy.inx.h:1 +msgid "Calculate first derivative numerically" +msgstr "" + +#: ../share/extensions/wavy.inx.h:2 +msgid "First derivative" +msgstr "" + +#: ../share/extensions/wavy.inx.h:3 +msgid "Function" +msgstr "" + +#: ../share/extensions/wavy.inx.h:4 +msgid "Function Plotter" +msgstr "" + +#: ../share/extensions/wavy.inx.h:5 +msgid "Nodes per period" +msgstr "" + +#: ../share/extensions/wavy.inx.h:6 +msgid "Periods (2*Pi each)" +msgstr "" + +#: ../share/extensions/whirl.inx.h:1 +msgid "Amount of Whirl" +msgstr "" + +#: ../share/extensions/whirl.inx.h:2 +#, fuzzy +msgid "Center X" +msgstr "Centro X:" + +#: ../share/extensions/whirl.inx.h:3 +#, fuzzy +msgid "Center Y" +msgstr "Centro Y:" + +#: ../share/extensions/whirl.inx.h:4 +#, fuzzy +msgid "Direction of Rotation" +msgstr "Bajar la selección al fondo" + +#: ../share/extensions/whirl.inx.h:5 +msgid "Whirl" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:1 +msgid "A popular graphics file format for clipart" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:2 +msgid "Windows Metafile (*.wmf)" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:3 +msgid "Windows Metafile Input" +msgstr "" + +#, fuzzy +#~ msgid "Canvas size:" +#~ msgstr "Tamaño de tipografía:" + +#, fuzzy +#~ msgid "Custom canvas" +#~ msgstr "Personalizar papel" + +#, fuzzy +#~ msgid "Current style" +#~ msgstr "Estilo de contorno" + +#, fuzzy +#~ msgid "Arrange Objects" +#~ msgstr "Objeto" + +#~ msgid "deg" +#~ msgstr "grados" + +#, fuzzy +#~ msgid "" +#~ "%s is not a valid preferences file.\n" +#~ "%s" +#~ msgstr "" +#~ "%s no es un archivo de preferencias válido.\n" +#~ "%s" + +#~ msgid "" +#~ "Inkscape will run with default settings.\n" +#~ "New settings will not be saved." +#~ msgstr "" +#~ "Inkscape se ejecutará con la configuración predeterminada.\n" +#~ "No se guardarán ajustes nuevos." + +#, fuzzy +#~ msgid "_Credits" +#~ msgstr "Coordenadas del cursor" + +#, fuzzy +#~ msgid "Grab sensitivity" +#~ msgstr "Definir como s_ensible" + +#, fuzzy +#~ msgid "Scroll by" +#~ msgstr "Barras de desplazamiento" + +#, fuzzy +#~ msgid "Acceleration" +#~ msgstr "Selección" + +#, fuzzy +#~ msgid "Speed" +#~ msgstr "Rojo:" + +#, fuzzy +#~ msgid "Zoom in/out by" +#~ msgstr "Alejar" + +#, fuzzy +#~ msgid "Transform" +#~ msgstr "Transfor_mar" + +#~ msgid "Rotate _90 deg CW" +#~ msgstr "Rotar _90 grados a la derecha" + +#~ msgid "Rotate 9_0 deg CCW" +#~ msgstr "Rotar 9_0 grados a la izquierda" + +#~ msgid "Flip selection horizontally" +#~ msgstr "Reflejar los objetos seleccionados horizontalmente" + +#~ msgid "Flip selection vertically" +#~ msgstr "Reflejar los objetos seleccionados verticalmente" + +#~ msgid "Edit" +#~ msgstr "Editar" + +#~ msgid "Add" +#~ msgstr "Añadir" + +#~ msgid "" +#~ "Select one path object with selector first, then switch back to node tool." +#~ msgstr "" +#~ "Primero seleccione un trazo con el selector, después vuelva a la " +#~ "herramienta de nodos." + +#, fuzzy +#~ msgid "C_reate" +#~ msgstr "Crear" + +#, fuzzy +#~ msgid "Automatically scale Rows to fit selected objects." +#~ msgstr "OR exclusivo de objetos seleccionados" + +#, fuzzy +#~ msgid "Go to root" +#~ msgstr "Editar" + +#, fuzzy +#~ msgid "X" +#~ msgstr "X:" + +#, fuzzy +#~ msgid "Y" +#~ msgstr "Y:" + +#~ msgid "Sides:" +#~ msgstr "Caras:" + +#~ msgid "R1:" +#~ msgstr "R1:" + +#~ msgid "R2:" +#~ msgstr "R2" + +#~ msgid "ARG1:" +#~ msgstr "ARG1:" + +#~ msgid "ARG2:" +#~ msgstr "ARG2:" + +#~ msgid "Flatsides:" +#~ msgstr "Caras:" + +#, fuzzy +#~ msgid "Radius X:" +#~ msgstr "Radio:" + +#, fuzzy +#~ msgid "Radius Y:" +#~ msgstr "Radio:" + +#, fuzzy +#~ msgid "Start Angle:" +#~ msgstr "Estrella" + +#, fuzzy +#~ msgid "End Angle:" +#~ msgstr "Ángulo:" + +#, fuzzy +#~ msgid "Open:" +#~ msgstr "Abrir _reciente" + +#~ msgid "Expansion:" +#~ msgstr "Expansión:" + +#, fuzzy +#~ msgid "Revolutions:" +#~ msgstr "Revolución:" + +#~ msgid "Argument:" +#~ msgstr "Argumento:" + +#~ msgid "T0:" +#~ msgstr "T0:" + +#~ msgid "RX:" +#~ msgstr "RX:" + +#~ msgid "RY:" +#~ msgstr "RY:" + +#, fuzzy +#~ msgid "Rectangle _Properties" +#~ msgstr "_Propiedades del rectángulo" + +#~ msgid "Star _Properties" +#~ msgstr "_Propiedades de la estrella" + +#, fuzzy +#~ msgid "Ellipse _Properties" +#~ msgstr "_Propiedades del enlace" + +#~ msgid "Spiral _Properties" +#~ msgstr "_Propiedades de la espiral" + +#, fuzzy +#~ msgid "Document Preferences" +#~ msgstr "Inkscape: _Avanzado" + +#, fuzzy +#~ msgid "Extensions Editor" +#~ msgstr "Expansión:" + +#, fuzzy +#~ msgid "Preferences" +#~ msgstr "Inkscape: _Avanzado" + +#, fuzzy +#~ msgid "Layer Editor" +#~ msgstr "Editor XML" + +#, fuzzy +#~ msgid "Text Properties" +#~ msgstr "_Propiedades del rectángulo" + +#, fuzzy +#~ msgid "Transformation" +#~ msgstr "Matriz de transformación" + +#, fuzzy +#~ msgid "_Export..." +#~ msgstr "_Importar..." + +#, fuzzy +#~ msgid "_Document Properties" +#~ msgstr "Opciones del _documento" + +#, fuzzy +#~ msgid "In_kscape Preferences" +#~ msgstr "Inkscape: _Avanzado" + +#, fuzzy +#~ msgid "Select _Original Clone" +#~ msgstr "Seleccion_ar todo" + +#, fuzzy +#~ msgid "Tile" +#~ msgstr "Título:" + +#, fuzzy +#~ msgid "Select A_ll" +#~ msgstr "Seleccion_ar todo" + +#, fuzzy +#~ msgid "Select Non_e" +#~ msgstr "Selección" + +#, fuzzy +#~ msgid "Zoom _In" +#~ msgstr "Aumentar" + +#, fuzzy +#~ msgid "Zoom _Out" +#~ msgstr "Alejar" + +#, fuzzy +#~ msgid "Pre_vious" +#~ msgstr "Zoom anterior" + +#, fuzzy +#~ msgid "Nex_t" +#~ msgstr "Zoom siguien_te" + +#, fuzzy +#~ msgid "Tool Co_ntrols bar" +#~ msgstr "Opciones de la herramienta" + +#, fuzzy +#~ msgid "R_ename Layer..." +#~ msgstr "Elevar nodo" + +#, fuzzy +#~ msgid "D_uplicate Layer" +#~ msgstr "Duplicar nodo" + +#, fuzzy +#~ msgid "_Anchor Layer" +#~ msgstr "Bajar nodo" + +#, fuzzy +#~ msgid "_Delete Layer" +#~ msgstr "Seleccionar" + +#, fuzzy +#~ msgid "Select Ne_xt Layer" +#~ msgstr "Cambiar a la ventana de documento siguiente" + +#, fuzzy +#~ msgid "Select Pre_vious Layer" +#~ msgstr "Cambiar a la ventana de documento anterior" + +#, fuzzy +#~ msgid "Select To_p Layer" +#~ msgstr "Seleccionar impresora" + +#, fuzzy +#~ msgid "Move to Ne_w Layer" +#~ msgstr "Cambiar a la ventana de documento anterior" + +#, fuzzy +#~ msgid "Move to Ne_xt Layer" +#~ msgstr "Cambiar a la ventana de documento siguiente" + +#, fuzzy +#~ msgid "Move to Pre_vious Layer" +#~ msgstr "Cambiar a la ventana de documento anterior" + +#, fuzzy +#~ msgid "Move to To_p Layer" +#~ msgstr "Cambiar a la ventana de documento anterior" + +#, fuzzy +#~ msgid "Move to B_ottom Layer" +#~ msgstr "_Bajar al fondo" + +#, fuzzy +#~ msgid "_Trace Bitmap..." +#~ msgstr "Imprimir como mapa de bits" + +#, fuzzy +#~ msgid "_Put Text on Path" +#~ msgstr "Convierte el contorno seleccionado en trazo" + +#, fuzzy +#~ msgid "_Remove Text from Path" +#~ msgstr "Convierte el contorno seleccionado en trazo" + +#~ msgid "Arc" +#~ msgstr "Arco" + +#, fuzzy +#~ msgid "Freehand" +#~ msgstr "A mano alzada y pluma" + +#, fuzzy +#~ msgid "Corners" +#~ msgstr "Esquinas:" + +#, fuzzy +#~ msgid "Delete" +#~ msgstr "_Eliminar" + +#, fuzzy +#~ msgid "Join" +#~ msgstr "Unión:" + +#, fuzzy +#~ msgid "Delete Segment" +#~ msgstr "Suprimir los nodos seleccionados" + +#, fuzzy +#~ msgid "Break" +#~ msgstr "Negro:" + +#, fuzzy +#~ msgid "Symmetric" +#~ msgstr "simétrico" + +#, fuzzy +#~ msgid "New" +#~ msgstr "_Nuevo" + +#, fuzzy +#~ msgid "Save" +#~ msgstr "_Guardar" + +#, fuzzy +#~ msgid "Save As..." +#~ msgstr "G_uardar como..." + +#, fuzzy +#~ msgid "Import..." +#~ msgstr "_Importar..." + +#, fuzzy +#~ msgid "Export..." +#~ msgstr "Exportar" + +#, fuzzy +#~ msgid "Print..." +#~ msgstr "_Imprimir" + +#, fuzzy +#~ msgid "Global Inkscape preferences (Shift+Ctrl+P)" +#~ msgstr "Opciones globales de Inkscape" + +#, fuzzy +#~ msgid "Undo" +#~ msgstr "_Deshacer" + +#, fuzzy +#~ msgid "Redo" +#~ msgstr "_Rehacer" + +#, fuzzy +#~ msgid "Cut" +#~ msgstr "Cor_tar" + +#, fuzzy +#~ msgid "Copy" +#~ msgstr "_Copiar" + +#, fuzzy +#~ msgid "Duplicate selected object(s) (Ctrl+D)" +#~ msgstr "Duplicar los objetos seleccionados" + +#, fuzzy +#~ msgid "Clone selected object (Alt+D)" +#~ msgstr "Duplicar los objetos seleccionados" + +#, fuzzy +#~ msgid "Zoom in (+)" +#~ msgstr "Aumentar" + +#, fuzzy +#~ msgid "Zoom out (-)" +#~ msgstr "Alejar" + +#, fuzzy +#~ msgid "Zoom to 1:1 (100%) (1)" +#~ msgstr "Zoom a 1:1" + +#, fuzzy +#~ msgid "Zoom to 1:2 (50%) (2)" +#~ msgstr "Zoom a 1:2" + +#, fuzzy +#~ msgid "Zoom to 2:1 (200%) (0)" +#~ msgstr "_Zoom a 2:1" + +#, fuzzy +#~ msgid "Zoom to fit selection in window (3)" +#~ msgstr "Ajustar la selección a la ventana" + +#, fuzzy +#~ msgid "Zoom to fit drawing in window (4)" +#~ msgstr "Ajustar el dibujo a la ventana" + +#, fuzzy +#~ msgid "Zoom to fit page in window (5)" +#~ msgstr "Ajustar la página a la ventana" + +#, fuzzy +#~ msgid "Zoom to fit page width in window (6)" +#~ msgstr "Ajustar la anchura de la página a la ventana" + +#, fuzzy +#~ msgid "Fill and Stroke dialog (Shift+Ctrl+F)" +#~ msgstr "_Relleno y contorno" + +#, fuzzy +#~ msgid "Group selected objects (Ctrl+G)" +#~ msgstr "Agrupar los objetos seleccionados" + +#, fuzzy +#~ msgid "Ungroup selected group(s) (Ctrl+U)" +#~ msgstr "Desagrupar grupo(s) seleccionado(s)" + +#, fuzzy +#~ msgid "Raise selection up one step (PgUp)" +#~ msgstr "Elevar la selección un nivel" + +#, fuzzy +#~ msgid "Lower selection down one step (PgDn)" +#~ msgstr "Bajar la selección un nivel" + +#, fuzzy +#~ msgid "Raise selection to top (Home)" +#~ msgstr "Poner la selección al frente" + +#, fuzzy +#~ msgid "Lower selection to bottom (End)" +#~ msgstr "Bajar la selección al fondo" + +#, fuzzy +#~ msgid "Move selection to new layer" +#~ msgstr "Bajar la selección un nivel" + +#, fuzzy +#~ msgid "Move selection to next layer" +#~ msgstr "Bajar la selección un nivel" + +#, fuzzy +#~ msgid "Move selection to previous layer" +#~ msgstr "Cambiar a la ventana de documento anterior" + +#, fuzzy +#~ msgid "Move selection to top layer" +#~ msgstr "Poner la selección al frente" + +#, fuzzy +#~ msgid "Move selection to bottom layer" +#~ msgstr "Bajar la selección al fondo" + +#, fuzzy +#~ msgid "Rotate selection 90° clockwise (Shift+Ctrl+Right)" +#~ msgstr "Rotar el objeto 90 grados a la derecha" + +#, fuzzy +#~ msgid "Rotate selection 90° counter-clockwise (Shift+Ctrl+Left)" +#~ msgstr "Rotar el objeto 90 grados a la izquierda" + +#, fuzzy +#~ msgid "Flip selection horizontally (H)" +#~ msgstr "Reflejar los objetos seleccionados horizontalmente" + +#, fuzzy +#~ msgid "Flip selection vertically (V)" +#~ msgstr "Reflejar los objetos seleccionados verticalmente" + +#, fuzzy +#~ msgid "Align and Distribute dialog (Shift+Ctrl+A)" +#~ msgstr "_Alinear y distribuir" + +#, fuzzy +#~ msgid "Convert selected object(s) to path(s) (Shift+Ctrl+C)" +#~ msgstr "Convierte el objeto seleccionado en trazos" + +#, fuzzy +#~ msgid "Convert selected stroke(s) to path(s) (Ctrl+Alt+C)" +#~ msgstr "Convierte el contorno seleccionado en trazo" + +#~ msgid "Cl_eanup" +#~ msgstr "Limpi_eza" + +#, fuzzy +#~ msgid "Text and Font dialog (Shift+Ctrl+T)" +#~ msgstr "Texto y tipografía" + +#, fuzzy +#~ msgid "Node tool" +#~ msgstr "Sin herramienta activa" + +#, fuzzy +#~ msgid "Zoom tool" +#~ msgstr "Alejar" + +#~ msgid "Rectangle tool" +#~ msgstr "Herramienta rectángulo" + +#~ msgid "Arc tool" +#~ msgstr "Herramienta arco" + +#~ msgid "Star tool" +#~ msgstr "Herramienta estrella" + +#~ msgid "Spiral tool" +#~ msgstr "Herramienta espiral" + +#, fuzzy +#~ msgid "Freehand tool" +#~ msgstr "A mano alzada y pluma" + +#, fuzzy +#~ msgid "Pen tool" +#~ msgstr "Herramienta rectángulo" + +#, fuzzy +#~ msgid "Calligraphy tool" +#~ msgstr "Caligrafía" + +#, fuzzy +#~ msgid "Text tool" +#~ msgstr "Zoom siguiente" + +#, fuzzy +#~ msgid "Dropper tool" +#~ msgstr "Cuentagotas" + +#, fuzzy +#~ msgid "When scaling rectangles, scale radii of rounded corners" +#~ msgstr "Coordenada vertical de la selección" + +#, fuzzy +#~ msgid "Delete segment between two nodes" +#~ msgstr "Suprimir los nodos seleccionados" + +#, fuzzy +#~ msgid "URI:" +#~ msgstr "URL:" + +#, fuzzy +#~ msgid "Select All in All Layers" +#~ msgstr "Seleccionar" + +#, fuzzy +#~ msgid "Invert Selection" +#~ msgstr "Selección" + +#, fuzzy +#~ msgid "Clean up selected path(s)" +#~ msgstr "Reducir los trazos seleccionados" + +#, fuzzy +#~ msgid "_Scripts..." +#~ msgstr "_Imprimir" + +#, fuzzy +#~ msgid "Align and Distribute" +#~ msgstr "_Alinear y distribuir" + +#, fuzzy +#~ msgid "Align and Distribute Dialog" +#~ msgstr "_Alinear y distribuir" + +#, fuzzy +#~ msgid "Export Dialog" +#~ msgstr "Exportar área" + +#, fuzzy +#~ msgid "Fill and Stroke Dialog" +#~ msgstr "_Relleno y contorno" + +#, fuzzy +#~ msgid "Find Dialog" +#~ msgstr "_Mostar/ocultar ventanas de diálogo" + +#, fuzzy +#~ msgid "Inkscape Preferences" +#~ msgstr "Inkscape: _Avanzado" + +#, fuzzy +#~ msgid "Inkscape Preferences Dialog" +#~ msgstr "Inkscape: _Avanzado" + +#, fuzzy +#~ msgid "Layer Editor Dialog" +#~ msgstr "Poner al fren_te" + +#, fuzzy +#~ msgid "Text Properties Dialog" +#~ msgstr "_Propiedades del rectángulo" + +#, fuzzy +#~ msgid "Transformation Dialog" +#~ msgstr "Transfor_mar" + +#, fuzzy +#~ msgid "Tree Editor" +#~ msgstr "Editor XML" + +#, fuzzy +#~ msgid "XML Editor Dialog" +#~ msgstr "Editor XML" + +#, fuzzy +#~ msgid "Row height:" +#~ msgstr "Alto:" + +#, fuzzy +#~ msgid "Column width:" +#~ msgstr "Círculo" + +#~ msgid "Creating anchor at (%g,%g)" +#~ msgstr "Creando ancla en (%g,%g)" + +#, fuzzy +#~ msgid "" +#~ "Click to pick fill color, Shift+click to pick stroke color. " +#~ "Drag to pick the average color of an area." +#~ msgstr "" +#~ "Haga clic para seleccionar un color, clic y arrastre para seleccionar la " +#~ "media de color de un área." + +#, fuzzy +#~ msgid "Skew: %0.2f%% x %0.2f%%" +#~ msgstr "Inclinar %0.2f%c %0.2f%c" + +#~ msgid "elementsofdesign.svg" +#~ msgstr "elementsofdesign.svg" + +#~ msgid "tipsandtricks.svg" +#~ msgstr "tipsandtricks.svg" + +#, fuzzy +#~ msgid "Inkscape" +#~ msgstr "Inkscape" + +#~ msgid "Left side of aligned objects to left side of anchor" +#~ msgstr "Lado izquierdo de los objetos alineados la izquierda del ancla" + +#~ msgid "Right side of aligned objects to right side of anchor" +#~ msgstr "Lado derecho de los objetos alineados a la derecha del ancla" + +#~ msgid "Top of aligned objects to top of anchor" +#~ msgstr "Lado superior de los objetos alineados por encima del ancla" + +#~ msgid "Bottom of aligned objects to bottom of anchor" +#~ msgstr "Lado inferior de los objetos alineados por debajo del ancla" + +#~ msgid "Distribute top sides of objects at even distances" +#~ msgstr "Distribuir el lado superior de los objetos a la misma distancia" + +#, fuzzy +#~ msgid "Alternate sign" +#~ msgstr "Saturación:" + +#, fuzzy +#~ msgid "Minor grid line color:" +#~ msgstr "Color de las líneas guía" + +#~ msgid "Grid color" +#~ msgstr "Color de la rejilla" + +#, fuzzy +#~ msgid "Grid emphasis color" +#~ msgstr "Color de la rejilla" + +#, fuzzy +#~ msgid "Background (also for export):" +#~ msgstr "Fondo (también para exportación):" + +#, fuzzy +#~ msgid "Picking colors:" +#~ msgstr "Color del resaltado:" + +#~ msgid "Fill style" +#~ msgstr "Estilo de relleno" + +#, fuzzy +#~ msgid "Fill:" +#~ msgstr "Relleno" + +#, fuzzy +#~ msgid "winding" +#~ msgstr "Renderizado" + +#, fuzzy +#~ msgid "alternating" +#~ msgstr "Saturación:" + +#, fuzzy +#~ msgid "Update Properties" +#~ msgstr "_Propiedades del elemento" + +#, fuzzy +#~ msgid "Label invalid" +#~ msgstr "El ID no es válido" + +#, fuzzy +#~ msgid "" +#~ "You cannot group objects from different groups or layers." +#~ msgstr "No puede agrupar objetos de diferentes grupos o capas." + +#, fuzzy +#~ msgid "Switch to the previous layer in the document" +#~ msgstr "Cambiar a la ventana de documento anterior" + +#, fuzzy +#~ msgid "executable" +#~ msgstr "Rectángulo" + +#, fuzzy +#~ msgid "file" +#~ msgstr "_Archivo" + +#, fuzzy +#~ msgid "extension" +#~ msgstr "Expansión:" + +#, fuzzy +#~ msgid "path" +#~ msgstr "T_razo" + +#, fuzzy +#~ msgid "absolute" +#~ msgstr "Valor" + +#~ msgid "Could not create sodipodi-svg-doc factory" +#~ msgstr "No se ha podido crear un documento de la fábrica sodipodi-svg-doc" + +#~ msgid "Autodetect" +#~ msgstr "Autodetectar" + +#~ msgid "Make s_ensitive" +#~ msgstr "Definir como s_ensible" + +#~ msgid "Make i_nsensitive" +#~ msgstr "Definir como i_nsensible" + +#, fuzzy +#~ msgid "Layer Properties" +#~ msgstr "_Propiedades de la estrella" + +#, fuzzy +#~ msgid "Select object(s) to tile." +#~ msgstr "Seleccione objetos para bajar." + +#, fuzzy +#~ msgid "Apply" +#~ msgstr "Aplicar a:" + +#~ msgid "Sensitive" +#~ msgstr "Sensible" + +#~ msgid "Active" +#~ msgstr "Activo" + +#~ msgid "Printable" +#~ msgstr "Imprimible" + +#, fuzzy +#~ msgid "Prefer bitmap (XPM) icons to SVG ones" +#~ msgstr "Preferir iconos de mapa de bits (XPM) a los SVG" + +#~ msgid "Trace" +#~ msgstr "Traza" + +#, fuzzy +#~ msgid "Error writing %s: %s" +#~ msgstr "Ha ocurrido un error al escribir %s: %s" + +#~ msgid "Untitled" +#~ msgstr "Sin título" + +#~ msgid "Document Name:" +#~ msgstr "Nombre del documento:" + +#~ msgid "Image URI:" +#~ msgstr "URI de la imagen:" + +#~ msgid "Visible" +#~ msgstr "Visible" + +#, fuzzy +#~ msgid "Drag to paint a calligraphic stroke." +#~ msgstr "Arrastre para dibujar una línea caligráfica." + +#, fuzzy +#~ msgid "Flatness:" +#~ msgstr "Caras:" + +#, fuzzy +#~ msgid "Other" +#~ msgstr "Metro" + +#, fuzzy +#~ msgid "Trace: Selected object is not an image" +#~ msgstr "El objeto seleccionado no es un trazo, no se puede perfilar." + +#, fuzzy +#~ msgid "object" +#~ msgstr "Objeto" + +#, fuzzy +#~ msgid "user space" +#~ msgstr "Unidad del espacio de usuario" + +#, fuzzy +#~ msgid "Coordinates:" +#~ msgstr "Coordenadas del cursor" + +#, fuzzy +#~ msgid "" +#~ "Distribute centers of objects of objects at even distances horizontally" +#~ msgstr "" +#~ "Distribuir el centro de los objetos a distancias horizontales equivalentes" + +#~ msgid "Alignment:" +#~ msgstr "Alineación:" + +#~ msgid "Text and font" +#~ msgstr "Texto y tipografía" + +#~ msgid "Draw arc: %s x %s" +#~ msgstr "Dibujar arco: %s x %s" + +#~ msgid "All shape tools" +#~ msgstr "Todas las herramientas de formas" + +#~ msgid "Draw rectangle: %s x %s" +#~ msgstr "Trazar rectángulo: %s x %s" + +#~ msgid "Move by %s, %s" +#~ msgstr "Mover %s, %s" + +#~ msgid "Scale %0.2f%%, %0.2f%%" +#~ msgstr "Escala %0.2f%%, %0.2f%%" + +#~ msgid "Rotate by %0.2f deg" +#~ msgstr "Rotar %0.2f grados" + +#~ msgid "Center at (%s,%s)" +#~ msgstr "Centro en (%s,%s)" + +#~ msgid "Draw spiral at (%s,%s)" +#~ msgstr "Trazar espiral en (%s,%s)" + +#~ msgid "Draw polygon at (%s,%s)" +#~ msgstr "Trazar polígono en (%s,%s)" + +#~ msgid "Draw star at (%s,%s)" +#~ msgstr "Trazar estrella en (%s,%s)" + +#, fuzzy +#~ msgid "Active group" +#~ msgstr "Activo" + +#~ msgid "No filename specified. Unable to save." +#~ msgstr "No se especificó un nombre de archivo. Imposible guardar." + +#, fuzzy +#~ msgid "typeset object" +#~ msgstr "Objetos seleccionados" + +#, fuzzy +#~ msgid "" +#~ "You cannot build a typeset from objects of different groups or layers." +#~ msgstr "No puede combinar objetos de diferentes grupos o capas." + +#, fuzzy +#~ msgid "Pattern Fill" +#~ msgstr "Patrón:" + +#~ msgid "Snap to grid" +#~ msgstr "Ajustar a la rejilla" + +#~ msgid "Snap to guides" +#~ msgstr "Ajustar a las guías" + +#, fuzzy +#~ msgid "_Menu" +#~ msgstr "Limpi_eza" + +#, fuzzy +#~ msgid "Snap points to the grid" +#~ msgstr "Ajustar a la rejilla" + +#, fuzzy +#~ msgid "Rect" +#~ msgstr "Rectángulo" + +#, fuzzy +#~ msgid "Rects" +#~ msgstr "Objeto" + +#~ msgid "meters" +#~ msgstr "metros" + +#~ msgid "Pre_v zoom" +#~ msgstr "Zoom ante_rior" + +#~ msgid "Userspace unit" +#~ msgstr "Unidad del espacio de usuario" + +#~ msgid "User" +#~ msgstr "Usuario" + +#~ msgid "Userspace units" +#~ msgstr "Unidades de espacio de usuario" + +#, fuzzy +#~ msgid "Ru_lers" +#~ msgstr "Reglas" + +#, fuzzy +#~ msgid "Show or hide rulers" +#~ msgstr "Mostrar/ocultar reglas" + +#, fuzzy +#~ msgid "Show or hide scrollbars" +#~ msgstr "Mostrar/ocultar barras de desplazamiento" + +#, fuzzy +#~ msgid "Click to pick, click and drag to pick the average color of an area." +#~ msgstr "" +#~ "Haga clic para seleccionar un color, clic y arrastre para seleccionar la " +#~ "media de color de un área." + +#~ msgid "Corner radius to half-width ratio" +#~ msgstr "Radio de la esquina a relación de mitad de ancho" + +#~ msgid "Corner radius to half-height ratio" +#~ msgstr "Radio de la esquina a relación de mitad de alto" + +#, fuzzy +#~ msgid "_New Window" +#~ msgstr "_Nueva vista" + +#~ msgid "Mode:" +#~ msgstr "Modo:" + +#~ msgid "RGB Colorspace" +#~ msgstr "Espacio de colores RGB" + +#~ msgid "CMYK Colorspace" +#~ msgstr "Espacio de colores CMYK" + +#~ msgid "Get from dropper" +#~ msgstr "Obtener del cuentagotas" + +#~ msgid "Alpha:" +#~ msgstr "Alfa:" + +#~ msgid "Value:" +#~ msgstr "Valor:" + +#~ msgid "Stroke settings" +#~ msgstr "Opciones de contorno" + +#~ msgid "Unable to import image '%s': %s" +#~ msgstr "No se puede importar la imagen '%s': %s" + +#~ msgid "Item properties" +#~ msgstr "Propiedades del elemento" + +#~ msgid "Autoraise Dialogs" +#~ msgstr "Mostrar diálogos de confirmación" + +#~ msgid "Quit" +#~ msgstr "Salir" + +#~ msgid "Cut the bottom path into pieces" +#~ msgstr "Cortar el trazo del fondo en pedazos" + +#~ msgid "Combine multiple paths" +#~ msgstr "Combinar múltiples trazos" + +#~ msgid "Fullscreen" +#~ msgstr "Pantalla completa" + +#, fuzzy +#~ msgid "New View" +#~ msgstr "_Nueva vista" + +#~ msgid "Fill and stroke settings" +#~ msgstr "Opciones de contorno y relleno" + +#~ msgid "Object transformations" +#~ msgstr "Transformaciones de objeto" + +#~ msgid "Align and distribute objects" +#~ msgstr "Alinear y distribuir objetos" + +#~ msgid "Text editing and font settings" +#~ msgstr "Propiedades de edición de texto y tipografía" + +#, fuzzy +#~ msgid "Display help for Keys and Mouse" +#~ msgstr "_Teclado y ratón" + +#, fuzzy +#~ msgid "Tutorial for the Advanced" +#~ msgstr "tutorial-advanced.svg" + +#~ msgid "Fill Rule" +#~ msgstr "Regla de relleno" + +#~ msgid "Tool has no options" +#~ msgstr "La herramienta no tiene opciones" + +#~ msgid "Use the extension of the file to choose a filetype" +#~ msgstr "Utilizar la extensión del archivo para elegir el tipo de archivo" + +#~ msgid "Roundness ratio for x:" +#~ msgstr "Radio de curvatura para x:" + +#~ msgid "Roundness ratio for y:" +#~ msgstr "Radio de curvatura para y:" + +#~ msgid "Visual transformation" +#~ msgstr "Transformación visual" + +#~ msgid "Show content" +#~ msgstr "Mostrar contenido" + +#~ msgid "Selected object has no curve, cannot outline." +#~ msgstr "El objeto seleccionado no tiene curva, no se puede perfilar." + +#~ msgid "Outline of object could not be computed." +#~ msgstr "No se pudo calcular el perfil del objeto." + +#~ msgid "Flat Sided" +#~ msgstr "Lados planos" + +#~ msgid "Inkscape _Options" +#~ msgstr "_Opciones de Inkscape" + +#~ msgid "Tool Optio_ns" +#~ msgstr "Opcio_nes de herramienta" + +#~ msgid "gradientUnits" +#~ msgstr "Unidades de gradiente" + +#~ msgid "gradientSpread" +#~ msgstr "Separación de gradiente" + +#~ msgid "nonzero" +#~ msgstr "no cero" + +#~ msgid "evenodd" +#~ msgstr "parimpar" diff --git a/po/et.po b/po/et.po new file mode 100644 index 000000000..e1354404d --- /dev/null +++ b/po/et.po @@ -0,0 +1,10370 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR Free Software Foundation, Inc. +# Lauris Kaplinski , 2000 +# +msgid "" +msgstr "" +"Project-Id-Version: sodipodi 0.18\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2005-12-04 11:51-0800\n" +"PO-Revision-Date: 2000-04-08 16:21+0200\n" +"Last-Translator: Lauris Kaplinski \n" +"Language-Team: Estonian\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../inkscape.desktop.in.h:1 +msgid "Create and edit Scalable Vector Graphics images" +msgstr "" + +#: ../inkscape.desktop.in.h:2 +msgid "Inkscape SVG Vector Illustrator" +msgstr "" + +#: ../../po/../src/arc-context.cpp:350 +msgid "" +"Ctrl: make circle or integer-ratio ellipse, snap arc/segment angle" +msgstr "" + +#: ../../po/../src/arc-context.cpp:351 ../../po/../src/rect-context.cpp:388 +msgid "Shift: draw around the starting point" +msgstr "" + +#: ../../po/../src/arc-context.cpp:413 +#: ../../po/../src/connector-context.cpp:493 +#: ../../po/../src/dyna-draw-context.cpp:506 +#: ../../po/../src/pen-context.cpp:329 ../../po/../src/pencil-context.cpp:208 +#: ../../po/../src/rect-context.cpp:452 ../../po/../src/spiral-context.cpp:421 +#: ../../po/../src/star-context.cpp:427 +msgid "Current layer is hidden. Unhide it to be able to draw on it." +msgstr "" + +#: ../../po/../src/arc-context.cpp:417 +#: ../../po/../src/connector-context.cpp:497 +#: ../../po/../src/dyna-draw-context.cpp:510 +#: ../../po/../src/pen-context.cpp:336 ../../po/../src/pencil-context.cpp:212 +#: ../../po/../src/rect-context.cpp:456 ../../po/../src/spiral-context.cpp:426 +#: ../../po/../src/star-context.cpp:431 +msgid "Current layer is locked. Unlock it to be able to draw on it." +msgstr "" + +#: ../../po/../src/arc-context.cpp:496 +#, c-format +msgid "" +"Ellipse: %s × %s; with Ctrl to make circle or integer-" +"ratio ellipse; with Shift to draw around the starting point" +msgstr "" + +#: ../../po/../src/connector-context.cpp:518 +#, fuzzy +msgid "Creating new connector" +msgstr "Shrift" + +#: ../../po/../src/connector-context.cpp:939 +msgid "Finishing connector" +msgstr "" + +#: ../../po/../src/connector-context.cpp:1108 +msgid "Connection point: click or drag to create a new connector" +msgstr "" + +#: ../../po/../src/connector-context.cpp:1185 +msgid "Connector endpoint: drag to reroute or connect to new shapes" +msgstr "" + +#: ../../po/../src/connector-context.cpp:1278 +#, fuzzy +msgid "Select at least one non-connector object." +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/desktop-events.cpp:238 +#, c-format +msgid "%s at %s" +msgstr "" + +#. TRANSLATORS: This string appears when double-clicking on a guide. +#. This is the distance by which the guide is to be moved. +#: ../../po/../src/desktop-events.cpp:277 +#, fuzzy +msgid " relative by " +msgstr "Lehekülg" + +#. TRANSLATORS: This string appears when double-clicking on a guide. +#. This is the target location where the guide is to be moved. +#: ../../po/../src/desktop-events.cpp:282 +#: ../../po/../src/desktop-events.cpp:395 +#, fuzzy +msgid " absolute to " +msgstr "Lehekülg" + +#. create dialog +#: ../../po/../src/desktop-events.cpp:348 +msgid "Guideline" +msgstr "" + +#: ../../po/../src/desktop-events.cpp:432 +#, fuzzy, c-format +msgid "Move %s" +msgstr "Punktiredaktor" + +#: ../../po/../src/desktop.cpp:678 +msgid "No previous zoom." +msgstr "" + +#: ../../po/../src/desktop.cpp:703 +msgid "No next zoom." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:182 +#, fuzzy +msgid "Nothing selected." +msgstr "Grupeerib valitud objektid" + +#: ../../po/../src/dialogs/clonetiler.cpp:188 +msgid "More than one object selected." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:195 +#, c-format +msgid "Object has %d tiled clones." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:200 +msgid "Object has no tiled clones." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:865 +#, fuzzy +msgid "Select one object whose tiled clones to unclump." +msgstr "Tee jooneks" + +#: ../../po/../src/dialogs/clonetiler.cpp:916 +#, fuzzy +msgid "Select one object whose tiled clones to remove." +msgstr "Tee jooneks" + +#: ../../po/../src/dialogs/clonetiler.cpp:984 +#: ../../po/../src/selection-chemistry.cpp:1774 +#, fuzzy +msgid "Select an object to clone." +msgstr "Tee jooneks" + +#: ../../po/../src/dialogs/clonetiler.cpp:990 +#: ../../po/../src/selection-chemistry.cpp:1780 +msgid "" +"If you want to clone several objects, group them and clone the " +"group." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1484 +msgid "Per row:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1497 +#, fuzzy +msgid "Per column:" +msgstr "Grupeerib valitud objektid" + +#: ../../po/../src/dialogs/clonetiler.cpp:1505 +#, fuzzy +msgid "Randomize:" +msgstr "Grupeerib valitud objektid" + +#: ../../po/../src/dialogs/clonetiler.cpp:1656 +msgid "_Symmetry" +msgstr "" + +#. TRANSLATORS: For the following 17 symmetry groups, see +#. * http://www.bib.ulb.ac.be/coursmath/doc/17.htm (visual examples); +#. * http://www.clarku.edu/~djoyce/wallpaper/seventeen.html (English vocabulary); or +#. * http://membres.lycos.fr/villemingerard/Geometri/Sym1D.htm (French vocabulary). +#. +#: ../../po/../src/dialogs/clonetiler.cpp:1664 +msgid "Select one of the 17 symmetry groups for the tiling" +msgstr "" + +#. TRANSLATORS: "translation" means "shift" / "displacement" here. +#: ../../po/../src/dialogs/clonetiler.cpp:1675 +msgid "P1: simple translation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1676 +msgid "P2: 180° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1677 +msgid "PM: reflection" +msgstr "" + +#. TRANSLATORS: "glide reflection" is a reflection and a translation combined. +#. For more info, see http://mathforum.org/sum95/suzanne/symsusan.html +#: ../../po/../src/dialogs/clonetiler.cpp:1680 +msgid "PG: glide reflection" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1681 +msgid "CM: reflection + glide reflection" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1682 +msgid "PMM: reflection + reflection" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1683 +msgid "PMG: reflection + 180° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1684 +msgid "PGG: glide reflection + 180° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1685 +msgid "CMM: reflection + reflection + 180° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1686 +msgid "P4: 90° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1687 +msgid "P4M: 90° rotation + 45° reflection" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1688 +msgid "P4G: 90° rotation + 90° reflection" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1689 +msgid "P3: 120° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1690 +msgid "P31M: reflection + 120° rotation, dense" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1691 +msgid "P3M1: reflection + 120° rotation, sparse" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1692 +msgid "P6: 60° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1693 +msgid "P6M: reflection + 60° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1721 +msgid "S_hift" +msgstr "" + +#. TRANSLATORS: "shift" means: the tiles will be shifted (offset) horizontally by this amount +#: ../../po/../src/dialogs/clonetiler.cpp:1731 +#, no-c-format +msgid "Shift X:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1739 +#, no-c-format +msgid "Horizontal shift per row (in % of tile width)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1747 +#, no-c-format +msgid "Horizontal shift per column (in % of tile width)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1754 +msgid "Randomize the horizontal shift by this percentage" +msgstr "" + +#. TRANSLATORS: "shift" means: the tiles will be shifted (offset) vertically by this amount +#: ../../po/../src/dialogs/clonetiler.cpp:1764 +#, no-c-format +msgid "Shift Y:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1772 +#, no-c-format +msgid "Vertical shift per row (in % of tile height)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1780 +#, no-c-format +msgid "Vertical shift per column (in % of tile height)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1787 +msgid "Randomize the vertical shift by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1795 +msgid "Exponent:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1802 +msgid "Whether rows are spaced evenly (1), converge (<1) or diverge (>1)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1809 +msgid "Whether columns are spaced evenly (1), converge (<1) or diverge (>1)" +msgstr "" + +#. TRANSLATORS: "Alternate" is a verb here +#: ../../po/../src/dialogs/clonetiler.cpp:1817 +#: ../../po/../src/dialogs/clonetiler.cpp:1907 +#: ../../po/../src/dialogs/clonetiler.cpp:1966 +#: ../../po/../src/dialogs/clonetiler.cpp:2022 +#: ../../po/../src/dialogs/clonetiler.cpp:2153 +msgid "Alternate:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1823 +msgid "Alternate the sign of shifts for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1828 +msgid "Alternate the sign of shifts for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1837 +#, fuzzy +msgid "Sc_ale" +msgstr "Skaala" + +#: ../../po/../src/dialogs/clonetiler.cpp:1845 +#, fuzzy +msgid "Scale X:" +msgstr "Lehekülg" + +#: ../../po/../src/dialogs/clonetiler.cpp:1853 +#, no-c-format +msgid "Horizontal scale per row (in % of tile width)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1861 +#, no-c-format +msgid "Horizontal scale per column (in % of tile width)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1868 +msgid "Randomize the horizontal scale by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1876 +#, fuzzy +msgid "Scale Y:" +msgstr "Lehekülg" + +#: ../../po/../src/dialogs/clonetiler.cpp:1884 +#, no-c-format +msgid "Vertical scale per row (in % of tile height)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1892 +#, no-c-format +msgid "Vertical scale per column (in % of tile height)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1899 +msgid "Randomize the vertical scale by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1913 +msgid "Alternate the sign of scales for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1918 +msgid "Alternate the sign of scales for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1927 +#, fuzzy +msgid "_Rotation" +msgstr "_Selektsioon" + +#: ../../po/../src/dialogs/clonetiler.cpp:1935 +#, fuzzy +msgid "Angle:" +msgstr "Lehekülg" + +#: ../../po/../src/dialogs/clonetiler.cpp:1943 +#, no-c-format +msgid "Rotate tiles by this angle for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1951 +#, no-c-format +msgid "Rotate tiles by this angle for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1958 +msgid "Randomize the rotation angle by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1972 +msgid "Alternate the rotation direction for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1977 +msgid "Alternate the rotation direction for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1985 +msgid "_Opacity" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1993 +msgid "Fade out:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2000 +msgid "Decrease tile opacity by this percentage for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2007 +msgid "Decrease tile opacity by this percentage for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2014 +msgid "Randomize the tile opacity by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2028 +msgid "Alternate the sign of opacity change for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2033 +msgid "Alternate the sign of opacity change for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2041 +#, fuzzy +msgid "Co_lor" +msgstr "Uus aken" + +#: ../../po/../src/dialogs/clonetiler.cpp:2046 +msgid "Initial color: " +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2050 +msgid "Initial color of tiled clones" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2050 +msgid "" +"Initial color for clones (works only if the original has unset fill or " +"stroke)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2065 +msgid "H:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2072 +msgid "Change the tile hue by this percentage for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2079 +msgid "Change the tile hue by this percentage for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2086 +msgid "Randomize the tile hue by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2095 +msgid "S:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2102 +msgid "Change the color saturation by this percentage for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2109 +msgid "Change the color saturation by this percentage for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2116 +msgid "Randomize the color saturation by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2124 +msgid "L:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2131 +msgid "Change the color lightness by this percentage for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2138 +msgid "Change the color lightness by this percentage for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2145 +msgid "Randomize the color lightness by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2159 +msgid "Alternate the sign of color changes for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2164 +msgid "Alternate the sign of color changes for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2172 +#, fuzzy +msgid "_Trace" +msgstr "_Import" + +#: ../../po/../src/dialogs/clonetiler.cpp:2179 +msgid "Trace the drawing under the tiles" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2183 +msgid "" +"For each clone, pick a value from the drawing in that clone's location and " +"apply it to the clone" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2197 +msgid "1. Pick from the drawing:" +msgstr "" + +#. ----Hbox2 +#: ../../po/../src/dialogs/clonetiler.cpp:2208 +#: ../../po/../src/dialogs/clonetiler.cpp:2355 +#: ../../po/../src/ui/dialog/tracedialog.cpp:445 +#, fuzzy +msgid "Color" +msgstr "Uus aken" + +#: ../../po/../src/dialogs/clonetiler.cpp:2209 +msgid "Pick the visible color and opacity" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2216 +#: ../../po/../src/dialogs/clonetiler.cpp:2365 +#: ../share/extensions/dropshadow.inx.h:3 +msgid "Opacity" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2217 +msgid "Pick the total accumulated opacity" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2224 +msgid "R" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2225 +msgid "Pick the Red component of the color" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2232 +msgid "G" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2233 +msgid "Pick the Green component of the color" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2240 +msgid "B" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2241 +msgid "Pick the Blue component of the color" +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2250 +msgid "clonetiler|H" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2251 +msgid "Pick the hue of the color" +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2260 +msgid "clonetiler|S" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2261 +msgid "Pick the saturation of the color" +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2270 +msgid "clonetiler|L" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2271 +msgid "Pick the lightness of the color" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2281 +msgid "2. Tweak the picked value:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2291 +msgid "Gamma-correct:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2296 +msgid "Shift the mid-range of the picked value upwards (>0) or downwards (<0)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2303 +msgid "Randomize:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2308 +msgid "Randomize the picked value by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2315 +#, fuzzy +msgid "Invert:" +msgstr "Trüki" + +#: ../../po/../src/dialogs/clonetiler.cpp:2319 +msgid "Invert the picked value" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2325 +msgid "3. Apply the value to the clones':" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2335 +#, fuzzy +msgid "Presence" +msgstr "Sodipodi" + +#: ../../po/../src/dialogs/clonetiler.cpp:2338 +msgid "" +"Each clone is created with the probability determined by the picked value in " +"that point" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2345 +msgid "Size" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2348 +msgid "Each clone's size is determined by the picked value in that point" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2358 +msgid "" +"Each clone is painted by the picked color (the original must have unset fill " +"or stroke)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2368 +msgid "Each clone's opacity is determined by the picked value in that point" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2395 +msgid "How many rows in the tiling" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2415 +msgid "How many columns in the tiling" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2445 +msgid "Width of the rectangle to be filled" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2470 +msgid "Height of the rectangle to be filled" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2485 +#, fuzzy +msgid "Rows, columns: " +msgstr "Uus aken" + +#: ../../po/../src/dialogs/clonetiler.cpp:2486 +msgid "Create the specified number of rows and columns" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2495 +msgid "Width, height: " +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2496 +msgid "Fill the specified width and height with the tiling" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2512 +msgid "Use saved size and position of the tile" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2515 +msgid "" +"Pretend that the size and position of the tile are the same as the last time " +"you tiled it (if any), instead of using the current size" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2539 +#, fuzzy +msgid " _Create " +msgstr "Lehekülg" + +#: ../../po/../src/dialogs/clonetiler.cpp:2541 +msgid "Create and tile the clones of the selection" +msgstr "" + +#. TRANSLATORS: if a group of objects are "clumped" together, then they +#. are unevenly spread in the given amount of space - as shown in the +#. diagrams on the left in the following screenshot: +#. http://www.inkscape.org/screenshots/gallery/inkscape-0.42-CVS-tiles-unclump.png +#. So unclumping is the process of spreading a number of objects out more evenly. +#: ../../po/../src/dialogs/clonetiler.cpp:2556 +msgid " _Unclump " +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2557 +msgid "Spread out clones to reduce clumping; can be applied repeatedly" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2563 +msgid " Re_move " +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2564 +msgid "Remove existing tiled clones of the selected object (siblings only)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2580 +msgid " R_eset " +msgstr "" + +#. TRANSLATORS: "change" is a noun here +#: ../../po/../src/dialogs/clonetiler.cpp:2582 +msgid "" +"Reset all shifts, scales, rotates, opacity and color changes in the dialog " +"to zero" +msgstr "" + +#: ../../po/../src/dialogs/color-picker.cpp:280 +#, fuzzy +msgid "Close" +msgstr "Uus aken" + +#: ../../po/../src/dialogs/debugdialog.cpp:138 +msgid "Messages" +msgstr "" + +#. ## Add a menu for clear() +#: ../../po/../src/dialogs/debugdialog.cpp:144 +#: ../../po/../src/menus-skeleton.h:16 +#: ../../po/../src/ui/dialog/messages.cpp:56 +#: ../../po/../src/ui/dialog/scriptdialog.cpp:181 +#, fuzzy +msgid "_File" +msgstr "_Uus fail" + +#. TRANSLATORS: "Clear" is a verb here +#: ../../po/../src/dialogs/debugdialog.cpp:145 +#: ../../po/../src/dialogs/find.cpp:753 +#: ../../po/../src/ui/dialog/messages.cpp:57 +#: ../../po/../src/ui/dialog/scriptdialog.cpp:182 +#, fuzzy +msgid "_Clear" +msgstr "Uus aken" + +#: ../../po/../src/dialogs/debugdialog.cpp:147 +#: ../../po/../src/ui/dialog/messages.cpp:59 +msgid "Capture log messages" +msgstr "" + +#: ../../po/../src/dialogs/debugdialog.cpp:149 +#: ../../po/../src/ui/dialog/messages.cpp:61 +msgid "Release log messages" +msgstr "" + +#. Notebook tab +#: ../../po/../src/dialogs/desktop-properties.cpp:909 +#: ../../po/../src/ui/dialog/document-preferences.cpp:89 +#: ../../po/../src/ui/widget/panel.cpp:107 +msgid "Grid" +msgstr "" + +#. Checkbuttons +#. / \todo FIXME: gray out snapping when grid is off +#. / \todo FIXME: gray out snapping when grid is off. +#. / Dissenting view: you want snapping without grid. +#: ../../po/../src/dialogs/desktop-properties.cpp:917 +#: ../../po/../src/ui/dialog/document-preferences.cpp:179 +msgid "Show grid" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:917 +#: ../../po/../src/ui/dialog/document-preferences.cpp:179 +#: ../../po/../src/verbs.cpp:2115 +msgid "Show or hide grid" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:918 +#: ../../po/../src/ui/dialog/document-preferences.cpp:180 +msgid "Snap bounding boxes to grid" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:918 +#: ../../po/../src/dialogs/desktop-properties.cpp:1001 +#: ../../po/../src/ui/dialog/document-preferences.cpp:181 +#: ../../po/../src/ui/dialog/document-preferences.cpp:236 +msgid "Snap the edges of the object bounding boxes" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:919 +#: ../../po/../src/ui/dialog/document-preferences.cpp:183 +msgid "Snap nodes to grid" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:919 +#: ../../po/../src/dialogs/desktop-properties.cpp:1002 +#: ../../po/../src/ui/dialog/document-preferences.cpp:184 +#: ../../po/../src/ui/dialog/document-preferences.cpp:239 +msgid "Snap path nodes, text baselines, ellipse centers, etc." +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:937 +#: ../../po/../src/ui/dialog/document-preferences.cpp:186 +msgid "Grid units:" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:939 +#: ../../po/../src/ui/dialog/document-preferences.cpp:187 +msgid "Origin X:" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:942 +#: ../../po/../src/ui/dialog/document-preferences.cpp:189 +msgid "Origin Y:" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:945 +#: ../../po/../src/ui/dialog/document-preferences.cpp:191 +msgid "Spacing X:" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:948 +#: ../../po/../src/ui/dialog/document-preferences.cpp:193 +msgid "Spacing Y:" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:952 +#: ../../po/../src/dialogs/desktop-properties.cpp:1013 +#: ../../po/../src/ui/dialog/document-preferences.cpp:195 +#: ../../po/../src/ui/dialog/document-preferences.cpp:241 +msgid "Snap units:" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:955 +#: ../../po/../src/dialogs/desktop-properties.cpp:1016 +#: ../../po/../src/ui/dialog/document-preferences.cpp:196 +#: ../../po/../src/ui/dialog/document-preferences.cpp:242 +msgid "Snap distance:" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:958 +#: ../../po/../src/ui/dialog/document-preferences.cpp:199 +msgid "Grid line color:" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:959 +#: ../../po/../src/ui/dialog/document-preferences.cpp:199 +msgid "Grid line color" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:959 +#: ../../po/../src/ui/dialog/document-preferences.cpp:200 +msgid "Color of grid lines" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:961 +#: ../../po/../src/ui/dialog/document-preferences.cpp:201 +msgid "Major grid line color:" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:962 +#: ../../po/../src/ui/dialog/document-preferences.cpp:201 +msgid "Major grid line color" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:962 +#: ../../po/../src/ui/dialog/document-preferences.cpp:202 +msgid "Color of the major (highlighted) grid lines" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:965 +#: ../../po/../src/ui/dialog/document-preferences.cpp:204 +msgid "Major grid line every:" +msgstr "" + +#. TRANSLATORS: This belongs to the "Major grid line every:" string, +#. see grid settings in the "Document Preferences" dialog +#: ../../po/../src/dialogs/desktop-properties.cpp:977 +#: ../../po/../src/ui/dialog/document-preferences.cpp:204 +#, fuzzy +msgid "lines" +msgstr "Uus aken" + +#. Guidelines page +#: ../../po/../src/dialogs/desktop-properties.cpp:991 +#: ../../po/../src/ui/dialog/document-preferences.cpp:90 +msgid "Guides" +msgstr "" + +#. / \todo FIXME: gray out snapping when guides are off +#. / Dissenting view: you want snapping without guides. +#: ../../po/../src/dialogs/desktop-properties.cpp:1000 +#: ../../po/../src/ui/dialog/document-preferences.cpp:234 +msgid "Show guides" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1000 +#: ../../po/../src/ui/dialog/document-preferences.cpp:234 +#: ../../po/../src/verbs.cpp:2116 +msgid "Show or hide guides" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1001 +#: ../../po/../src/ui/dialog/document-preferences.cpp:235 +msgid "Snap bounding boxes to guides" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1002 +#: ../../po/../src/ui/dialog/document-preferences.cpp:238 +msgid "Snap points to guides" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1020 +#: ../../po/../src/ui/dialog/document-preferences.cpp:243 +msgid "Guide color:" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1021 +#: ../../po/../src/ui/dialog/document-preferences.cpp:243 +msgid "Guideline color" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1021 +#: ../../po/../src/ui/dialog/document-preferences.cpp:244 +#, fuzzy +msgid "Color of guidelines" +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1023 +#: ../../po/../src/ui/dialog/document-preferences.cpp:245 +msgid "Highlight color:" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1024 +#: ../../po/../src/ui/dialog/document-preferences.cpp:245 +msgid "Highlighted guideline color" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1024 +#: ../../po/../src/ui/dialog/document-preferences.cpp:246 +msgid "Color of a guideline when it is under mouse" +msgstr "" + +#. Page page +#: ../../po/../src/dialogs/desktop-properties.cpp:1029 +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:855 +#: ../../po/../src/ui/dialog/document-preferences.cpp:88 +#: ../../po/../src/widgets/desktop-widget.cpp:1061 +#, fuzzy +msgid "Page" +msgstr "Lehekülg" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1039 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +msgid "Background:" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1040 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +msgid "Background color" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1041 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +msgid "" +"Color and transparency of the page background (also used for bitmap export)" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1045 +#: ../../po/../src/ui/dialog/document-preferences.cpp:147 +msgid "Show page border" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1049 +#: ../../po/../src/ui/dialog/document-preferences.cpp:148 +msgid "Border on top of drawing" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1052 +#: ../../po/../src/ui/dialog/document-preferences.cpp:149 +msgid "Border color:" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1053 +#: ../../po/../src/ui/dialog/document-preferences.cpp:149 +msgid "Page border color" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1054 +#: ../../po/../src/ui/dialog/document-preferences.cpp:150 +msgid "Color of the page border" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1059 +#: ../../po/../src/ui/dialog/document-preferences.cpp:152 +msgid "Show page shadow" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1063 +#: ../../po/../src/ui/dialog/document-preferences.cpp:153 +#, fuzzy +msgid "Default units:" +msgstr "Kustuta" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1069 +msgid "Units for the tool controls, ruler, and the statusbar" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1086 +#: ../../po/../src/ui/widget/page-sizer.cpp:209 +msgid "Page size:" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1110 +#: ../../po/../src/ui/widget/page-sizer.cpp:219 +msgid "Custom" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1121 +#: ../../po/../src/ui/widget/page-sizer.cpp:225 +#, fuzzy +msgid "Page orientation:" +msgstr "_Selektsioon" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1133 +#: ../../po/../src/ui/widget/page-sizer.cpp:232 +#, fuzzy +msgid "Landscape" +msgstr "Sodipodi" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1139 +#: ../../po/../src/ui/widget/page-sizer.cpp:234 +#, fuzzy +msgid "Portrait" +msgstr "Trüki" + +#. Custom paper frame +#: ../../po/../src/dialogs/desktop-properties.cpp:1148 +#: ../../po/../src/ui/widget/page-sizer.cpp:249 +msgid "Custom size" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1160 +#: ../../po/../src/dialogs/export.cpp:269 +#: ../../po/../src/ui/widget/page-sizer.cpp:261 +msgid "Units:" +msgstr "" + +#. Stroke width +#: ../../po/../src/dialogs/desktop-properties.cpp:1162 +#: ../../po/../src/dialogs/export.cpp:310 +#: ../../po/../src/dialogs/object-attributes.cpp:55 +#: ../../po/../src/dialogs/stroke-style.cpp:985 +#: ../../po/../src/ui/widget/page-sizer.cpp:262 +#: ../../po/../src/widgets/toolbox.cpp:1957 +msgid "Width:" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1183 +#: ../../po/../src/dialogs/export.cpp:326 +#: ../../po/../src/dialogs/export.cpp:431 +#: ../../po/../src/dialogs/object-attributes.cpp:56 +#: ../../po/../src/ui/widget/page-sizer.cpp:263 +msgid "Height:" +msgstr "" + +#. +#. * Ownership metadata tab +#. +#: ../../po/../src/dialogs/desktop-properties.cpp:1206 +msgid "Metadata" +msgstr "" + +#. add license selector pull-down +#: ../../po/../src/dialogs/desktop-properties.cpp:1225 +msgid "License" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1255 +msgid "Proprietary" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:212 +msgid "When transforming, show:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:223 +#, fuzzy +msgid "Objects" +msgstr "Grupeerib valitud objektid" + +#: ../../po/../src/dialogs/display-settings.cpp:224 +msgid "Show the actual objects when moving or transforming" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:231 +msgid "Box outline" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:232 +msgid "Show only a box outline of the objects when moving or transforming" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:238 +#, fuzzy +msgid "Per-object selection cue:" +msgstr "Tee jooneks" + +#. sorationsnapsperpi == 0 means no snapping +#: ../../po/../src/dialogs/display-settings.cpp:249 +#: ../../po/../src/dialogs/display-settings.cpp:386 +#: ../../po/../src/dialogs/display-settings.cpp:441 +#: ../../po/../src/dialogs/display-settings.cpp:1482 +#: ../../po/../src/dialogs/stroke-style.cpp:791 +#: ../../po/../src/interface.cpp:741 +#: ../../po/../src/ui/widget/selected-style.cpp:100 +#: ../../po/../src/verbs.cpp:1842 +msgid "None" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:250 +msgid "No per-object selection indication" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:256 +msgid "Mark" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:257 +msgid "Each selected object has a diamond mark in the top left corner" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:264 +msgid "Box" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:265 +msgid "Each selected object displays its bounding box" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:270 +msgid "Default scale origin:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:281 +msgid "Opposite bounding box edge" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:282 +msgid "Default scale origin will be on the bounding box of the item" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:288 +msgid "Farthest opposite node" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:289 +msgid "Default scale origin will be on the bounding box of the item's points" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:341 +msgid "degrees" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:350 +msgid "" +"Rotating with Ctrl pressed snaps every that much degrees; also, pressing " +"[ or ] rotates by this amount" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:407 +msgid "Rotation snaps every:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:430 +msgid "" +"None: dialogs are treated as regular windows; Normal: dialogs stay on top of " +"document windows; Aggressive: same as Normal but may work better with some " +"window managers." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:451 +msgid "Normal" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:461 +msgid "Aggressive" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:475 +msgid "Dialogs on top:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:645 +#, fuzzy +msgid "Show selection cue" +msgstr "Tee jooneks" + +#: ../../po/../src/dialogs/display-settings.cpp:646 +msgid "" +"Whether selected objects display a selection cue (the same as in selector)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:657 +#, fuzzy +msgid "Enable gradient editing" +msgstr "Trüki" + +#: ../../po/../src/dialogs/display-settings.cpp:658 +msgid "Whether selected objects display gradient editing controls" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:719 +#, fuzzy +msgid "No objects selected to take the style from." +msgstr "Tee jooneks" + +#: ../../po/../src/dialogs/display-settings.cpp:728 +msgid "" +"More than one object selected. Cannot take style from multiple " +"objects." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:767 +#, fuzzy +msgid "Create new objects with:" +msgstr "Grupeerib valitud objektid" + +#: ../../po/../src/dialogs/display-settings.cpp:777 +#, fuzzy +msgid "Take from selection" +msgstr "D_uplikaat" + +#: ../../po/../src/dialogs/display-settings.cpp:778 +msgid "Remember the style of the (first) selected object as this tool's style" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:782 +#, fuzzy +msgid "Last used style" +msgstr "Piirjoon" + +#: ../../po/../src/dialogs/display-settings.cpp:782 +msgid "Apply the style you last set on an object" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:790 +msgid "This tool's own style:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:790 +msgid "" +"Each tool may store its own style to apply to the newly created objects. Use " +"the button below to set it." +msgstr "" + +#. Mouse +#: ../../po/../src/dialogs/display-settings.cpp:877 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:55 +#, fuzzy +msgid "Mouse" +msgstr "Punktiredaktor" + +#. TRANSLATORS: "Grab" is a noun here. "Grab sensitivity" is intended to mean how +#. * close on the screen you need to be to an object to be able to grab it with mouse (in +#. * pixels). +#: ../../po/../src/dialogs/display-settings.cpp:883 +msgid "Grab sensitivity:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:884 +msgid "" +"How close on the screen you need to be to an object to be able to grab it " +"with mouse (in screen pixels)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:885 +#: ../../po/../src/dialogs/display-settings.cpp:897 +#: ../../po/../src/dialogs/display-settings.cpp:912 +#: ../../po/../src/dialogs/display-settings.cpp:930 +#: ../../po/../src/dialogs/display-settings.cpp:970 +msgid "pixels" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:895 +msgid "Click/drag threshold:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:896 +msgid "" +"Maximum mouse drag (in screen pixels) which is considered a click, not a drag" +msgstr "" + +#. Scrolling +#: ../../po/../src/dialogs/display-settings.cpp:907 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:56 +msgid "Scrolling" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:910 +msgid "Mouse wheel scrolls by:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:911 +msgid "" +"One mouse wheel notch scrolls by this distance in screen pixels " +"(horizontally with Shift)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:920 +msgid "Ctrl+arrows" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:928 +msgid "Scroll by:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:929 +msgid "Pressing Ctrl+arrow key scrolls by this distance (in screen pixels)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:939 +#, fuzzy +msgid "Acceleration:" +msgstr "_Selektsioon" + +#: ../../po/../src/dialogs/display-settings.cpp:940 +msgid "" +"Pressing and holding Ctrl+arrow will gradually speed up scrolling (0 for no " +"acceleration)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:949 +msgid "Autoscrolling" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:957 +#, fuzzy +msgid "Speed:" +msgstr "Skaala" + +#: ../../po/../src/dialogs/display-settings.cpp:958 +msgid "" +"How fast the canvas autoscrolls when you drag beyond canvas edge (0 to turn " +"autoscroll off)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:968 +#: ../../po/../src/ui/dialog/tracedialog.cpp:357 +#: ../../po/../src/ui/dialog/tracedialog.cpp:390 +msgid "Threshold:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:969 +msgid "" +"How far (in screen pixels) you need to be from the canvas edge to trigger " +"autoscroll; positive is outside the canvas, negative is within the canvas" +msgstr "" + +#. Steps +#: ../../po/../src/dialogs/display-settings.cpp:979 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:57 +#, fuzzy +msgid "Steps" +msgstr "Skaala" + +#: ../../po/../src/dialogs/display-settings.cpp:982 +msgid "Arrow keys move by:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:983 +msgid "" +"Pressing an arrow key moves selected object(s) or node(s) by this distance " +"(in px units)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:984 +#: ../../po/../src/dialogs/display-settings.cpp:995 +#: ../../po/../src/dialogs/display-settings.cpp:1006 +#: ../../po/../src/helper/units.cpp:42 +msgid "px" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:993 +msgid "> and < scale by:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:994 +msgid "" +"Pressing > or < scales selection up or down by this increment (in px units)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1004 +msgid "Inset/Outset by:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1005 +msgid "" +"Inset and Outset commands displace the path by this distance (in px units)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1017 +msgid "Compass-like display of angles" +msgstr "" + +#. TRANSLATORS: "positive clockwise" means "increasing in clockwise direction" +#: ../../po/../src/dialogs/display-settings.cpp:1019 +msgid "" +"When on, angles are displayed with 0 at north, 0 to 360 range, positive " +"clockwise; otherwise with 0 at east, -180 to 180 range, positive " +"counterclockwise" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1026 +#, fuzzy +msgid "Zoom in/out by:" +msgstr "Suurendus" + +#: ../../po/../src/dialogs/display-settings.cpp:1027 +msgid "" +"Zoom tool click, +/- keys, and middle click zoom in and out by this " +"multiplier" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1028 +#: ../../po/../src/helper/units.cpp:44 +msgid "%" +msgstr "" + +#. Tools +#: ../../po/../src/dialogs/display-settings.cpp:1037 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:58 +msgid "Tools" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1045 +#, fuzzy +msgid "Selector" +msgstr "_Selektsioon" + +#: ../../po/../src/dialogs/display-settings.cpp:1056 +#, fuzzy +msgid "Node" +msgstr "Punktiredaktor" + +#: ../../po/../src/dialogs/display-settings.cpp:1064 +#: ../../po/../src/verbs.cpp:2073 +#: ../../po/../src/widgets/desktop-widget.cpp:277 +msgid "Zoom" +msgstr "Suurendus" + +#. The 4 shape tools +#: ../../po/../src/dialogs/display-settings.cpp:1071 +#, fuzzy +msgid "Shapes" +msgstr "Salvesta" + +#: ../../po/../src/dialogs/display-settings.cpp:1079 +#: ../../po/../src/verbs.cpp:2055 +#, fuzzy +msgid "Rectangle" +msgstr "Lehekülg" + +#: ../../po/../src/dialogs/display-settings.cpp:1085 +#: ../../po/../src/verbs.cpp:2057 +msgid "Ellipse" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1091 +#: ../../po/../src/verbs.cpp:2059 +#, fuzzy +msgid "Star" +msgstr "Piirjoon" + +#: ../../po/../src/dialogs/display-settings.cpp:1097 +#: ../../po/../src/verbs.cpp:2061 +msgid "Spiral" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1111 +#: ../../po/../src/verbs.cpp:2063 +msgid "Pencil" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1114 +msgid "Tolerance:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1115 +msgid "" +"This value affects the amount of smoothing applied to freehand lines; lower " +"values produce more uneven paths with more nodes" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1131 +#: ../../po/../src/verbs.cpp:2065 +#, fuzzy +msgid "Pen" +msgstr "Trüki" + +#: ../../po/../src/dialogs/display-settings.cpp:1140 +#: ../../po/../src/verbs.cpp:2067 +msgid "Calligraphy" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1147 +#: ../../po/../src/dialogs/text-edit.cpp:353 +#: ../../po/../src/ui/dialog/text-properties.cpp:37 +#: ../../po/../src/verbs.cpp:2069 +msgid "Text" +msgstr "Tekst" + +#: ../../po/../src/dialogs/display-settings.cpp:1157 +#: ../../po/../src/verbs.cpp:2071 +#, fuzzy +msgid "Gradient" +msgstr "Trüki" + +#: ../../po/../src/dialogs/display-settings.cpp:1164 +#: ../../po/../src/verbs.cpp:2077 +#, fuzzy +msgid "Connector" +msgstr "Uus aken" + +#: ../../po/../src/dialogs/display-settings.cpp:1171 +#: ../../po/../src/verbs.cpp:2075 +msgid "Dropper" +msgstr "" + +#. Windows +#: ../../po/../src/dialogs/display-settings.cpp:1183 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:59 +msgid "Windows" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1188 +#, fuzzy +msgid "Save window geometry" +msgstr "Shrift" + +#: ../../po/../src/dialogs/display-settings.cpp:1189 +msgid "" +"Save the window size and position with each document (only for Inkscape SVG " +"format)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1196 +msgid "Dialogs are hidden in taskbar" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1197 +msgid "Whether dialog windows are to be hidden in the window manager taskbar" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1204 +msgid "Zoom when window is resized" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1205 +msgid "" +"Zoom drawing when document window is resized, to keep the same area visible " +"(this is the default which can be changed in any window using the button " +"above the right scrollbar)" +msgstr "" + +#. Clones +#: ../../po/../src/dialogs/display-settings.cpp:1213 +#: ../../po/../src/dialogs/find.cpp:624 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:60 +#, fuzzy +msgid "Clones" +msgstr "Uus aken" + +#: ../../po/../src/dialogs/display-settings.cpp:1217 +msgid "When the original moves, its clones and linked offsets:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1229 +msgid "Move in parallel" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1230 +msgid "Clones are translated by the same vector as their original." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1237 +msgid "Stay unmoved" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1238 +msgid "Clones preserve their positions when their original is moved." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1245 +msgid "Move according to transform" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1246 +msgid "" +"Each clone moves according to the value of its transform= attribute. For " +"example, a rotated clone will move in a different direction than its " +"original." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1255 +msgid "When the original is deleted, its clones:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1267 +msgid "Are unlinked" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1267 +msgid "Orphaned clones are converted to regular objects." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1273 +#, fuzzy +msgid "Are deleted" +msgstr "Grupeerib valitud objektid" + +#: ../../po/../src/dialogs/display-settings.cpp:1273 +msgid "Orphaned clones are deleted along with their original." +msgstr "" + +#. Transforms +#. TRANSLATORS: Noun, i.e. transformations. +#: ../../po/../src/dialogs/display-settings.cpp:1289 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:61 +#, fuzzy +msgid "Transforms" +msgstr "_Selektsioon" + +#: ../../po/../src/dialogs/display-settings.cpp:1292 +#, fuzzy +msgid "Scale stroke width" +msgstr "Trüki" + +#: ../../po/../src/dialogs/display-settings.cpp:1293 +#: ../../po/../src/widgets/select-toolbar.cpp:568 +msgid "When scaling objects, scale the stroke width by the same proportion" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1300 +msgid "Scale rounded corners in rectangles" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1301 +#: ../../po/../src/widgets/select-toolbar.cpp:580 +msgid "When scaling rectangles, scale the radii of rounded corners" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1308 +#, fuzzy +msgid "Transform gradients" +msgstr "_Selektsioon" + +#: ../../po/../src/dialogs/display-settings.cpp:1309 +#: ../../po/../src/widgets/select-toolbar.cpp:592 +msgid "Transform gradients (in fill or stroke) along with the objects" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1316 +#, fuzzy +msgid "Transform patterns" +msgstr "_Selektsioon" + +#: ../../po/../src/dialogs/display-settings.cpp:1317 +#: ../../po/../src/widgets/select-toolbar.cpp:604 +msgid "Transform patterns (in fill or stroke) along with the objects" +msgstr "" + +#. TRANSLATORS: How to specify the affine transformation in the SVG file. +#: ../../po/../src/dialogs/display-settings.cpp:1327 +msgid "Store transformation:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1338 +msgid "Optimized" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1339 +msgid "" +"If possible, apply transformation to objects without adding a transform= " +"attribute" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1346 +msgid "Preserved" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1347 +msgid "Always store transformation as a transform= attribute on objects" +msgstr "" + +#. Selecting +#: ../../po/../src/dialogs/display-settings.cpp:1355 +#, fuzzy +msgid "Selecting" +msgstr "_Selektsioon" + +#: ../../po/../src/dialogs/display-settings.cpp:1357 +msgid "Ctrl+A, Tab, Shift+Tab:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1366 +#, fuzzy +msgid "Select only within current layer" +msgstr "_Selektsioon" + +#: ../../po/../src/dialogs/display-settings.cpp:1367 +msgid "" +"Uncheck this to make keyboard selection commands work on objects in all " +"layers" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1374 +msgid "Ignore hidden objects" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1375 +msgid "" +"Uncheck this to be able to select objects that are hidden (either by " +"themselves or by being in a hidden group or layer)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1382 +#, fuzzy +msgid "Ignore locked objects" +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/dialogs/display-settings.cpp:1383 +msgid "" +"Uncheck this to be able to select objects that are locked (either by " +"themselves or by being in a locked group or layer)" +msgstr "" + +#. To be broken into: Display, Save, Export, SVG, Commands +#: ../../po/../src/dialogs/display-settings.cpp:1391 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:62 +msgid "Misc" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1394 +msgid "Default export resolution:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1395 +msgid "Default bitmap resolution (in dots per inch) in the Export dialog" +msgstr "" + +#. FIXME: add "Used for new exports; once exported, documents remember this value on per-object basis" when implemented +#: ../../po/../src/dialogs/display-settings.cpp:1396 +#: ../../po/../src/dialogs/export.cpp:442 +msgid "dpi" +msgstr "" + +#. TRANSLATORS: When on, an imported bitmap creates an element; otherwise it is a +#. * rectangle with bitmap fill. +#: ../../po/../src/dialogs/display-settings.cpp:1407 +msgid "Import bitmap as " +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1408 +msgid "" +"When on, an imported bitmap creates an element; otherwise it is a " +"rectangle with bitmap fill" +msgstr "" + +#. TRANSLATORS: When on, the print out (currently Postscript) will have +#. * a comment with the each object's label visible, marking the section +#. * of the printing commands that represent the given object. +#: ../../po/../src/dialogs/display-settings.cpp:1418 +msgid "Add label comments to printing output" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1419 +msgid "" +"When on, a comment will be added to the raw print output, marking the " +"rendered output for an object with its label" +msgstr "" + +#. TRANSLATORS: When on, enable the effects menu, default is off +#: ../../po/../src/dialogs/display-settings.cpp:1427 +msgid "Enable script effects (requires restart) - EXPERIMENTAL" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1428 +msgid "" +"When on, the effects menu is enabled, allowing external effect scripts to be " +"called, requires restart before effective - EXPERIMENTAL" +msgstr "" + +#. TRANSLATORS: The maximum length of the Open Recent list in the File menu. +#: ../../po/../src/dialogs/display-settings.cpp:1436 +#, fuzzy +msgid "Max recent documents:" +msgstr "Shrift" + +#: ../../po/../src/dialogs/display-settings.cpp:1437 +msgid "The maximum length of the Open Recent list in the File menu" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1447 +msgid "Simplification threshold:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1448 +msgid "" +"How strong is the Simplify command by default. If you invoke this command " +"several times in quick succession, it will act more and more aggressively; " +"invoking it again after a pause restores the default threshold." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1469 +msgid "Oversample bitmaps:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1488 +msgid "2x2" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1494 +msgid "4x4" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1500 +msgid "8x8" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1506 +msgid "16x16" +msgstr "" + +#. "view_icon_preview" +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2143 +msgid "_Page" +msgstr "Lehekülg" + +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2147 +msgid "_Drawing" +msgstr "Joonistus" + +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2149 +msgid "_Selection" +msgstr "_Selektsioon" + +#: ../../po/../src/dialogs/export.cpp:133 +msgid "_Custom" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:254 +#, fuzzy +msgid "Export area" +msgstr "_Import" + +#: ../../po/../src/dialogs/export.cpp:300 +msgid "_x0:" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:305 +#, fuzzy +msgid "x_1:" +msgstr "1:1" + +#: ../../po/../src/dialogs/export.cpp:316 +msgid "_y0:" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:321 +#, fuzzy +msgid "y_1:" +msgstr "1:1" + +#: ../../po/../src/dialogs/export.cpp:406 +msgid "Bitmap size" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:416 +#, fuzzy +msgid "_Width:" +msgstr "Piirjoon" + +#: ../../po/../src/dialogs/export.cpp:416 +#: ../../po/../src/dialogs/export.cpp:431 +msgid "pixels at" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:426 +msgid "dp_i" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:448 +#, fuzzy +msgid "_Filename" +msgstr "Trükib faili" + +#: ../../po/../src/dialogs/export.cpp:512 +msgid "_Browse..." +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:539 +#, fuzzy +msgid " _Export " +msgstr "Lehekülg" + +#: ../../po/../src/dialogs/export.cpp:541 +msgid "Export the bitmap file with these settings" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:968 +msgid "You have to enter a filename" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:973 +msgid "The chosen area to be exported is invalid" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:982 +#, c-format +msgid "Directory %s does not exist or is not a directory.\n" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:998 +#, fuzzy +msgid "Export in progress" +msgstr "_Import" + +#: ../../po/../src/dialogs/export.cpp:1004 +#, c-format +msgid "Exporting %s (%d x %d)" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:1031 +#, c-format +msgid "Could not export to filename %s.\n" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:1137 +#, fuzzy +msgid "Select a filename for exporting" +msgstr "_Selektsioon" + +#: ../../po/../src/dialogs/filedialog.cpp:367 +#, fuzzy +msgid "No preview" +msgstr "Uus aken" + +#: ../../po/../src/dialogs/filedialog.cpp:468 +msgid "too large for preview" +msgstr "" + +#: ../../po/../src/dialogs/filedialog.cpp:762 +#: ../../po/../src/dialogs/filedialog.cpp:763 +#, fuzzy +msgid "All Images" +msgstr "Lehekülg" + +#: ../../po/../src/dialogs/filedialog.cpp:767 +#: ../../po/../src/dialogs/filedialog.cpp:768 +#, fuzzy +msgid "All Files" +msgstr "Shrift" + +#: ../../po/../src/dialogs/filedialog.cpp:774 +#: ../../po/../src/dialogs/filedialog.cpp:775 +#, fuzzy +msgid "All Inkscape Files" +msgstr "Sodipodi" + +#: ../../po/../src/dialogs/filedialog.cpp:1176 +#, fuzzy +msgid "Guess from extension" +msgstr "D_uplikaat" + +#. ###### Add the file types menu +#. createFilterMenu(); +#. ###### Do we want the .xxx extension automatically added? +#: ../../po/../src/dialogs/filedialog.cpp:1261 +msgid "Append filename extension automatically" +msgstr "" + +#. TRANSLATORS: "%s" is replaced with "exact" or "partial" when this string is displayed +#: ../../po/../src/dialogs/find.cpp:378 +#, fuzzy, c-format +msgid "%d object found (out of %d), %s match." +msgid_plural "%d objects found (out of %d), %s match." +msgstr[0] "Kustutab valitud objekti(d)" +msgstr[1] "Kustutab valitud objekti(d)" + +#: ../../po/../src/dialogs/find.cpp:381 +#, fuzzy +msgid "exact" +msgstr "Tekst" + +#: ../../po/../src/dialogs/find.cpp:381 +msgid "partial" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:388 +#, fuzzy +msgid "No objects found" +msgstr "Grupeerib valitud objektid" + +#: ../../po/../src/dialogs/find.cpp:546 +msgid "T_ype: " +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:553 +msgid "Search in all object types" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:553 +#, fuzzy +msgid "All types" +msgstr "Shrift" + +#: ../../po/../src/dialogs/find.cpp:564 +msgid "Search all shapes" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:564 +msgid "All shapes" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:581 +#, fuzzy +msgid "Search rectangles" +msgstr "Lehekülg" + +#: ../../po/../src/dialogs/find.cpp:581 +#, fuzzy +msgid "Rectangles" +msgstr "Lehekülg" + +#: ../../po/../src/dialogs/find.cpp:586 +msgid "Search ellipses, arcs, circles" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:586 +msgid "Ellipses" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:591 +msgid "Search stars and polygons" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:591 +#, fuzzy +msgid "Stars" +msgstr "Piirjoon" + +#: ../../po/../src/dialogs/find.cpp:596 +#, fuzzy +msgid "Search spirals" +msgstr "Üldine" + +#: ../../po/../src/dialogs/find.cpp:596 +msgid "Spirals" +msgstr "" + +#. TRANSLATORS: polyline is a set of connected straight line segments +#. http://www.w3.org/TR/SVG11/shapes.html#PolylineElement +#: ../../po/../src/dialogs/find.cpp:609 +msgid "Search paths, lines, polylines" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:609 +msgid "Paths" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:614 +#, fuzzy +msgid "Search text objects" +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/dialogs/find.cpp:614 +#, fuzzy +msgid "Texts" +msgstr "Tekst" + +#: ../../po/../src/dialogs/find.cpp:619 +msgid "Search groups" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:619 +#, fuzzy +msgid "Groups" +msgstr "Grupeeri" + +#: ../../po/../src/dialogs/find.cpp:624 +msgid "Search clones" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:629 +msgid "Search images" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:629 +#, fuzzy +msgid "Images" +msgstr "Lehekülg" + +#: ../../po/../src/dialogs/find.cpp:634 +#, fuzzy +msgid "Search offset objects" +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/dialogs/find.cpp:634 +msgid "Offsets" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:694 +#, fuzzy +msgid "_Text: " +msgstr "Tekst" + +#: ../../po/../src/dialogs/find.cpp:694 +msgid "Find objects by their text content (exact or partial match)" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:695 +msgid "_ID: " +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:695 +msgid "Find objects by the value of the id attribute (exact or partial match)" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:696 +#, fuzzy +msgid "_Style: " +msgstr "Skaala" + +#: ../../po/../src/dialogs/find.cpp:696 +msgid "" +"Find objects by the value of the style attribute (exact or partial match)" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:697 +msgid "_Attribute: " +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:697 +msgid "Find objects by the name of an attribute (exact or partial match)" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:711 +#, fuzzy +msgid "Search in s_election" +msgstr "D_uplikaat" + +#: ../../po/../src/dialogs/find.cpp:715 +msgid "Limit search to the current selection" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:720 +#, fuzzy +msgid "Search in current _layer" +msgstr "_Selektsioon" + +#: ../../po/../src/dialogs/find.cpp:724 +#, fuzzy +msgid "Limit search to the current layer" +msgstr "_Selektsioon" + +#: ../../po/../src/dialogs/find.cpp:729 +msgid "Include _hidden" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:733 +msgid "Include hidden objects in search" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:738 +msgid "Include l_ocked" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:742 +#, fuzzy +msgid "Include locked objects in search" +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/dialogs/find.cpp:753 +msgid "Clear values" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:754 +#, fuzzy +msgid "_Find" +msgstr "Vabasta" + +#: ../../po/../src/dialogs/find.cpp:754 +msgid "Select objects matching all of the fields you filled in" +msgstr "" + +#: ../../po/../src/dialogs/iconpreview.cpp:145 +#, c-format +msgid "%d x %d" +msgstr "" + +#: ../../po/../src/dialogs/iconpreview.cpp:193 +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:857 +#: ../../po/../src/widgets/desktop-widget.cpp:1069 +#, fuzzy +msgid "Selection" +msgstr "_Selektsioon" + +#: ../../po/../src/dialogs/iconpreview.cpp:195 +#, fuzzy +msgid "Selection only or whole document" +msgstr "_Selektsioon" + +#: ../../po/../src/dialogs/iconpreview.cpp:203 +msgid "Refresh the icons" +msgstr "" + +#. Create the label for the object id +#: ../../po/../src/dialogs/item-properties.cpp:126 +#: ../../po/../src/dialogs/item-properties.cpp:327 +#: ../../po/../src/dialogs/item-properties.cpp:396 +#: ../../po/../src/dialogs/item-properties.cpp:403 +msgid "_Id" +msgstr "" + +#: ../../po/../src/dialogs/item-properties.cpp:135 +msgid "" +"The id= attribute (only letters, digits, and the characters .-_: allowed)" +msgstr "" + +#. Button for setting the object's id, label, title and description. +#: ../../po/../src/dialogs/item-properties.cpp:149 +#, fuzzy +msgid "_Set" +msgstr "_Selektsioon" + +#. Create the label for the object label +#: ../../po/../src/dialogs/item-properties.cpp:158 +msgid "_Label" +msgstr "" + +#: ../../po/../src/dialogs/item-properties.cpp:167 +msgid "A freeform label for the object" +msgstr "" + +#. Create the label for the object title +#: ../../po/../src/dialogs/item-properties.cpp:179 +#: ../../po/../src/dialogs/rdf.cpp:243 +#, fuzzy +msgid "Title" +msgstr "Värv" + +#. Create the frame for the object description +#: ../../po/../src/dialogs/item-properties.cpp:196 +#: ../../po/../src/dialogs/rdf.cpp:287 +#, fuzzy +msgid "Description" +msgstr "_Selektsioon" + +#. Hide +#: ../../po/../src/dialogs/item-properties.cpp:223 +#, fuzzy +msgid "_Hide" +msgstr "Vabasta" + +#: ../../po/../src/dialogs/item-properties.cpp:224 +msgid "Check to make the object invisible" +msgstr "" + +#. Lock +#. TRANSLATORS: "Lock" is a verb here +#: ../../po/../src/dialogs/item-properties.cpp:233 +msgid "L_ock" +msgstr "" + +#: ../../po/../src/dialogs/item-properties.cpp:234 +msgid "Check to make the object insensitive (not selectable by mouse)" +msgstr "" + +#: ../../po/../src/dialogs/item-properties.cpp:310 +#: ../../po/../src/dialogs/item-properties.cpp:317 +msgid "Ref" +msgstr "" + +#: ../../po/../src/dialogs/item-properties.cpp:398 +msgid "Id invalid! " +msgstr "" + +#: ../../po/../src/dialogs/item-properties.cpp:400 +msgid "Id exists! " +msgstr "" + +#: ../../po/../src/dialogs/layer-properties.cpp:50 +msgid "Layer name:" +msgstr "" + +#: ../../po/../src/dialogs/layer-properties.cpp:133 +#, fuzzy +msgid "Rename Layer" +msgstr "Lehekülg" + +#: ../../po/../src/dialogs/layer-properties.cpp:136 +#, fuzzy +msgid "_Rename" +msgstr "Trükib faili" + +#. TRANSLATORS: This means "The layer has been renamed" +#: ../../po/../src/dialogs/layer-properties.cpp:147 +#, fuzzy +msgid "Renamed layer" +msgstr "Lehekülg" + +#: ../../po/../src/dialogs/layer-properties.cpp:151 +#, fuzzy +msgid "Add Layer" +msgstr "_Selektsioon" + +#: ../../po/../src/dialogs/layer-properties.cpp:153 +msgid "_Add" +msgstr "" + +#: ../../po/../src/dialogs/layer-properties.cpp:167 +msgid "New layer created." +msgstr "" + +#: ../../po/../src/dialogs/object-attributes.cpp:34 +#, fuzzy +msgid "Href:" +msgstr "Skaala" + +#: ../../po/../src/dialogs/object-attributes.cpp:35 +msgid "Target:" +msgstr "" + +#: ../../po/../src/dialogs/object-attributes.cpp:36 +msgid "Type:" +msgstr "" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkRoleAttribute +#. Identifies the type of the related resource with an absolute URI +#: ../../po/../src/dialogs/object-attributes.cpp:39 +#, fuzzy +msgid "Role:" +msgstr "Skaala" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkArcRoleAttribute +#. For situations where the nature/role alone isn't enough, this offers an additional URI defining the purpose of the link. +#: ../../po/../src/dialogs/object-attributes.cpp:42 +msgid "Arcrole:" +msgstr "" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkTitleAttribute +#: ../../po/../src/dialogs/object-attributes.cpp:44 +#, fuzzy +msgid "Title:" +msgstr "Värv" + +#: ../../po/../src/dialogs/object-attributes.cpp:45 +msgid "Show:" +msgstr "" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkActuateAttribute +#: ../../po/../src/dialogs/object-attributes.cpp:47 +msgid "Actuate:" +msgstr "" + +#: ../../po/../src/dialogs/object-attributes.cpp:52 +msgid "URL:" +msgstr "" + +#: ../../po/../src/dialogs/object-attributes.cpp:53 +msgid "X:" +msgstr "" + +#: ../../po/../src/dialogs/object-attributes.cpp:54 +msgid "Y:" +msgstr "" + +#: ../../po/../src/dialogs/object-attributes.cpp:98 +#, c-format +msgid "%s attributes" +msgstr "" + +#: ../../po/../src/dialogs/object-properties.cpp:158 +#, fuzzy +msgid "_Fill" +msgstr "Värv" + +#: ../../po/../src/dialogs/object-properties.cpp:165 +#, fuzzy +msgid "Stroke _paint" +msgstr "Trüki" + +#: ../../po/../src/dialogs/object-properties.cpp:172 +#, fuzzy +msgid "Stroke st_yle" +msgstr "Piirjoon" + +#: ../../po/../src/dialogs/object-properties.cpp:183 +msgid "Master _opacity" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:244 +msgid "Name by which this document is formally known." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:246 +#, fuzzy +msgid "Date" +msgstr "Joonistus" + +#: ../../po/../src/dialogs/rdf.cpp:247 +msgid "Date associated with the creation of this document (YYYY-MM-DD)." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:249 +#, fuzzy +msgid "Format" +msgstr "Värvimine" + +#: ../../po/../src/dialogs/rdf.cpp:250 +msgid "The physical or digital manifestation of this document (MIME type)." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:252 +msgid "Type" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:253 +msgid "Type of document (DCMI Type)." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:256 +#, fuzzy +msgid "Creator" +msgstr "Üldine" + +#: ../../po/../src/dialogs/rdf.cpp:257 +msgid "" +"Name of entity primarily responsible for making the content of this document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:259 +msgid "Rights" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:260 +msgid "" +"Name of entity with rights to the Intellectual Property of this document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:262 +msgid "Publisher" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:263 +msgid "Name of entity responsible for making this document available." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:266 +#, fuzzy +msgid "Identifier" +msgstr "Üldine" + +#: ../../po/../src/dialogs/rdf.cpp:267 +msgid "Unique URI to reference this document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:269 +msgid "Source" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:270 +msgid "Unique URI to reference the source of this document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:272 +#, fuzzy +msgid "Relation" +msgstr "_Selektsioon" + +#: ../../po/../src/dialogs/rdf.cpp:273 +msgid "Unique URI to a related document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:275 +#, fuzzy +msgid "Language" +msgstr "Lehekülg" + +#: ../../po/../src/dialogs/rdf.cpp:276 +msgid "" +"Two-letter language tag with optional subtags for the language of this " +"document. (e.g. 'en-GB')" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:278 +msgid "Keywords" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:279 +msgid "" +"The topic of this document as comma-separated key words, phrases, or " +"classifications." +msgstr "" + +#. TRANSLATORS: "Coverage": the spatial or temporal characteristics of the content. +#. For info, see Appendix D of http://www.w3.org/TR/1998/WD-rdf-schema-19980409/ +#: ../../po/../src/dialogs/rdf.cpp:283 +msgid "Coverage" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:284 +msgid "Extent or scope of this document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:288 +msgid "A short account of the content of this document." +msgstr "" + +#. FIXME: need to handle 1 agent per line of input +#: ../../po/../src/dialogs/rdf.cpp:292 +#, fuzzy +msgid "Contributors" +msgstr "Üldine" + +#: ../../po/../src/dialogs/rdf.cpp:293 +msgid "" +"Names of entities responsible for making contributions to the content of " +"this document." +msgstr "" + +#. TRANSLATORS: URL to a page that defines the license for the document +#: ../../po/../src/dialogs/rdf.cpp:297 +msgid "URI" +msgstr "" + +#. TRANSLATORS: this is where you put a URL to a page that defines the license +#: ../../po/../src/dialogs/rdf.cpp:299 +msgid "URI to this document's license's namespace definition." +msgstr "" + +#. TRANSLATORS: fragment of XML representing the license of the document +#: ../../po/../src/dialogs/rdf.cpp:303 +msgid "Fragment" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:304 +msgid "XML fragment for the RDF 'License' section." +msgstr "" + +#: ../../po/../src/dialogs/stroke-style.cpp:774 +#: ../../po/../src/widgets/gradient-vector.cpp:263 +#: ../../po/../src/widgets/paint-selector.cpp:751 +msgid "No document selected" +msgstr "" + +#: ../../po/../src/dialogs/stroke-style.cpp:992 +#, fuzzy +msgid "Stroke width" +msgstr "Trüki" + +#. Join type +#. TRANSLATORS: The line join style specifies the shape to be used at the +#. corners of paths. It can be "miter", "round" or "bevel". +#: ../../po/../src/dialogs/stroke-style.cpp:1015 +msgid "Join:" +msgstr "" + +#. TRANSLATORS: Miter join: joining lines with a sharp (pointed) corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1027 +msgid "Miter join" +msgstr "" + +#. TRANSLATORS: Round join: joining lines with a rounded corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1035 +#, fuzzy +msgid "Round join" +msgstr "Grupeerib valitud objektid" + +#. TRANSLATORS: Bevel join: joining lines with a blunted (flattened) corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1043 +msgid "Bevel join" +msgstr "" + +#. Miterlimit +#. TRANSLATORS: Miter limit: only for "miter join", this limits the length +#. of the sharp "spike" when the lines connect at too sharp an angle. +#. When two line segments meet at a sharp angle, a miter join results in a +#. spike that extends well beyond the connection point. The purpose of the +#. miter limit is to cut off such spikes (i.e. convert them into bevels) +#. when they become too long. +#: ../../po/../src/dialogs/stroke-style.cpp:1054 +msgid "Miter limit:" +msgstr "" + +#: ../../po/../src/dialogs/stroke-style.cpp:1062 +msgid "Maximum length of the miter (in units of stroke width)" +msgstr "" + +#. Cap type +#. TRANSLATORS: cap type specifies the shape for the ends of lines +#: ../../po/../src/dialogs/stroke-style.cpp:1075 +msgid "Cap:" +msgstr "" + +#. TRANSLATORS: Butt cap: the line shape does not extend beyond the end point +#. of the line; the ends of the line are square +#: ../../po/../src/dialogs/stroke-style.cpp:1086 +msgid "Butt cap" +msgstr "" + +#. TRANSLATORS: Round cap: the line shape extends beyond the end point of the +#. line; the ends of the line are rounded +#: ../../po/../src/dialogs/stroke-style.cpp:1093 +#, fuzzy +msgid "Round cap" +msgstr "Grupeerib valitud objektid" + +#. TRANSLATORS: Square cap: the line shape extends beyond the end point of the +#. line; the ends of the line are square +#: ../../po/../src/dialogs/stroke-style.cpp:1100 +#, fuzzy +msgid "Square cap" +msgstr "Grupeerib valitud objektid" + +#. Dash +#: ../../po/../src/dialogs/stroke-style.cpp:1106 +msgid "Dashes:" +msgstr "" + +#. TRANSLATORS: Path markers are an SVG feature that allows you to attach arbitrary shapes +#. (arrowheads, bullets, faces, whatever) to the start, end, or middle nodes of a path. +#: ../../po/../src/dialogs/stroke-style.cpp:1127 +msgid "Start Markers:" +msgstr "" + +#: ../../po/../src/dialogs/stroke-style.cpp:1137 +msgid "Mid Markers:" +msgstr "" + +#: ../../po/../src/dialogs/stroke-style.cpp:1148 +msgid "End Markers:" +msgstr "" + +#: ../../po/../src/dialogs/swatches.cpp:424 +#, c-format +msgid "Palettes directory (%s) is unavailable." +msgstr "" + +#. TODO: Insert widgets +#: ../../po/../src/dialogs/text-edit.cpp:199 +#: ../../po/../src/ui/dialog/text-properties.cpp:36 +#, fuzzy +msgid "Font" +msgstr "Too kõige ette" + +#: ../../po/../src/dialogs/text-edit.cpp:216 +msgid "Layout" +msgstr "" + +#: ../../po/../src/dialogs/text-edit.cpp:229 +msgid "Align lines left" +msgstr "" + +#. TRANSLATORS: `Center' here is a verb. +#: ../../po/../src/dialogs/text-edit.cpp:243 +#, fuzzy +msgid "Center lines" +msgstr "Üldine" + +#: ../../po/../src/dialogs/text-edit.cpp:256 +msgid "Align lines right" +msgstr "" + +#: ../../po/../src/dialogs/text-edit.cpp:278 +#, fuzzy +msgid "Horizontal text" +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/dialogs/text-edit.cpp:292 +msgid "Vertical text" +msgstr "" + +#: ../../po/../src/dialogs/text-edit.cpp:307 +msgid "Line spacing:" +msgstr "" + +#: ../../po/../src/dialogs/text-edit.cpp:400 +msgid "Set as default" +msgstr "" + +#: ../../po/../src/dialogs/tiledialog.cpp:603 +#, fuzzy +msgid "Rows:" +msgstr "Skaala" + +#: ../../po/../src/dialogs/tiledialog.cpp:613 +msgid "Number of rows" +msgstr "" + +#: ../../po/../src/dialogs/tiledialog.cpp:617 +#, fuzzy +msgid "Equal height" +msgstr "Trüki" + +#: ../../po/../src/dialogs/tiledialog.cpp:627 +msgid "If not set, each row has the height of the tallest object in it" +msgstr "" + +#. #### Radio buttons to control vertical alignment #### +#. #### Radio buttons to control horizontal alignment #### +#: ../../po/../src/dialogs/tiledialog.cpp:637 +#: ../../po/../src/dialogs/tiledialog.cpp:708 +#, fuzzy +msgid "Align:" +msgstr "Shrift" + +#: ../../po/../src/dialogs/tiledialog.cpp:672 +msgid " X " +msgstr "" + +#. #### Number of columns #### +#: ../../po/../src/dialogs/tiledialog.cpp:678 +#, fuzzy +msgid "Columns:" +msgstr "Uus aken" + +#: ../../po/../src/dialogs/tiledialog.cpp:688 +msgid "Number of columns" +msgstr "" + +#: ../../po/../src/dialogs/tiledialog.cpp:692 +msgid "Equal width" +msgstr "" + +#: ../../po/../src/dialogs/tiledialog.cpp:701 +msgid "If not set, each column has the width of the widest object in it" +msgstr "" + +#. #### Radio buttons to control spacing manually or to fit selection bbox #### +#: ../../po/../src/dialogs/tiledialog.cpp:746 +#, fuzzy +msgid "Fit into selection box" +msgstr "D_uplikaat" + +#: ../../po/../src/dialogs/tiledialog.cpp:753 +#, fuzzy +msgid "Set spacing:" +msgstr "Trüki" + +#. #### Y Padding #### +#: ../../po/../src/dialogs/tiledialog.cpp:777 +#, fuzzy +msgid "Row spacing: " +msgstr "Trüki" + +#: ../../po/../src/dialogs/tiledialog.cpp:786 +#, fuzzy +msgid "Vertical spacing between rows" +msgstr "Kustutab valitud objekti(d)" + +#. #### X padding #### +#: ../../po/../src/dialogs/tiledialog.cpp:795 +msgid "Column spacing:" +msgstr "" + +#: ../../po/../src/dialogs/tiledialog.cpp:804 +#, fuzzy +msgid "Horizontal spacing between columns" +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/dialogs/tiledialog.cpp:818 +#, fuzzy +msgid "Arrange selected objects" +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/dialogs/xml-tree.cpp:178 +msgid "Click to select nodes, drag to rearrange." +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:189 +msgid "Click attribute to edit." +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:193 +#, c-format +msgid "" +"Attribute %s selected. Press Ctrl+Enter when done editing to " +"commit changes." +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:284 +msgid "Drag to reorder nodes" +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:304 +#, fuzzy +msgid "New element node" +msgstr "Uus fail" + +#: ../../po/../src/dialogs/xml-tree.cpp:326 +msgid "New text node" +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:347 +#, fuzzy +msgid "Duplicate node" +msgstr "D_uplikaat" + +#: ../../po/../src/dialogs/xml-tree.cpp:368 +#, fuzzy +msgid "Delete node" +msgstr "Kustuta" + +#: ../../po/../src/dialogs/xml-tree.cpp:384 +msgid "Unindent node" +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:399 +msgid "Indent node" +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:411 +#, fuzzy +msgid "Raise node" +msgstr "Lehekülg" + +#: ../../po/../src/dialogs/xml-tree.cpp:423 +msgid "Lower node" +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:468 +msgid "Delete attribute" +msgstr "" + +#. TRANSLATORS: "Attribute" is a noun here +#: ../../po/../src/dialogs/xml-tree.cpp:513 +msgid "Attribute name" +msgstr "" + +#. TRANSLATORS: "Set" is a verb here +#: ../../po/../src/dialogs/xml-tree.cpp:533 +msgid "Set attribute" +msgstr "" + +#. TRANSLATORS: "Set" is a verb here +#: ../../po/../src/dialogs/xml-tree.cpp:535 +#, fuzzy +msgid "Set" +msgstr "_Selektsioon" + +#. TRANSLATORS: "Attribute" is a noun here +#: ../../po/../src/dialogs/xml-tree.cpp:558 +msgid "Attribute value" +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:1318 +#, fuzzy +msgid "New element node..." +msgstr "Uus fail" + +#: ../../po/../src/dialogs/xml-tree.cpp:1339 +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:100 +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:98 +#, fuzzy +msgid "Cancel" +msgstr "Lehekülg" + +#: ../../po/../src/dialogs/xml-tree.cpp:1345 +#, fuzzy +msgid "Create" +msgstr "Üldine" + +#: ../../po/../src/dialogs/xml-tree.cpp:1458 +#, c-format +msgid "" +"Cannot set %s: Another element with value %s already exists!" +msgstr "" + +#: ../../po/../src/document.cpp:369 +#, fuzzy, c-format +msgid "New document %d" +msgstr "Shrift" + +#: ../../po/../src/document.cpp:401 +#, c-format +msgid "Memory document %d" +msgstr "" + +#: ../../po/../src/document.cpp:524 +#, c-format +msgid "Unnamed document %d" +msgstr "" + +#. We hit green anchor, closing Green-Blue-Red +#: ../../po/../src/draw-context.cpp:441 +msgid "Path is closed." +msgstr "" + +#. We hit bot start and end of single curve, closing paths +#: ../../po/../src/draw-context.cpp:456 +msgid "Closing path." +msgstr "" + +#. alpha of color under cursor, to show in the statusbar +#. locale-sensitive printf is OK, since this goes to the UI, not into SVG +#: ../../po/../src/dropper-context.cpp:354 +#, c-format +msgid " alpha %.3g" +msgstr "" + +#. where the color is picked, to show in the statusbar +#: ../../po/../src/dropper-context.cpp:356 +#, c-format +msgid ", averaged with radius %d" +msgstr "" + +#: ../../po/../src/dropper-context.cpp:356 +msgid " under cursor" +msgstr "" + +#. message, to show in the statusbar +#: ../../po/../src/dropper-context.cpp:358 +msgid "Release mouse to set color." +msgstr "" + +#: ../../po/../src/dropper-context.cpp:358 +#: ../../po/../src/tools-switch.cpp:207 +msgid "" +"Click to set fill, Shift+click to set stroke; drag to " +"average color in area; with Alt to pick inverse color; Ctrl+C " +"to copy the color under mouse to clipboard" +msgstr "" + +#: ../../po/../src/extension/dependency.cpp:244 +msgid "Dependency::" +msgstr "" + +#: ../../po/../src/extension/dependency.cpp:245 +#, fuzzy +msgid " type: " +msgstr "Shrift" + +#: ../../po/../src/extension/dependency.cpp:246 +#, fuzzy +msgid " location: " +msgstr "_Selektsioon" + +#: ../../po/../src/extension/dependency.cpp:247 +msgid " string: " +msgstr "" + +#: ../../po/../src/extension/dependency.cpp:250 +#, fuzzy +msgid " description: " +msgstr "_Selektsioon" + +#. static int i = 0; +#. std::cout << "Checking module[" << i++ << "]: " << name << std::endl; +#: ../../po/../src/extension/extension.cpp:244 +msgid "" +" This is caused by an improper .inx file for this extension. An improper ." +"inx file could have been caused by a faulty installation of Inkscape." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:247 +msgid "an ID was not defined for it." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:251 +msgid "there was no name defined for it." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:255 +msgid "the XML description of it got lost." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:259 +msgid "no implementation was defined for the extension." +msgstr "" + +#. std::cout << "Failed: " << *(_deps[i]) << std::endl; +#: ../../po/../src/extension/extension.cpp:266 +msgid "a dependency was not met." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:286 +msgid "Extension \"" +msgstr "" + +#: ../../po/../src/extension/extension.cpp:286 +msgid "\" failed to load because " +msgstr "" + +#: ../../po/../src/extension/extension.cpp:565 +#, c-format +msgid "Could not create extension error log file '%s'" +msgstr "" + +#. This is some filler text, needs to change before relase +#: ../../po/../src/extension/error-file.cpp:56 +msgid "" +"One or more extensions failed to load\n" +"\n" +"The failed extensions have been skipped. Inkscape will continue to run " +"normally but those extensions will be unavailable. For details to " +"troubleshoot this problem, please refer to the error log located at: " +msgstr "" + +#. This is some filler text, needs to change before relase +#: ../../po/../src/extension/error-file.cpp:65 +msgid "Show dialog on startup" +msgstr "" + +#: ../../po/../src/extension/implementation/script.cpp:845 +msgid "" +"Inkscape has received an error from the script that it called. The text " +"returned with the error is included below. Inkscape will continue working, " +"but the action you requested has been cancelled." +msgstr "" + +#: ../../po/../src/extension/implementation/script.cpp:858 +msgid "" +"Inkscape has received additional data from the script executed. The script " +"did not return an error, but this may indicate the results will not be as " +"expected." +msgstr "" + +#: ../../po/../src/extension/init.cpp:173 +msgid "Null external module directory name. Modules will not be loaded." +msgstr "" + +#: ../../po/../src/extension/init.cpp:187 +#, c-format +msgid "" +"Modules directory (%s) is unavailable. External modules in that directory " +"will not be loaded." +msgstr "" + +#: ../../po/../src/extension/internal/gnome.cpp:80 +#, fuzzy +msgid "Select printer" +msgstr "_Selektsioon" + +#: ../../po/../src/extension/internal/gnome.cpp:131 +#, fuzzy +msgid "Inkscape: Print Preview" +msgstr "Trükib faili" + +#: ../../po/../src/extension/internal/grid.cpp:213 +#, fuzzy +msgid "Line Width" +msgstr "Piirjoon" + +#: ../../po/../src/extension/internal/grid.cpp:214 +#, fuzzy +msgid "Horizontal Spacing" +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/extension/internal/grid.cpp:215 +msgid "Vertical Spacing" +msgstr "" + +#: ../../po/../src/extension/internal/grid.cpp:216 +#, fuzzy +msgid "Horizontal Offset" +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/extension/internal/grid.cpp:217 +msgid "Vertical Offset" +msgstr "" + +#: ../../po/../src/extension/internal/ps.cpp:123 +#, fuzzy +msgid "Print Destination" +msgstr "Trükib faili" + +#. Print properties frame +#: ../../po/../src/extension/internal/ps.cpp:138 +#, fuzzy +msgid "Print properties" +msgstr "Trükib faili" + +#: ../../po/../src/extension/internal/ps.cpp:145 +msgid "Print using PostScript operators" +msgstr "" + +#: ../../po/../src/extension/internal/ps.cpp:147 +msgid "" +"Use PostScript vector operators. The resulting image is usually smaller in " +"file size and can be arbitrarily scaled, but alpha transparency and patterns " +"will be lost." +msgstr "" + +#: ../../po/../src/extension/internal/ps.cpp:152 +#, fuzzy +msgid "Print as bitmap" +msgstr "_Import" + +#: ../../po/../src/extension/internal/ps.cpp:154 +msgid "" +"Print everything as bitmap. The resulting image is usually larger in file " +"size and cannot be arbitrarily scaled without quality loss, but all objects " +"will be rendered exactly as displayed." +msgstr "" + +#: ../../po/../src/extension/internal/ps.cpp:168 +msgid "Preferred resolution (dots per inch) of bitmap" +msgstr "" + +#: ../../po/../src/extension/internal/ps.cpp:182 +#, fuzzy +msgid "Resolution:" +msgstr "_Selektsioon" + +#. Print destination frame +#: ../../po/../src/extension/internal/ps.cpp:186 +#, fuzzy +msgid "Print destination" +msgstr "Trükib faili" + +#: ../../po/../src/extension/internal/ps.cpp:192 +msgid "" +"Use '> filename' to print to file.\n" +"Use '| prog arg...' to pipe to a program." +msgstr "" + +#: ../../po/../src/extension/internal/ps.cpp:1227 +msgid "write error occurred" +msgstr "" + +#: ../../po/../src/extension/prefdialog.cpp:21 +#, fuzzy +msgid " Preferences" +msgstr "Sodipodi" + +#. We can't call sp_ui_error_dialog because we may be +#. running from the console, in which case calling sp_ui +#. routines will cause a segfault. See bug 1000350 - bryce +#. sp_ui_error_dialog(_("Format autodetect failed. The file is being opened as SVG.")); +#: ../../po/../src/extension/system.cpp:105 +msgid "Format autodetect failed. The file is being opened as SVG." +msgstr "" + +#. TRANSLATORS: default.svg is localizable - this is the name of the default document +#. template. This way you can localize the default pagesize, translate the name of +#. the default layer, etc. If you wish to localize this file, please create a +#. localized share/templates/default.xx.svg file, where xx is your language code. +#: ../../po/../src/file.cpp:133 +#, fuzzy +msgid "default.svg" +msgstr "Kustuta" + +#: ../../po/../src/file.cpp:215 ../../po/../src/file.cpp:900 +#, c-format +msgid "Failed to load the requested file %s" +msgstr "" + +#: ../../po/../src/file.cpp:240 +#, fuzzy +msgid "Document not saved yet. Cannot revert." +msgstr "Shrift" + +#: ../../po/../src/file.cpp:246 +#, c-format +msgid "Changes will be lost! Are you sure you want to reload document %s?" +msgstr "" + +#: ../../po/../src/file.cpp:266 +#, fuzzy +msgid "Document reverted." +msgstr "Shrift" + +#: ../../po/../src/file.cpp:268 +#, fuzzy +msgid "Document not reverted." +msgstr "Shrift" + +#: ../../po/../src/file.cpp:382 +#, fuzzy +msgid "Select file to open" +msgstr "_Selektsioon" + +#: ../../po/../src/file.cpp:518 +#, c-format +msgid "Removed %i unused definition in <defs>." +msgid_plural "Removed %i unused definitions in <defs>." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/file.cpp:523 +msgid "No unused definitions in <defs>." +msgstr "" + +#: ../../po/../src/file.cpp:548 +#, c-format +msgid "" +"No Inkscape extension found to save document (%s). This may have been " +"caused by an unknown filename extension." +msgstr "" + +#: ../../po/../src/file.cpp:549 ../../po/../src/file.cpp:557 +#, fuzzy +msgid "Document not saved." +msgstr "Shrift" + +#: ../../po/../src/file.cpp:556 +#, c-format +msgid "File %s could not be saved." +msgstr "" + +#: ../../po/../src/file.cpp:566 +#, fuzzy +msgid "Document saved." +msgstr "Shrift" + +#: ../../po/../src/file.cpp:614 +#, fuzzy, c-format +msgid "drawing%s" +msgstr "Joonistus" + +#: ../../po/../src/file.cpp:620 +#, fuzzy, c-format +msgid "drawing-%d%s" +msgstr "Joonistus" + +#: ../../po/../src/file.cpp:655 +#, fuzzy +msgid "Select file to save to" +msgstr "_Selektsioon" + +#: ../../po/../src/file.cpp:739 +msgid "No changes need to be saved." +msgstr "" + +#: ../../po/../src/file.cpp:926 +msgid "Select file to import" +msgstr "" + +#: ../../po/../src/gradient-context.cpp:263 +msgid "Ctrl: snap gradient angle" +msgstr "" + +#: ../../po/../src/gradient-context.cpp:264 +msgid "Shift: draw gradient around the starting point" +msgstr "" + +#. We did an undoable action, but sp_document_done will be called by the knot when released +#. status text; we do not track coords because this branch is run once, not all the time +#. during drag +#: ../../po/../src/gradient-context.cpp:462 +#, c-format +msgid "Gradient for %d objects; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/gradient-context.cpp:464 +#, fuzzy +msgid "Select objects on which to create gradient." +msgstr "Tee jooneks" + +#: ../../po/../src/gradient-drag.cpp:65 +msgid "Linear gradient start" +msgstr "" + +#. POINT_LG_P1 +#: ../../po/../src/gradient-drag.cpp:66 +msgid "Linear gradient end" +msgstr "" + +#: ../../po/../src/gradient-drag.cpp:67 +msgid "Radial gradient center" +msgstr "" + +#: ../../po/../src/gradient-drag.cpp:68 ../../po/../src/gradient-drag.cpp:69 +msgid "Radial gradient radius" +msgstr "" + +#: ../../po/../src/gradient-drag.cpp:70 +msgid "Radial gradient focus" +msgstr "" + +#: ../../po/../src/gradient-drag.cpp:659 +#, c-format +msgid "" +"%s for: %s%s; drag with Ctrl to snap angle, with Ctrl+Alt to " +"preserve angle, with Ctrl+Shift to scale around center" +msgstr "" + +#: ../../po/../src/gradient-drag.cpp:662 +#, fuzzy +msgid " (stroke)" +msgstr "Piirjoon" + +#: ../../po/../src/gradient-drag.cpp:665 +msgid "" +"Radial gradient center and focus; drag with Shift to " +"separate focus" +msgstr "" + +#: ../../po/../src/gradient-drag.cpp:667 +#, c-format +msgid "" +"Gradient point shared by %d gradients; drag with Shift to " +"separate" +msgstr "" + +#: ../../po/../src/helper/units.cpp:40 +msgid "Unit" +msgstr "" + +#: ../../po/../src/helper/units.cpp:40 +msgid "Units" +msgstr "" + +#: ../../po/../src/helper/units.cpp:41 +#, fuzzy +msgid "Point" +msgstr "Trüki" + +#: ../../po/../src/helper/units.cpp:41 +msgid "pt" +msgstr "" + +#: ../../po/../src/helper/units.cpp:41 +#, fuzzy +msgid "Points" +msgstr "Trüki" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Pt" +msgstr "" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Pixel" +msgstr "" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Pixels" +msgstr "" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Px" +msgstr "" + +#. You can add new elements from this point forward +#: ../../po/../src/helper/units.cpp:44 ../share/extensions/straightseg.inx.h:2 +#, fuzzy +msgid "Percent" +msgstr "Trüki" + +#: ../../po/../src/helper/units.cpp:44 +#, fuzzy +msgid "Percents" +msgstr "Trüki" + +#: ../../po/../src/helper/units.cpp:45 +msgid "Millimeter" +msgstr "" + +#: ../../po/../src/helper/units.cpp:45 +msgid "mm" +msgstr "" + +#: ../../po/../src/helper/units.cpp:45 +msgid "Millimeters" +msgstr "" + +#: ../../po/../src/helper/units.cpp:46 +msgid "Centimeter" +msgstr "" + +#: ../../po/../src/helper/units.cpp:46 +msgid "cm" +msgstr "" + +#: ../../po/../src/helper/units.cpp:46 +#, fuzzy +msgid "Centimeters" +msgstr "Üldine" + +#: ../../po/../src/helper/units.cpp:47 +#, fuzzy +msgid "Meter" +msgstr "Üldine" + +#: ../../po/../src/helper/units.cpp:47 +msgid "m" +msgstr "" + +#: ../../po/../src/helper/units.cpp:47 +#, fuzzy +msgid "Meters" +msgstr "Üldine" + +#. no svg_unit +#: ../../po/../src/helper/units.cpp:48 +msgid "Inch" +msgstr "" + +#: ../../po/../src/helper/units.cpp:48 +msgid "in" +msgstr "" + +#: ../../po/../src/helper/units.cpp:48 +msgid "Inches" +msgstr "" + +#. Volatiles do not have default, so there are none here +#. TRANSLATORS: for info, see http://www.w3.org/TR/REC-CSS2/syndata.html#length-units +#: ../../po/../src/helper/units.cpp:51 +msgid "Em square" +msgstr "" + +#: ../../po/../src/helper/units.cpp:51 +msgid "em" +msgstr "" + +#: ../../po/../src/helper/units.cpp:51 +msgid "Em squares" +msgstr "" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/REC-CSS2/syndata.html#length-units +#: ../../po/../src/helper/units.cpp:53 +msgid "Ex square" +msgstr "" + +#: ../../po/../src/helper/units.cpp:53 +#, fuzzy +msgid "ex" +msgstr "Tekst" + +#: ../../po/../src/helper/units.cpp:53 +msgid "Ex squares" +msgstr "" + +#: ../../po/../src/inkscape.cpp:468 +msgid "Untitled document" +msgstr "" + +#. Show nice dialog box +#: ../../po/../src/inkscape.cpp:497 +msgid "Inkscape encountered an internal error and will close now.\n" +msgstr "" + +#: ../../po/../src/inkscape.cpp:498 +msgid "" +"Automatic backups of unsaved documents were done to the following " +"locations:\n" +msgstr "" + +#: ../../po/../src/inkscape.cpp:499 +msgid "Automatic backup of the following documents failed:\n" +msgstr "" + +#: ../../po/../src/inkscape.cpp:634 +#, c-format +msgid "" +"Cannot create directory %s.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:635 +#, c-format +msgid "" +"%s is not a valid directory.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:636 +#, c-format +msgid "" +"Cannot create file %s.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:637 +#, c-format +msgid "" +"Cannot write file %s.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:638 +msgid "" +"Although Inkscape will run, it will use default settings,\n" +"and any changes made in preferences will not be saved." +msgstr "" + +#: ../../po/../src/inkscape.cpp:708 +#, c-format +msgid "" +"%s is not a regular file.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:709 +#, c-format +msgid "" +"%s not a valid XML file, or\n" +"you don't have read permissions on it.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:711 +#, c-format +msgid "" +"%s is not a valid menus file.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:712 +msgid "" +"Inkscape will run with default menus.\n" +"New menus will not be saved." +msgstr "" + +#. sp_ui_menu_append_check_item_from_verb(m, view, _("_Menu"), _("Show or hide the menu bar"), "menu", +#. checkitem_toggled, checkitem_update, 0); +#: ../../po/../src/interface.cpp:753 +msgid "Commands Bar" +msgstr "" + +#: ../../po/../src/interface.cpp:753 +msgid "Show or hide the Commands bar (under the menu)" +msgstr "" + +#: ../../po/../src/interface.cpp:755 +msgid "Tool Controls" +msgstr "" + +#: ../../po/../src/interface.cpp:755 +msgid "Show or hide the Tool Controls panel" +msgstr "" + +#: ../../po/../src/interface.cpp:757 +msgid "_Toolbox" +msgstr "" + +#: ../../po/../src/interface.cpp:757 +msgid "Show or hide the main toolbox (on the left)" +msgstr "" + +#: ../../po/../src/interface.cpp:763 +msgid "_Statusbar" +msgstr "" + +#: ../../po/../src/interface.cpp:763 +msgid "Show or hide the statusbar (at the bottom of the window)" +msgstr "" + +#: ../../po/../src/interface.cpp:820 +#, c-format +msgid "Verb \"%s\" Unknown" +msgstr "" + +#. TRANSLATORS: #%s is the id of the group e.g. , not a number. +#: ../../po/../src/interface.cpp:930 +#, c-format +msgid "Enter group #%s" +msgstr "" + +#: ../../po/../src/interface.cpp:941 +#, fuzzy +msgid "Go to parent" +msgstr "Trüki" + +#: ../../po/../src/interface.cpp:972 +msgid "Could not parse SVG data" +msgstr "" + +#: ../../po/../src/interface.cpp:1135 +#, c-format +msgid "Overwrite %s" +msgstr "" + +#: ../../po/../src/interface.cpp:1153 +#, c-format +msgid "" +"The file %s already exists. Do you want to overwrite that file with the " +"current document?" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:59 +msgid "Jabber connection lost." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:72 +#, c-format +msgid "Sending message; %u message remaining in send queue." +msgid_plural "Sending message; %u messages remaining in send queue." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:78 +msgid "Receive queue empty." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:154 +#, c-format +msgid "Receiving change; %u change left to process." +msgid_plural "Receiving change; %u changes left to process." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:157 +#, c-format +msgid "%s has left the chatroom." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:221 +msgid "Nickname %1 is already in use. Please choose a different nickname." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:225 +msgid "An error was encountered while attempting to connect to the server." +msgstr "" + +#. Check to see if the user made any modifications to this document. If so, +#. we want to give them the option of (1) letting us clear their document or (2) +#. opening a new, blank document for the whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:131 +msgid "%1 has invited you to a whiteboard session." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:132 +msgid "Incoming whiteboard invitation from %1" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:135 +msgid "Do you wish to accept %1's whiteboard session invitation?" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:137 +msgid "" +"Would you like to accept %1's invitation in a new document window?\n" +"Accepting the invitation in your current window will discard unsaved changes." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:143 +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:198 +#, fuzzy +msgid "Accept invitation" +msgstr "_Selektsioon" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:144 +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:199 +msgid "Decline invitation" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:145 +#, fuzzy +msgid "Accept invitation in new document window" +msgstr "Shrift" + +#. We could not create a new desktop; ask the user if she or he wants to +#. replace the current document and accept the invitation, or reject the invitation. +#. TRANSLATORS: %1 is a userid here +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:196 +msgid "" +"A new document window could not be opened for a whiteboard session with %" +"1" +msgstr "" + +#. TRANSLATORS: %1 is the peer whom refused our invitation. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:238 +msgid "" +"The user %1 has refused your " +"whiteboard invitation.\n" +"\n" +msgstr "" + +#. TRANSLATORS: %1 is the peer whom refused our invitation, %2 is our Jabber identity. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:241 +msgid "" +"You are still connected to a Jabber server as %2, and may send an " +"invitation to %1 again, or you may send an invitation to a different " +"user." +msgstr "" + +#. TRANSLATORS: %1 is the peer whom we tried to contact, but is already in a whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:252 +msgid "" +"The user %1 is already in a " +"whiteboard session.\n" +"\n" +msgstr "" + +#. TRANSLATORS: %1 is the peer whom we tried to contact, but is already in a whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:255 +msgid "" +"You are still connected to a Jabber server as %1, and may send an " +"invitation to a different user." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/invitation-confirm-dialog.cpp:26 +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:24 +msgid "_Write session file:" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/message-processors.cpp:145 +#, c-format +msgid "%s has joined the chatroom." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/message-queue.cpp:87 +#, c-format +msgid "%u change in receive queue." +msgid_plural "%u changes in receive queue." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/jabber_whiteboard/message-queue.cpp:117 +#, c-format +msgid "%u change in send queue." +msgid_plural "%u changes in send queue." +msgstr[0] "" +msgstr[1] "" + +#. if ID is NULL, then we have a real problem -- we were not able to find a key +#. nor generate one. The only thing we can really do here is abort, since we have +#. no way to let the other client(s) uniquely identify this object. +#. FIXME: If this indicates a programming bug, then don't request translation with +#. * _(...): it is most useful in untranslated form so that developers may search for +#. * it when someone reports it in a bug report (as we want users to do for all bugs, +#. * as indicated by it being a g_warning string). +#. * +#. * Otherwise, if it is not a programming bug but a network error or a bug in the +#. * remote peer (perhaps running different software) or whatever, then present it in +#. * an alert box, and avoid use of technical jargon `NULL'. +#. +#: ../../po/../src/jabber_whiteboard/message-utilities.cpp:171 +msgid "" +"ID for new object is NULL even after generation and lookup attempts: the new " +"object will NOT be sent, nor will any of its child objects!" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:60 +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:995 +msgid "Select a location and filename" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:62 +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:997 +#, fuzzy +msgid "Set filename" +msgstr "Trükib faili" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:301 +msgid "No SSL certificate was found." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:304 +msgid "The SSL certificate provided by the Jabber server is untrusted." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:307 +msgid "The SSL certificate provided by the Jabber server is expired." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:310 +msgid "" +"The SSL certificate provided by the Jabber server has not been activated." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:313 +msgid "" +"The SSL certificate provided by the Jabber server contains a hostname that " +"does not match the Jabber server's hostname." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:316 +msgid "" +"The SSL certificate provided by the Jabber server contains an invalid " +"fingerprint." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:319 +msgid "An unknown error occurred while setting up the SSL connection." +msgstr "" + +#. TRANSLATORS: %1 is the message that describes the specific error that occurred when +#. establishing the SSL connection. +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:325 +msgid "" +"%1\n" +"\n" +"Do you wish to continue connecting to the Jabber server?" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:328 +msgid "Continue connecting and ignore further errors" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:329 +msgid "Continue connecting, but warn me of further errors" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:330 +#, fuzzy +msgid "Cancel connection" +msgstr "_Selektsioon" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:777 +#, c-format +msgid "Established whiteboard session with %s." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:785 +#, c-format +msgid "%s has left the whiteboard session." +msgstr "" + +#. Inform the user +#. TRANSLATORS: %1 is the name of the user that disconnected, %2 is the name of the user whom the disconnected user disconnected from. +#. This message is not used in a chatroom context. +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:790 +msgid "" +"The user %1 has left the " +"whiteboard session.\n" +"\n" +msgstr "" + +#. TRANSLATORS: %1 and %2 are userids +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:792 +msgid "" +"You are still connected to a Jabber server as %2, and may establish a " +"new session to %1 or a different user." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:988 +msgid "" +"Could not open file %1 for session recording.\n" +"The error encountered was: %2.\n" +"\n" +"You may select a different location to record the session, or you may opt to " +"not record this session." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:990 +msgid "Choose a different location" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:991 +msgid "Skip session recording" +msgstr "" + +#: ../../po/../src/knot.cpp:673 +msgid "Node or handle drag canceled." +msgstr "" + +#: ../../po/../src/libnrtype/FontFactory.cpp:358 +msgid "Ignoring font without family that will crash Pango" +msgstr "" + +#: ../../po/../src/main.cpp:395 +msgid "Print the Inkscape version number" +msgstr "" + +#: ../../po/../src/main.cpp:400 +msgid "Do not use X server (only process files from console)" +msgstr "" + +#: ../../po/../src/main.cpp:405 +msgid "Try to use X server (even if $DISPLAY is not set)" +msgstr "" + +#: ../../po/../src/main.cpp:410 +msgid "Open specified document(s) (option string may be excluded)" +msgstr "" + +#: ../../po/../src/main.cpp:411 ../../po/../src/main.cpp:416 +#: ../../po/../src/main.cpp:421 ../../po/../src/main.cpp:483 +#: ../../po/../src/main.cpp:488 ../../po/../src/main.cpp:493 +msgid "FILENAME" +msgstr "" + +#: ../../po/../src/main.cpp:415 +msgid "Print document(s) to specified output file (use '| program' for pipe)" +msgstr "" + +#: ../../po/../src/main.cpp:420 +msgid "Export document to a PNG file" +msgstr "" + +#: ../../po/../src/main.cpp:425 +msgid "The resolution used for exporting SVG into bitmap (default 90)" +msgstr "" + +#: ../../po/../src/main.cpp:426 +msgid "DPI" +msgstr "" + +#: ../../po/../src/main.cpp:430 +msgid "" +"Exported area in SVG user units (default is the canvas; 0,0 is lower-left " +"corner)" +msgstr "" + +#: ../../po/../src/main.cpp:431 +msgid "x0:y0:x1:y1" +msgstr "" + +#: ../../po/../src/main.cpp:435 +msgid "Exported area is the entire drawing (not canvas)" +msgstr "" + +#: ../../po/../src/main.cpp:440 +msgid "" +"Snap the bitmap export area outwards to the nearest integer values (in SVG " +"user units)" +msgstr "" + +#: ../../po/../src/main.cpp:445 +msgid "The width of exported bitmap in pixels (overrides export-dpi)" +msgstr "" + +#: ../../po/../src/main.cpp:446 +msgid "WIDTH" +msgstr "" + +#: ../../po/../src/main.cpp:450 +msgid "The height of exported bitmap in pixels (overrides export-dpi)" +msgstr "" + +#: ../../po/../src/main.cpp:451 +msgid "HEIGHT" +msgstr "" + +#: ../../po/../src/main.cpp:455 +msgid "The ID of the object to export (overrides export-area)" +msgstr "" + +#: ../../po/../src/main.cpp:456 ../../po/../src/main.cpp:532 +msgid "ID" +msgstr "" + +#. TRANSLATORS: this means: "Only export the object whose id is given in --export-id". +#. See "man inkscape" for details. +#: ../../po/../src/main.cpp:462 +msgid "" +"Export just the object with export-id, hide all others (only with export-id)" +msgstr "" + +#: ../../po/../src/main.cpp:467 +msgid "Use stored filename and DPI hints when exporting (only with export-id)" +msgstr "" + +#: ../../po/../src/main.cpp:472 +msgid "Background color of exported bitmap (any SVG-supported color string)" +msgstr "" + +#: ../../po/../src/main.cpp:473 +msgid "COLOR" +msgstr "" + +#: ../../po/../src/main.cpp:477 +msgid "Background opacity of exported bitmap (either 0.0 to 1.0, or 1 to 255)" +msgstr "" + +#: ../../po/../src/main.cpp:478 +msgid "VALUE" +msgstr "" + +#: ../../po/../src/main.cpp:482 +msgid "Export document to plain SVG file (no sodipodi or inkscape namespaces)" +msgstr "" + +#: ../../po/../src/main.cpp:487 +#, fuzzy +msgid "Export document to a PS file" +msgstr "_Import" + +#: ../../po/../src/main.cpp:492 +msgid "Export document to an EPS file" +msgstr "" + +#: ../../po/../src/main.cpp:497 +#, fuzzy +msgid "Convert text object to paths on export (EPS)" +msgstr "Tee jooneks" + +#: ../../po/../src/main.cpp:502 +msgid "Export files with the bounding box set to the page size (EPS)" +msgstr "" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:508 +msgid "" +"Query the X coordinate of the drawing or, if specified, of the object with --" +"query-id" +msgstr "" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:514 +msgid "" +"Query the Y coordinate of the drawing or, if specified, of the object with --" +"query-id" +msgstr "" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:520 +msgid "" +"Query the width of the drawing or, if specified, of the object with --query-" +"id" +msgstr "" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:526 +msgid "" +"Query the height of the drawing or, if specified, of the object with --query-" +"id" +msgstr "" + +#: ../../po/../src/main.cpp:531 +msgid "The ID of the object whose dimensions are queried" +msgstr "" + +#. TRANSLATORS: this option makes Inkscape print the name (path) of the extension directory +#: ../../po/../src/main.cpp:537 +msgid "Print out the extension directory and exit" +msgstr "" + +#: ../../po/../src/main.cpp:542 +msgid "Show given files one-by-one, switch to next on any key/mouse event" +msgstr "" + +#: ../../po/../src/main.cpp:547 +msgid "Use the new Gtkmm GUI interface" +msgstr "" + +#: ../../po/../src/main.cpp:552 +msgid "Remove unused definitions from the defs section(s) of the document" +msgstr "" + +#: ../../po/../src/main.cpp:741 +msgid "" +"[OPTIONS...] [FILE...]\n" +"\n" +"Available options:" +msgstr "" + +#: ../../po/../src/menus-skeleton.h:17 +#, fuzzy +msgid "_New" +msgstr "Uus" + +#: ../../po/../src/menus-skeleton.h:22 +#, fuzzy +msgid "Open _Recent" +msgstr "Ava" + +#: ../../po/../src/menus-skeleton.h:53 +#, fuzzy +msgid "_Edit" +msgstr "Punktiredaktor" + +#: ../../po/../src/menus-skeleton.h:84 +#, fuzzy +msgid "_View" +msgstr "Uus aken" + +#: ../../po/../src/menus-skeleton.h:85 +#, fuzzy +msgid "_Zoom" +msgstr "Suurendus" + +#: ../../po/../src/menus-skeleton.h:102 +#, fuzzy +msgid "Show/Hide" +msgstr "Vabasta" + +#: ../../po/../src/menus-skeleton.h:107 +#, fuzzy +msgid "_Display mode" +msgstr "Värvimine" + +#: ../../po/../src/menus-skeleton.h:126 +#, fuzzy +msgid "_Layer" +msgstr "_Selektsioon" + +#: ../../po/../src/menus-skeleton.h:143 +#, fuzzy +msgid "_Object" +msgstr "Grupeerib valitud objektid" + +#: ../../po/../src/menus-skeleton.h:165 +#, fuzzy +msgid "_Path" +msgstr "Lehekülg" + +#: ../../po/../src/menus-skeleton.h:188 +#, fuzzy +msgid "_Text" +msgstr "Tekst" + +#: ../../po/../src/menus-skeleton.h:200 +#, fuzzy +msgid "Effects" +msgstr "Grupeerib valitud objektid" + +#: ../../po/../src/menus-skeleton.h:207 +msgid "Whiteboa_rd" +msgstr "" + +#: ../../po/../src/menus-skeleton.h:220 +#, fuzzy +msgid "_Help" +msgstr "Vabasta" + +#: ../../po/../src/menus-skeleton.h:222 +msgid "Tutorials" +msgstr "" + +#: ../../po/../src/node-context.cpp:382 +msgid "" +"Ctrl: toggle node type, snap handle angle, move hor/vert; Ctrl" +"+Alt: move along handles" +msgstr "" + +#: ../../po/../src/node-context.cpp:383 +msgid "" +"Shift: toggle node selection, disable snapping, rotate both handles" +msgstr "" + +#: ../../po/../src/node-context.cpp:384 +msgid "Alt: lock handle length; Ctrl+Alt: move along handles" +msgstr "" + +#: ../../po/../src/nodepath.cpp:1399 ../../po/../src/nodepath.cpp:1411 +#: ../../po/../src/nodepath.cpp:1492 ../../po/../src/nodepath.cpp:1504 +msgid "To join, you must have two endnodes selected." +msgstr "" + +#: ../../po/../src/nodepath.cpp:1633 ../../po/../src/nodepath.cpp:1647 +msgid "" +"Select two non-endpoint nodes on a path between which to delete " +"segments." +msgstr "" + +#: ../../po/../src/nodepath.cpp:1743 +#, fuzzy +msgid "Cannot find path between nodes." +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/nodepath.cpp:2822 +#, c-format +msgid "" +"Node handle: angle %0.2f°, length %s; with Ctrl to snap " +"angle; with Alt to lock length; with Shift to rotate both " +"handles" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3351 +msgid "" +"Node: drag to edit the path; with Ctrl to snap to horizontal/" +"vertical; with Ctrl+Alt to snap to handles' directions" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3375 +msgid "" +"Node handle: drag to shape the curve; with Ctrl to snap angle; " +"with Alt to lock length; with Shift to rotate both handles" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3399 +msgid "" +"Node handle: drag to shape the curve; with Ctrl to snap angle; " +"with Alt to lock length; with Shift to rotate the opposite " +"handle in sync" +msgstr "" + +#. TRANSLATORS: "end" is an adjective here (NOT a verb) +#: ../../po/../src/nodepath.cpp:3591 +#, fuzzy +msgid "end node" +msgstr "Lehekülg" + +#. TRANSLATORS: "cusp" means "sharp" (cusp node); see also the Advanced Tutorial +#: ../../po/../src/nodepath.cpp:3596 +msgid "cusp" +msgstr "" + +#. TRANSLATORS: "smooth" is an adjective here +#: ../../po/../src/nodepath.cpp:3599 +msgid "smooth" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3601 +msgid "symmetric" +msgstr "" + +#. TRANSLATORS: "end" is an adjective here (NOT a verb) +#: ../../po/../src/nodepath.cpp:3607 +msgid "end node, handle retracted (drag with Shift to extend)" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3609 +msgid "one handle retracted (drag with Shift to extend)" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3612 +msgid "both handles retracted (drag with Shift to extend)" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3624 +msgid "Drag nodes or node handles; arrow keys to move nodes" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3625 +msgid "Drag the node or its handles; arrow keys to move the node" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3651 ../../po/../src/nodepath.cpp:3663 +#, fuzzy +msgid "Select a single object to edit its nodes or handles." +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/nodepath.cpp:3655 +#, c-format +msgid "" +"0 out of %i node selected. Click, Shift+click, " +"or drag around nodes to select." +msgid_plural "" +"0 out of %i nodes selected. Click, Shift+click, " +"or drag around nodes to select." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/nodepath.cpp:3661 +msgid "Drag the handles of the object to modify it." +msgstr "" + +#: ../../po/../src/nodepath.cpp:3669 +#, fuzzy, c-format +msgid "%i of %i node selected; %s. %s." +msgid_plural "%i of %i nodes selected; %s. %s." +msgstr[0] "Kustutab valitud objekti(d)" +msgstr[1] "Kustutab valitud objekti(d)" + +#: ../../po/../src/nodepath.cpp:3675 +#, fuzzy, c-format +msgid "%i of %i node selected. %s." +msgid_plural "%i of %i nodes selected. %s." +msgstr[0] "Kustutab valitud objekti(d)" +msgstr[1] "Kustutab valitud objekti(d)" + +#: ../../po/../src/object-edit.cpp:493 +msgid "" +"Adjust the horizontal rounding radius; with Ctrl to make the " +"vertical radius the same" +msgstr "" + +#: ../../po/../src/object-edit.cpp:499 +msgid "" +"Adjust the vertical rounding radius; with Ctrl to make the " +"horizontal radius the same" +msgstr "" + +#: ../../po/../src/object-edit.cpp:506 ../../po/../src/object-edit.cpp:513 +msgid "" +"Adjust the width and height of the rectangle; with Ctrl to " +"lock ratio or stretch in one dimension only" +msgstr "" + +#: ../../po/../src/object-edit.cpp:686 +msgid "Adjust ellipse width, with Ctrl to make circle" +msgstr "" + +#: ../../po/../src/object-edit.cpp:689 +msgid "Adjust ellipse height, with Ctrl to make circle" +msgstr "" + +#: ../../po/../src/object-edit.cpp:692 +msgid "" +"Position the start point of the arc or segment; with Ctrl to " +"snap angle; drag inside the ellipse for arc, outside for " +"segment" +msgstr "" + +#: ../../po/../src/object-edit.cpp:695 +msgid "" +"Position the end point of the arc or segment; with Ctrl to " +"snap angle; drag inside the ellipse for arc, outside for " +"segment" +msgstr "" + +#: ../../po/../src/object-edit.cpp:800 +msgid "" +"Adjust the tip radius of the star or polygon; with Shift to " +"round; with Alt to randomize" +msgstr "" + +#: ../../po/../src/object-edit.cpp:803 +msgid "" +"Adjust the base radius of the star; with Ctrl to keep star " +"rays radial (no skew); with Shift to round; with Alt to " +"randomize" +msgstr "" + +#: ../../po/../src/object-edit.cpp:967 +msgid "" +"Roll/unroll the spiral from inside; with Ctrl to snap angle; " +"with Alt to converge/diverge" +msgstr "" + +#: ../../po/../src/object-edit.cpp:969 +msgid "" +"Roll/unroll the spiral from outside; with Ctrl to snap angle; " +"with Shift to scale/rotate" +msgstr "" + +#: ../../po/../src/object-edit.cpp:1006 +msgid "Adjust the offset distance" +msgstr "" + +#. TRANSLATORS: This refers to the pattern that's inside the object +#: ../../po/../src/object-edit.cpp:1036 +msgid "Move the pattern fill inside the object" +msgstr "" + +#: ../../po/../src/object-edit.cpp:1038 +#, fuzzy +msgid "Scale the pattern fill uniformly" +msgstr "Tee jooneks" + +#: ../../po/../src/object-edit.cpp:1040 +msgid "Rotate the pattern fill; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/object-edit.cpp:1065 +msgid "Drag to resize the flowed text frame" +msgstr "" + +#. Item dialog +#: ../../po/../src/object-ui.cpp:106 +#, fuzzy +msgid "Object _Properties" +msgstr "Trükib faili" + +#. Select item +#: ../../po/../src/object-ui.cpp:116 +#, fuzzy +msgid "_Select This" +msgstr "_Selektsioon" + +#. Create link +#: ../../po/../src/object-ui.cpp:126 +#, fuzzy +msgid "_Create Link" +msgstr "Üldine" + +#. "Ungroup" +#: ../../po/../src/object-ui.cpp:199 ../../po/../src/verbs.cpp:1931 +#, fuzzy +msgid "_Ungroup" +msgstr "Vabasta" + +#. Link dialog +#: ../../po/../src/object-ui.cpp:239 +#, fuzzy +msgid "Link _Properties" +msgstr "Trükib faili" + +#. Select item +#: ../../po/../src/object-ui.cpp:249 +msgid "_Follow Link" +msgstr "" + +#. Reset transformations +#: ../../po/../src/object-ui.cpp:254 +msgid "_Remove Link" +msgstr "" + +#. Link dialog +#: ../../po/../src/object-ui.cpp:303 +#, fuzzy +msgid "Image _Properties" +msgstr "Värvimine" + +#. Item dialog +#: ../../po/../src/object-ui.cpp:344 +#, fuzzy +msgid "_Fill and Stroke" +msgstr "Piirjoon" + +#: ../../po/../src/path-chemistry.cpp:58 +#, fuzzy +msgid "Select at least two objects to combine." +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/path-chemistry.cpp:65 +#, fuzzy +msgid "At least one of the objects is not a path, cannot combine." +msgstr "Tee jooneks" + +#: ../../po/../src/path-chemistry.cpp:73 +msgid "" +"You cannot combine objects from different groups or layers." +msgstr "" + +#: ../../po/../src/path-chemistry.cpp:155 +#, fuzzy +msgid "Select path(s) to break apart." +msgstr "Tee jooneks" + +#: ../../po/../src/path-chemistry.cpp:231 +msgid "No path(s) to break apart in the selection." +msgstr "" + +#: ../../po/../src/path-chemistry.cpp:252 +#, fuzzy +msgid "Select object(s) to convert to path." +msgstr "Tee jooneks" + +#: ../../po/../src/path-chemistry.cpp:297 +#, fuzzy +msgid "No objects to convert to path in the selection." +msgstr "Tee jooneks" + +#: ../../po/../src/path-chemistry.cpp:345 +#, fuzzy +msgid "Select path(s) to reverse." +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/path-chemistry.cpp:370 +msgid "No paths to reverse in the selection." +msgstr "" + +#: ../../po/../src/pen-context.cpp:379 ../../po/../src/pencil-context.cpp:233 +#, fuzzy +msgid "Continuing selected path" +msgstr "Grupeerib valitud objektid" + +#: ../../po/../src/pen-context.cpp:390 ../../po/../src/pencil-context.cpp:242 +#, fuzzy +msgid "Creating new path" +msgstr "Shrift" + +#: ../../po/../src/pen-context.cpp:394 ../../po/../src/pencil-context.cpp:246 +#, fuzzy +msgid "Appending to selected path" +msgstr "D_uplikaat" + +#: ../../po/../src/pen-context.cpp:538 +msgid "Click or click and drag to close and finish the path." +msgstr "" + +#: ../../po/../src/pen-context.cpp:548 +msgid "" +"Click or click and drag to continue the path from this point." +msgstr "" + +#: ../../po/../src/pen-context.cpp:857 +#, c-format +msgid "" +"%s: angle %3.2f°, distance %s; with Ctrl to snap angle, " +"Enter to finish the path" +msgstr "" + +#: ../../po/../src/pen-context.cpp:882 +#, c-format +msgid "" +"Curve handle: angle %3.2f°, length %s; with Ctrl to snap " +"angle" +msgstr "" + +#: ../../po/../src/pen-context.cpp:912 +#, c-format +msgid "" +"%s: angle %3.2f°, length %s; with Ctrl to snap angle, " +"with Shift to move this handle only" +msgstr "" + +#: ../../po/../src/pen-context.cpp:946 +msgid "Finishing pen" +msgstr "" + +#: ../../po/../src/pencil-context.cpp:320 +msgid "Release here to close and finish the path." +msgstr "" + +#: ../../po/../src/pencil-context.cpp:326 +#, fuzzy +msgid "Drawing a freehand path" +msgstr "Shrift" + +#: ../../po/../src/pencil-context.cpp:331 +msgid "Drag to continue the path from this point." +msgstr "" + +#. Write curves to object +#: ../../po/../src/pencil-context.cpp:390 +msgid "Finishing freehand" +msgstr "" + +#: ../../po/../src/rect-context.cpp:387 +msgid "" +"Ctrl: make square or integer-ratio rect, lock a rounded corner " +"circular" +msgstr "" + +#: ../../po/../src/rect-context.cpp:549 +#, c-format +msgid "" +"Rectangle: %s × %s; with Ctrl to make square or integer-" +"ratio rectangle; with Shift to draw around the starting point" +msgstr "" + +#: ../../po/../src/select-context.cpp:243 +#, fuzzy +msgid "Move canceled." +msgstr "_Selektsioon" + +#: ../../po/../src/select-context.cpp:252 +#, fuzzy +msgid "Selection canceled." +msgstr "_Selektsioon" + +#: ../../po/../src/select-context.cpp:642 +msgid "Ctrl: select in groups, move hor/vert" +msgstr "" + +#: ../../po/../src/select-context.cpp:643 +msgid "Shift: toggle select, force rubberband, disable snapping" +msgstr "" + +#: ../../po/../src/select-context.cpp:644 +msgid "Alt: select under, move selected" +msgstr "" + +#: ../../po/../src/select-context.cpp:798 +#, fuzzy +msgid "Selected object is not a group. Cannot enter." +msgstr "Tee jooneks" + +#: ../../po/../src/select-context.cpp:876 +#, c-format +msgid "" +"Move by %s, %s; with Ctrl to restrict to horizontal/vertical; " +"with Shift to disable snapping" +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:228 +msgid "Nothing was deleted." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:259 +#, fuzzy +msgid "Select object(s) to duplicate." +msgstr "Tee jooneks" + +#: ../../po/../src/selection-chemistry.cpp:420 +#, fuzzy +msgid "Select two or more objects to group." +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/selection-chemistry.cpp:428 +#, fuzzy +msgid "Select at least two objects to group." +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/selection-chemistry.cpp:513 +#, fuzzy +msgid "Select a group to ungroup." +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/selection-chemistry.cpp:554 +msgid "No groups to ungroup in the selection." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:623 +#, fuzzy +msgid "Select objects to raise." +msgstr "Tee jooneks" + +#: ../../po/../src/selection-chemistry.cpp:629 +#: ../../po/../src/selection-chemistry.cpp:681 +#: ../../po/../src/selection-chemistry.cpp:715 +#: ../../po/../src/selection-chemistry.cpp:773 +msgid "" +"You cannot raise/lower objects from different groups or layers." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:673 +#, fuzzy +msgid "Select object(s) to raise to top." +msgstr "Tee jooneks" + +#: ../../po/../src/selection-chemistry.cpp:709 +#, fuzzy +msgid "Select object(s) to lower." +msgstr "Tee jooneks" + +#: ../../po/../src/selection-chemistry.cpp:765 +#, fuzzy +msgid "Select object(s) to lower to bottom." +msgstr "Tee jooneks" + +#: ../../po/../src/selection-chemistry.cpp:806 +msgid "Nothing to undo." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:813 +msgid "Nothing to redo." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:969 +msgid "Nothing was copied." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1051 +msgid "Current layer is hidden. Unhide it to be able to paste to it." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1055 +msgid "Current layer is locked. Unlock it to be able to paste to it." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1068 +#: ../../po/../src/selection-chemistry.cpp:1103 +#, fuzzy +msgid "Nothing on the clipboard." +msgstr "Tee jooneks" + +#: ../../po/../src/selection-chemistry.cpp:1109 +#, fuzzy +msgid "Select object(s) to paste style to." +msgstr "Tee jooneks" + +#: ../../po/../src/selection-chemistry.cpp:1128 +#, fuzzy +msgid "Select object(s) to move to the layer above." +msgstr "Tee jooneks" + +#: ../../po/../src/selection-chemistry.cpp:1146 +#, fuzzy +msgid "No more layers above." +msgstr "Shrift" + +#: ../../po/../src/selection-chemistry.cpp:1160 +#, fuzzy +msgid "Select object(s) to move to the layer below." +msgstr "Tee jooneks" + +#: ../../po/../src/selection-chemistry.cpp:1178 +#, fuzzy +msgid "No more layers below." +msgstr "Shrift" + +#: ../../po/../src/selection-chemistry.cpp:1811 +#, fuzzy +msgid "Select a clone to unlink." +msgstr "_Selektsioon" + +#: ../../po/../src/selection-chemistry.cpp:1842 +msgid "No clones to unlink in the selection." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1859 +msgid "" +"Select a clone to go to its original. Select a linked offset " +"to go to its source. Select a text on path to go to the path. Select " +"a flowed text to go to its frame." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1882 +msgid "" +"Cannot find the object to select (orphaned clone, offset, textpath, " +"flowed text?)" +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1888 +msgid "" +"The object you're trying to select is not visible (it is in <" +"defs>)" +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1915 +#, fuzzy +msgid "Select object(s) to convert to pattern." +msgstr "Tee jooneks" + +#: ../../po/../src/selection-chemistry.cpp:2006 +#, fuzzy +msgid "Select an object with pattern fill to extract objects from." +msgstr "Tee jooneks" + +#: ../../po/../src/selection-chemistry.cpp:2059 +#, fuzzy +msgid "No pattern fills in the selection." +msgstr "Tee jooneks" + +#: ../../po/../src/selection-chemistry.cpp:2079 +#, fuzzy +msgid "Select object(s) to make a bitmap copy." +msgstr "Tee jooneks" + +#: ../../po/../src/selection-describer.cpp:37 +msgid "Click selection to toggle scale/rotation handles" +msgstr "" + +#. no items +#: ../../po/../src/selection-describer.cpp:39 +msgid "" +"No objects selected. Click, Shift+click, or drag around objects to select." +msgstr "" + +#: ../../po/../src/selection-describer.cpp:51 +#, fuzzy, c-format +msgid " in layer %s" +msgstr "Lehekülg" + +#: ../../po/../src/selection-describer.cpp:54 +#, fuzzy, c-format +msgid " in layer %s" +msgstr "Lehekülg" + +#: ../../po/../src/selection-describer.cpp:66 +msgid "Use Shift+D to look up original" +msgstr "" + +#: ../../po/../src/selection-describer.cpp:70 +msgid "Use Shift+D to look up path" +msgstr "" + +#: ../../po/../src/selection-describer.cpp:74 +msgid "Use Shift+D to look up frame" +msgstr "" + +#: ../../po/../src/selection-describer.cpp:84 +#, fuzzy, c-format +msgid "%i object selected" +msgid_plural "%i objects selected" +msgstr[0] "Kustutab valitud objekti(d)" +msgstr[1] "Kustutab valitud objekti(d)" + +#: ../../po/../src/selection-describer.cpp:90 +#, c-format +msgid "%s%s. %s." +msgstr "" + +#: ../../po/../src/selection-describer.cpp:94 +#, fuzzy, c-format +msgid "%s in %i layer. %s." +msgid_plural "%s in %i layers. %s." +msgstr[0] "Kustutab valitud objekti(d)" +msgstr[1] "Kustutab valitud objekti(d)" + +#: ../../po/../src/seltrans.cpp:498 +msgid "" +"Center of rotation and skewing: drag to reposition; scaling with " +"Shift also uses this center" +msgstr "" + +#: ../../po/../src/seltrans.cpp:514 +msgid "" +"Squeeze or stretch selection; with Ctrl to scale uniformly; " +"with Shift to scale around rotation center" +msgstr "" + +#: ../../po/../src/seltrans.cpp:515 +msgid "" +"Scale selection; with Ctrl to scale uniformly; with Shift to scale around rotation center" +msgstr "" + +#: ../../po/../src/seltrans.cpp:519 +msgid "" +"Skew selection; with Ctrl to snap angle; with Shift to " +"skew around the opposite side" +msgstr "" + +#: ../../po/../src/seltrans.cpp:520 +msgid "" +"Rotate selection; with Ctrl to snap angle; with Shift " +"to rotate around the opposite corner" +msgstr "" + +#: ../../po/../src/seltrans.cpp:829 ../../po/../src/seltrans.cpp:909 +#, c-format +msgid "Scale: %0.2f%% x %0.2f%%; with Ctrl to lock ratio" +msgstr "" + +#. TRANSLATORS: don't modify the first ";" (it will NOT be displayed as ";" - only the second one will be) +#: ../../po/../src/seltrans.cpp:984 +#, c-format +msgid "Skew: %0.2f°; with Ctrl to snap angle" +msgstr "" + +#. TRANSLATORS: don't modify the first ";" (it will NOT be displayed as ";" - only the second one will be) +#: ../../po/../src/seltrans.cpp:1035 +#, c-format +msgid "Rotate: %0.2f°; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/seltrans.cpp:1090 +#, fuzzy, c-format +msgid "Move center to %s, %s" +msgstr "Punktiredaktor" + +#: ../../po/../src/slideshow.cpp:90 +#, fuzzy +msgid "Inkscape slideshow" +msgstr "Sodipodi" + +#: ../../po/../src/sp-anchor.cpp:181 +#, c-format +msgid "Link to %s" +msgstr "" + +#: ../../po/../src/sp-anchor.cpp:185 +msgid "Link without URI" +msgstr "" + +#: ../../po/../src/sp-ellipse.cpp:438 ../../po/../src/sp-ellipse.cpp:870 +msgid "Ellipse" +msgstr "" + +#: ../../po/../src/sp-ellipse.cpp:583 +msgid "Circle" +msgstr "" + +#: ../../po/../src/sp-ellipse.cpp:865 +#, fuzzy +msgid "Segment" +msgstr "Lehekülg" + +#: ../../po/../src/sp-ellipse.cpp:867 +msgid "Arc" +msgstr "" + +#. TRANSLATORS: "Flow region" is an area where text is allowed to flow +#: ../../po/../src/sp-flowregion.cpp:276 +msgid "Flow region" +msgstr "" + +#. TRANSLATORS: A region "cut out of" a flow region; text is not allowed to flow inside the +#. * flow excluded region. flowRegionExclude in SVG 1.2: see +#. * http://www.w3.org/TR/2004/WD-SVG12-20041027/flow.html#flowRegion-elem and +#. * http://www.w3.org/TR/2004/WD-SVG12-20041027/flow.html#flowRegionExclude-elem. +#: ../../po/../src/sp-flowregion.cpp:493 +msgid "Flow excluded region" +msgstr "" + +#: ../../po/../src/sp-flowtext.cpp:355 +#, c-format +msgid "Flowed text (%d characters)" +msgstr "" + +#: ../../po/../src/sp-flowtext.cpp:357 +#, c-format +msgid "Linked flowed text (%d characters)" +msgstr "" + +#: ../../po/../src/sp-guide.cpp:290 +msgid "vertical guideline" +msgstr "" + +#: ../../po/../src/sp-guide.cpp:292 +#, fuzzy +msgid "horizontal guideline" +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/sp-image.cpp:835 +msgid "embedded" +msgstr "" + +#: ../../po/../src/sp-image.cpp:839 +msgid "(null_pointer)" +msgstr "" + +#: ../../po/../src/sp-image.cpp:843 +#, c-format +msgid "Image with bad reference: %s" +msgstr "" + +#: ../../po/../src/sp-image.cpp:844 +#, c-format +msgid "Image %d × %d: %s" +msgstr "" + +#: ../../po/../src/sp-item-group.cpp:390 +#, fuzzy, c-format +msgid "Group of %d object" +msgid_plural "Group of %d objects" +msgstr[0] "Grupeerib valitud objektid" +msgstr[1] "Grupeerib valitud objektid" + +#: ../../po/../src/sp-item.cpp:720 +msgid "Object" +msgstr "" + +#: ../../po/../src/sp-line.cpp:202 +#, fuzzy +msgid "Line" +msgstr "Lehekülg" + +#. TRANSLATORS COMMENT: %s is either "outset" or "inset" depending on sign +#: ../../po/../src/sp-offset.cpp:433 +#, c-format +msgid "Linked offset, %s by %f pt" +msgstr "" + +#: ../../po/../src/sp-offset.cpp:434 ../../po/../src/sp-offset.cpp:438 +#, fuzzy +msgid "outset" +msgstr "Grupeerib valitud objektid" + +#: ../../po/../src/sp-offset.cpp:434 ../../po/../src/sp-offset.cpp:438 +#, fuzzy +msgid "inset" +msgstr "Trüki" + +#. TRANSLATORS COMMENT: %s is either "outset" or "inset" depending on sign +#: ../../po/../src/sp-offset.cpp:437 +#, c-format +msgid "Dynamic offset, %s by %f pt" +msgstr "" + +#: ../../po/../src/sp-path.cpp:127 +#, fuzzy, c-format +msgid "Path (%i node)" +msgid_plural "Path (%i nodes)" +msgstr[0] "Punktiredaktor" +msgstr[1] "Punktiredaktor" + +#: ../../po/../src/sp-polygon.cpp:216 +#, fuzzy +msgid "Polygon" +msgstr "Lehekülg" + +#: ../../po/../src/sp-polyline.cpp:179 +#, fuzzy +msgid "Polyline" +msgstr "Lehekülg" + +#: ../../po/../src/sp-rect.cpp:250 +#, fuzzy +msgid "Rectangle" +msgstr "Lehekülg" + +#. TRANSLATORS: since turn count isn't an integer, please adjust the +#. string as needed to deal with an localized plural forms. +#: ../../po/../src/sp-spiral.cpp:305 +#, c-format +msgid "Spiral with %3f turns" +msgstr "" + +#: ../../po/../src/sp-star.cpp:288 +#, c-format +msgid "Star with %d vertex" +msgid_plural "Star with %d vertices" +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/sp-star.cpp:292 +#, c-format +msgid "Polygon with %d vertex" +msgid_plural "Polygon with %d vertices" +msgstr[0] "" +msgstr[1] "" + +#. TRANSLATORS: For description of font with no name. +#: ../../po/../src/sp-text.cpp:420 +msgid "<no name found>" +msgstr "" + +#: ../../po/../src/sp-text.cpp:426 +#, fuzzy, c-format +msgid "Text on path (%s, %s)" +msgstr "Punktiredaktor" + +#: ../../po/../src/sp-text.cpp:427 +#, fuzzy, c-format +msgid "Text (%s, %s)" +msgstr "Punktiredaktor" + +#. TRANSLATORS: Used for statusbar description for long chains: +#. * "Clone of: Clone of: ... in Layer 1". +#: ../../po/../src/sp-use.cpp:317 +#, fuzzy +msgid "..." +msgstr "Ava" + +#: ../../po/../src/sp-use.cpp:325 +#, c-format +msgid "Clone of: %s" +msgstr "" + +#: ../../po/../src/sp-use.cpp:329 +msgid "Orphaned clone" +msgstr "" + +#: ../../po/../src/spiral-context.cpp:355 +msgid "Ctrl: snap angle" +msgstr "" + +#: ../../po/../src/spiral-context.cpp:357 +msgid "Alt: lock spiral radius" +msgstr "" + +#: ../../po/../src/spiral-context.cpp:469 +#, c-format +msgid "" +"Spiral: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/splivarot.cpp:106 +#, fuzzy +msgid "Select at least 2 paths to perform a boolean operation." +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/splivarot.cpp:112 +msgid "" +"Select exactly 2 paths to perform difference, XOR, division, or path " +"cut." +msgstr "" + +#: ../../po/../src/splivarot.cpp:129 ../../po/../src/splivarot.cpp:144 +msgid "" +"Unable to determine the z-order of the objects selected for " +"difference, XOR, division, or path cut." +msgstr "" + +#: ../../po/../src/splivarot.cpp:174 +#, fuzzy +msgid "" +"One of the objects is not a path, cannot perform boolean operation." +msgstr "Tee jooneks" + +#. TRANSLATORS: "to outline" means "to convert stroke to path" +#: ../../po/../src/splivarot.cpp:554 +#, fuzzy +msgid "Select path(s) to outline." +msgstr "Tee jooneks" + +#. TRANSLATORS: "to outline" means "to convert stroke to path" +#: ../../po/../src/splivarot.cpp:748 +msgid "No stroked paths to outline in the selection." +msgstr "" + +#: ../../po/../src/splivarot.cpp:832 +#, fuzzy +msgid "Selected object is not a path, cannot inset/outset." +msgstr "Tee jooneks" + +#: ../../po/../src/splivarot.cpp:1040 +#, fuzzy +msgid "Select path(s) to inset/outset." +msgstr "Tee jooneks" + +#: ../../po/../src/splivarot.cpp:1257 +msgid "No paths to inset/outset in the selection." +msgstr "" + +#: ../../po/../src/splivarot.cpp:1390 +#, fuzzy +msgid "Select path(s) to simplify." +msgstr "Tee jooneks" + +#: ../../po/../src/splivarot.cpp:1417 +msgid "No paths to simplify in the selection." +msgstr "" + +#: ../../po/../src/star-context.cpp:362 +msgid "Ctrl: snap angle; keep rays radial" +msgstr "" + +#: ../../po/../src/star-context.cpp:470 +#, c-format +msgid "" +"Polygon: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/star-context.cpp:471 +#, c-format +msgid "Star: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/text-chemistry.cpp:90 +#, fuzzy +msgid "Select a text and a path to put text on path." +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/text-chemistry.cpp:95 +msgid "" +"This text object is already put to a path. Remove it from the path " +"first. Use Shift+D to look up its path." +msgstr "" + +#. rect is the only SPShape which is not yet, and thus SVG forbids us from putting text on it +#: ../../po/../src/text-chemistry.cpp:101 +msgid "" +"You cannot put text on a rectangle in this version. Convert rectangle to " +"path first." +msgstr "" + +#: ../../po/../src/text-chemistry.cpp:159 +#, fuzzy +msgid "Select a text on path to remove it from path." +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/text-chemistry.cpp:181 +#, fuzzy +msgid "No texts-on-paths in the selection." +msgstr "Tee jooneks" + +#: ../../po/../src/text-chemistry.cpp:209 +#: ../../po/../src/text-chemistry.cpp:229 +#, fuzzy +msgid "Select text(s) to remove kerns from." +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/text-chemistry.cpp:250 +#, fuzzy +msgid "" +"Select a text and one or more paths or shapes to flow text " +"into frame." +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/text-chemistry.cpp:322 +#, fuzzy +msgid "Select a flowed text to unflow it." +msgstr "Tee jooneks" + +#: ../../po/../src/text-context.cpp:463 +msgid "Click to edit the text, drag to select part of the text." +msgstr "" + +#: ../../po/../src/text-context.cpp:465 +msgid "" +"Click to edit the flowed text, drag to select part of the text." +msgstr "" + +#: ../../po/../src/text-context.cpp:540 +msgid "Non-printable character" +msgstr "" + +#: ../../po/../src/text-context.cpp:589 +#, c-format +msgid "Unicode: %s: %s" +msgstr "" + +#: ../../po/../src/text-context.cpp:591 ../../po/../src/text-context.cpp:855 +msgid "Unicode: " +msgstr "" + +#: ../../po/../src/text-context.cpp:615 +msgid "Current layer is hidden. Unhide it to be able to add text." +msgstr "" + +#: ../../po/../src/text-context.cpp:619 +msgid "Current layer is locked. Unlock it to be able to add text." +msgstr "" + +#: ../../po/../src/text-context.cpp:673 +#, c-format +msgid "Flowed text frame: %s × %s" +msgstr "" + +#: ../../po/../src/text-context.cpp:708 ../../po/../src/text-context.cpp:1464 +msgid "Type text; Enter to start new line." +msgstr "" + +#: ../../po/../src/text-context.cpp:719 +msgid "Flowed text is created." +msgstr "" + +#: ../../po/../src/text-context.cpp:722 +msgid "" +"The frame is too small for the current font size. Flowed text not " +"created." +msgstr "" + +#: ../../po/../src/text-context.cpp:841 +msgid "No-break space" +msgstr "" + +#: ../../po/../src/text-context.cpp:1462 +msgid "Type flowed text; Enter to start new paragraph." +msgstr "" + +#: ../../po/../src/text-context.cpp:1472 ../../po/../src/tools-switch.cpp:189 +msgid "" +"Click to select or create text, drag to create flowed text; " +"then type." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:141 +msgid "" +"To edit a path, click, Shift+click, or drag around " +"nodes to select them, then drag nodes and handles. Click on an " +"object to select." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:147 +msgid "" +"Drag to create a rectangle. Drag controls to round corners and " +"resize. Click to select." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:153 +msgid "" +"Drag to create an ellipse. Drag controls to make an arc or " +"segment. Click to select." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:159 +msgid "" +"Drag to create a star. Drag controls to edit the star shape. " +"Click to select." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:165 +msgid "" +"Drag to create a spiral. Drag controls to edit the spiral " +"shape. Click to select." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:171 +msgid "" +"Drag to create a freehand line. Start drawing with Shift to " +"append to selected path." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:177 +msgid "" +"Click or click and drag to start a path; with Shift to " +"append to selected path." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:183 +msgid "" +"Drag to paint a calligraphic stroke. Left/right arrow " +"keys adjust width, up/down adjust angle." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:195 +msgid "" +"Drag or double click to create a gradient on selected objects, " +"drag handles to adjust gradients." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:201 +msgid "" +"Click or drag around an area to zoom in, Shift+click to " +"zoom out." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:213 +msgid "Click and drag between shapes to create a connector." +msgstr "" + +#: ../../po/../src/trace/potrace/inkscape-potrace.cpp:553 +#: ../../po/../src/trace/potrace/inkscape-potrace.cpp:654 +#, c-format +msgid "Trace: %d. %ld nodes" +msgstr "" + +#: ../../po/../src/trace/trace.cpp:53 ../../po/../src/trace/trace.cpp:62 +#: ../../po/../src/trace/trace.cpp:70 +#, fuzzy +msgid "Select an image to trace" +msgstr "Tee jooneks" + +#: ../../po/../src/trace/trace.cpp:133 +#, fuzzy +msgid "Trace: No active document" +msgstr "Shrift" + +#: ../../po/../src/trace/trace.cpp:154 +msgid "Trace: Image has no bitmap data" +msgstr "" + +#: ../../po/../src/trace/trace.cpp:267 +#, fuzzy, c-format +msgid "Trace: Done. %ld nodes created" +msgstr "Grupeerib valitud objektid" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:59 ../../po/../src/verbs.cpp:2212 +msgid "About Inkscape" +msgstr "" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:66 +msgid "_Splash" +msgstr "" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:68 +msgid "_Authors" +msgstr "" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:69 +#, fuzzy +msgid "_Translators" +msgstr "_Selektsioon" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:70 +#, fuzzy +msgid "_License" +msgstr "Trüki" + +#. TRANSLATORS: This is the filename of the `About Inkscape' picture in +#. the `screens' directory. Thus the translation of "about.svg" should be +#. the filename of its translated version, e.g. about.zh.svg for Chinese. +#. +#. N.B. about.svg changes once per release. (We should probably rename +#. the original to about-0.40.svg etc. as soon as we have a translation. +#. If we do so, then add an item to release-checklist saying that the +#. string here should be changed.) +#. FIXME? INKSCAPE_SCREENSDIR and "about.svg" are in UTF-8, not the +#. native filename encoding... and the filename passed to sp_document_new +#. should be in UTF-*8.. +#: ../../po/../src/ui/dialog/aboutbox.cpp:114 +msgid "about.svg" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:464 +msgid "Minimum horizontal gap (in px units) between bounding boxes" +msgstr "" + +#. TRANSLATORS: Horizontal gap +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:466 +#: ../../po/../src/widgets/toolbox.cpp:1556 +msgid "H:" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:474 +msgid "Minimum vertical gap (in px units) between bounding boxes" +msgstr "" + +#. TRANSLATORS: Vertical gap +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:476 +msgid "V:" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:734 +msgid "Align" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:735 +msgid "Distribute" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:736 +msgid "Remove overlaps" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:737 +#, fuzzy +msgid "Nodes" +msgstr "Punktiredaktor" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:742 +#, fuzzy +msgid "Relative to: " +msgstr "Lehekülg" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:747 +#, fuzzy +msgid "Align right sides of objects to left side of anchor" +msgstr "Tee jooneks" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:750 +msgid "Align left sides" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:753 +msgid "Center on vertical axis" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:756 +msgid "Align right sides" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:759 +#, fuzzy +msgid "Align left sides of objects to right side of anchor" +msgstr "Tee jooneks" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:762 +#, fuzzy +msgid "Align bottoms of objects to top of anchor" +msgstr "Tee jooneks" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:765 +#, fuzzy +msgid "Align tops" +msgstr "Shrift" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:768 +#, fuzzy +msgid "Center on horizontal axis" +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:771 +msgid "Align bottoms" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:774 +#, fuzzy +msgid "Align tops of objects to bottom of anchor" +msgstr "Tee jooneks" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:779 +#, fuzzy +msgid "Align baseline anchors of texts vertically" +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:782 +#, fuzzy +msgid "Align baseline anchors of texts horizontally" +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:787 +msgid "Make horizontal gaps between objects equal" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:791 +#, fuzzy +msgid "Distribute left sides equidistantly" +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:794 +#, fuzzy +msgid "Distribute centers equidistantly horizontally" +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:797 +#, fuzzy +msgid "Distribute right sides equidistantly" +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:801 +msgid "Make vertical gaps between objects equal" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:805 +#, fuzzy +msgid "Distribute tops equidistantly" +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:808 +#, fuzzy +msgid "Distribute centers equidistantly vertically" +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:811 +msgid "Distribute bottoms equidistantly" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:816 +#, fuzzy +msgid "Distribute baseline anchors of texts horizontally" +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:819 +#, fuzzy +msgid "Distribute baseline anchors of texts vertically" +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:824 +msgid "Randomize centers in both dimensions" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:827 +msgid "Unclump objects: try to equalize edge-to-edge distances" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:832 +msgid "" +"Move objects as little as possible so that their bounding boxes do not " +"overlap" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:837 +#, fuzzy +msgid "Align selected nodes horizontally" +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:840 +#, fuzzy +msgid "Align selected nodes vertically" +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:843 +#, fuzzy +msgid "Distribute selected nodes horizontally" +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:846 +#, fuzzy +msgid "Distribute selected nodes vertically" +msgstr "Kustutab valitud objekti(d)" + +#. Rest of the widgetry +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:851 +msgid "Last selected" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:852 +#, fuzzy +msgid "First selected" +msgstr "Grupeerib valitud objektid" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:853 +msgid "Biggest item" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:854 +msgid "Smallest item" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:856 +#: ../../po/../src/widgets/desktop-widget.cpp:1065 +#, fuzzy +msgid "Drawing" +msgstr "Joonistus" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:91 +msgid "Metadata 1" +msgstr "" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:92 +msgid "Metadata 2" +msgstr "" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:187 +msgid "X coordinate of grid origin" +msgstr "" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:189 +msgid "Y coordinate of grid origin" +msgstr "" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:191 +msgid "Distance of vertical grid lines" +msgstr "" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:193 +#, fuzzy +msgid "Distance of horizontal grid lines" +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:197 +msgid "Max. snapping distance from grid" +msgstr "" + +#: ../../po/../src/ui/dialog/export.cpp:34 +#, fuzzy +msgid "Export" +msgstr "_Import" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:36 +msgid "Fill" +msgstr "Värv" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:37 +#, fuzzy +msgid "Stroke Paint" +msgstr "Trüki" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:38 +#, fuzzy +msgid "Stroke Style" +msgstr "Piirjoon" + +#: ../../po/../src/ui/dialog/find.cpp:34 +#, fuzzy +msgid "Find" +msgstr "Vabasta" + +#: ../../po/../src/ui/dialog/memory.cpp:96 +msgid "Heap" +msgstr "" + +#: ../../po/../src/ui/dialog/memory.cpp:97 +#, fuzzy +msgid "In Use" +msgstr "Trüki" + +#. TRANSLATORS: "Slack" refers to memory which is in the heap but currently unused. +#. More typical usage is to call this memory "free" rather than "slack". +#: ../../po/../src/ui/dialog/memory.cpp:100 +#, fuzzy +msgid "Slack" +msgstr "Piirjoon" + +#: ../../po/../src/ui/dialog/memory.cpp:101 +#, fuzzy +msgid "Total" +msgstr "Värv" + +#: ../../po/../src/ui/dialog/memory.cpp:141 +#: ../../po/../src/ui/dialog/memory.cpp:147 +#: ../../po/../src/ui/dialog/memory.cpp:154 +#: ../../po/../src/ui/dialog/memory.cpp:186 +msgid "Unknown" +msgstr "" + +#: ../../po/../src/ui/dialog/memory.cpp:167 +#, fuzzy +msgid "Combined" +msgstr "Ühenda" + +#: ../../po/../src/ui/dialog/memory.cpp:209 +#, fuzzy +msgid "Recalculate" +msgstr "Lehekülg" + +#: ../../po/../src/ui/dialog/messages.cpp:74 +#, fuzzy +msgid "Ready." +msgstr "Skaala" + +#: ../../po/../src/ui/dialog/messages.cpp:75 +msgid "" +"Enable log display by setting dialogs.debug 'redirect' attribute to 1 in " +"preferences.xml" +msgstr "" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:184 +msgid "_Execute Python" +msgstr "" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:186 +msgid "_Execute Perl" +msgstr "" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:195 +msgid "Script" +msgstr "" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:205 +#, fuzzy +msgid "Output" +msgstr "Grupeerib valitud objektid" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:215 +msgid "Errors" +msgstr "" + +#. Dialog organization +#: ../../po/../src/ui/dialog/session-player.cpp:73 +#, fuzzy +msgid "Session file" +msgstr "Salvestab faili" + +#: ../../po/../src/ui/dialog/session-player.cpp:74 +msgid "Playback controls" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:75 +#, fuzzy +msgid "Message information" +msgstr "_Selektsioon" + +#. Active session file display +#. fixme: Does this mean the active file for the session, or the file for the active session? +#. Please indicate which with a TRANSLATORS comment. +#: ../../po/../src/ui/dialog/session-player.cpp:85 +msgid "Active session file:" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:86 +msgid "Delay (milliseconds):" +msgstr "" + +#. Unload/load buttons +#: ../../po/../src/ui/dialog/session-player.cpp:94 +#, fuzzy +msgid "Close file" +msgstr "Uus aken" + +#: ../../po/../src/ui/dialog/session-player.cpp:95 +msgid "Open new file" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:96 +msgid "Set delay" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:138 +#, fuzzy +msgid "Rewind" +msgstr "Skaala" + +#: ../../po/../src/ui/dialog/session-player.cpp:139 +msgid "Go back one change" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:140 +#, fuzzy +msgid "Pause" +msgstr "Lehekülg" + +#: ../../po/../src/ui/dialog/session-player.cpp:141 +msgid "Go forward one change" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:142 +msgid "Play" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:177 +#: ../../po/../src/verbs.cpp:1573 +msgid "Open session file" +msgstr "" + +#. ##Set up the Potrace panel +#. #### brightness #### +#. #### Multiple scanning#### +#. ----Hbox1 +#: ../../po/../src/ui/dialog/tracedialog.cpp:345 +#: ../../po/../src/ui/dialog/tracedialog.cpp:428 +msgid "Brightness" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:348 +msgid "Trace by a given brightness level" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:355 +msgid "Brightness cutoff for black/white" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:362 +#, fuzzy +msgid "Image Brightness" +msgstr "Värvimine" + +#. #### canny edge detection #### +#. TRANSLATORS: "Canny" is the name of the inventor of this edge detection method +#: ../../po/../src/ui/dialog/tracedialog.cpp:369 +msgid "Optimal Edge Detection (Canny)" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:372 +msgid "Trace with edge detection by J. Canny's algorithm" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:388 +msgid "Brightness cutoff for adjacent pixels (determines edge thickness)" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:395 +#, fuzzy +msgid "Edge Detection" +msgstr "_Selektsioon" + +#. #### quantization #### +#. TRANSLATORS: Color Quantization: the process of reducing the number of colors +#. in an image by selecting an optimized set of representative colors and then +#. re-applying this reduced set to the original image. +#: ../../po/../src/ui/dialog/tracedialog.cpp:404 +#, fuzzy +msgid "Color Quantization" +msgstr "Värvimine" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:407 +msgid "Trace along the boundaries of reduced colors" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:414 +msgid "The number of reduced colors" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:416 +#, fuzzy +msgid "Colors:" +msgstr "Uus aken" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:421 +msgid "Quantization / Reduction" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:431 +msgid "Trace the given number of brightness levels" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:438 +msgid "Scans:" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:440 +msgid "The desired number of scans" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:448 +msgid "Trace the given number of reduced colors" +msgstr "" + +#. ---Hbox3 +#: ../../po/../src/ui/dialog/tracedialog.cpp:454 +msgid "Monochrome" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:457 +msgid "Same as Color, but convert result to grayscale" +msgstr "" + +#. TRANSLATORS: "Stack" is a verb here +#: ../../po/../src/ui/dialog/tracedialog.cpp:460 +#, fuzzy +msgid "Stack" +msgstr "Piirjoon" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:463 +msgid "" +"Stack scans vertically (no gaps) or tile horizontally (usually with gaps)" +msgstr "" + +#. TRANSLATORS: "Smooth" is a verb here +#: ../../po/../src/ui/dialog/tracedialog.cpp:466 +msgid "Smooth" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:469 +msgid "Apply Gaussian blur to the bitmap before tracing" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:473 +msgid "Multiple Scanning" +msgstr "" + +#. #### Preview #### +#: ../../po/../src/ui/dialog/tracedialog.cpp:479 +#: ../../po/../src/ui/dialog/tracedialog.cpp:489 +#, fuzzy +msgid "Preview" +msgstr "Uus aken" + +#. do not expand +#: ../../po/../src/ui/dialog/tracedialog.cpp:483 +msgid "Preview the result without actual tracing" +msgstr "" + +#. #### swap black and white #### +#: ../../po/../src/ui/dialog/tracedialog.cpp:495 +msgid "Invert" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:499 +msgid "Invert black and white regions for single traces" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:503 +msgid "Thanks to Peter Selinger, http://potrace.sourceforge.net" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:506 +#, fuzzy +msgid "Credits" +msgstr "Värvimine" + +#. done +#. TRANSLATORS: Potrace is an application for transforming bitmaps into +#. vector graphics (http://potrace.sourceforge.net/) +#: ../../po/../src/ui/dialog/tracedialog.cpp:514 +#, fuzzy +msgid "Potrace" +msgstr "Trüki" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:527 +#, fuzzy +msgid "Abort a trace in progress" +msgstr "_Import" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:531 +msgid "Execute the trace" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:80 +#: ../../po/../src/ui/dialog/transformation.cpp:90 +#, fuzzy +msgid "_Horizontal" +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/ui/dialog/transformation.cpp:80 +msgid "Horizontal displacement (relative) or position (absolute)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:82 +#: ../../po/../src/ui/dialog/transformation.cpp:92 +#, fuzzy +msgid "_Vertical" +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/ui/dialog/transformation.cpp:82 +msgid "Vertical displacement (relative) or position (absolute)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:84 +#, fuzzy +msgid "_Width" +msgstr "Piirjoon" + +#: ../../po/../src/ui/dialog/transformation.cpp:84 +msgid "Horizontal size increment (absolute or percentage)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:86 +msgid "_Height" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:86 +msgid "Vertical size increment (absolute or percentage)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:88 +#, fuzzy +msgid "A_ngle" +msgstr "Lehekülg" + +#: ../../po/../src/ui/dialog/transformation.cpp:88 +#, fuzzy +msgid "Rotation angle (positive = counterclockwise)" +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/ui/dialog/transformation.cpp:90 +msgid "" +"Horizontal skew angle (positive = counterclockwise), or absolute " +"displacement, or percentage displacement" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:92 +msgid "" +"Vertical skew angle (positive = counterclockwise), or absolute displacement, " +"or percentage displacement" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:95 +#, fuzzy +msgid "Transformation matrix element A" +msgstr "_Selektsioon" + +#: ../../po/../src/ui/dialog/transformation.cpp:96 +#, fuzzy +msgid "Transformation matrix element B" +msgstr "_Selektsioon" + +#: ../../po/../src/ui/dialog/transformation.cpp:97 +#, fuzzy +msgid "Transformation matrix element C" +msgstr "_Selektsioon" + +#: ../../po/../src/ui/dialog/transformation.cpp:98 +#, fuzzy +msgid "Transformation matrix element D" +msgstr "_Selektsioon" + +#: ../../po/../src/ui/dialog/transformation.cpp:99 +#, fuzzy +msgid "Transformation matrix element E" +msgstr "_Selektsioon" + +#: ../../po/../src/ui/dialog/transformation.cpp:100 +#, fuzzy +msgid "Transformation matrix element F" +msgstr "_Selektsioon" + +#: ../../po/../src/ui/dialog/transformation.cpp:102 +#, fuzzy +msgid "Rela_tive move" +msgstr "Lehekülg" + +#: ../../po/../src/ui/dialog/transformation.cpp:102 +msgid "" +"Add the specified relative displacement to the current position; otherwise, " +"edit the current absolute position directly" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:103 +msgid "Scale proportionally" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:103 +msgid "Preserve the width/height ratio of the scaled objects" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:104 +msgid "Apply to each _object separately" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:104 +msgid "" +"Apply the scale/rotate/skew to each selected object separately; otherwise, " +"transform the selection as a whole" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:105 +msgid "Edit c_urrent matrix" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:105 +msgid "" +"Edit the current transform= matrix; otherwise, post-multiply transform= by " +"this matrix" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:115 +#, fuzzy +msgid "_Move" +msgstr "Punktiredaktor" + +#: ../../po/../src/ui/dialog/transformation.cpp:118 +#, fuzzy +msgid "_Scale" +msgstr "Skaala" + +#: ../../po/../src/ui/dialog/transformation.cpp:121 +#, fuzzy +msgid "_Rotate" +msgstr "_Selektsioon" + +#: ../../po/../src/ui/dialog/transformation.cpp:124 +#, fuzzy +msgid "Ske_w" +msgstr "Piirjoon" + +#: ../../po/../src/ui/dialog/transformation.cpp:127 +msgid "Matri_x" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:141 +msgid "Reset the values on the current tab to defaults" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:148 +#, fuzzy +msgid "Apply transformation to selection" +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:43 +msgid "_Use SSL" +msgstr "" + +#. Construct dialog interface +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:68 +#, fuzzy +msgid "_Server:" +msgstr "Värv" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:69 +#, fuzzy +msgid "_Username:" +msgstr "Trükib faili" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:70 +msgid "_Password:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:71 +msgid "P_ort:" +msgstr "" + +#. Buttons +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:99 +#, fuzzy +msgid "Connect" +msgstr "Uus aken" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:126 +msgid "Establishing connection to Jabber server %1 as user %2" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:131 +msgid "Failed to establish connection to Jabber server %1" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:136 +msgid "Authentication failed on Jabber server %1 as %2" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:141 +msgid "SSL initialization failed when connecting to Jabber server %1" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:147 +msgid "Connected to Jabber server %1 as %2" +msgstr "" + +#. Construct labels +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:75 +msgid "Chatroom _name:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:76 +msgid "Chatroom _server:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:77 +msgid "Chatroom _password:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:78 +msgid "Chatroom _handle:" +msgstr "" + +#. Button setup and callback registration +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:97 +msgid "Connect to chatroom" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:132 +msgid "Synchronizing with chatroom %1@%2 using the handle %3" +msgstr "" + +#. Construct dialog interface +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:78 +msgid "_User's Jabber ID:" +msgstr "" + +#. Buttons +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:82 +msgid "_Invite user" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:83 +#, fuzzy +msgid "_Cancel" +msgstr "Lehekülg" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:94 +msgid "Buddy List" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:170 +msgid "Sending whiteboard invitation to %1" +msgstr "" + +#. FIXME: strings are replaced by placeholders, NOT to be translated until the code is enabled +#. See http://sourceforge.net/mailarchive/message.php?msg_id=11746016 for details +#. File menu +#. Edit menu +#. View menu +#. Layer menu +#. Object menu +#. Path menu +#. add(Gtk::StockItem(CLEANUP, _("PLACEHOLDER, do not translate"))); (using Gtk::Stock::CLEAR) +#. Text menu +#. About menu +#. Tools toolbox +#. Select Tool controls +#. Node Tool controls +#. Calligraphy Tool controls +#. Session playback controls +#: ../../po/../src/ui/stock-items.cpp:34 ../../po/../src/ui/stock-items.cpp:35 +#: ../../po/../src/ui/stock-items.cpp:36 ../../po/../src/ui/stock-items.cpp:37 +#: ../../po/../src/ui/stock-items.cpp:38 ../../po/../src/ui/stock-items.cpp:39 +#: ../../po/../src/ui/stock-items.cpp:40 ../../po/../src/ui/stock-items.cpp:41 +#: ../../po/../src/ui/stock-items.cpp:42 ../../po/../src/ui/stock-items.cpp:43 +#: ../../po/../src/ui/stock-items.cpp:46 ../../po/../src/ui/stock-items.cpp:47 +#: ../../po/../src/ui/stock-items.cpp:48 ../../po/../src/ui/stock-items.cpp:49 +#: ../../po/../src/ui/stock-items.cpp:50 ../../po/../src/ui/stock-items.cpp:51 +#: ../../po/../src/ui/stock-items.cpp:52 ../../po/../src/ui/stock-items.cpp:53 +#: ../../po/../src/ui/stock-items.cpp:54 ../../po/../src/ui/stock-items.cpp:55 +#: ../../po/../src/ui/stock-items.cpp:56 ../../po/../src/ui/stock-items.cpp:57 +#: ../../po/../src/ui/stock-items.cpp:58 ../../po/../src/ui/stock-items.cpp:59 +#: ../../po/../src/ui/stock-items.cpp:62 ../../po/../src/ui/stock-items.cpp:63 +#: ../../po/../src/ui/stock-items.cpp:64 ../../po/../src/ui/stock-items.cpp:65 +#: ../../po/../src/ui/stock-items.cpp:66 ../../po/../src/ui/stock-items.cpp:67 +#: ../../po/../src/ui/stock-items.cpp:68 ../../po/../src/ui/stock-items.cpp:69 +#: ../../po/../src/ui/stock-items.cpp:70 ../../po/../src/ui/stock-items.cpp:71 +#: ../../po/../src/ui/stock-items.cpp:72 ../../po/../src/ui/stock-items.cpp:73 +#: ../../po/../src/ui/stock-items.cpp:74 ../../po/../src/ui/stock-items.cpp:75 +#: ../../po/../src/ui/stock-items.cpp:76 ../../po/../src/ui/stock-items.cpp:77 +#: ../../po/../src/ui/stock-items.cpp:78 ../../po/../src/ui/stock-items.cpp:79 +#: ../../po/../src/ui/stock-items.cpp:80 ../../po/../src/ui/stock-items.cpp:81 +#: ../../po/../src/ui/stock-items.cpp:82 ../../po/../src/ui/stock-items.cpp:83 +#: ../../po/../src/ui/stock-items.cpp:84 ../../po/../src/ui/stock-items.cpp:85 +#: ../../po/../src/ui/stock-items.cpp:86 ../../po/../src/ui/stock-items.cpp:87 +#: ../../po/../src/ui/stock-items.cpp:88 ../../po/../src/ui/stock-items.cpp:89 +#: ../../po/../src/ui/stock-items.cpp:92 ../../po/../src/ui/stock-items.cpp:93 +#: ../../po/../src/ui/stock-items.cpp:94 ../../po/../src/ui/stock-items.cpp:95 +#: ../../po/../src/ui/stock-items.cpp:96 ../../po/../src/ui/stock-items.cpp:97 +#: ../../po/../src/ui/stock-items.cpp:98 ../../po/../src/ui/stock-items.cpp:99 +#: ../../po/../src/ui/stock-items.cpp:100 +#: ../../po/../src/ui/stock-items.cpp:101 +#: ../../po/../src/ui/stock-items.cpp:102 +#: ../../po/../src/ui/stock-items.cpp:103 +#: ../../po/../src/ui/stock-items.cpp:104 +#: ../../po/../src/ui/stock-items.cpp:105 +#: ../../po/../src/ui/stock-items.cpp:108 +#: ../../po/../src/ui/stock-items.cpp:109 +#: ../../po/../src/ui/stock-items.cpp:110 +#: ../../po/../src/ui/stock-items.cpp:111 +#: ../../po/../src/ui/stock-items.cpp:112 +#: ../../po/../src/ui/stock-items.cpp:113 +#: ../../po/../src/ui/stock-items.cpp:114 +#: ../../po/../src/ui/stock-items.cpp:115 +#: ../../po/../src/ui/stock-items.cpp:116 +#: ../../po/../src/ui/stock-items.cpp:117 +#: ../../po/../src/ui/stock-items.cpp:118 +#: ../../po/../src/ui/stock-items.cpp:119 +#: ../../po/../src/ui/stock-items.cpp:120 +#: ../../po/../src/ui/stock-items.cpp:121 +#: ../../po/../src/ui/stock-items.cpp:122 +#: ../../po/../src/ui/stock-items.cpp:123 +#: ../../po/../src/ui/stock-items.cpp:124 +#: ../../po/../src/ui/stock-items.cpp:125 +#: ../../po/../src/ui/stock-items.cpp:126 +#: ../../po/../src/ui/stock-items.cpp:127 +#: ../../po/../src/ui/stock-items.cpp:130 +#: ../../po/../src/ui/stock-items.cpp:131 +#: ../../po/../src/ui/stock-items.cpp:132 +#: ../../po/../src/ui/stock-items.cpp:133 +#: ../../po/../src/ui/stock-items.cpp:134 +#: ../../po/../src/ui/stock-items.cpp:135 +#: ../../po/../src/ui/stock-items.cpp:136 +#: ../../po/../src/ui/stock-items.cpp:137 +#: ../../po/../src/ui/stock-items.cpp:138 +#: ../../po/../src/ui/stock-items.cpp:139 +#: ../../po/../src/ui/stock-items.cpp:140 +#: ../../po/../src/ui/stock-items.cpp:141 +#: ../../po/../src/ui/stock-items.cpp:142 +#: ../../po/../src/ui/stock-items.cpp:143 +#: ../../po/../src/ui/stock-items.cpp:144 +#: ../../po/../src/ui/stock-items.cpp:145 +#: ../../po/../src/ui/stock-items.cpp:146 +#: ../../po/../src/ui/stock-items.cpp:150 +#: ../../po/../src/ui/stock-items.cpp:151 +#: ../../po/../src/ui/stock-items.cpp:152 +#: ../../po/../src/ui/stock-items.cpp:153 +#: ../../po/../src/ui/stock-items.cpp:156 +#: ../../po/../src/ui/stock-items.cpp:157 +#: ../../po/../src/ui/stock-items.cpp:158 +#: ../../po/../src/ui/stock-items.cpp:161 +#: ../../po/../src/ui/stock-items.cpp:162 +#: ../../po/../src/ui/stock-items.cpp:163 +#: ../../po/../src/ui/stock-items.cpp:164 +#: ../../po/../src/ui/stock-items.cpp:165 +#: ../../po/../src/ui/stock-items.cpp:166 +#: ../../po/../src/ui/stock-items.cpp:167 +#: ../../po/../src/ui/stock-items.cpp:168 +#: ../../po/../src/ui/stock-items.cpp:169 +#: ../../po/../src/ui/stock-items.cpp:170 +#: ../../po/../src/ui/stock-items.cpp:171 +#: ../../po/../src/ui/stock-items.cpp:172 +#: ../../po/../src/ui/stock-items.cpp:175 +#: ../../po/../src/ui/stock-items.cpp:176 +#: ../../po/../src/ui/stock-items.cpp:177 +#: ../../po/../src/ui/stock-items.cpp:178 +#: ../../po/../src/ui/stock-items.cpp:181 +#: ../../po/../src/ui/stock-items.cpp:182 +#: ../../po/../src/ui/stock-items.cpp:183 +#: ../../po/../src/ui/stock-items.cpp:184 +#: ../../po/../src/ui/stock-items.cpp:185 +#: ../../po/../src/ui/stock-items.cpp:186 +#: ../../po/../src/ui/stock-items.cpp:187 +#: ../../po/../src/ui/stock-items.cpp:188 +#: ../../po/../src/ui/stock-items.cpp:189 +#: ../../po/../src/ui/stock-items.cpp:190 +#: ../../po/../src/ui/stock-items.cpp:191 +#: ../../po/../src/ui/stock-items.cpp:194 +#: ../../po/../src/ui/stock-items.cpp:195 +#: ../../po/../src/ui/stock-items.cpp:198 +#: ../../po/../src/ui/stock-items.cpp:199 +#: ../../po/../src/ui/stock-items.cpp:200 +#: ../../po/../src/ui/stock-items.cpp:201 +#: ../../po/../src/ui/stock-items.cpp:202 +msgid "PLACEHOLDER, do not translate" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:88 +msgid "small" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:89 +msgid "medium" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:90 +#, fuzzy +msgid "large" +msgstr "Lehekülg" + +#: ../../po/../src/ui/widget/panel.cpp:91 +msgid "huge" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:106 +#, fuzzy +msgid "List" +msgstr "Trüki" + +#: ../../po/../src/ui/widget/selected-style.cpp:67 +msgid "F:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:68 +msgid "S:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:69 +msgid "O:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:95 +msgid "N/A" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:98 +#: ../../po/../src/ui/widget/selected-style.cpp:712 +#, fuzzy +msgid "Nothing selected" +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/ui/widget/selected-style.cpp:103 +msgid "No fill" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:103 +#, fuzzy +msgid "No stroke" +msgstr "Piirjoon" + +#: ../../po/../src/ui/widget/selected-style.cpp:105 +#: ../../po/../src/widgets/paint-selector.cpp:190 +#, fuzzy +msgid "Pattern" +msgstr "Lehekülg" + +#: ../../po/../src/ui/widget/selected-style.cpp:108 +#: ../../po/../src/widgets/paint-selector.cpp:885 +#, fuzzy +msgid "Pattern fill" +msgstr "Lehekülg" + +#: ../../po/../src/ui/widget/selected-style.cpp:108 +#, fuzzy +msgid "Pattern stroke" +msgstr "Lehekülg" + +#: ../../po/../src/ui/widget/selected-style.cpp:110 +#, fuzzy +msgid "L Gradient" +msgstr "Trüki" + +#: ../../po/../src/ui/widget/selected-style.cpp:113 +#, fuzzy +msgid "Linear gradient fill" +msgstr "Trüki" + +#: ../../po/../src/ui/widget/selected-style.cpp:113 +#, fuzzy +msgid "Linear gradient stroke" +msgstr "Shrift" + +#: ../../po/../src/ui/widget/selected-style.cpp:115 +#, fuzzy +msgid "R Gradient" +msgstr "Trüki" + +#: ../../po/../src/ui/widget/selected-style.cpp:118 +#, fuzzy +msgid "Radial gradient fill" +msgstr "Trüki" + +#: ../../po/../src/ui/widget/selected-style.cpp:118 +#, fuzzy +msgid "Radial gradient stroke" +msgstr "Grupeerib valitud objektid" + +#: ../../po/../src/ui/widget/selected-style.cpp:120 +#, fuzzy +msgid "Different" +msgstr "Kustuta" + +#: ../../po/../src/ui/widget/selected-style.cpp:123 +#, fuzzy +msgid "Different fills" +msgstr "Kustuta" + +#: ../../po/../src/ui/widget/selected-style.cpp:123 +#, fuzzy +msgid "Different strokes" +msgstr "Kustuta" + +#: ../../po/../src/ui/widget/selected-style.cpp:125 +#, fuzzy +msgid "Unset" +msgstr "Trüki" + +#. TRANSLATORS COMMENT: unset is a verb here +#: ../../po/../src/ui/widget/selected-style.cpp:128 +#: ../../po/../src/ui/widget/selected-style.cpp:182 +#, fuzzy +msgid "Unset fill" +msgstr "_Uus fail" + +#: ../../po/../src/ui/widget/selected-style.cpp:128 +#: ../../po/../src/ui/widget/selected-style.cpp:182 +#, fuzzy +msgid "Unset stroke" +msgstr "Piirjoon" + +#: ../../po/../src/ui/widget/selected-style.cpp:131 +#, fuzzy +msgid "Flat color fill" +msgstr "Värvimine" + +#: ../../po/../src/ui/widget/selected-style.cpp:131 +msgid "Flat color stroke" +msgstr "" + +#. TRANSLATOR COMMENT: A means "Averaged" +#: ../../po/../src/ui/widget/selected-style.cpp:134 +msgid "A" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:137 +#, fuzzy +msgid "Fill is averaged over selected objects" +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/ui/widget/selected-style.cpp:137 +#, fuzzy +msgid "Stroke is averaged over selected objects" +msgstr "Kustutab valitud objekti(d)" + +#. TRANSLATOR COMMENT: M means "Multiple" +#: ../../po/../src/ui/widget/selected-style.cpp:140 +msgid "M" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:143 +#, fuzzy +msgid "Multiple selected objects have the same fill" +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/ui/widget/selected-style.cpp:143 +#, fuzzy +msgid "Multiple selected objects have the same stroke" +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/ui/widget/selected-style.cpp:145 +#, fuzzy +msgid "Edit fill..." +msgstr "Trüki" + +#: ../../po/../src/ui/widget/selected-style.cpp:145 +#, fuzzy +msgid "Edit stroke..." +msgstr "Trüki" + +#: ../../po/../src/ui/widget/selected-style.cpp:149 +msgid "Last set color" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:153 +#, fuzzy +msgid "Last selected color" +msgstr "Grupeerib valitud objektid" + +#: ../../po/../src/ui/widget/selected-style.cpp:157 +msgid "White" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:161 +#: ../../po/../src/widgets/sp-color-scales.cpp:461 +#: ../../po/../src/widgets/sp-color-scales.cpp:462 +#, fuzzy +msgid "Black" +msgstr "Vii kõige taha" + +#: ../../po/../src/ui/widget/selected-style.cpp:165 +#, fuzzy +msgid "Copy color" +msgstr "Uus aken" + +#: ../../po/../src/ui/widget/selected-style.cpp:169 +#, fuzzy +msgid "Paste color" +msgstr "Piirjoon" + +#: ../../po/../src/ui/widget/selected-style.cpp:173 +#, fuzzy +msgid "Swap fill and stroke" +msgstr "Piirjoon" + +#: ../../po/../src/ui/widget/selected-style.cpp:177 +msgid "Make fill opaque" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:177 +msgid "Make stroke opaque" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:186 +msgid "Remove fill" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:186 +#, fuzzy +msgid "Remove stroke" +msgstr "Piirjoon" + +#: ../../po/../src/ui/widget/selected-style.cpp:718 +msgid "Master opacity" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:744 +msgid "0 (transparent)" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:768 +msgid "1.0 (opaque)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1046 +msgid "Moved to next layer." +msgstr "" + +#: ../../po/../src/verbs.cpp:1048 +msgid "Cannot move past last layer." +msgstr "" + +#: ../../po/../src/verbs.cpp:1057 +msgid "Moved to previous layer." +msgstr "" + +#: ../../po/../src/verbs.cpp:1059 +msgid "Cannot move past first layer." +msgstr "" + +#: ../../po/../src/verbs.cpp:1076 ../../po/../src/verbs.cpp:1150 +#, fuzzy +msgid "No current layer." +msgstr "Shrift" + +#: ../../po/../src/verbs.cpp:1105 +#, fuzzy, c-format +msgid "Raised layer %s." +msgstr "Lehekülg" + +#: ../../po/../src/verbs.cpp:1109 +#, fuzzy, c-format +msgid "Lowered layer %s." +msgstr "_Selektsioon" + +#: ../../po/../src/verbs.cpp:1118 +msgid "Cannot move layer any further." +msgstr "" + +#. TRANSLATORS: this means "The layer has been deleted." +#: ../../po/../src/verbs.cpp:1148 +#, fuzzy +msgid "Deleted layer." +msgstr "_Selektsioon" + +#: ../../po/../src/verbs.cpp:1544 +msgid "" +"You need to connect to a Jabber server before sharing a document with " +"another user." +msgstr "" + +#: ../../po/../src/verbs.cpp:1559 +msgid "" +"You need to connect to a Jabber server before sharing a document with a " +"chatroom." +msgstr "" + +#: ../../po/../src/verbs.cpp:1569 +msgid "XML node tracker has not been initialized; nothing to dump" +msgstr "" + +#. TRANSLATORS: If you have translated the keys.svg file to your language, then +#. translate this string as "keys.LANG.svg" (where LANG is your language code); +#. otherwise leave as "keys.svg". +#: ../../po/../src/verbs.cpp:1631 +msgid "keys.svg" +msgstr "" + +#. TRANSLATORS: If you have translated the tutorial-basic.svg file to your language, +#. then translate this string as "tutorial-basic.LANG.svg" (where LANG is your language +#. code); otherwise leave as "tutorial-basic.svg". +#: ../../po/../src/verbs.cpp:1667 +msgid "tutorial-basic.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1671 +msgid "tutorial-shapes.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1675 +msgid "tutorial-advanced.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1679 +msgid "tutorial-tracing.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1683 +msgid "tutorial-calligraphy.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1687 +msgid "tutorial-elements.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1691 +msgid "tutorial-tips.svg" +msgstr "" + +#: ../../po/../src/verbs.cpp:1842 +msgid "Does nothing" +msgstr "" + +#. File +#: ../../po/../src/verbs.cpp:1845 +#, fuzzy +msgid "Default" +msgstr "Kustuta" + +#: ../../po/../src/verbs.cpp:1845 +#, fuzzy +msgid "Create new document from default template" +msgstr "Shrift" + +#: ../../po/../src/verbs.cpp:1847 +#, fuzzy +msgid "_Open..." +msgstr "Ava" + +#: ../../po/../src/verbs.cpp:1848 +#, fuzzy +msgid "Open existing document" +msgstr "Shrift" + +#: ../../po/../src/verbs.cpp:1849 +msgid "Re_vert" +msgstr "" + +#: ../../po/../src/verbs.cpp:1850 +msgid "Revert to the last saved version of document (changes will be lost)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1851 +#, fuzzy +msgid "_Save" +msgstr "Salvesta" + +#: ../../po/../src/verbs.cpp:1851 +#, fuzzy +msgid "Save document" +msgstr "Shrift" + +#: ../../po/../src/verbs.cpp:1853 +#, fuzzy +msgid "Save _As..." +msgstr "Salvestab faili" + +#: ../../po/../src/verbs.cpp:1854 +msgid "Save document under new name" +msgstr "" + +#: ../../po/../src/verbs.cpp:1855 +#, fuzzy +msgid "_Print..." +msgstr "Trüki" + +#: ../../po/../src/verbs.cpp:1855 +#, fuzzy +msgid "Print document" +msgstr "Shrift" + +#. TRANSLATORS: "Vacuum Defs" means "Clean up defs" (so as to remove unused definitions) +#: ../../po/../src/verbs.cpp:1858 +msgid "Vac_uum Defs" +msgstr "" + +#: ../../po/../src/verbs.cpp:1858 +msgid "Remove unused predefined items from the <defs> of the document" +msgstr "" + +#: ../../po/../src/verbs.cpp:1860 +#, fuzzy +msgid "Print _Direct" +msgstr "Trükib faili" + +#: ../../po/../src/verbs.cpp:1861 +msgid "Print directly without prompting to a file or pipe" +msgstr "" + +#: ../../po/../src/verbs.cpp:1862 +#, fuzzy +msgid "Print Previe_w" +msgstr "Trükib faili" + +#: ../../po/../src/verbs.cpp:1863 +#, fuzzy +msgid "Preview document printout" +msgstr "Shrift" + +#: ../../po/../src/verbs.cpp:1864 +#, fuzzy +msgid "_Import..." +msgstr "_Import" + +#: ../../po/../src/verbs.cpp:1865 +msgid "Import bitmap or SVG image into document" +msgstr "" + +#: ../../po/../src/verbs.cpp:1866 +#, fuzzy +msgid "_Export Bitmap..." +msgstr "_Import" + +#: ../../po/../src/verbs.cpp:1867 +#, fuzzy +msgid "Export document or selection as a bitmap image" +msgstr "_Import" + +#: ../../po/../src/verbs.cpp:1868 +#, fuzzy +msgid "N_ext Window" +msgstr "Uus aken" + +#: ../../po/../src/verbs.cpp:1869 +msgid "Switch to the next document window" +msgstr "" + +#: ../../po/../src/verbs.cpp:1870 +#, fuzzy +msgid "P_revious Window" +msgstr "Uus aken" + +#: ../../po/../src/verbs.cpp:1871 +msgid "Switch to the previous document window" +msgstr "" + +#: ../../po/../src/verbs.cpp:1872 +#, fuzzy +msgid "_Close" +msgstr "Uus aken" + +#: ../../po/../src/verbs.cpp:1873 +#, fuzzy +msgid "Close window" +msgstr "Uus aken" + +#: ../../po/../src/verbs.cpp:1874 +msgid "_Quit" +msgstr "" + +#: ../../po/../src/verbs.cpp:1874 +#, fuzzy +msgid "Quit Inkscape" +msgstr "Sodipodi" + +#. Edit +#: ../../po/../src/verbs.cpp:1877 +#, fuzzy +msgid "_Undo" +msgstr "Vabasta" + +#: ../../po/../src/verbs.cpp:1877 +msgid "Undo last action" +msgstr "" + +#: ../../po/../src/verbs.cpp:1879 +msgid "_Redo" +msgstr "" + +#: ../../po/../src/verbs.cpp:1880 +msgid "Do again last undone action" +msgstr "" + +#: ../../po/../src/verbs.cpp:1881 +msgid "Cu_t" +msgstr "" + +#: ../../po/../src/verbs.cpp:1882 +#, fuzzy +msgid "Cut selection to clipboard" +msgstr "Tee jooneks" + +#: ../../po/../src/verbs.cpp:1883 +msgid "_Copy" +msgstr "" + +#: ../../po/../src/verbs.cpp:1884 +#, fuzzy +msgid "Copy selection to clipboard" +msgstr "Tee jooneks" + +#: ../../po/../src/verbs.cpp:1885 +#, fuzzy +msgid "_Paste" +msgstr "Lehekülg" + +#: ../../po/../src/verbs.cpp:1886 +#, fuzzy +msgid "Paste objects from clipboard to mouse point" +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/verbs.cpp:1887 +#, fuzzy +msgid "Paste _Style" +msgstr "Piirjoon" + +#: ../../po/../src/verbs.cpp:1888 +#, fuzzy +msgid "Apply style of the copied object to selection" +msgstr "Tee jooneks" + +#: ../../po/../src/verbs.cpp:1889 +#, fuzzy +msgid "Paste _In Place" +msgstr "Piirjoon" + +#: ../../po/../src/verbs.cpp:1890 +#, fuzzy +msgid "Paste objects from clipboard to the original location" +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/verbs.cpp:1891 +msgid "_Delete" +msgstr "Kustuta" + +#: ../../po/../src/verbs.cpp:1892 +#, fuzzy +msgid "Delete selection" +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/verbs.cpp:1893 +#, fuzzy +msgid "Duplic_ate" +msgstr "D_uplikaat" + +#: ../../po/../src/verbs.cpp:1894 +#, fuzzy +msgid "Duplicate selected objects" +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/verbs.cpp:1895 +#, fuzzy +msgid "Clo_ne" +msgstr "Uus aken" + +#: ../../po/../src/verbs.cpp:1896 +msgid "Create a clone of selected object (a copy linked to the original)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1897 +msgid "Unlin_k Clone" +msgstr "" + +#: ../../po/../src/verbs.cpp:1898 +msgid "Cut the clone's link to its original" +msgstr "" + +#: ../../po/../src/verbs.cpp:1899 +#, fuzzy +msgid "Select _Original" +msgstr "_Selektsioon" + +#: ../../po/../src/verbs.cpp:1900 +#, fuzzy +msgid "Select the object to which the clone is linked" +msgstr "Tee jooneks" + +#. TRANSLATORS: Convert selection to a rectangle with tiled pattern fill +#: ../../po/../src/verbs.cpp:1902 +msgid "O_bjects to Pattern" +msgstr "" + +#: ../../po/../src/verbs.cpp:1903 +msgid "Convert selection to a rectangle with tiled pattern fill" +msgstr "" + +#. TRANSLATORS: Extract objects from a tiled pattern fill +#: ../../po/../src/verbs.cpp:1905 +#, fuzzy +msgid "Pattern to Ob_jects" +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/verbs.cpp:1906 +msgid "Extract objects from a tiled pattern fill" +msgstr "" + +#: ../../po/../src/verbs.cpp:1907 +msgid "Clea_r All" +msgstr "" + +#: ../../po/../src/verbs.cpp:1908 +msgid "Delete all objects from document" +msgstr "" + +#: ../../po/../src/verbs.cpp:1909 +#, fuzzy +msgid "Select Al_l" +msgstr "_Selektsioon" + +#: ../../po/../src/verbs.cpp:1910 +#, fuzzy +msgid "Select all objects or all nodes" +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/verbs.cpp:1911 +#, fuzzy +msgid "Select All in All La_yers" +msgstr "_Selektsioon" + +#: ../../po/../src/verbs.cpp:1912 +#, fuzzy +msgid "Select all objects in all visible and unlocked layers" +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/verbs.cpp:1913 +#, fuzzy +msgid "In_vert Selection" +msgstr "_Selektsioon" + +#: ../../po/../src/verbs.cpp:1914 +msgid "Invert selection (unselect what is selected and select everything else)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1915 +msgid "Invert in All Layers" +msgstr "" + +#: ../../po/../src/verbs.cpp:1916 +msgid "Invert selection in all visible and unlocked layers" +msgstr "" + +#: ../../po/../src/verbs.cpp:1917 +#, fuzzy +msgid "D_eselect" +msgstr "_Selektsioon" + +#: ../../po/../src/verbs.cpp:1918 +#, fuzzy +msgid "Deselect any selected objects or nodes" +msgstr "Kustutab valitud objekti(d)" + +#. Selection +#: ../../po/../src/verbs.cpp:1921 +#, fuzzy +msgid "Raise to _Top" +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/verbs.cpp:1922 +#, fuzzy +msgid "Raise selection to top" +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/verbs.cpp:1923 +#, fuzzy +msgid "Lower to _Bottom" +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/verbs.cpp:1924 +#, fuzzy +msgid "Lower selection to bottom" +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/verbs.cpp:1925 +#, fuzzy +msgid "_Raise" +msgstr "Lehekülg" + +#: ../../po/../src/verbs.cpp:1926 +#, fuzzy +msgid "Raise selection one step" +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/verbs.cpp:1927 +msgid "_Lower" +msgstr "" + +#: ../../po/../src/verbs.cpp:1928 +#, fuzzy +msgid "Lower selection one step" +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/verbs.cpp:1929 +#, fuzzy +msgid "_Group" +msgstr "Grupeeri" + +#: ../../po/../src/verbs.cpp:1930 +#, fuzzy +msgid "Group selected objects" +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/verbs.cpp:1932 +#, fuzzy +msgid "Ungroup selected groups" +msgstr "Lõhub valitud grupi objektideks" + +#: ../../po/../src/verbs.cpp:1934 +#, fuzzy +msgid "_Put on Path" +msgstr "Tee jooneks" + +#: ../../po/../src/verbs.cpp:1935 +#, fuzzy +msgid "Put text on path" +msgstr "Tee jooneks" + +#: ../../po/../src/verbs.cpp:1936 +#, fuzzy +msgid "_Remove from Path" +msgstr "Tee jooneks" + +#: ../../po/../src/verbs.cpp:1937 +#, fuzzy +msgid "Remove text from path" +msgstr "Tee jooneks" + +#: ../../po/../src/verbs.cpp:1938 +msgid "Remove Manual _Kerns" +msgstr "" + +#. TRANSLATORS: "glyph": An image used in the visual representation of characters; +#. roughly speaking, how a character looks. A font is a set of glyphs. +#: ../../po/../src/verbs.cpp:1941 +msgid "Remove all manual kerns and glyph rotations from a text object" +msgstr "" + +#: ../../po/../src/verbs.cpp:1943 +msgid "_Union" +msgstr "" + +#: ../../po/../src/verbs.cpp:1944 +#, fuzzy +msgid "Union of selected objects" +msgstr "Lõhub valitud grupi objektideks" + +#: ../../po/../src/verbs.cpp:1945 +#, fuzzy +msgid "_Intersection" +msgstr "_Interaktiivne" + +#: ../../po/../src/verbs.cpp:1946 +#, fuzzy +msgid "Intersection of selected objects" +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/verbs.cpp:1947 +#, fuzzy +msgid "_Difference" +msgstr "Kustuta" + +#: ../../po/../src/verbs.cpp:1948 +#, fuzzy +msgid "Difference of selected objects (bottom minus top)" +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/verbs.cpp:1949 +#, fuzzy +msgid "E_xclusion" +msgstr "_Selektsioon" + +#: ../../po/../src/verbs.cpp:1950 +#, fuzzy +msgid "Exclusive OR of selected objects" +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/verbs.cpp:1951 +msgid "Di_vision" +msgstr "" + +#: ../../po/../src/verbs.cpp:1952 +msgid "Cut the bottom object into pieces" +msgstr "" + +#. TRANSLATORS: "to cut a path" is not the same as "to break a path apart" - see the +#. Advanced tutorial for more info +#: ../../po/../src/verbs.cpp:1955 +#, fuzzy +msgid "Cut _Path" +msgstr "Grupeerib valitud objektid" + +#: ../../po/../src/verbs.cpp:1956 +msgid "Cut the bottom object's stroke into pieces, removing fill" +msgstr "" + +#. TRANSLATORS: "outset": expand a shape by offsetting the object's path, +#. i.e. by displacing it perpendicular to the path in each point. +#. See also the Advanced Tutorial for explanation. +#: ../../po/../src/verbs.cpp:1960 +#, fuzzy +msgid "Outs_et" +msgstr "Grupeerib valitud objektid" + +#: ../../po/../src/verbs.cpp:1961 +#, fuzzy +msgid "Outset selected paths" +msgstr "Grupeerib valitud objektid" + +#: ../../po/../src/verbs.cpp:1963 +#, fuzzy +msgid "O_utset Path by 1 px" +msgstr "Grupeerib valitud objektid" + +#: ../../po/../src/verbs.cpp:1964 +#, fuzzy +msgid "Outset selected paths by 1 px" +msgstr "Grupeerib valitud objektid" + +#: ../../po/../src/verbs.cpp:1966 +#, fuzzy +msgid "O_utset Path by 10 px" +msgstr "Grupeerib valitud objektid" + +#: ../../po/../src/verbs.cpp:1967 +#, fuzzy +msgid "Outset selected paths by 10 px" +msgstr "Grupeerib valitud objektid" + +#. TRANSLATORS: "inset": contract a shape by offsetting the object's path, +#. i.e. by displacing it perpendicular to the path in each point. +#. See also the Advanced Tutorial for explanation. +#: ../../po/../src/verbs.cpp:1971 +msgid "I_nset" +msgstr "" + +#: ../../po/../src/verbs.cpp:1972 +#, fuzzy +msgid "Inset selected paths" +msgstr "Grupeerib valitud objektid" + +#: ../../po/../src/verbs.cpp:1974 +#, fuzzy +msgid "I_nset Path by 1 px" +msgstr "Grupeerib valitud objektid" + +#: ../../po/../src/verbs.cpp:1975 +#, fuzzy +msgid "Inset selected paths by 1 px" +msgstr "Grupeerib valitud objektid" + +#: ../../po/../src/verbs.cpp:1977 +#, fuzzy +msgid "I_nset Path by 10 px" +msgstr "Grupeerib valitud objektid" + +#: ../../po/../src/verbs.cpp:1978 +#, fuzzy +msgid "Inset selected paths by 10 px" +msgstr "Grupeerib valitud objektid" + +#: ../../po/../src/verbs.cpp:1980 +msgid "D_ynamic Offset" +msgstr "" + +#: ../../po/../src/verbs.cpp:1980 +msgid "Create a dynamic offset object" +msgstr "" + +#: ../../po/../src/verbs.cpp:1982 +msgid "_Linked Offset" +msgstr "" + +#: ../../po/../src/verbs.cpp:1983 +msgid "Create a dynamic offset object linked to the original path" +msgstr "" + +#: ../../po/../src/verbs.cpp:1985 +#, fuzzy +msgid "_Stroke to Path" +msgstr "Piirjoon" + +#: ../../po/../src/verbs.cpp:1986 +#, fuzzy +msgid "Convert selected strokes to paths" +msgstr "Tee jooneks" + +#: ../../po/../src/verbs.cpp:1987 +#, fuzzy +msgid "Si_mplify" +msgstr "Grupeerib valitud objektid" + +#: ../../po/../src/verbs.cpp:1988 +#, fuzzy +msgid "Simplify selected paths by removing extra nodes" +msgstr "Grupeerib valitud objektid" + +#: ../../po/../src/verbs.cpp:1989 +#, fuzzy +msgid "_Reverse" +msgstr "Värv" + +#: ../../po/../src/verbs.cpp:1990 +#, fuzzy +msgid "Reverses the direction of selected paths; useful for flipping markers" +msgstr "Kustutab valitud objekti(d)" + +#. TRANSLATORS: "to trace" means "to convert a bitmap to vector graphics" (to vectorize) +#: ../../po/../src/verbs.cpp:1992 +#, fuzzy +msgid "_Trace Bitmap" +msgstr "_Import" + +#: ../../po/../src/verbs.cpp:1993 +#, fuzzy +msgid "Convert bitmap object to paths" +msgstr "Tee jooneks" + +#: ../../po/../src/verbs.cpp:1994 +#, fuzzy +msgid "_Make a Bitmap Copy" +msgstr "_Import" + +#: ../../po/../src/verbs.cpp:1995 +msgid "Export selection to a bitmap and insert it into document" +msgstr "" + +#: ../../po/../src/verbs.cpp:1996 +msgid "_Combine" +msgstr "Ühenda" + +#: ../../po/../src/verbs.cpp:1997 +msgid "Combine several paths into one" +msgstr "" + +#. TRANSLATORS: "to cut a path" is not the same as "to break a path apart" - see the +#. Advanced tutorial for more info +#: ../../po/../src/verbs.cpp:2000 +#, fuzzy +msgid "Break _Apart" +msgstr "Lammuta" + +#: ../../po/../src/verbs.cpp:2001 +#, fuzzy +msgid "Break selected paths into subpaths" +msgstr "Grupeerib valitud objektid" + +#: ../../po/../src/verbs.cpp:2002 +#, fuzzy +msgid "Gri_d Arrange..." +msgstr "Korraldus" + +#: ../../po/../src/verbs.cpp:2003 +msgid "Arrange selection in grid pattern" +msgstr "" + +#. Layer +#: ../../po/../src/verbs.cpp:2005 +#, fuzzy +msgid "_Add Layer..." +msgstr "Lehekülg" + +#: ../../po/../src/verbs.cpp:2006 +#, fuzzy +msgid "Create a new layer" +msgstr "Shrift" + +#: ../../po/../src/verbs.cpp:2007 +#, fuzzy +msgid "Re_name Layer..." +msgstr "Lehekülg" + +#: ../../po/../src/verbs.cpp:2008 +#, fuzzy +msgid "Rename the current layer" +msgstr "_Selektsioon" + +#: ../../po/../src/verbs.cpp:2009 +#, fuzzy +msgid "Switch to Layer Abov_e" +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/verbs.cpp:2010 +msgid "Switch to the layer above the current" +msgstr "" + +#: ../../po/../src/verbs.cpp:2011 +#, fuzzy +msgid "Switch to Layer Belo_w" +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/verbs.cpp:2012 +msgid "Switch to the layer below the current" +msgstr "" + +#: ../../po/../src/verbs.cpp:2013 +#, fuzzy +msgid "Move Selection to Layer Abo_ve" +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/verbs.cpp:2014 +msgid "Move selection to the layer above the current" +msgstr "" + +#: ../../po/../src/verbs.cpp:2015 +#, fuzzy +msgid "Move Selection to Layer Bel_ow" +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/verbs.cpp:2016 +msgid "Move selection to the layer below the current" +msgstr "" + +#: ../../po/../src/verbs.cpp:2017 +#, fuzzy +msgid "Layer to _Top" +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/verbs.cpp:2018 +#, fuzzy +msgid "Raise the current layer to the top" +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/verbs.cpp:2019 +#, fuzzy +msgid "Layer to _Bottom" +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/verbs.cpp:2020 +#, fuzzy +msgid "Lower the current layer to the bottom" +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/verbs.cpp:2021 +#, fuzzy +msgid "_Raise Layer" +msgstr "Lehekülg" + +#: ../../po/../src/verbs.cpp:2022 +msgid "Raise the current layer" +msgstr "" + +#: ../../po/../src/verbs.cpp:2023 +#, fuzzy +msgid "_Lower Layer" +msgstr "_Selektsioon" + +#: ../../po/../src/verbs.cpp:2024 +msgid "Lower the current layer" +msgstr "" + +#: ../../po/../src/verbs.cpp:2025 +#, fuzzy +msgid "_Delete Current Layer" +msgstr "_Selektsioon" + +#: ../../po/../src/verbs.cpp:2026 +#, fuzzy +msgid "Delete the current layer" +msgstr "_Selektsioon" + +#. Object +#: ../../po/../src/verbs.cpp:2029 +#, fuzzy +msgid "Rotate _90° CW" +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/verbs.cpp:2030 +#, fuzzy +msgid "Rotate selection 90° clockwise" +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/verbs.cpp:2031 +#, fuzzy +msgid "Rotate 9_0° CCW" +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/verbs.cpp:2032 +#, fuzzy +msgid "Rotate selection 90° counter-clockwise" +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/verbs.cpp:2033 +msgid "Remove _Transformations" +msgstr "" + +#: ../../po/../src/verbs.cpp:2034 +msgid "Remove transformations from object" +msgstr "" + +#: ../../po/../src/verbs.cpp:2035 +msgid "_Object to Path" +msgstr "" + +#: ../../po/../src/verbs.cpp:2036 +#, fuzzy +msgid "Convert selected objects to paths" +msgstr "Tee jooneks" + +#: ../../po/../src/verbs.cpp:2037 +msgid "_Flow into Frame" +msgstr "" + +#: ../../po/../src/verbs.cpp:2038 +#, fuzzy +msgid "Put text into frames" +msgstr "Tee jooneks" + +#: ../../po/../src/verbs.cpp:2039 +#, fuzzy +msgid "_Unflow" +msgstr "Vabasta" + +#: ../../po/../src/verbs.cpp:2040 +msgid "Remove text from frame (creates a single-line text object)" +msgstr "" + +#: ../../po/../src/verbs.cpp:2041 +#, fuzzy +msgid "_Convert to Text" +msgstr "Tee jooneks" + +#: ../../po/../src/verbs.cpp:2042 +#, fuzzy +msgid "Convert flowed text to regular text objects (preserves appearance)" +msgstr "Tee jooneks" + +#: ../../po/../src/verbs.cpp:2044 +#, fuzzy +msgid "Flip _Horizontal" +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/verbs.cpp:2044 +#, fuzzy +msgid "Flips selected objects horizontally" +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/verbs.cpp:2047 +#, fuzzy +msgid "Flip _Vertical" +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/verbs.cpp:2047 +#, fuzzy +msgid "Flips selected objects vertically" +msgstr "Kustutab valitud objekti(d)" + +#. Tools +#: ../../po/../src/verbs.cpp:2051 +#, fuzzy +msgid "Select" +msgstr "_Selektsioon" + +#: ../../po/../src/verbs.cpp:2052 +#, fuzzy +msgid "Select and transform objects" +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/verbs.cpp:2053 +#, fuzzy +msgid "Node Edit" +msgstr "Punktiredaktor" + +#: ../../po/../src/verbs.cpp:2054 +#, fuzzy +msgid "Edit path nodes or control handles" +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/verbs.cpp:2056 +msgid "Create rectangles and squares" +msgstr "" + +#: ../../po/../src/verbs.cpp:2058 +msgid "Create circles, ellipses, and arcs" +msgstr "" + +#: ../../po/../src/verbs.cpp:2060 +msgid "Create stars and polygons" +msgstr "" + +#: ../../po/../src/verbs.cpp:2062 +#, fuzzy +msgid "Create spirals" +msgstr "Üldine" + +#: ../../po/../src/verbs.cpp:2064 +msgid "Draw freehand lines" +msgstr "" + +#: ../../po/../src/verbs.cpp:2066 +msgid "Draw Bezier curves and straight lines" +msgstr "" + +#: ../../po/../src/verbs.cpp:2068 +msgid "Draw calligraphic lines" +msgstr "" + +#: ../../po/../src/verbs.cpp:2070 +#, fuzzy +msgid "Create and edit text objects" +msgstr "Grupeerib valitud objektid" + +#: ../../po/../src/verbs.cpp:2072 +#, fuzzy +msgid "Create and edit gradients" +msgstr "Grupeerib valitud objektid" + +#: ../../po/../src/verbs.cpp:2074 +#, fuzzy +msgid "Zoom in or out" +msgstr "Suurendus" + +#: ../../po/../src/verbs.cpp:2076 +msgid "Pick averaged colors from image" +msgstr "" + +#: ../../po/../src/verbs.cpp:2078 +#, fuzzy +msgid "Create connectors" +msgstr "Shrift" + +#. Tool prefs +#: ../../po/../src/verbs.cpp:2081 +msgid "Selector Preferences" +msgstr "" + +#: ../../po/../src/verbs.cpp:2082 +#, fuzzy +msgid "Open Preferences for the Selector tool" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2083 +msgid "Node Tool Preferences" +msgstr "" + +#: ../../po/../src/verbs.cpp:2084 +#, fuzzy +msgid "Open Preferences for the Node tool" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2085 +#, fuzzy +msgid "Rectangle Preferences" +msgstr "Trükib faili" + +#: ../../po/../src/verbs.cpp:2086 +#, fuzzy +msgid "Open Preferences for the Rectangle tool" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2087 +#, fuzzy +msgid "Ellipse Preferences" +msgstr "Värvimine" + +#: ../../po/../src/verbs.cpp:2088 +#, fuzzy +msgid "Open Preferences for the Ellipse tool" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2089 +#, fuzzy +msgid "Star Preferences" +msgstr "Värvimine" + +#: ../../po/../src/verbs.cpp:2090 +#, fuzzy +msgid "Open Preferences for the Star tool" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2091 +#, fuzzy +msgid "Spiral Preferences" +msgstr "Värvimine" + +#: ../../po/../src/verbs.cpp:2092 +#, fuzzy +msgid "Open Preferences for the Spiral tool" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2093 +#, fuzzy +msgid "Pencil Preferences" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2094 +#, fuzzy +msgid "Open Preferences for the Pencil tool" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2095 +#, fuzzy +msgid "Pen Preferences" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2096 +#, fuzzy +msgid "Open Preferences for the Pen tool" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2097 +msgid "Calligraphic Preferences" +msgstr "" + +#: ../../po/../src/verbs.cpp:2098 +#, fuzzy +msgid "Open Preferences for the Calligraphy tool" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2099 +#, fuzzy +msgid "Text Preferences" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2100 +#, fuzzy +msgid "Open Preferences for the Text tool" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2101 +#, fuzzy +msgid "Gradient Preferences" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2102 +#, fuzzy +msgid "Open Preferences for the Gradient tool" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2103 +#, fuzzy +msgid "Zoom Preferences" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2104 +#, fuzzy +msgid "Open Preferences for the Zoom tool" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2105 +#, fuzzy +msgid "Dropper Preferences" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2106 +#, fuzzy +msgid "Open Preferences for the Dropper tool" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2107 +#, fuzzy +msgid "Connector Preferences" +msgstr "Värvimine" + +#: ../../po/../src/verbs.cpp:2108 +#, fuzzy +msgid "Open Preferences for the Connector tool" +msgstr "Sodipodi" + +#. Zoom/View +#: ../../po/../src/verbs.cpp:2111 +#, fuzzy +msgid "Zoom In" +msgstr "Suurendus" + +#: ../../po/../src/verbs.cpp:2111 +#, fuzzy +msgid "Zoom in" +msgstr "Suurendus" + +#: ../../po/../src/verbs.cpp:2112 +#, fuzzy +msgid "Zoom Out" +msgstr "Suurendus" + +#: ../../po/../src/verbs.cpp:2112 +#, fuzzy +msgid "Zoom out" +msgstr "Suurendus" + +#: ../../po/../src/verbs.cpp:2113 +#, fuzzy +msgid "_Rulers" +msgstr "Värv" + +#: ../../po/../src/verbs.cpp:2113 +msgid "Show or hide the canvas rulers" +msgstr "" + +#: ../../po/../src/verbs.cpp:2114 +msgid "Scroll_bars" +msgstr "" + +#: ../../po/../src/verbs.cpp:2114 +msgid "Show or hide the canvas scrollbars" +msgstr "" + +#: ../../po/../src/verbs.cpp:2115 +msgid "_Grid" +msgstr "" + +#: ../../po/../src/verbs.cpp:2116 +msgid "G_uides" +msgstr "" + +#: ../../po/../src/verbs.cpp:2117 +msgid "Nex_t Zoom" +msgstr "" + +#: ../../po/../src/verbs.cpp:2117 +msgid "Next zoom (from the history of zooms)" +msgstr "" + +#: ../../po/../src/verbs.cpp:2119 +msgid "Pre_vious Zoom" +msgstr "" + +#: ../../po/../src/verbs.cpp:2119 +msgid "Previous zoom (from the history of zooms)" +msgstr "" + +#: ../../po/../src/verbs.cpp:2121 +#, fuzzy +msgid "Zoom 1:_1" +msgstr "Suurendus" + +#: ../../po/../src/verbs.cpp:2121 +#, fuzzy +msgid "Zoom to 1:1" +msgstr "Suurendus" + +#: ../../po/../src/verbs.cpp:2123 +#, fuzzy +msgid "Zoom 1:_2" +msgstr "Suurendus" + +#: ../../po/../src/verbs.cpp:2123 +#, fuzzy +msgid "Zoom to 1:2" +msgstr "Suurendus" + +#: ../../po/../src/verbs.cpp:2125 +#, fuzzy +msgid "_Zoom 2:1" +msgstr "Suurendus" + +#: ../../po/../src/verbs.cpp:2125 +#, fuzzy +msgid "Zoom to 2:1" +msgstr "Suurendus" + +#: ../../po/../src/verbs.cpp:2128 +msgid "_Fullscreen" +msgstr "" + +#: ../../po/../src/verbs.cpp:2128 +msgid "Stretch this document window to full screen" +msgstr "" + +#: ../../po/../src/verbs.cpp:2131 +#, fuzzy +msgid "Duplic_ate Window" +msgstr "D_uplikaat" + +#: ../../po/../src/verbs.cpp:2131 +#, fuzzy +msgid "Open a new window with the same document" +msgstr "Shrift" + +#: ../../po/../src/verbs.cpp:2133 +#, fuzzy +msgid "_New View Preview" +msgstr "Uus aken" + +#: ../../po/../src/verbs.cpp:2134 +#, fuzzy +msgid "New View Preview" +msgstr "Uus aken" + +#. "view_new_preview" +#: ../../po/../src/verbs.cpp:2136 +#, fuzzy +msgid "_Normal" +msgstr "Värvimine" + +#: ../../po/../src/verbs.cpp:2137 +msgid "Switch to normal display mode" +msgstr "" + +#: ../../po/../src/verbs.cpp:2138 +#, fuzzy +msgid "_Outline" +msgstr "Uus aken" + +#: ../../po/../src/verbs.cpp:2139 +msgid "Switch to outline (wireframe) display mode" +msgstr "" + +#: ../../po/../src/verbs.cpp:2141 +#, fuzzy +msgid "Ico_n Preview" +msgstr "Uus aken" + +#: ../../po/../src/verbs.cpp:2142 +msgid "Open a window to preview items at different icon resolutions" +msgstr "" + +#: ../../po/../src/verbs.cpp:2144 +msgid "Zoom to fit page in window" +msgstr "" + +#: ../../po/../src/verbs.cpp:2145 +#, fuzzy +msgid "Page _Width" +msgstr "Piirjoon" + +#: ../../po/../src/verbs.cpp:2146 +msgid "Zoom to fit page width in window" +msgstr "" + +#: ../../po/../src/verbs.cpp:2148 +#, fuzzy +msgid "Zoom to fit drawing in window" +msgstr "Suurendus" + +#: ../../po/../src/verbs.cpp:2150 +#, fuzzy +msgid "Zoom to fit selection in window" +msgstr "_Selektsioon" + +#. Dialogs +#: ../../po/../src/verbs.cpp:2153 +#, fuzzy +msgid "In_kscape Preferences..." +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2154 +#, fuzzy +msgid "Global Inkscape preferences" +msgstr "Värvimine" + +#: ../../po/../src/verbs.cpp:2155 +msgid "_Document Preferences..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2156 +#, fuzzy +msgid "Preferences saved with the document" +msgstr "Shrift" + +#: ../../po/../src/verbs.cpp:2157 +#, fuzzy +msgid "_Fill and Stroke..." +msgstr "Piirjoon" + +#: ../../po/../src/verbs.cpp:2158 +#, fuzzy +msgid "Fill and Stroke dialog" +msgstr "Piirjoon" + +#. TRANSLATORS: "Swatches" means: color samples +#: ../../po/../src/verbs.cpp:2160 +#, fuzzy +msgid "S_watches..." +msgstr "Salvestab faili" + +#: ../../po/../src/verbs.cpp:2161 +msgid "View color swatches" +msgstr "" + +#: ../../po/../src/verbs.cpp:2162 +#, fuzzy +msgid "Transfor_m..." +msgstr "_Selektsioon" + +#: ../../po/../src/verbs.cpp:2163 +#, fuzzy +msgid "Transform dialog" +msgstr "_Selektsioon" + +#: ../../po/../src/verbs.cpp:2164 +#, fuzzy +msgid "_Align and Distribute..." +msgstr "Grupeerib valitud objektid" + +#: ../../po/../src/verbs.cpp:2165 +#, fuzzy +msgid "Align and Distribute dialog" +msgstr "Grupeerib valitud objektid" + +#: ../../po/../src/verbs.cpp:2166 +#, fuzzy +msgid "_Text and Font..." +msgstr "Piirjoon" + +#: ../../po/../src/verbs.cpp:2167 +#, fuzzy +msgid "Text and Font dialog" +msgstr "Piirjoon" + +#: ../../po/../src/verbs.cpp:2168 +msgid "_XML Editor..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2169 +msgid "XML Editor" +msgstr "" + +#: ../../po/../src/verbs.cpp:2170 +#, fuzzy +msgid "_Find..." +msgstr "Trüki" + +#: ../../po/../src/verbs.cpp:2171 +#, fuzzy +msgid "Find objects in document" +msgstr "Shrift" + +#: ../../po/../src/verbs.cpp:2172 +msgid "_Messages..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2173 +msgid "View debug messages" +msgstr "" + +#: ../../po/../src/verbs.cpp:2174 +#, fuzzy +msgid "S_cripts..." +msgstr "Trüki" + +#: ../../po/../src/verbs.cpp:2175 +#, fuzzy +msgid "Run scripts" +msgstr "Grupeerib valitud objektid" + +#: ../../po/../src/verbs.cpp:2176 +#, fuzzy +msgid "Show/Hide D_ialogs" +msgstr "Piirjoon" + +#: ../../po/../src/verbs.cpp:2177 +msgid "Show or hide all active dialogs" +msgstr "" + +#. TRANSLATORS: "Tile clones" means: "Create tiled clones" +#: ../../po/../src/verbs.cpp:2179 +msgid "Tile clones..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2180 +msgid "Create and arrange multiple clones of selection" +msgstr "" + +#: ../../po/../src/verbs.cpp:2181 +#, fuzzy +msgid "_Object Properties..." +msgstr "Trükib faili" + +#: ../../po/../src/verbs.cpp:2182 +#, fuzzy +msgid "Object Properties dialog" +msgstr "Trükib faili" + +#: ../../po/../src/verbs.cpp:2185 +msgid "_Connect to Jabber server..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2185 +msgid "Connect to a Jabber server" +msgstr "" + +#: ../../po/../src/verbs.cpp:2187 +#, fuzzy +msgid "Share with _user..." +msgstr "Salvestab faili" + +#: ../../po/../src/verbs.cpp:2187 +msgid "Establish a whiteboard session with another Jabber user" +msgstr "" + +#: ../../po/../src/verbs.cpp:2189 +msgid "Share with _chatroom..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2189 +msgid "" +"Join a chatroom to start a new whiteboard session or join one in progress" +msgstr "" + +#: ../../po/../src/verbs.cpp:2191 +msgid "_Dump XML node tracker" +msgstr "" + +#: ../../po/../src/verbs.cpp:2191 +msgid "Dump the contents of the XML tracker to the console" +msgstr "" + +#: ../../po/../src/verbs.cpp:2193 +msgid "_Open session file..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2193 +msgid "Open and browse through records of past whiteboard sessions" +msgstr "" + +#: ../../po/../src/verbs.cpp:2195 +msgid "Session file playback" +msgstr "" + +#: ../../po/../src/verbs.cpp:2197 +msgid "_Disconnect from session" +msgstr "" + +#: ../../po/../src/verbs.cpp:2199 +msgid "Disconnect from _server" +msgstr "" + +#: ../../po/../src/verbs.cpp:2201 +msgid "_Input Devices..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2202 +msgid "Configure extended input devices" +msgstr "" + +#. Help +#: ../../po/../src/verbs.cpp:2205 +msgid "_Keys and Mouse" +msgstr "" + +#: ../../po/../src/verbs.cpp:2206 +msgid "Key and mouse shortcuts reference" +msgstr "" + +#: ../../po/../src/verbs.cpp:2207 +#, fuzzy +msgid "About E_xtensions" +msgstr "D_uplikaat" + +#: ../../po/../src/verbs.cpp:2208 +#, fuzzy +msgid "About Extensions..." +msgstr "D_uplikaat" + +#: ../../po/../src/verbs.cpp:2209 +#, fuzzy +msgid "About _Memory" +msgstr "D_uplikaat" + +#: ../../po/../src/verbs.cpp:2210 +#, fuzzy +msgid "About Memory..." +msgstr "D_uplikaat" + +#: ../../po/../src/verbs.cpp:2211 +msgid "_About Inkscape" +msgstr "" + +#. "help_about" +#. new HelpVerb(SP_VERB_SHOW_LICENSE, "ShowLicense", N_("Modifying or Redistributing Inkscape"), +#. N_("Show license to modify and/or redistribute Inkscape: GNU GPL"), NULL), +#. Tutorials +#: ../../po/../src/verbs.cpp:2217 +#, fuzzy +msgid "Inkscape: _Basic" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2218 +msgid "Getting started with Inkscape" +msgstr "" + +#. "tutorial_basic" +#: ../../po/../src/verbs.cpp:2219 +#, fuzzy +msgid "Inkscape: _Shapes" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2220 +msgid "Using shape tools to create and edit shapes" +msgstr "" + +#: ../../po/../src/verbs.cpp:2221 +#, fuzzy +msgid "Inkscape: _Advanced" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2222 +#, fuzzy +msgid "Advanced Inkscape topics" +msgstr "Sodipodi" + +#. "tutorial_advanced" +#. TRANSLATORS: "to trace" means "to convert a bitmap to vector graphics" (to vectorize) +#: ../../po/../src/verbs.cpp:2224 +#, fuzzy +msgid "Inkscape: T_racing" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2225 +msgid "Using bitmap tracing" +msgstr "" + +#. "tutorial_tracing" +#: ../../po/../src/verbs.cpp:2226 +#, fuzzy +msgid "Inkscape: _Calligraphy" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2227 +msgid "Using the Calligraphy pen tool" +msgstr "" + +#: ../../po/../src/verbs.cpp:2228 +msgid "_Elements of Design" +msgstr "" + +#: ../../po/../src/verbs.cpp:2229 +msgid "Principles of design in the tutorial form" +msgstr "" + +#. "tutorial_design" +#: ../../po/../src/verbs.cpp:2230 +msgid "_Tips and Tricks" +msgstr "" + +#: ../../po/../src/verbs.cpp:2231 +msgid "Miscellaneous tips and tricks" +msgstr "" + +#. "tutorial_tips" +#. Effect +#: ../../po/../src/verbs.cpp:2234 +msgid "Previous Effect" +msgstr "" + +#: ../../po/../src/verbs.cpp:2235 +msgid "Repeat the last effect with the same settings" +msgstr "" + +#. "tutorial_tips" +#: ../../po/../src/verbs.cpp:2236 +msgid "Previous Effect Settings..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2237 +msgid "Repeat the last effect with new settings" +msgstr "" + +#: ../../po/../src/widgets/dash-selector.cpp:106 +#, fuzzy +msgid "Dash pattern" +msgstr "Trüki" + +#: ../../po/../src/widgets/dash-selector.cpp:121 +#, fuzzy +msgid "Pattern offset" +msgstr "Lehekülg" + +#: ../../po/../src/widgets/desktop-widget.cpp:240 +#, fuzzy +msgid "Zoom drawing if window size changes" +msgstr "Suurendus" + +#: ../../po/../src/widgets/desktop-widget.cpp:298 +msgid "Cursor coordinates" +msgstr "" + +#. display the initial welcome message in the statusbar +#: ../../po/../src/widgets/desktop-widget.cpp:324 +msgid "" +"Welcome to Inkscape! Use shape or freehand tools to create objects; " +"use selector (arrow) to move or transform them." +msgstr "" + +#: ../../po/../src/widgets/desktop-widget.cpp:372 +#, c-format +msgid "%s: %d - Inkscape" +msgstr "" + +#: ../../po/../src/widgets/desktop-widget.cpp:374 +#, c-format +msgid "%s - Inkscape" +msgstr "" + +#: ../../po/../src/widgets/desktop-widget.cpp:532 +#, c-format +msgid "" +"Save changes to document \"%s\" before " +"closing?\n" +"\n" +"If you close without saving, your changes will be discarded." +msgstr "" + +#: ../../po/../src/widgets/desktop-widget.cpp:548 +#: ../../po/../src/widgets/desktop-widget.cpp:612 +msgid "Close _without saving" +msgstr "" + +#: ../../po/../src/widgets/desktop-widget.cpp:595 +#, c-format +msgid "" +"The file \"%s\" was saved with a " +"format (%s) that may cause data loss!\n" +"\n" +"Do you want to save this file in another format?" +msgstr "" + +#. Family frame +#: ../../po/../src/widgets/font-selector.cpp:156 +msgid "Font family" +msgstr "" + +#. Style frame +#: ../../po/../src/widgets/font-selector.cpp:184 +#, fuzzy +msgid "Style" +msgstr "Skaala" + +#: ../../po/../src/widgets/font-selector.cpp:219 +msgid "Font size:" +msgstr "" + +#. TRANSLATORS: Test string used in text and font dialog (when no +#. * text has been entered) to get a preview of the font. Choose +#. * some representative characters that users of your locale will be +#. * interested in. +#: ../../po/../src/widgets/font-selector.cpp:554 +msgid "AaBbCcIiPpQq12368.;/()" +msgstr "" + +#: ../../po/../src/widgets/gradient-selector.cpp:137 +#: ../../po/../src/widgets/gradient-toolbar.cpp:524 +#, fuzzy +msgid "Duplicate" +msgstr "D_uplikaat" + +#: ../../po/../src/widgets/gradient-selector.cpp:142 +#: ../../po/../src/widgets/gradient-toolbar.cpp:535 +#, fuzzy +msgid "Edit..." +msgstr "Trüki" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/pservers.html#LinearGradientSpreadMethodAttribute +#: ../../po/../src/widgets/gradient-selector.cpp:159 +msgid "" +"Whether to fill with flat color beyond the ends of the gradient vector " +"(spreadMethod=\"pad\"), or repeat the gradient in the same direction " +"(spreadMethod=\"repeat\"), or repeat the gradient in alternating opposite " +"directions (spreadMethod=\"reflect\")" +msgstr "" + +#: ../../po/../src/widgets/gradient-selector.cpp:165 +msgid "none" +msgstr "" + +#: ../../po/../src/widgets/gradient-selector.cpp:169 +#, fuzzy +msgid "reflected" +msgstr "Grupeerib valitud objektid" + +#: ../../po/../src/widgets/gradient-selector.cpp:173 +#, fuzzy +msgid "direct" +msgstr "Lehekülg" + +#: ../../po/../src/widgets/gradient-selector.cpp:181 +msgid "Repeat:" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:217 +msgid "No gradients" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:226 +#, fuzzy +msgid "Nothing selected" +msgstr "Grupeerib valitud objektid" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:237 +#, fuzzy +msgid "No gradients in selection" +msgstr "Grupeerib valitud objektid" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:247 +msgid "Multiple gradients" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:525 +msgid "" +"If the gradient is used by more than one object, create a copy of it for the " +"selected object(s)" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:536 +msgid "Edit the stops of the gradient" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:593 +#: ../../po/../src/widgets/toolbox.cpp:1103 +#: ../../po/../src/widgets/toolbox.cpp:1192 +#: ../../po/../src/widgets/toolbox.cpp:1485 +#: ../../po/../src/widgets/toolbox.cpp:1534 +#: ../../po/../src/widgets/toolbox.cpp:1766 +#: ../../po/../src/widgets/toolbox.cpp:1801 +#: ../../po/../src/widgets/toolbox.cpp:2331 +#: ../../po/../src/widgets/toolbox.cpp:2370 +msgid "New:" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:606 +#, fuzzy +msgid "Create linear gradient" +msgstr "Shrift" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:620 +msgid "Create radial (elliptic or circular) gradient" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:635 +#, fuzzy +msgid "on" +msgstr "Trüki" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:648 +#, fuzzy +msgid "Create gradient in the fill" +msgstr "Trüki" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:662 +msgid "Create gradient in the stroke" +msgstr "" + +#. FIXME: implement averaging of all parameters for multiple selected stars +#. gtk_label_set_markup(GTK_LABEL(l), _("Average:")); +#. FIXME: implement averaging of all parameters for multiple selected +#. gtk_label_set_markup(GTK_LABEL(l), _("Average:")); +#: ../../po/../src/widgets/gradient-toolbar.cpp:676 +#: ../../po/../src/widgets/toolbox.cpp:1105 +#: ../../po/../src/widgets/toolbox.cpp:1124 +#: ../../po/../src/widgets/toolbox.cpp:1493 +#: ../../po/../src/widgets/toolbox.cpp:1518 +#: ../../po/../src/widgets/toolbox.cpp:1768 +#: ../../po/../src/widgets/toolbox.cpp:1787 +#: ../../po/../src/widgets/toolbox.cpp:2334 +#: ../../po/../src/widgets/toolbox.cpp:2354 +msgid "Change:" +msgstr "" + +#: ../../po/../src/widgets/gradient-vector.cpp:269 +msgid "No gradients in document" +msgstr "" + +#: ../../po/../src/widgets/gradient-vector.cpp:275 +#, fuzzy +msgid "No gradient selected" +msgstr "Grupeerib valitud objektid" + +#: ../../po/../src/widgets/gradient-vector.cpp:532 +msgid "No stops in gradient" +msgstr "" + +#. TRANSLATORS: "Stop" means: a "phase" of a gradient +#: ../../po/../src/widgets/gradient-vector.cpp:794 +msgid "Add stop" +msgstr "" + +#: ../../po/../src/widgets/gradient-vector.cpp:797 +msgid "Add another control stop to gradient" +msgstr "" + +#: ../../po/../src/widgets/gradient-vector.cpp:799 +#, fuzzy +msgid "Delete stop" +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/widgets/gradient-vector.cpp:802 +msgid "Delete current control stop from gradient" +msgstr "" + +#. Label +#: ../../po/../src/widgets/gradient-vector.cpp:813 +msgid "Offset:" +msgstr "" + +#. TRANSLATORS: "Stop" means: a "phase" of a gradient +#: ../../po/../src/widgets/gradient-vector.cpp:858 +msgid "Stop Color" +msgstr "" + +#: ../../po/../src/widgets/gradient-vector.cpp:887 +#, fuzzy +msgid "Gradient editor" +msgstr "Trüki" + +#: ../../po/../src/widgets/layer-selector.cpp:119 +#, fuzzy +msgid "Toggle current layer visibility" +msgstr "Shrift" + +#: ../../po/../src/widgets/layer-selector.cpp:139 +#, fuzzy +msgid "Lock or unlock current layer" +msgstr "Shrift" + +#: ../../po/../src/widgets/layer-selector.cpp:142 +#, fuzzy +msgid "Current layer" +msgstr "Shrift" + +#: ../../po/../src/widgets/layer-selector.cpp:553 +msgid "(root)" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:182 +#: ../../po/../src/widgets/paint-selector.cpp:561 +#, fuzzy +msgid "No paint" +msgstr "Trüki" + +#: ../../po/../src/widgets/paint-selector.cpp:184 +#: ../../po/../src/widgets/paint-selector.cpp:629 +msgid "Flat color" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:186 +#: ../../po/../src/widgets/paint-selector.cpp:696 +msgid "Linear gradient" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:188 +#: ../../po/../src/widgets/paint-selector.cpp:699 +msgid "Radial gradient" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:192 +msgid "Unset paint (make it undefined so it can be inherited)" +msgstr "" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/painting.html#FillRuleProperty +#: ../../po/../src/widgets/paint-selector.cpp:204 +msgid "" +"Any path self-intersections or subpaths create holes in the fill (fill-rule: " +"evenodd)" +msgstr "" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/painting.html#FillRuleProperty +#: ../../po/../src/widgets/paint-selector.cpp:215 +msgid "" +"Fill is solid unless a subpath is counterdirectional (fill-rule: nonzero)" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:528 +#, fuzzy +msgid "No objects" +msgstr "Grupeerib valitud objektid" + +#: ../../po/../src/widgets/paint-selector.cpp:539 +msgid "Multiple styles" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:550 +msgid "Paint is undefined" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:757 +#, fuzzy +msgid "No patterns in document" +msgstr "Shrift" + +#: ../../po/../src/widgets/paint-selector.cpp:872 +msgid "" +"Use Edit > Object(s) to Pattern to create a new pattern from " +"selection." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:426 +msgid "Now stroke width is scaled when objects are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:428 +msgid "Now stroke width is not scaled when objects are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:436 +msgid "" +"Now rounded rectangle corners are scaled when rectangles are " +"scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:438 +msgid "" +"Now rounded rectangle corners are not scaled when rectangles " +"are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:446 +msgid "" +"Now gradients are transformed along with their objects when " +"those are transformed (moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:448 +msgid "" +"Now gradients remain fixed when objects are transformed " +"(moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:456 +msgid "" +"Now patterns are transformed along with their objects when " +"those are transformed (moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:458 +msgid "" +"Now patterns remain fixed when objects are transformed (moved, " +"scaled, rotated, or skewed)." +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:506 +#, fuzzy +msgid "select_toolbar|X" +msgstr "_Selektsioon" + +#: ../../po/../src/widgets/select-toolbar.cpp:506 +msgid "Horizontal coordinate of selection" +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:511 +#, fuzzy +msgid "select_toolbar|Y" +msgstr "_Selektsioon" + +#: ../../po/../src/widgets/select-toolbar.cpp:511 +msgid "Vertical coordinate of selection" +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:517 +#, fuzzy +msgid "select_toolbar|W" +msgstr "_Selektsioon" + +#: ../../po/../src/widgets/select-toolbar.cpp:517 +#, fuzzy +msgid "Width of selection" +msgstr "D_uplikaat" + +#: ../../po/../src/widgets/select-toolbar.cpp:525 +msgid "Change both width and height by the same proportion" +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:534 +#, fuzzy +msgid "select_toolbar|H" +msgstr "_Selektsioon" + +#: ../../po/../src/widgets/select-toolbar.cpp:534 +#, fuzzy +msgid "Height of selection" +msgstr "D_uplikaat" + +#: ../../po/../src/widgets/sp-color-gtkselector.cpp:62 +msgid "System" +msgstr "" + +#: ../../po/../src/widgets/sp-color-notebook.cpp:322 +msgid "RGBA_:" +msgstr "" + +#: ../../po/../src/widgets/sp-color-notebook.cpp:330 +msgid "Hexadecimal RGBA value of the color" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "RGB" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "HSL" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "CMYK" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:397 +msgid "_R" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:398 +#: ../../po/../src/widgets/sp-color-scales.cpp:399 +#, fuzzy +msgid "Red" +msgstr "Skaala" + +#: ../../po/../src/widgets/sp-color-scales.cpp:400 +msgid "_G" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:401 +#: ../../po/../src/widgets/sp-color-scales.cpp:402 +msgid "Green" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:403 +msgid "_B" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:404 +#: ../../po/../src/widgets/sp-color-scales.cpp:405 +#, fuzzy +msgid "Blue" +msgstr "Skaala" + +#. Label +#: ../../po/../src/widgets/sp-color-scales.cpp:406 +#: ../../po/../src/widgets/sp-color-scales.cpp:432 +#: ../../po/../src/widgets/sp-color-scales.cpp:463 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:141 +msgid "_A" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:407 +#: ../../po/../src/widgets/sp-color-scales.cpp:408 +#: ../../po/../src/widgets/sp-color-scales.cpp:433 +#: ../../po/../src/widgets/sp-color-scales.cpp:434 +#: ../../po/../src/widgets/sp-color-scales.cpp:464 +#: ../../po/../src/widgets/sp-color-scales.cpp:465 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:151 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:163 +msgid "Alpha (opacity)" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:423 +msgid "_H" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:424 +#: ../../po/../src/widgets/sp-color-scales.cpp:425 +#, fuzzy +msgid "Hue" +msgstr "Skaala" + +#: ../../po/../src/widgets/sp-color-scales.cpp:426 +msgid "_S" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:427 +#: ../../po/../src/widgets/sp-color-scales.cpp:428 +msgid "Saturation" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:429 +msgid "_L" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:430 +#: ../../po/../src/widgets/sp-color-scales.cpp:431 +#, fuzzy +msgid "Lightness" +msgstr "Värvimine" + +#: ../../po/../src/widgets/sp-color-scales.cpp:451 +msgid "_C" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:452 +#: ../../po/../src/widgets/sp-color-scales.cpp:453 +#, fuzzy +msgid "Cyan" +msgstr "Lehekülg" + +#: ../../po/../src/widgets/sp-color-scales.cpp:454 +msgid "_M" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:455 +#: ../../po/../src/widgets/sp-color-scales.cpp:456 +msgid "Magenta" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:457 +msgid "_Y" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:458 +#: ../../po/../src/widgets/sp-color-scales.cpp:459 +msgid "Yellow" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:460 +msgid "_K" +msgstr "" + +#: ../../po/../src/widgets/sp-color-selector.cpp:71 +msgid "Unnamed" +msgstr "" + +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:68 +msgid "Wheel" +msgstr "" + +#: ../../po/../src/widgets/sp-xmlview-attr-list.cpp:53 +msgid "Attribute" +msgstr "" + +#: ../../po/../src/widgets/sp-xmlview-attr-list.cpp:54 +#, fuzzy +msgid "Value" +msgstr "Skaala" + +#: ../../po/../src/widgets/toolbox.cpp:424 +#, fuzzy +msgid "Insert new nodes into selected segments" +msgstr "Tee jooneks" + +#: ../../po/../src/widgets/toolbox.cpp:426 +#, fuzzy +msgid "Delete selected nodes" +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/widgets/toolbox.cpp:431 +#, fuzzy +msgid "Join paths at selected nodes" +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/widgets/toolbox.cpp:433 +#, fuzzy +msgid "Join paths at selected nodes with new segment" +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/widgets/toolbox.cpp:436 +msgid "Split path between two non-endpoint nodes" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:439 +#, fuzzy +msgid "Break path at selected nodes" +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/widgets/toolbox.cpp:444 +#, fuzzy +msgid "Make selected nodes corner" +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/widgets/toolbox.cpp:447 +#, fuzzy +msgid "Make selected nodes smooth" +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/widgets/toolbox.cpp:450 +#, fuzzy +msgid "Make selected nodes symmetric" +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/widgets/toolbox.cpp:455 +#, fuzzy +msgid "Make selected segments lines" +msgstr "Tee jooneks" + +#: ../../po/../src/widgets/toolbox.cpp:458 +#, fuzzy +msgid "Make selected segments curves" +msgstr "Tee jooneks" + +#: ../../po/../src/widgets/toolbox.cpp:1199 +msgid "Polygon" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1206 +msgid "Regular polygon (with one handle) instead of a star" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1218 +msgid "Corners:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1218 +msgid "Number of corners of a polygon or star" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1228 +msgid "Spoke ratio:" +msgstr "" + +#. TRANSLATORS: Tip radius of a star is the distance from the center to the farthest handle. +#. Base radius is the same for the closest handle. +#: ../../po/../src/widgets/toolbox.cpp:1231 +msgid "Base radius to tip radius ratio" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1246 +#, fuzzy +msgid "Rounded:" +msgstr "Grupeerib valitud objektid" + +#: ../../po/../src/widgets/toolbox.cpp:1246 +msgid "How much rounded are the corners (0 for sharp)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1256 +msgid "Randomized:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1256 +msgid "Scatter randomly the corners and angles" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1269 +#: ../../po/../src/widgets/toolbox.cpp:1838 +#: ../../po/../src/widgets/toolbox.cpp:2061 +msgid "Defaults" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1270 +#: ../../po/../src/widgets/toolbox.cpp:1839 +#: ../../po/../src/widgets/toolbox.cpp:2062 +msgid "" +"Reset shape parameters to defaults (use Inkscape Preferences > Tools to " +"change defaults)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1544 +msgid "W:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1544 +#, fuzzy +msgid "Width of rectangle" +msgstr "D_uplikaat" + +#: ../../po/../src/widgets/toolbox.cpp:1556 +#, fuzzy +msgid "Height of rectangle" +msgstr "D_uplikaat" + +#: ../../po/../src/widgets/toolbox.cpp:1568 +#, fuzzy +msgid "Rx:" +msgstr "1:1" + +#: ../../po/../src/widgets/toolbox.cpp:1568 +msgid "Horizontal radius of rounded corners" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1578 +#, fuzzy +msgid "Ry:" +msgstr "1:1" + +#: ../../po/../src/widgets/toolbox.cpp:1578 +msgid "Vertical radius of rounded corners" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1594 +msgid "Not rounded" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1596 +msgid "Make corners sharp" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1805 +msgid "Turns:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1805 +msgid "Number of revolutions" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1815 +#, fuzzy +msgid "Divergence:" +msgstr "Kustuta" + +#: ../../po/../src/widgets/toolbox.cpp:1815 +msgid "How much denser/sparser are outer revolutions; 1 = uniform" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1825 +msgid "Inner radius:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1825 +msgid "Radius of the innermost revolution (relative to the spiral size)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1957 +msgid "The width of the calligraphic pen (relative to the visible canvas area)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1967 +#, fuzzy +msgid "Thinning:" +msgstr "Joonistus" + +#: ../../po/../src/widgets/toolbox.cpp:1967 +msgid "" +"How much velocity thins the stroke (> 0 makes fast strokes thinner, < 0 " +"makes them broader, 0 makes width independent of velocity)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1980 +#, fuzzy +msgid "Angle:" +msgstr "Lehekülg" + +#: ../../po/../src/widgets/toolbox.cpp:1980 +msgid "" +"The angle of the pen's nib (in degrees; 0 = horizontal; has no effect if " +"fixation = 0)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1990 +msgid "Fixation:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1990 +msgid "" +"How fixed is the pen angle (0 = always perpendicular to stroke direction, 1 " +"= fixed)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2003 +msgid "Mass:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2003 +msgid "How much inertia affects the movement of the pen" +msgstr "" + +#. TRANSLATORS: "drag" means "resistance" here +#: ../../po/../src/widgets/toolbox.cpp:2014 +#, fuzzy +msgid "Drag:" +msgstr "Joonistus" + +#: ../../po/../src/widgets/toolbox.cpp:2014 +msgid "How much resistance affects the movement of the pen" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2034 +msgid "Use the pressure of the input device to alter the width of the pen" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2047 +msgid "Use the tilt of the input device to alter the angle of the pen's nib" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2374 +#, fuzzy +msgid "Start:" +msgstr "Piirjoon" + +#: ../../po/../src/widgets/toolbox.cpp:2374 +msgid "The angle (in degrees) from the horizontal to the arc's start point" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2384 +msgid "End:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2384 +msgid "The angle (in degrees) from the horizontal to the arc's end point" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2395 +#, fuzzy +msgid "Open arc" +msgstr "Ava" + +#: ../../po/../src/widgets/toolbox.cpp:2396 +msgid "" +"Switch between arc (unclosed shape) and segment (closed shape with two radii)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2415 +msgid "Make whole" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2417 +msgid "Make the shape a whole ellipse, not arc or segment" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2644 +msgid "" +"When pressed, picks visible color without alpha and when not pressed, picks " +"color including its alpha" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:3039 +#, fuzzy +msgid "Make connectors avoid selected objects" +msgstr "Kustutab valitud objekti(d)" + +#: ../../po/../src/widgets/toolbox.cpp:3043 +#, fuzzy +msgid "Make connectors ignore selected objects" +msgstr "Kustutab valitud objekti(d)" + +#. +#. 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 : +#: ../share/extensions/addnodes.inx.h:1 +#, fuzzy +msgid "Add Nodes" +msgstr "Punktiredaktor" + +#: ../share/extensions/addnodes.inx.h:2 +msgid "Maximum Segment Length" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:1 +msgid "AI Input" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:2 ../share/extensions/ai_output.inx.h:2 +msgid "Adobe Illustrator (*.ai)" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:3 +msgid "Open files saved with Adobe Illustrator" +msgstr "" + +#: ../share/extensions/ai_output.inx.h:1 +#, fuzzy +msgid "AI Output" +msgstr "Grupeerib valitud objektid" + +#: ../share/extensions/ai_output.inx.h:3 +msgid "Write Adobe Illustrator" +msgstr "" + +#: ../share/extensions/dia.inx.h:1 +msgid "A diagram created with the program Dia" +msgstr "" + +#: ../share/extensions/dia.inx.h:2 +msgid "Dia Diagram (*.dia)" +msgstr "" + +#: ../share/extensions/dia.inx.h:3 +msgid "Dia Input" +msgstr "" + +#: ../share/extensions/dia.inx.h:4 +msgid "" +"In order to import Dia files, Dia itself must be installed. You can get Dia " +"at http://www.gnome.org/projects/dia/" +msgstr "" + +#: ../share/extensions/dia.inx.h:5 +msgid "" +"The dia2svg.sh script should be installed with your Inkscape distribution. " +"If you do not have it, there is likely to be something wrong with your " +"Inkscape installation." +msgstr "" + +#: ../share/extensions/dots.inx.h:1 +#, fuzzy +msgid "Connect the Dots" +msgstr "Uus aken" + +#: ../share/extensions/dots.inx.h:2 +msgid "Dot Size" +msgstr "" + +#: ../share/extensions/dots.inx.h:3 +#, fuzzy +msgid "Font Size" +msgstr "Too kõige ette" + +#: ../share/extensions/dropshadow.inx.h:1 +msgid "Color of shadow" +msgstr "" + +#: ../share/extensions/dropshadow.inx.h:2 +msgid "Dropshadow" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:1 +#: ../share/extensions/dxf_output.inx.h:1 +msgid "AutoCAD DXF (*.dxf)" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:2 +msgid "DXF Input" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:3 +msgid "Import AutoCAD's Document Exchange Format" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:4 +msgid "" +"dxf2svg may come with Inkscape, but is also at http://dxf-svg-convert." +"sourceforge.net/" +msgstr "" + +#: ../share/extensions/dxf_output.inx.h:2 +#, fuzzy +msgid "DXF Output" +msgstr "Grupeerib valitud objektid" + +#: ../share/extensions/dxf_output.inx.h:3 +msgid "DXF file written by pstoedit" +msgstr "" + +#: ../share/extensions/dxf_output.inx.h:4 +msgid "pstoedit must be installed to run see http://www.pstoedit.net/pstoedit" +msgstr "" + +#: ../share/extensions/embedimage.inx.h:1 +#, fuzzy +msgid "Embed Images" +msgstr "Lehekülg" + +#: ../share/extensions/eps_input.inx.h:1 +msgid "EPS Input" +msgstr "" + +#: ../share/extensions/eps_input.inx.h:2 +msgid "Encapsulated Postscript" +msgstr "" + +#: ../share/extensions/eps_input.inx.h:3 +msgid "Encapsulated Postscript (*.eps)" +msgstr "" + +#: ../share/extensions/epsi_output.inx.h:1 +#, fuzzy +msgid "EPSI Output" +msgstr "Grupeerib valitud objektid" + +#: ../share/extensions/epsi_output.inx.h:2 +msgid "Encapsulated Postscript Interchange (*.epsi)" +msgstr "" + +#: ../share/extensions/epsi_output.inx.h:3 +msgid "Encapsulated Postscript with a thumbnail" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:1 ../share/extensions/ffms.inx.h:1 +#: ../share/extensions/ffset.inx.h:1 ../share/extensions/ffss.inx.h:1 +#, fuzzy +msgid "Bridge Width" +msgstr "Piirjoon" + +#: ../share/extensions/ffmet.inx.h:2 ../share/extensions/ffms.inx.h:2 +msgid "First String Length" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:3 +msgid "FretFind Multi Length ET" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:4 ../share/extensions/ffms.inx.h:4 +#: ../share/extensions/ffset.inx.h:3 ../share/extensions/ffss.inx.h:3 +msgid "Fretboard Edges" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:5 ../share/extensions/ffms.inx.h:5 +msgid "Last String Length" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:6 ../share/extensions/ffms.inx.h:6 +#: ../share/extensions/ffset.inx.h:4 ../share/extensions/ffss.inx.h:4 +msgid "Number of Frets" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:7 ../share/extensions/ffms.inx.h:7 +#: ../share/extensions/ffset.inx.h:5 ../share/extensions/ffss.inx.h:5 +msgid "Number of Strings" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:8 ../share/extensions/ffms.inx.h:8 +#: ../share/extensions/ffset.inx.h:6 ../share/extensions/ffss.inx.h:6 +#, fuzzy +msgid "Nut Width" +msgstr "Piirjoon" + +#: ../share/extensions/ffmet.inx.h:9 ../share/extensions/ffms.inx.h:10 +msgid "Perpendicular Distance" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:10 ../share/extensions/ffset.inx.h:7 +msgid "Scale Base (2 for Octave)" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:11 ../share/extensions/ffset.inx.h:9 +msgid "Tones in Scale" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:12 ../share/extensions/ffms.inx.h:12 +#: ../share/extensions/ffset.inx.h:10 ../share/extensions/ffss.inx.h:10 +msgid "px per Unit" +msgstr "" + +#: ../share/extensions/ffms.inx.h:3 +msgid "FretFind Multi Length Scala" +msgstr "" + +#: ../share/extensions/ffms.inx.h:9 ../share/extensions/ffss.inx.h:7 +msgid "Path to Scala *.scl File" +msgstr "" + +#: ../share/extensions/ffms.inx.h:11 +msgid "Tuning (scale step for each string seperated by semicolons)" +msgstr "" + +#: ../share/extensions/ffset.inx.h:2 +msgid "FretFind Single Length ET" +msgstr "" + +#: ../share/extensions/ffset.inx.h:8 ../share/extensions/ffss.inx.h:8 +msgid "Scale Length" +msgstr "" + +#: ../share/extensions/ffss.inx.h:2 +msgid "FretFind Single Length Scala" +msgstr "" + +#: ../share/extensions/ffss.inx.h:9 +msgid "Tuning (Scale step for each string seperated by semicolons)" +msgstr "" + +#: ../share/extensions/handles.inx.h:1 +msgid "Draw Handles" +msgstr "" + +#: ../share/extensions/interp.inx.h:1 +#, fuzzy +msgid "Duplicate Endpaths" +msgstr "D_uplikaat" + +#: ../share/extensions/interp.inx.h:2 +#, fuzzy +msgid "Exponent" +msgstr "_Import" + +#: ../share/extensions/interp.inx.h:3 +msgid "Interpolate" +msgstr "" + +#: ../share/extensions/interp.inx.h:4 +msgid "Interpolate Style (Experimental)" +msgstr "" + +#: ../share/extensions/interp.inx.h:5 +msgid "Interpolation Method" +msgstr "" + +#: ../share/extensions/interp.inx.h:6 +msgid "Interpolation Steps" +msgstr "" + +#: ../share/extensions/kochify.inx.h:1 +msgid "Kochify" +msgstr "" + +#: ../share/extensions/kochify_load.inx.h:1 +msgid "Kochify (Load)" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:1 +#, fuzzy +msgid "Angle" +msgstr "Lehekülg" + +#: ../share/extensions/lindenmayer.inx.h:2 +msgid "Axiom" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:3 +#, fuzzy +msgid "Lindenmayer" +msgstr "Lehekülg" + +#: ../share/extensions/lindenmayer.inx.h:4 +#, fuzzy +msgid "Order" +msgstr "Järjekord" + +#: ../share/extensions/lindenmayer.inx.h:5 +#, fuzzy +msgid "Rules" +msgstr "Värv" + +#: ../share/extensions/lindenmayer.inx.h:6 +#, fuzzy +msgid "Step" +msgstr "Skaala" + +#: ../share/extensions/motion.inx.h:1 +#, fuzzy +msgid "Direction" +msgstr "_Selektsioon" + +#: ../share/extensions/motion.inx.h:2 +msgid "Magnitude" +msgstr "" + +#: ../share/extensions/motion.inx.h:3 +#, fuzzy +msgid "Motion" +msgstr "_Selektsioon" + +#: ../share/extensions/pdf_output.inx.h:1 +msgid "Adobe PDF (*.pdf)" +msgstr "" + +#: ../share/extensions/pdf_output.inx.h:2 +msgid "Adobe Portable Document Format" +msgstr "" + +#: ../share/extensions/pdf_output.inx.h:3 +#, fuzzy +msgid "PDF Output" +msgstr "Grupeerib valitud objektid" + +#: ../share/extensions/ps_input.inx.h:1 +#, fuzzy +msgid "Postscript" +msgstr "Trüki" + +#: ../share/extensions/ps_input.inx.h:2 +msgid "Postscript (*.ps)" +msgstr "" + +#: ../share/extensions/ps_input.inx.h:3 +msgid "Postscript Input" +msgstr "" + +#: ../share/extensions/radiusrand.inx.h:1 +#, fuzzy +msgid "Radius" +msgstr "Lehekülg" + +#: ../share/extensions/radiusrand.inx.h:2 +#, fuzzy +msgid "Radius Randomize" +msgstr "Lehekülg" + +#: ../share/extensions/radiusrand.inx.h:3 +msgid "Randomize Control Points" +msgstr "" + +#: ../share/extensions/radiusrand.inx.h:4 +#, fuzzy +msgid "Randomize Nodes" +msgstr "Lehekülg" + +#: ../share/extensions/rtree.inx.h:1 +msgid "Initial Size" +msgstr "" + +#: ../share/extensions/rtree.inx.h:2 +msgid "Minimum Size" +msgstr "" + +#: ../share/extensions/rtree.inx.h:3 +msgid "Random Tree" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:1 +msgid "A diagram created with the program Sketch" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:2 +msgid "Sketch Diagram (*.sk)" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:3 +msgid "Sketch Input" +msgstr "" + +#: ../share/extensions/straightseg.inx.h:1 +msgid "Behavior" +msgstr "" + +#: ../share/extensions/straightseg.inx.h:3 +msgid "Segment Straightener" +msgstr "" + +#: ../share/extensions/summersnight.inx.h:1 +msgid "Summer's Night" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:1 +#: ../share/extensions/svgz_output.inx.h:1 +#, fuzzy +msgid "Compressed Inkscape SVG (*.svgz)" +msgstr "Avab faili" + +#: ../share/extensions/svgz_input.inx.h:2 +#: ../share/extensions/svgz_output.inx.h:2 +msgid "Inkscape's native file format compressed with GZip" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:3 +msgid "SVGZ Input" +msgstr "" + +#: ../share/extensions/svgz_output.inx.h:3 +#, fuzzy +msgid "SVGZ Output" +msgstr "Grupeerib valitud objektid" + +#: ../share/extensions/txt2svg.inx.h:1 +msgid "ASCII Text" +msgstr "" + +#: ../share/extensions/txt2svg.inx.h:2 +msgid "Text File (*.txt)" +msgstr "" + +#: ../share/extensions/txt2svg.inx.h:3 +#, fuzzy +msgid "Text Input" +msgstr "Tekst" + +#: ../share/extensions/wavy.inx.h:1 +msgid "Calculate first derivative numerically" +msgstr "" + +#: ../share/extensions/wavy.inx.h:2 +msgid "First derivative" +msgstr "" + +#: ../share/extensions/wavy.inx.h:3 +msgid "Function" +msgstr "" + +#: ../share/extensions/wavy.inx.h:4 +msgid "Function Plotter" +msgstr "" + +#: ../share/extensions/wavy.inx.h:5 +msgid "Nodes per period" +msgstr "" + +#: ../share/extensions/wavy.inx.h:6 +msgid "Periods (2*Pi each)" +msgstr "" + +#: ../share/extensions/whirl.inx.h:1 +msgid "Amount of Whirl" +msgstr "" + +#: ../share/extensions/whirl.inx.h:2 +#, fuzzy +msgid "Center X" +msgstr "Üldine" + +#: ../share/extensions/whirl.inx.h:3 +#, fuzzy +msgid "Center Y" +msgstr "Üldine" + +#: ../share/extensions/whirl.inx.h:4 +#, fuzzy +msgid "Direction of Rotation" +msgstr "Kustutab valitud objekti(d)" + +#: ../share/extensions/whirl.inx.h:5 +msgid "Whirl" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:1 +msgid "A popular graphics file format for clipart" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:2 +msgid "Windows Metafile (*.wmf)" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:3 +msgid "Windows Metafile Input" +msgstr "" + +#, fuzzy +#~ msgid "Current style" +#~ msgstr "Piirjoon" + +#, fuzzy +#~ msgid "Arrange Objects" +#~ msgstr "Grupeerib valitud objektid" + +#, fuzzy +#~ msgid "_Credits" +#~ msgstr "Värvimine" + +#, fuzzy +#~ msgid "Acceleration" +#~ msgstr "_Selektsioon" + +#, fuzzy +#~ msgid "Speed" +#~ msgstr "Skaala" + +#, fuzzy +#~ msgid "Zoom in/out by" +#~ msgstr "Suurendus" + +#, fuzzy +#~ msgid "Transform" +#~ msgstr "_Selektsioon" + +#, fuzzy +#~ msgid "Rotate _90 deg CW" +#~ msgstr "Kustutab valitud objekti(d)" + +#, fuzzy +#~ msgid "Rotate 9_0 deg CCW" +#~ msgstr "Kustutab valitud objekti(d)" + +#, fuzzy +#~ msgid "Flip selection horizontally" +#~ msgstr "Kustutab valitud objekti(d)" + +#, fuzzy +#~ msgid "Flip selection vertically" +#~ msgstr "Kustutab valitud objekti(d)" + +#, fuzzy +#~ msgid "C_reate" +#~ msgstr "Üldine" + +#, fuzzy +#~ msgid "Automatically scale Rows to fit selected objects." +#~ msgstr "Kustutab valitud objekti(d)" + +#, fuzzy +#~ msgid "Automatically scale Columns to fit selected objects." +#~ msgstr "Kustutab valitud objekti(d)" + +#, fuzzy +#~ msgid "R1:" +#~ msgstr "1:1" + +#, fuzzy +#~ msgid "R2:" +#~ msgstr "2:1" + +#, fuzzy +#~ msgid "Start Angle:" +#~ msgstr "Piirjoon" + +#, fuzzy +#~ msgid "End Angle:" +#~ msgstr "Lehekülg" + +#, fuzzy +#~ msgid "Open:" +#~ msgstr "Ava" + +#, fuzzy +#~ msgid "Revolutions:" +#~ msgstr "_Selektsioon" + +#, fuzzy +#~ msgid "Rectangle _Properties" +#~ msgstr "Trükib faili" + +#, fuzzy +#~ msgid "Star _Properties" +#~ msgstr "Värvimine" + +#, fuzzy +#~ msgid "Ellipse _Properties" +#~ msgstr "Trükib faili" + +#, fuzzy +#~ msgid "Spiral _Properties" +#~ msgstr "Värvimine" + +#, fuzzy +#~ msgid "Document Preferences" +#~ msgstr "Sodipodi" + +#, fuzzy +#~ msgid "Extensions Editor" +#~ msgstr "D_uplikaat" + +#, fuzzy +#~ msgid "Preferences" +#~ msgstr "Sodipodi" + +#, fuzzy +#~ msgid "Layer Editor" +#~ msgstr "Kustutab valitud objekti(d)" + +#, fuzzy +#~ msgid "Text Properties" +#~ msgstr "Trükib faili" + +#, fuzzy +#~ msgid "_Export..." +#~ msgstr "_Import" + +#, fuzzy +#~ msgid "_Document Properties" +#~ msgstr "Shrift" + +#, fuzzy +#~ msgid "In_kscape Preferences" +#~ msgstr "Sodipodi" + +#, fuzzy +#~ msgid "Select _Original Clone" +#~ msgstr "_Selektsioon" + +#, fuzzy +#~ msgid "Tile" +#~ msgstr "_Uus fail" + +#, fuzzy +#~ msgid "Select A_ll" +#~ msgstr "_Selektsioon" + +#, fuzzy +#~ msgid "Select Non_e" +#~ msgstr "_Selektsioon" + +#, fuzzy +#~ msgid "Zoom _In" +#~ msgstr "Suurendus" + +#, fuzzy +#~ msgid "Zoom _Out" +#~ msgstr "Suurendus" + +#, fuzzy +#~ msgid "Pre_vious" +#~ msgstr "Uus aken" + +#, fuzzy +#~ msgid "Nex_t" +#~ msgstr "Tekst" + +#, fuzzy +#~ msgid "R_ename Layer..." +#~ msgstr "Lehekülg" + +#, fuzzy +#~ msgid "D_uplicate Layer" +#~ msgstr "D_uplikaat" + +#, fuzzy +#~ msgid "_Delete Layer" +#~ msgstr "_Selektsioon" + +#, fuzzy +#~ msgid "Select Ne_xt Layer" +#~ msgstr "_Selektsioon" + +#, fuzzy +#~ msgid "Select Pre_vious Layer" +#~ msgstr "_Selektsioon" + +#, fuzzy +#~ msgid "Select To_p Layer" +#~ msgstr "_Selektsioon" + +#, fuzzy +#~ msgid "Move to Ne_w Layer" +#~ msgstr "Shrift" + +#, fuzzy +#~ msgid "Move to B_ottom Layer" +#~ msgstr "Kustutab valitud objekti(d)" + +#, fuzzy +#~ msgid "_Trace Bitmap..." +#~ msgstr "_Import" + +#, fuzzy +#~ msgid "_Put Text on Path" +#~ msgstr "Tee jooneks" + +#, fuzzy +#~ msgid "_Remove Text from Path" +#~ msgstr "Tee jooneks" + +#, fuzzy +#~ msgid "DynaDraw" +#~ msgstr "Joonistus" + +#~ msgid "Stroke" +#~ msgstr "Piirjoon" + +#, fuzzy +#~ msgid "Corners" +#~ msgstr "Uus aken" + +#, fuzzy +#~ msgid "Delete" +#~ msgstr "Kustuta" + +#, fuzzy +#~ msgid "Join" +#~ msgstr "Trüki" + +#, fuzzy +#~ msgid "Delete Segment" +#~ msgstr "Kustutab valitud objekti(d)" + +#, fuzzy +#~ msgid "Break" +#~ msgstr "Lammuta" + +#~ msgid "New" +#~ msgstr "Uus" + +#, fuzzy +#~ msgid "Revert to Saved" +#~ msgstr "Tee jooneks" + +#, fuzzy +#~ msgid "Save" +#~ msgstr "Salvesta" + +#, fuzzy +#~ msgid "Save As..." +#~ msgstr "Salvestab faili" + +#, fuzzy +#~ msgid "Import..." +#~ msgstr "_Import" + +#, fuzzy +#~ msgid "Export..." +#~ msgstr "_Import" + +#, fuzzy +#~ msgid "Print..." +#~ msgstr "Trüki" + +#, fuzzy +#~ msgid "Global Inkscape preferences (Shift+Ctrl+P)" +#~ msgstr "Värvimine" + +#, fuzzy +#~ msgid "Undo" +#~ msgstr "Vabasta" + +#, fuzzy +#~ msgid "Redo" +#~ msgstr "Skaala" + +#, fuzzy +#~ msgid "Duplicate selected object(s) (Ctrl+D)" +#~ msgstr "Kustutab valitud objekti(d)" + +#, fuzzy +#~ msgid "Clone selected object (Alt+D)" +#~ msgstr "Kustutab valitud objekti(d)" + +#, fuzzy +#~ msgid "Zoom in (+)" +#~ msgstr "Suurendus" + +#, fuzzy +#~ msgid "Zoom out (-)" +#~ msgstr "Suurendus" + +#, fuzzy +#~ msgid "Zoom to 1:1 (100%) (1)" +#~ msgstr "Suurendus" + +#, fuzzy +#~ msgid "Zoom to 1:2 (50%) (2)" +#~ msgstr "Suurendus" + +#, fuzzy +#~ msgid "Zoom to 2:1 (200%) (0)" +#~ msgstr "Suurendus" + +#, fuzzy +#~ msgid "Zoom to fit selection in window (3)" +#~ msgstr "_Selektsioon" + +#, fuzzy +#~ msgid "Zoom to fit drawing in window (4)" +#~ msgstr "Suurendus" + +#, fuzzy +#~ msgid "Zoom to fit page in window (5)" +#~ msgstr "Suurendus" + +#, fuzzy +#~ msgid "Zoom to fit page width in window (6)" +#~ msgstr "Suurendus" + +#, fuzzy +#~ msgid "Fill and Stroke dialog (Shift+Ctrl+F)" +#~ msgstr "Piirjoon" + +#, fuzzy +#~ msgid "Group selected objects (Ctrl+G)" +#~ msgstr "Kustutab valitud objekti(d)" + +#, fuzzy +#~ msgid "Ungroup selected group(s) (Ctrl+U)" +#~ msgstr "Lõhub valitud grupi objektideks" + +#, fuzzy +#~ msgid "Raise selection up one step (PgUp)" +#~ msgstr "Kustutab valitud objekti(d)" + +#, fuzzy +#~ msgid "Lower selection down one step (PgDn)" +#~ msgstr "Kustutab valitud objekti(d)" + +#, fuzzy +#~ msgid "Raise selection to top (Home)" +#~ msgstr "Kustutab valitud objekti(d)" + +#, fuzzy +#~ msgid "Lower selection to bottom (End)" +#~ msgstr "Kustutab valitud objekti(d)" + +#, fuzzy +#~ msgid "Move selection to new layer" +#~ msgstr "Kustutab valitud objekti(d)" + +#, fuzzy +#~ msgid "Move selection to next layer" +#~ msgstr "Kustutab valitud objekti(d)" + +#, fuzzy +#~ msgid "Move selection to previous layer" +#~ msgstr "Tee jooneks" + +#, fuzzy +#~ msgid "Move selection to top layer" +#~ msgstr "Kustutab valitud objekti(d)" + +#, fuzzy +#~ msgid "Move selection to bottom layer" +#~ msgstr "Kustutab valitud objekti(d)" + +#, fuzzy +#~ msgid "Rotate selection 90° clockwise (Shift+Ctrl+Right)" +#~ msgstr "Kustutab valitud objekti(d)" + +#, fuzzy +#~ msgid "Rotate selection 90° counter-clockwise (Shift+Ctrl+Left)" +#~ msgstr "Kustutab valitud objekti(d)" + +#, fuzzy +#~ msgid "Flip selection horizontally (H)" +#~ msgstr "Kustutab valitud objekti(d)" + +#, fuzzy +#~ msgid "Flip selection vertically (V)" +#~ msgstr "Kustutab valitud objekti(d)" + +#, fuzzy +#~ msgid "Align and Distribute dialog (Shift+Ctrl+A)" +#~ msgstr "Grupeerib valitud objektid" + +#, fuzzy +#~ msgid "Convert selected object(s) to path(s) (Shift+Ctrl+C)" +#~ msgstr "Tee jooneks" + +#, fuzzy +#~ msgid "Convert selected stroke(s) to path(s) (Ctrl+Alt+C)" +#~ msgstr "Tee jooneks" + +#, fuzzy +#~ msgid "Text and Font dialog (Shift+Ctrl+T)" +#~ msgstr "Piirjoon" + +#, fuzzy +#~ msgid "Node tool" +#~ msgstr "Punktiredaktor" + +#, fuzzy +#~ msgid "Zoom tool" +#~ msgstr "Suurendus" + +#, fuzzy +#~ msgid "Rectangle tool" +#~ msgstr "Lehekülg" + +#, fuzzy +#~ msgid "Star tool" +#~ msgstr "Piirjoon" + +#, fuzzy +#~ msgid "Pen tool" +#~ msgstr "Lehekülg" + +#, fuzzy +#~ msgid "Delete segment between two nodes" +#~ msgstr "Kustutab valitud objekti(d)" + +#, fuzzy +#~ msgid "Select All in All Layers" +#~ msgstr "_Selektsioon" + +#, fuzzy +#~ msgid "Invert Selection" +#~ msgstr "_Selektsioon" + +#, fuzzy +#~ msgid "Clean up selected path(s)" +#~ msgstr "Grupeerib valitud objektid" + +#, fuzzy +#~ msgid "_Scripts..." +#~ msgstr "Trüki" + +#, fuzzy +#~ msgid "Align and Distribute" +#~ msgstr "Grupeerib valitud objektid" + +#, fuzzy +#~ msgid "Align and Distribute Dialog" +#~ msgstr "Grupeerib valitud objektid" + +#, fuzzy +#~ msgid "Export Dialog" +#~ msgstr "_Import" + +#, fuzzy +#~ msgid "Fill and Stroke Dialog" +#~ msgstr "Piirjoon" + +#, fuzzy +#~ msgid "Inkscape Preferences" +#~ msgstr "Sodipodi" + +#, fuzzy +#~ msgid "Inkscape Preferences Dialog" +#~ msgstr "Sodipodi" + +#, fuzzy +#~ msgid "Layer Editor Dialog" +#~ msgstr "Kustutab valitud objekti(d)" + +#, fuzzy +#~ msgid "Text Properties Dialog" +#~ msgstr "Trükib faili" + +#, fuzzy +#~ msgid "Tree Editor" +#~ msgstr "Trüki" + +#, fuzzy +#~ msgid "Column width:" +#~ msgstr "Uus aken" + +#, fuzzy +#~ msgid "Creating anchor at (%g,%g)" +#~ msgstr "Joonistus" + +#, fuzzy +#~ msgid "EPS Output Settings" +#~ msgstr "Shrift" + +#, fuzzy +#~ msgid "Inkscape" +#~ msgstr "Sodipodi" + +#, fuzzy +#~ msgid "Fill style" +#~ msgstr "Shrift" + +#, fuzzy +#~ msgid "Fill:" +#~ msgstr "Värv" + +#, fuzzy +#~ msgid "winding" +#~ msgstr "Joonistus" + +#, fuzzy +#~ msgid "Update Properties" +#~ msgstr "Trükib faili" + +#, fuzzy +#~ msgid "executable" +#~ msgstr "Lehekülg" + +#, fuzzy +#~ msgid "file" +#~ msgstr "Värv" + +#, fuzzy +#~ msgid "absolute" +#~ msgstr "Lehekülg" + +#, fuzzy +#~ msgid "SVG Files" +#~ msgstr "Salvestab faili" + +#, fuzzy +#~ msgid "Layer Properties" +#~ msgstr "Värvimine" + +#, fuzzy +#~ msgid "Select object(s) to tile." +#~ msgstr "Tee jooneks" + +#, fuzzy +#~ msgid "Printable" +#~ msgstr "Trükib faili" + +#, fuzzy +#~ msgid "Document Name:" +#~ msgstr "Shrift" + +#, fuzzy +#~ msgid "Flatness:" +#~ msgstr "Salvesta" + +#, fuzzy +#~ msgid "Other" +#~ msgstr "Järjekord" + +#, fuzzy +#~ msgid "Trace: Selected object is not an image" +#~ msgstr "Kustutab valitud objekti(d)" + +#, fuzzy +#~ msgid "object" +#~ msgstr "Grupeerib valitud objektid" + +#, fuzzy +#~ msgid "Coordinates:" +#~ msgstr "Värvimine" + +#, fuzzy +#~ msgid "Draw arc: %s x %s" +#~ msgstr "Joonistus" + +#, fuzzy +#~ msgid "typeset object" +#~ msgstr "Kustutab valitud objekti(d)" + +#, fuzzy +#~ msgid "Pattern Fill" +#~ msgstr "Lehekülg" + +#, fuzzy +#~ msgid "_Menu" +#~ msgstr "Ava" + +#, fuzzy +#~ msgid "Rect" +#~ msgstr "Lehekülg" + +#, fuzzy +#~ msgid "meters" +#~ msgstr "Üldine" + +#, fuzzy +#~ msgid "Ru_lers" +#~ msgstr "Värv" + +#, fuzzy +#~ msgid "Mode:" +#~ msgstr "Punktiredaktor" + +#, fuzzy +#~ msgid "Value:" +#~ msgstr "Skaala" + +#~ msgid "Stroke settings" +#~ msgstr "Piirjoon" + +#, fuzzy +#~ msgid "Combine multiple paths" +#~ msgstr "Grupeerib valitud objektid" + +#, fuzzy +#~ msgid "New View" +#~ msgstr "Uus aken" + +#, fuzzy +#~ msgid "Fill and stroke settings" +#~ msgstr "Piirjoon" + +#, fuzzy +#~ msgid "Text editing and font settings" +#~ msgstr "Piirjoon" + +#, fuzzy +#~ msgid "Fill Rule" +#~ msgstr "Värv" + +#, fuzzy +#~ msgid "Selected object has no curve, cannot outline." +#~ msgstr "Tee jooneks" + +#, fuzzy +#~ msgid "Inkscape _Options" +#~ msgstr "Sodipodi" + +#, fuzzy +#~ msgid "gradientUnits" +#~ msgstr "Trüki" + +#~ msgid "Bring to _Front" +#~ msgstr "Too kõige ette" + +#~ msgid "Send to _Back" +#~ msgstr "Vii kõige taha" + +#, fuzzy +#~ msgid "Ungroup" +#~ msgstr "Vabasta" + +#, fuzzy +#~ msgid "Fill settings" +#~ msgstr "Shrift" + +#, fuzzy +#~ msgid "Break line at selected nodes" +#~ msgstr "Kustutab valitud objekti(d)" + +#, fuzzy +#~ msgid "Import" +#~ msgstr "_Import" + +#, fuzzy +#~ msgid "Bring to Front" +#~ msgstr "Too kõige ette" + +#, fuzzy +#~ msgid "Send to Back" +#~ msgstr "Vii kõige taha" + +#, fuzzy +#~ msgid "Lower selected objects one position" +#~ msgstr "Kustutab valitud objekti(d)" + +#~ msgid "1:1" +#~ msgstr "1:1" + +#~ msgid "1:2" +#~ msgstr "1:2" + +#~ msgid "2:1" +#~ msgstr "2:1" + +#~ msgid "Sodipodi" +#~ msgstr "Sodipodi" + +#, fuzzy +#~ msgid "Desktop settings" +#~ msgstr "Piirjoon" + +#, fuzzy +#~ msgid "Display settings" +#~ msgstr "Värvimine" + +#, fuzzy +#~ msgid "Drawing Mode" +#~ msgstr "Joonistus" + +#, fuzzy +#~ msgid "Zoom in drawing" +#~ msgstr "Trükib faili" + +#, fuzzy +#~ msgid "Set zoom factor to 1:2" +#~ msgstr "Suurendus" + +#, fuzzy +#~ msgid "Set zoom factor to 2:1" +#~ msgstr "Suurendus" + +#, fuzzy +#~ msgid "Document" +#~ msgstr "Shrift" + +#, fuzzy +#~ msgid "Document variant:" +#~ msgstr "Shrift" + +#, fuzzy +#~ msgid "Save document as" +#~ msgstr "Shrift" + +#, fuzzy +#~ msgid "About sodipodi" +#~ msgstr "Sodipodi" + +#, fuzzy +#~ msgid "About Sodipodi" +#~ msgstr "Sodipodi" + +#, fuzzy +#~ msgid " General " +#~ msgstr "Üldine" + +#, fuzzy +#~ msgid "Butt endpoints" +#~ msgstr "Grupeerib valitud objektid" + +#, fuzzy +#~ msgid "Endpoints:" +#~ msgstr "Trüki" + +#, fuzzy +#~ msgid "centimeter" +#~ msgstr "Üldine" + +#, fuzzy +#~ msgid "points" +#~ msgstr "Trüki" + +#~ msgid "Back One" +#~ msgstr "Tahapoole" + +#, fuzzy +#~ msgid "Convert selected segments to curves" +#~ msgstr "Tee jooneks" + +#, fuzzy +#~ msgid "Cusp line at selected nodes" +#~ msgstr "Kustutab valitud objekti(d)" + +#, fuzzy +#~ msgid "Desktop" +#~ msgstr "Piirjoon" + +#, fuzzy +#~ msgid "Drawing Context" +#~ msgstr "Joonistus" + +#~ msgid "Forward One" +#~ msgstr "Ettepoole" + +#, fuzzy +#~ msgid "Join 2 selected endpoints" +#~ msgstr "Grupeerib valitud objektid" + +#, fuzzy +#~ msgid "Smooth line at selected nodes" +#~ msgstr "Kustutab valitud objekti(d)" + +#, fuzzy +#~ msgid "Drawing context" +#~ msgstr "Joonistus" + +#, fuzzy +#~ msgid "Edit font style of selected objects" +#~ msgstr "Kustutab valitud objekti(d)" + +#, fuzzy +#~ msgid "Import " +#~ msgstr "_Import" + +#, fuzzy +#~ msgid "New drawing" +#~ msgstr "Joonistus" + +#, fuzzy +#~ msgid "Rotate selected objects 90deg clockwise" +#~ msgstr "Kustutab valitud objekti(d)" + +#, fuzzy +#~ msgid "Save drawing " +#~ msgstr "Joonistus" + +#, fuzzy +#~ msgid "select direction" +#~ msgstr "_Selektsioon" + +#, fuzzy +#~ msgid "Change Content" +#~ msgstr "Joonistus" + +#, fuzzy +#~ msgid "New Element" +#~ msgstr "Uus fail" + +#, fuzzy +#~ msgid "No" +#~ msgstr "Punktiredaktor" + +#, fuzzy +#~ msgid "Copyright Lauris Kaplinski 1999-2000." +#~ msgstr "Copyright Lauris Kaplinski 1999." + +#~ msgid "" +#~ "A Vector Drawing Program.\n" +#~ "Released under GPL" +#~ msgstr "" +#~ "Vektorjoonistusprogramm.\n" +#~ "Litsenseeritud vastavalt GNU GPL tingimustele." + +#, fuzzy +#~ msgid "Del" +#~ msgstr "Kustuta" + +#~ msgid "_New File" +#~ msgstr "_Uus fail" + +#, fuzzy +#~ msgid "Groups selected items" +#~ msgstr "Grupeerib valitud objektid" + +#, fuzzy +#~ msgid "Duplic\t" +#~ msgstr "D_uplikaat" + +#~ msgid "" +#~ "Feature not yet implemented :-(\n" +#~ "Maybe in next release?" +#~ msgstr "" +#~ "Seda võimalust pole veel tehtud :-(\n" +#~ "Ehk järgmises versioonis..." diff --git a/po/eu.po b/po/eu.po new file mode 100644 index 000000000..f10f6ff8e --- /dev/null +++ b/po/eu.po @@ -0,0 +1,10738 @@ +# translation of inkscape to Spanish +# Copyright (C) 2000,2003,2004 Free Software Foundation, Inc. +# Traducido por Jose Antonio Salgueiro . Agradecimientos: zert, softcatala +# 2002-2003 +# Jose Antonio Salgueiro Aquino , 2003 +# Francisco Javier F. Serrador , 2003 +# Lucas Vieites , 2003 +# Daniel Díaz , 2004 +# +msgid "" +msgstr "" +"Project-Id-Version: Inkscape\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2005-12-04 11:51-0800\n" +"PO-Revision-Date: 2005-10-07 20:42+0100\n" +"Last-Translator: 3ARRANO.com <3arrano@3arrano.com>\n" +"Language-Team: 3ARRANO.com <3arrano@3arrano.com>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Poedit-Language: Basque\n" +"X-Poedit-Country: EUSKAL HERRIA\n" + +#: ../inkscape.desktop.in.h:1 +msgid "Create and edit Scalable Vector Graphics images" +msgstr "SVG irudiak sortu eta editatu" + +#: ../inkscape.desktop.in.h:2 +msgid "Inkscape SVG Vector Illustrator" +msgstr "Inkscape SVG Bektore Irudigilea" + +# Aldatu biharrekua +#: ../../po/../src/arc-context.cpp:350 +msgid "" +"Ctrl: make circle or integer-ratio ellipse, snap arc/segment angle" +msgstr "" +"Ktrl: biribila edo proportzio osoko elipsea egin, snap arkua/" +"segmentuaren angelua" + +#: ../../po/../src/arc-context.cpp:351 ../../po/../src/rect-context.cpp:388 +msgid "Shift: draw around the starting point" +msgstr "Maius: hasierako puntuaren inguruan marraztu" + +#: ../../po/../src/arc-context.cpp:413 +#: ../../po/../src/connector-context.cpp:493 +#: ../../po/../src/dyna-draw-context.cpp:506 +#: ../../po/../src/pen-context.cpp:329 ../../po/../src/pencil-context.cpp:208 +#: ../../po/../src/rect-context.cpp:452 ../../po/../src/spiral-context.cpp:421 +#: ../../po/../src/star-context.cpp:427 +msgid "Current layer is hidden. Unhide it to be able to draw on it." +msgstr "" +"Uneko geruza ezkutuan dago. Agertaraz ezazu bertan marraztu ahal " +"izateko." + +#: ../../po/../src/arc-context.cpp:417 +#: ../../po/../src/connector-context.cpp:497 +#: ../../po/../src/dyna-draw-context.cpp:510 +#: ../../po/../src/pen-context.cpp:336 ../../po/../src/pencil-context.cpp:212 +#: ../../po/../src/rect-context.cpp:456 ../../po/../src/spiral-context.cpp:426 +#: ../../po/../src/star-context.cpp:431 +msgid "Current layer is locked. Unlock it to be able to draw on it." +msgstr "" +"Uneko geruza blokeatuta dago. Desblokeatu bertan marraztu ahal " +"izateko." + +# berrikusi +#: ../../po/../src/arc-context.cpp:496 +#, c-format +msgid "" +"Ellipse: %s × %s; with Ctrl to make circle or integer-" +"ratio ellipse; with Shift to draw around the starting point" +msgstr "" +"Elipsea: %s × %s; gehitu Ktrl biribila edo proportzio " +"osoko elipsea egiteko; gehitu Maius hasierako puntuaren inguruan " +"marrazteko" + +#: ../../po/../src/connector-context.cpp:518 +#, fuzzy +msgid "Creating new connector" +msgstr "Creando curva nueva" + +#: ../../po/../src/connector-context.cpp:939 +#, fuzzy +msgid "Finishing connector" +msgstr "Terminar pluma" + +#: ../../po/../src/connector-context.cpp:1108 +msgid "Connection point: click or drag to create a new connector" +msgstr "" + +#: ../../po/../src/connector-context.cpp:1185 +msgid "Connector endpoint: drag to reroute or connect to new shapes" +msgstr "" + +#: ../../po/../src/connector-context.cpp:1278 +#, fuzzy +msgid "Select at least one non-connector object." +msgstr "Seleccione por lo menos dos objetos para agrupar." + +#: ../../po/../src/desktop-events.cpp:238 +#, c-format +msgid "%s at %s" +msgstr "%s hemen: %s" + +#. TRANSLATORS: This string appears when double-clicking on a guide. +#. This is the distance by which the guide is to be moved. +#: ../../po/../src/desktop-events.cpp:277 +#, fuzzy +msgid " relative by " +msgstr "Movimiento relativo" + +#. TRANSLATORS: This string appears when double-clicking on a guide. +#. This is the target location where the guide is to be moved. +#: ../../po/../src/desktop-events.cpp:282 +#: ../../po/../src/desktop-events.cpp:395 +msgid " absolute to " +msgstr "" + +#. create dialog +#: ../../po/../src/desktop-events.cpp:348 +msgid "Guideline" +msgstr "Gidalerroa" + +#: ../../po/../src/desktop-events.cpp:432 +#, c-format +msgid "Move %s" +msgstr "Mugitu %s" + +#: ../../po/../src/desktop.cpp:678 +msgid "No previous zoom." +msgstr "Ezin da urrundu." + +#: ../../po/../src/desktop.cpp:703 +msgid "No next zoom." +msgstr "Ezin da gerturatu." + +#: ../../po/../src/dialogs/clonetiler.cpp:182 +msgid "Nothing selected." +msgstr "Ez dago ezer hautatuta." + +#: ../../po/../src/dialogs/clonetiler.cpp:188 +msgid "More than one object selected." +msgstr "Objektu bat baino gehiago hautatuta." + +#: ../../po/../src/dialogs/clonetiler.cpp:195 +#, c-format +msgid "Object has %d tiled clones." +msgstr "Objektuak %d klon lauzatu ditu." + +#: ../../po/../src/dialogs/clonetiler.cpp:200 +msgid "Object has no tiled clones." +msgstr "Objektuak ez du klon lauzaturik." + +#: ../../po/../src/dialogs/clonetiler.cpp:865 +#, fuzzy +msgid "Select one object whose tiled clones to unclump." +msgstr "Seleccione objetos para bajar." + +#: ../../po/../src/dialogs/clonetiler.cpp:916 +#, fuzzy +msgid "Select one object whose tiled clones to remove." +msgstr "Seleccione objetos para bajar." + +#: ../../po/../src/dialogs/clonetiler.cpp:984 +#: ../../po/../src/selection-chemistry.cpp:1774 +#, fuzzy +msgid "Select an object to clone." +msgstr "Seleccione objetos para bajar." + +#: ../../po/../src/dialogs/clonetiler.cpp:990 +#: ../../po/../src/selection-chemistry.cpp:1780 +msgid "" +"If you want to clone several objects, group them and clone the " +"group." +msgstr "" +"Objektu bat baino gehiago klonatu nahi badituzu, elkartu itzazu eta " +"klonatu taldea." + +#: ../../po/../src/dialogs/clonetiler.cpp:1484 +msgid "Per row:" +msgstr "Lerroko:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1497 +#, fuzzy +msgid "Per column:" +msgstr "Sin gradiente seleccionado" + +#: ../../po/../src/dialogs/clonetiler.cpp:1505 +#, fuzzy +msgid "Randomize:" +msgstr "Último seleccionado" + +#: ../../po/../src/dialogs/clonetiler.cpp:1656 +#, fuzzy +msgid "_Symmetry" +msgstr "simétrico" + +#. TRANSLATORS: For the following 17 symmetry groups, see +#. * http://www.bib.ulb.ac.be/coursmath/doc/17.htm (visual examples); +#. * http://www.clarku.edu/~djoyce/wallpaper/seventeen.html (English vocabulary); or +#. * http://membres.lycos.fr/villemingerard/Geometri/Sym1D.htm (French vocabulary). +#. +#: ../../po/../src/dialogs/clonetiler.cpp:1664 +msgid "Select one of the 17 symmetry groups for the tiling" +msgstr "Hautatu lauzaketarako 17 simetria taldeetatik bat" + +#. TRANSLATORS: "translation" means "shift" / "displacement" here. +#: ../../po/../src/dialogs/clonetiler.cpp:1675 +msgid "P1: simple translation" +msgstr "P1: lekualdaketa arrunta" + +#: ../../po/../src/dialogs/clonetiler.cpp:1676 +msgid "P2: 180° rotation" +msgstr "P2: 180°ko biraketa" + +#: ../../po/../src/dialogs/clonetiler.cpp:1677 +msgid "PM: reflection" +msgstr "PM: islada" + +#. TRANSLATORS: "glide reflection" is a reflection and a translation combined. +#. For more info, see http://mathforum.org/sum95/suzanne/symsusan.html +#: ../../po/../src/dialogs/clonetiler.cpp:1680 +msgid "PG: glide reflection" +msgstr "PG: islada labaindua" + +#: ../../po/../src/dialogs/clonetiler.cpp:1681 +msgid "CM: reflection + glide reflection" +msgstr "CM: islada + islada labaindua" + +#: ../../po/../src/dialogs/clonetiler.cpp:1682 +msgid "PMM: reflection + reflection" +msgstr "PMM: islada + islada" + +#: ../../po/../src/dialogs/clonetiler.cpp:1683 +msgid "PMG: reflection + 180° rotation" +msgstr "PMG: islada + 180°ko biraketa" + +#: ../../po/../src/dialogs/clonetiler.cpp:1684 +msgid "PGG: glide reflection + 180° rotation" +msgstr "PGG: islada labaindua + 180°ko biraketa" + +#: ../../po/../src/dialogs/clonetiler.cpp:1685 +msgid "CMM: reflection + reflection + 180° rotation" +msgstr "CMM: islada + islada + 180°ko biraketa" + +#: ../../po/../src/dialogs/clonetiler.cpp:1686 +msgid "P4: 90° rotation" +msgstr "P4: 90°ko biraketa" + +#: ../../po/../src/dialogs/clonetiler.cpp:1687 +msgid "P4M: 90° rotation + 45° reflection" +msgstr "P4M: 90°ko biraketa + 45°ko islada" + +#: ../../po/../src/dialogs/clonetiler.cpp:1688 +msgid "P4G: 90° rotation + 90° reflection" +msgstr "P4G: 90°ko biraketa + 90°ko islada" + +#: ../../po/../src/dialogs/clonetiler.cpp:1689 +msgid "P3: 120° rotation" +msgstr "P3: 120°ko biraketa" + +#: ../../po/../src/dialogs/clonetiler.cpp:1690 +msgid "P31M: reflection + 120° rotation, dense" +msgstr "P31M: islada + 120°ko biraketa, dentsoa" + +#: ../../po/../src/dialogs/clonetiler.cpp:1691 +msgid "P3M1: reflection + 120° rotation, sparse" +msgstr "P3M1: islada + 120°ko biraketa, sakabanatua" + +#: ../../po/../src/dialogs/clonetiler.cpp:1692 +msgid "P6: 60° rotation" +msgstr "P6: 60°ko biraketa" + +#: ../../po/../src/dialogs/clonetiler.cpp:1693 +msgid "P6M: reflection + 60° rotation" +msgstr "P6M: islada + 60°ko biraketa" + +#: ../../po/../src/dialogs/clonetiler.cpp:1721 +msgid "S_hift" +msgstr "_Desplazamendua" + +#. TRANSLATORS: "shift" means: the tiles will be shifted (offset) horizontally by this amount +#: ../../po/../src/dialogs/clonetiler.cpp:1731 +#, no-c-format +msgid "Shift X:" +msgstr "X Despl.:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1739 +#, no-c-format +msgid "Horizontal shift per row (in % of tile width)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1747 +#, no-c-format +msgid "Horizontal shift per column (in % of tile width)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1754 +msgid "Randomize the horizontal shift by this percentage" +msgstr "" + +#. TRANSLATORS: "shift" means: the tiles will be shifted (offset) vertically by this amount +#: ../../po/../src/dialogs/clonetiler.cpp:1764 +#, no-c-format +msgid "Shift Y:" +msgstr "Y Despl.:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1772 +#, no-c-format +msgid "Vertical shift per row (in % of tile height)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1780 +#, no-c-format +msgid "Vertical shift per column (in % of tile height)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1787 +msgid "Randomize the vertical shift by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1795 +#, fuzzy +msgid "Exponent:" +msgstr "Elipse" + +#: ../../po/../src/dialogs/clonetiler.cpp:1802 +msgid "Whether rows are spaced evenly (1), converge (<1) or diverge (>1)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1809 +msgid "Whether columns are spaced evenly (1), converge (<1) or diverge (>1)" +msgstr "" + +#. TRANSLATORS: "Alternate" is a verb here +#: ../../po/../src/dialogs/clonetiler.cpp:1817 +#: ../../po/../src/dialogs/clonetiler.cpp:1907 +#: ../../po/../src/dialogs/clonetiler.cpp:1966 +#: ../../po/../src/dialogs/clonetiler.cpp:2022 +#: ../../po/../src/dialogs/clonetiler.cpp:2153 +msgid "Alternate:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1823 +msgid "Alternate the sign of shifts for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1828 +msgid "Alternate the sign of shifts for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1837 +#, fuzzy +msgid "Sc_ale" +msgstr "Escalar" + +#: ../../po/../src/dialogs/clonetiler.cpp:1845 +#, fuzzy +msgid "Scale X:" +msgstr "Círculo" + +#: ../../po/../src/dialogs/clonetiler.cpp:1853 +#, fuzzy, no-c-format +msgid "Horizontal scale per row (in % of tile width)" +msgstr "Coordenada horizontal de la selección" + +#: ../../po/../src/dialogs/clonetiler.cpp:1861 +#, fuzzy, no-c-format +msgid "Horizontal scale per column (in % of tile width)" +msgstr "Coordenada horizontal de la selección" + +#: ../../po/../src/dialogs/clonetiler.cpp:1868 +msgid "Randomize the horizontal scale by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1876 +#, fuzzy +msgid "Scale Y:" +msgstr "Círculo" + +#: ../../po/../src/dialogs/clonetiler.cpp:1884 +#, no-c-format +msgid "Vertical scale per row (in % of tile height)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1892 +#, no-c-format +msgid "Vertical scale per column (in % of tile height)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1899 +msgid "Randomize the vertical scale by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1913 +msgid "Alternate the sign of scales for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1918 +#, fuzzy +msgid "Alternate the sign of scales for each column" +msgstr "Coordenada horizontal de la selección" + +#: ../../po/../src/dialogs/clonetiler.cpp:1927 +msgid "_Rotation" +msgstr "_Biraketa" + +#: ../../po/../src/dialogs/clonetiler.cpp:1935 +msgid "Angle:" +msgstr "Angelua:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1943 +#, no-c-format +msgid "Rotate tiles by this angle for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1951 +#, no-c-format +msgid "Rotate tiles by this angle for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1958 +msgid "Randomize the rotation angle by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1972 +msgid "Alternate the rotation direction for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1977 +msgid "Alternate the rotation direction for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1985 +msgid "_Opacity" +msgstr "_Opakutasuna" + +#: ../../po/../src/dialogs/clonetiler.cpp:1993 +msgid "Fade out:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2000 +msgid "Decrease tile opacity by this percentage for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2007 +msgid "Decrease tile opacity by this percentage for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2014 +msgid "Randomize the tile opacity by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2028 +msgid "Alternate the sign of opacity change for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2033 +msgid "Alternate the sign of opacity change for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2041 +msgid "Co_lor" +msgstr "Ko_lorea" + +#: ../../po/../src/dialogs/clonetiler.cpp:2046 +msgid "Initial color: " +msgstr "Hasierako kolorea:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2050 +msgid "Initial color of tiled clones" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2050 +msgid "" +"Initial color for clones (works only if the original has unset fill or " +"stroke)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2065 +msgid "H:" +msgstr "H:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2072 +msgid "Change the tile hue by this percentage for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2079 +msgid "Change the tile hue by this percentage for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2086 +msgid "Randomize the tile hue by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2095 +msgid "S:" +msgstr "S:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2102 +msgid "Change the color saturation by this percentage for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2109 +msgid "Change the color saturation by this percentage for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2116 +msgid "Randomize the color saturation by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2124 +msgid "L:" +msgstr "L:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2131 +msgid "Change the color lightness by this percentage for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2138 +msgid "Change the color lightness by this percentage for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2145 +msgid "Randomize the color lightness by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2159 +msgid "Alternate the sign of color changes for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2164 +msgid "Alternate the sign of color changes for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2172 +msgid "_Trace" +msgstr "_Marraztu" + +#: ../../po/../src/dialogs/clonetiler.cpp:2179 +msgid "Trace the drawing under the tiles" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2183 +msgid "" +"For each clone, pick a value from the drawing in that clone's location and " +"apply it to the clone" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2197 +msgid "1. Pick from the drawing:" +msgstr "" + +#. ----Hbox2 +#: ../../po/../src/dialogs/clonetiler.cpp:2208 +#: ../../po/../src/dialogs/clonetiler.cpp:2355 +#: ../../po/../src/ui/dialog/tracedialog.cpp:445 +msgid "Color" +msgstr "Kolorea" + +#: ../../po/../src/dialogs/clonetiler.cpp:2209 +msgid "Pick the visible color and opacity" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2216 +#: ../../po/../src/dialogs/clonetiler.cpp:2365 +#: ../share/extensions/dropshadow.inx.h:3 +msgid "Opacity" +msgstr "Opakutasuna" + +#: ../../po/../src/dialogs/clonetiler.cpp:2217 +msgid "Pick the total accumulated opacity" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2224 +msgid "R" +msgstr "R" + +#: ../../po/../src/dialogs/clonetiler.cpp:2225 +msgid "Pick the Red component of the color" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2232 +msgid "G" +msgstr "G" + +#: ../../po/../src/dialogs/clonetiler.cpp:2233 +msgid "Pick the Green component of the color" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2240 +msgid "B" +msgstr "B" + +#: ../../po/../src/dialogs/clonetiler.cpp:2241 +msgid "Pick the Blue component of the color" +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2250 +msgid "clonetiler|H" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2251 +#, fuzzy +msgid "Pick the hue of the color" +msgstr "Número de revoluciones" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2260 +msgid "clonetiler|S" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2261 +msgid "Pick the saturation of the color" +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2270 +msgid "clonetiler|L" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2271 +msgid "Pick the lightness of the color" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2281 +msgid "2. Tweak the picked value:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2291 +msgid "Gamma-correct:" +msgstr "Gamma-zuzenketa:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2296 +msgid "Shift the mid-range of the picked value upwards (>0) or downwards (<0)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2303 +msgid "Randomize:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2308 +msgid "Randomize the picked value by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2315 +#, fuzzy +msgid "Invert:" +msgstr "Re_ducir" + +#: ../../po/../src/dialogs/clonetiler.cpp:2319 +msgid "Invert the picked value" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2325 +msgid "3. Apply the value to the clones':" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2335 +#, fuzzy +msgid "Presence" +msgstr "Conservar" + +#: ../../po/../src/dialogs/clonetiler.cpp:2338 +msgid "" +"Each clone is created with the probability determined by the picked value in " +"that point" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2345 +msgid "Size" +msgstr "Neurria" + +#: ../../po/../src/dialogs/clonetiler.cpp:2348 +msgid "Each clone's size is determined by the picked value in that point" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2358 +msgid "" +"Each clone is painted by the picked color (the original must have unset fill " +"or stroke)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2368 +msgid "Each clone's opacity is determined by the picked value in that point" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2395 +msgid "How many rows in the tiling" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2415 +msgid "How many columns in the tiling" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2445 +msgid "Width of the rectangle to be filled" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2470 +msgid "Height of the rectangle to be filled" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2485 +msgid "Rows, columns: " +msgstr "Lerroak, zutabeak:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2486 +msgid "Create the specified number of rows and columns" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2495 +msgid "Width, height: " +msgstr "Zabalera, garaiera:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2496 +msgid "Fill the specified width and height with the tiling" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2512 +msgid "Use saved size and position of the tile" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2515 +msgid "" +"Pretend that the size and position of the tile are the same as the last time " +"you tiled it (if any), instead of using the current size" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2539 +#, fuzzy +msgid " _Create " +msgstr "Círculo" + +#: ../../po/../src/dialogs/clonetiler.cpp:2541 +msgid "Create and tile the clones of the selection" +msgstr "" + +#. TRANSLATORS: if a group of objects are "clumped" together, then they +#. are unevenly spread in the given amount of space - as shown in the +#. diagrams on the left in the following screenshot: +#. http://www.inkscape.org/screenshots/gallery/inkscape-0.42-CVS-tiles-unclump.png +#. So unclumping is the process of spreading a number of objects out more evenly. +#: ../../po/../src/dialogs/clonetiler.cpp:2556 +msgid " _Unclump " +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2557 +msgid "Spread out clones to reduce clumping; can be applied repeatedly" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2563 +#, fuzzy +msgid " Re_move " +msgstr "_Eliminar enlace" + +#: ../../po/../src/dialogs/clonetiler.cpp:2564 +msgid "Remove existing tiled clones of the selected object (siblings only)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2580 +#, fuzzy +msgid " R_eset " +msgstr "_Eliminar enlace" + +#. TRANSLATORS: "change" is a noun here +#: ../../po/../src/dialogs/clonetiler.cpp:2582 +msgid "" +"Reset all shifts, scales, rotates, opacity and color changes in the dialog " +"to zero" +msgstr "" + +#: ../../po/../src/dialogs/color-picker.cpp:280 +msgid "Close" +msgstr "Itxi" + +#: ../../po/../src/dialogs/debugdialog.cpp:138 +msgid "Messages" +msgstr "Mezuak" + +#. ## Add a menu for clear() +#: ../../po/../src/dialogs/debugdialog.cpp:144 +#: ../../po/../src/menus-skeleton.h:16 +#: ../../po/../src/ui/dialog/messages.cpp:56 +#: ../../po/../src/ui/dialog/scriptdialog.cpp:181 +msgid "_File" +msgstr "_Fitxategia" + +#. TRANSLATORS: "Clear" is a verb here +#: ../../po/../src/dialogs/debugdialog.cpp:145 +#: ../../po/../src/dialogs/find.cpp:753 +#: ../../po/../src/ui/dialog/messages.cpp:57 +#: ../../po/../src/ui/dialog/scriptdialog.cpp:182 +msgid "_Clear" +msgstr "_Garbitu" + +#: ../../po/../src/dialogs/debugdialog.cpp:147 +#: ../../po/../src/ui/dialog/messages.cpp:59 +msgid "Capture log messages" +msgstr "" + +#: ../../po/../src/dialogs/debugdialog.cpp:149 +#: ../../po/../src/ui/dialog/messages.cpp:61 +msgid "Release log messages" +msgstr "" + +#. Notebook tab +#: ../../po/../src/dialogs/desktop-properties.cpp:909 +#: ../../po/../src/ui/dialog/document-preferences.cpp:89 +#: ../../po/../src/ui/widget/panel.cpp:107 +msgid "Grid" +msgstr "Sareta" + +#. Checkbuttons +#. / \todo FIXME: gray out snapping when grid is off +#. / \todo FIXME: gray out snapping when grid is off. +#. / Dissenting view: you want snapping without grid. +#: ../../po/../src/dialogs/desktop-properties.cpp:917 +#: ../../po/../src/ui/dialog/document-preferences.cpp:179 +msgid "Show grid" +msgstr "Sareta erakutsi" + +#: ../../po/../src/dialogs/desktop-properties.cpp:917 +#: ../../po/../src/ui/dialog/document-preferences.cpp:179 +#: ../../po/../src/verbs.cpp:2115 +#, fuzzy +msgid "Show or hide grid" +msgstr "Mostrar/ocultar la rejilla" + +#: ../../po/../src/dialogs/desktop-properties.cpp:918 +#: ../../po/../src/ui/dialog/document-preferences.cpp:180 +#, fuzzy +msgid "Snap bounding boxes to grid" +msgstr "Ajustar a la rejilla" + +#: ../../po/../src/dialogs/desktop-properties.cpp:918 +#: ../../po/../src/dialogs/desktop-properties.cpp:1001 +#: ../../po/../src/ui/dialog/document-preferences.cpp:181 +#: ../../po/../src/ui/dialog/document-preferences.cpp:236 +msgid "Snap the edges of the object bounding boxes" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:919 +#: ../../po/../src/ui/dialog/document-preferences.cpp:183 +#, fuzzy +msgid "Snap nodes to grid" +msgstr "Ajustar a la rejilla" + +#: ../../po/../src/dialogs/desktop-properties.cpp:919 +#: ../../po/../src/dialogs/desktop-properties.cpp:1002 +#: ../../po/../src/ui/dialog/document-preferences.cpp:184 +#: ../../po/../src/ui/dialog/document-preferences.cpp:239 +msgid "Snap path nodes, text baselines, ellipse centers, etc." +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:937 +#: ../../po/../src/ui/dialog/document-preferences.cpp:186 +msgid "Grid units:" +msgstr "Saretaren unitateak:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:939 +#: ../../po/../src/ui/dialog/document-preferences.cpp:187 +msgid "Origin X:" +msgstr "X jatorria:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:942 +#: ../../po/../src/ui/dialog/document-preferences.cpp:189 +msgid "Origin Y:" +msgstr "Y jatorria:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:945 +#: ../../po/../src/ui/dialog/document-preferences.cpp:191 +msgid "Spacing X:" +msgstr "X hutsunea:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:948 +#: ../../po/../src/ui/dialog/document-preferences.cpp:193 +msgid "Spacing Y:" +msgstr "Y hutsunea:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:952 +#: ../../po/../src/dialogs/desktop-properties.cpp:1013 +#: ../../po/../src/ui/dialog/document-preferences.cpp:195 +#: ../../po/../src/ui/dialog/document-preferences.cpp:241 +msgid "Snap units:" +msgstr "Egokitzeko unitateak:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:955 +#: ../../po/../src/dialogs/desktop-properties.cpp:1016 +#: ../../po/../src/ui/dialog/document-preferences.cpp:196 +#: ../../po/../src/ui/dialog/document-preferences.cpp:242 +msgid "Snap distance:" +msgstr "Egokitzeko distantzia:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:958 +#: ../../po/../src/ui/dialog/document-preferences.cpp:199 +#, fuzzy +msgid "Grid line color:" +msgstr "Color de las líneas guía" + +#: ../../po/../src/dialogs/desktop-properties.cpp:959 +#: ../../po/../src/ui/dialog/document-preferences.cpp:199 +#, fuzzy +msgid "Grid line color" +msgstr "Color de las líneas guía" + +#: ../../po/../src/dialogs/desktop-properties.cpp:959 +#: ../../po/../src/ui/dialog/document-preferences.cpp:200 +#, fuzzy +msgid "Color of grid lines" +msgstr "Espaciado de líneas:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:961 +#: ../../po/../src/ui/dialog/document-preferences.cpp:201 +#, fuzzy +msgid "Major grid line color:" +msgstr "Color de las líneas guía" + +#: ../../po/../src/dialogs/desktop-properties.cpp:962 +#: ../../po/../src/ui/dialog/document-preferences.cpp:201 +#, fuzzy +msgid "Major grid line color" +msgstr "Color de las líneas guía" + +#: ../../po/../src/dialogs/desktop-properties.cpp:962 +#: ../../po/../src/ui/dialog/document-preferences.cpp:202 +msgid "Color of the major (highlighted) grid lines" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:965 +#: ../../po/../src/ui/dialog/document-preferences.cpp:204 +#, fuzzy +msgid "Major grid line every:" +msgstr "Color de las líneas guía" + +#. TRANSLATORS: This belongs to the "Major grid line every:" string, +#. see grid settings in the "Document Preferences" dialog +#: ../../po/../src/dialogs/desktop-properties.cpp:977 +#: ../../po/../src/ui/dialog/document-preferences.cpp:204 +msgid "lines" +msgstr "lerro" + +#. Guidelines page +#: ../../po/../src/dialogs/desktop-properties.cpp:991 +#: ../../po/../src/ui/dialog/document-preferences.cpp:90 +msgid "Guides" +msgstr "Gidak" + +#. / \todo FIXME: gray out snapping when guides are off +#. / Dissenting view: you want snapping without guides. +#: ../../po/../src/dialogs/desktop-properties.cpp:1000 +#: ../../po/../src/ui/dialog/document-preferences.cpp:234 +msgid "Show guides" +msgstr "Erakutsi gidak" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1000 +#: ../../po/../src/ui/dialog/document-preferences.cpp:234 +#: ../../po/../src/verbs.cpp:2116 +#, fuzzy +msgid "Show or hide guides" +msgstr "Mostrar/ocultar guías" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1001 +#: ../../po/../src/ui/dialog/document-preferences.cpp:235 +#, fuzzy +msgid "Snap bounding boxes to guides" +msgstr "Ajustar a las guías" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1002 +#: ../../po/../src/ui/dialog/document-preferences.cpp:238 +#, fuzzy +msgid "Snap points to guides" +msgstr "Ajustar a la rejilla" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1020 +#: ../../po/../src/ui/dialog/document-preferences.cpp:243 +msgid "Guide color:" +msgstr "Giden kolorea:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1021 +#: ../../po/../src/ui/dialog/document-preferences.cpp:243 +msgid "Guideline color" +msgstr "Gidalerroen kolorea" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1021 +#: ../../po/../src/ui/dialog/document-preferences.cpp:244 +msgid "Color of guidelines" +msgstr "Gidalerroen kolorea" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1023 +#: ../../po/../src/ui/dialog/document-preferences.cpp:245 +msgid "Highlight color:" +msgstr "Nabarmentze kolorea:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1024 +#: ../../po/../src/ui/dialog/document-preferences.cpp:245 +msgid "Highlighted guideline color" +msgstr "Gidalerroen nabarmentze kolorea" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1024 +#: ../../po/../src/ui/dialog/document-preferences.cpp:246 +msgid "Color of a guideline when it is under mouse" +msgstr "" + +#. Page page +#: ../../po/../src/dialogs/desktop-properties.cpp:1029 +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:855 +#: ../../po/../src/ui/dialog/document-preferences.cpp:88 +#: ../../po/../src/widgets/desktop-widget.cpp:1061 +msgid "Page" +msgstr "Orria" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1039 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +msgid "Background:" +msgstr "Atzeko kolorea:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1040 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +msgid "Background color" +msgstr "Atzeko planoko kolorea" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1041 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +msgid "" +"Color and transparency of the page background (also used for bitmap export)" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1045 +#: ../../po/../src/ui/dialog/document-preferences.cpp:147 +#, fuzzy +msgid "Show page border" +msgstr "Mostrar contorno del papel" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1049 +#: ../../po/../src/ui/dialog/document-preferences.cpp:148 +msgid "Border on top of drawing" +msgstr "Contorno encima del dibujo" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1052 +#: ../../po/../src/ui/dialog/document-preferences.cpp:149 +msgid "Border color:" +msgstr "Ertzaren kolorea:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1053 +#: ../../po/../src/ui/dialog/document-preferences.cpp:149 +#, fuzzy +msgid "Page border color" +msgstr "Color del contorno del papel" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1054 +#: ../../po/../src/ui/dialog/document-preferences.cpp:150 +#, fuzzy +msgid "Color of the page border" +msgstr "Oihal-ertzaren kolorea" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1059 +#: ../../po/../src/ui/dialog/document-preferences.cpp:152 +msgid "Show page shadow" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1063 +#: ../../po/../src/ui/dialog/document-preferences.cpp:153 +#, fuzzy +msgid "Default units:" +msgstr "Predeterminados" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1069 +msgid "Units for the tool controls, ruler, and the statusbar" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1086 +#: ../../po/../src/ui/widget/page-sizer.cpp:209 +#, fuzzy +msgid "Page size:" +msgstr "Tamaño del papel:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1110 +#: ../../po/../src/ui/widget/page-sizer.cpp:219 +msgid "Custom" +msgstr "Pertsonalizatua" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1121 +#: ../../po/../src/ui/widget/page-sizer.cpp:225 +#, fuzzy +msgid "Page orientation:" +msgstr "Oihalaren norantza:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1133 +#: ../../po/../src/ui/widget/page-sizer.cpp:232 +msgid "Landscape" +msgstr "Pasaia" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1139 +#: ../../po/../src/ui/widget/page-sizer.cpp:234 +msgid "Portrait" +msgstr "Erretratua" + +#. Custom paper frame +#: ../../po/../src/dialogs/desktop-properties.cpp:1148 +#: ../../po/../src/ui/widget/page-sizer.cpp:249 +#, fuzzy +msgid "Custom size" +msgstr "Pertsonalizatua" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1160 +#: ../../po/../src/dialogs/export.cpp:269 +#: ../../po/../src/ui/widget/page-sizer.cpp:261 +msgid "Units:" +msgstr "Unitateak:" + +#. Stroke width +#: ../../po/../src/dialogs/desktop-properties.cpp:1162 +#: ../../po/../src/dialogs/export.cpp:310 +#: ../../po/../src/dialogs/object-attributes.cpp:55 +#: ../../po/../src/dialogs/stroke-style.cpp:985 +#: ../../po/../src/ui/widget/page-sizer.cpp:262 +#: ../../po/../src/widgets/toolbox.cpp:1957 +msgid "Width:" +msgstr "Zabalera:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1183 +#: ../../po/../src/dialogs/export.cpp:326 +#: ../../po/../src/dialogs/export.cpp:431 +#: ../../po/../src/dialogs/object-attributes.cpp:56 +#: ../../po/../src/ui/widget/page-sizer.cpp:263 +msgid "Height:" +msgstr "Altuera:" + +#. +#. * Ownership metadata tab +#. +#: ../../po/../src/dialogs/desktop-properties.cpp:1206 +msgid "Metadata" +msgstr "Metadatuak" + +#. add license selector pull-down +#: ../../po/../src/dialogs/desktop-properties.cpp:1225 +msgid "License" +msgstr "Baimena" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1255 +msgid "Proprietary" +msgstr "Jabea" + +#: ../../po/../src/dialogs/display-settings.cpp:212 +#, fuzzy +msgid "When transforming, show:" +msgstr "Transformaciones de objeto" + +#: ../../po/../src/dialogs/display-settings.cpp:223 +msgid "Objects" +msgstr "Objektuak" + +#: ../../po/../src/dialogs/display-settings.cpp:224 +msgid "Show the actual objects when moving or transforming" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:231 +#, fuzzy +msgid "Box outline" +msgstr "Mostrar el boceto" + +#: ../../po/../src/dialogs/display-settings.cpp:232 +msgid "Show only a box outline of the objects when moving or transforming" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:238 +msgid "Per-object selection cue:" +msgstr "" + +#. sorationsnapsperpi == 0 means no snapping +#: ../../po/../src/dialogs/display-settings.cpp:249 +#: ../../po/../src/dialogs/display-settings.cpp:386 +#: ../../po/../src/dialogs/display-settings.cpp:441 +#: ../../po/../src/dialogs/display-settings.cpp:1482 +#: ../../po/../src/dialogs/stroke-style.cpp:791 +#: ../../po/../src/interface.cpp:741 +#: ../../po/../src/ui/widget/selected-style.cpp:100 +#: ../../po/../src/verbs.cpp:1842 +msgid "None" +msgstr "Bat ere ez" + +#: ../../po/../src/dialogs/display-settings.cpp:250 +msgid "No per-object selection indication" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:256 +msgid "Mark" +msgstr "Markatu" + +#: ../../po/../src/dialogs/display-settings.cpp:257 +msgid "Each selected object has a diamond mark in the top left corner" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:264 +msgid "Box" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:265 +msgid "Each selected object displays its bounding box" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:270 +#, fuzzy +msgid "Default scale origin:" +msgstr "Tolerancia por omisión del cursor:" + +#: ../../po/../src/dialogs/display-settings.cpp:281 +#, fuzzy +msgid "Opposite bounding box edge" +msgstr "Ajustar a la rejilla" + +#: ../../po/../src/dialogs/display-settings.cpp:282 +msgid "Default scale origin will be on the bounding box of the item" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:288 +msgid "Farthest opposite node" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:289 +msgid "Default scale origin will be on the bounding box of the item's points" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:341 +msgid "degrees" +msgstr "gradu" + +#: ../../po/../src/dialogs/display-settings.cpp:350 +msgid "" +"Rotating with Ctrl pressed snaps every that much degrees; also, pressing " +"[ or ] rotates by this amount" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:407 +msgid "Rotation snaps every:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:430 +msgid "" +"None: dialogs are treated as regular windows; Normal: dialogs stay on top of " +"document windows; Aggressive: same as Normal but may work better with some " +"window managers." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:451 +msgid "Normal" +msgstr "Arrunta" + +#: ../../po/../src/dialogs/display-settings.cpp:461 +msgid "Aggressive" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:475 +#, fuzzy +msgid "Dialogs on top:" +msgstr "_Diálogos" + +#: ../../po/../src/dialogs/display-settings.cpp:645 +#, fuzzy +msgid "Show selection cue" +msgstr "Bajar la selección un nivel" + +#: ../../po/../src/dialogs/display-settings.cpp:646 +msgid "" +"Whether selected objects display a selection cue (the same as in selector)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:657 +#, fuzzy +msgid "Enable gradient editing" +msgstr "Editor de gradiente" + +#: ../../po/../src/dialogs/display-settings.cpp:658 +msgid "Whether selected objects display gradient editing controls" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:719 +#, fuzzy +msgid "No objects selected to take the style from." +msgstr "Seleccione los objetos a los que quiera pegarle el estilo." + +#: ../../po/../src/dialogs/display-settings.cpp:728 +msgid "" +"More than one object selected. Cannot take style from multiple " +"objects." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:767 +#, fuzzy +msgid "Create new objects with:" +msgstr "Crear y editar objetos de texto (F8)" + +#: ../../po/../src/dialogs/display-settings.cpp:777 +#, fuzzy +msgid "Take from selection" +msgstr "Altura de la selección" + +#: ../../po/../src/dialogs/display-settings.cpp:778 +msgid "Remember the style of the (first) selected object as this tool's style" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:782 +#, fuzzy +msgid "Last used style" +msgstr "Pegar e_stilo" + +#: ../../po/../src/dialogs/display-settings.cpp:782 +msgid "Apply the style you last set on an object" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:790 +msgid "This tool's own style:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:790 +msgid "" +"Each tool may store its own style to apply to the newly created objects. Use " +"the button below to set it." +msgstr "" + +#. Mouse +#: ../../po/../src/dialogs/display-settings.cpp:877 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:55 +msgid "Mouse" +msgstr "Sagua" + +#. TRANSLATORS: "Grab" is a noun here. "Grab sensitivity" is intended to mean how +#. * close on the screen you need to be to an object to be able to grab it with mouse (in +#. * pixels). +#: ../../po/../src/dialogs/display-settings.cpp:883 +#, fuzzy +msgid "Grab sensitivity:" +msgstr "Definir como s_ensible" + +#: ../../po/../src/dialogs/display-settings.cpp:884 +msgid "" +"How close on the screen you need to be to an object to be able to grab it " +"with mouse (in screen pixels)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:885 +#: ../../po/../src/dialogs/display-settings.cpp:897 +#: ../../po/../src/dialogs/display-settings.cpp:912 +#: ../../po/../src/dialogs/display-settings.cpp:930 +#: ../../po/../src/dialogs/display-settings.cpp:970 +msgid "pixels" +msgstr "pixel" + +#: ../../po/../src/dialogs/display-settings.cpp:895 +msgid "Click/drag threshold:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:896 +msgid "" +"Maximum mouse drag (in screen pixels) which is considered a click, not a drag" +msgstr "" + +#. Scrolling +#: ../../po/../src/dialogs/display-settings.cpp:907 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:56 +#, fuzzy +msgid "Scrolling" +msgstr "Barras de desplazamiento" + +#: ../../po/../src/dialogs/display-settings.cpp:910 +msgid "Mouse wheel scrolls by:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:911 +msgid "" +"One mouse wheel notch scrolls by this distance in screen pixels " +"(horizontally with Shift)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:920 +msgid "Ctrl+arrows" +msgstr "Ktrl+geziak" + +#: ../../po/../src/dialogs/display-settings.cpp:928 +#, fuzzy +msgid "Scroll by:" +msgstr "Barras de desplazamiento" + +#: ../../po/../src/dialogs/display-settings.cpp:929 +msgid "Pressing Ctrl+arrow key scrolls by this distance (in screen pixels)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:939 +#, fuzzy +msgid "Acceleration:" +msgstr "Selección" + +#: ../../po/../src/dialogs/display-settings.cpp:940 +msgid "" +"Pressing and holding Ctrl+arrow will gradually speed up scrolling (0 for no " +"acceleration)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:949 +msgid "Autoscrolling" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:957 +#, fuzzy +msgid "Speed:" +msgstr "Rojo:" + +#: ../../po/../src/dialogs/display-settings.cpp:958 +msgid "" +"How fast the canvas autoscrolls when you drag beyond canvas edge (0 to turn " +"autoscroll off)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:968 +#: ../../po/../src/ui/dialog/tracedialog.cpp:357 +#: ../../po/../src/ui/dialog/tracedialog.cpp:390 +msgid "Threshold:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:969 +msgid "" +"How far (in screen pixels) you need to be from the canvas edge to trigger " +"autoscroll; positive is outside the canvas, negative is within the canvas" +msgstr "" + +#. Steps +#: ../../po/../src/dialogs/display-settings.cpp:979 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:57 +#, fuzzy +msgid "Steps" +msgstr "Estilo" + +#: ../../po/../src/dialogs/display-settings.cpp:982 +msgid "Arrow keys move by:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:983 +msgid "" +"Pressing an arrow key moves selected object(s) or node(s) by this distance " +"(in px units)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:984 +#: ../../po/../src/dialogs/display-settings.cpp:995 +#: ../../po/../src/dialogs/display-settings.cpp:1006 +#: ../../po/../src/helper/units.cpp:42 +msgid "px" +msgstr "px" + +#: ../../po/../src/dialogs/display-settings.cpp:993 +msgid "> and < scale by:" +msgstr "> eta < eskala: " + +#: ../../po/../src/dialogs/display-settings.cpp:994 +msgid "" +"Pressing > or < scales selection up or down by this increment (in px units)" +msgstr "" +"> edo < sakatuz hautatutakoa gora edo behera eskalatzen du hemen zehazturiko " +"balioaz (px unitatetan)" + +#: ../../po/../src/dialogs/display-settings.cpp:1004 +msgid "Inset/Outset by:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1005 +msgid "" +"Inset and Outset commands displace the path by this distance (in px units)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1017 +msgid "Compass-like display of angles" +msgstr "" + +#. TRANSLATORS: "positive clockwise" means "increasing in clockwise direction" +#: ../../po/../src/dialogs/display-settings.cpp:1019 +msgid "" +"When on, angles are displayed with 0 at north, 0 to 360 range, positive " +"clockwise; otherwise with 0 at east, -180 to 180 range, positive " +"counterclockwise" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1026 +#, fuzzy +msgid "Zoom in/out by:" +msgstr "Alejar" + +#: ../../po/../src/dialogs/display-settings.cpp:1027 +msgid "" +"Zoom tool click, +/- keys, and middle click zoom in and out by this " +"multiplier" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1028 +#: ../../po/../src/helper/units.cpp:44 +msgid "%" +msgstr "%" + +#. Tools +#: ../../po/../src/dialogs/display-settings.cpp:1037 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:58 +msgid "Tools" +msgstr "Tresnak" + +#: ../../po/../src/dialogs/display-settings.cpp:1045 +#, fuzzy +msgid "Selector" +msgstr "Seleccionar" + +#: ../../po/../src/dialogs/display-settings.cpp:1056 +#, fuzzy +msgid "Node" +msgstr "Ninguno" + +#: ../../po/../src/dialogs/display-settings.cpp:1064 +#: ../../po/../src/verbs.cpp:2073 +#: ../../po/../src/widgets/desktop-widget.cpp:277 +msgid "Zoom" +msgstr "Gerturatu" + +#. The 4 shape tools +#: ../../po/../src/dialogs/display-settings.cpp:1071 +#, fuzzy +msgid "Shapes" +msgstr "Agudeza:" + +#: ../../po/../src/dialogs/display-settings.cpp:1079 +#: ../../po/../src/verbs.cpp:2055 +msgid "Rectangle" +msgstr "Laukizuzena" + +#: ../../po/../src/dialogs/display-settings.cpp:1085 +#: ../../po/../src/verbs.cpp:2057 +msgid "Ellipse" +msgstr "Elipsia" + +#: ../../po/../src/dialogs/display-settings.cpp:1091 +#: ../../po/../src/verbs.cpp:2059 +msgid "Star" +msgstr "Izarra" + +#: ../../po/../src/dialogs/display-settings.cpp:1097 +#: ../../po/../src/verbs.cpp:2061 +msgid "Spiral" +msgstr "Kiribila" + +#: ../../po/../src/dialogs/display-settings.cpp:1111 +#: ../../po/../src/verbs.cpp:2063 +msgid "Pencil" +msgstr "Arkatza" + +#: ../../po/../src/dialogs/display-settings.cpp:1114 +#, fuzzy +msgid "Tolerance:" +msgstr "Traza" + +#: ../../po/../src/dialogs/display-settings.cpp:1115 +msgid "" +"This value affects the amount of smoothing applied to freehand lines; lower " +"values produce more uneven paths with more nodes" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1131 +#: ../../po/../src/verbs.cpp:2065 +msgid "Pen" +msgstr "Luma" + +#: ../../po/../src/dialogs/display-settings.cpp:1140 +#: ../../po/../src/verbs.cpp:2067 +msgid "Calligraphy" +msgstr "Kaligrafia" + +#: ../../po/../src/dialogs/display-settings.cpp:1147 +#: ../../po/../src/dialogs/text-edit.cpp:353 +#: ../../po/../src/ui/dialog/text-properties.cpp:37 +#: ../../po/../src/verbs.cpp:2069 +msgid "Text" +msgstr "Testua" + +#: ../../po/../src/dialogs/display-settings.cpp:1157 +#: ../../po/../src/verbs.cpp:2071 +#, fuzzy +msgid "Gradient" +msgstr "Editor de gradiente" + +#: ../../po/../src/dialogs/display-settings.cpp:1164 +#: ../../po/../src/verbs.cpp:2077 +#, fuzzy +msgid "Connector" +msgstr "Esquinas:" + +#: ../../po/../src/dialogs/display-settings.cpp:1171 +#: ../../po/../src/verbs.cpp:2075 +msgid "Dropper" +msgstr "Kolore hartzailea" + +#. Windows +#: ../../po/../src/dialogs/display-settings.cpp:1183 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:59 +msgid "Windows" +msgstr "Leihoak" + +#: ../../po/../src/dialogs/display-settings.cpp:1188 +#, fuzzy +msgid "Save window geometry" +msgstr "Guardar documento" + +#: ../../po/../src/dialogs/display-settings.cpp:1189 +msgid "" +"Save the window size and position with each document (only for Inkscape SVG " +"format)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1196 +msgid "Dialogs are hidden in taskbar" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1197 +msgid "Whether dialog windows are to be hidden in the window manager taskbar" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1204 +#, fuzzy +msgid "Zoom when window is resized" +msgstr "Ampliar el dibujo si cambia el tamaño de la ventana" + +#: ../../po/../src/dialogs/display-settings.cpp:1205 +msgid "" +"Zoom drawing when document window is resized, to keep the same area visible " +"(this is the default which can be changed in any window using the button " +"above the right scrollbar)" +msgstr "" + +#. Clones +#: ../../po/../src/dialogs/display-settings.cpp:1213 +#: ../../po/../src/dialogs/find.cpp:624 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:60 +#, fuzzy +msgid "Clones" +msgstr "Cerrar" + +#: ../../po/../src/dialogs/display-settings.cpp:1217 +msgid "When the original moves, its clones and linked offsets:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1229 +msgid "Move in parallel" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1230 +msgid "Clones are translated by the same vector as their original." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1237 +msgid "Stay unmoved" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1238 +msgid "Clones preserve their positions when their original is moved." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1245 +msgid "Move according to transform" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1246 +msgid "" +"Each clone moves according to the value of its transform= attribute. For " +"example, a rotated clone will move in a different direction than its " +"original." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1255 +msgid "When the original is deleted, its clones:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1267 +msgid "Are unlinked" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1267 +msgid "Orphaned clones are converted to regular objects." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1273 +#, fuzzy +msgid "Are deleted" +msgstr "Primero seleccionado" + +#: ../../po/../src/dialogs/display-settings.cpp:1273 +msgid "Orphaned clones are deleted along with their original." +msgstr "" + +#. Transforms +#. TRANSLATORS: Noun, i.e. transformations. +#: ../../po/../src/dialogs/display-settings.cpp:1289 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:61 +#, fuzzy +msgid "Transforms" +msgstr "Transfor_mar" + +#: ../../po/../src/dialogs/display-settings.cpp:1292 +#, fuzzy +msgid "Scale stroke width" +msgstr "Contorno" + +#: ../../po/../src/dialogs/display-settings.cpp:1293 +#: ../../po/../src/widgets/select-toolbar.cpp:568 +msgid "When scaling objects, scale the stroke width by the same proportion" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1300 +msgid "Scale rounded corners in rectangles" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1301 +#: ../../po/../src/widgets/select-toolbar.cpp:580 +msgid "When scaling rectangles, scale the radii of rounded corners" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1308 +#, fuzzy +msgid "Transform gradients" +msgstr "Transfor_mar" + +#: ../../po/../src/dialogs/display-settings.cpp:1309 +#: ../../po/../src/widgets/select-toolbar.cpp:592 +msgid "Transform gradients (in fill or stroke) along with the objects" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1316 +#, fuzzy +msgid "Transform patterns" +msgstr "Matriz de transformación" + +#: ../../po/../src/dialogs/display-settings.cpp:1317 +#: ../../po/../src/widgets/select-toolbar.cpp:604 +msgid "Transform patterns (in fill or stroke) along with the objects" +msgstr "" + +#. TRANSLATORS: How to specify the affine transformation in the SVG file. +#: ../../po/../src/dialogs/display-settings.cpp:1327 +#, fuzzy +msgid "Store transformation:" +msgstr "Transformación de objeto" + +#: ../../po/../src/dialogs/display-settings.cpp:1338 +#, fuzzy +msgid "Optimized" +msgstr "Optimizar" + +#: ../../po/../src/dialogs/display-settings.cpp:1339 +msgid "" +"If possible, apply transformation to objects without adding a transform= " +"attribute" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1346 +#, fuzzy +msgid "Preserved" +msgstr "Conservar" + +#: ../../po/../src/dialogs/display-settings.cpp:1347 +msgid "Always store transformation as a transform= attribute on objects" +msgstr "" + +#. Selecting +#: ../../po/../src/dialogs/display-settings.cpp:1355 +#, fuzzy +msgid "Selecting" +msgstr "Selección" + +#: ../../po/../src/dialogs/display-settings.cpp:1357 +msgid "Ctrl+A, Tab, Shift+Tab:" +msgstr "Ktrl+A, Tab, Maius+Tab:" + +#: ../../po/../src/dialogs/display-settings.cpp:1366 +#, fuzzy +msgid "Select only within current layer" +msgstr "Seleccionar" + +#: ../../po/../src/dialogs/display-settings.cpp:1367 +msgid "" +"Uncheck this to make keyboard selection commands work on objects in all " +"layers" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1374 +msgid "Ignore hidden objects" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1375 +msgid "" +"Uncheck this to be able to select objects that are hidden (either by " +"themselves or by being in a hidden group or layer)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1382 +#, fuzzy +msgid "Ignore locked objects" +msgstr "Objetos seleccionados" + +#: ../../po/../src/dialogs/display-settings.cpp:1383 +msgid "" +"Uncheck this to be able to select objects that are locked (either by " +"themselves or by being in a locked group or layer)" +msgstr "" + +#. To be broken into: Display, Save, Export, SVG, Commands +#: ../../po/../src/dialogs/display-settings.cpp:1391 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:62 +msgid "Misc" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1394 +msgid "Default export resolution:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1395 +#, fuzzy +msgid "Default bitmap resolution (in dots per inch) in the Export dialog" +msgstr "Resolución preferida (puntos por pulgada) de mapa de bits" + +#. FIXME: add "Used for new exports; once exported, documents remember this value on per-object basis" when implemented +#: ../../po/../src/dialogs/display-settings.cpp:1396 +#: ../../po/../src/dialogs/export.cpp:442 +msgid "dpi" +msgstr "dpi" + +#. TRANSLATORS: When on, an imported bitmap creates an element; otherwise it is a +#. * rectangle with bitmap fill. +#: ../../po/../src/dialogs/display-settings.cpp:1407 +#, fuzzy +msgid "Import bitmap as " +msgstr "Importar mapa de bits o imagen SVG al documento" + +#: ../../po/../src/dialogs/display-settings.cpp:1408 +msgid "" +"When on, an imported bitmap creates an element; otherwise it is a " +"rectangle with bitmap fill" +msgstr "" + +#. TRANSLATORS: When on, the print out (currently Postscript) will have +#. * a comment with the each object's label visible, marking the section +#. * of the printing commands that represent the given object. +#: ../../po/../src/dialogs/display-settings.cpp:1418 +msgid "Add label comments to printing output" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1419 +msgid "" +"When on, a comment will be added to the raw print output, marking the " +"rendered output for an object with its label" +msgstr "" + +#. TRANSLATORS: When on, enable the effects menu, default is off +#: ../../po/../src/dialogs/display-settings.cpp:1427 +msgid "Enable script effects (requires restart) - EXPERIMENTAL" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1428 +msgid "" +"When on, the effects menu is enabled, allowing external effect scripts to be " +"called, requires restart before effective - EXPERIMENTAL" +msgstr "" + +#. TRANSLATORS: The maximum length of the Open Recent list in the File menu. +#: ../../po/../src/dialogs/display-settings.cpp:1436 +#, fuzzy +msgid "Max recent documents:" +msgstr "Imprimir documento" + +#: ../../po/../src/dialogs/display-settings.cpp:1437 +msgid "The maximum length of the Open Recent list in the File menu" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1447 +msgid "Simplification threshold:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1448 +msgid "" +"How strong is the Simplify command by default. If you invoke this command " +"several times in quick succession, it will act more and more aggressively; " +"invoking it again after a pause restores the default threshold." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1469 +msgid "Oversample bitmaps:" +msgstr "Bitmaps de sobremuestreo:" + +#: ../../po/../src/dialogs/display-settings.cpp:1488 +msgid "2x2" +msgstr "2x2" + +#: ../../po/../src/dialogs/display-settings.cpp:1494 +msgid "4x4" +msgstr "4x4" + +#: ../../po/../src/dialogs/display-settings.cpp:1500 +msgid "8x8" +msgstr "8x8" + +#: ../../po/../src/dialogs/display-settings.cpp:1506 +msgid "16x16" +msgstr "16x16" + +#. "view_icon_preview" +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2143 +msgid "_Page" +msgstr "_Orria" + +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2147 +msgid "_Drawing" +msgstr "_Marrazkia" + +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2149 +msgid "_Selection" +msgstr "_Hautapena" + +#: ../../po/../src/dialogs/export.cpp:133 +#, fuzzy +msgid "_Custom" +msgstr "Personalizar" + +#: ../../po/../src/dialogs/export.cpp:254 +msgid "Export area" +msgstr "Exportar área" + +#: ../../po/../src/dialogs/export.cpp:300 +#, fuzzy +msgid "_x0:" +msgstr "x0:" + +#: ../../po/../src/dialogs/export.cpp:305 +#, fuzzy +msgid "x_1:" +msgstr "x1:" + +#: ../../po/../src/dialogs/export.cpp:316 +#, fuzzy +msgid "_y0:" +msgstr "y0:" + +#: ../../po/../src/dialogs/export.cpp:321 +#, fuzzy +msgid "y_1:" +msgstr "y1:" + +#: ../../po/../src/dialogs/export.cpp:406 +msgid "Bitmap size" +msgstr "Bit maparen neurria" + +#: ../../po/../src/dialogs/export.cpp:416 +#, fuzzy +msgid "_Width:" +msgstr "Ancho:" + +#: ../../po/../src/dialogs/export.cpp:416 +#: ../../po/../src/dialogs/export.cpp:431 +#, fuzzy +msgid "pixels at" +msgstr "pixeles" + +#: ../../po/../src/dialogs/export.cpp:426 +#, fuzzy +msgid "dp_i" +msgstr "dpi" + +#: ../../po/../src/dialogs/export.cpp:448 +#, fuzzy +msgid "_Filename" +msgstr "Nombre de archivo" + +#: ../../po/../src/dialogs/export.cpp:512 +#, fuzzy +msgid "_Browse..." +msgstr "Examinar..." + +#: ../../po/../src/dialogs/export.cpp:539 +#, fuzzy +msgid " _Export " +msgstr "Círculo" + +#: ../../po/../src/dialogs/export.cpp:541 +msgid "Export the bitmap file with these settings" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:968 +msgid "You have to enter a filename" +msgstr "Fitxategi izen bat zehaztu behar duzu" + +#: ../../po/../src/dialogs/export.cpp:973 +msgid "The chosen area to be exported is invalid" +msgstr "El área que se ha seleccionado para exportar no es válida." + +#: ../../po/../src/dialogs/export.cpp:982 +#, c-format +msgid "Directory %s does not exist or is not a directory.\n" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:998 +msgid "Export in progress" +msgstr "Realizando exportación..." + +#: ../../po/../src/dialogs/export.cpp:1004 +#, fuzzy, c-format +msgid "Exporting %s (%d x %d)" +msgstr "Exportando [%d x %d] %s" + +#: ../../po/../src/dialogs/export.cpp:1031 +#, c-format +msgid "Could not export to filename %s.\n" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:1137 +msgid "Select a filename for exporting" +msgstr "Seleccione un nombre de archivo para exportar" + +#: ../../po/../src/dialogs/filedialog.cpp:367 +#, fuzzy +msgid "No preview" +msgstr "_Nueva vista" + +#: ../../po/../src/dialogs/filedialog.cpp:468 +msgid "too large for preview" +msgstr "" + +#: ../../po/../src/dialogs/filedialog.cpp:762 +#: ../../po/../src/dialogs/filedialog.cpp:763 +#, fuzzy +msgid "All Images" +msgstr "URI de la imagen:" + +#: ../../po/../src/dialogs/filedialog.cpp:767 +#: ../../po/../src/dialogs/filedialog.cpp:768 +#, fuzzy +msgid "All Files" +msgstr "Estilo de relleno" + +#: ../../po/../src/dialogs/filedialog.cpp:774 +#: ../../po/../src/dialogs/filedialog.cpp:775 +#, fuzzy +msgid "All Inkscape Files" +msgstr "Muestra de diapositivas Inkscape" + +#: ../../po/../src/dialogs/filedialog.cpp:1176 +#, fuzzy +msgid "Guess from extension" +msgstr "Altura de la selección" + +#. ###### Add the file types menu +#. createFilterMenu(); +#. ###### Do we want the .xxx extension automatically added? +#: ../../po/../src/dialogs/filedialog.cpp:1261 +msgid "Append filename extension automatically" +msgstr "Añadir extensión al nombre de archivo automáticamente" + +#. TRANSLATORS: "%s" is replaced with "exact" or "partial" when this string is displayed +#: ../../po/../src/dialogs/find.cpp:378 +#, fuzzy, c-format +msgid "%d object found (out of %d), %s match." +msgid_plural "%d objects found (out of %d), %s match." +msgstr[0] "%i objetos seleccionados. %s." +msgstr[1] "%i objetos seleccionados. %s." + +#: ../../po/../src/dialogs/find.cpp:381 +#, fuzzy +msgid "exact" +msgstr "Texto" + +#: ../../po/../src/dialogs/find.cpp:381 +#, fuzzy +msgid "partial" +msgstr "Espiral" + +#: ../../po/../src/dialogs/find.cpp:388 +#, fuzzy +msgid "No objects found" +msgstr "Sin objetos" + +#: ../../po/../src/dialogs/find.cpp:546 +#, fuzzy +msgid "T_ype: " +msgstr "Tipo:" + +#: ../../po/../src/dialogs/find.cpp:553 +msgid "Search in all object types" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:553 +#, fuzzy +msgid "All types" +msgstr "Estilo de relleno" + +#: ../../po/../src/dialogs/find.cpp:564 +msgid "Search all shapes" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:564 +#, fuzzy +msgid "All shapes" +msgstr "Todas las herramientas de formas" + +#: ../../po/../src/dialogs/find.cpp:581 +#, fuzzy +msgid "Search rectangles" +msgstr "Rectángulo" + +#: ../../po/../src/dialogs/find.cpp:581 +#, fuzzy +msgid "Rectangles" +msgstr "Rectángulo" + +#: ../../po/../src/dialogs/find.cpp:586 +msgid "Search ellipses, arcs, circles" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:586 +#, fuzzy +msgid "Ellipses" +msgstr "Elipse" + +#: ../../po/../src/dialogs/find.cpp:591 +#, fuzzy +msgid "Search stars and polygons" +msgstr "Crear estrellas y polígonos (*)" + +#: ../../po/../src/dialogs/find.cpp:591 +#, fuzzy +msgid "Stars" +msgstr "Estrella" + +#: ../../po/../src/dialogs/find.cpp:596 +#, fuzzy +msgid "Search spirals" +msgstr "Crear espirales (F9)" + +#: ../../po/../src/dialogs/find.cpp:596 +#, fuzzy +msgid "Spirals" +msgstr "Espiral" + +#. TRANSLATORS: polyline is a set of connected straight line segments +#. http://www.w3.org/TR/SVG11/shapes.html#PolylineElement +#: ../../po/../src/dialogs/find.cpp:609 +msgid "Search paths, lines, polylines" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:609 +#, fuzzy +msgid "Paths" +msgstr "T_razo" + +#: ../../po/../src/dialogs/find.cpp:614 +#, fuzzy +msgid "Search text objects" +msgstr "Objetos seleccionados" + +#: ../../po/../src/dialogs/find.cpp:614 +#, fuzzy +msgid "Texts" +msgstr "Texto" + +#: ../../po/../src/dialogs/find.cpp:619 +msgid "Search groups" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:619 +#, fuzzy +msgid "Groups" +msgstr "A_grupar" + +#: ../../po/../src/dialogs/find.cpp:624 +msgid "Search clones" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:629 +msgid "Search images" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:629 +#, fuzzy +msgid "Images" +msgstr "URI de la imagen:" + +#: ../../po/../src/dialogs/find.cpp:634 +#, fuzzy +msgid "Search offset objects" +msgstr "Crear un objeto de offset dinámico" + +#: ../../po/../src/dialogs/find.cpp:634 +#, fuzzy +msgid "Offsets" +msgstr "Offset:" + +#: ../../po/../src/dialogs/find.cpp:694 +#, fuzzy +msgid "_Text: " +msgstr "Texto" + +#: ../../po/../src/dialogs/find.cpp:694 +msgid "Find objects by their text content (exact or partial match)" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:695 +msgid "_ID: " +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:695 +msgid "Find objects by the value of the id attribute (exact or partial match)" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:696 +#, fuzzy +msgid "_Style: " +msgstr "Estilo" + +#: ../../po/../src/dialogs/find.cpp:696 +msgid "" +"Find objects by the value of the style attribute (exact or partial match)" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:697 +#, fuzzy +msgid "_Attribute: " +msgstr "Atributo" + +#: ../../po/../src/dialogs/find.cpp:697 +msgid "Find objects by the name of an attribute (exact or partial match)" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:711 +#, fuzzy +msgid "Search in s_election" +msgstr "Altura de la selección" + +#: ../../po/../src/dialogs/find.cpp:715 +msgid "Limit search to the current selection" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:720 +#, fuzzy +msgid "Search in current _layer" +msgstr "Seleccionar" + +#: ../../po/../src/dialogs/find.cpp:724 +#, fuzzy +msgid "Limit search to the current layer" +msgstr "Seleccionar" + +#: ../../po/../src/dialogs/find.cpp:729 +msgid "Include _hidden" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:733 +msgid "Include hidden objects in search" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:738 +msgid "Include l_ocked" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:742 +#, fuzzy +msgid "Include locked objects in search" +msgstr "Objetos seleccionados" + +#: ../../po/../src/dialogs/find.cpp:753 +#, fuzzy +msgid "Clear values" +msgstr "Limpia_r todo" + +#: ../../po/../src/dialogs/find.cpp:754 +#, fuzzy +msgid "_Find" +msgstr "Rejilla" + +#: ../../po/../src/dialogs/find.cpp:754 +msgid "Select objects matching all of the fields you filled in" +msgstr "" + +#: ../../po/../src/dialogs/iconpreview.cpp:145 +#, c-format +msgid "%d x %d" +msgstr "" + +#: ../../po/../src/dialogs/iconpreview.cpp:193 +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:857 +#: ../../po/../src/widgets/desktop-widget.cpp:1069 +msgid "Selection" +msgstr "Hautapena" + +#: ../../po/../src/dialogs/iconpreview.cpp:195 +#, fuzzy +msgid "Selection only or whole document" +msgstr "Seleccionar" + +#: ../../po/../src/dialogs/iconpreview.cpp:203 +msgid "Refresh the icons" +msgstr "" + +#. Create the label for the object id +#: ../../po/../src/dialogs/item-properties.cpp:126 +#: ../../po/../src/dialogs/item-properties.cpp:327 +#: ../../po/../src/dialogs/item-properties.cpp:396 +#: ../../po/../src/dialogs/item-properties.cpp:403 +msgid "_Id" +msgstr "" + +#: ../../po/../src/dialogs/item-properties.cpp:135 +msgid "" +"The id= attribute (only letters, digits, and the characters .-_: allowed)" +msgstr "" + +#. Button for setting the object's id, label, title and description. +#: ../../po/../src/dialogs/item-properties.cpp:149 +#, fuzzy +msgid "_Set" +msgstr "Ajustar ID" + +#. Create the label for the object label +#: ../../po/../src/dialogs/item-properties.cpp:158 +#, fuzzy +msgid "_Label" +msgstr "Definir atributo" + +#: ../../po/../src/dialogs/item-properties.cpp:167 +msgid "A freeform label for the object" +msgstr "" + +#. Create the label for the object title +#: ../../po/../src/dialogs/item-properties.cpp:179 +#: ../../po/../src/dialogs/rdf.cpp:243 +#, fuzzy +msgid "Title" +msgstr "Título:" + +#. Create the frame for the object description +#: ../../po/../src/dialogs/item-properties.cpp:196 +#: ../../po/../src/dialogs/rdf.cpp:287 +#, fuzzy +msgid "Description" +msgstr "Selección" + +#. Hide +#: ../../po/../src/dialogs/item-properties.cpp:223 +#, fuzzy +msgid "_Hide" +msgstr "Caras:" + +#: ../../po/../src/dialogs/item-properties.cpp:224 +msgid "Check to make the object invisible" +msgstr "" + +#. Lock +#. TRANSLATORS: "Lock" is a verb here +#: ../../po/../src/dialogs/item-properties.cpp:233 +msgid "L_ock" +msgstr "" + +#: ../../po/../src/dialogs/item-properties.cpp:234 +msgid "Check to make the object insensitive (not selectable by mouse)" +msgstr "" + +#: ../../po/../src/dialogs/item-properties.cpp:310 +#: ../../po/../src/dialogs/item-properties.cpp:317 +msgid "Ref" +msgstr "Ref" + +#: ../../po/../src/dialogs/item-properties.cpp:398 +#, fuzzy +msgid "Id invalid! " +msgstr "El ID no es válido" + +#: ../../po/../src/dialogs/item-properties.cpp:400 +#, fuzzy +msgid "Id exists! " +msgstr "El ID existe" + +#: ../../po/../src/dialogs/layer-properties.cpp:50 +msgid "Layer name:" +msgstr "" + +#: ../../po/../src/dialogs/layer-properties.cpp:133 +#, fuzzy +msgid "Rename Layer" +msgstr "Elevar nodo" + +#: ../../po/../src/dialogs/layer-properties.cpp:136 +#, fuzzy +msgid "_Rename" +msgstr "Nombre de archivo" + +#. TRANSLATORS: This means "The layer has been renamed" +#: ../../po/../src/dialogs/layer-properties.cpp:147 +#, fuzzy +msgid "Renamed layer" +msgstr "Elevar nodo" + +#: ../../po/../src/dialogs/layer-properties.cpp:151 +#, fuzzy +msgid "Add Layer" +msgstr "_Bajar" + +#: ../../po/../src/dialogs/layer-properties.cpp:153 +#, fuzzy +msgid "_Add" +msgstr "Añadir" + +#: ../../po/../src/dialogs/layer-properties.cpp:167 +msgid "New layer created." +msgstr "" + +#: ../../po/../src/dialogs/object-attributes.cpp:34 +msgid "Href:" +msgstr "Href:" + +#: ../../po/../src/dialogs/object-attributes.cpp:35 +msgid "Target:" +msgstr "Helburua:" + +#: ../../po/../src/dialogs/object-attributes.cpp:36 +msgid "Type:" +msgstr "Mota:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkRoleAttribute +#. Identifies the type of the related resource with an absolute URI +#: ../../po/../src/dialogs/object-attributes.cpp:39 +msgid "Role:" +msgstr "Rol:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkArcRoleAttribute +#. For situations where the nature/role alone isn't enough, this offers an additional URI defining the purpose of the link. +#: ../../po/../src/dialogs/object-attributes.cpp:42 +msgid "Arcrole:" +msgstr "Arcrole:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkTitleAttribute +#: ../../po/../src/dialogs/object-attributes.cpp:44 +msgid "Title:" +msgstr "Izenburua:" + +#: ../../po/../src/dialogs/object-attributes.cpp:45 +msgid "Show:" +msgstr "Erakutsi:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkActuateAttribute +#: ../../po/../src/dialogs/object-attributes.cpp:47 +msgid "Actuate:" +msgstr "Actuar:" + +#: ../../po/../src/dialogs/object-attributes.cpp:52 +msgid "URL:" +msgstr "URL:" + +#: ../../po/../src/dialogs/object-attributes.cpp:53 +msgid "X:" +msgstr "X:" + +#: ../../po/../src/dialogs/object-attributes.cpp:54 +msgid "Y:" +msgstr "Y:" + +#: ../../po/../src/dialogs/object-attributes.cpp:98 +#, c-format +msgid "%s attributes" +msgstr "%s atributu" + +#: ../../po/../src/dialogs/object-properties.cpp:158 +#, fuzzy +msgid "_Fill" +msgstr "Relleno" + +#: ../../po/../src/dialogs/object-properties.cpp:165 +#, fuzzy +msgid "Stroke _paint" +msgstr "Contorno" + +#: ../../po/../src/dialogs/object-properties.cpp:172 +#, fuzzy +msgid "Stroke st_yle" +msgstr "Estilo de contorno" + +#: ../../po/../src/dialogs/object-properties.cpp:183 +#, fuzzy +msgid "Master _opacity" +msgstr "Opacidad:" + +#: ../../po/../src/dialogs/rdf.cpp:244 +msgid "Name by which this document is formally known." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:246 +#, fuzzy +msgid "Date" +msgstr "_Pegar" + +#: ../../po/../src/dialogs/rdf.cpp:247 +msgid "Date associated with the creation of this document (YYYY-MM-DD)." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:249 +msgid "Format" +msgstr "Formatua" + +#: ../../po/../src/dialogs/rdf.cpp:250 +msgid "The physical or digital manifestation of this document (MIME type)." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:252 +#, fuzzy +msgid "Type" +msgstr "Tipo:" + +#: ../../po/../src/dialogs/rdf.cpp:253 +msgid "Type of document (DCMI Type)." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:256 +#, fuzzy +msgid "Creator" +msgstr "Crear" + +#: ../../po/../src/dialogs/rdf.cpp:257 +msgid "" +"Name of entity primarily responsible for making the content of this document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:259 +#, fuzzy +msgid "Rights" +msgstr "Alto:" + +#: ../../po/../src/dialogs/rdf.cpp:260 +msgid "" +"Name of entity with rights to the Intellectual Property of this document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:262 +msgid "Publisher" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:263 +msgid "Name of entity responsible for making this document available." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:266 +#, fuzzy +msgid "Identifier" +msgstr "Centímetro" + +#: ../../po/../src/dialogs/rdf.cpp:267 +msgid "Unique URI to reference this document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:269 +msgid "Source" +msgstr "Iturburua" + +#: ../../po/../src/dialogs/rdf.cpp:270 +msgid "Unique URI to reference the source of this document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:272 +#, fuzzy +msgid "Relation" +msgstr "Resolución:" + +#: ../../po/../src/dialogs/rdf.cpp:273 +#, fuzzy +msgid "Unique URI to a related document." +msgstr "Documento sin nombre" + +#: ../../po/../src/dialogs/rdf.cpp:275 +msgid "Language" +msgstr "Hizkuntza" + +#: ../../po/../src/dialogs/rdf.cpp:276 +msgid "" +"Two-letter language tag with optional subtags for the language of this " +"document. (e.g. 'en-GB')" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:278 +msgid "Keywords" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:279 +msgid "" +"The topic of this document as comma-separated key words, phrases, or " +"classifications." +msgstr "" + +#. TRANSLATORS: "Coverage": the spatial or temporal characteristics of the content. +#. For info, see Appendix D of http://www.w3.org/TR/1998/WD-rdf-schema-19980409/ +#: ../../po/../src/dialogs/rdf.cpp:283 +msgid "Coverage" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:284 +msgid "Extent or scope of this document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:288 +msgid "A short account of the content of this document." +msgstr "" + +#. FIXME: need to handle 1 agent per line of input +#: ../../po/../src/dialogs/rdf.cpp:292 +#, fuzzy +msgid "Contributors" +msgstr "Centímetros" + +#: ../../po/../src/dialogs/rdf.cpp:293 +msgid "" +"Names of entities responsible for making contributions to the content of " +"this document." +msgstr "" + +#. TRANSLATORS: URL to a page that defines the license for the document +#: ../../po/../src/dialogs/rdf.cpp:297 +msgid "URI" +msgstr "" + +#. TRANSLATORS: this is where you put a URL to a page that defines the license +#: ../../po/../src/dialogs/rdf.cpp:299 +msgid "URI to this document's license's namespace definition." +msgstr "" + +#. TRANSLATORS: fragment of XML representing the license of the document +#: ../../po/../src/dialogs/rdf.cpp:303 +#, fuzzy +msgid "Fragment" +msgstr "Argumento:" + +#: ../../po/../src/dialogs/rdf.cpp:304 +msgid "XML fragment for the RDF 'License' section." +msgstr "" + +#: ../../po/../src/dialogs/stroke-style.cpp:774 +#: ../../po/../src/widgets/gradient-vector.cpp:263 +#: ../../po/../src/widgets/paint-selector.cpp:751 +msgid "No document selected" +msgstr "Sin documentos seleccionados" + +#: ../../po/../src/dialogs/stroke-style.cpp:992 +#, fuzzy +msgid "Stroke width" +msgstr "Contorno" + +#. Join type +#. TRANSLATORS: The line join style specifies the shape to be used at the +#. corners of paths. It can be "miter", "round" or "bevel". +#: ../../po/../src/dialogs/stroke-style.cpp:1015 +msgid "Join:" +msgstr "Lotura:" + +#. TRANSLATORS: Miter join: joining lines with a sharp (pointed) corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1027 +msgid "Miter join" +msgstr "" + +#. TRANSLATORS: Round join: joining lines with a rounded corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1035 +msgid "Round join" +msgstr "" + +#. TRANSLATORS: Bevel join: joining lines with a blunted (flattened) corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1043 +msgid "Bevel join" +msgstr "" + +#. Miterlimit +#. TRANSLATORS: Miter limit: only for "miter join", this limits the length +#. of the sharp "spike" when the lines connect at too sharp an angle. +#. When two line segments meet at a sharp angle, a miter join results in a +#. spike that extends well beyond the connection point. The purpose of the +#. miter limit is to cut off such spikes (i.e. convert them into bevels) +#. when they become too long. +#: ../../po/../src/dialogs/stroke-style.cpp:1054 +msgid "Miter limit:" +msgstr "" + +#: ../../po/../src/dialogs/stroke-style.cpp:1062 +msgid "Maximum length of the miter (in units of stroke width)" +msgstr "" + +#. Cap type +#. TRANSLATORS: cap type specifies the shape for the ends of lines +#: ../../po/../src/dialogs/stroke-style.cpp:1075 +msgid "Cap:" +msgstr "Muturra:" + +#. TRANSLATORS: Butt cap: the line shape does not extend beyond the end point +#. of the line; the ends of the line are square +#: ../../po/../src/dialogs/stroke-style.cpp:1086 +msgid "Butt cap" +msgstr "" + +#. TRANSLATORS: Round cap: the line shape extends beyond the end point of the +#. line; the ends of the line are rounded +#: ../../po/../src/dialogs/stroke-style.cpp:1093 +msgid "Round cap" +msgstr "" + +#. TRANSLATORS: Square cap: the line shape extends beyond the end point of the +#. line; the ends of the line are square +#: ../../po/../src/dialogs/stroke-style.cpp:1100 +msgid "Square cap" +msgstr "" + +#. Dash +#: ../../po/../src/dialogs/stroke-style.cpp:1106 +#, fuzzy +msgid "Dashes:" +msgstr "Masa:" + +#. TRANSLATORS: Path markers are an SVG feature that allows you to attach arbitrary shapes +#. (arrowheads, bullets, faces, whatever) to the start, end, or middle nodes of a path. +#: ../../po/../src/dialogs/stroke-style.cpp:1127 +msgid "Start Markers:" +msgstr "Hasierako markak:" + +#: ../../po/../src/dialogs/stroke-style.cpp:1137 +msgid "Mid Markers:" +msgstr "Erdiko markak:" + +#: ../../po/../src/dialogs/stroke-style.cpp:1148 +msgid "End Markers:" +msgstr "Bukaerako markak:" + +#: ../../po/../src/dialogs/swatches.cpp:424 +#, c-format +msgid "Palettes directory (%s) is unavailable." +msgstr "" + +#. TODO: Insert widgets +#: ../../po/../src/dialogs/text-edit.cpp:199 +#: ../../po/../src/ui/dialog/text-properties.cpp:36 +#, fuzzy +msgid "Font" +msgstr "Punto" + +#: ../../po/../src/dialogs/text-edit.cpp:216 +msgid "Layout" +msgstr "Formatua" + +#: ../../po/../src/dialogs/text-edit.cpp:229 +msgid "Align lines left" +msgstr "" + +#. TRANSLATORS: `Center' here is a verb. +#: ../../po/../src/dialogs/text-edit.cpp:243 +#, fuzzy +msgid "Center lines" +msgstr "Centro Y:" + +#: ../../po/../src/dialogs/text-edit.cpp:256 +msgid "Align lines right" +msgstr "" + +#: ../../po/../src/dialogs/text-edit.cpp:278 +#, fuzzy +msgid "Horizontal text" +msgstr "Líneas horizontales" + +#: ../../po/../src/dialogs/text-edit.cpp:292 +#, fuzzy +msgid "Vertical text" +msgstr "Líneas verticales" + +#: ../../po/../src/dialogs/text-edit.cpp:307 +msgid "Line spacing:" +msgstr "Lerroen arteko tartea:" + +#: ../../po/../src/dialogs/text-edit.cpp:400 +msgid "Set as default" +msgstr "Aurrezehaztu gisa jarri" + +#: ../../po/../src/dialogs/tiledialog.cpp:603 +#, fuzzy +msgid "Rows:" +msgstr "Mostrar:" + +#: ../../po/../src/dialogs/tiledialog.cpp:613 +#, fuzzy +msgid "Number of rows" +msgstr "Número de revoluciones" + +#: ../../po/../src/dialogs/tiledialog.cpp:617 +#, fuzzy +msgid "Equal height" +msgstr "Alto:" + +#: ../../po/../src/dialogs/tiledialog.cpp:627 +msgid "If not set, each row has the height of the tallest object in it" +msgstr "" + +#. #### Radio buttons to control vertical alignment #### +#. #### Radio buttons to control horizontal alignment #### +#: ../../po/../src/dialogs/tiledialog.cpp:637 +#: ../../po/../src/dialogs/tiledialog.cpp:708 +#, fuzzy +msgid "Align:" +msgstr "Alinear" + +#: ../../po/../src/dialogs/tiledialog.cpp:672 +msgid " X " +msgstr " X " + +#. #### Number of columns #### +#: ../../po/../src/dialogs/tiledialog.cpp:678 +#, fuzzy +msgid "Columns:" +msgstr "Círculo" + +#: ../../po/../src/dialogs/tiledialog.cpp:688 +#, fuzzy +msgid "Number of columns" +msgstr "Número de revoluciones" + +#: ../../po/../src/dialogs/tiledialog.cpp:692 +#, fuzzy +msgid "Equal width" +msgstr "Ancho:" + +#: ../../po/../src/dialogs/tiledialog.cpp:701 +msgid "If not set, each column has the width of the widest object in it" +msgstr "" + +#. #### Radio buttons to control spacing manually or to fit selection bbox #### +#: ../../po/../src/dialogs/tiledialog.cpp:746 +#, fuzzy +msgid "Fit into selection box" +msgstr "Ancho de la selección" + +#: ../../po/../src/dialogs/tiledialog.cpp:753 +#, fuzzy +msgid "Set spacing:" +msgstr "Espaciado Y:" + +#. #### Y Padding #### +#: ../../po/../src/dialogs/tiledialog.cpp:777 +#, fuzzy +msgid "Row spacing: " +msgstr "Espaciado de líneas:" + +#: ../../po/../src/dialogs/tiledialog.cpp:786 +#, fuzzy +msgid "Vertical spacing between rows" +msgstr "Líneas verticales" + +#. #### X padding #### +#: ../../po/../src/dialogs/tiledialog.cpp:795 +#, fuzzy +msgid "Column spacing:" +msgstr "Espaciado de líneas:" + +#: ../../po/../src/dialogs/tiledialog.cpp:804 +#, fuzzy +msgid "Horizontal spacing between columns" +msgstr "Coordenada horizontal de la selección" + +#: ../../po/../src/dialogs/tiledialog.cpp:818 +#, fuzzy +msgid "Arrange selected objects" +msgstr "Agrupar los objetos seleccionados" + +#: ../../po/../src/dialogs/xml-tree.cpp:178 +#, fuzzy +msgid "Click to select nodes, drag to rearrange." +msgstr "Haga clic para seleccionar o crear un objeto de texto, luego escriba." + +#: ../../po/../src/dialogs/xml-tree.cpp:189 +msgid "Click attribute to edit." +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:193 +#, c-format +msgid "" +"Attribute %s selected. Press Ctrl+Enter when done editing to " +"commit changes." +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:284 +msgid "Drag to reorder nodes" +msgstr "Arrastrar para reordenar nodos" + +#: ../../po/../src/dialogs/xml-tree.cpp:304 +msgid "New element node" +msgstr "Nuevo nodo elemento" + +#: ../../po/../src/dialogs/xml-tree.cpp:326 +msgid "New text node" +msgstr "Siguiente nodo de texto" + +#: ../../po/../src/dialogs/xml-tree.cpp:347 +msgid "Duplicate node" +msgstr "Duplicar nodo" + +#: ../../po/../src/dialogs/xml-tree.cpp:368 +msgid "Delete node" +msgstr "Borrar nodo" + +#: ../../po/../src/dialogs/xml-tree.cpp:384 +msgid "Unindent node" +msgstr "Desangrar nodo" + +#: ../../po/../src/dialogs/xml-tree.cpp:399 +msgid "Indent node" +msgstr "Sangrar nodos" + +#: ../../po/../src/dialogs/xml-tree.cpp:411 +msgid "Raise node" +msgstr "Elevar nodo" + +#: ../../po/../src/dialogs/xml-tree.cpp:423 +msgid "Lower node" +msgstr "Bajar nodo" + +#: ../../po/../src/dialogs/xml-tree.cpp:468 +msgid "Delete attribute" +msgstr "Borrar atributo" + +#. TRANSLATORS: "Attribute" is a noun here +#: ../../po/../src/dialogs/xml-tree.cpp:513 +msgid "Attribute name" +msgstr "Nombre de atributo" + +#. TRANSLATORS: "Set" is a verb here +#: ../../po/../src/dialogs/xml-tree.cpp:533 +msgid "Set attribute" +msgstr "Definir atributo" + +#. TRANSLATORS: "Set" is a verb here +#: ../../po/../src/dialogs/xml-tree.cpp:535 +#, fuzzy +msgid "Set" +msgstr "Ajustar ID" + +#. TRANSLATORS: "Attribute" is a noun here +#: ../../po/../src/dialogs/xml-tree.cpp:558 +msgid "Attribute value" +msgstr "Valor del atributo" + +#: ../../po/../src/dialogs/xml-tree.cpp:1318 +msgid "New element node..." +msgstr "Nuevo nodo elemento..." + +#: ../../po/../src/dialogs/xml-tree.cpp:1339 +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:100 +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:98 +msgid "Cancel" +msgstr "Utzi" + +#: ../../po/../src/dialogs/xml-tree.cpp:1345 +msgid "Create" +msgstr "Sortu" + +#: ../../po/../src/dialogs/xml-tree.cpp:1458 +#, c-format +msgid "" +"Cannot set %s: Another element with value %s already exists!" +msgstr "" + +#: ../../po/../src/document.cpp:369 +#, c-format +msgid "New document %d" +msgstr "%d. Dokumentu Berria" + +#: ../../po/../src/document.cpp:401 +#, c-format +msgid "Memory document %d" +msgstr "%d. Memoria Dokumentua" + +#: ../../po/../src/document.cpp:524 +#, c-format +msgid "Unnamed document %d" +msgstr "%d. Dokumentu Izengabea" + +#. We hit green anchor, closing Green-Blue-Red +#: ../../po/../src/draw-context.cpp:441 +#, fuzzy +msgid "Path is closed." +msgstr "Trazo (%i nodos)" + +#. We hit bot start and end of single curve, closing paths +#: ../../po/../src/draw-context.cpp:456 +msgid "Closing path." +msgstr "" + +#. alpha of color under cursor, to show in the statusbar +#. locale-sensitive printf is OK, since this goes to the UI, not into SVG +#: ../../po/../src/dropper-context.cpp:354 +#, c-format +msgid " alpha %.3g" +msgstr "" + +#. where the color is picked, to show in the statusbar +#: ../../po/../src/dropper-context.cpp:356 +#, c-format +msgid ", averaged with radius %d" +msgstr "" + +#: ../../po/../src/dropper-context.cpp:356 +msgid " under cursor" +msgstr "" + +#. message, to show in the statusbar +#: ../../po/../src/dropper-context.cpp:358 +msgid "Release mouse to set color." +msgstr "" + +#: ../../po/../src/dropper-context.cpp:358 +#: ../../po/../src/tools-switch.cpp:207 +#, fuzzy +msgid "" +"Click to set fill, Shift+click to set stroke; drag to " +"average color in area; with Alt to pick inverse color; Ctrl+C " +"to copy the color under mouse to clipboard" +msgstr "" +"Haga clic para seleccionar un color, clic y arrastre para seleccionar la " +"media de color de un área." + +#: ../../po/../src/extension/dependency.cpp:244 +msgid "Dependency::" +msgstr "" + +#: ../../po/../src/extension/dependency.cpp:245 +#, fuzzy +msgid " type: " +msgstr "Estilo de relleno" + +#: ../../po/../src/extension/dependency.cpp:246 +#, fuzzy +msgid " location: " +msgstr "Resolución:" + +#: ../../po/../src/extension/dependency.cpp:247 +msgid " string: " +msgstr "" + +#: ../../po/../src/extension/dependency.cpp:250 +#, fuzzy +msgid " description: " +msgstr "Selección" + +#. static int i = 0; +#. std::cout << "Checking module[" << i++ << "]: " << name << std::endl; +#: ../../po/../src/extension/extension.cpp:244 +msgid "" +" This is caused by an improper .inx file for this extension. An improper ." +"inx file could have been caused by a faulty installation of Inkscape." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:247 +msgid "an ID was not defined for it." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:251 +msgid "there was no name defined for it." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:255 +msgid "the XML description of it got lost." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:259 +msgid "no implementation was defined for the extension." +msgstr "" + +#. std::cout << "Failed: " << *(_deps[i]) << std::endl; +#: ../../po/../src/extension/extension.cpp:266 +msgid "a dependency was not met." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:286 +#, fuzzy +msgid "Extension \"" +msgstr "Expansión:" + +#: ../../po/../src/extension/extension.cpp:286 +#, fuzzy +msgid "\" failed to load because " +msgstr "Error al cargar el archivo %s" + +#: ../../po/../src/extension/extension.cpp:565 +#, c-format +msgid "Could not create extension error log file '%s'" +msgstr "" + +#. This is some filler text, needs to change before relase +#: ../../po/../src/extension/error-file.cpp:56 +msgid "" +"One or more extensions failed to load\n" +"\n" +"The failed extensions have been skipped. Inkscape will continue to run " +"normally but those extensions will be unavailable. For details to " +"troubleshoot this problem, please refer to the error log located at: " +msgstr "" + +#. This is some filler text, needs to change before relase +#: ../../po/../src/extension/error-file.cpp:65 +msgid "Show dialog on startup" +msgstr "" + +#: ../../po/../src/extension/implementation/script.cpp:845 +msgid "" +"Inkscape has received an error from the script that it called. The text " +"returned with the error is included below. Inkscape will continue working, " +"but the action you requested has been cancelled." +msgstr "" + +#: ../../po/../src/extension/implementation/script.cpp:858 +msgid "" +"Inkscape has received additional data from the script executed. The script " +"did not return an error, but this may indicate the results will not be as " +"expected." +msgstr "" + +#: ../../po/../src/extension/init.cpp:173 +#, fuzzy +msgid "Null external module directory name. Modules will not be loaded." +msgstr "" +"El directorio de módulos (%s) no está disponible. No se cargarán los módulos " +"externos de ese directorio." + +#: ../../po/../src/extension/init.cpp:187 +#, fuzzy, c-format +msgid "" +"Modules directory (%s) is unavailable. External modules in that directory " +"will not be loaded." +msgstr "" +"El directorio de módulos (%s) no está disponible. No se cargarán los módulos " +"externos de ese directorio." + +#: ../../po/../src/extension/internal/gnome.cpp:80 +msgid "Select printer" +msgstr "Inprimagailua aukeratu" + +#: ../../po/../src/extension/internal/gnome.cpp:131 +#, fuzzy +msgid "Inkscape: Print Preview" +msgstr "Inkscape (nombre documento %s..): Presentación preliminar" + +#: ../../po/../src/extension/internal/grid.cpp:213 +#, fuzzy +msgid "Line Width" +msgstr "An_cho de página" + +#: ../../po/../src/extension/internal/grid.cpp:214 +#, fuzzy +msgid "Horizontal Spacing" +msgstr "Líneas horizontales" + +#: ../../po/../src/extension/internal/grid.cpp:215 +#, fuzzy +msgid "Vertical Spacing" +msgstr "Líneas verticales" + +#: ../../po/../src/extension/internal/grid.cpp:216 +#, fuzzy +msgid "Horizontal Offset" +msgstr "Líneas horizontales" + +#: ../../po/../src/extension/internal/grid.cpp:217 +#, fuzzy +msgid "Vertical Offset" +msgstr "Líneas verticales" + +#: ../../po/../src/extension/internal/ps.cpp:123 +msgid "Print Destination" +msgstr "Inprimatze helburua" + +#. Print properties frame +#: ../../po/../src/extension/internal/ps.cpp:138 +msgid "Print properties" +msgstr "Inprimaketaren ezaugarriak" + +#: ../../po/../src/extension/internal/ps.cpp:145 +msgid "Print using PostScript operators" +msgstr "Imprimir usando operadores PostScript" + +#: ../../po/../src/extension/internal/ps.cpp:147 +#, fuzzy +msgid "" +"Use PostScript vector operators. The resulting image is usually smaller in " +"file size and can be arbitrarily scaled, but alpha transparency and patterns " +"will be lost." +msgstr "" +"Usar operadores PostScript vectoriales. La imagen resultante normalmente " +"será menor y puede ser escalada arbitrariamente, pero la transparencia alfa, " +"los gradientes, los marcadores y los patrones se perderán." + +#: ../../po/../src/extension/internal/ps.cpp:152 +msgid "Print as bitmap" +msgstr "Imprimir como mapa de bits" + +#: ../../po/../src/extension/internal/ps.cpp:154 +msgid "" +"Print everything as bitmap. The resulting image is usually larger in file " +"size and cannot be arbitrarily scaled without quality loss, but all objects " +"will be rendered exactly as displayed." +msgstr "" +"Imprimir todo como mapa de bits. La imagen resultante normalmente será mayor " +"y la calidad dependerá del factor de ampliación, pero todos los objetos " +"serán renderizados idénticos a lo que ve en pantalla." + +#: ../../po/../src/extension/internal/ps.cpp:168 +msgid "Preferred resolution (dots per inch) of bitmap" +msgstr "Resolución preferida (puntos por pulgada) de mapa de bits" + +#: ../../po/../src/extension/internal/ps.cpp:182 +msgid "Resolution:" +msgstr "Bereizmena:" + +#. Print destination frame +#: ../../po/../src/extension/internal/ps.cpp:186 +msgid "Print destination" +msgstr "Destino de impresión" + +#: ../../po/../src/extension/internal/ps.cpp:192 +msgid "" +"Use '> filename' to print to file.\n" +"Use '| prog arg...' to pipe to a program." +msgstr "" +"Utilice '> archivo' para imprimir a un archivo.\n" +"Utilice '| prog arg...' para enviarlo a un programa." + +#: ../../po/../src/extension/internal/ps.cpp:1227 +msgid "write error occurred" +msgstr "ocurrió un error de escritura" + +#: ../../po/../src/extension/prefdialog.cpp:21 +#, fuzzy +msgid " Preferences" +msgstr "Inkscape: _Avanzado" + +#. We can't call sp_ui_error_dialog because we may be +#. running from the console, in which case calling sp_ui +#. routines will cause a segfault. See bug 1000350 - bryce +#. sp_ui_error_dialog(_("Format autodetect failed. The file is being opened as SVG.")); +#: ../../po/../src/extension/system.cpp:105 +msgid "Format autodetect failed. The file is being opened as SVG." +msgstr "La autodetección de formato falló. El archivo se abrirá como SVG." + +#. TRANSLATORS: default.svg is localizable - this is the name of the default document +#. template. This way you can localize the default pagesize, translate the name of +#. the default layer, etc. If you wish to localize this file, please create a +#. localized share/templates/default.xx.svg file, where xx is your language code. +#: ../../po/../src/file.cpp:133 +#, fuzzy +msgid "default.svg" +msgstr "Predeterminados" + +#: ../../po/../src/file.cpp:215 ../../po/../src/file.cpp:900 +#, c-format +msgid "Failed to load the requested file %s" +msgstr "Error al cargar el archivo %s" + +#: ../../po/../src/file.cpp:240 +#, fuzzy +msgid "Document not saved yet. Cannot revert." +msgstr "Documento no guardado." + +#: ../../po/../src/file.cpp:246 +#, c-format +msgid "Changes will be lost! Are you sure you want to reload document %s?" +msgstr "" + +#: ../../po/../src/file.cpp:266 +#, fuzzy +msgid "Document reverted." +msgstr "Documento guardado." + +#: ../../po/../src/file.cpp:268 +#, fuzzy +msgid "Document not reverted." +msgstr "Documento no guardado." + +#: ../../po/../src/file.cpp:382 +msgid "Select file to open" +msgstr "Seleccione el archivo a abrir" + +#: ../../po/../src/file.cpp:518 +#, c-format +msgid "Removed %i unused definition in <defs>." +msgid_plural "Removed %i unused definitions in <defs>." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/file.cpp:523 +msgid "No unused definitions in <defs>." +msgstr "" + +#: ../../po/../src/file.cpp:548 +#, c-format +msgid "" +"No Inkscape extension found to save document (%s). This may have been " +"caused by an unknown filename extension." +msgstr "" +"No se ha encontrado una extensión de Inkscape que pueda guardar el documento " +"(%s). Esto pudo ser causado por una extensión de archivo desconocida." + +#: ../../po/../src/file.cpp:549 ../../po/../src/file.cpp:557 +msgid "Document not saved." +msgstr "Ez da dokumentua gorde." + +#: ../../po/../src/file.cpp:556 +#, c-format +msgid "File %s could not be saved." +msgstr "No se pudo guardar el archivo %s." + +#: ../../po/../src/file.cpp:566 +msgid "Document saved." +msgstr "Gorde da dokumentua." + +#: ../../po/../src/file.cpp:614 +#, fuzzy, c-format +msgid "drawing%s" +msgstr "Dibujo" + +#: ../../po/../src/file.cpp:620 +#, fuzzy, c-format +msgid "drawing-%d%s" +msgstr "Dibujo" + +#: ../../po/../src/file.cpp:655 +#, fuzzy +msgid "Select file to save to" +msgstr "Seleccionar el archivo a guardar" + +#: ../../po/../src/file.cpp:739 +msgid "No changes need to be saved." +msgstr "No hay cambios que guardar." + +#: ../../po/../src/file.cpp:926 +msgid "Select file to import" +msgstr "Seleccionar el archivo a importar" + +#: ../../po/../src/gradient-context.cpp:263 +msgid "Ctrl: snap gradient angle" +msgstr "" + +#: ../../po/../src/gradient-context.cpp:264 +msgid "Shift: draw gradient around the starting point" +msgstr "" + +#. We did an undoable action, but sp_document_done will be called by the knot when released +#. status text; we do not track coords because this branch is run once, not all the time +#. during drag +#: ../../po/../src/gradient-context.cpp:462 +#, c-format +msgid "Gradient for %d objects; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/gradient-context.cpp:464 +#, fuzzy +msgid "Select objects on which to create gradient." +msgstr "Seleccione objetos para elevar." + +#: ../../po/../src/gradient-drag.cpp:65 +#, fuzzy +msgid "Linear gradient start" +msgstr "Gradiente lineal" + +#. POINT_LG_P1 +#: ../../po/../src/gradient-drag.cpp:66 +#, fuzzy +msgid "Linear gradient end" +msgstr "Gradiente lineal" + +#: ../../po/../src/gradient-drag.cpp:67 +#, fuzzy +msgid "Radial gradient center" +msgstr "Gradiente radial" + +#: ../../po/../src/gradient-drag.cpp:68 ../../po/../src/gradient-drag.cpp:69 +#, fuzzy +msgid "Radial gradient radius" +msgstr "Gradiente radial" + +#: ../../po/../src/gradient-drag.cpp:70 +#, fuzzy +msgid "Radial gradient focus" +msgstr "Gradiente radial" + +#: ../../po/../src/gradient-drag.cpp:659 +#, c-format +msgid "" +"%s for: %s%s; drag with Ctrl to snap angle, with Ctrl+Alt to " +"preserve angle, with Ctrl+Shift to scale around center" +msgstr "" + +#: ../../po/../src/gradient-drag.cpp:662 +msgid " (stroke)" +msgstr "" + +#: ../../po/../src/gradient-drag.cpp:665 +msgid "" +"Radial gradient center and focus; drag with Shift to " +"separate focus" +msgstr "" + +#: ../../po/../src/gradient-drag.cpp:667 +#, c-format +msgid "" +"Gradient point shared by %d gradients; drag with Shift to " +"separate" +msgstr "" + +#: ../../po/../src/helper/units.cpp:40 +msgid "Unit" +msgstr "Unitatea" + +#: ../../po/../src/helper/units.cpp:40 +msgid "Units" +msgstr "Unitateak" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Point" +msgstr "Puntua" + +#: ../../po/../src/helper/units.cpp:41 +msgid "pt" +msgstr "pt" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Points" +msgstr "Puntuak" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Pt" +msgstr "Pt" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Pixel" +msgstr "Pixel" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Pixels" +msgstr "Pixelak" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Px" +msgstr "Px" + +#. You can add new elements from this point forward +#: ../../po/../src/helper/units.cpp:44 ../share/extensions/straightseg.inx.h:2 +msgid "Percent" +msgstr "Ehunekoa" + +#: ../../po/../src/helper/units.cpp:44 +msgid "Percents" +msgstr "Ehunekoak" + +#: ../../po/../src/helper/units.cpp:45 +msgid "Millimeter" +msgstr "Milimetroa" + +#: ../../po/../src/helper/units.cpp:45 +msgid "mm" +msgstr "mm" + +#: ../../po/../src/helper/units.cpp:45 +msgid "Millimeters" +msgstr "Milimetroak" + +#: ../../po/../src/helper/units.cpp:46 +msgid "Centimeter" +msgstr "Zentimetroa" + +#: ../../po/../src/helper/units.cpp:46 +msgid "cm" +msgstr "zm" + +#: ../../po/../src/helper/units.cpp:46 +msgid "Centimeters" +msgstr "Zentimetroak" + +#: ../../po/../src/helper/units.cpp:47 +msgid "Meter" +msgstr "Metroa" + +#: ../../po/../src/helper/units.cpp:47 +msgid "m" +msgstr "m" + +#: ../../po/../src/helper/units.cpp:47 +#, fuzzy +msgid "Meters" +msgstr "Metro" + +#. no svg_unit +#: ../../po/../src/helper/units.cpp:48 +msgid "Inch" +msgstr "Hazbetea" + +#: ../../po/../src/helper/units.cpp:48 +msgid "in" +msgstr "in" + +#: ../../po/../src/helper/units.cpp:48 +msgid "Inches" +msgstr "Hazbeteak" + +#. Volatiles do not have default, so there are none here +#. TRANSLATORS: for info, see http://www.w3.org/TR/REC-CSS2/syndata.html#length-units +#: ../../po/../src/helper/units.cpp:51 +msgid "Em square" +msgstr "Em cuadrado" + +#: ../../po/../src/helper/units.cpp:51 +msgid "em" +msgstr "em" + +#: ../../po/../src/helper/units.cpp:51 +msgid "Em squares" +msgstr "Em cuadrados" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/REC-CSS2/syndata.html#length-units +#: ../../po/../src/helper/units.cpp:53 +msgid "Ex square" +msgstr "Ex cuadrado" + +#: ../../po/../src/helper/units.cpp:53 +msgid "ex" +msgstr "ex" + +#: ../../po/../src/helper/units.cpp:53 +msgid "Ex squares" +msgstr "Ex cuadrados" + +#: ../../po/../src/inkscape.cpp:468 +msgid "Untitled document" +msgstr "Izen gabeko dokumentua" + +#. Show nice dialog box +#: ../../po/../src/inkscape.cpp:497 +msgid "Inkscape encountered an internal error and will close now.\n" +msgstr "Inkscape ha encontrado un error interno y se cerrará.\n" + +#: ../../po/../src/inkscape.cpp:498 +#, fuzzy +msgid "" +"Automatic backups of unsaved documents were done to the following " +"locations:\n" +msgstr "" +"Las copias de seguridad automáticas se realizaron en los siguientes " +"directorios:\n" + +#: ../../po/../src/inkscape.cpp:499 +#, fuzzy +msgid "Automatic backup of the following documents failed:\n" +msgstr "La copia de seguridad de los siguientes documentos falló:\n" + +#: ../../po/../src/inkscape.cpp:634 +#, c-format +msgid "" +"Cannot create directory %s.\n" +"%s" +msgstr "" +"No se puede crear el directorio %s.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:635 +#, c-format +msgid "" +"%s is not a valid directory.\n" +"%s" +msgstr "" +"%s no es un directorio válido.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:636 +#, c-format +msgid "" +"Cannot create file %s.\n" +"%s" +msgstr "" +"No se puede crear el archivo %s.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:637 +#, c-format +msgid "" +"Cannot write file %s.\n" +"%s" +msgstr "" +"No se puede escribir el archivo %s.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:638 +msgid "" +"Although Inkscape will run, it will use default settings,\n" +"and any changes made in preferences will not be saved." +msgstr "" +"Aunque Inkscape se ejecutará, se usará la configuración predeterminada\n" +"y no se guardarán los cambios hechos en las preferencias." + +#: ../../po/../src/inkscape.cpp:708 +#, c-format +msgid "" +"%s is not a regular file.\n" +"%s" +msgstr "" +"%s no es un archivo normal.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:709 +#, c-format +msgid "" +"%s not a valid XML file, or\n" +"you don't have read permissions on it.\n" +"%s" +msgstr "" +"%s no es un archivo XML válido o\n" +"no tiene permiso de lectura para él.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:711 +#, fuzzy, c-format +msgid "" +"%s is not a valid menus file.\n" +"%s" +msgstr "" +"%s no es un archivo de preferencias válido.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:712 +#, fuzzy +msgid "" +"Inkscape will run with default menus.\n" +"New menus will not be saved." +msgstr "" +"Inkscape se ejecutará con la configuración predeterminada.\n" +"No se guardarán ajustes nuevos." + +#. sp_ui_menu_append_check_item_from_verb(m, view, _("_Menu"), _("Show or hide the menu bar"), "menu", +#. checkitem_toggled, checkitem_update, 0); +#: ../../po/../src/interface.cpp:753 +msgid "Commands Bar" +msgstr "Agindu-Barra" + +#: ../../po/../src/interface.cpp:753 +#, fuzzy +msgid "Show or hide the Commands bar (under the menu)" +msgstr "Mostrar/ocultar reglas" + +#: ../../po/../src/interface.cpp:755 +#, fuzzy +msgid "Tool Controls" +msgstr "Opciones de la herramienta" + +#: ../../po/../src/interface.cpp:755 +#, fuzzy +msgid "Show or hide the Tool Controls panel" +msgstr "Mostrar/ocultar reglas" + +#: ../../po/../src/interface.cpp:757 +msgid "_Toolbox" +msgstr "" + +#: ../../po/../src/interface.cpp:757 +msgid "Show or hide the main toolbox (on the left)" +msgstr "" + +#: ../../po/../src/interface.cpp:763 +msgid "_Statusbar" +msgstr "" + +#: ../../po/../src/interface.cpp:763 +msgid "Show or hide the statusbar (at the bottom of the window)" +msgstr "" + +#: ../../po/../src/interface.cpp:820 +#, c-format +msgid "Verb \"%s\" Unknown" +msgstr "" + +#. TRANSLATORS: #%s is the id of the group e.g. , not a number. +#: ../../po/../src/interface.cpp:930 +#, fuzzy, c-format +msgid "Enter group #%s" +msgstr "Editar" + +#: ../../po/../src/interface.cpp:941 +#, fuzzy +msgid "Go to parent" +msgstr "Sin pintura" + +#: ../../po/../src/interface.cpp:972 +msgid "Could not parse SVG data" +msgstr "No se pudieron interpretar los datos SVG" + +#: ../../po/../src/interface.cpp:1135 +#, c-format +msgid "Overwrite %s" +msgstr "Gainidatzi %s" + +#: ../../po/../src/interface.cpp:1153 +#, c-format +msgid "" +"The file %s already exists. Do you want to overwrite that file with the " +"current document?" +msgstr "" +"El archivo %s ya existe. ¿Desea sobrescribir ese archivo con el documento " +"actual?" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:59 +msgid "Jabber connection lost." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:72 +#, c-format +msgid "Sending message; %u message remaining in send queue." +msgid_plural "Sending message; %u messages remaining in send queue." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:78 +msgid "Receive queue empty." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:154 +#, c-format +msgid "Receiving change; %u change left to process." +msgid_plural "Receiving change; %u changes left to process." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:157 +#, c-format +msgid "%s has left the chatroom." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:221 +msgid "Nickname %1 is already in use. Please choose a different nickname." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:225 +msgid "An error was encountered while attempting to connect to the server." +msgstr "" + +#. Check to see if the user made any modifications to this document. If so, +#. we want to give them the option of (1) letting us clear their document or (2) +#. opening a new, blank document for the whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:131 +msgid "%1 has invited you to a whiteboard session." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:132 +msgid "Incoming whiteboard invitation from %1" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:135 +msgid "Do you wish to accept %1's whiteboard session invitation?" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:137 +msgid "" +"Would you like to accept %1's invitation in a new document window?\n" +"Accepting the invitation in your current window will discard unsaved changes." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:143 +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:198 +#, fuzzy +msgid "Accept invitation" +msgstr "Selección" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:144 +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:199 +msgid "Decline invitation" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:145 +#, fuzzy +msgid "Accept invitation in new document window" +msgstr "Cambiar a la ventana de documento siguiente" + +#. We could not create a new desktop; ask the user if she or he wants to +#. replace the current document and accept the invitation, or reject the invitation. +#. TRANSLATORS: %1 is a userid here +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:196 +msgid "" +"A new document window could not be opened for a whiteboard session with %" +"1" +msgstr "" + +#. TRANSLATORS: %1 is the peer whom refused our invitation. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:238 +msgid "" +"The user %1 has refused your " +"whiteboard invitation.\n" +"\n" +msgstr "" + +#. TRANSLATORS: %1 is the peer whom refused our invitation, %2 is our Jabber identity. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:241 +msgid "" +"You are still connected to a Jabber server as %2, and may send an " +"invitation to %1 again, or you may send an invitation to a different " +"user." +msgstr "" + +#. TRANSLATORS: %1 is the peer whom we tried to contact, but is already in a whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:252 +msgid "" +"The user %1 is already in a " +"whiteboard session.\n" +"\n" +msgstr "" + +#. TRANSLATORS: %1 is the peer whom we tried to contact, but is already in a whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:255 +msgid "" +"You are still connected to a Jabber server as %1, and may send an " +"invitation to a different user." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/invitation-confirm-dialog.cpp:26 +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:24 +msgid "_Write session file:" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/message-processors.cpp:145 +#, c-format +msgid "%s has joined the chatroom." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/message-queue.cpp:87 +#, c-format +msgid "%u change in receive queue." +msgid_plural "%u changes in receive queue." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/jabber_whiteboard/message-queue.cpp:117 +#, c-format +msgid "%u change in send queue." +msgid_plural "%u changes in send queue." +msgstr[0] "" +msgstr[1] "" + +#. if ID is NULL, then we have a real problem -- we were not able to find a key +#. nor generate one. The only thing we can really do here is abort, since we have +#. no way to let the other client(s) uniquely identify this object. +#. FIXME: If this indicates a programming bug, then don't request translation with +#. * _(...): it is most useful in untranslated form so that developers may search for +#. * it when someone reports it in a bug report (as we want users to do for all bugs, +#. * as indicated by it being a g_warning string). +#. * +#. * Otherwise, if it is not a programming bug but a network error or a bug in the +#. * remote peer (perhaps running different software) or whatever, then present it in +#. * an alert box, and avoid use of technical jargon `NULL'. +#. +#: ../../po/../src/jabber_whiteboard/message-utilities.cpp:171 +msgid "" +"ID for new object is NULL even after generation and lookup attempts: the new " +"object will NOT be sent, nor will any of its child objects!" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:60 +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:995 +msgid "Select a location and filename" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:62 +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:997 +#, fuzzy +msgid "Set filename" +msgstr "Nombre de archivo" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:301 +msgid "No SSL certificate was found." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:304 +msgid "The SSL certificate provided by the Jabber server is untrusted." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:307 +msgid "The SSL certificate provided by the Jabber server is expired." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:310 +msgid "" +"The SSL certificate provided by the Jabber server has not been activated." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:313 +msgid "" +"The SSL certificate provided by the Jabber server contains a hostname that " +"does not match the Jabber server's hostname." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:316 +msgid "" +"The SSL certificate provided by the Jabber server contains an invalid " +"fingerprint." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:319 +msgid "An unknown error occurred while setting up the SSL connection." +msgstr "" + +#. TRANSLATORS: %1 is the message that describes the specific error that occurred when +#. establishing the SSL connection. +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:325 +msgid "" +"%1\n" +"\n" +"Do you wish to continue connecting to the Jabber server?" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:328 +msgid "Continue connecting and ignore further errors" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:329 +msgid "Continue connecting, but warn me of further errors" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:330 +#, fuzzy +msgid "Cancel connection" +msgstr "Hautapena" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:777 +#, c-format +msgid "Established whiteboard session with %s." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:785 +#, c-format +msgid "%s has left the whiteboard session." +msgstr "" + +#. Inform the user +#. TRANSLATORS: %1 is the name of the user that disconnected, %2 is the name of the user whom the disconnected user disconnected from. +#. This message is not used in a chatroom context. +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:790 +msgid "" +"The user %1 has left the " +"whiteboard session.\n" +"\n" +msgstr "" + +#. TRANSLATORS: %1 and %2 are userids +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:792 +msgid "" +"You are still connected to a Jabber server as %2, and may establish a " +"new session to %1 or a different user." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:988 +msgid "" +"Could not open file %1 for session recording.\n" +"The error encountered was: %2.\n" +"\n" +"You may select a different location to record the session, or you may opt to " +"not record this session." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:990 +msgid "Choose a different location" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:991 +msgid "Skip session recording" +msgstr "" + +#: ../../po/../src/knot.cpp:673 +#, fuzzy +msgid "Node or handle drag canceled." +msgstr "Se ha cancelado el arrastre del nodo." + +#: ../../po/../src/libnrtype/FontFactory.cpp:358 +msgid "Ignoring font without family that will crash Pango" +msgstr "" + +#: ../../po/../src/main.cpp:395 +msgid "Print the Inkscape version number" +msgstr "" + +#: ../../po/../src/main.cpp:400 +msgid "Do not use X server (only process files from console)" +msgstr "No utilizar el servidor X (sólo procesar archivos desde la consola)" + +#: ../../po/../src/main.cpp:405 +msgid "Try to use X server (even if $DISPLAY is not set)" +msgstr "Intentar utilizar el servidor X (aunque no se haya definido $DISPLAY)" + +#: ../../po/../src/main.cpp:410 +msgid "Open specified document(s) (option string may be excluded)" +msgstr "" +"Abrir el(los) documento(s) especificado(s) (se pueden excluir las opciones " +"de cadena)" + +#: ../../po/../src/main.cpp:411 ../../po/../src/main.cpp:416 +#: ../../po/../src/main.cpp:421 ../../po/../src/main.cpp:483 +#: ../../po/../src/main.cpp:488 ../../po/../src/main.cpp:493 +msgid "FILENAME" +msgstr "FITXATEGI IZENA" + +#: ../../po/../src/main.cpp:415 +msgid "Print document(s) to specified output file (use '| program' for pipe)" +msgstr "" +"Imprimir documento(s) al archivo de salida especificado (use '| programa' " +"para el filtro)" + +#: ../../po/../src/main.cpp:420 +#, fuzzy +msgid "Export document to a PNG file" +msgstr "Exportar documento a archivo PNG" + +#: ../../po/../src/main.cpp:425 +#, fuzzy +msgid "The resolution used for exporting SVG into bitmap (default 90)" +msgstr "" +"La resolución utilizada para convertir SVG en mapa de bits (por omisión 72.0)" + +#: ../../po/../src/main.cpp:426 +msgid "DPI" +msgstr "DPI" + +#: ../../po/../src/main.cpp:430 +#, fuzzy +msgid "" +"Exported area in SVG user units (default is the canvas; 0,0 is lower-left " +"corner)" +msgstr "" +"Área exportada en milímetros (por omisión es el documento completo, 0,0 es " +"la esquina inferior izquierda)" + +#: ../../po/../src/main.cpp:431 +msgid "x0:y0:x1:y1" +msgstr "x0:y0:x1:y1" + +#: ../../po/../src/main.cpp:435 +msgid "Exported area is the entire drawing (not canvas)" +msgstr "" + +#: ../../po/../src/main.cpp:440 +msgid "" +"Snap the bitmap export area outwards to the nearest integer values (in SVG " +"user units)" +msgstr "" + +#: ../../po/../src/main.cpp:445 +#, fuzzy +msgid "The width of exported bitmap in pixels (overrides export-dpi)" +msgstr "El ancho del mapa de bits generado en pixeles (sobreescribe ppp)" + +#: ../../po/../src/main.cpp:446 +msgid "WIDTH" +msgstr "ZABALERA" + +#: ../../po/../src/main.cpp:450 +#, fuzzy +msgid "The height of exported bitmap in pixels (overrides export-dpi)" +msgstr "El alto del mapa de bits generado en pixeles (sobreescribe ppp)" + +#: ../../po/../src/main.cpp:451 +msgid "HEIGHT" +msgstr "GARAIERA" + +#: ../../po/../src/main.cpp:455 +#, fuzzy +msgid "The ID of the object to export (overrides export-area)" +msgstr "El ancho del mapa de bits generado en pixeles (sobreescribe ppp)" + +#: ../../po/../src/main.cpp:456 ../../po/../src/main.cpp:532 +msgid "ID" +msgstr "ID" + +#. TRANSLATORS: this means: "Only export the object whose id is given in --export-id". +#. See "man inkscape" for details. +#: ../../po/../src/main.cpp:462 +msgid "" +"Export just the object with export-id, hide all others (only with export-id)" +msgstr "" + +#: ../../po/../src/main.cpp:467 +msgid "Use stored filename and DPI hints when exporting (only with export-id)" +msgstr "" + +#: ../../po/../src/main.cpp:472 +#, fuzzy +msgid "Background color of exported bitmap (any SVG-supported color string)" +msgstr "" +"Color de fondo para el mapa de bits exportado (cualquier cadena de color " +"admitida por SVG)" + +#: ../../po/../src/main.cpp:473 +msgid "COLOR" +msgstr "KOLOREA" + +#: ../../po/../src/main.cpp:477 +#, fuzzy +msgid "Background opacity of exported bitmap (either 0.0 to 1.0, or 1 to 255)" +msgstr "" +"Color de fondo para el mapa de bits exportado (cualquier cadena de color " +"admitida por SVG)" + +#: ../../po/../src/main.cpp:478 +msgid "VALUE" +msgstr "" + +#: ../../po/../src/main.cpp:482 +msgid "Export document to plain SVG file (no sodipodi or inkscape namespaces)" +msgstr "" +"Exportar documento a archivo SVG plano (sin las características especiales " +"de Inkscape o Sodipodi)" + +#: ../../po/../src/main.cpp:487 +#, fuzzy +msgid "Export document to a PS file" +msgstr "Exportar documento a archivo PNG" + +#: ../../po/../src/main.cpp:492 +#, fuzzy +msgid "Export document to an EPS file" +msgstr "Exportar documento a archivo PNG" + +#: ../../po/../src/main.cpp:497 +#, fuzzy +msgid "Convert text object to paths on export (EPS)" +msgstr "Convierte el contorno seleccionado en trazo" + +#: ../../po/../src/main.cpp:502 +msgid "Export files with the bounding box set to the page size (EPS)" +msgstr "" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:508 +msgid "" +"Query the X coordinate of the drawing or, if specified, of the object with --" +"query-id" +msgstr "" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:514 +msgid "" +"Query the Y coordinate of the drawing or, if specified, of the object with --" +"query-id" +msgstr "" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:520 +msgid "" +"Query the width of the drawing or, if specified, of the object with --query-" +"id" +msgstr "" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:526 +msgid "" +"Query the height of the drawing or, if specified, of the object with --query-" +"id" +msgstr "" + +#: ../../po/../src/main.cpp:531 +#, fuzzy +msgid "The ID of the object whose dimensions are queried" +msgstr "El ancho del mapa de bits generado en pixeles (sobreescribe ppp)" + +#. TRANSLATORS: this option makes Inkscape print the name (path) of the extension directory +#: ../../po/../src/main.cpp:537 +msgid "Print out the extension directory and exit" +msgstr "" + +#: ../../po/../src/main.cpp:542 +msgid "Show given files one-by-one, switch to next on any key/mouse event" +msgstr "" +"Mostrar los archivos uno por uno, cambiar al siguiente al pulsar una tecla o " +"el ratón" + +#: ../../po/../src/main.cpp:547 +msgid "Use the new Gtkmm GUI interface" +msgstr "" + +#: ../../po/../src/main.cpp:552 +msgid "Remove unused definitions from the defs section(s) of the document" +msgstr "" + +#: ../../po/../src/main.cpp:741 +msgid "" +"[OPTIONS...] [FILE...]\n" +"\n" +"Available options:" +msgstr "" + +#: ../../po/../src/menus-skeleton.h:17 +msgid "_New" +msgstr "_Berria" + +#: ../../po/../src/menus-skeleton.h:22 +msgid "Open _Recent" +msgstr "B_erriki Irekiak" + +#: ../../po/../src/menus-skeleton.h:53 +msgid "_Edit" +msgstr "_Edizioa" + +#: ../../po/../src/menus-skeleton.h:84 +msgid "_View" +msgstr "_Ikusi" + +#: ../../po/../src/menus-skeleton.h:85 +#, fuzzy +msgid "_Zoom" +msgstr "Aumentar" + +#: ../../po/../src/menus-skeleton.h:102 +#, fuzzy +msgid "Show/Hide" +msgstr "Mostrar las guías" + +#: ../../po/../src/menus-skeleton.h:107 +msgid "_Display mode" +msgstr "" + +#: ../../po/../src/menus-skeleton.h:126 +#, fuzzy +msgid "_Layer" +msgstr "_Bajar" + +#: ../../po/../src/menus-skeleton.h:143 +msgid "_Object" +msgstr "_Objektua" + +#: ../../po/../src/menus-skeleton.h:165 +msgid "_Path" +msgstr "T_razua" + +#: ../../po/../src/menus-skeleton.h:188 +#, fuzzy +msgid "_Text" +msgstr "Texto" + +#: ../../po/../src/menus-skeleton.h:200 +#, fuzzy +msgid "Effects" +msgstr "Offset:" + +#: ../../po/../src/menus-skeleton.h:207 +msgid "Whiteboa_rd" +msgstr "" + +#: ../../po/../src/menus-skeleton.h:220 +msgid "_Help" +msgstr "_Laguntza" + +#: ../../po/../src/menus-skeleton.h:222 +#, fuzzy +msgid "Tutorials" +msgstr "_Ikastaroak" + +#: ../../po/../src/node-context.cpp:382 +msgid "" +"Ctrl: toggle node type, snap handle angle, move hor/vert; Ctrl" +"+Alt: move along handles" +msgstr "" + +#: ../../po/../src/node-context.cpp:383 +msgid "" +"Shift: toggle node selection, disable snapping, rotate both handles" +msgstr "" + +#: ../../po/../src/node-context.cpp:384 +msgid "Alt: lock handle length; Ctrl+Alt: move along handles" +msgstr "" + +#: ../../po/../src/nodepath.cpp:1399 ../../po/../src/nodepath.cpp:1411 +#: ../../po/../src/nodepath.cpp:1492 ../../po/../src/nodepath.cpp:1504 +#, fuzzy +msgid "To join, you must have two endnodes selected." +msgstr "Para unir debe seleccionar dos nodos finales." + +#: ../../po/../src/nodepath.cpp:1633 ../../po/../src/nodepath.cpp:1647 +#, fuzzy +msgid "" +"Select two non-endpoint nodes on a path between which to delete " +"segments." +msgstr "" +"Debe seleccionar dos nodos no finales de un trazo al que quiera eliminarle " +"segmentos." + +#: ../../po/../src/nodepath.cpp:1743 +msgid "Cannot find path between nodes." +msgstr "No se puede encontrar el trazo entre los nodos." + +#: ../../po/../src/nodepath.cpp:2822 +#, c-format +msgid "" +"Node handle: angle %0.2f°, length %s; with Ctrl to snap " +"angle; with Alt to lock length; with Shift to rotate both " +"handles" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3351 +msgid "" +"Node: drag to edit the path; with Ctrl to snap to horizontal/" +"vertical; with Ctrl+Alt to snap to handles' directions" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3375 +msgid "" +"Node handle: drag to shape the curve; with Ctrl to snap angle; " +"with Alt to lock length; with Shift to rotate both handles" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3399 +msgid "" +"Node handle: drag to shape the curve; with Ctrl to snap angle; " +"with Alt to lock length; with Shift to rotate the opposite " +"handle in sync" +msgstr "" + +#. TRANSLATORS: "end" is an adjective here (NOT a verb) +#: ../../po/../src/nodepath.cpp:3591 +#, fuzzy +msgid "end node" +msgstr "Sangrar nodos" + +#. TRANSLATORS: "cusp" means "sharp" (cusp node); see also the Advanced Tutorial +#: ../../po/../src/nodepath.cpp:3596 +msgid "cusp" +msgstr "zorrotza" + +#. TRANSLATORS: "smooth" is an adjective here +#: ../../po/../src/nodepath.cpp:3599 +msgid "smooth" +msgstr "leuna" + +#: ../../po/../src/nodepath.cpp:3601 +msgid "symmetric" +msgstr "simetrikoa" + +#. TRANSLATORS: "end" is an adjective here (NOT a verb) +#: ../../po/../src/nodepath.cpp:3607 +msgid "end node, handle retracted (drag with Shift to extend)" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3609 +msgid "one handle retracted (drag with Shift to extend)" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3612 +msgid "both handles retracted (drag with Shift to extend)" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3624 +#, fuzzy +msgid "Drag nodes or node handles; arrow keys to move nodes" +msgstr "Arrastre los nodos o puntos de control para editar el trazo" + +#: ../../po/../src/nodepath.cpp:3625 +#, fuzzy +msgid "Drag the node or its handles; arrow keys to move the node" +msgstr "" +"Arrastre para crear una línea a mano alzada. Presione 'a' para conmutar " +"Añadir/Nuevo." + +#: ../../po/../src/nodepath.cpp:3651 ../../po/../src/nodepath.cpp:3663 +#, fuzzy +msgid "Select a single object to edit its nodes or handles." +msgstr "Seleccionar todos los objetos o todos los nodos" + +#: ../../po/../src/nodepath.cpp:3655 +#, fuzzy, c-format +msgid "" +"0 out of %i node selected. Click, Shift+click, " +"or drag around nodes to select." +msgid_plural "" +"0 out of %i nodes selected. Click, Shift+click, " +"or drag around nodes to select." +msgstr[0] "" +"Se han seleccionado 0 de %i nodos. Haga clic, Mayús+clic o arrastre el ratón " +"alrededor de los nodos para seleccionarlos." +msgstr[1] "" +"Se han seleccionado 0 de %i nodos. Haga clic, Mayús+clic o arrastre el ratón " +"alrededor de los nodos para seleccionarlos." + +#: ../../po/../src/nodepath.cpp:3661 +msgid "Drag the handles of the object to modify it." +msgstr "" + +#: ../../po/../src/nodepath.cpp:3669 +#, fuzzy, c-format +msgid "%i of %i node selected; %s. %s." +msgid_plural "%i of %i nodes selected; %s. %s." +msgstr[0] "%i de %i nodos seleccionados; %s. %s." +msgstr[1] "%i de %i nodos seleccionados; %s. %s." + +#: ../../po/../src/nodepath.cpp:3675 +#, fuzzy, c-format +msgid "%i of %i node selected. %s." +msgid_plural "%i of %i nodes selected. %s." +msgstr[0] "%i de %i nodos seleccionados. %s." +msgstr[1] "%i de %i nodos seleccionados. %s." + +#: ../../po/../src/object-edit.cpp:493 +msgid "" +"Adjust the horizontal rounding radius; with Ctrl to make the " +"vertical radius the same" +msgstr "" + +#: ../../po/../src/object-edit.cpp:499 +msgid "" +"Adjust the vertical rounding radius; with Ctrl to make the " +"horizontal radius the same" +msgstr "" + +#: ../../po/../src/object-edit.cpp:506 ../../po/../src/object-edit.cpp:513 +msgid "" +"Adjust the width and height of the rectangle; with Ctrl to " +"lock ratio or stretch in one dimension only" +msgstr "" + +#: ../../po/../src/object-edit.cpp:686 +msgid "Adjust ellipse width, with Ctrl to make circle" +msgstr "" + +#: ../../po/../src/object-edit.cpp:689 +msgid "Adjust ellipse height, with Ctrl to make circle" +msgstr "" + +#: ../../po/../src/object-edit.cpp:692 +msgid "" +"Position the start point of the arc or segment; with Ctrl to " +"snap angle; drag inside the ellipse for arc, outside for " +"segment" +msgstr "" + +#: ../../po/../src/object-edit.cpp:695 +msgid "" +"Position the end point of the arc or segment; with Ctrl to " +"snap angle; drag inside the ellipse for arc, outside for " +"segment" +msgstr "" + +#: ../../po/../src/object-edit.cpp:800 +msgid "" +"Adjust the tip radius of the star or polygon; with Shift to " +"round; with Alt to randomize" +msgstr "" + +#: ../../po/../src/object-edit.cpp:803 +msgid "" +"Adjust the base radius of the star; with Ctrl to keep star " +"rays radial (no skew); with Shift to round; with Alt to " +"randomize" +msgstr "" + +#: ../../po/../src/object-edit.cpp:967 +msgid "" +"Roll/unroll the spiral from inside; with Ctrl to snap angle; " +"with Alt to converge/diverge" +msgstr "" + +#: ../../po/../src/object-edit.cpp:969 +msgid "" +"Roll/unroll the spiral from outside; with Ctrl to snap angle; " +"with Shift to scale/rotate" +msgstr "" + +#: ../../po/../src/object-edit.cpp:1006 +msgid "Adjust the offset distance" +msgstr "" + +#. TRANSLATORS: This refers to the pattern that's inside the object +#: ../../po/../src/object-edit.cpp:1036 +msgid "Move the pattern fill inside the object" +msgstr "" + +#: ../../po/../src/object-edit.cpp:1038 +#, fuzzy +msgid "Scale the pattern fill uniformly" +msgstr "Seleccione objetos para bajar." + +#: ../../po/../src/object-edit.cpp:1040 +msgid "Rotate the pattern fill; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/object-edit.cpp:1065 +msgid "Drag to resize the flowed text frame" +msgstr "" + +#. Item dialog +#: ../../po/../src/object-ui.cpp:106 +#, fuzzy +msgid "Object _Properties" +msgstr "_Propiedades del rectángulo" + +#. Select item +#: ../../po/../src/object-ui.cpp:116 +msgid "_Select This" +msgstr "_Seleccionar esto" + +#. Create link +#: ../../po/../src/object-ui.cpp:126 +msgid "_Create Link" +msgstr "_Crear enlace" + +#. "Ungroup" +#: ../../po/../src/object-ui.cpp:199 ../../po/../src/verbs.cpp:1931 +msgid "_Ungroup" +msgstr "_Sakabanatu" + +#. Link dialog +#: ../../po/../src/object-ui.cpp:239 +msgid "Link _Properties" +msgstr "_Propiedades del enlace" + +#. Select item +#: ../../po/../src/object-ui.cpp:249 +msgid "_Follow Link" +msgstr "Se_guir enlace" + +#. Reset transformations +#: ../../po/../src/object-ui.cpp:254 +msgid "_Remove Link" +msgstr "_Eliminar enlace" + +#. Link dialog +#: ../../po/../src/object-ui.cpp:303 +msgid "Image _Properties" +msgstr "_Propiedades de la imagen" + +#. Item dialog +#: ../../po/../src/object-ui.cpp:344 +msgid "_Fill and Stroke" +msgstr "_Bete eta Inguratu" + +#: ../../po/../src/path-chemistry.cpp:58 +#, fuzzy +msgid "Select at least two objects to combine." +msgstr "Seleccione por lo menos dos objetos para combinar." + +#: ../../po/../src/path-chemistry.cpp:65 +#, fuzzy +msgid "At least one of the objects is not a path, cannot combine." +msgstr "Uno de los objetos no es un trazo, no se puede combinar." + +#: ../../po/../src/path-chemistry.cpp:73 +#, fuzzy +msgid "" +"You cannot combine objects from different groups or layers." +msgstr "No puede combinar objetos de diferentes grupos o capas." + +#: ../../po/../src/path-chemistry.cpp:155 +#, fuzzy +msgid "Select path(s) to break apart." +msgstr "Seleccione trazos para descombinar." + +#: ../../po/../src/path-chemistry.cpp:231 +#, fuzzy +msgid "No path(s) to break apart in the selection." +msgstr "No hay grupos descombinables en la selección." + +#: ../../po/../src/path-chemistry.cpp:252 +#, fuzzy +msgid "Select object(s) to convert to path." +msgstr "Seleccione objetos para bajar al fondo." + +#: ../../po/../src/path-chemistry.cpp:297 +#, fuzzy +msgid "No objects to convert to path in the selection." +msgstr "No hay grupos desagrupables en la selección." + +#: ../../po/../src/path-chemistry.cpp:345 +#, fuzzy +msgid "Select path(s) to reverse." +msgstr "Seleccione dos o más objetos para agrupar." + +#: ../../po/../src/path-chemistry.cpp:370 +#, fuzzy +msgid "No paths to reverse in the selection." +msgstr "No hay grupos descombinables en la selección." + +#: ../../po/../src/pen-context.cpp:379 ../../po/../src/pencil-context.cpp:233 +#, fuzzy +msgid "Continuing selected path" +msgstr "Reducir los trazos seleccionados" + +#: ../../po/../src/pen-context.cpp:390 ../../po/../src/pencil-context.cpp:242 +#, fuzzy +msgid "Creating new path" +msgstr "Creando curva nueva" + +#: ../../po/../src/pen-context.cpp:394 ../../po/../src/pencil-context.cpp:246 +#, fuzzy +msgid "Appending to selected path" +msgstr "Añadiendo a selección" + +#: ../../po/../src/pen-context.cpp:538 +#, fuzzy +msgid "Click or click and drag to close and finish the path." +msgstr "Haga clic para seleccionar o crear un objeto de texto, luego escriba." + +#: ../../po/../src/pen-context.cpp:548 +#, fuzzy +msgid "" +"Click or click and drag to continue the path from this point." +msgstr "Haga clic para seleccionar o crear un objeto de texto, luego escriba." + +#: ../../po/../src/pen-context.cpp:857 +#, c-format +msgid "" +"%s: angle %3.2f°, distance %s; with Ctrl to snap angle, " +"Enter to finish the path" +msgstr "" + +#: ../../po/../src/pen-context.cpp:882 +#, c-format +msgid "" +"Curve handle: angle %3.2f°, length %s; with Ctrl to snap " +"angle" +msgstr "" + +# berrikusi +#: ../../po/../src/pen-context.cpp:912 +#, fuzzy, c-format +msgid "" +"%s: angle %3.2f°, length %s; with Ctrl to snap angle, " +"with Shift to move this handle only" +msgstr "" +"Elipsea: %s × %s; gehitu Ktrl biribila edo proportzio " +"osoko elipsea egiteko; gehitu Maius hasierako puntuaren inguruan " +"marrazteko" + +#: ../../po/../src/pen-context.cpp:946 +msgid "Finishing pen" +msgstr "Terminar pluma" + +#: ../../po/../src/pencil-context.cpp:320 +msgid "Release here to close and finish the path." +msgstr "" + +#: ../../po/../src/pencil-context.cpp:326 +#, fuzzy +msgid "Drawing a freehand path" +msgstr "Esku hutsezko marrazketa" + +#: ../../po/../src/pencil-context.cpp:331 +msgid "Drag to continue the path from this point." +msgstr "" + +#. Write curves to object +#: ../../po/../src/pencil-context.cpp:390 +msgid "Finishing freehand" +msgstr "Terminar mano alzada" + +#: ../../po/../src/rect-context.cpp:387 +msgid "" +"Ctrl: make square or integer-ratio rect, lock a rounded corner " +"circular" +msgstr "" + +#: ../../po/../src/rect-context.cpp:549 +#, c-format +msgid "" +"Rectangle: %s × %s; with Ctrl to make square or integer-" +"ratio rectangle; with Shift to draw around the starting point" +msgstr "" + +#: ../../po/../src/select-context.cpp:243 +#, fuzzy +msgid "Move canceled." +msgstr "Movimiento cancelado." + +#: ../../po/../src/select-context.cpp:252 +#, fuzzy +msgid "Selection canceled." +msgstr "Selección cancelada." + +#: ../../po/../src/select-context.cpp:642 +msgid "Ctrl: select in groups, move hor/vert" +msgstr "" + +#: ../../po/../src/select-context.cpp:643 +msgid "Shift: toggle select, force rubberband, disable snapping" +msgstr "" + +#: ../../po/../src/select-context.cpp:644 +msgid "Alt: select under, move selected" +msgstr "" + +#: ../../po/../src/select-context.cpp:798 +#, fuzzy +msgid "Selected object is not a group. Cannot enter." +msgstr "El objeto seleccionado no tiene contorno, no se puede perfilar." + +#: ../../po/../src/select-context.cpp:876 +#, c-format +msgid "" +"Move by %s, %s; with Ctrl to restrict to horizontal/vertical; " +"with Shift to disable snapping" +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:228 +#, fuzzy +msgid "Nothing was deleted." +msgstr "No se ha borrado nada." + +#: ../../po/../src/selection-chemistry.cpp:259 +#, fuzzy +msgid "Select object(s) to duplicate." +msgstr "Seleccione objetos para duplicar." + +#: ../../po/../src/selection-chemistry.cpp:420 +#, fuzzy +msgid "Select two or more objects to group." +msgstr "Seleccione dos o más objetos para agrupar." + +#: ../../po/../src/selection-chemistry.cpp:428 +#, fuzzy +msgid "Select at least two objects to group." +msgstr "Seleccione por lo menos dos objetos para agrupar." + +#: ../../po/../src/selection-chemistry.cpp:513 +#, fuzzy +msgid "Select a group to ungroup." +msgstr "Seleccione un grupo para desagrupar." + +#: ../../po/../src/selection-chemistry.cpp:554 +#, fuzzy +msgid "No groups to ungroup in the selection." +msgstr "No hay grupos desagrupables en la selección." + +#: ../../po/../src/selection-chemistry.cpp:623 +#, fuzzy +msgid "Select objects to raise." +msgstr "Seleccione objetos para elevar." + +#: ../../po/../src/selection-chemistry.cpp:629 +#: ../../po/../src/selection-chemistry.cpp:681 +#: ../../po/../src/selection-chemistry.cpp:715 +#: ../../po/../src/selection-chemistry.cpp:773 +#, fuzzy +msgid "" +"You cannot raise/lower objects from different groups or layers." +msgstr "No puede elevar/bajar objetos de diferentes grupos o capas." + +#: ../../po/../src/selection-chemistry.cpp:673 +#, fuzzy +msgid "Select object(s) to raise to top." +msgstr "Seleccione los objetos para poner al frente." + +#: ../../po/../src/selection-chemistry.cpp:709 +#, fuzzy +msgid "Select object(s) to lower." +msgstr "Seleccione objetos para bajar." + +#: ../../po/../src/selection-chemistry.cpp:765 +#, fuzzy +msgid "Select object(s) to lower to bottom." +msgstr "Seleccione objetos para bajar al fondo." + +#: ../../po/../src/selection-chemistry.cpp:806 +msgid "Nothing to undo." +msgstr "Nada que deshacer." + +#: ../../po/../src/selection-chemistry.cpp:813 +msgid "Nothing to redo." +msgstr "Nada que rehacer." + +#: ../../po/../src/selection-chemistry.cpp:969 +msgid "Nothing was copied." +msgstr "No se ha copiado nada." + +#: ../../po/../src/selection-chemistry.cpp:1051 +msgid "Current layer is hidden. Unhide it to be able to paste to it." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1055 +msgid "Current layer is locked. Unlock it to be able to paste to it." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1068 +#: ../../po/../src/selection-chemistry.cpp:1103 +#, fuzzy +msgid "Nothing on the clipboard." +msgstr "No hay nada en el portapapeles." + +#: ../../po/../src/selection-chemistry.cpp:1109 +#, fuzzy +msgid "Select object(s) to paste style to." +msgstr "Seleccione los objetos a los que quiera pegarle el estilo." + +#: ../../po/../src/selection-chemistry.cpp:1128 +#, fuzzy +msgid "Select object(s) to move to the layer above." +msgstr "Seleccione objetos para bajar al fondo." + +#: ../../po/../src/selection-chemistry.cpp:1146 +#, fuzzy +msgid "No more layers above." +msgstr "Documento guardado." + +#: ../../po/../src/selection-chemistry.cpp:1160 +#, fuzzy +msgid "Select object(s) to move to the layer below." +msgstr "Seleccione objetos para bajar al fondo." + +#: ../../po/../src/selection-chemistry.cpp:1178 +#, fuzzy +msgid "No more layers below." +msgstr "Documento guardado." + +#: ../../po/../src/selection-chemistry.cpp:1811 +#, fuzzy +msgid "Select a clone to unlink." +msgstr "Seleccione un grupo para desagrupar." + +#: ../../po/../src/selection-chemistry.cpp:1842 +#, fuzzy +msgid "No clones to unlink in the selection." +msgstr "No hay grupos desagrupables en la selección." + +#: ../../po/../src/selection-chemistry.cpp:1859 +msgid "" +"Select a clone to go to its original. Select a linked offset " +"to go to its source. Select a text on path to go to the path. Select " +"a flowed text to go to its frame." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1882 +msgid "" +"Cannot find the object to select (orphaned clone, offset, textpath, " +"flowed text?)" +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1888 +msgid "" +"The object you're trying to select is not visible (it is in <" +"defs>)" +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1915 +#, fuzzy +msgid "Select object(s) to convert to pattern." +msgstr "Seleccione objetos para bajar al fondo." + +#: ../../po/../src/selection-chemistry.cpp:2006 +#, fuzzy +msgid "Select an object with pattern fill to extract objects from." +msgstr "Seleccione objetos para bajar." + +#: ../../po/../src/selection-chemistry.cpp:2059 +#, fuzzy +msgid "No pattern fills in the selection." +msgstr "No hay grupos para reducir/ampliar en la selección." + +#: ../../po/../src/selection-chemistry.cpp:2079 +#, fuzzy +msgid "Select object(s) to make a bitmap copy." +msgstr "Seleccione los objetos para poner al frente." + +#: ../../po/../src/selection-describer.cpp:37 +msgid "Click selection to toggle scale/rotation handles" +msgstr "" +"Haga clic en la selección para conmutar los tiradores de escalado/rotación" + +#. no items +#: ../../po/../src/selection-describer.cpp:39 +#, fuzzy +msgid "" +"No objects selected. Click, Shift+click, or drag around objects to select." +msgstr "" +"No se han seleccionado objetos. Haga clic, Mayús+clic o arrastre para " +"seleccionar los objetos." + +#: ../../po/../src/selection-describer.cpp:51 +#, fuzzy, c-format +msgid " in layer %s" +msgstr "Elevar nodo" + +#: ../../po/../src/selection-describer.cpp:54 +#, fuzzy, c-format +msgid " in layer %s" +msgstr "Elevar nodo" + +#: ../../po/../src/selection-describer.cpp:66 +msgid "Use Shift+D to look up original" +msgstr "" + +#: ../../po/../src/selection-describer.cpp:70 +msgid "Use Shift+D to look up path" +msgstr "" + +#: ../../po/../src/selection-describer.cpp:74 +msgid "Use Shift+D to look up frame" +msgstr "" + +#: ../../po/../src/selection-describer.cpp:84 +#, fuzzy, c-format +msgid "%i object selected" +msgid_plural "%i objects selected" +msgstr[0] "%i objetos seleccionados. %s." +msgstr[1] "%i objetos seleccionados. %s." + +#: ../../po/../src/selection-describer.cpp:90 +#, c-format +msgid "%s%s. %s." +msgstr "" + +#: ../../po/../src/selection-describer.cpp:94 +#, fuzzy, c-format +msgid "%s in %i layer. %s." +msgid_plural "%s in %i layers. %s." +msgstr[0] "%i objetos seleccionados. %s." +msgstr[1] "%i objetos seleccionados. %s." + +#: ../../po/../src/seltrans.cpp:498 +msgid "" +"Center of rotation and skewing: drag to reposition; scaling with " +"Shift also uses this center" +msgstr "" + +#: ../../po/../src/seltrans.cpp:514 +msgid "" +"Squeeze or stretch selection; with Ctrl to scale uniformly; " +"with Shift to scale around rotation center" +msgstr "" + +#: ../../po/../src/seltrans.cpp:515 +msgid "" +"Scale selection; with Ctrl to scale uniformly; with Shift to scale around rotation center" +msgstr "" + +#: ../../po/../src/seltrans.cpp:519 +msgid "" +"Skew selection; with Ctrl to snap angle; with Shift to " +"skew around the opposite side" +msgstr "" + +#: ../../po/../src/seltrans.cpp:520 +msgid "" +"Rotate selection; with Ctrl to snap angle; with Shift " +"to rotate around the opposite corner" +msgstr "" + +#: ../../po/../src/seltrans.cpp:829 ../../po/../src/seltrans.cpp:909 +#, c-format +msgid "Scale: %0.2f%% x %0.2f%%; with Ctrl to lock ratio" +msgstr "" + +#. TRANSLATORS: don't modify the first ";" (it will NOT be displayed as ";" - only the second one will be) +#: ../../po/../src/seltrans.cpp:984 +#, c-format +msgid "Skew: %0.2f°; with Ctrl to snap angle" +msgstr "" + +#. TRANSLATORS: don't modify the first ";" (it will NOT be displayed as ";" - only the second one will be) +#: ../../po/../src/seltrans.cpp:1035 +#, c-format +msgid "Rotate: %0.2f°; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/seltrans.cpp:1090 +#, fuzzy, c-format +msgid "Move center to %s, %s" +msgstr "Enlazar a %s" + +#: ../../po/../src/slideshow.cpp:90 +msgid "Inkscape slideshow" +msgstr "Muestra de diapositivas Inkscape" + +#: ../../po/../src/sp-anchor.cpp:181 +#, fuzzy, c-format +msgid "Link to %s" +msgstr "Enlazar a %s" + +#: ../../po/../src/sp-anchor.cpp:185 +#, fuzzy +msgid "Link without URI" +msgstr "Enlazar a %s" + +#: ../../po/../src/sp-ellipse.cpp:438 ../../po/../src/sp-ellipse.cpp:870 +#, fuzzy +msgid "Ellipse" +msgstr "Elipse" + +#: ../../po/../src/sp-ellipse.cpp:583 +#, fuzzy +msgid "Circle" +msgstr "Círculo" + +#: ../../po/../src/sp-ellipse.cpp:865 +#, fuzzy +msgid "Segment" +msgstr "Elipse" + +#: ../../po/../src/sp-ellipse.cpp:867 +msgid "Arc" +msgstr "" + +#. TRANSLATORS: "Flow region" is an area where text is allowed to flow +#: ../../po/../src/sp-flowregion.cpp:276 +#, fuzzy +msgid "Flow region" +msgstr "Se_guir enlace" + +#. TRANSLATORS: A region "cut out of" a flow region; text is not allowed to flow inside the +#. * flow excluded region. flowRegionExclude in SVG 1.2: see +#. * http://www.w3.org/TR/2004/WD-SVG12-20041027/flow.html#flowRegion-elem and +#. * http://www.w3.org/TR/2004/WD-SVG12-20041027/flow.html#flowRegionExclude-elem. +#: ../../po/../src/sp-flowregion.cpp:493 +msgid "Flow excluded region" +msgstr "" + +#: ../../po/../src/sp-flowtext.cpp:355 +#, c-format +msgid "Flowed text (%d characters)" +msgstr "" + +#: ../../po/../src/sp-flowtext.cpp:357 +#, c-format +msgid "Linked flowed text (%d characters)" +msgstr "" + +#: ../../po/../src/sp-guide.cpp:290 +msgid "vertical guideline" +msgstr "gida bertikala" + +#: ../../po/../src/sp-guide.cpp:292 +msgid "horizontal guideline" +msgstr "gida horizontala" + +#: ../../po/../src/sp-image.cpp:835 +msgid "embedded" +msgstr "" + +#: ../../po/../src/sp-image.cpp:839 +msgid "(null_pointer)" +msgstr "" + +#: ../../po/../src/sp-image.cpp:843 +#, fuzzy, c-format +msgid "Image with bad reference: %s" +msgstr "Imagen con referencia incorrecta: %s" + +#: ../../po/../src/sp-image.cpp:844 +#, fuzzy, c-format +msgid "Image %d × %d: %s" +msgstr "Imagen de color %d x %d : %s" + +#: ../../po/../src/sp-item-group.cpp:390 +#, fuzzy, c-format +msgid "Group of %d object" +msgid_plural "Group of %d objects" +msgstr[0] "Grupo de %d objetos" +msgstr[1] "Grupo de %d objetos" + +#: ../../po/../src/sp-item.cpp:720 +msgid "Object" +msgstr "Objektua" + +#: ../../po/../src/sp-line.cpp:202 +#, fuzzy +msgid "Line" +msgstr "Elipse" + +#. TRANSLATORS COMMENT: %s is either "outset" or "inset" depending on sign +#: ../../po/../src/sp-offset.cpp:433 +#, c-format +msgid "Linked offset, %s by %f pt" +msgstr "" + +#: ../../po/../src/sp-offset.cpp:434 ../../po/../src/sp-offset.cpp:438 +#, fuzzy +msgid "outset" +msgstr "A_mpliar" + +#: ../../po/../src/sp-offset.cpp:434 ../../po/../src/sp-offset.cpp:438 +#, fuzzy +msgid "inset" +msgstr "Re_ducir" + +#. TRANSLATORS COMMENT: %s is either "outset" or "inset" depending on sign +#: ../../po/../src/sp-offset.cpp:437 +#, c-format +msgid "Dynamic offset, %s by %f pt" +msgstr "" + +#: ../../po/../src/sp-path.cpp:127 +#, fuzzy, c-format +msgid "Path (%i node)" +msgid_plural "Path (%i nodes)" +msgstr[0] "Trazo (%i nodos)" +msgstr[1] "Trazo (%i nodos)" + +#: ../../po/../src/sp-polygon.cpp:216 +#, fuzzy +msgid "Polygon" +msgstr "Círculo" + +#: ../../po/../src/sp-polyline.cpp:179 +#, fuzzy +msgid "Polyline" +msgstr "Elipse" + +#: ../../po/../src/sp-rect.cpp:250 +#, fuzzy +msgid "Rectangle" +msgstr "Rectángulo" + +#. TRANSLATORS: since turn count isn't an integer, please adjust the +#. string as needed to deal with an localized plural forms. +#: ../../po/../src/sp-spiral.cpp:305 +#, c-format +msgid "Spiral with %3f turns" +msgstr "" + +#: ../../po/../src/sp-star.cpp:288 +#, fuzzy, c-format +msgid "Star with %d vertex" +msgid_plural "Star with %d vertices" +msgstr[0] "Estrella de %d lados" +msgstr[1] "Estrella de %d lados" + +#: ../../po/../src/sp-star.cpp:292 +#, fuzzy, c-format +msgid "Polygon with %d vertex" +msgid_plural "Polygon with %d vertices" +msgstr[0] "Polígono de %d lados" +msgstr[1] "Polígono de %d lados" + +#. TRANSLATORS: For description of font with no name. +#: ../../po/../src/sp-text.cpp:420 +msgid "<no name found>" +msgstr "" + +#: ../../po/../src/sp-text.cpp:426 +#, fuzzy, c-format +msgid "Text on path (%s, %s)" +msgstr "Texto (%s, %.5gpt)" + +#: ../../po/../src/sp-text.cpp:427 +#, fuzzy, c-format +msgid "Text (%s, %s)" +msgstr "Texto (%s, %.5gpt)" + +#. TRANSLATORS: Used for statusbar description for long chains: +#. * "Clone of: Clone of: ... in Layer 1". +#: ../../po/../src/sp-use.cpp:317 +msgid "..." +msgstr "..." + +#: ../../po/../src/sp-use.cpp:325 +#, fuzzy, c-format +msgid "Clone of: %s" +msgstr "Enlazar a %s" + +#: ../../po/../src/sp-use.cpp:329 +msgid "Orphaned clone" +msgstr "" + +#: ../../po/../src/spiral-context.cpp:355 +msgid "Ctrl: snap angle" +msgstr "" + +#: ../../po/../src/spiral-context.cpp:357 +msgid "Alt: lock spiral radius" +msgstr "" + +#: ../../po/../src/spiral-context.cpp:469 +#, c-format +msgid "" +"Spiral: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/splivarot.cpp:106 +#, fuzzy +msgid "Select at least 2 paths to perform a boolean operation." +msgstr "" +"Debe seleccionar al menos dos trazos para realizar una operación booleana." + +#: ../../po/../src/splivarot.cpp:112 +#, fuzzy +msgid "" +"Select exactly 2 paths to perform difference, XOR, division, or path " +"cut." +msgstr "Seleccione solamente dos trazos para realizar diferencia o XOR." + +#: ../../po/../src/splivarot.cpp:129 ../../po/../src/splivarot.cpp:144 +#, fuzzy +msgid "" +"Unable to determine the z-order of the objects selected for " +"difference, XOR, division, or path cut." +msgstr "" +"No se pudo determinar el orden Z de los objetos seleccionados para la " +"diferencia." + +#: ../../po/../src/splivarot.cpp:174 +#, fuzzy +msgid "" +"One of the objects is not a path, cannot perform boolean operation." +msgstr "" +"Uno de los objetos no es un trazo, no se puede realizar una operación " +"booleana." + +#. TRANSLATORS: "to outline" means "to convert stroke to path" +#: ../../po/../src/splivarot.cpp:554 +#, fuzzy +msgid "Select path(s) to outline." +msgstr "Seleccione trazos para reducir/ampliar." + +#. TRANSLATORS: "to outline" means "to convert stroke to path" +#: ../../po/../src/splivarot.cpp:748 +#, fuzzy +msgid "No stroked paths to outline in the selection." +msgstr "No hay grupos para reducir/ampliar en la selección." + +#: ../../po/../src/splivarot.cpp:832 +#, fuzzy +msgid "Selected object is not a path, cannot inset/outset." +msgstr "El objeto seleccionado no es un trazo, no se puede reducir/ampliar." + +#: ../../po/../src/splivarot.cpp:1040 +#, fuzzy +msgid "Select path(s) to inset/outset." +msgstr "Seleccione trazos para reducir/ampliar." + +#: ../../po/../src/splivarot.cpp:1257 +#, fuzzy +msgid "No paths to inset/outset in the selection." +msgstr "No hay grupos para reducir/ampliar en la selección." + +#: ../../po/../src/splivarot.cpp:1390 +#, fuzzy +msgid "Select path(s) to simplify." +msgstr "Seleccione objetos para simplificar." + +#: ../../po/../src/splivarot.cpp:1417 +#, fuzzy +msgid "No paths to simplify in the selection." +msgstr "No hay grupos simplificables en la selección." + +#: ../../po/../src/star-context.cpp:362 +msgid "Ctrl: snap angle; keep rays radial" +msgstr "" + +#: ../../po/../src/star-context.cpp:470 +#, c-format +msgid "" +"Polygon: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/star-context.cpp:471 +#, c-format +msgid "Star: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/text-chemistry.cpp:90 +#, fuzzy +msgid "Select a text and a path to put text on path." +msgstr "" +"Debe seleccionar al menos dos trazos para realizar una operación booleana." + +#: ../../po/../src/text-chemistry.cpp:95 +msgid "" +"This text object is already put to a path. Remove it from the path " +"first. Use Shift+D to look up its path." +msgstr "" + +#. rect is the only SPShape which is not yet, and thus SVG forbids us from putting text on it +#: ../../po/../src/text-chemistry.cpp:101 +msgid "" +"You cannot put text on a rectangle in this version. Convert rectangle to " +"path first." +msgstr "" + +#: ../../po/../src/text-chemistry.cpp:159 +#, fuzzy +msgid "Select a text on path to remove it from path." +msgstr "" +"Debe seleccionar al menos dos trazos para realizar una operación booleana." + +#: ../../po/../src/text-chemistry.cpp:181 +#, fuzzy +msgid "No texts-on-paths in the selection." +msgstr "No hay grupos descombinables en la selección." + +#: ../../po/../src/text-chemistry.cpp:209 +#: ../../po/../src/text-chemistry.cpp:229 +#, fuzzy +msgid "Select text(s) to remove kerns from." +msgstr "Seleccione dos o más objetos para agrupar." + +#: ../../po/../src/text-chemistry.cpp:250 +#, fuzzy +msgid "" +"Select a text and one or more paths or shapes to flow text " +"into frame." +msgstr "" +"Debe seleccionar al menos dos trazos para realizar una operación booleana." + +#: ../../po/../src/text-chemistry.cpp:322 +#, fuzzy +msgid "Select a flowed text to unflow it." +msgstr "Seleccione trazos para reducir/ampliar." + +#: ../../po/../src/text-context.cpp:463 +#, fuzzy +msgid "Click to edit the text, drag to select part of the text." +msgstr "Haga clic para seleccionar o crear un objeto de texto, luego escriba." + +#: ../../po/../src/text-context.cpp:465 +#, fuzzy +msgid "" +"Click to edit the flowed text, drag to select part of the text." +msgstr "Haga clic para seleccionar o crear un objeto de texto, luego escriba." + +#: ../../po/../src/text-context.cpp:540 +msgid "Non-printable character" +msgstr "" + +#: ../../po/../src/text-context.cpp:589 +#, c-format +msgid "Unicode: %s: %s" +msgstr "" + +#: ../../po/../src/text-context.cpp:591 ../../po/../src/text-context.cpp:855 +msgid "Unicode: " +msgstr "" + +#: ../../po/../src/text-context.cpp:615 +msgid "Current layer is hidden. Unhide it to be able to add text." +msgstr "" + +#: ../../po/../src/text-context.cpp:619 +msgid "Current layer is locked. Unlock it to be able to add text." +msgstr "" + +#: ../../po/../src/text-context.cpp:673 +#, c-format +msgid "Flowed text frame: %s × %s" +msgstr "" + +#: ../../po/../src/text-context.cpp:708 ../../po/../src/text-context.cpp:1464 +msgid "Type text; Enter to start new line." +msgstr "" + +#: ../../po/../src/text-context.cpp:719 +msgid "Flowed text is created." +msgstr "" + +#: ../../po/../src/text-context.cpp:722 +msgid "" +"The frame is too small for the current font size. Flowed text not " +"created." +msgstr "" + +#: ../../po/../src/text-context.cpp:841 +msgid "No-break space" +msgstr "" + +#: ../../po/../src/text-context.cpp:1462 +msgid "Type flowed text; Enter to start new paragraph." +msgstr "" + +#: ../../po/../src/text-context.cpp:1472 ../../po/../src/tools-switch.cpp:189 +#, fuzzy +msgid "" +"Click to select or create text, drag to create flowed text; " +"then type." +msgstr "Haga clic para seleccionar o crear un objeto de texto, luego escriba." + +#: ../../po/../src/tools-switch.cpp:141 +#, fuzzy +msgid "" +"To edit a path, click, Shift+click, or drag around " +"nodes to select them, then drag nodes and handles. Click on an " +"object to select." +msgstr "" +"Para editar un trazo haga clic, Mayús+clic o arrastre alrededor de los nodos " +"para seleccionarlos. Para editar una forma, arrastre sus nodos." + +#: ../../po/../src/tools-switch.cpp:147 +#, fuzzy +msgid "" +"Drag to create a rectangle. Drag controls to round corners and " +"resize. Click to select." +msgstr "" +"Arrastre para crear un rectángulo. Utilice la herramienta de nodos para " +"redondear las esquinas." + +#: ../../po/../src/tools-switch.cpp:153 +#, fuzzy +msgid "" +"Drag to create an ellipse. Drag controls to make an arc or " +"segment. Click to select." +msgstr "" +"Arrastre para crear una elipse. Utilice la herramienta de nodos para crear " +"un arco o un segmento." + +#: ../../po/../src/tools-switch.cpp:159 +#, fuzzy +msgid "" +"Drag to create a star. Drag controls to edit the star shape. " +"Click to select." +msgstr "" +"Arrastre para crear una estrella. Utilice la herramienta de nodos para " +"editar la forma de la estrella." + +#: ../../po/../src/tools-switch.cpp:165 +#, fuzzy +msgid "" +"Drag to create a spiral. Drag controls to edit the spiral " +"shape. Click to select." +msgstr "" +"Arrastre para crear una espiral. Utilice la herramienta de nodos para editar " +"la forma de la espiral." + +#: ../../po/../src/tools-switch.cpp:171 +#, fuzzy +msgid "" +"Drag to create a freehand line. Start drawing with Shift to " +"append to selected path." +msgstr "" +"Arrastre para crear una línea a mano alzada. Presione 'a' para conmutar " +"Añadir/Nuevo." + +#: ../../po/../src/tools-switch.cpp:177 +#, fuzzy +msgid "" +"Click or click and drag to start a path; with Shift to " +"append to selected path." +msgstr "" +"Haga click para crear un nodo, arrastre para crear un nodo suave. Presione " +"'a' para conmutar Añadir/Nuevo." + +#: ../../po/../src/tools-switch.cpp:183 +msgid "" +"Drag to paint a calligraphic stroke. Left/right arrow " +"keys adjust width, up/down adjust angle." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:195 +#, fuzzy +msgid "" +"Drag or double click to create a gradient on selected objects, " +"drag handles to adjust gradients." +msgstr "" +"Arrastre para crear una línea a mano alzada. Presione 'a' para conmutar " +"Añadir/Nuevo." + +#: ../../po/../src/tools-switch.cpp:201 +#, fuzzy +msgid "" +"Click or drag around an area to zoom in, Shift+click to " +"zoom out." +msgstr "" +"Haga clic para acercar, Mayús+clic para alejar, arrastre en un área para " +"acercar." + +#: ../../po/../src/tools-switch.cpp:213 +msgid "Click and drag between shapes to create a connector." +msgstr "" + +#: ../../po/../src/trace/potrace/inkscape-potrace.cpp:553 +#: ../../po/../src/trace/potrace/inkscape-potrace.cpp:654 +#, c-format +msgid "Trace: %d. %ld nodes" +msgstr "" + +#: ../../po/../src/trace/trace.cpp:53 ../../po/../src/trace/trace.cpp:62 +#: ../../po/../src/trace/trace.cpp:70 +#, fuzzy +msgid "Select an image to trace" +msgstr "Seleccione objetos para bajar." + +#: ../../po/../src/trace/trace.cpp:133 +#, fuzzy +msgid "Trace: No active document" +msgstr "Crear un documento nuevo" + +#: ../../po/../src/trace/trace.cpp:154 +msgid "Trace: Image has no bitmap data" +msgstr "" + +#: ../../po/../src/trace/trace.cpp:267 +#, fuzzy, c-format +msgid "Trace: Done. %ld nodes created" +msgstr "Último seleccionado" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:59 ../../po/../src/verbs.cpp:2212 +msgid "About Inkscape" +msgstr "Inkscaperen Gainean" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:66 +msgid "_Splash" +msgstr "" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:68 +msgid "_Authors" +msgstr "" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:69 +#, fuzzy +msgid "_Translators" +msgstr "Transfor_mar" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:70 +#, fuzzy +msgid "_License" +msgstr "Baimena" + +#. TRANSLATORS: This is the filename of the `About Inkscape' picture in +#. the `screens' directory. Thus the translation of "about.svg" should be +#. the filename of its translated version, e.g. about.zh.svg for Chinese. +#. +#. N.B. about.svg changes once per release. (We should probably rename +#. the original to about-0.40.svg etc. as soon as we have a translation. +#. If we do so, then add an item to release-checklist saying that the +#. string here should be changed.) +#. FIXME? INKSCAPE_SCREENSDIR and "about.svg" are in UTF-8, not the +#. native filename encoding... and the filename passed to sp_document_new +#. should be in UTF-*8.. +#: ../../po/../src/ui/dialog/aboutbox.cpp:114 +msgid "about.svg" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:464 +msgid "Minimum horizontal gap (in px units) between bounding boxes" +msgstr "" + +#. TRANSLATORS: Horizontal gap +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:466 +#: ../../po/../src/widgets/toolbox.cpp:1556 +msgid "H:" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:474 +msgid "Minimum vertical gap (in px units) between bounding boxes" +msgstr "" + +#. TRANSLATORS: Vertical gap +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:476 +msgid "V:" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:734 +msgid "Align" +msgstr "Lerrokatu" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:735 +msgid "Distribute" +msgstr "Distribuir" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:736 +msgid "Remove overlaps" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:737 +#, fuzzy +msgid "Nodes" +msgstr "Ninguno" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:742 +#, fuzzy +msgid "Relative to: " +msgstr "Movimiento relativo" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:747 +#, fuzzy +msgid "Align right sides of objects to left side of anchor" +msgstr "Lado derecho de los objetos alineados a la izquierda del ancla" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:750 +#, fuzzy +msgid "Align left sides" +msgstr "Alinear" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:753 +#, fuzzy +msgid "Center on vertical axis" +msgstr "Centrar verticalmente" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:756 +#, fuzzy +msgid "Align right sides" +msgstr "Alinear" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:759 +#, fuzzy +msgid "Align left sides of objects to right side of anchor" +msgstr "Lado izquierdo de los objetos alineados a la derecha del ancla" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:762 +#, fuzzy +msgid "Align bottoms of objects to top of anchor" +msgstr "Lado inferior de los objetos alineados por encima del ancla" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:765 +#, fuzzy +msgid "Align tops" +msgstr "Alinear" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:768 +#, fuzzy +msgid "Center on horizontal axis" +msgstr "Centrar horizontalmente" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:771 +#, fuzzy +msgid "Align bottoms" +msgstr "Alinear" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:774 +#, fuzzy +msgid "Align tops of objects to bottom of anchor" +msgstr "Lado superior de los objetos alineados al fondo del ancla" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:779 +#, fuzzy +msgid "Align baseline anchors of texts vertically" +msgstr "Reflejar los objetos seleccionados verticalmente" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:782 +#, fuzzy +msgid "Align baseline anchors of texts horizontally" +msgstr "Reflejar los objetos seleccionados horizontalmente" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:787 +#, fuzzy +msgid "Make horizontal gaps between objects equal" +msgstr "Distribuir la distancia horizontal entre los objetos igualmente" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:791 +#, fuzzy +msgid "Distribute left sides equidistantly" +msgstr "Distribuir el lado izquierdo de los objetos a distancias equivalentes" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:794 +#, fuzzy +msgid "Distribute centers equidistantly horizontally" +msgstr "" +"Distribuir el centro de los objetos a distancias horizontales equivalentes" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:797 +#, fuzzy +msgid "Distribute right sides equidistantly" +msgstr "Distribuir los lados derechos de los objetos a distancias equivalentes" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:801 +#, fuzzy +msgid "Make vertical gaps between objects equal" +msgstr "Distribuir la distancia vertical entre los objetos igualmente" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:805 +#, fuzzy +msgid "Distribute tops equidistantly" +msgstr "" +"Distribuir los centros de los objetos a distancias iguales verticalmente" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:808 +#, fuzzy +msgid "Distribute centers equidistantly vertically" +msgstr "" +"Distribuir los centros de los objetos a distancias iguales verticalmente" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:811 +#, fuzzy +msgid "Distribute bottoms equidistantly" +msgstr "Distribuir los lados inferiores de los objetos a la misma distancia" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:816 +#, fuzzy +msgid "Distribute baseline anchors of texts horizontally" +msgstr "Reflejar los objetos seleccionados horizontalmente" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:819 +#, fuzzy +msgid "Distribute baseline anchors of texts vertically" +msgstr "" +"Distribuir los centros de los objetos a distancias iguales verticalmente" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:824 +msgid "Randomize centers in both dimensions" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:827 +msgid "Unclump objects: try to equalize edge-to-edge distances" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:832 +msgid "" +"Move objects as little as possible so that their bounding boxes do not " +"overlap" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:837 +#, fuzzy +msgid "Align selected nodes horizontally" +msgstr "Reflejar los objetos seleccionados horizontalmente" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:840 +#, fuzzy +msgid "Align selected nodes vertically" +msgstr "Reflejar los objetos seleccionados verticalmente" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:843 +#, fuzzy +msgid "Distribute selected nodes horizontally" +msgstr "Reflejar los objetos seleccionados horizontalmente" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:846 +#, fuzzy +msgid "Distribute selected nodes vertically" +msgstr "" +"Distribuir los centros de los objetos a distancias iguales verticalmente" + +#. Rest of the widgetry +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:851 +msgid "Last selected" +msgstr "Último seleccionado" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:852 +msgid "First selected" +msgstr "Primero seleccionado" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:853 +msgid "Biggest item" +msgstr "Elemento mayor" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:854 +msgid "Smallest item" +msgstr "Elemento menor" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:856 +#: ../../po/../src/widgets/desktop-widget.cpp:1065 +msgid "Drawing" +msgstr "Marrazkia" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:91 +#, fuzzy +msgid "Metadata 1" +msgstr "Metadatuak" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:92 +#, fuzzy +msgid "Metadata 2" +msgstr "Metadatuak" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:187 +#, fuzzy +msgid "X coordinate of grid origin" +msgstr "Coordenada vertical de la selección" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:189 +#, fuzzy +msgid "Y coordinate of grid origin" +msgstr "Coordenada vertical de la selección" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:191 +#, fuzzy +msgid "Distance of vertical grid lines" +msgstr "gida bertikala" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:193 +#, fuzzy +msgid "Distance of horizontal grid lines" +msgstr "gida horizontala" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:197 +msgid "Max. snapping distance from grid" +msgstr "" + +#: ../../po/../src/ui/dialog/export.cpp:34 +msgid "Export" +msgstr "Exportar" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:36 +msgid "Fill" +msgstr "Barnekaldea" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:37 +msgid "Stroke Paint" +msgstr "Inguratzeko Kolorea" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:38 +msgid "Stroke Style" +msgstr "Inguratzeko Estiloa" + +#: ../../po/../src/ui/dialog/find.cpp:34 +msgid "Find" +msgstr "Aurkitu" + +#: ../../po/../src/ui/dialog/memory.cpp:96 +#, fuzzy +msgid "Heap" +msgstr "A_yuda" + +#: ../../po/../src/ui/dialog/memory.cpp:97 +#, fuzzy +msgid "In Use" +msgstr "Re_ducir" + +#. TRANSLATORS: "Slack" refers to memory which is in the heap but currently unused. +#. More typical usage is to call this memory "free" rather than "slack". +#: ../../po/../src/ui/dialog/memory.cpp:100 +#, fuzzy +msgid "Slack" +msgstr "Estrella" + +#: ../../po/../src/ui/dialog/memory.cpp:101 +msgid "Total" +msgstr "Guztira" + +#: ../../po/../src/ui/dialog/memory.cpp:141 +#: ../../po/../src/ui/dialog/memory.cpp:147 +#: ../../po/../src/ui/dialog/memory.cpp:154 +#: ../../po/../src/ui/dialog/memory.cpp:186 +msgid "Unknown" +msgstr "Ezezaguna" + +#: ../../po/../src/ui/dialog/memory.cpp:167 +#, fuzzy +msgid "Combined" +msgstr "_Combinar" + +#: ../../po/../src/ui/dialog/memory.cpp:209 +#, fuzzy +msgid "Recalculate" +msgstr "Rectángulo" + +#: ../../po/../src/ui/dialog/messages.cpp:74 +#, fuzzy +msgid "Ready." +msgstr "Rojo:" + +#: ../../po/../src/ui/dialog/messages.cpp:75 +msgid "" +"Enable log display by setting dialogs.debug 'redirect' attribute to 1 in " +"preferences.xml" +msgstr "" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:184 +msgid "_Execute Python" +msgstr "P_ython abiarazi" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:186 +msgid "_Execute Perl" +msgstr "_Perl abiarazi" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:195 +msgid "Script" +msgstr "" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:205 +#, fuzzy +msgid "Output" +msgstr "A_mpliar" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:215 +msgid "Errors" +msgstr "Akatsak" + +#. Dialog organization +#: ../../po/../src/ui/dialog/session-player.cpp:73 +msgid "Session file" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:74 +#, fuzzy +msgid "Playback controls" +msgstr "Opciones de la herramienta" + +#: ../../po/../src/ui/dialog/session-player.cpp:75 +#, fuzzy +msgid "Message information" +msgstr "Reiniciar _transformación" + +#. Active session file display +#. fixme: Does this mean the active file for the session, or the file for the active session? +#. Please indicate which with a TRANSLATORS comment. +#: ../../po/../src/ui/dialog/session-player.cpp:85 +msgid "Active session file:" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:86 +msgid "Delay (milliseconds):" +msgstr "" + +#. Unload/load buttons +#: ../../po/../src/ui/dialog/session-player.cpp:94 +#, fuzzy +msgid "Close file" +msgstr "Itxi" + +#: ../../po/../src/ui/dialog/session-player.cpp:95 +msgid "Open new file" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:96 +#, fuzzy +msgid "Set delay" +msgstr "Aurrezehaztu gisa jarri" + +#: ../../po/../src/ui/dialog/session-player.cpp:138 +#, fuzzy +msgid "Rewind" +msgstr "Gorria" + +#: ../../po/../src/ui/dialog/session-player.cpp:139 +msgid "Go back one change" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:140 +#, fuzzy +msgid "Pause" +msgstr "_Pegar" + +#: ../../po/../src/ui/dialog/session-player.cpp:141 +msgid "Go forward one change" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:142 +msgid "Play" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:177 +#: ../../po/../src/verbs.cpp:1573 +msgid "Open session file" +msgstr "" + +#. ##Set up the Potrace panel +#. #### brightness #### +#. #### Multiple scanning#### +#. ----Hbox1 +#: ../../po/../src/ui/dialog/tracedialog.cpp:345 +#: ../../po/../src/ui/dialog/tracedialog.cpp:428 +msgid "Brightness" +msgstr "Argitasuna" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:348 +msgid "Trace by a given brightness level" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:355 +msgid "Brightness cutoff for black/white" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:362 +msgid "Image Brightness" +msgstr "Irudiaren Argitasuna" + +#. #### canny edge detection #### +#. TRANSLATORS: "Canny" is the name of the inventor of this edge detection method +#: ../../po/../src/ui/dialog/tracedialog.cpp:369 +msgid "Optimal Edge Detection (Canny)" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:372 +msgid "Trace with edge detection by J. Canny's algorithm" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:388 +msgid "Brightness cutoff for adjacent pixels (determines edge thickness)" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:395 +msgid "Edge Detection" +msgstr "Ardatzen Atzematea" + +#. #### quantization #### +#. TRANSLATORS: Color Quantization: the process of reducing the number of colors +#. in an image by selecting an optimized set of representative colors and then +#. re-applying this reduced set to the original image. +#: ../../po/../src/ui/dialog/tracedialog.cpp:404 +#, fuzzy +msgid "Color Quantization" +msgstr "Color de la pintura" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:407 +msgid "Trace along the boundaries of reduced colors" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:414 +#, fuzzy +msgid "The number of reduced colors" +msgstr "Número de revoluciones" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:416 +msgid "Colors:" +msgstr "Koloreak:" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:421 +msgid "Quantization / Reduction" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:431 +msgid "Trace the given number of brightness levels" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:438 +#, fuzzy +msgid "Scans:" +msgstr "Agudeza:" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:440 +msgid "The desired number of scans" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:448 +msgid "Trace the given number of reduced colors" +msgstr "" + +#. ---Hbox3 +#: ../../po/../src/ui/dialog/tracedialog.cpp:454 +msgid "Monochrome" +msgstr "Monokromoa" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:457 +msgid "Same as Color, but convert result to grayscale" +msgstr "" + +#. TRANSLATORS: "Stack" is a verb here +#: ../../po/../src/ui/dialog/tracedialog.cpp:460 +#, fuzzy +msgid "Stack" +msgstr "Estrella" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:463 +msgid "" +"Stack scans vertically (no gaps) or tile horizontally (usually with gaps)" +msgstr "" + +#. TRANSLATORS: "Smooth" is a verb here +#: ../../po/../src/ui/dialog/tracedialog.cpp:466 +#, fuzzy +msgid "Smooth" +msgstr "suave" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:469 +msgid "Apply Gaussian blur to the bitmap before tracing" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:473 +msgid "Multiple Scanning" +msgstr "" + +#. #### Preview #### +#: ../../po/../src/ui/dialog/tracedialog.cpp:479 +#: ../../po/../src/ui/dialog/tracedialog.cpp:489 +#, fuzzy +msgid "Preview" +msgstr "_Nueva vista" + +#. do not expand +#: ../../po/../src/ui/dialog/tracedialog.cpp:483 +msgid "Preview the result without actual tracing" +msgstr "" + +#. #### swap black and white #### +#: ../../po/../src/ui/dialog/tracedialog.cpp:495 +#, fuzzy +msgid "Invert" +msgstr "Re_ducir" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:499 +msgid "Invert black and white regions for single traces" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:503 +msgid "Thanks to Peter Selinger, http://potrace.sourceforge.net" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:506 +msgid "Credits" +msgstr "Kredituak" + +#. done +#. TRANSLATORS: Potrace is an application for transforming bitmaps into +#. vector graphics (http://potrace.sourceforge.net/) +#: ../../po/../src/ui/dialog/tracedialog.cpp:514 +#, fuzzy +msgid "Potrace" +msgstr "Traza" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:527 +#, fuzzy +msgid "Abort a trace in progress" +msgstr "Realizando exportación..." + +#: ../../po/../src/ui/dialog/tracedialog.cpp:531 +msgid "Execute the trace" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:80 +#: ../../po/../src/ui/dialog/transformation.cpp:90 +#, fuzzy +msgid "_Horizontal" +msgstr "Líneas horizontales" + +#: ../../po/../src/ui/dialog/transformation.cpp:80 +msgid "Horizontal displacement (relative) or position (absolute)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:82 +#: ../../po/../src/ui/dialog/transformation.cpp:92 +#, fuzzy +msgid "_Vertical" +msgstr "Líneas verticales" + +#: ../../po/../src/ui/dialog/transformation.cpp:82 +msgid "Vertical displacement (relative) or position (absolute)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:84 +#, fuzzy +msgid "_Width" +msgstr "Ancho:" + +#: ../../po/../src/ui/dialog/transformation.cpp:84 +msgid "Horizontal size increment (absolute or percentage)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:86 +#, fuzzy +msgid "_Height" +msgstr "Garaiera" + +#: ../../po/../src/ui/dialog/transformation.cpp:86 +msgid "Vertical size increment (absolute or percentage)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:88 +#, fuzzy +msgid "A_ngle" +msgstr "Angelua:" + +#: ../../po/../src/ui/dialog/transformation.cpp:88 +#, fuzzy +msgid "Rotation angle (positive = counterclockwise)" +msgstr "Rotar el objeto 90 grados a la izquierda" + +#: ../../po/../src/ui/dialog/transformation.cpp:90 +msgid "" +"Horizontal skew angle (positive = counterclockwise), or absolute " +"displacement, or percentage displacement" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:92 +msgid "" +"Vertical skew angle (positive = counterclockwise), or absolute displacement, " +"or percentage displacement" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:95 +#, fuzzy +msgid "Transformation matrix element A" +msgstr "Matriz de transformación" + +#: ../../po/../src/ui/dialog/transformation.cpp:96 +#, fuzzy +msgid "Transformation matrix element B" +msgstr "Matriz de transformación" + +#: ../../po/../src/ui/dialog/transformation.cpp:97 +#, fuzzy +msgid "Transformation matrix element C" +msgstr "Matriz de transformación" + +#: ../../po/../src/ui/dialog/transformation.cpp:98 +#, fuzzy +msgid "Transformation matrix element D" +msgstr "Matriz de transformación" + +#: ../../po/../src/ui/dialog/transformation.cpp:99 +#, fuzzy +msgid "Transformation matrix element E" +msgstr "Matriz de transformación" + +#: ../../po/../src/ui/dialog/transformation.cpp:100 +#, fuzzy +msgid "Transformation matrix element F" +msgstr "Matriz de transformación" + +#: ../../po/../src/ui/dialog/transformation.cpp:102 +#, fuzzy +msgid "Rela_tive move" +msgstr "Mugimendu erlatiboa" + +#: ../../po/../src/ui/dialog/transformation.cpp:102 +msgid "" +"Add the specified relative displacement to the current position; otherwise, " +"edit the current absolute position directly" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:103 +msgid "Scale proportionally" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:103 +msgid "Preserve the width/height ratio of the scaled objects" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:104 +msgid "Apply to each _object separately" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:104 +msgid "" +"Apply the scale/rotate/skew to each selected object separately; otherwise, " +"transform the selection as a whole" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:105 +msgid "Edit c_urrent matrix" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:105 +msgid "" +"Edit the current transform= matrix; otherwise, post-multiply transform= by " +"this matrix" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:115 +#, fuzzy +msgid "_Move" +msgstr "Mugitu" + +#: ../../po/../src/ui/dialog/transformation.cpp:118 +#, fuzzy +msgid "_Scale" +msgstr "Eskalatu" + +#: ../../po/../src/ui/dialog/transformation.cpp:121 +#, fuzzy +msgid "_Rotate" +msgstr "Biratu" + +#: ../../po/../src/ui/dialog/transformation.cpp:124 +#, fuzzy +msgid "Ske_w" +msgstr "Contorno" + +#: ../../po/../src/ui/dialog/transformation.cpp:127 +msgid "Matri_x" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:141 +#, fuzzy +msgid "Reset the values on the current tab to defaults" +msgstr "Ajustar la herramienta a opciones predeterminadas" + +#: ../../po/../src/ui/dialog/transformation.cpp:148 +#, fuzzy +msgid "Apply transformation to selection" +msgstr "Seleccionar y transformar objetos (F1)" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:43 +msgid "_Use SSL" +msgstr "" + +#. Construct dialog interface +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:68 +#, fuzzy +msgid "_Server:" +msgstr "Reglas" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:69 +#, fuzzy +msgid "_Username:" +msgstr "Nombre de archivo" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:70 +msgid "_Password:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:71 +msgid "P_ort:" +msgstr "" + +#. Buttons +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:99 +#, fuzzy +msgid "Connect" +msgstr "Cerrar" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:126 +msgid "Establishing connection to Jabber server %1 as user %2" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:131 +msgid "Failed to establish connection to Jabber server %1" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:136 +msgid "Authentication failed on Jabber server %1 as %2" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:141 +msgid "SSL initialization failed when connecting to Jabber server %1" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:147 +msgid "Connected to Jabber server %1 as %2" +msgstr "" + +#. Construct labels +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:75 +msgid "Chatroom _name:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:76 +msgid "Chatroom _server:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:77 +msgid "Chatroom _password:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:78 +msgid "Chatroom _handle:" +msgstr "" + +#. Button setup and callback registration +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:97 +msgid "Connect to chatroom" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:132 +msgid "Synchronizing with chatroom %1@%2 using the handle %3" +msgstr "" + +#. Construct dialog interface +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:78 +msgid "_User's Jabber ID:" +msgstr "" + +#. Buttons +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:82 +msgid "_Invite user" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:83 +#, fuzzy +msgid "_Cancel" +msgstr "Utzi" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:94 +msgid "Buddy List" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:170 +msgid "Sending whiteboard invitation to %1" +msgstr "" + +#. FIXME: strings are replaced by placeholders, NOT to be translated until the code is enabled +#. See http://sourceforge.net/mailarchive/message.php?msg_id=11746016 for details +#. File menu +#. Edit menu +#. View menu +#. Layer menu +#. Object menu +#. Path menu +#. add(Gtk::StockItem(CLEANUP, _("PLACEHOLDER, do not translate"))); (using Gtk::Stock::CLEAR) +#. Text menu +#. About menu +#. Tools toolbox +#. Select Tool controls +#. Node Tool controls +#. Calligraphy Tool controls +#. Session playback controls +#: ../../po/../src/ui/stock-items.cpp:34 ../../po/../src/ui/stock-items.cpp:35 +#: ../../po/../src/ui/stock-items.cpp:36 ../../po/../src/ui/stock-items.cpp:37 +#: ../../po/../src/ui/stock-items.cpp:38 ../../po/../src/ui/stock-items.cpp:39 +#: ../../po/../src/ui/stock-items.cpp:40 ../../po/../src/ui/stock-items.cpp:41 +#: ../../po/../src/ui/stock-items.cpp:42 ../../po/../src/ui/stock-items.cpp:43 +#: ../../po/../src/ui/stock-items.cpp:46 ../../po/../src/ui/stock-items.cpp:47 +#: ../../po/../src/ui/stock-items.cpp:48 ../../po/../src/ui/stock-items.cpp:49 +#: ../../po/../src/ui/stock-items.cpp:50 ../../po/../src/ui/stock-items.cpp:51 +#: ../../po/../src/ui/stock-items.cpp:52 ../../po/../src/ui/stock-items.cpp:53 +#: ../../po/../src/ui/stock-items.cpp:54 ../../po/../src/ui/stock-items.cpp:55 +#: ../../po/../src/ui/stock-items.cpp:56 ../../po/../src/ui/stock-items.cpp:57 +#: ../../po/../src/ui/stock-items.cpp:58 ../../po/../src/ui/stock-items.cpp:59 +#: ../../po/../src/ui/stock-items.cpp:62 ../../po/../src/ui/stock-items.cpp:63 +#: ../../po/../src/ui/stock-items.cpp:64 ../../po/../src/ui/stock-items.cpp:65 +#: ../../po/../src/ui/stock-items.cpp:66 ../../po/../src/ui/stock-items.cpp:67 +#: ../../po/../src/ui/stock-items.cpp:68 ../../po/../src/ui/stock-items.cpp:69 +#: ../../po/../src/ui/stock-items.cpp:70 ../../po/../src/ui/stock-items.cpp:71 +#: ../../po/../src/ui/stock-items.cpp:72 ../../po/../src/ui/stock-items.cpp:73 +#: ../../po/../src/ui/stock-items.cpp:74 ../../po/../src/ui/stock-items.cpp:75 +#: ../../po/../src/ui/stock-items.cpp:76 ../../po/../src/ui/stock-items.cpp:77 +#: ../../po/../src/ui/stock-items.cpp:78 ../../po/../src/ui/stock-items.cpp:79 +#: ../../po/../src/ui/stock-items.cpp:80 ../../po/../src/ui/stock-items.cpp:81 +#: ../../po/../src/ui/stock-items.cpp:82 ../../po/../src/ui/stock-items.cpp:83 +#: ../../po/../src/ui/stock-items.cpp:84 ../../po/../src/ui/stock-items.cpp:85 +#: ../../po/../src/ui/stock-items.cpp:86 ../../po/../src/ui/stock-items.cpp:87 +#: ../../po/../src/ui/stock-items.cpp:88 ../../po/../src/ui/stock-items.cpp:89 +#: ../../po/../src/ui/stock-items.cpp:92 ../../po/../src/ui/stock-items.cpp:93 +#: ../../po/../src/ui/stock-items.cpp:94 ../../po/../src/ui/stock-items.cpp:95 +#: ../../po/../src/ui/stock-items.cpp:96 ../../po/../src/ui/stock-items.cpp:97 +#: ../../po/../src/ui/stock-items.cpp:98 ../../po/../src/ui/stock-items.cpp:99 +#: ../../po/../src/ui/stock-items.cpp:100 +#: ../../po/../src/ui/stock-items.cpp:101 +#: ../../po/../src/ui/stock-items.cpp:102 +#: ../../po/../src/ui/stock-items.cpp:103 +#: ../../po/../src/ui/stock-items.cpp:104 +#: ../../po/../src/ui/stock-items.cpp:105 +#: ../../po/../src/ui/stock-items.cpp:108 +#: ../../po/../src/ui/stock-items.cpp:109 +#: ../../po/../src/ui/stock-items.cpp:110 +#: ../../po/../src/ui/stock-items.cpp:111 +#: ../../po/../src/ui/stock-items.cpp:112 +#: ../../po/../src/ui/stock-items.cpp:113 +#: ../../po/../src/ui/stock-items.cpp:114 +#: ../../po/../src/ui/stock-items.cpp:115 +#: ../../po/../src/ui/stock-items.cpp:116 +#: ../../po/../src/ui/stock-items.cpp:117 +#: ../../po/../src/ui/stock-items.cpp:118 +#: ../../po/../src/ui/stock-items.cpp:119 +#: ../../po/../src/ui/stock-items.cpp:120 +#: ../../po/../src/ui/stock-items.cpp:121 +#: ../../po/../src/ui/stock-items.cpp:122 +#: ../../po/../src/ui/stock-items.cpp:123 +#: ../../po/../src/ui/stock-items.cpp:124 +#: ../../po/../src/ui/stock-items.cpp:125 +#: ../../po/../src/ui/stock-items.cpp:126 +#: ../../po/../src/ui/stock-items.cpp:127 +#: ../../po/../src/ui/stock-items.cpp:130 +#: ../../po/../src/ui/stock-items.cpp:131 +#: ../../po/../src/ui/stock-items.cpp:132 +#: ../../po/../src/ui/stock-items.cpp:133 +#: ../../po/../src/ui/stock-items.cpp:134 +#: ../../po/../src/ui/stock-items.cpp:135 +#: ../../po/../src/ui/stock-items.cpp:136 +#: ../../po/../src/ui/stock-items.cpp:137 +#: ../../po/../src/ui/stock-items.cpp:138 +#: ../../po/../src/ui/stock-items.cpp:139 +#: ../../po/../src/ui/stock-items.cpp:140 +#: ../../po/../src/ui/stock-items.cpp:141 +#: ../../po/../src/ui/stock-items.cpp:142 +#: ../../po/../src/ui/stock-items.cpp:143 +#: ../../po/../src/ui/stock-items.cpp:144 +#: ../../po/../src/ui/stock-items.cpp:145 +#: ../../po/../src/ui/stock-items.cpp:146 +#: ../../po/../src/ui/stock-items.cpp:150 +#: ../../po/../src/ui/stock-items.cpp:151 +#: ../../po/../src/ui/stock-items.cpp:152 +#: ../../po/../src/ui/stock-items.cpp:153 +#: ../../po/../src/ui/stock-items.cpp:156 +#: ../../po/../src/ui/stock-items.cpp:157 +#: ../../po/../src/ui/stock-items.cpp:158 +#: ../../po/../src/ui/stock-items.cpp:161 +#: ../../po/../src/ui/stock-items.cpp:162 +#: ../../po/../src/ui/stock-items.cpp:163 +#: ../../po/../src/ui/stock-items.cpp:164 +#: ../../po/../src/ui/stock-items.cpp:165 +#: ../../po/../src/ui/stock-items.cpp:166 +#: ../../po/../src/ui/stock-items.cpp:167 +#: ../../po/../src/ui/stock-items.cpp:168 +#: ../../po/../src/ui/stock-items.cpp:169 +#: ../../po/../src/ui/stock-items.cpp:170 +#: ../../po/../src/ui/stock-items.cpp:171 +#: ../../po/../src/ui/stock-items.cpp:172 +#: ../../po/../src/ui/stock-items.cpp:175 +#: ../../po/../src/ui/stock-items.cpp:176 +#: ../../po/../src/ui/stock-items.cpp:177 +#: ../../po/../src/ui/stock-items.cpp:178 +#: ../../po/../src/ui/stock-items.cpp:181 +#: ../../po/../src/ui/stock-items.cpp:182 +#: ../../po/../src/ui/stock-items.cpp:183 +#: ../../po/../src/ui/stock-items.cpp:184 +#: ../../po/../src/ui/stock-items.cpp:185 +#: ../../po/../src/ui/stock-items.cpp:186 +#: ../../po/../src/ui/stock-items.cpp:187 +#: ../../po/../src/ui/stock-items.cpp:188 +#: ../../po/../src/ui/stock-items.cpp:189 +#: ../../po/../src/ui/stock-items.cpp:190 +#: ../../po/../src/ui/stock-items.cpp:191 +#: ../../po/../src/ui/stock-items.cpp:194 +#: ../../po/../src/ui/stock-items.cpp:195 +#: ../../po/../src/ui/stock-items.cpp:198 +#: ../../po/../src/ui/stock-items.cpp:199 +#: ../../po/../src/ui/stock-items.cpp:200 +#: ../../po/../src/ui/stock-items.cpp:201 +#: ../../po/../src/ui/stock-items.cpp:202 +msgid "PLACEHOLDER, do not translate" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:88 +msgid "small" +msgstr "txikia" + +#: ../../po/../src/ui/widget/panel.cpp:89 +msgid "medium" +msgstr "ertaina" + +#: ../../po/../src/ui/widget/panel.cpp:90 +#, fuzzy +msgid "large" +msgstr "Objetivo:" + +#: ../../po/../src/ui/widget/panel.cpp:91 +msgid "huge" +msgstr "handia" + +#: ../../po/../src/ui/widget/panel.cpp:106 +#, fuzzy +msgid "List" +msgstr "Re_ducir" + +#: ../../po/../src/ui/widget/selected-style.cpp:67 +msgid "F:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:68 +msgid "S:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:69 +msgid "O:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:95 +msgid "N/A" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:98 +#: ../../po/../src/ui/widget/selected-style.cpp:712 +#, fuzzy +msgid "Nothing selected" +msgstr "Suprimir los nodos seleccionados" + +#: ../../po/../src/ui/widget/selected-style.cpp:103 +msgid "No fill" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:103 +#, fuzzy +msgid "No stroke" +msgstr "Contorno" + +#: ../../po/../src/ui/widget/selected-style.cpp:105 +#: ../../po/../src/widgets/paint-selector.cpp:190 +msgid "Pattern" +msgstr "Eredua" + +#: ../../po/../src/ui/widget/selected-style.cpp:108 +#: ../../po/../src/widgets/paint-selector.cpp:885 +msgid "Pattern fill" +msgstr "Ereduaz bete" + +#: ../../po/../src/ui/widget/selected-style.cpp:108 +#, fuzzy +msgid "Pattern stroke" +msgstr "Patrón:" + +#: ../../po/../src/ui/widget/selected-style.cpp:110 +#, fuzzy +msgid "L Gradient" +msgstr "Editor de gradiente" + +#: ../../po/../src/ui/widget/selected-style.cpp:113 +#, fuzzy +msgid "Linear gradient fill" +msgstr "Gradiente lineal" + +#: ../../po/../src/ui/widget/selected-style.cpp:113 +#, fuzzy +msgid "Linear gradient stroke" +msgstr "Gradiente lineal" + +#: ../../po/../src/ui/widget/selected-style.cpp:115 +#, fuzzy +msgid "R Gradient" +msgstr "Editor de gradiente" + +#: ../../po/../src/ui/widget/selected-style.cpp:118 +#, fuzzy +msgid "Radial gradient fill" +msgstr "Gradiente radial" + +#: ../../po/../src/ui/widget/selected-style.cpp:118 +#, fuzzy +msgid "Radial gradient stroke" +msgstr "Gradiente radial" + +#: ../../po/../src/ui/widget/selected-style.cpp:120 +#, fuzzy +msgid "Different" +msgstr "_Ezberdintasuna" + +#: ../../po/../src/ui/widget/selected-style.cpp:123 +#, fuzzy +msgid "Different fills" +msgstr "_Ezberdintasuna" + +#: ../../po/../src/ui/widget/selected-style.cpp:123 +#, fuzzy +msgid "Different strokes" +msgstr "_Ezberdintasuna" + +#: ../../po/../src/ui/widget/selected-style.cpp:125 +#, fuzzy +msgid "Unset" +msgstr "Re_ducir" + +#. TRANSLATORS COMMENT: unset is a verb here +#: ../../po/../src/ui/widget/selected-style.cpp:128 +#: ../../po/../src/ui/widget/selected-style.cpp:182 +#, fuzzy +msgid "Unset fill" +msgstr "Sin título" + +#: ../../po/../src/ui/widget/selected-style.cpp:128 +#: ../../po/../src/ui/widget/selected-style.cpp:182 +msgid "Unset stroke" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:131 +#, fuzzy +msgid "Flat color fill" +msgstr "Color del resaltado:" + +#: ../../po/../src/ui/widget/selected-style.cpp:131 +#, fuzzy +msgid "Flat color stroke" +msgstr "Color del resaltado:" + +#. TRANSLATOR COMMENT: A means "Averaged" +#: ../../po/../src/ui/widget/selected-style.cpp:134 +#, fuzzy +msgid "A" +msgstr "_A" + +#: ../../po/../src/ui/widget/selected-style.cpp:137 +#, fuzzy +msgid "Fill is averaged over selected objects" +msgstr "OR exclusivo de objetos seleccionados" + +#: ../../po/../src/ui/widget/selected-style.cpp:137 +#, fuzzy +msgid "Stroke is averaged over selected objects" +msgstr "Intersección de objetos seleccionados" + +#. TRANSLATOR COMMENT: M means "Multiple" +#: ../../po/../src/ui/widget/selected-style.cpp:140 +#, fuzzy +msgid "M" +msgstr "_M" + +#: ../../po/../src/ui/widget/selected-style.cpp:143 +#, fuzzy +msgid "Multiple selected objects have the same fill" +msgstr "Reflejar los objetos seleccionados verticalmente" + +#: ../../po/../src/ui/widget/selected-style.cpp:143 +#, fuzzy +msgid "Multiple selected objects have the same stroke" +msgstr "Reflejar los objetos seleccionados verticalmente" + +#: ../../po/../src/ui/widget/selected-style.cpp:145 +#, fuzzy +msgid "Edit fill..." +msgstr "Editar" + +#: ../../po/../src/ui/widget/selected-style.cpp:145 +#, fuzzy +msgid "Edit stroke..." +msgstr "Editar" + +#: ../../po/../src/ui/widget/selected-style.cpp:149 +#, fuzzy +msgid "Last set color" +msgstr "Color del resaltado:" + +#: ../../po/../src/ui/widget/selected-style.cpp:153 +#, fuzzy +msgid "Last selected color" +msgstr "Último seleccionado" + +#: ../../po/../src/ui/widget/selected-style.cpp:157 +msgid "White" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:161 +#: ../../po/../src/widgets/sp-color-scales.cpp:461 +#: ../../po/../src/widgets/sp-color-scales.cpp:462 +msgid "Black" +msgstr "Beltza" + +#: ../../po/../src/ui/widget/selected-style.cpp:165 +#, fuzzy +msgid "Copy color" +msgstr "Kolorea" + +#: ../../po/../src/ui/widget/selected-style.cpp:169 +#, fuzzy +msgid "Paste color" +msgstr "Color del resaltado:" + +#: ../../po/../src/ui/widget/selected-style.cpp:173 +#, fuzzy +msgid "Swap fill and stroke" +msgstr "_Relleno y contorno" + +#: ../../po/../src/ui/widget/selected-style.cpp:177 +msgid "Make fill opaque" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:177 +msgid "Make stroke opaque" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:186 +#, fuzzy +msgid "Remove fill" +msgstr "_Eliminar enlace" + +#: ../../po/../src/ui/widget/selected-style.cpp:186 +#, fuzzy +msgid "Remove stroke" +msgstr "_Eliminar enlace" + +#: ../../po/../src/ui/widget/selected-style.cpp:718 +#, fuzzy +msgid "Master opacity" +msgstr "Opacidad:" + +#: ../../po/../src/ui/widget/selected-style.cpp:744 +msgid "0 (transparent)" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:768 +msgid "1.0 (opaque)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1046 +msgid "Moved to next layer." +msgstr "" + +#: ../../po/../src/verbs.cpp:1048 +msgid "Cannot move past last layer." +msgstr "" + +#: ../../po/../src/verbs.cpp:1057 +#, fuzzy +msgid "Moved to previous layer." +msgstr "Cambiar a la ventana de documento anterior" + +#: ../../po/../src/verbs.cpp:1059 +msgid "Cannot move past first layer." +msgstr "" + +#: ../../po/../src/verbs.cpp:1076 ../../po/../src/verbs.cpp:1150 +#, fuzzy +msgid "No current layer." +msgstr "Documento guardado." + +#: ../../po/../src/verbs.cpp:1105 +#, fuzzy, c-format +msgid "Raised layer %s." +msgstr "Elevar nodo" + +#: ../../po/../src/verbs.cpp:1109 +#, fuzzy, c-format +msgid "Lowered layer %s." +msgstr "Seleccionar" + +#: ../../po/../src/verbs.cpp:1118 +msgid "Cannot move layer any further." +msgstr "" + +#. TRANSLATORS: this means "The layer has been deleted." +#: ../../po/../src/verbs.cpp:1148 +#, fuzzy +msgid "Deleted layer." +msgstr "Seleccionar" + +#: ../../po/../src/verbs.cpp:1544 +msgid "" +"You need to connect to a Jabber server before sharing a document with " +"another user." +msgstr "" + +#: ../../po/../src/verbs.cpp:1559 +msgid "" +"You need to connect to a Jabber server before sharing a document with a " +"chatroom." +msgstr "" + +#: ../../po/../src/verbs.cpp:1569 +msgid "XML node tracker has not been initialized; nothing to dump" +msgstr "" + +#. TRANSLATORS: If you have translated the keys.svg file to your language, then +#. translate this string as "keys.LANG.svg" (where LANG is your language code); +#. otherwise leave as "keys.svg". +#: ../../po/../src/verbs.cpp:1631 +msgid "keys.svg" +msgstr "keys.svg" + +#. TRANSLATORS: If you have translated the tutorial-basic.svg file to your language, +#. then translate this string as "tutorial-basic.LANG.svg" (where LANG is your language +#. code); otherwise leave as "tutorial-basic.svg". +#: ../../po/../src/verbs.cpp:1667 +msgid "tutorial-basic.svg" +msgstr "tutorial-basic.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1671 +msgid "tutorial-shapes.svg" +msgstr "tutorial-shapes.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1675 +msgid "tutorial-advanced.svg" +msgstr "tutorial-advanced.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1679 +msgid "tutorial-tracing.svg" +msgstr "tutorial-tracing.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1683 +msgid "tutorial-calligraphy.svg" +msgstr "tutorial-calligraphy.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1687 +msgid "tutorial-elements.svg" +msgstr "tutorial-elements.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1691 +msgid "tutorial-tips.svg" +msgstr "tutorial-tips.svg" + +#: ../../po/../src/verbs.cpp:1842 +msgid "Does nothing" +msgstr "No hacer nada" + +#. File +#: ../../po/../src/verbs.cpp:1845 +msgid "Default" +msgstr "Lehenetsia" + +#: ../../po/../src/verbs.cpp:1845 +#, fuzzy +msgid "Create new document from default template" +msgstr "Crear un documento nuevo" + +#: ../../po/../src/verbs.cpp:1847 +msgid "_Open..." +msgstr "_Ireki..." + +#: ../../po/../src/verbs.cpp:1848 +msgid "Open existing document" +msgstr "Abrir un documento existente" + +#: ../../po/../src/verbs.cpp:1849 +msgid "Re_vert" +msgstr "" + +#: ../../po/../src/verbs.cpp:1850 +msgid "Revert to the last saved version of document (changes will be lost)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1851 +msgid "_Save" +msgstr "_Gorde" + +#: ../../po/../src/verbs.cpp:1851 +msgid "Save document" +msgstr "Guardar documento" + +#: ../../po/../src/verbs.cpp:1853 +msgid "Save _As..." +msgstr "Gorde _honela..." + +#: ../../po/../src/verbs.cpp:1854 +msgid "Save document under new name" +msgstr "Guardar documento con un nombre nuevo" + +#: ../../po/../src/verbs.cpp:1855 +msgid "_Print..." +msgstr "_Inprimatu" + +#: ../../po/../src/verbs.cpp:1855 +msgid "Print document" +msgstr "Imprimir documento" + +#. TRANSLATORS: "Vacuum Defs" means "Clean up defs" (so as to remove unused definitions) +#: ../../po/../src/verbs.cpp:1858 +msgid "Vac_uum Defs" +msgstr "" + +#: ../../po/../src/verbs.cpp:1858 +msgid "Remove unused predefined items from the <defs> of the document" +msgstr "" + +#: ../../po/../src/verbs.cpp:1860 +msgid "Print _Direct" +msgstr "Impresión _directa" + +#: ../../po/../src/verbs.cpp:1861 +#, fuzzy +msgid "Print directly without prompting to a file or pipe" +msgstr "Imprimir directamente a un archivo o pipe" + +#: ../../po/../src/verbs.cpp:1862 +msgid "Print Previe_w" +msgstr "_Vista preliminar" + +#: ../../po/../src/verbs.cpp:1863 +msgid "Preview document printout" +msgstr "Vista preliminar de impresión" + +#: ../../po/../src/verbs.cpp:1864 +msgid "_Import..." +msgstr "_Importar..." + +#: ../../po/../src/verbs.cpp:1865 +msgid "Import bitmap or SVG image into document" +msgstr "Importar mapa de bits o imagen SVG al documento" + +#: ../../po/../src/verbs.cpp:1866 +msgid "_Export Bitmap..." +msgstr "_Exportar mapa de bits..." + +#: ../../po/../src/verbs.cpp:1867 +#, fuzzy +msgid "Export document or selection as a bitmap image" +msgstr "Exportar documento como mapa de bits PNG" + +#: ../../po/../src/verbs.cpp:1868 +msgid "N_ext Window" +msgstr "_Hurrengo Leihoa" + +#: ../../po/../src/verbs.cpp:1869 +msgid "Switch to the next document window" +msgstr "Cambiar a la ventana de documento siguiente" + +#: ../../po/../src/verbs.cpp:1870 +msgid "P_revious Window" +msgstr "_Aurreko Leihoa" + +#: ../../po/../src/verbs.cpp:1871 +msgid "Switch to the previous document window" +msgstr "Cambiar a la ventana de documento anterior" + +#: ../../po/../src/verbs.cpp:1872 +msgid "_Close" +msgstr "It_xi" + +#: ../../po/../src/verbs.cpp:1873 +msgid "Close window" +msgstr "Itxi leihoa" + +#: ../../po/../src/verbs.cpp:1874 +msgid "_Quit" +msgstr "_Irten" + +#: ../../po/../src/verbs.cpp:1874 +msgid "Quit Inkscape" +msgstr "Irten Inkscapetik" + +#. Edit +#: ../../po/../src/verbs.cpp:1877 +msgid "_Undo" +msgstr "_Desegin" + +#: ../../po/../src/verbs.cpp:1877 +msgid "Undo last action" +msgstr "Azken ekintza desegin" + +#: ../../po/../src/verbs.cpp:1879 +msgid "_Redo" +msgstr "_Berregin" + +#: ../../po/../src/verbs.cpp:1880 +msgid "Do again last undone action" +msgstr "Azkena desegindako ekintza berregin" + +#: ../../po/../src/verbs.cpp:1881 +msgid "Cu_t" +msgstr "_Ebaki" + +#: ../../po/../src/verbs.cpp:1882 +#, fuzzy +msgid "Cut selection to clipboard" +msgstr "Cortar los objetos seleccionados y llevarlos al portapapeles" + +#: ../../po/../src/verbs.cpp:1883 +msgid "_Copy" +msgstr "_Kopiatu" + +#: ../../po/../src/verbs.cpp:1884 +#, fuzzy +msgid "Copy selection to clipboard" +msgstr "Copiar los objetos seleccionados al portapapeles" + +#: ../../po/../src/verbs.cpp:1885 +msgid "_Paste" +msgstr "_Itsatsi" + +#: ../../po/../src/verbs.cpp:1886 +#, fuzzy +msgid "Paste objects from clipboard to mouse point" +msgstr "Pegar los objetos desde el portapapeles" + +#: ../../po/../src/verbs.cpp:1887 +msgid "Paste _Style" +msgstr "Pegar e_stilo" + +#: ../../po/../src/verbs.cpp:1888 +#, fuzzy +msgid "Apply style of the copied object to selection" +msgstr "Aplicar el estilo del objeto copiado a la selección" + +#: ../../po/../src/verbs.cpp:1889 +msgid "Paste _In Place" +msgstr "Pegar en el s_itio" + +#: ../../po/../src/verbs.cpp:1890 +#, fuzzy +msgid "Paste objects from clipboard to the original location" +msgstr "Pegar los objetos en el lugar original." + +#: ../../po/../src/verbs.cpp:1891 +msgid "_Delete" +msgstr "E_zabatu" + +#: ../../po/../src/verbs.cpp:1892 +#, fuzzy +msgid "Delete selection" +msgstr "Suprimir los nodos seleccionados" + +#: ../../po/../src/verbs.cpp:1893 +#, fuzzy +msgid "Duplic_ate" +msgstr "D_uplicar" + +#: ../../po/../src/verbs.cpp:1894 +#, fuzzy +msgid "Duplicate selected objects" +msgstr "Duplicar los objetos seleccionados" + +#: ../../po/../src/verbs.cpp:1895 +msgid "Clo_ne" +msgstr "Klo_natu" + +#: ../../po/../src/verbs.cpp:1896 +#, fuzzy +msgid "Create a clone of selected object (a copy linked to the original)" +msgstr "Crear un objeto de offset dinámico enlazado al trazo original" + +#: ../../po/../src/verbs.cpp:1897 +msgid "Unlin_k Clone" +msgstr "" + +#: ../../po/../src/verbs.cpp:1898 +msgid "Cut the clone's link to its original" +msgstr "" + +#: ../../po/../src/verbs.cpp:1899 +#, fuzzy +msgid "Select _Original" +msgstr "Seleccion_ar todo" + +#: ../../po/../src/verbs.cpp:1900 +#, fuzzy +msgid "Select the object to which the clone is linked" +msgstr "Seleccione objetos para bajar." + +#. TRANSLATORS: Convert selection to a rectangle with tiled pattern fill +#: ../../po/../src/verbs.cpp:1902 +#, fuzzy +msgid "O_bjects to Pattern" +msgstr "_Objeto a trazo" + +#: ../../po/../src/verbs.cpp:1903 +msgid "Convert selection to a rectangle with tiled pattern fill" +msgstr "" + +#. TRANSLATORS: Extract objects from a tiled pattern fill +#: ../../po/../src/verbs.cpp:1905 +#, fuzzy +msgid "Pattern to Ob_jects" +msgstr "Patrón:" + +#: ../../po/../src/verbs.cpp:1906 +msgid "Extract objects from a tiled pattern fill" +msgstr "" + +#: ../../po/../src/verbs.cpp:1907 +msgid "Clea_r All" +msgstr "Limpia_r todo" + +#: ../../po/../src/verbs.cpp:1908 +msgid "Delete all objects from document" +msgstr "Borrar todos los objetos del documento" + +#: ../../po/../src/verbs.cpp:1909 +msgid "Select Al_l" +msgstr "Hautatu _Dena" + +#: ../../po/../src/verbs.cpp:1910 +msgid "Select all objects or all nodes" +msgstr "Seleccionar todos los objetos o todos los nodos" + +#: ../../po/../src/verbs.cpp:1911 +msgid "Select All in All La_yers" +msgstr "Hautatu Dena _Geruza Guztietan" + +#: ../../po/../src/verbs.cpp:1912 +#, fuzzy +msgid "Select all objects in all visible and unlocked layers" +msgstr "Seleccionar todos los objetos o todos los nodos" + +#: ../../po/../src/verbs.cpp:1913 +msgid "In_vert Selection" +msgstr "Hautapena Alderantzizkatu" + +#: ../../po/../src/verbs.cpp:1914 +msgid "Invert selection (unselect what is selected and select everything else)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1915 +msgid "Invert in All Layers" +msgstr "" + +#: ../../po/../src/verbs.cpp:1916 +msgid "Invert selection in all visible and unlocked layers" +msgstr "" + +#: ../../po/../src/verbs.cpp:1917 +msgid "D_eselect" +msgstr "D_eseleccionar" + +#: ../../po/../src/verbs.cpp:1918 +msgid "Deselect any selected objects or nodes" +msgstr "Deseleccionar los objetos o nodos seleccionados." + +#. Selection +#: ../../po/../src/verbs.cpp:1921 +msgid "Raise to _Top" +msgstr "Poner al fren_te" + +#: ../../po/../src/verbs.cpp:1922 +msgid "Raise selection to top" +msgstr "Poner la selección al frente" + +#: ../../po/../src/verbs.cpp:1923 +msgid "Lower to _Bottom" +msgstr "_Bajar al fondo" + +#: ../../po/../src/verbs.cpp:1924 +msgid "Lower selection to bottom" +msgstr "Bajar la selección al fondo" + +#: ../../po/../src/verbs.cpp:1925 +msgid "_Raise" +msgstr "Eleva_r" + +#: ../../po/../src/verbs.cpp:1926 +msgid "Raise selection one step" +msgstr "Elevar la selección un nivel" + +#: ../../po/../src/verbs.cpp:1927 +msgid "_Lower" +msgstr "_Bajar" + +#: ../../po/../src/verbs.cpp:1928 +msgid "Lower selection one step" +msgstr "Bajar la selección un nivel" + +#: ../../po/../src/verbs.cpp:1929 +msgid "_Group" +msgstr "_Elkartu" + +#: ../../po/../src/verbs.cpp:1930 +msgid "Group selected objects" +msgstr "Agrupar los objetos seleccionados" + +#: ../../po/../src/verbs.cpp:1932 +#, fuzzy +msgid "Ungroup selected groups" +msgstr "Desagrupar grupo(s) seleccionado(s)" + +#: ../../po/../src/verbs.cpp:1934 +#, fuzzy +msgid "_Put on Path" +msgstr "Convierte el contorno seleccionado en trazo" + +#: ../../po/../src/verbs.cpp:1935 +#, fuzzy +msgid "Put text on path" +msgstr "Convierte el contorno seleccionado en trazo" + +#: ../../po/../src/verbs.cpp:1936 +#, fuzzy +msgid "_Remove from Path" +msgstr "Deshacer _transformaciones" + +#: ../../po/../src/verbs.cpp:1937 +#, fuzzy +msgid "Remove text from path" +msgstr "Convierte el contorno seleccionado en trazo" + +#: ../../po/../src/verbs.cpp:1938 +msgid "Remove Manual _Kerns" +msgstr "" + +#. TRANSLATORS: "glyph": An image used in the visual representation of characters; +#. roughly speaking, how a character looks. A font is a set of glyphs. +#: ../../po/../src/verbs.cpp:1941 +#, fuzzy +msgid "Remove all manual kerns and glyph rotations from a text object" +msgstr "Eliminar transformaciones del objeto" + +#: ../../po/../src/verbs.cpp:1943 +msgid "_Union" +msgstr "_Lotura" + +#: ../../po/../src/verbs.cpp:1944 +msgid "Union of selected objects" +msgstr "Unión de objetos seleccionados" + +#: ../../po/../src/verbs.cpp:1945 +msgid "_Intersection" +msgstr "_Gurutzaketa" + +#: ../../po/../src/verbs.cpp:1946 +msgid "Intersection of selected objects" +msgstr "Intersección de objetos seleccionados" + +#: ../../po/../src/verbs.cpp:1947 +msgid "_Difference" +msgstr "_Ezberdintasuna" + +#: ../../po/../src/verbs.cpp:1948 +#, fuzzy +msgid "Difference of selected objects (bottom minus top)" +msgstr "Diferencia de objetos seleccionados" + +#: ../../po/../src/verbs.cpp:1949 +msgid "E_xclusion" +msgstr "E_xclusión" + +#: ../../po/../src/verbs.cpp:1950 +msgid "Exclusive OR of selected objects" +msgstr "OR exclusivo de objetos seleccionados" + +#: ../../po/../src/verbs.cpp:1951 +msgid "Di_vision" +msgstr "Di_visión" + +#: ../../po/../src/verbs.cpp:1952 +msgid "Cut the bottom object into pieces" +msgstr "Cortar el objeto del fondo en pedazos" + +#. TRANSLATORS: "to cut a path" is not the same as "to break a path apart" - see the +#. Advanced tutorial for more info +#: ../../po/../src/verbs.cpp:1955 +msgid "Cut _Path" +msgstr "Cortar trazo" + +#: ../../po/../src/verbs.cpp:1956 +#, fuzzy +msgid "Cut the bottom object's stroke into pieces, removing fill" +msgstr "Cortar el objeto del fondo en pedazos" + +#. TRANSLATORS: "outset": expand a shape by offsetting the object's path, +#. i.e. by displacing it perpendicular to the path in each point. +#. See also the Advanced Tutorial for explanation. +#: ../../po/../src/verbs.cpp:1960 +#, fuzzy +msgid "Outs_et" +msgstr "A_mpliar" + +#: ../../po/../src/verbs.cpp:1961 +#, fuzzy +msgid "Outset selected paths" +msgstr "Ampliar los trazos seleccionados" + +#: ../../po/../src/verbs.cpp:1963 +#, fuzzy +msgid "O_utset Path by 1 px" +msgstr "A_mpliar trazo 1 px" + +#: ../../po/../src/verbs.cpp:1964 +#, fuzzy +msgid "Outset selected paths by 1 px" +msgstr "Ampliar los trazos seleccionados 1 px" + +#: ../../po/../src/verbs.cpp:1966 +#, fuzzy +msgid "O_utset Path by 10 px" +msgstr "Re_ducir trazo 10 px" + +#: ../../po/../src/verbs.cpp:1967 +#, fuzzy +msgid "Outset selected paths by 10 px" +msgstr "Ampliar los trazos seleccionados 10 px" + +#. TRANSLATORS: "inset": contract a shape by offsetting the object's path, +#. i.e. by displacing it perpendicular to the path in each point. +#. See also the Advanced Tutorial for explanation. +#: ../../po/../src/verbs.cpp:1971 +msgid "I_nset" +msgstr "Re_ducir" + +#: ../../po/../src/verbs.cpp:1972 +#, fuzzy +msgid "Inset selected paths" +msgstr "Reducir los trazos seleccionados" + +#: ../../po/../src/verbs.cpp:1974 +#, fuzzy +msgid "I_nset Path by 1 px" +msgstr "Re_ducir trazo 1 px" + +#: ../../po/../src/verbs.cpp:1975 +#, fuzzy +msgid "Inset selected paths by 1 px" +msgstr "Reducir los trazos seleccionados 1 px" + +#: ../../po/../src/verbs.cpp:1977 +#, fuzzy +msgid "I_nset Path by 10 px" +msgstr "Re_ducir trazo 10 px" + +#: ../../po/../src/verbs.cpp:1978 +#, fuzzy +msgid "Inset selected paths by 10 px" +msgstr "Reducir los trazos seleccionados 10 px" + +#: ../../po/../src/verbs.cpp:1980 +msgid "D_ynamic Offset" +msgstr "Offset d_inámico" + +#: ../../po/../src/verbs.cpp:1980 +msgid "Create a dynamic offset object" +msgstr "Crear un objeto de offset dinámico" + +#: ../../po/../src/verbs.cpp:1982 +msgid "_Linked Offset" +msgstr "Offset en_lazado" + +#: ../../po/../src/verbs.cpp:1983 +msgid "Create a dynamic offset object linked to the original path" +msgstr "Crear un objeto de offset dinámico enlazado al trazo original" + +#: ../../po/../src/verbs.cpp:1985 +msgid "_Stroke to Path" +msgstr "Con_torno a trazo" + +#: ../../po/../src/verbs.cpp:1986 +#, fuzzy +msgid "Convert selected strokes to paths" +msgstr "Convierte el contorno seleccionado en trazo" + +#: ../../po/../src/verbs.cpp:1987 +msgid "Si_mplify" +msgstr "Sinp_lifikatu" + +#: ../../po/../src/verbs.cpp:1988 +#, fuzzy +msgid "Simplify selected paths by removing extra nodes" +msgstr "Simplifica el trazo seleccionado" + +#: ../../po/../src/verbs.cpp:1989 +#, fuzzy +msgid "_Reverse" +msgstr "Reglas" + +#: ../../po/../src/verbs.cpp:1990 +#, fuzzy +msgid "Reverses the direction of selected paths; useful for flipping markers" +msgstr "Intersección de objetos seleccionados" + +#. TRANSLATORS: "to trace" means "to convert a bitmap to vector graphics" (to vectorize) +#: ../../po/../src/verbs.cpp:1992 +#, fuzzy +msgid "_Trace Bitmap" +msgstr "Imprimir como mapa de bits" + +#: ../../po/../src/verbs.cpp:1993 +#, fuzzy +msgid "Convert bitmap object to paths" +msgstr "Convierte el contorno seleccionado en trazo" + +#: ../../po/../src/verbs.cpp:1994 +#, fuzzy +msgid "_Make a Bitmap Copy" +msgstr "Imprimir como mapa de bits" + +#: ../../po/../src/verbs.cpp:1995 +#, fuzzy +msgid "Export selection to a bitmap and insert it into document" +msgstr "Importar mapa de bits o imagen SVG al documento" + +#: ../../po/../src/verbs.cpp:1996 +msgid "_Combine" +msgstr "_Combinar" + +#: ../../po/../src/verbs.cpp:1997 +msgid "Combine several paths into one" +msgstr "" + +#. TRANSLATORS: "to cut a path" is not the same as "to break a path apart" - see the +#. Advanced tutorial for more info +#: ../../po/../src/verbs.cpp:2000 +msgid "Break _Apart" +msgstr "Descombin_ar" + +#: ../../po/../src/verbs.cpp:2001 +#, fuzzy +msgid "Break selected paths into subpaths" +msgstr "Separar los trazos seleccionados en subtrazos" + +#: ../../po/../src/verbs.cpp:2002 +msgid "Gri_d Arrange..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2003 +msgid "Arrange selection in grid pattern" +msgstr "" + +#. Layer +#: ../../po/../src/verbs.cpp:2005 +#, fuzzy +msgid "_Add Layer..." +msgstr "_Bajar" + +#: ../../po/../src/verbs.cpp:2006 +#, fuzzy +msgid "Create a new layer" +msgstr "Crear un documento nuevo" + +#: ../../po/../src/verbs.cpp:2007 +#, fuzzy +msgid "Re_name Layer..." +msgstr "Elevar nodo" + +#: ../../po/../src/verbs.cpp:2008 +#, fuzzy +msgid "Rename the current layer" +msgstr "Seleccionar" + +#: ../../po/../src/verbs.cpp:2009 +#, fuzzy +msgid "Switch to Layer Abov_e" +msgstr "Cambiar a la ventana de documento siguiente" + +#: ../../po/../src/verbs.cpp:2010 +#, fuzzy +msgid "Switch to the layer above the current" +msgstr "Cambiar a la ventana de documento siguiente" + +#: ../../po/../src/verbs.cpp:2011 +#, fuzzy +msgid "Switch to Layer Belo_w" +msgstr "Cambiar a la ventana de documento siguiente" + +#: ../../po/../src/verbs.cpp:2012 +#, fuzzy +msgid "Switch to the layer below the current" +msgstr "Cambiar a la ventana de documento siguiente" + +#: ../../po/../src/verbs.cpp:2013 +#, fuzzy +msgid "Move Selection to Layer Abo_ve" +msgstr "Bajar la selección al fondo" + +#: ../../po/../src/verbs.cpp:2014 +msgid "Move selection to the layer above the current" +msgstr "" + +#: ../../po/../src/verbs.cpp:2015 +#, fuzzy +msgid "Move Selection to Layer Bel_ow" +msgstr "Bajar la selección un nivel" + +#: ../../po/../src/verbs.cpp:2016 +msgid "Move selection to the layer below the current" +msgstr "" + +#: ../../po/../src/verbs.cpp:2017 +#, fuzzy +msgid "Layer to _Top" +msgstr "Poner al fren_te" + +#: ../../po/../src/verbs.cpp:2018 +#, fuzzy +msgid "Raise the current layer to the top" +msgstr "Poner la selección al frente" + +#: ../../po/../src/verbs.cpp:2019 +#, fuzzy +msgid "Layer to _Bottom" +msgstr "_Bajar al fondo" + +#: ../../po/../src/verbs.cpp:2020 +#, fuzzy +msgid "Lower the current layer to the bottom" +msgstr "Bajar la selección al fondo" + +#: ../../po/../src/verbs.cpp:2021 +#, fuzzy +msgid "_Raise Layer" +msgstr "Elevar nodo" + +#: ../../po/../src/verbs.cpp:2022 +msgid "Raise the current layer" +msgstr "" + +#: ../../po/../src/verbs.cpp:2023 +#, fuzzy +msgid "_Lower Layer" +msgstr "Bajar nodo" + +#: ../../po/../src/verbs.cpp:2024 +msgid "Lower the current layer" +msgstr "" + +#: ../../po/../src/verbs.cpp:2025 +#, fuzzy +msgid "_Delete Current Layer" +msgstr "Seleccionar" + +#: ../../po/../src/verbs.cpp:2026 +#, fuzzy +msgid "Delete the current layer" +msgstr "Seleccionar" + +#. Object +#: ../../po/../src/verbs.cpp:2029 +#, fuzzy +msgid "Rotate _90° CW" +msgstr "Rotar _90 grados a la derecha" + +#: ../../po/../src/verbs.cpp:2030 +#, fuzzy +msgid "Rotate selection 90° clockwise" +msgstr "Rotar el objeto 90 grados a la derecha" + +#: ../../po/../src/verbs.cpp:2031 +#, fuzzy +msgid "Rotate 9_0° CCW" +msgstr "Rotar 9_0 grados a la izquierda" + +#: ../../po/../src/verbs.cpp:2032 +#, fuzzy +msgid "Rotate selection 90° counter-clockwise" +msgstr "Rotar el objeto 90 grados a la izquierda" + +#: ../../po/../src/verbs.cpp:2033 +msgid "Remove _Transformations" +msgstr "Deshacer _transformaciones" + +#: ../../po/../src/verbs.cpp:2034 +msgid "Remove transformations from object" +msgstr "Eliminar transformaciones del objeto" + +#: ../../po/../src/verbs.cpp:2035 +msgid "_Object to Path" +msgstr "_Objeto a trazo" + +#: ../../po/../src/verbs.cpp:2036 +#, fuzzy +msgid "Convert selected objects to paths" +msgstr "Convierte el objeto seleccionado en trazos" + +#: ../../po/../src/verbs.cpp:2037 +msgid "_Flow into Frame" +msgstr "" + +#: ../../po/../src/verbs.cpp:2038 +#, fuzzy +msgid "Put text into frames" +msgstr "Convierte el contorno seleccionado en trazo" + +#: ../../po/../src/verbs.cpp:2039 +#, fuzzy +msgid "_Unflow" +msgstr "_Deshacer" + +#: ../../po/../src/verbs.cpp:2040 +msgid "Remove text from frame (creates a single-line text object)" +msgstr "" + +#: ../../po/../src/verbs.cpp:2041 +#, fuzzy +msgid "_Convert to Text" +msgstr "Convierte el contorno seleccionado en trazo" + +#: ../../po/../src/verbs.cpp:2042 +#, fuzzy +msgid "Convert flowed text to regular text objects (preserves appearance)" +msgstr "Convierte el objeto seleccionado en trazos" + +#: ../../po/../src/verbs.cpp:2044 +#, fuzzy +msgid "Flip _Horizontal" +msgstr "Islada _horizontala" + +#: ../../po/../src/verbs.cpp:2044 +#, fuzzy +msgid "Flips selected objects horizontally" +msgstr "Reflejar los objetos seleccionados horizontalmente" + +#: ../../po/../src/verbs.cpp:2047 +#, fuzzy +msgid "Flip _Vertical" +msgstr "Islada _bertikala" + +#: ../../po/../src/verbs.cpp:2047 +#, fuzzy +msgid "Flips selected objects vertically" +msgstr "Reflejar los objetos seleccionados verticalmente" + +#. Tools +#: ../../po/../src/verbs.cpp:2051 +msgid "Select" +msgstr "Hautatu" + +#: ../../po/../src/verbs.cpp:2052 +#, fuzzy +msgid "Select and transform objects" +msgstr "Seleccionar y transformar objetos (F1)" + +#: ../../po/../src/verbs.cpp:2053 +msgid "Node Edit" +msgstr "Edición de nodos" + +#: ../../po/../src/verbs.cpp:2054 +#, fuzzy +msgid "Edit path nodes or control handles" +msgstr "Editar trazo o tiradores de control (F2)" + +#: ../../po/../src/verbs.cpp:2056 +msgid "Create rectangles and squares" +msgstr "Laukizuzenak eta karratuak sortu" + +#: ../../po/../src/verbs.cpp:2058 +msgid "Create circles, ellipses, and arcs" +msgstr "Biribilak, elipseak eta arkuak sortu" + +#: ../../po/../src/verbs.cpp:2060 +msgid "Create stars and polygons" +msgstr "Izarrak eta poligonoak sortu" + +#: ../../po/../src/verbs.cpp:2062 +msgid "Create spirals" +msgstr "Kiribilak sortu" + +#: ../../po/../src/verbs.cpp:2064 +msgid "Draw freehand lines" +msgstr "Esku hutsezko marrazketa" + +#: ../../po/../src/verbs.cpp:2066 +msgid "Draw Bezier curves and straight lines" +msgstr "Bezier kurbak eta lerro zuzenak marraztu" + +#: ../../po/../src/verbs.cpp:2068 +msgid "Draw calligraphic lines" +msgstr "Kaligrafia lerroak marraztu" + +#: ../../po/../src/verbs.cpp:2070 +msgid "Create and edit text objects" +msgstr "Testu objektuak sortu eta editatu" + +#: ../../po/../src/verbs.cpp:2072 +msgid "Create and edit gradients" +msgstr "Gradienteak sortu eta editatu" + +#: ../../po/../src/verbs.cpp:2074 +msgid "Zoom in or out" +msgstr "Gerturatu edo urrundu" + +#: ../../po/../src/verbs.cpp:2076 +msgid "Pick averaged colors from image" +msgstr "Irudiaren batazbesteko kolorea hartu" + +#: ../../po/../src/verbs.cpp:2078 +#, fuzzy +msgid "Create connectors" +msgstr "Crear un documento nuevo" + +#. Tool prefs +#: ../../po/../src/verbs.cpp:2081 +msgid "Selector Preferences" +msgstr "" + +#: ../../po/../src/verbs.cpp:2082 +#, fuzzy +msgid "Open Preferences for the Selector tool" +msgstr "Inkscape: _Avanzado" + +#: ../../po/../src/verbs.cpp:2083 +msgid "Node Tool Preferences" +msgstr "" + +#: ../../po/../src/verbs.cpp:2084 +#, fuzzy +msgid "Open Preferences for the Node tool" +msgstr "Inkscape: _Avanzado" + +#: ../../po/../src/verbs.cpp:2085 +msgid "Rectangle Preferences" +msgstr "Laukizuzenetarako Hobespenak" + +#: ../../po/../src/verbs.cpp:2086 +#, fuzzy +msgid "Open Preferences for the Rectangle tool" +msgstr "Inkscape: _Avanzado" + +#: ../../po/../src/verbs.cpp:2087 +msgid "Ellipse Preferences" +msgstr "Elipseetarako Hobespenak" + +#: ../../po/../src/verbs.cpp:2088 +#, fuzzy +msgid "Open Preferences for the Ellipse tool" +msgstr "Inkscape: _Avanzado" + +#: ../../po/../src/verbs.cpp:2089 +msgid "Star Preferences" +msgstr "Izarretarako Hobespenak" + +#: ../../po/../src/verbs.cpp:2090 +#, fuzzy +msgid "Open Preferences for the Star tool" +msgstr "Inkscape: _Avanzado" + +#: ../../po/../src/verbs.cpp:2091 +msgid "Spiral Preferences" +msgstr "Kiribiletarako Hobespenak" + +#: ../../po/../src/verbs.cpp:2092 +#, fuzzy +msgid "Open Preferences for the Spiral tool" +msgstr "Inkscape: _Avanzado" + +#: ../../po/../src/verbs.cpp:2093 +msgid "Pencil Preferences" +msgstr "Arkatzaren Hobespenak" + +#: ../../po/../src/verbs.cpp:2094 +#, fuzzy +msgid "Open Preferences for the Pencil tool" +msgstr "Inkscape: _Avanzado" + +#: ../../po/../src/verbs.cpp:2095 +msgid "Pen Preferences" +msgstr "Lumaren Hobespenak" + +#: ../../po/../src/verbs.cpp:2096 +#, fuzzy +msgid "Open Preferences for the Pen tool" +msgstr "Inkscape: _Avanzado" + +#: ../../po/../src/verbs.cpp:2097 +msgid "Calligraphic Preferences" +msgstr "Kaligrafiaren Hobespenak" + +#: ../../po/../src/verbs.cpp:2098 +#, fuzzy +msgid "Open Preferences for the Calligraphy tool" +msgstr "Inkscape: _Avanzado" + +#: ../../po/../src/verbs.cpp:2099 +msgid "Text Preferences" +msgstr "Testurako Hobespenak" + +#: ../../po/../src/verbs.cpp:2100 +#, fuzzy +msgid "Open Preferences for the Text tool" +msgstr "Inkscape: _Avanzado" + +#: ../../po/../src/verbs.cpp:2101 +msgid "Gradient Preferences" +msgstr "Gradienteetarako Hobespenak" + +#: ../../po/../src/verbs.cpp:2102 +#, fuzzy +msgid "Open Preferences for the Gradient tool" +msgstr "Inkscape: _Avanzado" + +#: ../../po/../src/verbs.cpp:2103 +#, fuzzy +msgid "Zoom Preferences" +msgstr "Inkscape: _Avanzado" + +#: ../../po/../src/verbs.cpp:2104 +#, fuzzy +msgid "Open Preferences for the Zoom tool" +msgstr "Inkscape: _Avanzado" + +#: ../../po/../src/verbs.cpp:2105 +#, fuzzy +msgid "Dropper Preferences" +msgstr "Inkscape: _Avanzado" + +#: ../../po/../src/verbs.cpp:2106 +#, fuzzy +msgid "Open Preferences for the Dropper tool" +msgstr "Inkscape: _Avanzado" + +#: ../../po/../src/verbs.cpp:2107 +#, fuzzy +msgid "Connector Preferences" +msgstr "Izarretarako Hobespenak" + +#: ../../po/../src/verbs.cpp:2108 +#, fuzzy +msgid "Open Preferences for the Connector tool" +msgstr "Inkscape: _Avanzado" + +#. Zoom/View +#: ../../po/../src/verbs.cpp:2111 +msgid "Zoom In" +msgstr "Gerturatu" + +#: ../../po/../src/verbs.cpp:2111 +msgid "Zoom in" +msgstr "Gerturatu" + +#: ../../po/../src/verbs.cpp:2112 +msgid "Zoom Out" +msgstr "Urrundu" + +#: ../../po/../src/verbs.cpp:2112 +msgid "Zoom out" +msgstr "Urrundu" + +#: ../../po/../src/verbs.cpp:2113 +#, fuzzy +msgid "_Rulers" +msgstr "Reglas" + +#: ../../po/../src/verbs.cpp:2113 +#, fuzzy +msgid "Show or hide the canvas rulers" +msgstr "Mostrar/ocultar reglas" + +#: ../../po/../src/verbs.cpp:2114 +#, fuzzy +msgid "Scroll_bars" +msgstr "Barras de desplazamiento" + +#: ../../po/../src/verbs.cpp:2114 +#, fuzzy +msgid "Show or hide the canvas scrollbars" +msgstr "Mostrar/ocultar barras de desplazamiento" + +#: ../../po/../src/verbs.cpp:2115 +msgid "_Grid" +msgstr "_Sareta" + +#: ../../po/../src/verbs.cpp:2116 +msgid "G_uides" +msgstr "_Gidak" + +#: ../../po/../src/verbs.cpp:2117 +msgid "Nex_t Zoom" +msgstr "H_urrengo Zooma" + +#: ../../po/../src/verbs.cpp:2117 +msgid "Next zoom (from the history of zooms)" +msgstr "" + +#: ../../po/../src/verbs.cpp:2119 +msgid "Pre_vious Zoom" +msgstr "Au_rreko Zooma" + +#: ../../po/../src/verbs.cpp:2119 +msgid "Previous zoom (from the history of zooms)" +msgstr "" + +#: ../../po/../src/verbs.cpp:2121 +msgid "Zoom 1:_1" +msgstr "1:_1 Zooma" + +#: ../../po/../src/verbs.cpp:2121 +msgid "Zoom to 1:1" +msgstr "1:1 Zooma" + +#: ../../po/../src/verbs.cpp:2123 +msgid "Zoom 1:_2" +msgstr "1:_2 Zooma" + +#: ../../po/../src/verbs.cpp:2123 +msgid "Zoom to 1:2" +msgstr "1:2 Zooma" + +#: ../../po/../src/verbs.cpp:2125 +msgid "_Zoom 2:1" +msgstr "2:1 _Zooma" + +#: ../../po/../src/verbs.cpp:2125 +msgid "Zoom to 2:1" +msgstr "2:1 Zooma" + +#: ../../po/../src/verbs.cpp:2128 +msgid "_Fullscreen" +msgstr "_Osoko ikuskera" + +#: ../../po/../src/verbs.cpp:2128 +#, fuzzy +msgid "Stretch this document window to full screen" +msgstr "Cambiar a la ventana de documento anterior" + +#: ../../po/../src/verbs.cpp:2131 +#, fuzzy +msgid "Duplic_ate Window" +msgstr "Duplicar nodo" + +#: ../../po/../src/verbs.cpp:2131 +#, fuzzy +msgid "Open a new window with the same document" +msgstr "Opciones guardadas con el documento" + +#: ../../po/../src/verbs.cpp:2133 +#, fuzzy +msgid "_New View Preview" +msgstr "_Nueva vista" + +#: ../../po/../src/verbs.cpp:2134 +#, fuzzy +msgid "New View Preview" +msgstr "_Nueva vista" + +#. "view_new_preview" +#: ../../po/../src/verbs.cpp:2136 +#, fuzzy +msgid "_Normal" +msgstr "Arrunta" + +#: ../../po/../src/verbs.cpp:2137 +msgid "Switch to normal display mode" +msgstr "" + +#: ../../po/../src/verbs.cpp:2138 +#, fuzzy +msgid "_Outline" +msgstr "Mostrar el boceto" + +#: ../../po/../src/verbs.cpp:2139 +msgid "Switch to outline (wireframe) display mode" +msgstr "" + +#: ../../po/../src/verbs.cpp:2141 +#, fuzzy +msgid "Ico_n Preview" +msgstr "_Nueva vista" + +#: ../../po/../src/verbs.cpp:2142 +msgid "Open a window to preview items at different icon resolutions" +msgstr "" + +#: ../../po/../src/verbs.cpp:2144 +#, fuzzy +msgid "Zoom to fit page in window" +msgstr "Ajustar la página a la ventana" + +#: ../../po/../src/verbs.cpp:2145 +msgid "Page _Width" +msgstr "Orriaren _Zabalera" + +#: ../../po/../src/verbs.cpp:2146 +#, fuzzy +msgid "Zoom to fit page width in window" +msgstr "Ajustar la anchura de la página a la ventana" + +#: ../../po/../src/verbs.cpp:2148 +#, fuzzy +msgid "Zoom to fit drawing in window" +msgstr "Ajustar el dibujo a la ventana" + +#: ../../po/../src/verbs.cpp:2150 +#, fuzzy +msgid "Zoom to fit selection in window" +msgstr "Ajustar la selección a la ventana" + +#. Dialogs +#: ../../po/../src/verbs.cpp:2153 +msgid "In_kscape Preferences..." +msgstr "In_kscaperako Hobespenak" + +#: ../../po/../src/verbs.cpp:2154 +#, fuzzy +msgid "Global Inkscape preferences" +msgstr "Opciones globales de Inkscape" + +#: ../../po/../src/verbs.cpp:2155 +msgid "_Document Preferences..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2156 +#, fuzzy +msgid "Preferences saved with the document" +msgstr "Opciones guardadas con el documento" + +#: ../../po/../src/verbs.cpp:2157 +msgid "_Fill and Stroke..." +msgstr "_Bete eta Inguratu..." + +#: ../../po/../src/verbs.cpp:2158 +#, fuzzy +msgid "Fill and Stroke dialog" +msgstr "_Relleno y contorno" + +#. TRANSLATORS: "Swatches" means: color samples +#: ../../po/../src/verbs.cpp:2160 +#, fuzzy +msgid "S_watches..." +msgstr "G_uardar como..." + +#: ../../po/../src/verbs.cpp:2161 +msgid "View color swatches" +msgstr "" + +#: ../../po/../src/verbs.cpp:2162 +#, fuzzy +msgid "Transfor_m..." +msgstr "Transfor_mar" + +#: ../../po/../src/verbs.cpp:2163 +#, fuzzy +msgid "Transform dialog" +msgstr "Transfor_mar" + +#: ../../po/../src/verbs.cpp:2164 +#, fuzzy +msgid "_Align and Distribute..." +msgstr "_Alinear y distribuir" + +#: ../../po/../src/verbs.cpp:2165 +#, fuzzy +msgid "Align and Distribute dialog" +msgstr "_Alinear y distribuir" + +#: ../../po/../src/verbs.cpp:2166 +#, fuzzy +msgid "_Text and Font..." +msgstr "_Texto y tipografía" + +#: ../../po/../src/verbs.cpp:2167 +#, fuzzy +msgid "Text and Font dialog" +msgstr "Texto y tipografía" + +#: ../../po/../src/verbs.cpp:2168 +msgid "_XML Editor..." +msgstr "_XML Sorgailua" + +#: ../../po/../src/verbs.cpp:2169 +msgid "XML Editor" +msgstr "XML Sorgailua" + +#: ../../po/../src/verbs.cpp:2170 +msgid "_Find..." +msgstr "_Aurkitu" + +#: ../../po/../src/verbs.cpp:2171 +#, fuzzy +msgid "Find objects in document" +msgstr "Sin gradientes en el documento" + +#: ../../po/../src/verbs.cpp:2172 +msgid "_Messages..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2173 +msgid "View debug messages" +msgstr "" + +#: ../../po/../src/verbs.cpp:2174 +msgid "S_cripts..." +msgstr "S_criptak..." + +#: ../../po/../src/verbs.cpp:2175 +msgid "Run scripts" +msgstr "" + +#: ../../po/../src/verbs.cpp:2176 +#, fuzzy +msgid "Show/Hide D_ialogs" +msgstr "_Mostar/ocultar ventanas de diálogo" + +#: ../../po/../src/verbs.cpp:2177 +#, fuzzy +msgid "Show or hide all active dialogs" +msgstr "Conmutar la visibilidad de los diálogos activos" + +#. TRANSLATORS: "Tile clones" means: "Create tiled clones" +#: ../../po/../src/verbs.cpp:2179 +msgid "Tile clones..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2180 +msgid "Create and arrange multiple clones of selection" +msgstr "" + +#: ../../po/../src/verbs.cpp:2181 +#, fuzzy +msgid "_Object Properties..." +msgstr "_Propiedades del rectángulo" + +#: ../../po/../src/verbs.cpp:2182 +#, fuzzy +msgid "Object Properties dialog" +msgstr "_Propiedades del rectángulo" + +#: ../../po/../src/verbs.cpp:2185 +msgid "_Connect to Jabber server..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2185 +msgid "Connect to a Jabber server" +msgstr "" + +#: ../../po/../src/verbs.cpp:2187 +#, fuzzy +msgid "Share with _user..." +msgstr "Gorde _honela..." + +#: ../../po/../src/verbs.cpp:2187 +msgid "Establish a whiteboard session with another Jabber user" +msgstr "" + +#: ../../po/../src/verbs.cpp:2189 +msgid "Share with _chatroom..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2189 +msgid "" +"Join a chatroom to start a new whiteboard session or join one in progress" +msgstr "" + +#: ../../po/../src/verbs.cpp:2191 +msgid "_Dump XML node tracker" +msgstr "" + +#: ../../po/../src/verbs.cpp:2191 +msgid "Dump the contents of the XML tracker to the console" +msgstr "" + +#: ../../po/../src/verbs.cpp:2193 +msgid "_Open session file..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2193 +msgid "Open and browse through records of past whiteboard sessions" +msgstr "" + +#: ../../po/../src/verbs.cpp:2195 +msgid "Session file playback" +msgstr "" + +#: ../../po/../src/verbs.cpp:2197 +msgid "_Disconnect from session" +msgstr "" + +#: ../../po/../src/verbs.cpp:2199 +msgid "Disconnect from _server" +msgstr "" + +#: ../../po/../src/verbs.cpp:2201 +msgid "_Input Devices..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2202 +msgid "Configure extended input devices" +msgstr "" + +#. Help +#: ../../po/../src/verbs.cpp:2205 +msgid "_Keys and Mouse" +msgstr "_Teklatua eta sagua" + +#: ../../po/../src/verbs.cpp:2206 +msgid "Key and mouse shortcuts reference" +msgstr "" + +#: ../../po/../src/verbs.cpp:2207 +#, fuzzy +msgid "About E_xtensions" +msgstr "Expansión:" + +#: ../../po/../src/verbs.cpp:2208 +#, fuzzy +msgid "About Extensions..." +msgstr "Expansión:" + +#: ../../po/../src/verbs.cpp:2209 +#, fuzzy +msgid "About _Memory" +msgstr "Expansión:" + +#: ../../po/../src/verbs.cpp:2210 +#, fuzzy +msgid "About Memory..." +msgstr "Expansión:" + +#: ../../po/../src/verbs.cpp:2211 +msgid "_About Inkscape" +msgstr "Inkscaperen _Gainean" + +#. "help_about" +#. new HelpVerb(SP_VERB_SHOW_LICENSE, "ShowLicense", N_("Modifying or Redistributing Inkscape"), +#. N_("Show license to modify and/or redistribute Inkscape: GNU GPL"), NULL), +#. Tutorials +#: ../../po/../src/verbs.cpp:2217 +msgid "Inkscape: _Basic" +msgstr "Inkscape: _Oinarrizkoa" + +#: ../../po/../src/verbs.cpp:2218 +msgid "Getting started with Inkscape" +msgstr "" + +#. "tutorial_basic" +#: ../../po/../src/verbs.cpp:2219 +msgid "Inkscape: _Shapes" +msgstr "Inkscape: _Formak" + +#: ../../po/../src/verbs.cpp:2220 +msgid "Using shape tools to create and edit shapes" +msgstr "" + +#: ../../po/../src/verbs.cpp:2221 +msgid "Inkscape: _Advanced" +msgstr "Inkscape: _Aurreratua" + +#: ../../po/../src/verbs.cpp:2222 +#, fuzzy +msgid "Advanced Inkscape topics" +msgstr "Muestra de diapositivas Inkscape" + +#. "tutorial_advanced" +#. TRANSLATORS: "to trace" means "to convert a bitmap to vector graphics" (to vectorize) +#: ../../po/../src/verbs.cpp:2224 +msgid "Inkscape: T_racing" +msgstr "Inkscape: _Trazuak" + +#: ../../po/../src/verbs.cpp:2225 +#, fuzzy +msgid "Using bitmap tracing" +msgstr "Tamaño de mapa de bits" + +#. "tutorial_tracing" +#: ../../po/../src/verbs.cpp:2226 +msgid "Inkscape: _Calligraphy" +msgstr "Inkscape: _Kaligrafia" + +#: ../../po/../src/verbs.cpp:2227 +msgid "Using the Calligraphy pen tool" +msgstr "" + +#: ../../po/../src/verbs.cpp:2228 +msgid "_Elements of Design" +msgstr "_Diseinuaren elementuak" + +#: ../../po/../src/verbs.cpp:2229 +#, fuzzy +msgid "Principles of design in the tutorial form" +msgstr "_Elementos de diseño" + +#. "tutorial_design" +#: ../../po/../src/verbs.cpp:2230 +msgid "_Tips and Tricks" +msgstr "Trikimailuak eta _Gomendioak" + +#: ../../po/../src/verbs.cpp:2231 +#, fuzzy +msgid "Miscellaneous tips and tricks" +msgstr "_Trucos y consejos" + +#. "tutorial_tips" +#. Effect +#: ../../po/../src/verbs.cpp:2234 +#, fuzzy +msgid "Previous Effect" +msgstr "Zoom anterior" + +#: ../../po/../src/verbs.cpp:2235 +msgid "Repeat the last effect with the same settings" +msgstr "" + +#. "tutorial_tips" +#: ../../po/../src/verbs.cpp:2236 +#, fuzzy +msgid "Previous Effect Settings..." +msgstr "Zoom anterior" + +#: ../../po/../src/verbs.cpp:2237 +msgid "Repeat the last effect with new settings" +msgstr "" + +#: ../../po/../src/widgets/dash-selector.cpp:106 +#, fuzzy +msgid "Dash pattern" +msgstr "Contorno" + +#: ../../po/../src/widgets/dash-selector.cpp:121 +#, fuzzy +msgid "Pattern offset" +msgstr "Patrón:" + +#: ../../po/../src/widgets/desktop-widget.cpp:240 +msgid "Zoom drawing if window size changes" +msgstr "Egokitu marrazkira leihoaren tamaina aldatzean" + +#: ../../po/../src/widgets/desktop-widget.cpp:298 +msgid "Cursor coordinates" +msgstr "Kurtsorearen koordenatuak" + +#. display the initial welcome message in the statusbar +#: ../../po/../src/widgets/desktop-widget.cpp:324 +#, fuzzy +msgid "" +"Welcome to Inkscape! Use shape or freehand tools to create objects; " +"use selector (arrow) to move or transform them." +msgstr "" +"Bienvenido a Inkscape. Utilice las herramientas de forma o mano alzada para " +"crear objetos; utilice el selector (flecha) para moverlos o transformarlos." + +#: ../../po/../src/widgets/desktop-widget.cpp:372 +#, c-format +msgid "%s: %d - Inkscape" +msgstr "%s: %d - Inkscape" + +#: ../../po/../src/widgets/desktop-widget.cpp:374 +#, c-format +msgid "%s - Inkscape" +msgstr "%s - Inkscape" + +#: ../../po/../src/widgets/desktop-widget.cpp:532 +#, c-format +msgid "" +"Save changes to document \"%s\" before " +"closing?\n" +"\n" +"If you close without saving, your changes will be discarded." +msgstr "" +"Itxi aurretik, \"%s\" dokumentuan " +"eginiko aldaketak gorde nahi al dituzu?\n" +"\n" +"Gorde gabe ixten baduzu eginiko aldaketak galduko dira." + +#: ../../po/../src/widgets/desktop-widget.cpp:548 +#: ../../po/../src/widgets/desktop-widget.cpp:612 +msgid "Close _without saving" +msgstr "_Itxi gorde gabe" + +#: ../../po/../src/widgets/desktop-widget.cpp:595 +#, c-format +msgid "" +"The file \"%s\" was saved with a " +"format (%s) that may cause data loss!\n" +"\n" +"Do you want to save this file in another format?" +msgstr "" +"\"%s\" fitxategia informazio guztia " +"berreskura ezin daitekeen formatu batekin (%s) gorde zen.\n" +"\n" +"Fitxategia beste formatu batekin gorde nahi al duzu?" + +#. Family frame +#: ../../po/../src/widgets/font-selector.cpp:156 +msgid "Font family" +msgstr "Hizki mota" + +#. Style frame +#: ../../po/../src/widgets/font-selector.cpp:184 +msgid "Style" +msgstr "Estiloa" + +#: ../../po/../src/widgets/font-selector.cpp:219 +msgid "Font size:" +msgstr "Hizkien neurria:" + +#. TRANSLATORS: Test string used in text and font dialog (when no +#. * text has been entered) to get a preview of the font. Choose +#. * some representative characters that users of your locale will be +#. * interested in. +#: ../../po/../src/widgets/font-selector.cpp:554 +msgid "AaBbCcIiPpQq12368.;/()" +msgstr "AaBbDdIiPpRr12368.;/()" + +#: ../../po/../src/widgets/gradient-selector.cpp:137 +#: ../../po/../src/widgets/gradient-toolbar.cpp:524 +#, fuzzy +msgid "Duplicate" +msgstr "D_uplicar" + +#: ../../po/../src/widgets/gradient-selector.cpp:142 +#: ../../po/../src/widgets/gradient-toolbar.cpp:535 +#, fuzzy +msgid "Edit..." +msgstr "Editar" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/pservers.html#LinearGradientSpreadMethodAttribute +#: ../../po/../src/widgets/gradient-selector.cpp:159 +msgid "" +"Whether to fill with flat color beyond the ends of the gradient vector " +"(spreadMethod=\"pad\"), or repeat the gradient in the same direction " +"(spreadMethod=\"repeat\"), or repeat the gradient in alternating opposite " +"directions (spreadMethod=\"reflect\")" +msgstr "" + +#: ../../po/../src/widgets/gradient-selector.cpp:165 +msgid "none" +msgstr "bat ere ez" + +#: ../../po/../src/widgets/gradient-selector.cpp:169 +msgid "reflected" +msgstr "islatua" + +#: ../../po/../src/widgets/gradient-selector.cpp:173 +#, fuzzy +msgid "direct" +msgstr "Editar" + +#: ../../po/../src/widgets/gradient-selector.cpp:181 +msgid "Repeat:" +msgstr "Errepikatu:" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:217 +msgid "No gradients" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:226 +#, fuzzy +msgid "Nothing selected" +msgstr "Último seleccionado" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:237 +#, fuzzy +msgid "No gradients in selection" +msgstr "Sin gradiente seleccionado" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:247 +msgid "Multiple gradients" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:525 +msgid "" +"If the gradient is used by more than one object, create a copy of it for the " +"selected object(s)" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:536 +#, fuzzy +msgid "Edit the stops of the gradient" +msgstr "Gradiente sin paradas" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:593 +#: ../../po/../src/widgets/toolbox.cpp:1103 +#: ../../po/../src/widgets/toolbox.cpp:1192 +#: ../../po/../src/widgets/toolbox.cpp:1485 +#: ../../po/../src/widgets/toolbox.cpp:1534 +#: ../../po/../src/widgets/toolbox.cpp:1766 +#: ../../po/../src/widgets/toolbox.cpp:1801 +#: ../../po/../src/widgets/toolbox.cpp:2331 +#: ../../po/../src/widgets/toolbox.cpp:2370 +msgid "New:" +msgstr "Berria:" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:606 +#, fuzzy +msgid "Create linear gradient" +msgstr "Gradiente lineal" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:620 +msgid "Create radial (elliptic or circular) gradient" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:635 +#, fuzzy +msgid "on" +msgstr "Ninguno" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:648 +#, fuzzy +msgid "Create gradient in the fill" +msgstr "Editor de gradiente" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:662 +msgid "Create gradient in the stroke" +msgstr "" + +#. FIXME: implement averaging of all parameters for multiple selected stars +#. gtk_label_set_markup(GTK_LABEL(l), _("Average:")); +#. FIXME: implement averaging of all parameters for multiple selected +#. gtk_label_set_markup(GTK_LABEL(l), _("Average:")); +#: ../../po/../src/widgets/gradient-toolbar.cpp:676 +#: ../../po/../src/widgets/toolbox.cpp:1105 +#: ../../po/../src/widgets/toolbox.cpp:1124 +#: ../../po/../src/widgets/toolbox.cpp:1493 +#: ../../po/../src/widgets/toolbox.cpp:1518 +#: ../../po/../src/widgets/toolbox.cpp:1768 +#: ../../po/../src/widgets/toolbox.cpp:1787 +#: ../../po/../src/widgets/toolbox.cpp:2334 +#: ../../po/../src/widgets/toolbox.cpp:2354 +msgid "Change:" +msgstr "" + +#: ../../po/../src/widgets/gradient-vector.cpp:269 +msgid "No gradients in document" +msgstr "" + +#: ../../po/../src/widgets/gradient-vector.cpp:275 +msgid "No gradient selected" +msgstr "" + +#: ../../po/../src/widgets/gradient-vector.cpp:532 +msgid "No stops in gradient" +msgstr "" + +#. TRANSLATORS: "Stop" means: a "phase" of a gradient +#: ../../po/../src/widgets/gradient-vector.cpp:794 +msgid "Add stop" +msgstr "Geldiunea gehitu" + +#: ../../po/../src/widgets/gradient-vector.cpp:797 +msgid "Add another control stop to gradient" +msgstr "" + +#: ../../po/../src/widgets/gradient-vector.cpp:799 +msgid "Delete stop" +msgstr "Geldiunea kendu" + +#: ../../po/../src/widgets/gradient-vector.cpp:802 +msgid "Delete current control stop from gradient" +msgstr "" + +#. Label +#: ../../po/../src/widgets/gradient-vector.cpp:813 +msgid "Offset:" +msgstr "" + +#. TRANSLATORS: "Stop" means: a "phase" of a gradient +#: ../../po/../src/widgets/gradient-vector.cpp:858 +msgid "Stop Color" +msgstr "" + +#: ../../po/../src/widgets/gradient-vector.cpp:887 +msgid "Gradient editor" +msgstr "" + +#: ../../po/../src/widgets/layer-selector.cpp:119 +#, fuzzy +msgid "Toggle current layer visibility" +msgstr "Documento guardado." + +#: ../../po/../src/widgets/layer-selector.cpp:139 +#, fuzzy +msgid "Lock or unlock current layer" +msgstr "Documento guardado." + +#: ../../po/../src/widgets/layer-selector.cpp:142 +msgid "Current layer" +msgstr "Uneko geruza" + +#: ../../po/../src/widgets/layer-selector.cpp:553 +msgid "(root)" +msgstr "(erroa)" + +#: ../../po/../src/widgets/paint-selector.cpp:182 +#: ../../po/../src/widgets/paint-selector.cpp:561 +msgid "No paint" +msgstr "Margo gabe" + +#: ../../po/../src/widgets/paint-selector.cpp:184 +#: ../../po/../src/widgets/paint-selector.cpp:629 +#, fuzzy +msgid "Flat color" +msgstr "Color del resaltado:" + +#: ../../po/../src/widgets/paint-selector.cpp:186 +#: ../../po/../src/widgets/paint-selector.cpp:696 +msgid "Linear gradient" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:188 +#: ../../po/../src/widgets/paint-selector.cpp:699 +msgid "Radial gradient" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:192 +msgid "Unset paint (make it undefined so it can be inherited)" +msgstr "" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/painting.html#FillRuleProperty +#: ../../po/../src/widgets/paint-selector.cpp:204 +msgid "" +"Any path self-intersections or subpaths create holes in the fill (fill-rule: " +"evenodd)" +msgstr "" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/painting.html#FillRuleProperty +#: ../../po/../src/widgets/paint-selector.cpp:215 +msgid "" +"Fill is solid unless a subpath is counterdirectional (fill-rule: nonzero)" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:528 +msgid "No objects" +msgstr "Objektu gabe" + +#: ../../po/../src/widgets/paint-selector.cpp:539 +msgid "Multiple styles" +msgstr "Estilo anitzak" + +#: ../../po/../src/widgets/paint-selector.cpp:550 +msgid "Paint is undefined" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:757 +msgid "No patterns in document" +msgstr "Dokumentuan ez dago eredurik" + +#: ../../po/../src/widgets/paint-selector.cpp:872 +msgid "" +"Use Edit > Object(s) to Pattern to create a new pattern from " +"selection." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:426 +msgid "Now stroke width is scaled when objects are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:428 +msgid "Now stroke width is not scaled when objects are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:436 +msgid "" +"Now rounded rectangle corners are scaled when rectangles are " +"scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:438 +msgid "" +"Now rounded rectangle corners are not scaled when rectangles " +"are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:446 +msgid "" +"Now gradients are transformed along with their objects when " +"those are transformed (moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:448 +msgid "" +"Now gradients remain fixed when objects are transformed " +"(moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:456 +msgid "" +"Now patterns are transformed along with their objects when " +"those are transformed (moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:458 +msgid "" +"Now patterns remain fixed when objects are transformed (moved, " +"scaled, rotated, or skewed)." +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:506 +#, fuzzy +msgid "select_toolbar|X" +msgstr "Seleccionar" + +#: ../../po/../src/widgets/select-toolbar.cpp:506 +msgid "Horizontal coordinate of selection" +msgstr "Coordenada horizontal de la selección" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:511 +#, fuzzy +msgid "select_toolbar|Y" +msgstr "Seleccionar" + +#: ../../po/../src/widgets/select-toolbar.cpp:511 +msgid "Vertical coordinate of selection" +msgstr "Coordenada vertical de la selección" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:517 +#, fuzzy +msgid "select_toolbar|W" +msgstr "Seleccionar" + +#: ../../po/../src/widgets/select-toolbar.cpp:517 +msgid "Width of selection" +msgstr "Ancho de la selección" + +#: ../../po/../src/widgets/select-toolbar.cpp:525 +msgid "Change both width and height by the same proportion" +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:534 +#, fuzzy +msgid "select_toolbar|H" +msgstr "Seleccionar" + +#: ../../po/../src/widgets/select-toolbar.cpp:534 +msgid "Height of selection" +msgstr "Altura de la selección" + +#: ../../po/../src/widgets/sp-color-gtkselector.cpp:62 +msgid "System" +msgstr "Sistema" + +#: ../../po/../src/widgets/sp-color-notebook.cpp:322 +msgid "RGBA_:" +msgstr "RGBA_:" + +#: ../../po/../src/widgets/sp-color-notebook.cpp:330 +msgid "Hexadecimal RGBA value of the color" +msgstr "Kolorearen RGBA balio hamaseitarra" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "RGB" +msgstr "RGB" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "HSL" +msgstr "HSL" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "CMYK" +msgstr "CMYK" + +#: ../../po/../src/widgets/sp-color-scales.cpp:397 +msgid "_R" +msgstr "_R" + +#: ../../po/../src/widgets/sp-color-scales.cpp:398 +#: ../../po/../src/widgets/sp-color-scales.cpp:399 +msgid "Red" +msgstr "Gorria" + +#: ../../po/../src/widgets/sp-color-scales.cpp:400 +msgid "_G" +msgstr "_G" + +#: ../../po/../src/widgets/sp-color-scales.cpp:401 +#: ../../po/../src/widgets/sp-color-scales.cpp:402 +msgid "Green" +msgstr "Berdea" + +#: ../../po/../src/widgets/sp-color-scales.cpp:403 +msgid "_B" +msgstr "_B" + +#: ../../po/../src/widgets/sp-color-scales.cpp:404 +#: ../../po/../src/widgets/sp-color-scales.cpp:405 +msgid "Blue" +msgstr "Urdina" + +#. Label +#: ../../po/../src/widgets/sp-color-scales.cpp:406 +#: ../../po/../src/widgets/sp-color-scales.cpp:432 +#: ../../po/../src/widgets/sp-color-scales.cpp:463 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:141 +msgid "_A" +msgstr "_A" + +#: ../../po/../src/widgets/sp-color-scales.cpp:407 +#: ../../po/../src/widgets/sp-color-scales.cpp:408 +#: ../../po/../src/widgets/sp-color-scales.cpp:433 +#: ../../po/../src/widgets/sp-color-scales.cpp:434 +#: ../../po/../src/widgets/sp-color-scales.cpp:464 +#: ../../po/../src/widgets/sp-color-scales.cpp:465 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:151 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:163 +msgid "Alpha (opacity)" +msgstr "Alfa (opakutasuna)" + +#: ../../po/../src/widgets/sp-color-scales.cpp:423 +msgid "_H" +msgstr "_H" + +#: ../../po/../src/widgets/sp-color-scales.cpp:424 +#: ../../po/../src/widgets/sp-color-scales.cpp:425 +msgid "Hue" +msgstr "Tonua" + +#: ../../po/../src/widgets/sp-color-scales.cpp:426 +msgid "_S" +msgstr "_S" + +#: ../../po/../src/widgets/sp-color-scales.cpp:427 +#: ../../po/../src/widgets/sp-color-scales.cpp:428 +msgid "Saturation" +msgstr "Asetasuna" + +#: ../../po/../src/widgets/sp-color-scales.cpp:429 +msgid "_L" +msgstr "_L" + +#: ../../po/../src/widgets/sp-color-scales.cpp:430 +#: ../../po/../src/widgets/sp-color-scales.cpp:431 +msgid "Lightness" +msgstr "Argitasuna" + +#: ../../po/../src/widgets/sp-color-scales.cpp:451 +msgid "_C" +msgstr "_C" + +#: ../../po/../src/widgets/sp-color-scales.cpp:452 +#: ../../po/../src/widgets/sp-color-scales.cpp:453 +msgid "Cyan" +msgstr "Cyan" + +#: ../../po/../src/widgets/sp-color-scales.cpp:454 +msgid "_M" +msgstr "_M" + +#: ../../po/../src/widgets/sp-color-scales.cpp:455 +#: ../../po/../src/widgets/sp-color-scales.cpp:456 +msgid "Magenta" +msgstr "Magenta" + +#: ../../po/../src/widgets/sp-color-scales.cpp:457 +msgid "_Y" +msgstr "_Y" + +#: ../../po/../src/widgets/sp-color-scales.cpp:458 +#: ../../po/../src/widgets/sp-color-scales.cpp:459 +msgid "Yellow" +msgstr "Horia" + +#: ../../po/../src/widgets/sp-color-scales.cpp:460 +msgid "_K" +msgstr "_K" + +#: ../../po/../src/widgets/sp-color-selector.cpp:71 +msgid "Unnamed" +msgstr "Izengabea" + +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:68 +msgid "Wheel" +msgstr "Gurpila" + +#: ../../po/../src/widgets/sp-xmlview-attr-list.cpp:53 +msgid "Attribute" +msgstr "Atributua" + +#: ../../po/../src/widgets/sp-xmlview-attr-list.cpp:54 +msgid "Value" +msgstr "Balioa" + +#: ../../po/../src/widgets/toolbox.cpp:424 +msgid "Insert new nodes into selected segments" +msgstr "Insertar los nuevos nodos entre los segmentos seleccionados" + +#: ../../po/../src/widgets/toolbox.cpp:426 +msgid "Delete selected nodes" +msgstr "Suprimir los nodos seleccionados" + +#: ../../po/../src/widgets/toolbox.cpp:431 +msgid "Join paths at selected nodes" +msgstr "Unir los trazos en los nodos seleccionados." + +#: ../../po/../src/widgets/toolbox.cpp:433 +msgid "Join paths at selected nodes with new segment" +msgstr "Unir los trazos en los nodos seleccionados con un segmento nuevo" + +#: ../../po/../src/widgets/toolbox.cpp:436 +msgid "Split path between two non-endpoint nodes" +msgstr "Separar el trazo entre dos nodos." + +#: ../../po/../src/widgets/toolbox.cpp:439 +msgid "Break path at selected nodes" +msgstr "Romper el trazo en los nodos seleccionados" + +#: ../../po/../src/widgets/toolbox.cpp:444 +msgid "Make selected nodes corner" +msgstr "Convertir en esquina los nodos seleccionados" + +#: ../../po/../src/widgets/toolbox.cpp:447 +msgid "Make selected nodes smooth" +msgstr "Suavizar los nodos seleccionados" + +#: ../../po/../src/widgets/toolbox.cpp:450 +msgid "Make selected nodes symmetric" +msgstr "Hacer simétricos los nodos seleccionados." + +#: ../../po/../src/widgets/toolbox.cpp:455 +msgid "Make selected segments lines" +msgstr "Convertir los segmentos seleccionados en líneas" + +#: ../../po/../src/widgets/toolbox.cpp:458 +msgid "Make selected segments curves" +msgstr "Convertir los segmentos seleccionados a curvas" + +#: ../../po/../src/widgets/toolbox.cpp:1199 +msgid "Polygon" +msgstr "Poligonoa" + +#: ../../po/../src/widgets/toolbox.cpp:1206 +#, fuzzy +msgid "Regular polygon (with one handle) instead of a star" +msgstr "Crear polígonos en vez de estrellas" + +#: ../../po/../src/widgets/toolbox.cpp:1218 +msgid "Corners:" +msgstr "Erpinak:" + +#: ../../po/../src/widgets/toolbox.cpp:1218 +msgid "Number of corners of a polygon or star" +msgstr "Número de esquinas de un polígono o estrella" + +#: ../../po/../src/widgets/toolbox.cpp:1228 +#, fuzzy +msgid "Spoke ratio:" +msgstr "Proporción:" + +#. TRANSLATORS: Tip radius of a star is the distance from the center to the farthest handle. +#. Base radius is the same for the closest handle. +#: ../../po/../src/widgets/toolbox.cpp:1231 +msgid "Base radius to tip radius ratio" +msgstr "Relación entre el radio base y el radio de la punta" + +#: ../../po/../src/widgets/toolbox.cpp:1246 +#, fuzzy +msgid "Rounded:" +msgstr "No redondeado" + +#: ../../po/../src/widgets/toolbox.cpp:1246 +msgid "How much rounded are the corners (0 for sharp)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1256 +msgid "Randomized:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1256 +msgid "Scatter randomly the corners and angles" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1269 +#: ../../po/../src/widgets/toolbox.cpp:1838 +#: ../../po/../src/widgets/toolbox.cpp:2061 +msgid "Defaults" +msgstr "Predeterminados" + +#: ../../po/../src/widgets/toolbox.cpp:1270 +#: ../../po/../src/widgets/toolbox.cpp:1839 +#: ../../po/../src/widgets/toolbox.cpp:2062 +msgid "" +"Reset shape parameters to defaults (use Inkscape Preferences > Tools to " +"change defaults)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1544 +msgid "W:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1544 +#, fuzzy +msgid "Width of rectangle" +msgstr "Ancho de la selección" + +#: ../../po/../src/widgets/toolbox.cpp:1556 +#, fuzzy +msgid "Height of rectangle" +msgstr "Altura de la selección" + +#: ../../po/../src/widgets/toolbox.cpp:1568 +msgid "Rx:" +msgstr "Rx:" + +#: ../../po/../src/widgets/toolbox.cpp:1568 +#, fuzzy +msgid "Horizontal radius of rounded corners" +msgstr "Coordenada horizontal de la selección" + +#: ../../po/../src/widgets/toolbox.cpp:1578 +msgid "Ry:" +msgstr "Ry:" + +#: ../../po/../src/widgets/toolbox.cpp:1578 +#, fuzzy +msgid "Vertical radius of rounded corners" +msgstr "Coordenada vertical de la selección" + +#: ../../po/../src/widgets/toolbox.cpp:1594 +msgid "Not rounded" +msgstr "No redondeado" + +#: ../../po/../src/widgets/toolbox.cpp:1596 +msgid "Make corners sharp" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1805 +msgid "Turns:" +msgstr "Birak:" + +#: ../../po/../src/widgets/toolbox.cpp:1805 +msgid "Number of revolutions" +msgstr "Número de revoluciones" + +#: ../../po/../src/widgets/toolbox.cpp:1815 +msgid "Divergence:" +msgstr "Divergencia:" + +#: ../../po/../src/widgets/toolbox.cpp:1815 +msgid "How much denser/sparser are outer revolutions; 1 = uniform" +msgstr "" +"Cuánto más densas/difusas son las revoluciones exteriores; 1 = uniforme " + +#: ../../po/../src/widgets/toolbox.cpp:1825 +msgid "Inner radius:" +msgstr "Barne erradioa:" + +#: ../../po/../src/widgets/toolbox.cpp:1825 +#, fuzzy +msgid "Radius of the innermost revolution (relative to the spiral size)" +msgstr "Radio de la revolución más interior" + +#: ../../po/../src/widgets/toolbox.cpp:1957 +msgid "The width of the calligraphic pen (relative to the visible canvas area)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1967 +msgid "Thinning:" +msgstr "Mehetzea:" + +#: ../../po/../src/widgets/toolbox.cpp:1967 +msgid "" +"How much velocity thins the stroke (> 0 makes fast strokes thinner, < 0 " +"makes them broader, 0 makes width independent of velocity)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1980 +msgid "Angle:" +msgstr "Angelua:" + +#: ../../po/../src/widgets/toolbox.cpp:1980 +msgid "" +"The angle of the pen's nib (in degrees; 0 = horizontal; has no effect if " +"fixation = 0)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1990 +#, fuzzy +msgid "Fixation:" +msgstr "Orientación:" + +#: ../../po/../src/widgets/toolbox.cpp:1990 +msgid "" +"How fixed is the pen angle (0 = always perpendicular to stroke direction, 1 " +"= fixed)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2003 +msgid "Mass:" +msgstr "Masa:" + +#: ../../po/../src/widgets/toolbox.cpp:2003 +msgid "How much inertia affects the movement of the pen" +msgstr "" + +#. TRANSLATORS: "drag" means "resistance" here +#: ../../po/../src/widgets/toolbox.cpp:2014 +msgid "Drag:" +msgstr "Arrastea:" + +#: ../../po/../src/widgets/toolbox.cpp:2014 +msgid "How much resistance affects the movement of the pen" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2034 +msgid "Use the pressure of the input device to alter the width of the pen" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2047 +msgid "Use the tilt of the input device to alter the angle of the pen's nib" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2374 +msgid "Start:" +msgstr "Hasiera:" + +#: ../../po/../src/widgets/toolbox.cpp:2374 +msgid "The angle (in degrees) from the horizontal to the arc's start point" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2384 +msgid "End:" +msgstr "Amaiera:" + +#: ../../po/../src/widgets/toolbox.cpp:2384 +msgid "The angle (in degrees) from the horizontal to the arc's end point" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2395 +#, fuzzy +msgid "Open arc" +msgstr "Abrir _reciente" + +#: ../../po/../src/widgets/toolbox.cpp:2396 +msgid "" +"Switch between arc (unclosed shape) and segment (closed shape with two radii)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2415 +msgid "Make whole" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2417 +msgid "Make the shape a whole ellipse, not arc or segment" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2644 +msgid "" +"When pressed, picks visible color without alpha and when not pressed, picks " +"color including its alpha" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:3039 +#, fuzzy +msgid "Make connectors avoid selected objects" +msgstr "Intersección de objetos seleccionados" + +#: ../../po/../src/widgets/toolbox.cpp:3043 +#, fuzzy +msgid "Make connectors ignore selected objects" +msgstr "Suprimir los nodos seleccionados" + +#. +#. 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 : +#: ../share/extensions/addnodes.inx.h:1 +#, fuzzy +msgid "Add Nodes" +msgstr "Ninguno" + +#: ../share/extensions/addnodes.inx.h:2 +msgid "Maximum Segment Length" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:1 +#, fuzzy +msgid "AI Input" +msgstr "Entrada" + +#: ../share/extensions/ai_input.inx.h:2 ../share/extensions/ai_output.inx.h:2 +msgid "Adobe Illustrator (*.ai)" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:3 +msgid "Open files saved with Adobe Illustrator" +msgstr "" + +#: ../share/extensions/ai_output.inx.h:1 +#, fuzzy +msgid "AI Output" +msgstr "A_mpliar" + +#: ../share/extensions/ai_output.inx.h:3 +#, fuzzy +msgid "Write Adobe Illustrator" +msgstr "Ilustrador vectorial SVG" + +#: ../share/extensions/dia.inx.h:1 +msgid "A diagram created with the program Dia" +msgstr "" + +#: ../share/extensions/dia.inx.h:2 +msgid "Dia Diagram (*.dia)" +msgstr "" + +#: ../share/extensions/dia.inx.h:3 +#, fuzzy +msgid "Dia Input" +msgstr "Entrada" + +#: ../share/extensions/dia.inx.h:4 +msgid "" +"In order to import Dia files, Dia itself must be installed. You can get Dia " +"at http://www.gnome.org/projects/dia/" +msgstr "" + +#: ../share/extensions/dia.inx.h:5 +msgid "" +"The dia2svg.sh script should be installed with your Inkscape distribution. " +"If you do not have it, there is likely to be something wrong with your " +"Inkscape installation." +msgstr "" + +#: ../share/extensions/dots.inx.h:1 +#, fuzzy +msgid "Connect the Dots" +msgstr "Esquinas:" + +#: ../share/extensions/dots.inx.h:2 +#, fuzzy +msgid "Dot Size" +msgstr "Neurria" + +#: ../share/extensions/dots.inx.h:3 +#, fuzzy +msgid "Font Size" +msgstr "Hizkien neurria:" + +#: ../share/extensions/dropshadow.inx.h:1 +msgid "Color of shadow" +msgstr "" + +#: ../share/extensions/dropshadow.inx.h:2 +msgid "Dropshadow" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:1 +#: ../share/extensions/dxf_output.inx.h:1 +msgid "AutoCAD DXF (*.dxf)" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:2 +#, fuzzy +msgid "DXF Input" +msgstr "Entrada" + +#: ../share/extensions/dxf_input.inx.h:3 +msgid "Import AutoCAD's Document Exchange Format" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:4 +msgid "" +"dxf2svg may come with Inkscape, but is also at http://dxf-svg-convert." +"sourceforge.net/" +msgstr "" + +#: ../share/extensions/dxf_output.inx.h:2 +#, fuzzy +msgid "DXF Output" +msgstr "A_mpliar" + +#: ../share/extensions/dxf_output.inx.h:3 +msgid "DXF file written by pstoedit" +msgstr "" + +#: ../share/extensions/dxf_output.inx.h:4 +msgid "pstoedit must be installed to run see http://www.pstoedit.net/pstoedit" +msgstr "" + +#: ../share/extensions/embedimage.inx.h:1 +#, fuzzy +msgid "Embed Images" +msgstr "URI de la imagen:" + +#: ../share/extensions/eps_input.inx.h:1 +#, fuzzy +msgid "EPS Input" +msgstr "Entrada" + +#: ../share/extensions/eps_input.inx.h:2 +msgid "Encapsulated Postscript" +msgstr "" + +#: ../share/extensions/eps_input.inx.h:3 +msgid "Encapsulated Postscript (*.eps)" +msgstr "" + +#: ../share/extensions/epsi_output.inx.h:1 +#, fuzzy +msgid "EPSI Output" +msgstr "A_mpliar" + +#: ../share/extensions/epsi_output.inx.h:2 +msgid "Encapsulated Postscript Interchange (*.epsi)" +msgstr "" + +#: ../share/extensions/epsi_output.inx.h:3 +msgid "Encapsulated Postscript with a thumbnail" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:1 ../share/extensions/ffms.inx.h:1 +#: ../share/extensions/ffset.inx.h:1 ../share/extensions/ffss.inx.h:1 +#, fuzzy +msgid "Bridge Width" +msgstr "An_cho de página" + +#: ../share/extensions/ffmet.inx.h:2 ../share/extensions/ffms.inx.h:2 +msgid "First String Length" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:3 +msgid "FretFind Multi Length ET" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:4 ../share/extensions/ffms.inx.h:4 +#: ../share/extensions/ffset.inx.h:3 ../share/extensions/ffss.inx.h:3 +msgid "Fretboard Edges" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:5 ../share/extensions/ffms.inx.h:5 +msgid "Last String Length" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:6 ../share/extensions/ffms.inx.h:6 +#: ../share/extensions/ffset.inx.h:4 ../share/extensions/ffss.inx.h:4 +#, fuzzy +msgid "Number of Frets" +msgstr "Número de revoluciones" + +#: ../share/extensions/ffmet.inx.h:7 ../share/extensions/ffms.inx.h:7 +#: ../share/extensions/ffset.inx.h:5 ../share/extensions/ffss.inx.h:5 +#, fuzzy +msgid "Number of Strings" +msgstr "Número de revoluciones" + +#: ../share/extensions/ffmet.inx.h:8 ../share/extensions/ffms.inx.h:8 +#: ../share/extensions/ffset.inx.h:6 ../share/extensions/ffss.inx.h:6 +#, fuzzy +msgid "Nut Width" +msgstr "Zabalera" + +#: ../share/extensions/ffmet.inx.h:9 ../share/extensions/ffms.inx.h:10 +msgid "Perpendicular Distance" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:10 ../share/extensions/ffset.inx.h:7 +msgid "Scale Base (2 for Octave)" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:11 ../share/extensions/ffset.inx.h:9 +msgid "Tones in Scale" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:12 ../share/extensions/ffms.inx.h:12 +#: ../share/extensions/ffset.inx.h:10 ../share/extensions/ffss.inx.h:10 +msgid "px per Unit" +msgstr "" + +#: ../share/extensions/ffms.inx.h:3 +msgid "FretFind Multi Length Scala" +msgstr "" + +#: ../share/extensions/ffms.inx.h:9 ../share/extensions/ffss.inx.h:7 +msgid "Path to Scala *.scl File" +msgstr "" + +#: ../share/extensions/ffms.inx.h:11 +msgid "Tuning (scale step for each string seperated by semicolons)" +msgstr "" + +#: ../share/extensions/ffset.inx.h:2 +msgid "FretFind Single Length ET" +msgstr "" + +#: ../share/extensions/ffset.inx.h:8 ../share/extensions/ffss.inx.h:8 +msgid "Scale Length" +msgstr "" + +#: ../share/extensions/ffss.inx.h:2 +msgid "FretFind Single Length Scala" +msgstr "" + +#: ../share/extensions/ffss.inx.h:9 +msgid "Tuning (Scale step for each string seperated by semicolons)" +msgstr "" + +#: ../share/extensions/handles.inx.h:1 +#, fuzzy +msgid "Draw Handles" +msgstr "Esku hutsezko marrazketa" + +#: ../share/extensions/interp.inx.h:1 +#, fuzzy +msgid "Duplicate Endpaths" +msgstr "Duplicar nodo" + +#: ../share/extensions/interp.inx.h:2 +#, fuzzy +msgid "Exponent" +msgstr "Exportar" + +#: ../share/extensions/interp.inx.h:3 +msgid "Interpolate" +msgstr "" + +#: ../share/extensions/interp.inx.h:4 +msgid "Interpolate Style (Experimental)" +msgstr "" + +#: ../share/extensions/interp.inx.h:5 +msgid "Interpolation Method" +msgstr "" + +#: ../share/extensions/interp.inx.h:6 +msgid "Interpolation Steps" +msgstr "" + +#: ../share/extensions/kochify.inx.h:1 +msgid "Kochify" +msgstr "" + +#: ../share/extensions/kochify_load.inx.h:1 +msgid "Kochify (Load)" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:1 +#, fuzzy +msgid "Angle" +msgstr "Angelua:" + +#: ../share/extensions/lindenmayer.inx.h:2 +msgid "Axiom" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:3 +#, fuzzy +msgid "Lindenmayer" +msgstr "Elevar nodo" + +#: ../share/extensions/lindenmayer.inx.h:4 +msgid "Order" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:5 +#, fuzzy +msgid "Rules" +msgstr "Reglas" + +#: ../share/extensions/lindenmayer.inx.h:6 +#, fuzzy +msgid "Step" +msgstr "Estilo" + +#: ../share/extensions/motion.inx.h:1 +#, fuzzy +msgid "Direction" +msgstr "Selección" + +#: ../share/extensions/motion.inx.h:2 +#, fuzzy +msgid "Magnitude" +msgstr "Magenta" + +#: ../share/extensions/motion.inx.h:3 +#, fuzzy +msgid "Motion" +msgstr "_Biraketa" + +#: ../share/extensions/pdf_output.inx.h:1 +msgid "Adobe PDF (*.pdf)" +msgstr "" + +#: ../share/extensions/pdf_output.inx.h:2 +msgid "Adobe Portable Document Format" +msgstr "" + +#: ../share/extensions/pdf_output.inx.h:3 +#, fuzzy +msgid "PDF Output" +msgstr "A_mpliar" + +#: ../share/extensions/ps_input.inx.h:1 +#, fuzzy +msgid "Postscript" +msgstr "Erretratua" + +#: ../share/extensions/ps_input.inx.h:2 +msgid "Postscript (*.ps)" +msgstr "" + +#: ../share/extensions/ps_input.inx.h:3 +msgid "Postscript Input" +msgstr "" + +#: ../share/extensions/radiusrand.inx.h:1 +#, fuzzy +msgid "Radius" +msgstr "Radio:" + +#: ../share/extensions/radiusrand.inx.h:2 +#, fuzzy +msgid "Radius Randomize" +msgstr "Elevar nodo" + +#: ../share/extensions/radiusrand.inx.h:3 +msgid "Randomize Control Points" +msgstr "" + +#: ../share/extensions/radiusrand.inx.h:4 +#, fuzzy +msgid "Randomize Nodes" +msgstr "Elevar nodo" + +#: ../share/extensions/rtree.inx.h:1 +#, fuzzy +msgid "Initial Size" +msgstr "Bit maparen neurria" + +#: ../share/extensions/rtree.inx.h:2 +msgid "Minimum Size" +msgstr "" + +#: ../share/extensions/rtree.inx.h:3 +msgid "Random Tree" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:1 +msgid "A diagram created with the program Sketch" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:2 +msgid "Sketch Diagram (*.sk)" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:3 +msgid "Sketch Input" +msgstr "" + +#: ../share/extensions/straightseg.inx.h:1 +msgid "Behavior" +msgstr "" + +#: ../share/extensions/straightseg.inx.h:3 +msgid "Segment Straightener" +msgstr "" + +#: ../share/extensions/summersnight.inx.h:1 +msgid "Summer's Night" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:1 +#: ../share/extensions/svgz_output.inx.h:1 +msgid "Compressed Inkscape SVG (*.svgz)" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:2 +#: ../share/extensions/svgz_output.inx.h:2 +msgid "Inkscape's native file format compressed with GZip" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:3 +#, fuzzy +msgid "SVGZ Input" +msgstr "Entrada" + +#: ../share/extensions/svgz_output.inx.h:3 +#, fuzzy +msgid "SVGZ Output" +msgstr "A_mpliar" + +#: ../share/extensions/txt2svg.inx.h:1 +msgid "ASCII Text" +msgstr "" + +#: ../share/extensions/txt2svg.inx.h:2 +msgid "Text File (*.txt)" +msgstr "" + +#: ../share/extensions/txt2svg.inx.h:3 +#, fuzzy +msgid "Text Input" +msgstr "Entrada" + +#: ../share/extensions/wavy.inx.h:1 +msgid "Calculate first derivative numerically" +msgstr "" + +#: ../share/extensions/wavy.inx.h:2 +msgid "First derivative" +msgstr "" + +#: ../share/extensions/wavy.inx.h:3 +msgid "Function" +msgstr "" + +#: ../share/extensions/wavy.inx.h:4 +msgid "Function Plotter" +msgstr "" + +#: ../share/extensions/wavy.inx.h:5 +msgid "Nodes per period" +msgstr "" + +#: ../share/extensions/wavy.inx.h:6 +msgid "Periods (2*Pi each)" +msgstr "" + +#: ../share/extensions/whirl.inx.h:1 +msgid "Amount of Whirl" +msgstr "" + +#: ../share/extensions/whirl.inx.h:2 +#, fuzzy +msgid "Center X" +msgstr "Centro X:" + +#: ../share/extensions/whirl.inx.h:3 +#, fuzzy +msgid "Center Y" +msgstr "Centro Y:" + +#: ../share/extensions/whirl.inx.h:4 +#, fuzzy +msgid "Direction of Rotation" +msgstr "Bajar la selección al fondo" + +#: ../share/extensions/whirl.inx.h:5 +msgid "Whirl" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:1 +msgid "A popular graphics file format for clipart" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:2 +msgid "Windows Metafile (*.wmf)" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:3 +msgid "Windows Metafile Input" +msgstr "" + +#~ msgid "Canvas size:" +#~ msgstr "Oihalaren neurria:" + +#, fuzzy +#~ msgid "Custom canvas" +#~ msgstr "Personalizar papel" + +#~ msgid "Current style" +#~ msgstr "Uneko estiloa" + +#, fuzzy +#~ msgid "Arrange Objects" +#~ msgstr "Objeto" + +#~ msgid "deg" +#~ msgstr "gradu" + +#, fuzzy +#~ msgid "" +#~ "%s is not a valid preferences file.\n" +#~ "%s" +#~ msgstr "" +#~ "%s no es un archivo de preferencias válido.\n" +#~ "%s" + +#~ msgid "" +#~ "Inkscape will run with default settings.\n" +#~ "New settings will not be saved." +#~ msgstr "" +#~ "Inkscape se ejecutará con la configuración predeterminada.\n" +#~ "No se guardarán ajustes nuevos." + +#, fuzzy +#~ msgid "_Credits" +#~ msgstr "Kredituak" + +#, fuzzy +#~ msgid "Grab sensitivity" +#~ msgstr "Definir como s_ensible" + +#, fuzzy +#~ msgid "Scroll by" +#~ msgstr "Barras de desplazamiento" + +#, fuzzy +#~ msgid "Acceleration" +#~ msgstr "Selección" + +#~ msgid "Speed" +#~ msgstr "Abiadura" + +#, fuzzy +#~ msgid "Zoom in/out by" +#~ msgstr "Alejar" + +#, fuzzy +#~ msgid "Transform" +#~ msgstr "Transfor_mar" + +#~ msgid "Rotate _90 deg CW" +#~ msgstr "Biratu _90 gradu eskubira" + +#~ msgid "Rotate 9_0 deg CCW" +#~ msgstr "Biratu 9_0 gradu ezkerrera" + +#~ msgid "Flip selection horizontally" +#~ msgstr "Reflejar los objetos seleccionados horizontalmente" + +#~ msgid "Flip selection vertically" +#~ msgstr "Reflejar los objetos seleccionados verticalmente" + +#, fuzzy +#~ msgid "Click to pick fill color, Shift+click to pick stroke color. " +#~ "Drag to pick the average color of an area." +#~ msgstr "" +#~ "Haga clic para seleccionar un color, clic y arrastre para seleccionar la " +#~ "media de color de un área." + +#, fuzzy +#~ msgid "Skew: %0.2f%% x %0.2f%%" +#~ msgstr "Inclinar %0.2f%c %0.2f%c" + +#~ msgid "elementsofdesign.svg" +#~ msgstr "elementsofdesign.svg" + +#~ msgid "tipsandtricks.svg" +#~ msgstr "tipsandtricks.svg" + +#, fuzzy +#~ msgid "Inkscape" +#~ msgstr "Inkscape" + +#~ msgid "Left side of aligned objects to left side of anchor" +#~ msgstr "Lado izquierdo de los objetos alineados la izquierda del ancla" + +#~ msgid "Right side of aligned objects to right side of anchor" +#~ msgstr "Lado derecho de los objetos alineados a la derecha del ancla" + +#~ msgid "Top of aligned objects to top of anchor" +#~ msgstr "Lado superior de los objetos alineados por encima del ancla" + +#~ msgid "Bottom of aligned objects to bottom of anchor" +#~ msgstr "Lado inferior de los objetos alineados por debajo del ancla" + +#~ msgid "Distribute top sides of objects at even distances" +#~ msgstr "Distribuir el lado superior de los objetos a la misma distancia" + +#, fuzzy +#~ msgid "Alternate sign" +#~ msgstr "Saturación:" + +#, fuzzy +#~ msgid "Minor grid line color:" +#~ msgstr "Color de las líneas guía" + +#~ msgid "Grid color" +#~ msgstr "Color de la rejilla" + +#, fuzzy +#~ msgid "Grid emphasis color" +#~ msgstr "Color de la rejilla" + +#, fuzzy +#~ msgid "Background (also for export):" +#~ msgstr "Fondo (también para exportación):" + +#, fuzzy +#~ msgid "Picking colors:" +#~ msgstr "Color del resaltado:" + +#~ msgid "Fill style" +#~ msgstr "Estilo de relleno" + +#, fuzzy +#~ msgid "Fill:" +#~ msgstr "Relleno" + +#, fuzzy +#~ msgid "winding" +#~ msgstr "Renderizado" + +#, fuzzy +#~ msgid "alternating" +#~ msgstr "Saturación:" + +#, fuzzy +#~ msgid "Update Properties" +#~ msgstr "_Propiedades del elemento" + +#, fuzzy +#~ msgid "Label invalid" +#~ msgstr "El ID no es válido" + +#, fuzzy +#~ msgid "" +#~ "You cannot group objects from different groups or layers." +#~ msgstr "No puede agrupar objetos de diferentes grupos o capas." + +#, fuzzy +#~ msgid "Switch to the previous layer in the document" +#~ msgstr "Cambiar a la ventana de documento anterior" + +#, fuzzy +#~ msgid "executable" +#~ msgstr "Rectángulo" + +#, fuzzy +#~ msgid "file" +#~ msgstr "_Archivo" + +#, fuzzy +#~ msgid "extension" +#~ msgstr "Expansión:" + +#, fuzzy +#~ msgid "path" +#~ msgstr "T_razo" + +#, fuzzy +#~ msgid "absolute" +#~ msgstr "Valor" + +#~ msgid "Could not create sodipodi-svg-doc factory" +#~ msgstr "No se ha podido crear un documento de la fábrica sodipodi-svg-doc" + +#~ msgid "Autodetect" +#~ msgstr "Autodetectar" + +#~ msgid "Make s_ensitive" +#~ msgstr "Definir como s_ensible" + +#~ msgid "Make i_nsensitive" +#~ msgstr "Definir como i_nsensible" + +#, fuzzy +#~ msgid "Layer Properties" +#~ msgstr "_Propiedades de la estrella" + +#, fuzzy +#~ msgid "Select object(s) to tile." +#~ msgstr "Seleccione objetos para bajar." + +#, fuzzy +#~ msgid "Apply" +#~ msgstr "Aplicar a:" + +#~ msgid "Sensitive" +#~ msgstr "Sensible" + +#~ msgid "Active" +#~ msgstr "Activo" + +#~ msgid "Printable" +#~ msgstr "Imprimible" + +#, fuzzy +#~ msgid "Prefer bitmap (XPM) icons to SVG ones" +#~ msgstr "Preferir iconos de mapa de bits (XPM) a los SVG" + +#~ msgid "Trace" +#~ msgstr "Traza" + +#, fuzzy +#~ msgid "Error writing %s: %s" +#~ msgstr "Ha ocurrido un error al escribir %s: %s" + +#~ msgid "Untitled" +#~ msgstr "Sin título" + +#~ msgid "Document Name:" +#~ msgstr "Nombre del documento:" + +#~ msgid "Image URI:" +#~ msgstr "URI de la imagen:" + +#~ msgid "Visible" +#~ msgstr "Visible" + +#, fuzzy +#~ msgid "Drag to paint a calligraphic stroke." +#~ msgstr "Arrastre para dibujar una línea caligráfica." + +#, fuzzy +#~ msgid "Flatness:" +#~ msgstr "Caras:" + +#, fuzzy +#~ msgid "Other" +#~ msgstr "Metro" + +#, fuzzy +#~ msgid "Trace: Selected object is not an image" +#~ msgstr "El objeto seleccionado no es un trazo, no se puede perfilar." + +#, fuzzy +#~ msgid "object" +#~ msgstr "Objeto" + +#, fuzzy +#~ msgid "user space" +#~ msgstr "Unidad del espacio de usuario" + +#, fuzzy +#~ msgid "Coordinates:" +#~ msgstr "Coordenadas del cursor" + +#, fuzzy +#~ msgid "" +#~ "Distribute centers of objects of objects at even distances horizontally" +#~ msgstr "" +#~ "Distribuir el centro de los objetos a distancias horizontales equivalentes" + +#~ msgid "Alignment:" +#~ msgstr "Alineación:" + +#~ msgid "Text and font" +#~ msgstr "Texto y tipografía" + +#~ msgid "Draw arc: %s x %s" +#~ msgstr "Dibujar arco: %s x %s" + +#~ msgid "All shape tools" +#~ msgstr "Todas las herramientas de formas" + +#~ msgid "Draw rectangle: %s x %s" +#~ msgstr "Trazar rectángulo: %s x %s" + +#~ msgid "Move by %s, %s" +#~ msgstr "Mover %s, %s" + +#~ msgid "Scale %0.2f%%, %0.2f%%" +#~ msgstr "Escala %0.2f%%, %0.2f%%" + +#~ msgid "Rotate by %0.2f deg" +#~ msgstr "Rotar %0.2f grados" + +#~ msgid "Center at (%s,%s)" +#~ msgstr "Centro en (%s,%s)" + +#~ msgid "Draw spiral at (%s,%s)" +#~ msgstr "Trazar espiral en (%s,%s)" + +#~ msgid "Draw polygon at (%s,%s)" +#~ msgstr "Trazar polígono en (%s,%s)" + +#~ msgid "Draw star at (%s,%s)" +#~ msgstr "Trazar estrella en (%s,%s)" + +#, fuzzy +#~ msgid "Active group" +#~ msgstr "Activo" + +#~ msgid "No filename specified. Unable to save." +#~ msgstr "No se especificó un nombre de archivo. Imposible guardar." + +#, fuzzy +#~ msgid "typeset object" +#~ msgstr "Objetos seleccionados" + +#, fuzzy +#~ msgid "" +#~ "You cannot build a typeset from objects of different groups or layers." +#~ msgstr "No puede combinar objetos de diferentes grupos o capas." + +#, fuzzy +#~ msgid "Pattern Fill" +#~ msgstr "Patrón:" + +#~ msgid "Snap to grid" +#~ msgstr "Ajustar a la rejilla" + +#~ msgid "Snap to guides" +#~ msgstr "Ajustar a las guías" + +#, fuzzy +#~ msgid "_Menu" +#~ msgstr "Limpi_eza" + +#, fuzzy +#~ msgid "Snap points to the grid" +#~ msgstr "Ajustar a la rejilla" + +#, fuzzy +#~ msgid "Rect" +#~ msgstr "Rectángulo" + +#, fuzzy +#~ msgid "Rects" +#~ msgstr "Objeto" + +#~ msgid "meters" +#~ msgstr "metros" + +#~ msgid "Pre_v zoom" +#~ msgstr "Zoom ante_rior" + +#~ msgid "Userspace unit" +#~ msgstr "Unidad del espacio de usuario" + +#~ msgid "User" +#~ msgstr "Usuario" + +#~ msgid "Userspace units" +#~ msgstr "Unidades de espacio de usuario" + +#, fuzzy +#~ msgid "Ru_lers" +#~ msgstr "Reglas" + +#, fuzzy +#~ msgid "Show or hide rulers" +#~ msgstr "Mostrar/ocultar reglas" + +#, fuzzy +#~ msgid "Show or hide scrollbars" +#~ msgstr "Mostrar/ocultar barras de desplazamiento" + +#, fuzzy +#~ msgid "Click to pick, click and drag to pick the average color of an area." +#~ msgstr "" +#~ "Haga clic para seleccionar un color, clic y arrastre para seleccionar la " +#~ "media de color de un área." + +#~ msgid "Corner radius to half-width ratio" +#~ msgstr "Radio de la esquina a relación de mitad de ancho" + +#~ msgid "Corner radius to half-height ratio" +#~ msgstr "Radio de la esquina a relación de mitad de alto" + +#, fuzzy +#~ msgid "_New Window" +#~ msgstr "_Nueva vista" + +#~ msgid "Mode:" +#~ msgstr "Modo:" + +#~ msgid "RGB Colorspace" +#~ msgstr "Espacio de colores RGB" + +#~ msgid "CMYK Colorspace" +#~ msgstr "Espacio de colores CMYK" + +#~ msgid "Get from dropper" +#~ msgstr "Obtener del cuentagotas" + +#~ msgid "Alpha:" +#~ msgstr "Alfa:" + +#~ msgid "Value:" +#~ msgstr "Valor:" + +#~ msgid "Stroke settings" +#~ msgstr "Opciones de contorno" + +#~ msgid "Unable to import image '%s': %s" +#~ msgstr "No se puede importar la imagen '%s': %s" + +#~ msgid "Item properties" +#~ msgstr "Propiedades del elemento" + +#~ msgid "Autoraise Dialogs" +#~ msgstr "Mostrar diálogos de confirmación" + +#~ msgid "Quit" +#~ msgstr "Salir" + +#~ msgid "Cut the bottom path into pieces" +#~ msgstr "Cortar el trazo del fondo en pedazos" + +#~ msgid "Combine multiple paths" +#~ msgstr "Combinar múltiples trazos" + +#~ msgid "Fullscreen" +#~ msgstr "Pantalla completa" + +#, fuzzy +#~ msgid "New View" +#~ msgstr "_Nueva vista" + +#~ msgid "Fill and stroke settings" +#~ msgstr "Opciones de contorno y relleno" + +#~ msgid "Object transformations" +#~ msgstr "Transformaciones de objeto" + +#~ msgid "Align and distribute objects" +#~ msgstr "Alinear y distribuir objetos" + +#~ msgid "Text editing and font settings" +#~ msgstr "Propiedades de edición de texto y tipografía" + +#, fuzzy +#~ msgid "Display help for Keys and Mouse" +#~ msgstr "_Teclado y ratón" + +#, fuzzy +#~ msgid "Tutorial for the Advanced" +#~ msgstr "tutorial-advanced.svg" + +#~ msgid "Fill Rule" +#~ msgstr "Regla de relleno" + +#~ msgid "Tool has no options" +#~ msgstr "La herramienta no tiene opciones" + +#~ msgid "Use the extension of the file to choose a filetype" +#~ msgstr "Utilizar la extensión del archivo para elegir el tipo de archivo" + +#~ msgid "Roundness ratio for x:" +#~ msgstr "Radio de curvatura para x:" + +#~ msgid "Roundness ratio for y:" +#~ msgstr "Radio de curvatura para y:" + +#~ msgid "Visual transformation" +#~ msgstr "Transformación visual" + +#~ msgid "Show content" +#~ msgstr "Mostrar contenido" + +#~ msgid "Selected object has no curve, cannot outline." +#~ msgstr "El objeto seleccionado no tiene curva, no se puede perfilar." + +#~ msgid "Outline of object could not be computed." +#~ msgstr "No se pudo calcular el perfil del objeto." + +#~ msgid "Flat Sided" +#~ msgstr "Lados planos" + +#~ msgid "Tool Optio_ns" +#~ msgstr "Opcio_nes de herramienta" + +#~ msgid "gradientUnits" +#~ msgstr "Unidades de gradiente" + +#~ msgid "gradientSpread" +#~ msgstr "Separación de gradiente" + +#~ msgid "nonzero" +#~ msgstr "no cero" + +#~ msgid "evenodd" +#~ msgstr "parimpar" diff --git a/po/fr.po b/po/fr.po new file mode 100644 index 000000000..8468e6b49 --- /dev/null +++ b/po/fr.po @@ -0,0 +1,9703 @@ +# translation of fr.po to Français +# French translation of Inkscape. +# Copyright (C) 2000-2003, 2005 Free Software Foundation, Inc. +# Christophe Merlet (RedFox) , 2000-2002. +# Raymond Ostertag , 2002-2003. +# Didier Conchaudron , 2003. +# Matiphas , 2004. +# Frederic Rodrigo , 2004-2005. +# +# +msgid "" +msgstr "" +"Project-Id-Version: fr\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2005-12-04 11:51-0800\n" +"PO-Revision-Date: 2005-11-10 12:06+0100\n" +"Last-Translator: Matiphas \n" +"Language-Team: French\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2;plural=(n>1);\n" + +#: ../inkscape.desktop.in.h:1 +msgid "Create and edit Scalable Vector Graphics images" +msgstr "Créer et éditer des images Scalable Vector Graphics" + +#: ../inkscape.desktop.in.h:2 +msgid "Inkscape SVG Vector Illustrator" +msgstr "Illustrateur vectoriel SVG Inkscape" + +#: ../../po/../src/arc-context.cpp:350 +msgid "" +"Ctrl: make circle or integer-ratio ellipse, snap arc/segment angle" +msgstr "" +"Ctrl : dessiner des cercles ou des ellipses de ratio entier, forcer " +"la modification des angles des arcs/camemberts par incréments" + +#: ../../po/../src/arc-context.cpp:351 ../../po/../src/rect-context.cpp:388 +msgid "Shift: draw around the starting point" +msgstr "Maj : dessiner autour du point de départ" + +#: ../../po/../src/arc-context.cpp:413 +#: ../../po/../src/connector-context.cpp:493 +#: ../../po/../src/dyna-draw-context.cpp:506 +#: ../../po/../src/pen-context.cpp:329 ../../po/../src/pencil-context.cpp:208 +#: ../../po/../src/rect-context.cpp:452 ../../po/../src/spiral-context.cpp:421 +#: ../../po/../src/star-context.cpp:427 +msgid "Current layer is hidden. Unhide it to be able to draw on it." +msgstr "" +"Le calque courant est caché. Le rendre visible pour pouvoir y " +"dessiner." + +#: ../../po/../src/arc-context.cpp:417 +#: ../../po/../src/connector-context.cpp:497 +#: ../../po/../src/dyna-draw-context.cpp:510 +#: ../../po/../src/pen-context.cpp:336 ../../po/../src/pencil-context.cpp:212 +#: ../../po/../src/rect-context.cpp:456 ../../po/../src/spiral-context.cpp:426 +#: ../../po/../src/star-context.cpp:431 +msgid "Current layer is locked. Unlock it to be able to draw on it." +msgstr "" +"Le calque courant est verrouillé. Le déverrouiller pour pouvoir y " +"dessiner." + +#: ../../po/../src/arc-context.cpp:496 +#, c-format +msgid "" +"Ellipse: %s × %s; with Ctrl to make circle or integer-" +"ratio ellipse; with Shift to draw around the starting point" +msgstr "" +"Ellipse : %s × %s; Ctrl pour dessiner des cercles ou des " +"ellipses de ratio entier, Maj pour dessiner autour du point de départ" + +#: ../../po/../src/connector-context.cpp:518 +msgid "Creating new connector" +msgstr "Création d'un nouveau connecteur" + +#: ../../po/../src/connector-context.cpp:939 +msgid "Finishing connector" +msgstr "Tracé du connecteur terminé" + +#: ../../po/../src/connector-context.cpp:1108 +msgid "Connection point: click or drag to create a new connector" +msgstr "" +"Point de connnection : cliquer ou déplacer pour créer un nouveau " +"connecteur" + +#: ../../po/../src/connector-context.cpp:1185 +msgid "Connector endpoint: drag to reroute or connect to new shapes" +msgstr "" +"Fin de connecteur : déplacer pour rerouter ou connecter à de " +"nouvelles formes" + +#: ../../po/../src/connector-context.cpp:1278 +msgid "Select at least one non-connector object." +msgstr "Sélectionner au moins un objet non connecteur." + +#: ../../po/../src/desktop-events.cpp:238 +#, c-format +msgid "%s at %s" +msgstr "%s à %s" + +#. TRANSLATORS: This string appears when double-clicking on a guide. +#. This is the distance by which the guide is to be moved. +#: ../../po/../src/desktop-events.cpp:277 +msgid " relative by " +msgstr " de " + +#. TRANSLATORS: This string appears when double-clicking on a guide. +#. This is the target location where the guide is to be moved. +#: ../../po/../src/desktop-events.cpp:282 +#: ../../po/../src/desktop-events.cpp:395 +msgid " absolute to " +msgstr " en " + +#. create dialog +#: ../../po/../src/desktop-events.cpp:348 +msgid "Guideline" +msgstr "Ligne de guide" + +#: ../../po/../src/desktop-events.cpp:432 +#, c-format +msgid "Move %s" +msgstr "Déplacer %s" + +#: ../../po/../src/desktop.cpp:678 +msgid "No previous zoom." +msgstr "Plus de zoom précédent." + +#: ../../po/../src/desktop.cpp:703 +msgid "No next zoom." +msgstr "Plus de zoom suivant." + +#: ../../po/../src/dialogs/clonetiler.cpp:182 +msgid "Nothing selected." +msgstr "Aucune sélection." + +#: ../../po/../src/dialogs/clonetiler.cpp:188 +msgid "More than one object selected." +msgstr "Plus d'un objet est sélectionné." + +#: ../../po/../src/dialogs/clonetiler.cpp:195 +#, c-format +msgid "Object has %d tiled clones." +msgstr "L'objet a %d clones de pavage." + +#: ../../po/../src/dialogs/clonetiler.cpp:200 +msgid "Object has no tiled clones." +msgstr "L'objet n'a pas de clone de pavage." + +#: ../../po/../src/dialogs/clonetiler.cpp:865 +msgid "Select one object whose tiled clones to unclump." +msgstr "Sélectionner un objet pour en éparpiller les clones." + +#: ../../po/../src/dialogs/clonetiler.cpp:916 +msgid "Select one object whose tiled clones to remove." +msgstr "Sélectionner un objet duquel retirer les clones de pavage." + +#: ../../po/../src/dialogs/clonetiler.cpp:984 +#: ../../po/../src/selection-chemistry.cpp:1774 +msgid "Select an object to clone." +msgstr "Sélectionner un objet à cloner." + +#: ../../po/../src/dialogs/clonetiler.cpp:990 +#: ../../po/../src/selection-chemistry.cpp:1780 +msgid "" +"If you want to clone several objects, group them and clone the " +"group." +msgstr "" +"Si vous voulez cloner plusieurs objets, groupez-les puis clonez le " +"groupe." + +#: ../../po/../src/dialogs/clonetiler.cpp:1484 +msgid "Per row:" +msgstr "Par ligne :" + +#: ../../po/../src/dialogs/clonetiler.cpp:1497 +msgid "Per column:" +msgstr "Par colonne :" + +#: ../../po/../src/dialogs/clonetiler.cpp:1505 +msgid "Randomize:" +msgstr "Hasard :" + +#: ../../po/../src/dialogs/clonetiler.cpp:1656 +msgid "_Symmetry" +msgstr "_Symétrie" + +# See: +# http://www.bib.ulb.ac.be/coursmath/doc/17.htm (visual examples) +# http://membres.lycos.fr/villemingerard/Geometri/Sym1D.htm (French vocabulary) +# http://www.clarku.edu/~djoyce/wallpaper/seventeen.html (English vocabulary) +#. TRANSLATORS: For the following 17 symmetry groups, see +#. * http://www.bib.ulb.ac.be/coursmath/doc/17.htm (visual examples); +#. * http://www.clarku.edu/~djoyce/wallpaper/seventeen.html (English vocabulary); or +#. * http://membres.lycos.fr/villemingerard/Geometri/Sym1D.htm (French vocabulary). +#. +#: ../../po/../src/dialogs/clonetiler.cpp:1664 +msgid "Select one of the 17 symmetry groups for the tiling" +msgstr "Sélectionner un des 17 groupes de symétrie régissant le pavage" + +#. TRANSLATORS: "translation" means "shift" / "displacement" here. +#: ../../po/../src/dialogs/clonetiler.cpp:1675 +msgid "P1: simple translation" +msgstr "P1 : translation" + +#: ../../po/../src/dialogs/clonetiler.cpp:1676 +msgid "P2: 180° rotation" +msgstr "P2 : rotation de 180°" + +#: ../../po/../src/dialogs/clonetiler.cpp:1677 +msgid "PM: reflection" +msgstr "PM : réflexion" + +#. TRANSLATORS: "glide reflection" is a reflection and a translation combined. +#. For more info, see http://mathforum.org/sum95/suzanne/symsusan.html +#: ../../po/../src/dialogs/clonetiler.cpp:1680 +msgid "PG: glide reflection" +msgstr "PG : réflexion glissée" + +#: ../../po/../src/dialogs/clonetiler.cpp:1681 +msgid "CM: reflection + glide reflection" +msgstr "CM : réflexion + réflexion glissée" + +#: ../../po/../src/dialogs/clonetiler.cpp:1682 +msgid "PMM: reflection + reflection" +msgstr "PMM : réflexion + réflexion" + +#: ../../po/../src/dialogs/clonetiler.cpp:1683 +msgid "PMG: reflection + 180° rotation" +msgstr "PMG : réflexion + rotation de 180°" + +#: ../../po/../src/dialogs/clonetiler.cpp:1684 +msgid "PGG: glide reflection + 180° rotation" +msgstr "PGG : réflexion glissée + rotation de 180°" + +#: ../../po/../src/dialogs/clonetiler.cpp:1685 +msgid "CMM: reflection + reflection + 180° rotation" +msgstr "CMM : réflexion + réflexion + rotation de 180°" + +#: ../../po/../src/dialogs/clonetiler.cpp:1686 +msgid "P4: 90° rotation" +msgstr "P4 : rotation de 90°" + +#: ../../po/../src/dialogs/clonetiler.cpp:1687 +msgid "P4M: 90° rotation + 45° reflection" +msgstr "P4M: rotation de 90° + réflexion à 45°" + +#: ../../po/../src/dialogs/clonetiler.cpp:1688 +msgid "P4G: 90° rotation + 90° reflection" +msgstr "P4G : rotation de 90° + réflexion à 90°" + +#: ../../po/../src/dialogs/clonetiler.cpp:1689 +msgid "P3: 120° rotation" +msgstr "P3 : rotation de 120°" + +#: ../../po/../src/dialogs/clonetiler.cpp:1690 +msgid "P31M: reflection + 120° rotation, dense" +msgstr "P31M : réflexion + rotation de 120°, dense" + +#: ../../po/../src/dialogs/clonetiler.cpp:1691 +msgid "P3M1: reflection + 120° rotation, sparse" +msgstr "P3M1 : réflexion + rotation de 120°, clairsemé" + +#: ../../po/../src/dialogs/clonetiler.cpp:1692 +msgid "P6: 60° rotation" +msgstr "P6: rotation de 60°" + +#: ../../po/../src/dialogs/clonetiler.cpp:1693 +msgid "P6M: reflection + 60° rotation" +msgstr "P6M: réflexion + rotation de 60°" + +#: ../../po/../src/dialogs/clonetiler.cpp:1721 +msgid "S_hift" +msgstr "Translation (_h)" + +#. TRANSLATORS: "shift" means: the tiles will be shifted (offset) horizontally by this amount +#: ../../po/../src/dialogs/clonetiler.cpp:1731 +#, no-c-format +msgid "Shift X:" +msgstr "Translation X" + +#: ../../po/../src/dialogs/clonetiler.cpp:1739 +#, no-c-format +msgid "Horizontal shift per row (in % of tile width)" +msgstr "Translation horizontale à chaque ligne (en % de la largeur du pavage)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1747 +#, no-c-format +msgid "Horizontal shift per column (in % of tile width)" +msgstr "" +"Translation horizontale à chaque colonne (en % de la largeur du pavage)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1754 +msgid "Randomize the horizontal shift by this percentage" +msgstr "Rendre la translation horizontale aléatoire de ce pourcentage" + +#. TRANSLATORS: "shift" means: the tiles will be shifted (offset) vertically by this amount +#: ../../po/../src/dialogs/clonetiler.cpp:1764 +#, no-c-format +msgid "Shift Y:" +msgstr "Translation Y" + +#: ../../po/../src/dialogs/clonetiler.cpp:1772 +#, no-c-format +msgid "Vertical shift per row (in % of tile height)" +msgstr "Translation verticale à chaque ligne (en % de la hauteur du pavage)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1780 +#, no-c-format +msgid "Vertical shift per column (in % of tile height)" +msgstr "Translation verticale à chaque colonne (en % de la hauteur du pavage)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1787 +msgid "Randomize the vertical shift by this percentage" +msgstr "Rendre la translation verticale aléatoire de ce pourcentage" + +#: ../../po/../src/dialogs/clonetiler.cpp:1795 +msgid "Exponent:" +msgstr "Exposant :" + +#: ../../po/../src/dialogs/clonetiler.cpp:1802 +msgid "Whether rows are spaced evenly (1), converge (<1) or diverge (>1)" +msgstr "" +"Selon la valeur, l'inter ligne reste constant (1), converge (<1) ou diverge" +"(>1) " + +#: ../../po/../src/dialogs/clonetiler.cpp:1809 +msgid "Whether columns are spaced evenly (1), converge (<1) or diverge (>1)" +msgstr "" +"Selon la valeur, l'inter colonne reste constant (1), converge (<1) ou diverge" +"(>1) " + +#. TRANSLATORS: "Alternate" is a verb here +#: ../../po/../src/dialogs/clonetiler.cpp:1817 +#: ../../po/../src/dialogs/clonetiler.cpp:1907 +#: ../../po/../src/dialogs/clonetiler.cpp:1966 +#: ../../po/../src/dialogs/clonetiler.cpp:2022 +#: ../../po/../src/dialogs/clonetiler.cpp:2153 +msgid "Alternate:" +msgstr "Alterner :" + +#: ../../po/../src/dialogs/clonetiler.cpp:1823 +msgid "Alternate the sign of shifts for each row" +msgstr "Alterner le signe de la translation à chaque ligne" + +#: ../../po/../src/dialogs/clonetiler.cpp:1828 +msgid "Alternate the sign of shifts for each column" +msgstr "Alterner le signe de la translation à chaque colonne" + +#: ../../po/../src/dialogs/clonetiler.cpp:1837 +msgid "Sc_ale" +msgstr "Dimensions (_a)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1845 +msgid "Scale X:" +msgstr "Echelle X :" + +#: ../../po/../src/dialogs/clonetiler.cpp:1853 +#, no-c-format +msgid "Horizontal scale per row (in % of tile width)" +msgstr "" +"Redimensionnement horizontal à chaque ligne (en % de la largeur du pavage)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1861 +#, no-c-format +msgid "Horizontal scale per column (in % of tile width)" +msgstr "" +"Redimensionnement horizontal à chaque colonne (en % de la largeur du pavage)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1868 +msgid "Randomize the horizontal scale by this percentage" +msgstr "Rendre le redimensionnement horizontal aléatoire de ce pourcentage" + +#: ../../po/../src/dialogs/clonetiler.cpp:1876 +msgid "Scale Y:" +msgstr "Echelle Y :" + +#: ../../po/../src/dialogs/clonetiler.cpp:1884 +#, no-c-format +msgid "Vertical scale per row (in % of tile height)" +msgstr "" +"Redimensionnement vertical à chaque ligne (en % de la largeur du pavage)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1892 +#, no-c-format +msgid "Vertical scale per column (in % of tile height)" +msgstr "" +"Redimensionnement vertical à chaque colonne (en % de la largeur du pavage)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1899 +msgid "Randomize the vertical scale by this percentage" +msgstr "Rendre le Redimensionnement vertical aléatoire de ce pourcentage" + +#: ../../po/../src/dialogs/clonetiler.cpp:1913 +msgid "Alternate the sign of scales for each row" +msgstr "Alterner le signe du redimensionnement à chaque ligne" + +#: ../../po/../src/dialogs/clonetiler.cpp:1918 +msgid "Alternate the sign of scales for each column" +msgstr "Alterner le signe du redimensionnement à chaque colonne" + +#: ../../po/../src/dialogs/clonetiler.cpp:1927 +msgid "_Rotation" +msgstr "_Rotation" + +#: ../../po/../src/dialogs/clonetiler.cpp:1935 +msgid "Angle:" +msgstr "Angle :" + +#: ../../po/../src/dialogs/clonetiler.cpp:1943 +#, no-c-format +msgid "Rotate tiles by this angle for each row" +msgstr "Faire tourner les pavés de cet angle à chaque ligne" + +#: ../../po/../src/dialogs/clonetiler.cpp:1951 +#, no-c-format +msgid "Rotate tiles by this angle for each column" +msgstr "Faire tourner les pavés de cet angle à chaque colonne" + +#: ../../po/../src/dialogs/clonetiler.cpp:1958 +msgid "Randomize the rotation angle by this percentage" +msgstr "Rendre l'angle de rotation aléatoire de ce pourcentage" + +#: ../../po/../src/dialogs/clonetiler.cpp:1972 +msgid "Alternate the rotation direction for each row" +msgstr "Alterner le sens de la rotation à chaque ligne" + +#: ../../po/../src/dialogs/clonetiler.cpp:1977 +msgid "Alternate the rotation direction for each column" +msgstr "Alterner le sens de la rotation à chaque colonne" + +#: ../../po/../src/dialogs/clonetiler.cpp:1985 +msgid "_Opacity" +msgstr "_Opacité" + +#: ../../po/../src/dialogs/clonetiler.cpp:1993 +msgid "Fade out:" +msgstr "Disparition :" + +#: ../../po/../src/dialogs/clonetiler.cpp:2000 +msgid "Decrease tile opacity by this percentage for each row" +msgstr "Diminuer l'opacité des pavés de ce pourcentage à chaque ligne" + +#: ../../po/../src/dialogs/clonetiler.cpp:2007 +msgid "Decrease tile opacity by this percentage for each column" +msgstr "Diminuer l'opacité des pavés de ce pourcentage à chaque colonne" + +#: ../../po/../src/dialogs/clonetiler.cpp:2014 +msgid "Randomize the tile opacity by this percentage" +msgstr "Rendre l'opacité aléatoire de ce pourcentage" + +#: ../../po/../src/dialogs/clonetiler.cpp:2028 +msgid "Alternate the sign of opacity change for each row" +msgstr "Alterner le signe de la modification d'opacité à chaque ligne" + +#: ../../po/../src/dialogs/clonetiler.cpp:2033 +msgid "Alternate the sign of opacity change for each column" +msgstr "Alterner le signe de la modification d'opacité à chaque colonne" + +#: ../../po/../src/dialogs/clonetiler.cpp:2041 +msgid "Co_lor" +msgstr "Cou_leur" + +#: ../../po/../src/dialogs/clonetiler.cpp:2046 +msgid "Initial color: " +msgstr "Couleur initiale :" + +#: ../../po/../src/dialogs/clonetiler.cpp:2050 +msgid "Initial color of tiled clones" +msgstr "Couleur initiale des clones de pavage" + +#: ../../po/../src/dialogs/clonetiler.cpp:2050 +msgid "" +"Initial color for clones (works only if the original has unset fill or " +"stroke)" +msgstr "" +"Couleur initiale pour les clones (ne fonctionne que si l'original a un " +"remplissage ou un contour indéfini)" + +#: ../../po/../src/dialogs/clonetiler.cpp:2065 +msgid "H:" +msgstr "T :" + +#: ../../po/../src/dialogs/clonetiler.cpp:2072 +msgid "Change the tile hue by this percentage for each row" +msgstr "Modifier la teinte des pavés de ce pourcentage à chaque ligne" + +#: ../../po/../src/dialogs/clonetiler.cpp:2079 +msgid "Change the tile hue by this percentage for each column" +msgstr "Modifier la teinte des pavés de ce pourcentage à chaque colonne" + +#: ../../po/../src/dialogs/clonetiler.cpp:2086 +msgid "Randomize the tile hue by this percentage" +msgstr "Rendre la modification de teinte aléatoire de ce pourcentage" + +#: ../../po/../src/dialogs/clonetiler.cpp:2095 +msgid "S:" +msgstr "S :" + +#: ../../po/../src/dialogs/clonetiler.cpp:2102 +msgid "Change the color saturation by this percentage for each row" +msgstr "Modifier la saturation des pavés de ce pourcentage à chaque ligne" + +#: ../../po/../src/dialogs/clonetiler.cpp:2109 +msgid "Change the color saturation by this percentage for each column" +msgstr "Modifier la saturation des pavés de ce pourcentage à chaque colonne" + +#: ../../po/../src/dialogs/clonetiler.cpp:2116 +msgid "Randomize the color saturation by this percentage" +msgstr "Rendre la modification de saturation aléatoire de ce pourcentage" + +#: ../../po/../src/dialogs/clonetiler.cpp:2124 +msgid "L:" +msgstr "L :" + +#: ../../po/../src/dialogs/clonetiler.cpp:2131 +msgid "Change the color lightness by this percentage for each row" +msgstr "Modifier la luminosité des pavés de ce pourcentage à chaque ligne" + +#: ../../po/../src/dialogs/clonetiler.cpp:2138 +msgid "Change the color lightness by this percentage for each column" +msgstr "Modifier la luminosité des pavés de ce pourcentage à chaque colonne" + +#: ../../po/../src/dialogs/clonetiler.cpp:2145 +msgid "Randomize the color lightness by this percentage" +msgstr "Rendre la modification de luminosité aléatoire de ce pourcentage" + +#: ../../po/../src/dialogs/clonetiler.cpp:2159 +msgid "Alternate the sign of color changes for each row" +msgstr "Alterner le signe de la modification de couleur à chaque ligne" + +#: ../../po/../src/dialogs/clonetiler.cpp:2164 +msgid "Alternate the sign of color changes for each column" +msgstr "Alterner le signe de la modification de couleur à chaque colonne" + +#: ../../po/../src/dialogs/clonetiler.cpp:2172 +msgid "_Trace" +msgstr "Calquer (_t)" + +#: ../../po/../src/dialogs/clonetiler.cpp:2179 +msgid "Trace the drawing under the tiles" +msgstr "Calquer depuis le dessin sous les pavés" + +#: ../../po/../src/dialogs/clonetiler.cpp:2183 +msgid "" +"For each clone, pick a value from the drawing in that clone's location and " +"apply it to the clone" +msgstr "" +"Pour chaque clone, capturer une valeur du dessin à l'emplacement du clone et " +"l'appliquer au clone." + +#: ../../po/../src/dialogs/clonetiler.cpp:2197 +msgid "1. Pick from the drawing:" +msgstr "1. Capturer depuis le dessin :" + +#. ----Hbox2 +#: ../../po/../src/dialogs/clonetiler.cpp:2208 +#: ../../po/../src/dialogs/clonetiler.cpp:2355 +#: ../../po/../src/ui/dialog/tracedialog.cpp:445 +msgid "Color" +msgstr "Couleur" + +#: ../../po/../src/dialogs/clonetiler.cpp:2209 +msgid "Pick the visible color and opacity" +msgstr "Capturer la couleur et l'opacité visibles" + +#: ../../po/../src/dialogs/clonetiler.cpp:2216 +#: ../../po/../src/dialogs/clonetiler.cpp:2365 +#: ../share/extensions/dropshadow.inx.h:3 +msgid "Opacity" +msgstr "Opacité" + +#: ../../po/../src/dialogs/clonetiler.cpp:2217 +msgid "Pick the total accumulated opacity" +msgstr "Capturer l'opacité cumulée" + +# Red (in RGB) +#: ../../po/../src/dialogs/clonetiler.cpp:2224 +msgid "R" +msgstr "R" + +#: ../../po/../src/dialogs/clonetiler.cpp:2225 +msgid "Pick the Red component of the color" +msgstr "Capturer la composante rouge de la couleur" + +# Green (in RGB) +#: ../../po/../src/dialogs/clonetiler.cpp:2232 +msgid "G" +msgstr "V" + +#: ../../po/../src/dialogs/clonetiler.cpp:2233 +msgid "Pick the Green component of the color" +msgstr "Capturer la composante verte de la couleur" + +# Blue (in RGB) +#: ../../po/../src/dialogs/clonetiler.cpp:2240 +msgid "B" +msgstr "B" + +#: ../../po/../src/dialogs/clonetiler.cpp:2241 +msgid "Pick the Blue component of the color" +msgstr "Capturer la composante bleue de la couleur" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2250 +msgid "clonetiler|H" +msgstr "T" + +#: ../../po/../src/dialogs/clonetiler.cpp:2251 +msgid "Pick the hue of the color" +msgstr "Capturer la teinte de la couleur" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2260 +msgid "clonetiler|S" +msgstr "S" + +#: ../../po/../src/dialogs/clonetiler.cpp:2261 +msgid "Pick the saturation of the color" +msgstr "Capturer la saturation de la couleur" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2270 +msgid "clonetiler|L" +msgstr "L" + +#: ../../po/../src/dialogs/clonetiler.cpp:2271 +msgid "Pick the lightness of the color" +msgstr "Capturer la luminosité de la couleur" + +#: ../../po/../src/dialogs/clonetiler.cpp:2281 +msgid "2. Tweak the picked value:" +msgstr "2. Modifier la valeur capturée" + +#: ../../po/../src/dialogs/clonetiler.cpp:2291 +msgid "Gamma-correct:" +msgstr "Corriger le Gamma" + +#: ../../po/../src/dialogs/clonetiler.cpp:2296 +msgid "Shift the mid-range of the picked value upwards (>0) or downwards (<0)" +msgstr "" +"Décaler le milieu de la valeur capturée vers le haut (>0) ou vers le bas (<0)" + +#: ../../po/../src/dialogs/clonetiler.cpp:2303 +msgid "Randomize:" +msgstr "Hasard :" + +#: ../../po/../src/dialogs/clonetiler.cpp:2308 +msgid "Randomize the picked value by this percentage" +msgstr "Rendre la valeur capturée aléatoire de ce pourcentage" + +#: ../../po/../src/dialogs/clonetiler.cpp:2315 +msgid "Invert:" +msgstr "Inverser :" + +#: ../../po/../src/dialogs/clonetiler.cpp:2319 +msgid "Invert the picked value" +msgstr "Inverser la valeur capturée" + +#: ../../po/../src/dialogs/clonetiler.cpp:2325 +msgid "3. Apply the value to the clones':" +msgstr "3. Appliquer la valeur aux clones :" + +#: ../../po/../src/dialogs/clonetiler.cpp:2335 +msgid "Presence" +msgstr "Présence" + +#: ../../po/../src/dialogs/clonetiler.cpp:2338 +msgid "" +"Each clone is created with the probability determined by the picked value in " +"that point" +msgstr "" +"Chaque clone est créé selon la probabilité déterminée par la valeur capturée " +"en ce point" + +#: ../../po/../src/dialogs/clonetiler.cpp:2345 +msgid "Size" +msgstr "Taille" + +#: ../../po/../src/dialogs/clonetiler.cpp:2348 +msgid "Each clone's size is determined by the picked value in that point" +msgstr "" +"La taille de chaque clone est déterminée selon la valeur capturée en ce " +"point " + +#: ../../po/../src/dialogs/clonetiler.cpp:2358 +msgid "" +"Each clone is painted by the picked color (the original must have unset fill " +"or stroke)" +msgstr "" +"Chaque clone est peint selon la couleur capturée (l'original doit avoir un " +"remplissage ou un contour indéfini)" + +#: ../../po/../src/dialogs/clonetiler.cpp:2368 +msgid "Each clone's opacity is determined by the picked value in that point" +msgstr "" +"L'opacité de chaque clone est déterminée par la valeur capturée en ce point" + +#: ../../po/../src/dialogs/clonetiler.cpp:2395 +msgid "How many rows in the tiling" +msgstr "Nombre de lignes du pavage" + +#: ../../po/../src/dialogs/clonetiler.cpp:2415 +msgid "How many columns in the tiling" +msgstr "Nombre de colonnes du pavage" + +#: ../../po/../src/dialogs/clonetiler.cpp:2445 +msgid "Width of the rectangle to be filled" +msgstr "Largeur du rectangle à remplir" + +#: ../../po/../src/dialogs/clonetiler.cpp:2470 +msgid "Height of the rectangle to be filled" +msgstr "Hauteur du rectangle à remplir" + +#: ../../po/../src/dialogs/clonetiler.cpp:2485 +msgid "Rows, columns: " +msgstr "Lignes, colonnes :" + +#: ../../po/../src/dialogs/clonetiler.cpp:2486 +msgid "Create the specified number of rows and columns" +msgstr "Créer le nombre spécifié de lignes et de colonnes" + +#: ../../po/../src/dialogs/clonetiler.cpp:2495 +msgid "Width, height: " +msgstr "Largeur, hauteur :" + +#: ../../po/../src/dialogs/clonetiler.cpp:2496 +msgid "Fill the specified width and height with the tiling" +msgstr "Remplir avec le pavage selon la hauteur et la largeur spécifiées" + +#: ../../po/../src/dialogs/clonetiler.cpp:2512 +msgid "Use saved size and position of the tile" +msgstr "Utiliser les taille et position enregistrées du pavage" + +#: ../../po/../src/dialogs/clonetiler.cpp:2515 +msgid "" +"Pretend that the size and position of the tile are the same as the last time " +"you tiled it (if any), instead of using the current size" +msgstr "" +"Utiliser les mêmes taille et position de pavés que lors du pavage précédent " +"(si possible), au lieu d'utiliser les paramètres courants" + +#: ../../po/../src/dialogs/clonetiler.cpp:2539 +msgid " _Create " +msgstr " _Créer " + +#: ../../po/../src/dialogs/clonetiler.cpp:2541 +msgid "Create and tile the clones of the selection" +msgstr "Créer les clones et paver la sélection avec" + +#. TRANSLATORS: if a group of objects are "clumped" together, then they +#. are unevenly spread in the given amount of space - as shown in the +#. diagrams on the left in the following screenshot: +#. http://www.inkscape.org/screenshots/gallery/inkscape-0.42-CVS-tiles-unclump.png +#. So unclumping is the process of spreading a number of objects out more evenly. +#: ../../po/../src/dialogs/clonetiler.cpp:2556 +msgid " _Unclump " +msgstr "Eparpiller (_u)" + +#: ../../po/../src/dialogs/clonetiler.cpp:2557 +msgid "Spread out clones to reduce clumping; can be applied repeatedly" +msgstr "" +"Disperser les clones de façon à reduire le rassemblement; peut être appliqué " +"plusieurs fois" + +#: ../../po/../src/dialogs/clonetiler.cpp:2563 +msgid " Re_move " +msgstr "Suppri_mer" + +#: ../../po/../src/dialogs/clonetiler.cpp:2564 +msgid "Remove existing tiled clones of the selected object (siblings only)" +msgstr "" +"Retirer les clones de pavage de l'objet sélectionné (seulement les «enfants " +"de mêmes parents»)" + +#: ../../po/../src/dialogs/clonetiler.cpp:2580 +msgid " R_eset " +msgstr " Raz (_e) " + +#. TRANSLATORS: "change" is a noun here +#: ../../po/../src/dialogs/clonetiler.cpp:2582 +msgid "" +"Reset all shifts, scales, rotates, opacity and color changes in the dialog " +"to zero" +msgstr "" +"Remise à zéro de tous les décalages, redimensionnements, rotation et " +"opacités dans la boîte de dialogue" + +#: ../../po/../src/dialogs/color-picker.cpp:280 +msgid "Close" +msgstr "Fermer" + +#: ../../po/../src/dialogs/debugdialog.cpp:138 +msgid "Messages" +msgstr "Messages" + +#. ## Add a menu for clear() +#: ../../po/../src/dialogs/debugdialog.cpp:144 +#: ../../po/../src/menus-skeleton.h:16 +#: ../../po/../src/ui/dialog/messages.cpp:56 +#: ../../po/../src/ui/dialog/scriptdialog.cpp:181 +msgid "_File" +msgstr "_Fichier" + +#. TRANSLATORS: "Clear" is a verb here +#: ../../po/../src/dialogs/debugdialog.cpp:145 +#: ../../po/../src/dialogs/find.cpp:753 +#: ../../po/../src/ui/dialog/messages.cpp:57 +#: ../../po/../src/ui/dialog/scriptdialog.cpp:182 +msgid "_Clear" +msgstr "Effa_cer" + +#: ../../po/../src/dialogs/debugdialog.cpp:147 +#: ../../po/../src/ui/dialog/messages.cpp:59 +msgid "Capture log messages" +msgstr "Capturer les messages de log" + +#: ../../po/../src/dialogs/debugdialog.cpp:149 +#: ../../po/../src/ui/dialog/messages.cpp:61 +msgid "Release log messages" +msgstr "Détacher les messages de log" + +#. Notebook tab +#: ../../po/../src/dialogs/desktop-properties.cpp:909 +#: ../../po/../src/ui/dialog/document-preferences.cpp:89 +#: ../../po/../src/ui/widget/panel.cpp:107 +msgid "Grid" +msgstr "Grille" + +#. Checkbuttons +#. / \todo FIXME: gray out snapping when grid is off +#. / \todo FIXME: gray out snapping when grid is off. +#. / Dissenting view: you want snapping without grid. +#: ../../po/../src/dialogs/desktop-properties.cpp:917 +#: ../../po/../src/ui/dialog/document-preferences.cpp:179 +msgid "Show grid" +msgstr "Afficher la grille" + +#: ../../po/../src/dialogs/desktop-properties.cpp:917 +#: ../../po/../src/ui/dialog/document-preferences.cpp:179 +#: ../../po/../src/verbs.cpp:2115 +msgid "Show or hide grid" +msgstr "Afficher ou non la grille" + +#: ../../po/../src/dialogs/desktop-properties.cpp:918 +#: ../../po/../src/ui/dialog/document-preferences.cpp:180 +msgid "Snap bounding boxes to grid" +msgstr "Faire coller les boîtes à la grille" + +#: ../../po/../src/dialogs/desktop-properties.cpp:918 +#: ../../po/../src/dialogs/desktop-properties.cpp:1001 +#: ../../po/../src/ui/dialog/document-preferences.cpp:181 +#: ../../po/../src/ui/dialog/document-preferences.cpp:236 +msgid "Snap the edges of the object bounding boxes" +msgstr "Faire coller les côtés des boîtes de contour des objets" + +#: ../../po/../src/dialogs/desktop-properties.cpp:919 +#: ../../po/../src/ui/dialog/document-preferences.cpp:183 +msgid "Snap nodes to grid" +msgstr "Faire coller les nœuds à la grille" + +#: ../../po/../src/dialogs/desktop-properties.cpp:919 +#: ../../po/../src/dialogs/desktop-properties.cpp:1002 +#: ../../po/../src/ui/dialog/document-preferences.cpp:184 +#: ../../po/../src/ui/dialog/document-preferences.cpp:239 +msgid "Snap path nodes, text baselines, ellipse centers, etc." +msgstr "" +"Faire coller les nœuds de chemin, les ancres de texte, les centres " +"d'ellipse, etc." + +#: ../../po/../src/dialogs/desktop-properties.cpp:937 +#: ../../po/../src/ui/dialog/document-preferences.cpp:186 +msgid "Grid units:" +msgstr "Unités de la grille :" + +#: ../../po/../src/dialogs/desktop-properties.cpp:939 +#: ../../po/../src/ui/dialog/document-preferences.cpp:187 +msgid "Origin X:" +msgstr "Origine X :" + +#: ../../po/../src/dialogs/desktop-properties.cpp:942 +#: ../../po/../src/ui/dialog/document-preferences.cpp:189 +msgid "Origin Y:" +msgstr "Origine Y :" + +#: ../../po/../src/dialogs/desktop-properties.cpp:945 +#: ../../po/../src/ui/dialog/document-preferences.cpp:191 +msgid "Spacing X:" +msgstr "Espacement X :" + +#: ../../po/../src/dialogs/desktop-properties.cpp:948 +#: ../../po/../src/ui/dialog/document-preferences.cpp:193 +msgid "Spacing Y:" +msgstr "Espacement Y :" + +#: ../../po/../src/dialogs/desktop-properties.cpp:952 +#: ../../po/../src/dialogs/desktop-properties.cpp:1013 +#: ../../po/../src/ui/dialog/document-preferences.cpp:195 +#: ../../po/../src/ui/dialog/document-preferences.cpp:241 +msgid "Snap units:" +msgstr "Unités de collage :" + +#: ../../po/../src/dialogs/desktop-properties.cpp:955 +#: ../../po/../src/dialogs/desktop-properties.cpp:1016 +#: ../../po/../src/ui/dialog/document-preferences.cpp:196 +#: ../../po/../src/ui/dialog/document-preferences.cpp:242 +msgid "Snap distance:" +msgstr "Distance de collage :" + +#: ../../po/../src/dialogs/desktop-properties.cpp:958 +#: ../../po/../src/ui/dialog/document-preferences.cpp:199 +msgid "Grid line color:" +msgstr "Couleur de la grille :" + +#: ../../po/../src/dialogs/desktop-properties.cpp:959 +#: ../../po/../src/ui/dialog/document-preferences.cpp:199 +msgid "Grid line color" +msgstr "Couleur de la grille" + +#: ../../po/../src/dialogs/desktop-properties.cpp:959 +#: ../../po/../src/ui/dialog/document-preferences.cpp:200 +msgid "Color of grid lines" +msgstr "Couleur de la grille" + +#: ../../po/../src/dialogs/desktop-properties.cpp:961 +#: ../../po/../src/ui/dialog/document-preferences.cpp:201 +msgid "Major grid line color:" +msgstr "Couleur de la grille majeure :" + +#: ../../po/../src/dialogs/desktop-properties.cpp:962 +#: ../../po/../src/ui/dialog/document-preferences.cpp:201 +msgid "Major grid line color" +msgstr "Couleur de la grille majeure" + +#: ../../po/../src/dialogs/desktop-properties.cpp:962 +#: ../../po/../src/ui/dialog/document-preferences.cpp:202 +msgid "Color of the major (highlighted) grid lines" +msgstr "Couleur de la grille majeure (mise en valeur)" + +#: ../../po/../src/dialogs/desktop-properties.cpp:965 +#: ../../po/../src/ui/dialog/document-preferences.cpp:204 +msgid "Major grid line every:" +msgstr "Majorer la grille toutes les :" + +#. TRANSLATORS: This belongs to the "Major grid line every:" string, +#. see grid settings in the "Document Preferences" dialog +#: ../../po/../src/dialogs/desktop-properties.cpp:977 +#: ../../po/../src/ui/dialog/document-preferences.cpp:204 +msgid "lines" +msgstr "lignes" + +#. Guidelines page +#: ../../po/../src/dialogs/desktop-properties.cpp:991 +#: ../../po/../src/ui/dialog/document-preferences.cpp:90 +msgid "Guides" +msgstr "Guides" + +#. / \todo FIXME: gray out snapping when guides are off +#. / Dissenting view: you want snapping without guides. +#: ../../po/../src/dialogs/desktop-properties.cpp:1000 +#: ../../po/../src/ui/dialog/document-preferences.cpp:234 +msgid "Show guides" +msgstr "Afficher les guides" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1000 +#: ../../po/../src/ui/dialog/document-preferences.cpp:234 +#: ../../po/../src/verbs.cpp:2116 +msgid "Show or hide guides" +msgstr "Afficher ou non les guides" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1001 +#: ../../po/../src/ui/dialog/document-preferences.cpp:235 +msgid "Snap bounding boxes to guides" +msgstr "Faire coller les boîtes de contour aux guides" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1002 +#: ../../po/../src/ui/dialog/document-preferences.cpp:238 +msgid "Snap points to guides" +msgstr "Faire coller les nœuds aux guides" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1020 +#: ../../po/../src/ui/dialog/document-preferences.cpp:243 +msgid "Guide color:" +msgstr "Couleur des guides :" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1021 +#: ../../po/../src/ui/dialog/document-preferences.cpp:243 +msgid "Guideline color" +msgstr "Couleur des lignes de guide" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1021 +#: ../../po/../src/ui/dialog/document-preferences.cpp:244 +msgid "Color of guidelines" +msgstr "Couleur des lignes de guide" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1023 +#: ../../po/../src/ui/dialog/document-preferences.cpp:245 +msgid "Highlight color:" +msgstr "Couleur d'emphase :" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1024 +#: ../../po/../src/ui/dialog/document-preferences.cpp:245 +msgid "Highlighted guideline color" +msgstr "Couleur d'emphase des lignes de guide" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1024 +#: ../../po/../src/ui/dialog/document-preferences.cpp:246 +msgid "Color of a guideline when it is under mouse" +msgstr "" +"Couleur d'une ligne de guide quand elle est sous le curseur de la souris" + +#. Page page +#: ../../po/../src/dialogs/desktop-properties.cpp:1029 +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:855 +#: ../../po/../src/ui/dialog/document-preferences.cpp:88 +#: ../../po/../src/widgets/desktop-widget.cpp:1061 +msgid "Page" +msgstr "Page" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1039 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +msgid "Background:" +msgstr "Couleur de fond :" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1040 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +msgid "Background color" +msgstr "Couleur de fond" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1041 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +msgid "" +"Color and transparency of the page background (also used for bitmap export)" +msgstr "" +"Couleur et transparence du fond de page (également utilisé lors de " +"l'exportation en bitmap)" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1045 +#: ../../po/../src/ui/dialog/document-preferences.cpp:147 +#, fuzzy +msgid "Show page border" +msgstr "Afficher la bordure du canevas" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1049 +#: ../../po/../src/ui/dialog/document-preferences.cpp:148 +msgid "Border on top of drawing" +msgstr "Bordure au-dessus du dessin" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1052 +#: ../../po/../src/ui/dialog/document-preferences.cpp:149 +msgid "Border color:" +msgstr "Couleur de la bordure :" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1053 +#: ../../po/../src/ui/dialog/document-preferences.cpp:149 +#, fuzzy +msgid "Page border color" +msgstr "Couleur de la bordure du canevas" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1054 +#: ../../po/../src/ui/dialog/document-preferences.cpp:150 +#, fuzzy +msgid "Color of the page border" +msgstr "Colorer la bordure du canevas" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1059 +#: ../../po/../src/ui/dialog/document-preferences.cpp:152 +msgid "Show page shadow" +msgstr "Afficher une ombre de la page" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1063 +#: ../../po/../src/ui/dialog/document-preferences.cpp:153 +msgid "Default units:" +msgstr "Unités par défaut :" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1069 +msgid "Units for the tool controls, ruler, and the statusbar" +msgstr "Unités pour les contrôles des outils, les règles et la barre d'état" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1086 +#: ../../po/../src/ui/widget/page-sizer.cpp:209 +#, fuzzy +msgid "Page size:" +msgstr "Taille du canevas :" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1110 +#: ../../po/../src/ui/widget/page-sizer.cpp:219 +msgid "Custom" +msgstr "Personnalisé" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1121 +#: ../../po/../src/ui/widget/page-sizer.cpp:225 +#, fuzzy +msgid "Page orientation:" +msgstr "Orientation du canevas :" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1133 +#: ../../po/../src/ui/widget/page-sizer.cpp:232 +msgid "Landscape" +msgstr "Paysage" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1139 +#: ../../po/../src/ui/widget/page-sizer.cpp:234 +msgid "Portrait" +msgstr "Portrait" + +#. Custom paper frame +#: ../../po/../src/dialogs/desktop-properties.cpp:1148 +#: ../../po/../src/ui/widget/page-sizer.cpp:249 +#, fuzzy +msgid "Custom size" +msgstr "Personnalisé" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1160 +#: ../../po/../src/dialogs/export.cpp:269 +#: ../../po/../src/ui/widget/page-sizer.cpp:261 +msgid "Units:" +msgstr "Unités :" + +#. Stroke width +#: ../../po/../src/dialogs/desktop-properties.cpp:1162 +#: ../../po/../src/dialogs/export.cpp:310 +#: ../../po/../src/dialogs/object-attributes.cpp:55 +#: ../../po/../src/dialogs/stroke-style.cpp:985 +#: ../../po/../src/ui/widget/page-sizer.cpp:262 +#: ../../po/../src/widgets/toolbox.cpp:1957 +msgid "Width:" +msgstr "Largeur :" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1183 +#: ../../po/../src/dialogs/export.cpp:326 +#: ../../po/../src/dialogs/export.cpp:431 +#: ../../po/../src/dialogs/object-attributes.cpp:56 +#: ../../po/../src/ui/widget/page-sizer.cpp:263 +msgid "Height:" +msgstr "Hauteur :" + +#. +#. * Ownership metadata tab +#. +#: ../../po/../src/dialogs/desktop-properties.cpp:1206 +msgid "Metadata" +msgstr "Métadonnées" + +#. add license selector pull-down +#: ../../po/../src/dialogs/desktop-properties.cpp:1225 +msgid "License" +msgstr "Licence" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1255 +msgid "Proprietary" +msgstr "Propriétaire" + +#: ../../po/../src/dialogs/display-settings.cpp:212 +msgid "When transforming, show:" +msgstr "Lors des transformations, afficher :" + +#: ../../po/../src/dialogs/display-settings.cpp:223 +msgid "Objects" +msgstr "Objets" + +#: ../../po/../src/dialogs/display-settings.cpp:224 +msgid "Show the actual objects when moving or transforming" +msgstr "Afficher les objets lors des déplacements ou des transformations" + +#: ../../po/../src/dialogs/display-settings.cpp:231 +msgid "Box outline" +msgstr "Boîte de contour" + +#: ../../po/../src/dialogs/display-settings.cpp:232 +msgid "Show only a box outline of the objects when moving or transforming" +msgstr "" +"N'afficher que les boîtes de contour des objets lors de leurs déplacements " +"ou transformations" + +#: ../../po/../src/dialogs/display-settings.cpp:238 +msgid "Per-object selection cue:" +msgstr "Poignée de sélection d'objet :" + +#. sorationsnapsperpi == 0 means no snapping +#: ../../po/../src/dialogs/display-settings.cpp:249 +#: ../../po/../src/dialogs/display-settings.cpp:386 +#: ../../po/../src/dialogs/display-settings.cpp:441 +#: ../../po/../src/dialogs/display-settings.cpp:1482 +#: ../../po/../src/dialogs/stroke-style.cpp:791 +#: ../../po/../src/interface.cpp:741 +#: ../../po/../src/ui/widget/selected-style.cpp:100 +#: ../../po/../src/verbs.cpp:1842 +msgid "None" +msgstr "Aucun" + +#: ../../po/../src/dialogs/display-settings.cpp:250 +msgid "No per-object selection indication" +msgstr "Pas d'indication de sélection d'objet" + +#: ../../po/../src/dialogs/display-settings.cpp:256 +msgid "Mark" +msgstr "Marque" + +#: ../../po/../src/dialogs/display-settings.cpp:257 +msgid "Each selected object has a diamond mark in the top left corner" +msgstr "" +"Tous les objets sélectionnés sont marqués d'un losange dans leur coin en " +"haut à gauche" + +#: ../../po/../src/dialogs/display-settings.cpp:264 +msgid "Box" +msgstr "Boîte" + +#: ../../po/../src/dialogs/display-settings.cpp:265 +msgid "Each selected object displays its bounding box" +msgstr "Tous les objets sélectionnés affichent leurs boîtes de contour" + +#: ../../po/../src/dialogs/display-settings.cpp:270 +msgid "Default scale origin:" +msgstr "Origine par défaut du redimensionnement :" + +#: ../../po/../src/dialogs/display-settings.cpp:281 +msgid "Opposite bounding box edge" +msgstr "Arrête opposée de la boîte de contour" + +#: ../../po/../src/dialogs/display-settings.cpp:282 +msgid "Default scale origin will be on the bounding box of the item" +msgstr "" +"L'origine par défaut du redimensionnement sera sur la boîte de contour de " +"l'item" + +#: ../../po/../src/dialogs/display-settings.cpp:288 +msgid "Farthest opposite node" +msgstr "Nœud opposé le plus éloigné" + +#: ../../po/../src/dialogs/display-settings.cpp:289 +msgid "Default scale origin will be on the bounding box of the item's points" +msgstr "" +"L'origine par défaut du redimensionnement sera sur la boîte de contour des " +"points de l'item" + +#: ../../po/../src/dialogs/display-settings.cpp:341 +msgid "degrees" +msgstr "degrés" + +#: ../../po/../src/dialogs/display-settings.cpp:350 +msgid "" +"Rotating with Ctrl pressed snaps every that much degrees; also, pressing " +"[ or ] rotates by this amount" +msgstr "" +"Ctrl appuyé forcera des rotations de tant de degrés; de même en appuyant sur " +"[ ou ], les rotations se feront selon cet incrément" + +#: ../../po/../src/dialogs/display-settings.cpp:407 +msgid "Rotation snaps every:" +msgstr "Incrément de rotation :" + +#: ../../po/../src/dialogs/display-settings.cpp:430 +msgid "" +"None: dialogs are treated as regular windows; Normal: dialogs stay on top of " +"document windows; Aggressive: same as Normal but may work better with some " +"window managers." +msgstr "" +"Aucun : les boîtes de dialogue sont traités comme des fenêtres standard. " +"Normal : les les boîtes de dialogue restent au-dessus de la fenêtre du " +"document. Agressif : comme Normal, mais fonctionne mieux avec certains " +"gestionnaires de fenêtre." + +#: ../../po/../src/dialogs/display-settings.cpp:451 +msgid "Normal" +msgstr "Normal" + +#: ../../po/../src/dialogs/display-settings.cpp:461 +msgid "Aggressive" +msgstr "Agressif" + +#: ../../po/../src/dialogs/display-settings.cpp:475 +msgid "Dialogs on top:" +msgstr "Dialogues au-dessus de la fenêtre:" + +#: ../../po/../src/dialogs/display-settings.cpp:645 +msgid "Show selection cue" +msgstr "Afficher les poignées de sélection" + +#: ../../po/../src/dialogs/display-settings.cpp:646 +msgid "" +"Whether selected objects display a selection cue (the same as in selector)" +msgstr "" +"L'objet sélectionné affiche ses poignées de sélection (les mêmes que dans le " +"sélecteur)" + +#: ../../po/../src/dialogs/display-settings.cpp:657 +msgid "Enable gradient editing" +msgstr "Activer l'édition de dégradé" + +#: ../../po/../src/dialogs/display-settings.cpp:658 +msgid "Whether selected objects display gradient editing controls" +msgstr "" +"A cocher pour que les objets sélectionnés affichent leurs poignées d'édition " +"de dégradés" + +#: ../../po/../src/dialogs/display-settings.cpp:719 +msgid "No objects selected to take the style from." +msgstr "Pas d'objet sélectionné pour en capturer le style." + +#: ../../po/../src/dialogs/display-settings.cpp:728 +msgid "" +"More than one object selected. Cannot take style from multiple " +"objects." +msgstr "" +"Plus d'un objet est sélectionné. Impossible de capturer le style de " +"plusieurs objets." + +#: ../../po/../src/dialogs/display-settings.cpp:767 +msgid "Create new objects with:" +msgstr "Créer de nouveaux objets avec :" + +#: ../../po/../src/dialogs/display-settings.cpp:777 +msgid "Take from selection" +msgstr "Capturer depuis la sélection" + +#: ../../po/../src/dialogs/display-settings.cpp:778 +msgid "Remember the style of the (first) selected object as this tool's style" +msgstr "Retenir le style du premier objet sélectionné comme style de cet outil" + +#: ../../po/../src/dialogs/display-settings.cpp:782 +#, fuzzy +msgid "Last used style" +msgstr "Coller le _style" + +#: ../../po/../src/dialogs/display-settings.cpp:782 +msgid "Apply the style you last set on an object" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:790 +msgid "This tool's own style:" +msgstr "Style propre à l'outil :" + +#: ../../po/../src/dialogs/display-settings.cpp:790 +msgid "" +"Each tool may store its own style to apply to the newly created objects. Use " +"the button below to set it." +msgstr "" +"Chaque outil retient son propre style à appliquer aux nouveaux objets créés. " +"Cocher le bouton ci-dessous pour définir ceci." + +#. Mouse +#: ../../po/../src/dialogs/display-settings.cpp:877 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:55 +msgid "Mouse" +msgstr "Souris" + +#. TRANSLATORS: "Grab" is a noun here. "Grab sensitivity" is intended to mean how +#. * close on the screen you need to be to an object to be able to grab it with mouse (in +#. * pixels). +#: ../../po/../src/dialogs/display-settings.cpp:883 +msgid "Grab sensitivity:" +msgstr "Sensibilité :" + +#: ../../po/../src/dialogs/display-settings.cpp:884 +msgid "" +"How close on the screen you need to be to an object to be able to grab it " +"with mouse (in screen pixels)" +msgstr "" +"Distance à l'écran à partir de la quelle peut saisir un objet avec la souris " +"(en pixels à l'écran)" + +#: ../../po/../src/dialogs/display-settings.cpp:885 +#: ../../po/../src/dialogs/display-settings.cpp:897 +#: ../../po/../src/dialogs/display-settings.cpp:912 +#: ../../po/../src/dialogs/display-settings.cpp:930 +#: ../../po/../src/dialogs/display-settings.cpp:970 +msgid "pixels" +msgstr "pixels" + +#: ../../po/../src/dialogs/display-settings.cpp:895 +msgid "Click/drag threshold:" +msgstr "Seuil de cliquer-déplacer :" + +#: ../../po/../src/dialogs/display-settings.cpp:896 +msgid "" +"Maximum mouse drag (in screen pixels) which is considered a click, not a drag" +msgstr "" +"Déplacement maximal de la souris (en pixels à l'écran) considéré comme un " +"clic et non un déplacement" + +#. Scrolling +#: ../../po/../src/dialogs/display-settings.cpp:907 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:56 +msgid "Scrolling" +msgstr "Défilement" + +#: ../../po/../src/dialogs/display-settings.cpp:910 +msgid "Mouse wheel scrolls by:" +msgstr "La molette de la souris défile de :" + +#: ../../po/../src/dialogs/display-settings.cpp:911 +msgid "" +"One mouse wheel notch scrolls by this distance in screen pixels " +"(horizontally with Shift)" +msgstr "" +"Un cran de la molette de la souris fait défiler de tant de pixels " +"(horizontalement avec Maj)" + +#: ../../po/../src/dialogs/display-settings.cpp:920 +msgid "Ctrl+arrows" +msgstr "Ctrl+flèches" + +#: ../../po/../src/dialogs/display-settings.cpp:928 +msgid "Scroll by:" +msgstr "Défiler de :" + +#: ../../po/../src/dialogs/display-settings.cpp:929 +msgid "Pressing Ctrl+arrow key scrolls by this distance (in screen pixels)" +msgstr "" +"Appuyer sur Ctrl+flèches fait défiler de cette distance (en pixels à l'écran)" + +#: ../../po/../src/dialogs/display-settings.cpp:939 +msgid "Acceleration:" +msgstr "Accélération :" + +#: ../../po/../src/dialogs/display-settings.cpp:940 +msgid "" +"Pressing and holding Ctrl+arrow will gradually speed up scrolling (0 for no " +"acceleration)" +msgstr "" +"Garder appuyé Ctrl+flèches accélère graduellement la vitesse du défilement " +"(0 pour aucune accélération)" + +#: ../../po/../src/dialogs/display-settings.cpp:949 +msgid "Autoscrolling" +msgstr "Défilement automatique" + +#: ../../po/../src/dialogs/display-settings.cpp:957 +msgid "Speed:" +msgstr "Vitesse :" + +#: ../../po/../src/dialogs/display-settings.cpp:958 +msgid "" +"How fast the canvas autoscrolls when you drag beyond canvas edge (0 to turn " +"autoscroll off)" +msgstr "" +"Vitesse du défilement automatique du canevas lors que l'on tire un objet au " +"dehors du canevas (0 pour aucun autodéfilement)" + +#: ../../po/../src/dialogs/display-settings.cpp:968 +#: ../../po/../src/ui/dialog/tracedialog.cpp:357 +#: ../../po/../src/ui/dialog/tracedialog.cpp:390 +msgid "Threshold:" +msgstr "Seuil :" + +#: ../../po/../src/dialogs/display-settings.cpp:969 +msgid "" +"How far (in screen pixels) you need to be from the canvas edge to trigger " +"autoscroll; positive is outside the canvas, negative is within the canvas" +msgstr "" +"Distance (en pixels à l'écran) à laquelle il faut être du bord du canevas " +"pour activer le défilement automatique; les valeurs positives sont en dehors " +"du canevas, les négatives à l'intérieur" + +#. Steps +#: ../../po/../src/dialogs/display-settings.cpp:979 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:57 +msgid "Steps" +msgstr "Incréments" + +#: ../../po/../src/dialogs/display-settings.cpp:982 +msgid "Arrow keys move by:" +msgstr "Les flèches déplacent de :" + +#: ../../po/../src/dialogs/display-settings.cpp:983 +msgid "" +"Pressing an arrow key moves selected object(s) or node(s) by this distance " +"(in px units)" +msgstr "" +"Appuyer sur une flèche déplace les objet(s) ou les nœud(s) sélectionnés de " +"cette distance (en px ou pixels SVG)" + +#: ../../po/../src/dialogs/display-settings.cpp:984 +#: ../../po/../src/dialogs/display-settings.cpp:995 +#: ../../po/../src/dialogs/display-settings.cpp:1006 +#: ../../po/../src/helper/units.cpp:42 +msgid "px" +msgstr "px" + +#: ../../po/../src/dialogs/display-settings.cpp:993 +msgid "> and < scale by:" +msgstr "> et < redimensionnent de :" + +#: ../../po/../src/dialogs/display-settings.cpp:994 +msgid "" +"Pressing > or < scales selection up or down by this increment (in px units)" +msgstr "" +"Appuyer sur > ou < redimensionne de cet incrément (en px ou pixels SVG)" + +#: ../../po/../src/dialogs/display-settings.cpp:1004 +msgid "Inset/Outset by:" +msgstr "Éroder/dilater de :" + +#: ../../po/../src/dialogs/display-settings.cpp:1005 +msgid "" +"Inset and Outset commands displace the path by this distance (in px units)" +msgstr "" +"Les commandes éroder et dilater déplacent le chemin de cette distance (en px " +"ou pixels SVG)" + +#: ../../po/../src/dialogs/display-settings.cpp:1017 +msgid "Compass-like display of angles" +msgstr "Afficher les angles comme sur une boussole" + +#. TRANSLATORS: "positive clockwise" means "increasing in clockwise direction" +#: ../../po/../src/dialogs/display-settings.cpp:1019 +msgid "" +"When on, angles are displayed with 0 at north, 0 to 360 range, positive " +"clockwise; otherwise with 0 at east, -180 to 180 range, positive " +"counterclockwise" +msgstr "" +"A cocher pour que les angles soient affichés en sens horaire de 0 (au nord) " +"à 360; à décocher pour qu'ils soient affichés de -180 à 180 en sens anti-" +"horaire (0 étant à l'est)" + +#: ../../po/../src/dialogs/display-settings.cpp:1026 +msgid "Zoom in/out by:" +msgstr "(Dé)Zoommer de :" + +#: ../../po/../src/dialogs/display-settings.cpp:1027 +msgid "" +"Zoom tool click, +/- keys, and middle click zoom in and out by this " +"multiplier" +msgstr "" +"Les outils de zoom (clic en mode zoom, touches +/-, clic bouton du milieu) " +"zoomment ou dézoomment selon ce facteur" + +#: ../../po/../src/dialogs/display-settings.cpp:1028 +#: ../../po/../src/helper/units.cpp:44 +msgid "%" +msgstr "%" + +#. Tools +#: ../../po/../src/dialogs/display-settings.cpp:1037 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:58 +msgid "Tools" +msgstr "Outils" + +#: ../../po/../src/dialogs/display-settings.cpp:1045 +msgid "Selector" +msgstr "Sélecteur" + +#: ../../po/../src/dialogs/display-settings.cpp:1056 +msgid "Node" +msgstr "Noeud" + +#: ../../po/../src/dialogs/display-settings.cpp:1064 +#: ../../po/../src/verbs.cpp:2073 +#: ../../po/../src/widgets/desktop-widget.cpp:277 +msgid "Zoom" +msgstr "Zoom" + +#. The 4 shape tools +#: ../../po/../src/dialogs/display-settings.cpp:1071 +msgid "Shapes" +msgstr "Formes" + +#: ../../po/../src/dialogs/display-settings.cpp:1079 +#: ../../po/../src/verbs.cpp:2055 +msgid "Rectangle" +msgstr "Rectangle" + +#: ../../po/../src/dialogs/display-settings.cpp:1085 +#: ../../po/../src/verbs.cpp:2057 +msgid "Ellipse" +msgstr "Ellipse" + +#: ../../po/../src/dialogs/display-settings.cpp:1091 +#: ../../po/../src/verbs.cpp:2059 +msgid "Star" +msgstr "Étoile" + +#: ../../po/../src/dialogs/display-settings.cpp:1097 +#: ../../po/../src/verbs.cpp:2061 +msgid "Spiral" +msgstr "Spirale" + +#: ../../po/../src/dialogs/display-settings.cpp:1111 +#: ../../po/../src/verbs.cpp:2063 +msgid "Pencil" +msgstr "Crayon" + +#: ../../po/../src/dialogs/display-settings.cpp:1114 +msgid "Tolerance:" +msgstr "Tolérance :" + +#: ../../po/../src/dialogs/display-settings.cpp:1115 +msgid "" +"This value affects the amount of smoothing applied to freehand lines; lower " +"values produce more uneven paths with more nodes" +msgstr "" +"Cette valeur affecte le lissage appliqué aux lignes à main levés; les " +"valeurs faibles produisent des chemins irréguliers avec plus de nœuds" + +#: ../../po/../src/dialogs/display-settings.cpp:1131 +#: ../../po/../src/verbs.cpp:2065 +msgid "Pen" +msgstr "Stylo" + +#: ../../po/../src/dialogs/display-settings.cpp:1140 +#: ../../po/../src/verbs.cpp:2067 +msgid "Calligraphy" +msgstr "Plume calligraphique" + +#: ../../po/../src/dialogs/display-settings.cpp:1147 +#: ../../po/../src/dialogs/text-edit.cpp:353 +#: ../../po/../src/ui/dialog/text-properties.cpp:37 +#: ../../po/../src/verbs.cpp:2069 +msgid "Text" +msgstr "Texte" + +#: ../../po/../src/dialogs/display-settings.cpp:1157 +#: ../../po/../src/verbs.cpp:2071 +msgid "Gradient" +msgstr "Dégradé" + +#: ../../po/../src/dialogs/display-settings.cpp:1164 +#: ../../po/../src/verbs.cpp:2077 +msgid "Connector" +msgstr "Connecteur" + +#: ../../po/../src/dialogs/display-settings.cpp:1171 +#: ../../po/../src/verbs.cpp:2075 +msgid "Dropper" +msgstr "Pipette" + +#. Windows +#: ../../po/../src/dialogs/display-settings.cpp:1183 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:59 +msgid "Windows" +msgstr "Fenêtres" + +#: ../../po/../src/dialogs/display-settings.cpp:1188 +msgid "Save window geometry" +msgstr "Enregistrer la taille et la position de la fenêtre" + +#: ../../po/../src/dialogs/display-settings.cpp:1189 +msgid "" +"Save the window size and position with each document (only for Inkscape SVG " +"format)" +msgstr "" +"Enregistrer la taille et la position de la fenêtre avec chaque document " +"(seulement pour le format SVG d'Inkscape)" + +#: ../../po/../src/dialogs/display-settings.cpp:1196 +msgid "Dialogs are hidden in taskbar" +msgstr "Les boîtes de dialogue sont cachés dans la barre des tâches" + +#: ../../po/../src/dialogs/display-settings.cpp:1197 +msgid "Whether dialog windows are to be hidden in the window manager taskbar" +msgstr "" +"Les boîtes de dialogue sont cachées dans la barre des tâches du gestionnaire " +"de fenêtre" + +#: ../../po/../src/dialogs/display-settings.cpp:1204 +msgid "Zoom when window is resized" +msgstr "Zoommer quand la fenêtre est redimensionnée" + +#: ../../po/../src/dialogs/display-settings.cpp:1205 +msgid "" +"Zoom drawing when document window is resized, to keep the same area visible " +"(this is the default which can be changed in any window using the button " +"above the right scrollbar)" +msgstr "" +"Le dessin est rezoommé quand la fenêtre est redimensionnée, pour garder " +"visible la même aire (c'est l'option par défaut qui peut être changée dans " +"toute fenêtre en utilisant le boutton au dessus de la barre de défilement de " +"droite)" + +#. Clones +#: ../../po/../src/dialogs/display-settings.cpp:1213 +#: ../../po/../src/dialogs/find.cpp:624 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:60 +msgid "Clones" +msgstr "Clones" + +#: ../../po/../src/dialogs/display-settings.cpp:1217 +msgid "When the original moves, its clones and linked offsets:" +msgstr "Lorsque l'original est déplacé, ses clones et offsets liés :" + +#: ../../po/../src/dialogs/display-settings.cpp:1229 +msgid "Move in parallel" +msgstr "Sont déplacés en parallèle" + +#: ../../po/../src/dialogs/display-settings.cpp:1230 +msgid "Clones are translated by the same vector as their original." +msgstr "Les clones sont déplacés du même vecteur que leur original." + +#: ../../po/../src/dialogs/display-settings.cpp:1237 +msgid "Stay unmoved" +msgstr "Ne bougent pas" + +#: ../../po/../src/dialogs/display-settings.cpp:1238 +msgid "Clones preserve their positions when their original is moved." +msgstr "Les clones restent sur place quand leur original est déplacé." + +#: ../../po/../src/dialogs/display-settings.cpp:1245 +msgid "Move according to transform" +msgstr "Déplacés en fonction leurs transformations" + +#: ../../po/../src/dialogs/display-settings.cpp:1246 +msgid "" +"Each clone moves according to the value of its transform= attribute. For " +"example, a rotated clone will move in a different direction than its " +"original." +msgstr "" +"Chaque clone est déplacé en fonction de son attribut ‘transform’. Par " +"exemple, un clone qui a déjà été tourné sera déplacé dans une direction " +"différente de celle de son original." + +#: ../../po/../src/dialogs/display-settings.cpp:1255 +msgid "When the original is deleted, its clones:" +msgstr "Lors que l'original est supprimé, ses clones :" + +#: ../../po/../src/dialogs/display-settings.cpp:1267 +msgid "Are unlinked" +msgstr "Sont déliés" + +#: ../../po/../src/dialogs/display-settings.cpp:1267 +msgid "Orphaned clones are converted to regular objects." +msgstr "Les clones orphelins sont convertis en objets normaux." + +#: ../../po/../src/dialogs/display-settings.cpp:1273 +msgid "Are deleted" +msgstr "Sont supprimés" + +#: ../../po/../src/dialogs/display-settings.cpp:1273 +msgid "Orphaned clones are deleted along with their original." +msgstr "Les clones orphelins sont supprimés en même temps que leur original." + +#. Transforms +#. TRANSLATORS: Noun, i.e. transformations. +#: ../../po/../src/dialogs/display-settings.cpp:1289 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:61 +msgid "Transforms" +msgstr "Transformations" + +#: ../../po/../src/dialogs/display-settings.cpp:1292 +msgid "Scale stroke width" +msgstr "Mettre à l'échelle la largeur du contour" + +#: ../../po/../src/dialogs/display-settings.cpp:1293 +#: ../../po/../src/widgets/select-toolbar.cpp:568 +msgid "When scaling objects, scale the stroke width by the same proportion" +msgstr "" +"Lors d'un redimensionnement des objets, préserver la proportion des largeurs " +"des contours" + +#: ../../po/../src/dialogs/display-settings.cpp:1300 +msgid "Scale rounded corners in rectangles" +msgstr "Mettre à l'échelle les coins arrondis des rectangles" + +#: ../../po/../src/dialogs/display-settings.cpp:1301 +#: ../../po/../src/widgets/select-toolbar.cpp:580 +msgid "When scaling rectangles, scale the radii of rounded corners" +msgstr "" +"Lors du redimensionnements d'un rectangle, préserver la proportion des " +"rayons des coins arrondis" + +#: ../../po/../src/dialogs/display-settings.cpp:1308 +msgid "Transform gradients" +msgstr "Transformer les dégradés" + +#: ../../po/../src/dialogs/display-settings.cpp:1309 +#: ../../po/../src/widgets/select-toolbar.cpp:592 +msgid "Transform gradients (in fill or stroke) along with the objects" +msgstr "Transformer les dégradés avec les objets (remplissage et contour)" + +#: ../../po/../src/dialogs/display-settings.cpp:1316 +msgid "Transform patterns" +msgstr "Transformer les motifs de remplissage" + +#: ../../po/../src/dialogs/display-settings.cpp:1317 +#: ../../po/../src/widgets/select-toolbar.cpp:604 +msgid "Transform patterns (in fill or stroke) along with the objects" +msgstr "" +"Transformer les motifs de remplissage avec les objets (remplissage et " +"contour)" + +#. TRANSLATORS: How to specify the affine transformation in the SVG file. +#: ../../po/../src/dialogs/display-settings.cpp:1327 +msgid "Store transformation:" +msgstr "Enregistrement des transformations :" + +#: ../../po/../src/dialogs/display-settings.cpp:1338 +msgid "Optimized" +msgstr "Optimisé" + +#: ../../po/../src/dialogs/display-settings.cpp:1339 +msgid "" +"If possible, apply transformation to objects without adding a transform= " +"attribute" +msgstr "" +"Si possible, appliquer des transformations aux objets sans ajouter " +"l'attribut ‘transform’" + +#: ../../po/../src/dialogs/display-settings.cpp:1346 +msgid "Preserved" +msgstr "Préservé" + +#: ../../po/../src/dialogs/display-settings.cpp:1347 +msgid "Always store transformation as a transform= attribute on objects" +msgstr "" +"Toujours enregistrer les transformations dans l'attribut ‘transform’ des " +"objets" + +#. Selecting +#: ../../po/../src/dialogs/display-settings.cpp:1355 +msgid "Selecting" +msgstr "Sélection" + +#: ../../po/../src/dialogs/display-settings.cpp:1357 +msgid "Ctrl+A, Tab, Shift+Tab:" +msgstr "Ctrl+A, Tab, Maj+Tab :" + +#: ../../po/../src/dialogs/display-settings.cpp:1366 +msgid "Select only within current layer" +msgstr "Ne sélectionner que dans le calque courant" + +#: ../../po/../src/dialogs/display-settings.cpp:1367 +msgid "" +"Uncheck this to make keyboard selection commands work on objects in all " +"layers" +msgstr "" +"A décocher pour permettre la sélection de tout objet dans tout calque via " +"les raccourcis clavier" + +#: ../../po/../src/dialogs/display-settings.cpp:1374 +msgid "Ignore hidden objects" +msgstr "Ignorer les objets cachés" + +#: ../../po/../src/dialogs/display-settings.cpp:1375 +msgid "" +"Uncheck this to be able to select objects that are hidden (either by " +"themselves or by being in a hidden group or layer)" +msgstr "" +"A décocher pour pouvoir sélectionner les objets cachés (objets cachés ou " +"appartenant à un groupe ou calque caché)" + +#: ../../po/../src/dialogs/display-settings.cpp:1382 +msgid "Ignore locked objects" +msgstr "Ignorer les objets verrouillés" + +#: ../../po/../src/dialogs/display-settings.cpp:1383 +msgid "" +"Uncheck this to be able to select objects that are locked (either by " +"themselves or by being in a locked group or layer)" +msgstr "" +"A décocher pour pouvoir sélectionner les objets verrouillés (objets " +"verrouillés ou appartenant à un groupe ou calque verrouillé)" + +#. To be broken into: Display, Save, Export, SVG, Commands +#: ../../po/../src/dialogs/display-settings.cpp:1391 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:62 +msgid "Misc" +msgstr "Divers" + +#: ../../po/../src/dialogs/display-settings.cpp:1394 +msgid "Default export resolution:" +msgstr "Résolution par défaut d'exportation :" + +#: ../../po/../src/dialogs/display-settings.cpp:1395 +msgid "Default bitmap resolution (in dots per inch) in the Export dialog" +msgstr "" +"Résolution par défaut (point par pouce) dans la boîte de dialogue exporter" + +#. FIXME: add "Used for new exports; once exported, documents remember this value on per-object basis" when implemented +#: ../../po/../src/dialogs/display-settings.cpp:1396 +#: ../../po/../src/dialogs/export.cpp:442 +msgid "dpi" +msgstr "ppp" + +#. TRANSLATORS: When on, an imported bitmap creates an element; otherwise it is a +#. * rectangle with bitmap fill. +#: ../../po/../src/dialogs/display-settings.cpp:1407 +msgid "Import bitmap as " +msgstr "Importer le bitmap en tant qu'" + +#: ../../po/../src/dialogs/display-settings.cpp:1408 +msgid "" +"When on, an imported bitmap creates an element; otherwise it is a " +"rectangle with bitmap fill" +msgstr "" +"A cocher pour que l'import d'un bitmap crée un élément ; décocher " +"pour un rectangle rempli avec le bitmap" + +#. TRANSLATORS: When on, the print out (currently Postscript) will have +#. * a comment with the each object's label visible, marking the section +#. * of the printing commands that represent the given object. +#: ../../po/../src/dialogs/display-settings.cpp:1418 +msgid "Add label comments to printing output" +msgstr "Ajouter les labels de commentaires à l'impression" + +#: ../../po/../src/dialogs/display-settings.cpp:1419 +msgid "" +"When on, a comment will be added to the raw print output, marking the " +"rendered output for an object with its label" +msgstr "" +"A cocher pour qu'un commentaire soit ajouté à l'impression brute, signalant " +"le rendu pour un objet avec ce label" + +#. TRANSLATORS: When on, enable the effects menu, default is off +#: ../../po/../src/dialogs/display-settings.cpp:1427 +msgid "Enable script effects (requires restart) - EXPERIMENTAL" +msgstr "Activer les scripts d'effets (redémarrer l'application) - EXPERIMENTAL" + +#: ../../po/../src/dialogs/display-settings.cpp:1428 +msgid "" +"When on, the effects menu is enabled, allowing external effect scripts to be " +"called, requires restart before effective - EXPERIMENTAL" +msgstr "" +"Cocher pour que le menu des effets soit activé, permettant l'appel de " +"scripts externes. Nécessite de redémarrer l'application pour prendre effet - " +"EXPERIMENTAL" + +#. TRANSLATORS: The maximum length of the Open Recent list in the File menu. +#: ../../po/../src/dialogs/display-settings.cpp:1436 +msgid "Max recent documents:" +msgstr "Nombre maximum de documents récents :" + +#: ../../po/../src/dialogs/display-settings.cpp:1437 +msgid "The maximum length of the Open Recent list in the File menu" +msgstr "" +"La taille maximum de la liste «Récemment ouvert» dans le menu «Fichier»" + +#: ../../po/../src/dialogs/display-settings.cpp:1447 +msgid "Simplification threshold:" +msgstr "Seuil de simplification :" + +#: ../../po/../src/dialogs/display-settings.cpp:1448 +msgid "" +"How strong is the Simplify command by default. If you invoke this command " +"several times in quick succession, it will act more and more aggressively; " +"invoking it again after a pause restores the default threshold." +msgstr "" +"Force par défaut de la commande Simplifier. En faisant appel à cette " +"commande plusieurs fois de suite, elle agira de façon de plus en plus " +"agressive; un appel après une pause restaurera la valeur par défaut." + +#: ../../po/../src/dialogs/display-settings.cpp:1469 +msgid "Oversample bitmaps:" +msgstr "Sur-échantilloner les bitmaps :" + +#: ../../po/../src/dialogs/display-settings.cpp:1488 +msgid "2x2" +msgstr "2x2" + +#: ../../po/../src/dialogs/display-settings.cpp:1494 +msgid "4x4" +msgstr "4x4" + +#: ../../po/../src/dialogs/display-settings.cpp:1500 +msgid "8x8" +msgstr "8x8" + +#: ../../po/../src/dialogs/display-settings.cpp:1506 +msgid "16x16" +msgstr "16x16" + +#. "view_icon_preview" +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2143 +msgid "_Page" +msgstr "_Page" + +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2147 +msgid "_Drawing" +msgstr "_Dessin" + +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2149 +msgid "_Selection" +msgstr "_Sélection" + +#: ../../po/../src/dialogs/export.cpp:133 +msgid "_Custom" +msgstr "Personnalisé (_c)" + +#: ../../po/../src/dialogs/export.cpp:254 +msgid "Export area" +msgstr "Exporter la zone" + +#: ../../po/../src/dialogs/export.cpp:300 +msgid "_x0:" +msgstr "_x0 :" + +#: ../../po/../src/dialogs/export.cpp:305 +msgid "x_1:" +msgstr "x_1 :" + +#: ../../po/../src/dialogs/export.cpp:316 +msgid "_y0:" +msgstr "_y0 :" + +#: ../../po/../src/dialogs/export.cpp:321 +msgid "y_1:" +msgstr "y_1 :" + +#: ../../po/../src/dialogs/export.cpp:406 +msgid "Bitmap size" +msgstr "Taille du bitmap" + +#: ../../po/../src/dialogs/export.cpp:416 +msgid "_Width:" +msgstr "Largeur (_w):" + +#: ../../po/../src/dialogs/export.cpp:416 +#: ../../po/../src/dialogs/export.cpp:431 +msgid "pixels at" +msgstr "pixels à" + +#: ../../po/../src/dialogs/export.cpp:426 +msgid "dp_i" +msgstr "ppp (_i)" + +#: ../../po/../src/dialogs/export.cpp:448 +msgid "_Filename" +msgstr "Nom du _fichier" + +#: ../../po/../src/dialogs/export.cpp:512 +msgid "_Browse..." +msgstr "Parcourir (_b)..." + +#: ../../po/../src/dialogs/export.cpp:539 +msgid " _Export " +msgstr " _Exporter " + +#: ../../po/../src/dialogs/export.cpp:541 +msgid "Export the bitmap file with these settings" +msgstr "Exporter le fichier bitmap avec ces réglages" + +#: ../../po/../src/dialogs/export.cpp:968 +msgid "You have to enter a filename" +msgstr "Vous devez entrer un nom de fichier" + +#: ../../po/../src/dialogs/export.cpp:973 +msgid "The chosen area to be exported is invalid" +msgstr "La zone d'exportation choisie est invalide" + +#: ../../po/../src/dialogs/export.cpp:982 +#, c-format +msgid "Directory %s does not exist or is not a directory.\n" +msgstr "Le répertoire %s n'existe pas ou ce n'est pas un répertoire.\n" + +#: ../../po/../src/dialogs/export.cpp:998 +msgid "Export in progress" +msgstr "Exportation en cours" + +#: ../../po/../src/dialogs/export.cpp:1004 +#, c-format +msgid "Exporting %s (%d x %d)" +msgstr "Export %s (%d x %d)" + +#: ../../po/../src/dialogs/export.cpp:1031 +#, c-format +msgid "Could not export to filename %s.\n" +msgstr "Impossible d'exporter dans le fichier %s.\n" + +#: ../../po/../src/dialogs/export.cpp:1137 +msgid "Select a filename for exporting" +msgstr "Sélectionner un nom de fichier pour exporter" + +#: ../../po/../src/dialogs/filedialog.cpp:367 +msgid "No preview" +msgstr "Pas d'aperçu" + +#: ../../po/../src/dialogs/filedialog.cpp:468 +msgid "too large for preview" +msgstr "trop grand pour un aperçu" + +#: ../../po/../src/dialogs/filedialog.cpp:762 +#: ../../po/../src/dialogs/filedialog.cpp:763 +msgid "All Images" +msgstr "Toutes les images" + +#: ../../po/../src/dialogs/filedialog.cpp:767 +#: ../../po/../src/dialogs/filedialog.cpp:768 +msgid "All Files" +msgstr "Tous les fichiers" + +#: ../../po/../src/dialogs/filedialog.cpp:774 +#: ../../po/../src/dialogs/filedialog.cpp:775 +msgid "All Inkscape Files" +msgstr "Tous les fichiers Inkscape" + +#: ../../po/../src/dialogs/filedialog.cpp:1176 +msgid "Guess from extension" +msgstr "Selon l'extension" + +#. ###### Add the file types menu +#. createFilterMenu(); +#. ###### Do we want the .xxx extension automatically added? +#: ../../po/../src/dialogs/filedialog.cpp:1261 +msgid "Append filename extension automatically" +msgstr "Ajouter automatiquement une extension aux noms de fichiers" + +#. TRANSLATORS: "%s" is replaced with "exact" or "partial" when this string is displayed +#: ../../po/../src/dialogs/find.cpp:378 +#, c-format +msgid "%d object found (out of %d), %s match." +msgid_plural "%d objects found (out of %d), %s match." +msgstr[0] "%d objet trouvé (sur %d), correspondance %s." +msgstr[1] "%d objets trouvés (sur %d), correspondance %s." + +#: ../../po/../src/dialogs/find.cpp:381 +msgid "exact" +msgstr "exacte" + +#: ../../po/../src/dialogs/find.cpp:381 +msgid "partial" +msgstr "partielle" + +#: ../../po/../src/dialogs/find.cpp:388 +msgid "No objects found" +msgstr "Pas d'objet trouvé" + +#: ../../po/../src/dialogs/find.cpp:546 +msgid "T_ype: " +msgstr "T_ype : " + +#: ../../po/../src/dialogs/find.cpp:553 +msgid "Search in all object types" +msgstr "Rechercher dans tous les types d'objets" + +#: ../../po/../src/dialogs/find.cpp:553 +msgid "All types" +msgstr "Tous les types" + +#: ../../po/../src/dialogs/find.cpp:564 +msgid "Search all shapes" +msgstr "Rechercher toutes les formes" + +#: ../../po/../src/dialogs/find.cpp:564 +msgid "All shapes" +msgstr "Toutes les formes" + +#: ../../po/../src/dialogs/find.cpp:581 +msgid "Search rectangles" +msgstr "Rechercher les rectangle" + +#: ../../po/../src/dialogs/find.cpp:581 +msgid "Rectangles" +msgstr "Rectangles" + +#: ../../po/../src/dialogs/find.cpp:586 +msgid "Search ellipses, arcs, circles" +msgstr "Rechercher les ellipses, arcs, cercles" + +#: ../../po/../src/dialogs/find.cpp:586 +msgid "Ellipses" +msgstr "Ellipses" + +#: ../../po/../src/dialogs/find.cpp:591 +msgid "Search stars and polygons" +msgstr "Rechercher les étoiles et les polygones" + +#: ../../po/../src/dialogs/find.cpp:591 +msgid "Stars" +msgstr "Étoiles" + +#: ../../po/../src/dialogs/find.cpp:596 +msgid "Search spirals" +msgstr "Rechercher les spirales" + +#: ../../po/../src/dialogs/find.cpp:596 +msgid "Spirals" +msgstr "Spirales" + +#. TRANSLATORS: polyline is a set of connected straight line segments +#. http://www.w3.org/TR/SVG11/shapes.html#PolylineElement +#: ../../po/../src/dialogs/find.cpp:609 +msgid "Search paths, lines, polylines" +msgstr "Rechercher les chemins, lignes, polylignes" + +#: ../../po/../src/dialogs/find.cpp:609 +msgid "Paths" +msgstr "Chemins" + +#: ../../po/../src/dialogs/find.cpp:614 +msgid "Search text objects" +msgstr "Rechercher les objets textes" + +#: ../../po/../src/dialogs/find.cpp:614 +msgid "Texts" +msgstr "Textes" + +#: ../../po/../src/dialogs/find.cpp:619 +msgid "Search groups" +msgstr "Rechercher les groupes" + +#: ../../po/../src/dialogs/find.cpp:619 +msgid "Groups" +msgstr "Groupes" + +#: ../../po/../src/dialogs/find.cpp:624 +msgid "Search clones" +msgstr "Rechercher les clones" + +#: ../../po/../src/dialogs/find.cpp:629 +msgid "Search images" +msgstr "Rechercher les images" + +#: ../../po/../src/dialogs/find.cpp:629 +msgid "Images" +msgstr "Images" + +#: ../../po/../src/dialogs/find.cpp:634 +msgid "Search offset objects" +msgstr "Rechercher les objets offset" + +#: ../../po/../src/dialogs/find.cpp:634 +msgid "Offsets" +msgstr "Offsets" + +#: ../../po/../src/dialogs/find.cpp:694 +msgid "_Text: " +msgstr "_Texte : " + +#: ../../po/../src/dialogs/find.cpp:694 +msgid "Find objects by their text content (exact or partial match)" +msgstr "" +"Rechercher des objets par le texte qu'ils contiennent (exact ou partiel)" + +#: ../../po/../src/dialogs/find.cpp:695 +msgid "_ID: " +msgstr "_ID : " + +#: ../../po/../src/dialogs/find.cpp:695 +msgid "Find objects by the value of the id attribute (exact or partial match)" +msgstr "" +"Rechercher des objets par la valeur de l'attribut «id» (exact ou partiel)" + +#: ../../po/../src/dialogs/find.cpp:696 +msgid "_Style: " +msgstr "_Style : " + +#: ../../po/../src/dialogs/find.cpp:696 +msgid "" +"Find objects by the value of the style attribute (exact or partial match)" +msgstr "" +"Rechercher des objets par la valeur de l'attribut de style (exact ou partiel)" + +#: ../../po/../src/dialogs/find.cpp:697 +msgid "_Attribute: " +msgstr "_Attribut : " + +#: ../../po/../src/dialogs/find.cpp:697 +msgid "Find objects by the name of an attribute (exact or partial match)" +msgstr "Rechercher des objets par le nom d'un attribut (exact ou partiel)" + +#: ../../po/../src/dialogs/find.cpp:711 +msgid "Search in s_election" +msgstr "R_echercher dans la sélection" + +#: ../../po/../src/dialogs/find.cpp:715 +msgid "Limit search to the current selection" +msgstr "Limiter la recherche à la sélection courante" + +#: ../../po/../src/dialogs/find.cpp:720 +msgid "Search in current _layer" +msgstr "Rechercher dans le ca_lque courant" + +#: ../../po/../src/dialogs/find.cpp:724 +msgid "Limit search to the current layer" +msgstr "Limiter la recherche au calque courant" + +#: ../../po/../src/dialogs/find.cpp:729 +msgid "Include _hidden" +msgstr "Inclure cac_hés" + +#: ../../po/../src/dialogs/find.cpp:733 +msgid "Include hidden objects in search" +msgstr "Inclure les objets cachés dans la recherche" + +#: ../../po/../src/dialogs/find.cpp:738 +msgid "Include l_ocked" +msgstr "Inclure verr_ouillés" + +#: ../../po/../src/dialogs/find.cpp:742 +msgid "Include locked objects in search" +msgstr "Inclure les objets verrouillés dans la recherche" + +#: ../../po/../src/dialogs/find.cpp:753 +msgid "Clear values" +msgstr "Effacer les valeurs" + +#: ../../po/../src/dialogs/find.cpp:754 +msgid "_Find" +msgstr "Rechercher (_f)" + +#: ../../po/../src/dialogs/find.cpp:754 +msgid "Select objects matching all of the fields you filled in" +msgstr "" +"Sélectionner les objets qui correspondent à tous les champs que vous avez " +"rempli" + +#: ../../po/../src/dialogs/iconpreview.cpp:145 +#, c-format +msgid "%d x %d" +msgstr "%d x %d" + +#: ../../po/../src/dialogs/iconpreview.cpp:193 +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:857 +#: ../../po/../src/widgets/desktop-widget.cpp:1069 +msgid "Selection" +msgstr "Sélection" + +#: ../../po/../src/dialogs/iconpreview.cpp:195 +msgid "Selection only or whole document" +msgstr "Seulement la sélection ou tout le document" + +#: ../../po/../src/dialogs/iconpreview.cpp:203 +msgid "Refresh the icons" +msgstr "Rafraîchir les icônes" + +#. Create the label for the object id +#: ../../po/../src/dialogs/item-properties.cpp:126 +#: ../../po/../src/dialogs/item-properties.cpp:327 +#: ../../po/../src/dialogs/item-properties.cpp:396 +#: ../../po/../src/dialogs/item-properties.cpp:403 +msgid "_Id" +msgstr "_Id" + +#: ../../po/../src/dialogs/item-properties.cpp:135 +msgid "" +"The id= attribute (only letters, digits, and the characters .-_: allowed)" +msgstr "L'attribut id (seul les lettres, les chiffres et -_: sont autorisés)" + +#. Button for setting the object's id, label, title and description. +#: ../../po/../src/dialogs/item-properties.cpp:149 +msgid "_Set" +msgstr "Définir (_s)" + +#. Create the label for the object label +#: ../../po/../src/dialogs/item-properties.cpp:158 +msgid "_Label" +msgstr "_Label" + +#: ../../po/../src/dialogs/item-properties.cpp:167 +msgid "A freeform label for the object" +msgstr "Un label librement attribuable aux objets" + +#. Create the label for the object title +#: ../../po/../src/dialogs/item-properties.cpp:179 +#: ../../po/../src/dialogs/rdf.cpp:243 +msgid "Title" +msgstr "Titre" + +#. Create the frame for the object description +#: ../../po/../src/dialogs/item-properties.cpp:196 +#: ../../po/../src/dialogs/rdf.cpp:287 +msgid "Description" +msgstr "Description" + +#. Hide +#: ../../po/../src/dialogs/item-properties.cpp:223 +msgid "_Hide" +msgstr "Cac_her" + +#: ../../po/../src/dialogs/item-properties.cpp:224 +msgid "Check to make the object invisible" +msgstr "A cocher pour rendre l'objet invisible" + +#. Lock +#. TRANSLATORS: "Lock" is a verb here +#: ../../po/../src/dialogs/item-properties.cpp:233 +msgid "L_ock" +msgstr "Verr_ouiller" + +#: ../../po/../src/dialogs/item-properties.cpp:234 +msgid "Check to make the object insensitive (not selectable by mouse)" +msgstr "" +"A cocher pour rendre l'objet insensible (non sélectionnable à la souris)" + +#: ../../po/../src/dialogs/item-properties.cpp:310 +#: ../../po/../src/dialogs/item-properties.cpp:317 +msgid "Ref" +msgstr "Réf" + +#: ../../po/../src/dialogs/item-properties.cpp:398 +msgid "Id invalid! " +msgstr "ID invalide !" + +#: ../../po/../src/dialogs/item-properties.cpp:400 +msgid "Id exists! " +msgstr "Cet Id existe déjà !" + +#: ../../po/../src/dialogs/layer-properties.cpp:50 +msgid "Layer name:" +msgstr "Nom du calque :" + +#: ../../po/../src/dialogs/layer-properties.cpp:133 +msgid "Rename Layer" +msgstr "Renommer le calque" + +#: ../../po/../src/dialogs/layer-properties.cpp:136 +msgid "_Rename" +msgstr "_Renommer" + +#. TRANSLATORS: This means "The layer has been renamed" +#: ../../po/../src/dialogs/layer-properties.cpp:147 +msgid "Renamed layer" +msgstr "Calque renommé" + +#: ../../po/../src/dialogs/layer-properties.cpp:151 +msgid "Add Layer" +msgstr "Ajouter un calque" + +#: ../../po/../src/dialogs/layer-properties.cpp:153 +msgid "_Add" +msgstr "_Ajouter" + +#: ../../po/../src/dialogs/layer-properties.cpp:167 +msgid "New layer created." +msgstr "Nouveau calque créé." + +#: ../../po/../src/dialogs/object-attributes.cpp:34 +msgid "Href:" +msgstr "Hréf :" + +#: ../../po/../src/dialogs/object-attributes.cpp:35 +msgid "Target:" +msgstr "Cible :" + +#: ../../po/../src/dialogs/object-attributes.cpp:36 +msgid "Type:" +msgstr "Type :" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkRoleAttribute +#. Identifies the type of the related resource with an absolute URI +#: ../../po/../src/dialogs/object-attributes.cpp:39 +msgid "Role:" +msgstr "Rôle :" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkArcRoleAttribute +#. For situations where the nature/role alone isn't enough, this offers an additional URI defining the purpose of the link. +#: ../../po/../src/dialogs/object-attributes.cpp:42 +msgid "Arcrole:" +msgstr "Arc-rôle :" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkTitleAttribute +#: ../../po/../src/dialogs/object-attributes.cpp:44 +msgid "Title:" +msgstr "Titre :" + +#: ../../po/../src/dialogs/object-attributes.cpp:45 +msgid "Show:" +msgstr "Afficher :" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkActuateAttribute +#: ../../po/../src/dialogs/object-attributes.cpp:47 +msgid "Actuate:" +msgstr "Contenu non automatique :" + +#: ../../po/../src/dialogs/object-attributes.cpp:52 +msgid "URL:" +msgstr "URL :" + +#: ../../po/../src/dialogs/object-attributes.cpp:53 +msgid "X:" +msgstr "X :" + +#: ../../po/../src/dialogs/object-attributes.cpp:54 +msgid "Y:" +msgstr "Y :" + +#: ../../po/../src/dialogs/object-attributes.cpp:98 +#, c-format +msgid "%s attributes" +msgstr "%s attributs" + +#: ../../po/../src/dialogs/object-properties.cpp:158 +msgid "_Fill" +msgstr "Remplissage (_f)" + +#: ../../po/../src/dialogs/object-properties.cpp:165 +msgid "Stroke _paint" +msgstr "Rem_plissage du contour" + +#: ../../po/../src/dialogs/object-properties.cpp:172 +msgid "Stroke st_yle" +msgstr "St_yle du contour" + +#: ../../po/../src/dialogs/object-properties.cpp:183 +msgid "Master _opacity" +msgstr "_Opacité globale" + +#: ../../po/../src/dialogs/rdf.cpp:244 +msgid "Name by which this document is formally known." +msgstr "Nom sous lequel le document est formellement connu." + +#: ../../po/../src/dialogs/rdf.cpp:246 +msgid "Date" +msgstr "Date" + +#: ../../po/../src/dialogs/rdf.cpp:247 +msgid "Date associated with the creation of this document (YYYY-MM-DD)." +msgstr "Date associée à la création du document (AAAA-MM-JJ)." + +#: ../../po/../src/dialogs/rdf.cpp:249 +msgid "Format" +msgstr "Format" + +#: ../../po/../src/dialogs/rdf.cpp:250 +msgid "The physical or digital manifestation of this document (MIME type)." +msgstr "La manifestation physique ou numérique de ce document (type MIME)." + +#: ../../po/../src/dialogs/rdf.cpp:252 +msgid "Type" +msgstr "Type" + +#: ../../po/../src/dialogs/rdf.cpp:253 +msgid "Type of document (DCMI Type)." +msgstr "Type du document (Type DCMI)." + +#: ../../po/../src/dialogs/rdf.cpp:256 +msgid "Creator" +msgstr "Créateur" + +#: ../../po/../src/dialogs/rdf.cpp:257 +msgid "" +"Name of entity primarily responsible for making the content of this document." +msgstr "" +"Entité principalement responsable de la création du contenu de ce document." + +#: ../../po/../src/dialogs/rdf.cpp:259 +msgid "Rights" +msgstr "Droits" + +#: ../../po/../src/dialogs/rdf.cpp:260 +msgid "" +"Name of entity with rights to the Intellectual Property of this document." +msgstr "" +"Nom de l'entité possédant les droits de Propriété Intellectuelle sur ce " +"document." + +#: ../../po/../src/dialogs/rdf.cpp:262 +msgid "Publisher" +msgstr "Éditeur" + +#: ../../po/../src/dialogs/rdf.cpp:263 +msgid "Name of entity responsible for making this document available." +msgstr "Nom de l'entité responsable de la distribution de ce document." + +#: ../../po/../src/dialogs/rdf.cpp:266 +msgid "Identifier" +msgstr "Identifiant" + +#: ../../po/../src/dialogs/rdf.cpp:267 +msgid "Unique URI to reference this document." +msgstr "URI unique pour référencer ce document." + +#: ../../po/../src/dialogs/rdf.cpp:269 +msgid "Source" +msgstr "Source" + +#: ../../po/../src/dialogs/rdf.cpp:270 +msgid "Unique URI to reference the source of this document." +msgstr "" +"URI unique pour référencer la ressource dont le document actuel est dérivé." + +#: ../../po/../src/dialogs/rdf.cpp:272 +msgid "Relation" +msgstr "Relation" + +#: ../../po/../src/dialogs/rdf.cpp:273 +msgid "Unique URI to a related document." +msgstr "URI unique à une ressource apparentée." + +#: ../../po/../src/dialogs/rdf.cpp:275 +msgid "Language" +msgstr "Langue" + +#: ../../po/../src/dialogs/rdf.cpp:276 +msgid "" +"Two-letter language tag with optional subtags for the language of this " +"document. (e.g. 'en-GB')" +msgstr "" +"Langue en deux lettres, avec optionellement une spécification régionale. (ex " +"'fr-FR')" + +#: ../../po/../src/dialogs/rdf.cpp:278 +msgid "Keywords" +msgstr "Mots clés" + +#: ../../po/../src/dialogs/rdf.cpp:279 +msgid "" +"The topic of this document as comma-separated key words, phrases, or " +"classifications." +msgstr "" +"Le sujet de ce document sous forme de mots clés, phrases ou éléments de " +"classification, séparés par des virgules." + +#. TRANSLATORS: "Coverage": the spatial or temporal characteristics of the content. +#. For info, see Appendix D of http://www.w3.org/TR/1998/WD-rdf-schema-19980409/ +#: ../../po/../src/dialogs/rdf.cpp:283 +msgid "Coverage" +msgstr "Couverture" + +#: ../../po/../src/dialogs/rdf.cpp:284 +msgid "Extent or scope of this document." +msgstr "Étendue ou portée spatio-temporelle du contenu de ce document." + +#: ../../po/../src/dialogs/rdf.cpp:288 +msgid "A short account of the content of this document." +msgstr "Une courte explication du contenu de ce document." + +#. FIXME: need to handle 1 agent per line of input +#: ../../po/../src/dialogs/rdf.cpp:292 +msgid "Contributors" +msgstr "Collaborateurs" + +#: ../../po/../src/dialogs/rdf.cpp:293 +msgid "" +"Names of entities responsible for making contributions to the content of " +"this document." +msgstr "Nom des entités ayant contribué au contenu de ce document." + +#. TRANSLATORS: URL to a page that defines the license for the document +#: ../../po/../src/dialogs/rdf.cpp:297 +msgid "URI" +msgstr "URI" + +#. TRANSLATORS: this is where you put a URL to a page that defines the license +#: ../../po/../src/dialogs/rdf.cpp:299 +msgid "URI to this document's license's namespace definition." +msgstr "URI de la définition de l'espace de nom de la licence de ce document." + +#. TRANSLATORS: fragment of XML representing the license of the document +#: ../../po/../src/dialogs/rdf.cpp:303 +msgid "Fragment" +msgstr "Fragment" + +#: ../../po/../src/dialogs/rdf.cpp:304 +msgid "XML fragment for the RDF 'License' section." +msgstr "Fragment XML la section 'Licence' (RDF)." + +#: ../../po/../src/dialogs/stroke-style.cpp:774 +#: ../../po/../src/widgets/gradient-vector.cpp:263 +#: ../../po/../src/widgets/paint-selector.cpp:751 +msgid "No document selected" +msgstr "Aucun document sélectionné" + +#: ../../po/../src/dialogs/stroke-style.cpp:992 +msgid "Stroke width" +msgstr "Largeur du contour" + +#. Join type +#. TRANSLATORS: The line join style specifies the shape to be used at the +#. corners of paths. It can be "miter", "round" or "bevel". +#: ../../po/../src/dialogs/stroke-style.cpp:1015 +msgid "Join:" +msgstr "Raccord :" + +#. TRANSLATORS: Miter join: joining lines with a sharp (pointed) corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1027 +msgid "Miter join" +msgstr "Raccord droit" + +#. TRANSLATORS: Round join: joining lines with a rounded corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1035 +msgid "Round join" +msgstr "Raccord arrondi" + +#. TRANSLATORS: Bevel join: joining lines with a blunted (flattened) corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1043 +msgid "Bevel join" +msgstr "Raccord biseauté" + +#. Miterlimit +#. TRANSLATORS: Miter limit: only for "miter join", this limits the length +#. of the sharp "spike" when the lines connect at too sharp an angle. +#. When two line segments meet at a sharp angle, a miter join results in a +#. spike that extends well beyond the connection point. The purpose of the +#. miter limit is to cut off such spikes (i.e. convert them into bevels) +#. when they become too long. +#: ../../po/../src/dialogs/stroke-style.cpp:1054 +msgid "Miter limit:" +msgstr "Limite de la coiffe :" + +#: ../../po/../src/dialogs/stroke-style.cpp:1062 +msgid "Maximum length of the miter (in units of stroke width)" +msgstr "Longueur maximum de la coiffe (en unité de la largeur du contour)" + +#. Cap type +#. TRANSLATORS: cap type specifies the shape for the ends of lines +#: ../../po/../src/dialogs/stroke-style.cpp:1075 +msgid "Cap:" +msgstr "Coiffe :" + +#. TRANSLATORS: Butt cap: the line shape does not extend beyond the end point +#. of the line; the ends of the line are square +#: ../../po/../src/dialogs/stroke-style.cpp:1086 +msgid "Butt cap" +msgstr "Coiffe terminale" + +#. TRANSLATORS: Round cap: the line shape extends beyond the end point of the +#. line; the ends of the line are rounded +#: ../../po/../src/dialogs/stroke-style.cpp:1093 +msgid "Round cap" +msgstr "Coiffe arrondie" + +#. TRANSLATORS: Square cap: the line shape extends beyond the end point of the +#. line; the ends of the line are square +#: ../../po/../src/dialogs/stroke-style.cpp:1100 +msgid "Square cap" +msgstr "Coiffe carrée" + +#. Dash +#: ../../po/../src/dialogs/stroke-style.cpp:1106 +msgid "Dashes:" +msgstr "Pointillés :" + +#. TRANSLATORS: Path markers are an SVG feature that allows you to attach arbitrary shapes +#. (arrowheads, bullets, faces, whatever) to the start, end, or middle nodes of a path. +#: ../../po/../src/dialogs/stroke-style.cpp:1127 +msgid "Start Markers:" +msgstr "Marqueurs de début :" + +#: ../../po/../src/dialogs/stroke-style.cpp:1137 +msgid "Mid Markers:" +msgstr "Marqueurs intermédiaires :" + +#: ../../po/../src/dialogs/stroke-style.cpp:1148 +msgid "End Markers:" +msgstr "Marqueurs de fin :" + +#: ../../po/../src/dialogs/swatches.cpp:424 +#, c-format +msgid "Palettes directory (%s) is unavailable." +msgstr "Le répertoire des palettes (%s) est indisponible." + +#. TODO: Insert widgets +#: ../../po/../src/dialogs/text-edit.cpp:199 +#: ../../po/../src/ui/dialog/text-properties.cpp:36 +msgid "Font" +msgstr "Police" + +#: ../../po/../src/dialogs/text-edit.cpp:216 +msgid "Layout" +msgstr "Disposer" + +#: ../../po/../src/dialogs/text-edit.cpp:229 +msgid "Align lines left" +msgstr "Aligner les lignes à gauche" + +#. TRANSLATORS: `Center' here is a verb. +#: ../../po/../src/dialogs/text-edit.cpp:243 +msgid "Center lines" +msgstr "Centrer les lignes" + +#: ../../po/../src/dialogs/text-edit.cpp:256 +msgid "Align lines right" +msgstr "Aligner les lignes à droite" + +#: ../../po/../src/dialogs/text-edit.cpp:278 +msgid "Horizontal text" +msgstr "Texte horizontal" + +#: ../../po/../src/dialogs/text-edit.cpp:292 +msgid "Vertical text" +msgstr "Texte vertical" + +#: ../../po/../src/dialogs/text-edit.cpp:307 +msgid "Line spacing:" +msgstr "Espacement des lignes :" + +#: ../../po/../src/dialogs/text-edit.cpp:400 +msgid "Set as default" +msgstr "Enregistrer comme valeur par défaut" + +#: ../../po/../src/dialogs/tiledialog.cpp:603 +msgid "Rows:" +msgstr "Lignes :" + +#: ../../po/../src/dialogs/tiledialog.cpp:613 +msgid "Number of rows" +msgstr "Nombre de lignes" + +#: ../../po/../src/dialogs/tiledialog.cpp:617 +msgid "Equal height" +msgstr "Egaliser la hauteur :" + +#: ../../po/../src/dialogs/tiledialog.cpp:627 +msgid "If not set, each row has the height of the tallest object in it" +msgstr "" +"Si décoché, chaque ligne a la hauteur de l'objet le plus haut qu'elle " +"contient" + +#. #### Radio buttons to control vertical alignment #### +#. #### Radio buttons to control horizontal alignment #### +#: ../../po/../src/dialogs/tiledialog.cpp:637 +#: ../../po/../src/dialogs/tiledialog.cpp:708 +msgid "Align:" +msgstr "Aligner :" + +#: ../../po/../src/dialogs/tiledialog.cpp:672 +msgid " X " +msgstr " X " + +#. #### Number of columns #### +#: ../../po/../src/dialogs/tiledialog.cpp:678 +msgid "Columns:" +msgstr "Colonnes :" + +#: ../../po/../src/dialogs/tiledialog.cpp:688 +msgid "Number of columns" +msgstr "Nombre de colonnes" + +#: ../../po/../src/dialogs/tiledialog.cpp:692 +msgid "Equal width" +msgstr "Egaliser la largeur :" + +#: ../../po/../src/dialogs/tiledialog.cpp:701 +msgid "If not set, each column has the width of the widest object in it" +msgstr "" +"Si décoché, chaque ligne a la largeur de l'objet le plus large qu'elle " +"contient" + +#. #### Radio buttons to control spacing manually or to fit selection bbox #### +#: ../../po/../src/dialogs/tiledialog.cpp:746 +msgid "Fit into selection box" +msgstr "Ajuster à la boîte de sélection" + +#: ../../po/../src/dialogs/tiledialog.cpp:753 +msgid "Set spacing:" +msgstr "Définir l'espacement :" + +#. #### Y Padding #### +#: ../../po/../src/dialogs/tiledialog.cpp:777 +msgid "Row spacing: " +msgstr "Espacement des lignes :" + +#: ../../po/../src/dialogs/tiledialog.cpp:786 +msgid "Vertical spacing between rows" +msgstr "Espace vertical entre les lignes" + +#. #### X padding #### +#: ../../po/../src/dialogs/tiledialog.cpp:795 +msgid "Column spacing:" +msgstr "Espacement des colonnes :" + +#: ../../po/../src/dialogs/tiledialog.cpp:804 +msgid "Horizontal spacing between columns" +msgstr "Espace horizontal entre les colonnes" + +#: ../../po/../src/dialogs/tiledialog.cpp:818 +#, fuzzy +msgid "Arrange selected objects" +msgstr "Grouper les objets sélectionnés" + +#: ../../po/../src/dialogs/xml-tree.cpp:178 +msgid "Click to select nodes, drag to rearrange." +msgstr "" +"Cliquer pour sélectionner un nœud, cliquer-déplacer pour le " +"déplacer." + +#: ../../po/../src/dialogs/xml-tree.cpp:189 +msgid "Click attribute to edit." +msgstr "Cliquer sur les attributs pour pouvoir les éditer." + +#: ../../po/../src/dialogs/xml-tree.cpp:193 +#, c-format +msgid "" +"Attribute %s selected. Press Ctrl+Enter when done editing to " +"commit changes." +msgstr "" +"Attribut %s sélectionné. Appuyer sur Ctrl+Enter après édition " +"pour valider." + +#: ../../po/../src/dialogs/xml-tree.cpp:284 +msgid "Drag to reorder nodes" +msgstr "Cliquer-déplacer pour réorganiser les nœuds" + +#: ../../po/../src/dialogs/xml-tree.cpp:304 +msgid "New element node" +msgstr "Nouveau nœud élément" + +#: ../../po/../src/dialogs/xml-tree.cpp:326 +msgid "New text node" +msgstr "Nouveau nœud texte" + +#: ../../po/../src/dialogs/xml-tree.cpp:347 +msgid "Duplicate node" +msgstr "Dupliquer le nœud" + +#: ../../po/../src/dialogs/xml-tree.cpp:368 +msgid "Delete node" +msgstr "Supprimer le nœud" + +#: ../../po/../src/dialogs/xml-tree.cpp:384 +msgid "Unindent node" +msgstr "Désindenter le nœud" + +#: ../../po/../src/dialogs/xml-tree.cpp:399 +msgid "Indent node" +msgstr "Indenter le nœud" + +#: ../../po/../src/dialogs/xml-tree.cpp:411 +msgid "Raise node" +msgstr "Monter le nœud" + +#: ../../po/../src/dialogs/xml-tree.cpp:423 +msgid "Lower node" +msgstr "Descendre le nœud" + +#: ../../po/../src/dialogs/xml-tree.cpp:468 +msgid "Delete attribute" +msgstr "Supprimer l'attribut" + +#. TRANSLATORS: "Attribute" is a noun here +#: ../../po/../src/dialogs/xml-tree.cpp:513 +msgid "Attribute name" +msgstr "Nom de l'attribut" + +#. TRANSLATORS: "Set" is a verb here +#: ../../po/../src/dialogs/xml-tree.cpp:533 +msgid "Set attribute" +msgstr "Définir l'attribut" + +#. TRANSLATORS: "Set" is a verb here +#: ../../po/../src/dialogs/xml-tree.cpp:535 +msgid "Set" +msgstr "Définir" + +#. TRANSLATORS: "Attribute" is a noun here +#: ../../po/../src/dialogs/xml-tree.cpp:558 +msgid "Attribute value" +msgstr "Valeur de l'attribut" + +#: ../../po/../src/dialogs/xml-tree.cpp:1318 +msgid "New element node..." +msgstr "Nouveau nœud élément..." + +#: ../../po/../src/dialogs/xml-tree.cpp:1339 +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:100 +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:98 +msgid "Cancel" +msgstr "Annuler" + +#: ../../po/../src/dialogs/xml-tree.cpp:1345 +msgid "Create" +msgstr "Créer" + +#: ../../po/../src/dialogs/xml-tree.cpp:1458 +#, c-format +msgid "" +"Cannot set %s: Another element with value %s already exists!" +msgstr "" +"Impossible de définir %s: un autre élément avec la valeur %s " +"existe déjà!" + +#: ../../po/../src/document.cpp:369 +#, c-format +msgid "New document %d" +msgstr "Nouveau document %d" + +#: ../../po/../src/document.cpp:401 +#, c-format +msgid "Memory document %d" +msgstr "Document d'information %d" + +#: ../../po/../src/document.cpp:524 +#, c-format +msgid "Unnamed document %d" +msgstr "Document sans nom %d" + +#. We hit green anchor, closing Green-Blue-Red +#: ../../po/../src/draw-context.cpp:441 +msgid "Path is closed." +msgstr "Le chemin est fermé." + +#. We hit bot start and end of single curve, closing paths +#: ../../po/../src/draw-context.cpp:456 +msgid "Closing path." +msgstr "Fermeture de chemin." + +#. alpha of color under cursor, to show in the statusbar +#. locale-sensitive printf is OK, since this goes to the UI, not into SVG +#: ../../po/../src/dropper-context.cpp:354 +#, c-format +msgid " alpha %.3g" +msgstr " alpha %.3g" + +#. where the color is picked, to show in the statusbar +#: ../../po/../src/dropper-context.cpp:356 +#, c-format +msgid ", averaged with radius %d" +msgstr ", moyenné avec un rayon de %d" + +#: ../../po/../src/dropper-context.cpp:356 +msgid " under cursor" +msgstr " sous le curseur" + +#. message, to show in the statusbar +#: ../../po/../src/dropper-context.cpp:358 +msgid "Release mouse to set color." +msgstr "Relâcher la souris pour affecter la couleur." + +#: ../../po/../src/dropper-context.cpp:358 +#: ../../po/../src/tools-switch.cpp:207 +msgid "" +"Click to set fill, Shift+click to set stroke; drag to " +"average color in area; with Alt to pick inverse color; Ctrl+C " +"to copy the color under mouse to clipboard" +msgstr "" +"Cliquer pour affecter le remplissage, Maj+cliquer pour " +"affecter le contour; cliquer-déplacer pour capturer la couleur " +"moyenne sur une zone; à combiner avec Alt pour capturer la couleur " +"inverse; Ctrl+C pour copier la couleur sous le curseur de la souris " +"vers le presse-papiers " + +#: ../../po/../src/extension/dependency.cpp:244 +msgid "Dependency::" +msgstr "Dépendance::" + +#: ../../po/../src/extension/dependency.cpp:245 +msgid " type: " +msgstr " type : " + +#: ../../po/../src/extension/dependency.cpp:246 +msgid " location: " +msgstr " emplacement : " + +#: ../../po/../src/extension/dependency.cpp:247 +msgid " string: " +msgstr " chaîne : " + +#: ../../po/../src/extension/dependency.cpp:250 +msgid " description: " +msgstr " description : " + +#. static int i = 0; +#. std::cout << "Checking module[" << i++ << "]: " << name << std::endl; +#: ../../po/../src/extension/extension.cpp:244 +msgid "" +" This is caused by an improper .inx file for this extension. An improper ." +"inx file could have been caused by a faulty installation of Inkscape." +msgstr "" +" C'est le résultat d'un fichier .inx incorrect pour cette extension. Un " +"fichier .inx incorrect peut être du à un problème d'installation d'Inkscape." + +#: ../../po/../src/extension/extension.cpp:247 +msgid "an ID was not defined for it." +msgstr "aucun ID ne lui a été affecté." + +#: ../../po/../src/extension/extension.cpp:251 +msgid "there was no name defined for it." +msgstr "aucun nom ne lui a été affecté." + +#: ../../po/../src/extension/extension.cpp:255 +msgid "the XML description of it got lost." +msgstr "sa description XML a été perdue." + +#: ../../po/../src/extension/extension.cpp:259 +msgid "no implementation was defined for the extension." +msgstr "aucune implémentation n'a été définie pour cette extension." + +#. std::cout << "Failed: " << *(_deps[i]) << std::endl; +#: ../../po/../src/extension/extension.cpp:266 +msgid "a dependency was not met." +msgstr "une dépendance est manquante." + +#: ../../po/../src/extension/extension.cpp:286 +msgid "Extension \"" +msgstr "L'extension «" + +#: ../../po/../src/extension/extension.cpp:286 +msgid "\" failed to load because " +msgstr "» n'a pas été chargée, car " + +#: ../../po/../src/extension/extension.cpp:565 +#, c-format +msgid "Could not create extension error log file '%s'" +msgstr "Impossible de créer le fichier d'erreur de l'extension : '%s'" + +#. This is some filler text, needs to change before relase +#: ../../po/../src/extension/error-file.cpp:56 +msgid "" +"One or more extensions failed to load\n" +"\n" +"The failed extensions have been skipped. Inkscape will continue to run " +"normally but those extensions will be unavailable. For details to " +"troubleshoot this problem, please refer to the error log located at: " +msgstr "" +"Le chargement d'une ou plusieurs " +"extensions a échoué\n" +"\n" +"Les extensions défectueuses ont été sautées. Inkscape va continuer à " +"fonctionner normalement, mais ces extensions seront indisponibles. Pour plus " +"de détails concernant ce problème, référez-vous à l'historique (log) des " +"messages d'erreur : " + +#. This is some filler text, needs to change before relase +#: ../../po/../src/extension/error-file.cpp:65 +msgid "Show dialog on startup" +msgstr "Afficher le dialogue au démarrage" + +#: ../../po/../src/extension/implementation/script.cpp:845 +msgid "" +"Inkscape has received an error from the script that it called. The text " +"returned with the error is included below. Inkscape will continue working, " +"but the action you requested has been cancelled." +msgstr "" +"Inkscape a reçu une erreur du script appelé. The texte retourné avec " +"l'erreur est affiché ci-dessous. Inkscape continue de fonctionner " +"normalement, mais l'action requise a été annulée." + +#: ../../po/../src/extension/implementation/script.cpp:858 +msgid "" +"Inkscape has received additional data from the script executed. The script " +"did not return an error, but this may indicate the results will not be as " +"expected." +msgstr "" +"Inkscape a reçu des données additionnelles du script exécuté. The script n'a " +"pas retourné d'erreur, mais ceci peut indiquer que les résultats ne sont pas " +"ceux attendus." + +#: ../../po/../src/extension/init.cpp:173 +msgid "Null external module directory name. Modules will not be loaded." +msgstr "" +"Le répertoire des modules externes est «Nul». Les modules ne seront pas " +"chargés." + +#: ../../po/../src/extension/init.cpp:187 +#, c-format +msgid "" +"Modules directory (%s) is unavailable. External modules in that directory " +"will not be loaded." +msgstr "" +"Le répertoire des modules (%s) est indisponible.Les modules externes de ce " +"répertoire ne seront pas chargés." + +#: ../../po/../src/extension/internal/gnome.cpp:80 +msgid "Select printer" +msgstr "Sélectionner l'imprimante" + +#: ../../po/../src/extension/internal/gnome.cpp:131 +msgid "Inkscape: Print Preview" +msgstr "Inkscape : aperçu avant impression" + +#: ../../po/../src/extension/internal/grid.cpp:213 +msgid "Line Width" +msgstr "Largeur de ligne" + +#: ../../po/../src/extension/internal/grid.cpp:214 +msgid "Horizontal Spacing" +msgstr "Espacement horizontal" + +#: ../../po/../src/extension/internal/grid.cpp:215 +msgid "Vertical Spacing" +msgstr "Espacement vertical" + +#: ../../po/../src/extension/internal/grid.cpp:216 +msgid "Horizontal Offset" +msgstr "Décalage horizontal" + +#: ../../po/../src/extension/internal/grid.cpp:217 +msgid "Vertical Offset" +msgstr "Décalage vertical" + +#: ../../po/../src/extension/internal/ps.cpp:123 +msgid "Print Destination" +msgstr "Destination d'impression" + +#. Print properties frame +#: ../../po/../src/extension/internal/ps.cpp:138 +msgid "Print properties" +msgstr "Propriétés d'impression" + +#: ../../po/../src/extension/internal/ps.cpp:145 +msgid "Print using PostScript operators" +msgstr "Imprimer en utilisant les opérateurs PostScript" + +#: ../../po/../src/extension/internal/ps.cpp:147 +msgid "" +"Use PostScript vector operators. The resulting image is usually smaller in " +"file size and can be arbitrarily scaled, but alpha transparency and patterns " +"will be lost." +msgstr "" +"Utiliser les opérateurs vectoriels PostScript. Le fichier image résultant " +"est en général moins volumineux et reste redimensionnable; cependant, la " +"transparence alpha et les motifs de remplissage seront perdus." + +#: ../../po/../src/extension/internal/ps.cpp:152 +msgid "Print as bitmap" +msgstr "Imprimer en bitmap" + +#: ../../po/../src/extension/internal/ps.cpp:154 +msgid "" +"Print everything as bitmap. The resulting image is usually larger in file " +"size and cannot be arbitrarily scaled without quality loss, but all objects " +"will be rendered exactly as displayed." +msgstr "" +"Tout imprimer en tant que bitmap. Le fichier image résultant sera en général " +"plus volumineux et n'est plus redimenssionnable sans perte de qualité, " +"cependant tous les objets seront rendus tels qu'affichés." + +#: ../../po/../src/extension/internal/ps.cpp:168 +msgid "Preferred resolution (dots per inch) of bitmap" +msgstr "Résolution préférée (point par pouce) du bitmap" + +#: ../../po/../src/extension/internal/ps.cpp:182 +msgid "Resolution:" +msgstr "Résolution :" + +#. Print destination frame +#: ../../po/../src/extension/internal/ps.cpp:186 +msgid "Print destination" +msgstr "Destination de l'impression" + +#: ../../po/../src/extension/internal/ps.cpp:192 +msgid "" +"Use '> filename' to print to file.\n" +"Use '| prog arg...' to pipe to a program." +msgstr "" +"Utiliser '> fichier' pour imprimer vers un fichier.\n" +"Utiliser '| prog arg...' pour envoyer au travers d'un tube (pipe) à un " +"programme." + +#: ../../po/../src/extension/internal/ps.cpp:1227 +msgid "write error occurred" +msgstr "une erreur d'écriture s'est produite" + +#: ../../po/../src/extension/prefdialog.cpp:21 +msgid " Preferences" +msgstr " Préférences" + +#. We can't call sp_ui_error_dialog because we may be +#. running from the console, in which case calling sp_ui +#. routines will cause a segfault. See bug 1000350 - bryce +#. sp_ui_error_dialog(_("Format autodetect failed. The file is being opened as SVG.")); +#: ../../po/../src/extension/system.cpp:105 +msgid "Format autodetect failed. The file is being opened as SVG." +msgstr "" +"Échec de la détection automatique du format. Le fichier est ouvert en tant " +"que SVG." + +#. TRANSLATORS: default.svg is localizable - this is the name of the default document +#. template. This way you can localize the default pagesize, translate the name of +#. the default layer, etc. If you wish to localize this file, please create a +#. localized share/templates/default.xx.svg file, where xx is your language code. +#: ../../po/../src/file.cpp:133 +msgid "default.svg" +msgstr "default.fr.svg" + +#: ../../po/../src/file.cpp:215 ../../po/../src/file.cpp:900 +#, c-format +msgid "Failed to load the requested file %s" +msgstr "Échec du chargement du fichier %s" + +#: ../../po/../src/file.cpp:240 +msgid "Document not saved yet. Cannot revert." +msgstr "Document non enregistré. Impossible de le recharger." + +#: ../../po/../src/file.cpp:246 +#, c-format +msgid "Changes will be lost! Are you sure you want to reload document %s?" +msgstr "" +"Les changements seront perdus ! Êtes-vous sûr de vouloir recharger le " +"document %s ?" + +#: ../../po/../src/file.cpp:266 +msgid "Document reverted." +msgstr "Document rechargé." + +#: ../../po/../src/file.cpp:268 +msgid "Document not reverted." +msgstr "Document non rechargé." + +#: ../../po/../src/file.cpp:382 +msgid "Select file to open" +msgstr "Sélectionner un fichier à ouvrir" + +#: ../../po/../src/file.cpp:518 +#, c-format +msgid "Removed %i unused definition in <defs>." +msgid_plural "Removed %i unused definitions in <defs>." +msgstr[0] "" +"Suppression de %i définition inutilisée dans les <defs>." +msgstr[1] "" +"Suppression de %i définitions inutilisées dans les <defs>." + +#: ../../po/../src/file.cpp:523 +msgid "No unused definitions in <defs>." +msgstr "Aucune définition inutilisée dans les <defs>." + +#: ../../po/../src/file.cpp:548 +#, c-format +msgid "" +"No Inkscape extension found to save document (%s). This may have been " +"caused by an unknown filename extension." +msgstr "" +"Aucune extension Inkscape pour enregistrer le document (%s) n'a été trouvée. " +"Cela peut venir d'une extension de fichier inconnue." + +#: ../../po/../src/file.cpp:549 ../../po/../src/file.cpp:557 +msgid "Document not saved." +msgstr "Document non enregistré." + +#: ../../po/../src/file.cpp:556 +#, c-format +msgid "File %s could not be saved." +msgstr "Le fichier %s n'a pas pu être enregistré." + +#: ../../po/../src/file.cpp:566 +msgid "Document saved." +msgstr "Document enregistré." + +#: ../../po/../src/file.cpp:614 +#, c-format +msgid "drawing%s" +msgstr "dessin%s" + +#: ../../po/../src/file.cpp:620 +#, c-format +msgid "drawing-%d%s" +msgstr "dessin-%d%s" + +#: ../../po/../src/file.cpp:655 +msgid "Select file to save to" +msgstr "Sélectionner le fichier dans lequel enregistrer" + +#: ../../po/../src/file.cpp:739 +msgid "No changes need to be saved." +msgstr "Aucun changement à enregistrer." + +#: ../../po/../src/file.cpp:926 +msgid "Select file to import" +msgstr "Sélectionner un fichier à importer" + +#: ../../po/../src/gradient-context.cpp:263 +msgid "Ctrl: snap gradient angle" +msgstr "" +"Ctrl : pour forcer la modification de l'inclinaison du dégradé par " +"incréments" + +#: ../../po/../src/gradient-context.cpp:264 +msgid "Shift: draw gradient around the starting point" +msgstr "Maj : pour dessiner le dégradé autour du point de départ" + +#. We did an undoable action, but sp_document_done will be called by the knot when released +#. status text; we do not track coords because this branch is run once, not all the time +#. during drag +#: ../../po/../src/gradient-context.cpp:462 +#, c-format +msgid "Gradient for %d objects; with Ctrl to snap angle" +msgstr "" +"Dégradé appliqué à %d objets; Utiliser Ctrl pour forcer la " +"modification de son inclinaison par incréments" + +#: ../../po/../src/gradient-context.cpp:464 +msgid "Select objects on which to create gradient." +msgstr "Sélectionner des objets auxquels appliquer un dégradé." + +#: ../../po/../src/gradient-drag.cpp:65 +msgid "Linear gradient start" +msgstr "Début de dégradé linéaire" + +#. POINT_LG_P1 +#: ../../po/../src/gradient-drag.cpp:66 +msgid "Linear gradient end" +msgstr "Fin de dégradé linéaire" + +#: ../../po/../src/gradient-drag.cpp:67 +msgid "Radial gradient center" +msgstr "Centre de dégradé radial" + +#: ../../po/../src/gradient-drag.cpp:68 ../../po/../src/gradient-drag.cpp:69 +msgid "Radial gradient radius" +msgstr "Rayon de dégradé radial" + +#: ../../po/../src/gradient-drag.cpp:70 +msgid "Radial gradient focus" +msgstr "Foyer de dégradé radial" + +#: ../../po/../src/gradient-drag.cpp:659 +#, c-format +msgid "" +"%s for: %s%s; drag with Ctrl to snap angle, with Ctrl+Alt to " +"preserve angle, with Ctrl+Shift to scale around center" +msgstr "" +"%s pour %s%s; cliquer-déplacer avec Ctrl pour faire varier l'angle " +"par incréments; Ctrl+Alt pour préserver l'angle, avec Ctrl+Maj " +"pour redimensionner autour du centre" + +#: ../../po/../src/gradient-drag.cpp:662 +msgid " (stroke)" +msgstr " (contour)" + +#: ../../po/../src/gradient-drag.cpp:665 +msgid "" +"Radial gradient center and focus; drag with Shift to " +"separate focus" +msgstr "" +"Dégradé radial, centre et foyer; Maj+déplacer pour " +"séparer le foyer" + +#: ../../po/../src/gradient-drag.cpp:667 +#, c-format +msgid "" +"Gradient point shared by %d gradients; drag with Shift to " +"separate" +msgstr "" +"Point de dégradé partagé entre %d dégradés; Maj+déplacer pour " +"séparer " + +#: ../../po/../src/helper/units.cpp:40 +msgid "Unit" +msgstr "Unité" + +#: ../../po/../src/helper/units.cpp:40 +msgid "Units" +msgstr "Unités" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Point" +msgstr "Point" + +#: ../../po/../src/helper/units.cpp:41 +msgid "pt" +msgstr "pt" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Points" +msgstr "Points" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Pt" +msgstr "Pt" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Pixel" +msgstr "Pixel" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Pixels" +msgstr "Pixels" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Px" +msgstr "Px" + +#. You can add new elements from this point forward +#: ../../po/../src/helper/units.cpp:44 ../share/extensions/straightseg.inx.h:2 +msgid "Percent" +msgstr "Pourcent" + +#: ../../po/../src/helper/units.cpp:44 +msgid "Percents" +msgstr "Pourcents" + +#: ../../po/../src/helper/units.cpp:45 +msgid "Millimeter" +msgstr "Millimètre" + +#: ../../po/../src/helper/units.cpp:45 +msgid "mm" +msgstr "mm" + +#: ../../po/../src/helper/units.cpp:45 +msgid "Millimeters" +msgstr "Millimètres" + +#: ../../po/../src/helper/units.cpp:46 +msgid "Centimeter" +msgstr "Centimètre" + +#: ../../po/../src/helper/units.cpp:46 +msgid "cm" +msgstr "cm" + +#: ../../po/../src/helper/units.cpp:46 +msgid "Centimeters" +msgstr "Centimètres" + +#: ../../po/../src/helper/units.cpp:47 +msgid "Meter" +msgstr "Mètre" + +#: ../../po/../src/helper/units.cpp:47 +msgid "m" +msgstr "m" + +#: ../../po/../src/helper/units.cpp:47 +msgid "Meters" +msgstr "Mètres" + +#. no svg_unit +#: ../../po/../src/helper/units.cpp:48 +msgid "Inch" +msgstr "Pouce" + +#: ../../po/../src/helper/units.cpp:48 +msgid "in" +msgstr "in" + +#: ../../po/../src/helper/units.cpp:48 +msgid "Inches" +msgstr "Pouces" + +#. Volatiles do not have default, so there are none here +#. TRANSLATORS: for info, see http://www.w3.org/TR/REC-CSS2/syndata.html#length-units +#: ../../po/../src/helper/units.cpp:51 +msgid "Em square" +msgstr "Em carré" + +#: ../../po/../src/helper/units.cpp:51 +msgid "em" +msgstr "em" + +#: ../../po/../src/helper/units.cpp:51 +msgid "Em squares" +msgstr "Em carrés" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/REC-CSS2/syndata.html#length-units +#: ../../po/../src/helper/units.cpp:53 +msgid "Ex square" +msgstr "Ex carré" + +#: ../../po/../src/helper/units.cpp:53 +msgid "ex" +msgstr "ex" + +#: ../../po/../src/helper/units.cpp:53 +msgid "Ex squares" +msgstr "Ex carrés" + +#: ../../po/../src/inkscape.cpp:468 +msgid "Untitled document" +msgstr "Document sans titre" + +#. Show nice dialog box +#: ../../po/../src/inkscape.cpp:497 +msgid "Inkscape encountered an internal error and will close now.\n" +msgstr "Inkscape a subi une erreur interne et va se fermer maintenant\n" + +#: ../../po/../src/inkscape.cpp:498 +msgid "" +"Automatic backups of unsaved documents were done to the following " +"locations:\n" +msgstr "" +"Les enregistrements automatiques des documents non enregistrés ont été " +"effectués à cet emplacement :\n" + +#: ../../po/../src/inkscape.cpp:499 +msgid "Automatic backup of the following documents failed:\n" +msgstr "Les enregistrements automatiques des documents suivants ont échoué :\n" + +#: ../../po/../src/inkscape.cpp:634 +#, c-format +msgid "" +"Cannot create directory %s.\n" +"%s" +msgstr "" +"Impossible de créer le répertoire %s.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:635 +#, c-format +msgid "" +"%s is not a valid directory.\n" +"%s" +msgstr "" +"%s n'est pas un répertoire valide.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:636 +#, c-format +msgid "" +"Cannot create file %s.\n" +"%s" +msgstr "" +"Impossible de créer le fichier %s.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:637 +#, c-format +msgid "" +"Cannot write file %s.\n" +"%s" +msgstr "" +"Impossible d'écrire le fichier %s.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:638 +msgid "" +"Although Inkscape will run, it will use default settings,\n" +"and any changes made in preferences will not be saved." +msgstr "" +"Inkscape va démarrer, cependant, il utilisera les préférences par défaut,\n" +"et aucune modification de ces préférences ne sera enregistrée." + +#: ../../po/../src/inkscape.cpp:708 +#, c-format +msgid "" +"%s is not a regular file.\n" +"%s" +msgstr "" +"%s n'est pas un fichier régulier.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:709 +#, c-format +msgid "" +"%s not a valid XML file, or\n" +"you don't have read permissions on it.\n" +"%s" +msgstr "" +"%s n'est pas un fichier XML valide, ou\n" +"vous n'avez pas les droits pour le lire.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:711 +#, c-format +msgid "" +"%s is not a valid menus file.\n" +"%s" +msgstr "" +"%s n'est pas un fichier de menus valide.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:712 +msgid "" +"Inkscape will run with default menus.\n" +"New menus will not be saved." +msgstr "" +"Inkscape va démarrer avec les menus par défaut.\n" +"Les nouveaux menus ne seront pas enregistrés." + +#. sp_ui_menu_append_check_item_from_verb(m, view, _("_Menu"), _("Show or hide the menu bar"), "menu", +#. checkitem_toggled, checkitem_update, 0); +#: ../../po/../src/interface.cpp:753 +msgid "Commands Bar" +msgstr "Barre de commandes" + +#: ../../po/../src/interface.cpp:753 +msgid "Show or hide the Commands bar (under the menu)" +msgstr "Afficher ou non la barre de commandes (sous le menu)" + +#: ../../po/../src/interface.cpp:755 +msgid "Tool Controls" +msgstr "Contrôles des outils" + +#: ../../po/../src/interface.cpp:755 +msgid "Show or hide the Tool Controls panel" +msgstr "Afficher ou non les panneaux de contrôle des outils" + +#: ../../po/../src/interface.cpp:757 +msgid "_Toolbox" +msgstr "Boî_te à outils" + +#: ../../po/../src/interface.cpp:757 +msgid "Show or hide the main toolbox (on the left)" +msgstr "Afficher ou non la boîte à outils principale (à gauche)" + +#: ../../po/../src/interface.cpp:763 +msgid "_Statusbar" +msgstr "Barre d'état (_s)" + +#: ../../po/../src/interface.cpp:763 +msgid "Show or hide the statusbar (at the bottom of the window)" +msgstr "Afficher ou non la barre d'état (en bas de la fenêtre)" + +#: ../../po/../src/interface.cpp:820 +#, c-format +msgid "Verb \"%s\" Unknown" +msgstr "Verbe \"%s\" inconnu" + +#. TRANSLATORS: #%s is the id of the group e.g. , not a number. +#: ../../po/../src/interface.cpp:930 +#, c-format +msgid "Enter group #%s" +msgstr "Entrer dans le groupe #%s" + +#: ../../po/../src/interface.cpp:941 +msgid "Go to parent" +msgstr "Aller au parent" + +#: ../../po/../src/interface.cpp:972 +msgid "Could not parse SVG data" +msgstr "Impossible de parcourir les données SVG" + +#: ../../po/../src/interface.cpp:1135 +#, c-format +msgid "Overwrite %s" +msgstr "Écraser %s" + +#: ../../po/../src/interface.cpp:1153 +#, c-format +msgid "" +"The file %s already exists. Do you want to overwrite that file with the " +"current document?" +msgstr "" +"Le fichier %s existe déjà. Voulez-vous que le document courant écrase ce " +"fichier ?" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:59 +msgid "Jabber connection lost." +msgstr "Connection Jabber perdue." + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:72 +#, c-format +msgid "Sending message; %u message remaining in send queue." +msgid_plural "Sending message; %u messages remaining in send queue." +msgstr[0] "Envoi d'un message; il reste %u message dans la file d'envoi." +msgstr[1] "Envoi d'un message; il reste %u messages dans la file d'envoi." + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:78 +msgid "Receive queue empty." +msgstr "File de réception vide." + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:154 +#, c-format +msgid "Receiving change; %u change left to process." +msgid_plural "Receiving change; %u changes left to process." +msgstr[0] "Réception d'un changement : il reste %u changement à traiter." +msgstr[1] "Réception d'un changement : il reste %u changements à traiter." + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:157 +#, c-format +msgid "%s has left the chatroom." +msgstr "%s a quitté la pièce de discussion." + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:221 +msgid "Nickname %1 is already in use. Please choose a different nickname." +msgstr "Le surnom %1 est déjà utilisé. Veuillez choisir un surnom différent." + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:225 +msgid "An error was encountered while attempting to connect to the server." +msgstr "Erreur lors de la tentative de connection au serveur." + +#. Check to see if the user made any modifications to this document. If so, +#. we want to give them the option of (1) letting us clear their document or (2) +#. opening a new, blank document for the whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:131 +msgid "%1 has invited you to a whiteboard session." +msgstr "%1 vous a invité à une session de tableau blanc." + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:132 +msgid "Incoming whiteboard invitation from %1" +msgstr "Réception d'une invitation à une session de tableau blanc de %1" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:135 +msgid "Do you wish to accept %1's whiteboard session invitation?" +msgstr "" +"Voulez-vous accepter l'invitation de %1 à une session de tableau " +"blanc ?" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:137 +msgid "" +"Would you like to accept %1's invitation in a new document window?\n" +"Accepting the invitation in your current window will discard unsaved changes." +msgstr "" +"Voulez-vous accepter l'invitation de %1 dans une nouvelle fenêtre " +"document ?\n" +" Accepter l'invitation dans la fenêtre courante annulera vos changements non " +"enregistrés." + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:143 +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:198 +msgid "Accept invitation" +msgstr "Accepter l'invitation" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:144 +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:199 +msgid "Decline invitation" +msgstr "Décliner l'invitation" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:145 +msgid "Accept invitation in new document window" +msgstr "Accepter l'invitation dans une nouvelle fenêtre document" + +#. We could not create a new desktop; ask the user if she or he wants to +#. replace the current document and accept the invitation, or reject the invitation. +#. TRANSLATORS: %1 is a userid here +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:196 +msgid "" +"A new document window could not be opened for a whiteboard session with %" +"1" +msgstr "" +"Echec de l'ouverture d'une nouvelle fenêtre document pour la session de " +"tableau blanc avec %1" + +#. TRANSLATORS: %1 is the peer whom refused our invitation. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:238 +msgid "" +"The user %1 has refused your " +"whiteboard invitation.\n" +"\n" +msgstr "" +"L'utilisateur %1 a décliné " +"votre invitation à une session de tableau blanc.\n" +"\n" + +#. TRANSLATORS: %1 is the peer whom refused our invitation, %2 is our Jabber identity. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:241 +msgid "" +"You are still connected to a Jabber server as %2, and may send an " +"invitation to %1 again, or you may send an invitation to a different " +"user." +msgstr "" +"Vous êtes toujours connecté(e) à un serveur Jabber en tant que %2, et " +"pouvez envoyer une invitation à %1 de nouveau ou à un autre " +"utilisateur." + +#. TRANSLATORS: %1 is the peer whom we tried to contact, but is already in a whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:252 +msgid "" +"The user %1 is already in a " +"whiteboard session.\n" +"\n" +msgstr "" +"L'utilisateur %1 participe déjà " +"à une session de tableau blanc.\n" +"\n" + +#. TRANSLATORS: %1 is the peer whom we tried to contact, but is already in a whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:255 +msgid "" +"You are still connected to a Jabber server as %1, and may send an " +"invitation to a different user." +msgstr "" +"Vous êtes toujours connecté(e) à un serveur Jabber en tant que %1, et " +"pouvez envoyer une invitation à un autre utilisateur." + +#: ../../po/../src/jabber_whiteboard/invitation-confirm-dialog.cpp:26 +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:24 +msgid "_Write session file:" +msgstr "Enregistrer le fichier de session (_w) :" + +#: ../../po/../src/jabber_whiteboard/message-processors.cpp:145 +#, c-format +msgid "%s has joined the chatroom." +msgstr "%s a rejoint la pièce de discussion." + +#: ../../po/../src/jabber_whiteboard/message-queue.cpp:87 +#, c-format +msgid "%u change in receive queue." +msgid_plural "%u changes in receive queue." +msgstr[0] "%u changement dans la file de réception." +msgstr[1] "%u changements dans la file de réception." + +#: ../../po/../src/jabber_whiteboard/message-queue.cpp:117 +#, c-format +msgid "%u change in send queue." +msgid_plural "%u changes in send queue." +msgstr[0] "%u changement dans la file d'envoi." +msgstr[1] "%u changements dans la file d'envoi." + +#. if ID is NULL, then we have a real problem -- we were not able to find a key +#. nor generate one. The only thing we can really do here is abort, since we have +#. no way to let the other client(s) uniquely identify this object. +#. FIXME: If this indicates a programming bug, then don't request translation with +#. * _(...): it is most useful in untranslated form so that developers may search for +#. * it when someone reports it in a bug report (as we want users to do for all bugs, +#. * as indicated by it being a g_warning string). +#. * +#. * Otherwise, if it is not a programming bug but a network error or a bug in the +#. * remote peer (perhaps running different software) or whatever, then present it in +#. * an alert box, and avoid use of technical jargon `NULL'. +#. +#: ../../po/../src/jabber_whiteboard/message-utilities.cpp:171 +msgid "" +"ID for new object is NULL even after generation and lookup attempts: the new " +"object will NOT be sent, nor will any of its child objects!" +msgstr "" +"L'ID du nouvel objet est NULL, même après des tentatives de création et de " +"recherche : le nouvel objet ne sera PAS envoyé, ni aucun de des descendants !" + +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:60 +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:995 +msgid "Select a location and filename" +msgstr "Sélectionner un emplacement et un nom de fichier" + +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:62 +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:997 +msgid "Set filename" +msgstr "Définir un nom de fichier" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:301 +msgid "No SSL certificate was found." +msgstr "Aucun certificat SSL trouvé." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:304 +msgid "The SSL certificate provided by the Jabber server is untrusted." +msgstr "" +"Le certificat SSL fourni par le serveur Jabber n'est pas digne de confiance." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:307 +msgid "The SSL certificate provided by the Jabber server is expired." +msgstr "Le certificat SSL fourni par le serveur Jabber a expiré." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:310 +msgid "" +"The SSL certificate provided by the Jabber server has not been activated." +msgstr "Le certificat SSL fourni par le serveur Jabber n'a pas été activé." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:313 +msgid "" +"The SSL certificate provided by the Jabber server contains a hostname that " +"does not match the Jabber server's hostname." +msgstr "" +"Le certificat SSL fourni par le serveur Jabber contient un nom d'hôte qui ne " +"correspond pas à celui du serveur Jabber." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:316 +msgid "" +"The SSL certificate provided by the Jabber server contains an invalid " +"fingerprint." +msgstr "" +"Le certificat SSL fourni par le serveur Jabber contient une empreinte " +"invalide." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:319 +msgid "An unknown error occurred while setting up the SSL connection." +msgstr "Erreur inconnue lors de l'établissement de la connection SSL." + +#. TRANSLATORS: %1 is the message that describes the specific error that occurred when +#. establishing the SSL connection. +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:325 +msgid "" +"%1\n" +"\n" +"Do you wish to continue connecting to the Jabber server?" +msgstr "" +"%1\n" +"\n" +"Voulez-vous poursuivre la connection au serveur Jabber ?" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:328 +msgid "Continue connecting and ignore further errors" +msgstr "Poursuivre la connection et ignorer les prochaines erreurs" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:329 +msgid "Continue connecting, but warn me of further errors" +msgstr "Poursuivre la connection, mais me prévenir des erreurs suivantes" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:330 +msgid "Cancel connection" +msgstr "Annuler la connection" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:777 +#, c-format +msgid "Established whiteboard session with %s." +msgstr "Session de tableau blanc établie avec %s." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:785 +#, c-format +msgid "%s has left the whiteboard session." +msgstr "%s a quitté la session de tableau blanc." + +#. Inform the user +#. TRANSLATORS: %1 is the name of the user that disconnected, %2 is the name of the user whom the disconnected user disconnected from. +#. This message is not used in a chatroom context. +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:790 +msgid "" +"The user %1 has left the " +"whiteboard session.\n" +"\n" +msgstr "" +"L'utilisateur %1 a quitté la " +"session de tableau blanc.\n" +"\n" + +#. TRANSLATORS: %1 and %2 are userids +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:792 +msgid "" +"You are still connected to a Jabber server as %2, and may establish a " +"new session to %1 or a different user." +msgstr "" +"Vous êtes toujours connecté(e) à un serveur Jabber en tant que %2, et " +"pouvez établir une nouvelle session avec %1 ou un autre utilisateur." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:988 +msgid "" +"Could not open file %1 for session recording.\n" +"The error encountered was: %2.\n" +"\n" +"You may select a different location to record the session, or you may opt to " +"not record this session." +msgstr "" +"Impossible d'ouvrir le fichier %1 pour enregistrer la session.\n" +"Erreur rencontrée : %2.\n" +"\n" +"Vous pouvez choisir un autre emplacement pour enregistrer la session, ou " +"décider de ne pas l'enregistrer." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:990 +msgid "Choose a different location" +msgstr "Choisir un emplacement différent" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:991 +msgid "Skip session recording" +msgstr "Passer l'enregistrement de la session" + +#: ../../po/../src/knot.cpp:673 +msgid "Node or handle drag canceled." +msgstr "Déplacement de nœud ou de poignée annulé." + +#: ../../po/../src/libnrtype/FontFactory.cpp:358 +msgid "Ignoring font without family that will crash Pango" +msgstr "Ignorer les polices sans famille qui font planter Pango" + +#: ../../po/../src/main.cpp:395 +msgid "Print the Inkscape version number" +msgstr "Afficher la version d'Inkscape" + +#: ../../po/../src/main.cpp:400 +msgid "Do not use X server (only process files from console)" +msgstr "" +"Ne pas utiliser le serveur X (traiter les fichiers seulement depuis la " +"console)" + +#: ../../po/../src/main.cpp:405 +msgid "Try to use X server (even if $DISPLAY is not set)" +msgstr "Essayer d'utiliser le serveur X (même si $DISPLAY n'est pas défini)" + +#: ../../po/../src/main.cpp:410 +msgid "Open specified document(s) (option string may be excluded)" +msgstr "Ouvrir les document(s) spécifiés (la chaîne d'option peut être exclue)" + +#: ../../po/../src/main.cpp:411 ../../po/../src/main.cpp:416 +#: ../../po/../src/main.cpp:421 ../../po/../src/main.cpp:483 +#: ../../po/../src/main.cpp:488 ../../po/../src/main.cpp:493 +msgid "FILENAME" +msgstr "NOM_DE_FICHIER" + +#: ../../po/../src/main.cpp:415 +msgid "Print document(s) to specified output file (use '| program' for pipe)" +msgstr "" +"Imprimer les document(s) dans le fichier de sortie spécifié (utilisez '| " +"programme ' pour relier à un programme)" + +#: ../../po/../src/main.cpp:420 +msgid "Export document to a PNG file" +msgstr "Exporter le document sous forme d'image PNG" + +#: ../../po/../src/main.cpp:425 +msgid "The resolution used for exporting SVG into bitmap (default 90)" +msgstr "La résolution utilisée pour exporter un SVG en bitmap (défaut 90)" + +#: ../../po/../src/main.cpp:426 +msgid "DPI" +msgstr "PPP" + +#: ../../po/../src/main.cpp:430 +msgid "" +"Exported area in SVG user units (default is the canvas; 0,0 is lower-left " +"corner)" +msgstr "" +"Zone à exporter en unités utilisateur SVG (par défaut, le canevas entier; 0, " +"0 est le coin inférieur gauche)" + +#: ../../po/../src/main.cpp:431 +msgid "x0:y0:x1:y1" +msgstr "x0:y0:x1:y1" + +#: ../../po/../src/main.cpp:435 +msgid "Exported area is the entire drawing (not canvas)" +msgstr "La zone à exporter est le dessin entier (pas le canevas)" + +#: ../../po/../src/main.cpp:440 +msgid "" +"Snap the bitmap export area outwards to the nearest integer values (in SVG " +"user units)" +msgstr "" +"Faire coller la zone d'exportation de bitmap aux valeurs entières " +"supérieures les plus proches (en unités utilisateur SVG)" + +#: ../../po/../src/main.cpp:445 +msgid "The width of exported bitmap in pixels (overrides export-dpi)" +msgstr "La largeur en pixels du bitmap exporté (redéfinit la résolution)" + +#: ../../po/../src/main.cpp:446 +msgid "WIDTH" +msgstr "LARGEUR" + +#: ../../po/../src/main.cpp:450 +msgid "The height of exported bitmap in pixels (overrides export-dpi)" +msgstr "La hauteur en pixels du bitmap exporté (redéfinit la résolution)" + +#: ../../po/../src/main.cpp:451 +msgid "HEIGHT" +msgstr "HAUTEUR" + +#: ../../po/../src/main.cpp:455 +msgid "The ID of the object to export (overrides export-area)" +msgstr "L'ID de l'objet à exporter (redéfinit la zone d'exportation)" + +#: ../../po/../src/main.cpp:456 ../../po/../src/main.cpp:532 +msgid "ID" +msgstr "ID" + +#. TRANSLATORS: this means: "Only export the object whose id is given in --export-id". +#. See "man inkscape" for details. +#: ../../po/../src/main.cpp:462 +msgid "" +"Export just the object with export-id, hide all others (only with export-id)" +msgstr "" +"N'exporter que l'objet avec export-id, cacher tous les autres (seulement " +"avec export-id)" + +#: ../../po/../src/main.cpp:467 +msgid "Use stored filename and DPI hints when exporting (only with export-id)" +msgstr "" +"Utiliser le nom de fichier et la résolution enregistrés lors de " +"l'exportation (seulement avec export-id)" + +#: ../../po/../src/main.cpp:472 +msgid "Background color of exported bitmap (any SVG-supported color string)" +msgstr "" +"Couleur de fond du bitmap exporté (n'importe quelle code de couleur permis " +"par SVG)" + +#: ../../po/../src/main.cpp:473 +msgid "COLOR" +msgstr "COULEUR" + +#: ../../po/../src/main.cpp:477 +msgid "Background opacity of exported bitmap (either 0.0 to 1.0, or 1 to 255)" +msgstr "Opacité du fond du bitmap exporté (entre 0.0 et 1.0 ou 1 et 255))" + +#: ../../po/../src/main.cpp:478 +msgid "VALUE" +msgstr "VALEUR" + +#: ../../po/../src/main.cpp:482 +msgid "Export document to plain SVG file (no sodipodi or inkscape namespaces)" +msgstr "" +"Exporter le document en SVG simple (sans espace de nom de Sodipodi ou " +"d'Inkscape)" + +#: ../../po/../src/main.cpp:487 +msgid "Export document to a PS file" +msgstr "Exporter le document en fichier PS" + +#: ../../po/../src/main.cpp:492 +msgid "Export document to an EPS file" +msgstr "Exporter le document en fichier EPS" + +#: ../../po/../src/main.cpp:497 +msgid "Convert text object to paths on export (EPS)" +msgstr "Convertir les objets texte en chemins lors de l'export (EPS)" + +#: ../../po/../src/main.cpp:502 +msgid "Export files with the bounding box set to the page size (EPS)" +msgstr "Exporter les fichiers avec pour boîte de contour la page (EPS)" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:508 +msgid "" +"Query the X coordinate of the drawing or, if specified, of the object with --" +"query-id" +msgstr "" +"Demander l'abscisse (coordonnée X) du dessin ou, si spécifié avec --query-" +"id, de l'objet" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:514 +msgid "" +"Query the Y coordinate of the drawing or, if specified, of the object with --" +"query-id" +msgstr "" +"Demander l'ordonnée (coordonnée Y) du dessin ou, si spécifié avec --query-" +"id, de l'objet" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:520 +msgid "" +"Query the width of the drawing or, if specified, of the object with --query-" +"id" +msgstr "" +"Demander la largeur du dessin ou, si spécifié avec --query-id, de l'objet" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:526 +msgid "" +"Query the height of the drawing or, if specified, of the object with --query-" +"id" +msgstr "" +"Demander la hauteur du dessin ou, si spécifié avec --query-id, de l'objet" + +#: ../../po/../src/main.cpp:531 +msgid "The ID of the object whose dimensions are queried" +msgstr "L'ID de l'objet dont les dimensions sont demandées" + +#. TRANSLATORS: this option makes Inkscape print the name (path) of the extension directory +#: ../../po/../src/main.cpp:537 +msgid "Print out the extension directory and exit" +msgstr "Lister le contenu du répertoire d'extensions, puis sortir" + +#: ../../po/../src/main.cpp:542 +msgid "Show given files one-by-one, switch to next on any key/mouse event" +msgstr "" +"Afficher les fichiers donnés un par un, passer au suivant à chaque événement " +"clavier/souris" + +#: ../../po/../src/main.cpp:547 +msgid "Use the new Gtkmm GUI interface" +msgstr "Utiliser la nouvelle interface Gtkmm" + +#: ../../po/../src/main.cpp:552 +msgid "Remove unused definitions from the defs section(s) of the document" +msgstr "Retirer les éléments inutiles des section(s) defs du document" + +#: ../../po/../src/main.cpp:741 +msgid "" +"[OPTIONS...] [FILE...]\n" +"\n" +"Available options:" +msgstr "" +"[OPTIONS...] [FICHIER...]\n" +"\n" +"Options disponibles :" + +#: ../../po/../src/menus-skeleton.h:17 +msgid "_New" +msgstr "_Nouveau" + +#: ../../po/../src/menus-skeleton.h:22 +msgid "Open _Recent" +msgstr "_Récemment ouvert" + +#: ../../po/../src/menus-skeleton.h:53 +msgid "_Edit" +msgstr "_Edition" + +#: ../../po/../src/menus-skeleton.h:84 +msgid "_View" +msgstr "_Vue" + +#: ../../po/../src/menus-skeleton.h:85 +#, fuzzy +msgid "_Zoom" +msgstr "Zoom" + +#: ../../po/../src/menus-skeleton.h:102 +msgid "Show/Hide" +msgstr "Afficher/cacher" + +#: ../../po/../src/menus-skeleton.h:107 +msgid "_Display mode" +msgstr "" + +#: ../../po/../src/menus-skeleton.h:126 +msgid "_Layer" +msgstr "Ca_lque" + +#: ../../po/../src/menus-skeleton.h:143 +msgid "_Object" +msgstr "_Objet" + +#: ../../po/../src/menus-skeleton.h:165 +msgid "_Path" +msgstr "Chemin (_p)" + +#: ../../po/../src/menus-skeleton.h:188 +msgid "_Text" +msgstr "_Texte" + +#: ../../po/../src/menus-skeleton.h:200 +msgid "Effects" +msgstr "Effets" + +#: ../../po/../src/menus-skeleton.h:207 +msgid "Whiteboa_rd" +msgstr "Tableau blanc (_r)" + +#: ../../po/../src/menus-skeleton.h:220 +msgid "_Help" +msgstr "Aide (_h)" + +#: ../../po/../src/menus-skeleton.h:222 +msgid "Tutorials" +msgstr "Didacticiels" + +#: ../../po/../src/node-context.cpp:382 +msgid "" +"Ctrl: toggle node type, snap handle angle, move hor/vert; Ctrl" +"+Alt: move along handles" +msgstr "" +"Ctrl : selon le contexte, modifier le type des nœuds, forcer la " +"modification des angles de leurs poignées par incréments, forcer le " +"déplacement horizontal/vertical; Ctrl+Alt : déplacer le long des " +"poignées" + +#: ../../po/../src/node-context.cpp:383 +msgid "" +"Shift: toggle node selection, disable snapping, rotate both handles" +msgstr "" +"Maj : selon le contexte, sélection multiple des nœuds, désactiver le " +"collage, forcer la rotation simultanée des deux poignées des noeuds " +"sélectionnés" + +#: ../../po/../src/node-context.cpp:384 +msgid "Alt: lock handle length; Ctrl+Alt: move along handles" +msgstr "" +"Alt : bloquer la longueur des poignées; Ctrl+Alt : déplacer le " +"long des poignées" + +#: ../../po/../src/nodepath.cpp:1399 ../../po/../src/nodepath.cpp:1411 +#: ../../po/../src/nodepath.cpp:1492 ../../po/../src/nodepath.cpp:1504 +msgid "To join, you must have two endnodes selected." +msgstr "" +"Pour joindre, vous devez avoir sélectionné deux nœuds terminaux." + +#: ../../po/../src/nodepath.cpp:1633 ../../po/../src/nodepath.cpp:1647 +msgid "" +"Select two non-endpoint nodes on a path between which to delete " +"segments." +msgstr "" +"Vous devez sélectionner deux nœuds non-terminaux d'un chemin pour " +"supprimer un segment entre eux." + +#: ../../po/../src/nodepath.cpp:1743 +msgid "Cannot find path between nodes." +msgstr "Impossible de trouver un chemin entre les nœuds." + +#: ../../po/../src/nodepath.cpp:2822 +#, c-format +msgid "" +"Node handle: angle %0.2f°, length %s; with Ctrl to snap " +"angle; with Alt to lock length; with Shift to rotate both " +"handles" +msgstr "" +"Poignée de contrôle de nœud: %0.2f°, longueur %s; Ctrl " +"pour tourner par incréments; Alt pour préserver la longueur; Maj pour tourner les 2 poignées simultanément" + +#: ../../po/../src/nodepath.cpp:3351 +msgid "" +"Node: drag to edit the path; with Ctrl to snap to horizontal/" +"vertical; with Ctrl+Alt to snap to handles' directions" +msgstr "" +"Nœuds : déplacer pour éditer le chemin; Ctrl pour faire coller " +"à la grille horizontalement/verticalement; Ctrl+Alt déplacer selon la " +"direction des poignées" + +#: ../../po/../src/nodepath.cpp:3375 +msgid "" +"Node handle: drag to shape the curve; with Ctrl to snap angle; " +"with Alt to lock length; with Shift to rotate both handles" +msgstr "" +"Poignée de contrôle de nœud : la déplacer pour modifier la courbe; " +"Ctrl pour la tourner par incréments; Alt pour préserver sa " +"longueur; Maj pour tourner les deux poignées" + +#: ../../po/../src/nodepath.cpp:3399 +msgid "" +"Node handle: drag to shape the curve; with Ctrl to snap angle; " +"with Alt to lock length; with Shift to rotate the opposite " +"handle in sync" +msgstr "" +"Poignée de contrôle de nœud : la déplacer pour modifier la courbe; " +"Ctrl pour la tourner par incréments; Alt pour préserver sa " +"longueur; Maj pour tourner les deux poignées" + +#. TRANSLATORS: "end" is an adjective here (NOT a verb) +#: ../../po/../src/nodepath.cpp:3591 +msgid "end node" +msgstr "nœud terminal" + +#. TRANSLATORS: "cusp" means "sharp" (cusp node); see also the Advanced Tutorial +#: ../../po/../src/nodepath.cpp:3596 +msgid "cusp" +msgstr "dur" + +#. TRANSLATORS: "smooth" is an adjective here +#: ../../po/../src/nodepath.cpp:3599 +msgid "smooth" +msgstr "doux" + +#: ../../po/../src/nodepath.cpp:3601 +msgid "symmetric" +msgstr "symétrique" + +#. TRANSLATORS: "end" is an adjective here (NOT a verb) +#: ../../po/../src/nodepath.cpp:3607 +msgid "end node, handle retracted (drag with Shift to extend)" +msgstr "" +"nœud terminal, poignée de contrôle rétractée (cliquer-déplacer avec Maj pour la faire ressortir)" + +#: ../../po/../src/nodepath.cpp:3609 +msgid "one handle retracted (drag with Shift to extend)" +msgstr "" +"une poignée de contrôle rétractée (cliquer-déplacer avec Maj pour la " +"faire ressortir)" + +#: ../../po/../src/nodepath.cpp:3612 +msgid "both handles retracted (drag with Shift to extend)" +msgstr "" +"deux poignées de contrôle rétractées (cliquer-déplacer avec Maj pour " +"les faire ressortir)" + +#: ../../po/../src/nodepath.cpp:3624 +msgid "Drag nodes or node handles; arrow keys to move nodes" +msgstr "" +"Cliquer-déplacer les nœuds ou leurs poignées; flèche pour " +"déplacer les nœuds" + +#: ../../po/../src/nodepath.cpp:3625 +msgid "Drag the node or its handles; arrow keys to move the node" +msgstr "" +"Cliquer-déplacer le nœud ou ses poignées; flèche pour déplacer " +"le nœud" + +#: ../../po/../src/nodepath.cpp:3651 ../../po/../src/nodepath.cpp:3663 +msgid "Select a single object to edit its nodes or handles." +msgstr "Sélectionner un seul objet pour éditer ses nœuds ou poignées." + +#: ../../po/../src/nodepath.cpp:3655 +#, c-format +msgid "" +"0 out of %i node selected. Click, Shift+click, " +"or drag around nodes to select." +msgid_plural "" +"0 out of %i nodes selected. Click, Shift+click, " +"or drag around nodes to select." +msgstr[0] "" +"0 sur %i nœud sélectionné. Sélectionnez des nœuds par " +"Clic, Maj+Clic ou cliquer-déplacer." +msgstr[1] "" +"0 sur %i nœuds sélectionnés. Sélectionnez des nœuds par " +"Clic, Maj+Clic ou cliquer-déplacer." + +#: ../../po/../src/nodepath.cpp:3661 +msgid "Drag the handles of the object to modify it." +msgstr "Déplacer les poignées d'un objet pour le modifier." + +#: ../../po/../src/nodepath.cpp:3669 +#, c-format +msgid "%i of %i node selected; %s. %s." +msgid_plural "%i of %i nodes selected; %s. %s." +msgstr[0] "%i nœud sélectionné sur %i; %s. %s." +msgstr[1] "%i nœuds sélectionnés sur %i; %s. %s." + +#: ../../po/../src/nodepath.cpp:3675 +#, c-format +msgid "%i of %i node selected. %s." +msgid_plural "%i of %i nodes selected. %s." +msgstr[0] "%i nœud sélectionné sur %i. %s." +msgstr[1] "%i nœuds sélectionnés sur %i. %s." + +#: ../../po/../src/object-edit.cpp:493 +msgid "" +"Adjust the horizontal rounding radius; with Ctrl to make the " +"vertical radius the same" +msgstr "" +"Ajuster le rayon d'arrondi horizontal; Ctrl que le rayon " +"vertical soit identique" + +#: ../../po/../src/object-edit.cpp:499 +msgid "" +"Adjust the vertical rounding radius; with Ctrl to make the " +"horizontal radius the same" +msgstr "" +"Ajuster le rayon d'arrondi vertical; Ctrl pour que le rayon " +"horizontal soit identique" + +#: ../../po/../src/object-edit.cpp:506 ../../po/../src/object-edit.cpp:513 +msgid "" +"Adjust the width and height of the rectangle; with Ctrl to " +"lock ratio or stretch in one dimension only" +msgstr "" +"Ajuster la hauteur et la largeur du rectangle; Ctrl " +"verrouiller le rapport des dimensions ou incliner dans une seule dimension" + +#: ../../po/../src/object-edit.cpp:686 +msgid "Adjust ellipse width, with Ctrl to make circle" +msgstr "" +"Ajuster la largeur de l'ellipse; Ctrl pour en faire un cercle" + +#: ../../po/../src/object-edit.cpp:689 +msgid "Adjust ellipse height, with Ctrl to make circle" +msgstr "" +"Ajuster la hauteur de l'ellipse; Ctrl pour en faire un cercle" + +#: ../../po/../src/object-edit.cpp:692 +msgid "" +"Position the start point of the arc or segment; with Ctrl to " +"snap angle; drag inside the ellipse for arc, outside for " +"segment" +msgstr "" +"Positionner le point de départ de l'arc ou du camembert; Ctrl " +"pour touner par incréments; déplacer vers l'intérieur de l'ellipse " +"pour un arc, vers l'extérieur pour un camembert" + +#: ../../po/../src/object-edit.cpp:695 +msgid "" +"Position the end point of the arc or segment; with Ctrl to " +"snap angle; drag inside the ellipse for arc, outside for " +"segment" +msgstr "" +"Positionner le point final de l'arc ou du camembert; Ctrl pour " +"tourner par incréments; déplacer vers l'intérieur de l'ellipse pour " +"un arc, vers l'extérieur pour un camembert" + +#: ../../po/../src/object-edit.cpp:800 +msgid "" +"Adjust the tip radius of the star or polygon; with Shift to " +"round; with Alt to randomize" +msgstr "" +"Ajuster le rayon des sommets de l'étoile ou du polygone; Maj " +"pour arrondir; Alt pour rendre aléatoire" + +#: ../../po/../src/object-edit.cpp:803 +msgid "" +"Adjust the base radius of the star; with Ctrl to keep star " +"rays radial (no skew); with Shift to round; with Alt to " +"randomize" +msgstr "" +"Ajuster le rayon de base de l'étoile; Ctrl pour garder " +"l'étoile parfaitement radiale (pas d'inclinaison); Maj pour arrondir; " +"Alt pour rendre aléatoire" + +#: ../../po/../src/object-edit.cpp:967 +msgid "" +"Roll/unroll the spiral from inside; with Ctrl to snap angle; " +"with Alt to converge/diverge" +msgstr "" +"Enrouler/dérouler la spirale depuis l'intérieur; Ctrl pour " +"tourner par incréments; Alt pour la faire converger/diverger" + +#: ../../po/../src/object-edit.cpp:969 +msgid "" +"Roll/unroll the spiral from outside; with Ctrl to snap angle; " +"with Shift to scale/rotate" +msgstr "" +"Enrouler/dérouler la spirale depuis l'extérieur; Ctrl pour " +"tourner par incréments; Maj pour redimensionner/ tourner" + +#: ../../po/../src/object-edit.cpp:1006 +msgid "Adjust the offset distance" +msgstr "Ajuster la distance d'offset" + +#. TRANSLATORS: This refers to the pattern that's inside the object +#: ../../po/../src/object-edit.cpp:1036 +msgid "Move the pattern fill inside the object" +msgstr "Déplacer le motif de remplissage à l'intérieur de l'objet" + +#: ../../po/../src/object-edit.cpp:1038 +msgid "Scale the pattern fill uniformly" +msgstr "Mettre à l'échelle le motif de remplissage de façon uniforme" + +#: ../../po/../src/object-edit.cpp:1040 +msgid "Rotate the pattern fill; with Ctrl to snap angle" +msgstr "" +"Tourner le motif de remplissage; Ctrl pour tourner par " +"incréments" + +#: ../../po/../src/object-edit.cpp:1065 +msgid "Drag to resize the flowed text frame" +msgstr "Cliquer-déplacer pour redimensionner le cadre du texte" + +#. Item dialog +#: ../../po/../src/object-ui.cpp:106 +msgid "Object _Properties" +msgstr "_Propriétés de l'objet" + +#. Select item +#: ../../po/../src/object-ui.cpp:116 +msgid "_Select This" +msgstr "_Sélectionner ceci" + +#. Create link +#: ../../po/../src/object-ui.cpp:126 +msgid "_Create Link" +msgstr "_Créer un lien" + +#. "Ungroup" +#: ../../po/../src/object-ui.cpp:199 ../../po/../src/verbs.cpp:1931 +msgid "_Ungroup" +msgstr "_Dégrouper" + +#. Link dialog +#: ../../po/../src/object-ui.cpp:239 +msgid "Link _Properties" +msgstr "_Propriétés du lien" + +#. Select item +#: ../../po/../src/object-ui.cpp:249 +msgid "_Follow Link" +msgstr "Suivre le lien (_f)" + +#. Reset transformations +#: ../../po/../src/object-ui.cpp:254 +msgid "_Remove Link" +msgstr "_Retirer le lien" + +#. Link dialog +#: ../../po/../src/object-ui.cpp:303 +msgid "Image _Properties" +msgstr "_Propriétés de l'image" + +#. Item dialog +#: ../../po/../src/object-ui.cpp:344 +msgid "_Fill and Stroke" +msgstr "Remplissage et contour (_f)" + +#: ../../po/../src/path-chemistry.cpp:58 +msgid "Select at least two objects to combine." +msgstr "Sélectionner au moins 2 objets pour les combiner." + +#: ../../po/../src/path-chemistry.cpp:65 +msgid "At least one of the objects is not a path, cannot combine." +msgstr "Un des objets n'est pas un chemin, impossible de les combiner." + +#: ../../po/../src/path-chemistry.cpp:73 +msgid "" +"You cannot combine objects from different groups or layers." +msgstr "" +"Vous ne pouvez pas combiner des objets de différents groupes ou " +"calques." + +#: ../../po/../src/path-chemistry.cpp:155 +msgid "Select path(s) to break apart." +msgstr "Sélectionner des chemin(s) à séparer." + +#: ../../po/../src/path-chemistry.cpp:231 +msgid "No path(s) to break apart in the selection." +msgstr "Aucun chemin à séparer dans la sélection." + +#: ../../po/../src/path-chemistry.cpp:252 +msgid "Select object(s) to convert to path." +msgstr "Sélectionner les objet(s) à convertir en chemin." + +#: ../../po/../src/path-chemistry.cpp:297 +msgid "No objects to convert to path in the selection." +msgstr "Pas d'objet à convertir en chemin dans la sélection." + +#: ../../po/../src/path-chemistry.cpp:345 +msgid "Select path(s) to reverse." +msgstr "Sélectionner les chemin(s) à inverser." + +#: ../../po/../src/path-chemistry.cpp:370 +msgid "No paths to reverse in the selection." +msgstr "Aucun chemin à inverser dans la sélection." + +#: ../../po/../src/pen-context.cpp:379 ../../po/../src/pencil-context.cpp:233 +msgid "Continuing selected path" +msgstr "Prolongation du chemin sélectionné" + +#: ../../po/../src/pen-context.cpp:390 ../../po/../src/pencil-context.cpp:242 +msgid "Creating new path" +msgstr "Création d'un nouveau chemin" + +#: ../../po/../src/pen-context.cpp:394 ../../po/../src/pencil-context.cpp:246 +msgid "Appending to selected path" +msgstr "Ajout au chemin sélectionné" + +#: ../../po/../src/pen-context.cpp:538 +msgid "Click or click and drag to close and finish the path." +msgstr "" +"Cliquer ou cliquer-déplacer pour fermer et finir le chemin." + +#: ../../po/../src/pen-context.cpp:548 +msgid "" +"Click or click and drag to continue the path from this point." +msgstr "" +"Cliquer ou cliquer-déplacer pour prolonger le chemin à partir " +"de ce point." + +#: ../../po/../src/pen-context.cpp:857 +#, c-format +msgid "" +"%s: angle %3.2f°, distance %s; with Ctrl to snap angle, " +"Enter to finish the path" +msgstr "" +"%s: angle %3.2f°, distance %s; Ctrl pour tourner par " +"incréments, Entrée pour finir le chemin" + +#: ../../po/../src/pen-context.cpp:882 +#, c-format +msgid "" +"Curve handle: angle %3.2f°, length %s; with Ctrl to snap " +"angle" +msgstr "" +"Poignée de contrôle: angle %3.2f°,longueur %s; Ctrl pour " +"tourner par incréments" + +#: ../../po/../src/pen-context.cpp:912 +#, c-format +msgid "" +"%s: angle %3.2f°, length %s; with Ctrl to snap angle, " +"with Shift to move this handle only" +msgstr "" +"%s: angle %3.2f°, longueur %s; with Ctrl pour tourner par " +"incréments; Maj pour ne déplacer que cette poignée" + +#: ../../po/../src/pen-context.cpp:946 +msgid "Finishing pen" +msgstr "Tracé au stylo terminé" + +#: ../../po/../src/pencil-context.cpp:320 +msgid "Release here to close and finish the path." +msgstr "Relâcher ici pour fermer et finir le chemin." + +#: ../../po/../src/pencil-context.cpp:326 +msgid "Drawing a freehand path" +msgstr "Dessin d'une ligne à main levée" + +#: ../../po/../src/pencil-context.cpp:331 +msgid "Drag to continue the path from this point." +msgstr "Déplacer pour continuer le chemin à partir de ce point." + +#. Write curves to object +#: ../../po/../src/pencil-context.cpp:390 +msgid "Finishing freehand" +msgstr "Dessin à main levée terminé" + +#: ../../po/../src/rect-context.cpp:387 +msgid "" +"Ctrl: make square or integer-ratio rect, lock a rounded corner " +"circular" +msgstr "" +"Ctrl : forcer un rectangle carré ou de ratio entier, préserver le " +"rayon d'arrondi d'un coin" + +#: ../../po/../src/rect-context.cpp:549 +#, c-format +msgid "" +"Rectangle: %s × %s; with Ctrl to make square or integer-" +"ratio rectangle; with Shift to draw around the starting point" +msgstr "" +"Rectangle : %s × %s; Ctrl forcer un rectangle carré ou de " +"ratio entier; Maj dessiner autour du point de départ" + +#: ../../po/../src/select-context.cpp:243 +msgid "Move canceled." +msgstr "Déplacement annulé." + +#: ../../po/../src/select-context.cpp:252 +msgid "Selection canceled." +msgstr "Sélection annulée." + +#: ../../po/../src/select-context.cpp:642 +msgid "Ctrl: select in groups, move hor/vert" +msgstr "" +"Ctrl : sélectionner en groupes, déplacer horizontalement/verticalment" + +#: ../../po/../src/select-context.cpp:643 +msgid "Shift: toggle select, force rubberband, disable snapping" +msgstr "" +"Maj : selon le contexte, sélection multiple, forcer la bande étirable " +"ou désactiver le collage" + +#: ../../po/../src/select-context.cpp:644 +msgid "Alt: select under, move selected" +msgstr "Alt : sélectionner sous, déplacer la sélection" + +#: ../../po/../src/select-context.cpp:798 +#, fuzzy +msgid "Selected object is not a group. Cannot enter." +msgstr "" +"L'objet sélectionné n'est pas un chemin, impossible de l'éroder/" +"dilater." + +#: ../../po/../src/select-context.cpp:876 +#, c-format +msgid "" +"Move by %s, %s; with Ctrl to restrict to horizontal/vertical; " +"with Shift to disable snapping" +msgstr "" +"Déplacer de %s, %s; Ctrl restreindre à l'horizontale/" +"verticale; Maj désactiver le collage" + +#: ../../po/../src/selection-chemistry.cpp:228 +msgid "Nothing was deleted." +msgstr "Rien n'a été supprimé." + +#: ../../po/../src/selection-chemistry.cpp:259 +msgid "Select object(s) to duplicate." +msgstr "Sélectionner des objet(s) à dupliquer." + +#: ../../po/../src/selection-chemistry.cpp:420 +msgid "Select two or more objects to group." +msgstr "Sélectionner deux objets ou plus pour les grouper." + +#: ../../po/../src/selection-chemistry.cpp:428 +msgid "Select at least two objects to group." +msgstr "Sélectionner au moins deux objets pour les grouper." + +#: ../../po/../src/selection-chemistry.cpp:513 +msgid "Select a group to ungroup." +msgstr "Sélectionner un groupe à dégrouper." + +#: ../../po/../src/selection-chemistry.cpp:554 +msgid "No groups to ungroup in the selection." +msgstr "Aucun groupe à dégrouper dans la sélection." + +#: ../../po/../src/selection-chemistry.cpp:623 +msgid "Select objects to raise." +msgstr "Sélectionner des objets à monter." + +#: ../../po/../src/selection-chemistry.cpp:629 +#: ../../po/../src/selection-chemistry.cpp:681 +#: ../../po/../src/selection-chemistry.cpp:715 +#: ../../po/../src/selection-chemistry.cpp:773 +msgid "" +"You cannot raise/lower objects from different groups or layers." +msgstr "" +"Vous ne pouvez pas monter/descendre des objets de différents groupes " +"ou calques." + +#: ../../po/../src/selection-chemistry.cpp:673 +msgid "Select object(s) to raise to top." +msgstr "Sélectionner des objets à monter au premier plan." + +#: ../../po/../src/selection-chemistry.cpp:709 +msgid "Select object(s) to lower." +msgstr "Sélectionner des objet(s) à descendre." + +#: ../../po/../src/selection-chemistry.cpp:765 +msgid "Select object(s) to lower to bottom." +msgstr "Sélectionner des objet(s) à descendre à l'arrière plan." + +#: ../../po/../src/selection-chemistry.cpp:806 +msgid "Nothing to undo." +msgstr "Rien à défaire." + +#: ../../po/../src/selection-chemistry.cpp:813 +msgid "Nothing to redo." +msgstr "Rien à refaire." + +#: ../../po/../src/selection-chemistry.cpp:969 +msgid "Nothing was copied." +msgstr "Rien n'a été copié." + +#: ../../po/../src/selection-chemistry.cpp:1051 +msgid "Current layer is hidden. Unhide it to be able to paste to it." +msgstr "" +"Le calque courant est caché. Le rendre visible pour pouvoir y coller." + +#: ../../po/../src/selection-chemistry.cpp:1055 +msgid "Current layer is locked. Unlock it to be able to paste to it." +msgstr "" +"Le calque courant est verrouillé. Le déverrouiller pour pouvoir y " +"coller." + +#: ../../po/../src/selection-chemistry.cpp:1068 +#: ../../po/../src/selection-chemistry.cpp:1103 +msgid "Nothing on the clipboard." +msgstr "Rien dans le presse-papiers." + +#: ../../po/../src/selection-chemistry.cpp:1109 +msgid "Select object(s) to paste style to." +msgstr "Sélectionner des objet(s) sur lesquels coller un style ." + +#: ../../po/../src/selection-chemistry.cpp:1128 +msgid "Select object(s) to move to the layer above." +msgstr "Sélectionner des objet(s) à déplacer au calque du dessus." + +#: ../../po/../src/selection-chemistry.cpp:1146 +msgid "No more layers above." +msgstr "Plus de calque au-dessus." + +#: ../../po/../src/selection-chemistry.cpp:1160 +msgid "Select object(s) to move to the layer below." +msgstr "Sélectionner des objet(s) à déplacer au calque du dessous." + +#: ../../po/../src/selection-chemistry.cpp:1178 +msgid "No more layers below." +msgstr "Plus de calque en-dessous." + +#: ../../po/../src/selection-chemistry.cpp:1811 +msgid "Select a clone to unlink." +msgstr "Sélectionner un clone à délier." + +#: ../../po/../src/selection-chemistry.cpp:1842 +msgid "No clones to unlink in the selection." +msgstr "Aucun clone à délier dans la sélection." + +#: ../../po/../src/selection-chemistry.cpp:1859 +msgid "" +"Select a clone to go to its original. Select a linked offset " +"to go to its source. Select a text on path to go to the path. Select " +"a flowed text to go to its frame." +msgstr "" +"Sélectionner un clone pour sélectionner son original. Sélectionner un " +"offset lié pour sélectionner sa source. Sélectionner un texte " +"suivant un chemin pour sélectionner son chemin. Sélectionner un texte " +"encadré pour sélectionner son cadre." + +#: ../../po/../src/selection-chemistry.cpp:1882 +msgid "" +"Cannot find the object to select (orphaned clone, offset, textpath, " +"flowed text?)" +msgstr "" +"Impossible de trouver l'objet à sélectionner (clone orphelin, offset, " +"chemin de texte, texte encadré ?)" + +#: ../../po/../src/selection-chemistry.cpp:1888 +msgid "" +"The object you're trying to select is not visible (it is in <" +"defs>)" +msgstr "" +"L'objet que vous essayez de sélectionner n'est pas visible (il est " +"dans <defs>)" + +#: ../../po/../src/selection-chemistry.cpp:1915 +msgid "Select object(s) to convert to pattern." +msgstr "Sélectionner des objet(s) à convertir en motif de remplissage." + +#: ../../po/../src/selection-chemistry.cpp:2006 +msgid "Select an object with pattern fill to extract objects from." +msgstr "" +"Sélectionner un objet rempli avec un motif pour en extraire des objet" +"(s)." + +#: ../../po/../src/selection-chemistry.cpp:2059 +msgid "No pattern fills in the selection." +msgstr "Aucun motif de remplissage dans la sélection." + +#: ../../po/../src/selection-chemistry.cpp:2079 +msgid "Select object(s) to make a bitmap copy." +msgstr "Sélectionner des objet(s) pour en faire une copie bitmap." + +#: ../../po/../src/selection-describer.cpp:37 +msgid "Click selection to toggle scale/rotation handles" +msgstr "" +"Cliquer sur la sélection pour alterner les modes rotation/redimensionnement" + +#. no items +#: ../../po/../src/selection-describer.cpp:39 +msgid "" +"No objects selected. Click, Shift+click, or drag around objects to select." +msgstr "" +"Pas d'objets sélectionnés. Sélectionnez des objets par Clic, Maj+Clic ou " +"cliquer-déplacer." + +#: ../../po/../src/selection-describer.cpp:51 +#, c-format +msgid " in layer %s" +msgstr " dans le calque %s" + +#: ../../po/../src/selection-describer.cpp:54 +#, c-format +msgid " in layer %s" +msgstr " dans le calque %s" + +#: ../../po/../src/selection-describer.cpp:66 +msgid "Use Shift+D to look up original" +msgstr "Utilisez Maj+D pour sélectionner l'original" + +#: ../../po/../src/selection-describer.cpp:70 +msgid "Use Shift+D to look up path" +msgstr "Utilisez Maj+D pour sélectionner le chemin" + +#: ../../po/../src/selection-describer.cpp:74 +msgid "Use Shift+D to look up frame" +msgstr "Utilisez Maj+D pour sélectionner le cadre" + +#: ../../po/../src/selection-describer.cpp:84 +#, c-format +msgid "%i object selected" +msgid_plural "%i objects selected" +msgstr[0] "%i objet sélectionné" +msgstr[1] "%i objets sélectionnés" + +#: ../../po/../src/selection-describer.cpp:90 +#, c-format +msgid "%s%s. %s." +msgstr "%s%s. %s." + +#: ../../po/../src/selection-describer.cpp:94 +#, c-format +msgid "%s in %i layer. %s." +msgid_plural "%s in %i layers. %s." +msgstr[0] "%s dans %i calque. %s." +msgstr[1] "%s dans %i calques. %s." + +#: ../../po/../src/seltrans.cpp:498 +msgid "" +"Center of rotation and skewing: drag to reposition; scaling with " +"Shift also uses this center" +msgstr "" +"Centre de rotation/inclinaison : cliquer-déplacer pour le déplacer; " +"redimensionner avec Maj utilise aussi ce centre" + +#: ../../po/../src/seltrans.cpp:514 +msgid "" +"Squeeze or stretch selection; with Ctrl to scale uniformly; " +"with Shift to scale around rotation center" +msgstr "" +"Agrandir ou rétrécir la sélection; Ctrl pour redimensionner " +"uniformément; Maj pour redimensionner autour du centre de rotation" + +#: ../../po/../src/seltrans.cpp:515 +msgid "" +"Scale selection; with Ctrl to scale uniformly; with Shift to scale around rotation center" +msgstr "" +"Redimensionner la sélection; Ctrl pour redimensionner " +"uniformément autour du centre de rotation" + +#: ../../po/../src/seltrans.cpp:519 +msgid "" +"Skew selection; with Ctrl to snap angle; with Shift to " +"skew around the opposite side" +msgstr "" +"Incliner la sélection; Ctrl pour incliner par incréments; " +"Maj pour incliner autour du coin opposé" + +#: ../../po/../src/seltrans.cpp:520 +msgid "" +"Rotate selection; with Ctrl to snap angle; with Shift " +"to rotate around the opposite corner" +msgstr "" +"Tourner la sélection; Ctrl pour tourner par incréments; " +"Maj pour tourner autour du coin opposé" + +#: ../../po/../src/seltrans.cpp:829 ../../po/../src/seltrans.cpp:909 +#, c-format +msgid "Scale: %0.2f%% x %0.2f%%; with Ctrl to lock ratio" +msgstr "" +"Redimensionnement : %0.2f%% x %0.2f%%; Ctrl pour préserver le " +"ratio" + +#. TRANSLATORS: don't modify the first ";" (it will NOT be displayed as ";" - only the second one will be) +#: ../../po/../src/seltrans.cpp:984 +#, c-format +msgid "Skew: %0.2f°; with Ctrl to snap angle" +msgstr "" +"Inclinaison : %0.2f°; Ctrl pour incliner par incréments" + +#. TRANSLATORS: don't modify the first ";" (it will NOT be displayed as ";" - only the second one will be) +#: ../../po/../src/seltrans.cpp:1035 +#, c-format +msgid "Rotate: %0.2f°; with Ctrl to snap angle" +msgstr "Rotation : %0.2f°; Ctrl pour tourner par incréments" + +#: ../../po/../src/seltrans.cpp:1090 +#, c-format +msgid "Move center to %s, %s" +msgstr "Déplacer le centre en %s, %s" + +#: ../../po/../src/slideshow.cpp:90 +msgid "Inkscape slideshow" +msgstr "Diaporama Inkscape" + +#: ../../po/../src/sp-anchor.cpp:181 +#, c-format +msgid "Link to %s" +msgstr "Lien vers %s" + +#: ../../po/../src/sp-anchor.cpp:185 +msgid "Link without URI" +msgstr "Lien sans URI" + +#: ../../po/../src/sp-ellipse.cpp:438 ../../po/../src/sp-ellipse.cpp:870 +msgid "Ellipse" +msgstr "Ellipse" + +#: ../../po/../src/sp-ellipse.cpp:583 +msgid "Circle" +msgstr "Cercle" + +#: ../../po/../src/sp-ellipse.cpp:865 +msgid "Segment" +msgstr "Camembert" + +#: ../../po/../src/sp-ellipse.cpp:867 +msgid "Arc" +msgstr "Arc" + +#. TRANSLATORS: "Flow region" is an area where text is allowed to flow +#: ../../po/../src/sp-flowregion.cpp:276 +msgid "Flow region" +msgstr "Région d'encadrement" + +#. TRANSLATORS: A region "cut out of" a flow region; text is not allowed to flow inside the +#. * flow excluded region. flowRegionExclude in SVG 1.2: see +#. * http://www.w3.org/TR/2004/WD-SVG12-20041027/flow.html#flowRegion-elem and +#. * http://www.w3.org/TR/2004/WD-SVG12-20041027/flow.html#flowRegionExclude-elem. +#: ../../po/../src/sp-flowregion.cpp:493 +msgid "Flow excluded region" +msgstr "Région d'encadrement exclue" + +#: ../../po/../src/sp-flowtext.cpp:355 +#, c-format +msgid "Flowed text (%d characters)" +msgstr "Texte encadré (%d caractères)" + +#: ../../po/../src/sp-flowtext.cpp:357 +#, c-format +msgid "Linked flowed text (%d characters)" +msgstr "Texte encadré lié (%d caractères)" + +#: ../../po/../src/sp-guide.cpp:290 +msgid "vertical guideline" +msgstr "Guide vertical" + +#: ../../po/../src/sp-guide.cpp:292 +msgid "horizontal guideline" +msgstr "Guide horizontal" + +#: ../../po/../src/sp-image.cpp:835 +msgid "embedded" +msgstr "embarquée" + +#: ../../po/../src/sp-image.cpp:839 +msgid "(null_pointer)" +msgstr "(pointeur nul)" + +#: ../../po/../src/sp-image.cpp:843 +#, c-format +msgid "Image with bad reference: %s" +msgstr "Image avec une mauvaise référence : %s" + +#: ../../po/../src/sp-image.cpp:844 +#, c-format +msgid "Image %d × %d: %s" +msgstr "Image %d × %d : %s" + +#: ../../po/../src/sp-item-group.cpp:390 +#, c-format +msgid "Group of %d object" +msgid_plural "Group of %d objects" +msgstr[0] "Groupe de %d objet" +msgstr[1] "Groupe de %d objets" + +#: ../../po/../src/sp-item.cpp:720 +msgid "Object" +msgstr "Objet" + +#: ../../po/../src/sp-line.cpp:202 +msgid "Line" +msgstr "Ligne" + +#. TRANSLATORS COMMENT: %s is either "outset" or "inset" depending on sign +#: ../../po/../src/sp-offset.cpp:433 +#, c-format +msgid "Linked offset, %s by %f pt" +msgstr "Offset lié, %s de %f pt" + +#: ../../po/../src/sp-offset.cpp:434 ../../po/../src/sp-offset.cpp:438 +msgid "outset" +msgstr "dilater" + +#: ../../po/../src/sp-offset.cpp:434 ../../po/../src/sp-offset.cpp:438 +msgid "inset" +msgstr "éroder" + +#. TRANSLATORS COMMENT: %s is either "outset" or "inset" depending on sign +#: ../../po/../src/sp-offset.cpp:437 +#, c-format +msgid "Dynamic offset, %s by %f pt" +msgstr "Offset dynamique, %s de %f pt" + +#: ../../po/../src/sp-path.cpp:127 +#, c-format +msgid "Path (%i node)" +msgid_plural "Path (%i nodes)" +msgstr[0] "Chemin (%i nœud)" +msgstr[1] "Chemin (%i nœuds)" + +#: ../../po/../src/sp-polygon.cpp:216 +msgid "Polygon" +msgstr "Polygone" + +#: ../../po/../src/sp-polyline.cpp:179 +msgid "Polyline" +msgstr "Polyligne" + +#: ../../po/../src/sp-rect.cpp:250 +msgid "Rectangle" +msgstr "Rectangle" + +#. TRANSLATORS: since turn count isn't an integer, please adjust the +#. string as needed to deal with an localized plural forms. +#: ../../po/../src/sp-spiral.cpp:305 +#, c-format +msgid "Spiral with %3f turns" +msgstr "Spirale à %3f tours" + +#: ../../po/../src/sp-star.cpp:288 +#, c-format +msgid "Star with %d vertex" +msgid_plural "Star with %d vertices" +msgstr[0] "Étoile à %d branche" +msgstr[1] "Étoile à %d branches" + +#: ../../po/../src/sp-star.cpp:292 +#, c-format +msgid "Polygon with %d vertex" +msgid_plural "Polygon with %d vertices" +msgstr[0] "Polygone à %d sommet" +msgstr[1] "Polygone à %d sommets" + +#. TRANSLATORS: For description of font with no name. +#: ../../po/../src/sp-text.cpp:420 +msgid "<no name found>" +msgstr "<aucun nom trouvé>" + +#: ../../po/../src/sp-text.cpp:426 +#, c-format +msgid "Text on path (%s, %s)" +msgstr "Texte suivant un chemin (%s, %s)" + +#: ../../po/../src/sp-text.cpp:427 +#, c-format +msgid "Text (%s, %s)" +msgstr "Texte (%s, %s)" + +#. TRANSLATORS: Used for statusbar description for long chains: +#. * "Clone of: Clone of: ... in Layer 1". +#: ../../po/../src/sp-use.cpp:317 +msgid "..." +msgstr "..." + +#: ../../po/../src/sp-use.cpp:325 +#, c-format +msgid "Clone of: %s" +msgstr "Clone de : %s" + +#: ../../po/../src/sp-use.cpp:329 +msgid "Orphaned clone" +msgstr "Clone Orphelin" + +#: ../../po/../src/spiral-context.cpp:355 +msgid "Ctrl: snap angle" +msgstr "Ctrl : pour tourner par incréments" + +#: ../../po/../src/spiral-context.cpp:357 +msgid "Alt: lock spiral radius" +msgstr "Alt : préserver le rayon de la spirale" + +#: ../../po/../src/spiral-context.cpp:469 +#, c-format +msgid "" +"Spiral: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" +"Spirale : rayon %s, angle %5g°; avec Ctrl pour tourner " +"par incréments" + +#: ../../po/../src/splivarot.cpp:106 +msgid "Select at least 2 paths to perform a boolean operation." +msgstr "Sélectionner au moins 2 chemins pour une opération booléenne." + +#: ../../po/../src/splivarot.cpp:112 +msgid "" +"Select exactly 2 paths to perform difference, XOR, division, or path " +"cut." +msgstr "" +"Sélectionner exactement 2 chemins pour en faire une différence, une " +"exclusion ou les découper." + +#: ../../po/../src/splivarot.cpp:129 ../../po/../src/splivarot.cpp:144 +msgid "" +"Unable to determine the z-order of the objects selected for " +"difference, XOR, division, or path cut." +msgstr "" +"Impossible de déterminer l'ordre en z des objets sélectionnés pour en " +"faire une différence, une exclusion ou les découper." + +#: ../../po/../src/splivarot.cpp:174 +msgid "" +"One of the objects is not a path, cannot perform boolean operation." +msgstr "" +"Un des objets n'est pas un chemin, impossible d'effectuer une " +"opération booléenne." + +#. TRANSLATORS: "to outline" means "to convert stroke to path" +#: ../../po/../src/splivarot.cpp:554 +msgid "Select path(s) to outline." +msgstr "" +"Sélectionner des chemin(s) pour en convertir le contour en chemin" + +#. TRANSLATORS: "to outline" means "to convert stroke to path" +#: ../../po/../src/splivarot.cpp:748 +msgid "No stroked paths to outline in the selection." +msgstr "" +"Aucun contour (de chemin) à transformer en chemin dans la sélection." + +#: ../../po/../src/splivarot.cpp:832 +msgid "Selected object is not a path, cannot inset/outset." +msgstr "" +"L'objet sélectionné n'est pas un chemin, impossible de l'éroder/" +"dilater." + +#: ../../po/../src/splivarot.cpp:1040 +msgid "Select path(s) to inset/outset." +msgstr "Sélectionner des chemin(s) pour les éroder/dilater." + +#: ../../po/../src/splivarot.cpp:1257 +msgid "No paths to inset/outset in the selection." +msgstr "Aucun chemin à éroder/dilater dans la sélection." + +#: ../../po/../src/splivarot.cpp:1390 +msgid "Select path(s) to simplify." +msgstr "Sélectionner des chemin(s) à simplifier." + +#: ../../po/../src/splivarot.cpp:1417 +msgid "No paths to simplify in the selection." +msgstr "Aucun chemin à simplifier dans la sélection." + +#: ../../po/../src/star-context.cpp:362 +msgid "Ctrl: snap angle; keep rays radial" +msgstr "" +"Ctrl pour tourner par incréments; forcer la radialité des branches" + +#: ../../po/../src/star-context.cpp:470 +#, c-format +msgid "" +"Polygon: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" +"Polygone : rayon %s, angle %5g°; Ctrl pour tourner par " +"incréments" + +#: ../../po/../src/star-context.cpp:471 +#, c-format +msgid "Star: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" +"Étoile : rayon %s, angle %5g°; Ctrl pour tourner/incliner " +"par incréments" + +#: ../../po/../src/text-chemistry.cpp:90 +msgid "Select a text and a path to put text on path." +msgstr "" +"Sélectionner un texte et un chemin pour placer le texte suivant le " +"chemin." + +#: ../../po/../src/text-chemistry.cpp:95 +msgid "" +"This text object is already put to a path. Remove it from the path " +"first. Use Shift+D to look up its path." +msgstr "" +"Cet objet texte est déjà suivant un chemin. Le retirer du chemin " +"d'abord. Utiliser Maj+D pour trouver ce chemin." + +#. rect is the only SPShape which is not yet, and thus SVG forbids us from putting text on it +#: ../../po/../src/text-chemistry.cpp:101 +msgid "" +"You cannot put text on a rectangle in this version. Convert rectangle to " +"path first." +msgstr "" +"Vous ne pouvez pas mettre du texte dans un rectangle (dans cette version). " +"Il faut convertir le rectangle en chemin avant." + +#: ../../po/../src/text-chemistry.cpp:159 +msgid "Select a text on path to remove it from path." +msgstr "" +"Sélectionner un texte suivant un chemin pour le retirer de ce chemin." + +#: ../../po/../src/text-chemistry.cpp:181 +msgid "No texts-on-paths in the selection." +msgstr "Aucun texte suivant un chemin dans la sélection." + +#: ../../po/../src/text-chemistry.cpp:209 +#: ../../po/../src/text-chemistry.cpp:229 +msgid "Select text(s) to remove kerns from." +msgstr "Sélectionner des texte(s) pour en retirer les crénages." + +#: ../../po/../src/text-chemistry.cpp:250 +msgid "" +"Select a text and one or more paths or shapes to flow text " +"into frame." +msgstr "" +"Sélectionner un texte et un ou plusieurs chemins ou formes " +"pour y encadrer le texte." + +#: ../../po/../src/text-chemistry.cpp:322 +msgid "Select a flowed text to unflow it." +msgstr "Sélectionner un texte encadré pour le désencadrer." + +#: ../../po/../src/text-context.cpp:463 +msgid "Click to edit the text, drag to select part of the text." +msgstr "" +"Cliquer pour éditer le texte cliquer-déplacer pour " +"sélectionner une partie du texte." + +#: ../../po/../src/text-context.cpp:465 +msgid "" +"Click to edit the flowed text, drag to select part of the text." +msgstr "" +"Cliquer pour éditer le texte encadré, cliquer-déplacer pour " +"sélectionner une partie du texte." + +#: ../../po/../src/text-context.cpp:540 +msgid "Non-printable character" +msgstr "Caractère non imprimable" + +#: ../../po/../src/text-context.cpp:589 +#, c-format +msgid "Unicode: %s: %s" +msgstr "Unicode : %s : %s " + +#: ../../po/../src/text-context.cpp:591 ../../po/../src/text-context.cpp:855 +msgid "Unicode: " +msgstr "Unicode : " + +#: ../../po/../src/text-context.cpp:615 +msgid "Current layer is hidden. Unhide it to be able to add text." +msgstr "" +"Le calque courant est caché. Le rendre visible pour pouvoir y ajouter " +"du texte." + +#: ../../po/../src/text-context.cpp:619 +msgid "Current layer is locked. Unlock it to be able to add text." +msgstr "" +"Le calque courant est verrouillé. Le déverrouiller pour pouvoir y " +"ajouter du texte." + +#: ../../po/../src/text-context.cpp:673 +#, c-format +msgid "Flowed text frame: %s × %s" +msgstr "Cadre de texte : %s × %s" + +#: ../../po/../src/text-context.cpp:708 ../../po/../src/text-context.cpp:1464 +msgid "Type text; Enter to start new line." +msgstr "Taper le texte; Entrée pour commencer une nouvelle ligne." + +#: ../../po/../src/text-context.cpp:719 +msgid "Flowed text is created." +msgstr "Le texte encadré a été créé" + +#: ../../po/../src/text-context.cpp:722 +msgid "" +"The frame is too small for the current font size. Flowed text not " +"created." +msgstr "" +"Le cadre est trop petit pour la taille de police courante. Le texte " +"encadré n'a pas été créé." + +#: ../../po/../src/text-context.cpp:841 +msgid "No-break space" +msgstr "Espace insécable" + +#: ../../po/../src/text-context.cpp:1462 +msgid "Type flowed text; Enter to start new paragraph." +msgstr "" +"Taper le texte encadré; Entrée pour commencer un nouveau paragraphe." + +#: ../../po/../src/text-context.cpp:1472 ../../po/../src/tools-switch.cpp:189 +msgid "" +"Click to select or create text, drag to create flowed text; " +"then type." +msgstr "" +"Cliquer pour sélectionner ou créer un texte, cliquer-déplacer " +"pour créer un texte encadré; puis taper le texte." + +#: ../../po/../src/tools-switch.cpp:141 +msgid "" +"To edit a path, click, Shift+click, or drag around " +"nodes to select them, then drag nodes and handles. Click on an " +"object to select." +msgstr "" +"Pour éditer un chemin, sélectionnez des nœuds par cliquer, Maj" +"+cliquer ou cliquer-déplacer, puis déplacez les nœuds et/ou les " +"poignées. Cliquer sur un objet pour le sélectionner." + +#: ../../po/../src/tools-switch.cpp:147 +msgid "" +"Drag to create a rectangle. Drag controls to round corners and " +"resize. Click to select." +msgstr "" +"Cliquer-déplacer pour créer un rectangle. Déplacer les poignées pour arrondir les coins. Cliquer pour sélectionner." + +#: ../../po/../src/tools-switch.cpp:153 +msgid "" +"Drag to create an ellipse. Drag controls to make an arc or " +"segment. Click to select." +msgstr "" +"Cliquer-déplacer pour créer une ellipse. Déplacer les poignées " +"pour faire des arcs ou des camemberts. Cliquer pour sélectionner." + +#: ../../po/../src/tools-switch.cpp:159 +msgid "" +"Drag to create a star. Drag controls to edit the star shape. " +"Click to select." +msgstr "" +"Cliquer-déplacer pour créer une étoile. Déplacer les poignées " +"pour éditer la forme de l'étoile. Cliquer pour sélectionner." + +#: ../../po/../src/tools-switch.cpp:165 +msgid "" +"Drag to create a spiral. Drag controls to edit the spiral " +"shape. Click to select." +msgstr "" +"Cliquer-déplacer pour créer un spirale. Déplacer les poignées " +"pour modifier la forme de la spirale. Cliquer pour sélectionner." + +#: ../../po/../src/tools-switch.cpp:171 +msgid "" +"Drag to create a freehand line. Start drawing with Shift to " +"append to selected path." +msgstr "" +"Cliquer-déplacer pour créer une ligne à main levée. Commencer le " +"tracé en appuyant sur Maj pour l'ajouter au chemin sélectionné." + +#: ../../po/../src/tools-switch.cpp:177 +msgid "" +"Click or click and drag to start a path; with Shift to " +"append to selected path." +msgstr "" +"Cliquer ou cliquer-déplacer pour commencer un chemin; Maj pour ajouter au chemin sélectionné." + +#: ../../po/../src/tools-switch.cpp:183 +msgid "" +"Drag to paint a calligraphic stroke. Left/right arrow " +"keys adjust width, up/down adjust angle." +msgstr "" +"Cliquer-déplacer pour calligraphier. Les flèches gauche/" +"droite ajustent la largeur de la plume, haut/bas son " +"angle." + +#: ../../po/../src/tools-switch.cpp:195 +msgid "" +"Drag or double click to create a gradient on selected objects, " +"drag handles to adjust gradients." +msgstr "" +"Cliquer-déplacer ou double-cliquerpour créer un dégradé sur " +"les objets sélectionnés, déplacer les poignées pour ajuster les " +"dégradés." + +#: ../../po/../src/tools-switch.cpp:201 +msgid "" +"Click or drag around an area to zoom in, Shift+click to " +"zoom out." +msgstr "" +"Cliquer ou cliquer-déplacer sur une zone pour zoommer, Maj" +"+cliquer pour dézoommer." + +#: ../../po/../src/tools-switch.cpp:213 +msgid "Click and drag between shapes to create a connector." +msgstr "Cliquer et déplacer entre des formes pour créer un connecteur." + +#: ../../po/../src/trace/potrace/inkscape-potrace.cpp:553 +#: ../../po/../src/trace/potrace/inkscape-potrace.cpp:654 +#, c-format +msgid "Trace: %d. %ld nodes" +msgstr "Vectoriser : %d. %ld nœuds" + +#: ../../po/../src/trace/trace.cpp:53 ../../po/../src/trace/trace.cpp:62 +#: ../../po/../src/trace/trace.cpp:70 +msgid "Select an image to trace" +msgstr "Sélectionner une image à vectoriser" + +#: ../../po/../src/trace/trace.cpp:133 +msgid "Trace: No active document" +msgstr "Vectoriser : pas de document actif" + +#: ../../po/../src/trace/trace.cpp:154 +msgid "Trace: Image has no bitmap data" +msgstr "Vectoriser : l'image ne contient pas de données bitmap" + +#: ../../po/../src/trace/trace.cpp:267 +#, c-format +msgid "Trace: Done. %ld nodes created" +msgstr "Vectorisation effectuée. %ld nœuds créés." + +#: ../../po/../src/ui/dialog/aboutbox.cpp:59 ../../po/../src/verbs.cpp:2212 +msgid "About Inkscape" +msgstr "À propos d'Inkscape" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:66 +msgid "_Splash" +msgstr "" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:68 +#, fuzzy +msgid "_Authors" +msgstr "Auteurs" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:69 +#, fuzzy +msgid "_Translators" +msgstr "Traducteurs" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:70 +msgid "_License" +msgstr "_License" + +#. TRANSLATORS: This is the filename of the `About Inkscape' picture in +#. the `screens' directory. Thus the translation of "about.svg" should be +#. the filename of its translated version, e.g. about.zh.svg for Chinese. +#. +#. N.B. about.svg changes once per release. (We should probably rename +#. the original to about-0.40.svg etc. as soon as we have a translation. +#. If we do so, then add an item to release-checklist saying that the +#. string here should be changed.) +#. FIXME? INKSCAPE_SCREENSDIR and "about.svg" are in UTF-8, not the +#. native filename encoding... and the filename passed to sp_document_new +#. should be in UTF-*8.. +#: ../../po/../src/ui/dialog/aboutbox.cpp:114 +msgid "about.svg" +msgstr "about.svg" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:464 +msgid "Minimum horizontal gap (in px units) between bounding boxes" +msgstr "" + +#. TRANSLATORS: Horizontal gap +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:466 +#: ../../po/../src/widgets/toolbox.cpp:1556 +msgid "H:" +msgstr "H :" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:474 +msgid "Minimum vertical gap (in px units) between bounding boxes" +msgstr "" + +#. TRANSLATORS: Vertical gap +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:476 +msgid "V:" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:734 +msgid "Align" +msgstr "Aligner" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:735 +msgid "Distribute" +msgstr "Distribuer" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:736 +msgid "Remove overlaps" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:737 +msgid "Nodes" +msgstr "Nœuds" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:742 +msgid "Relative to: " +msgstr "Relativement à : " + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:747 +msgid "Align right sides of objects to left side of anchor" +msgstr "Aligner les côtés droits des objets au coté gauche de l'ancre" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:750 +msgid "Align left sides" +msgstr "Aligner les côtés gauches" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:753 +msgid "Center on vertical axis" +msgstr "Centrer selon un axe vertical" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:756 +msgid "Align right sides" +msgstr "Aligner les côtés droits" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:759 +msgid "Align left sides of objects to right side of anchor" +msgstr "Aligner les côtés gauches des objets au coté droit de l'ancre" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:762 +msgid "Align bottoms of objects to top of anchor" +msgstr "Aligner les bas des objets avec le haut de l'ancre" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:765 +msgid "Align tops" +msgstr "Aligner les hauts des objets" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:768 +msgid "Center on horizontal axis" +msgstr "Centrer selon un axe horizontal" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:771 +msgid "Align bottoms" +msgstr "Aligner les bas des objets" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:774 +msgid "Align tops of objects to bottom of anchor" +msgstr "Aligner les hauts des objets avec le bas de l'ancre" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:779 +msgid "Align baseline anchors of texts vertically" +msgstr "Aligner verticalement les ancres des objets texte" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:782 +msgid "Align baseline anchors of texts horizontally" +msgstr "Aligner horizontalement les ancres des objets texte" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:787 +msgid "Make horizontal gaps between objects equal" +msgstr "Distribuer des distances égales horizontalement entre les objets" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:791 +msgid "Distribute left sides equidistantly" +msgstr "Distribuer des distances égales entre les côtés gauches des objets" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:794 +msgid "Distribute centers equidistantly horizontally" +msgstr "" +"Distribuer des distances égales horizontalement entre les centres des objets" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:797 +msgid "Distribute right sides equidistantly" +msgstr "Distribuer des distances égales entre les côtés droits des objets" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:801 +msgid "Make vertical gaps between objects equal" +msgstr "Distribuer des distances égales verticalement entre les objets " + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:805 +msgid "Distribute tops equidistantly" +msgstr "Distribuer des distances égales entre les côtés hauts des objets" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:808 +msgid "Distribute centers equidistantly vertically" +msgstr "" +"Distribuer des distances égales verticalement entre les centres des objets" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:811 +msgid "Distribute bottoms equidistantly" +msgstr "Distribuer des distances égales entre les côtés bas des objets" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:816 +msgid "Distribute baseline anchors of texts horizontally" +msgstr "" +"Distribuer des distances égales horizontalement entre les ancres des objets " +"texte" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:819 +msgid "Distribute baseline anchors of texts vertically" +msgstr "" +"Distribuer des distances égales verticalement entre les ancres des objets " +"texte" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:824 +msgid "Randomize centers in both dimensions" +msgstr "Eparpiller aléatoirement les centres dans toutes les directions" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:827 +msgid "Unclump objects: try to equalize edge-to-edge distances" +msgstr "Eparpiller les objets : tenter d'égaliser les distances de bord à bord" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:832 +msgid "" +"Move objects as little as possible so that their bounding boxes do not " +"overlap" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:837 +msgid "Align selected nodes horizontally" +msgstr "Aligner les nœuds sélectionnés horizontalement" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:840 +msgid "Align selected nodes vertically" +msgstr "Aligner les nœuds sélectionnés verticalement" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:843 +msgid "Distribute selected nodes horizontally" +msgstr "" +"Distribuer des distances égales horizontalement entre les nœuds sélectionnés" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:846 +msgid "Distribute selected nodes vertically" +msgstr "" +"Distribuer des distances égales verticalement entre les nœuds sélectionnés" + +#. Rest of the widgetry +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:851 +msgid "Last selected" +msgstr "Dernier sélectionné" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:852 +msgid "First selected" +msgstr "Premier sélectionné" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:853 +msgid "Biggest item" +msgstr "Élément le plus gros" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:854 +msgid "Smallest item" +msgstr "Élément le plus petit" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:856 +#: ../../po/../src/widgets/desktop-widget.cpp:1065 +msgid "Drawing" +msgstr "Dessin" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:91 +#, fuzzy +msgid "Metadata 1" +msgstr "Métadonnées" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:92 +#, fuzzy +msgid "Metadata 2" +msgstr "Métadonnées" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:187 +#, fuzzy +msgid "X coordinate of grid origin" +msgstr "Coordonnée verticale de la sélection" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:189 +#, fuzzy +msgid "Y coordinate of grid origin" +msgstr "Coordonnée verticale de la sélection" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:191 +#, fuzzy +msgid "Distance of vertical grid lines" +msgstr "Guide vertical" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:193 +#, fuzzy +msgid "Distance of horizontal grid lines" +msgstr "Guide horizontal" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:197 +msgid "Max. snapping distance from grid" +msgstr "" + +#: ../../po/../src/ui/dialog/export.cpp:34 +msgid "Export" +msgstr "Exporter" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:36 +msgid "Fill" +msgstr "Remplissage" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:37 +msgid "Stroke Paint" +msgstr "Remplissage du contour" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:38 +msgid "Stroke Style" +msgstr "Style du contour" + +#: ../../po/../src/ui/dialog/find.cpp:34 +msgid "Find" +msgstr "Rechercher" + +#: ../../po/../src/ui/dialog/memory.cpp:96 +msgid "Heap" +msgstr "Pas" + +#: ../../po/../src/ui/dialog/memory.cpp:97 +msgid "In Use" +msgstr "Utilisée" + +#. TRANSLATORS: "Slack" refers to memory which is in the heap but currently unused. +#. More typical usage is to call this memory "free" rather than "slack". +#: ../../po/../src/ui/dialog/memory.cpp:100 +msgid "Slack" +msgstr "Molle" + +#: ../../po/../src/ui/dialog/memory.cpp:101 +msgid "Total" +msgstr "Total" + +#: ../../po/../src/ui/dialog/memory.cpp:141 +#: ../../po/../src/ui/dialog/memory.cpp:147 +#: ../../po/../src/ui/dialog/memory.cpp:154 +#: ../../po/../src/ui/dialog/memory.cpp:186 +msgid "Unknown" +msgstr "Inconnu" + +#: ../../po/../src/ui/dialog/memory.cpp:167 +msgid "Combined" +msgstr "Combinée" + +#: ../../po/../src/ui/dialog/memory.cpp:209 +msgid "Recalculate" +msgstr "Recalculer" + +#: ../../po/../src/ui/dialog/messages.cpp:74 +msgid "Ready." +msgstr "Prêt." + +#: ../../po/../src/ui/dialog/messages.cpp:75 +msgid "" +"Enable log display by setting dialogs.debug 'redirect' attribute to 1 in " +"preferences.xml" +msgstr "" +"Activer l'affichage des logs en attribuant 1 à dialogs.debug 'redirect' dans " +"preferences.xml" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:184 +msgid "_Execute Python" +msgstr "_Exécuter Python" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:186 +msgid "_Execute Perl" +msgstr "_Exécuter Perl" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:195 +msgid "Script" +msgstr "Script" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:205 +msgid "Output" +msgstr "Résultat" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:215 +msgid "Errors" +msgstr "Erreurs" + +#. Dialog organization +#: ../../po/../src/ui/dialog/session-player.cpp:73 +msgid "Session file" +msgstr "Fichier de session" + +#: ../../po/../src/ui/dialog/session-player.cpp:74 +msgid "Playback controls" +msgstr "Contrôles du playback" + +#: ../../po/../src/ui/dialog/session-player.cpp:75 +msgid "Message information" +msgstr "Message information" + +#. Active session file display +#. fixme: Does this mean the active file for the session, or the file for the active session? +#. Please indicate which with a TRANSLATORS comment. +#: ../../po/../src/ui/dialog/session-player.cpp:85 +msgid "Active session file:" +msgstr "Fichier de session actif :" + +#: ../../po/../src/ui/dialog/session-player.cpp:86 +msgid "Delay (milliseconds):" +msgstr "Délai (millisecondes) :" + +#. Unload/load buttons +#: ../../po/../src/ui/dialog/session-player.cpp:94 +msgid "Close file" +msgstr "Fermer le fichier" + +#: ../../po/../src/ui/dialog/session-player.cpp:95 +msgid "Open new file" +msgstr "Ouvrir un nouveau fichier" + +#: ../../po/../src/ui/dialog/session-player.cpp:96 +msgid "Set delay" +msgstr "Définir le délai" + +#: ../../po/../src/ui/dialog/session-player.cpp:138 +msgid "Rewind" +msgstr "Revenir au début" + +#: ../../po/../src/ui/dialog/session-player.cpp:139 +msgid "Go back one change" +msgstr "Revenir d'un changement" + +#: ../../po/../src/ui/dialog/session-player.cpp:140 +msgid "Pause" +msgstr "Pause" + +#: ../../po/../src/ui/dialog/session-player.cpp:141 +msgid "Go forward one change" +msgstr "Avancer d'un changement" + +#: ../../po/../src/ui/dialog/session-player.cpp:142 +msgid "Play" +msgstr "Jouer" + +#: ../../po/../src/ui/dialog/session-player.cpp:177 +#: ../../po/../src/verbs.cpp:1573 +msgid "Open session file" +msgstr "Ouvrir un fichier de session" + +#. ##Set up the Potrace panel +#. #### brightness #### +#. #### Multiple scanning#### +#. ----Hbox1 +#: ../../po/../src/ui/dialog/tracedialog.cpp:345 +#: ../../po/../src/ui/dialog/tracedialog.cpp:428 +msgid "Brightness" +msgstr "Luminosité" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:348 +msgid "Trace by a given brightness level" +msgstr "Vectoriser suivant un niveau de luminosité" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:355 +msgid "Brightness cutoff for black/white" +msgstr "Limite de luminosité pour la détermination blanc/noir" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:362 +msgid "Image Brightness" +msgstr "Luminosité de l'image" + +#. #### canny edge detection #### +#. TRANSLATORS: "Canny" is the name of the inventor of this edge detection method +#: ../../po/../src/ui/dialog/tracedialog.cpp:369 +msgid "Optimal Edge Detection (Canny)" +msgstr "Détection optimale des arêtes (Canny)" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:372 +msgid "Trace with edge detection by J. Canny's algorithm" +msgstr "Utiliser l'algorithme détection d'arêtes de J. Canny pour vectoriser" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:388 +msgid "Brightness cutoff for adjacent pixels (determines edge thickness)" +msgstr "" +"Limite de luminosité pour déterminer les pixels adjacent (détermine la " +"finesse des arrêtes)" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:395 +msgid "Edge Detection" +msgstr "Détection de contour" + +#. #### quantization #### +#. TRANSLATORS: Color Quantization: the process of reducing the number of colors +#. in an image by selecting an optimized set of representative colors and then +#. re-applying this reduced set to the original image. +#: ../../po/../src/ui/dialog/tracedialog.cpp:404 +msgid "Color Quantization" +msgstr "Quantification des couleurs" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:407 +msgid "Trace along the boundaries of reduced colors" +msgstr "Vectoriser les contours déterminés par les couleurs réduites" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:414 +msgid "The number of reduced colors" +msgstr "Nombre de couleurs réduites" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:416 +msgid "Colors:" +msgstr "Couleurs :" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:421 +msgid "Quantization / Reduction" +msgstr "Quantification / Réduction" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:431 +msgid "Trace the given number of brightness levels" +msgstr "Vectoriser suivant les différents niveaux de luminosité" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:438 +msgid "Scans:" +msgstr "Passes :" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:440 +msgid "The desired number of scans" +msgstr "Nombre de passes désiré" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:448 +msgid "Trace the given number of reduced colors" +msgstr "Vectoriser suivant les différentes couleurs réduites" + +#. ---Hbox3 +#: ../../po/../src/ui/dialog/tracedialog.cpp:454 +msgid "Monochrome" +msgstr "Monochrome" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:457 +msgid "Same as Color, but convert result to grayscale" +msgstr "Comme pour couleur, mais convertit le résultat en niveau de gris" + +#. TRANSLATORS: "Stack" is a verb here +#: ../../po/../src/ui/dialog/tracedialog.cpp:460 +msgid "Stack" +msgstr "Empiler" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:463 +msgid "" +"Stack scans vertically (no gaps) or tile horizontally (usually with gaps)" +msgstr "" +"Empiler les passes verticalement (pas de lacunes) ou les paver " +"horizontalement (souvent avec des lacunes)" + +#. TRANSLATORS: "Smooth" is a verb here +#: ../../po/../src/ui/dialog/tracedialog.cpp:466 +msgid "Smooth" +msgstr "Adoucir" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:469 +msgid "Apply Gaussian blur to the bitmap before tracing" +msgstr "Appliquer un flou gaussien sur le bitmap avant de le vectoriser" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:473 +msgid "Multiple Scanning" +msgstr "Passes multiples" + +#. #### Preview #### +#: ../../po/../src/ui/dialog/tracedialog.cpp:479 +#: ../../po/../src/ui/dialog/tracedialog.cpp:489 +msgid "Preview" +msgstr "Aperçu" + +#. do not expand +#: ../../po/../src/ui/dialog/tracedialog.cpp:483 +msgid "Preview the result without actual tracing" +msgstr "Aperçu du résultat sans vraiment effectuer la vectorisation" + +#. #### swap black and white #### +#: ../../po/../src/ui/dialog/tracedialog.cpp:495 +msgid "Invert" +msgstr "Inverser" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:499 +msgid "Invert black and white regions for single traces" +msgstr "Inverser le blanc et le noir pour les vectorisations uniques" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:503 +msgid "Thanks to Peter Selinger, http://potrace.sourceforge.net" +msgstr "Merci à Peter Selinger, http://potrace.sourceforge.net" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:506 +msgid "Credits" +msgstr "Crédits" + +#. done +#. TRANSLATORS: Potrace is an application for transforming bitmaps into +#. vector graphics (http://potrace.sourceforge.net/) +#: ../../po/../src/ui/dialog/tracedialog.cpp:514 +msgid "Potrace" +msgstr "Potrace" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:527 +msgid "Abort a trace in progress" +msgstr "Annuler une vectorisation en cours" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:531 +msgid "Execute the trace" +msgstr "Lancer la vectorisation" + +#: ../../po/../src/ui/dialog/transformation.cpp:80 +#: ../../po/../src/ui/dialog/transformation.cpp:90 +#, fuzzy +msgid "_Horizontal" +msgstr "Horizontal" + +#: ../../po/../src/ui/dialog/transformation.cpp:80 +msgid "Horizontal displacement (relative) or position (absolute)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:82 +#: ../../po/../src/ui/dialog/transformation.cpp:92 +#, fuzzy +msgid "_Vertical" +msgstr "Vertical" + +#: ../../po/../src/ui/dialog/transformation.cpp:82 +msgid "Vertical displacement (relative) or position (absolute)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:84 +#, fuzzy +msgid "_Width" +msgstr "Largeur (_w):" + +#: ../../po/../src/ui/dialog/transformation.cpp:84 +msgid "Horizontal size increment (absolute or percentage)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:86 +#, fuzzy +msgid "_Height" +msgstr "Hauteur" + +#: ../../po/../src/ui/dialog/transformation.cpp:86 +msgid "Vertical size increment (absolute or percentage)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:88 +#, fuzzy +msgid "A_ngle" +msgstr "Angle :" + +#: ../../po/../src/ui/dialog/transformation.cpp:88 +#, fuzzy +msgid "Rotation angle (positive = counterclockwise)" +msgstr "Tourner la sélection de 90° dans le sens anti-horaire" + +#: ../../po/../src/ui/dialog/transformation.cpp:90 +msgid "" +"Horizontal skew angle (positive = counterclockwise), or absolute " +"displacement, or percentage displacement" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:92 +msgid "" +"Vertical skew angle (positive = counterclockwise), or absolute displacement, " +"or percentage displacement" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:95 +#, fuzzy +msgid "Transformation matrix element A" +msgstr "Matrice de transformation" + +#: ../../po/../src/ui/dialog/transformation.cpp:96 +#, fuzzy +msgid "Transformation matrix element B" +msgstr "Matrice de transformation" + +#: ../../po/../src/ui/dialog/transformation.cpp:97 +#, fuzzy +msgid "Transformation matrix element C" +msgstr "Matrice de transformation" + +#: ../../po/../src/ui/dialog/transformation.cpp:98 +#, fuzzy +msgid "Transformation matrix element D" +msgstr "Matrice de transformation" + +#: ../../po/../src/ui/dialog/transformation.cpp:99 +#, fuzzy +msgid "Transformation matrix element E" +msgstr "Matrice de transformation" + +#: ../../po/../src/ui/dialog/transformation.cpp:100 +#, fuzzy +msgid "Transformation matrix element F" +msgstr "Matrice de transformation" + +#: ../../po/../src/ui/dialog/transformation.cpp:102 +#, fuzzy +msgid "Rela_tive move" +msgstr "Déplacement relatif" + +#: ../../po/../src/ui/dialog/transformation.cpp:102 +msgid "" +"Add the specified relative displacement to the current position; otherwise, " +"edit the current absolute position directly" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:103 +msgid "Scale proportionally" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:103 +msgid "Preserve the width/height ratio of the scaled objects" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:104 +msgid "Apply to each _object separately" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:104 +msgid "" +"Apply the scale/rotate/skew to each selected object separately; otherwise, " +"transform the selection as a whole" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:105 +#, fuzzy +msgid "Edit c_urrent matrix" +msgstr "Monter le calque courant" + +#: ../../po/../src/ui/dialog/transformation.cpp:105 +msgid "" +"Edit the current transform= matrix; otherwise, post-multiply transform= by " +"this matrix" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:115 +#, fuzzy +msgid "_Move" +msgstr "Déplacer" + +#: ../../po/../src/ui/dialog/transformation.cpp:118 +#, fuzzy +msgid "_Scale" +msgstr "Échelle" + +#: ../../po/../src/ui/dialog/transformation.cpp:121 +#, fuzzy +msgid "_Rotate" +msgstr "Rotation" + +#: ../../po/../src/ui/dialog/transformation.cpp:124 +#, fuzzy +msgid "Ske_w" +msgstr "Incliner" + +#: ../../po/../src/ui/dialog/transformation.cpp:127 +msgid "Matri_x" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:141 +msgid "Reset the values on the current tab to defaults" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:148 +#, fuzzy +msgid "Apply transformation to selection" +msgstr "Appliquer la transformation à l'objet" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:43 +msgid "_Use SSL" +msgstr "_Utiliser SSL" + +#. Construct dialog interface +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:68 +msgid "_Server:" +msgstr "_Serveur" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:69 +msgid "_Username:" +msgstr "Nom d'_utilisateur :" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:70 +msgid "_Password:" +msgstr "Mot de _passe :" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:71 +msgid "P_ort:" +msgstr "P_ort :" + +#. Buttons +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:99 +msgid "Connect" +msgstr "Se connecter" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:126 +msgid "Establishing connection to Jabber server %1 as user %2" +msgstr "" +"Etablissement de la connection au serveur Jabber %1 en tant " +"qu'uyilisateur %2" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:131 +msgid "Failed to establish connection to Jabber server %1" +msgstr "Echec de la tentative de connection au serveur Jabber %1" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:136 +msgid "Authentication failed on Jabber server %1 as %2" +msgstr "" +"Ecchec de l'authentification sur le serveur Jabber %1 en tant que %" +"2" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:141 +msgid "SSL initialization failed when connecting to Jabber server %1" +msgstr "" +"Echec de l'initialisation SSL lors de la connection au serveur Jabber %1" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:147 +msgid "Connected to Jabber server %1 as %2" +msgstr "Connecté(e) au serveur Jabber %1 en tant que %2" + +#. Construct labels +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:75 +msgid "Chatroom _name:" +msgstr "_Nom de la pièce de discussion" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:76 +msgid "Chatroom _server:" +msgstr "_Serveur de la pièce de discussion" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:77 +msgid "Chatroom _password:" +msgstr "Mot de _passe de la pièce de discussion :" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:78 +msgid "Chatroom _handle:" +msgstr "Indicatif de " + +#. Button setup and callback registration +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:97 +msgid "Connect to chatroom" +msgstr "Se connecter à la pièce de discussion" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:132 +msgid "Synchronizing with chatroom %1@%2 using the handle %3" +msgstr "" +"Synchronisation avec la pièce de discussion %1@%2 en utilisant " +"l'indicatif %3" + +#. Construct dialog interface +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:78 +msgid "_User's Jabber ID:" +msgstr "ID Jabber de l'utilisateur :" + +#. Buttons +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:82 +msgid "_Invite user" +msgstr "_Inviter un utilisateur" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:83 +msgid "_Cancel" +msgstr "Annuler (_c)" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:94 +msgid "Buddy List" +msgstr "List d'amis" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:170 +msgid "Sending whiteboard invitation to %1" +msgstr "Envoi d'une invitation à une session de tableau blanc à %1" + +#. FIXME: strings are replaced by placeholders, NOT to be translated until the code is enabled +#. See http://sourceforge.net/mailarchive/message.php?msg_id=11746016 for details +#. File menu +#. Edit menu +#. View menu +#. Layer menu +#. Object menu +#. Path menu +#. add(Gtk::StockItem(CLEANUP, _("PLACEHOLDER, do not translate"))); (using Gtk::Stock::CLEAR) +#. Text menu +#. About menu +#. Tools toolbox +#. Select Tool controls +#. Node Tool controls +#. Calligraphy Tool controls +#. Session playback controls +#: ../../po/../src/ui/stock-items.cpp:34 ../../po/../src/ui/stock-items.cpp:35 +#: ../../po/../src/ui/stock-items.cpp:36 ../../po/../src/ui/stock-items.cpp:37 +#: ../../po/../src/ui/stock-items.cpp:38 ../../po/../src/ui/stock-items.cpp:39 +#: ../../po/../src/ui/stock-items.cpp:40 ../../po/../src/ui/stock-items.cpp:41 +#: ../../po/../src/ui/stock-items.cpp:42 ../../po/../src/ui/stock-items.cpp:43 +#: ../../po/../src/ui/stock-items.cpp:46 ../../po/../src/ui/stock-items.cpp:47 +#: ../../po/../src/ui/stock-items.cpp:48 ../../po/../src/ui/stock-items.cpp:49 +#: ../../po/../src/ui/stock-items.cpp:50 ../../po/../src/ui/stock-items.cpp:51 +#: ../../po/../src/ui/stock-items.cpp:52 ../../po/../src/ui/stock-items.cpp:53 +#: ../../po/../src/ui/stock-items.cpp:54 ../../po/../src/ui/stock-items.cpp:55 +#: ../../po/../src/ui/stock-items.cpp:56 ../../po/../src/ui/stock-items.cpp:57 +#: ../../po/../src/ui/stock-items.cpp:58 ../../po/../src/ui/stock-items.cpp:59 +#: ../../po/../src/ui/stock-items.cpp:62 ../../po/../src/ui/stock-items.cpp:63 +#: ../../po/../src/ui/stock-items.cpp:64 ../../po/../src/ui/stock-items.cpp:65 +#: ../../po/../src/ui/stock-items.cpp:66 ../../po/../src/ui/stock-items.cpp:67 +#: ../../po/../src/ui/stock-items.cpp:68 ../../po/../src/ui/stock-items.cpp:69 +#: ../../po/../src/ui/stock-items.cpp:70 ../../po/../src/ui/stock-items.cpp:71 +#: ../../po/../src/ui/stock-items.cpp:72 ../../po/../src/ui/stock-items.cpp:73 +#: ../../po/../src/ui/stock-items.cpp:74 ../../po/../src/ui/stock-items.cpp:75 +#: ../../po/../src/ui/stock-items.cpp:76 ../../po/../src/ui/stock-items.cpp:77 +#: ../../po/../src/ui/stock-items.cpp:78 ../../po/../src/ui/stock-items.cpp:79 +#: ../../po/../src/ui/stock-items.cpp:80 ../../po/../src/ui/stock-items.cpp:81 +#: ../../po/../src/ui/stock-items.cpp:82 ../../po/../src/ui/stock-items.cpp:83 +#: ../../po/../src/ui/stock-items.cpp:84 ../../po/../src/ui/stock-items.cpp:85 +#: ../../po/../src/ui/stock-items.cpp:86 ../../po/../src/ui/stock-items.cpp:87 +#: ../../po/../src/ui/stock-items.cpp:88 ../../po/../src/ui/stock-items.cpp:89 +#: ../../po/../src/ui/stock-items.cpp:92 ../../po/../src/ui/stock-items.cpp:93 +#: ../../po/../src/ui/stock-items.cpp:94 ../../po/../src/ui/stock-items.cpp:95 +#: ../../po/../src/ui/stock-items.cpp:96 ../../po/../src/ui/stock-items.cpp:97 +#: ../../po/../src/ui/stock-items.cpp:98 ../../po/../src/ui/stock-items.cpp:99 +#: ../../po/../src/ui/stock-items.cpp:100 +#: ../../po/../src/ui/stock-items.cpp:101 +#: ../../po/../src/ui/stock-items.cpp:102 +#: ../../po/../src/ui/stock-items.cpp:103 +#: ../../po/../src/ui/stock-items.cpp:104 +#: ../../po/../src/ui/stock-items.cpp:105 +#: ../../po/../src/ui/stock-items.cpp:108 +#: ../../po/../src/ui/stock-items.cpp:109 +#: ../../po/../src/ui/stock-items.cpp:110 +#: ../../po/../src/ui/stock-items.cpp:111 +#: ../../po/../src/ui/stock-items.cpp:112 +#: ../../po/../src/ui/stock-items.cpp:113 +#: ../../po/../src/ui/stock-items.cpp:114 +#: ../../po/../src/ui/stock-items.cpp:115 +#: ../../po/../src/ui/stock-items.cpp:116 +#: ../../po/../src/ui/stock-items.cpp:117 +#: ../../po/../src/ui/stock-items.cpp:118 +#: ../../po/../src/ui/stock-items.cpp:119 +#: ../../po/../src/ui/stock-items.cpp:120 +#: ../../po/../src/ui/stock-items.cpp:121 +#: ../../po/../src/ui/stock-items.cpp:122 +#: ../../po/../src/ui/stock-items.cpp:123 +#: ../../po/../src/ui/stock-items.cpp:124 +#: ../../po/../src/ui/stock-items.cpp:125 +#: ../../po/../src/ui/stock-items.cpp:126 +#: ../../po/../src/ui/stock-items.cpp:127 +#: ../../po/../src/ui/stock-items.cpp:130 +#: ../../po/../src/ui/stock-items.cpp:131 +#: ../../po/../src/ui/stock-items.cpp:132 +#: ../../po/../src/ui/stock-items.cpp:133 +#: ../../po/../src/ui/stock-items.cpp:134 +#: ../../po/../src/ui/stock-items.cpp:135 +#: ../../po/../src/ui/stock-items.cpp:136 +#: ../../po/../src/ui/stock-items.cpp:137 +#: ../../po/../src/ui/stock-items.cpp:138 +#: ../../po/../src/ui/stock-items.cpp:139 +#: ../../po/../src/ui/stock-items.cpp:140 +#: ../../po/../src/ui/stock-items.cpp:141 +#: ../../po/../src/ui/stock-items.cpp:142 +#: ../../po/../src/ui/stock-items.cpp:143 +#: ../../po/../src/ui/stock-items.cpp:144 +#: ../../po/../src/ui/stock-items.cpp:145 +#: ../../po/../src/ui/stock-items.cpp:146 +#: ../../po/../src/ui/stock-items.cpp:150 +#: ../../po/../src/ui/stock-items.cpp:151 +#: ../../po/../src/ui/stock-items.cpp:152 +#: ../../po/../src/ui/stock-items.cpp:153 +#: ../../po/../src/ui/stock-items.cpp:156 +#: ../../po/../src/ui/stock-items.cpp:157 +#: ../../po/../src/ui/stock-items.cpp:158 +#: ../../po/../src/ui/stock-items.cpp:161 +#: ../../po/../src/ui/stock-items.cpp:162 +#: ../../po/../src/ui/stock-items.cpp:163 +#: ../../po/../src/ui/stock-items.cpp:164 +#: ../../po/../src/ui/stock-items.cpp:165 +#: ../../po/../src/ui/stock-items.cpp:166 +#: ../../po/../src/ui/stock-items.cpp:167 +#: ../../po/../src/ui/stock-items.cpp:168 +#: ../../po/../src/ui/stock-items.cpp:169 +#: ../../po/../src/ui/stock-items.cpp:170 +#: ../../po/../src/ui/stock-items.cpp:171 +#: ../../po/../src/ui/stock-items.cpp:172 +#: ../../po/../src/ui/stock-items.cpp:175 +#: ../../po/../src/ui/stock-items.cpp:176 +#: ../../po/../src/ui/stock-items.cpp:177 +#: ../../po/../src/ui/stock-items.cpp:178 +#: ../../po/../src/ui/stock-items.cpp:181 +#: ../../po/../src/ui/stock-items.cpp:182 +#: ../../po/../src/ui/stock-items.cpp:183 +#: ../../po/../src/ui/stock-items.cpp:184 +#: ../../po/../src/ui/stock-items.cpp:185 +#: ../../po/../src/ui/stock-items.cpp:186 +#: ../../po/../src/ui/stock-items.cpp:187 +#: ../../po/../src/ui/stock-items.cpp:188 +#: ../../po/../src/ui/stock-items.cpp:189 +#: ../../po/../src/ui/stock-items.cpp:190 +#: ../../po/../src/ui/stock-items.cpp:191 +#: ../../po/../src/ui/stock-items.cpp:194 +#: ../../po/../src/ui/stock-items.cpp:195 +#: ../../po/../src/ui/stock-items.cpp:198 +#: ../../po/../src/ui/stock-items.cpp:199 +#: ../../po/../src/ui/stock-items.cpp:200 +#: ../../po/../src/ui/stock-items.cpp:201 +#: ../../po/../src/ui/stock-items.cpp:202 +msgid "PLACEHOLDER, do not translate" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:88 +msgid "small" +msgstr "petit" + +#: ../../po/../src/ui/widget/panel.cpp:89 +msgid "medium" +msgstr "moyen" + +#: ../../po/../src/ui/widget/panel.cpp:90 +msgid "large" +msgstr "grand" + +#: ../../po/../src/ui/widget/panel.cpp:91 +msgid "huge" +msgstr "très grand" + +#: ../../po/../src/ui/widget/panel.cpp:106 +msgid "List" +msgstr "Liste" + +#: ../../po/../src/ui/widget/selected-style.cpp:67 +msgid "F:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:68 +msgid "S:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:69 +msgid "O:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:95 +msgid "N/A" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:98 +#: ../../po/../src/ui/widget/selected-style.cpp:712 +#, fuzzy +msgid "Nothing selected" +msgstr "Aucun dégradé n'est sélectionné" + +#: ../../po/../src/ui/widget/selected-style.cpp:103 +msgid "No fill" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:103 +#, fuzzy +msgid "No stroke" +msgstr " (contour)" + +#: ../../po/../src/ui/widget/selected-style.cpp:105 +#: ../../po/../src/widgets/paint-selector.cpp:190 +msgid "Pattern" +msgstr "Motif" + +#: ../../po/../src/ui/widget/selected-style.cpp:108 +#: ../../po/../src/widgets/paint-selector.cpp:885 +msgid "Pattern fill" +msgstr "Motif de remplissage" + +#: ../../po/../src/ui/widget/selected-style.cpp:108 +#, fuzzy +msgid "Pattern stroke" +msgstr "Décalage du motif" + +#: ../../po/../src/ui/widget/selected-style.cpp:110 +#, fuzzy +msgid "L Gradient" +msgstr "Dégradé" + +#: ../../po/../src/ui/widget/selected-style.cpp:113 +#, fuzzy +msgid "Linear gradient fill" +msgstr "Dégradé linéaire" + +#: ../../po/../src/ui/widget/selected-style.cpp:113 +#, fuzzy +msgid "Linear gradient stroke" +msgstr "Dégradé linéaire" + +#: ../../po/../src/ui/widget/selected-style.cpp:115 +#, fuzzy +msgid "R Gradient" +msgstr "Dégradé" + +#: ../../po/../src/ui/widget/selected-style.cpp:118 +#, fuzzy +msgid "Radial gradient fill" +msgstr "Dégradé radial" + +#: ../../po/../src/ui/widget/selected-style.cpp:118 +#, fuzzy +msgid "Radial gradient stroke" +msgstr "Dégradé radial" + +#: ../../po/../src/ui/widget/selected-style.cpp:120 +#, fuzzy +msgid "Different" +msgstr "_Différence" + +#: ../../po/../src/ui/widget/selected-style.cpp:123 +#, fuzzy +msgid "Different fills" +msgstr "_Différence" + +#: ../../po/../src/ui/widget/selected-style.cpp:123 +#, fuzzy +msgid "Different strokes" +msgstr "_Différence" + +#: ../../po/../src/ui/widget/selected-style.cpp:125 +#, fuzzy +msgid "Unset" +msgstr "éroder" + +#. TRANSLATORS COMMENT: unset is a verb here +#: ../../po/../src/ui/widget/selected-style.cpp:128 +#: ../../po/../src/ui/widget/selected-style.cpp:182 +msgid "Unset fill" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:128 +#: ../../po/../src/ui/widget/selected-style.cpp:182 +#, fuzzy +msgid "Unset stroke" +msgstr " (contour)" + +#: ../../po/../src/ui/widget/selected-style.cpp:131 +#, fuzzy +msgid "Flat color fill" +msgstr "Couleur uniforme" + +#: ../../po/../src/ui/widget/selected-style.cpp:131 +#, fuzzy +msgid "Flat color stroke" +msgstr "Couleur uniforme" + +# Alpha (opacity) +#. TRANSLATOR COMMENT: A means "Averaged" +#: ../../po/../src/ui/widget/selected-style.cpp:134 +#, fuzzy +msgid "A" +msgstr "_A" + +#: ../../po/../src/ui/widget/selected-style.cpp:137 +#, fuzzy +msgid "Fill is averaged over selected objects" +msgstr "Ou exclusif (XOR) des objets sélectionnes" + +#: ../../po/../src/ui/widget/selected-style.cpp:137 +#, fuzzy +msgid "Stroke is averaged over selected objects" +msgstr "Faire que les connecteurs évitent les objets sélectionnés" + +# Magenta (in CYMK) +#. TRANSLATOR COMMENT: M means "Multiple" +#: ../../po/../src/ui/widget/selected-style.cpp:140 +#, fuzzy +msgid "M" +msgstr "_M" + +#: ../../po/../src/ui/widget/selected-style.cpp:143 +#, fuzzy +msgid "Multiple selected objects have the same fill" +msgstr "Retourner verticalement les objets sélectionnés" + +#: ../../po/../src/ui/widget/selected-style.cpp:143 +#, fuzzy +msgid "Multiple selected objects have the same stroke" +msgstr "Retourner verticalement les objets sélectionnés" + +#: ../../po/../src/ui/widget/selected-style.cpp:145 +#, fuzzy +msgid "Edit fill..." +msgstr "Éditer..." + +#: ../../po/../src/ui/widget/selected-style.cpp:145 +#, fuzzy +msgid "Edit stroke..." +msgstr "Éditer..." + +#: ../../po/../src/ui/widget/selected-style.cpp:149 +#, fuzzy +msgid "Last set color" +msgstr "Couleur uniforme" + +#: ../../po/../src/ui/widget/selected-style.cpp:153 +#, fuzzy +msgid "Last selected color" +msgstr "Dernier sélectionné" + +#: ../../po/../src/ui/widget/selected-style.cpp:157 +#, fuzzy +msgid "White" +msgstr "Tableau blanc (_r)" + +#: ../../po/../src/ui/widget/selected-style.cpp:161 +#: ../../po/../src/widgets/sp-color-scales.cpp:461 +#: ../../po/../src/widgets/sp-color-scales.cpp:462 +msgid "Black" +msgstr "Noir" + +#: ../../po/../src/ui/widget/selected-style.cpp:165 +#, fuzzy +msgid "Copy color" +msgstr "Couleur du stop" + +#: ../../po/../src/ui/widget/selected-style.cpp:169 +#, fuzzy +msgid "Paste color" +msgstr "Couleur uniforme" + +#: ../../po/../src/ui/widget/selected-style.cpp:173 +#, fuzzy +msgid "Swap fill and stroke" +msgstr "Remplissage et contour (_f)" + +#: ../../po/../src/ui/widget/selected-style.cpp:177 +msgid "Make fill opaque" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:177 +msgid "Make stroke opaque" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:186 +#, fuzzy +msgid "Remove fill" +msgstr "Suppri_mer" + +#: ../../po/../src/ui/widget/selected-style.cpp:186 +#, fuzzy +msgid "Remove stroke" +msgstr "_Retirer le lien" + +#: ../../po/../src/ui/widget/selected-style.cpp:718 +#, fuzzy +msgid "Master opacity" +msgstr "_Opacité globale" + +#: ../../po/../src/ui/widget/selected-style.cpp:744 +msgid "0 (transparent)" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:768 +msgid "1.0 (opaque)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1046 +msgid "Moved to next layer." +msgstr "Déplacé au calque suivant." + +#: ../../po/../src/verbs.cpp:1048 +msgid "Cannot move past last layer." +msgstr "Impossible de déplacer derrière le dernier calque." + +#: ../../po/../src/verbs.cpp:1057 +msgid "Moved to previous layer." +msgstr "Déplacé au calque précédent." + +#: ../../po/../src/verbs.cpp:1059 +msgid "Cannot move past first layer." +msgstr "Impossible de déplacer devant le premier calque." + +#: ../../po/../src/verbs.cpp:1076 ../../po/../src/verbs.cpp:1150 +msgid "No current layer." +msgstr "Aucun calque courant." + +#: ../../po/../src/verbs.cpp:1105 +#, c-format +msgid "Raised layer %s." +msgstr "Calque %s monté." + +#: ../../po/../src/verbs.cpp:1109 +#, c-format +msgid "Lowered layer %s." +msgstr "Calque %s descendu." + +#: ../../po/../src/verbs.cpp:1118 +msgid "Cannot move layer any further." +msgstr "Impossible de déplacer le calque plus loin." + +#. TRANSLATORS: this means "The layer has been deleted." +#: ../../po/../src/verbs.cpp:1148 +msgid "Deleted layer." +msgstr "Calque supprimé." + +#: ../../po/../src/verbs.cpp:1544 +msgid "" +"You need to connect to a Jabber server before sharing a document with " +"another user." +msgstr "" +"Vous devez être connecté(e) à un serveur jabber avant de partager un " +"document avec un autre utilisateur." + +#: ../../po/../src/verbs.cpp:1559 +msgid "" +"You need to connect to a Jabber server before sharing a document with a " +"chatroom." +msgstr "" +"Vous devez être connecté(e) à un serveur jabber avant de partager un " +"document avec une pièce de discussion." + +#: ../../po/../src/verbs.cpp:1569 +msgid "XML node tracker has not been initialized; nothing to dump" +msgstr "" +"Le traceur de nœud XML n'a pas été initialisé; il n'y a rien à décharger" + +# Name of the displayed file (in Help > tutorials > ...). To be translated if the tutorial has been translated. +#. TRANSLATORS: If you have translated the keys.svg file to your language, then +#. translate this string as "keys.LANG.svg" (where LANG is your language code); +#. otherwise leave as "keys.svg". +#: ../../po/../src/verbs.cpp:1631 +msgid "keys.svg" +msgstr "keys.fr.svg" + +# Name of the displayed file (in Help > tutorials > ...). To be translated if the tutorial has been translated. +#. TRANSLATORS: If you have translated the tutorial-basic.svg file to your language, +#. then translate this string as "tutorial-basic.LANG.svg" (where LANG is your language +#. code); otherwise leave as "tutorial-basic.svg". +#: ../../po/../src/verbs.cpp:1667 +msgid "tutorial-basic.svg" +msgstr "tutorial-basic.fr.svg" + +# Name of the displayed file (in Help > tutorials > ...). To be translated if the tutorial has been translated. +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1671 +msgid "tutorial-shapes.svg" +msgstr "tutorial-shapes.fr.svg" + +# Name of the displayed file (in Help > tutorials > ...). To be translated if the tutorial has been translated. +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1675 +msgid "tutorial-advanced.svg" +msgstr "tutorial-advanced.fr.svg" + +# Name of the displayed file (in Help > tutorials > ...). To be translated if the tutorial has been translated. +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1679 +msgid "tutorial-tracing.svg" +msgstr "tutorial-tracing.fr.svg" + +# Name of the displayed file (in Help > tutorials > ...). To be translated if the tutorial has been translated. +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1683 +msgid "tutorial-calligraphy.svg" +msgstr "tutorial-calligraphy.fr.svg" + +# Name of the displayed file (in Help > tutorials > ...). To be translated if the tutorial has been translated. +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1687 +msgid "tutorial-elements.svg" +msgstr "tutorial-elements.fr.svg" + +# Name of the displayed file (in Help > tutorials > ...). To be translated if the tutorial has been translated. +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1691 +msgid "tutorial-tips.svg" +msgstr "tutorial-tips.fr.svg" + +#: ../../po/../src/verbs.cpp:1842 +msgid "Does nothing" +msgstr "Ne fait rien" + +#. File +#: ../../po/../src/verbs.cpp:1845 +msgid "Default" +msgstr "Défaut" + +#: ../../po/../src/verbs.cpp:1845 +msgid "Create new document from default template" +msgstr "Créer un nouveau document depuis le modèle par défaut" + +#: ../../po/../src/verbs.cpp:1847 +msgid "_Open..." +msgstr "_Ouvrir..." + +#: ../../po/../src/verbs.cpp:1848 +msgid "Open existing document" +msgstr "Ouvrir un document existant" + +#: ../../po/../src/verbs.cpp:1849 +msgid "Re_vert" +msgstr "Recharger (_v)" + +#: ../../po/../src/verbs.cpp:1850 +msgid "Revert to the last saved version of document (changes will be lost)" +msgstr "" +"Recharger le dernier enregistrement du document (les changements seront " +"perdus)" + +#: ../../po/../src/verbs.cpp:1851 +msgid "_Save" +msgstr "Enregi_strer" + +#: ../../po/../src/verbs.cpp:1851 +msgid "Save document" +msgstr "Enregistrer le document" + +#: ../../po/../src/verbs.cpp:1853 +msgid "Save _As..." +msgstr "Enregistrer sous... (_a)" + +#: ../../po/../src/verbs.cpp:1854 +msgid "Save document under new name" +msgstr "Enregistrer le document sous un nouveau nom" + +#: ../../po/../src/verbs.cpp:1855 +msgid "_Print..." +msgstr "Im_primer..." + +#: ../../po/../src/verbs.cpp:1855 +msgid "Print document" +msgstr "Imprimer le document" + +#. TRANSLATORS: "Vacuum Defs" means "Clean up defs" (so as to remove unused definitions) +#: ../../po/../src/verbs.cpp:1858 +msgid "Vac_uum Defs" +msgstr "Nettoyer les Defs (_u)" + +#: ../../po/../src/verbs.cpp:1858 +msgid "Remove unused predefined items from the <defs> of the document" +msgstr "Retirer les éléments inutilisés des <defs> du document" + +#: ../../po/../src/verbs.cpp:1860 +msgid "Print _Direct" +msgstr "Imprimer _directement" + +#: ../../po/../src/verbs.cpp:1861 +msgid "Print directly without prompting to a file or pipe" +msgstr "Imprimer directement sans passer par un fichier ou un tube" + +#: ../../po/../src/verbs.cpp:1862 +msgid "Print Previe_w" +msgstr "Aperçu avant impression" + +#: ../../po/../src/verbs.cpp:1863 +msgid "Preview document printout" +msgstr "Prévisualiser avant impression" + +#: ../../po/../src/verbs.cpp:1864 +msgid "_Import..." +msgstr "_Importer..." + +#: ../../po/../src/verbs.cpp:1865 +msgid "Import bitmap or SVG image into document" +msgstr "Importer des images SVG ou bitmap dans le document" + +#: ../../po/../src/verbs.cpp:1866 +msgid "_Export Bitmap..." +msgstr "_Exporter en bitmap..." + +#: ../../po/../src/verbs.cpp:1867 +msgid "Export document or selection as a bitmap image" +msgstr "Exporter le document ou la sélection en image bitmap" + +#: ../../po/../src/verbs.cpp:1868 +msgid "N_ext Window" +msgstr "Fenêtre suivant_e" + +#: ../../po/../src/verbs.cpp:1869 +msgid "Switch to the next document window" +msgstr "Passer à la fenêtre (document) suivante" + +#: ../../po/../src/verbs.cpp:1870 +msgid "P_revious Window" +msgstr "Fenêtre p_récédente" + +#: ../../po/../src/verbs.cpp:1871 +msgid "Switch to the previous document window" +msgstr "Passer à la fenêtre (document) précédente" + +#: ../../po/../src/verbs.cpp:1872 +msgid "_Close" +msgstr "Fermer (_c)" + +#: ../../po/../src/verbs.cpp:1873 +msgid "Close window" +msgstr "Fermer la fenêtre" + +#: ../../po/../src/verbs.cpp:1874 +msgid "_Quit" +msgstr "_Quitter" + +#: ../../po/../src/verbs.cpp:1874 +msgid "Quit Inkscape" +msgstr "Quitter Inkscape" + +#. Edit +#: ../../po/../src/verbs.cpp:1877 +msgid "_Undo" +msgstr "Ann_uler" + +#: ../../po/../src/verbs.cpp:1877 +msgid "Undo last action" +msgstr "Annuler la dernière action" + +#: ../../po/../src/verbs.cpp:1879 +msgid "_Redo" +msgstr "_Refaire" + +#: ../../po/../src/verbs.cpp:1880 +msgid "Do again last undone action" +msgstr "Refaire la dernière action annulée" + +#: ../../po/../src/verbs.cpp:1881 +msgid "Cu_t" +msgstr "Couper (_t)" + +#: ../../po/../src/verbs.cpp:1882 +msgid "Cut selection to clipboard" +msgstr "Couper la sélection vers le presse-papiers" + +#: ../../po/../src/verbs.cpp:1883 +msgid "_Copy" +msgstr "_Copier" + +#: ../../po/../src/verbs.cpp:1884 +msgid "Copy selection to clipboard" +msgstr "Copier la sélection vers le presse-papiers" + +#: ../../po/../src/verbs.cpp:1885 +msgid "_Paste" +msgstr "Coller (_p)" + +#: ../../po/../src/verbs.cpp:1886 +msgid "Paste objects from clipboard to mouse point" +msgstr "Coller les objets du presse-papiers sous le pointeur de souris" + +#: ../../po/../src/verbs.cpp:1887 +msgid "Paste _Style" +msgstr "Coller le _style" + +#: ../../po/../src/verbs.cpp:1888 +msgid "Apply style of the copied object to selection" +msgstr "Appliquer le style de l'objet copié a la sélection" + +#: ../../po/../src/verbs.cpp:1889 +msgid "Paste _In Place" +msgstr "Coller sur place (_i)" + +#: ../../po/../src/verbs.cpp:1890 +msgid "Paste objects from clipboard to the original location" +msgstr "Coller les objets du presse-papiers à leur emplacement d'origine" + +#: ../../po/../src/verbs.cpp:1891 +msgid "_Delete" +msgstr "Supprimer (_d)" + +#: ../../po/../src/verbs.cpp:1892 +msgid "Delete selection" +msgstr "Supprimer la sélection" + +#: ../../po/../src/verbs.cpp:1893 +msgid "Duplic_ate" +msgstr "D_upliquer" + +#: ../../po/../src/verbs.cpp:1894 +msgid "Duplicate selected objects" +msgstr "Dupliquer les objets sélectionnés" + +#: ../../po/../src/verbs.cpp:1895 +msgid "Clo_ne" +msgstr "Clo_ner" + +# fred: dynamic offset object +#: ../../po/../src/verbs.cpp:1896 +msgid "Create a clone of selected object (a copy linked to the original)" +msgstr "Créer un clone (une copie liée à l'original) de l'objet sélectionné" + +#: ../../po/../src/verbs.cpp:1897 +msgid "Unlin_k Clone" +msgstr "Délier le clone (_k)" + +#: ../../po/../src/verbs.cpp:1898 +msgid "Cut the clone's link to its original" +msgstr "Couper le lien entre le clone et son original" + +#: ../../po/../src/verbs.cpp:1899 +msgid "Select _Original" +msgstr "Sélectionner l'_original" + +#: ../../po/../src/verbs.cpp:1900 +msgid "Select the object to which the clone is linked" +msgstr "Sélectionner l'objet auquel le clone est lié" + +#. TRANSLATORS: Convert selection to a rectangle with tiled pattern fill +#: ../../po/../src/verbs.cpp:1902 +msgid "O_bjects to Pattern" +msgstr "_Objets en motif" + +#: ../../po/../src/verbs.cpp:1903 +msgid "Convert selection to a rectangle with tiled pattern fill" +msgstr "Convertir la sélection en rectangle rempli par ce motif" + +#. TRANSLATORS: Extract objects from a tiled pattern fill +#: ../../po/../src/verbs.cpp:1905 +msgid "Pattern to Ob_jects" +msgstr "Motif en ob_jets" + +#: ../../po/../src/verbs.cpp:1906 +msgid "Extract objects from a tiled pattern fill" +msgstr "Extraire des objet(s) d'un motif de remplissage" + +#: ../../po/../src/verbs.cpp:1907 +msgid "Clea_r All" +msgstr "Tout efface_r" + +#: ../../po/../src/verbs.cpp:1908 +msgid "Delete all objects from document" +msgstr "Supprimer tous les objets du document" + +#: ../../po/../src/verbs.cpp:1909 +msgid "Select Al_l" +msgstr "Tout sé_lectionner" + +#: ../../po/../src/verbs.cpp:1910 +msgid "Select all objects or all nodes" +msgstr "Sélectionner tous les objets ou tous les nœuds" + +#: ../../po/../src/verbs.cpp:1911 +msgid "Select All in All La_yers" +msgstr "Sélectionner tout dans tous les calques (_y)" + +#: ../../po/../src/verbs.cpp:1912 +msgid "Select all objects in all visible and unlocked layers" +msgstr "" +"Sélectionner tous les objets dans tous les calques visibles et non " +"verrouillés" + +#: ../../po/../src/verbs.cpp:1913 +msgid "In_vert Selection" +msgstr "In_verser la sélection" + +#: ../../po/../src/verbs.cpp:1914 +msgid "Invert selection (unselect what is selected and select everything else)" +msgstr "" +"Inverser la sélection (désélectionner tout ce qui était sélectionné, et " +"sélectionner tout le reste)" + +#: ../../po/../src/verbs.cpp:1915 +msgid "Invert in All Layers" +msgstr "Inverser dans tous les calques" + +#: ../../po/../src/verbs.cpp:1916 +msgid "Invert selection in all visible and unlocked layers" +msgstr "" +"Inverser la sélection dans tous les calques visibles et non verrouillés" + +#: ../../po/../src/verbs.cpp:1917 +msgid "D_eselect" +msgstr "Désél_ectionner" + +#: ../../po/../src/verbs.cpp:1918 +msgid "Deselect any selected objects or nodes" +msgstr "Désélectionner tous les objets ou nœuds" + +#. Selection +#: ../../po/../src/verbs.cpp:1921 +msgid "Raise to _Top" +msgstr "Mon_ter au premier plan" + +#: ../../po/../src/verbs.cpp:1922 +msgid "Raise selection to top" +msgstr "Monter la sélection au premier plan" + +#: ../../po/../src/verbs.cpp:1923 +msgid "Lower to _Bottom" +msgstr "Descendre à l'arrière plan (_b)" + +#: ../../po/../src/verbs.cpp:1924 +msgid "Lower selection to bottom" +msgstr "Descendre la sélection à l'arrière plan" + +#: ../../po/../src/verbs.cpp:1925 +msgid "_Raise" +msgstr "Monte_r" + +#: ../../po/../src/verbs.cpp:1926 +msgid "Raise selection one step" +msgstr "Monter la sélection d'un cran ((ordre-z))" + +#: ../../po/../src/verbs.cpp:1927 +msgid "_Lower" +msgstr "Descendre (_l)" + +#: ../../po/../src/verbs.cpp:1928 +msgid "Lower selection one step" +msgstr "Descendre la sélection d'un cran (ordre-z)" + +#: ../../po/../src/verbs.cpp:1929 +msgid "_Group" +msgstr "_Grouper" + +#: ../../po/../src/verbs.cpp:1930 +msgid "Group selected objects" +msgstr "Grouper les objets sélectionnés" + +#: ../../po/../src/verbs.cpp:1932 +msgid "Ungroup selected groups" +msgstr "Dégrouper les groupes sélectionnés" + +#: ../../po/../src/verbs.cpp:1934 +msgid "_Put on Path" +msgstr "Mettre suivant un chemin (_p)" + +#: ../../po/../src/verbs.cpp:1935 +msgid "Put text on path" +msgstr "Mettre du texte suivant un chemin" + +#: ../../po/../src/verbs.cpp:1936 +msgid "_Remove from Path" +msgstr "_Retirer du chemin" + +#: ../../po/../src/verbs.cpp:1937 +msgid "Remove text from path" +msgstr "Retirer le texte du chemin" + +#: ../../po/../src/verbs.cpp:1938 +msgid "Remove Manual _Kerns" +msgstr "Retirer les crénages manuels (_K)" + +#. TRANSLATORS: "glyph": An image used in the visual representation of characters; +#. roughly speaking, how a character looks. A font is a set of glyphs. +#: ../../po/../src/verbs.cpp:1941 +msgid "Remove all manual kerns and glyph rotations from a text object" +msgstr "Retirer les crénages manuels et rotations de glyphes d'un texte" + +#: ../../po/../src/verbs.cpp:1943 +msgid "_Union" +msgstr "_Union" + +#: ../../po/../src/verbs.cpp:1944 +msgid "Union of selected objects" +msgstr "Faire l'union des objets sélectionnés" + +#: ../../po/../src/verbs.cpp:1945 +msgid "_Intersection" +msgstr "_Intersection" + +#: ../../po/../src/verbs.cpp:1946 +msgid "Intersection of selected objects" +msgstr "Intersection des objets sélectionnes" + +#: ../../po/../src/verbs.cpp:1947 +msgid "_Difference" +msgstr "_Différence" + +#: ../../po/../src/verbs.cpp:1948 +msgid "Difference of selected objects (bottom minus top)" +msgstr "Différence entre les objets sélectionnes (dessous moins dessus)" + +#: ../../po/../src/verbs.cpp:1949 +msgid "E_xclusion" +msgstr "E_xclusion" + +#: ../../po/../src/verbs.cpp:1950 +msgid "Exclusive OR of selected objects" +msgstr "Ou exclusif (XOR) des objets sélectionnes" + +#: ../../po/../src/verbs.cpp:1951 +msgid "Di_vision" +msgstr "Di_vision" + +#: ../../po/../src/verbs.cpp:1952 +msgid "Cut the bottom object into pieces" +msgstr "Couper l'objet du dessous en morceaux" + +#. TRANSLATORS: "to cut a path" is not the same as "to break a path apart" - see the +#. Advanced tutorial for more info +#: ../../po/../src/verbs.cpp:1955 +msgid "Cut _Path" +msgstr "Décou_per les chemins" + +#: ../../po/../src/verbs.cpp:1956 +msgid "Cut the bottom object's stroke into pieces, removing fill" +msgstr "Découper le contour de l'objet du dessus, retire le remplissage" + +#. TRANSLATORS: "outset": expand a shape by offsetting the object's path, +#. i.e. by displacing it perpendicular to the path in each point. +#. See also the Advanced Tutorial for explanation. +#: ../../po/../src/verbs.cpp:1960 +msgid "Outs_et" +msgstr "Dilat_er" + +#: ../../po/../src/verbs.cpp:1961 +msgid "Outset selected paths" +msgstr "Dilater les chemins sélectionnés" + +#: ../../po/../src/verbs.cpp:1963 +msgid "O_utset Path by 1 px" +msgstr "Dilater le chemin de 1px (_u)" + +#: ../../po/../src/verbs.cpp:1964 +msgid "Outset selected paths by 1 px" +msgstr "Dilater les chemins sélectionnés de 1px" + +#: ../../po/../src/verbs.cpp:1966 +msgid "O_utset Path by 10 px" +msgstr "Dilater le chemin de 10px (_u)" + +#: ../../po/../src/verbs.cpp:1967 +msgid "Outset selected paths by 10 px" +msgstr "Dilater les chemins sélectionnés de 10px" + +#. TRANSLATORS: "inset": contract a shape by offsetting the object's path, +#. i.e. by displacing it perpendicular to the path in each point. +#. See also the Advanced Tutorial for explanation. +#: ../../po/../src/verbs.cpp:1971 +msgid "I_nset" +msgstr "Éroder (_n)" + +#: ../../po/../src/verbs.cpp:1972 +msgid "Inset selected paths" +msgstr "Éroder les chemins sélectionnés" + +#: ../../po/../src/verbs.cpp:1974 +msgid "I_nset Path by 1 px" +msgstr "Éroder le chemi_n de 1px" + +#: ../../po/../src/verbs.cpp:1975 +msgid "Inset selected paths by 1 px" +msgstr "Éroder les chemins sélectionnés de 1px" + +#: ../../po/../src/verbs.cpp:1977 +msgid "I_nset Path by 10 px" +msgstr "Éroder le chemi_n de 10px" + +#: ../../po/../src/verbs.cpp:1978 +msgid "Inset selected paths by 10 px" +msgstr "Éroder les chemins sélectionnés de 10px" + +#: ../../po/../src/verbs.cpp:1980 +msgid "D_ynamic Offset" +msgstr "Offset d_ynamique" + +#: ../../po/../src/verbs.cpp:1980 +msgid "Create a dynamic offset object" +msgstr "Créer un objet offset dynamique" + +#: ../../po/../src/verbs.cpp:1982 +msgid "_Linked Offset" +msgstr "Offset _lié" + +# fred: dynamic offset object +#: ../../po/../src/verbs.cpp:1983 +msgid "Create a dynamic offset object linked to the original path" +msgstr "Créer un objet offset dynamique lié au chemin original" + +#: ../../po/../src/verbs.cpp:1985 +msgid "_Stroke to Path" +msgstr "Contour en chemin (_s)" + +#: ../../po/../src/verbs.cpp:1986 +msgid "Convert selected strokes to paths" +msgstr "Convertir les contours sélectionnés en chemins" + +#: ../../po/../src/verbs.cpp:1987 +msgid "Si_mplify" +msgstr "Si_mplifier" + +#: ../../po/../src/verbs.cpp:1988 +msgid "Simplify selected paths by removing extra nodes" +msgstr "Simplifier les chemins sélectionnés en retirant des nœuds superflus" + +#: ../../po/../src/verbs.cpp:1989 +msgid "_Reverse" +msgstr "Inverse_r" + +#: ../../po/../src/verbs.cpp:1990 +msgid "Reverses the direction of selected paths; useful for flipping markers" +msgstr "" +"Inverser la direction des chemins sélectionnés; utile pour inverser la " +"direction des marqueurs" + +#. TRANSLATORS: "to trace" means "to convert a bitmap to vector graphics" (to vectorize) +#: ../../po/../src/verbs.cpp:1992 +msgid "_Trace Bitmap" +msgstr "Vec_toriser le bitmap" + +#: ../../po/../src/verbs.cpp:1993 +msgid "Convert bitmap object to paths" +msgstr "Convertir un objet bitmap en chemin" + +#: ../../po/../src/verbs.cpp:1994 +msgid "_Make a Bitmap Copy" +msgstr "Faire une copie en bit_map" + +#: ../../po/../src/verbs.cpp:1995 +msgid "Export selection to a bitmap and insert it into document" +msgstr "Exporter la sélection en bitmap et réinsérer celui-ci dans le document" + +#: ../../po/../src/verbs.cpp:1996 +msgid "_Combine" +msgstr "_Combiner" + +#: ../../po/../src/verbs.cpp:1997 +msgid "Combine several paths into one" +msgstr "Combiner plusieurs chemins en un seul" + +#. TRANSLATORS: "to cut a path" is not the same as "to break a path apart" - see the +#. Advanced tutorial for more info +#: ../../po/../src/verbs.cpp:2000 +msgid "Break _Apart" +msgstr "Séparer" + +#: ../../po/../src/verbs.cpp:2001 +msgid "Break selected paths into subpaths" +msgstr "Séparer les chemins sélectionnés en sous-chemins" + +#: ../../po/../src/verbs.cpp:2002 +msgid "Gri_d Arrange..." +msgstr "_Disposer sur une grille..." + +#: ../../po/../src/verbs.cpp:2003 +msgid "Arrange selection in grid pattern" +msgstr "Disposer la sélection selon une grille" + +#. Layer +#: ../../po/../src/verbs.cpp:2005 +msgid "_Add Layer..." +msgstr "_Ajouter un calque..." + +#: ../../po/../src/verbs.cpp:2006 +msgid "Create a new layer" +msgstr "Créer un nouveau calque" + +#: ../../po/../src/verbs.cpp:2007 +msgid "Re_name Layer..." +msgstr "Re_nommer le calque..." + +#: ../../po/../src/verbs.cpp:2008 +msgid "Rename the current layer" +msgstr "Renommer le calque courant" + +#: ../../po/../src/verbs.cpp:2009 +msgid "Switch to Layer Abov_e" +msgstr "Passer au calque supéri_eur" + +#: ../../po/../src/verbs.cpp:2010 +msgid "Switch to the layer above the current" +msgstr "Passer au calque au-dessus du calque courrant" + +#: ../../po/../src/verbs.cpp:2011 +msgid "Switch to Layer Belo_w" +msgstr "Passer au calque inférieur (_w)" + +#: ../../po/../src/verbs.cpp:2012 +msgid "Switch to the layer below the current" +msgstr "Passer au calque en-dessous du calque courrant" + +#: ../../po/../src/verbs.cpp:2013 +msgid "Move Selection to Layer Abo_ve" +msgstr "Déplacer la sélection au calque supérieur (_v)" + +#: ../../po/../src/verbs.cpp:2014 +msgid "Move selection to the layer above the current" +msgstr "Déplacer la sélection vers le calque au-dessus du calque courant" + +#: ../../po/../src/verbs.cpp:2015 +msgid "Move Selection to Layer Bel_ow" +msgstr "Déplacer la sélection au calque inférieur (_o)" + +#: ../../po/../src/verbs.cpp:2016 +msgid "Move selection to the layer below the current" +msgstr "Déplacer la sélection vers le calque en-dessous du calque courant" + +#: ../../po/../src/verbs.cpp:2017 +msgid "Layer to _Top" +msgstr "Calque au premier plan (_t)" + +#: ../../po/../src/verbs.cpp:2018 +msgid "Raise the current layer to the top" +msgstr "Monter le calque courant au premier plan" + +#: ../../po/../src/verbs.cpp:2019 +msgid "Layer to _Bottom" +msgstr "Calque à l'arrière plan (_b)" + +#: ../../po/../src/verbs.cpp:2020 +msgid "Lower the current layer to the bottom" +msgstr "Descendre le calque courant à l'arrière plan" + +#: ../../po/../src/verbs.cpp:2021 +msgid "_Raise Layer" +msgstr "Monte_r le calque" + +#: ../../po/../src/verbs.cpp:2022 +msgid "Raise the current layer" +msgstr "Monter le calque courant" + +#: ../../po/../src/verbs.cpp:2023 +msgid "_Lower Layer" +msgstr "Descendre le ca_lque" + +#: ../../po/../src/verbs.cpp:2024 +msgid "Lower the current layer" +msgstr "Descendre le calque courant" + +#: ../../po/../src/verbs.cpp:2025 +msgid "_Delete Current Layer" +msgstr "Supprimer le calque courant (_d)" + +#: ../../po/../src/verbs.cpp:2026 +msgid "Delete the current layer" +msgstr "Supprimer le calque courant" + +#. Object +#: ../../po/../src/verbs.cpp:2029 +#, fuzzy +msgid "Rotate _90° CW" +msgstr "Tourner de _90 degrés à droite" + +#: ../../po/../src/verbs.cpp:2030 +#, fuzzy +msgid "Rotate selection 90° clockwise" +msgstr "Tourner la sélection de 90° dans le sens horaire" + +#: ../../po/../src/verbs.cpp:2031 +#, fuzzy +msgid "Rotate 9_0° CCW" +msgstr "Tourner de 9_0 degrés à gauche" + +#: ../../po/../src/verbs.cpp:2032 +#, fuzzy +msgid "Rotate selection 90° counter-clockwise" +msgstr "Tourner la sélection de 90° dans le sens anti-horaire" + +#: ../../po/../src/verbs.cpp:2033 +msgid "Remove _Transformations" +msgstr "Supprimer les _transformations" + +#: ../../po/../src/verbs.cpp:2034 +msgid "Remove transformations from object" +msgstr "Supprimer les transformations de l'objet" + +#: ../../po/../src/verbs.cpp:2035 +msgid "_Object to Path" +msgstr "_Objet en chemin" + +#: ../../po/../src/verbs.cpp:2036 +msgid "Convert selected objects to paths" +msgstr "Convertir les objets sélectionnés en chemins" + +#: ../../po/../src/verbs.cpp:2037 +msgid "_Flow into Frame" +msgstr "Encadrer (_f)" + +#: ../../po/../src/verbs.cpp:2038 +msgid "Put text into frames" +msgstr "Insérer du texte dans des cadres" + +#: ../../po/../src/verbs.cpp:2039 +msgid "_Unflow" +msgstr "Désencadrer (_u)" + +#: ../../po/../src/verbs.cpp:2040 +msgid "Remove text from frame (creates a single-line text object)" +msgstr "Retirer le texte du cadre (crée un objet texte d'une seule ligne)" + +#: ../../po/../src/verbs.cpp:2041 +msgid "_Convert to Text" +msgstr "_Convertir en texte" + +#: ../../po/../src/verbs.cpp:2042 +msgid "Convert flowed text to regular text objects (preserves appearance)" +msgstr "" +"Convertir du texte encadré en textes normaux (en préservant leur apparence)" + +#: ../../po/../src/verbs.cpp:2044 +msgid "Flip _Horizontal" +msgstr "Retourner _horizontalement" + +#: ../../po/../src/verbs.cpp:2044 +msgid "Flips selected objects horizontally" +msgstr "Retourner horizontalement les objets sélectionnés" + +#: ../../po/../src/verbs.cpp:2047 +msgid "Flip _Vertical" +msgstr "Retourner _verticalement" + +#: ../../po/../src/verbs.cpp:2047 +msgid "Flips selected objects vertically" +msgstr "Retourner verticalement les objets sélectionnés" + +#. Tools +#: ../../po/../src/verbs.cpp:2051 +msgid "Select" +msgstr "Sélectionner" + +#: ../../po/../src/verbs.cpp:2052 +msgid "Select and transform objects" +msgstr "Sélectionner et transformer des objets" + +#: ../../po/../src/verbs.cpp:2053 +msgid "Node Edit" +msgstr "Éditer les nœuds" + +#: ../../po/../src/verbs.cpp:2054 +msgid "Edit path nodes or control handles" +msgstr "Éditer les nœuds ou les poignées de contrôle d'un chemin" + +#: ../../po/../src/verbs.cpp:2056 +msgid "Create rectangles and squares" +msgstr "Créer des rectangles et des carrés" + +#: ../../po/../src/verbs.cpp:2058 +msgid "Create circles, ellipses, and arcs" +msgstr "Créer des cercles, des ellipses et des arcs" + +#: ../../po/../src/verbs.cpp:2060 +msgid "Create stars and polygons" +msgstr "Créer des étoiles et des polygones" + +#: ../../po/../src/verbs.cpp:2062 +msgid "Create spirals" +msgstr "Créer des spirales" + +#: ../../po/../src/verbs.cpp:2064 +msgid "Draw freehand lines" +msgstr "Dessiner des lignes à main levée" + +#: ../../po/../src/verbs.cpp:2066 +msgid "Draw Bezier curves and straight lines" +msgstr "Tracer des courbes de Bézier et des segments de droites" + +#: ../../po/../src/verbs.cpp:2068 +msgid "Draw calligraphic lines" +msgstr "Tracer des lignes calligraphique à la plume" + +#: ../../po/../src/verbs.cpp:2070 +msgid "Create and edit text objects" +msgstr "Créer et éditer des objets textes" + +#: ../../po/../src/verbs.cpp:2072 +msgid "Create and edit gradients" +msgstr "Créer et éditer des dégradés" + +#: ../../po/../src/verbs.cpp:2074 +msgid "Zoom in or out" +msgstr "(Dé)zoommer" + +#: ../../po/../src/verbs.cpp:2076 +msgid "Pick averaged colors from image" +msgstr "Capturer des couleurs moyennées depuis l'image" + +#: ../../po/../src/verbs.cpp:2078 +msgid "Create connectors" +msgstr "Créer des connecteurs" + +#. Tool prefs +#: ../../po/../src/verbs.cpp:2081 +msgid "Selector Preferences" +msgstr "Préférences du sélecteur" + +#: ../../po/../src/verbs.cpp:2082 +msgid "Open Preferences for the Selector tool" +msgstr "Ouvrir les préférences de l'outil sélecteur" + +#: ../../po/../src/verbs.cpp:2083 +msgid "Node Tool Preferences" +msgstr "Préférences des nœuds" + +#: ../../po/../src/verbs.cpp:2084 +msgid "Open Preferences for the Node tool" +msgstr "Ouvrir les préférences de l'outil nœud" + +#: ../../po/../src/verbs.cpp:2085 +msgid "Rectangle Preferences" +msgstr "Préférences des rectangles" + +#: ../../po/../src/verbs.cpp:2086 +msgid "Open Preferences for the Rectangle tool" +msgstr "Ouvrir les préférences de l'outil rectangle" + +#: ../../po/../src/verbs.cpp:2087 +msgid "Ellipse Preferences" +msgstr "Préférences des ellipses" + +#: ../../po/../src/verbs.cpp:2088 +msgid "Open Preferences for the Ellipse tool" +msgstr "Ouvrir les préférences de l'outil ellipse" + +#: ../../po/../src/verbs.cpp:2089 +msgid "Star Preferences" +msgstr "Préférences des étoiles" + +#: ../../po/../src/verbs.cpp:2090 +msgid "Open Preferences for the Star tool" +msgstr "Ouvrir les préférences de l'outil étoile" + +#: ../../po/../src/verbs.cpp:2091 +msgid "Spiral Preferences" +msgstr "Préférences des spirales" + +#: ../../po/../src/verbs.cpp:2092 +msgid "Open Preferences for the Spiral tool" +msgstr "Ouvrir les préférences de l'outil spirale" + +#: ../../po/../src/verbs.cpp:2093 +msgid "Pencil Preferences" +msgstr "Préférences du crayon" + +#: ../../po/../src/verbs.cpp:2094 +msgid "Open Preferences for the Pencil tool" +msgstr "Ouvrir les préférences de l'outil crayon" + +#: ../../po/../src/verbs.cpp:2095 +msgid "Pen Preferences" +msgstr "Préférences du stylo" + +#: ../../po/../src/verbs.cpp:2096 +msgid "Open Preferences for the Pen tool" +msgstr "Ouvrir les préférences de l'outil stylo" + +#: ../../po/../src/verbs.cpp:2097 +msgid "Calligraphic Preferences" +msgstr "Préférences de la plume calligraphique" + +#: ../../po/../src/verbs.cpp:2098 +msgid "Open Preferences for the Calligraphy tool" +msgstr "Ouvrir les préférences de la plume calligraphique" + +#: ../../po/../src/verbs.cpp:2099 +msgid "Text Preferences" +msgstr "Préférences des textes" + +#: ../../po/../src/verbs.cpp:2100 +msgid "Open Preferences for the Text tool" +msgstr "Ouvrir les préférences de l'outil texte" + +#: ../../po/../src/verbs.cpp:2101 +msgid "Gradient Preferences" +msgstr "Préférences des dégradés" + +#: ../../po/../src/verbs.cpp:2102 +msgid "Open Preferences for the Gradient tool" +msgstr "Ouvrir les préférences de l'outil de dégradé" + +#: ../../po/../src/verbs.cpp:2103 +msgid "Zoom Preferences" +msgstr "Préférences du zoom" + +#: ../../po/../src/verbs.cpp:2104 +msgid "Open Preferences for the Zoom tool" +msgstr "Ouvrir les préférences de l'outil zoom" + +#: ../../po/../src/verbs.cpp:2105 +msgid "Dropper Preferences" +msgstr "Préférences de la pipette" + +#: ../../po/../src/verbs.cpp:2106 +msgid "Open Preferences for the Dropper tool" +msgstr "Ouvrir les préférences de l'outil pipette" + +#: ../../po/../src/verbs.cpp:2107 +msgid "Connector Preferences" +msgstr "Préférences des connecteurs" + +#: ../../po/../src/verbs.cpp:2108 +msgid "Open Preferences for the Connector tool" +msgstr "Ouvrir les préférences de l'outil connecteur" + +#. Zoom/View +#: ../../po/../src/verbs.cpp:2111 +msgid "Zoom In" +msgstr "Zoommer" + +#: ../../po/../src/verbs.cpp:2111 +msgid "Zoom in" +msgstr "Zoommer" + +#: ../../po/../src/verbs.cpp:2112 +msgid "Zoom Out" +msgstr "Dézoommer" + +#: ../../po/../src/verbs.cpp:2112 +msgid "Zoom out" +msgstr "Dézoommer" + +#: ../../po/../src/verbs.cpp:2113 +msgid "_Rulers" +msgstr "_Règles" + +#: ../../po/../src/verbs.cpp:2113 +msgid "Show or hide the canvas rulers" +msgstr "Afficher ou non les règles du canevas" + +#: ../../po/../src/verbs.cpp:2114 +msgid "Scroll_bars" +msgstr "_Barres de défilement" + +#: ../../po/../src/verbs.cpp:2114 +msgid "Show or hide the canvas scrollbars" +msgstr "Afficher ou non les barres de défilement du canevas" + +#: ../../po/../src/verbs.cpp:2115 +msgid "_Grid" +msgstr "_Grille" + +#: ../../po/../src/verbs.cpp:2116 +msgid "G_uides" +msgstr "G_uides" + +#: ../../po/../src/verbs.cpp:2117 +msgid "Nex_t Zoom" +msgstr "Zoom suivan_t" + +#: ../../po/../src/verbs.cpp:2117 +msgid "Next zoom (from the history of zooms)" +msgstr "Zoom suivant (dans l'historique des zooms)" + +#: ../../po/../src/verbs.cpp:2119 +msgid "Pre_vious Zoom" +msgstr "Zoom précédent (_v)" + +#: ../../po/../src/verbs.cpp:2119 +msgid "Previous zoom (from the history of zooms)" +msgstr "Zoom précédent (dans l'historique des zooms)" + +#: ../../po/../src/verbs.cpp:2121 +msgid "Zoom 1:_1" +msgstr "Zoom 1:_1" + +#: ../../po/../src/verbs.cpp:2121 +msgid "Zoom to 1:1" +msgstr "Zoommer à 1:1" + +#: ../../po/../src/verbs.cpp:2123 +msgid "Zoom 1:_2" +msgstr "Zoom 1:_2" + +#: ../../po/../src/verbs.cpp:2123 +msgid "Zoom to 1:2" +msgstr "Zoommer à 1:2" + +#: ../../po/../src/verbs.cpp:2125 +msgid "_Zoom 2:1" +msgstr "_Zoom 2:1" + +#: ../../po/../src/verbs.cpp:2125 +msgid "Zoom to 2:1" +msgstr "Zoommer à 2:1" + +#: ../../po/../src/verbs.cpp:2128 +msgid "_Fullscreen" +msgstr "Plein écran (_f)" + +#: ../../po/../src/verbs.cpp:2128 +msgid "Stretch this document window to full screen" +msgstr "Afficher cette fenêtre (document) en plein écran" + +#: ../../po/../src/verbs.cpp:2131 +msgid "Duplic_ate Window" +msgstr "Dupliquer la fenêtre (_a)" + +#: ../../po/../src/verbs.cpp:2131 +msgid "Open a new window with the same document" +msgstr "Ouvrir une nouvelle fenêtre avec le même document" + +#: ../../po/../src/verbs.cpp:2133 +msgid "_New View Preview" +msgstr "_Nouvel aperçu" + +#: ../../po/../src/verbs.cpp:2134 +msgid "New View Preview" +msgstr "Nouvel aperçu" + +#. "view_new_preview" +#: ../../po/../src/verbs.cpp:2136 +#, fuzzy +msgid "_Normal" +msgstr "Normal" + +#: ../../po/../src/verbs.cpp:2137 +msgid "Switch to normal display mode" +msgstr "" + +#: ../../po/../src/verbs.cpp:2138 +#, fuzzy +msgid "_Outline" +msgstr "Boîte de contour" + +#: ../../po/../src/verbs.cpp:2139 +msgid "Switch to outline (wireframe) display mode" +msgstr "" + +#: ../../po/../src/verbs.cpp:2141 +msgid "Ico_n Preview" +msgstr "Aperçu d'icô_ne" + +#: ../../po/../src/verbs.cpp:2142 +msgid "Open a window to preview items at different icon resolutions" +msgstr "" +"Ouvrir une fenêtre d'aperçu des éléments en icônes à différentes résolutions" + +#: ../../po/../src/verbs.cpp:2144 +msgid "Zoom to fit page in window" +msgstr "Ajuster la page à la fenêtre" + +#: ../../po/../src/verbs.cpp:2145 +msgid "Page _Width" +msgstr "Largeur de la page (_w)" + +#: ../../po/../src/verbs.cpp:2146 +msgid "Zoom to fit page width in window" +msgstr "Ajuster la largeur de la page à la fenêtre" + +#: ../../po/../src/verbs.cpp:2148 +msgid "Zoom to fit drawing in window" +msgstr "Ajuster le dessin à la fenêtre" + +#: ../../po/../src/verbs.cpp:2150 +msgid "Zoom to fit selection in window" +msgstr "Ajuster la sélection à la fenêtre" + +#. Dialogs +#: ../../po/../src/verbs.cpp:2153 +msgid "In_kscape Preferences..." +msgstr "Préférences d'In_kscape..." + +#: ../../po/../src/verbs.cpp:2154 +msgid "Global Inkscape preferences" +msgstr "Préférences globales d'Inkscape" + +#: ../../po/../src/verbs.cpp:2155 +msgid "_Document Preferences..." +msgstr "Préférences du _document..." + +#: ../../po/../src/verbs.cpp:2156 +msgid "Preferences saved with the document" +msgstr "Préférences enregistrées avec le document" + +#: ../../po/../src/verbs.cpp:2157 +msgid "_Fill and Stroke..." +msgstr "Remplissage et contour... (_f)" + +#: ../../po/../src/verbs.cpp:2158 +msgid "Fill and Stroke dialog" +msgstr "Boîte de dialogue «remplissage et contour»" + +#. TRANSLATORS: "Swatches" means: color samples +#: ../../po/../src/verbs.cpp:2160 +msgid "S_watches..." +msgstr "Palettes...(_w)" + +#: ../../po/../src/verbs.cpp:2161 +msgid "View color swatches" +msgstr "Voir les palettes de couleurs" + +#: ../../po/../src/verbs.cpp:2162 +msgid "Transfor_m..." +msgstr "Transfor_mer..." + +#: ../../po/../src/verbs.cpp:2163 +msgid "Transform dialog" +msgstr "Boîte de dialogue «transformer»" + +#: ../../po/../src/verbs.cpp:2164 +msgid "_Align and Distribute..." +msgstr "_Aligner et distribuer..." + +#: ../../po/../src/verbs.cpp:2165 +msgid "Align and Distribute dialog" +msgstr "Boîte de dialogue «aligner et distribuer»" + +#: ../../po/../src/verbs.cpp:2166 +msgid "_Text and Font..." +msgstr "_Texte et police..." + +#: ../../po/../src/verbs.cpp:2167 +msgid "Text and Font dialog" +msgstr "Boîte de dialogue «texte et police»" + +#: ../../po/../src/verbs.cpp:2168 +msgid "_XML Editor..." +msgstr "Éditeur _XML..." + +#: ../../po/../src/verbs.cpp:2169 +msgid "XML Editor" +msgstr "Editeur XML" + +#: ../../po/../src/verbs.cpp:2170 +msgid "_Find..." +msgstr "Rechercher... (_f)" + +#: ../../po/../src/verbs.cpp:2171 +msgid "Find objects in document" +msgstr "Rechercher des objets dans le document" + +#: ../../po/../src/verbs.cpp:2172 +msgid "_Messages..." +msgstr "_Messages..." + +#: ../../po/../src/verbs.cpp:2173 +msgid "View debug messages" +msgstr "Voir les messages de débuggage" + +#: ../../po/../src/verbs.cpp:2174 +msgid "S_cripts..." +msgstr "S_cripts..." + +#: ../../po/../src/verbs.cpp:2175 +msgid "Run scripts" +msgstr "Exécuter des scripts" + +#: ../../po/../src/verbs.cpp:2176 +msgid "Show/Hide D_ialogs" +msgstr "Afficher/cacher les boîtes de d_ialogue" + +#: ../../po/../src/verbs.cpp:2177 +msgid "Show or hide all active dialogs" +msgstr "Afficher ou cacher les boîtes de dialogue actives" + +#. TRANSLATORS: "Tile clones" means: "Create tiled clones" +#: ../../po/../src/verbs.cpp:2179 +msgid "Tile clones..." +msgstr "Paver avec des clones..." + +#: ../../po/../src/verbs.cpp:2180 +msgid "Create and arrange multiple clones of selection" +msgstr "Créer et organiser des clones multiples de la sélection" + +#: ../../po/../src/verbs.cpp:2181 +msgid "_Object Properties..." +msgstr "Propriétés de l'_objet..." + +#: ../../po/../src/verbs.cpp:2182 +msgid "Object Properties dialog" +msgstr "Boîte de dialogue «propriétés de l'objet»" + +#: ../../po/../src/verbs.cpp:2185 +msgid "_Connect to Jabber server..." +msgstr "Se _connecter à un serveur Jabber" + +#: ../../po/../src/verbs.cpp:2185 +msgid "Connect to a Jabber server" +msgstr "Se connecter à un serveur Jabber" + +#: ../../po/../src/verbs.cpp:2187 +msgid "Share with _user..." +msgstr "Partager avec l'_utilisateur" + +#: ../../po/../src/verbs.cpp:2187 +msgid "Establish a whiteboard session with another Jabber user" +msgstr "Etablir une session de tableau blanc avec un autre utilisateur Jabber" + +#: ../../po/../src/verbs.cpp:2189 +msgid "Share with _chatroom..." +msgstr "Partager avec la piè_ce de discussion" + +#: ../../po/../src/verbs.cpp:2189 +msgid "" +"Join a chatroom to start a new whiteboard session or join one in progress" +msgstr "" +"Rejoindre une pièce de discussion pour débuter une session de tableau blanc " +"ou en rejoindre une existante" + +#: ../../po/../src/verbs.cpp:2191 +msgid "_Dump XML node tracker" +msgstr "_Décharger le traceur de nœud XML" + +#: ../../po/../src/verbs.cpp:2191 +msgid "Dump the contents of the XML tracker to the console" +msgstr "Décharger/afficher le contenu du traceur XML dans la console" + +#: ../../po/../src/verbs.cpp:2193 +msgid "_Open session file..." +msgstr "_Ouvrir un fichier de session..." + +#: ../../po/../src/verbs.cpp:2193 +msgid "Open and browse through records of past whiteboard sessions" +msgstr "" +"Ouvrir et parcourir les enregistrements de sessions de tableau blanc passées" + +#: ../../po/../src/verbs.cpp:2195 +msgid "Session file playback" +msgstr "Playback d'un fichier de session" + +#: ../../po/../src/verbs.cpp:2197 +msgid "_Disconnect from session" +msgstr "Se _déconnecter de la session" + +#: ../../po/../src/verbs.cpp:2199 +msgid "Disconnect from _server" +msgstr "Se déconnecter du serveur" + +#: ../../po/../src/verbs.cpp:2201 +msgid "_Input Devices..." +msgstr "Périphériques de sais_ie..." + +#: ../../po/../src/verbs.cpp:2202 +msgid "Configure extended input devices" +msgstr "Configurer les périphériques de saisie étendus" + +#. Help +#: ../../po/../src/verbs.cpp:2205 +msgid "_Keys and Mouse" +msgstr "Clavier et souris (_K)" + +#: ../../po/../src/verbs.cpp:2206 +msgid "Key and mouse shortcuts reference" +msgstr "Liste des raccourcis clavier et souris" + +#: ../../po/../src/verbs.cpp:2207 +msgid "About E_xtensions" +msgstr "A propos des e_xtensions" + +#: ../../po/../src/verbs.cpp:2208 +msgid "About Extensions..." +msgstr "A propos des extension" + +#: ../../po/../src/verbs.cpp:2209 +msgid "About _Memory" +msgstr "Gestion _mémoire" + +#: ../../po/../src/verbs.cpp:2210 +msgid "About Memory..." +msgstr "Gestion de la mémoire" + +#: ../../po/../src/verbs.cpp:2211 +msgid "_About Inkscape" +msgstr "_À propos d'Inkscape" + +#. "help_about" +#. new HelpVerb(SP_VERB_SHOW_LICENSE, "ShowLicense", N_("Modifying or Redistributing Inkscape"), +#. N_("Show license to modify and/or redistribute Inkscape: GNU GPL"), NULL), +#. Tutorials +#: ../../po/../src/verbs.cpp:2217 +msgid "Inkscape: _Basic" +msgstr "Inkscape : _basique" + +#: ../../po/../src/verbs.cpp:2218 +msgid "Getting started with Inkscape" +msgstr "Premiers pas avec Inkscape" + +#. "tutorial_basic" +#: ../../po/../src/verbs.cpp:2219 +msgid "Inkscape: _Shapes" +msgstr "Inkscape : forme_s" + +#: ../../po/../src/verbs.cpp:2220 +msgid "Using shape tools to create and edit shapes" +msgstr "Utilisation des outils de formes pour créer et éditer des formes" + +#: ../../po/../src/verbs.cpp:2221 +msgid "Inkscape: _Advanced" +msgstr "Inkscape : _avancé" + +#: ../../po/../src/verbs.cpp:2222 +msgid "Advanced Inkscape topics" +msgstr "Sujets avancés d'Inkscape" + +#. "tutorial_advanced" +#. TRANSLATORS: "to trace" means "to convert a bitmap to vector graphics" (to vectorize) +#: ../../po/../src/verbs.cpp:2224 +msgid "Inkscape: T_racing" +msgstr "Inkscape : vecto_risation" + +#: ../../po/../src/verbs.cpp:2225 +msgid "Using bitmap tracing" +msgstr "Vectorisation de bitmap" + +#. "tutorial_tracing" +#: ../../po/../src/verbs.cpp:2226 +msgid "Inkscape: _Calligraphy" +msgstr "Inkscape : _calligraphie" + +#: ../../po/../src/verbs.cpp:2227 +msgid "Using the Calligraphy pen tool" +msgstr "Utilisation de la plume calligraphique d'Inkscape" + +#: ../../po/../src/verbs.cpp:2228 +msgid "_Elements of Design" +msgstr "Rudiments de d_esign" + +#: ../../po/../src/verbs.cpp:2229 +msgid "Principles of design in the tutorial form" +msgstr "Rudiments de design sous forme de didacticiel" + +#. "tutorial_design" +#: ../../po/../src/verbs.cpp:2230 +msgid "_Tips and Tricks" +msgstr "_Trucs et astuces" + +#: ../../po/../src/verbs.cpp:2231 +msgid "Miscellaneous tips and tricks" +msgstr "Divers trucs et astuces" + +#. "tutorial_tips" +#. Effect +#: ../../po/../src/verbs.cpp:2234 +msgid "Previous Effect" +msgstr "Effet précédent" + +#: ../../po/../src/verbs.cpp:2235 +msgid "Repeat the last effect with the same settings" +msgstr "Répéter le dernier effet avec les mêmes paramètres" + +#. "tutorial_tips" +#: ../../po/../src/verbs.cpp:2236 +msgid "Previous Effect Settings..." +msgstr "Paramètres de l'effet précédent..." + +#: ../../po/../src/verbs.cpp:2237 +msgid "Repeat the last effect with new settings" +msgstr "Répéter le dernier effet avec les nouveaux paramètres" + +#: ../../po/../src/widgets/dash-selector.cpp:106 +msgid "Dash pattern" +msgstr "Motif de pointillé" + +#: ../../po/../src/widgets/dash-selector.cpp:121 +msgid "Pattern offset" +msgstr "Décalage du motif" + +#: ../../po/../src/widgets/desktop-widget.cpp:240 +msgid "Zoom drawing if window size changes" +msgstr "Zoomer le dessin si la taille de la fenêtre change" + +#: ../../po/../src/widgets/desktop-widget.cpp:298 +msgid "Cursor coordinates" +msgstr "Coordonnées du curseur" + +#. display the initial welcome message in the statusbar +#: ../../po/../src/widgets/desktop-widget.cpp:324 +msgid "" +"Welcome to Inkscape! Use shape or freehand tools to create objects; " +"use selector (arrow) to move or transform them." +msgstr "" +"Bienvenue dans Inkscape! Utilisez les formes ou l'outil de dessin à " +"main levée pour créer des objets; utilisez les sélecteurs (flèches) pour les " +"déplacer ou les modifier." + +#: ../../po/../src/widgets/desktop-widget.cpp:372 +#, c-format +msgid "%s: %d - Inkscape" +msgstr "%s: %d - Inkscape" + +#: ../../po/../src/widgets/desktop-widget.cpp:374 +#, c-format +msgid "%s - Inkscape" +msgstr "%s - Inkscape" + +#: ../../po/../src/widgets/desktop-widget.cpp:532 +#, c-format +msgid "" +"Save changes to document \"%s\" before " +"closing?\n" +"\n" +"If you close without saving, your changes will be discarded." +msgstr "" +"Enregistrer les modifications du " +"document «%s» avant de fermer ?\n" +"\n" +"Si vous fermez sans enregistrer, vos modifications seront perdues." + +#: ../../po/../src/widgets/desktop-widget.cpp:548 +#: ../../po/../src/widgets/desktop-widget.cpp:612 +msgid "Close _without saving" +msgstr "Fermer sans enregistrer (_w)" + +#: ../../po/../src/widgets/desktop-widget.cpp:595 +#, c-format +msgid "" +"The file \"%s\" was saved with a " +"format (%s) that may cause data loss!\n" +"\n" +"Do you want to save this file in another format?" +msgstr "" +"Le fichier «%s» a été enregistré dans " +"un format (%s) qui peut causer des pertes de données !\n" +"\n" +"Voulez-vous enregistrer ce fichier dans un autre format ?" + +#. Family frame +#: ../../po/../src/widgets/font-selector.cpp:156 +msgid "Font family" +msgstr "Famille de police" + +#. Style frame +#: ../../po/../src/widgets/font-selector.cpp:184 +msgid "Style" +msgstr "Style" + +#: ../../po/../src/widgets/font-selector.cpp:219 +msgid "Font size:" +msgstr "Taille de police :" + +# Do not try to translate. This is a test string used in text and font dialog, when no text has been typed in order to get a preview of the font. +# Simply copying it. +#. TRANSLATORS: Test string used in text and font dialog (when no +#. * text has been entered) to get a preview of the font. Choose +#. * some representative characters that users of your locale will be +#. * interested in. +#: ../../po/../src/widgets/font-selector.cpp:554 +msgid "AaBbCcIiPpQq12368.;/()" +msgstr "AaBbCcIiPpQq12368.;/()" + +#: ../../po/../src/widgets/gradient-selector.cpp:137 +#: ../../po/../src/widgets/gradient-toolbar.cpp:524 +msgid "Duplicate" +msgstr "Dupliquer" + +#: ../../po/../src/widgets/gradient-selector.cpp:142 +#: ../../po/../src/widgets/gradient-toolbar.cpp:535 +msgid "Edit..." +msgstr "Éditer..." + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/pservers.html#LinearGradientSpreadMethodAttribute +#: ../../po/../src/widgets/gradient-selector.cpp:159 +msgid "" +"Whether to fill with flat color beyond the ends of the gradient vector " +"(spreadMethod=\"pad\"), or repeat the gradient in the same direction " +"(spreadMethod=\"repeat\"), or repeat the gradient in alternating opposite " +"directions (spreadMethod=\"reflect\")" +msgstr "" +"Comment compléter le dégradé au delà de la définition de son vecteur : " +"prolonger par une zone uniforme de la dernière couleur (aucune, spreadMethod=" +"\"pad\"), répéter le dégradé (directe, spreadMethod=\"repeat\") ou le " +"réfléchir (réflection, spreadMethod=\"reflect\")" + +#: ../../po/../src/widgets/gradient-selector.cpp:165 +msgid "none" +msgstr "aucune" + +#: ../../po/../src/widgets/gradient-selector.cpp:169 +msgid "reflected" +msgstr "réflection" + +#: ../../po/../src/widgets/gradient-selector.cpp:173 +msgid "direct" +msgstr "directe" + +#: ../../po/../src/widgets/gradient-selector.cpp:181 +msgid "Repeat:" +msgstr "Répétition :" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:217 +msgid "No gradients" +msgstr "Aucun dégradé" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:226 +msgid "Nothing selected" +msgstr "Aucune sélection" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:237 +msgid "No gradients in selection" +msgstr "Aucun dégradé dans la sélection" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:247 +msgid "Multiple gradients" +msgstr "Plusieurs dégradés" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:525 +msgid "" +"If the gradient is used by more than one object, create a copy of it for the " +"selected object(s)" +msgstr "" +"Si le dégradé est utilisé par plus d'un objet, en créer une copie pour " +"l'objet sélectionné" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:536 +msgid "Edit the stops of the gradient" +msgstr "Editer les stops du dégradé" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:593 +#: ../../po/../src/widgets/toolbox.cpp:1103 +#: ../../po/../src/widgets/toolbox.cpp:1192 +#: ../../po/../src/widgets/toolbox.cpp:1485 +#: ../../po/../src/widgets/toolbox.cpp:1534 +#: ../../po/../src/widgets/toolbox.cpp:1766 +#: ../../po/../src/widgets/toolbox.cpp:1801 +#: ../../po/../src/widgets/toolbox.cpp:2331 +#: ../../po/../src/widgets/toolbox.cpp:2370 +msgid "New:" +msgstr "Créer :" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:606 +msgid "Create linear gradient" +msgstr "Créer un dégradé linéaire" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:620 +msgid "Create radial (elliptic or circular) gradient" +msgstr "Créer un dégradé radial (elliptique ou circulaire)" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:635 +msgid "on" +msgstr "à" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:648 +msgid "Create gradient in the fill" +msgstr "Appliquer le dégradé au remplissage" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:662 +msgid "Create gradient in the stroke" +msgstr "Appliquer le dégradé au contour" + +#. FIXME: implement averaging of all parameters for multiple selected stars +#. gtk_label_set_markup(GTK_LABEL(l), _("Average:")); +#. FIXME: implement averaging of all parameters for multiple selected +#. gtk_label_set_markup(GTK_LABEL(l), _("Average:")); +#: ../../po/../src/widgets/gradient-toolbar.cpp:676 +#: ../../po/../src/widgets/toolbox.cpp:1105 +#: ../../po/../src/widgets/toolbox.cpp:1124 +#: ../../po/../src/widgets/toolbox.cpp:1493 +#: ../../po/../src/widgets/toolbox.cpp:1518 +#: ../../po/../src/widgets/toolbox.cpp:1768 +#: ../../po/../src/widgets/toolbox.cpp:1787 +#: ../../po/../src/widgets/toolbox.cpp:2334 +#: ../../po/../src/widgets/toolbox.cpp:2354 +msgid "Change:" +msgstr "Modifier :" + +#: ../../po/../src/widgets/gradient-vector.cpp:269 +msgid "No gradients in document" +msgstr "Le document ne contient pas de dégradé" + +#: ../../po/../src/widgets/gradient-vector.cpp:275 +msgid "No gradient selected" +msgstr "Aucun dégradé n'est sélectionné" + +#: ../../po/../src/widgets/gradient-vector.cpp:532 +msgid "No stops in gradient" +msgstr "Il n'y a pas de stop dans le dégradé" + +#. TRANSLATORS: "Stop" means: a "phase" of a gradient +#: ../../po/../src/widgets/gradient-vector.cpp:794 +msgid "Add stop" +msgstr "Ajouter un stop" + +#: ../../po/../src/widgets/gradient-vector.cpp:797 +msgid "Add another control stop to gradient" +msgstr "Ajouter un nouveau stop de contrôle au dégradé" + +#: ../../po/../src/widgets/gradient-vector.cpp:799 +msgid "Delete stop" +msgstr "Supprimer un stop" + +#: ../../po/../src/widgets/gradient-vector.cpp:802 +msgid "Delete current control stop from gradient" +msgstr "Supprimer le stop courant du dégradé" + +#. Label +#: ../../po/../src/widgets/gradient-vector.cpp:813 +msgid "Offset:" +msgstr "Décalage :" + +#. TRANSLATORS: "Stop" means: a "phase" of a gradient +#: ../../po/../src/widgets/gradient-vector.cpp:858 +msgid "Stop Color" +msgstr "Couleur du stop" + +#: ../../po/../src/widgets/gradient-vector.cpp:887 +msgid "Gradient editor" +msgstr "Éditeur de dégradé" + +#: ../../po/../src/widgets/layer-selector.cpp:119 +msgid "Toggle current layer visibility" +msgstr "Rendre (in)visible le calque courant" + +#: ../../po/../src/widgets/layer-selector.cpp:139 +msgid "Lock or unlock current layer" +msgstr "(Dé)verrouiller le calque courant" + +#: ../../po/../src/widgets/layer-selector.cpp:142 +msgid "Current layer" +msgstr "Calque courant" + +#: ../../po/../src/widgets/layer-selector.cpp:553 +msgid "(root)" +msgstr "(racine)" + +#: ../../po/../src/widgets/paint-selector.cpp:182 +#: ../../po/../src/widgets/paint-selector.cpp:561 +msgid "No paint" +msgstr "Pas de peinture" + +#: ../../po/../src/widgets/paint-selector.cpp:184 +#: ../../po/../src/widgets/paint-selector.cpp:629 +msgid "Flat color" +msgstr "Couleur uniforme" + +#: ../../po/../src/widgets/paint-selector.cpp:186 +#: ../../po/../src/widgets/paint-selector.cpp:696 +msgid "Linear gradient" +msgstr "Dégradé linéaire" + +#: ../../po/../src/widgets/paint-selector.cpp:188 +#: ../../po/../src/widgets/paint-selector.cpp:699 +msgid "Radial gradient" +msgstr "Dégradé radial" + +#: ../../po/../src/widgets/paint-selector.cpp:192 +msgid "Unset paint (make it undefined so it can be inherited)" +msgstr "" +"Indéfinir la peinture (le rendre indéfini de sorte qu'il puisse être hérité)" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/painting.html#FillRuleProperty +#: ../../po/../src/widgets/paint-selector.cpp:204 +msgid "" +"Any path self-intersections or subpaths create holes in the fill (fill-rule: " +"evenodd)" +msgstr "" +"Toute intersection d'un chemin avec lui-même ou avec un de ses sous-chemins " +"engendrera des lacunes dans le remplissage (fill-rule: evenodd)" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/painting.html#FillRuleProperty +#: ../../po/../src/widgets/paint-selector.cpp:215 +msgid "" +"Fill is solid unless a subpath is counterdirectional (fill-rule: nonzero)" +msgstr "" +"Pas de lacune dans le remplissage à moins qu'un sous-chemin soit en " +"direction inverse (fill-rule: nonzero)" + +#: ../../po/../src/widgets/paint-selector.cpp:528 +msgid "No objects" +msgstr "Aucun objet" + +#: ../../po/../src/widgets/paint-selector.cpp:539 +msgid "Multiple styles" +msgstr "Styles multiples" + +#: ../../po/../src/widgets/paint-selector.cpp:550 +msgid "Paint is undefined" +msgstr "La peinture est indéfinie" + +#: ../../po/../src/widgets/paint-selector.cpp:757 +msgid "No patterns in document" +msgstr "Aucun motif de remplissage dans le document" + +#: ../../po/../src/widgets/paint-selector.cpp:872 +msgid "" +"Use Edit > Object(s) to Pattern to create a new pattern from " +"selection." +msgstr "" +"Utiliser Édition > Objet(s) en motif pour faire de la sélection un " +"nouveau motif de remplissage." + +#: ../../po/../src/widgets/select-toolbar.cpp:426 +msgid "Now stroke width is scaled when objects are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:428 +msgid "Now stroke width is not scaled when objects are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:436 +msgid "" +"Now rounded rectangle corners are scaled when rectangles are " +"scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:438 +msgid "" +"Now rounded rectangle corners are not scaled when rectangles " +"are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:446 +msgid "" +"Now gradients are transformed along with their objects when " +"those are transformed (moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:448 +msgid "" +"Now gradients remain fixed when objects are transformed " +"(moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:456 +msgid "" +"Now patterns are transformed along with their objects when " +"those are transformed (moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:458 +msgid "" +"Now patterns remain fixed when objects are transformed (moved, " +"scaled, rotated, or skewed)." +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:506 +msgid "select_toolbar|X" +msgstr "X" + +#: ../../po/../src/widgets/select-toolbar.cpp:506 +msgid "Horizontal coordinate of selection" +msgstr "Coordonnée horizontale de la sélection" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:511 +msgid "select_toolbar|Y" +msgstr "Y" + +#: ../../po/../src/widgets/select-toolbar.cpp:511 +msgid "Vertical coordinate of selection" +msgstr "Coordonnée verticale de la sélection" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:517 +msgid "select_toolbar|W" +msgstr "L" + +#: ../../po/../src/widgets/select-toolbar.cpp:517 +msgid "Width of selection" +msgstr "Largeur de la sélection" + +#: ../../po/../src/widgets/select-toolbar.cpp:525 +msgid "Change both width and height by the same proportion" +msgstr "Modifier la hauteur et la largeur selon la même proportion" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:534 +msgid "select_toolbar|H" +msgstr "H" + +#: ../../po/../src/widgets/select-toolbar.cpp:534 +msgid "Height of selection" +msgstr "Hauteur de la sélection" + +#: ../../po/../src/widgets/sp-color-gtkselector.cpp:62 +msgid "System" +msgstr "Système" + +#: ../../po/../src/widgets/sp-color-notebook.cpp:322 +msgid "RGBA_:" +msgstr "RVBA _:" + +#: ../../po/../src/widgets/sp-color-notebook.cpp:330 +msgid "Hexadecimal RGBA value of the color" +msgstr "Valeur hexadécimale RVBA de la couleur" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "RGB" +msgstr "RVB" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "HSL" +msgstr "TSL" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "CMYK" +msgstr "CMJN" + +# Red (in RGB) +#: ../../po/../src/widgets/sp-color-scales.cpp:397 +msgid "_R" +msgstr "_R" + +#: ../../po/../src/widgets/sp-color-scales.cpp:398 +#: ../../po/../src/widgets/sp-color-scales.cpp:399 +msgid "Red" +msgstr "Rouge" + +# Green (in RGB) +#: ../../po/../src/widgets/sp-color-scales.cpp:400 +msgid "_G" +msgstr "V (_g)" + +#: ../../po/../src/widgets/sp-color-scales.cpp:401 +#: ../../po/../src/widgets/sp-color-scales.cpp:402 +msgid "Green" +msgstr "Vert" + +# Blue (in RGB) +#: ../../po/../src/widgets/sp-color-scales.cpp:403 +msgid "_B" +msgstr "_B" + +#: ../../po/../src/widgets/sp-color-scales.cpp:404 +#: ../../po/../src/widgets/sp-color-scales.cpp:405 +msgid "Blue" +msgstr "Bleu" + +# Alpha (opacity) +#. Label +#: ../../po/../src/widgets/sp-color-scales.cpp:406 +#: ../../po/../src/widgets/sp-color-scales.cpp:432 +#: ../../po/../src/widgets/sp-color-scales.cpp:463 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:141 +msgid "_A" +msgstr "_A" + +#: ../../po/../src/widgets/sp-color-scales.cpp:407 +#: ../../po/../src/widgets/sp-color-scales.cpp:408 +#: ../../po/../src/widgets/sp-color-scales.cpp:433 +#: ../../po/../src/widgets/sp-color-scales.cpp:434 +#: ../../po/../src/widgets/sp-color-scales.cpp:464 +#: ../../po/../src/widgets/sp-color-scales.cpp:465 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:151 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:163 +msgid "Alpha (opacity)" +msgstr "Alpha (opacité)" + +# Hue (in HSL) +#: ../../po/../src/widgets/sp-color-scales.cpp:423 +msgid "_H" +msgstr "T (_h)" + +#: ../../po/../src/widgets/sp-color-scales.cpp:424 +#: ../../po/../src/widgets/sp-color-scales.cpp:425 +msgid "Hue" +msgstr "Teinte" + +# Saturation (in HSL) +#: ../../po/../src/widgets/sp-color-scales.cpp:426 +msgid "_S" +msgstr "_S" + +#: ../../po/../src/widgets/sp-color-scales.cpp:427 +#: ../../po/../src/widgets/sp-color-scales.cpp:428 +msgid "Saturation" +msgstr "Saturation" + +# Luminosity (in HSL) +#: ../../po/../src/widgets/sp-color-scales.cpp:429 +msgid "_L" +msgstr "_L" + +#: ../../po/../src/widgets/sp-color-scales.cpp:430 +#: ../../po/../src/widgets/sp-color-scales.cpp:431 +msgid "Lightness" +msgstr "Luminosité" + +# Cyan (in CYMK) +#: ../../po/../src/widgets/sp-color-scales.cpp:451 +msgid "_C" +msgstr "_C" + +#: ../../po/../src/widgets/sp-color-scales.cpp:452 +#: ../../po/../src/widgets/sp-color-scales.cpp:453 +msgid "Cyan" +msgstr "Cyan" + +# Magenta (in CYMK) +#: ../../po/../src/widgets/sp-color-scales.cpp:454 +msgid "_M" +msgstr "_M" + +#: ../../po/../src/widgets/sp-color-scales.cpp:455 +#: ../../po/../src/widgets/sp-color-scales.cpp:456 +msgid "Magenta" +msgstr "Magenta" + +# Yellow (in CYMK) +#: ../../po/../src/widgets/sp-color-scales.cpp:457 +msgid "_Y" +msgstr "J (_y)" + +#: ../../po/../src/widgets/sp-color-scales.cpp:458 +#: ../../po/../src/widgets/sp-color-scales.cpp:459 +msgid "Yellow" +msgstr "Jaune" + +# BlacK (in CYMK) +#: ../../po/../src/widgets/sp-color-scales.cpp:460 +msgid "_K" +msgstr "N (_k)" + +#: ../../po/../src/widgets/sp-color-selector.cpp:71 +msgid "Unnamed" +msgstr "Sans nom" + +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:68 +msgid "Wheel" +msgstr "Roue" + +#: ../../po/../src/widgets/sp-xmlview-attr-list.cpp:53 +msgid "Attribute" +msgstr "Attribut" + +#: ../../po/../src/widgets/sp-xmlview-attr-list.cpp:54 +msgid "Value" +msgstr "Valeur" + +#: ../../po/../src/widgets/toolbox.cpp:424 +msgid "Insert new nodes into selected segments" +msgstr "Insérer de nouveaux nœuds aux milieux des segments sélectionnés" + +#: ../../po/../src/widgets/toolbox.cpp:426 +msgid "Delete selected nodes" +msgstr "Supprimer les nœuds sélectionnés" + +#: ../../po/../src/widgets/toolbox.cpp:431 +msgid "Join paths at selected nodes" +msgstr "Joindre les chemins aux nœuds sélectionnés" + +#: ../../po/../src/widgets/toolbox.cpp:433 +msgid "Join paths at selected nodes with new segment" +msgstr "Joindre les chemins aux nœuds sélectionnés par un nouveau segment" + +#: ../../po/../src/widgets/toolbox.cpp:436 +msgid "Split path between two non-endpoint nodes" +msgstr "Supprimer un segment entre deux nœuds non terminaux" + +#: ../../po/../src/widgets/toolbox.cpp:439 +msgid "Break path at selected nodes" +msgstr "Briser le chemin aux nœuds sélectionnés" + +#: ../../po/../src/widgets/toolbox.cpp:444 +msgid "Make selected nodes corner" +msgstr "Rendre durs les nœuds sélectionnés" + +#: ../../po/../src/widgets/toolbox.cpp:447 +msgid "Make selected nodes smooth" +msgstr "Rendre doux les nœuds sélectionnés" + +#: ../../po/../src/widgets/toolbox.cpp:450 +msgid "Make selected nodes symmetric" +msgstr "Rendre symétriques les nœuds sélectionnés" + +#: ../../po/../src/widgets/toolbox.cpp:455 +msgid "Make selected segments lines" +msgstr "Rendre rectilignes les segments sélectionnés" + +#: ../../po/../src/widgets/toolbox.cpp:458 +msgid "Make selected segments curves" +msgstr "Rendre courbes les segments sélectionnés" + +#: ../../po/../src/widgets/toolbox.cpp:1199 +msgid "Polygon" +msgstr "Polygone" + +#: ../../po/../src/widgets/toolbox.cpp:1206 +msgid "Regular polygon (with one handle) instead of a star" +msgstr "Polygone régulier (avec une poignée) au lieu d'une étoile" + +#: ../../po/../src/widgets/toolbox.cpp:1218 +msgid "Corners:" +msgstr "Sommets :" + +#: ../../po/../src/widgets/toolbox.cpp:1218 +msgid "Number of corners of a polygon or star" +msgstr "Nombre de sommets du polygone ou de l'étoile" + +#: ../../po/../src/widgets/toolbox.cpp:1228 +msgid "Spoke ratio:" +msgstr "Ratio des rayons :" + +#. TRANSLATORS: Tip radius of a star is the distance from the center to the farthest handle. +#. Base radius is the same for the closest handle. +#: ../../po/../src/widgets/toolbox.cpp:1231 +msgid "Base radius to tip radius ratio" +msgstr "Rapport du rayon intérieur sur le rayon extérieur" + +#: ../../po/../src/widgets/toolbox.cpp:1246 +msgid "Rounded:" +msgstr "Arrondi :" + +#: ../../po/../src/widgets/toolbox.cpp:1246 +msgid "How much rounded are the corners (0 for sharp)" +msgstr "Quantité d'arrondi des sommets (0 pour pointu)" + +#: ../../po/../src/widgets/toolbox.cpp:1256 +msgid "Randomized:" +msgstr "Hasard :" + +#: ../../po/../src/widgets/toolbox.cpp:1256 +msgid "Scatter randomly the corners and angles" +msgstr "Disperser aléatoirement les sommets et les angles" + +#: ../../po/../src/widgets/toolbox.cpp:1269 +#: ../../po/../src/widgets/toolbox.cpp:1838 +#: ../../po/../src/widgets/toolbox.cpp:2061 +msgid "Defaults" +msgstr "RAZ" + +#: ../../po/../src/widgets/toolbox.cpp:1270 +#: ../../po/../src/widgets/toolbox.cpp:1839 +#: ../../po/../src/widgets/toolbox.cpp:2062 +msgid "" +"Reset shape parameters to defaults (use Inkscape Preferences > Tools to " +"change defaults)" +msgstr "" +"Restaurer les préférences de la forme par défaut (changez les valeurs par " +"défaut dans Inkscape Préférences > Outils)" + +#: ../../po/../src/widgets/toolbox.cpp:1544 +msgid "W:" +msgstr "L :" + +#: ../../po/../src/widgets/toolbox.cpp:1544 +msgid "Width of rectangle" +msgstr "Largeur du rectangle" + +#: ../../po/../src/widgets/toolbox.cpp:1556 +msgid "Height of rectangle" +msgstr "Hauteur du rectangle" + +#: ../../po/../src/widgets/toolbox.cpp:1568 +msgid "Rx:" +msgstr "Rx :" + +#: ../../po/../src/widgets/toolbox.cpp:1568 +msgid "Horizontal radius of rounded corners" +msgstr "Rayon horizontal des coins arrondis" + +#: ../../po/../src/widgets/toolbox.cpp:1578 +msgid "Ry:" +msgstr "Ry :" + +#: ../../po/../src/widgets/toolbox.cpp:1578 +msgid "Vertical radius of rounded corners" +msgstr "Rayon vertical des coins arrondis" + +#: ../../po/../src/widgets/toolbox.cpp:1594 +msgid "Not rounded" +msgstr "Pas d'arrondi" + +#: ../../po/../src/widgets/toolbox.cpp:1596 +msgid "Make corners sharp" +msgstr "Rendre les coins pointus" + +#: ../../po/../src/widgets/toolbox.cpp:1805 +msgid "Turns:" +msgstr "Tours :" + +#: ../../po/../src/widgets/toolbox.cpp:1805 +msgid "Number of revolutions" +msgstr "Nombre de révolutions" + +#: ../../po/../src/widgets/toolbox.cpp:1815 +msgid "Divergence:" +msgstr "Divergence :" + +#: ../../po/../src/widgets/toolbox.cpp:1815 +msgid "How much denser/sparser are outer revolutions; 1 = uniform" +msgstr "Densité de la révolution; 1 = uniforme" + +#: ../../po/../src/widgets/toolbox.cpp:1825 +msgid "Inner radius:" +msgstr "Rayon intérieur :" + +#: ../../po/../src/widgets/toolbox.cpp:1825 +msgid "Radius of the innermost revolution (relative to the spiral size)" +msgstr "Rayon de la révolution intérieure (relatif à la taille de la spirale)" + +#: ../../po/../src/widgets/toolbox.cpp:1957 +msgid "The width of the calligraphic pen (relative to the visible canvas area)" +msgstr "" +"Largeur de la plume calligraphique (relativement à l'aire de travail visible)" + +#: ../../po/../src/widgets/toolbox.cpp:1967 +msgid "Thinning:" +msgstr "Mincissement :" + +#: ../../po/../src/widgets/toolbox.cpp:1967 +msgid "" +"How much velocity thins the stroke (> 0 makes fast strokes thinner, < 0 " +"makes them broader, 0 makes width independent of velocity)" +msgstr "" +"Largeur du tracé en fonction de la vélocité. (>0 la vitesse du tracé diminue " +"sa largeur, <0 l'augmente, 0 ne l'influence pas)" + +#: ../../po/../src/widgets/toolbox.cpp:1980 +msgid "Angle:" +msgstr "Angle :" + +#: ../../po/../src/widgets/toolbox.cpp:1980 +msgid "" +"The angle of the pen's nib (in degrees; 0 = horizontal; has no effect if " +"fixation = 0)" +msgstr "" +"Angle de la plume calligraphique (en degrés; 0 = horizontal; n'a pas d'effet " +"si orientation = 0)" + +#: ../../po/../src/widgets/toolbox.cpp:1990 +msgid "Fixation:" +msgstr "Fixité :" + +#: ../../po/../src/widgets/toolbox.cpp:1990 +msgid "" +"How fixed is the pen angle (0 = always perpendicular to stroke direction, 1 " +"= fixed)" +msgstr "" +"Variation ou non de l'angle de la plume calligraphique par rapport au tracé " +"(0 = toujours perpendiculaire à la direction du tracé, 1 = invariant)" + +#: ../../po/../src/widgets/toolbox.cpp:2003 +msgid "Mass:" +msgstr "Masse :" + +#: ../../po/../src/widgets/toolbox.cpp:2003 +msgid "How much inertia affects the movement of the pen" +msgstr "Inertie affectant les mouvements de la plume calligraphique" + +#. TRANSLATORS: "drag" means "resistance" here +#: ../../po/../src/widgets/toolbox.cpp:2014 +msgid "Drag:" +msgstr "Frottement :" + +#: ../../po/../src/widgets/toolbox.cpp:2014 +msgid "How much resistance affects the movement of the pen" +msgstr "" +"Résistance affectant les mouvements de la plume calligraphique sur le papier" + +#: ../../po/../src/widgets/toolbox.cpp:2034 +msgid "Use the pressure of the input device to alter the width of the pen" +msgstr "" +"Utiliser la pression du périphérique d'entrée pour modifier la largeur du " +"stylo" + +#: ../../po/../src/widgets/toolbox.cpp:2047 +msgid "Use the tilt of the input device to alter the angle of the pen's nib" +msgstr "" +"Utiliser l'inclinaison du périphérique d'entrée pour modifier l'angle de la " +"plume" + +#: ../../po/../src/widgets/toolbox.cpp:2374 +msgid "Start:" +msgstr "Début :" + +#: ../../po/../src/widgets/toolbox.cpp:2374 +msgid "The angle (in degrees) from the horizontal to the arc's start point" +msgstr "Angle (en degrés) entre l'horizontale et le début de l'arc" + +#: ../../po/../src/widgets/toolbox.cpp:2384 +msgid "End:" +msgstr "Fin :" + +#: ../../po/../src/widgets/toolbox.cpp:2384 +msgid "The angle (in degrees) from the horizontal to the arc's end point" +msgstr "Angle (en degrés) entre l'horizontale et la fin de l'arc" + +#: ../../po/../src/widgets/toolbox.cpp:2395 +msgid "Open arc" +msgstr "Arc ouvert" + +#: ../../po/../src/widgets/toolbox.cpp:2396 +msgid "" +"Switch between arc (unclosed shape) and segment (closed shape with two radii)" +msgstr "" +"Choisir entre un arc (une forme non fermée) et un camembert (une forme " +"fermée avec ses deux rayons)" + +#: ../../po/../src/widgets/toolbox.cpp:2415 +msgid "Make whole" +msgstr "Refermer" + +#: ../../po/../src/widgets/toolbox.cpp:2417 +msgid "Make the shape a whole ellipse, not arc or segment" +msgstr "Fermer l'ellipse, ne pas obtenir un arc ou un camembert" + +#: ../../po/../src/widgets/toolbox.cpp:2644 +msgid "" +"When pressed, picks visible color without alpha and when not pressed, picks " +"color including its alpha" +msgstr "" +"Enfoncer ce bouton pour que la couleur visible soit capturée sans alpha; " +"sinon, la couleur est capturée avec alpha" + +#: ../../po/../src/widgets/toolbox.cpp:3039 +msgid "Make connectors avoid selected objects" +msgstr "Faire que les connecteurs évitent les objets sélectionnés" + +#: ../../po/../src/widgets/toolbox.cpp:3043 +msgid "Make connectors ignore selected objects" +msgstr "Faire que les connecteurs ignorent les objets sélectionnés" + +#. +#. 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 : +#: ../share/extensions/addnodes.inx.h:1 +#, fuzzy +msgid "Add Nodes" +msgstr "Nœuds" + +#: ../share/extensions/addnodes.inx.h:2 +msgid "Maximum Segment Length" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:1 +msgid "AI Input" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:2 ../share/extensions/ai_output.inx.h:2 +msgid "Adobe Illustrator (*.ai)" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:3 +msgid "Open files saved with Adobe Illustrator" +msgstr "" + +#: ../share/extensions/ai_output.inx.h:1 +#, fuzzy +msgid "AI Output" +msgstr "Résultat" + +#: ../share/extensions/ai_output.inx.h:3 +msgid "Write Adobe Illustrator" +msgstr "" + +#: ../share/extensions/dia.inx.h:1 +msgid "A diagram created with the program Dia" +msgstr "" + +#: ../share/extensions/dia.inx.h:2 +msgid "Dia Diagram (*.dia)" +msgstr "" + +#: ../share/extensions/dia.inx.h:3 +msgid "Dia Input" +msgstr "" + +#: ../share/extensions/dia.inx.h:4 +msgid "" +"In order to import Dia files, Dia itself must be installed. You can get Dia " +"at http://www.gnome.org/projects/dia/" +msgstr "" + +#: ../share/extensions/dia.inx.h:5 +msgid "" +"The dia2svg.sh script should be installed with your Inkscape distribution. " +"If you do not have it, there is likely to be something wrong with your " +"Inkscape installation." +msgstr "" + +#: ../share/extensions/dots.inx.h:1 +#, fuzzy +msgid "Connect the Dots" +msgstr "Connecteur" + +#: ../share/extensions/dots.inx.h:2 +#, fuzzy +msgid "Dot Size" +msgstr "Taille" + +#: ../share/extensions/dots.inx.h:3 +#, fuzzy +msgid "Font Size" +msgstr "Taille de police :" + +#: ../share/extensions/dropshadow.inx.h:1 +msgid "Color of shadow" +msgstr "" + +#: ../share/extensions/dropshadow.inx.h:2 +#, fuzzy +msgid "Dropshadow" +msgstr "Afficher une ombre de la page" + +#: ../share/extensions/dxf_input.inx.h:1 +#: ../share/extensions/dxf_output.inx.h:1 +msgid "AutoCAD DXF (*.dxf)" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:2 +msgid "DXF Input" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:3 +msgid "Import AutoCAD's Document Exchange Format" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:4 +msgid "" +"dxf2svg may come with Inkscape, but is also at http://dxf-svg-convert." +"sourceforge.net/" +msgstr "" + +#: ../share/extensions/dxf_output.inx.h:2 +#, fuzzy +msgid "DXF Output" +msgstr "Résultat" + +#: ../share/extensions/dxf_output.inx.h:3 +msgid "DXF file written by pstoedit" +msgstr "" + +#: ../share/extensions/dxf_output.inx.h:4 +msgid "pstoedit must be installed to run see http://www.pstoedit.net/pstoedit" +msgstr "" + +#: ../share/extensions/embedimage.inx.h:1 +#, fuzzy +msgid "Embed Images" +msgstr "Images" + +#: ../share/extensions/eps_input.inx.h:1 +msgid "EPS Input" +msgstr "" + +#: ../share/extensions/eps_input.inx.h:2 +msgid "Encapsulated Postscript" +msgstr "" + +#: ../share/extensions/eps_input.inx.h:3 +msgid "Encapsulated Postscript (*.eps)" +msgstr "" + +#: ../share/extensions/epsi_output.inx.h:1 +#, fuzzy +msgid "EPSI Output" +msgstr "Résultat" + +#: ../share/extensions/epsi_output.inx.h:2 +msgid "Encapsulated Postscript Interchange (*.epsi)" +msgstr "" + +#: ../share/extensions/epsi_output.inx.h:3 +msgid "Encapsulated Postscript with a thumbnail" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:1 ../share/extensions/ffms.inx.h:1 +#: ../share/extensions/ffset.inx.h:1 ../share/extensions/ffss.inx.h:1 +#, fuzzy +msgid "Bridge Width" +msgstr "Largeur de ligne" + +#: ../share/extensions/ffmet.inx.h:2 ../share/extensions/ffms.inx.h:2 +msgid "First String Length" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:3 +msgid "FretFind Multi Length ET" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:4 ../share/extensions/ffms.inx.h:4 +#: ../share/extensions/ffset.inx.h:3 ../share/extensions/ffss.inx.h:3 +msgid "Fretboard Edges" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:5 ../share/extensions/ffms.inx.h:5 +msgid "Last String Length" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:6 ../share/extensions/ffms.inx.h:6 +#: ../share/extensions/ffset.inx.h:4 ../share/extensions/ffss.inx.h:4 +#, fuzzy +msgid "Number of Frets" +msgstr "Nombre de lignes" + +#: ../share/extensions/ffmet.inx.h:7 ../share/extensions/ffms.inx.h:7 +#: ../share/extensions/ffset.inx.h:5 ../share/extensions/ffss.inx.h:5 +#, fuzzy +msgid "Number of Strings" +msgstr "Nombre de lignes" + +#: ../share/extensions/ffmet.inx.h:8 ../share/extensions/ffms.inx.h:8 +#: ../share/extensions/ffset.inx.h:6 ../share/extensions/ffss.inx.h:6 +#, fuzzy +msgid "Nut Width" +msgstr "Largeur" + +#: ../share/extensions/ffmet.inx.h:9 ../share/extensions/ffms.inx.h:10 +msgid "Perpendicular Distance" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:10 ../share/extensions/ffset.inx.h:7 +msgid "Scale Base (2 for Octave)" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:11 ../share/extensions/ffset.inx.h:9 +msgid "Tones in Scale" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:12 ../share/extensions/ffms.inx.h:12 +#: ../share/extensions/ffset.inx.h:10 ../share/extensions/ffss.inx.h:10 +msgid "px per Unit" +msgstr "" + +#: ../share/extensions/ffms.inx.h:3 +msgid "FretFind Multi Length Scala" +msgstr "" + +#: ../share/extensions/ffms.inx.h:9 ../share/extensions/ffss.inx.h:7 +msgid "Path to Scala *.scl File" +msgstr "" + +#: ../share/extensions/ffms.inx.h:11 +msgid "Tuning (scale step for each string seperated by semicolons)" +msgstr "" + +#: ../share/extensions/ffset.inx.h:2 +msgid "FretFind Single Length ET" +msgstr "" + +#: ../share/extensions/ffset.inx.h:8 ../share/extensions/ffss.inx.h:8 +msgid "Scale Length" +msgstr "" + +#: ../share/extensions/ffss.inx.h:2 +msgid "FretFind Single Length Scala" +msgstr "" + +#: ../share/extensions/ffss.inx.h:9 +msgid "Tuning (Scale step for each string seperated by semicolons)" +msgstr "" + +#: ../share/extensions/handles.inx.h:1 +#, fuzzy +msgid "Draw Handles" +msgstr "Dessiner des lignes à main levée" + +#: ../share/extensions/interp.inx.h:1 +#, fuzzy +msgid "Duplicate Endpaths" +msgstr "Dupliquer le nœud" + +#: ../share/extensions/interp.inx.h:2 +#, fuzzy +msgid "Exponent" +msgstr "Exporter" + +#: ../share/extensions/interp.inx.h:3 +msgid "Interpolate" +msgstr "" + +#: ../share/extensions/interp.inx.h:4 +msgid "Interpolate Style (Experimental)" +msgstr "" + +#: ../share/extensions/interp.inx.h:5 +msgid "Interpolation Method" +msgstr "" + +#: ../share/extensions/interp.inx.h:6 +msgid "Interpolation Steps" +msgstr "" + +#: ../share/extensions/kochify.inx.h:1 +msgid "Kochify" +msgstr "" + +#: ../share/extensions/kochify_load.inx.h:1 +msgid "Kochify (Load)" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:1 +#, fuzzy +msgid "Angle" +msgstr "Angle :" + +#: ../share/extensions/lindenmayer.inx.h:2 +msgid "Axiom" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:3 +#, fuzzy +msgid "Lindenmayer" +msgstr "Renommer le calque" + +#: ../share/extensions/lindenmayer.inx.h:4 +msgid "Order" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:5 +#, fuzzy +msgid "Rules" +msgstr "_Règles" + +#: ../share/extensions/lindenmayer.inx.h:6 +#, fuzzy +msgid "Step" +msgstr "Incréments" + +#: ../share/extensions/motion.inx.h:1 +#, fuzzy +msgid "Direction" +msgstr "Description" + +#: ../share/extensions/motion.inx.h:2 +#, fuzzy +msgid "Magnitude" +msgstr "Magenta" + +#: ../share/extensions/motion.inx.h:3 +#, fuzzy +msgid "Motion" +msgstr "_Rotation" + +#: ../share/extensions/pdf_output.inx.h:1 +msgid "Adobe PDF (*.pdf)" +msgstr "" + +#: ../share/extensions/pdf_output.inx.h:2 +msgid "Adobe Portable Document Format" +msgstr "" + +#: ../share/extensions/pdf_output.inx.h:3 +#, fuzzy +msgid "PDF Output" +msgstr "Résultat" + +#: ../share/extensions/ps_input.inx.h:1 +#, fuzzy +msgid "Postscript" +msgstr "Portrait" + +#: ../share/extensions/ps_input.inx.h:2 +msgid "Postscript (*.ps)" +msgstr "" + +#: ../share/extensions/ps_input.inx.h:3 +msgid "Postscript Input" +msgstr "" + +#: ../share/extensions/radiusrand.inx.h:1 +#, fuzzy +msgid "Radius" +msgstr "Monte_r" + +#: ../share/extensions/radiusrand.inx.h:2 +#, fuzzy +msgid "Radius Randomize" +msgstr "Hasard :" + +#: ../share/extensions/radiusrand.inx.h:3 +msgid "Randomize Control Points" +msgstr "" + +#: ../share/extensions/radiusrand.inx.h:4 +#, fuzzy +msgid "Randomize Nodes" +msgstr "Hasard :" + +#: ../share/extensions/rtree.inx.h:1 +#, fuzzy +msgid "Initial Size" +msgstr "Taille du bitmap" + +#: ../share/extensions/rtree.inx.h:2 +msgid "Minimum Size" +msgstr "" + +#: ../share/extensions/rtree.inx.h:3 +#, fuzzy +msgid "Random Tree" +msgstr "Hasard :" + +#: ../share/extensions/sk_input.inx.h:1 +msgid "A diagram created with the program Sketch" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:2 +msgid "Sketch Diagram (*.sk)" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:3 +msgid "Sketch Input" +msgstr "" + +#: ../share/extensions/straightseg.inx.h:1 +msgid "Behavior" +msgstr "" + +#: ../share/extensions/straightseg.inx.h:3 +msgid "Segment Straightener" +msgstr "" + +#: ../share/extensions/summersnight.inx.h:1 +msgid "Summer's Night" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:1 +#: ../share/extensions/svgz_output.inx.h:1 +msgid "Compressed Inkscape SVG (*.svgz)" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:2 +#: ../share/extensions/svgz_output.inx.h:2 +msgid "Inkscape's native file format compressed with GZip" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:3 +msgid "SVGZ Input" +msgstr "" + +#: ../share/extensions/svgz_output.inx.h:3 +#, fuzzy +msgid "SVGZ Output" +msgstr "Résultat" + +#: ../share/extensions/txt2svg.inx.h:1 +msgid "ASCII Text" +msgstr "" + +#: ../share/extensions/txt2svg.inx.h:2 +msgid "Text File (*.txt)" +msgstr "" + +#: ../share/extensions/txt2svg.inx.h:3 +msgid "Text Input" +msgstr "" + +#: ../share/extensions/wavy.inx.h:1 +msgid "Calculate first derivative numerically" +msgstr "" + +#: ../share/extensions/wavy.inx.h:2 +msgid "First derivative" +msgstr "" + +#: ../share/extensions/wavy.inx.h:3 +msgid "Function" +msgstr "" + +#: ../share/extensions/wavy.inx.h:4 +msgid "Function Plotter" +msgstr "" + +#: ../share/extensions/wavy.inx.h:5 +msgid "Nodes per period" +msgstr "" + +#: ../share/extensions/wavy.inx.h:6 +msgid "Periods (2*Pi each)" +msgstr "" + +#: ../share/extensions/whirl.inx.h:1 +msgid "Amount of Whirl" +msgstr "" + +#: ../share/extensions/whirl.inx.h:2 +#, fuzzy +msgid "Center X" +msgstr "Centrer les lignes" + +#: ../share/extensions/whirl.inx.h:3 +#, fuzzy +msgid "Center Y" +msgstr "Centrer les lignes" + +#: ../share/extensions/whirl.inx.h:4 +#, fuzzy +msgid "Direction of Rotation" +msgstr "Décliner l'invitation" + +#: ../share/extensions/whirl.inx.h:5 +msgid "Whirl" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:1 +msgid "A popular graphics file format for clipart" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:2 +msgid "Windows Metafile (*.wmf)" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:3 +msgid "Windows Metafile Input" +msgstr "" + +#~ msgid "Custom canvas" +#~ msgstr "Canevas personnalisé" + +#~ msgid "Current style" +#~ msgstr "Style courant" + +#~ msgid "" +#~ "Current style is updated every time you change the style of any object " +#~ "(its fill, stroke, transparency, etc.)" +#~ msgstr "" +#~ "Le style courant est mis à jour chaque fois que le style d'un objet est " +#~ "changé (remplissage, contour, transparence, etc.)" + +#~ msgid "Arrange Objects" +#~ msgstr "Organiser des objets" + +#~ msgid "deg" +#~ msgstr "deg" + +#~ msgid "" +#~ "%s is not a valid preferences file.\n" +#~ "%s" +#~ msgstr "" +#~ "%s n'est pas un fichier de préférences valide.\n" +#~ "%s" + +#~ msgid "" +#~ "Inkscape will run with default settings.\n" +#~ "New settings will not be saved." +#~ msgstr "" +#~ "Inkscape va démarrer avec les préférences par défaut.\n" +#~ "Les nouvelles préférences ne seront pas enregistrées." + +#~ msgid "_Credits" +#~ msgstr "_Crédits" + +#~ msgid "Grab sensitivity" +#~ msgstr "Sensibilité" + +#~ msgid "Click/drag threshold" +#~ msgstr "Seuil de cliquer-déplacer" + +#~ msgid "Mouse wheel scrolls by" +#~ msgstr "La molette de la souris défile de" + +#~ msgid "Scroll by" +#~ msgstr "Défiler de" + +#~ msgid "Acceleration" +#~ msgstr "Accélération" + +#~ msgid "Speed" +#~ msgstr "Vitesse" + +#~ msgid "Threshold" +#~ msgstr "Seuil" + +#~ msgid "Arrow keys move by" +#~ msgstr "Les flèches déplacent de" + +#~ msgid "> and < scale by" +#~ msgstr "> et < redimensionnent de" + +#~ msgid "Inset/Outset by" +#~ msgstr "Éroder/dilater de" + +#~ msgid "Rotation snaps every" +#~ msgstr "Incrément de rotation" + +#~ msgid "Zoom in/out by" +#~ msgstr "(Dé)Zoommer de" + +#~ msgid "Transform" +#~ msgstr "Transformer" + +#~ msgid "Flip selection horizontally" +#~ msgstr "Retourner les objets sélectionnés horizontalement" + +#~ msgid "Flip selection vertically" +#~ msgstr "Retourner les objets sélectionnés verticalement" + +#~ msgid "" +#~ "0 out of %i node selected. Click, Shift+click, or drag around nodes to select.0 out of %i nodes " +#~ "selected. Click, Shift+click, or drag around nodes " +#~ "to select." +#~ msgstr "" +#~ "0 nœud sélectionné sur %i. Cliquer, Maj+cliquer, ou cliquer-déplacer sur/autour des nœuds pour en " +#~ "sélectionner0 nœud sélectionné sur %i. Cliquer, " +#~ "Maj+cliquer, ou cliquer-déplacer sur/autour des nœuds pour " +#~ "en sélectionner" + +#, fuzzy +#~ msgid "Could not read next message due to I/O error (error: %s)!" +#~ msgstr "Impossible de créer le fichier d'erreur de l'extension : '%s'" + +#~ msgid "Open one of the recently visited documents" +#~ msgstr "Ouvrir un des documents récemment ouverts" + +#~ msgid "" +#~ "Show or hide parts of the document window (differently for normal and " +#~ "fullscreen modes)" +#~ msgstr "" +#~ "Afficher ou non des parties de la fenêtre du document (différent pour les " +#~ "modes normal et plein écran)" + +#~ msgid "Interactive Inkscape tutorials" +#~ msgstr "Didacticiels interactifs d'Inkscape" + +#~ msgid "Modifying or Redistributing Inkscape" +#~ msgstr "Modification ou redistribution du logiciel" + +#~ msgid "Show license to modify and/or redistribute Inkscape: GNU GPL" +#~ msgstr "" +#~ "Afficher la license de modification et/ou redistribution d'Inkscape: GNU " +#~ "GPL" diff --git a/po/ga.po b/po/ga.po new file mode 100644 index 000000000..9d4bbb61c --- /dev/null +++ b/po/ga.po @@ -0,0 +1,10146 @@ +# Irish language translation of sodipodi +# Copyright (C) 2000 Free Software Foundation, Inc. +# Alastair McKinstry , 2000. +# +msgid "" +msgstr "" +"Project-Id-Version: sodipodi 0.24\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2005-12-04 11:51-0800\n" +"PO-Revision-Date: 2000-08-24 20:00-0000\n" +"Last-Translator: Alastair McKinstry \n" +"Language-Team: Irish \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8-bit\n" + +#: ../inkscape.desktop.in.h:1 +msgid "Create and edit Scalable Vector Graphics images" +msgstr "" + +#: ../inkscape.desktop.in.h:2 +msgid "Inkscape SVG Vector Illustrator" +msgstr "" + +#: ../../po/../src/arc-context.cpp:350 +msgid "" +"Ctrl: make circle or integer-ratio ellipse, snap arc/segment angle" +msgstr "" + +#: ../../po/../src/arc-context.cpp:351 ../../po/../src/rect-context.cpp:388 +msgid "Shift: draw around the starting point" +msgstr "" + +#: ../../po/../src/arc-context.cpp:413 +#: ../../po/../src/connector-context.cpp:493 +#: ../../po/../src/dyna-draw-context.cpp:506 +#: ../../po/../src/pen-context.cpp:329 ../../po/../src/pencil-context.cpp:208 +#: ../../po/../src/rect-context.cpp:452 ../../po/../src/spiral-context.cpp:421 +#: ../../po/../src/star-context.cpp:427 +msgid "Current layer is hidden. Unhide it to be able to draw on it." +msgstr "" + +#: ../../po/../src/arc-context.cpp:417 +#: ../../po/../src/connector-context.cpp:497 +#: ../../po/../src/dyna-draw-context.cpp:510 +#: ../../po/../src/pen-context.cpp:336 ../../po/../src/pencil-context.cpp:212 +#: ../../po/../src/rect-context.cpp:456 ../../po/../src/spiral-context.cpp:426 +#: ../../po/../src/star-context.cpp:431 +msgid "Current layer is locked. Unlock it to be able to draw on it." +msgstr "" + +#: ../../po/../src/arc-context.cpp:496 +#, c-format +msgid "" +"Ellipse: %s × %s; with Ctrl to make circle or integer-" +"ratio ellipse; with Shift to draw around the starting point" +msgstr "" + +#: ../../po/../src/connector-context.cpp:518 +#, fuzzy +msgid "Creating new connector" +msgstr "Sábháil Comhad" + +#: ../../po/../src/connector-context.cpp:939 +msgid "Finishing connector" +msgstr "" + +#: ../../po/../src/connector-context.cpp:1108 +msgid "Connection point: click or drag to create a new connector" +msgstr "" + +#: ../../po/../src/connector-context.cpp:1185 +msgid "Connector endpoint: drag to reroute or connect to new shapes" +msgstr "" + +#: ../../po/../src/connector-context.cpp:1278 +#, fuzzy +msgid "Select at least one non-connector object." +msgstr "Tóg" + +#: ../../po/../src/desktop-events.cpp:238 +#, c-format +msgid "%s at %s" +msgstr "" + +#. TRANSLATORS: This string appears when double-clicking on a guide. +#. This is the distance by which the guide is to be moved. +#: ../../po/../src/desktop-events.cpp:277 +#, fuzzy +msgid " relative by " +msgstr "Greamaigh" + +#. TRANSLATORS: This string appears when double-clicking on a guide. +#. This is the target location where the guide is to be moved. +#: ../../po/../src/desktop-events.cpp:282 +#: ../../po/../src/desktop-events.cpp:395 +#, fuzzy +msgid " absolute to " +msgstr "Greamaigh" + +#. create dialog +#: ../../po/../src/desktop-events.cpp:348 +msgid "Guideline" +msgstr "" + +#: ../../po/../src/desktop-events.cpp:432 +#, fuzzy, c-format +msgid "Move %s" +msgstr "Nód" + +#: ../../po/../src/desktop.cpp:678 +msgid "No previous zoom." +msgstr "" + +#: ../../po/../src/desktop.cpp:703 +msgid "No next zoom." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:182 +#, fuzzy +msgid "Nothing selected." +msgstr "Priontáil comhad" + +#: ../../po/../src/dialogs/clonetiler.cpp:188 +msgid "More than one object selected." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:195 +#, c-format +msgid "Object has %d tiled clones." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:200 +msgid "Object has no tiled clones." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:865 +#, fuzzy +msgid "Select one object whose tiled clones to unclump." +msgstr "Tóg" + +#: ../../po/../src/dialogs/clonetiler.cpp:916 +#, fuzzy +msgid "Select one object whose tiled clones to remove." +msgstr "Tóg" + +#: ../../po/../src/dialogs/clonetiler.cpp:984 +#: ../../po/../src/selection-chemistry.cpp:1774 +#, fuzzy +msgid "Select an object to clone." +msgstr "Tóg" + +#: ../../po/../src/dialogs/clonetiler.cpp:990 +#: ../../po/../src/selection-chemistry.cpp:1780 +msgid "" +"If you want to clone several objects, group them and clone the " +"group." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1484 +msgid "Per row:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1497 +#, fuzzy +msgid "Per column:" +msgstr "Priontáil comhad" + +#: ../../po/../src/dialogs/clonetiler.cpp:1505 +#, fuzzy +msgid "Randomize:" +msgstr "Priontáil comhad" + +#: ../../po/../src/dialogs/clonetiler.cpp:1656 +msgid "_Symmetry" +msgstr "" + +#. TRANSLATORS: For the following 17 symmetry groups, see +#. * http://www.bib.ulb.ac.be/coursmath/doc/17.htm (visual examples); +#. * http://www.clarku.edu/~djoyce/wallpaper/seventeen.html (English vocabulary); or +#. * http://membres.lycos.fr/villemingerard/Geometri/Sym1D.htm (French vocabulary). +#. +#: ../../po/../src/dialogs/clonetiler.cpp:1664 +msgid "Select one of the 17 symmetry groups for the tiling" +msgstr "" + +#. TRANSLATORS: "translation" means "shift" / "displacement" here. +#: ../../po/../src/dialogs/clonetiler.cpp:1675 +msgid "P1: simple translation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1676 +msgid "P2: 180° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1677 +msgid "PM: reflection" +msgstr "" + +#. TRANSLATORS: "glide reflection" is a reflection and a translation combined. +#. For more info, see http://mathforum.org/sum95/suzanne/symsusan.html +#: ../../po/../src/dialogs/clonetiler.cpp:1680 +msgid "PG: glide reflection" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1681 +msgid "CM: reflection + glide reflection" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1682 +msgid "PMM: reflection + reflection" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1683 +msgid "PMG: reflection + 180° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1684 +msgid "PGG: glide reflection + 180° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1685 +msgid "CMM: reflection + reflection + 180° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1686 +msgid "P4: 90° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1687 +msgid "P4M: 90° rotation + 45° reflection" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1688 +msgid "P4G: 90° rotation + 90° reflection" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1689 +msgid "P3: 120° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1690 +msgid "P31M: reflection + 120° rotation, dense" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1691 +msgid "P3M1: reflection + 120° rotation, sparse" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1692 +msgid "P6: 60° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1693 +msgid "P6M: reflection + 60° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1721 +msgid "S_hift" +msgstr "" + +#. TRANSLATORS: "shift" means: the tiles will be shifted (offset) horizontally by this amount +#: ../../po/../src/dialogs/clonetiler.cpp:1731 +#, no-c-format +msgid "Shift X:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1739 +#, no-c-format +msgid "Horizontal shift per row (in % of tile width)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1747 +#, no-c-format +msgid "Horizontal shift per column (in % of tile width)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1754 +msgid "Randomize the horizontal shift by this percentage" +msgstr "" + +#. TRANSLATORS: "shift" means: the tiles will be shifted (offset) vertically by this amount +#: ../../po/../src/dialogs/clonetiler.cpp:1764 +#, no-c-format +msgid "Shift Y:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1772 +#, no-c-format +msgid "Vertical shift per row (in % of tile height)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1780 +#, no-c-format +msgid "Vertical shift per column (in % of tile height)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1787 +msgid "Randomize the vertical shift by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1795 +msgid "Exponent:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1802 +msgid "Whether rows are spaced evenly (1), converge (<1) or diverge (>1)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1809 +msgid "Whether columns are spaced evenly (1), converge (<1) or diverge (>1)" +msgstr "" + +#. TRANSLATORS: "Alternate" is a verb here +#: ../../po/../src/dialogs/clonetiler.cpp:1817 +#: ../../po/../src/dialogs/clonetiler.cpp:1907 +#: ../../po/../src/dialogs/clonetiler.cpp:1966 +#: ../../po/../src/dialogs/clonetiler.cpp:2022 +#: ../../po/../src/dialogs/clonetiler.cpp:2153 +msgid "Alternate:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1823 +msgid "Alternate the sign of shifts for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1828 +msgid "Alternate the sign of shifts for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1837 +msgid "Sc_ale" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1845 +#, fuzzy +msgid "Scale X:" +msgstr "Priontáil" + +#: ../../po/../src/dialogs/clonetiler.cpp:1853 +#, no-c-format +msgid "Horizontal scale per row (in % of tile width)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1861 +#, no-c-format +msgid "Horizontal scale per column (in % of tile width)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1868 +msgid "Randomize the horizontal scale by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1876 +#, fuzzy +msgid "Scale Y:" +msgstr "Priontáil" + +#: ../../po/../src/dialogs/clonetiler.cpp:1884 +#, no-c-format +msgid "Vertical scale per row (in % of tile height)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1892 +#, no-c-format +msgid "Vertical scale per column (in % of tile height)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1899 +msgid "Randomize the vertical scale by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1913 +msgid "Alternate the sign of scales for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1918 +msgid "Alternate the sign of scales for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1927 +#, fuzzy +msgid "_Rotation" +msgstr "Tóg" + +#: ../../po/../src/dialogs/clonetiler.cpp:1935 +#, fuzzy +msgid "Angle:" +msgstr "Priontáil" + +#: ../../po/../src/dialogs/clonetiler.cpp:1943 +#, no-c-format +msgid "Rotate tiles by this angle for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1951 +#, no-c-format +msgid "Rotate tiles by this angle for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1958 +msgid "Randomize the rotation angle by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1972 +msgid "Alternate the rotation direction for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1977 +msgid "Alternate the rotation direction for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1985 +msgid "_Opacity" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1993 +msgid "Fade out:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2000 +msgid "Decrease tile opacity by this percentage for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2007 +msgid "Decrease tile opacity by this percentage for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2014 +msgid "Randomize the tile opacity by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2028 +msgid "Alternate the sign of opacity change for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2033 +msgid "Alternate the sign of opacity change for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2041 +#, fuzzy +msgid "Co_lor" +msgstr "Dath 2" + +#: ../../po/../src/dialogs/clonetiler.cpp:2046 +#, fuzzy +msgid "Initial color: " +msgstr "Dath" + +#: ../../po/../src/dialogs/clonetiler.cpp:2050 +msgid "Initial color of tiled clones" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2050 +msgid "" +"Initial color for clones (works only if the original has unset fill or " +"stroke)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2065 +msgid "H:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2072 +msgid "Change the tile hue by this percentage for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2079 +msgid "Change the tile hue by this percentage for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2086 +msgid "Randomize the tile hue by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2095 +msgid "S:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2102 +msgid "Change the color saturation by this percentage for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2109 +msgid "Change the color saturation by this percentage for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2116 +msgid "Randomize the color saturation by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2124 +msgid "L:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2131 +msgid "Change the color lightness by this percentage for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2138 +msgid "Change the color lightness by this percentage for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2145 +msgid "Randomize the color lightness by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2159 +msgid "Alternate the sign of color changes for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2164 +msgid "Alternate the sign of color changes for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2172 +#, fuzzy +msgid "_Trace" +msgstr "Radharc Nua" + +#: ../../po/../src/dialogs/clonetiler.cpp:2179 +msgid "Trace the drawing under the tiles" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2183 +msgid "" +"For each clone, pick a value from the drawing in that clone's location and " +"apply it to the clone" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2197 +msgid "1. Pick from the drawing:" +msgstr "" + +#. ----Hbox2 +#: ../../po/../src/dialogs/clonetiler.cpp:2208 +#: ../../po/../src/dialogs/clonetiler.cpp:2355 +#: ../../po/../src/ui/dialog/tracedialog.cpp:445 +#, fuzzy +msgid "Color" +msgstr "Dath 2" + +#: ../../po/../src/dialogs/clonetiler.cpp:2209 +msgid "Pick the visible color and opacity" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2216 +#: ../../po/../src/dialogs/clonetiler.cpp:2365 +#: ../share/extensions/dropshadow.inx.h:3 +msgid "Opacity" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2217 +msgid "Pick the total accumulated opacity" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2224 +msgid "R" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2225 +msgid "Pick the Red component of the color" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2232 +msgid "G" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2233 +msgid "Pick the Green component of the color" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2240 +msgid "B" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2241 +msgid "Pick the Blue component of the color" +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2250 +msgid "clonetiler|H" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2251 +msgid "Pick the hue of the color" +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2260 +msgid "clonetiler|S" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2261 +msgid "Pick the saturation of the color" +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2270 +msgid "clonetiler|L" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2271 +msgid "Pick the lightness of the color" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2281 +msgid "2. Tweak the picked value:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2291 +msgid "Gamma-correct:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2296 +msgid "Shift the mid-range of the picked value upwards (>0) or downwards (<0)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2303 +msgid "Randomize:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2308 +msgid "Randomize the picked value by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2315 +#, fuzzy +msgid "Invert:" +msgstr "Priontáil" + +#: ../../po/../src/dialogs/clonetiler.cpp:2319 +msgid "Invert the picked value" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2325 +msgid "3. Apply the value to the clones':" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2335 +#, fuzzy +msgid "Presence" +msgstr "Sodipodi" + +#: ../../po/../src/dialogs/clonetiler.cpp:2338 +msgid "" +"Each clone is created with the probability determined by the picked value in " +"that point" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2345 +msgid "Size" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2348 +msgid "Each clone's size is determined by the picked value in that point" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2358 +msgid "" +"Each clone is painted by the picked color (the original must have unset fill " +"or stroke)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2368 +msgid "Each clone's opacity is determined by the picked value in that point" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2395 +msgid "How many rows in the tiling" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2415 +msgid "How many columns in the tiling" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2445 +msgid "Width of the rectangle to be filled" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2470 +msgid "Height of the rectangle to be filled" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2485 +#, fuzzy +msgid "Rows, columns: " +msgstr "Dath" + +#: ../../po/../src/dialogs/clonetiler.cpp:2486 +msgid "Create the specified number of rows and columns" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2495 +#, fuzzy +msgid "Width, height: " +msgstr "Airde" + +#: ../../po/../src/dialogs/clonetiler.cpp:2496 +msgid "Fill the specified width and height with the tiling" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2512 +msgid "Use saved size and position of the tile" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2515 +msgid "" +"Pretend that the size and position of the tile are the same as the last time " +"you tiled it (if any), instead of using the current size" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2539 +#, fuzzy +msgid " _Create " +msgstr "Priontáil" + +#: ../../po/../src/dialogs/clonetiler.cpp:2541 +msgid "Create and tile the clones of the selection" +msgstr "" + +#. TRANSLATORS: if a group of objects are "clumped" together, then they +#. are unevenly spread in the given amount of space - as shown in the +#. diagrams on the left in the following screenshot: +#. http://www.inkscape.org/screenshots/gallery/inkscape-0.42-CVS-tiles-unclump.png +#. So unclumping is the process of spreading a number of objects out more evenly. +#: ../../po/../src/dialogs/clonetiler.cpp:2556 +msgid " _Unclump " +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2557 +msgid "Spread out clones to reduce clumping; can be applied repeatedly" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2563 +msgid " Re_move " +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2564 +msgid "Remove existing tiled clones of the selected object (siblings only)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2580 +msgid " R_eset " +msgstr "" + +#. TRANSLATORS: "change" is a noun here +#: ../../po/../src/dialogs/clonetiler.cpp:2582 +msgid "" +"Reset all shifts, scales, rotates, opacity and color changes in the dialog " +"to zero" +msgstr "" + +#: ../../po/../src/dialogs/color-picker.cpp:280 +#, fuzzy +msgid "Close" +msgstr "Radharc Nua" + +#: ../../po/../src/dialogs/debugdialog.cpp:138 +msgid "Messages" +msgstr "" + +#. ## Add a menu for clear() +#: ../../po/../src/dialogs/debugdialog.cpp:144 +#: ../../po/../src/menus-skeleton.h:16 +#: ../../po/../src/ui/dialog/messages.cpp:56 +#: ../../po/../src/ui/dialog/scriptdialog.cpp:181 +#, fuzzy +msgid "_File" +msgstr "Comhad _Nua" + +#. TRANSLATORS: "Clear" is a verb here +#: ../../po/../src/dialogs/debugdialog.cpp:145 +#: ../../po/../src/dialogs/find.cpp:753 +#: ../../po/../src/ui/dialog/messages.cpp:57 +#: ../../po/../src/ui/dialog/scriptdialog.cpp:182 +#, fuzzy +msgid "_Clear" +msgstr "Radharc Nua" + +#: ../../po/../src/dialogs/debugdialog.cpp:147 +#: ../../po/../src/ui/dialog/messages.cpp:59 +msgid "Capture log messages" +msgstr "" + +#: ../../po/../src/dialogs/debugdialog.cpp:149 +#: ../../po/../src/ui/dialog/messages.cpp:61 +msgid "Release log messages" +msgstr "" + +#. Notebook tab +#: ../../po/../src/dialogs/desktop-properties.cpp:909 +#: ../../po/../src/ui/dialog/document-preferences.cpp:89 +#: ../../po/../src/ui/widget/panel.cpp:107 +msgid "Grid" +msgstr "" + +#. Checkbuttons +#. / \todo FIXME: gray out snapping when grid is off +#. / \todo FIXME: gray out snapping when grid is off. +#. / Dissenting view: you want snapping without grid. +#: ../../po/../src/dialogs/desktop-properties.cpp:917 +#: ../../po/../src/ui/dialog/document-preferences.cpp:179 +msgid "Show grid" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:917 +#: ../../po/../src/ui/dialog/document-preferences.cpp:179 +#: ../../po/../src/verbs.cpp:2115 +msgid "Show or hide grid" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:918 +#: ../../po/../src/ui/dialog/document-preferences.cpp:180 +msgid "Snap bounding boxes to grid" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:918 +#: ../../po/../src/dialogs/desktop-properties.cpp:1001 +#: ../../po/../src/ui/dialog/document-preferences.cpp:181 +#: ../../po/../src/ui/dialog/document-preferences.cpp:236 +msgid "Snap the edges of the object bounding boxes" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:919 +#: ../../po/../src/ui/dialog/document-preferences.cpp:183 +msgid "Snap nodes to grid" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:919 +#: ../../po/../src/dialogs/desktop-properties.cpp:1002 +#: ../../po/../src/ui/dialog/document-preferences.cpp:184 +#: ../../po/../src/ui/dialog/document-preferences.cpp:239 +msgid "Snap path nodes, text baselines, ellipse centers, etc." +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:937 +#: ../../po/../src/ui/dialog/document-preferences.cpp:186 +msgid "Grid units:" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:939 +#: ../../po/../src/ui/dialog/document-preferences.cpp:187 +msgid "Origin X:" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:942 +#: ../../po/../src/ui/dialog/document-preferences.cpp:189 +msgid "Origin Y:" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:945 +#: ../../po/../src/ui/dialog/document-preferences.cpp:191 +msgid "Spacing X:" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:948 +#: ../../po/../src/ui/dialog/document-preferences.cpp:193 +msgid "Spacing Y:" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:952 +#: ../../po/../src/dialogs/desktop-properties.cpp:1013 +#: ../../po/../src/ui/dialog/document-preferences.cpp:195 +#: ../../po/../src/ui/dialog/document-preferences.cpp:241 +msgid "Snap units:" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:955 +#: ../../po/../src/dialogs/desktop-properties.cpp:1016 +#: ../../po/../src/ui/dialog/document-preferences.cpp:196 +#: ../../po/../src/ui/dialog/document-preferences.cpp:242 +msgid "Snap distance:" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:958 +#: ../../po/../src/ui/dialog/document-preferences.cpp:199 +#, fuzzy +msgid "Grid line color:" +msgstr "Dath" + +#: ../../po/../src/dialogs/desktop-properties.cpp:959 +#: ../../po/../src/ui/dialog/document-preferences.cpp:199 +#, fuzzy +msgid "Grid line color" +msgstr "Dath" + +#: ../../po/../src/dialogs/desktop-properties.cpp:959 +#: ../../po/../src/ui/dialog/document-preferences.cpp:200 +#, fuzzy +msgid "Color of grid lines" +msgstr "Dath 1" + +#: ../../po/../src/dialogs/desktop-properties.cpp:961 +#: ../../po/../src/ui/dialog/document-preferences.cpp:201 +#, fuzzy +msgid "Major grid line color:" +msgstr "Dath" + +#: ../../po/../src/dialogs/desktop-properties.cpp:962 +#: ../../po/../src/ui/dialog/document-preferences.cpp:201 +#, fuzzy +msgid "Major grid line color" +msgstr "Dath" + +#: ../../po/../src/dialogs/desktop-properties.cpp:962 +#: ../../po/../src/ui/dialog/document-preferences.cpp:202 +msgid "Color of the major (highlighted) grid lines" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:965 +#: ../../po/../src/ui/dialog/document-preferences.cpp:204 +#, fuzzy +msgid "Major grid line every:" +msgstr "Dath" + +#. TRANSLATORS: This belongs to the "Major grid line every:" string, +#. see grid settings in the "Document Preferences" dialog +#: ../../po/../src/dialogs/desktop-properties.cpp:977 +#: ../../po/../src/ui/dialog/document-preferences.cpp:204 +#, fuzzy +msgid "lines" +msgstr "Radharc Nua" + +#. Guidelines page +#: ../../po/../src/dialogs/desktop-properties.cpp:991 +#: ../../po/../src/ui/dialog/document-preferences.cpp:90 +msgid "Guides" +msgstr "" + +#. / \todo FIXME: gray out snapping when guides are off +#. / Dissenting view: you want snapping without guides. +#: ../../po/../src/dialogs/desktop-properties.cpp:1000 +#: ../../po/../src/ui/dialog/document-preferences.cpp:234 +msgid "Show guides" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1000 +#: ../../po/../src/ui/dialog/document-preferences.cpp:234 +#: ../../po/../src/verbs.cpp:2116 +msgid "Show or hide guides" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1001 +#: ../../po/../src/ui/dialog/document-preferences.cpp:235 +msgid "Snap bounding boxes to guides" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1002 +#: ../../po/../src/ui/dialog/document-preferences.cpp:238 +msgid "Snap points to guides" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1020 +#: ../../po/../src/ui/dialog/document-preferences.cpp:243 +#, fuzzy +msgid "Guide color:" +msgstr "Dath" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1021 +#: ../../po/../src/ui/dialog/document-preferences.cpp:243 +msgid "Guideline color" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1021 +#: ../../po/../src/ui/dialog/document-preferences.cpp:244 +#, fuzzy +msgid "Color of guidelines" +msgstr "Tóg" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1023 +#: ../../po/../src/ui/dialog/document-preferences.cpp:245 +msgid "Highlight color:" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1024 +#: ../../po/../src/ui/dialog/document-preferences.cpp:245 +msgid "Highlighted guideline color" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1024 +#: ../../po/../src/ui/dialog/document-preferences.cpp:246 +msgid "Color of a guideline when it is under mouse" +msgstr "" + +#. Page page +#: ../../po/../src/dialogs/desktop-properties.cpp:1029 +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:855 +#: ../../po/../src/ui/dialog/document-preferences.cpp:88 +#: ../../po/../src/widgets/desktop-widget.cpp:1061 +msgid "Page" +msgstr "Leathanach" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1039 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +#, fuzzy +msgid "Background:" +msgstr "Dath" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1040 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +#, fuzzy +msgid "Background color" +msgstr "Dath" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1041 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +msgid "" +"Color and transparency of the page background (also used for bitmap export)" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1045 +#: ../../po/../src/ui/dialog/document-preferences.cpp:147 +msgid "Show page border" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1049 +#: ../../po/../src/ui/dialog/document-preferences.cpp:148 +msgid "Border on top of drawing" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1052 +#: ../../po/../src/ui/dialog/document-preferences.cpp:149 +#, fuzzy +msgid "Border color:" +msgstr "Dath" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1053 +#: ../../po/../src/ui/dialog/document-preferences.cpp:149 +#, fuzzy +msgid "Page border color" +msgstr "Dath" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1054 +#: ../../po/../src/ui/dialog/document-preferences.cpp:150 +#, fuzzy +msgid "Color of the page border" +msgstr "Dath 1" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1059 +#: ../../po/../src/ui/dialog/document-preferences.cpp:152 +msgid "Show page shadow" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1063 +#: ../../po/../src/ui/dialog/document-preferences.cpp:153 +#, fuzzy +msgid "Default units:" +msgstr "Scríos" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1069 +msgid "Units for the tool controls, ruler, and the statusbar" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1086 +#: ../../po/../src/ui/widget/page-sizer.cpp:209 +#, fuzzy +msgid "Page size:" +msgstr "Meid pictiúr" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1110 +#: ../../po/../src/ui/widget/page-sizer.cpp:219 +#, fuzzy +msgid "Custom" +msgstr "Gearr" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1121 +#: ../../po/../src/ui/widget/page-sizer.cpp:225 +#, fuzzy +msgid "Page orientation:" +msgstr "Meid pictiúr" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1133 +#: ../../po/../src/ui/widget/page-sizer.cpp:232 +#, fuzzy +msgid "Landscape" +msgstr "Sodipodi" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1139 +#: ../../po/../src/ui/widget/page-sizer.cpp:234 +#, fuzzy +msgid "Portrait" +msgstr "Priontáil" + +#. Custom paper frame +#: ../../po/../src/dialogs/desktop-properties.cpp:1148 +#: ../../po/../src/ui/widget/page-sizer.cpp:249 +#, fuzzy +msgid "Custom size" +msgstr "Gearr" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1160 +#: ../../po/../src/dialogs/export.cpp:269 +#: ../../po/../src/ui/widget/page-sizer.cpp:261 +msgid "Units:" +msgstr "" + +#. Stroke width +#: ../../po/../src/dialogs/desktop-properties.cpp:1162 +#: ../../po/../src/dialogs/export.cpp:310 +#: ../../po/../src/dialogs/object-attributes.cpp:55 +#: ../../po/../src/dialogs/stroke-style.cpp:985 +#: ../../po/../src/ui/widget/page-sizer.cpp:262 +#: ../../po/../src/widgets/toolbox.cpp:1957 +#, fuzzy +msgid "Width:" +msgstr "Leitheid" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1183 +#: ../../po/../src/dialogs/export.cpp:326 +#: ../../po/../src/dialogs/export.cpp:431 +#: ../../po/../src/dialogs/object-attributes.cpp:56 +#: ../../po/../src/ui/widget/page-sizer.cpp:263 +#, fuzzy +msgid "Height:" +msgstr "Airde" + +#. +#. * Ownership metadata tab +#. +#: ../../po/../src/dialogs/desktop-properties.cpp:1206 +msgid "Metadata" +msgstr "" + +#. add license selector pull-down +#: ../../po/../src/dialogs/desktop-properties.cpp:1225 +msgid "License" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1255 +msgid "Proprietary" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:212 +#, fuzzy +msgid "When transforming, show:" +msgstr "Roghanna Oaf" + +#: ../../po/../src/dialogs/display-settings.cpp:223 +msgid "Objects" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:224 +msgid "Show the actual objects when moving or transforming" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:231 +msgid "Box outline" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:232 +msgid "Show only a box outline of the objects when moving or transforming" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:238 +msgid "Per-object selection cue:" +msgstr "" + +#. sorationsnapsperpi == 0 means no snapping +#: ../../po/../src/dialogs/display-settings.cpp:249 +#: ../../po/../src/dialogs/display-settings.cpp:386 +#: ../../po/../src/dialogs/display-settings.cpp:441 +#: ../../po/../src/dialogs/display-settings.cpp:1482 +#: ../../po/../src/dialogs/stroke-style.cpp:791 +#: ../../po/../src/interface.cpp:741 +#: ../../po/../src/ui/widget/selected-style.cpp:100 +#: ../../po/../src/verbs.cpp:1842 +msgid "None" +msgstr "Tada" + +#: ../../po/../src/dialogs/display-settings.cpp:250 +msgid "No per-object selection indication" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:256 +msgid "Mark" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:257 +msgid "Each selected object has a diamond mark in the top left corner" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:264 +msgid "Box" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:265 +msgid "Each selected object displays its bounding box" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:270 +msgid "Default scale origin:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:281 +msgid "Opposite bounding box edge" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:282 +msgid "Default scale origin will be on the bounding box of the item" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:288 +msgid "Farthest opposite node" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:289 +msgid "Default scale origin will be on the bounding box of the item's points" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:341 +msgid "degrees" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:350 +msgid "" +"Rotating with Ctrl pressed snaps every that much degrees; also, pressing " +"[ or ] rotates by this amount" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:407 +msgid "Rotation snaps every:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:430 +msgid "" +"None: dialogs are treated as regular windows; Normal: dialogs stay on top of " +"document windows; Aggressive: same as Normal but may work better with some " +"window managers." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:451 +msgid "Normal" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:461 +msgid "Aggressive" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:475 +msgid "Dialogs on top:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:645 +#, fuzzy +msgid "Show selection cue" +msgstr "Tóg" + +#: ../../po/../src/dialogs/display-settings.cpp:646 +msgid "" +"Whether selected objects display a selection cue (the same as in selector)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:657 +#, fuzzy +msgid "Enable gradient editing" +msgstr "Priontáil comhad" + +#: ../../po/../src/dialogs/display-settings.cpp:658 +msgid "Whether selected objects display gradient editing controls" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:719 +#, fuzzy +msgid "No objects selected to take the style from." +msgstr "Tóg" + +#: ../../po/../src/dialogs/display-settings.cpp:728 +msgid "" +"More than one object selected. Cannot take style from multiple " +"objects." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:767 +#, fuzzy +msgid "Create new objects with:" +msgstr "Tóg" + +#: ../../po/../src/dialogs/display-settings.cpp:777 +#, fuzzy +msgid "Take from selection" +msgstr "Scríos" + +#: ../../po/../src/dialogs/display-settings.cpp:778 +msgid "Remember the style of the (first) selected object as this tool's style" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:782 +#, fuzzy +msgid "Last used style" +msgstr "Greamaigh" + +#: ../../po/../src/dialogs/display-settings.cpp:782 +msgid "Apply the style you last set on an object" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:790 +msgid "This tool's own style:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:790 +msgid "" +"Each tool may store its own style to apply to the newly created objects. Use " +"the button below to set it." +msgstr "" + +#. Mouse +#: ../../po/../src/dialogs/display-settings.cpp:877 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:55 +#, fuzzy +msgid "Mouse" +msgstr "Nód" + +#. TRANSLATORS: "Grab" is a noun here. "Grab sensitivity" is intended to mean how +#. * close on the screen you need to be to an object to be able to grab it with mouse (in +#. * pixels). +#: ../../po/../src/dialogs/display-settings.cpp:883 +msgid "Grab sensitivity:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:884 +msgid "" +"How close on the screen you need to be to an object to be able to grab it " +"with mouse (in screen pixels)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:885 +#: ../../po/../src/dialogs/display-settings.cpp:897 +#: ../../po/../src/dialogs/display-settings.cpp:912 +#: ../../po/../src/dialogs/display-settings.cpp:930 +#: ../../po/../src/dialogs/display-settings.cpp:970 +msgid "pixels" +msgstr "pixelanna" + +#: ../../po/../src/dialogs/display-settings.cpp:895 +msgid "Click/drag threshold:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:896 +msgid "" +"Maximum mouse drag (in screen pixels) which is considered a click, not a drag" +msgstr "" + +#. Scrolling +#: ../../po/../src/dialogs/display-settings.cpp:907 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:56 +msgid "Scrolling" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:910 +msgid "Mouse wheel scrolls by:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:911 +msgid "" +"One mouse wheel notch scrolls by this distance in screen pixels " +"(horizontally with Shift)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:920 +msgid "Ctrl+arrows" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:928 +msgid "Scroll by:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:929 +msgid "Pressing Ctrl+arrow key scrolls by this distance (in screen pixels)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:939 +#, fuzzy +msgid "Acceleration:" +msgstr "Tóg" + +#: ../../po/../src/dialogs/display-settings.cpp:940 +msgid "" +"Pressing and holding Ctrl+arrow will gradually speed up scrolling (0 for no " +"acceleration)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:949 +msgid "Autoscrolling" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:957 +#, fuzzy +msgid "Speed:" +msgstr "Luach:" + +#: ../../po/../src/dialogs/display-settings.cpp:958 +msgid "" +"How fast the canvas autoscrolls when you drag beyond canvas edge (0 to turn " +"autoscroll off)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:968 +#: ../../po/../src/ui/dialog/tracedialog.cpp:357 +#: ../../po/../src/ui/dialog/tracedialog.cpp:390 +msgid "Threshold:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:969 +msgid "" +"How far (in screen pixels) you need to be from the canvas edge to trigger " +"autoscroll; positive is outside the canvas, negative is within the canvas" +msgstr "" + +#. Steps +#: ../../po/../src/dialogs/display-settings.cpp:979 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:57 +msgid "Steps" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:982 +msgid "Arrow keys move by:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:983 +msgid "" +"Pressing an arrow key moves selected object(s) or node(s) by this distance " +"(in px units)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:984 +#: ../../po/../src/dialogs/display-settings.cpp:995 +#: ../../po/../src/dialogs/display-settings.cpp:1006 +#: ../../po/../src/helper/units.cpp:42 +msgid "px" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:993 +msgid "> and < scale by:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:994 +msgid "" +"Pressing > or < scales selection up or down by this increment (in px units)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1004 +msgid "Inset/Outset by:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1005 +msgid "" +"Inset and Outset commands displace the path by this distance (in px units)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1017 +msgid "Compass-like display of angles" +msgstr "" + +#. TRANSLATORS: "positive clockwise" means "increasing in clockwise direction" +#: ../../po/../src/dialogs/display-settings.cpp:1019 +msgid "" +"When on, angles are displayed with 0 at north, 0 to 360 range, positive " +"clockwise; otherwise with 0 at east, -180 to 180 range, positive " +"counterclockwise" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1026 +#, fuzzy +msgid "Zoom in/out by:" +msgstr "Priontáil comhad" + +#: ../../po/../src/dialogs/display-settings.cpp:1027 +msgid "" +"Zoom tool click, +/- keys, and middle click zoom in and out by this " +"multiplier" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1028 +#: ../../po/../src/helper/units.cpp:44 +msgid "%" +msgstr "" + +#. Tools +#: ../../po/../src/dialogs/display-settings.cpp:1037 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:58 +msgid "Tools" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1045 +#, fuzzy +msgid "Selector" +msgstr "Tóg" + +#: ../../po/../src/dialogs/display-settings.cpp:1056 +msgid "Node" +msgstr "Nód" + +#: ../../po/../src/dialogs/display-settings.cpp:1064 +#: ../../po/../src/verbs.cpp:2073 +#: ../../po/../src/widgets/desktop-widget.cpp:277 +msgid "Zoom" +msgstr "" + +#. The 4 shape tools +#: ../../po/../src/dialogs/display-settings.cpp:1071 +#, fuzzy +msgid "Shapes" +msgstr "Sábháil\t" + +#: ../../po/../src/dialogs/display-settings.cpp:1079 +#: ../../po/../src/verbs.cpp:2055 +msgid "Rectangle" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1085 +#: ../../po/../src/verbs.cpp:2057 +msgid "Ellipse" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1091 +#: ../../po/../src/verbs.cpp:2059 +msgid "Star" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1097 +#: ../../po/../src/verbs.cpp:2061 +#, fuzzy +msgid "Spiral" +msgstr "Spéisialta" + +#: ../../po/../src/dialogs/display-settings.cpp:1111 +#: ../../po/../src/verbs.cpp:2063 +msgid "Pencil" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1114 +msgid "Tolerance:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1115 +msgid "" +"This value affects the amount of smoothing applied to freehand lines; lower " +"values produce more uneven paths with more nodes" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1131 +#: ../../po/../src/verbs.cpp:2065 +#, fuzzy +msgid "Pen" +msgstr "Priontáil" + +#: ../../po/../src/dialogs/display-settings.cpp:1140 +#: ../../po/../src/verbs.cpp:2067 +msgid "Calligraphy" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1147 +#: ../../po/../src/dialogs/text-edit.cpp:353 +#: ../../po/../src/ui/dialog/text-properties.cpp:37 +#: ../../po/../src/verbs.cpp:2069 +msgid "Text" +msgstr "Teacs" + +#: ../../po/../src/dialogs/display-settings.cpp:1157 +#: ../../po/../src/verbs.cpp:2071 +#, fuzzy +msgid "Gradient" +msgstr "Priontáil comhad" + +#: ../../po/../src/dialogs/display-settings.cpp:1164 +#: ../../po/../src/verbs.cpp:2077 +#, fuzzy +msgid "Connector" +msgstr "Radharc Nua" + +#: ../../po/../src/dialogs/display-settings.cpp:1171 +#: ../../po/../src/verbs.cpp:2075 +msgid "Dropper" +msgstr "" + +#. Windows +#: ../../po/../src/dialogs/display-settings.cpp:1183 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:59 +#, fuzzy +msgid "Windows" +msgstr "fuinneog1" + +#: ../../po/../src/dialogs/display-settings.cpp:1188 +msgid "Save window geometry" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1189 +msgid "" +"Save the window size and position with each document (only for Inkscape SVG " +"format)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1196 +msgid "Dialogs are hidden in taskbar" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1197 +msgid "Whether dialog windows are to be hidden in the window manager taskbar" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1204 +msgid "Zoom when window is resized" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1205 +msgid "" +"Zoom drawing when document window is resized, to keep the same area visible " +"(this is the default which can be changed in any window using the button " +"above the right scrollbar)" +msgstr "" + +#. Clones +#: ../../po/../src/dialogs/display-settings.cpp:1213 +#: ../../po/../src/dialogs/find.cpp:624 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:60 +#, fuzzy +msgid "Clones" +msgstr "Radharc Nua" + +#: ../../po/../src/dialogs/display-settings.cpp:1217 +msgid "When the original moves, its clones and linked offsets:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1229 +msgid "Move in parallel" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1230 +msgid "Clones are translated by the same vector as their original." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1237 +msgid "Stay unmoved" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1238 +msgid "Clones preserve their positions when their original is moved." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1245 +msgid "Move according to transform" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1246 +msgid "" +"Each clone moves according to the value of its transform= attribute. For " +"example, a rotated clone will move in a different direction than its " +"original." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1255 +msgid "When the original is deleted, its clones:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1267 +msgid "Are unlinked" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1267 +msgid "Orphaned clones are converted to regular objects." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1273 +#, fuzzy +msgid "Are deleted" +msgstr "Scríos" + +#: ../../po/../src/dialogs/display-settings.cpp:1273 +msgid "Orphaned clones are deleted along with their original." +msgstr "" + +#. Transforms +#. TRANSLATORS: Noun, i.e. transformations. +#: ../../po/../src/dialogs/display-settings.cpp:1289 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:61 +#, fuzzy +msgid "Transforms" +msgstr "Roghanna Oaf" + +#: ../../po/../src/dialogs/display-settings.cpp:1292 +#, fuzzy +msgid "Scale stroke width" +msgstr "Priontáil" + +#: ../../po/../src/dialogs/display-settings.cpp:1293 +#: ../../po/../src/widgets/select-toolbar.cpp:568 +msgid "When scaling objects, scale the stroke width by the same proportion" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1300 +msgid "Scale rounded corners in rectangles" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1301 +#: ../../po/../src/widgets/select-toolbar.cpp:580 +msgid "When scaling rectangles, scale the radii of rounded corners" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1308 +#, fuzzy +msgid "Transform gradients" +msgstr "Roghanna Oaf" + +#: ../../po/../src/dialogs/display-settings.cpp:1309 +#: ../../po/../src/widgets/select-toolbar.cpp:592 +msgid "Transform gradients (in fill or stroke) along with the objects" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1316 +#, fuzzy +msgid "Transform patterns" +msgstr "Roghanna Oaf" + +#: ../../po/../src/dialogs/display-settings.cpp:1317 +#: ../../po/../src/widgets/select-toolbar.cpp:604 +msgid "Transform patterns (in fill or stroke) along with the objects" +msgstr "" + +#. TRANSLATORS: How to specify the affine transformation in the SVG file. +#: ../../po/../src/dialogs/display-settings.cpp:1327 +#, fuzzy +msgid "Store transformation:" +msgstr "Roghanna Oaf" + +#: ../../po/../src/dialogs/display-settings.cpp:1338 +msgid "Optimized" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1339 +msgid "" +"If possible, apply transformation to objects without adding a transform= " +"attribute" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1346 +msgid "Preserved" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1347 +msgid "Always store transformation as a transform= attribute on objects" +msgstr "" + +#. Selecting +#: ../../po/../src/dialogs/display-settings.cpp:1355 +#, fuzzy +msgid "Selecting" +msgstr "Tóg" + +#: ../../po/../src/dialogs/display-settings.cpp:1357 +msgid "Ctrl+A, Tab, Shift+Tab:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1366 +#, fuzzy +msgid "Select only within current layer" +msgstr "Tóg" + +#: ../../po/../src/dialogs/display-settings.cpp:1367 +msgid "" +"Uncheck this to make keyboard selection commands work on objects in all " +"layers" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1374 +msgid "Ignore hidden objects" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1375 +msgid "" +"Uncheck this to be able to select objects that are hidden (either by " +"themselves or by being in a hidden group or layer)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1382 +#, fuzzy +msgid "Ignore locked objects" +msgstr "Tóg" + +#: ../../po/../src/dialogs/display-settings.cpp:1383 +msgid "" +"Uncheck this to be able to select objects that are locked (either by " +"themselves or by being in a locked group or layer)" +msgstr "" + +#. To be broken into: Display, Save, Export, SVG, Commands +#: ../../po/../src/dialogs/display-settings.cpp:1391 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:62 +msgid "Misc" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1394 +msgid "Default export resolution:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1395 +msgid "Default bitmap resolution (in dots per inch) in the Export dialog" +msgstr "" + +#. FIXME: add "Used for new exports; once exported, documents remember this value on per-object basis" when implemented +#: ../../po/../src/dialogs/display-settings.cpp:1396 +#: ../../po/../src/dialogs/export.cpp:442 +msgid "dpi" +msgstr "dpi" + +#. TRANSLATORS: When on, an imported bitmap creates an element; otherwise it is a +#. * rectangle with bitmap fill. +#: ../../po/../src/dialogs/display-settings.cpp:1407 +msgid "Import bitmap as " +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1408 +msgid "" +"When on, an imported bitmap creates an element; otherwise it is a " +"rectangle with bitmap fill" +msgstr "" + +#. TRANSLATORS: When on, the print out (currently Postscript) will have +#. * a comment with the each object's label visible, marking the section +#. * of the printing commands that represent the given object. +#: ../../po/../src/dialogs/display-settings.cpp:1418 +msgid "Add label comments to printing output" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1419 +msgid "" +"When on, a comment will be added to the raw print output, marking the " +"rendered output for an object with its label" +msgstr "" + +#. TRANSLATORS: When on, enable the effects menu, default is off +#: ../../po/../src/dialogs/display-settings.cpp:1427 +msgid "Enable script effects (requires restart) - EXPERIMENTAL" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1428 +msgid "" +"When on, the effects menu is enabled, allowing external effect scripts to be " +"called, requires restart before effective - EXPERIMENTAL" +msgstr "" + +#. TRANSLATORS: The maximum length of the Open Recent list in the File menu. +#: ../../po/../src/dialogs/display-settings.cpp:1436 +#, fuzzy +msgid "Max recent documents:" +msgstr "Sábháil Comhad" + +#: ../../po/../src/dialogs/display-settings.cpp:1437 +msgid "The maximum length of the Open Recent list in the File menu" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1447 +msgid "Simplification threshold:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1448 +msgid "" +"How strong is the Simplify command by default. If you invoke this command " +"several times in quick succession, it will act more and more aggressively; " +"invoking it again after a pause restores the default threshold." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1469 +msgid "Oversample bitmaps:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1488 +msgid "2x2" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1494 +msgid "4x4" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1500 +msgid "8x8" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1506 +msgid "16x16" +msgstr "" + +#. "view_icon_preview" +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2143 +msgid "_Page" +msgstr "_Leathanach" + +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2147 +msgid "_Drawing" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2149 +#, fuzzy +msgid "_Selection" +msgstr "Tóg" + +#: ../../po/../src/dialogs/export.cpp:133 +#, fuzzy +msgid "_Custom" +msgstr "Gearr" + +#: ../../po/../src/dialogs/export.cpp:254 +msgid "Export area" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:300 +msgid "_x0:" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:305 +#, fuzzy +msgid "x_1:" +msgstr "1:1" + +#: ../../po/../src/dialogs/export.cpp:316 +msgid "_y0:" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:321 +#, fuzzy +msgid "y_1:" +msgstr "1:1" + +#: ../../po/../src/dialogs/export.cpp:406 +#, fuzzy +msgid "Bitmap size" +msgstr "Meid pictiúr" + +#: ../../po/../src/dialogs/export.cpp:416 +#, fuzzy +msgid "_Width:" +msgstr "Leitheid" + +#: ../../po/../src/dialogs/export.cpp:416 +#: ../../po/../src/dialogs/export.cpp:431 +#, fuzzy +msgid "pixels at" +msgstr "pixelanna" + +#: ../../po/../src/dialogs/export.cpp:426 +#, fuzzy +msgid "dp_i" +msgstr "dpi" + +#: ../../po/../src/dialogs/export.cpp:448 +#, fuzzy +msgid "_Filename" +msgstr "ainm" + +#: ../../po/../src/dialogs/export.cpp:512 +msgid "_Browse..." +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:539 +#, fuzzy +msgid " _Export " +msgstr "Priontáil" + +#: ../../po/../src/dialogs/export.cpp:541 +msgid "Export the bitmap file with these settings" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:968 +msgid "You have to enter a filename" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:973 +msgid "The chosen area to be exported is invalid" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:982 +#, c-format +msgid "Directory %s does not exist or is not a directory.\n" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:998 +msgid "Export in progress" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:1004 +#, c-format +msgid "Exporting %s (%d x %d)" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:1031 +#, c-format +msgid "Could not export to filename %s.\n" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:1137 +msgid "Select a filename for exporting" +msgstr "" + +#: ../../po/../src/dialogs/filedialog.cpp:367 +#, fuzzy +msgid "No preview" +msgstr "Radharc Nua" + +#: ../../po/../src/dialogs/filedialog.cpp:468 +msgid "too large for preview" +msgstr "" + +#: ../../po/../src/dialogs/filedialog.cpp:762 +#: ../../po/../src/dialogs/filedialog.cpp:763 +#, fuzzy +msgid "All Images" +msgstr "Meid pictiúr" + +#: ../../po/../src/dialogs/filedialog.cpp:767 +#: ../../po/../src/dialogs/filedialog.cpp:768 +#, fuzzy +msgid "All Files" +msgstr "Ainm comhad:" + +#: ../../po/../src/dialogs/filedialog.cpp:774 +#: ../../po/../src/dialogs/filedialog.cpp:775 +#, fuzzy +msgid "All Inkscape Files" +msgstr "Sodipodi" + +#: ../../po/../src/dialogs/filedialog.cpp:1176 +#, fuzzy +msgid "Guess from extension" +msgstr "Scríos" + +#. ###### Add the file types menu +#. createFilterMenu(); +#. ###### Do we want the .xxx extension automatically added? +#: ../../po/../src/dialogs/filedialog.cpp:1261 +msgid "Append filename extension automatically" +msgstr "" + +#. TRANSLATORS: "%s" is replaced with "exact" or "partial" when this string is displayed +#: ../../po/../src/dialogs/find.cpp:378 +#, c-format +msgid "%d object found (out of %d), %s match." +msgid_plural "%d objects found (out of %d), %s match." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/dialogs/find.cpp:381 +#, fuzzy +msgid "exact" +msgstr "Teacs" + +#: ../../po/../src/dialogs/find.cpp:381 +#, fuzzy +msgid "partial" +msgstr "Spéisialta" + +#: ../../po/../src/dialogs/find.cpp:388 +#, fuzzy +msgid "No objects found" +msgstr "Sábháil Comhad" + +#: ../../po/../src/dialogs/find.cpp:546 +msgid "T_ype: " +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:553 +msgid "Search in all object types" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:553 +#, fuzzy +msgid "All types" +msgstr "Ainm comhad:" + +#: ../../po/../src/dialogs/find.cpp:564 +msgid "Search all shapes" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:564 +msgid "All shapes" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:581 +msgid "Search rectangles" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:581 +#, fuzzy +msgid "Rectangles" +msgstr "Priontáil" + +#: ../../po/../src/dialogs/find.cpp:586 +msgid "Search ellipses, arcs, circles" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:586 +msgid "Ellipses" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:591 +msgid "Search stars and polygons" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:591 +#, fuzzy +msgid "Stars" +msgstr "Dath" + +#: ../../po/../src/dialogs/find.cpp:596 +#, fuzzy +msgid "Search spirals" +msgstr "Spéisialta" + +#: ../../po/../src/dialogs/find.cpp:596 +#, fuzzy +msgid "Spirals" +msgstr "Spéisialta" + +#. TRANSLATORS: polyline is a set of connected straight line segments +#. http://www.w3.org/TR/SVG11/shapes.html#PolylineElement +#: ../../po/../src/dialogs/find.cpp:609 +msgid "Search paths, lines, polylines" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:609 +msgid "Paths" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:614 +#, fuzzy +msgid "Search text objects" +msgstr "Tóg" + +#: ../../po/../src/dialogs/find.cpp:614 +#, fuzzy +msgid "Texts" +msgstr "Teacs" + +#: ../../po/../src/dialogs/find.cpp:619 +msgid "Search groups" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:619 +#, fuzzy +msgid "Groups" +msgstr "_Grupa" + +#: ../../po/../src/dialogs/find.cpp:624 +msgid "Search clones" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:629 +msgid "Search images" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:629 +#, fuzzy +msgid "Images" +msgstr "Meid pictiúr" + +#: ../../po/../src/dialogs/find.cpp:634 +#, fuzzy +msgid "Search offset objects" +msgstr "Tóg" + +#: ../../po/../src/dialogs/find.cpp:634 +msgid "Offsets" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:694 +#, fuzzy +msgid "_Text: " +msgstr "Teacs" + +#: ../../po/../src/dialogs/find.cpp:694 +msgid "Find objects by their text content (exact or partial match)" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:695 +msgid "_ID: " +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:695 +msgid "Find objects by the value of the id attribute (exact or partial match)" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:696 +#, fuzzy +msgid "_Style: " +msgstr "Greamaigh" + +#: ../../po/../src/dialogs/find.cpp:696 +msgid "" +"Find objects by the value of the style attribute (exact or partial match)" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:697 +msgid "_Attribute: " +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:697 +msgid "Find objects by the name of an attribute (exact or partial match)" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:711 +#, fuzzy +msgid "Search in s_election" +msgstr "Scríos" + +#: ../../po/../src/dialogs/find.cpp:715 +msgid "Limit search to the current selection" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:720 +#, fuzzy +msgid "Search in current _layer" +msgstr "Tóg" + +#: ../../po/../src/dialogs/find.cpp:724 +#, fuzzy +msgid "Limit search to the current layer" +msgstr "Tóg" + +#: ../../po/../src/dialogs/find.cpp:729 +msgid "Include _hidden" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:733 +msgid "Include hidden objects in search" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:738 +msgid "Include l_ocked" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:742 +#, fuzzy +msgid "Include locked objects in search" +msgstr "Tóg" + +#: ../../po/../src/dialogs/find.cpp:753 +#, fuzzy +msgid "Clear values" +msgstr "Dath 1" + +#: ../../po/../src/dialogs/find.cpp:754 +#, fuzzy +msgid "_Find" +msgstr "Leasú" + +#: ../../po/../src/dialogs/find.cpp:754 +msgid "Select objects matching all of the fields you filled in" +msgstr "" + +#: ../../po/../src/dialogs/iconpreview.cpp:145 +#, c-format +msgid "%d x %d" +msgstr "" + +#: ../../po/../src/dialogs/iconpreview.cpp:193 +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:857 +#: ../../po/../src/widgets/desktop-widget.cpp:1069 +msgid "Selection" +msgstr "" + +#: ../../po/../src/dialogs/iconpreview.cpp:195 +#, fuzzy +msgid "Selection only or whole document" +msgstr "Tóg" + +#: ../../po/../src/dialogs/iconpreview.cpp:203 +msgid "Refresh the icons" +msgstr "" + +#. Create the label for the object id +#: ../../po/../src/dialogs/item-properties.cpp:126 +#: ../../po/../src/dialogs/item-properties.cpp:327 +#: ../../po/../src/dialogs/item-properties.cpp:396 +#: ../../po/../src/dialogs/item-properties.cpp:403 +msgid "_Id" +msgstr "" + +#: ../../po/../src/dialogs/item-properties.cpp:135 +msgid "" +"The id= attribute (only letters, digits, and the characters .-_: allowed)" +msgstr "" + +#. Button for setting the object's id, label, title and description. +#: ../../po/../src/dialogs/item-properties.cpp:149 +#, fuzzy +msgid "_Set" +msgstr "Tóg" + +#. Create the label for the object label +#: ../../po/../src/dialogs/item-properties.cpp:158 +msgid "_Label" +msgstr "" + +#: ../../po/../src/dialogs/item-properties.cpp:167 +msgid "A freeform label for the object" +msgstr "" + +#. Create the label for the object title +#: ../../po/../src/dialogs/item-properties.cpp:179 +#: ../../po/../src/dialogs/rdf.cpp:243 +#, fuzzy +msgid "Title" +msgstr "Comhad Nua" + +#. Create the frame for the object description +#: ../../po/../src/dialogs/item-properties.cpp:196 +#: ../../po/../src/dialogs/rdf.cpp:287 +msgid "Description" +msgstr "" + +#. Hide +#: ../../po/../src/dialogs/item-properties.cpp:223 +#, fuzzy +msgid "_Hide" +msgstr "Leasú" + +#: ../../po/../src/dialogs/item-properties.cpp:224 +msgid "Check to make the object invisible" +msgstr "" + +#. Lock +#. TRANSLATORS: "Lock" is a verb here +#: ../../po/../src/dialogs/item-properties.cpp:233 +msgid "L_ock" +msgstr "" + +#: ../../po/../src/dialogs/item-properties.cpp:234 +msgid "Check to make the object insensitive (not selectable by mouse)" +msgstr "" + +#: ../../po/../src/dialogs/item-properties.cpp:310 +#: ../../po/../src/dialogs/item-properties.cpp:317 +msgid "Ref" +msgstr "" + +#: ../../po/../src/dialogs/item-properties.cpp:398 +msgid "Id invalid! " +msgstr "" + +#: ../../po/../src/dialogs/item-properties.cpp:400 +msgid "Id exists! " +msgstr "" + +#: ../../po/../src/dialogs/layer-properties.cpp:50 +msgid "Layer name:" +msgstr "" + +#: ../../po/../src/dialogs/layer-properties.cpp:133 +#, fuzzy +msgid "Rename Layer" +msgstr "Greamaigh" + +#: ../../po/../src/dialogs/layer-properties.cpp:136 +#, fuzzy +msgid "_Rename" +msgstr "ainm" + +#. TRANSLATORS: This means "The layer has been renamed" +#: ../../po/../src/dialogs/layer-properties.cpp:147 +#, fuzzy +msgid "Renamed layer" +msgstr "Greamaigh" + +#: ../../po/../src/dialogs/layer-properties.cpp:151 +#, fuzzy +msgid "Add Layer" +msgstr "Tóg" + +#: ../../po/../src/dialogs/layer-properties.cpp:153 +#, fuzzy +msgid "_Add" +msgstr "Suim" + +#: ../../po/../src/dialogs/layer-properties.cpp:167 +msgid "New layer created." +msgstr "" + +#: ../../po/../src/dialogs/object-attributes.cpp:34 +#, fuzzy +msgid "Href:" +msgstr "Luach:" + +#: ../../po/../src/dialogs/object-attributes.cpp:35 +msgid "Target:" +msgstr "" + +#: ../../po/../src/dialogs/object-attributes.cpp:36 +msgid "Type:" +msgstr "" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkRoleAttribute +#. Identifies the type of the related resource with an absolute URI +#: ../../po/../src/dialogs/object-attributes.cpp:39 +#, fuzzy +msgid "Role:" +msgstr "Luach:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkArcRoleAttribute +#. For situations where the nature/role alone isn't enough, this offers an additional URI defining the purpose of the link. +#: ../../po/../src/dialogs/object-attributes.cpp:42 +msgid "Arcrole:" +msgstr "" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkTitleAttribute +#: ../../po/../src/dialogs/object-attributes.cpp:44 +#, fuzzy +msgid "Title:" +msgstr "Comhad Nua" + +#: ../../po/../src/dialogs/object-attributes.cpp:45 +msgid "Show:" +msgstr "" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkActuateAttribute +#: ../../po/../src/dialogs/object-attributes.cpp:47 +msgid "Actuate:" +msgstr "" + +#: ../../po/../src/dialogs/object-attributes.cpp:52 +msgid "URL:" +msgstr "" + +#: ../../po/../src/dialogs/object-attributes.cpp:53 +msgid "X:" +msgstr "" + +#: ../../po/../src/dialogs/object-attributes.cpp:54 +msgid "Y:" +msgstr "" + +#: ../../po/../src/dialogs/object-attributes.cpp:98 +#, c-format +msgid "%s attributes" +msgstr "" + +#: ../../po/../src/dialogs/object-properties.cpp:158 +#, fuzzy +msgid "_Fill" +msgstr "Comhad Nua" + +#: ../../po/../src/dialogs/object-properties.cpp:165 +#, fuzzy +msgid "Stroke _paint" +msgstr "Priontáil" + +#: ../../po/../src/dialogs/object-properties.cpp:172 +#, fuzzy +msgid "Stroke st_yle" +msgstr "Roghanna Dath" + +#: ../../po/../src/dialogs/object-properties.cpp:183 +msgid "Master _opacity" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:244 +msgid "Name by which this document is formally known." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:246 +#, fuzzy +msgid "Date" +msgstr "Scríobh teacs" + +#: ../../po/../src/dialogs/rdf.cpp:247 +msgid "Date associated with the creation of this document (YYYY-MM-DD)." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:249 +msgid "Format" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:250 +msgid "The physical or digital manifestation of this document (MIME type)." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:252 +msgid "Type" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:253 +msgid "Type of document (DCMI Type)." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:256 +#, fuzzy +msgid "Creator" +msgstr "Radharc Nua" + +#: ../../po/../src/dialogs/rdf.cpp:257 +msgid "" +"Name of entity primarily responsible for making the content of this document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:259 +#, fuzzy +msgid "Rights" +msgstr "deis" + +#: ../../po/../src/dialogs/rdf.cpp:260 +msgid "" +"Name of entity with rights to the Intellectual Property of this document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:262 +msgid "Publisher" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:263 +msgid "Name of entity responsible for making this document available." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:266 +msgid "Identifier" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:267 +msgid "Unique URI to reference this document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:269 +msgid "Source" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:270 +msgid "Unique URI to reference the source of this document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:272 +#, fuzzy +msgid "Relation" +msgstr "Tóg" + +#: ../../po/../src/dialogs/rdf.cpp:273 +msgid "Unique URI to a related document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:275 +msgid "Language" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:276 +msgid "" +"Two-letter language tag with optional subtags for the language of this " +"document. (e.g. 'en-GB')" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:278 +msgid "Keywords" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:279 +msgid "" +"The topic of this document as comma-separated key words, phrases, or " +"classifications." +msgstr "" + +#. TRANSLATORS: "Coverage": the spatial or temporal characteristics of the content. +#. For info, see Appendix D of http://www.w3.org/TR/1998/WD-rdf-schema-19980409/ +#: ../../po/../src/dialogs/rdf.cpp:283 +msgid "Coverage" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:284 +msgid "Extent or scope of this document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:288 +msgid "A short account of the content of this document." +msgstr "" + +#. FIXME: need to handle 1 agent per line of input +#: ../../po/../src/dialogs/rdf.cpp:292 +msgid "Contributors" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:293 +msgid "" +"Names of entities responsible for making contributions to the content of " +"this document." +msgstr "" + +#. TRANSLATORS: URL to a page that defines the license for the document +#: ../../po/../src/dialogs/rdf.cpp:297 +msgid "URI" +msgstr "" + +#. TRANSLATORS: this is where you put a URL to a page that defines the license +#: ../../po/../src/dialogs/rdf.cpp:299 +msgid "URI to this document's license's namespace definition." +msgstr "" + +#. TRANSLATORS: fragment of XML representing the license of the document +#: ../../po/../src/dialogs/rdf.cpp:303 +msgid "Fragment" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:304 +msgid "XML fragment for the RDF 'License' section." +msgstr "" + +#: ../../po/../src/dialogs/stroke-style.cpp:774 +#: ../../po/../src/widgets/gradient-vector.cpp:263 +#: ../../po/../src/widgets/paint-selector.cpp:751 +msgid "No document selected" +msgstr "" + +#: ../../po/../src/dialogs/stroke-style.cpp:992 +#, fuzzy +msgid "Stroke width" +msgstr "Priontáil" + +#. Join type +#. TRANSLATORS: The line join style specifies the shape to be used at the +#. corners of paths. It can be "miter", "round" or "bevel". +#: ../../po/../src/dialogs/stroke-style.cpp:1015 +msgid "Join:" +msgstr "" + +#. TRANSLATORS: Miter join: joining lines with a sharp (pointed) corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1027 +msgid "Miter join" +msgstr "" + +#. TRANSLATORS: Round join: joining lines with a rounded corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1035 +msgid "Round join" +msgstr "" + +#. TRANSLATORS: Bevel join: joining lines with a blunted (flattened) corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1043 +msgid "Bevel join" +msgstr "" + +#. Miterlimit +#. TRANSLATORS: Miter limit: only for "miter join", this limits the length +#. of the sharp "spike" when the lines connect at too sharp an angle. +#. When two line segments meet at a sharp angle, a miter join results in a +#. spike that extends well beyond the connection point. The purpose of the +#. miter limit is to cut off such spikes (i.e. convert them into bevels) +#. when they become too long. +#: ../../po/../src/dialogs/stroke-style.cpp:1054 +msgid "Miter limit:" +msgstr "" + +#: ../../po/../src/dialogs/stroke-style.cpp:1062 +msgid "Maximum length of the miter (in units of stroke width)" +msgstr "" + +#. Cap type +#. TRANSLATORS: cap type specifies the shape for the ends of lines +#: ../../po/../src/dialogs/stroke-style.cpp:1075 +msgid "Cap:" +msgstr "" + +#. TRANSLATORS: Butt cap: the line shape does not extend beyond the end point +#. of the line; the ends of the line are square +#: ../../po/../src/dialogs/stroke-style.cpp:1086 +msgid "Butt cap" +msgstr "" + +#. TRANSLATORS: Round cap: the line shape extends beyond the end point of the +#. line; the ends of the line are rounded +#: ../../po/../src/dialogs/stroke-style.cpp:1093 +msgid "Round cap" +msgstr "" + +#. TRANSLATORS: Square cap: the line shape extends beyond the end point of the +#. line; the ends of the line are square +#: ../../po/../src/dialogs/stroke-style.cpp:1100 +msgid "Square cap" +msgstr "" + +#. Dash +#: ../../po/../src/dialogs/stroke-style.cpp:1106 +msgid "Dashes:" +msgstr "" + +#. TRANSLATORS: Path markers are an SVG feature that allows you to attach arbitrary shapes +#. (arrowheads, bullets, faces, whatever) to the start, end, or middle nodes of a path. +#: ../../po/../src/dialogs/stroke-style.cpp:1127 +msgid "Start Markers:" +msgstr "" + +#: ../../po/../src/dialogs/stroke-style.cpp:1137 +msgid "Mid Markers:" +msgstr "" + +#: ../../po/../src/dialogs/stroke-style.cpp:1148 +msgid "End Markers:" +msgstr "" + +#: ../../po/../src/dialogs/swatches.cpp:424 +#, c-format +msgid "Palettes directory (%s) is unavailable." +msgstr "" + +#. TODO: Insert widgets +#: ../../po/../src/dialogs/text-edit.cpp:199 +#: ../../po/../src/ui/dialog/text-properties.cpp:36 +#, fuzzy +msgid "Font" +msgstr "Priontáil" + +#: ../../po/../src/dialogs/text-edit.cpp:216 +msgid "Layout" +msgstr "" + +#: ../../po/../src/dialogs/text-edit.cpp:229 +msgid "Align lines left" +msgstr "" + +#. TRANSLATORS: `Center' here is a verb. +#: ../../po/../src/dialogs/text-edit.cpp:243 +msgid "Center lines" +msgstr "" + +#: ../../po/../src/dialogs/text-edit.cpp:256 +msgid "Align lines right" +msgstr "" + +#: ../../po/../src/dialogs/text-edit.cpp:278 +#, fuzzy +msgid "Horizontal text" +msgstr "Tóg" + +#: ../../po/../src/dialogs/text-edit.cpp:292 +msgid "Vertical text" +msgstr "" + +#: ../../po/../src/dialogs/text-edit.cpp:307 +msgid "Line spacing:" +msgstr "" + +#: ../../po/../src/dialogs/text-edit.cpp:400 +msgid "Set as default" +msgstr "" + +#: ../../po/../src/dialogs/tiledialog.cpp:603 +#, fuzzy +msgid "Rows:" +msgstr "Luach:" + +#: ../../po/../src/dialogs/tiledialog.cpp:613 +msgid "Number of rows" +msgstr "" + +#: ../../po/../src/dialogs/tiledialog.cpp:617 +#, fuzzy +msgid "Equal height" +msgstr "Airde" + +#: ../../po/../src/dialogs/tiledialog.cpp:627 +msgid "If not set, each row has the height of the tallest object in it" +msgstr "" + +#. #### Radio buttons to control vertical alignment #### +#. #### Radio buttons to control horizontal alignment #### +#: ../../po/../src/dialogs/tiledialog.cpp:637 +#: ../../po/../src/dialogs/tiledialog.cpp:708 +#, fuzzy +msgid "Align:" +msgstr "Nódanna" + +#: ../../po/../src/dialogs/tiledialog.cpp:672 +msgid " X " +msgstr "" + +#. #### Number of columns #### +#: ../../po/../src/dialogs/tiledialog.cpp:678 +#, fuzzy +msgid "Columns:" +msgstr "Dath" + +#: ../../po/../src/dialogs/tiledialog.cpp:688 +msgid "Number of columns" +msgstr "" + +#: ../../po/../src/dialogs/tiledialog.cpp:692 +#, fuzzy +msgid "Equal width" +msgstr "Leitheid" + +#: ../../po/../src/dialogs/tiledialog.cpp:701 +msgid "If not set, each column has the width of the widest object in it" +msgstr "" + +#. #### Radio buttons to control spacing manually or to fit selection bbox #### +#: ../../po/../src/dialogs/tiledialog.cpp:746 +#, fuzzy +msgid "Fit into selection box" +msgstr "Tóg" + +#: ../../po/../src/dialogs/tiledialog.cpp:753 +#, fuzzy +msgid "Set spacing:" +msgstr "Priontáil" + +#. #### Y Padding #### +#: ../../po/../src/dialogs/tiledialog.cpp:777 +#, fuzzy +msgid "Row spacing: " +msgstr "Priontáil" + +#: ../../po/../src/dialogs/tiledialog.cpp:786 +#, fuzzy +msgid "Vertical spacing between rows" +msgstr "Tóg" + +#. #### X padding #### +#: ../../po/../src/dialogs/tiledialog.cpp:795 +msgid "Column spacing:" +msgstr "" + +#: ../../po/../src/dialogs/tiledialog.cpp:804 +#, fuzzy +msgid "Horizontal spacing between columns" +msgstr "Tóg" + +#: ../../po/../src/dialogs/tiledialog.cpp:818 +#, fuzzy +msgid "Arrange selected objects" +msgstr "Tóg" + +#: ../../po/../src/dialogs/xml-tree.cpp:178 +msgid "Click to select nodes, drag to rearrange." +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:189 +msgid "Click attribute to edit." +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:193 +#, c-format +msgid "" +"Attribute %s selected. Press Ctrl+Enter when done editing to " +"commit changes." +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:284 +msgid "Drag to reorder nodes" +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:304 +msgid "New element node" +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:326 +msgid "New text node" +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:347 +msgid "Duplicate node" +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:368 +#, fuzzy +msgid "Delete node" +msgstr "Scríos" + +#: ../../po/../src/dialogs/xml-tree.cpp:384 +msgid "Unindent node" +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:399 +msgid "Indent node" +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:411 +#, fuzzy +msgid "Raise node" +msgstr "Greamaigh" + +#: ../../po/../src/dialogs/xml-tree.cpp:423 +msgid "Lower node" +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:468 +msgid "Delete attribute" +msgstr "" + +#. TRANSLATORS: "Attribute" is a noun here +#: ../../po/../src/dialogs/xml-tree.cpp:513 +msgid "Attribute name" +msgstr "" + +#. TRANSLATORS: "Set" is a verb here +#: ../../po/../src/dialogs/xml-tree.cpp:533 +msgid "Set attribute" +msgstr "" + +#. TRANSLATORS: "Set" is a verb here +#: ../../po/../src/dialogs/xml-tree.cpp:535 +#, fuzzy +msgid "Set" +msgstr "Tóg" + +#. TRANSLATORS: "Attribute" is a noun here +#: ../../po/../src/dialogs/xml-tree.cpp:558 +msgid "Attribute value" +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:1318 +msgid "New element node..." +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:1339 +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:100 +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:98 +msgid "Cancel" +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:1345 +msgid "Create" +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:1458 +#, c-format +msgid "" +"Cannot set %s: Another element with value %s already exists!" +msgstr "" + +#: ../../po/../src/document.cpp:369 +#, c-format +msgid "New document %d" +msgstr "" + +#: ../../po/../src/document.cpp:401 +#, c-format +msgid "Memory document %d" +msgstr "" + +#: ../../po/../src/document.cpp:524 +#, c-format +msgid "Unnamed document %d" +msgstr "" + +#. We hit green anchor, closing Green-Blue-Red +#: ../../po/../src/draw-context.cpp:441 +msgid "Path is closed." +msgstr "" + +#. We hit bot start and end of single curve, closing paths +#: ../../po/../src/draw-context.cpp:456 +msgid "Closing path." +msgstr "" + +#. alpha of color under cursor, to show in the statusbar +#. locale-sensitive printf is OK, since this goes to the UI, not into SVG +#: ../../po/../src/dropper-context.cpp:354 +#, c-format +msgid " alpha %.3g" +msgstr "" + +#. where the color is picked, to show in the statusbar +#: ../../po/../src/dropper-context.cpp:356 +#, c-format +msgid ", averaged with radius %d" +msgstr "" + +#: ../../po/../src/dropper-context.cpp:356 +msgid " under cursor" +msgstr "" + +#. message, to show in the statusbar +#: ../../po/../src/dropper-context.cpp:358 +msgid "Release mouse to set color." +msgstr "" + +#: ../../po/../src/dropper-context.cpp:358 +#: ../../po/../src/tools-switch.cpp:207 +msgid "" +"Click to set fill, Shift+click to set stroke; drag to " +"average color in area; with Alt to pick inverse color; Ctrl+C " +"to copy the color under mouse to clipboard" +msgstr "" + +#: ../../po/../src/extension/dependency.cpp:244 +msgid "Dependency::" +msgstr "" + +#: ../../po/../src/extension/dependency.cpp:245 +#, fuzzy +msgid " type: " +msgstr "Ainm comhad:" + +#: ../../po/../src/extension/dependency.cpp:246 +#, fuzzy +msgid " location: " +msgstr "Tóg" + +#: ../../po/../src/extension/dependency.cpp:247 +msgid " string: " +msgstr "" + +#: ../../po/../src/extension/dependency.cpp:250 +msgid " description: " +msgstr "" + +#. static int i = 0; +#. std::cout << "Checking module[" << i++ << "]: " << name << std::endl; +#: ../../po/../src/extension/extension.cpp:244 +msgid "" +" This is caused by an improper .inx file for this extension. An improper ." +"inx file could have been caused by a faulty installation of Inkscape." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:247 +msgid "an ID was not defined for it." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:251 +msgid "there was no name defined for it." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:255 +msgid "the XML description of it got lost." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:259 +msgid "no implementation was defined for the extension." +msgstr "" + +#. std::cout << "Failed: " << *(_deps[i]) << std::endl; +#: ../../po/../src/extension/extension.cpp:266 +msgid "a dependency was not met." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:286 +msgid "Extension \"" +msgstr "" + +#: ../../po/../src/extension/extension.cpp:286 +msgid "\" failed to load because " +msgstr "" + +#: ../../po/../src/extension/extension.cpp:565 +#, c-format +msgid "Could not create extension error log file '%s'" +msgstr "" + +#. This is some filler text, needs to change before relase +#: ../../po/../src/extension/error-file.cpp:56 +msgid "" +"One or more extensions failed to load\n" +"\n" +"The failed extensions have been skipped. Inkscape will continue to run " +"normally but those extensions will be unavailable. For details to " +"troubleshoot this problem, please refer to the error log located at: " +msgstr "" + +#. This is some filler text, needs to change before relase +#: ../../po/../src/extension/error-file.cpp:65 +msgid "Show dialog on startup" +msgstr "" + +#: ../../po/../src/extension/implementation/script.cpp:845 +msgid "" +"Inkscape has received an error from the script that it called. The text " +"returned with the error is included below. Inkscape will continue working, " +"but the action you requested has been cancelled." +msgstr "" + +#: ../../po/../src/extension/implementation/script.cpp:858 +msgid "" +"Inkscape has received additional data from the script executed. The script " +"did not return an error, but this may indicate the results will not be as " +"expected." +msgstr "" + +#: ../../po/../src/extension/init.cpp:173 +msgid "Null external module directory name. Modules will not be loaded." +msgstr "" + +#: ../../po/../src/extension/init.cpp:187 +#, c-format +msgid "" +"Modules directory (%s) is unavailable. External modules in that directory " +"will not be loaded." +msgstr "" + +#: ../../po/../src/extension/internal/gnome.cpp:80 +#, fuzzy +msgid "Select printer" +msgstr "Tóg" + +#: ../../po/../src/extension/internal/gnome.cpp:131 +#, fuzzy +msgid "Inkscape: Print Preview" +msgstr "Priontáil comhad" + +#: ../../po/../src/extension/internal/grid.cpp:213 +#, fuzzy +msgid "Line Width" +msgstr "Leitheid" + +#: ../../po/../src/extension/internal/grid.cpp:214 +#, fuzzy +msgid "Horizontal Spacing" +msgstr "Tóg" + +#: ../../po/../src/extension/internal/grid.cpp:215 +msgid "Vertical Spacing" +msgstr "" + +#: ../../po/../src/extension/internal/grid.cpp:216 +#, fuzzy +msgid "Horizontal Offset" +msgstr "Tóg" + +#: ../../po/../src/extension/internal/grid.cpp:217 +msgid "Vertical Offset" +msgstr "" + +#: ../../po/../src/extension/internal/ps.cpp:123 +#, fuzzy +msgid "Print Destination" +msgstr "Priontáil comhad" + +#. Print properties frame +#: ../../po/../src/extension/internal/ps.cpp:138 +#, fuzzy +msgid "Print properties" +msgstr "Priontáil comhad" + +#: ../../po/../src/extension/internal/ps.cpp:145 +msgid "Print using PostScript operators" +msgstr "" + +#: ../../po/../src/extension/internal/ps.cpp:147 +msgid "" +"Use PostScript vector operators. The resulting image is usually smaller in " +"file size and can be arbitrarily scaled, but alpha transparency and patterns " +"will be lost." +msgstr "" + +#: ../../po/../src/extension/internal/ps.cpp:152 +msgid "Print as bitmap" +msgstr "" + +#: ../../po/../src/extension/internal/ps.cpp:154 +msgid "" +"Print everything as bitmap. The resulting image is usually larger in file " +"size and cannot be arbitrarily scaled without quality loss, but all objects " +"will be rendered exactly as displayed." +msgstr "" + +#: ../../po/../src/extension/internal/ps.cpp:168 +msgid "Preferred resolution (dots per inch) of bitmap" +msgstr "" + +#: ../../po/../src/extension/internal/ps.cpp:182 +msgid "Resolution:" +msgstr "" + +#. Print destination frame +#: ../../po/../src/extension/internal/ps.cpp:186 +#, fuzzy +msgid "Print destination" +msgstr "Priontáil comhad" + +#: ../../po/../src/extension/internal/ps.cpp:192 +msgid "" +"Use '> filename' to print to file.\n" +"Use '| prog arg...' to pipe to a program." +msgstr "" + +#: ../../po/../src/extension/internal/ps.cpp:1227 +msgid "write error occurred" +msgstr "" + +#: ../../po/../src/extension/prefdialog.cpp:21 +#, fuzzy +msgid " Preferences" +msgstr "Sodipodi" + +#. We can't call sp_ui_error_dialog because we may be +#. running from the console, in which case calling sp_ui +#. routines will cause a segfault. See bug 1000350 - bryce +#. sp_ui_error_dialog(_("Format autodetect failed. The file is being opened as SVG.")); +#: ../../po/../src/extension/system.cpp:105 +msgid "Format autodetect failed. The file is being opened as SVG." +msgstr "" + +#. TRANSLATORS: default.svg is localizable - this is the name of the default document +#. template. This way you can localize the default pagesize, translate the name of +#. the default layer, etc. If you wish to localize this file, please create a +#. localized share/templates/default.xx.svg file, where xx is your language code. +#: ../../po/../src/file.cpp:133 +#, fuzzy +msgid "default.svg" +msgstr "Scríos" + +#: ../../po/../src/file.cpp:215 ../../po/../src/file.cpp:900 +#, c-format +msgid "Failed to load the requested file %s" +msgstr "" + +#: ../../po/../src/file.cpp:240 +#, fuzzy +msgid "Document not saved yet. Cannot revert." +msgstr "Roghanna Dath" + +#: ../../po/../src/file.cpp:246 +#, c-format +msgid "Changes will be lost! Are you sure you want to reload document %s?" +msgstr "" + +#: ../../po/../src/file.cpp:266 +#, fuzzy +msgid "Document reverted." +msgstr "Roghanna Dath" + +#: ../../po/../src/file.cpp:268 +#, fuzzy +msgid "Document not reverted." +msgstr "Roghanna Dath" + +#: ../../po/../src/file.cpp:382 +msgid "Select file to open" +msgstr "" + +#: ../../po/../src/file.cpp:518 +#, c-format +msgid "Removed %i unused definition in <defs>." +msgid_plural "Removed %i unused definitions in <defs>." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/file.cpp:523 +msgid "No unused definitions in <defs>." +msgstr "" + +#: ../../po/../src/file.cpp:548 +#, c-format +msgid "" +"No Inkscape extension found to save document (%s). This may have been " +"caused by an unknown filename extension." +msgstr "" + +#: ../../po/../src/file.cpp:549 ../../po/../src/file.cpp:557 +#, fuzzy +msgid "Document not saved." +msgstr "Roghanna Dath" + +#: ../../po/../src/file.cpp:556 +#, c-format +msgid "File %s could not be saved." +msgstr "" + +#: ../../po/../src/file.cpp:566 +#, fuzzy +msgid "Document saved." +msgstr "Roghanna Dath" + +#: ../../po/../src/file.cpp:614 +#, c-format +msgid "drawing%s" +msgstr "" + +#: ../../po/../src/file.cpp:620 +#, c-format +msgid "drawing-%d%s" +msgstr "" + +#: ../../po/../src/file.cpp:655 +#, fuzzy +msgid "Select file to save to" +msgstr "Tóg" + +#: ../../po/../src/file.cpp:739 +msgid "No changes need to be saved." +msgstr "" + +#: ../../po/../src/file.cpp:926 +msgid "Select file to import" +msgstr "" + +#: ../../po/../src/gradient-context.cpp:263 +msgid "Ctrl: snap gradient angle" +msgstr "" + +#: ../../po/../src/gradient-context.cpp:264 +msgid "Shift: draw gradient around the starting point" +msgstr "" + +#. We did an undoable action, but sp_document_done will be called by the knot when released +#. status text; we do not track coords because this branch is run once, not all the time +#. during drag +#: ../../po/../src/gradient-context.cpp:462 +#, c-format +msgid "Gradient for %d objects; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/gradient-context.cpp:464 +#, fuzzy +msgid "Select objects on which to create gradient." +msgstr "Tóg" + +#: ../../po/../src/gradient-drag.cpp:65 +msgid "Linear gradient start" +msgstr "" + +#. POINT_LG_P1 +#: ../../po/../src/gradient-drag.cpp:66 +msgid "Linear gradient end" +msgstr "" + +#: ../../po/../src/gradient-drag.cpp:67 +msgid "Radial gradient center" +msgstr "" + +#: ../../po/../src/gradient-drag.cpp:68 ../../po/../src/gradient-drag.cpp:69 +msgid "Radial gradient radius" +msgstr "" + +#: ../../po/../src/gradient-drag.cpp:70 +msgid "Radial gradient focus" +msgstr "" + +#: ../../po/../src/gradient-drag.cpp:659 +#, c-format +msgid "" +"%s for: %s%s; drag with Ctrl to snap angle, with Ctrl+Alt to " +"preserve angle, with Ctrl+Shift to scale around center" +msgstr "" + +#: ../../po/../src/gradient-drag.cpp:662 +msgid " (stroke)" +msgstr "" + +#: ../../po/../src/gradient-drag.cpp:665 +msgid "" +"Radial gradient center and focus; drag with Shift to " +"separate focus" +msgstr "" + +#: ../../po/../src/gradient-drag.cpp:667 +#, c-format +msgid "" +"Gradient point shared by %d gradients; drag with Shift to " +"separate" +msgstr "" + +#: ../../po/../src/helper/units.cpp:40 +msgid "Unit" +msgstr "" + +#: ../../po/../src/helper/units.cpp:40 +msgid "Units" +msgstr "" + +#: ../../po/../src/helper/units.cpp:41 +#, fuzzy +msgid "Point" +msgstr "Priontáil" + +#: ../../po/../src/helper/units.cpp:41 +msgid "pt" +msgstr "" + +#: ../../po/../src/helper/units.cpp:41 +#, fuzzy +msgid "Points" +msgstr "Priontáil" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Pt" +msgstr "" + +#: ../../po/../src/helper/units.cpp:42 +#, fuzzy +msgid "Pixel" +msgstr "pixelanna" + +#: ../../po/../src/helper/units.cpp:42 +#, fuzzy +msgid "Pixels" +msgstr "pixelanna" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Px" +msgstr "" + +#. You can add new elements from this point forward +#: ../../po/../src/helper/units.cpp:44 ../share/extensions/straightseg.inx.h:2 +#, fuzzy +msgid "Percent" +msgstr "Priontáil" + +#: ../../po/../src/helper/units.cpp:44 +#, fuzzy +msgid "Percents" +msgstr "Priontáil" + +#: ../../po/../src/helper/units.cpp:45 +msgid "Millimeter" +msgstr "" + +#: ../../po/../src/helper/units.cpp:45 +msgid "mm" +msgstr "" + +#: ../../po/../src/helper/units.cpp:45 +msgid "Millimeters" +msgstr "" + +#: ../../po/../src/helper/units.cpp:46 +msgid "Centimeter" +msgstr "" + +#: ../../po/../src/helper/units.cpp:46 +msgid "cm" +msgstr "" + +#: ../../po/../src/helper/units.cpp:46 +msgid "Centimeters" +msgstr "" + +#: ../../po/../src/helper/units.cpp:47 +msgid "Meter" +msgstr "" + +#: ../../po/../src/helper/units.cpp:47 +msgid "m" +msgstr "" + +#: ../../po/../src/helper/units.cpp:47 +msgid "Meters" +msgstr "" + +#. no svg_unit +#: ../../po/../src/helper/units.cpp:48 +msgid "Inch" +msgstr "" + +#: ../../po/../src/helper/units.cpp:48 +msgid "in" +msgstr "" + +#: ../../po/../src/helper/units.cpp:48 +msgid "Inches" +msgstr "" + +#. Volatiles do not have default, so there are none here +#. TRANSLATORS: for info, see http://www.w3.org/TR/REC-CSS2/syndata.html#length-units +#: ../../po/../src/helper/units.cpp:51 +msgid "Em square" +msgstr "" + +#: ../../po/../src/helper/units.cpp:51 +msgid "em" +msgstr "" + +#: ../../po/../src/helper/units.cpp:51 +msgid "Em squares" +msgstr "" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/REC-CSS2/syndata.html#length-units +#: ../../po/../src/helper/units.cpp:53 +msgid "Ex square" +msgstr "" + +#: ../../po/../src/helper/units.cpp:53 +#, fuzzy +msgid "ex" +msgstr "Teacs" + +#: ../../po/../src/helper/units.cpp:53 +msgid "Ex squares" +msgstr "" + +#: ../../po/../src/inkscape.cpp:468 +msgid "Untitled document" +msgstr "" + +#. Show nice dialog box +#: ../../po/../src/inkscape.cpp:497 +msgid "Inkscape encountered an internal error and will close now.\n" +msgstr "" + +#: ../../po/../src/inkscape.cpp:498 +msgid "" +"Automatic backups of unsaved documents were done to the following " +"locations:\n" +msgstr "" + +#: ../../po/../src/inkscape.cpp:499 +msgid "Automatic backup of the following documents failed:\n" +msgstr "" + +#: ../../po/../src/inkscape.cpp:634 +#, c-format +msgid "" +"Cannot create directory %s.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:635 +#, c-format +msgid "" +"%s is not a valid directory.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:636 +#, c-format +msgid "" +"Cannot create file %s.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:637 +#, c-format +msgid "" +"Cannot write file %s.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:638 +msgid "" +"Although Inkscape will run, it will use default settings,\n" +"and any changes made in preferences will not be saved." +msgstr "" + +#: ../../po/../src/inkscape.cpp:708 +#, c-format +msgid "" +"%s is not a regular file.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:709 +#, c-format +msgid "" +"%s not a valid XML file, or\n" +"you don't have read permissions on it.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:711 +#, c-format +msgid "" +"%s is not a valid menus file.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:712 +msgid "" +"Inkscape will run with default menus.\n" +"New menus will not be saved." +msgstr "" + +#. sp_ui_menu_append_check_item_from_verb(m, view, _("_Menu"), _("Show or hide the menu bar"), "menu", +#. checkitem_toggled, checkitem_update, 0); +#: ../../po/../src/interface.cpp:753 +msgid "Commands Bar" +msgstr "" + +#: ../../po/../src/interface.cpp:753 +msgid "Show or hide the Commands bar (under the menu)" +msgstr "" + +#: ../../po/../src/interface.cpp:755 +#, fuzzy +msgid "Tool Controls" +msgstr "Roghanna Oaf" + +#: ../../po/../src/interface.cpp:755 +msgid "Show or hide the Tool Controls panel" +msgstr "" + +#: ../../po/../src/interface.cpp:757 +msgid "_Toolbox" +msgstr "" + +#: ../../po/../src/interface.cpp:757 +msgid "Show or hide the main toolbox (on the left)" +msgstr "" + +#: ../../po/../src/interface.cpp:763 +msgid "_Statusbar" +msgstr "" + +#: ../../po/../src/interface.cpp:763 +msgid "Show or hide the statusbar (at the bottom of the window)" +msgstr "" + +#: ../../po/../src/interface.cpp:820 +#, c-format +msgid "Verb \"%s\" Unknown" +msgstr "" + +#. TRANSLATORS: #%s is the id of the group e.g. , not a number. +#: ../../po/../src/interface.cpp:930 +#, fuzzy, c-format +msgid "Enter group #%s" +msgstr "Eagar Nód" + +#: ../../po/../src/interface.cpp:941 +#, fuzzy +msgid "Go to parent" +msgstr "Priontáil" + +#: ../../po/../src/interface.cpp:972 +msgid "Could not parse SVG data" +msgstr "" + +#: ../../po/../src/interface.cpp:1135 +#, c-format +msgid "Overwrite %s" +msgstr "" + +#: ../../po/../src/interface.cpp:1153 +#, c-format +msgid "" +"The file %s already exists. Do you want to overwrite that file with the " +"current document?" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:59 +msgid "Jabber connection lost." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:72 +#, c-format +msgid "Sending message; %u message remaining in send queue." +msgid_plural "Sending message; %u messages remaining in send queue." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:78 +msgid "Receive queue empty." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:154 +#, c-format +msgid "Receiving change; %u change left to process." +msgid_plural "Receiving change; %u changes left to process." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:157 +#, c-format +msgid "%s has left the chatroom." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:221 +msgid "Nickname %1 is already in use. Please choose a different nickname." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:225 +msgid "An error was encountered while attempting to connect to the server." +msgstr "" + +#. Check to see if the user made any modifications to this document. If so, +#. we want to give them the option of (1) letting us clear their document or (2) +#. opening a new, blank document for the whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:131 +msgid "%1 has invited you to a whiteboard session." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:132 +msgid "Incoming whiteboard invitation from %1" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:135 +msgid "Do you wish to accept %1's whiteboard session invitation?" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:137 +msgid "" +"Would you like to accept %1's invitation in a new document window?\n" +"Accepting the invitation in your current window will discard unsaved changes." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:143 +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:198 +#, fuzzy +msgid "Accept invitation" +msgstr "Tóg" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:144 +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:199 +msgid "Decline invitation" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:145 +#, fuzzy +msgid "Accept invitation in new document window" +msgstr "Sábháil Comhad" + +#. We could not create a new desktop; ask the user if she or he wants to +#. replace the current document and accept the invitation, or reject the invitation. +#. TRANSLATORS: %1 is a userid here +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:196 +msgid "" +"A new document window could not be opened for a whiteboard session with %" +"1" +msgstr "" + +#. TRANSLATORS: %1 is the peer whom refused our invitation. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:238 +msgid "" +"The user %1 has refused your " +"whiteboard invitation.\n" +"\n" +msgstr "" + +#. TRANSLATORS: %1 is the peer whom refused our invitation, %2 is our Jabber identity. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:241 +msgid "" +"You are still connected to a Jabber server as %2, and may send an " +"invitation to %1 again, or you may send an invitation to a different " +"user." +msgstr "" + +#. TRANSLATORS: %1 is the peer whom we tried to contact, but is already in a whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:252 +msgid "" +"The user %1 is already in a " +"whiteboard session.\n" +"\n" +msgstr "" + +#. TRANSLATORS: %1 is the peer whom we tried to contact, but is already in a whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:255 +msgid "" +"You are still connected to a Jabber server as %1, and may send an " +"invitation to a different user." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/invitation-confirm-dialog.cpp:26 +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:24 +msgid "_Write session file:" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/message-processors.cpp:145 +#, c-format +msgid "%s has joined the chatroom." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/message-queue.cpp:87 +#, c-format +msgid "%u change in receive queue." +msgid_plural "%u changes in receive queue." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/jabber_whiteboard/message-queue.cpp:117 +#, c-format +msgid "%u change in send queue." +msgid_plural "%u changes in send queue." +msgstr[0] "" +msgstr[1] "" + +#. if ID is NULL, then we have a real problem -- we were not able to find a key +#. nor generate one. The only thing we can really do here is abort, since we have +#. no way to let the other client(s) uniquely identify this object. +#. FIXME: If this indicates a programming bug, then don't request translation with +#. * _(...): it is most useful in untranslated form so that developers may search for +#. * it when someone reports it in a bug report (as we want users to do for all bugs, +#. * as indicated by it being a g_warning string). +#. * +#. * Otherwise, if it is not a programming bug but a network error or a bug in the +#. * remote peer (perhaps running different software) or whatever, then present it in +#. * an alert box, and avoid use of technical jargon `NULL'. +#. +#: ../../po/../src/jabber_whiteboard/message-utilities.cpp:171 +msgid "" +"ID for new object is NULL even after generation and lookup attempts: the new " +"object will NOT be sent, nor will any of its child objects!" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:60 +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:995 +msgid "Select a location and filename" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:62 +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:997 +#, fuzzy +msgid "Set filename" +msgstr "ainm" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:301 +msgid "No SSL certificate was found." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:304 +msgid "The SSL certificate provided by the Jabber server is untrusted." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:307 +msgid "The SSL certificate provided by the Jabber server is expired." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:310 +msgid "" +"The SSL certificate provided by the Jabber server has not been activated." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:313 +msgid "" +"The SSL certificate provided by the Jabber server contains a hostname that " +"does not match the Jabber server's hostname." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:316 +msgid "" +"The SSL certificate provided by the Jabber server contains an invalid " +"fingerprint." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:319 +msgid "An unknown error occurred while setting up the SSL connection." +msgstr "" + +#. TRANSLATORS: %1 is the message that describes the specific error that occurred when +#. establishing the SSL connection. +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:325 +msgid "" +"%1\n" +"\n" +"Do you wish to continue connecting to the Jabber server?" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:328 +msgid "Continue connecting and ignore further errors" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:329 +msgid "Continue connecting, but warn me of further errors" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:330 +msgid "Cancel connection" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:777 +#, c-format +msgid "Established whiteboard session with %s." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:785 +#, c-format +msgid "%s has left the whiteboard session." +msgstr "" + +#. Inform the user +#. TRANSLATORS: %1 is the name of the user that disconnected, %2 is the name of the user whom the disconnected user disconnected from. +#. This message is not used in a chatroom context. +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:790 +msgid "" +"The user %1 has left the " +"whiteboard session.\n" +"\n" +msgstr "" + +#. TRANSLATORS: %1 and %2 are userids +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:792 +msgid "" +"You are still connected to a Jabber server as %2, and may establish a " +"new session to %1 or a different user." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:988 +msgid "" +"Could not open file %1 for session recording.\n" +"The error encountered was: %2.\n" +"\n" +"You may select a different location to record the session, or you may opt to " +"not record this session." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:990 +msgid "Choose a different location" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:991 +msgid "Skip session recording" +msgstr "" + +#: ../../po/../src/knot.cpp:673 +msgid "Node or handle drag canceled." +msgstr "" + +#: ../../po/../src/libnrtype/FontFactory.cpp:358 +msgid "Ignoring font without family that will crash Pango" +msgstr "" + +#: ../../po/../src/main.cpp:395 +msgid "Print the Inkscape version number" +msgstr "" + +#: ../../po/../src/main.cpp:400 +msgid "Do not use X server (only process files from console)" +msgstr "" + +#: ../../po/../src/main.cpp:405 +msgid "Try to use X server (even if $DISPLAY is not set)" +msgstr "" + +#: ../../po/../src/main.cpp:410 +msgid "Open specified document(s) (option string may be excluded)" +msgstr "" + +#: ../../po/../src/main.cpp:411 ../../po/../src/main.cpp:416 +#: ../../po/../src/main.cpp:421 ../../po/../src/main.cpp:483 +#: ../../po/../src/main.cpp:488 ../../po/../src/main.cpp:493 +msgid "FILENAME" +msgstr "AINM CHOMAD" + +#: ../../po/../src/main.cpp:415 +msgid "Print document(s) to specified output file (use '| program' for pipe)" +msgstr "" + +#: ../../po/../src/main.cpp:420 +msgid "Export document to a PNG file" +msgstr "" + +#: ../../po/../src/main.cpp:425 +msgid "The resolution used for exporting SVG into bitmap (default 90)" +msgstr "" + +#: ../../po/../src/main.cpp:426 +msgid "DPI" +msgstr "" + +#: ../../po/../src/main.cpp:430 +msgid "" +"Exported area in SVG user units (default is the canvas; 0,0 is lower-left " +"corner)" +msgstr "" + +#: ../../po/../src/main.cpp:431 +msgid "x0:y0:x1:y1" +msgstr "" + +#: ../../po/../src/main.cpp:435 +msgid "Exported area is the entire drawing (not canvas)" +msgstr "" + +#: ../../po/../src/main.cpp:440 +msgid "" +"Snap the bitmap export area outwards to the nearest integer values (in SVG " +"user units)" +msgstr "" + +#: ../../po/../src/main.cpp:445 +msgid "The width of exported bitmap in pixels (overrides export-dpi)" +msgstr "" + +#: ../../po/../src/main.cpp:446 +msgid "WIDTH" +msgstr "" + +#: ../../po/../src/main.cpp:450 +msgid "The height of exported bitmap in pixels (overrides export-dpi)" +msgstr "" + +#: ../../po/../src/main.cpp:451 +msgid "HEIGHT" +msgstr "" + +#: ../../po/../src/main.cpp:455 +msgid "The ID of the object to export (overrides export-area)" +msgstr "" + +#: ../../po/../src/main.cpp:456 ../../po/../src/main.cpp:532 +msgid "ID" +msgstr "" + +#. TRANSLATORS: this means: "Only export the object whose id is given in --export-id". +#. See "man inkscape" for details. +#: ../../po/../src/main.cpp:462 +msgid "" +"Export just the object with export-id, hide all others (only with export-id)" +msgstr "" + +#: ../../po/../src/main.cpp:467 +msgid "Use stored filename and DPI hints when exporting (only with export-id)" +msgstr "" + +#: ../../po/../src/main.cpp:472 +msgid "Background color of exported bitmap (any SVG-supported color string)" +msgstr "" + +#: ../../po/../src/main.cpp:473 +msgid "COLOR" +msgstr "" + +#: ../../po/../src/main.cpp:477 +msgid "Background opacity of exported bitmap (either 0.0 to 1.0, or 1 to 255)" +msgstr "" + +#: ../../po/../src/main.cpp:478 +msgid "VALUE" +msgstr "" + +#: ../../po/../src/main.cpp:482 +msgid "Export document to plain SVG file (no sodipodi or inkscape namespaces)" +msgstr "" + +#: ../../po/../src/main.cpp:487 +msgid "Export document to a PS file" +msgstr "" + +#: ../../po/../src/main.cpp:492 +msgid "Export document to an EPS file" +msgstr "" + +#: ../../po/../src/main.cpp:497 +#, fuzzy +msgid "Convert text object to paths on export (EPS)" +msgstr "Tóg" + +#: ../../po/../src/main.cpp:502 +msgid "Export files with the bounding box set to the page size (EPS)" +msgstr "" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:508 +msgid "" +"Query the X coordinate of the drawing or, if specified, of the object with --" +"query-id" +msgstr "" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:514 +msgid "" +"Query the Y coordinate of the drawing or, if specified, of the object with --" +"query-id" +msgstr "" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:520 +msgid "" +"Query the width of the drawing or, if specified, of the object with --query-" +"id" +msgstr "" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:526 +msgid "" +"Query the height of the drawing or, if specified, of the object with --query-" +"id" +msgstr "" + +#: ../../po/../src/main.cpp:531 +msgid "The ID of the object whose dimensions are queried" +msgstr "" + +#. TRANSLATORS: this option makes Inkscape print the name (path) of the extension directory +#: ../../po/../src/main.cpp:537 +msgid "Print out the extension directory and exit" +msgstr "" + +#: ../../po/../src/main.cpp:542 +msgid "Show given files one-by-one, switch to next on any key/mouse event" +msgstr "" + +#: ../../po/../src/main.cpp:547 +msgid "Use the new Gtkmm GUI interface" +msgstr "" + +#: ../../po/../src/main.cpp:552 +msgid "Remove unused definitions from the defs section(s) of the document" +msgstr "" + +#: ../../po/../src/main.cpp:741 +msgid "" +"[OPTIONS...] [FILE...]\n" +"\n" +"Available options:" +msgstr "" + +#: ../../po/../src/menus-skeleton.h:17 +#, fuzzy +msgid "_New" +msgstr "Nua" + +#: ../../po/../src/menus-skeleton.h:22 +#, fuzzy +msgid "Open _Recent" +msgstr "Oscáil" + +#: ../../po/../src/menus-skeleton.h:53 +#, fuzzy +msgid "_Edit" +msgstr "Eagar Nód" + +#: ../../po/../src/menus-skeleton.h:84 +#, fuzzy +msgid "_View" +msgstr "Radharc Nua" + +#: ../../po/../src/menus-skeleton.h:85 +#, fuzzy +msgid "_Zoom" +msgstr "Priontáil comhad" + +#: ../../po/../src/menus-skeleton.h:102 +#, fuzzy +msgid "Show/Hide" +msgstr "Leasú" + +#: ../../po/../src/menus-skeleton.h:107 +#, fuzzy +msgid "_Display mode" +msgstr "Roghanna Dath" + +#: ../../po/../src/menus-skeleton.h:126 +#, fuzzy +msgid "_Layer" +msgstr "Tóg" + +#: ../../po/../src/menus-skeleton.h:143 +#, fuzzy +msgid "_Object" +msgstr "Tóg" + +#: ../../po/../src/menus-skeleton.h:165 +#, fuzzy +msgid "_Path" +msgstr "Greamaigh" + +#: ../../po/../src/menus-skeleton.h:188 +#, fuzzy +msgid "_Text" +msgstr "Teacs" + +#: ../../po/../src/menus-skeleton.h:200 +msgid "Effects" +msgstr "" + +#: ../../po/../src/menus-skeleton.h:207 +msgid "Whiteboa_rd" +msgstr "" + +#: ../../po/../src/menus-skeleton.h:220 +#, fuzzy +msgid "_Help" +msgstr "Leasú" + +#: ../../po/../src/menus-skeleton.h:222 +msgid "Tutorials" +msgstr "" + +#: ../../po/../src/node-context.cpp:382 +msgid "" +"Ctrl: toggle node type, snap handle angle, move hor/vert; Ctrl" +"+Alt: move along handles" +msgstr "" + +#: ../../po/../src/node-context.cpp:383 +msgid "" +"Shift: toggle node selection, disable snapping, rotate both handles" +msgstr "" + +#: ../../po/../src/node-context.cpp:384 +msgid "Alt: lock handle length; Ctrl+Alt: move along handles" +msgstr "" + +#: ../../po/../src/nodepath.cpp:1399 ../../po/../src/nodepath.cpp:1411 +#: ../../po/../src/nodepath.cpp:1492 ../../po/../src/nodepath.cpp:1504 +msgid "To join, you must have two endnodes selected." +msgstr "" + +#: ../../po/../src/nodepath.cpp:1633 ../../po/../src/nodepath.cpp:1647 +msgid "" +"Select two non-endpoint nodes on a path between which to delete " +"segments." +msgstr "" + +#: ../../po/../src/nodepath.cpp:1743 +#, fuzzy +msgid "Cannot find path between nodes." +msgstr "Tóg" + +#: ../../po/../src/nodepath.cpp:2822 +#, c-format +msgid "" +"Node handle: angle %0.2f°, length %s; with Ctrl to snap " +"angle; with Alt to lock length; with Shift to rotate both " +"handles" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3351 +msgid "" +"Node: drag to edit the path; with Ctrl to snap to horizontal/" +"vertical; with Ctrl+Alt to snap to handles' directions" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3375 +msgid "" +"Node handle: drag to shape the curve; with Ctrl to snap angle; " +"with Alt to lock length; with Shift to rotate both handles" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3399 +msgid "" +"Node handle: drag to shape the curve; with Ctrl to snap angle; " +"with Alt to lock length; with Shift to rotate the opposite " +"handle in sync" +msgstr "" + +#. TRANSLATORS: "end" is an adjective here (NOT a verb) +#: ../../po/../src/nodepath.cpp:3591 +#, fuzzy +msgid "end node" +msgstr "Greamaigh" + +#. TRANSLATORS: "cusp" means "sharp" (cusp node); see also the Advanced Tutorial +#: ../../po/../src/nodepath.cpp:3596 +msgid "cusp" +msgstr "" + +#. TRANSLATORS: "smooth" is an adjective here +#: ../../po/../src/nodepath.cpp:3599 +msgid "smooth" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3601 +msgid "symmetric" +msgstr "" + +#. TRANSLATORS: "end" is an adjective here (NOT a verb) +#: ../../po/../src/nodepath.cpp:3607 +msgid "end node, handle retracted (drag with Shift to extend)" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3609 +msgid "one handle retracted (drag with Shift to extend)" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3612 +msgid "both handles retracted (drag with Shift to extend)" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3624 +msgid "Drag nodes or node handles; arrow keys to move nodes" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3625 +msgid "Drag the node or its handles; arrow keys to move the node" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3651 ../../po/../src/nodepath.cpp:3663 +#, fuzzy +msgid "Select a single object to edit its nodes or handles." +msgstr "Tóg" + +#: ../../po/../src/nodepath.cpp:3655 +#, c-format +msgid "" +"0 out of %i node selected. Click, Shift+click, " +"or drag around nodes to select." +msgid_plural "" +"0 out of %i nodes selected. Click, Shift+click, " +"or drag around nodes to select." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/nodepath.cpp:3661 +msgid "Drag the handles of the object to modify it." +msgstr "" + +#: ../../po/../src/nodepath.cpp:3669 +#, c-format +msgid "%i of %i node selected; %s. %s." +msgid_plural "%i of %i nodes selected; %s. %s." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/nodepath.cpp:3675 +#, c-format +msgid "%i of %i node selected. %s." +msgid_plural "%i of %i nodes selected. %s." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/object-edit.cpp:493 +msgid "" +"Adjust the horizontal rounding radius; with Ctrl to make the " +"vertical radius the same" +msgstr "" + +#: ../../po/../src/object-edit.cpp:499 +msgid "" +"Adjust the vertical rounding radius; with Ctrl to make the " +"horizontal radius the same" +msgstr "" + +#: ../../po/../src/object-edit.cpp:506 ../../po/../src/object-edit.cpp:513 +msgid "" +"Adjust the width and height of the rectangle; with Ctrl to " +"lock ratio or stretch in one dimension only" +msgstr "" + +#: ../../po/../src/object-edit.cpp:686 +msgid "Adjust ellipse width, with Ctrl to make circle" +msgstr "" + +#: ../../po/../src/object-edit.cpp:689 +msgid "Adjust ellipse height, with Ctrl to make circle" +msgstr "" + +#: ../../po/../src/object-edit.cpp:692 +msgid "" +"Position the start point of the arc or segment; with Ctrl to " +"snap angle; drag inside the ellipse for arc, outside for " +"segment" +msgstr "" + +#: ../../po/../src/object-edit.cpp:695 +msgid "" +"Position the end point of the arc or segment; with Ctrl to " +"snap angle; drag inside the ellipse for arc, outside for " +"segment" +msgstr "" + +#: ../../po/../src/object-edit.cpp:800 +msgid "" +"Adjust the tip radius of the star or polygon; with Shift to " +"round; with Alt to randomize" +msgstr "" + +#: ../../po/../src/object-edit.cpp:803 +msgid "" +"Adjust the base radius of the star; with Ctrl to keep star " +"rays radial (no skew); with Shift to round; with Alt to " +"randomize" +msgstr "" + +#: ../../po/../src/object-edit.cpp:967 +msgid "" +"Roll/unroll the spiral from inside; with Ctrl to snap angle; " +"with Alt to converge/diverge" +msgstr "" + +#: ../../po/../src/object-edit.cpp:969 +msgid "" +"Roll/unroll the spiral from outside; with Ctrl to snap angle; " +"with Shift to scale/rotate" +msgstr "" + +#: ../../po/../src/object-edit.cpp:1006 +msgid "Adjust the offset distance" +msgstr "" + +#. TRANSLATORS: This refers to the pattern that's inside the object +#: ../../po/../src/object-edit.cpp:1036 +msgid "Move the pattern fill inside the object" +msgstr "" + +#: ../../po/../src/object-edit.cpp:1038 +#, fuzzy +msgid "Scale the pattern fill uniformly" +msgstr "Tóg" + +#: ../../po/../src/object-edit.cpp:1040 +msgid "Rotate the pattern fill; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/object-edit.cpp:1065 +msgid "Drag to resize the flowed text frame" +msgstr "" + +#. Item dialog +#: ../../po/../src/object-ui.cpp:106 +#, fuzzy +msgid "Object _Properties" +msgstr "Meid pictiúr" + +#. Select item +#: ../../po/../src/object-ui.cpp:116 +#, fuzzy +msgid "_Select This" +msgstr "Tóg" + +#. Create link +#: ../../po/../src/object-ui.cpp:126 +msgid "_Create Link" +msgstr "" + +#. "Ungroup" +#: ../../po/../src/object-ui.cpp:199 ../../po/../src/verbs.cpp:1931 +#, fuzzy +msgid "_Ungroup" +msgstr "_Grupa" + +#. Link dialog +#: ../../po/../src/object-ui.cpp:239 +#, fuzzy +msgid "Link _Properties" +msgstr "Priontáil comhad" + +#. Select item +#: ../../po/../src/object-ui.cpp:249 +msgid "_Follow Link" +msgstr "" + +#. Reset transformations +#: ../../po/../src/object-ui.cpp:254 +msgid "_Remove Link" +msgstr "" + +#. Link dialog +#: ../../po/../src/object-ui.cpp:303 +#, fuzzy +msgid "Image _Properties" +msgstr "Meid pictiúr" + +#. Item dialog +#: ../../po/../src/object-ui.cpp:344 +#, fuzzy +msgid "_Fill and Stroke" +msgstr "Roghanna Dath" + +#: ../../po/../src/path-chemistry.cpp:58 +#, fuzzy +msgid "Select at least two objects to combine." +msgstr "Tóg" + +#: ../../po/../src/path-chemistry.cpp:65 +#, fuzzy +msgid "At least one of the objects is not a path, cannot combine." +msgstr "Tóg" + +#: ../../po/../src/path-chemistry.cpp:73 +msgid "" +"You cannot combine objects from different groups or layers." +msgstr "" + +#: ../../po/../src/path-chemistry.cpp:155 +#, fuzzy +msgid "Select path(s) to break apart." +msgstr "Tóg" + +#: ../../po/../src/path-chemistry.cpp:231 +msgid "No path(s) to break apart in the selection." +msgstr "" + +#: ../../po/../src/path-chemistry.cpp:252 +#, fuzzy +msgid "Select object(s) to convert to path." +msgstr "Tóg" + +#: ../../po/../src/path-chemistry.cpp:297 +#, fuzzy +msgid "No objects to convert to path in the selection." +msgstr "Tóg" + +#: ../../po/../src/path-chemistry.cpp:345 +#, fuzzy +msgid "Select path(s) to reverse." +msgstr "Tóg" + +#: ../../po/../src/path-chemistry.cpp:370 +msgid "No paths to reverse in the selection." +msgstr "" + +#: ../../po/../src/pen-context.cpp:379 ../../po/../src/pencil-context.cpp:233 +#, fuzzy +msgid "Continuing selected path" +msgstr "Tóg" + +#: ../../po/../src/pen-context.cpp:390 ../../po/../src/pencil-context.cpp:242 +#, fuzzy +msgid "Creating new path" +msgstr "Sábháil Comhad" + +#: ../../po/../src/pen-context.cpp:394 ../../po/../src/pencil-context.cpp:246 +#, fuzzy +msgid "Appending to selected path" +msgstr "Tóg" + +#: ../../po/../src/pen-context.cpp:538 +msgid "Click or click and drag to close and finish the path." +msgstr "" + +#: ../../po/../src/pen-context.cpp:548 +msgid "" +"Click or click and drag to continue the path from this point." +msgstr "" + +#: ../../po/../src/pen-context.cpp:857 +#, c-format +msgid "" +"%s: angle %3.2f°, distance %s; with Ctrl to snap angle, " +"Enter to finish the path" +msgstr "" + +#: ../../po/../src/pen-context.cpp:882 +#, c-format +msgid "" +"Curve handle: angle %3.2f°, length %s; with Ctrl to snap " +"angle" +msgstr "" + +#: ../../po/../src/pen-context.cpp:912 +#, c-format +msgid "" +"%s: angle %3.2f°, length %s; with Ctrl to snap angle, " +"with Shift to move this handle only" +msgstr "" + +#: ../../po/../src/pen-context.cpp:946 +msgid "Finishing pen" +msgstr "" + +#: ../../po/../src/pencil-context.cpp:320 +msgid "Release here to close and finish the path." +msgstr "" + +#: ../../po/../src/pencil-context.cpp:326 +#, fuzzy +msgid "Drawing a freehand path" +msgstr "Sábháil Comhad" + +#: ../../po/../src/pencil-context.cpp:331 +msgid "Drag to continue the path from this point." +msgstr "" + +#. Write curves to object +#: ../../po/../src/pencil-context.cpp:390 +msgid "Finishing freehand" +msgstr "" + +#: ../../po/../src/rect-context.cpp:387 +msgid "" +"Ctrl: make square or integer-ratio rect, lock a rounded corner " +"circular" +msgstr "" + +#: ../../po/../src/rect-context.cpp:549 +#, c-format +msgid "" +"Rectangle: %s × %s; with Ctrl to make square or integer-" +"ratio rectangle; with Shift to draw around the starting point" +msgstr "" + +#: ../../po/../src/select-context.cpp:243 +msgid "Move canceled." +msgstr "" + +#: ../../po/../src/select-context.cpp:252 +#, fuzzy +msgid "Selection canceled." +msgstr "Tóg" + +#: ../../po/../src/select-context.cpp:642 +msgid "Ctrl: select in groups, move hor/vert" +msgstr "" + +#: ../../po/../src/select-context.cpp:643 +msgid "Shift: toggle select, force rubberband, disable snapping" +msgstr "" + +#: ../../po/../src/select-context.cpp:644 +msgid "Alt: select under, move selected" +msgstr "" + +#: ../../po/../src/select-context.cpp:798 +#, fuzzy +msgid "Selected object is not a group. Cannot enter." +msgstr "Tóg" + +#: ../../po/../src/select-context.cpp:876 +#, c-format +msgid "" +"Move by %s, %s; with Ctrl to restrict to horizontal/vertical; " +"with Shift to disable snapping" +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:228 +msgid "Nothing was deleted." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:259 +#, fuzzy +msgid "Select object(s) to duplicate." +msgstr "Tóg" + +#: ../../po/../src/selection-chemistry.cpp:420 +#, fuzzy +msgid "Select two or more objects to group." +msgstr "Tóg" + +#: ../../po/../src/selection-chemistry.cpp:428 +#, fuzzy +msgid "Select at least two objects to group." +msgstr "Tóg" + +#: ../../po/../src/selection-chemistry.cpp:513 +#, fuzzy +msgid "Select a group to ungroup." +msgstr "Tóg" + +#: ../../po/../src/selection-chemistry.cpp:554 +msgid "No groups to ungroup in the selection." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:623 +#, fuzzy +msgid "Select objects to raise." +msgstr "Tóg" + +#: ../../po/../src/selection-chemistry.cpp:629 +#: ../../po/../src/selection-chemistry.cpp:681 +#: ../../po/../src/selection-chemistry.cpp:715 +#: ../../po/../src/selection-chemistry.cpp:773 +msgid "" +"You cannot raise/lower objects from different groups or layers." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:673 +#, fuzzy +msgid "Select object(s) to raise to top." +msgstr "Tóg" + +#: ../../po/../src/selection-chemistry.cpp:709 +#, fuzzy +msgid "Select object(s) to lower." +msgstr "Tóg" + +#: ../../po/../src/selection-chemistry.cpp:765 +#, fuzzy +msgid "Select object(s) to lower to bottom." +msgstr "Tóg" + +#: ../../po/../src/selection-chemistry.cpp:806 +msgid "Nothing to undo." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:813 +msgid "Nothing to redo." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:969 +msgid "Nothing was copied." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1051 +msgid "Current layer is hidden. Unhide it to be able to paste to it." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1055 +msgid "Current layer is locked. Unlock it to be able to paste to it." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1068 +#: ../../po/../src/selection-chemistry.cpp:1103 +#, fuzzy +msgid "Nothing on the clipboard." +msgstr "Tóg" + +#: ../../po/../src/selection-chemistry.cpp:1109 +#, fuzzy +msgid "Select object(s) to paste style to." +msgstr "Tóg" + +#: ../../po/../src/selection-chemistry.cpp:1128 +#, fuzzy +msgid "Select object(s) to move to the layer above." +msgstr "Tóg" + +#: ../../po/../src/selection-chemistry.cpp:1146 +#, fuzzy +msgid "No more layers above." +msgstr "Roghanna Dath" + +#: ../../po/../src/selection-chemistry.cpp:1160 +#, fuzzy +msgid "Select object(s) to move to the layer below." +msgstr "Tóg" + +#: ../../po/../src/selection-chemistry.cpp:1178 +#, fuzzy +msgid "No more layers below." +msgstr "Roghanna Dath" + +#: ../../po/../src/selection-chemistry.cpp:1811 +#, fuzzy +msgid "Select a clone to unlink." +msgstr "Tóg" + +#: ../../po/../src/selection-chemistry.cpp:1842 +msgid "No clones to unlink in the selection." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1859 +msgid "" +"Select a clone to go to its original. Select a linked offset " +"to go to its source. Select a text on path to go to the path. Select " +"a flowed text to go to its frame." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1882 +msgid "" +"Cannot find the object to select (orphaned clone, offset, textpath, " +"flowed text?)" +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1888 +msgid "" +"The object you're trying to select is not visible (it is in <" +"defs>)" +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1915 +#, fuzzy +msgid "Select object(s) to convert to pattern." +msgstr "Tóg" + +#: ../../po/../src/selection-chemistry.cpp:2006 +#, fuzzy +msgid "Select an object with pattern fill to extract objects from." +msgstr "Tóg" + +#: ../../po/../src/selection-chemistry.cpp:2059 +#, fuzzy +msgid "No pattern fills in the selection." +msgstr "Tóg" + +#: ../../po/../src/selection-chemistry.cpp:2079 +#, fuzzy +msgid "Select object(s) to make a bitmap copy." +msgstr "Tóg" + +#: ../../po/../src/selection-describer.cpp:37 +msgid "Click selection to toggle scale/rotation handles" +msgstr "" + +#. no items +#: ../../po/../src/selection-describer.cpp:39 +msgid "" +"No objects selected. Click, Shift+click, or drag around objects to select." +msgstr "" + +#: ../../po/../src/selection-describer.cpp:51 +#, fuzzy, c-format +msgid " in layer %s" +msgstr "Greamaigh" + +#: ../../po/../src/selection-describer.cpp:54 +#, fuzzy, c-format +msgid " in layer %s" +msgstr "Greamaigh" + +#: ../../po/../src/selection-describer.cpp:66 +msgid "Use Shift+D to look up original" +msgstr "" + +#: ../../po/../src/selection-describer.cpp:70 +msgid "Use Shift+D to look up path" +msgstr "" + +#: ../../po/../src/selection-describer.cpp:74 +msgid "Use Shift+D to look up frame" +msgstr "" + +#: ../../po/../src/selection-describer.cpp:84 +#, c-format +msgid "%i object selected" +msgid_plural "%i objects selected" +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/selection-describer.cpp:90 +#, c-format +msgid "%s%s. %s." +msgstr "" + +#: ../../po/../src/selection-describer.cpp:94 +#, c-format +msgid "%s in %i layer. %s." +msgid_plural "%s in %i layers. %s." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/seltrans.cpp:498 +msgid "" +"Center of rotation and skewing: drag to reposition; scaling with " +"Shift also uses this center" +msgstr "" + +#: ../../po/../src/seltrans.cpp:514 +msgid "" +"Squeeze or stretch selection; with Ctrl to scale uniformly; " +"with Shift to scale around rotation center" +msgstr "" + +#: ../../po/../src/seltrans.cpp:515 +msgid "" +"Scale selection; with Ctrl to scale uniformly; with Shift to scale around rotation center" +msgstr "" + +#: ../../po/../src/seltrans.cpp:519 +msgid "" +"Skew selection; with Ctrl to snap angle; with Shift to " +"skew around the opposite side" +msgstr "" + +#: ../../po/../src/seltrans.cpp:520 +msgid "" +"Rotate selection; with Ctrl to snap angle; with Shift " +"to rotate around the opposite corner" +msgstr "" + +#: ../../po/../src/seltrans.cpp:829 ../../po/../src/seltrans.cpp:909 +#, c-format +msgid "Scale: %0.2f%% x %0.2f%%; with Ctrl to lock ratio" +msgstr "" + +#. TRANSLATORS: don't modify the first ";" (it will NOT be displayed as ";" - only the second one will be) +#: ../../po/../src/seltrans.cpp:984 +#, c-format +msgid "Skew: %0.2f°; with Ctrl to snap angle" +msgstr "" + +#. TRANSLATORS: don't modify the first ";" (it will NOT be displayed as ";" - only the second one will be) +#: ../../po/../src/seltrans.cpp:1035 +#, c-format +msgid "Rotate: %0.2f°; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/seltrans.cpp:1090 +#, fuzzy, c-format +msgid "Move center to %s, %s" +msgstr "Nód" + +#: ../../po/../src/slideshow.cpp:90 +#, fuzzy +msgid "Inkscape slideshow" +msgstr "Sodipodi" + +#: ../../po/../src/sp-anchor.cpp:181 +#, c-format +msgid "Link to %s" +msgstr "" + +#: ../../po/../src/sp-anchor.cpp:185 +msgid "Link without URI" +msgstr "" + +#: ../../po/../src/sp-ellipse.cpp:438 ../../po/../src/sp-ellipse.cpp:870 +msgid "Ellipse" +msgstr "" + +#: ../../po/../src/sp-ellipse.cpp:583 +msgid "Circle" +msgstr "" + +#: ../../po/../src/sp-ellipse.cpp:865 +#, fuzzy +msgid "Segment" +msgstr "Priontáil" + +#: ../../po/../src/sp-ellipse.cpp:867 +msgid "Arc" +msgstr "" + +#. TRANSLATORS: "Flow region" is an area where text is allowed to flow +#: ../../po/../src/sp-flowregion.cpp:276 +msgid "Flow region" +msgstr "" + +#. TRANSLATORS: A region "cut out of" a flow region; text is not allowed to flow inside the +#. * flow excluded region. flowRegionExclude in SVG 1.2: see +#. * http://www.w3.org/TR/2004/WD-SVG12-20041027/flow.html#flowRegion-elem and +#. * http://www.w3.org/TR/2004/WD-SVG12-20041027/flow.html#flowRegionExclude-elem. +#: ../../po/../src/sp-flowregion.cpp:493 +msgid "Flow excluded region" +msgstr "" + +#: ../../po/../src/sp-flowtext.cpp:355 +#, c-format +msgid "Flowed text (%d characters)" +msgstr "" + +#: ../../po/../src/sp-flowtext.cpp:357 +#, c-format +msgid "Linked flowed text (%d characters)" +msgstr "" + +#: ../../po/../src/sp-guide.cpp:290 +msgid "vertical guideline" +msgstr "" + +#: ../../po/../src/sp-guide.cpp:292 +#, fuzzy +msgid "horizontal guideline" +msgstr "Tóg" + +#: ../../po/../src/sp-image.cpp:835 +msgid "embedded" +msgstr "" + +#: ../../po/../src/sp-image.cpp:839 +msgid "(null_pointer)" +msgstr "" + +#: ../../po/../src/sp-image.cpp:843 +#, c-format +msgid "Image with bad reference: %s" +msgstr "" + +#: ../../po/../src/sp-image.cpp:844 +#, c-format +msgid "Image %d × %d: %s" +msgstr "" + +#: ../../po/../src/sp-item-group.cpp:390 +#, c-format +msgid "Group of %d object" +msgid_plural "Group of %d objects" +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/sp-item.cpp:720 +msgid "Object" +msgstr "" + +#: ../../po/../src/sp-line.cpp:202 +#, fuzzy +msgid "Line" +msgstr "Priontáil" + +#. TRANSLATORS COMMENT: %s is either "outset" or "inset" depending on sign +#: ../../po/../src/sp-offset.cpp:433 +#, c-format +msgid "Linked offset, %s by %f pt" +msgstr "" + +#: ../../po/../src/sp-offset.cpp:434 ../../po/../src/sp-offset.cpp:438 +#, fuzzy +msgid "outset" +msgstr "Tóg" + +#: ../../po/../src/sp-offset.cpp:434 ../../po/../src/sp-offset.cpp:438 +#, fuzzy +msgid "inset" +msgstr "Priontáil" + +#. TRANSLATORS COMMENT: %s is either "outset" or "inset" depending on sign +#: ../../po/../src/sp-offset.cpp:437 +#, c-format +msgid "Dynamic offset, %s by %f pt" +msgstr "" + +#: ../../po/../src/sp-path.cpp:127 +#, fuzzy, c-format +msgid "Path (%i node)" +msgid_plural "Path (%i nodes)" +msgstr[0] "Nód" +msgstr[1] "Nód" + +#: ../../po/../src/sp-polygon.cpp:216 +#, fuzzy +msgid "Polygon" +msgstr "Priontáil" + +#: ../../po/../src/sp-polyline.cpp:179 +#, fuzzy +msgid "Polyline" +msgstr "Priontáil" + +#: ../../po/../src/sp-rect.cpp:250 +#, fuzzy +msgid "Rectangle" +msgstr "Priontáil" + +#. TRANSLATORS: since turn count isn't an integer, please adjust the +#. string as needed to deal with an localized plural forms. +#: ../../po/../src/sp-spiral.cpp:305 +#, c-format +msgid "Spiral with %3f turns" +msgstr "" + +#: ../../po/../src/sp-star.cpp:288 +#, c-format +msgid "Star with %d vertex" +msgid_plural "Star with %d vertices" +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/sp-star.cpp:292 +#, c-format +msgid "Polygon with %d vertex" +msgid_plural "Polygon with %d vertices" +msgstr[0] "" +msgstr[1] "" + +#. TRANSLATORS: For description of font with no name. +#: ../../po/../src/sp-text.cpp:420 +msgid "<no name found>" +msgstr "" + +#: ../../po/../src/sp-text.cpp:426 +#, fuzzy, c-format +msgid "Text on path (%s, %s)" +msgstr "Nód" + +#: ../../po/../src/sp-text.cpp:427 +#, fuzzy, c-format +msgid "Text (%s, %s)" +msgstr "Nód" + +#. TRANSLATORS: Used for statusbar description for long chains: +#. * "Clone of: Clone of: ... in Layer 1". +#: ../../po/../src/sp-use.cpp:317 +#, fuzzy +msgid "..." +msgstr "Oscáil" + +#: ../../po/../src/sp-use.cpp:325 +#, c-format +msgid "Clone of: %s" +msgstr "" + +#: ../../po/../src/sp-use.cpp:329 +msgid "Orphaned clone" +msgstr "" + +#: ../../po/../src/spiral-context.cpp:355 +msgid "Ctrl: snap angle" +msgstr "" + +#: ../../po/../src/spiral-context.cpp:357 +msgid "Alt: lock spiral radius" +msgstr "" + +#: ../../po/../src/spiral-context.cpp:469 +#, c-format +msgid "" +"Spiral: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/splivarot.cpp:106 +#, fuzzy +msgid "Select at least 2 paths to perform a boolean operation." +msgstr "Tóg" + +#: ../../po/../src/splivarot.cpp:112 +msgid "" +"Select exactly 2 paths to perform difference, XOR, division, or path " +"cut." +msgstr "" + +#: ../../po/../src/splivarot.cpp:129 ../../po/../src/splivarot.cpp:144 +msgid "" +"Unable to determine the z-order of the objects selected for " +"difference, XOR, division, or path cut." +msgstr "" + +#: ../../po/../src/splivarot.cpp:174 +#, fuzzy +msgid "" +"One of the objects is not a path, cannot perform boolean operation." +msgstr "Tóg" + +#. TRANSLATORS: "to outline" means "to convert stroke to path" +#: ../../po/../src/splivarot.cpp:554 +#, fuzzy +msgid "Select path(s) to outline." +msgstr "Tóg" + +#. TRANSLATORS: "to outline" means "to convert stroke to path" +#: ../../po/../src/splivarot.cpp:748 +msgid "No stroked paths to outline in the selection." +msgstr "" + +#: ../../po/../src/splivarot.cpp:832 +#, fuzzy +msgid "Selected object is not a path, cannot inset/outset." +msgstr "Tóg" + +#: ../../po/../src/splivarot.cpp:1040 +#, fuzzy +msgid "Select path(s) to inset/outset." +msgstr "Tóg" + +#: ../../po/../src/splivarot.cpp:1257 +msgid "No paths to inset/outset in the selection." +msgstr "" + +#: ../../po/../src/splivarot.cpp:1390 +#, fuzzy +msgid "Select path(s) to simplify." +msgstr "Tóg" + +#: ../../po/../src/splivarot.cpp:1417 +msgid "No paths to simplify in the selection." +msgstr "" + +#: ../../po/../src/star-context.cpp:362 +msgid "Ctrl: snap angle; keep rays radial" +msgstr "" + +#: ../../po/../src/star-context.cpp:470 +#, c-format +msgid "" +"Polygon: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/star-context.cpp:471 +#, c-format +msgid "Star: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/text-chemistry.cpp:90 +#, fuzzy +msgid "Select a text and a path to put text on path." +msgstr "Tóg" + +#: ../../po/../src/text-chemistry.cpp:95 +msgid "" +"This text object is already put to a path. Remove it from the path " +"first. Use Shift+D to look up its path." +msgstr "" + +#. rect is the only SPShape which is not yet, and thus SVG forbids us from putting text on it +#: ../../po/../src/text-chemistry.cpp:101 +msgid "" +"You cannot put text on a rectangle in this version. Convert rectangle to " +"path first." +msgstr "" + +#: ../../po/../src/text-chemistry.cpp:159 +#, fuzzy +msgid "Select a text on path to remove it from path." +msgstr "Tóg" + +#: ../../po/../src/text-chemistry.cpp:181 +#, fuzzy +msgid "No texts-on-paths in the selection." +msgstr "Tóg" + +#: ../../po/../src/text-chemistry.cpp:209 +#: ../../po/../src/text-chemistry.cpp:229 +#, fuzzy +msgid "Select text(s) to remove kerns from." +msgstr "Tóg" + +#: ../../po/../src/text-chemistry.cpp:250 +#, fuzzy +msgid "" +"Select a text and one or more paths or shapes to flow text " +"into frame." +msgstr "Tóg" + +#: ../../po/../src/text-chemistry.cpp:322 +#, fuzzy +msgid "Select a flowed text to unflow it." +msgstr "Tóg" + +#: ../../po/../src/text-context.cpp:463 +msgid "Click to edit the text, drag to select part of the text." +msgstr "" + +#: ../../po/../src/text-context.cpp:465 +msgid "" +"Click to edit the flowed text, drag to select part of the text." +msgstr "" + +#: ../../po/../src/text-context.cpp:540 +msgid "Non-printable character" +msgstr "" + +#: ../../po/../src/text-context.cpp:589 +#, c-format +msgid "Unicode: %s: %s" +msgstr "" + +#: ../../po/../src/text-context.cpp:591 ../../po/../src/text-context.cpp:855 +msgid "Unicode: " +msgstr "" + +#: ../../po/../src/text-context.cpp:615 +msgid "Current layer is hidden. Unhide it to be able to add text." +msgstr "" + +#: ../../po/../src/text-context.cpp:619 +msgid "Current layer is locked. Unlock it to be able to add text." +msgstr "" + +#: ../../po/../src/text-context.cpp:673 +#, c-format +msgid "Flowed text frame: %s × %s" +msgstr "" + +#: ../../po/../src/text-context.cpp:708 ../../po/../src/text-context.cpp:1464 +msgid "Type text; Enter to start new line." +msgstr "" + +#: ../../po/../src/text-context.cpp:719 +msgid "Flowed text is created." +msgstr "" + +#: ../../po/../src/text-context.cpp:722 +msgid "" +"The frame is too small for the current font size. Flowed text not " +"created." +msgstr "" + +#: ../../po/../src/text-context.cpp:841 +msgid "No-break space" +msgstr "" + +#: ../../po/../src/text-context.cpp:1462 +msgid "Type flowed text; Enter to start new paragraph." +msgstr "" + +#: ../../po/../src/text-context.cpp:1472 ../../po/../src/tools-switch.cpp:189 +msgid "" +"Click to select or create text, drag to create flowed text; " +"then type." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:141 +msgid "" +"To edit a path, click, Shift+click, or drag around " +"nodes to select them, then drag nodes and handles. Click on an " +"object to select." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:147 +msgid "" +"Drag to create a rectangle. Drag controls to round corners and " +"resize. Click to select." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:153 +msgid "" +"Drag to create an ellipse. Drag controls to make an arc or " +"segment. Click to select." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:159 +msgid "" +"Drag to create a star. Drag controls to edit the star shape. " +"Click to select." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:165 +msgid "" +"Drag to create a spiral. Drag controls to edit the spiral " +"shape. Click to select." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:171 +msgid "" +"Drag to create a freehand line. Start drawing with Shift to " +"append to selected path." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:177 +msgid "" +"Click or click and drag to start a path; with Shift to " +"append to selected path." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:183 +msgid "" +"Drag to paint a calligraphic stroke. Left/right arrow " +"keys adjust width, up/down adjust angle." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:195 +msgid "" +"Drag or double click to create a gradient on selected objects, " +"drag handles to adjust gradients." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:201 +msgid "" +"Click or drag around an area to zoom in, Shift+click to " +"zoom out." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:213 +msgid "Click and drag between shapes to create a connector." +msgstr "" + +#: ../../po/../src/trace/potrace/inkscape-potrace.cpp:553 +#: ../../po/../src/trace/potrace/inkscape-potrace.cpp:654 +#, c-format +msgid "Trace: %d. %ld nodes" +msgstr "" + +#: ../../po/../src/trace/trace.cpp:53 ../../po/../src/trace/trace.cpp:62 +#: ../../po/../src/trace/trace.cpp:70 +#, fuzzy +msgid "Select an image to trace" +msgstr "Tóg" + +#: ../../po/../src/trace/trace.cpp:133 +#, fuzzy +msgid "Trace: No active document" +msgstr "Sábháil Comhad" + +#: ../../po/../src/trace/trace.cpp:154 +msgid "Trace: Image has no bitmap data" +msgstr "" + +#: ../../po/../src/trace/trace.cpp:267 +#, fuzzy, c-format +msgid "Trace: Done. %ld nodes created" +msgstr "Priontáil comhad" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:59 ../../po/../src/verbs.cpp:2212 +msgid "About Inkscape" +msgstr "" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:66 +msgid "_Splash" +msgstr "" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:68 +msgid "_Authors" +msgstr "" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:69 +#, fuzzy +msgid "_Translators" +msgstr "Roghanna Oaf" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:70 +#, fuzzy +msgid "_License" +msgstr "Priontáil" + +#. TRANSLATORS: This is the filename of the `About Inkscape' picture in +#. the `screens' directory. Thus the translation of "about.svg" should be +#. the filename of its translated version, e.g. about.zh.svg for Chinese. +#. +#. N.B. about.svg changes once per release. (We should probably rename +#. the original to about-0.40.svg etc. as soon as we have a translation. +#. If we do so, then add an item to release-checklist saying that the +#. string here should be changed.) +#. FIXME? INKSCAPE_SCREENSDIR and "about.svg" are in UTF-8, not the +#. native filename encoding... and the filename passed to sp_document_new +#. should be in UTF-*8.. +#: ../../po/../src/ui/dialog/aboutbox.cpp:114 +msgid "about.svg" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:464 +msgid "Minimum horizontal gap (in px units) between bounding boxes" +msgstr "" + +#. TRANSLATORS: Horizontal gap +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:466 +#: ../../po/../src/widgets/toolbox.cpp:1556 +msgid "H:" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:474 +msgid "Minimum vertical gap (in px units) between bounding boxes" +msgstr "" + +#. TRANSLATORS: Vertical gap +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:476 +msgid "V:" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:734 +msgid "Align" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:735 +msgid "Distribute" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:736 +msgid "Remove overlaps" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:737 +#, fuzzy +msgid "Nodes" +msgstr "Nód" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:742 +#, fuzzy +msgid "Relative to: " +msgstr "Greamaigh" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:747 +#, fuzzy +msgid "Align right sides of objects to left side of anchor" +msgstr "Tóg" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:750 +#, fuzzy +msgid "Align left sides" +msgstr "Nódanna" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:753 +msgid "Center on vertical axis" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:756 +#, fuzzy +msgid "Align right sides" +msgstr "Nódanna" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:759 +#, fuzzy +msgid "Align left sides of objects to right side of anchor" +msgstr "Tóg" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:762 +#, fuzzy +msgid "Align bottoms of objects to top of anchor" +msgstr "Tóg" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:765 +#, fuzzy +msgid "Align tops" +msgstr "Nódanna" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:768 +#, fuzzy +msgid "Center on horizontal axis" +msgstr "Tóg" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:771 +#, fuzzy +msgid "Align bottoms" +msgstr "Nódanna" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:774 +#, fuzzy +msgid "Align tops of objects to bottom of anchor" +msgstr "Tóg" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:779 +#, fuzzy +msgid "Align baseline anchors of texts vertically" +msgstr "Tóg" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:782 +#, fuzzy +msgid "Align baseline anchors of texts horizontally" +msgstr "Tóg" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:787 +msgid "Make horizontal gaps between objects equal" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:791 +#, fuzzy +msgid "Distribute left sides equidistantly" +msgstr "Tóg" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:794 +#, fuzzy +msgid "Distribute centers equidistantly horizontally" +msgstr "Tóg" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:797 +#, fuzzy +msgid "Distribute right sides equidistantly" +msgstr "Tóg" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:801 +msgid "Make vertical gaps between objects equal" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:805 +#, fuzzy +msgid "Distribute tops equidistantly" +msgstr "Tóg" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:808 +#, fuzzy +msgid "Distribute centers equidistantly vertically" +msgstr "Tóg" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:811 +msgid "Distribute bottoms equidistantly" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:816 +#, fuzzy +msgid "Distribute baseline anchors of texts horizontally" +msgstr "Tóg" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:819 +#, fuzzy +msgid "Distribute baseline anchors of texts vertically" +msgstr "Tóg" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:824 +msgid "Randomize centers in both dimensions" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:827 +msgid "Unclump objects: try to equalize edge-to-edge distances" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:832 +msgid "" +"Move objects as little as possible so that their bounding boxes do not " +"overlap" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:837 +#, fuzzy +msgid "Align selected nodes horizontally" +msgstr "Tóg" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:840 +#, fuzzy +msgid "Align selected nodes vertically" +msgstr "Tóg" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:843 +#, fuzzy +msgid "Distribute selected nodes horizontally" +msgstr "Tóg" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:846 +#, fuzzy +msgid "Distribute selected nodes vertically" +msgstr "Tóg" + +#. Rest of the widgetry +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:851 +msgid "Last selected" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:852 +msgid "First selected" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:853 +msgid "Biggest item" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:854 +msgid "Smallest item" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:856 +#: ../../po/../src/widgets/desktop-widget.cpp:1065 +msgid "Drawing" +msgstr "" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:91 +msgid "Metadata 1" +msgstr "" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:92 +msgid "Metadata 2" +msgstr "" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:187 +#, fuzzy +msgid "X coordinate of grid origin" +msgstr "Dath 1" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:189 +#, fuzzy +msgid "Y coordinate of grid origin" +msgstr "Dath 1" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:191 +msgid "Distance of vertical grid lines" +msgstr "" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:193 +#, fuzzy +msgid "Distance of horizontal grid lines" +msgstr "Tóg" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:197 +msgid "Max. snapping distance from grid" +msgstr "" + +#: ../../po/../src/ui/dialog/export.cpp:34 +#, fuzzy +msgid "Export" +msgstr "Priontáil" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:36 +#, fuzzy +msgid "Fill" +msgstr "Comhad Nua" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:37 +#, fuzzy +msgid "Stroke Paint" +msgstr "Priontáil" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:38 +#, fuzzy +msgid "Stroke Style" +msgstr "Roghanna Dath" + +#: ../../po/../src/ui/dialog/find.cpp:34 +#, fuzzy +msgid "Find" +msgstr "Leasú" + +#: ../../po/../src/ui/dialog/memory.cpp:96 +msgid "Heap" +msgstr "" + +#: ../../po/../src/ui/dialog/memory.cpp:97 +#, fuzzy +msgid "In Use" +msgstr "Priontáil" + +#. TRANSLATORS: "Slack" refers to memory which is in the heap but currently unused. +#. More typical usage is to call this memory "free" rather than "slack". +#: ../../po/../src/ui/dialog/memory.cpp:100 +#, fuzzy +msgid "Slack" +msgstr "Dath" + +#: ../../po/../src/ui/dialog/memory.cpp:101 +#, fuzzy +msgid "Total" +msgstr "Comhad Nua" + +#: ../../po/../src/ui/dialog/memory.cpp:141 +#: ../../po/../src/ui/dialog/memory.cpp:147 +#: ../../po/../src/ui/dialog/memory.cpp:154 +#: ../../po/../src/ui/dialog/memory.cpp:186 +#, fuzzy +msgid "Unknown" +msgstr "Tada" + +#: ../../po/../src/ui/dialog/memory.cpp:167 +msgid "Combined" +msgstr "" + +#: ../../po/../src/ui/dialog/memory.cpp:209 +msgid "Recalculate" +msgstr "" + +#: ../../po/../src/ui/dialog/messages.cpp:74 +#, fuzzy +msgid "Ready." +msgstr "Luach:" + +#: ../../po/../src/ui/dialog/messages.cpp:75 +msgid "" +"Enable log display by setting dialogs.debug 'redirect' attribute to 1 in " +"preferences.xml" +msgstr "" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:184 +msgid "_Execute Python" +msgstr "" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:186 +msgid "_Execute Perl" +msgstr "" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:195 +msgid "Script" +msgstr "" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:205 +#, fuzzy +msgid "Output" +msgstr "Gearr" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:215 +msgid "Errors" +msgstr "" + +#. Dialog organization +#: ../../po/../src/ui/dialog/session-player.cpp:73 +msgid "Session file" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:74 +#, fuzzy +msgid "Playback controls" +msgstr "Roghanna Oaf" + +#: ../../po/../src/ui/dialog/session-player.cpp:75 +#, fuzzy +msgid "Message information" +msgstr "Roghanna Oaf" + +#. Active session file display +#. fixme: Does this mean the active file for the session, or the file for the active session? +#. Please indicate which with a TRANSLATORS comment. +#: ../../po/../src/ui/dialog/session-player.cpp:85 +msgid "Active session file:" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:86 +msgid "Delay (milliseconds):" +msgstr "" + +#. Unload/load buttons +#: ../../po/../src/ui/dialog/session-player.cpp:94 +#, fuzzy +msgid "Close file" +msgstr "Radharc Nua" + +#: ../../po/../src/ui/dialog/session-player.cpp:95 +msgid "Open new file" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:96 +msgid "Set delay" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:138 +#, fuzzy +msgid "Rewind" +msgstr "Luach:" + +#: ../../po/../src/ui/dialog/session-player.cpp:139 +msgid "Go back one change" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:140 +#, fuzzy +msgid "Pause" +msgstr "Greamaigh" + +#: ../../po/../src/ui/dialog/session-player.cpp:141 +msgid "Go forward one change" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:142 +msgid "Play" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:177 +#: ../../po/../src/verbs.cpp:1573 +msgid "Open session file" +msgstr "" + +#. ##Set up the Potrace panel +#. #### brightness #### +#. #### Multiple scanning#### +#. ----Hbox1 +#: ../../po/../src/ui/dialog/tracedialog.cpp:345 +#: ../../po/../src/ui/dialog/tracedialog.cpp:428 +#, fuzzy +msgid "Brightness" +msgstr "deis" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:348 +msgid "Trace by a given brightness level" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:355 +msgid "Brightness cutoff for black/white" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:362 +#, fuzzy +msgid "Image Brightness" +msgstr "Meid pictiúr" + +#. #### canny edge detection #### +#. TRANSLATORS: "Canny" is the name of the inventor of this edge detection method +#: ../../po/../src/ui/dialog/tracedialog.cpp:369 +msgid "Optimal Edge Detection (Canny)" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:372 +msgid "Trace with edge detection by J. Canny's algorithm" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:388 +msgid "Brightness cutoff for adjacent pixels (determines edge thickness)" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:395 +#, fuzzy +msgid "Edge Detection" +msgstr "Scríos" + +#. #### quantization #### +#. TRANSLATORS: Color Quantization: the process of reducing the number of colors +#. in an image by selecting an optimized set of representative colors and then +#. re-applying this reduced set to the original image. +#: ../../po/../src/ui/dialog/tracedialog.cpp:404 +#, fuzzy +msgid "Color Quantization" +msgstr "Dath 1" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:407 +msgid "Trace along the boundaries of reduced colors" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:414 +msgid "The number of reduced colors" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:416 +#, fuzzy +msgid "Colors:" +msgstr "Dath" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:421 +msgid "Quantization / Reduction" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:431 +msgid "Trace the given number of brightness levels" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:438 +msgid "Scans:" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:440 +msgid "The desired number of scans" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:448 +msgid "Trace the given number of reduced colors" +msgstr "" + +#. ---Hbox3 +#: ../../po/../src/ui/dialog/tracedialog.cpp:454 +msgid "Monochrome" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:457 +msgid "Same as Color, but convert result to grayscale" +msgstr "" + +#. TRANSLATORS: "Stack" is a verb here +#: ../../po/../src/ui/dialog/tracedialog.cpp:460 +#, fuzzy +msgid "Stack" +msgstr "Dath" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:463 +msgid "" +"Stack scans vertically (no gaps) or tile horizontally (usually with gaps)" +msgstr "" + +#. TRANSLATORS: "Smooth" is a verb here +#: ../../po/../src/ui/dialog/tracedialog.cpp:466 +msgid "Smooth" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:469 +msgid "Apply Gaussian blur to the bitmap before tracing" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:473 +msgid "Multiple Scanning" +msgstr "" + +#. #### Preview #### +#: ../../po/../src/ui/dialog/tracedialog.cpp:479 +#: ../../po/../src/ui/dialog/tracedialog.cpp:489 +#, fuzzy +msgid "Preview" +msgstr "Radharc Nua" + +#. do not expand +#: ../../po/../src/ui/dialog/tracedialog.cpp:483 +msgid "Preview the result without actual tracing" +msgstr "" + +#. #### swap black and white #### +#: ../../po/../src/ui/dialog/tracedialog.cpp:495 +msgid "Invert" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:499 +msgid "Invert black and white regions for single traces" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:503 +msgid "Thanks to Peter Selinger, http://potrace.sourceforge.net" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:506 +#, fuzzy +msgid "Credits" +msgstr "Dath 1" + +#. done +#. TRANSLATORS: Potrace is an application for transforming bitmaps into +#. vector graphics (http://potrace.sourceforge.net/) +#: ../../po/../src/ui/dialog/tracedialog.cpp:514 +#, fuzzy +msgid "Potrace" +msgstr "Priontáil" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:527 +msgid "Abort a trace in progress" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:531 +msgid "Execute the trace" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:80 +#: ../../po/../src/ui/dialog/transformation.cpp:90 +#, fuzzy +msgid "_Horizontal" +msgstr "Tóg" + +#: ../../po/../src/ui/dialog/transformation.cpp:80 +msgid "Horizontal displacement (relative) or position (absolute)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:82 +#: ../../po/../src/ui/dialog/transformation.cpp:92 +#, fuzzy +msgid "_Vertical" +msgstr "Tóg" + +#: ../../po/../src/ui/dialog/transformation.cpp:82 +msgid "Vertical displacement (relative) or position (absolute)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:84 +#, fuzzy +msgid "_Width" +msgstr "Leitheid" + +#: ../../po/../src/ui/dialog/transformation.cpp:84 +msgid "Horizontal size increment (absolute or percentage)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:86 +#, fuzzy +msgid "_Height" +msgstr "Airde" + +#: ../../po/../src/ui/dialog/transformation.cpp:86 +msgid "Vertical size increment (absolute or percentage)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:88 +msgid "A_ngle" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:88 +msgid "Rotation angle (positive = counterclockwise)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:90 +msgid "" +"Horizontal skew angle (positive = counterclockwise), or absolute " +"displacement, or percentage displacement" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:92 +msgid "" +"Vertical skew angle (positive = counterclockwise), or absolute displacement, " +"or percentage displacement" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:95 +#, fuzzy +msgid "Transformation matrix element A" +msgstr "Roghanna Oaf" + +#: ../../po/../src/ui/dialog/transformation.cpp:96 +#, fuzzy +msgid "Transformation matrix element B" +msgstr "Roghanna Oaf" + +#: ../../po/../src/ui/dialog/transformation.cpp:97 +#, fuzzy +msgid "Transformation matrix element C" +msgstr "Roghanna Oaf" + +#: ../../po/../src/ui/dialog/transformation.cpp:98 +#, fuzzy +msgid "Transformation matrix element D" +msgstr "Roghanna Oaf" + +#: ../../po/../src/ui/dialog/transformation.cpp:99 +#, fuzzy +msgid "Transformation matrix element E" +msgstr "Roghanna Oaf" + +#: ../../po/../src/ui/dialog/transformation.cpp:100 +#, fuzzy +msgid "Transformation matrix element F" +msgstr "Roghanna Oaf" + +#: ../../po/../src/ui/dialog/transformation.cpp:102 +#, fuzzy +msgid "Rela_tive move" +msgstr "Greamaigh" + +#: ../../po/../src/ui/dialog/transformation.cpp:102 +msgid "" +"Add the specified relative displacement to the current position; otherwise, " +"edit the current absolute position directly" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:103 +msgid "Scale proportionally" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:103 +msgid "Preserve the width/height ratio of the scaled objects" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:104 +msgid "Apply to each _object separately" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:104 +msgid "" +"Apply the scale/rotate/skew to each selected object separately; otherwise, " +"transform the selection as a whole" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:105 +msgid "Edit c_urrent matrix" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:105 +msgid "" +"Edit the current transform= matrix; otherwise, post-multiply transform= by " +"this matrix" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:115 +#, fuzzy +msgid "_Move" +msgstr "Nód" + +#: ../../po/../src/ui/dialog/transformation.cpp:118 +#, fuzzy +msgid "_Scale" +msgstr "Sábháil\t" + +#: ../../po/../src/ui/dialog/transformation.cpp:121 +#, fuzzy +msgid "_Rotate" +msgstr "Tóg" + +#: ../../po/../src/ui/dialog/transformation.cpp:124 +#, fuzzy +msgid "Ske_w" +msgstr "Priontáil" + +#: ../../po/../src/ui/dialog/transformation.cpp:127 +msgid "Matri_x" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:141 +msgid "Reset the values on the current tab to defaults" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:148 +#, fuzzy +msgid "Apply transformation to selection" +msgstr "Tóg" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:43 +msgid "_Use SSL" +msgstr "" + +#. Construct dialog interface +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:68 +#, fuzzy +msgid "_Server:" +msgstr "Comhad Nua" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:69 +#, fuzzy +msgid "_Username:" +msgstr "ainm" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:70 +msgid "_Password:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:71 +msgid "P_ort:" +msgstr "" + +#. Buttons +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:99 +#, fuzzy +msgid "Connect" +msgstr "Radharc Nua" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:126 +msgid "Establishing connection to Jabber server %1 as user %2" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:131 +msgid "Failed to establish connection to Jabber server %1" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:136 +msgid "Authentication failed on Jabber server %1 as %2" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:141 +msgid "SSL initialization failed when connecting to Jabber server %1" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:147 +msgid "Connected to Jabber server %1 as %2" +msgstr "" + +#. Construct labels +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:75 +msgid "Chatroom _name:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:76 +msgid "Chatroom _server:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:77 +msgid "Chatroom _password:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:78 +msgid "Chatroom _handle:" +msgstr "" + +#. Button setup and callback registration +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:97 +msgid "Connect to chatroom" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:132 +msgid "Synchronizing with chatroom %1@%2 using the handle %3" +msgstr "" + +#. Construct dialog interface +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:78 +msgid "_User's Jabber ID:" +msgstr "" + +#. Buttons +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:82 +msgid "_Invite user" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:83 +#, fuzzy +msgid "_Cancel" +msgstr "Radharc Nua" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:94 +msgid "Buddy List" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:170 +msgid "Sending whiteboard invitation to %1" +msgstr "" + +#. FIXME: strings are replaced by placeholders, NOT to be translated until the code is enabled +#. See http://sourceforge.net/mailarchive/message.php?msg_id=11746016 for details +#. File menu +#. Edit menu +#. View menu +#. Layer menu +#. Object menu +#. Path menu +#. add(Gtk::StockItem(CLEANUP, _("PLACEHOLDER, do not translate"))); (using Gtk::Stock::CLEAR) +#. Text menu +#. About menu +#. Tools toolbox +#. Select Tool controls +#. Node Tool controls +#. Calligraphy Tool controls +#. Session playback controls +#: ../../po/../src/ui/stock-items.cpp:34 ../../po/../src/ui/stock-items.cpp:35 +#: ../../po/../src/ui/stock-items.cpp:36 ../../po/../src/ui/stock-items.cpp:37 +#: ../../po/../src/ui/stock-items.cpp:38 ../../po/../src/ui/stock-items.cpp:39 +#: ../../po/../src/ui/stock-items.cpp:40 ../../po/../src/ui/stock-items.cpp:41 +#: ../../po/../src/ui/stock-items.cpp:42 ../../po/../src/ui/stock-items.cpp:43 +#: ../../po/../src/ui/stock-items.cpp:46 ../../po/../src/ui/stock-items.cpp:47 +#: ../../po/../src/ui/stock-items.cpp:48 ../../po/../src/ui/stock-items.cpp:49 +#: ../../po/../src/ui/stock-items.cpp:50 ../../po/../src/ui/stock-items.cpp:51 +#: ../../po/../src/ui/stock-items.cpp:52 ../../po/../src/ui/stock-items.cpp:53 +#: ../../po/../src/ui/stock-items.cpp:54 ../../po/../src/ui/stock-items.cpp:55 +#: ../../po/../src/ui/stock-items.cpp:56 ../../po/../src/ui/stock-items.cpp:57 +#: ../../po/../src/ui/stock-items.cpp:58 ../../po/../src/ui/stock-items.cpp:59 +#: ../../po/../src/ui/stock-items.cpp:62 ../../po/../src/ui/stock-items.cpp:63 +#: ../../po/../src/ui/stock-items.cpp:64 ../../po/../src/ui/stock-items.cpp:65 +#: ../../po/../src/ui/stock-items.cpp:66 ../../po/../src/ui/stock-items.cpp:67 +#: ../../po/../src/ui/stock-items.cpp:68 ../../po/../src/ui/stock-items.cpp:69 +#: ../../po/../src/ui/stock-items.cpp:70 ../../po/../src/ui/stock-items.cpp:71 +#: ../../po/../src/ui/stock-items.cpp:72 ../../po/../src/ui/stock-items.cpp:73 +#: ../../po/../src/ui/stock-items.cpp:74 ../../po/../src/ui/stock-items.cpp:75 +#: ../../po/../src/ui/stock-items.cpp:76 ../../po/../src/ui/stock-items.cpp:77 +#: ../../po/../src/ui/stock-items.cpp:78 ../../po/../src/ui/stock-items.cpp:79 +#: ../../po/../src/ui/stock-items.cpp:80 ../../po/../src/ui/stock-items.cpp:81 +#: ../../po/../src/ui/stock-items.cpp:82 ../../po/../src/ui/stock-items.cpp:83 +#: ../../po/../src/ui/stock-items.cpp:84 ../../po/../src/ui/stock-items.cpp:85 +#: ../../po/../src/ui/stock-items.cpp:86 ../../po/../src/ui/stock-items.cpp:87 +#: ../../po/../src/ui/stock-items.cpp:88 ../../po/../src/ui/stock-items.cpp:89 +#: ../../po/../src/ui/stock-items.cpp:92 ../../po/../src/ui/stock-items.cpp:93 +#: ../../po/../src/ui/stock-items.cpp:94 ../../po/../src/ui/stock-items.cpp:95 +#: ../../po/../src/ui/stock-items.cpp:96 ../../po/../src/ui/stock-items.cpp:97 +#: ../../po/../src/ui/stock-items.cpp:98 ../../po/../src/ui/stock-items.cpp:99 +#: ../../po/../src/ui/stock-items.cpp:100 +#: ../../po/../src/ui/stock-items.cpp:101 +#: ../../po/../src/ui/stock-items.cpp:102 +#: ../../po/../src/ui/stock-items.cpp:103 +#: ../../po/../src/ui/stock-items.cpp:104 +#: ../../po/../src/ui/stock-items.cpp:105 +#: ../../po/../src/ui/stock-items.cpp:108 +#: ../../po/../src/ui/stock-items.cpp:109 +#: ../../po/../src/ui/stock-items.cpp:110 +#: ../../po/../src/ui/stock-items.cpp:111 +#: ../../po/../src/ui/stock-items.cpp:112 +#: ../../po/../src/ui/stock-items.cpp:113 +#: ../../po/../src/ui/stock-items.cpp:114 +#: ../../po/../src/ui/stock-items.cpp:115 +#: ../../po/../src/ui/stock-items.cpp:116 +#: ../../po/../src/ui/stock-items.cpp:117 +#: ../../po/../src/ui/stock-items.cpp:118 +#: ../../po/../src/ui/stock-items.cpp:119 +#: ../../po/../src/ui/stock-items.cpp:120 +#: ../../po/../src/ui/stock-items.cpp:121 +#: ../../po/../src/ui/stock-items.cpp:122 +#: ../../po/../src/ui/stock-items.cpp:123 +#: ../../po/../src/ui/stock-items.cpp:124 +#: ../../po/../src/ui/stock-items.cpp:125 +#: ../../po/../src/ui/stock-items.cpp:126 +#: ../../po/../src/ui/stock-items.cpp:127 +#: ../../po/../src/ui/stock-items.cpp:130 +#: ../../po/../src/ui/stock-items.cpp:131 +#: ../../po/../src/ui/stock-items.cpp:132 +#: ../../po/../src/ui/stock-items.cpp:133 +#: ../../po/../src/ui/stock-items.cpp:134 +#: ../../po/../src/ui/stock-items.cpp:135 +#: ../../po/../src/ui/stock-items.cpp:136 +#: ../../po/../src/ui/stock-items.cpp:137 +#: ../../po/../src/ui/stock-items.cpp:138 +#: ../../po/../src/ui/stock-items.cpp:139 +#: ../../po/../src/ui/stock-items.cpp:140 +#: ../../po/../src/ui/stock-items.cpp:141 +#: ../../po/../src/ui/stock-items.cpp:142 +#: ../../po/../src/ui/stock-items.cpp:143 +#: ../../po/../src/ui/stock-items.cpp:144 +#: ../../po/../src/ui/stock-items.cpp:145 +#: ../../po/../src/ui/stock-items.cpp:146 +#: ../../po/../src/ui/stock-items.cpp:150 +#: ../../po/../src/ui/stock-items.cpp:151 +#: ../../po/../src/ui/stock-items.cpp:152 +#: ../../po/../src/ui/stock-items.cpp:153 +#: ../../po/../src/ui/stock-items.cpp:156 +#: ../../po/../src/ui/stock-items.cpp:157 +#: ../../po/../src/ui/stock-items.cpp:158 +#: ../../po/../src/ui/stock-items.cpp:161 +#: ../../po/../src/ui/stock-items.cpp:162 +#: ../../po/../src/ui/stock-items.cpp:163 +#: ../../po/../src/ui/stock-items.cpp:164 +#: ../../po/../src/ui/stock-items.cpp:165 +#: ../../po/../src/ui/stock-items.cpp:166 +#: ../../po/../src/ui/stock-items.cpp:167 +#: ../../po/../src/ui/stock-items.cpp:168 +#: ../../po/../src/ui/stock-items.cpp:169 +#: ../../po/../src/ui/stock-items.cpp:170 +#: ../../po/../src/ui/stock-items.cpp:171 +#: ../../po/../src/ui/stock-items.cpp:172 +#: ../../po/../src/ui/stock-items.cpp:175 +#: ../../po/../src/ui/stock-items.cpp:176 +#: ../../po/../src/ui/stock-items.cpp:177 +#: ../../po/../src/ui/stock-items.cpp:178 +#: ../../po/../src/ui/stock-items.cpp:181 +#: ../../po/../src/ui/stock-items.cpp:182 +#: ../../po/../src/ui/stock-items.cpp:183 +#: ../../po/../src/ui/stock-items.cpp:184 +#: ../../po/../src/ui/stock-items.cpp:185 +#: ../../po/../src/ui/stock-items.cpp:186 +#: ../../po/../src/ui/stock-items.cpp:187 +#: ../../po/../src/ui/stock-items.cpp:188 +#: ../../po/../src/ui/stock-items.cpp:189 +#: ../../po/../src/ui/stock-items.cpp:190 +#: ../../po/../src/ui/stock-items.cpp:191 +#: ../../po/../src/ui/stock-items.cpp:194 +#: ../../po/../src/ui/stock-items.cpp:195 +#: ../../po/../src/ui/stock-items.cpp:198 +#: ../../po/../src/ui/stock-items.cpp:199 +#: ../../po/../src/ui/stock-items.cpp:200 +#: ../../po/../src/ui/stock-items.cpp:201 +#: ../../po/../src/ui/stock-items.cpp:202 +msgid "PLACEHOLDER, do not translate" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:88 +msgid "small" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:89 +msgid "medium" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:90 +#, fuzzy +msgid "large" +msgstr "Leathanach" + +#: ../../po/../src/ui/widget/panel.cpp:91 +msgid "huge" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:106 +#, fuzzy +msgid "List" +msgstr "Priontáil" + +#: ../../po/../src/ui/widget/selected-style.cpp:67 +msgid "F:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:68 +msgid "S:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:69 +msgid "O:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:95 +msgid "N/A" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:98 +#: ../../po/../src/ui/widget/selected-style.cpp:712 +#, fuzzy +msgid "Nothing selected" +msgstr "Tóg" + +#: ../../po/../src/ui/widget/selected-style.cpp:103 +#, fuzzy +msgid "No fill" +msgstr "Dath 1" + +#: ../../po/../src/ui/widget/selected-style.cpp:103 +#, fuzzy +msgid "No stroke" +msgstr "Priontáil" + +#: ../../po/../src/ui/widget/selected-style.cpp:105 +#: ../../po/../src/widgets/paint-selector.cpp:190 +#, fuzzy +msgid "Pattern" +msgstr "Priontáil comhad" + +#: ../../po/../src/ui/widget/selected-style.cpp:108 +#: ../../po/../src/widgets/paint-selector.cpp:885 +#, fuzzy +msgid "Pattern fill" +msgstr "Priontáil comhad" + +#: ../../po/../src/ui/widget/selected-style.cpp:108 +#, fuzzy +msgid "Pattern stroke" +msgstr "Priontáil comhad" + +#: ../../po/../src/ui/widget/selected-style.cpp:110 +#, fuzzy +msgid "L Gradient" +msgstr "Priontáil comhad" + +#: ../../po/../src/ui/widget/selected-style.cpp:113 +#, fuzzy +msgid "Linear gradient fill" +msgstr "Priontáil comhad" + +#: ../../po/../src/ui/widget/selected-style.cpp:113 +#, fuzzy +msgid "Linear gradient stroke" +msgstr "Sábháil Comhad" + +#: ../../po/../src/ui/widget/selected-style.cpp:115 +#, fuzzy +msgid "R Gradient" +msgstr "Priontáil comhad" + +#: ../../po/../src/ui/widget/selected-style.cpp:118 +#, fuzzy +msgid "Radial gradient fill" +msgstr "Priontáil comhad" + +#: ../../po/../src/ui/widget/selected-style.cpp:118 +#, fuzzy +msgid "Radial gradient stroke" +msgstr "Priontáil comhad" + +#: ../../po/../src/ui/widget/selected-style.cpp:120 +#, fuzzy +msgid "Different" +msgstr "Scríos" + +#: ../../po/../src/ui/widget/selected-style.cpp:123 +#, fuzzy +msgid "Different fills" +msgstr "Scríos" + +#: ../../po/../src/ui/widget/selected-style.cpp:123 +#, fuzzy +msgid "Different strokes" +msgstr "Scríos" + +#: ../../po/../src/ui/widget/selected-style.cpp:125 +#, fuzzy +msgid "Unset" +msgstr "Priontáil" + +#. TRANSLATORS COMMENT: unset is a verb here +#: ../../po/../src/ui/widget/selected-style.cpp:128 +#: ../../po/../src/ui/widget/selected-style.cpp:182 +#, fuzzy +msgid "Unset fill" +msgstr "Comhad _Nua" + +#: ../../po/../src/ui/widget/selected-style.cpp:128 +#: ../../po/../src/ui/widget/selected-style.cpp:182 +msgid "Unset stroke" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:131 +#, fuzzy +msgid "Flat color fill" +msgstr "Dath" + +#: ../../po/../src/ui/widget/selected-style.cpp:131 +#, fuzzy +msgid "Flat color stroke" +msgstr "Dath" + +#. TRANSLATOR COMMENT: A means "Averaged" +#: ../../po/../src/ui/widget/selected-style.cpp:134 +msgid "A" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:137 +#, fuzzy +msgid "Fill is averaged over selected objects" +msgstr "Tóg" + +#: ../../po/../src/ui/widget/selected-style.cpp:137 +#, fuzzy +msgid "Stroke is averaged over selected objects" +msgstr "Tóg" + +#. TRANSLATOR COMMENT: M means "Multiple" +#: ../../po/../src/ui/widget/selected-style.cpp:140 +msgid "M" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:143 +#, fuzzy +msgid "Multiple selected objects have the same fill" +msgstr "Tóg" + +#: ../../po/../src/ui/widget/selected-style.cpp:143 +#, fuzzy +msgid "Multiple selected objects have the same stroke" +msgstr "Tóg" + +#: ../../po/../src/ui/widget/selected-style.cpp:145 +#, fuzzy +msgid "Edit fill..." +msgstr "Eagar Nód" + +#: ../../po/../src/ui/widget/selected-style.cpp:145 +#, fuzzy +msgid "Edit stroke..." +msgstr "Eagar Nód" + +#: ../../po/../src/ui/widget/selected-style.cpp:149 +#, fuzzy +msgid "Last set color" +msgstr "Dath" + +#: ../../po/../src/ui/widget/selected-style.cpp:153 +#, fuzzy +msgid "Last selected color" +msgstr "Tóg" + +#: ../../po/../src/ui/widget/selected-style.cpp:157 +msgid "White" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:161 +#: ../../po/../src/widgets/sp-color-scales.cpp:461 +#: ../../po/../src/widgets/sp-color-scales.cpp:462 +msgid "Black" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:165 +#, fuzzy +msgid "Copy color" +msgstr "Dath" + +#: ../../po/../src/ui/widget/selected-style.cpp:169 +#, fuzzy +msgid "Paste color" +msgstr "Dath" + +#: ../../po/../src/ui/widget/selected-style.cpp:173 +#, fuzzy +msgid "Swap fill and stroke" +msgstr "Roghanna Dath" + +#: ../../po/../src/ui/widget/selected-style.cpp:177 +msgid "Make fill opaque" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:177 +msgid "Make stroke opaque" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:186 +msgid "Remove fill" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:186 +msgid "Remove stroke" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:718 +msgid "Master opacity" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:744 +msgid "0 (transparent)" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:768 +msgid "1.0 (opaque)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1046 +msgid "Moved to next layer." +msgstr "" + +#: ../../po/../src/verbs.cpp:1048 +msgid "Cannot move past last layer." +msgstr "" + +#: ../../po/../src/verbs.cpp:1057 +msgid "Moved to previous layer." +msgstr "" + +#: ../../po/../src/verbs.cpp:1059 +msgid "Cannot move past first layer." +msgstr "" + +#: ../../po/../src/verbs.cpp:1076 ../../po/../src/verbs.cpp:1150 +#, fuzzy +msgid "No current layer." +msgstr "Roghanna Dath" + +#: ../../po/../src/verbs.cpp:1105 +#, fuzzy, c-format +msgid "Raised layer %s." +msgstr "Greamaigh" + +#: ../../po/../src/verbs.cpp:1109 +#, fuzzy, c-format +msgid "Lowered layer %s." +msgstr "Tóg" + +#: ../../po/../src/verbs.cpp:1118 +msgid "Cannot move layer any further." +msgstr "" + +#. TRANSLATORS: this means "The layer has been deleted." +#: ../../po/../src/verbs.cpp:1148 +#, fuzzy +msgid "Deleted layer." +msgstr "Tóg" + +#: ../../po/../src/verbs.cpp:1544 +msgid "" +"You need to connect to a Jabber server before sharing a document with " +"another user." +msgstr "" + +#: ../../po/../src/verbs.cpp:1559 +msgid "" +"You need to connect to a Jabber server before sharing a document with a " +"chatroom." +msgstr "" + +#: ../../po/../src/verbs.cpp:1569 +msgid "XML node tracker has not been initialized; nothing to dump" +msgstr "" + +#. TRANSLATORS: If you have translated the keys.svg file to your language, then +#. translate this string as "keys.LANG.svg" (where LANG is your language code); +#. otherwise leave as "keys.svg". +#: ../../po/../src/verbs.cpp:1631 +msgid "keys.svg" +msgstr "" + +#. TRANSLATORS: If you have translated the tutorial-basic.svg file to your language, +#. then translate this string as "tutorial-basic.LANG.svg" (where LANG is your language +#. code); otherwise leave as "tutorial-basic.svg". +#: ../../po/../src/verbs.cpp:1667 +msgid "tutorial-basic.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1671 +msgid "tutorial-shapes.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1675 +msgid "tutorial-advanced.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1679 +msgid "tutorial-tracing.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1683 +msgid "tutorial-calligraphy.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1687 +msgid "tutorial-elements.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1691 +msgid "tutorial-tips.svg" +msgstr "" + +#: ../../po/../src/verbs.cpp:1842 +msgid "Does nothing" +msgstr "" + +#. File +#: ../../po/../src/verbs.cpp:1845 +#, fuzzy +msgid "Default" +msgstr "Scríos" + +#: ../../po/../src/verbs.cpp:1845 +#, fuzzy +msgid "Create new document from default template" +msgstr "Sábháil Comhad" + +#: ../../po/../src/verbs.cpp:1847 +#, fuzzy +msgid "_Open..." +msgstr "Oscáil" + +#: ../../po/../src/verbs.cpp:1848 +msgid "Open existing document" +msgstr "" + +#: ../../po/../src/verbs.cpp:1849 +msgid "Re_vert" +msgstr "" + +#: ../../po/../src/verbs.cpp:1850 +msgid "Revert to the last saved version of document (changes will be lost)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1851 +#, fuzzy +msgid "_Save" +msgstr "Sábháil\t" + +#: ../../po/../src/verbs.cpp:1851 +msgid "Save document" +msgstr "" + +#: ../../po/../src/verbs.cpp:1853 +#, fuzzy +msgid "Save _As..." +msgstr "Sábháil Comhad" + +#: ../../po/../src/verbs.cpp:1854 +msgid "Save document under new name" +msgstr "" + +#: ../../po/../src/verbs.cpp:1855 +#, fuzzy +msgid "_Print..." +msgstr "Priontáil" + +#: ../../po/../src/verbs.cpp:1855 +msgid "Print document" +msgstr "" + +#. TRANSLATORS: "Vacuum Defs" means "Clean up defs" (so as to remove unused definitions) +#: ../../po/../src/verbs.cpp:1858 +msgid "Vac_uum Defs" +msgstr "" + +#: ../../po/../src/verbs.cpp:1858 +msgid "Remove unused predefined items from the <defs> of the document" +msgstr "" + +#: ../../po/../src/verbs.cpp:1860 +#, fuzzy +msgid "Print _Direct" +msgstr "Priontáil comhad" + +#: ../../po/../src/verbs.cpp:1861 +msgid "Print directly without prompting to a file or pipe" +msgstr "" + +#: ../../po/../src/verbs.cpp:1862 +#, fuzzy +msgid "Print Previe_w" +msgstr "Priontáil comhad" + +#: ../../po/../src/verbs.cpp:1863 +msgid "Preview document printout" +msgstr "" + +#: ../../po/../src/verbs.cpp:1864 +msgid "_Import..." +msgstr "" + +#: ../../po/../src/verbs.cpp:1865 +msgid "Import bitmap or SVG image into document" +msgstr "" + +#: ../../po/../src/verbs.cpp:1866 +msgid "_Export Bitmap..." +msgstr "" + +#: ../../po/../src/verbs.cpp:1867 +msgid "Export document or selection as a bitmap image" +msgstr "" + +#: ../../po/../src/verbs.cpp:1868 +#, fuzzy +msgid "N_ext Window" +msgstr "fuinneog1" + +#: ../../po/../src/verbs.cpp:1869 +msgid "Switch to the next document window" +msgstr "" + +#: ../../po/../src/verbs.cpp:1870 +#, fuzzy +msgid "P_revious Window" +msgstr "fuinneog1" + +#: ../../po/../src/verbs.cpp:1871 +msgid "Switch to the previous document window" +msgstr "" + +#: ../../po/../src/verbs.cpp:1872 +#, fuzzy +msgid "_Close" +msgstr "Radharc Nua" + +#: ../../po/../src/verbs.cpp:1873 +#, fuzzy +msgid "Close window" +msgstr "Radharc Nua" + +#: ../../po/../src/verbs.cpp:1874 +msgid "_Quit" +msgstr "" + +#: ../../po/../src/verbs.cpp:1874 +#, fuzzy +msgid "Quit Inkscape" +msgstr "Sodipodi" + +#. Edit +#: ../../po/../src/verbs.cpp:1877 +#, fuzzy +msgid "_Undo" +msgstr "Leasú" + +#: ../../po/../src/verbs.cpp:1877 +msgid "Undo last action" +msgstr "" + +#: ../../po/../src/verbs.cpp:1879 +msgid "_Redo" +msgstr "" + +#: ../../po/../src/verbs.cpp:1880 +msgid "Do again last undone action" +msgstr "" + +#: ../../po/../src/verbs.cpp:1881 +#, fuzzy +msgid "Cu_t" +msgstr "Gearr" + +#: ../../po/../src/verbs.cpp:1882 +#, fuzzy +msgid "Cut selection to clipboard" +msgstr "Tóg" + +#: ../../po/../src/verbs.cpp:1883 +#, fuzzy +msgid "_Copy" +msgstr "Cóip" + +#: ../../po/../src/verbs.cpp:1884 +#, fuzzy +msgid "Copy selection to clipboard" +msgstr "Tóg" + +#: ../../po/../src/verbs.cpp:1885 +#, fuzzy +msgid "_Paste" +msgstr "Greamaigh" + +#: ../../po/../src/verbs.cpp:1886 +#, fuzzy +msgid "Paste objects from clipboard to mouse point" +msgstr "Tóg" + +#: ../../po/../src/verbs.cpp:1887 +#, fuzzy +msgid "Paste _Style" +msgstr "Greamaigh" + +#: ../../po/../src/verbs.cpp:1888 +#, fuzzy +msgid "Apply style of the copied object to selection" +msgstr "Tóg" + +#: ../../po/../src/verbs.cpp:1889 +#, fuzzy +msgid "Paste _In Place" +msgstr "Greamaigh" + +#: ../../po/../src/verbs.cpp:1890 +#, fuzzy +msgid "Paste objects from clipboard to the original location" +msgstr "Tóg" + +#: ../../po/../src/verbs.cpp:1891 +msgid "_Delete" +msgstr "_Scríos" + +#: ../../po/../src/verbs.cpp:1892 +#, fuzzy +msgid "Delete selection" +msgstr "Scríos" + +#: ../../po/../src/verbs.cpp:1893 +msgid "Duplic_ate" +msgstr "" + +#: ../../po/../src/verbs.cpp:1894 +#, fuzzy +msgid "Duplicate selected objects" +msgstr "Tóg" + +#: ../../po/../src/verbs.cpp:1895 +#, fuzzy +msgid "Clo_ne" +msgstr "Radharc Nua" + +#: ../../po/../src/verbs.cpp:1896 +msgid "Create a clone of selected object (a copy linked to the original)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1897 +msgid "Unlin_k Clone" +msgstr "" + +#: ../../po/../src/verbs.cpp:1898 +msgid "Cut the clone's link to its original" +msgstr "" + +#: ../../po/../src/verbs.cpp:1899 +#, fuzzy +msgid "Select _Original" +msgstr "Tóg" + +#: ../../po/../src/verbs.cpp:1900 +#, fuzzy +msgid "Select the object to which the clone is linked" +msgstr "Tóg" + +#. TRANSLATORS: Convert selection to a rectangle with tiled pattern fill +#: ../../po/../src/verbs.cpp:1902 +#, fuzzy +msgid "O_bjects to Pattern" +msgstr "Roghanna Oaf" + +#: ../../po/../src/verbs.cpp:1903 +msgid "Convert selection to a rectangle with tiled pattern fill" +msgstr "" + +#. TRANSLATORS: Extract objects from a tiled pattern fill +#: ../../po/../src/verbs.cpp:1905 +#, fuzzy +msgid "Pattern to Ob_jects" +msgstr "Priontáil comhad" + +#: ../../po/../src/verbs.cpp:1906 +msgid "Extract objects from a tiled pattern fill" +msgstr "" + +#: ../../po/../src/verbs.cpp:1907 +#, fuzzy +msgid "Clea_r All" +msgstr "Dath 1" + +#: ../../po/../src/verbs.cpp:1908 +msgid "Delete all objects from document" +msgstr "" + +#: ../../po/../src/verbs.cpp:1909 +#, fuzzy +msgid "Select Al_l" +msgstr "Tóg" + +#: ../../po/../src/verbs.cpp:1910 +#, fuzzy +msgid "Select all objects or all nodes" +msgstr "Tóg" + +#: ../../po/../src/verbs.cpp:1911 +#, fuzzy +msgid "Select All in All La_yers" +msgstr "Tóg" + +#: ../../po/../src/verbs.cpp:1912 +#, fuzzy +msgid "Select all objects in all visible and unlocked layers" +msgstr "Tóg" + +#: ../../po/../src/verbs.cpp:1913 +#, fuzzy +msgid "In_vert Selection" +msgstr "Tóg" + +#: ../../po/../src/verbs.cpp:1914 +msgid "Invert selection (unselect what is selected and select everything else)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1915 +msgid "Invert in All Layers" +msgstr "" + +#: ../../po/../src/verbs.cpp:1916 +msgid "Invert selection in all visible and unlocked layers" +msgstr "" + +#: ../../po/../src/verbs.cpp:1917 +#, fuzzy +msgid "D_eselect" +msgstr "Tóg" + +#: ../../po/../src/verbs.cpp:1918 +#, fuzzy +msgid "Deselect any selected objects or nodes" +msgstr "Tóg" + +#. Selection +#: ../../po/../src/verbs.cpp:1921 +#, fuzzy +msgid "Raise to _Top" +msgstr "Tóg" + +#: ../../po/../src/verbs.cpp:1922 +#, fuzzy +msgid "Raise selection to top" +msgstr "Tóg" + +#: ../../po/../src/verbs.cpp:1923 +#, fuzzy +msgid "Lower to _Bottom" +msgstr "Tóg" + +#: ../../po/../src/verbs.cpp:1924 +#, fuzzy +msgid "Lower selection to bottom" +msgstr "Tóg" + +#: ../../po/../src/verbs.cpp:1925 +#, fuzzy +msgid "_Raise" +msgstr "Greamaigh" + +#: ../../po/../src/verbs.cpp:1926 +#, fuzzy +msgid "Raise selection one step" +msgstr "Tóg" + +#: ../../po/../src/verbs.cpp:1927 +msgid "_Lower" +msgstr "" + +#: ../../po/../src/verbs.cpp:1928 +#, fuzzy +msgid "Lower selection one step" +msgstr "Tóg" + +#: ../../po/../src/verbs.cpp:1929 +msgid "_Group" +msgstr "_Grupa" + +#: ../../po/../src/verbs.cpp:1930 +msgid "Group selected objects" +msgstr "" + +#: ../../po/../src/verbs.cpp:1932 +#, fuzzy +msgid "Ungroup selected groups" +msgstr "Tóg" + +#: ../../po/../src/verbs.cpp:1934 +#, fuzzy +msgid "_Put on Path" +msgstr "Tóg" + +#: ../../po/../src/verbs.cpp:1935 +#, fuzzy +msgid "Put text on path" +msgstr "Tóg" + +#: ../../po/../src/verbs.cpp:1936 +#, fuzzy +msgid "_Remove from Path" +msgstr "Roghanna Oaf" + +#: ../../po/../src/verbs.cpp:1937 +#, fuzzy +msgid "Remove text from path" +msgstr "Tóg" + +#: ../../po/../src/verbs.cpp:1938 +msgid "Remove Manual _Kerns" +msgstr "" + +#. TRANSLATORS: "glyph": An image used in the visual representation of characters; +#. roughly speaking, how a character looks. A font is a set of glyphs. +#: ../../po/../src/verbs.cpp:1941 +#, fuzzy +msgid "Remove all manual kerns and glyph rotations from a text object" +msgstr "Roghanna Oaf" + +#: ../../po/../src/verbs.cpp:1943 +#, fuzzy +msgid "_Union" +msgstr "Tada" + +#: ../../po/../src/verbs.cpp:1944 +#, fuzzy +msgid "Union of selected objects" +msgstr "Tóg" + +#: ../../po/../src/verbs.cpp:1945 +msgid "_Intersection" +msgstr "" + +#: ../../po/../src/verbs.cpp:1946 +#, fuzzy +msgid "Intersection of selected objects" +msgstr "Tóg" + +#: ../../po/../src/verbs.cpp:1947 +#, fuzzy +msgid "_Difference" +msgstr "Scríos" + +#: ../../po/../src/verbs.cpp:1948 +#, fuzzy +msgid "Difference of selected objects (bottom minus top)" +msgstr "Tóg" + +#: ../../po/../src/verbs.cpp:1949 +msgid "E_xclusion" +msgstr "" + +#: ../../po/../src/verbs.cpp:1950 +#, fuzzy +msgid "Exclusive OR of selected objects" +msgstr "Tóg" + +#: ../../po/../src/verbs.cpp:1951 +msgid "Di_vision" +msgstr "" + +#: ../../po/../src/verbs.cpp:1952 +msgid "Cut the bottom object into pieces" +msgstr "" + +#. TRANSLATORS: "to cut a path" is not the same as "to break a path apart" - see the +#. Advanced tutorial for more info +#: ../../po/../src/verbs.cpp:1955 +#, fuzzy +msgid "Cut _Path" +msgstr "Tóg" + +#: ../../po/../src/verbs.cpp:1956 +msgid "Cut the bottom object's stroke into pieces, removing fill" +msgstr "" + +#. TRANSLATORS: "outset": expand a shape by offsetting the object's path, +#. i.e. by displacing it perpendicular to the path in each point. +#. See also the Advanced Tutorial for explanation. +#: ../../po/../src/verbs.cpp:1960 +#, fuzzy +msgid "Outs_et" +msgstr "Tóg" + +#: ../../po/../src/verbs.cpp:1961 +#, fuzzy +msgid "Outset selected paths" +msgstr "Tóg" + +#: ../../po/../src/verbs.cpp:1963 +#, fuzzy +msgid "O_utset Path by 1 px" +msgstr "Tóg" + +#: ../../po/../src/verbs.cpp:1964 +#, fuzzy +msgid "Outset selected paths by 1 px" +msgstr "Tóg" + +#: ../../po/../src/verbs.cpp:1966 +#, fuzzy +msgid "O_utset Path by 10 px" +msgstr "Tóg" + +#: ../../po/../src/verbs.cpp:1967 +#, fuzzy +msgid "Outset selected paths by 10 px" +msgstr "Tóg" + +#. TRANSLATORS: "inset": contract a shape by offsetting the object's path, +#. i.e. by displacing it perpendicular to the path in each point. +#. See also the Advanced Tutorial for explanation. +#: ../../po/../src/verbs.cpp:1971 +msgid "I_nset" +msgstr "" + +#: ../../po/../src/verbs.cpp:1972 +#, fuzzy +msgid "Inset selected paths" +msgstr "Tóg" + +#: ../../po/../src/verbs.cpp:1974 +#, fuzzy +msgid "I_nset Path by 1 px" +msgstr "Tóg" + +#: ../../po/../src/verbs.cpp:1975 +#, fuzzy +msgid "Inset selected paths by 1 px" +msgstr "Tóg" + +#: ../../po/../src/verbs.cpp:1977 +#, fuzzy +msgid "I_nset Path by 10 px" +msgstr "Tóg" + +#: ../../po/../src/verbs.cpp:1978 +#, fuzzy +msgid "Inset selected paths by 10 px" +msgstr "Tóg" + +#: ../../po/../src/verbs.cpp:1980 +msgid "D_ynamic Offset" +msgstr "" + +#: ../../po/../src/verbs.cpp:1980 +msgid "Create a dynamic offset object" +msgstr "" + +#: ../../po/../src/verbs.cpp:1982 +msgid "_Linked Offset" +msgstr "" + +#: ../../po/../src/verbs.cpp:1983 +msgid "Create a dynamic offset object linked to the original path" +msgstr "" + +#: ../../po/../src/verbs.cpp:1985 +#, fuzzy +msgid "_Stroke to Path" +msgstr "Roghanna Dath" + +#: ../../po/../src/verbs.cpp:1986 +#, fuzzy +msgid "Convert selected strokes to paths" +msgstr "Tóg" + +#: ../../po/../src/verbs.cpp:1987 +msgid "Si_mplify" +msgstr "" + +#: ../../po/../src/verbs.cpp:1988 +msgid "Simplify selected paths by removing extra nodes" +msgstr "" + +#: ../../po/../src/verbs.cpp:1989 +#, fuzzy +msgid "_Reverse" +msgstr "Comhad Nua" + +#: ../../po/../src/verbs.cpp:1990 +#, fuzzy +msgid "Reverses the direction of selected paths; useful for flipping markers" +msgstr "Tóg" + +#. TRANSLATORS: "to trace" means "to convert a bitmap to vector graphics" (to vectorize) +#: ../../po/../src/verbs.cpp:1992 +msgid "_Trace Bitmap" +msgstr "" + +#: ../../po/../src/verbs.cpp:1993 +#, fuzzy +msgid "Convert bitmap object to paths" +msgstr "Tóg" + +#: ../../po/../src/verbs.cpp:1994 +msgid "_Make a Bitmap Copy" +msgstr "" + +#: ../../po/../src/verbs.cpp:1995 +msgid "Export selection to a bitmap and insert it into document" +msgstr "" + +#: ../../po/../src/verbs.cpp:1996 +msgid "_Combine" +msgstr "" + +#: ../../po/../src/verbs.cpp:1997 +msgid "Combine several paths into one" +msgstr "" + +#. TRANSLATORS: "to cut a path" is not the same as "to break a path apart" - see the +#. Advanced tutorial for more info +#: ../../po/../src/verbs.cpp:2000 +msgid "Break _Apart" +msgstr "" + +#: ../../po/../src/verbs.cpp:2001 +#, fuzzy +msgid "Break selected paths into subpaths" +msgstr "Tóg" + +#: ../../po/../src/verbs.cpp:2002 +msgid "Gri_d Arrange..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2003 +msgid "Arrange selection in grid pattern" +msgstr "" + +#. Layer +#: ../../po/../src/verbs.cpp:2005 +#, fuzzy +msgid "_Add Layer..." +msgstr "Greamaigh" + +#: ../../po/../src/verbs.cpp:2006 +#, fuzzy +msgid "Create a new layer" +msgstr "Sábháil Comhad" + +#: ../../po/../src/verbs.cpp:2007 +#, fuzzy +msgid "Re_name Layer..." +msgstr "Greamaigh" + +#: ../../po/../src/verbs.cpp:2008 +#, fuzzy +msgid "Rename the current layer" +msgstr "Tóg" + +#: ../../po/../src/verbs.cpp:2009 +#, fuzzy +msgid "Switch to Layer Abov_e" +msgstr "Tóg" + +#: ../../po/../src/verbs.cpp:2010 +msgid "Switch to the layer above the current" +msgstr "" + +#: ../../po/../src/verbs.cpp:2011 +#, fuzzy +msgid "Switch to Layer Belo_w" +msgstr "Tóg" + +#: ../../po/../src/verbs.cpp:2012 +msgid "Switch to the layer below the current" +msgstr "" + +#: ../../po/../src/verbs.cpp:2013 +#, fuzzy +msgid "Move Selection to Layer Abo_ve" +msgstr "Tóg" + +#: ../../po/../src/verbs.cpp:2014 +msgid "Move selection to the layer above the current" +msgstr "" + +#: ../../po/../src/verbs.cpp:2015 +#, fuzzy +msgid "Move Selection to Layer Bel_ow" +msgstr "Tóg" + +#: ../../po/../src/verbs.cpp:2016 +msgid "Move selection to the layer below the current" +msgstr "" + +#: ../../po/../src/verbs.cpp:2017 +#, fuzzy +msgid "Layer to _Top" +msgstr "Tóg" + +#: ../../po/../src/verbs.cpp:2018 +#, fuzzy +msgid "Raise the current layer to the top" +msgstr "Tóg" + +#: ../../po/../src/verbs.cpp:2019 +#, fuzzy +msgid "Layer to _Bottom" +msgstr "Tóg" + +#: ../../po/../src/verbs.cpp:2020 +#, fuzzy +msgid "Lower the current layer to the bottom" +msgstr "Tóg" + +#: ../../po/../src/verbs.cpp:2021 +#, fuzzy +msgid "_Raise Layer" +msgstr "Greamaigh" + +#: ../../po/../src/verbs.cpp:2022 +msgid "Raise the current layer" +msgstr "" + +#: ../../po/../src/verbs.cpp:2023 +#, fuzzy +msgid "_Lower Layer" +msgstr "Tóg" + +#: ../../po/../src/verbs.cpp:2024 +msgid "Lower the current layer" +msgstr "" + +#: ../../po/../src/verbs.cpp:2025 +#, fuzzy +msgid "_Delete Current Layer" +msgstr "Tóg" + +#: ../../po/../src/verbs.cpp:2026 +#, fuzzy +msgid "Delete the current layer" +msgstr "Tóg" + +#. Object +#: ../../po/../src/verbs.cpp:2029 +msgid "Rotate _90° CW" +msgstr "" + +#: ../../po/../src/verbs.cpp:2030 +msgid "Rotate selection 90° clockwise" +msgstr "" + +#: ../../po/../src/verbs.cpp:2031 +msgid "Rotate 9_0° CCW" +msgstr "" + +#: ../../po/../src/verbs.cpp:2032 +msgid "Rotate selection 90° counter-clockwise" +msgstr "" + +#: ../../po/../src/verbs.cpp:2033 +#, fuzzy +msgid "Remove _Transformations" +msgstr "Roghanna Oaf" + +#: ../../po/../src/verbs.cpp:2034 +#, fuzzy +msgid "Remove transformations from object" +msgstr "Roghanna Oaf" + +#: ../../po/../src/verbs.cpp:2035 +#, fuzzy +msgid "_Object to Path" +msgstr "Roghanna Oaf" + +#: ../../po/../src/verbs.cpp:2036 +#, fuzzy +msgid "Convert selected objects to paths" +msgstr "Tóg" + +#: ../../po/../src/verbs.cpp:2037 +msgid "_Flow into Frame" +msgstr "" + +#: ../../po/../src/verbs.cpp:2038 +#, fuzzy +msgid "Put text into frames" +msgstr "Tóg" + +#: ../../po/../src/verbs.cpp:2039 +#, fuzzy +msgid "_Unflow" +msgstr "Leasú" + +#: ../../po/../src/verbs.cpp:2040 +msgid "Remove text from frame (creates a single-line text object)" +msgstr "" + +#: ../../po/../src/verbs.cpp:2041 +#, fuzzy +msgid "_Convert to Text" +msgstr "Tóg" + +#: ../../po/../src/verbs.cpp:2042 +#, fuzzy +msgid "Convert flowed text to regular text objects (preserves appearance)" +msgstr "Tóg" + +#: ../../po/../src/verbs.cpp:2044 +#, fuzzy +msgid "Flip _Horizontal" +msgstr "Tóg" + +#: ../../po/../src/verbs.cpp:2044 +#, fuzzy +msgid "Flips selected objects horizontally" +msgstr "Tóg" + +#: ../../po/../src/verbs.cpp:2047 +#, fuzzy +msgid "Flip _Vertical" +msgstr "Tóg" + +#: ../../po/../src/verbs.cpp:2047 +#, fuzzy +msgid "Flips selected objects vertically" +msgstr "Tóg" + +#. Tools +#: ../../po/../src/verbs.cpp:2051 +msgid "Select" +msgstr "Tóg" + +#: ../../po/../src/verbs.cpp:2052 +#, fuzzy +msgid "Select and transform objects" +msgstr "Tóg" + +#: ../../po/../src/verbs.cpp:2053 +#, fuzzy +msgid "Node Edit" +msgstr "Eagar Nód" + +#: ../../po/../src/verbs.cpp:2054 +msgid "Edit path nodes or control handles" +msgstr "" + +#: ../../po/../src/verbs.cpp:2056 +msgid "Create rectangles and squares" +msgstr "" + +#: ../../po/../src/verbs.cpp:2058 +msgid "Create circles, ellipses, and arcs" +msgstr "" + +#: ../../po/../src/verbs.cpp:2060 +msgid "Create stars and polygons" +msgstr "" + +#: ../../po/../src/verbs.cpp:2062 +#, fuzzy +msgid "Create spirals" +msgstr "Spéisialta" + +#: ../../po/../src/verbs.cpp:2064 +msgid "Draw freehand lines" +msgstr "" + +#: ../../po/../src/verbs.cpp:2066 +msgid "Draw Bezier curves and straight lines" +msgstr "" + +#: ../../po/../src/verbs.cpp:2068 +msgid "Draw calligraphic lines" +msgstr "" + +#: ../../po/../src/verbs.cpp:2070 +#, fuzzy +msgid "Create and edit text objects" +msgstr "Tóg" + +#: ../../po/../src/verbs.cpp:2072 +#, fuzzy +msgid "Create and edit gradients" +msgstr "Tóg" + +#: ../../po/../src/verbs.cpp:2074 +#, fuzzy +msgid "Zoom in or out" +msgstr "Priontáil comhad" + +#: ../../po/../src/verbs.cpp:2076 +msgid "Pick averaged colors from image" +msgstr "" + +#: ../../po/../src/verbs.cpp:2078 +#, fuzzy +msgid "Create connectors" +msgstr "Sábháil Comhad" + +#. Tool prefs +#: ../../po/../src/verbs.cpp:2081 +msgid "Selector Preferences" +msgstr "" + +#: ../../po/../src/verbs.cpp:2082 +#, fuzzy +msgid "Open Preferences for the Selector tool" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2083 +msgid "Node Tool Preferences" +msgstr "" + +#: ../../po/../src/verbs.cpp:2084 +#, fuzzy +msgid "Open Preferences for the Node tool" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2085 +#, fuzzy +msgid "Rectangle Preferences" +msgstr "Meid pictiúr" + +#: ../../po/../src/verbs.cpp:2086 +#, fuzzy +msgid "Open Preferences for the Rectangle tool" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2087 +#, fuzzy +msgid "Ellipse Preferences" +msgstr "Roghanna Dath" + +#: ../../po/../src/verbs.cpp:2088 +#, fuzzy +msgid "Open Preferences for the Ellipse tool" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2089 +#, fuzzy +msgid "Star Preferences" +msgstr "Meid pictiúr" + +#: ../../po/../src/verbs.cpp:2090 +#, fuzzy +msgid "Open Preferences for the Star tool" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2091 +#, fuzzy +msgid "Spiral Preferences" +msgstr "Roghanna Dath" + +#: ../../po/../src/verbs.cpp:2092 +#, fuzzy +msgid "Open Preferences for the Spiral tool" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2093 +#, fuzzy +msgid "Pencil Preferences" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2094 +#, fuzzy +msgid "Open Preferences for the Pencil tool" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2095 +#, fuzzy +msgid "Pen Preferences" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2096 +#, fuzzy +msgid "Open Preferences for the Pen tool" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2097 +msgid "Calligraphic Preferences" +msgstr "" + +#: ../../po/../src/verbs.cpp:2098 +#, fuzzy +msgid "Open Preferences for the Calligraphy tool" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2099 +#, fuzzy +msgid "Text Preferences" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2100 +#, fuzzy +msgid "Open Preferences for the Text tool" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2101 +#, fuzzy +msgid "Gradient Preferences" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2102 +#, fuzzy +msgid "Open Preferences for the Gradient tool" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2103 +#, fuzzy +msgid "Zoom Preferences" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2104 +#, fuzzy +msgid "Open Preferences for the Zoom tool" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2105 +#, fuzzy +msgid "Dropper Preferences" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2106 +#, fuzzy +msgid "Open Preferences for the Dropper tool" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2107 +#, fuzzy +msgid "Connector Preferences" +msgstr "Meid pictiúr" + +#: ../../po/../src/verbs.cpp:2108 +#, fuzzy +msgid "Open Preferences for the Connector tool" +msgstr "Sodipodi" + +#. Zoom/View +#: ../../po/../src/verbs.cpp:2111 +#, fuzzy +msgid "Zoom In" +msgstr "Priontáil comhad" + +#: ../../po/../src/verbs.cpp:2111 +#, fuzzy +msgid "Zoom in" +msgstr "Priontáil comhad" + +#: ../../po/../src/verbs.cpp:2112 +#, fuzzy +msgid "Zoom Out" +msgstr "Priontáil comhad" + +#: ../../po/../src/verbs.cpp:2112 +#, fuzzy +msgid "Zoom out" +msgstr "Priontáil comhad" + +#: ../../po/../src/verbs.cpp:2113 +#, fuzzy +msgid "_Rulers" +msgstr "Comhad Nua" + +#: ../../po/../src/verbs.cpp:2113 +msgid "Show or hide the canvas rulers" +msgstr "" + +#: ../../po/../src/verbs.cpp:2114 +msgid "Scroll_bars" +msgstr "" + +#: ../../po/../src/verbs.cpp:2114 +msgid "Show or hide the canvas scrollbars" +msgstr "" + +#: ../../po/../src/verbs.cpp:2115 +msgid "_Grid" +msgstr "" + +#: ../../po/../src/verbs.cpp:2116 +msgid "G_uides" +msgstr "" + +#: ../../po/../src/verbs.cpp:2117 +msgid "Nex_t Zoom" +msgstr "" + +#: ../../po/../src/verbs.cpp:2117 +msgid "Next zoom (from the history of zooms)" +msgstr "" + +#: ../../po/../src/verbs.cpp:2119 +msgid "Pre_vious Zoom" +msgstr "" + +#: ../../po/../src/verbs.cpp:2119 +msgid "Previous zoom (from the history of zooms)" +msgstr "" + +#: ../../po/../src/verbs.cpp:2121 +#, fuzzy +msgid "Zoom 1:_1" +msgstr "Priontáil comhad" + +#: ../../po/../src/verbs.cpp:2121 +msgid "Zoom to 1:1" +msgstr "" + +#: ../../po/../src/verbs.cpp:2123 +#, fuzzy +msgid "Zoom 1:_2" +msgstr "Priontáil comhad" + +#: ../../po/../src/verbs.cpp:2123 +msgid "Zoom to 1:2" +msgstr "" + +#: ../../po/../src/verbs.cpp:2125 +#, fuzzy +msgid "_Zoom 2:1" +msgstr "Priontáil comhad" + +#: ../../po/../src/verbs.cpp:2125 +msgid "Zoom to 2:1" +msgstr "" + +#: ../../po/../src/verbs.cpp:2128 +msgid "_Fullscreen" +msgstr "" + +#: ../../po/../src/verbs.cpp:2128 +msgid "Stretch this document window to full screen" +msgstr "" + +#: ../../po/../src/verbs.cpp:2131 +#, fuzzy +msgid "Duplic_ate Window" +msgstr "Radharc Nua" + +#: ../../po/../src/verbs.cpp:2131 +msgid "Open a new window with the same document" +msgstr "" + +#: ../../po/../src/verbs.cpp:2133 +#, fuzzy +msgid "_New View Preview" +msgstr "Radharc Nua" + +#: ../../po/../src/verbs.cpp:2134 +#, fuzzy +msgid "New View Preview" +msgstr "Radharc Nua" + +#. "view_new_preview" +#: ../../po/../src/verbs.cpp:2136 +msgid "_Normal" +msgstr "" + +#: ../../po/../src/verbs.cpp:2137 +msgid "Switch to normal display mode" +msgstr "" + +#: ../../po/../src/verbs.cpp:2138 +#, fuzzy +msgid "_Outline" +msgstr "Radharc Nua" + +#: ../../po/../src/verbs.cpp:2139 +msgid "Switch to outline (wireframe) display mode" +msgstr "" + +#: ../../po/../src/verbs.cpp:2141 +#, fuzzy +msgid "Ico_n Preview" +msgstr "Radharc Nua" + +#: ../../po/../src/verbs.cpp:2142 +msgid "Open a window to preview items at different icon resolutions" +msgstr "" + +#: ../../po/../src/verbs.cpp:2144 +msgid "Zoom to fit page in window" +msgstr "" + +#: ../../po/../src/verbs.cpp:2145 +#, fuzzy +msgid "Page _Width" +msgstr "Leitheid" + +#: ../../po/../src/verbs.cpp:2146 +msgid "Zoom to fit page width in window" +msgstr "" + +#: ../../po/../src/verbs.cpp:2148 +msgid "Zoom to fit drawing in window" +msgstr "" + +#: ../../po/../src/verbs.cpp:2150 +msgid "Zoom to fit selection in window" +msgstr "" + +#. Dialogs +#: ../../po/../src/verbs.cpp:2153 +#, fuzzy +msgid "In_kscape Preferences..." +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2154 +#, fuzzy +msgid "Global Inkscape preferences" +msgstr "Roghanna Dath" + +#: ../../po/../src/verbs.cpp:2155 +msgid "_Document Preferences..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2156 +msgid "Preferences saved with the document" +msgstr "" + +#: ../../po/../src/verbs.cpp:2157 +#, fuzzy +msgid "_Fill and Stroke..." +msgstr "Roghanna Dath" + +#: ../../po/../src/verbs.cpp:2158 +#, fuzzy +msgid "Fill and Stroke dialog" +msgstr "Roghanna Dath" + +#. TRANSLATORS: "Swatches" means: color samples +#: ../../po/../src/verbs.cpp:2160 +#, fuzzy +msgid "S_watches..." +msgstr "Sábháil Comhad" + +#: ../../po/../src/verbs.cpp:2161 +msgid "View color swatches" +msgstr "" + +#: ../../po/../src/verbs.cpp:2162 +#, fuzzy +msgid "Transfor_m..." +msgstr "Roghanna Oaf" + +#: ../../po/../src/verbs.cpp:2163 +#, fuzzy +msgid "Transform dialog" +msgstr "Roghanna Oaf" + +#: ../../po/../src/verbs.cpp:2164 +#, fuzzy +msgid "_Align and Distribute..." +msgstr "Tóg" + +#: ../../po/../src/verbs.cpp:2165 +#, fuzzy +msgid "Align and Distribute dialog" +msgstr "Tóg" + +#: ../../po/../src/verbs.cpp:2166 +#, fuzzy +msgid "_Text and Font..." +msgstr "Roghanna Dath" + +#: ../../po/../src/verbs.cpp:2167 +#, fuzzy +msgid "Text and Font dialog" +msgstr "Roghanna Dath" + +#: ../../po/../src/verbs.cpp:2168 +msgid "_XML Editor..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2169 +msgid "XML Editor" +msgstr "" + +#: ../../po/../src/verbs.cpp:2170 +#, fuzzy +msgid "_Find..." +msgstr "Priontáil" + +#: ../../po/../src/verbs.cpp:2171 +#, fuzzy +msgid "Find objects in document" +msgstr "Sábháil Comhad" + +#: ../../po/../src/verbs.cpp:2172 +msgid "_Messages..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2173 +msgid "View debug messages" +msgstr "" + +#: ../../po/../src/verbs.cpp:2174 +#, fuzzy +msgid "S_cripts..." +msgstr "Priontáil" + +#: ../../po/../src/verbs.cpp:2175 +msgid "Run scripts" +msgstr "" + +#: ../../po/../src/verbs.cpp:2176 +#, fuzzy +msgid "Show/Hide D_ialogs" +msgstr "Roghanna Dath" + +#: ../../po/../src/verbs.cpp:2177 +msgid "Show or hide all active dialogs" +msgstr "" + +#. TRANSLATORS: "Tile clones" means: "Create tiled clones" +#: ../../po/../src/verbs.cpp:2179 +msgid "Tile clones..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2180 +msgid "Create and arrange multiple clones of selection" +msgstr "" + +#: ../../po/../src/verbs.cpp:2181 +#, fuzzy +msgid "_Object Properties..." +msgstr "Meid pictiúr" + +#: ../../po/../src/verbs.cpp:2182 +#, fuzzy +msgid "Object Properties dialog" +msgstr "Meid pictiúr" + +#: ../../po/../src/verbs.cpp:2185 +msgid "_Connect to Jabber server..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2185 +msgid "Connect to a Jabber server" +msgstr "" + +#: ../../po/../src/verbs.cpp:2187 +#, fuzzy +msgid "Share with _user..." +msgstr "Sábháil Comhad" + +#: ../../po/../src/verbs.cpp:2187 +msgid "Establish a whiteboard session with another Jabber user" +msgstr "" + +#: ../../po/../src/verbs.cpp:2189 +msgid "Share with _chatroom..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2189 +msgid "" +"Join a chatroom to start a new whiteboard session or join one in progress" +msgstr "" + +#: ../../po/../src/verbs.cpp:2191 +msgid "_Dump XML node tracker" +msgstr "" + +#: ../../po/../src/verbs.cpp:2191 +msgid "Dump the contents of the XML tracker to the console" +msgstr "" + +#: ../../po/../src/verbs.cpp:2193 +msgid "_Open session file..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2193 +msgid "Open and browse through records of past whiteboard sessions" +msgstr "" + +#: ../../po/../src/verbs.cpp:2195 +msgid "Session file playback" +msgstr "" + +#: ../../po/../src/verbs.cpp:2197 +msgid "_Disconnect from session" +msgstr "" + +#: ../../po/../src/verbs.cpp:2199 +msgid "Disconnect from _server" +msgstr "" + +#: ../../po/../src/verbs.cpp:2201 +msgid "_Input Devices..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2202 +msgid "Configure extended input devices" +msgstr "" + +#. Help +#: ../../po/../src/verbs.cpp:2205 +msgid "_Keys and Mouse" +msgstr "" + +#: ../../po/../src/verbs.cpp:2206 +msgid "Key and mouse shortcuts reference" +msgstr "" + +#: ../../po/../src/verbs.cpp:2207 +#, fuzzy +msgid "About E_xtensions" +msgstr "Scríos" + +#: ../../po/../src/verbs.cpp:2208 +#, fuzzy +msgid "About Extensions..." +msgstr "Scríos" + +#: ../../po/../src/verbs.cpp:2209 +#, fuzzy +msgid "About _Memory" +msgstr "Scríos" + +#: ../../po/../src/verbs.cpp:2210 +#, fuzzy +msgid "About Memory..." +msgstr "Scríos" + +#: ../../po/../src/verbs.cpp:2211 +msgid "_About Inkscape" +msgstr "" + +#. "help_about" +#. new HelpVerb(SP_VERB_SHOW_LICENSE, "ShowLicense", N_("Modifying or Redistributing Inkscape"), +#. N_("Show license to modify and/or redistribute Inkscape: GNU GPL"), NULL), +#. Tutorials +#: ../../po/../src/verbs.cpp:2217 +#, fuzzy +msgid "Inkscape: _Basic" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2218 +msgid "Getting started with Inkscape" +msgstr "" + +#. "tutorial_basic" +#: ../../po/../src/verbs.cpp:2219 +#, fuzzy +msgid "Inkscape: _Shapes" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2220 +msgid "Using shape tools to create and edit shapes" +msgstr "" + +#: ../../po/../src/verbs.cpp:2221 +#, fuzzy +msgid "Inkscape: _Advanced" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2222 +#, fuzzy +msgid "Advanced Inkscape topics" +msgstr "Sodipodi" + +#. "tutorial_advanced" +#. TRANSLATORS: "to trace" means "to convert a bitmap to vector graphics" (to vectorize) +#: ../../po/../src/verbs.cpp:2224 +#, fuzzy +msgid "Inkscape: T_racing" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2225 +#, fuzzy +msgid "Using bitmap tracing" +msgstr "Meid pictiúr" + +#. "tutorial_tracing" +#: ../../po/../src/verbs.cpp:2226 +#, fuzzy +msgid "Inkscape: _Calligraphy" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2227 +msgid "Using the Calligraphy pen tool" +msgstr "" + +#: ../../po/../src/verbs.cpp:2228 +msgid "_Elements of Design" +msgstr "" + +#: ../../po/../src/verbs.cpp:2229 +msgid "Principles of design in the tutorial form" +msgstr "" + +#. "tutorial_design" +#: ../../po/../src/verbs.cpp:2230 +msgid "_Tips and Tricks" +msgstr "" + +#: ../../po/../src/verbs.cpp:2231 +msgid "Miscellaneous tips and tricks" +msgstr "" + +#. "tutorial_tips" +#. Effect +#: ../../po/../src/verbs.cpp:2234 +msgid "Previous Effect" +msgstr "" + +#: ../../po/../src/verbs.cpp:2235 +msgid "Repeat the last effect with the same settings" +msgstr "" + +#. "tutorial_tips" +#: ../../po/../src/verbs.cpp:2236 +msgid "Previous Effect Settings..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2237 +msgid "Repeat the last effect with new settings" +msgstr "" + +#: ../../po/../src/widgets/dash-selector.cpp:106 +#, fuzzy +msgid "Dash pattern" +msgstr "Priontáil" + +#: ../../po/../src/widgets/dash-selector.cpp:121 +#, fuzzy +msgid "Pattern offset" +msgstr "Priontáil comhad" + +#: ../../po/../src/widgets/desktop-widget.cpp:240 +msgid "Zoom drawing if window size changes" +msgstr "" + +#: ../../po/../src/widgets/desktop-widget.cpp:298 +msgid "Cursor coordinates" +msgstr "" + +#. display the initial welcome message in the statusbar +#: ../../po/../src/widgets/desktop-widget.cpp:324 +msgid "" +"Welcome to Inkscape! Use shape or freehand tools to create objects; " +"use selector (arrow) to move or transform them." +msgstr "" + +#: ../../po/../src/widgets/desktop-widget.cpp:372 +#, c-format +msgid "%s: %d - Inkscape" +msgstr "" + +#: ../../po/../src/widgets/desktop-widget.cpp:374 +#, c-format +msgid "%s - Inkscape" +msgstr "" + +#: ../../po/../src/widgets/desktop-widget.cpp:532 +#, c-format +msgid "" +"Save changes to document \"%s\" before " +"closing?\n" +"\n" +"If you close without saving, your changes will be discarded." +msgstr "" + +#: ../../po/../src/widgets/desktop-widget.cpp:548 +#: ../../po/../src/widgets/desktop-widget.cpp:612 +msgid "Close _without saving" +msgstr "" + +#: ../../po/../src/widgets/desktop-widget.cpp:595 +#, c-format +msgid "" +"The file \"%s\" was saved with a " +"format (%s) that may cause data loss!\n" +"\n" +"Do you want to save this file in another format?" +msgstr "" + +#. Family frame +#: ../../po/../src/widgets/font-selector.cpp:156 +msgid "Font family" +msgstr "" + +#. Style frame +#: ../../po/../src/widgets/font-selector.cpp:184 +msgid "Style" +msgstr "" + +#: ../../po/../src/widgets/font-selector.cpp:219 +msgid "Font size:" +msgstr "" + +#. TRANSLATORS: Test string used in text and font dialog (when no +#. * text has been entered) to get a preview of the font. Choose +#. * some representative characters that users of your locale will be +#. * interested in. +#: ../../po/../src/widgets/font-selector.cpp:554 +msgid "AaBbCcIiPpQq12368.;/()" +msgstr "" + +#: ../../po/../src/widgets/gradient-selector.cpp:137 +#: ../../po/../src/widgets/gradient-toolbar.cpp:524 +#, fuzzy +msgid "Duplicate" +msgstr "Radharc Nua" + +#: ../../po/../src/widgets/gradient-selector.cpp:142 +#: ../../po/../src/widgets/gradient-toolbar.cpp:535 +#, fuzzy +msgid "Edit..." +msgstr "Eagar Nód" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/pservers.html#LinearGradientSpreadMethodAttribute +#: ../../po/../src/widgets/gradient-selector.cpp:159 +msgid "" +"Whether to fill with flat color beyond the ends of the gradient vector " +"(spreadMethod=\"pad\"), or repeat the gradient in the same direction " +"(spreadMethod=\"repeat\"), or repeat the gradient in alternating opposite " +"directions (spreadMethod=\"reflect\")" +msgstr "" + +#: ../../po/../src/widgets/gradient-selector.cpp:165 +#, fuzzy +msgid "none" +msgstr "Tada" + +#: ../../po/../src/widgets/gradient-selector.cpp:169 +#, fuzzy +msgid "reflected" +msgstr "Scríos" + +#: ../../po/../src/widgets/gradient-selector.cpp:173 +#, fuzzy +msgid "direct" +msgstr "Tóg" + +#: ../../po/../src/widgets/gradient-selector.cpp:181 +msgid "Repeat:" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:217 +msgid "No gradients" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:226 +#, fuzzy +msgid "Nothing selected" +msgstr "Priontáil comhad" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:237 +#, fuzzy +msgid "No gradients in selection" +msgstr "Priontáil comhad" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:247 +msgid "Multiple gradients" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:525 +msgid "" +"If the gradient is used by more than one object, create a copy of it for the " +"selected object(s)" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:536 +msgid "Edit the stops of the gradient" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:593 +#: ../../po/../src/widgets/toolbox.cpp:1103 +#: ../../po/../src/widgets/toolbox.cpp:1192 +#: ../../po/../src/widgets/toolbox.cpp:1485 +#: ../../po/../src/widgets/toolbox.cpp:1534 +#: ../../po/../src/widgets/toolbox.cpp:1766 +#: ../../po/../src/widgets/toolbox.cpp:1801 +#: ../../po/../src/widgets/toolbox.cpp:2331 +#: ../../po/../src/widgets/toolbox.cpp:2370 +msgid "New:" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:606 +#, fuzzy +msgid "Create linear gradient" +msgstr "Sábháil Comhad" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:620 +msgid "Create radial (elliptic or circular) gradient" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:635 +#, fuzzy +msgid "on" +msgstr "Síos" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:648 +#, fuzzy +msgid "Create gradient in the fill" +msgstr "Priontáil comhad" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:662 +msgid "Create gradient in the stroke" +msgstr "" + +#. FIXME: implement averaging of all parameters for multiple selected stars +#. gtk_label_set_markup(GTK_LABEL(l), _("Average:")); +#. FIXME: implement averaging of all parameters for multiple selected +#. gtk_label_set_markup(GTK_LABEL(l), _("Average:")); +#: ../../po/../src/widgets/gradient-toolbar.cpp:676 +#: ../../po/../src/widgets/toolbox.cpp:1105 +#: ../../po/../src/widgets/toolbox.cpp:1124 +#: ../../po/../src/widgets/toolbox.cpp:1493 +#: ../../po/../src/widgets/toolbox.cpp:1518 +#: ../../po/../src/widgets/toolbox.cpp:1768 +#: ../../po/../src/widgets/toolbox.cpp:1787 +#: ../../po/../src/widgets/toolbox.cpp:2334 +#: ../../po/../src/widgets/toolbox.cpp:2354 +msgid "Change:" +msgstr "" + +#: ../../po/../src/widgets/gradient-vector.cpp:269 +msgid "No gradients in document" +msgstr "" + +#: ../../po/../src/widgets/gradient-vector.cpp:275 +#, fuzzy +msgid "No gradient selected" +msgstr "Priontáil comhad" + +#: ../../po/../src/widgets/gradient-vector.cpp:532 +msgid "No stops in gradient" +msgstr "" + +#. TRANSLATORS: "Stop" means: a "phase" of a gradient +#: ../../po/../src/widgets/gradient-vector.cpp:794 +msgid "Add stop" +msgstr "" + +#: ../../po/../src/widgets/gradient-vector.cpp:797 +msgid "Add another control stop to gradient" +msgstr "" + +#: ../../po/../src/widgets/gradient-vector.cpp:799 +#, fuzzy +msgid "Delete stop" +msgstr "Scríos" + +#: ../../po/../src/widgets/gradient-vector.cpp:802 +msgid "Delete current control stop from gradient" +msgstr "" + +#. Label +#: ../../po/../src/widgets/gradient-vector.cpp:813 +msgid "Offset:" +msgstr "" + +#. TRANSLATORS: "Stop" means: a "phase" of a gradient +#: ../../po/../src/widgets/gradient-vector.cpp:858 +#, fuzzy +msgid "Stop Color" +msgstr "Dath" + +#: ../../po/../src/widgets/gradient-vector.cpp:887 +#, fuzzy +msgid "Gradient editor" +msgstr "Priontáil comhad" + +#: ../../po/../src/widgets/layer-selector.cpp:119 +#, fuzzy +msgid "Toggle current layer visibility" +msgstr "Roghanna Dath" + +#: ../../po/../src/widgets/layer-selector.cpp:139 +#, fuzzy +msgid "Lock or unlock current layer" +msgstr "Roghanna Dath" + +#: ../../po/../src/widgets/layer-selector.cpp:142 +#, fuzzy +msgid "Current layer" +msgstr "Roghanna Dath" + +#: ../../po/../src/widgets/layer-selector.cpp:553 +msgid "(root)" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:182 +#: ../../po/../src/widgets/paint-selector.cpp:561 +#, fuzzy +msgid "No paint" +msgstr "Priontáil" + +#: ../../po/../src/widgets/paint-selector.cpp:184 +#: ../../po/../src/widgets/paint-selector.cpp:629 +#, fuzzy +msgid "Flat color" +msgstr "Dath" + +#: ../../po/../src/widgets/paint-selector.cpp:186 +#: ../../po/../src/widgets/paint-selector.cpp:696 +msgid "Linear gradient" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:188 +#: ../../po/../src/widgets/paint-selector.cpp:699 +msgid "Radial gradient" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:192 +msgid "Unset paint (make it undefined so it can be inherited)" +msgstr "" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/painting.html#FillRuleProperty +#: ../../po/../src/widgets/paint-selector.cpp:204 +msgid "" +"Any path self-intersections or subpaths create holes in the fill (fill-rule: " +"evenodd)" +msgstr "" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/painting.html#FillRuleProperty +#: ../../po/../src/widgets/paint-selector.cpp:215 +msgid "" +"Fill is solid unless a subpath is counterdirectional (fill-rule: nonzero)" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:528 +msgid "No objects" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:539 +msgid "Multiple styles" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:550 +msgid "Paint is undefined" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:757 +#, fuzzy +msgid "No patterns in document" +msgstr "Sábháil Comhad" + +#: ../../po/../src/widgets/paint-selector.cpp:872 +msgid "" +"Use Edit > Object(s) to Pattern to create a new pattern from " +"selection." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:426 +msgid "Now stroke width is scaled when objects are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:428 +msgid "Now stroke width is not scaled when objects are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:436 +msgid "" +"Now rounded rectangle corners are scaled when rectangles are " +"scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:438 +msgid "" +"Now rounded rectangle corners are not scaled when rectangles " +"are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:446 +msgid "" +"Now gradients are transformed along with their objects when " +"those are transformed (moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:448 +msgid "" +"Now gradients remain fixed when objects are transformed " +"(moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:456 +msgid "" +"Now patterns are transformed along with their objects when " +"those are transformed (moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:458 +msgid "" +"Now patterns remain fixed when objects are transformed (moved, " +"scaled, rotated, or skewed)." +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:506 +#, fuzzy +msgid "select_toolbar|X" +msgstr "Tóg" + +#: ../../po/../src/widgets/select-toolbar.cpp:506 +msgid "Horizontal coordinate of selection" +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:511 +#, fuzzy +msgid "select_toolbar|Y" +msgstr "Tóg" + +#: ../../po/../src/widgets/select-toolbar.cpp:511 +msgid "Vertical coordinate of selection" +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:517 +#, fuzzy +msgid "select_toolbar|W" +msgstr "Tóg" + +#: ../../po/../src/widgets/select-toolbar.cpp:517 +msgid "Width of selection" +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:525 +msgid "Change both width and height by the same proportion" +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:534 +#, fuzzy +msgid "select_toolbar|H" +msgstr "Tóg" + +#: ../../po/../src/widgets/select-toolbar.cpp:534 +msgid "Height of selection" +msgstr "" + +#: ../../po/../src/widgets/sp-color-gtkselector.cpp:62 +msgid "System" +msgstr "" + +#: ../../po/../src/widgets/sp-color-notebook.cpp:322 +msgid "RGBA_:" +msgstr "" + +#: ../../po/../src/widgets/sp-color-notebook.cpp:330 +msgid "Hexadecimal RGBA value of the color" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "RGB" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "HSL" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "CMYK" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:397 +msgid "_R" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:398 +#: ../../po/../src/widgets/sp-color-scales.cpp:399 +#, fuzzy +msgid "Red" +msgstr "Luach:" + +#: ../../po/../src/widgets/sp-color-scales.cpp:400 +msgid "_G" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:401 +#: ../../po/../src/widgets/sp-color-scales.cpp:402 +msgid "Green" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:403 +msgid "_B" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:404 +#: ../../po/../src/widgets/sp-color-scales.cpp:405 +#, fuzzy +msgid "Blue" +msgstr "Luach:" + +#. Label +#: ../../po/../src/widgets/sp-color-scales.cpp:406 +#: ../../po/../src/widgets/sp-color-scales.cpp:432 +#: ../../po/../src/widgets/sp-color-scales.cpp:463 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:141 +msgid "_A" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:407 +#: ../../po/../src/widgets/sp-color-scales.cpp:408 +#: ../../po/../src/widgets/sp-color-scales.cpp:433 +#: ../../po/../src/widgets/sp-color-scales.cpp:434 +#: ../../po/../src/widgets/sp-color-scales.cpp:464 +#: ../../po/../src/widgets/sp-color-scales.cpp:465 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:151 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:163 +msgid "Alpha (opacity)" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:423 +msgid "_H" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:424 +#: ../../po/../src/widgets/sp-color-scales.cpp:425 +#, fuzzy +msgid "Hue" +msgstr "Luach:" + +#: ../../po/../src/widgets/sp-color-scales.cpp:426 +msgid "_S" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:427 +#: ../../po/../src/widgets/sp-color-scales.cpp:428 +msgid "Saturation" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:429 +msgid "_L" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:430 +#: ../../po/../src/widgets/sp-color-scales.cpp:431 +#, fuzzy +msgid "Lightness" +msgstr "deis" + +#: ../../po/../src/widgets/sp-color-scales.cpp:451 +msgid "_C" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:452 +#: ../../po/../src/widgets/sp-color-scales.cpp:453 +msgid "Cyan" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:454 +msgid "_M" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:455 +#: ../../po/../src/widgets/sp-color-scales.cpp:456 +msgid "Magenta" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:457 +msgid "_Y" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:458 +#: ../../po/../src/widgets/sp-color-scales.cpp:459 +msgid "Yellow" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:460 +msgid "_K" +msgstr "" + +#: ../../po/../src/widgets/sp-color-selector.cpp:71 +#, fuzzy +msgid "Unnamed" +msgstr "ainm" + +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:68 +msgid "Wheel" +msgstr "" + +#: ../../po/../src/widgets/sp-xmlview-attr-list.cpp:53 +msgid "Attribute" +msgstr "" + +#: ../../po/../src/widgets/sp-xmlview-attr-list.cpp:54 +msgid "Value" +msgstr "Luach" + +#: ../../po/../src/widgets/toolbox.cpp:424 +msgid "Insert new nodes into selected segments" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:426 +msgid "Delete selected nodes" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:431 +#, fuzzy +msgid "Join paths at selected nodes" +msgstr "Tóg" + +#: ../../po/../src/widgets/toolbox.cpp:433 +msgid "Join paths at selected nodes with new segment" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:436 +msgid "Split path between two non-endpoint nodes" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:439 +msgid "Break path at selected nodes" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:444 +msgid "Make selected nodes corner" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:447 +msgid "Make selected nodes smooth" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:450 +msgid "Make selected nodes symmetric" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:455 +msgid "Make selected segments lines" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:458 +msgid "Make selected segments curves" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1199 +msgid "Polygon" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1206 +msgid "Regular polygon (with one handle) instead of a star" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1218 +msgid "Corners:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1218 +msgid "Number of corners of a polygon or star" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1228 +#, fuzzy +msgid "Spoke ratio:" +msgstr "Roghanna Oaf" + +#. TRANSLATORS: Tip radius of a star is the distance from the center to the farthest handle. +#. Base radius is the same for the closest handle. +#: ../../po/../src/widgets/toolbox.cpp:1231 +msgid "Base radius to tip radius ratio" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1246 +#, fuzzy +msgid "Rounded:" +msgstr "Luach:" + +#: ../../po/../src/widgets/toolbox.cpp:1246 +msgid "How much rounded are the corners (0 for sharp)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1256 +msgid "Randomized:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1256 +msgid "Scatter randomly the corners and angles" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1269 +#: ../../po/../src/widgets/toolbox.cpp:1838 +#: ../../po/../src/widgets/toolbox.cpp:2061 +msgid "Defaults" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1270 +#: ../../po/../src/widgets/toolbox.cpp:1839 +#: ../../po/../src/widgets/toolbox.cpp:2062 +msgid "" +"Reset shape parameters to defaults (use Inkscape Preferences > Tools to " +"change defaults)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1544 +msgid "W:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1544 +msgid "Width of rectangle" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1556 +msgid "Height of rectangle" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1568 +#, fuzzy +msgid "Rx:" +msgstr "1:1" + +#: ../../po/../src/widgets/toolbox.cpp:1568 +msgid "Horizontal radius of rounded corners" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1578 +#, fuzzy +msgid "Ry:" +msgstr "1:1" + +#: ../../po/../src/widgets/toolbox.cpp:1578 +msgid "Vertical radius of rounded corners" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1594 +msgid "Not rounded" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1596 +msgid "Make corners sharp" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1805 +msgid "Turns:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1805 +msgid "Number of revolutions" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1815 +#, fuzzy +msgid "Divergence:" +msgstr "Scríos" + +#: ../../po/../src/widgets/toolbox.cpp:1815 +msgid "How much denser/sparser are outer revolutions; 1 = uniform" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1825 +msgid "Inner radius:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1825 +msgid "Radius of the innermost revolution (relative to the spiral size)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1957 +msgid "The width of the calligraphic pen (relative to the visible canvas area)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1967 +msgid "Thinning:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1967 +msgid "" +"How much velocity thins the stroke (> 0 makes fast strokes thinner, < 0 " +"makes them broader, 0 makes width independent of velocity)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1980 +msgid "Angle:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1980 +msgid "" +"The angle of the pen's nib (in degrees; 0 = horizontal; has no effect if " +"fixation = 0)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1990 +msgid "Fixation:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1990 +msgid "" +"How fixed is the pen angle (0 = always perpendicular to stroke direction, 1 " +"= fixed)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2003 +msgid "Mass:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2003 +msgid "How much inertia affects the movement of the pen" +msgstr "" + +#. TRANSLATORS: "drag" means "resistance" here +#: ../../po/../src/widgets/toolbox.cpp:2014 +msgid "Drag:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2014 +msgid "How much resistance affects the movement of the pen" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2034 +msgid "Use the pressure of the input device to alter the width of the pen" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2047 +msgid "Use the tilt of the input device to alter the angle of the pen's nib" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2374 +#, fuzzy +msgid "Start:" +msgstr "Dath" + +#: ../../po/../src/widgets/toolbox.cpp:2374 +msgid "The angle (in degrees) from the horizontal to the arc's start point" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2384 +msgid "End:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2384 +msgid "The angle (in degrees) from the horizontal to the arc's end point" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2395 +#, fuzzy +msgid "Open arc" +msgstr "Oscáil" + +#: ../../po/../src/widgets/toolbox.cpp:2396 +msgid "" +"Switch between arc (unclosed shape) and segment (closed shape with two radii)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2415 +msgid "Make whole" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2417 +msgid "Make the shape a whole ellipse, not arc or segment" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2644 +msgid "" +"When pressed, picks visible color without alpha and when not pressed, picks " +"color including its alpha" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:3039 +#, fuzzy +msgid "Make connectors avoid selected objects" +msgstr "Tóg" + +#: ../../po/../src/widgets/toolbox.cpp:3043 +#, fuzzy +msgid "Make connectors ignore selected objects" +msgstr "Tóg" + +#. +#. 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 : +#: ../share/extensions/addnodes.inx.h:1 +#, fuzzy +msgid "Add Nodes" +msgstr "Nód" + +#: ../share/extensions/addnodes.inx.h:2 +msgid "Maximum Segment Length" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:1 +msgid "AI Input" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:2 ../share/extensions/ai_output.inx.h:2 +msgid "Adobe Illustrator (*.ai)" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:3 +msgid "Open files saved with Adobe Illustrator" +msgstr "" + +#: ../share/extensions/ai_output.inx.h:1 +#, fuzzy +msgid "AI Output" +msgstr "Gearr" + +#: ../share/extensions/ai_output.inx.h:3 +msgid "Write Adobe Illustrator" +msgstr "" + +#: ../share/extensions/dia.inx.h:1 +msgid "A diagram created with the program Dia" +msgstr "" + +#: ../share/extensions/dia.inx.h:2 +msgid "Dia Diagram (*.dia)" +msgstr "" + +#: ../share/extensions/dia.inx.h:3 +msgid "Dia Input" +msgstr "" + +#: ../share/extensions/dia.inx.h:4 +msgid "" +"In order to import Dia files, Dia itself must be installed. You can get Dia " +"at http://www.gnome.org/projects/dia/" +msgstr "" + +#: ../share/extensions/dia.inx.h:5 +msgid "" +"The dia2svg.sh script should be installed with your Inkscape distribution. " +"If you do not have it, there is likely to be something wrong with your " +"Inkscape installation." +msgstr "" + +#: ../share/extensions/dots.inx.h:1 +#, fuzzy +msgid "Connect the Dots" +msgstr "Radharc Nua" + +#: ../share/extensions/dots.inx.h:2 +msgid "Dot Size" +msgstr "" + +#: ../share/extensions/dots.inx.h:3 +#, fuzzy +msgid "Font Size" +msgstr "Priontáil" + +#: ../share/extensions/dropshadow.inx.h:1 +msgid "Color of shadow" +msgstr "" + +#: ../share/extensions/dropshadow.inx.h:2 +msgid "Dropshadow" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:1 +#: ../share/extensions/dxf_output.inx.h:1 +msgid "AutoCAD DXF (*.dxf)" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:2 +msgid "DXF Input" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:3 +msgid "Import AutoCAD's Document Exchange Format" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:4 +msgid "" +"dxf2svg may come with Inkscape, but is also at http://dxf-svg-convert." +"sourceforge.net/" +msgstr "" + +#: ../share/extensions/dxf_output.inx.h:2 +#, fuzzy +msgid "DXF Output" +msgstr "Gearr" + +#: ../share/extensions/dxf_output.inx.h:3 +msgid "DXF file written by pstoedit" +msgstr "" + +#: ../share/extensions/dxf_output.inx.h:4 +msgid "pstoedit must be installed to run see http://www.pstoedit.net/pstoedit" +msgstr "" + +#: ../share/extensions/embedimage.inx.h:1 +#, fuzzy +msgid "Embed Images" +msgstr "Meid pictiúr" + +#: ../share/extensions/eps_input.inx.h:1 +msgid "EPS Input" +msgstr "" + +#: ../share/extensions/eps_input.inx.h:2 +msgid "Encapsulated Postscript" +msgstr "" + +#: ../share/extensions/eps_input.inx.h:3 +msgid "Encapsulated Postscript (*.eps)" +msgstr "" + +#: ../share/extensions/epsi_output.inx.h:1 +#, fuzzy +msgid "EPSI Output" +msgstr "Gearr" + +#: ../share/extensions/epsi_output.inx.h:2 +msgid "Encapsulated Postscript Interchange (*.epsi)" +msgstr "" + +#: ../share/extensions/epsi_output.inx.h:3 +msgid "Encapsulated Postscript with a thumbnail" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:1 ../share/extensions/ffms.inx.h:1 +#: ../share/extensions/ffset.inx.h:1 ../share/extensions/ffss.inx.h:1 +#, fuzzy +msgid "Bridge Width" +msgstr "Leitheid" + +#: ../share/extensions/ffmet.inx.h:2 ../share/extensions/ffms.inx.h:2 +msgid "First String Length" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:3 +msgid "FretFind Multi Length ET" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:4 ../share/extensions/ffms.inx.h:4 +#: ../share/extensions/ffset.inx.h:3 ../share/extensions/ffss.inx.h:3 +msgid "Fretboard Edges" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:5 ../share/extensions/ffms.inx.h:5 +msgid "Last String Length" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:6 ../share/extensions/ffms.inx.h:6 +#: ../share/extensions/ffset.inx.h:4 ../share/extensions/ffss.inx.h:4 +msgid "Number of Frets" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:7 ../share/extensions/ffms.inx.h:7 +#: ../share/extensions/ffset.inx.h:5 ../share/extensions/ffss.inx.h:5 +msgid "Number of Strings" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:8 ../share/extensions/ffms.inx.h:8 +#: ../share/extensions/ffset.inx.h:6 ../share/extensions/ffss.inx.h:6 +#, fuzzy +msgid "Nut Width" +msgstr "Leitheid" + +#: ../share/extensions/ffmet.inx.h:9 ../share/extensions/ffms.inx.h:10 +msgid "Perpendicular Distance" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:10 ../share/extensions/ffset.inx.h:7 +msgid "Scale Base (2 for Octave)" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:11 ../share/extensions/ffset.inx.h:9 +msgid "Tones in Scale" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:12 ../share/extensions/ffms.inx.h:12 +#: ../share/extensions/ffset.inx.h:10 ../share/extensions/ffss.inx.h:10 +msgid "px per Unit" +msgstr "" + +#: ../share/extensions/ffms.inx.h:3 +msgid "FretFind Multi Length Scala" +msgstr "" + +#: ../share/extensions/ffms.inx.h:9 ../share/extensions/ffss.inx.h:7 +msgid "Path to Scala *.scl File" +msgstr "" + +#: ../share/extensions/ffms.inx.h:11 +msgid "Tuning (scale step for each string seperated by semicolons)" +msgstr "" + +#: ../share/extensions/ffset.inx.h:2 +msgid "FretFind Single Length ET" +msgstr "" + +#: ../share/extensions/ffset.inx.h:8 ../share/extensions/ffss.inx.h:8 +msgid "Scale Length" +msgstr "" + +#: ../share/extensions/ffss.inx.h:2 +msgid "FretFind Single Length Scala" +msgstr "" + +#: ../share/extensions/ffss.inx.h:9 +msgid "Tuning (Scale step for each string seperated by semicolons)" +msgstr "" + +#: ../share/extensions/handles.inx.h:1 +msgid "Draw Handles" +msgstr "" + +#: ../share/extensions/interp.inx.h:1 +#, fuzzy +msgid "Duplicate Endpaths" +msgstr "Radharc Nua" + +#: ../share/extensions/interp.inx.h:2 +#, fuzzy +msgid "Exponent" +msgstr "Priontáil" + +#: ../share/extensions/interp.inx.h:3 +msgid "Interpolate" +msgstr "" + +#: ../share/extensions/interp.inx.h:4 +msgid "Interpolate Style (Experimental)" +msgstr "" + +#: ../share/extensions/interp.inx.h:5 +msgid "Interpolation Method" +msgstr "" + +#: ../share/extensions/interp.inx.h:6 +msgid "Interpolation Steps" +msgstr "" + +#: ../share/extensions/kochify.inx.h:1 +msgid "Kochify" +msgstr "" + +#: ../share/extensions/kochify_load.inx.h:1 +msgid "Kochify (Load)" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:1 +msgid "Angle" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:2 +msgid "Axiom" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:3 +#, fuzzy +msgid "Lindenmayer" +msgstr "Greamaigh" + +#: ../share/extensions/lindenmayer.inx.h:4 +msgid "Order" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:5 +#, fuzzy +msgid "Rules" +msgstr "Comhad Nua" + +#: ../share/extensions/lindenmayer.inx.h:6 +msgid "Step" +msgstr "" + +#: ../share/extensions/motion.inx.h:1 +#, fuzzy +msgid "Direction" +msgstr "Tóg" + +#: ../share/extensions/motion.inx.h:2 +msgid "Magnitude" +msgstr "" + +#: ../share/extensions/motion.inx.h:3 +#, fuzzy +msgid "Motion" +msgstr "Tóg" + +#: ../share/extensions/pdf_output.inx.h:1 +msgid "Adobe PDF (*.pdf)" +msgstr "" + +#: ../share/extensions/pdf_output.inx.h:2 +msgid "Adobe Portable Document Format" +msgstr "" + +#: ../share/extensions/pdf_output.inx.h:3 +#, fuzzy +msgid "PDF Output" +msgstr "Gearr" + +#: ../share/extensions/ps_input.inx.h:1 +#, fuzzy +msgid "Postscript" +msgstr "Priontáil" + +#: ../share/extensions/ps_input.inx.h:2 +msgid "Postscript (*.ps)" +msgstr "" + +#: ../share/extensions/ps_input.inx.h:3 +msgid "Postscript Input" +msgstr "" + +#: ../share/extensions/radiusrand.inx.h:1 +#, fuzzy +msgid "Radius" +msgstr "Greamaigh" + +#: ../share/extensions/radiusrand.inx.h:2 +#, fuzzy +msgid "Radius Randomize" +msgstr "Greamaigh" + +#: ../share/extensions/radiusrand.inx.h:3 +msgid "Randomize Control Points" +msgstr "" + +#: ../share/extensions/radiusrand.inx.h:4 +#, fuzzy +msgid "Randomize Nodes" +msgstr "Greamaigh" + +#: ../share/extensions/rtree.inx.h:1 +#, fuzzy +msgid "Initial Size" +msgstr "Meid pictiúr" + +#: ../share/extensions/rtree.inx.h:2 +msgid "Minimum Size" +msgstr "" + +#: ../share/extensions/rtree.inx.h:3 +msgid "Random Tree" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:1 +msgid "A diagram created with the program Sketch" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:2 +msgid "Sketch Diagram (*.sk)" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:3 +msgid "Sketch Input" +msgstr "" + +#: ../share/extensions/straightseg.inx.h:1 +msgid "Behavior" +msgstr "" + +#: ../share/extensions/straightseg.inx.h:3 +msgid "Segment Straightener" +msgstr "" + +#: ../share/extensions/summersnight.inx.h:1 +msgid "Summer's Night" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:1 +#: ../share/extensions/svgz_output.inx.h:1 +#, fuzzy +msgid "Compressed Inkscape SVG (*.svgz)" +msgstr "Oscáil comhad" + +#: ../share/extensions/svgz_input.inx.h:2 +#: ../share/extensions/svgz_output.inx.h:2 +msgid "Inkscape's native file format compressed with GZip" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:3 +msgid "SVGZ Input" +msgstr "" + +#: ../share/extensions/svgz_output.inx.h:3 +#, fuzzy +msgid "SVGZ Output" +msgstr "Gearr" + +#: ../share/extensions/txt2svg.inx.h:1 +msgid "ASCII Text" +msgstr "" + +#: ../share/extensions/txt2svg.inx.h:2 +msgid "Text File (*.txt)" +msgstr "" + +#: ../share/extensions/txt2svg.inx.h:3 +#, fuzzy +msgid "Text Input" +msgstr "Dath" + +#: ../share/extensions/wavy.inx.h:1 +msgid "Calculate first derivative numerically" +msgstr "" + +#: ../share/extensions/wavy.inx.h:2 +msgid "First derivative" +msgstr "" + +#: ../share/extensions/wavy.inx.h:3 +msgid "Function" +msgstr "" + +#: ../share/extensions/wavy.inx.h:4 +msgid "Function Plotter" +msgstr "" + +#: ../share/extensions/wavy.inx.h:5 +msgid "Nodes per period" +msgstr "" + +#: ../share/extensions/wavy.inx.h:6 +msgid "Periods (2*Pi each)" +msgstr "" + +#: ../share/extensions/whirl.inx.h:1 +msgid "Amount of Whirl" +msgstr "" + +#: ../share/extensions/whirl.inx.h:2 +msgid "Center X" +msgstr "" + +#: ../share/extensions/whirl.inx.h:3 +msgid "Center Y" +msgstr "" + +#: ../share/extensions/whirl.inx.h:4 +#, fuzzy +msgid "Direction of Rotation" +msgstr "Tóg" + +#: ../share/extensions/whirl.inx.h:5 +msgid "Whirl" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:1 +msgid "A popular graphics file format for clipart" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:2 +msgid "Windows Metafile (*.wmf)" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:3 +msgid "Windows Metafile Input" +msgstr "" + +#, fuzzy +#~ msgid "Custom canvas" +#~ msgstr "Gearr" + +#, fuzzy +#~ msgid "Current style" +#~ msgstr "Roghanna Dath" + +#, fuzzy +#~ msgid "_Credits" +#~ msgstr "Dath 1" + +#, fuzzy +#~ msgid "Acceleration" +#~ msgstr "Tóg" + +#, fuzzy +#~ msgid "Speed" +#~ msgstr "Luach:" + +#, fuzzy +#~ msgid "Zoom in/out by" +#~ msgstr "Priontáil comhad" + +#, fuzzy +#~ msgid "Transform" +#~ msgstr "Roghanna Oaf" + +#, fuzzy +#~ msgid "Flip selection horizontally" +#~ msgstr "Tóg" + +#, fuzzy +#~ msgid "Flip selection vertically" +#~ msgstr "Tóg" + +#, fuzzy +#~ msgid "Edit" +#~ msgstr "Eagar Nód" + +#~ msgid "Add" +#~ msgstr "Suim" + +#, fuzzy +#~ msgid "C_reate" +#~ msgstr "Radharc Nua" + +#, fuzzy +#~ msgid "Automatically scale Rows to fit selected objects." +#~ msgstr "Tóg" + +#, fuzzy +#~ msgid "Go to root" +#~ msgstr "Eagar Nód" + +#, fuzzy +#~ msgid "X" +#~ msgstr "X1" + +#, fuzzy +#~ msgid "Y" +#~ msgstr "Y1" + +#, fuzzy +#~ msgid "R1:" +#~ msgstr "1:1" + +#, fuzzy +#~ msgid "R2:" +#~ msgstr "2:1" + +#, fuzzy +#~ msgid "Start Angle:" +#~ msgstr "Dath" + +#, fuzzy +#~ msgid "Open:" +#~ msgstr "Oscáil" + +#, fuzzy +#~ msgid "Rectangle _Properties" +#~ msgstr "Meid pictiúr" + +#, fuzzy +#~ msgid "Star _Properties" +#~ msgstr "Meid pictiúr" + +#, fuzzy +#~ msgid "Ellipse _Properties" +#~ msgstr "Priontáil comhad" + +#, fuzzy +#~ msgid "Spiral _Properties" +#~ msgstr "Roghanna Dath" + +#, fuzzy +#~ msgid "Document Preferences" +#~ msgstr "Sodipodi" + +#, fuzzy +#~ msgid "Extensions Editor" +#~ msgstr "Scríos" + +#, fuzzy +#~ msgid "Preferences" +#~ msgstr "Sodipodi" + +#, fuzzy +#~ msgid "Layer Editor" +#~ msgstr "Tóg" + +#, fuzzy +#~ msgid "Text Properties" +#~ msgstr "Meid pictiúr" + +#, fuzzy +#~ msgid "Transformation" +#~ msgstr "Roghanna Oaf" + +#, fuzzy +#~ msgid "_Document Properties" +#~ msgstr "Roghanna Dath" + +#, fuzzy +#~ msgid "In_kscape Preferences" +#~ msgstr "Sodipodi" + +#, fuzzy +#~ msgid "Select _Original Clone" +#~ msgstr "Tóg" + +#, fuzzy +#~ msgid "Tile" +#~ msgstr "Comhad Nua" + +#, fuzzy +#~ msgid "Select A_ll" +#~ msgstr "Tóg" + +#, fuzzy +#~ msgid "Select Non_e" +#~ msgstr "Tóg" + +#, fuzzy +#~ msgid "Zoom _In" +#~ msgstr "Priontáil comhad" + +#, fuzzy +#~ msgid "Zoom _Out" +#~ msgstr "Priontáil comhad" + +#, fuzzy +#~ msgid "Pre_vious" +#~ msgstr "fuinneog1" + +#, fuzzy +#~ msgid "Nex_t" +#~ msgstr "Teacs" + +#, fuzzy +#~ msgid "Tool Co_ntrols bar" +#~ msgstr "Roghanna Oaf" + +#, fuzzy +#~ msgid "R_ename Layer..." +#~ msgstr "Greamaigh" + +#, fuzzy +#~ msgid "D_uplicate Layer" +#~ msgstr "Radharc Nua" + +#, fuzzy +#~ msgid "_Delete Layer" +#~ msgstr "Tóg" + +#, fuzzy +#~ msgid "Select Ne_xt Layer" +#~ msgstr "Tóg" + +#, fuzzy +#~ msgid "Select Pre_vious Layer" +#~ msgstr "Tóg" + +#, fuzzy +#~ msgid "Select To_p Layer" +#~ msgstr "Tóg" + +#, fuzzy +#~ msgid "Move to Ne_w Layer" +#~ msgstr "Sábháil Comhad" + +#, fuzzy +#~ msgid "Move to B_ottom Layer" +#~ msgstr "Tóg" + +#, fuzzy +#~ msgid "_Put Text on Path" +#~ msgstr "Tóg" + +#, fuzzy +#~ msgid "_Remove Text from Path" +#~ msgstr "Tóg" + +#, fuzzy +#~ msgid "Corners" +#~ msgstr "Radharc Nua" + +#, fuzzy +#~ msgid "Delete" +#~ msgstr "_Scríos" + +#, fuzzy +#~ msgid "Join" +#~ msgstr "Priontáil" + +#, fuzzy +#~ msgid "Delete Segment" +#~ msgstr "Scríos" + +#~ msgid "New" +#~ msgstr "Nua" + +#, fuzzy +#~ msgid "Save" +#~ msgstr "Sábháil\t" + +#, fuzzy +#~ msgid "Save As..." +#~ msgstr "Sábháil Comhad" + +#, fuzzy +#~ msgid "Print..." +#~ msgstr "Priontáil" + +#, fuzzy +#~ msgid "Global Inkscape preferences (Shift+Ctrl+P)" +#~ msgstr "Roghanna Dath" + +#, fuzzy +#~ msgid "Undo" +#~ msgstr "Leasú" + +#, fuzzy +#~ msgid "Redo" +#~ msgstr "Luach:" + +#, fuzzy +#~ msgid "Cut" +#~ msgstr "Gearr" + +#, fuzzy +#~ msgid "Copy" +#~ msgstr "Cóip" + +#, fuzzy +#~ msgid "Duplicate selected object(s) (Ctrl+D)" +#~ msgstr "Tóg" + +#, fuzzy +#~ msgid "Clone selected object (Alt+D)" +#~ msgstr "Tóg" + +#, fuzzy +#~ msgid "Zoom in (+)" +#~ msgstr "Priontáil comhad" + +#, fuzzy +#~ msgid "Zoom out (-)" +#~ msgstr "Priontáil comhad" + +#, fuzzy +#~ msgid "Fill and Stroke dialog (Shift+Ctrl+F)" +#~ msgstr "Roghanna Dath" + +#, fuzzy +#~ msgid "Group selected objects (Ctrl+G)" +#~ msgstr "Tóg" + +#, fuzzy +#~ msgid "Raise selection up one step (PgUp)" +#~ msgstr "Tóg" + +#, fuzzy +#~ msgid "Lower selection down one step (PgDn)" +#~ msgstr "Tóg" + +#, fuzzy +#~ msgid "Raise selection to top (Home)" +#~ msgstr "Tóg" + +#, fuzzy +#~ msgid "Lower selection to bottom (End)" +#~ msgstr "Tóg" + +#, fuzzy +#~ msgid "Move selection to new layer" +#~ msgstr "Tóg" + +#, fuzzy +#~ msgid "Move selection to next layer" +#~ msgstr "Tóg" + +#, fuzzy +#~ msgid "Move selection to previous layer" +#~ msgstr "Tóg" + +#, fuzzy +#~ msgid "Move selection to top layer" +#~ msgstr "Tóg" + +#, fuzzy +#~ msgid "Move selection to bottom layer" +#~ msgstr "Tóg" + +#, fuzzy +#~ msgid "Flip selection horizontally (H)" +#~ msgstr "Tóg" + +#, fuzzy +#~ msgid "Flip selection vertically (V)" +#~ msgstr "Tóg" + +#, fuzzy +#~ msgid "Align and Distribute dialog (Shift+Ctrl+A)" +#~ msgstr "Tóg" + +#, fuzzy +#~ msgid "Convert selected object(s) to path(s) (Shift+Ctrl+C)" +#~ msgstr "Tóg" + +#, fuzzy +#~ msgid "Convert selected stroke(s) to path(s) (Ctrl+Alt+C)" +#~ msgstr "Tóg" + +#, fuzzy +#~ msgid "Text and Font dialog (Shift+Ctrl+T)" +#~ msgstr "Roghanna Dath" + +#, fuzzy +#~ msgid "Node tool" +#~ msgstr "Eagar Nód" + +#, fuzzy +#~ msgid "Zoom tool" +#~ msgstr "Priontáil comhad" + +#, fuzzy +#~ msgid "Rectangle tool" +#~ msgstr "Priontáil" + +#, fuzzy +#~ msgid "Arc tool" +#~ msgstr "Dath" + +#, fuzzy +#~ msgid "Star tool" +#~ msgstr "Dath" + +#, fuzzy +#~ msgid "Spiral tool" +#~ msgstr "Spéisialta" + +#, fuzzy +#~ msgid "Delete segment between two nodes" +#~ msgstr "Tóg" + +#, fuzzy +#~ msgid "Select All in All Layers" +#~ msgstr "Tóg" + +#, fuzzy +#~ msgid "Invert Selection" +#~ msgstr "Tóg" + +#, fuzzy +#~ msgid "Clean up selected path(s)" +#~ msgstr "Tóg" + +#, fuzzy +#~ msgid "_Scripts..." +#~ msgstr "Priontáil" + +#, fuzzy +#~ msgid "Align and Distribute" +#~ msgstr "Tóg" + +#, fuzzy +#~ msgid "Align and Distribute Dialog" +#~ msgstr "Tóg" + +#, fuzzy +#~ msgid "Export Dialog" +#~ msgstr "Spéisialta" + +#, fuzzy +#~ msgid "Fill and Stroke Dialog" +#~ msgstr "Roghanna Dath" + +#, fuzzy +#~ msgid "Inkscape Preferences" +#~ msgstr "Sodipodi" + +#, fuzzy +#~ msgid "Inkscape Preferences Dialog" +#~ msgstr "Sodipodi" + +#, fuzzy +#~ msgid "Layer Editor Dialog" +#~ msgstr "Tóg" + +#, fuzzy +#~ msgid "Text Properties Dialog" +#~ msgstr "Meid pictiúr" + +#, fuzzy +#~ msgid "Transformation Dialog" +#~ msgstr "Roghanna Oaf" + +#, fuzzy +#~ msgid "Tree Editor" +#~ msgstr "Priontáil comhad" + +#, fuzzy +#~ msgid "Row height:" +#~ msgstr "Airde" + +#, fuzzy +#~ msgid "Column width:" +#~ msgstr "Dath" + +#, fuzzy +#~ msgid "Creating anchor at (%g,%g)" +#~ msgstr "Scríobh teacs" + +#, fuzzy +#~ msgid "EPS Output Settings" +#~ msgstr "Roghanna Dath" + +#, fuzzy +#~ msgid "Inkscape" +#~ msgstr "Sodipodi" + +#, fuzzy +#~ msgid "Grid emphasis color" +#~ msgstr "Dath" + +#, fuzzy +#~ msgid "Background (also for export):" +#~ msgstr "Dath" + +#, fuzzy +#~ msgid "Fill:" +#~ msgstr "Comhad Nua" + +#, fuzzy +#~ msgid "Update Properties" +#~ msgstr "Meid pictiúr" + +#, fuzzy +#~ msgid "executable" +#~ msgstr "Priontáil" + +#, fuzzy +#~ msgid "file" +#~ msgstr "Comhad _Nua" + +#, fuzzy +#~ msgid "absolute" +#~ msgstr "Greamaigh" + +#, fuzzy +#~ msgid "SVG Files" +#~ msgstr "Oscáil comhad" + +#, fuzzy +#~ msgid "Layer Properties" +#~ msgstr "Meid pictiúr" + +#, fuzzy +#~ msgid "Select object(s) to tile." +#~ msgstr "Tóg" + +#, fuzzy +#~ msgid "Printable" +#~ msgstr "Priontáil comhad" + +#, fuzzy +#~ msgid "Document Name:" +#~ msgstr "Roghanna Dath" + +#, fuzzy +#~ msgid "Image URI:" +#~ msgstr "Meid pictiúr" + +#, fuzzy +#~ msgid "Flatness:" +#~ msgstr "Sábháil\t" + +#, fuzzy +#~ msgid "Trace: Selected object is not an image" +#~ msgstr "Tóg" + +#, fuzzy +#~ msgid "Coordinates:" +#~ msgstr "Dath 1" + +#, fuzzy +#~ msgid "typeset object" +#~ msgstr "Tóg" + +#, fuzzy +#~ msgid "Pattern Fill" +#~ msgstr "Priontáil comhad" + +#, fuzzy +#~ msgid "_Menu" +#~ msgstr "Oscáil" + +#, fuzzy +#~ msgid "Rect" +#~ msgstr "Tóg" + +#, fuzzy +#~ msgid "Ru_lers" +#~ msgstr "Comhad Nua" + +#, fuzzy +#~ msgid "Mode:" +#~ msgstr "Nód" + +#~ msgid "Value:" +#~ msgstr "Luach:" + +#, fuzzy +#~ msgid "Stroke settings" +#~ msgstr "Roghanna Dath" + +#, fuzzy +#~ msgid "New View" +#~ msgstr "Radharc Nua" + +#, fuzzy +#~ msgid "Fill and stroke settings" +#~ msgstr "Roghanna Dath" + +#, fuzzy +#~ msgid "Object transformations" +#~ msgstr "Roghanna Oaf" + +#, fuzzy +#~ msgid "Text editing and font settings" +#~ msgstr "Roghanna Dath" + +#, fuzzy +#~ msgid "Fill Rule" +#~ msgstr "Comhad Nua" + +#, fuzzy +#~ msgid "Tool has no options" +#~ msgstr "Roghanna Oaf" + +#, fuzzy +#~ msgid "Selected object has no curve, cannot outline." +#~ msgstr "Tóg" + +#, fuzzy +#~ msgid "Inkscape _Options" +#~ msgstr "Sodipodi" + +#, fuzzy +#~ msgid "Tool Optio_ns" +#~ msgstr "Roghanna Oaf" + +#, fuzzy +#~ msgid "gradientUnits" +#~ msgstr "Priontáil comhad" + +#, fuzzy +#~ msgid "nonzero" +#~ msgstr "Tada" + +#, fuzzy +#~ msgid "End color" +#~ msgstr "Dath" + +#, fuzzy +#~ msgid "Object Size and Position" +#~ msgstr "Roghanna Oaf" + +#, fuzzy +#~ msgid "Lower selected objects one position" +#~ msgstr "Tóg" + +#~ msgid "1:1" +#~ msgstr "1:1" + +#~ msgid "1:2" +#~ msgstr "1:2" + +#~ msgid "2:1" +#~ msgstr "2:1" + +#~ msgid "Sodipodi" +#~ msgstr "Sodipodi" + +#, fuzzy +#~ msgid "Desktop settings" +#~ msgstr "Roghanna Dath" + +#, fuzzy +#~ msgid "Display settings" +#~ msgstr "Roghanna Dath" + +#, fuzzy +#~ msgid "Document variant:" +#~ msgstr "Roghanna Dath" + +#, fuzzy +#~ msgid "About sodipodi" +#~ msgstr "Sodipodi" + +#, fuzzy +#~ msgid "About Sodipodi" +#~ msgstr "Sodipodi" + +#, fuzzy +#~ msgid "Choose fill color" +#~ msgstr "Dath 1" + +#~ msgid "1.0MB" +#~ msgstr "1.0MB" + +#~ msgid "X0" +#~ msgstr "X0" + +#~ msgid "Y0" +#~ msgstr "Y0" + +#, fuzzy +#~ msgid "Nope !" +#~ msgstr "Tada" + +#~ msgid "Key" +#~ msgstr "Eoachair" + +#, fuzzy +#~ msgid "No" +#~ msgstr "Nód" + +#, fuzzy +#~ msgid "Pixels\n" +#~ msgstr "pixelanna" + +#~ msgid "Up" +#~ msgstr "Suas" + +#~ msgid "left" +#~ msgstr "clé" diff --git a/po/gl.po b/po/gl.po new file mode 100644 index 000000000..c65d2b67c --- /dev/null +++ b/po/gl.po @@ -0,0 +1,11428 @@ +# Traducción ó Galego de Sodipodi +# Copyright (C) 2000 Francisco Xosé Vázquez Grandal. +# Francisco Xosé Vázquez Grandal , 2001. +# +# O teu SO en Galego ¿en que se non?. ¡¡MOITO TRASNO!! +# +# ESTA TRADUCCIÓN MELLORA COS ANOS. AMIGUIÑO, OS GALEGOS SOMOSCHE ASI. +# +# () \\ Fco. Xosé Vázquez Grandal +# ^ (o_ \\ mailto:fxvazquez@arrakis.es +# | /)\c{} \\ http://www.arrakis.es/~fxvazquez/ +# `-V__)_ \\ http://www.trasno.net +# +msgid "" +msgstr "" +"Project-Id-Version: 0.23\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2005-12-04 11:51-0800\n" +"PO-Revision-Date: 2001-11-10 16:49GMT\n" +"Last-Translator: Francisco Xosé Vázquez Grandal \n" +"Language-Team: Galician \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 0.9.5\n" + +#: ../inkscape.desktop.in.h:1 +msgid "Create and edit Scalable Vector Graphics images" +msgstr "" + +#: ../inkscape.desktop.in.h:2 +msgid "Inkscape SVG Vector Illustrator" +msgstr "" + +#: ../../po/../src/arc-context.cpp:350 +msgid "" +"Ctrl: make circle or integer-ratio ellipse, snap arc/segment angle" +msgstr "" + +#: ../../po/../src/arc-context.cpp:351 ../../po/../src/rect-context.cpp:388 +msgid "Shift: draw around the starting point" +msgstr "" + +#: ../../po/../src/arc-context.cpp:413 +#: ../../po/../src/connector-context.cpp:493 +#: ../../po/../src/dyna-draw-context.cpp:506 +#: ../../po/../src/pen-context.cpp:329 ../../po/../src/pencil-context.cpp:208 +#: ../../po/../src/rect-context.cpp:452 ../../po/../src/spiral-context.cpp:421 +#: ../../po/../src/star-context.cpp:427 +msgid "Current layer is hidden. Unhide it to be able to draw on it." +msgstr "" + +#: ../../po/../src/arc-context.cpp:417 +#: ../../po/../src/connector-context.cpp:497 +#: ../../po/../src/dyna-draw-context.cpp:510 +#: ../../po/../src/pen-context.cpp:336 ../../po/../src/pencil-context.cpp:212 +#: ../../po/../src/rect-context.cpp:456 ../../po/../src/spiral-context.cpp:426 +#: ../../po/../src/star-context.cpp:431 +msgid "Current layer is locked. Unlock it to be able to draw on it." +msgstr "" + +#: ../../po/../src/arc-context.cpp:496 +#, c-format +msgid "" +"Ellipse: %s × %s; with Ctrl to make circle or integer-" +"ratio ellipse; with Shift to draw around the starting point" +msgstr "" + +#: ../../po/../src/connector-context.cpp:518 +#, fuzzy +msgid "Creating new connector" +msgstr "Documento" + +#: ../../po/../src/connector-context.cpp:939 +#, fuzzy +msgid "Finishing connector" +msgstr "Man alzada" + +#: ../../po/../src/connector-context.cpp:1108 +msgid "Connection point: click or drag to create a new connector" +msgstr "" + +#: ../../po/../src/connector-context.cpp:1185 +msgid "Connector endpoint: drag to reroute or connect to new shapes" +msgstr "" + +# [*] Revisar +#: ../../po/../src/connector-context.cpp:1278 +#, fuzzy +msgid "Select at least one non-connector object." +msgstr "Voltea-los obxectos seleccionados" + +#: ../../po/../src/desktop-events.cpp:238 +#, c-format +msgid "%s at %s" +msgstr "" + +#. TRANSLATORS: This string appears when double-clicking on a guide. +#. This is the distance by which the guide is to be moved. +#: ../../po/../src/desktop-events.cpp:277 +#, fuzzy +msgid " relative by " +msgstr "movemento vertical" + +#. TRANSLATORS: This string appears when double-clicking on a guide. +#. This is the target location where the guide is to be moved. +#: ../../po/../src/desktop-events.cpp:282 +#: ../../po/../src/desktop-events.cpp:395 +#, fuzzy +msgid " absolute to " +msgstr "absoluto" + +#. create dialog +#: ../../po/../src/desktop-events.cpp:348 +#, fuzzy +msgid "Guideline" +msgstr "Cor da guía liña" + +#: ../../po/../src/desktop-events.cpp:432 +#, fuzzy, c-format +msgid "Move %s" +msgstr "Mover" + +#: ../../po/../src/desktop.cpp:678 +msgid "No previous zoom." +msgstr "" + +#: ../../po/../src/desktop.cpp:703 +msgid "No next zoom." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:182 +#, fuzzy +msgid "Nothing selected." +msgstr "Último seleccionado" + +#: ../../po/../src/dialogs/clonetiler.cpp:188 +msgid "More than one object selected." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:195 +#, c-format +msgid "Object has %d tiled clones." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:200 +msgid "Object has no tiled clones." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:865 +#, fuzzy +msgid "Select one object whose tiled clones to unclump." +msgstr "Converti-los obxectos seleccionados a curvas" + +#: ../../po/../src/dialogs/clonetiler.cpp:916 +#, fuzzy +msgid "Select one object whose tiled clones to remove." +msgstr "Converti-los obxectos seleccionados a curvas" + +#: ../../po/../src/dialogs/clonetiler.cpp:984 +#: ../../po/../src/selection-chemistry.cpp:1774 +#, fuzzy +msgid "Select an object to clone." +msgstr "Converti-los obxectos seleccionados a curvas" + +#: ../../po/../src/dialogs/clonetiler.cpp:990 +#: ../../po/../src/selection-chemistry.cpp:1780 +msgid "" +"If you want to clone several objects, group them and clone the " +"group." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1484 +msgid "Per row:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1497 +#, fuzzy +msgid "Per column:" +msgstr "Último seleccionado" + +#: ../../po/../src/dialogs/clonetiler.cpp:1505 +#, fuzzy +msgid "Randomize:" +msgstr "Último seleccionado" + +#: ../../po/../src/dialogs/clonetiler.cpp:1656 +#, fuzzy +msgid "_Symmetry" +msgstr "Simétrico " + +#. TRANSLATORS: For the following 17 symmetry groups, see +#. * http://www.bib.ulb.ac.be/coursmath/doc/17.htm (visual examples); +#. * http://www.clarku.edu/~djoyce/wallpaper/seventeen.html (English vocabulary); or +#. * http://membres.lycos.fr/villemingerard/Geometri/Sym1D.htm (French vocabulary). +#. +#: ../../po/../src/dialogs/clonetiler.cpp:1664 +msgid "Select one of the 17 symmetry groups for the tiling" +msgstr "" + +#. TRANSLATORS: "translation" means "shift" / "displacement" here. +#: ../../po/../src/dialogs/clonetiler.cpp:1675 +msgid "P1: simple translation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1676 +msgid "P2: 180° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1677 +msgid "PM: reflection" +msgstr "" + +#. TRANSLATORS: "glide reflection" is a reflection and a translation combined. +#. For more info, see http://mathforum.org/sum95/suzanne/symsusan.html +#: ../../po/../src/dialogs/clonetiler.cpp:1680 +msgid "PG: glide reflection" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1681 +msgid "CM: reflection + glide reflection" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1682 +msgid "PMM: reflection + reflection" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1683 +msgid "PMG: reflection + 180° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1684 +msgid "PGG: glide reflection + 180° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1685 +msgid "CMM: reflection + reflection + 180° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1686 +msgid "P4: 90° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1687 +msgid "P4M: 90° rotation + 45° reflection" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1688 +msgid "P4G: 90° rotation + 90° reflection" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1689 +msgid "P3: 120° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1690 +msgid "P31M: reflection + 120° rotation, dense" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1691 +msgid "P3M1: reflection + 120° rotation, sparse" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1692 +msgid "P6: 60° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1693 +msgid "P6M: reflection + 60° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1721 +msgid "S_hift" +msgstr "" + +#. TRANSLATORS: "shift" means: the tiles will be shifted (offset) horizontally by this amount +#: ../../po/../src/dialogs/clonetiler.cpp:1731 +#, fuzzy, no-c-format +msgid "Shift X:" +msgstr "Cambiar" + +#: ../../po/../src/dialogs/clonetiler.cpp:1739 +#, no-c-format +msgid "Horizontal shift per row (in % of tile width)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1747 +#, no-c-format +msgid "Horizontal shift per column (in % of tile width)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1754 +msgid "Randomize the horizontal shift by this percentage" +msgstr "" + +#. TRANSLATORS: "shift" means: the tiles will be shifted (offset) vertically by this amount +#: ../../po/../src/dialogs/clonetiler.cpp:1764 +#, fuzzy, no-c-format +msgid "Shift Y:" +msgstr "Cambiar" + +#: ../../po/../src/dialogs/clonetiler.cpp:1772 +#, no-c-format +msgid "Vertical shift per row (in % of tile height)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1780 +#, no-c-format +msgid "Vertical shift per column (in % of tile height)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1787 +msgid "Randomize the vertical shift by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1795 +#, fuzzy +msgid "Exponent:" +msgstr "Cambiar" + +#: ../../po/../src/dialogs/clonetiler.cpp:1802 +msgid "Whether rows are spaced evenly (1), converge (<1) or diverge (>1)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1809 +msgid "Whether columns are spaced evenly (1), converge (<1) or diverge (>1)" +msgstr "" + +#. TRANSLATORS: "Alternate" is a verb here +#: ../../po/../src/dialogs/clonetiler.cpp:1817 +#: ../../po/../src/dialogs/clonetiler.cpp:1907 +#: ../../po/../src/dialogs/clonetiler.cpp:1966 +#: ../../po/../src/dialogs/clonetiler.cpp:2022 +#: ../../po/../src/dialogs/clonetiler.cpp:2153 +msgid "Alternate:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1823 +msgid "Alternate the sign of shifts for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1828 +msgid "Alternate the sign of shifts for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1837 +#, fuzzy +msgid "Sc_ale" +msgstr "Escala" + +#: ../../po/../src/dialogs/clonetiler.cpp:1845 +#, fuzzy +msgid "Scale X:" +msgstr "Cambiar" + +#: ../../po/../src/dialogs/clonetiler.cpp:1853 +#, fuzzy, no-c-format +msgid "Horizontal scale per row (in % of tile width)" +msgstr "valor de escala horizontal" + +#: ../../po/../src/dialogs/clonetiler.cpp:1861 +#, fuzzy, no-c-format +msgid "Horizontal scale per column (in % of tile width)" +msgstr "valor de escala horizontal" + +#: ../../po/../src/dialogs/clonetiler.cpp:1868 +msgid "Randomize the horizontal scale by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1876 +#, fuzzy +msgid "Scale Y:" +msgstr "Cambiar" + +#: ../../po/../src/dialogs/clonetiler.cpp:1884 +#, fuzzy, no-c-format +msgid "Vertical scale per row (in % of tile height)" +msgstr "valor de escala vertical" + +#: ../../po/../src/dialogs/clonetiler.cpp:1892 +#, fuzzy, no-c-format +msgid "Vertical scale per column (in % of tile height)" +msgstr "valor de escala vertical" + +#: ../../po/../src/dialogs/clonetiler.cpp:1899 +msgid "Randomize the vertical scale by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1913 +#, fuzzy +msgid "Alternate the sign of scales for each row" +msgstr "valor de escala vertical" + +#: ../../po/../src/dialogs/clonetiler.cpp:1918 +#, fuzzy +msgid "Alternate the sign of scales for each column" +msgstr "valor de escala vertical" + +#: ../../po/../src/dialogs/clonetiler.cpp:1927 +#, fuzzy +msgid "_Rotation" +msgstr "Selección" + +#: ../../po/../src/dialogs/clonetiler.cpp:1935 +#, fuzzy +msgid "Angle:" +msgstr "Cambiar" + +#: ../../po/../src/dialogs/clonetiler.cpp:1943 +#, no-c-format +msgid "Rotate tiles by this angle for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1951 +#, no-c-format +msgid "Rotate tiles by this angle for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1958 +msgid "Randomize the rotation angle by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1972 +msgid "Alternate the rotation direction for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1977 +msgid "Alternate the rotation direction for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1985 +#, fuzzy +msgid "_Opacity" +msgstr "Opacidade:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1993 +#, fuzzy +msgid "Fade out:" +msgstr "Cambiar" + +#: ../../po/../src/dialogs/clonetiler.cpp:2000 +msgid "Decrease tile opacity by this percentage for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2007 +msgid "Decrease tile opacity by this percentage for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2014 +msgid "Randomize the tile opacity by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2028 +msgid "Alternate the sign of opacity change for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2033 +msgid "Alternate the sign of opacity change for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2041 +#, fuzzy +msgid "Co_lor" +msgstr "Cor:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2046 +#, fuzzy +msgid "Initial color: " +msgstr "Cor do recheo : " + +#: ../../po/../src/dialogs/clonetiler.cpp:2050 +msgid "Initial color of tiled clones" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2050 +msgid "" +"Initial color for clones (works only if the original has unset fill or " +"stroke)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2065 +#, fuzzy +msgid "H:" +msgstr "Cambiar" + +#: ../../po/../src/dialogs/clonetiler.cpp:2072 +msgid "Change the tile hue by this percentage for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2079 +msgid "Change the tile hue by this percentage for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2086 +msgid "Randomize the tile hue by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2095 +#, fuzzy +msgid "S:" +msgstr "Cambiar" + +#: ../../po/../src/dialogs/clonetiler.cpp:2102 +msgid "Change the color saturation by this percentage for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2109 +msgid "Change the color saturation by this percentage for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2116 +msgid "Randomize the color saturation by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2124 +#, fuzzy +msgid "L:" +msgstr "Cambiar" + +#: ../../po/../src/dialogs/clonetiler.cpp:2131 +msgid "Change the color lightness by this percentage for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2138 +msgid "Change the color lightness by this percentage for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2145 +msgid "Randomize the color lightness by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2159 +msgid "Alternate the sign of color changes for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2164 +msgid "Alternate the sign of color changes for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2172 +#, fuzzy +msgid "_Trace" +msgstr "Bitmap roto" + +#: ../../po/../src/dialogs/clonetiler.cpp:2179 +msgid "Trace the drawing under the tiles" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2183 +msgid "" +"For each clone, pick a value from the drawing in that clone's location and " +"apply it to the clone" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2197 +msgid "1. Pick from the drawing:" +msgstr "" + +#. ----Hbox2 +#: ../../po/../src/dialogs/clonetiler.cpp:2208 +#: ../../po/../src/dialogs/clonetiler.cpp:2355 +#: ../../po/../src/ui/dialog/tracedialog.cpp:445 +#, fuzzy +msgid "Color" +msgstr "Cor:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2209 +msgid "Pick the visible color and opacity" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2216 +#: ../../po/../src/dialogs/clonetiler.cpp:2365 +#: ../share/extensions/dropshadow.inx.h:3 +#, fuzzy +msgid "Opacity" +msgstr "Opacidade:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2217 +msgid "Pick the total accumulated opacity" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2224 +msgid "R" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2225 +msgid "Pick the Red component of the color" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2232 +msgid "G" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2233 +msgid "Pick the Green component of the color" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2240 +msgid "B" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2241 +msgid "Pick the Blue component of the color" +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2250 +msgid "clonetiler|H" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2251 +#, fuzzy +msgid "Pick the hue of the color" +msgstr "Escolle-la cor da liña" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2260 +msgid "clonetiler|S" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2261 +#, fuzzy +msgid "Pick the saturation of the color" +msgstr "Escolle-la cor da liña" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2270 +msgid "clonetiler|L" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2271 +msgid "Pick the lightness of the color" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2281 +msgid "2. Tweak the picked value:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2291 +msgid "Gamma-correct:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2296 +msgid "Shift the mid-range of the picked value upwards (>0) or downwards (<0)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2303 +msgid "Randomize:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2308 +msgid "Randomize the picked value by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2315 +#, fuzzy +msgid "Invert:" +msgstr "polgada" + +#: ../../po/../src/dialogs/clonetiler.cpp:2319 +msgid "Invert the picked value" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2325 +msgid "3. Apply the value to the clones':" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2335 +#, fuzzy +msgid "Presence" +msgstr "O elemento é de referencia" + +#: ../../po/../src/dialogs/clonetiler.cpp:2338 +msgid "" +"Each clone is created with the probability determined by the picked value in " +"that point" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2345 +#, fuzzy +msgid "Size" +msgstr "Guías" + +#: ../../po/../src/dialogs/clonetiler.cpp:2348 +msgid "Each clone's size is determined by the picked value in that point" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2358 +msgid "" +"Each clone is painted by the picked color (the original must have unset fill " +"or stroke)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2368 +msgid "Each clone's opacity is determined by the picked value in that point" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2395 +msgid "How many rows in the tiling" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2415 +msgid "How many columns in the tiling" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2445 +msgid "Width of the rectangle to be filled" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2470 +msgid "Height of the rectangle to be filled" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2485 +#, fuzzy +msgid "Rows, columns: " +msgstr "Cambiar" + +#: ../../po/../src/dialogs/clonetiler.cpp:2486 +msgid "Create the specified number of rows and columns" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2495 +#, fuzzy +msgid "Width, height: " +msgstr "Alto:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2496 +msgid "Fill the specified width and height with the tiling" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2512 +#, fuzzy +msgid "Use saved size and position of the tile" +msgstr "Posición" + +#: ../../po/../src/dialogs/clonetiler.cpp:2515 +msgid "" +"Pretend that the size and position of the tile are the same as the last time " +"you tiled it (if any), instead of using the current size" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2539 +#, fuzzy +msgid " _Create " +msgstr "Cambiar" + +#: ../../po/../src/dialogs/clonetiler.cpp:2541 +msgid "Create and tile the clones of the selection" +msgstr "" + +#. TRANSLATORS: if a group of objects are "clumped" together, then they +#. are unevenly spread in the given amount of space - as shown in the +#. diagrams on the left in the following screenshot: +#. http://www.inkscape.org/screenshots/gallery/inkscape-0.42-CVS-tiles-unclump.png +#. So unclumping is the process of spreading a number of objects out more evenly. +#: ../../po/../src/dialogs/clonetiler.cpp:2556 +msgid " _Unclump " +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2557 +msgid "Spread out clones to reduce clumping; can be applied repeatedly" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2563 +msgid " Re_move " +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2564 +msgid "Remove existing tiled clones of the selected object (siblings only)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2580 +msgid " R_eset " +msgstr "" + +#. TRANSLATORS: "change" is a noun here +#: ../../po/../src/dialogs/clonetiler.cpp:2582 +msgid "" +"Reset all shifts, scales, rotates, opacity and color changes in the dialog " +"to zero" +msgstr "" + +#: ../../po/../src/dialogs/color-picker.cpp:280 +#, fuzzy +msgid "Close" +msgstr "Nova vista" + +#: ../../po/../src/dialogs/debugdialog.cpp:138 +msgid "Messages" +msgstr "" + +#. ## Add a menu for clear() +#: ../../po/../src/dialogs/debugdialog.cpp:144 +#: ../../po/../src/menus-skeleton.h:16 +#: ../../po/../src/ui/dialog/messages.cpp:56 +#: ../../po/../src/ui/dialog/scriptdialog.cpp:181 +msgid "_File" +msgstr "_Ficheiro" + +#. TRANSLATORS: "Clear" is a verb here +#: ../../po/../src/dialogs/debugdialog.cpp:145 +#: ../../po/../src/dialogs/find.cpp:753 +#: ../../po/../src/ui/dialog/messages.cpp:57 +#: ../../po/../src/ui/dialog/scriptdialog.cpp:182 +#, fuzzy +msgid "_Clear" +msgstr "Nova vista" + +#: ../../po/../src/dialogs/debugdialog.cpp:147 +#: ../../po/../src/ui/dialog/messages.cpp:59 +msgid "Capture log messages" +msgstr "" + +#: ../../po/../src/dialogs/debugdialog.cpp:149 +#: ../../po/../src/ui/dialog/messages.cpp:61 +msgid "Release log messages" +msgstr "" + +#. Notebook tab +#: ../../po/../src/dialogs/desktop-properties.cpp:909 +#: ../../po/../src/ui/dialog/document-preferences.cpp:89 +#: ../../po/../src/ui/widget/panel.cpp:107 +msgid "Grid" +msgstr "Reixa" + +#. Checkbuttons +#. / \todo FIXME: gray out snapping when grid is off +#. / \todo FIXME: gray out snapping when grid is off. +#. / Dissenting view: you want snapping without grid. +#: ../../po/../src/dialogs/desktop-properties.cpp:917 +#: ../../po/../src/ui/dialog/document-preferences.cpp:179 +msgid "Show grid" +msgstr "Amosa-la reixa" + +#: ../../po/../src/dialogs/desktop-properties.cpp:917 +#: ../../po/../src/ui/dialog/document-preferences.cpp:179 +#: ../../po/../src/verbs.cpp:2115 +#, fuzzy +msgid "Show or hide grid" +msgstr "Amosa-la reixa" + +#: ../../po/../src/dialogs/desktop-properties.cpp:918 +#: ../../po/../src/ui/dialog/document-preferences.cpp:180 +#, fuzzy +msgid "Snap bounding boxes to grid" +msgstr "Enganchar á reixa" + +#: ../../po/../src/dialogs/desktop-properties.cpp:918 +#: ../../po/../src/dialogs/desktop-properties.cpp:1001 +#: ../../po/../src/ui/dialog/document-preferences.cpp:181 +#: ../../po/../src/ui/dialog/document-preferences.cpp:236 +msgid "Snap the edges of the object bounding boxes" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:919 +#: ../../po/../src/ui/dialog/document-preferences.cpp:183 +#, fuzzy +msgid "Snap nodes to grid" +msgstr "Enganchar á reixa" + +#: ../../po/../src/dialogs/desktop-properties.cpp:919 +#: ../../po/../src/dialogs/desktop-properties.cpp:1002 +#: ../../po/../src/ui/dialog/document-preferences.cpp:184 +#: ../../po/../src/ui/dialog/document-preferences.cpp:239 +msgid "Snap path nodes, text baselines, ellipse centers, etc." +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:937 +#: ../../po/../src/ui/dialog/document-preferences.cpp:186 +msgid "Grid units:" +msgstr "Unidades da reixa:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:939 +#: ../../po/../src/ui/dialog/document-preferences.cpp:187 +msgid "Origin X:" +msgstr "Orixe X:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:942 +#: ../../po/../src/ui/dialog/document-preferences.cpp:189 +msgid "Origin Y:" +msgstr "Orixe Y:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:945 +#: ../../po/../src/ui/dialog/document-preferences.cpp:191 +msgid "Spacing X:" +msgstr "Separación X:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:948 +#: ../../po/../src/ui/dialog/document-preferences.cpp:193 +msgid "Spacing Y:" +msgstr "Separación Y:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:952 +#: ../../po/../src/dialogs/desktop-properties.cpp:1013 +#: ../../po/../src/ui/dialog/document-preferences.cpp:195 +#: ../../po/../src/ui/dialog/document-preferences.cpp:241 +msgid "Snap units:" +msgstr "Unidades de enganche:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:955 +#: ../../po/../src/dialogs/desktop-properties.cpp:1016 +#: ../../po/../src/ui/dialog/document-preferences.cpp:196 +#: ../../po/../src/ui/dialog/document-preferences.cpp:242 +msgid "Snap distance:" +msgstr "Distancia de enganche:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:958 +#: ../../po/../src/ui/dialog/document-preferences.cpp:199 +#, fuzzy +msgid "Grid line color:" +msgstr "Cor da guía liña" + +#: ../../po/../src/dialogs/desktop-properties.cpp:959 +#: ../../po/../src/ui/dialog/document-preferences.cpp:199 +#, fuzzy +msgid "Grid line color" +msgstr "Cor da guía liña" + +#: ../../po/../src/dialogs/desktop-properties.cpp:959 +#: ../../po/../src/ui/dialog/document-preferences.cpp:200 +#, fuzzy +msgid "Color of grid lines" +msgstr "Escolle-las cores para as liñas guía" + +#: ../../po/../src/dialogs/desktop-properties.cpp:961 +#: ../../po/../src/ui/dialog/document-preferences.cpp:201 +#, fuzzy +msgid "Major grid line color:" +msgstr "Cor da guía liña" + +#: ../../po/../src/dialogs/desktop-properties.cpp:962 +#: ../../po/../src/ui/dialog/document-preferences.cpp:201 +#, fuzzy +msgid "Major grid line color" +msgstr "Cor da guía liña" + +#: ../../po/../src/dialogs/desktop-properties.cpp:962 +#: ../../po/../src/ui/dialog/document-preferences.cpp:202 +#, fuzzy +msgid "Color of the major (highlighted) grid lines" +msgstr "Escolle-la cor para as liñas guía destacadas" + +#: ../../po/../src/dialogs/desktop-properties.cpp:965 +#: ../../po/../src/ui/dialog/document-preferences.cpp:204 +#, fuzzy +msgid "Major grid line every:" +msgstr "Cor da guía liña" + +#. TRANSLATORS: This belongs to the "Major grid line every:" string, +#. see grid settings in the "Document Preferences" dialog +#: ../../po/../src/dialogs/desktop-properties.cpp:977 +#: ../../po/../src/ui/dialog/document-preferences.cpp:204 +#, fuzzy +msgid "lines" +msgstr "Nova vista" + +#. Guidelines page +#: ../../po/../src/dialogs/desktop-properties.cpp:991 +#: ../../po/../src/ui/dialog/document-preferences.cpp:90 +msgid "Guides" +msgstr "Guías" + +#. / \todo FIXME: gray out snapping when guides are off +#. / Dissenting view: you want snapping without guides. +#: ../../po/../src/dialogs/desktop-properties.cpp:1000 +#: ../../po/../src/ui/dialog/document-preferences.cpp:234 +msgid "Show guides" +msgstr "Amosar guías" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1000 +#: ../../po/../src/ui/dialog/document-preferences.cpp:234 +#: ../../po/../src/verbs.cpp:2116 +#, fuzzy +msgid "Show or hide guides" +msgstr "Amosar guías" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1001 +#: ../../po/../src/ui/dialog/document-preferences.cpp:235 +#, fuzzy +msgid "Snap bounding boxes to guides" +msgstr "Enganchar ás guías" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1002 +#: ../../po/../src/ui/dialog/document-preferences.cpp:238 +#, fuzzy +msgid "Snap points to guides" +msgstr "Enganchar á reixa" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1020 +#: ../../po/../src/ui/dialog/document-preferences.cpp:243 +#, fuzzy +msgid "Guide color:" +msgstr "Cor das guías" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1021 +#: ../../po/../src/ui/dialog/document-preferences.cpp:243 +msgid "Guideline color" +msgstr "Cor da guía liña" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1021 +#: ../../po/../src/ui/dialog/document-preferences.cpp:244 +#, fuzzy +msgid "Color of guidelines" +msgstr "Escolle-las cores para as liñas guía" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1023 +#: ../../po/../src/ui/dialog/document-preferences.cpp:245 +msgid "Highlight color:" +msgstr "Cor de destaque" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1024 +#: ../../po/../src/ui/dialog/document-preferences.cpp:245 +#, fuzzy +msgid "Highlighted guideline color" +msgstr "Cor da liña guía destacada" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1024 +#: ../../po/../src/ui/dialog/document-preferences.cpp:246 +msgid "Color of a guideline when it is under mouse" +msgstr "" + +#. Page page +#: ../../po/../src/dialogs/desktop-properties.cpp:1029 +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:855 +#: ../../po/../src/ui/dialog/document-preferences.cpp:88 +#: ../../po/../src/widgets/desktop-widget.cpp:1061 +msgid "Page" +msgstr "Páxina" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1039 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +#, fuzzy +msgid "Background:" +msgstr "Cor da reixa" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1040 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +#, fuzzy +msgid "Background color" +msgstr "Cor da reixa" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1041 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +msgid "" +"Color and transparency of the page background (also used for bitmap export)" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1045 +#: ../../po/../src/ui/dialog/document-preferences.cpp:147 +#, fuzzy +msgid "Show page border" +msgstr "Amosa-la reixa" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1049 +#: ../../po/../src/ui/dialog/document-preferences.cpp:148 +#, fuzzy +msgid "Border on top of drawing" +msgstr "Zoom ó debuxo" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1052 +#: ../../po/../src/ui/dialog/document-preferences.cpp:149 +#, fuzzy +msgid "Border color:" +msgstr "Cor da reixa:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1053 +#: ../../po/../src/ui/dialog/document-preferences.cpp:149 +#, fuzzy +msgid "Page border color" +msgstr "Cor da reixa:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1054 +#: ../../po/../src/ui/dialog/document-preferences.cpp:150 +#, fuzzy +msgid "Color of the page border" +msgstr "Amosa-la reixa" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1059 +#: ../../po/../src/ui/dialog/document-preferences.cpp:152 +msgid "Show page shadow" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1063 +#: ../../po/../src/ui/dialog/document-preferences.cpp:153 +#, fuzzy +msgid "Default units:" +msgstr "Borrar" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1069 +msgid "Units for the tool controls, ruler, and the statusbar" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1086 +#: ../../po/../src/ui/widget/page-sizer.cpp:209 +#, fuzzy +msgid "Page size:" +msgstr "Tamaño do Papel:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1110 +#: ../../po/../src/ui/widget/page-sizer.cpp:219 +msgid "Custom" +msgstr "Persoalizado" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1121 +#: ../../po/../src/ui/widget/page-sizer.cpp:225 +#, fuzzy +msgid "Page orientation:" +msgstr "Tamaño do Papel:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1133 +#: ../../po/../src/ui/widget/page-sizer.cpp:232 +#, fuzzy +msgid "Landscape" +msgstr "Sodipodi" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1139 +#: ../../po/../src/ui/widget/page-sizer.cpp:234 +#, fuzzy +msgid "Portrait" +msgstr "Punto" + +#. Custom paper frame +#: ../../po/../src/dialogs/desktop-properties.cpp:1148 +#: ../../po/../src/ui/widget/page-sizer.cpp:249 +#, fuzzy +msgid "Custom size" +msgstr "Persoalizado" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1160 +#: ../../po/../src/dialogs/export.cpp:269 +#: ../../po/../src/ui/widget/page-sizer.cpp:261 +msgid "Units:" +msgstr "Unidades:" + +#. Stroke width +#: ../../po/../src/dialogs/desktop-properties.cpp:1162 +#: ../../po/../src/dialogs/export.cpp:310 +#: ../../po/../src/dialogs/object-attributes.cpp:55 +#: ../../po/../src/dialogs/stroke-style.cpp:985 +#: ../../po/../src/ui/widget/page-sizer.cpp:262 +#: ../../po/../src/widgets/toolbox.cpp:1957 +msgid "Width:" +msgstr "Ancho:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1183 +#: ../../po/../src/dialogs/export.cpp:326 +#: ../../po/../src/dialogs/export.cpp:431 +#: ../../po/../src/dialogs/object-attributes.cpp:56 +#: ../../po/../src/ui/widget/page-sizer.cpp:263 +msgid "Height:" +msgstr "Alto:" + +#. +#. * Ownership metadata tab +#. +#: ../../po/../src/dialogs/desktop-properties.cpp:1206 +msgid "Metadata" +msgstr "" + +#. add license selector pull-down +#: ../../po/../src/dialogs/desktop-properties.cpp:1225 +#, fuzzy +msgid "License" +msgstr "polgada" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1255 +msgid "Proprietary" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:212 +#, fuzzy +msgid "When transforming, show:" +msgstr "Reinicia-la transformación" + +#: ../../po/../src/dialogs/display-settings.cpp:223 +#, fuzzy +msgid "Objects" +msgstr "Obxecto" + +#: ../../po/../src/dialogs/display-settings.cpp:224 +msgid "Show the actual objects when moving or transforming" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:231 +#, fuzzy +msgid "Box outline" +msgstr "Amosar guías" + +#: ../../po/../src/dialogs/display-settings.cpp:232 +msgid "Show only a box outline of the objects when moving or transforming" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:238 +#, fuzzy +msgid "Per-object selection cue:" +msgstr "Converti-los obxectos seleccionados a curvas" + +#. sorationsnapsperpi == 0 means no snapping +#: ../../po/../src/dialogs/display-settings.cpp:249 +#: ../../po/../src/dialogs/display-settings.cpp:386 +#: ../../po/../src/dialogs/display-settings.cpp:441 +#: ../../po/../src/dialogs/display-settings.cpp:1482 +#: ../../po/../src/dialogs/stroke-style.cpp:791 +#: ../../po/../src/interface.cpp:741 +#: ../../po/../src/ui/widget/selected-style.cpp:100 +#: ../../po/../src/verbs.cpp:1842 +msgid "None" +msgstr "Ningun" + +#: ../../po/../src/dialogs/display-settings.cpp:250 +msgid "No per-object selection indication" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:256 +msgid "Mark" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:257 +msgid "Each selected object has a diamond mark in the top left corner" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:264 +msgid "Box" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:265 +msgid "Each selected object displays its bounding box" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:270 +msgid "Default scale origin:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:281 +#, fuzzy +msgid "Opposite bounding box edge" +msgstr "Enganchar á reixa" + +#: ../../po/../src/dialogs/display-settings.cpp:282 +msgid "Default scale origin will be on the bounding box of the item" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:288 +msgid "Farthest opposite node" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:289 +msgid "Default scale origin will be on the bounding box of the item's points" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:341 +#, fuzzy +msgid "degrees" +msgstr "grado" + +#: ../../po/../src/dialogs/display-settings.cpp:350 +msgid "" +"Rotating with Ctrl pressed snaps every that much degrees; also, pressing " +"[ or ] rotates by this amount" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:407 +msgid "Rotation snaps every:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:430 +msgid "" +"None: dialogs are treated as regular windows; Normal: dialogs stay on top of " +"document windows; Aggressive: same as Normal but may work better with some " +"window managers." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:451 +msgid "Normal" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:461 +msgid "Aggressive" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:475 +msgid "Dialogs on top:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:645 +#, fuzzy +msgid "Show selection cue" +msgstr "Converti-los obxectos seleccionados a curvas" + +#: ../../po/../src/dialogs/display-settings.cpp:646 +msgid "" +"Whether selected objects display a selection cue (the same as in selector)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:657 +#, fuzzy +msgid "Enable gradient editing" +msgstr "Degradado" + +#: ../../po/../src/dialogs/display-settings.cpp:658 +msgid "Whether selected objects display gradient editing controls" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:719 +#, fuzzy +msgid "No objects selected to take the style from." +msgstr "Converti-los obxectos seleccionados a curvas" + +#: ../../po/../src/dialogs/display-settings.cpp:728 +msgid "" +"More than one object selected. Cannot take style from multiple " +"objects." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:767 +#, fuzzy +msgid "Create new objects with:" +msgstr "Engadir atributo" + +#: ../../po/../src/dialogs/display-settings.cpp:777 +#, fuzzy +msgid "Take from selection" +msgstr "Transforma-la selección" + +#: ../../po/../src/dialogs/display-settings.cpp:778 +msgid "Remember the style of the (first) selected object as this tool's style" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:782 +#, fuzzy +msgid "Last used style" +msgstr "Ancho do trazado" + +#: ../../po/../src/dialogs/display-settings.cpp:782 +msgid "Apply the style you last set on an object" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:790 +msgid "This tool's own style:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:790 +msgid "" +"Each tool may store its own style to apply to the newly created objects. Use " +"the button below to set it." +msgstr "" + +#. Mouse +#: ../../po/../src/dialogs/display-settings.cpp:877 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:55 +#, fuzzy +msgid "Mouse" +msgstr "Mover" + +#. TRANSLATORS: "Grab" is a noun here. "Grab sensitivity" is intended to mean how +#. * close on the screen you need to be to an object to be able to grab it with mouse (in +#. * pixels). +#: ../../po/../src/dialogs/display-settings.cpp:883 +#, fuzzy +msgid "Grab sensitivity:" +msgstr "Facer sensible" + +#: ../../po/../src/dialogs/display-settings.cpp:884 +msgid "" +"How close on the screen you need to be to an object to be able to grab it " +"with mouse (in screen pixels)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:885 +#: ../../po/../src/dialogs/display-settings.cpp:897 +#: ../../po/../src/dialogs/display-settings.cpp:912 +#: ../../po/../src/dialogs/display-settings.cpp:930 +#: ../../po/../src/dialogs/display-settings.cpp:970 +msgid "pixels" +msgstr "Pixeles" + +#: ../../po/../src/dialogs/display-settings.cpp:895 +msgid "Click/drag threshold:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:896 +msgid "" +"Maximum mouse drag (in screen pixels) which is considered a click, not a drag" +msgstr "" + +#. Scrolling +#: ../../po/../src/dialogs/display-settings.cpp:907 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:56 +msgid "Scrolling" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:910 +msgid "Mouse wheel scrolls by:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:911 +msgid "" +"One mouse wheel notch scrolls by this distance in screen pixels " +"(horizontally with Shift)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:920 +msgid "Ctrl+arrows" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:928 +msgid "Scroll by:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:929 +msgid "Pressing Ctrl+arrow key scrolls by this distance (in screen pixels)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:939 +#, fuzzy +msgid "Acceleration:" +msgstr "Selección" + +#: ../../po/../src/dialogs/display-settings.cpp:940 +msgid "" +"Pressing and holding Ctrl+arrow will gradually speed up scrolling (0 for no " +"acceleration)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:949 +msgid "Autoscrolling" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:957 +#, fuzzy +msgid "Speed:" +msgstr "Vermello:" + +#: ../../po/../src/dialogs/display-settings.cpp:958 +msgid "" +"How fast the canvas autoscrolls when you drag beyond canvas edge (0 to turn " +"autoscroll off)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:968 +#: ../../po/../src/ui/dialog/tracedialog.cpp:357 +#: ../../po/../src/ui/dialog/tracedialog.cpp:390 +msgid "Threshold:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:969 +msgid "" +"How far (in screen pixels) you need to be from the canvas edge to trigger " +"autoscroll; positive is outside the canvas, negative is within the canvas" +msgstr "" + +#. Steps +#: ../../po/../src/dialogs/display-settings.cpp:979 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:57 +#, fuzzy +msgid "Steps" +msgstr " Estilo " + +#: ../../po/../src/dialogs/display-settings.cpp:982 +msgid "Arrow keys move by:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:983 +msgid "" +"Pressing an arrow key moves selected object(s) or node(s) by this distance " +"(in px units)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:984 +#: ../../po/../src/dialogs/display-settings.cpp:995 +#: ../../po/../src/dialogs/display-settings.cpp:1006 +#: ../../po/../src/helper/units.cpp:42 +msgid "px" +msgstr "px" + +#: ../../po/../src/dialogs/display-settings.cpp:993 +msgid "> and < scale by:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:994 +msgid "" +"Pressing > or < scales selection up or down by this increment (in px units)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1004 +msgid "Inset/Outset by:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1005 +msgid "" +"Inset and Outset commands displace the path by this distance (in px units)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1017 +msgid "Compass-like display of angles" +msgstr "" + +#. TRANSLATORS: "positive clockwise" means "increasing in clockwise direction" +#: ../../po/../src/dialogs/display-settings.cpp:1019 +msgid "" +"When on, angles are displayed with 0 at north, 0 to 360 range, positive " +"clockwise; otherwise with 0 at east, -180 to 180 range, positive " +"counterclockwise" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1026 +#, fuzzy +msgid "Zoom in/out by:" +msgstr "Zoom fora" + +#: ../../po/../src/dialogs/display-settings.cpp:1027 +msgid "" +"Zoom tool click, +/- keys, and middle click zoom in and out by this " +"multiplier" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1028 +#: ../../po/../src/helper/units.cpp:44 +msgid "%" +msgstr "%" + +#. Tools +#: ../../po/../src/dialogs/display-settings.cpp:1037 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:58 +msgid "Tools" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1045 +#, fuzzy +msgid "Selector" +msgstr "Seleccionar" + +#: ../../po/../src/dialogs/display-settings.cpp:1056 +msgid "Node" +msgstr "Nodo" + +#: ../../po/../src/dialogs/display-settings.cpp:1064 +#: ../../po/../src/verbs.cpp:2073 +#: ../../po/../src/widgets/desktop-widget.cpp:277 +msgid "Zoom" +msgstr "Zoom" + +#. The 4 shape tools +#: ../../po/../src/dialogs/display-settings.cpp:1071 +#, fuzzy +msgid "Shapes" +msgstr "Peza" + +#: ../../po/../src/dialogs/display-settings.cpp:1079 +#: ../../po/../src/verbs.cpp:2055 +msgid "Rectangle" +msgstr "Rectángulo" + +#: ../../po/../src/dialogs/display-settings.cpp:1085 +#: ../../po/../src/verbs.cpp:2057 +msgid "Ellipse" +msgstr "Elipse" + +#: ../../po/../src/dialogs/display-settings.cpp:1091 +#: ../../po/../src/verbs.cpp:2059 +#, fuzzy +msgid "Star" +msgstr "Trazo" + +#: ../../po/../src/dialogs/display-settings.cpp:1097 +#: ../../po/../src/verbs.cpp:2061 +msgid "Spiral" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1111 +#: ../../po/../src/verbs.cpp:2063 +msgid "Pencil" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1114 +msgid "Tolerance:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1115 +msgid "" +"This value affects the amount of smoothing applied to freehand lines; lower " +"values produce more uneven paths with more nodes" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1131 +#: ../../po/../src/verbs.cpp:2065 +#, fuzzy +msgid "Pen" +msgstr "Porcentaxe" + +#: ../../po/../src/dialogs/display-settings.cpp:1140 +#: ../../po/../src/verbs.cpp:2067 +msgid "Calligraphy" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1147 +#: ../../po/../src/dialogs/text-edit.cpp:353 +#: ../../po/../src/ui/dialog/text-properties.cpp:37 +#: ../../po/../src/verbs.cpp:2069 +msgid "Text" +msgstr "Texto" + +#: ../../po/../src/dialogs/display-settings.cpp:1157 +#: ../../po/../src/verbs.cpp:2071 +#, fuzzy +msgid "Gradient" +msgstr "Recheo de degradado" + +#: ../../po/../src/dialogs/display-settings.cpp:1164 +#: ../../po/../src/verbs.cpp:2077 +#, fuzzy +msgid "Connector" +msgstr "Nova vista" + +#: ../../po/../src/dialogs/display-settings.cpp:1171 +#: ../../po/../src/verbs.cpp:2075 +msgid "Dropper" +msgstr "" + +#. Windows +#: ../../po/../src/dialogs/display-settings.cpp:1183 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:59 +#, fuzzy +msgid "Windows" +msgstr "fiestra1" + +#: ../../po/../src/dialogs/display-settings.cpp:1188 +#, fuzzy +msgid "Save window geometry" +msgstr "Documento" + +#: ../../po/../src/dialogs/display-settings.cpp:1189 +msgid "" +"Save the window size and position with each document (only for Inkscape SVG " +"format)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1196 +msgid "Dialogs are hidden in taskbar" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1197 +msgid "Whether dialog windows are to be hidden in the window manager taskbar" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1204 +msgid "Zoom when window is resized" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1205 +msgid "" +"Zoom drawing when document window is resized, to keep the same area visible " +"(this is the default which can be changed in any window using the button " +"above the right scrollbar)" +msgstr "" + +#. Clones +#: ../../po/../src/dialogs/display-settings.cpp:1213 +#: ../../po/../src/dialogs/find.cpp:624 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:60 +#, fuzzy +msgid "Clones" +msgstr "Nova vista" + +#: ../../po/../src/dialogs/display-settings.cpp:1217 +msgid "When the original moves, its clones and linked offsets:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1229 +msgid "Move in parallel" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1230 +msgid "Clones are translated by the same vector as their original." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1237 +msgid "Stay unmoved" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1238 +msgid "Clones preserve their positions when their original is moved." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1245 +msgid "Move according to transform" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1246 +msgid "" +"Each clone moves according to the value of its transform= attribute. For " +"example, a rotated clone will move in a different direction than its " +"original." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1255 +msgid "When the original is deleted, its clones:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1267 +msgid "Are unlinked" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1267 +msgid "Orphaned clones are converted to regular objects." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1273 +#, fuzzy +msgid "Are deleted" +msgstr "Primeiro seleccionado" + +#: ../../po/../src/dialogs/display-settings.cpp:1273 +msgid "Orphaned clones are deleted along with their original." +msgstr "" + +#. Transforms +#. TRANSLATORS: Noun, i.e. transformations. +#: ../../po/../src/dialogs/display-settings.cpp:1289 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:61 +#, fuzzy +msgid "Transforms" +msgstr "Transformación" + +#: ../../po/../src/dialogs/display-settings.cpp:1292 +#, fuzzy +msgid "Scale stroke width" +msgstr "Ancho do trazado" + +#: ../../po/../src/dialogs/display-settings.cpp:1293 +#: ../../po/../src/widgets/select-toolbar.cpp:568 +msgid "When scaling objects, scale the stroke width by the same proportion" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1300 +msgid "Scale rounded corners in rectangles" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1301 +#: ../../po/../src/widgets/select-toolbar.cpp:580 +msgid "When scaling rectangles, scale the radii of rounded corners" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1308 +#, fuzzy +msgid "Transform gradients" +msgstr "Transformación" + +#: ../../po/../src/dialogs/display-settings.cpp:1309 +#: ../../po/../src/widgets/select-toolbar.cpp:592 +msgid "Transform gradients (in fill or stroke) along with the objects" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1316 +#, fuzzy +msgid "Transform patterns" +msgstr "Transformación" + +#: ../../po/../src/dialogs/display-settings.cpp:1317 +#: ../../po/../src/widgets/select-toolbar.cpp:604 +msgid "Transform patterns (in fill or stroke) along with the objects" +msgstr "" + +#. TRANSLATORS: How to specify the affine transformation in the SVG file. +#: ../../po/../src/dialogs/display-settings.cpp:1327 +#, fuzzy +msgid "Store transformation:" +msgstr "Reinicia-la transformación" + +#: ../../po/../src/dialogs/display-settings.cpp:1338 +msgid "Optimized" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1339 +msgid "" +"If possible, apply transformation to objects without adding a transform= " +"attribute" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1346 +msgid "Preserved" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1347 +msgid "Always store transformation as a transform= attribute on objects" +msgstr "" + +#. Selecting +#: ../../po/../src/dialogs/display-settings.cpp:1355 +#, fuzzy +msgid "Selecting" +msgstr "Selección" + +#: ../../po/../src/dialogs/display-settings.cpp:1357 +msgid "Ctrl+A, Tab, Shift+Tab:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1366 +#, fuzzy +msgid "Select only within current layer" +msgstr "Seleccionar" + +#: ../../po/../src/dialogs/display-settings.cpp:1367 +msgid "" +"Uncheck this to make keyboard selection commands work on objects in all " +"layers" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1374 +msgid "Ignore hidden objects" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1375 +msgid "" +"Uncheck this to be able to select objects that are hidden (either by " +"themselves or by being in a hidden group or layer)" +msgstr "" + +# [*] Revisar +#: ../../po/../src/dialogs/display-settings.cpp:1382 +#, fuzzy +msgid "Ignore locked objects" +msgstr "Voltea-los obxectos seleccionados" + +#: ../../po/../src/dialogs/display-settings.cpp:1383 +msgid "" +"Uncheck this to be able to select objects that are locked (either by " +"themselves or by being in a locked group or layer)" +msgstr "" + +#. To be broken into: Display, Save, Export, SVG, Commands +#: ../../po/../src/dialogs/display-settings.cpp:1391 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:62 +msgid "Misc" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1394 +msgid "Default export resolution:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1395 +msgid "Default bitmap resolution (in dots per inch) in the Export dialog" +msgstr "" + +#. FIXME: add "Used for new exports; once exported, documents remember this value on per-object basis" when implemented +#: ../../po/../src/dialogs/display-settings.cpp:1396 +#: ../../po/../src/dialogs/export.cpp:442 +msgid "dpi" +msgstr "ppp" + +#. TRANSLATORS: When on, an imported bitmap creates an element; otherwise it is a +#. * rectangle with bitmap fill. +#: ../../po/../src/dialogs/display-settings.cpp:1407 +msgid "Import bitmap as " +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1408 +msgid "" +"When on, an imported bitmap creates an element; otherwise it is a " +"rectangle with bitmap fill" +msgstr "" + +#. TRANSLATORS: When on, the print out (currently Postscript) will have +#. * a comment with the each object's label visible, marking the section +#. * of the printing commands that represent the given object. +#: ../../po/../src/dialogs/display-settings.cpp:1418 +msgid "Add label comments to printing output" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1419 +msgid "" +"When on, a comment will be added to the raw print output, marking the " +"rendered output for an object with its label" +msgstr "" + +#. TRANSLATORS: When on, enable the effects menu, default is off +#: ../../po/../src/dialogs/display-settings.cpp:1427 +msgid "Enable script effects (requires restart) - EXPERIMENTAL" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1428 +msgid "" +"When on, the effects menu is enabled, allowing external effect scripts to be " +"called, requires restart before effective - EXPERIMENTAL" +msgstr "" + +#. TRANSLATORS: The maximum length of the Open Recent list in the File menu. +#: ../../po/../src/dialogs/display-settings.cpp:1436 +#, fuzzy +msgid "Max recent documents:" +msgstr "Documento" + +#: ../../po/../src/dialogs/display-settings.cpp:1437 +msgid "The maximum length of the Open Recent list in the File menu" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1447 +msgid "Simplification threshold:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1448 +msgid "" +"How strong is the Simplify command by default. If you invoke this command " +"several times in quick succession, it will act more and more aggressively; " +"invoking it again after a pause restores the default threshold." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1469 +msgid "Oversample bitmaps:" +msgstr "Sobremostrear bitmaps:" + +#: ../../po/../src/dialogs/display-settings.cpp:1488 +msgid "2x2" +msgstr "2x2" + +#: ../../po/../src/dialogs/display-settings.cpp:1494 +msgid "4x4" +msgstr "4x4" + +#: ../../po/../src/dialogs/display-settings.cpp:1500 +msgid "8x8" +msgstr "8x8" + +#: ../../po/../src/dialogs/display-settings.cpp:1506 +msgid "16x16" +msgstr "16x16" + +#. "view_icon_preview" +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2143 +msgid "_Page" +msgstr "_Páxina" + +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2147 +msgid "_Drawing" +msgstr "_Debuxando" + +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2149 +msgid "_Selection" +msgstr "_Selección" + +#: ../../po/../src/dialogs/export.cpp:133 +#, fuzzy +msgid "_Custom" +msgstr "Persoalizado" + +#: ../../po/../src/dialogs/export.cpp:254 +#, fuzzy +msgid "Export area" +msgstr "Exportar como" + +#: ../../po/../src/dialogs/export.cpp:300 +msgid "_x0:" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:305 +#, fuzzy +msgid "x_1:" +msgstr "1:1" + +#: ../../po/../src/dialogs/export.cpp:316 +msgid "_y0:" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:321 +#, fuzzy +msgid "y_1:" +msgstr "1:1" + +#: ../../po/../src/dialogs/export.cpp:406 +#, fuzzy +msgid "Bitmap size" +msgstr "Tamaño da imaxe" + +#: ../../po/../src/dialogs/export.cpp:416 +#, fuzzy +msgid "_Width:" +msgstr "Ancho:" + +#: ../../po/../src/dialogs/export.cpp:416 +#: ../../po/../src/dialogs/export.cpp:431 +#, fuzzy +msgid "pixels at" +msgstr "Pixeles" + +#: ../../po/../src/dialogs/export.cpp:426 +#, fuzzy +msgid "dp_i" +msgstr "ppp" + +#: ../../po/../src/dialogs/export.cpp:448 +#, fuzzy +msgid "_Filename" +msgstr "Nome do ficheiro:" + +#: ../../po/../src/dialogs/export.cpp:512 +msgid "_Browse..." +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:539 +#, fuzzy +msgid " _Export " +msgstr "Cambiar" + +#: ../../po/../src/dialogs/export.cpp:541 +msgid "Export the bitmap file with these settings" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:968 +#, fuzzy +msgid "You have to enter a filename" +msgstr "Garda-lo debuxo con novo nome" + +#: ../../po/../src/dialogs/export.cpp:973 +msgid "The chosen area to be exported is invalid" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:982 +#, c-format +msgid "Directory %s does not exist or is not a directory.\n" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:998 +#, fuzzy +msgid "Export in progress" +msgstr "Exportar como" + +#: ../../po/../src/dialogs/export.cpp:1004 +#, c-format +msgid "Exporting %s (%d x %d)" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:1031 +#, c-format +msgid "Could not export to filename %s.\n" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:1137 +#, fuzzy +msgid "Select a filename for exporting" +msgstr "Seleccione o ficheiro a importar" + +#: ../../po/../src/dialogs/filedialog.cpp:367 +#, fuzzy +msgid "No preview" +msgstr "Nova vista" + +#: ../../po/../src/dialogs/filedialog.cpp:468 +msgid "too large for preview" +msgstr "" + +#: ../../po/../src/dialogs/filedialog.cpp:762 +#: ../../po/../src/dialogs/filedialog.cpp:763 +#, fuzzy +msgid "All Images" +msgstr "Tamaño da imaxe" + +#: ../../po/../src/dialogs/filedialog.cpp:767 +#: ../../po/../src/dialogs/filedialog.cpp:768 +#, fuzzy +msgid "All Files" +msgstr "Configuración do recheo" + +#: ../../po/../src/dialogs/filedialog.cpp:774 +#: ../../po/../src/dialogs/filedialog.cpp:775 +#, fuzzy +msgid "All Inkscape Files" +msgstr "Sodipodi" + +#: ../../po/../src/dialogs/filedialog.cpp:1176 +#, fuzzy +msgid "Guess from extension" +msgstr "Transforma-la selección" + +#. ###### Add the file types menu +#. createFilterMenu(); +#. ###### Do we want the .xxx extension automatically added? +#: ../../po/../src/dialogs/filedialog.cpp:1261 +msgid "Append filename extension automatically" +msgstr "" + +#. TRANSLATORS: "%s" is replaced with "exact" or "partial" when this string is displayed +#: ../../po/../src/dialogs/find.cpp:378 +#, fuzzy, c-format +msgid "%d object found (out of %d), %s match." +msgid_plural "%d objects found (out of %d), %s match." +msgstr[0] "Suaviza-la liña nos nodos seleccionados" +msgstr[1] "Suaviza-la liña nos nodos seleccionados" + +#: ../../po/../src/dialogs/find.cpp:381 +#, fuzzy +msgid "exact" +msgstr "Texto" + +#: ../../po/../src/dialogs/find.cpp:381 +msgid "partial" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:388 +#, fuzzy +msgid "No objects found" +msgstr "Obxecto texto" + +#: ../../po/../src/dialogs/find.cpp:546 +msgid "T_ype: " +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:553 +msgid "Search in all object types" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:553 +#, fuzzy +msgid "All types" +msgstr "Configuración do recheo" + +#: ../../po/../src/dialogs/find.cpp:564 +msgid "Search all shapes" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:564 +msgid "All shapes" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:581 +#, fuzzy +msgid "Search rectangles" +msgstr "Rectángulo" + +#: ../../po/../src/dialogs/find.cpp:581 +#, fuzzy +msgid "Rectangles" +msgstr "Rectángulo" + +#: ../../po/../src/dialogs/find.cpp:586 +msgid "Search ellipses, arcs, circles" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:586 +#, fuzzy +msgid "Ellipses" +msgstr "Elipse" + +#: ../../po/../src/dialogs/find.cpp:591 +msgid "Search stars and polygons" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:591 +#, fuzzy +msgid "Stars" +msgstr "Trazo" + +#: ../../po/../src/dialogs/find.cpp:596 +#, fuzzy +msgid "Search spirals" +msgstr "Debuxar rectangulo" + +#: ../../po/../src/dialogs/find.cpp:596 +#, fuzzy +msgid "Spirals" +msgstr "Pixeles" + +#. TRANSLATORS: polyline is a set of connected straight line segments +#. http://www.w3.org/TR/SVG11/shapes.html#PolylineElement +#: ../../po/../src/dialogs/find.cpp:609 +msgid "Search paths, lines, polylines" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:609 +msgid "Paths" +msgstr "" + +# [*] Revisar +#: ../../po/../src/dialogs/find.cpp:614 +#, fuzzy +msgid "Search text objects" +msgstr "Voltea-los obxectos seleccionados" + +#: ../../po/../src/dialogs/find.cpp:614 +#, fuzzy +msgid "Texts" +msgstr "Texto" + +#: ../../po/../src/dialogs/find.cpp:619 +msgid "Search groups" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:619 +#, fuzzy +msgid "Groups" +msgstr "Agrupar" + +#: ../../po/../src/dialogs/find.cpp:624 +msgid "Search clones" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:629 +#, fuzzy +msgid "Search images" +msgstr "Escalar coa imaxe" + +#: ../../po/../src/dialogs/find.cpp:629 +#, fuzzy +msgid "Images" +msgstr "Tamaño da imaxe" + +# [*] Revisar +#: ../../po/../src/dialogs/find.cpp:634 +#, fuzzy +msgid "Search offset objects" +msgstr "Voltea-los obxectos seleccionados" + +#: ../../po/../src/dialogs/find.cpp:634 +msgid "Offsets" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:694 +#, fuzzy +msgid "_Text: " +msgstr "Texto" + +#: ../../po/../src/dialogs/find.cpp:694 +msgid "Find objects by their text content (exact or partial match)" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:695 +msgid "_ID: " +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:695 +msgid "Find objects by the value of the id attribute (exact or partial match)" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:696 +#, fuzzy +msgid "_Style: " +msgstr " Estilo " + +#: ../../po/../src/dialogs/find.cpp:696 +msgid "" +"Find objects by the value of the style attribute (exact or partial match)" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:697 +#, fuzzy +msgid "_Attribute: " +msgstr "Atributo:" + +#: ../../po/../src/dialogs/find.cpp:697 +msgid "Find objects by the name of an attribute (exact or partial match)" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:711 +#, fuzzy +msgid "Search in s_election" +msgstr "Zoom á selección" + +#: ../../po/../src/dialogs/find.cpp:715 +msgid "Limit search to the current selection" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:720 +#, fuzzy +msgid "Search in current _layer" +msgstr "Seleccionar" + +#: ../../po/../src/dialogs/find.cpp:724 +#, fuzzy +msgid "Limit search to the current layer" +msgstr "Seleccionar" + +#: ../../po/../src/dialogs/find.cpp:729 +msgid "Include _hidden" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:733 +msgid "Include hidden objects in search" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:738 +msgid "Include l_ocked" +msgstr "" + +# [*] Revisar +#: ../../po/../src/dialogs/find.cpp:742 +#, fuzzy +msgid "Include locked objects in search" +msgstr "Voltea-los obxectos seleccionados" + +#: ../../po/../src/dialogs/find.cpp:753 +#, fuzzy +msgid "Clear values" +msgstr "Cor do recheo" + +#: ../../po/../src/dialogs/find.cpp:754 +#, fuzzy +msgid "_Find" +msgstr "Reixa" + +#: ../../po/../src/dialogs/find.cpp:754 +msgid "Select objects matching all of the fields you filled in" +msgstr "" + +#: ../../po/../src/dialogs/iconpreview.cpp:145 +#, c-format +msgid "%d x %d" +msgstr "" + +#: ../../po/../src/dialogs/iconpreview.cpp:193 +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:857 +#: ../../po/../src/widgets/desktop-widget.cpp:1069 +msgid "Selection" +msgstr "Selección" + +#: ../../po/../src/dialogs/iconpreview.cpp:195 +#, fuzzy +msgid "Selection only or whole document" +msgstr "Seleccionar" + +#: ../../po/../src/dialogs/iconpreview.cpp:203 +msgid "Refresh the icons" +msgstr "" + +#. Create the label for the object id +#: ../../po/../src/dialogs/item-properties.cpp:126 +#: ../../po/../src/dialogs/item-properties.cpp:327 +#: ../../po/../src/dialogs/item-properties.cpp:396 +#: ../../po/../src/dialogs/item-properties.cpp:403 +msgid "_Id" +msgstr "" + +#: ../../po/../src/dialogs/item-properties.cpp:135 +msgid "" +"The id= attribute (only letters, digits, and the characters .-_: allowed)" +msgstr "" + +#. Button for setting the object's id, label, title and description. +#: ../../po/../src/dialogs/item-properties.cpp:149 +#, fuzzy +msgid "_Set" +msgstr "Seleccionar" + +#. Create the label for the object label +#: ../../po/../src/dialogs/item-properties.cpp:158 +#, fuzzy +msgid "_Label" +msgstr "biselar" + +#: ../../po/../src/dialogs/item-properties.cpp:167 +msgid "A freeform label for the object" +msgstr "" + +#. Create the label for the object title +#: ../../po/../src/dialogs/item-properties.cpp:179 +#: ../../po/../src/dialogs/rdf.cpp:243 +#, fuzzy +msgid "Title" +msgstr "Ficheiro" + +#. Create the frame for the object description +#: ../../po/../src/dialogs/item-properties.cpp:196 +#: ../../po/../src/dialogs/rdf.cpp:287 +#, fuzzy +msgid "Description" +msgstr "Posición" + +#. Hide +#: ../../po/../src/dialogs/item-properties.cpp:223 +#, fuzzy +msgid "_Hide" +msgstr "Guías" + +#: ../../po/../src/dialogs/item-properties.cpp:224 +msgid "Check to make the object invisible" +msgstr "" + +#. Lock +#. TRANSLATORS: "Lock" is a verb here +#: ../../po/../src/dialogs/item-properties.cpp:233 +msgid "L_ock" +msgstr "" + +#: ../../po/../src/dialogs/item-properties.cpp:234 +msgid "Check to make the object insensitive (not selectable by mouse)" +msgstr "" + +#: ../../po/../src/dialogs/item-properties.cpp:310 +#: ../../po/../src/dialogs/item-properties.cpp:317 +msgid "Ref" +msgstr "" + +#: ../../po/../src/dialogs/item-properties.cpp:398 +#, fuzzy +msgid "Id invalid! " +msgstr "O ID é válido" + +#: ../../po/../src/dialogs/item-properties.cpp:400 +msgid "Id exists! " +msgstr "" + +#: ../../po/../src/dialogs/layer-properties.cpp:50 +msgid "Layer name:" +msgstr "" + +#: ../../po/../src/dialogs/layer-properties.cpp:133 +#, fuzzy +msgid "Rename Layer" +msgstr "Pegar" + +#: ../../po/../src/dialogs/layer-properties.cpp:136 +#, fuzzy +msgid "_Rename" +msgstr "Nome do ficheiro:" + +#. TRANSLATORS: This means "The layer has been renamed" +#: ../../po/../src/dialogs/layer-properties.cpp:147 +#, fuzzy +msgid "Renamed layer" +msgstr "Pegar" + +#: ../../po/../src/dialogs/layer-properties.cpp:151 +#, fuzzy +msgid "Add Layer" +msgstr "Seleccionar" + +#: ../../po/../src/dialogs/layer-properties.cpp:153 +#, fuzzy +msgid "_Add" +msgstr "Engadir" + +#: ../../po/../src/dialogs/layer-properties.cpp:167 +msgid "New layer created." +msgstr "" + +#: ../../po/../src/dialogs/object-attributes.cpp:34 +msgid "Href:" +msgstr "" + +#: ../../po/../src/dialogs/object-attributes.cpp:35 +msgid "Target:" +msgstr "" + +#: ../../po/../src/dialogs/object-attributes.cpp:36 +msgid "Type:" +msgstr "" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkRoleAttribute +#. Identifies the type of the related resource with an absolute URI +#: ../../po/../src/dialogs/object-attributes.cpp:39 +#, fuzzy +msgid "Role:" +msgstr "Vermello:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkArcRoleAttribute +#. For situations where the nature/role alone isn't enough, this offers an additional URI defining the purpose of the link. +#: ../../po/../src/dialogs/object-attributes.cpp:42 +msgid "Arcrole:" +msgstr "" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkTitleAttribute +#: ../../po/../src/dialogs/object-attributes.cpp:44 +#, fuzzy +msgid "Title:" +msgstr "Ficheiro" + +#: ../../po/../src/dialogs/object-attributes.cpp:45 +msgid "Show:" +msgstr "" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkActuateAttribute +#: ../../po/../src/dialogs/object-attributes.cpp:47 +#, fuzzy +msgid "Actuate:" +msgstr "Atributo:" + +#: ../../po/../src/dialogs/object-attributes.cpp:52 +msgid "URL:" +msgstr "" + +#: ../../po/../src/dialogs/object-attributes.cpp:53 +msgid "X:" +msgstr "X:" + +#: ../../po/../src/dialogs/object-attributes.cpp:54 +msgid "Y:" +msgstr "Y:" + +#: ../../po/../src/dialogs/object-attributes.cpp:98 +#, fuzzy, c-format +msgid "%s attributes" +msgstr "Atributos" + +#: ../../po/../src/dialogs/object-properties.cpp:158 +#, fuzzy +msgid "_Fill" +msgstr "Reencher" + +#: ../../po/../src/dialogs/object-properties.cpp:165 +#, fuzzy +msgid "Stroke _paint" +msgstr "Ancho do trazado" + +#: ../../po/../src/dialogs/object-properties.cpp:172 +#, fuzzy +msgid "Stroke st_yle" +msgstr "Configuración do escritorio" + +#: ../../po/../src/dialogs/object-properties.cpp:183 +#, fuzzy +msgid "Master _opacity" +msgstr "Opacidade:" + +#: ../../po/../src/dialogs/rdf.cpp:244 +msgid "Name by which this document is formally known." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:246 +#, fuzzy +msgid "Date" +msgstr "Debuxar texto" + +#: ../../po/../src/dialogs/rdf.cpp:247 +msgid "Date associated with the creation of this document (YYYY-MM-DD)." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:249 +#, fuzzy +msgid "Format" +msgstr "Fractal" + +#: ../../po/../src/dialogs/rdf.cpp:250 +msgid "The physical or digital manifestation of this document (MIME type)." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:252 +msgid "Type" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:253 +msgid "Type of document (DCMI Type)." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:256 +#, fuzzy +msgid "Creator" +msgstr "Centrar" + +#: ../../po/../src/dialogs/rdf.cpp:257 +msgid "" +"Name of entity primarily responsible for making the content of this document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:259 +#, fuzzy +msgid "Rights" +msgstr "Alto" + +#: ../../po/../src/dialogs/rdf.cpp:260 +msgid "" +"Name of entity with rights to the Intellectual Property of this document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:262 +msgid "Publisher" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:263 +msgid "Name of entity responsible for making this document available." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:266 +#, fuzzy +msgid "Identifier" +msgstr "Centrar" + +#: ../../po/../src/dialogs/rdf.cpp:267 +msgid "Unique URI to reference this document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:269 +msgid "Source" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:270 +msgid "Unique URI to reference the source of this document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:272 +#, fuzzy +msgid "Relation" +msgstr "Selección" + +#: ../../po/../src/dialogs/rdf.cpp:273 +msgid "Unique URI to a related document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:275 +#, fuzzy +msgid "Language" +msgstr "ángulo" + +#: ../../po/../src/dialogs/rdf.cpp:276 +msgid "" +"Two-letter language tag with optional subtags for the language of this " +"document. (e.g. 'en-GB')" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:278 +msgid "Keywords" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:279 +msgid "" +"The topic of this document as comma-separated key words, phrases, or " +"classifications." +msgstr "" + +#. TRANSLATORS: "Coverage": the spatial or temporal characteristics of the content. +#. For info, see Appendix D of http://www.w3.org/TR/1998/WD-rdf-schema-19980409/ +#: ../../po/../src/dialogs/rdf.cpp:283 +msgid "Coverage" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:284 +msgid "Extent or scope of this document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:288 +msgid "A short account of the content of this document." +msgstr "" + +#. FIXME: need to handle 1 agent per line of input +#: ../../po/../src/dialogs/rdf.cpp:292 +#, fuzzy +msgid "Contributors" +msgstr "Centímetros" + +#: ../../po/../src/dialogs/rdf.cpp:293 +msgid "" +"Names of entities responsible for making contributions to the content of " +"this document." +msgstr "" + +#. TRANSLATORS: URL to a page that defines the license for the document +#: ../../po/../src/dialogs/rdf.cpp:297 +msgid "URI" +msgstr "" + +#. TRANSLATORS: this is where you put a URL to a page that defines the license +#: ../../po/../src/dialogs/rdf.cpp:299 +msgid "URI to this document's license's namespace definition." +msgstr "" + +#. TRANSLATORS: fragment of XML representing the license of the document +#: ../../po/../src/dialogs/rdf.cpp:303 +msgid "Fragment" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:304 +msgid "XML fragment for the RDF 'License' section." +msgstr "" + +#: ../../po/../src/dialogs/stroke-style.cpp:774 +#: ../../po/../src/widgets/gradient-vector.cpp:263 +#: ../../po/../src/widgets/paint-selector.cpp:751 +#, fuzzy +msgid "No document selected" +msgstr "Último seleccionado" + +#: ../../po/../src/dialogs/stroke-style.cpp:992 +#, fuzzy +msgid "Stroke width" +msgstr "Ancho do trazado" + +#. Join type +#. TRANSLATORS: The line join style specifies the shape to be used at the +#. corners of paths. It can be "miter", "round" or "bevel". +#: ../../po/../src/dialogs/stroke-style.cpp:1015 +msgid "Join:" +msgstr "Xuntar:" + +# [*] Revisar +#. TRANSLATORS: Miter join: joining lines with a sharp (pointed) corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1027 +#, fuzzy +msgid "Miter join" +msgstr "Xuntar metades" + +# [*] Revisar +#. TRANSLATORS: Round join: joining lines with a rounded corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1035 +msgid "Round join" +msgstr "Xuntar redondeado" + +# [*] Revisar +#. TRANSLATORS: Bevel join: joining lines with a blunted (flattened) corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1043 +msgid "Bevel join" +msgstr "Xuntar biselado" + +# [*] Revisar +#. Miterlimit +#. TRANSLATORS: Miter limit: only for "miter join", this limits the length +#. of the sharp "spike" when the lines connect at too sharp an angle. +#. When two line segments meet at a sharp angle, a miter join results in a +#. spike that extends well beyond the connection point. The purpose of the +#. miter limit is to cut off such spikes (i.e. convert them into bevels) +#. when they become too long. +#: ../../po/../src/dialogs/stroke-style.cpp:1054 +#, fuzzy +msgid "Miter limit:" +msgstr "Xuntar metades" + +#: ../../po/../src/dialogs/stroke-style.cpp:1062 +msgid "Maximum length of the miter (in units of stroke width)" +msgstr "" + +#. Cap type +#. TRANSLATORS: cap type specifies the shape for the ends of lines +#: ../../po/../src/dialogs/stroke-style.cpp:1075 +#, fuzzy +msgid "Cap:" +msgstr " Tapa " + +#. TRANSLATORS: Butt cap: the line shape does not extend beyond the end point +#. of the line; the ends of the line are square +#: ../../po/../src/dialogs/stroke-style.cpp:1086 +msgid "Butt cap" +msgstr "" + +# [*] Revisar +#. TRANSLATORS: Round cap: the line shape extends beyond the end point of the +#. line; the ends of the line are rounded +#: ../../po/../src/dialogs/stroke-style.cpp:1093 +#, fuzzy +msgid "Round cap" +msgstr "Xuntar redondeado" + +# [*] Revisar +#. TRANSLATORS: Square cap: the line shape extends beyond the end point of the +#. line; the ends of the line are square +#: ../../po/../src/dialogs/stroke-style.cpp:1100 +#, fuzzy +msgid "Square cap" +msgstr "Encadrar puntos finais" + +#. Dash +#: ../../po/../src/dialogs/stroke-style.cpp:1106 +#, fuzzy +msgid "Dashes:" +msgstr "punteada" + +#. TRANSLATORS: Path markers are an SVG feature that allows you to attach arbitrary shapes +#. (arrowheads, bullets, faces, whatever) to the start, end, or middle nodes of a path. +#: ../../po/../src/dialogs/stroke-style.cpp:1127 +#, fuzzy +msgid "Start Markers:" +msgstr "Propiedades do texto" + +#: ../../po/../src/dialogs/stroke-style.cpp:1137 +msgid "Mid Markers:" +msgstr "" + +#: ../../po/../src/dialogs/stroke-style.cpp:1148 +msgid "End Markers:" +msgstr "" + +#: ../../po/../src/dialogs/swatches.cpp:424 +#, c-format +msgid "Palettes directory (%s) is unavailable." +msgstr "" + +#. TODO: Insert widgets +#: ../../po/../src/dialogs/text-edit.cpp:199 +#: ../../po/../src/ui/dialog/text-properties.cpp:36 +#, fuzzy +msgid "Font" +msgstr "Punto" + +# [*] Revisar +#: ../../po/../src/dialogs/text-edit.cpp:216 +msgid "Layout" +msgstr "Equipamento" + +#: ../../po/../src/dialogs/text-edit.cpp:229 +#, fuzzy +msgid "Align lines left" +msgstr "Aliñar arriba á esqueda" + +#. TRANSLATORS: `Center' here is a verb. +#: ../../po/../src/dialogs/text-edit.cpp:243 +#, fuzzy +msgid "Center lines" +msgstr "Centrar" + +#: ../../po/../src/dialogs/text-edit.cpp:256 +#, fuzzy +msgid "Align lines right" +msgstr "Aliñar arriba á dereita" + +#: ../../po/../src/dialogs/text-edit.cpp:278 +#, fuzzy +msgid "Horizontal text" +msgstr "movemento horizontal" + +#: ../../po/../src/dialogs/text-edit.cpp:292 +#, fuzzy +msgid "Vertical text" +msgstr "Valor de centrado vertical" + +#: ../../po/../src/dialogs/text-edit.cpp:307 +#, fuzzy +msgid "Line spacing:" +msgstr "Separación X:" + +#: ../../po/../src/dialogs/text-edit.cpp:400 +msgid "Set as default" +msgstr "" + +#: ../../po/../src/dialogs/tiledialog.cpp:603 +#, fuzzy +msgid "Rows:" +msgstr "Vermello:" + +#: ../../po/../src/dialogs/tiledialog.cpp:613 +msgid "Number of rows" +msgstr "" + +#: ../../po/../src/dialogs/tiledialog.cpp:617 +#, fuzzy +msgid "Equal height" +msgstr "Alto:" + +#: ../../po/../src/dialogs/tiledialog.cpp:627 +msgid "If not set, each row has the height of the tallest object in it" +msgstr "" + +#. #### Radio buttons to control vertical alignment #### +#. #### Radio buttons to control horizontal alignment #### +#: ../../po/../src/dialogs/tiledialog.cpp:637 +#: ../../po/../src/dialogs/tiledialog.cpp:708 +#, fuzzy +msgid "Align:" +msgstr "Aliñar" + +#: ../../po/../src/dialogs/tiledialog.cpp:672 +#, fuzzy +msgid " X " +msgstr "X +" + +#. #### Number of columns #### +#: ../../po/../src/dialogs/tiledialog.cpp:678 +#, fuzzy +msgid "Columns:" +msgstr "Cambiar" + +#: ../../po/../src/dialogs/tiledialog.cpp:688 +msgid "Number of columns" +msgstr "" + +#: ../../po/../src/dialogs/tiledialog.cpp:692 +#, fuzzy +msgid "Equal width" +msgstr "Ancho " + +#: ../../po/../src/dialogs/tiledialog.cpp:701 +msgid "If not set, each column has the width of the widest object in it" +msgstr "" + +#. #### Radio buttons to control spacing manually or to fit selection bbox #### +#: ../../po/../src/dialogs/tiledialog.cpp:746 +#, fuzzy +msgid "Fit into selection box" +msgstr "Corta-la selección" + +#: ../../po/../src/dialogs/tiledialog.cpp:753 +#, fuzzy +msgid "Set spacing:" +msgstr "Separación Y:" + +#. #### Y Padding #### +#: ../../po/../src/dialogs/tiledialog.cpp:777 +#, fuzzy +msgid "Row spacing: " +msgstr "Separación X:" + +#: ../../po/../src/dialogs/tiledialog.cpp:786 +#, fuzzy +msgid "Vertical spacing between rows" +msgstr "Valor de centrado vertical" + +#. #### X padding #### +#: ../../po/../src/dialogs/tiledialog.cpp:795 +#, fuzzy +msgid "Column spacing:" +msgstr "Separación X:" + +#: ../../po/../src/dialogs/tiledialog.cpp:804 +#, fuzzy +msgid "Horizontal spacing between columns" +msgstr "valor de escala horizontal" + +#: ../../po/../src/dialogs/tiledialog.cpp:818 +#, fuzzy +msgid "Arrange selected objects" +msgstr "Agrupa-los obxectos seleccionados" + +#: ../../po/../src/dialogs/xml-tree.cpp:178 +msgid "Click to select nodes, drag to rearrange." +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:189 +msgid "Click attribute to edit." +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:193 +#, c-format +msgid "" +"Attribute %s selected. Press Ctrl+Enter when done editing to " +"commit changes." +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:284 +msgid "Drag to reorder nodes" +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:304 +#, fuzzy +msgid "New element node" +msgstr "Documento" + +#: ../../po/../src/dialogs/xml-tree.cpp:326 +msgid "New text node" +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:347 +#, fuzzy +msgid "Duplicate node" +msgstr "Duplicar" + +#: ../../po/../src/dialogs/xml-tree.cpp:368 +#, fuzzy +msgid "Delete node" +msgstr "Borrar" + +#: ../../po/../src/dialogs/xml-tree.cpp:384 +#, fuzzy +msgid "Unindent node" +msgstr "Editar nodos" + +#: ../../po/../src/dialogs/xml-tree.cpp:399 +#, fuzzy +msgid "Indent node" +msgstr "Editar nodos" + +#: ../../po/../src/dialogs/xml-tree.cpp:411 +#, fuzzy +msgid "Raise node" +msgstr "Pegar" + +#: ../../po/../src/dialogs/xml-tree.cpp:423 +msgid "Lower node" +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:468 +msgid "Delete attribute" +msgstr "Borrar atributo" + +#. TRANSLATORS: "Attribute" is a noun here +#: ../../po/../src/dialogs/xml-tree.cpp:513 +#, fuzzy +msgid "Attribute name" +msgstr "Atributo:" + +#. TRANSLATORS: "Set" is a verb here +#: ../../po/../src/dialogs/xml-tree.cpp:533 +#, fuzzy +msgid "Set attribute" +msgstr "Borrar atributo" + +#. TRANSLATORS: "Set" is a verb here +#: ../../po/../src/dialogs/xml-tree.cpp:535 +#, fuzzy +msgid "Set" +msgstr "Seleccionar" + +#. TRANSLATORS: "Attribute" is a noun here +#: ../../po/../src/dialogs/xml-tree.cpp:558 +#, fuzzy +msgid "Attribute value" +msgstr "Atributos" + +#: ../../po/../src/dialogs/xml-tree.cpp:1318 +msgid "New element node..." +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:1339 +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:100 +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:98 +#, fuzzy +msgid "Cancel" +msgstr "Cambiar" + +#: ../../po/../src/dialogs/xml-tree.cpp:1345 +#, fuzzy +msgid "Create" +msgstr "Centrar" + +#: ../../po/../src/dialogs/xml-tree.cpp:1458 +#, c-format +msgid "" +"Cannot set %s: Another element with value %s already exists!" +msgstr "" + +#: ../../po/../src/document.cpp:369 +#, fuzzy, c-format +msgid "New document %d" +msgstr "Documento" + +#: ../../po/../src/document.cpp:401 +#, c-format +msgid "Memory document %d" +msgstr "" + +#: ../../po/../src/document.cpp:524 +#, c-format +msgid "Unnamed document %d" +msgstr "" + +#. We hit green anchor, closing Green-Blue-Red +#: ../../po/../src/draw-context.cpp:441 +msgid "Path is closed." +msgstr "" + +#. We hit bot start and end of single curve, closing paths +#: ../../po/../src/draw-context.cpp:456 +msgid "Closing path." +msgstr "" + +#. alpha of color under cursor, to show in the statusbar +#. locale-sensitive printf is OK, since this goes to the UI, not into SVG +#: ../../po/../src/dropper-context.cpp:354 +#, c-format +msgid " alpha %.3g" +msgstr "" + +#. where the color is picked, to show in the statusbar +#: ../../po/../src/dropper-context.cpp:356 +#, c-format +msgid ", averaged with radius %d" +msgstr "" + +#: ../../po/../src/dropper-context.cpp:356 +msgid " under cursor" +msgstr "" + +#. message, to show in the statusbar +#: ../../po/../src/dropper-context.cpp:358 +msgid "Release mouse to set color." +msgstr "" + +#: ../../po/../src/dropper-context.cpp:358 +#: ../../po/../src/tools-switch.cpp:207 +msgid "" +"Click to set fill, Shift+click to set stroke; drag to " +"average color in area; with Alt to pick inverse color; Ctrl+C " +"to copy the color under mouse to clipboard" +msgstr "" + +#: ../../po/../src/extension/dependency.cpp:244 +msgid "Dependency::" +msgstr "" + +#: ../../po/../src/extension/dependency.cpp:245 +#, fuzzy +msgid " type: " +msgstr "Configuración do recheo" + +#: ../../po/../src/extension/dependency.cpp:246 +#, fuzzy +msgid " location: " +msgstr "Selección" + +#: ../../po/../src/extension/dependency.cpp:247 +msgid " string: " +msgstr "" + +#: ../../po/../src/extension/dependency.cpp:250 +#, fuzzy +msgid " description: " +msgstr "Posición" + +#. static int i = 0; +#. std::cout << "Checking module[" << i++ << "]: " << name << std::endl; +#: ../../po/../src/extension/extension.cpp:244 +msgid "" +" This is caused by an improper .inx file for this extension. An improper ." +"inx file could have been caused by a faulty installation of Inkscape." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:247 +msgid "an ID was not defined for it." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:251 +msgid "there was no name defined for it." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:255 +msgid "the XML description of it got lost." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:259 +msgid "no implementation was defined for the extension." +msgstr "" + +#. std::cout << "Failed: " << *(_deps[i]) << std::endl; +#: ../../po/../src/extension/extension.cpp:266 +msgid "a dependency was not met." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:286 +msgid "Extension \"" +msgstr "" + +#: ../../po/../src/extension/extension.cpp:286 +msgid "\" failed to load because " +msgstr "" + +#: ../../po/../src/extension/extension.cpp:565 +#, c-format +msgid "Could not create extension error log file '%s'" +msgstr "" + +#. This is some filler text, needs to change before relase +#: ../../po/../src/extension/error-file.cpp:56 +msgid "" +"One or more extensions failed to load\n" +"\n" +"The failed extensions have been skipped. Inkscape will continue to run " +"normally but those extensions will be unavailable. For details to " +"troubleshoot this problem, please refer to the error log located at: " +msgstr "" + +#. This is some filler text, needs to change before relase +#: ../../po/../src/extension/error-file.cpp:65 +msgid "Show dialog on startup" +msgstr "" + +#: ../../po/../src/extension/implementation/script.cpp:845 +msgid "" +"Inkscape has received an error from the script that it called. The text " +"returned with the error is included below. Inkscape will continue working, " +"but the action you requested has been cancelled." +msgstr "" + +#: ../../po/../src/extension/implementation/script.cpp:858 +msgid "" +"Inkscape has received additional data from the script executed. The script " +"did not return an error, but this may indicate the results will not be as " +"expected." +msgstr "" + +#: ../../po/../src/extension/init.cpp:173 +msgid "Null external module directory name. Modules will not be loaded." +msgstr "" + +#: ../../po/../src/extension/init.cpp:187 +#, c-format +msgid "" +"Modules directory (%s) is unavailable. External modules in that directory " +"will not be loaded." +msgstr "" + +#: ../../po/../src/extension/internal/gnome.cpp:80 +#, fuzzy +msgid "Select printer" +msgstr "Selección" + +#: ../../po/../src/extension/internal/gnome.cpp:131 +#, fuzzy +msgid "Inkscape: Print Preview" +msgstr "Sodipodi (nome do doc. %s..): Previsualización da impresión" + +#: ../../po/../src/extension/internal/grid.cpp:213 +#, fuzzy +msgid "Line Width" +msgstr " Ancho " + +#: ../../po/../src/extension/internal/grid.cpp:214 +#, fuzzy +msgid "Horizontal Spacing" +msgstr "movemento horizontal" + +#: ../../po/../src/extension/internal/grid.cpp:215 +#, fuzzy +msgid "Vertical Spacing" +msgstr "Valor de centrado vertical" + +#: ../../po/../src/extension/internal/grid.cpp:216 +#, fuzzy +msgid "Horizontal Offset" +msgstr "movemento horizontal" + +#: ../../po/../src/extension/internal/grid.cpp:217 +#, fuzzy +msgid "Vertical Offset" +msgstr "Valor de centrado vertical" + +#: ../../po/../src/extension/internal/ps.cpp:123 +#, fuzzy +msgid "Print Destination" +msgstr "Imprimi-lo debuxo" + +#. Print properties frame +#: ../../po/../src/extension/internal/ps.cpp:138 +#, fuzzy +msgid "Print properties" +msgstr "Propiedades do elemento" + +#: ../../po/../src/extension/internal/ps.cpp:145 +msgid "Print using PostScript operators" +msgstr "" + +#: ../../po/../src/extension/internal/ps.cpp:147 +msgid "" +"Use PostScript vector operators. The resulting image is usually smaller in " +"file size and can be arbitrarily scaled, but alpha transparency and patterns " +"will be lost." +msgstr "" + +#: ../../po/../src/extension/internal/ps.cpp:152 +#, fuzzy +msgid "Print as bitmap" +msgstr "Exporta-lo ficheiro" + +#: ../../po/../src/extension/internal/ps.cpp:154 +msgid "" +"Print everything as bitmap. The resulting image is usually larger in file " +"size and cannot be arbitrarily scaled without quality loss, but all objects " +"will be rendered exactly as displayed." +msgstr "" + +#: ../../po/../src/extension/internal/ps.cpp:168 +msgid "Preferred resolution (dots per inch) of bitmap" +msgstr "" + +#: ../../po/../src/extension/internal/ps.cpp:182 +#, fuzzy +msgid "Resolution:" +msgstr "Selección" + +#. Print destination frame +#: ../../po/../src/extension/internal/ps.cpp:186 +#, fuzzy +msgid "Print destination" +msgstr "Imprimi-lo debuxo" + +#: ../../po/../src/extension/internal/ps.cpp:192 +msgid "" +"Use '> filename' to print to file.\n" +"Use '| prog arg...' to pipe to a program." +msgstr "" + +#: ../../po/../src/extension/internal/ps.cpp:1227 +msgid "write error occurred" +msgstr "" + +#: ../../po/../src/extension/prefdialog.cpp:21 +#, fuzzy +msgid " Preferences" +msgstr "O elemento é de referencia" + +#. We can't call sp_ui_error_dialog because we may be +#. running from the console, in which case calling sp_ui +#. routines will cause a segfault. See bug 1000350 - bryce +#. sp_ui_error_dialog(_("Format autodetect failed. The file is being opened as SVG.")); +#: ../../po/../src/extension/system.cpp:105 +msgid "Format autodetect failed. The file is being opened as SVG." +msgstr "" + +#. TRANSLATORS: default.svg is localizable - this is the name of the default document +#. template. This way you can localize the default pagesize, translate the name of +#. the default layer, etc. If you wish to localize this file, please create a +#. localized share/templates/default.xx.svg file, where xx is your language code. +#: ../../po/../src/file.cpp:133 +#, fuzzy +msgid "default.svg" +msgstr "Borrar" + +#: ../../po/../src/file.cpp:215 ../../po/../src/file.cpp:900 +#, c-format +msgid "Failed to load the requested file %s" +msgstr "" + +#: ../../po/../src/file.cpp:240 +#, fuzzy +msgid "Document not saved yet. Cannot revert." +msgstr "Documento" + +#: ../../po/../src/file.cpp:246 +#, c-format +msgid "Changes will be lost! Are you sure you want to reload document %s?" +msgstr "" + +#: ../../po/../src/file.cpp:266 +#, fuzzy +msgid "Document reverted." +msgstr "Documento" + +#: ../../po/../src/file.cpp:268 +#, fuzzy +msgid "Document not reverted." +msgstr "Documento" + +#: ../../po/../src/file.cpp:382 +msgid "Select file to open" +msgstr "Seleccione o ficheiro que quere abrir" + +#: ../../po/../src/file.cpp:518 +#, c-format +msgid "Removed %i unused definition in <defs>." +msgid_plural "Removed %i unused definitions in <defs>." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/file.cpp:523 +msgid "No unused definitions in <defs>." +msgstr "" + +#: ../../po/../src/file.cpp:548 +#, c-format +msgid "" +"No Inkscape extension found to save document (%s). This may have been " +"caused by an unknown filename extension." +msgstr "" + +#: ../../po/../src/file.cpp:549 ../../po/../src/file.cpp:557 +#, fuzzy +msgid "Document not saved." +msgstr "Documento" + +#: ../../po/../src/file.cpp:556 +#, c-format +msgid "File %s could not be saved." +msgstr "" + +#: ../../po/../src/file.cpp:566 +#, fuzzy +msgid "Document saved." +msgstr "Documento" + +#: ../../po/../src/file.cpp:614 +#, fuzzy, c-format +msgid "drawing%s" +msgstr "Debuxando" + +#: ../../po/../src/file.cpp:620 +#, fuzzy, c-format +msgid "drawing-%d%s" +msgstr "Debuxando" + +#: ../../po/../src/file.cpp:655 +#, fuzzy +msgid "Select file to save to" +msgstr "Seleccione o ficheiro que quere abrir" + +#: ../../po/../src/file.cpp:739 +msgid "No changes need to be saved." +msgstr "" + +#: ../../po/../src/file.cpp:926 +msgid "Select file to import" +msgstr "Seleccione o ficheiro a importar" + +#: ../../po/../src/gradient-context.cpp:263 +msgid "Ctrl: snap gradient angle" +msgstr "" + +#: ../../po/../src/gradient-context.cpp:264 +msgid "Shift: draw gradient around the starting point" +msgstr "" + +#. We did an undoable action, but sp_document_done will be called by the knot when released +#. status text; we do not track coords because this branch is run once, not all the time +#. during drag +#: ../../po/../src/gradient-context.cpp:462 +#, c-format +msgid "Gradient for %d objects; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/gradient-context.cpp:464 +#, fuzzy +msgid "Select objects on which to create gradient." +msgstr "Converti-los obxectos seleccionados a curvas" + +#: ../../po/../src/gradient-drag.cpp:65 +#, fuzzy +msgid "Linear gradient start" +msgstr "Engadir novo degradado" + +#. POINT_LG_P1 +#: ../../po/../src/gradient-drag.cpp:66 +#, fuzzy +msgid "Linear gradient end" +msgstr "Engadir novo degradado" + +#: ../../po/../src/gradient-drag.cpp:67 +#, fuzzy +msgid "Radial gradient center" +msgstr "Engadir novo degradado" + +#: ../../po/../src/gradient-drag.cpp:68 ../../po/../src/gradient-drag.cpp:69 +#, fuzzy +msgid "Radial gradient radius" +msgstr "Engadir novo degradado" + +#: ../../po/../src/gradient-drag.cpp:70 +#, fuzzy +msgid "Radial gradient focus" +msgstr "Engadir novo degradado" + +#: ../../po/../src/gradient-drag.cpp:659 +#, c-format +msgid "" +"%s for: %s%s; drag with Ctrl to snap angle, with Ctrl+Alt to " +"preserve angle, with Ctrl+Shift to scale around center" +msgstr "" + +#: ../../po/../src/gradient-drag.cpp:662 +#, fuzzy +msgid " (stroke)" +msgstr "Está trazado" + +#: ../../po/../src/gradient-drag.cpp:665 +msgid "" +"Radial gradient center and focus; drag with Shift to " +"separate focus" +msgstr "" + +#: ../../po/../src/gradient-drag.cpp:667 +#, c-format +msgid "" +"Gradient point shared by %d gradients; drag with Shift to " +"separate" +msgstr "" + +#: ../../po/../src/helper/units.cpp:40 +#, fuzzy +msgid "Unit" +msgstr "Unidades:" + +#: ../../po/../src/helper/units.cpp:40 +#, fuzzy +msgid "Units" +msgstr "Unidades:" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Point" +msgstr "Punto" + +# [*] mirar unidades +#: ../../po/../src/helper/units.cpp:41 +msgid "pt" +msgstr "pt" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Points" +msgstr "Puntos" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Pt" +msgstr "" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Pixel" +msgstr "Pixel" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Pixels" +msgstr "Pixeles" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Px" +msgstr "" + +#. You can add new elements from this point forward +#: ../../po/../src/helper/units.cpp:44 ../share/extensions/straightseg.inx.h:2 +msgid "Percent" +msgstr "Porcentaxe" + +#: ../../po/../src/helper/units.cpp:44 +#, fuzzy +msgid "Percents" +msgstr "Porcentaxe" + +#: ../../po/../src/helper/units.cpp:45 +msgid "Millimeter" +msgstr "Milímetro" + +#: ../../po/../src/helper/units.cpp:45 +msgid "mm" +msgstr "mm" + +#: ../../po/../src/helper/units.cpp:45 +msgid "Millimeters" +msgstr "Milímetros" + +#: ../../po/../src/helper/units.cpp:46 +msgid "Centimeter" +msgstr "Centímetro" + +#: ../../po/../src/helper/units.cpp:46 +msgid "cm" +msgstr "cm" + +#: ../../po/../src/helper/units.cpp:46 +msgid "Centimeters" +msgstr "Centímetros" + +#: ../../po/../src/helper/units.cpp:47 +#, fuzzy +msgid "Meter" +msgstr "Centrar" + +#: ../../po/../src/helper/units.cpp:47 +#, fuzzy +msgid "m" +msgstr "em" + +#: ../../po/../src/helper/units.cpp:47 +#, fuzzy +msgid "Meters" +msgstr "Centrar" + +#. no svg_unit +#: ../../po/../src/helper/units.cpp:48 +msgid "Inch" +msgstr "Polgada" + +# [*] mirar unidades +#: ../../po/../src/helper/units.cpp:48 +msgid "in" +msgstr "in" + +#: ../../po/../src/helper/units.cpp:48 +msgid "Inches" +msgstr "Polgadas" + +# [*] Revisar +#. Volatiles do not have default, so there are none here +#. TRANSLATORS: for info, see http://www.w3.org/TR/REC-CSS2/syndata.html#length-units +#: ../../po/../src/helper/units.cpp:51 +msgid "Em square" +msgstr "Em cadrado" + +#: ../../po/../src/helper/units.cpp:51 +msgid "em" +msgstr "em" + +# [*] Revisar +#: ../../po/../src/helper/units.cpp:51 +msgid "Em squares" +msgstr "Em cadrados" + +# [*] Revisar +#. TRANSLATORS: for info, see http://www.w3.org/TR/REC-CSS2/syndata.html#length-units +#: ../../po/../src/helper/units.cpp:53 +msgid "Ex square" +msgstr "Ex cadrado" + +#: ../../po/../src/helper/units.cpp:53 +msgid "ex" +msgstr "ex" + +# [*] Revisar +#: ../../po/../src/helper/units.cpp:53 +msgid "Ex squares" +msgstr "Ex cadrados" + +#: ../../po/../src/inkscape.cpp:468 +msgid "Untitled document" +msgstr "" + +#. Show nice dialog box +#: ../../po/../src/inkscape.cpp:497 +msgid "Inkscape encountered an internal error and will close now.\n" +msgstr "" + +#: ../../po/../src/inkscape.cpp:498 +msgid "" +"Automatic backups of unsaved documents were done to the following " +"locations:\n" +msgstr "" + +#: ../../po/../src/inkscape.cpp:499 +msgid "Automatic backup of the following documents failed:\n" +msgstr "" + +#: ../../po/../src/inkscape.cpp:634 +#, c-format +msgid "" +"Cannot create directory %s.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:635 +#, c-format +msgid "" +"%s is not a valid directory.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:636 +#, c-format +msgid "" +"Cannot create file %s.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:637 +#, c-format +msgid "" +"Cannot write file %s.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:638 +msgid "" +"Although Inkscape will run, it will use default settings,\n" +"and any changes made in preferences will not be saved." +msgstr "" + +#: ../../po/../src/inkscape.cpp:708 +#, c-format +msgid "" +"%s is not a regular file.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:709 +#, c-format +msgid "" +"%s not a valid XML file, or\n" +"you don't have read permissions on it.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:711 +#, c-format +msgid "" +"%s is not a valid menus file.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:712 +msgid "" +"Inkscape will run with default menus.\n" +"New menus will not be saved." +msgstr "" + +#. sp_ui_menu_append_check_item_from_verb(m, view, _("_Menu"), _("Show or hide the menu bar"), "menu", +#. checkitem_toggled, checkitem_update, 0); +#: ../../po/../src/interface.cpp:753 +msgid "Commands Bar" +msgstr "" + +#: ../../po/../src/interface.cpp:753 +#, fuzzy +msgid "Show or hide the Commands bar (under the menu)" +msgstr "Amosar guías" + +#: ../../po/../src/interface.cpp:755 +#, fuzzy +msgid "Tool Controls" +msgstr "Opcións de Oaf" + +#: ../../po/../src/interface.cpp:755 +#, fuzzy +msgid "Show or hide the Tool Controls panel" +msgstr "Amosar guías" + +#: ../../po/../src/interface.cpp:757 +msgid "_Toolbox" +msgstr "" + +#: ../../po/../src/interface.cpp:757 +msgid "Show or hide the main toolbox (on the left)" +msgstr "" + +#: ../../po/../src/interface.cpp:763 +msgid "_Statusbar" +msgstr "" + +#: ../../po/../src/interface.cpp:763 +msgid "Show or hide the statusbar (at the bottom of the window)" +msgstr "" + +#: ../../po/../src/interface.cpp:820 +#, c-format +msgid "Verb \"%s\" Unknown" +msgstr "" + +#. TRANSLATORS: #%s is the id of the group e.g. , not a number. +#: ../../po/../src/interface.cpp:930 +#, fuzzy, c-format +msgid "Enter group #%s" +msgstr "Editar nodos" + +#: ../../po/../src/interface.cpp:941 +#, fuzzy +msgid "Go to parent" +msgstr "Zoom á páxina" + +#: ../../po/../src/interface.cpp:972 +msgid "Could not parse SVG data" +msgstr "" + +#: ../../po/../src/interface.cpp:1135 +#, c-format +msgid "Overwrite %s" +msgstr "" + +#: ../../po/../src/interface.cpp:1153 +#, c-format +msgid "" +"The file %s already exists. Do you want to overwrite that file with the " +"current document?" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:59 +msgid "Jabber connection lost." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:72 +#, c-format +msgid "Sending message; %u message remaining in send queue." +msgid_plural "Sending message; %u messages remaining in send queue." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:78 +msgid "Receive queue empty." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:154 +#, c-format +msgid "Receiving change; %u change left to process." +msgid_plural "Receiving change; %u changes left to process." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:157 +#, c-format +msgid "%s has left the chatroom." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:221 +msgid "Nickname %1 is already in use. Please choose a different nickname." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:225 +msgid "An error was encountered while attempting to connect to the server." +msgstr "" + +#. Check to see if the user made any modifications to this document. If so, +#. we want to give them the option of (1) letting us clear their document or (2) +#. opening a new, blank document for the whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:131 +msgid "%1 has invited you to a whiteboard session." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:132 +msgid "Incoming whiteboard invitation from %1" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:135 +msgid "Do you wish to accept %1's whiteboard session invitation?" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:137 +msgid "" +"Would you like to accept %1's invitation in a new document window?\n" +"Accepting the invitation in your current window will discard unsaved changes." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:143 +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:198 +#, fuzzy +msgid "Accept invitation" +msgstr "Selección" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:144 +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:199 +msgid "Decline invitation" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:145 +#, fuzzy +msgid "Accept invitation in new document window" +msgstr "Documento" + +#. We could not create a new desktop; ask the user if she or he wants to +#. replace the current document and accept the invitation, or reject the invitation. +#. TRANSLATORS: %1 is a userid here +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:196 +msgid "" +"A new document window could not be opened for a whiteboard session with %" +"1" +msgstr "" + +#. TRANSLATORS: %1 is the peer whom refused our invitation. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:238 +msgid "" +"The user %1 has refused your " +"whiteboard invitation.\n" +"\n" +msgstr "" + +#. TRANSLATORS: %1 is the peer whom refused our invitation, %2 is our Jabber identity. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:241 +msgid "" +"You are still connected to a Jabber server as %2, and may send an " +"invitation to %1 again, or you may send an invitation to a different " +"user." +msgstr "" + +#. TRANSLATORS: %1 is the peer whom we tried to contact, but is already in a whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:252 +msgid "" +"The user %1 is already in a " +"whiteboard session.\n" +"\n" +msgstr "" + +#. TRANSLATORS: %1 is the peer whom we tried to contact, but is already in a whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:255 +msgid "" +"You are still connected to a Jabber server as %1, and may send an " +"invitation to a different user." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/invitation-confirm-dialog.cpp:26 +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:24 +msgid "_Write session file:" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/message-processors.cpp:145 +#, c-format +msgid "%s has joined the chatroom." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/message-queue.cpp:87 +#, c-format +msgid "%u change in receive queue." +msgid_plural "%u changes in receive queue." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/jabber_whiteboard/message-queue.cpp:117 +#, c-format +msgid "%u change in send queue." +msgid_plural "%u changes in send queue." +msgstr[0] "" +msgstr[1] "" + +#. if ID is NULL, then we have a real problem -- we were not able to find a key +#. nor generate one. The only thing we can really do here is abort, since we have +#. no way to let the other client(s) uniquely identify this object. +#. FIXME: If this indicates a programming bug, then don't request translation with +#. * _(...): it is most useful in untranslated form so that developers may search for +#. * it when someone reports it in a bug report (as we want users to do for all bugs, +#. * as indicated by it being a g_warning string). +#. * +#. * Otherwise, if it is not a programming bug but a network error or a bug in the +#. * remote peer (perhaps running different software) or whatever, then present it in +#. * an alert box, and avoid use of technical jargon `NULL'. +#. +#: ../../po/../src/jabber_whiteboard/message-utilities.cpp:171 +msgid "" +"ID for new object is NULL even after generation and lookup attempts: the new " +"object will NOT be sent, nor will any of its child objects!" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:60 +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:995 +msgid "Select a location and filename" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:62 +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:997 +#, fuzzy +msgid "Set filename" +msgstr "Nome do ficheiro png" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:301 +msgid "No SSL certificate was found." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:304 +msgid "The SSL certificate provided by the Jabber server is untrusted." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:307 +msgid "The SSL certificate provided by the Jabber server is expired." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:310 +msgid "" +"The SSL certificate provided by the Jabber server has not been activated." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:313 +msgid "" +"The SSL certificate provided by the Jabber server contains a hostname that " +"does not match the Jabber server's hostname." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:316 +msgid "" +"The SSL certificate provided by the Jabber server contains an invalid " +"fingerprint." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:319 +msgid "An unknown error occurred while setting up the SSL connection." +msgstr "" + +#. TRANSLATORS: %1 is the message that describes the specific error that occurred when +#. establishing the SSL connection. +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:325 +msgid "" +"%1\n" +"\n" +"Do you wish to continue connecting to the Jabber server?" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:328 +msgid "Continue connecting and ignore further errors" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:329 +msgid "Continue connecting, but warn me of further errors" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:330 +#, fuzzy +msgid "Cancel connection" +msgstr "Selección" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:777 +#, c-format +msgid "Established whiteboard session with %s." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:785 +#, c-format +msgid "%s has left the whiteboard session." +msgstr "" + +#. Inform the user +#. TRANSLATORS: %1 is the name of the user that disconnected, %2 is the name of the user whom the disconnected user disconnected from. +#. This message is not used in a chatroom context. +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:790 +msgid "" +"The user %1 has left the " +"whiteboard session.\n" +"\n" +msgstr "" + +#. TRANSLATORS: %1 and %2 are userids +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:792 +msgid "" +"You are still connected to a Jabber server as %2, and may establish a " +"new session to %1 or a different user." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:988 +msgid "" +"Could not open file %1 for session recording.\n" +"The error encountered was: %2.\n" +"\n" +"You may select a different location to record the session, or you may opt to " +"not record this session." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:990 +msgid "Choose a different location" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:991 +msgid "Skip session recording" +msgstr "" + +#: ../../po/../src/knot.cpp:673 +msgid "Node or handle drag canceled." +msgstr "" + +#: ../../po/../src/libnrtype/FontFactory.cpp:358 +msgid "Ignoring font without family that will crash Pango" +msgstr "" + +#: ../../po/../src/main.cpp:395 +msgid "Print the Inkscape version number" +msgstr "" + +#: ../../po/../src/main.cpp:400 +msgid "Do not use X server (only process files from console)" +msgstr "" + +#: ../../po/../src/main.cpp:405 +msgid "Try to use X server (even if $DISPLAY is not set)" +msgstr "" + +#: ../../po/../src/main.cpp:410 +#, fuzzy +msgid "Open specified document(s) (option string may be excluded)" +msgstr "Abri-lo ficheiro especificado (débese exclui-la cadea de opcion)" + +#: ../../po/../src/main.cpp:411 ../../po/../src/main.cpp:416 +#: ../../po/../src/main.cpp:421 ../../po/../src/main.cpp:483 +#: ../../po/../src/main.cpp:488 ../../po/../src/main.cpp:493 +msgid "FILENAME" +msgstr "NOME DO FICHEIRO" + +#: ../../po/../src/main.cpp:415 +#, fuzzy +msgid "Print document(s) to specified output file (use '| program' for pipe)" +msgstr "" +"Imprimi-los ficheiros ó ficheiro de saida especificado (use '| programa' " +"para canalización)" + +#: ../../po/../src/main.cpp:420 +#, fuzzy +msgid "Export document to a PNG file" +msgstr "Exporta-lo debuxo a png" + +#: ../../po/../src/main.cpp:425 +msgid "The resolution used for exporting SVG into bitmap (default 90)" +msgstr "" + +#: ../../po/../src/main.cpp:426 +msgid "DPI" +msgstr "" + +#: ../../po/../src/main.cpp:430 +msgid "" +"Exported area in SVG user units (default is the canvas; 0,0 is lower-left " +"corner)" +msgstr "" + +#: ../../po/../src/main.cpp:431 +msgid "x0:y0:x1:y1" +msgstr "" + +#: ../../po/../src/main.cpp:435 +msgid "Exported area is the entire drawing (not canvas)" +msgstr "" + +#: ../../po/../src/main.cpp:440 +msgid "" +"Snap the bitmap export area outwards to the nearest integer values (in SVG " +"user units)" +msgstr "" + +#: ../../po/../src/main.cpp:445 +msgid "The width of exported bitmap in pixels (overrides export-dpi)" +msgstr "" + +#: ../../po/../src/main.cpp:446 +msgid "WIDTH" +msgstr "" + +#: ../../po/../src/main.cpp:450 +msgid "The height of exported bitmap in pixels (overrides export-dpi)" +msgstr "" + +#: ../../po/../src/main.cpp:451 +msgid "HEIGHT" +msgstr "" + +#: ../../po/../src/main.cpp:455 +msgid "The ID of the object to export (overrides export-area)" +msgstr "" + +#: ../../po/../src/main.cpp:456 ../../po/../src/main.cpp:532 +#, fuzzy +msgid "ID" +msgstr "ID:" + +#. TRANSLATORS: this means: "Only export the object whose id is given in --export-id". +#. See "man inkscape" for details. +#: ../../po/../src/main.cpp:462 +msgid "" +"Export just the object with export-id, hide all others (only with export-id)" +msgstr "" + +#: ../../po/../src/main.cpp:467 +msgid "Use stored filename and DPI hints when exporting (only with export-id)" +msgstr "" + +#: ../../po/../src/main.cpp:472 +msgid "Background color of exported bitmap (any SVG-supported color string)" +msgstr "" + +#: ../../po/../src/main.cpp:473 +msgid "COLOR" +msgstr "" + +#: ../../po/../src/main.cpp:477 +msgid "Background opacity of exported bitmap (either 0.0 to 1.0, or 1 to 255)" +msgstr "" + +#: ../../po/../src/main.cpp:478 +msgid "VALUE" +msgstr "" + +#: ../../po/../src/main.cpp:482 +msgid "Export document to plain SVG file (no sodipodi or inkscape namespaces)" +msgstr "" + +#: ../../po/../src/main.cpp:487 +#, fuzzy +msgid "Export document to a PS file" +msgstr "Exporta-lo debuxo a png" + +#: ../../po/../src/main.cpp:492 +#, fuzzy +msgid "Export document to an EPS file" +msgstr "Exporta-lo debuxo a png" + +#: ../../po/../src/main.cpp:497 +#, fuzzy +msgid "Convert text object to paths on export (EPS)" +msgstr "Converti-los obxectos seleccionados a curvas" + +#: ../../po/../src/main.cpp:502 +msgid "Export files with the bounding box set to the page size (EPS)" +msgstr "" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:508 +msgid "" +"Query the X coordinate of the drawing or, if specified, of the object with --" +"query-id" +msgstr "" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:514 +msgid "" +"Query the Y coordinate of the drawing or, if specified, of the object with --" +"query-id" +msgstr "" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:520 +msgid "" +"Query the width of the drawing or, if specified, of the object with --query-" +"id" +msgstr "" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:526 +msgid "" +"Query the height of the drawing or, if specified, of the object with --query-" +"id" +msgstr "" + +#: ../../po/../src/main.cpp:531 +msgid "The ID of the object whose dimensions are queried" +msgstr "" + +#. TRANSLATORS: this option makes Inkscape print the name (path) of the extension directory +#: ../../po/../src/main.cpp:537 +msgid "Print out the extension directory and exit" +msgstr "" + +#: ../../po/../src/main.cpp:542 +msgid "Show given files one-by-one, switch to next on any key/mouse event" +msgstr "" +"Amosa-los ficheiros un a un, cambiar ó seguinte nun evento de teclado/rato" + +#: ../../po/../src/main.cpp:547 +msgid "Use the new Gtkmm GUI interface" +msgstr "" + +#: ../../po/../src/main.cpp:552 +msgid "Remove unused definitions from the defs section(s) of the document" +msgstr "" + +#: ../../po/../src/main.cpp:741 +msgid "" +"[OPTIONS...] [FILE...]\n" +"\n" +"Available options:" +msgstr "" + +#: ../../po/../src/menus-skeleton.h:17 +msgid "_New" +msgstr "_Novo" + +#: ../../po/../src/menus-skeleton.h:22 +#, fuzzy +msgid "Open _Recent" +msgstr "_Abrir" + +#: ../../po/../src/menus-skeleton.h:53 +#, fuzzy +msgid "_Edit" +msgstr "Editar" + +#: ../../po/../src/menus-skeleton.h:84 +#, fuzzy +msgid "_View" +msgstr "Nova vista" + +#: ../../po/../src/menus-skeleton.h:85 +#, fuzzy +msgid "_Zoom" +msgstr "Zoom" + +#: ../../po/../src/menus-skeleton.h:102 +#, fuzzy +msgid "Show/Hide" +msgstr "Amosar guías" + +#: ../../po/../src/menus-skeleton.h:107 +#, fuzzy +msgid "_Display mode" +msgstr "Visualización" + +#: ../../po/../src/menus-skeleton.h:126 +#, fuzzy +msgid "_Layer" +msgstr "Seleccionar" + +#: ../../po/../src/menus-skeleton.h:143 +#, fuzzy +msgid "_Object" +msgstr "Obxecto" + +#: ../../po/../src/menus-skeleton.h:165 +#, fuzzy +msgid "_Path" +msgstr "Pegar" + +#: ../../po/../src/menus-skeleton.h:188 +#, fuzzy +msgid "_Text" +msgstr "Texto" + +#: ../../po/../src/menus-skeleton.h:200 +#, fuzzy +msgid "Effects" +msgstr "Obxecto" + +#: ../../po/../src/menus-skeleton.h:207 +msgid "Whiteboa_rd" +msgstr "" + +#: ../../po/../src/menus-skeleton.h:220 +#, fuzzy +msgid "_Help" +msgstr "_Axuda" + +#: ../../po/../src/menus-skeleton.h:222 +msgid "Tutorials" +msgstr "" + +#: ../../po/../src/node-context.cpp:382 +msgid "" +"Ctrl: toggle node type, snap handle angle, move hor/vert; Ctrl" +"+Alt: move along handles" +msgstr "" + +#: ../../po/../src/node-context.cpp:383 +msgid "" +"Shift: toggle node selection, disable snapping, rotate both handles" +msgstr "" + +#: ../../po/../src/node-context.cpp:384 +msgid "Alt: lock handle length; Ctrl+Alt: move along handles" +msgstr "" + +#: ../../po/../src/nodepath.cpp:1399 ../../po/../src/nodepath.cpp:1411 +#: ../../po/../src/nodepath.cpp:1492 ../../po/../src/nodepath.cpp:1504 +msgid "To join, you must have two endnodes selected." +msgstr "" + +#: ../../po/../src/nodepath.cpp:1633 ../../po/../src/nodepath.cpp:1647 +msgid "" +"Select two non-endpoint nodes on a path between which to delete " +"segments." +msgstr "" + +#: ../../po/../src/nodepath.cpp:1743 +#, fuzzy +msgid "Cannot find path between nodes." +msgstr "Suaviza-la liña nos nodos seleccionados" + +#: ../../po/../src/nodepath.cpp:2822 +#, c-format +msgid "" +"Node handle: angle %0.2f°, length %s; with Ctrl to snap " +"angle; with Alt to lock length; with Shift to rotate both " +"handles" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3351 +msgid "" +"Node: drag to edit the path; with Ctrl to snap to horizontal/" +"vertical; with Ctrl+Alt to snap to handles' directions" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3375 +msgid "" +"Node handle: drag to shape the curve; with Ctrl to snap angle; " +"with Alt to lock length; with Shift to rotate both handles" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3399 +msgid "" +"Node handle: drag to shape the curve; with Ctrl to snap angle; " +"with Alt to lock length; with Shift to rotate the opposite " +"handle in sync" +msgstr "" + +#. TRANSLATORS: "end" is an adjective here (NOT a verb) +#: ../../po/../src/nodepath.cpp:3591 +#, fuzzy +msgid "end node" +msgstr "Editar nodos" + +#. TRANSLATORS: "cusp" means "sharp" (cusp node); see also the Advanced Tutorial +#: ../../po/../src/nodepath.cpp:3596 +#, fuzzy +msgid "cusp" +msgstr "nos" + +#. TRANSLATORS: "smooth" is an adjective here +#: ../../po/../src/nodepath.cpp:3599 +msgid "smooth" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3601 +#, fuzzy +msgid "symmetric" +msgstr "Asimétrico" + +#. TRANSLATORS: "end" is an adjective here (NOT a verb) +#: ../../po/../src/nodepath.cpp:3607 +msgid "end node, handle retracted (drag with Shift to extend)" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3609 +msgid "one handle retracted (drag with Shift to extend)" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3612 +msgid "both handles retracted (drag with Shift to extend)" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3624 +msgid "Drag nodes or node handles; arrow keys to move nodes" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3625 +msgid "Drag the node or its handles; arrow keys to move the node" +msgstr "" + +# [*] Revisar +#: ../../po/../src/nodepath.cpp:3651 ../../po/../src/nodepath.cpp:3663 +#, fuzzy +msgid "Select a single object to edit its nodes or handles." +msgstr "Voltea-los obxectos seleccionados" + +#: ../../po/../src/nodepath.cpp:3655 +#, c-format +msgid "" +"0 out of %i node selected. Click, Shift+click, " +"or drag around nodes to select." +msgid_plural "" +"0 out of %i nodes selected. Click, Shift+click, " +"or drag around nodes to select." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/nodepath.cpp:3661 +msgid "Drag the handles of the object to modify it." +msgstr "" + +#: ../../po/../src/nodepath.cpp:3669 +#, fuzzy, c-format +msgid "%i of %i node selected; %s. %s." +msgid_plural "%i of %i nodes selected; %s. %s." +msgstr[0] "Suaviza-la liña nos nodos seleccionados" +msgstr[1] "Suaviza-la liña nos nodos seleccionados" + +#: ../../po/../src/nodepath.cpp:3675 +#, fuzzy, c-format +msgid "%i of %i node selected. %s." +msgid_plural "%i of %i nodes selected. %s." +msgstr[0] "Suaviza-la liña nos nodos seleccionados" +msgstr[1] "Suaviza-la liña nos nodos seleccionados" + +#: ../../po/../src/object-edit.cpp:493 +msgid "" +"Adjust the horizontal rounding radius; with Ctrl to make the " +"vertical radius the same" +msgstr "" + +#: ../../po/../src/object-edit.cpp:499 +msgid "" +"Adjust the vertical rounding radius; with Ctrl to make the " +"horizontal radius the same" +msgstr "" + +#: ../../po/../src/object-edit.cpp:506 ../../po/../src/object-edit.cpp:513 +msgid "" +"Adjust the width and height of the rectangle; with Ctrl to " +"lock ratio or stretch in one dimension only" +msgstr "" + +#: ../../po/../src/object-edit.cpp:686 +msgid "Adjust ellipse width, with Ctrl to make circle" +msgstr "" + +#: ../../po/../src/object-edit.cpp:689 +msgid "Adjust ellipse height, with Ctrl to make circle" +msgstr "" + +#: ../../po/../src/object-edit.cpp:692 +msgid "" +"Position the start point of the arc or segment; with Ctrl to " +"snap angle; drag inside the ellipse for arc, outside for " +"segment" +msgstr "" + +#: ../../po/../src/object-edit.cpp:695 +msgid "" +"Position the end point of the arc or segment; with Ctrl to " +"snap angle; drag inside the ellipse for arc, outside for " +"segment" +msgstr "" + +#: ../../po/../src/object-edit.cpp:800 +msgid "" +"Adjust the tip radius of the star or polygon; with Shift to " +"round; with Alt to randomize" +msgstr "" + +#: ../../po/../src/object-edit.cpp:803 +msgid "" +"Adjust the base radius of the star; with Ctrl to keep star " +"rays radial (no skew); with Shift to round; with Alt to " +"randomize" +msgstr "" + +#: ../../po/../src/object-edit.cpp:967 +msgid "" +"Roll/unroll the spiral from inside; with Ctrl to snap angle; " +"with Alt to converge/diverge" +msgstr "" + +#: ../../po/../src/object-edit.cpp:969 +msgid "" +"Roll/unroll the spiral from outside; with Ctrl to snap angle; " +"with Shift to scale/rotate" +msgstr "" + +#: ../../po/../src/object-edit.cpp:1006 +msgid "Adjust the offset distance" +msgstr "" + +#. TRANSLATORS: This refers to the pattern that's inside the object +#: ../../po/../src/object-edit.cpp:1036 +msgid "Move the pattern fill inside the object" +msgstr "" + +#: ../../po/../src/object-edit.cpp:1038 +#, fuzzy +msgid "Scale the pattern fill uniformly" +msgstr "Converti-los obxectos seleccionados a curvas" + +#: ../../po/../src/object-edit.cpp:1040 +msgid "Rotate the pattern fill; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/object-edit.cpp:1065 +msgid "Drag to resize the flowed text frame" +msgstr "" + +#. Item dialog +#: ../../po/../src/object-ui.cpp:106 +#, fuzzy +msgid "Object _Properties" +msgstr "Propiedades do obxecto" + +#. Select item +#: ../../po/../src/object-ui.cpp:116 +#, fuzzy +msgid "_Select This" +msgstr "Seleccionar esto" + +#. Create link +#: ../../po/../src/object-ui.cpp:126 +#, fuzzy +msgid "_Create Link" +msgstr "Centrar" + +#. "Ungroup" +#: ../../po/../src/object-ui.cpp:199 ../../po/../src/verbs.cpp:1931 +msgid "_Ungroup" +msgstr "_Desagrupar" + +#. Link dialog +#: ../../po/../src/object-ui.cpp:239 +#, fuzzy +msgid "Link _Properties" +msgstr "Propiedades do elemento" + +#. Select item +#: ../../po/../src/object-ui.cpp:249 +#, fuzzy +msgid "_Follow Link" +msgstr "liña completa" + +#. Reset transformations +#: ../../po/../src/object-ui.cpp:254 +msgid "_Remove Link" +msgstr "" + +#. Link dialog +#: ../../po/../src/object-ui.cpp:303 +#, fuzzy +msgid "Image _Properties" +msgstr "Propiedades do elemento" + +#. Item dialog +#: ../../po/../src/object-ui.cpp:344 +#, fuzzy +msgid "_Fill and Stroke" +msgstr "Configuración do escritorio" + +# [*] Revisar +#: ../../po/../src/path-chemistry.cpp:58 +#, fuzzy +msgid "Select at least two objects to combine." +msgstr "Voltea-los obxectos seleccionados" + +#: ../../po/../src/path-chemistry.cpp:65 +#, fuzzy +msgid "At least one of the objects is not a path, cannot combine." +msgstr "Converti-los obxectos seleccionados a curvas" + +#: ../../po/../src/path-chemistry.cpp:73 +msgid "" +"You cannot combine objects from different groups or layers." +msgstr "" + +#: ../../po/../src/path-chemistry.cpp:155 +#, fuzzy +msgid "Select path(s) to break apart." +msgstr "Converti-los obxectos seleccionados a curvas" + +#: ../../po/../src/path-chemistry.cpp:231 +msgid "No path(s) to break apart in the selection." +msgstr "" + +#: ../../po/../src/path-chemistry.cpp:252 +#, fuzzy +msgid "Select object(s) to convert to path." +msgstr "Converti-los obxectos seleccionados a curvas" + +#: ../../po/../src/path-chemistry.cpp:297 +#, fuzzy +msgid "No objects to convert to path in the selection." +msgstr "Converti-los obxectos seleccionados a curvas" + +#: ../../po/../src/path-chemistry.cpp:345 +#, fuzzy +msgid "Select path(s) to reverse." +msgstr "Eleva-la selección ó tope" + +#: ../../po/../src/path-chemistry.cpp:370 +msgid "No paths to reverse in the selection." +msgstr "" + +#: ../../po/../src/pen-context.cpp:379 ../../po/../src/pencil-context.cpp:233 +#, fuzzy +msgid "Continuing selected path" +msgstr "Combina-las curvas seleccionadas" + +#: ../../po/../src/pen-context.cpp:390 ../../po/../src/pencil-context.cpp:242 +#, fuzzy +msgid "Creating new path" +msgstr "Documento" + +#: ../../po/../src/pen-context.cpp:394 ../../po/../src/pencil-context.cpp:246 +#, fuzzy +msgid "Appending to selected path" +msgstr "Zoom á selección" + +#: ../../po/../src/pen-context.cpp:538 +msgid "Click or click and drag to close and finish the path." +msgstr "" + +#: ../../po/../src/pen-context.cpp:548 +msgid "" +"Click or click and drag to continue the path from this point." +msgstr "" + +#: ../../po/../src/pen-context.cpp:857 +#, c-format +msgid "" +"%s: angle %3.2f°, distance %s; with Ctrl to snap angle, " +"Enter to finish the path" +msgstr "" + +#: ../../po/../src/pen-context.cpp:882 +#, c-format +msgid "" +"Curve handle: angle %3.2f°, length %s; with Ctrl to snap " +"angle" +msgstr "" + +#: ../../po/../src/pen-context.cpp:912 +#, c-format +msgid "" +"%s: angle %3.2f°, length %s; with Ctrl to snap angle, " +"with Shift to move this handle only" +msgstr "" + +#: ../../po/../src/pen-context.cpp:946 +#, fuzzy +msgid "Finishing pen" +msgstr "Man alzada" + +#: ../../po/../src/pencil-context.cpp:320 +msgid "Release here to close and finish the path." +msgstr "" + +#: ../../po/../src/pencil-context.cpp:326 +#, fuzzy +msgid "Drawing a freehand path" +msgstr "Debuxar liña a man alzada" + +#: ../../po/../src/pencil-context.cpp:331 +msgid "Drag to continue the path from this point." +msgstr "" + +#. Write curves to object +#: ../../po/../src/pencil-context.cpp:390 +#, fuzzy +msgid "Finishing freehand" +msgstr "Man alzada" + +#: ../../po/../src/rect-context.cpp:387 +msgid "" +"Ctrl: make square or integer-ratio rect, lock a rounded corner " +"circular" +msgstr "" + +#: ../../po/../src/rect-context.cpp:549 +#, c-format +msgid "" +"Rectangle: %s × %s; with Ctrl to make square or integer-" +"ratio rectangle; with Shift to draw around the starting point" +msgstr "" + +#: ../../po/../src/select-context.cpp:243 +#, fuzzy +msgid "Move canceled." +msgstr "Selección" + +#: ../../po/../src/select-context.cpp:252 +#, fuzzy +msgid "Selection canceled." +msgstr "Selección" + +#: ../../po/../src/select-context.cpp:642 +msgid "Ctrl: select in groups, move hor/vert" +msgstr "" + +#: ../../po/../src/select-context.cpp:643 +msgid "Shift: toggle select, force rubberband, disable snapping" +msgstr "" + +#: ../../po/../src/select-context.cpp:644 +msgid "Alt: select under, move selected" +msgstr "" + +#: ../../po/../src/select-context.cpp:798 +#, fuzzy +msgid "Selected object is not a group. Cannot enter." +msgstr "Converti-los obxectos seleccionados a curvas" + +#: ../../po/../src/select-context.cpp:876 +#, c-format +msgid "" +"Move by %s, %s; with Ctrl to restrict to horizontal/vertical; " +"with Shift to disable snapping" +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:228 +msgid "Nothing was deleted." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:259 +#, fuzzy +msgid "Select object(s) to duplicate." +msgstr "Converti-los obxectos seleccionados a curvas" + +#: ../../po/../src/selection-chemistry.cpp:420 +#, fuzzy +msgid "Select two or more objects to group." +msgstr "Eleva-la selección ó tope" + +# [*] Revisar +#: ../../po/../src/selection-chemistry.cpp:428 +#, fuzzy +msgid "Select at least two objects to group." +msgstr "Voltea-los obxectos seleccionados" + +#: ../../po/../src/selection-chemistry.cpp:513 +#, fuzzy +msgid "Select a group to ungroup." +msgstr "Eleva-la selección ó tope" + +#: ../../po/../src/selection-chemistry.cpp:554 +msgid "No groups to ungroup in the selection." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:623 +#, fuzzy +msgid "Select objects to raise." +msgstr "Converti-los obxectos seleccionados a curvas" + +#: ../../po/../src/selection-chemistry.cpp:629 +#: ../../po/../src/selection-chemistry.cpp:681 +#: ../../po/../src/selection-chemistry.cpp:715 +#: ../../po/../src/selection-chemistry.cpp:773 +msgid "" +"You cannot raise/lower objects from different groups or layers." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:673 +#, fuzzy +msgid "Select object(s) to raise to top." +msgstr "Converti-los obxectos seleccionados a curvas" + +#: ../../po/../src/selection-chemistry.cpp:709 +#, fuzzy +msgid "Select object(s) to lower." +msgstr "Converti-los obxectos seleccionados a curvas" + +#: ../../po/../src/selection-chemistry.cpp:765 +#, fuzzy +msgid "Select object(s) to lower to bottom." +msgstr "Converti-los obxectos seleccionados a curvas" + +#: ../../po/../src/selection-chemistry.cpp:806 +msgid "Nothing to undo." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:813 +msgid "Nothing to redo." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:969 +msgid "Nothing was copied." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1051 +msgid "Current layer is hidden. Unhide it to be able to paste to it." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1055 +msgid "Current layer is locked. Unlock it to be able to paste to it." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1068 +#: ../../po/../src/selection-chemistry.cpp:1103 +#, fuzzy +msgid "Nothing on the clipboard." +msgstr "Copia-la selección ó portarretallos" + +#: ../../po/../src/selection-chemistry.cpp:1109 +#, fuzzy +msgid "Select object(s) to paste style to." +msgstr "Converti-los obxectos seleccionados a curvas" + +#: ../../po/../src/selection-chemistry.cpp:1128 +#, fuzzy +msgid "Select object(s) to move to the layer above." +msgstr "Converti-los obxectos seleccionados a curvas" + +#: ../../po/../src/selection-chemistry.cpp:1146 +#, fuzzy +msgid "No more layers above." +msgstr "Documento" + +#: ../../po/../src/selection-chemistry.cpp:1160 +#, fuzzy +msgid "Select object(s) to move to the layer below." +msgstr "Converti-los obxectos seleccionados a curvas" + +#: ../../po/../src/selection-chemistry.cpp:1178 +#, fuzzy +msgid "No more layers below." +msgstr "Documento" + +#: ../../po/../src/selection-chemistry.cpp:1811 +#, fuzzy +msgid "Select a clone to unlink." +msgstr "Seleccione o ficheiro que quere abrir" + +#: ../../po/../src/selection-chemistry.cpp:1842 +msgid "No clones to unlink in the selection." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1859 +msgid "" +"Select a clone to go to its original. Select a linked offset " +"to go to its source. Select a text on path to go to the path. Select " +"a flowed text to go to its frame." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1882 +msgid "" +"Cannot find the object to select (orphaned clone, offset, textpath, " +"flowed text?)" +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1888 +msgid "" +"The object you're trying to select is not visible (it is in <" +"defs>)" +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1915 +#, fuzzy +msgid "Select object(s) to convert to pattern." +msgstr "Converti-los obxectos seleccionados a curvas" + +#: ../../po/../src/selection-chemistry.cpp:2006 +#, fuzzy +msgid "Select an object with pattern fill to extract objects from." +msgstr "Converti-los obxectos seleccionados a curvas" + +#: ../../po/../src/selection-chemistry.cpp:2059 +#, fuzzy +msgid "No pattern fills in the selection." +msgstr "Converti-los obxectos seleccionados a curvas" + +#: ../../po/../src/selection-chemistry.cpp:2079 +#, fuzzy +msgid "Select object(s) to make a bitmap copy." +msgstr "Converti-los obxectos seleccionados a curvas" + +#: ../../po/../src/selection-describer.cpp:37 +msgid "Click selection to toggle scale/rotation handles" +msgstr "" + +#. no items +#: ../../po/../src/selection-describer.cpp:39 +msgid "" +"No objects selected. Click, Shift+click, or drag around objects to select." +msgstr "" + +#: ../../po/../src/selection-describer.cpp:51 +#, fuzzy, c-format +msgid " in layer %s" +msgstr "Pegar" + +#: ../../po/../src/selection-describer.cpp:54 +#, fuzzy, c-format +msgid " in layer %s" +msgstr "Pegar" + +#: ../../po/../src/selection-describer.cpp:66 +msgid "Use Shift+D to look up original" +msgstr "" + +#: ../../po/../src/selection-describer.cpp:70 +msgid "Use Shift+D to look up path" +msgstr "" + +#: ../../po/../src/selection-describer.cpp:74 +msgid "Use Shift+D to look up frame" +msgstr "" + +#: ../../po/../src/selection-describer.cpp:84 +#, fuzzy, c-format +msgid "%i object selected" +msgid_plural "%i objects selected" +msgstr[0] "Suaviza-la liña nos nodos seleccionados" +msgstr[1] "Suaviza-la liña nos nodos seleccionados" + +#: ../../po/../src/selection-describer.cpp:90 +#, c-format +msgid "%s%s. %s." +msgstr "" + +#: ../../po/../src/selection-describer.cpp:94 +#, fuzzy, c-format +msgid "%s in %i layer. %s." +msgid_plural "%s in %i layers. %s." +msgstr[0] "Suaviza-la liña nos nodos seleccionados" +msgstr[1] "Suaviza-la liña nos nodos seleccionados" + +#: ../../po/../src/seltrans.cpp:498 +msgid "" +"Center of rotation and skewing: drag to reposition; scaling with " +"Shift also uses this center" +msgstr "" + +#: ../../po/../src/seltrans.cpp:514 +msgid "" +"Squeeze or stretch selection; with Ctrl to scale uniformly; " +"with Shift to scale around rotation center" +msgstr "" + +#: ../../po/../src/seltrans.cpp:515 +msgid "" +"Scale selection; with Ctrl to scale uniformly; with Shift to scale around rotation center" +msgstr "" + +#: ../../po/../src/seltrans.cpp:519 +msgid "" +"Skew selection; with Ctrl to snap angle; with Shift to " +"skew around the opposite side" +msgstr "" + +#: ../../po/../src/seltrans.cpp:520 +msgid "" +"Rotate selection; with Ctrl to snap angle; with Shift " +"to rotate around the opposite corner" +msgstr "" + +#: ../../po/../src/seltrans.cpp:829 ../../po/../src/seltrans.cpp:909 +#, c-format +msgid "Scale: %0.2f%% x %0.2f%%; with Ctrl to lock ratio" +msgstr "" + +#. TRANSLATORS: don't modify the first ";" (it will NOT be displayed as ";" - only the second one will be) +#: ../../po/../src/seltrans.cpp:984 +#, c-format +msgid "Skew: %0.2f°; with Ctrl to snap angle" +msgstr "" + +#. TRANSLATORS: don't modify the first ";" (it will NOT be displayed as ";" - only the second one will be) +#: ../../po/../src/seltrans.cpp:1035 +#, c-format +msgid "Rotate: %0.2f°; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/seltrans.cpp:1090 +#, fuzzy, c-format +msgid "Move center to %s, %s" +msgstr "Mover" + +#: ../../po/../src/slideshow.cpp:90 +#, fuzzy +msgid "Inkscape slideshow" +msgstr "Sodipodi" + +#: ../../po/../src/sp-anchor.cpp:181 +#, c-format +msgid "Link to %s" +msgstr "" + +#: ../../po/../src/sp-anchor.cpp:185 +msgid "Link without URI" +msgstr "" + +#: ../../po/../src/sp-ellipse.cpp:438 ../../po/../src/sp-ellipse.cpp:870 +#, fuzzy +msgid "Ellipse" +msgstr "Elipse" + +#: ../../po/../src/sp-ellipse.cpp:583 +#, fuzzy +msgid "Circle" +msgstr "Cambiar" + +#: ../../po/../src/sp-ellipse.cpp:865 +#, fuzzy +msgid "Segment" +msgstr "Cambiar" + +#: ../../po/../src/sp-ellipse.cpp:867 +msgid "Arc" +msgstr "" + +#. TRANSLATORS: "Flow region" is an area where text is allowed to flow +#: ../../po/../src/sp-flowregion.cpp:276 +#, fuzzy +msgid "Flow region" +msgstr "liña completa" + +#. TRANSLATORS: A region "cut out of" a flow region; text is not allowed to flow inside the +#. * flow excluded region. flowRegionExclude in SVG 1.2: see +#. * http://www.w3.org/TR/2004/WD-SVG12-20041027/flow.html#flowRegion-elem and +#. * http://www.w3.org/TR/2004/WD-SVG12-20041027/flow.html#flowRegionExclude-elem. +#: ../../po/../src/sp-flowregion.cpp:493 +msgid "Flow excluded region" +msgstr "" + +#: ../../po/../src/sp-flowtext.cpp:355 +#, c-format +msgid "Flowed text (%d characters)" +msgstr "" + +#: ../../po/../src/sp-flowtext.cpp:357 +#, c-format +msgid "Linked flowed text (%d characters)" +msgstr "" + +#: ../../po/../src/sp-guide.cpp:290 +#, fuzzy +msgid "vertical guideline" +msgstr "Valor de centrado vertical" + +#: ../../po/../src/sp-guide.cpp:292 +#, fuzzy +msgid "horizontal guideline" +msgstr "movemento horizontal" + +#: ../../po/../src/sp-image.cpp:835 +msgid "embedded" +msgstr "" + +#: ../../po/../src/sp-image.cpp:839 +msgid "(null_pointer)" +msgstr "" + +#: ../../po/../src/sp-image.cpp:843 +#, fuzzy, c-format +msgid "Image with bad reference: %s" +msgstr "O elemento é de referencia" + +#: ../../po/../src/sp-image.cpp:844 +#, c-format +msgid "Image %d × %d: %s" +msgstr "" + +#: ../../po/../src/sp-item-group.cpp:390 +#, fuzzy, c-format +msgid "Group of %d object" +msgid_plural "Group of %d objects" +msgstr[0] "Grupo de %d elementos" +msgstr[1] "Grupo de %d elementos" + +#: ../../po/../src/sp-item.cpp:720 +msgid "Object" +msgstr "Obxecto" + +#: ../../po/../src/sp-line.cpp:202 +#, fuzzy +msgid "Line" +msgstr "Cambiar" + +#. TRANSLATORS COMMENT: %s is either "outset" or "inset" depending on sign +#: ../../po/../src/sp-offset.cpp:433 +#, c-format +msgid "Linked offset, %s by %f pt" +msgstr "" + +#: ../../po/../src/sp-offset.cpp:434 ../../po/../src/sp-offset.cpp:438 +#, fuzzy +msgid "outset" +msgstr "Combina-las curvas seleccionadas" + +#: ../../po/../src/sp-offset.cpp:434 ../../po/../src/sp-offset.cpp:438 +#, fuzzy +msgid "inset" +msgstr "polgada" + +#. TRANSLATORS COMMENT: %s is either "outset" or "inset" depending on sign +#: ../../po/../src/sp-offset.cpp:437 +#, c-format +msgid "Dynamic offset, %s by %f pt" +msgstr "" + +#: ../../po/../src/sp-path.cpp:127 +#, fuzzy, c-format +msgid "Path (%i node)" +msgid_plural "Path (%i nodes)" +msgstr[0] "Mover" +msgstr[1] "Mover" + +#: ../../po/../src/sp-polygon.cpp:216 +#, fuzzy +msgid "Polygon" +msgstr "Cambiar" + +#: ../../po/../src/sp-polyline.cpp:179 +#, fuzzy +msgid "Polyline" +msgstr "Elipse" + +#: ../../po/../src/sp-rect.cpp:250 +#, fuzzy +msgid "Rectangle" +msgstr "Cambiar" + +#. TRANSLATORS: since turn count isn't an integer, please adjust the +#. string as needed to deal with an localized plural forms. +#: ../../po/../src/sp-spiral.cpp:305 +#, c-format +msgid "Spiral with %3f turns" +msgstr "" + +#: ../../po/../src/sp-star.cpp:288 +#, c-format +msgid "Star with %d vertex" +msgid_plural "Star with %d vertices" +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/sp-star.cpp:292 +#, c-format +msgid "Polygon with %d vertex" +msgid_plural "Polygon with %d vertices" +msgstr[0] "" +msgstr[1] "" + +#. TRANSLATORS: For description of font with no name. +#: ../../po/../src/sp-text.cpp:420 +msgid "<no name found>" +msgstr "" + +#: ../../po/../src/sp-text.cpp:426 +#, fuzzy, c-format +msgid "Text on path (%s, %s)" +msgstr "Mover" + +#: ../../po/../src/sp-text.cpp:427 +#, fuzzy, c-format +msgid "Text (%s, %s)" +msgstr "Mover" + +#. TRANSLATORS: Used for statusbar description for long chains: +#. * "Clone of: Clone of: ... in Layer 1". +#: ../../po/../src/sp-use.cpp:317 +#, fuzzy +msgid "..." +msgstr "_Abrir" + +#: ../../po/../src/sp-use.cpp:325 +#, fuzzy, c-format +msgid "Clone of: %s" +msgstr "Cambiar" + +#: ../../po/../src/sp-use.cpp:329 +#, fuzzy +msgid "Orphaned clone" +msgstr "Cambiar" + +#: ../../po/../src/spiral-context.cpp:355 +msgid "Ctrl: snap angle" +msgstr "" + +#: ../../po/../src/spiral-context.cpp:357 +msgid "Alt: lock spiral radius" +msgstr "" + +#: ../../po/../src/spiral-context.cpp:469 +#, c-format +msgid "" +"Spiral: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" + +# [*] Revisar +#: ../../po/../src/splivarot.cpp:106 +#, fuzzy +msgid "Select at least 2 paths to perform a boolean operation." +msgstr "Voltea-los obxectos seleccionados" + +#: ../../po/../src/splivarot.cpp:112 +msgid "" +"Select exactly 2 paths to perform difference, XOR, division, or path " +"cut." +msgstr "" + +#: ../../po/../src/splivarot.cpp:129 ../../po/../src/splivarot.cpp:144 +msgid "" +"Unable to determine the z-order of the objects selected for " +"difference, XOR, division, or path cut." +msgstr "" + +#: ../../po/../src/splivarot.cpp:174 +#, fuzzy +msgid "" +"One of the objects is not a path, cannot perform boolean operation." +msgstr "Converti-los obxectos seleccionados a curvas" + +#. TRANSLATORS: "to outline" means "to convert stroke to path" +#: ../../po/../src/splivarot.cpp:554 +#, fuzzy +msgid "Select path(s) to outline." +msgstr "Converti-los obxectos seleccionados a curvas" + +#. TRANSLATORS: "to outline" means "to convert stroke to path" +#: ../../po/../src/splivarot.cpp:748 +msgid "No stroked paths to outline in the selection." +msgstr "" + +#: ../../po/../src/splivarot.cpp:832 +#, fuzzy +msgid "Selected object is not a path, cannot inset/outset." +msgstr "Converti-los obxectos seleccionados a curvas" + +#: ../../po/../src/splivarot.cpp:1040 +#, fuzzy +msgid "Select path(s) to inset/outset." +msgstr "Converti-los obxectos seleccionados a curvas" + +#: ../../po/../src/splivarot.cpp:1257 +msgid "No paths to inset/outset in the selection." +msgstr "" + +#: ../../po/../src/splivarot.cpp:1390 +#, fuzzy +msgid "Select path(s) to simplify." +msgstr "Converti-los obxectos seleccionados a curvas" + +#: ../../po/../src/splivarot.cpp:1417 +msgid "No paths to simplify in the selection." +msgstr "" + +#: ../../po/../src/star-context.cpp:362 +msgid "Ctrl: snap angle; keep rays radial" +msgstr "" + +#: ../../po/../src/star-context.cpp:470 +#, c-format +msgid "" +"Polygon: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/star-context.cpp:471 +#, c-format +msgid "Star: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" + +# [*] Revisar +#: ../../po/../src/text-chemistry.cpp:90 +#, fuzzy +msgid "Select a text and a path to put text on path." +msgstr "Voltea-los obxectos seleccionados" + +#: ../../po/../src/text-chemistry.cpp:95 +msgid "" +"This text object is already put to a path. Remove it from the path " +"first. Use Shift+D to look up its path." +msgstr "" + +#. rect is the only SPShape which is not yet, and thus SVG forbids us from putting text on it +#: ../../po/../src/text-chemistry.cpp:101 +msgid "" +"You cannot put text on a rectangle in this version. Convert rectangle to " +"path first." +msgstr "" + +# [*] Revisar +#: ../../po/../src/text-chemistry.cpp:159 +#, fuzzy +msgid "Select a text on path to remove it from path." +msgstr "Voltea-los obxectos seleccionados" + +#: ../../po/../src/text-chemistry.cpp:181 +#, fuzzy +msgid "No texts-on-paths in the selection." +msgstr "Converti-los obxectos seleccionados a curvas" + +#: ../../po/../src/text-chemistry.cpp:209 +#: ../../po/../src/text-chemistry.cpp:229 +#, fuzzy +msgid "Select text(s) to remove kerns from." +msgstr "Eleva-la selección ó tope" + +# [*] Revisar +#: ../../po/../src/text-chemistry.cpp:250 +#, fuzzy +msgid "" +"Select a text and one or more paths or shapes to flow text " +"into frame." +msgstr "Voltea-los obxectos seleccionados" + +#: ../../po/../src/text-chemistry.cpp:322 +#, fuzzy +msgid "Select a flowed text to unflow it." +msgstr "Converti-los obxectos seleccionados a curvas" + +#: ../../po/../src/text-context.cpp:463 +msgid "Click to edit the text, drag to select part of the text." +msgstr "" + +#: ../../po/../src/text-context.cpp:465 +msgid "" +"Click to edit the flowed text, drag to select part of the text." +msgstr "" + +#: ../../po/../src/text-context.cpp:540 +msgid "Non-printable character" +msgstr "" + +#: ../../po/../src/text-context.cpp:589 +#, c-format +msgid "Unicode: %s: %s" +msgstr "" + +#: ../../po/../src/text-context.cpp:591 ../../po/../src/text-context.cpp:855 +msgid "Unicode: " +msgstr "" + +#: ../../po/../src/text-context.cpp:615 +msgid "Current layer is hidden. Unhide it to be able to add text." +msgstr "" + +#: ../../po/../src/text-context.cpp:619 +msgid "Current layer is locked. Unlock it to be able to add text." +msgstr "" + +#: ../../po/../src/text-context.cpp:673 +#, c-format +msgid "Flowed text frame: %s × %s" +msgstr "" + +#: ../../po/../src/text-context.cpp:708 ../../po/../src/text-context.cpp:1464 +msgid "Type text; Enter to start new line." +msgstr "" + +#: ../../po/../src/text-context.cpp:719 +msgid "Flowed text is created." +msgstr "" + +#: ../../po/../src/text-context.cpp:722 +msgid "" +"The frame is too small for the current font size. Flowed text not " +"created." +msgstr "" + +#: ../../po/../src/text-context.cpp:841 +msgid "No-break space" +msgstr "" + +#: ../../po/../src/text-context.cpp:1462 +msgid "Type flowed text; Enter to start new paragraph." +msgstr "" + +#: ../../po/../src/text-context.cpp:1472 ../../po/../src/tools-switch.cpp:189 +msgid "" +"Click to select or create text, drag to create flowed text; " +"then type." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:141 +msgid "" +"To edit a path, click, Shift+click, or drag around " +"nodes to select them, then drag nodes and handles. Click on an " +"object to select." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:147 +msgid "" +"Drag to create a rectangle. Drag controls to round corners and " +"resize. Click to select." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:153 +msgid "" +"Drag to create an ellipse. Drag controls to make an arc or " +"segment. Click to select." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:159 +msgid "" +"Drag to create a star. Drag controls to edit the star shape. " +"Click to select." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:165 +msgid "" +"Drag to create a spiral. Drag controls to edit the spiral " +"shape. Click to select." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:171 +msgid "" +"Drag to create a freehand line. Start drawing with Shift to " +"append to selected path." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:177 +msgid "" +"Click or click and drag to start a path; with Shift to " +"append to selected path." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:183 +msgid "" +"Drag to paint a calligraphic stroke. Left/right arrow " +"keys adjust width, up/down adjust angle." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:195 +msgid "" +"Drag or double click to create a gradient on selected objects, " +"drag handles to adjust gradients." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:201 +msgid "" +"Click or drag around an area to zoom in, Shift+click to " +"zoom out." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:213 +msgid "Click and drag between shapes to create a connector." +msgstr "" + +#: ../../po/../src/trace/potrace/inkscape-potrace.cpp:553 +#: ../../po/../src/trace/potrace/inkscape-potrace.cpp:654 +#, c-format +msgid "Trace: %d. %ld nodes" +msgstr "" + +#: ../../po/../src/trace/trace.cpp:53 ../../po/../src/trace/trace.cpp:62 +#: ../../po/../src/trace/trace.cpp:70 +#, fuzzy +msgid "Select an image to trace" +msgstr "Converti-los obxectos seleccionados a curvas" + +#: ../../po/../src/trace/trace.cpp:133 +#, fuzzy +msgid "Trace: No active document" +msgstr "Documento" + +#: ../../po/../src/trace/trace.cpp:154 +msgid "Trace: Image has no bitmap data" +msgstr "" + +#: ../../po/../src/trace/trace.cpp:267 +#, fuzzy, c-format +msgid "Trace: Done. %ld nodes created" +msgstr "Último seleccionado" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:59 ../../po/../src/verbs.cpp:2212 +msgid "About Inkscape" +msgstr "" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:66 +msgid "_Splash" +msgstr "" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:68 +msgid "_Authors" +msgstr "" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:69 +#, fuzzy +msgid "_Translators" +msgstr "Transformación" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:70 +#, fuzzy +msgid "_License" +msgstr "polgada" + +#. TRANSLATORS: This is the filename of the `About Inkscape' picture in +#. the `screens' directory. Thus the translation of "about.svg" should be +#. the filename of its translated version, e.g. about.zh.svg for Chinese. +#. +#. N.B. about.svg changes once per release. (We should probably rename +#. the original to about-0.40.svg etc. as soon as we have a translation. +#. If we do so, then add an item to release-checklist saying that the +#. string here should be changed.) +#. FIXME? INKSCAPE_SCREENSDIR and "about.svg" are in UTF-8, not the +#. native filename encoding... and the filename passed to sp_document_new +#. should be in UTF-*8.. +#: ../../po/../src/ui/dialog/aboutbox.cpp:114 +msgid "about.svg" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:464 +msgid "Minimum horizontal gap (in px units) between bounding boxes" +msgstr "" + +#. TRANSLATORS: Horizontal gap +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:466 +#: ../../po/../src/widgets/toolbox.cpp:1556 +msgid "H:" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:474 +msgid "Minimum vertical gap (in px units) between bounding boxes" +msgstr "" + +#. TRANSLATORS: Vertical gap +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:476 +msgid "V:" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:734 +msgid "Align" +msgstr "Aliñar" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:735 +#, fuzzy +msgid "Distribute" +msgstr "Atributos" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:736 +msgid "Remove overlaps" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:737 +msgid "Nodes" +msgstr "Nodos" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:742 +#, fuzzy +msgid "Relative to: " +msgstr "movemento vertical" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:747 +#, fuzzy +msgid "Align right sides of objects to left side of anchor" +msgstr "Aliña-lo interior do obxecto á beira esquerda" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:750 +#, fuzzy +msgid "Align left sides" +msgstr "Aliñar á esquerda ó medio" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:753 +#, fuzzy +msgid "Center on vertical axis" +msgstr "voltear vertical" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:756 +#, fuzzy +msgid "Align right sides" +msgstr "Aliñar á dereita ó medio" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:759 +#, fuzzy +msgid "Align left sides of objects to right side of anchor" +msgstr "Aliña-lo interior do obxecto á beira dereita" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:762 +#, fuzzy +msgid "Align bottoms of objects to top of anchor" +msgstr "Aliña-lo interior do obxecto á beira inferior" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:765 +#, fuzzy +msgid "Align tops" +msgstr "Obxecto" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:768 +#, fuzzy +msgid "Center on horizontal axis" +msgstr "voltear horizontal" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:771 +#, fuzzy +msgid "Align bottoms" +msgstr "Aliñar abaixo á esquerda" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:774 +#, fuzzy +msgid "Align tops of objects to bottom of anchor" +msgstr "Aliña-lo interior do obxecto á beira superior" + +# [*] Revisar +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:779 +#, fuzzy +msgid "Align baseline anchors of texts vertically" +msgstr "Voltea-los obxectos seleccionados" + +# [*] Revisar +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:782 +#, fuzzy +msgid "Align baseline anchors of texts horizontally" +msgstr "Voltea-los obxectos seleccionados" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:787 +msgid "Make horizontal gaps between objects equal" +msgstr "" + +# [*] Revisar +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:791 +#, fuzzy +msgid "Distribute left sides equidistantly" +msgstr "Voltea-los obxectos seleccionados" + +# [*] Revisar +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:794 +#, fuzzy +msgid "Distribute centers equidistantly horizontally" +msgstr "Voltea-los obxectos seleccionados" + +# [*] Revisar +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:797 +#, fuzzy +msgid "Distribute right sides equidistantly" +msgstr "Voltea-los obxectos seleccionados" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:801 +msgid "Make vertical gaps between objects equal" +msgstr "" + +# [*] Revisar +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:805 +#, fuzzy +msgid "Distribute tops equidistantly" +msgstr "Voltea-los obxectos seleccionados" + +# [*] Revisar +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:808 +#, fuzzy +msgid "Distribute centers equidistantly vertically" +msgstr "Voltea-los obxectos seleccionados" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:811 +msgid "Distribute bottoms equidistantly" +msgstr "" + +# [*] Revisar +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:816 +#, fuzzy +msgid "Distribute baseline anchors of texts horizontally" +msgstr "Voltea-los obxectos seleccionados" + +# [*] Revisar +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:819 +#, fuzzy +msgid "Distribute baseline anchors of texts vertically" +msgstr "Voltea-los obxectos seleccionados" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:824 +msgid "Randomize centers in both dimensions" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:827 +msgid "Unclump objects: try to equalize edge-to-edge distances" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:832 +msgid "" +"Move objects as little as possible so that their bounding boxes do not " +"overlap" +msgstr "" + +# [*] Revisar +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:837 +#, fuzzy +msgid "Align selected nodes horizontally" +msgstr "Voltea-los obxectos seleccionados" + +# [*] Revisar +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:840 +#, fuzzy +msgid "Align selected nodes vertically" +msgstr "Voltea-los obxectos seleccionados" + +# [*] Revisar +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:843 +#, fuzzy +msgid "Distribute selected nodes horizontally" +msgstr "Voltea-los obxectos seleccionados" + +# [*] Revisar +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:846 +#, fuzzy +msgid "Distribute selected nodes vertically" +msgstr "Voltea-los obxectos seleccionados" + +#. Rest of the widgetry +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:851 +msgid "Last selected" +msgstr "Último seleccionado" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:852 +msgid "First selected" +msgstr "Primeiro seleccionado" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:853 +msgid "Biggest item" +msgstr "Elemento meirande" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:854 +msgid "Smallest item" +msgstr "Elemento menor" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:856 +#: ../../po/../src/widgets/desktop-widget.cpp:1065 +msgid "Drawing" +msgstr "Debuxando" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:91 +msgid "Metadata 1" +msgstr "" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:92 +msgid "Metadata 2" +msgstr "" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:187 +#, fuzzy +msgid "X coordinate of grid origin" +msgstr "Escolle-las cores para as liñas guía" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:189 +#, fuzzy +msgid "Y coordinate of grid origin" +msgstr "Escolle-las cores para as liñas guía" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:191 +#, fuzzy +msgid "Distance of vertical grid lines" +msgstr "Configura-la distancia entre liñas verticais da reixa" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:193 +#, fuzzy +msgid "Distance of horizontal grid lines" +msgstr "Configura-la distancia entre liñas horizontais da reixa" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:197 +msgid "Max. snapping distance from grid" +msgstr "" + +#: ../../po/../src/ui/dialog/export.cpp:34 +msgid "Export" +msgstr "Exportar" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:36 +msgid "Fill" +msgstr "Reencher" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:37 +#, fuzzy +msgid "Stroke Paint" +msgstr "Ancho do trazado" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:38 +#, fuzzy +msgid "Stroke Style" +msgstr "Configuración do escritorio" + +#: ../../po/../src/ui/dialog/find.cpp:34 +#, fuzzy +msgid "Find" +msgstr "Reixa" + +#: ../../po/../src/ui/dialog/memory.cpp:96 +#, fuzzy +msgid "Heap" +msgstr "_Axuda" + +#: ../../po/../src/ui/dialog/memory.cpp:97 +#, fuzzy +msgid "In Use" +msgstr "polgada" + +#. TRANSLATORS: "Slack" refers to memory which is in the heap but currently unused. +#. More typical usage is to call this memory "free" rather than "slack". +#: ../../po/../src/ui/dialog/memory.cpp:100 +#, fuzzy +msgid "Slack" +msgstr "Trazo" + +#: ../../po/../src/ui/dialog/memory.cpp:101 +#, fuzzy +msgid "Total" +msgstr "Ficheiro" + +#: ../../po/../src/ui/dialog/memory.cpp:141 +#: ../../po/../src/ui/dialog/memory.cpp:147 +#: ../../po/../src/ui/dialog/memory.cpp:154 +#: ../../po/../src/ui/dialog/memory.cpp:186 +#, fuzzy +msgid "Unknown" +msgstr "Elemento descoñecido :-(" + +#: ../../po/../src/ui/dialog/memory.cpp:167 +#, fuzzy +msgid "Combined" +msgstr "_Combinar" + +#: ../../po/../src/ui/dialog/memory.cpp:209 +#, fuzzy +msgid "Recalculate" +msgstr "Rectángulo" + +#: ../../po/../src/ui/dialog/messages.cpp:74 +#, fuzzy +msgid "Ready." +msgstr "Vermello:" + +#: ../../po/../src/ui/dialog/messages.cpp:75 +msgid "" +"Enable log display by setting dialogs.debug 'redirect' attribute to 1 in " +"preferences.xml" +msgstr "" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:184 +msgid "_Execute Python" +msgstr "" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:186 +msgid "_Execute Perl" +msgstr "" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:195 +msgid "Script" +msgstr "" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:205 +#, fuzzy +msgid "Output" +msgstr "Cortar" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:215 +msgid "Errors" +msgstr "" + +#. Dialog organization +#: ../../po/../src/ui/dialog/session-player.cpp:73 +#, fuzzy +msgid "Session file" +msgstr "Garda-lo ficheiro" + +#: ../../po/../src/ui/dialog/session-player.cpp:74 +#, fuzzy +msgid "Playback controls" +msgstr "Opcións de Oaf" + +#: ../../po/../src/ui/dialog/session-player.cpp:75 +#, fuzzy +msgid "Message information" +msgstr "Reinicia-la transformación" + +#. Active session file display +#. fixme: Does this mean the active file for the session, or the file for the active session? +#. Please indicate which with a TRANSLATORS comment. +#: ../../po/../src/ui/dialog/session-player.cpp:85 +msgid "Active session file:" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:86 +msgid "Delay (milliseconds):" +msgstr "" + +#. Unload/load buttons +#: ../../po/../src/ui/dialog/session-player.cpp:94 +#, fuzzy +msgid "Close file" +msgstr "Cor do recheo" + +#: ../../po/../src/ui/dialog/session-player.cpp:95 +#, fuzzy +msgid "Open new file" +msgstr "Abrir novo debuxo" + +#: ../../po/../src/ui/dialog/session-player.cpp:96 +#, fuzzy +msgid "Set delay" +msgstr "Borrar atributo" + +#: ../../po/../src/ui/dialog/session-player.cpp:138 +#, fuzzy +msgid "Rewind" +msgstr "Vermello:" + +#: ../../po/../src/ui/dialog/session-player.cpp:139 +msgid "Go back one change" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:140 +#, fuzzy +msgid "Pause" +msgstr "Pegar" + +#: ../../po/../src/ui/dialog/session-player.cpp:141 +msgid "Go forward one change" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:142 +msgid "Play" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:177 +#: ../../po/../src/verbs.cpp:1573 +msgid "Open session file" +msgstr "" + +#. ##Set up the Potrace panel +#. #### brightness #### +#. #### Multiple scanning#### +#. ----Hbox1 +#: ../../po/../src/ui/dialog/tracedialog.cpp:345 +#: ../../po/../src/ui/dialog/tracedialog.cpp:428 +#, fuzzy +msgid "Brightness" +msgstr "Alto" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:348 +msgid "Trace by a given brightness level" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:355 +msgid "Brightness cutoff for black/white" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:362 +#, fuzzy +msgid "Image Brightness" +msgstr "Tamaño da imaxe" + +#. #### canny edge detection #### +#. TRANSLATORS: "Canny" is the name of the inventor of this edge detection method +#: ../../po/../src/ui/dialog/tracedialog.cpp:369 +msgid "Optimal Edge Detection (Canny)" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:372 +msgid "Trace with edge detection by J. Canny's algorithm" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:388 +msgid "Brightness cutoff for adjacent pixels (determines edge thickness)" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:395 +#, fuzzy +msgid "Edge Detection" +msgstr "Selección" + +#. #### quantization #### +#. TRANSLATORS: Color Quantization: the process of reducing the number of colors +#. in an image by selecting an optimized set of representative colors and then +#. re-applying this reduced set to the original image. +#: ../../po/../src/ui/dialog/tracedialog.cpp:404 +#, fuzzy +msgid "Color Quantization" +msgstr "Bitmap a cor" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:407 +msgid "Trace along the boundaries of reduced colors" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:414 +msgid "The number of reduced colors" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:416 +#, fuzzy +msgid "Colors:" +msgstr "Cor" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:421 +msgid "Quantization / Reduction" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:431 +msgid "Trace the given number of brightness levels" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:438 +#, fuzzy +msgid "Scans:" +msgstr "Peza" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:440 +msgid "The desired number of scans" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:448 +msgid "Trace the given number of reduced colors" +msgstr "" + +#. ---Hbox3 +#: ../../po/../src/ui/dialog/tracedialog.cpp:454 +msgid "Monochrome" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:457 +msgid "Same as Color, but convert result to grayscale" +msgstr "" + +#. TRANSLATORS: "Stack" is a verb here +#: ../../po/../src/ui/dialog/tracedialog.cpp:460 +#, fuzzy +msgid "Stack" +msgstr "Trazo" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:463 +msgid "" +"Stack scans vertically (no gaps) or tile horizontally (usually with gaps)" +msgstr "" + +#. TRANSLATORS: "Smooth" is a verb here +#: ../../po/../src/ui/dialog/tracedialog.cpp:466 +msgid "Smooth" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:469 +msgid "Apply Gaussian blur to the bitmap before tracing" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:473 +msgid "Multiple Scanning" +msgstr "" + +#. #### Preview #### +#: ../../po/../src/ui/dialog/tracedialog.cpp:479 +#: ../../po/../src/ui/dialog/tracedialog.cpp:489 +#, fuzzy +msgid "Preview" +msgstr "Nova vista" + +#. do not expand +#: ../../po/../src/ui/dialog/tracedialog.cpp:483 +msgid "Preview the result without actual tracing" +msgstr "" + +#. #### swap black and white #### +#: ../../po/../src/ui/dialog/tracedialog.cpp:495 +msgid "Invert" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:499 +msgid "Invert black and white regions for single traces" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:503 +msgid "Thanks to Peter Selinger, http://potrace.sourceforge.net" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:506 +#, fuzzy +msgid "Credits" +msgstr "Bitmap a cor" + +#. done +#. TRANSLATORS: Potrace is an application for transforming bitmaps into +#. vector graphics (http://potrace.sourceforge.net/) +#: ../../po/../src/ui/dialog/tracedialog.cpp:514 +#, fuzzy +msgid "Potrace" +msgstr "Punto" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:527 +#, fuzzy +msgid "Abort a trace in progress" +msgstr "Exportar como" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:531 +msgid "Execute the trace" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:80 +#: ../../po/../src/ui/dialog/transformation.cpp:90 +#, fuzzy +msgid "_Horizontal" +msgstr "movemento horizontal" + +#: ../../po/../src/ui/dialog/transformation.cpp:80 +msgid "Horizontal displacement (relative) or position (absolute)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:82 +#: ../../po/../src/ui/dialog/transformation.cpp:92 +#, fuzzy +msgid "_Vertical" +msgstr "Valor de centrado vertical" + +#: ../../po/../src/ui/dialog/transformation.cpp:82 +msgid "Vertical displacement (relative) or position (absolute)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:84 +#, fuzzy +msgid "_Width" +msgstr "Ancho:" + +#: ../../po/../src/ui/dialog/transformation.cpp:84 +msgid "Horizontal size increment (absolute or percentage)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:86 +#, fuzzy +msgid "_Height" +msgstr "Alto:" + +#: ../../po/../src/ui/dialog/transformation.cpp:86 +msgid "Vertical size increment (absolute or percentage)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:88 +#, fuzzy +msgid "A_ngle" +msgstr "ángulo" + +#: ../../po/../src/ui/dialog/transformation.cpp:88 +#, fuzzy +msgid "Rotation angle (positive = counterclockwise)" +msgstr "Rota-los obxectos seleccionados 90° en sentido horario" + +#: ../../po/../src/ui/dialog/transformation.cpp:90 +msgid "" +"Horizontal skew angle (positive = counterclockwise), or absolute " +"displacement, or percentage displacement" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:92 +msgid "" +"Vertical skew angle (positive = counterclockwise), or absolute displacement, " +"or percentage displacement" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:95 +#, fuzzy +msgid "Transformation matrix element A" +msgstr "Transformación" + +#: ../../po/../src/ui/dialog/transformation.cpp:96 +#, fuzzy +msgid "Transformation matrix element B" +msgstr "Transformación" + +#: ../../po/../src/ui/dialog/transformation.cpp:97 +#, fuzzy +msgid "Transformation matrix element C" +msgstr "Transformación" + +#: ../../po/../src/ui/dialog/transformation.cpp:98 +#, fuzzy +msgid "Transformation matrix element D" +msgstr "Transformación" + +#: ../../po/../src/ui/dialog/transformation.cpp:99 +#, fuzzy +msgid "Transformation matrix element E" +msgstr "Transformación" + +#: ../../po/../src/ui/dialog/transformation.cpp:100 +#, fuzzy +msgid "Transformation matrix element F" +msgstr "Transformación" + +#: ../../po/../src/ui/dialog/transformation.cpp:102 +#, fuzzy +msgid "Rela_tive move" +msgstr "movemento vertical" + +#: ../../po/../src/ui/dialog/transformation.cpp:102 +msgid "" +"Add the specified relative displacement to the current position; otherwise, " +"edit the current absolute position directly" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:103 +msgid "Scale proportionally" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:103 +msgid "Preserve the width/height ratio of the scaled objects" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:104 +msgid "Apply to each _object separately" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:104 +msgid "" +"Apply the scale/rotate/skew to each selected object separately; otherwise, " +"transform the selection as a whole" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:105 +msgid "Edit c_urrent matrix" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:105 +msgid "" +"Edit the current transform= matrix; otherwise, post-multiply transform= by " +"this matrix" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:115 +#, fuzzy +msgid "_Move" +msgstr "Mover" + +#: ../../po/../src/ui/dialog/transformation.cpp:118 +#, fuzzy +msgid "_Scale" +msgstr "Escala" + +#: ../../po/../src/ui/dialog/transformation.cpp:121 +#, fuzzy +msgid "_Rotate" +msgstr "Rotar" + +#: ../../po/../src/ui/dialog/transformation.cpp:124 +#, fuzzy +msgid "Ske_w" +msgstr "Inclinar" + +#: ../../po/../src/ui/dialog/transformation.cpp:127 +msgid "Matri_x" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:141 +#, fuzzy +msgid "Reset the values on the current tab to defaults" +msgstr "Reinicia-lo formulario ós valores por defecto - Ctrl+r" + +#: ../../po/../src/ui/dialog/transformation.cpp:148 +#, fuzzy +msgid "Apply transformation to selection" +msgstr "Aplica-la transformación á copia - Ctrl+m" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:43 +msgid "_Use SSL" +msgstr "" + +#. Construct dialog interface +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:68 +#, fuzzy +msgid "_Server:" +msgstr "Ficheiro" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:69 +#, fuzzy +msgid "_Username:" +msgstr "Nome do ficheiro:" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:70 +msgid "_Password:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:71 +msgid "P_ort:" +msgstr "" + +#. Buttons +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:99 +#, fuzzy +msgid "Connect" +msgstr "Contido" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:126 +msgid "Establishing connection to Jabber server %1 as user %2" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:131 +msgid "Failed to establish connection to Jabber server %1" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:136 +msgid "Authentication failed on Jabber server %1 as %2" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:141 +msgid "SSL initialization failed when connecting to Jabber server %1" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:147 +msgid "Connected to Jabber server %1 as %2" +msgstr "" + +#. Construct labels +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:75 +msgid "Chatroom _name:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:76 +msgid "Chatroom _server:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:77 +msgid "Chatroom _password:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:78 +msgid "Chatroom _handle:" +msgstr "" + +#. Button setup and callback registration +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:97 +msgid "Connect to chatroom" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:132 +msgid "Synchronizing with chatroom %1@%2 using the handle %3" +msgstr "" + +#. Construct dialog interface +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:78 +msgid "_User's Jabber ID:" +msgstr "" + +#. Buttons +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:82 +msgid "_Invite user" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:83 +#, fuzzy +msgid "_Cancel" +msgstr "Cambiar" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:94 +msgid "Buddy List" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:170 +msgid "Sending whiteboard invitation to %1" +msgstr "" + +#. FIXME: strings are replaced by placeholders, NOT to be translated until the code is enabled +#. See http://sourceforge.net/mailarchive/message.php?msg_id=11746016 for details +#. File menu +#. Edit menu +#. View menu +#. Layer menu +#. Object menu +#. Path menu +#. add(Gtk::StockItem(CLEANUP, _("PLACEHOLDER, do not translate"))); (using Gtk::Stock::CLEAR) +#. Text menu +#. About menu +#. Tools toolbox +#. Select Tool controls +#. Node Tool controls +#. Calligraphy Tool controls +#. Session playback controls +#: ../../po/../src/ui/stock-items.cpp:34 ../../po/../src/ui/stock-items.cpp:35 +#: ../../po/../src/ui/stock-items.cpp:36 ../../po/../src/ui/stock-items.cpp:37 +#: ../../po/../src/ui/stock-items.cpp:38 ../../po/../src/ui/stock-items.cpp:39 +#: ../../po/../src/ui/stock-items.cpp:40 ../../po/../src/ui/stock-items.cpp:41 +#: ../../po/../src/ui/stock-items.cpp:42 ../../po/../src/ui/stock-items.cpp:43 +#: ../../po/../src/ui/stock-items.cpp:46 ../../po/../src/ui/stock-items.cpp:47 +#: ../../po/../src/ui/stock-items.cpp:48 ../../po/../src/ui/stock-items.cpp:49 +#: ../../po/../src/ui/stock-items.cpp:50 ../../po/../src/ui/stock-items.cpp:51 +#: ../../po/../src/ui/stock-items.cpp:52 ../../po/../src/ui/stock-items.cpp:53 +#: ../../po/../src/ui/stock-items.cpp:54 ../../po/../src/ui/stock-items.cpp:55 +#: ../../po/../src/ui/stock-items.cpp:56 ../../po/../src/ui/stock-items.cpp:57 +#: ../../po/../src/ui/stock-items.cpp:58 ../../po/../src/ui/stock-items.cpp:59 +#: ../../po/../src/ui/stock-items.cpp:62 ../../po/../src/ui/stock-items.cpp:63 +#: ../../po/../src/ui/stock-items.cpp:64 ../../po/../src/ui/stock-items.cpp:65 +#: ../../po/../src/ui/stock-items.cpp:66 ../../po/../src/ui/stock-items.cpp:67 +#: ../../po/../src/ui/stock-items.cpp:68 ../../po/../src/ui/stock-items.cpp:69 +#: ../../po/../src/ui/stock-items.cpp:70 ../../po/../src/ui/stock-items.cpp:71 +#: ../../po/../src/ui/stock-items.cpp:72 ../../po/../src/ui/stock-items.cpp:73 +#: ../../po/../src/ui/stock-items.cpp:74 ../../po/../src/ui/stock-items.cpp:75 +#: ../../po/../src/ui/stock-items.cpp:76 ../../po/../src/ui/stock-items.cpp:77 +#: ../../po/../src/ui/stock-items.cpp:78 ../../po/../src/ui/stock-items.cpp:79 +#: ../../po/../src/ui/stock-items.cpp:80 ../../po/../src/ui/stock-items.cpp:81 +#: ../../po/../src/ui/stock-items.cpp:82 ../../po/../src/ui/stock-items.cpp:83 +#: ../../po/../src/ui/stock-items.cpp:84 ../../po/../src/ui/stock-items.cpp:85 +#: ../../po/../src/ui/stock-items.cpp:86 ../../po/../src/ui/stock-items.cpp:87 +#: ../../po/../src/ui/stock-items.cpp:88 ../../po/../src/ui/stock-items.cpp:89 +#: ../../po/../src/ui/stock-items.cpp:92 ../../po/../src/ui/stock-items.cpp:93 +#: ../../po/../src/ui/stock-items.cpp:94 ../../po/../src/ui/stock-items.cpp:95 +#: ../../po/../src/ui/stock-items.cpp:96 ../../po/../src/ui/stock-items.cpp:97 +#: ../../po/../src/ui/stock-items.cpp:98 ../../po/../src/ui/stock-items.cpp:99 +#: ../../po/../src/ui/stock-items.cpp:100 +#: ../../po/../src/ui/stock-items.cpp:101 +#: ../../po/../src/ui/stock-items.cpp:102 +#: ../../po/../src/ui/stock-items.cpp:103 +#: ../../po/../src/ui/stock-items.cpp:104 +#: ../../po/../src/ui/stock-items.cpp:105 +#: ../../po/../src/ui/stock-items.cpp:108 +#: ../../po/../src/ui/stock-items.cpp:109 +#: ../../po/../src/ui/stock-items.cpp:110 +#: ../../po/../src/ui/stock-items.cpp:111 +#: ../../po/../src/ui/stock-items.cpp:112 +#: ../../po/../src/ui/stock-items.cpp:113 +#: ../../po/../src/ui/stock-items.cpp:114 +#: ../../po/../src/ui/stock-items.cpp:115 +#: ../../po/../src/ui/stock-items.cpp:116 +#: ../../po/../src/ui/stock-items.cpp:117 +#: ../../po/../src/ui/stock-items.cpp:118 +#: ../../po/../src/ui/stock-items.cpp:119 +#: ../../po/../src/ui/stock-items.cpp:120 +#: ../../po/../src/ui/stock-items.cpp:121 +#: ../../po/../src/ui/stock-items.cpp:122 +#: ../../po/../src/ui/stock-items.cpp:123 +#: ../../po/../src/ui/stock-items.cpp:124 +#: ../../po/../src/ui/stock-items.cpp:125 +#: ../../po/../src/ui/stock-items.cpp:126 +#: ../../po/../src/ui/stock-items.cpp:127 +#: ../../po/../src/ui/stock-items.cpp:130 +#: ../../po/../src/ui/stock-items.cpp:131 +#: ../../po/../src/ui/stock-items.cpp:132 +#: ../../po/../src/ui/stock-items.cpp:133 +#: ../../po/../src/ui/stock-items.cpp:134 +#: ../../po/../src/ui/stock-items.cpp:135 +#: ../../po/../src/ui/stock-items.cpp:136 +#: ../../po/../src/ui/stock-items.cpp:137 +#: ../../po/../src/ui/stock-items.cpp:138 +#: ../../po/../src/ui/stock-items.cpp:139 +#: ../../po/../src/ui/stock-items.cpp:140 +#: ../../po/../src/ui/stock-items.cpp:141 +#: ../../po/../src/ui/stock-items.cpp:142 +#: ../../po/../src/ui/stock-items.cpp:143 +#: ../../po/../src/ui/stock-items.cpp:144 +#: ../../po/../src/ui/stock-items.cpp:145 +#: ../../po/../src/ui/stock-items.cpp:146 +#: ../../po/../src/ui/stock-items.cpp:150 +#: ../../po/../src/ui/stock-items.cpp:151 +#: ../../po/../src/ui/stock-items.cpp:152 +#: ../../po/../src/ui/stock-items.cpp:153 +#: ../../po/../src/ui/stock-items.cpp:156 +#: ../../po/../src/ui/stock-items.cpp:157 +#: ../../po/../src/ui/stock-items.cpp:158 +#: ../../po/../src/ui/stock-items.cpp:161 +#: ../../po/../src/ui/stock-items.cpp:162 +#: ../../po/../src/ui/stock-items.cpp:163 +#: ../../po/../src/ui/stock-items.cpp:164 +#: ../../po/../src/ui/stock-items.cpp:165 +#: ../../po/../src/ui/stock-items.cpp:166 +#: ../../po/../src/ui/stock-items.cpp:167 +#: ../../po/../src/ui/stock-items.cpp:168 +#: ../../po/../src/ui/stock-items.cpp:169 +#: ../../po/../src/ui/stock-items.cpp:170 +#: ../../po/../src/ui/stock-items.cpp:171 +#: ../../po/../src/ui/stock-items.cpp:172 +#: ../../po/../src/ui/stock-items.cpp:175 +#: ../../po/../src/ui/stock-items.cpp:176 +#: ../../po/../src/ui/stock-items.cpp:177 +#: ../../po/../src/ui/stock-items.cpp:178 +#: ../../po/../src/ui/stock-items.cpp:181 +#: ../../po/../src/ui/stock-items.cpp:182 +#: ../../po/../src/ui/stock-items.cpp:183 +#: ../../po/../src/ui/stock-items.cpp:184 +#: ../../po/../src/ui/stock-items.cpp:185 +#: ../../po/../src/ui/stock-items.cpp:186 +#: ../../po/../src/ui/stock-items.cpp:187 +#: ../../po/../src/ui/stock-items.cpp:188 +#: ../../po/../src/ui/stock-items.cpp:189 +#: ../../po/../src/ui/stock-items.cpp:190 +#: ../../po/../src/ui/stock-items.cpp:191 +#: ../../po/../src/ui/stock-items.cpp:194 +#: ../../po/../src/ui/stock-items.cpp:195 +#: ../../po/../src/ui/stock-items.cpp:198 +#: ../../po/../src/ui/stock-items.cpp:199 +#: ../../po/../src/ui/stock-items.cpp:200 +#: ../../po/../src/ui/stock-items.cpp:201 +#: ../../po/../src/ui/stock-items.cpp:202 +msgid "PLACEHOLDER, do not translate" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:88 +msgid "small" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:89 +msgid "medium" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:90 +#, fuzzy +msgid "large" +msgstr "Páxina" + +#: ../../po/../src/ui/widget/panel.cpp:91 +msgid "huge" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:106 +#, fuzzy +msgid "List" +msgstr "polgada" + +#: ../../po/../src/ui/widget/selected-style.cpp:67 +msgid "F:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:68 +msgid "S:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:69 +msgid "O:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:95 +msgid "N/A" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:98 +#: ../../po/../src/ui/widget/selected-style.cpp:712 +#, fuzzy +msgid "Nothing selected" +msgstr "Borra-los nodos seleccionados" + +#: ../../po/../src/ui/widget/selected-style.cpp:103 +msgid "No fill" +msgstr "Sen recheo" + +#: ../../po/../src/ui/widget/selected-style.cpp:103 +#, fuzzy +msgid "No stroke" +msgstr "Está trazado" + +#: ../../po/../src/ui/widget/selected-style.cpp:105 +#: ../../po/../src/widgets/paint-selector.cpp:190 +#, fuzzy +msgid "Pattern" +msgstr "Patrón" + +#: ../../po/../src/ui/widget/selected-style.cpp:108 +#: ../../po/../src/widgets/paint-selector.cpp:885 +#, fuzzy +msgid "Pattern fill" +msgstr "Patrón" + +#: ../../po/../src/ui/widget/selected-style.cpp:108 +#, fuzzy +msgid "Pattern stroke" +msgstr "Recheo de patrón" + +#: ../../po/../src/ui/widget/selected-style.cpp:110 +#, fuzzy +msgid "L Gradient" +msgstr "Recheo de degradado" + +#: ../../po/../src/ui/widget/selected-style.cpp:113 +#, fuzzy +msgid "Linear gradient fill" +msgstr "Engadir novo degradado" + +#: ../../po/../src/ui/widget/selected-style.cpp:113 +#, fuzzy +msgid "Linear gradient stroke" +msgstr "Engadir novo degradado" + +#: ../../po/../src/ui/widget/selected-style.cpp:115 +#, fuzzy +msgid "R Gradient" +msgstr "Recheo de degradado" + +#: ../../po/../src/ui/widget/selected-style.cpp:118 +#, fuzzy +msgid "Radial gradient fill" +msgstr "Engadir novo degradado" + +#: ../../po/../src/ui/widget/selected-style.cpp:118 +#, fuzzy +msgid "Radial gradient stroke" +msgstr "Engadir novo degradado" + +#: ../../po/../src/ui/widget/selected-style.cpp:120 +#, fuzzy +msgid "Different" +msgstr "Grado" + +#: ../../po/../src/ui/widget/selected-style.cpp:123 +#, fuzzy +msgid "Different fills" +msgstr "Grado" + +#: ../../po/../src/ui/widget/selected-style.cpp:123 +#, fuzzy +msgid "Different strokes" +msgstr "Grado" + +#: ../../po/../src/ui/widget/selected-style.cpp:125 +#, fuzzy +msgid "Unset" +msgstr "polgada" + +#. TRANSLATORS COMMENT: unset is a verb here +#: ../../po/../src/ui/widget/selected-style.cpp:128 +#: ../../po/../src/ui/widget/selected-style.cpp:182 +#, fuzzy +msgid "Unset fill" +msgstr "_Ficheiro" + +#: ../../po/../src/ui/widget/selected-style.cpp:128 +#: ../../po/../src/ui/widget/selected-style.cpp:182 +#, fuzzy +msgid "Unset stroke" +msgstr "Está trazado" + +#: ../../po/../src/ui/widget/selected-style.cpp:131 +#, fuzzy +msgid "Flat color fill" +msgstr "cor" + +#: ../../po/../src/ui/widget/selected-style.cpp:131 +#, fuzzy +msgid "Flat color stroke" +msgstr "cor" + +#. TRANSLATOR COMMENT: A means "Averaged" +#: ../../po/../src/ui/widget/selected-style.cpp:134 +msgid "A" +msgstr "" + +# [*] Revisar Layout +#: ../../po/../src/ui/widget/selected-style.cpp:137 +#, fuzzy +msgid "Fill is averaged over selected objects" +msgstr "Edita-lo equipamento dos obxectos seleccionados" + +#: ../../po/../src/ui/widget/selected-style.cpp:137 +#, fuzzy +msgid "Stroke is averaged over selected objects" +msgstr "Edita-lo estilo de trazado dos obxectos seleccionados" + +#. TRANSLATOR COMMENT: M means "Multiple" +#: ../../po/../src/ui/widget/selected-style.cpp:140 +msgid "M" +msgstr "" + +# [*] Revisar +#: ../../po/../src/ui/widget/selected-style.cpp:143 +#, fuzzy +msgid "Multiple selected objects have the same fill" +msgstr "Voltea-los obxectos seleccionados" + +# [*] Revisar +#: ../../po/../src/ui/widget/selected-style.cpp:143 +#, fuzzy +msgid "Multiple selected objects have the same stroke" +msgstr "Voltea-los obxectos seleccionados" + +#: ../../po/../src/ui/widget/selected-style.cpp:145 +#, fuzzy +msgid "Edit fill..." +msgstr "Editar" + +#: ../../po/../src/ui/widget/selected-style.cpp:145 +#, fuzzy +msgid "Edit stroke..." +msgstr "Editar" + +#: ../../po/../src/ui/widget/selected-style.cpp:149 +#, fuzzy +msgid "Last set color" +msgstr "cor" + +#: ../../po/../src/ui/widget/selected-style.cpp:153 +#, fuzzy +msgid "Last selected color" +msgstr "Último seleccionado" + +#: ../../po/../src/ui/widget/selected-style.cpp:157 +msgid "White" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:161 +#: ../../po/../src/widgets/sp-color-scales.cpp:461 +#: ../../po/../src/widgets/sp-color-scales.cpp:462 +#, fuzzy +msgid "Black" +msgstr "Un atrás" + +#: ../../po/../src/ui/widget/selected-style.cpp:165 +#, fuzzy +msgid "Copy color" +msgstr "Cor do trazado:" + +#: ../../po/../src/ui/widget/selected-style.cpp:169 +#, fuzzy +msgid "Paste color" +msgstr "cor" + +#: ../../po/../src/ui/widget/selected-style.cpp:173 +#, fuzzy +msgid "Swap fill and stroke" +msgstr "Configuración do escritorio" + +#: ../../po/../src/ui/widget/selected-style.cpp:177 +msgid "Make fill opaque" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:177 +msgid "Make stroke opaque" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:186 +#, fuzzy +msgid "Remove fill" +msgstr "Sen recheo" + +#: ../../po/../src/ui/widget/selected-style.cpp:186 +#, fuzzy +msgid "Remove stroke" +msgstr "Está trazado" + +#: ../../po/../src/ui/widget/selected-style.cpp:718 +#, fuzzy +msgid "Master opacity" +msgstr "Opacidade:" + +#: ../../po/../src/ui/widget/selected-style.cpp:744 +msgid "0 (transparent)" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:768 +msgid "1.0 (opaque)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1046 +msgid "Moved to next layer." +msgstr "" + +#: ../../po/../src/verbs.cpp:1048 +msgid "Cannot move past last layer." +msgstr "" + +#: ../../po/../src/verbs.cpp:1057 +msgid "Moved to previous layer." +msgstr "" + +#: ../../po/../src/verbs.cpp:1059 +msgid "Cannot move past first layer." +msgstr "" + +#: ../../po/../src/verbs.cpp:1076 ../../po/../src/verbs.cpp:1150 +#, fuzzy +msgid "No current layer." +msgstr "Documento" + +#: ../../po/../src/verbs.cpp:1105 +#, fuzzy, c-format +msgid "Raised layer %s." +msgstr "Pegar" + +#: ../../po/../src/verbs.cpp:1109 +#, fuzzy, c-format +msgid "Lowered layer %s." +msgstr "Seleccionar" + +#: ../../po/../src/verbs.cpp:1118 +msgid "Cannot move layer any further." +msgstr "" + +#. TRANSLATORS: this means "The layer has been deleted." +#: ../../po/../src/verbs.cpp:1148 +#, fuzzy +msgid "Deleted layer." +msgstr "Seleccionar" + +#: ../../po/../src/verbs.cpp:1544 +msgid "" +"You need to connect to a Jabber server before sharing a document with " +"another user." +msgstr "" + +#: ../../po/../src/verbs.cpp:1559 +msgid "" +"You need to connect to a Jabber server before sharing a document with a " +"chatroom." +msgstr "" + +#: ../../po/../src/verbs.cpp:1569 +msgid "XML node tracker has not been initialized; nothing to dump" +msgstr "" + +#. TRANSLATORS: If you have translated the keys.svg file to your language, then +#. translate this string as "keys.LANG.svg" (where LANG is your language code); +#. otherwise leave as "keys.svg". +#: ../../po/../src/verbs.cpp:1631 +msgid "keys.svg" +msgstr "" + +#. TRANSLATORS: If you have translated the tutorial-basic.svg file to your language, +#. then translate this string as "tutorial-basic.LANG.svg" (where LANG is your language +#. code); otherwise leave as "tutorial-basic.svg". +#: ../../po/../src/verbs.cpp:1667 +msgid "tutorial-basic.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1671 +msgid "tutorial-shapes.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1675 +msgid "tutorial-advanced.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1679 +msgid "tutorial-tracing.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1683 +msgid "tutorial-calligraphy.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1687 +msgid "tutorial-elements.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1691 +msgid "tutorial-tips.svg" +msgstr "" + +#: ../../po/../src/verbs.cpp:1842 +msgid "Does nothing" +msgstr "" + +#. File +#: ../../po/../src/verbs.cpp:1845 +#, fuzzy +msgid "Default" +msgstr "Borrar" + +#: ../../po/../src/verbs.cpp:1845 +#, fuzzy +msgid "Create new document from default template" +msgstr "Documento" + +#: ../../po/../src/verbs.cpp:1847 +#, fuzzy +msgid "_Open..." +msgstr "_Abrir" + +#: ../../po/../src/verbs.cpp:1848 +#, fuzzy +msgid "Open existing document" +msgstr "Documento" + +#: ../../po/../src/verbs.cpp:1849 +msgid "Re_vert" +msgstr "" + +#: ../../po/../src/verbs.cpp:1850 +msgid "Revert to the last saved version of document (changes will be lost)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1851 +#, fuzzy +msgid "_Save" +msgstr "Peza" + +#: ../../po/../src/verbs.cpp:1851 +#, fuzzy +msgid "Save document" +msgstr "Documento" + +#: ../../po/../src/verbs.cpp:1853 +#, fuzzy +msgid "Save _As..." +msgstr "Garda-lo ficheiro" + +#: ../../po/../src/verbs.cpp:1854 +#, fuzzy +msgid "Save document under new name" +msgstr "Garda-lo debuxo con novo nome" + +#: ../../po/../src/verbs.cpp:1855 +#, fuzzy +msgid "_Print..." +msgstr "Punto" + +#: ../../po/../src/verbs.cpp:1855 +#, fuzzy +msgid "Print document" +msgstr "Documento" + +#. TRANSLATORS: "Vacuum Defs" means "Clean up defs" (so as to remove unused definitions) +#: ../../po/../src/verbs.cpp:1858 +msgid "Vac_uum Defs" +msgstr "" + +#: ../../po/../src/verbs.cpp:1858 +msgid "Remove unused predefined items from the <defs> of the document" +msgstr "" + +#: ../../po/../src/verbs.cpp:1860 +#, fuzzy +msgid "Print _Direct" +msgstr "Propiedades do elemento" + +#: ../../po/../src/verbs.cpp:1861 +msgid "Print directly without prompting to a file or pipe" +msgstr "" + +#: ../../po/../src/verbs.cpp:1862 +#, fuzzy +msgid "Print Previe_w" +msgstr "Imprimi-lo debuxo" + +#: ../../po/../src/verbs.cpp:1863 +#, fuzzy +msgid "Preview document printout" +msgstr "Previsualiza-la impresión do debuxo" + +#: ../../po/../src/verbs.cpp:1864 +#, fuzzy +msgid "_Import..." +msgstr "Importar" + +#: ../../po/../src/verbs.cpp:1865 +msgid "Import bitmap or SVG image into document" +msgstr "" + +#: ../../po/../src/verbs.cpp:1866 +#, fuzzy +msgid "_Export Bitmap..." +msgstr "Exporta-lo ficheiro" + +#: ../../po/../src/verbs.cpp:1867 +#, fuzzy +msgid "Export document or selection as a bitmap image" +msgstr "Exporta-lo debuxo a png" + +#: ../../po/../src/verbs.cpp:1868 +#, fuzzy +msgid "N_ext Window" +msgstr "Pecha-lo formulario" + +#: ../../po/../src/verbs.cpp:1869 +msgid "Switch to the next document window" +msgstr "" + +#: ../../po/../src/verbs.cpp:1870 +#, fuzzy +msgid "P_revious Window" +msgstr "Pecha-lo formulario" + +#: ../../po/../src/verbs.cpp:1871 +msgid "Switch to the previous document window" +msgstr "" + +#: ../../po/../src/verbs.cpp:1872 +#, fuzzy +msgid "_Close" +msgstr "Nova vista" + +#: ../../po/../src/verbs.cpp:1873 +#, fuzzy +msgid "Close window" +msgstr "Nova vista" + +#: ../../po/../src/verbs.cpp:1874 +#, fuzzy +msgid "_Quit" +msgstr "_Saír" + +#: ../../po/../src/verbs.cpp:1874 +#, fuzzy +msgid "Quit Inkscape" +msgstr "Sodipodi" + +#. Edit +#: ../../po/../src/verbs.cpp:1877 +#, fuzzy +msgid "_Undo" +msgstr "Desfacer " + +#: ../../po/../src/verbs.cpp:1877 +#, fuzzy +msgid "Undo last action" +msgstr "Reinicia-la transformación" + +#: ../../po/../src/verbs.cpp:1879 +#, fuzzy +msgid "_Redo" +msgstr "Refacer" + +#: ../../po/../src/verbs.cpp:1880 +msgid "Do again last undone action" +msgstr "" + +#: ../../po/../src/verbs.cpp:1881 +#, fuzzy +msgid "Cu_t" +msgstr "Cortar" + +#: ../../po/../src/verbs.cpp:1882 +#, fuzzy +msgid "Cut selection to clipboard" +msgstr "Converti-los obxectos seleccionados a curvas" + +#: ../../po/../src/verbs.cpp:1883 +#, fuzzy +msgid "_Copy" +msgstr "Copiar" + +#: ../../po/../src/verbs.cpp:1884 +#, fuzzy +msgid "Copy selection to clipboard" +msgstr "Copia-la selección ó portarretallos" + +#: ../../po/../src/verbs.cpp:1885 +#, fuzzy +msgid "_Paste" +msgstr "Pegar" + +#: ../../po/../src/verbs.cpp:1886 +#, fuzzy +msgid "Paste objects from clipboard to mouse point" +msgstr "Pegar do portarretallos" + +#: ../../po/../src/verbs.cpp:1887 +#, fuzzy +msgid "Paste _Style" +msgstr "Ancho do trazado" + +#: ../../po/../src/verbs.cpp:1888 +#, fuzzy +msgid "Apply style of the copied object to selection" +msgstr "Copia-la selección ó portarretallos" + +#: ../../po/../src/verbs.cpp:1889 +#, fuzzy +msgid "Paste _In Place" +msgstr "Ancho do trazado" + +#: ../../po/../src/verbs.cpp:1890 +#, fuzzy +msgid "Paste objects from clipboard to the original location" +msgstr "Aliñar obxectos á metade horizontal" + +#: ../../po/../src/verbs.cpp:1891 +#, fuzzy +msgid "_Delete" +msgstr "Borrar" + +#: ../../po/../src/verbs.cpp:1892 +#, fuzzy +msgid "Delete selection" +msgstr "Duplica-la selección" + +#: ../../po/../src/verbs.cpp:1893 +#, fuzzy +msgid "Duplic_ate" +msgstr "Duplicar" + +# [*] Revisar +#: ../../po/../src/verbs.cpp:1894 +#, fuzzy +msgid "Duplicate selected objects" +msgstr "Voltea-los obxectos seleccionados" + +#: ../../po/../src/verbs.cpp:1895 +#, fuzzy +msgid "Clo_ne" +msgstr "Nova vista" + +#: ../../po/../src/verbs.cpp:1896 +msgid "Create a clone of selected object (a copy linked to the original)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1897 +msgid "Unlin_k Clone" +msgstr "" + +#: ../../po/../src/verbs.cpp:1898 +msgid "Cut the clone's link to its original" +msgstr "" + +#: ../../po/../src/verbs.cpp:1899 +#, fuzzy +msgid "Select _Original" +msgstr "Seleccionar" + +#: ../../po/../src/verbs.cpp:1900 +#, fuzzy +msgid "Select the object to which the clone is linked" +msgstr "Converti-los obxectos seleccionados a curvas" + +#. TRANSLATORS: Convert selection to a rectangle with tiled pattern fill +#: ../../po/../src/verbs.cpp:1902 +#, fuzzy +msgid "O_bjects to Pattern" +msgstr "Reinicia-la transformación" + +#: ../../po/../src/verbs.cpp:1903 +msgid "Convert selection to a rectangle with tiled pattern fill" +msgstr "" + +# [*] Revisar +#. TRANSLATORS: Extract objects from a tiled pattern fill +#: ../../po/../src/verbs.cpp:1905 +#, fuzzy +msgid "Pattern to Ob_jects" +msgstr "Voltea-los obxectos seleccionados" + +#: ../../po/../src/verbs.cpp:1906 +msgid "Extract objects from a tiled pattern fill" +msgstr "" + +#: ../../po/../src/verbs.cpp:1907 +#, fuzzy +msgid "Clea_r All" +msgstr "Cor do recheo" + +#: ../../po/../src/verbs.cpp:1908 +msgid "Delete all objects from document" +msgstr "" + +#: ../../po/../src/verbs.cpp:1909 +#, fuzzy +msgid "Select Al_l" +msgstr "Seleccionar" + +# [*] Revisar +#: ../../po/../src/verbs.cpp:1910 +#, fuzzy +msgid "Select all objects or all nodes" +msgstr "Voltea-los obxectos seleccionados" + +#: ../../po/../src/verbs.cpp:1911 +#, fuzzy +msgid "Select All in All La_yers" +msgstr "Seleccionar" + +# [*] Revisar +#: ../../po/../src/verbs.cpp:1912 +#, fuzzy +msgid "Select all objects in all visible and unlocked layers" +msgstr "Voltea-los obxectos seleccionados" + +#: ../../po/../src/verbs.cpp:1913 +#, fuzzy +msgid "In_vert Selection" +msgstr "Selección" + +#: ../../po/../src/verbs.cpp:1914 +msgid "Invert selection (unselect what is selected and select everything else)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1915 +msgid "Invert in All Layers" +msgstr "" + +#: ../../po/../src/verbs.cpp:1916 +msgid "Invert selection in all visible and unlocked layers" +msgstr "" + +#: ../../po/../src/verbs.cpp:1917 +#, fuzzy +msgid "D_eselect" +msgstr "Seleccionar" + +#: ../../po/../src/verbs.cpp:1918 +#, fuzzy +msgid "Deselect any selected objects or nodes" +msgstr "Borra-los nodos seleccionados" + +#. Selection +#: ../../po/../src/verbs.cpp:1921 +#, fuzzy +msgid "Raise to _Top" +msgstr "Eleva-la selección ó tope" + +#: ../../po/../src/verbs.cpp:1922 +#, fuzzy +msgid "Raise selection to top" +msgstr "Eleva-la selección ó tope" + +#: ../../po/../src/verbs.cpp:1923 +#, fuzzy +msgid "Lower to _Bottom" +msgstr "Baixa-la selección ó fondo" + +#: ../../po/../src/verbs.cpp:1924 +#, fuzzy +msgid "Lower selection to bottom" +msgstr "Baixa-la selección ó fondo" + +#: ../../po/../src/verbs.cpp:1925 +#, fuzzy +msgid "_Raise" +msgstr "Pegar" + +#: ../../po/../src/verbs.cpp:1926 +#, fuzzy +msgid "Raise selection one step" +msgstr "Eleva-la selección unha capa" + +#: ../../po/../src/verbs.cpp:1927 +msgid "_Lower" +msgstr "" + +#: ../../po/../src/verbs.cpp:1928 +#, fuzzy +msgid "Lower selection one step" +msgstr "Baixa-la selección unha capa" + +#: ../../po/../src/verbs.cpp:1929 +msgid "_Group" +msgstr "_Agrupar" + +#: ../../po/../src/verbs.cpp:1930 +msgid "Group selected objects" +msgstr "Agrupa-los obxectos seleccionados" + +#: ../../po/../src/verbs.cpp:1932 +#, fuzzy +msgid "Ungroup selected groups" +msgstr "Desagrupa-los obxectos seleccionados" + +#: ../../po/../src/verbs.cpp:1934 +#, fuzzy +msgid "_Put on Path" +msgstr "Converti-los obxectos seleccionados a curvas" + +#: ../../po/../src/verbs.cpp:1935 +#, fuzzy +msgid "Put text on path" +msgstr "Converti-los obxectos seleccionados a curvas" + +#: ../../po/../src/verbs.cpp:1936 +#, fuzzy +msgid "_Remove from Path" +msgstr "Elimina-la transformación" + +#: ../../po/../src/verbs.cpp:1937 +#, fuzzy +msgid "Remove text from path" +msgstr "Converti-los obxectos seleccionados a curvas" + +#: ../../po/../src/verbs.cpp:1938 +msgid "Remove Manual _Kerns" +msgstr "" + +#. TRANSLATORS: "glyph": An image used in the visual representation of characters; +#. roughly speaking, how a character looks. A font is a set of glyphs. +#: ../../po/../src/verbs.cpp:1941 +#, fuzzy +msgid "Remove all manual kerns and glyph rotations from a text object" +msgstr "Elimina-la transformación" + +#: ../../po/../src/verbs.cpp:1943 +#, fuzzy +msgid "_Union" +msgstr "ningún" + +#: ../../po/../src/verbs.cpp:1944 +#, fuzzy +msgid "Union of selected objects" +msgstr "Desagrupa-los obxectos seleccionados" + +#: ../../po/../src/verbs.cpp:1945 +#, fuzzy +msgid "_Intersection" +msgstr "_Interactivo" + +#: ../../po/../src/verbs.cpp:1946 +#, fuzzy +msgid "Intersection of selected objects" +msgstr "Borra-los nodos seleccionados" + +#: ../../po/../src/verbs.cpp:1947 +#, fuzzy +msgid "_Difference" +msgstr "Grado" + +#: ../../po/../src/verbs.cpp:1948 +#, fuzzy +msgid "Difference of selected objects (bottom minus top)" +msgstr "Borra-los nodos seleccionados" + +#: ../../po/../src/verbs.cpp:1949 +#, fuzzy +msgid "E_xclusion" +msgstr "Dimensión" + +# [*] Revisar Layout +#: ../../po/../src/verbs.cpp:1950 +#, fuzzy +msgid "Exclusive OR of selected objects" +msgstr "Edita-lo equipamento dos obxectos seleccionados" + +#: ../../po/../src/verbs.cpp:1951 +msgid "Di_vision" +msgstr "" + +#: ../../po/../src/verbs.cpp:1952 +msgid "Cut the bottom object into pieces" +msgstr "" + +#. TRANSLATORS: "to cut a path" is not the same as "to break a path apart" - see the +#. Advanced tutorial for more info +#: ../../po/../src/verbs.cpp:1955 +#, fuzzy +msgid "Cut _Path" +msgstr "Combina-las curvas seleccionadas" + +#: ../../po/../src/verbs.cpp:1956 +msgid "Cut the bottom object's stroke into pieces, removing fill" +msgstr "" + +#. TRANSLATORS: "outset": expand a shape by offsetting the object's path, +#. i.e. by displacing it perpendicular to the path in each point. +#. See also the Advanced Tutorial for explanation. +#: ../../po/../src/verbs.cpp:1960 +#, fuzzy +msgid "Outs_et" +msgstr "Combina-las curvas seleccionadas" + +#: ../../po/../src/verbs.cpp:1961 +#, fuzzy +msgid "Outset selected paths" +msgstr "Combina-las curvas seleccionadas" + +#: ../../po/../src/verbs.cpp:1963 +#, fuzzy +msgid "O_utset Path by 1 px" +msgstr "Combina-las curvas seleccionadas" + +#: ../../po/../src/verbs.cpp:1964 +#, fuzzy +msgid "Outset selected paths by 1 px" +msgstr "Combina-las curvas seleccionadas" + +#: ../../po/../src/verbs.cpp:1966 +#, fuzzy +msgid "O_utset Path by 10 px" +msgstr "Combina-las curvas seleccionadas" + +#: ../../po/../src/verbs.cpp:1967 +#, fuzzy +msgid "Outset selected paths by 10 px" +msgstr "Combina-las curvas seleccionadas" + +#. TRANSLATORS: "inset": contract a shape by offsetting the object's path, +#. i.e. by displacing it perpendicular to the path in each point. +#. See also the Advanced Tutorial for explanation. +#: ../../po/../src/verbs.cpp:1971 +msgid "I_nset" +msgstr "" + +#: ../../po/../src/verbs.cpp:1972 +#, fuzzy +msgid "Inset selected paths" +msgstr "Combina-las curvas seleccionadas" + +#: ../../po/../src/verbs.cpp:1974 +#, fuzzy +msgid "I_nset Path by 1 px" +msgstr "Combina-las curvas seleccionadas" + +#: ../../po/../src/verbs.cpp:1975 +#, fuzzy +msgid "Inset selected paths by 1 px" +msgstr "Combina-las curvas seleccionadas" + +#: ../../po/../src/verbs.cpp:1977 +#, fuzzy +msgid "I_nset Path by 10 px" +msgstr "Combina-las curvas seleccionadas" + +#: ../../po/../src/verbs.cpp:1978 +#, fuzzy +msgid "Inset selected paths by 10 px" +msgstr "Combina-las curvas seleccionadas" + +#: ../../po/../src/verbs.cpp:1980 +msgid "D_ynamic Offset" +msgstr "" + +#: ../../po/../src/verbs.cpp:1980 +msgid "Create a dynamic offset object" +msgstr "" + +#: ../../po/../src/verbs.cpp:1982 +msgid "_Linked Offset" +msgstr "" + +#: ../../po/../src/verbs.cpp:1983 +msgid "Create a dynamic offset object linked to the original path" +msgstr "" + +#: ../../po/../src/verbs.cpp:1985 +#, fuzzy +msgid "_Stroke to Path" +msgstr "Ancho do trazado" + +#: ../../po/../src/verbs.cpp:1986 +#, fuzzy +msgid "Convert selected strokes to paths" +msgstr "Converti-los obxectos seleccionados a curvas" + +#: ../../po/../src/verbs.cpp:1987 +#, fuzzy +msgid "Si_mplify" +msgstr "Combina-las curvas seleccionadas" + +#: ../../po/../src/verbs.cpp:1988 +#, fuzzy +msgid "Simplify selected paths by removing extra nodes" +msgstr "Combina-las curvas seleccionadas" + +#: ../../po/../src/verbs.cpp:1989 +#, fuzzy +msgid "_Reverse" +msgstr "Ficheiro" + +#: ../../po/../src/verbs.cpp:1990 +#, fuzzy +msgid "Reverses the direction of selected paths; useful for flipping markers" +msgstr "Borra-los nodos seleccionados" + +#. TRANSLATORS: "to trace" means "to convert a bitmap to vector graphics" (to vectorize) +#: ../../po/../src/verbs.cpp:1992 +#, fuzzy +msgid "_Trace Bitmap" +msgstr "Bitmap roto" + +#: ../../po/../src/verbs.cpp:1993 +#, fuzzy +msgid "Convert bitmap object to paths" +msgstr "Converti-los obxectos seleccionados a curvas" + +#: ../../po/../src/verbs.cpp:1994 +#, fuzzy +msgid "_Make a Bitmap Copy" +msgstr "Bitmap roto" + +#: ../../po/../src/verbs.cpp:1995 +msgid "Export selection to a bitmap and insert it into document" +msgstr "" + +#: ../../po/../src/verbs.cpp:1996 +msgid "_Combine" +msgstr "_Combinar" + +#: ../../po/../src/verbs.cpp:1997 +msgid "Combine several paths into one" +msgstr "" + +#. TRANSLATORS: "to cut a path" is not the same as "to break a path apart" - see the +#. Advanced tutorial for more info +#: ../../po/../src/verbs.cpp:2000 +#, fuzzy +msgid "Break _Apart" +msgstr "_Romper aparte" + +# [*] Mirar +#: ../../po/../src/verbs.cpp:2001 +#, fuzzy +msgid "Break selected paths into subpaths" +msgstr "Fragmenta-las curvas seleccionadas" + +#: ../../po/../src/verbs.cpp:2002 +msgid "Gri_d Arrange..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2003 +msgid "Arrange selection in grid pattern" +msgstr "" + +#. Layer +#: ../../po/../src/verbs.cpp:2005 +#, fuzzy +msgid "_Add Layer..." +msgstr "Pegar" + +#: ../../po/../src/verbs.cpp:2006 +#, fuzzy +msgid "Create a new layer" +msgstr "Documento" + +#: ../../po/../src/verbs.cpp:2007 +#, fuzzy +msgid "Re_name Layer..." +msgstr "Pegar" + +#: ../../po/../src/verbs.cpp:2008 +#, fuzzy +msgid "Rename the current layer" +msgstr "Seleccionar" + +#: ../../po/../src/verbs.cpp:2009 +#, fuzzy +msgid "Switch to Layer Abov_e" +msgstr "Baixa-la selección ó fondo" + +#: ../../po/../src/verbs.cpp:2010 +msgid "Switch to the layer above the current" +msgstr "" + +#: ../../po/../src/verbs.cpp:2011 +#, fuzzy +msgid "Switch to Layer Belo_w" +msgstr "Baixa-la selección unha capa" + +#: ../../po/../src/verbs.cpp:2012 +msgid "Switch to the layer below the current" +msgstr "" + +#: ../../po/../src/verbs.cpp:2013 +#, fuzzy +msgid "Move Selection to Layer Abo_ve" +msgstr "Baixa-la selección ó fondo" + +#: ../../po/../src/verbs.cpp:2014 +msgid "Move selection to the layer above the current" +msgstr "" + +#: ../../po/../src/verbs.cpp:2015 +#, fuzzy +msgid "Move Selection to Layer Bel_ow" +msgstr "Baixa-la selección unha capa" + +#: ../../po/../src/verbs.cpp:2016 +msgid "Move selection to the layer below the current" +msgstr "" + +#: ../../po/../src/verbs.cpp:2017 +#, fuzzy +msgid "Layer to _Top" +msgstr "Eleva-la selección ó tope" + +#: ../../po/../src/verbs.cpp:2018 +#, fuzzy +msgid "Raise the current layer to the top" +msgstr "Eleva-la selección ó tope" + +#: ../../po/../src/verbs.cpp:2019 +#, fuzzy +msgid "Layer to _Bottom" +msgstr "Baixa-la selección ó fondo" + +#: ../../po/../src/verbs.cpp:2020 +#, fuzzy +msgid "Lower the current layer to the bottom" +msgstr "Baixa-la selección ó fondo" + +#: ../../po/../src/verbs.cpp:2021 +#, fuzzy +msgid "_Raise Layer" +msgstr "Pegar" + +#: ../../po/../src/verbs.cpp:2022 +msgid "Raise the current layer" +msgstr "" + +#: ../../po/../src/verbs.cpp:2023 +#, fuzzy +msgid "_Lower Layer" +msgstr "Seleccionar" + +#: ../../po/../src/verbs.cpp:2024 +msgid "Lower the current layer" +msgstr "" + +#: ../../po/../src/verbs.cpp:2025 +#, fuzzy +msgid "_Delete Current Layer" +msgstr "Seleccionar" + +#: ../../po/../src/verbs.cpp:2026 +#, fuzzy +msgid "Delete the current layer" +msgstr "Seleccionar" + +#. Object +#: ../../po/../src/verbs.cpp:2029 +#, fuzzy +msgid "Rotate _90° CW" +msgstr "Poñe-lo ángulo a 90°" + +#: ../../po/../src/verbs.cpp:2030 +#, fuzzy +msgid "Rotate selection 90° clockwise" +msgstr "Rota-los obxectos seleccionados 90° en sentido horario" + +#: ../../po/../src/verbs.cpp:2031 +#, fuzzy +msgid "Rotate 9_0° CCW" +msgstr "Poñe-lo ángulo a 90°" + +#: ../../po/../src/verbs.cpp:2032 +#, fuzzy +msgid "Rotate selection 90° counter-clockwise" +msgstr "Rota-los obxectos seleccionados 90° en sentido horario" + +#: ../../po/../src/verbs.cpp:2033 +#, fuzzy +msgid "Remove _Transformations" +msgstr "Elimina-la transformación" + +#: ../../po/../src/verbs.cpp:2034 +#, fuzzy +msgid "Remove transformations from object" +msgstr "Elimina-la transformación" + +#: ../../po/../src/verbs.cpp:2035 +#, fuzzy +msgid "_Object to Path" +msgstr "Reinicia-la transformación" + +#: ../../po/../src/verbs.cpp:2036 +#, fuzzy +msgid "Convert selected objects to paths" +msgstr "Converti-los obxectos seleccionados a curvas" + +#: ../../po/../src/verbs.cpp:2037 +msgid "_Flow into Frame" +msgstr "" + +#: ../../po/../src/verbs.cpp:2038 +#, fuzzy +msgid "Put text into frames" +msgstr "Converti-los obxectos seleccionados a curvas" + +#: ../../po/../src/verbs.cpp:2039 +#, fuzzy +msgid "_Unflow" +msgstr "Desfacer " + +#: ../../po/../src/verbs.cpp:2040 +msgid "Remove text from frame (creates a single-line text object)" +msgstr "" + +#: ../../po/../src/verbs.cpp:2041 +#, fuzzy +msgid "_Convert to Text" +msgstr "Converti-los obxectos seleccionados a curvas" + +#: ../../po/../src/verbs.cpp:2042 +#, fuzzy +msgid "Convert flowed text to regular text objects (preserves appearance)" +msgstr "Converti-los segmentos seleccionados a liñas" + +#: ../../po/../src/verbs.cpp:2044 +#, fuzzy +msgid "Flip _Horizontal" +msgstr "voltear horizontal" + +# [*] Revisar +#: ../../po/../src/verbs.cpp:2044 +#, fuzzy +msgid "Flips selected objects horizontally" +msgstr "Voltea-los obxectos seleccionados" + +#: ../../po/../src/verbs.cpp:2047 +#, fuzzy +msgid "Flip _Vertical" +msgstr "voltear vertical" + +# [*] Revisar +#: ../../po/../src/verbs.cpp:2047 +#, fuzzy +msgid "Flips selected objects vertically" +msgstr "Voltea-los obxectos seleccionados" + +#. Tools +#: ../../po/../src/verbs.cpp:2051 +msgid "Select" +msgstr "Seleccionar" + +#: ../../po/../src/verbs.cpp:2052 +#, fuzzy +msgid "Select and transform objects" +msgstr "Reinicia-la transformación" + +#: ../../po/../src/verbs.cpp:2053 +#, fuzzy +msgid "Node Edit" +msgstr "Edición de nodos" + +# [*] Revisar Layout +#: ../../po/../src/verbs.cpp:2054 +#, fuzzy +msgid "Edit path nodes or control handles" +msgstr "Edita-lo equipamento dos obxectos seleccionados" + +#: ../../po/../src/verbs.cpp:2056 +#, fuzzy +msgid "Create rectangles and squares" +msgstr "Debuxar rectangulo" + +#: ../../po/../src/verbs.cpp:2058 +msgid "Create circles, ellipses, and arcs" +msgstr "" + +#: ../../po/../src/verbs.cpp:2060 +msgid "Create stars and polygons" +msgstr "" + +#: ../../po/../src/verbs.cpp:2062 +#, fuzzy +msgid "Create spirals" +msgstr "Debuxar rectangulo" + +#: ../../po/../src/verbs.cpp:2064 +#, fuzzy +msgid "Draw freehand lines" +msgstr "Debuxar liña a man alzada" + +#: ../../po/../src/verbs.cpp:2066 +#, fuzzy +msgid "Draw Bezier curves and straight lines" +msgstr "Debuxar liña a man alzada" + +#: ../../po/../src/verbs.cpp:2068 +msgid "Draw calligraphic lines" +msgstr "" + +#: ../../po/../src/verbs.cpp:2070 +#, fuzzy +msgid "Create and edit text objects" +msgstr "Engadir atributo" + +#: ../../po/../src/verbs.cpp:2072 +#, fuzzy +msgid "Create and edit gradients" +msgstr "Engadir atributo" + +#: ../../po/../src/verbs.cpp:2074 +#, fuzzy +msgid "Zoom in or out" +msgstr "Zoom fora" + +#: ../../po/../src/verbs.cpp:2076 +msgid "Pick averaged colors from image" +msgstr "" + +#: ../../po/../src/verbs.cpp:2078 +#, fuzzy +msgid "Create connectors" +msgstr "Documento" + +#. Tool prefs +#: ../../po/../src/verbs.cpp:2081 +msgid "Selector Preferences" +msgstr "" + +#: ../../po/../src/verbs.cpp:2082 +#, fuzzy +msgid "Open Preferences for the Selector tool" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2083 +#, fuzzy +msgid "Node Tool Preferences" +msgstr "O elemento é de referencia" + +#: ../../po/../src/verbs.cpp:2084 +#, fuzzy +msgid "Open Preferences for the Node tool" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2085 +#, fuzzy +msgid "Rectangle Preferences" +msgstr "Propiedades do texto" + +#: ../../po/../src/verbs.cpp:2086 +#, fuzzy +msgid "Open Preferences for the Rectangle tool" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2087 +#, fuzzy +msgid "Ellipse Preferences" +msgstr "O elemento é de referencia" + +#: ../../po/../src/verbs.cpp:2088 +#, fuzzy +msgid "Open Preferences for the Ellipse tool" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2089 +#, fuzzy +msgid "Star Preferences" +msgstr "Propiedades do texto" + +#: ../../po/../src/verbs.cpp:2090 +#, fuzzy +msgid "Open Preferences for the Star tool" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2091 +#, fuzzy +msgid "Spiral Preferences" +msgstr "Propiedades do texto" + +#: ../../po/../src/verbs.cpp:2092 +#, fuzzy +msgid "Open Preferences for the Spiral tool" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2093 +#, fuzzy +msgid "Pencil Preferences" +msgstr "O elemento é de referencia" + +#: ../../po/../src/verbs.cpp:2094 +#, fuzzy +msgid "Open Preferences for the Pencil tool" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2095 +#, fuzzy +msgid "Pen Preferences" +msgstr "O elemento é de referencia" + +#: ../../po/../src/verbs.cpp:2096 +#, fuzzy +msgid "Open Preferences for the Pen tool" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2097 +msgid "Calligraphic Preferences" +msgstr "" + +#: ../../po/../src/verbs.cpp:2098 +#, fuzzy +msgid "Open Preferences for the Calligraphy tool" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2099 +#, fuzzy +msgid "Text Preferences" +msgstr "O elemento é de referencia" + +#: ../../po/../src/verbs.cpp:2100 +#, fuzzy +msgid "Open Preferences for the Text tool" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2101 +#, fuzzy +msgid "Gradient Preferences" +msgstr "O elemento é de referencia" + +#: ../../po/../src/verbs.cpp:2102 +#, fuzzy +msgid "Open Preferences for the Gradient tool" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2103 +#, fuzzy +msgid "Zoom Preferences" +msgstr "O elemento é de referencia" + +#: ../../po/../src/verbs.cpp:2104 +#, fuzzy +msgid "Open Preferences for the Zoom tool" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2105 +#, fuzzy +msgid "Dropper Preferences" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2106 +#, fuzzy +msgid "Open Preferences for the Dropper tool" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2107 +#, fuzzy +msgid "Connector Preferences" +msgstr "Propiedades do texto" + +#: ../../po/../src/verbs.cpp:2108 +#, fuzzy +msgid "Open Preferences for the Connector tool" +msgstr "Sodipodi" + +#. Zoom/View +#: ../../po/../src/verbs.cpp:2111 +#, fuzzy +msgid "Zoom In" +msgstr "Zoom dentro" + +#: ../../po/../src/verbs.cpp:2111 +msgid "Zoom in" +msgstr "Zoom dentro" + +#: ../../po/../src/verbs.cpp:2112 +#, fuzzy +msgid "Zoom Out" +msgstr "Zoom fora" + +#: ../../po/../src/verbs.cpp:2112 +msgid "Zoom out" +msgstr "Zoom fora" + +#: ../../po/../src/verbs.cpp:2113 +#, fuzzy +msgid "_Rulers" +msgstr "Ficheiro" + +#: ../../po/../src/verbs.cpp:2113 +#, fuzzy +msgid "Show or hide the canvas rulers" +msgstr "Amosar guías" + +#: ../../po/../src/verbs.cpp:2114 +msgid "Scroll_bars" +msgstr "" + +#: ../../po/../src/verbs.cpp:2114 +#, fuzzy +msgid "Show or hide the canvas scrollbars" +msgstr "Amosar guías" + +#: ../../po/../src/verbs.cpp:2115 +#, fuzzy +msgid "_Grid" +msgstr "Reixa" + +#: ../../po/../src/verbs.cpp:2116 +#, fuzzy +msgid "G_uides" +msgstr "Guías" + +#: ../../po/../src/verbs.cpp:2117 +msgid "Nex_t Zoom" +msgstr "" + +#: ../../po/../src/verbs.cpp:2117 +msgid "Next zoom (from the history of zooms)" +msgstr "" + +#: ../../po/../src/verbs.cpp:2119 +msgid "Pre_vious Zoom" +msgstr "" + +#: ../../po/../src/verbs.cpp:2119 +msgid "Previous zoom (from the history of zooms)" +msgstr "" + +#: ../../po/../src/verbs.cpp:2121 +#, fuzzy +msgid "Zoom 1:_1" +msgstr "Zoom a 1:1" + +#: ../../po/../src/verbs.cpp:2121 +msgid "Zoom to 1:1" +msgstr "Zoom a 1:1" + +#: ../../po/../src/verbs.cpp:2123 +#, fuzzy +msgid "Zoom 1:_2" +msgstr "Zoom a 1:1" + +#: ../../po/../src/verbs.cpp:2123 +#, fuzzy +msgid "Zoom to 1:2" +msgstr "Zoom a 1:1" + +#: ../../po/../src/verbs.cpp:2125 +#, fuzzy +msgid "_Zoom 2:1" +msgstr "Zoom a 1:1" + +#: ../../po/../src/verbs.cpp:2125 +#, fuzzy +msgid "Zoom to 2:1" +msgstr "Zoom a 1:1" + +#: ../../po/../src/verbs.cpp:2128 +msgid "_Fullscreen" +msgstr "" + +#: ../../po/../src/verbs.cpp:2128 +msgid "Stretch this document window to full screen" +msgstr "" + +#: ../../po/../src/verbs.cpp:2131 +#, fuzzy +msgid "Duplic_ate Window" +msgstr "Duplicar" + +#: ../../po/../src/verbs.cpp:2131 +#, fuzzy +msgid "Open a new window with the same document" +msgstr "Documento" + +#: ../../po/../src/verbs.cpp:2133 +#, fuzzy +msgid "_New View Preview" +msgstr "Nova vista" + +#: ../../po/../src/verbs.cpp:2134 +#, fuzzy +msgid "New View Preview" +msgstr "Nova vista" + +#. "view_new_preview" +#: ../../po/../src/verbs.cpp:2136 +#, fuzzy +msgid "_Normal" +msgstr "Fractal" + +#: ../../po/../src/verbs.cpp:2137 +msgid "Switch to normal display mode" +msgstr "" + +#: ../../po/../src/verbs.cpp:2138 +#, fuzzy +msgid "_Outline" +msgstr "Amosar guías" + +#: ../../po/../src/verbs.cpp:2139 +msgid "Switch to outline (wireframe) display mode" +msgstr "" + +#: ../../po/../src/verbs.cpp:2141 +#, fuzzy +msgid "Ico_n Preview" +msgstr "Nova vista" + +#: ../../po/../src/verbs.cpp:2142 +msgid "Open a window to preview items at different icon resolutions" +msgstr "" + +#: ../../po/../src/verbs.cpp:2144 +#, fuzzy +msgid "Zoom to fit page in window" +msgstr "Configura-lo ancho da páxina" + +#: ../../po/../src/verbs.cpp:2145 +#, fuzzy +msgid "Page _Width" +msgstr "Configura-lo ancho da páxina" + +#: ../../po/../src/verbs.cpp:2146 +#, fuzzy +msgid "Zoom to fit page width in window" +msgstr "Configura-lo ancho da páxina" + +#: ../../po/../src/verbs.cpp:2148 +#, fuzzy +msgid "Zoom to fit drawing in window" +msgstr "Zoom ó debuxo" + +#: ../../po/../src/verbs.cpp:2150 +#, fuzzy +msgid "Zoom to fit selection in window" +msgstr "Eleva-la selección ó tope" + +#. Dialogs +#: ../../po/../src/verbs.cpp:2153 +#, fuzzy +msgid "In_kscape Preferences..." +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2154 +#, fuzzy +msgid "Global Inkscape preferences" +msgstr "Configuración da visualización" + +#: ../../po/../src/verbs.cpp:2155 +msgid "_Document Preferences..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2156 +#, fuzzy +msgid "Preferences saved with the document" +msgstr "Documento" + +#: ../../po/../src/verbs.cpp:2157 +#, fuzzy +msgid "_Fill and Stroke..." +msgstr "Configuración do escritorio" + +#: ../../po/../src/verbs.cpp:2158 +#, fuzzy +msgid "Fill and Stroke dialog" +msgstr "Configuración do escritorio" + +#. TRANSLATORS: "Swatches" means: color samples +#: ../../po/../src/verbs.cpp:2160 +#, fuzzy +msgid "S_watches..." +msgstr "Garda-lo ficheiro" + +#: ../../po/../src/verbs.cpp:2161 +msgid "View color swatches" +msgstr "" + +#: ../../po/../src/verbs.cpp:2162 +#, fuzzy +msgid "Transfor_m..." +msgstr "Transformación" + +#: ../../po/../src/verbs.cpp:2163 +#, fuzzy +msgid "Transform dialog" +msgstr "Formulario de transformacións" + +#: ../../po/../src/verbs.cpp:2164 +#, fuzzy +msgid "_Align and Distribute..." +msgstr "Atributos" + +#: ../../po/../src/verbs.cpp:2165 +#, fuzzy +msgid "Align and Distribute dialog" +msgstr "Atributos" + +#: ../../po/../src/verbs.cpp:2166 +#, fuzzy +msgid "_Text and Font..." +msgstr "Configuración do escritorio" + +#: ../../po/../src/verbs.cpp:2167 +#, fuzzy +msgid "Text and Font dialog" +msgstr "Configuración do escritorio" + +#: ../../po/../src/verbs.cpp:2168 +#, fuzzy +msgid "_XML Editor..." +msgstr "Editar..." + +#: ../../po/../src/verbs.cpp:2169 +msgid "XML Editor" +msgstr "" + +#: ../../po/../src/verbs.cpp:2170 +#, fuzzy +msgid "_Find..." +msgstr "Punto" + +#: ../../po/../src/verbs.cpp:2171 +#, fuzzy +msgid "Find objects in document" +msgstr "Documento" + +#: ../../po/../src/verbs.cpp:2172 +msgid "_Messages..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2173 +msgid "View debug messages" +msgstr "" + +#: ../../po/../src/verbs.cpp:2174 +#, fuzzy +msgid "S_cripts..." +msgstr "Punto" + +# [*] Revisar +#: ../../po/../src/verbs.cpp:2175 +#, fuzzy +msgid "Run scripts" +msgstr "Xuntar redondeado" + +#: ../../po/../src/verbs.cpp:2176 +#, fuzzy +msgid "Show/Hide D_ialogs" +msgstr "Pecha-lo formulario" + +#: ../../po/../src/verbs.cpp:2177 +msgid "Show or hide all active dialogs" +msgstr "" + +#. TRANSLATORS: "Tile clones" means: "Create tiled clones" +#: ../../po/../src/verbs.cpp:2179 +msgid "Tile clones..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2180 +msgid "Create and arrange multiple clones of selection" +msgstr "" + +#: ../../po/../src/verbs.cpp:2181 +#, fuzzy +msgid "_Object Properties..." +msgstr "Propiedades do obxecto" + +#: ../../po/../src/verbs.cpp:2182 +#, fuzzy +msgid "Object Properties dialog" +msgstr "Propiedades do obxecto" + +#: ../../po/../src/verbs.cpp:2185 +msgid "_Connect to Jabber server..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2185 +msgid "Connect to a Jabber server" +msgstr "" + +#: ../../po/../src/verbs.cpp:2187 +#, fuzzy +msgid "Share with _user..." +msgstr "Garda-lo ficheiro" + +#: ../../po/../src/verbs.cpp:2187 +msgid "Establish a whiteboard session with another Jabber user" +msgstr "" + +#: ../../po/../src/verbs.cpp:2189 +msgid "Share with _chatroom..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2189 +msgid "" +"Join a chatroom to start a new whiteboard session or join one in progress" +msgstr "" + +#: ../../po/../src/verbs.cpp:2191 +msgid "_Dump XML node tracker" +msgstr "" + +#: ../../po/../src/verbs.cpp:2191 +msgid "Dump the contents of the XML tracker to the console" +msgstr "" + +#: ../../po/../src/verbs.cpp:2193 +msgid "_Open session file..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2193 +msgid "Open and browse through records of past whiteboard sessions" +msgstr "" + +#: ../../po/../src/verbs.cpp:2195 +msgid "Session file playback" +msgstr "" + +#: ../../po/../src/verbs.cpp:2197 +msgid "_Disconnect from session" +msgstr "" + +#: ../../po/../src/verbs.cpp:2199 +msgid "Disconnect from _server" +msgstr "" + +#: ../../po/../src/verbs.cpp:2201 +msgid "_Input Devices..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2202 +msgid "Configure extended input devices" +msgstr "" + +#. Help +#: ../../po/../src/verbs.cpp:2205 +msgid "_Keys and Mouse" +msgstr "" + +#: ../../po/../src/verbs.cpp:2206 +msgid "Key and mouse shortcuts reference" +msgstr "" + +#: ../../po/../src/verbs.cpp:2207 +#, fuzzy +msgid "About E_xtensions" +msgstr "Configura-las dimensións" + +#: ../../po/../src/verbs.cpp:2208 +#, fuzzy +msgid "About Extensions..." +msgstr "Configura-las dimensións" + +#: ../../po/../src/verbs.cpp:2209 +#, fuzzy +msgid "About _Memory" +msgstr "Configura-las dimensións" + +#: ../../po/../src/verbs.cpp:2210 +#, fuzzy +msgid "About Memory..." +msgstr "S_obre ..." + +#: ../../po/../src/verbs.cpp:2211 +msgid "_About Inkscape" +msgstr "" + +#. "help_about" +#. new HelpVerb(SP_VERB_SHOW_LICENSE, "ShowLicense", N_("Modifying or Redistributing Inkscape"), +#. N_("Show license to modify and/or redistribute Inkscape: GNU GPL"), NULL), +#. Tutorials +#: ../../po/../src/verbs.cpp:2217 +#, fuzzy +msgid "Inkscape: _Basic" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2218 +msgid "Getting started with Inkscape" +msgstr "" + +#. "tutorial_basic" +#: ../../po/../src/verbs.cpp:2219 +#, fuzzy +msgid "Inkscape: _Shapes" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2220 +msgid "Using shape tools to create and edit shapes" +msgstr "" + +#: ../../po/../src/verbs.cpp:2221 +#, fuzzy +msgid "Inkscape: _Advanced" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2222 +#, fuzzy +msgid "Advanced Inkscape topics" +msgstr "Sodipodi" + +#. "tutorial_advanced" +#. TRANSLATORS: "to trace" means "to convert a bitmap to vector graphics" (to vectorize) +#: ../../po/../src/verbs.cpp:2224 +#, fuzzy +msgid "Inkscape: T_racing" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2225 +#, fuzzy +msgid "Using bitmap tracing" +msgstr "Tamaño da imaxe" + +#. "tutorial_tracing" +#: ../../po/../src/verbs.cpp:2226 +#, fuzzy +msgid "Inkscape: _Calligraphy" +msgstr "Sodipodi" + +#: ../../po/../src/verbs.cpp:2227 +msgid "Using the Calligraphy pen tool" +msgstr "" + +#: ../../po/../src/verbs.cpp:2228 +msgid "_Elements of Design" +msgstr "" + +#: ../../po/../src/verbs.cpp:2229 +msgid "Principles of design in the tutorial form" +msgstr "" + +#. "tutorial_design" +#: ../../po/../src/verbs.cpp:2230 +msgid "_Tips and Tricks" +msgstr "" + +#: ../../po/../src/verbs.cpp:2231 +msgid "Miscellaneous tips and tricks" +msgstr "" + +#. "tutorial_tips" +#. Effect +#: ../../po/../src/verbs.cpp:2234 +msgid "Previous Effect" +msgstr "" + +#: ../../po/../src/verbs.cpp:2235 +msgid "Repeat the last effect with the same settings" +msgstr "" + +#. "tutorial_tips" +#: ../../po/../src/verbs.cpp:2236 +msgid "Previous Effect Settings..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2237 +msgid "Repeat the last effect with new settings" +msgstr "" + +#: ../../po/../src/widgets/dash-selector.cpp:106 +#, fuzzy +msgid "Dash pattern" +msgstr "Ancho do trazado" + +#: ../../po/../src/widgets/dash-selector.cpp:121 +#, fuzzy +msgid "Pattern offset" +msgstr "Recheo de patrón" + +#: ../../po/../src/widgets/desktop-widget.cpp:240 +#, fuzzy +msgid "Zoom drawing if window size changes" +msgstr "Zoom ó debuxo" + +#: ../../po/../src/widgets/desktop-widget.cpp:298 +msgid "Cursor coordinates" +msgstr "" + +#. display the initial welcome message in the statusbar +#: ../../po/../src/widgets/desktop-widget.cpp:324 +msgid "" +"Welcome to Inkscape! Use shape or freehand tools to create objects; " +"use selector (arrow) to move or transform them." +msgstr "" + +#: ../../po/../src/widgets/desktop-widget.cpp:372 +#, c-format +msgid "%s: %d - Inkscape" +msgstr "" + +#: ../../po/../src/widgets/desktop-widget.cpp:374 +#, c-format +msgid "%s - Inkscape" +msgstr "" + +#: ../../po/../src/widgets/desktop-widget.cpp:532 +#, c-format +msgid "" +"Save changes to document \"%s\" before " +"closing?\n" +"\n" +"If you close without saving, your changes will be discarded." +msgstr "" + +#: ../../po/../src/widgets/desktop-widget.cpp:548 +#: ../../po/../src/widgets/desktop-widget.cpp:612 +msgid "Close _without saving" +msgstr "" + +#: ../../po/../src/widgets/desktop-widget.cpp:595 +#, c-format +msgid "" +"The file \"%s\" was saved with a " +"format (%s) that may cause data loss!\n" +"\n" +"Do you want to save this file in another format?" +msgstr "" + +#. Family frame +#: ../../po/../src/widgets/font-selector.cpp:156 +msgid "Font family" +msgstr "" + +#. Style frame +#: ../../po/../src/widgets/font-selector.cpp:184 +#, fuzzy +msgid "Style" +msgstr " Estilo " + +#: ../../po/../src/widgets/font-selector.cpp:219 +msgid "Font size:" +msgstr "" + +#. TRANSLATORS: Test string used in text and font dialog (when no +#. * text has been entered) to get a preview of the font. Choose +#. * some representative characters that users of your locale will be +#. * interested in. +#: ../../po/../src/widgets/font-selector.cpp:554 +msgid "AaBbCcIiPpQq12368.;/()" +msgstr "" + +#: ../../po/../src/widgets/gradient-selector.cpp:137 +#: ../../po/../src/widgets/gradient-toolbar.cpp:524 +#, fuzzy +msgid "Duplicate" +msgstr "Duplicar" + +#: ../../po/../src/widgets/gradient-selector.cpp:142 +#: ../../po/../src/widgets/gradient-toolbar.cpp:535 +#, fuzzy +msgid "Edit..." +msgstr "Editar" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/pservers.html#LinearGradientSpreadMethodAttribute +#: ../../po/../src/widgets/gradient-selector.cpp:159 +msgid "" +"Whether to fill with flat color beyond the ends of the gradient vector " +"(spreadMethod=\"pad\"), or repeat the gradient in the same direction " +"(spreadMethod=\"repeat\"), or repeat the gradient in alternating opposite " +"directions (spreadMethod=\"reflect\")" +msgstr "" + +#: ../../po/../src/widgets/gradient-selector.cpp:165 +#, fuzzy +msgid "none" +msgstr "Ningun" + +#: ../../po/../src/widgets/gradient-selector.cpp:169 +#, fuzzy +msgid "reflected" +msgstr "Primeiro seleccionado" + +#: ../../po/../src/widgets/gradient-selector.cpp:173 +#, fuzzy +msgid "direct" +msgstr "Rectángulo" + +#: ../../po/../src/widgets/gradient-selector.cpp:181 +#, fuzzy +msgid "Repeat:" +msgstr "Reler" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:217 +msgid "No gradients" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:226 +#, fuzzy +msgid "Nothing selected" +msgstr "Último seleccionado" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:237 +#, fuzzy +msgid "No gradients in selection" +msgstr "Último seleccionado" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:247 +msgid "Multiple gradients" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:525 +msgid "" +"If the gradient is used by more than one object, create a copy of it for the " +"selected object(s)" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:536 +#, fuzzy +msgid "Edit the stops of the gradient" +msgstr "Engadir novo degradado" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:593 +#: ../../po/../src/widgets/toolbox.cpp:1103 +#: ../../po/../src/widgets/toolbox.cpp:1192 +#: ../../po/../src/widgets/toolbox.cpp:1485 +#: ../../po/../src/widgets/toolbox.cpp:1534 +#: ../../po/../src/widgets/toolbox.cpp:1766 +#: ../../po/../src/widgets/toolbox.cpp:1801 +#: ../../po/../src/widgets/toolbox.cpp:2331 +#: ../../po/../src/widgets/toolbox.cpp:2370 +msgid "New:" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:606 +#, fuzzy +msgid "Create linear gradient" +msgstr "Engadir novo degradado" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:620 +msgid "Create radial (elliptic or circular) gradient" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:635 +#, fuzzy +msgid "on" +msgstr "Ningun" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:648 +#, fuzzy +msgid "Create gradient in the fill" +msgstr "Degradado" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:662 +msgid "Create gradient in the stroke" +msgstr "" + +#. FIXME: implement averaging of all parameters for multiple selected stars +#. gtk_label_set_markup(GTK_LABEL(l), _("Average:")); +#. FIXME: implement averaging of all parameters for multiple selected +#. gtk_label_set_markup(GTK_LABEL(l), _("Average:")); +#: ../../po/../src/widgets/gradient-toolbar.cpp:676 +#: ../../po/../src/widgets/toolbox.cpp:1105 +#: ../../po/../src/widgets/toolbox.cpp:1124 +#: ../../po/../src/widgets/toolbox.cpp:1493 +#: ../../po/../src/widgets/toolbox.cpp:1518 +#: ../../po/../src/widgets/toolbox.cpp:1768 +#: ../../po/../src/widgets/toolbox.cpp:1787 +#: ../../po/../src/widgets/toolbox.cpp:2334 +#: ../../po/../src/widgets/toolbox.cpp:2354 +#, fuzzy +msgid "Change:" +msgstr "Cambiar" + +#: ../../po/../src/widgets/gradient-vector.cpp:269 +msgid "No gradients in document" +msgstr "" + +#: ../../po/../src/widgets/gradient-vector.cpp:275 +#, fuzzy +msgid "No gradient selected" +msgstr "Último seleccionado" + +#: ../../po/../src/widgets/gradient-vector.cpp:532 +#, fuzzy +msgid "No stops in gradient" +msgstr "Engadir novo degradado" + +#. TRANSLATORS: "Stop" means: a "phase" of a gradient +#: ../../po/../src/widgets/gradient-vector.cpp:794 +#, fuzzy +msgid "Add stop" +msgstr "escritorio" + +#: ../../po/../src/widgets/gradient-vector.cpp:797 +msgid "Add another control stop to gradient" +msgstr "" + +#: ../../po/../src/widgets/gradient-vector.cpp:799 +#, fuzzy +msgid "Delete stop" +msgstr "Borra-la selección" + +#: ../../po/../src/widgets/gradient-vector.cpp:802 +msgid "Delete current control stop from gradient" +msgstr "" + +#. Label +#: ../../po/../src/widgets/gradient-vector.cpp:813 +msgid "Offset:" +msgstr "" + +#. TRANSLATORS: "Stop" means: a "phase" of a gradient +#: ../../po/../src/widgets/gradient-vector.cpp:858 +#, fuzzy +msgid "Stop Color" +msgstr "Cor do trazado:" + +#: ../../po/../src/widgets/gradient-vector.cpp:887 +#, fuzzy +msgid "Gradient editor" +msgstr "Degradado" + +#: ../../po/../src/widgets/layer-selector.cpp:119 +#, fuzzy +msgid "Toggle current layer visibility" +msgstr "Documento" + +#: ../../po/../src/widgets/layer-selector.cpp:139 +#, fuzzy +msgid "Lock or unlock current layer" +msgstr "Documento" + +#: ../../po/../src/widgets/layer-selector.cpp:142 +#, fuzzy +msgid "Current layer" +msgstr "Documento" + +#: ../../po/../src/widgets/layer-selector.cpp:553 +msgid "(root)" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:182 +#: ../../po/../src/widgets/paint-selector.cpp:561 +#, fuzzy +msgid "No paint" +msgstr "Punto" + +#: ../../po/../src/widgets/paint-selector.cpp:184 +#: ../../po/../src/widgets/paint-selector.cpp:629 +#, fuzzy +msgid "Flat color" +msgstr "cor" + +#: ../../po/../src/widgets/paint-selector.cpp:186 +#: ../../po/../src/widgets/paint-selector.cpp:696 +#, fuzzy +msgid "Linear gradient" +msgstr "Engadir novo degradado" + +#: ../../po/../src/widgets/paint-selector.cpp:188 +#: ../../po/../src/widgets/paint-selector.cpp:699 +#, fuzzy +msgid "Radial gradient" +msgstr "Engadir novo degradado" + +#: ../../po/../src/widgets/paint-selector.cpp:192 +msgid "Unset paint (make it undefined so it can be inherited)" +msgstr "" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/painting.html#FillRuleProperty +#: ../../po/../src/widgets/paint-selector.cpp:204 +msgid "" +"Any path self-intersections or subpaths create holes in the fill (fill-rule: " +"evenodd)" +msgstr "" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/painting.html#FillRuleProperty +#: ../../po/../src/widgets/paint-selector.cpp:215 +msgid "" +"Fill is solid unless a subpath is counterdirectional (fill-rule: nonzero)" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:528 +#, fuzzy +msgid "No objects" +msgstr "Obxecto texto" + +#: ../../po/../src/widgets/paint-selector.cpp:539 +msgid "Multiple styles" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:550 +msgid "Paint is undefined" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:757 +#, fuzzy +msgid "No patterns in document" +msgstr "Documento" + +#: ../../po/../src/widgets/paint-selector.cpp:872 +msgid "" +"Use Edit > Object(s) to Pattern to create a new pattern from " +"selection." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:426 +msgid "Now stroke width is scaled when objects are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:428 +msgid "Now stroke width is not scaled when objects are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:436 +msgid "" +"Now rounded rectangle corners are scaled when rectangles are " +"scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:438 +msgid "" +"Now rounded rectangle corners are not scaled when rectangles " +"are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:446 +msgid "" +"Now gradients are transformed along with their objects when " +"those are transformed (moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:448 +msgid "" +"Now gradients remain fixed when objects are transformed " +"(moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:456 +msgid "" +"Now patterns are transformed along with their objects when " +"those are transformed (moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:458 +msgid "" +"Now patterns remain fixed when objects are transformed (moved, " +"scaled, rotated, or skewed)." +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:506 +#, fuzzy +msgid "select_toolbar|X" +msgstr "Seleccionar" + +#: ../../po/../src/widgets/select-toolbar.cpp:506 +#, fuzzy +msgid "Horizontal coordinate of selection" +msgstr "Valor de centrado horizontal" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:511 +#, fuzzy +msgid "select_toolbar|Y" +msgstr "Seleccionar" + +#: ../../po/../src/widgets/select-toolbar.cpp:511 +msgid "Vertical coordinate of selection" +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:517 +#, fuzzy +msgid "select_toolbar|W" +msgstr "Seleccionar" + +#: ../../po/../src/widgets/select-toolbar.cpp:517 +#, fuzzy +msgid "Width of selection" +msgstr "Corta-la selección" + +#: ../../po/../src/widgets/select-toolbar.cpp:525 +msgid "Change both width and height by the same proportion" +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:534 +#, fuzzy +msgid "select_toolbar|H" +msgstr "Seleccionar" + +#: ../../po/../src/widgets/select-toolbar.cpp:534 +#, fuzzy +msgid "Height of selection" +msgstr "Zoom á selección" + +#: ../../po/../src/widgets/sp-color-gtkselector.cpp:62 +msgid "System" +msgstr "" + +#: ../../po/../src/widgets/sp-color-notebook.cpp:322 +msgid "RGBA_:" +msgstr "" + +#: ../../po/../src/widgets/sp-color-notebook.cpp:330 +msgid "Hexadecimal RGBA value of the color" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "RGB" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "HSL" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "CMYK" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:397 +msgid "_R" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:398 +#: ../../po/../src/widgets/sp-color-scales.cpp:399 +#, fuzzy +msgid "Red" +msgstr "Vermello:" + +#: ../../po/../src/widgets/sp-color-scales.cpp:400 +msgid "_G" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:401 +#: ../../po/../src/widgets/sp-color-scales.cpp:402 +#, fuzzy +msgid "Green" +msgstr "Verde:" + +#: ../../po/../src/widgets/sp-color-scales.cpp:403 +msgid "_B" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:404 +#: ../../po/../src/widgets/sp-color-scales.cpp:405 +#, fuzzy +msgid "Blue" +msgstr "Azul:" + +#. Label +#: ../../po/../src/widgets/sp-color-scales.cpp:406 +#: ../../po/../src/widgets/sp-color-scales.cpp:432 +#: ../../po/../src/widgets/sp-color-scales.cpp:463 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:141 +msgid "_A" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:407 +#: ../../po/../src/widgets/sp-color-scales.cpp:408 +#: ../../po/../src/widgets/sp-color-scales.cpp:433 +#: ../../po/../src/widgets/sp-color-scales.cpp:434 +#: ../../po/../src/widgets/sp-color-scales.cpp:464 +#: ../../po/../src/widgets/sp-color-scales.cpp:465 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:151 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:163 +msgid "Alpha (opacity)" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:423 +msgid "_H" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:424 +#: ../../po/../src/widgets/sp-color-scales.cpp:425 +#, fuzzy +msgid "Hue" +msgstr "Azul:" + +#: ../../po/../src/widgets/sp-color-scales.cpp:426 +msgid "_S" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:427 +#: ../../po/../src/widgets/sp-color-scales.cpp:428 +msgid "Saturation" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:429 +msgid "_L" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:430 +#: ../../po/../src/widgets/sp-color-scales.cpp:431 +#, fuzzy +msgid "Lightness" +msgstr "Alto" + +#: ../../po/../src/widgets/sp-color-scales.cpp:451 +msgid "_C" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:452 +#: ../../po/../src/widgets/sp-color-scales.cpp:453 +#, fuzzy +msgid "Cyan" +msgstr " Tapa " + +#: ../../po/../src/widgets/sp-color-scales.cpp:454 +msgid "_M" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:455 +#: ../../po/../src/widgets/sp-color-scales.cpp:456 +msgid "Magenta" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:457 +msgid "_Y" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:458 +#: ../../po/../src/widgets/sp-color-scales.cpp:459 +msgid "Yellow" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:460 +msgid "_K" +msgstr "" + +#: ../../po/../src/widgets/sp-color-selector.cpp:71 +#, fuzzy +msgid "Unnamed" +msgstr "nome" + +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:68 +msgid "Wheel" +msgstr "" + +#: ../../po/../src/widgets/sp-xmlview-attr-list.cpp:53 +#, fuzzy +msgid "Attribute" +msgstr "Atributos" + +#: ../../po/../src/widgets/sp-xmlview-attr-list.cpp:54 +msgid "Value" +msgstr "Valor" + +#: ../../po/../src/widgets/toolbox.cpp:424 +#, fuzzy +msgid "Insert new nodes into selected segments" +msgstr "Incluir un nodo nos segmentos seleccionados" + +#: ../../po/../src/widgets/toolbox.cpp:426 +msgid "Delete selected nodes" +msgstr "Borra-los nodos seleccionados" + +#: ../../po/../src/widgets/toolbox.cpp:431 +#, fuzzy +msgid "Join paths at selected nodes" +msgstr "Suaviza-la liña nos nodos seleccionados" + +#: ../../po/../src/widgets/toolbox.cpp:433 +#, fuzzy +msgid "Join paths at selected nodes with new segment" +msgstr "Suaviza-la liña nos nodos seleccionados" + +#: ../../po/../src/widgets/toolbox.cpp:436 +msgid "Split path between two non-endpoint nodes" +msgstr "" + +# [*] Mirar +#: ../../po/../src/widgets/toolbox.cpp:439 +#, fuzzy +msgid "Break path at selected nodes" +msgstr "Fragmenta-lo nodo seleccionado" + +#: ../../po/../src/widgets/toolbox.cpp:444 +#, fuzzy +msgid "Make selected nodes corner" +msgstr "Borra-los nodos seleccionados" + +#: ../../po/../src/widgets/toolbox.cpp:447 +#, fuzzy +msgid "Make selected nodes smooth" +msgstr "Borra-los nodos seleccionados" + +#: ../../po/../src/widgets/toolbox.cpp:450 +#, fuzzy +msgid "Make selected nodes symmetric" +msgstr "Borra-los nodos seleccionados" + +#: ../../po/../src/widgets/toolbox.cpp:455 +#, fuzzy +msgid "Make selected segments lines" +msgstr "Converti-los segmentos seleccionados a liñas" + +#: ../../po/../src/widgets/toolbox.cpp:458 +#, fuzzy +msgid "Make selected segments curves" +msgstr "Converti-los segmentos seleccionados a curvas" + +#: ../../po/../src/widgets/toolbox.cpp:1199 +msgid "Polygon" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1206 +msgid "Regular polygon (with one handle) instead of a star" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1218 +msgid "Corners:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1218 +msgid "Number of corners of a polygon or star" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1228 +#, fuzzy +msgid "Spoke ratio:" +msgstr "Bloquea-la relación de aspecto" + +#. TRANSLATORS: Tip radius of a star is the distance from the center to the farthest handle. +#. Base radius is the same for the closest handle. +#: ../../po/../src/widgets/toolbox.cpp:1231 +msgid "Base radius to tip radius ratio" +msgstr "" + +# [*] Revisar +#: ../../po/../src/widgets/toolbox.cpp:1246 +#, fuzzy +msgid "Rounded:" +msgstr "Redondear puntos finais" + +#: ../../po/../src/widgets/toolbox.cpp:1246 +msgid "How much rounded are the corners (0 for sharp)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1256 +msgid "Randomized:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1256 +msgid "Scatter randomly the corners and angles" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1269 +#: ../../po/../src/widgets/toolbox.cpp:1838 +#: ../../po/../src/widgets/toolbox.cpp:2061 +msgid "Defaults" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1270 +#: ../../po/../src/widgets/toolbox.cpp:1839 +#: ../../po/../src/widgets/toolbox.cpp:2062 +msgid "" +"Reset shape parameters to defaults (use Inkscape Preferences > Tools to " +"change defaults)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1544 +msgid "W:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1544 +#, fuzzy +msgid "Width of rectangle" +msgstr "Corta-la selección" + +#: ../../po/../src/widgets/toolbox.cpp:1556 +#, fuzzy +msgid "Height of rectangle" +msgstr "Zoom á selección" + +#: ../../po/../src/widgets/toolbox.cpp:1568 +#, fuzzy +msgid "Rx:" +msgstr "1:1" + +#: ../../po/../src/widgets/toolbox.cpp:1568 +#, fuzzy +msgid "Horizontal radius of rounded corners" +msgstr "Valor de centrado horizontal" + +#: ../../po/../src/widgets/toolbox.cpp:1578 +#, fuzzy +msgid "Ry:" +msgstr "1:1" + +#: ../../po/../src/widgets/toolbox.cpp:1578 +#, fuzzy +msgid "Vertical radius of rounded corners" +msgstr "Valor de centrado horizontal" + +#: ../../po/../src/widgets/toolbox.cpp:1594 +#, fuzzy +msgid "Not rounded" +msgstr "redondear" + +#: ../../po/../src/widgets/toolbox.cpp:1596 +msgid "Make corners sharp" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1805 +#, fuzzy +msgid "Turns:" +msgstr "Transformación" + +#: ../../po/../src/widgets/toolbox.cpp:1805 +msgid "Number of revolutions" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1815 +#, fuzzy +msgid "Divergence:" +msgstr "Grado" + +#: ../../po/../src/widgets/toolbox.cpp:1815 +msgid "How much denser/sparser are outer revolutions; 1 = uniform" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1825 +msgid "Inner radius:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1825 +msgid "Radius of the innermost revolution (relative to the spiral size)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1957 +msgid "The width of the calligraphic pen (relative to the visible canvas area)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1967 +#, fuzzy +msgid "Thinning:" +msgstr "Renderizado" + +#: ../../po/../src/widgets/toolbox.cpp:1967 +msgid "" +"How much velocity thins the stroke (> 0 makes fast strokes thinner, < 0 " +"makes them broader, 0 makes width independent of velocity)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1980 +#, fuzzy +msgid "Angle:" +msgstr "ángulo" + +#: ../../po/../src/widgets/toolbox.cpp:1980 +msgid "" +"The angle of the pen's nib (in degrees; 0 = horizontal; has no effect if " +"fixation = 0)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1990 +msgid "Fixation:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1990 +msgid "" +"How fixed is the pen angle (0 = always perpendicular to stroke direction, 1 " +"= fixed)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2003 +msgid "Mass:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2003 +msgid "How much inertia affects the movement of the pen" +msgstr "" + +#. TRANSLATORS: "drag" means "resistance" here +#: ../../po/../src/widgets/toolbox.cpp:2014 +#, fuzzy +msgid "Drag:" +msgstr "Debuxar" + +#: ../../po/../src/widgets/toolbox.cpp:2014 +msgid "How much resistance affects the movement of the pen" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2034 +msgid "Use the pressure of the input device to alter the width of the pen" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2047 +msgid "Use the tilt of the input device to alter the angle of the pen's nib" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2374 +#, fuzzy +msgid "Start:" +msgstr "Trazo" + +#: ../../po/../src/widgets/toolbox.cpp:2374 +msgid "The angle (in degrees) from the horizontal to the arc's start point" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2384 +msgid "End:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2384 +msgid "The angle (in degrees) from the horizontal to the arc's end point" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2395 +#, fuzzy +msgid "Open arc" +msgstr "_Abrir" + +#: ../../po/../src/widgets/toolbox.cpp:2396 +msgid "" +"Switch between arc (unclosed shape) and segment (closed shape with two radii)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2415 +msgid "Make whole" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2417 +msgid "Make the shape a whole ellipse, not arc or segment" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2644 +msgid "" +"When pressed, picks visible color without alpha and when not pressed, picks " +"color including its alpha" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:3039 +#, fuzzy +msgid "Make connectors avoid selected objects" +msgstr "Borra-los nodos seleccionados" + +#: ../../po/../src/widgets/toolbox.cpp:3043 +#, fuzzy +msgid "Make connectors ignore selected objects" +msgstr "Borra-los nodos seleccionados" + +#. +#. 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 : +#: ../share/extensions/addnodes.inx.h:1 +#, fuzzy +msgid "Add Nodes" +msgstr "Nodos" + +#: ../share/extensions/addnodes.inx.h:2 +msgid "Maximum Segment Length" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:1 +msgid "AI Input" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:2 ../share/extensions/ai_output.inx.h:2 +msgid "Adobe Illustrator (*.ai)" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:3 +msgid "Open files saved with Adobe Illustrator" +msgstr "" + +#: ../share/extensions/ai_output.inx.h:1 +#, fuzzy +msgid "AI Output" +msgstr "Cortar" + +#: ../share/extensions/ai_output.inx.h:3 +msgid "Write Adobe Illustrator" +msgstr "" + +#: ../share/extensions/dia.inx.h:1 +msgid "A diagram created with the program Dia" +msgstr "" + +#: ../share/extensions/dia.inx.h:2 +msgid "Dia Diagram (*.dia)" +msgstr "" + +#: ../share/extensions/dia.inx.h:3 +msgid "Dia Input" +msgstr "" + +#: ../share/extensions/dia.inx.h:4 +msgid "" +"In order to import Dia files, Dia itself must be installed. You can get Dia " +"at http://www.gnome.org/projects/dia/" +msgstr "" + +#: ../share/extensions/dia.inx.h:5 +msgid "" +"The dia2svg.sh script should be installed with your Inkscape distribution. " +"If you do not have it, there is likely to be something wrong with your " +"Inkscape installation." +msgstr "" + +#: ../share/extensions/dots.inx.h:1 +#, fuzzy +msgid "Connect the Dots" +msgstr "Nova vista" + +#: ../share/extensions/dots.inx.h:2 +#, fuzzy +msgid "Dot Size" +msgstr "Guías" + +#: ../share/extensions/dots.inx.h:3 +#, fuzzy +msgid "Font Size" +msgstr "Guías" + +#: ../share/extensions/dropshadow.inx.h:1 +msgid "Color of shadow" +msgstr "" + +#: ../share/extensions/dropshadow.inx.h:2 +msgid "Dropshadow" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:1 +#: ../share/extensions/dxf_output.inx.h:1 +msgid "AutoCAD DXF (*.dxf)" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:2 +msgid "DXF Input" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:3 +msgid "Import AutoCAD's Document Exchange Format" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:4 +msgid "" +"dxf2svg may come with Inkscape, but is also at http://dxf-svg-convert." +"sourceforge.net/" +msgstr "" + +#: ../share/extensions/dxf_output.inx.h:2 +#, fuzzy +msgid "DXF Output" +msgstr "Cortar" + +#: ../share/extensions/dxf_output.inx.h:3 +msgid "DXF file written by pstoedit" +msgstr "" + +#: ../share/extensions/dxf_output.inx.h:4 +msgid "pstoedit must be installed to run see http://www.pstoedit.net/pstoedit" +msgstr "" + +#: ../share/extensions/embedimage.inx.h:1 +#, fuzzy +msgid "Embed Images" +msgstr "Tamaño da imaxe" + +#: ../share/extensions/eps_input.inx.h:1 +msgid "EPS Input" +msgstr "" + +#: ../share/extensions/eps_input.inx.h:2 +msgid "Encapsulated Postscript" +msgstr "" + +#: ../share/extensions/eps_input.inx.h:3 +msgid "Encapsulated Postscript (*.eps)" +msgstr "" + +#: ../share/extensions/epsi_output.inx.h:1 +#, fuzzy +msgid "EPSI Output" +msgstr "Cortar" + +#: ../share/extensions/epsi_output.inx.h:2 +msgid "Encapsulated Postscript Interchange (*.epsi)" +msgstr "" + +#: ../share/extensions/epsi_output.inx.h:3 +msgid "Encapsulated Postscript with a thumbnail" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:1 ../share/extensions/ffms.inx.h:1 +#: ../share/extensions/ffset.inx.h:1 ../share/extensions/ffss.inx.h:1 +#, fuzzy +msgid "Bridge Width" +msgstr " Ancho " + +#: ../share/extensions/ffmet.inx.h:2 ../share/extensions/ffms.inx.h:2 +msgid "First String Length" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:3 +msgid "FretFind Multi Length ET" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:4 ../share/extensions/ffms.inx.h:4 +#: ../share/extensions/ffset.inx.h:3 ../share/extensions/ffss.inx.h:3 +msgid "Fretboard Edges" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:5 ../share/extensions/ffms.inx.h:5 +msgid "Last String Length" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:6 ../share/extensions/ffms.inx.h:6 +#: ../share/extensions/ffset.inx.h:4 ../share/extensions/ffss.inx.h:4 +msgid "Number of Frets" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:7 ../share/extensions/ffms.inx.h:7 +#: ../share/extensions/ffset.inx.h:5 ../share/extensions/ffss.inx.h:5 +msgid "Number of Strings" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:8 ../share/extensions/ffms.inx.h:8 +#: ../share/extensions/ffset.inx.h:6 ../share/extensions/ffss.inx.h:6 +#, fuzzy +msgid "Nut Width" +msgstr "Ancho" + +#: ../share/extensions/ffmet.inx.h:9 ../share/extensions/ffms.inx.h:10 +msgid "Perpendicular Distance" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:10 ../share/extensions/ffset.inx.h:7 +msgid "Scale Base (2 for Octave)" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:11 ../share/extensions/ffset.inx.h:9 +msgid "Tones in Scale" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:12 ../share/extensions/ffms.inx.h:12 +#: ../share/extensions/ffset.inx.h:10 ../share/extensions/ffss.inx.h:10 +msgid "px per Unit" +msgstr "" + +#: ../share/extensions/ffms.inx.h:3 +msgid "FretFind Multi Length Scala" +msgstr "" + +#: ../share/extensions/ffms.inx.h:9 ../share/extensions/ffss.inx.h:7 +msgid "Path to Scala *.scl File" +msgstr "" + +#: ../share/extensions/ffms.inx.h:11 +msgid "Tuning (scale step for each string seperated by semicolons)" +msgstr "" + +#: ../share/extensions/ffset.inx.h:2 +msgid "FretFind Single Length ET" +msgstr "" + +#: ../share/extensions/ffset.inx.h:8 ../share/extensions/ffss.inx.h:8 +msgid "Scale Length" +msgstr "" + +#: ../share/extensions/ffss.inx.h:2 +msgid "FretFind Single Length Scala" +msgstr "" + +#: ../share/extensions/ffss.inx.h:9 +msgid "Tuning (Scale step for each string seperated by semicolons)" +msgstr "" + +#: ../share/extensions/handles.inx.h:1 +#, fuzzy +msgid "Draw Handles" +msgstr "Debuxar liña a man alzada" + +#: ../share/extensions/interp.inx.h:1 +#, fuzzy +msgid "Duplicate Endpaths" +msgstr "Duplicar" + +#: ../share/extensions/interp.inx.h:2 +#, fuzzy +msgid "Exponent" +msgstr "Exportar" + +#: ../share/extensions/interp.inx.h:3 +msgid "Interpolate" +msgstr "" + +#: ../share/extensions/interp.inx.h:4 +msgid "Interpolate Style (Experimental)" +msgstr "" + +#: ../share/extensions/interp.inx.h:5 +msgid "Interpolation Method" +msgstr "" + +#: ../share/extensions/interp.inx.h:6 +msgid "Interpolation Steps" +msgstr "" + +#: ../share/extensions/kochify.inx.h:1 +msgid "Kochify" +msgstr "" + +#: ../share/extensions/kochify_load.inx.h:1 +msgid "Kochify (Load)" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:1 +#, fuzzy +msgid "Angle" +msgstr "ángulo" + +#: ../share/extensions/lindenmayer.inx.h:2 +msgid "Axiom" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:3 +#, fuzzy +msgid "Lindenmayer" +msgstr "Pegar" + +#: ../share/extensions/lindenmayer.inx.h:4 +msgid "Order" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:5 +#, fuzzy +msgid "Rules" +msgstr "Ficheiro" + +#: ../share/extensions/lindenmayer.inx.h:6 +#, fuzzy +msgid "Step" +msgstr " Estilo " + +#: ../share/extensions/motion.inx.h:1 +#, fuzzy +msgid "Direction" +msgstr "Posición" + +#: ../share/extensions/motion.inx.h:2 +msgid "Magnitude" +msgstr "" + +#: ../share/extensions/motion.inx.h:3 +#, fuzzy +msgid "Motion" +msgstr "Selección" + +#: ../share/extensions/pdf_output.inx.h:1 +msgid "Adobe PDF (*.pdf)" +msgstr "" + +#: ../share/extensions/pdf_output.inx.h:2 +msgid "Adobe Portable Document Format" +msgstr "" + +#: ../share/extensions/pdf_output.inx.h:3 +#, fuzzy +msgid "PDF Output" +msgstr "Cortar" + +#: ../share/extensions/ps_input.inx.h:1 +#, fuzzy +msgid "Postscript" +msgstr "Punto" + +#: ../share/extensions/ps_input.inx.h:2 +msgid "Postscript (*.ps)" +msgstr "" + +#: ../share/extensions/ps_input.inx.h:3 +msgid "Postscript Input" +msgstr "" + +#: ../share/extensions/radiusrand.inx.h:1 +#, fuzzy +msgid "Radius" +msgstr "Pegar" + +#: ../share/extensions/radiusrand.inx.h:2 +#, fuzzy +msgid "Radius Randomize" +msgstr "Pegar" + +#: ../share/extensions/radiusrand.inx.h:3 +msgid "Randomize Control Points" +msgstr "" + +#: ../share/extensions/radiusrand.inx.h:4 +#, fuzzy +msgid "Randomize Nodes" +msgstr "Pegar" + +#: ../share/extensions/rtree.inx.h:1 +#, fuzzy +msgid "Initial Size" +msgstr "Tamaño da imaxe" + +#: ../share/extensions/rtree.inx.h:2 +msgid "Minimum Size" +msgstr "" + +#: ../share/extensions/rtree.inx.h:3 +msgid "Random Tree" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:1 +msgid "A diagram created with the program Sketch" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:2 +msgid "Sketch Diagram (*.sk)" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:3 +msgid "Sketch Input" +msgstr "" + +#: ../share/extensions/straightseg.inx.h:1 +msgid "Behavior" +msgstr "" + +#: ../share/extensions/straightseg.inx.h:3 +msgid "Segment Straightener" +msgstr "" + +#: ../share/extensions/summersnight.inx.h:1 +msgid "Summer's Night" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:1 +#: ../share/extensions/svgz_output.inx.h:1 +#, fuzzy +msgid "Compressed Inkscape SVG (*.svgz)" +msgstr "Tamaño do ficheiro sen comprimir:" + +#: ../share/extensions/svgz_input.inx.h:2 +#: ../share/extensions/svgz_output.inx.h:2 +msgid "Inkscape's native file format compressed with GZip" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:3 +msgid "SVGZ Input" +msgstr "" + +#: ../share/extensions/svgz_output.inx.h:3 +#, fuzzy +msgid "SVGZ Output" +msgstr "Cortar" + +#: ../share/extensions/txt2svg.inx.h:1 +msgid "ASCII Text" +msgstr "" + +#: ../share/extensions/txt2svg.inx.h:2 +msgid "Text File (*.txt)" +msgstr "" + +#: ../share/extensions/txt2svg.inx.h:3 +#, fuzzy +msgid "Text Input" +msgstr "Texto" + +#: ../share/extensions/wavy.inx.h:1 +msgid "Calculate first derivative numerically" +msgstr "" + +#: ../share/extensions/wavy.inx.h:2 +msgid "First derivative" +msgstr "" + +#: ../share/extensions/wavy.inx.h:3 +msgid "Function" +msgstr "" + +#: ../share/extensions/wavy.inx.h:4 +msgid "Function Plotter" +msgstr "" + +#: ../share/extensions/wavy.inx.h:5 +msgid "Nodes per period" +msgstr "" + +#: ../share/extensions/wavy.inx.h:6 +msgid "Periods (2*Pi each)" +msgstr "" + +#: ../share/extensions/whirl.inx.h:1 +msgid "Amount of Whirl" +msgstr "" + +#: ../share/extensions/whirl.inx.h:2 +#, fuzzy +msgid "Center X" +msgstr "Centrar" + +#: ../share/extensions/whirl.inx.h:3 +#, fuzzy +msgid "Center Y" +msgstr "Centrar" + +#: ../share/extensions/whirl.inx.h:4 +#, fuzzy +msgid "Direction of Rotation" +msgstr "Baixa-la selección ó fondo" + +#: ../share/extensions/whirl.inx.h:5 +msgid "Whirl" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:1 +msgid "A popular graphics file format for clipart" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:2 +msgid "Windows Metafile (*.wmf)" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:3 +msgid "Windows Metafile Input" +msgstr "" + +#, fuzzy +#~ msgid "Custom canvas" +#~ msgstr "Papel Persoalizado" + +#, fuzzy +#~ msgid "Current style" +#~ msgstr "Configuración do escritorio" + +#, fuzzy +#~ msgid "Arrange Objects" +#~ msgstr "Obxecto" + +#~ msgid "deg" +#~ msgstr "grado" + +#, fuzzy +#~ msgid "_Credits" +#~ msgstr "Bitmap a cor" + +#, fuzzy +#~ msgid "Grab sensitivity" +#~ msgstr "Facer sensible" + +#, fuzzy +#~ msgid "Acceleration" +#~ msgstr "Selección" + +#, fuzzy +#~ msgid "Speed" +#~ msgstr "Vermello:" + +#, fuzzy +#~ msgid "Zoom in/out by" +#~ msgstr "Zoom fora" + +#, fuzzy +#~ msgid "Transform" +#~ msgstr "Transformación" + +#, fuzzy +#~ msgid "Rotate _90 deg CW" +#~ msgstr "Poñe-lo ángulo a 90°" + +#, fuzzy +#~ msgid "Rotate 9_0 deg CCW" +#~ msgstr "Poñe-lo ángulo a 90°" + +# [*] Revisar +#, fuzzy +#~ msgid "Flip selection horizontally" +#~ msgstr "Voltea-los obxectos seleccionados" + +# [*] Revisar +#, fuzzy +#~ msgid "Flip selection vertically" +#~ msgstr "Voltea-los obxectos seleccionados" + +#~ msgid "Edit" +#~ msgstr "Editar" + +#~ msgid "Add" +#~ msgstr "Engadir" + +#, fuzzy +#~ msgid "C_reate" +#~ msgstr "Centrar" + +#, fuzzy +#~ msgid "Automatically scale Rows to fit selected objects." +#~ msgstr "Edita-lo estilo de recheo dos obxectos seleccionados" + +#, fuzzy +#~ msgid "Automatically scale Columns to fit selected objects." +#~ msgstr "Edita-lo estilo de recheo dos obxectos seleccionados" + +#, fuzzy +#~ msgid "Go to root" +#~ msgstr "Editar nodos" + +#, fuzzy +#~ msgid "X" +#~ msgstr "X1" + +#, fuzzy +#~ msgid "Y" +#~ msgstr "Y1" + +#, fuzzy +#~ msgid " " +#~ msgstr "X +" + +#, fuzzy +#~ msgid "Sides:" +#~ msgstr "Guías" + +#, fuzzy +#~ msgid "R1:" +#~ msgstr "1:1" + +#, fuzzy +#~ msgid "R2:" +#~ msgstr "2:1" + +#, fuzzy +#~ msgid "Flatsides:" +#~ msgstr "Guías" + +#, fuzzy +#~ msgid "Start Angle:" +#~ msgstr "Trazo" + +#, fuzzy +#~ msgid "End Angle:" +#~ msgstr "ángulo" + +#, fuzzy +#~ msgid "Open:" +#~ msgstr "_Abrir" + +#, fuzzy +#~ msgid "Revolutions:" +#~ msgstr "Selección" + +#, fuzzy +#~ msgid "RX:" +#~ msgstr "X:" + +#, fuzzy +#~ msgid "RY:" +#~ msgstr "Y:" + +#, fuzzy +#~ msgid "Rectangle _Properties" +#~ msgstr "Propiedades do texto" + +#, fuzzy +#~ msgid "Star _Properties" +#~ msgstr "Propiedades do texto" + +#, fuzzy +#~ msgid "Ellipse _Properties" +#~ msgstr "Propiedades do elemento" + +#, fuzzy +#~ msgid "Spiral _Properties" +#~ msgstr "Propiedades do texto" + +#, fuzzy +#~ msgid "Document Preferences" +#~ msgstr "O elemento é de referencia" + +#, fuzzy +#~ msgid "Extensions Editor" +#~ msgstr "Configura-las dimensións" + +#, fuzzy +#~ msgid "Preferences" +#~ msgstr "O elemento é de referencia" + +#, fuzzy +#~ msgid "Layer Editor" +#~ msgstr "Eleva-la selección ó tope" + +#, fuzzy +#~ msgid "Text Properties" +#~ msgstr "Propiedades do texto" + +#, fuzzy +#~ msgid "Transformation" +#~ msgstr "Transformación" + +#, fuzzy +#~ msgid "_Export..." +#~ msgstr "Importar" + +#, fuzzy +#~ msgid "_Document Properties" +#~ msgstr "Configuración do documento" + +#, fuzzy +#~ msgid "In_kscape Preferences" +#~ msgstr "Sodipodi" + +#, fuzzy +#~ msgid "Select _Original Clone" +#~ msgstr "Seleccionar" + +#, fuzzy +#~ msgid "Tile" +#~ msgstr "Ficheiro" + +#, fuzzy +#~ msgid "Select A_ll" +#~ msgstr "Seleccionar" + +#, fuzzy +#~ msgid "Select Non_e" +#~ msgstr "Selección" + +#, fuzzy +#~ msgid "Zoom _In" +#~ msgstr "Zoom dentro" + +#, fuzzy +#~ msgid "Zoom _Out" +#~ msgstr "Zoom fora" + +#, fuzzy +#~ msgid "Pre_vious" +#~ msgstr "Pecha-lo formulario" + +#, fuzzy +#~ msgid "Nex_t" +#~ msgstr "Texto" + +#, fuzzy +#~ msgid "Tool Co_ntrols bar" +#~ msgstr "Opcións de Oaf" + +#, fuzzy +#~ msgid "R_ename Layer..." +#~ msgstr "Pegar" + +#, fuzzy +#~ msgid "D_uplicate Layer" +#~ msgstr "Duplicar" + +#, fuzzy +#~ msgid "_Delete Layer" +#~ msgstr "Seleccionar" + +#, fuzzy +#~ msgid "Select Ne_xt Layer" +#~ msgstr "Seleccionar" + +#, fuzzy +#~ msgid "Select Pre_vious Layer" +#~ msgstr "Selección" + +#, fuzzy +#~ msgid "Select To_p Layer" +#~ msgstr "Selección" + +#, fuzzy +#~ msgid "Move to Ne_w Layer" +#~ msgstr "Documento" + +#, fuzzy +#~ msgid "Move to B_ottom Layer" +#~ msgstr "Baixa-la selección ó fondo" + +#, fuzzy +#~ msgid "_Trace Bitmap..." +#~ msgstr "Bitmap roto" + +#, fuzzy +#~ msgid "_Put Text on Path" +#~ msgstr "Converti-los obxectos seleccionados a curvas" + +#, fuzzy +#~ msgid "_Remove Text from Path" +#~ msgstr "Converti-los obxectos seleccionados a curvas" + +#, fuzzy +#~ msgid "Freehand" +#~ msgstr "Man alzada" + +#, fuzzy +#~ msgid "DynaDraw" +#~ msgstr "Debuxar" + +#~ msgid "Stroke" +#~ msgstr "Trazo" + +#, fuzzy +#~ msgid "Corners" +#~ msgstr "Nova vista" + +#, fuzzy +#~ msgid "Delete" +#~ msgstr "Borrar" + +#, fuzzy +#~ msgid "Join" +#~ msgstr "Xuntar:" + +#, fuzzy +#~ msgid "Delete Segment" +#~ msgstr "Duplica-la selección" + +#, fuzzy +#~ msgid "Break" +#~ msgstr "_Romper aparte" + +#, fuzzy +#~ msgid "Symmetric" +#~ msgstr "Asimétrico" + +#, fuzzy +#~ msgid "Line" +#~ msgstr " Liña " + +#~ msgid "New" +#~ msgstr "Novo" + +#, fuzzy +#~ msgid "Revert to Saved" +#~ msgstr "Convertir a Cu_rvas" + +#, fuzzy +#~ msgid "Save" +#~ msgstr "Peza" + +#, fuzzy +#~ msgid "Save As..." +#~ msgstr "Garda-lo ficheiro" + +#, fuzzy +#~ msgid "Import..." +#~ msgstr "Importar" + +#, fuzzy +#~ msgid "Export..." +#~ msgstr "Exportar" + +#, fuzzy +#~ msgid "Print..." +#~ msgstr "Punto" + +#, fuzzy +#~ msgid "Global Inkscape preferences (Shift+Ctrl+P)" +#~ msgstr "Configuración da visualización" + +#, fuzzy +#~ msgid "Undo" +#~ msgstr "Desfacer " + +#, fuzzy +#~ msgid "Redo" +#~ msgstr "Refacer" + +#, fuzzy +#~ msgid "Cut" +#~ msgstr "Cortar" + +#, fuzzy +#~ msgid "Copy" +#~ msgstr "Copiar" + +# [*] Revisar +#, fuzzy +#~ msgid "Duplicate selected object(s) (Ctrl+D)" +#~ msgstr "Voltea-los obxectos seleccionados" + +# [*] Revisar +#, fuzzy +#~ msgid "Clone selected object (Alt+D)" +#~ msgstr "Voltea-los obxectos seleccionados" + +#, fuzzy +#~ msgid "Zoom in (+)" +#~ msgstr "Zoom dentro" + +#, fuzzy +#~ msgid "Zoom out (-)" +#~ msgstr "Zoom fora" + +#, fuzzy +#~ msgid "Zoom to 1:1 (100%) (1)" +#~ msgstr "Zoom a 1:1" + +#, fuzzy +#~ msgid "Zoom to 1:2 (50%) (2)" +#~ msgstr "Zoom a 1:1" + +#, fuzzy +#~ msgid "Zoom to 2:1 (200%) (0)" +#~ msgstr "Zoom a 1:1" + +#, fuzzy +#~ msgid "Zoom to fit selection in window (3)" +#~ msgstr "Eleva-la selección ó tope" + +#, fuzzy +#~ msgid "Zoom to fit drawing in window (4)" +#~ msgstr "Zoom ó debuxo" + +#, fuzzy +#~ msgid "Zoom to fit page in window (5)" +#~ msgstr "Configura-lo ancho da páxina" + +#, fuzzy +#~ msgid "Zoom to fit page width in window (6)" +#~ msgstr "Configura-lo ancho da páxina" + +#, fuzzy +#~ msgid "Fill and Stroke dialog (Shift+Ctrl+F)" +#~ msgstr "Configuración do escritorio" + +#, fuzzy +#~ msgid "Group selected objects (Ctrl+G)" +#~ msgstr "Agrupa-los obxectos seleccionados" + +#, fuzzy +#~ msgid "Ungroup selected group(s) (Ctrl+U)" +#~ msgstr "Desagrupa-los obxectos seleccionados" + +#, fuzzy +#~ msgid "Raise selection up one step (PgUp)" +#~ msgstr "Eleva-la selección unha capa" + +#, fuzzy +#~ msgid "Lower selection down one step (PgDn)" +#~ msgstr "Baixa-la selección unha capa" + +#, fuzzy +#~ msgid "Raise selection to top (Home)" +#~ msgstr "Eleva-la selección ó tope" + +#, fuzzy +#~ msgid "Lower selection to bottom (End)" +#~ msgstr "Baixa-la selección ó fondo" + +#, fuzzy +#~ msgid "Move selection to new layer" +#~ msgstr "Baixa-la selección unha capa" + +#, fuzzy +#~ msgid "Move selection to next layer" +#~ msgstr "Baixa-la selección unha capa" + +#, fuzzy +#~ msgid "Move selection to previous layer" +#~ msgstr "Copia-la selección ó portarretallos" + +#, fuzzy +#~ msgid "Move selection to top layer" +#~ msgstr "Eleva-la selección ó tope" + +#, fuzzy +#~ msgid "Move selection to bottom layer" +#~ msgstr "Baixa-la selección ó fondo" + +#, fuzzy +#~ msgid "Rotate selection 90° clockwise (Shift+Ctrl+Right)" +#~ msgstr "Rota-los obxectos seleccionados 90° en sentido horario" + +#, fuzzy +#~ msgid "Rotate selection 90° counter-clockwise (Shift+Ctrl+Left)" +#~ msgstr "Rota-los obxectos seleccionados 90° en sentido horario" + +# [*] Revisar +#, fuzzy +#~ msgid "Flip selection horizontally (H)" +#~ msgstr "Voltea-los obxectos seleccionados" + +# [*] Revisar +#, fuzzy +#~ msgid "Flip selection vertically (V)" +#~ msgstr "Voltea-los obxectos seleccionados" + +#, fuzzy +#~ msgid "Align and Distribute dialog (Shift+Ctrl+A)" +#~ msgstr "Atributos" + +#, fuzzy +#~ msgid "Convert selected object(s) to path(s) (Shift+Ctrl+C)" +#~ msgstr "Converti-los obxectos seleccionados a curvas" + +#, fuzzy +#~ msgid "Convert selected stroke(s) to path(s) (Ctrl+Alt+C)" +#~ msgstr "Converti-los obxectos seleccionados a curvas" + +#, fuzzy +#~ msgid "Text and Font dialog (Shift+Ctrl+T)" +#~ msgstr "Configuración do escritorio" + +#, fuzzy +#~ msgid "Node tool" +#~ msgstr "Edición de nodos" + +#, fuzzy +#~ msgid "Zoom tool" +#~ msgstr "Zoom fora" + +#, fuzzy +#~ msgid "Rectangle tool" +#~ msgstr "Rectángulo" + +#, fuzzy +#~ msgid "Star tool" +#~ msgstr "Trazo" + +#, fuzzy +#~ msgid "Spiral tool" +#~ msgstr "Pixeles" + +#, fuzzy +#~ msgid "Freehand tool" +#~ msgstr "Man alzada" + +#, fuzzy +#~ msgid "Pen tool" +#~ msgstr "Rectángulo" + +#, fuzzy +#~ msgid "When scaling rectangles, scale radii of rounded corners" +#~ msgstr "Valor de centrado horizontal" + +#, fuzzy +#~ msgid "Delete segment between two nodes" +#~ msgstr "Borra-los nodos seleccionados" + +#, fuzzy +#~ msgid "Select All in All Layers" +#~ msgstr "Seleccionar" + +#, fuzzy +#~ msgid "Invert Selection" +#~ msgstr "Selección" + +#, fuzzy +#~ msgid "Clean up selected path(s)" +#~ msgstr "Combina-las curvas seleccionadas" + +#, fuzzy +#~ msgid "_Scripts..." +#~ msgstr "Punto" + +#, fuzzy +#~ msgid "Align and Distribute" +#~ msgstr "Atributos" + +#, fuzzy +#~ msgid "Align and Distribute Dialog" +#~ msgstr "Atributos" + +#, fuzzy +#~ msgid "Export Dialog" +#~ msgstr "Exportar como" + +#, fuzzy +#~ msgid "Fill and Stroke Dialog" +#~ msgstr "Configuración do escritorio" + +#, fuzzy +#~ msgid "Find Dialog" +#~ msgstr "Formulario de aliñacións" + +#, fuzzy +#~ msgid "Inkscape Preferences" +#~ msgstr "Sodipodi" + +#, fuzzy +#~ msgid "Inkscape Preferences Dialog" +#~ msgstr "Sodipodi" + +#, fuzzy +#~ msgid "Layer Editor Dialog" +#~ msgstr "Eleva-la selección ó tope" + +#, fuzzy +#~ msgid "Text Properties Dialog" +#~ msgstr "Propiedades do obxecto" + +#, fuzzy +#~ msgid "Transformation Dialog" +#~ msgstr "Formulario de transformacións" + +#, fuzzy +#~ msgid "Tree Editor" +#~ msgstr "Degradado" + +#, fuzzy +#~ msgid "XML Editor Dialog" +#~ msgstr "Editar..." + +#, fuzzy +#~ msgid "Row height:" +#~ msgstr "Alto:" + +#, fuzzy +#~ msgid "Column width:" +#~ msgstr "Cambiar" + +#, fuzzy +#~ msgid "Creating anchor at (%g,%g)" +#~ msgstr "Debuxar texto" + +#, fuzzy +#~ msgid "EPS Output Settings" +#~ msgstr "Configuración do documento" + +#, fuzzy +#~ msgid "Inkscape" +#~ msgstr "Sodipodi" + +#, fuzzy +#~ msgid "Top of aligned objects to top of anchor" +#~ msgstr "Aliña-lo interior do obxecto á beira superior" + +#, fuzzy +#~ msgid "Rows:" +#~ msgstr "Elipse" + +#, fuzzy +#~ msgid "Minor grid line color:" +#~ msgstr "Cor da guía liña" + +#, fuzzy +#~ msgid "Grid color" +#~ msgstr "Cor da reixa:" + +#, fuzzy +#~ msgid "Grid emphasis color" +#~ msgstr "Cor da reixa:" + +#, fuzzy +#~ msgid "Major grid line spacing:" +#~ msgstr "Separación X:" + +#, fuzzy +#~ msgid "Background (also for export):" +#~ msgstr "Cor da reixa" + +#, fuzzy +#~ msgid "Picking colors:" +#~ msgstr "Escoller unha cor" + +#, fuzzy +#~ msgid "Fill style" +#~ msgstr "Configuración do recheo" + +#, fuzzy +#~ msgid "Fill:" +#~ msgstr "Reencher" + +#, fuzzy +#~ msgid "winding" +#~ msgstr "Renderizado" + +#, fuzzy +#~ msgid "Update Properties" +#~ msgstr "Propiedades do elemento" + +#, fuzzy +#~ msgid "Label invalid" +#~ msgstr "O ID é válido" + +#, fuzzy +#~ msgid "executable" +#~ msgstr "Rectángulo" + +#, fuzzy +#~ msgid "file" +#~ msgstr "_Ficheiro" + +# [*] mirar unidades +#, fuzzy +#~ msgid "path" +#~ msgstr "pt" + +#, fuzzy +#~ msgid "absolute" +#~ msgstr "absoluto" + +#~ msgid "Could not create sodipodi-svg-doc factory" +#~ msgstr "Non se puido crea-la factoría sodipodi-svg-doc" + +#, fuzzy +#~ msgid "SVG Files" +#~ msgstr "Ficheiro" + +#, fuzzy +#~ msgid "Make s_ensitive" +#~ msgstr "Facer sensible" + +#, fuzzy +#~ msgid "Make i_nsensitive" +#~ msgstr "Facer insensible" + +#, fuzzy +#~ msgid "Layer Properties" +#~ msgstr "Propiedades do texto" + +#, fuzzy +#~ msgid "Select object(s) to tile." +#~ msgstr "Converti-los obxectos seleccionados a curvas" + +#~ msgid "Sensitive" +#~ msgstr "Sensible" + +#~ msgid "Active" +#~ msgstr "Activo" + +#~ msgid "Printable" +#~ msgstr "Imprimible" + +#, fuzzy +#~ msgid "Document Name:" +#~ msgstr "Documento" + +#, fuzzy +#~ msgid "Image URI:" +#~ msgstr "Tamaño da imaxe" + +#~ msgid "Visible" +#~ msgstr "Visible" + +#, fuzzy +#~ msgid "Flatness:" +#~ msgstr "Guías" + +#, fuzzy +#~ msgid "Other" +#~ msgstr "Orde" + +#, fuzzy +#~ msgid "Trace: Selected object is not an image" +#~ msgstr "Rota-los obxectos seleccionados 90° en sentido horario" + +#, fuzzy +#~ msgid "object" +#~ msgstr "Obxecto" + +#, fuzzy +#~ msgid "user space" +#~ msgstr "Espacio de usuario" + +#, fuzzy +#~ msgid "Coordinates:" +#~ msgstr "Bitmap a cor" + +#, fuzzy +#~ msgid "Alignment:" +#~ msgstr "Aliñar" + +#, fuzzy +#~ msgid "Draw arc: %s x %s" +#~ msgstr "Debuxar" + +#, fuzzy +#~ msgid "Draw rectangle: %s x %s" +#~ msgstr "Debuxar rectangulo" + +#, fuzzy +#~ msgid "Active group" +#~ msgstr "Activo" + +#~ msgid "Grid color:" +#~ msgstr "Cor da reixa:" + +#, fuzzy +#~ msgid "typeset object" +#~ msgstr "Obxecto texto" + +#, fuzzy +#~ msgid "Pattern Fill" +#~ msgstr "Patrón" + +#~ msgid "Snap to grid" +#~ msgstr "Enganchar á reixa" + +#~ msgid "Snap to guides" +#~ msgstr "Enganchar ás guías" + +#, fuzzy +#~ msgid "_Menu" +#~ msgstr "_Abrir" + +#, fuzzy +#~ msgid "Snap points to the grid" +#~ msgstr "Enganchar á reixa" + +#, fuzzy +#~ msgid "Rect" +#~ msgstr "Rectángulo" + +#, fuzzy +#~ msgid "meters" +#~ msgstr "inglete" + +#, fuzzy +#~ msgid "Userspace unit" +#~ msgstr "Espacio de usuario" + +#, fuzzy +#~ msgid "User" +#~ msgstr "Espacio de usuario" + +#, fuzzy +#~ msgid "Userspace units" +#~ msgstr "Espacio de usuario" + +#, fuzzy +#~ msgid "Ru_lers" +#~ msgstr "Ficheiro" + +#, fuzzy +#~ msgid "Show or hide rulers" +#~ msgstr "Amosar guías" + +#, fuzzy +#~ msgid "_New Window" +#~ msgstr "Nova vista" + +#, fuzzy +#~ msgid "Mode:" +#~ msgstr "Mover" + +#~ msgid "Alpha:" +#~ msgstr "Alfa:" + +#~ msgid "Value:" +#~ msgstr "Valor:" + +#, fuzzy +#~ msgid "Stroke settings" +#~ msgstr "Configuración do escritorio" + +#~ msgid "Item properties" +#~ msgstr "Propiedades do elemento" + +#, fuzzy +#~ msgid "Quit" +#~ msgstr "_Saír" + +#, fuzzy +#~ msgid "Combine multiple paths" +#~ msgstr "Combina-las curvas seleccionadas" + +#, fuzzy +#~ msgid "New View" +#~ msgstr "Nova vista" + +#, fuzzy +#~ msgid "Fill and stroke settings" +#~ msgstr "Configuración do escritorio" + +#, fuzzy +#~ msgid "Object transformations" +#~ msgstr "Reinicia-la transformación" + +#, fuzzy +#~ msgid "Text editing and font settings" +#~ msgstr "Configuración do escritorio" + +#, fuzzy +#~ msgid "Fill Rule" +#~ msgstr "Reencher" + +#, fuzzy +#~ msgid "Tool has no options" +#~ msgstr "Opcións de Oaf" + +#, fuzzy +#~ msgid "Visual transformation" +#~ msgstr "Reinicia-la transformación" + +#, fuzzy +#~ msgid "Show content" +#~ msgstr "Contido" + +#, fuzzy +#~ msgid "Selected object has no curve, cannot outline." +#~ msgstr "Converti-los obxectos seleccionados a curvas" + +#, fuzzy +#~ msgid "Proportion:" +#~ msgstr "Posición" + +#, fuzzy +#~ msgid "Inkscape _Options" +#~ msgstr "Sodipodi" + +#, fuzzy +#~ msgid "Tool Optio_ns" +#~ msgstr "Opcións de Oaf" + +#, fuzzy +#~ msgid "gradientUnits" +#~ msgstr "Recheo de degradado" + +#, fuzzy +#~ msgid "nonzero" +#~ msgstr "ningún" + +#, fuzzy +#~ msgid "" +#~ "%s is not regular file.\n" +#~ "Although inkscape will run, you can\n" +#~ "neither load nor save preferences\n" +#~ msgstr "" +#~ "%s non é un ficheiro regular.\n" +#~ "Ainda asi sodipodi vai funcionar, non\n" +#~ "poderá cargar nin salva-las preferencias\n" + +#, fuzzy +#~ msgid "" +#~ "%s either is not valid xml file or\n" +#~ "you do not have read premissions on it.\n" +#~ "Although inkscape will run, you\n" +#~ "are neither able to load nor save\n" +#~ "preferences." +#~ msgstr "" +#~ "%s non é un ficheiro xml válido ou\n" +#~ "non tes permisos de lectura nel.\n" +#~ "Ainda asi sodipodi vai funcionar, non\n" +#~ "poderá cargar nin salva-las\n" +#~ "preferencias." + +#, fuzzy +#~ msgid "" +#~ "%s is not valid inkscape preferences file.\n" +#~ "Although inkscape will run, you\n" +#~ "are neither able to load nor save\n" +#~ "preferences." +#~ msgstr "" +#~ "%s non é un ficheiro de preferencias de sodipodi válido.\n" +#~ "Ainda asi sodipodi vai funcionar, non\n" +#~ "poderá cargar nin salva-las\n" +#~ "preferencias." + +#, fuzzy +#~ msgid "" +#~ "Cannot create directory %s.\n" +#~ "Although inkscape will run, you\n" +#~ "are neither able to load nor save\n" +#~ "%s." +#~ msgstr "" +#~ "Non se puido crea-lo directorio %s.\n" +#~ "Ainda asi sodipodi vai funcionar, non\n" +#~ "poderá cargar nin salva-las\n" +#~ "preferencias." + +#, fuzzy +#~ msgid "" +#~ "%s is not a valid directory.\n" +#~ "Although inkscape will run, you\n" +#~ "are neither able to load nor save\n" +#~ "preferences." +#~ msgstr "" +#~ "%s non é un directorio válido.\n" +#~ "Ainda asi sodipodi vai funcionar, non\n" +#~ "poderá cargar nin salva-las\n" +#~ "preferencias." + +#, fuzzy +#~ msgid "" +#~ "Cannot create file %s.\n" +#~ "Although inkscape will run, you\n" +#~ "are neither able to load nor save\n" +#~ "preferences." +#~ msgstr "" +#~ "Imposible crea-lo ficheiro %s\n" +#~ "Ainda asi sodipodi vai funcionar, non\n" +#~ "poderá cargar nin salva-las\n" +#~ "preferencias." + +#, fuzzy +#~ msgid "" +#~ "Cannot write file %s.\n" +#~ "Although inkscape will run, you\n" +#~ "are neither able to load nor save\n" +#~ "preferences." +#~ msgstr "" +#~ "Imposible escribi-lo ficheiro %s\n" +#~ "Ainda asi sodipodi vai funcionar, non\n" +#~ "poderá cargar nin salva-las\n" +#~ "preferencias." + +#, fuzzy +#~ msgid "End color" +#~ msgstr "Cor da reixa" + +#, fuzzy +#~ msgid "Make sides flat" +#~ msgstr "Facer sensible" + +#~ msgid "Bring to _Front" +#~ msgstr "Traer á _Fronte" + +#~ msgid "Send to _Back" +#~ msgstr "Mandar ó F_ondo" + +#~ msgid "Document %s has unsaved changes, save them?" +#~ msgstr "O documento %s ten cambios sen gardar, ¿quere gardalos?" + +#, fuzzy +#~ msgid "Object Size and Position" +#~ msgstr "Posición" + +#, fuzzy +#~ msgid "Size and Position" +#~ msgstr "Posición" + +#, fuzzy +#~ msgid "Tool attributes" +#~ msgstr "Atributos" + +#, fuzzy +#~ msgid "Proportion" +#~ msgstr "Posición" + +#, fuzzy +#~ msgid "Tool has no attributes" +#~ msgstr "Cambia-los atributos" + +#~ msgid "Item" +#~ msgstr "Elemento" + +#, fuzzy +#~ msgid "Group Properties" +#~ msgstr "Propiedades do texto" + +#~ msgid "Ungroup" +#~ msgstr "Desagrupar" + +# [*] mirar unidades +#, fuzzy +#~ msgid "Link" +#~ msgstr "in" + +#~ msgid "Fill settings" +#~ msgstr "Configuración do recheo" + +#, fuzzy +#~ msgid "Break line at selected nodes" +#~ msgstr "Liña cúspide no nodo seleccionado" + +#, fuzzy +#~ msgid "Bring to Front" +#~ msgstr "Traer á _Fronte" + +#, fuzzy +#~ msgid "Send to Back" +#~ msgstr "Mandar ó F_ondo" + +#, fuzzy +#~ msgid "Lower selected objects to bottom" +#~ msgstr "Baixa-la selección ó fondo" + +#, fuzzy +#~ msgid "Raise selected objects one position" +#~ msgstr "Eleva-la selección ó tope" + +#, fuzzy +#~ msgid "Lower selected objects one position" +#~ msgstr "Baixa-la selección ó fondo" + +#, fuzzy +#~ msgid "Draw freehand curves and straight lines" +#~ msgstr "Debuxar liña a man alzada" + +#, fuzzy +#~ msgid "In" +#~ msgstr "Polgada" + +#, fuzzy +#~ msgid "Toggle grid" +#~ msgstr "Conmuta-las beiras" + +#, fuzzy +#~ msgid "Toggle guides" +#~ msgstr "Conmuta-las beiras" + +#~ msgid "1:1" +#~ msgstr "1:1" + +#~ msgid "1:2" +#~ msgstr "1:2" + +#~ msgid "2:1" +#~ msgstr "2:1" + +#, fuzzy +#~ msgid "Editing window properties" +#~ msgstr "Propiedades do elemento" + +#, fuzzy +#~ msgid "Tool Attributes" +#~ msgstr "Atributos" + +#~ msgid "Sodipodi" +#~ msgstr "Sodipodi" + +#~ msgid "Desktop settings" +#~ msgstr "Configuración do escritorio" + +#, fuzzy +#~ msgid "Iso grid" +#~ msgstr "Amosa-la reixa" + +#~ msgid "Display settings" +#~ msgstr "Configuración da visualización" + +#, fuzzy +#~ msgid "Export png file" +#~ msgstr "Exporta-lo ficheiro" + +#, fuzzy +#~ msgid "Object style" +#~ msgstr "Obxecto" + +#, fuzzy +#~ msgid "New Docked Toolbox" +#~ msgstr "Amosa-la caixa de ferramentas" + +#, fuzzy +#~ msgid "Drawing Mode" +#~ msgstr "Contexto de debuxo" + +#, fuzzy +#~ msgid "" +#~ "%s is not regular file.\n" +#~ "Although inkscape will run, you are\n" +#~ "not able to use extensions (plugins)\n" +#~ msgstr "" +#~ "%s non é un ficheiro regular.\n" +#~ "Ainda asi sodipodi vai funcionar, non\n" +#~ "poderá cargar nin salva-las preferencias\n" + +#, fuzzy +#~ msgid "" +#~ "%s either is not valid xml file or\n" +#~ "you do not have read premissions on it.\n" +#~ "Although inkscape will run, you are\n" +#~ "not able to use extensions (plugins)\n" +#~ msgstr "" +#~ "%s non é un ficheiro xml válido ou\n" +#~ "non tes permisos de lectura nel.\n" +#~ "Ainda asi sodipodi vai funcionar, non\n" +#~ "poderá cargar nin salva-las\n" +#~ "preferencias." + +#, fuzzy +#~ msgid "" +#~ "%s is not valid inkscape extensions file.\n" +#~ "Although inkscape will run, you are\n" +#~ "not able to use extensions (plugins)\n" +#~ msgstr "" +#~ "%s non é un ficheiro de preferencias de sodipodi válido.\n" +#~ "Ainda asi sodipodi vai funcionar, non\n" +#~ "poderá cargar nin salva-las\n" +#~ "preferencias." + +#, fuzzy +#~ msgid "" +#~ "Cannot create directory %s.\n" +#~ "Although inkscape will run, you are\n" +#~ "not able to use extensions (plugins)\n" +#~ msgstr "" +#~ "Non se puido crea-lo directorio %s.\n" +#~ "Ainda asi sodipodi vai funcionar, non\n" +#~ "poderá cargar nin salva-las\n" +#~ "preferencias." + +#, fuzzy +#~ msgid "" +#~ "%s is not a valid directory.\n" +#~ "Although inkscape will run, you are\n" +#~ "not able to use extensions (plugins)\n" +#~ msgstr "" +#~ "%s non é un directorio válido.\n" +#~ "Ainda asi sodipodi vai funcionar, non\n" +#~ "poderá cargar nin salva-las\n" +#~ "preferencias." + +#, fuzzy +#~ msgid "" +#~ "Cannot create file %s.\n" +#~ "Although inkscape will run, you are\n" +#~ "not able to use extensions (plugins)\n" +#~ msgstr "" +#~ "Imposible crea-lo ficheiro %s\n" +#~ "Ainda asi sodipodi vai funcionar, non\n" +#~ "poderá cargar nin salva-las\n" +#~ "preferencias." + +#, fuzzy +#~ msgid "" +#~ "Cannot write file %s.\n" +#~ "Although inkscape will run, you are\n" +#~ "not able to use extensions (plugins)\n" +#~ msgstr "" +#~ "Imposible escribi-lo ficheiro %s\n" +#~ "Ainda asi sodipodi vai funcionar, non\n" +#~ "poderá cargar nin salva-las\n" +#~ "preferencias." + +#~ msgid "Unknown item :-(" +#~ msgstr "Elemento descoñecido :-(" + +#, fuzzy +#~ msgid "Zoom in drawing" +#~ msgstr "Zoom ó debuxo" + +#, fuzzy +#~ msgid "Set zoom factor to 1:1" +#~ msgstr "Zoom a 1:1" + +#, fuzzy +#~ msgid "Set zoom factor to 1:2" +#~ msgstr "Zoom a 1:1" + +#, fuzzy +#~ msgid "Set zoom factor to 2:1" +#~ msgstr "Zoom a 1:1" + +#~ msgid "Document" +#~ msgstr "Documento" + +#, fuzzy +#~ msgid "Document variant:" +#~ msgstr "Documento" + +#, fuzzy +#~ msgid "Save document as" +#~ msgstr "Documento" + +#, fuzzy +#~ msgid "About sodipodi" +#~ msgstr "Sodipodi" + +#, fuzzy +#~ msgid "About Sodipodi" +#~ msgstr "Sodipodi" + +#~ msgid "The SVG ID of item" +#~ msgstr "A ID SVG do elemento" + +#~ msgid "The ID is not valid" +#~ msgstr "O ID non é válido" + +#~ msgid "The ID is already defined" +#~ msgstr "O ID xa está definido" + +#, fuzzy +#~ msgid "Position and size" +#~ msgstr "Posición" + +#, fuzzy +#~ msgid "Display Properties" +#~ msgstr "Configuración da visualización" + +#, fuzzy +#~ msgid "Lower selected objects one level" +#~ msgstr "Converti-los obxectos seleccionados a curvas" + +#, fuzzy +#~ msgid "Select tool - select and transform objects" +#~ msgstr "Reinicia-la transformación" + +#~ msgid "A path - whatever it means" +#~ msgstr "Unha curva - o que queira que signifique" + +#~ msgid "Align objects to vertical mid" +#~ msgstr "Aliñar obxectos á metade vertical" + +#~ msgid "Align outside object to bottom border" +#~ msgstr "Aliña-lo exterior do obxecto á beira inferior" + +#~ msgid "Align outside object to left border" +#~ msgstr "Aliña-lo exterior do obxecto á beira esquerda" + +#~ msgid "Align outside object to right border" +#~ msgstr "Aliña-lo exterior do obxecto á beira dereita" + +#~ msgid "Align outside object to top border" +#~ msgstr "Aliña-lo exterior do obxecto á beira superior" + +#, fuzzy +#~ msgid "Alignment base" +#~ msgstr "Aliñar ó centro" + +#, fuzzy +#~ msgid "Choose align type" +#~ msgstr "Escolle-lo sistema de unidades" + +#~ msgid "Parent X =" +#~ msgstr "Pai X =" + +#~ msgid "Parent Y =" +#~ msgstr "Pai Y =" + +#~ msgid "Y +" +#~ msgstr "Y +" + +#, fuzzy +#~ msgid " Color fill " +#~ msgstr "Recheo de Cor " + +#~ msgid " General " +#~ msgstr " Xeral " + +#~ msgid "Add new gradient" +#~ msgstr "Engadir novo degradado" + +#~ msgid "Behind fill" +#~ msgstr "Detrás do recheo" + +# [*] Revisar +#~ msgid "Butt endpoints" +#~ msgstr "Xuntar a tope os puntos finais" + +#~ msgid "Choose fill color" +#~ msgstr "Escolle-la cor de recheo" + +#~ msgid "Choose stroke color" +#~ msgstr "Escolle-la cor de trazado" + +#~ msgid "Endpoints:" +#~ msgstr "Puntos finais:" + +#~ msgid "Fill Color:" +#~ msgstr "Cor de recheo:" + +#~ msgid "Fractal fill" +#~ msgstr "Recheo fractal" + +#, fuzzy +#~ msgid "Pick fill color" +#~ msgstr "Escoller unha cor" + +#~ msgid "Scale with object" +#~ msgstr "Escalar co obxecto" + +#~ msgid "centimeter" +#~ msgstr "centímetro" + +#~ msgid "millimeters" +#~ msgstr "milímetros" + +#~ msgid "points" +#~ msgstr "puntos" + +#~ msgid "1.0MB" +#~ msgstr "1.0MB" + +#~ msgid "Convert selected segments to curves" +#~ msgstr "Converti-los segmentos seleccionados a curvas" + +#~ msgid "Cusp line at selected nodes" +#~ msgstr "Liña cúspide no nodo seleccionado" + +#~ msgid "Desktop" +#~ msgstr "Escritorio" + +#~ msgid "Drawing Context" +#~ msgstr "Contexto de debuxo" + +#~ msgid "Export picture to png" +#~ msgstr "Exporta-lo debuxo a png" + +#~ msgid "Forward One" +#~ msgstr "Un adiante" + +#~ msgid "Include one node into selected segments" +#~ msgstr "Incluir un nodo nos segmentos seleccionados" + +#~ msgid "Join 2 selected endpoints" +#~ msgstr "Xuntar 2 puntos finais seleccionados" + +#~ msgid "Smooth line at selected nodes" +#~ msgstr "Suaviza-la liña nos nodos seleccionados" + +#~ msgid "Where to export" +#~ msgstr "Adonde exportar" + +#~ msgid "X0" +#~ msgstr "X0" + +#~ msgid "XML Tree" +#~ msgstr "Arbore XML" + +#~ msgid "Y0" +#~ msgstr "Y0" + +#~ msgid "_Align" +#~ msgstr "_Aliñar" + +# [*] Mirar +#~ msgid "Break apart selected paths" +#~ msgstr "Fragmenta-las curvas seleccionadas" + +#~ msgid "Drawing context" +#~ msgstr "Contexto de debuxo" + +#~ msgid "Edit font style of selected objects" +#~ msgstr "Edita-lo estilo da fonte dos obxectos seleccionados" + +#~ msgid "Import " +#~ msgstr "Importar" + +#~ msgid "New drawing" +#~ msgstr "Novo debuxo" + +#~ msgid "No I'd rather do some more cool vector drawing with sodipodi." +#~ msgstr "Non, Prefiro seguir a facer xeniais debuxos vectoriais co Sodipodi." + +#~ msgid "Nope !" +#~ msgstr "¡ Nopi !" + +#~ msgid "Paste from clipboard" +#~ msgstr "Pegar do portarretallos" + +#~ msgid "Preview print drawing" +#~ msgstr "Previsualiza-la impresión do debuxo" + +#~ msgid "Quit or not quit ?" +#~ msgstr "Saír ou non saír" + +#~ msgid "Really wanna quit sodipodi ?" +#~ msgstr "¿Pero de verdade que queres saír do Sodipodi?" + +#, fuzzy +#~ msgid "Rotate selected objects 90deg clockwise" +#~ msgstr "Rota-los obxectos seleccionados 90° en sentido horario" + +#~ msgid "Save drawing " +#~ msgstr "Garda-lo debuxo " + +#~ msgid "Yep !" +#~ msgstr "¡ Sipi !" + +#~ msgid "Yes quick! I want to leave sodipodi and come back later." +#~ msgstr "¡Si, saír! Quero saír de Sodipodi, e voltar maís tarde." + +#~ msgid "Align to bottom middle" +#~ msgstr "Aliñar abaixo ó medio" + +#~ msgid "Align to bottom right" +#~ msgstr "Aliñar abaixo á dereita" + +#~ msgid "Align to center" +#~ msgstr "Aliñar ó centro" + +#~ msgid "Align to top middle" +#~ msgstr "Aliñar arriba ó medio" + +#~ msgid "Choose metric for center" +#~ msgstr "Escolle-la metría para o centro" + +#~ msgid "Close dialog - Ctl+c" +#~ msgstr "Pecha-lo diálogo - Ctrl+c" + +#~ msgid "Expand dialog - Ctl+e" +#~ msgstr "Expandi-lo diálogo - Ctrl+e" + +#~ msgid "Keep height of selection during transformation" +#~ msgstr "Mante-lo alto da selección durante a transformación" + +#~ msgid "Keep width of selection during transformation" +#~ msgstr "Mante-lo ancho da selección durante a transformación" + +#~ msgid "Orig. Width: " +#~ msgstr "Ancho Orixe:" + +#~ msgid "Orig. X: " +#~ msgstr "Orix. X: " + +#, fuzzy +#~ msgid "Set angle to 0 degrees" +#~ msgstr "Poñe-lo ángulo a 0°" + +#, fuzzy +#~ msgid "Set angle to 180 degrees" +#~ msgstr "Poñe-lo ángulo a 180°" + +#, fuzzy +#~ msgid "Set angle to 270 degrees" +#~ msgstr "Poñe-lo ángulo a 270°" + +#~ msgid "Start transformation - Ctl+a" +#~ msgstr "Comeza-la transformación - Ctrl+a" + +#~ msgid "Toggle center given in selection/desktop coordiantes" +#~ msgstr "Conmuta-lo centro dado en coordenadas de selección/escritorio" + +#~ msgid "Use alignment during transformation" +#~ msgstr "Usa-lo aliñamento durante a transformación" + +#~ msgid "Use center as transformation fixpoint" +#~ msgstr "Usa-lo centro coma punto fixo da transformación" + +#~ msgid "Y: " +#~ msgstr "Y:" + +#~ msgid "keep aspect" +#~ msgstr "mante-lo aspecto" + +#~ msgid "lock/unlock horizontal and vertical scale" +#~ msgstr "bloquear/desbloquea-la escala horizontal" + +#~ msgid "select direction" +#~ msgstr "selecciona-la dirección" + +#~ msgid "select direction (horizontal/vertical skew)" +#~ msgstr "selecciona-la dirección (inclinación horizontal/vertical)" + +#~ msgid "select metric for scale" +#~ msgstr "selecciona-la metría para a escala" + +#~ msgid "select metric for values" +#~ msgstr "seleccionar-la metría para os valores" + +#~ msgid "skew" +#~ msgstr "inclinar" + +#~ msgid "toggle absolute/relative move" +#~ msgstr "conmuta-lo movemento a absoluto/relativo" + +#~ msgid "toggle absolute/relative scale" +#~ msgstr "conmuta-la escala a absoluta/relativa" + +#~ msgid "Change Attribute" +#~ msgstr "Cambia-los atributos" + +#, fuzzy +#~ msgid "Change Content" +#~ msgstr "Contexto de debuxo" + +#~ msgid "Do you want to delete attribute?" +#~ msgstr "¿Quere borra-los atributos?" + +#~ msgid "Hierarchy" +#~ msgstr "Xerarquía" + +# [*] mirar +#~ msgid "Key" +#~ msgstr "Chave" + +#, fuzzy +#~ msgid "You can't delete 'id' attribute!" +#~ msgstr "¿Quere borra-los atributos?" + +#, fuzzy +#~ msgid "Do you want to delete attribute %s?" +#~ msgstr "¿Quere borra-los atributos?" + +#, fuzzy +#~ msgid "No" +#~ msgstr "Nodo" + +#, fuzzy +#~ msgid "Do you want to delete element %s?" +#~ msgstr "¿Quere borra-los atributos?" + +#~ msgid "\"" +#~ msgstr "\"" + +#~ msgid "Choose base unit system for grid" +#~ msgstr "Escolle-lo sistema base de unidades para a reixa" + +#~ msgid "Millimeters\n" +#~ msgstr "Milímetros\n" + +#~ msgid "Choose color for grid" +#~ msgstr "Escolle-la cor da reixa" + +#~ msgid "Set maximum distance for grid snapping" +#~ msgstr "Configura-la distancia máxima para o enganche á reixa" + +#~ msgid "Choose unit system for grid snapping" +#~ msgstr "Escolle-lo sistema de unidades para o enganche á reixa" + +#~ msgid "Pixels\n" +#~ msgstr "Pixeles\n" + +#~ msgid "Set origin of page coordinate system" +#~ msgstr "Configura-la orixe do sistema de coordeadas da páxina" + +#~ msgid "Choose unit system for guideline snapping" +#~ msgstr "Escolle-lo sistema de unidades para o enganche as liñas guía" + +#~ msgid "Set maximum distance for guideline snapping" +#~ msgstr "Configura-la distancia máxima para o enganche ás liñas guía" + +#~ msgid "Choose paper size" +#~ msgstr "Escolle-lo tamaño do papel" + +#~ msgid "A4\n" +#~ msgstr "A4\n" + +#~ msgid "Set page height" +#~ msgstr "Configura-la altura da páxina" + +#~ msgid "window2" +#~ msgstr "fiestra2" + +#~ msgid "Copyright Lauris Kaplinski 1999-2000." +#~ msgstr "Copyright Lauris Kaplinski 1999-2000." + +#~ msgid "" +#~ "A Vector Drawing Program.\n" +#~ "Released under GPL" +#~ msgstr "" +#~ "Un programa de debuxo vectorial.\n" +#~ "Distribuido baixo licencia GPL" + +#~ msgid "Draw ellipse" +#~ msgstr "Debuxar elipse" + +# [*] mirar +#~ msgid "Dup" +#~ msgstr "Duplicar" + +#~ msgid "Do not use GUI. NB! if exist, should be FIRST argument!" +#~ msgstr "¡Non usa-lo IGU. NB! ¡se existe, debe se-lo PRIMEIRO argumento!" + +#~ msgid "Could not initialize Bonobo" +#~ msgstr "Non se puido iniciar Bonobo" + +#~ msgid "" +#~ "pixels\n" +#~ "millimeters\n" +#~ "centimeter\n" +#~ "points\n" +#~ "inches\n" +#~ msgstr "" +#~ "pixeles\n" +#~ "milímetros\n" +#~ "centímetros\n" +#~ "puntos\n" +#~ "polgadas\n" + +#~ msgid "double" +#~ msgstr "doble" + +#~ msgid " Join " +#~ msgstr " Xuntar " + +#~ msgid "butt" +#~ msgstr "fondo" + +#~ msgid "y" +#~ msgstr "y" + +#~ msgid "Height " +#~ msgstr "Alto" + +# [*] Mirar abreviaturas de unidades +#~ msgid "" +#~ "px\n" +#~ "mm\n" +#~ "cm\n" +#~ "pt\n" +#~ "in\n" +#~ msgstr "" +#~ "px\n" +#~ "mm\n" +#~ "cm\n" +#~ "pt\n" +#~ "in\n" + +# [*] Mirar abreviaturas das unidades +#~ msgid "" +#~ "px\n" +#~ "mm\n" +#~ "cm\n" +#~ "in\n" +#~ msgstr "" +#~ "px\n" +#~ "mm\n" +#~ "cm\n" +#~ "in\n" + +# [*] Mirar abreviaturas das unidades +#~ msgid "" +#~ "pt\n" +#~ "mm\n" +#~ "cm\n" +#~ "in\n" +#~ msgstr "" +#~ "pt\n" +#~ "mm\n" +#~ "cm\n" +#~ "in\n" diff --git a/po/hu.po b/po/hu.po new file mode 100644 index 000000000..92ff33919 --- /dev/null +++ b/po/hu.po @@ -0,0 +1,9671 @@ +# Inkscape Hungarian translation. +# Copyright (C) 2004, 2005 Free Software Foundation, Inc. +# Arpad Biro , 2004, 2005. +msgid "" +msgstr "" +"Project-Id-Version: Inkscape\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2005-12-04 11:51-0800\n" +"PO-Revision-Date: 2005-11-06 19:56+0100\n" +"Last-Translator: Arpad Biro \n" +"Language-Team: Hungarian\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 1.10.2\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: ../inkscape.desktop.in.h:1 +msgid "Create and edit Scalable Vector Graphics images" +msgstr "" +"Scalable Vector Graphics (méretezhető vektorgrafika, SVG) képek létrehozása " +"és szerkesztése" + +#: ../inkscape.desktop.in.h:2 +msgid "Inkscape SVG Vector Illustrator" +msgstr "Inkscape - vektoros (SVG) rajzoló" + +#: ../../po/../src/arc-context.cpp:350 +msgid "" +"Ctrl: make circle or integer-ratio ellipse, snap arc/segment angle" +msgstr "" +"Ctrl: kör vagy egész-arányú ellipszis rajzolása; ellipszisív illetve -" +"cikk szöghöz való illesztése" + +#: ../../po/../src/arc-context.cpp:351 ../../po/../src/rect-context.cpp:388 +msgid "Shift: draw around the starting point" +msgstr "Shift: rajzolás a kezdőpont köré" + +#: ../../po/../src/arc-context.cpp:413 +#: ../../po/../src/connector-context.cpp:493 +#: ../../po/../src/dyna-draw-context.cpp:506 +#: ../../po/../src/pen-context.cpp:329 ../../po/../src/pencil-context.cpp:208 +#: ../../po/../src/rect-context.cpp:452 ../../po/../src/spiral-context.cpp:421 +#: ../../po/../src/star-context.cpp:427 +msgid "Current layer is hidden. Unhide it to be able to draw on it." +msgstr "" +"Az aktuális réteg rejtett. Ha szeretne rajzolni rá, akkor szüntesse " +"meg annak rejtettségét." + +#: ../../po/../src/arc-context.cpp:417 +#: ../../po/../src/connector-context.cpp:497 +#: ../../po/../src/dyna-draw-context.cpp:510 +#: ../../po/../src/pen-context.cpp:336 ../../po/../src/pencil-context.cpp:212 +#: ../../po/../src/rect-context.cpp:456 ../../po/../src/spiral-context.cpp:426 +#: ../../po/../src/star-context.cpp:431 +msgid "Current layer is locked. Unlock it to be able to draw on it." +msgstr "" +"Az aktuális réteg zárolt. Ha szeretne rajzolni rá, akkor szüntesse " +"meg annak zároltságát." + +#: ../../po/../src/arc-context.cpp:496 +#, c-format +msgid "" +"Ellipse: %s × %s; with Ctrl to make circle or integer-" +"ratio ellipse; with Shift to draw around the starting point" +msgstr "" +"Ellipszis: %s × %s. Kör vagy egész-arányú ellipszis: Ctrl; rajzolás a kezdőpont köré: Shift." + +#: ../../po/../src/connector-context.cpp:518 +msgid "Creating new connector" +msgstr "Új kapocs létrehozása" + +#: ../../po/../src/connector-context.cpp:939 +msgid "Finishing connector" +msgstr "Kapocs befejezése" + +#: ../../po/../src/connector-context.cpp:1108 +msgid "Connection point: click or drag to create a new connector" +msgstr "" +"Kapcsolódási pont. Új kapocs létrehozása: kattintással vagy húzással." + +#: ../../po/../src/connector-context.cpp:1185 +msgid "Connector endpoint: drag to reroute or connect to new shapes" +msgstr "" +"Kapocs-végpont. Új útvonal készítése vagy más alakzatokhoz való " +"kapcsolás: húzással." + +#: ../../po/../src/connector-context.cpp:1278 +msgid "Select at least one non-connector object." +msgstr "Jelöljön ki legalább 1 nem-kapocs objektumot." + +#: ../../po/../src/desktop-events.cpp:238 +#, c-format +msgid "%s at %s" +msgstr "%s, pozíció: %s" + +#. TRANSLATORS: This string appears when double-clicking on a guide. +#. This is the distance by which the guide is to be moved. +#: ../../po/../src/desktop-events.cpp:277 +msgid " relative by " +msgstr " relatív, ennyivel: " + +#. TRANSLATORS: This string appears when double-clicking on a guide. +#. This is the target location where the guide is to be moved. +#: ../../po/../src/desktop-events.cpp:282 +#: ../../po/../src/desktop-events.cpp:395 +msgid " absolute to " +msgstr " abszolút, ide: " + +#. create dialog +#: ../../po/../src/desktop-events.cpp:348 +msgid "Guideline" +msgstr "Segédvonal" + +#: ../../po/../src/desktop-events.cpp:432 +#, c-format +msgid "Move %s" +msgstr "Áthelyezés: %s" + +#: ../../po/../src/desktop.cpp:678 +msgid "No previous zoom." +msgstr "Nincs előző nagyítás." + +#: ../../po/../src/desktop.cpp:703 +msgid "No next zoom." +msgstr "Nincs következő nagyítás." + +#: ../../po/../src/dialogs/clonetiler.cpp:182 +msgid "Nothing selected." +msgstr "Semmi nincs kijelölve." + +#: ../../po/../src/dialogs/clonetiler.cpp:188 +msgid "More than one object selected." +msgstr "Több objektum van kijelölve." + +#: ../../po/../src/dialogs/clonetiler.cpp:195 +#, c-format +msgid "Object has %d tiled clones." +msgstr "Az objektumnak %d csempézett klónja van." + +#: ../../po/../src/dialogs/clonetiler.cpp:200 +msgid "Object has no tiled clones." +msgstr "Az objektumnak nincs csempézett klónja." + +#: ../../po/../src/dialogs/clonetiler.cpp:865 +msgid "Select one object whose tiled clones to unclump." +msgstr "" +"Jelöljön ki egy objektumot, amelynek a csempézett klónjai " +"egyenletesítendők." + +#: ../../po/../src/dialogs/clonetiler.cpp:916 +msgid "Select one object whose tiled clones to remove." +msgstr "" +"Jelöljön ki egy objektumot, amelynek a csempézett klónjai törlendők." + +#: ../../po/../src/dialogs/clonetiler.cpp:984 +#: ../../po/../src/selection-chemistry.cpp:1774 +msgid "Select an object to clone." +msgstr "Jelölje ki a klónozandó objektumot." + +#: ../../po/../src/dialogs/clonetiler.cpp:990 +#: ../../po/../src/selection-chemistry.cpp:1780 +msgid "" +"If you want to clone several objects, group them and clone the " +"group." +msgstr "" +"Ha több objektumot szeretne klónozni, akkor foglalja azokat csoportba, majd klónozza a csoportot." + +#: ../../po/../src/dialogs/clonetiler.cpp:1484 +msgid "Per row:" +msgstr "Soronként:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1497 +msgid "Per column:" +msgstr "Oszloponként:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1505 +msgid "Randomize:" +msgstr "Véletlenszerűség:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1656 +msgid "_Symmetry" +msgstr "_Szimmetria" + +#. TRANSLATORS: For the following 17 symmetry groups, see +#. * http://www.bib.ulb.ac.be/coursmath/doc/17.htm (visual examples); +#. * http://www.clarku.edu/~djoyce/wallpaper/seventeen.html (English vocabulary); or +#. * http://membres.lycos.fr/villemingerard/Geometri/Sym1D.htm (French vocabulary). +#. +#: ../../po/../src/dialogs/clonetiler.cpp:1664 +msgid "Select one of the 17 symmetry groups for the tiling" +msgstr "" +"Válassza ki a csempézéshez használandó szimmetriacsoportot a lehetséges 17 " +"közül" + +#. TRANSLATORS: "translation" means "shift" / "displacement" here. +#: ../../po/../src/dialogs/clonetiler.cpp:1675 +msgid "P1: simple translation" +msgstr "P1: egyszerű eltolás" + +#: ../../po/../src/dialogs/clonetiler.cpp:1676 +msgid "P2: 180° rotation" +msgstr "P2: 180°-os forgatás" + +#: ../../po/../src/dialogs/clonetiler.cpp:1677 +msgid "PM: reflection" +msgstr "PM: tükrözés" + +#. TRANSLATORS: "glide reflection" is a reflection and a translation combined. +#. For more info, see http://mathforum.org/sum95/suzanne/symsusan.html +#: ../../po/../src/dialogs/clonetiler.cpp:1680 +msgid "PG: glide reflection" +msgstr "PG: eltolásos tükrözés" + +#: ../../po/../src/dialogs/clonetiler.cpp:1681 +msgid "CM: reflection + glide reflection" +msgstr "CM: tükrözés + eltolásos tükrözés" + +#: ../../po/../src/dialogs/clonetiler.cpp:1682 +msgid "PMM: reflection + reflection" +msgstr "PMM: tükrözés + tükrözés" + +#: ../../po/../src/dialogs/clonetiler.cpp:1683 +msgid "PMG: reflection + 180° rotation" +msgstr "PMG: tükrözés + 180°-os forgatás" + +#: ../../po/../src/dialogs/clonetiler.cpp:1684 +msgid "PGG: glide reflection + 180° rotation" +msgstr "PGG: eltolásos tükrözés + 180°-os forgatás" + +#: ../../po/../src/dialogs/clonetiler.cpp:1685 +msgid "CMM: reflection + reflection + 180° rotation" +msgstr "CMM: tükrözés + tükrözés + 180°-os forgatás" + +#: ../../po/../src/dialogs/clonetiler.cpp:1686 +msgid "P4: 90° rotation" +msgstr "P4: 90°-os forgatás" + +#: ../../po/../src/dialogs/clonetiler.cpp:1687 +msgid "P4M: 90° rotation + 45° reflection" +msgstr "P4M: 90°-os forgatás + 45°-os tükrözés" + +#: ../../po/../src/dialogs/clonetiler.cpp:1688 +msgid "P4G: 90° rotation + 90° reflection" +msgstr "P4G: 90°-os forgatás + 90°-os tükrözés" + +#: ../../po/../src/dialogs/clonetiler.cpp:1689 +msgid "P3: 120° rotation" +msgstr "P3: 120°-os forgatás" + +#: ../../po/../src/dialogs/clonetiler.cpp:1690 +msgid "P31M: reflection + 120° rotation, dense" +msgstr "P31M: tükrözés + 120°-os forgatás, sűrű" + +#: ../../po/../src/dialogs/clonetiler.cpp:1691 +msgid "P3M1: reflection + 120° rotation, sparse" +msgstr "P3M1: tükrözés + 120°-os forgatás, ritka" + +#: ../../po/../src/dialogs/clonetiler.cpp:1692 +msgid "P6: 60° rotation" +msgstr "P6: 60°-os forgatás" + +#: ../../po/../src/dialogs/clonetiler.cpp:1693 +msgid "P6M: reflection + 60° rotation" +msgstr "P6M: tükrözés + 60°-os forgatás" + +#: ../../po/../src/dialogs/clonetiler.cpp:1721 +msgid "S_hift" +msgstr "_Eltolás" + +#. TRANSLATORS: "shift" means: the tiles will be shifted (offset) horizontally by this amount +#: ../../po/../src/dialogs/clonetiler.cpp:1731 +#, no-c-format +msgid "Shift X:" +msgstr "X irányú eltolás:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1739 +#, no-c-format +msgid "Horizontal shift per row (in % of tile width)" +msgstr "Soronkénti vízszintes eltolás (a csempeszélesség százalékában)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1747 +#, no-c-format +msgid "Horizontal shift per column (in % of tile width)" +msgstr "Oszloponkénti vízszintes eltolás (a csempeszélesség százalékában)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1754 +msgid "Randomize the horizontal shift by this percentage" +msgstr "A vízszintes eltolás véletlenszerűsítése ennyi százalékkal" + +#. TRANSLATORS: "shift" means: the tiles will be shifted (offset) vertically by this amount +#: ../../po/../src/dialogs/clonetiler.cpp:1764 +#, no-c-format +msgid "Shift Y:" +msgstr "Y irányú eltolás:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1772 +#, no-c-format +msgid "Vertical shift per row (in % of tile height)" +msgstr "Soronkénti függőleges eltolás (a csempemagasság százalékában)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1780 +#, no-c-format +msgid "Vertical shift per column (in % of tile height)" +msgstr "Oszloponkénti függőleges eltolás (a csempemagasság százalékában)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1787 +msgid "Randomize the vertical shift by this percentage" +msgstr "A függőleges eltolás véletlenszerűsítése ennyi százalékkal" + +#: ../../po/../src/dialogs/clonetiler.cpp:1795 +msgid "Exponent:" +msgstr "Kitevő:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1802 +msgid "Whether rows are spaced evenly (1), converge (<1) or diverge (>1)" +msgstr "" +"A sorok egyenletesen oszlanak el (1), konvergálnak (<1) vagy divergálnak (>1)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1809 +msgid "Whether columns are spaced evenly (1), converge (<1) or diverge (>1)" +msgstr "" +"Az oszlopok egyenletesen oszlanak el (1), konvergálnak (<1) vagy divergálnak " +"(>1)" + +#. TRANSLATORS: "Alternate" is a verb here +#: ../../po/../src/dialogs/clonetiler.cpp:1817 +#: ../../po/../src/dialogs/clonetiler.cpp:1907 +#: ../../po/../src/dialogs/clonetiler.cpp:1966 +#: ../../po/../src/dialogs/clonetiler.cpp:2022 +#: ../../po/../src/dialogs/clonetiler.cpp:2153 +msgid "Alternate:" +msgstr "Váltakozás:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1823 +msgid "Alternate the sign of shifts for each row" +msgstr "Az eltolások előjelének módosítása soronként" + +#: ../../po/../src/dialogs/clonetiler.cpp:1828 +msgid "Alternate the sign of shifts for each column" +msgstr "Az eltolások előjelének módosítása oszloponként" + +#: ../../po/../src/dialogs/clonetiler.cpp:1837 +msgid "Sc_ale" +msgstr "_Méretezés" + +#: ../../po/../src/dialogs/clonetiler.cpp:1845 +msgid "Scale X:" +msgstr "X irányú átméretezés:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1853 +#, no-c-format +msgid "Horizontal scale per row (in % of tile width)" +msgstr "Soronkénti vízszintes átméretezés (a csempeszélesség százalékában)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1861 +#, no-c-format +msgid "Horizontal scale per column (in % of tile width)" +msgstr "Oszloponkénti vízszintes átméretezés (a csempeszélesség százalékában)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1868 +msgid "Randomize the horizontal scale by this percentage" +msgstr "A vízszintes átméretezés véletlenszerűsítése ennyi százalékkal" + +#: ../../po/../src/dialogs/clonetiler.cpp:1876 +msgid "Scale Y:" +msgstr "Y irányú átméretezés:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1884 +#, no-c-format +msgid "Vertical scale per row (in % of tile height)" +msgstr "Soronkénti függőleges átméretezés (a csempemagasság százalékában)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1892 +#, no-c-format +msgid "Vertical scale per column (in % of tile height)" +msgstr "Oszloponkénti függőleges átméretezés (a csempemagasság százalékában)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1899 +msgid "Randomize the vertical scale by this percentage" +msgstr "A függőleges átméretezés véletlenszerűsítése ennyi százalékkal" + +#: ../../po/../src/dialogs/clonetiler.cpp:1913 +msgid "Alternate the sign of scales for each row" +msgstr "Az átméretezések előjelének módosítása soronként" + +#: ../../po/../src/dialogs/clonetiler.cpp:1918 +msgid "Alternate the sign of scales for each column" +msgstr "Az átméretezések előjelének módosítása oszloponként" + +#: ../../po/../src/dialogs/clonetiler.cpp:1927 +msgid "_Rotation" +msgstr "_Forgatás" + +#: ../../po/../src/dialogs/clonetiler.cpp:1935 +msgid "Angle:" +msgstr "Szög:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1943 +#, no-c-format +msgid "Rotate tiles by this angle for each row" +msgstr "Csempék soronkénti elforgatásának szöge" + +#: ../../po/../src/dialogs/clonetiler.cpp:1951 +#, no-c-format +msgid "Rotate tiles by this angle for each column" +msgstr "Csempék oszloponkénti elforgatásának szöge" + +#: ../../po/../src/dialogs/clonetiler.cpp:1958 +msgid "Randomize the rotation angle by this percentage" +msgstr "Az elforgatási szög véletlenszerűsítése ennyi százalékkal" + +#: ../../po/../src/dialogs/clonetiler.cpp:1972 +msgid "Alternate the rotation direction for each row" +msgstr "Az elforgatási irány módosítása soronként" + +#: ../../po/../src/dialogs/clonetiler.cpp:1977 +msgid "Alternate the rotation direction for each column" +msgstr "Az elforgatási irány módosítása oszloponként" + +#: ../../po/../src/dialogs/clonetiler.cpp:1985 +msgid "_Opacity" +msgstr "Átlátszatla_nság" + +#: ../../po/../src/dialogs/clonetiler.cpp:1993 +msgid "Fade out:" +msgstr "Halványítás:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2000 +msgid "Decrease tile opacity by this percentage for each row" +msgstr "A csempék átlátszatlanságának soronkénti csökkentésének százaléka" + +#: ../../po/../src/dialogs/clonetiler.cpp:2007 +msgid "Decrease tile opacity by this percentage for each column" +msgstr "A csempék átlátszatlanságának oszloponkénti csökkentésének százaléka" + +#: ../../po/../src/dialogs/clonetiler.cpp:2014 +msgid "Randomize the tile opacity by this percentage" +msgstr "A csempék átlátszatlanságának véletlenszerűsítése ennyi százalékkal" + +#: ../../po/../src/dialogs/clonetiler.cpp:2028 +msgid "Alternate the sign of opacity change for each row" +msgstr "Az átlátszatlanság-változás előjelének módosítása soronként" + +#: ../../po/../src/dialogs/clonetiler.cpp:2033 +msgid "Alternate the sign of opacity change for each column" +msgstr "Az átlátszatlanság-változás előjelének módosítása oszloponként" + +#: ../../po/../src/dialogs/clonetiler.cpp:2041 +msgid "Co_lor" +msgstr "S_zín" + +#: ../../po/../src/dialogs/clonetiler.cpp:2046 +msgid "Initial color: " +msgstr "Kezdeti szín: " + +#: ../../po/../src/dialogs/clonetiler.cpp:2050 +msgid "Initial color of tiled clones" +msgstr "A csempézett klónok kezdeti színe" + +#: ../../po/../src/dialogs/clonetiler.cpp:2050 +msgid "" +"Initial color for clones (works only if the original has unset fill or " +"stroke)" +msgstr "" +"Kezdeti szín a klónok számára (csak akkor lép érvénybe, ha az eredeti " +"objektumnak nincs kitöltése vagy körvonala)" + +#: ../../po/../src/dialogs/clonetiler.cpp:2065 +msgid "H:" +msgstr "Á:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2072 +msgid "Change the tile hue by this percentage for each row" +msgstr "A csempék árnyalatának soronkénti módosítása ennyi százalékkal" + +#: ../../po/../src/dialogs/clonetiler.cpp:2079 +msgid "Change the tile hue by this percentage for each column" +msgstr "A csempék árnyalatának oszloponkénti módosítása ennyi százalékkal" + +#: ../../po/../src/dialogs/clonetiler.cpp:2086 +msgid "Randomize the tile hue by this percentage" +msgstr "A csempék árnyalatának véletlenszerűsítése ennyi százalékkal" + +#: ../../po/../src/dialogs/clonetiler.cpp:2095 +msgid "S:" +msgstr "T:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2102 +msgid "Change the color saturation by this percentage for each row" +msgstr "A színtelítettség soronkénti módosítása ennyi százalékkal" + +#: ../../po/../src/dialogs/clonetiler.cpp:2109 +msgid "Change the color saturation by this percentage for each column" +msgstr "A színtelítettség oszloponkénti módosítása ennyi százalékkal" + +#: ../../po/../src/dialogs/clonetiler.cpp:2116 +msgid "Randomize the color saturation by this percentage" +msgstr "A színtelítettség véletlenszerűsítése ennyi százalékkal" + +#: ../../po/../src/dialogs/clonetiler.cpp:2124 +msgid "L:" +msgstr "F:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2131 +msgid "Change the color lightness by this percentage for each row" +msgstr "A színfényesség soronkénti módosítása ennyi százalékkal" + +#: ../../po/../src/dialogs/clonetiler.cpp:2138 +msgid "Change the color lightness by this percentage for each column" +msgstr "A színfényesség oszloponkénti módosítása ennyi százalékkal" + +#: ../../po/../src/dialogs/clonetiler.cpp:2145 +msgid "Randomize the color lightness by this percentage" +msgstr "A színfényesség véletlenszerűsítése ennyi százalékkal" + +#: ../../po/../src/dialogs/clonetiler.cpp:2159 +msgid "Alternate the sign of color changes for each row" +msgstr "A színváltozás előjelének módosítása soronként" + +#: ../../po/../src/dialogs/clonetiler.cpp:2164 +msgid "Alternate the sign of color changes for each column" +msgstr "A színváltozás előjelének módosítása oszloponként" + +#: ../../po/../src/dialogs/clonetiler.cpp:2172 +msgid "_Trace" +msgstr "Vekt_orizálás" + +#: ../../po/../src/dialogs/clonetiler.cpp:2179 +msgid "Trace the drawing under the tiles" +msgstr "A csempék alatti rajz vektorizálása" + +#: ../../po/../src/dialogs/clonetiler.cpp:2183 +msgid "" +"For each clone, pick a value from the drawing in that clone's location and " +"apply it to the clone" +msgstr "" +"Minden egyes klónra: egy érték leolvasása a rajzról az adott klón helyén, és " +"annak alkalmazása a klónra" + +#: ../../po/../src/dialogs/clonetiler.cpp:2197 +msgid "1. Pick from the drawing:" +msgstr "1. Leolvasás a rajzról:" + +#. ----Hbox2 +#: ../../po/../src/dialogs/clonetiler.cpp:2208 +#: ../../po/../src/dialogs/clonetiler.cpp:2355 +#: ../../po/../src/ui/dialog/tracedialog.cpp:445 +msgid "Color" +msgstr "Szín" + +#: ../../po/../src/dialogs/clonetiler.cpp:2209 +msgid "Pick the visible color and opacity" +msgstr "A látható szín és átlátszatlanság leolvasása" + +#: ../../po/../src/dialogs/clonetiler.cpp:2216 +#: ../../po/../src/dialogs/clonetiler.cpp:2365 +#: ../share/extensions/dropshadow.inx.h:3 +msgid "Opacity" +msgstr "Átlátszatlanság" + +#: ../../po/../src/dialogs/clonetiler.cpp:2217 +msgid "Pick the total accumulated opacity" +msgstr "A teljes, összegződött átlátszatlanság leolvasása" + +#: ../../po/../src/dialogs/clonetiler.cpp:2224 +msgid "R" +msgstr "V" + +#: ../../po/../src/dialogs/clonetiler.cpp:2225 +msgid "Pick the Red component of the color" +msgstr "A szín vörös-komponensének leolvasása" + +#: ../../po/../src/dialogs/clonetiler.cpp:2232 +msgid "G" +msgstr "Z" + +#: ../../po/../src/dialogs/clonetiler.cpp:2233 +msgid "Pick the Green component of the color" +msgstr "A szín zöld-komponensének leolvasása" + +#: ../../po/../src/dialogs/clonetiler.cpp:2240 +msgid "B" +msgstr "K" + +#: ../../po/../src/dialogs/clonetiler.cpp:2241 +msgid "Pick the Blue component of the color" +msgstr "A szín kék-komponensének leolvasása" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2250 +msgid "clonetiler|H" +msgstr "Á" + +#: ../../po/../src/dialogs/clonetiler.cpp:2251 +msgid "Pick the hue of the color" +msgstr "A szín árnyalatának leolvasása" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2260 +msgid "clonetiler|S" +msgstr "T" + +#: ../../po/../src/dialogs/clonetiler.cpp:2261 +msgid "Pick the saturation of the color" +msgstr "A szín telítettségének leolvasása" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2270 +msgid "clonetiler|L" +msgstr "F" + +#: ../../po/../src/dialogs/clonetiler.cpp:2271 +msgid "Pick the lightness of the color" +msgstr "A szín fényességének leolvasása" + +#: ../../po/../src/dialogs/clonetiler.cpp:2281 +msgid "2. Tweak the picked value:" +msgstr "2. A leolvasott érték módosítása:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2291 +msgid "Gamma-correct:" +msgstr "Gamma-korrekció:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2296 +msgid "Shift the mid-range of the picked value upwards (>0) or downwards (<0)" +msgstr "" +"A leolvasott érték középtartományának eltolása felfelé (>0) vagy lefelé (<0)" + +# TODO: ellenőrizni +#: ../../po/../src/dialogs/clonetiler.cpp:2303 +msgid "Randomize:" +msgstr "Véletlenszerűség:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2308 +msgid "Randomize the picked value by this percentage" +msgstr "A leolvasott érték véletlenszerűsítése ennyi százalékkal" + +#: ../../po/../src/dialogs/clonetiler.cpp:2315 +msgid "Invert:" +msgstr "Invertálás:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2319 +msgid "Invert the picked value" +msgstr "A leolvasott érték invertálása" + +#: ../../po/../src/dialogs/clonetiler.cpp:2325 +msgid "3. Apply the value to the clones':" +msgstr "3. Az érték alkalmazása a klónok ezen tulajdonságaira:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2335 +msgid "Presence" +msgstr "Megjelenés" + +#: ../../po/../src/dialogs/clonetiler.cpp:2338 +msgid "" +"Each clone is created with the probability determined by the picked value in " +"that point" +msgstr "" +"Minden egyes klón az azon pontban leolvasott érték által meghatározott " +"valószínűség szerint van létrehozva" + +#: ../../po/../src/dialogs/clonetiler.cpp:2345 +msgid "Size" +msgstr "Méret" + +#: ../../po/../src/dialogs/clonetiler.cpp:2348 +msgid "Each clone's size is determined by the picked value in that point" +msgstr "" +"Minden egyes klón méretét az azon pontban leolvasott érték határozza meg" + +#: ../../po/../src/dialogs/clonetiler.cpp:2358 +msgid "" +"Each clone is painted by the picked color (the original must have unset fill " +"or stroke)" +msgstr "" +"Minden egyes klón a leolvasott színnel lesz megrajzolva (az eredeti " +"objektumnak vagy kitöltése vagy körvonala ne legyen)" + +#: ../../po/../src/dialogs/clonetiler.cpp:2368 +msgid "Each clone's opacity is determined by the picked value in that point" +msgstr "" +"Minden egyes klón átlátszatlanságát az azon pontban leolvasott érték " +"határozza meg" + +#: ../../po/../src/dialogs/clonetiler.cpp:2395 +msgid "How many rows in the tiling" +msgstr "Sorok száma a csempézésben" + +#: ../../po/../src/dialogs/clonetiler.cpp:2415 +msgid "How many columns in the tiling" +msgstr "Oszlopok száma a csempézésben" + +#: ../../po/../src/dialogs/clonetiler.cpp:2445 +msgid "Width of the rectangle to be filled" +msgstr "A kitöltendő téglalap szélessége" + +#: ../../po/../src/dialogs/clonetiler.cpp:2470 +msgid "Height of the rectangle to be filled" +msgstr "A kitöltendő téglalap magassága" + +#: ../../po/../src/dialogs/clonetiler.cpp:2485 +msgid "Rows, columns: " +msgstr "Sorok, oszlopok: " + +#: ../../po/../src/dialogs/clonetiler.cpp:2486 +msgid "Create the specified number of rows and columns" +msgstr "A megadott számú sor illetve oszlop létrehozása" + +#: ../../po/../src/dialogs/clonetiler.cpp:2495 +msgid "Width, height: " +msgstr "Szélesség, magasság: " + +#: ../../po/../src/dialogs/clonetiler.cpp:2496 +msgid "Fill the specified width and height with the tiling" +msgstr "A megadott szélesség illetve magasság kitöltése a csempézéssel" + +#: ../../po/../src/dialogs/clonetiler.cpp:2512 +msgid "Use saved size and position of the tile" +msgstr "A csempe elmentett méretének és pozíciójának használata" + +#: ../../po/../src/dialogs/clonetiler.cpp:2515 +msgid "" +"Pretend that the size and position of the tile are the same as the last time " +"you tiled it (if any), instead of using the current size" +msgstr "" +"A csempe legutóbbi csempézésekor érvényes méretének és pozíciójának " +"használata (ha van olyan) az aktuális értékek helyett" + +#: ../../po/../src/dialogs/clonetiler.cpp:2539 +msgid " _Create " +msgstr " _Létrehozás " + +#: ../../po/../src/dialogs/clonetiler.cpp:2541 +msgid "Create and tile the clones of the selection" +msgstr "A kijelölés klónjainak létrehozása és csempézése" + +#. TRANSLATORS: if a group of objects are "clumped" together, then they +#. are unevenly spread in the given amount of space - as shown in the +#. diagrams on the left in the following screenshot: +#. http://www.inkscape.org/screenshots/gallery/inkscape-0.42-CVS-tiles-unclump.png +#. So unclumping is the process of spreading a number of objects out more evenly. +#: ../../po/../src/dialogs/clonetiler.cpp:2556 +msgid " _Unclump " +msgstr " E_gyenletesítés " + +#: ../../po/../src/dialogs/clonetiler.cpp:2557 +msgid "Spread out clones to reduce clumping; can be applied repeatedly" +msgstr "" +"A klónok olyan módon való áthelyezése, hogy csökkenjen azok rendezetlensége; " +"ismétlődően is alkalmazható" + +#: ../../po/../src/dialogs/clonetiler.cpp:2563 +msgid " Re_move " +msgstr " _Törlés " + +#: ../../po/../src/dialogs/clonetiler.cpp:2564 +msgid "Remove existing tiled clones of the selected object (siblings only)" +msgstr "" +"A kijelölt objektum csempézett klónjainak eltávolítása (csak testvérek)" + +#: ../../po/../src/dialogs/clonetiler.cpp:2580 +msgid " R_eset " +msgstr " _Visszaállítás " + +#. TRANSLATORS: "change" is a noun here +#: ../../po/../src/dialogs/clonetiler.cpp:2582 +msgid "" +"Reset all shifts, scales, rotates, opacity and color changes in the dialog " +"to zero" +msgstr "" +"Az összes eltolás, átméretezés, elforgatás, átlátszatlanság-módosítás és " +"színmódosítás visszaállítása nullára a párbeszédablakban" + +#: ../../po/../src/dialogs/color-picker.cpp:280 +msgid "Close" +msgstr "Bezárás" + +#: ../../po/../src/dialogs/debugdialog.cpp:138 +msgid "Messages" +msgstr "Üzenetek" + +#. ## Add a menu for clear() +#: ../../po/../src/dialogs/debugdialog.cpp:144 +#: ../../po/../src/menus-skeleton.h:16 +#: ../../po/../src/ui/dialog/messages.cpp:56 +#: ../../po/../src/ui/dialog/scriptdialog.cpp:181 +msgid "_File" +msgstr "_Fájl" + +#. TRANSLATORS: "Clear" is a verb here +#: ../../po/../src/dialogs/debugdialog.cpp:145 +#: ../../po/../src/dialogs/find.cpp:753 +#: ../../po/../src/ui/dialog/messages.cpp:57 +#: ../../po/../src/ui/dialog/scriptdialog.cpp:182 +msgid "_Clear" +msgstr "_Törlés" + +#: ../../po/../src/dialogs/debugdialog.cpp:147 +#: ../../po/../src/ui/dialog/messages.cpp:59 +msgid "Capture log messages" +msgstr "Naplóüzenetek megjelenítése" + +#: ../../po/../src/dialogs/debugdialog.cpp:149 +#: ../../po/../src/ui/dialog/messages.cpp:61 +msgid "Release log messages" +msgstr "Naplóüzenetek megjelenítésének megszüntetése" + +#. Notebook tab +#: ../../po/../src/dialogs/desktop-properties.cpp:909 +#: ../../po/../src/ui/dialog/document-preferences.cpp:89 +#: ../../po/../src/ui/widget/panel.cpp:107 +msgid "Grid" +msgstr "Rács" + +#. Checkbuttons +#. / \todo FIXME: gray out snapping when grid is off +#. / \todo FIXME: gray out snapping when grid is off. +#. / Dissenting view: you want snapping without grid. +#: ../../po/../src/dialogs/desktop-properties.cpp:917 +#: ../../po/../src/ui/dialog/document-preferences.cpp:179 +msgid "Show grid" +msgstr "Rács megjelenítése" + +#: ../../po/../src/dialogs/desktop-properties.cpp:917 +#: ../../po/../src/ui/dialog/document-preferences.cpp:179 +#: ../../po/../src/verbs.cpp:2115 +msgid "Show or hide grid" +msgstr "Rács megjelenítése vagy elrejtése" + +#: ../../po/../src/dialogs/desktop-properties.cpp:918 +#: ../../po/../src/ui/dialog/document-preferences.cpp:180 +msgid "Snap bounding boxes to grid" +msgstr "Határoló téglalapok illesztése a rácsra" + +#: ../../po/../src/dialogs/desktop-properties.cpp:918 +#: ../../po/../src/dialogs/desktop-properties.cpp:1001 +#: ../../po/../src/ui/dialog/document-preferences.cpp:181 +#: ../../po/../src/ui/dialog/document-preferences.cpp:236 +msgid "Snap the edges of the object bounding boxes" +msgstr "Az objektumok határoló téglalapjának széleinek illesztése" + +#: ../../po/../src/dialogs/desktop-properties.cpp:919 +#: ../../po/../src/ui/dialog/document-preferences.cpp:183 +msgid "Snap nodes to grid" +msgstr "Csomópontok illesztése a rácsra" + +#: ../../po/../src/dialogs/desktop-properties.cpp:919 +#: ../../po/../src/dialogs/desktop-properties.cpp:1002 +#: ../../po/../src/ui/dialog/document-preferences.cpp:184 +#: ../../po/../src/ui/dialog/document-preferences.cpp:239 +msgid "Snap path nodes, text baselines, ellipse centers, etc." +msgstr "" +"Lánc-csomópontok, szöveg-alapvonalak, ellipszis-középpontok stb. illesztése" + +#: ../../po/../src/dialogs/desktop-properties.cpp:937 +#: ../../po/../src/ui/dialog/document-preferences.cpp:186 +msgid "Grid units:" +msgstr "Rács-mértékegység:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:939 +#: ../../po/../src/ui/dialog/document-preferences.cpp:187 +msgid "Origin X:" +msgstr "X-origó:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:942 +#: ../../po/../src/ui/dialog/document-preferences.cpp:189 +msgid "Origin Y:" +msgstr "Y-origó:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:945 +#: ../../po/../src/ui/dialog/document-preferences.cpp:191 +msgid "Spacing X:" +msgstr "X-távolság:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:948 +#: ../../po/../src/ui/dialog/document-preferences.cpp:193 +msgid "Spacing Y:" +msgstr "Y-távolság:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:952 +#: ../../po/../src/dialogs/desktop-properties.cpp:1013 +#: ../../po/../src/ui/dialog/document-preferences.cpp:195 +#: ../../po/../src/ui/dialog/document-preferences.cpp:241 +msgid "Snap units:" +msgstr "Illesztési mértékegység:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:955 +#: ../../po/../src/dialogs/desktop-properties.cpp:1016 +#: ../../po/../src/ui/dialog/document-preferences.cpp:196 +#: ../../po/../src/ui/dialog/document-preferences.cpp:242 +msgid "Snap distance:" +msgstr "Illesztési távolság:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:958 +#: ../../po/../src/ui/dialog/document-preferences.cpp:199 +msgid "Grid line color:" +msgstr "A rács színe:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:959 +#: ../../po/../src/ui/dialog/document-preferences.cpp:199 +msgid "Grid line color" +msgstr "A rácsvonalak színe" + +#: ../../po/../src/dialogs/desktop-properties.cpp:959 +#: ../../po/../src/ui/dialog/document-preferences.cpp:200 +msgid "Color of grid lines" +msgstr "A rácsvonalak színe" + +#: ../../po/../src/dialogs/desktop-properties.cpp:961 +#: ../../po/../src/ui/dialog/document-preferences.cpp:201 +msgid "Major grid line color:" +msgstr "A fő-rácsvonalak színe:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:962 +#: ../../po/../src/ui/dialog/document-preferences.cpp:201 +msgid "Major grid line color" +msgstr "A fő-rácsvonalak színe" + +#: ../../po/../src/dialogs/desktop-properties.cpp:962 +#: ../../po/../src/ui/dialog/document-preferences.cpp:202 +msgid "Color of the major (highlighted) grid lines" +msgstr "A fő-rácsvonalak (kiemelt rácsvonalak) színe" + +#: ../../po/../src/dialogs/desktop-properties.cpp:965 +#: ../../po/../src/ui/dialog/document-preferences.cpp:204 +msgid "Major grid line every:" +msgstr "Fő-rácsvonal: minden" + +#. TRANSLATORS: This belongs to the "Major grid line every:" string, +#. see grid settings in the "Document Preferences" dialog +#: ../../po/../src/dialogs/desktop-properties.cpp:977 +#: ../../po/../src/ui/dialog/document-preferences.cpp:204 +msgid "lines" +msgstr ". vonal" + +#. Guidelines page +#: ../../po/../src/dialogs/desktop-properties.cpp:991 +#: ../../po/../src/ui/dialog/document-preferences.cpp:90 +msgid "Guides" +msgstr "Segédvonalak" + +#. / \todo FIXME: gray out snapping when guides are off +#. / Dissenting view: you want snapping without guides. +#: ../../po/../src/dialogs/desktop-properties.cpp:1000 +#: ../../po/../src/ui/dialog/document-preferences.cpp:234 +msgid "Show guides" +msgstr "Segédvonalak megjelenítése" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1000 +#: ../../po/../src/ui/dialog/document-preferences.cpp:234 +#: ../../po/../src/verbs.cpp:2116 +msgid "Show or hide guides" +msgstr "Segédvonalak megjelenítése vagy elrejtése" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1001 +#: ../../po/../src/ui/dialog/document-preferences.cpp:235 +msgid "Snap bounding boxes to guides" +msgstr "Határoló téglalapok illesztése a segédvonalakra" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1002 +#: ../../po/../src/ui/dialog/document-preferences.cpp:238 +msgid "Snap points to guides" +msgstr "Pontok illesztése a segédvonalakra" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1020 +#: ../../po/../src/ui/dialog/document-preferences.cpp:243 +msgid "Guide color:" +msgstr "Segédvonalak színe:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1021 +#: ../../po/../src/ui/dialog/document-preferences.cpp:243 +msgid "Guideline color" +msgstr "Segédvonalak színe" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1021 +#: ../../po/../src/ui/dialog/document-preferences.cpp:244 +msgid "Color of guidelines" +msgstr "A segédvonalak színe" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1023 +#: ../../po/../src/ui/dialog/document-preferences.cpp:245 +msgid "Highlight color:" +msgstr "Kijelölési szín:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1024 +#: ../../po/../src/ui/dialog/document-preferences.cpp:245 +msgid "Highlighted guideline color" +msgstr "Kijelölt segédvonal színe" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1024 +#: ../../po/../src/ui/dialog/document-preferences.cpp:246 +msgid "Color of a guideline when it is under mouse" +msgstr "Az egérmutató alatt levő segédvonal színe" + +#. Page page +#: ../../po/../src/dialogs/desktop-properties.cpp:1029 +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:855 +#: ../../po/../src/ui/dialog/document-preferences.cpp:88 +#: ../../po/../src/widgets/desktop-widget.cpp:1061 +msgid "Page" +msgstr "Lap" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1039 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +msgid "Background:" +msgstr "Háttér:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1040 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +msgid "Background color" +msgstr "Háttérszín" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1041 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +msgid "" +"Color and transparency of the page background (also used for bitmap export)" +msgstr "" +"A lap hátterének színe és átlátszósága (bitkép-exporthoz is fel lesz " +"használva)" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1045 +#: ../../po/../src/ui/dialog/document-preferences.cpp:147 +#, fuzzy +msgid "Show page border" +msgstr "A rajzvászon keretének megjelenítése" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1049 +#: ../../po/../src/ui/dialog/document-preferences.cpp:148 +msgid "Border on top of drawing" +msgstr "A keret a rajz előtt legyen" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1052 +#: ../../po/../src/ui/dialog/document-preferences.cpp:149 +msgid "Border color:" +msgstr "A keret színe:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1053 +#: ../../po/../src/ui/dialog/document-preferences.cpp:149 +#, fuzzy +msgid "Page border color" +msgstr "A rajzvászon keretének színe" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1054 +#: ../../po/../src/ui/dialog/document-preferences.cpp:150 +#, fuzzy +msgid "Color of the page border" +msgstr "A rajzvászon keretének színe" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1059 +#: ../../po/../src/ui/dialog/document-preferences.cpp:152 +msgid "Show page shadow" +msgstr "Lap-árnyék megjelenítése" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1063 +#: ../../po/../src/ui/dialog/document-preferences.cpp:153 +msgid "Default units:" +msgstr "Alapértelmezett mértékegység:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1069 +msgid "Units for the tool controls, ruler, and the statusbar" +msgstr "" +"Az eszközvezérlők, a vonalzó és az állapotsor által használt mértékegység" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1086 +#: ../../po/../src/ui/widget/page-sizer.cpp:209 +#, fuzzy +msgid "Page size:" +msgstr "A rajzvászon mérete:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1110 +#: ../../po/../src/ui/widget/page-sizer.cpp:219 +msgid "Custom" +msgstr "Egyéni" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1121 +#: ../../po/../src/ui/widget/page-sizer.cpp:225 +#, fuzzy +msgid "Page orientation:" +msgstr "A rajzvászon tájolása:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1133 +#: ../../po/../src/ui/widget/page-sizer.cpp:232 +msgid "Landscape" +msgstr "Fekvő" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1139 +#: ../../po/../src/ui/widget/page-sizer.cpp:234 +msgid "Portrait" +msgstr "Álló" + +#. Custom paper frame +#: ../../po/../src/dialogs/desktop-properties.cpp:1148 +#: ../../po/../src/ui/widget/page-sizer.cpp:249 +#, fuzzy +msgid "Custom size" +msgstr "Egyéni" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1160 +#: ../../po/../src/dialogs/export.cpp:269 +#: ../../po/../src/ui/widget/page-sizer.cpp:261 +msgid "Units:" +msgstr "Mértékegység:" + +#. Stroke width +#: ../../po/../src/dialogs/desktop-properties.cpp:1162 +#: ../../po/../src/dialogs/export.cpp:310 +#: ../../po/../src/dialogs/object-attributes.cpp:55 +#: ../../po/../src/dialogs/stroke-style.cpp:985 +#: ../../po/../src/ui/widget/page-sizer.cpp:262 +#: ../../po/../src/widgets/toolbox.cpp:1957 +msgid "Width:" +msgstr "Szélesség:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1183 +#: ../../po/../src/dialogs/export.cpp:326 +#: ../../po/../src/dialogs/export.cpp:431 +#: ../../po/../src/dialogs/object-attributes.cpp:56 +#: ../../po/../src/ui/widget/page-sizer.cpp:263 +msgid "Height:" +msgstr "Magasság:" + +#. +#. * Ownership metadata tab +#. +#: ../../po/../src/dialogs/desktop-properties.cpp:1206 +msgid "Metadata" +msgstr "Metaadatok" + +#. add license selector pull-down +#: ../../po/../src/dialogs/desktop-properties.cpp:1225 +msgid "License" +msgstr "Licenc" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1255 +msgid "Proprietary" +msgstr "Zárt (proprietary)" + +#: ../../po/../src/dialogs/display-settings.cpp:212 +msgid "When transforming, show:" +msgstr "Transzformáció közben megjelenítendő:" + +#: ../../po/../src/dialogs/display-settings.cpp:223 +msgid "Objects" +msgstr "Objektumok" + +#: ../../po/../src/dialogs/display-settings.cpp:224 +msgid "Show the actual objects when moving or transforming" +msgstr "" +"A tényleges objektumok megjelenítése áthelyezéskor illetve transzformáció " +"közben" + +#: ../../po/../src/dialogs/display-settings.cpp:231 +msgid "Box outline" +msgstr "Téglalap-körvonal" + +#: ../../po/../src/dialogs/display-settings.cpp:232 +msgid "Show only a box outline of the objects when moving or transforming" +msgstr "" +"Csak az objektumok téglalap-körvonalának megjelenítése áthelyezéskor illetve " +"transzformáció közben" + +#: ../../po/../src/dialogs/display-settings.cpp:238 +msgid "Per-object selection cue:" +msgstr "Kijelölés objektumonkénti jelzése:" + +#. sorationsnapsperpi == 0 means no snapping +#: ../../po/../src/dialogs/display-settings.cpp:249 +#: ../../po/../src/dialogs/display-settings.cpp:386 +#: ../../po/../src/dialogs/display-settings.cpp:441 +#: ../../po/../src/dialogs/display-settings.cpp:1482 +#: ../../po/../src/dialogs/stroke-style.cpp:791 +#: ../../po/../src/interface.cpp:741 +#: ../../po/../src/ui/widget/selected-style.cpp:100 +#: ../../po/../src/verbs.cpp:1842 +msgid "None" +msgstr "Nincs" + +#: ../../po/../src/dialogs/display-settings.cpp:250 +msgid "No per-object selection indication" +msgstr "Nincs objektumonkénti kijelölés-jelzés" + +#: ../../po/../src/dialogs/display-settings.cpp:256 +msgid "Mark" +msgstr "Jel" + +#: ../../po/../src/dialogs/display-settings.cpp:257 +msgid "Each selected object has a diamond mark in the top left corner" +msgstr "" +"Az összes kijelölt objektum bal felső sarkában megjelenik egy gyémánt alakú " +"jel" + +#: ../../po/../src/dialogs/display-settings.cpp:264 +msgid "Box" +msgstr "Téglalap" + +#: ../../po/../src/dialogs/display-settings.cpp:265 +msgid "Each selected object displays its bounding box" +msgstr "Az összes kijelölt objektum határoló téglalapjának megjelenítése" + +#: ../../po/../src/dialogs/display-settings.cpp:270 +msgid "Default scale origin:" +msgstr "Az átméretezés alapértelmezett origója:" + +#: ../../po/../src/dialogs/display-settings.cpp:281 +msgid "Opposite bounding box edge" +msgstr "A határoló téglalap túlsó széle" + +#: ../../po/../src/dialogs/display-settings.cpp:282 +msgid "Default scale origin will be on the bounding box of the item" +msgstr "" +"Az átméretezés alapértelmezett origója az elem határoló téglalapján lesz" + +#: ../../po/../src/dialogs/display-settings.cpp:288 +msgid "Farthest opposite node" +msgstr "A legtávolabbi túlsó csomópont" + +#: ../../po/../src/dialogs/display-settings.cpp:289 +msgid "Default scale origin will be on the bounding box of the item's points" +msgstr "" +"Az átméretezés alapértelmezett origója az elem pontjainak határoló " +"téglalapján lesz" + +#: ../../po/../src/dialogs/display-settings.cpp:341 +msgid "degrees" +msgstr "fok" + +#: ../../po/../src/dialogs/display-settings.cpp:350 +msgid "" +"Rotating with Ctrl pressed snaps every that much degrees; also, pressing " +"[ or ] rotates by this amount" +msgstr "" +"A Ctrl billentyű nyomva tartásával végzett elforgatás ennyi fokonként " +"történik, továbbá a \"[\" és a \"]\" billentyű ennyivel való elforgatást " +"jelent" + +#: ../../po/../src/dialogs/display-settings.cpp:407 +msgid "Rotation snaps every:" +msgstr "Az elforgatás lépésköze:" + +#: ../../po/../src/dialogs/display-settings.cpp:430 +msgid "" +"None: dialogs are treated as regular windows; Normal: dialogs stay on top of " +"document windows; Aggressive: same as Normal but may work better with some " +"window managers." +msgstr "" +"Nincs: a párbeszédablakok normál ablakokként vannak kezelve; Normál: a " +"párbeszédablakok a dokumentumablakok felett maradnak; Agresszív: megegyezik " +"a Normállal, viszont bizonyos ablakkezelők esetén jobb eredményt nyújthat" + +#: ../../po/../src/dialogs/display-settings.cpp:451 +msgid "Normal" +msgstr "Normál" + +#: ../../po/../src/dialogs/display-settings.cpp:461 +msgid "Aggressive" +msgstr "Agresszív" + +#: ../../po/../src/dialogs/display-settings.cpp:475 +msgid "Dialogs on top:" +msgstr "Párbeszédablakok felülre helyezése:" + +#: ../../po/../src/dialogs/display-settings.cpp:645 +msgid "Show selection cue" +msgstr "Kijelölési jel megjelenítése" + +#: ../../po/../src/dialogs/display-settings.cpp:646 +msgid "" +"Whether selected objects display a selection cue (the same as in selector)" +msgstr "" +"A kijelölt objektumoknál megjelenik-e a megfelelő kijelölési jelző (a " +"kijelölőeszközzel megegyezően)" + +#: ../../po/../src/dialogs/display-settings.cpp:657 +msgid "Enable gradient editing" +msgstr "Színátmenet-szerkesztés engedélyezése" + +#: ../../po/../src/dialogs/display-settings.cpp:658 +msgid "Whether selected objects display gradient editing controls" +msgstr "" +"A kijelölt objektumoknál megjelennek-e a színátmenet-szerkesztési " +"vezérlőelemek" + +#: ../../po/../src/dialogs/display-settings.cpp:719 +msgid "No objects selected to take the style from." +msgstr "Nincs kijelölt objektum, ezért nem lehet stílust átvenni." + +#: ../../po/../src/dialogs/display-settings.cpp:728 +msgid "" +"More than one object selected. Cannot take style from multiple " +"objects." +msgstr "" +"Több objektum van kijelölve. Több objektum esetén nem vehető át a " +"stílus." + +#: ../../po/../src/dialogs/display-settings.cpp:767 +msgid "Create new objects with:" +msgstr "Új objektumok létrehozása ezzel:" + +#: ../../po/../src/dialogs/display-settings.cpp:777 +msgid "Take from selection" +msgstr "Beállítás a kijelölésből" + +#: ../../po/../src/dialogs/display-settings.cpp:778 +msgid "Remember the style of the (first) selected object as this tool's style" +msgstr "Az eszköz stílusa a(z először) kijelölt objektum stílusa legyen" + +#: ../../po/../src/dialogs/display-settings.cpp:782 +#, fuzzy +msgid "Last used style" +msgstr "_Stílus beillesztése" + +#: ../../po/../src/dialogs/display-settings.cpp:782 +msgid "Apply the style you last set on an object" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:790 +msgid "This tool's own style:" +msgstr "Ezen eszköz saját stílusa:" + +#: ../../po/../src/dialogs/display-settings.cpp:790 +msgid "" +"Each tool may store its own style to apply to the newly created objects. Use " +"the button below to set it." +msgstr "" +"Minden eszköz eltárolhatja a saját stílusát, amely az ezt követően " +"létrehozott objektumokra lesz érvényes. A lentebbi gombbal állítható be." + +#. Mouse +#: ../../po/../src/dialogs/display-settings.cpp:877 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:55 +msgid "Mouse" +msgstr "Egér" + +#. TRANSLATORS: "Grab" is a noun here. "Grab sensitivity" is intended to mean how +#. * close on the screen you need to be to an object to be able to grab it with mouse (in +#. * pixels). +#: ../../po/../src/dialogs/display-settings.cpp:883 +msgid "Grab sensitivity:" +msgstr "Megfogási érzékenység:" + +#: ../../po/../src/dialogs/display-settings.cpp:884 +msgid "" +"How close on the screen you need to be to an object to be able to grab it " +"with mouse (in screen pixels)" +msgstr "" +"Milyen közel kell egy objektumhoz lenni (képernyő-képpontban mérve) a " +"képernyőn ahhoz, hogy az egérrel megfogható legyen" + +#: ../../po/../src/dialogs/display-settings.cpp:885 +#: ../../po/../src/dialogs/display-settings.cpp:897 +#: ../../po/../src/dialogs/display-settings.cpp:912 +#: ../../po/../src/dialogs/display-settings.cpp:930 +#: ../../po/../src/dialogs/display-settings.cpp:970 +msgid "pixels" +msgstr "képpont" + +#: ../../po/../src/dialogs/display-settings.cpp:895 +msgid "Click/drag threshold:" +msgstr "Kattintás/húzás határa:" + +#: ../../po/../src/dialogs/display-settings.cpp:896 +msgid "" +"Maximum mouse drag (in screen pixels) which is considered a click, not a drag" +msgstr "" +"Az a maximális húzási távolság (képernyő-képpontban mérve), amely még " +"kattintásnak lesz véve, nem pedig húzásnak" + +#. Scrolling +#: ../../po/../src/dialogs/display-settings.cpp:907 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:56 +msgid "Scrolling" +msgstr "Görgetés" + +#: ../../po/../src/dialogs/display-settings.cpp:910 +msgid "Mouse wheel scrolls by:" +msgstr "Az egérgörgő görgetési mértéke:" + +#: ../../po/../src/dialogs/display-settings.cpp:911 +msgid "" +"One mouse wheel notch scrolls by this distance in screen pixels " +"(horizontally with Shift)" +msgstr "" +"Ennyi képernyő-képponttal görget az egérgörgő egységnyi megmozdítása (a " +"Shift billentyű lenyomása esetén vízszintesen)" + +#: ../../po/../src/dialogs/display-settings.cpp:920 +msgid "Ctrl+arrows" +msgstr "Ctrl+nyilak" + +#: ../../po/../src/dialogs/display-settings.cpp:928 +msgid "Scroll by:" +msgstr "Görgetési mérték:" + +#: ../../po/../src/dialogs/display-settings.cpp:929 +msgid "Pressing Ctrl+arrow key scrolls by this distance (in screen pixels)" +msgstr "" +"A Ctrl és egy nyílbillentyű lenyomása ekkora távolsággal görget (képernyő-" +"képpontban mérve)" + +#: ../../po/../src/dialogs/display-settings.cpp:939 +msgid "Acceleration:" +msgstr "Gyorsítás:" + +#: ../../po/../src/dialogs/display-settings.cpp:940 +msgid "" +"Pressing and holding Ctrl+arrow will gradually speed up scrolling (0 for no " +"acceleration)" +msgstr "" +"\"Ctrl+nyílbillentyű\" kombináció nyomva tartása esetén fokozatosan " +"növekedni fog a görgetési sebesség (0 esetén nincs gyorsítás)" + +#: ../../po/../src/dialogs/display-settings.cpp:949 +msgid "Autoscrolling" +msgstr "Automatikus görgetés" + +#: ../../po/../src/dialogs/display-settings.cpp:957 +msgid "Speed:" +msgstr "Sebesség:" + +#: ../../po/../src/dialogs/display-settings.cpp:958 +msgid "" +"How fast the canvas autoscrolls when you drag beyond canvas edge (0 to turn " +"autoscroll off)" +msgstr "" +"A rajzvászon automatikus görgetésének sebessége a rajzvászon szélén túl való " +"húzáskor (0 esetén nincs automatikus görgetés)" + +#: ../../po/../src/dialogs/display-settings.cpp:968 +#: ../../po/../src/ui/dialog/tracedialog.cpp:357 +#: ../../po/../src/ui/dialog/tracedialog.cpp:390 +msgid "Threshold:" +msgstr "Küszöb:" + +#: ../../po/../src/dialogs/display-settings.cpp:969 +msgid "" +"How far (in screen pixels) you need to be from the canvas edge to trigger " +"autoscroll; positive is outside the canvas, negative is within the canvas" +msgstr "" +"Mekkora távolságra kell lenni (képernyő-képpontban mérve) a rajzvászon " +"szélétől ahhoz, hogy az automatikus görgetés aktivizálódjon; a pozitív " +"értékek a rajzvásznon kívüli területet jelölik, a negatívok pedig az azon " +"belülit" + +#. Steps +#: ../../po/../src/dialogs/display-settings.cpp:979 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:57 +msgid "Steps" +msgstr "Lépésközök" + +#: ../../po/../src/dialogs/display-settings.cpp:982 +msgid "Arrow keys move by:" +msgstr "A nyílbillentyűk elmozdítási mértéke:" + +#: ../../po/../src/dialogs/display-settings.cpp:983 +msgid "" +"Pressing an arrow key moves selected object(s) or node(s) by this distance " +"(in px units)" +msgstr "" +"Egy nyílbillentyű lenyomása ekkora távolságra (képpontban (px) mérve) " +"mozdítja el a kijelölt objektumo(ka)t illetve csomóponto(ka)t" + +#: ../../po/../src/dialogs/display-settings.cpp:984 +#: ../../po/../src/dialogs/display-settings.cpp:995 +#: ../../po/../src/dialogs/display-settings.cpp:1006 +#: ../../po/../src/helper/units.cpp:42 +msgid "px" +msgstr "px" + +#: ../../po/../src/dialogs/display-settings.cpp:993 +msgid "> and < scale by:" +msgstr "A \">\" és a \"<\" billentyű méretezési mértéke:" + +#: ../../po/../src/dialogs/display-settings.cpp:994 +msgid "" +"Pressing > or < scales selection up or down by this increment (in px units)" +msgstr "" +"A \">\" illetve a \"<\" billentyű lenyomása ennyivel méretezi át (képpontban " +"(px) mérve) a kijelölést (felfelé illetve lefelé)" + +#: ../../po/../src/dialogs/display-settings.cpp:1004 +msgid "Inset/Outset by:" +msgstr "Zsugorítás/nyújtás mértéke:" + +#: ../../po/../src/dialogs/display-settings.cpp:1005 +msgid "" +"Inset and Outset commands displace the path by this distance (in px units)" +msgstr "" +"A zsugorítási és a nyújtási művelet ekkora (képpontokban (px) megadott) " +"távolsággal mozdítja el a láncot" + +#: ../../po/../src/dialogs/display-settings.cpp:1017 +msgid "Compass-like display of angles" +msgstr "Szögek iránytű-szerű megjelenítése" + +#. TRANSLATORS: "positive clockwise" means "increasing in clockwise direction" +#: ../../po/../src/dialogs/display-settings.cpp:1019 +msgid "" +"When on, angles are displayed with 0 at north, 0 to 360 range, positive " +"clockwise; otherwise with 0 at east, -180 to 180 range, positive " +"counterclockwise" +msgstr "" +"Ha be van kapcsolva, akkor a szögek megjelenítésénél az északi irány jelenti " +"a 0-t, a tartomány 0-tól 360-ig terjed, az értékek pedig az óramutató járása " +"szerinti irányban növekednek. Ha nincs bekapcsolva, akkor a keleti irány " +"jelenti a 0-t, a tartomány -180-tól 180-ig terjed, az értékek pedig az " +"óramutató járásával ellentétes irányban növekednek." + +#: ../../po/../src/dialogs/display-settings.cpp:1026 +msgid "Zoom in/out by:" +msgstr "Nagyítás/kicsinyítés mértéke:" + +#: ../../po/../src/dialogs/display-settings.cpp:1027 +msgid "" +"Zoom tool click, +/- keys, and middle click zoom in and out by this " +"multiplier" +msgstr "" +"A nagyítóeszköz, a \"+\" illetve a \"-\" billentyűk és a középső egérgombbal " +"való kattintás ekkora arányban nagyít illetve kicsinyít" + +#: ../../po/../src/dialogs/display-settings.cpp:1028 +#: ../../po/../src/helper/units.cpp:44 +msgid "%" +msgstr "%" + +#. Tools +#: ../../po/../src/dialogs/display-settings.cpp:1037 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:58 +msgid "Tools" +msgstr "Eszközök" + +#: ../../po/../src/dialogs/display-settings.cpp:1045 +msgid "Selector" +msgstr "Kijelölés" + +#: ../../po/../src/dialogs/display-settings.cpp:1056 +msgid "Node" +msgstr "Csomópont" + +#: ../../po/../src/dialogs/display-settings.cpp:1064 +#: ../../po/../src/verbs.cpp:2073 +#: ../../po/../src/widgets/desktop-widget.cpp:277 +msgid "Zoom" +msgstr "Nagyítás" + +#. The 4 shape tools +#: ../../po/../src/dialogs/display-settings.cpp:1071 +msgid "Shapes" +msgstr "Alakzatok" + +#: ../../po/../src/dialogs/display-settings.cpp:1079 +#: ../../po/../src/verbs.cpp:2055 +msgid "Rectangle" +msgstr "Téglalap" + +#: ../../po/../src/dialogs/display-settings.cpp:1085 +#: ../../po/../src/verbs.cpp:2057 +msgid "Ellipse" +msgstr "Ellipszis" + +#: ../../po/../src/dialogs/display-settings.cpp:1091 +#: ../../po/../src/verbs.cpp:2059 +msgid "Star" +msgstr "Csillag" + +#: ../../po/../src/dialogs/display-settings.cpp:1097 +#: ../../po/../src/verbs.cpp:2061 +msgid "Spiral" +msgstr "Spirál" + +#: ../../po/../src/dialogs/display-settings.cpp:1111 +#: ../../po/../src/verbs.cpp:2063 +msgid "Pencil" +msgstr "Ceruza" + +#: ../../po/../src/dialogs/display-settings.cpp:1114 +msgid "Tolerance:" +msgstr "Tűrés:" + +#: ../../po/../src/dialogs/display-settings.cpp:1115 +msgid "" +"This value affects the amount of smoothing applied to freehand lines; lower " +"values produce more uneven paths with more nodes" +msgstr "" +"Ez az érték megszabja, hogy mekkora mértékű simítás legyen alkalmazva a " +"szabadkézi vonalakra; alacsonyabb érték esetén a láncok kevésbé lesznek " +"egyenletesek és több csomópontot fognak tartalmazni" + +#: ../../po/../src/dialogs/display-settings.cpp:1131 +#: ../../po/../src/verbs.cpp:2065 +msgid "Pen" +msgstr "Toll" + +#: ../../po/../src/dialogs/display-settings.cpp:1140 +#: ../../po/../src/verbs.cpp:2067 +msgid "Calligraphy" +msgstr "Művészi rajz" + +#: ../../po/../src/dialogs/display-settings.cpp:1147 +#: ../../po/../src/dialogs/text-edit.cpp:353 +#: ../../po/../src/ui/dialog/text-properties.cpp:37 +#: ../../po/../src/verbs.cpp:2069 +msgid "Text" +msgstr "Szöveg" + +#: ../../po/../src/dialogs/display-settings.cpp:1157 +#: ../../po/../src/verbs.cpp:2071 +msgid "Gradient" +msgstr "Színátmenet" + +#: ../../po/../src/dialogs/display-settings.cpp:1164 +#: ../../po/../src/verbs.cpp:2077 +msgid "Connector" +msgstr "Kapocs" + +#: ../../po/../src/dialogs/display-settings.cpp:1171 +#: ../../po/../src/verbs.cpp:2075 +msgid "Dropper" +msgstr "Színpipetta" + +#. Windows +#: ../../po/../src/dialogs/display-settings.cpp:1183 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:59 +msgid "Windows" +msgstr "Ablakok" + +#: ../../po/../src/dialogs/display-settings.cpp:1188 +msgid "Save window geometry" +msgstr "Ablakgeometria elmentése" + +#: ../../po/../src/dialogs/display-settings.cpp:1189 +msgid "" +"Save the window size and position with each document (only for Inkscape SVG " +"format)" +msgstr "" +"Ablakméret és -pozíció elmentése minden dokumentumba (csak Inkscape SVG " +"fájlformátum esetén)" + +#: ../../po/../src/dialogs/display-settings.cpp:1196 +msgid "Dialogs are hidden in taskbar" +msgstr "Párbeszédablakok ne jelenjenek meg a feladatlistában" + +#: ../../po/../src/dialogs/display-settings.cpp:1197 +msgid "Whether dialog windows are to be hidden in the window manager taskbar" +msgstr "" +"A párbeszédablakok ki legyenek-e hagyva az ablakkezelő által megjelenített " +"feladatlistából" + +#: ../../po/../src/dialogs/display-settings.cpp:1204 +msgid "Zoom when window is resized" +msgstr "Nagyítás módosítása az ablakméret változásakor" + +#: ../../po/../src/dialogs/display-settings.cpp:1205 +msgid "" +"Zoom drawing when document window is resized, to keep the same area visible " +"(this is the default which can be changed in any window using the button " +"above the right scrollbar)" +msgstr "" +"A rajz nagyítási mértékének módosítása a dokumentumablak átméretezésekor - " +"így átméretezés után ugyanaz a terület lesz látható, mint előtte. Az itt " +"megadott érték az alapértelmezés. Minden egyes ablakban külön-külön is " +"beállítható a kívánt viselkedés a jobb oldali gördítősáv feletti gombbal." + +#. Clones +#: ../../po/../src/dialogs/display-settings.cpp:1213 +#: ../../po/../src/dialogs/find.cpp:624 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:60 +msgid "Clones" +msgstr "Klónok" + +#: ../../po/../src/dialogs/display-settings.cpp:1217 +msgid "When the original moves, its clones and linked offsets:" +msgstr "Az eredeti objektum áthelyezésekor a klónjai és a kapcsolt peremei:" + +#: ../../po/../src/dialogs/display-settings.cpp:1229 +msgid "Move in parallel" +msgstr "Párhuzamosan elmozdulnak" + +#: ../../po/../src/dialogs/display-settings.cpp:1230 +msgid "Clones are translated by the same vector as their original." +msgstr "" +"A klónok ugyanazzal a vektorral lesznek elmozdítva, mint az eredeti objektum" + +#: ../../po/../src/dialogs/display-settings.cpp:1237 +msgid "Stay unmoved" +msgstr "Nem mozdulnak el" + +#: ../../po/../src/dialogs/display-settings.cpp:1238 +msgid "Clones preserve their positions when their original is moved." +msgstr "A klónok helye nem változik az eredeti objektum elmozdításakor" + +#: ../../po/../src/dialogs/display-settings.cpp:1245 +msgid "Move according to transform" +msgstr "A \"transform\" tulajdonság szerint mozdulnak el" + +#: ../../po/../src/dialogs/display-settings.cpp:1246 +msgid "" +"Each clone moves according to the value of its transform= attribute. For " +"example, a rotated clone will move in a different direction than its " +"original." +msgstr "" +"Minden klón a saját \"transform=\" tulajdonságának értéke szerint mozdul el. " +"Példa: egy elforgatott klón más irányba mozdulhat el, mint az eredeti " +"objektum." + +#: ../../po/../src/dialogs/display-settings.cpp:1255 +msgid "When the original is deleted, its clones:" +msgstr "Az eredeti objektum törlésekor a klónjai:" + +#: ../../po/../src/dialogs/display-settings.cpp:1267 +msgid "Are unlinked" +msgstr "Lekapcsolódnak" + +#: ../../po/../src/dialogs/display-settings.cpp:1267 +msgid "Orphaned clones are converted to regular objects." +msgstr "Az elárvult klónok normál objektumokká lesznek alakítva" + +#: ../../po/../src/dialogs/display-settings.cpp:1273 +msgid "Are deleted" +msgstr "Törlődnek" + +#: ../../po/../src/dialogs/display-settings.cpp:1273 +msgid "Orphaned clones are deleted along with their original." +msgstr "Az elárvult klónok az eredeti objektummal együtt törlődnek" + +#. Transforms +#. TRANSLATORS: Noun, i.e. transformations. +#: ../../po/../src/dialogs/display-settings.cpp:1289 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:61 +msgid "Transforms" +msgstr "Transzformációk" + +#: ../../po/../src/dialogs/display-settings.cpp:1292 +msgid "Scale stroke width" +msgstr "Körvonalszélesség átméretezése" + +#: ../../po/../src/dialogs/display-settings.cpp:1293 +#: ../../po/../src/widgets/select-toolbar.cpp:568 +msgid "When scaling objects, scale the stroke width by the same proportion" +msgstr "" +"Objektumok átméretezésekor a körvonalszélesség is legyen - azonos arányban - " +"átméretezve" + +#: ../../po/../src/dialogs/display-settings.cpp:1300 +msgid "Scale rounded corners in rectangles" +msgstr "Lekerekített csúcsok átméretezése a téglalapokban" + +#: ../../po/../src/dialogs/display-settings.cpp:1301 +#: ../../po/../src/widgets/select-toolbar.cpp:580 +msgid "When scaling rectangles, scale the radii of rounded corners" +msgstr "" +"Téglalapok átméretezésekor a lekerekített csúcsok sugarai is legyenek " +"átméretezve" + +#: ../../po/../src/dialogs/display-settings.cpp:1308 +msgid "Transform gradients" +msgstr "Színátmenetek transzformációja" + +#: ../../po/../src/dialogs/display-settings.cpp:1309 +#: ../../po/../src/widgets/select-toolbar.cpp:592 +msgid "Transform gradients (in fill or stroke) along with the objects" +msgstr "" +"Színátmenetek transzformációja (kitöltésben és körvonalban) az objektumokkal " +"együtt" + +#: ../../po/../src/dialogs/display-settings.cpp:1316 +msgid "Transform patterns" +msgstr "Minták transzformációja" + +#: ../../po/../src/dialogs/display-settings.cpp:1317 +#: ../../po/../src/widgets/select-toolbar.cpp:604 +msgid "Transform patterns (in fill or stroke) along with the objects" +msgstr "" +"Minták transzformációja (kitöltésben és körvonalban) az objektumokkal együtt" + +#. TRANSLATORS: How to specify the affine transformation in the SVG file. +#: ../../po/../src/dialogs/display-settings.cpp:1327 +msgid "Store transformation:" +msgstr "Transzformáció tárolása:" + +#: ../../po/../src/dialogs/display-settings.cpp:1338 +msgid "Optimized" +msgstr "Optimalizálva" + +#: ../../po/../src/dialogs/display-settings.cpp:1339 +msgid "" +"If possible, apply transformation to objects without adding a transform= " +"attribute" +msgstr "" +"\"transform=\" tulajdonság hozzáadása nélkül legyenek alkalmazva a " +"transzformációk az objektumokra, amikor csak lehetséges" + +#: ../../po/../src/dialogs/display-settings.cpp:1346 +msgid "Preserved" +msgstr "Megőrizve" + +#: ../../po/../src/dialogs/display-settings.cpp:1347 +msgid "Always store transformation as a transform= attribute on objects" +msgstr "" +"A transzformációk mindig \"transform=\" objektumtulajdonságban legyenek " +"eltárolva" + +#. Selecting +#: ../../po/../src/dialogs/display-settings.cpp:1355 +msgid "Selecting" +msgstr "Kijelölés" + +#: ../../po/../src/dialogs/display-settings.cpp:1357 +msgid "Ctrl+A, Tab, Shift+Tab:" +msgstr "Ctrl+A, Tab, Shift+Tab:" + +#: ../../po/../src/dialogs/display-settings.cpp:1366 +msgid "Select only within current layer" +msgstr "Kijelölés csak az aktuális rétegben" + +#: ../../po/../src/dialogs/display-settings.cpp:1367 +msgid "" +"Uncheck this to make keyboard selection commands work on objects in all " +"layers" +msgstr "" +"Ha nincs bejelölve, akkor a kijelölési billentyűkombinációk az összes réteg " +"objektumaira vonatkoznak" + +#: ../../po/../src/dialogs/display-settings.cpp:1374 +msgid "Ignore hidden objects" +msgstr "Rejtett objektumok figyelmen kívül való hagyása" + +#: ../../po/../src/dialogs/display-settings.cpp:1375 +msgid "" +"Uncheck this to be able to select objects that are hidden (either by " +"themselves or by being in a hidden group or layer)" +msgstr "" +"Ha nincs bejelölve, akkor a rejtett objektumokat (vagyis azon objektumokat, " +"amelyek vagy egyénileg rejtettek, vagy egy rejtett csoportban illetve " +"rétegben vannak) is ki lehet jelölni" + +#: ../../po/../src/dialogs/display-settings.cpp:1382 +msgid "Ignore locked objects" +msgstr "Zárolt objektumok figyelmen kívül való hagyása" + +#: ../../po/../src/dialogs/display-settings.cpp:1383 +msgid "" +"Uncheck this to be able to select objects that are locked (either by " +"themselves or by being in a locked group or layer)" +msgstr "" +"Ha nincs bejelölve, akkor a zárolt objektumokat (vagyis azon objektumokat, " +"amelyek vagy egyénileg zároltak, vagy egy zárolt csoportban illetve rétegben " +"vannak) is ki lehet jelölni" + +#. To be broken into: Display, Save, Export, SVG, Commands +#: ../../po/../src/dialogs/display-settings.cpp:1391 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:62 +msgid "Misc" +msgstr "Egyéb" + +#: ../../po/../src/dialogs/display-settings.cpp:1394 +msgid "Default export resolution:" +msgstr "Alapértelmezett exportálási felbontás:" + +#: ../../po/../src/dialogs/display-settings.cpp:1395 +msgid "Default bitmap resolution (in dots per inch) in the Export dialog" +msgstr "" +"Az alapértelmezett bitkép-felbontás (pont/hüvelykben) az exportálási " +"párbeszédablakban" + +#. FIXME: add "Used for new exports; once exported, documents remember this value on per-object basis" when implemented +#: ../../po/../src/dialogs/display-settings.cpp:1396 +#: ../../po/../src/dialogs/export.cpp:442 +msgid "dpi" +msgstr "DPI" + +#. TRANSLATORS: When on, an imported bitmap creates an element; otherwise it is a +#. * rectangle with bitmap fill. +#: ../../po/../src/dialogs/display-settings.cpp:1407 +msgid "Import bitmap as " +msgstr "Bitkép importálása -ként" + +#: ../../po/../src/dialogs/display-settings.cpp:1408 +msgid "" +"When on, an imported bitmap creates an element; otherwise it is a " +"rectangle with bitmap fill" +msgstr "" +"Ha a beállítás be van kapcsolva, akkor az importált bitképekhez egy " +"elem jön létre; ha pedig ki van kapcsolva, akkor téglalap jön létre bitkép-" +"kitöltéssel" + +#. TRANSLATORS: When on, the print out (currently Postscript) will have +#. * a comment with the each object's label visible, marking the section +#. * of the printing commands that represent the given object. +#: ../../po/../src/dialogs/display-settings.cpp:1418 +msgid "Add label comments to printing output" +msgstr "Címke-megjegyzések a nyomtatási kimenetbe" + +#: ../../po/../src/dialogs/display-settings.cpp:1419 +msgid "" +"When on, a comment will be added to the raw print output, marking the " +"rendered output for an object with its label" +msgstr "" +"Ha be van kapcsolva, akkor a nyers nyomtatási kimenetbe megjegyzések lesznek " +"helyezve - megjelölve az illető objektumokat azok címkéjével" + +#. TRANSLATORS: When on, enable the effects menu, default is off +#: ../../po/../src/dialogs/display-settings.cpp:1427 +msgid "Enable script effects (requires restart) - EXPERIMENTAL" +msgstr "" +"Szkript-effektusok engedélyezése (program-újraindítást igényel) - KÍSÉRLETI " +"FUNKCIÓ" + +#: ../../po/../src/dialogs/display-settings.cpp:1428 +msgid "" +"When on, the effects menu is enabled, allowing external effect scripts to be " +"called, requires restart before effective - EXPERIMENTAL" +msgstr "" +"Ha be van kapcsolva, akkor az Effektusok menü bekapcsolt állapotban van - " +"lehetővé téve külső effektus-programok végrehajtását. Az érvénybelépéshez " +"program-újraindítás szükséges. Egyelőre kísérleti funkció." + +#. TRANSLATORS: The maximum length of the Open Recent list in the File menu. +#: ../../po/../src/dialogs/display-settings.cpp:1436 +msgid "Max recent documents:" +msgstr "Legutóbbi dokumentumok maximális száma:" + +#: ../../po/../src/dialogs/display-settings.cpp:1437 +msgid "The maximum length of the Open Recent list in the File menu" +msgstr "" +"A Fájl menüben megjelenő \"Legutóbbi megnyitása\" lista maximális hossza" + +#: ../../po/../src/dialogs/display-settings.cpp:1447 +msgid "Simplification threshold:" +msgstr "Egyszerűsítési küszöb:" + +#: ../../po/../src/dialogs/display-settings.cpp:1448 +msgid "" +"How strong is the Simplify command by default. If you invoke this command " +"several times in quick succession, it will act more and more aggressively; " +"invoking it again after a pause restores the default threshold." +msgstr "" +"Az Egyszerűsítés művelet alapértelmezett erőssége. Ha ez a művelet gyors " +"egymásutánban többször végrehajtásra kerül, akkor egyre erőteljesebb hatást " +"fog kifejteni; ha viszont egy szünetet követően kerül újra végrehajtásra, " +"akkor visszaáll az alapértelmezett küszöb." + +#: ../../po/../src/dialogs/display-settings.cpp:1469 +msgid "Oversample bitmaps:" +msgstr "Bitképek túlmintavételezése:" + +#: ../../po/../src/dialogs/display-settings.cpp:1488 +msgid "2x2" +msgstr "2x2" + +#: ../../po/../src/dialogs/display-settings.cpp:1494 +msgid "4x4" +msgstr "4x4" + +#: ../../po/../src/dialogs/display-settings.cpp:1500 +msgid "8x8" +msgstr "8x8" + +#: ../../po/../src/dialogs/display-settings.cpp:1506 +msgid "16x16" +msgstr "16x16" + +#. "view_icon_preview" +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2143 +msgid "_Page" +msgstr "_Lap" + +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2147 +msgid "_Drawing" +msgstr "_Rajz" + +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2149 +msgid "_Selection" +msgstr "_Kijelölés" + +#: ../../po/../src/dialogs/export.cpp:133 +msgid "_Custom" +msgstr "Egyén_i" + +#: ../../po/../src/dialogs/export.cpp:254 +msgid "Export area" +msgstr "Exportálási terület" + +#: ../../po/../src/dialogs/export.cpp:300 +msgid "_x0:" +msgstr "_x0:" + +#: ../../po/../src/dialogs/export.cpp:305 +msgid "x_1:" +msgstr "x_1:" + +#: ../../po/../src/dialogs/export.cpp:316 +msgid "_y0:" +msgstr "y_0:" + +#: ../../po/../src/dialogs/export.cpp:321 +msgid "y_1:" +msgstr "_y1:" + +#: ../../po/../src/dialogs/export.cpp:406 +msgid "Bitmap size" +msgstr "Bitkép mérete" + +#: ../../po/../src/dialogs/export.cpp:416 +msgid "_Width:" +msgstr "_Szélesség:" + +#: ../../po/../src/dialogs/export.cpp:416 +#: ../../po/../src/dialogs/export.cpp:431 +msgid "pixels at" +msgstr "képpont; felbontás:" + +#: ../../po/../src/dialogs/export.cpp:426 +msgid "dp_i" +msgstr "_DPI" + +#: ../../po/../src/dialogs/export.cpp:448 +msgid "_Filename" +msgstr "_Fájlnév" + +#: ../../po/../src/dialogs/export.cpp:512 +msgid "_Browse..." +msgstr "_Tallózás..." + +#: ../../po/../src/dialogs/export.cpp:539 +msgid " _Export " +msgstr " _Exportálás " + +#: ../../po/../src/dialogs/export.cpp:541 +msgid "Export the bitmap file with these settings" +msgstr "Exportálás bitkép-fájlba a megadott beállításokkal" + +#: ../../po/../src/dialogs/export.cpp:968 +msgid "You have to enter a filename" +msgstr "Meg kell adni egy fájlnevet" + +#: ../../po/../src/dialogs/export.cpp:973 +msgid "The chosen area to be exported is invalid" +msgstr "Az exportálásra kijelölt terület érvénytelen" + +#: ../../po/../src/dialogs/export.cpp:982 +#, c-format +msgid "Directory %s does not exist or is not a directory.\n" +msgstr "\"%s\" nevű könyvtár nem létezik, vagy az objektum nem könyvtár.\n" + +#: ../../po/../src/dialogs/export.cpp:998 +msgid "Export in progress" +msgstr "Exportálás folyamatban" + +#: ../../po/../src/dialogs/export.cpp:1004 +#, c-format +msgid "Exporting %s (%d x %d)" +msgstr "Exportálás (%s, %d x %d)" + +#: ../../po/../src/dialogs/export.cpp:1031 +#, c-format +msgid "Could not export to filename %s.\n" +msgstr "Nem sikerült \"%s\" nevű fájlba exportálni.\n" + +#: ../../po/../src/dialogs/export.cpp:1137 +msgid "Select a filename for exporting" +msgstr "Adjon meg egy fájlnevet az exportáláshoz" + +#: ../../po/../src/dialogs/filedialog.cpp:367 +msgid "No preview" +msgstr "Nincs előnézet" + +#: ../../po/../src/dialogs/filedialog.cpp:468 +msgid "too large for preview" +msgstr "előnézet-készítéshez túl nagy" + +#: ../../po/../src/dialogs/filedialog.cpp:762 +#: ../../po/../src/dialogs/filedialog.cpp:763 +msgid "All Images" +msgstr "Az összes kép" + +#: ../../po/../src/dialogs/filedialog.cpp:767 +#: ../../po/../src/dialogs/filedialog.cpp:768 +msgid "All Files" +msgstr "Az összes fájl" + +#: ../../po/../src/dialogs/filedialog.cpp:774 +#: ../../po/../src/dialogs/filedialog.cpp:775 +msgid "All Inkscape Files" +msgstr "Az összes Inkscape-fájl" + +#: ../../po/../src/dialogs/filedialog.cpp:1176 +msgid "Guess from extension" +msgstr "Meghatározás a fájlkiterjesztés alapján" + +#. ###### Add the file types menu +#. createFilterMenu(); +#. ###### Do we want the .xxx extension automatically added? +#: ../../po/../src/dialogs/filedialog.cpp:1261 +msgid "Append filename extension automatically" +msgstr "Fájlkiterjesztés automatikus hozzáfűzése" + +#. TRANSLATORS: "%s" is replaced with "exact" or "partial" when this string is displayed +#: ../../po/../src/dialogs/find.cpp:378 +#, c-format +msgid "%d object found (out of %d), %s match." +msgid_plural "%d objects found (out of %d), %s match." +msgstr[0] "%d találat (%d objektumból), %s egyezés." +msgstr[1] "%d találat (%d objektumból), %s egyezés." + +#: ../../po/../src/dialogs/find.cpp:381 +msgid "exact" +msgstr "pontos" + +#: ../../po/../src/dialogs/find.cpp:381 +msgid "partial" +msgstr "részleges" + +#: ../../po/../src/dialogs/find.cpp:388 +msgid "No objects found" +msgstr "Nincs találat" + +#: ../../po/../src/dialogs/find.cpp:546 +msgid "T_ype: " +msgstr "Tí_pus: " + +#: ../../po/../src/dialogs/find.cpp:553 +msgid "Search in all object types" +msgstr "A keresés terjedjen ki az összes objektumtípusra" + +#: ../../po/../src/dialogs/find.cpp:553 +msgid "All types" +msgstr "Az összes típus" + +#: ../../po/../src/dialogs/find.cpp:564 +msgid "Search all shapes" +msgstr "Keresés az összes alakzatra" + +#: ../../po/../src/dialogs/find.cpp:564 +msgid "All shapes" +msgstr "Az összes alakzat" + +#: ../../po/../src/dialogs/find.cpp:581 +msgid "Search rectangles" +msgstr "Keresés téglalapokra" + +#: ../../po/../src/dialogs/find.cpp:581 +msgid "Rectangles" +msgstr "Téglalapok" + +#: ../../po/../src/dialogs/find.cpp:586 +msgid "Search ellipses, arcs, circles" +msgstr "Keresés ellipszisekre, ellipszisívekre és körökre" + +#: ../../po/../src/dialogs/find.cpp:586 +msgid "Ellipses" +msgstr "Ellipszisek" + +#: ../../po/../src/dialogs/find.cpp:591 +msgid "Search stars and polygons" +msgstr "Keresés csillagokra és sokszögekre" + +#: ../../po/../src/dialogs/find.cpp:591 +msgid "Stars" +msgstr "Csillagok" + +#: ../../po/../src/dialogs/find.cpp:596 +msgid "Search spirals" +msgstr "Keresés spirálokra" + +#: ../../po/../src/dialogs/find.cpp:596 +msgid "Spirals" +msgstr "Spirálok" + +#. TRANSLATORS: polyline is a set of connected straight line segments +#. http://www.w3.org/TR/SVG11/shapes.html#PolylineElement +#: ../../po/../src/dialogs/find.cpp:609 +msgid "Search paths, lines, polylines" +msgstr "Keresés láncokra, vonalakra és kapcsolódó vonalakra" + +#: ../../po/../src/dialogs/find.cpp:609 +msgid "Paths" +msgstr "Láncok" + +#: ../../po/../src/dialogs/find.cpp:614 +msgid "Search text objects" +msgstr "Keresés szövegre" + +#: ../../po/../src/dialogs/find.cpp:614 +msgid "Texts" +msgstr "Szövegek" + +#: ../../po/../src/dialogs/find.cpp:619 +msgid "Search groups" +msgstr "Keresés csoportokra" + +#: ../../po/../src/dialogs/find.cpp:619 +msgid "Groups" +msgstr "Csoportok" + +#: ../../po/../src/dialogs/find.cpp:624 +msgid "Search clones" +msgstr "Keresés klónokra" + +#: ../../po/../src/dialogs/find.cpp:629 +msgid "Search images" +msgstr "Keresés képekre" + +#: ../../po/../src/dialogs/find.cpp:629 +msgid "Images" +msgstr "Képek" + +#: ../../po/../src/dialogs/find.cpp:634 +msgid "Search offset objects" +msgstr "Keresés peremobjektumokra" + +#: ../../po/../src/dialogs/find.cpp:634 +msgid "Offsets" +msgstr "Peremobjektumok" + +#: ../../po/../src/dialogs/find.cpp:694 +msgid "_Text: " +msgstr "Szö_veg: " + +#: ../../po/../src/dialogs/find.cpp:694 +msgid "Find objects by their text content (exact or partial match)" +msgstr "" +"Objektumok keresése a szövegtartalmuk alapján (pontos vagy részleges egyezés)" + +#: ../../po/../src/dialogs/find.cpp:695 +msgid "_ID: " +msgstr "_Azonosító: " + +#: ../../po/../src/dialogs/find.cpp:695 +msgid "Find objects by the value of the id attribute (exact or partial match)" +msgstr "" +"Objektumok keresése az azonosítójuk (az \"id\" tulajdonságuk értéke) alapján " +"(pontos vagy részleges egyezés)" + +#: ../../po/../src/dialogs/find.cpp:696 +msgid "_Style: " +msgstr "_Stílus: " + +#: ../../po/../src/dialogs/find.cpp:696 +msgid "" +"Find objects by the value of the style attribute (exact or partial match)" +msgstr "" +"Objektumok keresése a stílusuk (a \"style\" tulajdonságuk értéke) alapján " +"(pontos vagy részleges egyezés)" + +#: ../../po/../src/dialogs/find.cpp:697 +msgid "_Attribute: " +msgstr "Attri_bútum: " + +#: ../../po/../src/dialogs/find.cpp:697 +msgid "Find objects by the name of an attribute (exact or partial match)" +msgstr "" +"Objektumok keresése egy attribútum (tulajdonság) neve alapján (pontos vagy " +"részleges egyezés)" + +#: ../../po/../src/dialogs/find.cpp:711 +msgid "Search in s_election" +msgstr "Keresés a ki_jelölésben" + +#: ../../po/../src/dialogs/find.cpp:715 +msgid "Limit search to the current selection" +msgstr "A keresés csak az aktuális kijelölésre vonatkozzon" + +#: ../../po/../src/dialogs/find.cpp:720 +msgid "Search in current _layer" +msgstr "Keresés az aktuális réte_gben" + +#: ../../po/../src/dialogs/find.cpp:724 +msgid "Limit search to the current layer" +msgstr "A keresés csak az aktuális rétegre vonatkozzon" + +#: ../../po/../src/dialogs/find.cpp:729 +msgid "Include _hidden" +msgstr "_Rejtettekkel együtt" + +#: ../../po/../src/dialogs/find.cpp:733 +msgid "Include hidden objects in search" +msgstr "A keresés terjedjen ki a rejtett objektumokra is" + +#: ../../po/../src/dialogs/find.cpp:738 +msgid "Include l_ocked" +msgstr "_Zároltakkal együtt" + +#: ../../po/../src/dialogs/find.cpp:742 +msgid "Include locked objects in search" +msgstr "A keresés terjedjen ki a zárolt objektumokra is" + +#: ../../po/../src/dialogs/find.cpp:753 +msgid "Clear values" +msgstr "Az értékek törlése" + +#: ../../po/../src/dialogs/find.cpp:754 +msgid "_Find" +msgstr "K_eresés" + +#: ../../po/../src/dialogs/find.cpp:754 +msgid "Select objects matching all of the fields you filled in" +msgstr "Az összes kitöltött mező értékére illeszkedő objektumok kijelölése" + +#: ../../po/../src/dialogs/iconpreview.cpp:145 +#, c-format +msgid "%d x %d" +msgstr "%d x %d" + +#: ../../po/../src/dialogs/iconpreview.cpp:193 +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:857 +#: ../../po/../src/widgets/desktop-widget.cpp:1069 +msgid "Selection" +msgstr "Kijelölés" + +#: ../../po/../src/dialogs/iconpreview.cpp:195 +msgid "Selection only or whole document" +msgstr "Csak a kijelölés, vagy az egész dokumentum" + +#: ../../po/../src/dialogs/iconpreview.cpp:203 +msgid "Refresh the icons" +msgstr "Az ikonok frissítése" + +#. Create the label for the object id +#: ../../po/../src/dialogs/item-properties.cpp:126 +#: ../../po/../src/dialogs/item-properties.cpp:327 +#: ../../po/../src/dialogs/item-properties.cpp:396 +#: ../../po/../src/dialogs/item-properties.cpp:403 +msgid "_Id" +msgstr "_Azonosító" + +#: ../../po/../src/dialogs/item-properties.cpp:135 +msgid "" +"The id= attribute (only letters, digits, and the characters .-_: allowed)" +msgstr "" +"Az \"id=\" tulajdonság (a felhasználható karakterek: betűk, számjegyek, " +"továbbá a következők: .:-_)" + +#. Button for setting the object's id, label, title and description. +#: ../../po/../src/dialogs/item-properties.cpp:149 +msgid "_Set" +msgstr "_Beállítás" + +#. Create the label for the object label +#: ../../po/../src/dialogs/item-properties.cpp:158 +msgid "_Label" +msgstr "_Címke" + +#: ../../po/../src/dialogs/item-properties.cpp:167 +msgid "A freeform label for the object" +msgstr "Az objektum címkéje; kötetlen formátumú" + +# May contain a short, human readable description of the resource as plain, unmarked text. +#. Create the label for the object title +#: ../../po/../src/dialogs/item-properties.cpp:179 +#: ../../po/../src/dialogs/rdf.cpp:243 +msgid "Title" +msgstr "Cím" + +#. Create the frame for the object description +#: ../../po/../src/dialogs/item-properties.cpp:196 +#: ../../po/../src/dialogs/rdf.cpp:287 +msgid "Description" +msgstr "Leírás" + +#. Hide +#: ../../po/../src/dialogs/item-properties.cpp:223 +msgid "_Hide" +msgstr "El_rejtés" + +#: ../../po/../src/dialogs/item-properties.cpp:224 +msgid "Check to make the object invisible" +msgstr "Ha szeretné az objektumot láthatatlanná tenni, akkor jelölje be" + +#. Lock +#. TRANSLATORS: "Lock" is a verb here +#: ../../po/../src/dialogs/item-properties.cpp:233 +msgid "L_ock" +msgstr "_Zárolás" + +#: ../../po/../src/dialogs/item-properties.cpp:234 +msgid "Check to make the object insensitive (not selectable by mouse)" +msgstr "" +"Ha szeretné megszüntetni az objektum érzékenységét (annak érdekében, hogy ne " +"lehessen azt egérrel kijelölni), akkor jelölje be" + +#: ../../po/../src/dialogs/item-properties.cpp:310 +#: ../../po/../src/dialogs/item-properties.cpp:317 +msgid "Ref" +msgstr "Hivatkozás" + +#: ../../po/../src/dialogs/item-properties.cpp:398 +msgid "Id invalid! " +msgstr "Érvénytelen azonosító " + +#: ../../po/../src/dialogs/item-properties.cpp:400 +msgid "Id exists! " +msgstr "Az azonosító már létezik " + +#: ../../po/../src/dialogs/layer-properties.cpp:50 +msgid "Layer name:" +msgstr "A réteg neve:" + +#: ../../po/../src/dialogs/layer-properties.cpp:133 +msgid "Rename Layer" +msgstr "Réteg átnevezése" + +#: ../../po/../src/dialogs/layer-properties.cpp:136 +msgid "_Rename" +msgstr "Átne_vezés" + +#. TRANSLATORS: This means "The layer has been renamed" +#: ../../po/../src/dialogs/layer-properties.cpp:147 +msgid "Renamed layer" +msgstr "A réteg átnevezése megtörtént." + +#: ../../po/../src/dialogs/layer-properties.cpp:151 +msgid "Add Layer" +msgstr "Réteg felvétele" + +#: ../../po/../src/dialogs/layer-properties.cpp:153 +msgid "_Add" +msgstr "_Felvétel" + +#: ../../po/../src/dialogs/layer-properties.cpp:167 +msgid "New layer created." +msgstr "Új réteg létrehozva." + +# Contains a URI, possibly relative, pointing to the related resource +#: ../../po/../src/dialogs/object-attributes.cpp:34 +msgid "Href:" +msgstr "Hivatkozás (href):" + +#: ../../po/../src/dialogs/object-attributes.cpp:35 +msgid "Target:" +msgstr "Cél (target):" + +#: ../../po/../src/dialogs/object-attributes.cpp:36 +msgid "Type:" +msgstr "Típus (type):" + +# Identifies the type of the related resource with an absolute URI +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkRoleAttribute +#. Identifies the type of the related resource with an absolute URI +#: ../../po/../src/dialogs/object-attributes.cpp:39 +msgid "Role:" +msgstr "Fajta (role):" + +# For situations where the nature/role alone isn't enough, this offers an additional URI defining the purpose of the link. +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkArcRoleAttribute +#. For situations where the nature/role alone isn't enough, this offers an additional URI defining the purpose of the link. +#: ../../po/../src/dialogs/object-attributes.cpp:42 +msgid "Arcrole:" +msgstr "Szerep (arcrole):" + +# May contain a short, human readable description of the resource as plain, unmarked text. +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkTitleAttribute +#: ../../po/../src/dialogs/object-attributes.cpp:44 +msgid "Title:" +msgstr "Leírás (title):" + +#: ../../po/../src/dialogs/object-attributes.cpp:45 +msgid "Show:" +msgstr "Megjelenítés (show):" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkActuateAttribute +#: ../../po/../src/dialogs/object-attributes.cpp:47 +msgid "Actuate:" +msgstr "Indítás (actuate):" + +#: ../../po/../src/dialogs/object-attributes.cpp:52 +msgid "URL:" +msgstr "URL:" + +#: ../../po/../src/dialogs/object-attributes.cpp:53 +msgid "X:" +msgstr "X:" + +#: ../../po/../src/dialogs/object-attributes.cpp:54 +msgid "Y:" +msgstr "Y:" + +#: ../../po/../src/dialogs/object-attributes.cpp:98 +#, c-format +msgid "%s attributes" +msgstr "%s tulajdonságai" + +#: ../../po/../src/dialogs/object-properties.cpp:158 +msgid "_Fill" +msgstr "K_itöltés" + +#: ../../po/../src/dialogs/object-properties.cpp:165 +msgid "Stroke _paint" +msgstr "Körv_onalrajzolat" + +#: ../../po/../src/dialogs/object-properties.cpp:172 +msgid "Stroke st_yle" +msgstr "Körvonalstíl_us" + +#: ../../po/../src/dialogs/object-properties.cpp:183 +msgid "Master _opacity" +msgstr "Ala_p-átlátszatlanság" + +#: ../../po/../src/dialogs/rdf.cpp:244 +msgid "Name by which this document is formally known." +msgstr "A dokumentum formális neve." + +#: ../../po/../src/dialogs/rdf.cpp:246 +msgid "Date" +msgstr "Dátum" + +#: ../../po/../src/dialogs/rdf.cpp:247 +msgid "Date associated with the creation of this document (YYYY-MM-DD)." +msgstr "A dokumentum létrehozásához kapcsolható dátum (ÉÉÉÉ-HH-NN)." + +#: ../../po/../src/dialogs/rdf.cpp:249 +msgid "Format" +msgstr "Formátum" + +#: ../../po/../src/dialogs/rdf.cpp:250 +msgid "The physical or digital manifestation of this document (MIME type)." +msgstr "A dokumentum fizikai vagy digitális formátuma (MIME-típus)." + +#: ../../po/../src/dialogs/rdf.cpp:252 +msgid "Type" +msgstr "Típus" + +#: ../../po/../src/dialogs/rdf.cpp:253 +msgid "Type of document (DCMI Type)." +msgstr "A dokumentum típusa (DCMI-típus)." + +#: ../../po/../src/dialogs/rdf.cpp:256 +msgid "Creator" +msgstr "Készítő" + +#: ../../po/../src/dialogs/rdf.cpp:257 +msgid "" +"Name of entity primarily responsible for making the content of this document." +msgstr "" +"A dokumentum tartalmának elkészítéséért elsődlegesen felelős személy " +"(entitás) neve." + +#: ../../po/../src/dialogs/rdf.cpp:259 +msgid "Rights" +msgstr "Jogok" + +#: ../../po/../src/dialogs/rdf.cpp:260 +msgid "" +"Name of entity with rights to the Intellectual Property of this document." +msgstr "" +"A dokumentum szellemi tulajdonjogaival rendelkező személy (entitás) neve." + +#: ../../po/../src/dialogs/rdf.cpp:262 +msgid "Publisher" +msgstr "Kiadó" + +#: ../../po/../src/dialogs/rdf.cpp:263 +msgid "Name of entity responsible for making this document available." +msgstr "A dokumentum elérhetővé tételéért felelős személy (entitás) neve." + +#: ../../po/../src/dialogs/rdf.cpp:266 +msgid "Identifier" +msgstr "Azonosító" + +#: ../../po/../src/dialogs/rdf.cpp:267 +msgid "Unique URI to reference this document." +msgstr "A dokumentumra való hivatkozásra használható egyedi URI." + +#: ../../po/../src/dialogs/rdf.cpp:269 +msgid "Source" +msgstr "Forrás" + +#: ../../po/../src/dialogs/rdf.cpp:270 +msgid "Unique URI to reference the source of this document." +msgstr "A dokumentum forrására való hivatkozásra használható egyedi URI." + +#: ../../po/../src/dialogs/rdf.cpp:272 +msgid "Relation" +msgstr "Kapcsolat" + +#: ../../po/../src/dialogs/rdf.cpp:273 +msgid "Unique URI to a related document." +msgstr "Egy kapcsolódó dokumentumra utaló egyedi URI." + +#: ../../po/../src/dialogs/rdf.cpp:275 +msgid "Language" +msgstr "Nyelv" + +#: ../../po/../src/dialogs/rdf.cpp:276 +msgid "" +"Two-letter language tag with optional subtags for the language of this " +"document. (e.g. 'en-GB')" +msgstr "" +"A dokumentum nyelvének kétbetűs jele esetlegesen ellátva kiegészítő jelekkel " +"(példa: \"en-GB\")." + +#: ../../po/../src/dialogs/rdf.cpp:278 +msgid "Keywords" +msgstr "Kulcsszavak" + +#: ../../po/../src/dialogs/rdf.cpp:279 +msgid "" +"The topic of this document as comma-separated key words, phrases, or " +"classifications." +msgstr "" +"A dokumentum témája - kulcsszavak, kifejezések vagy besorolások vesszővel " +"elválasztva." + +#. TRANSLATORS: "Coverage": the spatial or temporal characteristics of the content. +#. For info, see Appendix D of http://www.w3.org/TR/1998/WD-rdf-schema-19980409/ +#: ../../po/../src/dialogs/rdf.cpp:283 +msgid "Coverage" +msgstr "Hely/idő" + +#: ../../po/../src/dialogs/rdf.cpp:284 +msgid "Extent or scope of this document." +msgstr "A dokumentum által átfogott hely vagy idő." + +#: ../../po/../src/dialogs/rdf.cpp:288 +msgid "A short account of the content of this document." +msgstr "A dokumentum tartalmának rövid leírása." + +#. FIXME: need to handle 1 agent per line of input +#: ../../po/../src/dialogs/rdf.cpp:292 +msgid "Contributors" +msgstr "Közreműködők" + +#: ../../po/../src/dialogs/rdf.cpp:293 +msgid "" +"Names of entities responsible for making contributions to the content of " +"this document." +msgstr "" +"A dokumentum tartalmának elkészítésében közreműködő személyek (entitások) " +"neve." + +#. TRANSLATORS: URL to a page that defines the license for the document +#: ../../po/../src/dialogs/rdf.cpp:297 +msgid "URI" +msgstr "URI" + +#. TRANSLATORS: this is where you put a URL to a page that defines the license +#: ../../po/../src/dialogs/rdf.cpp:299 +msgid "URI to this document's license's namespace definition." +msgstr "A dokumentum licencének névtérdefiníciójára utaló URI." + +#. TRANSLATORS: fragment of XML representing the license of the document +#: ../../po/../src/dialogs/rdf.cpp:303 +msgid "Fragment" +msgstr "Rész" + +#: ../../po/../src/dialogs/rdf.cpp:304 +msgid "XML fragment for the RDF 'License' section." +msgstr "Az RDF szerinti \"Licenc\" szakaszt tartalmazó XML-rész." + +#: ../../po/../src/dialogs/stroke-style.cpp:774 +#: ../../po/../src/widgets/gradient-vector.cpp:263 +#: ../../po/../src/widgets/paint-selector.cpp:751 +msgid "No document selected" +msgstr "Nincs kijelölve dokumentum" + +#: ../../po/../src/dialogs/stroke-style.cpp:992 +msgid "Stroke width" +msgstr "Körvonalszélesség" + +#. Join type +#. TRANSLATORS: The line join style specifies the shape to be used at the +#. corners of paths. It can be "miter", "round" or "bevel". +#: ../../po/../src/dialogs/stroke-style.cpp:1015 +msgid "Join:" +msgstr "Sarok:" + +#. TRANSLATORS: Miter join: joining lines with a sharp (pointed) corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1027 +msgid "Miter join" +msgstr "Hegyes sarok" + +#. TRANSLATORS: Round join: joining lines with a rounded corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1035 +msgid "Round join" +msgstr "Lekerekített sarok" + +#. TRANSLATORS: Bevel join: joining lines with a blunted (flattened) corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1043 +msgid "Bevel join" +msgstr "Levágott sarok" + +#. Miterlimit +#. TRANSLATORS: Miter limit: only for "miter join", this limits the length +#. of the sharp "spike" when the lines connect at too sharp an angle. +#. When two line segments meet at a sharp angle, a miter join results in a +#. spike that extends well beyond the connection point. The purpose of the +#. miter limit is to cut off such spikes (i.e. convert them into bevels) +#. when they become too long. +#: ../../po/../src/dialogs/stroke-style.cpp:1054 +msgid "Miter limit:" +msgstr "Túlnyúlási korlát:" + +#: ../../po/../src/dialogs/stroke-style.cpp:1062 +msgid "Maximum length of the miter (in units of stroke width)" +msgstr "A csúcs maximális hossza (a körvonalszélesség arányában megadva)" + +#. Cap type +#. TRANSLATORS: cap type specifies the shape for the ends of lines +#: ../../po/../src/dialogs/stroke-style.cpp:1075 +msgid "Cap:" +msgstr "Vonalvég:" + +#. TRANSLATORS: Butt cap: the line shape does not extend beyond the end point +#. of the line; the ends of the line are square +#: ../../po/../src/dialogs/stroke-style.cpp:1086 +msgid "Butt cap" +msgstr "Szögletes, levágott vonalvég" + +#. TRANSLATORS: Round cap: the line shape extends beyond the end point of the +#. line; the ends of the line are rounded +#: ../../po/../src/dialogs/stroke-style.cpp:1093 +msgid "Round cap" +msgstr "Lekerekített vonalvég" + +#. TRANSLATORS: Square cap: the line shape extends beyond the end point of the +#. line; the ends of the line are square +#: ../../po/../src/dialogs/stroke-style.cpp:1100 +msgid "Square cap" +msgstr "Négyzetszerű vonalvég" + +#. Dash +#: ../../po/../src/dialogs/stroke-style.cpp:1106 +msgid "Dashes:" +msgstr "Vonalminta:" + +#. TRANSLATORS: Path markers are an SVG feature that allows you to attach arbitrary shapes +#. (arrowheads, bullets, faces, whatever) to the start, end, or middle nodes of a path. +#: ../../po/../src/dialogs/stroke-style.cpp:1127 +msgid "Start Markers:" +msgstr "Kezdet jelölése:" + +#: ../../po/../src/dialogs/stroke-style.cpp:1137 +msgid "Mid Markers:" +msgstr "Közép jelölése:" + +#: ../../po/../src/dialogs/stroke-style.cpp:1148 +msgid "End Markers:" +msgstr "Vég jelölése:" + +#: ../../po/../src/dialogs/swatches.cpp:424 +#, c-format +msgid "Palettes directory (%s) is unavailable." +msgstr "A palettakönyvtár (%s) nem elérhető." + +#. TODO: Insert widgets +#: ../../po/../src/dialogs/text-edit.cpp:199 +#: ../../po/../src/ui/dialog/text-properties.cpp:36 +msgid "Font" +msgstr "Betűtípus" + +#: ../../po/../src/dialogs/text-edit.cpp:216 +msgid "Layout" +msgstr "Elrendezés" + +#: ../../po/../src/dialogs/text-edit.cpp:229 +msgid "Align lines left" +msgstr "Sorok igazítása balra" + +#. TRANSLATORS: `Center' here is a verb. +#: ../../po/../src/dialogs/text-edit.cpp:243 +msgid "Center lines" +msgstr "Sorok igazítása középre" + +#: ../../po/../src/dialogs/text-edit.cpp:256 +msgid "Align lines right" +msgstr "Sorok igazítása jobbra" + +#: ../../po/../src/dialogs/text-edit.cpp:278 +msgid "Horizontal text" +msgstr "Vízszintes szöveg" + +#: ../../po/../src/dialogs/text-edit.cpp:292 +msgid "Vertical text" +msgstr "Függőleges szöveg" + +#: ../../po/../src/dialogs/text-edit.cpp:307 +msgid "Line spacing:" +msgstr "Sortávolság:" + +#: ../../po/../src/dialogs/text-edit.cpp:400 +msgid "Set as default" +msgstr "Beállítás alapértelmezésnek" + +#: ../../po/../src/dialogs/tiledialog.cpp:603 +msgid "Rows:" +msgstr "Sorok száma:" + +#: ../../po/../src/dialogs/tiledialog.cpp:613 +msgid "Number of rows" +msgstr "A sorok száma" + +#: ../../po/../src/dialogs/tiledialog.cpp:617 +msgid "Equal height" +msgstr "Azonos magasság" + +#: ../../po/../src/dialogs/tiledialog.cpp:627 +msgid "If not set, each row has the height of the tallest object in it" +msgstr "" +"Ha nincs bejelölve, akkor minden sor magassága a benne levő legmagasabb " +"objektuméval lesz egyenlő" + +#. #### Radio buttons to control vertical alignment #### +#. #### Radio buttons to control horizontal alignment #### +#: ../../po/../src/dialogs/tiledialog.cpp:637 +#: ../../po/../src/dialogs/tiledialog.cpp:708 +msgid "Align:" +msgstr "Igazítás:" + +#: ../../po/../src/dialogs/tiledialog.cpp:672 +msgid " X " +msgstr " X " + +#. #### Number of columns #### +#: ../../po/../src/dialogs/tiledialog.cpp:678 +msgid "Columns:" +msgstr "Oszlopok száma:" + +#: ../../po/../src/dialogs/tiledialog.cpp:688 +msgid "Number of columns" +msgstr "Az oszlopok száma" + +#: ../../po/../src/dialogs/tiledialog.cpp:692 +msgid "Equal width" +msgstr "Azonos szélesség" + +#: ../../po/../src/dialogs/tiledialog.cpp:701 +msgid "If not set, each column has the width of the widest object in it" +msgstr "" +"Ha nincs bejelölve, akkor minden oszlop szélessége a benne levő legszélesebb " +"objektuméval lesz egyenlő" + +#. #### Radio buttons to control spacing manually or to fit selection bbox #### +#: ../../po/../src/dialogs/tiledialog.cpp:746 +msgid "Fit into selection box" +msgstr "Illesztés a kijelölési téglalapba" + +#: ../../po/../src/dialogs/tiledialog.cpp:753 +msgid "Set spacing:" +msgstr "Helykihagyás beállítása:" + +#. #### Y Padding #### +#: ../../po/../src/dialogs/tiledialog.cpp:777 +msgid "Row spacing: " +msgstr "Sortávolság: " + +#: ../../po/../src/dialogs/tiledialog.cpp:786 +msgid "Vertical spacing between rows" +msgstr "Függőleges helykihagyás a sorok közt" + +#. #### X padding #### +#: ../../po/../src/dialogs/tiledialog.cpp:795 +msgid "Column spacing:" +msgstr "Oszloptávolság:" + +#: ../../po/../src/dialogs/tiledialog.cpp:804 +msgid "Horizontal spacing between columns" +msgstr "Vízszintes helykihagyás az oszlopok közt" + +#: ../../po/../src/dialogs/tiledialog.cpp:818 +#, fuzzy +msgid "Arrange selected objects" +msgstr "A kijelölt objektumok csoportba foglalása" + +#: ../../po/../src/dialogs/xml-tree.cpp:178 +msgid "Click to select nodes, drag to rearrange." +msgstr "" +"Csomópontok kijelölése: kattintással. Átrendezés: húzással." + +#: ../../po/../src/dialogs/xml-tree.cpp:189 +msgid "Click attribute to edit." +msgstr "Egy tulajdonság szerkesztéséhez kattintson rá arra." + +#: ../../po/../src/dialogs/xml-tree.cpp:193 +#, c-format +msgid "" +"Attribute %s selected. Press Ctrl+Enter when done editing to " +"commit changes." +msgstr "" +"A(z) \"%s\" tulajdonság lett kijelölve. A szerkesztés végeztével " +"nyomja le a Ctrl+Enter billentyűkombinációt a módosítások " +"érvényesítéséhez." + +#: ../../po/../src/dialogs/xml-tree.cpp:284 +msgid "Drag to reorder nodes" +msgstr "A csomópontok átrendezhetők az egérrel" + +#: ../../po/../src/dialogs/xml-tree.cpp:304 +msgid "New element node" +msgstr "Új elemcsomópont" + +#: ../../po/../src/dialogs/xml-tree.cpp:326 +msgid "New text node" +msgstr "Új szövegcsomópont" + +#: ../../po/../src/dialogs/xml-tree.cpp:347 +msgid "Duplicate node" +msgstr "Csomópont kettőzése" + +#: ../../po/../src/dialogs/xml-tree.cpp:368 +msgid "Delete node" +msgstr "Csomópont törlése" + +#: ../../po/../src/dialogs/xml-tree.cpp:384 +msgid "Unindent node" +msgstr "Csomópontot egy szinttel kijjebb" + +#: ../../po/../src/dialogs/xml-tree.cpp:399 +msgid "Indent node" +msgstr "Csomópontot egy szinttel beljebb" + +#: ../../po/../src/dialogs/xml-tree.cpp:411 +msgid "Raise node" +msgstr "Csomópontot eggyel feljebb" + +#: ../../po/../src/dialogs/xml-tree.cpp:423 +msgid "Lower node" +msgstr "Csomópontot eggyel lejjebb" + +#: ../../po/../src/dialogs/xml-tree.cpp:468 +msgid "Delete attribute" +msgstr "Tulajdonság törlése" + +#. TRANSLATORS: "Attribute" is a noun here +#: ../../po/../src/dialogs/xml-tree.cpp:513 +msgid "Attribute name" +msgstr "Tulajdonságnév" + +#. TRANSLATORS: "Set" is a verb here +#: ../../po/../src/dialogs/xml-tree.cpp:533 +msgid "Set attribute" +msgstr "Tulajdonság beállítása" + +#. TRANSLATORS: "Set" is a verb here +#: ../../po/../src/dialogs/xml-tree.cpp:535 +msgid "Set" +msgstr "Beállítás" + +#. TRANSLATORS: "Attribute" is a noun here +#: ../../po/../src/dialogs/xml-tree.cpp:558 +msgid "Attribute value" +msgstr "A tulajdonság értéke" + +#: ../../po/../src/dialogs/xml-tree.cpp:1318 +msgid "New element node..." +msgstr "Új elemcsomópont..." + +#: ../../po/../src/dialogs/xml-tree.cpp:1339 +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:100 +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:98 +msgid "Cancel" +msgstr "Mégsem" + +#: ../../po/../src/dialogs/xml-tree.cpp:1345 +msgid "Create" +msgstr "Létrehozás" + +#: ../../po/../src/dialogs/xml-tree.cpp:1458 +#, c-format +msgid "" +"Cannot set %s: Another element with value %s already exists!" +msgstr "" +"\"%s\" nem állítható be: már létezik \"%s\" értékkel " +"rendelkező elem." + +#: ../../po/../src/document.cpp:369 +#, c-format +msgid "New document %d" +msgstr "Új dokumentum %d" + +#: ../../po/../src/document.cpp:401 +#, c-format +msgid "Memory document %d" +msgstr "Memóriadokumentum %d" + +#: ../../po/../src/document.cpp:524 +#, c-format +msgid "Unnamed document %d" +msgstr "Névtelen dokumentum %d" + +#. We hit green anchor, closing Green-Blue-Red +#: ../../po/../src/draw-context.cpp:441 +msgid "Path is closed." +msgstr "A lánc lezárva." + +#. We hit bot start and end of single curve, closing paths +#: ../../po/../src/draw-context.cpp:456 +msgid "Closing path." +msgstr "A lánc lezárása." + +#. alpha of color under cursor, to show in the statusbar +#. locale-sensitive printf is OK, since this goes to the UI, not into SVG +#: ../../po/../src/dropper-context.cpp:354 +#, c-format +msgid " alpha %.3g" +msgstr " alfa: %.3g" + +#. where the color is picked, to show in the statusbar +#: ../../po/../src/dropper-context.cpp:356 +#, c-format +msgid ", averaged with radius %d" +msgstr ", átlagolva - sugár: %d" + +#: ../../po/../src/dropper-context.cpp:356 +msgid " under cursor" +msgstr " a kurzor alatt" + +#. message, to show in the statusbar +#: ../../po/../src/dropper-context.cpp:358 +msgid "Release mouse to set color." +msgstr "Színbeállításhoz engedje fel az egérgombot." + +#: ../../po/../src/dropper-context.cpp:358 +#: ../../po/../src/tools-switch.cpp:207 +msgid "" +"Click to set fill, Shift+click to set stroke; drag to " +"average color in area; with Alt to pick inverse color; Ctrl+C " +"to copy the color under mouse to clipboard" +msgstr "" +"A kitöltési szín kattintással állítható be, a körvonalszín pedig " +"Shift+kattintással. Egy terület átlagszínének leolvasása: " +"húzással. Inverz szín leolvasása: Alt. Az egérkurzor alatti " +"szín másolása a vágólapra: Ctrl+C." + +#: ../../po/../src/extension/dependency.cpp:244 +msgid "Dependency::" +msgstr "Függőség::" + +#: ../../po/../src/extension/dependency.cpp:245 +msgid " type: " +msgstr " típus: " + +#: ../../po/../src/extension/dependency.cpp:246 +msgid " location: " +msgstr " hely: " + +#: ../../po/../src/extension/dependency.cpp:247 +msgid " string: " +msgstr " szöveg: " + +#: ../../po/../src/extension/dependency.cpp:250 +msgid " description: " +msgstr " leírás: " + +#. static int i = 0; +#. std::cout << "Checking module[" << i++ << "]: " << name << std::endl; +#: ../../po/../src/extension/extension.cpp:244 +msgid "" +" This is caused by an improper .inx file for this extension. An improper ." +"inx file could have been caused by a faulty installation of Inkscape." +msgstr "" +" Ennek oka: helytelen \".inx\"-fájl tartozik a kiterjesztéshez. Helytelen \"." +"inx\"-fájl például egy hibás Inkscape-telepítésből származhat." + +#: ../../po/../src/extension/extension.cpp:247 +msgid "an ID was not defined for it." +msgstr "nincs megadva hozzá azonosító." + +#: ../../po/../src/extension/extension.cpp:251 +msgid "there was no name defined for it." +msgstr "nincs megadva hozzá név." + +#: ../../po/../src/extension/extension.cpp:255 +msgid "the XML description of it got lost." +msgstr "az XML-leírása elveszett." + +#: ../../po/../src/extension/extension.cpp:259 +msgid "no implementation was defined for the extension." +msgstr "a kiterjesztéshez nincs megadva megvalósítás." + +#. std::cout << "Failed: " << *(_deps[i]) << std::endl; +#: ../../po/../src/extension/extension.cpp:266 +msgid "a dependency was not met." +msgstr "egy függőség nem teljesül." + +#: ../../po/../src/extension/extension.cpp:286 +msgid "Extension \"" +msgstr "A(z) \"" + +#: ../../po/../src/extension/extension.cpp:286 +msgid "\" failed to load because " +msgstr "\" kiterjesztést nem sikerült betölteni, mivel " + +#: ../../po/../src/extension/extension.cpp:565 +#, c-format +msgid "Could not create extension error log file '%s'" +msgstr "" +"Nem sikerült \"%s\" nevű fájlt létrehozni a kiterjesztések hibanaplója " +"számára" + +#. This is some filler text, needs to change before relase +#: ../../po/../src/extension/error-file.cpp:56 +msgid "" +"One or more extensions failed to load\n" +"\n" +"The failed extensions have been skipped. Inkscape will continue to run " +"normally but those extensions will be unavailable. For details to " +"troubleshoot this problem, please refer to the error log located at: " +msgstr "" +"Egy vagy több kiterjesztést nem " +"sikerült betölteni.\n" +"\n" +"A nem betölthető kiterjesztések ki lettek hagyva. Az Inkscape normál módon " +"fog működni, de ezek a kiterjesztések nem lesznek elérhetők. A probléma " +"részleteit tartalmazó hibanapló a következő helyen található:" + +#. This is some filler text, needs to change before relase +#: ../../po/../src/extension/error-file.cpp:65 +msgid "Show dialog on startup" +msgstr "Párbeszédablak megjelenítése indításkor" + +#: ../../po/../src/extension/implementation/script.cpp:845 +msgid "" +"Inkscape has received an error from the script that it called. The text " +"returned with the error is included below. Inkscape will continue working, " +"but the action you requested has been cancelled." +msgstr "" +"Az Inkscape egy hibaüzenetet kapott a meghívott programtól. A hibaüzenet " +"szövege lentebb látható. Az Inkscape működése folytatódik, de a kért " +"tevékenység nem lett végrehajtva." + +#: ../../po/../src/extension/implementation/script.cpp:858 +msgid "" +"Inkscape has received additional data from the script executed. The script " +"did not return an error, but this may indicate the results will not be as " +"expected." +msgstr "" +"Az Inkscape további adatokat kapott a végrehajtott programtól. A program nem " +"adott hibaüzenetet, de elképzelhető, hogy az eredmény el fog térni a várttól." + +#: ../../po/../src/extension/init.cpp:173 +msgid "Null external module directory name. Modules will not be loaded." +msgstr "" +"A külső modulok könyvtárának neve nincs megadva. A modulok nem lesznek " +"betöltve." + +#: ../../po/../src/extension/init.cpp:187 +#, c-format +msgid "" +"Modules directory (%s) is unavailable. External modules in that directory " +"will not be loaded." +msgstr "" +"A modulkönyvtár (%s) nem elérhető. Az abban levő külső modulok nem lesznek " +"betöltve." + +#: ../../po/../src/extension/internal/gnome.cpp:80 +msgid "Select printer" +msgstr "Nyomtató kiválasztása" + +#: ../../po/../src/extension/internal/gnome.cpp:131 +msgid "Inkscape: Print Preview" +msgstr "Inkscape: nyomtatási kép" + +#: ../../po/../src/extension/internal/grid.cpp:213 +msgid "Line Width" +msgstr "Vonalszélesség" + +#: ../../po/../src/extension/internal/grid.cpp:214 +msgid "Horizontal Spacing" +msgstr "Vízszintes helykihagyás" + +#: ../../po/../src/extension/internal/grid.cpp:215 +msgid "Vertical Spacing" +msgstr "Függőleges helykihagyás" + +#: ../../po/../src/extension/internal/grid.cpp:216 +msgid "Horizontal Offset" +msgstr "Vízszintes eltolás" + +#: ../../po/../src/extension/internal/grid.cpp:217 +msgid "Vertical Offset" +msgstr "Függőleges eltolás" + +#: ../../po/../src/extension/internal/ps.cpp:123 +msgid "Print Destination" +msgstr "Nyomtatási cél" + +#. Print properties frame +#: ../../po/../src/extension/internal/ps.cpp:138 +msgid "Print properties" +msgstr "Nyomtatási tulajdonságok" + +#: ../../po/../src/extension/internal/ps.cpp:145 +msgid "Print using PostScript operators" +msgstr "Nyomtatás PostScript-műveletekkel" + +#: ../../po/../src/extension/internal/ps.cpp:147 +msgid "" +"Use PostScript vector operators. The resulting image is usually smaller in " +"file size and can be arbitrarily scaled, but alpha transparency and patterns " +"will be lost." +msgstr "" +"A PostScript vektorműveleteinek használata. Az így készített kép általában " +"kisebb fájlméretű és tetszőlegesen méretezhető, viszont az átlátszóság és a " +"minták elvesznek." + +#: ../../po/../src/extension/internal/ps.cpp:152 +msgid "Print as bitmap" +msgstr "Nyomtatás bitképként" + +#: ../../po/../src/extension/internal/ps.cpp:154 +msgid "" +"Print everything as bitmap. The resulting image is usually larger in file " +"size and cannot be arbitrarily scaled without quality loss, but all objects " +"will be rendered exactly as displayed." +msgstr "" +"Minden objektum bitképként való nyomtatása. Az így készített kép általában " +"nagyobb fájlméretű, továbbá nem lehet tetszőlegesen nagyítani " +"minőségveszteség nélkül, viszont az objektumok megjelenése megegyezik a " +"képernyőn látottal." + +#: ../../po/../src/extension/internal/ps.cpp:168 +msgid "Preferred resolution (dots per inch) of bitmap" +msgstr "A kívánt bitkép-felbontás (pont/hüvelykben)" + +#: ../../po/../src/extension/internal/ps.cpp:182 +msgid "Resolution:" +msgstr "Felbontás:" + +#. Print destination frame +#: ../../po/../src/extension/internal/ps.cpp:186 +msgid "Print destination" +msgstr "Nyomtatási cél" + +#: ../../po/../src/extension/internal/ps.cpp:192 +msgid "" +"Use '> filename' to print to file.\n" +"Use '| prog arg...' to pipe to a program." +msgstr "" +"Fájlba való nyomtatáshoz használja a \"> fájlnév\" konstrukciót,\n" +"a kimenetnek egy program számára való átadásához pedig a\n" +"következőt: \"| programnév argumentum ...\"." + +#: ../../po/../src/extension/internal/ps.cpp:1227 +msgid "write error occurred" +msgstr "írási hiba történt" + +#: ../../po/../src/extension/prefdialog.cpp:21 +msgid " Preferences" +msgstr " Beállítások" + +#. We can't call sp_ui_error_dialog because we may be +#. running from the console, in which case calling sp_ui +#. routines will cause a segfault. See bug 1000350 - bryce +#. sp_ui_error_dialog(_("Format autodetect failed. The file is being opened as SVG.")); +#: ../../po/../src/extension/system.cpp:105 +msgid "Format autodetect failed. The file is being opened as SVG." +msgstr "" +"Az automatikus formátumazonosítás nem járt sikerrel. A fájl SVG-ként lesz " +"megnyitva." + +#. TRANSLATORS: default.svg is localizable - this is the name of the default document +#. template. This way you can localize the default pagesize, translate the name of +#. the default layer, etc. If you wish to localize this file, please create a +#. localized share/templates/default.xx.svg file, where xx is your language code. +#: ../../po/../src/file.cpp:133 +msgid "default.svg" +msgstr "default.hu.svg" + +#: ../../po/../src/file.cpp:215 ../../po/../src/file.cpp:900 +#, c-format +msgid "Failed to load the requested file %s" +msgstr "Nem sikerült betölteni a kért fájlt (%s)" + +#: ../../po/../src/file.cpp:240 +msgid "Document not saved yet. Cannot revert." +msgstr "A dokumentum még nem volt mentve. Visszaállítás nem végezhető." + +#: ../../po/../src/file.cpp:246 +#, c-format +msgid "Changes will be lost! Are you sure you want to reload document %s?" +msgstr "" +"A módosítások elvesznek. Biztos, hogy újra be kívánja tölteni \"%s\" " +"dokumentumot?" + +#: ../../po/../src/file.cpp:266 +msgid "Document reverted." +msgstr "A dokumentum visszaállítva." + +#: ../../po/../src/file.cpp:268 +msgid "Document not reverted." +msgstr "A dokumentum nem lett visszaállítva." + +#: ../../po/../src/file.cpp:382 +msgid "Select file to open" +msgstr "Válassza ki a megnyitandó fájlt" + +#: ../../po/../src/file.cpp:518 +#, c-format +msgid "Removed %i unused definition in <defs>." +msgid_plural "Removed %i unused definitions in <defs>." +msgstr[0] "%i felhasználatlan <defs>-definíció eltávolítva." +msgstr[1] "%i felhasználatlan <defs>-definíció eltávolítva." + +#: ../../po/../src/file.cpp:523 +msgid "No unused definitions in <defs>." +msgstr "Nincs felhasználatlan <defs>-definíció." + +#: ../../po/../src/file.cpp:548 +#, c-format +msgid "" +"No Inkscape extension found to save document (%s). This may have been " +"caused by an unknown filename extension." +msgstr "" +"Nem található a dokumentum (%s) mentésére használható Inkscape-kiterjesztés. " +"Elképzelhető, hogy a fájlkiterjesztés ismeretlen." + +#: ../../po/../src/file.cpp:549 ../../po/../src/file.cpp:557 +msgid "Document not saved." +msgstr "A dokumentum nem lett elmentve." + +#: ../../po/../src/file.cpp:556 +#, c-format +msgid "File %s could not be saved." +msgstr "Nem sikerült elmenteni a(z) %s fájlt." + +#: ../../po/../src/file.cpp:566 +msgid "Document saved." +msgstr "A dokumentum elmentve." + +#: ../../po/../src/file.cpp:614 +#, c-format +msgid "drawing%s" +msgstr "rajz%s" + +#: ../../po/../src/file.cpp:620 +#, c-format +msgid "drawing-%d%s" +msgstr "rajz-%d%s" + +#: ../../po/../src/file.cpp:655 +msgid "Select file to save to" +msgstr "Adja meg a mentési fájlnevet" + +#: ../../po/../src/file.cpp:739 +msgid "No changes need to be saved." +msgstr "Nincs elmentést igénylő módosítás." + +#: ../../po/../src/file.cpp:926 +msgid "Select file to import" +msgstr "Válassza ki az importálandó fájlt" + +#: ../../po/../src/gradient-context.cpp:263 +msgid "Ctrl: snap gradient angle" +msgstr "Ctrl: a színátmenet szöghöz való illesztése" + +#: ../../po/../src/gradient-context.cpp:264 +msgid "Shift: draw gradient around the starting point" +msgstr "Shift: színátmenet rajzolása a kezdőpont köré" + +#. We did an undoable action, but sp_document_done will be called by the knot when released +#. status text; we do not track coords because this branch is run once, not all the time +#. during drag +#: ../../po/../src/gradient-context.cpp:462 +#, c-format +msgid "Gradient for %d objects; with Ctrl to snap angle" +msgstr "" +"Színátmenet %d objektumhoz. Szöghöz való illesztés: Ctrl." + +#: ../../po/../src/gradient-context.cpp:464 +msgid "Select objects on which to create gradient." +msgstr "" +"Jelölje ki az objektumokat, amelyeken a színátmenetet létre szeretné " +"hozni." + +#: ../../po/../src/gradient-drag.cpp:65 +msgid "Linear gradient start" +msgstr "Lineáris színátmenet kezdete" + +#. POINT_LG_P1 +#: ../../po/../src/gradient-drag.cpp:66 +msgid "Linear gradient end" +msgstr "Lineáris színátmenet vége" + +#: ../../po/../src/gradient-drag.cpp:67 +msgid "Radial gradient center" +msgstr "Sugárirányú színátmenet középpontja" + +#: ../../po/../src/gradient-drag.cpp:68 ../../po/../src/gradient-drag.cpp:69 +msgid "Radial gradient radius" +msgstr "Sugárirányú színátmenet sugara" + +#: ../../po/../src/gradient-drag.cpp:70 +msgid "Radial gradient focus" +msgstr "Sugárirányú színátmenet fókusza" + +#: ../../po/../src/gradient-drag.cpp:659 +#, c-format +msgid "" +"%s for: %s%s; drag with Ctrl to snap angle, with Ctrl+Alt to " +"preserve angle, with Ctrl+Shift to scale around center" +msgstr "" +"%s ehhez: %s%s. Szöghöz való illesztés: Ctrl+húzás. Szög megőrzése: " +"Ctrl+Alt. Átméretezés a középpont körül: Ctrl+Shift." + +#: ../../po/../src/gradient-drag.cpp:662 +msgid " (stroke)" +msgstr " (körvonal)" + +#: ../../po/../src/gradient-drag.cpp:665 +msgid "" +"Radial gradient center and focus; drag with Shift to " +"separate focus" +msgstr "" +"Sugárirányú színátmenet középpontja és fókusza. A fókusz " +"különválasztása: Shift+húzás." + +#: ../../po/../src/gradient-drag.cpp:667 +#, c-format +msgid "" +"Gradient point shared by %d gradients; drag with Shift to " +"separate" +msgstr "" +"%d színátmenet közös színátmenet-pontja. Különválasztás: Shift" +"+húzás." + +#: ../../po/../src/helper/units.cpp:40 +msgid "Unit" +msgstr "Mértékegység" + +#: ../../po/../src/helper/units.cpp:40 +msgid "Units" +msgstr "Mértékegység" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Point" +msgstr "Pont" + +#: ../../po/../src/helper/units.cpp:41 +msgid "pt" +msgstr "pt" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Points" +msgstr "Pont" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Pt" +msgstr "Pt" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Pixel" +msgstr "Képpont" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Pixels" +msgstr "Képpont" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Px" +msgstr "Px" + +#. You can add new elements from this point forward +#: ../../po/../src/helper/units.cpp:44 ../share/extensions/straightseg.inx.h:2 +msgid "Percent" +msgstr "Százalék" + +#: ../../po/../src/helper/units.cpp:44 +msgid "Percents" +msgstr "Százalék" + +#: ../../po/../src/helper/units.cpp:45 +msgid "Millimeter" +msgstr "Milliméter" + +#: ../../po/../src/helper/units.cpp:45 +msgid "mm" +msgstr "mm" + +#: ../../po/../src/helper/units.cpp:45 +msgid "Millimeters" +msgstr "Milliméter" + +#: ../../po/../src/helper/units.cpp:46 +msgid "Centimeter" +msgstr "Centiméter" + +#: ../../po/../src/helper/units.cpp:46 +msgid "cm" +msgstr "cm" + +#: ../../po/../src/helper/units.cpp:46 +msgid "Centimeters" +msgstr "Centiméter" + +#: ../../po/../src/helper/units.cpp:47 +msgid "Meter" +msgstr "Méter" + +#: ../../po/../src/helper/units.cpp:47 +msgid "m" +msgstr "m" + +#: ../../po/../src/helper/units.cpp:47 +msgid "Meters" +msgstr "Méter" + +#. no svg_unit +#: ../../po/../src/helper/units.cpp:48 +msgid "Inch" +msgstr "Hüvelyk" + +#: ../../po/../src/helper/units.cpp:48 +msgid "in" +msgstr "in" + +#: ../../po/../src/helper/units.cpp:48 +msgid "Inches" +msgstr "Hüvelyk" + +# A square the size of a capital letter M. +# The em square is the box in which glyphs are placed. +# It is exactly equal in height to the actual value for font-size. +#. Volatiles do not have default, so there are none here +#. TRANSLATORS: for info, see http://www.w3.org/TR/REC-CSS2/syndata.html#length-units +#: ../../po/../src/helper/units.cpp:51 +msgid "Em square" +msgstr "Em-négyzet" + +#: ../../po/../src/helper/units.cpp:51 +msgid "em" +msgstr "em" + +#: ../../po/../src/helper/units.cpp:51 +msgid "Em squares" +msgstr "Em-négyzet" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/REC-CSS2/syndata.html#length-units +#: ../../po/../src/helper/units.cpp:53 +msgid "Ex square" +msgstr "Ex-négyzet" + +#: ../../po/../src/helper/units.cpp:53 +msgid "ex" +msgstr "ex" + +#: ../../po/../src/helper/units.cpp:53 +msgid "Ex squares" +msgstr "Ex-négyzet" + +#: ../../po/../src/inkscape.cpp:468 +msgid "Untitled document" +msgstr "Névtelen dokumentum" + +#. Show nice dialog box +#: ../../po/../src/inkscape.cpp:497 +msgid "Inkscape encountered an internal error and will close now.\n" +msgstr "Az Inkscape belső hibába ütközött. A program bezárásra kerül.\n" + +#: ../../po/../src/inkscape.cpp:498 +msgid "" +"Automatic backups of unsaved documents were done to the following " +"locations:\n" +msgstr "A nem mentett dokumentumokról mentés készült a következő helyekre:\n" + +#: ../../po/../src/inkscape.cpp:499 +msgid "Automatic backup of the following documents failed:\n" +msgstr "" +"Nem sikerült automatikus mentést készíteni a következő dokumentumokról:\n" + +#: ../../po/../src/inkscape.cpp:634 +#, c-format +msgid "" +"Cannot create directory %s.\n" +"%s" +msgstr "" +"Nem sikerült létrehozni %s nevű könyvtárt.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:635 +#, c-format +msgid "" +"%s is not a valid directory.\n" +"%s" +msgstr "" +"A(z) %s nem egy érvényes könyvtár.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:636 +#, c-format +msgid "" +"Cannot create file %s.\n" +"%s" +msgstr "" +"Nem sikerült létrehozni %s nevű fájlt.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:637 +#, c-format +msgid "" +"Cannot write file %s.\n" +"%s" +msgstr "" +"Nem sikerült írni a(z) %s fájlba.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:638 +msgid "" +"Although Inkscape will run, it will use default settings,\n" +"and any changes made in preferences will not be saved." +msgstr "" +"Az Inkscape ugyan működni fog, de az alapértelmezett beállításokat\n" +"fogja használni. A beállításokon végzett módosítások nem lesznek elmentve." + +#: ../../po/../src/inkscape.cpp:708 +#, c-format +msgid "" +"%s is not a regular file.\n" +"%s" +msgstr "" +"A(z) %s nem szokványos fájl.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:709 +#, c-format +msgid "" +"%s not a valid XML file, or\n" +"you don't have read permissions on it.\n" +"%s" +msgstr "" +"Vagy nem érvényes XML-fájl a(z) \"%s\",\n" +"vagy Önnek nincs olvasási engedélye a fájlra.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:711 +#, c-format +msgid "" +"%s is not a valid menus file.\n" +"%s" +msgstr "" +"A(z) %s nem egy érvényes menüfájl.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:712 +msgid "" +"Inkscape will run with default menus.\n" +"New menus will not be saved." +msgstr "" +"Az Inkscape az alapértelmezett menüket fogja használni.\n" +"Az új menük nem kerülnek mentésre." + +#. sp_ui_menu_append_check_item_from_verb(m, view, _("_Menu"), _("Show or hide the menu bar"), "menu", +#. checkitem_toggled, checkitem_update, 0); +#: ../../po/../src/interface.cpp:753 +msgid "Commands Bar" +msgstr "Parancssáv" + +#: ../../po/../src/interface.cpp:753 +msgid "Show or hide the Commands bar (under the menu)" +msgstr "A parancssáv megjelenítése (a menü alatt) vagy elrejtése" + +#: ../../po/../src/interface.cpp:755 +msgid "Tool Controls" +msgstr "Eszközvezérlők" + +#: ../../po/../src/interface.cpp:755 +msgid "Show or hide the Tool Controls panel" +msgstr "Az eszközvezérlőket tartalmazó eszköztár megjelenítése vagy elrejtése" + +#: ../../po/../src/interface.cpp:757 +msgid "_Toolbox" +msgstr "_Eszköztár" + +#: ../../po/../src/interface.cpp:757 +msgid "Show or hide the main toolbox (on the left)" +msgstr "A fő eszköztár megjelenítése (a bal oldalon) vagy elrejtése" + +#: ../../po/../src/interface.cpp:763 +msgid "_Statusbar" +msgstr "Á_llapotsor" + +#: ../../po/../src/interface.cpp:763 +msgid "Show or hide the statusbar (at the bottom of the window)" +msgstr "Az állapotsor megjelenítése (az ablak alján) vagy elrejtése" + +#: ../../po/../src/interface.cpp:820 +#, c-format +msgid "Verb \"%s\" Unknown" +msgstr "Ismeretlen funkció: \"%s\"" + +#. TRANSLATORS: #%s is the id of the group e.g. , not a number. +#: ../../po/../src/interface.cpp:930 +#, c-format +msgid "Enter group #%s" +msgstr "Belépés a \"#%s\" csoportba" + +#: ../../po/../src/interface.cpp:941 +msgid "Go to parent" +msgstr "Ugrás a szülőre" + +#: ../../po/../src/interface.cpp:972 +msgid "Could not parse SVG data" +msgstr "Nem sikerült értelmezni az SVG-adatokat" + +#: ../../po/../src/interface.cpp:1135 +#, c-format +msgid "Overwrite %s" +msgstr "%s felülírása" + +#: ../../po/../src/interface.cpp:1153 +#, c-format +msgid "" +"The file %s already exists. Do you want to overwrite that file with the " +"current document?" +msgstr "" +"Már létezik %s nevű fájl. Szeretné felülírni a meglevő fájlt a jelenlegi " +"dokumentummal?" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:59 +msgid "Jabber connection lost." +msgstr "A Jabber-kapcsolat megszűnt." + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:72 +#, c-format +msgid "Sending message; %u message remaining in send queue." +msgid_plural "Sending message; %u messages remaining in send queue." +msgstr[0] "Üzenet küldése; %u üzenet van még a küldési sorban." +msgstr[1] "Üzenet küldése; %u üzenet van még a küldési sorban." + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:78 +msgid "Receive queue empty." +msgstr "A fogadási sor üres." + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:154 +#, c-format +msgid "Receiving change; %u change left to process." +msgid_plural "Receiving change; %u changes left to process." +msgstr[0] "Módosítás fogadása; %u módosítás van hátra." +msgstr[1] "Módosítás fogadása; %u módosítás van hátra." + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:157 +#, c-format +msgid "%s has left the chatroom." +msgstr "%s elhagyta a csevegőszobát." + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:221 +msgid "Nickname %1 is already in use. Please choose a different nickname." +msgstr "A(z) \"%1\" név már foglalt. Válasszon másikat." + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:225 +msgid "An error was encountered while attempting to connect to the server." +msgstr "Hiba történt a kiszolgálóra való csatlakozás közben." + +#. Check to see if the user made any modifications to this document. If so, +#. we want to give them the option of (1) letting us clear their document or (2) +#. opening a new, blank document for the whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:131 +msgid "%1 has invited you to a whiteboard session." +msgstr "%1 meghívta Önt egy rajztábla-munkamenetre." + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:132 +msgid "Incoming whiteboard invitation from %1" +msgstr "Bejövő rajztábla-meghívás \"%1\" felhasználótól" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:135 +msgid "Do you wish to accept %1's whiteboard session invitation?" +msgstr "Elfogadja \"%1\" rajztábla-munkamenetre szóló meghívását?" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:137 +msgid "" +"Would you like to accept %1's invitation in a new document window?\n" +"Accepting the invitation in your current window will discard unsaved changes." +msgstr "" +"Elfogadja \"%1\" meghívását egy új dokumentumablakban?\n" +"A meghívásnak a jelenlegi ablakban való elfogadása esetén a nem mentett " +"módosítások elvesznek." + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:143 +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:198 +msgid "Accept invitation" +msgstr "Meghívás elfogadása" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:144 +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:199 +msgid "Decline invitation" +msgstr "Meghívás elutasítása" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:145 +msgid "Accept invitation in new document window" +msgstr "Meghívás elfogadása új dokumentumablakban" + +#. We could not create a new desktop; ask the user if she or he wants to +#. replace the current document and accept the invitation, or reject the invitation. +#. TRANSLATORS: %1 is a userid here +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:196 +msgid "" +"A new document window could not be opened for a whiteboard session with %" +"1" +msgstr "" +"Nem sikerült új dokumentumablakot nyitni a(z) \"%1\" felhasználóval " +"létrehozandó rajztábla-munkamenet számára" + +#. TRANSLATORS: %1 is the peer whom refused our invitation. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:238 +msgid "" +"The user %1 has refused your " +"whiteboard invitation.\n" +"\n" +msgstr "" +"A(z) \"%1\" nevű felhasználó " +"elutasította az Ön rajztábla-meghívását.\n" +"\n" + +#. TRANSLATORS: %1 is the peer whom refused our invitation, %2 is our Jabber identity. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:241 +msgid "" +"You are still connected to a Jabber server as %2, and may send an " +"invitation to %1 again, or you may send an invitation to a different " +"user." +msgstr "" +"Még kapcsolódva van \"%2\" néven egy Jabber-kiszolgálóhoz. Küldhet " +"ismételten egy meghívást \"%1\" számára, vagy küldhet meghívást egy " +"másik felhasználónak." + +#. TRANSLATORS: %1 is the peer whom we tried to contact, but is already in a whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:252 +msgid "" +"The user %1 is already in a " +"whiteboard session.\n" +"\n" +msgstr "" +"A(z) \"%1\" felhasználó már " +"benne van egy rajztábla-munkamenetben.\n" +"\n" + +#. TRANSLATORS: %1 is the peer whom we tried to contact, but is already in a whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:255 +msgid "" +"You are still connected to a Jabber server as %1, and may send an " +"invitation to a different user." +msgstr "" +"Még kapcsolódva van \"%1\" néven egy Jabber-kiszolgálóhoz. Küldhet " +"meghívást egy másik felhasználónak." + +#: ../../po/../src/jabber_whiteboard/invitation-confirm-dialog.cpp:26 +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:24 +msgid "_Write session file:" +msgstr "Munkamenet-_fájl készítése:" + +#: ../../po/../src/jabber_whiteboard/message-processors.cpp:145 +#, c-format +msgid "%s has joined the chatroom." +msgstr "%s csatlakozott a csevegőszobához." + +#: ../../po/../src/jabber_whiteboard/message-queue.cpp:87 +#, c-format +msgid "%u change in receive queue." +msgid_plural "%u changes in receive queue." +msgstr[0] "%u módosítás van a fogadási sorban." +msgstr[1] "%u módosítás van a fogadási sorban." + +#: ../../po/../src/jabber_whiteboard/message-queue.cpp:117 +#, c-format +msgid "%u change in send queue." +msgid_plural "%u changes in send queue." +msgstr[0] "%u módosítás van a küldési sorban." +msgstr[1] "%u módosítás van a küldési sorban." + +#. if ID is NULL, then we have a real problem -- we were not able to find a key +#. nor generate one. The only thing we can really do here is abort, since we have +#. no way to let the other client(s) uniquely identify this object. +#. FIXME: If this indicates a programming bug, then don't request translation with +#. * _(...): it is most useful in untranslated form so that developers may search for +#. * it when someone reports it in a bug report (as we want users to do for all bugs, +#. * as indicated by it being a g_warning string). +#. * +#. * Otherwise, if it is not a programming bug but a network error or a bug in the +#. * remote peer (perhaps running different software) or whatever, then present it in +#. * an alert box, and avoid use of technical jargon `NULL'. +#. +#: ../../po/../src/jabber_whiteboard/message-utilities.cpp:171 +msgid "" +"ID for new object is NULL even after generation and lookup attempts: the new " +"object will NOT be sent, nor will any of its child objects!" +msgstr "" +"Az új objektum azonosítója a generálási és keresési kísérleteket követően is " +"NULL. Az új objektum és annak leszármazottjai nem lesznek elküldve." + +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:60 +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:995 +msgid "Select a location and filename" +msgstr "Válasszon egy helyet és egy fájlnevet" + +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:62 +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:997 +msgid "Set filename" +msgstr "Fájlnév beállítása" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:301 +msgid "No SSL certificate was found." +msgstr "SSL-tanúsítvány nem található." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:304 +msgid "The SSL certificate provided by the Jabber server is untrusted." +msgstr "A Jabber-kiszolgáló által adott SSL-tanúsítvány nem megbízható." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:307 +msgid "The SSL certificate provided by the Jabber server is expired." +msgstr "A Jabber-kiszolgáló által adott SSL-tanúsítvány már lejárt." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:310 +msgid "" +"The SSL certificate provided by the Jabber server has not been activated." +msgstr "A Jabber-kiszolgáló által adott SSL-tanúsítvány nem lett aktiválva." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:313 +msgid "" +"The SSL certificate provided by the Jabber server contains a hostname that " +"does not match the Jabber server's hostname." +msgstr "" +"A Jabber-kiszolgáló által adott SSL-tanúsítvány olyan gépnevet tartalmaz, " +"amely eltér a Jabber-kiszolgáló gépnevétől." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:316 +msgid "" +"The SSL certificate provided by the Jabber server contains an invalid " +"fingerprint." +msgstr "" +"A Jabber-kiszolgáló által adott SSL-tanúsítvány érvénytelen ujjlenyomatot " +"tartalmaz." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:319 +msgid "An unknown error occurred while setting up the SSL connection." +msgstr "Ismeretlen hiba történt az SSL-kapcsolat létrehozásakor." + +#. TRANSLATORS: %1 is the message that describes the specific error that occurred when +#. establishing the SSL connection. +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:325 +msgid "" +"%1\n" +"\n" +"Do you wish to continue connecting to the Jabber server?" +msgstr "" +"%1\n" +"\n" +"Szeretné folytatni a Jabber-kiszolgálóhoz való kapcsolódást?" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:328 +msgid "Continue connecting and ignore further errors" +msgstr "Kapcsolódás folytatása a további hibák figyelmen kívül hagyásával" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:329 +msgid "Continue connecting, but warn me of further errors" +msgstr "Kapcsolódás folytatása, figyelmeztetés a további hibákra" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:330 +msgid "Cancel connection" +msgstr "Kapcsolódás leállítása" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:777 +#, c-format +msgid "Established whiteboard session with %s." +msgstr "Rajztábla-munkamenet létrehozva ezzel: %s." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:785 +#, c-format +msgid "%s has left the whiteboard session." +msgstr "%s elhagyta a rajztábla-munkamenetet." + +#. Inform the user +#. TRANSLATORS: %1 is the name of the user that disconnected, %2 is the name of the user whom the disconnected user disconnected from. +#. This message is not used in a chatroom context. +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:790 +msgid "" +"The user %1 has left the " +"whiteboard session.\n" +"\n" +msgstr "" +"A(z) \"%1\" nevű felhasználó " +"elhagyta a rajztábla-munkamenetet.\n" +"\n" + +#. TRANSLATORS: %1 and %2 are userids +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:792 +msgid "" +"You are still connected to a Jabber server as %2, and may establish a " +"new session to %1 or a different user." +msgstr "" +"Még kapcsolódva van \"%2\" néven egy Jabber-kiszolgálóhoz. " +"Létrehozhat egy új munkamenetet \"%1\" vagy más felhasználóval." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:988 +msgid "" +"Could not open file %1 for session recording.\n" +"The error encountered was: %2.\n" +"\n" +"You may select a different location to record the session, or you may opt to " +"not record this session." +msgstr "" +"Nem sikerült megnyitni a(z) \"%1\" fájlt munkamenet-felvételhez.\n" +"A hiba: \"%2\".\n" +"\n" +"Kiválaszthat egy másik helyet a munkamenet eltárolásához, vagy választhatja " +"azt is, hogy nem veszi fel a munkamenetet." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:990 +msgid "Choose a different location" +msgstr "Másik hely kiválasztása" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:991 +msgid "Skip session recording" +msgstr "Ne legyen felvéve a munkamenet" + +#: ../../po/../src/knot.cpp:673 +msgid "Node or handle drag canceled." +msgstr "Csomópont vagy vezérlőelem húzása megszakítva." + +#: ../../po/../src/libnrtype/FontFactory.cpp:358 +msgid "Ignoring font without family that will crash Pango" +msgstr "" +"A családmegadás nélküli betűtípus figyelmen kívül hagyása (az ilyen " +"betűtípus problémát okozhat)" + +#: ../../po/../src/main.cpp:395 +msgid "Print the Inkscape version number" +msgstr "Az Inkscape verziószámának kiírása" + +#: ../../po/../src/main.cpp:400 +msgid "Do not use X server (only process files from console)" +msgstr "" +"Az X grafikus rendszer ne legyen használva (fájlok feldolgozása a konzolról)" + +#: ../../po/../src/main.cpp:405 +msgid "Try to use X server (even if $DISPLAY is not set)" +msgstr "" +"Az X grafikus rendszer használatának megkísérlése akkor is, ha a DISPLAY " +"változó nincs beállítva" + +#: ../../po/../src/main.cpp:410 +msgid "Open specified document(s) (option string may be excluded)" +msgstr "A megadott dokumentum(ok) megnyitása (az opciók elhagyhatók)" + +#: ../../po/../src/main.cpp:411 ../../po/../src/main.cpp:416 +#: ../../po/../src/main.cpp:421 ../../po/../src/main.cpp:483 +#: ../../po/../src/main.cpp:488 ../../po/../src/main.cpp:493 +msgid "FILENAME" +msgstr "FÁJLNÉV" + +#: ../../po/../src/main.cpp:415 +msgid "Print document(s) to specified output file (use '| program' for pipe)" +msgstr "" +"A dokumentum(ok) nyomtatása egy adott fájlba (program számára való átadás: " +"\"| programnév\")" + +#: ../../po/../src/main.cpp:420 +msgid "Export document to a PNG file" +msgstr "A dokumentum exportálása PNG formátumú képbe" + +#: ../../po/../src/main.cpp:425 +msgid "The resolution used for exporting SVG into bitmap (default 90)" +msgstr "" +"Az SVG-dokumentum bitképbe való exportálásához használt felbontás " +"(alapértelmezés: 90)" + +#: ../../po/../src/main.cpp:426 +msgid "DPI" +msgstr "DPI" + +#: ../../po/../src/main.cpp:430 +msgid "" +"Exported area in SVG user units (default is the canvas; 0,0 is lower-left " +"corner)" +msgstr "" +"Az exportált terület felhasználói SVG-mértékegységben (alapértelmezés: a " +"rajzvászon, a bal alsó sarok a 0,0 pont)" + +#: ../../po/../src/main.cpp:431 +msgid "x0:y0:x1:y1" +msgstr "x0:y0:x1:y1" + +#: ../../po/../src/main.cpp:435 +msgid "Exported area is the entire drawing (not canvas)" +msgstr "Az exportált terület a teljes rajz (nem a rajzvászon)" + +#: ../../po/../src/main.cpp:440 +msgid "" +"Snap the bitmap export area outwards to the nearest integer values (in SVG " +"user units)" +msgstr "" +"Az exportált képpontos terület illesztése kifelé a legközelebbi egész " +"értékekhez (felhasználói SVG-mértékegységben)" + +#: ../../po/../src/main.cpp:445 +msgid "The width of exported bitmap in pixels (overrides export-dpi)" +msgstr "" +"Az exportált bitkép szélessége képpontban (felülbírálja az export-dpi " +"értéket)" + +#: ../../po/../src/main.cpp:446 +msgid "WIDTH" +msgstr "SZÉLESSÉG" + +#: ../../po/../src/main.cpp:450 +msgid "The height of exported bitmap in pixels (overrides export-dpi)" +msgstr "" +"Az exportált bitkép magassága képpontban (felülbírálja az export-dpi értéket)" + +#: ../../po/../src/main.cpp:451 +msgid "HEIGHT" +msgstr "MAGASSÁG" + +#: ../../po/../src/main.cpp:455 +msgid "The ID of the object to export (overrides export-area)" +msgstr "" +"Az exportálandó objektum azonosítója (felülbírálja az export-area értéket)" + +#: ../../po/../src/main.cpp:456 ../../po/../src/main.cpp:532 +msgid "ID" +msgstr "Azonosító" + +#. TRANSLATORS: this means: "Only export the object whose id is given in --export-id". +#. See "man inkscape" for details. +#: ../../po/../src/main.cpp:462 +msgid "" +"Export just the object with export-id, hide all others (only with export-id)" +msgstr "" +"Csak az export-id-vel rendelkező objektum exportálása; a többi elrejtése " +"(csak export-id esetén)" + +#: ../../po/../src/main.cpp:467 +msgid "Use stored filename and DPI hints when exporting (only with export-id)" +msgstr "" +"Tárolt fájlnév és DPI-információk használata exportáláskor (csak export-id " +"esetén)" + +#: ../../po/../src/main.cpp:472 +msgid "Background color of exported bitmap (any SVG-supported color string)" +msgstr "" +"Az exportált bitkép háttérszíne (bármilyen, az SVG formátum által támogatott " +"színmegadás)" + +#: ../../po/../src/main.cpp:473 +msgid "COLOR" +msgstr "SZÍN" + +#: ../../po/../src/main.cpp:477 +msgid "Background opacity of exported bitmap (either 0.0 to 1.0, or 1 to 255)" +msgstr "" +"Az exportált bitkép hátterének átlátszatlansága (vagy 0,0 és 1,0 közt, vagy " +"1 és 255 közt)" + +#: ../../po/../src/main.cpp:478 +msgid "VALUE" +msgstr "ÉRTÉK" + +#: ../../po/../src/main.cpp:482 +msgid "Export document to plain SVG file (no sodipodi or inkscape namespaces)" +msgstr "" +"A dokumentum exportálása normál SVG-fájlba (nincs sem \"sodipodi\", sem " +"\"inkscape\" névtér)" + +#: ../../po/../src/main.cpp:487 +msgid "Export document to a PS file" +msgstr "A dokumentum exportálása PS formátumú fájlba" + +#: ../../po/../src/main.cpp:492 +msgid "Export document to an EPS file" +msgstr "A dokumentum exportálása EPS formátumú fájlba" + +#: ../../po/../src/main.cpp:497 +msgid "Convert text object to paths on export (EPS)" +msgstr "Szövegobjektum átalakítása láncokká az exportálás közben (EPS)" + +#: ../../po/../src/main.cpp:502 +msgid "Export files with the bounding box set to the page size (EPS)" +msgstr "Exportáláskor a határoló téglalap a lapméretre legyen állítva (EPS)" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:508 +msgid "" +"Query the X coordinate of the drawing or, if specified, of the object with --" +"query-id" +msgstr "" +"A rajz (illetve, ha az meg van adva, a --query-id opcióval megadott " +"objektum) X-koordinátájának lekérdezése" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:514 +msgid "" +"Query the Y coordinate of the drawing or, if specified, of the object with --" +"query-id" +msgstr "" +"A rajz (illetve, ha az meg van adva, a --query-id opcióval megadott " +"objektum) Y-koordinátájának lekérdezése" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:520 +msgid "" +"Query the width of the drawing or, if specified, of the object with --query-" +"id" +msgstr "" +"A rajz (illetve, ha az meg van adva, a --query-id opcióval megadott " +"objektum) szélességének lekérdezése" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:526 +msgid "" +"Query the height of the drawing or, if specified, of the object with --query-" +"id" +msgstr "" +"A rajz (illetve, ha az meg van adva, a --query-id opcióval megadott " +"objektum) magasságának lekérdezése" + +#: ../../po/../src/main.cpp:531 +msgid "The ID of the object whose dimensions are queried" +msgstr "Azon objektum azonosítója, amelynek a kiterjedése lekérdezendő" + +#. TRANSLATORS: this option makes Inkscape print the name (path) of the extension directory +#: ../../po/../src/main.cpp:537 +msgid "Print out the extension directory and exit" +msgstr "A kiterjesztés-könyvtár kiírása, majd kilépés" + +#: ../../po/../src/main.cpp:542 +msgid "Show given files one-by-one, switch to next on any key/mouse event" +msgstr "" +"A megadott fájlok egyenkénti megjelenítése - ugrás a következőre: " +"billentyűzet vagy egér használatával" + +#: ../../po/../src/main.cpp:547 +msgid "Use the new Gtkmm GUI interface" +msgstr "Az új Gtkmm felhasználói felület használata" + +#: ../../po/../src/main.cpp:552 +msgid "Remove unused definitions from the defs section(s) of the document" +msgstr "A nem használt definíciók eltávolítása a dokumentum defs-részeiből" + +#: ../../po/../src/main.cpp:741 +msgid "" +"[OPTIONS...] [FILE...]\n" +"\n" +"Available options:" +msgstr "" +"[OPCIÓK...] [FÁJL...]\n" +"\n" +"Használható opciók:" + +#: ../../po/../src/menus-skeleton.h:17 +msgid "_New" +msgstr "Ú_j" + +#: ../../po/../src/menus-skeleton.h:22 +msgid "Open _Recent" +msgstr "Leg_utóbbi megnyitása" + +#: ../../po/../src/menus-skeleton.h:53 +msgid "_Edit" +msgstr "S_zerkesztés" + +#: ../../po/../src/menus-skeleton.h:84 +msgid "_View" +msgstr "_Nézet" + +#: ../../po/../src/menus-skeleton.h:85 +#, fuzzy +msgid "_Zoom" +msgstr "Nagyítás" + +#: ../../po/../src/menus-skeleton.h:102 +msgid "Show/Hide" +msgstr "Megjelenítés/elrejtés" + +#: ../../po/../src/menus-skeleton.h:107 +msgid "_Display mode" +msgstr "" + +#: ../../po/../src/menus-skeleton.h:126 +msgid "_Layer" +msgstr "_Réteg" + +#: ../../po/../src/menus-skeleton.h:143 +msgid "_Object" +msgstr "_Objektum" + +#: ../../po/../src/menus-skeleton.h:165 +msgid "_Path" +msgstr "_Lánc" + +#: ../../po/../src/menus-skeleton.h:188 +msgid "_Text" +msgstr "Szö_veg" + +#: ../../po/../src/menus-skeleton.h:200 +msgid "Effects" +msgstr "Effektusok" + +#: ../../po/../src/menus-skeleton.h:207 +msgid "Whiteboa_rd" +msgstr "R_ajztábla" + +#: ../../po/../src/menus-skeleton.h:220 +msgid "_Help" +msgstr "_Segítség" + +#: ../../po/../src/menus-skeleton.h:222 +msgid "Tutorials" +msgstr "Ismertetők" + +#: ../../po/../src/node-context.cpp:382 +msgid "" +"Ctrl: toggle node type, snap handle angle, move hor/vert; Ctrl" +"+Alt: move along handles" +msgstr "" +"Ctrl: csomóponttípus módosítása; vezérlőelem szöghöz való illesztése; " +"vízszintes/függőleges áthelyezés; Ctrl+Alt: áthelyezés vezérlőelemek " +"mentén" + +#: ../../po/../src/node-context.cpp:383 +msgid "" +"Shift: toggle node selection, disable snapping, rotate both handles" +msgstr "" +"Shift: csomópontkijelölés bekapcsolása/kikapcsolása; illesztés " +"kikapcsolása; mindkét vezérlőelem forgatása" + +#: ../../po/../src/node-context.cpp:384 +msgid "Alt: lock handle length; Ctrl+Alt: move along handles" +msgstr "" +"Alt: vezérlőelem hosszának megőrzése; Ctrl+Alt: áthelyezés " +"vezérlőelemek mentén" + +#: ../../po/../src/nodepath.cpp:1399 ../../po/../src/nodepath.cpp:1411 +#: ../../po/../src/nodepath.cpp:1492 ../../po/../src/nodepath.cpp:1504 +msgid "To join, you must have two endnodes selected." +msgstr "Összekapcsoláshoz két végpontot kell kijelölni." + +#: ../../po/../src/nodepath.cpp:1633 ../../po/../src/nodepath.cpp:1647 +msgid "" +"Select two non-endpoint nodes on a path between which to delete " +"segments." +msgstr "" +"Ki kell jelölni egy láncon két, nem végponti csomópontot, amelyek a " +"törlendő szakaszokat közrefogják." + +#: ../../po/../src/nodepath.cpp:1743 +msgid "Cannot find path between nodes." +msgstr "A csomópontok közt nem található lánc." + +#: ../../po/../src/nodepath.cpp:2822 +#, c-format +msgid "" +"Node handle: angle %0.2f°, length %s; with Ctrl to snap " +"angle; with Alt to lock length; with Shift to rotate both " +"handles" +msgstr "" +"Csomópont-vezérlőelem. Szög: %0.2f°. Hossz: %s. Szöghöz való " +"illesztés: Ctrl; hossz megőrzése: Alt; mindkét vezérlőelem " +"forgatása: Shift." + +#: ../../po/../src/nodepath.cpp:3351 +msgid "" +"Node: drag to edit the path; with Ctrl to snap to horizontal/" +"vertical; with Ctrl+Alt to snap to handles' directions" +msgstr "" +"Csomópont. Lánc szerkesztése: húzással; vízszintes/függőleges " +"illesztés: Ctrl; illesztés a vezérlőelemek irányában: Ctrl+Alt." + +#: ../../po/../src/nodepath.cpp:3375 +msgid "" +"Node handle: drag to shape the curve; with Ctrl to snap angle; " +"with Alt to lock length; with Shift to rotate both handles" +msgstr "" +"Csomópont-vezérlőelem. Ív alakítása: húzással; szöghöz való " +"illesztés: Ctrl; hossz megőrzése: Alt; mindkét vezérlőelem " +"forgatása: Shift." + +#: ../../po/../src/nodepath.cpp:3399 +msgid "" +"Node handle: drag to shape the curve; with Ctrl to snap angle; " +"with Alt to lock length; with Shift to rotate the opposite " +"handle in sync" +msgstr "" +"Csomópont-vezérlőelem. Ív alakítása: húzással; szöghöz való " +"illesztés: Ctrl; hossz megőrzése: Alt; túlsó vezérlőelem " +"forgatása szinkronban: Shift." + +#. TRANSLATORS: "end" is an adjective here (NOT a verb) +#: ../../po/../src/nodepath.cpp:3591 +msgid "end node" +msgstr "szélső csomópont" + +#. TRANSLATORS: "cusp" means "sharp" (cusp node); see also the Advanced Tutorial +#: ../../po/../src/nodepath.cpp:3596 +msgid "cusp" +msgstr "csúcs" + +#. TRANSLATORS: "smooth" is an adjective here +#: ../../po/../src/nodepath.cpp:3599 +msgid "smooth" +msgstr "íves" + +#: ../../po/../src/nodepath.cpp:3601 +msgid "symmetric" +msgstr "szimmetrikus" + +#. TRANSLATORS: "end" is an adjective here (NOT a verb) +#: ../../po/../src/nodepath.cpp:3607 +msgid "end node, handle retracted (drag with Shift to extend)" +msgstr "" +"szélső csomópont, vezérlőelem behúzva (kiterjesztés: Shift+húzás)" + +#: ../../po/../src/nodepath.cpp:3609 +msgid "one handle retracted (drag with Shift to extend)" +msgstr "egy vezérlőelem behúzva (kiterjesztés: Shift+húzás)" + +#: ../../po/../src/nodepath.cpp:3612 +msgid "both handles retracted (drag with Shift to extend)" +msgstr "mindkét vezérlőelem behúzva (kiterjesztés: Shift+húzás)" + +#: ../../po/../src/nodepath.cpp:3624 +msgid "Drag nodes or node handles; arrow keys to move nodes" +msgstr "" +"Csomópontok illetve csomópont-vezérlőelemek áthelyezése: húzással. " +"Csomópontok áthelyezése a nyílbillentyűkkel is lehetséges." + +#: ../../po/../src/nodepath.cpp:3625 +msgid "Drag the node or its handles; arrow keys to move the node" +msgstr "" +"A csomópont illetve a csomópont-vezérlőelemek áthelyezése: húzással. " +"A csomópont áthelyezése a nyílbillentyűkkel is lehetséges." + +#: ../../po/../src/nodepath.cpp:3651 ../../po/../src/nodepath.cpp:3663 +msgid "Select a single object to edit its nodes or handles." +msgstr "" +"Jelölje ki az objektumot, amelynek csomópontjait illetve vezérlőelemeit " +"módosítani kívánja." + +#: ../../po/../src/nodepath.cpp:3655 +#, c-format +msgid "" +"0 out of %i node selected. Click, Shift+click, " +"or drag around nodes to select." +msgid_plural "" +"0 out of %i nodes selected. Click, Shift+click, " +"or drag around nodes to select." +msgstr[0] "" +"%i csomópontból 0 van kijelölve. Kijelölés: kattintással, Shift+kattintással, vagy egy terület húzással való " +"kijelölésével." +msgstr[1] "" +"%i csomópontból 0 van kijelölve. Kijelölés: kattintással, Shift+kattintással, vagy egy terület húzással való " +"kijelölésével." + +#: ../../po/../src/nodepath.cpp:3661 +msgid "Drag the handles of the object to modify it." +msgstr "Az objektum módosítása a vezérlőelemeinek a húzásával végezhető." + +#: ../../po/../src/nodepath.cpp:3669 +#, c-format +msgid "%i of %i node selected; %s. %s." +msgid_plural "%i of %i nodes selected; %s. %s." +msgstr[0] "%i csomópont kijelölve (összesen: %i); %s. %s." +msgstr[1] "%i csomópont kijelölve (összesen: %i); %s. %s." + +#: ../../po/../src/nodepath.cpp:3675 +#, c-format +msgid "%i of %i node selected. %s." +msgid_plural "%i of %i nodes selected. %s." +msgstr[0] "%i csomópont kijelölve (összesen: %i). %s." +msgstr[1] "%i csomópont kijelölve (összesen: %i). %s." + +#: ../../po/../src/object-edit.cpp:493 +msgid "" +"Adjust the horizontal rounding radius; with Ctrl to make the " +"vertical radius the same" +msgstr "" +"A vízszintes lekerekítési sugár beállítása. A függőleges sugár " +"ugyanerre való beállítása: Ctrl." + +#: ../../po/../src/object-edit.cpp:499 +msgid "" +"Adjust the vertical rounding radius; with Ctrl to make the " +"horizontal radius the same" +msgstr "" +"A függőleges lekerekítési sugár beállítása. A vízszintes sugár " +"ugyanerre való beállítása: Ctrl." + +#: ../../po/../src/object-edit.cpp:506 ../../po/../src/object-edit.cpp:513 +msgid "" +"Adjust the width and height of the rectangle; with Ctrl to " +"lock ratio or stretch in one dimension only" +msgstr "" +"A téglalap szélességének és magasságának beállítása. Az arány " +"megőrzése vagy csak egy irányban való nyújtás: Ctrl." + +#: ../../po/../src/object-edit.cpp:686 +msgid "Adjust ellipse width, with Ctrl to make circle" +msgstr "" +"Az ellipszis szélességének beállítása. Körré alakítás: Ctrl." + +#: ../../po/../src/object-edit.cpp:689 +msgid "Adjust ellipse height, with Ctrl to make circle" +msgstr "" +"Az ellipszis magasságának beállítása. Körré alakítás: Ctrl." + +#: ../../po/../src/object-edit.cpp:692 +msgid "" +"Position the start point of the arc or segment; with Ctrl to " +"snap angle; drag inside the ellipse for arc, outside for " +"segment" +msgstr "" +"Az ellipszisív illetve -cikk kezdőpontjának elhelyezése. Szöghöz való " +"illesztés: Ctrl; ív: az ellipszisen belül való húzás; cikk: " +"kívül való húzás." + +#: ../../po/../src/object-edit.cpp:695 +msgid "" +"Position the end point of the arc or segment; with Ctrl to " +"snap angle; drag inside the ellipse for arc, outside for " +"segment" +msgstr "" +"Az ellipszisív illetve -cikk végpontjának elhelyezése. Szöghöz való " +"illesztés: Ctrl; ív: az ellipszisen belül való húzás; cikk: " +"kívül való húzás." + +#: ../../po/../src/object-edit.cpp:800 +msgid "" +"Adjust the tip radius of the star or polygon; with Shift to " +"round; with Alt to randomize" +msgstr "" +"A csillag vagy sokszög csúcsponti sugarának beállítása. Lekerekítés: " +"Shift; véletlenszerűség: Alt." + +#: ../../po/../src/object-edit.cpp:803 +msgid "" +"Adjust the base radius of the star; with Ctrl to keep star " +"rays radial (no skew); with Shift to round; with Alt to " +"randomize" +msgstr "" +"A csillag alapponti sugarának beállítása. A csillag ágainak " +"sugárirányban való tartása (nyírás elkerülése): Ctrl; lekerekítés: " +"Shift; véletlenszerűség: Alt." + +#: ../../po/../src/object-edit.cpp:967 +msgid "" +"Roll/unroll the spiral from inside; with Ctrl to snap angle; " +"with Alt to converge/diverge" +msgstr "" +"A spirál rajzolása/törlése belül. Szöghöz való illesztés: Ctrl; tágítás/szűkítés: Alt." + +#: ../../po/../src/object-edit.cpp:969 +msgid "" +"Roll/unroll the spiral from outside; with Ctrl to snap angle; " +"with Shift to scale/rotate" +msgstr "" +"A spirál rajzolása/törlése kívül. Szöghöz való illesztés: Ctrl; átméretezés/forgatás: Shift." + +#: ../../po/../src/object-edit.cpp:1006 +msgid "Adjust the offset distance" +msgstr "A peremtávolság beállítása" + +#. TRANSLATORS: This refers to the pattern that's inside the object +#: ../../po/../src/object-edit.cpp:1036 +msgid "Move the pattern fill inside the object" +msgstr "Az objektumon belüli kitöltőminta áthelyezése" + +#: ../../po/../src/object-edit.cpp:1038 +msgid "Scale the pattern fill uniformly" +msgstr "A kitöltőminta egyenletes átméretezése" + +#: ../../po/../src/object-edit.cpp:1040 +msgid "Rotate the pattern fill; with Ctrl to snap angle" +msgstr "" +"A kitöltőminta elforgatása. Szöghöz való illesztés: Ctrl." + +#: ../../po/../src/object-edit.cpp:1065 +msgid "Drag to resize the flowed text frame" +msgstr "A tördelt szöveg keretének átméretezése húzással lehetséges." + +#. Item dialog +#: ../../po/../src/object-ui.cpp:106 +msgid "Object _Properties" +msgstr "Objekt_um-tulajdonságok" + +#. Select item +#: ../../po/../src/object-ui.cpp:116 +msgid "_Select This" +msgstr "Elem ki_jelölése" + +#. Create link +#: ../../po/../src/object-ui.cpp:126 +msgid "_Create Link" +msgstr "_Hivatkozás létrehozása" + +#. "Ungroup" +#: ../../po/../src/object-ui.cpp:199 ../../po/../src/verbs.cpp:1931 +msgid "_Ungroup" +msgstr "Cso_port szétbontása" + +#. Link dialog +#: ../../po/../src/object-ui.cpp:239 +msgid "Link _Properties" +msgstr "Hivatk_ozás tulajdonságai" + +#. Select item +#: ../../po/../src/object-ui.cpp:249 +msgid "_Follow Link" +msgstr "Hiv_atkozás követése" + +#. Reset transformations +#: ../../po/../src/object-ui.cpp:254 +msgid "_Remove Link" +msgstr "Hivatkozás törlé_se" + +#. Link dialog +#: ../../po/../src/object-ui.cpp:303 +msgid "Image _Properties" +msgstr "Ké_p tulajdonságai" + +#. Item dialog +#: ../../po/../src/object-ui.cpp:344 +msgid "_Fill and Stroke" +msgstr "Kitö_ltés és körvonal" + +#: ../../po/../src/path-chemistry.cpp:58 +msgid "Select at least two objects to combine." +msgstr "Jelöljön ki legalább 2 objektumot az összevonáshoz." + +#: ../../po/../src/path-chemistry.cpp:65 +msgid "At least one of the objects is not a path, cannot combine." +msgstr "Egy vagy több objektum nem lánc; összevonás nem végezhető." + +#: ../../po/../src/path-chemistry.cpp:73 +msgid "" +"You cannot combine objects from different groups or layers." +msgstr "" +"Eltérő csoportban illetve rétegben levő objektumok nem " +"vonhatók össze." + +#: ../../po/../src/path-chemistry.cpp:155 +msgid "Select path(s) to break apart." +msgstr "Jelölje ki a szétbontandó lánco(ka)t." + +#: ../../po/../src/path-chemistry.cpp:231 +msgid "No path(s) to break apart in the selection." +msgstr "A kijelölésben nincs szétbontható lánc." + +#: ../../po/../src/path-chemistry.cpp:252 +msgid "Select object(s) to convert to path." +msgstr "Jelölje ki a lánccá alakítandó objektumo(ka)t." + +#: ../../po/../src/path-chemistry.cpp:297 +msgid "No objects to convert to path in the selection." +msgstr "A kijelölésben nincs lánccá alakítható objektum." + +#: ../../po/../src/path-chemistry.cpp:345 +msgid "Select path(s) to reverse." +msgstr "Jelöljön ki egy vagy több láncot a megfordításhoz." + +#: ../../po/../src/path-chemistry.cpp:370 +msgid "No paths to reverse in the selection." +msgstr "A kijelölésben nincs megfordítható lánc." + +#: ../../po/../src/pen-context.cpp:379 ../../po/../src/pencil-context.cpp:233 +msgid "Continuing selected path" +msgstr "A kijelölt lánc folytatása" + +#: ../../po/../src/pen-context.cpp:390 ../../po/../src/pencil-context.cpp:242 +msgid "Creating new path" +msgstr "Új lánc létrehozása" + +#: ../../po/../src/pen-context.cpp:394 ../../po/../src/pencil-context.cpp:246 +msgid "Appending to selected path" +msgstr "Hozzáfűzés a kijelölt lánchoz" + +#: ../../po/../src/pen-context.cpp:538 +msgid "Click or click and drag to close and finish the path." +msgstr "" +"A lánc lezárása és befejezése: kattintással vagy kattintással + " +"húzással." + +#: ../../po/../src/pen-context.cpp:548 +msgid "" +"Click or click and drag to continue the path from this point." +msgstr "" +"A lánc folytatása ebből a pontból: kattintással vagy kattintással " +"+ húzással." + +#: ../../po/../src/pen-context.cpp:857 +#, c-format +msgid "" +"%s: angle %3.2f°, distance %s; with Ctrl to snap angle, " +"Enter to finish the path" +msgstr "" +"%s. Szög: %3.2f°. Távolság: %s. Szöghöz való illesztés: Ctrl; a lánc befejezése: Enter." + +#: ../../po/../src/pen-context.cpp:882 +#, c-format +msgid "" +"Curve handle: angle %3.2f°, length %s; with Ctrl to snap " +"angle" +msgstr "" +"Ív-vezérlőelem. Szög: %3.2f°. Hossz: %s. Szöghöz való illesztés: " +"Ctrl." + +#: ../../po/../src/pen-context.cpp:912 +#, c-format +msgid "" +"%s: angle %3.2f°, length %s; with Ctrl to snap angle, " +"with Shift to move this handle only" +msgstr "" +"%s. Szög: %3.2f°. Hossz: %s. Szöghöz való illesztés: Ctrl; csak ezen vezérlőelem áthelyezése: Shift." + +#: ../../po/../src/pen-context.cpp:946 +msgid "Finishing pen" +msgstr "Tollal rajzolt vonal befejezése" + +#: ../../po/../src/pencil-context.cpp:320 +msgid "Release here to close and finish the path." +msgstr "A lánc lezárásához és befejezéséhez engedje fel a gombot itt." + +#: ../../po/../src/pencil-context.cpp:326 +msgid "Drawing a freehand path" +msgstr "Szabadkézi lánc rajzolása" + +#: ../../po/../src/pencil-context.cpp:331 +msgid "Drag to continue the path from this point." +msgstr "A lánc folytatása ebből a pontból: húzással." + +#. Write curves to object +#: ../../po/../src/pencil-context.cpp:390 +msgid "Finishing freehand" +msgstr "Szabadkézi vonal befejezése" + +#: ../../po/../src/rect-context.cpp:387 +msgid "" +"Ctrl: make square or integer-ratio rect, lock a rounded corner " +"circular" +msgstr "" +"Ctrl: négyzet vagy egész-arányú téglalap rajzolása; lekerekített " +"csúcs körívessé tétele" + +#: ../../po/../src/rect-context.cpp:549 +#, c-format +msgid "" +"Rectangle: %s × %s; with Ctrl to make square or integer-" +"ratio rectangle; with Shift to draw around the starting point" +msgstr "" +"Téglalap: %s × %s. Négyzet vagy egész-arányú téglalap: Ctrl; rajzolás a kezdőpont köré: Shift." + +#: ../../po/../src/select-context.cpp:243 +msgid "Move canceled." +msgstr "Áthelyezés megszakítva." + +#: ../../po/../src/select-context.cpp:252 +msgid "Selection canceled." +msgstr "Kijelölés megszakítva." + +#: ../../po/../src/select-context.cpp:642 +msgid "Ctrl: select in groups, move hor/vert" +msgstr "" +"Ctrl: kijelölés csoporton belül, illetve vízszintes/függőleges " +"áthelyezés" + +#: ../../po/../src/select-context.cpp:643 +msgid "Shift: toggle select, force rubberband, disable snapping" +msgstr "" +"Shift: kijelölés bekapcsolása/kikapcsolása; területkijelölés; " +"illesztés kikapcsolása" + +#: ../../po/../src/select-context.cpp:644 +msgid "Alt: select under, move selected" +msgstr "" +"Alt: hátrébb levő objektum kijelölése, illetve kijelölt objektumok " +"áthelyezése" + +#: ../../po/../src/select-context.cpp:798 +#, fuzzy +msgid "Selected object is not a group. Cannot enter." +msgstr "" +"A kijelölt objektum nem lánc; zsugorítás illetve nyújtás nem " +"végezhető." + +#: ../../po/../src/select-context.cpp:876 +#, c-format +msgid "" +"Move by %s, %s; with Ctrl to restrict to horizontal/vertical; " +"with Shift to disable snapping" +msgstr "" +"Áthelyezés: %s, %s. Vízszintes/függőleges: Ctrl; illesztés " +"kikapcsolása: Shift." + +#: ../../po/../src/selection-chemistry.cpp:228 +msgid "Nothing was deleted." +msgstr "Nem történt törlés." + +#: ../../po/../src/selection-chemistry.cpp:259 +msgid "Select object(s) to duplicate." +msgstr "Jelölje ki a kettőzendő objektumo(ka)t." + +#: ../../po/../src/selection-chemistry.cpp:420 +msgid "Select two or more objects to group." +msgstr "Jelöljön ki 2 vagy több objektumot a csoportosításhoz." + +#: ../../po/../src/selection-chemistry.cpp:428 +msgid "Select at least two objects to group." +msgstr "Jelöljön ki legalább 2 objektumot a csoportosításhoz." + +#: ../../po/../src/selection-chemistry.cpp:513 +msgid "Select a group to ungroup." +msgstr "Jelölje ki a szétbontandó csoportot." + +#: ../../po/../src/selection-chemistry.cpp:554 +msgid "No groups to ungroup in the selection." +msgstr "A kijelölésben nincs szétbontható csoport." + +#: ../../po/../src/selection-chemistry.cpp:623 +msgid "Select objects to raise." +msgstr "Jelölje ki az előrébb helyezendő objektumokat." + +#: ../../po/../src/selection-chemistry.cpp:629 +#: ../../po/../src/selection-chemistry.cpp:681 +#: ../../po/../src/selection-chemistry.cpp:715 +#: ../../po/../src/selection-chemistry.cpp:773 +msgid "" +"You cannot raise/lower objects from different groups or layers." +msgstr "" +"Eltérő csoportban illetve rétegben levő objektumok nem " +"helyezhetők előrébb illetve hátrébb." + +#: ../../po/../src/selection-chemistry.cpp:673 +msgid "Select object(s) to raise to top." +msgstr "Jelölje ki az elölre helyezendő objektumo(ka)t." + +#: ../../po/../src/selection-chemistry.cpp:709 +msgid "Select object(s) to lower." +msgstr "Jelölje ki a hátrébb helyezendő objektumo(ka)t." + +#: ../../po/../src/selection-chemistry.cpp:765 +msgid "Select object(s) to lower to bottom." +msgstr "Jelölje ki a hátulra helyezendő objektumo(ka)t." + +#: ../../po/../src/selection-chemistry.cpp:806 +msgid "Nothing to undo." +msgstr "Nincs visszavonható művelet." + +#: ../../po/../src/selection-chemistry.cpp:813 +msgid "Nothing to redo." +msgstr "Nincs újra végrehajtható művelet." + +#: ../../po/../src/selection-chemistry.cpp:969 +msgid "Nothing was copied." +msgstr "Nem történt másolás." + +#: ../../po/../src/selection-chemistry.cpp:1051 +msgid "Current layer is hidden. Unhide it to be able to paste to it." +msgstr "" +"Az aktuális réteg rejtett. Ha szeretne beillesztést végezni arra, " +"akkor szüntesse meg annak rejtettségét." + +#: ../../po/../src/selection-chemistry.cpp:1055 +msgid "Current layer is locked. Unlock it to be able to paste to it." +msgstr "" +"Az aktuális réteg zárolt. Ha szeretne beillesztést végezni arra, " +"akkor szüntesse meg annak zároltságát." + +#: ../../po/../src/selection-chemistry.cpp:1068 +#: ../../po/../src/selection-chemistry.cpp:1103 +msgid "Nothing on the clipboard." +msgstr "A vágólap üres." + +#: ../../po/../src/selection-chemistry.cpp:1109 +msgid "Select object(s) to paste style to." +msgstr "Jelöljön ki objektumo(ka)t a stílus beillesztéséhez." + +#: ../../po/../src/selection-chemistry.cpp:1128 +msgid "Select object(s) to move to the layer above." +msgstr "Jelölje ki az előrébb levő rétegbe áthelyezendő objektumo(ka)t." + +#: ../../po/../src/selection-chemistry.cpp:1146 +msgid "No more layers above." +msgstr "Nincs előrébb levő réteg." + +#: ../../po/../src/selection-chemistry.cpp:1160 +msgid "Select object(s) to move to the layer below." +msgstr "Jelölje ki a hátrébb levő rétegbe áthelyezendő objektumo(ka)t." + +#: ../../po/../src/selection-chemistry.cpp:1178 +msgid "No more layers below." +msgstr "Nincs hátrébb levő réteg." + +#: ../../po/../src/selection-chemistry.cpp:1811 +msgid "Select a clone to unlink." +msgstr "Jelölje ki a lekapcsolandó klónt." + +#: ../../po/../src/selection-chemistry.cpp:1842 +msgid "No clones to unlink in the selection." +msgstr "A kijelölésben nincs lekapcsolható klón." + +#: ../../po/../src/selection-chemistry.cpp:1859 +msgid "" +"Select a clone to go to its original. Select a linked offset " +"to go to its source. Select a text on path to go to the path. Select " +"a flowed text to go to its frame." +msgstr "" +"Klónt kijelölve eljuthat annak eredeti objektumához; kapcsolt " +"peremet kijelölve annak forrásához; láncon levő szöveget " +"kijelölve a lánchoz; tördelt szöveget kijelölve pedig annak keretéhez." + +#: ../../po/../src/selection-chemistry.cpp:1882 +msgid "" +"Cannot find the object to select (orphaned clone, offset, textpath, " +"flowed text?)" +msgstr "" +"A kijelölendő objektum nem található (elárvult klón, perem, szöveg-" +"lánc, vagy tördelt szöveg?)" + +#: ../../po/../src/selection-chemistry.cpp:1888 +msgid "" +"The object you're trying to select is not visible (it is in <" +"defs>)" +msgstr "A kijelölendő objektum nem látható (<defs>-ben szerepel)" + +#: ../../po/../src/selection-chemistry.cpp:1915 +msgid "Select object(s) to convert to pattern." +msgstr "Jelölje ki a mintává alakítandó objektumo(ka)t." + +#: ../../po/../src/selection-chemistry.cpp:2006 +msgid "Select an object with pattern fill to extract objects from." +msgstr "" +"Jelölje ki azt a mintával kitöltött objektumot, amelyből ki szeretné " +"nyerni az objektumokat." + +#: ../../po/../src/selection-chemistry.cpp:2059 +msgid "No pattern fills in the selection." +msgstr "A kijelölésben nincs kitöltőminta." + +#: ../../po/../src/selection-chemistry.cpp:2079 +msgid "Select object(s) to make a bitmap copy." +msgstr "Jelölje ki a bitképbe másolandó objektumo(ka)t." + +#: ../../po/../src/selection-describer.cpp:37 +msgid "Click selection to toggle scale/rotation handles" +msgstr "" +"A méretezési és az elforgatási mód közti váltáshoz kattintson a kijelölésre" + +#. no items +#: ../../po/../src/selection-describer.cpp:39 +msgid "" +"No objects selected. Click, Shift+click, or drag around objects to select." +msgstr "" +"Nincs kijelölve objektum. Kijelölés: kattintással (ha szükséges, Shifttel) " +"vagy egy terület kijelölésével." + +#: ../../po/../src/selection-describer.cpp:51 +#, c-format +msgid " in layer %s" +msgstr " a(z) \"%s\" rétegben" + +#: ../../po/../src/selection-describer.cpp:54 +#, c-format +msgid " in layer %s" +msgstr " a(z) \"%s\" rétegben" + +# kiíráskor tesz egy pontot a végére +#: ../../po/../src/selection-describer.cpp:66 +msgid "Use Shift+D to look up original" +msgstr "Az eredeti objektum meghatározása: Shift+D" + +# kiíráskor tesz egy pontot a végére +#: ../../po/../src/selection-describer.cpp:70 +msgid "Use Shift+D to look up path" +msgstr "A lánc meghatározása: Shift+D" + +# kiíráskor tesz egy pontot a végére +#: ../../po/../src/selection-describer.cpp:74 +msgid "Use Shift+D to look up frame" +msgstr "A keret meghatározása: Shift+D" + +#: ../../po/../src/selection-describer.cpp:84 +#, c-format +msgid "%i object selected" +msgid_plural "%i objects selected" +msgstr[0] "%i objektum kijelölve" +msgstr[1] "%i objektum kijelölve" + +#: ../../po/../src/selection-describer.cpp:90 +#, c-format +msgid "%s%s. %s." +msgstr "%s%s. %s." + +#: ../../po/../src/selection-describer.cpp:94 +#, c-format +msgid "%s in %i layer. %s." +msgid_plural "%s in %i layers. %s." +msgstr[0] "%s %i rétegben. %s." +msgstr[1] "%s %i rétegben. %s." + +#: ../../po/../src/seltrans.cpp:498 +msgid "" +"Center of rotation and skewing: drag to reposition; scaling with " +"Shift also uses this center" +msgstr "" +"Az elforgatás illetve nyírás középpontja. Áthelyezés: húzással. A " +"Shifttel való átméretezés ugyanezen középpontot használja." + +#: ../../po/../src/seltrans.cpp:514 +msgid "" +"Squeeze or stretch selection; with Ctrl to scale uniformly; " +"with Shift to scale around rotation center" +msgstr "" +"A kijelölés zsugorítása vagy nyújtása. Egyenletes átméretezés: " +"Ctrl; átméretezés a forgatási középpontból: Shift." + +#: ../../po/../src/seltrans.cpp:515 +msgid "" +"Scale selection; with Ctrl to scale uniformly; with Shift to scale around rotation center" +msgstr "" +"A kijelölés átméretezése. Egyenletes átméretezés: Ctrl; " +"átméretezés a forgatási középpontból: Shift." + +#: ../../po/../src/seltrans.cpp:519 +msgid "" +"Skew selection; with Ctrl to snap angle; with Shift to " +"skew around the opposite side" +msgstr "" +"A kijelölés nyírása. Szöghöz való illesztés: Ctrl; nyírás a " +"túlsó oldalhoz viszonyítva: Shift." + +#: ../../po/../src/seltrans.cpp:520 +msgid "" +"Rotate selection; with Ctrl to snap angle; with Shift " +"to rotate around the opposite corner" +msgstr "" +"A kijelölés elforgatása. Szöghöz való illesztés: Ctrl; " +"forgatás a túlsó sarok körül: Shift." + +#: ../../po/../src/seltrans.cpp:829 ../../po/../src/seltrans.cpp:909 +#, c-format +msgid "Scale: %0.2f%% x %0.2f%%; with Ctrl to lock ratio" +msgstr "" +"Átméretezés: %0.2f%% x %0.2f%%. Az arány megőrzése: Ctrl." + +#. TRANSLATORS: don't modify the first ";" (it will NOT be displayed as ";" - only the second one will be) +#: ../../po/../src/seltrans.cpp:984 +#, c-format +msgid "Skew: %0.2f°; with Ctrl to snap angle" +msgstr "Nyírás: %0.2f°. Szöghöz való illesztés: Ctrl." + +#. TRANSLATORS: don't modify the first ";" (it will NOT be displayed as ";" - only the second one will be) +#: ../../po/../src/seltrans.cpp:1035 +#, c-format +msgid "Rotate: %0.2f°; with Ctrl to snap angle" +msgstr "Elforgatás: %0.2f°. Szöghöz való illesztés: Ctrl." + +#: ../../po/../src/seltrans.cpp:1090 +#, c-format +msgid "Move center to %s, %s" +msgstr "Középpont áthelyezése ide: %s, %s" + +#: ../../po/../src/slideshow.cpp:90 +msgid "Inkscape slideshow" +msgstr "Inkscape diavetítés" + +#: ../../po/../src/sp-anchor.cpp:181 +#, c-format +msgid "Link to %s" +msgstr "Hivatkozás erre: %s" + +#: ../../po/../src/sp-anchor.cpp:185 +msgid "Link without URI" +msgstr "URI nélküli hivatkozás" + +#: ../../po/../src/sp-ellipse.cpp:438 ../../po/../src/sp-ellipse.cpp:870 +msgid "Ellipse" +msgstr "Ellipszis" + +#: ../../po/../src/sp-ellipse.cpp:583 +msgid "Circle" +msgstr "Kör" + +#: ../../po/../src/sp-ellipse.cpp:865 +msgid "Segment" +msgstr "Ellipsziscikk" + +#: ../../po/../src/sp-ellipse.cpp:867 +msgid "Arc" +msgstr "Ellipszisív" + +#. TRANSLATORS: "Flow region" is an area where text is allowed to flow +#: ../../po/../src/sp-flowregion.cpp:276 +msgid "Flow region" +msgstr "Tördelési terület" + +#. TRANSLATORS: A region "cut out of" a flow region; text is not allowed to flow inside the +#. * flow excluded region. flowRegionExclude in SVG 1.2: see +#. * http://www.w3.org/TR/2004/WD-SVG12-20041027/flow.html#flowRegion-elem and +#. * http://www.w3.org/TR/2004/WD-SVG12-20041027/flow.html#flowRegionExclude-elem. +#: ../../po/../src/sp-flowregion.cpp:493 +msgid "Flow excluded region" +msgstr "Tördelésből kizárt terület" + +#: ../../po/../src/sp-flowtext.cpp:355 +#, c-format +msgid "Flowed text (%d characters)" +msgstr "Tördelt szöveg (%d karakter)" + +#: ../../po/../src/sp-flowtext.cpp:357 +#, c-format +msgid "Linked flowed text (%d characters)" +msgstr "Kapcsolt tördelt szöveg (%d karakter)" + +#: ../../po/../src/sp-guide.cpp:290 +msgid "vertical guideline" +msgstr "függőleges segédvonal" + +#: ../../po/../src/sp-guide.cpp:292 +msgid "horizontal guideline" +msgstr "vízszintes segédvonal" + +#: ../../po/../src/sp-image.cpp:835 +msgid "embedded" +msgstr "beágyazott" + +#: ../../po/../src/sp-image.cpp:839 +msgid "(null_pointer)" +msgstr "(null_hivatkozás)" + +#: ../../po/../src/sp-image.cpp:843 +#, c-format +msgid "Image with bad reference: %s" +msgstr "Helytelen képhivatkozás: %s" + +#: ../../po/../src/sp-image.cpp:844 +#, c-format +msgid "Image %d × %d: %s" +msgstr "%d × %d méretű kép: %s" + +#: ../../po/../src/sp-item-group.cpp:390 +#, c-format +msgid "Group of %d object" +msgid_plural "Group of %d objects" +msgstr[0] "%d objektumot tartalmazó csoport" +msgstr[1] "%d objektumot tartalmazó csoport" + +#: ../../po/../src/sp-item.cpp:720 +msgid "Object" +msgstr "Objektum" + +#: ../../po/../src/sp-line.cpp:202 +msgid "Line" +msgstr "Vonal" + +#. TRANSLATORS COMMENT: %s is either "outset" or "inset" depending on sign +#: ../../po/../src/sp-offset.cpp:433 +#, c-format +msgid "Linked offset, %s by %f pt" +msgstr "Kapcsolt perem; %s %f ponttal (pt)" + +#: ../../po/../src/sp-offset.cpp:434 ../../po/../src/sp-offset.cpp:438 +msgid "outset" +msgstr "nyújtva" + +#: ../../po/../src/sp-offset.cpp:434 ../../po/../src/sp-offset.cpp:438 +msgid "inset" +msgstr "zsugorítva" + +#. TRANSLATORS COMMENT: %s is either "outset" or "inset" depending on sign +#: ../../po/../src/sp-offset.cpp:437 +#, c-format +msgid "Dynamic offset, %s by %f pt" +msgstr "Dinamikus perem; %s %f ponttal (pt)" + +#: ../../po/../src/sp-path.cpp:127 +#, c-format +msgid "Path (%i node)" +msgid_plural "Path (%i nodes)" +msgstr[0] "Lánc (%i csomópont)" +msgstr[1] "Lánc (%i csomópont)" + +#: ../../po/../src/sp-polygon.cpp:216 +msgid "Polygon" +msgstr "Sokszög" + +#: ../../po/../src/sp-polyline.cpp:179 +msgid "Polyline" +msgstr "Kapcsolódó vonalak" + +#: ../../po/../src/sp-rect.cpp:250 +msgid "Rectangle" +msgstr "Téglalap" + +#. TRANSLATORS: since turn count isn't an integer, please adjust the +#. string as needed to deal with an localized plural forms. +#: ../../po/../src/sp-spiral.cpp:305 +#, c-format +msgid "Spiral with %3f turns" +msgstr "%3f fordulatú spirál" + +#: ../../po/../src/sp-star.cpp:288 +#, c-format +msgid "Star with %d vertex" +msgid_plural "Star with %d vertices" +msgstr[0] "%d csúcsú csillag" +msgstr[1] "%d csúcsú csillag" + +#: ../../po/../src/sp-star.cpp:292 +#, c-format +msgid "Polygon with %d vertex" +msgid_plural "Polygon with %d vertices" +msgstr[0] "%d csúcsú sokszög" +msgstr[1] "%d csúcsú sokszög" + +#. TRANSLATORS: For description of font with no name. +#: ../../po/../src/sp-text.cpp:420 +msgid "<no name found>" +msgstr "<név nem található>" + +#: ../../po/../src/sp-text.cpp:426 +#, c-format +msgid "Text on path (%s, %s)" +msgstr "Láncon levő szöveg (%s, %s)" + +#: ../../po/../src/sp-text.cpp:427 +#, c-format +msgid "Text (%s, %s)" +msgstr "Szöveg (%s, %s)" + +#. TRANSLATORS: Used for statusbar description for long chains: +#. * "Clone of: Clone of: ... in Layer 1". +#: ../../po/../src/sp-use.cpp:317 +msgid "..." +msgstr "..." + +#: ../../po/../src/sp-use.cpp:325 +#, c-format +msgid "Clone of: %s" +msgstr "\"%s\" klónja" + +#: ../../po/../src/sp-use.cpp:329 +msgid "Orphaned clone" +msgstr "Elárvult klón" + +#: ../../po/../src/spiral-context.cpp:355 +msgid "Ctrl: snap angle" +msgstr "Ctrl: szöghöz való illesztés" + +#: ../../po/../src/spiral-context.cpp:357 +msgid "Alt: lock spiral radius" +msgstr "Alt: a spirál sugarának megőrzése" + +#: ../../po/../src/spiral-context.cpp:469 +#, c-format +msgid "" +"Spiral: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" +"Spirál. Sugár: %s, szög: %5g°. Szöghöz való illesztés: Ctrl." + +#: ../../po/../src/splivarot.cpp:106 +msgid "Select at least 2 paths to perform a boolean operation." +msgstr "Logikai műveletekhez legalább 2 láncot ki kell jelölni." + +#: ../../po/../src/splivarot.cpp:112 +msgid "" +"Select exactly 2 paths to perform difference, XOR, division, or path " +"cut." +msgstr "" +"Különbségképzés, kizáró VAGY, felosztás illetve láncelvágás esetén " +"pontosan 2 láncot kell kijelölni." + +#: ../../po/../src/splivarot.cpp:129 ../../po/../src/splivarot.cpp:144 +msgid "" +"Unable to determine the z-order of the objects selected for " +"difference, XOR, division, or path cut." +msgstr "" +"Nem sikerült meghatározni a különbségképzéshez, \"kizáró VAGY\" művelethez, " +"felosztáshoz illetve láncelvágáshoz kijelölt objektumok z-sorrendjét." + +#: ../../po/../src/splivarot.cpp:174 +msgid "" +"One of the objects is not a path, cannot perform boolean operation." +msgstr "Az egyik objektum nem lánc; logikai művelet nem hajtható végre." + +#. TRANSLATORS: "to outline" means "to convert stroke to path" +#: ../../po/../src/splivarot.cpp:554 +msgid "Select path(s) to outline." +msgstr "Jelöljön ki lánco(ka)t a körvonal lánccá alakításához." + +#. TRANSLATORS: "to outline" means "to convert stroke to path" +#: ../../po/../src/splivarot.cpp:748 +msgid "No stroked paths to outline in the selection." +msgstr "A kijelölésben nincs körvonallal rendelkező lánc." + +#: ../../po/../src/splivarot.cpp:832 +msgid "Selected object is not a path, cannot inset/outset." +msgstr "" +"A kijelölt objektum nem lánc; zsugorítás illetve nyújtás nem " +"végezhető." + +#: ../../po/../src/splivarot.cpp:1040 +msgid "Select path(s) to inset/outset." +msgstr "Jelölje ki a zsugorítandó illetve nyújtandó lánco(ka)t." + +#: ../../po/../src/splivarot.cpp:1257 +msgid "No paths to inset/outset in the selection." +msgstr "A kijelölésben nincs zsugorítható illetve nyújtható lánc." + +#: ../../po/../src/splivarot.cpp:1390 +msgid "Select path(s) to simplify." +msgstr "Jelölje ki az egyszerűsítendő lánco(ka)t." + +#: ../../po/../src/splivarot.cpp:1417 +msgid "No paths to simplify in the selection." +msgstr "A kijelölésben nincs egyszerűsíthető lánc." + +#: ../../po/../src/star-context.cpp:362 +msgid "Ctrl: snap angle; keep rays radial" +msgstr "Ctrl: szöghöz való illesztés; ágak sugárirányban való tartása" + +#: ../../po/../src/star-context.cpp:470 +#, c-format +msgid "" +"Polygon: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" +"Sokszög. Sugár: %s, szög: %5g°. Szöghöz való illesztés: Ctrl." + +#: ../../po/../src/star-context.cpp:471 +#, c-format +msgid "Star: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" +"Csillag. Sugár: %s, szög: %5g°. Szöghöz való illesztés: Ctrl." + +#: ../../po/../src/text-chemistry.cpp:90 +msgid "Select a text and a path to put text on path." +msgstr "" +"Szövegnek egy láncra való illesztéséhez jelöljön ki egy szöveget és egy " +"láncot." + +#: ../../po/../src/text-chemistry.cpp:95 +msgid "" +"This text object is already put to a path. Remove it from the path " +"first. Use Shift+D to look up its path." +msgstr "" +"Ez a szövegobjektum már láncra lett illesztve. Előbb távolítsa el a " +"láncról. A lánc meghatározása: Shift+D." + +#. rect is the only SPShape which is not yet, and thus SVG forbids us from putting text on it +#: ../../po/../src/text-chemistry.cpp:101 +msgid "" +"You cannot put text on a rectangle in this version. Convert rectangle to " +"path first." +msgstr "" +"A jelenlegi verzió nem támogatja a szöveg téglalapra való illesztését. Az " +"illesztés elvégzéséhez alakítsa lánccá a téglalapot." + +#: ../../po/../src/text-chemistry.cpp:159 +msgid "Select a text on path to remove it from path." +msgstr "" +"Szövegnek egy láncról való eltávolításához jelöljön ki egy láncon levő " +"szöveget." + +#: ../../po/../src/text-chemistry.cpp:181 +msgid "No texts-on-paths in the selection." +msgstr "A kijelölésben nincs láncon levő szöveg." + +#: ../../po/../src/text-chemistry.cpp:209 +#: ../../po/../src/text-chemistry.cpp:229 +msgid "Select text(s) to remove kerns from." +msgstr "Jelöljön ki egy vagy több szöveget az alávágás eltávolításához." + +#: ../../po/../src/text-chemistry.cpp:250 +msgid "" +"Select a text and one or more paths or shapes to flow text " +"into frame." +msgstr "" +"Szövegnek egy keretbe való tördeléséhez jelöljön ki egy szöveget és " +"egy vagy több láncot illetve alakzatot." + +#: ../../po/../src/text-chemistry.cpp:322 +msgid "Select a flowed text to unflow it." +msgstr "" +"Szöveg tördelésének megszüntetéséhez jelölje ki a tördelt szöveget." + +#: ../../po/../src/text-context.cpp:463 +msgid "Click to edit the text, drag to select part of the text." +msgstr "" +"A szöveg szerkesztése: kattintással. A szöveg egy részének " +"kijelölése: húzással." + +#: ../../po/../src/text-context.cpp:465 +msgid "" +"Click to edit the flowed text, drag to select part of the text." +msgstr "" +"A tördelt szöveg szerkesztése: kattintással. A szöveg egy részének " +"kijelölése: húzással." + +#: ../../po/../src/text-context.cpp:540 +msgid "Non-printable character" +msgstr "Nem nyomtatható karakter" + +#: ../../po/../src/text-context.cpp:589 +#, c-format +msgid "Unicode: %s: %s" +msgstr "Unicode: %s: %s" + +#: ../../po/../src/text-context.cpp:591 ../../po/../src/text-context.cpp:855 +msgid "Unicode: " +msgstr "Unicode: " + +#: ../../po/../src/text-context.cpp:615 +msgid "Current layer is hidden. Unhide it to be able to add text." +msgstr "" +"Az aktuális réteg rejtett. Ha szeretne szöveget felvenni arra, akkor " +"szüntesse meg annak rejtettségét." + +#: ../../po/../src/text-context.cpp:619 +msgid "Current layer is locked. Unlock it to be able to add text." +msgstr "" +"Az aktuális réteg zárolt. Ha szeretne szöveget felvenni arra, akkor " +"szüntesse meg annak zároltságát." + +#: ../../po/../src/text-context.cpp:673 +#, c-format +msgid "Flowed text frame: %s × %s" +msgstr "Tördelt szöveg kerete: %s × %s" + +#: ../../po/../src/text-context.cpp:708 ../../po/../src/text-context.cpp:1464 +msgid "Type text; Enter to start new line." +msgstr "" +"Gépelje be a szöveget. Új sort az Enter billentyűvel lehet kezdeni." + +#: ../../po/../src/text-context.cpp:719 +msgid "Flowed text is created." +msgstr "Tördelt szöveg létrehozva." + +#: ../../po/../src/text-context.cpp:722 +msgid "" +"The frame is too small for the current font size. Flowed text not " +"created." +msgstr "" +"A keret túl kicsi a jelenlegi betűmérethez viszonyítva. A tördelt " +"szöveg nem lett létrehozva." + +#: ../../po/../src/text-context.cpp:841 +msgid "No-break space" +msgstr "Nem törhető szóköz" + +#: ../../po/../src/text-context.cpp:1462 +msgid "Type flowed text; Enter to start new paragraph." +msgstr "" +"Gépelje be a tördelendő szöveget. Új bekezdést az Enter billentyűvel " +"lehet kezdeni." + +#: ../../po/../src/text-context.cpp:1472 ../../po/../src/tools-switch.cpp:189 +msgid "" +"Click to select or create text, drag to create flowed text; " +"then type." +msgstr "" +"Szöveg kijelölése vagy létrehozása: kattintással. Tördelt szöveg " +"létrehozása: húzással. Szövegmódosítás: gépeléssel." + +#: ../../po/../src/tools-switch.cpp:141 +msgid "" +"To edit a path, click, Shift+click, or drag around " +"nodes to select them, then drag nodes and handles. Click on an " +"object to select." +msgstr "" +"Lánc szerkesztéséhez jelöljön ki csomópontokat (kattintással, Shift" +"+kattintással vagy terület-kijelöléssel), majd helyezze át " +"azokat vagy vezérlőelemeiket. Objektumkijelölés: kattintással." + +#: ../../po/../src/tools-switch.cpp:147 +msgid "" +"Drag to create a rectangle. Drag controls to round corners and " +"resize. Click to select." +msgstr "" +"Téglalap létrehozása: húzással. Sarkok lekerekítése illetve " +"átméretezés: vezérlőelemekkel. Kijelölés: kattintással." + +#: ../../po/../src/tools-switch.cpp:153 +msgid "" +"Drag to create an ellipse. Drag controls to make an arc or " +"segment. Click to select." +msgstr "" +"Ellipszis létrehozása: húzással. Ellipszisív vagy -cikk létrehozása: " +"vezérlőelemekkel. Kijelölés: kattintással." + +#: ../../po/../src/tools-switch.cpp:159 +msgid "" +"Drag to create a star. Drag controls to edit the star shape. " +"Click to select." +msgstr "" +"Csillag létrehozása: húzással. A csillag alakjának módosítása: " +"vezérlőelemekkel. Kijelölés: kattintással." + +#: ../../po/../src/tools-switch.cpp:165 +msgid "" +"Drag to create a spiral. Drag controls to edit the spiral " +"shape. Click to select." +msgstr "" +"Spirál létrehozása: húzással. A spirál alakjának módosítása: " +"vezérlőelemekkel. Kijelölés: kattintással." + +#: ../../po/../src/tools-switch.cpp:171 +msgid "" +"Drag to create a freehand line. Start drawing with Shift to " +"append to selected path." +msgstr "" +"Szabadkézi vonal létrehozása: húzással. A kijelölt lánchoz való " +"hozzáfűzéshez a Shift lenyomása mellett kezdje a rajzolást." + +#: ../../po/../src/tools-switch.cpp:177 +msgid "" +"Click or click and drag to start a path; with Shift to " +"append to selected path." +msgstr "" +"Lánc létrehozása: kattintással vagy kattintással + húzással. A " +"kijelölt lánchoz való hozzáfűzés: Shift." + +#: ../../po/../src/tools-switch.cpp:183 +msgid "" +"Drag to paint a calligraphic stroke. Left/right arrow " +"keys adjust width, up/down adjust angle." +msgstr "" +"Művészi vonal rajzolása: húzással. Szélesség állítása: Balra/" +"Jobbra nyíl. Szög állítása: Fel/Le nyíl." + +#: ../../po/../src/tools-switch.cpp:195 +msgid "" +"Drag or double click to create a gradient on selected objects, " +"drag handles to adjust gradients." +msgstr "" +"Színátmenet létrehozása a kijelölt objektumokon: húzással vagy " +"dupla kattintással. A színátmenetek módosítása: a vezérlőelemek " +"húzásával." + +#: ../../po/../src/tools-switch.cpp:201 +msgid "" +"Click or drag around an area to zoom in, Shift+click to " +"zoom out." +msgstr "" +"Nagyítás: kattintással vagy a kívánt terület kijelölésével. " +"Kicsinyítés: Shift+kattintással." + +#: ../../po/../src/tools-switch.cpp:213 +msgid "Click and drag between shapes to create a connector." +msgstr "" +"Kapocs létrehozása: az alakzatok közt való kattintással + húzással." + +#: ../../po/../src/trace/potrace/inkscape-potrace.cpp:553 +#: ../../po/../src/trace/potrace/inkscape-potrace.cpp:654 +#, c-format +msgid "Trace: %d. %ld nodes" +msgstr "Vektorizálás: %d. %ld csomópont." + +#: ../../po/../src/trace/trace.cpp:53 ../../po/../src/trace/trace.cpp:62 +#: ../../po/../src/trace/trace.cpp:70 +msgid "Select an image to trace" +msgstr "Jelölje ki a vektorizálandó képet." + +#: ../../po/../src/trace/trace.cpp:133 +msgid "Trace: No active document" +msgstr "Vektorizálás: nincs aktív dokumentum" + +#: ../../po/../src/trace/trace.cpp:154 +msgid "Trace: Image has no bitmap data" +msgstr "Vektorizálás: a képben nincs bitkép-adat" + +#: ../../po/../src/trace/trace.cpp:267 +#, c-format +msgid "Trace: Done. %ld nodes created" +msgstr "Vektorizálás: kész. %ld csomópont létrehozva." + +#: ../../po/../src/ui/dialog/aboutbox.cpp:59 ../../po/../src/verbs.cpp:2212 +msgid "About Inkscape" +msgstr "Az Inkscape névjegye" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:66 +msgid "_Splash" +msgstr "" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:68 +#, fuzzy +msgid "_Authors" +msgstr "Szerzők" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:69 +#, fuzzy +msgid "_Translators" +msgstr "Fordítók" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:70 +msgid "_License" +msgstr "_Licenc" + +#. TRANSLATORS: This is the filename of the `About Inkscape' picture in +#. the `screens' directory. Thus the translation of "about.svg" should be +#. the filename of its translated version, e.g. about.zh.svg for Chinese. +#. +#. N.B. about.svg changes once per release. (We should probably rename +#. the original to about-0.40.svg etc. as soon as we have a translation. +#. If we do so, then add an item to release-checklist saying that the +#. string here should be changed.) +#. FIXME? INKSCAPE_SCREENSDIR and "about.svg" are in UTF-8, not the +#. native filename encoding... and the filename passed to sp_document_new +#. should be in UTF-*8.. +#: ../../po/../src/ui/dialog/aboutbox.cpp:114 +msgid "about.svg" +msgstr "about.svg" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:464 +msgid "Minimum horizontal gap (in px units) between bounding boxes" +msgstr "" + +#. TRANSLATORS: Horizontal gap +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:466 +#: ../../po/../src/widgets/toolbox.cpp:1556 +msgid "H:" +msgstr "M:" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:474 +msgid "Minimum vertical gap (in px units) between bounding boxes" +msgstr "" + +#. TRANSLATORS: Vertical gap +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:476 +msgid "V:" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:734 +msgid "Align" +msgstr "Igazítás" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:735 +msgid "Distribute" +msgstr "Elrendezés" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:736 +msgid "Remove overlaps" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:737 +msgid "Nodes" +msgstr "Csomópontok" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:742 +msgid "Relative to: " +msgstr "Ehhez viszonyítva: " + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:747 +msgid "Align right sides of objects to left side of anchor" +msgstr "Az objektumok jobb oldalának igazítása a horgony bal oldalához" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:750 +msgid "Align left sides" +msgstr "Bal oldalak igazítása" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:753 +msgid "Center on vertical axis" +msgstr "Középre igazítás a függőleges tengelyhez" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:756 +msgid "Align right sides" +msgstr "Jobb oldalak igazítása" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:759 +msgid "Align left sides of objects to right side of anchor" +msgstr "Az objektumok bal oldalának igazítása a horgony jobb oldalához" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:762 +msgid "Align bottoms of objects to top of anchor" +msgstr "Az objektumok aljának igazítása a horgony tetejéhez" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:765 +msgid "Align tops" +msgstr "Felső szélek igazítása" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:768 +msgid "Center on horizontal axis" +msgstr "Középre igazítás a vízszintes tengelyhez" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:771 +msgid "Align bottoms" +msgstr "Alsó szélek igazítása" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:774 +msgid "Align tops of objects to bottom of anchor" +msgstr "Az objektumok tetejének igazítása a horgony aljához" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:779 +msgid "Align baseline anchors of texts vertically" +msgstr "A szövegek alapvonal-horgonyainak függőleges igazítása" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:782 +msgid "Align baseline anchors of texts horizontally" +msgstr "A szövegek alapvonal-horgonyainak vízszintes igazítása" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:787 +msgid "Make horizontal gaps between objects equal" +msgstr "Az objektumok közti vízszintes helyek azonossá tétele" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:791 +msgid "Distribute left sides equidistantly" +msgstr "A bal oldalak egyenletes távolságban való elrendezése" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:794 +msgid "Distribute centers equidistantly horizontally" +msgstr "A közepek egyenletes távolságban való vízszintes elrendezése" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:797 +msgid "Distribute right sides equidistantly" +msgstr "A jobb oldalak egyenletes távolságban való elrendezése" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:801 +msgid "Make vertical gaps between objects equal" +msgstr "Az objektumok közti függőleges helyek azonossá tétele" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:805 +msgid "Distribute tops equidistantly" +msgstr "A felső szélek egyenletes távolságban való elrendezése" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:808 +msgid "Distribute centers equidistantly vertically" +msgstr "A közepek egyenletes távolságban való függőleges elrendezése" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:811 +msgid "Distribute bottoms equidistantly" +msgstr "Az alsó szélek egyenletes távolságban való elrendezése" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:816 +msgid "Distribute baseline anchors of texts horizontally" +msgstr "A szövegek alapvonal-horgonyainak vízszintes elrendezése" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:819 +msgid "Distribute baseline anchors of texts vertically" +msgstr "A szövegek alapvonal-horgonyainak függőleges elrendezése" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:824 +msgid "Randomize centers in both dimensions" +msgstr "A közepek véletlenszerű elrendezése mindkét dimenzióban" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:827 +msgid "Unclump objects: try to equalize edge-to-edge distances" +msgstr "Objektumok egyenletesítése: a szélek közti távolságok azonossá tevése" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:832 +msgid "" +"Move objects as little as possible so that their bounding boxes do not " +"overlap" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:837 +msgid "Align selected nodes horizontally" +msgstr "A kijelölt csomópontok vízszintes igazítása" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:840 +msgid "Align selected nodes vertically" +msgstr "A kijelölt csomópontok függőleges igazítása" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:843 +msgid "Distribute selected nodes horizontally" +msgstr "A kijelölt csomópontok vízszintes elrendezése" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:846 +msgid "Distribute selected nodes vertically" +msgstr "A kijelölt csomópontok függőleges elrendezése" + +#. Rest of the widgetry +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:851 +msgid "Last selected" +msgstr "Legutóbb kijelölt" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:852 +msgid "First selected" +msgstr "Először kijelölt" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:853 +msgid "Biggest item" +msgstr "Legnagyobb elem" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:854 +msgid "Smallest item" +msgstr "Legkisebb elem" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:856 +#: ../../po/../src/widgets/desktop-widget.cpp:1065 +msgid "Drawing" +msgstr "Rajz" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:91 +#, fuzzy +msgid "Metadata 1" +msgstr "Metaadatok" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:92 +#, fuzzy +msgid "Metadata 2" +msgstr "Metaadatok" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:187 +#, fuzzy +msgid "X coordinate of grid origin" +msgstr "A kijelölés függőleges koordinátája" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:189 +#, fuzzy +msgid "Y coordinate of grid origin" +msgstr "A kijelölés függőleges koordinátája" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:191 +#, fuzzy +msgid "Distance of vertical grid lines" +msgstr "függőleges segédvonal" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:193 +#, fuzzy +msgid "Distance of horizontal grid lines" +msgstr "vízszintes segédvonal" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:197 +msgid "Max. snapping distance from grid" +msgstr "" + +#: ../../po/../src/ui/dialog/export.cpp:34 +msgid "Export" +msgstr "Exportálás" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:36 +msgid "Fill" +msgstr "Kitöltés" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:37 +msgid "Stroke Paint" +msgstr "Körvonalrajzolat" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:38 +msgid "Stroke Style" +msgstr "Körvonalstílus" + +#: ../../po/../src/ui/dialog/find.cpp:34 +msgid "Find" +msgstr "Keresés" + +#: ../../po/../src/ui/dialog/memory.cpp:96 +msgid "Heap" +msgstr "Heap" + +#: ../../po/../src/ui/dialog/memory.cpp:97 +msgid "In Use" +msgstr "Használatban" + +#. TRANSLATORS: "Slack" refers to memory which is in the heap but currently unused. +#. More typical usage is to call this memory "free" rather than "slack". +#: ../../po/../src/ui/dialog/memory.cpp:100 +msgid "Slack" +msgstr "Szabad" + +# May contain a short, human readable description of the resource as plain, unmarked text. +#: ../../po/../src/ui/dialog/memory.cpp:101 +msgid "Total" +msgstr "Összesen" + +#: ../../po/../src/ui/dialog/memory.cpp:141 +#: ../../po/../src/ui/dialog/memory.cpp:147 +#: ../../po/../src/ui/dialog/memory.cpp:154 +#: ../../po/../src/ui/dialog/memory.cpp:186 +msgid "Unknown" +msgstr "Ismeretlen" + +#: ../../po/../src/ui/dialog/memory.cpp:167 +msgid "Combined" +msgstr "Együttesen" + +#: ../../po/../src/ui/dialog/memory.cpp:209 +msgid "Recalculate" +msgstr "Újraszámolás" + +#: ../../po/../src/ui/dialog/messages.cpp:74 +msgid "Ready." +msgstr "Kész." + +#: ../../po/../src/ui/dialog/messages.cpp:75 +msgid "" +"Enable log display by setting dialogs.debug 'redirect' attribute to 1 in " +"preferences.xml" +msgstr "" +"A napló megjelenítésének bekapcsolása a preferences.xml-beli dialogs.debug " +"'redirect' attribútum 1-re való állításával lehetséges" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:184 +msgid "_Execute Python" +msgstr "P_ython végrehajtása" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:186 +msgid "_Execute Perl" +msgstr "P_erl végrehajtása" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:195 +msgid "Script" +msgstr "Szkript" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:205 +msgid "Output" +msgstr "Kimenet" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:215 +msgid "Errors" +msgstr "Hibák" + +#. Dialog organization +#: ../../po/../src/ui/dialog/session-player.cpp:73 +msgid "Session file" +msgstr "Munkamenet-fájl" + +#: ../../po/../src/ui/dialog/session-player.cpp:74 +msgid "Playback controls" +msgstr "Lejátszásvezérlők" + +#: ../../po/../src/ui/dialog/session-player.cpp:75 +msgid "Message information" +msgstr "Üzenetinformáció" + +#. Active session file display +#. fixme: Does this mean the active file for the session, or the file for the active session? +#. Please indicate which with a TRANSLATORS comment. +#: ../../po/../src/ui/dialog/session-player.cpp:85 +msgid "Active session file:" +msgstr "Aktív munkamenet-fájl:" + +#: ../../po/../src/ui/dialog/session-player.cpp:86 +msgid "Delay (milliseconds):" +msgstr "Késleltetés (ezredmásodperc):" + +#. Unload/load buttons +#: ../../po/../src/ui/dialog/session-player.cpp:94 +msgid "Close file" +msgstr "Fájl bezárása" + +#: ../../po/../src/ui/dialog/session-player.cpp:95 +msgid "Open new file" +msgstr "Új fájl megnyitása" + +#: ../../po/../src/ui/dialog/session-player.cpp:96 +msgid "Set delay" +msgstr "Késleltetés beállítása" + +#: ../../po/../src/ui/dialog/session-player.cpp:138 +msgid "Rewind" +msgstr "Visszatekerés" + +#: ../../po/../src/ui/dialog/session-player.cpp:139 +msgid "Go back one change" +msgstr "Vissza egy módosítással" + +#: ../../po/../src/ui/dialog/session-player.cpp:140 +msgid "Pause" +msgstr "Szünet" + +#: ../../po/../src/ui/dialog/session-player.cpp:141 +msgid "Go forward one change" +msgstr "Előre egy módosítással" + +#: ../../po/../src/ui/dialog/session-player.cpp:142 +msgid "Play" +msgstr "Lejátszás" + +#: ../../po/../src/ui/dialog/session-player.cpp:177 +#: ../../po/../src/verbs.cpp:1573 +msgid "Open session file" +msgstr "Munkamenet-fájl megnyitása" + +#. ##Set up the Potrace panel +#. #### brightness #### +#. #### Multiple scanning#### +#. ----Hbox1 +#: ../../po/../src/ui/dialog/tracedialog.cpp:345 +#: ../../po/../src/ui/dialog/tracedialog.cpp:428 +msgid "Brightness" +msgstr "Fényesség" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:348 +msgid "Trace by a given brightness level" +msgstr "Vektorizálás egy adott fényességszinttel" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:355 +msgid "Brightness cutoff for black/white" +msgstr "Fényesség-levágás fekete-fehér esetén" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:362 +msgid "Image Brightness" +msgstr "Képfényesség" + +#. #### canny edge detection #### +#. TRANSLATORS: "Canny" is the name of the inventor of this edge detection method +#: ../../po/../src/ui/dialog/tracedialog.cpp:369 +msgid "Optimal Edge Detection (Canny)" +msgstr "Optimális élkeresés (Canny-módszer)" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:372 +msgid "Trace with edge detection by J. Canny's algorithm" +msgstr "Vektorizálás J. Canny módszere alapján végzett élkereséssel" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:388 +msgid "Brightness cutoff for adjacent pixels (determines edge thickness)" +msgstr "" +"Fényesség-levágás a szomszédos képpontoknál (meghatározza az élvastagságot)" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:395 +msgid "Edge Detection" +msgstr "Élkeresés" + +#. #### quantization #### +#. TRANSLATORS: Color Quantization: the process of reducing the number of colors +#. in an image by selecting an optimized set of representative colors and then +#. re-applying this reduced set to the original image. +#: ../../po/../src/ui/dialog/tracedialog.cpp:404 +msgid "Color Quantization" +msgstr "Színek számának csökkentése" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:407 +msgid "Trace along the boundaries of reduced colors" +msgstr "Vektorizálás a csökkentett színek határai mentén" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:414 +msgid "The number of reduced colors" +msgstr "A csökkentett színek száma" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:416 +msgid "Colors:" +msgstr "Színek:" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:421 +msgid "Quantization / Reduction" +msgstr "Színcsökkentés" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:431 +msgid "Trace the given number of brightness levels" +msgstr "A megadott számú fényességszint vektorizálása" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:438 +msgid "Scans:" +msgstr "Képek:" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:440 +msgid "The desired number of scans" +msgstr "Az elkészítendő képek száma" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:448 +msgid "Trace the given number of reduced colors" +msgstr "A megadott számú csökkentett szín vektorizálása" + +#. ---Hbox3 +#: ../../po/../src/ui/dialog/tracedialog.cpp:454 +msgid "Monochrome" +msgstr "Egyszínű" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:457 +msgid "Same as Color, but convert result to grayscale" +msgstr "Megegyezik a Színnel, de az eredmény szürkeárnyalatossá lesz alakítva" + +#. TRANSLATORS: "Stack" is a verb here +#: ../../po/../src/ui/dialog/tracedialog.cpp:460 +msgid "Stack" +msgstr "Egymásra" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:463 +msgid "" +"Stack scans vertically (no gaps) or tile horizontally (usually with gaps)" +msgstr "" +"A képek függőleges egymásra helyezése (nincsenek rések) vagy vízszintes " +"csempézése (általában vannak rések)" + +#. TRANSLATORS: "Smooth" is a verb here +#: ../../po/../src/ui/dialog/tracedialog.cpp:466 +msgid "Smooth" +msgstr "Simítás" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:469 +msgid "Apply Gaussian blur to the bitmap before tracing" +msgstr "Gauss-elmosás alkalmazása a bitképre a vektorizálás előtt" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:473 +msgid "Multiple Scanning" +msgstr "Többszörös feldolgozás" + +#. #### Preview #### +#: ../../po/../src/ui/dialog/tracedialog.cpp:479 +#: ../../po/../src/ui/dialog/tracedialog.cpp:489 +msgid "Preview" +msgstr "Előnézet" + +#. do not expand +#: ../../po/../src/ui/dialog/tracedialog.cpp:483 +msgid "Preview the result without actual tracing" +msgstr "" +"Az eredmény előnézetének megjelenítése a vektorizálás végrehajtása nélkül" + +#. #### swap black and white #### +#: ../../po/../src/ui/dialog/tracedialog.cpp:495 +msgid "Invert" +msgstr "Invertálás" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:499 +msgid "Invert black and white regions for single traces" +msgstr "Fekete-fehér területek invertálása egyszeri vektorizáláshoz" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:503 +msgid "Thanks to Peter Selinger, http://potrace.sourceforge.net" +msgstr "Köszönet Peter Selingernek - http://potrace.sourceforge.net" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:506 +msgid "Credits" +msgstr "Közreműködők" + +#. done +#. TRANSLATORS: Potrace is an application for transforming bitmaps into +#. vector graphics (http://potrace.sourceforge.net/) +#: ../../po/../src/ui/dialog/tracedialog.cpp:514 +msgid "Potrace" +msgstr "Potrace" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:527 +msgid "Abort a trace in progress" +msgstr "Folyamatban levő vektorizálás megszakítása" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:531 +msgid "Execute the trace" +msgstr "A vektorizálás végrehajtása" + +#: ../../po/../src/ui/dialog/transformation.cpp:80 +#: ../../po/../src/ui/dialog/transformation.cpp:90 +#, fuzzy +msgid "_Horizontal" +msgstr "Vízszintes" + +#: ../../po/../src/ui/dialog/transformation.cpp:80 +msgid "Horizontal displacement (relative) or position (absolute)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:82 +#: ../../po/../src/ui/dialog/transformation.cpp:92 +#, fuzzy +msgid "_Vertical" +msgstr "Függőleges" + +#: ../../po/../src/ui/dialog/transformation.cpp:82 +msgid "Vertical displacement (relative) or position (absolute)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:84 +#, fuzzy +msgid "_Width" +msgstr "_Szélesség:" + +#: ../../po/../src/ui/dialog/transformation.cpp:84 +msgid "Horizontal size increment (absolute or percentage)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:86 +#, fuzzy +msgid "_Height" +msgstr "Magasság" + +#: ../../po/../src/ui/dialog/transformation.cpp:86 +msgid "Vertical size increment (absolute or percentage)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:88 +#, fuzzy +msgid "A_ngle" +msgstr "Szög:" + +#: ../../po/../src/ui/dialog/transformation.cpp:88 +#, fuzzy +msgid "Rotation angle (positive = counterclockwise)" +msgstr "" +"A kijelölt objektumok elforgatása az óramutató járásával ellentétes irányban " +"90 fokkal" + +#: ../../po/../src/ui/dialog/transformation.cpp:90 +msgid "" +"Horizontal skew angle (positive = counterclockwise), or absolute " +"displacement, or percentage displacement" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:92 +msgid "" +"Vertical skew angle (positive = counterclockwise), or absolute displacement, " +"or percentage displacement" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:95 +#, fuzzy +msgid "Transformation matrix element A" +msgstr "Transzformációs mátrix" + +#: ../../po/../src/ui/dialog/transformation.cpp:96 +#, fuzzy +msgid "Transformation matrix element B" +msgstr "Transzformációs mátrix" + +#: ../../po/../src/ui/dialog/transformation.cpp:97 +#, fuzzy +msgid "Transformation matrix element C" +msgstr "Transzformációs mátrix" + +#: ../../po/../src/ui/dialog/transformation.cpp:98 +#, fuzzy +msgid "Transformation matrix element D" +msgstr "Transzformációs mátrix" + +#: ../../po/../src/ui/dialog/transformation.cpp:99 +#, fuzzy +msgid "Transformation matrix element E" +msgstr "Transzformációs mátrix" + +#: ../../po/../src/ui/dialog/transformation.cpp:100 +#, fuzzy +msgid "Transformation matrix element F" +msgstr "Transzformációs mátrix" + +#: ../../po/../src/ui/dialog/transformation.cpp:102 +#, fuzzy +msgid "Rela_tive move" +msgstr "Relatív áthelyezés" + +#: ../../po/../src/ui/dialog/transformation.cpp:102 +msgid "" +"Add the specified relative displacement to the current position; otherwise, " +"edit the current absolute position directly" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:103 +msgid "Scale proportionally" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:103 +msgid "Preserve the width/height ratio of the scaled objects" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:104 +msgid "Apply to each _object separately" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:104 +msgid "" +"Apply the scale/rotate/skew to each selected object separately; otherwise, " +"transform the selection as a whole" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:105 +#, fuzzy +msgid "Edit c_urrent matrix" +msgstr "Az aktuális réteg eggyel előrébb való helyezése" + +#: ../../po/../src/ui/dialog/transformation.cpp:105 +msgid "" +"Edit the current transform= matrix; otherwise, post-multiply transform= by " +"this matrix" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:115 +#, fuzzy +msgid "_Move" +msgstr "Áthelyezés" + +#: ../../po/../src/ui/dialog/transformation.cpp:118 +#, fuzzy +msgid "_Scale" +msgstr "Méretezés" + +#: ../../po/../src/ui/dialog/transformation.cpp:121 +#, fuzzy +msgid "_Rotate" +msgstr "Forgatás" + +#: ../../po/../src/ui/dialog/transformation.cpp:124 +#, fuzzy +msgid "Ske_w" +msgstr "Nyírás" + +#: ../../po/../src/ui/dialog/transformation.cpp:127 +msgid "Matri_x" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:141 +msgid "Reset the values on the current tab to defaults" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:148 +#, fuzzy +msgid "Apply transformation to selection" +msgstr "Transzformáció alkalmazása az objektumra" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:43 +msgid "_Use SSL" +msgstr "_SSL használata" + +#. Construct dialog interface +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:68 +msgid "_Server:" +msgstr "_Kiszolgáló:" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:69 +msgid "_Username:" +msgstr "_Felhasználónév:" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:70 +msgid "_Password:" +msgstr "_Jelszó:" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:71 +msgid "P_ort:" +msgstr "_Port:" + +#. Buttons +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:99 +msgid "Connect" +msgstr "Kapcsolódás" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:126 +msgid "Establishing connection to Jabber server %1 as user %2" +msgstr "" +"Kapcsolat létrehozása a(z) \"%1\" Jabber-kiszolgálóhoz \"%2\" " +"felhasználóként" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:131 +msgid "Failed to establish connection to Jabber server %1" +msgstr "Nem sikerült kapcsolódni a(z) \"%1\" Jabber-kiszolgálóhoz" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:136 +msgid "Authentication failed on Jabber server %1 as %2" +msgstr "" +"Nem sikerült az azonosítás a(z) \"%1\" Jabber-kiszolgálón \"%2" +"\" névvel" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:141 +msgid "SSL initialization failed when connecting to Jabber server %1" +msgstr "" +"Az SSL-inicializálás nem sikerült a(z) \"%1\" Jabber-kiszolgálóhoz " +"való kapcsolódáskor" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:147 +msgid "Connected to Jabber server %1 as %2" +msgstr "" +"Kapcsolódva a(z) \"%1\" Jabber-kiszolgálóhoz \"%2\" néven" + +#. Construct labels +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:75 +msgid "Chatroom _name:" +msgstr "A csevegőszoba _neve:" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:76 +msgid "Chatroom _server:" +msgstr "A csevegőszoba kiszo_lgálója:" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:77 +msgid "Chatroom _password:" +msgstr "A csevegőszoba _jelszava:" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:78 +msgid "Chatroom _handle:" +msgstr "A csevegőszoba _azonosítója:" + +#. Button setup and callback registration +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:97 +msgid "Connect to chatroom" +msgstr "Kapcsolódás a csevegőszobához" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:132 +msgid "Synchronizing with chatroom %1@%2 using the handle %3" +msgstr "" +"Szinkronizálás a(z) \"%1@%2\" csevegőszobával a(z) \"%3\" " +"azonosítót használva" + +#. Construct dialog interface +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:78 +msgid "_User's Jabber ID:" +msgstr "A felhasználó Jabber-_azonosítója:" + +#. Buttons +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:82 +msgid "_Invite user" +msgstr "Felhasználó meg_hívása" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:83 +msgid "_Cancel" +msgstr "_Mégsem" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:94 +msgid "Buddy List" +msgstr "Partnerlista" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:170 +msgid "Sending whiteboard invitation to %1" +msgstr "Rajztábla-meghívás küldése \"%1\" felhasználónak" + +#. FIXME: strings are replaced by placeholders, NOT to be translated until the code is enabled +#. See http://sourceforge.net/mailarchive/message.php?msg_id=11746016 for details +#. File menu +#. Edit menu +#. View menu +#. Layer menu +#. Object menu +#. Path menu +#. add(Gtk::StockItem(CLEANUP, _("PLACEHOLDER, do not translate"))); (using Gtk::Stock::CLEAR) +#. Text menu +#. About menu +#. Tools toolbox +#. Select Tool controls +#. Node Tool controls +#. Calligraphy Tool controls +#. Session playback controls +#: ../../po/../src/ui/stock-items.cpp:34 ../../po/../src/ui/stock-items.cpp:35 +#: ../../po/../src/ui/stock-items.cpp:36 ../../po/../src/ui/stock-items.cpp:37 +#: ../../po/../src/ui/stock-items.cpp:38 ../../po/../src/ui/stock-items.cpp:39 +#: ../../po/../src/ui/stock-items.cpp:40 ../../po/../src/ui/stock-items.cpp:41 +#: ../../po/../src/ui/stock-items.cpp:42 ../../po/../src/ui/stock-items.cpp:43 +#: ../../po/../src/ui/stock-items.cpp:46 ../../po/../src/ui/stock-items.cpp:47 +#: ../../po/../src/ui/stock-items.cpp:48 ../../po/../src/ui/stock-items.cpp:49 +#: ../../po/../src/ui/stock-items.cpp:50 ../../po/../src/ui/stock-items.cpp:51 +#: ../../po/../src/ui/stock-items.cpp:52 ../../po/../src/ui/stock-items.cpp:53 +#: ../../po/../src/ui/stock-items.cpp:54 ../../po/../src/ui/stock-items.cpp:55 +#: ../../po/../src/ui/stock-items.cpp:56 ../../po/../src/ui/stock-items.cpp:57 +#: ../../po/../src/ui/stock-items.cpp:58 ../../po/../src/ui/stock-items.cpp:59 +#: ../../po/../src/ui/stock-items.cpp:62 ../../po/../src/ui/stock-items.cpp:63 +#: ../../po/../src/ui/stock-items.cpp:64 ../../po/../src/ui/stock-items.cpp:65 +#: ../../po/../src/ui/stock-items.cpp:66 ../../po/../src/ui/stock-items.cpp:67 +#: ../../po/../src/ui/stock-items.cpp:68 ../../po/../src/ui/stock-items.cpp:69 +#: ../../po/../src/ui/stock-items.cpp:70 ../../po/../src/ui/stock-items.cpp:71 +#: ../../po/../src/ui/stock-items.cpp:72 ../../po/../src/ui/stock-items.cpp:73 +#: ../../po/../src/ui/stock-items.cpp:74 ../../po/../src/ui/stock-items.cpp:75 +#: ../../po/../src/ui/stock-items.cpp:76 ../../po/../src/ui/stock-items.cpp:77 +#: ../../po/../src/ui/stock-items.cpp:78 ../../po/../src/ui/stock-items.cpp:79 +#: ../../po/../src/ui/stock-items.cpp:80 ../../po/../src/ui/stock-items.cpp:81 +#: ../../po/../src/ui/stock-items.cpp:82 ../../po/../src/ui/stock-items.cpp:83 +#: ../../po/../src/ui/stock-items.cpp:84 ../../po/../src/ui/stock-items.cpp:85 +#: ../../po/../src/ui/stock-items.cpp:86 ../../po/../src/ui/stock-items.cpp:87 +#: ../../po/../src/ui/stock-items.cpp:88 ../../po/../src/ui/stock-items.cpp:89 +#: ../../po/../src/ui/stock-items.cpp:92 ../../po/../src/ui/stock-items.cpp:93 +#: ../../po/../src/ui/stock-items.cpp:94 ../../po/../src/ui/stock-items.cpp:95 +#: ../../po/../src/ui/stock-items.cpp:96 ../../po/../src/ui/stock-items.cpp:97 +#: ../../po/../src/ui/stock-items.cpp:98 ../../po/../src/ui/stock-items.cpp:99 +#: ../../po/../src/ui/stock-items.cpp:100 +#: ../../po/../src/ui/stock-items.cpp:101 +#: ../../po/../src/ui/stock-items.cpp:102 +#: ../../po/../src/ui/stock-items.cpp:103 +#: ../../po/../src/ui/stock-items.cpp:104 +#: ../../po/../src/ui/stock-items.cpp:105 +#: ../../po/../src/ui/stock-items.cpp:108 +#: ../../po/../src/ui/stock-items.cpp:109 +#: ../../po/../src/ui/stock-items.cpp:110 +#: ../../po/../src/ui/stock-items.cpp:111 +#: ../../po/../src/ui/stock-items.cpp:112 +#: ../../po/../src/ui/stock-items.cpp:113 +#: ../../po/../src/ui/stock-items.cpp:114 +#: ../../po/../src/ui/stock-items.cpp:115 +#: ../../po/../src/ui/stock-items.cpp:116 +#: ../../po/../src/ui/stock-items.cpp:117 +#: ../../po/../src/ui/stock-items.cpp:118 +#: ../../po/../src/ui/stock-items.cpp:119 +#: ../../po/../src/ui/stock-items.cpp:120 +#: ../../po/../src/ui/stock-items.cpp:121 +#: ../../po/../src/ui/stock-items.cpp:122 +#: ../../po/../src/ui/stock-items.cpp:123 +#: ../../po/../src/ui/stock-items.cpp:124 +#: ../../po/../src/ui/stock-items.cpp:125 +#: ../../po/../src/ui/stock-items.cpp:126 +#: ../../po/../src/ui/stock-items.cpp:127 +#: ../../po/../src/ui/stock-items.cpp:130 +#: ../../po/../src/ui/stock-items.cpp:131 +#: ../../po/../src/ui/stock-items.cpp:132 +#: ../../po/../src/ui/stock-items.cpp:133 +#: ../../po/../src/ui/stock-items.cpp:134 +#: ../../po/../src/ui/stock-items.cpp:135 +#: ../../po/../src/ui/stock-items.cpp:136 +#: ../../po/../src/ui/stock-items.cpp:137 +#: ../../po/../src/ui/stock-items.cpp:138 +#: ../../po/../src/ui/stock-items.cpp:139 +#: ../../po/../src/ui/stock-items.cpp:140 +#: ../../po/../src/ui/stock-items.cpp:141 +#: ../../po/../src/ui/stock-items.cpp:142 +#: ../../po/../src/ui/stock-items.cpp:143 +#: ../../po/../src/ui/stock-items.cpp:144 +#: ../../po/../src/ui/stock-items.cpp:145 +#: ../../po/../src/ui/stock-items.cpp:146 +#: ../../po/../src/ui/stock-items.cpp:150 +#: ../../po/../src/ui/stock-items.cpp:151 +#: ../../po/../src/ui/stock-items.cpp:152 +#: ../../po/../src/ui/stock-items.cpp:153 +#: ../../po/../src/ui/stock-items.cpp:156 +#: ../../po/../src/ui/stock-items.cpp:157 +#: ../../po/../src/ui/stock-items.cpp:158 +#: ../../po/../src/ui/stock-items.cpp:161 +#: ../../po/../src/ui/stock-items.cpp:162 +#: ../../po/../src/ui/stock-items.cpp:163 +#: ../../po/../src/ui/stock-items.cpp:164 +#: ../../po/../src/ui/stock-items.cpp:165 +#: ../../po/../src/ui/stock-items.cpp:166 +#: ../../po/../src/ui/stock-items.cpp:167 +#: ../../po/../src/ui/stock-items.cpp:168 +#: ../../po/../src/ui/stock-items.cpp:169 +#: ../../po/../src/ui/stock-items.cpp:170 +#: ../../po/../src/ui/stock-items.cpp:171 +#: ../../po/../src/ui/stock-items.cpp:172 +#: ../../po/../src/ui/stock-items.cpp:175 +#: ../../po/../src/ui/stock-items.cpp:176 +#: ../../po/../src/ui/stock-items.cpp:177 +#: ../../po/../src/ui/stock-items.cpp:178 +#: ../../po/../src/ui/stock-items.cpp:181 +#: ../../po/../src/ui/stock-items.cpp:182 +#: ../../po/../src/ui/stock-items.cpp:183 +#: ../../po/../src/ui/stock-items.cpp:184 +#: ../../po/../src/ui/stock-items.cpp:185 +#: ../../po/../src/ui/stock-items.cpp:186 +#: ../../po/../src/ui/stock-items.cpp:187 +#: ../../po/../src/ui/stock-items.cpp:188 +#: ../../po/../src/ui/stock-items.cpp:189 +#: ../../po/../src/ui/stock-items.cpp:190 +#: ../../po/../src/ui/stock-items.cpp:191 +#: ../../po/../src/ui/stock-items.cpp:194 +#: ../../po/../src/ui/stock-items.cpp:195 +#: ../../po/../src/ui/stock-items.cpp:198 +#: ../../po/../src/ui/stock-items.cpp:199 +#: ../../po/../src/ui/stock-items.cpp:200 +#: ../../po/../src/ui/stock-items.cpp:201 +#: ../../po/../src/ui/stock-items.cpp:202 +msgid "PLACEHOLDER, do not translate" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:88 +msgid "small" +msgstr "kicsi" + +#: ../../po/../src/ui/widget/panel.cpp:89 +msgid "medium" +msgstr "közepes" + +#: ../../po/../src/ui/widget/panel.cpp:90 +msgid "large" +msgstr "nagy" + +#: ../../po/../src/ui/widget/panel.cpp:91 +msgid "huge" +msgstr "nagyon nagy" + +#: ../../po/../src/ui/widget/panel.cpp:106 +msgid "List" +msgstr "Lista" + +#: ../../po/../src/ui/widget/selected-style.cpp:67 +msgid "F:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:68 +msgid "S:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:69 +msgid "O:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:95 +msgid "N/A" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:98 +#: ../../po/../src/ui/widget/selected-style.cpp:712 +#, fuzzy +msgid "Nothing selected" +msgstr "Nincs kijelölve színátmenet" + +#: ../../po/../src/ui/widget/selected-style.cpp:103 +msgid "No fill" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:103 +#, fuzzy +msgid "No stroke" +msgstr " (körvonal)" + +#: ../../po/../src/ui/widget/selected-style.cpp:105 +#: ../../po/../src/widgets/paint-selector.cpp:190 +msgid "Pattern" +msgstr "Minta" + +#: ../../po/../src/ui/widget/selected-style.cpp:108 +#: ../../po/../src/widgets/paint-selector.cpp:885 +msgid "Pattern fill" +msgstr "Mintával való kitöltés" + +#: ../../po/../src/ui/widget/selected-style.cpp:108 +#, fuzzy +msgid "Pattern stroke" +msgstr "A minta eltolása" + +#: ../../po/../src/ui/widget/selected-style.cpp:110 +#, fuzzy +msgid "L Gradient" +msgstr "Színátmenet" + +#: ../../po/../src/ui/widget/selected-style.cpp:113 +#, fuzzy +msgid "Linear gradient fill" +msgstr "Lineáris színátmenet" + +#: ../../po/../src/ui/widget/selected-style.cpp:113 +#, fuzzy +msgid "Linear gradient stroke" +msgstr "Lineáris színátmenet" + +#: ../../po/../src/ui/widget/selected-style.cpp:115 +#, fuzzy +msgid "R Gradient" +msgstr "Színátmenet" + +#: ../../po/../src/ui/widget/selected-style.cpp:118 +#, fuzzy +msgid "Radial gradient fill" +msgstr "Sugárirányú színátmenet" + +#: ../../po/../src/ui/widget/selected-style.cpp:118 +#, fuzzy +msgid "Radial gradient stroke" +msgstr "Sugárirányú színátmenet" + +#: ../../po/../src/ui/widget/selected-style.cpp:120 +#, fuzzy +msgid "Different" +msgstr "_Különbség" + +#: ../../po/../src/ui/widget/selected-style.cpp:123 +#, fuzzy +msgid "Different fills" +msgstr "_Különbség" + +#: ../../po/../src/ui/widget/selected-style.cpp:123 +#, fuzzy +msgid "Different strokes" +msgstr "_Különbség" + +#: ../../po/../src/ui/widget/selected-style.cpp:125 +#, fuzzy +msgid "Unset" +msgstr "zsugorítva" + +#. TRANSLATORS COMMENT: unset is a verb here +#: ../../po/../src/ui/widget/selected-style.cpp:128 +#: ../../po/../src/ui/widget/selected-style.cpp:182 +msgid "Unset fill" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:128 +#: ../../po/../src/ui/widget/selected-style.cpp:182 +#, fuzzy +msgid "Unset stroke" +msgstr " (körvonal)" + +#: ../../po/../src/ui/widget/selected-style.cpp:131 +#, fuzzy +msgid "Flat color fill" +msgstr "Egyenletes szín" + +#: ../../po/../src/ui/widget/selected-style.cpp:131 +#, fuzzy +msgid "Flat color stroke" +msgstr "Egyenletes szín" + +#. TRANSLATOR COMMENT: A means "Averaged" +#: ../../po/../src/ui/widget/selected-style.cpp:134 +#, fuzzy +msgid "A" +msgstr "_A" + +#: ../../po/../src/ui/widget/selected-style.cpp:137 +#, fuzzy +msgid "Fill is averaged over selected objects" +msgstr "Kizáró VAGY végrehajtása a kijelölt objektumokon" + +#: ../../po/../src/ui/widget/selected-style.cpp:137 +#, fuzzy +msgid "Stroke is averaged over selected objects" +msgstr "A kapcsok kerüljék ki a kijelölt objektumokat" + +#. TRANSLATOR COMMENT: M means "Multiple" +#: ../../po/../src/ui/widget/selected-style.cpp:140 +#, fuzzy +msgid "M" +msgstr "_B" + +#: ../../po/../src/ui/widget/selected-style.cpp:143 +#, fuzzy +msgid "Multiple selected objects have the same fill" +msgstr "A kijelölt objektumok függőleges tükrözése" + +#: ../../po/../src/ui/widget/selected-style.cpp:143 +#, fuzzy +msgid "Multiple selected objects have the same stroke" +msgstr "A kijelölt objektumok függőleges tükrözése" + +#: ../../po/../src/ui/widget/selected-style.cpp:145 +#, fuzzy +msgid "Edit fill..." +msgstr "Szerkesztés..." + +#: ../../po/../src/ui/widget/selected-style.cpp:145 +#, fuzzy +msgid "Edit stroke..." +msgstr "Szerkesztés..." + +#: ../../po/../src/ui/widget/selected-style.cpp:149 +#, fuzzy +msgid "Last set color" +msgstr "Egyenletes szín" + +#: ../../po/../src/ui/widget/selected-style.cpp:153 +#, fuzzy +msgid "Last selected color" +msgstr "Legutóbb kijelölt" + +#: ../../po/../src/ui/widget/selected-style.cpp:157 +#, fuzzy +msgid "White" +msgstr "R_ajztábla" + +#: ../../po/../src/ui/widget/selected-style.cpp:161 +#: ../../po/../src/widgets/sp-color-scales.cpp:461 +#: ../../po/../src/widgets/sp-color-scales.cpp:462 +msgid "Black" +msgstr "Fekete" + +#: ../../po/../src/ui/widget/selected-style.cpp:165 +#, fuzzy +msgid "Copy color" +msgstr "Fázis színe" + +#: ../../po/../src/ui/widget/selected-style.cpp:169 +#, fuzzy +msgid "Paste color" +msgstr "Egyenletes szín" + +#: ../../po/../src/ui/widget/selected-style.cpp:173 +#, fuzzy +msgid "Swap fill and stroke" +msgstr "Kitö_ltés és körvonal" + +#: ../../po/../src/ui/widget/selected-style.cpp:177 +msgid "Make fill opaque" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:177 +msgid "Make stroke opaque" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:186 +#, fuzzy +msgid "Remove fill" +msgstr " _Törlés " + +#: ../../po/../src/ui/widget/selected-style.cpp:186 +#, fuzzy +msgid "Remove stroke" +msgstr "Hivatkozás törlé_se" + +#: ../../po/../src/ui/widget/selected-style.cpp:718 +#, fuzzy +msgid "Master opacity" +msgstr "Ala_p-átlátszatlanság" + +#: ../../po/../src/ui/widget/selected-style.cpp:744 +msgid "0 (transparent)" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:768 +msgid "1.0 (opaque)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1046 +msgid "Moved to next layer." +msgstr "A következő rétegre való ugrás megtörtént." + +#: ../../po/../src/verbs.cpp:1048 +msgid "Cannot move past last layer." +msgstr "Az utolsó rétegnél tovább nem lehet ugrani." + +#: ../../po/../src/verbs.cpp:1057 +msgid "Moved to previous layer." +msgstr "Az előző rétegre való ugrás megtörtént." + +#: ../../po/../src/verbs.cpp:1059 +msgid "Cannot move past first layer." +msgstr "Az első rétegnél tovább nem lehet ugrani." + +#: ../../po/../src/verbs.cpp:1076 ../../po/../src/verbs.cpp:1150 +msgid "No current layer." +msgstr "Nincs aktuális réteg." + +#: ../../po/../src/verbs.cpp:1105 +#, c-format +msgid "Raised layer %s." +msgstr "A(z) \"%s\" réteg előrébb lett helyezve." + +#: ../../po/../src/verbs.cpp:1109 +#, c-format +msgid "Lowered layer %s." +msgstr "A(z) \"%s\" réteg hátrébb lett helyezve." + +#: ../../po/../src/verbs.cpp:1118 +msgid "Cannot move layer any further." +msgstr "A réteg nem mozdítható tovább." + +#. TRANSLATORS: this means "The layer has been deleted." +#: ../../po/../src/verbs.cpp:1148 +msgid "Deleted layer." +msgstr "A réteg törölve." + +#: ../../po/../src/verbs.cpp:1544 +msgid "" +"You need to connect to a Jabber server before sharing a document with " +"another user." +msgstr "" +"Kapcsolódni kell egy Jabber-kiszolgálóhoz, mielőtt dokumentumot osztana meg " +"egy felhasználóval." + +#: ../../po/../src/verbs.cpp:1559 +msgid "" +"You need to connect to a Jabber server before sharing a document with a " +"chatroom." +msgstr "" +"Kapcsolódni kell egy Jabber-kiszolgálóhoz, mielőtt dokumentumot osztana meg " +"egy csevegőszobával." + +#: ../../po/../src/verbs.cpp:1569 +msgid "XML node tracker has not been initialized; nothing to dump" +msgstr "" +"Az XML-csomópontok nyomkövetője nem lett inicializálva; nincs kiírandó adat." + +#. TRANSLATORS: If you have translated the keys.svg file to your language, then +#. translate this string as "keys.LANG.svg" (where LANG is your language code); +#. otherwise leave as "keys.svg". +#: ../../po/../src/verbs.cpp:1631 +msgid "keys.svg" +msgstr "keys.svg" + +#. TRANSLATORS: If you have translated the tutorial-basic.svg file to your language, +#. then translate this string as "tutorial-basic.LANG.svg" (where LANG is your language +#. code); otherwise leave as "tutorial-basic.svg". +#: ../../po/../src/verbs.cpp:1667 +msgid "tutorial-basic.svg" +msgstr "tutorial-basic.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1671 +msgid "tutorial-shapes.svg" +msgstr "tutorial-shapes.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1675 +msgid "tutorial-advanced.svg" +msgstr "tutorial-advanced.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1679 +msgid "tutorial-tracing.svg" +msgstr "tutorial-tracing.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1683 +msgid "tutorial-calligraphy.svg" +msgstr "tutorial-calligraphy.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1687 +msgid "tutorial-elements.svg" +msgstr "tutorial-elements.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1691 +msgid "tutorial-tips.svg" +msgstr "tutorial-tips.svg" + +#: ../../po/../src/verbs.cpp:1842 +msgid "Does nothing" +msgstr "Nincs funkció" + +#. File +#: ../../po/../src/verbs.cpp:1845 +msgid "Default" +msgstr "Alapértelmezett" + +#: ../../po/../src/verbs.cpp:1845 +msgid "Create new document from default template" +msgstr "Új dokumentum létrehozása az alapértelmezett sablonból" + +#: ../../po/../src/verbs.cpp:1847 +msgid "_Open..." +msgstr "_Megnyitás..." + +#: ../../po/../src/verbs.cpp:1848 +msgid "Open existing document" +msgstr "Létező dokumentum megnyitása" + +#: ../../po/../src/verbs.cpp:1849 +msgid "Re_vert" +msgstr "_Visszaállítás" + +#: ../../po/../src/verbs.cpp:1850 +msgid "Revert to the last saved version of document (changes will be lost)" +msgstr "" +"Visszatérés a dokumentum legutóbb mentett változatához (a módosítások " +"elvesznek)" + +#: ../../po/../src/verbs.cpp:1851 +msgid "_Save" +msgstr "M_entés" + +#: ../../po/../src/verbs.cpp:1851 +msgid "Save document" +msgstr "Dokumentum mentése" + +#: ../../po/../src/verbs.cpp:1853 +msgid "Save _As..." +msgstr "Mentés más_ként..." + +#: ../../po/../src/verbs.cpp:1854 +msgid "Save document under new name" +msgstr "Dokumentum mentése új névvel" + +#: ../../po/../src/verbs.cpp:1855 +msgid "_Print..." +msgstr "_Nyomtatás..." + +#: ../../po/../src/verbs.cpp:1855 +msgid "Print document" +msgstr "Dokumentum nyomtatása" + +#. TRANSLATORS: "Vacuum Defs" means "Clean up defs" (so as to remove unused definitions) +#: ../../po/../src/verbs.cpp:1858 +msgid "Vac_uum Defs" +msgstr "_Takarítás a definíciók közt" + +#: ../../po/../src/verbs.cpp:1858 +msgid "Remove unused predefined items from the <defs> of the document" +msgstr "" +"A nem használt előredefiniált elemek eltávolítása a dokumentum <defs> " +"elemeiből" + +#: ../../po/../src/verbs.cpp:1860 +msgid "Print _Direct" +msgstr "Köz_vetlen nyomtatás" + +#: ../../po/../src/verbs.cpp:1861 +msgid "Print directly without prompting to a file or pipe" +msgstr "" +"Nyomtatás közvetlenül (megerősítés-kérés nélkül) fájlba vagy egy program " +"felé (csővezetékbe)" + +#: ../../po/../src/verbs.cpp:1862 +msgid "Print Previe_w" +msgstr "N_yomtatási kép" + +#: ../../po/../src/verbs.cpp:1863 +msgid "Preview document printout" +msgstr "A dokumentum nyomtatási képének megjelenítése" + +#: ../../po/../src/verbs.cpp:1864 +msgid "_Import..." +msgstr "_Importálás..." + +#: ../../po/../src/verbs.cpp:1865 +msgid "Import bitmap or SVG image into document" +msgstr "Bitkép vagy SVG-kép importálása a dokumentumba" + +#: ../../po/../src/verbs.cpp:1866 +msgid "_Export Bitmap..." +msgstr "E_xportálás bitképbe..." + +#: ../../po/../src/verbs.cpp:1867 +msgid "Export document or selection as a bitmap image" +msgstr "A dokumentum vagy a kijelölés exportálása bitképbe" + +#: ../../po/../src/verbs.cpp:1868 +msgid "N_ext Window" +msgstr "Követke_ző ablak" + +#: ../../po/../src/verbs.cpp:1869 +msgid "Switch to the next document window" +msgstr "Váltás a következő dokumentum ablakára" + +#: ../../po/../src/verbs.cpp:1870 +msgid "P_revious Window" +msgstr "Előző _ablak" + +#: ../../po/../src/verbs.cpp:1871 +msgid "Switch to the previous document window" +msgstr "Váltás az előző dokumentum ablakára" + +#: ../../po/../src/verbs.cpp:1872 +msgid "_Close" +msgstr "_Bezárás" + +#: ../../po/../src/verbs.cpp:1873 +msgid "Close window" +msgstr "Ablak bezárása" + +#: ../../po/../src/verbs.cpp:1874 +msgid "_Quit" +msgstr "Ki_lépés" + +#: ../../po/../src/verbs.cpp:1874 +msgid "Quit Inkscape" +msgstr "Kilépés az Inkscape-ből" + +#. Edit +#: ../../po/../src/verbs.cpp:1877 +msgid "_Undo" +msgstr "_Visszavonás" + +#: ../../po/../src/verbs.cpp:1877 +msgid "Undo last action" +msgstr "A legutóbbi művelet visszavonása" + +#: ../../po/../src/verbs.cpp:1879 +msgid "_Redo" +msgstr "Új_ra végrehajtás" + +#: ../../po/../src/verbs.cpp:1880 +msgid "Do again last undone action" +msgstr "A legutóbbi visszavont művelet ismételt végrehajtása" + +#: ../../po/../src/verbs.cpp:1881 +msgid "Cu_t" +msgstr "_Kivágás" + +#: ../../po/../src/verbs.cpp:1882 +msgid "Cut selection to clipboard" +msgstr "A kijelölés áthelyezése a vágólapra" + +#: ../../po/../src/verbs.cpp:1883 +msgid "_Copy" +msgstr "_Másolás" + +#: ../../po/../src/verbs.cpp:1884 +msgid "Copy selection to clipboard" +msgstr "A kijelölés másolása a vágólapra" + +#: ../../po/../src/verbs.cpp:1885 +msgid "_Paste" +msgstr "_Beillesztés" + +#: ../../po/../src/verbs.cpp:1886 +msgid "Paste objects from clipboard to mouse point" +msgstr "Objektumok beillesztése a vágólapról az egér pozíciójához" + +#: ../../po/../src/verbs.cpp:1887 +msgid "Paste _Style" +msgstr "_Stílus beillesztése" + +#: ../../po/../src/verbs.cpp:1888 +msgid "Apply style of the copied object to selection" +msgstr "A kimásolt objektum stílusának alkalmazása a kijelölésre" + +#: ../../po/../src/verbs.cpp:1889 +msgid "Paste _In Place" +msgstr "Beillesztés a megfelelő _helyre" + +#: ../../po/../src/verbs.cpp:1890 +msgid "Paste objects from clipboard to the original location" +msgstr "Objektumok beillesztése a vágólapról azok eredeti helyére" + +#: ../../po/../src/verbs.cpp:1891 +msgid "_Delete" +msgstr "_Törlés" + +#: ../../po/../src/verbs.cpp:1892 +msgid "Delete selection" +msgstr "A kijelölés törlése" + +#: ../../po/../src/verbs.cpp:1893 +msgid "Duplic_ate" +msgstr "Kettő_zés" + +#: ../../po/../src/verbs.cpp:1894 +msgid "Duplicate selected objects" +msgstr "A kijelölt objektumok kettőzése" + +#: ../../po/../src/verbs.cpp:1895 +msgid "Clo_ne" +msgstr "Klón_ozás" + +#: ../../po/../src/verbs.cpp:1896 +msgid "Create a clone of selected object (a copy linked to the original)" +msgstr "" +"Klón (az eredetihez kapcsolt másolat) létrehozása a kijelölt objektumból" + +#: ../../po/../src/verbs.cpp:1897 +msgid "Unlin_k Clone" +msgstr "Klón _lekapcsolása" + +#: ../../po/../src/verbs.cpp:1898 +msgid "Cut the clone's link to its original" +msgstr "A klónnak az eredeti objektummal való kapcsolatának megszüntetése" + +#: ../../po/../src/verbs.cpp:1899 +msgid "Select _Original" +msgstr "Eredet_i kijelölése" + +#: ../../po/../src/verbs.cpp:1900 +msgid "Select the object to which the clone is linked" +msgstr "Azon objektum kijelölése, amelyhez a klón kapcsolva van" + +#. TRANSLATORS: Convert selection to a rectangle with tiled pattern fill +#: ../../po/../src/verbs.cpp:1902 +msgid "O_bjects to Pattern" +msgstr "Objekt_umok átalakítása mintává" + +#: ../../po/../src/verbs.cpp:1903 +msgid "Convert selection to a rectangle with tiled pattern fill" +msgstr "A kijelölés átalakítása csempézett téglalappá" + +#. TRANSLATORS: Extract objects from a tiled pattern fill +#: ../../po/../src/verbs.cpp:1905 +msgid "Pattern to Ob_jects" +msgstr "Mint_a átalakítása objektumokká" + +#: ../../po/../src/verbs.cpp:1906 +msgid "Extract objects from a tiled pattern fill" +msgstr "Objektumok kinyerése egy csempézett mintából" + +#: ../../po/../src/verbs.cpp:1907 +msgid "Clea_r All" +msgstr "Minden objektum tör_lése" + +#: ../../po/../src/verbs.cpp:1908 +msgid "Delete all objects from document" +msgstr "A dokumentumban levő összes objektum törlése" + +#: ../../po/../src/verbs.cpp:1909 +msgid "Select Al_l" +msgstr "Min_den kijelölése" + +#: ../../po/../src/verbs.cpp:1910 +msgid "Select all objects or all nodes" +msgstr "Az összes objektum vagy az összes csomópont kijelölése" + +#: ../../po/../src/verbs.cpp:1911 +msgid "Select All in All La_yers" +msgstr "Minden kijelölése az összes réte_gben" + +#: ../../po/../src/verbs.cpp:1912 +msgid "Select all objects in all visible and unlocked layers" +msgstr "Az összes objektum kijelölése az összes látható és zárolatlan rétegben" + +#: ../../po/../src/verbs.cpp:1913 +msgid "In_vert Selection" +msgstr "Ki_jelölés invertálása" + +#: ../../po/../src/verbs.cpp:1914 +msgid "Invert selection (unselect what is selected and select everything else)" +msgstr "" +"A kijelölés megfordítása (a kijelölt objektumok kijelöletlenné tétele és az " +"összes többi kijelölése)" + +#: ../../po/../src/verbs.cpp:1915 +msgid "Invert in All Layers" +msgstr "Invertálás az összes rétegben" + +#: ../../po/../src/verbs.cpp:1916 +msgid "Invert selection in all visible and unlocked layers" +msgstr "A kijelölés megfordítása az összes látható és zárolatlan rétegben" + +#: ../../po/../src/verbs.cpp:1917 +msgid "D_eselect" +msgstr "Kijelölés megszü_ntetése" + +#: ../../po/../src/verbs.cpp:1918 +msgid "Deselect any selected objects or nodes" +msgstr "Az objektumok vagy csomópontok kijelölésének megszüntetése" + +#. Selection +#: ../../po/../src/verbs.cpp:1921 +msgid "Raise to _Top" +msgstr "_Elölre helyezés" + +#: ../../po/../src/verbs.cpp:1922 +msgid "Raise selection to top" +msgstr "A kijelölt objektumok áthelyezése a többi elé" + +#: ../../po/../src/verbs.cpp:1923 +msgid "Lower to _Bottom" +msgstr "_Hátulra helyezés" + +#: ../../po/../src/verbs.cpp:1924 +msgid "Lower selection to bottom" +msgstr "A kijelölt objektumok áthelyezése a többi mögé" + +#: ../../po/../src/verbs.cpp:1925 +msgid "_Raise" +msgstr "E_lőrébb helyezés" + +#: ../../po/../src/verbs.cpp:1926 +msgid "Raise selection one step" +msgstr "A kijelölt objektumok eggyel előrébb való helyezése" + +#: ../../po/../src/verbs.cpp:1927 +msgid "_Lower" +msgstr "Há_trébb helyezés" + +#: ../../po/../src/verbs.cpp:1928 +msgid "Lower selection one step" +msgstr "A kijelölt objektumok eggyel hátrébb való helyezése" + +#: ../../po/../src/verbs.cpp:1929 +msgid "_Group" +msgstr "_Csoportosítás" + +#: ../../po/../src/verbs.cpp:1930 +msgid "Group selected objects" +msgstr "A kijelölt objektumok csoportba foglalása" + +#: ../../po/../src/verbs.cpp:1932 +msgid "Ungroup selected groups" +msgstr "A kijelölt csoportok szétbontása" + +#: ../../po/../src/verbs.cpp:1934 +msgid "_Put on Path" +msgstr "Láncra való _illesztés" + +#: ../../po/../src/verbs.cpp:1935 +msgid "Put text on path" +msgstr "Szöveg illesztése láncra" + +#: ../../po/../src/verbs.cpp:1936 +msgid "_Remove from Path" +msgstr "Láncról való _eltávolítás" + +#: ../../po/../src/verbs.cpp:1937 +msgid "Remove text from path" +msgstr "Szöveg eltávolítása láncról" + +#: ../../po/../src/verbs.cpp:1938 +msgid "Remove Manual _Kerns" +msgstr "Kézi _alávágások eltávolítása" + +#. TRANSLATORS: "glyph": An image used in the visual representation of characters; +#. roughly speaking, how a character looks. A font is a set of glyphs. +#: ../../po/../src/verbs.cpp:1941 +msgid "Remove all manual kerns and glyph rotations from a text object" +msgstr "" +"Az összes kézi alávágás és karakter-elforgatás eltávolítása egy " +"szövegobjektumból" + +#: ../../po/../src/verbs.cpp:1943 +msgid "_Union" +msgstr "_Unió" + +#: ../../po/../src/verbs.cpp:1944 +msgid "Union of selected objects" +msgstr "A kijelölt objektumok uniója" + +#: ../../po/../src/verbs.cpp:1945 +msgid "_Intersection" +msgstr "_Metszet" + +#: ../../po/../src/verbs.cpp:1946 +msgid "Intersection of selected objects" +msgstr "A kijelölt objektumok metszete" + +#: ../../po/../src/verbs.cpp:1947 +msgid "_Difference" +msgstr "_Különbség" + +#: ../../po/../src/verbs.cpp:1948 +msgid "Difference of selected objects (bottom minus top)" +msgstr "A kijelölt objektumok különbsége (hátulsó mínusz elülső)" + +#: ../../po/../src/verbs.cpp:1949 +msgid "E_xclusion" +msgstr "Ki_zárás" + +#: ../../po/../src/verbs.cpp:1950 +msgid "Exclusive OR of selected objects" +msgstr "Kizáró VAGY végrehajtása a kijelölt objektumokon" + +#: ../../po/../src/verbs.cpp:1951 +msgid "Di_vision" +msgstr "_Felosztás" + +#: ../../po/../src/verbs.cpp:1952 +msgid "Cut the bottom object into pieces" +msgstr "A hátulsó objektum feldarabolása" + +#. TRANSLATORS: "to cut a path" is not the same as "to break a path apart" - see the +#. Advanced tutorial for more info +#: ../../po/../src/verbs.cpp:1955 +msgid "Cut _Path" +msgstr "Lánc el_vágása" + +#: ../../po/../src/verbs.cpp:1956 +msgid "Cut the bottom object's stroke into pieces, removing fill" +msgstr "" +"A hátulsó objektum körvonalának feldarabolása a kitöltés eltávolításával" + +#. TRANSLATORS: "outset": expand a shape by offsetting the object's path, +#. i.e. by displacing it perpendicular to the path in each point. +#. See also the Advanced Tutorial for explanation. +#: ../../po/../src/verbs.cpp:1960 +msgid "Outs_et" +msgstr "_Nyújtás" + +#: ../../po/../src/verbs.cpp:1961 +msgid "Outset selected paths" +msgstr "A kijelölt láncok nyújtása" + +#: ../../po/../src/verbs.cpp:1963 +msgid "O_utset Path by 1 px" +msgstr "Lánc _nyújtása 1 px mérettel" + +#: ../../po/../src/verbs.cpp:1964 +msgid "Outset selected paths by 1 px" +msgstr "A kijelölt láncok nyújtása 1 px mérettel" + +#: ../../po/../src/verbs.cpp:1966 +msgid "O_utset Path by 10 px" +msgstr "Lánc _nyújtása 10 px mérettel" + +#: ../../po/../src/verbs.cpp:1967 +msgid "Outset selected paths by 10 px" +msgstr "A kijelölt láncok nyújtása 10 px mérettel" + +#. TRANSLATORS: "inset": contract a shape by offsetting the object's path, +#. i.e. by displacing it perpendicular to the path in each point. +#. See also the Advanced Tutorial for explanation. +#: ../../po/../src/verbs.cpp:1971 +msgid "I_nset" +msgstr "Zsu_gorítás" + +#: ../../po/../src/verbs.cpp:1972 +msgid "Inset selected paths" +msgstr "A kijelölt láncok zsugorítása" + +#: ../../po/../src/verbs.cpp:1974 +msgid "I_nset Path by 1 px" +msgstr "Lánc zsu_gorítása 1 px mérettel" + +#: ../../po/../src/verbs.cpp:1975 +msgid "Inset selected paths by 1 px" +msgstr "A kijelölt láncok zsugorítása 1 px mérettel" + +#: ../../po/../src/verbs.cpp:1977 +msgid "I_nset Path by 10 px" +msgstr "Lánc zsu_gorítása 10 px mérettel" + +#: ../../po/../src/verbs.cpp:1978 +msgid "Inset selected paths by 10 px" +msgstr "A kijelölt láncok zsugorítása 10 px mérettel" + +#: ../../po/../src/verbs.cpp:1980 +msgid "D_ynamic Offset" +msgstr "_Dinamikus perem" + +#: ../../po/../src/verbs.cpp:1980 +msgid "Create a dynamic offset object" +msgstr "Dinamikus peremobjektum létrehozása" + +#: ../../po/../src/verbs.cpp:1982 +msgid "_Linked Offset" +msgstr "Kap_csolt perem" + +#: ../../po/../src/verbs.cpp:1983 +msgid "Create a dynamic offset object linked to the original path" +msgstr "Dinamikus peremobjektum létrehozása az eredeti lánchoz kapcsolva" + +#: ../../po/../src/verbs.cpp:1985 +msgid "_Stroke to Path" +msgstr "Körvonal át_alakítása lánccá" + +#: ../../po/../src/verbs.cpp:1986 +msgid "Convert selected strokes to paths" +msgstr "A kijelölt körvonalak láncokká alakítása" + +#: ../../po/../src/verbs.cpp:1987 +msgid "Si_mplify" +msgstr "_Egyszerűsítés" + +#: ../../po/../src/verbs.cpp:1988 +msgid "Simplify selected paths by removing extra nodes" +msgstr "A kijelölt láncok egyszerűsítése az extra csomópontok eltávolításával" + +#: ../../po/../src/verbs.cpp:1989 +msgid "_Reverse" +msgstr "Megfo_rdítás" + +#: ../../po/../src/verbs.cpp:1990 +msgid "Reverses the direction of selected paths; useful for flipping markers" +msgstr "" +"A kijelölt láncok irányának megfordítása. Hasznos lehet például a " +"jelölőelemek megfordításához." + +#. TRANSLATORS: "to trace" means "to convert a bitmap to vector graphics" (to vectorize) +#: ../../po/../src/verbs.cpp:1992 +msgid "_Trace Bitmap" +msgstr "Bitkép vektor_izálása" + +#: ../../po/../src/verbs.cpp:1993 +msgid "Convert bitmap object to paths" +msgstr "Bitkép-objektum átalakítása láncokká" + +#: ../../po/../src/verbs.cpp:1994 +msgid "_Make a Bitmap Copy" +msgstr "Bitké_p-másolat készítése" + +#: ../../po/../src/verbs.cpp:1995 +msgid "Export selection to a bitmap and insert it into document" +msgstr "A kijelölés exportálása bitképbe, majd beillesztése a dokumentumba" + +#: ../../po/../src/verbs.cpp:1996 +msgid "_Combine" +msgstr "Összev_onás" + +#: ../../po/../src/verbs.cpp:1997 +msgid "Combine several paths into one" +msgstr "Több lánc összevonása eggyé" + +# node-ok és szakaszok száma nem változik +#. TRANSLATORS: "to cut a path" is not the same as "to break a path apart" - see the +#. Advanced tutorial for more info +#: ../../po/../src/verbs.cpp:2000 +msgid "Break _Apart" +msgstr "_Szétbontás" + +#: ../../po/../src/verbs.cpp:2001 +msgid "Break selected paths into subpaths" +msgstr "A kijelölt láncok alláncokra való bontása" + +#: ../../po/../src/verbs.cpp:2002 +msgid "Gri_d Arrange..." +msgstr "Rácsra való i_gazítás..." + +#: ../../po/../src/verbs.cpp:2003 +msgid "Arrange selection in grid pattern" +msgstr "A kijelölt objektumok elrendezése rács alakzatban" + +#. Layer +#: ../../po/../src/verbs.cpp:2005 +msgid "_Add Layer..." +msgstr "Réteg _felvétele..." + +#: ../../po/../src/verbs.cpp:2006 +msgid "Create a new layer" +msgstr "Új réteg létrehozása" + +#: ../../po/../src/verbs.cpp:2007 +msgid "Re_name Layer..." +msgstr "Réteg át_nevezése..." + +#: ../../po/../src/verbs.cpp:2008 +msgid "Rename the current layer" +msgstr "Az aktuális réteg átnevezése" + +#: ../../po/../src/verbs.cpp:2009 +msgid "Switch to Layer Abov_e" +msgstr "_Váltás az előrébb levő rétegre" + +#: ../../po/../src/verbs.cpp:2010 +msgid "Switch to the layer above the current" +msgstr "Váltás az aktuális réteg feletti rétegre" + +#: ../../po/../src/verbs.cpp:2011 +msgid "Switch to Layer Belo_w" +msgstr "Váltá_s a hátrébb levő rétegre" + +#: ../../po/../src/verbs.cpp:2012 +msgid "Switch to the layer below the current" +msgstr "Váltás az aktuális réteg alatti rétegre" + +#: ../../po/../src/verbs.cpp:2013 +msgid "Move Selection to Layer Abo_ve" +msgstr "_Kijelölés áthelyezése az előrébb levő rétegbe" + +#: ../../po/../src/verbs.cpp:2014 +msgid "Move selection to the layer above the current" +msgstr "A kijelölés áthelyezése az aktuális réteg feletti rétegbe" + +#: ../../po/../src/verbs.cpp:2015 +msgid "Move Selection to Layer Bel_ow" +msgstr "K_ijelölés áthelyezése a hátrébb levő rétegbe" + +#: ../../po/../src/verbs.cpp:2016 +msgid "Move selection to the layer below the current" +msgstr "A kijelölés áthelyezése az aktuális réteg alatti rétegbe" + +#: ../../po/../src/verbs.cpp:2017 +msgid "Layer to _Top" +msgstr "Réteg _elölre helyezése" + +#: ../../po/../src/verbs.cpp:2018 +msgid "Raise the current layer to the top" +msgstr "Az aktuális réteg áthelyezése a többi elé" + +#: ../../po/../src/verbs.cpp:2019 +msgid "Layer to _Bottom" +msgstr "Réteg _hátulra helyezése" + +#: ../../po/../src/verbs.cpp:2020 +msgid "Lower the current layer to the bottom" +msgstr "Az aktuális réteg áthelyezése a többi mögé" + +#: ../../po/../src/verbs.cpp:2021 +msgid "_Raise Layer" +msgstr "Réteg e_lőrébb helyezése" + +#: ../../po/../src/verbs.cpp:2022 +msgid "Raise the current layer" +msgstr "Az aktuális réteg eggyel előrébb való helyezése" + +#: ../../po/../src/verbs.cpp:2023 +msgid "_Lower Layer" +msgstr "Réteg há_trébb helyezése" + +#: ../../po/../src/verbs.cpp:2024 +msgid "Lower the current layer" +msgstr "Az aktuális réteg eggyel hátrébb való helyezése" + +#: ../../po/../src/verbs.cpp:2025 +msgid "_Delete Current Layer" +msgstr "Aktuális réteg tö_rlése" + +#: ../../po/../src/verbs.cpp:2026 +msgid "Delete the current layer" +msgstr "Az aktuális réteg törlése" + +#. Object +#: ../../po/../src/verbs.cpp:2029 +#, fuzzy +msgid "Rotate _90° CW" +msgstr "Elfo_rgatás -90 fokkal" + +#: ../../po/../src/verbs.cpp:2030 +#, fuzzy +msgid "Rotate selection 90° clockwise" +msgstr "" +"A kijelölt objektumok elforgatása az óramutató járásának irányában 90 fokkal" + +#: ../../po/../src/verbs.cpp:2031 +#, fuzzy +msgid "Rotate 9_0° CCW" +msgstr "Elforgatás +_90 fokkal" + +#: ../../po/../src/verbs.cpp:2032 +#, fuzzy +msgid "Rotate selection 90° counter-clockwise" +msgstr "" +"A kijelölt objektumok elforgatása az óramutató járásával ellentétes irányban " +"90 fokkal" + +#: ../../po/../src/verbs.cpp:2033 +msgid "Remove _Transformations" +msgstr "Transzformációk visszavo_nása" + +#: ../../po/../src/verbs.cpp:2034 +msgid "Remove transformations from object" +msgstr "Az objektum transzformációjának megszüntetése" + +#: ../../po/../src/verbs.cpp:2035 +msgid "_Object to Path" +msgstr "Objektum átalakítása _lánccá" + +#: ../../po/../src/verbs.cpp:2036 +msgid "Convert selected objects to paths" +msgstr "A kijelölt objektumok láncokká alakítása" + +#: ../../po/../src/verbs.cpp:2037 +msgid "_Flow into Frame" +msgstr "Szöveg _tördelése keretbe" + +#: ../../po/../src/verbs.cpp:2038 +msgid "Put text into frames" +msgstr "Szöveg illesztése keretekbe" + +#: ../../po/../src/verbs.cpp:2039 +msgid "_Unflow" +msgstr "Szövegtördelés me_gszüntetése" + +#: ../../po/../src/verbs.cpp:2040 +msgid "Remove text from frame (creates a single-line text object)" +msgstr "Szöveg eltávolítása keretből (egysoros szövegobjektumot hoz létre)" + +#: ../../po/../src/verbs.cpp:2041 +msgid "_Convert to Text" +msgstr "Szöveggé való _konvertálás" + +#: ../../po/../src/verbs.cpp:2042 +msgid "Convert flowed text to regular text objects (preserves appearance)" +msgstr "" +"Tördelt szöveg normál szövegobjektumokká való alakítása (a megjelenés " +"megőrzésével)" + +#: ../../po/../src/verbs.cpp:2044 +msgid "Flip _Horizontal" +msgstr "_Vízszintes tükrözés" + +#: ../../po/../src/verbs.cpp:2044 +msgid "Flips selected objects horizontally" +msgstr "A kijelölt objektumok vízszintes tükrözése" + +#: ../../po/../src/verbs.cpp:2047 +msgid "Flip _Vertical" +msgstr "_Függőleges tükrözés" + +#: ../../po/../src/verbs.cpp:2047 +msgid "Flips selected objects vertically" +msgstr "A kijelölt objektumok függőleges tükrözése" + +#. Tools +#: ../../po/../src/verbs.cpp:2051 +msgid "Select" +msgstr "Kijelölés" + +#: ../../po/../src/verbs.cpp:2052 +msgid "Select and transform objects" +msgstr "Objektumok kijelölése és transzformációja" + +#: ../../po/../src/verbs.cpp:2053 +msgid "Node Edit" +msgstr "Csomópontszerkesztés" + +#: ../../po/../src/verbs.cpp:2054 +msgid "Edit path nodes or control handles" +msgstr "Lánc-csomópontok és kontrollpontok szerkesztése" + +#: ../../po/../src/verbs.cpp:2056 +msgid "Create rectangles and squares" +msgstr "Téglalapok és négyzetek rajzolása" + +#: ../../po/../src/verbs.cpp:2058 +msgid "Create circles, ellipses, and arcs" +msgstr "Körök, ellipszisek és ívek rajzolása" + +#: ../../po/../src/verbs.cpp:2060 +msgid "Create stars and polygons" +msgstr "Csillagok és sokszögek rajzolása" + +#: ../../po/../src/verbs.cpp:2062 +msgid "Create spirals" +msgstr "Spirálok rajzolása" + +#: ../../po/../src/verbs.cpp:2064 +msgid "Draw freehand lines" +msgstr "Szabadkézi vonalak rajzolása" + +#: ../../po/../src/verbs.cpp:2066 +msgid "Draw Bezier curves and straight lines" +msgstr "Bézier-görbék és egyenes vonalak rajzolása" + +#: ../../po/../src/verbs.cpp:2068 +msgid "Draw calligraphic lines" +msgstr "Művészi vonalak rajzolása" + +#: ../../po/../src/verbs.cpp:2070 +msgid "Create and edit text objects" +msgstr "Szövegobjektumok létrehozása és szerkesztése" + +#: ../../po/../src/verbs.cpp:2072 +msgid "Create and edit gradients" +msgstr "Színátmenetek létrehozása és szerkesztése" + +#: ../../po/../src/verbs.cpp:2074 +msgid "Zoom in or out" +msgstr "Nagyítás és kicsinyítés" + +#: ../../po/../src/verbs.cpp:2076 +msgid "Pick averaged colors from image" +msgstr "Átlagszín leolvasása a képről - színpipetta" + +#: ../../po/../src/verbs.cpp:2078 +msgid "Create connectors" +msgstr "Kapcsok létrehozása" + +#. Tool prefs +#: ../../po/../src/verbs.cpp:2081 +msgid "Selector Preferences" +msgstr "Kijelölőeszköz-beállítások" + +#: ../../po/../src/verbs.cpp:2082 +msgid "Open Preferences for the Selector tool" +msgstr "A kijelölőeszköz beállításainak megnyitása" + +#: ../../po/../src/verbs.cpp:2083 +msgid "Node Tool Preferences" +msgstr "Csomóponteszköz-beállítások" + +#: ../../po/../src/verbs.cpp:2084 +msgid "Open Preferences for the Node tool" +msgstr "A csomóponteszköz beállításainak megnyitása" + +#: ../../po/../src/verbs.cpp:2085 +msgid "Rectangle Preferences" +msgstr "Téglalap-beállítások" + +#: ../../po/../src/verbs.cpp:2086 +msgid "Open Preferences for the Rectangle tool" +msgstr "A téglalapeszköz beállításainak megnyitása" + +#: ../../po/../src/verbs.cpp:2087 +msgid "Ellipse Preferences" +msgstr "Ellipszis-beállítások" + +#: ../../po/../src/verbs.cpp:2088 +msgid "Open Preferences for the Ellipse tool" +msgstr "Az ellipsziseszköz beállításainak megnyitása" + +#: ../../po/../src/verbs.cpp:2089 +msgid "Star Preferences" +msgstr "Csillag-beállítások" + +#: ../../po/../src/verbs.cpp:2090 +msgid "Open Preferences for the Star tool" +msgstr "A csillageszköz beállításainak megnyitása" + +#: ../../po/../src/verbs.cpp:2091 +msgid "Spiral Preferences" +msgstr "Spirál-beállítások" + +#: ../../po/../src/verbs.cpp:2092 +msgid "Open Preferences for the Spiral tool" +msgstr "A spiráleszköz beállításainak megnyitása" + +#: ../../po/../src/verbs.cpp:2093 +msgid "Pencil Preferences" +msgstr "Ceruza-beállítások" + +#: ../../po/../src/verbs.cpp:2094 +msgid "Open Preferences for the Pencil tool" +msgstr "A \"ceruza\" eszköz beállításainak megnyitása" + +#: ../../po/../src/verbs.cpp:2095 +msgid "Pen Preferences" +msgstr "Toll-beállítások" + +#: ../../po/../src/verbs.cpp:2096 +msgid "Open Preferences for the Pen tool" +msgstr "A \"toll\" eszköz beállításainak megnyitása" + +#: ../../po/../src/verbs.cpp:2097 +msgid "Calligraphic Preferences" +msgstr "Művészitoll-beállítások" + +#: ../../po/../src/verbs.cpp:2098 +msgid "Open Preferences for the Calligraphy tool" +msgstr "A \"művészi toll\" eszköz beállításainak megnyitása" + +#: ../../po/../src/verbs.cpp:2099 +msgid "Text Preferences" +msgstr "Szövegeszköz-beállítások" + +#: ../../po/../src/verbs.cpp:2100 +msgid "Open Preferences for the Text tool" +msgstr "A szövegeszköz beállításainak megnyitása" + +#: ../../po/../src/verbs.cpp:2101 +msgid "Gradient Preferences" +msgstr "Színátmenet-beállítások" + +#: ../../po/../src/verbs.cpp:2102 +msgid "Open Preferences for the Gradient tool" +msgstr "A színátmenet-eszköz beállításainak megnyitása" + +#: ../../po/../src/verbs.cpp:2103 +msgid "Zoom Preferences" +msgstr "Nagyítóeszköz-beállítások" + +#: ../../po/../src/verbs.cpp:2104 +msgid "Open Preferences for the Zoom tool" +msgstr "A nagyítóeszköz beállításainak megnyitása" + +#: ../../po/../src/verbs.cpp:2105 +msgid "Dropper Preferences" +msgstr "Színpipetta-beállítások" + +#: ../../po/../src/verbs.cpp:2106 +msgid "Open Preferences for the Dropper tool" +msgstr "A \"színpipetta\" eszköz beállításainak megnyitása" + +#: ../../po/../src/verbs.cpp:2107 +msgid "Connector Preferences" +msgstr "Kapocs-beállítások" + +#: ../../po/../src/verbs.cpp:2108 +msgid "Open Preferences for the Connector tool" +msgstr "A kapocseszköz beállításainak megnyitása" + +#. Zoom/View +#: ../../po/../src/verbs.cpp:2111 +msgid "Zoom In" +msgstr "Nagyítás" + +#: ../../po/../src/verbs.cpp:2111 +msgid "Zoom in" +msgstr "Nagyítás" + +#: ../../po/../src/verbs.cpp:2112 +msgid "Zoom Out" +msgstr "Kicsinyítés" + +#: ../../po/../src/verbs.cpp:2112 +msgid "Zoom out" +msgstr "Kicsinyítés" + +#: ../../po/../src/verbs.cpp:2113 +msgid "_Rulers" +msgstr "_Vonalzók" + +#: ../../po/../src/verbs.cpp:2113 +msgid "Show or hide the canvas rulers" +msgstr "A rajzvászon vonalzóinak megjelenítése vagy elrejtése" + +#: ../../po/../src/verbs.cpp:2114 +msgid "Scroll_bars" +msgstr "_Gördítősávok" + +#: ../../po/../src/verbs.cpp:2114 +msgid "Show or hide the canvas scrollbars" +msgstr "A rajzvászon gördítősávjainak megjelenítése vagy elrejtése" + +#: ../../po/../src/verbs.cpp:2115 +msgid "_Grid" +msgstr "Rá_cs" + +#: ../../po/../src/verbs.cpp:2116 +msgid "G_uides" +msgstr "Se_gédvonalak" + +#: ../../po/../src/verbs.cpp:2117 +msgid "Nex_t Zoom" +msgstr "Kö_vetkező nagyítás" + +#: ../../po/../src/verbs.cpp:2117 +msgid "Next zoom (from the history of zooms)" +msgstr "Következő nagyítás (a nagyítási előzményekből)" + +#: ../../po/../src/verbs.cpp:2119 +msgid "Pre_vious Zoom" +msgstr "_Előző nagyítás" + +#: ../../po/../src/verbs.cpp:2119 +msgid "Previous zoom (from the history of zooms)" +msgstr "Előző nagyítás (a nagyítási előzményekből)" + +#: ../../po/../src/verbs.cpp:2121 +msgid "Zoom 1:_1" +msgstr "Tényleges (_1:1) méret" + +#: ../../po/../src/verbs.cpp:2121 +msgid "Zoom to 1:1" +msgstr "Nagyítás beállítása a tényleges (1:1) méretre" + +#: ../../po/../src/verbs.cpp:2123 +msgid "Zoom 1:_2" +msgstr "Felezett (1:_2) méret" + +#: ../../po/../src/verbs.cpp:2123 +msgid "Zoom to 1:2" +msgstr "Nagyítás beállítása a tényleges méret felére (1:2)" + +#: ../../po/../src/verbs.cpp:2125 +msgid "_Zoom 2:1" +msgstr "_Dupla (2:1) méret" + +#: ../../po/../src/verbs.cpp:2125 +msgid "Zoom to 2:1" +msgstr "Nagyítás beállítása a tényleges méret kétszeresére (2:1)" + +#: ../../po/../src/verbs.cpp:2128 +msgid "_Fullscreen" +msgstr "_Teljes képernyő" + +#: ../../po/../src/verbs.cpp:2128 +msgid "Stretch this document window to full screen" +msgstr "A dokumentumablak teljes képernyősre való méretezése" + +#: ../../po/../src/verbs.cpp:2131 +msgid "Duplic_ate Window" +msgstr "A_blak kettőzése" + +#: ../../po/../src/verbs.cpp:2131 +msgid "Open a new window with the same document" +msgstr "Új ablak nyitása ugyanezzel a dokumentummal" + +#: ../../po/../src/verbs.cpp:2133 +msgid "_New View Preview" +msgstr "Ú_j nézet előnézete" + +#: ../../po/../src/verbs.cpp:2134 +msgid "New View Preview" +msgstr "Új nézet előnézete" + +#. "view_new_preview" +#: ../../po/../src/verbs.cpp:2136 +#, fuzzy +msgid "_Normal" +msgstr "Normál" + +#: ../../po/../src/verbs.cpp:2137 +msgid "Switch to normal display mode" +msgstr "" + +#: ../../po/../src/verbs.cpp:2138 +#, fuzzy +msgid "_Outline" +msgstr "Téglalap-körvonal" + +#: ../../po/../src/verbs.cpp:2139 +msgid "Switch to outline (wireframe) display mode" +msgstr "" + +#: ../../po/../src/verbs.cpp:2141 +msgid "Ico_n Preview" +msgstr "Ik_on-előnézet" + +#: ../../po/../src/verbs.cpp:2142 +msgid "Open a window to preview items at different icon resolutions" +msgstr "" +"Ablak nyitása az elemek különböző ikonfelbontásokkal való megtekintésére" + +#: ../../po/../src/verbs.cpp:2144 +msgid "Zoom to fit page in window" +msgstr "" +"Nagyítási mérték beállítása akkorára, hogy pontosan a lap legyen látható az " +"ablakban" + +#: ../../po/../src/verbs.cpp:2145 +msgid "Page _Width" +msgstr "Lap_szélesség" + +#: ../../po/../src/verbs.cpp:2146 +msgid "Zoom to fit page width in window" +msgstr "" +"Nagyítási mérték beállítása akkorára, hogy a lap szélessége megegyezzen az " +"ablak szélességével" + +#: ../../po/../src/verbs.cpp:2148 +msgid "Zoom to fit drawing in window" +msgstr "" +"Nagyítási mérték beállítása akkorára, hogy pontosan a rajz legyen látható az " +"ablakban" + +#: ../../po/../src/verbs.cpp:2150 +msgid "Zoom to fit selection in window" +msgstr "" +"Nagyítási mérték beállítása akkorára, hogy pontosan a kijelölés legyen " +"látható az ablakban" + +#. Dialogs +#: ../../po/../src/verbs.cpp:2153 +msgid "In_kscape Preferences..." +msgstr "Inksc_ape-beállítások..." + +#: ../../po/../src/verbs.cpp:2154 +msgid "Global Inkscape preferences" +msgstr "Az Inkscape globális beállításai" + +#: ../../po/../src/verbs.cpp:2155 +msgid "_Document Preferences..." +msgstr "_Dokumentum-beállítások..." + +#: ../../po/../src/verbs.cpp:2156 +msgid "Preferences saved with the document" +msgstr "A dokumentummal együtt elmentett beállítások" + +#: ../../po/../src/verbs.cpp:2157 +msgid "_Fill and Stroke..." +msgstr "_Kitöltés és körvonal..." + +#: ../../po/../src/verbs.cpp:2158 +msgid "Fill and Stroke dialog" +msgstr "\"Kitöltés és körvonal\" párbeszédablak" + +#. TRANSLATORS: "Swatches" means: color samples +#: ../../po/../src/verbs.cpp:2160 +msgid "S_watches..." +msgstr "Szí_nminták..." + +#: ../../po/../src/verbs.cpp:2161 +msgid "View color swatches" +msgstr "Színminták megtekintése" + +#: ../../po/../src/verbs.cpp:2162 +msgid "Transfor_m..." +msgstr "Tr_anszformáció..." + +#: ../../po/../src/verbs.cpp:2163 +msgid "Transform dialog" +msgstr "\"Transzformáció\" párbeszédablak" + +#: ../../po/../src/verbs.cpp:2164 +msgid "_Align and Distribute..." +msgstr "_Igazítás és elrendezés..." + +#: ../../po/../src/verbs.cpp:2165 +msgid "Align and Distribute dialog" +msgstr "\"Igazítás és elrendezés\" párbeszédablak" + +#: ../../po/../src/verbs.cpp:2166 +msgid "_Text and Font..." +msgstr "_Szöveg és betűtípus..." + +#: ../../po/../src/verbs.cpp:2167 +msgid "Text and Font dialog" +msgstr "\"Szöveg és betűtípus\" párbeszédablak" + +#: ../../po/../src/verbs.cpp:2168 +msgid "_XML Editor..." +msgstr "_XML-szerkesztő..." + +#: ../../po/../src/verbs.cpp:2169 +msgid "XML Editor" +msgstr "XML-szerkesztő" + +#: ../../po/../src/verbs.cpp:2170 +msgid "_Find..." +msgstr "K_eresés..." + +#: ../../po/../src/verbs.cpp:2171 +msgid "Find objects in document" +msgstr "Objektumok keresése a dokumentumban" + +#: ../../po/../src/verbs.cpp:2172 +msgid "_Messages..." +msgstr "Üze_netek..." + +#: ../../po/../src/verbs.cpp:2173 +msgid "View debug messages" +msgstr "Nyomkövetési üzenetek megjelenítése" + +#: ../../po/../src/verbs.cpp:2174 +msgid "S_cripts..." +msgstr "Szkr_iptek..." + +#: ../../po/../src/verbs.cpp:2175 +msgid "Run scripts" +msgstr "Szkriptek végrehajtása" + +#: ../../po/../src/verbs.cpp:2176 +msgid "Show/Hide D_ialogs" +msgstr "_Párbeszédablakok megjelenítése/elrejtése" + +#: ../../po/../src/verbs.cpp:2177 +msgid "Show or hide all active dialogs" +msgstr "Az összes aktív párbeszédablak megjelenítése vagy elrejtése" + +#. TRANSLATORS: "Tile clones" means: "Create tiled clones" +#: ../../po/../src/verbs.cpp:2179 +msgid "Tile clones..." +msgstr "Csempézett klónok..." + +#: ../../po/../src/verbs.cpp:2180 +msgid "Create and arrange multiple clones of selection" +msgstr "A kijelölés többszörös klónjainak létrehozása és elrendezése" + +#: ../../po/../src/verbs.cpp:2181 +msgid "_Object Properties..." +msgstr "_Objektum-tulajdonságok..." + +#: ../../po/../src/verbs.cpp:2182 +msgid "Object Properties dialog" +msgstr "\"Objektum-tulajdonságok\" párbeszédablak" + +#: ../../po/../src/verbs.cpp:2185 +msgid "_Connect to Jabber server..." +msgstr "_Kapcsolódás egy Jabber-kiszolgálóhoz..." + +#: ../../po/../src/verbs.cpp:2185 +msgid "Connect to a Jabber server" +msgstr "Kapcsolódás egy Jabber-kiszolgálóhoz" + +#: ../../po/../src/verbs.cpp:2187 +msgid "Share with _user..." +msgstr "Megosztás egy _felhasználóval..." + +#: ../../po/../src/verbs.cpp:2187 +msgid "Establish a whiteboard session with another Jabber user" +msgstr "Rajztábla-munkamenet létrehozása egy másik Jabber-felhasználóval" + +#: ../../po/../src/verbs.cpp:2189 +msgid "Share with _chatroom..." +msgstr "Megosztás egy _csevegőszobával..." + +#: ../../po/../src/verbs.cpp:2189 +msgid "" +"Join a chatroom to start a new whiteboard session or join one in progress" +msgstr "" +"Csatlakozás egy csevegőszobához egy új rajztábla-munkamenet indítása vagy " +"egy létezőhöz való csatlakozás céljából" + +#: ../../po/../src/verbs.cpp:2191 +msgid "_Dump XML node tracker" +msgstr "_XML-csomópontok nyomkövetési adatainak kiírása" + +#: ../../po/../src/verbs.cpp:2191 +msgid "Dump the contents of the XML tracker to the console" +msgstr "Az XML-nyomkövető tartalmának kiírása a konzolra" + +#: ../../po/../src/verbs.cpp:2193 +msgid "_Open session file..." +msgstr "Munkamenet-fájl _megnyitása..." + +#: ../../po/../src/verbs.cpp:2193 +msgid "Open and browse through records of past whiteboard sessions" +msgstr "Korábbi rajztábla-munkamenetek megnyitása illetve azok közti böngészés" + +#: ../../po/../src/verbs.cpp:2195 +msgid "Session file playback" +msgstr "Munkamenet-fájl visszajátszása" + +#: ../../po/../src/verbs.cpp:2197 +msgid "_Disconnect from session" +msgstr "Lekapcsolódás a m_unkamenetről" + +#: ../../po/../src/verbs.cpp:2199 +msgid "Disconnect from _server" +msgstr "Lekapcsolódás a k_iszolgálóról" + +#: ../../po/../src/verbs.cpp:2201 +msgid "_Input Devices..." +msgstr "Beviteli eszkö_zök..." + +#: ../../po/../src/verbs.cpp:2202 +msgid "Configure extended input devices" +msgstr "Kiterjesztett beviteli eszközök beállítása" + +#. Help +#: ../../po/../src/verbs.cpp:2205 +msgid "_Keys and Mouse" +msgstr "_Billentyűzet és egér" + +#: ../../po/../src/verbs.cpp:2206 +msgid "Key and mouse shortcuts reference" +msgstr "Billentyű- és egérkombinációk leírása" + +#: ../../po/../src/verbs.cpp:2207 +msgid "About E_xtensions" +msgstr "Információ a _kiterjesztésekről" + +#: ../../po/../src/verbs.cpp:2208 +msgid "About Extensions..." +msgstr "Információ a kiterjesztésekkel kapcsolatban..." + +#: ../../po/../src/verbs.cpp:2209 +msgid "About _Memory" +msgstr "_Memória-információ" + +#: ../../po/../src/verbs.cpp:2210 +msgid "About Memory..." +msgstr "Információ a memóriával kapcsolatban..." + +#: ../../po/../src/verbs.cpp:2211 +msgid "_About Inkscape" +msgstr "Az Inkscape _névjegye" + +#. "help_about" +#. new HelpVerb(SP_VERB_SHOW_LICENSE, "ShowLicense", N_("Modifying or Redistributing Inkscape"), +#. N_("Show license to modify and/or redistribute Inkscape: GNU GPL"), NULL), +#. Tutorials +#: ../../po/../src/verbs.cpp:2217 +msgid "Inkscape: _Basic" +msgstr "Inkscape: _Bevezetés" + +#: ../../po/../src/verbs.cpp:2218 +msgid "Getting started with Inkscape" +msgstr "Bevezetés az Inkscape-be" + +#. "tutorial_basic" +#: ../../po/../src/verbs.cpp:2219 +msgid "Inkscape: _Shapes" +msgstr "Inkscape: _Alakzatok" + +#: ../../po/../src/verbs.cpp:2220 +msgid "Using shape tools to create and edit shapes" +msgstr "Alakzatok létrehozása és szerkesztése az alakzateszközökkel" + +#: ../../po/../src/verbs.cpp:2221 +msgid "Inkscape: _Advanced" +msgstr "Inkscape: _Haladó" + +#: ../../po/../src/verbs.cpp:2222 +msgid "Advanced Inkscape topics" +msgstr "Haladó szintű Inkscape-témakörök" + +#. "tutorial_advanced" +#. TRANSLATORS: "to trace" means "to convert a bitmap to vector graphics" (to vectorize) +#: ../../po/../src/verbs.cpp:2224 +msgid "Inkscape: T_racing" +msgstr "Inkscape: _Vektorizálás" + +#: ../../po/../src/verbs.cpp:2225 +msgid "Using bitmap tracing" +msgstr "A bitkép-vektorizálás használata" + +#. "tutorial_tracing" +#: ../../po/../src/verbs.cpp:2226 +msgid "Inkscape: _Calligraphy" +msgstr "Inkscape: _Művészi toll" + +#: ../../po/../src/verbs.cpp:2227 +msgid "Using the Calligraphy pen tool" +msgstr "A \"művészi toll\" eszköz használata" + +#: ../../po/../src/verbs.cpp:2228 +msgid "_Elements of Design" +msgstr "A tervezés _elemei" + +#: ../../po/../src/verbs.cpp:2229 +msgid "Principles of design in the tutorial form" +msgstr "A tervezés alapelvei" + +#. "tutorial_design" +#: ../../po/../src/verbs.cpp:2230 +msgid "_Tips and Tricks" +msgstr "_Tippek és trükkök" + +#: ../../po/../src/verbs.cpp:2231 +msgid "Miscellaneous tips and tricks" +msgstr "Különböző tippek és trükkök" + +#. "tutorial_tips" +#. Effect +#: ../../po/../src/verbs.cpp:2234 +msgid "Previous Effect" +msgstr "Előző effektus" + +#: ../../po/../src/verbs.cpp:2235 +msgid "Repeat the last effect with the same settings" +msgstr "A legutóbbi effektus megismétlése azonos beállításokkal" + +#. "tutorial_tips" +#: ../../po/../src/verbs.cpp:2236 +msgid "Previous Effect Settings..." +msgstr "Előző effektus beállításai..." + +#: ../../po/../src/verbs.cpp:2237 +msgid "Repeat the last effect with new settings" +msgstr "A legutóbbi effektus megismétlése új beállításokkal" + +#: ../../po/../src/widgets/dash-selector.cpp:106 +msgid "Dash pattern" +msgstr "Vonalminta" + +#: ../../po/../src/widgets/dash-selector.cpp:121 +msgid "Pattern offset" +msgstr "A minta eltolása" + +#: ../../po/../src/widgets/desktop-widget.cpp:240 +msgid "Zoom drawing if window size changes" +msgstr "A rajz nagyításának módosítása az ablak méretének változásakor" + +#: ../../po/../src/widgets/desktop-widget.cpp:298 +msgid "Cursor coordinates" +msgstr "Kurzorkoordináták" + +#. display the initial welcome message in the statusbar +#: ../../po/../src/widgets/desktop-widget.cpp:324 +msgid "" +"Welcome to Inkscape! Use shape or freehand tools to create objects; " +"use selector (arrow) to move or transform them." +msgstr "" +"Üdvözli az Inkscape. Objektum-létrehozáshoz használja az " +"alakzateszközöket és a szabadkézi eszközöket, áthelyezéshez/módosításhoz " +"pedig a kijelölőeszközt (nyilat)." + +#: ../../po/../src/widgets/desktop-widget.cpp:372 +#, c-format +msgid "%s: %d - Inkscape" +msgstr "%s: %d - Inkscape" + +#: ../../po/../src/widgets/desktop-widget.cpp:374 +#, c-format +msgid "%s - Inkscape" +msgstr "%s - Inkscape" + +#: ../../po/../src/widgets/desktop-widget.cpp:532 +#, c-format +msgid "" +"Save changes to document \"%s\" before " +"closing?\n" +"\n" +"If you close without saving, your changes will be discarded." +msgstr "" +"A bezárás előtt elmenti \"%s\" " +"módosításait?\n" +"\n" +"Ha mentés nélkül végez bezárást, akkor az összes módosítás elvész." + +#: ../../po/../src/widgets/desktop-widget.cpp:548 +#: ../../po/../src/widgets/desktop-widget.cpp:612 +msgid "Close _without saving" +msgstr "_Bezárás mentés nélkül" + +#: ../../po/../src/widgets/desktop-widget.cpp:595 +#, c-format +msgid "" +"The file \"%s\" was saved with a " +"format (%s) that may cause data loss!\n" +"\n" +"Do you want to save this file in another format?" +msgstr "" +"A(z) \"%s\" fájl olyan formátumban " +"volt elmentve (%s), amely adatvesztést okozhat.\n" +"\n" +"El kívánja menteni a dokumentumot egy másik formátumban?" + +#. Family frame +#: ../../po/../src/widgets/font-selector.cpp:156 +msgid "Font family" +msgstr "Betűtípus-család" + +#. Style frame +#: ../../po/../src/widgets/font-selector.cpp:184 +msgid "Style" +msgstr "Stílus" + +#: ../../po/../src/widgets/font-selector.cpp:219 +msgid "Font size:" +msgstr "Betűtípus-méret:" + +#. TRANSLATORS: Test string used in text and font dialog (when no +#. * text has been entered) to get a preview of the font. Choose +#. * some representative characters that users of your locale will be +#. * interested in. +#: ../../po/../src/widgets/font-selector.cpp:554 +msgid "AaBbCcIiPpQq12368.;/()" +msgstr "AaBbCcIiPpQq12368.;/()ÁáÉéÍíÓóÖöŐőÚúÜüŰű" + +#: ../../po/../src/widgets/gradient-selector.cpp:137 +#: ../../po/../src/widgets/gradient-toolbar.cpp:524 +msgid "Duplicate" +msgstr "Kettőzés" + +#: ../../po/../src/widgets/gradient-selector.cpp:142 +#: ../../po/../src/widgets/gradient-toolbar.cpp:535 +msgid "Edit..." +msgstr "Szerkesztés..." + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/pservers.html#LinearGradientSpreadMethodAttribute +#: ../../po/../src/widgets/gradient-selector.cpp:159 +msgid "" +"Whether to fill with flat color beyond the ends of the gradient vector " +"(spreadMethod=\"pad\"), or repeat the gradient in the same direction " +"(spreadMethod=\"repeat\"), or repeat the gradient in alternating opposite " +"directions (spreadMethod=\"reflect\")" +msgstr "" +"Az átmenetvektor szélein túl egyenletes színnel történjen-e a kitöltés " +"(spreadMethod=\"pad\", nincs ismétlődés), vagy ismétlődjön az átmenet " +"ugyanabban az irányban (spreadMethod=\"repeat\", normál ismétlődés), vagy " +"pedig ismétlődjön az átmenet ellentétesen, azaz váltakozó irányban " +"(spreadMethod=\"reflect\", tükrözéses ismétlődés)" + +#: ../../po/../src/widgets/gradient-selector.cpp:165 +msgid "none" +msgstr "nincs" + +#: ../../po/../src/widgets/gradient-selector.cpp:169 +msgid "reflected" +msgstr "tükrözött" + +#: ../../po/../src/widgets/gradient-selector.cpp:173 +msgid "direct" +msgstr "normál" + +#: ../../po/../src/widgets/gradient-selector.cpp:181 +msgid "Repeat:" +msgstr "Ismétlődés:" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:217 +msgid "No gradients" +msgstr "Nincs színátmenet" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:226 +msgid "Nothing selected" +msgstr "Nincs kijelölés" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:237 +msgid "No gradients in selection" +msgstr "Nincs kijelölve színátmenet" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:247 +msgid "Multiple gradients" +msgstr "Több színátmenet" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:525 +msgid "" +"If the gradient is used by more than one object, create a copy of it for the " +"selected object(s)" +msgstr "" +"Ha a színátmenetet több objektum használja, akkor annak másolatának " +"létrehozása a kijelölt objektum(ok) számára" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:536 +msgid "Edit the stops of the gradient" +msgstr "A színátmenet fázisainak szerkesztése" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:593 +#: ../../po/../src/widgets/toolbox.cpp:1103 +#: ../../po/../src/widgets/toolbox.cpp:1192 +#: ../../po/../src/widgets/toolbox.cpp:1485 +#: ../../po/../src/widgets/toolbox.cpp:1534 +#: ../../po/../src/widgets/toolbox.cpp:1766 +#: ../../po/../src/widgets/toolbox.cpp:1801 +#: ../../po/../src/widgets/toolbox.cpp:2331 +#: ../../po/../src/widgets/toolbox.cpp:2370 +msgid "New:" +msgstr "Új:" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:606 +msgid "Create linear gradient" +msgstr "Lineáris színátmenet létrehozása" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:620 +msgid "Create radial (elliptic or circular) gradient" +msgstr "Sugárirányú (ellipszis vagy kör alakú) színátmenet létrehozása" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:635 +msgid "on" +msgstr "ezen:" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:648 +msgid "Create gradient in the fill" +msgstr "Színátmenet létrehozása a kitöltésben" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:662 +msgid "Create gradient in the stroke" +msgstr "Színátmenet létrehozása a körvonalban" + +#. FIXME: implement averaging of all parameters for multiple selected stars +#. gtk_label_set_markup(GTK_LABEL(l), _("Average:")); +#. FIXME: implement averaging of all parameters for multiple selected +#. gtk_label_set_markup(GTK_LABEL(l), _("Average:")); +#: ../../po/../src/widgets/gradient-toolbar.cpp:676 +#: ../../po/../src/widgets/toolbox.cpp:1105 +#: ../../po/../src/widgets/toolbox.cpp:1124 +#: ../../po/../src/widgets/toolbox.cpp:1493 +#: ../../po/../src/widgets/toolbox.cpp:1518 +#: ../../po/../src/widgets/toolbox.cpp:1768 +#: ../../po/../src/widgets/toolbox.cpp:1787 +#: ../../po/../src/widgets/toolbox.cpp:2334 +#: ../../po/../src/widgets/toolbox.cpp:2354 +msgid "Change:" +msgstr "Módosítás:" + +#: ../../po/../src/widgets/gradient-vector.cpp:269 +msgid "No gradients in document" +msgstr "Nincs színátmenet a dokumentumban" + +#: ../../po/../src/widgets/gradient-vector.cpp:275 +msgid "No gradient selected" +msgstr "Nincs kijelölve színátmenet" + +#: ../../po/../src/widgets/gradient-vector.cpp:532 +msgid "No stops in gradient" +msgstr "Nincs fázis a színátmenetben" + +#. TRANSLATORS: "Stop" means: a "phase" of a gradient +#: ../../po/../src/widgets/gradient-vector.cpp:794 +msgid "Add stop" +msgstr "Fázis felvétele" + +#: ../../po/../src/widgets/gradient-vector.cpp:797 +msgid "Add another control stop to gradient" +msgstr "Újabb fázis felvétele a színátmenetbe" + +#: ../../po/../src/widgets/gradient-vector.cpp:799 +msgid "Delete stop" +msgstr "Fázis törlése" + +#: ../../po/../src/widgets/gradient-vector.cpp:802 +msgid "Delete current control stop from gradient" +msgstr "A jelenlegi fázis törlése a színátmenetből" + +#. Label +#: ../../po/../src/widgets/gradient-vector.cpp:813 +msgid "Offset:" +msgstr "Pozíció:" + +#. TRANSLATORS: "Stop" means: a "phase" of a gradient +#: ../../po/../src/widgets/gradient-vector.cpp:858 +msgid "Stop Color" +msgstr "Fázis színe" + +#: ../../po/../src/widgets/gradient-vector.cpp:887 +msgid "Gradient editor" +msgstr "Színátmenet-szerkesztő" + +#: ../../po/../src/widgets/layer-selector.cpp:119 +msgid "Toggle current layer visibility" +msgstr "Az aktuális réteg láthatóságának átkapcsolása" + +#: ../../po/../src/widgets/layer-selector.cpp:139 +msgid "Lock or unlock current layer" +msgstr "Az aktuális réteg zárolása illetve feloldása" + +#: ../../po/../src/widgets/layer-selector.cpp:142 +msgid "Current layer" +msgstr "Aktuális réteg" + +#: ../../po/../src/widgets/layer-selector.cpp:553 +msgid "(root)" +msgstr "(gyökér)" + +#: ../../po/../src/widgets/paint-selector.cpp:182 +#: ../../po/../src/widgets/paint-selector.cpp:561 +msgid "No paint" +msgstr "Nincs megrajzolva" + +#: ../../po/../src/widgets/paint-selector.cpp:184 +#: ../../po/../src/widgets/paint-selector.cpp:629 +msgid "Flat color" +msgstr "Egyenletes szín" + +#: ../../po/../src/widgets/paint-selector.cpp:186 +#: ../../po/../src/widgets/paint-selector.cpp:696 +msgid "Linear gradient" +msgstr "Lineáris színátmenet" + +#: ../../po/../src/widgets/paint-selector.cpp:188 +#: ../../po/../src/widgets/paint-selector.cpp:699 +msgid "Radial gradient" +msgstr "Sugárirányú színátmenet" + +#: ../../po/../src/widgets/paint-selector.cpp:192 +msgid "Unset paint (make it undefined so it can be inherited)" +msgstr "A rajzolat törlése (definiálatlanná tevés, hogy öröklődhessen)" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/painting.html#FillRuleProperty +#: ../../po/../src/widgets/paint-selector.cpp:204 +msgid "" +"Any path self-intersections or subpaths create holes in the fill (fill-rule: " +"evenodd)" +msgstr "" +"A láncok önmagukkal való metszései és az alláncok üres területeket hoznak " +"létre a kitöltésben (fill-rule: evenodd, azaz kitöltési szabály: váltakozó)" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/painting.html#FillRuleProperty +#: ../../po/../src/widgets/paint-selector.cpp:215 +msgid "" +"Fill is solid unless a subpath is counterdirectional (fill-rule: nonzero)" +msgstr "" +"A kitöltés egyenletes, kivéve akkor, ha egy allánc ellentétes irányú (fill-" +"rule: nonzero, azaz kitöltési szabály: nem-nulla)" + +#: ../../po/../src/widgets/paint-selector.cpp:528 +msgid "No objects" +msgstr "Nincs objektum" + +#: ../../po/../src/widgets/paint-selector.cpp:539 +msgid "Multiple styles" +msgstr "Többféle stílus" + +#: ../../po/../src/widgets/paint-selector.cpp:550 +msgid "Paint is undefined" +msgstr "A rajzolat definiálatlan" + +#: ../../po/../src/widgets/paint-selector.cpp:757 +msgid "No patterns in document" +msgstr "Nincs minta a dokumentumban" + +#: ../../po/../src/widgets/paint-selector.cpp:872 +msgid "" +"Use Edit > Object(s) to Pattern to create a new pattern from " +"selection." +msgstr "" +"Egy új mintának a kijelölésből való létrehozásához használja a " +"Szerkesztés > Objektum átalakítása mintává funkciót." + +#: ../../po/../src/widgets/select-toolbar.cpp:426 +msgid "Now stroke width is scaled when objects are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:428 +msgid "Now stroke width is not scaled when objects are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:436 +msgid "" +"Now rounded rectangle corners are scaled when rectangles are " +"scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:438 +msgid "" +"Now rounded rectangle corners are not scaled when rectangles " +"are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:446 +msgid "" +"Now gradients are transformed along with their objects when " +"those are transformed (moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:448 +msgid "" +"Now gradients remain fixed when objects are transformed " +"(moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:456 +msgid "" +"Now patterns are transformed along with their objects when " +"those are transformed (moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:458 +msgid "" +"Now patterns remain fixed when objects are transformed (moved, " +"scaled, rotated, or skewed)." +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:506 +msgid "select_toolbar|X" +msgstr "X" + +#: ../../po/../src/widgets/select-toolbar.cpp:506 +msgid "Horizontal coordinate of selection" +msgstr "A kijelölés vízszintes koordinátája" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:511 +msgid "select_toolbar|Y" +msgstr "Y" + +#: ../../po/../src/widgets/select-toolbar.cpp:511 +msgid "Vertical coordinate of selection" +msgstr "A kijelölés függőleges koordinátája" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:517 +msgid "select_toolbar|W" +msgstr "Sz" + +#: ../../po/../src/widgets/select-toolbar.cpp:517 +msgid "Width of selection" +msgstr "A kijelölés szélessége" + +#: ../../po/../src/widgets/select-toolbar.cpp:525 +msgid "Change both width and height by the same proportion" +msgstr "A szélesség és a magasság azonos arányban való módosítása" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:534 +msgid "select_toolbar|H" +msgstr "M" + +#: ../../po/../src/widgets/select-toolbar.cpp:534 +msgid "Height of selection" +msgstr "A kijelölés magassága" + +#: ../../po/../src/widgets/sp-color-gtkselector.cpp:62 +msgid "System" +msgstr "Rendszer" + +#: ../../po/../src/widgets/sp-color-notebook.cpp:322 +msgid "RGBA_:" +msgstr "R_GBA:" + +#: ../../po/../src/widgets/sp-color-notebook.cpp:330 +msgid "Hexadecimal RGBA value of the color" +msgstr "A szín hexadecimális RGBA-értéke (vörös, zöld, kék, alfa)" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "RGB" +msgstr "RGB" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "HSL" +msgstr "HSL" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "CMYK" +msgstr "CMYK" + +#: ../../po/../src/widgets/sp-color-scales.cpp:397 +msgid "_R" +msgstr "_V" + +#: ../../po/../src/widgets/sp-color-scales.cpp:398 +#: ../../po/../src/widgets/sp-color-scales.cpp:399 +msgid "Red" +msgstr "Vörös" + +#: ../../po/../src/widgets/sp-color-scales.cpp:400 +msgid "_G" +msgstr "_Z" + +#: ../../po/../src/widgets/sp-color-scales.cpp:401 +#: ../../po/../src/widgets/sp-color-scales.cpp:402 +msgid "Green" +msgstr "Zöld" + +#: ../../po/../src/widgets/sp-color-scales.cpp:403 +msgid "_B" +msgstr "_K" + +#: ../../po/../src/widgets/sp-color-scales.cpp:404 +#: ../../po/../src/widgets/sp-color-scales.cpp:405 +msgid "Blue" +msgstr "Kék" + +#. Label +#: ../../po/../src/widgets/sp-color-scales.cpp:406 +#: ../../po/../src/widgets/sp-color-scales.cpp:432 +#: ../../po/../src/widgets/sp-color-scales.cpp:463 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:141 +msgid "_A" +msgstr "_A" + +#: ../../po/../src/widgets/sp-color-scales.cpp:407 +#: ../../po/../src/widgets/sp-color-scales.cpp:408 +#: ../../po/../src/widgets/sp-color-scales.cpp:433 +#: ../../po/../src/widgets/sp-color-scales.cpp:434 +#: ../../po/../src/widgets/sp-color-scales.cpp:464 +#: ../../po/../src/widgets/sp-color-scales.cpp:465 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:151 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:163 +msgid "Alpha (opacity)" +msgstr "Alfa (átlátszatlanság)" + +#: ../../po/../src/widgets/sp-color-scales.cpp:423 +msgid "_H" +msgstr "_Á" + +#: ../../po/../src/widgets/sp-color-scales.cpp:424 +#: ../../po/../src/widgets/sp-color-scales.cpp:425 +msgid "Hue" +msgstr "Árnyalat" + +#: ../../po/../src/widgets/sp-color-scales.cpp:426 +msgid "_S" +msgstr "_T" + +#: ../../po/../src/widgets/sp-color-scales.cpp:427 +#: ../../po/../src/widgets/sp-color-scales.cpp:428 +msgid "Saturation" +msgstr "Telítettség" + +#: ../../po/../src/widgets/sp-color-scales.cpp:429 +msgid "_L" +msgstr "_F" + +#: ../../po/../src/widgets/sp-color-scales.cpp:430 +#: ../../po/../src/widgets/sp-color-scales.cpp:431 +msgid "Lightness" +msgstr "Fényesség" + +#: ../../po/../src/widgets/sp-color-scales.cpp:451 +msgid "_C" +msgstr "_C" + +#: ../../po/../src/widgets/sp-color-scales.cpp:452 +#: ../../po/../src/widgets/sp-color-scales.cpp:453 +msgid "Cyan" +msgstr "Ciánkék" + +#: ../../po/../src/widgets/sp-color-scales.cpp:454 +msgid "_M" +msgstr "_B" + +#: ../../po/../src/widgets/sp-color-scales.cpp:455 +#: ../../po/../src/widgets/sp-color-scales.cpp:456 +msgid "Magenta" +msgstr "Bíbor" + +#: ../../po/../src/widgets/sp-color-scales.cpp:457 +msgid "_Y" +msgstr "_S" + +#: ../../po/../src/widgets/sp-color-scales.cpp:458 +#: ../../po/../src/widgets/sp-color-scales.cpp:459 +msgid "Yellow" +msgstr "Sárga" + +#: ../../po/../src/widgets/sp-color-scales.cpp:460 +msgid "_K" +msgstr "_K" + +#: ../../po/../src/widgets/sp-color-selector.cpp:71 +msgid "Unnamed" +msgstr "Névtelen" + +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:68 +msgid "Wheel" +msgstr "Kerék" + +#: ../../po/../src/widgets/sp-xmlview-attr-list.cpp:53 +msgid "Attribute" +msgstr "Tulajdonság" + +#: ../../po/../src/widgets/sp-xmlview-attr-list.cpp:54 +msgid "Value" +msgstr "Érték" + +#: ../../po/../src/widgets/toolbox.cpp:424 +msgid "Insert new nodes into selected segments" +msgstr "Új csomópontok felvétele a kijelölt szakaszokra" + +#: ../../po/../src/widgets/toolbox.cpp:426 +msgid "Delete selected nodes" +msgstr "A kijelölt csomópontok törlése" + +#: ../../po/../src/widgets/toolbox.cpp:431 +msgid "Join paths at selected nodes" +msgstr "Láncok összekapcsolása a kijelölt csomópontoknál" + +#: ../../po/../src/widgets/toolbox.cpp:433 +msgid "Join paths at selected nodes with new segment" +msgstr "Láncok összekapcsolása új szakasszal a kijelölt csomópontoknál" + +#: ../../po/../src/widgets/toolbox.cpp:436 +msgid "Split path between two non-endpoint nodes" +msgstr "Lánc elvágása szakasztörléssel két, nem végponti csomópont közt" + +#: ../../po/../src/widgets/toolbox.cpp:439 +msgid "Break path at selected nodes" +msgstr "Lánc elvágása a kijelölt csomópontoknál" + +#: ../../po/../src/widgets/toolbox.cpp:444 +msgid "Make selected nodes corner" +msgstr "A kijelölt csomópontok csúccsá tétele" + +#: ../../po/../src/widgets/toolbox.cpp:447 +msgid "Make selected nodes smooth" +msgstr "A kijelölt csomópontok ívessé tétele" + +#: ../../po/../src/widgets/toolbox.cpp:450 +msgid "Make selected nodes symmetric" +msgstr "A kijelölt csomópontok szimmetrikussá tétele" + +#: ../../po/../src/widgets/toolbox.cpp:455 +msgid "Make selected segments lines" +msgstr "A kijelölt szakaszok egyenesekké alakítása" + +#: ../../po/../src/widgets/toolbox.cpp:458 +msgid "Make selected segments curves" +msgstr "A kijelölt szakaszok görbékké alakítása" + +#: ../../po/../src/widgets/toolbox.cpp:1199 +msgid "Polygon" +msgstr "Sokszög" + +#: ../../po/../src/widgets/toolbox.cpp:1206 +msgid "Regular polygon (with one handle) instead of a star" +msgstr "Csillag helyett (1 vezérlőelemmel rendelkező) szabályos sokszög" + +#: ../../po/../src/widgets/toolbox.cpp:1218 +msgid "Corners:" +msgstr "Csúcsok:" + +#: ../../po/../src/widgets/toolbox.cpp:1218 +msgid "Number of corners of a polygon or star" +msgstr "A sokszög illetve csillag csúcsainak száma" + +#: ../../po/../src/widgets/toolbox.cpp:1228 +msgid "Spoke ratio:" +msgstr "Ágarány:" + +# Tip radius is the distance from the center to the farthest handle. +# Base radius is the same for closest handle. +#. TRANSLATORS: Tip radius of a star is the distance from the center to the farthest handle. +#. Base radius is the same for the closest handle. +#: ../../po/../src/widgets/toolbox.cpp:1231 +msgid "Base radius to tip radius ratio" +msgstr "Az alapponti és a csúcsponti sugár aránya" + +# TODO: ellenőrizni +#: ../../po/../src/widgets/toolbox.cpp:1246 +msgid "Rounded:" +msgstr "Lekerekítettség:" + +#: ../../po/../src/widgets/toolbox.cpp:1246 +msgid "How much rounded are the corners (0 for sharp)" +msgstr "Mennyire lekerekítettek a sarkok (0: hegyesek)" + +# TODO: ellenőrizni +#: ../../po/../src/widgets/toolbox.cpp:1256 +msgid "Randomized:" +msgstr "Véletlenszerűség:" + +#: ../../po/../src/widgets/toolbox.cpp:1256 +msgid "Scatter randomly the corners and angles" +msgstr "A csúcsok és a szögek véletlenszerű elrendezése" + +#: ../../po/../src/widgets/toolbox.cpp:1269 +#: ../../po/../src/widgets/toolbox.cpp:1838 +#: ../../po/../src/widgets/toolbox.cpp:2061 +msgid "Defaults" +msgstr "Alapértelmezések" + +#: ../../po/../src/widgets/toolbox.cpp:1270 +#: ../../po/../src/widgets/toolbox.cpp:1839 +#: ../../po/../src/widgets/toolbox.cpp:2062 +msgid "" +"Reset shape parameters to defaults (use Inkscape Preferences > Tools to " +"change defaults)" +msgstr "" +"Az alakzat paramétereinek visszaállítása az alapértelmezett értékekre (az " +"alapértelmezések módosítása az Inkscape-beállítások > Eszközök funkcióval " +"lehetséges)" + +#: ../../po/../src/widgets/toolbox.cpp:1544 +msgid "W:" +msgstr "Sz:" + +#: ../../po/../src/widgets/toolbox.cpp:1544 +msgid "Width of rectangle" +msgstr "A téglalap szélessége" + +#: ../../po/../src/widgets/toolbox.cpp:1556 +msgid "Height of rectangle" +msgstr "A téglalap magassága" + +#: ../../po/../src/widgets/toolbox.cpp:1568 +msgid "Rx:" +msgstr "Rx:" + +#: ../../po/../src/widgets/toolbox.cpp:1568 +msgid "Horizontal radius of rounded corners" +msgstr "A lekerekített csúcsok vízszintes sugara" + +#: ../../po/../src/widgets/toolbox.cpp:1578 +msgid "Ry:" +msgstr "Ry:" + +#: ../../po/../src/widgets/toolbox.cpp:1578 +msgid "Vertical radius of rounded corners" +msgstr "A lekerekített csúcsok függőleges sugara" + +#: ../../po/../src/widgets/toolbox.cpp:1594 +msgid "Not rounded" +msgstr "Nem lekerekített" + +#: ../../po/../src/widgets/toolbox.cpp:1596 +msgid "Make corners sharp" +msgstr "A csúcsok szögletessé tétele" + +#: ../../po/../src/widgets/toolbox.cpp:1805 +msgid "Turns:" +msgstr "Fordulatok:" + +#: ../../po/../src/widgets/toolbox.cpp:1805 +msgid "Number of revolutions" +msgstr "A körbefordulások száma" + +#: ../../po/../src/widgets/toolbox.cpp:1815 +msgid "Divergence:" +msgstr "Tágulás:" + +#: ../../po/../src/widgets/toolbox.cpp:1815 +msgid "How much denser/sparser are outer revolutions; 1 = uniform" +msgstr "" +"Mennyivel sűrűbbek illetve ritkábbak a külső fordulatok; 1 = egyenletes" + +#: ../../po/../src/widgets/toolbox.cpp:1825 +msgid "Inner radius:" +msgstr "Belső sugár:" + +#: ../../po/../src/widgets/toolbox.cpp:1825 +msgid "Radius of the innermost revolution (relative to the spiral size)" +msgstr "A legbelső fordulat sugara (a spirál méretéhez viszonyítva)" + +#: ../../po/../src/widgets/toolbox.cpp:1957 +msgid "The width of the calligraphic pen (relative to the visible canvas area)" +msgstr "" +"A művészi toll szélessége (a látható rajzvászon-területhez viszonyítva)" + +#: ../../po/../src/widgets/toolbox.cpp:1967 +msgid "Thinning:" +msgstr "Keskenyítés:" + +#: ../../po/../src/widgets/toolbox.cpp:1967 +msgid "" +"How much velocity thins the stroke (> 0 makes fast strokes thinner, < 0 " +"makes them broader, 0 makes width independent of velocity)" +msgstr "" +"A sebesség mennyire keskenyíti a vonalat (ha 0-nál nagyobb az érték, akkor a " +"gyors vonalhúzás keskenyebb vonalat eredményez; ha 0-nál kisebb, akkor " +"szélesebbet; 0 esetén pedig nem függ a szélesség a sebességtől)" + +#: ../../po/../src/widgets/toolbox.cpp:1980 +msgid "Angle:" +msgstr "Szög:" + +#: ../../po/../src/widgets/toolbox.cpp:1980 +msgid "" +"The angle of the pen's nib (in degrees; 0 = horizontal; has no effect if " +"fixation = 0)" +msgstr "" +"A toll hegyének szöge (fokban; 0 fok esetén vízszintes; ha a rögzítettség " +"értéke 0, akkor nincs hatása)" + +#: ../../po/../src/widgets/toolbox.cpp:1990 +msgid "Fixation:" +msgstr "Rögzítettség:" + +#: ../../po/../src/widgets/toolbox.cpp:1990 +msgid "" +"How fixed is the pen angle (0 = always perpendicular to stroke direction, 1 " +"= fixed)" +msgstr "" +"Mennyire rögzített a toll szöge (0: mindig merőleges a vonalhúzás irányára, " +"1: rögzített)" + +#: ../../po/../src/widgets/toolbox.cpp:2003 +msgid "Mass:" +msgstr "Tömeg:" + +#: ../../po/../src/widgets/toolbox.cpp:2003 +msgid "How much inertia affects the movement of the pen" +msgstr "Mekkora tehetetlenség hat a toll mozgására" + +#. TRANSLATORS: "drag" means "resistance" here +#: ../../po/../src/widgets/toolbox.cpp:2014 +msgid "Drag:" +msgstr "Ellenállás:" + +#: ../../po/../src/widgets/toolbox.cpp:2014 +msgid "How much resistance affects the movement of the pen" +msgstr "Mekkora ellenállás hat a toll mozgására" + +#: ../../po/../src/widgets/toolbox.cpp:2034 +msgid "Use the pressure of the input device to alter the width of the pen" +msgstr "" +"A beviteli eszköz nyomásának használata a tollszélesség változtatásához" + +#: ../../po/../src/widgets/toolbox.cpp:2047 +msgid "Use the tilt of the input device to alter the angle of the pen's nib" +msgstr "" +"A beviteli eszköz dőlésének használata a tollhegy szögének változtatásához" + +#: ../../po/../src/widgets/toolbox.cpp:2374 +msgid "Start:" +msgstr "Kezdet:" + +#: ../../po/../src/widgets/toolbox.cpp:2374 +msgid "The angle (in degrees) from the horizontal to the arc's start point" +msgstr "Az ellipszisív kezdőpontjának szöge a vízszintestől számítva (fokban)" + +#: ../../po/../src/widgets/toolbox.cpp:2384 +msgid "End:" +msgstr "Vég:" + +#: ../../po/../src/widgets/toolbox.cpp:2384 +msgid "The angle (in degrees) from the horizontal to the arc's end point" +msgstr "Az ellipszisív végpontjának szöge a vízszintestől számítva (fokban)" + +#: ../../po/../src/widgets/toolbox.cpp:2395 +msgid "Open arc" +msgstr "Nyitott ellipszisív" + +#: ../../po/../src/widgets/toolbox.cpp:2396 +msgid "" +"Switch between arc (unclosed shape) and segment (closed shape with two radii)" +msgstr "" +"Váltás ellipszisív (nem lezárt alakzat) és -cikk (lezárt alakzat két " +"sugárral) közt" + +#: ../../po/../src/widgets/toolbox.cpp:2415 +msgid "Make whole" +msgstr "Kiegészítés" + +#: ../../po/../src/widgets/toolbox.cpp:2417 +msgid "Make the shape a whole ellipse, not arc or segment" +msgstr "Az alakzat teljes ellipszissé tétele (hogy ne ív illetve cikk legyen)" + +#: ../../po/../src/widgets/toolbox.cpp:2644 +msgid "" +"When pressed, picks visible color without alpha and when not pressed, picks " +"color including its alpha" +msgstr "" +"Amikor le van nyomva, akkor a látható színt olvassa le az átlátszóság " +"nélkül; amikor nincs lenyomva, akkor az átlátszósággal együtt olvassa azt le" + +#: ../../po/../src/widgets/toolbox.cpp:3039 +msgid "Make connectors avoid selected objects" +msgstr "A kapcsok kerüljék ki a kijelölt objektumokat" + +#: ../../po/../src/widgets/toolbox.cpp:3043 +msgid "Make connectors ignore selected objects" +msgstr "A kapcsok hagyják figyelmen kívül a kijelölt objektumokat" + +#. +#. 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 : +#: ../share/extensions/addnodes.inx.h:1 +#, fuzzy +msgid "Add Nodes" +msgstr "Csomópontok" + +#: ../share/extensions/addnodes.inx.h:2 +msgid "Maximum Segment Length" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:1 +msgid "AI Input" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:2 ../share/extensions/ai_output.inx.h:2 +msgid "Adobe Illustrator (*.ai)" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:3 +msgid "Open files saved with Adobe Illustrator" +msgstr "" + +#: ../share/extensions/ai_output.inx.h:1 +#, fuzzy +msgid "AI Output" +msgstr "Kimenet" + +#: ../share/extensions/ai_output.inx.h:3 +msgid "Write Adobe Illustrator" +msgstr "" + +#: ../share/extensions/dia.inx.h:1 +msgid "A diagram created with the program Dia" +msgstr "" + +#: ../share/extensions/dia.inx.h:2 +msgid "Dia Diagram (*.dia)" +msgstr "" + +#: ../share/extensions/dia.inx.h:3 +msgid "Dia Input" +msgstr "" + +#: ../share/extensions/dia.inx.h:4 +msgid "" +"In order to import Dia files, Dia itself must be installed. You can get Dia " +"at http://www.gnome.org/projects/dia/" +msgstr "" + +#: ../share/extensions/dia.inx.h:5 +msgid "" +"The dia2svg.sh script should be installed with your Inkscape distribution. " +"If you do not have it, there is likely to be something wrong with your " +"Inkscape installation." +msgstr "" + +#: ../share/extensions/dots.inx.h:1 +#, fuzzy +msgid "Connect the Dots" +msgstr "Kapocs" + +#: ../share/extensions/dots.inx.h:2 +#, fuzzy +msgid "Dot Size" +msgstr "Méret" + +#: ../share/extensions/dots.inx.h:3 +#, fuzzy +msgid "Font Size" +msgstr "Betűtípus-méret:" + +#: ../share/extensions/dropshadow.inx.h:1 +msgid "Color of shadow" +msgstr "" + +#: ../share/extensions/dropshadow.inx.h:2 +#, fuzzy +msgid "Dropshadow" +msgstr "Lap-árnyék megjelenítése" + +#: ../share/extensions/dxf_input.inx.h:1 +#: ../share/extensions/dxf_output.inx.h:1 +msgid "AutoCAD DXF (*.dxf)" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:2 +msgid "DXF Input" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:3 +msgid "Import AutoCAD's Document Exchange Format" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:4 +msgid "" +"dxf2svg may come with Inkscape, but is also at http://dxf-svg-convert." +"sourceforge.net/" +msgstr "" + +#: ../share/extensions/dxf_output.inx.h:2 +#, fuzzy +msgid "DXF Output" +msgstr "Kimenet" + +#: ../share/extensions/dxf_output.inx.h:3 +msgid "DXF file written by pstoedit" +msgstr "" + +#: ../share/extensions/dxf_output.inx.h:4 +msgid "pstoedit must be installed to run see http://www.pstoedit.net/pstoedit" +msgstr "" + +#: ../share/extensions/embedimage.inx.h:1 +#, fuzzy +msgid "Embed Images" +msgstr "Képek" + +#: ../share/extensions/eps_input.inx.h:1 +msgid "EPS Input" +msgstr "" + +#: ../share/extensions/eps_input.inx.h:2 +msgid "Encapsulated Postscript" +msgstr "" + +#: ../share/extensions/eps_input.inx.h:3 +msgid "Encapsulated Postscript (*.eps)" +msgstr "" + +#: ../share/extensions/epsi_output.inx.h:1 +#, fuzzy +msgid "EPSI Output" +msgstr "Kimenet" + +#: ../share/extensions/epsi_output.inx.h:2 +msgid "Encapsulated Postscript Interchange (*.epsi)" +msgstr "" + +#: ../share/extensions/epsi_output.inx.h:3 +msgid "Encapsulated Postscript with a thumbnail" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:1 ../share/extensions/ffms.inx.h:1 +#: ../share/extensions/ffset.inx.h:1 ../share/extensions/ffss.inx.h:1 +#, fuzzy +msgid "Bridge Width" +msgstr "Vonalszélesség" + +#: ../share/extensions/ffmet.inx.h:2 ../share/extensions/ffms.inx.h:2 +msgid "First String Length" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:3 +msgid "FretFind Multi Length ET" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:4 ../share/extensions/ffms.inx.h:4 +#: ../share/extensions/ffset.inx.h:3 ../share/extensions/ffss.inx.h:3 +msgid "Fretboard Edges" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:5 ../share/extensions/ffms.inx.h:5 +msgid "Last String Length" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:6 ../share/extensions/ffms.inx.h:6 +#: ../share/extensions/ffset.inx.h:4 ../share/extensions/ffss.inx.h:4 +#, fuzzy +msgid "Number of Frets" +msgstr "A sorok száma" + +#: ../share/extensions/ffmet.inx.h:7 ../share/extensions/ffms.inx.h:7 +#: ../share/extensions/ffset.inx.h:5 ../share/extensions/ffss.inx.h:5 +#, fuzzy +msgid "Number of Strings" +msgstr "A sorok száma" + +#: ../share/extensions/ffmet.inx.h:8 ../share/extensions/ffms.inx.h:8 +#: ../share/extensions/ffset.inx.h:6 ../share/extensions/ffss.inx.h:6 +#, fuzzy +msgid "Nut Width" +msgstr "Szélesség" + +#: ../share/extensions/ffmet.inx.h:9 ../share/extensions/ffms.inx.h:10 +msgid "Perpendicular Distance" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:10 ../share/extensions/ffset.inx.h:7 +msgid "Scale Base (2 for Octave)" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:11 ../share/extensions/ffset.inx.h:9 +msgid "Tones in Scale" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:12 ../share/extensions/ffms.inx.h:12 +#: ../share/extensions/ffset.inx.h:10 ../share/extensions/ffss.inx.h:10 +msgid "px per Unit" +msgstr "" + +#: ../share/extensions/ffms.inx.h:3 +msgid "FretFind Multi Length Scala" +msgstr "" + +#: ../share/extensions/ffms.inx.h:9 ../share/extensions/ffss.inx.h:7 +msgid "Path to Scala *.scl File" +msgstr "" + +#: ../share/extensions/ffms.inx.h:11 +msgid "Tuning (scale step for each string seperated by semicolons)" +msgstr "" + +#: ../share/extensions/ffset.inx.h:2 +msgid "FretFind Single Length ET" +msgstr "" + +#: ../share/extensions/ffset.inx.h:8 ../share/extensions/ffss.inx.h:8 +msgid "Scale Length" +msgstr "" + +#: ../share/extensions/ffss.inx.h:2 +msgid "FretFind Single Length Scala" +msgstr "" + +#: ../share/extensions/ffss.inx.h:9 +msgid "Tuning (Scale step for each string seperated by semicolons)" +msgstr "" + +#: ../share/extensions/handles.inx.h:1 +#, fuzzy +msgid "Draw Handles" +msgstr "Szabadkézi vonalak rajzolása" + +#: ../share/extensions/interp.inx.h:1 +#, fuzzy +msgid "Duplicate Endpaths" +msgstr "Csomópont kettőzése" + +#: ../share/extensions/interp.inx.h:2 +#, fuzzy +msgid "Exponent" +msgstr "Exportálás" + +#: ../share/extensions/interp.inx.h:3 +msgid "Interpolate" +msgstr "" + +#: ../share/extensions/interp.inx.h:4 +msgid "Interpolate Style (Experimental)" +msgstr "" + +#: ../share/extensions/interp.inx.h:5 +msgid "Interpolation Method" +msgstr "" + +#: ../share/extensions/interp.inx.h:6 +msgid "Interpolation Steps" +msgstr "" + +#: ../share/extensions/kochify.inx.h:1 +msgid "Kochify" +msgstr "" + +#: ../share/extensions/kochify_load.inx.h:1 +msgid "Kochify (Load)" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:1 +#, fuzzy +msgid "Angle" +msgstr "Szög:" + +#: ../share/extensions/lindenmayer.inx.h:2 +msgid "Axiom" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:3 +#, fuzzy +msgid "Lindenmayer" +msgstr "Réteg átnevezése" + +#: ../share/extensions/lindenmayer.inx.h:4 +msgid "Order" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:5 +#, fuzzy +msgid "Rules" +msgstr "_Vonalzók" + +#: ../share/extensions/lindenmayer.inx.h:6 +#, fuzzy +msgid "Step" +msgstr "Lépésközök" + +#: ../share/extensions/motion.inx.h:1 +#, fuzzy +msgid "Direction" +msgstr "Leírás" + +#: ../share/extensions/motion.inx.h:2 +#, fuzzy +msgid "Magnitude" +msgstr "Bíbor" + +#: ../share/extensions/motion.inx.h:3 +#, fuzzy +msgid "Motion" +msgstr "_Forgatás" + +#: ../share/extensions/pdf_output.inx.h:1 +msgid "Adobe PDF (*.pdf)" +msgstr "" + +#: ../share/extensions/pdf_output.inx.h:2 +msgid "Adobe Portable Document Format" +msgstr "" + +#: ../share/extensions/pdf_output.inx.h:3 +#, fuzzy +msgid "PDF Output" +msgstr "Kimenet" + +#: ../share/extensions/ps_input.inx.h:1 +#, fuzzy +msgid "Postscript" +msgstr "Álló" + +#: ../share/extensions/ps_input.inx.h:2 +msgid "Postscript (*.ps)" +msgstr "" + +#: ../share/extensions/ps_input.inx.h:3 +msgid "Postscript Input" +msgstr "" + +#: ../share/extensions/radiusrand.inx.h:1 +#, fuzzy +msgid "Radius" +msgstr "E_lőrébb helyezés" + +# TODO: ellenőrizni +#: ../share/extensions/radiusrand.inx.h:2 +#, fuzzy +msgid "Radius Randomize" +msgstr "Véletlenszerűség:" + +#: ../share/extensions/radiusrand.inx.h:3 +msgid "Randomize Control Points" +msgstr "" + +# TODO: ellenőrizni +#: ../share/extensions/radiusrand.inx.h:4 +#, fuzzy +msgid "Randomize Nodes" +msgstr "Véletlenszerűség:" + +#: ../share/extensions/rtree.inx.h:1 +#, fuzzy +msgid "Initial Size" +msgstr "Bitkép mérete" + +#: ../share/extensions/rtree.inx.h:2 +msgid "Minimum Size" +msgstr "" + +# TODO: ellenőrizni +#: ../share/extensions/rtree.inx.h:3 +#, fuzzy +msgid "Random Tree" +msgstr "Véletlenszerűség:" + +#: ../share/extensions/sk_input.inx.h:1 +msgid "A diagram created with the program Sketch" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:2 +msgid "Sketch Diagram (*.sk)" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:3 +msgid "Sketch Input" +msgstr "" + +#: ../share/extensions/straightseg.inx.h:1 +msgid "Behavior" +msgstr "" + +#: ../share/extensions/straightseg.inx.h:3 +msgid "Segment Straightener" +msgstr "" + +#: ../share/extensions/summersnight.inx.h:1 +msgid "Summer's Night" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:1 +#: ../share/extensions/svgz_output.inx.h:1 +msgid "Compressed Inkscape SVG (*.svgz)" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:2 +#: ../share/extensions/svgz_output.inx.h:2 +msgid "Inkscape's native file format compressed with GZip" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:3 +msgid "SVGZ Input" +msgstr "" + +#: ../share/extensions/svgz_output.inx.h:3 +#, fuzzy +msgid "SVGZ Output" +msgstr "Kimenet" + +#: ../share/extensions/txt2svg.inx.h:1 +msgid "ASCII Text" +msgstr "" + +#: ../share/extensions/txt2svg.inx.h:2 +msgid "Text File (*.txt)" +msgstr "" + +#: ../share/extensions/txt2svg.inx.h:3 +msgid "Text Input" +msgstr "" + +#: ../share/extensions/wavy.inx.h:1 +msgid "Calculate first derivative numerically" +msgstr "" + +#: ../share/extensions/wavy.inx.h:2 +msgid "First derivative" +msgstr "" + +#: ../share/extensions/wavy.inx.h:3 +msgid "Function" +msgstr "" + +#: ../share/extensions/wavy.inx.h:4 +msgid "Function Plotter" +msgstr "" + +#: ../share/extensions/wavy.inx.h:5 +msgid "Nodes per period" +msgstr "" + +#: ../share/extensions/wavy.inx.h:6 +msgid "Periods (2*Pi each)" +msgstr "" + +#: ../share/extensions/whirl.inx.h:1 +msgid "Amount of Whirl" +msgstr "" + +#: ../share/extensions/whirl.inx.h:2 +#, fuzzy +msgid "Center X" +msgstr "Sorok igazítása középre" + +#: ../share/extensions/whirl.inx.h:3 +#, fuzzy +msgid "Center Y" +msgstr "Sorok igazítása középre" + +#: ../share/extensions/whirl.inx.h:4 +#, fuzzy +msgid "Direction of Rotation" +msgstr "Meghívás elutasítása" + +#: ../share/extensions/whirl.inx.h:5 +msgid "Whirl" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:1 +msgid "A popular graphics file format for clipart" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:2 +msgid "Windows Metafile (*.wmf)" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:3 +msgid "Windows Metafile Input" +msgstr "" + +#~ msgid "Custom canvas" +#~ msgstr "Egyéni rajzvászon" + +#~ msgid "Current style" +#~ msgstr "Aktuális stílus" + +#~ msgid "" +#~ "Current style is updated every time you change the style of any object " +#~ "(its fill, stroke, transparency, etc.)" +#~ msgstr "" +#~ "Az aktuális stílus minden objektum stílusának (kitöltés, körvonal, " +#~ "átlátszóság, ...) minden módosításakor frissítésre kerül" + +#~ msgid "Arrange Objects" +#~ msgstr "Objektumok elrendezése" + +#~ msgid "deg" +#~ msgstr "fok" + +#~ msgid "" +#~ "%s is not a valid preferences file.\n" +#~ "%s" +#~ msgstr "" +#~ "A(z) %s nem egy érvényes beállításfájl.\n" +#~ "%s" + +#~ msgid "" +#~ "Inkscape will run with default settings.\n" +#~ "New settings will not be saved." +#~ msgstr "" +#~ "Az Inkscape az alapértelmezett beállításokat fogja használni.\n" +#~ "Az új beállítások nem kerülnek mentésre." + +#~ msgid "_Credits" +#~ msgstr "_Közreműködők" + +#~ msgid "Grab sensitivity" +#~ msgstr "Megfogási érzékenység" + +#~ msgid "Click/drag threshold" +#~ msgstr "Kattintás/húzás határa" + +#~ msgid "Mouse wheel scrolls by" +#~ msgstr "Az egérgörgő görgetési mértéke" + +#~ msgid "Scroll by" +#~ msgstr "Görgetési mérték" + +#~ msgid "Acceleration" +#~ msgstr "Gyorsítás" + +#~ msgid "Speed" +#~ msgstr "Sebesség" + +#~ msgid "Threshold" +#~ msgstr "Küszöb" + +#~ msgid "Arrow keys move by" +#~ msgstr "A nyílbillentyűk elmozdítási mértéke" + +#~ msgid "> and < scale by" +#~ msgstr "A \">\" és a \"<\" billentyű méretezési mértéke" + +#~ msgid "Inset/Outset by" +#~ msgstr "Zsugorítás/nyújtás mértéke" + +#~ msgid "Rotation snaps every" +#~ msgstr "Az elforgatás lépésköze" + +#~ msgid "Zoom in/out by" +#~ msgstr "Nagyítás/kicsinyítés mértéke" + +#~ msgid "Transform" +#~ msgstr "Transzformáció" diff --git a/po/it.po b/po/it.po new file mode 100644 index 000000000..9891753bb --- /dev/null +++ b/po/it.po @@ -0,0 +1,9615 @@ +# Italian translation of inkscape. +# Copyright (C) 2000, 2001, 2002, 2005 Free Software Foundation, Inc. +# This file is distributed under the same license as the inkscape package. +# Brisa Francesco , 2000. +# Alessio Frusciante , 2002, 2003. +# Luca Bruno , 2005. +# Luca Ferretti , 2005 +# +msgid "" +msgstr "" +"Project-Id-Version: 0.43\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2005-12-04 11:51-0800\n" +"PO-Revision-Date: 2005-11-07 18:27+0100\n" +"Last-Translator: Luca Bruno >\n" +"Language-Team: Italian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: ../inkscape.desktop.in.h:1 +msgid "Create and edit Scalable Vector Graphics images" +msgstr "Crea e modifica immagini Scalable Vector Graphics" + +#: ../inkscape.desktop.in.h:2 +msgid "Inkscape SVG Vector Illustrator" +msgstr "Inkscape Illustratore Vettoriale SVG" + +#: ../../po/../src/arc-context.cpp:350 +msgid "" +"Ctrl: make circle or integer-ratio ellipse, snap arc/segment angle" +msgstr "" +"Ctrl: disegna cerchi o ellissi in scala, fa scattare gli angoli di " +"archi/segmenti" + +#: ../../po/../src/arc-context.cpp:351 ../../po/../src/rect-context.cpp:388 +msgid "Shift: draw around the starting point" +msgstr "Maiusc: disegna attorno al punto iniziale" + +#: ../../po/../src/arc-context.cpp:413 +#: ../../po/../src/connector-context.cpp:493 +#: ../../po/../src/dyna-draw-context.cpp:506 +#: ../../po/../src/pen-context.cpp:329 ../../po/../src/pencil-context.cpp:208 +#: ../../po/../src/rect-context.cpp:452 ../../po/../src/spiral-context.cpp:421 +#: ../../po/../src/star-context.cpp:427 +msgid "Current layer is hidden. Unhide it to be able to draw on it." +msgstr "" +"Il livello attuale è nascosto. Per potervi disegnare occorre " +"mostrarlo." + +#: ../../po/../src/arc-context.cpp:417 +#: ../../po/../src/connector-context.cpp:497 +#: ../../po/../src/dyna-draw-context.cpp:510 +#: ../../po/../src/pen-context.cpp:336 ../../po/../src/pencil-context.cpp:212 +#: ../../po/../src/rect-context.cpp:456 ../../po/../src/spiral-context.cpp:426 +#: ../../po/../src/star-context.cpp:431 +msgid "Current layer is locked. Unlock it to be able to draw on it." +msgstr "" +"Il livello attuale è bloccato. Per potervi disegnare occorre " +"sbloccarlo." + +#: ../../po/../src/arc-context.cpp:496 +#, c-format +msgid "" +"Ellipse: %s × %s; with Ctrl to make circle or integer-" +"ratio ellipse; with Shift to draw around the starting point" +msgstr "" +"Ellisse: %s × %s; con Ctrl per fare cerchi o elissi in " +"scala; con Maiusc per disegnare attorno al punto iniziale" + +#: ../../po/../src/connector-context.cpp:518 +msgid "Creating new connector" +msgstr "Creazione nuovo connettore" + +#: ../../po/../src/connector-context.cpp:939 +msgid "Finishing connector" +msgstr "Terminazione connettore" + +#: ../../po/../src/connector-context.cpp:1108 +msgid "Connection point: click or drag to create a new connector" +msgstr "" +"Punto di connessione: fare clic o trascinare per creare una nuovo " +"connettore" + +#: ../../po/../src/connector-context.cpp:1185 +msgid "Connector endpoint: drag to reroute or connect to new shapes" +msgstr "" +"Punto finale connettore: trascinare per ritracciare o connettere a " +"nuove forme" + +#: ../../po/../src/connector-context.cpp:1278 +msgid "Select at least one non-connector object." +msgstr "Selezionare almeno un oggetto non-connettore." + +#: ../../po/../src/desktop-events.cpp:238 +#, c-format +msgid "%s at %s" +msgstr "%s in %s" + +#. TRANSLATORS: This string appears when double-clicking on a guide. +#. This is the distance by which the guide is to be moved. +#: ../../po/../src/desktop-events.cpp:277 +msgid " relative by " +msgstr " in modo relativo a " + +#. TRANSLATORS: This string appears when double-clicking on a guide. +#. This is the target location where the guide is to be moved. +#: ../../po/../src/desktop-events.cpp:282 +#: ../../po/../src/desktop-events.cpp:395 +msgid " absolute to " +msgstr " in modo assoluto a " + +#. create dialog +#: ../../po/../src/desktop-events.cpp:348 +msgid "Guideline" +msgstr "Linea guida" + +#: ../../po/../src/desktop-events.cpp:432 +#, c-format +msgid "Move %s" +msgstr "Sposta %s" + +#: ../../po/../src/desktop.cpp:678 +msgid "No previous zoom." +msgstr "Nessuno zoom precedente." + +#: ../../po/../src/desktop.cpp:703 +msgid "No next zoom." +msgstr "Nessuno zoom successivo." + +#: ../../po/../src/dialogs/clonetiler.cpp:182 +msgid "Nothing selected." +msgstr "Nessuna selezione." + +#: ../../po/../src/dialogs/clonetiler.cpp:188 +msgid "More than one object selected." +msgstr "Più di un elemento selezionato." + +#: ../../po/../src/dialogs/clonetiler.cpp:195 +#, c-format +msgid "Object has %d tiled clones." +msgstr "L'oggetto ha %d cloni in serie. " + +#: ../../po/../src/dialogs/clonetiler.cpp:200 +msgid "Object has no tiled clones." +msgstr "L'oggetto non ha cloni in serie." + +#: ../../po/../src/dialogs/clonetiler.cpp:865 +msgid "Select one object whose tiled clones to unclump." +msgstr "Selezionare un oggetto di cui sparpagliare i cloni in serie." + +#: ../../po/../src/dialogs/clonetiler.cpp:916 +msgid "Select one object whose tiled clones to remove." +msgstr "Selezionare un oggetto da cui rimuovere i cloni in serie" + +#: ../../po/../src/dialogs/clonetiler.cpp:984 +#: ../../po/../src/selection-chemistry.cpp:1774 +msgid "Select an object to clone." +msgstr "Selezionare un oggetto da clonare." + +#: ../../po/../src/dialogs/clonetiler.cpp:990 +#: ../../po/../src/selection-chemistry.cpp:1780 +msgid "" +"If you want to clone several objects, group them and clone the " +"group." +msgstr "" +"Se si vogliono clonare diversi oggetti, bisogna raggrupparli e " +"clonare il gruppo." + +#: ../../po/../src/dialogs/clonetiler.cpp:1484 +msgid "Per row:" +msgstr "Per riga:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1497 +msgid "Per column:" +msgstr "Per colonna:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1505 +msgid "Randomize:" +msgstr "Casualità:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1656 +msgid "_Symmetry" +msgstr "_Simmetria" + +#. TRANSLATORS: For the following 17 symmetry groups, see +#. * http://www.bib.ulb.ac.be/coursmath/doc/17.htm (visual examples); +#. * http://www.clarku.edu/~djoyce/wallpaper/seventeen.html (English vocabulary); or +#. * http://membres.lycos.fr/villemingerard/Geometri/Sym1D.htm (French vocabulary). +#. +#: ../../po/../src/dialogs/clonetiler.cpp:1664 +msgid "Select one of the 17 symmetry groups for the tiling" +msgstr "Selezionare uno dei 17 gruppi di simmetria per il riempimento" + +#. TRANSLATORS: "translation" means "shift" / "displacement" here. +#: ../../po/../src/dialogs/clonetiler.cpp:1675 +msgid "P1: simple translation" +msgstr "P1: traslazione semplice" + +#: ../../po/../src/dialogs/clonetiler.cpp:1676 +msgid "P2: 180° rotation" +msgstr "P2: rotazione 180°" + +#: ../../po/../src/dialogs/clonetiler.cpp:1677 +msgid "PM: reflection" +msgstr "PM: riflessione" + +#. TRANSLATORS: "glide reflection" is a reflection and a translation combined. +#. For more info, see http://mathforum.org/sum95/suzanne/symsusan.html +#: ../../po/../src/dialogs/clonetiler.cpp:1680 +msgid "PG: glide reflection" +msgstr "PG: riflessione scorrevole" + +#: ../../po/../src/dialogs/clonetiler.cpp:1681 +msgid "CM: reflection + glide reflection" +msgstr "CM: riflessione + riflessione scorrevole" + +#: ../../po/../src/dialogs/clonetiler.cpp:1682 +msgid "PMM: reflection + reflection" +msgstr "PMM: riflessione + riflessione" + +#: ../../po/../src/dialogs/clonetiler.cpp:1683 +msgid "PMG: reflection + 180° rotation" +msgstr "PMG: riflessione + rotazione 180°" + +#: ../../po/../src/dialogs/clonetiler.cpp:1684 +msgid "PGG: glide reflection + 180° rotation" +msgstr "PGG: riflessione scorrevole + rotazione 180°" + +#: ../../po/../src/dialogs/clonetiler.cpp:1685 +msgid "CMM: reflection + reflection + 180° rotation" +msgstr "CMM: riflessione + riflessione + rotazione 180°" + +#: ../../po/../src/dialogs/clonetiler.cpp:1686 +msgid "P4: 90° rotation" +msgstr "P4: rotazione 90°" + +#: ../../po/../src/dialogs/clonetiler.cpp:1687 +msgid "P4M: 90° rotation + 45° reflection" +msgstr "P4M: rotazione 90° + riflessione 45°" + +#: ../../po/../src/dialogs/clonetiler.cpp:1688 +msgid "P4G: 90° rotation + 90° reflection" +msgstr "P4G: rotazione 90° + riflessione 90°" + +#: ../../po/../src/dialogs/clonetiler.cpp:1689 +msgid "P3: 120° rotation" +msgstr "P3: rotazione 120°" + +#: ../../po/../src/dialogs/clonetiler.cpp:1690 +msgid "P31M: reflection + 120° rotation, dense" +msgstr "P31M: riflessione + rotazione 120°, denso" + +#: ../../po/../src/dialogs/clonetiler.cpp:1691 +msgid "P3M1: reflection + 120° rotation, sparse" +msgstr "P3M1: riflessione + rotazione 120°, rado" + +#: ../../po/../src/dialogs/clonetiler.cpp:1692 +msgid "P6: 60° rotation" +msgstr "P6: rotazione 60°" + +#: ../../po/../src/dialogs/clonetiler.cpp:1693 +msgid "P6M: reflection + 60° rotation" +msgstr "P6M: riflessione + rotazione 60°" + +#: ../../po/../src/dialogs/clonetiler.cpp:1721 +msgid "S_hift" +msgstr "Spos_tamento" + +#. TRANSLATORS: "shift" means: the tiles will be shifted (offset) horizontally by this amount +#: ../../po/../src/dialogs/clonetiler.cpp:1731 +#, no-c-format +msgid "Shift X:" +msgstr "Spostamento X:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1739 +#, no-c-format +msgid "Horizontal shift per row (in % of tile width)" +msgstr "" +"Lo spostamento orizzontale per ogni riga (in % sulla larghezza del clone)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1747 +#, no-c-format +msgid "Horizontal shift per column (in % of tile width)" +msgstr "" +"Lo spostamento orizzontale per ogni colonna (in % sulla larghezza del clone)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1754 +msgid "Randomize the horizontal shift by this percentage" +msgstr "Rende casuale di questa percentuale lo spostamento orizzontale" + +#. TRANSLATORS: "shift" means: the tiles will be shifted (offset) vertically by this amount +#: ../../po/../src/dialogs/clonetiler.cpp:1764 +#, no-c-format +msgid "Shift Y:" +msgstr "Spostamento Y:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1772 +#, no-c-format +msgid "Vertical shift per row (in % of tile height)" +msgstr "Lo spostamento verticale per ogni riga (in % sull'altezza del clone)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1780 +#, no-c-format +msgid "Vertical shift per column (in % of tile height)" +msgstr "" +"Lo spostamento verticale per ogni colonna (in % sull'altezza del clone)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1787 +msgid "Randomize the vertical shift by this percentage" +msgstr "Rende casuale di questa percentuale lo spostamento verticale" + +#: ../../po/../src/dialogs/clonetiler.cpp:1795 +msgid "Exponent:" +msgstr "Esponente:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1802 +msgid "Whether rows are spaced evenly (1), converge (<1) or diverge (>1)" +msgstr "" +"Specifica se le righe sono a spaziatura costante (1), convergenti (<1) o " +"divergenti (<1)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1809 +msgid "Whether columns are spaced evenly (1), converge (<1) or diverge (>1)" +msgstr "" +"Specifica se le colonne sono a spaziatura costante (1), convergenti (<1) o " +"divergenti (<1)" + +#. TRANSLATORS: "Alternate" is a verb here +#: ../../po/../src/dialogs/clonetiler.cpp:1817 +#: ../../po/../src/dialogs/clonetiler.cpp:1907 +#: ../../po/../src/dialogs/clonetiler.cpp:1966 +#: ../../po/../src/dialogs/clonetiler.cpp:2022 +#: ../../po/../src/dialogs/clonetiler.cpp:2153 +msgid "Alternate:" +msgstr "Alterna:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1823 +msgid "Alternate the sign of shifts for each row" +msgstr "Alterna il segno dello spostamento per ogni riga" + +#: ../../po/../src/dialogs/clonetiler.cpp:1828 +msgid "Alternate the sign of shifts for each column" +msgstr "Alterna il segno dello spostamento per ogni colonna" + +#: ../../po/../src/dialogs/clonetiler.cpp:1837 +msgid "Sc_ale" +msgstr "Sc_ala" + +#: ../../po/../src/dialogs/clonetiler.cpp:1845 +msgid "Scale X:" +msgstr "Scala X:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1853 +#, no-c-format +msgid "Horizontal scale per row (in % of tile width)" +msgstr "" +"Il ridimensionamento orizzontale per ogni riga (in % sulla larghezza del " +"clone)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1861 +#, no-c-format +msgid "Horizontal scale per column (in % of tile width)" +msgstr "" +"Il ridimensionamento orizzontale per ogni colonna (in % sulla larghezza del " +"clone)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1868 +msgid "Randomize the horizontal scale by this percentage" +msgstr "Rende casuale di questa percentuale il ridimensionamento orizzontale" + +#: ../../po/../src/dialogs/clonetiler.cpp:1876 +msgid "Scale Y:" +msgstr "Scala Y:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1884 +#, no-c-format +msgid "Vertical scale per row (in % of tile height)" +msgstr "" +"Il ridimensionamento verticale per ogni riga (in % sulla larghezza del clone)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1892 +#, no-c-format +msgid "Vertical scale per column (in % of tile height)" +msgstr "" +"I ridimensionamento verticale per ogni colonna (in % sulla larghezza del " +"clone)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1899 +msgid "Randomize the vertical scale by this percentage" +msgstr "Rende casuale di questa percentuale il ridimensionamento verticale" + +#: ../../po/../src/dialogs/clonetiler.cpp:1913 +msgid "Alternate the sign of scales for each row" +msgstr "Alterna il segno del ridimensionamento per ogni riga" + +#: ../../po/../src/dialogs/clonetiler.cpp:1918 +msgid "Alternate the sign of scales for each column" +msgstr "Alterna il segno del ridimensionamento per ogni colonna" + +#: ../../po/../src/dialogs/clonetiler.cpp:1927 +msgid "_Rotation" +msgstr "_Rotazione" + +#: ../../po/../src/dialogs/clonetiler.cpp:1935 +msgid "Angle:" +msgstr "Angolo:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1943 +#, no-c-format +msgid "Rotate tiles by this angle for each row" +msgstr "Ruota i cloni di questo angolo per ogni riga" + +#: ../../po/../src/dialogs/clonetiler.cpp:1951 +#, no-c-format +msgid "Rotate tiles by this angle for each column" +msgstr "Ruota i cloni di questo angolo per ogni colonna" + +#: ../../po/../src/dialogs/clonetiler.cpp:1958 +msgid "Randomize the rotation angle by this percentage" +msgstr "Rende casuale di questa percentuale l'angolo di rotazione" + +#: ../../po/../src/dialogs/clonetiler.cpp:1972 +msgid "Alternate the rotation direction for each row" +msgstr "Alterna la direzione della rotazione per ogni riga" + +#: ../../po/../src/dialogs/clonetiler.cpp:1977 +msgid "Alternate the rotation direction for each column" +msgstr "Alterna la direzione della rotazione per ogni colonna" + +#: ../../po/../src/dialogs/clonetiler.cpp:1985 +msgid "_Opacity" +msgstr "_Opacità" + +#: ../../po/../src/dialogs/clonetiler.cpp:1993 +msgid "Fade out:" +msgstr "Sfocatura" + +#: ../../po/../src/dialogs/clonetiler.cpp:2000 +msgid "Decrease tile opacity by this percentage for each row" +msgstr "Riduce di questa percentuale per ogni riga l'opacità dei cloni" + +#: ../../po/../src/dialogs/clonetiler.cpp:2007 +msgid "Decrease tile opacity by this percentage for each column" +msgstr "Riduce di questa percentuale per ogni colonna l'opacità dei cloni" + +#: ../../po/../src/dialogs/clonetiler.cpp:2014 +msgid "Randomize the tile opacity by this percentage" +msgstr "Rende casuale di questa percentuale l'opacità dei cloni" + +#: ../../po/../src/dialogs/clonetiler.cpp:2028 +msgid "Alternate the sign of opacity change for each row" +msgstr "Alterna il segno del valore di opacità per ogni riga" + +#: ../../po/../src/dialogs/clonetiler.cpp:2033 +msgid "Alternate the sign of opacity change for each column" +msgstr "Alterna il segno del valore di opacità per ogni colonna" + +#: ../../po/../src/dialogs/clonetiler.cpp:2041 +msgid "Co_lor" +msgstr "Co_lore" + +#: ../../po/../src/dialogs/clonetiler.cpp:2046 +msgid "Initial color: " +msgstr "Colore iniziale: " + +#: ../../po/../src/dialogs/clonetiler.cpp:2050 +msgid "Initial color of tiled clones" +msgstr "Colore iniziale dei cloni in serie" + +#: ../../po/../src/dialogs/clonetiler.cpp:2050 +msgid "" +"Initial color for clones (works only if the original has unset fill or " +"stroke)" +msgstr "" +"Colore iniziale dei cloni (funziona solo se l'originale non possiede " +"riempimenti o bordi)" + +#: ../../po/../src/dialogs/clonetiler.cpp:2065 +msgid "H:" +msgstr "H:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2072 +msgid "Change the tile hue by this percentage for each row" +msgstr "Cambia di questa percentuale per ogni riga l'opacità dei cloni" + +#: ../../po/../src/dialogs/clonetiler.cpp:2079 +msgid "Change the tile hue by this percentage for each column" +msgstr "Cambia di questa percentuale per ogni colonna l'opacità dei cloni" + +#: ../../po/../src/dialogs/clonetiler.cpp:2086 +msgid "Randomize the tile hue by this percentage" +msgstr "Rende casuale di questa percentuale l'opacità del clone" + +#: ../../po/../src/dialogs/clonetiler.cpp:2095 +msgid "S:" +msgstr "S:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2102 +msgid "Change the color saturation by this percentage for each row" +msgstr "Cambia di questa percentuale per ogni riga la saturazione del colore" + +#: ../../po/../src/dialogs/clonetiler.cpp:2109 +msgid "Change the color saturation by this percentage for each column" +msgstr "" +"Cambia di questa percentuale per ogni colonna la saturazione del colore" + +#: ../../po/../src/dialogs/clonetiler.cpp:2116 +msgid "Randomize the color saturation by this percentage" +msgstr "Rende casuale di questa percentuale la saturazione del clone" + +#: ../../po/../src/dialogs/clonetiler.cpp:2124 +msgid "L:" +msgstr "L:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2131 +msgid "Change the color lightness by this percentage for each row" +msgstr "Riduce di questa percentuale per ogni riga la luminosità dei cloni" + +#: ../../po/../src/dialogs/clonetiler.cpp:2138 +msgid "Change the color lightness by this percentage for each column" +msgstr "Riduce di questa percentuale per ogni colonna la luminosità dei cloni" + +#: ../../po/../src/dialogs/clonetiler.cpp:2145 +msgid "Randomize the color lightness by this percentage" +msgstr "Rende casuale di questa percentuale la luminosità del clone" + +#: ../../po/../src/dialogs/clonetiler.cpp:2159 +msgid "Alternate the sign of color changes for each row" +msgstr "Alterna il segno del valore di cambiamento del valore per ogni riga" + +#: ../../po/../src/dialogs/clonetiler.cpp:2164 +msgid "Alternate the sign of color changes for each column" +msgstr "Alterna il segno del valore di cambiamento del valore per ogni riga" + +#: ../../po/../src/dialogs/clonetiler.cpp:2172 +msgid "_Trace" +msgstr "Ve_ttorizza" + +#: ../../po/../src/dialogs/clonetiler.cpp:2179 +msgid "Trace the drawing under the tiles" +msgstr "Vettorizza il disegno sotto i cloni" + +#: ../../po/../src/dialogs/clonetiler.cpp:2183 +msgid "" +"For each clone, pick a value from the drawing in that clone's location and " +"apply it to the clone" +msgstr "" +"Per ogni clone preleva il valore del disegno su cui il clone è posto e lo " +"applica al clone" + +#: ../../po/../src/dialogs/clonetiler.cpp:2197 +msgid "1. Pick from the drawing:" +msgstr "1. Preleva dal disegno:" + +#. ----Hbox2 +#: ../../po/../src/dialogs/clonetiler.cpp:2208 +#: ../../po/../src/dialogs/clonetiler.cpp:2355 +#: ../../po/../src/ui/dialog/tracedialog.cpp:445 +msgid "Color" +msgstr "Colore" + +#: ../../po/../src/dialogs/clonetiler.cpp:2209 +msgid "Pick the visible color and opacity" +msgstr "Preleva il colore visibile e l'opacità" + +#: ../../po/../src/dialogs/clonetiler.cpp:2216 +#: ../../po/../src/dialogs/clonetiler.cpp:2365 +#: ../share/extensions/dropshadow.inx.h:3 +msgid "Opacity" +msgstr "Opacità" + +#: ../../po/../src/dialogs/clonetiler.cpp:2217 +msgid "Pick the total accumulated opacity" +msgstr "Preleva l'opacità accumulata totale" + +#: ../../po/../src/dialogs/clonetiler.cpp:2224 +msgid "R" +msgstr "R" + +#: ../../po/../src/dialogs/clonetiler.cpp:2225 +msgid "Pick the Red component of the color" +msgstr "Preleva la componente Rossa del colore" + +#: ../../po/../src/dialogs/clonetiler.cpp:2232 +msgid "G" +msgstr "G" + +#: ../../po/../src/dialogs/clonetiler.cpp:2233 +msgid "Pick the Green component of the color" +msgstr "Preleva la componente Verde del colore" + +#: ../../po/../src/dialogs/clonetiler.cpp:2240 +msgid "B" +msgstr "B" + +#: ../../po/../src/dialogs/clonetiler.cpp:2241 +msgid "Pick the Blue component of the color" +msgstr "Preleva la componente Blu del colore" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2250 +msgid "clonetiler|H" +msgstr "H" + +#: ../../po/../src/dialogs/clonetiler.cpp:2251 +msgid "Pick the hue of the color" +msgstr "Preleva l'opacità del colore" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2260 +msgid "clonetiler|S" +msgstr "S" + +#: ../../po/../src/dialogs/clonetiler.cpp:2261 +msgid "Pick the saturation of the color" +msgstr "Preleva la saturazione del colore" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2270 +msgid "clonetiler|L" +msgstr "L" + +#: ../../po/../src/dialogs/clonetiler.cpp:2271 +msgid "Pick the lightness of the color" +msgstr "Preleva la luminosità del colore" + +#: ../../po/../src/dialogs/clonetiler.cpp:2281 +msgid "2. Tweak the picked value:" +msgstr "2. Corregge il valore prelevato:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2291 +msgid "Gamma-correct:" +msgstr "Correzione-gamma:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2296 +msgid "Shift the mid-range of the picked value upwards (>0) or downwards (<0)" +msgstr "" +"Sposta l'intervallo medio del valore prelevato verso l'alto (>0) o verso il " +"basso (<0)" + +#: ../../po/../src/dialogs/clonetiler.cpp:2303 +msgid "Randomize:" +msgstr "Casualità:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2308 +msgid "Randomize the picked value by this percentage" +msgstr "Rende casuale di questa percentuale il valore prelevato" + +#: ../../po/../src/dialogs/clonetiler.cpp:2315 +msgid "Invert:" +msgstr "Inverti:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2319 +msgid "Invert the picked value" +msgstr "Inverti il valore prelevato" + +#: ../../po/../src/dialogs/clonetiler.cpp:2325 +msgid "3. Apply the value to the clones':" +msgstr "3. Applica il valore prelevato ai cloni:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2335 +msgid "Presence" +msgstr "Presenza" + +#: ../../po/../src/dialogs/clonetiler.cpp:2338 +msgid "" +"Each clone is created with the probability determined by the picked value in " +"that point" +msgstr "" +"Ogni clone viene creato con la probabilità determinata dal valore prelevato " +"in quel punto" + +#: ../../po/../src/dialogs/clonetiler.cpp:2345 +msgid "Size" +msgstr "Dimensione" + +#: ../../po/../src/dialogs/clonetiler.cpp:2348 +msgid "Each clone's size is determined by the picked value in that point" +msgstr "" +"La dimensione di ogni clone è determinata dal valore preso in quel punto" + +#: ../../po/../src/dialogs/clonetiler.cpp:2358 +msgid "" +"Each clone is painted by the picked color (the original must have unset fill " +"or stroke)" +msgstr "" +"Ogni clone è colorato col colore prelevato (l'originale non deve avere " +"riempimento o bordo)" + +#: ../../po/../src/dialogs/clonetiler.cpp:2368 +msgid "Each clone's opacity is determined by the picked value in that point" +msgstr "L'opacità di ogni clone è determinata dal valore preso in quel punto" + +#: ../../po/../src/dialogs/clonetiler.cpp:2395 +msgid "How many rows in the tiling" +msgstr "Il numero di righe della serie" + +#: ../../po/../src/dialogs/clonetiler.cpp:2415 +msgid "How many columns in the tiling" +msgstr "Il numero di colonne della serie" + +#: ../../po/../src/dialogs/clonetiler.cpp:2445 +msgid "Width of the rectangle to be filled" +msgstr "Larghezza del rettangolo da riempire" + +#: ../../po/../src/dialogs/clonetiler.cpp:2470 +msgid "Height of the rectangle to be filled" +msgstr "Altezza del rettangolo da riempire" + +#: ../../po/../src/dialogs/clonetiler.cpp:2485 +msgid "Rows, columns: " +msgstr "Righe, colonne: " + +#: ../../po/../src/dialogs/clonetiler.cpp:2486 +msgid "Create the specified number of rows and columns" +msgstr "Crea il numero specificato di righe e colonne" + +#: ../../po/../src/dialogs/clonetiler.cpp:2495 +msgid "Width, height: " +msgstr "Larghezza, altezza: " + +#: ../../po/../src/dialogs/clonetiler.cpp:2496 +msgid "Fill the specified width and height with the tiling" +msgstr "Riempie la larghezza e l'altezza specificata con i cloni" + +#: ../../po/../src/dialogs/clonetiler.cpp:2512 +msgid "Use saved size and position of the tile" +msgstr "Usa la dimensione e la posizione salvata per la serie" + +#: ../../po/../src/dialogs/clonetiler.cpp:2515 +msgid "" +"Pretend that the size and position of the tile are the same as the last time " +"you tiled it (if any), instead of using the current size" +msgstr "" +"Forza la dimensione e la posizione del clone all'ultima clonazione salvata, " +"invece di usare le dimensioni attuali" + +#: ../../po/../src/dialogs/clonetiler.cpp:2539 +msgid " _Create " +msgstr " _Crea " + +#: ../../po/../src/dialogs/clonetiler.cpp:2541 +msgid "Create and tile the clones of the selection" +msgstr "Crea e serializza i cloni della selezione" + +#. TRANSLATORS: if a group of objects are "clumped" together, then they +#. are unevenly spread in the given amount of space - as shown in the +#. diagrams on the left in the following screenshot: +#. http://www.inkscape.org/screenshots/gallery/inkscape-0.42-CVS-tiles-unclump.png +#. So unclumping is the process of spreading a number of objects out more evenly. +#: ../../po/../src/dialogs/clonetiler.cpp:2556 +msgid " _Unclump " +msgstr " Spa_rpaglia " + +#: ../../po/../src/dialogs/clonetiler.cpp:2557 +msgid "Spread out clones to reduce clumping; can be applied repeatedly" +msgstr "" +"Distribuisce i cloni in modo da ridurre gli agglomerati, può essere ripetuto" + +#: ../../po/../src/dialogs/clonetiler.cpp:2563 +msgid " Re_move " +msgstr " Ri_muovi " + +#: ../../po/../src/dialogs/clonetiler.cpp:2564 +msgid "Remove existing tiled clones of the selected object (siblings only)" +msgstr "Rimuovi i cloni in serie dell'oggetto selezionati (solo imparentati)" + +#: ../../po/../src/dialogs/clonetiler.cpp:2580 +msgid " R_eset " +msgstr " R_eimposta " + +#. TRANSLATORS: "change" is a noun here +#: ../../po/../src/dialogs/clonetiler.cpp:2582 +msgid "" +"Reset all shifts, scales, rotates, opacity and color changes in the dialog " +"to zero" +msgstr "" +"Reimposta tutti gli spostamenti, scale, rotazioni, opacità e cambiamenti di " +"colore nella sottofinestra a zero" + +#: ../../po/../src/dialogs/color-picker.cpp:280 +msgid "Close" +msgstr "Chiudi" + +#: ../../po/../src/dialogs/debugdialog.cpp:138 +msgid "Messages" +msgstr "Messaggi" + +#. ## Add a menu for clear() +#: ../../po/../src/dialogs/debugdialog.cpp:144 +#: ../../po/../src/menus-skeleton.h:16 +#: ../../po/../src/ui/dialog/messages.cpp:56 +#: ../../po/../src/ui/dialog/scriptdialog.cpp:181 +msgid "_File" +msgstr "_File" + +#. TRANSLATORS: "Clear" is a verb here +#: ../../po/../src/dialogs/debugdialog.cpp:145 +#: ../../po/../src/dialogs/find.cpp:753 +#: ../../po/../src/ui/dialog/messages.cpp:57 +#: ../../po/../src/ui/dialog/scriptdialog.cpp:182 +msgid "_Clear" +msgstr "_Pulisci" + +#: ../../po/../src/dialogs/debugdialog.cpp:147 +#: ../../po/../src/ui/dialog/messages.cpp:59 +msgid "Capture log messages" +msgstr "Intercetta i messaggi di log" + +#: ../../po/../src/dialogs/debugdialog.cpp:149 +#: ../../po/../src/ui/dialog/messages.cpp:61 +msgid "Release log messages" +msgstr "Ignora i messaggi di log" + +#. Notebook tab +#: ../../po/../src/dialogs/desktop-properties.cpp:909 +#: ../../po/../src/ui/dialog/document-preferences.cpp:89 +#: ../../po/../src/ui/widget/panel.cpp:107 +msgid "Grid" +msgstr "Griglia" + +#. Checkbuttons +#. / \todo FIXME: gray out snapping when grid is off +#. / \todo FIXME: gray out snapping when grid is off. +#. / Dissenting view: you want snapping without grid. +#: ../../po/../src/dialogs/desktop-properties.cpp:917 +#: ../../po/../src/ui/dialog/document-preferences.cpp:179 +msgid "Show grid" +msgstr "Mostra la griglia" + +#: ../../po/../src/dialogs/desktop-properties.cpp:917 +#: ../../po/../src/ui/dialog/document-preferences.cpp:179 +#: ../../po/../src/verbs.cpp:2115 +msgid "Show or hide grid" +msgstr "Mostra o nasconde la griglia" + +# cambiato attacca->aggancia ed aggiunto di limitazione +#: ../../po/../src/dialogs/desktop-properties.cpp:918 +#: ../../po/../src/ui/dialog/document-preferences.cpp:180 +msgid "Snap bounding boxes to grid" +msgstr "Aggancia i riquadri di limitazione alla griglia" + +#: ../../po/../src/dialogs/desktop-properties.cpp:918 +#: ../../po/../src/dialogs/desktop-properties.cpp:1001 +#: ../../po/../src/ui/dialog/document-preferences.cpp:181 +#: ../../po/../src/ui/dialog/document-preferences.cpp:236 +msgid "Snap the edges of the object bounding boxes" +msgstr "Aggancia i bordi dei riquadri degli oggetti" + +#: ../../po/../src/dialogs/desktop-properties.cpp:919 +#: ../../po/../src/ui/dialog/document-preferences.cpp:183 +msgid "Snap nodes to grid" +msgstr "Aggancia i nodi alla griglia" + +#: ../../po/../src/dialogs/desktop-properties.cpp:919 +#: ../../po/../src/dialogs/desktop-properties.cpp:1002 +#: ../../po/../src/ui/dialog/document-preferences.cpp:184 +#: ../../po/../src/ui/dialog/document-preferences.cpp:239 +msgid "Snap path nodes, text baselines, ellipse centers, etc." +msgstr "" +"Aggancia i nodi dei percorsi, le linee base del testo, i centri degli " +"ellissi, ecc." + +#: ../../po/../src/dialogs/desktop-properties.cpp:937 +#: ../../po/../src/ui/dialog/document-preferences.cpp:186 +msgid "Grid units:" +msgstr "Unità della griglia:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:939 +#: ../../po/../src/ui/dialog/document-preferences.cpp:187 +msgid "Origin X:" +msgstr "Origine X:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:942 +#: ../../po/../src/ui/dialog/document-preferences.cpp:189 +msgid "Origin Y:" +msgstr "Origine Y:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:945 +#: ../../po/../src/ui/dialog/document-preferences.cpp:191 +msgid "Spacing X:" +msgstr "Spaziatura X:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:948 +#: ../../po/../src/ui/dialog/document-preferences.cpp:193 +msgid "Spacing Y:" +msgstr "Spaziatura Y:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:952 +#: ../../po/../src/dialogs/desktop-properties.cpp:1013 +#: ../../po/../src/ui/dialog/document-preferences.cpp:195 +#: ../../po/../src/ui/dialog/document-preferences.cpp:241 +msgid "Snap units:" +msgstr "Unità di spostamento:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:955 +#: ../../po/../src/dialogs/desktop-properties.cpp:1016 +#: ../../po/../src/ui/dialog/document-preferences.cpp:196 +#: ../../po/../src/ui/dialog/document-preferences.cpp:242 +msgid "Snap distance:" +msgstr "Distanza del reticolo:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:958 +#: ../../po/../src/ui/dialog/document-preferences.cpp:199 +msgid "Grid line color:" +msgstr "Colore della griglia:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:959 +#: ../../po/../src/ui/dialog/document-preferences.cpp:199 +msgid "Grid line color" +msgstr "Colore della griglia" + +#: ../../po/../src/dialogs/desktop-properties.cpp:959 +#: ../../po/../src/ui/dialog/document-preferences.cpp:200 +msgid "Color of grid lines" +msgstr "Colore delle linee della griglia" + +#: ../../po/../src/dialogs/desktop-properties.cpp:961 +#: ../../po/../src/ui/dialog/document-preferences.cpp:201 +msgid "Major grid line color:" +msgstr "Colore delle linee delle griglia maggiori:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:962 +#: ../../po/../src/ui/dialog/document-preferences.cpp:201 +msgid "Major grid line color" +msgstr "Colore delle linee maggiori della griglia" + +#: ../../po/../src/dialogs/desktop-properties.cpp:962 +#: ../../po/../src/ui/dialog/document-preferences.cpp:202 +msgid "Color of the major (highlighted) grid lines" +msgstr "Colore delle linee maggiori (evidenziate) della griglia" + +#: ../../po/../src/dialogs/desktop-properties.cpp:965 +#: ../../po/../src/ui/dialog/document-preferences.cpp:204 +msgid "Major grid line every:" +msgstr "Linee maggiori della griglia ogni:" + +#. TRANSLATORS: This belongs to the "Major grid line every:" string, +#. see grid settings in the "Document Preferences" dialog +#: ../../po/../src/dialogs/desktop-properties.cpp:977 +#: ../../po/../src/ui/dialog/document-preferences.cpp:204 +msgid "lines" +msgstr "linee" + +#. Guidelines page +#: ../../po/../src/dialogs/desktop-properties.cpp:991 +#: ../../po/../src/ui/dialog/document-preferences.cpp:90 +msgid "Guides" +msgstr "Guide" + +#. / \todo FIXME: gray out snapping when guides are off +#. / Dissenting view: you want snapping without guides. +#: ../../po/../src/dialogs/desktop-properties.cpp:1000 +#: ../../po/../src/ui/dialog/document-preferences.cpp:234 +msgid "Show guides" +msgstr "Mostra le guide" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1000 +#: ../../po/../src/ui/dialog/document-preferences.cpp:234 +#: ../../po/../src/verbs.cpp:2116 +msgid "Show or hide guides" +msgstr "Mostra o nasconde le guide" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1001 +#: ../../po/../src/ui/dialog/document-preferences.cpp:235 +msgid "Snap bounding boxes to guides" +msgstr "Attacca i riquadri alle guide" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1002 +#: ../../po/../src/ui/dialog/document-preferences.cpp:238 +msgid "Snap points to guides" +msgstr "Attacca i punti alle guide" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1020 +#: ../../po/../src/ui/dialog/document-preferences.cpp:243 +msgid "Guide color:" +msgstr "Colore delle guide:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1021 +#: ../../po/../src/ui/dialog/document-preferences.cpp:243 +msgid "Guideline color" +msgstr "Colore delle linea guida" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1021 +#: ../../po/../src/ui/dialog/document-preferences.cpp:244 +msgid "Color of guidelines" +msgstr "Colore delle linee guida" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1023 +#: ../../po/../src/ui/dialog/document-preferences.cpp:245 +msgid "Highlight color:" +msgstr "Colore di evidenziazione:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1024 +#: ../../po/../src/ui/dialog/document-preferences.cpp:245 +msgid "Highlighted guideline color" +msgstr "Colore di evidenziazione della linea guida" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1024 +#: ../../po/../src/ui/dialog/document-preferences.cpp:246 +msgid "Color of a guideline when it is under mouse" +msgstr "Colore di una guida quando è sotto il mouse" + +#. Page page +#: ../../po/../src/dialogs/desktop-properties.cpp:1029 +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:855 +#: ../../po/../src/ui/dialog/document-preferences.cpp:88 +#: ../../po/../src/widgets/desktop-widget.cpp:1061 +msgid "Page" +msgstr "Pagina" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1039 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +msgid "Background:" +msgstr "Colore di sfondo:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1040 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +msgid "Background color" +msgstr "Colore di sfondo" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1041 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +msgid "" +"Color and transparency of the page background (also used for bitmap export)" +msgstr "" +"Colore e trasparenza dello sfondo della pagina (usati anche per " +"l'esportazione bitmap)" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1045 +#: ../../po/../src/ui/dialog/document-preferences.cpp:147 +#, fuzzy +msgid "Show page border" +msgstr "Mostra i bordi della tela" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1049 +#: ../../po/../src/ui/dialog/document-preferences.cpp:148 +msgid "Border on top of drawing" +msgstr "Bordi in cima al disegno" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1052 +#: ../../po/../src/ui/dialog/document-preferences.cpp:149 +msgid "Border color:" +msgstr "Colore del bordo:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1053 +#: ../../po/../src/ui/dialog/document-preferences.cpp:149 +#, fuzzy +msgid "Page border color" +msgstr "Colore del bordo della tela" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1054 +#: ../../po/../src/ui/dialog/document-preferences.cpp:150 +#, fuzzy +msgid "Color of the page border" +msgstr "Colore dei bordi della tela" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1059 +#: ../../po/../src/ui/dialog/document-preferences.cpp:152 +msgid "Show page shadow" +msgstr "Mostra l'ombra della pagina" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1063 +#: ../../po/../src/ui/dialog/document-preferences.cpp:153 +msgid "Default units:" +msgstr "Unità predefinite:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1069 +msgid "Units for the tool controls, ruler, and the statusbar" +msgstr "Unità per i controlli degli strumenti, il righello e la barra di stato" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1086 +#: ../../po/../src/ui/widget/page-sizer.cpp:209 +#, fuzzy +msgid "Page size:" +msgstr "Dimensione della tela:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1110 +#: ../../po/../src/ui/widget/page-sizer.cpp:219 +msgid "Custom" +msgstr "Personalizzata" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1121 +#: ../../po/../src/ui/widget/page-sizer.cpp:225 +#, fuzzy +msgid "Page orientation:" +msgstr "Orientamento della tela:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1133 +#: ../../po/../src/ui/widget/page-sizer.cpp:232 +msgid "Landscape" +msgstr "Orizzontale" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1139 +#: ../../po/../src/ui/widget/page-sizer.cpp:234 +msgid "Portrait" +msgstr "Verticale" + +#. Custom paper frame +#: ../../po/../src/dialogs/desktop-properties.cpp:1148 +#: ../../po/../src/ui/widget/page-sizer.cpp:249 +#, fuzzy +msgid "Custom size" +msgstr "Personalizzata" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1160 +#: ../../po/../src/dialogs/export.cpp:269 +#: ../../po/../src/ui/widget/page-sizer.cpp:261 +msgid "Units:" +msgstr "Unità:" + +#. Stroke width +#: ../../po/../src/dialogs/desktop-properties.cpp:1162 +#: ../../po/../src/dialogs/export.cpp:310 +#: ../../po/../src/dialogs/object-attributes.cpp:55 +#: ../../po/../src/dialogs/stroke-style.cpp:985 +#: ../../po/../src/ui/widget/page-sizer.cpp:262 +#: ../../po/../src/widgets/toolbox.cpp:1957 +msgid "Width:" +msgstr "Larghezza:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1183 +#: ../../po/../src/dialogs/export.cpp:326 +#: ../../po/../src/dialogs/export.cpp:431 +#: ../../po/../src/dialogs/object-attributes.cpp:56 +#: ../../po/../src/ui/widget/page-sizer.cpp:263 +msgid "Height:" +msgstr "Altezza:" + +#. +#. * Ownership metadata tab +#. +#: ../../po/../src/dialogs/desktop-properties.cpp:1206 +msgid "Metadata" +msgstr "Metadata" + +#. add license selector pull-down +#: ../../po/../src/dialogs/desktop-properties.cpp:1225 +msgid "License" +msgstr "Licenza" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1255 +msgid "Proprietary" +msgstr "Proprietario" + +#: ../../po/../src/dialogs/display-settings.cpp:212 +msgid "When transforming, show:" +msgstr "Durante la strasformazione, mostra:" + +#: ../../po/../src/dialogs/display-settings.cpp:223 +msgid "Objects" +msgstr "Oggetti" + +#: ../../po/../src/dialogs/display-settings.cpp:224 +msgid "Show the actual objects when moving or transforming" +msgstr "Mostra l'oggetto attuale durante il movimento o la trasformazione" + +#: ../../po/../src/dialogs/display-settings.cpp:231 +msgid "Box outline" +msgstr "Riquadro" + +#: ../../po/../src/dialogs/display-settings.cpp:232 +msgid "Show only a box outline of the objects when moving or transforming" +msgstr "" +"Mostra solo il riquadro dell'oggetto durante il movimento o la trasformazione" + +#: ../../po/../src/dialogs/display-settings.cpp:238 +msgid "Per-object selection cue:" +msgstr "Suggerimento di selezione ad oggetto:" + +#. sorationsnapsperpi == 0 means no snapping +#: ../../po/../src/dialogs/display-settings.cpp:249 +#: ../../po/../src/dialogs/display-settings.cpp:386 +#: ../../po/../src/dialogs/display-settings.cpp:441 +#: ../../po/../src/dialogs/display-settings.cpp:1482 +#: ../../po/../src/dialogs/stroke-style.cpp:791 +#: ../../po/../src/interface.cpp:741 +#: ../../po/../src/ui/widget/selected-style.cpp:100 +#: ../../po/../src/verbs.cpp:1842 +msgid "None" +msgstr "Nessuno" + +#: ../../po/../src/dialogs/display-settings.cpp:250 +msgid "No per-object selection indication" +msgstr "Nessuna indicazione di selezione ad oggetto" + +#: ../../po/../src/dialogs/display-settings.cpp:256 +msgid "Mark" +msgstr "Segno" + +#: ../../po/../src/dialogs/display-settings.cpp:257 +msgid "Each selected object has a diamond mark in the top left corner" +msgstr "" +"Ogni oggetto selezionato ha un segno a forma di diamante nell'angolo " +"superiore sinistro" + +#: ../../po/../src/dialogs/display-settings.cpp:264 +msgid "Box" +msgstr "Riquadro" + +#: ../../po/../src/dialogs/display-settings.cpp:265 +msgid "Each selected object displays its bounding box" +msgstr "Ongi oggetto selezionato mostra il proprio riquadro" + +#: ../../po/../src/dialogs/display-settings.cpp:270 +msgid "Default scale origin:" +msgstr "Origine predefinita della scala:" + +#: ../../po/../src/dialogs/display-settings.cpp:281 +msgid "Opposite bounding box edge" +msgstr "Al margine opposto del riquadro" + +#: ../../po/../src/dialogs/display-settings.cpp:282 +msgid "Default scale origin will be on the bounding box of the item" +msgstr "L'origine predefinita della scala è sul riquadro dell'elemento" + +#: ../../po/../src/dialogs/display-settings.cpp:288 +msgid "Farthest opposite node" +msgstr "Sul nodo opposto più lontano" + +#: ../../po/../src/dialogs/display-settings.cpp:289 +msgid "Default scale origin will be on the bounding box of the item's points" +msgstr "" +"L'origine predefinita della scala è sul riquadro dei punti dell'elemento" + +#: ../../po/../src/dialogs/display-settings.cpp:341 +msgid "degrees" +msgstr "gradi" + +#: ../../po/../src/dialogs/display-settings.cpp:350 +msgid "" +"Rotating with Ctrl pressed snaps every that much degrees; also, pressing " +"[ or ] rotates by this amount" +msgstr "" +"La rotazione con Ctrl premuto scatta di questo ammontare di gradi; inoltre, " +"la pressione di [ o ] effettua una rotazione di questi gradi" + +#: ../../po/../src/dialogs/display-settings.cpp:407 +msgid "Rotation snaps every:" +msgstr "La rotazione scatta ogni:" + +#: ../../po/../src/dialogs/display-settings.cpp:430 +msgid "" +"None: dialogs are treated as regular windows; Normal: dialogs stay on top of " +"document windows; Aggressive: same as Normal but may work better with some " +"window managers." +msgstr "" +"Nessuno: le sottofinestre sono trattate come finestre normali; Normale: le " +"sottofinestre stanno sopra alla finestra del documento; Aggresivo: come in " +"Normale, ma funziona meglio con alcuni gestori di finestre." + +#: ../../po/../src/dialogs/display-settings.cpp:451 +msgid "Normal" +msgstr "Normale" + +#: ../../po/../src/dialogs/display-settings.cpp:461 +msgid "Aggressive" +msgstr "Aggressivo" + +#: ../../po/../src/dialogs/display-settings.cpp:475 +msgid "Dialogs on top:" +msgstr "Risalto delle sottofinestre:" + +#: ../../po/../src/dialogs/display-settings.cpp:645 +msgid "Show selection cue" +msgstr "Mostra suggerimento di selezione" + +#: ../../po/../src/dialogs/display-settings.cpp:646 +msgid "" +"Whether selected objects display a selection cue (the same as in selector)" +msgstr "" +"Qualsiasi elemento selezionato mostra un suggerimento di selezione (lo " +"stesso del selettore)" + +#: ../../po/../src/dialogs/display-settings.cpp:657 +msgid "Enable gradient editing" +msgstr "Abilita l'editor di gradiente" + +#: ../../po/../src/dialogs/display-settings.cpp:658 +msgid "Whether selected objects display gradient editing controls" +msgstr "" +"L'elemento selezionato mostra i controlli per la modifica del gradiente" + +#: ../../po/../src/dialogs/display-settings.cpp:719 +msgid "No objects selected to take the style from." +msgstr "Nessun elemento selezionato da cui prendere lo stile." + +#: ../../po/../src/dialogs/display-settings.cpp:728 +msgid "" +"More than one object selected. Cannot take style from multiple " +"objects." +msgstr "" +"Più di un elemento selezionato. Impossibile prendere lo stile da più " +"oggetti." + +#: ../../po/../src/dialogs/display-settings.cpp:767 +msgid "Create new objects with:" +msgstr "Crea nuovi oggetti con:" + +#: ../../po/../src/dialogs/display-settings.cpp:777 +msgid "Take from selection" +msgstr "Prendi dalla selezione" + +#: ../../po/../src/dialogs/display-settings.cpp:778 +msgid "Remember the style of the (first) selected object as this tool's style" +msgstr "" +"Imposta lo stile del (primo) elemento selezionato come stile di questo " +"strumento" + +#: ../../po/../src/dialogs/display-settings.cpp:782 +#, fuzzy +msgid "Last used style" +msgstr "Incolla _stile" + +#: ../../po/../src/dialogs/display-settings.cpp:782 +msgid "Apply the style you last set on an object" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:790 +msgid "This tool's own style:" +msgstr "Stile di questo strumento:" + +#: ../../po/../src/dialogs/display-settings.cpp:790 +msgid "" +"Each tool may store its own style to apply to the newly created objects. Use " +"the button below to set it." +msgstr "" +"Ogni strumento può salvare il proprio stile per applicarlo agli oggetti che " +"saranno creati. Usare il bottone sotto per impostarlo." + +#. Mouse +#: ../../po/../src/dialogs/display-settings.cpp:877 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:55 +msgid "Mouse" +msgstr "Mouse" + +#. TRANSLATORS: "Grab" is a noun here. "Grab sensitivity" is intended to mean how +#. * close on the screen you need to be to an object to be able to grab it with mouse (in +#. * pixels). +#: ../../po/../src/dialogs/display-settings.cpp:883 +msgid "Grab sensitivity:" +msgstr "Area di azione:" + +#: ../../po/../src/dialogs/display-settings.cpp:884 +msgid "" +"How close on the screen you need to be to an object to be able to grab it " +"with mouse (in screen pixels)" +msgstr "" +"La distanza in pixel a cui si può essere da un oggetto per poterlo attivare " +"col mouse (in pixel dello schermo)" + +#: ../../po/../src/dialogs/display-settings.cpp:885 +#: ../../po/../src/dialogs/display-settings.cpp:897 +#: ../../po/../src/dialogs/display-settings.cpp:912 +#: ../../po/../src/dialogs/display-settings.cpp:930 +#: ../../po/../src/dialogs/display-settings.cpp:970 +msgid "pixels" +msgstr "pixel" + +#: ../../po/../src/dialogs/display-settings.cpp:895 +msgid "Click/drag threshold:" +msgstr "Soglia per il click o spostamento" + +#: ../../po/../src/dialogs/display-settings.cpp:896 +msgid "" +"Maximum mouse drag (in screen pixels) which is considered a click, not a drag" +msgstr "" +"Spostamento in pixel massimo col mouse da considerarsi ancora selezione e " +"non spostamento" + +#. Scrolling +#: ../../po/../src/dialogs/display-settings.cpp:907 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:56 +msgid "Scrolling" +msgstr "Scorrimento" + +#: ../../po/../src/dialogs/display-settings.cpp:910 +msgid "Mouse wheel scrolls by:" +msgstr "Scorrimento con la rotella del mouse:" + +#: ../../po/../src/dialogs/display-settings.cpp:911 +msgid "" +"One mouse wheel notch scrolls by this distance in screen pixels " +"(horizontally with Shift)" +msgstr "" +"Con uno scatto della rotella del mouse si scorre di questa distanza " +"(orizzontalmente con Maiusc)" + +#: ../../po/../src/dialogs/display-settings.cpp:920 +msgid "Ctrl+arrows" +msgstr "Ctrl+frecce" + +#: ../../po/../src/dialogs/display-settings.cpp:928 +msgid "Scroll by:" +msgstr "Scorrimento:" + +#: ../../po/../src/dialogs/display-settings.cpp:929 +msgid "Pressing Ctrl+arrow key scrolls by this distance (in screen pixels)" +msgstr "" +"Premendo Ctrl+freccia si scorre di questa distanza (in pixel dello schermo)" + +#: ../../po/../src/dialogs/display-settings.cpp:939 +msgid "Acceleration:" +msgstr "Accelerazione:" + +#: ../../po/../src/dialogs/display-settings.cpp:940 +msgid "" +"Pressing and holding Ctrl+arrow will gradually speed up scrolling (0 for no " +"acceleration)" +msgstr "" +"Tenendo premuto ctrl+freccia si accelererà lo scorrimento (0 per non avere " +"accelerazione)" + +#: ../../po/../src/dialogs/display-settings.cpp:949 +msgid "Autoscrolling" +msgstr "Scorrimento automatico" + +#: ../../po/../src/dialogs/display-settings.cpp:957 +msgid "Speed:" +msgstr "Velocità:" + +#: ../../po/../src/dialogs/display-settings.cpp:958 +msgid "" +"How fast the canvas autoscrolls when you drag beyond canvas edge (0 to turn " +"autoscroll off)" +msgstr "" +"La velocità con cui la tela scorrerà automaticamente durante il " +"trascinamento fuori dal bordo (0 per disattivarlo)" + +#: ../../po/../src/dialogs/display-settings.cpp:968 +#: ../../po/../src/ui/dialog/tracedialog.cpp:357 +#: ../../po/../src/ui/dialog/tracedialog.cpp:390 +msgid "Threshold:" +msgstr "Soglia" + +#: ../../po/../src/dialogs/display-settings.cpp:969 +msgid "" +"How far (in screen pixels) you need to be from the canvas edge to trigger " +"autoscroll; positive is outside the canvas, negative is within the canvas" +msgstr "" +"La distanza (in pixel dello schermo) dal bordo della tela per attivare lo " +"scorrimento automatico; un numero positivo indica l'esterno della tela, uno " +"negativo l'esterno" + +#. Steps +#: ../../po/../src/dialogs/display-settings.cpp:979 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:57 +msgid "Steps" +msgstr "Scatti" + +#: ../../po/../src/dialogs/display-settings.cpp:982 +msgid "Arrow keys move by:" +msgstr "Le frecce direzionali muovono di:" + +#: ../../po/../src/dialogs/display-settings.cpp:983 +msgid "" +"Pressing an arrow key moves selected object(s) or node(s) by this distance " +"(in px units)" +msgstr "" +"Premendo una freccia direzionale l'oggetto o il nodo selezionato si muovono " +"di questa distanza (in pixel)" + +#: ../../po/../src/dialogs/display-settings.cpp:984 +#: ../../po/../src/dialogs/display-settings.cpp:995 +#: ../../po/../src/dialogs/display-settings.cpp:1006 +#: ../../po/../src/helper/units.cpp:42 +msgid "px" +msgstr "px" + +#: ../../po/../src/dialogs/display-settings.cpp:993 +msgid "> and < scale by:" +msgstr "> e < ridimensionano di:" + +#: ../../po/../src/dialogs/display-settings.cpp:994 +msgid "" +"Pressing > or < scales selection up or down by this increment (in px units)" +msgstr "" +"Premendo > o < si ridimensiona la selezione di questo fattore (in pixel)" + +#: ../../po/../src/dialogs/display-settings.cpp:1004 +msgid "Inset/Outset by:" +msgstr "Intrudi/Estrudi di:" + +#: ../../po/../src/dialogs/display-settings.cpp:1005 +msgid "" +"Inset and Outset commands displace the path by this distance (in px units)" +msgstr "" +"I comandi Intrudi ed Estrudi spostano il tracciato di questa distanza (in " +"pixel)" + +#: ../../po/../src/dialogs/display-settings.cpp:1017 +msgid "Compass-like display of angles" +msgstr "Visualizzazione tipo bussola degli angoli" + +#. TRANSLATORS: "positive clockwise" means "increasing in clockwise direction" +#: ../../po/../src/dialogs/display-settings.cpp:1019 +msgid "" +"When on, angles are displayed with 0 at north, 0 to 360 range, positive " +"clockwise; otherwise with 0 at east, -180 to 180 range, positive " +"counterclockwise" +msgstr "" +"Quando attivo, gli angoli sono visualizzato con lo 0 a nord, nell'intervallo " +"0~360, con positivo in senso orario. Se disattivato, lo 0 è a est, " +"nell'intervallo -180~180, con positivo in senso antiorario" + +#: ../../po/../src/dialogs/display-settings.cpp:1026 +msgid "Zoom in/out by:" +msgstr "Ingrandimento/Riduzione:" + +#: ../../po/../src/dialogs/display-settings.cpp:1027 +msgid "" +"Zoom tool click, +/- keys, and middle click zoom in and out by this " +"multiplier" +msgstr "" +"Un click dell'ingrandimento, i tasti +/- e un click centrale " +"dell'ingrandimento rimpiccioliscono o ingrandiscono di questo fattore" + +#: ../../po/../src/dialogs/display-settings.cpp:1028 +#: ../../po/../src/helper/units.cpp:44 +msgid "%" +msgstr "%" + +#. Tools +#: ../../po/../src/dialogs/display-settings.cpp:1037 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:58 +msgid "Tools" +msgstr "Strumenti" + +#: ../../po/../src/dialogs/display-settings.cpp:1045 +msgid "Selector" +msgstr "Selettore" + +#: ../../po/../src/dialogs/display-settings.cpp:1056 +msgid "Node" +msgstr "Nodo" + +#: ../../po/../src/dialogs/display-settings.cpp:1064 +#: ../../po/../src/verbs.cpp:2073 +#: ../../po/../src/widgets/desktop-widget.cpp:277 +msgid "Zoom" +msgstr "Ingrandimento" + +#. The 4 shape tools +#: ../../po/../src/dialogs/display-settings.cpp:1071 +msgid "Shapes" +msgstr "Forme" + +#: ../../po/../src/dialogs/display-settings.cpp:1079 +#: ../../po/../src/verbs.cpp:2055 +msgid "Rectangle" +msgstr "Rettangolo" + +#: ../../po/../src/dialogs/display-settings.cpp:1085 +#: ../../po/../src/verbs.cpp:2057 +msgid "Ellipse" +msgstr "Ellisse" + +#: ../../po/../src/dialogs/display-settings.cpp:1091 +#: ../../po/../src/verbs.cpp:2059 +msgid "Star" +msgstr "Stella" + +#: ../../po/../src/dialogs/display-settings.cpp:1097 +#: ../../po/../src/verbs.cpp:2061 +msgid "Spiral" +msgstr "Spirale" + +#: ../../po/../src/dialogs/display-settings.cpp:1111 +#: ../../po/../src/verbs.cpp:2063 +msgid "Pencil" +msgstr "Pastello" + +#: ../../po/../src/dialogs/display-settings.cpp:1114 +msgid "Tolerance:" +msgstr "Tolleranza:" + +#: ../../po/../src/dialogs/display-settings.cpp:1115 +msgid "" +"This value affects the amount of smoothing applied to freehand lines; lower " +"values produce more uneven paths with more nodes" +msgstr "" +"Questo valore riguarda l'uniformità delle linee a mano libera; più basso è " +"il valore e più la linea sarà irregolare e con più nodi" + +#: ../../po/../src/dialogs/display-settings.cpp:1131 +#: ../../po/../src/verbs.cpp:2065 +msgid "Pen" +msgstr "Penna" + +#: ../../po/../src/dialogs/display-settings.cpp:1140 +#: ../../po/../src/verbs.cpp:2067 +msgid "Calligraphy" +msgstr "Pennino" + +#: ../../po/../src/dialogs/display-settings.cpp:1147 +#: ../../po/../src/dialogs/text-edit.cpp:353 +#: ../../po/../src/ui/dialog/text-properties.cpp:37 +#: ../../po/../src/verbs.cpp:2069 +msgid "Text" +msgstr "Testo" + +#: ../../po/../src/dialogs/display-settings.cpp:1157 +#: ../../po/../src/verbs.cpp:2071 +msgid "Gradient" +msgstr "Gradiente" + +#: ../../po/../src/dialogs/display-settings.cpp:1164 +#: ../../po/../src/verbs.cpp:2077 +msgid "Connector" +msgstr "Connettore" + +#: ../../po/../src/dialogs/display-settings.cpp:1171 +#: ../../po/../src/verbs.cpp:2075 +msgid "Dropper" +msgstr "Contagocce" + +#. Windows +#: ../../po/../src/dialogs/display-settings.cpp:1183 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:59 +msgid "Windows" +msgstr "Finestre" + +#: ../../po/../src/dialogs/display-settings.cpp:1188 +msgid "Save window geometry" +msgstr "Salva la dimensione della finestra" + +#: ../../po/../src/dialogs/display-settings.cpp:1189 +msgid "" +"Save the window size and position with each document (only for Inkscape SVG " +"format)" +msgstr "" +"Salva la dimensione e la posizione della finestra per ogni documento (solo " +"per il formato Inkscape SVG)" + +#: ../../po/../src/dialogs/display-settings.cpp:1196 +msgid "Dialogs are hidden in taskbar" +msgstr "Sottofinestre non mostrate nella barra" + +#: ../../po/../src/dialogs/display-settings.cpp:1197 +msgid "Whether dialog windows are to be hidden in the window manager taskbar" +msgstr "" +"Le sottofinestre non verranno mostrate nella barra del gestore di finestre" + +#: ../../po/../src/dialogs/display-settings.cpp:1204 +msgid "Zoom when window is resized" +msgstr "Adatta al ridimensionamento della finestra" + +#: ../../po/../src/dialogs/display-settings.cpp:1205 +msgid "" +"Zoom drawing when document window is resized, to keep the same area visible " +"(this is the default which can be changed in any window using the button " +"above the right scrollbar)" +msgstr "" +"Adatta il disegno quando la finestra del documento viene ridimensionata, per " +"mantenere la stessa area visibile (questo sarà il comportamento " +"preimpostato, potrà essere cambiato per ciascuna finestra usando il bottone " +"sopra la barra di scorrimento di destra)" + +#. Clones +#: ../../po/../src/dialogs/display-settings.cpp:1213 +#: ../../po/../src/dialogs/find.cpp:624 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:60 +msgid "Clones" +msgstr "Cloni" + +#: ../../po/../src/dialogs/display-settings.cpp:1217 +msgid "When the original moves, its clones and linked offsets:" +msgstr "" +"Quando l'originale viene spostato, i cloni e gli elementi collegati vengono:" + +#: ../../po/../src/dialogs/display-settings.cpp:1229 +msgid "Move in parallel" +msgstr "Mossi in parallelo" + +#: ../../po/../src/dialogs/display-settings.cpp:1230 +msgid "Clones are translated by the same vector as their original." +msgstr "I cloni vengono traslati dello stesso vettore dell'originale" + +#: ../../po/../src/dialogs/display-settings.cpp:1237 +msgid "Stay unmoved" +msgstr "Lasciati fermi" + +#: ../../po/../src/dialogs/display-settings.cpp:1238 +msgid "Clones preserve their positions when their original is moved." +msgstr "I cloni preservano la loro posizione quando l'originale viene spostato" + +#: ../../po/../src/dialogs/display-settings.cpp:1245 +msgid "Move according to transform" +msgstr "Mossi secondo la trasformazione" + +#: ../../po/../src/dialogs/display-settings.cpp:1246 +msgid "" +"Each clone moves according to the value of its transform= attribute. For " +"example, a rotated clone will move in a different direction than its " +"original." +msgstr "" +"Ogni clone viene mosso secondo il valore del suo attributo transform=. Per " +"esempio, un clone ruotato verrà mosso in una direzione diversa dal suo " +"originale." + +#: ../../po/../src/dialogs/display-settings.cpp:1255 +msgid "When the original is deleted, its clones:" +msgstr "Quando l'originale viene cancellato, i suoi cloni vengono:" + +#: ../../po/../src/dialogs/display-settings.cpp:1267 +msgid "Are unlinked" +msgstr "Scollegati" + +#: ../../po/../src/dialogs/display-settings.cpp:1267 +msgid "Orphaned clones are converted to regular objects." +msgstr "I cloni orfani vengono convertiti in oggetti normali" + +#: ../../po/../src/dialogs/display-settings.cpp:1273 +msgid "Are deleted" +msgstr "Cancellati" + +#: ../../po/../src/dialogs/display-settings.cpp:1273 +msgid "Orphaned clones are deleted along with their original." +msgstr "I cloni orfani vengono cancellati con il loro originale." + +#. Transforms +#. TRANSLATORS: Noun, i.e. transformations. +#: ../../po/../src/dialogs/display-settings.cpp:1289 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:61 +msgid "Transforms" +msgstr "Trasformazioni" + +#: ../../po/../src/dialogs/display-settings.cpp:1292 +msgid "Scale stroke width" +msgstr "Mantieni le proporzioni dei contorni" + +#: ../../po/../src/dialogs/display-settings.cpp:1293 +#: ../../po/../src/widgets/select-toolbar.cpp:568 +msgid "When scaling objects, scale the stroke width by the same proportion" +msgstr "" +"Adatta le dimensioni dei contorni durante il ridimensionamento dell'oggetto" + +#: ../../po/../src/dialogs/display-settings.cpp:1300 +msgid "Scale rounded corners in rectangles" +msgstr "Adatta gli angoli arrotondati nei rettangoli" + +#: ../../po/../src/dialogs/display-settings.cpp:1301 +#: ../../po/../src/widgets/select-toolbar.cpp:580 +msgid "When scaling rectangles, scale the radii of rounded corners" +msgstr "" +"Adatta i radiali degli angoli arrotondati durante il ridimensionamento dei " +"rettangoli" + +#: ../../po/../src/dialogs/display-settings.cpp:1308 +msgid "Transform gradients" +msgstr "Trasforma gradienti" + +#: ../../po/../src/dialogs/display-settings.cpp:1309 +#: ../../po/../src/widgets/select-toolbar.cpp:592 +msgid "Transform gradients (in fill or stroke) along with the objects" +msgstr "" +"Trasforma i gradienti (di contorno o di riempimento) insieme agli oggetti" + +#: ../../po/../src/dialogs/display-settings.cpp:1316 +msgid "Transform patterns" +msgstr "Trasforma motivi" + +#: ../../po/../src/dialogs/display-settings.cpp:1317 +#: ../../po/../src/widgets/select-toolbar.cpp:604 +msgid "Transform patterns (in fill or stroke) along with the objects" +msgstr "Trasforma i motivi (di contorno o di riempimento) insieme agli oggetti" + +#. TRANSLATORS: How to specify the affine transformation in the SVG file. +#: ../../po/../src/dialogs/display-settings.cpp:1327 +msgid "Store transformation:" +msgstr "Salvataggio trasformazioni:" + +#: ../../po/../src/dialogs/display-settings.cpp:1338 +msgid "Optimized" +msgstr "Ottimizzato" + +#: ../../po/../src/dialogs/display-settings.cpp:1339 +msgid "" +"If possible, apply transformation to objects without adding a transform= " +"attribute" +msgstr "" +"Se possibile, applica le traformazioni all'oggetto senza aggiungere un " +"attributo transfom=" + +#: ../../po/../src/dialogs/display-settings.cpp:1346 +msgid "Preserved" +msgstr "Preservato" + +#: ../../po/../src/dialogs/display-settings.cpp:1347 +msgid "Always store transformation as a transform= attribute on objects" +msgstr "Salva sempre le trasformazioni come attributo transform di un oggetto" + +#. Selecting +#: ../../po/../src/dialogs/display-settings.cpp:1355 +msgid "Selecting" +msgstr "Selezione" + +#: ../../po/../src/dialogs/display-settings.cpp:1357 +msgid "Ctrl+A, Tab, Shift+Tab:" +msgstr "Ctrl+A, Tab, Maiusc+Tab:" + +#: ../../po/../src/dialogs/display-settings.cpp:1366 +msgid "Select only within current layer" +msgstr "Seleziona solo nel livello attuale" + +#: ../../po/../src/dialogs/display-settings.cpp:1367 +msgid "" +"Uncheck this to make keyboard selection commands work on objects in all " +"layers" +msgstr "" +"Deselezionare questa opzione per permettere alle selezioni da tastiera di " +"operare sugli oggetti di tutti i livelli" + +#: ../../po/../src/dialogs/display-settings.cpp:1374 +msgid "Ignore hidden objects" +msgstr "Ignora gli oggetti nascosti" + +#: ../../po/../src/dialogs/display-settings.cpp:1375 +msgid "" +"Uncheck this to be able to select objects that are hidden (either by " +"themselves or by being in a hidden group or layer)" +msgstr "" +"Deselezionare questa opzione per poter selezionare oggetti non visibili " +"(nascosti loro stessi o in un gruppo o livello nascosto)" + +#: ../../po/../src/dialogs/display-settings.cpp:1382 +msgid "Ignore locked objects" +msgstr "Ignora gli oggetti bloccati" + +#: ../../po/../src/dialogs/display-settings.cpp:1383 +msgid "" +"Uncheck this to be able to select objects that are locked (either by " +"themselves or by being in a locked group or layer)" +msgstr "" +"Deselezionare questa opzione per poter selezionare oggetti bloccati " +"(bloccati loro stessi o in un gruppo o livello bloccato)" + +#. To be broken into: Display, Save, Export, SVG, Commands +#: ../../po/../src/dialogs/display-settings.cpp:1391 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:62 +msgid "Misc" +msgstr "Varie" + +#: ../../po/../src/dialogs/display-settings.cpp:1394 +msgid "Default export resolution:" +msgstr "Risoluzione predefinita per l'esportazione" + +#: ../../po/../src/dialogs/display-settings.cpp:1395 +msgid "Default bitmap resolution (in dots per inch) in the Export dialog" +msgstr "" +"Risoluzione predefinita (in punti per pollice) delle bitmap nella " +"sottofinestra Esporta" + +#. FIXME: add "Used for new exports; once exported, documents remember this value on per-object basis" when implemented +#: ../../po/../src/dialogs/display-settings.cpp:1396 +#: ../../po/../src/dialogs/export.cpp:442 +msgid "dpi" +msgstr "dpi" + +#. TRANSLATORS: When on, an imported bitmap creates an element; otherwise it is a +#. * rectangle with bitmap fill. +#: ../../po/../src/dialogs/display-settings.cpp:1407 +msgid "Import bitmap as " +msgstr "Importa bitmap come " + +#: ../../po/../src/dialogs/display-settings.cpp:1408 +msgid "" +"When on, an imported bitmap creates an element; otherwise it is a " +"rectangle with bitmap fill" +msgstr "" +"Quando è attivo, una bitmap importata crea un elemento , altrimenti " +"un rettangolo con la bitmap come riempimento" + +#. TRANSLATORS: When on, the print out (currently Postscript) will have +#. * a comment with the each object's label visible, marking the section +#. * of the printing commands that represent the given object. +#: ../../po/../src/dialogs/display-settings.cpp:1418 +msgid "Add label comments to printing output" +msgstr "Aggiungi i commenti all'output di stampa" + +#: ../../po/../src/dialogs/display-settings.cpp:1419 +msgid "" +"When on, a comment will be added to the raw print output, marking the " +"rendered output for an object with its label" +msgstr "" +"Quando impostato, viene aggiunto un commento all'output di stampa grezzo, in " +"modo da evidenziare la visualizzazione di di stampa di un oggetto con la " +"propria etichetta" + +#. TRANSLATORS: When on, enable the effects menu, default is off +#: ../../po/../src/dialogs/display-settings.cpp:1427 +msgid "Enable script effects (requires restart) - EXPERIMENTAL" +msgstr "Abilita gli script degli effetti (richiede il riavvio) - SPERIMENTALE" + +#: ../../po/../src/dialogs/display-settings.cpp:1428 +msgid "" +"When on, the effects menu is enabled, allowing external effect scripts to be " +"called, requires restart before effective - EXPERIMENTAL" +msgstr "" +"Quando attivo, il menu degli effetti è abilitato, permettendo di eseguire " +"script per gli effetti esterni. Per funzionare richiede il riavvio - " +"SPERIMENTALE" + +#. TRANSLATORS: The maximum length of the Open Recent list in the File menu. +#: ../../po/../src/dialogs/display-settings.cpp:1436 +msgid "Max recent documents:" +msgstr "Numero massimo di documenti recenti:" + +#: ../../po/../src/dialogs/display-settings.cpp:1437 +msgid "The maximum length of the Open Recent list in the File menu" +msgstr "La lunghezza massima della lista Apri recente del menu File" + +#: ../../po/../src/dialogs/display-settings.cpp:1447 +msgid "Simplification threshold:" +msgstr "Soglia per la semplificazione:" + +#: ../../po/../src/dialogs/display-settings.cpp:1448 +msgid "" +"How strong is the Simplify command by default. If you invoke this command " +"several times in quick succession, it will act more and more aggressively; " +"invoking it again after a pause restores the default threshold." +msgstr "" +"La forza predefinita del comando Semplifica. Se si invoca questo comando " +"diverse volte in rapida successione, si comporterà in modo sempre più " +"aggressivo; effettuando una pausa sarà ripristinata la soglia predefinita." + +#: ../../po/../src/dialogs/display-settings.cpp:1469 +msgid "Oversample bitmaps:" +msgstr "Sovracampionamento bitmap:" + +#: ../../po/../src/dialogs/display-settings.cpp:1488 +msgid "2x2" +msgstr "2x2" + +#: ../../po/../src/dialogs/display-settings.cpp:1494 +msgid "4x4" +msgstr "4x4" + +#: ../../po/../src/dialogs/display-settings.cpp:1500 +msgid "8x8" +msgstr "8x8" + +#: ../../po/../src/dialogs/display-settings.cpp:1506 +msgid "16x16" +msgstr "16x16" + +#. "view_icon_preview" +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2143 +msgid "_Page" +msgstr "_Pagina" + +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2147 +msgid "_Drawing" +msgstr "_Disegno" + +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2149 +msgid "_Selection" +msgstr "_Selezione" + +#: ../../po/../src/dialogs/export.cpp:133 +msgid "_Custom" +msgstr "_Personalizzata" + +#: ../../po/../src/dialogs/export.cpp:254 +msgid "Export area" +msgstr "Area di esportazione" + +#: ../../po/../src/dialogs/export.cpp:300 +msgid "_x0:" +msgstr "_x0:" + +#: ../../po/../src/dialogs/export.cpp:305 +msgid "x_1:" +msgstr "x_1:" + +#: ../../po/../src/dialogs/export.cpp:316 +msgid "_y0:" +msgstr "_y0:" + +#: ../../po/../src/dialogs/export.cpp:321 +msgid "y_1:" +msgstr "y_1:" + +#: ../../po/../src/dialogs/export.cpp:406 +msgid "Bitmap size" +msgstr "Dimensione della bitmap" + +#: ../../po/../src/dialogs/export.cpp:416 +msgid "_Width:" +msgstr "_Larghezza:" + +#: ../../po/../src/dialogs/export.cpp:416 +#: ../../po/../src/dialogs/export.cpp:431 +msgid "pixels at" +msgstr "pixel a" + +#: ../../po/../src/dialogs/export.cpp:426 +msgid "dp_i" +msgstr "dp_i" + +#: ../../po/../src/dialogs/export.cpp:448 +msgid "_Filename" +msgstr "Nome del _file" + +#: ../../po/../src/dialogs/export.cpp:512 +msgid "_Browse..." +msgstr "_Sfoglia..." + +#: ../../po/../src/dialogs/export.cpp:539 +msgid " _Export " +msgstr " _Esporta " + +#: ../../po/../src/dialogs/export.cpp:541 +msgid "Export the bitmap file with these settings" +msgstr "Esporta il file bitmap con queste impostazioni" + +#: ../../po/../src/dialogs/export.cpp:968 +msgid "You have to enter a filename" +msgstr "Bisogna inserire il nome del file" + +#: ../../po/../src/dialogs/export.cpp:973 +msgid "The chosen area to be exported is invalid" +msgstr "L'area di esportazione selezionata non è valida" + +#: ../../po/../src/dialogs/export.cpp:982 +#, c-format +msgid "Directory %s does not exist or is not a directory.\n" +msgstr "La cartella %s non esiste o non è una cartella.\n" + +#: ../../po/../src/dialogs/export.cpp:998 +msgid "Export in progress" +msgstr "Esportazione in avanzamento" + +#: ../../po/../src/dialogs/export.cpp:1004 +#, c-format +msgid "Exporting %s (%d x %d)" +msgstr "Sto esportando %s (%d x %d) " + +#: ../../po/../src/dialogs/export.cpp:1031 +#, c-format +msgid "Could not export to filename %s.\n" +msgstr "Impossibile esportare col nome del file %s. \n" + +#: ../../po/../src/dialogs/export.cpp:1137 +msgid "Select a filename for exporting" +msgstr "Selezionare il nome del file dove esportare" + +#: ../../po/../src/dialogs/filedialog.cpp:367 +msgid "No preview" +msgstr "Nessuna anteprima" + +#: ../../po/../src/dialogs/filedialog.cpp:468 +msgid "too large for preview" +msgstr "troppo grande per l'anteprima" + +#: ../../po/../src/dialogs/filedialog.cpp:762 +#: ../../po/../src/dialogs/filedialog.cpp:763 +msgid "All Images" +msgstr "Tutte le immagini" + +#: ../../po/../src/dialogs/filedialog.cpp:767 +#: ../../po/../src/dialogs/filedialog.cpp:768 +msgid "All Files" +msgstr "Tutti i file" + +#: ../../po/../src/dialogs/filedialog.cpp:774 +#: ../../po/../src/dialogs/filedialog.cpp:775 +msgid "All Inkscape Files" +msgstr "Tutti i file di Inkscape" + +#: ../../po/../src/dialogs/filedialog.cpp:1176 +msgid "Guess from extension" +msgstr "Determina dall'estensione" + +#. ###### Add the file types menu +#. createFilterMenu(); +#. ###### Do we want the .xxx extension automatically added? +#: ../../po/../src/dialogs/filedialog.cpp:1261 +msgid "Append filename extension automatically" +msgstr "Aggiungi automaticamente l'estensione" + +#. TRANSLATORS: "%s" is replaced with "exact" or "partial" when this string is displayed +#: ../../po/../src/dialogs/find.cpp:378 +#, c-format +msgid "%d object found (out of %d), %s match." +msgid_plural "%d objects found (out of %d), %s match." +msgstr[0] "" +"%d oggetto trovato (su un totale di %d), corrispondenza %s ." +msgstr[1] "" +"%d oggetti trovati (su un totale di %d), corrispondenza %s ." + +#: ../../po/../src/dialogs/find.cpp:381 +msgid "exact" +msgstr "esatta" + +#: ../../po/../src/dialogs/find.cpp:381 +msgid "partial" +msgstr "parziale" + +#: ../../po/../src/dialogs/find.cpp:388 +msgid "No objects found" +msgstr "Nessun oggetto trovato" + +#: ../../po/../src/dialogs/find.cpp:546 +msgid "T_ype: " +msgstr "T_ipo:" + +#: ../../po/../src/dialogs/find.cpp:553 +msgid "Search in all object types" +msgstr "Cerca oggetti di tutti i tipi" + +#: ../../po/../src/dialogs/find.cpp:553 +msgid "All types" +msgstr "Tutti i tipi" + +#: ../../po/../src/dialogs/find.cpp:564 +msgid "Search all shapes" +msgstr "Cerca tutte le forme" + +#: ../../po/../src/dialogs/find.cpp:564 +msgid "All shapes" +msgstr "Tutte le forme" + +#: ../../po/../src/dialogs/find.cpp:581 +msgid "Search rectangles" +msgstr "Cerca rettangoli" + +#: ../../po/../src/dialogs/find.cpp:581 +msgid "Rectangles" +msgstr "Rettangoli" + +#: ../../po/../src/dialogs/find.cpp:586 +msgid "Search ellipses, arcs, circles" +msgstr "Cerca ellissi, archi e cerchi" + +#: ../../po/../src/dialogs/find.cpp:586 +msgid "Ellipses" +msgstr "Ellissi" + +#: ../../po/../src/dialogs/find.cpp:591 +msgid "Search stars and polygons" +msgstr "Cerca stelle e poligoni" + +#: ../../po/../src/dialogs/find.cpp:591 +msgid "Stars" +msgstr "Stelle" + +#: ../../po/../src/dialogs/find.cpp:596 +msgid "Search spirals" +msgstr "Cerca spirali" + +#: ../../po/../src/dialogs/find.cpp:596 +msgid "Spirals" +msgstr "Spirali" + +#. TRANSLATORS: polyline is a set of connected straight line segments +#. http://www.w3.org/TR/SVG11/shapes.html#PolylineElement +#: ../../po/../src/dialogs/find.cpp:609 +msgid "Search paths, lines, polylines" +msgstr "Cerca percorsi, linee, poligonali" + +#: ../../po/../src/dialogs/find.cpp:609 +msgid "Paths" +msgstr "Percorsi" + +#: ../../po/../src/dialogs/find.cpp:614 +msgid "Search text objects" +msgstr "Cerca testi" + +#: ../../po/../src/dialogs/find.cpp:614 +msgid "Texts" +msgstr "Testi" + +#: ../../po/../src/dialogs/find.cpp:619 +msgid "Search groups" +msgstr "Cerca gruppi" + +#: ../../po/../src/dialogs/find.cpp:619 +msgid "Groups" +msgstr "Gruppi" + +#: ../../po/../src/dialogs/find.cpp:624 +msgid "Search clones" +msgstr "Cerca cloni" + +#: ../../po/../src/dialogs/find.cpp:629 +msgid "Search images" +msgstr "Cerca immagini" + +#: ../../po/../src/dialogs/find.cpp:629 +msgid "Images" +msgstr "Immagini" + +#: ../../po/../src/dialogs/find.cpp:634 +msgid "Search offset objects" +msgstr "Cerca proiezioni dell'oggetto" + +#: ../../po/../src/dialogs/find.cpp:634 +msgid "Offsets" +msgstr "Proiezioni" + +#: ../../po/../src/dialogs/find.cpp:694 +msgid "_Text: " +msgstr "_Testo: " + +#: ../../po/../src/dialogs/find.cpp:694 +msgid "Find objects by their text content (exact or partial match)" +msgstr "" +"Trova oggetti in base al contenuto testuale (corrispondenza esatta o " +"parziale)" + +#: ../../po/../src/dialogs/find.cpp:695 +msgid "_ID: " +msgstr "_ID: " + +#: ../../po/../src/dialogs/find.cpp:695 +msgid "Find objects by the value of the id attribute (exact or partial match)" +msgstr "" +"Trova oggetti in base al valore dell'attributo id (corrispondenza esatta o " +"parziale)" + +#: ../../po/../src/dialogs/find.cpp:696 +msgid "_Style: " +msgstr "_Stile: " + +#: ../../po/../src/dialogs/find.cpp:696 +msgid "" +"Find objects by the value of the style attribute (exact or partial match)" +msgstr "" +"Trova oggetti in base al valore dell'attributo stile (corrispondenza esatta " +"o parziale)" + +#: ../../po/../src/dialogs/find.cpp:697 +msgid "_Attribute: " +msgstr "_Attributi:" + +#: ../../po/../src/dialogs/find.cpp:697 +msgid "Find objects by the name of an attribute (exact or partial match)" +msgstr "" +"Trova oggetti in base al nome di un attributo (corrispondenza esatta o " +"parziale)" + +#: ../../po/../src/dialogs/find.cpp:711 +msgid "Search in s_election" +msgstr "Cerca nella s_elezione" + +#: ../../po/../src/dialogs/find.cpp:715 +msgid "Limit search to the current selection" +msgstr "Limita la ricerca alla selezione attuale" + +#: ../../po/../src/dialogs/find.cpp:720 +msgid "Search in current _layer" +msgstr "Cerca nel _livello attuale" + +#: ../../po/../src/dialogs/find.cpp:724 +msgid "Limit search to the current layer" +msgstr "Limita la ricerca al livello attuale" + +#: ../../po/../src/dialogs/find.cpp:729 +msgid "Include _hidden" +msgstr "Includi nascosti" + +#: ../../po/../src/dialogs/find.cpp:733 +msgid "Include hidden objects in search" +msgstr "Include nella ricerca gli oggetti nascosti" + +#: ../../po/../src/dialogs/find.cpp:738 +msgid "Include l_ocked" +msgstr "Includi bloccati" + +#: ../../po/../src/dialogs/find.cpp:742 +msgid "Include locked objects in search" +msgstr "Inlcude nella selezione gli oggetti bloccati" + +#: ../../po/../src/dialogs/find.cpp:753 +msgid "Clear values" +msgstr "Pulisci" + +#: ../../po/../src/dialogs/find.cpp:754 +msgid "_Find" +msgstr "_Trova" + +#: ../../po/../src/dialogs/find.cpp:754 +msgid "Select objects matching all of the fields you filled in" +msgstr "Cerca oggetti corrispondenti a tutti i campi spuntati" + +#: ../../po/../src/dialogs/iconpreview.cpp:145 +#, c-format +msgid "%d x %d" +msgstr "%d × %d" + +#: ../../po/../src/dialogs/iconpreview.cpp:193 +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:857 +#: ../../po/../src/widgets/desktop-widget.cpp:1069 +msgid "Selection" +msgstr "Selezione" + +#: ../../po/../src/dialogs/iconpreview.cpp:195 +msgid "Selection only or whole document" +msgstr "Solo selezione o l'intero documento" + +#: ../../po/../src/dialogs/iconpreview.cpp:203 +msgid "Refresh the icons" +msgstr "Aggiorna le icone" + +#. Create the label for the object id +#: ../../po/../src/dialogs/item-properties.cpp:126 +#: ../../po/../src/dialogs/item-properties.cpp:327 +#: ../../po/../src/dialogs/item-properties.cpp:396 +#: ../../po/../src/dialogs/item-properties.cpp:403 +msgid "_Id" +msgstr "_Id" + +#: ../../po/../src/dialogs/item-properties.cpp:135 +msgid "" +"The id= attribute (only letters, digits, and the characters .-_: allowed)" +msgstr "" +"L'attributo id= (sono ammessi solo lettere, numeri, e i caratteri .-_:)" + +#. Button for setting the object's id, label, title and description. +#: ../../po/../src/dialogs/item-properties.cpp:149 +msgid "_Set" +msgstr "Impo_sta" + +#. Create the label for the object label +#: ../../po/../src/dialogs/item-properties.cpp:158 +msgid "_Label" +msgstr "Etichet_ta" + +#: ../../po/../src/dialogs/item-properties.cpp:167 +msgid "A freeform label for the object" +msgstr "Un'etichetta personale per l'oggetto" + +#. Create the label for the object title +#: ../../po/../src/dialogs/item-properties.cpp:179 +#: ../../po/../src/dialogs/rdf.cpp:243 +msgid "Title" +msgstr "Titolo" + +#. Create the frame for the object description +#: ../../po/../src/dialogs/item-properties.cpp:196 +#: ../../po/../src/dialogs/rdf.cpp:287 +msgid "Description" +msgstr "Descrizione" + +#. Hide +#: ../../po/../src/dialogs/item-properties.cpp:223 +msgid "_Hide" +msgstr "Na_scondi" + +#: ../../po/../src/dialogs/item-properties.cpp:224 +msgid "Check to make the object invisible" +msgstr "Rende l'oggetto invisibile" + +#. Lock +#. TRANSLATORS: "Lock" is a verb here +#: ../../po/../src/dialogs/item-properties.cpp:233 +msgid "L_ock" +msgstr "Bl_occa" + +#: ../../po/../src/dialogs/item-properties.cpp:234 +msgid "Check to make the object insensitive (not selectable by mouse)" +msgstr "Rende l'oggetto bloccato (non selezionabile col mouse)" + +#: ../../po/../src/dialogs/item-properties.cpp:310 +#: ../../po/../src/dialogs/item-properties.cpp:317 +msgid "Ref" +msgstr "Riferimento" + +#: ../../po/../src/dialogs/item-properties.cpp:398 +msgid "Id invalid! " +msgstr "Id non valido! " + +#: ../../po/../src/dialogs/item-properties.cpp:400 +msgid "Id exists! " +msgstr "Id esistente!" + +#: ../../po/../src/dialogs/layer-properties.cpp:50 +msgid "Layer name:" +msgstr "Nome del livello:" + +#: ../../po/../src/dialogs/layer-properties.cpp:133 +msgid "Rename Layer" +msgstr "Rinomina livello" + +#: ../../po/../src/dialogs/layer-properties.cpp:136 +msgid "_Rename" +msgstr "_Rinomina" + +#. TRANSLATORS: This means "The layer has been renamed" +#: ../../po/../src/dialogs/layer-properties.cpp:147 +msgid "Renamed layer" +msgstr "Livello rinominato" + +#: ../../po/../src/dialogs/layer-properties.cpp:151 +msgid "Add Layer" +msgstr "Aggiungi livello" + +#: ../../po/../src/dialogs/layer-properties.cpp:153 +msgid "_Add" +msgstr "_Aggiungi" + +#: ../../po/../src/dialogs/layer-properties.cpp:167 +msgid "New layer created." +msgstr "Nuovo livello creato." + +#: ../../po/../src/dialogs/object-attributes.cpp:34 +msgid "Href:" +msgstr "Href:" + +#: ../../po/../src/dialogs/object-attributes.cpp:35 +msgid "Target:" +msgstr "Target:" + +#: ../../po/../src/dialogs/object-attributes.cpp:36 +msgid "Type:" +msgstr "Tipo:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkRoleAttribute +#. Identifies the type of the related resource with an absolute URI +#: ../../po/../src/dialogs/object-attributes.cpp:39 +msgid "Role:" +msgstr "Ruolo:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkArcRoleAttribute +#. For situations where the nature/role alone isn't enough, this offers an additional URI defining the purpose of the link. +#: ../../po/../src/dialogs/object-attributes.cpp:42 +msgid "Arcrole:" +msgstr "Ruolo aggiuntivo:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkTitleAttribute +#: ../../po/../src/dialogs/object-attributes.cpp:44 +msgid "Title:" +msgstr "Titolo:" + +#: ../../po/../src/dialogs/object-attributes.cpp:45 +msgid "Show:" +msgstr "Mostra:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkActuateAttribute +#: ../../po/../src/dialogs/object-attributes.cpp:47 +msgid "Actuate:" +msgstr "Attuazione:" + +#: ../../po/../src/dialogs/object-attributes.cpp:52 +msgid "URL:" +msgstr "URL:" + +#: ../../po/../src/dialogs/object-attributes.cpp:53 +msgid "X:" +msgstr "X:" + +#: ../../po/../src/dialogs/object-attributes.cpp:54 +msgid "Y:" +msgstr "Y:" + +#: ../../po/../src/dialogs/object-attributes.cpp:98 +#, c-format +msgid "%s attributes" +msgstr "%s attributi" + +#: ../../po/../src/dialogs/object-properties.cpp:158 +msgid "_Fill" +msgstr "Rie_mpimento" + +#: ../../po/../src/dialogs/object-properties.cpp:165 +msgid "Stroke _paint" +msgstr "Colore c_ontorno" + +#: ../../po/../src/dialogs/object-properties.cpp:172 +msgid "Stroke st_yle" +msgstr "St_ile contorno" + +#: ../../po/../src/dialogs/object-properties.cpp:183 +msgid "Master _opacity" +msgstr "_Opacità generale" + +#: ../../po/../src/dialogs/rdf.cpp:244 +msgid "Name by which this document is formally known." +msgstr "Il nome con cui viene formalmente conosciuto questo documento." + +#: ../../po/../src/dialogs/rdf.cpp:246 +msgid "Date" +msgstr "Data" + +#: ../../po/../src/dialogs/rdf.cpp:247 +msgid "Date associated with the creation of this document (YYYY-MM-DD)." +msgstr "Data associata alla creazione di questo documento (AAAA-MM-GG)." + +#: ../../po/../src/dialogs/rdf.cpp:249 +msgid "Format" +msgstr "Formato" + +#: ../../po/../src/dialogs/rdf.cpp:250 +msgid "The physical or digital manifestation of this document (MIME type)." +msgstr "Il formato fisico o digitale del documento (MIME type)." + +#: ../../po/../src/dialogs/rdf.cpp:252 +msgid "Type" +msgstr "Tipo" + +#: ../../po/../src/dialogs/rdf.cpp:253 +msgid "Type of document (DCMI Type)." +msgstr "Tipo del documento (DCMI type)" + +#: ../../po/../src/dialogs/rdf.cpp:256 +msgid "Creator" +msgstr "Creatore" + +#: ../../po/../src/dialogs/rdf.cpp:257 +msgid "" +"Name of entity primarily responsible for making the content of this document." +msgstr "Nome del reponsabile della creazione del documento." + +#: ../../po/../src/dialogs/rdf.cpp:259 +msgid "Rights" +msgstr "Diritti" + +#: ../../po/../src/dialogs/rdf.cpp:260 +msgid "" +"Name of entity with rights to the Intellectual Property of this document." +msgstr "Nome del detentore dei diritti intellettuali sul documento." + +#: ../../po/../src/dialogs/rdf.cpp:262 +msgid "Publisher" +msgstr "Editore" + +#: ../../po/../src/dialogs/rdf.cpp:263 +msgid "Name of entity responsible for making this document available." +msgstr "Nome del reponsabile della pubblicazione del documento." + +#: ../../po/../src/dialogs/rdf.cpp:266 +msgid "Identifier" +msgstr "Identificatore" + +#: ../../po/../src/dialogs/rdf.cpp:267 +msgid "Unique URI to reference this document." +msgstr "URI unico di riferimento al documento" + +#: ../../po/../src/dialogs/rdf.cpp:269 +msgid "Source" +msgstr "Sorgente" + +#: ../../po/../src/dialogs/rdf.cpp:270 +msgid "Unique URI to reference the source of this document." +msgstr "URI unico di riferimento alla sorgente del documento" + +#: ../../po/../src/dialogs/rdf.cpp:272 +msgid "Relation" +msgstr "Relazione" + +#: ../../po/../src/dialogs/rdf.cpp:273 +msgid "Unique URI to a related document." +msgstr "URI unico di riferimento al documento relazionato" + +#: ../../po/../src/dialogs/rdf.cpp:275 +msgid "Language" +msgstr "Lingua" + +#: ../../po/../src/dialogs/rdf.cpp:276 +msgid "" +"Two-letter language tag with optional subtags for the language of this " +"document. (e.g. 'en-GB')" +msgstr "" +"L'identificatore di due lettere della lingua e opzionalmente il sottocodice " +"per il paese per questo documento (es. 'it-IT')" + +#: ../../po/../src/dialogs/rdf.cpp:278 +msgid "Keywords" +msgstr "Parole chiave" + +#: ../../po/../src/dialogs/rdf.cpp:279 +msgid "" +"The topic of this document as comma-separated key words, phrases, or " +"classifications." +msgstr "" +"L'argomento del documento espresso in parole chiave, frasi, classificazioni " +"separate da virgole." + +#. TRANSLATORS: "Coverage": the spatial or temporal characteristics of the content. +#. For info, see Appendix D of http://www.w3.org/TR/1998/WD-rdf-schema-19980409/ +#: ../../po/../src/dialogs/rdf.cpp:283 +msgid "Coverage" +msgstr "Intento" + +#: ../../po/../src/dialogs/rdf.cpp:284 +msgid "Extent or scope of this document." +msgstr "Intento o scopo del documento." + +#: ../../po/../src/dialogs/rdf.cpp:288 +msgid "A short account of the content of this document." +msgstr "Una breve descrizione del contenuto del documento." + +#. FIXME: need to handle 1 agent per line of input +#: ../../po/../src/dialogs/rdf.cpp:292 +msgid "Contributors" +msgstr "Contributori" + +#: ../../po/../src/dialogs/rdf.cpp:293 +msgid "" +"Names of entities responsible for making contributions to the content of " +"this document." +msgstr "Nome dei contributori alla realizzazione del documento." + +#. TRANSLATORS: URL to a page that defines the license for the document +#: ../../po/../src/dialogs/rdf.cpp:297 +msgid "URI" +msgstr "URI" + +#. TRANSLATORS: this is where you put a URL to a page that defines the license +#: ../../po/../src/dialogs/rdf.cpp:299 +msgid "URI to this document's license's namespace definition." +msgstr "Indirizzo della licenza completa" + +#. TRANSLATORS: fragment of XML representing the license of the document +#: ../../po/../src/dialogs/rdf.cpp:303 +msgid "Fragment" +msgstr "Frammento" + +#: ../../po/../src/dialogs/rdf.cpp:304 +msgid "XML fragment for the RDF 'License' section." +msgstr "Frammento XML per la sezione 'License' delle RDF." + +#: ../../po/../src/dialogs/stroke-style.cpp:774 +#: ../../po/../src/widgets/gradient-vector.cpp:263 +#: ../../po/../src/widgets/paint-selector.cpp:751 +msgid "No document selected" +msgstr "Nessun documento selezionato" + +#: ../../po/../src/dialogs/stroke-style.cpp:992 +msgid "Stroke width" +msgstr "Larghezza contorno" + +#. Join type +#. TRANSLATORS: The line join style specifies the shape to be used at the +#. corners of paths. It can be "miter", "round" or "bevel". +#: ../../po/../src/dialogs/stroke-style.cpp:1015 +msgid "Join:" +msgstr "Spigoli:" + +#. TRANSLATORS: Miter join: joining lines with a sharp (pointed) corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1027 +msgid "Miter join" +msgstr "Spigolo vivo" + +#. TRANSLATORS: Round join: joining lines with a rounded corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1035 +msgid "Round join" +msgstr "Spigolo arrotondato" + +#. TRANSLATORS: Bevel join: joining lines with a blunted (flattened) corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1043 +msgid "Bevel join" +msgstr "Spigolo tagliato" + +#. Miterlimit +#. TRANSLATORS: Miter limit: only for "miter join", this limits the length +#. of the sharp "spike" when the lines connect at too sharp an angle. +#. When two line segments meet at a sharp angle, a miter join results in a +#. spike that extends well beyond the connection point. The purpose of the +#. miter limit is to cut off such spikes (i.e. convert them into bevels) +#. when they become too long. +#: ../../po/../src/dialogs/stroke-style.cpp:1054 +msgid "Miter limit:" +msgstr "Spigolosità:" + +#: ../../po/../src/dialogs/stroke-style.cpp:1062 +msgid "Maximum length of the miter (in units of stroke width)" +msgstr "" +"Lunghezza massima dello spigolo (nelle unità della larghezza del contorno)" + +#. Cap type +#. TRANSLATORS: cap type specifies the shape for the ends of lines +#: ../../po/../src/dialogs/stroke-style.cpp:1075 +msgid "Cap:" +msgstr "Estremi:" + +#. TRANSLATORS: Butt cap: the line shape does not extend beyond the end point +#. of the line; the ends of the line are square +#: ../../po/../src/dialogs/stroke-style.cpp:1086 +msgid "Butt cap" +msgstr "Estremo geometrico" + +#. TRANSLATORS: Round cap: the line shape extends beyond the end point of the +#. line; the ends of the line are rounded +#: ../../po/../src/dialogs/stroke-style.cpp:1093 +msgid "Round cap" +msgstr "Estremo arrotondato" + +#. TRANSLATORS: Square cap: the line shape extends beyond the end point of the +#. line; the ends of the line are square +#: ../../po/../src/dialogs/stroke-style.cpp:1100 +msgid "Square cap" +msgstr "Estremo squadrato" + +#. Dash +#: ../../po/../src/dialogs/stroke-style.cpp:1106 +msgid "Dashes:" +msgstr "Tratteggio:" + +#. TRANSLATORS: Path markers are an SVG feature that allows you to attach arbitrary shapes +#. (arrowheads, bullets, faces, whatever) to the start, end, or middle nodes of a path. +#: ../../po/../src/dialogs/stroke-style.cpp:1127 +msgid "Start Markers:" +msgstr "Delimitatore iniziale:" + +#: ../../po/../src/dialogs/stroke-style.cpp:1137 +msgid "Mid Markers:" +msgstr "Delimitatore medio:" + +#: ../../po/../src/dialogs/stroke-style.cpp:1148 +msgid "End Markers:" +msgstr "Delimitatore finale:" + +#: ../../po/../src/dialogs/swatches.cpp:424 +#, c-format +msgid "Palettes directory (%s) is unavailable." +msgstr "La cartella delle palette (%s) non è disponibile." + +#. TODO: Insert widgets +#: ../../po/../src/dialogs/text-edit.cpp:199 +#: ../../po/../src/ui/dialog/text-properties.cpp:36 +msgid "Font" +msgstr "Carattere" + +#: ../../po/../src/dialogs/text-edit.cpp:216 +msgid "Layout" +msgstr "Aspetto" + +#: ../../po/../src/dialogs/text-edit.cpp:229 +msgid "Align lines left" +msgstr "Allinea a sinistra" + +#. TRANSLATORS: `Center' here is a verb. +#: ../../po/../src/dialogs/text-edit.cpp:243 +msgid "Center lines" +msgstr "Centra" + +#: ../../po/../src/dialogs/text-edit.cpp:256 +msgid "Align lines right" +msgstr "Allinea a destra" + +#: ../../po/../src/dialogs/text-edit.cpp:278 +msgid "Horizontal text" +msgstr "Testo orizzontale" + +#: ../../po/../src/dialogs/text-edit.cpp:292 +msgid "Vertical text" +msgstr "Testo verticale" + +#: ../../po/../src/dialogs/text-edit.cpp:307 +msgid "Line spacing:" +msgstr "Spaziatura linee" + +#: ../../po/../src/dialogs/text-edit.cpp:400 +msgid "Set as default" +msgstr "Imposta come predefinito" + +#: ../../po/../src/dialogs/tiledialog.cpp:603 +msgid "Rows:" +msgstr "Righe:" + +#: ../../po/../src/dialogs/tiledialog.cpp:613 +msgid "Number of rows" +msgstr "Numero di righe" + +#: ../../po/../src/dialogs/tiledialog.cpp:617 +msgid "Equal height" +msgstr "Altezza uguale" + +#: ../../po/../src/dialogs/tiledialog.cpp:627 +msgid "If not set, each row has the height of the tallest object in it" +msgstr "Se non impostata, ogni riga ha l'altezza del suo oggetto più alto" + +#. #### Radio buttons to control vertical alignment #### +#. #### Radio buttons to control horizontal alignment #### +#: ../../po/../src/dialogs/tiledialog.cpp:637 +#: ../../po/../src/dialogs/tiledialog.cpp:708 +msgid "Align:" +msgstr "Allineamento:" + +#: ../../po/../src/dialogs/tiledialog.cpp:672 +msgid " X " +msgstr " X " + +#. #### Number of columns #### +#: ../../po/../src/dialogs/tiledialog.cpp:678 +msgid "Columns:" +msgstr "Colonne:" + +#: ../../po/../src/dialogs/tiledialog.cpp:688 +msgid "Number of columns" +msgstr "Numero di colonne" + +#: ../../po/../src/dialogs/tiledialog.cpp:692 +msgid "Equal width" +msgstr "Larghezza uguale" + +#: ../../po/../src/dialogs/tiledialog.cpp:701 +msgid "If not set, each column has the width of the widest object in it" +msgstr "" +"Se non impostata, ogni colonna ha la larghezza del suo oggetto più largo" + +#. #### Radio buttons to control spacing manually or to fit selection bbox #### +#: ../../po/../src/dialogs/tiledialog.cpp:746 +msgid "Fit into selection box" +msgstr "Adatta al riquadro della selezione" + +#: ../../po/../src/dialogs/tiledialog.cpp:753 +msgid "Set spacing:" +msgstr "Imposta Spaziatura:" + +#. #### Y Padding #### +#: ../../po/../src/dialogs/tiledialog.cpp:777 +msgid "Row spacing: " +msgstr "Spaziatura righe: " + +#: ../../po/../src/dialogs/tiledialog.cpp:786 +msgid "Vertical spacing between rows" +msgstr "Spaziatura verticale tra le righe" + +#. #### X padding #### +#: ../../po/../src/dialogs/tiledialog.cpp:795 +msgid "Column spacing:" +msgstr "Spaziatura colonne:" + +#: ../../po/../src/dialogs/tiledialog.cpp:804 +msgid "Horizontal spacing between columns" +msgstr "La spaziatura orizzontale tra le colonne" + +#: ../../po/../src/dialogs/tiledialog.cpp:818 +#, fuzzy +msgid "Arrange selected objects" +msgstr "Raggruppa gli oggetti selezionati" + +#: ../../po/../src/dialogs/xml-tree.cpp:178 +msgid "Click to select nodes, drag to rearrange." +msgstr "Clicca per selezionare i nodi, Spostali per sistemarli." + +#: ../../po/../src/dialogs/xml-tree.cpp:189 +msgid "Click attribute to edit." +msgstr "Clicca l'attributo da modificare." + +#: ../../po/../src/dialogs/xml-tree.cpp:193 +#, c-format +msgid "" +"Attribute %s selected. Press Ctrl+Enter when done editing to " +"commit changes." +msgstr "" +"Selezionato l'attributo %s. Premere Ctrl+Enter quando finito " +"per effettuare i cambiamenti." + +#: ../../po/../src/dialogs/xml-tree.cpp:284 +msgid "Drag to reorder nodes" +msgstr "Trascina per riordinare i nodi" + +#: ../../po/../src/dialogs/xml-tree.cpp:304 +msgid "New element node" +msgstr "Nuovo elemento nodo" + +#: ../../po/../src/dialogs/xml-tree.cpp:326 +msgid "New text node" +msgstr "Nuovo nodo testuale" + +#: ../../po/../src/dialogs/xml-tree.cpp:347 +msgid "Duplicate node" +msgstr "Duplica nodo" + +#: ../../po/../src/dialogs/xml-tree.cpp:368 +msgid "Delete node" +msgstr "Cancella nodo" + +#: ../../po/../src/dialogs/xml-tree.cpp:384 +msgid "Unindent node" +msgstr "Dis-indenta nodo" + +#: ../../po/../src/dialogs/xml-tree.cpp:399 +msgid "Indent node" +msgstr "Indenta nodo" + +#: ../../po/../src/dialogs/xml-tree.cpp:411 +msgid "Raise node" +msgstr "Alza nodo" + +#: ../../po/../src/dialogs/xml-tree.cpp:423 +msgid "Lower node" +msgstr "Abbassa nodo" + +#: ../../po/../src/dialogs/xml-tree.cpp:468 +msgid "Delete attribute" +msgstr "Cancella attributo" + +#. TRANSLATORS: "Attribute" is a noun here +#: ../../po/../src/dialogs/xml-tree.cpp:513 +msgid "Attribute name" +msgstr "Nome attributo" + +#. TRANSLATORS: "Set" is a verb here +#: ../../po/../src/dialogs/xml-tree.cpp:533 +msgid "Set attribute" +msgstr "Imposta attributo" + +#. TRANSLATORS: "Set" is a verb here +#: ../../po/../src/dialogs/xml-tree.cpp:535 +msgid "Set" +msgstr "Imposta" + +#. TRANSLATORS: "Attribute" is a noun here +#: ../../po/../src/dialogs/xml-tree.cpp:558 +msgid "Attribute value" +msgstr "Valore attributo" + +#: ../../po/../src/dialogs/xml-tree.cpp:1318 +msgid "New element node..." +msgstr "Nuovo elemento nodo..." + +#: ../../po/../src/dialogs/xml-tree.cpp:1339 +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:100 +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:98 +msgid "Cancel" +msgstr "Cancella" + +#: ../../po/../src/dialogs/xml-tree.cpp:1345 +msgid "Create" +msgstr "Crea" + +#: ../../po/../src/dialogs/xml-tree.cpp:1458 +#, c-format +msgid "" +"Cannot set %s: Another element with value %s already exists!" +msgstr "" +"Impossibile impostare %s:Esiste già una altro elemento con valore %" +"s!" + +#: ../../po/../src/document.cpp:369 +#, c-format +msgid "New document %d" +msgstr "Nuovo documento %d" + +#: ../../po/../src/document.cpp:401 +#, c-format +msgid "Memory document %d" +msgstr "Documento memoria %d" + +#: ../../po/../src/document.cpp:524 +#, c-format +msgid "Unnamed document %d" +msgstr "Documento senza nome %d" + +#. We hit green anchor, closing Green-Blue-Red +#: ../../po/../src/draw-context.cpp:441 +msgid "Path is closed." +msgstr "Il tracciato è chiuso." + +#. We hit bot start and end of single curve, closing paths +#: ../../po/../src/draw-context.cpp:456 +msgid "Closing path." +msgstr "Chiusura tracciato." + +#. alpha of color under cursor, to show in the statusbar +#. locale-sensitive printf is OK, since this goes to the UI, not into SVG +#: ../../po/../src/dropper-context.cpp:354 +#, c-format +msgid " alpha %.3g" +msgstr " alpha %.3g" + +#. where the color is picked, to show in the statusbar +#: ../../po/../src/dropper-context.cpp:356 +#, c-format +msgid ", averaged with radius %d" +msgstr ", medio con radiale %d" + +#: ../../po/../src/dropper-context.cpp:356 +msgid " under cursor" +msgstr " sotto il cursore" + +#. message, to show in the statusbar +#: ../../po/../src/dropper-context.cpp:358 +msgid "Release mouse to set color." +msgstr "Rilascia il mouse per impostare il colore." + +#: ../../po/../src/dropper-context.cpp:358 +#: ../../po/../src/tools-switch.cpp:207 +msgid "" +"Click to set fill, Shift+click to set stroke; drag to " +"average color in area; with Alt to pick inverse color; Ctrl+C " +"to copy the color under mouse to clipboard" +msgstr "" +"Cliccare per impostare il colore di riempimento, Maiusc+click " +"per impostare il colore del contorno; trascinare per prelevare il " +"colore medio di un area; con Alt per prelevare il colore inverso; " +"Ctrl+C per copiare negli appunti il colore sotto al mouse" + +#: ../../po/../src/extension/dependency.cpp:244 +msgid "Dependency::" +msgstr "Dipendenza::" + +#: ../../po/../src/extension/dependency.cpp:245 +msgid " type: " +msgstr " tipo: " + +#: ../../po/../src/extension/dependency.cpp:246 +msgid " location: " +msgstr " locazione: " + +#: ../../po/../src/extension/dependency.cpp:247 +msgid " string: " +msgstr " stringa: " + +#: ../../po/../src/extension/dependency.cpp:250 +msgid " description: " +msgstr " descrizione: " + +#. static int i = 0; +#. std::cout << "Checking module[" << i++ << "]: " << name << std::endl; +#: ../../po/../src/extension/extension.cpp:244 +msgid "" +" This is caused by an improper .inx file for this extension. An improper ." +"inx file could have been caused by a faulty installation of Inkscape." +msgstr "" +" Questo può essere stato causato da un file .inx per l'estensione scorretto." +"Un file .inx scorretto potrebbe essere causato da una installazione " +"problematica di Inkscape." + +#: ../../po/../src/extension/extension.cpp:247 +msgid "an ID was not defined for it." +msgstr "non è stato definito un ID in proposito." + +#: ../../po/../src/extension/extension.cpp:251 +msgid "there was no name defined for it." +msgstr "non è stato definito nessun nome in proposito." + +#: ../../po/../src/extension/extension.cpp:255 +msgid "the XML description of it got lost." +msgstr "la descrizione XML è andata perduta." + +#: ../../po/../src/extension/extension.cpp:259 +msgid "no implementation was defined for the extension." +msgstr "non è stata definita nessuna implementazione per l'estansione." + +#. std::cout << "Failed: " << *(_deps[i]) << std::endl; +#: ../../po/../src/extension/extension.cpp:266 +msgid "a dependency was not met." +msgstr "una dipendenza non è stata soddisfatta." + +#: ../../po/../src/extension/extension.cpp:286 +msgid "Extension \"" +msgstr "Impossibile caricare l'estensione \"" + +#: ../../po/../src/extension/extension.cpp:286 +msgid "\" failed to load because " +msgstr "\" perchè " + +#: ../../po/../src/extension/extension.cpp:565 +#, c-format +msgid "Could not create extension error log file '%s'" +msgstr "" +"Impossibile creare il file per il registro degli errori dell'estensione '%s'" + +#. This is some filler text, needs to change before relase +#: ../../po/../src/extension/error-file.cpp:56 +msgid "" +"One or more extensions failed to load\n" +"\n" +"The failed extensions have been skipped. Inkscape will continue to run " +"normally but those extensions will be unavailable. For details to " +"troubleshoot this problem, please refer to the error log located at: " +msgstr "" +"Errore nel caricamento di una o più " +"estensioni\n" +"\n" +"Le estensioni problematiche verranno ignorate. Inkscape continuerà a " +"funzionare normalmente ma queste estensioni non saranno disponibili. Per " +"ottenere dettagli per risolvere questo problema, consultare il registro " +"degli errori disponibile presso: " + +#. This is some filler text, needs to change before relase +#: ../../po/../src/extension/error-file.cpp:65 +msgid "Show dialog on startup" +msgstr "Mostra la finestra all'avvio" + +#: ../../po/../src/extension/implementation/script.cpp:845 +msgid "" +"Inkscape has received an error from the script that it called. The text " +"returned with the error is included below. Inkscape will continue working, " +"but the action you requested has been cancelled." +msgstr "" +"Inkscape ha ricevuto un errore dallo script invocato. Il testo restituito " +"dall'errore è disponibile più sotto. Inkscape continuerà a funzionare, ma " +"l'azione richiesta è stata annullata." + +#: ../../po/../src/extension/implementation/script.cpp:858 +msgid "" +"Inkscape has received additional data from the script executed. The script " +"did not return an error, but this may indicate the results will not be as " +"expected." +msgstr "" +"Inkscape ha ricevuto dei dati aggiuntivi dallo script invocato. Lo script " +"non ha riportato errori, ma questo potrebbe indicare che il risultato non è " +"quello atteso." + +#: ../../po/../src/extension/init.cpp:173 +msgid "Null external module directory name. Modules will not be loaded." +msgstr "" +"Nessun nome per la cartella dei moduli esterni. I moduli non verranno " +"caricati." + +#: ../../po/../src/extension/init.cpp:187 +#, c-format +msgid "" +"Modules directory (%s) is unavailable. External modules in that directory " +"will not be loaded." +msgstr "" +"La cartella dei moduli (%s) non è disponibile. I moduli esterni presenti in " +"questa cartella non verranno caricati." + +#: ../../po/../src/extension/internal/gnome.cpp:80 +msgid "Select printer" +msgstr "Seleziona stampante" + +#: ../../po/../src/extension/internal/gnome.cpp:131 +msgid "Inkscape: Print Preview" +msgstr "Inkscape: Anteprima di stampa" + +#: ../../po/../src/extension/internal/grid.cpp:213 +msgid "Line Width" +msgstr "Larghezza linea" + +#: ../../po/../src/extension/internal/grid.cpp:214 +msgid "Horizontal Spacing" +msgstr "Spaziatura Orizzontale" + +#: ../../po/../src/extension/internal/grid.cpp:215 +msgid "Vertical Spacing" +msgstr "Spaziatura verticale" + +#: ../../po/../src/extension/internal/grid.cpp:216 +msgid "Horizontal Offset" +msgstr "Proiezione orizzontale" + +#: ../../po/../src/extension/internal/grid.cpp:217 +msgid "Vertical Offset" +msgstr "Proiezione verticale" + +#: ../../po/../src/extension/internal/ps.cpp:123 +msgid "Print Destination" +msgstr "Destinazione stampa" + +#. Print properties frame +#: ../../po/../src/extension/internal/ps.cpp:138 +msgid "Print properties" +msgstr "Impostazioni stampa" + +#: ../../po/../src/extension/internal/ps.cpp:145 +msgid "Print using PostScript operators" +msgstr "Stampa usando gli operatori PostScript" + +#: ../../po/../src/extension/internal/ps.cpp:147 +msgid "" +"Use PostScript vector operators. The resulting image is usually smaller in " +"file size and can be arbitrarily scaled, but alpha transparency and patterns " +"will be lost." +msgstr "" +"Usa gli operatori vettoriali PostScript. L'immagine risultante solitamente è " +"di dimensioni più contenute e può essere ridimensionata a piacere, ma " +"verranno persi i motivi e la trasparenza alpha." + +#: ../../po/../src/extension/internal/ps.cpp:152 +msgid "Print as bitmap" +msgstr "Stampa come bitmap" + +#: ../../po/../src/extension/internal/ps.cpp:154 +msgid "" +"Print everything as bitmap. The resulting image is usually larger in file " +"size and cannot be arbitrarily scaled without quality loss, but all objects " +"will be rendered exactly as displayed." +msgstr "" +"Stampa tutto come bitmap. L'immagine risultante solitamente è di dimensioni " +"maggiori e non può essere ridimensionata senza una perdità di qualità, ma " +"tutti gli oggetti verranno disegnati esattamente come vengono mostrati." + +#: ../../po/../src/extension/internal/ps.cpp:168 +msgid "Preferred resolution (dots per inch) of bitmap" +msgstr "Risoluzione preferita della bitmap (in punti per pollice)" + +#: ../../po/../src/extension/internal/ps.cpp:182 +msgid "Resolution:" +msgstr "Risoluzione:" + +#. Print destination frame +#: ../../po/../src/extension/internal/ps.cpp:186 +msgid "Print destination" +msgstr "Destinazione stampa" + +#: ../../po/../src/extension/internal/ps.cpp:192 +msgid "" +"Use '> filename' to print to file.\n" +"Use '| prog arg...' to pipe to a program." +msgstr "" +"Usare '> filename' per stampare su file.\n" +"Usare '| prog arg...' per mandare in pipe ad un programma." + +#: ../../po/../src/extension/internal/ps.cpp:1227 +msgid "write error occurred" +msgstr "errore in scrittura" + +#: ../../po/../src/extension/prefdialog.cpp:21 +msgid " Preferences" +msgstr " Preferenze" + +#. We can't call sp_ui_error_dialog because we may be +#. running from the console, in which case calling sp_ui +#. routines will cause a segfault. See bug 1000350 - bryce +#. sp_ui_error_dialog(_("Format autodetect failed. The file is being opened as SVG.")); +#: ../../po/../src/extension/system.cpp:105 +msgid "Format autodetect failed. The file is being opened as SVG." +msgstr "" +"Impossibile la determinazione automatica del formato. Il file verrà aperto " +"come SVG." + +#. TRANSLATORS: default.svg is localizable - this is the name of the default document +#. template. This way you can localize the default pagesize, translate the name of +#. the default layer, etc. If you wish to localize this file, please create a +#. localized share/templates/default.xx.svg file, where xx is your language code. +#: ../../po/../src/file.cpp:133 +msgid "default.svg" +msgstr "default.it.svg" + +#: ../../po/../src/file.cpp:215 ../../po/../src/file.cpp:900 +#, c-format +msgid "Failed to load the requested file %s" +msgstr "Impossibile caricare il file %s" + +#: ../../po/../src/file.cpp:240 +msgid "Document not saved yet. Cannot revert." +msgstr "Documento non ancora salvato. Impossibile ricaricarlo." + +#: ../../po/../src/file.cpp:246 +#, c-format +msgid "Changes will be lost! Are you sure you want to reload document %s?" +msgstr "" +"Le modifiche andranno perdute! Sicuri di voler ricaricare il documento %s?" + +#: ../../po/../src/file.cpp:266 +msgid "Document reverted." +msgstr "Documento ricaricato." + +#: ../../po/../src/file.cpp:268 +msgid "Document not reverted." +msgstr "Documento non ricaricato." + +#: ../../po/../src/file.cpp:382 +msgid "Select file to open" +msgstr "Selezionare il file da aprire" + +#: ../../po/../src/file.cpp:518 +#, c-format +msgid "Removed %i unused definition in <defs>." +msgid_plural "Removed %i unused definitions in <defs>." +msgstr[0] "Rimossa %i definizione inutilizzata in <defs>." +msgstr[1] "Rimosse %i definizioni inutilizzate in <defs>." + +#: ../../po/../src/file.cpp:523 +msgid "No unused definitions in <defs>." +msgstr "Nessuna definizione inutilizzata in <defs>." + +#: ../../po/../src/file.cpp:548 +#, c-format +msgid "" +"No Inkscape extension found to save document (%s). This may have been " +"caused by an unknown filename extension." +msgstr "" +"Non è stata trovata alcuna estensione di Inkscape per salvare il documento (%" +"s). Ciò potrebbe esser stato causato da un'estensione del nome del file " +"sconosciuta." + +#: ../../po/../src/file.cpp:549 ../../po/../src/file.cpp:557 +msgid "Document not saved." +msgstr "Documento non salvato." + +#: ../../po/../src/file.cpp:556 +#, c-format +msgid "File %s could not be saved." +msgstr "Impossibile salvare il file %s." + +#: ../../po/../src/file.cpp:566 +msgid "Document saved." +msgstr "Documento salvato." + +#: ../../po/../src/file.cpp:614 +#, c-format +msgid "drawing%s" +msgstr "disegno%s" + +#: ../../po/../src/file.cpp:620 +#, c-format +msgid "drawing-%d%s" +msgstr "disegno-%d%s" + +#: ../../po/../src/file.cpp:655 +msgid "Select file to save to" +msgstr "Selezionare il file da salvare" + +#: ../../po/../src/file.cpp:739 +msgid "No changes need to be saved." +msgstr "Nessuna modifica da salvare." + +#: ../../po/../src/file.cpp:926 +msgid "Select file to import" +msgstr "Selezionare il file da importare" + +#: ../../po/../src/gradient-context.cpp:263 +msgid "Ctrl: snap gradient angle" +msgstr "Ctrl: fa scattare l'angolo del gradiente" + +#: ../../po/../src/gradient-context.cpp:264 +msgid "Shift: draw gradient around the starting point" +msgstr "Maiusc: disegna il gradiente attorno al punto iniziale" + +#. We did an undoable action, but sp_document_done will be called by the knot when released +#. status text; we do not track coords because this branch is run once, not all the time +#. during drag +#: ../../po/../src/gradient-context.cpp:462 +#, c-format +msgid "Gradient for %d objects; with Ctrl to snap angle" +msgstr "" +"Gradiente per %d oggetti; con Ctrl per far scattare l'angolo" + +#: ../../po/../src/gradient-context.cpp:464 +msgid "Select objects on which to create gradient." +msgstr "Selezionare l'oggetto su cui creare il gradiente." + +#: ../../po/../src/gradient-drag.cpp:65 +msgid "Linear gradient start" +msgstr "Inizio del gradiente lineare" + +#. POINT_LG_P1 +#: ../../po/../src/gradient-drag.cpp:66 +msgid "Linear gradient end" +msgstr "Fine del gradiente lineare" + +#: ../../po/../src/gradient-drag.cpp:67 +msgid "Radial gradient center" +msgstr "Centro del gradiente radiale" + +#: ../../po/../src/gradient-drag.cpp:68 ../../po/../src/gradient-drag.cpp:69 +msgid "Radial gradient radius" +msgstr "Raggio del gradiente radiale" + +#: ../../po/../src/gradient-drag.cpp:70 +msgid "Radial gradient focus" +msgstr "Fuoco del gradiente radiale" + +#: ../../po/../src/gradient-drag.cpp:659 +#, c-format +msgid "" +"%s for: %s%s; drag with Ctrl to snap angle, with Ctrl+Alt to " +"preserve angle, with Ctrl+Shift to scale around center" +msgstr "" +"%s per: %s%s; trascinare con Ctrl per far scattare l'angolo; con " +"Ctrl+Alt per mantenere l'angolo; con Ctrl+Maiusc per " +"ridimensionare attorno al centro" + +#: ../../po/../src/gradient-drag.cpp:662 +msgid " (stroke)" +msgstr " (contorno)" + +#: ../../po/../src/gradient-drag.cpp:665 +msgid "" +"Radial gradient center and focus; drag with Shift to " +"separate focus" +msgstr "" +"Centro e fuoco del gradiente radiale; trascinare con " +"Maiusc per separare il fuoco" + +#: ../../po/../src/gradient-drag.cpp:667 +#, c-format +msgid "" +"Gradient point shared by %d gradients; drag with Shift to " +"separate" +msgstr "" +"Punto del gradiente condiviso con %d gradienti; trascinare con " +"Maiusc per separare" + +#: ../../po/../src/helper/units.cpp:40 +msgid "Unit" +msgstr "Unità" + +#: ../../po/../src/helper/units.cpp:40 +msgid "Units" +msgstr "Unità" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Point" +msgstr "Punto" + +#: ../../po/../src/helper/units.cpp:41 +msgid "pt" +msgstr "pt" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Points" +msgstr "Punti" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Pt" +msgstr "Pt" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Pixel" +msgstr "Pixel" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Pixels" +msgstr "Pixel" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Px" +msgstr "Px" + +#. You can add new elements from this point forward +#: ../../po/../src/helper/units.cpp:44 ../share/extensions/straightseg.inx.h:2 +msgid "Percent" +msgstr "Percentuale" + +#: ../../po/../src/helper/units.cpp:44 +msgid "Percents" +msgstr "Percentuale" + +#: ../../po/../src/helper/units.cpp:45 +msgid "Millimeter" +msgstr "Millimetro" + +#: ../../po/../src/helper/units.cpp:45 +msgid "mm" +msgstr "mm" + +#: ../../po/../src/helper/units.cpp:45 +msgid "Millimeters" +msgstr "Millimetri" + +#: ../../po/../src/helper/units.cpp:46 +msgid "Centimeter" +msgstr "Centimetro" + +#: ../../po/../src/helper/units.cpp:46 +msgid "cm" +msgstr "cm" + +#: ../../po/../src/helper/units.cpp:46 +msgid "Centimeters" +msgstr "Centimetri" + +#: ../../po/../src/helper/units.cpp:47 +msgid "Meter" +msgstr "Metro" + +#: ../../po/../src/helper/units.cpp:47 +msgid "m" +msgstr "m" + +#: ../../po/../src/helper/units.cpp:47 +msgid "Meters" +msgstr "Metri" + +#. no svg_unit +#: ../../po/../src/helper/units.cpp:48 +msgid "Inch" +msgstr "Pollice" + +#: ../../po/../src/helper/units.cpp:48 +msgid "in" +msgstr "in" + +#: ../../po/../src/helper/units.cpp:48 +msgid "Inches" +msgstr "Pollici" + +#. Volatiles do not have default, so there are none here +#. TRANSLATORS: for info, see http://www.w3.org/TR/REC-CSS2/syndata.html#length-units +#: ../../po/../src/helper/units.cpp:51 +msgid "Em square" +msgstr "Riquadro Em" + +#: ../../po/../src/helper/units.cpp:51 +msgid "em" +msgstr "em" + +#: ../../po/../src/helper/units.cpp:51 +msgid "Em squares" +msgstr "Riquadri Em" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/REC-CSS2/syndata.html#length-units +#: ../../po/../src/helper/units.cpp:53 +msgid "Ex square" +msgstr "Riquadro Ex" + +#: ../../po/../src/helper/units.cpp:53 +msgid "ex" +msgstr "ex" + +#: ../../po/../src/helper/units.cpp:53 +msgid "Ex squares" +msgstr "Riquadri Ex" + +#: ../../po/../src/inkscape.cpp:468 +msgid "Untitled document" +msgstr "Documento senza nome" + +#. Show nice dialog box +#: ../../po/../src/inkscape.cpp:497 +msgid "Inkscape encountered an internal error and will close now.\n" +msgstr "" +"Si è verificato un errore interno ed Inkscape verrà chiuso immediatamente.\n" + +#: ../../po/../src/inkscape.cpp:498 +msgid "" +"Automatic backups of unsaved documents were done to the following " +"locations:\n" +msgstr "" +"I backup automatici dei documenti non salvati sono stati fatti ai seguenti " +"indirizzi:\n" + +#: ../../po/../src/inkscape.cpp:499 +msgid "Automatic backup of the following documents failed:\n" +msgstr "Fallito il backup automatico dei seguenti documenti:\n" + +#: ../../po/../src/inkscape.cpp:634 +#, c-format +msgid "" +"Cannot create directory %s.\n" +"%s" +msgstr "" +"Impossibile creare la cartella %s.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:635 +#, c-format +msgid "" +"%s is not a valid directory.\n" +"%s" +msgstr "" +"%s non è una cartella valida.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:636 +#, c-format +msgid "" +"Cannot create file %s.\n" +"%s" +msgstr "" +"Impossibile creare il file %s.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:637 +#, c-format +msgid "" +"Cannot write file %s.\n" +"%s" +msgstr "" +"Impossibile scrivere il file %s.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:638 +msgid "" +"Although Inkscape will run, it will use default settings,\n" +"and any changes made in preferences will not be saved." +msgstr "" +"Nonostante Inkscape venga eseguito, userà le impostazione predefinite,\n" +"e ogni modifica fatta alle impostazioni non verrà salvata." + +#: ../../po/../src/inkscape.cpp:708 +#, c-format +msgid "" +"%s is not a regular file.\n" +"%s" +msgstr "" +"%s non è un file regolare.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:709 +#, c-format +msgid "" +"%s not a valid XML file, or\n" +"you don't have read permissions on it.\n" +"%s" +msgstr "" +"%s non è un file XML valido, oppure\n" +"non si hanno i permessi per leggerlo.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:711 +#, c-format +msgid "" +"%s is not a valid menus file.\n" +"%s" +msgstr "" +"%s non è un file di menù valido.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:712 +msgid "" +"Inkscape will run with default menus.\n" +"New menus will not be saved." +msgstr "" +"Inkscape verrà eseguito con i menù predefiniti.\n" +"I nuovi menù non verranno salvati." + +#. sp_ui_menu_append_check_item_from_verb(m, view, _("_Menu"), _("Show or hide the menu bar"), "menu", +#. checkitem_toggled, checkitem_update, 0); +#: ../../po/../src/interface.cpp:753 +msgid "Commands Bar" +msgstr "Barra dei comandi" + +#: ../../po/../src/interface.cpp:753 +msgid "Show or hide the Commands bar (under the menu)" +msgstr "Mostra o nasconde la barra dei dei comandi (sotto il menu)" + +#: ../../po/../src/interface.cpp:755 +msgid "Tool Controls" +msgstr "Controlli strumento" + +#: ../../po/../src/interface.cpp:755 +msgid "Show or hide the Tool Controls panel" +msgstr "Mostra o nasconde il pannello dei controlli degli strumenti" + +# cfr la traduzione di Illustrator +#: ../../po/../src/interface.cpp:757 +msgid "_Toolbox" +msgstr "Barra degli s_trumenti" + +#: ../../po/../src/interface.cpp:757 +msgid "Show or hide the main toolbox (on the left)" +msgstr "Mostra o nasconde la barra degli strumenti (sulla sinistra)" + +#: ../../po/../src/interface.cpp:763 +msgid "_Statusbar" +msgstr "Barra di _stato" + +#: ../../po/../src/interface.cpp:763 +msgid "Show or hide the statusbar (at the bottom of the window)" +msgstr "Mostra o nasconde la barra di stato (in fondo alla finestra)" + +# Verb dovrebbe essere parola chiave per menù scritti in XML +# del GTK+ versione 2.6 o superiore -Luca +#: ../../po/../src/interface.cpp:820 +#, c-format +msgid "Verb \"%s\" Unknown" +msgstr "Verb \"%s\" sconosciuto" + +#. TRANSLATORS: #%s is the id of the group e.g. , not a number. +#: ../../po/../src/interface.cpp:930 +#, c-format +msgid "Enter group #%s" +msgstr "Modifica gruppo #%s" + +#: ../../po/../src/interface.cpp:941 +msgid "Go to parent" +msgstr "Livello superiore" + +#: ../../po/../src/interface.cpp:972 +msgid "Could not parse SVG data" +msgstr "Impossibile leggere i dati SVG" + +#: ../../po/../src/interface.cpp:1135 +#, c-format +msgid "Overwrite %s" +msgstr "Sovrascrivere %s" + +#: ../../po/../src/interface.cpp:1153 +#, c-format +msgid "" +"The file %s already exists. Do you want to overwrite that file with the " +"current document?" +msgstr "" +"Il file %s esiste già. Sovrascrivere questo file con il documento attuale?" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:59 +msgid "Jabber connection lost." +msgstr "Connessione Jabber persa." + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:72 +#, c-format +msgid "Sending message; %u message remaining in send queue." +msgid_plural "Sending message; %u messages remaining in send queue." +msgstr[0] "Invio messaggio; %u messaggio da spedire in coda." +msgstr[1] "Invio messaggio; %u messaggi da spedire in coda." + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:78 +msgid "Receive queue empty." +msgstr "Coda di ricezione vuota." + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:154 +#, c-format +msgid "Receiving change; %u change left to process." +msgid_plural "Receiving change; %u changes left to process." +msgstr[0] "Ricezione modifiche; %u modifica ancora da processare." +msgstr[1] "Ricezione modifiche; %u modifiche ancora da processare." + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:157 +#, c-format +msgid "%s has left the chatroom." +msgstr "%s ha lasciato la chatroom." + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:221 +msgid "Nickname %1 is already in use. Please choose a different nickname." +msgstr "Il nickname %1 è già in uso. Sceglierne uno differente." + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:225 +msgid "An error was encountered while attempting to connect to the server." +msgstr "" +"Si è verificato un errore durate il tentativo di connettersi al server." + +#. Check to see if the user made any modifications to this document. If so, +#. we want to give them the option of (1) letting us clear their document or (2) +#. opening a new, blank document for the whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:131 +msgid "%1 has invited you to a whiteboard session." +msgstr "%1 ti ha invitato ad una sessione whiteboard." + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:132 +msgid "Incoming whiteboard invitation from %1" +msgstr "In arrivo invito per sessione whiteboard da %1" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:135 +msgid "Do you wish to accept %1's whiteboard session invitation?" +msgstr "Accettare l'invito di %1 alla sessione whiteboard?" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:137 +msgid "" +"Would you like to accept %1's invitation in a new document window?\n" +"Accepting the invitation in your current window will discard unsaved changes." +msgstr "" +"Si vuole accettare l'invito di %1 in una nuova finestra di documento?\n" +"Se si accetta l'invito nella finestra in uso, si perderanno le modifiche non " +"salvate." + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:143 +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:198 +msgid "Accept invitation" +msgstr "Accetta invito" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:144 +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:199 +msgid "Decline invitation" +msgstr "Declina invito" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:145 +msgid "Accept invitation in new document window" +msgstr "Accetta invito in una nuova finestra di documento" + +#. We could not create a new desktop; ask the user if she or he wants to +#. replace the current document and accept the invitation, or reject the invitation. +#. TRANSLATORS: %1 is a userid here +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:196 +msgid "" +"A new document window could not be opened for a whiteboard session with %" +"1" +msgstr "" +"Non è possibile aprire una nuova finestra di documento per una sessione " +"whiteboard con %1" + +#. TRANSLATORS: %1 is the peer whom refused our invitation. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:238 +msgid "" +"The user %1 has refused your " +"whiteboard invitation.\n" +"\n" +msgstr "" +"L'utente %i ha rifiutato l'invito " +"whiteboard.\n" +"\n" + +#. TRANSLATORS: %1 is the peer whom refused our invitation, %2 is our Jabber identity. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:241 +msgid "" +"You are still connected to a Jabber server as %2, and may send an " +"invitation to %1 again, or you may send an invitation to a different " +"user." +msgstr "" +"Si è ancora connessi ad un server Jabber come %2 ed è possibile " +"inviare nuovamente un invito a %1 oppure un invito ad un diverso " +"utente." + +#. TRANSLATORS: %1 is the peer whom we tried to contact, but is already in a whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:252 +msgid "" +"The user %1 is already in a " +"whiteboard session.\n" +"\n" +msgstr "" +"L'utente %i è già in una sessione " +"whiteboard\n" +"\n" + +#. TRANSLATORS: %1 is the peer whom we tried to contact, but is already in a whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:255 +msgid "" +"You are still connected to a Jabber server as %1, and may send an " +"invitation to a different user." +msgstr "" +"Si è ancora connessi ad un server Jabber come %2 ed è possibile " +"inviare un invito ad un diverso utente." + +#: ../../po/../src/jabber_whiteboard/invitation-confirm-dialog.cpp:26 +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:24 +msgid "_Write session file:" +msgstr "_Scrivi file sessione:" + +#: ../../po/../src/jabber_whiteboard/message-processors.cpp:145 +#, c-format +msgid "%s has joined the chatroom." +msgstr "%s si è unito alla chatroom." + +#: ../../po/../src/jabber_whiteboard/message-queue.cpp:87 +#, c-format +msgid "%u change in receive queue." +msgid_plural "%u changes in receive queue." +msgstr[0] "%u modifica nella coda di ricezione." +msgstr[1] "%u modifiche nella coda di ricezione." + +#: ../../po/../src/jabber_whiteboard/message-queue.cpp:117 +#, c-format +msgid "%u change in send queue." +msgid_plural "%u changes in send queue." +msgstr[0] "%u modifica nella coda di invio." +msgstr[1] "%u modifiche nella coda di invio." + +#. if ID is NULL, then we have a real problem -- we were not able to find a key +#. nor generate one. The only thing we can really do here is abort, since we have +#. no way to let the other client(s) uniquely identify this object. +#. FIXME: If this indicates a programming bug, then don't request translation with +#. * _(...): it is most useful in untranslated form so that developers may search for +#. * it when someone reports it in a bug report (as we want users to do for all bugs, +#. * as indicated by it being a g_warning string). +#. * +#. * Otherwise, if it is not a programming bug but a network error or a bug in the +#. * remote peer (perhaps running different software) or whatever, then present it in +#. * an alert box, and avoid use of technical jargon `NULL'. +#. +#: ../../po/../src/jabber_whiteboard/message-utilities.cpp:171 +msgid "" +"ID for new object is NULL even after generation and lookup attempts: the new " +"object will NOT be sent, nor will any of its child objects!" +msgstr "" +"L'ID del nuovo oggetto è NULL anche dopo i tentativi di generazione e " +"controllo: il nuovo oggetto NON verrà inviato, così come nessuno dei suoi " +"oggetti figli!" + +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:60 +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:995 +msgid "Select a location and filename" +msgstr "Selezionare posizione e nome del file" + +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:62 +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:997 +msgid "Set filename" +msgstr "Imposta nome file" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:301 +msgid "No SSL certificate was found." +msgstr "Non è stato trovato alcun certificato SSL." + +# untrusted -> non fidato (stessa traduzione epiphany) +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:304 +msgid "The SSL certificate provided by the Jabber server is untrusted." +msgstr "Il certificato SSL fornito dal server Jabber non è fidato." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:307 +msgid "The SSL certificate provided by the Jabber server is expired." +msgstr "Il certificato SSL fornito dal server Jabber è scaduto." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:310 +msgid "" +"The SSL certificate provided by the Jabber server has not been activated." +msgstr "" +"Il certificato SSL fornito dal server Jabber non è ancora stato attivato." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:313 +msgid "" +"The SSL certificate provided by the Jabber server contains a hostname that " +"does not match the Jabber server's hostname." +msgstr "" +"Il certificato SSL fornito dal server Jabber contiene un nome host che non " +"corrisponde al nome host del server stesso." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:316 +msgid "" +"The SSL certificate provided by the Jabber server contains an invalid " +"fingerprint." +msgstr "" +"Il certificato SSL fornito dal server Jabber contiere un fingerprint non " +"valido." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:319 +msgid "An unknown error occurred while setting up the SSL connection." +msgstr "" +"Si è verificato un errore sconosciuto durate l'impostazione della " +"connessione SSL." + +#. TRANSLATORS: %1 is the message that describes the specific error that occurred when +#. establishing the SSL connection. +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:325 +msgid "" +"%1\n" +"\n" +"Do you wish to continue connecting to the Jabber server?" +msgstr "" +"%1\n" +"\n" +"Continuare la connessione al server Jabber?" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:328 +msgid "Continue connecting and ignore further errors" +msgstr "Continuare la connessione ed ignorare ulteriori errori" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:329 +msgid "Continue connecting, but warn me of further errors" +msgstr "Continuare la connessione, ma avvisare per ulteriori errori" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:330 +msgid "Cancel connection" +msgstr "Annulla connessione" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:777 +#, c-format +msgid "Established whiteboard session with %s." +msgstr "Instaurata sessione whiteboard con %s." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:785 +#, c-format +msgid "%s has left the whiteboard session." +msgstr "%s ha lasciato la sessione whiteboard." + +#. Inform the user +#. TRANSLATORS: %1 is the name of the user that disconnected, %2 is the name of the user whom the disconnected user disconnected from. +#. This message is not used in a chatroom context. +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:790 +msgid "" +"The user %1 has left the " +"whiteboard session.\n" +"\n" +msgstr "" +"L'utente %1 ha lasciato la sessione " +"whiteboard.\n" +"\n" + +#. TRANSLATORS: %1 and %2 are userids +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:792 +msgid "" +"You are still connected to a Jabber server as %2, and may establish a " +"new session to %1 or a different user." +msgstr "" +"Si è ancora connessi al server Jabber come %2 ed è possibile " +"instaurare una nuova sessione con %1 o con un diverso utente." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:988 +msgid "" +"Could not open file %1 for session recording.\n" +"The error encountered was: %2.\n" +"\n" +"You may select a different location to record the session, or you may opt to " +"not record this session." +msgstr "" +"Impossibile aprire il file %1 per la registrazione della sessione.\n" +"L'errore incontrato è stato: %2.\n" +"\n" +"È possibile selezionare una diversa posizione per la registrazione della " +"sessione, oppure scegliere di non registrare la sessione." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:990 +msgid "Choose a different location" +msgstr "Scegliere una posizione differente" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:991 +msgid "Skip session recording" +msgstr "Omettere registrazione della sessione" + +#: ../../po/../src/knot.cpp:673 +msgid "Node or handle drag canceled." +msgstr "Nodo o maniglia cancellato." + +#: ../../po/../src/libnrtype/FontFactory.cpp:358 +msgid "Ignoring font without family that will crash Pango" +msgstr "I font senza famiglia che fanno andare in Crash Pango vengono ingorati" + +#: ../../po/../src/main.cpp:395 +msgid "Print the Inkscape version number" +msgstr "Mostra la versione di Inkscape" + +#: ../../po/../src/main.cpp:400 +msgid "Do not use X server (only process files from console)" +msgstr "Non usare il server X (processa i file da console)" + +#: ../../po/../src/main.cpp:405 +msgid "Try to use X server (even if $DISPLAY is not set)" +msgstr "Prova a usare il server X (anche se $DISPLAY non è impostata)" + +#: ../../po/../src/main.cpp:410 +msgid "Open specified document(s) (option string may be excluded)" +msgstr "Apre il documento specificato (le opzioni possono essere omesse)" + +#: ../../po/../src/main.cpp:411 ../../po/../src/main.cpp:416 +#: ../../po/../src/main.cpp:421 ../../po/../src/main.cpp:483 +#: ../../po/../src/main.cpp:488 ../../po/../src/main.cpp:493 +msgid "FILENAME" +msgstr "NOMEFILE" + +#: ../../po/../src/main.cpp:415 +msgid "Print document(s) to specified output file (use '| program' for pipe)" +msgstr "" +"Stampa il documento al file di output specificato (usare'|·programma' per il " +"pipe)" + +#: ../../po/../src/main.cpp:420 +msgid "Export document to a PNG file" +msgstr "Esporta il documento come file PNG" + +#: ../../po/../src/main.cpp:425 +msgid "The resolution used for exporting SVG into bitmap (default 90)" +msgstr "La risoluzione per esportare SVG in bitmap (predefinita 90)" + +#: ../../po/../src/main.cpp:426 +msgid "DPI" +msgstr "DPI" + +#: ../../po/../src/main.cpp:430 +msgid "" +"Exported area in SVG user units (default is the canvas; 0,0 is lower-left " +"corner)" +msgstr "" +"L'area esportata in unità utente SVG (predefinita tutta la tela; 0,0 è " +"l'angolo inferiore sinistro)" + +#: ../../po/../src/main.cpp:431 +msgid "x0:y0:x1:y1" +msgstr "x0:y0:x1:y1" + +#: ../../po/../src/main.cpp:435 +msgid "Exported area is the entire drawing (not canvas)" +msgstr "L'area esportata è il disegno intero (non la tela)" + +#: ../../po/../src/main.cpp:440 +msgid "" +"Snap the bitmap export area outwards to the nearest integer values (in SVG " +"user units)" +msgstr "" +"Aggancia l'area esterna di esportazione bitmap al valore intero più vicino " +"(in unità utente SVG)" + +#: ../../po/../src/main.cpp:445 +msgid "The width of exported bitmap in pixels (overrides export-dpi)" +msgstr "La larghezza in pixel della bitmap esportata (precede export-dpi)" + +#: ../../po/../src/main.cpp:446 +msgid "WIDTH" +msgstr "LARGHEZZA" + +#: ../../po/../src/main.cpp:450 +msgid "The height of exported bitmap in pixels (overrides export-dpi)" +msgstr "L'altezza in pixel della bitmap esportata (precede export-dpi)" + +#: ../../po/../src/main.cpp:451 +msgid "HEIGHT" +msgstr "ALTEZZA" + +#: ../../po/../src/main.cpp:455 +msgid "The ID of the object to export (overrides export-area)" +msgstr "L'ID dell'oggetto da esportare (precede export-area)" + +#: ../../po/../src/main.cpp:456 ../../po/../src/main.cpp:532 +msgid "ID" +msgstr "ID" + +#. TRANSLATORS: this means: "Only export the object whose id is given in --export-id". +#. See "man inkscape" for details. +#: ../../po/../src/main.cpp:462 +msgid "" +"Export just the object with export-id, hide all others (only with export-id)" +msgstr "" +"Esporta solo l'oggetto con l'export-id dato, nasconde tutti gli altri (solo " +"con export-id)" + +#: ../../po/../src/main.cpp:467 +msgid "Use stored filename and DPI hints when exporting (only with export-id)" +msgstr "" +"Usa il nome del file e il valore DPI salvato quando esporta (solo con export-" +"id)" + +#: ../../po/../src/main.cpp:472 +msgid "Background color of exported bitmap (any SVG-supported color string)" +msgstr "" +"Colore di sfondo della bitmap esportata (ogni stringa di colore supportata " +"da SVG)" + +#: ../../po/../src/main.cpp:473 +msgid "COLOR" +msgstr "COLORE" + +#: ../../po/../src/main.cpp:477 +msgid "Background opacity of exported bitmap (either 0.0 to 1.0, or 1 to 255)" +msgstr "" +"Opacità dello sfondo della bitmap esportata (sia da 0.0 a 1.0, che da 1 a " +"255)" + +#: ../../po/../src/main.cpp:478 +msgid "VALUE" +msgstr "VALORE" + +#: ../../po/../src/main.cpp:482 +msgid "Export document to plain SVG file (no sodipodi or inkscape namespaces)" +msgstr "" +"Esporta il documento come SVG puro (senza i namespace di sodipodi o di " +"inkscape)" + +#: ../../po/../src/main.cpp:487 +msgid "Export document to a PS file" +msgstr "Esporta il documento come file PS" + +#: ../../po/../src/main.cpp:492 +msgid "Export document to an EPS file" +msgstr "Esporta il documento come file EPS" + +#: ../../po/../src/main.cpp:497 +msgid "Convert text object to paths on export (EPS)" +msgstr "Converte i testi in tracciati durante l'esportazione (EPS)" + +#: ../../po/../src/main.cpp:502 +msgid "Export files with the bounding box set to the page size (EPS)" +msgstr "" +"Esporta i file con il riquadro impostato alla dimensione della pagina (EPS)" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:508 +msgid "" +"Query the X coordinate of the drawing or, if specified, of the object with --" +"query-id" +msgstr "" +"Richiede la cordinata X del disegno o dell'oggetto se specificato con --" +"query-id" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:514 +msgid "" +"Query the Y coordinate of the drawing or, if specified, of the object with --" +"query-id" +msgstr "" +"Richiede la cordinata Y del disegno o dell'oggetto se specificato con --" +"query-id" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:520 +msgid "" +"Query the width of the drawing or, if specified, of the object with --query-" +"id" +msgstr "" +"Richiede la larghezza del disegno o dell'oggetto se specificato con --query-" +"id" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:526 +msgid "" +"Query the height of the drawing or, if specified, of the object with --query-" +"id" +msgstr "" +"Richiede l'altezza del disegno o dell'oggetto se specificato con --query-id" + +#: ../../po/../src/main.cpp:531 +msgid "The ID of the object whose dimensions are queried" +msgstr "L'ID dell'oggetto di cui si richiedono le dimensioni" + +#. TRANSLATORS: this option makes Inkscape print the name (path) of the extension directory +#: ../../po/../src/main.cpp:537 +msgid "Print out the extension directory and exit" +msgstr "Stampa la directory delle estensioni e esce" + +#: ../../po/../src/main.cpp:542 +msgid "Show given files one-by-one, switch to next on any key/mouse event" +msgstr "" +"Mostra i file uno alla volta, passa al successivo ad ogni evento del mouse o " +"dei tasti" + +#: ../../po/../src/main.cpp:547 +msgid "Use the new Gtkmm GUI interface" +msgstr "Usa la nuova interfaccia grafica con Gtkmm" + +#: ../../po/../src/main.cpp:552 +msgid "Remove unused definitions from the defs section(s) of the document" +msgstr "Elimina definizioni superflue dalle sezioni defs del documento" + +#: ../../po/../src/main.cpp:741 +msgid "" +"[OPTIONS...] [FILE...]\n" +"\n" +"Available options:" +msgstr "" +"[OPZIONI...] [FILE...]\n" +"\n" +"Opzioni disponibili:" + +#: ../../po/../src/menus-skeleton.h:17 +msgid "_New" +msgstr "_Nuovo" + +#: ../../po/../src/menus-skeleton.h:22 +msgid "Open _Recent" +msgstr "Apri _recente" + +#: ../../po/../src/menus-skeleton.h:53 +msgid "_Edit" +msgstr "_Modifica" + +#: ../../po/../src/menus-skeleton.h:84 +msgid "_View" +msgstr "_Visualizza" + +#: ../../po/../src/menus-skeleton.h:85 +#, fuzzy +msgid "_Zoom" +msgstr "Ingrandimento" + +#: ../../po/../src/menus-skeleton.h:102 +msgid "Show/Hide" +msgstr "Mostra/Nascondi" + +#: ../../po/../src/menus-skeleton.h:107 +msgid "_Display mode" +msgstr "" + +#: ../../po/../src/menus-skeleton.h:126 +msgid "_Layer" +msgstr "_Livello" + +#: ../../po/../src/menus-skeleton.h:143 +msgid "_Object" +msgstr "_Oggetto" + +#: ../../po/../src/menus-skeleton.h:165 +msgid "_Path" +msgstr "_Tracciato" + +#: ../../po/../src/menus-skeleton.h:188 +msgid "_Text" +msgstr "_Testo" + +#: ../../po/../src/menus-skeleton.h:200 +msgid "Effects" +msgstr "Effetti" + +#: ../../po/../src/menus-skeleton.h:207 +msgid "Whiteboa_rd" +msgstr "Whiteboa_rd" + +#: ../../po/../src/menus-skeleton.h:220 +msgid "_Help" +msgstr "Ai_uto" + +#: ../../po/../src/menus-skeleton.h:222 +msgid "Tutorials" +msgstr "Lezioni" + +#: ../../po/../src/node-context.cpp:382 +msgid "" +"Ctrl: toggle node type, snap handle angle, move hor/vert; Ctrl" +"+Alt: move along handles" +msgstr "" +"Ctrl: cambia il tipo di nodo, fa scattare l'angolo della maniglia, " +"muove oriz/vert; Ctrl+Alt: muove tra le maniglie" + +#: ../../po/../src/node-context.cpp:383 +msgid "" +"Shift: toggle node selection, disable snapping, rotate both handles" +msgstr "" +"Maiusc: commuta la selezione del nodo, disabilita lo scatto, ruota " +"entrambe le maniglie" + +#: ../../po/../src/node-context.cpp:384 +msgid "Alt: lock handle length; Ctrl+Alt: move along handles" +msgstr "" +"Alt: blocca la lunghezza della maniglia; Ctrl+Alt: muove tra " +"le maniglie" + +#: ../../po/../src/nodepath.cpp:1399 ../../po/../src/nodepath.cpp:1411 +#: ../../po/../src/nodepath.cpp:1492 ../../po/../src/nodepath.cpp:1504 +msgid "To join, you must have two endnodes selected." +msgstr "Bisogna aver selezionato due nodi finali per unirli." + +#: ../../po/../src/nodepath.cpp:1633 ../../po/../src/nodepath.cpp:1647 +msgid "" +"Select two non-endpoint nodes on a path between which to delete " +"segments." +msgstr "" +"Selezionare due nodi non finali da cui cancellare il segmento di " +"tracciato." + +#: ../../po/../src/nodepath.cpp:1743 +msgid "Cannot find path between nodes." +msgstr "Impossibile trovare un tracciato tra i nodi." + +# -Luca +# angoli a scatti????? Però è quullo che fa :-) +# PS io toglierei i "con .." +#: ../../po/../src/nodepath.cpp:2822 +#, c-format +msgid "" +"Node handle: angle %0.2f°, length %s; with Ctrl to snap " +"angle; with Alt to lock length; with Shift to rotate both " +"handles" +msgstr "" +"Maniglia del nodo: angolo %0.2f°, lunghezza %s; Ctrl per " +"angoli a scatti; Alt per bloccare la lunghezza; Maiusc per " +"ruotare entrambe le maniglie" + +#: ../../po/../src/nodepath.cpp:3351 +msgid "" +"Node: drag to edit the path; with Ctrl to snap to horizontal/" +"vertical; with Ctrl+Alt to snap to handles' directions" +msgstr "" +"Nodo: trascinare per modificare il tracciato; con Ctrl per far " +"scattare in oriz/vert; con Ctrl+Alt per far scattare sulle maniglie " +"di direzione" + +#: ../../po/../src/nodepath.cpp:3375 +msgid "" +"Node handle: drag to shape the curve; with Ctrl to snap angle; " +"with Alt to lock length; with Shift to rotate both handles" +msgstr "" +"Maniglia del nodo: trascinare per formare la curva; con Ctrl " +"per far scattare l'angolo; con Alt per bloccare la lunghezza; con " +"Maiusc per ruotare in sincronia la maniglia opposta" + +#: ../../po/../src/nodepath.cpp:3399 +msgid "" +"Node handle: drag to shape the curve; with Ctrl to snap angle; " +"with Alt to lock length; with Shift to rotate the opposite " +"handle in sync" +msgstr "" +"Maniglia del nodo: trascinare per formare la curva; con Ctrl " +"per far scattare l'angolo; con Alt per bloccare la lunghezza; con " +"Maiusc per ruotare in sincronia la maniglia opposta" + +#. TRANSLATORS: "end" is an adjective here (NOT a verb) +#: ../../po/../src/nodepath.cpp:3591 +msgid "end node" +msgstr "nodo finale" + +#. TRANSLATORS: "cusp" means "sharp" (cusp node); see also the Advanced Tutorial +#: ../../po/../src/nodepath.cpp:3596 +msgid "cusp" +msgstr "angolare" + +#. TRANSLATORS: "smooth" is an adjective here +#: ../../po/../src/nodepath.cpp:3599 +msgid "smooth" +msgstr "curvo" + +#: ../../po/../src/nodepath.cpp:3601 +msgid "symmetric" +msgstr "simmetrico" + +#. TRANSLATORS: "end" is an adjective here (NOT a verb) +#: ../../po/../src/nodepath.cpp:3607 +msgid "end node, handle retracted (drag with Shift to extend)" +msgstr "" +"nodo finale, maniglia ritratta (trascinare con Maiusc per estenderla)" + +#: ../../po/../src/nodepath.cpp:3609 +msgid "one handle retracted (drag with Shift to extend)" +msgstr "una maniglia ritratta (trascinare con Maiusc per estenderla)" + +#: ../../po/../src/nodepath.cpp:3612 +msgid "both handles retracted (drag with Shift to extend)" +msgstr "" +"entrambe le maniglie ritratte (trascinare con Maiusc per estenderle)" + +#: ../../po/../src/nodepath.cpp:3624 +msgid "Drag nodes or node handles; arrow keys to move nodes" +msgstr "" +"Trascinare i nodi o le maniglie dei nodi; usare i tasti freccia per spostare i nodi" + +#: ../../po/../src/nodepath.cpp:3625 +msgid "Drag the node or its handles; arrow keys to move the node" +msgstr "" +"Trascinare il nodo o le sue maniglie; usare i tasti freccia " +"per spostare il nodo" + +#: ../../po/../src/nodepath.cpp:3651 ../../po/../src/nodepath.cpp:3663 +msgid "Select a single object to edit its nodes or handles." +msgstr "Selezionare un singolo oggetto per modificarne i nodi o le maniglie" + +#: ../../po/../src/nodepath.cpp:3655 +#, fuzzy, c-format +msgid "" +"0 out of %i node selected. Click, Shift+click, " +"or drag around nodes to select." +msgid_plural "" +"0 out of %i nodes selected. Click, Shift+click, " +"or drag around nodes to select." +msgstr[0] "" +"Nessun oggetto selezionato. Click, Maiusc+click, o trascinare attorno agli " +"oggetti per selezionare." +msgstr[1] "" +"Nessun oggetto selezionato. Click, Maiusc+click, o trascinare attorno agli " +"oggetti per selezionare." + +#: ../../po/../src/nodepath.cpp:3661 +msgid "Drag the handles of the object to modify it." +msgstr "Trascinare le maniglie dell'oggetto per modificarlo." + +#: ../../po/../src/nodepath.cpp:3669 +#, c-format +msgid "%i of %i node selected; %s. %s." +msgid_plural "%i of %i nodes selected; %s. %s." +msgstr[0] "%i di %i nodo selezionato; %s. %s." +msgstr[1] "%i di %i nodi selezionati; %s. %s." + +#: ../../po/../src/nodepath.cpp:3675 +#, c-format +msgid "%i of %i node selected. %s." +msgid_plural "%i of %i nodes selected. %s." +msgstr[0] "%i di %i nodo selezionato; %s." +msgstr[1] "%i di %i nodi selezionati; %s." + +#: ../../po/../src/object-edit.cpp:493 +msgid "" +"Adjust the horizontal rounding radius; with Ctrl to make the " +"vertical radius the same" +msgstr "" +"Modifica l'arrotondamento orizzontale; con Ctrl per rendere " +"uguale l'arrotondamento verticale" + +#: ../../po/../src/object-edit.cpp:499 +msgid "" +"Adjust the vertical rounding radius; with Ctrl to make the " +"horizontal radius the same" +msgstr "" +"Modifica l'arrotondamento verticale; con Ctrl per rendere " +"uguale l'arrotondamento orizzontale" + +#: ../../po/../src/object-edit.cpp:506 ../../po/../src/object-edit.cpp:513 +msgid "" +"Adjust the width and height of the rectangle; with Ctrl to " +"lock ratio or stretch in one dimension only" +msgstr "" +"Modifica l'altezza e la larghezza del rattangolo; con Ctrl per " +"mantenere la proporzione o allungare su una sola dimensione" + +#: ../../po/../src/object-edit.cpp:686 +msgid "Adjust ellipse width, with Ctrl to make circle" +msgstr "" +"Modifica la larghezza dell'ellisse, con Ctrl per farne un " +"cerchio" + +#: ../../po/../src/object-edit.cpp:689 +msgid "Adjust ellipse height, with Ctrl to make circle" +msgstr "" +"Modifica l'altezza dell'ellisse, con Ctrl per farne un cerchio" + +#: ../../po/../src/object-edit.cpp:692 +msgid "" +"Position the start point of the arc or segment; with Ctrl to " +"snap angle; drag inside the ellipse for arc, outside for " +"segment" +msgstr "" +"Posizionare il punto iniziale dell'arco o del segmento; con Ctrl per far scattare l'angolo; trascinare dentro l'ellisse per un " +"arco, fuori per un segmento" + +#: ../../po/../src/object-edit.cpp:695 +msgid "" +"Position the end point of the arc or segment; with Ctrl to " +"snap angle; drag inside the ellipse for arc, outside for " +"segment" +msgstr "" +"Posizionare il punto finale dell'arco o del segmento; con Ctrl " +"per far scattare l'angolo; trascinare dentro l'ellisse per un arco, " +"fuori per un segmento" + +#: ../../po/../src/object-edit.cpp:800 +msgid "" +"Adjust the tip radius of the star or polygon; with Shift to " +"round; with Alt to randomize" +msgstr "" +"Modifica il diametro della stella o del poligono; con Maiusc " +"per arrotondare; con Alt per avere casualità" + +#: ../../po/../src/object-edit.cpp:803 +msgid "" +"Adjust the base radius of the star; with Ctrl to keep star " +"rays radial (no skew); with Shift to round; with Alt to " +"randomize" +msgstr "" +"Modifica il diametro interno della stella; con Ctrl per " +"mantenere la direzione dei raggi (senza deformazione); con Maiusc per " +"arrotondare; con Alt per avere casualità" + +#: ../../po/../src/object-edit.cpp:967 +msgid "" +"Roll/unroll the spiral from inside; with Ctrl to snap angle; " +"with Alt to converge/diverge" +msgstr "" +"Arrotola/srotola una spirale dall'interno; con Ctrl per far " +"scattare l'angolo; con Alt per far convergere/divergere" + +#: ../../po/../src/object-edit.cpp:969 +msgid "" +"Roll/unroll the spiral from outside; with Ctrl to snap angle; " +"with Shift to scale/rotate" +msgstr "" +"Arrotola/srotola una spirale dall'esterno; con Ctrl per far " +"scattare l'angolo; con Maiusc per ridimensionare/ruotare" + +#: ../../po/../src/object-edit.cpp:1006 +msgid "Adjust the offset distance" +msgstr "Regola la distanza di proiezione" + +#. TRANSLATORS: This refers to the pattern that's inside the object +#: ../../po/../src/object-edit.cpp:1036 +msgid "Move the pattern fill inside the object" +msgstr "Muove il motivo di riempimento all'interno dell'oggetto" + +#: ../../po/../src/object-edit.cpp:1038 +msgid "Scale the pattern fill uniformly" +msgstr "Ridimensiona uniformemente il motivo di riempimento" + +#: ../../po/../src/object-edit.cpp:1040 +msgid "Rotate the pattern fill; with Ctrl to snap angle" +msgstr "" +"Ruota il motivo di riempimento; con Ctrl per far scattare " +"l'angolo" + +#: ../../po/../src/object-edit.cpp:1065 +msgid "Drag to resize the flowed text frame" +msgstr "Trascinare per ridimensionare il riquadro del testo dinamico" + +#. Item dialog +#: ../../po/../src/object-ui.cpp:106 +msgid "Object _Properties" +msgstr "_Proprietà dell'oggetto" + +#. Select item +#: ../../po/../src/object-ui.cpp:116 +msgid "_Select This" +msgstr "_Seleziona questo" + +#. Create link +#: ../../po/../src/object-ui.cpp:126 +msgid "_Create Link" +msgstr "_Crea collegamento" + +#. "Ungroup" +#: ../../po/../src/object-ui.cpp:199 ../../po/../src/verbs.cpp:1931 +msgid "_Ungroup" +msgstr "_Dividi" + +#. Link dialog +#: ../../po/../src/object-ui.cpp:239 +msgid "Link _Properties" +msgstr "Proprietà Collegamento" + +#. Select item +#: ../../po/../src/object-ui.cpp:249 +msgid "_Follow Link" +msgstr "Segui Collegamento" + +#. Reset transformations +#: ../../po/../src/object-ui.cpp:254 +msgid "_Remove Link" +msgstr "Rimuovi Collegamento" + +#. Link dialog +#: ../../po/../src/object-ui.cpp:303 +msgid "Image _Properties" +msgstr "_Proprietà Immagine" + +#. Item dialog +#: ../../po/../src/object-ui.cpp:344 +msgid "_Fill and Stroke" +msgstr "Riempimento e Contorni" + +#: ../../po/../src/path-chemistry.cpp:58 +msgid "Select at least two objects to combine." +msgstr "Selezionare almeno due oggetti da combinare." + +#: ../../po/../src/path-chemistry.cpp:65 +msgid "At least one of the objects is not a path, cannot combine." +msgstr "Combinazione impossibile, almeno un oggetto non è un tracciato." + +#: ../../po/../src/path-chemistry.cpp:73 +msgid "" +"You cannot combine objects from different groups or layers." +msgstr "" +"Non è possibile combinare oggetti in gruppi o livelli diversi." + +#: ../../po/../src/path-chemistry.cpp:155 +msgid "Select path(s) to break apart." +msgstr "Selezionare il tracciato da separare." + +#: ../../po/../src/path-chemistry.cpp:231 +msgid "No path(s) to break apart in the selection." +msgstr "Nessun tracciato da separare nella selezione." + +#: ../../po/../src/path-chemistry.cpp:252 +msgid "Select object(s) to convert to path." +msgstr "Selezionare l'oggetto da convertire in tracciato." + +#: ../../po/../src/path-chemistry.cpp:297 +msgid "No objects to convert to path in the selection." +msgstr "Nessun oggetto nella selezione da convertire in tracciato." + +#: ../../po/../src/path-chemistry.cpp:345 +msgid "Select path(s) to reverse." +msgstr "Selezionare il tracciato da invertire." + +#: ../../po/../src/path-chemistry.cpp:370 +msgid "No paths to reverse in the selection." +msgstr "Nessun tracciato nella selezione da invertire." + +#: ../../po/../src/pen-context.cpp:379 ../../po/../src/pencil-context.cpp:233 +msgid "Continuing selected path" +msgstr "Continuazione del tracciato selezionato" + +#: ../../po/../src/pen-context.cpp:390 ../../po/../src/pencil-context.cpp:242 +msgid "Creating new path" +msgstr "Creazione nuovo tracciato" + +#: ../../po/../src/pen-context.cpp:394 ../../po/../src/pencil-context.cpp:246 +msgid "Appending to selected path" +msgstr "Aggiunta al tracciato selezionato" + +#: ../../po/../src/pen-context.cpp:538 +msgid "Click or click and drag to close and finish the path." +msgstr "" +"Fare clic o fare clic e trascinare per chiudere e terminare il " +"tracciato." + +#: ../../po/../src/pen-context.cpp:548 +msgid "" +"Click or click and drag to continue the path from this point." +msgstr "" +"Fare clic o fare clic e trascinare per continuare il tracciato " +"da questo punto." + +#: ../../po/../src/pen-context.cpp:857 +#, c-format +msgid "" +"%s: angle %3.2f°, distance %s; with Ctrl to snap angle, " +"Enter to finish the path" +msgstr "" +"%s: angolo %3.2f°, distanza %s; Ctrl angoli a scatti; " +"Invio per terminare il tracciato" + +#: ../../po/../src/pen-context.cpp:882 +#, c-format +msgid "" +"Curve handle: angle %3.2f°, length %s; with Ctrl to snap " +"angle" +msgstr "" +"Maniglia curva: angolo %3.2f° lunghezza %s; Ctrl per " +"angoli a scatti" + +#: ../../po/../src/pen-context.cpp:912 +#, c-format +msgid "" +"%s: angle %3.2f°, length %s; with Ctrl to snap angle, " +"with Shift to move this handle only" +msgstr "" +"%s: angolo %3.2f°, lunghezza %s; Ctrl per angoli a " +"scatti, Maiusc per muovere solo questa maniglia" + +#: ../../po/../src/pen-context.cpp:946 +msgid "Finishing pen" +msgstr "Terminazione penna" + +#: ../../po/../src/pencil-context.cpp:320 +msgid "Release here to close and finish the path." +msgstr "Rilasciare qui per chiudere e terminare il tracciato." + +#: ../../po/../src/pencil-context.cpp:326 +msgid "Drawing a freehand path" +msgstr "Disegna un percorso a mano libera" + +#: ../../po/../src/pencil-context.cpp:331 +msgid "Drag to continue the path from this point." +msgstr "Trascinare per continuare il tracciato da questo punto." + +#. Write curves to object +#: ../../po/../src/pencil-context.cpp:390 +msgid "Finishing freehand" +msgstr "Terminazione mano libera" + +#: ../../po/../src/rect-context.cpp:387 +msgid "" +"Ctrl: make square or integer-ratio rect, lock a rounded corner " +"circular" +msgstr "" +"Ctrl: Crea un quadrato o un rettangolo intero, un angolo arrotondato " +"circolare" + +#: ../../po/../src/rect-context.cpp:549 +#, c-format +msgid "" +"Rectangle: %s × %s; with Ctrl to make square or integer-" +"ratio rectangle; with Shift to draw around the starting point" +msgstr "" +"Rettangolo: %s × %s; con Ctrl per fare quadrati o " +"rettangoli interi; con Maiusc per disegnare attorno al punto iniziale" + +#: ../../po/../src/select-context.cpp:243 +msgid "Move canceled." +msgstr "Spostamento cancellato." + +#: ../../po/../src/select-context.cpp:252 +msgid "Selection canceled." +msgstr "Selezione cancellata." + +#: ../../po/../src/select-context.cpp:642 +msgid "Ctrl: select in groups, move hor/vert" +msgstr "Ctrl: seleziona nei gruppi, muove oriz/vert" + +#: ../../po/../src/select-context.cpp:643 +msgid "Shift: toggle select, force rubberband, disable snapping" +msgstr "Maiusc: commuta selezione, forza elastico, disabilita lo scatto" + +#: ../../po/../src/select-context.cpp:644 +msgid "Alt: select under, move selected" +msgstr "Alt: seleziona sotto, muove la selezione" + +#: ../../po/../src/select-context.cpp:798 +#, fuzzy +msgid "Selected object is not a group. Cannot enter." +msgstr "" +"L'oggetto selezionato non è un tracciato, impossibile intrudere/" +"estrudere." + +#: ../../po/../src/select-context.cpp:876 +#, c-format +msgid "" +"Move by %s, %s; with Ctrl to restrict to horizontal/vertical; " +"with Shift to disable snapping" +msgstr "" +"Muove di %s, %s; con Ctrl per restringere a oriz/vert; con " +"Maiusc per disabilitare lo scatto" + +#: ../../po/../src/selection-chemistry.cpp:228 +msgid "Nothing was deleted." +msgstr "Niente da eliminare." + +#: ../../po/../src/selection-chemistry.cpp:259 +msgid "Select object(s) to duplicate." +msgstr "Selezionare l'oggetto da duplicare." + +#: ../../po/../src/selection-chemistry.cpp:420 +msgid "Select two or more objects to group." +msgstr "Selezionare due o più oggetti da raggruppare." + +#: ../../po/../src/selection-chemistry.cpp:428 +msgid "Select at least two objects to group." +msgstr "Selezionare almeno due oggetti da raggruppare." + +#: ../../po/../src/selection-chemistry.cpp:513 +msgid "Select a group to ungroup." +msgstr "Selezionare un gruppo da dividere." + +#: ../../po/../src/selection-chemistry.cpp:554 +msgid "No groups to ungroup in the selection." +msgstr "Nessun gruppo nella selezione da dividere." + +#: ../../po/../src/selection-chemistry.cpp:623 +msgid "Select objects to raise." +msgstr "Selezionare l'oggetto da alzare." + +#: ../../po/../src/selection-chemistry.cpp:629 +#: ../../po/../src/selection-chemistry.cpp:681 +#: ../../po/../src/selection-chemistry.cpp:715 +#: ../../po/../src/selection-chemistry.cpp:773 +msgid "" +"You cannot raise/lower objects from different groups or layers." +msgstr "" +"Non è possibile alzare/abbassare oggetti in gruppi o livelli " +"differenti." + +#: ../../po/../src/selection-chemistry.cpp:673 +msgid "Select object(s) to raise to top." +msgstr "Selezionare l'oggetto da spostare in cima." + +#: ../../po/../src/selection-chemistry.cpp:709 +msgid "Select object(s) to lower." +msgstr "Selezionare l'oggetto da abbassare." + +#: ../../po/../src/selection-chemistry.cpp:765 +msgid "Select object(s) to lower to bottom." +msgstr "Selezionare l'oggetto da spostare in fondo." + +#: ../../po/../src/selection-chemistry.cpp:806 +msgid "Nothing to undo." +msgstr "Niente da annullare." + +#: ../../po/../src/selection-chemistry.cpp:813 +msgid "Nothing to redo." +msgstr "Niente da ripetere." + +#: ../../po/../src/selection-chemistry.cpp:969 +msgid "Nothing was copied." +msgstr "Niente da copiare." + +#: ../../po/../src/selection-chemistry.cpp:1051 +msgid "Current layer is hidden. Unhide it to be able to paste to it." +msgstr "" +"Il livello attuale è nascosto. Per potervi incollare occorre prima " +"mostrarlo." + +#: ../../po/../src/selection-chemistry.cpp:1055 +msgid "Current layer is locked. Unlock it to be able to paste to it." +msgstr "" +"Il livello attuale è bloccato. Per potervi incollare occorre prima " +"sbloccarlo." + +#: ../../po/../src/selection-chemistry.cpp:1068 +#: ../../po/../src/selection-chemistry.cpp:1103 +msgid "Nothing on the clipboard." +msgstr "Niente negli appunti." + +#: ../../po/../src/selection-chemistry.cpp:1109 +msgid "Select object(s) to paste style to." +msgstr "Selezionare l'oggetto a cui incollare lo stile." + +#: ../../po/../src/selection-chemistry.cpp:1128 +msgid "Select object(s) to move to the layer above." +msgstr "Selezionare l'oggetto da spostare al livello superiore." + +#: ../../po/../src/selection-chemistry.cpp:1146 +msgid "No more layers above." +msgstr "Nessun livello superiore." + +#: ../../po/../src/selection-chemistry.cpp:1160 +msgid "Select object(s) to move to the layer below." +msgstr "Selezionare l'oggetto da spostare al livello inferiore." + +#: ../../po/../src/selection-chemistry.cpp:1178 +msgid "No more layers below." +msgstr "Nessun livello inferiore." + +#: ../../po/../src/selection-chemistry.cpp:1811 +msgid "Select a clone to unlink." +msgstr "Selezionare un clone da scollegare." + +#: ../../po/../src/selection-chemistry.cpp:1842 +msgid "No clones to unlink in the selection." +msgstr "Nessuna clone da scollegare nella selezione." + +#: ../../po/../src/selection-chemistry.cpp:1859 +msgid "" +"Select a clone to go to its original. Select a linked offset " +"to go to its source. Select a text on path to go to the path. Select " +"a flowed text to go to its frame." +msgstr "" +"Selezionare un clone per andare al suo originale. Selezionare una " +"proiezione collegata per andare alla sua fonte. Selezionare un " +"testo su tracciato per andare al tracciato. Selezionare un testo " +"dinamico per andare al suo riquadro." + +#: ../../po/../src/selection-chemistry.cpp:1882 +msgid "" +"Cannot find the object to select (orphaned clone, offset, textpath, " +"flowed text?)" +msgstr "" +"Impossibile trovare l'oggetto da selezionare (clone orfano, " +"proiezione, testo su percorso o testo dinamico?)" + +#: ../../po/../src/selection-chemistry.cpp:1888 +msgid "" +"The object you're trying to select is not visible (it is in <" +"defs>)" +msgstr "" +"L'oggetto che si vuole selezionare non è visibile (è in <defs>)" + +#: ../../po/../src/selection-chemistry.cpp:1915 +msgid "Select object(s) to convert to pattern." +msgstr "Selezionare l'oggetto da convertire in motivo." + +#: ../../po/../src/selection-chemistry.cpp:2006 +msgid "Select an object with pattern fill to extract objects from." +msgstr "" +"Selezionare un oggetto con motivo di riempimento da cui estrarre " +"l'oggetto." + +#: ../../po/../src/selection-chemistry.cpp:2059 +msgid "No pattern fills in the selection." +msgstr "Nessun motivo di riempimento nella selezione." + +#: ../../po/../src/selection-chemistry.cpp:2079 +msgid "Select object(s) to make a bitmap copy." +msgstr "Selezionare l'oggetto di cui fare una copia bitmap." + +#: ../../po/../src/selection-describer.cpp:37 +msgid "Click selection to toggle scale/rotation handles" +msgstr "" +"Clicca la selezione per alternare le maniglie di ridimensionamento/rotazione" + +#. no items +#: ../../po/../src/selection-describer.cpp:39 +msgid "" +"No objects selected. Click, Shift+click, or drag around objects to select." +msgstr "" +"Nessun oggetto selezionato. Click, Maiusc+click, o trascinare attorno agli " +"oggetti per selezionare." + +#: ../../po/../src/selection-describer.cpp:51 +#, c-format +msgid " in layer %s" +msgstr " nel livello %s" + +#: ../../po/../src/selection-describer.cpp:54 +#, c-format +msgid " in layer %s" +msgstr " nel livello %s" + +#: ../../po/../src/selection-describer.cpp:66 +msgid "Use Shift+D to look up original" +msgstr "Usare Maiusc+D per trovare l'originale" + +#: ../../po/../src/selection-describer.cpp:70 +msgid "Use Shift+D to look up path" +msgstr "Usare Maiusc+D per trovare il tracciato" + +#: ../../po/../src/selection-describer.cpp:74 +msgid "Use Shift+D to look up frame" +msgstr "Usare Maiusc+D per trovare il riquadro" + +#: ../../po/../src/selection-describer.cpp:84 +#, c-format +msgid "%i object selected" +msgid_plural "%i objects selected" +msgstr[0] "%i oggetto selezionato" +msgstr[1] "%i oggetti selezionati" + +#: ../../po/../src/selection-describer.cpp:90 +#, c-format +msgid "%s%s. %s." +msgstr "%s%s. %s." + +#: ../../po/../src/selection-describer.cpp:94 +#, c-format +msgid "%s in %i layer. %s." +msgid_plural "%s in %i layers. %s." +msgstr[0] "%s in %i livello. %s." +msgstr[1] "%s in %i livelli. %s." + +#: ../../po/../src/seltrans.cpp:498 +msgid "" +"Center of rotation and skewing: drag to reposition; scaling with " +"Shift also uses this center" +msgstr "" +"Centro di rotazione e distorsione: trascinare per riposizionarlo; " +"anche il ridimensionamento con Maiusc usa questo centro" + +#: ../../po/../src/seltrans.cpp:514 +msgid "" +"Squeeze or stretch selection; with Ctrl to scale uniformly; " +"with Shift to scale around rotation center" +msgstr "" +"Accorcia o allunga la selezione; con Ctrl per ridimensionare " +"uniformemente; con Maiusc per ridimensionare attorno al centro di " +"rotazione" + +#: ../../po/../src/seltrans.cpp:515 +msgid "" +"Scale selection; with Ctrl to scale uniformly; with Shift to scale around rotation center" +msgstr "" +"Ridimensiona la selezione; con Ctrl per ridimensionare " +"uniformemente; con Maiusc per ridimensionare attorno al centro di " +"rotazione" + +#: ../../po/../src/seltrans.cpp:519 +msgid "" +"Skew selection; with Ctrl to snap angle; with Shift to " +"skew around the opposite side" +msgstr "" +"Distorce la selezione; con Ctrl per far scattare l'angolo; con " +"Maiusc per distorcere attorno al lato opposto" + +#: ../../po/../src/seltrans.cpp:520 +msgid "" +"Rotate selection; with Ctrl to snap angle; with Shift " +"to rotate around the opposite corner" +msgstr "" +"Ruota la selezione; con Ctrl per far scattare l'angolo; con " +"Maiusc per ruotare attorno all'angolo opposto" + +#: ../../po/../src/seltrans.cpp:829 ../../po/../src/seltrans.cpp:909 +#, c-format +msgid "Scale: %0.2f%% x %0.2f%%; with Ctrl to lock ratio" +msgstr "" +"Ridimensiona: %0.2f%% x %0.2f%%; con Ctrl per mantenere la " +"proporzione" + +#. TRANSLATORS: don't modify the first ";" (it will NOT be displayed as ";" - only the second one will be) +#: ../../po/../src/seltrans.cpp:984 +#, c-format +msgid "Skew: %0.2f°; with Ctrl to snap angle" +msgstr "" +"Distorsione: %0.2f°; con Ctrl per far scattare l'angolo" + +#. TRANSLATORS: don't modify the first ";" (it will NOT be displayed as ";" - only the second one will be) +#: ../../po/../src/seltrans.cpp:1035 +#, c-format +msgid "Rotate: %0.2f°; with Ctrl to snap angle" +msgstr "" +"Rotazione: %0.2f gradi; con Ctrl per far scattare l'angolo" + +#: ../../po/../src/seltrans.cpp:1090 +#, c-format +msgid "Move center to %s, %s" +msgstr "Muove il centro in %s, %s" + +#: ../../po/../src/slideshow.cpp:90 +msgid "Inkscape slideshow" +msgstr "Inkscape presentazione" + +#: ../../po/../src/sp-anchor.cpp:181 +#, c-format +msgid "Link to %s" +msgstr "Collegamento a %s" + +#: ../../po/../src/sp-anchor.cpp:185 +msgid "Link without URI" +msgstr "Collegamento senza URI" + +#: ../../po/../src/sp-ellipse.cpp:438 ../../po/../src/sp-ellipse.cpp:870 +msgid "Ellipse" +msgstr "Ellisse" + +#: ../../po/../src/sp-ellipse.cpp:583 +msgid "Circle" +msgstr "Cerchio" + +#: ../../po/../src/sp-ellipse.cpp:865 +msgid "Segment" +msgstr "Segmento" + +#: ../../po/../src/sp-ellipse.cpp:867 +msgid "Arc" +msgstr "Arco" + +#. TRANSLATORS: "Flow region" is an area where text is allowed to flow +#: ../../po/../src/sp-flowregion.cpp:276 +msgid "Flow region" +msgstr "Regione dinamica" + +#. TRANSLATORS: A region "cut out of" a flow region; text is not allowed to flow inside the +#. * flow excluded region. flowRegionExclude in SVG 1.2: see +#. * http://www.w3.org/TR/2004/WD-SVG12-20041027/flow.html#flowRegion-elem and +#. * http://www.w3.org/TR/2004/WD-SVG12-20041027/flow.html#flowRegionExclude-elem. +#: ../../po/../src/sp-flowregion.cpp:493 +msgid "Flow excluded region" +msgstr "Regione non dinamica" + +#: ../../po/../src/sp-flowtext.cpp:355 +#, c-format +msgid "Flowed text (%d characters)" +msgstr "Testo dinamico (%d caratteri)" + +#: ../../po/../src/sp-flowtext.cpp:357 +#, c-format +msgid "Linked flowed text (%d characters)" +msgstr "Testo dinamico collegato (%d caratteri)" + +#: ../../po/../src/sp-guide.cpp:290 +msgid "vertical guideline" +msgstr "linea guida vertical" + +#: ../../po/../src/sp-guide.cpp:292 +msgid "horizontal guideline" +msgstr "linea guida verticale" + +#: ../../po/../src/sp-image.cpp:835 +msgid "embedded" +msgstr "integrato" + +#: ../../po/../src/sp-image.cpp:839 +msgid "(null_pointer)" +msgstr "(null_pointer)" + +#: ../../po/../src/sp-image.cpp:843 +#, c-format +msgid "Image with bad reference: %s" +msgstr "Immmagine con un descrittore sbagliato: %s" + +#: ../../po/../src/sp-image.cpp:844 +#, c-format +msgid "Image %d × %d: %s" +msgstr "Immagine %d × %d: %s" + +#: ../../po/../src/sp-item-group.cpp:390 +#, c-format +msgid "Group of %d object" +msgid_plural "Group of %d objects" +msgstr[0] "Gruppo di %d oggetto" +msgstr[1] "Gruppo di %d oggetti" + +#: ../../po/../src/sp-item.cpp:720 +msgid "Object" +msgstr "Oggetto" + +#: ../../po/../src/sp-line.cpp:202 +msgid "Line" +msgstr "Linea" + +#. TRANSLATORS COMMENT: %s is either "outset" or "inset" depending on sign +#: ../../po/../src/sp-offset.cpp:433 +#, c-format +msgid "Linked offset, %s by %f pt" +msgstr "Proiezione collegata, %s di %f pt" + +#: ../../po/../src/sp-offset.cpp:434 ../../po/../src/sp-offset.cpp:438 +msgid "outset" +msgstr "estrusione" + +#: ../../po/../src/sp-offset.cpp:434 ../../po/../src/sp-offset.cpp:438 +msgid "inset" +msgstr "intrusione" + +#. TRANSLATORS COMMENT: %s is either "outset" or "inset" depending on sign +#: ../../po/../src/sp-offset.cpp:437 +#, c-format +msgid "Dynamic offset, %s by %f pt" +msgstr "Proiezione dinamica, %s di %f pt" + +#: ../../po/../src/sp-path.cpp:127 +#, c-format +msgid "Path (%i node)" +msgid_plural "Path (%i nodes)" +msgstr[0] "Tracciato (%i nodo)" +msgstr[1] "Tracciato (%i nodi)" + +#: ../../po/../src/sp-polygon.cpp:216 +msgid "Polygon" +msgstr "Poligono" + +#: ../../po/../src/sp-polyline.cpp:179 +msgid "Polyline" +msgstr "Poligonale" + +#: ../../po/../src/sp-rect.cpp:250 +msgid "Rectangle" +msgstr "Rettangolo" + +#. TRANSLATORS: since turn count isn't an integer, please adjust the +#. string as needed to deal with an localized plural forms. +#: ../../po/../src/sp-spiral.cpp:305 +#, c-format +msgid "Spiral with %3f turns" +msgstr "Spirale di %3f giri" + +#: ../../po/../src/sp-star.cpp:288 +#, c-format +msgid "Star with %d vertex" +msgid_plural "Star with %d vertices" +msgstr[0] "Stella con %d vertice" +msgstr[1] "Stella con %d vertici" + +#: ../../po/../src/sp-star.cpp:292 +#, c-format +msgid "Polygon with %d vertex" +msgid_plural "Polygon with %d vertices" +msgstr[0] "Poligono con %d vertice" +msgstr[1] "Poligono con %d vertici" + +#. TRANSLATORS: For description of font with no name. +#: ../../po/../src/sp-text.cpp:420 +msgid "<no name found>" +msgstr "<nessun nome trovato>" + +#: ../../po/../src/sp-text.cpp:426 +#, c-format +msgid "Text on path (%s, %s)" +msgstr "Testo su tracciato (%s, %s)" + +#: ../../po/../src/sp-text.cpp:427 +#, c-format +msgid "Text (%s, %s)" +msgstr "Testo (%s, %s)" + +#. TRANSLATORS: Used for statusbar description for long chains: +#. * "Clone of: Clone of: ... in Layer 1". +#: ../../po/../src/sp-use.cpp:317 +msgid "..." +msgstr "..." + +#: ../../po/../src/sp-use.cpp:325 +#, c-format +msgid "Clone of: %s" +msgstr "Clone di: %s" + +#: ../../po/../src/sp-use.cpp:329 +msgid "Orphaned clone" +msgstr "Clone orfano" + +#: ../../po/../src/spiral-context.cpp:355 +msgid "Ctrl: snap angle" +msgstr "Ctrl: fa scattare l'angolo" + +#: ../../po/../src/spiral-context.cpp:357 +msgid "Alt: lock spiral radius" +msgstr "Alt: mantiene il raggio della spirale" + +#: ../../po/../src/spiral-context.cpp:469 +#, c-format +msgid "" +"Spiral: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" +"Spirale: raggio %s, angolo %5g°; con Ctrl per far " +"scattare l'angolo" + +#: ../../po/../src/splivarot.cpp:106 +msgid "Select at least 2 paths to perform a boolean operation." +msgstr "" +"Selezionare almeno 2 tracciati per effettuare un'operazione booleana." + +#: ../../po/../src/splivarot.cpp:112 +msgid "" +"Select exactly 2 paths to perform difference, XOR, division, or path " +"cut." +msgstr "" +"Selezionare esattamente 2 tracciati per effettuare differenza, XOR, " +"divisione o taglio del tracciato." + +#: ../../po/../src/splivarot.cpp:129 ../../po/../src/splivarot.cpp:144 +msgid "" +"Unable to determine the z-order of the objects selected for " +"difference, XOR, division, or path cut." +msgstr "" +"Impossibile determinare l'ordinamento-z degli oggetti selezionati per " +"la differenza, XOR, divisione o taglio del tracciato." + +#: ../../po/../src/splivarot.cpp:174 +msgid "" +"One of the objects is not a path, cannot perform boolean operation." +msgstr "" +"Uno degli oggetti non è un tracciato, impossibile eseguire " +"l'operazione booleana." + +#. TRANSLATORS: "to outline" means "to convert stroke to path" +#: ../../po/../src/splivarot.cpp:554 +msgid "Select path(s) to outline." +msgstr "Selezionare il tracciato da convertire." + +#. TRANSLATORS: "to outline" means "to convert stroke to path" +#: ../../po/../src/splivarot.cpp:748 +msgid "No stroked paths to outline in the selection." +msgstr "Nessun tracciato contornato da convertire nella selezione." + +#: ../../po/../src/splivarot.cpp:832 +msgid "Selected object is not a path, cannot inset/outset." +msgstr "" +"L'oggetto selezionato non è un tracciato, impossibile intrudere/" +"estrudere." + +#: ../../po/../src/splivarot.cpp:1040 +msgid "Select path(s) to inset/outset." +msgstr "Selezionare il tracciato da intrudere/estrudere." + +#: ../../po/../src/splivarot.cpp:1257 +msgid "No paths to inset/outset in the selection." +msgstr "Nessun tracciatoda intrudere/estrudere nella selezione." + +#: ../../po/../src/splivarot.cpp:1390 +msgid "Select path(s) to simplify." +msgstr "Selezionare il tracciato da semplificare." + +#: ../../po/../src/splivarot.cpp:1417 +msgid "No paths to simplify in the selection." +msgstr "Nessun tracciatoda semplificare nella selezione." + +#: ../../po/../src/star-context.cpp:362 +msgid "Ctrl: snap angle; keep rays radial" +msgstr "Ctrl: fa scattare l'angolo; mantiene la direzione dei raggi" + +#: ../../po/../src/star-context.cpp:470 +#, c-format +msgid "" +"Polygon: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" +"Poligono: raggio %s, angolo %5g°; con Ctrl per far " +"scattare l'angolo" + +#: ../../po/../src/star-context.cpp:471 +#, c-format +msgid "Star: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" +"Stella: raggio %s, angolo %5g°; con Ctrl per far scattare " +"l'angolo" + +#: ../../po/../src/text-chemistry.cpp:90 +msgid "Select a text and a path to put text on path." +msgstr "" +"Selezionare un testo ed un tracciato per mettere il testo sul " +"tracciato." + +#: ../../po/../src/text-chemistry.cpp:95 +msgid "" +"This text object is already put to a path. Remove it from the path " +"first. Use Shift+D to look up its path." +msgstr "" +"Questo testo è già su un tracciato. Rimuoverlo prima dal tracciato." +"Usare Maiusc+D per trovare il suo tracciato." + +#. rect is the only SPShape which is not yet, and thus SVG forbids us from putting text on it +#: ../../po/../src/text-chemistry.cpp:101 +msgid "" +"You cannot put text on a rectangle in this version. Convert rectangle to " +"path first." +msgstr "" +"In questa versione non è possibile mettere il testo sun un rettangolo. " +"Convertire prima il rettangolo in tracciato." + +#: ../../po/../src/text-chemistry.cpp:159 +msgid "Select a text on path to remove it from path." +msgstr "Selezionare un testo su tracciato per rimuoverlo dal tracciato." + +#: ../../po/../src/text-chemistry.cpp:181 +msgid "No texts-on-paths in the selection." +msgstr "Nessun testo su tracciato nella selezione." + +#: ../../po/../src/text-chemistry.cpp:209 +#: ../../po/../src/text-chemistry.cpp:229 +msgid "Select text(s) to remove kerns from." +msgstr "Selezionare il testo da cui rimuovere le trasformazioni." + +#: ../../po/../src/text-chemistry.cpp:250 +msgid "" +"Select a text and one or more paths or shapes to flow text " +"into frame." +msgstr "" +"Selezionare un testo ed uno o più tracciati o forme per " +"fluire il testo nella struttura." + +#: ../../po/../src/text-chemistry.cpp:322 +msgid "Select a flowed text to unflow it." +msgstr "Selezionare un testo dinamico da spezzare." + +#: ../../po/../src/text-context.cpp:463 +msgid "Click to edit the text, drag to select part of the text." +msgstr "" +"Cliccare per modificare il testo, trascinare per selezionarne " +"una parte." + +#: ../../po/../src/text-context.cpp:465 +msgid "" +"Click to edit the flowed text, drag to select part of the text." +msgstr "" +"Cliccare per modificare il testo dinamico, trascinare per " +"selezionarne una parte." + +#: ../../po/../src/text-context.cpp:540 +msgid "Non-printable character" +msgstr "Carattare non stampabile" + +#: ../../po/../src/text-context.cpp:589 +#, c-format +msgid "Unicode: %s: %s" +msgstr "Unicode: %s: %s" + +#: ../../po/../src/text-context.cpp:591 ../../po/../src/text-context.cpp:855 +msgid "Unicode: " +msgstr "Unicode: " + +#: ../../po/../src/text-context.cpp:615 +msgid "Current layer is hidden. Unhide it to be able to add text." +msgstr "" +"Il livello attuale è nascosto.·Per potervi aggiungere testo occorre " +"mostrarlo." + +#: ../../po/../src/text-context.cpp:619 +msgid "Current layer is locked. Unlock it to be able to add text." +msgstr "" +"Il livello attuale è bloccato.·Per potervi aggiungere testo occorre " +"sbloccarlo." + +#: ../../po/../src/text-context.cpp:673 +#, c-format +msgid "Flowed text frame: %s × %s" +msgstr "Struttura del testo dinamico: %s × %s" + +#: ../../po/../src/text-context.cpp:708 ../../po/../src/text-context.cpp:1464 +msgid "Type text; Enter to start new line." +msgstr "Inserire il testo; Invio per iniziare una nuova riga." + +#: ../../po/../src/text-context.cpp:719 +msgid "Flowed text is created." +msgstr "Il testo dinamico è stato creato." + +#: ../../po/../src/text-context.cpp:722 +msgid "" +"The frame is too small for the current font size. Flowed text not " +"created." +msgstr "" +"La struttura è troppo piccola per la dimensione del carattere " +"attuale. Testo dinamico non creato." + +#: ../../po/../src/text-context.cpp:841 +msgid "No-break space" +msgstr "Spazio non interrompibile" + +#: ../../po/../src/text-context.cpp:1462 +msgid "Type flowed text; Enter to start new paragraph." +msgstr "" +"Inserire il testo dinamico;Invio per iniziare un nuovo paragrafo." + +#: ../../po/../src/text-context.cpp:1472 ../../po/../src/tools-switch.cpp:189 +msgid "" +"Click to select or create text, drag to create flowed text; " +"then type." +msgstr "" +"Cliccare per selezionare o creare un testo, trascinareper " +"creare un testo dinamico; quindi scrivere." + +#: ../../po/../src/tools-switch.cpp:141 +msgid "" +"To edit a path, click, Shift+click, or drag around " +"nodes to select them, then drag nodes and handles. Click on an " +"object to select." +msgstr "" +"Per modificare un tracciato, click, Maiusc+click, o " +"trascinare attorno ai nodi per selezionarli, quindi trascinare " +"i nodi e le maniglie. Cliccare su un oggetto per selezionare." + +#: ../../po/../src/tools-switch.cpp:147 +msgid "" +"Drag to create a rectangle. Drag controls to round corners and " +"resize. Click to select." +msgstr "" +"Trascinare per creare un rettangolo. Trascinare i controlli " +"per arrotondare gli angoli e ridimensionare. Cliccare per selezionare." + +#: ../../po/../src/tools-switch.cpp:153 +msgid "" +"Drag to create an ellipse. Drag controls to make an arc or " +"segment. Click to select." +msgstr "" +"Trascinare per creare un ellisse. Trascinare i controlli per " +"farne un arco un segmento. Cliccare per selezionare." + +#: ../../po/../src/tools-switch.cpp:159 +msgid "" +"Drag to create a star. Drag controls to edit the star shape. " +"Click to select." +msgstr "" +"Trascinare per creare una stella. Trascinare i controlli per " +"modificarne la forma. Cliccare per selezionare." + +#: ../../po/../src/tools-switch.cpp:165 +msgid "" +"Drag to create a spiral. Drag controls to edit the spiral " +"shape. Click to select." +msgstr "" +"Trascinare per creare una spirale. Trascinare i controlli per " +"modificarne la forma. Cliccare per selezionare." + +#: ../../po/../src/tools-switch.cpp:171 +msgid "" +"Drag to create a freehand line. Start drawing with Shift to " +"append to selected path." +msgstr "" +"Trascinare per creare una linea a mano libera. Iniziare a disegnare " +"con Maiusc per aggiungere al tracciato selezionato." + +#: ../../po/../src/tools-switch.cpp:177 +msgid "" +"Click or click and drag to start a path; with Shift to " +"append to selected path." +msgstr "" +"Fare clic o fare clic e trascinare per iniziare un percorso; " +"con Maiusc per accodare al percorso selezionato." + +#: ../../po/../src/tools-switch.cpp:183 +msgid "" +"Drag to paint a calligraphic stroke. Left/right arrow " +"keys adjust width, up/down adjust angle." +msgstr "" +"Trascinare per disegnare un tratto di pennino. Freccia sinistra/destra per modificare la larghezza, su/giù l'angolo." + +#: ../../po/../src/tools-switch.cpp:195 +msgid "" +"Drag or double click to create a gradient on selected objects, " +"drag handles to adjust gradients." +msgstr "" +"Trascinare o doppio click per creare un gradiente un gradiente " +"sull'oggetto selezionato; trascniare le maniglie per modificare il " +"gradiente." + +#: ../../po/../src/tools-switch.cpp:201 +msgid "" +"Click or drag around an area to zoom in, Shift+click to " +"zoom out." +msgstr "" +"Cliccare o trascinare una zona per ingrandire, Maiusc" +"+click per rimpicciolire." + +#: ../../po/../src/tools-switch.cpp:213 +msgid "Click and drag between shapes to create a connector." +msgstr "Fare clic e trascinare tra le forme per creare un connettore." + +#: ../../po/../src/trace/potrace/inkscape-potrace.cpp:553 +#: ../../po/../src/trace/potrace/inkscape-potrace.cpp:654 +#, c-format +msgid "Trace: %d. %ld nodes" +msgstr "Vettorizza: %d. %ld nodi" + +#: ../../po/../src/trace/trace.cpp:53 ../../po/../src/trace/trace.cpp:62 +#: ../../po/../src/trace/trace.cpp:70 +msgid "Select an image to trace" +msgstr "Selezionare una immagine da vettorizzare" + +#: ../../po/../src/trace/trace.cpp:133 +msgid "Trace: No active document" +msgstr "Vettorizza: Nessun documento attivo" + +#: ../../po/../src/trace/trace.cpp:154 +msgid "Trace: Image has no bitmap data" +msgstr "Vettorizza: L'immagine non contiene bitmap data" + +#: ../../po/../src/trace/trace.cpp:267 +#, c-format +msgid "Trace: Done. %ld nodes created" +msgstr "Vettorizza: Eseguito. %ld nodi creati" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:59 ../../po/../src/verbs.cpp:2212 +msgid "About Inkscape" +msgstr "Informazioni su Inkscape" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:66 +msgid "_Splash" +msgstr "" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:68 +#, fuzzy +msgid "_Authors" +msgstr "Autori" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:69 +#, fuzzy +msgid "_Translators" +msgstr "Traduttori" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:70 +msgid "_License" +msgstr "_Licenza" + +#. TRANSLATORS: This is the filename of the `About Inkscape' picture in +#. the `screens' directory. Thus the translation of "about.svg" should be +#. the filename of its translated version, e.g. about.zh.svg for Chinese. +#. +#. N.B. about.svg changes once per release. (We should probably rename +#. the original to about-0.40.svg etc. as soon as we have a translation. +#. If we do so, then add an item to release-checklist saying that the +#. string here should be changed.) +#. FIXME? INKSCAPE_SCREENSDIR and "about.svg" are in UTF-8, not the +#. native filename encoding... and the filename passed to sp_document_new +#. should be in UTF-*8.. +#: ../../po/../src/ui/dialog/aboutbox.cpp:114 +msgid "about.svg" +msgstr "about.svg" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:464 +msgid "Minimum horizontal gap (in px units) between bounding boxes" +msgstr "" + +#. TRANSLATORS: Horizontal gap +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:466 +#: ../../po/../src/widgets/toolbox.cpp:1556 +msgid "H:" +msgstr "A:" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:474 +msgid "Minimum vertical gap (in px units) between bounding boxes" +msgstr "" + +#. TRANSLATORS: Vertical gap +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:476 +msgid "V:" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:734 +msgid "Align" +msgstr "Allineamento" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:735 +msgid "Distribute" +msgstr "Distribuzione" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:736 +msgid "Remove overlaps" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:737 +msgid "Nodes" +msgstr "Nodi" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:742 +msgid "Relative to: " +msgstr "Relativo a: " + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:747 +msgid "Align right sides of objects to left side of anchor" +msgstr "Allinea lato destro dell'oggetto al lato sinistro del fisso" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:750 +msgid "Align left sides" +msgstr "Allinea lati sinistri" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:753 +msgid "Center on vertical axis" +msgstr "Centra sull'asse verticale" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:756 +msgid "Align right sides" +msgstr "Allinea i lati destri" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:759 +msgid "Align left sides of objects to right side of anchor" +msgstr "Allinea lato destro dell'oggetto al lato sinistro del fisso" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:762 +msgid "Align bottoms of objects to top of anchor" +msgstr "Allinea margine inferiore dell'oggetto al margine superiore del fisso" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:765 +msgid "Align tops" +msgstr "Allinea i lati superiori" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:768 +msgid "Center on horizontal axis" +msgstr "Centra sull'asse orizzonatle" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:771 +msgid "Align bottoms" +msgstr "Allinea i lati inferiori" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:774 +msgid "Align tops of objects to bottom of anchor" +msgstr "" +"Allinea il margine superiore dell'oggetto al margine inferiore del fisso" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:779 +msgid "Align baseline anchors of texts vertically" +msgstr "Allinea verticalmente la linea base del testo" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:782 +msgid "Align baseline anchors of texts horizontally" +msgstr "Allinea orizzontalmente la linea base del testo" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:787 +msgid "Make horizontal gaps between objects equal" +msgstr "Distribuisce equamente la distanza orizzontale tra gli oggetti" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:791 +msgid "Distribute left sides equidistantly" +msgstr "Distribuisce i lati sinistri degli oggetti alla stessa distanza" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:794 +msgid "Distribute centers equidistantly horizontally" +msgstr "" +"Distribuisce orizzontalmente i centri degli oggetti alla stessa distanza" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:797 +msgid "Distribute right sides equidistantly" +msgstr "Distribuisce i lati destri degli oggetti alla stessa distanza" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:801 +msgid "Make vertical gaps between objects equal" +msgstr "Distribuisce equamente la distanza verticale tra gli oggetti" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:805 +msgid "Distribute tops equidistantly" +msgstr "Distribuisce i lati superiori degli oggetti alla stessa distanza" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:808 +msgid "Distribute centers equidistantly vertically" +msgstr "Distribuisce verticalmente i centri degli oggetti alla stessa distanza" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:811 +msgid "Distribute bottoms equidistantly" +msgstr "Distribuisce i lati inferiori degli oggetti alla stessa distanza" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:816 +msgid "Distribute baseline anchors of texts horizontally" +msgstr "Distribuisce orizzontalmente la linea base del testo" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:819 +msgid "Distribute baseline anchors of texts vertically" +msgstr "Distribuisce verticalmente la linea base del testo" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:824 +msgid "Randomize centers in both dimensions" +msgstr "Rendi casuali i centri su entrambe le dimensioni" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:827 +msgid "Unclump objects: try to equalize edge-to-edge distances" +msgstr "" +"Sparpaglia oggetti: prova a rendere uguali le distanze da bordo a bordo" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:832 +msgid "" +"Move objects as little as possible so that their bounding boxes do not " +"overlap" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:837 +msgid "Align selected nodes horizontally" +msgstr "Allinea orizzontalmente i nodi selezionati" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:840 +msgid "Align selected nodes vertically" +msgstr "Allinea verticalmente i nodi selezionati" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:843 +msgid "Distribute selected nodes horizontally" +msgstr "Distribuisce orizzontalmente i nodi selezionati" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:846 +msgid "Distribute selected nodes vertically" +msgstr "Distribuisce verticalmente i nodi selezionati" + +#. Rest of the widgetry +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:851 +msgid "Last selected" +msgstr "Ultimo selezionato" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:852 +msgid "First selected" +msgstr "Primo selezionato" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:853 +msgid "Biggest item" +msgstr "L'oggetto più grande" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:854 +msgid "Smallest item" +msgstr "L'oggetto più piccolo" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:856 +#: ../../po/../src/widgets/desktop-widget.cpp:1065 +msgid "Drawing" +msgstr "Disegno" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:91 +#, fuzzy +msgid "Metadata 1" +msgstr "Metadata" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:92 +#, fuzzy +msgid "Metadata 2" +msgstr "Metadata" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:187 +#, fuzzy +msgid "X coordinate of grid origin" +msgstr "Cordinate verticali della selezione" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:189 +#, fuzzy +msgid "Y coordinate of grid origin" +msgstr "Cordinate verticali della selezione" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:191 +#, fuzzy +msgid "Distance of vertical grid lines" +msgstr "linea guida vertical" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:193 +#, fuzzy +msgid "Distance of horizontal grid lines" +msgstr "linea guida verticale" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:197 +msgid "Max. snapping distance from grid" +msgstr "" + +#: ../../po/../src/ui/dialog/export.cpp:34 +msgid "Export" +msgstr "Esporta" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:36 +msgid "Fill" +msgstr "Riempimento" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:37 +msgid "Stroke Paint" +msgstr "Colore contorno" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:38 +msgid "Stroke Style" +msgstr "Stile contorno" + +#: ../../po/../src/ui/dialog/find.cpp:34 +msgid "Find" +msgstr "Trova" + +#: ../../po/../src/ui/dialog/memory.cpp:96 +msgid "Heap" +msgstr "Heap" + +#: ../../po/../src/ui/dialog/memory.cpp:97 +msgid "In Use" +msgstr "In uso" + +#. TRANSLATORS: "Slack" refers to memory which is in the heap but currently unused. +#. More typical usage is to call this memory "free" rather than "slack". +#: ../../po/../src/ui/dialog/memory.cpp:100 +msgid "Slack" +msgstr "Slack" + +#: ../../po/../src/ui/dialog/memory.cpp:101 +msgid "Total" +msgstr "Totale" + +#: ../../po/../src/ui/dialog/memory.cpp:141 +#: ../../po/../src/ui/dialog/memory.cpp:147 +#: ../../po/../src/ui/dialog/memory.cpp:154 +#: ../../po/../src/ui/dialog/memory.cpp:186 +msgid "Unknown" +msgstr "Sconosciuto" + +#: ../../po/../src/ui/dialog/memory.cpp:167 +msgid "Combined" +msgstr "Combinato" + +#: ../../po/../src/ui/dialog/memory.cpp:209 +msgid "Recalculate" +msgstr "Ricalcola" + +#: ../../po/../src/ui/dialog/messages.cpp:74 +msgid "Ready." +msgstr "Pronto." + +#: ../../po/../src/ui/dialog/messages.cpp:75 +msgid "" +"Enable log display by setting dialogs.debug 'redirect' attribute to 1 in " +"preferences.xml" +msgstr "" +"Attivare il display di log impostando a 1 l'attributo 'redirect' di dialogs." +"debug nel filepreferences.xml" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:184 +msgid "_Execute Python" +msgstr "_Esegui Python" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:186 +msgid "_Execute Perl" +msgstr "_Esegui Perl" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:195 +msgid "Script" +msgstr "Script" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:205 +msgid "Output" +msgstr "Output" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:215 +msgid "Errors" +msgstr "Errori" + +#. Dialog organization +#: ../../po/../src/ui/dialog/session-player.cpp:73 +msgid "Session file" +msgstr "File di sessione" + +#: ../../po/../src/ui/dialog/session-player.cpp:74 +msgid "Playback controls" +msgstr "Controlli di riproduzione" + +#: ../../po/../src/ui/dialog/session-player.cpp:75 +msgid "Message information" +msgstr "Messaggio di informazione" + +#. Active session file display +#. fixme: Does this mean the active file for the session, or the file for the active session? +#. Please indicate which with a TRANSLATORS comment. +#: ../../po/../src/ui/dialog/session-player.cpp:85 +msgid "Active session file:" +msgstr "File sessione attiva:" + +#: ../../po/../src/ui/dialog/session-player.cpp:86 +msgid "Delay (milliseconds):" +msgstr "Ritardo (millisecondi):" + +#. Unload/load buttons +#: ../../po/../src/ui/dialog/session-player.cpp:94 +msgid "Close file" +msgstr "Chiudi file" + +#: ../../po/../src/ui/dialog/session-player.cpp:95 +msgid "Open new file" +msgstr "Apri nuovo file" + +#: ../../po/../src/ui/dialog/session-player.cpp:96 +msgid "Set delay" +msgstr "Imposta ritardo" + +#: ../../po/../src/ui/dialog/session-player.cpp:138 +msgid "Rewind" +msgstr "Riavvolgi" + +#: ../../po/../src/ui/dialog/session-player.cpp:139 +msgid "Go back one change" +msgstr "Va indietro di una modifica" + +#: ../../po/../src/ui/dialog/session-player.cpp:140 +msgid "Pause" +msgstr "Pausa" + +#: ../../po/../src/ui/dialog/session-player.cpp:141 +msgid "Go forward one change" +msgstr "Va avanti di una modifica" + +#: ../../po/../src/ui/dialog/session-player.cpp:142 +msgid "Play" +msgstr "Riproduci" + +#: ../../po/../src/ui/dialog/session-player.cpp:177 +#: ../../po/../src/verbs.cpp:1573 +msgid "Open session file" +msgstr "Apre file di sessione" + +#. ##Set up the Potrace panel +#. #### brightness #### +#. #### Multiple scanning#### +#. ----Hbox1 +#: ../../po/../src/ui/dialog/tracedialog.cpp:345 +#: ../../po/../src/ui/dialog/tracedialog.cpp:428 +msgid "Brightness" +msgstr "Luminosità:" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:348 +msgid "Trace by a given brightness level" +msgstr "Vettorizza in base ad un livello di luminosità fornito" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:355 +msgid "Brightness cutoff for black/white" +msgstr "Appiattimento della luminosità per bianco/nero" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:362 +msgid "Image Brightness" +msgstr "Luminosità Immagine" + +#. #### canny edge detection #### +#. TRANSLATORS: "Canny" is the name of the inventor of this edge detection method +#: ../../po/../src/ui/dialog/tracedialog.cpp:369 +msgid "Optimal Edge Detection (Canny)" +msgstr "Rilevamento Ottimale Bordo (Canny)" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:372 +msgid "Trace with edge detection by J. Canny's algorithm" +msgstr "Vettorizza con l'algoritmo di rilevamento dei bordi di J.Canny" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:388 +msgid "Brightness cutoff for adjacent pixels (determines edge thickness)" +msgstr "" +"Appiattimento della luminosità per i pixel adiacenti (determina lo spessore " +"del bordo)" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:395 +msgid "Edge Detection" +msgstr "Rilevamento Bordo" + +#. #### quantization #### +#. TRANSLATORS: Color Quantization: the process of reducing the number of colors +#. in an image by selecting an optimized set of representative colors and then +#. re-applying this reduced set to the original image. +#: ../../po/../src/ui/dialog/tracedialog.cpp:404 +msgid "Color Quantization" +msgstr "Quantificazione Colore" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:407 +msgid "Trace along the boundaries of reduced colors" +msgstr "Vettorizza coi bordi dei colori ridotti" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:414 +msgid "The number of reduced colors" +msgstr "Il numero dei colori ridotti" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:416 +msgid "Colors:" +msgstr "Colori:" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:421 +msgid "Quantization / Reduction" +msgstr "Quantificazione / Riduzione" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:431 +msgid "Trace the given number of brightness levels" +msgstr "Vettorizza con il numero fornito di livelli di luminosità" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:438 +msgid "Scans:" +msgstr "Scansioni:" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:440 +msgid "The desired number of scans" +msgstr "Il numero voluto di scansioni" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:448 +msgid "Trace the given number of reduced colors" +msgstr "Vettorizza con il numero fornito di colori ridotti" + +#. ---Hbox3 +#: ../../po/../src/ui/dialog/tracedialog.cpp:454 +msgid "Monochrome" +msgstr "Monocromatico" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:457 +msgid "Same as Color, but convert result to grayscale" +msgstr "Come per Colore, ma converte il risultato in scala di grigi" + +#. TRANSLATORS: "Stack" is a verb here +#: ../../po/../src/ui/dialog/tracedialog.cpp:460 +msgid "Stack" +msgstr "Pila" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:463 +msgid "" +"Stack scans vertically (no gaps) or tile horizontally (usually with gaps)" +msgstr "" +"Scansione della pila verticale (senza interruzioni) o orizzontale " +"(solitamente con interruzioni)" + +#. TRANSLATORS: "Smooth" is a verb here +#: ../../po/../src/ui/dialog/tracedialog.cpp:466 +msgid "Smooth" +msgstr "Uniformità" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:469 +msgid "Apply Gaussian blur to the bitmap before tracing" +msgstr "Applica l'effetto Gaussian blur alla bitmap prima di vettorizzare" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:473 +msgid "Multiple Scanning" +msgstr "Scansioni Multiple" + +#. #### Preview #### +#: ../../po/../src/ui/dialog/tracedialog.cpp:479 +#: ../../po/../src/ui/dialog/tracedialog.cpp:489 +msgid "Preview" +msgstr "Anteprima" + +#. do not expand +#: ../../po/../src/ui/dialog/tracedialog.cpp:483 +msgid "Preview the result without actual tracing" +msgstr "Mostra l'anteprima del risultato senza vettorizzare" + +#. #### swap black and white #### +#: ../../po/../src/ui/dialog/tracedialog.cpp:495 +msgid "Invert" +msgstr "Inverti" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:499 +msgid "Invert black and white regions for single traces" +msgstr "Inverte le regioni di bianco e nero per vettorizzazioni singole" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:503 +msgid "Thanks to Peter Selinger, http://potrace.sourceforge.net" +msgstr "Grazie a Peter Selinger, http://potrace.sourceforge.net" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:506 +msgid "Credits" +msgstr "Ringraziamenti" + +#. done +#. TRANSLATORS: Potrace is an application for transforming bitmaps into +#. vector graphics (http://potrace.sourceforge.net/) +#: ../../po/../src/ui/dialog/tracedialog.cpp:514 +msgid "Potrace" +msgstr "Potrace" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:527 +msgid "Abort a trace in progress" +msgstr "Annulla una vettorizzazione in corso" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:531 +msgid "Execute the trace" +msgstr "Esegue la vettorizzazione" + +#: ../../po/../src/ui/dialog/transformation.cpp:80 +#: ../../po/../src/ui/dialog/transformation.cpp:90 +#, fuzzy +msgid "_Horizontal" +msgstr "Orizzontale" + +#: ../../po/../src/ui/dialog/transformation.cpp:80 +msgid "Horizontal displacement (relative) or position (absolute)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:82 +#: ../../po/../src/ui/dialog/transformation.cpp:92 +#, fuzzy +msgid "_Vertical" +msgstr "Verticale" + +#: ../../po/../src/ui/dialog/transformation.cpp:82 +msgid "Vertical displacement (relative) or position (absolute)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:84 +#, fuzzy +msgid "_Width" +msgstr "_Larghezza:" + +#: ../../po/../src/ui/dialog/transformation.cpp:84 +msgid "Horizontal size increment (absolute or percentage)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:86 +#, fuzzy +msgid "_Height" +msgstr "Altezza" + +#: ../../po/../src/ui/dialog/transformation.cpp:86 +msgid "Vertical size increment (absolute or percentage)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:88 +#, fuzzy +msgid "A_ngle" +msgstr "Angolo:" + +#: ../../po/../src/ui/dialog/transformation.cpp:88 +#, fuzzy +msgid "Rotation angle (positive = counterclockwise)" +msgstr "Ruota la selezione di 90° anti-orari" + +#: ../../po/../src/ui/dialog/transformation.cpp:90 +msgid "" +"Horizontal skew angle (positive = counterclockwise), or absolute " +"displacement, or percentage displacement" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:92 +msgid "" +"Vertical skew angle (positive = counterclockwise), or absolute displacement, " +"or percentage displacement" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:95 +#, fuzzy +msgid "Transformation matrix element A" +msgstr "Matrice di trasformazione" + +#: ../../po/../src/ui/dialog/transformation.cpp:96 +#, fuzzy +msgid "Transformation matrix element B" +msgstr "Matrice di trasformazione" + +#: ../../po/../src/ui/dialog/transformation.cpp:97 +#, fuzzy +msgid "Transformation matrix element C" +msgstr "Matrice di trasformazione" + +#: ../../po/../src/ui/dialog/transformation.cpp:98 +#, fuzzy +msgid "Transformation matrix element D" +msgstr "Matrice di trasformazione" + +#: ../../po/../src/ui/dialog/transformation.cpp:99 +#, fuzzy +msgid "Transformation matrix element E" +msgstr "Matrice di trasformazione" + +#: ../../po/../src/ui/dialog/transformation.cpp:100 +#, fuzzy +msgid "Transformation matrix element F" +msgstr "Matrice di trasformazione" + +#: ../../po/../src/ui/dialog/transformation.cpp:102 +#, fuzzy +msgid "Rela_tive move" +msgstr "Movimento relativo" + +#: ../../po/../src/ui/dialog/transformation.cpp:102 +msgid "" +"Add the specified relative displacement to the current position; otherwise, " +"edit the current absolute position directly" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:103 +msgid "Scale proportionally" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:103 +msgid "Preserve the width/height ratio of the scaled objects" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:104 +msgid "Apply to each _object separately" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:104 +msgid "" +"Apply the scale/rotate/skew to each selected object separately; otherwise, " +"transform the selection as a whole" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:105 +#, fuzzy +msgid "Edit c_urrent matrix" +msgstr "Alza il livello attuale" + +#: ../../po/../src/ui/dialog/transformation.cpp:105 +msgid "" +"Edit the current transform= matrix; otherwise, post-multiply transform= by " +"this matrix" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:115 +#, fuzzy +msgid "_Move" +msgstr "Muovi" + +#: ../../po/../src/ui/dialog/transformation.cpp:118 +#, fuzzy +msgid "_Scale" +msgstr "Scala" + +#: ../../po/../src/ui/dialog/transformation.cpp:121 +#, fuzzy +msgid "_Rotate" +msgstr "Ruota" + +#: ../../po/../src/ui/dialog/transformation.cpp:124 +#, fuzzy +msgid "Ske_w" +msgstr "Distorsione" + +#: ../../po/../src/ui/dialog/transformation.cpp:127 +msgid "Matri_x" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:141 +msgid "Reset the values on the current tab to defaults" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:148 +#, fuzzy +msgid "Apply transformation to selection" +msgstr "Applica la trasformazione all'oggetto" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:43 +msgid "_Use SSL" +msgstr "_Usare SSL" + +#. Construct dialog interface +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:68 +msgid "_Server:" +msgstr "_Server:" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:69 +msgid "_Username:" +msgstr "Nome _utente:" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:70 +msgid "_Password:" +msgstr "_Password:" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:71 +msgid "P_ort:" +msgstr "P_orta:" + +#. Buttons +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:99 +msgid "Connect" +msgstr "Connetti" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:126 +msgid "Establishing connection to Jabber server %1 as user %2" +msgstr "" +"Instaurazione connessione al server Jabber %1 come utente %2" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:131 +msgid "Failed to establish connection to Jabber server %1" +msgstr "Fallita instaurazione connessione al server Jabber %1" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:136 +msgid "Authentication failed on Jabber server %1 as %2" +msgstr "Fallita autenticazione sul server Jabber %1 come %2" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:141 +msgid "SSL initialization failed when connecting to Jabber server %1" +msgstr "" +"Inizializzazione SSL fallita durante la connessione al server Jabber %1" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:147 +msgid "Connected to Jabber server %1 as %2" +msgstr "Connesso al server Jabber %1 come %2" + +#. Construct labels +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:75 +msgid "Chatroom _name:" +msgstr "_Nome chatroom:" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:76 +msgid "Chatroom _server:" +msgstr "_Server chatroom:" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:77 +msgid "Chatroom _password:" +msgstr "_Password chatroom:" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:78 +msgid "Chatroom _handle:" +msgstr "_Handle della chatroom:" + +#. Button setup and callback registration +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:97 +msgid "Connect to chatroom" +msgstr "Connetti a chatromm" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:132 +msgid "Synchronizing with chatroom %1@%2 using the handle %3" +msgstr "" +"Sincronizzazione con la chatromm %1@%2 usando l'handle %3" + +#. Construct dialog interface +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:78 +msgid "_User's Jabber ID:" +msgstr "ID Jabber dell'_utente:" + +#. Buttons +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:82 +msgid "_Invite user" +msgstr "_Invita utente" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:83 +msgid "_Cancel" +msgstr "A_nnulla" + +# Come in GAIM +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:94 +msgid "Buddy List" +msgstr "Lista contatti" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:170 +msgid "Sending whiteboard invitation to %1" +msgstr "Spedizione invito whiteboard a %1" + +#. FIXME: strings are replaced by placeholders, NOT to be translated until the code is enabled +#. See http://sourceforge.net/mailarchive/message.php?msg_id=11746016 for details +#. File menu +#. Edit menu +#. View menu +#. Layer menu +#. Object menu +#. Path menu +#. add(Gtk::StockItem(CLEANUP, _("PLACEHOLDER, do not translate"))); (using Gtk::Stock::CLEAR) +#. Text menu +#. About menu +#. Tools toolbox +#. Select Tool controls +#. Node Tool controls +#. Calligraphy Tool controls +#. Session playback controls +#: ../../po/../src/ui/stock-items.cpp:34 ../../po/../src/ui/stock-items.cpp:35 +#: ../../po/../src/ui/stock-items.cpp:36 ../../po/../src/ui/stock-items.cpp:37 +#: ../../po/../src/ui/stock-items.cpp:38 ../../po/../src/ui/stock-items.cpp:39 +#: ../../po/../src/ui/stock-items.cpp:40 ../../po/../src/ui/stock-items.cpp:41 +#: ../../po/../src/ui/stock-items.cpp:42 ../../po/../src/ui/stock-items.cpp:43 +#: ../../po/../src/ui/stock-items.cpp:46 ../../po/../src/ui/stock-items.cpp:47 +#: ../../po/../src/ui/stock-items.cpp:48 ../../po/../src/ui/stock-items.cpp:49 +#: ../../po/../src/ui/stock-items.cpp:50 ../../po/../src/ui/stock-items.cpp:51 +#: ../../po/../src/ui/stock-items.cpp:52 ../../po/../src/ui/stock-items.cpp:53 +#: ../../po/../src/ui/stock-items.cpp:54 ../../po/../src/ui/stock-items.cpp:55 +#: ../../po/../src/ui/stock-items.cpp:56 ../../po/../src/ui/stock-items.cpp:57 +#: ../../po/../src/ui/stock-items.cpp:58 ../../po/../src/ui/stock-items.cpp:59 +#: ../../po/../src/ui/stock-items.cpp:62 ../../po/../src/ui/stock-items.cpp:63 +#: ../../po/../src/ui/stock-items.cpp:64 ../../po/../src/ui/stock-items.cpp:65 +#: ../../po/../src/ui/stock-items.cpp:66 ../../po/../src/ui/stock-items.cpp:67 +#: ../../po/../src/ui/stock-items.cpp:68 ../../po/../src/ui/stock-items.cpp:69 +#: ../../po/../src/ui/stock-items.cpp:70 ../../po/../src/ui/stock-items.cpp:71 +#: ../../po/../src/ui/stock-items.cpp:72 ../../po/../src/ui/stock-items.cpp:73 +#: ../../po/../src/ui/stock-items.cpp:74 ../../po/../src/ui/stock-items.cpp:75 +#: ../../po/../src/ui/stock-items.cpp:76 ../../po/../src/ui/stock-items.cpp:77 +#: ../../po/../src/ui/stock-items.cpp:78 ../../po/../src/ui/stock-items.cpp:79 +#: ../../po/../src/ui/stock-items.cpp:80 ../../po/../src/ui/stock-items.cpp:81 +#: ../../po/../src/ui/stock-items.cpp:82 ../../po/../src/ui/stock-items.cpp:83 +#: ../../po/../src/ui/stock-items.cpp:84 ../../po/../src/ui/stock-items.cpp:85 +#: ../../po/../src/ui/stock-items.cpp:86 ../../po/../src/ui/stock-items.cpp:87 +#: ../../po/../src/ui/stock-items.cpp:88 ../../po/../src/ui/stock-items.cpp:89 +#: ../../po/../src/ui/stock-items.cpp:92 ../../po/../src/ui/stock-items.cpp:93 +#: ../../po/../src/ui/stock-items.cpp:94 ../../po/../src/ui/stock-items.cpp:95 +#: ../../po/../src/ui/stock-items.cpp:96 ../../po/../src/ui/stock-items.cpp:97 +#: ../../po/../src/ui/stock-items.cpp:98 ../../po/../src/ui/stock-items.cpp:99 +#: ../../po/../src/ui/stock-items.cpp:100 +#: ../../po/../src/ui/stock-items.cpp:101 +#: ../../po/../src/ui/stock-items.cpp:102 +#: ../../po/../src/ui/stock-items.cpp:103 +#: ../../po/../src/ui/stock-items.cpp:104 +#: ../../po/../src/ui/stock-items.cpp:105 +#: ../../po/../src/ui/stock-items.cpp:108 +#: ../../po/../src/ui/stock-items.cpp:109 +#: ../../po/../src/ui/stock-items.cpp:110 +#: ../../po/../src/ui/stock-items.cpp:111 +#: ../../po/../src/ui/stock-items.cpp:112 +#: ../../po/../src/ui/stock-items.cpp:113 +#: ../../po/../src/ui/stock-items.cpp:114 +#: ../../po/../src/ui/stock-items.cpp:115 +#: ../../po/../src/ui/stock-items.cpp:116 +#: ../../po/../src/ui/stock-items.cpp:117 +#: ../../po/../src/ui/stock-items.cpp:118 +#: ../../po/../src/ui/stock-items.cpp:119 +#: ../../po/../src/ui/stock-items.cpp:120 +#: ../../po/../src/ui/stock-items.cpp:121 +#: ../../po/../src/ui/stock-items.cpp:122 +#: ../../po/../src/ui/stock-items.cpp:123 +#: ../../po/../src/ui/stock-items.cpp:124 +#: ../../po/../src/ui/stock-items.cpp:125 +#: ../../po/../src/ui/stock-items.cpp:126 +#: ../../po/../src/ui/stock-items.cpp:127 +#: ../../po/../src/ui/stock-items.cpp:130 +#: ../../po/../src/ui/stock-items.cpp:131 +#: ../../po/../src/ui/stock-items.cpp:132 +#: ../../po/../src/ui/stock-items.cpp:133 +#: ../../po/../src/ui/stock-items.cpp:134 +#: ../../po/../src/ui/stock-items.cpp:135 +#: ../../po/../src/ui/stock-items.cpp:136 +#: ../../po/../src/ui/stock-items.cpp:137 +#: ../../po/../src/ui/stock-items.cpp:138 +#: ../../po/../src/ui/stock-items.cpp:139 +#: ../../po/../src/ui/stock-items.cpp:140 +#: ../../po/../src/ui/stock-items.cpp:141 +#: ../../po/../src/ui/stock-items.cpp:142 +#: ../../po/../src/ui/stock-items.cpp:143 +#: ../../po/../src/ui/stock-items.cpp:144 +#: ../../po/../src/ui/stock-items.cpp:145 +#: ../../po/../src/ui/stock-items.cpp:146 +#: ../../po/../src/ui/stock-items.cpp:150 +#: ../../po/../src/ui/stock-items.cpp:151 +#: ../../po/../src/ui/stock-items.cpp:152 +#: ../../po/../src/ui/stock-items.cpp:153 +#: ../../po/../src/ui/stock-items.cpp:156 +#: ../../po/../src/ui/stock-items.cpp:157 +#: ../../po/../src/ui/stock-items.cpp:158 +#: ../../po/../src/ui/stock-items.cpp:161 +#: ../../po/../src/ui/stock-items.cpp:162 +#: ../../po/../src/ui/stock-items.cpp:163 +#: ../../po/../src/ui/stock-items.cpp:164 +#: ../../po/../src/ui/stock-items.cpp:165 +#: ../../po/../src/ui/stock-items.cpp:166 +#: ../../po/../src/ui/stock-items.cpp:167 +#: ../../po/../src/ui/stock-items.cpp:168 +#: ../../po/../src/ui/stock-items.cpp:169 +#: ../../po/../src/ui/stock-items.cpp:170 +#: ../../po/../src/ui/stock-items.cpp:171 +#: ../../po/../src/ui/stock-items.cpp:172 +#: ../../po/../src/ui/stock-items.cpp:175 +#: ../../po/../src/ui/stock-items.cpp:176 +#: ../../po/../src/ui/stock-items.cpp:177 +#: ../../po/../src/ui/stock-items.cpp:178 +#: ../../po/../src/ui/stock-items.cpp:181 +#: ../../po/../src/ui/stock-items.cpp:182 +#: ../../po/../src/ui/stock-items.cpp:183 +#: ../../po/../src/ui/stock-items.cpp:184 +#: ../../po/../src/ui/stock-items.cpp:185 +#: ../../po/../src/ui/stock-items.cpp:186 +#: ../../po/../src/ui/stock-items.cpp:187 +#: ../../po/../src/ui/stock-items.cpp:188 +#: ../../po/../src/ui/stock-items.cpp:189 +#: ../../po/../src/ui/stock-items.cpp:190 +#: ../../po/../src/ui/stock-items.cpp:191 +#: ../../po/../src/ui/stock-items.cpp:194 +#: ../../po/../src/ui/stock-items.cpp:195 +#: ../../po/../src/ui/stock-items.cpp:198 +#: ../../po/../src/ui/stock-items.cpp:199 +#: ../../po/../src/ui/stock-items.cpp:200 +#: ../../po/../src/ui/stock-items.cpp:201 +#: ../../po/../src/ui/stock-items.cpp:202 +msgid "PLACEHOLDER, do not translate" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:88 +msgid "small" +msgstr "piccola" + +#: ../../po/../src/ui/widget/panel.cpp:89 +msgid "medium" +msgstr "media" + +#: ../../po/../src/ui/widget/panel.cpp:90 +msgid "large" +msgstr "grande" + +#: ../../po/../src/ui/widget/panel.cpp:91 +msgid "huge" +msgstr "enorme" + +#: ../../po/../src/ui/widget/panel.cpp:106 +msgid "List" +msgstr "Elenco" + +#: ../../po/../src/ui/widget/selected-style.cpp:67 +msgid "F:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:68 +msgid "S:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:69 +msgid "O:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:95 +msgid "N/A" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:98 +#: ../../po/../src/ui/widget/selected-style.cpp:712 +#, fuzzy +msgid "Nothing selected" +msgstr "Nessun gradiente selezionato" + +#: ../../po/../src/ui/widget/selected-style.cpp:103 +msgid "No fill" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:103 +#, fuzzy +msgid "No stroke" +msgstr " (contorno)" + +#: ../../po/../src/ui/widget/selected-style.cpp:105 +#: ../../po/../src/widgets/paint-selector.cpp:190 +msgid "Pattern" +msgstr "Motivo" + +#: ../../po/../src/ui/widget/selected-style.cpp:108 +#: ../../po/../src/widgets/paint-selector.cpp:885 +msgid "Pattern fill" +msgstr "Motivo" + +#: ../../po/../src/ui/widget/selected-style.cpp:108 +#, fuzzy +msgid "Pattern stroke" +msgstr "Spessore del motivo" + +#: ../../po/../src/ui/widget/selected-style.cpp:110 +#, fuzzy +msgid "L Gradient" +msgstr "Gradiente" + +#: ../../po/../src/ui/widget/selected-style.cpp:113 +#, fuzzy +msgid "Linear gradient fill" +msgstr "Gradiente lineare" + +#: ../../po/../src/ui/widget/selected-style.cpp:113 +#, fuzzy +msgid "Linear gradient stroke" +msgstr "Gradiente lineare" + +#: ../../po/../src/ui/widget/selected-style.cpp:115 +#, fuzzy +msgid "R Gradient" +msgstr "Gradiente" + +#: ../../po/../src/ui/widget/selected-style.cpp:118 +#, fuzzy +msgid "Radial gradient fill" +msgstr "Gradiente radiale" + +#: ../../po/../src/ui/widget/selected-style.cpp:118 +#, fuzzy +msgid "Radial gradient stroke" +msgstr "Gradiente radiale" + +#: ../../po/../src/ui/widget/selected-style.cpp:120 +#, fuzzy +msgid "Different" +msgstr "_Differenza" + +#: ../../po/../src/ui/widget/selected-style.cpp:123 +#, fuzzy +msgid "Different fills" +msgstr "_Differenza" + +#: ../../po/../src/ui/widget/selected-style.cpp:123 +#, fuzzy +msgid "Different strokes" +msgstr "_Differenza" + +#: ../../po/../src/ui/widget/selected-style.cpp:125 +#, fuzzy +msgid "Unset" +msgstr "intrusione" + +#. TRANSLATORS COMMENT: unset is a verb here +#: ../../po/../src/ui/widget/selected-style.cpp:128 +#: ../../po/../src/ui/widget/selected-style.cpp:182 +msgid "Unset fill" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:128 +#: ../../po/../src/ui/widget/selected-style.cpp:182 +#, fuzzy +msgid "Unset stroke" +msgstr " (contorno)" + +#: ../../po/../src/ui/widget/selected-style.cpp:131 +#, fuzzy +msgid "Flat color fill" +msgstr "Colore unico" + +#: ../../po/../src/ui/widget/selected-style.cpp:131 +#, fuzzy +msgid "Flat color stroke" +msgstr "Colore unico" + +#. TRANSLATOR COMMENT: A means "Averaged" +#: ../../po/../src/ui/widget/selected-style.cpp:134 +#, fuzzy +msgid "A" +msgstr "_A" + +#: ../../po/../src/ui/widget/selected-style.cpp:137 +#, fuzzy +msgid "Fill is averaged over selected objects" +msgstr "Esegue un OR esclusivo tra gli oggetti selezionati" + +#: ../../po/../src/ui/widget/selected-style.cpp:137 +#, fuzzy +msgid "Stroke is averaged over selected objects" +msgstr "Fa sì che i connettori evitino gli oggetti selezionati" + +#. TRANSLATOR COMMENT: M means "Multiple" +#: ../../po/../src/ui/widget/selected-style.cpp:140 +#, fuzzy +msgid "M" +msgstr "_M" + +#: ../../po/../src/ui/widget/selected-style.cpp:143 +#, fuzzy +msgid "Multiple selected objects have the same fill" +msgstr "Riflette verticalmente gli oggetti selezionati" + +#: ../../po/../src/ui/widget/selected-style.cpp:143 +#, fuzzy +msgid "Multiple selected objects have the same stroke" +msgstr "Riflette verticalmente gli oggetti selezionati" + +#: ../../po/../src/ui/widget/selected-style.cpp:145 +#, fuzzy +msgid "Edit fill..." +msgstr "Modifica..." + +#: ../../po/../src/ui/widget/selected-style.cpp:145 +#, fuzzy +msgid "Edit stroke..." +msgstr "Modifica..." + +#: ../../po/../src/ui/widget/selected-style.cpp:149 +#, fuzzy +msgid "Last set color" +msgstr "Colore unico" + +#: ../../po/../src/ui/widget/selected-style.cpp:153 +#, fuzzy +msgid "Last selected color" +msgstr "Ultimo selezionato" + +#: ../../po/../src/ui/widget/selected-style.cpp:157 +#, fuzzy +msgid "White" +msgstr "Whiteboa_rd" + +#: ../../po/../src/ui/widget/selected-style.cpp:161 +#: ../../po/../src/widgets/sp-color-scales.cpp:461 +#: ../../po/../src/widgets/sp-color-scales.cpp:462 +msgid "Black" +msgstr "Nero" + +#: ../../po/../src/ui/widget/selected-style.cpp:165 +#, fuzzy +msgid "Copy color" +msgstr "Colore del passaggio" + +#: ../../po/../src/ui/widget/selected-style.cpp:169 +#, fuzzy +msgid "Paste color" +msgstr "Colore unico" + +#: ../../po/../src/ui/widget/selected-style.cpp:173 +#, fuzzy +msgid "Swap fill and stroke" +msgstr "Riempimento e Contorni" + +#: ../../po/../src/ui/widget/selected-style.cpp:177 +msgid "Make fill opaque" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:177 +msgid "Make stroke opaque" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:186 +#, fuzzy +msgid "Remove fill" +msgstr " Ri_muovi " + +#: ../../po/../src/ui/widget/selected-style.cpp:186 +#, fuzzy +msgid "Remove stroke" +msgstr "Rimuovi Collegamento" + +#: ../../po/../src/ui/widget/selected-style.cpp:718 +#, fuzzy +msgid "Master opacity" +msgstr "_Opacità generale" + +#: ../../po/../src/ui/widget/selected-style.cpp:744 +msgid "0 (transparent)" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:768 +msgid "1.0 (opaque)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1046 +msgid "Moved to next layer." +msgstr "Spostato al livello successivo." + +#: ../../po/../src/verbs.cpp:1048 +msgid "Cannot move past last layer." +msgstr "Impossibile spostare ad un livello successivo all'ultimo." + +#: ../../po/../src/verbs.cpp:1057 +msgid "Moved to previous layer." +msgstr "Spostato al livello precedente." + +#: ../../po/../src/verbs.cpp:1059 +msgid "Cannot move past first layer." +msgstr "Impossibile spostare ad un livello precedente al primo." + +#: ../../po/../src/verbs.cpp:1076 ../../po/../src/verbs.cpp:1150 +msgid "No current layer." +msgstr "Nessun livello attuale." + +#: ../../po/../src/verbs.cpp:1105 +#, c-format +msgid "Raised layer %s." +msgstr "Alzato il livello %s." + +#: ../../po/../src/verbs.cpp:1109 +#, c-format +msgid "Lowered layer %s." +msgstr "Abbassato il livello %s." + +#: ../../po/../src/verbs.cpp:1118 +msgid "Cannot move layer any further." +msgstr "Non si può spostare ulteriormente il livello." + +#. TRANSLATORS: this means "The layer has been deleted." +#: ../../po/../src/verbs.cpp:1148 +msgid "Deleted layer." +msgstr "Livello eliminato." + +#: ../../po/../src/verbs.cpp:1544 +msgid "" +"You need to connect to a Jabber server before sharing a document with " +"another user." +msgstr "" +"È necessario connettersi ad un server Jabber prima di condividere un " +"documento con un altro utente." + +#: ../../po/../src/verbs.cpp:1559 +msgid "" +"You need to connect to a Jabber server before sharing a document with a " +"chatroom." +msgstr "" +"È necessario connettersi ad un server Jabber prima di condividere un " +"documento con una chatroom." + +#: ../../po/../src/verbs.cpp:1569 +msgid "XML node tracker has not been initialized; nothing to dump" +msgstr "Il tracker node XML non è stato inizializzato; niente da riversare" + +#. TRANSLATORS: If you have translated the keys.svg file to your language, then +#. translate this string as "keys.LANG.svg" (where LANG is your language code); +#. otherwise leave as "keys.svg". +#: ../../po/../src/verbs.cpp:1631 +msgid "keys.svg" +msgstr "keys.svg" + +#. TRANSLATORS: If you have translated the tutorial-basic.svg file to your language, +#. then translate this string as "tutorial-basic.LANG.svg" (where LANG is your language +#. code); otherwise leave as "tutorial-basic.svg". +#: ../../po/../src/verbs.cpp:1667 +msgid "tutorial-basic.svg" +msgstr "tutorial-basic.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1671 +msgid "tutorial-shapes.svg" +msgstr "tutorial-shapes.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1675 +msgid "tutorial-advanced.svg" +msgstr "tutorial-advanced.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1679 +msgid "tutorial-tracing.svg" +msgstr "tutorial-tracing.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1683 +msgid "tutorial-calligraphy.svg" +msgstr "tutorial-calligraphy.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1687 +msgid "tutorial-elements.svg" +msgstr "tutorial-elements.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1691 +msgid "tutorial-tips.svg" +msgstr "tutorial-tips.svg" + +#: ../../po/../src/verbs.cpp:1842 +msgid "Does nothing" +msgstr "Fa niente" + +#. File +#: ../../po/../src/verbs.cpp:1845 +msgid "Default" +msgstr "Predefinito" + +#: ../../po/../src/verbs.cpp:1845 +msgid "Create new document from default template" +msgstr "Crea un nuovo documento dal modello predefinito" + +#: ../../po/../src/verbs.cpp:1847 +msgid "_Open..." +msgstr "_Apri..." + +#: ../../po/../src/verbs.cpp:1848 +msgid "Open existing document" +msgstr "Apre un documento esistente" + +#: ../../po/../src/verbs.cpp:1849 +msgid "Re_vert" +msgstr "Ri_carica" + +#: ../../po/../src/verbs.cpp:1850 +msgid "Revert to the last saved version of document (changes will be lost)" +msgstr "" +"Ricarica l'ultima versione salvata del documento (i cambiamenti verranno " +"persi)" + +#: ../../po/../src/verbs.cpp:1851 +msgid "_Save" +msgstr "_Salva" + +#: ../../po/../src/verbs.cpp:1851 +msgid "Save document" +msgstr "Salva il documento" + +#: ../../po/../src/verbs.cpp:1853 +msgid "Save _As..." +msgstr "Salv_a come..." + +#: ../../po/../src/verbs.cpp:1854 +msgid "Save document under new name" +msgstr "Salva il documento con un nuovo nome" + +#: ../../po/../src/verbs.cpp:1855 +msgid "_Print..." +msgstr "Stam_pa..." + +#: ../../po/../src/verbs.cpp:1855 +msgid "Print document" +msgstr "Stampa il documento" + +#. TRANSLATORS: "Vacuum Defs" means "Clean up defs" (so as to remove unused definitions) +#: ../../po/../src/verbs.cpp:1858 +msgid "Vac_uum Defs" +msgstr "Definizioni s_uperflue" + +#: ../../po/../src/verbs.cpp:1858 +msgid "Remove unused predefined items from the <defs> of the document" +msgstr "" +"Elimina elementi predefiniti inutilizzati dai <defs> del documento" + +#: ../../po/../src/verbs.cpp:1860 +msgid "Print _Direct" +msgstr "Stampa _diretta" + +#: ../../po/../src/verbs.cpp:1861 +msgid "Print directly without prompting to a file or pipe" +msgstr "Stampa diretta su un file o in una pipe senza chiedere conferma" + +#: ../../po/../src/verbs.cpp:1862 +msgid "Print Previe_w" +msgstr "Anteprima di stam_pa" + +#: ../../po/../src/verbs.cpp:1863 +msgid "Preview document printout" +msgstr "Mostra l'anteprima del documento" + +#: ../../po/../src/verbs.cpp:1864 +msgid "_Import..." +msgstr "_Importa..." + +#: ../../po/../src/verbs.cpp:1865 +msgid "Import bitmap or SVG image into document" +msgstr "Importa una bitmap o un'immagine SVG nel documento" + +#: ../../po/../src/verbs.cpp:1866 +msgid "_Export Bitmap..." +msgstr "_Esporta bitmap..." + +#: ../../po/../src/verbs.cpp:1867 +msgid "Export document or selection as a bitmap image" +msgstr "Esporta il documento o la selezione come una immagine bitmap" + +#: ../../po/../src/verbs.cpp:1868 +msgid "N_ext Window" +msgstr "Fin_estra successiva" + +#: ../../po/../src/verbs.cpp:1869 +msgid "Switch to the next document window" +msgstr "Passa alla finestra successiva" + +#: ../../po/../src/verbs.cpp:1870 +msgid "P_revious Window" +msgstr "Finestra p_recedente" + +#: ../../po/../src/verbs.cpp:1871 +msgid "Switch to the previous document window" +msgstr "Passa alla finestra precedente" + +#: ../../po/../src/verbs.cpp:1872 +msgid "_Close" +msgstr "_Chiudi" + +#: ../../po/../src/verbs.cpp:1873 +msgid "Close window" +msgstr "Chiude la finestra" + +#: ../../po/../src/verbs.cpp:1874 +msgid "_Quit" +msgstr "_Esci" + +#: ../../po/../src/verbs.cpp:1874 +msgid "Quit Inkscape" +msgstr "Chiude Inkscape" + +#. Edit +#: ../../po/../src/verbs.cpp:1877 +msgid "_Undo" +msgstr "Ann_ulla" + +#: ../../po/../src/verbs.cpp:1877 +msgid "Undo last action" +msgstr "Annulla l'ultima azione" + +#: ../../po/../src/verbs.cpp:1879 +msgid "_Redo" +msgstr "_Ripeti" + +#: ../../po/../src/verbs.cpp:1880 +msgid "Do again last undone action" +msgstr "Ripete l'ultima azione annullata" + +#: ../../po/../src/verbs.cpp:1881 +msgid "Cu_t" +msgstr "_Taglia" + +#: ../../po/../src/verbs.cpp:1882 +msgid "Cut selection to clipboard" +msgstr "Taglia la selezione e la sposta negli appunti" + +#: ../../po/../src/verbs.cpp:1883 +msgid "_Copy" +msgstr "_Copia" + +#: ../../po/../src/verbs.cpp:1884 +msgid "Copy selection to clipboard" +msgstr "Copia la selezione negli appunti" + +#: ../../po/../src/verbs.cpp:1885 +msgid "_Paste" +msgstr "I_ncolla" + +#: ../../po/../src/verbs.cpp:1886 +msgid "Paste objects from clipboard to mouse point" +msgstr "Incolla l'oggetto dagli appunti sotto al puntatore" + +#: ../../po/../src/verbs.cpp:1887 +msgid "Paste _Style" +msgstr "Incolla _stile" + +#: ../../po/../src/verbs.cpp:1888 +msgid "Apply style of the copied object to selection" +msgstr "Applica alla selezione lo stile dell'oggetto copiato" + +#: ../../po/../src/verbs.cpp:1889 +msgid "Paste _In Place" +msgstr "Incolla _in origine" + +#: ../../po/../src/verbs.cpp:1890 +msgid "Paste objects from clipboard to the original location" +msgstr "Incolla l'oggetto dagli appunti al suo luogo di origine" + +#: ../../po/../src/verbs.cpp:1891 +msgid "_Delete" +msgstr "Eli_mina" + +#: ../../po/../src/verbs.cpp:1892 +msgid "Delete selection" +msgstr "Elimina la selezione" + +#: ../../po/../src/verbs.cpp:1893 +msgid "Duplic_ate" +msgstr "Duplic_a" + +#: ../../po/../src/verbs.cpp:1894 +msgid "Duplicate selected objects" +msgstr "Duplica gli oggetti selezionati" + +#: ../../po/../src/verbs.cpp:1895 +msgid "Clo_ne" +msgstr "Clo_na" + +#: ../../po/../src/verbs.cpp:1896 +msgid "Create a clone of selected object (a copy linked to the original)" +msgstr "" +"Crea un clone dell'oggetto selezionato (una copia collegata all'originale)" + +#: ../../po/../src/verbs.cpp:1897 +msgid "Unlin_k Clone" +msgstr "Scolle_ga clone" + +#: ../../po/../src/verbs.cpp:1898 +msgid "Cut the clone's link to its original" +msgstr "Rimuove il collegamente tra il clone e l'originale" + +#: ../../po/../src/verbs.cpp:1899 +msgid "Select _Original" +msgstr "Seleziona _originale" + +#: ../../po/../src/verbs.cpp:1900 +msgid "Select the object to which the clone is linked" +msgstr "Seleziona l'oggetto a cui il clone è collegato" + +#. TRANSLATORS: Convert selection to a rectangle with tiled pattern fill +#: ../../po/../src/verbs.cpp:1902 +msgid "O_bjects to Pattern" +msgstr "_Da oggetto a motivo" + +#: ../../po/../src/verbs.cpp:1903 +msgid "Convert selection to a rectangle with tiled pattern fill" +msgstr "Converte la selezione in un rettangolo a motivo" + +#. TRANSLATORS: Extract objects from a tiled pattern fill +#: ../../po/../src/verbs.cpp:1905 +msgid "Pattern to Ob_jects" +msgstr "Da moti_vo a oggetto" + +#: ../../po/../src/verbs.cpp:1906 +msgid "Extract objects from a tiled pattern fill" +msgstr "Estrae un oggetto da un motivo" + +#: ../../po/../src/verbs.cpp:1907 +msgid "Clea_r All" +msgstr "Elimina tu_tto" + +#: ../../po/../src/verbs.cpp:1908 +msgid "Delete all objects from document" +msgstr "Elimina tutti gli oggetti dal documento" + +#: ../../po/../src/verbs.cpp:1909 +msgid "Select Al_l" +msgstr "Se_leziona tutto" + +#: ../../po/../src/verbs.cpp:1910 +msgid "Select all objects or all nodes" +msgstr "Seleziona tutti gli oggetti o nodi" + +#: ../../po/../src/verbs.cpp:1911 +msgid "Select All in All La_yers" +msgstr "Seleziona tutto in tutti li_velli" + +#: ../../po/../src/verbs.cpp:1912 +msgid "Select all objects in all visible and unlocked layers" +msgstr "Seleziona tutti gli oggetti in tutti i livelli visibili e sbloccati" + +#: ../../po/../src/verbs.cpp:1913 +msgid "In_vert Selection" +msgstr "In_verti selezione" + +#: ../../po/../src/verbs.cpp:1914 +msgid "Invert selection (unselect what is selected and select everything else)" +msgstr "" +"Inverte la selezione (deseleziona cosa è selezionato e seleziona tutto il " +"resto)" + +#: ../../po/../src/verbs.cpp:1915 +msgid "Invert in All Layers" +msgstr "Inverti in tutti livelli" + +#: ../../po/../src/verbs.cpp:1916 +msgid "Invert selection in all visible and unlocked layers" +msgstr "Inverte la selezione in tutti i livelli visibili e sbloccati" + +#: ../../po/../src/verbs.cpp:1917 +msgid "D_eselect" +msgstr "D_eseleziona" + +#: ../../po/../src/verbs.cpp:1918 +msgid "Deselect any selected objects or nodes" +msgstr "Deseleziona tutti i nodi o gli oggetti selezionati" + +#. Selection +#: ../../po/../src/verbs.cpp:1921 +msgid "Raise to _Top" +msgstr "Spos_ta in cima" + +#: ../../po/../src/verbs.cpp:1922 +msgid "Raise selection to top" +msgstr "Sposta la selezione in cima" + +#: ../../po/../src/verbs.cpp:1923 +msgid "Lower to _Bottom" +msgstr "Sposta in fondo" + +#: ../../po/../src/verbs.cpp:1924 +msgid "Lower selection to bottom" +msgstr "Sposta la selezione in fondo" + +#: ../../po/../src/verbs.cpp:1925 +msgid "_Raise" +msgstr "Al_za" + +#: ../../po/../src/verbs.cpp:1926 +msgid "Raise selection one step" +msgstr "Alza la selezione di un livello" + +#: ../../po/../src/verbs.cpp:1927 +msgid "_Lower" +msgstr "A_bbassa" + +#: ../../po/../src/verbs.cpp:1928 +msgid "Lower selection one step" +msgstr "Abbassa la selezione di un livello" + +#: ../../po/../src/verbs.cpp:1929 +msgid "_Group" +msgstr "Ra_ggruppa" + +#: ../../po/../src/verbs.cpp:1930 +msgid "Group selected objects" +msgstr "Raggruppa gli oggetti selezionati" + +#: ../../po/../src/verbs.cpp:1932 +msgid "Ungroup selected groups" +msgstr "Divide il gruppo selezionato" + +#: ../../po/../src/verbs.cpp:1934 +msgid "_Put on Path" +msgstr "Metti su tracciato" + +#: ../../po/../src/verbs.cpp:1935 +msgid "Put text on path" +msgstr "Mette il testo sul tracciato" + +#: ../../po/../src/verbs.cpp:1936 +msgid "_Remove from Path" +msgstr "_Rimuovi dal tracciato" + +#: ../../po/../src/verbs.cpp:1937 +msgid "Remove text from path" +msgstr "Rimuove il testo dal tracciato" + +#: ../../po/../src/verbs.cpp:1938 +msgid "Remove Manual _Kerns" +msgstr "Rimuovi trasformazioni" + +#. TRANSLATORS: "glyph": An image used in the visual representation of characters; +#. roughly speaking, how a character looks. A font is a set of glyphs. +#: ../../po/../src/verbs.cpp:1941 +msgid "Remove all manual kerns and glyph rotations from a text object" +msgstr "Rimuovi tutte le trasformazioni e rotazioni da un oggetto testuale" + +#: ../../po/../src/verbs.cpp:1943 +msgid "_Union" +msgstr "_Unione" + +#: ../../po/../src/verbs.cpp:1944 +msgid "Union of selected objects" +msgstr "Unione tra gli oggetti selezionati" + +#: ../../po/../src/verbs.cpp:1945 +msgid "_Intersection" +msgstr "_Intersezione" + +#: ../../po/../src/verbs.cpp:1946 +msgid "Intersection of selected objects" +msgstr "Intersezione tra gli oggetti selezionati" + +#: ../../po/../src/verbs.cpp:1947 +msgid "_Difference" +msgstr "_Differenza" + +#: ../../po/../src/verbs.cpp:1948 +msgid "Difference of selected objects (bottom minus top)" +msgstr "Differenza tra gli oggetti selezionati (inferiore meno superiore)" + +#: ../../po/../src/verbs.cpp:1949 +msgid "E_xclusion" +msgstr "E_sclusione" + +#: ../../po/../src/verbs.cpp:1950 +msgid "Exclusive OR of selected objects" +msgstr "Esegue un OR esclusivo tra gli oggetti selezionati" + +#: ../../po/../src/verbs.cpp:1951 +msgid "Di_vision" +msgstr "Di_visione" + +#: ../../po/../src/verbs.cpp:1952 +msgid "Cut the bottom object into pieces" +msgstr "Taglia i contorni dell'oggetto inferiore" + +#. TRANSLATORS: "to cut a path" is not the same as "to break a path apart" - see the +#. Advanced tutorial for more info +#: ../../po/../src/verbs.cpp:1955 +msgid "Cut _Path" +msgstr "Taglia _tracciato" + +#: ../../po/../src/verbs.cpp:1956 +msgid "Cut the bottom object's stroke into pieces, removing fill" +msgstr "Taglia il contorno dell'oggetto inferiore, rimuovendo il riempimento" + +#. TRANSLATORS: "outset": expand a shape by offsetting the object's path, +#. i.e. by displacing it perpendicular to the path in each point. +#. See also the Advanced Tutorial for explanation. +#: ../../po/../src/verbs.cpp:1960 +msgid "Outs_et" +msgstr "_Estrudi" + +#: ../../po/../src/verbs.cpp:1961 +msgid "Outset selected paths" +msgstr "Estrude il tracciato selezionato" + +#: ../../po/../src/verbs.cpp:1963 +msgid "O_utset Path by 1 px" +msgstr "Estr_udi Tracciato di 1px" + +#: ../../po/../src/verbs.cpp:1964 +msgid "Outset selected paths by 1 px" +msgstr "Estrude il tracciato selezionato di 1px" + +#: ../../po/../src/verbs.cpp:1966 +msgid "O_utset Path by 10 px" +msgstr "Estr_udi Tracciato di 10px" + +#: ../../po/../src/verbs.cpp:1967 +msgid "Outset selected paths by 10 px" +msgstr "Estrude il tracciato selezionato di 10px" + +#. TRANSLATORS: "inset": contract a shape by offsetting the object's path, +#. i.e. by displacing it perpendicular to the path in each point. +#. See also the Advanced Tutorial for explanation. +#: ../../po/../src/verbs.cpp:1971 +msgid "I_nset" +msgstr "I_ntrudi" + +#: ../../po/../src/verbs.cpp:1972 +msgid "Inset selected paths" +msgstr "Intrude il tracciato selezionato" + +#: ../../po/../src/verbs.cpp:1974 +msgid "I_nset Path by 1 px" +msgstr "I_ntrudi Tracciato di 1px" + +#: ../../po/../src/verbs.cpp:1975 +msgid "Inset selected paths by 1 px" +msgstr "Intrude il tracciato selezionato di 1px" + +#: ../../po/../src/verbs.cpp:1977 +msgid "I_nset Path by 10 px" +msgstr "I_ntrudi Tracciato di 10px" + +#: ../../po/../src/verbs.cpp:1978 +msgid "Inset selected paths by 10 px" +msgstr "Intrude il tracciato selezionato di 10px" + +#: ../../po/../src/verbs.cpp:1980 +msgid "D_ynamic Offset" +msgstr "Proiezione dina_mica" + +#: ../../po/../src/verbs.cpp:1980 +msgid "Create a dynamic offset object" +msgstr "Crea una proiezione dinamica" + +#: ../../po/../src/verbs.cpp:1982 +msgid "_Linked Offset" +msgstr "Proiezione co_llegata" + +#: ../../po/../src/verbs.cpp:1983 +msgid "Create a dynamic offset object linked to the original path" +msgstr "Creata una proiezione dinamica del tracciato originale" + +#: ../../po/../src/verbs.cpp:1985 +msgid "_Stroke to Path" +msgstr "Da _linea a tracciato" + +#: ../../po/../src/verbs.cpp:1986 +msgid "Convert selected strokes to paths" +msgstr "Converte le linee selezionate in tracciati" + +#: ../../po/../src/verbs.cpp:1987 +msgid "Si_mplify" +msgstr "Se_mplifica" + +#: ../../po/../src/verbs.cpp:1988 +msgid "Simplify selected paths by removing extra nodes" +msgstr "Semplifica il tracciato selezionato rimuovendo nodi superflui" + +#: ../../po/../src/verbs.cpp:1989 +msgid "_Reverse" +msgstr "Inve_rti" + +#: ../../po/../src/verbs.cpp:1990 +msgid "Reverses the direction of selected paths; useful for flipping markers" +msgstr "Inverti la direzione del tracciato, utile per riflettere i terminatori" + +#. TRANSLATORS: "to trace" means "to convert a bitmap to vector graphics" (to vectorize) +#: ../../po/../src/verbs.cpp:1992 +msgid "_Trace Bitmap" +msgstr "Ve_ttorizza bitmap" + +#: ../../po/../src/verbs.cpp:1993 +msgid "Convert bitmap object to paths" +msgstr "Converte oggetti bitmap in tracciati" + +#: ../../po/../src/verbs.cpp:1994 +msgid "_Make a Bitmap Copy" +msgstr "Crea una copia bit_map" + +#: ../../po/../src/verbs.cpp:1995 +msgid "Export selection to a bitmap and insert it into document" +msgstr "Esporta la selezione come bitmap e la inserisce nel documento" + +#: ../../po/../src/verbs.cpp:1996 +msgid "_Combine" +msgstr "_Combina" + +#: ../../po/../src/verbs.cpp:1997 +msgid "Combine several paths into one" +msgstr "Combina diversi tracciati in uno unico" + +#. TRANSLATORS: "to cut a path" is not the same as "to break a path apart" - see the +#. Advanced tutorial for more info +#: ../../po/../src/verbs.cpp:2000 +msgid "Break _Apart" +msgstr "Sep_ara" + +#: ../../po/../src/verbs.cpp:2001 +msgid "Break selected paths into subpaths" +msgstr "Separa il tracciato selezionato in sotto-tracciati" + +#: ../../po/../src/verbs.cpp:2002 +msgid "Gri_d Arrange..." +msgstr "_Disposizione a griglia..." + +#: ../../po/../src/verbs.cpp:2003 +msgid "Arrange selection in grid pattern" +msgstr "Dispone la selezione su una griglia" + +#. Layer +#: ../../po/../src/verbs.cpp:2005 +msgid "_Add Layer..." +msgstr "_Aggiungi livello..." + +#: ../../po/../src/verbs.cpp:2006 +msgid "Create a new layer" +msgstr "Crea un nuovo livello" + +#: ../../po/../src/verbs.cpp:2007 +msgid "Re_name Layer..." +msgstr "Rinomi_na livello..." + +#: ../../po/../src/verbs.cpp:2008 +msgid "Rename the current layer" +msgstr "Rinomina il livello attuale" + +#: ../../po/../src/verbs.cpp:2009 +msgid "Switch to Layer Abov_e" +msgstr "Passa al livello superiore" + +#: ../../po/../src/verbs.cpp:2010 +msgid "Switch to the layer above the current" +msgstr "Passa al livello superiore all'attuale" + +#: ../../po/../src/verbs.cpp:2011 +msgid "Switch to Layer Belo_w" +msgstr "Passa al livello inferiore" + +#: ../../po/../src/verbs.cpp:2012 +msgid "Switch to the layer below the current" +msgstr "Passa al livello inferiore all'attuale" + +#: ../../po/../src/verbs.cpp:2013 +msgid "Move Selection to Layer Abo_ve" +msgstr "Sposta selezione al li_vello superiore" + +#: ../../po/../src/verbs.cpp:2014 +msgid "Move selection to the layer above the current" +msgstr "Sposta la selezione al livello superiore all'attuale" + +#: ../../po/../src/verbs.cpp:2015 +msgid "Move Selection to Layer Bel_ow" +msgstr "Sposta selezione al li_vello inferiore" + +#: ../../po/../src/verbs.cpp:2016 +msgid "Move selection to the layer below the current" +msgstr "Sposta la selezione al livello inferiore all'attuale" + +#: ../../po/../src/verbs.cpp:2017 +msgid "Layer to _Top" +msgstr "Spos_ta livello in cima" + +#: ../../po/../src/verbs.cpp:2018 +msgid "Raise the current layer to the top" +msgstr "Sposta il livello attuale in cima" + +#: ../../po/../src/verbs.cpp:2019 +msgid "Layer to _Bottom" +msgstr "Sposta livello in fon_do" + +#: ../../po/../src/verbs.cpp:2020 +msgid "Lower the current layer to the bottom" +msgstr "Sposta il livello attuale in fondo" + +#: ../../po/../src/verbs.cpp:2021 +msgid "_Raise Layer" +msgstr "Alza li_vello" + +#: ../../po/../src/verbs.cpp:2022 +msgid "Raise the current layer" +msgstr "Alza il livello attuale" + +#: ../../po/../src/verbs.cpp:2023 +msgid "_Lower Layer" +msgstr "Abbassa _livello" + +#: ../../po/../src/verbs.cpp:2024 +msgid "Lower the current layer" +msgstr "Abbassa il livello attuale" + +#: ../../po/../src/verbs.cpp:2025 +msgid "_Delete Current Layer" +msgstr "Elimina livello a_ttuale" + +#: ../../po/../src/verbs.cpp:2026 +msgid "Delete the current layer" +msgstr "Elimina il livello attuale" + +#. Object +#: ../../po/../src/verbs.cpp:2029 +#, fuzzy +msgid "Rotate _90° CW" +msgstr "Ruota _90° orari" + +#: ../../po/../src/verbs.cpp:2030 +#, fuzzy +msgid "Rotate selection 90° clockwise" +msgstr "Ruota la selezione di 90° orari" + +#: ../../po/../src/verbs.cpp:2031 +#, fuzzy +msgid "Rotate 9_0° CCW" +msgstr "Ruota 9_0° anti-orari" + +#: ../../po/../src/verbs.cpp:2032 +#, fuzzy +msgid "Rotate selection 90° counter-clockwise" +msgstr "Ruota la selezione di 90° anti-orari" + +#: ../../po/../src/verbs.cpp:2033 +msgid "Remove _Transformations" +msgstr "Rimuovi _trasformazioni" + +#: ../../po/../src/verbs.cpp:2034 +msgid "Remove transformations from object" +msgstr "Rimuove le trasformazioni dall'oggetto" + +#: ../../po/../src/verbs.cpp:2035 +msgid "_Object to Path" +msgstr "Da _oggetto a tracciato" + +#: ../../po/../src/verbs.cpp:2036 +msgid "Convert selected objects to paths" +msgstr "Converte in tracciati gli oggetti selezionati" + +#: ../../po/../src/verbs.cpp:2037 +msgid "_Flow into Frame" +msgstr "_Fluisci in struttura" + +#: ../../po/../src/verbs.cpp:2038 +msgid "Put text into frames" +msgstr "Mette il testo nella struttura" + +#: ../../po/../src/verbs.cpp:2039 +msgid "_Unflow" +msgstr "Spe_zza" + +#: ../../po/../src/verbs.cpp:2040 +msgid "Remove text from frame (creates a single-line text object)" +msgstr "" +"Rimuove il testo dalla struttura (crea un oggetto testuale su una riga)" + +#: ../../po/../src/verbs.cpp:2041 +msgid "_Convert to Text" +msgstr "_Converti in testo" + +#: ../../po/../src/verbs.cpp:2042 +msgid "Convert flowed text to regular text objects (preserves appearance)" +msgstr "" +"Converte in testo semplice il testo dinamico (mantiene le caratteristiche)" + +#: ../../po/../src/verbs.cpp:2044 +msgid "Flip _Horizontal" +msgstr "Rifletti _orizzontalmente" + +#: ../../po/../src/verbs.cpp:2044 +msgid "Flips selected objects horizontally" +msgstr "Riflette orizzontalmente gli oggetti selezionati" + +#: ../../po/../src/verbs.cpp:2047 +msgid "Flip _Vertical" +msgstr "Rifletti _verticalmente" + +#: ../../po/../src/verbs.cpp:2047 +msgid "Flips selected objects vertically" +msgstr "Riflette verticalmente gli oggetti selezionati" + +#. Tools +#: ../../po/../src/verbs.cpp:2051 +msgid "Select" +msgstr "Seleziona" + +#: ../../po/../src/verbs.cpp:2052 +msgid "Select and transform objects" +msgstr "Seleziona e trasforma oggetti" + +#: ../../po/../src/verbs.cpp:2053 +msgid "Node Edit" +msgstr "Modifica nodo" + +#: ../../po/../src/verbs.cpp:2054 +msgid "Edit path nodes or control handles" +msgstr "Modifica nodi del tracciato o maniglie di controllo" + +#: ../../po/../src/verbs.cpp:2056 +msgid "Create rectangles and squares" +msgstr "Crea rettangoli e quadrati" + +#: ../../po/../src/verbs.cpp:2058 +msgid "Create circles, ellipses, and arcs" +msgstr "Crea cerchi, ellissi e archi" + +#: ../../po/../src/verbs.cpp:2060 +msgid "Create stars and polygons" +msgstr "Crea stelle e poligoni" + +#: ../../po/../src/verbs.cpp:2062 +msgid "Create spirals" +msgstr "Crea spirali" + +#: ../../po/../src/verbs.cpp:2064 +msgid "Draw freehand lines" +msgstr "Disegna linee a mano libera" + +#: ../../po/../src/verbs.cpp:2066 +msgid "Draw Bezier curves and straight lines" +msgstr "Disegna tracciati e linee dritte" + +#: ../../po/../src/verbs.cpp:2068 +msgid "Draw calligraphic lines" +msgstr "Disegna linee calligrafiche" + +#: ../../po/../src/verbs.cpp:2070 +msgid "Create and edit text objects" +msgstr "Crea e modifica gli oggetti testuali" + +#: ../../po/../src/verbs.cpp:2072 +msgid "Create and edit gradients" +msgstr "Crea e modifica i gradienti" + +#: ../../po/../src/verbs.cpp:2074 +msgid "Zoom in or out" +msgstr "Ingrandisci o rimpicciolisci" + +#: ../../po/../src/verbs.cpp:2076 +msgid "Pick averaged colors from image" +msgstr "Preleva colore dall'immagine" + +#: ../../po/../src/verbs.cpp:2078 +msgid "Create connectors" +msgstr "Crea connettori" + +#. Tool prefs +#: ../../po/../src/verbs.cpp:2081 +msgid "Selector Preferences" +msgstr "Preferenze selettore" + +#: ../../po/../src/verbs.cpp:2082 +msgid "Open Preferences for the Selector tool" +msgstr "Apre le preferenze di Inkscape per lo strumento «Selettore»" + +#: ../../po/../src/verbs.cpp:2083 +msgid "Node Tool Preferences" +msgstr "Preferenze strumento nodo" + +#: ../../po/../src/verbs.cpp:2084 +msgid "Open Preferences for the Node tool" +msgstr "Apre le preferenze di Inkscape per lo strumento «Nodo»" + +#: ../../po/../src/verbs.cpp:2085 +msgid "Rectangle Preferences" +msgstr "Preferenze rettangolo" + +#: ../../po/../src/verbs.cpp:2086 +msgid "Open Preferences for the Rectangle tool" +msgstr "Apre le preferenze di Inkscape per lo strumento «Rettangolo»" + +#: ../../po/../src/verbs.cpp:2087 +msgid "Ellipse Preferences" +msgstr "Preferenze ellisse" + +#: ../../po/../src/verbs.cpp:2088 +msgid "Open Preferences for the Ellipse tool" +msgstr "Apre le preferenze di Inkscape per lo strumento «Ellisse»" + +#: ../../po/../src/verbs.cpp:2089 +msgid "Star Preferences" +msgstr "Preferenze stella" + +#: ../../po/../src/verbs.cpp:2090 +msgid "Open Preferences for the Star tool" +msgstr "Apre le preferenze di Inkscape per lo strumento «Stella»" + +#: ../../po/../src/verbs.cpp:2091 +msgid "Spiral Preferences" +msgstr "Preferenze spirale" + +#: ../../po/../src/verbs.cpp:2092 +msgid "Open Preferences for the Spiral tool" +msgstr "Apre le preferenze di Inkscape per lo strumento «Spirale»" + +#: ../../po/../src/verbs.cpp:2093 +msgid "Pencil Preferences" +msgstr "Preferenze matita" + +#: ../../po/../src/verbs.cpp:2094 +msgid "Open Preferences for the Pencil tool" +msgstr "Apre le preferenze di Inkscape per lo strumento «Matita»" + +#: ../../po/../src/verbs.cpp:2095 +msgid "Pen Preferences" +msgstr "Preferenze penna" + +#: ../../po/../src/verbs.cpp:2096 +msgid "Open Preferences for the Pen tool" +msgstr "Apre le preferenze di Inkscape per lo strumento «Penna»" + +#: ../../po/../src/verbs.cpp:2097 +msgid "Calligraphic Preferences" +msgstr "Preferenze pennino" + +#: ../../po/../src/verbs.cpp:2098 +msgid "Open Preferences for the Calligraphy tool" +msgstr "Apre le preferenze di Inkscape per lo strumento «Pennino»" + +#: ../../po/../src/verbs.cpp:2099 +msgid "Text Preferences" +msgstr "Preferenze testo" + +#: ../../po/../src/verbs.cpp:2100 +msgid "Open Preferences for the Text tool" +msgstr "Apre le preferenze di Inkscape per lo strumento «Testo»" + +#: ../../po/../src/verbs.cpp:2101 +msgid "Gradient Preferences" +msgstr "Preferenze gradiente" + +#: ../../po/../src/verbs.cpp:2102 +msgid "Open Preferences for the Gradient tool" +msgstr "Apre le preferenze di Inkscape per lo strumento «Gradiente»" + +#: ../../po/../src/verbs.cpp:2103 +msgid "Zoom Preferences" +msgstr "Preferenze ingranditore" + +#: ../../po/../src/verbs.cpp:2104 +msgid "Open Preferences for the Zoom tool" +msgstr "Apre le preferenze di Inkscape per lo strumento «Ingranditore»" + +#: ../../po/../src/verbs.cpp:2105 +msgid "Dropper Preferences" +msgstr "Preferenze contagocce" + +#: ../../po/../src/verbs.cpp:2106 +msgid "Open Preferences for the Dropper tool" +msgstr "Apre le preferenze di Inkscape per lo strumento «Contagocce»" + +# -Luca +#: ../../po/../src/verbs.cpp:2107 +msgid "Connector Preferences" +msgstr "Preferenze connettore" + +#: ../../po/../src/verbs.cpp:2108 +msgid "Open Preferences for the Connector tool" +msgstr "Apre le preferenze di Inkscape per lo strumento «Connettore»" + +#. Zoom/View +#: ../../po/../src/verbs.cpp:2111 +msgid "Zoom In" +msgstr "Ingrandisci" + +#: ../../po/../src/verbs.cpp:2111 +msgid "Zoom in" +msgstr "Aumenta l'ingrandimento" + +#: ../../po/../src/verbs.cpp:2112 +msgid "Zoom Out" +msgstr "Riduci" + +#: ../../po/../src/verbs.cpp:2112 +msgid "Zoom out" +msgstr "Riduce l'ingrandimento" + +#: ../../po/../src/verbs.cpp:2113 +msgid "_Rulers" +msgstr "_Righelli" + +#: ../../po/../src/verbs.cpp:2113 +msgid "Show or hide the canvas rulers" +msgstr "Mostra o nasconde i righelli" + +#: ../../po/../src/verbs.cpp:2114 +msgid "Scroll_bars" +msgstr "_Barre di Scorrimento" + +#: ../../po/../src/verbs.cpp:2114 +msgid "Show or hide the canvas scrollbars" +msgstr "Mostra o nasconde le barre di scorrimento" + +#: ../../po/../src/verbs.cpp:2115 +msgid "_Grid" +msgstr "_Griglia" + +#: ../../po/../src/verbs.cpp:2116 +msgid "G_uides" +msgstr "G_uide" + +#: ../../po/../src/verbs.cpp:2117 +msgid "Nex_t Zoom" +msgstr "Ingrandimen_to successivo" + +#: ../../po/../src/verbs.cpp:2117 +msgid "Next zoom (from the history of zooms)" +msgstr "Ingrandimento successivo (dalla cronologia degli zoom)" + +#: ../../po/../src/verbs.cpp:2119 +msgid "Pre_vious Zoom" +msgstr "Ingrandimento p_recedente" + +#: ../../po/../src/verbs.cpp:2119 +msgid "Previous zoom (from the history of zooms)" +msgstr "Ingrandimento precedente (dalla cronologia degli zoom)" + +#: ../../po/../src/verbs.cpp:2121 +msgid "Zoom 1:_1" +msgstr "Ingrandimento 1:_1" + +#: ../../po/../src/verbs.cpp:2121 +msgid "Zoom to 1:1" +msgstr "Ingrandisce a 1:1" + +#: ../../po/../src/verbs.cpp:2123 +msgid "Zoom 1:_2" +msgstr "Ingrandimento 1:_2" + +#: ../../po/../src/verbs.cpp:2123 +msgid "Zoom to 1:2" +msgstr "Ingrandisce a 1:2" + +#: ../../po/../src/verbs.cpp:2125 +msgid "_Zoom 2:1" +msgstr "In_grandimento 2:1" + +#: ../../po/../src/verbs.cpp:2125 +msgid "Zoom to 2:1" +msgstr "Ingrandisce a 2:1" + +#: ../../po/../src/verbs.cpp:2128 +msgid "_Fullscreen" +msgstr "Scher_mo intero" + +#: ../../po/../src/verbs.cpp:2128 +msgid "Stretch this document window to full screen" +msgstr "Allarga la finestra a pieno schermo" + +#: ../../po/../src/verbs.cpp:2131 +msgid "Duplic_ate Window" +msgstr "Duplic_a finestra" + +#: ../../po/../src/verbs.cpp:2131 +msgid "Open a new window with the same document" +msgstr "Apre lo stesso documento in una nuova finestra" + +#: ../../po/../src/verbs.cpp:2133 +msgid "_New View Preview" +msgstr "_Nuova vista anteprima" + +#: ../../po/../src/verbs.cpp:2134 +msgid "New View Preview" +msgstr "Nuova visualizzazione di anteprima" + +#. "view_new_preview" +#: ../../po/../src/verbs.cpp:2136 +#, fuzzy +msgid "_Normal" +msgstr "Normale" + +#: ../../po/../src/verbs.cpp:2137 +msgid "Switch to normal display mode" +msgstr "" + +#: ../../po/../src/verbs.cpp:2138 +#, fuzzy +msgid "_Outline" +msgstr "Riquadro" + +#: ../../po/../src/verbs.cpp:2139 +msgid "Switch to outline (wireframe) display mode" +msgstr "" + +#: ../../po/../src/verbs.cpp:2141 +msgid "Ico_n Preview" +msgstr "Anteprima ico_na" + +#: ../../po/../src/verbs.cpp:2142 +msgid "Open a window to preview items at different icon resolutions" +msgstr "" +"Apre una finestra per mostrare l'anteprima come icona a varie risoluzioni" + +#: ../../po/../src/verbs.cpp:2144 +msgid "Zoom to fit page in window" +msgstr "Ingrandisce per adattare la pagina alla finestra" + +#: ../../po/../src/verbs.cpp:2145 +msgid "Page _Width" +msgstr "Larg_hezza pagina" + +#: ../../po/../src/verbs.cpp:2146 +msgid "Zoom to fit page width in window" +msgstr "Ingrandisce per adattare la larghezza della pagina alla finestra" + +#: ../../po/../src/verbs.cpp:2148 +msgid "Zoom to fit drawing in window" +msgstr "Ingrandisce per adattare il disegno alla finestra" + +#: ../../po/../src/verbs.cpp:2150 +msgid "Zoom to fit selection in window" +msgstr "Ingrandisce per adattare la selezione alla finestra" + +#. Dialogs +#: ../../po/../src/verbs.cpp:2153 +msgid "In_kscape Preferences..." +msgstr "Preferenze di In_kscape..." + +#: ../../po/../src/verbs.cpp:2154 +msgid "Global Inkscape preferences" +msgstr "Preferenze globali di Inkscape" + +#: ../../po/../src/verbs.cpp:2155 +msgid "_Document Preferences..." +msgstr "Preferenze del _documento..." + +#: ../../po/../src/verbs.cpp:2156 +msgid "Preferences saved with the document" +msgstr "Preferenze salvate col documento" + +#: ../../po/../src/verbs.cpp:2157 +msgid "_Fill and Stroke..." +msgstr "Riem_pimento e contorni..." + +#: ../../po/../src/verbs.cpp:2158 +msgid "Fill and Stroke dialog" +msgstr "Sottofinestra per riempimento e contorni" + +#. TRANSLATORS: "Swatches" means: color samples +#: ../../po/../src/verbs.cpp:2160 +msgid "S_watches..." +msgstr "Campio_ni..." + +#: ../../po/../src/verbs.cpp:2161 +msgid "View color swatches" +msgstr "Mostra l'elenco dei campioni di colore" + +#: ../../po/../src/verbs.cpp:2162 +msgid "Transfor_m..." +msgstr "Trasfor_ma..." + +#: ../../po/../src/verbs.cpp:2163 +msgid "Transform dialog" +msgstr "Sottofinestra per trasformazioni" + +#: ../../po/../src/verbs.cpp:2164 +msgid "_Align and Distribute..." +msgstr "_Allinea e distribuisci..." + +#: ../../po/../src/verbs.cpp:2165 +msgid "Align and Distribute dialog" +msgstr "Sottofinestra per allineamento e distribuzione" + +#: ../../po/../src/verbs.cpp:2166 +msgid "_Text and Font..." +msgstr "_Testo e carattere..." + +#: ../../po/../src/verbs.cpp:2167 +msgid "Text and Font dialog" +msgstr "Sottofinestra per testo e carattere" + +#: ../../po/../src/verbs.cpp:2168 +msgid "_XML Editor..." +msgstr "Editor _XML..." + +#: ../../po/../src/verbs.cpp:2169 +msgid "XML Editor" +msgstr "Editor XML" + +#: ../../po/../src/verbs.cpp:2170 +msgid "_Find..." +msgstr "_Trova..." + +#: ../../po/../src/verbs.cpp:2171 +msgid "Find objects in document" +msgstr "Trova oggetti nel documento" + +#: ../../po/../src/verbs.cpp:2172 +msgid "_Messages..." +msgstr "_Messaggi..." + +#: ../../po/../src/verbs.cpp:2173 +msgid "View debug messages" +msgstr "Mostra i messaggi di debug" + +#: ../../po/../src/verbs.cpp:2174 +msgid "S_cripts..." +msgstr "S_cript..." + +#: ../../po/../src/verbs.cpp:2175 +msgid "Run scripts" +msgstr "Esegue gli script" + +#: ../../po/../src/verbs.cpp:2176 +msgid "Show/Hide D_ialogs" +msgstr "Mostra/Nascondi sottof_inestre" + +#: ../../po/../src/verbs.cpp:2177 +msgid "Show or hide all active dialogs" +msgstr "Mostra o nasconde tutte le sottofinestre attive" + +#. TRANSLATORS: "Tile clones" means: "Create tiled clones" +#: ../../po/../src/verbs.cpp:2179 +msgid "Tile clones..." +msgstr "Crea cloni in serie..." + +#: ../../po/../src/verbs.cpp:2180 +msgid "Create and arrange multiple clones of selection" +msgstr "Crea e modifica una serie di cloni della selezione" + +#: ../../po/../src/verbs.cpp:2181 +msgid "_Object Properties..." +msgstr "Proprietà _oggetto..." + +#: ../../po/../src/verbs.cpp:2182 +msgid "Object Properties dialog" +msgstr "Sottofinestra delle proprietà dell'oggetto" + +#: ../../po/../src/verbs.cpp:2185 +msgid "_Connect to Jabber server..." +msgstr "_Connetti a server Jabber..." + +#: ../../po/../src/verbs.cpp:2185 +msgid "Connect to a Jabber server" +msgstr "Connette ad un server Jabber" + +#: ../../po/../src/verbs.cpp:2187 +msgid "Share with _user..." +msgstr "Condividi con _utente..." + +#: ../../po/../src/verbs.cpp:2187 +msgid "Establish a whiteboard session with another Jabber user" +msgstr "Stabilisce una sessione whiteboard con una altro utente di Jabber" + +#: ../../po/../src/verbs.cpp:2189 +msgid "Share with _chatroom..." +msgstr "Condividi con _chatroom..." + +#: ../../po/../src/verbs.cpp:2189 +msgid "" +"Join a chatroom to start a new whiteboard session or join one in progress" +msgstr "" +"Collega ad una chatroom per avviare una nuova sessione whiteboard o per " +"unirsi ad una in corso" + +#: ../../po/../src/verbs.cpp:2191 +msgid "_Dump XML node tracker" +msgstr "_Riversa tracker node XML" + +#: ../../po/../src/verbs.cpp:2191 +msgid "Dump the contents of the XML tracker to the console" +msgstr "Riversa il contenuto del tracker XML sulla console" + +#: ../../po/../src/verbs.cpp:2193 +msgid "_Open session file..." +msgstr "_Apri file sessione..." + +#: ../../po/../src/verbs.cpp:2193 +msgid "Open and browse through records of past whiteboard sessions" +msgstr "Apre e esplora le registrazioni di sessioni whiteboard passate" + +#: ../../po/../src/verbs.cpp:2195 +msgid "Session file playback" +msgstr "Riproduzione file sessione" + +#: ../../po/../src/verbs.cpp:2197 +msgid "_Disconnect from session" +msgstr "_Disconnetti dalla sessione" + +#: ../../po/../src/verbs.cpp:2199 +msgid "Disconnect from _server" +msgstr "Disconnetti dal _server" + +#: ../../po/../src/verbs.cpp:2201 +msgid "_Input Devices..." +msgstr "Dispositivi di _input..." + +#: ../../po/../src/verbs.cpp:2202 +msgid "Configure extended input devices" +msgstr "Configura i dispositivi di input esteso" + +#. Help +#: ../../po/../src/verbs.cpp:2205 +msgid "_Keys and Mouse" +msgstr "Tasti e m_ouse" + +#: ../../po/../src/verbs.cpp:2206 +msgid "Key and mouse shortcuts reference" +msgstr "Guida alle scorciatoie col mouse e con la tastiera" + +#: ../../po/../src/verbs.cpp:2207 +msgid "About E_xtensions" +msgstr "Informazioni sulle e_stensioni" + +#: ../../po/../src/verbs.cpp:2208 +msgid "About Extensions..." +msgstr "Informazioni sulle estensioni..." + +#: ../../po/../src/verbs.cpp:2209 +msgid "About _Memory" +msgstr "Informazioni sulla _memoria" + +#: ../../po/../src/verbs.cpp:2210 +msgid "About Memory..." +msgstr "Informazioni sulla memoria..." + +#: ../../po/../src/verbs.cpp:2211 +msgid "_About Inkscape" +msgstr "Inform_azioni su Inkscape" + +#. "help_about" +#. new HelpVerb(SP_VERB_SHOW_LICENSE, "ShowLicense", N_("Modifying or Redistributing Inkscape"), +#. N_("Show license to modify and/or redistribute Inkscape: GNU GPL"), NULL), +#. Tutorials +#: ../../po/../src/verbs.cpp:2217 +msgid "Inkscape: _Basic" +msgstr "Inkscape: _Base" + +#: ../../po/../src/verbs.cpp:2218 +msgid "Getting started with Inkscape" +msgstr "Primi passi con Inkscape" + +#. "tutorial_basic" +#: ../../po/../src/verbs.cpp:2219 +msgid "Inkscape: _Shapes" +msgstr "Ink_scape: Forme" + +#: ../../po/../src/verbs.cpp:2220 +msgid "Using shape tools to create and edit shapes" +msgstr "Utilizzo gli strumenti per creare e moficare forme" + +#: ../../po/../src/verbs.cpp:2221 +msgid "Inkscape: _Advanced" +msgstr "Inkscape: _Avanzato" + +#: ../../po/../src/verbs.cpp:2222 +msgid "Advanced Inkscape topics" +msgstr "Lezioni avanzate su Inkscape" + +#. "tutorial_advanced" +#. TRANSLATORS: "to trace" means "to convert a bitmap to vector graphics" (to vectorize) +#: ../../po/../src/verbs.cpp:2224 +msgid "Inkscape: T_racing" +msgstr "Inkscape: Vetto_rizzazione" + +#: ../../po/../src/verbs.cpp:2225 +msgid "Using bitmap tracing" +msgstr "Utilizzo della vettorizzazione delle immagini" + +#. "tutorial_tracing" +#: ../../po/../src/verbs.cpp:2226 +msgid "Inkscape: _Calligraphy" +msgstr "Inks_cape: Pennino" + +#: ../../po/../src/verbs.cpp:2227 +msgid "Using the Calligraphy pen tool" +msgstr "Utilizzo del Pennino" + +#: ../../po/../src/verbs.cpp:2228 +msgid "_Elements of Design" +msgstr "_Elementi di grafica" + +#: ../../po/../src/verbs.cpp:2229 +msgid "Principles of design in the tutorial form" +msgstr "Principi di grafica" + +#. "tutorial_design" +#: ../../po/../src/verbs.cpp:2230 +msgid "_Tips and Tricks" +msgstr "_Trucchi" + +#: ../../po/../src/verbs.cpp:2231 +msgid "Miscellaneous tips and tricks" +msgstr "Trucchi vari" + +#. "tutorial_tips" +#. Effect +#: ../../po/../src/verbs.cpp:2234 +msgid "Previous Effect" +msgstr "Effetto Precedente" + +#: ../../po/../src/verbs.cpp:2235 +msgid "Repeat the last effect with the same settings" +msgstr "Ripete l'ultimo effetto con le stesse impostazioni" + +#. "tutorial_tips" +#: ../../po/../src/verbs.cpp:2236 +msgid "Previous Effect Settings..." +msgstr "Impostazioni effetto precedente..." + +#: ../../po/../src/verbs.cpp:2237 +msgid "Repeat the last effect with new settings" +msgstr "Ripete l'ultimo effetto con nuove impostazioni" + +#: ../../po/../src/widgets/dash-selector.cpp:106 +msgid "Dash pattern" +msgstr "Motivo del tratteggio" + +#: ../../po/../src/widgets/dash-selector.cpp:121 +msgid "Pattern offset" +msgstr "Spessore del motivo" + +#: ../../po/../src/widgets/desktop-widget.cpp:240 +msgid "Zoom drawing if window size changes" +msgstr "Aggiusta l'ingrandimento se cambia la dimensione della finestra" + +#: ../../po/../src/widgets/desktop-widget.cpp:298 +msgid "Cursor coordinates" +msgstr "Cordinate del cursore" + +#. display the initial welcome message in the statusbar +#: ../../po/../src/widgets/desktop-widget.cpp:324 +msgid "" +"Welcome to Inkscape! Use shape or freehand tools to create objects; " +"use selector (arrow) to move or transform them." +msgstr "" +"Benvenuti in Inkscape! Usare le forme o gli strumenti a mano libera " +"per creare gli oggetti; usare il selettore (freccia) per muoverli o " +"trasformarli." + +#: ../../po/../src/widgets/desktop-widget.cpp:372 +#, c-format +msgid "%s: %d - Inkscape" +msgstr "%s: %d - Inkscape" + +#: ../../po/../src/widgets/desktop-widget.cpp:374 +#, c-format +msgid "%s - Inkscape" +msgstr "%s - Inkscape" + +#: ../../po/../src/widgets/desktop-widget.cpp:532 +#, c-format +msgid "" +"Save changes to document \"%s\" before " +"closing?\n" +"\n" +"If you close without saving, your changes will be discarded." +msgstr "" +"Salvare i cambiamenti al documento \"%s" +"\" prima di chiudere?\n" +"\n" +"Chiudendo senza salvare, le modifiche verranno perse." + +#: ../../po/../src/widgets/desktop-widget.cpp:548 +#: ../../po/../src/widgets/desktop-widget.cpp:612 +msgid "Close _without saving" +msgstr "_Chiudi senza salvare" + +#: ../../po/../src/widgets/desktop-widget.cpp:595 +#, c-format +msgid "" +"The file \"%s\" was saved with a " +"format (%s) that may cause data loss!\n" +"\n" +"Do you want to save this file in another format?" +msgstr "" +"Il·file·\"%s\"·è stato salvato con un " +"formato (%s) che può provocare perdite di dati!\n" +"\n" +"Salvarlo con un altro formato?" + +#. Family frame +#: ../../po/../src/widgets/font-selector.cpp:156 +msgid "Font family" +msgstr "Carattere" + +#. Style frame +#: ../../po/../src/widgets/font-selector.cpp:184 +msgid "Style" +msgstr "Stile" + +#: ../../po/../src/widgets/font-selector.cpp:219 +msgid "Font size:" +msgstr "Dimensione carattere:" + +#. TRANSLATORS: Test string used in text and font dialog (when no +#. * text has been entered) to get a preview of the font. Choose +#. * some representative characters that users of your locale will be +#. * interested in. +#: ../../po/../src/widgets/font-selector.cpp:554 +msgid "AaBbCcIiPpQq12368.;/()" +msgstr "AaBbCcIiPpQq12368.;/()" + +#: ../../po/../src/widgets/gradient-selector.cpp:137 +#: ../../po/../src/widgets/gradient-toolbar.cpp:524 +msgid "Duplicate" +msgstr "Duplica" + +#: ../../po/../src/widgets/gradient-selector.cpp:142 +#: ../../po/../src/widgets/gradient-toolbar.cpp:535 +msgid "Edit..." +msgstr "Modifica..." + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/pservers.html#LinearGradientSpreadMethodAttribute +#: ../../po/../src/widgets/gradient-selector.cpp:159 +msgid "" +"Whether to fill with flat color beyond the ends of the gradient vector " +"(spreadMethod=\"pad\"), or repeat the gradient in the same direction " +"(spreadMethod=\"repeat\"), or repeat the gradient in alternating opposite " +"directions (spreadMethod=\"reflect\")" +msgstr "" +"Determina se riempire dopo la fine del gradiente con un colore unico " +"(spreadMethod=\"pad\"), ripetere il gradiente nella stessa direzione " +"(spreadMethod=\"repeat\") o ripetere il gradiente nella direzione opposta " +"(spreadMethod=\"reflect\")" + +#: ../../po/../src/widgets/gradient-selector.cpp:165 +msgid "none" +msgstr "nessuna" + +#: ../../po/../src/widgets/gradient-selector.cpp:169 +msgid "reflected" +msgstr "riflessa" + +#: ../../po/../src/widgets/gradient-selector.cpp:173 +msgid "direct" +msgstr "diretta" + +#: ../../po/../src/widgets/gradient-selector.cpp:181 +msgid "Repeat:" +msgstr "Ripetizione:" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:217 +msgid "No gradients" +msgstr "Nessun gradiente" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:226 +msgid "Nothing selected" +msgstr "Nessuna selezione" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:237 +msgid "No gradients in selection" +msgstr "Nessun gradiente selezionato" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:247 +msgid "Multiple gradients" +msgstr "Gradienti multipli" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:525 +msgid "" +"If the gradient is used by more than one object, create a copy of it for the " +"selected object(s)" +msgstr "" +"Se il gradiente è usato da più di un oggetto, ne crea una copia per " +"l'oggetto selezionato" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:536 +msgid "Edit the stops of the gradient" +msgstr "Modifica i passaggi del gradiente" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:593 +#: ../../po/../src/widgets/toolbox.cpp:1103 +#: ../../po/../src/widgets/toolbox.cpp:1192 +#: ../../po/../src/widgets/toolbox.cpp:1485 +#: ../../po/../src/widgets/toolbox.cpp:1534 +#: ../../po/../src/widgets/toolbox.cpp:1766 +#: ../../po/../src/widgets/toolbox.cpp:1801 +#: ../../po/../src/widgets/toolbox.cpp:2331 +#: ../../po/../src/widgets/toolbox.cpp:2370 +msgid "New:" +msgstr "Nuovo:" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:606 +msgid "Create linear gradient" +msgstr "Crea gradiente lineare" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:620 +msgid "Create radial (elliptic or circular) gradient" +msgstr "Crea un gradiente radiale (ellittico o circolare)" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:635 +msgid "on" +msgstr "abilitato" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:648 +msgid "Create gradient in the fill" +msgstr "Crea gradiente per il riempimento" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:662 +msgid "Create gradient in the stroke" +msgstr "Crea gradiente per i contorni" + +#. FIXME: implement averaging of all parameters for multiple selected stars +#. gtk_label_set_markup(GTK_LABEL(l), _("Average:")); +#. FIXME: implement averaging of all parameters for multiple selected +#. gtk_label_set_markup(GTK_LABEL(l), _("Average:")); +#: ../../po/../src/widgets/gradient-toolbar.cpp:676 +#: ../../po/../src/widgets/toolbox.cpp:1105 +#: ../../po/../src/widgets/toolbox.cpp:1124 +#: ../../po/../src/widgets/toolbox.cpp:1493 +#: ../../po/../src/widgets/toolbox.cpp:1518 +#: ../../po/../src/widgets/toolbox.cpp:1768 +#: ../../po/../src/widgets/toolbox.cpp:1787 +#: ../../po/../src/widgets/toolbox.cpp:2334 +#: ../../po/../src/widgets/toolbox.cpp:2354 +msgid "Change:" +msgstr "Cambia:" + +#: ../../po/../src/widgets/gradient-vector.cpp:269 +msgid "No gradients in document" +msgstr "Nessun gradiente nel documento" + +#: ../../po/../src/widgets/gradient-vector.cpp:275 +msgid "No gradient selected" +msgstr "Nessun gradiente selezionato" + +#: ../../po/../src/widgets/gradient-vector.cpp:532 +msgid "No stops in gradient" +msgstr "Nessun passaggio nel gradiente" + +#. TRANSLATORS: "Stop" means: a "phase" of a gradient +#: ../../po/../src/widgets/gradient-vector.cpp:794 +msgid "Add stop" +msgstr "Aggiungi passaggio" + +#: ../../po/../src/widgets/gradient-vector.cpp:797 +msgid "Add another control stop to gradient" +msgstr "Aggiunge un altro passaggio al gradiente" + +#: ../../po/../src/widgets/gradient-vector.cpp:799 +msgid "Delete stop" +msgstr "Cancella passaggio" + +#: ../../po/../src/widgets/gradient-vector.cpp:802 +msgid "Delete current control stop from gradient" +msgstr "Elimina il passaggio corrente dal gradiente" + +#. Label +#: ../../po/../src/widgets/gradient-vector.cpp:813 +msgid "Offset:" +msgstr "Opacità:" + +#. TRANSLATORS: "Stop" means: a "phase" of a gradient +#: ../../po/../src/widgets/gradient-vector.cpp:858 +msgid "Stop Color" +msgstr "Colore del passaggio" + +#: ../../po/../src/widgets/gradient-vector.cpp:887 +msgid "Gradient editor" +msgstr "Editor di gradiente" + +#: ../../po/../src/widgets/layer-selector.cpp:119 +msgid "Toggle current layer visibility" +msgstr "Imposta la visibilità del livello attuale" + +#: ../../po/../src/widgets/layer-selector.cpp:139 +msgid "Lock or unlock current layer" +msgstr "Blocca o sblocca il livello attuale" + +#: ../../po/../src/widgets/layer-selector.cpp:142 +msgid "Current layer" +msgstr "Livello attuale" + +#: ../../po/../src/widgets/layer-selector.cpp:553 +msgid "(root)" +msgstr "(root)" + +#: ../../po/../src/widgets/paint-selector.cpp:182 +#: ../../po/../src/widgets/paint-selector.cpp:561 +msgid "No paint" +msgstr "Nessun colore" + +#: ../../po/../src/widgets/paint-selector.cpp:184 +#: ../../po/../src/widgets/paint-selector.cpp:629 +msgid "Flat color" +msgstr "Colore unico" + +#: ../../po/../src/widgets/paint-selector.cpp:186 +#: ../../po/../src/widgets/paint-selector.cpp:696 +msgid "Linear gradient" +msgstr "Gradiente lineare" + +#: ../../po/../src/widgets/paint-selector.cpp:188 +#: ../../po/../src/widgets/paint-selector.cpp:699 +msgid "Radial gradient" +msgstr "Gradiente radiale" + +#: ../../po/../src/widgets/paint-selector.cpp:192 +msgid "Unset paint (make it undefined so it can be inherited)" +msgstr "Disattiva riempimento (affinché possa essere ereditato)" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/painting.html#FillRuleProperty +#: ../../po/../src/widgets/paint-selector.cpp:204 +msgid "" +"Any path self-intersections or subpaths create holes in the fill (fill-rule: " +"evenodd)" +msgstr "" +"Qualsiasi autointersezione del tracciato o sottotracciati crea vuoti nel " +"riempimento (fill-rule:evenodd)" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/painting.html#FillRuleProperty +#: ../../po/../src/widgets/paint-selector.cpp:215 +msgid "" +"Fill is solid unless a subpath is counterdirectional (fill-rule: nonzero)" +msgstr "" +"Il riempimento è intero a meno che un sottotracciato sia in direzione " +"opposta (fill-rule: nonzero)" + +#: ../../po/../src/widgets/paint-selector.cpp:528 +msgid "No objects" +msgstr "Nessun oggetto" + +#: ../../po/../src/widgets/paint-selector.cpp:539 +msgid "Multiple styles" +msgstr "Stili multipli" + +#: ../../po/../src/widgets/paint-selector.cpp:550 +msgid "Paint is undefined" +msgstr "Il riempimento non è definito" + +#: ../../po/../src/widgets/paint-selector.cpp:757 +msgid "No patterns in document" +msgstr "Nessun motivo nel documento" + +#: ../../po/../src/widgets/paint-selector.cpp:872 +msgid "" +"Use Edit > Object(s) to Pattern to create a new pattern from " +"selection." +msgstr "" +"Usare Modifca > Da oggetto a motivo per creare un nuovo motivo " +"dalla selezione" + +#: ../../po/../src/widgets/select-toolbar.cpp:426 +msgid "Now stroke width is scaled when objects are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:428 +msgid "Now stroke width is not scaled when objects are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:436 +msgid "" +"Now rounded rectangle corners are scaled when rectangles are " +"scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:438 +msgid "" +"Now rounded rectangle corners are not scaled when rectangles " +"are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:446 +msgid "" +"Now gradients are transformed along with their objects when " +"those are transformed (moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:448 +msgid "" +"Now gradients remain fixed when objects are transformed " +"(moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:456 +msgid "" +"Now patterns are transformed along with their objects when " +"those are transformed (moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:458 +msgid "" +"Now patterns remain fixed when objects are transformed (moved, " +"scaled, rotated, or skewed)." +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:506 +msgid "select_toolbar|X" +msgstr "X" + +#: ../../po/../src/widgets/select-toolbar.cpp:506 +msgid "Horizontal coordinate of selection" +msgstr "Coordinate orizzontali della selezione" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:511 +msgid "select_toolbar|Y" +msgstr "Y" + +#: ../../po/../src/widgets/select-toolbar.cpp:511 +msgid "Vertical coordinate of selection" +msgstr "Cordinate verticali della selezione" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:517 +msgid "select_toolbar|W" +msgstr "W" + +#: ../../po/../src/widgets/select-toolbar.cpp:517 +msgid "Width of selection" +msgstr "Larghezza della selezione" + +#: ../../po/../src/widgets/select-toolbar.cpp:525 +msgid "Change both width and height by the same proportion" +msgstr "Cambia l'altezza e la larghezza della selezione in proporzione" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:534 +msgid "select_toolbar|H" +msgstr "H" + +#: ../../po/../src/widgets/select-toolbar.cpp:534 +msgid "Height of selection" +msgstr "Altezza della selezione" + +#: ../../po/../src/widgets/sp-color-gtkselector.cpp:62 +msgid "System" +msgstr "Sistema" + +#: ../../po/../src/widgets/sp-color-notebook.cpp:322 +msgid "RGBA_:" +msgstr "RGBA_:" + +#: ../../po/../src/widgets/sp-color-notebook.cpp:330 +msgid "Hexadecimal RGBA value of the color" +msgstr "Valore RGBA esadecimale del colore" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "RGB" +msgstr "RGB" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "HSL" +msgstr "HSL" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "CMYK" +msgstr "CMYK" + +#: ../../po/../src/widgets/sp-color-scales.cpp:397 +msgid "_R" +msgstr "_R" + +#: ../../po/../src/widgets/sp-color-scales.cpp:398 +#: ../../po/../src/widgets/sp-color-scales.cpp:399 +msgid "Red" +msgstr "Rosso" + +#: ../../po/../src/widgets/sp-color-scales.cpp:400 +msgid "_G" +msgstr "_G" + +#: ../../po/../src/widgets/sp-color-scales.cpp:401 +#: ../../po/../src/widgets/sp-color-scales.cpp:402 +msgid "Green" +msgstr "Verde" + +#: ../../po/../src/widgets/sp-color-scales.cpp:403 +msgid "_B" +msgstr "_B" + +#: ../../po/../src/widgets/sp-color-scales.cpp:404 +#: ../../po/../src/widgets/sp-color-scales.cpp:405 +msgid "Blue" +msgstr "Blu" + +#. Label +#: ../../po/../src/widgets/sp-color-scales.cpp:406 +#: ../../po/../src/widgets/sp-color-scales.cpp:432 +#: ../../po/../src/widgets/sp-color-scales.cpp:463 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:141 +msgid "_A" +msgstr "_A" + +#: ../../po/../src/widgets/sp-color-scales.cpp:407 +#: ../../po/../src/widgets/sp-color-scales.cpp:408 +#: ../../po/../src/widgets/sp-color-scales.cpp:433 +#: ../../po/../src/widgets/sp-color-scales.cpp:434 +#: ../../po/../src/widgets/sp-color-scales.cpp:464 +#: ../../po/../src/widgets/sp-color-scales.cpp:465 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:151 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:163 +msgid "Alpha (opacity)" +msgstr "Alpha (opacità)" + +#: ../../po/../src/widgets/sp-color-scales.cpp:423 +msgid "_H" +msgstr "_H" + +#: ../../po/../src/widgets/sp-color-scales.cpp:424 +#: ../../po/../src/widgets/sp-color-scales.cpp:425 +msgid "Hue" +msgstr "Colore" + +#: ../../po/../src/widgets/sp-color-scales.cpp:426 +msgid "_S" +msgstr "_S" + +#: ../../po/../src/widgets/sp-color-scales.cpp:427 +#: ../../po/../src/widgets/sp-color-scales.cpp:428 +msgid "Saturation" +msgstr "Saturazione" + +#: ../../po/../src/widgets/sp-color-scales.cpp:429 +msgid "_L" +msgstr "_L" + +#: ../../po/../src/widgets/sp-color-scales.cpp:430 +#: ../../po/../src/widgets/sp-color-scales.cpp:431 +msgid "Lightness" +msgstr "Luminosità" + +#: ../../po/../src/widgets/sp-color-scales.cpp:451 +msgid "_C" +msgstr "_C" + +#: ../../po/../src/widgets/sp-color-scales.cpp:452 +#: ../../po/../src/widgets/sp-color-scales.cpp:453 +msgid "Cyan" +msgstr "Cyan" + +#: ../../po/../src/widgets/sp-color-scales.cpp:454 +msgid "_M" +msgstr "_M" + +#: ../../po/../src/widgets/sp-color-scales.cpp:455 +#: ../../po/../src/widgets/sp-color-scales.cpp:456 +msgid "Magenta" +msgstr "Magenta" + +#: ../../po/../src/widgets/sp-color-scales.cpp:457 +msgid "_Y" +msgstr "_Y" + +#: ../../po/../src/widgets/sp-color-scales.cpp:458 +#: ../../po/../src/widgets/sp-color-scales.cpp:459 +msgid "Yellow" +msgstr "Giallo" + +#: ../../po/../src/widgets/sp-color-scales.cpp:460 +msgid "_K" +msgstr "_K" + +#: ../../po/../src/widgets/sp-color-selector.cpp:71 +msgid "Unnamed" +msgstr "Senza nome" + +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:68 +msgid "Wheel" +msgstr "Ruota" + +#: ../../po/../src/widgets/sp-xmlview-attr-list.cpp:53 +msgid "Attribute" +msgstr "Attributo" + +#: ../../po/../src/widgets/sp-xmlview-attr-list.cpp:54 +msgid "Value" +msgstr "Valore" + +#: ../../po/../src/widgets/toolbox.cpp:424 +msgid "Insert new nodes into selected segments" +msgstr "Inserisce nuovi nodi nel segmento selezionato" + +#: ../../po/../src/widgets/toolbox.cpp:426 +msgid "Delete selected nodes" +msgstr "Elimina i nodi selezionati" + +#: ../../po/../src/widgets/toolbox.cpp:431 +msgid "Join paths at selected nodes" +msgstr "Unisce i tracciati nei nodi selezionati" + +#: ../../po/../src/widgets/toolbox.cpp:433 +msgid "Join paths at selected nodes with new segment" +msgstr "Unisce i tracciati nei nodi selezionati con un nuovo segmento" + +#: ../../po/../src/widgets/toolbox.cpp:436 +msgid "Split path between two non-endpoint nodes" +msgstr "Divide il tracciato tra due nodi non finali" + +#: ../../po/../src/widgets/toolbox.cpp:439 +msgid "Break path at selected nodes" +msgstr "Separa il percorso nel nodo selezionato" + +#: ../../po/../src/widgets/toolbox.cpp:444 +msgid "Make selected nodes corner" +msgstr "Rende angolari i nodi selezionati" + +#: ../../po/../src/widgets/toolbox.cpp:447 +msgid "Make selected nodes smooth" +msgstr "Rende curvilinei i nodi selezionati" + +#: ../../po/../src/widgets/toolbox.cpp:450 +msgid "Make selected nodes symmetric" +msgstr "Rende simmetrici i nodi selezionati" + +#: ../../po/../src/widgets/toolbox.cpp:455 +msgid "Make selected segments lines" +msgstr "Trasforma in linee i segmenti selezionati" + +#: ../../po/../src/widgets/toolbox.cpp:458 +msgid "Make selected segments curves" +msgstr "Trasforma in curve i segmenti selezionati" + +#: ../../po/../src/widgets/toolbox.cpp:1199 +msgid "Polygon" +msgstr "Poligono" + +#: ../../po/../src/widgets/toolbox.cpp:1206 +msgid "Regular polygon (with one handle) instead of a star" +msgstr "Poligono regolare (con una maniglia) invece di una stella" + +#: ../../po/../src/widgets/toolbox.cpp:1218 +msgid "Corners:" +msgstr "Angoli:" + +#: ../../po/../src/widgets/toolbox.cpp:1218 +msgid "Number of corners of a polygon or star" +msgstr "Numero di angoli di un poligono o di una stella" + +#: ../../po/../src/widgets/toolbox.cpp:1228 +msgid "Spoke ratio:" +msgstr "Rapporto raggio:" + +#. TRANSLATORS: Tip radius of a star is the distance from the center to the farthest handle. +#. Base radius is the same for the closest handle. +#: ../../po/../src/widgets/toolbox.cpp:1231 +msgid "Base radius to tip radius ratio" +msgstr "Rapporto tra diametro e diametro interno" + +#: ../../po/../src/widgets/toolbox.cpp:1246 +msgid "Rounded:" +msgstr "Arrotondamento:" + +#: ../../po/../src/widgets/toolbox.cpp:1246 +msgid "How much rounded are the corners (0 for sharp)" +msgstr "Il grado di arrotondamento degli angoli (0 per gli spigoli)" + +#: ../../po/../src/widgets/toolbox.cpp:1256 +msgid "Randomized:" +msgstr "Casualità:" + +#: ../../po/../src/widgets/toolbox.cpp:1256 +msgid "Scatter randomly the corners and angles" +msgstr "Separa casualmente gli angoli" + +#: ../../po/../src/widgets/toolbox.cpp:1269 +#: ../../po/../src/widgets/toolbox.cpp:1838 +#: ../../po/../src/widgets/toolbox.cpp:2061 +msgid "Defaults" +msgstr "Predefiniti" + +#: ../../po/../src/widgets/toolbox.cpp:1270 +#: ../../po/../src/widgets/toolbox.cpp:1839 +#: ../../po/../src/widgets/toolbox.cpp:2062 +msgid "" +"Reset shape parameters to defaults (use Inkscape Preferences > Tools to " +"change defaults)" +msgstr "" +"Reimposta i parametri delle forma ai valori predefiniti (usare Preferenze di " +"Inkscape > Strumenti per cambiare i valori predefiniti)" + +#: ../../po/../src/widgets/toolbox.cpp:1544 +msgid "W:" +msgstr "L:" + +#: ../../po/../src/widgets/toolbox.cpp:1544 +msgid "Width of rectangle" +msgstr "Larghezza del rettangolo" + +#: ../../po/../src/widgets/toolbox.cpp:1556 +msgid "Height of rectangle" +msgstr "Altezza del rettangolo" + +#: ../../po/../src/widgets/toolbox.cpp:1568 +msgid "Rx:" +msgstr "Rx:" + +#: ../../po/../src/widgets/toolbox.cpp:1568 +msgid "Horizontal radius of rounded corners" +msgstr "Raggio orizzontale di un angolo arrotondato" + +#: ../../po/../src/widgets/toolbox.cpp:1578 +msgid "Ry:" +msgstr "Ry:" + +#: ../../po/../src/widgets/toolbox.cpp:1578 +msgid "Vertical radius of rounded corners" +msgstr "Raggio verticale di un angolo arrotondato" + +#: ../../po/../src/widgets/toolbox.cpp:1594 +msgid "Not rounded" +msgstr "Non arrotondato" + +#: ../../po/../src/widgets/toolbox.cpp:1596 +msgid "Make corners sharp" +msgstr "Rende gli angoli spigolosi" + +#: ../../po/../src/widgets/toolbox.cpp:1805 +msgid "Turns:" +msgstr "Rivoluzioni:" + +#: ../../po/../src/widgets/toolbox.cpp:1805 +msgid "Number of revolutions" +msgstr "Numero di rivoluzioni" + +#: ../../po/../src/widgets/toolbox.cpp:1815 +msgid "Divergence:" +msgstr "Divergenza:" + +#: ../../po/../src/widgets/toolbox.cpp:1815 +msgid "How much denser/sparser are outer revolutions; 1 = uniform" +msgstr "La densità delle rivoluzioni esterne; 1 = uniformi" + +#: ../../po/../src/widgets/toolbox.cpp:1825 +msgid "Inner radius:" +msgstr "Radiale interno:" + +#: ../../po/../src/widgets/toolbox.cpp:1825 +msgid "Radius of the innermost revolution (relative to the spiral size)" +msgstr "" +"Il radiale delle rivoluzioni più interne (relativo alle dimensioni della " +"spirale)" + +#: ../../po/../src/widgets/toolbox.cpp:1957 +msgid "The width of the calligraphic pen (relative to the visible canvas area)" +msgstr "La larghezza del pennino (realtiva all'area visibile)" + +#: ../../po/../src/widgets/toolbox.cpp:1967 +msgid "Thinning:" +msgstr "Diradamento:" + +#: ../../po/../src/widgets/toolbox.cpp:1967 +msgid "" +"How much velocity thins the stroke (> 0 makes fast strokes thinner, < 0 " +"makes them broader, 0 makes width independent of velocity)" +msgstr "" +"La velocità di diradamento del contorno (> 0 tratti più netti, < 0 tratti " +"più larghi; 0 la larghezza è indipendente dalla velocità)" + +#: ../../po/../src/widgets/toolbox.cpp:1980 +msgid "Angle:" +msgstr "Angolo:" + +#: ../../po/../src/widgets/toolbox.cpp:1980 +msgid "" +"The angle of the pen's nib (in degrees; 0 = horizontal; has no effect if " +"fixation = 0)" +msgstr "" +"L'angolazione della penna (in gradi; 0 = orizzontale; non ha effetto se " + +#: ../../po/../src/widgets/toolbox.cpp:1990 +msgid "Fixation:" +msgstr "Fissaggio:" + +#: ../../po/../src/widgets/toolbox.cpp:1990 +msgid "" +"How fixed is the pen angle (0 = always perpendicular to stroke direction, 1 " +"= fixed)" +msgstr "" +"L'angolo di fissaggio della penna (0 = sempre perpendicolare alla direzione, " +"1 = fisso)" + +#: ../../po/../src/widgets/toolbox.cpp:2003 +msgid "Mass:" +msgstr "Massa:" + +#: ../../po/../src/widgets/toolbox.cpp:2003 +msgid "How much inertia affects the movement of the pen" +msgstr "L'inerzia del movimeto della penna" + +#. TRANSLATORS: "drag" means "resistance" here +#: ../../po/../src/widgets/toolbox.cpp:2014 +msgid "Drag:" +msgstr "Resistenza:" + +#: ../../po/../src/widgets/toolbox.cpp:2014 +msgid "How much resistance affects the movement of the pen" +msgstr "La resistenza al movimento della penna" + +#: ../../po/../src/widgets/toolbox.cpp:2034 +msgid "Use the pressure of the input device to alter the width of the pen" +msgstr "" +"Usare la pressione del dispositivo di input per alterare la larghezza della " +"penna" + +#: ../../po/../src/widgets/toolbox.cpp:2047 +msgid "Use the tilt of the input device to alter the angle of the pen's nib" +msgstr "" +"Usare l'inclinazione della dispositivo di input per alterare l'angolo della " +"punta della penna" + +#: ../../po/../src/widgets/toolbox.cpp:2374 +msgid "Start:" +msgstr "Inizio:" + +#: ../../po/../src/widgets/toolbox.cpp:2374 +msgid "The angle (in degrees) from the horizontal to the arc's start point" +msgstr "L'angolo (in gradi) tra l'orizzontale e il punto iniziale dell'arco" + +#: ../../po/../src/widgets/toolbox.cpp:2384 +msgid "End:" +msgstr "Fine:" + +#: ../../po/../src/widgets/toolbox.cpp:2384 +msgid "The angle (in degrees) from the horizontal to the arc's end point" +msgstr "L'angolo (in gradi) tra l'orizzontale e il punto iniziale dell'arco" + +#: ../../po/../src/widgets/toolbox.cpp:2395 +msgid "Open arc" +msgstr "Apri arco" + +#: ../../po/../src/widgets/toolbox.cpp:2396 +msgid "" +"Switch between arc (unclosed shape) and segment (closed shape with two radii)" +msgstr "" +"Commuta tra arco (forma aperta) e segmento (forma chiusa con due radiali)" + +#: ../../po/../src/widgets/toolbox.cpp:2415 +msgid "Make whole" +msgstr "Rendi intero" + +#: ../../po/../src/widgets/toolbox.cpp:2417 +msgid "Make the shape a whole ellipse, not arc or segment" +msgstr "Rende la forma in un ellisse intero, non un arco o un segmento" + +#: ../../po/../src/widgets/toolbox.cpp:2644 +msgid "" +"When pressed, picks visible color without alpha and when not pressed, picks " +"color including its alpha" +msgstr "" +"Quando abilitato preleva il colore senza la trasparenza; quando abilitato " +"preleva il colore compresa la trasparenza" + +#: ../../po/../src/widgets/toolbox.cpp:3039 +msgid "Make connectors avoid selected objects" +msgstr "Fa sì che i connettori evitino gli oggetti selezionati" + +#: ../../po/../src/widgets/toolbox.cpp:3043 +msgid "Make connectors ignore selected objects" +msgstr "Fa sì che i connettori ignorino gli oggetti selezionati" + +#. +#. 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 : +#: ../share/extensions/addnodes.inx.h:1 +#, fuzzy +msgid "Add Nodes" +msgstr "Nodi" + +#: ../share/extensions/addnodes.inx.h:2 +msgid "Maximum Segment Length" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:1 +msgid "AI Input" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:2 ../share/extensions/ai_output.inx.h:2 +msgid "Adobe Illustrator (*.ai)" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:3 +msgid "Open files saved with Adobe Illustrator" +msgstr "" + +#: ../share/extensions/ai_output.inx.h:1 +#, fuzzy +msgid "AI Output" +msgstr "Output" + +#: ../share/extensions/ai_output.inx.h:3 +msgid "Write Adobe Illustrator" +msgstr "" + +#: ../share/extensions/dia.inx.h:1 +msgid "A diagram created with the program Dia" +msgstr "" + +#: ../share/extensions/dia.inx.h:2 +msgid "Dia Diagram (*.dia)" +msgstr "" + +#: ../share/extensions/dia.inx.h:3 +msgid "Dia Input" +msgstr "" + +#: ../share/extensions/dia.inx.h:4 +msgid "" +"In order to import Dia files, Dia itself must be installed. You can get Dia " +"at http://www.gnome.org/projects/dia/" +msgstr "" + +#: ../share/extensions/dia.inx.h:5 +msgid "" +"The dia2svg.sh script should be installed with your Inkscape distribution. " +"If you do not have it, there is likely to be something wrong with your " +"Inkscape installation." +msgstr "" + +#: ../share/extensions/dots.inx.h:1 +#, fuzzy +msgid "Connect the Dots" +msgstr "Connettore" + +#: ../share/extensions/dots.inx.h:2 +#, fuzzy +msgid "Dot Size" +msgstr "Dimensione" + +#: ../share/extensions/dots.inx.h:3 +#, fuzzy +msgid "Font Size" +msgstr "Dimensione carattere:" + +#: ../share/extensions/dropshadow.inx.h:1 +msgid "Color of shadow" +msgstr "" + +#: ../share/extensions/dropshadow.inx.h:2 +#, fuzzy +msgid "Dropshadow" +msgstr "Mostra l'ombra della pagina" + +#: ../share/extensions/dxf_input.inx.h:1 +#: ../share/extensions/dxf_output.inx.h:1 +msgid "AutoCAD DXF (*.dxf)" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:2 +msgid "DXF Input" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:3 +msgid "Import AutoCAD's Document Exchange Format" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:4 +msgid "" +"dxf2svg may come with Inkscape, but is also at http://dxf-svg-convert." +"sourceforge.net/" +msgstr "" + +#: ../share/extensions/dxf_output.inx.h:2 +#, fuzzy +msgid "DXF Output" +msgstr "Output" + +#: ../share/extensions/dxf_output.inx.h:3 +msgid "DXF file written by pstoedit" +msgstr "" + +#: ../share/extensions/dxf_output.inx.h:4 +msgid "pstoedit must be installed to run see http://www.pstoedit.net/pstoedit" +msgstr "" + +#: ../share/extensions/embedimage.inx.h:1 +#, fuzzy +msgid "Embed Images" +msgstr "Immagini" + +#: ../share/extensions/eps_input.inx.h:1 +msgid "EPS Input" +msgstr "" + +#: ../share/extensions/eps_input.inx.h:2 +msgid "Encapsulated Postscript" +msgstr "" + +#: ../share/extensions/eps_input.inx.h:3 +msgid "Encapsulated Postscript (*.eps)" +msgstr "" + +#: ../share/extensions/epsi_output.inx.h:1 +#, fuzzy +msgid "EPSI Output" +msgstr "Output" + +#: ../share/extensions/epsi_output.inx.h:2 +msgid "Encapsulated Postscript Interchange (*.epsi)" +msgstr "" + +#: ../share/extensions/epsi_output.inx.h:3 +msgid "Encapsulated Postscript with a thumbnail" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:1 ../share/extensions/ffms.inx.h:1 +#: ../share/extensions/ffset.inx.h:1 ../share/extensions/ffss.inx.h:1 +#, fuzzy +msgid "Bridge Width" +msgstr "Larghezza linea" + +#: ../share/extensions/ffmet.inx.h:2 ../share/extensions/ffms.inx.h:2 +msgid "First String Length" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:3 +msgid "FretFind Multi Length ET" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:4 ../share/extensions/ffms.inx.h:4 +#: ../share/extensions/ffset.inx.h:3 ../share/extensions/ffss.inx.h:3 +msgid "Fretboard Edges" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:5 ../share/extensions/ffms.inx.h:5 +msgid "Last String Length" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:6 ../share/extensions/ffms.inx.h:6 +#: ../share/extensions/ffset.inx.h:4 ../share/extensions/ffss.inx.h:4 +#, fuzzy +msgid "Number of Frets" +msgstr "Numero di righe" + +#: ../share/extensions/ffmet.inx.h:7 ../share/extensions/ffms.inx.h:7 +#: ../share/extensions/ffset.inx.h:5 ../share/extensions/ffss.inx.h:5 +#, fuzzy +msgid "Number of Strings" +msgstr "Numero di righe" + +#: ../share/extensions/ffmet.inx.h:8 ../share/extensions/ffms.inx.h:8 +#: ../share/extensions/ffset.inx.h:6 ../share/extensions/ffss.inx.h:6 +#, fuzzy +msgid "Nut Width" +msgstr "Larghezza" + +#: ../share/extensions/ffmet.inx.h:9 ../share/extensions/ffms.inx.h:10 +msgid "Perpendicular Distance" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:10 ../share/extensions/ffset.inx.h:7 +msgid "Scale Base (2 for Octave)" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:11 ../share/extensions/ffset.inx.h:9 +msgid "Tones in Scale" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:12 ../share/extensions/ffms.inx.h:12 +#: ../share/extensions/ffset.inx.h:10 ../share/extensions/ffss.inx.h:10 +msgid "px per Unit" +msgstr "" + +#: ../share/extensions/ffms.inx.h:3 +msgid "FretFind Multi Length Scala" +msgstr "" + +#: ../share/extensions/ffms.inx.h:9 ../share/extensions/ffss.inx.h:7 +msgid "Path to Scala *.scl File" +msgstr "" + +#: ../share/extensions/ffms.inx.h:11 +msgid "Tuning (scale step for each string seperated by semicolons)" +msgstr "" + +#: ../share/extensions/ffset.inx.h:2 +msgid "FretFind Single Length ET" +msgstr "" + +#: ../share/extensions/ffset.inx.h:8 ../share/extensions/ffss.inx.h:8 +msgid "Scale Length" +msgstr "" + +#: ../share/extensions/ffss.inx.h:2 +msgid "FretFind Single Length Scala" +msgstr "" + +#: ../share/extensions/ffss.inx.h:9 +msgid "Tuning (Scale step for each string seperated by semicolons)" +msgstr "" + +#: ../share/extensions/handles.inx.h:1 +#, fuzzy +msgid "Draw Handles" +msgstr "Disegna linee a mano libera" + +#: ../share/extensions/interp.inx.h:1 +#, fuzzy +msgid "Duplicate Endpaths" +msgstr "Duplica nodo" + +#: ../share/extensions/interp.inx.h:2 +#, fuzzy +msgid "Exponent" +msgstr "Esporta" + +#: ../share/extensions/interp.inx.h:3 +msgid "Interpolate" +msgstr "" + +#: ../share/extensions/interp.inx.h:4 +msgid "Interpolate Style (Experimental)" +msgstr "" + +#: ../share/extensions/interp.inx.h:5 +msgid "Interpolation Method" +msgstr "" + +#: ../share/extensions/interp.inx.h:6 +msgid "Interpolation Steps" +msgstr "" + +#: ../share/extensions/kochify.inx.h:1 +msgid "Kochify" +msgstr "" + +#: ../share/extensions/kochify_load.inx.h:1 +msgid "Kochify (Load)" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:1 +#, fuzzy +msgid "Angle" +msgstr "Angolo:" + +#: ../share/extensions/lindenmayer.inx.h:2 +msgid "Axiom" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:3 +#, fuzzy +msgid "Lindenmayer" +msgstr "Rinomina livello" + +#: ../share/extensions/lindenmayer.inx.h:4 +msgid "Order" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:5 +#, fuzzy +msgid "Rules" +msgstr "_Righelli" + +#: ../share/extensions/lindenmayer.inx.h:6 +#, fuzzy +msgid "Step" +msgstr "Scatti" + +#: ../share/extensions/motion.inx.h:1 +#, fuzzy +msgid "Direction" +msgstr "Descrizione" + +#: ../share/extensions/motion.inx.h:2 +#, fuzzy +msgid "Magnitude" +msgstr "Magenta" + +#: ../share/extensions/motion.inx.h:3 +#, fuzzy +msgid "Motion" +msgstr "_Rotazione" + +#: ../share/extensions/pdf_output.inx.h:1 +msgid "Adobe PDF (*.pdf)" +msgstr "" + +#: ../share/extensions/pdf_output.inx.h:2 +msgid "Adobe Portable Document Format" +msgstr "" + +#: ../share/extensions/pdf_output.inx.h:3 +#, fuzzy +msgid "PDF Output" +msgstr "Output" + +#: ../share/extensions/ps_input.inx.h:1 +#, fuzzy +msgid "Postscript" +msgstr "Verticale" + +#: ../share/extensions/ps_input.inx.h:2 +msgid "Postscript (*.ps)" +msgstr "" + +#: ../share/extensions/ps_input.inx.h:3 +msgid "Postscript Input" +msgstr "" + +#: ../share/extensions/radiusrand.inx.h:1 +#, fuzzy +msgid "Radius" +msgstr "Al_za" + +#: ../share/extensions/radiusrand.inx.h:2 +#, fuzzy +msgid "Radius Randomize" +msgstr "Casualità:" + +#: ../share/extensions/radiusrand.inx.h:3 +msgid "Randomize Control Points" +msgstr "" + +#: ../share/extensions/radiusrand.inx.h:4 +#, fuzzy +msgid "Randomize Nodes" +msgstr "Casualità:" + +#: ../share/extensions/rtree.inx.h:1 +#, fuzzy +msgid "Initial Size" +msgstr "Dimensione della bitmap" + +#: ../share/extensions/rtree.inx.h:2 +msgid "Minimum Size" +msgstr "" + +#: ../share/extensions/rtree.inx.h:3 +#, fuzzy +msgid "Random Tree" +msgstr "Casualità:" + +#: ../share/extensions/sk_input.inx.h:1 +msgid "A diagram created with the program Sketch" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:2 +msgid "Sketch Diagram (*.sk)" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:3 +msgid "Sketch Input" +msgstr "" + +#: ../share/extensions/straightseg.inx.h:1 +msgid "Behavior" +msgstr "" + +#: ../share/extensions/straightseg.inx.h:3 +msgid "Segment Straightener" +msgstr "" + +#: ../share/extensions/summersnight.inx.h:1 +msgid "Summer's Night" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:1 +#: ../share/extensions/svgz_output.inx.h:1 +msgid "Compressed Inkscape SVG (*.svgz)" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:2 +#: ../share/extensions/svgz_output.inx.h:2 +msgid "Inkscape's native file format compressed with GZip" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:3 +msgid "SVGZ Input" +msgstr "" + +#: ../share/extensions/svgz_output.inx.h:3 +#, fuzzy +msgid "SVGZ Output" +msgstr "Output" + +#: ../share/extensions/txt2svg.inx.h:1 +msgid "ASCII Text" +msgstr "" + +#: ../share/extensions/txt2svg.inx.h:2 +msgid "Text File (*.txt)" +msgstr "" + +#: ../share/extensions/txt2svg.inx.h:3 +msgid "Text Input" +msgstr "" + +#: ../share/extensions/wavy.inx.h:1 +msgid "Calculate first derivative numerically" +msgstr "" + +#: ../share/extensions/wavy.inx.h:2 +msgid "First derivative" +msgstr "" + +#: ../share/extensions/wavy.inx.h:3 +msgid "Function" +msgstr "" + +#: ../share/extensions/wavy.inx.h:4 +msgid "Function Plotter" +msgstr "" + +#: ../share/extensions/wavy.inx.h:5 +msgid "Nodes per period" +msgstr "" + +#: ../share/extensions/wavy.inx.h:6 +msgid "Periods (2*Pi each)" +msgstr "" + +#: ../share/extensions/whirl.inx.h:1 +msgid "Amount of Whirl" +msgstr "" + +#: ../share/extensions/whirl.inx.h:2 +#, fuzzy +msgid "Center X" +msgstr "Centra" + +#: ../share/extensions/whirl.inx.h:3 +#, fuzzy +msgid "Center Y" +msgstr "Centra" + +#: ../share/extensions/whirl.inx.h:4 +#, fuzzy +msgid "Direction of Rotation" +msgstr "Declina invito" + +#: ../share/extensions/whirl.inx.h:5 +msgid "Whirl" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:1 +msgid "A popular graphics file format for clipart" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:2 +msgid "Windows Metafile (*.wmf)" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:3 +msgid "Windows Metafile Input" +msgstr "" + +#~ msgid "Custom canvas" +#~ msgstr "Tela personalizzata" + +#~ msgid "Current style" +#~ msgstr "Stile corrente" + +#~ msgid "" +#~ "Current style is updated every time you change the style of any object " +#~ "(its fill, stroke, transparency, etc.)" +#~ msgstr "" +#~ "Lo stile corrente viene aggiornato ogni volta che cambia lo stile di un " +#~ "qualsiasi oggetto (il suo riempimento, contorni, trasparenza, ecc.)" + +#~ msgid "Arrange Objects" +#~ msgstr "Dispone gli oggetti" + +#~ msgid "deg" +#~ msgstr "gradi" + +#~ msgid "" +#~ "%s is not a valid preferences file.\n" +#~ "%s" +#~ msgstr "" +#~ "%s non è un file di preferenze valido.\n" +#~ "%s" + +#~ msgid "" +#~ "Inkscape will run with default settings.\n" +#~ "New settings will not be saved." +#~ msgstr "" +#~ "Inkscape verrà eseguito con le impostazioni predefinite.\n" +#~ "Le nuove impostazioni non verranno salvate." + +#~ msgid "" +#~ "0 out of %i node selected. Click, Shift+click, or drag around nodes to select.0 out of %i nodes " +#~ "selected. Click, Shift+click, or drag around nodes " +#~ "to select." +#~ msgstr "" +#~ "0 di %i nodo selezionato. Click, Maiusc+click, o trascinare attorno agli oggetti per selezionare.0 di " +#~ "%i nodi selezionati. Click, Maiusc+click, o " +#~ "trascinare attorno agli oggetti per selezionare." + +#~ msgid "_Credits" +#~ msgstr "_Ringraziamenti" + +#~ msgid "Grab sensitivity" +#~ msgstr "Area di azione" + +#~ msgid "Click/drag threshold" +#~ msgstr "Soglia per il click o spostamento" + +#~ msgid "Mouse wheel scrolls by" +#~ msgstr "Scorrimento con la rotella del mouse di" + +#~ msgid "Scroll by" +#~ msgstr "Scorrimento di" + +#~ msgid "Acceleration" +#~ msgstr "Accelerazione" + +#~ msgid "Speed" +#~ msgstr "Velocità" + +#~ msgid "Threshold" +#~ msgstr "Soglia" + +#~ msgid "Arrow keys move by" +#~ msgstr "Le frecce direzionali muovono di" + +#~ msgid "> and < scale by" +#~ msgstr "> e < ridimensionano di" + +#~ msgid "Inset/Outset by" +#~ msgstr "Intrudi/Estrudi di" + +#~ msgid "Rotation snaps every" +#~ msgstr "La rotazione scatta ogni" + +#~ msgid "Zoom in/out by" +#~ msgstr "Ingrandimento/Riduzione di" + +#~ msgid "Transform" +#~ msgstr "Trasforma" + +#~ msgid "Flip selection horizontally" +#~ msgstr "Riflette la selezione orizzontalmente" + +#~ msgid "Flip selection vertically" +#~ msgstr "Riflette la selezione verticalmente" diff --git a/po/ja.po b/po/ja.po new file mode 100644 index 000000000..1dcf2859e --- /dev/null +++ b/po/ja.po @@ -0,0 +1,9284 @@ +# translation of ja.po to Japanese +# sodipodi ja.po. +# Copyright (C) 2000-2001, 2004, 2005 Free Software Foundation, Inc. +# Yukihiro Nakai , 2000, 2003. +# Takeshi Aihana , 2000-2001. +# Mitsuru Oka , 2001. +# Junichi Uekawa , 2002. +# Mitsuru Oka , 2002. +# Masatake YAMATO , 2002. +# shivaken , 2004, 2005. +msgid "" +msgstr "" +"Project-Id-Version: ja\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2005-12-04 11:51-0800\n" +"PO-Revision-Date: 2005-11-16 00:21+0900\n" +"Last-Translator: shivaken \n" +"Language-Team: Japanese \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 1.10.2\n" + +#: ../inkscape.desktop.in.h:1 +msgid "Create and edit Scalable Vector Graphics images" +msgstr "" + +#: ../inkscape.desktop.in.h:2 +msgid "Inkscape SVG Vector Illustrator" +msgstr "Inkscape SVG ベクトル イラストレータ" + +#: ../../po/../src/arc-context.cpp:350 +msgid "" +"Ctrl: make circle or integer-ratio ellipse, snap arc/segment angle" +msgstr "円/弧を作成 … Ctrl: 比率をスナップ" + +#: ../../po/../src/arc-context.cpp:351 ../../po/../src/rect-context.cpp:388 +msgid "Shift: draw around the starting point" +msgstr "Shift: 始点を中心に描画" + +#: ../../po/../src/arc-context.cpp:413 +#: ../../po/../src/connector-context.cpp:493 +#: ../../po/../src/dyna-draw-context.cpp:506 +#: ../../po/../src/pen-context.cpp:329 ../../po/../src/pencil-context.cpp:208 +#: ../../po/../src/rect-context.cpp:452 ../../po/../src/spiral-context.cpp:421 +#: ../../po/../src/star-context.cpp:427 +msgid "Current layer is hidden. Unhide it to be able to draw on it." +msgstr "" +"現在のレイヤーは非表示になっています。表示にして編集してください。" + +#: ../../po/../src/arc-context.cpp:417 +#: ../../po/../src/connector-context.cpp:497 +#: ../../po/../src/dyna-draw-context.cpp:510 +#: ../../po/../src/pen-context.cpp:336 ../../po/../src/pencil-context.cpp:212 +#: ../../po/../src/rect-context.cpp:456 ../../po/../src/spiral-context.cpp:426 +#: ../../po/../src/star-context.cpp:431 +msgid "Current layer is locked. Unlock it to be able to draw on it." +msgstr "" +"現在のレイヤーはロックされています。ロックを解除して編集してください。" + +#: ../../po/../src/arc-context.cpp:496 +#, c-format +msgid "" +"Ellipse: %s × %s; with Ctrl to make circle or integer-" +"ratio ellipse; with Shift to draw around the starting point" +msgstr "" +"円/弧: %s x %s … Ctrl: 比率をスナップ, Shift: 始点を中" +"心に描画" + +#: ../../po/../src/connector-context.cpp:518 +msgid "Creating new connector" +msgstr "新規コネクタを作成" + +#: ../../po/../src/connector-context.cpp:939 +msgid "Finishing connector" +msgstr "コネクタを終了" + +#: ../../po/../src/connector-context.cpp:1108 +msgid "Connection point: click or drag to create a new connector" +msgstr "コネクタ 始点: クリックまたはドラッグで新しいコネクタを作成" + +#: ../../po/../src/connector-context.cpp:1185 +msgid "Connector endpoint: drag to reroute or connect to new shapes" +msgstr "コネクタ 終点: ドラッグでオブジェクトに接続" + +#: ../../po/../src/connector-context.cpp:1278 +msgid "Select at least one non-connector object." +msgstr "一つ以上のコネクタ以外のオブジェクトを選択してください。" + +#: ../../po/../src/desktop-events.cpp:238 +#, c-format +msgid "%s at %s" +msgstr "%s at %s" + +#. TRANSLATORS: This string appears when double-clicking on a guide. +#. This is the distance by which the guide is to be moved. +#: ../../po/../src/desktop-events.cpp:277 +msgid " relative by " +msgstr "相対位置で指定" + +#. TRANSLATORS: This string appears when double-clicking on a guide. +#. This is the target location where the guide is to be moved. +#: ../../po/../src/desktop-events.cpp:282 +#: ../../po/../src/desktop-events.cpp:395 +msgid " absolute to " +msgstr " 絶対位置 " + +#. create dialog +#: ../../po/../src/desktop-events.cpp:348 +msgid "Guideline" +msgstr "ガイドライン" + +#: ../../po/../src/desktop-events.cpp:432 +#, c-format +msgid "Move %s" +msgstr "%sを移動" + +#: ../../po/../src/desktop.cpp:678 +msgid "No previous zoom." +msgstr "前のズームはありません。" + +#: ../../po/../src/desktop.cpp:703 +msgid "No next zoom." +msgstr "次のズームはありません。" + +#: ../../po/../src/dialogs/clonetiler.cpp:182 +msgid "Nothing selected." +msgstr "何も選択されていません。" + +#: ../../po/../src/dialogs/clonetiler.cpp:188 +msgid "More than one object selected." +msgstr "二つ以上のオブジェクトが選択されています。" + +#: ../../po/../src/dialogs/clonetiler.cpp:195 +#, c-format +msgid "Object has %d tiled clones." +msgstr "" +"オブジェクトは %d 個のタイルクローンを持っています。" + +#: ../../po/../src/dialogs/clonetiler.cpp:200 +msgid "Object has no tiled clones." +msgstr "オブジェクトはタイルクローンを持っていません。" + +#: ../../po/../src/dialogs/clonetiler.cpp:865 +msgid "Select one object whose tiled clones to unclump." +msgstr "タイルクローンを解除するオブジェクトを選択してください。" + +#: ../../po/../src/dialogs/clonetiler.cpp:916 +msgid "Select one object whose tiled clones to remove." +msgstr "タイルクローンを解除するオブジェクトを選択してください。" + +#: ../../po/../src/dialogs/clonetiler.cpp:984 +#: ../../po/../src/selection-chemistry.cpp:1774 +msgid "Select an object to clone." +msgstr "クローンするオブジェクトを選択してください。" + +#: ../../po/../src/dialogs/clonetiler.cpp:990 +#: ../../po/../src/selection-chemistry.cpp:1780 +msgid "" +"If you want to clone several objects, group them and clone the " +"group." +msgstr "" +"複数のオブジェクトのクローンを作る場合、グループ化してクローンをしてくださ" +"い。" + +#: ../../po/../src/dialogs/clonetiler.cpp:1484 +msgid "Per row:" +msgstr "行ごと:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1497 +msgid "Per column:" +msgstr "列ごと:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1505 +msgid "Randomize:" +msgstr "ランダマイズ:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1656 +msgid "_Symmetry" +msgstr "対称化方法(_S)" + +#. TRANSLATORS: For the following 17 symmetry groups, see +#. * http://www.bib.ulb.ac.be/coursmath/doc/17.htm (visual examples); +#. * http://www.clarku.edu/~djoyce/wallpaper/seventeen.html (English vocabulary); or +#. * http://membres.lycos.fr/villemingerard/Geometri/Sym1D.htm (French vocabulary). +#. +#: ../../po/../src/dialogs/clonetiler.cpp:1664 +msgid "Select one of the 17 symmetry groups for the tiling" +msgstr "対称化方法を選んでください" + +#. TRANSLATORS: "translation" means "shift" / "displacement" here. +#: ../../po/../src/dialogs/clonetiler.cpp:1675 +msgid "P1: simple translation" +msgstr "P1: シンプル" + +#: ../../po/../src/dialogs/clonetiler.cpp:1676 +msgid "P2: 180° rotation" +msgstr "P2: 180° 回転" + +#: ../../po/../src/dialogs/clonetiler.cpp:1677 +msgid "PM: reflection" +msgstr "PM: 反射" + +#. TRANSLATORS: "glide reflection" is a reflection and a translation combined. +#. For more info, see http://mathforum.org/sum95/suzanne/symsusan.html +#: ../../po/../src/dialogs/clonetiler.cpp:1680 +msgid "PG: glide reflection" +msgstr "PG: 映進" + +#: ../../po/../src/dialogs/clonetiler.cpp:1681 +msgid "CM: reflection + glide reflection" +msgstr "CM: 反転 + 映進" + +#: ../../po/../src/dialogs/clonetiler.cpp:1682 +msgid "PMM: reflection + reflection" +msgstr "PMM: 反転 + 反転" + +#: ../../po/../src/dialogs/clonetiler.cpp:1683 +msgid "PMG: reflection + 180° rotation" +msgstr "PMG: 反転 + 180° 回転" + +#: ../../po/../src/dialogs/clonetiler.cpp:1684 +msgid "PGG: glide reflection + 180° rotation" +msgstr "PGG: 滑らか反転 + 180° 回転" + +#: ../../po/../src/dialogs/clonetiler.cpp:1685 +msgid "CMM: reflection + reflection + 180° rotation" +msgstr "CMM: 反転 + 反転 + 180° 回転" + +#: ../../po/../src/dialogs/clonetiler.cpp:1686 +msgid "P4: 90° rotation" +msgstr "P4: 90° 回転" + +#: ../../po/../src/dialogs/clonetiler.cpp:1687 +msgid "P4M: 90° rotation + 45° reflection" +msgstr "P4M: 90° 回転 + 45° 反転" + +#: ../../po/../src/dialogs/clonetiler.cpp:1688 +msgid "P4G: 90° rotation + 90° reflection" +msgstr "P4G: 90° 回転 + 90° 反転" + +#: ../../po/../src/dialogs/clonetiler.cpp:1689 +msgid "P3: 120° rotation" +msgstr "P3: 120° 回転" + +#: ../../po/../src/dialogs/clonetiler.cpp:1690 +msgid "P31M: reflection + 120° rotation, dense" +msgstr "P31M: 反転 + 120° 回転, 濃く" + +#: ../../po/../src/dialogs/clonetiler.cpp:1691 +msgid "P3M1: reflection + 120° rotation, sparse" +msgstr "P31M1: 反転 + 120° 回転, 薄く" + +#: ../../po/../src/dialogs/clonetiler.cpp:1692 +msgid "P6: 60° rotation" +msgstr "P6: 60° 回転" + +#: ../../po/../src/dialogs/clonetiler.cpp:1693 +msgid "P6M: reflection + 60° rotation" +msgstr "P6M: 反転 + 60° 回転" + +#: ../../po/../src/dialogs/clonetiler.cpp:1721 +msgid "S_hift" +msgstr "シフト(_S)" + +#. TRANSLATORS: "shift" means: the tiles will be shifted (offset) horizontally by this amount +#: ../../po/../src/dialogs/clonetiler.cpp:1731 +#, no-c-format +msgid "Shift X:" +msgstr "水平シフト:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1739 +#, no-c-format +msgid "Horizontal shift per row (in % of tile width)" +msgstr "行ごとの水平方向へのシフト(幅に対するパーセンテージ)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1747 +#, no-c-format +msgid "Horizontal shift per column (in % of tile width)" +msgstr "列ごとの水平方向へのシフト(幅に対するパーセンテージ)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1754 +msgid "Randomize the horizontal shift by this percentage" +msgstr "水平へのシフトをこの割合でランダムにする" + +#. TRANSLATORS: "shift" means: the tiles will be shifted (offset) vertically by this amount +#: ../../po/../src/dialogs/clonetiler.cpp:1764 +#, no-c-format +msgid "Shift Y:" +msgstr "垂直シフト:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1772 +#, no-c-format +msgid "Vertical shift per row (in % of tile height)" +msgstr "行ごとの垂直方向へのシフト(高さに対するパーセンテージ)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1780 +#, no-c-format +msgid "Vertical shift per column (in % of tile height)" +msgstr "列ごとの垂直方向へのシフト(高さに対するパーセンテージ)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1787 +msgid "Randomize the vertical shift by this percentage" +msgstr "垂直へのシフトをこの割合でランダムにする" + +#: ../../po/../src/dialogs/clonetiler.cpp:1795 +msgid "Exponent:" +msgstr "指数:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1802 +#, fuzzy +msgid "Whether rows are spaced evenly (1), converge (<1) or diverge (>1)" +msgstr "行間隔: 枚(1) or 1点(<1) or 分岐(>1) " + +#: ../../po/../src/dialogs/clonetiler.cpp:1809 +#, fuzzy +msgid "Whether columns are spaced evenly (1), converge (<1) or diverge (>1)" +msgstr "列間隔: 枚(1) or 1点(<1) or 分岐(>1) " + +#. TRANSLATORS: "Alternate" is a verb here +#: ../../po/../src/dialogs/clonetiler.cpp:1817 +#: ../../po/../src/dialogs/clonetiler.cpp:1907 +#: ../../po/../src/dialogs/clonetiler.cpp:1966 +#: ../../po/../src/dialogs/clonetiler.cpp:2022 +#: ../../po/../src/dialogs/clonetiler.cpp:2153 +msgid "Alternate:" +msgstr "交互にする:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1823 +msgid "Alternate the sign of shifts for each row" +msgstr "行ごとに交互にシフト" + +#: ../../po/../src/dialogs/clonetiler.cpp:1828 +msgid "Alternate the sign of shifts for each column" +msgstr "列ごとに交互にシフト" + +#: ../../po/../src/dialogs/clonetiler.cpp:1837 +msgid "Sc_ale" +msgstr "拡大縮小(_a)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1845 +msgid "Scale X:" +msgstr "水平方向での拡大縮小:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1853 +#, no-c-format +msgid "Horizontal scale per row (in % of tile width)" +msgstr "行ごとの水平方向での拡大縮小(幅に対するパーセンテージ)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1861 +#, no-c-format +msgid "Horizontal scale per column (in % of tile width)" +msgstr "列ごとの水平方向での拡大縮小(幅に対するパーセンテージ)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1868 +msgid "Randomize the horizontal scale by this percentage" +msgstr "水平方向での拡大縮小をこの割合でランダムにする" + +#: ../../po/../src/dialogs/clonetiler.cpp:1876 +msgid "Scale Y:" +msgstr "垂直方向での拡大縮小:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1884 +#, no-c-format +msgid "Vertical scale per row (in % of tile height)" +msgstr "行ごとの垂直方向での拡大縮小(高さに対するパーセンテージ)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1892 +#, no-c-format +msgid "Vertical scale per column (in % of tile height)" +msgstr "列ごとの垂直方向での拡大縮小(高さに対するパーセンテージ)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1899 +msgid "Randomize the vertical scale by this percentage" +msgstr "垂直方向での拡大縮小をこの割合でランダムにする" + +#: ../../po/../src/dialogs/clonetiler.cpp:1913 +msgid "Alternate the sign of scales for each row" +msgstr "行ごとに交互に拡大縮小" + +#: ../../po/../src/dialogs/clonetiler.cpp:1918 +msgid "Alternate the sign of scales for each column" +msgstr "列ごとに交互に拡大縮小" + +#: ../../po/../src/dialogs/clonetiler.cpp:1927 +msgid "_Rotation" +msgstr "回転(_R)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1935 +msgid "Angle:" +msgstr "角度:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1943 +#, no-c-format +msgid "Rotate tiles by this angle for each row" +msgstr "行ごとにこの角度回転" + +#: ../../po/../src/dialogs/clonetiler.cpp:1951 +#, no-c-format +msgid "Rotate tiles by this angle for each column" +msgstr "列ごとにこの角度回転" + +#: ../../po/../src/dialogs/clonetiler.cpp:1958 +msgid "Randomize the rotation angle by this percentage" +msgstr "回転角度をランダマイズ(パーセンテージ)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1972 +msgid "Alternate the rotation direction for each row" +msgstr "行ごとに交互に回転" + +#: ../../po/../src/dialogs/clonetiler.cpp:1977 +msgid "Alternate the rotation direction for each column" +msgstr "列ごとに交互に回転" + +#: ../../po/../src/dialogs/clonetiler.cpp:1985 +msgid "_Opacity" +msgstr "不透明度(_O)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1993 +msgid "Fade out:" +msgstr "フェードアウト:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2000 +msgid "Decrease tile opacity by this percentage for each row" +msgstr "行ごとに不透明度を減少(パーセンテージ)" + +#: ../../po/../src/dialogs/clonetiler.cpp:2007 +msgid "Decrease tile opacity by this percentage for each column" +msgstr "列ごとに不透明度を減少(パーセンテージ)" + +#: ../../po/../src/dialogs/clonetiler.cpp:2014 +msgid "Randomize the tile opacity by this percentage" +msgstr "不透明度の変化をランダマイズ(パーセンテージ)" + +#: ../../po/../src/dialogs/clonetiler.cpp:2028 +msgid "Alternate the sign of opacity change for each row" +msgstr "行ごとに交互に不透明度を変化させる" + +#: ../../po/../src/dialogs/clonetiler.cpp:2033 +msgid "Alternate the sign of opacity change for each column" +msgstr "行ごとに交互に不透明度を変化させる" + +#: ../../po/../src/dialogs/clonetiler.cpp:2041 +msgid "Co_lor" +msgstr "色" + +#: ../../po/../src/dialogs/clonetiler.cpp:2046 +msgid "Initial color: " +msgstr "始めの色:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2050 +msgid "Initial color of tiled clones" +msgstr "始めのタイルクローンの色" + +#: ../../po/../src/dialogs/clonetiler.cpp:2050 +msgid "" +"Initial color for clones (works only if the original has unset fill or " +"stroke)" +msgstr "" +"クローンの始めの色(クローンのオリジナルのフィル/ストロークが未設定の場合のみ" +"有効)" + +#: ../../po/../src/dialogs/clonetiler.cpp:2065 +msgid "H:" +msgstr "色相:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2072 +msgid "Change the tile hue by this percentage for each row" +msgstr "行ごとに色相を変化させる" + +#: ../../po/../src/dialogs/clonetiler.cpp:2079 +msgid "Change the tile hue by this percentage for each column" +msgstr "列ごとに色相を変化させる" + +#: ../../po/../src/dialogs/clonetiler.cpp:2086 +msgid "Randomize the tile hue by this percentage" +msgstr "色相の変化度をランダマイズ" + +#: ../../po/../src/dialogs/clonetiler.cpp:2095 +msgid "S:" +msgstr "彩度:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2102 +msgid "Change the color saturation by this percentage for each row" +msgstr "行ごとに彩度を変化させる" + +#: ../../po/../src/dialogs/clonetiler.cpp:2109 +msgid "Change the color saturation by this percentage for each column" +msgstr "列ごとに彩度を変化させる" + +#: ../../po/../src/dialogs/clonetiler.cpp:2116 +msgid "Randomize the color saturation by this percentage" +msgstr "彩度の変化度をランダマイズ" + +#: ../../po/../src/dialogs/clonetiler.cpp:2124 +msgid "L:" +msgstr "明度:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2131 +msgid "Change the color lightness by this percentage for each row" +msgstr "行ごとに明度を変化させる" + +#: ../../po/../src/dialogs/clonetiler.cpp:2138 +msgid "Change the color lightness by this percentage for each column" +msgstr "列ごとに明度を変化させる" + +#: ../../po/../src/dialogs/clonetiler.cpp:2145 +msgid "Randomize the color lightness by this percentage" +msgstr "明度の変化度をランダマイズ" + +#: ../../po/../src/dialogs/clonetiler.cpp:2159 +msgid "Alternate the sign of color changes for each row" +msgstr "行ごと交互に色を変化させる" + +#: ../../po/../src/dialogs/clonetiler.cpp:2164 +msgid "Alternate the sign of color changes for each column" +msgstr "列ごと交互に色を変化させる" + +#: ../../po/../src/dialogs/clonetiler.cpp:2172 +msgid "_Trace" +msgstr "トレース(_T)" + +#: ../../po/../src/dialogs/clonetiler.cpp:2179 +msgid "Trace the drawing under the tiles" +msgstr "タイル下の状態をトレース" + +#: ../../po/../src/dialogs/clonetiler.cpp:2183 +msgid "" +"For each clone, pick a value from the drawing in that clone's location and " +"apply it to the clone" +msgstr "全てのクローンがその場の色の値を抽出し適用" + +#: ../../po/../src/dialogs/clonetiler.cpp:2197 +msgid "1. Pick from the drawing:" +msgstr "1. その場から抽出:" + +#. ----Hbox2 +#: ../../po/../src/dialogs/clonetiler.cpp:2208 +#: ../../po/../src/dialogs/clonetiler.cpp:2355 +#: ../../po/../src/ui/dialog/tracedialog.cpp:445 +msgid "Color" +msgstr "色" + +#: ../../po/../src/dialogs/clonetiler.cpp:2209 +msgid "Pick the visible color and opacity" +msgstr "表示可能な色を抽出(透過属性を含まない)" + +#: ../../po/../src/dialogs/clonetiler.cpp:2216 +#: ../../po/../src/dialogs/clonetiler.cpp:2365 +#: ../share/extensions/dropshadow.inx.h:3 +msgid "Opacity" +msgstr "不透明度" + +#: ../../po/../src/dialogs/clonetiler.cpp:2217 +msgid "Pick the total accumulated opacity" +msgstr "場の不透明度の合計を抽出" + +#: ../../po/../src/dialogs/clonetiler.cpp:2224 +msgid "R" +msgstr "R" + +#: ../../po/../src/dialogs/clonetiler.cpp:2225 +msgid "Pick the Red component of the color" +msgstr "Rを抽出" + +#: ../../po/../src/dialogs/clonetiler.cpp:2232 +msgid "G" +msgstr "G" + +#: ../../po/../src/dialogs/clonetiler.cpp:2233 +msgid "Pick the Green component of the color" +msgstr "Gを抽出" + +#: ../../po/../src/dialogs/clonetiler.cpp:2240 +msgid "B" +msgstr "B" + +#: ../../po/../src/dialogs/clonetiler.cpp:2241 +msgid "Pick the Blue component of the color" +msgstr "Bを抽出" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2250 +msgid "clonetiler|H" +msgstr "色相" + +#: ../../po/../src/dialogs/clonetiler.cpp:2251 +msgid "Pick the hue of the color" +msgstr "色相を抽出" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2260 +msgid "clonetiler|S" +msgstr "彩度" + +#: ../../po/../src/dialogs/clonetiler.cpp:2261 +msgid "Pick the saturation of the color" +msgstr "彩度を抽出" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2270 +msgid "clonetiler|L" +msgstr "明度" + +#: ../../po/../src/dialogs/clonetiler.cpp:2271 +msgid "Pick the lightness of the color" +msgstr "明度を抽出" + +#: ../../po/../src/dialogs/clonetiler.cpp:2281 +msgid "2. Tweak the picked value:" +msgstr "2. 抽出値の補正:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2291 +msgid "Gamma-correct:" +msgstr "ガンマ補正" + +#: ../../po/../src/dialogs/clonetiler.cpp:2296 +msgid "Shift the mid-range of the picked value upwards (>0) or downwards (<0)" +msgstr "抽出値の中間を補正(+ or -)" + +#: ../../po/../src/dialogs/clonetiler.cpp:2303 +msgid "Randomize:" +msgstr "ランダマイズ:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2308 +msgid "Randomize the picked value by this percentage" +msgstr "抽出値をランダマイズ" + +#: ../../po/../src/dialogs/clonetiler.cpp:2315 +msgid "Invert:" +msgstr "反転:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2319 +msgid "Invert the picked value" +msgstr "抽出値を反転" + +#: ../../po/../src/dialogs/clonetiler.cpp:2325 +msgid "3. Apply the value to the clones':" +msgstr "3. 抽出値の適応範囲:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2335 +msgid "Presence" +msgstr "全て" + +#: ../../po/../src/dialogs/clonetiler.cpp:2338 +msgid "" +"Each clone is created with the probability determined by the picked value in " +"that point" +msgstr "全てのクローンをその場から抽出した値を元に生成" + +#: ../../po/../src/dialogs/clonetiler.cpp:2345 +msgid "Size" +msgstr "サイズ" + +#: ../../po/../src/dialogs/clonetiler.cpp:2348 +msgid "Each clone's size is determined by the picked value in that point" +msgstr "その場から抽出した値を元にサイズを決定" + +#: ../../po/../src/dialogs/clonetiler.cpp:2358 +msgid "" +"Each clone is painted by the picked color (the original must have unset fill " +"or stroke)" +msgstr "" +"その場から抽出した色を元に色を決定(オリジナルは無着色でなければならない)" + +#: ../../po/../src/dialogs/clonetiler.cpp:2368 +msgid "Each clone's opacity is determined by the picked value in that point" +msgstr "全てのクローンの不透明度をその場の値を元に決定" + +#: ../../po/../src/dialogs/clonetiler.cpp:2395 +msgid "How many rows in the tiling" +msgstr "タイルの行数" + +#: ../../po/../src/dialogs/clonetiler.cpp:2415 +msgid "How many columns in the tiling" +msgstr "タイルの列数" + +#: ../../po/../src/dialogs/clonetiler.cpp:2445 +msgid "Width of the rectangle to be filled" +msgstr "タイルで埋める幅" + +#: ../../po/../src/dialogs/clonetiler.cpp:2470 +msgid "Height of the rectangle to be filled" +msgstr "タイルで埋める高さ" + +#: ../../po/../src/dialogs/clonetiler.cpp:2485 +msgid "Rows, columns: " +msgstr "行、列:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2486 +msgid "Create the specified number of rows and columns" +msgstr "設定された数のタイルを生成" + +#: ../../po/../src/dialogs/clonetiler.cpp:2495 +msgid "Width, height: " +msgstr "幅、高さ:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2496 +msgid "Fill the specified width and height with the tiling" +msgstr "タイルで埋めつくす範囲を指定" + +#: ../../po/../src/dialogs/clonetiler.cpp:2512 +msgid "Use saved size and position of the tile" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2515 +msgid "" +"Pretend that the size and position of the tile are the same as the last time " +"you tiled it (if any), instead of using the current size" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2539 +msgid " _Create " +msgstr " 適用(_C) " + +#: ../../po/../src/dialogs/clonetiler.cpp:2541 +msgid "Create and tile the clones of the selection" +msgstr "選択オブジェクトのクローンタイルを作成、配置" + +#. TRANSLATORS: if a group of objects are "clumped" together, then they +#. are unevenly spread in the given amount of space - as shown in the +#. diagrams on the left in the following screenshot: +#. http://www.inkscape.org/screenshots/gallery/inkscape-0.42-CVS-tiles-unclump.png +#. So unclumping is the process of spreading a number of objects out more evenly. +#: ../../po/../src/dialogs/clonetiler.cpp:2556 +msgid " _Unclump " +msgstr "凝集(_U)" + +#: ../../po/../src/dialogs/clonetiler.cpp:2557 +msgid "Spread out clones to reduce clumping; can be applied repeatedly" +msgstr "散らばったクローンを徐々に集合(繰り返し可能)" + +#: ../../po/../src/dialogs/clonetiler.cpp:2563 +msgid " Re_move " +msgstr " 削除(_M) " + +#: ../../po/../src/dialogs/clonetiler.cpp:2564 +msgid "Remove existing tiled clones of the selected object (siblings only)" +msgstr "選択オブジェクトのクローンタイルを削除" + +#: ../../po/../src/dialogs/clonetiler.cpp:2580 +msgid " R_eset " +msgstr " リセット(_E) " + +#. TRANSLATORS: "change" is a noun here +#: ../../po/../src/dialogs/clonetiler.cpp:2582 +msgid "" +"Reset all shifts, scales, rotates, opacity and color changes in the dialog " +"to zero" +msgstr "全ての設定を初期値に戻す" + +#: ../../po/../src/dialogs/color-picker.cpp:280 +msgid "Close" +msgstr "閉じる" + +#: ../../po/../src/dialogs/debugdialog.cpp:138 +msgid "Messages" +msgstr "デバッグ" + +#. ## Add a menu for clear() +#: ../../po/../src/dialogs/debugdialog.cpp:144 +#: ../../po/../src/menus-skeleton.h:16 +#: ../../po/../src/ui/dialog/messages.cpp:56 +#: ../../po/../src/ui/dialog/scriptdialog.cpp:181 +msgid "_File" +msgstr "ファイル(_F)" + +#. TRANSLATORS: "Clear" is a verb here +#: ../../po/../src/dialogs/debugdialog.cpp:145 +#: ../../po/../src/dialogs/find.cpp:753 +#: ../../po/../src/ui/dialog/messages.cpp:57 +#: ../../po/../src/ui/dialog/scriptdialog.cpp:182 +msgid "_Clear" +msgstr "ログをクリア(_C)" + +#: ../../po/../src/dialogs/debugdialog.cpp:147 +#: ../../po/../src/ui/dialog/messages.cpp:59 +msgid "Capture log messages" +msgstr "ログをキャプチャ" + +#: ../../po/../src/dialogs/debugdialog.cpp:149 +#: ../../po/../src/ui/dialog/messages.cpp:61 +msgid "Release log messages" +msgstr "ログを解放" + +#. Notebook tab +#: ../../po/../src/dialogs/desktop-properties.cpp:909 +#: ../../po/../src/ui/dialog/document-preferences.cpp:89 +#: ../../po/../src/ui/widget/panel.cpp:107 +msgid "Grid" +msgstr "グリッド" + +#. Checkbuttons +#. / \todo FIXME: gray out snapping when grid is off +#. / \todo FIXME: gray out snapping when grid is off. +#. / Dissenting view: you want snapping without grid. +#: ../../po/../src/dialogs/desktop-properties.cpp:917 +#: ../../po/../src/ui/dialog/document-preferences.cpp:179 +msgid "Show grid" +msgstr "グリッドの表示" + +#: ../../po/../src/dialogs/desktop-properties.cpp:917 +#: ../../po/../src/ui/dialog/document-preferences.cpp:179 +#: ../../po/../src/verbs.cpp:2115 +msgid "Show or hide grid" +msgstr "グリッドの表示/非表示" + +#: ../../po/../src/dialogs/desktop-properties.cpp:918 +#: ../../po/../src/ui/dialog/document-preferences.cpp:180 +msgid "Snap bounding boxes to grid" +msgstr "隣り合うボックスをグリッドに合わせる" + +#: ../../po/../src/dialogs/desktop-properties.cpp:918 +#: ../../po/../src/dialogs/desktop-properties.cpp:1001 +#: ../../po/../src/ui/dialog/document-preferences.cpp:181 +#: ../../po/../src/ui/dialog/document-preferences.cpp:236 +msgid "Snap the edges of the object bounding boxes" +msgstr "オブジェクトをグリッドに合わせる" + +#: ../../po/../src/dialogs/desktop-properties.cpp:919 +#: ../../po/../src/ui/dialog/document-preferences.cpp:183 +msgid "Snap nodes to grid" +msgstr "ノードをグリッドに合わせる" + +#: ../../po/../src/dialogs/desktop-properties.cpp:919 +#: ../../po/../src/dialogs/desktop-properties.cpp:1002 +#: ../../po/../src/ui/dialog/document-preferences.cpp:184 +#: ../../po/../src/ui/dialog/document-preferences.cpp:239 +msgid "Snap path nodes, text baselines, ellipse centers, etc." +msgstr "パスのノード、テキストのベースライン、円/弧などを合わせる" + +#: ../../po/../src/dialogs/desktop-properties.cpp:937 +#: ../../po/../src/ui/dialog/document-preferences.cpp:186 +msgid "Grid units:" +msgstr "グリッド単位:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:939 +#: ../../po/../src/ui/dialog/document-preferences.cpp:187 +msgid "Origin X:" +msgstr "X方向の始点:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:942 +#: ../../po/../src/ui/dialog/document-preferences.cpp:189 +msgid "Origin Y:" +msgstr "Y方向の始点:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:945 +#: ../../po/../src/ui/dialog/document-preferences.cpp:191 +msgid "Spacing X:" +msgstr "X方向の間隔:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:948 +#: ../../po/../src/ui/dialog/document-preferences.cpp:193 +msgid "Spacing Y:" +msgstr "Y方向の間隔:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:952 +#: ../../po/../src/dialogs/desktop-properties.cpp:1013 +#: ../../po/../src/ui/dialog/document-preferences.cpp:195 +#: ../../po/../src/ui/dialog/document-preferences.cpp:241 +msgid "Snap units:" +msgstr "ユニットに合わせる:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:955 +#: ../../po/../src/dialogs/desktop-properties.cpp:1016 +#: ../../po/../src/ui/dialog/document-preferences.cpp:196 +#: ../../po/../src/ui/dialog/document-preferences.cpp:242 +msgid "Snap distance:" +msgstr "合わせる距離:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:958 +#: ../../po/../src/ui/dialog/document-preferences.cpp:199 +msgid "Grid line color:" +msgstr "グリッドラインカラー" + +#: ../../po/../src/dialogs/desktop-properties.cpp:959 +#: ../../po/../src/ui/dialog/document-preferences.cpp:199 +msgid "Grid line color" +msgstr "グリッドラインカラー" + +#: ../../po/../src/dialogs/desktop-properties.cpp:959 +#: ../../po/../src/ui/dialog/document-preferences.cpp:200 +msgid "Color of grid lines" +msgstr "グリッドラインカラー" + +#: ../../po/../src/dialogs/desktop-properties.cpp:961 +#: ../../po/../src/ui/dialog/document-preferences.cpp:201 +msgid "Major grid line color:" +msgstr "メジャーガイドラインカラー" + +#: ../../po/../src/dialogs/desktop-properties.cpp:962 +#: ../../po/../src/ui/dialog/document-preferences.cpp:201 +msgid "Major grid line color" +msgstr "メジャーガイドラインカラー" + +#: ../../po/../src/dialogs/desktop-properties.cpp:962 +#: ../../po/../src/ui/dialog/document-preferences.cpp:202 +msgid "Color of the major (highlighted) grid lines" +msgstr "メジャー(ハイライト)ガイドラインカラー" + +#: ../../po/../src/dialogs/desktop-properties.cpp:965 +#: ../../po/../src/ui/dialog/document-preferences.cpp:204 +msgid "Major grid line every:" +msgstr "メジャーガイドラインの間隔:" + +#. TRANSLATORS: This belongs to the "Major grid line every:" string, +#. see grid settings in the "Document Preferences" dialog +#: ../../po/../src/dialogs/desktop-properties.cpp:977 +#: ../../po/../src/ui/dialog/document-preferences.cpp:204 +msgid "lines" +msgstr "線" + +#. Guidelines page +#: ../../po/../src/dialogs/desktop-properties.cpp:991 +#: ../../po/../src/ui/dialog/document-preferences.cpp:90 +msgid "Guides" +msgstr "ガイド" + +#. / \todo FIXME: gray out snapping when guides are off +#. / Dissenting view: you want snapping without guides. +#: ../../po/../src/dialogs/desktop-properties.cpp:1000 +#: ../../po/../src/ui/dialog/document-preferences.cpp:234 +msgid "Show guides" +msgstr "ガイドを表示" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1000 +#: ../../po/../src/ui/dialog/document-preferences.cpp:234 +#: ../../po/../src/verbs.cpp:2116 +msgid "Show or hide guides" +msgstr "ガイドの表示" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1001 +#: ../../po/../src/ui/dialog/document-preferences.cpp:235 +msgid "Snap bounding boxes to guides" +msgstr "ガイドに合わせる" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1002 +#: ../../po/../src/ui/dialog/document-preferences.cpp:238 +msgid "Snap points to guides" +msgstr "ポイントをガイドに合わせる" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1020 +#: ../../po/../src/ui/dialog/document-preferences.cpp:243 +msgid "Guide color:" +msgstr "ガイドカラー:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1021 +#: ../../po/../src/ui/dialog/document-preferences.cpp:243 +msgid "Guideline color" +msgstr "ガイドラインカラー" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1021 +#: ../../po/../src/ui/dialog/document-preferences.cpp:244 +msgid "Color of guidelines" +msgstr "ガイドラインカラー" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1023 +#: ../../po/../src/ui/dialog/document-preferences.cpp:245 +msgid "Highlight color:" +msgstr "ハイライトカラー:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1024 +#: ../../po/../src/ui/dialog/document-preferences.cpp:245 +msgid "Highlighted guideline color" +msgstr "ハイライトガイドラインカラー" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1024 +#: ../../po/../src/ui/dialog/document-preferences.cpp:246 +msgid "Color of a guideline when it is under mouse" +msgstr "ハイライトガイドラインカラー" + +#. Page page +#: ../../po/../src/dialogs/desktop-properties.cpp:1029 +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:855 +#: ../../po/../src/ui/dialog/document-preferences.cpp:88 +#: ../../po/../src/widgets/desktop-widget.cpp:1061 +msgid "Page" +msgstr "ページ" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1039 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +msgid "Background:" +msgstr "背景色:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1040 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +msgid "Background color" +msgstr "背景色" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1041 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +msgid "" +"Color and transparency of the page background (also used for bitmap export)" +msgstr "ドキュメントの背景色と不透明度(ビットマップへのエクスポートにも使用)" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1045 +#: ../../po/../src/ui/dialog/document-preferences.cpp:147 +#, fuzzy +msgid "Show page border" +msgstr "境界線を表示" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1049 +#: ../../po/../src/ui/dialog/document-preferences.cpp:148 +msgid "Border on top of drawing" +msgstr "描画の境界線" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1052 +#: ../../po/../src/ui/dialog/document-preferences.cpp:149 +msgid "Border color:" +msgstr "境界線色" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1053 +#: ../../po/../src/ui/dialog/document-preferences.cpp:149 +#, fuzzy +msgid "Page border color" +msgstr "用紙の境界線の色" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1054 +#: ../../po/../src/ui/dialog/document-preferences.cpp:150 +#, fuzzy +msgid "Color of the page border" +msgstr "境界線の色" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1059 +#: ../../po/../src/ui/dialog/document-preferences.cpp:152 +msgid "Show page shadow" +msgstr "ページに影をつける" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1063 +#: ../../po/../src/ui/dialog/document-preferences.cpp:153 +msgid "Default units:" +msgstr "単位" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1069 +msgid "Units for the tool controls, ruler, and the statusbar" +msgstr "ツールや定規、ステータスバーの単位" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1086 +#: ../../po/../src/ui/widget/page-sizer.cpp:209 +#, fuzzy +msgid "Page size:" +msgstr "用紙サイズ:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1110 +#: ../../po/../src/ui/widget/page-sizer.cpp:219 +msgid "Custom" +msgstr "カスタム" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1121 +#: ../../po/../src/ui/widget/page-sizer.cpp:225 +#, fuzzy +msgid "Page orientation:" +msgstr "用紙方向:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1133 +#: ../../po/../src/ui/widget/page-sizer.cpp:232 +msgid "Landscape" +msgstr "横書き" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1139 +#: ../../po/../src/ui/widget/page-sizer.cpp:234 +msgid "Portrait" +msgstr "縦書き" + +#. Custom paper frame +#: ../../po/../src/dialogs/desktop-properties.cpp:1148 +#: ../../po/../src/ui/widget/page-sizer.cpp:249 +#, fuzzy +msgid "Custom size" +msgstr "カスタム" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1160 +#: ../../po/../src/dialogs/export.cpp:269 +#: ../../po/../src/ui/widget/page-sizer.cpp:261 +msgid "Units:" +msgstr "単位:" + +#. Stroke width +#: ../../po/../src/dialogs/desktop-properties.cpp:1162 +#: ../../po/../src/dialogs/export.cpp:310 +#: ../../po/../src/dialogs/object-attributes.cpp:55 +#: ../../po/../src/dialogs/stroke-style.cpp:985 +#: ../../po/../src/ui/widget/page-sizer.cpp:262 +#: ../../po/../src/widgets/toolbox.cpp:1957 +msgid "Width:" +msgstr "幅:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1183 +#: ../../po/../src/dialogs/export.cpp:326 +#: ../../po/../src/dialogs/export.cpp:431 +#: ../../po/../src/dialogs/object-attributes.cpp:56 +#: ../../po/../src/ui/widget/page-sizer.cpp:263 +msgid "Height:" +msgstr "高さ:" + +#. +#. * Ownership metadata tab +#. +#: ../../po/../src/dialogs/desktop-properties.cpp:1206 +msgid "Metadata" +msgstr "メタデータ" + +#. add license selector pull-down +#: ../../po/../src/dialogs/desktop-properties.cpp:1225 +msgid "License" +msgstr "ライセンス" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1255 +msgid "Proprietary" +msgstr "プロプライエタリ" + +#: ../../po/../src/dialogs/display-settings.cpp:212 +msgid "When transforming, show:" +msgstr "変形時の表示方法:" + +#: ../../po/../src/dialogs/display-settings.cpp:223 +msgid "Objects" +msgstr "オブジェクトを表示" + +#: ../../po/../src/dialogs/display-settings.cpp:224 +msgid "Show the actual objects when moving or transforming" +msgstr "移動/変形時にオブジェクトの実体を表示" + +#: ../../po/../src/dialogs/display-settings.cpp:231 +msgid "Box outline" +msgstr "枠のみ" + +#: ../../po/../src/dialogs/display-settings.cpp:232 +msgid "Show only a box outline of the objects when moving or transforming" +msgstr "移動/変形時に枠のみ表示" + +#: ../../po/../src/dialogs/display-settings.cpp:238 +msgid "Per-object selection cue:" +msgstr "選択オブジェクトの明示方法:" + +#. sorationsnapsperpi == 0 means no snapping +#: ../../po/../src/dialogs/display-settings.cpp:249 +#: ../../po/../src/dialogs/display-settings.cpp:386 +#: ../../po/../src/dialogs/display-settings.cpp:441 +#: ../../po/../src/dialogs/display-settings.cpp:1482 +#: ../../po/../src/dialogs/stroke-style.cpp:791 +#: ../../po/../src/interface.cpp:741 +#: ../../po/../src/ui/widget/selected-style.cpp:100 +#: ../../po/../src/verbs.cpp:1842 +msgid "None" +msgstr "なし" + +#: ../../po/../src/dialogs/display-settings.cpp:250 +msgid "No per-object selection indication" +msgstr "オブジェクトごとの選択表示をしない" + +#: ../../po/../src/dialogs/display-settings.cpp:256 +msgid "Mark" +msgstr "マーク" + +#: ../../po/../src/dialogs/display-settings.cpp:257 +msgid "Each selected object has a diamond mark in the top left corner" +msgstr "選択したオブジェクトそれぞれにマークを表示" + +#: ../../po/../src/dialogs/display-settings.cpp:264 +msgid "Box" +msgstr "枠" + +#: ../../po/../src/dialogs/display-settings.cpp:265 +msgid "Each selected object displays its bounding box" +msgstr "選択したオブジェクトそれぞれの枠を表示" + +#: ../../po/../src/dialogs/display-settings.cpp:270 +msgid "Default scale origin:" +msgstr "計測起点:" + +#: ../../po/../src/dialogs/display-settings.cpp:281 +msgid "Opposite bounding box edge" +msgstr "外枠の反対側の端" + +#: ../../po/../src/dialogs/display-settings.cpp:282 +msgid "Default scale origin will be on the bounding box of the item" +msgstr "オブジェクトの外枠を計測に使う" + +#: ../../po/../src/dialogs/display-settings.cpp:288 +msgid "Farthest opposite node" +msgstr "最も遠いノード" + +#: ../../po/../src/dialogs/display-settings.cpp:289 +msgid "Default scale origin will be on the bounding box of the item's points" +msgstr "最も遠いノードを計測の起点に使う" + +#: ../../po/../src/dialogs/display-settings.cpp:341 +msgid "degrees" +msgstr "度" + +#: ../../po/../src/dialogs/display-settings.cpp:350 +msgid "" +"Rotating with Ctrl pressed snaps every that much degrees; also, pressing " +"[ or ] rotates by this amount" +msgstr "[, ]や[Ctrl]を押しながらの回転の際にスナップする角度" + +#: ../../po/../src/dialogs/display-settings.cpp:407 +msgid "Rotation snaps every:" +msgstr "回転の単位:" + +#: ../../po/../src/dialogs/display-settings.cpp:430 +msgid "" +"None: dialogs are treated as regular windows; Normal: dialogs stay on top of " +"document windows; Aggressive: same as Normal but may work better with some " +"window managers." +msgstr "" +"なし: ダイアログを通常のウィンドウとして扱う標準: ダイアログをドキュメント" +"ウィンドウの前に置くアグレッシブ: 標準より積極的に制御を行う" + +#: ../../po/../src/dialogs/display-settings.cpp:451 +msgid "Normal" +msgstr "標準" + +#: ../../po/../src/dialogs/display-settings.cpp:461 +msgid "Aggressive" +msgstr "アグレッシブ" + +#: ../../po/../src/dialogs/display-settings.cpp:475 +msgid "Dialogs on top:" +msgstr "ダイアログの表示方法" + +#: ../../po/../src/dialogs/display-settings.cpp:645 +msgid "Show selection cue" +msgstr "選択表示" + +#: ../../po/../src/dialogs/display-settings.cpp:646 +msgid "" +"Whether selected objects display a selection cue (the same as in selector)" +msgstr "選択済みオブジェクトの選択表示をする" + +#: ../../po/../src/dialogs/display-settings.cpp:657 +msgid "Enable gradient editing" +msgstr "グラデーションを有効にする" + +#: ../../po/../src/dialogs/display-settings.cpp:658 +#, fuzzy +msgid "Whether selected objects display gradient editing controls" +msgstr "選択済みオブジェクトの選択表示をする" + +#: ../../po/../src/dialogs/display-settings.cpp:719 +msgid "No objects selected to take the style from." +msgstr "スタイルを記憶するためにオブジェクトを選択してください。" + +#: ../../po/../src/dialogs/display-settings.cpp:728 +msgid "" +"More than one object selected. Cannot take style from multiple " +"objects." +msgstr "" +"二つ以上のオブジェクトが選択されています。スタイルを記憶するために一つ" +"だけ選択してください。" + +#: ../../po/../src/dialogs/display-settings.cpp:767 +msgid "Create new objects with:" +msgstr "新規オブジェクトのスタイル:" + +#: ../../po/../src/dialogs/display-settings.cpp:777 +msgid "Take from selection" +msgstr "選択オブジェクトのスタイルを使用" + +#: ../../po/../src/dialogs/display-settings.cpp:778 +msgid "Remember the style of the (first) selected object as this tool's style" +msgstr "選択オブジェクトのスタイルを記憶" + +#: ../../po/../src/dialogs/display-settings.cpp:782 +#, fuzzy +msgid "Last used style" +msgstr "スタイルをペースト" + +#: ../../po/../src/dialogs/display-settings.cpp:782 +msgid "Apply the style you last set on an object" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:790 +msgid "This tool's own style:" +msgstr "ツールごとのスタイル" + +#: ../../po/../src/dialogs/display-settings.cpp:790 +msgid "" +"Each tool may store its own style to apply to the newly created objects. Use " +"the button below to set it." +msgstr "それぞれのツールのスタイルを使用" + +#. Mouse +#: ../../po/../src/dialogs/display-settings.cpp:877 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:55 +msgid "Mouse" +msgstr "マウス" + +#. TRANSLATORS: "Grab" is a noun here. "Grab sensitivity" is intended to mean how +#. * close on the screen you need to be to an object to be able to grab it with mouse (in +#. * pixels). +#: ../../po/../src/dialogs/display-settings.cpp:883 +msgid "Grab sensitivity:" +msgstr "選択の感度" + +#: ../../po/../src/dialogs/display-settings.cpp:884 +msgid "" +"How close on the screen you need to be to an object to be able to grab it " +"with mouse (in screen pixels)" +msgstr "マウスで選択する際にどれだけオブジェクトに近いと掴めるかの感度" + +#: ../../po/../src/dialogs/display-settings.cpp:885 +#: ../../po/../src/dialogs/display-settings.cpp:897 +#: ../../po/../src/dialogs/display-settings.cpp:912 +#: ../../po/../src/dialogs/display-settings.cpp:930 +#: ../../po/../src/dialogs/display-settings.cpp:970 +msgid "pixels" +msgstr "ピクセル" + +#: ../../po/../src/dialogs/display-settings.cpp:895 +msgid "Click/drag threshold:" +msgstr "クリック/ドラッグの区別" + +#: ../../po/../src/dialogs/display-settings.cpp:896 +msgid "" +"Maximum mouse drag (in screen pixels) which is considered a click, not a drag" +msgstr "ドラッグではなくクリックとする動きの最大値" + +#. Scrolling +#: ../../po/../src/dialogs/display-settings.cpp:907 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:56 +msgid "Scrolling" +msgstr "スクロール" + +#: ../../po/../src/dialogs/display-settings.cpp:910 +msgid "Mouse wheel scrolls by:" +msgstr "マウスホイールでのスクロール:" + +#: ../../po/../src/dialogs/display-settings.cpp:911 +msgid "" +"One mouse wheel notch scrolls by this distance in screen pixels " +"(horizontally with Shift)" +msgstr "ホイールを一度動かした際にスクロールする量" + +#: ../../po/../src/dialogs/display-settings.cpp:920 +msgid "Ctrl+arrows" +msgstr "コントロールキー+カーソルキー" + +#: ../../po/../src/dialogs/display-settings.cpp:928 +msgid "Scroll by:" +msgstr "スクロールバー:" + +#: ../../po/../src/dialogs/display-settings.cpp:929 +#, fuzzy +msgid "Pressing Ctrl+arrow key scrolls by this distance (in screen pixels)" +msgstr "Ctrlキーと矢印でスクロールする量" + +#: ../../po/../src/dialogs/display-settings.cpp:939 +msgid "Acceleration:" +msgstr "加速:" + +#: ../../po/../src/dialogs/display-settings.cpp:940 +msgid "" +"Pressing and holding Ctrl+arrow will gradually speed up scrolling (0 for no " +"acceleration)" +msgstr "Ctrlキーと矢印のスクロールの加速度 (0で加速なし)" + +#: ../../po/../src/dialogs/display-settings.cpp:949 +msgid "Autoscrolling" +msgstr "自動スクロール" + +#: ../../po/../src/dialogs/display-settings.cpp:957 +msgid "Speed:" +msgstr "スピード:" + +#: ../../po/../src/dialogs/display-settings.cpp:958 +msgid "" +"How fast the canvas autoscrolls when you drag beyond canvas edge (0 to turn " +"autoscroll off)" +msgstr "自動スクロールの速さ (0で自動スクロールをオフ)" + +#: ../../po/../src/dialogs/display-settings.cpp:968 +#: ../../po/../src/ui/dialog/tracedialog.cpp:357 +#: ../../po/../src/ui/dialog/tracedialog.cpp:390 +msgid "Threshold:" +msgstr "閾値:" + +#: ../../po/../src/dialogs/display-settings.cpp:969 +msgid "" +"How far (in screen pixels) you need to be from the canvas edge to trigger " +"autoscroll; positive is outside the canvas, negative is within the canvas" +msgstr "" +"どれだけ端より外にカーソルを持っていけば自動スクロールが働くか。0以上でキャン" +"バスより外、0以下でキャンバスの中で作動。" + +#. Steps +#: ../../po/../src/dialogs/display-settings.cpp:979 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:57 +msgid "Steps" +msgstr "変化度" + +#: ../../po/../src/dialogs/display-settings.cpp:982 +msgid "Arrow keys move by:" +msgstr "カーソルキーでの移動:" + +#: ../../po/../src/dialogs/display-settings.cpp:983 +msgid "" +"Pressing an arrow key moves selected object(s) or node(s) by this distance " +"(in px units)" +msgstr "カーソルキーによるオブジェクト移動距離(SVGピクセル)" + +#: ../../po/../src/dialogs/display-settings.cpp:984 +#: ../../po/../src/dialogs/display-settings.cpp:995 +#: ../../po/../src/dialogs/display-settings.cpp:1006 +#: ../../po/../src/helper/units.cpp:42 +msgid "px" +msgstr "ピクセル" + +#: ../../po/../src/dialogs/display-settings.cpp:993 +msgid "> and < scale by:" +msgstr "[<], [>]キーでの拡大/縮小:" + +#: ../../po/../src/dialogs/display-settings.cpp:994 +msgid "" +"Pressing > or < scales selection up or down by this increment (in px units)" +msgstr "[<], [>]キーでの拡大/縮小の変化度(SVGピクセル)" + +#: ../../po/../src/dialogs/display-settings.cpp:1004 +msgid "Inset/Outset by:" +msgstr "インセット/アウトセット:" + +#: ../../po/../src/dialogs/display-settings.cpp:1005 +msgid "" +"Inset and Outset commands displace the path by this distance (in px units)" +msgstr "[インセット/アウトセット] での変化度(ピクセル)" + +#: ../../po/../src/dialogs/display-settings.cpp:1017 +msgid "Compass-like display of angles" +msgstr "コンパス状の角度表示" + +#. TRANSLATORS: "positive clockwise" means "increasing in clockwise direction" +#: ../../po/../src/dialogs/display-settings.cpp:1019 +msgid "" +"When on, angles are displayed with 0 at north, 0 to 360 range, positive " +"clockwise; otherwise with 0 at east, -180 to 180 range, positive " +"counterclockwise" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1026 +msgid "Zoom in/out by:" +msgstr "ズームイン/アウト:" + +#: ../../po/../src/dialogs/display-settings.cpp:1027 +msgid "" +"Zoom tool click, +/- keys, and middle click zoom in and out by this " +"multiplier" +msgstr "[+], [/]キーや真中ボタンによるズームの変化度" + +#: ../../po/../src/dialogs/display-settings.cpp:1028 +#: ../../po/../src/helper/units.cpp:44 +msgid "%" +msgstr "%" + +#. Tools +#: ../../po/../src/dialogs/display-settings.cpp:1037 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:58 +msgid "Tools" +msgstr "ツール" + +#: ../../po/../src/dialogs/display-settings.cpp:1045 +msgid "Selector" +msgstr "選択" + +#: ../../po/../src/dialogs/display-settings.cpp:1056 +msgid "Node" +msgstr "ノード" + +#: ../../po/../src/dialogs/display-settings.cpp:1064 +#: ../../po/../src/verbs.cpp:2073 +#: ../../po/../src/widgets/desktop-widget.cpp:277 +msgid "Zoom" +msgstr "ズーム" + +#. The 4 shape tools +#: ../../po/../src/dialogs/display-settings.cpp:1071 +msgid "Shapes" +msgstr "シェープ" + +#: ../../po/../src/dialogs/display-settings.cpp:1079 +#: ../../po/../src/verbs.cpp:2055 +msgid "Rectangle" +msgstr "矩形" + +#: ../../po/../src/dialogs/display-settings.cpp:1085 +#: ../../po/../src/verbs.cpp:2057 +msgid "Ellipse" +msgstr "円/弧" + +#: ../../po/../src/dialogs/display-settings.cpp:1091 +#: ../../po/../src/verbs.cpp:2059 +msgid "Star" +msgstr "星" + +#: ../../po/../src/dialogs/display-settings.cpp:1097 +#: ../../po/../src/verbs.cpp:2061 +msgid "Spiral" +msgstr "螺旋" + +#: ../../po/../src/dialogs/display-settings.cpp:1111 +#: ../../po/../src/verbs.cpp:2063 +msgid "Pencil" +msgstr "鉛筆" + +#: ../../po/../src/dialogs/display-settings.cpp:1114 +msgid "Tolerance:" +msgstr "許容誤差:" + +#: ../../po/../src/dialogs/display-settings.cpp:1115 +msgid "" +"This value affects the amount of smoothing applied to freehand lines; lower " +"values produce more uneven paths with more nodes" +msgstr "鉛筆ツールでできるパスの滑らかさ、少ないとパスを多く作成する" + +#: ../../po/../src/dialogs/display-settings.cpp:1131 +#: ../../po/../src/verbs.cpp:2065 +msgid "Pen" +msgstr "ペン" + +#: ../../po/../src/dialogs/display-settings.cpp:1140 +#: ../../po/../src/verbs.cpp:2067 +msgid "Calligraphy" +msgstr "カリグラフィ" + +#: ../../po/../src/dialogs/display-settings.cpp:1147 +#: ../../po/../src/dialogs/text-edit.cpp:353 +#: ../../po/../src/ui/dialog/text-properties.cpp:37 +#: ../../po/../src/verbs.cpp:2069 +msgid "Text" +msgstr "テキスト" + +#: ../../po/../src/dialogs/display-settings.cpp:1157 +#: ../../po/../src/verbs.cpp:2071 +msgid "Gradient" +msgstr "グラデーション" + +#: ../../po/../src/dialogs/display-settings.cpp:1164 +#: ../../po/../src/verbs.cpp:2077 +msgid "Connector" +msgstr "コネクタ" + +#: ../../po/../src/dialogs/display-settings.cpp:1171 +#: ../../po/../src/verbs.cpp:2075 +msgid "Dropper" +msgstr "スポイト" + +#. Windows +#: ../../po/../src/dialogs/display-settings.cpp:1183 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:59 +msgid "Windows" +msgstr "ウインドウ" + +#: ../../po/../src/dialogs/display-settings.cpp:1188 +msgid "Save window geometry" +msgstr "ウインドウサイズの保存" + +#: ../../po/../src/dialogs/display-settings.cpp:1189 +msgid "" +"Save the window size and position with each document (only for Inkscape SVG " +"format)" +msgstr "" +"ウインドウの場所、サイズをドキュメントごとに保存(Inkscape SVGフォーマットの" +"み)" + +#: ../../po/../src/dialogs/display-settings.cpp:1196 +msgid "Dialogs are hidden in taskbar" +msgstr "ダイアログをタスクバーに隠す" + +#: ../../po/../src/dialogs/display-settings.cpp:1197 +msgid "Whether dialog windows are to be hidden in the window manager taskbar" +msgstr "ダイアログをタスクバーに隠す設定" + +#: ../../po/../src/dialogs/display-settings.cpp:1204 +msgid "Zoom when window is resized" +msgstr "ウィンドウサイズのリサイズに併せる" + +#: ../../po/../src/dialogs/display-settings.cpp:1205 +msgid "" +"Zoom drawing when document window is resized, to keep the same area visible " +"(this is the default which can be changed in any window using the button " +"above the right scrollbar)" +msgstr "" +"ウィンドウのサイズ変更に併せてズームを変更する。(縦スクロールバーの上に設定変" +"更するボタンがある)" + +#. Clones +#: ../../po/../src/dialogs/display-settings.cpp:1213 +#: ../../po/../src/dialogs/find.cpp:624 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:60 +msgid "Clones" +msgstr "クローン" + +#: ../../po/../src/dialogs/display-settings.cpp:1217 +msgid "When the original moves, its clones and linked offsets:" +msgstr "オリジナルを移動したら" + +#: ../../po/../src/dialogs/display-settings.cpp:1229 +msgid "Move in parallel" +msgstr "並行に移動" + +#: ../../po/../src/dialogs/display-settings.cpp:1230 +msgid "Clones are translated by the same vector as their original." +msgstr "オリジナルと同じ様に移動" + +#: ../../po/../src/dialogs/display-settings.cpp:1237 +msgid "Stay unmoved" +msgstr "そのまま" + +#: ../../po/../src/dialogs/display-settings.cpp:1238 +msgid "Clones preserve their positions when their original is moved." +msgstr "オリジナルを動かしてもクローンはそのまま" + +#: ../../po/../src/dialogs/display-settings.cpp:1245 +msgid "Move according to transform" +msgstr "変形に併せて移動" + +#: ../../po/../src/dialogs/display-settings.cpp:1246 +msgid "" +"Each clone moves according to the value of its transform= attribute. For " +"example, a rotated clone will move in a different direction than its " +"original." +msgstr "" +"それぞれのクローンをtransform属性の値に合わせて移動させる。例えば回転させられ" +"たクローンはそれによってオリジナルと違う方向に移動する" + +#: ../../po/../src/dialogs/display-settings.cpp:1255 +msgid "When the original is deleted, its clones:" +msgstr "オリジナルを削除したら" + +#: ../../po/../src/dialogs/display-settings.cpp:1267 +msgid "Are unlinked" +msgstr "リンクを解除する" + +#: ../../po/../src/dialogs/display-settings.cpp:1267 +msgid "Orphaned clones are converted to regular objects." +msgstr "通常のオブジェクトに変換する" + +#: ../../po/../src/dialogs/display-settings.cpp:1273 +msgid "Are deleted" +msgstr "削除する" + +#: ../../po/../src/dialogs/display-settings.cpp:1273 +msgid "Orphaned clones are deleted along with their original." +msgstr "オリジナルと一緒に削除する" + +#. Transforms +#. TRANSLATORS: Noun, i.e. transformations. +#: ../../po/../src/dialogs/display-settings.cpp:1289 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:61 +msgid "Transforms" +msgstr "変形" + +#: ../../po/../src/dialogs/display-settings.cpp:1292 +msgid "Scale stroke width" +msgstr "線の幅を拡大/縮小" + +#: ../../po/../src/dialogs/display-settings.cpp:1293 +#: ../../po/../src/widgets/select-toolbar.cpp:568 +msgid "When scaling objects, scale the stroke width by the same proportion" +msgstr "オブジェクトの拡大/縮小に合わせて線幅も拡大/縮小する" + +#: ../../po/../src/dialogs/display-settings.cpp:1300 +msgid "Scale rounded corners in rectangles" +msgstr "角のまるみを同期" + +#: ../../po/../src/dialogs/display-settings.cpp:1301 +#: ../../po/../src/widgets/select-toolbar.cpp:580 +msgid "When scaling rectangles, scale the radii of rounded corners" +msgstr "オブジェクトの変形に角のまるみを同期させる" + +#: ../../po/../src/dialogs/display-settings.cpp:1308 +msgid "Transform gradients" +msgstr "グラデーションを同期" + +#: ../../po/../src/dialogs/display-settings.cpp:1309 +#: ../../po/../src/widgets/select-toolbar.cpp:592 +msgid "Transform gradients (in fill or stroke) along with the objects" +msgstr "オブジェクトの変形にグラデーションを同期させる" + +#: ../../po/../src/dialogs/display-settings.cpp:1316 +msgid "Transform patterns" +msgstr "パターンを同期" + +#: ../../po/../src/dialogs/display-settings.cpp:1317 +#: ../../po/../src/widgets/select-toolbar.cpp:604 +msgid "Transform patterns (in fill or stroke) along with the objects" +msgstr "オブジェクトの変形にパターンを同期させる" + +#. TRANSLATORS: How to specify the affine transformation in the SVG file. +#: ../../po/../src/dialogs/display-settings.cpp:1327 +msgid "Store transformation:" +msgstr "オブジェクト変形方法:" + +#: ../../po/../src/dialogs/display-settings.cpp:1338 +msgid "Optimized" +msgstr "transform属性を使わない" + +#: ../../po/../src/dialogs/display-settings.cpp:1339 +msgid "" +"If possible, apply transformation to objects without adding a transform= " +"attribute" +msgstr "transform属性を使わないでオブジェクトを変形する" + +#: ../../po/../src/dialogs/display-settings.cpp:1346 +msgid "Preserved" +msgstr "transform属性を使う" + +#: ../../po/../src/dialogs/display-settings.cpp:1347 +msgid "Always store transformation as a transform= attribute on objects" +msgstr "transform属性をつかってオブジェクトを変形する" + +#. Selecting +#: ../../po/../src/dialogs/display-settings.cpp:1355 +msgid "Selecting" +msgstr "選択" + +#: ../../po/../src/dialogs/display-settings.cpp:1357 +msgid "Ctrl+A, Tab, Shift+Tab:" +msgstr "Ctrl+A, Tab, Shift+Tab:" + +#: ../../po/../src/dialogs/display-settings.cpp:1366 +msgid "Select only within current layer" +msgstr "現在のレイヤーのオブジェクトのみ選択" + +#: ../../po/../src/dialogs/display-settings.cpp:1367 +msgid "" +"Uncheck this to make keyboard selection commands work on objects in all " +"layers" +msgstr "チェックをはずすとすべてのレイヤーのオブジェクトを選択できる" + +#: ../../po/../src/dialogs/display-settings.cpp:1374 +msgid "Ignore hidden objects" +msgstr "隠されたオブジェクトを選択しない" + +#: ../../po/../src/dialogs/display-settings.cpp:1375 +msgid "" +"Uncheck this to be able to select objects that are hidden (either by " +"themselves or by being in a hidden group or layer)" +msgstr "チェックをはずすと隠されたオブジェクトを選択できる" + +#: ../../po/../src/dialogs/display-settings.cpp:1382 +msgid "Ignore locked objects" +msgstr "ロックされたオブジェクトを選択しない" + +#: ../../po/../src/dialogs/display-settings.cpp:1383 +msgid "" +"Uncheck this to be able to select objects that are locked (either by " +"themselves or by being in a locked group or layer)" +msgstr "チェックをはずすとロックされたオブジェクトを選択できる" + +#. To be broken into: Display, Save, Export, SVG, Commands +#: ../../po/../src/dialogs/display-settings.cpp:1391 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:62 +msgid "Misc" +msgstr "その他" + +#: ../../po/../src/dialogs/display-settings.cpp:1394 +msgid "Default export resolution:" +msgstr "エクスポートのデフォルト解像度:" + +#: ../../po/../src/dialogs/display-settings.cpp:1395 +msgid "Default bitmap resolution (in dots per inch) in the Export dialog" +msgstr "エクスポートのデフォルト解像度(インチあたりのドット数)" + +#. FIXME: add "Used for new exports; once exported, documents remember this value on per-object basis" when implemented +#: ../../po/../src/dialogs/display-settings.cpp:1396 +#: ../../po/../src/dialogs/export.cpp:442 +msgid "dpi" +msgstr "dpi" + +#. TRANSLATORS: When on, an imported bitmap creates an element; otherwise it is a +#. * rectangle with bitmap fill. +#: ../../po/../src/dialogs/display-settings.cpp:1407 +msgid "Import bitmap as " +msgstr "要素としてビットマップをインポート" + +#: ../../po/../src/dialogs/display-settings.cpp:1408 +msgid "" +"When on, an imported bitmap creates an element; otherwise it is a " +"rectangle with bitmap fill" +msgstr "ビットマップのインポート時に要素を作成" + +#. TRANSLATORS: When on, the print out (currently Postscript) will have +#. * a comment with the each object's label visible, marking the section +#. * of the printing commands that represent the given object. +#: ../../po/../src/dialogs/display-settings.cpp:1418 +msgid "Add label comments to printing output" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1419 +msgid "" +"When on, a comment will be added to the raw print output, marking the " +"rendered output for an object with its label" +msgstr "" + +#. TRANSLATORS: When on, enable the effects menu, default is off +#: ../../po/../src/dialogs/display-settings.cpp:1427 +msgid "Enable script effects (requires restart) - EXPERIMENTAL" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1428 +msgid "" +"When on, the effects menu is enabled, allowing external effect scripts to be " +"called, requires restart before effective - EXPERIMENTAL" +msgstr "" + +#. TRANSLATORS: The maximum length of the Open Recent list in the File menu. +#: ../../po/../src/dialogs/display-settings.cpp:1436 +msgid "Max recent documents:" +msgstr "[最近開いたファイル]の最大値:" + +#: ../../po/../src/dialogs/display-settings.cpp:1437 +msgid "The maximum length of the Open Recent list in the File menu" +msgstr "[最近開いたファイル]リストの最大表示数" + +#: ../../po/../src/dialogs/display-settings.cpp:1447 +msgid "Simplification threshold:" +msgstr "[パスの簡略化]の閾値" + +#: ../../po/../src/dialogs/display-settings.cpp:1448 +msgid "" +"How strong is the Simplify command by default. If you invoke this command " +"several times in quick succession, it will act more and more aggressively; " +"invoking it again after a pause restores the default threshold." +msgstr "[パスの簡略化]の強さ。繰り返し使用時、どこまで適用されるか" + +#: ../../po/../src/dialogs/display-settings.cpp:1469 +msgid "Oversample bitmaps:" +msgstr "オーバーサンプルビットマップ:" + +#: ../../po/../src/dialogs/display-settings.cpp:1488 +msgid "2x2" +msgstr "2x2" + +#: ../../po/../src/dialogs/display-settings.cpp:1494 +msgid "4x4" +msgstr "4x4" + +#: ../../po/../src/dialogs/display-settings.cpp:1500 +msgid "8x8" +msgstr "8x8" + +#: ../../po/../src/dialogs/display-settings.cpp:1506 +msgid "16x16" +msgstr "16x16" + +#. "view_icon_preview" +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2143 +msgid "_Page" +msgstr "ページ" + +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2147 +msgid "_Drawing" +msgstr "描画" + +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2149 +msgid "_Selection" +msgstr "選択" + +#: ../../po/../src/dialogs/export.cpp:133 +msgid "_Custom" +msgstr "カスタム(_C)" + +#: ../../po/../src/dialogs/export.cpp:254 +msgid "Export area" +msgstr "指定範囲を出力" + +#: ../../po/../src/dialogs/export.cpp:300 +msgid "_x0:" +msgstr "_x0:" + +#: ../../po/../src/dialogs/export.cpp:305 +msgid "x_1:" +msgstr "x_1:" + +#: ../../po/../src/dialogs/export.cpp:316 +msgid "_y0:" +msgstr "_y0:" + +#: ../../po/../src/dialogs/export.cpp:321 +msgid "y_1:" +msgstr "y_1:" + +#: ../../po/../src/dialogs/export.cpp:406 +msgid "Bitmap size" +msgstr "ビットマップサイズ" + +#: ../../po/../src/dialogs/export.cpp:416 +msgid "_Width:" +msgstr "幅(_W):" + +#: ../../po/../src/dialogs/export.cpp:416 +#: ../../po/../src/dialogs/export.cpp:431 +msgid "pixels at" +msgstr "ピクセル" + +#: ../../po/../src/dialogs/export.cpp:426 +msgid "dp_i" +msgstr "dp_i" + +#: ../../po/../src/dialogs/export.cpp:448 +msgid "_Filename" +msgstr "ファイル名(_F)" + +#: ../../po/../src/dialogs/export.cpp:512 +msgid "_Browse..." +msgstr "参照(_B)..." + +#: ../../po/../src/dialogs/export.cpp:539 +msgid " _Export " +msgstr " エクスポート(_E) " + +#: ../../po/../src/dialogs/export.cpp:541 +msgid "Export the bitmap file with these settings" +msgstr "この設定でビットマップファイルにエクスポートする" + +#: ../../po/../src/dialogs/export.cpp:968 +msgid "You have to enter a filename" +msgstr "ファイル名を入力してください" + +#: ../../po/../src/dialogs/export.cpp:973 +msgid "The chosen area to be exported is invalid" +msgstr "指定された範囲のエクスポートはできません" + +#: ../../po/../src/dialogs/export.cpp:982 +#, c-format +msgid "Directory %s does not exist or is not a directory.\n" +msgstr "%s は存在しないか、ディレクトリではありません。\n" + +#: ../../po/../src/dialogs/export.cpp:998 +msgid "Export in progress" +msgstr "エクスポートの進捗" + +#: ../../po/../src/dialogs/export.cpp:1004 +#, c-format +msgid "Exporting %s (%d x %d)" +msgstr "エクスポート %s (%d x %d)" + +#: ../../po/../src/dialogs/export.cpp:1031 +#, c-format +msgid "Could not export to filename %s.\n" +msgstr "%sにエクスポートできませんでした。\n" + +#: ../../po/../src/dialogs/export.cpp:1137 +msgid "Select a filename for exporting" +msgstr "エクスポートするファイルを選択" + +#: ../../po/../src/dialogs/filedialog.cpp:367 +msgid "No preview" +msgstr "プレビューなし" + +#: ../../po/../src/dialogs/filedialog.cpp:468 +msgid "too large for preview" +msgstr "プレビューには大きすぎます。" + +#: ../../po/../src/dialogs/filedialog.cpp:762 +#: ../../po/../src/dialogs/filedialog.cpp:763 +msgid "All Images" +msgstr "全ての画像" + +#: ../../po/../src/dialogs/filedialog.cpp:767 +#: ../../po/../src/dialogs/filedialog.cpp:768 +msgid "All Files" +msgstr "全てのファイル" + +#: ../../po/../src/dialogs/filedialog.cpp:774 +#: ../../po/../src/dialogs/filedialog.cpp:775 +msgid "All Inkscape Files" +msgstr "全てのInkscapeファイル" + +#: ../../po/../src/dialogs/filedialog.cpp:1176 +msgid "Guess from extension" +msgstr "拡張子で判断" + +#. ###### Add the file types menu +#. createFilterMenu(); +#. ###### Do we want the .xxx extension automatically added? +#: ../../po/../src/dialogs/filedialog.cpp:1261 +msgid "Append filename extension automatically" +msgstr "自動的に拡張子を追加" + +#. TRANSLATORS: "%s" is replaced with "exact" or "partial" when this string is displayed +#: ../../po/../src/dialogs/find.cpp:378 +#, c-format +msgid "%d object found (out of %d), %s match." +msgid_plural "%d objects found (out of %d), %s match." +msgstr[0] "%d個のオブジェクトが見付かりました。(検索対象: %d個) %s一致" +msgstr[1] "%d個のオブジェクトが見付かりました。(検索対象: %d個) %s一致" + +#: ../../po/../src/dialogs/find.cpp:381 +msgid "exact" +msgstr "完全" + +#: ../../po/../src/dialogs/find.cpp:381 +msgid "partial" +msgstr "一部" + +#: ../../po/../src/dialogs/find.cpp:388 +msgid "No objects found" +msgstr "オブジェクトが見付かりませんでした" + +#: ../../po/../src/dialogs/find.cpp:546 +msgid "T_ype: " +msgstr "タイプ:" + +#: ../../po/../src/dialogs/find.cpp:553 +msgid "Search in all object types" +msgstr "全てのオブジェクトタイプから検索" + +#: ../../po/../src/dialogs/find.cpp:553 +msgid "All types" +msgstr "全てのタイプ" + +#: ../../po/../src/dialogs/find.cpp:564 +msgid "Search all shapes" +msgstr "全てのシェイプから検索" + +#: ../../po/../src/dialogs/find.cpp:564 +msgid "All shapes" +msgstr "全てのシェイプツール" + +#: ../../po/../src/dialogs/find.cpp:581 +msgid "Search rectangles" +msgstr "矩形を検索" + +#: ../../po/../src/dialogs/find.cpp:581 +msgid "Rectangles" +msgstr "矩形" + +#: ../../po/../src/dialogs/find.cpp:586 +msgid "Search ellipses, arcs, circles" +msgstr "楕・円を検索" + +#: ../../po/../src/dialogs/find.cpp:586 +msgid "Ellipses" +msgstr "楕円" + +#: ../../po/../src/dialogs/find.cpp:591 +msgid "Search stars and polygons" +msgstr "星型やポリゴンを検索" + +#: ../../po/../src/dialogs/find.cpp:591 +msgid "Stars" +msgstr "星" + +#: ../../po/../src/dialogs/find.cpp:596 +msgid "Search spirals" +msgstr "螺旋を検索" + +#: ../../po/../src/dialogs/find.cpp:596 +msgid "Spirals" +msgstr "螺旋" + +#. TRANSLATORS: polyline is a set of connected straight line segments +#. http://www.w3.org/TR/SVG11/shapes.html#PolylineElement +#: ../../po/../src/dialogs/find.cpp:609 +msgid "Search paths, lines, polylines" +msgstr "パスや線を検索" + +#: ../../po/../src/dialogs/find.cpp:609 +msgid "Paths" +msgstr "パス" + +#: ../../po/../src/dialogs/find.cpp:614 +msgid "Search text objects" +msgstr "テキストを検索" + +#: ../../po/../src/dialogs/find.cpp:614 +msgid "Texts" +msgstr "テキスト" + +#: ../../po/../src/dialogs/find.cpp:619 +msgid "Search groups" +msgstr "グループを検索" + +#: ../../po/../src/dialogs/find.cpp:619 +msgid "Groups" +msgstr "グループ" + +#: ../../po/../src/dialogs/find.cpp:624 +msgid "Search clones" +msgstr "クローンを検索" + +#: ../../po/../src/dialogs/find.cpp:629 +msgid "Search images" +msgstr "画像を検索" + +#: ../../po/../src/dialogs/find.cpp:629 +msgid "Images" +msgstr "画像" + +#: ../../po/../src/dialogs/find.cpp:634 +msgid "Search offset objects" +msgstr "オフセットオブジェクトを検索" + +#: ../../po/../src/dialogs/find.cpp:634 +msgid "Offsets" +msgstr "オフセット" + +#: ../../po/../src/dialogs/find.cpp:694 +msgid "_Text: " +msgstr "テキスト: " + +#: ../../po/../src/dialogs/find.cpp:694 +msgid "Find objects by their text content (exact or partial match)" +msgstr "含まれる文字列で検索" + +#: ../../po/../src/dialogs/find.cpp:695 +msgid "_ID: " +msgstr "_ID: " + +#: ../../po/../src/dialogs/find.cpp:695 +msgid "Find objects by the value of the id attribute (exact or partial match)" +msgstr "IDで検索(完全/一部一致)" + +#: ../../po/../src/dialogs/find.cpp:696 +msgid "_Style: " +msgstr "スタイル: " + +#: ../../po/../src/dialogs/find.cpp:696 +msgid "" +"Find objects by the value of the style attribute (exact or partial match)" +msgstr "スタイルで検索(完全/一部一致)" + +#: ../../po/../src/dialogs/find.cpp:697 +msgid "_Attribute: " +msgstr "属性: " + +#: ../../po/../src/dialogs/find.cpp:697 +msgid "Find objects by the name of an attribute (exact or partial match)" +msgstr "名前で検索(完全/一部一致)" + +#: ../../po/../src/dialogs/find.cpp:711 +msgid "Search in s_election" +msgstr "選択オブジェクトから検索" + +#: ../../po/../src/dialogs/find.cpp:715 +msgid "Limit search to the current selection" +msgstr "選択したなかから検索" + +#: ../../po/../src/dialogs/find.cpp:720 +msgid "Search in current _layer" +msgstr "現在のレイヤー上を検索" + +#: ../../po/../src/dialogs/find.cpp:724 +msgid "Limit search to the current layer" +msgstr "検索対象を現在のレイヤー上に限定" + +#: ../../po/../src/dialogs/find.cpp:729 +msgid "Include _hidden" +msgstr "非表示のオブジェクトを含む" + +#: ../../po/../src/dialogs/find.cpp:733 +msgid "Include hidden objects in search" +msgstr "非表示のオブジェクトを検索対象にする" + +#: ../../po/../src/dialogs/find.cpp:738 +msgid "Include l_ocked" +msgstr "ロックされたオブジェクトを含む" + +#: ../../po/../src/dialogs/find.cpp:742 +msgid "Include locked objects in search" +msgstr "ロックされたオブジェクトを検索対象にする" + +#: ../../po/../src/dialogs/find.cpp:753 +msgid "Clear values" +msgstr "値をクリア" + +#: ../../po/../src/dialogs/find.cpp:754 +msgid "_Find" +msgstr "検索" + +#: ../../po/../src/dialogs/find.cpp:754 +msgid "Select objects matching all of the fields you filled in" +msgstr "入力した項目を対象に検索" + +#: ../../po/../src/dialogs/iconpreview.cpp:145 +#, c-format +msgid "%d x %d" +msgstr "" + +#: ../../po/../src/dialogs/iconpreview.cpp:193 +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:857 +#: ../../po/../src/widgets/desktop-widget.cpp:1069 +msgid "Selection" +msgstr "選択" + +#: ../../po/../src/dialogs/iconpreview.cpp:195 +msgid "Selection only or whole document" +msgstr "現在のレイヤーのオブジェクトを全て選択" + +#: ../../po/../src/dialogs/iconpreview.cpp:203 +msgid "Refresh the icons" +msgstr "アイコンをリフレッシュ" + +#. Create the label for the object id +#: ../../po/../src/dialogs/item-properties.cpp:126 +#: ../../po/../src/dialogs/item-properties.cpp:327 +#: ../../po/../src/dialogs/item-properties.cpp:396 +#: ../../po/../src/dialogs/item-properties.cpp:403 +msgid "_Id" +msgstr "ID(_I)" + +#: ../../po/../src/dialogs/item-properties.cpp:135 +msgid "" +"The id= attribute (only letters, digits, and the characters .-_: allowed)" +msgstr "ID属性 (文字、数字、.-_:が使用可能)" + +#. Button for setting the object's id, label, title and description. +#: ../../po/../src/dialogs/item-properties.cpp:149 +msgid "_Set" +msgstr "セット(_S)" + +#. Create the label for the object label +#: ../../po/../src/dialogs/item-properties.cpp:158 +msgid "_Label" +msgstr "ラベル(_L)" + +#: ../../po/../src/dialogs/item-properties.cpp:167 +msgid "A freeform label for the object" +msgstr "任意のラベル" + +#. Create the label for the object title +#: ../../po/../src/dialogs/item-properties.cpp:179 +#: ../../po/../src/dialogs/rdf.cpp:243 +msgid "Title" +msgstr "タイトル" + +#. Create the frame for the object description +#: ../../po/../src/dialogs/item-properties.cpp:196 +#: ../../po/../src/dialogs/rdf.cpp:287 +msgid "Description" +msgstr "記述" + +#. Hide +#: ../../po/../src/dialogs/item-properties.cpp:223 +msgid "_Hide" +msgstr "隠す(_H)" + +#: ../../po/../src/dialogs/item-properties.cpp:224 +msgid "Check to make the object invisible" +msgstr "オブジェクトを隠す" + +#. Lock +#. TRANSLATORS: "Lock" is a verb here +#: ../../po/../src/dialogs/item-properties.cpp:233 +msgid "L_ock" +msgstr "ロック(_O)" + +#: ../../po/../src/dialogs/item-properties.cpp:234 +msgid "Check to make the object insensitive (not selectable by mouse)" +msgstr "マウスで選択できなくする" + +#: ../../po/../src/dialogs/item-properties.cpp:310 +#: ../../po/../src/dialogs/item-properties.cpp:317 +msgid "Ref" +msgstr "リファレンス" + +#: ../../po/../src/dialogs/item-properties.cpp:398 +msgid "Id invalid! " +msgstr "無効なIDです!" + +#: ../../po/../src/dialogs/item-properties.cpp:400 +msgid "Id exists! " +msgstr "存在するIDです!" + +#: ../../po/../src/dialogs/layer-properties.cpp:50 +msgid "Layer name:" +msgstr "レイヤー名:" + +#: ../../po/../src/dialogs/layer-properties.cpp:133 +msgid "Rename Layer" +msgstr "レイヤーの名前を編集" + +#: ../../po/../src/dialogs/layer-properties.cpp:136 +msgid "_Rename" +msgstr "レイヤー名を変更" + +#. TRANSLATORS: This means "The layer has been renamed" +#: ../../po/../src/dialogs/layer-properties.cpp:147 +msgid "Renamed layer" +msgstr "レイヤーの名前を変更しました" + +#: ../../po/../src/dialogs/layer-properties.cpp:151 +msgid "Add Layer" +msgstr "レイヤー(_L)" + +#: ../../po/../src/dialogs/layer-properties.cpp:153 +msgid "_Add" +msgstr "追加(_A)" + +#: ../../po/../src/dialogs/layer-properties.cpp:167 +msgid "New layer created." +msgstr "新しいレイヤーを作成しました。" + +#: ../../po/../src/dialogs/object-attributes.cpp:34 +msgid "Href:" +msgstr "ハイパーリンク:" + +#: ../../po/../src/dialogs/object-attributes.cpp:35 +msgid "Target:" +msgstr "ターゲット:" + +#: ../../po/../src/dialogs/object-attributes.cpp:36 +msgid "Type:" +msgstr "タイプ:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkRoleAttribute +#. Identifies the type of the related resource with an absolute URI +#: ../../po/../src/dialogs/object-attributes.cpp:39 +msgid "Role:" +msgstr "ロール:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkArcRoleAttribute +#. For situations where the nature/role alone isn't enough, this offers an additional URI defining the purpose of the link. +#: ../../po/../src/dialogs/object-attributes.cpp:42 +msgid "Arcrole:" +msgstr "アークロール:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkTitleAttribute +#: ../../po/../src/dialogs/object-attributes.cpp:44 +msgid "Title:" +msgstr "タイトル:" + +#: ../../po/../src/dialogs/object-attributes.cpp:45 +msgid "Show:" +msgstr "表示:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkActuateAttribute +#: ../../po/../src/dialogs/object-attributes.cpp:47 +msgid "Actuate:" +msgstr "アクチュエート:" + +#: ../../po/../src/dialogs/object-attributes.cpp:52 +msgid "URL:" +msgstr "URL:" + +#: ../../po/../src/dialogs/object-attributes.cpp:53 +msgid "X:" +msgstr "X:" + +#: ../../po/../src/dialogs/object-attributes.cpp:54 +msgid "Y:" +msgstr "Y:" + +#: ../../po/../src/dialogs/object-attributes.cpp:98 +#, c-format +msgid "%s attributes" +msgstr "%sの属性" + +#: ../../po/../src/dialogs/object-properties.cpp:158 +msgid "_Fill" +msgstr "フィル(_F)" + +#: ../../po/../src/dialogs/object-properties.cpp:165 +msgid "Stroke _paint" +msgstr "ストロークペイント(_P)" + +#: ../../po/../src/dialogs/object-properties.cpp:172 +msgid "Stroke st_yle" +msgstr "ストロークスタイル(_Y)" + +#: ../../po/../src/dialogs/object-properties.cpp:183 +msgid "Master _opacity" +msgstr "透過性(_O)" + +#: ../../po/../src/dialogs/rdf.cpp:244 +msgid "Name by which this document is formally known." +msgstr "正式なドキュメントの名前" + +#: ../../po/../src/dialogs/rdf.cpp:246 +msgid "Date" +msgstr "日付" + +#: ../../po/../src/dialogs/rdf.cpp:247 +msgid "Date associated with the creation of this document (YYYY-MM-DD)." +msgstr "作成日(YYYY-MM-DD)" + +#: ../../po/../src/dialogs/rdf.cpp:249 +msgid "Format" +msgstr "フォーマット" + +#: ../../po/../src/dialogs/rdf.cpp:250 +msgid "The physical or digital manifestation of this document (MIME type)." +msgstr "MIMEタイプ" + +#: ../../po/../src/dialogs/rdf.cpp:252 +msgid "Type" +msgstr "タイプ" + +#: ../../po/../src/dialogs/rdf.cpp:253 +msgid "Type of document (DCMI Type)." +msgstr "ドキュメントタイプ(DCMIタイプ)" + +#: ../../po/../src/dialogs/rdf.cpp:256 +msgid "Creator" +msgstr "作成者" + +#: ../../po/../src/dialogs/rdf.cpp:257 +msgid "" +"Name of entity primarily responsible for making the content of this document." +msgstr "作成者名" + +#: ../../po/../src/dialogs/rdf.cpp:259 +msgid "Rights" +msgstr "権利者" + +#: ../../po/../src/dialogs/rdf.cpp:260 +msgid "" +"Name of entity with rights to the Intellectual Property of this document." +msgstr "権利者名" + +#: ../../po/../src/dialogs/rdf.cpp:262 +msgid "Publisher" +msgstr "発行者" + +#: ../../po/../src/dialogs/rdf.cpp:263 +msgid "Name of entity responsible for making this document available." +msgstr "発行者名" + +#: ../../po/../src/dialogs/rdf.cpp:266 +msgid "Identifier" +msgstr "識別子" + +#: ../../po/../src/dialogs/rdf.cpp:267 +msgid "Unique URI to reference this document." +msgstr "URL" + +#: ../../po/../src/dialogs/rdf.cpp:269 +msgid "Source" +msgstr "ソース" + +#: ../../po/../src/dialogs/rdf.cpp:270 +msgid "Unique URI to reference the source of this document." +msgstr "ソースへのURL" + +#: ../../po/../src/dialogs/rdf.cpp:272 +msgid "Relation" +msgstr "関連" + +#: ../../po/../src/dialogs/rdf.cpp:273 +msgid "Unique URI to a related document." +msgstr "関連URL" + +#: ../../po/../src/dialogs/rdf.cpp:275 +msgid "Language" +msgstr "言語" + +#: ../../po/../src/dialogs/rdf.cpp:276 +msgid "" +"Two-letter language tag with optional subtags for the language of this " +"document. (e.g. 'en-GB')" +msgstr "言語(eg ’ja_JP')" + +#: ../../po/../src/dialogs/rdf.cpp:278 +msgid "Keywords" +msgstr "キーワード" + +#: ../../po/../src/dialogs/rdf.cpp:279 +msgid "" +"The topic of this document as comma-separated key words, phrases, or " +"classifications." +msgstr "ドキュメントに関するキーワードまたは分類(カンマ区切りで書く)" + +#. TRANSLATORS: "Coverage": the spatial or temporal characteristics of the content. +#. For info, see Appendix D of http://www.w3.org/TR/1998/WD-rdf-schema-19980409/ +#: ../../po/../src/dialogs/rdf.cpp:283 +msgid "Coverage" +msgstr "適用範囲" + +#: ../../po/../src/dialogs/rdf.cpp:284 +msgid "Extent or scope of this document." +msgstr "ドキュメントのスコープの範囲" + +#: ../../po/../src/dialogs/rdf.cpp:288 +msgid "A short account of the content of this document." +msgstr "ドキュメントに関するコメントなど" + +#. FIXME: need to handle 1 agent per line of input +#: ../../po/../src/dialogs/rdf.cpp:292 +msgid "Contributors" +msgstr "貢献者" + +#: ../../po/../src/dialogs/rdf.cpp:293 +msgid "" +"Names of entities responsible for making contributions to the content of " +"this document." +msgstr "ドキュメント作成の貢献者名" + +#. TRANSLATORS: URL to a page that defines the license for the document +#: ../../po/../src/dialogs/rdf.cpp:297 +msgid "URI" +msgstr "URI" + +#. TRANSLATORS: this is where you put a URL to a page that defines the license +#: ../../po/../src/dialogs/rdf.cpp:299 +msgid "URI to this document's license's namespace definition." +msgstr "ドキュメントのライセンスのURI" + +#. TRANSLATORS: fragment of XML representing the license of the document +#: ../../po/../src/dialogs/rdf.cpp:303 +msgid "Fragment" +msgstr "フラグメント" + +#: ../../po/../src/dialogs/rdf.cpp:304 +msgid "XML fragment for the RDF 'License' section." +msgstr "RDFのライセンスの断片" + +#: ../../po/../src/dialogs/stroke-style.cpp:774 +#: ../../po/../src/widgets/gradient-vector.cpp:263 +#: ../../po/../src/widgets/paint-selector.cpp:751 +msgid "No document selected" +msgstr "ドキュメントが選択されていません" + +#: ../../po/../src/dialogs/stroke-style.cpp:992 +msgid "Stroke width" +msgstr "線の幅" + +#. Join type +#. TRANSLATORS: The line join style specifies the shape to be used at the +#. corners of paths. It can be "miter", "round" or "bevel". +#: ../../po/../src/dialogs/stroke-style.cpp:1015 +msgid "Join:" +msgstr "結合:" + +#. TRANSLATORS: Miter join: joining lines with a sharp (pointed) corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1027 +msgid "Miter join" +msgstr "角" + +#. TRANSLATORS: Round join: joining lines with a rounded corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1035 +msgid "Round join" +msgstr "丸" + +#. TRANSLATORS: Bevel join: joining lines with a blunted (flattened) corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1043 +msgid "Bevel join" +msgstr "斜" + +#. Miterlimit +#. TRANSLATORS: Miter limit: only for "miter join", this limits the length +#. of the sharp "spike" when the lines connect at too sharp an angle. +#. When two line segments meet at a sharp angle, a miter join results in a +#. spike that extends well beyond the connection point. The purpose of the +#. miter limit is to cut off such spikes (i.e. convert them into bevels) +#. when they become too long. +#: ../../po/../src/dialogs/stroke-style.cpp:1054 +msgid "Miter limit:" +msgstr "連結リミット" + +#: ../../po/../src/dialogs/stroke-style.cpp:1062 +msgid "Maximum length of the miter (in units of stroke width)" +msgstr "線をつなぐ限界の長さ(線幅を基準として)" + +#. Cap type +#. TRANSLATORS: cap type specifies the shape for the ends of lines +#: ../../po/../src/dialogs/stroke-style.cpp:1075 +msgid "Cap:" +msgstr "端:" + +#. TRANSLATORS: Butt cap: the line shape does not extend beyond the end point +#. of the line; the ends of the line are square +#: ../../po/../src/dialogs/stroke-style.cpp:1086 +msgid "Butt cap" +msgstr "角" + +#. TRANSLATORS: Round cap: the line shape extends beyond the end point of the +#. line; the ends of the line are rounded +#: ../../po/../src/dialogs/stroke-style.cpp:1093 +msgid "Round cap" +msgstr "丸" + +#. TRANSLATORS: Square cap: the line shape extends beyond the end point of the +#. line; the ends of the line are square +#: ../../po/../src/dialogs/stroke-style.cpp:1100 +msgid "Square cap" +msgstr "四角" + +#. Dash +#: ../../po/../src/dialogs/stroke-style.cpp:1106 +msgid "Dashes:" +msgstr "点線:" + +#. TRANSLATORS: Path markers are an SVG feature that allows you to attach arbitrary shapes +#. (arrowheads, bullets, faces, whatever) to the start, end, or middle nodes of a path. +#: ../../po/../src/dialogs/stroke-style.cpp:1127 +msgid "Start Markers:" +msgstr "先端" + +#: ../../po/../src/dialogs/stroke-style.cpp:1137 +msgid "Mid Markers:" +msgstr "中心" + +#: ../../po/../src/dialogs/stroke-style.cpp:1148 +msgid "End Markers:" +msgstr "終端" + +#: ../../po/../src/dialogs/swatches.cpp:424 +#, c-format +msgid "Palettes directory (%s) is unavailable." +msgstr "" + +#. TODO: Insert widgets +#: ../../po/../src/dialogs/text-edit.cpp:199 +#: ../../po/../src/ui/dialog/text-properties.cpp:36 +msgid "Font" +msgstr "フォント" + +#: ../../po/../src/dialogs/text-edit.cpp:216 +msgid "Layout" +msgstr "レイアウト" + +#: ../../po/../src/dialogs/text-edit.cpp:229 +msgid "Align lines left" +msgstr "左に整列" + +#. TRANSLATORS: `Center' here is a verb. +#: ../../po/../src/dialogs/text-edit.cpp:243 +msgid "Center lines" +msgstr "中心線" + +#: ../../po/../src/dialogs/text-edit.cpp:256 +msgid "Align lines right" +msgstr "右に整列" + +#: ../../po/../src/dialogs/text-edit.cpp:278 +msgid "Horizontal text" +msgstr "横書" + +#: ../../po/../src/dialogs/text-edit.cpp:292 +msgid "Vertical text" +msgstr "縦書" + +#: ../../po/../src/dialogs/text-edit.cpp:307 +msgid "Line spacing:" +msgstr "線の間隔:" + +#: ../../po/../src/dialogs/text-edit.cpp:400 +msgid "Set as default" +msgstr "デフォルトに設定" + +#: ../../po/../src/dialogs/tiledialog.cpp:603 +msgid "Rows:" +msgstr "行:" + +#: ../../po/../src/dialogs/tiledialog.cpp:613 +msgid "Number of rows" +msgstr "行数" + +#: ../../po/../src/dialogs/tiledialog.cpp:617 +msgid "Equal height" +msgstr "等高" + +#: ../../po/../src/dialogs/tiledialog.cpp:627 +msgid "If not set, each row has the height of the tallest object in it" +msgstr "" + +#. #### Radio buttons to control vertical alignment #### +#. #### Radio buttons to control horizontal alignment #### +#: ../../po/../src/dialogs/tiledialog.cpp:637 +#: ../../po/../src/dialogs/tiledialog.cpp:708 +msgid "Align:" +msgstr "整列" + +#: ../../po/../src/dialogs/tiledialog.cpp:672 +msgid " X " +msgstr " X" + +#. #### Number of columns #### +#: ../../po/../src/dialogs/tiledialog.cpp:678 +msgid "Columns:" +msgstr "列:" + +#: ../../po/../src/dialogs/tiledialog.cpp:688 +msgid "Number of columns" +msgstr "列数" + +#: ../../po/../src/dialogs/tiledialog.cpp:692 +msgid "Equal width" +msgstr "等幅" + +#: ../../po/../src/dialogs/tiledialog.cpp:701 +msgid "If not set, each column has the width of the widest object in it" +msgstr "" + +#. #### Radio buttons to control spacing manually or to fit selection bbox #### +#: ../../po/../src/dialogs/tiledialog.cpp:746 +msgid "Fit into selection box" +msgstr "選択オブジェクトにフィット" + +#: ../../po/../src/dialogs/tiledialog.cpp:753 +msgid "Set spacing:" +msgstr "間隔:" + +#. #### Y Padding #### +#: ../../po/../src/dialogs/tiledialog.cpp:777 +msgid "Row spacing: " +msgstr "行間: " + +#: ../../po/../src/dialogs/tiledialog.cpp:786 +msgid "Vertical spacing between rows" +msgstr "行間の縦幅" + +#. #### X padding #### +#: ../../po/../src/dialogs/tiledialog.cpp:795 +msgid "Column spacing:" +msgstr "行の間隔:" + +#: ../../po/../src/dialogs/tiledialog.cpp:804 +#, fuzzy +msgid "Horizontal spacing between columns" +msgstr "各列の水平方向の変化度" + +#: ../../po/../src/dialogs/tiledialog.cpp:818 +#, fuzzy +msgid "Arrange selected objects" +msgstr "選択したオブジェクトをグループ化" + +#: ../../po/../src/dialogs/xml-tree.cpp:178 +msgid "Click to select nodes, drag to rearrange." +msgstr "クリック: ノードを選択、または編集" + +#: ../../po/../src/dialogs/xml-tree.cpp:189 +msgid "Click attribute to edit." +msgstr "クリック: 属性を選択、編集" + +#: ../../po/../src/dialogs/xml-tree.cpp:193 +#, c-format +msgid "" +"Attribute %s selected. Press Ctrl+Enter when done editing to " +"commit changes." +msgstr "%s属性を選択しています。Ctrl+Enterで反映させてください。" + +#: ../../po/../src/dialogs/xml-tree.cpp:284 +msgid "Drag to reorder nodes" +msgstr "再編成ノードへドラッグ" + +#: ../../po/../src/dialogs/xml-tree.cpp:304 +msgid "New element node" +msgstr "要素の新規作成" + +#: ../../po/../src/dialogs/xml-tree.cpp:326 +msgid "New text node" +msgstr "テキストノードの新規作成" + +#: ../../po/../src/dialogs/xml-tree.cpp:347 +msgid "Duplicate node" +msgstr "ノードを複製" + +#: ../../po/../src/dialogs/xml-tree.cpp:368 +msgid "Delete node" +msgstr "ノードの削除" + +#: ../../po/../src/dialogs/xml-tree.cpp:384 +msgid "Unindent node" +msgstr "ノードのインデントを除去" + +#: ../../po/../src/dialogs/xml-tree.cpp:399 +msgid "Indent node" +msgstr "ノードのインデント" + +#: ../../po/../src/dialogs/xml-tree.cpp:411 +msgid "Raise node" +msgstr "ノードを上げる" + +#: ../../po/../src/dialogs/xml-tree.cpp:423 +msgid "Lower node" +msgstr "ノードを下げる" + +#: ../../po/../src/dialogs/xml-tree.cpp:468 +msgid "Delete attribute" +msgstr "属性を削除" + +#. TRANSLATORS: "Attribute" is a noun here +#: ../../po/../src/dialogs/xml-tree.cpp:513 +msgid "Attribute name" +msgstr "属性名" + +#. TRANSLATORS: "Set" is a verb here +#: ../../po/../src/dialogs/xml-tree.cpp:533 +msgid "Set attribute" +msgstr "属性を追加" + +#. TRANSLATORS: "Set" is a verb here +#: ../../po/../src/dialogs/xml-tree.cpp:535 +msgid "Set" +msgstr "セット" + +#. TRANSLATORS: "Attribute" is a noun here +#: ../../po/../src/dialogs/xml-tree.cpp:558 +msgid "Attribute value" +msgstr "属性値" + +#: ../../po/../src/dialogs/xml-tree.cpp:1318 +msgid "New element node..." +msgstr "要素ノードの新規作成..." + +#: ../../po/../src/dialogs/xml-tree.cpp:1339 +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:100 +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:98 +msgid "Cancel" +msgstr "キャンセル" + +#: ../../po/../src/dialogs/xml-tree.cpp:1345 +msgid "Create" +msgstr "作成" + +#: ../../po/../src/dialogs/xml-tree.cpp:1458 +#, c-format +msgid "" +"Cannot set %s: Another element with value %s already exists!" +msgstr "%s属性をセットできませんでした。%sは既に存在します。" + +#: ../../po/../src/document.cpp:369 +#, c-format +msgid "New document %d" +msgstr "新規ドキュメント %d" + +#: ../../po/../src/document.cpp:401 +#, c-format +msgid "Memory document %d" +msgstr "メモリドキュメント %d" + +#: ../../po/../src/document.cpp:524 +#, c-format +msgid "Unnamed document %d" +msgstr "無題ドキュメント %d" + +#. We hit green anchor, closing Green-Blue-Red +#: ../../po/../src/draw-context.cpp:441 +msgid "Path is closed." +msgstr "パスは閉じています。" + +#. We hit bot start and end of single curve, closing paths +#: ../../po/../src/draw-context.cpp:456 +msgid "Closing path." +msgstr "閉じたパス" + +#. alpha of color under cursor, to show in the statusbar +#. locale-sensitive printf is OK, since this goes to the UI, not into SVG +#: ../../po/../src/dropper-context.cpp:354 +#, c-format +msgid " alpha %.3g" +msgstr " 透明度 %.3g" + +#. where the color is picked, to show in the statusbar +#: ../../po/../src/dropper-context.cpp:356 +#, c-format +msgid ", averaged with radius %d" +msgstr ", %dの円での平均値" + +#: ../../po/../src/dropper-context.cpp:356 +msgid " under cursor" +msgstr " (カーソル下の値)" + +#. message, to show in the statusbar +#: ../../po/../src/dropper-context.cpp:358 +msgid "Release mouse to set color." +msgstr "ボタンを離して色をセット" + +#: ../../po/../src/dropper-context.cpp:358 +#: ../../po/../src/tools-switch.cpp:207 +msgid "" +"Click to set fill, Shift+click to set stroke; drag to " +"average color in area; with Alt to pick inverse color; Ctrl+C " +"to copy the color under mouse to clipboard" +msgstr "" +"クリックでフィルカラーを、Shift+クリックでストロークカラーを、" +"ドラッグでドラッグした領域の色の平均を、Ctrl+Cでマウスポインタの位置の" +"色をクリップボードへコピー" + +#: ../../po/../src/extension/dependency.cpp:244 +msgid "Dependency::" +msgstr "依存度::" + +#: ../../po/../src/extension/dependency.cpp:245 +msgid " type: " +msgstr " タイプ: " + +#: ../../po/../src/extension/dependency.cpp:246 +msgid " location: " +msgstr "" + +#: ../../po/../src/extension/dependency.cpp:247 +msgid " string: " +msgstr "" + +#: ../../po/../src/extension/dependency.cpp:250 +msgid " description: " +msgstr " 記述: " + +#. static int i = 0; +#. std::cout << "Checking module[" << i++ << "]: " << name << std::endl; +#: ../../po/../src/extension/extension.cpp:244 +msgid "" +" This is caused by an improper .inx file for this extension. An improper ." +"inx file could have been caused by a faulty installation of Inkscape." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:247 +msgid "an ID was not defined for it." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:251 +msgid "there was no name defined for it." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:255 +msgid "the XML description of it got lost." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:259 +msgid "no implementation was defined for the extension." +msgstr "" + +#. std::cout << "Failed: " << *(_deps[i]) << std::endl; +#: ../../po/../src/extension/extension.cpp:266 +msgid "a dependency was not met." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:286 +msgid "Extension \"" +msgstr "エクステンション \"" + +#: ../../po/../src/extension/extension.cpp:286 +msgid "\" failed to load because " +msgstr "\" ロードに失敗しました" + +#: ../../po/../src/extension/extension.cpp:565 +#, c-format +msgid "Could not create extension error log file '%s'" +msgstr "拡張のエラーログ'%s'作成できません" + +#. This is some filler text, needs to change before relase +#: ../../po/../src/extension/error-file.cpp:56 +msgid "" +"One or more extensions failed to load\n" +"\n" +"The failed extensions have been skipped. Inkscape will continue to run " +"normally but those extensions will be unavailable. For details to " +"troubleshoot this problem, please refer to the error log located at: " +msgstr "" + +#. This is some filler text, needs to change before relase +#: ../../po/../src/extension/error-file.cpp:65 +msgid "Show dialog on startup" +msgstr "" + +#: ../../po/../src/extension/implementation/script.cpp:845 +msgid "" +"Inkscape has received an error from the script that it called. The text " +"returned with the error is included below. Inkscape will continue working, " +"but the action you requested has been cancelled." +msgstr "" + +#: ../../po/../src/extension/implementation/script.cpp:858 +msgid "" +"Inkscape has received additional data from the script executed. The script " +"did not return an error, but this may indicate the results will not be as " +"expected." +msgstr "" + +#: ../../po/../src/extension/init.cpp:173 +#, fuzzy +msgid "Null external module directory name. Modules will not be loaded." +msgstr "" +"モジュールのディレクトリ%sにアクセスできません。外部モジュールはロードされま" +"せん。" + +#: ../../po/../src/extension/init.cpp:187 +#, fuzzy, c-format +msgid "" +"Modules directory (%s) is unavailable. External modules in that directory " +"will not be loaded." +msgstr "" +"モジュールのディレクトリ%sにアクセスできません。外部モジュールはロードされま" +"せん。" + +#: ../../po/../src/extension/internal/gnome.cpp:80 +msgid "Select printer" +msgstr "プリンタの選択" + +#: ../../po/../src/extension/internal/gnome.cpp:131 +msgid "Inkscape: Print Preview" +msgstr "Inkscape: 印刷プレビュー" + +#: ../../po/../src/extension/internal/grid.cpp:213 +msgid "Line Width" +msgstr "行幅" + +#: ../../po/../src/extension/internal/grid.cpp:214 +msgid "Horizontal Spacing" +msgstr "横間隔" + +#: ../../po/../src/extension/internal/grid.cpp:215 +msgid "Vertical Spacing" +msgstr "縦間隔" + +#: ../../po/../src/extension/internal/grid.cpp:216 +msgid "Horizontal Offset" +msgstr "水平オフセット" + +#: ../../po/../src/extension/internal/grid.cpp:217 +msgid "Vertical Offset" +msgstr "垂直オフセット" + +#: ../../po/../src/extension/internal/ps.cpp:123 +msgid "Print Destination" +msgstr "印刷先" + +#. Print properties frame +#: ../../po/../src/extension/internal/ps.cpp:138 +msgid "Print properties" +msgstr "印刷のプロパティ" + +#: ../../po/../src/extension/internal/ps.cpp:145 +msgid "Print using PostScript operators" +msgstr "PostScriptを経由" + +#: ../../po/../src/extension/internal/ps.cpp:147 +msgid "" +"Use PostScript vector operators. The resulting image is usually smaller in " +"file size and can be arbitrarily scaled, but alpha transparency and patterns " +"will be lost." +msgstr "" +"PostScriptベクトルオペレータを使うと、出力されるデータは小さくなり自動的にサ" +"イズ調整されます。透明度、パターンが失われます" + +#: ../../po/../src/extension/internal/ps.cpp:152 +msgid "Print as bitmap" +msgstr "ビットマップ印刷" + +#: ../../po/../src/extension/internal/ps.cpp:154 +msgid "" +"Print everything as bitmap. The resulting image is usually larger in file " +"size and cannot be arbitrarily scaled without quality loss, but all objects " +"will be rendered exactly as displayed." +msgstr "" +"すべてをビットマップで印刷します。出力するデータは大きくなり品質はズームに依" +"存します。すべてのグラフィックは表示と同様に印刷されます。" + +#: ../../po/../src/extension/internal/ps.cpp:168 +msgid "Preferred resolution (dots per inch) of bitmap" +msgstr "ビットマップ解像度(インチあたりのドット数)" + +#: ../../po/../src/extension/internal/ps.cpp:182 +msgid "Resolution:" +msgstr "解像度:" + +#. Print destination frame +#: ../../po/../src/extension/internal/ps.cpp:186 +msgid "Print destination" +msgstr "印刷先" + +#: ../../po/../src/extension/internal/ps.cpp:192 +msgid "" +"Use '> filename' to print to file.\n" +"Use '| prog arg...' to pipe to a program." +msgstr "" +"'> ファイル名'でファイルに出力\n" +"'| プログラム 引数...'で他のプログラムに出力を渡します。" + +#: ../../po/../src/extension/internal/ps.cpp:1227 +msgid "write error occurred" +msgstr "書き込みエラーが起こりました。" + +#: ../../po/../src/extension/prefdialog.cpp:21 +msgid " Preferences" +msgstr " 設定" + +#. We can't call sp_ui_error_dialog because we may be +#. running from the console, in which case calling sp_ui +#. routines will cause a segfault. See bug 1000350 - bryce +#. sp_ui_error_dialog(_("Format autodetect failed. The file is being opened as SVG.")); +#: ../../po/../src/extension/system.cpp:105 +msgid "Format autodetect failed. The file is being opened as SVG." +msgstr "フォーマットの自動検出が失敗。SVGとして開きます。" + +#. TRANSLATORS: default.svg is localizable - this is the name of the default document +#. template. This way you can localize the default pagesize, translate the name of +#. the default layer, etc. If you wish to localize this file, please create a +#. localized share/templates/default.xx.svg file, where xx is your language code. +#: ../../po/../src/file.cpp:133 +msgid "default.svg" +msgstr "default.svg" + +#: ../../po/../src/file.cpp:215 ../../po/../src/file.cpp:900 +#, c-format +msgid "Failed to load the requested file %s" +msgstr "%sを開くのに失敗しました" + +#: ../../po/../src/file.cpp:240 +msgid "Document not saved yet. Cannot revert." +msgstr "ドキュメントが保存されていないため復帰できません。" + +#: ../../po/../src/file.cpp:246 +#, c-format +msgid "Changes will be lost! Are you sure you want to reload document %s?" +msgstr "変更が失われます! 本当に%sを復帰させますか?" + +#: ../../po/../src/file.cpp:266 +msgid "Document reverted." +msgstr "ドキュメントは復帰しました。" + +#: ../../po/../src/file.cpp:268 +msgid "Document not reverted." +msgstr "ドキュメントは復帰できませんでした" + +#: ../../po/../src/file.cpp:382 +msgid "Select file to open" +msgstr "開くファイルを選択" + +#: ../../po/../src/file.cpp:518 +#, fuzzy, c-format +msgid "Removed %i unused definition in <defs>." +msgid_plural "Removed %i unused definitions in <defs>." +msgstr[0] "%i個のオブジェクトを<defs>から削除しました" +msgstr[1] "%i個のオブジェクトを<defs>から削除しました" + +#: ../../po/../src/file.cpp:523 +#, fuzzy +msgid "No unused definitions in <defs>." +msgstr "<defs>には未使用のオブジェクトはありませんでした" + +#: ../../po/../src/file.cpp:548 +#, c-format +msgid "" +"No Inkscape extension found to save document (%s). This may have been " +"caused by an unknown filename extension." +msgstr "%sの拡張子では保存に適切なフォーマットが見つかりません。" + +#: ../../po/../src/file.cpp:549 ../../po/../src/file.cpp:557 +msgid "Document not saved." +msgstr "ドキュメントを保存できませんでした。" + +#: ../../po/../src/file.cpp:556 +#, c-format +msgid "File %s could not be saved." +msgstr "%sを保存できませんでした。" + +#: ../../po/../src/file.cpp:566 +msgid "Document saved." +msgstr "ドキュメントを保存しました。" + +#: ../../po/../src/file.cpp:614 +#, c-format +msgid "drawing%s" +msgstr "描画%s" + +#: ../../po/../src/file.cpp:620 +#, c-format +msgid "drawing-%d%s" +msgstr "描画-%d%s" + +#: ../../po/../src/file.cpp:655 +msgid "Select file to save to" +msgstr "保存するファイルを選択" + +#: ../../po/../src/file.cpp:739 +msgid "No changes need to be saved." +msgstr "保存の必要がありませんでした。" + +#: ../../po/../src/file.cpp:926 +msgid "Select file to import" +msgstr "インポートするファイルを選択" + +#: ../../po/../src/gradient-context.cpp:263 +msgid "Ctrl: snap gradient angle" +msgstr "Ctrl: 角度をスナップ" + +#: ../../po/../src/gradient-context.cpp:264 +msgid "Shift: draw gradient around the starting point" +msgstr "Shift: 始点を中心にグラデーションを描画" + +#. We did an undoable action, but sp_document_done will be called by the knot when released +#. status text; we do not track coords because this branch is run once, not all the time +#. during drag +#: ../../po/../src/gradient-context.cpp:462 +#, c-format +msgid "Gradient for %d objects; with Ctrl to snap angle" +msgstr "グラデーション %d: … Ctrl: 角度をスナップ" + +#: ../../po/../src/gradient-context.cpp:464 +msgid "Select objects on which to create gradient." +msgstr "グラデーションを追加するオブジェクトを選択してください" + +#: ../../po/../src/gradient-drag.cpp:65 +msgid "Linear gradient start" +msgstr "線形グラデーション 始点" + +#. POINT_LG_P1 +#: ../../po/../src/gradient-drag.cpp:66 +msgid "Linear gradient end" +msgstr "線形グラデーション 終点" + +#: ../../po/../src/gradient-drag.cpp:67 +msgid "Radial gradient center" +msgstr "放射グラデーション 中心" + +#: ../../po/../src/gradient-drag.cpp:68 ../../po/../src/gradient-drag.cpp:69 +msgid "Radial gradient radius" +msgstr "放射グラデーション 半径" + +#: ../../po/../src/gradient-drag.cpp:70 +msgid "Radial gradient focus" +msgstr "放射グラデーション フォーカス" + +#: ../../po/../src/gradient-drag.cpp:659 +#, fuzzy, c-format +msgid "" +"%s for: %s%s; drag with Ctrl to snap angle, with Ctrl+Alt to " +"preserve angle, with Ctrl+Shift to scale around center" +msgstr "" +"オブジェクトを拡大/縮小 … Ctrl: 形状を固定、Shift: 中心" +"を固定" + +#: ../../po/../src/gradient-drag.cpp:662 +msgid " (stroke)" +msgstr " (ストローク)" + +#: ../../po/../src/gradient-drag.cpp:665 +msgid "" +"Radial gradient center and focus; drag with Shift to " +"separate focus" +msgstr "" + +#: ../../po/../src/gradient-drag.cpp:667 +#, c-format +msgid "" +"Gradient point shared by %d gradients; drag with Shift to " +"separate" +msgstr "" + +#: ../../po/../src/helper/units.cpp:40 +msgid "Unit" +msgstr "ユニット" + +#: ../../po/../src/helper/units.cpp:40 +msgid "Units" +msgstr "ユニット" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Point" +msgstr "ポイント" + +#: ../../po/../src/helper/units.cpp:41 +msgid "pt" +msgstr "ポイント" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Points" +msgstr "ポイント" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Pt" +msgstr "Pt" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Pixel" +msgstr "ピクセル" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Pixels" +msgstr "ピクセル" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Px" +msgstr "Px" + +#. You can add new elements from this point forward +#: ../../po/../src/helper/units.cpp:44 ../share/extensions/straightseg.inx.h:2 +msgid "Percent" +msgstr "パーセント" + +#: ../../po/../src/helper/units.cpp:44 +msgid "Percents" +msgstr "パーセント" + +#: ../../po/../src/helper/units.cpp:45 +msgid "Millimeter" +msgstr "ミリメートル" + +#: ../../po/../src/helper/units.cpp:45 +msgid "mm" +msgstr "mm" + +#: ../../po/../src/helper/units.cpp:45 +msgid "Millimeters" +msgstr "ミリメートル" + +#: ../../po/../src/helper/units.cpp:46 +msgid "Centimeter" +msgstr "センチメートル" + +#: ../../po/../src/helper/units.cpp:46 +msgid "cm" +msgstr "cm" + +#: ../../po/../src/helper/units.cpp:46 +msgid "Centimeters" +msgstr "センチメートル" + +#: ../../po/../src/helper/units.cpp:47 +msgid "Meter" +msgstr "メートル" + +#: ../../po/../src/helper/units.cpp:47 +msgid "m" +msgstr "ミリ" + +#: ../../po/../src/helper/units.cpp:47 +msgid "Meters" +msgstr "メートル" + +#. no svg_unit +#: ../../po/../src/helper/units.cpp:48 +msgid "Inch" +msgstr "インチ" + +#: ../../po/../src/helper/units.cpp:48 +msgid "in" +msgstr "インチ" + +#: ../../po/../src/helper/units.cpp:48 +msgid "Inches" +msgstr "インチ" + +#. Volatiles do not have default, so there are none here +#. TRANSLATORS: for info, see http://www.w3.org/TR/REC-CSS2/syndata.html#length-units +#: ../../po/../src/helper/units.cpp:51 +msgid "Em square" +msgstr "EM スクエア" + +#: ../../po/../src/helper/units.cpp:51 +msgid "em" +msgstr "em" + +#: ../../po/../src/helper/units.cpp:51 +msgid "Em squares" +msgstr "EM スクエア" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/REC-CSS2/syndata.html#length-units +#: ../../po/../src/helper/units.cpp:53 +msgid "Ex square" +msgstr "EX スクエア" + +#: ../../po/../src/helper/units.cpp:53 +msgid "ex" +msgstr "ex" + +#: ../../po/../src/helper/units.cpp:53 +msgid "Ex squares" +msgstr "EX スクエア" + +#: ../../po/../src/inkscape.cpp:468 +msgid "Untitled document" +msgstr "無題ドキュメント" + +#. Show nice dialog box +#: ../../po/../src/inkscape.cpp:497 +msgid "Inkscape encountered an internal error and will close now.\n" +msgstr "Inkscapeで内部エラーが発生しました。今すぐ終了します。\n" + +#: ../../po/../src/inkscape.cpp:498 +msgid "" +"Automatic backups of unsaved documents were done to the following " +"locations:\n" +msgstr "未保存ドキュメントの自動バックアップを次の場所に行いました:\n" + +#: ../../po/../src/inkscape.cpp:499 +msgid "Automatic backup of the following documents failed:\n" +msgstr "次のドキュメントの自動バックアップに失敗しました:\n" + +#: ../../po/../src/inkscape.cpp:634 +#, c-format +msgid "" +"Cannot create directory %s.\n" +"%s" +msgstr "" +"ディレクトリ%sを作成できません。\n" +"%s" + +#: ../../po/../src/inkscape.cpp:635 +#, c-format +msgid "" +"%s is not a valid directory.\n" +"%s" +msgstr "" +"%sはディレクトリではありません。\n" +"%s" + +#: ../../po/../src/inkscape.cpp:636 +#, c-format +msgid "" +"Cannot create file %s.\n" +"%s" +msgstr "" +"ファイル%sを作成できません。\n" +"%s" + +#: ../../po/../src/inkscape.cpp:637 +#, c-format +msgid "" +"Cannot write file %s.\n" +"%s" +msgstr "" +"ファイル%sに書き込めません。\n" +"%s" + +#: ../../po/../src/inkscape.cpp:638 +msgid "" +"Although Inkscape will run, it will use default settings,\n" +"and any changes made in preferences will not be saved." +msgstr "Inkscapeはデフォルト設定で起動し、設定を保存しません。" + +#: ../../po/../src/inkscape.cpp:708 +#, c-format +msgid "" +"%s is not a regular file.\n" +"%s" +msgstr "" +"%s は通常のファイルではありません.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:709 +#, c-format +msgid "" +"%s not a valid XML file, or\n" +"you don't have read permissions on it.\n" +"%s" +msgstr "" +"%sはXMLファイルではないか、読み込み権限がありません。\n" +"%s" + +#: ../../po/../src/inkscape.cpp:711 +#, fuzzy, c-format +msgid "" +"%s is not a valid menus file.\n" +"%s" +msgstr "" +"%sは正しい設定ファイルではありません。\n" +"%s" + +#: ../../po/../src/inkscape.cpp:712 +#, fuzzy +msgid "" +"Inkscape will run with default menus.\n" +"New menus will not be saved." +msgstr "" +"Inkscapeはデフォルト設定で起動します。\n" +"新しい設定が保存されます。" + +#. sp_ui_menu_append_check_item_from_verb(m, view, _("_Menu"), _("Show or hide the menu bar"), "menu", +#. checkitem_toggled, checkitem_update, 0); +#: ../../po/../src/interface.cpp:753 +msgid "Commands Bar" +msgstr "コマンドバー" + +#: ../../po/../src/interface.cpp:753 +msgid "Show or hide the Commands bar (under the menu)" +msgstr "コマンドバーを表示/非表示" + +#: ../../po/../src/interface.cpp:755 +msgid "Tool Controls" +msgstr "ツールコントロール" + +#: ../../po/../src/interface.cpp:755 +msgid "Show or hide the Tool Controls panel" +msgstr "ツールコントロールパネルを表示/非表示" + +#: ../../po/../src/interface.cpp:757 +msgid "_Toolbox" +msgstr "ツールボックス" + +#: ../../po/../src/interface.cpp:757 +msgid "Show or hide the main toolbox (on the left)" +msgstr "ツールボックス(å·¦)を表示/非表示" + +#: ../../po/../src/interface.cpp:763 +msgid "_Statusbar" +msgstr "ステータスバー" + +#: ../../po/../src/interface.cpp:763 +msgid "Show or hide the statusbar (at the bottom of the window)" +msgstr "ステータスバー(下)を表示/非表示" + +#: ../../po/../src/interface.cpp:820 +#, c-format +msgid "Verb \"%s\" Unknown" +msgstr "" + +#. TRANSLATORS: #%s is the id of the group e.g. , not a number. +#: ../../po/../src/interface.cpp:930 +#, c-format +msgid "Enter group #%s" +msgstr "#%sグループに追加" + +#: ../../po/../src/interface.cpp:941 +msgid "Go to parent" +msgstr "親レイヤーへ移動" + +#: ../../po/../src/interface.cpp:972 +msgid "Could not parse SVG data" +msgstr "SVGデータを解析出来ません" + +#: ../../po/../src/interface.cpp:1135 +#, c-format +msgid "Overwrite %s" +msgstr "%sを上書き" + +#: ../../po/../src/interface.cpp:1153 +#, c-format +msgid "" +"The file %s already exists. Do you want to overwrite that file with the " +"current document?" +msgstr "%sは存在します。現在のドキュメントで上書きしますか?" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:59 +msgid "Jabber connection lost." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:72 +#, c-format +msgid "Sending message; %u message remaining in send queue." +msgid_plural "Sending message; %u messages remaining in send queue." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:78 +msgid "Receive queue empty." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:154 +#, c-format +msgid "Receiving change; %u change left to process." +msgid_plural "Receiving change; %u changes left to process." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:157 +#, c-format +msgid "%s has left the chatroom." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:221 +msgid "Nickname %1 is already in use. Please choose a different nickname." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:225 +msgid "An error was encountered while attempting to connect to the server." +msgstr "" + +#. Check to see if the user made any modifications to this document. If so, +#. we want to give them the option of (1) letting us clear their document or (2) +#. opening a new, blank document for the whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:131 +msgid "%1 has invited you to a whiteboard session." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:132 +msgid "Incoming whiteboard invitation from %1" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:135 +msgid "Do you wish to accept %1's whiteboard session invitation?" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:137 +msgid "" +"Would you like to accept %1's invitation in a new document window?\n" +"Accepting the invitation in your current window will discard unsaved changes." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:143 +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:198 +#, fuzzy +msgid "Accept invitation" +msgstr "加速" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:144 +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:199 +msgid "Decline invitation" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:145 +#, fuzzy +msgid "Accept invitation in new document window" +msgstr "新規ドキュメントを作成" + +#. We could not create a new desktop; ask the user if she or he wants to +#. replace the current document and accept the invitation, or reject the invitation. +#. TRANSLATORS: %1 is a userid here +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:196 +msgid "" +"A new document window could not be opened for a whiteboard session with %" +"1" +msgstr "" + +#. TRANSLATORS: %1 is the peer whom refused our invitation. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:238 +msgid "" +"The user %1 has refused your " +"whiteboard invitation.\n" +"\n" +msgstr "" + +#. TRANSLATORS: %1 is the peer whom refused our invitation, %2 is our Jabber identity. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:241 +msgid "" +"You are still connected to a Jabber server as %2, and may send an " +"invitation to %1 again, or you may send an invitation to a different " +"user." +msgstr "" + +#. TRANSLATORS: %1 is the peer whom we tried to contact, but is already in a whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:252 +msgid "" +"The user %1 is already in a " +"whiteboard session.\n" +"\n" +msgstr "" + +#. TRANSLATORS: %1 is the peer whom we tried to contact, but is already in a whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:255 +msgid "" +"You are still connected to a Jabber server as %1, and may send an " +"invitation to a different user." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/invitation-confirm-dialog.cpp:26 +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:24 +msgid "_Write session file:" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/message-processors.cpp:145 +#, c-format +msgid "%s has joined the chatroom." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/message-queue.cpp:87 +#, fuzzy, c-format +msgid "%u change in receive queue." +msgid_plural "%u changes in receive queue." +msgstr[0] "保存の必要がありませんでした。" +msgstr[1] "保存の必要がありませんでした。" + +#: ../../po/../src/jabber_whiteboard/message-queue.cpp:117 +#, fuzzy, c-format +msgid "%u change in send queue." +msgid_plural "%u changes in send queue." +msgstr[0] "保存の必要がありませんでした。" +msgstr[1] "保存の必要がありませんでした。" + +#. if ID is NULL, then we have a real problem -- we were not able to find a key +#. nor generate one. The only thing we can really do here is abort, since we have +#. no way to let the other client(s) uniquely identify this object. +#. FIXME: If this indicates a programming bug, then don't request translation with +#. * _(...): it is most useful in untranslated form so that developers may search for +#. * it when someone reports it in a bug report (as we want users to do for all bugs, +#. * as indicated by it being a g_warning string). +#. * +#. * Otherwise, if it is not a programming bug but a network error or a bug in the +#. * remote peer (perhaps running different software) or whatever, then present it in +#. * an alert box, and avoid use of technical jargon `NULL'. +#. +#: ../../po/../src/jabber_whiteboard/message-utilities.cpp:171 +msgid "" +"ID for new object is NULL even after generation and lookup attempts: the new " +"object will NOT be sent, nor will any of its child objects!" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:60 +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:995 +msgid "Select a location and filename" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:62 +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:997 +#, fuzzy +msgid "Set filename" +msgstr "ファイル名" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:301 +msgid "No SSL certificate was found." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:304 +msgid "The SSL certificate provided by the Jabber server is untrusted." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:307 +msgid "The SSL certificate provided by the Jabber server is expired." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:310 +msgid "" +"The SSL certificate provided by the Jabber server has not been activated." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:313 +msgid "" +"The SSL certificate provided by the Jabber server contains a hostname that " +"does not match the Jabber server's hostname." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:316 +msgid "" +"The SSL certificate provided by the Jabber server contains an invalid " +"fingerprint." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:319 +msgid "An unknown error occurred while setting up the SSL connection." +msgstr "" + +#. TRANSLATORS: %1 is the message that describes the specific error that occurred when +#. establishing the SSL connection. +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:325 +msgid "" +"%1\n" +"\n" +"Do you wish to continue connecting to the Jabber server?" +msgstr "" +"%1\n" +"\n" +"Jabberサーバとの接続を継続しますか?" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:328 +msgid "Continue connecting and ignore further errors" +msgstr "エラーを無視して接続を継続" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:329 +msgid "Continue connecting, but warn me of further errors" +msgstr "エラーを警告して接続を継続" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:330 +msgid "Cancel connection" +msgstr "接続を中止" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:777 +#, c-format +msgid "Established whiteboard session with %s." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:785 +#, c-format +msgid "%s has left the whiteboard session." +msgstr "" + +#. Inform the user +#. TRANSLATORS: %1 is the name of the user that disconnected, %2 is the name of the user whom the disconnected user disconnected from. +#. This message is not used in a chatroom context. +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:790 +msgid "" +"The user %1 has left the " +"whiteboard session.\n" +"\n" +msgstr "" + +#. TRANSLATORS: %1 and %2 are userids +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:792 +msgid "" +"You are still connected to a Jabber server as %2, and may establish a " +"new session to %1 or a different user." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:988 +msgid "" +"Could not open file %1 for session recording.\n" +"The error encountered was: %2.\n" +"\n" +"You may select a different location to record the session, or you may opt to " +"not record this session." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:990 +msgid "Choose a different location" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:991 +msgid "Skip session recording" +msgstr "" + +#: ../../po/../src/knot.cpp:673 +msgid "Node or handle drag canceled." +msgstr "ノードかドラッグはキャンセルされました。" + +#: ../../po/../src/libnrtype/FontFactory.cpp:358 +msgid "Ignoring font without family that will crash Pango" +msgstr "" + +#: ../../po/../src/main.cpp:395 +msgid "Print the Inkscape version number" +msgstr "Inkscapeのバージョンを表示" + +#: ../../po/../src/main.cpp:400 +msgid "Do not use X server (only process files from console)" +msgstr "X サーバを使用しない (コンソールでファイルの処理だけを行う)" + +#: ../../po/../src/main.cpp:405 +msgid "Try to use X server (even if $DISPLAY is not set)" +msgstr "$DISPLAY 変数が設定されていなくても X サーバの利用を試みる" + +#: ../../po/../src/main.cpp:410 +msgid "Open specified document(s) (option string may be excluded)" +msgstr "" +"指定したドキュメントを開く (オプション文字列は無視されることがあります。)" + +#: ../../po/../src/main.cpp:411 ../../po/../src/main.cpp:416 +#: ../../po/../src/main.cpp:421 ../../po/../src/main.cpp:483 +#: ../../po/../src/main.cpp:488 ../../po/../src/main.cpp:493 +msgid "FILENAME" +msgstr "ファイル名" + +#: ../../po/../src/main.cpp:415 +msgid "Print document(s) to specified output file (use '| program' for pipe)" +msgstr "指定されたファイルにドキュメントを印刷 ('| program'でパイプ)" + +#: ../../po/../src/main.cpp:420 +msgid "Export document to a PNG file" +msgstr "ドキュメントをPNGファイルにエクスポート" + +#: ../../po/../src/main.cpp:425 +#, fuzzy +msgid "The resolution used for exporting SVG into bitmap (default 90)" +msgstr "SVGのエクスポート時の解像度 (デフォルト 72)" + +#: ../../po/../src/main.cpp:426 +msgid "DPI" +msgstr "DPI" + +#: ../../po/../src/main.cpp:430 +#, fuzzy +msgid "" +"Exported area in SVG user units (default is the canvas; 0,0 is lower-left " +"corner)" +msgstr "出力範囲をSVGピクセルで指定 (既定値はドキュメント全体, 0,0 は左下端)" + +#: ../../po/../src/main.cpp:431 +msgid "x0:y0:x1:y1" +msgstr "x0:y0:x1:y1" + +#: ../../po/../src/main.cpp:435 +msgid "Exported area is the entire drawing (not canvas)" +msgstr "" + +#: ../../po/../src/main.cpp:440 +msgid "" +"Snap the bitmap export area outwards to the nearest integer values (in SVG " +"user units)" +msgstr "" + +#: ../../po/../src/main.cpp:445 +msgid "The width of exported bitmap in pixels (overrides export-dpi)" +msgstr "" +"生成されるビットマップ幅をピクセル値で指定 (エクスポート解像度より優先)" + +#: ../../po/../src/main.cpp:446 +msgid "WIDTH" +msgstr "幅" + +#: ../../po/../src/main.cpp:450 +msgid "The height of exported bitmap in pixels (overrides export-dpi)" +msgstr "" +"生成されるビットマップの高さをピクセル値で指定 (エクスポート解像度より優先)" + +#: ../../po/../src/main.cpp:451 +msgid "HEIGHT" +msgstr "高さ" + +#: ../../po/../src/main.cpp:455 +msgid "The ID of the object to export (overrides export-area)" +msgstr "エクスポートするオブジェクトのID (エクスポート領域より優先)" + +#: ../../po/../src/main.cpp:456 ../../po/../src/main.cpp:532 +msgid "ID" +msgstr "ID" + +#. TRANSLATORS: this means: "Only export the object whose id is given in --export-id". +#. See "man inkscape" for details. +#: ../../po/../src/main.cpp:462 +msgid "" +"Export just the object with export-id, hide all others (only with export-id)" +msgstr "エクスポートIDのみでエクスポート (エクスポートIDのみ)" + +#: ../../po/../src/main.cpp:467 +msgid "Use stored filename and DPI hints when exporting (only with export-id)" +msgstr "ファイル名やDPIを頼りにエクスポート (エクスポートIDのみ)" + +#: ../../po/../src/main.cpp:472 +msgid "Background color of exported bitmap (any SVG-supported color string)" +msgstr "エクスポート画像の背景色を指定 (SVG でサポートされるカラー)" + +#: ../../po/../src/main.cpp:473 +msgid "COLOR" +msgstr "色" + +#: ../../po/../src/main.cpp:477 +msgid "Background opacity of exported bitmap (either 0.0 to 1.0, or 1 to 255)" +msgstr "出力ビットマップの透明度を指定 (0.0〜1.0、または1〜255)" + +#: ../../po/../src/main.cpp:478 +msgid "VALUE" +msgstr "値" + +#: ../../po/../src/main.cpp:482 +msgid "Export document to plain SVG file (no sodipodi or inkscape namespaces)" +msgstr "標準 SVG ファイルへエクスポート (inkscape名前空間を使用しない)" + +#: ../../po/../src/main.cpp:487 +#, fuzzy +msgid "Export document to a PS file" +msgstr "ドキュメントをPNGファイルにエクスポート" + +#: ../../po/../src/main.cpp:492 +#, fuzzy +msgid "Export document to an EPS file" +msgstr "ドキュメントをPNGファイルにエクスポート" + +#: ../../po/../src/main.cpp:497 +#, fuzzy +msgid "Convert text object to paths on export (EPS)" +msgstr "ビットマップをパスに変換" + +#: ../../po/../src/main.cpp:502 +msgid "Export files with the bounding box set to the page size (EPS)" +msgstr "" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:508 +msgid "" +"Query the X coordinate of the drawing or, if specified, of the object with --" +"query-id" +msgstr "" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:514 +msgid "" +"Query the Y coordinate of the drawing or, if specified, of the object with --" +"query-id" +msgstr "" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:520 +msgid "" +"Query the width of the drawing or, if specified, of the object with --query-" +"id" +msgstr "" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:526 +msgid "" +"Query the height of the drawing or, if specified, of the object with --query-" +"id" +msgstr "" + +#: ../../po/../src/main.cpp:531 +#, fuzzy +msgid "The ID of the object whose dimensions are queried" +msgstr "エクスポートするオブジェクトのID (エクスポート領域より優先)" + +#. TRANSLATORS: this option makes Inkscape print the name (path) of the extension directory +#: ../../po/../src/main.cpp:537 +msgid "Print out the extension directory and exit" +msgstr "" + +#: ../../po/../src/main.cpp:542 +msgid "Show given files one-by-one, switch to next on any key/mouse event" +msgstr "一つずつ与えられたファイルを表示。任意のキー/マウスで次にスイッチ" + +#: ../../po/../src/main.cpp:547 +msgid "Use the new Gtkmm GUI interface" +msgstr "" + +#: ../../po/../src/main.cpp:552 +#, fuzzy +msgid "Remove unused definitions from the defs section(s) of the document" +msgstr "未使用のオブジェクトを<defs>から削除する" + +#: ../../po/../src/main.cpp:741 +msgid "" +"[OPTIONS...] [FILE...]\n" +"\n" +"Available options:" +msgstr "" +"[オプション...] [ファイル...]\n" +"\n" +"有効なオプション:" + +#: ../../po/../src/menus-skeleton.h:17 +msgid "_New" +msgstr "新規" + +#: ../../po/../src/menus-skeleton.h:22 +msgid "Open _Recent" +msgstr "最近開いたファイル" + +#: ../../po/../src/menus-skeleton.h:53 +msgid "_Edit" +msgstr "編集(_E)" + +#: ../../po/../src/menus-skeleton.h:84 +msgid "_View" +msgstr "表示(_V)" + +#: ../../po/../src/menus-skeleton.h:85 +#, fuzzy +msgid "_Zoom" +msgstr "ズーム" + +#: ../../po/../src/menus-skeleton.h:102 +#, fuzzy +msgid "Show/Hide" +msgstr "表示/非表示" + +#: ../../po/../src/menus-skeleton.h:107 +msgid "_Display mode" +msgstr "" + +#: ../../po/../src/menus-skeleton.h:126 +msgid "_Layer" +msgstr "レイヤー(_L)" + +#: ../../po/../src/menus-skeleton.h:143 +msgid "_Object" +msgstr "オブジェクト(_O)" + +#: ../../po/../src/menus-skeleton.h:165 +msgid "_Path" +msgstr "パス(_P)" + +#: ../../po/../src/menus-skeleton.h:188 +msgid "_Text" +msgstr "テキスト(_T)" + +#: ../../po/../src/menus-skeleton.h:200 +#, fuzzy +msgid "Effects" +msgstr "オフセット" + +#: ../../po/../src/menus-skeleton.h:207 +msgid "Whiteboa_rd" +msgstr "" + +#: ../../po/../src/menus-skeleton.h:220 +msgid "_Help" +msgstr "ヘルプ(_H)" + +#: ../../po/../src/menus-skeleton.h:222 +msgid "Tutorials" +msgstr "チュートリアル" + +#: ../../po/../src/node-context.cpp:382 +msgid "" +"Ctrl: toggle node type, snap handle angle, move hor/vert; Ctrl" +"+Alt: move along handles" +msgstr "" +"Ctrl: [ノードの種類、ハンドル角度、水平/垂直の移動]を切替え、 Ctrl" +"+Alt: ハンドルに沿って移動" + +#: ../../po/../src/node-context.cpp:383 +msgid "" +"Shift: toggle node selection, disable snapping, rotate both handles" +msgstr "" +"Shift: ノード選択モードを切替え、スナップ、ハンドルの回転を無効化" + +#: ../../po/../src/node-context.cpp:384 +msgid "Alt: lock handle length; Ctrl+Alt: move along handles" +msgstr "" +"Alt: ハンドルの長さをロック, Ctrl+Alt: ハンドルに沿って移動" + +#: ../../po/../src/nodepath.cpp:1399 ../../po/../src/nodepath.cpp:1411 +#: ../../po/../src/nodepath.cpp:1492 ../../po/../src/nodepath.cpp:1504 +msgid "To join, you must have two endnodes selected." +msgstr "2つのノードを選択して、結合をしてください。" + +#: ../../po/../src/nodepath.cpp:1633 ../../po/../src/nodepath.cpp:1647 +msgid "" +"Select two non-endpoint nodes on a path between which to delete " +"segments." +msgstr "線を分割する2つのノードを選択してください。" + +#: ../../po/../src/nodepath.cpp:1743 +msgid "Cannot find path between nodes." +msgstr "選択ノードの間にはパスがありません。" + +#: ../../po/../src/nodepath.cpp:2822 +#, fuzzy, c-format +msgid "" +"Node handle: angle %0.2f°, length %s; with Ctrl to snap " +"angle; with Alt to lock length; with Shift to rotate both " +"handles" +msgstr "" +"ノードハンドル: ドラッグでカーブを編集、Ctrlで角度をスナップ、" +"Alt: 長さを固定、Shift: 反対側のハンドルを同期" + +#: ../../po/../src/nodepath.cpp:3351 +msgid "" +"Node: drag to edit the path; with Ctrl to snap to horizontal/" +"vertical; with Ctrl+Alt to snap to handles' directions" +msgstr "" +"ノード: ドラッグでパスを編集 、Ctrl: 水平、垂直にスナップ、" +"Ctrl+Alt: ハンドルの方向にスナップ" + +#: ../../po/../src/nodepath.cpp:3375 +#, fuzzy +msgid "" +"Node handle: drag to shape the curve; with Ctrl to snap angle; " +"with Alt to lock length; with Shift to rotate both handles" +msgstr "" +"ノードハンドル: ドラッグでカーブを編集、Ctrlで角度をスナップ、" +"Alt: 長さを固定、Shift: 反対側のハンドルを同期" + +#: ../../po/../src/nodepath.cpp:3399 +msgid "" +"Node handle: drag to shape the curve; with Ctrl to snap angle; " +"with Alt to lock length; with Shift to rotate the opposite " +"handle in sync" +msgstr "" +"ノードハンドル: ドラッグでカーブを編集、Ctrlで角度をスナップ、" +"Alt: 長さを固定、Shift: 反対側のハンドルを同期" + +#. TRANSLATORS: "end" is an adjective here (NOT a verb) +#: ../../po/../src/nodepath.cpp:3591 +msgid "end node" +msgstr "終点ノード" + +#. TRANSLATORS: "cusp" means "sharp" (cusp node); see also the Advanced Tutorial +#: ../../po/../src/nodepath.cpp:3596 +msgid "cusp" +msgstr "角" + +#. TRANSLATORS: "smooth" is an adjective here +#: ../../po/../src/nodepath.cpp:3599 +msgid "smooth" +msgstr "滑らか" + +#: ../../po/../src/nodepath.cpp:3601 +msgid "symmetric" +msgstr "対象" + +#. TRANSLATORS: "end" is an adjective here (NOT a verb) +#: ../../po/../src/nodepath.cpp:3607 +msgid "end node, handle retracted (drag with Shift to extend)" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3609 +msgid "one handle retracted (drag with Shift to extend)" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3612 +msgid "both handles retracted (drag with Shift to extend)" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3624 +#, fuzzy +msgid "Drag nodes or node handles; arrow keys to move nodes" +msgstr "ノード、またはノードハンドルを使ってパスを編集" + +#: ../../po/../src/nodepath.cpp:3625 +#, fuzzy +msgid "Drag the node or its handles; arrow keys to move the node" +msgstr "" +"ドラッグでフリーハンドで線を描く … a: 作成/追加のモード切替え" + +#: ../../po/../src/nodepath.cpp:3651 ../../po/../src/nodepath.cpp:3663 +#, fuzzy +msgid "Select a single object to edit its nodes or handles." +msgstr "全てのオブジェクト、パスを選択" + +#: ../../po/../src/nodepath.cpp:3655 +#, fuzzy, c-format +msgid "" +"0 out of %i node selected. Click, Shift+click, " +"or drag around nodes to select." +msgid_plural "" +"0 out of %i nodes selected. Click, Shift+click, " +"or drag around nodes to select." +msgstr[0] "" +"%iのノードが選択可能、クリック、Shift+クリック、ドラッグでノードを選択" +"してください。" +msgstr[1] "" +"%iのノードが選択可能、クリック、Shift+クリック、ドラッグでノードを選択" +"してください。" + +#: ../../po/../src/nodepath.cpp:3661 +msgid "Drag the handles of the object to modify it." +msgstr "" + +#: ../../po/../src/nodepath.cpp:3669 +#, fuzzy, c-format +msgid "%i of %i node selected; %s. %s." +msgid_plural "%i of %i nodes selected; %s. %s." +msgstr[0] "%i個のノードを選択しています。(%i個が選択可能) ノード状態: %s. %s." +msgstr[1] "%i個のノードを選択しています。(%i個が選択可能) ノード状態: %s. %s." + +#: ../../po/../src/nodepath.cpp:3675 +#, fuzzy, c-format +msgid "%i of %i node selected. %s." +msgid_plural "%i of %i nodes selected. %s." +msgstr[0] "%i個のノードを選択しています。(%i個が選択可能) ノード状態: %s" +msgstr[1] "%i個のノードを選択しています。(%i個が選択可能) ノード状態: %s" + +#: ../../po/../src/object-edit.cpp:493 +msgid "" +"Adjust the horizontal rounding radius; with Ctrl to make the " +"vertical radius the same" +msgstr "水平半径を調整 … Ctrl: 垂直方向の半径を同じに" + +#: ../../po/../src/object-edit.cpp:499 +msgid "" +"Adjust the vertical rounding radius; with Ctrl to make the " +"horizontal radius the same" +msgstr "垂直半径を調整 … Ctrl: 水平方向の半径を同じに" + +#: ../../po/../src/object-edit.cpp:506 ../../po/../src/object-edit.cpp:513 +msgid "" +"Adjust the width and height of the rectangle; with Ctrl to " +"lock ratio or stretch in one dimension only" +msgstr "四角の幅、高さを調節 … Ctrl: 縦または横を固定" + +#: ../../po/../src/object-edit.cpp:686 +msgid "Adjust ellipse width, with Ctrl to make circle" +msgstr "円/弧の幅を調節 … Ctrl: 円に固定" + +#: ../../po/../src/object-edit.cpp:689 +msgid "Adjust ellipse height, with Ctrl to make circle" +msgstr "円/弧の高さを調節 … Ctrl: 円に固定" + +#: ../../po/../src/object-edit.cpp:692 +msgid "" +"Position the start point of the arc or segment; with Ctrl to " +"snap angle; drag inside the ellipse for arc, outside for " +"segment" +msgstr "円/弧の始点 … Ctrl: 角度をスナップ" + +#: ../../po/../src/object-edit.cpp:695 +msgid "" +"Position the end point of the arc or segment; with Ctrl to " +"snap angle; drag inside the ellipse for arc, outside for " +"segment" +msgstr "円/弧の終点 … Ctrl: 角度をスナップ" + +#: ../../po/../src/object-edit.cpp:800 +msgid "" +"Adjust the tip radius of the star or polygon; with Shift to " +"round; with Alt to randomize" +msgstr "" +"星/ポリゴンの半径を調整 … Shift: 丸める、 Alt: ランダム" +"化" + +#: ../../po/../src/object-edit.cpp:803 +msgid "" +"Adjust the base radius of the star; with Ctrl to keep star " +"rays radial (no skew); with Shift to round; with Alt to " +"randomize" +msgstr "" +"星/ポリゴンの内径を調整 … Shift: 丸める、 Alt: ランダム" +"化" + +#: ../../po/../src/object-edit.cpp:967 +msgid "" +"Roll/unroll the spiral from inside; with Ctrl to snap angle; " +"with Alt to converge/diverge" +msgstr "" +"螺旋の内側の巻き … Ctrl: 角度をスナップ、Alt: 集中/分散" + +#: ../../po/../src/object-edit.cpp:969 +msgid "" +"Roll/unroll the spiral from outside; with Ctrl to snap angle; " +"with Shift to scale/rotate" +msgstr "" +"螺旋の外側の巻き … Ctrl: 角度をスナップ、Alt: 拡大/縮小" +"/回転" + +#: ../../po/../src/object-edit.cpp:1006 +msgid "Adjust the offset distance" +msgstr "間隔を調整" + +#. TRANSLATORS: This refers to the pattern that's inside the object +#: ../../po/../src/object-edit.cpp:1036 +msgid "Move the pattern fill inside the object" +msgstr "パターンの移動を同期" + +#: ../../po/../src/object-edit.cpp:1038 +msgid "Scale the pattern fill uniformly" +msgstr "パターンの拡大/縮小を同期" + +#: ../../po/../src/object-edit.cpp:1040 +msgid "Rotate the pattern fill; with Ctrl to snap angle" +msgstr "パターンの回転を同期" + +#: ../../po/../src/object-edit.cpp:1065 +msgid "Drag to resize the flowed text frame" +msgstr "" + +#. Item dialog +#: ../../po/../src/object-ui.cpp:106 +msgid "Object _Properties" +msgstr "プロパティ..." + +#. Select item +#: ../../po/../src/object-ui.cpp:116 +msgid "_Select This" +msgstr "選択" + +#. Create link +#: ../../po/../src/object-ui.cpp:126 +msgid "_Create Link" +msgstr "リンクの作成" + +#. "Ungroup" +#: ../../po/../src/object-ui.cpp:199 ../../po/../src/verbs.cpp:1931 +msgid "_Ungroup" +msgstr "グループ解除" + +#. Link dialog +#: ../../po/../src/object-ui.cpp:239 +msgid "Link _Properties" +msgstr "リンクのプロパティ" + +#. Select item +#: ../../po/../src/object-ui.cpp:249 +msgid "_Follow Link" +msgstr "リンクを追う" + +#. Reset transformations +#: ../../po/../src/object-ui.cpp:254 +msgid "_Remove Link" +msgstr "リンクを除去" + +#. Link dialog +#: ../../po/../src/object-ui.cpp:303 +msgid "Image _Properties" +msgstr "イメージのプロパティ" + +#. Item dialog +#: ../../po/../src/object-ui.cpp:344 +msgid "_Fill and Stroke" +msgstr "フィル/ストローク" + +#: ../../po/../src/path-chemistry.cpp:58 +msgid "Select at least two objects to combine." +msgstr "連結する二つ以上のオブジェクト選択してください" + +#: ../../po/../src/path-chemistry.cpp:65 +msgid "At least one of the objects is not a path, cannot combine." +msgstr "パスでないオブジェクトは連結できません。" + +#: ../../po/../src/path-chemistry.cpp:73 +msgid "" +"You cannot combine objects from different groups or layers." +msgstr "異なるグループ、レイヤーのオブジェクトは連結できません。" + +#: ../../po/../src/path-chemistry.cpp:155 +msgid "Select path(s) to break apart." +msgstr "分割するパスを選択してください" + +#: ../../po/../src/path-chemistry.cpp:231 +msgid "No path(s) to break apart in the selection." +msgstr "分割するパスが選択されていません。" + +#: ../../po/../src/path-chemistry.cpp:252 +msgid "Select object(s) to convert to path." +msgstr "パスに変換するオブジェクトを選択してください" + +#: ../../po/../src/path-chemistry.cpp:297 +msgid "No objects to convert to path in the selection." +msgstr "パスに変換するオブジェクトが選択されていません。" + +#: ../../po/../src/path-chemistry.cpp:345 +msgid "Select path(s) to reverse." +msgstr "逆転させるパスを1つ以上選択してください。" + +#: ../../po/../src/path-chemistry.cpp:370 +msgid "No paths to reverse in the selection." +msgstr "逆転させるパスが選択されていません。" + +#: ../../po/../src/pen-context.cpp:379 ../../po/../src/pencil-context.cpp:233 +#, fuzzy +msgid "Continuing selected path" +msgstr "オブジェクトを縮小する" + +#: ../../po/../src/pen-context.cpp:390 ../../po/../src/pencil-context.cpp:242 +msgid "Creating new path" +msgstr "新規パスを作成" + +#: ../../po/../src/pen-context.cpp:394 ../../po/../src/pencil-context.cpp:246 +msgid "Appending to selected path" +msgstr "選択パスに追加" + +#: ../../po/../src/pen-context.cpp:538 +#, fuzzy +msgid "Click or click and drag to close and finish the path." +msgstr "クリック: ノードを選択、または編集" + +#: ../../po/../src/pen-context.cpp:548 +#, fuzzy +msgid "" +"Click or click and drag to continue the path from this point." +msgstr "クリック: ノードを選択、または編集" + +#: ../../po/../src/pen-context.cpp:857 +#, fuzzy, c-format +msgid "" +"%s: angle %3.2f°, distance %s; with Ctrl to snap angle, " +"Enter to finish the path" +msgstr "" +"ノードハンドル: ドラッグでカーブを編集、Ctrlで角度をスナップ、" +"Alt: 長さを固定、Shift: 反対側のハンドルを同期" + +#: ../../po/../src/pen-context.cpp:882 +#, fuzzy, c-format +msgid "" +"Curve handle: angle %3.2f°, length %s; with Ctrl to snap " +"angle" +msgstr "回転: %0.2f度; Ctrl: 角度をスナップ" + +#: ../../po/../src/pen-context.cpp:912 +#, fuzzy, c-format +msgid "" +"%s: angle %3.2f°, length %s; with Ctrl to snap angle, " +"with Shift to move this handle only" +msgstr "" +"ノードハンドル: ドラッグでカーブを編集、Ctrlで角度をスナップ、" +"Alt: 長さを固定、Shift: 反対側のハンドルを同期" + +#: ../../po/../src/pen-context.cpp:946 +msgid "Finishing pen" +msgstr "ペンを終了" + +#: ../../po/../src/pencil-context.cpp:320 +msgid "Release here to close and finish the path." +msgstr "" + +#: ../../po/../src/pencil-context.cpp:326 +#, fuzzy +msgid "Drawing a freehand path" +msgstr "フリーハンド線" + +#: ../../po/../src/pencil-context.cpp:331 +msgid "Drag to continue the path from this point." +msgstr "" + +#. Write curves to object +#: ../../po/../src/pencil-context.cpp:390 +msgid "Finishing freehand" +msgstr "フリーハンドツールを終了" + +#: ../../po/../src/rect-context.cpp:387 +msgid "" +"Ctrl: make square or integer-ratio rect, lock a rounded corner " +"circular" +msgstr "Ctrl: 四角を作成、または角の丸みを固定" + +#: ../../po/../src/rect-context.cpp:549 +#, c-format +msgid "" +"Rectangle: %s × %s; with Ctrl to make square or integer-" +"ratio rectangle; with Shift to draw around the starting point" +msgstr "" +"四角: %s x %s … Ctrl: 正数比にスナップ、Shift: 開始点の" +"周囲に展開" + +#: ../../po/../src/select-context.cpp:243 +msgid "Move canceled." +msgstr "移動をキャンセルしました。" + +#: ../../po/../src/select-context.cpp:252 +msgid "Selection canceled." +msgstr "選択をキャンセルしました。" + +#: ../../po/../src/select-context.cpp:642 +msgid "Ctrl: select in groups, move hor/vert" +msgstr "Ctrl: グループを選択しています。水平/垂直に移動。" + +#: ../../po/../src/select-context.cpp:643 +msgid "Shift: toggle select, force rubberband, disable snapping" +msgstr "Shift: スナップを無効化" + +#: ../../po/../src/select-context.cpp:644 +msgid "Alt: select under, move selected" +msgstr "Alt: 選択オブジェクトを移動" + +#: ../../po/../src/select-context.cpp:798 +#, fuzzy +msgid "Selected object is not a group. Cannot enter." +msgstr "選択オブジェクトはパスではないためインセット/アウトセットできません" + +#: ../../po/../src/select-context.cpp:876 +#, c-format +msgid "" +"Move by %s, %s; with Ctrl to restrict to horizontal/vertical; " +"with Shift to disable snapping" +msgstr "" +"移動[%s, %s] … Ctrl: 水平/垂直移動、Shift: スナップを無" +"効化" + +#: ../../po/../src/selection-chemistry.cpp:228 +msgid "Nothing was deleted." +msgstr "何も削除出来ませんでした。" + +#: ../../po/../src/selection-chemistry.cpp:259 +msgid "Select object(s) to duplicate." +msgstr "複製するオブジェクトを選択してください。" + +#: ../../po/../src/selection-chemistry.cpp:420 +msgid "Select two or more objects to group." +msgstr "グループ化する二つ以上のオブジェクトを選択してください。" + +#: ../../po/../src/selection-chemistry.cpp:428 +msgid "Select at least two objects to group." +msgstr "グループ化する二つ以上のオブジェクトを選択してください。" + +#: ../../po/../src/selection-chemistry.cpp:513 +msgid "Select a group to ungroup." +msgstr "解除するグループを選択してください。" + +#: ../../po/../src/selection-chemistry.cpp:554 +msgid "No groups to ungroup in the selection." +msgstr "解除するグループが選択されていません。" + +#: ../../po/../src/selection-chemistry.cpp:623 +msgid "Select objects to raise." +msgstr "前面に出すオブジェクトを選択してください" + +#: ../../po/../src/selection-chemistry.cpp:629 +#: ../../po/../src/selection-chemistry.cpp:681 +#: ../../po/../src/selection-chemistry.cpp:715 +#: ../../po/../src/selection-chemistry.cpp:773 +msgid "" +"You cannot raise/lower objects from different groups or layers." +msgstr "異なるグループ、レイヤーのオブジェクトは前面/背面に移動できません。" + +#: ../../po/../src/selection-chemistry.cpp:673 +msgid "Select object(s) to raise to top." +msgstr "前面に移動させるオブジェクトを選択してください" + +#: ../../po/../src/selection-chemistry.cpp:709 +msgid "Select object(s) to lower." +msgstr "背面に移動させるオブジェクトを選択してください" + +#: ../../po/../src/selection-chemistry.cpp:765 +msgid "Select object(s) to lower to bottom." +msgstr "最背面に移動させるオブェクトを選択してください" + +#: ../../po/../src/selection-chemistry.cpp:806 +msgid "Nothing to undo." +msgstr "元に戻せません" + +#: ../../po/../src/selection-chemistry.cpp:813 +msgid "Nothing to redo." +msgstr "やり直し出来ません" + +#: ../../po/../src/selection-chemistry.cpp:969 +msgid "Nothing was copied." +msgstr "コピー出来ません" + +#: ../../po/../src/selection-chemistry.cpp:1051 +msgid "Current layer is hidden. Unhide it to be able to paste to it." +msgstr "" +"カレントレイヤーは非表示になっています。非表示を解除してください。" + +#: ../../po/../src/selection-chemistry.cpp:1055 +msgid "Current layer is locked. Unlock it to be able to paste to it." +msgstr "" +"カレントレイヤーはロックされています。ロックを解除してください。" + +#: ../../po/../src/selection-chemistry.cpp:1068 +#: ../../po/../src/selection-chemistry.cpp:1103 +msgid "Nothing on the clipboard." +msgstr "クリップボードが空です。" + +#: ../../po/../src/selection-chemistry.cpp:1109 +msgid "Select object(s) to paste style to." +msgstr "スタイルをペーストする対象を選択してください。" + +#: ../../po/../src/selection-chemistry.cpp:1128 +#, fuzzy +msgid "Select object(s) to move to the layer above." +msgstr "パスに変換するオブジェクトを選択してください" + +#: ../../po/../src/selection-chemistry.cpp:1146 +#, fuzzy +msgid "No more layers above." +msgstr "レイヤーはありません。" + +#: ../../po/../src/selection-chemistry.cpp:1160 +#, fuzzy +msgid "Select object(s) to move to the layer below." +msgstr "パスに変換するオブジェクトを選択してください" + +#: ../../po/../src/selection-chemistry.cpp:1178 +#, fuzzy +msgid "No more layers below." +msgstr "レイヤーはありません。" + +#: ../../po/../src/selection-chemistry.cpp:1811 +msgid "Select a clone to unlink." +msgstr "解除するクローンを選択してください。" + +#: ../../po/../src/selection-chemistry.cpp:1842 +msgid "No clones to unlink in the selection." +msgstr "解除するクローンが選択されていません。" + +#: ../../po/../src/selection-chemistry.cpp:1859 +#, fuzzy +msgid "" +"Select a clone to go to its original. Select a linked offset " +"to go to its source. Select a text on path to go to the path. Select " +"a flowed text to go to its frame." +msgstr "" +"[クローン、リンクオフセット、パスと結合したテキスト]を先に選択してください。" + +#: ../../po/../src/selection-chemistry.cpp:1882 +#, fuzzy +msgid "" +"Cannot find the object to select (orphaned clone, offset, textpath, " +"flowed text?)" +msgstr "" +"[クローン、リンクオフセット、パスと結合したテキスト]のオリジナルが見つかりま" +"せんでした。" + +#: ../../po/../src/selection-chemistry.cpp:1888 +msgid "" +"The object you're trying to select is not visible (it is in <" +"defs>)" +msgstr "" +"選択しようとしているオリジナルは可視ではありません。(<defs>にあります)" + +#: ../../po/../src/selection-chemistry.cpp:1915 +msgid "Select object(s) to convert to pattern." +msgstr "タイル化するオブジェクトを選択してください" + +#: ../../po/../src/selection-chemistry.cpp:2006 +msgid "Select an object with pattern fill to extract objects from." +msgstr "パターン化されたオブジェクトを選択してください。" + +#: ../../po/../src/selection-chemistry.cpp:2059 +msgid "No pattern fills in the selection." +msgstr "パターン化されたオブジェクトが選択されていません。" + +#: ../../po/../src/selection-chemistry.cpp:2079 +msgid "Select object(s) to make a bitmap copy." +msgstr "ビットマップコピーの対象を選択してください" + +#: ../../po/../src/selection-describer.cpp:37 +msgid "Click selection to toggle scale/rotation handles" +msgstr "選択オブジェクトをクリックすると拡大/回転を変更できます。" + +#. no items +#: ../../po/../src/selection-describer.cpp:39 +msgid "" +"No objects selected. Click, Shift+click, or drag around objects to select." +msgstr "" +"オブジェクトが選択されていません。クリックまたはドラッグでオブジェクトを選択" +"してください。" + +#: ../../po/../src/selection-describer.cpp:51 +#, c-format +msgid " in layer %s" +msgstr " / レイヤー[%s]" + +#: ../../po/../src/selection-describer.cpp:54 +#, c-format +msgid " in layer %s" +msgstr " / レイヤー[%s]" + +#: ../../po/../src/selection-describer.cpp:66 +msgid "Use Shift+D to look up original" +msgstr "Shift+Dでオリジナルを見付けられます。" + +#: ../../po/../src/selection-describer.cpp:70 +msgid "Use Shift+D to look up path" +msgstr "Shift+Dでパスを見付けられます。" + +#: ../../po/../src/selection-describer.cpp:74 +msgid "Use Shift+D to look up frame" +msgstr "Shift+Dでフレームを見付けられます。" + +#: ../../po/../src/selection-describer.cpp:84 +#, fuzzy, c-format +msgid "%i object selected" +msgid_plural "%i objects selected" +msgstr[0] "%i個のオブジェクトが選択されています。%s。" +msgstr[1] "%i個のオブジェクトが選択されています。%s。" + +#: ../../po/../src/selection-describer.cpp:90 +#, c-format +msgid "%s%s. %s." +msgstr "" + +#: ../../po/../src/selection-describer.cpp:94 +#, c-format +msgid "%s in %i layer. %s." +msgid_plural "%s in %i layers. %s." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/seltrans.cpp:498 +msgid "" +"Center of rotation and skewing: drag to reposition; scaling with " +"Shift also uses this center" +msgstr "" +"回転/傾ける の中心 … マウスで中心を変更できます。拡大/縮小もこの中心" +"を使います。" + +#: ../../po/../src/seltrans.cpp:514 +msgid "" +"Squeeze or stretch selection; with Ctrl to scale uniformly; " +"with Shift to scale around rotation center" +msgstr "" +"縮める/伸ばす … Ctrl: 形状を固定、Shift: 中心を使う" + +#: ../../po/../src/seltrans.cpp:515 +msgid "" +"Scale selection; with Ctrl to scale uniformly; with Shift to scale around rotation center" +msgstr "" +"オブジェクトを拡大/縮小 … Ctrl: 形状を固定、Shift: 中心" +"を固定" + +#: ../../po/../src/seltrans.cpp:519 +#, fuzzy +msgid "" +"Skew selection; with Ctrl to snap angle; with Shift to " +"skew around the opposite side" +msgstr "" +"回転 Ctrl: 角度をスナップ, Shift: 反対の端を中心に" + +#: ../../po/../src/seltrans.cpp:520 +msgid "" +"Rotate selection; with Ctrl to snap angle; with Shift " +"to rotate around the opposite corner" +msgstr "" +"回転 Ctrl: 角度をスナップ, Shift: 反対の端を中心に" + +#: ../../po/../src/seltrans.cpp:829 ../../po/../src/seltrans.cpp:909 +#, c-format +msgid "Scale: %0.2f%% x %0.2f%%; with Ctrl to lock ratio" +msgstr "拡大/縮小: %0.2f%% x %0.2f%%; Ctrl: 比率を固定" + +#. TRANSLATORS: don't modify the first ";" (it will NOT be displayed as ";" - only the second one will be) +#: ../../po/../src/seltrans.cpp:984 +#, fuzzy, c-format +msgid "Skew: %0.2f°; with Ctrl to snap angle" +msgstr "回転: %0.2f度; Ctrl: 角度をスナップ" + +#. TRANSLATORS: don't modify the first ";" (it will NOT be displayed as ";" - only the second one will be) +#: ../../po/../src/seltrans.cpp:1035 +#, fuzzy, c-format +msgid "Rotate: %0.2f°; with Ctrl to snap angle" +msgstr "回転: %0.2f度; Ctrl: 角度をスナップ" + +#: ../../po/../src/seltrans.cpp:1090 +#, c-format +msgid "Move center to %s, %s" +msgstr "移動 中心を%s, %s" + +#: ../../po/../src/slideshow.cpp:90 +msgid "Inkscape slideshow" +msgstr "Inkscape スライドショー" + +#: ../../po/../src/sp-anchor.cpp:181 +#, c-format +msgid "Link to %s" +msgstr "%sにリンク" + +#: ../../po/../src/sp-anchor.cpp:185 +msgid "Link without URI" +msgstr "URIなしでリンク" + +#: ../../po/../src/sp-ellipse.cpp:438 ../../po/../src/sp-ellipse.cpp:870 +msgid "Ellipse" +msgstr "楕円" + +#: ../../po/../src/sp-ellipse.cpp:583 +msgid "Circle" +msgstr "円" + +#: ../../po/../src/sp-ellipse.cpp:865 +#, fuzzy +msgid "Segment" +msgstr "矩形" + +#: ../../po/../src/sp-ellipse.cpp:867 +msgid "Arc" +msgstr "弧" + +#. TRANSLATORS: "Flow region" is an area where text is allowed to flow +#: ../../po/../src/sp-flowregion.cpp:276 +#, fuzzy +msgid "Flow region" +msgstr "リンクを追う" + +#. TRANSLATORS: A region "cut out of" a flow region; text is not allowed to flow inside the +#. * flow excluded region. flowRegionExclude in SVG 1.2: see +#. * http://www.w3.org/TR/2004/WD-SVG12-20041027/flow.html#flowRegion-elem and +#. * http://www.w3.org/TR/2004/WD-SVG12-20041027/flow.html#flowRegionExclude-elem. +#: ../../po/../src/sp-flowregion.cpp:493 +msgid "Flow excluded region" +msgstr "" + +#: ../../po/../src/sp-flowtext.cpp:355 +#, c-format +msgid "Flowed text (%d characters)" +msgstr "" + +#: ../../po/../src/sp-flowtext.cpp:357 +#, c-format +msgid "Linked flowed text (%d characters)" +msgstr "" + +#: ../../po/../src/sp-guide.cpp:290 +msgid "vertical guideline" +msgstr "垂直ガイドライン" + +#: ../../po/../src/sp-guide.cpp:292 +msgid "horizontal guideline" +msgstr "水平ガイドライン" + +#: ../../po/../src/sp-image.cpp:835 +msgid "embedded" +msgstr "" + +#: ../../po/../src/sp-image.cpp:839 +msgid "(null_pointer)" +msgstr "" + +#: ../../po/../src/sp-image.cpp:843 +#, c-format +msgid "Image with bad reference: %s" +msgstr "無効な画像参照: %s" + +#: ../../po/../src/sp-image.cpp:844 +#, fuzzy, c-format +msgid "Image %d × %d: %s" +msgstr "画像 %d x %d: %s" + +#: ../../po/../src/sp-item-group.cpp:390 +#, fuzzy, c-format +msgid "Group of %d object" +msgid_plural "Group of %d objects" +msgstr[0] "%d オブジェクトのグループ" +msgstr[1] "%d オブジェクトのグループ" + +#: ../../po/../src/sp-item.cpp:720 +msgid "Object" +msgstr "オブジェクト" + +#: ../../po/../src/sp-line.cpp:202 +#, fuzzy +msgid "Line" +msgstr "円" + +#. TRANSLATORS COMMENT: %s is either "outset" or "inset" depending on sign +#: ../../po/../src/sp-offset.cpp:433 +#, fuzzy, c-format +msgid "Linked offset, %s by %f pt" +msgstr "リンクオフセット, (%s, %f pt)" + +#: ../../po/../src/sp-offset.cpp:434 ../../po/../src/sp-offset.cpp:438 +msgid "outset" +msgstr "アウトセット" + +#: ../../po/../src/sp-offset.cpp:434 ../../po/../src/sp-offset.cpp:438 +msgid "inset" +msgstr "インセット" + +#. TRANSLATORS COMMENT: %s is either "outset" or "inset" depending on sign +#: ../../po/../src/sp-offset.cpp:437 +#, c-format +msgid "Dynamic offset, %s by %f pt" +msgstr "ダイナミックオフセット, (%s, %f pt)" + +#: ../../po/../src/sp-path.cpp:127 +#, c-format +msgid "Path (%i node)" +msgid_plural "Path (%i nodes)" +msgstr[0] "パス (%iノード)" +msgstr[1] "パス (%iノード)" + +#: ../../po/../src/sp-polygon.cpp:216 +msgid "Polygon" +msgstr "ポリゴン" + +#: ../../po/../src/sp-polyline.cpp:179 +#, fuzzy +msgid "Polyline" +msgstr "楕円" + +#: ../../po/../src/sp-rect.cpp:250 +msgid "Rectangle" +msgstr "矩形" + +#. TRANSLATORS: since turn count isn't an integer, please adjust the +#. string as needed to deal with an localized plural forms. +#: ../../po/../src/sp-spiral.cpp:305 +#, c-format +msgid "Spiral with %3f turns" +msgstr "螺旋(巻数: %3f)" + +#: ../../po/../src/sp-star.cpp:288 +#, fuzzy, c-format +msgid "Star with %d vertex" +msgid_plural "Star with %d vertices" +msgstr[0] "星(%d点)" +msgstr[1] "星(%d点)" + +#: ../../po/../src/sp-star.cpp:292 +#, fuzzy, c-format +msgid "Polygon with %d vertex" +msgid_plural "Polygon with %d vertices" +msgstr[0] "ポリゴン(%d点)" +msgstr[1] "ポリゴン(%d点)" + +#. TRANSLATORS: For description of font with no name. +#: ../../po/../src/sp-text.cpp:420 +msgid "<no name found>" +msgstr "<みつかりませんでした>" + +#: ../../po/../src/sp-text.cpp:426 +#, c-format +msgid "Text on path (%s, %s)" +msgstr "パス上テキスト (%s, %s)" + +#: ../../po/../src/sp-text.cpp:427 +#, c-format +msgid "Text (%s, %s)" +msgstr "テキスト (%s, %s)" + +#. TRANSLATORS: Used for statusbar description for long chains: +#. * "Clone of: Clone of: ... in Layer 1". +#: ../../po/../src/sp-use.cpp:317 +msgid "..." +msgstr "..." + +#: ../../po/../src/sp-use.cpp:325 +#, fuzzy, c-format +msgid "Clone of: %s" +msgstr "%sにリンク" + +#: ../../po/../src/sp-use.cpp:329 +msgid "Orphaned clone" +msgstr "みなしごクローン" + +#: ../../po/../src/spiral-context.cpp:355 +msgid "Ctrl: snap angle" +msgstr "Ctrl: 角度をスナップ" + +#: ../../po/../src/spiral-context.cpp:357 +msgid "Alt: lock spiral radius" +msgstr "Altで螺旋の半径を固定" + +#: ../../po/../src/spiral-context.cpp:469 +#, c-format +msgid "" +"Spiral: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "螺旋: 半径%s, %5g度 … Ctrl: 角度をスナップ" + +#: ../../po/../src/splivarot.cpp:106 +msgid "Select at least 2 paths to perform a boolean operation." +msgstr "すくなくとも二つ以上のパスを選択してください" + +#: ../../po/../src/splivarot.cpp:112 +msgid "" +"Select exactly 2 paths to perform difference, XOR, division, or path " +"cut." +msgstr "分離、パスのカットをするパスを二つ選択してください。" + +#: ../../po/../src/splivarot.cpp:129 ../../po/../src/splivarot.cpp:144 +msgid "" +"Unable to determine the z-order of the objects selected for " +"difference, XOR, division, or path cut." +msgstr "オブジェクトの高さに違いがないため分離、パスのカットができません。" + +#: ../../po/../src/splivarot.cpp:174 +msgid "" +"One of the objects is not a path, cannot perform boolean operation." +msgstr "パスでないオブジェクトは結合できません。" + +#. TRANSLATORS: "to outline" means "to convert stroke to path" +#: ../../po/../src/splivarot.cpp:554 +msgid "Select path(s) to outline." +msgstr "パスにするストロークを選択してください。" + +#. TRANSLATORS: "to outline" means "to convert stroke to path" +#: ../../po/../src/splivarot.cpp:748 +msgid "No stroked paths to outline in the selection." +msgstr "パスにするストロークが選択されていません。" + +#: ../../po/../src/splivarot.cpp:832 +msgid "Selected object is not a path, cannot inset/outset." +msgstr "選択オブジェクトはパスではないためインセット/アウトセットできません" + +#: ../../po/../src/splivarot.cpp:1040 +msgid "Select path(s) to inset/outset." +msgstr "インセット/アウトセットするパスを選択してください。" + +#: ../../po/../src/splivarot.cpp:1257 +msgid "No paths to inset/outset in the selection." +msgstr "インセット/アウトセットするパスが選択されていません。" + +#: ../../po/../src/splivarot.cpp:1390 +msgid "Select path(s) to simplify." +msgstr "簡略化するパスを選択してください。" + +#: ../../po/../src/splivarot.cpp:1417 +msgid "No paths to simplify in the selection." +msgstr "選択オブジェクトに簡略化するパスがありません。" + +#: ../../po/../src/star-context.cpp:362 +msgid "Ctrl: snap angle; keep rays radial" +msgstr "Ctrl: 角度をスナップ" + +#: ../../po/../src/star-context.cpp:470 +#, c-format +msgid "" +"Polygon: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "ポリゴン: 半径%s, %5g度 … Ctrl: 角度をスナップ" + +#: ../../po/../src/star-context.cpp:471 +#, c-format +msgid "Star: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "星: 半径%s, %5g度 … Ctrl: 角度をスナップ" + +#: ../../po/../src/text-chemistry.cpp:90 +msgid "Select a text and a path to put text on path." +msgstr "パス上に追加するテキストとパスを選択してください。" + +#: ../../po/../src/text-chemistry.cpp:95 +msgid "" +"This text object is already put to a path. Remove it from the path " +"first. Use Shift+D to look up its path." +msgstr "" +"このテキストはすでにパスに追加されています。Shift+Dをつかってそ" +"のパスを見つけてください。" + +#. rect is the only SPShape which is not yet, and thus SVG forbids us from putting text on it +#: ../../po/../src/text-chemistry.cpp:101 +msgid "" +"You cannot put text on a rectangle in this version. Convert rectangle to " +"path first." +msgstr "" +"このバージョンでは四角にテキストを追加することができません。四角をパスに変換" +"してください。" + +#: ../../po/../src/text-chemistry.cpp:159 +msgid "Select a text on path to remove it from path." +msgstr "分離するテキストを乗せたパスを選択してください。" + +#: ../../po/../src/text-chemistry.cpp:181 +msgid "No texts-on-paths in the selection." +msgstr "選択済みのパス上にテキストはありません。" + +#: ../../po/../src/text-chemistry.cpp:209 +#: ../../po/../src/text-chemistry.cpp:229 +msgid "Select text(s) to remove kerns from." +msgstr "カーニングを元に戻すテキストを選択してください。" + +#: ../../po/../src/text-chemistry.cpp:250 +msgid "" +"Select a text and one or more paths or shapes to flow text " +"into frame." +msgstr "" +"パス上に追加するテキストとパスまたはオブジェクトを選択し" +"てください。" + +#: ../../po/../src/text-chemistry.cpp:322 +msgid "Select a flowed text to unflow it." +msgstr "フロー解除するフローテキスト選択してください。" + +#: ../../po/../src/text-context.cpp:463 +#, fuzzy +msgid "Click to edit the text, drag to select part of the text." +msgstr "クリック: ノードを選択、または編集" + +#: ../../po/../src/text-context.cpp:465 +#, fuzzy +msgid "" +"Click to edit the flowed text, drag to select part of the text." +msgstr "クリック: ノードを選択、または編集" + +#: ../../po/../src/text-context.cpp:540 +msgid "Non-printable character" +msgstr "印刷不可能な文字" + +#: ../../po/../src/text-context.cpp:589 +#, c-format +msgid "Unicode: %s: %s" +msgstr "ユニコード: %s: %s" + +#: ../../po/../src/text-context.cpp:591 ../../po/../src/text-context.cpp:855 +msgid "Unicode: " +msgstr "ユニコード: " + +#: ../../po/../src/text-context.cpp:615 +msgid "Current layer is hidden. Unhide it to be able to add text." +msgstr "" +"カレントレイヤーは非表示になっています。テキストを追加するために非表示" +"を解除してください。" + +#: ../../po/../src/text-context.cpp:619 +msgid "Current layer is locked. Unlock it to be able to add text." +msgstr "" +"カレントレイヤーはロックされています。テキストを追加するためにロックを" +"解除してください。" + +#: ../../po/../src/text-context.cpp:673 +#, c-format +msgid "Flowed text frame: %s × %s" +msgstr "" + +#: ../../po/../src/text-context.cpp:708 ../../po/../src/text-context.cpp:1464 +msgid "Type text; Enter to start new line." +msgstr "テキスト入力: Enterで新しい行を開始。" + +#: ../../po/../src/text-context.cpp:719 +msgid "Flowed text is created." +msgstr "フローテキストを作成しました。" + +#: ../../po/../src/text-context.cpp:722 +msgid "" +"The frame is too small for the current font size. Flowed text not " +"created." +msgstr "" + +#: ../../po/../src/text-context.cpp:841 +msgid "No-break space" +msgstr "非分割スペース" + +#: ../../po/../src/text-context.cpp:1462 +msgid "Type flowed text; Enter to start new paragraph." +msgstr "" + +#: ../../po/../src/text-context.cpp:1472 ../../po/../src/tools-switch.cpp:189 +#, fuzzy +msgid "" +"Click to select or create text, drag to create flowed text; " +"then type." +msgstr "クリック: テキストを選択、または作成" + +#: ../../po/../src/tools-switch.cpp:141 +msgid "" +"To edit a path, click, Shift+click, or drag around " +"nodes to select them, then drag nodes and handles. Click on an " +"object to select." +msgstr "クリック/ドラッグでパスを整形" + +#: ../../po/../src/tools-switch.cpp:147 +msgid "" +"Drag to create a rectangle. Drag controls to round corners and " +"resize. Click to select." +msgstr "ドラッグで四角を描く。" + +#: ../../po/../src/tools-switch.cpp:153 +msgid "" +"Drag to create an ellipse. Drag controls to make an arc or " +"segment. Click to select." +msgstr "ドラッグで円を描く。" + +#: ../../po/../src/tools-switch.cpp:159 +msgid "" +"Drag to create a star. Drag controls to edit the star shape. " +"Click to select." +msgstr "ドラッグで星を描く。" + +#: ../../po/../src/tools-switch.cpp:165 +msgid "" +"Drag to create a spiral. Drag controls to edit the spiral " +"shape. Click to select." +msgstr "ドラッグで螺旋を描く。" + +#: ../../po/../src/tools-switch.cpp:171 +#, fuzzy +msgid "" +"Drag to create a freehand line. Start drawing with Shift to " +"append to selected path." +msgstr "" +"ドラッグでフリーハンドで線を描く … a: 作成/追加のモード切替え" + +#: ../../po/../src/tools-switch.cpp:177 +#, fuzzy +msgid "" +"Click or click and drag to start a path; with Shift to " +"append to selected path." +msgstr "" +"クリックでノードを作成 … ドラッグ: 滑らかな線を作成、a: " +"作成/追加のモード切替え" + +#: ../../po/../src/tools-switch.cpp:183 +msgid "" +"Drag to paint a calligraphic stroke. Left/right arrow " +"keys adjust width, up/down adjust angle." +msgstr "" +"ドラッグでカリグラフィック線を描く … カーソル[右/左]: 幅を調" +"節、カーソル[上/下]: 角度を調節" + +#: ../../po/../src/tools-switch.cpp:195 +msgid "" +"Drag or double click to create a gradient on selected objects, " +"drag handles to adjust gradients." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:201 +msgid "" +"Click or drag around an area to zoom in, Shift+click to " +"zoom out." +msgstr "" +"クリック/ドラッグ: ズームイン, Shift+クリック: ズームアウト" + +#: ../../po/../src/tools-switch.cpp:213 +msgid "Click and drag between shapes to create a connector." +msgstr "" + +#: ../../po/../src/trace/potrace/inkscape-potrace.cpp:553 +#: ../../po/../src/trace/potrace/inkscape-potrace.cpp:654 +#, c-format +msgid "Trace: %d. %ld nodes" +msgstr "" + +#: ../../po/../src/trace/trace.cpp:53 ../../po/../src/trace/trace.cpp:62 +#: ../../po/../src/trace/trace.cpp:70 +msgid "Select an image to trace" +msgstr "トレースするイメージを選択してください。" + +#: ../../po/../src/trace/trace.cpp:133 +msgid "Trace: No active document" +msgstr "トレース: アクティブなドキュメントがありません" + +#: ../../po/../src/trace/trace.cpp:154 +msgid "Trace: Image has no bitmap data" +msgstr "トレース: イメージはビットマップではありません" + +#: ../../po/../src/trace/trace.cpp:267 +#, c-format +msgid "Trace: Done. %ld nodes created" +msgstr "" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:59 ../../po/../src/verbs.cpp:2212 +msgid "About Inkscape" +msgstr "Inkscapeについて" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:66 +msgid "_Splash" +msgstr "" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:68 +msgid "_Authors" +msgstr "" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:69 +#, fuzzy +msgid "_Translators" +msgstr "変形" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:70 +#, fuzzy +msgid "_License" +msgstr "ライセンス" + +#. TRANSLATORS: This is the filename of the `About Inkscape' picture in +#. the `screens' directory. Thus the translation of "about.svg" should be +#. the filename of its translated version, e.g. about.zh.svg for Chinese. +#. +#. N.B. about.svg changes once per release. (We should probably rename +#. the original to about-0.40.svg etc. as soon as we have a translation. +#. If we do so, then add an item to release-checklist saying that the +#. string here should be changed.) +#. FIXME? INKSCAPE_SCREENSDIR and "about.svg" are in UTF-8, not the +#. native filename encoding... and the filename passed to sp_document_new +#. should be in UTF-*8.. +#: ../../po/../src/ui/dialog/aboutbox.cpp:114 +msgid "about.svg" +msgstr "about.svg" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:464 +msgid "Minimum horizontal gap (in px units) between bounding boxes" +msgstr "" + +#. TRANSLATORS: Horizontal gap +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:466 +#: ../../po/../src/widgets/toolbox.cpp:1556 +msgid "H:" +msgstr "高さ:" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:474 +msgid "Minimum vertical gap (in px units) between bounding boxes" +msgstr "" + +#. TRANSLATORS: Vertical gap +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:476 +msgid "V:" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:734 +msgid "Align" +msgstr "整列" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:735 +msgid "Distribute" +msgstr "配置" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:736 +msgid "Remove overlaps" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:737 +#, fuzzy +msgid "Nodes" +msgstr "ノード" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:742 +msgid "Relative to: " +msgstr "基準: " + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:747 +msgid "Align right sides of objects to left side of anchor" +msgstr "右端を基準の左側にそろえて配置" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:750 +msgid "Align left sides" +msgstr "左揃え" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:753 +msgid "Center on vertical axis" +msgstr "縦にセンタリング" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:756 +msgid "Align right sides" +msgstr "右揃え" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:759 +msgid "Align left sides of objects to right side of anchor" +msgstr "左端を基準の右側にそろえて配置" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:762 +msgid "Align bottoms of objects to top of anchor" +msgstr "下端を基準の上端にそろえて配置" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:765 +msgid "Align tops" +msgstr "上端揃え" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:768 +msgid "Center on horizontal axis" +msgstr "横にセンタリング" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:771 +msgid "Align bottoms" +msgstr "下端揃え" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:774 +msgid "Align tops of objects to bottom of anchor" +msgstr "上端を基準の下端に揃えて配置" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:779 +msgid "Align baseline anchors of texts vertically" +msgstr "ベースラインで垂直に揃える" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:782 +msgid "Align baseline anchors of texts horizontally" +msgstr "ベースラインで水平に揃える" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:787 +msgid "Make horizontal gaps between objects equal" +msgstr "水平方向に等幅配置" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:791 +msgid "Distribute left sides equidistantly" +msgstr "左端の間隔で等幅配置" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:794 +msgid "Distribute centers equidistantly horizontally" +msgstr "中央の間隔で水平方向に等幅配置" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:797 +msgid "Distribute right sides equidistantly" +msgstr "右端の間隔で等幅配置" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:801 +msgid "Make vertical gaps between objects equal" +msgstr "垂直方向に間隔配置" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:805 +msgid "Distribute tops equidistantly" +msgstr "上端の間隔で等幅配置" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:808 +msgid "Distribute centers equidistantly vertically" +msgstr "中央の間隔で垂直方向に等幅配置" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:811 +msgid "Distribute bottoms equidistantly" +msgstr "下端の間隔で等幅配置" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:816 +msgid "Distribute baseline anchors of texts horizontally" +msgstr "ベースラインで水平に整列" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:819 +msgid "Distribute baseline anchors of texts vertically" +msgstr "ベースラインで垂直に整列" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:824 +msgid "Randomize centers in both dimensions" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:827 +msgid "Unclump objects: try to equalize edge-to-edge distances" +msgstr "端と端を等間隔に" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:832 +msgid "" +"Move objects as little as possible so that their bounding boxes do not " +"overlap" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:837 +msgid "Align selected nodes horizontally" +msgstr "選択ノードを水平に配置" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:840 +msgid "Align selected nodes vertically" +msgstr "選択ノードを垂直に配置" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:843 +msgid "Distribute selected nodes horizontally" +msgstr "選択ノードを水平に整列" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:846 +msgid "Distribute selected nodes vertically" +msgstr "選択ノードを垂直に整列" + +#. Rest of the widgetry +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:851 +msgid "Last selected" +msgstr "最後の選択部分" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:852 +msgid "First selected" +msgstr "最初の選択部分" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:853 +msgid "Biggest item" +msgstr "最大オブジェクト" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:854 +msgid "Smallest item" +msgstr "最小オブジェクト" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:856 +#: ../../po/../src/widgets/desktop-widget.cpp:1065 +msgid "Drawing" +msgstr "描画" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:91 +#, fuzzy +msgid "Metadata 1" +msgstr "メタデータ" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:92 +#, fuzzy +msgid "Metadata 2" +msgstr "メタデータ" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:187 +#, fuzzy +msgid "X coordinate of grid origin" +msgstr "選択オブジェクトの垂直位置" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:189 +#, fuzzy +msgid "Y coordinate of grid origin" +msgstr "選択オブジェクトの垂直位置" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:191 +#, fuzzy +msgid "Distance of vertical grid lines" +msgstr "垂直ガイドライン" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:193 +#, fuzzy +msgid "Distance of horizontal grid lines" +msgstr "水平ガイドライン" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:197 +msgid "Max. snapping distance from grid" +msgstr "" + +#: ../../po/../src/ui/dialog/export.cpp:34 +msgid "Export" +msgstr "エクスポート" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:36 +msgid "Fill" +msgstr "フィル" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:37 +msgid "Stroke Paint" +msgstr "ストロークペイント" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:38 +msgid "Stroke Style" +msgstr "ストロークスタイル" + +#: ../../po/../src/ui/dialog/find.cpp:34 +msgid "Find" +msgstr "検索" + +#: ../../po/../src/ui/dialog/memory.cpp:96 +msgid "Heap" +msgstr "ヒープ" + +#: ../../po/../src/ui/dialog/memory.cpp:97 +msgid "In Use" +msgstr "使用中" + +#. TRANSLATORS: "Slack" refers to memory which is in the heap but currently unused. +#. More typical usage is to call this memory "free" rather than "slack". +#: ../../po/../src/ui/dialog/memory.cpp:100 +msgid "Slack" +msgstr "スラック" + +#: ../../po/../src/ui/dialog/memory.cpp:101 +msgid "Total" +msgstr "合計" + +#: ../../po/../src/ui/dialog/memory.cpp:141 +#: ../../po/../src/ui/dialog/memory.cpp:147 +#: ../../po/../src/ui/dialog/memory.cpp:154 +#: ../../po/../src/ui/dialog/memory.cpp:186 +msgid "Unknown" +msgstr "不明" + +#: ../../po/../src/ui/dialog/memory.cpp:167 +msgid "Combined" +msgstr "合計" + +#: ../../po/../src/ui/dialog/memory.cpp:209 +msgid "Recalculate" +msgstr "再計算" + +#: ../../po/../src/ui/dialog/messages.cpp:74 +#, fuzzy +msgid "Ready." +msgstr "赤:" + +#: ../../po/../src/ui/dialog/messages.cpp:75 +msgid "" +"Enable log display by setting dialogs.debug 'redirect' attribute to 1 in " +"preferences.xml" +msgstr "" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:184 +msgid "_Execute Python" +msgstr "Pythonを実行(_E)" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:186 +msgid "_Execute Perl" +msgstr "Perlを実行(_E)" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:195 +msgid "Script" +msgstr "スクリプト" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:205 +msgid "Output" +msgstr "出力" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:215 +msgid "Errors" +msgstr "エラー" + +#. Dialog organization +#: ../../po/../src/ui/dialog/session-player.cpp:73 +msgid "Session file" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:74 +#, fuzzy +msgid "Playback controls" +msgstr "ツールコントロール" + +#: ../../po/../src/ui/dialog/session-player.cpp:75 +#, fuzzy +msgid "Message information" +msgstr "変形をリセット" + +#. Active session file display +#. fixme: Does this mean the active file for the session, or the file for the active session? +#. Please indicate which with a TRANSLATORS comment. +#: ../../po/../src/ui/dialog/session-player.cpp:85 +msgid "Active session file:" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:86 +msgid "Delay (milliseconds):" +msgstr "" + +#. Unload/load buttons +#: ../../po/../src/ui/dialog/session-player.cpp:94 +#, fuzzy +msgid "Close file" +msgstr "閉じる" + +#: ../../po/../src/ui/dialog/session-player.cpp:95 +msgid "Open new file" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:96 +#, fuzzy +msgid "Set delay" +msgstr "デフォルトに設定" + +#: ../../po/../src/ui/dialog/session-player.cpp:138 +#, fuzzy +msgid "Rewind" +msgstr "赤:" + +#: ../../po/../src/ui/dialog/session-player.cpp:139 +msgid "Go back one change" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:140 +#, fuzzy +msgid "Pause" +msgstr "ペースト" + +#: ../../po/../src/ui/dialog/session-player.cpp:141 +msgid "Go forward one change" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:142 +msgid "Play" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:177 +#: ../../po/../src/verbs.cpp:1573 +msgid "Open session file" +msgstr "" + +#. ##Set up the Potrace panel +#. #### brightness #### +#. #### Multiple scanning#### +#. ----Hbox1 +#: ../../po/../src/ui/dialog/tracedialog.cpp:345 +#: ../../po/../src/ui/dialog/tracedialog.cpp:428 +msgid "Brightness" +msgstr "明るさ" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:348 +msgid "Trace by a given brightness level" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:355 +msgid "Brightness cutoff for black/white" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:362 +msgid "Image Brightness" +msgstr "画像の明るさ" + +#. #### canny edge detection #### +#. TRANSLATORS: "Canny" is the name of the inventor of this edge detection method +#: ../../po/../src/ui/dialog/tracedialog.cpp:369 +msgid "Optimal Edge Detection (Canny)" +msgstr "Cannyエッジ検出法" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:372 +msgid "Trace with edge detection by J. Canny's algorithm" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:388 +msgid "Brightness cutoff for adjacent pixels (determines edge thickness)" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:395 +msgid "Edge Detection" +msgstr "エッジ検出" + +#. #### quantization #### +#. TRANSLATORS: Color Quantization: the process of reducing the number of colors +#. in an image by selecting an optimized set of representative colors and then +#. re-applying this reduced set to the original image. +#: ../../po/../src/ui/dialog/tracedialog.cpp:404 +msgid "Color Quantization" +msgstr "色定量化" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:407 +msgid "Trace along the boundaries of reduced colors" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:414 +msgid "The number of reduced colors" +msgstr "減色数" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:416 +msgid "Colors:" +msgstr "色:" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:421 +msgid "Quantization / Reduction" +msgstr "色定量化/減色" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:431 +msgid "Trace the given number of brightness levels" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:438 +msgid "Scans:" +msgstr "スキャン:" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:440 +msgid "The desired number of scans" +msgstr "スキャン回数" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:448 +msgid "Trace the given number of reduced colors" +msgstr "" + +#. ---Hbox3 +#: ../../po/../src/ui/dialog/tracedialog.cpp:454 +msgid "Monochrome" +msgstr "モノクロ" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:457 +msgid "Same as Color, but convert result to grayscale" +msgstr "グレイスケールに変換する" + +#. TRANSLATORS: "Stack" is a verb here +#: ../../po/../src/ui/dialog/tracedialog.cpp:460 +msgid "Stack" +msgstr "スタック" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:463 +msgid "" +"Stack scans vertically (no gaps) or tile horizontally (usually with gaps)" +msgstr "" + +#. TRANSLATORS: "Smooth" is a verb here +#: ../../po/../src/ui/dialog/tracedialog.cpp:466 +msgid "Smooth" +msgstr "潤滑化" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:469 +msgid "Apply Gaussian blur to the bitmap before tracing" +msgstr "ガウスぼかしを行ってからトレース" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:473 +msgid "Multiple Scanning" +msgstr "多重スキャン" + +#. #### Preview #### +#: ../../po/../src/ui/dialog/tracedialog.cpp:479 +#: ../../po/../src/ui/dialog/tracedialog.cpp:489 +msgid "Preview" +msgstr "プレビュー" + +#. do not expand +#: ../../po/../src/ui/dialog/tracedialog.cpp:483 +msgid "Preview the result without actual tracing" +msgstr "実際にトレースせずにプレビューを見る" + +#. #### swap black and white #### +#: ../../po/../src/ui/dialog/tracedialog.cpp:495 +msgid "Invert" +msgstr "復帰" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:499 +msgid "Invert black and white regions for single traces" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:503 +msgid "Thanks to Peter Selinger, http://potrace.sourceforge.net" +msgstr "Peter Selinger (http://potrace.sourceforge.net) に感謝" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:506 +msgid "Credits" +msgstr "クレジット" + +#. done +#. TRANSLATORS: Potrace is an application for transforming bitmaps into +#. vector graphics (http://potrace.sourceforge.net/) +#: ../../po/../src/ui/dialog/tracedialog.cpp:514 +msgid "Potrace" +msgstr "Potrace" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:527 +msgid "Abort a trace in progress" +msgstr "トレースを中止" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:531 +msgid "Execute the trace" +msgstr "トレースを実行" + +#: ../../po/../src/ui/dialog/transformation.cpp:80 +#: ../../po/../src/ui/dialog/transformation.cpp:90 +#, fuzzy +msgid "_Horizontal" +msgstr "横書" + +#: ../../po/../src/ui/dialog/transformation.cpp:80 +msgid "Horizontal displacement (relative) or position (absolute)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:82 +#: ../../po/../src/ui/dialog/transformation.cpp:92 +#, fuzzy +msgid "_Vertical" +msgstr "縦書" + +#: ../../po/../src/ui/dialog/transformation.cpp:82 +msgid "Vertical displacement (relative) or position (absolute)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:84 +#, fuzzy +msgid "_Width" +msgstr "幅(_W):" + +#: ../../po/../src/ui/dialog/transformation.cpp:84 +msgid "Horizontal size increment (absolute or percentage)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:86 +#, fuzzy +msgid "_Height" +msgstr "高さ:" + +#: ../../po/../src/ui/dialog/transformation.cpp:86 +msgid "Vertical size increment (absolute or percentage)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:88 +#, fuzzy +msgid "A_ngle" +msgstr "角度:" + +#: ../../po/../src/ui/dialog/transformation.cpp:88 +#, fuzzy +msgid "Rotation angle (positive = counterclockwise)" +msgstr "オブジェクトを90度反時計まわりに回転" + +#: ../../po/../src/ui/dialog/transformation.cpp:90 +msgid "" +"Horizontal skew angle (positive = counterclockwise), or absolute " +"displacement, or percentage displacement" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:92 +msgid "" +"Vertical skew angle (positive = counterclockwise), or absolute displacement, " +"or percentage displacement" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:95 +#, fuzzy +msgid "Transformation matrix element A" +msgstr "変形" + +#: ../../po/../src/ui/dialog/transformation.cpp:96 +#, fuzzy +msgid "Transformation matrix element B" +msgstr "変形" + +#: ../../po/../src/ui/dialog/transformation.cpp:97 +#, fuzzy +msgid "Transformation matrix element C" +msgstr "変形" + +#: ../../po/../src/ui/dialog/transformation.cpp:98 +#, fuzzy +msgid "Transformation matrix element D" +msgstr "変形" + +#: ../../po/../src/ui/dialog/transformation.cpp:99 +#, fuzzy +msgid "Transformation matrix element E" +msgstr "変形" + +#: ../../po/../src/ui/dialog/transformation.cpp:100 +#, fuzzy +msgid "Transformation matrix element F" +msgstr "変形" + +#: ../../po/../src/ui/dialog/transformation.cpp:102 +#, fuzzy +msgid "Rela_tive move" +msgstr "相対位置" + +#: ../../po/../src/ui/dialog/transformation.cpp:102 +msgid "" +"Add the specified relative displacement to the current position; otherwise, " +"edit the current absolute position directly" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:103 +msgid "Scale proportionally" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:103 +msgid "Preserve the width/height ratio of the scaled objects" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:104 +msgid "Apply to each _object separately" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:104 +msgid "" +"Apply the scale/rotate/skew to each selected object separately; otherwise, " +"transform the selection as a whole" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:105 +#, fuzzy +msgid "Edit c_urrent matrix" +msgstr "現在のレイヤーを前面へ移動" + +#: ../../po/../src/ui/dialog/transformation.cpp:105 +msgid "" +"Edit the current transform= matrix; otherwise, post-multiply transform= by " +"this matrix" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:115 +#, fuzzy +msgid "_Move" +msgstr "移動" + +#: ../../po/../src/ui/dialog/transformation.cpp:118 +#, fuzzy +msgid "_Scale" +msgstr "スケール" + +#: ../../po/../src/ui/dialog/transformation.cpp:121 +#, fuzzy +msgid "_Rotate" +msgstr "回転" + +#: ../../po/../src/ui/dialog/transformation.cpp:124 +#, fuzzy +msgid "Ske_w" +msgstr "傾斜" + +#: ../../po/../src/ui/dialog/transformation.cpp:127 +msgid "Matri_x" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:141 +msgid "Reset the values on the current tab to defaults" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:148 +#, fuzzy +msgid "Apply transformation to selection" +msgstr "変形を適用" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:43 +msgid "_Use SSL" +msgstr "" + +#. Construct dialog interface +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:68 +#, fuzzy +msgid "_Server:" +msgstr "逆転(_R)" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:69 +#, fuzzy +msgid "_Username:" +msgstr "レイヤー名を変更" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:70 +msgid "_Password:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:71 +msgid "P_ort:" +msgstr "" + +#. Buttons +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:99 +#, fuzzy +msgid "Connect" +msgstr "クローン" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:126 +msgid "Establishing connection to Jabber server %1 as user %2" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:131 +msgid "Failed to establish connection to Jabber server %1" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:136 +msgid "Authentication failed on Jabber server %1 as %2" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:141 +msgid "SSL initialization failed when connecting to Jabber server %1" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:147 +msgid "Connected to Jabber server %1 as %2" +msgstr "" + +#. Construct labels +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:75 +#, fuzzy +msgid "Chatroom _name:" +msgstr "レイヤー名" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:76 +msgid "Chatroom _server:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:77 +msgid "Chatroom _password:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:78 +msgid "Chatroom _handle:" +msgstr "" + +#. Button setup and callback registration +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:97 +msgid "Connect to chatroom" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:132 +msgid "Synchronizing with chatroom %1@%2 using the handle %3" +msgstr "" + +#. Construct dialog interface +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:78 +msgid "_User's Jabber ID:" +msgstr "" + +#. Buttons +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:82 +msgid "_Invite user" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:83 +#, fuzzy +msgid "_Cancel" +msgstr "キャンセル" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:94 +msgid "Buddy List" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:170 +msgid "Sending whiteboard invitation to %1" +msgstr "" + +#. FIXME: strings are replaced by placeholders, NOT to be translated until the code is enabled +#. See http://sourceforge.net/mailarchive/message.php?msg_id=11746016 for details +#. File menu +#. Edit menu +#. View menu +#. Layer menu +#. Object menu +#. Path menu +#. add(Gtk::StockItem(CLEANUP, _("PLACEHOLDER, do not translate"))); (using Gtk::Stock::CLEAR) +#. Text menu +#. About menu +#. Tools toolbox +#. Select Tool controls +#. Node Tool controls +#. Calligraphy Tool controls +#. Session playback controls +#: ../../po/../src/ui/stock-items.cpp:34 ../../po/../src/ui/stock-items.cpp:35 +#: ../../po/../src/ui/stock-items.cpp:36 ../../po/../src/ui/stock-items.cpp:37 +#: ../../po/../src/ui/stock-items.cpp:38 ../../po/../src/ui/stock-items.cpp:39 +#: ../../po/../src/ui/stock-items.cpp:40 ../../po/../src/ui/stock-items.cpp:41 +#: ../../po/../src/ui/stock-items.cpp:42 ../../po/../src/ui/stock-items.cpp:43 +#: ../../po/../src/ui/stock-items.cpp:46 ../../po/../src/ui/stock-items.cpp:47 +#: ../../po/../src/ui/stock-items.cpp:48 ../../po/../src/ui/stock-items.cpp:49 +#: ../../po/../src/ui/stock-items.cpp:50 ../../po/../src/ui/stock-items.cpp:51 +#: ../../po/../src/ui/stock-items.cpp:52 ../../po/../src/ui/stock-items.cpp:53 +#: ../../po/../src/ui/stock-items.cpp:54 ../../po/../src/ui/stock-items.cpp:55 +#: ../../po/../src/ui/stock-items.cpp:56 ../../po/../src/ui/stock-items.cpp:57 +#: ../../po/../src/ui/stock-items.cpp:58 ../../po/../src/ui/stock-items.cpp:59 +#: ../../po/../src/ui/stock-items.cpp:62 ../../po/../src/ui/stock-items.cpp:63 +#: ../../po/../src/ui/stock-items.cpp:64 ../../po/../src/ui/stock-items.cpp:65 +#: ../../po/../src/ui/stock-items.cpp:66 ../../po/../src/ui/stock-items.cpp:67 +#: ../../po/../src/ui/stock-items.cpp:68 ../../po/../src/ui/stock-items.cpp:69 +#: ../../po/../src/ui/stock-items.cpp:70 ../../po/../src/ui/stock-items.cpp:71 +#: ../../po/../src/ui/stock-items.cpp:72 ../../po/../src/ui/stock-items.cpp:73 +#: ../../po/../src/ui/stock-items.cpp:74 ../../po/../src/ui/stock-items.cpp:75 +#: ../../po/../src/ui/stock-items.cpp:76 ../../po/../src/ui/stock-items.cpp:77 +#: ../../po/../src/ui/stock-items.cpp:78 ../../po/../src/ui/stock-items.cpp:79 +#: ../../po/../src/ui/stock-items.cpp:80 ../../po/../src/ui/stock-items.cpp:81 +#: ../../po/../src/ui/stock-items.cpp:82 ../../po/../src/ui/stock-items.cpp:83 +#: ../../po/../src/ui/stock-items.cpp:84 ../../po/../src/ui/stock-items.cpp:85 +#: ../../po/../src/ui/stock-items.cpp:86 ../../po/../src/ui/stock-items.cpp:87 +#: ../../po/../src/ui/stock-items.cpp:88 ../../po/../src/ui/stock-items.cpp:89 +#: ../../po/../src/ui/stock-items.cpp:92 ../../po/../src/ui/stock-items.cpp:93 +#: ../../po/../src/ui/stock-items.cpp:94 ../../po/../src/ui/stock-items.cpp:95 +#: ../../po/../src/ui/stock-items.cpp:96 ../../po/../src/ui/stock-items.cpp:97 +#: ../../po/../src/ui/stock-items.cpp:98 ../../po/../src/ui/stock-items.cpp:99 +#: ../../po/../src/ui/stock-items.cpp:100 +#: ../../po/../src/ui/stock-items.cpp:101 +#: ../../po/../src/ui/stock-items.cpp:102 +#: ../../po/../src/ui/stock-items.cpp:103 +#: ../../po/../src/ui/stock-items.cpp:104 +#: ../../po/../src/ui/stock-items.cpp:105 +#: ../../po/../src/ui/stock-items.cpp:108 +#: ../../po/../src/ui/stock-items.cpp:109 +#: ../../po/../src/ui/stock-items.cpp:110 +#: ../../po/../src/ui/stock-items.cpp:111 +#: ../../po/../src/ui/stock-items.cpp:112 +#: ../../po/../src/ui/stock-items.cpp:113 +#: ../../po/../src/ui/stock-items.cpp:114 +#: ../../po/../src/ui/stock-items.cpp:115 +#: ../../po/../src/ui/stock-items.cpp:116 +#: ../../po/../src/ui/stock-items.cpp:117 +#: ../../po/../src/ui/stock-items.cpp:118 +#: ../../po/../src/ui/stock-items.cpp:119 +#: ../../po/../src/ui/stock-items.cpp:120 +#: ../../po/../src/ui/stock-items.cpp:121 +#: ../../po/../src/ui/stock-items.cpp:122 +#: ../../po/../src/ui/stock-items.cpp:123 +#: ../../po/../src/ui/stock-items.cpp:124 +#: ../../po/../src/ui/stock-items.cpp:125 +#: ../../po/../src/ui/stock-items.cpp:126 +#: ../../po/../src/ui/stock-items.cpp:127 +#: ../../po/../src/ui/stock-items.cpp:130 +#: ../../po/../src/ui/stock-items.cpp:131 +#: ../../po/../src/ui/stock-items.cpp:132 +#: ../../po/../src/ui/stock-items.cpp:133 +#: ../../po/../src/ui/stock-items.cpp:134 +#: ../../po/../src/ui/stock-items.cpp:135 +#: ../../po/../src/ui/stock-items.cpp:136 +#: ../../po/../src/ui/stock-items.cpp:137 +#: ../../po/../src/ui/stock-items.cpp:138 +#: ../../po/../src/ui/stock-items.cpp:139 +#: ../../po/../src/ui/stock-items.cpp:140 +#: ../../po/../src/ui/stock-items.cpp:141 +#: ../../po/../src/ui/stock-items.cpp:142 +#: ../../po/../src/ui/stock-items.cpp:143 +#: ../../po/../src/ui/stock-items.cpp:144 +#: ../../po/../src/ui/stock-items.cpp:145 +#: ../../po/../src/ui/stock-items.cpp:146 +#: ../../po/../src/ui/stock-items.cpp:150 +#: ../../po/../src/ui/stock-items.cpp:151 +#: ../../po/../src/ui/stock-items.cpp:152 +#: ../../po/../src/ui/stock-items.cpp:153 +#: ../../po/../src/ui/stock-items.cpp:156 +#: ../../po/../src/ui/stock-items.cpp:157 +#: ../../po/../src/ui/stock-items.cpp:158 +#: ../../po/../src/ui/stock-items.cpp:161 +#: ../../po/../src/ui/stock-items.cpp:162 +#: ../../po/../src/ui/stock-items.cpp:163 +#: ../../po/../src/ui/stock-items.cpp:164 +#: ../../po/../src/ui/stock-items.cpp:165 +#: ../../po/../src/ui/stock-items.cpp:166 +#: ../../po/../src/ui/stock-items.cpp:167 +#: ../../po/../src/ui/stock-items.cpp:168 +#: ../../po/../src/ui/stock-items.cpp:169 +#: ../../po/../src/ui/stock-items.cpp:170 +#: ../../po/../src/ui/stock-items.cpp:171 +#: ../../po/../src/ui/stock-items.cpp:172 +#: ../../po/../src/ui/stock-items.cpp:175 +#: ../../po/../src/ui/stock-items.cpp:176 +#: ../../po/../src/ui/stock-items.cpp:177 +#: ../../po/../src/ui/stock-items.cpp:178 +#: ../../po/../src/ui/stock-items.cpp:181 +#: ../../po/../src/ui/stock-items.cpp:182 +#: ../../po/../src/ui/stock-items.cpp:183 +#: ../../po/../src/ui/stock-items.cpp:184 +#: ../../po/../src/ui/stock-items.cpp:185 +#: ../../po/../src/ui/stock-items.cpp:186 +#: ../../po/../src/ui/stock-items.cpp:187 +#: ../../po/../src/ui/stock-items.cpp:188 +#: ../../po/../src/ui/stock-items.cpp:189 +#: ../../po/../src/ui/stock-items.cpp:190 +#: ../../po/../src/ui/stock-items.cpp:191 +#: ../../po/../src/ui/stock-items.cpp:194 +#: ../../po/../src/ui/stock-items.cpp:195 +#: ../../po/../src/ui/stock-items.cpp:198 +#: ../../po/../src/ui/stock-items.cpp:199 +#: ../../po/../src/ui/stock-items.cpp:200 +#: ../../po/../src/ui/stock-items.cpp:201 +#: ../../po/../src/ui/stock-items.cpp:202 +msgid "PLACEHOLDER, do not translate" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:88 +msgid "small" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:89 +msgid "medium" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:90 +#, fuzzy +msgid "large" +msgstr "ターゲット:" + +#: ../../po/../src/ui/widget/panel.cpp:91 +msgid "huge" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:106 +#, fuzzy +msgid "List" +msgstr "インセット" + +#: ../../po/../src/ui/widget/selected-style.cpp:67 +msgid "F:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:68 +msgid "S:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:69 +msgid "O:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:95 +msgid "N/A" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:98 +#: ../../po/../src/ui/widget/selected-style.cpp:712 +#, fuzzy +msgid "Nothing selected" +msgstr "グラデーションが選択されていません" + +#: ../../po/../src/ui/widget/selected-style.cpp:103 +msgid "No fill" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:103 +#, fuzzy +msgid "No stroke" +msgstr " (ストローク)" + +#: ../../po/../src/ui/widget/selected-style.cpp:105 +#: ../../po/../src/widgets/paint-selector.cpp:190 +msgid "Pattern" +msgstr "パターン" + +#: ../../po/../src/ui/widget/selected-style.cpp:108 +#: ../../po/../src/widgets/paint-selector.cpp:885 +msgid "Pattern fill" +msgstr "パターン" + +#: ../../po/../src/ui/widget/selected-style.cpp:108 +#, fuzzy +msgid "Pattern stroke" +msgstr "間隔" + +#: ../../po/../src/ui/widget/selected-style.cpp:110 +#, fuzzy +msgid "L Gradient" +msgstr "グラデーション" + +#: ../../po/../src/ui/widget/selected-style.cpp:113 +#, fuzzy +msgid "Linear gradient fill" +msgstr "線形グラデーション" + +#: ../../po/../src/ui/widget/selected-style.cpp:113 +#, fuzzy +msgid "Linear gradient stroke" +msgstr "線形グラデーション" + +#: ../../po/../src/ui/widget/selected-style.cpp:115 +#, fuzzy +msgid "R Gradient" +msgstr "グラデーション" + +#: ../../po/../src/ui/widget/selected-style.cpp:118 +#, fuzzy +msgid "Radial gradient fill" +msgstr "放射グラデーション" + +#: ../../po/../src/ui/widget/selected-style.cpp:118 +#, fuzzy +msgid "Radial gradient stroke" +msgstr "放射グラデーション" + +#: ../../po/../src/ui/widget/selected-style.cpp:120 +#, fuzzy +msgid "Different" +msgstr "差分(_D)" + +#: ../../po/../src/ui/widget/selected-style.cpp:123 +#, fuzzy +msgid "Different fills" +msgstr "差分(_D)" + +#: ../../po/../src/ui/widget/selected-style.cpp:123 +#, fuzzy +msgid "Different strokes" +msgstr "差分(_D)" + +#: ../../po/../src/ui/widget/selected-style.cpp:125 +#, fuzzy +msgid "Unset" +msgstr "インセット" + +#. TRANSLATORS COMMENT: unset is a verb here +#: ../../po/../src/ui/widget/selected-style.cpp:128 +#: ../../po/../src/ui/widget/selected-style.cpp:182 +msgid "Unset fill" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:128 +#: ../../po/../src/ui/widget/selected-style.cpp:182 +#, fuzzy +msgid "Unset stroke" +msgstr " (ストローク)" + +#: ../../po/../src/ui/widget/selected-style.cpp:131 +#, fuzzy +msgid "Flat color fill" +msgstr "フラットカラー" + +#: ../../po/../src/ui/widget/selected-style.cpp:131 +#, fuzzy +msgid "Flat color stroke" +msgstr "フラットカラー" + +#. TRANSLATOR COMMENT: A means "Averaged" +#: ../../po/../src/ui/widget/selected-style.cpp:134 +#, fuzzy +msgid "A" +msgstr "_A" + +#: ../../po/../src/ui/widget/selected-style.cpp:137 +#, fuzzy +msgid "Fill is averaged over selected objects" +msgstr "オブジェクトの重なる部分を切りぬく" + +#: ../../po/../src/ui/widget/selected-style.cpp:137 +#, fuzzy +msgid "Stroke is averaged over selected objects" +msgstr "オブジェクトの重なる部分を切り出す" + +#. TRANSLATOR COMMENT: M means "Multiple" +#: ../../po/../src/ui/widget/selected-style.cpp:140 +#, fuzzy +msgid "M" +msgstr "_M" + +#: ../../po/../src/ui/widget/selected-style.cpp:143 +#, fuzzy +msgid "Multiple selected objects have the same fill" +msgstr "選択オブジェクトを垂直に反転" + +#: ../../po/../src/ui/widget/selected-style.cpp:143 +#, fuzzy +msgid "Multiple selected objects have the same stroke" +msgstr "選択オブジェクトを垂直に反転" + +#: ../../po/../src/ui/widget/selected-style.cpp:145 +#, fuzzy +msgid "Edit fill..." +msgstr "編集" + +#: ../../po/../src/ui/widget/selected-style.cpp:145 +#, fuzzy +msgid "Edit stroke..." +msgstr "編集" + +#: ../../po/../src/ui/widget/selected-style.cpp:149 +#, fuzzy +msgid "Last set color" +msgstr "フラットカラー" + +#: ../../po/../src/ui/widget/selected-style.cpp:153 +#, fuzzy +msgid "Last selected color" +msgstr "最後の選択部分" + +#: ../../po/../src/ui/widget/selected-style.cpp:157 +msgid "White" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:161 +#: ../../po/../src/widgets/sp-color-scales.cpp:461 +#: ../../po/../src/widgets/sp-color-scales.cpp:462 +msgid "Black" +msgstr "黒:" + +#: ../../po/../src/ui/widget/selected-style.cpp:165 +#, fuzzy +msgid "Copy color" +msgstr "色" + +#: ../../po/../src/ui/widget/selected-style.cpp:169 +#, fuzzy +msgid "Paste color" +msgstr "フラットカラー" + +#: ../../po/../src/ui/widget/selected-style.cpp:173 +#, fuzzy +msgid "Swap fill and stroke" +msgstr "フィル/ストローク" + +#: ../../po/../src/ui/widget/selected-style.cpp:177 +msgid "Make fill opaque" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:177 +msgid "Make stroke opaque" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:186 +#, fuzzy +msgid "Remove fill" +msgstr " 削除(_M) " + +#: ../../po/../src/ui/widget/selected-style.cpp:186 +#, fuzzy +msgid "Remove stroke" +msgstr "リンクを除去" + +#: ../../po/../src/ui/widget/selected-style.cpp:718 +#, fuzzy +msgid "Master opacity" +msgstr "透過性(_O)" + +#: ../../po/../src/ui/widget/selected-style.cpp:744 +msgid "0 (transparent)" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:768 +msgid "1.0 (opaque)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1046 +msgid "Moved to next layer." +msgstr "次のレイヤーに移動" + +#: ../../po/../src/verbs.cpp:1048 +#, fuzzy +msgid "Cannot move past last layer." +msgstr "前のレイヤーを移動できません。" + +#: ../../po/../src/verbs.cpp:1057 +msgid "Moved to previous layer." +msgstr "前のレイヤーに切替え" + +#: ../../po/../src/verbs.cpp:1059 +#, fuzzy +msgid "Cannot move past first layer." +msgstr "前のレイヤーを移動できません。" + +#: ../../po/../src/verbs.cpp:1076 ../../po/../src/verbs.cpp:1150 +msgid "No current layer." +msgstr "レイヤーはありません。" + +#: ../../po/../src/verbs.cpp:1105 +#, c-format +msgid "Raised layer %s." +msgstr "レイヤー%sを前面に移動しました。" + +#: ../../po/../src/verbs.cpp:1109 +#, c-format +msgid "Lowered layer %s." +msgstr "レイヤー%sを背面に移動しました。" + +#: ../../po/../src/verbs.cpp:1118 +#, fuzzy +msgid "Cannot move layer any further." +msgstr "レイヤーを移動できません。" + +#. TRANSLATORS: this means "The layer has been deleted." +#: ../../po/../src/verbs.cpp:1148 +msgid "Deleted layer." +msgstr "レイヤーを削除しました。" + +#: ../../po/../src/verbs.cpp:1544 +msgid "" +"You need to connect to a Jabber server before sharing a document with " +"another user." +msgstr "" + +#: ../../po/../src/verbs.cpp:1559 +msgid "" +"You need to connect to a Jabber server before sharing a document with a " +"chatroom." +msgstr "" + +#: ../../po/../src/verbs.cpp:1569 +msgid "XML node tracker has not been initialized; nothing to dump" +msgstr "" + +#. TRANSLATORS: If you have translated the keys.svg file to your language, then +#. translate this string as "keys.LANG.svg" (where LANG is your language code); +#. otherwise leave as "keys.svg". +#: ../../po/../src/verbs.cpp:1631 +msgid "keys.svg" +msgstr "keys.svg" + +#. TRANSLATORS: If you have translated the tutorial-basic.svg file to your language, +#. then translate this string as "tutorial-basic.LANG.svg" (where LANG is your language +#. code); otherwise leave as "tutorial-basic.svg". +#: ../../po/../src/verbs.cpp:1667 +msgid "tutorial-basic.svg" +msgstr "tutorial-basic.ja.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1671 +msgid "tutorial-shapes.svg" +msgstr "tutorial-shapes.ja.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1675 +msgid "tutorial-advanced.svg" +msgstr "tutorial-advanced.ja.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1679 +msgid "tutorial-tracing.svg" +msgstr "tutorial-tracing.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1683 +msgid "tutorial-calligraphy.svg" +msgstr "tutorial-calligraphy.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1687 +msgid "tutorial-elements.svg" +msgstr "tutorial-elements.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1691 +msgid "tutorial-tips.svg" +msgstr "tutorial-tips.svg" + +#: ../../po/../src/verbs.cpp:1842 +msgid "Does nothing" +msgstr "何もしない" + +#. File +#: ../../po/../src/verbs.cpp:1845 +msgid "Default" +msgstr "デフォルト" + +#: ../../po/../src/verbs.cpp:1845 +msgid "Create new document from default template" +msgstr "デフォルトテンプレートで新規ドキュメントを作成" + +#: ../../po/../src/verbs.cpp:1847 +msgid "_Open..." +msgstr "開く..." + +#: ../../po/../src/verbs.cpp:1848 +msgid "Open existing document" +msgstr "既存のドキュメントを開く" + +#: ../../po/../src/verbs.cpp:1849 +msgid "Re_vert" +msgstr "ファイルに復帰" + +#: ../../po/../src/verbs.cpp:1850 +msgid "Revert to the last saved version of document (changes will be lost)" +msgstr "最後に保存された状態に復帰。(変更は失われます)" + +#: ../../po/../src/verbs.cpp:1851 +msgid "_Save" +msgstr "保存" + +#: ../../po/../src/verbs.cpp:1851 +msgid "Save document" +msgstr "ドキュメントの保存" + +#: ../../po/../src/verbs.cpp:1853 +msgid "Save _As..." +msgstr "名前をつけて保存..." + +#: ../../po/../src/verbs.cpp:1854 +msgid "Save document under new name" +msgstr "新規ファイル名でドキュメントを保存" + +#: ../../po/../src/verbs.cpp:1855 +msgid "_Print..." +msgstr "印刷..." + +#: ../../po/../src/verbs.cpp:1855 +msgid "Print document" +msgstr "ドキュメントを印刷" + +#. TRANSLATORS: "Vacuum Defs" means "Clean up defs" (so as to remove unused definitions) +#: ../../po/../src/verbs.cpp:1858 +msgid "Vac_uum Defs" +msgstr "バキューム" + +#: ../../po/../src/verbs.cpp:1858 +#, fuzzy +msgid "Remove unused predefined items from the <defs> of the document" +msgstr "未使用のオブジェクトを<defs>から削除する" + +#: ../../po/../src/verbs.cpp:1860 +msgid "Print _Direct" +msgstr "直接印刷..." + +#: ../../po/../src/verbs.cpp:1861 +#, fuzzy +msgid "Print directly without prompting to a file or pipe" +msgstr "ファイルまたはパイプに印刷" + +#: ../../po/../src/verbs.cpp:1862 +msgid "Print Previe_w" +msgstr "印刷プレビュー" + +#: ../../po/../src/verbs.cpp:1863 +msgid "Preview document printout" +msgstr "印刷ドキュメントのプレビュー" + +#: ../../po/../src/verbs.cpp:1864 +msgid "_Import..." +msgstr "インポート" + +#: ../../po/../src/verbs.cpp:1865 +msgid "Import bitmap or SVG image into document" +msgstr "ビットマップまたはSVGイメージをインポート" + +#: ../../po/../src/verbs.cpp:1866 +msgid "_Export Bitmap..." +msgstr "エクスポート" + +#: ../../po/../src/verbs.cpp:1867 +msgid "Export document or selection as a bitmap image" +msgstr "ドキュメントを PNG ビットマップとして出力" + +#: ../../po/../src/verbs.cpp:1868 +msgid "N_ext Window" +msgstr "次のウィンドウ" + +#: ../../po/../src/verbs.cpp:1869 +msgid "Switch to the next document window" +msgstr "次のウィンドウに切替え" + +#: ../../po/../src/verbs.cpp:1870 +msgid "P_revious Window" +msgstr "前のウィンドウ" + +#: ../../po/../src/verbs.cpp:1871 +msgid "Switch to the previous document window" +msgstr "前のウィンドウに切替え" + +#: ../../po/../src/verbs.cpp:1872 +msgid "_Close" +msgstr "閉じる" + +#: ../../po/../src/verbs.cpp:1873 +msgid "Close window" +msgstr "ウインドウを閉じる" + +#: ../../po/../src/verbs.cpp:1874 +msgid "_Quit" +msgstr "終了" + +#: ../../po/../src/verbs.cpp:1874 +msgid "Quit Inkscape" +msgstr "Inkscapeを終了" + +#. Edit +#: ../../po/../src/verbs.cpp:1877 +msgid "_Undo" +msgstr "元に戻す" + +#: ../../po/../src/verbs.cpp:1877 +msgid "Undo last action" +msgstr "最後の操作をキャンセル" + +#: ../../po/../src/verbs.cpp:1879 +msgid "_Redo" +msgstr "やり直し" + +#: ../../po/../src/verbs.cpp:1880 +msgid "Do again last undone action" +msgstr "戻した操作を再実行" + +#: ../../po/../src/verbs.cpp:1881 +msgid "Cu_t" +msgstr "カット" + +#: ../../po/../src/verbs.cpp:1882 +msgid "Cut selection to clipboard" +msgstr "選択オブジェクトをクリップボードへ切り取る" + +#: ../../po/../src/verbs.cpp:1883 +msgid "_Copy" +msgstr "コピー" + +#: ../../po/../src/verbs.cpp:1884 +msgid "Copy selection to clipboard" +msgstr "選択オブジェクトをクリップボードへ複製" + +#: ../../po/../src/verbs.cpp:1885 +msgid "_Paste" +msgstr "ペースト" + +#: ../../po/../src/verbs.cpp:1886 +#, fuzzy +msgid "Paste objects from clipboard to mouse point" +msgstr "オブジェクトをクリップボードからペースト" + +#: ../../po/../src/verbs.cpp:1887 +msgid "Paste _Style" +msgstr "スタイルをペースト" + +#: ../../po/../src/verbs.cpp:1888 +msgid "Apply style of the copied object to selection" +msgstr "選択オブジェクトにスタイルをペースト" + +#: ../../po/../src/verbs.cpp:1889 +msgid "Paste _In Place" +msgstr "同じ場所にペースト" + +#: ../../po/../src/verbs.cpp:1890 +#, fuzzy +msgid "Paste objects from clipboard to the original location" +msgstr "コピー元と同じ場所にペースト" + +#: ../../po/../src/verbs.cpp:1891 +msgid "_Delete" +msgstr "削除" + +#: ../../po/../src/verbs.cpp:1892 +msgid "Delete selection" +msgstr "選択したオブジェクトを削除" + +#: ../../po/../src/verbs.cpp:1893 +msgid "Duplic_ate" +msgstr "複製" + +#: ../../po/../src/verbs.cpp:1894 +#, fuzzy +msgid "Duplicate selected objects" +msgstr "選択オブジェクトを複製" + +#: ../../po/../src/verbs.cpp:1895 +msgid "Clo_ne" +msgstr "クローン" + +#: ../../po/../src/verbs.cpp:1896 +msgid "Create a clone of selected object (a copy linked to the original)" +msgstr "選択オブジェクトのクローンを作成" + +#: ../../po/../src/verbs.cpp:1897 +msgid "Unlin_k Clone" +msgstr "クローンの解除" + +#: ../../po/../src/verbs.cpp:1898 +msgid "Cut the clone's link to its original" +msgstr "オリジナルとのリンクを解除する" + +#: ../../po/../src/verbs.cpp:1899 +msgid "Select _Original" +msgstr "オリジナルを選択" + +#: ../../po/../src/verbs.cpp:1900 +msgid "Select the object to which the clone is linked" +msgstr "クローンするオブジェクトを選択してください" + +#. TRANSLATORS: Convert selection to a rectangle with tiled pattern fill +#: ../../po/../src/verbs.cpp:1902 +msgid "O_bjects to Pattern" +msgstr "オブジェクトをパターンに" + +#: ../../po/../src/verbs.cpp:1903 +msgid "Convert selection to a rectangle with tiled pattern fill" +msgstr "選択オブジェクトをパターンタイルにする" + +#. TRANSLATORS: Extract objects from a tiled pattern fill +#: ../../po/../src/verbs.cpp:1905 +msgid "Pattern to Ob_jects" +msgstr "パターンをオブジェクトに" + +#: ../../po/../src/verbs.cpp:1906 +msgid "Extract objects from a tiled pattern fill" +msgstr "パターンタイル化を解除" + +#: ../../po/../src/verbs.cpp:1907 +msgid "Clea_r All" +msgstr "全て消去" + +#: ../../po/../src/verbs.cpp:1908 +msgid "Delete all objects from document" +msgstr "ドキュメントからすべてのオブジェクトを削除します" + +#: ../../po/../src/verbs.cpp:1909 +msgid "Select Al_l" +msgstr "全て選択" + +#: ../../po/../src/verbs.cpp:1910 +msgid "Select all objects or all nodes" +msgstr "全てのオブジェクト、パスを選択" + +#: ../../po/../src/verbs.cpp:1911 +msgid "Select All in All La_yers" +msgstr "全てのレイヤーの全てのオブジェクトを選択" + +#: ../../po/../src/verbs.cpp:1912 +msgid "Select all objects in all visible and unlocked layers" +msgstr "全てのレイヤーの可視でロックされていないオブジェクトを選択" + +#: ../../po/../src/verbs.cpp:1913 +msgid "In_vert Selection" +msgstr "選択を逆転" + +#: ../../po/../src/verbs.cpp:1914 +msgid "Invert selection (unselect what is selected and select everything else)" +msgstr "逆選択(選択オブジェクトの選択を解除、非選択オブジェクトを選択)" + +#: ../../po/../src/verbs.cpp:1915 +msgid "Invert in All Layers" +msgstr "全てのレイヤーで逆転" + +#: ../../po/../src/verbs.cpp:1916 +msgid "Invert selection in all visible and unlocked layers" +msgstr "可視、非ロックのレイヤー全てで選択を逆転" + +#: ../../po/../src/verbs.cpp:1917 +msgid "D_eselect" +msgstr "選択解除" + +#: ../../po/../src/verbs.cpp:1918 +msgid "Deselect any selected objects or nodes" +msgstr "選択オブジェクトの選択解除" + +#. Selection +#: ../../po/../src/verbs.cpp:1921 +msgid "Raise to _Top" +msgstr "最前面へ" + +#: ../../po/../src/verbs.cpp:1922 +msgid "Raise selection to top" +msgstr "最前面に移動" + +#: ../../po/../src/verbs.cpp:1923 +msgid "Lower to _Bottom" +msgstr "最背面へ" + +#: ../../po/../src/verbs.cpp:1924 +msgid "Lower selection to bottom" +msgstr "最背面に移動" + +#: ../../po/../src/verbs.cpp:1925 +msgid "_Raise" +msgstr "前面へ" + +#: ../../po/../src/verbs.cpp:1926 +msgid "Raise selection one step" +msgstr "前面に移動" + +#: ../../po/../src/verbs.cpp:1927 +msgid "_Lower" +msgstr "背面へ" + +#: ../../po/../src/verbs.cpp:1928 +msgid "Lower selection one step" +msgstr "背面に移動" + +#: ../../po/../src/verbs.cpp:1929 +msgid "_Group" +msgstr "グループ化(_G)" + +#: ../../po/../src/verbs.cpp:1930 +msgid "Group selected objects" +msgstr "選択したオブジェクトをグループ化" + +#: ../../po/../src/verbs.cpp:1932 +#, fuzzy +msgid "Ungroup selected groups" +msgstr "選択したグループのグループ解除" + +#: ../../po/../src/verbs.cpp:1934 +msgid "_Put on Path" +msgstr "テキストをパス上に(_P)" + +#: ../../po/../src/verbs.cpp:1935 +msgid "Put text on path" +msgstr "パスの上にテキストを置く" + +#: ../../po/../src/verbs.cpp:1936 +msgid "_Remove from Path" +msgstr "パスからテキストを分離(_R)" + +#: ../../po/../src/verbs.cpp:1937 +msgid "Remove text from path" +msgstr "パスに乗せたテキストを分離" + +#: ../../po/../src/verbs.cpp:1938 +msgid "Remove Manual _Kerns" +msgstr "カーニングを元に戻す" + +#. TRANSLATORS: "glyph": An image used in the visual representation of characters; +#. roughly speaking, how a character looks. A font is a set of glyphs. +#: ../../po/../src/verbs.cpp:1941 +msgid "Remove all manual kerns and glyph rotations from a text object" +msgstr "テキストのカーニング、回転を元に戻す" + +#: ../../po/../src/verbs.cpp:1943 +msgid "_Union" +msgstr "統合(_U)" + +#: ../../po/../src/verbs.cpp:1944 +msgid "Union of selected objects" +msgstr "選択したオブジェクトを統合" + +#: ../../po/../src/verbs.cpp:1945 +msgid "_Intersection" +msgstr "切り出し(_I)" + +#: ../../po/../src/verbs.cpp:1946 +msgid "Intersection of selected objects" +msgstr "オブジェクトの重なる部分を切り出す" + +#: ../../po/../src/verbs.cpp:1947 +msgid "_Difference" +msgstr "差分(_D)" + +#: ../../po/../src/verbs.cpp:1948 +msgid "Difference of selected objects (bottom minus top)" +msgstr "後で選択したオブジェクトで切り取る" + +#: ../../po/../src/verbs.cpp:1949 +msgid "E_xclusion" +msgstr "切りぬき(_X)" + +#: ../../po/../src/verbs.cpp:1950 +msgid "Exclusive OR of selected objects" +msgstr "オブジェクトの重なる部分を切りぬく" + +#: ../../po/../src/verbs.cpp:1951 +msgid "Di_vision" +msgstr "分離(_V)" + +#: ../../po/../src/verbs.cpp:1952 +msgid "Cut the bottom object into pieces" +msgstr "後で選択したオブジェクトの重なる部分のみ残す" + +#. TRANSLATORS: "to cut a path" is not the same as "to break a path apart" - see the +#. Advanced tutorial for more info +#: ../../po/../src/verbs.cpp:1955 +msgid "Cut _Path" +msgstr "パスをカット(_P)" + +#: ../../po/../src/verbs.cpp:1956 +msgid "Cut the bottom object's stroke into pieces, removing fill" +msgstr "重なった部分のパスのみを残す" + +#. TRANSLATORS: "outset": expand a shape by offsetting the object's path, +#. i.e. by displacing it perpendicular to the path in each point. +#. See also the Advanced Tutorial for explanation. +#: ../../po/../src/verbs.cpp:1960 +msgid "Outs_et" +msgstr "アウトセット(_E)" + +#: ../../po/../src/verbs.cpp:1961 +#, fuzzy +msgid "Outset selected paths" +msgstr "パスの外郭を抽出" + +#: ../../po/../src/verbs.cpp:1963 +msgid "O_utset Path by 1 px" +msgstr "1px アウトセット" + +#: ../../po/../src/verbs.cpp:1964 +#, fuzzy +msgid "Outset selected paths by 1 px" +msgstr "1px 外郭を抽出" + +#: ../../po/../src/verbs.cpp:1966 +msgid "O_utset Path by 10 px" +msgstr "10px アウトセット" + +#: ../../po/../src/verbs.cpp:1967 +#, fuzzy +msgid "Outset selected paths by 10 px" +msgstr "10px 外郭を抽出" + +#. TRANSLATORS: "inset": contract a shape by offsetting the object's path, +#. i.e. by displacing it perpendicular to the path in each point. +#. See also the Advanced Tutorial for explanation. +#: ../../po/../src/verbs.cpp:1971 +msgid "I_nset" +msgstr "インセット(_N)" + +#: ../../po/../src/verbs.cpp:1972 +#, fuzzy +msgid "Inset selected paths" +msgstr "パスの内殻を抽出" + +#: ../../po/../src/verbs.cpp:1974 +msgid "I_nset Path by 1 px" +msgstr "1px インセット" + +#: ../../po/../src/verbs.cpp:1975 +#, fuzzy +msgid "Inset selected paths by 1 px" +msgstr "パスの1px 内殻を抽出" + +#: ../../po/../src/verbs.cpp:1977 +msgid "I_nset Path by 10 px" +msgstr "10px インセット" + +#: ../../po/../src/verbs.cpp:1978 +#, fuzzy +msgid "Inset selected paths by 10 px" +msgstr "パスの10px 内殻を抽出" + +#: ../../po/../src/verbs.cpp:1980 +msgid "D_ynamic Offset" +msgstr "ダイナミックオフセット(_Y)" + +#: ../../po/../src/verbs.cpp:1980 +msgid "Create a dynamic offset object" +msgstr "ダイナミックオフセットを作成" + +#: ../../po/../src/verbs.cpp:1982 +msgid "_Linked Offset" +msgstr "リンクオフセット(_L)" + +#: ../../po/../src/verbs.cpp:1983 +msgid "Create a dynamic offset object linked to the original path" +msgstr "オリジナルにリンクするオフセットを作成" + +#: ../../po/../src/verbs.cpp:1985 +msgid "_Stroke to Path" +msgstr "ストロークをパスに変換" + +#: ../../po/../src/verbs.cpp:1986 +#, fuzzy +msgid "Convert selected strokes to paths" +msgstr "選択ストロークをパスに変換" + +#: ../../po/../src/verbs.cpp:1987 +msgid "Si_mplify" +msgstr "パスの簡略化(_M)" + +#: ../../po/../src/verbs.cpp:1988 +#, fuzzy +msgid "Simplify selected paths by removing extra nodes" +msgstr "選択パスからノードを削除し簡略化" + +#: ../../po/../src/verbs.cpp:1989 +msgid "_Reverse" +msgstr "逆転(_R)" + +#: ../../po/../src/verbs.cpp:1990 +#, fuzzy +msgid "Reverses the direction of selected paths; useful for flipping markers" +msgstr "パスの方向を逆転させる" + +#. TRANSLATORS: "to trace" means "to convert a bitmap to vector graphics" (to vectorize) +#: ../../po/../src/verbs.cpp:1992 +msgid "_Trace Bitmap" +msgstr "ビットマップをトレース" + +#: ../../po/../src/verbs.cpp:1993 +msgid "Convert bitmap object to paths" +msgstr "ビットマップをパスに変換" + +#: ../../po/../src/verbs.cpp:1994 +msgid "_Make a Bitmap Copy" +msgstr "ビットマップコピー" + +#: ../../po/../src/verbs.cpp:1995 +msgid "Export selection to a bitmap and insert it into document" +msgstr "ビットマップイメージをエクスポート" + +#: ../../po/../src/verbs.cpp:1996 +msgid "_Combine" +msgstr "連結(_C)" + +#: ../../po/../src/verbs.cpp:1997 +msgid "Combine several paths into one" +msgstr "パスをひとつに結合" + +#. TRANSLATORS: "to cut a path" is not the same as "to break a path apart" - see the +#. Advanced tutorial for more info +#: ../../po/../src/verbs.cpp:2000 +msgid "Break _Apart" +msgstr "分割(_A)" + +#: ../../po/../src/verbs.cpp:2001 +#, fuzzy +msgid "Break selected paths into subpaths" +msgstr "選択したパスをサブパスに分割" + +#: ../../po/../src/verbs.cpp:2002 +msgid "Gri_d Arrange..." +msgstr "グリッド配置" + +#: ../../po/../src/verbs.cpp:2003 +msgid "Arrange selection in grid pattern" +msgstr "選択オブジェクトをグリッドパターンで配置" + +#. Layer +#: ../../po/../src/verbs.cpp:2005 +msgid "_Add Layer..." +msgstr "新規レイヤー(_A)" + +#: ../../po/../src/verbs.cpp:2006 +msgid "Create a new layer" +msgstr "新規レイヤーを作成" + +#: ../../po/../src/verbs.cpp:2007 +msgid "Re_name Layer..." +msgstr "レイヤー名を変更(_n)" + +#: ../../po/../src/verbs.cpp:2008 +msgid "Rename the current layer" +msgstr "現在のレイヤーの名称を変更" + +#: ../../po/../src/verbs.cpp:2009 +msgid "Switch to Layer Abov_e" +msgstr "前面のレイヤーに切替え(_e)" + +#: ../../po/../src/verbs.cpp:2010 +msgid "Switch to the layer above the current" +msgstr "前面のレイヤーに切替え" + +#: ../../po/../src/verbs.cpp:2011 +msgid "Switch to Layer Belo_w" +msgstr "背面のレイヤーに切替え(_w)" + +#: ../../po/../src/verbs.cpp:2012 +msgid "Switch to the layer below the current" +msgstr "背面のレイヤーに切替え" + +#: ../../po/../src/verbs.cpp:2013 +msgid "Move Selection to Layer Abo_ve" +msgstr "前面のレイヤーに移動(_v)" + +#: ../../po/../src/verbs.cpp:2014 +msgid "Move selection to the layer above the current" +msgstr "選択オブジェクトを前面のレイヤーに移動" + +#: ../../po/../src/verbs.cpp:2015 +msgid "Move Selection to Layer Bel_ow" +msgstr "背面のレイヤーに移動(_o)" + +#: ../../po/../src/verbs.cpp:2016 +msgid "Move selection to the layer below the current" +msgstr "選択オブジェクトを背面のレイヤーに移動" + +#: ../../po/../src/verbs.cpp:2017 +msgid "Layer to _Top" +msgstr "レイヤーを最前面へ(_T)" + +#: ../../po/../src/verbs.cpp:2018 +msgid "Raise the current layer to the top" +msgstr "現在のレイヤーを最前面へ移動" + +#: ../../po/../src/verbs.cpp:2019 +msgid "Layer to _Bottom" +msgstr "レイヤーを最背面へ(_B)" + +#: ../../po/../src/verbs.cpp:2020 +msgid "Lower the current layer to the bottom" +msgstr "現在のレイヤーを最背面へ移動" + +#: ../../po/../src/verbs.cpp:2021 +msgid "_Raise Layer" +msgstr "レイヤーを前面へ(_R)" + +#: ../../po/../src/verbs.cpp:2022 +msgid "Raise the current layer" +msgstr "現在のレイヤーを前面へ移動" + +#: ../../po/../src/verbs.cpp:2023 +msgid "_Lower Layer" +msgstr "レイヤーを背面へ(_L)" + +#: ../../po/../src/verbs.cpp:2024 +msgid "Lower the current layer" +msgstr "現在のレイヤーを背面へ移動" + +#: ../../po/../src/verbs.cpp:2025 +msgid "_Delete Current Layer" +msgstr "レイヤーを削除(_D)" + +#: ../../po/../src/verbs.cpp:2026 +msgid "Delete the current layer" +msgstr "現在のレイヤーを削除" + +#. Object +#: ../../po/../src/verbs.cpp:2029 +#, fuzzy +msgid "Rotate _90° CW" +msgstr "90度回転(_9)" + +#: ../../po/../src/verbs.cpp:2030 +#, fuzzy +msgid "Rotate selection 90° clockwise" +msgstr "オブジェクトを90度時計まわりに回転" + +#: ../../po/../src/verbs.cpp:2031 +#, fuzzy +msgid "Rotate 9_0° CCW" +msgstr "90度反時計回転(_0)" + +#: ../../po/../src/verbs.cpp:2032 +#, fuzzy +msgid "Rotate selection 90° counter-clockwise" +msgstr "オブジェクトを90度反時計まわりに回転" + +#: ../../po/../src/verbs.cpp:2033 +msgid "Remove _Transformations" +msgstr "変形を解除(_T)" + +#: ../../po/../src/verbs.cpp:2034 +msgid "Remove transformations from object" +msgstr "オブジェクトの変形を解除" + +#: ../../po/../src/verbs.cpp:2035 +msgid "_Object to Path" +msgstr "オブジェクトをパスに変換(_O)" + +#: ../../po/../src/verbs.cpp:2036 +msgid "Convert selected objects to paths" +msgstr "選択オブジェクトをパスに変換" + +#: ../../po/../src/verbs.cpp:2037 +msgid "_Flow into Frame" +msgstr "テキストをフレームに挿入(_F)" + +#: ../../po/../src/verbs.cpp:2038 +msgid "Put text into frames" +msgstr "テキストをフレームの中に挿入" + +#: ../../po/../src/verbs.cpp:2039 +msgid "_Unflow" +msgstr "フロー解除(_U)" + +#: ../../po/../src/verbs.cpp:2040 +msgid "Remove text from frame (creates a single-line text object)" +msgstr "フレームからテキストを分離" + +#: ../../po/../src/verbs.cpp:2041 +msgid "_Convert to Text" +msgstr "テキストに変換" + +#: ../../po/../src/verbs.cpp:2042 +msgid "Convert flowed text to regular text objects (preserves appearance)" +msgstr "フローテキストを元のテキストオブジェクトに変換" + +#: ../../po/../src/verbs.cpp:2044 +msgid "Flip _Horizontal" +msgstr "水平に反転(_H)" + +#: ../../po/../src/verbs.cpp:2044 +msgid "Flips selected objects horizontally" +msgstr "選択オブジェクトを水平に反転" + +#: ../../po/../src/verbs.cpp:2047 +msgid "Flip _Vertical" +msgstr "垂直に反転(_V)" + +#: ../../po/../src/verbs.cpp:2047 +msgid "Flips selected objects vertically" +msgstr "選択オブジェクトを垂直に反転" + +#. Tools +#: ../../po/../src/verbs.cpp:2051 +msgid "Select" +msgstr "選択" + +#: ../../po/../src/verbs.cpp:2052 +msgid "Select and transform objects" +msgstr "変形" + +#: ../../po/../src/verbs.cpp:2053 +msgid "Node Edit" +msgstr "ノード" + +#: ../../po/../src/verbs.cpp:2054 +msgid "Edit path nodes or control handles" +msgstr "パス/ノード" + +#: ../../po/../src/verbs.cpp:2056 +msgid "Create rectangles and squares" +msgstr "長方形や正方形" + +#: ../../po/../src/verbs.cpp:2058 +msgid "Create circles, ellipses, and arcs" +msgstr "円/弧" + +#: ../../po/../src/verbs.cpp:2060 +msgid "Create stars and polygons" +msgstr "星型/ポリゴン" + +#: ../../po/../src/verbs.cpp:2062 +msgid "Create spirals" +msgstr "螺旋" + +#: ../../po/../src/verbs.cpp:2064 +msgid "Draw freehand lines" +msgstr "フリーハンド線" + +#: ../../po/../src/verbs.cpp:2066 +msgid "Draw Bezier curves and straight lines" +msgstr "ベジエ線/直線" + +#: ../../po/../src/verbs.cpp:2068 +msgid "Draw calligraphic lines" +msgstr "カリグラフィック線" + +#: ../../po/../src/verbs.cpp:2070 +msgid "Create and edit text objects" +msgstr "テキスト" + +#: ../../po/../src/verbs.cpp:2072 +msgid "Create and edit gradients" +msgstr "グラデーションを作成/編集" + +#: ../../po/../src/verbs.cpp:2074 +msgid "Zoom in or out" +msgstr "ズーム" + +#: ../../po/../src/verbs.cpp:2076 +msgid "Pick averaged colors from image" +msgstr "スポイト" + +#: ../../po/../src/verbs.cpp:2078 +msgid "Create connectors" +msgstr "新規コネクタの作成" + +#. Tool prefs +#: ../../po/../src/verbs.cpp:2081 +msgid "Selector Preferences" +msgstr "セレクタの設定" + +#: ../../po/../src/verbs.cpp:2082 +msgid "Open Preferences for the Selector tool" +msgstr "セレクタの設定を開く" + +#: ../../po/../src/verbs.cpp:2083 +msgid "Node Tool Preferences" +msgstr "ノードツールの設定" + +#: ../../po/../src/verbs.cpp:2084 +msgid "Open Preferences for the Node tool" +msgstr "ノードツールの設定を開く" + +#: ../../po/../src/verbs.cpp:2085 +msgid "Rectangle Preferences" +msgstr "矩形の設定" + +#: ../../po/../src/verbs.cpp:2086 +msgid "Open Preferences for the Rectangle tool" +msgstr "矩形の設定を開く" + +#: ../../po/../src/verbs.cpp:2087 +msgid "Ellipse Preferences" +msgstr "円/弧の設定" + +#: ../../po/../src/verbs.cpp:2088 +msgid "Open Preferences for the Ellipse tool" +msgstr "円/弧の設定を開く" + +#: ../../po/../src/verbs.cpp:2089 +msgid "Star Preferences" +msgstr "星の設定" + +#: ../../po/../src/verbs.cpp:2090 +msgid "Open Preferences for the Star tool" +msgstr "星の設定を開く" + +#: ../../po/../src/verbs.cpp:2091 +msgid "Spiral Preferences" +msgstr "螺旋のプロパティ" + +#: ../../po/../src/verbs.cpp:2092 +msgid "Open Preferences for the Spiral tool" +msgstr "螺旋のプロパティを開く" + +#: ../../po/../src/verbs.cpp:2093 +msgid "Pencil Preferences" +msgstr "鉛筆の設定" + +#: ../../po/../src/verbs.cpp:2094 +msgid "Open Preferences for the Pencil tool" +msgstr "鉛筆の設定を開く" + +#: ../../po/../src/verbs.cpp:2095 +msgid "Pen Preferences" +msgstr "ペンの設定" + +#: ../../po/../src/verbs.cpp:2096 +msgid "Open Preferences for the Pen tool" +msgstr "ペンの設定を開く" + +#: ../../po/../src/verbs.cpp:2097 +msgid "Calligraphic Preferences" +msgstr "カリグラフィック線の設定" + +#: ../../po/../src/verbs.cpp:2098 +msgid "Open Preferences for the Calligraphy tool" +msgstr "カリグラフィック線の設定を開く" + +#: ../../po/../src/verbs.cpp:2099 +msgid "Text Preferences" +msgstr "テキストの設定" + +#: ../../po/../src/verbs.cpp:2100 +msgid "Open Preferences for the Text tool" +msgstr "テキストの設定を開く" + +#: ../../po/../src/verbs.cpp:2101 +msgid "Gradient Preferences" +msgstr "グラデーションの設定" + +#: ../../po/../src/verbs.cpp:2102 +msgid "Open Preferences for the Gradient tool" +msgstr "グラデーションツールの設定を開く" + +#: ../../po/../src/verbs.cpp:2103 +msgid "Zoom Preferences" +msgstr "ズームの設定" + +#: ../../po/../src/verbs.cpp:2104 +msgid "Open Preferences for the Zoom tool" +msgstr "ズームの設定を開く" + +#: ../../po/../src/verbs.cpp:2105 +msgid "Dropper Preferences" +msgstr "スポイトの設定" + +#: ../../po/../src/verbs.cpp:2106 +msgid "Open Preferences for the Dropper tool" +msgstr "スポイトの設定を開く" + +#: ../../po/../src/verbs.cpp:2107 +msgid "Connector Preferences" +msgstr "コネクタの設定" + +#: ../../po/../src/verbs.cpp:2108 +msgid "Open Preferences for the Connector tool" +msgstr "コネクタの設定を開く" + +#. Zoom/View +#: ../../po/../src/verbs.cpp:2111 +msgid "Zoom In" +msgstr "ズーム" + +#: ../../po/../src/verbs.cpp:2111 +msgid "Zoom in" +msgstr "ズーム" + +#: ../../po/../src/verbs.cpp:2112 +msgid "Zoom Out" +msgstr "ズームアウト" + +#: ../../po/../src/verbs.cpp:2112 +msgid "Zoom out" +msgstr "ズームアウト" + +#: ../../po/../src/verbs.cpp:2113 +msgid "_Rulers" +msgstr "定規" + +#: ../../po/../src/verbs.cpp:2113 +msgid "Show or hide the canvas rulers" +msgstr "定規を表示/非表示" + +#: ../../po/../src/verbs.cpp:2114 +msgid "Scroll_bars" +msgstr "スクロールバー" + +#: ../../po/../src/verbs.cpp:2114 +msgid "Show or hide the canvas scrollbars" +msgstr "スクロールバーを表示/非表示" + +#: ../../po/../src/verbs.cpp:2115 +msgid "_Grid" +msgstr "グリッド" + +#: ../../po/../src/verbs.cpp:2116 +msgid "G_uides" +msgstr "ガイド" + +#: ../../po/../src/verbs.cpp:2117 +msgid "Nex_t Zoom" +msgstr "次のズーム" + +#: ../../po/../src/verbs.cpp:2117 +msgid "Next zoom (from the history of zooms)" +msgstr "次のズーム (ズーム履歴を使用)" + +#: ../../po/../src/verbs.cpp:2119 +msgid "Pre_vious Zoom" +msgstr "前のズーム" + +#: ../../po/../src/verbs.cpp:2119 +msgid "Previous zoom (from the history of zooms)" +msgstr "前のズーム (ズーム履歴を使用)" + +#: ../../po/../src/verbs.cpp:2121 +msgid "Zoom 1:_1" +msgstr "ズーム 1:1" + +#: ../../po/../src/verbs.cpp:2121 +msgid "Zoom to 1:1" +msgstr "1:1 にズーム" + +#: ../../po/../src/verbs.cpp:2123 +msgid "Zoom 1:_2" +msgstr "ズーム 1:2" + +#: ../../po/../src/verbs.cpp:2123 +msgid "Zoom to 1:2" +msgstr "1:2 にズーム" + +#: ../../po/../src/verbs.cpp:2125 +msgid "_Zoom 2:1" +msgstr "ズーム 2:1" + +#: ../../po/../src/verbs.cpp:2125 +msgid "Zoom to 2:1" +msgstr "2:1 にズーム" + +#: ../../po/../src/verbs.cpp:2128 +msgid "_Fullscreen" +msgstr "フルスクリーン" + +#: ../../po/../src/verbs.cpp:2128 +msgid "Stretch this document window to full screen" +msgstr "フルスクリーンに切替え" + +#: ../../po/../src/verbs.cpp:2131 +msgid "Duplic_ate Window" +msgstr "ウインドウを複製" + +#: ../../po/../src/verbs.cpp:2131 +msgid "Open a new window with the same document" +msgstr "現在のドキュメントを新しいウィンドウで開く" + +#: ../../po/../src/verbs.cpp:2133 +msgid "_New View Preview" +msgstr "新規のビュー/プレビュー" + +#: ../../po/../src/verbs.cpp:2134 +msgid "New View Preview" +msgstr "新規のビュー/プレビュー" + +#. "view_new_preview" +#: ../../po/../src/verbs.cpp:2136 +#, fuzzy +msgid "_Normal" +msgstr "標準" + +#: ../../po/../src/verbs.cpp:2137 +msgid "Switch to normal display mode" +msgstr "" + +#: ../../po/../src/verbs.cpp:2138 +#, fuzzy +msgid "_Outline" +msgstr "枠のみ" + +#: ../../po/../src/verbs.cpp:2139 +msgid "Switch to outline (wireframe) display mode" +msgstr "" + +#: ../../po/../src/verbs.cpp:2141 +msgid "Ico_n Preview" +msgstr "アイコンプレビュー" + +#: ../../po/../src/verbs.cpp:2142 +msgid "Open a window to preview items at different icon resolutions" +msgstr "" + +#: ../../po/../src/verbs.cpp:2144 +msgid "Zoom to fit page in window" +msgstr "ページに合わせてズーム" + +#: ../../po/../src/verbs.cpp:2145 +msgid "Page _Width" +msgstr "ページ幅" + +#: ../../po/../src/verbs.cpp:2146 +msgid "Zoom to fit page width in window" +msgstr "ページ幅に合わせてズーム" + +#: ../../po/../src/verbs.cpp:2148 +msgid "Zoom to fit drawing in window" +msgstr "描画をウィンドウに合わせる" + +#: ../../po/../src/verbs.cpp:2150 +msgid "Zoom to fit selection in window" +msgstr "選択オブジェクトに合わせてズーム" + +#. Dialogs +#: ../../po/../src/verbs.cpp:2153 +msgid "In_kscape Preferences..." +msgstr "Inkscapeの設定..." + +#: ../../po/../src/verbs.cpp:2154 +msgid "Global Inkscape preferences" +msgstr "Inkscapeの設定を開く" + +#: ../../po/../src/verbs.cpp:2155 +msgid "_Document Preferences..." +msgstr "ドキュメントの設定..." + +#: ../../po/../src/verbs.cpp:2156 +msgid "Preferences saved with the document" +msgstr "ドキュメントの設定を開く" + +#: ../../po/../src/verbs.cpp:2157 +msgid "_Fill and Stroke..." +msgstr "フィル/ストローク..." + +#: ../../po/../src/verbs.cpp:2158 +msgid "Fill and Stroke dialog" +msgstr "フィル/ストローク ダイアログ" + +#. TRANSLATORS: "Swatches" means: color samples +#: ../../po/../src/verbs.cpp:2160 +msgid "S_watches..." +msgstr "スウォッチ..." + +#: ../../po/../src/verbs.cpp:2161 +msgid "View color swatches" +msgstr "スウォッチ ダイアログ" + +#: ../../po/../src/verbs.cpp:2162 +msgid "Transfor_m..." +msgstr "変形..." + +#: ../../po/../src/verbs.cpp:2163 +msgid "Transform dialog" +msgstr "変形 ダイアログ" + +#: ../../po/../src/verbs.cpp:2164 +msgid "_Align and Distribute..." +msgstr "整列/配置..." + +#: ../../po/../src/verbs.cpp:2165 +msgid "Align and Distribute dialog" +msgstr "整列/配置 ダイアログ" + +#: ../../po/../src/verbs.cpp:2166 +msgid "_Text and Font..." +msgstr "テキスト/フォント..." + +#: ../../po/../src/verbs.cpp:2167 +msgid "Text and Font dialog" +msgstr "テキスト/フォント ダイアログ" + +#: ../../po/../src/verbs.cpp:2168 +msgid "_XML Editor..." +msgstr "XMLエディタ..." + +#: ../../po/../src/verbs.cpp:2169 +msgid "XML Editor" +msgstr "XMLエディタ" + +#: ../../po/../src/verbs.cpp:2170 +msgid "_Find..." +msgstr "検索..." + +#: ../../po/../src/verbs.cpp:2171 +msgid "Find objects in document" +msgstr "ドキュメントから検索" + +#: ../../po/../src/verbs.cpp:2172 +msgid "_Messages..." +msgstr "デバッグ..." + +#: ../../po/../src/verbs.cpp:2173 +msgid "View debug messages" +msgstr "デバッグメッセージを表示" + +#: ../../po/../src/verbs.cpp:2174 +msgid "S_cripts..." +msgstr "スクリプト..." + +#: ../../po/../src/verbs.cpp:2175 +msgid "Run scripts" +msgstr "スクリプトを実行" + +#: ../../po/../src/verbs.cpp:2176 +msgid "Show/Hide D_ialogs" +msgstr "ダイアログの表示/非表示" + +#: ../../po/../src/verbs.cpp:2177 +msgid "Show or hide all active dialogs" +msgstr "アクティブな全ダイアログの表示/非表示" + +#. TRANSLATORS: "Tile clones" means: "Create tiled clones" +#: ../../po/../src/verbs.cpp:2179 +msgid "Tile clones..." +msgstr "クローンタイル..." + +#: ../../po/../src/verbs.cpp:2180 +msgid "Create and arrange multiple clones of selection" +msgstr "選択オブジェクトのクローンを並べて生成" + +#: ../../po/../src/verbs.cpp:2181 +msgid "_Object Properties..." +msgstr "プロパティ..." + +#: ../../po/../src/verbs.cpp:2182 +msgid "Object Properties dialog" +msgstr "オブジェクトのプロパティ" + +#: ../../po/../src/verbs.cpp:2185 +msgid "_Connect to Jabber server..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2185 +msgid "Connect to a Jabber server" +msgstr "" + +#: ../../po/../src/verbs.cpp:2187 +msgid "Share with _user..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2187 +msgid "Establish a whiteboard session with another Jabber user" +msgstr "" + +#: ../../po/../src/verbs.cpp:2189 +msgid "Share with _chatroom..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2189 +msgid "" +"Join a chatroom to start a new whiteboard session or join one in progress" +msgstr "" + +#: ../../po/../src/verbs.cpp:2191 +msgid "_Dump XML node tracker" +msgstr "" + +#: ../../po/../src/verbs.cpp:2191 +msgid "Dump the contents of the XML tracker to the console" +msgstr "" + +#: ../../po/../src/verbs.cpp:2193 +msgid "_Open session file..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2193 +msgid "Open and browse through records of past whiteboard sessions" +msgstr "" + +#: ../../po/../src/verbs.cpp:2195 +msgid "Session file playback" +msgstr "" + +#: ../../po/../src/verbs.cpp:2197 +msgid "_Disconnect from session" +msgstr "" + +#: ../../po/../src/verbs.cpp:2199 +msgid "Disconnect from _server" +msgstr "" + +#: ../../po/../src/verbs.cpp:2201 +msgid "_Input Devices..." +msgstr "入力デバイス(_I)" + +#: ../../po/../src/verbs.cpp:2202 +msgid "Configure extended input devices" +msgstr "拡張入力デバイスの設定" + +#. Help +#: ../../po/../src/verbs.cpp:2205 +msgid "_Keys and Mouse" +msgstr "キー/マウス(_K)" + +#: ../../po/../src/verbs.cpp:2206 +msgid "Key and mouse shortcuts reference" +msgstr "キー/マウスのショートカット設定" + +#: ../../po/../src/verbs.cpp:2207 +msgid "About E_xtensions" +msgstr "エクステンション" + +#: ../../po/../src/verbs.cpp:2208 +msgid "About Extensions..." +msgstr "エクステンション..." + +#: ../../po/../src/verbs.cpp:2209 +msgid "About _Memory" +msgstr "メモリ" + +#: ../../po/../src/verbs.cpp:2210 +msgid "About Memory..." +msgstr "メモリ..." + +#: ../../po/../src/verbs.cpp:2211 +msgid "_About Inkscape" +msgstr "Inkscapeについて(_A)" + +#. "help_about" +#. new HelpVerb(SP_VERB_SHOW_LICENSE, "ShowLicense", N_("Modifying or Redistributing Inkscape"), +#. N_("Show license to modify and/or redistribute Inkscape: GNU GPL"), NULL), +#. Tutorials +#: ../../po/../src/verbs.cpp:2217 +msgid "Inkscape: _Basic" +msgstr "Inkscape: 基本" + +#: ../../po/../src/verbs.cpp:2218 +msgid "Getting started with Inkscape" +msgstr "Inkscapeではじめよう" + +#. "tutorial_basic" +#: ../../po/../src/verbs.cpp:2219 +msgid "Inkscape: _Shapes" +msgstr "Inkscape: シェイプ(_S)" + +#: ../../po/../src/verbs.cpp:2220 +msgid "Using shape tools to create and edit shapes" +msgstr "シェイプツールを使った創作と整形" + +#: ../../po/../src/verbs.cpp:2221 +msgid "Inkscape: _Advanced" +msgstr "Inkscape: 上級" + +#: ../../po/../src/verbs.cpp:2222 +msgid "Advanced Inkscape topics" +msgstr "Inkscape上級テクニック" + +#. "tutorial_advanced" +#. TRANSLATORS: "to trace" means "to convert a bitmap to vector graphics" (to vectorize) +#: ../../po/../src/verbs.cpp:2224 +msgid "Inkscape: T_racing" +msgstr "Inkscape: トレーシング" + +#: ../../po/../src/verbs.cpp:2225 +msgid "Using bitmap tracing" +msgstr "ビットマップトレーシングの使い方" + +#. "tutorial_tracing" +#: ../../po/../src/verbs.cpp:2226 +msgid "Inkscape: _Calligraphy" +msgstr "Inkscape: カリグラフィ" + +#: ../../po/../src/verbs.cpp:2227 +msgid "Using the Calligraphy pen tool" +msgstr "カリグラフィペンの使い方" + +#: ../../po/../src/verbs.cpp:2228 +msgid "_Elements of Design" +msgstr "デザイン" + +#: ../../po/../src/verbs.cpp:2229 +msgid "Principles of design in the tutorial form" +msgstr "デザイン理論についてのチュートリアル" + +#. "tutorial_design" +#: ../../po/../src/verbs.cpp:2230 +msgid "_Tips and Tricks" +msgstr "ヒント(_T)" + +#: ../../po/../src/verbs.cpp:2231 +msgid "Miscellaneous tips and tricks" +msgstr "その他のテクニック" + +#. "tutorial_tips" +#. Effect +#: ../../po/../src/verbs.cpp:2234 +msgid "Previous Effect" +msgstr "前のエフェクト" + +#: ../../po/../src/verbs.cpp:2235 +msgid "Repeat the last effect with the same settings" +msgstr "" + +#. "tutorial_tips" +#: ../../po/../src/verbs.cpp:2236 +msgid "Previous Effect Settings..." +msgstr "前のエフェクト設定..." + +#: ../../po/../src/verbs.cpp:2237 +msgid "Repeat the last effect with new settings" +msgstr "前回のエフェクト設定を繰り返す" + +#: ../../po/../src/widgets/dash-selector.cpp:106 +msgid "Dash pattern" +msgstr "点線パターン" + +#: ../../po/../src/widgets/dash-selector.cpp:121 +msgid "Pattern offset" +msgstr "間隔" + +#: ../../po/../src/widgets/desktop-widget.cpp:240 +msgid "Zoom drawing if window size changes" +msgstr "ウインドウサイズの変更に合わせてズームする" + +#: ../../po/../src/widgets/desktop-widget.cpp:298 +msgid "Cursor coordinates" +msgstr "カーソル位置" + +#. display the initial welcome message in the statusbar +#: ../../po/../src/widgets/desktop-widget.cpp:324 +msgid "" +"Welcome to Inkscape! Use shape or freehand tools to create objects; " +"use selector (arrow) to move or transform them." +msgstr "Inkscapeへようこそ!" + +#: ../../po/../src/widgets/desktop-widget.cpp:372 +#, c-format +msgid "%s: %d - Inkscape" +msgstr "%s: %d - Inkscape" + +#: ../../po/../src/widgets/desktop-widget.cpp:374 +#, c-format +msgid "%s - Inkscape" +msgstr "%s - Inkscape" + +#: ../../po/../src/widgets/desktop-widget.cpp:532 +#, c-format +msgid "" +"Save changes to document \"%s\" before " +"closing?\n" +"\n" +"If you close without saving, your changes will be discarded." +msgstr "" +"終了する前に\"%s\"に保存しますか?\n" +"\n" +"もし保存せずに終了すると変更が反映されません。" + +#: ../../po/../src/widgets/desktop-widget.cpp:548 +#: ../../po/../src/widgets/desktop-widget.cpp:612 +msgid "Close _without saving" +msgstr "変更を破棄" + +#: ../../po/../src/widgets/desktop-widget.cpp:595 +#, c-format +msgid "" +"The file \"%s\" was saved with a " +"format (%s) that may cause data loss!\n" +"\n" +"Do you want to save this file in another format?" +msgstr "" +"\"%s\"はデータの損失を起こす可能性のあ" +"る(%s)フォーマットで保存されています。\n" +"\n" +"別のフォーマットで保存しますか?" + +#. Family frame +#: ../../po/../src/widgets/font-selector.cpp:156 +msgid "Font family" +msgstr "フォント" + +#. Style frame +#: ../../po/../src/widgets/font-selector.cpp:184 +msgid "Style" +msgstr "スタイル" + +#: ../../po/../src/widgets/font-selector.cpp:219 +msgid "Font size:" +msgstr "サイズ:" + +#. TRANSLATORS: Test string used in text and font dialog (when no +#. * text has been entered) to get a preview of the font. Choose +#. * some representative characters that users of your locale will be +#. * interested in. +#: ../../po/../src/widgets/font-selector.cpp:554 +msgid "AaBbCcIiPpQq12368.;/()" +msgstr "AaBbCcIiPpQq12368.;/()" + +#: ../../po/../src/widgets/gradient-selector.cpp:137 +#: ../../po/../src/widgets/gradient-toolbar.cpp:524 +msgid "Duplicate" +msgstr "コピー" + +#: ../../po/../src/widgets/gradient-selector.cpp:142 +#: ../../po/../src/widgets/gradient-toolbar.cpp:535 +msgid "Edit..." +msgstr "編集" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/pservers.html#LinearGradientSpreadMethodAttribute +#: ../../po/../src/widgets/gradient-selector.cpp:159 +msgid "" +"Whether to fill with flat color beyond the ends of the gradient vector " +"(spreadMethod=\"pad\"), or repeat the gradient in the same direction " +"(spreadMethod=\"repeat\"), or repeat the gradient in alternating opposite " +"directions (spreadMethod=\"reflect\")" +msgstr "" +"グラデーションの繰り返し方法を次から選びます。\n" +" なし: グラデーションを繰り返さない\n" +" リフレクト: グラデーションを反転しながら繰り返し\n" +" ダイレクト: グラデーションをそのまま繰り返し" + +#: ../../po/../src/widgets/gradient-selector.cpp:165 +msgid "none" +msgstr "なし" + +#: ../../po/../src/widgets/gradient-selector.cpp:169 +msgid "reflected" +msgstr "リフレクト" + +#: ../../po/../src/widgets/gradient-selector.cpp:173 +msgid "direct" +msgstr "ダイレクト" + +#: ../../po/../src/widgets/gradient-selector.cpp:181 +msgid "Repeat:" +msgstr "繰り返し:" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:217 +msgid "No gradients" +msgstr "グラデーションが選択されていません" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:226 +msgid "Nothing selected" +msgstr "何も選択されていません" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:237 +msgid "No gradients in selection" +msgstr "グラデーションが選択されていません" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:247 +msgid "Multiple gradients" +msgstr "多数のグラデーションを選択" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:525 +msgid "" +"If the gradient is used by more than one object, create a copy of it for the " +"selected object(s)" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:536 +msgid "Edit the stops of the gradient" +msgstr "グラデーション色を編集" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:593 +#: ../../po/../src/widgets/toolbox.cpp:1103 +#: ../../po/../src/widgets/toolbox.cpp:1192 +#: ../../po/../src/widgets/toolbox.cpp:1485 +#: ../../po/../src/widgets/toolbox.cpp:1534 +#: ../../po/../src/widgets/toolbox.cpp:1766 +#: ../../po/../src/widgets/toolbox.cpp:1801 +#: ../../po/../src/widgets/toolbox.cpp:2331 +#: ../../po/../src/widgets/toolbox.cpp:2370 +msgid "New:" +msgstr "タイプ" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:606 +msgid "Create linear gradient" +msgstr "線形グラデーションを作成" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:620 +msgid "Create radial (elliptic or circular) gradient" +msgstr "放射グラデーションを作成" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:635 +msgid "on" +msgstr "対象" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:648 +msgid "Create gradient in the fill" +msgstr "フィル上にグラデーションを作成" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:662 +msgid "Create gradient in the stroke" +msgstr "ストローク上にグラデーションを作成" + +#. FIXME: implement averaging of all parameters for multiple selected stars +#. gtk_label_set_markup(GTK_LABEL(l), _("Average:")); +#. FIXME: implement averaging of all parameters for multiple selected +#. gtk_label_set_markup(GTK_LABEL(l), _("Average:")); +#: ../../po/../src/widgets/gradient-toolbar.cpp:676 +#: ../../po/../src/widgets/toolbox.cpp:1105 +#: ../../po/../src/widgets/toolbox.cpp:1124 +#: ../../po/../src/widgets/toolbox.cpp:1493 +#: ../../po/../src/widgets/toolbox.cpp:1518 +#: ../../po/../src/widgets/toolbox.cpp:1768 +#: ../../po/../src/widgets/toolbox.cpp:1787 +#: ../../po/../src/widgets/toolbox.cpp:2334 +#: ../../po/../src/widgets/toolbox.cpp:2354 +msgid "Change:" +msgstr "設定:" + +#: ../../po/../src/widgets/gradient-vector.cpp:269 +msgid "No gradients in document" +msgstr "ドキュメントにグラデーションがありません" + +#: ../../po/../src/widgets/gradient-vector.cpp:275 +msgid "No gradient selected" +msgstr "グラデーションが選択されていません" + +#: ../../po/../src/widgets/gradient-vector.cpp:532 +msgid "No stops in gradient" +msgstr "グラデーション色がありません" + +#. TRANSLATORS: "Stop" means: a "phase" of a gradient +#: ../../po/../src/widgets/gradient-vector.cpp:794 +msgid "Add stop" +msgstr "色を追加" + +#: ../../po/../src/widgets/gradient-vector.cpp:797 +msgid "Add another control stop to gradient" +msgstr "グラデーションに制御色を追加" + +#: ../../po/../src/widgets/gradient-vector.cpp:799 +msgid "Delete stop" +msgstr "色を削除" + +#: ../../po/../src/widgets/gradient-vector.cpp:802 +msgid "Delete current control stop from gradient" +msgstr "グラデーションから制御色を削除" + +#. Label +#: ../../po/../src/widgets/gradient-vector.cpp:813 +msgid "Offset:" +msgstr "オフセット:" + +#. TRANSLATORS: "Stop" means: a "phase" of a gradient +#: ../../po/../src/widgets/gradient-vector.cpp:858 +msgid "Stop Color" +msgstr "色" + +#: ../../po/../src/widgets/gradient-vector.cpp:887 +msgid "Gradient editor" +msgstr "グラデーションエディタ" + +#: ../../po/../src/widgets/layer-selector.cpp:119 +msgid "Toggle current layer visibility" +msgstr "現在のレイヤーを可視化/非可視化" + +#: ../../po/../src/widgets/layer-selector.cpp:139 +msgid "Lock or unlock current layer" +msgstr "現在のレイヤーをロック/アンロック" + +#: ../../po/../src/widgets/layer-selector.cpp:142 +msgid "Current layer" +msgstr "現在のレイヤー" + +#: ../../po/../src/widgets/layer-selector.cpp:553 +msgid "(root)" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:182 +#: ../../po/../src/widgets/paint-selector.cpp:561 +msgid "No paint" +msgstr "なし" + +#: ../../po/../src/widgets/paint-selector.cpp:184 +#: ../../po/../src/widgets/paint-selector.cpp:629 +msgid "Flat color" +msgstr "フラットカラー" + +#: ../../po/../src/widgets/paint-selector.cpp:186 +#: ../../po/../src/widgets/paint-selector.cpp:696 +msgid "Linear gradient" +msgstr "線形グラデーション" + +#: ../../po/../src/widgets/paint-selector.cpp:188 +#: ../../po/../src/widgets/paint-selector.cpp:699 +msgid "Radial gradient" +msgstr "放射グラデーション" + +#: ../../po/../src/widgets/paint-selector.cpp:192 +msgid "Unset paint (make it undefined so it can be inherited)" +msgstr "" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/painting.html#FillRuleProperty +#: ../../po/../src/widgets/paint-selector.cpp:204 +msgid "" +"Any path self-intersections or subpaths create holes in the fill (fill-rule: " +"evenodd)" +msgstr "" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/painting.html#FillRuleProperty +#: ../../po/../src/widgets/paint-selector.cpp:215 +msgid "" +"Fill is solid unless a subpath is counterdirectional (fill-rule: nonzero)" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:528 +msgid "No objects" +msgstr "オブジェクトが選択されていません" + +#: ../../po/../src/widgets/paint-selector.cpp:539 +msgid "Multiple styles" +msgstr "マルチスタイル" + +#: ../../po/../src/widgets/paint-selector.cpp:550 +msgid "Paint is undefined" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:757 +msgid "No patterns in document" +msgstr "ドキュメントにパターンタイルがありません" + +#: ../../po/../src/widgets/paint-selector.cpp:872 +msgid "" +"Use Edit > Object(s) to Pattern to create a new pattern from " +"selection." +msgstr "" +"編集 > オブジェクトをパターンタイルにを使ってパターンタイルを作って" +"ください" + +#: ../../po/../src/widgets/select-toolbar.cpp:426 +msgid "Now stroke width is scaled when objects are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:428 +msgid "Now stroke width is not scaled when objects are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:436 +msgid "" +"Now rounded rectangle corners are scaled when rectangles are " +"scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:438 +msgid "" +"Now rounded rectangle corners are not scaled when rectangles " +"are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:446 +msgid "" +"Now gradients are transformed along with their objects when " +"those are transformed (moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:448 +msgid "" +"Now gradients remain fixed when objects are transformed " +"(moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:456 +msgid "" +"Now patterns are transformed along with their objects when " +"those are transformed (moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:458 +msgid "" +"Now patterns remain fixed when objects are transformed (moved, " +"scaled, rotated, or skewed)." +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:506 +msgid "select_toolbar|X" +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:506 +msgid "Horizontal coordinate of selection" +msgstr "選択オブジェクトの水平位置" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:511 +msgid "select_toolbar|Y" +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:511 +msgid "Vertical coordinate of selection" +msgstr "選択オブジェクトの垂直位置" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:517 +msgid "select_toolbar|W" +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:517 +msgid "Width of selection" +msgstr "選択オブジェクトの幅" + +#: ../../po/../src/widgets/select-toolbar.cpp:525 +msgid "Change both width and height by the same proportion" +msgstr "形状を固定したまま大きさを変更" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:534 +msgid "select_toolbar|H" +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:534 +msgid "Height of selection" +msgstr "選択オブジェクトの高さ" + +#: ../../po/../src/widgets/sp-color-gtkselector.cpp:62 +msgid "System" +msgstr "システム" + +#: ../../po/../src/widgets/sp-color-notebook.cpp:322 +msgid "RGBA_:" +msgstr "RGBA_:" + +#: ../../po/../src/widgets/sp-color-notebook.cpp:330 +msgid "Hexadecimal RGBA value of the color" +msgstr "16ビットRGBAカラー" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "RGB" +msgstr "RGB" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "HSL" +msgstr "HSL" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "CMYK" +msgstr "CMYK" + +#: ../../po/../src/widgets/sp-color-scales.cpp:397 +msgid "_R" +msgstr "_R" + +#: ../../po/../src/widgets/sp-color-scales.cpp:398 +#: ../../po/../src/widgets/sp-color-scales.cpp:399 +msgid "Red" +msgstr "赤:" + +#: ../../po/../src/widgets/sp-color-scales.cpp:400 +msgid "_G" +msgstr "_G" + +#: ../../po/../src/widgets/sp-color-scales.cpp:401 +#: ../../po/../src/widgets/sp-color-scales.cpp:402 +msgid "Green" +msgstr "緑:" + +#: ../../po/../src/widgets/sp-color-scales.cpp:403 +msgid "_B" +msgstr "_B" + +#: ../../po/../src/widgets/sp-color-scales.cpp:404 +#: ../../po/../src/widgets/sp-color-scales.cpp:405 +msgid "Blue" +msgstr "青:" + +#. Label +#: ../../po/../src/widgets/sp-color-scales.cpp:406 +#: ../../po/../src/widgets/sp-color-scales.cpp:432 +#: ../../po/../src/widgets/sp-color-scales.cpp:463 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:141 +msgid "_A" +msgstr "_A" + +#: ../../po/../src/widgets/sp-color-scales.cpp:407 +#: ../../po/../src/widgets/sp-color-scales.cpp:408 +#: ../../po/../src/widgets/sp-color-scales.cpp:433 +#: ../../po/../src/widgets/sp-color-scales.cpp:434 +#: ../../po/../src/widgets/sp-color-scales.cpp:464 +#: ../../po/../src/widgets/sp-color-scales.cpp:465 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:151 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:163 +msgid "Alpha (opacity)" +msgstr "不透明度" + +#: ../../po/../src/widgets/sp-color-scales.cpp:423 +msgid "_H" +msgstr "_H" + +#: ../../po/../src/widgets/sp-color-scales.cpp:424 +#: ../../po/../src/widgets/sp-color-scales.cpp:425 +msgid "Hue" +msgstr "色相:" + +#: ../../po/../src/widgets/sp-color-scales.cpp:426 +msgid "_S" +msgstr "_S" + +#: ../../po/../src/widgets/sp-color-scales.cpp:427 +#: ../../po/../src/widgets/sp-color-scales.cpp:428 +msgid "Saturation" +msgstr "彩度:" + +#: ../../po/../src/widgets/sp-color-scales.cpp:429 +msgid "_L" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:430 +#: ../../po/../src/widgets/sp-color-scales.cpp:431 +msgid "Lightness" +msgstr "明るさ" + +#: ../../po/../src/widgets/sp-color-scales.cpp:451 +msgid "_C" +msgstr "_C" + +#: ../../po/../src/widgets/sp-color-scales.cpp:452 +#: ../../po/../src/widgets/sp-color-scales.cpp:453 +msgid "Cyan" +msgstr "シアン:" + +#: ../../po/../src/widgets/sp-color-scales.cpp:454 +msgid "_M" +msgstr "_M" + +#: ../../po/../src/widgets/sp-color-scales.cpp:455 +#: ../../po/../src/widgets/sp-color-scales.cpp:456 +msgid "Magenta" +msgstr "マゼンタ:" + +#: ../../po/../src/widgets/sp-color-scales.cpp:457 +msgid "_Y" +msgstr "_Y" + +#: ../../po/../src/widgets/sp-color-scales.cpp:458 +#: ../../po/../src/widgets/sp-color-scales.cpp:459 +msgid "Yellow" +msgstr "黄:" + +#: ../../po/../src/widgets/sp-color-scales.cpp:460 +msgid "_K" +msgstr "_K" + +#: ../../po/../src/widgets/sp-color-selector.cpp:71 +msgid "Unnamed" +msgstr "無名" + +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:68 +msgid "Wheel" +msgstr "ホイール" + +#: ../../po/../src/widgets/sp-xmlview-attr-list.cpp:53 +msgid "Attribute" +msgstr "属性" + +#: ../../po/../src/widgets/sp-xmlview-attr-list.cpp:54 +msgid "Value" +msgstr "値" + +#: ../../po/../src/widgets/toolbox.cpp:424 +msgid "Insert new nodes into selected segments" +msgstr "ノードを選択セグメントに挿入する" + +#: ../../po/../src/widgets/toolbox.cpp:426 +msgid "Delete selected nodes" +msgstr "選択したノードの削除" + +#: ../../po/../src/widgets/toolbox.cpp:431 +msgid "Join paths at selected nodes" +msgstr "選択ノードに線を融合" + +#: ../../po/../src/widgets/toolbox.cpp:433 +msgid "Join paths at selected nodes with new segment" +msgstr "新しいセグメントで選択ノードに線を融合" + +#: ../../po/../src/widgets/toolbox.cpp:436 +msgid "Split path between two non-endpoint nodes" +msgstr "二つのノードのパスを削除" + +#: ../../po/../src/widgets/toolbox.cpp:439 +msgid "Break path at selected nodes" +msgstr "選択ノード間のパスを削除" + +#: ../../po/../src/widgets/toolbox.cpp:444 +msgid "Make selected nodes corner" +msgstr "選択ノードを角に" + +#: ../../po/../src/widgets/toolbox.cpp:447 +msgid "Make selected nodes smooth" +msgstr "選択ノードを滑かに" + +#: ../../po/../src/widgets/toolbox.cpp:450 +msgid "Make selected nodes symmetric" +msgstr "選択ノードをシンメトリックに" + +#: ../../po/../src/widgets/toolbox.cpp:455 +msgid "Make selected segments lines" +msgstr "選択セグメントを直線に" + +#: ../../po/../src/widgets/toolbox.cpp:458 +msgid "Make selected segments curves" +msgstr "選択セグメントを曲線に" + +#: ../../po/../src/widgets/toolbox.cpp:1199 +msgid "Polygon" +msgstr "ポリゴン" + +#: ../../po/../src/widgets/toolbox.cpp:1206 +msgid "Regular polygon (with one handle) instead of a star" +msgstr "星ではなくポリゴンに" + +#: ../../po/../src/widgets/toolbox.cpp:1218 +msgid "Corners:" +msgstr "角:" + +#: ../../po/../src/widgets/toolbox.cpp:1218 +msgid "Number of corners of a polygon or star" +msgstr "角の数" + +#: ../../po/../src/widgets/toolbox.cpp:1228 +msgid "Spoke ratio:" +msgstr "スポーク比:" + +#. TRANSLATORS: Tip radius of a star is the distance from the center to the farthest handle. +#. Base radius is the same for the closest handle. +#: ../../po/../src/widgets/toolbox.cpp:1231 +msgid "Base radius to tip radius ratio" +msgstr "中心へ指向する度合" + +#: ../../po/../src/widgets/toolbox.cpp:1246 +msgid "Rounded:" +msgstr "まるめ度:" + +#: ../../po/../src/widgets/toolbox.cpp:1246 +msgid "How much rounded are the corners (0 for sharp)" +msgstr "どれくらい角をまるめるか" + +#: ../../po/../src/widgets/toolbox.cpp:1256 +msgid "Randomized:" +msgstr "ランダム度:" + +#: ../../po/../src/widgets/toolbox.cpp:1256 +msgid "Scatter randomly the corners and angles" +msgstr "ランダムに角と角度を変形" + +#: ../../po/../src/widgets/toolbox.cpp:1269 +#: ../../po/../src/widgets/toolbox.cpp:1838 +#: ../../po/../src/widgets/toolbox.cpp:2061 +msgid "Defaults" +msgstr "デフォルト" + +#: ../../po/../src/widgets/toolbox.cpp:1270 +#: ../../po/../src/widgets/toolbox.cpp:1839 +#: ../../po/../src/widgets/toolbox.cpp:2062 +msgid "" +"Reset shape parameters to defaults (use Inkscape Preferences > Tools to " +"change defaults)" +msgstr "デフォルトにリセット (Inkscape設定 > ツール でデフォルトを設定)" + +#: ../../po/../src/widgets/toolbox.cpp:1544 +msgid "W:" +msgstr "幅:" + +#: ../../po/../src/widgets/toolbox.cpp:1544 +msgid "Width of rectangle" +msgstr "矩形の幅" + +#: ../../po/../src/widgets/toolbox.cpp:1556 +msgid "Height of rectangle" +msgstr "矩形の高さ" + +#: ../../po/../src/widgets/toolbox.cpp:1568 +msgid "Rx:" +msgstr "水平半径:" + +#: ../../po/../src/widgets/toolbox.cpp:1568 +msgid "Horizontal radius of rounded corners" +msgstr "丸角の水平半径" + +#: ../../po/../src/widgets/toolbox.cpp:1578 +msgid "Ry:" +msgstr "垂直半径:" + +#: ../../po/../src/widgets/toolbox.cpp:1578 +msgid "Vertical radius of rounded corners" +msgstr "丸角の垂直半径" + +#: ../../po/../src/widgets/toolbox.cpp:1594 +msgid "Not rounded" +msgstr "鋭利に" + +#: ../../po/../src/widgets/toolbox.cpp:1596 +msgid "Make corners sharp" +msgstr "角を鋭利に" + +#: ../../po/../src/widgets/toolbox.cpp:1805 +msgid "Turns:" +msgstr "渦巻度" + +#: ../../po/../src/widgets/toolbox.cpp:1805 +msgid "Number of revolutions" +msgstr "渦巻の巻きぐあい" + +#: ../../po/../src/widgets/toolbox.cpp:1815 +msgid "Divergence:" +msgstr "相違:" + +#: ../../po/../src/widgets/toolbox.cpp:1815 +msgid "How much denser/sparser are outer revolutions; 1 = uniform" +msgstr "内と外の変化度" + +#: ../../po/../src/widgets/toolbox.cpp:1825 +msgid "Inner radius:" +msgstr "内半径:" + +#: ../../po/../src/widgets/toolbox.cpp:1825 +msgid "Radius of the innermost revolution (relative to the spiral size)" +msgstr "中心部の最小半径(相対値)" + +#: ../../po/../src/widgets/toolbox.cpp:1957 +msgid "The width of the calligraphic pen (relative to the visible canvas area)" +msgstr "カリグラフィックペンの太さ(キャンバスサイズに比例)" + +#: ../../po/../src/widgets/toolbox.cpp:1967 +msgid "Thinning:" +msgstr "太さ:" + +#: ../../po/../src/widgets/toolbox.cpp:1967 +msgid "" +"How much velocity thins the stroke (> 0 makes fast strokes thinner, < 0 " +"makes them broader, 0 makes width independent of velocity)" +msgstr "" +"速度が線の太さに与える影響 (正の値: 速く引くと細く、負の値: 速く引くと太く、" +"0: 速さの影響なし)" + +#: ../../po/../src/widgets/toolbox.cpp:1980 +msgid "Angle:" +msgstr "角度:" + +#: ../../po/../src/widgets/toolbox.cpp:1980 +msgid "" +"The angle of the pen's nib (in degrees; 0 = horizontal; has no effect if " +"fixation = 0)" +msgstr "ペンの角度 (0: æ°´å¹³)" + +#: ../../po/../src/widgets/toolbox.cpp:1990 +msgid "Fixation:" +msgstr "展開係数:" + +#: ../../po/../src/widgets/toolbox.cpp:1990 +msgid "" +"How fixed is the pen angle (0 = always perpendicular to stroke direction, 1 " +"= fixed)" +msgstr "ペンの角度をどれくらい固定するか (0: 線の角度に常に追従、1: 固定)" + +#: ../../po/../src/widgets/toolbox.cpp:2003 +msgid "Mass:" +msgstr "質量:" + +#: ../../po/../src/widgets/toolbox.cpp:2003 +msgid "How much inertia affects the movement of the pen" +msgstr "ペンの移動時の慣性の強さ" + +#. TRANSLATORS: "drag" means "resistance" here +#: ../../po/../src/widgets/toolbox.cpp:2014 +msgid "Drag:" +msgstr "抵抗:" + +#: ../../po/../src/widgets/toolbox.cpp:2014 +msgid "How much resistance affects the movement of the pen" +msgstr "ペンの動きに対する抵抗" + +#: ../../po/../src/widgets/toolbox.cpp:2034 +msgid "Use the pressure of the input device to alter the width of the pen" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2047 +msgid "Use the tilt of the input device to alter the angle of the pen's nib" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2374 +msgid "Start:" +msgstr "始点:" + +#: ../../po/../src/widgets/toolbox.cpp:2374 +msgid "The angle (in degrees) from the horizontal to the arc's start point" +msgstr "始点と水平の間の角度" + +#: ../../po/../src/widgets/toolbox.cpp:2384 +msgid "End:" +msgstr "終点:" + +#: ../../po/../src/widgets/toolbox.cpp:2384 +msgid "The angle (in degrees) from the horizontal to the arc's end point" +msgstr "終点と水平の間の角度" + +#: ../../po/../src/widgets/toolbox.cpp:2395 +msgid "Open arc" +msgstr "弧を開放" + +#: ../../po/../src/widgets/toolbox.cpp:2396 +msgid "" +"Switch between arc (unclosed shape) and segment (closed shape with two radii)" +msgstr "円と弧を切替え" + +#: ../../po/../src/widgets/toolbox.cpp:2415 +msgid "Make whole" +msgstr "弧を円に" + +#: ../../po/../src/widgets/toolbox.cpp:2417 +msgid "Make the shape a whole ellipse, not arc or segment" +msgstr "弧を閉じた円に" + +#: ../../po/../src/widgets/toolbox.cpp:2644 +msgid "" +"When pressed, picks visible color without alpha and when not pressed, picks " +"color including its alpha" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:3039 +msgid "Make connectors avoid selected objects" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:3043 +msgid "Make connectors ignore selected objects" +msgstr "" + +#. +#. 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 : +#: ../share/extensions/addnodes.inx.h:1 +#, fuzzy +msgid "Add Nodes" +msgstr "ノード" + +#: ../share/extensions/addnodes.inx.h:2 +msgid "Maximum Segment Length" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:1 +msgid "AI Input" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:2 ../share/extensions/ai_output.inx.h:2 +msgid "Adobe Illustrator (*.ai)" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:3 +msgid "Open files saved with Adobe Illustrator" +msgstr "" + +#: ../share/extensions/ai_output.inx.h:1 +#, fuzzy +msgid "AI Output" +msgstr "出力" + +#: ../share/extensions/ai_output.inx.h:3 +msgid "Write Adobe Illustrator" +msgstr "" + +#: ../share/extensions/dia.inx.h:1 +msgid "A diagram created with the program Dia" +msgstr "" + +#: ../share/extensions/dia.inx.h:2 +msgid "Dia Diagram (*.dia)" +msgstr "" + +#: ../share/extensions/dia.inx.h:3 +msgid "Dia Input" +msgstr "" + +#: ../share/extensions/dia.inx.h:4 +msgid "" +"In order to import Dia files, Dia itself must be installed. You can get Dia " +"at http://www.gnome.org/projects/dia/" +msgstr "" + +#: ../share/extensions/dia.inx.h:5 +msgid "" +"The dia2svg.sh script should be installed with your Inkscape distribution. " +"If you do not have it, there is likely to be something wrong with your " +"Inkscape installation." +msgstr "" + +#: ../share/extensions/dots.inx.h:1 +#, fuzzy +msgid "Connect the Dots" +msgstr "コネクタ" + +#: ../share/extensions/dots.inx.h:2 +#, fuzzy +msgid "Dot Size" +msgstr "サイズ" + +#: ../share/extensions/dots.inx.h:3 +#, fuzzy +msgid "Font Size" +msgstr "サイズ:" + +#: ../share/extensions/dropshadow.inx.h:1 +msgid "Color of shadow" +msgstr "" + +#: ../share/extensions/dropshadow.inx.h:2 +#, fuzzy +msgid "Dropshadow" +msgstr "ページに影をつける" + +#: ../share/extensions/dxf_input.inx.h:1 +#: ../share/extensions/dxf_output.inx.h:1 +msgid "AutoCAD DXF (*.dxf)" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:2 +msgid "DXF Input" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:3 +msgid "Import AutoCAD's Document Exchange Format" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:4 +msgid "" +"dxf2svg may come with Inkscape, but is also at http://dxf-svg-convert." +"sourceforge.net/" +msgstr "" + +#: ../share/extensions/dxf_output.inx.h:2 +#, fuzzy +msgid "DXF Output" +msgstr "出力" + +#: ../share/extensions/dxf_output.inx.h:3 +msgid "DXF file written by pstoedit" +msgstr "" + +#: ../share/extensions/dxf_output.inx.h:4 +msgid "pstoedit must be installed to run see http://www.pstoedit.net/pstoedit" +msgstr "" + +#: ../share/extensions/embedimage.inx.h:1 +#, fuzzy +msgid "Embed Images" +msgstr "画像" + +#: ../share/extensions/eps_input.inx.h:1 +msgid "EPS Input" +msgstr "" + +#: ../share/extensions/eps_input.inx.h:2 +msgid "Encapsulated Postscript" +msgstr "" + +#: ../share/extensions/eps_input.inx.h:3 +msgid "Encapsulated Postscript (*.eps)" +msgstr "" + +#: ../share/extensions/epsi_output.inx.h:1 +#, fuzzy +msgid "EPSI Output" +msgstr "出力" + +#: ../share/extensions/epsi_output.inx.h:2 +msgid "Encapsulated Postscript Interchange (*.epsi)" +msgstr "" + +#: ../share/extensions/epsi_output.inx.h:3 +msgid "Encapsulated Postscript with a thumbnail" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:1 ../share/extensions/ffms.inx.h:1 +#: ../share/extensions/ffset.inx.h:1 ../share/extensions/ffss.inx.h:1 +#, fuzzy +msgid "Bridge Width" +msgstr "行幅" + +#: ../share/extensions/ffmet.inx.h:2 ../share/extensions/ffms.inx.h:2 +msgid "First String Length" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:3 +msgid "FretFind Multi Length ET" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:4 ../share/extensions/ffms.inx.h:4 +#: ../share/extensions/ffset.inx.h:3 ../share/extensions/ffss.inx.h:3 +msgid "Fretboard Edges" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:5 ../share/extensions/ffms.inx.h:5 +msgid "Last String Length" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:6 ../share/extensions/ffms.inx.h:6 +#: ../share/extensions/ffset.inx.h:4 ../share/extensions/ffss.inx.h:4 +#, fuzzy +msgid "Number of Frets" +msgstr "行数" + +#: ../share/extensions/ffmet.inx.h:7 ../share/extensions/ffms.inx.h:7 +#: ../share/extensions/ffset.inx.h:5 ../share/extensions/ffss.inx.h:5 +#, fuzzy +msgid "Number of Strings" +msgstr "行数" + +#: ../share/extensions/ffmet.inx.h:8 ../share/extensions/ffms.inx.h:8 +#: ../share/extensions/ffset.inx.h:6 ../share/extensions/ffss.inx.h:6 +#, fuzzy +msgid "Nut Width" +msgstr "幅:" + +#: ../share/extensions/ffmet.inx.h:9 ../share/extensions/ffms.inx.h:10 +msgid "Perpendicular Distance" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:10 ../share/extensions/ffset.inx.h:7 +msgid "Scale Base (2 for Octave)" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:11 ../share/extensions/ffset.inx.h:9 +msgid "Tones in Scale" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:12 ../share/extensions/ffms.inx.h:12 +#: ../share/extensions/ffset.inx.h:10 ../share/extensions/ffss.inx.h:10 +msgid "px per Unit" +msgstr "" + +#: ../share/extensions/ffms.inx.h:3 +msgid "FretFind Multi Length Scala" +msgstr "" + +#: ../share/extensions/ffms.inx.h:9 ../share/extensions/ffss.inx.h:7 +msgid "Path to Scala *.scl File" +msgstr "" + +#: ../share/extensions/ffms.inx.h:11 +msgid "Tuning (scale step for each string seperated by semicolons)" +msgstr "" + +#: ../share/extensions/ffset.inx.h:2 +msgid "FretFind Single Length ET" +msgstr "" + +#: ../share/extensions/ffset.inx.h:8 ../share/extensions/ffss.inx.h:8 +msgid "Scale Length" +msgstr "" + +#: ../share/extensions/ffss.inx.h:2 +msgid "FretFind Single Length Scala" +msgstr "" + +#: ../share/extensions/ffss.inx.h:9 +msgid "Tuning (Scale step for each string seperated by semicolons)" +msgstr "" + +#: ../share/extensions/handles.inx.h:1 +#, fuzzy +msgid "Draw Handles" +msgstr "フリーハンド線" + +#: ../share/extensions/interp.inx.h:1 +#, fuzzy +msgid "Duplicate Endpaths" +msgstr "ノードを複製" + +#: ../share/extensions/interp.inx.h:2 +#, fuzzy +msgid "Exponent" +msgstr "エクスポート" + +#: ../share/extensions/interp.inx.h:3 +msgid "Interpolate" +msgstr "" + +#: ../share/extensions/interp.inx.h:4 +msgid "Interpolate Style (Experimental)" +msgstr "" + +#: ../share/extensions/interp.inx.h:5 +msgid "Interpolation Method" +msgstr "" + +#: ../share/extensions/interp.inx.h:6 +msgid "Interpolation Steps" +msgstr "" + +#: ../share/extensions/kochify.inx.h:1 +msgid "Kochify" +msgstr "" + +#: ../share/extensions/kochify_load.inx.h:1 +msgid "Kochify (Load)" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:1 +#, fuzzy +msgid "Angle" +msgstr "角度:" + +#: ../share/extensions/lindenmayer.inx.h:2 +msgid "Axiom" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:3 +#, fuzzy +msgid "Lindenmayer" +msgstr "レイヤーの名前を編集" + +#: ../share/extensions/lindenmayer.inx.h:4 +msgid "Order" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:5 +#, fuzzy +msgid "Rules" +msgstr "定規" + +#: ../share/extensions/lindenmayer.inx.h:6 +#, fuzzy +msgid "Step" +msgstr "変化度" + +#: ../share/extensions/motion.inx.h:1 +#, fuzzy +msgid "Direction" +msgstr "記述" + +#: ../share/extensions/motion.inx.h:2 +#, fuzzy +msgid "Magnitude" +msgstr "マゼンタ:" + +#: ../share/extensions/motion.inx.h:3 +#, fuzzy +msgid "Motion" +msgstr "回転(_R)" + +#: ../share/extensions/pdf_output.inx.h:1 +msgid "Adobe PDF (*.pdf)" +msgstr "" + +#: ../share/extensions/pdf_output.inx.h:2 +msgid "Adobe Portable Document Format" +msgstr "" + +#: ../share/extensions/pdf_output.inx.h:3 +#, fuzzy +msgid "PDF Output" +msgstr "出力" + +#: ../share/extensions/ps_input.inx.h:1 +#, fuzzy +msgid "Postscript" +msgstr "縦書き" + +#: ../share/extensions/ps_input.inx.h:2 +msgid "Postscript (*.ps)" +msgstr "" + +#: ../share/extensions/ps_input.inx.h:3 +msgid "Postscript Input" +msgstr "" + +#: ../share/extensions/radiusrand.inx.h:1 +#, fuzzy +msgid "Radius" +msgstr "前面へ" + +#: ../share/extensions/radiusrand.inx.h:2 +#, fuzzy +msgid "Radius Randomize" +msgstr "ランダマイズ:" + +#: ../share/extensions/radiusrand.inx.h:3 +msgid "Randomize Control Points" +msgstr "" + +#: ../share/extensions/radiusrand.inx.h:4 +#, fuzzy +msgid "Randomize Nodes" +msgstr "ランダム度:" + +#: ../share/extensions/rtree.inx.h:1 +#, fuzzy +msgid "Initial Size" +msgstr "ビットマップサイズ" + +#: ../share/extensions/rtree.inx.h:2 +msgid "Minimum Size" +msgstr "" + +#: ../share/extensions/rtree.inx.h:3 +#, fuzzy +msgid "Random Tree" +msgstr "ランダマイズ:" + +#: ../share/extensions/sk_input.inx.h:1 +msgid "A diagram created with the program Sketch" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:2 +msgid "Sketch Diagram (*.sk)" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:3 +msgid "Sketch Input" +msgstr "" + +#: ../share/extensions/straightseg.inx.h:1 +msgid "Behavior" +msgstr "" + +#: ../share/extensions/straightseg.inx.h:3 +msgid "Segment Straightener" +msgstr "" + +#: ../share/extensions/summersnight.inx.h:1 +msgid "Summer's Night" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:1 +#: ../share/extensions/svgz_output.inx.h:1 +msgid "Compressed Inkscape SVG (*.svgz)" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:2 +#: ../share/extensions/svgz_output.inx.h:2 +msgid "Inkscape's native file format compressed with GZip" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:3 +msgid "SVGZ Input" +msgstr "" + +#: ../share/extensions/svgz_output.inx.h:3 +#, fuzzy +msgid "SVGZ Output" +msgstr "出力" + +#: ../share/extensions/txt2svg.inx.h:1 +msgid "ASCII Text" +msgstr "" + +#: ../share/extensions/txt2svg.inx.h:2 +msgid "Text File (*.txt)" +msgstr "" + +#: ../share/extensions/txt2svg.inx.h:3 +msgid "Text Input" +msgstr "" + +#: ../share/extensions/wavy.inx.h:1 +msgid "Calculate first derivative numerically" +msgstr "" + +#: ../share/extensions/wavy.inx.h:2 +msgid "First derivative" +msgstr "" + +#: ../share/extensions/wavy.inx.h:3 +msgid "Function" +msgstr "" + +#: ../share/extensions/wavy.inx.h:4 +msgid "Function Plotter" +msgstr "" + +#: ../share/extensions/wavy.inx.h:5 +msgid "Nodes per period" +msgstr "" + +#: ../share/extensions/wavy.inx.h:6 +msgid "Periods (2*Pi each)" +msgstr "" + +#: ../share/extensions/whirl.inx.h:1 +msgid "Amount of Whirl" +msgstr "" + +#: ../share/extensions/whirl.inx.h:2 +#, fuzzy +msgid "Center X" +msgstr "中心線" + +#: ../share/extensions/whirl.inx.h:3 +#, fuzzy +msgid "Center Y" +msgstr "中心線" + +#: ../share/extensions/whirl.inx.h:4 +#, fuzzy +msgid "Direction of Rotation" +msgstr "最背面に移動" + +#: ../share/extensions/whirl.inx.h:5 +msgid "Whirl" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:1 +msgid "A popular graphics file format for clipart" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:2 +msgid "Windows Metafile (*.wmf)" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:3 +msgid "Windows Metafile Input" +msgstr "" + +#~ msgid "Custom canvas" +#~ msgstr "カスタム" + +#~ msgid "Current style" +#~ msgstr "現在のスタイル" + +#~ msgid "" +#~ "Current style is updated every time you change the style of any object " +#~ "(its fill, stroke, transparency, etc.)" +#~ msgstr "オブジェクトのスタイルを変える度にアップデート" + +#~ msgid "Arrange Objects" +#~ msgstr "オブジェクトを配置" + +#~ msgid "deg" +#~ msgstr "度" + +#~ msgid "" +#~ "%s is not a valid preferences file.\n" +#~ "%s" +#~ msgstr "" +#~ "%sは正しい設定ファイルではありません。\n" +#~ "%s" + +#~ msgid "" +#~ "Inkscape will run with default settings.\n" +#~ "New settings will not be saved." +#~ msgstr "" +#~ "Inkscapeはデフォルト設定で起動します。\n" +#~ "新しい設定が保存されます。" + +#, fuzzy +#~ msgid "_Credits" +#~ msgstr "クレジット" + +#~ msgid "Grab sensitivity" +#~ msgstr "選択の感度" + +#~ msgid "Click/drag threshold" +#~ msgstr "クリック/ドラッグの閾値" + +#~ msgid "Mouse wheel scrolls by" +#~ msgstr "マウスホイールでのスクロール:" + +#~ msgid "Scroll by" +#~ msgstr "スクロール" + +#~ msgid "Acceleration" +#~ msgstr "加速" + +#~ msgid "Speed" +#~ msgstr "スピード" + +#~ msgid "Threshold" +#~ msgstr "閾値" + +#~ msgid "Arrow keys move by" +#~ msgstr "カーソルキーでの移動" + +#~ msgid "> and < scale by" +#~ msgstr "[<], [>]キーでの拡大/縮小" + +#~ msgid "Inset/Outset by" +#~ msgstr "インセット/アウトセット:" + +#~ msgid "Rotation snaps every" +#~ msgstr "スナップ角度" + +#~ msgid "Zoom in/out by" +#~ msgstr "ズームイン/アウト" + +#~ msgid "Transform" +#~ msgstr "変形" diff --git a/po/mk.po b/po/mk.po new file mode 100755 index 000000000..9d4ae32e1 --- /dev/null +++ b/po/mk.po @@ -0,0 +1,9817 @@ +# translation of sodipodi.HEAD.po to +# translation of sodipodi.HEAD.po to +# This file is distributed under the same license as the PACKAGE package. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER, 2003 +# +msgid "" +msgstr "" +"Project-Id-Version: sodipodi.HEAD\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2005-12-04 11:51-0800\n" +"PO-Revision-Date: 2003-06-15 09:44+0200\n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 1.0\n" + +#: ../inkscape.desktop.in.h:1 +msgid "Create and edit Scalable Vector Graphics images" +msgstr "" + +#: ../inkscape.desktop.in.h:2 +msgid "Inkscape SVG Vector Illustrator" +msgstr "" + +#: ../../po/../src/arc-context.cpp:350 +msgid "" +"Ctrl: make circle or integer-ratio ellipse, snap arc/segment angle" +msgstr "" + +#: ../../po/../src/arc-context.cpp:351 ../../po/../src/rect-context.cpp:388 +msgid "Shift: draw around the starting point" +msgstr "" + +#: ../../po/../src/arc-context.cpp:413 +#: ../../po/../src/connector-context.cpp:493 +#: ../../po/../src/dyna-draw-context.cpp:506 +#: ../../po/../src/pen-context.cpp:329 ../../po/../src/pencil-context.cpp:208 +#: ../../po/../src/rect-context.cpp:452 ../../po/../src/spiral-context.cpp:421 +#: ../../po/../src/star-context.cpp:427 +msgid "Current layer is hidden. Unhide it to be able to draw on it." +msgstr "" + +#: ../../po/../src/arc-context.cpp:417 +#: ../../po/../src/connector-context.cpp:497 +#: ../../po/../src/dyna-draw-context.cpp:510 +#: ../../po/../src/pen-context.cpp:336 ../../po/../src/pencil-context.cpp:212 +#: ../../po/../src/rect-context.cpp:456 ../../po/../src/spiral-context.cpp:426 +#: ../../po/../src/star-context.cpp:431 +msgid "Current layer is locked. Unlock it to be able to draw on it." +msgstr "" + +#: ../../po/../src/arc-context.cpp:496 +#, c-format +msgid "" +"Ellipse: %s × %s; with Ctrl to make circle or integer-" +"ratio ellipse; with Shift to draw around the starting point" +msgstr "" + +#: ../../po/../src/connector-context.cpp:518 +#, fuzzy +msgid "Creating new connector" +msgstr "Зачувај документ" + +#: ../../po/../src/connector-context.cpp:939 +msgid "Finishing connector" +msgstr "" + +#: ../../po/../src/connector-context.cpp:1108 +msgid "Connection point: click or drag to create a new connector" +msgstr "" + +#: ../../po/../src/connector-context.cpp:1185 +msgid "Connector endpoint: drag to reroute or connect to new shapes" +msgstr "" + +#: ../../po/../src/connector-context.cpp:1278 +msgid "Select at least one non-connector object." +msgstr "" + +#: ../../po/../src/desktop-events.cpp:238 +#, c-format +msgid "%s at %s" +msgstr "" + +#. TRANSLATORS: This string appears when double-clicking on a guide. +#. This is the distance by which the guide is to be moved. +#: ../../po/../src/desktop-events.cpp:277 +msgid " relative by " +msgstr "" + +#. TRANSLATORS: This string appears when double-clicking on a guide. +#. This is the target location where the guide is to be moved. +#: ../../po/../src/desktop-events.cpp:282 +#: ../../po/../src/desktop-events.cpp:395 +msgid " absolute to " +msgstr "" + +#. create dialog +#: ../../po/../src/desktop-events.cpp:348 +#, fuzzy +msgid "Guideline" +msgstr "Водичи" + +#: ../../po/../src/desktop-events.cpp:432 +#, fuzzy, c-format +msgid "Move %s" +msgstr "Премести" + +#: ../../po/../src/desktop.cpp:678 +msgid "No previous zoom." +msgstr "" + +#: ../../po/../src/desktop.cpp:703 +msgid "No next zoom." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:182 +msgid "Nothing selected." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:188 +msgid "More than one object selected." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:195 +#, c-format +msgid "Object has %d tiled clones." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:200 +msgid "Object has no tiled clones." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:865 +msgid "Select one object whose tiled clones to unclump." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:916 +msgid "Select one object whose tiled clones to remove." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:984 +#: ../../po/../src/selection-chemistry.cpp:1774 +msgid "Select an object to clone." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:990 +#: ../../po/../src/selection-chemistry.cpp:1780 +msgid "" +"If you want to clone several objects, group them and clone the " +"group." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1484 +msgid "Per row:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1497 +msgid "Per column:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1505 +msgid "Randomize:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1656 +msgid "_Symmetry" +msgstr "" + +#. TRANSLATORS: For the following 17 symmetry groups, see +#. * http://www.bib.ulb.ac.be/coursmath/doc/17.htm (visual examples); +#. * http://www.clarku.edu/~djoyce/wallpaper/seventeen.html (English vocabulary); or +#. * http://membres.lycos.fr/villemingerard/Geometri/Sym1D.htm (French vocabulary). +#. +#: ../../po/../src/dialogs/clonetiler.cpp:1664 +msgid "Select one of the 17 symmetry groups for the tiling" +msgstr "" + +#. TRANSLATORS: "translation" means "shift" / "displacement" here. +#: ../../po/../src/dialogs/clonetiler.cpp:1675 +msgid "P1: simple translation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1676 +msgid "P2: 180° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1677 +msgid "PM: reflection" +msgstr "" + +#. TRANSLATORS: "glide reflection" is a reflection and a translation combined. +#. For more info, see http://mathforum.org/sum95/suzanne/symsusan.html +#: ../../po/../src/dialogs/clonetiler.cpp:1680 +msgid "PG: glide reflection" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1681 +msgid "CM: reflection + glide reflection" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1682 +msgid "PMM: reflection + reflection" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1683 +msgid "PMG: reflection + 180° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1684 +msgid "PGG: glide reflection + 180° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1685 +msgid "CMM: reflection + reflection + 180° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1686 +msgid "P4: 90° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1687 +msgid "P4M: 90° rotation + 45° reflection" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1688 +msgid "P4G: 90° rotation + 90° reflection" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1689 +msgid "P3: 120° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1690 +msgid "P31M: reflection + 120° rotation, dense" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1691 +msgid "P3M1: reflection + 120° rotation, sparse" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1692 +msgid "P6: 60° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1693 +msgid "P6M: reflection + 60° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1721 +msgid "S_hift" +msgstr "" + +#. TRANSLATORS: "shift" means: the tiles will be shifted (offset) horizontally by this amount +#: ../../po/../src/dialogs/clonetiler.cpp:1731 +#, no-c-format +msgid "Shift X:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1739 +#, no-c-format +msgid "Horizontal shift per row (in % of tile width)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1747 +#, no-c-format +msgid "Horizontal shift per column (in % of tile width)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1754 +msgid "Randomize the horizontal shift by this percentage" +msgstr "" + +#. TRANSLATORS: "shift" means: the tiles will be shifted (offset) vertically by this amount +#: ../../po/../src/dialogs/clonetiler.cpp:1764 +#, no-c-format +msgid "Shift Y:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1772 +#, no-c-format +msgid "Vertical shift per row (in % of tile height)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1780 +#, no-c-format +msgid "Vertical shift per column (in % of tile height)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1787 +msgid "Randomize the vertical shift by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1795 +#, fuzzy +msgid "Exponent:" +msgstr "Елипса" + +#: ../../po/../src/dialogs/clonetiler.cpp:1802 +msgid "Whether rows are spaced evenly (1), converge (<1) or diverge (>1)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1809 +msgid "Whether columns are spaced evenly (1), converge (<1) or diverge (>1)" +msgstr "" + +#. TRANSLATORS: "Alternate" is a verb here +#: ../../po/../src/dialogs/clonetiler.cpp:1817 +#: ../../po/../src/dialogs/clonetiler.cpp:1907 +#: ../../po/../src/dialogs/clonetiler.cpp:1966 +#: ../../po/../src/dialogs/clonetiler.cpp:2022 +#: ../../po/../src/dialogs/clonetiler.cpp:2153 +msgid "Alternate:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1823 +msgid "Alternate the sign of shifts for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1828 +msgid "Alternate the sign of shifts for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1837 +#, fuzzy +msgid "Sc_ale" +msgstr "Промени големина" + +#: ../../po/../src/dialogs/clonetiler.cpp:1845 +#, fuzzy +msgid "Scale X:" +msgstr "Датотека" + +#: ../../po/../src/dialogs/clonetiler.cpp:1853 +#, no-c-format +msgid "Horizontal scale per row (in % of tile width)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1861 +#, no-c-format +msgid "Horizontal scale per column (in % of tile width)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1868 +msgid "Randomize the horizontal scale by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1876 +#, fuzzy +msgid "Scale Y:" +msgstr "Датотека" + +#: ../../po/../src/dialogs/clonetiler.cpp:1884 +#, no-c-format +msgid "Vertical scale per row (in % of tile height)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1892 +#, no-c-format +msgid "Vertical scale per column (in % of tile height)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1899 +msgid "Randomize the vertical scale by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1913 +msgid "Alternate the sign of scales for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1918 +msgid "Alternate the sign of scales for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1927 +#, fuzzy +msgid "_Rotation" +msgstr "Избор" + +#: ../../po/../src/dialogs/clonetiler.cpp:1935 +#, fuzzy +msgid "Angle:" +msgstr "Правоаголник" + +#: ../../po/../src/dialogs/clonetiler.cpp:1943 +#, no-c-format +msgid "Rotate tiles by this angle for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1951 +#, no-c-format +msgid "Rotate tiles by this angle for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1958 +msgid "Randomize the rotation angle by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1972 +msgid "Alternate the rotation direction for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1977 +msgid "Alternate the rotation direction for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1985 +msgid "_Opacity" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1993 +msgid "Fade out:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2000 +msgid "Decrease tile opacity by this percentage for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2007 +msgid "Decrease tile opacity by this percentage for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2014 +msgid "Randomize the tile opacity by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2028 +msgid "Alternate the sign of opacity change for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2033 +msgid "Alternate the sign of opacity change for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2041 +#, fuzzy +msgid "Co_lor" +msgstr "Затвори" + +#: ../../po/../src/dialogs/clonetiler.cpp:2046 +#, fuzzy +msgid "Initial color: " +msgstr "Боја на мрежата:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2050 +msgid "Initial color of tiled clones" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2050 +msgid "" +"Initial color for clones (works only if the original has unset fill or " +"stroke)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2065 +#, fuzzy +msgid "H:" +msgstr "Елипса" + +#: ../../po/../src/dialogs/clonetiler.cpp:2072 +msgid "Change the tile hue by this percentage for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2079 +msgid "Change the tile hue by this percentage for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2086 +msgid "Randomize the tile hue by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2095 +#, fuzzy +msgid "S:" +msgstr "Елипса" + +#: ../../po/../src/dialogs/clonetiler.cpp:2102 +msgid "Change the color saturation by this percentage for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2109 +msgid "Change the color saturation by this percentage for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2116 +msgid "Randomize the color saturation by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2124 +#, fuzzy +msgid "L:" +msgstr "Елипса" + +#: ../../po/../src/dialogs/clonetiler.cpp:2131 +msgid "Change the color lightness by this percentage for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2138 +msgid "Change the color lightness by this percentage for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2145 +msgid "Randomize the color lightness by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2159 +msgid "Alternate the sign of color changes for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2164 +msgid "Alternate the sign of color changes for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2172 +#, fuzzy +msgid "_Trace" +msgstr "Создади" + +#: ../../po/../src/dialogs/clonetiler.cpp:2179 +msgid "Trace the drawing under the tiles" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2183 +msgid "" +"For each clone, pick a value from the drawing in that clone's location and " +"apply it to the clone" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2197 +msgid "1. Pick from the drawing:" +msgstr "" + +#. ----Hbox2 +#: ../../po/../src/dialogs/clonetiler.cpp:2208 +#: ../../po/../src/dialogs/clonetiler.cpp:2355 +#: ../../po/../src/ui/dialog/tracedialog.cpp:445 +#, fuzzy +msgid "Color" +msgstr "Затвори" + +#: ../../po/../src/dialogs/clonetiler.cpp:2209 +msgid "Pick the visible color and opacity" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2216 +#: ../../po/../src/dialogs/clonetiler.cpp:2365 +#: ../share/extensions/dropshadow.inx.h:3 +msgid "Opacity" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2217 +msgid "Pick the total accumulated opacity" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2224 +msgid "R" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2225 +msgid "Pick the Red component of the color" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2232 +msgid "G" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2233 +msgid "Pick the Green component of the color" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2240 +msgid "B" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2241 +msgid "Pick the Blue component of the color" +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2250 +msgid "clonetiler|H" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2251 +msgid "Pick the hue of the color" +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2260 +msgid "clonetiler|S" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2261 +msgid "Pick the saturation of the color" +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2270 +msgid "clonetiler|L" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2271 +msgid "Pick the lightness of the color" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2281 +msgid "2. Tweak the picked value:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2291 +msgid "Gamma-correct:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2296 +msgid "Shift the mid-range of the picked value upwards (>0) or downwards (<0)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2303 +msgid "Randomize:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2308 +msgid "Randomize the picked value by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2315 +#, fuzzy +msgid "Invert:" +msgstr "Точка" + +#: ../../po/../src/dialogs/clonetiler.cpp:2319 +msgid "Invert the picked value" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2325 +msgid "3. Apply the value to the clones':" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2335 +#, fuzzy +msgid "Presence" +msgstr "Правоаголник" + +#: ../../po/../src/dialogs/clonetiler.cpp:2338 +msgid "" +"Each clone is created with the probability determined by the picked value in " +"that point" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2345 +msgid "Size" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2348 +msgid "Each clone's size is determined by the picked value in that point" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2358 +msgid "" +"Each clone is painted by the picked color (the original must have unset fill " +"or stroke)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2368 +msgid "Each clone's opacity is determined by the picked value in that point" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2395 +msgid "How many rows in the tiling" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2415 +msgid "How many columns in the tiling" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2445 +msgid "Width of the rectangle to be filled" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2470 +msgid "Height of the rectangle to be filled" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2485 +#, fuzzy +msgid "Rows, columns: " +msgstr "Датотека" + +#: ../../po/../src/dialogs/clonetiler.cpp:2486 +msgid "Create the specified number of rows and columns" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2495 +msgid "Width, height: " +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2496 +msgid "Fill the specified width and height with the tiling" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2512 +msgid "Use saved size and position of the tile" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2515 +msgid "" +"Pretend that the size and position of the tile are the same as the last time " +"you tiled it (if any), instead of using the current size" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2539 +#, fuzzy +msgid " _Create " +msgstr "Датотека" + +#: ../../po/../src/dialogs/clonetiler.cpp:2541 +msgid "Create and tile the clones of the selection" +msgstr "" + +#. TRANSLATORS: if a group of objects are "clumped" together, then they +#. are unevenly spread in the given amount of space - as shown in the +#. diagrams on the left in the following screenshot: +#. http://www.inkscape.org/screenshots/gallery/inkscape-0.42-CVS-tiles-unclump.png +#. So unclumping is the process of spreading a number of objects out more evenly. +#: ../../po/../src/dialogs/clonetiler.cpp:2556 +msgid " _Unclump " +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2557 +msgid "Spread out clones to reduce clumping; can be applied repeatedly" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2563 +msgid " Re_move " +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2564 +msgid "Remove existing tiled clones of the selected object (siblings only)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2580 +msgid " R_eset " +msgstr "" + +#. TRANSLATORS: "change" is a noun here +#: ../../po/../src/dialogs/clonetiler.cpp:2582 +msgid "" +"Reset all shifts, scales, rotates, opacity and color changes in the dialog " +"to zero" +msgstr "" + +#: ../../po/../src/dialogs/color-picker.cpp:280 +#, fuzzy +msgid "Close" +msgstr "Затвори" + +#: ../../po/../src/dialogs/debugdialog.cpp:138 +msgid "Messages" +msgstr "" + +#. ## Add a menu for clear() +#: ../../po/../src/dialogs/debugdialog.cpp:144 +#: ../../po/../src/menus-skeleton.h:16 +#: ../../po/../src/ui/dialog/messages.cpp:56 +#: ../../po/../src/ui/dialog/scriptdialog.cpp:181 +#, fuzzy +msgid "_File" +msgstr "Датотека" + +#. TRANSLATORS: "Clear" is a verb here +#: ../../po/../src/dialogs/debugdialog.cpp:145 +#: ../../po/../src/dialogs/find.cpp:753 +#: ../../po/../src/ui/dialog/messages.cpp:57 +#: ../../po/../src/ui/dialog/scriptdialog.cpp:182 +#, fuzzy +msgid "_Clear" +msgstr "Затвори" + +#: ../../po/../src/dialogs/debugdialog.cpp:147 +#: ../../po/../src/ui/dialog/messages.cpp:59 +msgid "Capture log messages" +msgstr "" + +#: ../../po/../src/dialogs/debugdialog.cpp:149 +#: ../../po/../src/ui/dialog/messages.cpp:61 +msgid "Release log messages" +msgstr "" + +#. Notebook tab +#: ../../po/../src/dialogs/desktop-properties.cpp:909 +#: ../../po/../src/ui/dialog/document-preferences.cpp:89 +#: ../../po/../src/ui/widget/panel.cpp:107 +#, fuzzy +msgid "Grid" +msgstr "Решетка" + +#. Checkbuttons +#. / \todo FIXME: gray out snapping when grid is off +#. / \todo FIXME: gray out snapping when grid is off. +#. / Dissenting view: you want snapping without grid. +#: ../../po/../src/dialogs/desktop-properties.cpp:917 +#: ../../po/../src/ui/dialog/document-preferences.cpp:179 +msgid "Show grid" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:917 +#: ../../po/../src/ui/dialog/document-preferences.cpp:179 +#: ../../po/../src/verbs.cpp:2115 +msgid "Show or hide grid" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:918 +#: ../../po/../src/ui/dialog/document-preferences.cpp:180 +msgid "Snap bounding boxes to grid" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:918 +#: ../../po/../src/dialogs/desktop-properties.cpp:1001 +#: ../../po/../src/ui/dialog/document-preferences.cpp:181 +#: ../../po/../src/ui/dialog/document-preferences.cpp:236 +msgid "Snap the edges of the object bounding boxes" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:919 +#: ../../po/../src/ui/dialog/document-preferences.cpp:183 +msgid "Snap nodes to grid" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:919 +#: ../../po/../src/dialogs/desktop-properties.cpp:1002 +#: ../../po/../src/ui/dialog/document-preferences.cpp:184 +#: ../../po/../src/ui/dialog/document-preferences.cpp:239 +msgid "Snap path nodes, text baselines, ellipse centers, etc." +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:937 +#: ../../po/../src/ui/dialog/document-preferences.cpp:186 +msgid "Grid units:" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:939 +#: ../../po/../src/ui/dialog/document-preferences.cpp:187 +msgid "Origin X:" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:942 +#: ../../po/../src/ui/dialog/document-preferences.cpp:189 +msgid "Origin Y:" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:945 +#: ../../po/../src/ui/dialog/document-preferences.cpp:191 +msgid "Spacing X:" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:948 +#: ../../po/../src/ui/dialog/document-preferences.cpp:193 +msgid "Spacing Y:" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:952 +#: ../../po/../src/dialogs/desktop-properties.cpp:1013 +#: ../../po/../src/ui/dialog/document-preferences.cpp:195 +#: ../../po/../src/ui/dialog/document-preferences.cpp:241 +msgid "Snap units:" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:955 +#: ../../po/../src/dialogs/desktop-properties.cpp:1016 +#: ../../po/../src/ui/dialog/document-preferences.cpp:196 +#: ../../po/../src/ui/dialog/document-preferences.cpp:242 +msgid "Snap distance:" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:958 +#: ../../po/../src/ui/dialog/document-preferences.cpp:199 +#, fuzzy +msgid "Grid line color:" +msgstr "Боја на мрежата:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:959 +#: ../../po/../src/ui/dialog/document-preferences.cpp:199 +#, fuzzy +msgid "Grid line color" +msgstr "Боја на решетка" + +#: ../../po/../src/dialogs/desktop-properties.cpp:959 +#: ../../po/../src/ui/dialog/document-preferences.cpp:200 +msgid "Color of grid lines" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:961 +#: ../../po/../src/ui/dialog/document-preferences.cpp:201 +#, fuzzy +msgid "Major grid line color:" +msgstr "Боја на мрежата:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:962 +#: ../../po/../src/ui/dialog/document-preferences.cpp:201 +#, fuzzy +msgid "Major grid line color" +msgstr "Боја на мрежата:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:962 +#: ../../po/../src/ui/dialog/document-preferences.cpp:202 +msgid "Color of the major (highlighted) grid lines" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:965 +#: ../../po/../src/ui/dialog/document-preferences.cpp:204 +#, fuzzy +msgid "Major grid line every:" +msgstr "Боја на мрежата:" + +#. TRANSLATORS: This belongs to the "Major grid line every:" string, +#. see grid settings in the "Document Preferences" dialog +#: ../../po/../src/dialogs/desktop-properties.cpp:977 +#: ../../po/../src/ui/dialog/document-preferences.cpp:204 +#, fuzzy +msgid "lines" +msgstr "Затвори" + +#. Guidelines page +#: ../../po/../src/dialogs/desktop-properties.cpp:991 +#: ../../po/../src/ui/dialog/document-preferences.cpp:90 +#, fuzzy +msgid "Guides" +msgstr "Водичи" + +#. / \todo FIXME: gray out snapping when guides are off +#. / Dissenting view: you want snapping without guides. +#: ../../po/../src/dialogs/desktop-properties.cpp:1000 +#: ../../po/../src/ui/dialog/document-preferences.cpp:234 +msgid "Show guides" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1000 +#: ../../po/../src/ui/dialog/document-preferences.cpp:234 +#: ../../po/../src/verbs.cpp:2116 +msgid "Show or hide guides" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1001 +#: ../../po/../src/ui/dialog/document-preferences.cpp:235 +msgid "Snap bounding boxes to guides" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1002 +#: ../../po/../src/ui/dialog/document-preferences.cpp:238 +msgid "Snap points to guides" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1020 +#: ../../po/../src/ui/dialog/document-preferences.cpp:243 +#, fuzzy +msgid "Guide color:" +msgstr "Боја на мрежата:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1021 +#: ../../po/../src/ui/dialog/document-preferences.cpp:243 +msgid "Guideline color" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1021 +#: ../../po/../src/ui/dialog/document-preferences.cpp:244 +msgid "Color of guidelines" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1023 +#: ../../po/../src/ui/dialog/document-preferences.cpp:245 +#, fuzzy +msgid "Highlight color:" +msgstr "Боја на подвлекување" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1024 +#: ../../po/../src/ui/dialog/document-preferences.cpp:245 +msgid "Highlighted guideline color" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1024 +#: ../../po/../src/ui/dialog/document-preferences.cpp:246 +msgid "Color of a guideline when it is under mouse" +msgstr "" + +#. Page page +#: ../../po/../src/dialogs/desktop-properties.cpp:1029 +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:855 +#: ../../po/../src/ui/dialog/document-preferences.cpp:88 +#: ../../po/../src/widgets/desktop-widget.cpp:1061 +#, fuzzy +msgid "Page" +msgstr "Страница" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1039 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +#, fuzzy +msgid "Background:" +msgstr "Боја на решетка" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1040 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +#, fuzzy +msgid "Background color" +msgstr "Боја на решетка" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1041 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +msgid "" +"Color and transparency of the page background (also used for bitmap export)" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1045 +#: ../../po/../src/ui/dialog/document-preferences.cpp:147 +msgid "Show page border" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1049 +#: ../../po/../src/ui/dialog/document-preferences.cpp:148 +msgid "Border on top of drawing" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1052 +#: ../../po/../src/ui/dialog/document-preferences.cpp:149 +#, fuzzy +msgid "Border color:" +msgstr "Боја на мрежата:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1053 +#: ../../po/../src/ui/dialog/document-preferences.cpp:149 +#, fuzzy +msgid "Page border color" +msgstr "Боја на мрежата:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1054 +#: ../../po/../src/ui/dialog/document-preferences.cpp:150 +msgid "Color of the page border" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1059 +#: ../../po/../src/ui/dialog/document-preferences.cpp:152 +msgid "Show page shadow" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1063 +#: ../../po/../src/ui/dialog/document-preferences.cpp:153 +#, fuzzy +msgid "Default units:" +msgstr "Номинални" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1069 +msgid "Units for the tool controls, ruler, and the statusbar" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1086 +#: ../../po/../src/ui/widget/page-sizer.cpp:209 +#, fuzzy +msgid "Page size:" +msgstr "Големина на фонт:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1110 +#: ../../po/../src/ui/widget/page-sizer.cpp:219 +#, fuzzy +msgid "Custom" +msgstr "Сопствено" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1121 +#: ../../po/../src/ui/widget/page-sizer.cpp:225 +#, fuzzy +msgid "Page orientation:" +msgstr "Ориентација:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1133 +#: ../../po/../src/ui/widget/page-sizer.cpp:232 +msgid "Landscape" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1139 +#: ../../po/../src/ui/widget/page-sizer.cpp:234 +#, fuzzy +msgid "Portrait" +msgstr "Точка" + +#. Custom paper frame +#: ../../po/../src/dialogs/desktop-properties.cpp:1148 +#: ../../po/../src/ui/widget/page-sizer.cpp:249 +#, fuzzy +msgid "Custom size" +msgstr "Сопствено" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1160 +#: ../../po/../src/dialogs/export.cpp:269 +#: ../../po/../src/ui/widget/page-sizer.cpp:261 +msgid "Units:" +msgstr "" + +#. Stroke width +#: ../../po/../src/dialogs/desktop-properties.cpp:1162 +#: ../../po/../src/dialogs/export.cpp:310 +#: ../../po/../src/dialogs/object-attributes.cpp:55 +#: ../../po/../src/dialogs/stroke-style.cpp:985 +#: ../../po/../src/ui/widget/page-sizer.cpp:262 +#: ../../po/../src/widgets/toolbox.cpp:1957 +#, fuzzy +msgid "Width:" +msgstr "Ширина:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1183 +#: ../../po/../src/dialogs/export.cpp:326 +#: ../../po/../src/dialogs/export.cpp:431 +#: ../../po/../src/dialogs/object-attributes.cpp:56 +#: ../../po/../src/ui/widget/page-sizer.cpp:263 +#, fuzzy +msgid "Height:" +msgstr "Висина:" + +#. +#. * Ownership metadata tab +#. +#: ../../po/../src/dialogs/desktop-properties.cpp:1206 +msgid "Metadata" +msgstr "" + +#. add license selector pull-down +#: ../../po/../src/dialogs/desktop-properties.cpp:1225 +msgid "License" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1255 +msgid "Proprietary" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:212 +msgid "When transforming, show:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:223 +#, fuzzy +msgid "Objects" +msgstr "Објект" + +#: ../../po/../src/dialogs/display-settings.cpp:224 +msgid "Show the actual objects when moving or transforming" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:231 +msgid "Box outline" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:232 +msgid "Show only a box outline of the objects when moving or transforming" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:238 +msgid "Per-object selection cue:" +msgstr "" + +#. sorationsnapsperpi == 0 means no snapping +#: ../../po/../src/dialogs/display-settings.cpp:249 +#: ../../po/../src/dialogs/display-settings.cpp:386 +#: ../../po/../src/dialogs/display-settings.cpp:441 +#: ../../po/../src/dialogs/display-settings.cpp:1482 +#: ../../po/../src/dialogs/stroke-style.cpp:791 +#: ../../po/../src/interface.cpp:741 +#: ../../po/../src/ui/widget/selected-style.cpp:100 +#: ../../po/../src/verbs.cpp:1842 +#, fuzzy +msgid "None" +msgstr "Ништо" + +#: ../../po/../src/dialogs/display-settings.cpp:250 +msgid "No per-object selection indication" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:256 +msgid "Mark" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:257 +msgid "Each selected object has a diamond mark in the top left corner" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:264 +msgid "Box" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:265 +msgid "Each selected object displays its bounding box" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:270 +msgid "Default scale origin:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:281 +msgid "Opposite bounding box edge" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:282 +msgid "Default scale origin will be on the bounding box of the item" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:288 +msgid "Farthest opposite node" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:289 +msgid "Default scale origin will be on the bounding box of the item's points" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:341 +msgid "degrees" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:350 +msgid "" +"Rotating with Ctrl pressed snaps every that much degrees; also, pressing " +"[ or ] rotates by this amount" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:407 +msgid "Rotation snaps every:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:430 +msgid "" +"None: dialogs are treated as regular windows; Normal: dialogs stay on top of " +"document windows; Aggressive: same as Normal but may work better with some " +"window managers." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:451 +msgid "Normal" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:461 +msgid "Aggressive" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:475 +msgid "Dialogs on top:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:645 +#, fuzzy +msgid "Show selection cue" +msgstr "Избор" + +#: ../../po/../src/dialogs/display-settings.cpp:646 +msgid "" +"Whether selected objects display a selection cue (the same as in selector)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:657 +msgid "Enable gradient editing" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:658 +msgid "Whether selected objects display gradient editing controls" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:719 +msgid "No objects selected to take the style from." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:728 +msgid "" +"More than one object selected. Cannot take style from multiple " +"objects." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:767 +#, fuzzy +msgid "Create new objects with:" +msgstr "Зачувај документ" + +#: ../../po/../src/dialogs/display-settings.cpp:777 +#, fuzzy +msgid "Take from selection" +msgstr "Избриши" + +#: ../../po/../src/dialogs/display-settings.cpp:778 +msgid "Remember the style of the (first) selected object as this tool's style" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:782 +msgid "Last used style" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:782 +msgid "Apply the style you last set on an object" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:790 +msgid "This tool's own style:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:790 +msgid "" +"Each tool may store its own style to apply to the newly created objects. Use " +"the button below to set it." +msgstr "" + +#. Mouse +#: ../../po/../src/dialogs/display-settings.cpp:877 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:55 +#, fuzzy +msgid "Mouse" +msgstr "Премести" + +#. TRANSLATORS: "Grab" is a noun here. "Grab sensitivity" is intended to mean how +#. * close on the screen you need to be to an object to be able to grab it with mouse (in +#. * pixels). +#: ../../po/../src/dialogs/display-settings.cpp:883 +msgid "Grab sensitivity:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:884 +msgid "" +"How close on the screen you need to be to an object to be able to grab it " +"with mouse (in screen pixels)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:885 +#: ../../po/../src/dialogs/display-settings.cpp:897 +#: ../../po/../src/dialogs/display-settings.cpp:912 +#: ../../po/../src/dialogs/display-settings.cpp:930 +#: ../../po/../src/dialogs/display-settings.cpp:970 +#, fuzzy +msgid "pixels" +msgstr "пиксели" + +#: ../../po/../src/dialogs/display-settings.cpp:895 +msgid "Click/drag threshold:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:896 +msgid "" +"Maximum mouse drag (in screen pixels) which is considered a click, not a drag" +msgstr "" + +#. Scrolling +#: ../../po/../src/dialogs/display-settings.cpp:907 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:56 +msgid "Scrolling" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:910 +msgid "Mouse wheel scrolls by:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:911 +msgid "" +"One mouse wheel notch scrolls by this distance in screen pixels " +"(horizontally with Shift)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:920 +msgid "Ctrl+arrows" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:928 +msgid "Scroll by:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:929 +msgid "Pressing Ctrl+arrow key scrolls by this distance (in screen pixels)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:939 +#, fuzzy +msgid "Acceleration:" +msgstr "Избор" + +#: ../../po/../src/dialogs/display-settings.cpp:940 +msgid "" +"Pressing and holding Ctrl+arrow will gradually speed up scrolling (0 for no " +"acceleration)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:949 +msgid "Autoscrolling" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:957 +msgid "Speed:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:958 +msgid "" +"How fast the canvas autoscrolls when you drag beyond canvas edge (0 to turn " +"autoscroll off)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:968 +#: ../../po/../src/ui/dialog/tracedialog.cpp:357 +#: ../../po/../src/ui/dialog/tracedialog.cpp:390 +msgid "Threshold:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:969 +msgid "" +"How far (in screen pixels) you need to be from the canvas edge to trigger " +"autoscroll; positive is outside the canvas, negative is within the canvas" +msgstr "" + +#. Steps +#: ../../po/../src/dialogs/display-settings.cpp:979 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:57 +#, fuzzy +msgid "Steps" +msgstr "Стил" + +#: ../../po/../src/dialogs/display-settings.cpp:982 +msgid "Arrow keys move by:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:983 +msgid "" +"Pressing an arrow key moves selected object(s) or node(s) by this distance " +"(in px units)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:984 +#: ../../po/../src/dialogs/display-settings.cpp:995 +#: ../../po/../src/dialogs/display-settings.cpp:1006 +#: ../../po/../src/helper/units.cpp:42 +#, fuzzy +msgid "px" +msgstr "px" + +#: ../../po/../src/dialogs/display-settings.cpp:993 +msgid "> and < scale by:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:994 +msgid "" +"Pressing > or < scales selection up or down by this increment (in px units)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1004 +msgid "Inset/Outset by:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1005 +msgid "" +"Inset and Outset commands displace the path by this distance (in px units)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1017 +msgid "Compass-like display of angles" +msgstr "" + +#. TRANSLATORS: "positive clockwise" means "increasing in clockwise direction" +#: ../../po/../src/dialogs/display-settings.cpp:1019 +msgid "" +"When on, angles are displayed with 0 at north, 0 to 360 range, positive " +"clockwise; otherwise with 0 at east, -180 to 180 range, positive " +"counterclockwise" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1026 +msgid "Zoom in/out by:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1027 +msgid "" +"Zoom tool click, +/- keys, and middle click zoom in and out by this " +"multiplier" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1028 +#: ../../po/../src/helper/units.cpp:44 +#, fuzzy +msgid "%" +msgstr "%" + +#. Tools +#: ../../po/../src/dialogs/display-settings.cpp:1037 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:58 +msgid "Tools" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1045 +#, fuzzy +msgid "Selector" +msgstr "Избор" + +#: ../../po/../src/dialogs/display-settings.cpp:1056 +#, fuzzy +msgid "Node" +msgstr "Ништо" + +#: ../../po/../src/dialogs/display-settings.cpp:1064 +#: ../../po/../src/verbs.cpp:2073 +#: ../../po/../src/widgets/desktop-widget.cpp:277 +#, fuzzy +msgid "Zoom" +msgstr "Зум" + +#. The 4 shape tools +#: ../../po/../src/dialogs/display-settings.cpp:1071 +#, fuzzy +msgid "Shapes" +msgstr "Облик" + +#: ../../po/../src/dialogs/display-settings.cpp:1079 +#: ../../po/../src/verbs.cpp:2055 +#, fuzzy +msgid "Rectangle" +msgstr "Правоаголник" + +#: ../../po/../src/dialogs/display-settings.cpp:1085 +#: ../../po/../src/verbs.cpp:2057 +#, fuzzy +msgid "Ellipse" +msgstr "Елипса" + +#: ../../po/../src/dialogs/display-settings.cpp:1091 +#: ../../po/../src/verbs.cpp:2059 +msgid "Star" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1097 +#: ../../po/../src/verbs.cpp:2061 +#, fuzzy +msgid "Spiral" +msgstr "Спирала" + +#: ../../po/../src/dialogs/display-settings.cpp:1111 +#: ../../po/../src/verbs.cpp:2063 +msgid "Pencil" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1114 +msgid "Tolerance:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1115 +msgid "" +"This value affects the amount of smoothing applied to freehand lines; lower " +"values produce more uneven paths with more nodes" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1131 +#: ../../po/../src/verbs.cpp:2065 +#, fuzzy +msgid "Pen" +msgstr "Пенкало" + +#: ../../po/../src/dialogs/display-settings.cpp:1140 +#: ../../po/../src/verbs.cpp:2067 +msgid "Calligraphy" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1147 +#: ../../po/../src/dialogs/text-edit.cpp:353 +#: ../../po/../src/ui/dialog/text-properties.cpp:37 +#: ../../po/../src/verbs.cpp:2069 +#, fuzzy +msgid "Text" +msgstr "Текст" + +#: ../../po/../src/dialogs/display-settings.cpp:1157 +#: ../../po/../src/verbs.cpp:2071 +#, fuzzy +msgid "Gradient" +msgstr "Аргумент:" + +#: ../../po/../src/dialogs/display-settings.cpp:1164 +#: ../../po/../src/verbs.cpp:2077 +#, fuzzy +msgid "Connector" +msgstr "Затвори" + +#: ../../po/../src/dialogs/display-settings.cpp:1171 +#: ../../po/../src/verbs.cpp:2075 +msgid "Dropper" +msgstr "" + +#. Windows +#: ../../po/../src/dialogs/display-settings.cpp:1183 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:59 +msgid "Windows" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1188 +#, fuzzy +msgid "Save window geometry" +msgstr "Зачувај документ" + +#: ../../po/../src/dialogs/display-settings.cpp:1189 +msgid "" +"Save the window size and position with each document (only for Inkscape SVG " +"format)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1196 +msgid "Dialogs are hidden in taskbar" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1197 +msgid "Whether dialog windows are to be hidden in the window manager taskbar" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1204 +msgid "Zoom when window is resized" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1205 +msgid "" +"Zoom drawing when document window is resized, to keep the same area visible " +"(this is the default which can be changed in any window using the button " +"above the right scrollbar)" +msgstr "" + +#. Clones +#: ../../po/../src/dialogs/display-settings.cpp:1213 +#: ../../po/../src/dialogs/find.cpp:624 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:60 +#, fuzzy +msgid "Clones" +msgstr "Затвори" + +#: ../../po/../src/dialogs/display-settings.cpp:1217 +msgid "When the original moves, its clones and linked offsets:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1229 +msgid "Move in parallel" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1230 +msgid "Clones are translated by the same vector as their original." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1237 +msgid "Stay unmoved" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1238 +msgid "Clones preserve their positions when their original is moved." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1245 +msgid "Move according to transform" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1246 +msgid "" +"Each clone moves according to the value of its transform= attribute. For " +"example, a rotated clone will move in a different direction than its " +"original." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1255 +msgid "When the original is deleted, its clones:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1267 +msgid "Are unlinked" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1267 +msgid "Orphaned clones are converted to regular objects." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1273 +#, fuzzy +msgid "Are deleted" +msgstr "Избор" + +#: ../../po/../src/dialogs/display-settings.cpp:1273 +msgid "Orphaned clones are deleted along with their original." +msgstr "" + +#. Transforms +#. TRANSLATORS: Noun, i.e. transformations. +#: ../../po/../src/dialogs/display-settings.cpp:1289 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:61 +msgid "Transforms" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1292 +msgid "Scale stroke width" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1293 +#: ../../po/../src/widgets/select-toolbar.cpp:568 +msgid "When scaling objects, scale the stroke width by the same proportion" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1300 +msgid "Scale rounded corners in rectangles" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1301 +#: ../../po/../src/widgets/select-toolbar.cpp:580 +msgid "When scaling rectangles, scale the radii of rounded corners" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1308 +msgid "Transform gradients" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1309 +#: ../../po/../src/widgets/select-toolbar.cpp:592 +msgid "Transform gradients (in fill or stroke) along with the objects" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1316 +msgid "Transform patterns" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1317 +#: ../../po/../src/widgets/select-toolbar.cpp:604 +msgid "Transform patterns (in fill or stroke) along with the objects" +msgstr "" + +#. TRANSLATORS: How to specify the affine transformation in the SVG file. +#: ../../po/../src/dialogs/display-settings.cpp:1327 +msgid "Store transformation:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1338 +#, fuzzy +msgid "Optimized" +msgstr "Оптимизирај" + +#: ../../po/../src/dialogs/display-settings.cpp:1339 +msgid "" +"If possible, apply transformation to objects without adding a transform= " +"attribute" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1346 +msgid "Preserved" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1347 +msgid "Always store transformation as a transform= attribute on objects" +msgstr "" + +#. Selecting +#: ../../po/../src/dialogs/display-settings.cpp:1355 +#, fuzzy +msgid "Selecting" +msgstr "Избор" + +#: ../../po/../src/dialogs/display-settings.cpp:1357 +msgid "Ctrl+A, Tab, Shift+Tab:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1366 +#, fuzzy +msgid "Select only within current layer" +msgstr "Документ" + +#: ../../po/../src/dialogs/display-settings.cpp:1367 +msgid "" +"Uncheck this to make keyboard selection commands work on objects in all " +"layers" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1374 +msgid "Ignore hidden objects" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1375 +msgid "" +"Uncheck this to be able to select objects that are hidden (either by " +"themselves or by being in a hidden group or layer)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1382 +msgid "Ignore locked objects" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1383 +msgid "" +"Uncheck this to be able to select objects that are locked (either by " +"themselves or by being in a locked group or layer)" +msgstr "" + +#. To be broken into: Display, Save, Export, SVG, Commands +#: ../../po/../src/dialogs/display-settings.cpp:1391 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:62 +msgid "Misc" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1394 +msgid "Default export resolution:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1395 +msgid "Default bitmap resolution (in dots per inch) in the Export dialog" +msgstr "" + +#. FIXME: add "Used for new exports; once exported, documents remember this value on per-object basis" when implemented +#: ../../po/../src/dialogs/display-settings.cpp:1396 +#: ../../po/../src/dialogs/export.cpp:442 +#, fuzzy +msgid "dpi" +msgstr "dpi" + +#. TRANSLATORS: When on, an imported bitmap creates an element; otherwise it is a +#. * rectangle with bitmap fill. +#: ../../po/../src/dialogs/display-settings.cpp:1407 +msgid "Import bitmap as " +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1408 +msgid "" +"When on, an imported bitmap creates an element; otherwise it is a " +"rectangle with bitmap fill" +msgstr "" + +#. TRANSLATORS: When on, the print out (currently Postscript) will have +#. * a comment with the each object's label visible, marking the section +#. * of the printing commands that represent the given object. +#: ../../po/../src/dialogs/display-settings.cpp:1418 +msgid "Add label comments to printing output" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1419 +msgid "" +"When on, a comment will be added to the raw print output, marking the " +"rendered output for an object with its label" +msgstr "" + +#. TRANSLATORS: When on, enable the effects menu, default is off +#: ../../po/../src/dialogs/display-settings.cpp:1427 +msgid "Enable script effects (requires restart) - EXPERIMENTAL" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1428 +msgid "" +"When on, the effects menu is enabled, allowing external effect scripts to be " +"called, requires restart before effective - EXPERIMENTAL" +msgstr "" + +#. TRANSLATORS: The maximum length of the Open Recent list in the File menu. +#: ../../po/../src/dialogs/display-settings.cpp:1436 +#, fuzzy +msgid "Max recent documents:" +msgstr "Зачувај документ" + +#: ../../po/../src/dialogs/display-settings.cpp:1437 +msgid "The maximum length of the Open Recent list in the File menu" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1447 +msgid "Simplification threshold:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1448 +msgid "" +"How strong is the Simplify command by default. If you invoke this command " +"several times in quick succession, it will act more and more aggressively; " +"invoking it again after a pause restores the default threshold." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1469 +msgid "Oversample bitmaps:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1488 +msgid "2x2" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1494 +msgid "4x4" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1500 +msgid "8x8" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1506 +msgid "16x16" +msgstr "" + +#. "view_icon_preview" +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2143 +#, fuzzy +msgid "_Page" +msgstr "Страница" + +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2147 +#, fuzzy +msgid "_Drawing" +msgstr "Цртеж" + +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2149 +#, fuzzy +msgid "_Selection" +msgstr "Избор" + +#: ../../po/../src/dialogs/export.cpp:133 +#, fuzzy +msgid "_Custom" +msgstr "Сопствено" + +#: ../../po/../src/dialogs/export.cpp:254 +msgid "Export area" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:300 +msgid "_x0:" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:305 +msgid "x_1:" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:316 +msgid "_y0:" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:321 +msgid "y_1:" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:406 +msgid "Bitmap size" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:416 +#, fuzzy +msgid "_Width:" +msgstr "Ширина:" + +#: ../../po/../src/dialogs/export.cpp:416 +#: ../../po/../src/dialogs/export.cpp:431 +#, fuzzy +msgid "pixels at" +msgstr "пиксели" + +#: ../../po/../src/dialogs/export.cpp:426 +#, fuzzy +msgid "dp_i" +msgstr "dpi" + +#: ../../po/../src/dialogs/export.cpp:448 +#, fuzzy +msgid "_Filename" +msgstr "Датотека" + +#: ../../po/../src/dialogs/export.cpp:512 +msgid "_Browse..." +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:539 +#, fuzzy +msgid " _Export " +msgstr "Датотека" + +#: ../../po/../src/dialogs/export.cpp:541 +msgid "Export the bitmap file with these settings" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:968 +msgid "You have to enter a filename" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:973 +msgid "The chosen area to be exported is invalid" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:982 +#, c-format +msgid "Directory %s does not exist or is not a directory.\n" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:998 +msgid "Export in progress" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:1004 +#, c-format +msgid "Exporting %s (%d x %d)" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:1031 +#, c-format +msgid "Could not export to filename %s.\n" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:1137 +msgid "Select a filename for exporting" +msgstr "" + +#: ../../po/../src/dialogs/filedialog.cpp:367 +#, fuzzy +msgid "No preview" +msgstr "Печати на екран" + +#: ../../po/../src/dialogs/filedialog.cpp:468 +msgid "too large for preview" +msgstr "" + +#: ../../po/../src/dialogs/filedialog.cpp:762 +#: ../../po/../src/dialogs/filedialog.cpp:763 +#, fuzzy +msgid "All Images" +msgstr "Слика" + +#: ../../po/../src/dialogs/filedialog.cpp:767 +#: ../../po/../src/dialogs/filedialog.cpp:768 +msgid "All Files" +msgstr "" + +#: ../../po/../src/dialogs/filedialog.cpp:774 +#: ../../po/../src/dialogs/filedialog.cpp:775 +msgid "All Inkscape Files" +msgstr "" + +#: ../../po/../src/dialogs/filedialog.cpp:1176 +#, fuzzy +msgid "Guess from extension" +msgstr "Избриши" + +#. ###### Add the file types menu +#. createFilterMenu(); +#. ###### Do we want the .xxx extension automatically added? +#: ../../po/../src/dialogs/filedialog.cpp:1261 +msgid "Append filename extension automatically" +msgstr "" + +#. TRANSLATORS: "%s" is replaced with "exact" or "partial" when this string is displayed +#: ../../po/../src/dialogs/find.cpp:378 +#, c-format +msgid "%d object found (out of %d), %s match." +msgid_plural "%d objects found (out of %d), %s match." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/dialogs/find.cpp:381 +#, fuzzy +msgid "exact" +msgstr "Текст" + +#: ../../po/../src/dialogs/find.cpp:381 +#, fuzzy +msgid "partial" +msgstr "Спирала" + +#: ../../po/../src/dialogs/find.cpp:388 +#, fuzzy +msgid "No objects found" +msgstr "Зачувај документ" + +#: ../../po/../src/dialogs/find.cpp:546 +#, fuzzy +msgid "T_ype: " +msgstr "Тип:" + +#: ../../po/../src/dialogs/find.cpp:553 +msgid "Search in all object types" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:553 +msgid "All types" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:564 +msgid "Search all shapes" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:564 +msgid "All shapes" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:581 +#, fuzzy +msgid "Search rectangles" +msgstr "Правоаголник" + +#: ../../po/../src/dialogs/find.cpp:581 +#, fuzzy +msgid "Rectangles" +msgstr "Правоаголник" + +#: ../../po/../src/dialogs/find.cpp:586 +msgid "Search ellipses, arcs, circles" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:586 +#, fuzzy +msgid "Ellipses" +msgstr "Елипса" + +#: ../../po/../src/dialogs/find.cpp:591 +msgid "Search stars and polygons" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:591 +#, fuzzy +msgid "Stars" +msgstr "Стил" + +#: ../../po/../src/dialogs/find.cpp:596 +#, fuzzy +msgid "Search spirals" +msgstr "Спирала" + +#: ../../po/../src/dialogs/find.cpp:596 +#, fuzzy +msgid "Spirals" +msgstr "Спирала" + +#. TRANSLATORS: polyline is a set of connected straight line segments +#. http://www.w3.org/TR/SVG11/shapes.html#PolylineElement +#: ../../po/../src/dialogs/find.cpp:609 +msgid "Search paths, lines, polylines" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:609 +#, fuzzy +msgid "Paths" +msgstr "Вметни" + +#: ../../po/../src/dialogs/find.cpp:614 +msgid "Search text objects" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:614 +#, fuzzy +msgid "Texts" +msgstr "Текст" + +#: ../../po/../src/dialogs/find.cpp:619 +msgid "Search groups" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:619 +#, fuzzy +msgid "Groups" +msgstr "Група" + +#: ../../po/../src/dialogs/find.cpp:624 +msgid "Search clones" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:629 +msgid "Search images" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:629 +#, fuzzy +msgid "Images" +msgstr "Слика" + +#: ../../po/../src/dialogs/find.cpp:634 +msgid "Search offset objects" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:634 +msgid "Offsets" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:694 +#, fuzzy +msgid "_Text: " +msgstr "Текст" + +#: ../../po/../src/dialogs/find.cpp:694 +msgid "Find objects by their text content (exact or partial match)" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:695 +msgid "_ID: " +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:695 +msgid "Find objects by the value of the id attribute (exact or partial match)" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:696 +#, fuzzy +msgid "_Style: " +msgstr "Стил" + +#: ../../po/../src/dialogs/find.cpp:696 +msgid "" +"Find objects by the value of the style attribute (exact or partial match)" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:697 +#, fuzzy +msgid "_Attribute: " +msgstr "Атрибут" + +#: ../../po/../src/dialogs/find.cpp:697 +msgid "Find objects by the name of an attribute (exact or partial match)" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:711 +#, fuzzy +msgid "Search in s_election" +msgstr "Избор" + +#: ../../po/../src/dialogs/find.cpp:715 +msgid "Limit search to the current selection" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:720 +#, fuzzy +msgid "Search in current _layer" +msgstr "Документ" + +#: ../../po/../src/dialogs/find.cpp:724 +#, fuzzy +msgid "Limit search to the current layer" +msgstr "Документ" + +#: ../../po/../src/dialogs/find.cpp:729 +msgid "Include _hidden" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:733 +msgid "Include hidden objects in search" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:738 +msgid "Include l_ocked" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:742 +msgid "Include locked objects in search" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:753 +#, fuzzy +msgid "Clear values" +msgstr "Исчисти ги сите" + +#: ../../po/../src/dialogs/find.cpp:754 +#, fuzzy +msgid "_Find" +msgstr "Решетка" + +#: ../../po/../src/dialogs/find.cpp:754 +msgid "Select objects matching all of the fields you filled in" +msgstr "" + +#: ../../po/../src/dialogs/iconpreview.cpp:145 +#, c-format +msgid "%d x %d" +msgstr "" + +#: ../../po/../src/dialogs/iconpreview.cpp:193 +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:857 +#: ../../po/../src/widgets/desktop-widget.cpp:1069 +#, fuzzy +msgid "Selection" +msgstr "Избор" + +#: ../../po/../src/dialogs/iconpreview.cpp:195 +#, fuzzy +msgid "Selection only or whole document" +msgstr "Документ" + +#: ../../po/../src/dialogs/iconpreview.cpp:203 +msgid "Refresh the icons" +msgstr "" + +#. Create the label for the object id +#: ../../po/../src/dialogs/item-properties.cpp:126 +#: ../../po/../src/dialogs/item-properties.cpp:327 +#: ../../po/../src/dialogs/item-properties.cpp:396 +#: ../../po/../src/dialogs/item-properties.cpp:403 +msgid "_Id" +msgstr "" + +#: ../../po/../src/dialogs/item-properties.cpp:135 +msgid "" +"The id= attribute (only letters, digits, and the characters .-_: allowed)" +msgstr "" + +#. Button for setting the object's id, label, title and description. +#: ../../po/../src/dialogs/item-properties.cpp:149 +#, fuzzy +msgid "_Set" +msgstr "Избор" + +#. Create the label for the object label +#: ../../po/../src/dialogs/item-properties.cpp:158 +#, fuzzy +msgid "_Label" +msgstr "Долни" + +#: ../../po/../src/dialogs/item-properties.cpp:167 +msgid "A freeform label for the object" +msgstr "" + +#. Create the label for the object title +#: ../../po/../src/dialogs/item-properties.cpp:179 +#: ../../po/../src/dialogs/rdf.cpp:243 +#, fuzzy +msgid "Title" +msgstr "Наслов:" + +#. Create the frame for the object description +#: ../../po/../src/dialogs/item-properties.cpp:196 +#: ../../po/../src/dialogs/rdf.cpp:287 +#, fuzzy +msgid "Description" +msgstr "Избор" + +#. Hide +#: ../../po/../src/dialogs/item-properties.cpp:223 +#, fuzzy +msgid "_Hide" +msgstr "Водичи" + +#: ../../po/../src/dialogs/item-properties.cpp:224 +msgid "Check to make the object invisible" +msgstr "" + +#. Lock +#. TRANSLATORS: "Lock" is a verb here +#: ../../po/../src/dialogs/item-properties.cpp:233 +msgid "L_ock" +msgstr "" + +#: ../../po/../src/dialogs/item-properties.cpp:234 +msgid "Check to make the object insensitive (not selectable by mouse)" +msgstr "" + +#: ../../po/../src/dialogs/item-properties.cpp:310 +#: ../../po/../src/dialogs/item-properties.cpp:317 +msgid "Ref" +msgstr "" + +#: ../../po/../src/dialogs/item-properties.cpp:398 +msgid "Id invalid! " +msgstr "" + +#: ../../po/../src/dialogs/item-properties.cpp:400 +msgid "Id exists! " +msgstr "" + +#: ../../po/../src/dialogs/layer-properties.cpp:50 +msgid "Layer name:" +msgstr "" + +#: ../../po/../src/dialogs/layer-properties.cpp:133 +#, fuzzy +msgid "Rename Layer" +msgstr "Избриши" + +#: ../../po/../src/dialogs/layer-properties.cpp:136 +#, fuzzy +msgid "_Rename" +msgstr "Датотека" + +#. TRANSLATORS: This means "The layer has been renamed" +#: ../../po/../src/dialogs/layer-properties.cpp:147 +#, fuzzy +msgid "Renamed layer" +msgstr "Избриши" + +#: ../../po/../src/dialogs/layer-properties.cpp:151 +#, fuzzy +msgid "Add Layer" +msgstr "Долни" + +#: ../../po/../src/dialogs/layer-properties.cpp:153 +#, fuzzy +msgid "_Add" +msgstr "Додај" + +#: ../../po/../src/dialogs/layer-properties.cpp:167 +msgid "New layer created." +msgstr "" + +#: ../../po/../src/dialogs/object-attributes.cpp:34 +msgid "Href:" +msgstr "" + +#: ../../po/../src/dialogs/object-attributes.cpp:35 +msgid "Target:" +msgstr "" + +#: ../../po/../src/dialogs/object-attributes.cpp:36 +#, fuzzy +msgid "Type:" +msgstr "Тип:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkRoleAttribute +#. Identifies the type of the related resource with an absolute URI +#: ../../po/../src/dialogs/object-attributes.cpp:39 +msgid "Role:" +msgstr "" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkArcRoleAttribute +#. For situations where the nature/role alone isn't enough, this offers an additional URI defining the purpose of the link. +#: ../../po/../src/dialogs/object-attributes.cpp:42 +msgid "Arcrole:" +msgstr "" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkTitleAttribute +#: ../../po/../src/dialogs/object-attributes.cpp:44 +#, fuzzy +msgid "Title:" +msgstr "Наслов:" + +#: ../../po/../src/dialogs/object-attributes.cpp:45 +msgid "Show:" +msgstr "" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkActuateAttribute +#: ../../po/../src/dialogs/object-attributes.cpp:47 +msgid "Actuate:" +msgstr "" + +#: ../../po/../src/dialogs/object-attributes.cpp:52 +#, fuzzy +msgid "URL:" +msgstr "URL:" + +#: ../../po/../src/dialogs/object-attributes.cpp:53 +msgid "X:" +msgstr "" + +#: ../../po/../src/dialogs/object-attributes.cpp:54 +#, fuzzy +msgid "Y:" +msgstr "Y:" + +#: ../../po/../src/dialogs/object-attributes.cpp:98 +#, c-format +msgid "%s attributes" +msgstr "" + +#: ../../po/../src/dialogs/object-properties.cpp:158 +#, fuzzy +msgid "_Fill" +msgstr "Пополни" + +#: ../../po/../src/dialogs/object-properties.cpp:165 +msgid "Stroke _paint" +msgstr "" + +#: ../../po/../src/dialogs/object-properties.cpp:172 +msgid "Stroke st_yle" +msgstr "" + +#: ../../po/../src/dialogs/object-properties.cpp:183 +msgid "Master _opacity" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:244 +msgid "Name by which this document is formally known." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:246 +#, fuzzy +msgid "Date" +msgstr "Вметни" + +#: ../../po/../src/dialogs/rdf.cpp:247 +msgid "Date associated with the creation of this document (YYYY-MM-DD)." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:249 +msgid "Format" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:250 +msgid "The physical or digital manifestation of this document (MIME type)." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:252 +#, fuzzy +msgid "Type" +msgstr "Тип:" + +#: ../../po/../src/dialogs/rdf.cpp:253 +msgid "Type of document (DCMI Type)." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:256 +#, fuzzy +msgid "Creator" +msgstr "Создади" + +#: ../../po/../src/dialogs/rdf.cpp:257 +msgid "" +"Name of entity primarily responsible for making the content of this document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:259 +#, fuzzy +msgid "Rights" +msgstr "Висина:" + +#: ../../po/../src/dialogs/rdf.cpp:260 +msgid "" +"Name of entity with rights to the Intellectual Property of this document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:262 +msgid "Publisher" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:263 +msgid "Name of entity responsible for making this document available." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:266 +#, fuzzy +msgid "Identifier" +msgstr "Сантиметар" + +#: ../../po/../src/dialogs/rdf.cpp:267 +msgid "Unique URI to reference this document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:269 +msgid "Source" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:270 +msgid "Unique URI to reference the source of this document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:272 +#, fuzzy +msgid "Relation" +msgstr "Избор" + +#: ../../po/../src/dialogs/rdf.cpp:273 +msgid "Unique URI to a related document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:275 +msgid "Language" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:276 +msgid "" +"Two-letter language tag with optional subtags for the language of this " +"document. (e.g. 'en-GB')" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:278 +msgid "Keywords" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:279 +msgid "" +"The topic of this document as comma-separated key words, phrases, or " +"classifications." +msgstr "" + +#. TRANSLATORS: "Coverage": the spatial or temporal characteristics of the content. +#. For info, see Appendix D of http://www.w3.org/TR/1998/WD-rdf-schema-19980409/ +#: ../../po/../src/dialogs/rdf.cpp:283 +msgid "Coverage" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:284 +msgid "Extent or scope of this document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:288 +msgid "A short account of the content of this document." +msgstr "" + +#. FIXME: need to handle 1 agent per line of input +#: ../../po/../src/dialogs/rdf.cpp:292 +#, fuzzy +msgid "Contributors" +msgstr "Сантиметри" + +#: ../../po/../src/dialogs/rdf.cpp:293 +msgid "" +"Names of entities responsible for making contributions to the content of " +"this document." +msgstr "" + +#. TRANSLATORS: URL to a page that defines the license for the document +#: ../../po/../src/dialogs/rdf.cpp:297 +msgid "URI" +msgstr "" + +#. TRANSLATORS: this is where you put a URL to a page that defines the license +#: ../../po/../src/dialogs/rdf.cpp:299 +msgid "URI to this document's license's namespace definition." +msgstr "" + +#. TRANSLATORS: fragment of XML representing the license of the document +#: ../../po/../src/dialogs/rdf.cpp:303 +#, fuzzy +msgid "Fragment" +msgstr "Аргумент:" + +#: ../../po/../src/dialogs/rdf.cpp:304 +msgid "XML fragment for the RDF 'License' section." +msgstr "" + +#: ../../po/../src/dialogs/stroke-style.cpp:774 +#: ../../po/../src/widgets/gradient-vector.cpp:263 +#: ../../po/../src/widgets/paint-selector.cpp:751 +msgid "No document selected" +msgstr "" + +#: ../../po/../src/dialogs/stroke-style.cpp:992 +msgid "Stroke width" +msgstr "" + +#. Join type +#. TRANSLATORS: The line join style specifies the shape to be used at the +#. corners of paths. It can be "miter", "round" or "bevel". +#: ../../po/../src/dialogs/stroke-style.cpp:1015 +msgid "Join:" +msgstr "" + +#. TRANSLATORS: Miter join: joining lines with a sharp (pointed) corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1027 +msgid "Miter join" +msgstr "" + +#. TRANSLATORS: Round join: joining lines with a rounded corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1035 +msgid "Round join" +msgstr "" + +#. TRANSLATORS: Bevel join: joining lines with a blunted (flattened) corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1043 +msgid "Bevel join" +msgstr "" + +#. Miterlimit +#. TRANSLATORS: Miter limit: only for "miter join", this limits the length +#. of the sharp "spike" when the lines connect at too sharp an angle. +#. When two line segments meet at a sharp angle, a miter join results in a +#. spike that extends well beyond the connection point. The purpose of the +#. miter limit is to cut off such spikes (i.e. convert them into bevels) +#. when they become too long. +#: ../../po/../src/dialogs/stroke-style.cpp:1054 +msgid "Miter limit:" +msgstr "" + +#: ../../po/../src/dialogs/stroke-style.cpp:1062 +msgid "Maximum length of the miter (in units of stroke width)" +msgstr "" + +#. Cap type +#. TRANSLATORS: cap type specifies the shape for the ends of lines +#: ../../po/../src/dialogs/stroke-style.cpp:1075 +msgid "Cap:" +msgstr "" + +#. TRANSLATORS: Butt cap: the line shape does not extend beyond the end point +#. of the line; the ends of the line are square +#: ../../po/../src/dialogs/stroke-style.cpp:1086 +msgid "Butt cap" +msgstr "" + +#. TRANSLATORS: Round cap: the line shape extends beyond the end point of the +#. line; the ends of the line are rounded +#: ../../po/../src/dialogs/stroke-style.cpp:1093 +msgid "Round cap" +msgstr "" + +#. TRANSLATORS: Square cap: the line shape extends beyond the end point of the +#. line; the ends of the line are square +#: ../../po/../src/dialogs/stroke-style.cpp:1100 +msgid "Square cap" +msgstr "" + +#. Dash +#: ../../po/../src/dialogs/stroke-style.cpp:1106 +msgid "Dashes:" +msgstr "" + +#. TRANSLATORS: Path markers are an SVG feature that allows you to attach arbitrary shapes +#. (arrowheads, bullets, faces, whatever) to the start, end, or middle nodes of a path. +#: ../../po/../src/dialogs/stroke-style.cpp:1127 +msgid "Start Markers:" +msgstr "" + +#: ../../po/../src/dialogs/stroke-style.cpp:1137 +msgid "Mid Markers:" +msgstr "" + +#: ../../po/../src/dialogs/stroke-style.cpp:1148 +msgid "End Markers:" +msgstr "" + +#: ../../po/../src/dialogs/swatches.cpp:424 +#, c-format +msgid "Palettes directory (%s) is unavailable." +msgstr "" + +#. TODO: Insert widgets +#: ../../po/../src/dialogs/text-edit.cpp:199 +#: ../../po/../src/ui/dialog/text-properties.cpp:36 +#, fuzzy +msgid "Font" +msgstr "Точка" + +#: ../../po/../src/dialogs/text-edit.cpp:216 +#, fuzzy +msgid "Layout" +msgstr "Изглед" + +#: ../../po/../src/dialogs/text-edit.cpp:229 +msgid "Align lines left" +msgstr "" + +#. TRANSLATORS: `Center' here is a verb. +#: ../../po/../src/dialogs/text-edit.cpp:243 +#, fuzzy +msgid "Center lines" +msgstr "Преврти вертикално" + +#: ../../po/../src/dialogs/text-edit.cpp:256 +msgid "Align lines right" +msgstr "" + +#: ../../po/../src/dialogs/text-edit.cpp:278 +#, fuzzy +msgid "Horizontal text" +msgstr "Преврти хоризонтално" + +#: ../../po/../src/dialogs/text-edit.cpp:292 +#, fuzzy +msgid "Vertical text" +msgstr "Преврти вертикално" + +#: ../../po/../src/dialogs/text-edit.cpp:307 +msgid "Line spacing:" +msgstr "" + +#: ../../po/../src/dialogs/text-edit.cpp:400 +#, fuzzy +msgid "Set as default" +msgstr "Постави како основно" + +#: ../../po/../src/dialogs/tiledialog.cpp:603 +msgid "Rows:" +msgstr "" + +#: ../../po/../src/dialogs/tiledialog.cpp:613 +msgid "Number of rows" +msgstr "" + +#: ../../po/../src/dialogs/tiledialog.cpp:617 +#, fuzzy +msgid "Equal height" +msgstr "Висина:" + +#: ../../po/../src/dialogs/tiledialog.cpp:627 +msgid "If not set, each row has the height of the tallest object in it" +msgstr "" + +#. #### Radio buttons to control vertical alignment #### +#. #### Radio buttons to control horizontal alignment #### +#: ../../po/../src/dialogs/tiledialog.cpp:637 +#: ../../po/../src/dialogs/tiledialog.cpp:708 +#, fuzzy +msgid "Align:" +msgstr "Порамни" + +#: ../../po/../src/dialogs/tiledialog.cpp:672 +msgid " X " +msgstr "" + +#. #### Number of columns #### +#: ../../po/../src/dialogs/tiledialog.cpp:678 +#, fuzzy +msgid "Columns:" +msgstr "Датотека" + +#: ../../po/../src/dialogs/tiledialog.cpp:688 +msgid "Number of columns" +msgstr "" + +#: ../../po/../src/dialogs/tiledialog.cpp:692 +#, fuzzy +msgid "Equal width" +msgstr "Ширина:" + +#: ../../po/../src/dialogs/tiledialog.cpp:701 +msgid "If not set, each column has the width of the widest object in it" +msgstr "" + +#. #### Radio buttons to control spacing manually or to fit selection bbox #### +#: ../../po/../src/dialogs/tiledialog.cpp:746 +#, fuzzy +msgid "Fit into selection box" +msgstr "Избор" + +#: ../../po/../src/dialogs/tiledialog.cpp:753 +#, fuzzy +msgid "Set spacing:" +msgstr "Преврти вертикално" + +#. #### Y Padding #### +#: ../../po/../src/dialogs/tiledialog.cpp:777 +#, fuzzy +msgid "Row spacing: " +msgstr "Преврти вертикално" + +#: ../../po/../src/dialogs/tiledialog.cpp:786 +#, fuzzy +msgid "Vertical spacing between rows" +msgstr "Преврти вертикално" + +#. #### X padding #### +#: ../../po/../src/dialogs/tiledialog.cpp:795 +msgid "Column spacing:" +msgstr "" + +#: ../../po/../src/dialogs/tiledialog.cpp:804 +#, fuzzy +msgid "Horizontal spacing between columns" +msgstr "Преврти хоризонтално" + +#: ../../po/../src/dialogs/tiledialog.cpp:818 +#, fuzzy +msgid "Arrange selected objects" +msgstr "Избор" + +#: ../../po/../src/dialogs/xml-tree.cpp:178 +msgid "Click to select nodes, drag to rearrange." +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:189 +msgid "Click attribute to edit." +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:193 +#, c-format +msgid "" +"Attribute %s selected. Press Ctrl+Enter when done editing to " +"commit changes." +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:284 +msgid "Drag to reorder nodes" +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:304 +msgid "New element node" +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:326 +msgid "New text node" +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:347 +msgid "Duplicate node" +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:368 +msgid "Delete node" +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:384 +msgid "Unindent node" +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:399 +msgid "Indent node" +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:411 +msgid "Raise node" +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:423 +msgid "Lower node" +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:468 +msgid "Delete attribute" +msgstr "" + +#. TRANSLATORS: "Attribute" is a noun here +#: ../../po/../src/dialogs/xml-tree.cpp:513 +msgid "Attribute name" +msgstr "" + +#. TRANSLATORS: "Set" is a verb here +#: ../../po/../src/dialogs/xml-tree.cpp:533 +msgid "Set attribute" +msgstr "" + +#. TRANSLATORS: "Set" is a verb here +#: ../../po/../src/dialogs/xml-tree.cpp:535 +#, fuzzy +msgid "Set" +msgstr "Избор" + +#. TRANSLATORS: "Attribute" is a noun here +#: ../../po/../src/dialogs/xml-tree.cpp:558 +msgid "Attribute value" +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:1318 +msgid "New element node..." +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:1339 +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:100 +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:98 +#, fuzzy +msgid "Cancel" +msgstr "Откажи" + +#: ../../po/../src/dialogs/xml-tree.cpp:1345 +#, fuzzy +msgid "Create" +msgstr "Создади" + +#: ../../po/../src/dialogs/xml-tree.cpp:1458 +#, c-format +msgid "" +"Cannot set %s: Another element with value %s already exists!" +msgstr "" + +#: ../../po/../src/document.cpp:369 +#, c-format +msgid "New document %d" +msgstr "" + +#: ../../po/../src/document.cpp:401 +#, c-format +msgid "Memory document %d" +msgstr "" + +#: ../../po/../src/document.cpp:524 +#, c-format +msgid "Unnamed document %d" +msgstr "" + +#. We hit green anchor, closing Green-Blue-Red +#: ../../po/../src/draw-context.cpp:441 +msgid "Path is closed." +msgstr "" + +#. We hit bot start and end of single curve, closing paths +#: ../../po/../src/draw-context.cpp:456 +msgid "Closing path." +msgstr "" + +#. alpha of color under cursor, to show in the statusbar +#. locale-sensitive printf is OK, since this goes to the UI, not into SVG +#: ../../po/../src/dropper-context.cpp:354 +#, c-format +msgid " alpha %.3g" +msgstr "" + +#. where the color is picked, to show in the statusbar +#: ../../po/../src/dropper-context.cpp:356 +#, c-format +msgid ", averaged with radius %d" +msgstr "" + +#: ../../po/../src/dropper-context.cpp:356 +msgid " under cursor" +msgstr "" + +#. message, to show in the statusbar +#: ../../po/../src/dropper-context.cpp:358 +msgid "Release mouse to set color." +msgstr "" + +#: ../../po/../src/dropper-context.cpp:358 +#: ../../po/../src/tools-switch.cpp:207 +msgid "" +"Click to set fill, Shift+click to set stroke; drag to " +"average color in area; with Alt to pick inverse color; Ctrl+C " +"to copy the color under mouse to clipboard" +msgstr "" + +#: ../../po/../src/extension/dependency.cpp:244 +msgid "Dependency::" +msgstr "" + +#: ../../po/../src/extension/dependency.cpp:245 +#, fuzzy +msgid " type: " +msgstr "Тип:" + +#: ../../po/../src/extension/dependency.cpp:246 +#, fuzzy +msgid " location: " +msgstr "Избор" + +#: ../../po/../src/extension/dependency.cpp:247 +msgid " string: " +msgstr "" + +#: ../../po/../src/extension/dependency.cpp:250 +#, fuzzy +msgid " description: " +msgstr "Избор" + +#. static int i = 0; +#. std::cout << "Checking module[" << i++ << "]: " << name << std::endl; +#: ../../po/../src/extension/extension.cpp:244 +msgid "" +" This is caused by an improper .inx file for this extension. An improper ." +"inx file could have been caused by a faulty installation of Inkscape." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:247 +msgid "an ID was not defined for it." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:251 +msgid "there was no name defined for it." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:255 +msgid "the XML description of it got lost." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:259 +msgid "no implementation was defined for the extension." +msgstr "" + +#. std::cout << "Failed: " << *(_deps[i]) << std::endl; +#: ../../po/../src/extension/extension.cpp:266 +msgid "a dependency was not met." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:286 +msgid "Extension \"" +msgstr "" + +#: ../../po/../src/extension/extension.cpp:286 +msgid "\" failed to load because " +msgstr "" + +#: ../../po/../src/extension/extension.cpp:565 +#, c-format +msgid "Could not create extension error log file '%s'" +msgstr "" + +#. This is some filler text, needs to change before relase +#: ../../po/../src/extension/error-file.cpp:56 +msgid "" +"One or more extensions failed to load\n" +"\n" +"The failed extensions have been skipped. Inkscape will continue to run " +"normally but those extensions will be unavailable. For details to " +"troubleshoot this problem, please refer to the error log located at: " +msgstr "" + +#. This is some filler text, needs to change before relase +#: ../../po/../src/extension/error-file.cpp:65 +msgid "Show dialog on startup" +msgstr "" + +#: ../../po/../src/extension/implementation/script.cpp:845 +msgid "" +"Inkscape has received an error from the script that it called. The text " +"returned with the error is included below. Inkscape will continue working, " +"but the action you requested has been cancelled." +msgstr "" + +#: ../../po/../src/extension/implementation/script.cpp:858 +msgid "" +"Inkscape has received additional data from the script executed. The script " +"did not return an error, but this may indicate the results will not be as " +"expected." +msgstr "" + +#: ../../po/../src/extension/init.cpp:173 +msgid "Null external module directory name. Modules will not be loaded." +msgstr "" + +#: ../../po/../src/extension/init.cpp:187 +#, c-format +msgid "" +"Modules directory (%s) is unavailable. External modules in that directory " +"will not be loaded." +msgstr "" + +#: ../../po/../src/extension/internal/gnome.cpp:80 +msgid "Select printer" +msgstr "" + +#: ../../po/../src/extension/internal/gnome.cpp:131 +#, fuzzy +msgid "Inkscape: Print Preview" +msgstr "Печати на екран" + +#: ../../po/../src/extension/internal/grid.cpp:213 +#, fuzzy +msgid "Line Width" +msgstr "Ширина:" + +#: ../../po/../src/extension/internal/grid.cpp:214 +#, fuzzy +msgid "Horizontal Spacing" +msgstr "Преврти хоризонтално" + +#: ../../po/../src/extension/internal/grid.cpp:215 +#, fuzzy +msgid "Vertical Spacing" +msgstr "Преврти вертикално" + +#: ../../po/../src/extension/internal/grid.cpp:216 +#, fuzzy +msgid "Horizontal Offset" +msgstr "Преврти хоризонтално" + +#: ../../po/../src/extension/internal/grid.cpp:217 +#, fuzzy +msgid "Vertical Offset" +msgstr "Преврти вертикално" + +#: ../../po/../src/extension/internal/ps.cpp:123 +#, fuzzy +msgid "Print Destination" +msgstr "Ориентација:" + +#. Print properties frame +#: ../../po/../src/extension/internal/ps.cpp:138 +#, fuzzy +msgid "Print properties" +msgstr "Печати на екран" + +#: ../../po/../src/extension/internal/ps.cpp:145 +msgid "Print using PostScript operators" +msgstr "" + +#: ../../po/../src/extension/internal/ps.cpp:147 +msgid "" +"Use PostScript vector operators. The resulting image is usually smaller in " +"file size and can be arbitrarily scaled, but alpha transparency and patterns " +"will be lost." +msgstr "" + +#: ../../po/../src/extension/internal/ps.cpp:152 +msgid "Print as bitmap" +msgstr "" + +#: ../../po/../src/extension/internal/ps.cpp:154 +msgid "" +"Print everything as bitmap. The resulting image is usually larger in file " +"size and cannot be arbitrarily scaled without quality loss, but all objects " +"will be rendered exactly as displayed." +msgstr "" + +#: ../../po/../src/extension/internal/ps.cpp:168 +msgid "Preferred resolution (dots per inch) of bitmap" +msgstr "" + +#: ../../po/../src/extension/internal/ps.cpp:182 +#, fuzzy +msgid "Resolution:" +msgstr "Избор" + +#. Print destination frame +#: ../../po/../src/extension/internal/ps.cpp:186 +msgid "Print destination" +msgstr "" + +#: ../../po/../src/extension/internal/ps.cpp:192 +msgid "" +"Use '> filename' to print to file.\n" +"Use '| prog arg...' to pipe to a program." +msgstr "" + +#: ../../po/../src/extension/internal/ps.cpp:1227 +msgid "write error occurred" +msgstr "" + +#: ../../po/../src/extension/prefdialog.cpp:21 +#, fuzzy +msgid " Preferences" +msgstr "Правоаголник" + +#. We can't call sp_ui_error_dialog because we may be +#. running from the console, in which case calling sp_ui +#. routines will cause a segfault. See bug 1000350 - bryce +#. sp_ui_error_dialog(_("Format autodetect failed. The file is being opened as SVG.")); +#: ../../po/../src/extension/system.cpp:105 +msgid "Format autodetect failed. The file is being opened as SVG." +msgstr "" + +#. TRANSLATORS: default.svg is localizable - this is the name of the default document +#. template. This way you can localize the default pagesize, translate the name of +#. the default layer, etc. If you wish to localize this file, please create a +#. localized share/templates/default.xx.svg file, where xx is your language code. +#: ../../po/../src/file.cpp:133 +#, fuzzy +msgid "default.svg" +msgstr "Номинални" + +#: ../../po/../src/file.cpp:215 ../../po/../src/file.cpp:900 +#, c-format +msgid "Failed to load the requested file %s" +msgstr "" + +#: ../../po/../src/file.cpp:240 +msgid "Document not saved yet. Cannot revert." +msgstr "" + +#: ../../po/../src/file.cpp:246 +#, c-format +msgid "Changes will be lost! Are you sure you want to reload document %s?" +msgstr "" + +#: ../../po/../src/file.cpp:266 +#, fuzzy +msgid "Document reverted." +msgstr "Документ" + +#: ../../po/../src/file.cpp:268 +msgid "Document not reverted." +msgstr "" + +#: ../../po/../src/file.cpp:382 +msgid "Select file to open" +msgstr "" + +#: ../../po/../src/file.cpp:518 +#, c-format +msgid "Removed %i unused definition in <defs>." +msgid_plural "Removed %i unused definitions in <defs>." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/file.cpp:523 +msgid "No unused definitions in <defs>." +msgstr "" + +#: ../../po/../src/file.cpp:548 +#, c-format +msgid "" +"No Inkscape extension found to save document (%s). This may have been " +"caused by an unknown filename extension." +msgstr "" + +#: ../../po/../src/file.cpp:549 ../../po/../src/file.cpp:557 +msgid "Document not saved." +msgstr "" + +#: ../../po/../src/file.cpp:556 +#, c-format +msgid "File %s could not be saved." +msgstr "" + +#: ../../po/../src/file.cpp:566 +#, fuzzy +msgid "Document saved." +msgstr "Документ" + +#: ../../po/../src/file.cpp:614 +#, fuzzy, c-format +msgid "drawing%s" +msgstr "Цртеж" + +#: ../../po/../src/file.cpp:620 +#, fuzzy, c-format +msgid "drawing-%d%s" +msgstr "Цртеж" + +#: ../../po/../src/file.cpp:655 +msgid "Select file to save to" +msgstr "" + +#: ../../po/../src/file.cpp:739 +msgid "No changes need to be saved." +msgstr "" + +#: ../../po/../src/file.cpp:926 +msgid "Select file to import" +msgstr "" + +#: ../../po/../src/gradient-context.cpp:263 +msgid "Ctrl: snap gradient angle" +msgstr "" + +#: ../../po/../src/gradient-context.cpp:264 +msgid "Shift: draw gradient around the starting point" +msgstr "" + +#. We did an undoable action, but sp_document_done will be called by the knot when released +#. status text; we do not track coords because this branch is run once, not all the time +#. during drag +#: ../../po/../src/gradient-context.cpp:462 +#, c-format +msgid "Gradient for %d objects; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/gradient-context.cpp:464 +msgid "Select objects on which to create gradient." +msgstr "" + +#: ../../po/../src/gradient-drag.cpp:65 +msgid "Linear gradient start" +msgstr "" + +#. POINT_LG_P1 +#: ../../po/../src/gradient-drag.cpp:66 +msgid "Linear gradient end" +msgstr "" + +#: ../../po/../src/gradient-drag.cpp:67 +msgid "Radial gradient center" +msgstr "" + +#: ../../po/../src/gradient-drag.cpp:68 ../../po/../src/gradient-drag.cpp:69 +msgid "Radial gradient radius" +msgstr "" + +#: ../../po/../src/gradient-drag.cpp:70 +msgid "Radial gradient focus" +msgstr "" + +#: ../../po/../src/gradient-drag.cpp:659 +#, c-format +msgid "" +"%s for: %s%s; drag with Ctrl to snap angle, with Ctrl+Alt to " +"preserve angle, with Ctrl+Shift to scale around center" +msgstr "" + +#: ../../po/../src/gradient-drag.cpp:662 +msgid " (stroke)" +msgstr "" + +#: ../../po/../src/gradient-drag.cpp:665 +msgid "" +"Radial gradient center and focus; drag with Shift to " +"separate focus" +msgstr "" + +#: ../../po/../src/gradient-drag.cpp:667 +#, c-format +msgid "" +"Gradient point shared by %d gradients; drag with Shift to " +"separate" +msgstr "" + +#: ../../po/../src/helper/units.cpp:40 +#, fuzzy +msgid "Unit" +msgstr "Единица" + +#: ../../po/../src/helper/units.cpp:40 +#, fuzzy +msgid "Units" +msgstr "Единици" + +#: ../../po/../src/helper/units.cpp:41 +#, fuzzy +msgid "Point" +msgstr "Точка" + +#: ../../po/../src/helper/units.cpp:41 +msgid "pt" +msgstr "" + +#: ../../po/../src/helper/units.cpp:41 +#, fuzzy +msgid "Points" +msgstr "Точки" + +#: ../../po/../src/helper/units.cpp:41 +#, fuzzy +msgid "Pt" +msgstr "Pt" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Pixel" +msgstr "" + +#: ../../po/../src/helper/units.cpp:42 +#, fuzzy +msgid "Pixels" +msgstr "Пиксели" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Px" +msgstr "" + +#. You can add new elements from this point forward +#: ../../po/../src/helper/units.cpp:44 ../share/extensions/straightseg.inx.h:2 +#, fuzzy +msgid "Percent" +msgstr "Процент" + +#: ../../po/../src/helper/units.cpp:44 +msgid "Percents" +msgstr "" + +#: ../../po/../src/helper/units.cpp:45 +#, fuzzy +msgid "Millimeter" +msgstr "Милиметар" + +#: ../../po/../src/helper/units.cpp:45 +#, fuzzy +msgid "mm" +msgstr "mm" + +#: ../../po/../src/helper/units.cpp:45 +#, fuzzy +msgid "Millimeters" +msgstr "Милиметри" + +#: ../../po/../src/helper/units.cpp:46 +#, fuzzy +msgid "Centimeter" +msgstr "Сантиметар" + +#: ../../po/../src/helper/units.cpp:46 +#, fuzzy +msgid "cm" +msgstr "см" + +#: ../../po/../src/helper/units.cpp:46 +#, fuzzy +msgid "Centimeters" +msgstr "Сантиметри" + +#: ../../po/../src/helper/units.cpp:47 +#, fuzzy +msgid "Meter" +msgstr "Метар" + +#: ../../po/../src/helper/units.cpp:47 +#, fuzzy +msgid "m" +msgstr "м" + +#: ../../po/../src/helper/units.cpp:47 +#, fuzzy +msgid "Meters" +msgstr "Метар" + +#. no svg_unit +#: ../../po/../src/helper/units.cpp:48 +#, fuzzy +msgid "Inch" +msgstr "Инч" + +#: ../../po/../src/helper/units.cpp:48 +#, fuzzy +msgid "in" +msgstr "во" + +#: ../../po/../src/helper/units.cpp:48 +#, fuzzy +msgid "Inches" +msgstr "Инчи" + +#. Volatiles do not have default, so there are none here +#. TRANSLATORS: for info, see http://www.w3.org/TR/REC-CSS2/syndata.html#length-units +#: ../../po/../src/helper/units.cpp:51 +msgid "Em square" +msgstr "" + +#: ../../po/../src/helper/units.cpp:51 +msgid "em" +msgstr "" + +#: ../../po/../src/helper/units.cpp:51 +msgid "Em squares" +msgstr "" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/REC-CSS2/syndata.html#length-units +#: ../../po/../src/helper/units.cpp:53 +msgid "Ex square" +msgstr "" + +#: ../../po/../src/helper/units.cpp:53 +msgid "ex" +msgstr "" + +#: ../../po/../src/helper/units.cpp:53 +msgid "Ex squares" +msgstr "" + +#: ../../po/../src/inkscape.cpp:468 +msgid "Untitled document" +msgstr "" + +#. Show nice dialog box +#: ../../po/../src/inkscape.cpp:497 +msgid "Inkscape encountered an internal error and will close now.\n" +msgstr "" + +#: ../../po/../src/inkscape.cpp:498 +msgid "" +"Automatic backups of unsaved documents were done to the following " +"locations:\n" +msgstr "" + +#: ../../po/../src/inkscape.cpp:499 +msgid "Automatic backup of the following documents failed:\n" +msgstr "" + +#: ../../po/../src/inkscape.cpp:634 +#, c-format +msgid "" +"Cannot create directory %s.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:635 +#, c-format +msgid "" +"%s is not a valid directory.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:636 +#, c-format +msgid "" +"Cannot create file %s.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:637 +#, c-format +msgid "" +"Cannot write file %s.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:638 +msgid "" +"Although Inkscape will run, it will use default settings,\n" +"and any changes made in preferences will not be saved." +msgstr "" + +#: ../../po/../src/inkscape.cpp:708 +#, c-format +msgid "" +"%s is not a regular file.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:709 +#, c-format +msgid "" +"%s not a valid XML file, or\n" +"you don't have read permissions on it.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:711 +#, c-format +msgid "" +"%s is not a valid menus file.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:712 +msgid "" +"Inkscape will run with default menus.\n" +"New menus will not be saved." +msgstr "" + +#. sp_ui_menu_append_check_item_from_verb(m, view, _("_Menu"), _("Show or hide the menu bar"), "menu", +#. checkitem_toggled, checkitem_update, 0); +#: ../../po/../src/interface.cpp:753 +msgid "Commands Bar" +msgstr "" + +#: ../../po/../src/interface.cpp:753 +msgid "Show or hide the Commands bar (under the menu)" +msgstr "" + +#: ../../po/../src/interface.cpp:755 +msgid "Tool Controls" +msgstr "" + +#: ../../po/../src/interface.cpp:755 +msgid "Show or hide the Tool Controls panel" +msgstr "" + +#: ../../po/../src/interface.cpp:757 +msgid "_Toolbox" +msgstr "" + +#: ../../po/../src/interface.cpp:757 +msgid "Show or hide the main toolbox (on the left)" +msgstr "" + +#: ../../po/../src/interface.cpp:763 +msgid "_Statusbar" +msgstr "" + +#: ../../po/../src/interface.cpp:763 +msgid "Show or hide the statusbar (at the bottom of the window)" +msgstr "" + +#: ../../po/../src/interface.cpp:820 +#, c-format +msgid "Verb \"%s\" Unknown" +msgstr "" + +#. TRANSLATORS: #%s is the id of the group e.g. , not a number. +#: ../../po/../src/interface.cpp:930 +#, fuzzy, c-format +msgid "Enter group #%s" +msgstr "Уреди" + +#: ../../po/../src/interface.cpp:941 +msgid "Go to parent" +msgstr "" + +#: ../../po/../src/interface.cpp:972 +msgid "Could not parse SVG data" +msgstr "" + +#: ../../po/../src/interface.cpp:1135 +#, c-format +msgid "Overwrite %s" +msgstr "" + +#: ../../po/../src/interface.cpp:1153 +#, c-format +msgid "" +"The file %s already exists. Do you want to overwrite that file with the " +"current document?" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:59 +msgid "Jabber connection lost." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:72 +#, c-format +msgid "Sending message; %u message remaining in send queue." +msgid_plural "Sending message; %u messages remaining in send queue." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:78 +msgid "Receive queue empty." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:154 +#, c-format +msgid "Receiving change; %u change left to process." +msgid_plural "Receiving change; %u changes left to process." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:157 +#, c-format +msgid "%s has left the chatroom." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:221 +msgid "Nickname %1 is already in use. Please choose a different nickname." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:225 +msgid "An error was encountered while attempting to connect to the server." +msgstr "" + +#. Check to see if the user made any modifications to this document. If so, +#. we want to give them the option of (1) letting us clear their document or (2) +#. opening a new, blank document for the whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:131 +msgid "%1 has invited you to a whiteboard session." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:132 +msgid "Incoming whiteboard invitation from %1" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:135 +msgid "Do you wish to accept %1's whiteboard session invitation?" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:137 +msgid "" +"Would you like to accept %1's invitation in a new document window?\n" +"Accepting the invitation in your current window will discard unsaved changes." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:143 +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:198 +#, fuzzy +msgid "Accept invitation" +msgstr "Избор" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:144 +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:199 +msgid "Decline invitation" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:145 +#, fuzzy +msgid "Accept invitation in new document window" +msgstr "Зачувај документ" + +#. We could not create a new desktop; ask the user if she or he wants to +#. replace the current document and accept the invitation, or reject the invitation. +#. TRANSLATORS: %1 is a userid here +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:196 +msgid "" +"A new document window could not be opened for a whiteboard session with %" +"1" +msgstr "" + +#. TRANSLATORS: %1 is the peer whom refused our invitation. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:238 +msgid "" +"The user %1 has refused your " +"whiteboard invitation.\n" +"\n" +msgstr "" + +#. TRANSLATORS: %1 is the peer whom refused our invitation, %2 is our Jabber identity. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:241 +msgid "" +"You are still connected to a Jabber server as %2, and may send an " +"invitation to %1 again, or you may send an invitation to a different " +"user." +msgstr "" + +#. TRANSLATORS: %1 is the peer whom we tried to contact, but is already in a whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:252 +msgid "" +"The user %1 is already in a " +"whiteboard session.\n" +"\n" +msgstr "" + +#. TRANSLATORS: %1 is the peer whom we tried to contact, but is already in a whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:255 +msgid "" +"You are still connected to a Jabber server as %1, and may send an " +"invitation to a different user." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/invitation-confirm-dialog.cpp:26 +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:24 +msgid "_Write session file:" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/message-processors.cpp:145 +#, c-format +msgid "%s has joined the chatroom." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/message-queue.cpp:87 +#, c-format +msgid "%u change in receive queue." +msgid_plural "%u changes in receive queue." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/jabber_whiteboard/message-queue.cpp:117 +#, c-format +msgid "%u change in send queue." +msgid_plural "%u changes in send queue." +msgstr[0] "" +msgstr[1] "" + +#. if ID is NULL, then we have a real problem -- we were not able to find a key +#. nor generate one. The only thing we can really do here is abort, since we have +#. no way to let the other client(s) uniquely identify this object. +#. FIXME: If this indicates a programming bug, then don't request translation with +#. * _(...): it is most useful in untranslated form so that developers may search for +#. * it when someone reports it in a bug report (as we want users to do for all bugs, +#. * as indicated by it being a g_warning string). +#. * +#. * Otherwise, if it is not a programming bug but a network error or a bug in the +#. * remote peer (perhaps running different software) or whatever, then present it in +#. * an alert box, and avoid use of technical jargon `NULL'. +#. +#: ../../po/../src/jabber_whiteboard/message-utilities.cpp:171 +msgid "" +"ID for new object is NULL even after generation and lookup attempts: the new " +"object will NOT be sent, nor will any of its child objects!" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:60 +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:995 +msgid "Select a location and filename" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:62 +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:997 +#, fuzzy +msgid "Set filename" +msgstr "Датотека" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:301 +msgid "No SSL certificate was found." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:304 +msgid "The SSL certificate provided by the Jabber server is untrusted." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:307 +msgid "The SSL certificate provided by the Jabber server is expired." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:310 +msgid "" +"The SSL certificate provided by the Jabber server has not been activated." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:313 +msgid "" +"The SSL certificate provided by the Jabber server contains a hostname that " +"does not match the Jabber server's hostname." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:316 +msgid "" +"The SSL certificate provided by the Jabber server contains an invalid " +"fingerprint." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:319 +msgid "An unknown error occurred while setting up the SSL connection." +msgstr "" + +#. TRANSLATORS: %1 is the message that describes the specific error that occurred when +#. establishing the SSL connection. +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:325 +msgid "" +"%1\n" +"\n" +"Do you wish to continue connecting to the Jabber server?" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:328 +msgid "Continue connecting and ignore further errors" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:329 +msgid "Continue connecting, but warn me of further errors" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:330 +#, fuzzy +msgid "Cancel connection" +msgstr "Избор" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:777 +#, c-format +msgid "Established whiteboard session with %s." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:785 +#, c-format +msgid "%s has left the whiteboard session." +msgstr "" + +#. Inform the user +#. TRANSLATORS: %1 is the name of the user that disconnected, %2 is the name of the user whom the disconnected user disconnected from. +#. This message is not used in a chatroom context. +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:790 +msgid "" +"The user %1 has left the " +"whiteboard session.\n" +"\n" +msgstr "" + +#. TRANSLATORS: %1 and %2 are userids +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:792 +msgid "" +"You are still connected to a Jabber server as %2, and may establish a " +"new session to %1 or a different user." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:988 +msgid "" +"Could not open file %1 for session recording.\n" +"The error encountered was: %2.\n" +"\n" +"You may select a different location to record the session, or you may opt to " +"not record this session." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:990 +msgid "Choose a different location" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:991 +msgid "Skip session recording" +msgstr "" + +#: ../../po/../src/knot.cpp:673 +msgid "Node or handle drag canceled." +msgstr "" + +#: ../../po/../src/libnrtype/FontFactory.cpp:358 +msgid "Ignoring font without family that will crash Pango" +msgstr "" + +#: ../../po/../src/main.cpp:395 +msgid "Print the Inkscape version number" +msgstr "" + +#: ../../po/../src/main.cpp:400 +msgid "Do not use X server (only process files from console)" +msgstr "" + +#: ../../po/../src/main.cpp:405 +msgid "Try to use X server (even if $DISPLAY is not set)" +msgstr "" + +#: ../../po/../src/main.cpp:410 +msgid "Open specified document(s) (option string may be excluded)" +msgstr "" + +#: ../../po/../src/main.cpp:411 ../../po/../src/main.cpp:416 +#: ../../po/../src/main.cpp:421 ../../po/../src/main.cpp:483 +#: ../../po/../src/main.cpp:488 ../../po/../src/main.cpp:493 +#, fuzzy +msgid "FILENAME" +msgstr "ИМЕ НА ДАТОТЕКА" + +#: ../../po/../src/main.cpp:415 +msgid "Print document(s) to specified output file (use '| program' for pipe)" +msgstr "" + +#: ../../po/../src/main.cpp:420 +msgid "Export document to a PNG file" +msgstr "" + +#: ../../po/../src/main.cpp:425 +msgid "The resolution used for exporting SVG into bitmap (default 90)" +msgstr "" + +#: ../../po/../src/main.cpp:426 +#, fuzzy +msgid "DPI" +msgstr "DPI" + +#: ../../po/../src/main.cpp:430 +msgid "" +"Exported area in SVG user units (default is the canvas; 0,0 is lower-left " +"corner)" +msgstr "" + +#: ../../po/../src/main.cpp:431 +msgid "x0:y0:x1:y1" +msgstr "" + +#: ../../po/../src/main.cpp:435 +msgid "Exported area is the entire drawing (not canvas)" +msgstr "" + +#: ../../po/../src/main.cpp:440 +msgid "" +"Snap the bitmap export area outwards to the nearest integer values (in SVG " +"user units)" +msgstr "" + +#: ../../po/../src/main.cpp:445 +msgid "The width of exported bitmap in pixels (overrides export-dpi)" +msgstr "" + +#: ../../po/../src/main.cpp:446 +msgid "WIDTH" +msgstr "" + +#: ../../po/../src/main.cpp:450 +msgid "The height of exported bitmap in pixels (overrides export-dpi)" +msgstr "" + +#: ../../po/../src/main.cpp:451 +msgid "HEIGHT" +msgstr "" + +#: ../../po/../src/main.cpp:455 +msgid "The ID of the object to export (overrides export-area)" +msgstr "" + +#: ../../po/../src/main.cpp:456 ../../po/../src/main.cpp:532 +msgid "ID" +msgstr "" + +#. TRANSLATORS: this means: "Only export the object whose id is given in --export-id". +#. See "man inkscape" for details. +#: ../../po/../src/main.cpp:462 +msgid "" +"Export just the object with export-id, hide all others (only with export-id)" +msgstr "" + +#: ../../po/../src/main.cpp:467 +msgid "Use stored filename and DPI hints when exporting (only with export-id)" +msgstr "" + +#: ../../po/../src/main.cpp:472 +msgid "Background color of exported bitmap (any SVG-supported color string)" +msgstr "" + +#: ../../po/../src/main.cpp:473 +msgid "COLOR" +msgstr "" + +#: ../../po/../src/main.cpp:477 +msgid "Background opacity of exported bitmap (either 0.0 to 1.0, or 1 to 255)" +msgstr "" + +#: ../../po/../src/main.cpp:478 +msgid "VALUE" +msgstr "" + +#: ../../po/../src/main.cpp:482 +msgid "Export document to plain SVG file (no sodipodi or inkscape namespaces)" +msgstr "" + +#: ../../po/../src/main.cpp:487 +msgid "Export document to a PS file" +msgstr "" + +#: ../../po/../src/main.cpp:492 +msgid "Export document to an EPS file" +msgstr "" + +#: ../../po/../src/main.cpp:497 +msgid "Convert text object to paths on export (EPS)" +msgstr "" + +#: ../../po/../src/main.cpp:502 +msgid "Export files with the bounding box set to the page size (EPS)" +msgstr "" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:508 +msgid "" +"Query the X coordinate of the drawing or, if specified, of the object with --" +"query-id" +msgstr "" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:514 +msgid "" +"Query the Y coordinate of the drawing or, if specified, of the object with --" +"query-id" +msgstr "" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:520 +msgid "" +"Query the width of the drawing or, if specified, of the object with --query-" +"id" +msgstr "" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:526 +msgid "" +"Query the height of the drawing or, if specified, of the object with --query-" +"id" +msgstr "" + +#: ../../po/../src/main.cpp:531 +msgid "The ID of the object whose dimensions are queried" +msgstr "" + +#. TRANSLATORS: this option makes Inkscape print the name (path) of the extension directory +#: ../../po/../src/main.cpp:537 +msgid "Print out the extension directory and exit" +msgstr "" + +#: ../../po/../src/main.cpp:542 +msgid "Show given files one-by-one, switch to next on any key/mouse event" +msgstr "" + +#: ../../po/../src/main.cpp:547 +msgid "Use the new Gtkmm GUI interface" +msgstr "" + +#: ../../po/../src/main.cpp:552 +msgid "Remove unused definitions from the defs section(s) of the document" +msgstr "" + +#: ../../po/../src/main.cpp:741 +msgid "" +"[OPTIONS...] [FILE...]\n" +"\n" +"Available options:" +msgstr "" + +#: ../../po/../src/menus-skeleton.h:17 +#, fuzzy +msgid "_New" +msgstr "Ново" + +#: ../../po/../src/menus-skeleton.h:22 +#, fuzzy +msgid "Open _Recent" +msgstr "Отвори" + +#: ../../po/../src/menus-skeleton.h:53 +#, fuzzy +msgid "_Edit" +msgstr "Уреди" + +#: ../../po/../src/menus-skeleton.h:84 +#, fuzzy +msgid "_View" +msgstr "Преглед" + +#: ../../po/../src/menus-skeleton.h:85 +#, fuzzy +msgid "_Zoom" +msgstr "Зум" + +#: ../../po/../src/menus-skeleton.h:102 +#, fuzzy +msgid "Show/Hide" +msgstr "Водичи" + +#: ../../po/../src/menus-skeleton.h:107 +#, fuzzy +msgid "_Display mode" +msgstr "Прикажи" + +#: ../../po/../src/menus-skeleton.h:126 +#, fuzzy +msgid "_Layer" +msgstr "Долни" + +#: ../../po/../src/menus-skeleton.h:143 +#, fuzzy +msgid "_Object" +msgstr "Објект" + +#: ../../po/../src/menus-skeleton.h:165 +#, fuzzy +msgid "_Path" +msgstr "Вметни" + +#: ../../po/../src/menus-skeleton.h:188 +#, fuzzy +msgid "_Text" +msgstr "Текст" + +#: ../../po/../src/menus-skeleton.h:200 +#, fuzzy +msgid "Effects" +msgstr "Објект" + +#: ../../po/../src/menus-skeleton.h:207 +msgid "Whiteboa_rd" +msgstr "" + +#: ../../po/../src/menus-skeleton.h:220 +#, fuzzy +msgid "_Help" +msgstr "Водичи" + +#: ../../po/../src/menus-skeleton.h:222 +msgid "Tutorials" +msgstr "" + +#: ../../po/../src/node-context.cpp:382 +msgid "" +"Ctrl: toggle node type, snap handle angle, move hor/vert; Ctrl" +"+Alt: move along handles" +msgstr "" + +#: ../../po/../src/node-context.cpp:383 +msgid "" +"Shift: toggle node selection, disable snapping, rotate both handles" +msgstr "" + +#: ../../po/../src/node-context.cpp:384 +msgid "Alt: lock handle length; Ctrl+Alt: move along handles" +msgstr "" + +#: ../../po/../src/nodepath.cpp:1399 ../../po/../src/nodepath.cpp:1411 +#: ../../po/../src/nodepath.cpp:1492 ../../po/../src/nodepath.cpp:1504 +msgid "To join, you must have two endnodes selected." +msgstr "" + +#: ../../po/../src/nodepath.cpp:1633 ../../po/../src/nodepath.cpp:1647 +msgid "" +"Select two non-endpoint nodes on a path between which to delete " +"segments." +msgstr "" + +#: ../../po/../src/nodepath.cpp:1743 +msgid "Cannot find path between nodes." +msgstr "" + +#: ../../po/../src/nodepath.cpp:2822 +#, c-format +msgid "" +"Node handle: angle %0.2f°, length %s; with Ctrl to snap " +"angle; with Alt to lock length; with Shift to rotate both " +"handles" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3351 +msgid "" +"Node: drag to edit the path; with Ctrl to snap to horizontal/" +"vertical; with Ctrl+Alt to snap to handles' directions" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3375 +msgid "" +"Node handle: drag to shape the curve; with Ctrl to snap angle; " +"with Alt to lock length; with Shift to rotate both handles" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3399 +msgid "" +"Node handle: drag to shape the curve; with Ctrl to snap angle; " +"with Alt to lock length; with Shift to rotate the opposite " +"handle in sync" +msgstr "" + +#. TRANSLATORS: "end" is an adjective here (NOT a verb) +#: ../../po/../src/nodepath.cpp:3591 +msgid "end node" +msgstr "" + +#. TRANSLATORS: "cusp" means "sharp" (cusp node); see also the Advanced Tutorial +#: ../../po/../src/nodepath.cpp:3596 +msgid "cusp" +msgstr "" + +#. TRANSLATORS: "smooth" is an adjective here +#: ../../po/../src/nodepath.cpp:3599 +msgid "smooth" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3601 +msgid "symmetric" +msgstr "" + +#. TRANSLATORS: "end" is an adjective here (NOT a verb) +#: ../../po/../src/nodepath.cpp:3607 +msgid "end node, handle retracted (drag with Shift to extend)" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3609 +msgid "one handle retracted (drag with Shift to extend)" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3612 +msgid "both handles retracted (drag with Shift to extend)" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3624 +msgid "Drag nodes or node handles; arrow keys to move nodes" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3625 +msgid "Drag the node or its handles; arrow keys to move the node" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3651 ../../po/../src/nodepath.cpp:3663 +msgid "Select a single object to edit its nodes or handles." +msgstr "" + +#: ../../po/../src/nodepath.cpp:3655 +#, c-format +msgid "" +"0 out of %i node selected. Click, Shift+click, " +"or drag around nodes to select." +msgid_plural "" +"0 out of %i nodes selected. Click, Shift+click, " +"or drag around nodes to select." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/nodepath.cpp:3661 +msgid "Drag the handles of the object to modify it." +msgstr "" + +#: ../../po/../src/nodepath.cpp:3669 +#, c-format +msgid "%i of %i node selected; %s. %s." +msgid_plural "%i of %i nodes selected; %s. %s." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/nodepath.cpp:3675 +#, c-format +msgid "%i of %i node selected. %s." +msgid_plural "%i of %i nodes selected. %s." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/object-edit.cpp:493 +msgid "" +"Adjust the horizontal rounding radius; with Ctrl to make the " +"vertical radius the same" +msgstr "" + +#: ../../po/../src/object-edit.cpp:499 +msgid "" +"Adjust the vertical rounding radius; with Ctrl to make the " +"horizontal radius the same" +msgstr "" + +#: ../../po/../src/object-edit.cpp:506 ../../po/../src/object-edit.cpp:513 +msgid "" +"Adjust the width and height of the rectangle; with Ctrl to " +"lock ratio or stretch in one dimension only" +msgstr "" + +#: ../../po/../src/object-edit.cpp:686 +msgid "Adjust ellipse width, with Ctrl to make circle" +msgstr "" + +#: ../../po/../src/object-edit.cpp:689 +msgid "Adjust ellipse height, with Ctrl to make circle" +msgstr "" + +#: ../../po/../src/object-edit.cpp:692 +msgid "" +"Position the start point of the arc or segment; with Ctrl to " +"snap angle; drag inside the ellipse for arc, outside for " +"segment" +msgstr "" + +#: ../../po/../src/object-edit.cpp:695 +msgid "" +"Position the end point of the arc or segment; with Ctrl to " +"snap angle; drag inside the ellipse for arc, outside for " +"segment" +msgstr "" + +#: ../../po/../src/object-edit.cpp:800 +msgid "" +"Adjust the tip radius of the star or polygon; with Shift to " +"round; with Alt to randomize" +msgstr "" + +#: ../../po/../src/object-edit.cpp:803 +msgid "" +"Adjust the base radius of the star; with Ctrl to keep star " +"rays radial (no skew); with Shift to round; with Alt to " +"randomize" +msgstr "" + +#: ../../po/../src/object-edit.cpp:967 +msgid "" +"Roll/unroll the spiral from inside; with Ctrl to snap angle; " +"with Alt to converge/diverge" +msgstr "" + +#: ../../po/../src/object-edit.cpp:969 +msgid "" +"Roll/unroll the spiral from outside; with Ctrl to snap angle; " +"with Shift to scale/rotate" +msgstr "" + +#: ../../po/../src/object-edit.cpp:1006 +msgid "Adjust the offset distance" +msgstr "" + +#. TRANSLATORS: This refers to the pattern that's inside the object +#: ../../po/../src/object-edit.cpp:1036 +msgid "Move the pattern fill inside the object" +msgstr "" + +#: ../../po/../src/object-edit.cpp:1038 +msgid "Scale the pattern fill uniformly" +msgstr "" + +#: ../../po/../src/object-edit.cpp:1040 +msgid "Rotate the pattern fill; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/object-edit.cpp:1065 +msgid "Drag to resize the flowed text frame" +msgstr "" + +#. Item dialog +#: ../../po/../src/object-ui.cpp:106 +#, fuzzy +msgid "Object _Properties" +msgstr "Правоаголник" + +#. Select item +#: ../../po/../src/object-ui.cpp:116 +#, fuzzy +msgid "_Select This" +msgstr "Избор" + +#. Create link +#: ../../po/../src/object-ui.cpp:126 +#, fuzzy +msgid "_Create Link" +msgstr "Создади" + +#. "Ungroup" +#: ../../po/../src/object-ui.cpp:199 ../../po/../src/verbs.cpp:1931 +#, fuzzy +msgid "_Ungroup" +msgstr "Одгрупирај" + +#. Link dialog +#: ../../po/../src/object-ui.cpp:239 +msgid "Link _Properties" +msgstr "" + +#. Select item +#: ../../po/../src/object-ui.cpp:249 +msgid "_Follow Link" +msgstr "" + +#. Reset transformations +#: ../../po/../src/object-ui.cpp:254 +msgid "_Remove Link" +msgstr "" + +#. Link dialog +#: ../../po/../src/object-ui.cpp:303 +msgid "Image _Properties" +msgstr "" + +#. Item dialog +#: ../../po/../src/object-ui.cpp:344 +msgid "_Fill and Stroke" +msgstr "" + +#: ../../po/../src/path-chemistry.cpp:58 +msgid "Select at least two objects to combine." +msgstr "" + +#: ../../po/../src/path-chemistry.cpp:65 +msgid "At least one of the objects is not a path, cannot combine." +msgstr "" + +#: ../../po/../src/path-chemistry.cpp:73 +msgid "" +"You cannot combine objects from different groups or layers." +msgstr "" + +#: ../../po/../src/path-chemistry.cpp:155 +msgid "Select path(s) to break apart." +msgstr "" + +#: ../../po/../src/path-chemistry.cpp:231 +msgid "No path(s) to break apart in the selection." +msgstr "" + +#: ../../po/../src/path-chemistry.cpp:252 +msgid "Select object(s) to convert to path." +msgstr "" + +#: ../../po/../src/path-chemistry.cpp:297 +msgid "No objects to convert to path in the selection." +msgstr "" + +#: ../../po/../src/path-chemistry.cpp:345 +msgid "Select path(s) to reverse." +msgstr "" + +#: ../../po/../src/path-chemistry.cpp:370 +msgid "No paths to reverse in the selection." +msgstr "" + +#: ../../po/../src/pen-context.cpp:379 ../../po/../src/pencil-context.cpp:233 +#, fuzzy +msgid "Continuing selected path" +msgstr "Избор" + +#: ../../po/../src/pen-context.cpp:390 ../../po/../src/pencil-context.cpp:242 +#, fuzzy +msgid "Creating new path" +msgstr "Зачувај документ" + +#: ../../po/../src/pen-context.cpp:394 ../../po/../src/pencil-context.cpp:246 +msgid "Appending to selected path" +msgstr "" + +#: ../../po/../src/pen-context.cpp:538 +msgid "Click or click and drag to close and finish the path." +msgstr "" + +#: ../../po/../src/pen-context.cpp:548 +msgid "" +"Click or click and drag to continue the path from this point." +msgstr "" + +#: ../../po/../src/pen-context.cpp:857 +#, c-format +msgid "" +"%s: angle %3.2f°, distance %s; with Ctrl to snap angle, " +"Enter to finish the path" +msgstr "" + +#: ../../po/../src/pen-context.cpp:882 +#, c-format +msgid "" +"Curve handle: angle %3.2f°, length %s; with Ctrl to snap " +"angle" +msgstr "" + +#: ../../po/../src/pen-context.cpp:912 +#, c-format +msgid "" +"%s: angle %3.2f°, length %s; with Ctrl to snap angle, " +"with Shift to move this handle only" +msgstr "" + +#: ../../po/../src/pen-context.cpp:946 +msgid "Finishing pen" +msgstr "" + +#: ../../po/../src/pencil-context.cpp:320 +msgid "Release here to close and finish the path." +msgstr "" + +#: ../../po/../src/pencil-context.cpp:326 +#, fuzzy +msgid "Drawing a freehand path" +msgstr "Зачувај документ" + +#: ../../po/../src/pencil-context.cpp:331 +msgid "Drag to continue the path from this point." +msgstr "" + +#. Write curves to object +#: ../../po/../src/pencil-context.cpp:390 +msgid "Finishing freehand" +msgstr "" + +#: ../../po/../src/rect-context.cpp:387 +msgid "" +"Ctrl: make square or integer-ratio rect, lock a rounded corner " +"circular" +msgstr "" + +#: ../../po/../src/rect-context.cpp:549 +#, c-format +msgid "" +"Rectangle: %s × %s; with Ctrl to make square or integer-" +"ratio rectangle; with Shift to draw around the starting point" +msgstr "" + +#: ../../po/../src/select-context.cpp:243 +#, fuzzy +msgid "Move canceled." +msgstr "Избор" + +#: ../../po/../src/select-context.cpp:252 +#, fuzzy +msgid "Selection canceled." +msgstr "Избор" + +#: ../../po/../src/select-context.cpp:642 +msgid "Ctrl: select in groups, move hor/vert" +msgstr "" + +#: ../../po/../src/select-context.cpp:643 +msgid "Shift: toggle select, force rubberband, disable snapping" +msgstr "" + +#: ../../po/../src/select-context.cpp:644 +msgid "Alt: select under, move selected" +msgstr "" + +#: ../../po/../src/select-context.cpp:798 +msgid "Selected object is not a group. Cannot enter." +msgstr "" + +#: ../../po/../src/select-context.cpp:876 +#, c-format +msgid "" +"Move by %s, %s; with Ctrl to restrict to horizontal/vertical; " +"with Shift to disable snapping" +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:228 +msgid "Nothing was deleted." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:259 +msgid "Select object(s) to duplicate." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:420 +msgid "Select two or more objects to group." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:428 +msgid "Select at least two objects to group." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:513 +msgid "Select a group to ungroup." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:554 +msgid "No groups to ungroup in the selection." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:623 +msgid "Select objects to raise." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:629 +#: ../../po/../src/selection-chemistry.cpp:681 +#: ../../po/../src/selection-chemistry.cpp:715 +#: ../../po/../src/selection-chemistry.cpp:773 +msgid "" +"You cannot raise/lower objects from different groups or layers." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:673 +msgid "Select object(s) to raise to top." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:709 +msgid "Select object(s) to lower." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:765 +msgid "Select object(s) to lower to bottom." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:806 +msgid "Nothing to undo." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:813 +#, fuzzy +msgid "Nothing to redo." +msgstr "Донеси Напред" + +#: ../../po/../src/selection-chemistry.cpp:969 +msgid "Nothing was copied." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1051 +msgid "Current layer is hidden. Unhide it to be able to paste to it." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1055 +msgid "Current layer is locked. Unlock it to be able to paste to it." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1068 +#: ../../po/../src/selection-chemistry.cpp:1103 +#, fuzzy +msgid "Nothing on the clipboard." +msgstr "Донеси Напред" + +#: ../../po/../src/selection-chemistry.cpp:1109 +msgid "Select object(s) to paste style to." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1128 +msgid "Select object(s) to move to the layer above." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1146 +#, fuzzy +msgid "No more layers above." +msgstr "Документ" + +#: ../../po/../src/selection-chemistry.cpp:1160 +msgid "Select object(s) to move to the layer below." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1178 +#, fuzzy +msgid "No more layers below." +msgstr "Документ" + +#: ../../po/../src/selection-chemistry.cpp:1811 +msgid "Select a clone to unlink." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1842 +msgid "No clones to unlink in the selection." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1859 +msgid "" +"Select a clone to go to its original. Select a linked offset " +"to go to its source. Select a text on path to go to the path. Select " +"a flowed text to go to its frame." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1882 +msgid "" +"Cannot find the object to select (orphaned clone, offset, textpath, " +"flowed text?)" +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1888 +msgid "" +"The object you're trying to select is not visible (it is in <" +"defs>)" +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1915 +msgid "Select object(s) to convert to pattern." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:2006 +msgid "Select an object with pattern fill to extract objects from." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:2059 +msgid "No pattern fills in the selection." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:2079 +msgid "Select object(s) to make a bitmap copy." +msgstr "" + +#: ../../po/../src/selection-describer.cpp:37 +msgid "Click selection to toggle scale/rotation handles" +msgstr "" + +#. no items +#: ../../po/../src/selection-describer.cpp:39 +msgid "" +"No objects selected. Click, Shift+click, or drag around objects to select." +msgstr "" + +#: ../../po/../src/selection-describer.cpp:51 +#, c-format +msgid " in layer %s" +msgstr "" + +#: ../../po/../src/selection-describer.cpp:54 +#, c-format +msgid " in layer %s" +msgstr "" + +#: ../../po/../src/selection-describer.cpp:66 +msgid "Use Shift+D to look up original" +msgstr "" + +#: ../../po/../src/selection-describer.cpp:70 +msgid "Use Shift+D to look up path" +msgstr "" + +#: ../../po/../src/selection-describer.cpp:74 +msgid "Use Shift+D to look up frame" +msgstr "" + +#: ../../po/../src/selection-describer.cpp:84 +#, c-format +msgid "%i object selected" +msgid_plural "%i objects selected" +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/selection-describer.cpp:90 +#, c-format +msgid "%s%s. %s." +msgstr "" + +#: ../../po/../src/selection-describer.cpp:94 +#, c-format +msgid "%s in %i layer. %s." +msgid_plural "%s in %i layers. %s." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/seltrans.cpp:498 +msgid "" +"Center of rotation and skewing: drag to reposition; scaling with " +"Shift also uses this center" +msgstr "" + +#: ../../po/../src/seltrans.cpp:514 +msgid "" +"Squeeze or stretch selection; with Ctrl to scale uniformly; " +"with Shift to scale around rotation center" +msgstr "" + +#: ../../po/../src/seltrans.cpp:515 +msgid "" +"Scale selection; with Ctrl to scale uniformly; with Shift to scale around rotation center" +msgstr "" + +#: ../../po/../src/seltrans.cpp:519 +msgid "" +"Skew selection; with Ctrl to snap angle; with Shift to " +"skew around the opposite side" +msgstr "" + +#: ../../po/../src/seltrans.cpp:520 +msgid "" +"Rotate selection; with Ctrl to snap angle; with Shift " +"to rotate around the opposite corner" +msgstr "" + +#: ../../po/../src/seltrans.cpp:829 ../../po/../src/seltrans.cpp:909 +#, c-format +msgid "Scale: %0.2f%% x %0.2f%%; with Ctrl to lock ratio" +msgstr "" + +#. TRANSLATORS: don't modify the first ";" (it will NOT be displayed as ";" - only the second one will be) +#: ../../po/../src/seltrans.cpp:984 +#, c-format +msgid "Skew: %0.2f°; with Ctrl to snap angle" +msgstr "" + +#. TRANSLATORS: don't modify the first ";" (it will NOT be displayed as ";" - only the second one will be) +#: ../../po/../src/seltrans.cpp:1035 +#, c-format +msgid "Rotate: %0.2f°; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/seltrans.cpp:1090 +#, c-format +msgid "Move center to %s, %s" +msgstr "" + +#: ../../po/../src/slideshow.cpp:90 +msgid "Inkscape slideshow" +msgstr "" + +#: ../../po/../src/sp-anchor.cpp:181 +#, c-format +msgid "Link to %s" +msgstr "" + +#: ../../po/../src/sp-anchor.cpp:185 +msgid "Link without URI" +msgstr "" + +#: ../../po/../src/sp-ellipse.cpp:438 ../../po/../src/sp-ellipse.cpp:870 +#, fuzzy +msgid "Ellipse" +msgstr "Елипса" + +#: ../../po/../src/sp-ellipse.cpp:583 +#, fuzzy +msgid "Circle" +msgstr "Датотека" + +#: ../../po/../src/sp-ellipse.cpp:865 +#, fuzzy +msgid "Segment" +msgstr "Елипса" + +#: ../../po/../src/sp-ellipse.cpp:867 +msgid "Arc" +msgstr "" + +#. TRANSLATORS: "Flow region" is an area where text is allowed to flow +#: ../../po/../src/sp-flowregion.cpp:276 +msgid "Flow region" +msgstr "" + +#. TRANSLATORS: A region "cut out of" a flow region; text is not allowed to flow inside the +#. * flow excluded region. flowRegionExclude in SVG 1.2: see +#. * http://www.w3.org/TR/2004/WD-SVG12-20041027/flow.html#flowRegion-elem and +#. * http://www.w3.org/TR/2004/WD-SVG12-20041027/flow.html#flowRegionExclude-elem. +#: ../../po/../src/sp-flowregion.cpp:493 +msgid "Flow excluded region" +msgstr "" + +#: ../../po/../src/sp-flowtext.cpp:355 +#, c-format +msgid "Flowed text (%d characters)" +msgstr "" + +#: ../../po/../src/sp-flowtext.cpp:357 +#, c-format +msgid "Linked flowed text (%d characters)" +msgstr "" + +#: ../../po/../src/sp-guide.cpp:290 +msgid "vertical guideline" +msgstr "" + +#: ../../po/../src/sp-guide.cpp:292 +msgid "horizontal guideline" +msgstr "" + +#: ../../po/../src/sp-image.cpp:835 +msgid "embedded" +msgstr "" + +#: ../../po/../src/sp-image.cpp:839 +msgid "(null_pointer)" +msgstr "" + +#: ../../po/../src/sp-image.cpp:843 +#, c-format +msgid "Image with bad reference: %s" +msgstr "" + +#: ../../po/../src/sp-image.cpp:844 +#, c-format +msgid "Image %d × %d: %s" +msgstr "" + +#: ../../po/../src/sp-item-group.cpp:390 +#, c-format +msgid "Group of %d object" +msgid_plural "Group of %d objects" +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/sp-item.cpp:720 +#, fuzzy +msgid "Object" +msgstr "Објект" + +#: ../../po/../src/sp-line.cpp:202 +#, fuzzy +msgid "Line" +msgstr "Елипса" + +#. TRANSLATORS COMMENT: %s is either "outset" or "inset" depending on sign +#: ../../po/../src/sp-offset.cpp:433 +#, c-format +msgid "Linked offset, %s by %f pt" +msgstr "" + +#: ../../po/../src/sp-offset.cpp:434 ../../po/../src/sp-offset.cpp:438 +#, fuzzy +msgid "outset" +msgstr "Надвор" + +#: ../../po/../src/sp-offset.cpp:434 ../../po/../src/sp-offset.cpp:438 +#, fuzzy +msgid "inset" +msgstr "Точка" + +#. TRANSLATORS COMMENT: %s is either "outset" or "inset" depending on sign +#: ../../po/../src/sp-offset.cpp:437 +#, c-format +msgid "Dynamic offset, %s by %f pt" +msgstr "" + +#: ../../po/../src/sp-path.cpp:127 +#, c-format +msgid "Path (%i node)" +msgid_plural "Path (%i nodes)" +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/sp-polygon.cpp:216 +#, fuzzy +msgid "Polygon" +msgstr "Датотека" + +#: ../../po/../src/sp-polyline.cpp:179 +#, fuzzy +msgid "Polyline" +msgstr "Елипса" + +#: ../../po/../src/sp-rect.cpp:250 +#, fuzzy +msgid "Rectangle" +msgstr "Правоаголник" + +#. TRANSLATORS: since turn count isn't an integer, please adjust the +#. string as needed to deal with an localized plural forms. +#: ../../po/../src/sp-spiral.cpp:305 +#, c-format +msgid "Spiral with %3f turns" +msgstr "" + +#: ../../po/../src/sp-star.cpp:288 +#, c-format +msgid "Star with %d vertex" +msgid_plural "Star with %d vertices" +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/sp-star.cpp:292 +#, c-format +msgid "Polygon with %d vertex" +msgid_plural "Polygon with %d vertices" +msgstr[0] "" +msgstr[1] "" + +#. TRANSLATORS: For description of font with no name. +#: ../../po/../src/sp-text.cpp:420 +msgid "<no name found>" +msgstr "" + +#: ../../po/../src/sp-text.cpp:426 +#, c-format +msgid "Text on path (%s, %s)" +msgstr "" + +#: ../../po/../src/sp-text.cpp:427 +#, c-format +msgid "Text (%s, %s)" +msgstr "" + +#. TRANSLATORS: Used for statusbar description for long chains: +#. * "Clone of: Clone of: ... in Layer 1". +#: ../../po/../src/sp-use.cpp:317 +#, fuzzy +msgid "..." +msgstr "Отвори..." + +#: ../../po/../src/sp-use.cpp:325 +#, fuzzy, c-format +msgid "Clone of: %s" +msgstr "Датотека" + +#: ../../po/../src/sp-use.cpp:329 +msgid "Orphaned clone" +msgstr "" + +#: ../../po/../src/spiral-context.cpp:355 +msgid "Ctrl: snap angle" +msgstr "" + +#: ../../po/../src/spiral-context.cpp:357 +msgid "Alt: lock spiral radius" +msgstr "" + +#: ../../po/../src/spiral-context.cpp:469 +#, c-format +msgid "" +"Spiral: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/splivarot.cpp:106 +msgid "Select at least 2 paths to perform a boolean operation." +msgstr "" + +#: ../../po/../src/splivarot.cpp:112 +msgid "" +"Select exactly 2 paths to perform difference, XOR, division, or path " +"cut." +msgstr "" + +#: ../../po/../src/splivarot.cpp:129 ../../po/../src/splivarot.cpp:144 +msgid "" +"Unable to determine the z-order of the objects selected for " +"difference, XOR, division, or path cut." +msgstr "" + +#: ../../po/../src/splivarot.cpp:174 +msgid "" +"One of the objects is not a path, cannot perform boolean operation." +msgstr "" + +#. TRANSLATORS: "to outline" means "to convert stroke to path" +#: ../../po/../src/splivarot.cpp:554 +msgid "Select path(s) to outline." +msgstr "" + +#. TRANSLATORS: "to outline" means "to convert stroke to path" +#: ../../po/../src/splivarot.cpp:748 +msgid "No stroked paths to outline in the selection." +msgstr "" + +#: ../../po/../src/splivarot.cpp:832 +msgid "Selected object is not a path, cannot inset/outset." +msgstr "" + +#: ../../po/../src/splivarot.cpp:1040 +msgid "Select path(s) to inset/outset." +msgstr "" + +#: ../../po/../src/splivarot.cpp:1257 +msgid "No paths to inset/outset in the selection." +msgstr "" + +#: ../../po/../src/splivarot.cpp:1390 +msgid "Select path(s) to simplify." +msgstr "" + +#: ../../po/../src/splivarot.cpp:1417 +msgid "No paths to simplify in the selection." +msgstr "" + +#: ../../po/../src/star-context.cpp:362 +msgid "Ctrl: snap angle; keep rays radial" +msgstr "" + +#: ../../po/../src/star-context.cpp:470 +#, c-format +msgid "" +"Polygon: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/star-context.cpp:471 +#, c-format +msgid "Star: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/text-chemistry.cpp:90 +msgid "Select a text and a path to put text on path." +msgstr "" + +#: ../../po/../src/text-chemistry.cpp:95 +msgid "" +"This text object is already put to a path. Remove it from the path " +"first. Use Shift+D to look up its path." +msgstr "" + +#. rect is the only SPShape which is not yet, and thus SVG forbids us from putting text on it +#: ../../po/../src/text-chemistry.cpp:101 +msgid "" +"You cannot put text on a rectangle in this version. Convert rectangle to " +"path first." +msgstr "" + +#: ../../po/../src/text-chemistry.cpp:159 +msgid "Select a text on path to remove it from path." +msgstr "" + +#: ../../po/../src/text-chemistry.cpp:181 +msgid "No texts-on-paths in the selection." +msgstr "" + +#: ../../po/../src/text-chemistry.cpp:209 +#: ../../po/../src/text-chemistry.cpp:229 +msgid "Select text(s) to remove kerns from." +msgstr "" + +#: ../../po/../src/text-chemistry.cpp:250 +msgid "" +"Select a text and one or more paths or shapes to flow text " +"into frame." +msgstr "" + +#: ../../po/../src/text-chemistry.cpp:322 +msgid "Select a flowed text to unflow it." +msgstr "" + +#: ../../po/../src/text-context.cpp:463 +msgid "Click to edit the text, drag to select part of the text." +msgstr "" + +#: ../../po/../src/text-context.cpp:465 +msgid "" +"Click to edit the flowed text, drag to select part of the text." +msgstr "" + +#: ../../po/../src/text-context.cpp:540 +msgid "Non-printable character" +msgstr "" + +#: ../../po/../src/text-context.cpp:589 +#, c-format +msgid "Unicode: %s: %s" +msgstr "" + +#: ../../po/../src/text-context.cpp:591 ../../po/../src/text-context.cpp:855 +msgid "Unicode: " +msgstr "" + +#: ../../po/../src/text-context.cpp:615 +msgid "Current layer is hidden. Unhide it to be able to add text." +msgstr "" + +#: ../../po/../src/text-context.cpp:619 +msgid "Current layer is locked. Unlock it to be able to add text." +msgstr "" + +#: ../../po/../src/text-context.cpp:673 +#, c-format +msgid "Flowed text frame: %s × %s" +msgstr "" + +#: ../../po/../src/text-context.cpp:708 ../../po/../src/text-context.cpp:1464 +msgid "Type text; Enter to start new line." +msgstr "" + +#: ../../po/../src/text-context.cpp:719 +msgid "Flowed text is created." +msgstr "" + +#: ../../po/../src/text-context.cpp:722 +msgid "" +"The frame is too small for the current font size. Flowed text not " +"created." +msgstr "" + +#: ../../po/../src/text-context.cpp:841 +msgid "No-break space" +msgstr "" + +#: ../../po/../src/text-context.cpp:1462 +msgid "Type flowed text; Enter to start new paragraph." +msgstr "" + +#: ../../po/../src/text-context.cpp:1472 ../../po/../src/tools-switch.cpp:189 +msgid "" +"Click to select or create text, drag to create flowed text; " +"then type." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:141 +msgid "" +"To edit a path, click, Shift+click, or drag around " +"nodes to select them, then drag nodes and handles. Click on an " +"object to select." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:147 +msgid "" +"Drag to create a rectangle. Drag controls to round corners and " +"resize. Click to select." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:153 +msgid "" +"Drag to create an ellipse. Drag controls to make an arc or " +"segment. Click to select." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:159 +msgid "" +"Drag to create a star. Drag controls to edit the star shape. " +"Click to select." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:165 +msgid "" +"Drag to create a spiral. Drag controls to edit the spiral " +"shape. Click to select." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:171 +msgid "" +"Drag to create a freehand line. Start drawing with Shift to " +"append to selected path." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:177 +msgid "" +"Click or click and drag to start a path; with Shift to " +"append to selected path." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:183 +msgid "" +"Drag to paint a calligraphic stroke. Left/right arrow " +"keys adjust width, up/down adjust angle." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:195 +msgid "" +"Drag or double click to create a gradient on selected objects, " +"drag handles to adjust gradients." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:201 +msgid "" +"Click or drag around an area to zoom in, Shift+click to " +"zoom out." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:213 +msgid "Click and drag between shapes to create a connector." +msgstr "" + +#: ../../po/../src/trace/potrace/inkscape-potrace.cpp:553 +#: ../../po/../src/trace/potrace/inkscape-potrace.cpp:654 +#, c-format +msgid "Trace: %d. %ld nodes" +msgstr "" + +#: ../../po/../src/trace/trace.cpp:53 ../../po/../src/trace/trace.cpp:62 +#: ../../po/../src/trace/trace.cpp:70 +msgid "Select an image to trace" +msgstr "" + +#: ../../po/../src/trace/trace.cpp:133 +#, fuzzy +msgid "Trace: No active document" +msgstr "Зачувај документ" + +#: ../../po/../src/trace/trace.cpp:154 +msgid "Trace: Image has no bitmap data" +msgstr "" + +#: ../../po/../src/trace/trace.cpp:267 +#, c-format +msgid "Trace: Done. %ld nodes created" +msgstr "" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:59 ../../po/../src/verbs.cpp:2212 +msgid "About Inkscape" +msgstr "" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:66 +msgid "_Splash" +msgstr "" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:68 +msgid "_Authors" +msgstr "" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:69 +#, fuzzy +msgid "_Translators" +msgstr "Ориентација:" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:70 +#, fuzzy +msgid "_License" +msgstr "Линк" + +#. TRANSLATORS: This is the filename of the `About Inkscape' picture in +#. the `screens' directory. Thus the translation of "about.svg" should be +#. the filename of its translated version, e.g. about.zh.svg for Chinese. +#. +#. N.B. about.svg changes once per release. (We should probably rename +#. the original to about-0.40.svg etc. as soon as we have a translation. +#. If we do so, then add an item to release-checklist saying that the +#. string here should be changed.) +#. FIXME? INKSCAPE_SCREENSDIR and "about.svg" are in UTF-8, not the +#. native filename encoding... and the filename passed to sp_document_new +#. should be in UTF-*8.. +#: ../../po/../src/ui/dialog/aboutbox.cpp:114 +msgid "about.svg" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:464 +msgid "Minimum horizontal gap (in px units) between bounding boxes" +msgstr "" + +#. TRANSLATORS: Horizontal gap +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:466 +#: ../../po/../src/widgets/toolbox.cpp:1556 +msgid "H:" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:474 +msgid "Minimum vertical gap (in px units) between bounding boxes" +msgstr "" + +#. TRANSLATORS: Vertical gap +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:476 +msgid "V:" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:734 +#, fuzzy +msgid "Align" +msgstr "Порамни" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:735 +#, fuzzy +msgid "Distribute" +msgstr "Дистрибуција" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:736 +msgid "Remove overlaps" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:737 +#, fuzzy +msgid "Nodes" +msgstr "Ништо" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:742 +#, fuzzy +msgid "Relative to: " +msgstr "Избор" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:747 +msgid "Align right sides of objects to left side of anchor" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:750 +#, fuzzy +msgid "Align left sides" +msgstr "Порамни" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:753 +msgid "Center on vertical axis" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:756 +#, fuzzy +msgid "Align right sides" +msgstr "Порамни" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:759 +msgid "Align left sides of objects to right side of anchor" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:762 +msgid "Align bottoms of objects to top of anchor" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:765 +#, fuzzy +msgid "Align tops" +msgstr "Порамни" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:768 +msgid "Center on horizontal axis" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:771 +#, fuzzy +msgid "Align bottoms" +msgstr "Порамни" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:774 +msgid "Align tops of objects to bottom of anchor" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:779 +#, fuzzy +msgid "Align baseline anchors of texts vertically" +msgstr "Преврти вертикално" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:782 +#, fuzzy +msgid "Align baseline anchors of texts horizontally" +msgstr "Преврти хоризонтално" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:787 +msgid "Make horizontal gaps between objects equal" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:791 +#, fuzzy +msgid "Distribute left sides equidistantly" +msgstr "Преврти вертикално" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:794 +#, fuzzy +msgid "Distribute centers equidistantly horizontally" +msgstr "Преврти хоризонтално" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:797 +#, fuzzy +msgid "Distribute right sides equidistantly" +msgstr "Преврти вертикално" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:801 +msgid "Make vertical gaps between objects equal" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:805 +#, fuzzy +msgid "Distribute tops equidistantly" +msgstr "Преврти вертикално" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:808 +#, fuzzy +msgid "Distribute centers equidistantly vertically" +msgstr "Преврти вертикално" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:811 +msgid "Distribute bottoms equidistantly" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:816 +#, fuzzy +msgid "Distribute baseline anchors of texts horizontally" +msgstr "Преврти хоризонтално" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:819 +#, fuzzy +msgid "Distribute baseline anchors of texts vertically" +msgstr "Преврти вертикално" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:824 +msgid "Randomize centers in both dimensions" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:827 +msgid "Unclump objects: try to equalize edge-to-edge distances" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:832 +msgid "" +"Move objects as little as possible so that their bounding boxes do not " +"overlap" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:837 +#, fuzzy +msgid "Align selected nodes horizontally" +msgstr "Преврти хоризонтално" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:840 +#, fuzzy +msgid "Align selected nodes vertically" +msgstr "Преврти вертикално" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:843 +#, fuzzy +msgid "Distribute selected nodes horizontally" +msgstr "Преврти хоризонтално" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:846 +#, fuzzy +msgid "Distribute selected nodes vertically" +msgstr "Преврти вертикално" + +#. Rest of the widgetry +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:851 +msgid "Last selected" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:852 +msgid "First selected" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:853 +msgid "Biggest item" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:854 +msgid "Smallest item" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:856 +#: ../../po/../src/widgets/desktop-widget.cpp:1065 +#, fuzzy +msgid "Drawing" +msgstr "Цртеж" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:91 +msgid "Metadata 1" +msgstr "" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:92 +msgid "Metadata 2" +msgstr "" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:187 +msgid "X coordinate of grid origin" +msgstr "" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:189 +msgid "Y coordinate of grid origin" +msgstr "" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:191 +msgid "Distance of vertical grid lines" +msgstr "" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:193 +msgid "Distance of horizontal grid lines" +msgstr "" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:197 +msgid "Max. snapping distance from grid" +msgstr "" + +#: ../../po/../src/ui/dialog/export.cpp:34 +#, fuzzy +msgid "Export" +msgstr "Извези" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:36 +#, fuzzy +msgid "Fill" +msgstr "Пополни" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:37 +msgid "Stroke Paint" +msgstr "" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:38 +msgid "Stroke Style" +msgstr "" + +#: ../../po/../src/ui/dialog/find.cpp:34 +#, fuzzy +msgid "Find" +msgstr "Решетка" + +#: ../../po/../src/ui/dialog/memory.cpp:96 +msgid "Heap" +msgstr "" + +#: ../../po/../src/ui/dialog/memory.cpp:97 +#, fuzzy +msgid "In Use" +msgstr "Точка" + +#. TRANSLATORS: "Slack" refers to memory which is in the heap but currently unused. +#. More typical usage is to call this memory "free" rather than "slack". +#: ../../po/../src/ui/dialog/memory.cpp:100 +#, fuzzy +msgid "Slack" +msgstr "Стил" + +#: ../../po/../src/ui/dialog/memory.cpp:101 +#, fuzzy +msgid "Total" +msgstr "Наслов:" + +#: ../../po/../src/ui/dialog/memory.cpp:141 +#: ../../po/../src/ui/dialog/memory.cpp:147 +#: ../../po/../src/ui/dialog/memory.cpp:154 +#: ../../po/../src/ui/dialog/memory.cpp:186 +#, fuzzy +msgid "Unknown" +msgstr "Непознато" + +#: ../../po/../src/ui/dialog/memory.cpp:167 +#, fuzzy +msgid "Combined" +msgstr "Комбинирај" + +#: ../../po/../src/ui/dialog/memory.cpp:209 +#, fuzzy +msgid "Recalculate" +msgstr "Правоаголник" + +#: ../../po/../src/ui/dialog/messages.cpp:74 +#, fuzzy +msgid "Ready." +msgstr "Повтори" + +#: ../../po/../src/ui/dialog/messages.cpp:75 +msgid "" +"Enable log display by setting dialogs.debug 'redirect' attribute to 1 in " +"preferences.xml" +msgstr "" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:184 +msgid "_Execute Python" +msgstr "" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:186 +msgid "_Execute Perl" +msgstr "" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:195 +msgid "Script" +msgstr "" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:205 +#, fuzzy +msgid "Output" +msgstr "Надвор" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:215 +msgid "Errors" +msgstr "" + +#. Dialog organization +#: ../../po/../src/ui/dialog/session-player.cpp:73 +msgid "Session file" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:74 +msgid "Playback controls" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:75 +msgid "Message information" +msgstr "" + +#. Active session file display +#. fixme: Does this mean the active file for the session, or the file for the active session? +#. Please indicate which with a TRANSLATORS comment. +#: ../../po/../src/ui/dialog/session-player.cpp:85 +msgid "Active session file:" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:86 +msgid "Delay (milliseconds):" +msgstr "" + +#. Unload/load buttons +#: ../../po/../src/ui/dialog/session-player.cpp:94 +#, fuzzy +msgid "Close file" +msgstr "Затвори" + +#: ../../po/../src/ui/dialog/session-player.cpp:95 +msgid "Open new file" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:96 +#, fuzzy +msgid "Set delay" +msgstr "Постави како основно" + +#: ../../po/../src/ui/dialog/session-player.cpp:138 +#, fuzzy +msgid "Rewind" +msgstr "Повтори" + +#: ../../po/../src/ui/dialog/session-player.cpp:139 +msgid "Go back one change" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:140 +#, fuzzy +msgid "Pause" +msgstr "Вметни" + +#: ../../po/../src/ui/dialog/session-player.cpp:141 +msgid "Go forward one change" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:142 +msgid "Play" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:177 +#: ../../po/../src/verbs.cpp:1573 +msgid "Open session file" +msgstr "" + +#. ##Set up the Potrace panel +#. #### brightness #### +#. #### Multiple scanning#### +#. ----Hbox1 +#: ../../po/../src/ui/dialog/tracedialog.cpp:345 +#: ../../po/../src/ui/dialog/tracedialog.cpp:428 +#, fuzzy +msgid "Brightness" +msgstr "Висина:" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:348 +msgid "Trace by a given brightness level" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:355 +msgid "Brightness cutoff for black/white" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:362 +msgid "Image Brightness" +msgstr "" + +#. #### canny edge detection #### +#. TRANSLATORS: "Canny" is the name of the inventor of this edge detection method +#: ../../po/../src/ui/dialog/tracedialog.cpp:369 +msgid "Optimal Edge Detection (Canny)" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:372 +msgid "Trace with edge detection by J. Canny's algorithm" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:388 +msgid "Brightness cutoff for adjacent pixels (determines edge thickness)" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:395 +#, fuzzy +msgid "Edge Detection" +msgstr "Избор" + +#. #### quantization #### +#. TRANSLATORS: Color Quantization: the process of reducing the number of colors +#. in an image by selecting an optimized set of representative colors and then +#. re-applying this reduced set to the original image. +#: ../../po/../src/ui/dialog/tracedialog.cpp:404 +msgid "Color Quantization" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:407 +msgid "Trace along the boundaries of reduced colors" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:414 +msgid "The number of reduced colors" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:416 +#, fuzzy +msgid "Colors:" +msgstr "Затвори" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:421 +msgid "Quantization / Reduction" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:431 +msgid "Trace the given number of brightness levels" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:438 +#, fuzzy +msgid "Scans:" +msgstr "Облик" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:440 +msgid "The desired number of scans" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:448 +msgid "Trace the given number of reduced colors" +msgstr "" + +#. ---Hbox3 +#: ../../po/../src/ui/dialog/tracedialog.cpp:454 +msgid "Monochrome" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:457 +msgid "Same as Color, but convert result to grayscale" +msgstr "" + +#. TRANSLATORS: "Stack" is a verb here +#: ../../po/../src/ui/dialog/tracedialog.cpp:460 +#, fuzzy +msgid "Stack" +msgstr "Стил" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:463 +msgid "" +"Stack scans vertically (no gaps) or tile horizontally (usually with gaps)" +msgstr "" + +#. TRANSLATORS: "Smooth" is a verb here +#: ../../po/../src/ui/dialog/tracedialog.cpp:466 +msgid "Smooth" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:469 +msgid "Apply Gaussian blur to the bitmap before tracing" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:473 +msgid "Multiple Scanning" +msgstr "" + +#. #### Preview #### +#: ../../po/../src/ui/dialog/tracedialog.cpp:479 +#: ../../po/../src/ui/dialog/tracedialog.cpp:489 +#, fuzzy +msgid "Preview" +msgstr "Печати на екран" + +#. do not expand +#: ../../po/../src/ui/dialog/tracedialog.cpp:483 +msgid "Preview the result without actual tracing" +msgstr "" + +#. #### swap black and white #### +#: ../../po/../src/ui/dialog/tracedialog.cpp:495 +msgid "Invert" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:499 +msgid "Invert black and white regions for single traces" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:503 +msgid "Thanks to Peter Selinger, http://potrace.sourceforge.net" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:506 +#, fuzzy +msgid "Credits" +msgstr "Создади" + +#. done +#. TRANSLATORS: Potrace is an application for transforming bitmaps into +#. vector graphics (http://potrace.sourceforge.net/) +#: ../../po/../src/ui/dialog/tracedialog.cpp:514 +#, fuzzy +msgid "Potrace" +msgstr "Точка" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:527 +msgid "Abort a trace in progress" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:531 +msgid "Execute the trace" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:80 +#: ../../po/../src/ui/dialog/transformation.cpp:90 +#, fuzzy +msgid "_Horizontal" +msgstr "Преврти хоризонтално" + +#: ../../po/../src/ui/dialog/transformation.cpp:80 +msgid "Horizontal displacement (relative) or position (absolute)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:82 +#: ../../po/../src/ui/dialog/transformation.cpp:92 +#, fuzzy +msgid "_Vertical" +msgstr "Преврти вертикално" + +#: ../../po/../src/ui/dialog/transformation.cpp:82 +msgid "Vertical displacement (relative) or position (absolute)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:84 +#, fuzzy +msgid "_Width" +msgstr "Ширина:" + +#: ../../po/../src/ui/dialog/transformation.cpp:84 +msgid "Horizontal size increment (absolute or percentage)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:86 +#, fuzzy +msgid "_Height" +msgstr "Висина:" + +#: ../../po/../src/ui/dialog/transformation.cpp:86 +msgid "Vertical size increment (absolute or percentage)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:88 +#, fuzzy +msgid "A_ngle" +msgstr "Агол" + +#: ../../po/../src/ui/dialog/transformation.cpp:88 +msgid "Rotation angle (positive = counterclockwise)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:90 +msgid "" +"Horizontal skew angle (positive = counterclockwise), or absolute " +"displacement, or percentage displacement" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:92 +msgid "" +"Vertical skew angle (positive = counterclockwise), or absolute displacement, " +"or percentage displacement" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:95 +#, fuzzy +msgid "Transformation matrix element A" +msgstr "Правоаголник" + +#: ../../po/../src/ui/dialog/transformation.cpp:96 +#, fuzzy +msgid "Transformation matrix element B" +msgstr "Правоаголник" + +#: ../../po/../src/ui/dialog/transformation.cpp:97 +#, fuzzy +msgid "Transformation matrix element C" +msgstr "Правоаголник" + +#: ../../po/../src/ui/dialog/transformation.cpp:98 +#, fuzzy +msgid "Transformation matrix element D" +msgstr "Правоаголник" + +#: ../../po/../src/ui/dialog/transformation.cpp:99 +#, fuzzy +msgid "Transformation matrix element E" +msgstr "Правоаголник" + +#: ../../po/../src/ui/dialog/transformation.cpp:100 +#, fuzzy +msgid "Transformation matrix element F" +msgstr "Правоаголник" + +#: ../../po/../src/ui/dialog/transformation.cpp:102 +#, fuzzy +msgid "Rela_tive move" +msgstr "Избор" + +#: ../../po/../src/ui/dialog/transformation.cpp:102 +msgid "" +"Add the specified relative displacement to the current position; otherwise, " +"edit the current absolute position directly" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:103 +msgid "Scale proportionally" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:103 +msgid "Preserve the width/height ratio of the scaled objects" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:104 +msgid "Apply to each _object separately" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:104 +msgid "" +"Apply the scale/rotate/skew to each selected object separately; otherwise, " +"transform the selection as a whole" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:105 +msgid "Edit c_urrent matrix" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:105 +msgid "" +"Edit the current transform= matrix; otherwise, post-multiply transform= by " +"this matrix" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:115 +#, fuzzy +msgid "_Move" +msgstr "Премести" + +#: ../../po/../src/ui/dialog/transformation.cpp:118 +#, fuzzy +msgid "_Scale" +msgstr "Промени големина" + +#: ../../po/../src/ui/dialog/transformation.cpp:121 +#, fuzzy +msgid "_Rotate" +msgstr "Ротирај" + +#: ../../po/../src/ui/dialog/transformation.cpp:124 +msgid "Ske_w" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:127 +msgid "Matri_x" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:141 +msgid "Reset the values on the current tab to defaults" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:148 +msgid "Apply transformation to selection" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:43 +msgid "_Use SSL" +msgstr "" + +#. Construct dialog interface +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:68 +#, fuzzy +msgid "_Server:" +msgstr "Филтри" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:69 +#, fuzzy +msgid "_Username:" +msgstr "Датотека" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:70 +msgid "_Password:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:71 +msgid "P_ort:" +msgstr "" + +#. Buttons +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:99 +#, fuzzy +msgid "Connect" +msgstr "Затвори" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:126 +msgid "Establishing connection to Jabber server %1 as user %2" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:131 +msgid "Failed to establish connection to Jabber server %1" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:136 +msgid "Authentication failed on Jabber server %1 as %2" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:141 +msgid "SSL initialization failed when connecting to Jabber server %1" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:147 +msgid "Connected to Jabber server %1 as %2" +msgstr "" + +#. Construct labels +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:75 +msgid "Chatroom _name:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:76 +msgid "Chatroom _server:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:77 +msgid "Chatroom _password:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:78 +msgid "Chatroom _handle:" +msgstr "" + +#. Button setup and callback registration +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:97 +msgid "Connect to chatroom" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:132 +msgid "Synchronizing with chatroom %1@%2 using the handle %3" +msgstr "" + +#. Construct dialog interface +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:78 +msgid "_User's Jabber ID:" +msgstr "" + +#. Buttons +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:82 +msgid "_Invite user" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:83 +#, fuzzy +msgid "_Cancel" +msgstr "Откажи" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:94 +msgid "Buddy List" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:170 +msgid "Sending whiteboard invitation to %1" +msgstr "" + +#. FIXME: strings are replaced by placeholders, NOT to be translated until the code is enabled +#. See http://sourceforge.net/mailarchive/message.php?msg_id=11746016 for details +#. File menu +#. Edit menu +#. View menu +#. Layer menu +#. Object menu +#. Path menu +#. add(Gtk::StockItem(CLEANUP, _("PLACEHOLDER, do not translate"))); (using Gtk::Stock::CLEAR) +#. Text menu +#. About menu +#. Tools toolbox +#. Select Tool controls +#. Node Tool controls +#. Calligraphy Tool controls +#. Session playback controls +#: ../../po/../src/ui/stock-items.cpp:34 ../../po/../src/ui/stock-items.cpp:35 +#: ../../po/../src/ui/stock-items.cpp:36 ../../po/../src/ui/stock-items.cpp:37 +#: ../../po/../src/ui/stock-items.cpp:38 ../../po/../src/ui/stock-items.cpp:39 +#: ../../po/../src/ui/stock-items.cpp:40 ../../po/../src/ui/stock-items.cpp:41 +#: ../../po/../src/ui/stock-items.cpp:42 ../../po/../src/ui/stock-items.cpp:43 +#: ../../po/../src/ui/stock-items.cpp:46 ../../po/../src/ui/stock-items.cpp:47 +#: ../../po/../src/ui/stock-items.cpp:48 ../../po/../src/ui/stock-items.cpp:49 +#: ../../po/../src/ui/stock-items.cpp:50 ../../po/../src/ui/stock-items.cpp:51 +#: ../../po/../src/ui/stock-items.cpp:52 ../../po/../src/ui/stock-items.cpp:53 +#: ../../po/../src/ui/stock-items.cpp:54 ../../po/../src/ui/stock-items.cpp:55 +#: ../../po/../src/ui/stock-items.cpp:56 ../../po/../src/ui/stock-items.cpp:57 +#: ../../po/../src/ui/stock-items.cpp:58 ../../po/../src/ui/stock-items.cpp:59 +#: ../../po/../src/ui/stock-items.cpp:62 ../../po/../src/ui/stock-items.cpp:63 +#: ../../po/../src/ui/stock-items.cpp:64 ../../po/../src/ui/stock-items.cpp:65 +#: ../../po/../src/ui/stock-items.cpp:66 ../../po/../src/ui/stock-items.cpp:67 +#: ../../po/../src/ui/stock-items.cpp:68 ../../po/../src/ui/stock-items.cpp:69 +#: ../../po/../src/ui/stock-items.cpp:70 ../../po/../src/ui/stock-items.cpp:71 +#: ../../po/../src/ui/stock-items.cpp:72 ../../po/../src/ui/stock-items.cpp:73 +#: ../../po/../src/ui/stock-items.cpp:74 ../../po/../src/ui/stock-items.cpp:75 +#: ../../po/../src/ui/stock-items.cpp:76 ../../po/../src/ui/stock-items.cpp:77 +#: ../../po/../src/ui/stock-items.cpp:78 ../../po/../src/ui/stock-items.cpp:79 +#: ../../po/../src/ui/stock-items.cpp:80 ../../po/../src/ui/stock-items.cpp:81 +#: ../../po/../src/ui/stock-items.cpp:82 ../../po/../src/ui/stock-items.cpp:83 +#: ../../po/../src/ui/stock-items.cpp:84 ../../po/../src/ui/stock-items.cpp:85 +#: ../../po/../src/ui/stock-items.cpp:86 ../../po/../src/ui/stock-items.cpp:87 +#: ../../po/../src/ui/stock-items.cpp:88 ../../po/../src/ui/stock-items.cpp:89 +#: ../../po/../src/ui/stock-items.cpp:92 ../../po/../src/ui/stock-items.cpp:93 +#: ../../po/../src/ui/stock-items.cpp:94 ../../po/../src/ui/stock-items.cpp:95 +#: ../../po/../src/ui/stock-items.cpp:96 ../../po/../src/ui/stock-items.cpp:97 +#: ../../po/../src/ui/stock-items.cpp:98 ../../po/../src/ui/stock-items.cpp:99 +#: ../../po/../src/ui/stock-items.cpp:100 +#: ../../po/../src/ui/stock-items.cpp:101 +#: ../../po/../src/ui/stock-items.cpp:102 +#: ../../po/../src/ui/stock-items.cpp:103 +#: ../../po/../src/ui/stock-items.cpp:104 +#: ../../po/../src/ui/stock-items.cpp:105 +#: ../../po/../src/ui/stock-items.cpp:108 +#: ../../po/../src/ui/stock-items.cpp:109 +#: ../../po/../src/ui/stock-items.cpp:110 +#: ../../po/../src/ui/stock-items.cpp:111 +#: ../../po/../src/ui/stock-items.cpp:112 +#: ../../po/../src/ui/stock-items.cpp:113 +#: ../../po/../src/ui/stock-items.cpp:114 +#: ../../po/../src/ui/stock-items.cpp:115 +#: ../../po/../src/ui/stock-items.cpp:116 +#: ../../po/../src/ui/stock-items.cpp:117 +#: ../../po/../src/ui/stock-items.cpp:118 +#: ../../po/../src/ui/stock-items.cpp:119 +#: ../../po/../src/ui/stock-items.cpp:120 +#: ../../po/../src/ui/stock-items.cpp:121 +#: ../../po/../src/ui/stock-items.cpp:122 +#: ../../po/../src/ui/stock-items.cpp:123 +#: ../../po/../src/ui/stock-items.cpp:124 +#: ../../po/../src/ui/stock-items.cpp:125 +#: ../../po/../src/ui/stock-items.cpp:126 +#: ../../po/../src/ui/stock-items.cpp:127 +#: ../../po/../src/ui/stock-items.cpp:130 +#: ../../po/../src/ui/stock-items.cpp:131 +#: ../../po/../src/ui/stock-items.cpp:132 +#: ../../po/../src/ui/stock-items.cpp:133 +#: ../../po/../src/ui/stock-items.cpp:134 +#: ../../po/../src/ui/stock-items.cpp:135 +#: ../../po/../src/ui/stock-items.cpp:136 +#: ../../po/../src/ui/stock-items.cpp:137 +#: ../../po/../src/ui/stock-items.cpp:138 +#: ../../po/../src/ui/stock-items.cpp:139 +#: ../../po/../src/ui/stock-items.cpp:140 +#: ../../po/../src/ui/stock-items.cpp:141 +#: ../../po/../src/ui/stock-items.cpp:142 +#: ../../po/../src/ui/stock-items.cpp:143 +#: ../../po/../src/ui/stock-items.cpp:144 +#: ../../po/../src/ui/stock-items.cpp:145 +#: ../../po/../src/ui/stock-items.cpp:146 +#: ../../po/../src/ui/stock-items.cpp:150 +#: ../../po/../src/ui/stock-items.cpp:151 +#: ../../po/../src/ui/stock-items.cpp:152 +#: ../../po/../src/ui/stock-items.cpp:153 +#: ../../po/../src/ui/stock-items.cpp:156 +#: ../../po/../src/ui/stock-items.cpp:157 +#: ../../po/../src/ui/stock-items.cpp:158 +#: ../../po/../src/ui/stock-items.cpp:161 +#: ../../po/../src/ui/stock-items.cpp:162 +#: ../../po/../src/ui/stock-items.cpp:163 +#: ../../po/../src/ui/stock-items.cpp:164 +#: ../../po/../src/ui/stock-items.cpp:165 +#: ../../po/../src/ui/stock-items.cpp:166 +#: ../../po/../src/ui/stock-items.cpp:167 +#: ../../po/../src/ui/stock-items.cpp:168 +#: ../../po/../src/ui/stock-items.cpp:169 +#: ../../po/../src/ui/stock-items.cpp:170 +#: ../../po/../src/ui/stock-items.cpp:171 +#: ../../po/../src/ui/stock-items.cpp:172 +#: ../../po/../src/ui/stock-items.cpp:175 +#: ../../po/../src/ui/stock-items.cpp:176 +#: ../../po/../src/ui/stock-items.cpp:177 +#: ../../po/../src/ui/stock-items.cpp:178 +#: ../../po/../src/ui/stock-items.cpp:181 +#: ../../po/../src/ui/stock-items.cpp:182 +#: ../../po/../src/ui/stock-items.cpp:183 +#: ../../po/../src/ui/stock-items.cpp:184 +#: ../../po/../src/ui/stock-items.cpp:185 +#: ../../po/../src/ui/stock-items.cpp:186 +#: ../../po/../src/ui/stock-items.cpp:187 +#: ../../po/../src/ui/stock-items.cpp:188 +#: ../../po/../src/ui/stock-items.cpp:189 +#: ../../po/../src/ui/stock-items.cpp:190 +#: ../../po/../src/ui/stock-items.cpp:191 +#: ../../po/../src/ui/stock-items.cpp:194 +#: ../../po/../src/ui/stock-items.cpp:195 +#: ../../po/../src/ui/stock-items.cpp:198 +#: ../../po/../src/ui/stock-items.cpp:199 +#: ../../po/../src/ui/stock-items.cpp:200 +#: ../../po/../src/ui/stock-items.cpp:201 +#: ../../po/../src/ui/stock-items.cpp:202 +msgid "PLACEHOLDER, do not translate" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:88 +msgid "small" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:89 +msgid "medium" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:90 +#, fuzzy +msgid "large" +msgstr "Страница" + +#: ../../po/../src/ui/widget/panel.cpp:91 +msgid "huge" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:106 +#, fuzzy +msgid "List" +msgstr "Точка" + +#: ../../po/../src/ui/widget/selected-style.cpp:67 +msgid "F:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:68 +msgid "S:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:69 +msgid "O:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:95 +msgid "N/A" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:98 +#: ../../po/../src/ui/widget/selected-style.cpp:712 +#, fuzzy +msgid "Nothing selected" +msgstr "Избор" + +#: ../../po/../src/ui/widget/selected-style.cpp:103 +msgid "No fill" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:103 +msgid "No stroke" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:105 +#: ../../po/../src/widgets/paint-selector.cpp:190 +#, fuzzy +msgid "Pattern" +msgstr "Вметни" + +#: ../../po/../src/ui/widget/selected-style.cpp:108 +#: ../../po/../src/widgets/paint-selector.cpp:885 +msgid "Pattern fill" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:108 +#, fuzzy +msgid "Pattern stroke" +msgstr "Вметни" + +#: ../../po/../src/ui/widget/selected-style.cpp:110 +#, fuzzy +msgid "L Gradient" +msgstr "Аргумент:" + +#: ../../po/../src/ui/widget/selected-style.cpp:113 +#, fuzzy +msgid "Linear gradient fill" +msgstr "Зачувај документ" + +#: ../../po/../src/ui/widget/selected-style.cpp:113 +#, fuzzy +msgid "Linear gradient stroke" +msgstr "Зачувај документ" + +#: ../../po/../src/ui/widget/selected-style.cpp:115 +#, fuzzy +msgid "R Gradient" +msgstr "Аргумент:" + +#: ../../po/../src/ui/widget/selected-style.cpp:118 +msgid "Radial gradient fill" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:118 +msgid "Radial gradient stroke" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:120 +#, fuzzy +msgid "Different" +msgstr "Процент" + +#: ../../po/../src/ui/widget/selected-style.cpp:123 +msgid "Different fills" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:123 +msgid "Different strokes" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:125 +#, fuzzy +msgid "Unset" +msgstr "Точка" + +#. TRANSLATORS COMMENT: unset is a verb here +#: ../../po/../src/ui/widget/selected-style.cpp:128 +#: ../../po/../src/ui/widget/selected-style.cpp:182 +#, fuzzy +msgid "Unset fill" +msgstr "Безимено" + +#: ../../po/../src/ui/widget/selected-style.cpp:128 +#: ../../po/../src/ui/widget/selected-style.cpp:182 +msgid "Unset stroke" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:131 +#, fuzzy +msgid "Flat color fill" +msgstr "Боја на подвлекување" + +#: ../../po/../src/ui/widget/selected-style.cpp:131 +#, fuzzy +msgid "Flat color stroke" +msgstr "Боја на подвлекување" + +#. TRANSLATOR COMMENT: A means "Averaged" +#: ../../po/../src/ui/widget/selected-style.cpp:134 +msgid "A" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:137 +#, fuzzy +msgid "Fill is averaged over selected objects" +msgstr "Избор" + +#: ../../po/../src/ui/widget/selected-style.cpp:137 +#, fuzzy +msgid "Stroke is averaged over selected objects" +msgstr "Избор" + +#. TRANSLATOR COMMENT: M means "Multiple" +#: ../../po/../src/ui/widget/selected-style.cpp:140 +msgid "M" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:143 +#, fuzzy +msgid "Multiple selected objects have the same fill" +msgstr "Преврти вертикално" + +#: ../../po/../src/ui/widget/selected-style.cpp:143 +#, fuzzy +msgid "Multiple selected objects have the same stroke" +msgstr "Преврти вертикално" + +#: ../../po/../src/ui/widget/selected-style.cpp:145 +#, fuzzy +msgid "Edit fill..." +msgstr "Уреди" + +#: ../../po/../src/ui/widget/selected-style.cpp:145 +#, fuzzy +msgid "Edit stroke..." +msgstr "Уреди" + +#: ../../po/../src/ui/widget/selected-style.cpp:149 +#, fuzzy +msgid "Last set color" +msgstr "Боја на подвлекување" + +#: ../../po/../src/ui/widget/selected-style.cpp:153 +#, fuzzy +msgid "Last selected color" +msgstr "Избор" + +#: ../../po/../src/ui/widget/selected-style.cpp:157 +msgid "White" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:161 +#: ../../po/../src/widgets/sp-color-scales.cpp:461 +#: ../../po/../src/widgets/sp-color-scales.cpp:462 +msgid "Black" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:165 +#, fuzzy +msgid "Copy color" +msgstr "Затвори" + +#: ../../po/../src/ui/widget/selected-style.cpp:169 +#, fuzzy +msgid "Paste color" +msgstr "Боја на подвлекување" + +#: ../../po/../src/ui/widget/selected-style.cpp:173 +msgid "Swap fill and stroke" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:177 +msgid "Make fill opaque" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:177 +msgid "Make stroke opaque" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:186 +msgid "Remove fill" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:186 +msgid "Remove stroke" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:718 +msgid "Master opacity" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:744 +msgid "0 (transparent)" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:768 +msgid "1.0 (opaque)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1046 +msgid "Moved to next layer." +msgstr "" + +#: ../../po/../src/verbs.cpp:1048 +msgid "Cannot move past last layer." +msgstr "" + +#: ../../po/../src/verbs.cpp:1057 +msgid "Moved to previous layer." +msgstr "" + +#: ../../po/../src/verbs.cpp:1059 +msgid "Cannot move past first layer." +msgstr "" + +#: ../../po/../src/verbs.cpp:1076 ../../po/../src/verbs.cpp:1150 +#, fuzzy +msgid "No current layer." +msgstr "Документ" + +#: ../../po/../src/verbs.cpp:1105 +#, c-format +msgid "Raised layer %s." +msgstr "" + +#: ../../po/../src/verbs.cpp:1109 +#, c-format +msgid "Lowered layer %s." +msgstr "" + +#: ../../po/../src/verbs.cpp:1118 +msgid "Cannot move layer any further." +msgstr "" + +#. TRANSLATORS: this means "The layer has been deleted." +#: ../../po/../src/verbs.cpp:1148 +#, fuzzy +msgid "Deleted layer." +msgstr "Избриши" + +#: ../../po/../src/verbs.cpp:1544 +msgid "" +"You need to connect to a Jabber server before sharing a document with " +"another user." +msgstr "" + +#: ../../po/../src/verbs.cpp:1559 +msgid "" +"You need to connect to a Jabber server before sharing a document with a " +"chatroom." +msgstr "" + +#: ../../po/../src/verbs.cpp:1569 +msgid "XML node tracker has not been initialized; nothing to dump" +msgstr "" + +#. TRANSLATORS: If you have translated the keys.svg file to your language, then +#. translate this string as "keys.LANG.svg" (where LANG is your language code); +#. otherwise leave as "keys.svg". +#: ../../po/../src/verbs.cpp:1631 +msgid "keys.svg" +msgstr "" + +#. TRANSLATORS: If you have translated the tutorial-basic.svg file to your language, +#. then translate this string as "tutorial-basic.LANG.svg" (where LANG is your language +#. code); otherwise leave as "tutorial-basic.svg". +#: ../../po/../src/verbs.cpp:1667 +msgid "tutorial-basic.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1671 +msgid "tutorial-shapes.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1675 +msgid "tutorial-advanced.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1679 +msgid "tutorial-tracing.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1683 +msgid "tutorial-calligraphy.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1687 +msgid "tutorial-elements.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1691 +msgid "tutorial-tips.svg" +msgstr "" + +#: ../../po/../src/verbs.cpp:1842 +msgid "Does nothing" +msgstr "" + +#. File +#: ../../po/../src/verbs.cpp:1845 +#, fuzzy +msgid "Default" +msgstr "Номинални" + +#: ../../po/../src/verbs.cpp:1845 +#, fuzzy +msgid "Create new document from default template" +msgstr "Зачувај документ" + +#: ../../po/../src/verbs.cpp:1847 +#, fuzzy +msgid "_Open..." +msgstr "Отвори..." + +#: ../../po/../src/verbs.cpp:1848 +msgid "Open existing document" +msgstr "" + +#: ../../po/../src/verbs.cpp:1849 +msgid "Re_vert" +msgstr "" + +#: ../../po/../src/verbs.cpp:1850 +msgid "Revert to the last saved version of document (changes will be lost)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1851 +#, fuzzy +msgid "_Save" +msgstr "Зачувај" + +#: ../../po/../src/verbs.cpp:1851 +#, fuzzy +msgid "Save document" +msgstr "Зачувај документ" + +#: ../../po/../src/verbs.cpp:1853 +#, fuzzy +msgid "Save _As..." +msgstr "Зачувај како..." + +#: ../../po/../src/verbs.cpp:1854 +msgid "Save document under new name" +msgstr "" + +#: ../../po/../src/verbs.cpp:1855 +#, fuzzy +msgid "_Print..." +msgstr "Печати..." + +#: ../../po/../src/verbs.cpp:1855 +msgid "Print document" +msgstr "" + +#. TRANSLATORS: "Vacuum Defs" means "Clean up defs" (so as to remove unused definitions) +#: ../../po/../src/verbs.cpp:1858 +msgid "Vac_uum Defs" +msgstr "" + +#: ../../po/../src/verbs.cpp:1858 +msgid "Remove unused predefined items from the <defs> of the document" +msgstr "" + +#: ../../po/../src/verbs.cpp:1860 +#, fuzzy +msgid "Print _Direct" +msgstr "Печати на екран" + +#: ../../po/../src/verbs.cpp:1861 +msgid "Print directly without prompting to a file or pipe" +msgstr "" + +#: ../../po/../src/verbs.cpp:1862 +#, fuzzy +msgid "Print Previe_w" +msgstr "Печати на екран" + +#: ../../po/../src/verbs.cpp:1863 +msgid "Preview document printout" +msgstr "" + +#: ../../po/../src/verbs.cpp:1864 +#, fuzzy +msgid "_Import..." +msgstr "Увези" + +#: ../../po/../src/verbs.cpp:1865 +msgid "Import bitmap or SVG image into document" +msgstr "" + +#: ../../po/../src/verbs.cpp:1866 +msgid "_Export Bitmap..." +msgstr "" + +#: ../../po/../src/verbs.cpp:1867 +msgid "Export document or selection as a bitmap image" +msgstr "" + +#: ../../po/../src/verbs.cpp:1868 +#, fuzzy +msgid "N_ext Window" +msgstr "Преглед" + +#: ../../po/../src/verbs.cpp:1869 +msgid "Switch to the next document window" +msgstr "" + +#: ../../po/../src/verbs.cpp:1870 +#, fuzzy +msgid "P_revious Window" +msgstr "Преглед" + +#: ../../po/../src/verbs.cpp:1871 +msgid "Switch to the previous document window" +msgstr "" + +#: ../../po/../src/verbs.cpp:1872 +#, fuzzy +msgid "_Close" +msgstr "Затвори" + +#: ../../po/../src/verbs.cpp:1873 +msgid "Close window" +msgstr "" + +#: ../../po/../src/verbs.cpp:1874 +msgid "_Quit" +msgstr "" + +#: ../../po/../src/verbs.cpp:1874 +msgid "Quit Inkscape" +msgstr "" + +#. Edit +#: ../../po/../src/verbs.cpp:1877 +#, fuzzy +msgid "_Undo" +msgstr "Врати" + +#: ../../po/../src/verbs.cpp:1877 +msgid "Undo last action" +msgstr "" + +#: ../../po/../src/verbs.cpp:1879 +#, fuzzy +msgid "_Redo" +msgstr "Повтори" + +#: ../../po/../src/verbs.cpp:1880 +msgid "Do again last undone action" +msgstr "" + +#: ../../po/../src/verbs.cpp:1881 +#, fuzzy +msgid "Cu_t" +msgstr "Исечи" + +#: ../../po/../src/verbs.cpp:1882 +msgid "Cut selection to clipboard" +msgstr "" + +#: ../../po/../src/verbs.cpp:1883 +#, fuzzy +msgid "_Copy" +msgstr "Копирај" + +#: ../../po/../src/verbs.cpp:1884 +msgid "Copy selection to clipboard" +msgstr "" + +#: ../../po/../src/verbs.cpp:1885 +#, fuzzy +msgid "_Paste" +msgstr "Вметни" + +#: ../../po/../src/verbs.cpp:1886 +msgid "Paste objects from clipboard to mouse point" +msgstr "" + +#: ../../po/../src/verbs.cpp:1887 +msgid "Paste _Style" +msgstr "" + +#: ../../po/../src/verbs.cpp:1888 +msgid "Apply style of the copied object to selection" +msgstr "" + +#: ../../po/../src/verbs.cpp:1889 +msgid "Paste _In Place" +msgstr "" + +#: ../../po/../src/verbs.cpp:1890 +msgid "Paste objects from clipboard to the original location" +msgstr "" + +#: ../../po/../src/verbs.cpp:1891 +#, fuzzy +msgid "_Delete" +msgstr "Избриши" + +#: ../../po/../src/verbs.cpp:1892 +#, fuzzy +msgid "Delete selection" +msgstr "Избриши" + +#: ../../po/../src/verbs.cpp:1893 +#, fuzzy +msgid "Duplic_ate" +msgstr "Дуплицирај" + +#: ../../po/../src/verbs.cpp:1894 +#, fuzzy +msgid "Duplicate selected objects" +msgstr "Избор" + +#: ../../po/../src/verbs.cpp:1895 +#, fuzzy +msgid "Clo_ne" +msgstr "Затвори" + +#: ../../po/../src/verbs.cpp:1896 +msgid "Create a clone of selected object (a copy linked to the original)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1897 +msgid "Unlin_k Clone" +msgstr "" + +#: ../../po/../src/verbs.cpp:1898 +msgid "Cut the clone's link to its original" +msgstr "" + +#: ../../po/../src/verbs.cpp:1899 +#, fuzzy +msgid "Select _Original" +msgstr "Избор" + +#: ../../po/../src/verbs.cpp:1900 +msgid "Select the object to which the clone is linked" +msgstr "" + +#. TRANSLATORS: Convert selection to a rectangle with tiled pattern fill +#: ../../po/../src/verbs.cpp:1902 +msgid "O_bjects to Pattern" +msgstr "" + +#: ../../po/../src/verbs.cpp:1903 +msgid "Convert selection to a rectangle with tiled pattern fill" +msgstr "" + +#. TRANSLATORS: Extract objects from a tiled pattern fill +#: ../../po/../src/verbs.cpp:1905 +msgid "Pattern to Ob_jects" +msgstr "" + +#: ../../po/../src/verbs.cpp:1906 +msgid "Extract objects from a tiled pattern fill" +msgstr "" + +#: ../../po/../src/verbs.cpp:1907 +#, fuzzy +msgid "Clea_r All" +msgstr "Исчисти ги сите" + +#: ../../po/../src/verbs.cpp:1908 +msgid "Delete all objects from document" +msgstr "" + +#: ../../po/../src/verbs.cpp:1909 +#, fuzzy +msgid "Select Al_l" +msgstr "Избери ги сите" + +#: ../../po/../src/verbs.cpp:1910 +msgid "Select all objects or all nodes" +msgstr "" + +#: ../../po/../src/verbs.cpp:1911 +#, fuzzy +msgid "Select All in All La_yers" +msgstr "Избор" + +#: ../../po/../src/verbs.cpp:1912 +msgid "Select all objects in all visible and unlocked layers" +msgstr "" + +#: ../../po/../src/verbs.cpp:1913 +#, fuzzy +msgid "In_vert Selection" +msgstr "Избор" + +#: ../../po/../src/verbs.cpp:1914 +msgid "Invert selection (unselect what is selected and select everything else)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1915 +msgid "Invert in All Layers" +msgstr "" + +#: ../../po/../src/verbs.cpp:1916 +msgid "Invert selection in all visible and unlocked layers" +msgstr "" + +#: ../../po/../src/verbs.cpp:1917 +#, fuzzy +msgid "D_eselect" +msgstr "Избор" + +#: ../../po/../src/verbs.cpp:1918 +msgid "Deselect any selected objects or nodes" +msgstr "" + +#. Selection +#: ../../po/../src/verbs.cpp:1921 +msgid "Raise to _Top" +msgstr "" + +#: ../../po/../src/verbs.cpp:1922 +msgid "Raise selection to top" +msgstr "" + +#: ../../po/../src/verbs.cpp:1923 +msgid "Lower to _Bottom" +msgstr "" + +#: ../../po/../src/verbs.cpp:1924 +msgid "Lower selection to bottom" +msgstr "" + +#: ../../po/../src/verbs.cpp:1925 +#, fuzzy +msgid "_Raise" +msgstr "Крени" + +#: ../../po/../src/verbs.cpp:1926 +msgid "Raise selection one step" +msgstr "" + +#: ../../po/../src/verbs.cpp:1927 +#, fuzzy +msgid "_Lower" +msgstr "Долни" + +#: ../../po/../src/verbs.cpp:1928 +msgid "Lower selection one step" +msgstr "" + +#: ../../po/../src/verbs.cpp:1929 +#, fuzzy +msgid "_Group" +msgstr "Група" + +#: ../../po/../src/verbs.cpp:1930 +msgid "Group selected objects" +msgstr "" + +#: ../../po/../src/verbs.cpp:1932 +msgid "Ungroup selected groups" +msgstr "" + +#: ../../po/../src/verbs.cpp:1934 +msgid "_Put on Path" +msgstr "" + +#: ../../po/../src/verbs.cpp:1935 +msgid "Put text on path" +msgstr "" + +#: ../../po/../src/verbs.cpp:1936 +msgid "_Remove from Path" +msgstr "" + +#: ../../po/../src/verbs.cpp:1937 +msgid "Remove text from path" +msgstr "" + +#: ../../po/../src/verbs.cpp:1938 +msgid "Remove Manual _Kerns" +msgstr "" + +#. TRANSLATORS: "glyph": An image used in the visual representation of characters; +#. roughly speaking, how a character looks. A font is a set of glyphs. +#: ../../po/../src/verbs.cpp:1941 +msgid "Remove all manual kerns and glyph rotations from a text object" +msgstr "" + +#: ../../po/../src/verbs.cpp:1943 +#, fuzzy +msgid "_Union" +msgstr "Непознато" + +#: ../../po/../src/verbs.cpp:1944 +msgid "Union of selected objects" +msgstr "" + +#: ../../po/../src/verbs.cpp:1945 +#, fuzzy +msgid "_Intersection" +msgstr "Избор" + +#: ../../po/../src/verbs.cpp:1946 +msgid "Intersection of selected objects" +msgstr "" + +#: ../../po/../src/verbs.cpp:1947 +msgid "_Difference" +msgstr "" + +#: ../../po/../src/verbs.cpp:1948 +msgid "Difference of selected objects (bottom minus top)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1949 +#, fuzzy +msgid "E_xclusion" +msgstr "Наставка" + +#: ../../po/../src/verbs.cpp:1950 +msgid "Exclusive OR of selected objects" +msgstr "" + +#: ../../po/../src/verbs.cpp:1951 +msgid "Di_vision" +msgstr "" + +#: ../../po/../src/verbs.cpp:1952 +msgid "Cut the bottom object into pieces" +msgstr "" + +#. TRANSLATORS: "to cut a path" is not the same as "to break a path apart" - see the +#. Advanced tutorial for more info +#: ../../po/../src/verbs.cpp:1955 +msgid "Cut _Path" +msgstr "" + +#: ../../po/../src/verbs.cpp:1956 +msgid "Cut the bottom object's stroke into pieces, removing fill" +msgstr "" + +#. TRANSLATORS: "outset": expand a shape by offsetting the object's path, +#. i.e. by displacing it perpendicular to the path in each point. +#. See also the Advanced Tutorial for explanation. +#: ../../po/../src/verbs.cpp:1960 +#, fuzzy +msgid "Outs_et" +msgstr "Надвор" + +#: ../../po/../src/verbs.cpp:1961 +#, fuzzy +msgid "Outset selected paths" +msgstr "Избор" + +#: ../../po/../src/verbs.cpp:1963 +msgid "O_utset Path by 1 px" +msgstr "" + +#: ../../po/../src/verbs.cpp:1964 +msgid "Outset selected paths by 1 px" +msgstr "" + +#: ../../po/../src/verbs.cpp:1966 +msgid "O_utset Path by 10 px" +msgstr "" + +#: ../../po/../src/verbs.cpp:1967 +msgid "Outset selected paths by 10 px" +msgstr "" + +#. TRANSLATORS: "inset": contract a shape by offsetting the object's path, +#. i.e. by displacing it perpendicular to the path in each point. +#. See also the Advanced Tutorial for explanation. +#: ../../po/../src/verbs.cpp:1971 +msgid "I_nset" +msgstr "" + +#: ../../po/../src/verbs.cpp:1972 +#, fuzzy +msgid "Inset selected paths" +msgstr "Избор" + +#: ../../po/../src/verbs.cpp:1974 +msgid "I_nset Path by 1 px" +msgstr "" + +#: ../../po/../src/verbs.cpp:1975 +#, fuzzy +msgid "Inset selected paths by 1 px" +msgstr "Избор" + +#: ../../po/../src/verbs.cpp:1977 +msgid "I_nset Path by 10 px" +msgstr "" + +#: ../../po/../src/verbs.cpp:1978 +#, fuzzy +msgid "Inset selected paths by 10 px" +msgstr "Избор" + +#: ../../po/../src/verbs.cpp:1980 +msgid "D_ynamic Offset" +msgstr "" + +#: ../../po/../src/verbs.cpp:1980 +msgid "Create a dynamic offset object" +msgstr "" + +#: ../../po/../src/verbs.cpp:1982 +msgid "_Linked Offset" +msgstr "" + +#: ../../po/../src/verbs.cpp:1983 +msgid "Create a dynamic offset object linked to the original path" +msgstr "" + +#: ../../po/../src/verbs.cpp:1985 +msgid "_Stroke to Path" +msgstr "" + +#: ../../po/../src/verbs.cpp:1986 +#, fuzzy +msgid "Convert selected strokes to paths" +msgstr "Избор" + +#: ../../po/../src/verbs.cpp:1987 +msgid "Si_mplify" +msgstr "" + +#: ../../po/../src/verbs.cpp:1988 +msgid "Simplify selected paths by removing extra nodes" +msgstr "" + +#: ../../po/../src/verbs.cpp:1989 +#, fuzzy +msgid "_Reverse" +msgstr "Филтри" + +#: ../../po/../src/verbs.cpp:1990 +msgid "Reverses the direction of selected paths; useful for flipping markers" +msgstr "" + +#. TRANSLATORS: "to trace" means "to convert a bitmap to vector graphics" (to vectorize) +#: ../../po/../src/verbs.cpp:1992 +msgid "_Trace Bitmap" +msgstr "" + +#: ../../po/../src/verbs.cpp:1993 +msgid "Convert bitmap object to paths" +msgstr "" + +#: ../../po/../src/verbs.cpp:1994 +msgid "_Make a Bitmap Copy" +msgstr "" + +#: ../../po/../src/verbs.cpp:1995 +msgid "Export selection to a bitmap and insert it into document" +msgstr "" + +#: ../../po/../src/verbs.cpp:1996 +#, fuzzy +msgid "_Combine" +msgstr "Комбинирај" + +#: ../../po/../src/verbs.cpp:1997 +msgid "Combine several paths into one" +msgstr "" + +#. TRANSLATORS: "to cut a path" is not the same as "to break a path apart" - see the +#. Advanced tutorial for more info +#: ../../po/../src/verbs.cpp:2000 +msgid "Break _Apart" +msgstr "" + +#: ../../po/../src/verbs.cpp:2001 +msgid "Break selected paths into subpaths" +msgstr "" + +#: ../../po/../src/verbs.cpp:2002 +msgid "Gri_d Arrange..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2003 +msgid "Arrange selection in grid pattern" +msgstr "" + +#. Layer +#: ../../po/../src/verbs.cpp:2005 +#, fuzzy +msgid "_Add Layer..." +msgstr "Долни" + +#: ../../po/../src/verbs.cpp:2006 +#, fuzzy +msgid "Create a new layer" +msgstr "Зачувај документ" + +#: ../../po/../src/verbs.cpp:2007 +#, fuzzy +msgid "Re_name Layer..." +msgstr "Избриши" + +#: ../../po/../src/verbs.cpp:2008 +#, fuzzy +msgid "Rename the current layer" +msgstr "Документ" + +#: ../../po/../src/verbs.cpp:2009 +msgid "Switch to Layer Abov_e" +msgstr "" + +#: ../../po/../src/verbs.cpp:2010 +msgid "Switch to the layer above the current" +msgstr "" + +#: ../../po/../src/verbs.cpp:2011 +msgid "Switch to Layer Belo_w" +msgstr "" + +#: ../../po/../src/verbs.cpp:2012 +msgid "Switch to the layer below the current" +msgstr "" + +#: ../../po/../src/verbs.cpp:2013 +#, fuzzy +msgid "Move Selection to Layer Abo_ve" +msgstr "Документ" + +#: ../../po/../src/verbs.cpp:2014 +msgid "Move selection to the layer above the current" +msgstr "" + +#: ../../po/../src/verbs.cpp:2015 +#, fuzzy +msgid "Move Selection to Layer Bel_ow" +msgstr "Документ" + +#: ../../po/../src/verbs.cpp:2016 +msgid "Move selection to the layer below the current" +msgstr "" + +#: ../../po/../src/verbs.cpp:2017 +msgid "Layer to _Top" +msgstr "" + +#: ../../po/../src/verbs.cpp:2018 +msgid "Raise the current layer to the top" +msgstr "" + +#: ../../po/../src/verbs.cpp:2019 +msgid "Layer to _Bottom" +msgstr "" + +#: ../../po/../src/verbs.cpp:2020 +msgid "Lower the current layer to the bottom" +msgstr "" + +#: ../../po/../src/verbs.cpp:2021 +#, fuzzy +msgid "_Raise Layer" +msgstr "Крени" + +#: ../../po/../src/verbs.cpp:2022 +msgid "Raise the current layer" +msgstr "" + +#: ../../po/../src/verbs.cpp:2023 +#, fuzzy +msgid "_Lower Layer" +msgstr "Долни" + +#: ../../po/../src/verbs.cpp:2024 +msgid "Lower the current layer" +msgstr "" + +#: ../../po/../src/verbs.cpp:2025 +#, fuzzy +msgid "_Delete Current Layer" +msgstr "Документ" + +#: ../../po/../src/verbs.cpp:2026 +msgid "Delete the current layer" +msgstr "" + +#. Object +#: ../../po/../src/verbs.cpp:2029 +#, fuzzy +msgid "Rotate _90° CW" +msgstr "Ротирај за 90 степени" + +#: ../../po/../src/verbs.cpp:2030 +#, fuzzy +msgid "Rotate selection 90° clockwise" +msgstr "Ротирај за 90 степени" + +#: ../../po/../src/verbs.cpp:2031 +#, fuzzy +msgid "Rotate 9_0° CCW" +msgstr "Ротирај за 90 степени" + +#: ../../po/../src/verbs.cpp:2032 +#, fuzzy +msgid "Rotate selection 90° counter-clockwise" +msgstr "Ротирај за 90 степени" + +#: ../../po/../src/verbs.cpp:2033 +msgid "Remove _Transformations" +msgstr "" + +#: ../../po/../src/verbs.cpp:2034 +msgid "Remove transformations from object" +msgstr "" + +#: ../../po/../src/verbs.cpp:2035 +msgid "_Object to Path" +msgstr "" + +#: ../../po/../src/verbs.cpp:2036 +#, fuzzy +msgid "Convert selected objects to paths" +msgstr "Избор" + +#: ../../po/../src/verbs.cpp:2037 +msgid "_Flow into Frame" +msgstr "" + +#: ../../po/../src/verbs.cpp:2038 +msgid "Put text into frames" +msgstr "" + +#: ../../po/../src/verbs.cpp:2039 +#, fuzzy +msgid "_Unflow" +msgstr "Врати" + +#: ../../po/../src/verbs.cpp:2040 +msgid "Remove text from frame (creates a single-line text object)" +msgstr "" + +#: ../../po/../src/verbs.cpp:2041 +msgid "_Convert to Text" +msgstr "" + +#: ../../po/../src/verbs.cpp:2042 +msgid "Convert flowed text to regular text objects (preserves appearance)" +msgstr "" + +#: ../../po/../src/verbs.cpp:2044 +#, fuzzy +msgid "Flip _Horizontal" +msgstr "Преврти хоризонтално" + +#: ../../po/../src/verbs.cpp:2044 +#, fuzzy +msgid "Flips selected objects horizontally" +msgstr "Преврти хоризонтално" + +#: ../../po/../src/verbs.cpp:2047 +#, fuzzy +msgid "Flip _Vertical" +msgstr "Преврти вертикално" + +#: ../../po/../src/verbs.cpp:2047 +#, fuzzy +msgid "Flips selected objects vertically" +msgstr "Преврти вертикално" + +#. Tools +#: ../../po/../src/verbs.cpp:2051 +#, fuzzy +msgid "Select" +msgstr "Избор" + +#: ../../po/../src/verbs.cpp:2052 +msgid "Select and transform objects" +msgstr "" + +#: ../../po/../src/verbs.cpp:2053 +#, fuzzy +msgid "Node Edit" +msgstr "Уреди" + +#: ../../po/../src/verbs.cpp:2054 +msgid "Edit path nodes or control handles" +msgstr "" + +#: ../../po/../src/verbs.cpp:2056 +msgid "Create rectangles and squares" +msgstr "" + +#: ../../po/../src/verbs.cpp:2058 +msgid "Create circles, ellipses, and arcs" +msgstr "" + +#: ../../po/../src/verbs.cpp:2060 +msgid "Create stars and polygons" +msgstr "" + +#: ../../po/../src/verbs.cpp:2062 +#, fuzzy +msgid "Create spirals" +msgstr "Спирала" + +#: ../../po/../src/verbs.cpp:2064 +msgid "Draw freehand lines" +msgstr "" + +#: ../../po/../src/verbs.cpp:2066 +msgid "Draw Bezier curves and straight lines" +msgstr "" + +#: ../../po/../src/verbs.cpp:2068 +msgid "Draw calligraphic lines" +msgstr "" + +#: ../../po/../src/verbs.cpp:2070 +msgid "Create and edit text objects" +msgstr "" + +#: ../../po/../src/verbs.cpp:2072 +#, fuzzy +msgid "Create and edit gradients" +msgstr "Зачувај документ" + +#: ../../po/../src/verbs.cpp:2074 +#, fuzzy +msgid "Zoom in or out" +msgstr "Зум" + +#: ../../po/../src/verbs.cpp:2076 +msgid "Pick averaged colors from image" +msgstr "" + +#: ../../po/../src/verbs.cpp:2078 +#, fuzzy +msgid "Create connectors" +msgstr "Зачувај документ" + +#. Tool prefs +#: ../../po/../src/verbs.cpp:2081 +msgid "Selector Preferences" +msgstr "" + +#: ../../po/../src/verbs.cpp:2082 +#, fuzzy +msgid "Open Preferences for the Selector tool" +msgstr "Правоаголник" + +#: ../../po/../src/verbs.cpp:2083 +msgid "Node Tool Preferences" +msgstr "" + +#: ../../po/../src/verbs.cpp:2084 +#, fuzzy +msgid "Open Preferences for the Node tool" +msgstr "Правоаголник" + +#: ../../po/../src/verbs.cpp:2085 +#, fuzzy +msgid "Rectangle Preferences" +msgstr "Правоаголник" + +#: ../../po/../src/verbs.cpp:2086 +#, fuzzy +msgid "Open Preferences for the Rectangle tool" +msgstr "Правоаголник" + +#: ../../po/../src/verbs.cpp:2087 +msgid "Ellipse Preferences" +msgstr "" + +#: ../../po/../src/verbs.cpp:2088 +#, fuzzy +msgid "Open Preferences for the Ellipse tool" +msgstr "Правоаголник" + +#: ../../po/../src/verbs.cpp:2089 +msgid "Star Preferences" +msgstr "" + +#: ../../po/../src/verbs.cpp:2090 +#, fuzzy +msgid "Open Preferences for the Star tool" +msgstr "Правоаголник" + +#: ../../po/../src/verbs.cpp:2091 +msgid "Spiral Preferences" +msgstr "" + +#: ../../po/../src/verbs.cpp:2092 +#, fuzzy +msgid "Open Preferences for the Spiral tool" +msgstr "Правоаголник" + +#: ../../po/../src/verbs.cpp:2093 +msgid "Pencil Preferences" +msgstr "" + +#: ../../po/../src/verbs.cpp:2094 +#, fuzzy +msgid "Open Preferences for the Pencil tool" +msgstr "Правоаголник" + +#: ../../po/../src/verbs.cpp:2095 +msgid "Pen Preferences" +msgstr "" + +#: ../../po/../src/verbs.cpp:2096 +#, fuzzy +msgid "Open Preferences for the Pen tool" +msgstr "Правоаголник" + +#: ../../po/../src/verbs.cpp:2097 +msgid "Calligraphic Preferences" +msgstr "" + +#: ../../po/../src/verbs.cpp:2098 +#, fuzzy +msgid "Open Preferences for the Calligraphy tool" +msgstr "Правоаголник" + +#: ../../po/../src/verbs.cpp:2099 +msgid "Text Preferences" +msgstr "" + +#: ../../po/../src/verbs.cpp:2100 +#, fuzzy +msgid "Open Preferences for the Text tool" +msgstr "Правоаголник" + +#: ../../po/../src/verbs.cpp:2101 +#, fuzzy +msgid "Gradient Preferences" +msgstr "Правоаголник" + +#: ../../po/../src/verbs.cpp:2102 +#, fuzzy +msgid "Open Preferences for the Gradient tool" +msgstr "Правоаголник" + +#: ../../po/../src/verbs.cpp:2103 +msgid "Zoom Preferences" +msgstr "" + +#: ../../po/../src/verbs.cpp:2104 +#, fuzzy +msgid "Open Preferences for the Zoom tool" +msgstr "Правоаголник" + +#: ../../po/../src/verbs.cpp:2105 +msgid "Dropper Preferences" +msgstr "" + +#: ../../po/../src/verbs.cpp:2106 +#, fuzzy +msgid "Open Preferences for the Dropper tool" +msgstr "Правоаголник" + +#: ../../po/../src/verbs.cpp:2107 +#, fuzzy +msgid "Connector Preferences" +msgstr "Правоаголник" + +#: ../../po/../src/verbs.cpp:2108 +#, fuzzy +msgid "Open Preferences for the Connector tool" +msgstr "Правоаголник" + +#. Zoom/View +#: ../../po/../src/verbs.cpp:2111 +#, fuzzy +msgid "Zoom In" +msgstr "Зум" + +#: ../../po/../src/verbs.cpp:2111 +#, fuzzy +msgid "Zoom in" +msgstr "Зум" + +#: ../../po/../src/verbs.cpp:2112 +#, fuzzy +msgid "Zoom Out" +msgstr "Зум" + +#: ../../po/../src/verbs.cpp:2112 +#, fuzzy +msgid "Zoom out" +msgstr "Зум" + +#: ../../po/../src/verbs.cpp:2113 +#, fuzzy +msgid "_Rulers" +msgstr "Филтри" + +#: ../../po/../src/verbs.cpp:2113 +msgid "Show or hide the canvas rulers" +msgstr "" + +#: ../../po/../src/verbs.cpp:2114 +msgid "Scroll_bars" +msgstr "" + +#: ../../po/../src/verbs.cpp:2114 +msgid "Show or hide the canvas scrollbars" +msgstr "" + +#: ../../po/../src/verbs.cpp:2115 +#, fuzzy +msgid "_Grid" +msgstr "Решетка" + +#: ../../po/../src/verbs.cpp:2116 +#, fuzzy +msgid "G_uides" +msgstr "Водичи" + +#: ../../po/../src/verbs.cpp:2117 +msgid "Nex_t Zoom" +msgstr "" + +#: ../../po/../src/verbs.cpp:2117 +msgid "Next zoom (from the history of zooms)" +msgstr "" + +#: ../../po/../src/verbs.cpp:2119 +msgid "Pre_vious Zoom" +msgstr "" + +#: ../../po/../src/verbs.cpp:2119 +msgid "Previous zoom (from the history of zooms)" +msgstr "" + +#: ../../po/../src/verbs.cpp:2121 +#, fuzzy +msgid "Zoom 1:_1" +msgstr "Зум" + +#: ../../po/../src/verbs.cpp:2121 +msgid "Zoom to 1:1" +msgstr "" + +#: ../../po/../src/verbs.cpp:2123 +#, fuzzy +msgid "Zoom 1:_2" +msgstr "Зум" + +#: ../../po/../src/verbs.cpp:2123 +msgid "Zoom to 1:2" +msgstr "" + +#: ../../po/../src/verbs.cpp:2125 +#, fuzzy +msgid "_Zoom 2:1" +msgstr "Зум" + +#: ../../po/../src/verbs.cpp:2125 +msgid "Zoom to 2:1" +msgstr "" + +#: ../../po/../src/verbs.cpp:2128 +msgid "_Fullscreen" +msgstr "" + +#: ../../po/../src/verbs.cpp:2128 +msgid "Stretch this document window to full screen" +msgstr "" + +#: ../../po/../src/verbs.cpp:2131 +#, fuzzy +msgid "Duplic_ate Window" +msgstr "Дуплицирај" + +#: ../../po/../src/verbs.cpp:2131 +msgid "Open a new window with the same document" +msgstr "" + +#: ../../po/../src/verbs.cpp:2133 +#, fuzzy +msgid "_New View Preview" +msgstr "Печати на екран" + +#: ../../po/../src/verbs.cpp:2134 +#, fuzzy +msgid "New View Preview" +msgstr "Печати на екран" + +#. "view_new_preview" +#: ../../po/../src/verbs.cpp:2136 +msgid "_Normal" +msgstr "" + +#: ../../po/../src/verbs.cpp:2137 +msgid "Switch to normal display mode" +msgstr "" + +#: ../../po/../src/verbs.cpp:2138 +#, fuzzy +msgid "_Outline" +msgstr "Затвори" + +#: ../../po/../src/verbs.cpp:2139 +msgid "Switch to outline (wireframe) display mode" +msgstr "" + +#: ../../po/../src/verbs.cpp:2141 +#, fuzzy +msgid "Ico_n Preview" +msgstr "Печати на екран" + +#: ../../po/../src/verbs.cpp:2142 +msgid "Open a window to preview items at different icon resolutions" +msgstr "" + +#: ../../po/../src/verbs.cpp:2144 +msgid "Zoom to fit page in window" +msgstr "" + +#: ../../po/../src/verbs.cpp:2145 +msgid "Page _Width" +msgstr "" + +#: ../../po/../src/verbs.cpp:2146 +msgid "Zoom to fit page width in window" +msgstr "" + +#: ../../po/../src/verbs.cpp:2148 +msgid "Zoom to fit drawing in window" +msgstr "" + +#: ../../po/../src/verbs.cpp:2150 +msgid "Zoom to fit selection in window" +msgstr "" + +#. Dialogs +#: ../../po/../src/verbs.cpp:2153 +msgid "In_kscape Preferences..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2154 +msgid "Global Inkscape preferences" +msgstr "" + +#: ../../po/../src/verbs.cpp:2155 +msgid "_Document Preferences..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2156 +msgid "Preferences saved with the document" +msgstr "" + +#: ../../po/../src/verbs.cpp:2157 +msgid "_Fill and Stroke..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2158 +msgid "Fill and Stroke dialog" +msgstr "" + +#. TRANSLATORS: "Swatches" means: color samples +#: ../../po/../src/verbs.cpp:2160 +#, fuzzy +msgid "S_watches..." +msgstr "Зачувај како..." + +#: ../../po/../src/verbs.cpp:2161 +msgid "View color swatches" +msgstr "" + +#: ../../po/../src/verbs.cpp:2162 +msgid "Transfor_m..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2163 +msgid "Transform dialog" +msgstr "" + +#: ../../po/../src/verbs.cpp:2164 +msgid "_Align and Distribute..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2165 +msgid "Align and Distribute dialog" +msgstr "" + +#: ../../po/../src/verbs.cpp:2166 +msgid "_Text and Font..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2167 +msgid "Text and Font dialog" +msgstr "" + +#: ../../po/../src/verbs.cpp:2168 +msgid "_XML Editor..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2169 +msgid "XML Editor" +msgstr "" + +#: ../../po/../src/verbs.cpp:2170 +#, fuzzy +msgid "_Find..." +msgstr "Печати..." + +#: ../../po/../src/verbs.cpp:2171 +#, fuzzy +msgid "Find objects in document" +msgstr "Зачувај документ" + +#: ../../po/../src/verbs.cpp:2172 +msgid "_Messages..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2173 +msgid "View debug messages" +msgstr "" + +#: ../../po/../src/verbs.cpp:2174 +#, fuzzy +msgid "S_cripts..." +msgstr "Печати..." + +#: ../../po/../src/verbs.cpp:2175 +msgid "Run scripts" +msgstr "" + +#: ../../po/../src/verbs.cpp:2176 +msgid "Show/Hide D_ialogs" +msgstr "" + +#: ../../po/../src/verbs.cpp:2177 +msgid "Show or hide all active dialogs" +msgstr "" + +#. TRANSLATORS: "Tile clones" means: "Create tiled clones" +#: ../../po/../src/verbs.cpp:2179 +msgid "Tile clones..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2180 +msgid "Create and arrange multiple clones of selection" +msgstr "" + +#: ../../po/../src/verbs.cpp:2181 +msgid "_Object Properties..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2182 +msgid "Object Properties dialog" +msgstr "" + +#: ../../po/../src/verbs.cpp:2185 +msgid "_Connect to Jabber server..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2185 +msgid "Connect to a Jabber server" +msgstr "" + +#: ../../po/../src/verbs.cpp:2187 +#, fuzzy +msgid "Share with _user..." +msgstr "Зачувај како..." + +#: ../../po/../src/verbs.cpp:2187 +msgid "Establish a whiteboard session with another Jabber user" +msgstr "" + +#: ../../po/../src/verbs.cpp:2189 +msgid "Share with _chatroom..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2189 +msgid "" +"Join a chatroom to start a new whiteboard session or join one in progress" +msgstr "" + +#: ../../po/../src/verbs.cpp:2191 +msgid "_Dump XML node tracker" +msgstr "" + +#: ../../po/../src/verbs.cpp:2191 +msgid "Dump the contents of the XML tracker to the console" +msgstr "" + +#: ../../po/../src/verbs.cpp:2193 +msgid "_Open session file..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2193 +msgid "Open and browse through records of past whiteboard sessions" +msgstr "" + +#: ../../po/../src/verbs.cpp:2195 +msgid "Session file playback" +msgstr "" + +#: ../../po/../src/verbs.cpp:2197 +msgid "_Disconnect from session" +msgstr "" + +#: ../../po/../src/verbs.cpp:2199 +msgid "Disconnect from _server" +msgstr "" + +#: ../../po/../src/verbs.cpp:2201 +msgid "_Input Devices..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2202 +msgid "Configure extended input devices" +msgstr "" + +#. Help +#: ../../po/../src/verbs.cpp:2205 +msgid "_Keys and Mouse" +msgstr "" + +#: ../../po/../src/verbs.cpp:2206 +msgid "Key and mouse shortcuts reference" +msgstr "" + +#: ../../po/../src/verbs.cpp:2207 +#, fuzzy +msgid "About E_xtensions" +msgstr "Избриши" + +#: ../../po/../src/verbs.cpp:2208 +#, fuzzy +msgid "About Extensions..." +msgstr "Избриши" + +#: ../../po/../src/verbs.cpp:2209 +msgid "About _Memory" +msgstr "" + +#: ../../po/../src/verbs.cpp:2210 +#, fuzzy +msgid "About Memory..." +msgstr "Избриши" + +#: ../../po/../src/verbs.cpp:2211 +msgid "_About Inkscape" +msgstr "" + +#. "help_about" +#. new HelpVerb(SP_VERB_SHOW_LICENSE, "ShowLicense", N_("Modifying or Redistributing Inkscape"), +#. N_("Show license to modify and/or redistribute Inkscape: GNU GPL"), NULL), +#. Tutorials +#: ../../po/../src/verbs.cpp:2217 +msgid "Inkscape: _Basic" +msgstr "" + +#: ../../po/../src/verbs.cpp:2218 +msgid "Getting started with Inkscape" +msgstr "" + +#. "tutorial_basic" +#: ../../po/../src/verbs.cpp:2219 +msgid "Inkscape: _Shapes" +msgstr "" + +#: ../../po/../src/verbs.cpp:2220 +msgid "Using shape tools to create and edit shapes" +msgstr "" + +#: ../../po/../src/verbs.cpp:2221 +msgid "Inkscape: _Advanced" +msgstr "" + +#: ../../po/../src/verbs.cpp:2222 +msgid "Advanced Inkscape topics" +msgstr "" + +#. "tutorial_advanced" +#. TRANSLATORS: "to trace" means "to convert a bitmap to vector graphics" (to vectorize) +#: ../../po/../src/verbs.cpp:2224 +#, fuzzy +msgid "Inkscape: T_racing" +msgstr "Печати на екран" + +#: ../../po/../src/verbs.cpp:2225 +msgid "Using bitmap tracing" +msgstr "" + +#. "tutorial_tracing" +#: ../../po/../src/verbs.cpp:2226 +#, fuzzy +msgid "Inkscape: _Calligraphy" +msgstr "Печати на екран" + +#: ../../po/../src/verbs.cpp:2227 +msgid "Using the Calligraphy pen tool" +msgstr "" + +#: ../../po/../src/verbs.cpp:2228 +msgid "_Elements of Design" +msgstr "" + +#: ../../po/../src/verbs.cpp:2229 +msgid "Principles of design in the tutorial form" +msgstr "" + +#. "tutorial_design" +#: ../../po/../src/verbs.cpp:2230 +msgid "_Tips and Tricks" +msgstr "" + +#: ../../po/../src/verbs.cpp:2231 +msgid "Miscellaneous tips and tricks" +msgstr "" + +#. "tutorial_tips" +#. Effect +#: ../../po/../src/verbs.cpp:2234 +msgid "Previous Effect" +msgstr "" + +#: ../../po/../src/verbs.cpp:2235 +msgid "Repeat the last effect with the same settings" +msgstr "" + +#. "tutorial_tips" +#: ../../po/../src/verbs.cpp:2236 +msgid "Previous Effect Settings..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2237 +msgid "Repeat the last effect with new settings" +msgstr "" + +#: ../../po/../src/widgets/dash-selector.cpp:106 +msgid "Dash pattern" +msgstr "" + +#: ../../po/../src/widgets/dash-selector.cpp:121 +msgid "Pattern offset" +msgstr "" + +#: ../../po/../src/widgets/desktop-widget.cpp:240 +msgid "Zoom drawing if window size changes" +msgstr "" + +#: ../../po/../src/widgets/desktop-widget.cpp:298 +msgid "Cursor coordinates" +msgstr "" + +#. display the initial welcome message in the statusbar +#: ../../po/../src/widgets/desktop-widget.cpp:324 +msgid "" +"Welcome to Inkscape! Use shape or freehand tools to create objects; " +"use selector (arrow) to move or transform them." +msgstr "" + +#: ../../po/../src/widgets/desktop-widget.cpp:372 +#, c-format +msgid "%s: %d - Inkscape" +msgstr "" + +#: ../../po/../src/widgets/desktop-widget.cpp:374 +#, c-format +msgid "%s - Inkscape" +msgstr "" + +#: ../../po/../src/widgets/desktop-widget.cpp:532 +#, c-format +msgid "" +"Save changes to document \"%s\" before " +"closing?\n" +"\n" +"If you close without saving, your changes will be discarded." +msgstr "" + +#: ../../po/../src/widgets/desktop-widget.cpp:548 +#: ../../po/../src/widgets/desktop-widget.cpp:612 +msgid "Close _without saving" +msgstr "" + +#: ../../po/../src/widgets/desktop-widget.cpp:595 +#, c-format +msgid "" +"The file \"%s\" was saved with a " +"format (%s) that may cause data loss!\n" +"\n" +"Do you want to save this file in another format?" +msgstr "" + +#. Family frame +#: ../../po/../src/widgets/font-selector.cpp:156 +#, fuzzy +msgid "Font family" +msgstr "Група на фонтови" + +#. Style frame +#: ../../po/../src/widgets/font-selector.cpp:184 +#, fuzzy +msgid "Style" +msgstr "Стил" + +#: ../../po/../src/widgets/font-selector.cpp:219 +#, fuzzy +msgid "Font size:" +msgstr "Големина на фонт:" + +#. TRANSLATORS: Test string used in text and font dialog (when no +#. * text has been entered) to get a preview of the font. Choose +#. * some representative characters that users of your locale will be +#. * interested in. +#: ../../po/../src/widgets/font-selector.cpp:554 +msgid "AaBbCcIiPpQq12368.;/()" +msgstr "" + +#: ../../po/../src/widgets/gradient-selector.cpp:137 +#: ../../po/../src/widgets/gradient-toolbar.cpp:524 +#, fuzzy +msgid "Duplicate" +msgstr "Дуплицирај" + +#: ../../po/../src/widgets/gradient-selector.cpp:142 +#: ../../po/../src/widgets/gradient-toolbar.cpp:535 +#, fuzzy +msgid "Edit..." +msgstr "Уреди" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/pservers.html#LinearGradientSpreadMethodAttribute +#: ../../po/../src/widgets/gradient-selector.cpp:159 +msgid "" +"Whether to fill with flat color beyond the ends of the gradient vector " +"(spreadMethod=\"pad\"), or repeat the gradient in the same direction " +"(spreadMethod=\"repeat\"), or repeat the gradient in alternating opposite " +"directions (spreadMethod=\"reflect\")" +msgstr "" + +#: ../../po/../src/widgets/gradient-selector.cpp:165 +#, fuzzy +msgid "none" +msgstr "Ништо" + +#: ../../po/../src/widgets/gradient-selector.cpp:169 +#, fuzzy +msgid "reflected" +msgstr "Избор" + +#: ../../po/../src/widgets/gradient-selector.cpp:173 +#, fuzzy +msgid "direct" +msgstr "Уреди" + +#: ../../po/../src/widgets/gradient-selector.cpp:181 +msgid "Repeat:" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:217 +msgid "No gradients" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:226 +msgid "Nothing selected" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:237 +msgid "No gradients in selection" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:247 +msgid "Multiple gradients" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:525 +msgid "" +"If the gradient is used by more than one object, create a copy of it for the " +"selected object(s)" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:536 +msgid "Edit the stops of the gradient" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:593 +#: ../../po/../src/widgets/toolbox.cpp:1103 +#: ../../po/../src/widgets/toolbox.cpp:1192 +#: ../../po/../src/widgets/toolbox.cpp:1485 +#: ../../po/../src/widgets/toolbox.cpp:1534 +#: ../../po/../src/widgets/toolbox.cpp:1766 +#: ../../po/../src/widgets/toolbox.cpp:1801 +#: ../../po/../src/widgets/toolbox.cpp:2331 +#: ../../po/../src/widgets/toolbox.cpp:2370 +msgid "New:" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:606 +#, fuzzy +msgid "Create linear gradient" +msgstr "Зачувај документ" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:620 +msgid "Create radial (elliptic or circular) gradient" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:635 +#, fuzzy +msgid "on" +msgstr "Ништо" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:648 +msgid "Create gradient in the fill" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:662 +msgid "Create gradient in the stroke" +msgstr "" + +#. FIXME: implement averaging of all parameters for multiple selected stars +#. gtk_label_set_markup(GTK_LABEL(l), _("Average:")); +#. FIXME: implement averaging of all parameters for multiple selected +#. gtk_label_set_markup(GTK_LABEL(l), _("Average:")); +#: ../../po/../src/widgets/gradient-toolbar.cpp:676 +#: ../../po/../src/widgets/toolbox.cpp:1105 +#: ../../po/../src/widgets/toolbox.cpp:1124 +#: ../../po/../src/widgets/toolbox.cpp:1493 +#: ../../po/../src/widgets/toolbox.cpp:1518 +#: ../../po/../src/widgets/toolbox.cpp:1768 +#: ../../po/../src/widgets/toolbox.cpp:1787 +#: ../../po/../src/widgets/toolbox.cpp:2334 +#: ../../po/../src/widgets/toolbox.cpp:2354 +msgid "Change:" +msgstr "" + +#: ../../po/../src/widgets/gradient-vector.cpp:269 +msgid "No gradients in document" +msgstr "" + +#: ../../po/../src/widgets/gradient-vector.cpp:275 +msgid "No gradient selected" +msgstr "" + +#: ../../po/../src/widgets/gradient-vector.cpp:532 +msgid "No stops in gradient" +msgstr "" + +#. TRANSLATORS: "Stop" means: a "phase" of a gradient +#: ../../po/../src/widgets/gradient-vector.cpp:794 +msgid "Add stop" +msgstr "" + +#: ../../po/../src/widgets/gradient-vector.cpp:797 +msgid "Add another control stop to gradient" +msgstr "" + +#: ../../po/../src/widgets/gradient-vector.cpp:799 +#, fuzzy +msgid "Delete stop" +msgstr "Избриши" + +#: ../../po/../src/widgets/gradient-vector.cpp:802 +msgid "Delete current control stop from gradient" +msgstr "" + +#. Label +#: ../../po/../src/widgets/gradient-vector.cpp:813 +msgid "Offset:" +msgstr "" + +#. TRANSLATORS: "Stop" means: a "phase" of a gradient +#: ../../po/../src/widgets/gradient-vector.cpp:858 +msgid "Stop Color" +msgstr "" + +#: ../../po/../src/widgets/gradient-vector.cpp:887 +msgid "Gradient editor" +msgstr "" + +#: ../../po/../src/widgets/layer-selector.cpp:119 +#, fuzzy +msgid "Toggle current layer visibility" +msgstr "Документ" + +#: ../../po/../src/widgets/layer-selector.cpp:139 +#, fuzzy +msgid "Lock or unlock current layer" +msgstr "Документ" + +#: ../../po/../src/widgets/layer-selector.cpp:142 +#, fuzzy +msgid "Current layer" +msgstr "Документ" + +#: ../../po/../src/widgets/layer-selector.cpp:553 +msgid "(root)" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:182 +#: ../../po/../src/widgets/paint-selector.cpp:561 +msgid "No paint" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:184 +#: ../../po/../src/widgets/paint-selector.cpp:629 +#, fuzzy +msgid "Flat color" +msgstr "Боја на подвлекување" + +#: ../../po/../src/widgets/paint-selector.cpp:186 +#: ../../po/../src/widgets/paint-selector.cpp:696 +msgid "Linear gradient" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:188 +#: ../../po/../src/widgets/paint-selector.cpp:699 +msgid "Radial gradient" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:192 +msgid "Unset paint (make it undefined so it can be inherited)" +msgstr "" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/painting.html#FillRuleProperty +#: ../../po/../src/widgets/paint-selector.cpp:204 +msgid "" +"Any path self-intersections or subpaths create holes in the fill (fill-rule: " +"evenodd)" +msgstr "" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/painting.html#FillRuleProperty +#: ../../po/../src/widgets/paint-selector.cpp:215 +msgid "" +"Fill is solid unless a subpath is counterdirectional (fill-rule: nonzero)" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:528 +msgid "No objects" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:539 +msgid "Multiple styles" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:550 +msgid "Paint is undefined" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:757 +#, fuzzy +msgid "No patterns in document" +msgstr "Зачувај документ" + +#: ../../po/../src/widgets/paint-selector.cpp:872 +msgid "" +"Use Edit > Object(s) to Pattern to create a new pattern from " +"selection." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:426 +msgid "Now stroke width is scaled when objects are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:428 +msgid "Now stroke width is not scaled when objects are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:436 +msgid "" +"Now rounded rectangle corners are scaled when rectangles are " +"scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:438 +msgid "" +"Now rounded rectangle corners are not scaled when rectangles " +"are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:446 +msgid "" +"Now gradients are transformed along with their objects when " +"those are transformed (moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:448 +msgid "" +"Now gradients remain fixed when objects are transformed " +"(moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:456 +msgid "" +"Now patterns are transformed along with their objects when " +"those are transformed (moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:458 +msgid "" +"Now patterns remain fixed when objects are transformed (moved, " +"scaled, rotated, or skewed)." +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:506 +#, fuzzy +msgid "select_toolbar|X" +msgstr "Избор" + +#: ../../po/../src/widgets/select-toolbar.cpp:506 +msgid "Horizontal coordinate of selection" +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:511 +#, fuzzy +msgid "select_toolbar|Y" +msgstr "Избор" + +#: ../../po/../src/widgets/select-toolbar.cpp:511 +msgid "Vertical coordinate of selection" +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:517 +#, fuzzy +msgid "select_toolbar|W" +msgstr "Избор" + +#: ../../po/../src/widgets/select-toolbar.cpp:517 +msgid "Width of selection" +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:525 +msgid "Change both width and height by the same proportion" +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:534 +#, fuzzy +msgid "select_toolbar|H" +msgstr "Избор" + +#: ../../po/../src/widgets/select-toolbar.cpp:534 +msgid "Height of selection" +msgstr "" + +#: ../../po/../src/widgets/sp-color-gtkselector.cpp:62 +#, fuzzy +msgid "System" +msgstr "Елемент" + +#: ../../po/../src/widgets/sp-color-notebook.cpp:322 +#, fuzzy +msgid "RGBA_:" +msgstr "RGB" + +#: ../../po/../src/widgets/sp-color-notebook.cpp:330 +msgid "Hexadecimal RGBA value of the color" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +#, fuzzy +msgid "RGB" +msgstr "RGB" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "HSL" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +#, fuzzy +msgid "CMYK" +msgstr "CMYK" + +#: ../../po/../src/widgets/sp-color-scales.cpp:397 +msgid "_R" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:398 +#: ../../po/../src/widgets/sp-color-scales.cpp:399 +#, fuzzy +msgid "Red" +msgstr "Повтори" + +#: ../../po/../src/widgets/sp-color-scales.cpp:400 +msgid "_G" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:401 +#: ../../po/../src/widgets/sp-color-scales.cpp:402 +msgid "Green" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:403 +msgid "_B" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:404 +#: ../../po/../src/widgets/sp-color-scales.cpp:405 +#, fuzzy +msgid "Blue" +msgstr "Вредност" + +#. Label +#: ../../po/../src/widgets/sp-color-scales.cpp:406 +#: ../../po/../src/widgets/sp-color-scales.cpp:432 +#: ../../po/../src/widgets/sp-color-scales.cpp:463 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:141 +msgid "_A" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:407 +#: ../../po/../src/widgets/sp-color-scales.cpp:408 +#: ../../po/../src/widgets/sp-color-scales.cpp:433 +#: ../../po/../src/widgets/sp-color-scales.cpp:434 +#: ../../po/../src/widgets/sp-color-scales.cpp:464 +#: ../../po/../src/widgets/sp-color-scales.cpp:465 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:151 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:163 +msgid "Alpha (opacity)" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:423 +msgid "_H" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:424 +#: ../../po/../src/widgets/sp-color-scales.cpp:425 +msgid "Hue" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:426 +msgid "_S" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:427 +#: ../../po/../src/widgets/sp-color-scales.cpp:428 +msgid "Saturation" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:429 +msgid "_L" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:430 +#: ../../po/../src/widgets/sp-color-scales.cpp:431 +#, fuzzy +msgid "Lightness" +msgstr "Висина:" + +#: ../../po/../src/widgets/sp-color-scales.cpp:451 +msgid "_C" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:452 +#: ../../po/../src/widgets/sp-color-scales.cpp:453 +#, fuzzy +msgid "Cyan" +msgstr "Откажи" + +#: ../../po/../src/widgets/sp-color-scales.cpp:454 +msgid "_M" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:455 +#: ../../po/../src/widgets/sp-color-scales.cpp:456 +msgid "Magenta" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:457 +msgid "_Y" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:458 +#: ../../po/../src/widgets/sp-color-scales.cpp:459 +msgid "Yellow" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:460 +msgid "_K" +msgstr "" + +#: ../../po/../src/widgets/sp-color-selector.cpp:71 +msgid "Unnamed" +msgstr "" + +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:68 +msgid "Wheel" +msgstr "" + +#: ../../po/../src/widgets/sp-xmlview-attr-list.cpp:53 +#, fuzzy +msgid "Attribute" +msgstr "Атрибут" + +#: ../../po/../src/widgets/sp-xmlview-attr-list.cpp:54 +#, fuzzy +msgid "Value" +msgstr "Вредност" + +#: ../../po/../src/widgets/toolbox.cpp:424 +msgid "Insert new nodes into selected segments" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:426 +msgid "Delete selected nodes" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:431 +msgid "Join paths at selected nodes" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:433 +msgid "Join paths at selected nodes with new segment" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:436 +msgid "Split path between two non-endpoint nodes" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:439 +msgid "Break path at selected nodes" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:444 +msgid "Make selected nodes corner" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:447 +msgid "Make selected nodes smooth" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:450 +msgid "Make selected nodes symmetric" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:455 +msgid "Make selected segments lines" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:458 +msgid "Make selected segments curves" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1199 +msgid "Polygon" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1206 +msgid "Regular polygon (with one handle) instead of a star" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1218 +msgid "Corners:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1218 +msgid "Number of corners of a polygon or star" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1228 +#, fuzzy +msgid "Spoke ratio:" +msgstr "Ориентација:" + +#. TRANSLATORS: Tip radius of a star is the distance from the center to the farthest handle. +#. Base radius is the same for the closest handle. +#: ../../po/../src/widgets/toolbox.cpp:1231 +msgid "Base radius to tip radius ratio" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1246 +msgid "Rounded:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1246 +msgid "How much rounded are the corners (0 for sharp)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1256 +msgid "Randomized:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1256 +msgid "Scatter randomly the corners and angles" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1269 +#: ../../po/../src/widgets/toolbox.cpp:1838 +#: ../../po/../src/widgets/toolbox.cpp:2061 +#, fuzzy +msgid "Defaults" +msgstr "Номинални" + +#: ../../po/../src/widgets/toolbox.cpp:1270 +#: ../../po/../src/widgets/toolbox.cpp:1839 +#: ../../po/../src/widgets/toolbox.cpp:2062 +msgid "" +"Reset shape parameters to defaults (use Inkscape Preferences > Tools to " +"change defaults)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1544 +msgid "W:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1544 +#, fuzzy +msgid "Width of rectangle" +msgstr "Правоаголник" + +#: ../../po/../src/widgets/toolbox.cpp:1556 +#, fuzzy +msgid "Height of rectangle" +msgstr "Правоаголник" + +#: ../../po/../src/widgets/toolbox.cpp:1568 +msgid "Rx:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1568 +msgid "Horizontal radius of rounded corners" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1578 +msgid "Ry:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1578 +msgid "Vertical radius of rounded corners" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1594 +msgid "Not rounded" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1596 +msgid "Make corners sharp" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1805 +msgid "Turns:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1805 +msgid "Number of revolutions" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1815 +msgid "Divergence:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1815 +msgid "How much denser/sparser are outer revolutions; 1 = uniform" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1825 +msgid "Inner radius:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1825 +msgid "Radius of the innermost revolution (relative to the spiral size)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1957 +msgid "The width of the calligraphic pen (relative to the visible canvas area)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1967 +msgid "Thinning:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1967 +msgid "" +"How much velocity thins the stroke (> 0 makes fast strokes thinner, < 0 " +"makes them broader, 0 makes width independent of velocity)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1980 +msgid "Angle:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1980 +msgid "" +"The angle of the pen's nib (in degrees; 0 = horizontal; has no effect if " +"fixation = 0)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1990 +#, fuzzy +msgid "Fixation:" +msgstr "Ориентација:" + +#: ../../po/../src/widgets/toolbox.cpp:1990 +msgid "" +"How fixed is the pen angle (0 = always perpendicular to stroke direction, 1 " +"= fixed)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2003 +msgid "Mass:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2003 +msgid "How much inertia affects the movement of the pen" +msgstr "" + +#. TRANSLATORS: "drag" means "resistance" here +#: ../../po/../src/widgets/toolbox.cpp:2014 +msgid "Drag:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2014 +msgid "How much resistance affects the movement of the pen" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2034 +msgid "Use the pressure of the input device to alter the width of the pen" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2047 +msgid "Use the tilt of the input device to alter the angle of the pen's nib" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2374 +msgid "Start:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2374 +msgid "The angle (in degrees) from the horizontal to the arc's start point" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2384 +msgid "End:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2384 +msgid "The angle (in degrees) from the horizontal to the arc's end point" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2395 +#, fuzzy +msgid "Open arc" +msgstr "Отвори" + +#: ../../po/../src/widgets/toolbox.cpp:2396 +msgid "" +"Switch between arc (unclosed shape) and segment (closed shape with two radii)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2415 +msgid "Make whole" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2417 +msgid "Make the shape a whole ellipse, not arc or segment" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2644 +msgid "" +"When pressed, picks visible color without alpha and when not pressed, picks " +"color including its alpha" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:3039 +msgid "Make connectors avoid selected objects" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:3043 +msgid "Make connectors ignore selected objects" +msgstr "" + +#. +#. 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 : +#: ../share/extensions/addnodes.inx.h:1 +#, fuzzy +msgid "Add Nodes" +msgstr "Ништо" + +#: ../share/extensions/addnodes.inx.h:2 +msgid "Maximum Segment Length" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:1 +#, fuzzy +msgid "AI Input" +msgstr "Внеси" + +#: ../share/extensions/ai_input.inx.h:2 ../share/extensions/ai_output.inx.h:2 +msgid "Adobe Illustrator (*.ai)" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:3 +msgid "Open files saved with Adobe Illustrator" +msgstr "" + +#: ../share/extensions/ai_output.inx.h:1 +#, fuzzy +msgid "AI Output" +msgstr "Надвор" + +#: ../share/extensions/ai_output.inx.h:3 +msgid "Write Adobe Illustrator" +msgstr "" + +#: ../share/extensions/dia.inx.h:1 +msgid "A diagram created with the program Dia" +msgstr "" + +#: ../share/extensions/dia.inx.h:2 +msgid "Dia Diagram (*.dia)" +msgstr "" + +#: ../share/extensions/dia.inx.h:3 +#, fuzzy +msgid "Dia Input" +msgstr "Внеси" + +#: ../share/extensions/dia.inx.h:4 +msgid "" +"In order to import Dia files, Dia itself must be installed. You can get Dia " +"at http://www.gnome.org/projects/dia/" +msgstr "" + +#: ../share/extensions/dia.inx.h:5 +msgid "" +"The dia2svg.sh script should be installed with your Inkscape distribution. " +"If you do not have it, there is likely to be something wrong with your " +"Inkscape installation." +msgstr "" + +#: ../share/extensions/dots.inx.h:1 +#, fuzzy +msgid "Connect the Dots" +msgstr "Затвори" + +#: ../share/extensions/dots.inx.h:2 +#, fuzzy +msgid "Dot Size" +msgstr "Големина на фонт:" + +#: ../share/extensions/dots.inx.h:3 +#, fuzzy +msgid "Font Size" +msgstr "Големина на фонт:" + +#: ../share/extensions/dropshadow.inx.h:1 +msgid "Color of shadow" +msgstr "" + +#: ../share/extensions/dropshadow.inx.h:2 +msgid "Dropshadow" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:1 +#: ../share/extensions/dxf_output.inx.h:1 +msgid "AutoCAD DXF (*.dxf)" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:2 +#, fuzzy +msgid "DXF Input" +msgstr "Внеси" + +#: ../share/extensions/dxf_input.inx.h:3 +msgid "Import AutoCAD's Document Exchange Format" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:4 +msgid "" +"dxf2svg may come with Inkscape, but is also at http://dxf-svg-convert." +"sourceforge.net/" +msgstr "" + +#: ../share/extensions/dxf_output.inx.h:2 +#, fuzzy +msgid "DXF Output" +msgstr "Надвор" + +#: ../share/extensions/dxf_output.inx.h:3 +msgid "DXF file written by pstoedit" +msgstr "" + +#: ../share/extensions/dxf_output.inx.h:4 +msgid "pstoedit must be installed to run see http://www.pstoedit.net/pstoedit" +msgstr "" + +#: ../share/extensions/embedimage.inx.h:1 +#, fuzzy +msgid "Embed Images" +msgstr "Слика" + +#: ../share/extensions/eps_input.inx.h:1 +#, fuzzy +msgid "EPS Input" +msgstr "Внеси" + +#: ../share/extensions/eps_input.inx.h:2 +msgid "Encapsulated Postscript" +msgstr "" + +#: ../share/extensions/eps_input.inx.h:3 +msgid "Encapsulated Postscript (*.eps)" +msgstr "" + +#: ../share/extensions/epsi_output.inx.h:1 +#, fuzzy +msgid "EPSI Output" +msgstr "Надвор" + +#: ../share/extensions/epsi_output.inx.h:2 +msgid "Encapsulated Postscript Interchange (*.epsi)" +msgstr "" + +#: ../share/extensions/epsi_output.inx.h:3 +msgid "Encapsulated Postscript with a thumbnail" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:1 ../share/extensions/ffms.inx.h:1 +#: ../share/extensions/ffset.inx.h:1 ../share/extensions/ffss.inx.h:1 +#, fuzzy +msgid "Bridge Width" +msgstr "Ширина:" + +#: ../share/extensions/ffmet.inx.h:2 ../share/extensions/ffms.inx.h:2 +msgid "First String Length" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:3 +msgid "FretFind Multi Length ET" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:4 ../share/extensions/ffms.inx.h:4 +#: ../share/extensions/ffset.inx.h:3 ../share/extensions/ffss.inx.h:3 +msgid "Fretboard Edges" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:5 ../share/extensions/ffms.inx.h:5 +msgid "Last String Length" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:6 ../share/extensions/ffms.inx.h:6 +#: ../share/extensions/ffset.inx.h:4 ../share/extensions/ffss.inx.h:4 +msgid "Number of Frets" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:7 ../share/extensions/ffms.inx.h:7 +#: ../share/extensions/ffset.inx.h:5 ../share/extensions/ffss.inx.h:5 +msgid "Number of Strings" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:8 ../share/extensions/ffms.inx.h:8 +#: ../share/extensions/ffset.inx.h:6 ../share/extensions/ffss.inx.h:6 +#, fuzzy +msgid "Nut Width" +msgstr "Ширина:" + +#: ../share/extensions/ffmet.inx.h:9 ../share/extensions/ffms.inx.h:10 +msgid "Perpendicular Distance" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:10 ../share/extensions/ffset.inx.h:7 +msgid "Scale Base (2 for Octave)" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:11 ../share/extensions/ffset.inx.h:9 +msgid "Tones in Scale" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:12 ../share/extensions/ffms.inx.h:12 +#: ../share/extensions/ffset.inx.h:10 ../share/extensions/ffss.inx.h:10 +msgid "px per Unit" +msgstr "" + +#: ../share/extensions/ffms.inx.h:3 +msgid "FretFind Multi Length Scala" +msgstr "" + +#: ../share/extensions/ffms.inx.h:9 ../share/extensions/ffss.inx.h:7 +msgid "Path to Scala *.scl File" +msgstr "" + +#: ../share/extensions/ffms.inx.h:11 +msgid "Tuning (scale step for each string seperated by semicolons)" +msgstr "" + +#: ../share/extensions/ffset.inx.h:2 +msgid "FretFind Single Length ET" +msgstr "" + +#: ../share/extensions/ffset.inx.h:8 ../share/extensions/ffss.inx.h:8 +msgid "Scale Length" +msgstr "" + +#: ../share/extensions/ffss.inx.h:2 +msgid "FretFind Single Length Scala" +msgstr "" + +#: ../share/extensions/ffss.inx.h:9 +msgid "Tuning (Scale step for each string seperated by semicolons)" +msgstr "" + +#: ../share/extensions/handles.inx.h:1 +msgid "Draw Handles" +msgstr "" + +#: ../share/extensions/interp.inx.h:1 +#, fuzzy +msgid "Duplicate Endpaths" +msgstr "Дуплицирај" + +#: ../share/extensions/interp.inx.h:2 +#, fuzzy +msgid "Exponent" +msgstr "Извези" + +#: ../share/extensions/interp.inx.h:3 +msgid "Interpolate" +msgstr "" + +#: ../share/extensions/interp.inx.h:4 +msgid "Interpolate Style (Experimental)" +msgstr "" + +#: ../share/extensions/interp.inx.h:5 +msgid "Interpolation Method" +msgstr "" + +#: ../share/extensions/interp.inx.h:6 +msgid "Interpolation Steps" +msgstr "" + +#: ../share/extensions/kochify.inx.h:1 +msgid "Kochify" +msgstr "" + +#: ../share/extensions/kochify_load.inx.h:1 +msgid "Kochify (Load)" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:1 +#, fuzzy +msgid "Angle" +msgstr "Агол" + +#: ../share/extensions/lindenmayer.inx.h:2 +msgid "Axiom" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:3 +#, fuzzy +msgid "Lindenmayer" +msgstr "Избриши" + +#: ../share/extensions/lindenmayer.inx.h:4 +msgid "Order" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:5 +#, fuzzy +msgid "Rules" +msgstr "Филтри" + +#: ../share/extensions/lindenmayer.inx.h:6 +#, fuzzy +msgid "Step" +msgstr "Стил" + +#: ../share/extensions/motion.inx.h:1 +#, fuzzy +msgid "Direction" +msgstr "Избор" + +#: ../share/extensions/motion.inx.h:2 +msgid "Magnitude" +msgstr "" + +#: ../share/extensions/motion.inx.h:3 +#, fuzzy +msgid "Motion" +msgstr "Избор" + +#: ../share/extensions/pdf_output.inx.h:1 +msgid "Adobe PDF (*.pdf)" +msgstr "" + +#: ../share/extensions/pdf_output.inx.h:2 +msgid "Adobe Portable Document Format" +msgstr "" + +#: ../share/extensions/pdf_output.inx.h:3 +#, fuzzy +msgid "PDF Output" +msgstr "Надвор" + +#: ../share/extensions/ps_input.inx.h:1 +#, fuzzy +msgid "Postscript" +msgstr "Точка" + +#: ../share/extensions/ps_input.inx.h:2 +msgid "Postscript (*.ps)" +msgstr "" + +#: ../share/extensions/ps_input.inx.h:3 +msgid "Postscript Input" +msgstr "" + +#: ../share/extensions/radiusrand.inx.h:1 +#, fuzzy +msgid "Radius" +msgstr "Крени" + +#: ../share/extensions/radiusrand.inx.h:2 +msgid "Radius Randomize" +msgstr "" + +#: ../share/extensions/radiusrand.inx.h:3 +msgid "Randomize Control Points" +msgstr "" + +#: ../share/extensions/radiusrand.inx.h:4 +msgid "Randomize Nodes" +msgstr "" + +#: ../share/extensions/rtree.inx.h:1 +msgid "Initial Size" +msgstr "" + +#: ../share/extensions/rtree.inx.h:2 +msgid "Minimum Size" +msgstr "" + +#: ../share/extensions/rtree.inx.h:3 +msgid "Random Tree" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:1 +msgid "A diagram created with the program Sketch" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:2 +msgid "Sketch Diagram (*.sk)" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:3 +msgid "Sketch Input" +msgstr "" + +#: ../share/extensions/straightseg.inx.h:1 +msgid "Behavior" +msgstr "" + +#: ../share/extensions/straightseg.inx.h:3 +msgid "Segment Straightener" +msgstr "" + +#: ../share/extensions/summersnight.inx.h:1 +msgid "Summer's Night" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:1 +#: ../share/extensions/svgz_output.inx.h:1 +msgid "Compressed Inkscape SVG (*.svgz)" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:2 +#: ../share/extensions/svgz_output.inx.h:2 +msgid "Inkscape's native file format compressed with GZip" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:3 +#, fuzzy +msgid "SVGZ Input" +msgstr "Внеси" + +#: ../share/extensions/svgz_output.inx.h:3 +#, fuzzy +msgid "SVGZ Output" +msgstr "Надвор" + +#: ../share/extensions/txt2svg.inx.h:1 +msgid "ASCII Text" +msgstr "" + +#: ../share/extensions/txt2svg.inx.h:2 +msgid "Text File (*.txt)" +msgstr "" + +#: ../share/extensions/txt2svg.inx.h:3 +#, fuzzy +msgid "Text Input" +msgstr "Внеси" + +#: ../share/extensions/wavy.inx.h:1 +msgid "Calculate first derivative numerically" +msgstr "" + +#: ../share/extensions/wavy.inx.h:2 +msgid "First derivative" +msgstr "" + +#: ../share/extensions/wavy.inx.h:3 +msgid "Function" +msgstr "" + +#: ../share/extensions/wavy.inx.h:4 +msgid "Function Plotter" +msgstr "" + +#: ../share/extensions/wavy.inx.h:5 +msgid "Nodes per period" +msgstr "" + +#: ../share/extensions/wavy.inx.h:6 +msgid "Periods (2*Pi each)" +msgstr "" + +#: ../share/extensions/whirl.inx.h:1 +msgid "Amount of Whirl" +msgstr "" + +#: ../share/extensions/whirl.inx.h:2 +#, fuzzy +msgid "Center X" +msgstr "Преврти вертикално" + +#: ../share/extensions/whirl.inx.h:3 +#, fuzzy +msgid "Center Y" +msgstr "Преврти вертикално" + +#: ../share/extensions/whirl.inx.h:4 +msgid "Direction of Rotation" +msgstr "" + +#: ../share/extensions/whirl.inx.h:5 +msgid "Whirl" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:1 +msgid "A popular graphics file format for clipart" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:2 +msgid "Windows Metafile (*.wmf)" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:3 +msgid "Windows Metafile Input" +msgstr "" + +#, fuzzy +#~ msgid "Custom canvas" +#~ msgstr "Сопствено" + +#, fuzzy +#~ msgid "Arrange Objects" +#~ msgstr "Објект" + +#, fuzzy +#~ msgid "_Credits" +#~ msgstr "Создади" + +#, fuzzy +#~ msgid "Acceleration" +#~ msgstr "Избор" + +#, fuzzy +#~ msgid "Zoom in/out by" +#~ msgstr "Зум" + +#, fuzzy +#~ msgid "Transform" +#~ msgstr "Ориентација:" + +#, fuzzy +#~ msgid "Rotate _90 deg CW" +#~ msgstr "Ротирај за 90 степени" + +#, fuzzy +#~ msgid "Rotate 9_0 deg CCW" +#~ msgstr "Ротирај за 90 степени" + +#, fuzzy +#~ msgid "Flip selection horizontally" +#~ msgstr "Преврти хоризонтално" + +#, fuzzy +#~ msgid "Flip selection vertically" +#~ msgstr "Преврти вертикално" + +#, fuzzy +#~ msgid "Edit" +#~ msgstr "Уреди" + +#, fuzzy +#~ msgid "Add" +#~ msgstr "Додај" + +#, fuzzy +#~ msgid "C_reate" +#~ msgstr "Создади" + +#, fuzzy +#~ msgid "Go to root" +#~ msgstr "Уреди" + +#, fuzzy +#~ msgid "Y" +#~ msgstr "Y:" + +#, fuzzy +#~ msgid "Flatsides:" +#~ msgstr "Големина на фонт:" + +#, fuzzy +#~ msgid "Open:" +#~ msgstr "Отвори" + +#, fuzzy +#~ msgid "Revolutions:" +#~ msgstr "Избор" + +#, fuzzy +#~ msgid "Argument:" +#~ msgstr "Аргумент:" + +#, fuzzy +#~ msgid "Rectangle _Properties" +#~ msgstr "Правоаголник" + +#, fuzzy +#~ msgid "Ellipse _Properties" +#~ msgstr "Правоаголник" + +#, fuzzy +#~ msgid "Extensions Editor" +#~ msgstr "Избриши" + +#, fuzzy +#~ msgid "Preferences" +#~ msgstr "Правоаголник" + +#, fuzzy +#~ msgid "Text Properties" +#~ msgstr "Правоаголник" + +#, fuzzy +#~ msgid "_Export..." +#~ msgstr "Увези" + +#, fuzzy +#~ msgid "_Document Properties" +#~ msgstr "Документ" + +#, fuzzy +#~ msgid "In_kscape Preferences" +#~ msgstr "Правоаголник" + +#, fuzzy +#~ msgid "Select _Original Clone" +#~ msgstr "Избор" + +#, fuzzy +#~ msgid "Tile" +#~ msgstr "Наслов:" + +#, fuzzy +#~ msgid "Select A_ll" +#~ msgstr "Избери ги сите" + +#, fuzzy +#~ msgid "Select Non_e" +#~ msgstr "Избор" + +#, fuzzy +#~ msgid "Zoom _In" +#~ msgstr "Зум" + +#, fuzzy +#~ msgid "Zoom _Out" +#~ msgstr "Зум" + +#, fuzzy +#~ msgid "Pre_vious" +#~ msgstr "Преглед" + +#, fuzzy +#~ msgid "Nex_t" +#~ msgstr "Текст" + +#, fuzzy +#~ msgid "D_uplicate Layer" +#~ msgstr "Дуплицирај" + +#, fuzzy +#~ msgid "_Anchor Layer" +#~ msgstr "Долни" + +#, fuzzy +#~ msgid "_Delete Layer" +#~ msgstr "Избриши" + +#, fuzzy +#~ msgid "Select Ne_xt Layer" +#~ msgstr "Документ" + +#, fuzzy +#~ msgid "Select Pre_vious Layer" +#~ msgstr "Избор" + +#, fuzzy +#~ msgid "Select To_p Layer" +#~ msgstr "Избор" + +#, fuzzy +#~ msgid "Move to Ne_w Layer" +#~ msgstr "Зачувај документ" + +#, fuzzy +#~ msgid "DynaDraw" +#~ msgstr "Цртање" + +#, fuzzy +#~ msgid "Corners" +#~ msgstr "Затвори" + +#, fuzzy +#~ msgid "Delete" +#~ msgstr "Избриши" + +#, fuzzy +#~ msgid "Join" +#~ msgstr "во" + +#, fuzzy +#~ msgid "Delete Segment" +#~ msgstr "Избриши" + +#, fuzzy +#~ msgid "New" +#~ msgstr "Ново" + +#, fuzzy +#~ msgid "Save" +#~ msgstr "Зачувај" + +#, fuzzy +#~ msgid "Save As..." +#~ msgstr "Зачувај како..." + +#, fuzzy +#~ msgid "Import..." +#~ msgstr "Увези" + +#, fuzzy +#~ msgid "Export..." +#~ msgstr "Извези" + +#, fuzzy +#~ msgid "Print..." +#~ msgstr "Печати..." + +#, fuzzy +#~ msgid "Undo" +#~ msgstr "Врати" + +#, fuzzy +#~ msgid "Redo" +#~ msgstr "Повтори" + +#, fuzzy +#~ msgid "Cut" +#~ msgstr "Исечи" + +#, fuzzy +#~ msgid "Copy" +#~ msgstr "Копирај" + +#, fuzzy +#~ msgid "Zoom in (+)" +#~ msgstr "Зум" + +#, fuzzy +#~ msgid "Zoom out (-)" +#~ msgstr "Зум" + +#, fuzzy +#~ msgid "Rotate selection 90° clockwise (Shift+Ctrl+Right)" +#~ msgstr "Ротирај за 90 степени" + +#, fuzzy +#~ msgid "Rotate selection 90° counter-clockwise (Shift+Ctrl+Left)" +#~ msgstr "Ротирај за 90 степени" + +#, fuzzy +#~ msgid "Flip selection horizontally (H)" +#~ msgstr "Преврти хоризонтално" + +#, fuzzy +#~ msgid "Flip selection vertically (V)" +#~ msgstr "Преврти вертикално" + +#, fuzzy +#~ msgid "Node tool" +#~ msgstr "Уреди" + +#, fuzzy +#~ msgid "Zoom tool" +#~ msgstr "Зум" + +#, fuzzy +#~ msgid "Rectangle tool" +#~ msgstr "Правоаголник" + +#, fuzzy +#~ msgid "Spiral tool" +#~ msgstr "Спирала" + +#, fuzzy +#~ msgid "Text tool" +#~ msgstr "Текст" + +#, fuzzy +#~ msgid "URI:" +#~ msgstr "URL:" + +#, fuzzy +#~ msgid "Select All in All Layers" +#~ msgstr "Избор" + +#, fuzzy +#~ msgid "Invert Selection" +#~ msgstr "Избор" + +#, fuzzy +#~ msgid "_Scripts..." +#~ msgstr "Печати..." + +#, fuzzy +#~ msgid "Align and Distribute" +#~ msgstr "Дистрибуција" + +#, fuzzy +#~ msgid "Export Dialog" +#~ msgstr "Извези" + +#, fuzzy +#~ msgid "Inkscape Preferences" +#~ msgstr "Правоаголник" + +#, fuzzy +#~ msgid "Inkscape Preferences Dialog" +#~ msgstr "Правоаголник" + +#, fuzzy +#~ msgid "Text Properties Dialog" +#~ msgstr "Правоаголник" + +#, fuzzy +#~ msgid "Tree Editor" +#~ msgstr "Уреди" + +#, fuzzy +#~ msgid "Row height:" +#~ msgstr "Висина:" + +#, fuzzy +#~ msgid "Column width:" +#~ msgstr "Датотека" + +#, fuzzy +#~ msgid "Inkscape" +#~ msgstr "Печати на екран" + +#, fuzzy +#~ msgid "Minor grid line color:" +#~ msgstr "Боја на мрежата:" + +#, fuzzy +#~ msgid "Grid emphasis color" +#~ msgstr "Боја на решетка" + +#, fuzzy +#~ msgid "Background (also for export):" +#~ msgstr "Боја на решетка" + +#, fuzzy +#~ msgid "Picking colors:" +#~ msgstr "Боја на подвлекување" + +#, fuzzy +#~ msgid "Fill:" +#~ msgstr "Пополни" + +#, fuzzy +#~ msgid "Update Properties" +#~ msgstr "Правоаголник" + +#, fuzzy +#~ msgid "executable" +#~ msgstr "Правоаголник" + +#, fuzzy +#~ msgid "file" +#~ msgstr "Датотека" + +#, fuzzy +#~ msgid "path" +#~ msgstr "Вметни" + +#, fuzzy +#~ msgid "absolute" +#~ msgstr "Вредност" + +#, fuzzy +#~ msgid "Layer Properties" +#~ msgstr "Правоаголник" + +#, fuzzy +#~ msgid "Active" +#~ msgstr "Активен" + +#, fuzzy +#~ msgid "Untitled" +#~ msgstr "Безимено" + +#, fuzzy +#~ msgid "Flatness:" +#~ msgstr "Големина на фонт:" + +#, fuzzy +#~ msgid "Other" +#~ msgstr "Редослед" + +#, fuzzy +#~ msgid "object" +#~ msgstr "Објект" + +#, fuzzy +#~ msgid "Active group" +#~ msgstr "Активен" + +#, fuzzy +#~ msgid "Rotate by %0.2f deg" +#~ msgstr "Ротирај за 90 степени" + +#, fuzzy +#~ msgid "typeset object" +#~ msgstr "Објект" + +#, fuzzy +#~ msgid "Rect" +#~ msgstr "Правоаголник" + +#, fuzzy +#~ msgid "meters" +#~ msgstr "метри" + +#, fuzzy +#~ msgid "User" +#~ msgstr "Корисник" + +#, fuzzy +#~ msgid "Ru_lers" +#~ msgstr "Филтри" + +#, fuzzy +#~ msgid "Value:" +#~ msgstr "Вредност:" + +#, fuzzy +#~ msgid "Position and size" +#~ msgstr "Позиција и големина" + +#, fuzzy +#~ msgid "In" +#~ msgstr "Во" + +#, fuzzy +#~ msgid "1:1" +#~ msgstr "1:1" + +#, fuzzy +#~ msgid "Page layout" +#~ msgstr "Изглед на страницата" + +#, fuzzy +#~ msgid "Size and Position" +#~ msgstr "Големина и позиција" diff --git a/po/nb.po b/po/nb.po new file mode 100644 index 000000000..0f3f77da3 --- /dev/null +++ b/po/nb.po @@ -0,0 +1,10881 @@ +# Norwegian translation of sodipodi (bokmÃ¥l dialect). +# Copyright © 2000-2002 Free Software Foundation, Inc. +# Kjartan Maraas , 2000-2002. +# +msgid "" +msgstr "" +"Project-Id-Version: sodipodi 0.25\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2005-12-04 11:51-0800\n" +"PO-Revision-Date: 2003-01-25 00:49+0100\n" +"Last-Translator: Kjartan Maraas \n" +"Language-Team: Norwegian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8-bit\n" + +#: ../inkscape.desktop.in.h:1 +msgid "Create and edit Scalable Vector Graphics images" +msgstr "" + +#: ../inkscape.desktop.in.h:2 +#, fuzzy +msgid "Inkscape SVG Vector Illustrator" +msgstr "Vektorillustrator" + +#: ../../po/../src/arc-context.cpp:350 +msgid "" +"Ctrl: make circle or integer-ratio ellipse, snap arc/segment angle" +msgstr "" + +#: ../../po/../src/arc-context.cpp:351 ../../po/../src/rect-context.cpp:388 +msgid "Shift: draw around the starting point" +msgstr "" + +#: ../../po/../src/arc-context.cpp:413 +#: ../../po/../src/connector-context.cpp:493 +#: ../../po/../src/dyna-draw-context.cpp:506 +#: ../../po/../src/pen-context.cpp:329 ../../po/../src/pencil-context.cpp:208 +#: ../../po/../src/rect-context.cpp:452 ../../po/../src/spiral-context.cpp:421 +#: ../../po/../src/star-context.cpp:427 +msgid "Current layer is hidden. Unhide it to be able to draw on it." +msgstr "" + +#: ../../po/../src/arc-context.cpp:417 +#: ../../po/../src/connector-context.cpp:497 +#: ../../po/../src/dyna-draw-context.cpp:510 +#: ../../po/../src/pen-context.cpp:336 ../../po/../src/pencil-context.cpp:212 +#: ../../po/../src/rect-context.cpp:456 ../../po/../src/spiral-context.cpp:426 +#: ../../po/../src/star-context.cpp:431 +msgid "Current layer is locked. Unlock it to be able to draw on it." +msgstr "" + +#: ../../po/../src/arc-context.cpp:496 +#, c-format +msgid "" +"Ellipse: %s × %s; with Ctrl to make circle or integer-" +"ratio ellipse; with Shift to draw around the starting point" +msgstr "" + +#: ../../po/../src/connector-context.cpp:518 +#, fuzzy +msgid "Creating new connector" +msgstr "Opprett nytt SVG-dokument" + +#: ../../po/../src/connector-context.cpp:939 +#, fuzzy +msgid "Finishing connector" +msgstr "FrihÃ¥nd" + +#: ../../po/../src/connector-context.cpp:1108 +msgid "Connection point: click or drag to create a new connector" +msgstr "" + +#: ../../po/../src/connector-context.cpp:1185 +msgid "Connector endpoint: drag to reroute or connect to new shapes" +msgstr "" + +#: ../../po/../src/connector-context.cpp:1278 +#, fuzzy +msgid "Select at least one non-connector object." +msgstr "Ingen gradienter i dokumentet" + +#: ../../po/../src/desktop-events.cpp:238 +#, c-format +msgid "%s at %s" +msgstr "" + +#. TRANSLATORS: This string appears when double-clicking on a guide. +#. This is the distance by which the guide is to be moved. +#: ../../po/../src/desktop-events.cpp:277 +#, fuzzy +msgid " relative by " +msgstr "Relativ flytting" + +#. TRANSLATORS: This string appears when double-clicking on a guide. +#. This is the target location where the guide is to be moved. +#: ../../po/../src/desktop-events.cpp:282 +#: ../../po/../src/desktop-events.cpp:395 +msgid " absolute to " +msgstr "" + +#. create dialog +#: ../../po/../src/desktop-events.cpp:348 +#, fuzzy +msgid "Guideline" +msgstr "Farge pÃ¥ retningslinje" + +#: ../../po/../src/desktop-events.cpp:432 +#, fuzzy, c-format +msgid "Move %s" +msgstr "Flytt" + +#: ../../po/../src/desktop.cpp:678 +msgid "No previous zoom." +msgstr "" + +#: ../../po/../src/desktop.cpp:703 +msgid "No next zoom." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:182 +#, fuzzy +msgid "Nothing selected." +msgstr "Sist valgte" + +#: ../../po/../src/dialogs/clonetiler.cpp:188 +msgid "More than one object selected." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:195 +#, c-format +msgid "Object has %d tiled clones." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:200 +msgid "Object has no tiled clones." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:865 +#, fuzzy +msgid "Select one object whose tiled clones to unclump." +msgstr "Klipp ut valgte objekter til utklippstavlen" + +#: ../../po/../src/dialogs/clonetiler.cpp:916 +#, fuzzy +msgid "Select one object whose tiled clones to remove." +msgstr "Klipp ut valgte objekter til utklippstavlen" + +#: ../../po/../src/dialogs/clonetiler.cpp:984 +#: ../../po/../src/selection-chemistry.cpp:1774 +#, fuzzy +msgid "Select an object to clone." +msgstr "Klipp ut valgte objekter til utklippstavlen" + +#: ../../po/../src/dialogs/clonetiler.cpp:990 +#: ../../po/../src/selection-chemistry.cpp:1780 +msgid "" +"If you want to clone several objects, group them and clone the " +"group." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1484 +msgid "Per row:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1497 +#, fuzzy +msgid "Per column:" +msgstr "Ingen gradient valgt" + +#: ../../po/../src/dialogs/clonetiler.cpp:1505 +#, fuzzy +msgid "Randomize:" +msgstr "Sist valgte" + +#: ../../po/../src/dialogs/clonetiler.cpp:1656 +msgid "_Symmetry" +msgstr "" + +#. TRANSLATORS: For the following 17 symmetry groups, see +#. * http://www.bib.ulb.ac.be/coursmath/doc/17.htm (visual examples); +#. * http://www.clarku.edu/~djoyce/wallpaper/seventeen.html (English vocabulary); or +#. * http://membres.lycos.fr/villemingerard/Geometri/Sym1D.htm (French vocabulary). +#. +#: ../../po/../src/dialogs/clonetiler.cpp:1664 +msgid "Select one of the 17 symmetry groups for the tiling" +msgstr "" + +#. TRANSLATORS: "translation" means "shift" / "displacement" here. +#: ../../po/../src/dialogs/clonetiler.cpp:1675 +msgid "P1: simple translation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1676 +msgid "P2: 180° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1677 +msgid "PM: reflection" +msgstr "" + +#. TRANSLATORS: "glide reflection" is a reflection and a translation combined. +#. For more info, see http://mathforum.org/sum95/suzanne/symsusan.html +#: ../../po/../src/dialogs/clonetiler.cpp:1680 +msgid "PG: glide reflection" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1681 +msgid "CM: reflection + glide reflection" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1682 +msgid "PMM: reflection + reflection" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1683 +msgid "PMG: reflection + 180° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1684 +msgid "PGG: glide reflection + 180° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1685 +msgid "CMM: reflection + reflection + 180° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1686 +msgid "P4: 90° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1687 +msgid "P4M: 90° rotation + 45° reflection" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1688 +msgid "P4G: 90° rotation + 90° reflection" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1689 +msgid "P3: 120° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1690 +msgid "P31M: reflection + 120° rotation, dense" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1691 +msgid "P3M1: reflection + 120° rotation, sparse" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1692 +msgid "P6: 60° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1693 +msgid "P6M: reflection + 60° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1721 +msgid "S_hift" +msgstr "" + +#. TRANSLATORS: "shift" means: the tiles will be shifted (offset) horizontally by this amount +#: ../../po/../src/dialogs/clonetiler.cpp:1731 +#, no-c-format +msgid "Shift X:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1739 +#, no-c-format +msgid "Horizontal shift per row (in % of tile width)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1747 +#, no-c-format +msgid "Horizontal shift per column (in % of tile width)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1754 +msgid "Randomize the horizontal shift by this percentage" +msgstr "" + +#. TRANSLATORS: "shift" means: the tiles will be shifted (offset) vertically by this amount +#: ../../po/../src/dialogs/clonetiler.cpp:1764 +#, no-c-format +msgid "Shift Y:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1772 +#, no-c-format +msgid "Vertical shift per row (in % of tile height)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1780 +#, no-c-format +msgid "Vertical shift per column (in % of tile height)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1787 +msgid "Randomize the vertical shift by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1795 +msgid "Exponent:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1802 +msgid "Whether rows are spaced evenly (1), converge (<1) or diverge (>1)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1809 +msgid "Whether columns are spaced evenly (1), converge (<1) or diverge (>1)" +msgstr "" + +#. TRANSLATORS: "Alternate" is a verb here +#: ../../po/../src/dialogs/clonetiler.cpp:1817 +#: ../../po/../src/dialogs/clonetiler.cpp:1907 +#: ../../po/../src/dialogs/clonetiler.cpp:1966 +#: ../../po/../src/dialogs/clonetiler.cpp:2022 +#: ../../po/../src/dialogs/clonetiler.cpp:2153 +msgid "Alternate:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1823 +msgid "Alternate the sign of shifts for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1828 +msgid "Alternate the sign of shifts for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1837 +#, fuzzy +msgid "Sc_ale" +msgstr "Skaler" + +#: ../../po/../src/dialogs/clonetiler.cpp:1845 +#, fuzzy +msgid "Scale X:" +msgstr "Rektangel" + +#: ../../po/../src/dialogs/clonetiler.cpp:1853 +#, no-c-format +msgid "Horizontal scale per row (in % of tile width)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1861 +#, no-c-format +msgid "Horizontal scale per column (in % of tile width)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1868 +msgid "Randomize the horizontal scale by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1876 +#, fuzzy +msgid "Scale Y:" +msgstr "Rektangel" + +#: ../../po/../src/dialogs/clonetiler.cpp:1884 +#, no-c-format +msgid "Vertical scale per row (in % of tile height)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1892 +#, no-c-format +msgid "Vertical scale per column (in % of tile height)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1899 +msgid "Randomize the vertical scale by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1913 +msgid "Alternate the sign of scales for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1918 +msgid "Alternate the sign of scales for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1927 +#, fuzzy +msgid "_Rotation" +msgstr "Vending:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1935 +#, fuzzy +msgid "Angle:" +msgstr "Rektangel" + +#: ../../po/../src/dialogs/clonetiler.cpp:1943 +#, no-c-format +msgid "Rotate tiles by this angle for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1951 +#, no-c-format +msgid "Rotate tiles by this angle for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1958 +msgid "Randomize the rotation angle by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1972 +msgid "Alternate the rotation direction for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1977 +msgid "Alternate the rotation direction for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1985 +#, fuzzy +msgid "_Opacity" +msgstr "Ugjennomsiktighet" + +#: ../../po/../src/dialogs/clonetiler.cpp:1993 +msgid "Fade out:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2000 +msgid "Decrease tile opacity by this percentage for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2007 +msgid "Decrease tile opacity by this percentage for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2014 +msgid "Randomize the tile opacity by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2028 +msgid "Alternate the sign of opacity change for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2033 +msgid "Alternate the sign of opacity change for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2041 +#, fuzzy +msgid "Co_lor" +msgstr "Lukk" + +#: ../../po/../src/dialogs/clonetiler.cpp:2046 +#, fuzzy +msgid "Initial color: " +msgstr "Farge pÃ¥ rutenett:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2050 +msgid "Initial color of tiled clones" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2050 +msgid "" +"Initial color for clones (works only if the original has unset fill or " +"stroke)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2065 +msgid "H:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2072 +msgid "Change the tile hue by this percentage for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2079 +msgid "Change the tile hue by this percentage for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2086 +msgid "Randomize the tile hue by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2095 +msgid "S:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2102 +msgid "Change the color saturation by this percentage for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2109 +msgid "Change the color saturation by this percentage for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2116 +msgid "Randomize the color saturation by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2124 +#, fuzzy +msgid "L:" +msgstr "Lenke til %s" + +#: ../../po/../src/dialogs/clonetiler.cpp:2131 +msgid "Change the color lightness by this percentage for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2138 +msgid "Change the color lightness by this percentage for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2145 +msgid "Randomize the color lightness by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2159 +msgid "Alternate the sign of color changes for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2164 +msgid "Alternate the sign of color changes for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2172 +#, fuzzy +msgid "_Trace" +msgstr "Spor" + +#: ../../po/../src/dialogs/clonetiler.cpp:2179 +msgid "Trace the drawing under the tiles" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2183 +msgid "" +"For each clone, pick a value from the drawing in that clone's location and " +"apply it to the clone" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2197 +msgid "1. Pick from the drawing:" +msgstr "" + +#. ----Hbox2 +#: ../../po/../src/dialogs/clonetiler.cpp:2208 +#: ../../po/../src/dialogs/clonetiler.cpp:2355 +#: ../../po/../src/ui/dialog/tracedialog.cpp:445 +#, fuzzy +msgid "Color" +msgstr "Lukk" + +#: ../../po/../src/dialogs/clonetiler.cpp:2209 +msgid "Pick the visible color and opacity" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2216 +#: ../../po/../src/dialogs/clonetiler.cpp:2365 +#: ../share/extensions/dropshadow.inx.h:3 +#, fuzzy +msgid "Opacity" +msgstr "Ugjennomsiktighet" + +#: ../../po/../src/dialogs/clonetiler.cpp:2217 +msgid "Pick the total accumulated opacity" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2224 +msgid "R" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2225 +msgid "Pick the Red component of the color" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2232 +msgid "G" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2233 +msgid "Pick the Green component of the color" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2240 +msgid "B" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2241 +msgid "Pick the Blue component of the color" +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2250 +msgid "clonetiler|H" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2251 +msgid "Pick the hue of the color" +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2260 +msgid "clonetiler|S" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2261 +msgid "Pick the saturation of the color" +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2270 +msgid "clonetiler|L" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2271 +msgid "Pick the lightness of the color" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2281 +msgid "2. Tweak the picked value:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2291 +msgid "Gamma-correct:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2296 +msgid "Shift the mid-range of the picked value upwards (>0) or downwards (<0)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2303 +msgid "Randomize:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2308 +msgid "Randomize the picked value by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2315 +#, fuzzy +msgid "Invert:" +msgstr "Punkt" + +#: ../../po/../src/dialogs/clonetiler.cpp:2319 +msgid "Invert the picked value" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2325 +msgid "3. Apply the value to the clones':" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2335 +#, fuzzy +msgid "Presence" +msgstr "Preserver" + +#: ../../po/../src/dialogs/clonetiler.cpp:2338 +msgid "" +"Each clone is created with the probability determined by the picked value in " +"that point" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2345 +#, fuzzy +msgid "Size" +msgstr "Sider:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2348 +msgid "Each clone's size is determined by the picked value in that point" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2358 +msgid "" +"Each clone is painted by the picked color (the original must have unset fill " +"or stroke)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2368 +msgid "Each clone's opacity is determined by the picked value in that point" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2395 +msgid "How many rows in the tiling" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2415 +msgid "How many columns in the tiling" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2445 +msgid "Width of the rectangle to be filled" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2470 +msgid "Height of the rectangle to be filled" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2485 +#, fuzzy +msgid "Rows, columns: " +msgstr "Lukk" + +#: ../../po/../src/dialogs/clonetiler.cpp:2486 +msgid "Create the specified number of rows and columns" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2495 +msgid "Width, height: " +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2496 +msgid "Fill the specified width and height with the tiling" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2512 +#, fuzzy +msgid "Use saved size and position of the tile" +msgstr "Objektstørrelse og posisjon" + +#: ../../po/../src/dialogs/clonetiler.cpp:2515 +msgid "" +"Pretend that the size and position of the tile are the same as the last time " +"you tiled it (if any), instead of using the current size" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2539 +#, fuzzy +msgid " _Create " +msgstr "Rektangel" + +#: ../../po/../src/dialogs/clonetiler.cpp:2541 +msgid "Create and tile the clones of the selection" +msgstr "" + +#. TRANSLATORS: if a group of objects are "clumped" together, then they +#. are unevenly spread in the given amount of space - as shown in the +#. diagrams on the left in the following screenshot: +#. http://www.inkscape.org/screenshots/gallery/inkscape-0.42-CVS-tiles-unclump.png +#. So unclumping is the process of spreading a number of objects out more evenly. +#: ../../po/../src/dialogs/clonetiler.cpp:2556 +msgid " _Unclump " +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2557 +msgid "Spread out clones to reduce clumping; can be applied repeatedly" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2563 +#, fuzzy +msgid " Re_move " +msgstr "Fjern lenke" + +#: ../../po/../src/dialogs/clonetiler.cpp:2564 +msgid "Remove existing tiled clones of the selected object (siblings only)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2580 +#, fuzzy +msgid " R_eset " +msgstr "Fjern lenke" + +#. TRANSLATORS: "change" is a noun here +#: ../../po/../src/dialogs/clonetiler.cpp:2582 +msgid "" +"Reset all shifts, scales, rotates, opacity and color changes in the dialog " +"to zero" +msgstr "" + +#: ../../po/../src/dialogs/color-picker.cpp:280 +msgid "Close" +msgstr "Lukk" + +#: ../../po/../src/dialogs/debugdialog.cpp:138 +msgid "Messages" +msgstr "" + +#. ## Add a menu for clear() +#: ../../po/../src/dialogs/debugdialog.cpp:144 +#: ../../po/../src/menus-skeleton.h:16 +#: ../../po/../src/ui/dialog/messages.cpp:56 +#: ../../po/../src/ui/dialog/scriptdialog.cpp:181 +#, fuzzy +msgid "_File" +msgstr "Fil" + +#. TRANSLATORS: "Clear" is a verb here +#: ../../po/../src/dialogs/debugdialog.cpp:145 +#: ../../po/../src/dialogs/find.cpp:753 +#: ../../po/../src/ui/dialog/messages.cpp:57 +#: ../../po/../src/ui/dialog/scriptdialog.cpp:182 +#, fuzzy +msgid "_Clear" +msgstr "Lukk" + +#: ../../po/../src/dialogs/debugdialog.cpp:147 +#: ../../po/../src/ui/dialog/messages.cpp:59 +msgid "Capture log messages" +msgstr "" + +#: ../../po/../src/dialogs/debugdialog.cpp:149 +#: ../../po/../src/ui/dialog/messages.cpp:61 +msgid "Release log messages" +msgstr "" + +#. Notebook tab +#: ../../po/../src/dialogs/desktop-properties.cpp:909 +#: ../../po/../src/ui/dialog/document-preferences.cpp:89 +#: ../../po/../src/ui/widget/panel.cpp:107 +msgid "Grid" +msgstr "Rutenett" + +#. Checkbuttons +#. / \todo FIXME: gray out snapping when grid is off +#. / \todo FIXME: gray out snapping when grid is off. +#. / Dissenting view: you want snapping without grid. +#: ../../po/../src/dialogs/desktop-properties.cpp:917 +#: ../../po/../src/ui/dialog/document-preferences.cpp:179 +msgid "Show grid" +msgstr "Vis rutenett" + +#: ../../po/../src/dialogs/desktop-properties.cpp:917 +#: ../../po/../src/ui/dialog/document-preferences.cpp:179 +#: ../../po/../src/verbs.cpp:2115 +#, fuzzy +msgid "Show or hide grid" +msgstr "Vis rutenett" + +#: ../../po/../src/dialogs/desktop-properties.cpp:918 +#: ../../po/../src/ui/dialog/document-preferences.cpp:180 +#, fuzzy +msgid "Snap bounding boxes to grid" +msgstr "Fest til rutenett" + +#: ../../po/../src/dialogs/desktop-properties.cpp:918 +#: ../../po/../src/dialogs/desktop-properties.cpp:1001 +#: ../../po/../src/ui/dialog/document-preferences.cpp:181 +#: ../../po/../src/ui/dialog/document-preferences.cpp:236 +msgid "Snap the edges of the object bounding boxes" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:919 +#: ../../po/../src/ui/dialog/document-preferences.cpp:183 +#, fuzzy +msgid "Snap nodes to grid" +msgstr "Fest til rutenett" + +#: ../../po/../src/dialogs/desktop-properties.cpp:919 +#: ../../po/../src/dialogs/desktop-properties.cpp:1002 +#: ../../po/../src/ui/dialog/document-preferences.cpp:184 +#: ../../po/../src/ui/dialog/document-preferences.cpp:239 +msgid "Snap path nodes, text baselines, ellipse centers, etc." +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:937 +#: ../../po/../src/ui/dialog/document-preferences.cpp:186 +msgid "Grid units:" +msgstr "Enhet for rutenett:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:939 +#: ../../po/../src/ui/dialog/document-preferences.cpp:187 +msgid "Origin X:" +msgstr "Opprinnelse X:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:942 +#: ../../po/../src/ui/dialog/document-preferences.cpp:189 +msgid "Origin Y:" +msgstr "Opprinnelse Y:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:945 +#: ../../po/../src/ui/dialog/document-preferences.cpp:191 +msgid "Spacing X:" +msgstr "Mellomrom X:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:948 +#: ../../po/../src/ui/dialog/document-preferences.cpp:193 +msgid "Spacing Y:" +msgstr "Mellomrom Y:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:952 +#: ../../po/../src/dialogs/desktop-properties.cpp:1013 +#: ../../po/../src/ui/dialog/document-preferences.cpp:195 +#: ../../po/../src/ui/dialog/document-preferences.cpp:241 +msgid "Snap units:" +msgstr "Enheter for festing:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:955 +#: ../../po/../src/dialogs/desktop-properties.cpp:1016 +#: ../../po/../src/ui/dialog/document-preferences.cpp:196 +#: ../../po/../src/ui/dialog/document-preferences.cpp:242 +msgid "Snap distance:" +msgstr "Festeavstand:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:958 +#: ../../po/../src/ui/dialog/document-preferences.cpp:199 +#, fuzzy +msgid "Grid line color:" +msgstr "Farge pÃ¥ retningslinje" + +#: ../../po/../src/dialogs/desktop-properties.cpp:959 +#: ../../po/../src/ui/dialog/document-preferences.cpp:199 +#, fuzzy +msgid "Grid line color" +msgstr "Farge pÃ¥ retningslinje" + +#: ../../po/../src/dialogs/desktop-properties.cpp:959 +#: ../../po/../src/ui/dialog/document-preferences.cpp:200 +#, fuzzy +msgid "Color of grid lines" +msgstr "Mellomrom X:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:961 +#: ../../po/../src/ui/dialog/document-preferences.cpp:201 +#, fuzzy +msgid "Major grid line color:" +msgstr "Farge pÃ¥ retningslinje" + +#: ../../po/../src/dialogs/desktop-properties.cpp:962 +#: ../../po/../src/ui/dialog/document-preferences.cpp:201 +#, fuzzy +msgid "Major grid line color" +msgstr "Farge pÃ¥ retningslinje" + +#: ../../po/../src/dialogs/desktop-properties.cpp:962 +#: ../../po/../src/ui/dialog/document-preferences.cpp:202 +msgid "Color of the major (highlighted) grid lines" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:965 +#: ../../po/../src/ui/dialog/document-preferences.cpp:204 +#, fuzzy +msgid "Major grid line every:" +msgstr "Farge pÃ¥ retningslinje" + +#. TRANSLATORS: This belongs to the "Major grid line every:" string, +#. see grid settings in the "Document Preferences" dialog +#: ../../po/../src/dialogs/desktop-properties.cpp:977 +#: ../../po/../src/ui/dialog/document-preferences.cpp:204 +#, fuzzy +msgid "lines" +msgstr "Lukk" + +#. Guidelines page +#: ../../po/../src/dialogs/desktop-properties.cpp:991 +#: ../../po/../src/ui/dialog/document-preferences.cpp:90 +msgid "Guides" +msgstr "Rettesnorer" + +#. / \todo FIXME: gray out snapping when guides are off +#. / Dissenting view: you want snapping without guides. +#: ../../po/../src/dialogs/desktop-properties.cpp:1000 +#: ../../po/../src/ui/dialog/document-preferences.cpp:234 +msgid "Show guides" +msgstr "Vis rutenett" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1000 +#: ../../po/../src/ui/dialog/document-preferences.cpp:234 +#: ../../po/../src/verbs.cpp:2116 +#, fuzzy +msgid "Show or hide guides" +msgstr "Vis rutenett" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1001 +#: ../../po/../src/ui/dialog/document-preferences.cpp:235 +#, fuzzy +msgid "Snap bounding boxes to guides" +msgstr "Fest til guider" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1002 +#: ../../po/../src/ui/dialog/document-preferences.cpp:238 +#, fuzzy +msgid "Snap points to guides" +msgstr "Fest til rutenett" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1020 +#: ../../po/../src/ui/dialog/document-preferences.cpp:243 +#, fuzzy +msgid "Guide color:" +msgstr "Rutenettfarge:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1021 +#: ../../po/../src/ui/dialog/document-preferences.cpp:243 +msgid "Guideline color" +msgstr "Farge pÃ¥ retningslinje" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1021 +#: ../../po/../src/ui/dialog/document-preferences.cpp:244 +#, fuzzy +msgid "Color of guidelines" +msgstr "Vend valgte objekter horisontalt" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1023 +#: ../../po/../src/ui/dialog/document-preferences.cpp:245 +msgid "Highlight color:" +msgstr "Merk farge:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1024 +#: ../../po/../src/ui/dialog/document-preferences.cpp:245 +msgid "Highlighted guideline color" +msgstr "Uthevet farge for retningslinje" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1024 +#: ../../po/../src/ui/dialog/document-preferences.cpp:246 +msgid "Color of a guideline when it is under mouse" +msgstr "" + +#. Page page +#: ../../po/../src/dialogs/desktop-properties.cpp:1029 +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:855 +#: ../../po/../src/ui/dialog/document-preferences.cpp:88 +#: ../../po/../src/widgets/desktop-widget.cpp:1061 +msgid "Page" +msgstr "Side" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1039 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +#, fuzzy +msgid "Background:" +msgstr "Sluttfarge" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1040 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +#, fuzzy +msgid "Background color" +msgstr "Sluttfarge" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1041 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +msgid "" +"Color and transparency of the page background (also used for bitmap export)" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1045 +#: ../../po/../src/ui/dialog/document-preferences.cpp:147 +#, fuzzy +msgid "Show page border" +msgstr "Vis kant" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1049 +#: ../../po/../src/ui/dialog/document-preferences.cpp:148 +msgid "Border on top of drawing" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1052 +#: ../../po/../src/ui/dialog/document-preferences.cpp:149 +#, fuzzy +msgid "Border color:" +msgstr "Farge pÃ¥ rutenett:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1053 +#: ../../po/../src/ui/dialog/document-preferences.cpp:149 +#, fuzzy +msgid "Page border color" +msgstr "Farge pÃ¥ rutenett:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1054 +#: ../../po/../src/ui/dialog/document-preferences.cpp:150 +#, fuzzy +msgid "Color of the page border" +msgstr "Vis kant" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1059 +#: ../../po/../src/ui/dialog/document-preferences.cpp:152 +msgid "Show page shadow" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1063 +#: ../../po/../src/ui/dialog/document-preferences.cpp:153 +#, fuzzy +msgid "Default units:" +msgstr "Forvalg" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1069 +msgid "Units for the tool controls, ruler, and the statusbar" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1086 +#: ../../po/../src/ui/widget/page-sizer.cpp:209 +#, fuzzy +msgid "Page size:" +msgstr "Papirstørrelse:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1110 +#: ../../po/../src/ui/widget/page-sizer.cpp:219 +msgid "Custom" +msgstr "Tilpasset" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1121 +#: ../../po/../src/ui/widget/page-sizer.cpp:225 +#, fuzzy +msgid "Page orientation:" +msgstr "Orientering:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1133 +#: ../../po/../src/ui/widget/page-sizer.cpp:232 +#, fuzzy +msgid "Landscape" +msgstr "Sodipodi: %s: XML-visning" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1139 +#: ../../po/../src/ui/widget/page-sizer.cpp:234 +#, fuzzy +msgid "Portrait" +msgstr "Punkt" + +#. Custom paper frame +#: ../../po/../src/dialogs/desktop-properties.cpp:1148 +#: ../../po/../src/ui/widget/page-sizer.cpp:249 +#, fuzzy +msgid "Custom size" +msgstr "Tilpasset" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1160 +#: ../../po/../src/dialogs/export.cpp:269 +#: ../../po/../src/ui/widget/page-sizer.cpp:261 +msgid "Units:" +msgstr "Enheter:" + +#. Stroke width +#: ../../po/../src/dialogs/desktop-properties.cpp:1162 +#: ../../po/../src/dialogs/export.cpp:310 +#: ../../po/../src/dialogs/object-attributes.cpp:55 +#: ../../po/../src/dialogs/stroke-style.cpp:985 +#: ../../po/../src/ui/widget/page-sizer.cpp:262 +#: ../../po/../src/widgets/toolbox.cpp:1957 +msgid "Width:" +msgstr "Bredde:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1183 +#: ../../po/../src/dialogs/export.cpp:326 +#: ../../po/../src/dialogs/export.cpp:431 +#: ../../po/../src/dialogs/object-attributes.cpp:56 +#: ../../po/../src/ui/widget/page-sizer.cpp:263 +msgid "Height:" +msgstr "Høyde:" + +#. +#. * Ownership metadata tab +#. +#: ../../po/../src/dialogs/desktop-properties.cpp:1206 +msgid "Metadata" +msgstr "" + +#. add license selector pull-down +#: ../../po/../src/dialogs/desktop-properties.cpp:1225 +msgid "License" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1255 +msgid "Proprietary" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:212 +#, fuzzy +msgid "When transforming, show:" +msgstr "Objekt-transformasjon" + +#: ../../po/../src/dialogs/display-settings.cpp:223 +#, fuzzy +msgid "Objects" +msgstr "Objekt" + +#: ../../po/../src/dialogs/display-settings.cpp:224 +msgid "Show the actual objects when moving or transforming" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:231 +#, fuzzy +msgid "Box outline" +msgstr "Vis omriss" + +#: ../../po/../src/dialogs/display-settings.cpp:232 +msgid "Show only a box outline of the objects when moving or transforming" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:238 +msgid "Per-object selection cue:" +msgstr "" + +#. sorationsnapsperpi == 0 means no snapping +#: ../../po/../src/dialogs/display-settings.cpp:249 +#: ../../po/../src/dialogs/display-settings.cpp:386 +#: ../../po/../src/dialogs/display-settings.cpp:441 +#: ../../po/../src/dialogs/display-settings.cpp:1482 +#: ../../po/../src/dialogs/stroke-style.cpp:791 +#: ../../po/../src/interface.cpp:741 +#: ../../po/../src/ui/widget/selected-style.cpp:100 +#: ../../po/../src/verbs.cpp:1842 +msgid "None" +msgstr "Ingen" + +#: ../../po/../src/dialogs/display-settings.cpp:250 +msgid "No per-object selection indication" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:256 +msgid "Mark" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:257 +msgid "Each selected object has a diamond mark in the top left corner" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:264 +msgid "Box" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:265 +msgid "Each selected object displays its bounding box" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:270 +#, fuzzy +msgid "Default scale origin:" +msgstr "Forvalgt markørtoleranse:" + +#: ../../po/../src/dialogs/display-settings.cpp:281 +#, fuzzy +msgid "Opposite bounding box edge" +msgstr "Fest til rutenett" + +#: ../../po/../src/dialogs/display-settings.cpp:282 +msgid "Default scale origin will be on the bounding box of the item" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:288 +msgid "Farthest opposite node" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:289 +msgid "Default scale origin will be on the bounding box of the item's points" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:341 +#, fuzzy +msgid "degrees" +msgstr "grad" + +#: ../../po/../src/dialogs/display-settings.cpp:350 +msgid "" +"Rotating with Ctrl pressed snaps every that much degrees; also, pressing " +"[ or ] rotates by this amount" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:407 +msgid "Rotation snaps every:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:430 +msgid "" +"None: dialogs are treated as regular windows; Normal: dialogs stay on top of " +"document windows; Aggressive: same as Normal but may work better with some " +"window managers." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:451 +msgid "Normal" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:461 +msgid "Aggressive" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:475 +#, fuzzy +msgid "Dialogs on top:" +msgstr "Dialoger" + +#: ../../po/../src/dialogs/display-settings.cpp:645 +#, fuzzy +msgid "Show selection cue" +msgstr "Senk valgte objekter ett nivÃ¥" + +#: ../../po/../src/dialogs/display-settings.cpp:646 +msgid "" +"Whether selected objects display a selection cue (the same as in selector)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:657 +#, fuzzy +msgid "Enable gradient editing" +msgstr "Gradientvektor" + +#: ../../po/../src/dialogs/display-settings.cpp:658 +msgid "Whether selected objects display gradient editing controls" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:719 +#, fuzzy +msgid "No objects selected to take the style from." +msgstr "Senk valgte objekter til bunnen" + +#: ../../po/../src/dialogs/display-settings.cpp:728 +msgid "" +"More than one object selected. Cannot take style from multiple " +"objects." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:767 +#, fuzzy +msgid "Create new objects with:" +msgstr "Distribuer" + +#: ../../po/../src/dialogs/display-settings.cpp:777 +#, fuzzy +msgid "Take from selection" +msgstr "Transformer utvalg" + +#: ../../po/../src/dialogs/display-settings.cpp:778 +msgid "Remember the style of the (first) selected object as this tool's style" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:782 +#, fuzzy +msgid "Last used style" +msgstr "Stil for strøk" + +#: ../../po/../src/dialogs/display-settings.cpp:782 +msgid "Apply the style you last set on an object" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:790 +msgid "This tool's own style:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:790 +msgid "" +"Each tool may store its own style to apply to the newly created objects. Use " +"the button below to set it." +msgstr "" + +#. Mouse +#: ../../po/../src/dialogs/display-settings.cpp:877 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:55 +#, fuzzy +msgid "Mouse" +msgstr "Flytt" + +#. TRANSLATORS: "Grab" is a noun here. "Grab sensitivity" is intended to mean how +#. * close on the screen you need to be to an object to be able to grab it with mouse (in +#. * pixels). +#: ../../po/../src/dialogs/display-settings.cpp:883 +#, fuzzy +msgid "Grab sensitivity:" +msgstr "Gjør sensitiv" + +#: ../../po/../src/dialogs/display-settings.cpp:884 +msgid "" +"How close on the screen you need to be to an object to be able to grab it " +"with mouse (in screen pixels)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:885 +#: ../../po/../src/dialogs/display-settings.cpp:897 +#: ../../po/../src/dialogs/display-settings.cpp:912 +#: ../../po/../src/dialogs/display-settings.cpp:930 +#: ../../po/../src/dialogs/display-settings.cpp:970 +msgid "pixels" +msgstr "piksler" + +#: ../../po/../src/dialogs/display-settings.cpp:895 +msgid "Click/drag threshold:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:896 +msgid "" +"Maximum mouse drag (in screen pixels) which is considered a click, not a drag" +msgstr "" + +#. Scrolling +#: ../../po/../src/dialogs/display-settings.cpp:907 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:56 +msgid "Scrolling" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:910 +msgid "Mouse wheel scrolls by:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:911 +msgid "" +"One mouse wheel notch scrolls by this distance in screen pixels " +"(horizontally with Shift)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:920 +msgid "Ctrl+arrows" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:928 +msgid "Scroll by:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:929 +msgid "Pressing Ctrl+arrow key scrolls by this distance (in screen pixels)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:939 +#, fuzzy +msgid "Acceleration:" +msgstr "Valg" + +#: ../../po/../src/dialogs/display-settings.cpp:940 +msgid "" +"Pressing and holding Ctrl+arrow will gradually speed up scrolling (0 for no " +"acceleration)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:949 +msgid "Autoscrolling" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:957 +#, fuzzy +msgid "Speed:" +msgstr "Rød:" + +#: ../../po/../src/dialogs/display-settings.cpp:958 +msgid "" +"How fast the canvas autoscrolls when you drag beyond canvas edge (0 to turn " +"autoscroll off)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:968 +#: ../../po/../src/ui/dialog/tracedialog.cpp:357 +#: ../../po/../src/ui/dialog/tracedialog.cpp:390 +msgid "Threshold:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:969 +msgid "" +"How far (in screen pixels) you need to be from the canvas edge to trigger " +"autoscroll; positive is outside the canvas, negative is within the canvas" +msgstr "" + +#. Steps +#: ../../po/../src/dialogs/display-settings.cpp:979 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:57 +#, fuzzy +msgid "Steps" +msgstr "Stil" + +#: ../../po/../src/dialogs/display-settings.cpp:982 +msgid "Arrow keys move by:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:983 +msgid "" +"Pressing an arrow key moves selected object(s) or node(s) by this distance " +"(in px units)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:984 +#: ../../po/../src/dialogs/display-settings.cpp:995 +#: ../../po/../src/dialogs/display-settings.cpp:1006 +#: ../../po/../src/helper/units.cpp:42 +msgid "px" +msgstr "px" + +#: ../../po/../src/dialogs/display-settings.cpp:993 +msgid "> and < scale by:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:994 +msgid "" +"Pressing > or < scales selection up or down by this increment (in px units)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1004 +msgid "Inset/Outset by:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1005 +msgid "" +"Inset and Outset commands displace the path by this distance (in px units)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1017 +msgid "Compass-like display of angles" +msgstr "" + +#. TRANSLATORS: "positive clockwise" means "increasing in clockwise direction" +#: ../../po/../src/dialogs/display-settings.cpp:1019 +msgid "" +"When on, angles are displayed with 0 at north, 0 to 360 range, positive " +"clockwise; otherwise with 0 at east, -180 to 180 range, positive " +"counterclockwise" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1026 +#, fuzzy +msgid "Zoom in/out by:" +msgstr "Zoom ut i tegning" + +#: ../../po/../src/dialogs/display-settings.cpp:1027 +msgid "" +"Zoom tool click, +/- keys, and middle click zoom in and out by this " +"multiplier" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1028 +#: ../../po/../src/helper/units.cpp:44 +msgid "%" +msgstr "%" + +#. Tools +#: ../../po/../src/dialogs/display-settings.cpp:1037 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:58 +msgid "Tools" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1045 +#, fuzzy +msgid "Selector" +msgstr "Velg" + +#: ../../po/../src/dialogs/display-settings.cpp:1056 +#, fuzzy +msgid "Node" +msgstr "Noder" + +#: ../../po/../src/dialogs/display-settings.cpp:1064 +#: ../../po/../src/verbs.cpp:2073 +#: ../../po/../src/widgets/desktop-widget.cpp:277 +msgid "Zoom" +msgstr "Zoom" + +#. The 4 shape tools +#: ../../po/../src/dialogs/display-settings.cpp:1071 +#, fuzzy +msgid "Shapes" +msgstr "Form" + +#: ../../po/../src/dialogs/display-settings.cpp:1079 +#: ../../po/../src/verbs.cpp:2055 +msgid "Rectangle" +msgstr "Rektangel" + +#: ../../po/../src/dialogs/display-settings.cpp:1085 +#: ../../po/../src/verbs.cpp:2057 +msgid "Ellipse" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1091 +#: ../../po/../src/verbs.cpp:2059 +msgid "Star" +msgstr "Stjerne" + +#: ../../po/../src/dialogs/display-settings.cpp:1097 +#: ../../po/../src/verbs.cpp:2061 +msgid "Spiral" +msgstr "Spiral" + +#: ../../po/../src/dialogs/display-settings.cpp:1111 +#: ../../po/../src/verbs.cpp:2063 +msgid "Pencil" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1114 +#, fuzzy +msgid "Tolerance:" +msgstr "Spor" + +#: ../../po/../src/dialogs/display-settings.cpp:1115 +msgid "" +"This value affects the amount of smoothing applied to freehand lines; lower " +"values produce more uneven paths with more nodes" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1131 +#: ../../po/../src/verbs.cpp:2065 +#, fuzzy +msgid "Pen" +msgstr "Prosent" + +#: ../../po/../src/dialogs/display-settings.cpp:1140 +#: ../../po/../src/verbs.cpp:2067 +#, fuzzy +msgid "Calligraphy" +msgstr "Kalligrafisk linje" + +#: ../../po/../src/dialogs/display-settings.cpp:1147 +#: ../../po/../src/dialogs/text-edit.cpp:353 +#: ../../po/../src/ui/dialog/text-properties.cpp:37 +#: ../../po/../src/verbs.cpp:2069 +msgid "Text" +msgstr "Tekst" + +#: ../../po/../src/dialogs/display-settings.cpp:1157 +#: ../../po/../src/verbs.cpp:2071 +#, fuzzy +msgid "Gradient" +msgstr "Gradientvektor" + +#: ../../po/../src/dialogs/display-settings.cpp:1164 +#: ../../po/../src/verbs.cpp:2077 +#, fuzzy +msgid "Connector" +msgstr "Hjørner:" + +#: ../../po/../src/dialogs/display-settings.cpp:1171 +#: ../../po/../src/verbs.cpp:2075 +msgid "Dropper" +msgstr "" + +#. Windows +#: ../../po/../src/dialogs/display-settings.cpp:1183 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:59 +msgid "Windows" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1188 +#, fuzzy +msgid "Save window geometry" +msgstr "Lagre dokument" + +#: ../../po/../src/dialogs/display-settings.cpp:1189 +msgid "" +"Save the window size and position with each document (only for Inkscape SVG " +"format)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1196 +msgid "Dialogs are hidden in taskbar" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1197 +msgid "Whether dialog windows are to be hidden in the window manager taskbar" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1204 +#, fuzzy +msgid "Zoom when window is resized" +msgstr "Zoom tegning hvis et vindu størelse endres" + +#: ../../po/../src/dialogs/display-settings.cpp:1205 +msgid "" +"Zoom drawing when document window is resized, to keep the same area visible " +"(this is the default which can be changed in any window using the button " +"above the right scrollbar)" +msgstr "" + +#. Clones +#: ../../po/../src/dialogs/display-settings.cpp:1213 +#: ../../po/../src/dialogs/find.cpp:624 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:60 +#, fuzzy +msgid "Clones" +msgstr "Lukk" + +#: ../../po/../src/dialogs/display-settings.cpp:1217 +msgid "When the original moves, its clones and linked offsets:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1229 +msgid "Move in parallel" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1230 +msgid "Clones are translated by the same vector as their original." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1237 +msgid "Stay unmoved" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1238 +msgid "Clones preserve their positions when their original is moved." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1245 +msgid "Move according to transform" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1246 +msgid "" +"Each clone moves according to the value of its transform= attribute. For " +"example, a rotated clone will move in a different direction than its " +"original." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1255 +msgid "When the original is deleted, its clones:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1267 +msgid "Are unlinked" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1267 +msgid "Orphaned clones are converted to regular objects." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1273 +#, fuzzy +msgid "Are deleted" +msgstr "Først valgte" + +#: ../../po/../src/dialogs/display-settings.cpp:1273 +msgid "Orphaned clones are deleted along with their original." +msgstr "" + +#. Transforms +#. TRANSLATORS: Noun, i.e. transformations. +#: ../../po/../src/dialogs/display-settings.cpp:1289 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:61 +#, fuzzy +msgid "Transforms" +msgstr "Transformer:" + +#: ../../po/../src/dialogs/display-settings.cpp:1292 +#, fuzzy +msgid "Scale stroke width" +msgstr "Ingen maling" + +#: ../../po/../src/dialogs/display-settings.cpp:1293 +#: ../../po/../src/widgets/select-toolbar.cpp:568 +msgid "When scaling objects, scale the stroke width by the same proportion" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1300 +msgid "Scale rounded corners in rectangles" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1301 +#: ../../po/../src/widgets/select-toolbar.cpp:580 +msgid "When scaling rectangles, scale the radii of rounded corners" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1308 +#, fuzzy +msgid "Transform gradients" +msgstr "Transformer:" + +#: ../../po/../src/dialogs/display-settings.cpp:1309 +#: ../../po/../src/widgets/select-toolbar.cpp:592 +msgid "Transform gradients (in fill or stroke) along with the objects" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1316 +#, fuzzy +msgid "Transform patterns" +msgstr "Transformasjonsmatrise" + +#: ../../po/../src/dialogs/display-settings.cpp:1317 +#: ../../po/../src/widgets/select-toolbar.cpp:604 +msgid "Transform patterns (in fill or stroke) along with the objects" +msgstr "" + +#. TRANSLATORS: How to specify the affine transformation in the SVG file. +#: ../../po/../src/dialogs/display-settings.cpp:1327 +#, fuzzy +msgid "Store transformation:" +msgstr "Objekt-transformasjon" + +#: ../../po/../src/dialogs/display-settings.cpp:1338 +#, fuzzy +msgid "Optimized" +msgstr "Optimer" + +#: ../../po/../src/dialogs/display-settings.cpp:1339 +msgid "" +"If possible, apply transformation to objects without adding a transform= " +"attribute" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1346 +#, fuzzy +msgid "Preserved" +msgstr "Preserver" + +#: ../../po/../src/dialogs/display-settings.cpp:1347 +msgid "Always store transformation as a transform= attribute on objects" +msgstr "" + +#. Selecting +#: ../../po/../src/dialogs/display-settings.cpp:1355 +#, fuzzy +msgid "Selecting" +msgstr "Valg" + +#: ../../po/../src/dialogs/display-settings.cpp:1357 +msgid "Ctrl+A, Tab, Shift+Tab:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1366 +#, fuzzy +msgid "Select only within current layer" +msgstr "Velg" + +#: ../../po/../src/dialogs/display-settings.cpp:1367 +msgid "" +"Uncheck this to make keyboard selection commands work on objects in all " +"layers" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1374 +msgid "Ignore hidden objects" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1375 +msgid "" +"Uncheck this to be able to select objects that are hidden (either by " +"themselves or by being in a hidden group or layer)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1382 +#, fuzzy +msgid "Ignore locked objects" +msgstr "Valgte objekter" + +#: ../../po/../src/dialogs/display-settings.cpp:1383 +msgid "" +"Uncheck this to be able to select objects that are locked (either by " +"themselves or by being in a locked group or layer)" +msgstr "" + +#. To be broken into: Display, Save, Export, SVG, Commands +#: ../../po/../src/dialogs/display-settings.cpp:1391 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:62 +msgid "Misc" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1394 +msgid "Default export resolution:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1395 +msgid "Default bitmap resolution (in dots per inch) in the Export dialog" +msgstr "" + +#. FIXME: add "Used for new exports; once exported, documents remember this value on per-object basis" when implemented +#: ../../po/../src/dialogs/display-settings.cpp:1396 +#: ../../po/../src/dialogs/export.cpp:442 +msgid "dpi" +msgstr "dpi" + +#. TRANSLATORS: When on, an imported bitmap creates an element; otherwise it is a +#. * rectangle with bitmap fill. +#: ../../po/../src/dialogs/display-settings.cpp:1407 +#, fuzzy +msgid "Import bitmap as " +msgstr "Importer bitkart eller SVG-bilde i dokumentet" + +#: ../../po/../src/dialogs/display-settings.cpp:1408 +msgid "" +"When on, an imported bitmap creates an element; otherwise it is a " +"rectangle with bitmap fill" +msgstr "" + +#. TRANSLATORS: When on, the print out (currently Postscript) will have +#. * a comment with the each object's label visible, marking the section +#. * of the printing commands that represent the given object. +#: ../../po/../src/dialogs/display-settings.cpp:1418 +msgid "Add label comments to printing output" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1419 +msgid "" +"When on, a comment will be added to the raw print output, marking the " +"rendered output for an object with its label" +msgstr "" + +#. TRANSLATORS: When on, enable the effects menu, default is off +#: ../../po/../src/dialogs/display-settings.cpp:1427 +msgid "Enable script effects (requires restart) - EXPERIMENTAL" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1428 +msgid "" +"When on, the effects menu is enabled, allowing external effect scripts to be " +"called, requires restart before effective - EXPERIMENTAL" +msgstr "" + +#. TRANSLATORS: The maximum length of the Open Recent list in the File menu. +#: ../../po/../src/dialogs/display-settings.cpp:1436 +#, fuzzy +msgid "Max recent documents:" +msgstr "Skriv ut dokument" + +#: ../../po/../src/dialogs/display-settings.cpp:1437 +msgid "The maximum length of the Open Recent list in the File menu" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1447 +msgid "Simplification threshold:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1448 +msgid "" +"How strong is the Simplify command by default. If you invoke this command " +"several times in quick succession, it will act more and more aggressively; " +"invoking it again after a pause restores the default threshold." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1469 +msgid "Oversample bitmaps:" +msgstr "Oversample bitkart:" + +#: ../../po/../src/dialogs/display-settings.cpp:1488 +msgid "2x2" +msgstr "2x2" + +#: ../../po/../src/dialogs/display-settings.cpp:1494 +msgid "4x4" +msgstr "4x4" + +#: ../../po/../src/dialogs/display-settings.cpp:1500 +msgid "8x8" +msgstr "8x8" + +#: ../../po/../src/dialogs/display-settings.cpp:1506 +msgid "16x16" +msgstr "16x16" + +#. "view_icon_preview" +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2143 +#, fuzzy +msgid "_Page" +msgstr "Side" + +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2147 +#, fuzzy +msgid "_Drawing" +msgstr "Tegning" + +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2149 +#, fuzzy +msgid "_Selection" +msgstr "Valg" + +#: ../../po/../src/dialogs/export.cpp:133 +#, fuzzy +msgid "_Custom" +msgstr "Tilpasset" + +#: ../../po/../src/dialogs/export.cpp:254 +msgid "Export area" +msgstr "Eksporter omrÃ¥de" + +#: ../../po/../src/dialogs/export.cpp:300 +#, fuzzy +msgid "_x0:" +msgstr "x0:" + +#: ../../po/../src/dialogs/export.cpp:305 +#, fuzzy +msgid "x_1:" +msgstr "x1:" + +#: ../../po/../src/dialogs/export.cpp:316 +#, fuzzy +msgid "_y0:" +msgstr "y0:" + +#: ../../po/../src/dialogs/export.cpp:321 +#, fuzzy +msgid "y_1:" +msgstr "y1:" + +#: ../../po/../src/dialogs/export.cpp:406 +msgid "Bitmap size" +msgstr "Størrelse pÃ¥ bitkart" + +#: ../../po/../src/dialogs/export.cpp:416 +#, fuzzy +msgid "_Width:" +msgstr "Bredde:" + +#: ../../po/../src/dialogs/export.cpp:416 +#: ../../po/../src/dialogs/export.cpp:431 +#, fuzzy +msgid "pixels at" +msgstr "piksler" + +#: ../../po/../src/dialogs/export.cpp:426 +#, fuzzy +msgid "dp_i" +msgstr "dpi" + +#: ../../po/../src/dialogs/export.cpp:448 +#, fuzzy +msgid "_Filename" +msgstr "Fil" + +#: ../../po/../src/dialogs/export.cpp:512 +msgid "_Browse..." +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:539 +#, fuzzy +msgid " _Export " +msgstr "Rektangel" + +#: ../../po/../src/dialogs/export.cpp:541 +msgid "Export the bitmap file with these settings" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:968 +msgid "You have to enter a filename" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:973 +msgid "The chosen area to be exported is invalid" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:982 +#, c-format +msgid "Directory %s does not exist or is not a directory.\n" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:998 +#, fuzzy +msgid "Export in progress" +msgstr "Eksporter omrÃ¥de" + +#: ../../po/../src/dialogs/export.cpp:1004 +#, fuzzy, c-format +msgid "Exporting %s (%d x %d)" +msgstr "Fargebilde %d x %d: %s" + +#: ../../po/../src/dialogs/export.cpp:1031 +#, c-format +msgid "Could not export to filename %s.\n" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:1137 +#, fuzzy +msgid "Select a filename for exporting" +msgstr "Velg fil som skal importeres" + +#: ../../po/../src/dialogs/filedialog.cpp:367 +#, fuzzy +msgid "No preview" +msgstr "Ny forhÃ¥ndsvisning" + +#: ../../po/../src/dialogs/filedialog.cpp:468 +msgid "too large for preview" +msgstr "" + +#: ../../po/../src/dialogs/filedialog.cpp:762 +#: ../../po/../src/dialogs/filedialog.cpp:763 +#, fuzzy +msgid "All Images" +msgstr "Bilde" + +#: ../../po/../src/dialogs/filedialog.cpp:767 +#: ../../po/../src/dialogs/filedialog.cpp:768 +#, fuzzy +msgid "All Files" +msgstr "Fyllstil" + +#: ../../po/../src/dialogs/filedialog.cpp:774 +#: ../../po/../src/dialogs/filedialog.cpp:775 +#, fuzzy +msgid "All Inkscape Files" +msgstr "Sodipodi: %s: XML-visning" + +#: ../../po/../src/dialogs/filedialog.cpp:1176 +#, fuzzy +msgid "Guess from extension" +msgstr "Transformer utvalg" + +#. ###### Add the file types menu +#. createFilterMenu(); +#. ###### Do we want the .xxx extension automatically added? +#: ../../po/../src/dialogs/filedialog.cpp:1261 +msgid "Append filename extension automatically" +msgstr "" + +#. TRANSLATORS: "%s" is replaced with "exact" or "partial" when this string is displayed +#: ../../po/../src/dialogs/find.cpp:378 +#, fuzzy, c-format +msgid "%d object found (out of %d), %s match." +msgid_plural "%d objects found (out of %d), %s match." +msgstr[0] "SlÃ¥ sammen linjer ved valgte noder" +msgstr[1] "SlÃ¥ sammen linjer ved valgte noder" + +#: ../../po/../src/dialogs/find.cpp:381 +#, fuzzy +msgid "exact" +msgstr "Tekst" + +#: ../../po/../src/dialogs/find.cpp:381 +#, fuzzy +msgid "partial" +msgstr "Spiral" + +#: ../../po/../src/dialogs/find.cpp:388 +#, fuzzy +msgid "No objects found" +msgstr "Ingen objekter" + +#: ../../po/../src/dialogs/find.cpp:546 +#, fuzzy +msgid "T_ype: " +msgstr "Type:" + +#: ../../po/../src/dialogs/find.cpp:553 +msgid "Search in all object types" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:553 +#, fuzzy +msgid "All types" +msgstr "Fyllstil" + +#: ../../po/../src/dialogs/find.cpp:564 +msgid "Search all shapes" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:564 +#, fuzzy +msgid "All shapes" +msgstr "Alle formverktøy" + +#: ../../po/../src/dialogs/find.cpp:581 +#, fuzzy +msgid "Search rectangles" +msgstr "Rektangel" + +#: ../../po/../src/dialogs/find.cpp:581 +#, fuzzy +msgid "Rectangles" +msgstr "Rektangel" + +#: ../../po/../src/dialogs/find.cpp:586 +msgid "Search ellipses, arcs, circles" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:586 +msgid "Ellipses" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:591 +msgid "Search stars and polygons" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:591 +#, fuzzy +msgid "Stars" +msgstr "Stjerne" + +#: ../../po/../src/dialogs/find.cpp:596 +#, fuzzy +msgid "Search spirals" +msgstr "Opprett lenke" + +#: ../../po/../src/dialogs/find.cpp:596 +#, fuzzy +msgid "Spirals" +msgstr "Spiral" + +#. TRANSLATORS: polyline is a set of connected straight line segments +#. http://www.w3.org/TR/SVG11/shapes.html#PolylineElement +#: ../../po/../src/dialogs/find.cpp:609 +msgid "Search paths, lines, polylines" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:609 +msgid "Paths" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:614 +#, fuzzy +msgid "Search text objects" +msgstr "Valgte objekter" + +#: ../../po/../src/dialogs/find.cpp:614 +#, fuzzy +msgid "Texts" +msgstr "Tekst" + +#: ../../po/../src/dialogs/find.cpp:619 +msgid "Search groups" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:619 +#, fuzzy +msgid "Groups" +msgstr "Grupper" + +#: ../../po/../src/dialogs/find.cpp:624 +msgid "Search clones" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:629 +msgid "Search images" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:629 +#, fuzzy +msgid "Images" +msgstr "Bilde" + +#: ../../po/../src/dialogs/find.cpp:634 +#, fuzzy +msgid "Search offset objects" +msgstr "Valgte objekter" + +#: ../../po/../src/dialogs/find.cpp:634 +msgid "Offsets" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:694 +#, fuzzy +msgid "_Text: " +msgstr "Tekst" + +#: ../../po/../src/dialogs/find.cpp:694 +msgid "Find objects by their text content (exact or partial match)" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:695 +msgid "_ID: " +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:695 +msgid "Find objects by the value of the id attribute (exact or partial match)" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:696 +#, fuzzy +msgid "_Style: " +msgstr "Stil" + +#: ../../po/../src/dialogs/find.cpp:696 +msgid "" +"Find objects by the value of the style attribute (exact or partial match)" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:697 +#, fuzzy +msgid "_Attribute: " +msgstr "Attributt" + +#: ../../po/../src/dialogs/find.cpp:697 +msgid "Find objects by the name of an attribute (exact or partial match)" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:711 +#, fuzzy +msgid "Search in s_election" +msgstr "Valg" + +#: ../../po/../src/dialogs/find.cpp:715 +msgid "Limit search to the current selection" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:720 +#, fuzzy +msgid "Search in current _layer" +msgstr "Velg" + +#: ../../po/../src/dialogs/find.cpp:724 +#, fuzzy +msgid "Limit search to the current layer" +msgstr "Velg" + +#: ../../po/../src/dialogs/find.cpp:729 +msgid "Include _hidden" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:733 +msgid "Include hidden objects in search" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:738 +msgid "Include l_ocked" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:742 +#, fuzzy +msgid "Include locked objects in search" +msgstr "Valgte objekter" + +#: ../../po/../src/dialogs/find.cpp:753 +#, fuzzy +msgid "Clear values" +msgstr "Tøm alle" + +#: ../../po/../src/dialogs/find.cpp:754 +#, fuzzy +msgid "_Find" +msgstr "Rutenett" + +#: ../../po/../src/dialogs/find.cpp:754 +msgid "Select objects matching all of the fields you filled in" +msgstr "" + +#: ../../po/../src/dialogs/iconpreview.cpp:145 +#, c-format +msgid "%d x %d" +msgstr "" + +#: ../../po/../src/dialogs/iconpreview.cpp:193 +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:857 +#: ../../po/../src/widgets/desktop-widget.cpp:1069 +msgid "Selection" +msgstr "Valg" + +#: ../../po/../src/dialogs/iconpreview.cpp:195 +#, fuzzy +msgid "Selection only or whole document" +msgstr "Velg" + +#: ../../po/../src/dialogs/iconpreview.cpp:203 +msgid "Refresh the icons" +msgstr "" + +#. Create the label for the object id +#: ../../po/../src/dialogs/item-properties.cpp:126 +#: ../../po/../src/dialogs/item-properties.cpp:327 +#: ../../po/../src/dialogs/item-properties.cpp:396 +#: ../../po/../src/dialogs/item-properties.cpp:403 +msgid "_Id" +msgstr "" + +#: ../../po/../src/dialogs/item-properties.cpp:135 +msgid "" +"The id= attribute (only letters, digits, and the characters .-_: allowed)" +msgstr "" + +#. Button for setting the object's id, label, title and description. +#: ../../po/../src/dialogs/item-properties.cpp:149 +#, fuzzy +msgid "_Set" +msgstr "Velg" + +#. Create the label for the object label +#: ../../po/../src/dialogs/item-properties.cpp:158 +#, fuzzy +msgid "_Label" +msgstr "Sett attributt" + +#: ../../po/../src/dialogs/item-properties.cpp:167 +msgid "A freeform label for the object" +msgstr "" + +#. Create the label for the object title +#: ../../po/../src/dialogs/item-properties.cpp:179 +#: ../../po/../src/dialogs/rdf.cpp:243 +#, fuzzy +msgid "Title" +msgstr "Tittel:" + +#. Create the frame for the object description +#: ../../po/../src/dialogs/item-properties.cpp:196 +#: ../../po/../src/dialogs/rdf.cpp:287 +#, fuzzy +msgid "Description" +msgstr "Valg" + +#. Hide +#: ../../po/../src/dialogs/item-properties.cpp:223 +#, fuzzy +msgid "_Hide" +msgstr "Sider:" + +#: ../../po/../src/dialogs/item-properties.cpp:224 +msgid "Check to make the object invisible" +msgstr "" + +#. Lock +#. TRANSLATORS: "Lock" is a verb here +#: ../../po/../src/dialogs/item-properties.cpp:233 +msgid "L_ock" +msgstr "" + +#: ../../po/../src/dialogs/item-properties.cpp:234 +msgid "Check to make the object insensitive (not selectable by mouse)" +msgstr "" + +#: ../../po/../src/dialogs/item-properties.cpp:310 +#: ../../po/../src/dialogs/item-properties.cpp:317 +msgid "Ref" +msgstr "" + +#: ../../po/../src/dialogs/item-properties.cpp:398 +#, fuzzy +msgid "Id invalid! " +msgstr "IDen er gyldig" + +#: ../../po/../src/dialogs/item-properties.cpp:400 +msgid "Id exists! " +msgstr "" + +#: ../../po/../src/dialogs/layer-properties.cpp:50 +msgid "Layer name:" +msgstr "" + +#: ../../po/../src/dialogs/layer-properties.cpp:133 +#, fuzzy +msgid "Rename Layer" +msgstr "Hev node" + +#: ../../po/../src/dialogs/layer-properties.cpp:136 +#, fuzzy +msgid "_Rename" +msgstr "Fil" + +#. TRANSLATORS: This means "The layer has been renamed" +#: ../../po/../src/dialogs/layer-properties.cpp:147 +#, fuzzy +msgid "Renamed layer" +msgstr "Hev node" + +#: ../../po/../src/dialogs/layer-properties.cpp:151 +#, fuzzy +msgid "Add Layer" +msgstr "Senk" + +#: ../../po/../src/dialogs/layer-properties.cpp:153 +#, fuzzy +msgid "_Add" +msgstr "Legg til" + +#: ../../po/../src/dialogs/layer-properties.cpp:167 +msgid "New layer created." +msgstr "" + +#: ../../po/../src/dialogs/object-attributes.cpp:34 +msgid "Href:" +msgstr "Href:" + +#: ../../po/../src/dialogs/object-attributes.cpp:35 +msgid "Target:" +msgstr "MÃ¥l:" + +#: ../../po/../src/dialogs/object-attributes.cpp:36 +msgid "Type:" +msgstr "Type:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkRoleAttribute +#. Identifies the type of the related resource with an absolute URI +#: ../../po/../src/dialogs/object-attributes.cpp:39 +msgid "Role:" +msgstr "Rolle:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkArcRoleAttribute +#. For situations where the nature/role alone isn't enough, this offers an additional URI defining the purpose of the link. +#: ../../po/../src/dialogs/object-attributes.cpp:42 +msgid "Arcrole:" +msgstr "Arkusrolle:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkTitleAttribute +#: ../../po/../src/dialogs/object-attributes.cpp:44 +msgid "Title:" +msgstr "Tittel:" + +#: ../../po/../src/dialogs/object-attributes.cpp:45 +msgid "Show:" +msgstr "Vis:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkActuateAttribute +#: ../../po/../src/dialogs/object-attributes.cpp:47 +msgid "Actuate:" +msgstr "Aktuer:" + +#: ../../po/../src/dialogs/object-attributes.cpp:52 +msgid "URL:" +msgstr "URL:" + +#: ../../po/../src/dialogs/object-attributes.cpp:53 +msgid "X:" +msgstr "X:" + +#: ../../po/../src/dialogs/object-attributes.cpp:54 +msgid "Y:" +msgstr "Y:" + +#: ../../po/../src/dialogs/object-attributes.cpp:98 +#, c-format +msgid "%s attributes" +msgstr "%s-attributter" + +#: ../../po/../src/dialogs/object-properties.cpp:158 +#, fuzzy +msgid "_Fill" +msgstr "Fyll" + +#: ../../po/../src/dialogs/object-properties.cpp:165 +#, fuzzy +msgid "Stroke _paint" +msgstr "Ingen maling" + +#: ../../po/../src/dialogs/object-properties.cpp:172 +#, fuzzy +msgid "Stroke st_yle" +msgstr "Innstillinger for strøk" + +#: ../../po/../src/dialogs/object-properties.cpp:183 +#, fuzzy +msgid "Master _opacity" +msgstr "Ugjennomsiktighet" + +#: ../../po/../src/dialogs/rdf.cpp:244 +msgid "Name by which this document is formally known." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:246 +#, fuzzy +msgid "Date" +msgstr "Lim inn" + +#: ../../po/../src/dialogs/rdf.cpp:247 +msgid "Date associated with the creation of this document (YYYY-MM-DD)." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:249 +msgid "Format" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:250 +msgid "The physical or digital manifestation of this document (MIME type)." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:252 +#, fuzzy +msgid "Type" +msgstr "Type:" + +#: ../../po/../src/dialogs/rdf.cpp:253 +msgid "Type of document (DCMI Type)." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:256 +#, fuzzy +msgid "Creator" +msgstr "Opprett" + +#: ../../po/../src/dialogs/rdf.cpp:257 +msgid "" +"Name of entity primarily responsible for making the content of this document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:259 +#, fuzzy +msgid "Rights" +msgstr "Høyde:" + +#: ../../po/../src/dialogs/rdf.cpp:260 +msgid "" +"Name of entity with rights to the Intellectual Property of this document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:262 +msgid "Publisher" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:263 +msgid "Name of entity responsible for making this document available." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:266 +#, fuzzy +msgid "Identifier" +msgstr "Centimeter" + +#: ../../po/../src/dialogs/rdf.cpp:267 +msgid "Unique URI to reference this document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:269 +msgid "Source" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:270 +msgid "Unique URI to reference the source of this document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:272 +#, fuzzy +msgid "Relation" +msgstr "Vending:" + +#: ../../po/../src/dialogs/rdf.cpp:273 +#, fuzzy +msgid "Unique URI to a related document." +msgstr "Dokument uten navn" + +#: ../../po/../src/dialogs/rdf.cpp:275 +msgid "Language" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:276 +msgid "" +"Two-letter language tag with optional subtags for the language of this " +"document. (e.g. 'en-GB')" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:278 +msgid "Keywords" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:279 +msgid "" +"The topic of this document as comma-separated key words, phrases, or " +"classifications." +msgstr "" + +#. TRANSLATORS: "Coverage": the spatial or temporal characteristics of the content. +#. For info, see Appendix D of http://www.w3.org/TR/1998/WD-rdf-schema-19980409/ +#: ../../po/../src/dialogs/rdf.cpp:283 +msgid "Coverage" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:284 +msgid "Extent or scope of this document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:288 +msgid "A short account of the content of this document." +msgstr "" + +#. FIXME: need to handle 1 agent per line of input +#: ../../po/../src/dialogs/rdf.cpp:292 +#, fuzzy +msgid "Contributors" +msgstr "Centimeter" + +#: ../../po/../src/dialogs/rdf.cpp:293 +msgid "" +"Names of entities responsible for making contributions to the content of " +"this document." +msgstr "" + +#. TRANSLATORS: URL to a page that defines the license for the document +#: ../../po/../src/dialogs/rdf.cpp:297 +msgid "URI" +msgstr "" + +#. TRANSLATORS: this is where you put a URL to a page that defines the license +#: ../../po/../src/dialogs/rdf.cpp:299 +msgid "URI to this document's license's namespace definition." +msgstr "" + +#. TRANSLATORS: fragment of XML representing the license of the document +#: ../../po/../src/dialogs/rdf.cpp:303 +#, fuzzy +msgid "Fragment" +msgstr "Argument:" + +#: ../../po/../src/dialogs/rdf.cpp:304 +msgid "XML fragment for the RDF 'License' section." +msgstr "" + +#: ../../po/../src/dialogs/stroke-style.cpp:774 +#: ../../po/../src/widgets/gradient-vector.cpp:263 +#: ../../po/../src/widgets/paint-selector.cpp:751 +msgid "No document selected" +msgstr "Ingen dokumenter valgt" + +#: ../../po/../src/dialogs/stroke-style.cpp:992 +#, fuzzy +msgid "Stroke width" +msgstr "Ingen maling" + +#. Join type +#. TRANSLATORS: The line join style specifies the shape to be used at the +#. corners of paths. It can be "miter", "round" or "bevel". +#: ../../po/../src/dialogs/stroke-style.cpp:1015 +msgid "Join:" +msgstr "SlÃ¥ sammen:" + +#. TRANSLATORS: Miter join: joining lines with a sharp (pointed) corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1027 +msgid "Miter join" +msgstr "" + +#. TRANSLATORS: Round join: joining lines with a rounded corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1035 +msgid "Round join" +msgstr "" + +#. TRANSLATORS: Bevel join: joining lines with a blunted (flattened) corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1043 +msgid "Bevel join" +msgstr "" + +#. Miterlimit +#. TRANSLATORS: Miter limit: only for "miter join", this limits the length +#. of the sharp "spike" when the lines connect at too sharp an angle. +#. When two line segments meet at a sharp angle, a miter join results in a +#. spike that extends well beyond the connection point. The purpose of the +#. miter limit is to cut off such spikes (i.e. convert them into bevels) +#. when they become too long. +#: ../../po/../src/dialogs/stroke-style.cpp:1054 +msgid "Miter limit:" +msgstr "" + +#: ../../po/../src/dialogs/stroke-style.cpp:1062 +msgid "Maximum length of the miter (in units of stroke width)" +msgstr "" + +#. Cap type +#. TRANSLATORS: cap type specifies the shape for the ends of lines +#: ../../po/../src/dialogs/stroke-style.cpp:1075 +msgid "Cap:" +msgstr "Cap:" + +#. TRANSLATORS: Butt cap: the line shape does not extend beyond the end point +#. of the line; the ends of the line are square +#: ../../po/../src/dialogs/stroke-style.cpp:1086 +msgid "Butt cap" +msgstr "" + +#. TRANSLATORS: Round cap: the line shape extends beyond the end point of the +#. line; the ends of the line are rounded +#: ../../po/../src/dialogs/stroke-style.cpp:1093 +msgid "Round cap" +msgstr "" + +#. TRANSLATORS: Square cap: the line shape extends beyond the end point of the +#. line; the ends of the line are square +#: ../../po/../src/dialogs/stroke-style.cpp:1100 +msgid "Square cap" +msgstr "" + +#. Dash +#: ../../po/../src/dialogs/stroke-style.cpp:1106 +#, fuzzy +msgid "Dashes:" +msgstr "Masse:" + +#. TRANSLATORS: Path markers are an SVG feature that allows you to attach arbitrary shapes +#. (arrowheads, bullets, faces, whatever) to the start, end, or middle nodes of a path. +#: ../../po/../src/dialogs/stroke-style.cpp:1127 +#, fuzzy +msgid "Start Markers:" +msgstr "Egenskaper for stjerne" + +#: ../../po/../src/dialogs/stroke-style.cpp:1137 +msgid "Mid Markers:" +msgstr "" + +#: ../../po/../src/dialogs/stroke-style.cpp:1148 +msgid "End Markers:" +msgstr "" + +#: ../../po/../src/dialogs/swatches.cpp:424 +#, c-format +msgid "Palettes directory (%s) is unavailable." +msgstr "" + +#. TODO: Insert widgets +#: ../../po/../src/dialogs/text-edit.cpp:199 +#: ../../po/../src/ui/dialog/text-properties.cpp:36 +#, fuzzy +msgid "Font" +msgstr "Punkt" + +#: ../../po/../src/dialogs/text-edit.cpp:216 +msgid "Layout" +msgstr "Plassering" + +#: ../../po/../src/dialogs/text-edit.cpp:229 +msgid "Align lines left" +msgstr "" + +#. TRANSLATORS: `Center' here is a verb. +#: ../../po/../src/dialogs/text-edit.cpp:243 +#, fuzzy +msgid "Center lines" +msgstr "Senter Y:" + +#: ../../po/../src/dialogs/text-edit.cpp:256 +msgid "Align lines right" +msgstr "" + +#: ../../po/../src/dialogs/text-edit.cpp:278 +#, fuzzy +msgid "Horizontal text" +msgstr "Vend valgte objekter horisontalt" + +#: ../../po/../src/dialogs/text-edit.cpp:292 +#, fuzzy +msgid "Vertical text" +msgstr "Sentrer vertikalt" + +#: ../../po/../src/dialogs/text-edit.cpp:307 +#, fuzzy +msgid "Line spacing:" +msgstr "Mellomrom X:" + +#: ../../po/../src/dialogs/text-edit.cpp:400 +msgid "Set as default" +msgstr "Sett som forvalg" + +#: ../../po/../src/dialogs/tiledialog.cpp:603 +#, fuzzy +msgid "Rows:" +msgstr "Vis:" + +#: ../../po/../src/dialogs/tiledialog.cpp:613 +msgid "Number of rows" +msgstr "" + +#: ../../po/../src/dialogs/tiledialog.cpp:617 +#, fuzzy +msgid "Equal height" +msgstr "Høyde:" + +#: ../../po/../src/dialogs/tiledialog.cpp:627 +msgid "If not set, each row has the height of the tallest object in it" +msgstr "" + +#. #### Radio buttons to control vertical alignment #### +#. #### Radio buttons to control horizontal alignment #### +#: ../../po/../src/dialogs/tiledialog.cpp:637 +#: ../../po/../src/dialogs/tiledialog.cpp:708 +#, fuzzy +msgid "Align:" +msgstr "Linjestill:" + +#: ../../po/../src/dialogs/tiledialog.cpp:672 +msgid " X " +msgstr "" + +#. #### Number of columns #### +#: ../../po/../src/dialogs/tiledialog.cpp:678 +#, fuzzy +msgid "Columns:" +msgstr "Lukk" + +#: ../../po/../src/dialogs/tiledialog.cpp:688 +msgid "Number of columns" +msgstr "" + +#: ../../po/../src/dialogs/tiledialog.cpp:692 +#, fuzzy +msgid "Equal width" +msgstr "Bredde:" + +#: ../../po/../src/dialogs/tiledialog.cpp:701 +msgid "If not set, each column has the width of the widest object in it" +msgstr "" + +#. #### Radio buttons to control spacing manually or to fit selection bbox #### +#: ../../po/../src/dialogs/tiledialog.cpp:746 +#, fuzzy +msgid "Fit into selection box" +msgstr "Valg" + +#: ../../po/../src/dialogs/tiledialog.cpp:753 +#, fuzzy +msgid "Set spacing:" +msgstr "Mellomrom Y:" + +#. #### Y Padding #### +#: ../../po/../src/dialogs/tiledialog.cpp:777 +#, fuzzy +msgid "Row spacing: " +msgstr "Mellomrom X:" + +#: ../../po/../src/dialogs/tiledialog.cpp:786 +#, fuzzy +msgid "Vertical spacing between rows" +msgstr "Sentrer vertikalt" + +#. #### X padding #### +#: ../../po/../src/dialogs/tiledialog.cpp:795 +#, fuzzy +msgid "Column spacing:" +msgstr "Mellomrom X:" + +#: ../../po/../src/dialogs/tiledialog.cpp:804 +#, fuzzy +msgid "Horizontal spacing between columns" +msgstr "Vend valgte objekter horisontalt" + +#: ../../po/../src/dialogs/tiledialog.cpp:818 +#, fuzzy +msgid "Arrange selected objects" +msgstr "Grupper valgte objekter" + +#: ../../po/../src/dialogs/xml-tree.cpp:178 +msgid "Click to select nodes, drag to rearrange." +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:189 +msgid "Click attribute to edit." +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:193 +#, c-format +msgid "" +"Attribute %s selected. Press Ctrl+Enter when done editing to " +"commit changes." +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:284 +msgid "Drag to reorder nodes" +msgstr "Dra for Ã¥ omarrangere noder" + +#: ../../po/../src/dialogs/xml-tree.cpp:304 +msgid "New element node" +msgstr "Ny elementnode" + +#: ../../po/../src/dialogs/xml-tree.cpp:326 +msgid "New text node" +msgstr "Ny tekstnode" + +#: ../../po/../src/dialogs/xml-tree.cpp:347 +msgid "Duplicate node" +msgstr "Duplisert node" + +#: ../../po/../src/dialogs/xml-tree.cpp:368 +msgid "Delete node" +msgstr "Slett node" + +#: ../../po/../src/dialogs/xml-tree.cpp:384 +msgid "Unindent node" +msgstr "Fjern innrykk for node" + +#: ../../po/../src/dialogs/xml-tree.cpp:399 +msgid "Indent node" +msgstr "Rykk inn node" + +#: ../../po/../src/dialogs/xml-tree.cpp:411 +msgid "Raise node" +msgstr "Hev node" + +#: ../../po/../src/dialogs/xml-tree.cpp:423 +msgid "Lower node" +msgstr "Senk node" + +#: ../../po/../src/dialogs/xml-tree.cpp:468 +msgid "Delete attribute" +msgstr "Slett attributt" + +#. TRANSLATORS: "Attribute" is a noun here +#: ../../po/../src/dialogs/xml-tree.cpp:513 +msgid "Attribute name" +msgstr "Navn pÃ¥ attributt" + +#. TRANSLATORS: "Set" is a verb here +#: ../../po/../src/dialogs/xml-tree.cpp:533 +msgid "Set attribute" +msgstr "Sett attributt" + +#. TRANSLATORS: "Set" is a verb here +#: ../../po/../src/dialogs/xml-tree.cpp:535 +#, fuzzy +msgid "Set" +msgstr "Velg" + +#. TRANSLATORS: "Attribute" is a noun here +#: ../../po/../src/dialogs/xml-tree.cpp:558 +msgid "Attribute value" +msgstr "Verdi for attributt" + +#: ../../po/../src/dialogs/xml-tree.cpp:1318 +msgid "New element node..." +msgstr "Ny elementnode..." + +#: ../../po/../src/dialogs/xml-tree.cpp:1339 +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:100 +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:98 +msgid "Cancel" +msgstr "Avbryt" + +#: ../../po/../src/dialogs/xml-tree.cpp:1345 +msgid "Create" +msgstr "Opprett" + +#: ../../po/../src/dialogs/xml-tree.cpp:1458 +#, c-format +msgid "" +"Cannot set %s: Another element with value %s already exists!" +msgstr "" + +#: ../../po/../src/document.cpp:369 +#, c-format +msgid "New document %d" +msgstr "Nytt dokument %d" + +#: ../../po/../src/document.cpp:401 +#, c-format +msgid "Memory document %d" +msgstr "Dokument i minne %d" + +#: ../../po/../src/document.cpp:524 +#, c-format +msgid "Unnamed document %d" +msgstr "Dokument uten navn %d" + +#. We hit green anchor, closing Green-Blue-Red +#: ../../po/../src/draw-context.cpp:441 +msgid "Path is closed." +msgstr "" + +#. We hit bot start and end of single curve, closing paths +#: ../../po/../src/draw-context.cpp:456 +msgid "Closing path." +msgstr "" + +#. alpha of color under cursor, to show in the statusbar +#. locale-sensitive printf is OK, since this goes to the UI, not into SVG +#: ../../po/../src/dropper-context.cpp:354 +#, c-format +msgid " alpha %.3g" +msgstr "" + +#. where the color is picked, to show in the statusbar +#: ../../po/../src/dropper-context.cpp:356 +#, c-format +msgid ", averaged with radius %d" +msgstr "" + +#: ../../po/../src/dropper-context.cpp:356 +msgid " under cursor" +msgstr "" + +#. message, to show in the statusbar +#: ../../po/../src/dropper-context.cpp:358 +msgid "Release mouse to set color." +msgstr "" + +#: ../../po/../src/dropper-context.cpp:358 +#: ../../po/../src/tools-switch.cpp:207 +msgid "" +"Click to set fill, Shift+click to set stroke; drag to " +"average color in area; with Alt to pick inverse color; Ctrl+C " +"to copy the color under mouse to clipboard" +msgstr "" + +#: ../../po/../src/extension/dependency.cpp:244 +msgid "Dependency::" +msgstr "" + +#: ../../po/../src/extension/dependency.cpp:245 +#, fuzzy +msgid " type: " +msgstr "Fyllstil" + +#: ../../po/../src/extension/dependency.cpp:246 +#, fuzzy +msgid " location: " +msgstr "Vending:" + +#: ../../po/../src/extension/dependency.cpp:247 +msgid " string: " +msgstr "" + +#: ../../po/../src/extension/dependency.cpp:250 +#, fuzzy +msgid " description: " +msgstr "Valg" + +#. static int i = 0; +#. std::cout << "Checking module[" << i++ << "]: " << name << std::endl; +#: ../../po/../src/extension/extension.cpp:244 +msgid "" +" This is caused by an improper .inx file for this extension. An improper ." +"inx file could have been caused by a faulty installation of Inkscape." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:247 +msgid "an ID was not defined for it." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:251 +msgid "there was no name defined for it." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:255 +msgid "the XML description of it got lost." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:259 +msgid "no implementation was defined for the extension." +msgstr "" + +#. std::cout << "Failed: " << *(_deps[i]) << std::endl; +#: ../../po/../src/extension/extension.cpp:266 +msgid "a dependency was not met." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:286 +#, fuzzy +msgid "Extension \"" +msgstr "Utvidelse" + +#: ../../po/../src/extension/extension.cpp:286 +msgid "\" failed to load because " +msgstr "" + +#: ../../po/../src/extension/extension.cpp:565 +#, c-format +msgid "Could not create extension error log file '%s'" +msgstr "" + +#. This is some filler text, needs to change before relase +#: ../../po/../src/extension/error-file.cpp:56 +msgid "" +"One or more extensions failed to load\n" +"\n" +"The failed extensions have been skipped. Inkscape will continue to run " +"normally but those extensions will be unavailable. For details to " +"troubleshoot this problem, please refer to the error log located at: " +msgstr "" + +#. This is some filler text, needs to change before relase +#: ../../po/../src/extension/error-file.cpp:65 +msgid "Show dialog on startup" +msgstr "" + +#: ../../po/../src/extension/implementation/script.cpp:845 +msgid "" +"Inkscape has received an error from the script that it called. The text " +"returned with the error is included below. Inkscape will continue working, " +"but the action you requested has been cancelled." +msgstr "" + +#: ../../po/../src/extension/implementation/script.cpp:858 +msgid "" +"Inkscape has received additional data from the script executed. The script " +"did not return an error, but this may indicate the results will not be as " +"expected." +msgstr "" + +#: ../../po/../src/extension/init.cpp:173 +msgid "Null external module directory name. Modules will not be loaded." +msgstr "" + +#: ../../po/../src/extension/init.cpp:187 +#, c-format +msgid "" +"Modules directory (%s) is unavailable. External modules in that directory " +"will not be loaded." +msgstr "" + +#: ../../po/../src/extension/internal/gnome.cpp:80 +msgid "Select printer" +msgstr "Velg skriver" + +#: ../../po/../src/extension/internal/gnome.cpp:131 +#, fuzzy +msgid "Inkscape: Print Preview" +msgstr "Sodipodi (dokumentnavn %s..): ForhÃ¥ndsvisning" + +#: ../../po/../src/extension/internal/grid.cpp:213 +#, fuzzy +msgid "Line Width" +msgstr "Bredde:" + +#: ../../po/../src/extension/internal/grid.cpp:214 +#, fuzzy +msgid "Horizontal Spacing" +msgstr "Vend valgte objekter horisontalt" + +#: ../../po/../src/extension/internal/grid.cpp:215 +#, fuzzy +msgid "Vertical Spacing" +msgstr "Sentrer vertikalt" + +#: ../../po/../src/extension/internal/grid.cpp:216 +#, fuzzy +msgid "Horizontal Offset" +msgstr "Vend valgte objekter horisontalt" + +#: ../../po/../src/extension/internal/grid.cpp:217 +#, fuzzy +msgid "Vertical Offset" +msgstr "Sentrer vertikalt" + +#: ../../po/../src/extension/internal/ps.cpp:123 +#, fuzzy +msgid "Print Destination" +msgstr "UtskriftsmÃ¥l" + +#. Print properties frame +#: ../../po/../src/extension/internal/ps.cpp:138 +#, fuzzy +msgid "Print properties" +msgstr "Egenskaper for lenke" + +#: ../../po/../src/extension/internal/ps.cpp:145 +msgid "Print using PostScript operators" +msgstr "" + +#: ../../po/../src/extension/internal/ps.cpp:147 +msgid "" +"Use PostScript vector operators. The resulting image is usually smaller in " +"file size and can be arbitrarily scaled, but alpha transparency and patterns " +"will be lost." +msgstr "" + +#: ../../po/../src/extension/internal/ps.cpp:152 +#, fuzzy +msgid "Print as bitmap" +msgstr "Eksporter bitkart" + +#: ../../po/../src/extension/internal/ps.cpp:154 +msgid "" +"Print everything as bitmap. The resulting image is usually larger in file " +"size and cannot be arbitrarily scaled without quality loss, but all objects " +"will be rendered exactly as displayed." +msgstr "" + +#: ../../po/../src/extension/internal/ps.cpp:168 +msgid "Preferred resolution (dots per inch) of bitmap" +msgstr "" + +#: ../../po/../src/extension/internal/ps.cpp:182 +#, fuzzy +msgid "Resolution:" +msgstr "Vending:" + +#. Print destination frame +#: ../../po/../src/extension/internal/ps.cpp:186 +msgid "Print destination" +msgstr "UtskriftsmÃ¥l" + +#: ../../po/../src/extension/internal/ps.cpp:192 +msgid "" +"Use '> filename' to print to file.\n" +"Use '| prog arg...' to pipe to a program." +msgstr "" + +#: ../../po/../src/extension/internal/ps.cpp:1227 +msgid "write error occurred" +msgstr "" + +#: ../../po/../src/extension/prefdialog.cpp:21 +#, fuzzy +msgid " Preferences" +msgstr "Oppføring er referanse" + +#. We can't call sp_ui_error_dialog because we may be +#. running from the console, in which case calling sp_ui +#. routines will cause a segfault. See bug 1000350 - bryce +#. sp_ui_error_dialog(_("Format autodetect failed. The file is being opened as SVG.")); +#: ../../po/../src/extension/system.cpp:105 +msgid "Format autodetect failed. The file is being opened as SVG." +msgstr "" + +#. TRANSLATORS: default.svg is localizable - this is the name of the default document +#. template. This way you can localize the default pagesize, translate the name of +#. the default layer, etc. If you wish to localize this file, please create a +#. localized share/templates/default.xx.svg file, where xx is your language code. +#: ../../po/../src/file.cpp:133 +#, fuzzy +msgid "default.svg" +msgstr "Forvalg" + +#: ../../po/../src/file.cpp:215 ../../po/../src/file.cpp:900 +#, c-format +msgid "Failed to load the requested file %s" +msgstr "" + +#: ../../po/../src/file.cpp:240 +#, fuzzy +msgid "Document not saved yet. Cannot revert." +msgstr "Dokumentnavn:" + +#: ../../po/../src/file.cpp:246 +#, c-format +msgid "Changes will be lost! Are you sure you want to reload document %s?" +msgstr "" + +#: ../../po/../src/file.cpp:266 +#, fuzzy +msgid "Document reverted." +msgstr "Dokumentnavn:" + +#: ../../po/../src/file.cpp:268 +#, fuzzy +msgid "Document not reverted." +msgstr "Dokumentnavn:" + +#: ../../po/../src/file.cpp:382 +msgid "Select file to open" +msgstr "Velg fil som skal Ã¥pnes" + +#: ../../po/../src/file.cpp:518 +#, c-format +msgid "Removed %i unused definition in <defs>." +msgid_plural "Removed %i unused definitions in <defs>." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/file.cpp:523 +msgid "No unused definitions in <defs>." +msgstr "" + +#: ../../po/../src/file.cpp:548 +#, c-format +msgid "" +"No Inkscape extension found to save document (%s). This may have been " +"caused by an unknown filename extension." +msgstr "" + +#: ../../po/../src/file.cpp:549 ../../po/../src/file.cpp:557 +#, fuzzy +msgid "Document not saved." +msgstr "Dokumentnavn:" + +#: ../../po/../src/file.cpp:556 +#, c-format +msgid "File %s could not be saved." +msgstr "" + +#: ../../po/../src/file.cpp:566 +#, fuzzy +msgid "Document saved." +msgstr "Dokumentnavn:" + +#: ../../po/../src/file.cpp:614 +#, fuzzy, c-format +msgid "drawing%s" +msgstr "Tegning" + +#: ../../po/../src/file.cpp:620 +#, fuzzy, c-format +msgid "drawing-%d%s" +msgstr "Tegning" + +#: ../../po/../src/file.cpp:655 +#, fuzzy +msgid "Select file to save to" +msgstr "Velg fil som skal Ã¥pnes" + +#: ../../po/../src/file.cpp:739 +msgid "No changes need to be saved." +msgstr "" + +#: ../../po/../src/file.cpp:926 +msgid "Select file to import" +msgstr "Velg fil som skal importeres" + +#: ../../po/../src/gradient-context.cpp:263 +msgid "Ctrl: snap gradient angle" +msgstr "" + +#: ../../po/../src/gradient-context.cpp:264 +msgid "Shift: draw gradient around the starting point" +msgstr "" + +#. We did an undoable action, but sp_document_done will be called by the knot when released +#. status text; we do not track coords because this branch is run once, not all the time +#. during drag +#: ../../po/../src/gradient-context.cpp:462 +#, c-format +msgid "Gradient for %d objects; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/gradient-context.cpp:464 +#, fuzzy +msgid "Select objects on which to create gradient." +msgstr "Klipp ut valgte objekter til utklippstavlen" + +#: ../../po/../src/gradient-drag.cpp:65 +#, fuzzy +msgid "Linear gradient start" +msgstr "Lineær gradient" + +#. POINT_LG_P1 +#: ../../po/../src/gradient-drag.cpp:66 +#, fuzzy +msgid "Linear gradient end" +msgstr "Lineær gradient" + +#: ../../po/../src/gradient-drag.cpp:67 +#, fuzzy +msgid "Radial gradient center" +msgstr "Radial gradient" + +#: ../../po/../src/gradient-drag.cpp:68 ../../po/../src/gradient-drag.cpp:69 +#, fuzzy +msgid "Radial gradient radius" +msgstr "Radial gradient" + +#: ../../po/../src/gradient-drag.cpp:70 +#, fuzzy +msgid "Radial gradient focus" +msgstr "Radial gradient" + +#: ../../po/../src/gradient-drag.cpp:659 +#, c-format +msgid "" +"%s for: %s%s; drag with Ctrl to snap angle, with Ctrl+Alt to " +"preserve angle, with Ctrl+Shift to scale around center" +msgstr "" + +#: ../../po/../src/gradient-drag.cpp:662 +msgid " (stroke)" +msgstr "" + +#: ../../po/../src/gradient-drag.cpp:665 +msgid "" +"Radial gradient center and focus; drag with Shift to " +"separate focus" +msgstr "" + +#: ../../po/../src/gradient-drag.cpp:667 +#, c-format +msgid "" +"Gradient point shared by %d gradients; drag with Shift to " +"separate" +msgstr "" + +#: ../../po/../src/helper/units.cpp:40 +msgid "Unit" +msgstr "Enhet" + +#: ../../po/../src/helper/units.cpp:40 +msgid "Units" +msgstr "Enheter" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Point" +msgstr "Punkt" + +#: ../../po/../src/helper/units.cpp:41 +msgid "pt" +msgstr "pt" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Points" +msgstr "Punkter" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Pt" +msgstr "Pkt" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Pixel" +msgstr "Piksel" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Pixels" +msgstr "Piksler" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Px" +msgstr "Px" + +#. You can add new elements from this point forward +#: ../../po/../src/helper/units.cpp:44 ../share/extensions/straightseg.inx.h:2 +msgid "Percent" +msgstr "Prosent" + +#: ../../po/../src/helper/units.cpp:44 +msgid "Percents" +msgstr "Prosent" + +#: ../../po/../src/helper/units.cpp:45 +msgid "Millimeter" +msgstr "Millimeter" + +#: ../../po/../src/helper/units.cpp:45 +msgid "mm" +msgstr "mm" + +#: ../../po/../src/helper/units.cpp:45 +msgid "Millimeters" +msgstr "Millimeter" + +#: ../../po/../src/helper/units.cpp:46 +msgid "Centimeter" +msgstr "Centimeter" + +#: ../../po/../src/helper/units.cpp:46 +msgid "cm" +msgstr "cm" + +#: ../../po/../src/helper/units.cpp:46 +msgid "Centimeters" +msgstr "Centimeter" + +#: ../../po/../src/helper/units.cpp:47 +msgid "Meter" +msgstr "Meter" + +#: ../../po/../src/helper/units.cpp:47 +msgid "m" +msgstr "m" + +#: ../../po/../src/helper/units.cpp:47 +#, fuzzy +msgid "Meters" +msgstr "Meter" + +#. no svg_unit +#: ../../po/../src/helper/units.cpp:48 +msgid "Inch" +msgstr "Tomme" + +#: ../../po/../src/helper/units.cpp:48 +msgid "in" +msgstr "in" + +#: ../../po/../src/helper/units.cpp:48 +msgid "Inches" +msgstr "Tommer" + +#. Volatiles do not have default, so there are none here +#. TRANSLATORS: for info, see http://www.w3.org/TR/REC-CSS2/syndata.html#length-units +#: ../../po/../src/helper/units.cpp:51 +msgid "Em square" +msgstr "Em kvadrat" + +#: ../../po/../src/helper/units.cpp:51 +msgid "em" +msgstr "em" + +#: ../../po/../src/helper/units.cpp:51 +msgid "Em squares" +msgstr "Em kvadrat" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/REC-CSS2/syndata.html#length-units +#: ../../po/../src/helper/units.cpp:53 +msgid "Ex square" +msgstr "Ex kvadrat" + +#: ../../po/../src/helper/units.cpp:53 +msgid "ex" +msgstr "ex" + +#: ../../po/../src/helper/units.cpp:53 +msgid "Ex squares" +msgstr "Ex kvadrat" + +#: ../../po/../src/inkscape.cpp:468 +msgid "Untitled document" +msgstr "Dokument uten navn" + +#. Show nice dialog box +#: ../../po/../src/inkscape.cpp:497 +#, fuzzy +msgid "Inkscape encountered an internal error and will close now.\n" +msgstr "Det oppsto en intern feil i sodipodi og programmet vil lukkes nÃ¥.\n" + +#: ../../po/../src/inkscape.cpp:498 +#, fuzzy +msgid "" +"Automatic backups of unsaved documents were done to the following " +"locations:\n" +msgstr "" +"Automatiske sikkerhetskopier av dokumenter som ikke er lagret ble utført til " +"følgende lokasjoner:\n" + +#: ../../po/../src/inkscape.cpp:499 +#, fuzzy +msgid "Automatic backup of the following documents failed:\n" +msgstr "Automatisk sikkerhetskopiering av følgende dokumenter feilet:\n" + +#: ../../po/../src/inkscape.cpp:634 +#, c-format +msgid "" +"Cannot create directory %s.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:635 +#, c-format +msgid "" +"%s is not a valid directory.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:636 +#, c-format +msgid "" +"Cannot create file %s.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:637 +#, c-format +msgid "" +"Cannot write file %s.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:638 +msgid "" +"Although Inkscape will run, it will use default settings,\n" +"and any changes made in preferences will not be saved." +msgstr "" + +#: ../../po/../src/inkscape.cpp:708 +#, c-format +msgid "" +"%s is not a regular file.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:709 +#, c-format +msgid "" +"%s not a valid XML file, or\n" +"you don't have read permissions on it.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:711 +#, c-format +msgid "" +"%s is not a valid menus file.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:712 +msgid "" +"Inkscape will run with default menus.\n" +"New menus will not be saved." +msgstr "" + +#. sp_ui_menu_append_check_item_from_verb(m, view, _("_Menu"), _("Show or hide the menu bar"), "menu", +#. checkitem_toggled, checkitem_update, 0); +#: ../../po/../src/interface.cpp:753 +msgid "Commands Bar" +msgstr "" + +#: ../../po/../src/interface.cpp:753 +#, fuzzy +msgid "Show or hide the Commands bar (under the menu)" +msgstr "Vis rutenett" + +#: ../../po/../src/interface.cpp:755 +#, fuzzy +msgid "Tool Controls" +msgstr "Alternativer for verktøy" + +#: ../../po/../src/interface.cpp:755 +#, fuzzy +msgid "Show or hide the Tool Controls panel" +msgstr "Vis rutenett" + +#: ../../po/../src/interface.cpp:757 +msgid "_Toolbox" +msgstr "" + +#: ../../po/../src/interface.cpp:757 +msgid "Show or hide the main toolbox (on the left)" +msgstr "" + +#: ../../po/../src/interface.cpp:763 +msgid "_Statusbar" +msgstr "" + +#: ../../po/../src/interface.cpp:763 +msgid "Show or hide the statusbar (at the bottom of the window)" +msgstr "" + +#: ../../po/../src/interface.cpp:820 +#, c-format +msgid "Verb \"%s\" Unknown" +msgstr "" + +#. TRANSLATORS: #%s is the id of the group e.g. , not a number. +#: ../../po/../src/interface.cpp:930 +#, fuzzy, c-format +msgid "Enter group #%s" +msgstr "Rediger" + +#: ../../po/../src/interface.cpp:941 +#, fuzzy +msgid "Go to parent" +msgstr "Ingen maling" + +#: ../../po/../src/interface.cpp:972 +msgid "Could not parse SVG data" +msgstr "" + +#: ../../po/../src/interface.cpp:1135 +#, c-format +msgid "Overwrite %s" +msgstr "" + +#: ../../po/../src/interface.cpp:1153 +#, c-format +msgid "" +"The file %s already exists. Do you want to overwrite that file with the " +"current document?" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:59 +msgid "Jabber connection lost." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:72 +#, c-format +msgid "Sending message; %u message remaining in send queue." +msgid_plural "Sending message; %u messages remaining in send queue." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:78 +msgid "Receive queue empty." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:154 +#, c-format +msgid "Receiving change; %u change left to process." +msgid_plural "Receiving change; %u changes left to process." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:157 +#, c-format +msgid "%s has left the chatroom." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:221 +msgid "Nickname %1 is already in use. Please choose a different nickname." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:225 +msgid "An error was encountered while attempting to connect to the server." +msgstr "" + +#. Check to see if the user made any modifications to this document. If so, +#. we want to give them the option of (1) letting us clear their document or (2) +#. opening a new, blank document for the whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:131 +msgid "%1 has invited you to a whiteboard session." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:132 +msgid "Incoming whiteboard invitation from %1" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:135 +msgid "Do you wish to accept %1's whiteboard session invitation?" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:137 +msgid "" +"Would you like to accept %1's invitation in a new document window?\n" +"Accepting the invitation in your current window will discard unsaved changes." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:143 +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:198 +#, fuzzy +msgid "Accept invitation" +msgstr "Valg" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:144 +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:199 +msgid "Decline invitation" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:145 +#, fuzzy +msgid "Accept invitation in new document window" +msgstr "Opprett nytt SVG-dokument" + +#. We could not create a new desktop; ask the user if she or he wants to +#. replace the current document and accept the invitation, or reject the invitation. +#. TRANSLATORS: %1 is a userid here +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:196 +msgid "" +"A new document window could not be opened for a whiteboard session with %" +"1" +msgstr "" + +#. TRANSLATORS: %1 is the peer whom refused our invitation. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:238 +msgid "" +"The user %1 has refused your " +"whiteboard invitation.\n" +"\n" +msgstr "" + +#. TRANSLATORS: %1 is the peer whom refused our invitation, %2 is our Jabber identity. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:241 +msgid "" +"You are still connected to a Jabber server as %2, and may send an " +"invitation to %1 again, or you may send an invitation to a different " +"user." +msgstr "" + +#. TRANSLATORS: %1 is the peer whom we tried to contact, but is already in a whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:252 +msgid "" +"The user %1 is already in a " +"whiteboard session.\n" +"\n" +msgstr "" + +#. TRANSLATORS: %1 is the peer whom we tried to contact, but is already in a whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:255 +msgid "" +"You are still connected to a Jabber server as %1, and may send an " +"invitation to a different user." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/invitation-confirm-dialog.cpp:26 +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:24 +msgid "_Write session file:" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/message-processors.cpp:145 +#, c-format +msgid "%s has joined the chatroom." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/message-queue.cpp:87 +#, c-format +msgid "%u change in receive queue." +msgid_plural "%u changes in receive queue." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/jabber_whiteboard/message-queue.cpp:117 +#, c-format +msgid "%u change in send queue." +msgid_plural "%u changes in send queue." +msgstr[0] "" +msgstr[1] "" + +#. if ID is NULL, then we have a real problem -- we were not able to find a key +#. nor generate one. The only thing we can really do here is abort, since we have +#. no way to let the other client(s) uniquely identify this object. +#. FIXME: If this indicates a programming bug, then don't request translation with +#. * _(...): it is most useful in untranslated form so that developers may search for +#. * it when someone reports it in a bug report (as we want users to do for all bugs, +#. * as indicated by it being a g_warning string). +#. * +#. * Otherwise, if it is not a programming bug but a network error or a bug in the +#. * remote peer (perhaps running different software) or whatever, then present it in +#. * an alert box, and avoid use of technical jargon `NULL'. +#. +#: ../../po/../src/jabber_whiteboard/message-utilities.cpp:171 +msgid "" +"ID for new object is NULL even after generation and lookup attempts: the new " +"object will NOT be sent, nor will any of its child objects!" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:60 +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:995 +msgid "Select a location and filename" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:62 +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:997 +#, fuzzy +msgid "Set filename" +msgstr "Lagre fil" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:301 +msgid "No SSL certificate was found." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:304 +msgid "The SSL certificate provided by the Jabber server is untrusted." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:307 +msgid "The SSL certificate provided by the Jabber server is expired." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:310 +msgid "" +"The SSL certificate provided by the Jabber server has not been activated." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:313 +msgid "" +"The SSL certificate provided by the Jabber server contains a hostname that " +"does not match the Jabber server's hostname." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:316 +msgid "" +"The SSL certificate provided by the Jabber server contains an invalid " +"fingerprint." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:319 +msgid "An unknown error occurred while setting up the SSL connection." +msgstr "" + +#. TRANSLATORS: %1 is the message that describes the specific error that occurred when +#. establishing the SSL connection. +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:325 +msgid "" +"%1\n" +"\n" +"Do you wish to continue connecting to the Jabber server?" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:328 +msgid "Continue connecting and ignore further errors" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:329 +msgid "Continue connecting, but warn me of further errors" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:330 +#, fuzzy +msgid "Cancel connection" +msgstr "Valg" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:777 +#, c-format +msgid "Established whiteboard session with %s." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:785 +#, c-format +msgid "%s has left the whiteboard session." +msgstr "" + +#. Inform the user +#. TRANSLATORS: %1 is the name of the user that disconnected, %2 is the name of the user whom the disconnected user disconnected from. +#. This message is not used in a chatroom context. +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:790 +msgid "" +"The user %1 has left the " +"whiteboard session.\n" +"\n" +msgstr "" + +#. TRANSLATORS: %1 and %2 are userids +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:792 +msgid "" +"You are still connected to a Jabber server as %2, and may establish a " +"new session to %1 or a different user." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:988 +msgid "" +"Could not open file %1 for session recording.\n" +"The error encountered was: %2.\n" +"\n" +"You may select a different location to record the session, or you may opt to " +"not record this session." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:990 +msgid "Choose a different location" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:991 +msgid "Skip session recording" +msgstr "" + +#: ../../po/../src/knot.cpp:673 +msgid "Node or handle drag canceled." +msgstr "" + +#: ../../po/../src/libnrtype/FontFactory.cpp:358 +msgid "Ignoring font without family that will crash Pango" +msgstr "" + +#: ../../po/../src/main.cpp:395 +msgid "Print the Inkscape version number" +msgstr "" + +#: ../../po/../src/main.cpp:400 +msgid "Do not use X server (only process files from console)" +msgstr "Ikke bruk X-tjeneren (prosesser filer fra konsollet)" + +#: ../../po/../src/main.cpp:405 +#, fuzzy +msgid "Try to use X server (even if $DISPLAY is not set)" +msgstr "Prøv Ã¥ bruke X-tjeneren selv om ikke $DISPLAY er satt." + +#: ../../po/../src/main.cpp:410 +msgid "Open specified document(s) (option string may be excluded)" +msgstr "Åpne spesifisert(e) dokument(er) (alternativ-streng kan eksluderes)" + +#: ../../po/../src/main.cpp:411 ../../po/../src/main.cpp:416 +#: ../../po/../src/main.cpp:421 ../../po/../src/main.cpp:483 +#: ../../po/../src/main.cpp:488 ../../po/../src/main.cpp:493 +msgid "FILENAME" +msgstr "FILNAVN" + +#: ../../po/../src/main.cpp:415 +msgid "Print document(s) to specified output file (use '| program' for pipe)" +msgstr "Skriv ut dokument(er) til spesifisert utfil (bruk '| program' for rør)" + +#: ../../po/../src/main.cpp:420 +#, fuzzy +msgid "Export document to a PNG file" +msgstr "Eksporter dokument som en png-fil" + +#: ../../po/../src/main.cpp:425 +msgid "The resolution used for exporting SVG into bitmap (default 90)" +msgstr "" + +#: ../../po/../src/main.cpp:426 +msgid "DPI" +msgstr "DPI" + +#: ../../po/../src/main.cpp:430 +#, fuzzy +msgid "" +"Exported area in SVG user units (default is the canvas; 0,0 is lower-left " +"corner)" +msgstr "" +"Eksportert omrÃ¥de i millimeter (forvalg er hele dokumentet, 0,0 er nedre " +"venstre hjørne)" + +#: ../../po/../src/main.cpp:431 +msgid "x0:y0:x1:y1" +msgstr "x0:y0:x1:y1" + +#: ../../po/../src/main.cpp:435 +msgid "Exported area is the entire drawing (not canvas)" +msgstr "" + +#: ../../po/../src/main.cpp:440 +msgid "" +"Snap the bitmap export area outwards to the nearest integer values (in SVG " +"user units)" +msgstr "" + +#: ../../po/../src/main.cpp:445 +msgid "The width of exported bitmap in pixels (overrides export-dpi)" +msgstr "" + +#: ../../po/../src/main.cpp:446 +msgid "WIDTH" +msgstr "BREDDE" + +#: ../../po/../src/main.cpp:450 +msgid "The height of exported bitmap in pixels (overrides export-dpi)" +msgstr "" + +#: ../../po/../src/main.cpp:451 +msgid "HEIGHT" +msgstr "HØYDE" + +#: ../../po/../src/main.cpp:455 +msgid "The ID of the object to export (overrides export-area)" +msgstr "" + +#: ../../po/../src/main.cpp:456 ../../po/../src/main.cpp:532 +msgid "ID" +msgstr "" + +#. TRANSLATORS: this means: "Only export the object whose id is given in --export-id". +#. See "man inkscape" for details. +#: ../../po/../src/main.cpp:462 +msgid "" +"Export just the object with export-id, hide all others (only with export-id)" +msgstr "" + +#: ../../po/../src/main.cpp:467 +msgid "Use stored filename and DPI hints when exporting (only with export-id)" +msgstr "" + +#: ../../po/../src/main.cpp:472 +msgid "Background color of exported bitmap (any SVG-supported color string)" +msgstr "" + +#: ../../po/../src/main.cpp:473 +msgid "COLOR" +msgstr "FARGE" + +#: ../../po/../src/main.cpp:477 +msgid "Background opacity of exported bitmap (either 0.0 to 1.0, or 1 to 255)" +msgstr "" + +#: ../../po/../src/main.cpp:478 +msgid "VALUE" +msgstr "" + +#: ../../po/../src/main.cpp:482 +#, fuzzy +msgid "Export document to plain SVG file (no sodipodi or inkscape namespaces)" +msgstr "" +"Eksporter dokument til en vanlig SVG-fil (ingen «xmlns:sodipodi» navneomrÃ¥de)" + +#: ../../po/../src/main.cpp:487 +#, fuzzy +msgid "Export document to a PS file" +msgstr "Eksporter dokument som en png-fil" + +#: ../../po/../src/main.cpp:492 +#, fuzzy +msgid "Export document to an EPS file" +msgstr "Eksporter dokument som en png-fil" + +#: ../../po/../src/main.cpp:497 +#, fuzzy +msgid "Convert text object to paths on export (EPS)" +msgstr "Senk valgte objekter til bunnen" + +#: ../../po/../src/main.cpp:502 +msgid "Export files with the bounding box set to the page size (EPS)" +msgstr "" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:508 +msgid "" +"Query the X coordinate of the drawing or, if specified, of the object with --" +"query-id" +msgstr "" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:514 +msgid "" +"Query the Y coordinate of the drawing or, if specified, of the object with --" +"query-id" +msgstr "" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:520 +msgid "" +"Query the width of the drawing or, if specified, of the object with --query-" +"id" +msgstr "" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:526 +msgid "" +"Query the height of the drawing or, if specified, of the object with --query-" +"id" +msgstr "" + +#: ../../po/../src/main.cpp:531 +msgid "The ID of the object whose dimensions are queried" +msgstr "" + +#. TRANSLATORS: this option makes Inkscape print the name (path) of the extension directory +#: ../../po/../src/main.cpp:537 +msgid "Print out the extension directory and exit" +msgstr "" + +#: ../../po/../src/main.cpp:542 +msgid "Show given files one-by-one, switch to next on any key/mouse event" +msgstr "" +"Vis oppgitte filer en-etter-en, bytt til neste ved tastatur-/mus-hendelse" + +#: ../../po/../src/main.cpp:547 +msgid "Use the new Gtkmm GUI interface" +msgstr "" + +#: ../../po/../src/main.cpp:552 +msgid "Remove unused definitions from the defs section(s) of the document" +msgstr "" + +#: ../../po/../src/main.cpp:741 +msgid "" +"[OPTIONS...] [FILE...]\n" +"\n" +"Available options:" +msgstr "" + +#: ../../po/../src/menus-skeleton.h:17 +#, fuzzy +msgid "_New" +msgstr "Ny" + +#: ../../po/../src/menus-skeleton.h:22 +#, fuzzy +msgid "Open _Recent" +msgstr "Åpne" + +#: ../../po/../src/menus-skeleton.h:53 +#, fuzzy +msgid "_Edit" +msgstr "Rediger" + +#: ../../po/../src/menus-skeleton.h:84 +#, fuzzy +msgid "_View" +msgstr "Visning" + +#: ../../po/../src/menus-skeleton.h:85 +#, fuzzy +msgid "_Zoom" +msgstr "Zoom" + +#: ../../po/../src/menus-skeleton.h:102 +#, fuzzy +msgid "Show/Hide" +msgstr "Vis rutenett" + +#: ../../po/../src/menus-skeleton.h:107 +#, fuzzy +msgid "_Display mode" +msgstr "Skjerminstillinger" + +#: ../../po/../src/menus-skeleton.h:126 +#, fuzzy +msgid "_Layer" +msgstr "Senk" + +#: ../../po/../src/menus-skeleton.h:143 +#, fuzzy +msgid "_Object" +msgstr "Objekt" + +#: ../../po/../src/menus-skeleton.h:165 +#, fuzzy +msgid "_Path" +msgstr "Lim inn" + +#: ../../po/../src/menus-skeleton.h:188 +#, fuzzy +msgid "_Text" +msgstr "Tekst" + +#: ../../po/../src/menus-skeleton.h:200 +#, fuzzy +msgid "Effects" +msgstr "Objekt" + +#: ../../po/../src/menus-skeleton.h:207 +msgid "Whiteboa_rd" +msgstr "" + +#: ../../po/../src/menus-skeleton.h:220 +#, fuzzy +msgid "_Help" +msgstr "Sider:" + +#: ../../po/../src/menus-skeleton.h:222 +msgid "Tutorials" +msgstr "" + +#: ../../po/../src/node-context.cpp:382 +msgid "" +"Ctrl: toggle node type, snap handle angle, move hor/vert; Ctrl" +"+Alt: move along handles" +msgstr "" + +#: ../../po/../src/node-context.cpp:383 +msgid "" +"Shift: toggle node selection, disable snapping, rotate both handles" +msgstr "" + +#: ../../po/../src/node-context.cpp:384 +msgid "Alt: lock handle length; Ctrl+Alt: move along handles" +msgstr "" + +#: ../../po/../src/nodepath.cpp:1399 ../../po/../src/nodepath.cpp:1411 +#: ../../po/../src/nodepath.cpp:1492 ../../po/../src/nodepath.cpp:1504 +msgid "To join, you must have two endnodes selected." +msgstr "" + +#: ../../po/../src/nodepath.cpp:1633 ../../po/../src/nodepath.cpp:1647 +msgid "" +"Select two non-endpoint nodes on a path between which to delete " +"segments." +msgstr "" + +#: ../../po/../src/nodepath.cpp:1743 +#, fuzzy +msgid "Cannot find path between nodes." +msgstr "SlÃ¥ sammen linjer ved valgte noder" + +#: ../../po/../src/nodepath.cpp:2822 +#, c-format +msgid "" +"Node handle: angle %0.2f°, length %s; with Ctrl to snap " +"angle; with Alt to lock length; with Shift to rotate both " +"handles" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3351 +msgid "" +"Node: drag to edit the path; with Ctrl to snap to horizontal/" +"vertical; with Ctrl+Alt to snap to handles' directions" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3375 +msgid "" +"Node handle: drag to shape the curve; with Ctrl to snap angle; " +"with Alt to lock length; with Shift to rotate both handles" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3399 +msgid "" +"Node handle: drag to shape the curve; with Ctrl to snap angle; " +"with Alt to lock length; with Shift to rotate the opposite " +"handle in sync" +msgstr "" + +#. TRANSLATORS: "end" is an adjective here (NOT a verb) +#: ../../po/../src/nodepath.cpp:3591 +#, fuzzy +msgid "end node" +msgstr "Rykk inn node" + +#. TRANSLATORS: "cusp" means "sharp" (cusp node); see also the Advanced Tutorial +#: ../../po/../src/nodepath.cpp:3596 +msgid "cusp" +msgstr "" + +#. TRANSLATORS: "smooth" is an adjective here +#: ../../po/../src/nodepath.cpp:3599 +msgid "smooth" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3601 +msgid "symmetric" +msgstr "" + +#. TRANSLATORS: "end" is an adjective here (NOT a verb) +#: ../../po/../src/nodepath.cpp:3607 +msgid "end node, handle retracted (drag with Shift to extend)" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3609 +msgid "one handle retracted (drag with Shift to extend)" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3612 +msgid "both handles retracted (drag with Shift to extend)" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3624 +#, fuzzy +msgid "Drag nodes or node handles; arrow keys to move nodes" +msgstr "Oppretter ny kurve. Trykk «+» for Ã¥ velge mellom Legg til/Ny." + +#: ../../po/../src/nodepath.cpp:3625 +#, fuzzy +msgid "Drag the node or its handles; arrow keys to move the node" +msgstr "Oppretter ny kurve. Trykk «+» for Ã¥ velge mellom Legg til/Ny." + +#: ../../po/../src/nodepath.cpp:3651 ../../po/../src/nodepath.cpp:3663 +#, fuzzy +msgid "Select a single object to edit its nodes or handles." +msgstr "Ingen gradienter i dokumentet" + +#: ../../po/../src/nodepath.cpp:3655 +#, c-format +msgid "" +"0 out of %i node selected. Click, Shift+click, " +"or drag around nodes to select." +msgid_plural "" +"0 out of %i nodes selected. Click, Shift+click, " +"or drag around nodes to select." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/nodepath.cpp:3661 +msgid "Drag the handles of the object to modify it." +msgstr "" + +#: ../../po/../src/nodepath.cpp:3669 +#, fuzzy, c-format +msgid "%i of %i node selected; %s. %s." +msgid_plural "%i of %i nodes selected; %s. %s." +msgstr[0] "SlÃ¥ sammen linjer ved valgte noder" +msgstr[1] "SlÃ¥ sammen linjer ved valgte noder" + +#: ../../po/../src/nodepath.cpp:3675 +#, fuzzy, c-format +msgid "%i of %i node selected. %s." +msgid_plural "%i of %i nodes selected. %s." +msgstr[0] "SlÃ¥ sammen linjer ved valgte noder" +msgstr[1] "SlÃ¥ sammen linjer ved valgte noder" + +#: ../../po/../src/object-edit.cpp:493 +msgid "" +"Adjust the horizontal rounding radius; with Ctrl to make the " +"vertical radius the same" +msgstr "" + +#: ../../po/../src/object-edit.cpp:499 +msgid "" +"Adjust the vertical rounding radius; with Ctrl to make the " +"horizontal radius the same" +msgstr "" + +#: ../../po/../src/object-edit.cpp:506 ../../po/../src/object-edit.cpp:513 +msgid "" +"Adjust the width and height of the rectangle; with Ctrl to " +"lock ratio or stretch in one dimension only" +msgstr "" + +#: ../../po/../src/object-edit.cpp:686 +msgid "Adjust ellipse width, with Ctrl to make circle" +msgstr "" + +#: ../../po/../src/object-edit.cpp:689 +msgid "Adjust ellipse height, with Ctrl to make circle" +msgstr "" + +#: ../../po/../src/object-edit.cpp:692 +msgid "" +"Position the start point of the arc or segment; with Ctrl to " +"snap angle; drag inside the ellipse for arc, outside for " +"segment" +msgstr "" + +#: ../../po/../src/object-edit.cpp:695 +msgid "" +"Position the end point of the arc or segment; with Ctrl to " +"snap angle; drag inside the ellipse for arc, outside for " +"segment" +msgstr "" + +#: ../../po/../src/object-edit.cpp:800 +msgid "" +"Adjust the tip radius of the star or polygon; with Shift to " +"round; with Alt to randomize" +msgstr "" + +#: ../../po/../src/object-edit.cpp:803 +msgid "" +"Adjust the base radius of the star; with Ctrl to keep star " +"rays radial (no skew); with Shift to round; with Alt to " +"randomize" +msgstr "" + +#: ../../po/../src/object-edit.cpp:967 +msgid "" +"Roll/unroll the spiral from inside; with Ctrl to snap angle; " +"with Alt to converge/diverge" +msgstr "" + +#: ../../po/../src/object-edit.cpp:969 +msgid "" +"Roll/unroll the spiral from outside; with Ctrl to snap angle; " +"with Shift to scale/rotate" +msgstr "" + +#: ../../po/../src/object-edit.cpp:1006 +msgid "Adjust the offset distance" +msgstr "" + +#. TRANSLATORS: This refers to the pattern that's inside the object +#: ../../po/../src/object-edit.cpp:1036 +msgid "Move the pattern fill inside the object" +msgstr "" + +#: ../../po/../src/object-edit.cpp:1038 +#, fuzzy +msgid "Scale the pattern fill uniformly" +msgstr "Klipp ut valgte objekter til utklippstavlen" + +#: ../../po/../src/object-edit.cpp:1040 +msgid "Rotate the pattern fill; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/object-edit.cpp:1065 +msgid "Drag to resize the flowed text frame" +msgstr "" + +#. Item dialog +#: ../../po/../src/object-ui.cpp:106 +#, fuzzy +msgid "Object _Properties" +msgstr "Egenskaper for rektangel" + +#. Select item +#: ../../po/../src/object-ui.cpp:116 +#, fuzzy +msgid "_Select This" +msgstr "Velg dette" + +#. Create link +#: ../../po/../src/object-ui.cpp:126 +#, fuzzy +msgid "_Create Link" +msgstr "Opprett lenke" + +#. "Ungroup" +#: ../../po/../src/object-ui.cpp:199 ../../po/../src/verbs.cpp:1931 +#, fuzzy +msgid "_Ungroup" +msgstr "Del opp gruppe" + +#. Link dialog +#: ../../po/../src/object-ui.cpp:239 +#, fuzzy +msgid "Link _Properties" +msgstr "Egenskaper for lenke" + +#. Select item +#: ../../po/../src/object-ui.cpp:249 +#, fuzzy +msgid "_Follow Link" +msgstr "Følg lenke" + +#. Reset transformations +#: ../../po/../src/object-ui.cpp:254 +#, fuzzy +msgid "_Remove Link" +msgstr "Fjern lenke" + +#. Link dialog +#: ../../po/../src/object-ui.cpp:303 +#, fuzzy +msgid "Image _Properties" +msgstr "Egenskaper for bilde" + +#. Item dialog +#: ../../po/../src/object-ui.cpp:344 +#, fuzzy +msgid "_Fill and Stroke" +msgstr "Fyll og strøk" + +#: ../../po/../src/path-chemistry.cpp:58 +#, fuzzy +msgid "Select at least two objects to combine." +msgstr "Ingen gradienter i dokumentet" + +#: ../../po/../src/path-chemistry.cpp:65 +#, fuzzy +msgid "At least one of the objects is not a path, cannot combine." +msgstr "Senk valgte objekter til bunnen" + +#: ../../po/../src/path-chemistry.cpp:73 +msgid "" +"You cannot combine objects from different groups or layers." +msgstr "" + +#: ../../po/../src/path-chemistry.cpp:155 +#, fuzzy +msgid "Select path(s) to break apart." +msgstr "Klipp ut valgte objekter til utklippstavlen" + +#: ../../po/../src/path-chemistry.cpp:231 +msgid "No path(s) to break apart in the selection." +msgstr "" + +#: ../../po/../src/path-chemistry.cpp:252 +#, fuzzy +msgid "Select object(s) to convert to path." +msgstr "Klipp ut valgte objekter til utklippstavlen" + +#: ../../po/../src/path-chemistry.cpp:297 +#, fuzzy +msgid "No objects to convert to path in the selection." +msgstr "Klipp ut valgte objekter til utklippstavlen" + +#: ../../po/../src/path-chemistry.cpp:345 +#, fuzzy +msgid "Select path(s) to reverse." +msgstr "Hev valgte objekter til toppen" + +#: ../../po/../src/path-chemistry.cpp:370 +msgid "No paths to reverse in the selection." +msgstr "" + +#: ../../po/../src/pen-context.cpp:379 ../../po/../src/pencil-context.cpp:233 +#, fuzzy +msgid "Continuing selected path" +msgstr "Senk valgte objekter til bunnen" + +#: ../../po/../src/pen-context.cpp:390 ../../po/../src/pencil-context.cpp:242 +#, fuzzy +msgid "Creating new path" +msgstr "Opprett nytt SVG-dokument" + +#: ../../po/../src/pen-context.cpp:394 ../../po/../src/pencil-context.cpp:246 +#, fuzzy +msgid "Appending to selected path" +msgstr "Senk valgte objekter til bunnen" + +#: ../../po/../src/pen-context.cpp:538 +msgid "Click or click and drag to close and finish the path." +msgstr "" + +#: ../../po/../src/pen-context.cpp:548 +msgid "" +"Click or click and drag to continue the path from this point." +msgstr "" + +#: ../../po/../src/pen-context.cpp:857 +#, c-format +msgid "" +"%s: angle %3.2f°, distance %s; with Ctrl to snap angle, " +"Enter to finish the path" +msgstr "" + +#: ../../po/../src/pen-context.cpp:882 +#, c-format +msgid "" +"Curve handle: angle %3.2f°, length %s; with Ctrl to snap " +"angle" +msgstr "" + +#: ../../po/../src/pen-context.cpp:912 +#, c-format +msgid "" +"%s: angle %3.2f°, length %s; with Ctrl to snap angle, " +"with Shift to move this handle only" +msgstr "" + +#: ../../po/../src/pen-context.cpp:946 +#, fuzzy +msgid "Finishing pen" +msgstr "FrihÃ¥nd" + +#: ../../po/../src/pencil-context.cpp:320 +msgid "Release here to close and finish the path." +msgstr "" + +#: ../../po/../src/pencil-context.cpp:326 +#, fuzzy +msgid "Drawing a freehand path" +msgstr "Opprett nytt SVG-dokument" + +#: ../../po/../src/pencil-context.cpp:331 +msgid "Drag to continue the path from this point." +msgstr "" + +#. Write curves to object +#: ../../po/../src/pencil-context.cpp:390 +#, fuzzy +msgid "Finishing freehand" +msgstr "FrihÃ¥nd" + +#: ../../po/../src/rect-context.cpp:387 +msgid "" +"Ctrl: make square or integer-ratio rect, lock a rounded corner " +"circular" +msgstr "" + +#: ../../po/../src/rect-context.cpp:549 +#, c-format +msgid "" +"Rectangle: %s × %s; with Ctrl to make square or integer-" +"ratio rectangle; with Shift to draw around the starting point" +msgstr "" + +#: ../../po/../src/select-context.cpp:243 +#, fuzzy +msgid "Move canceled." +msgstr "Valg" + +#: ../../po/../src/select-context.cpp:252 +#, fuzzy +msgid "Selection canceled." +msgstr "Valg" + +#: ../../po/../src/select-context.cpp:642 +msgid "Ctrl: select in groups, move hor/vert" +msgstr "" + +#: ../../po/../src/select-context.cpp:643 +msgid "Shift: toggle select, force rubberband, disable snapping" +msgstr "" + +#: ../../po/../src/select-context.cpp:644 +msgid "Alt: select under, move selected" +msgstr "" + +#: ../../po/../src/select-context.cpp:798 +#, fuzzy +msgid "Selected object is not a group. Cannot enter." +msgstr "Senk valgte objekter til bunnen" + +#: ../../po/../src/select-context.cpp:876 +#, c-format +msgid "" +"Move by %s, %s; with Ctrl to restrict to horizontal/vertical; " +"with Shift to disable snapping" +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:228 +msgid "Nothing was deleted." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:259 +#, fuzzy +msgid "Select object(s) to duplicate." +msgstr "Klipp ut valgte objekter til utklippstavlen" + +#: ../../po/../src/selection-chemistry.cpp:420 +#, fuzzy +msgid "Select two or more objects to group." +msgstr "Hev valgte objekter til toppen" + +#: ../../po/../src/selection-chemistry.cpp:428 +#, fuzzy +msgid "Select at least two objects to group." +msgstr "Ingen gradienter i dokumentet" + +#: ../../po/../src/selection-chemistry.cpp:513 +#, fuzzy +msgid "Select a group to ungroup." +msgstr "Hev valgte objekter til toppen" + +#: ../../po/../src/selection-chemistry.cpp:554 +msgid "No groups to ungroup in the selection." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:623 +#, fuzzy +msgid "Select objects to raise." +msgstr "Klipp ut valgte objekter til utklippstavlen" + +#: ../../po/../src/selection-chemistry.cpp:629 +#: ../../po/../src/selection-chemistry.cpp:681 +#: ../../po/../src/selection-chemistry.cpp:715 +#: ../../po/../src/selection-chemistry.cpp:773 +msgid "" +"You cannot raise/lower objects from different groups or layers." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:673 +#, fuzzy +msgid "Select object(s) to raise to top." +msgstr "Senk valgte objekter til bunnen" + +#: ../../po/../src/selection-chemistry.cpp:709 +#, fuzzy +msgid "Select object(s) to lower." +msgstr "Klipp ut valgte objekter til utklippstavlen" + +#: ../../po/../src/selection-chemistry.cpp:765 +#, fuzzy +msgid "Select object(s) to lower to bottom." +msgstr "Klipp ut valgte objekter til utklippstavlen" + +#: ../../po/../src/selection-chemistry.cpp:806 +msgid "Nothing to undo." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:813 +msgid "Nothing to redo." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:969 +msgid "Nothing was copied." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1051 +msgid "Current layer is hidden. Unhide it to be able to paste to it." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1055 +msgid "Current layer is locked. Unlock it to be able to paste to it." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1068 +#: ../../po/../src/selection-chemistry.cpp:1103 +#, fuzzy +msgid "Nothing on the clipboard." +msgstr "Kopier valgte objekter til utklippstavlen" + +#: ../../po/../src/selection-chemistry.cpp:1109 +#, fuzzy +msgid "Select object(s) to paste style to." +msgstr "Senk valgte objekter til bunnen" + +#: ../../po/../src/selection-chemistry.cpp:1128 +#, fuzzy +msgid "Select object(s) to move to the layer above." +msgstr "Klipp ut valgte objekter til utklippstavlen" + +#: ../../po/../src/selection-chemistry.cpp:1146 +#, fuzzy +msgid "No more layers above." +msgstr "Dokumentnavn:" + +#: ../../po/../src/selection-chemistry.cpp:1160 +#, fuzzy +msgid "Select object(s) to move to the layer below." +msgstr "Klipp ut valgte objekter til utklippstavlen" + +#: ../../po/../src/selection-chemistry.cpp:1178 +#, fuzzy +msgid "No more layers below." +msgstr "Dokumentnavn:" + +#: ../../po/../src/selection-chemistry.cpp:1811 +#, fuzzy +msgid "Select a clone to unlink." +msgstr "Velg fil som skal Ã¥pnes" + +#: ../../po/../src/selection-chemistry.cpp:1842 +msgid "No clones to unlink in the selection." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1859 +msgid "" +"Select a clone to go to its original. Select a linked offset " +"to go to its source. Select a text on path to go to the path. Select " +"a flowed text to go to its frame." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1882 +msgid "" +"Cannot find the object to select (orphaned clone, offset, textpath, " +"flowed text?)" +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1888 +msgid "" +"The object you're trying to select is not visible (it is in <" +"defs>)" +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1915 +#, fuzzy +msgid "Select object(s) to convert to pattern." +msgstr "Klipp ut valgte objekter til utklippstavlen" + +#: ../../po/../src/selection-chemistry.cpp:2006 +#, fuzzy +msgid "Select an object with pattern fill to extract objects from." +msgstr "Klipp ut valgte objekter til utklippstavlen" + +#: ../../po/../src/selection-chemistry.cpp:2059 +#, fuzzy +msgid "No pattern fills in the selection." +msgstr "Klipp ut valgte objekter til utklippstavlen" + +#: ../../po/../src/selection-chemistry.cpp:2079 +#, fuzzy +msgid "Select object(s) to make a bitmap copy." +msgstr "Senk valgte objekter til bunnen" + +#: ../../po/../src/selection-describer.cpp:37 +msgid "Click selection to toggle scale/rotation handles" +msgstr "" + +#. no items +#: ../../po/../src/selection-describer.cpp:39 +msgid "" +"No objects selected. Click, Shift+click, or drag around objects to select." +msgstr "" + +#: ../../po/../src/selection-describer.cpp:51 +#, fuzzy, c-format +msgid " in layer %s" +msgstr "Hev node" + +#: ../../po/../src/selection-describer.cpp:54 +#, fuzzy, c-format +msgid " in layer %s" +msgstr "Hev node" + +#: ../../po/../src/selection-describer.cpp:66 +msgid "Use Shift+D to look up original" +msgstr "" + +#: ../../po/../src/selection-describer.cpp:70 +msgid "Use Shift+D to look up path" +msgstr "" + +#: ../../po/../src/selection-describer.cpp:74 +msgid "Use Shift+D to look up frame" +msgstr "" + +#: ../../po/../src/selection-describer.cpp:84 +#, fuzzy, c-format +msgid "%i object selected" +msgid_plural "%i objects selected" +msgstr[0] "SlÃ¥ sammen linjer ved valgte noder" +msgstr[1] "SlÃ¥ sammen linjer ved valgte noder" + +#: ../../po/../src/selection-describer.cpp:90 +#, c-format +msgid "%s%s. %s." +msgstr "" + +#: ../../po/../src/selection-describer.cpp:94 +#, fuzzy, c-format +msgid "%s in %i layer. %s." +msgid_plural "%s in %i layers. %s." +msgstr[0] "SlÃ¥ sammen linjer ved valgte noder" +msgstr[1] "SlÃ¥ sammen linjer ved valgte noder" + +#: ../../po/../src/seltrans.cpp:498 +msgid "" +"Center of rotation and skewing: drag to reposition; scaling with " +"Shift also uses this center" +msgstr "" + +#: ../../po/../src/seltrans.cpp:514 +msgid "" +"Squeeze or stretch selection; with Ctrl to scale uniformly; " +"with Shift to scale around rotation center" +msgstr "" + +#: ../../po/../src/seltrans.cpp:515 +msgid "" +"Scale selection; with Ctrl to scale uniformly; with Shift to scale around rotation center" +msgstr "" + +#: ../../po/../src/seltrans.cpp:519 +msgid "" +"Skew selection; with Ctrl to snap angle; with Shift to " +"skew around the opposite side" +msgstr "" + +#: ../../po/../src/seltrans.cpp:520 +msgid "" +"Rotate selection; with Ctrl to snap angle; with Shift " +"to rotate around the opposite corner" +msgstr "" + +#: ../../po/../src/seltrans.cpp:829 ../../po/../src/seltrans.cpp:909 +#, c-format +msgid "Scale: %0.2f%% x %0.2f%%; with Ctrl to lock ratio" +msgstr "" + +#. TRANSLATORS: don't modify the first ";" (it will NOT be displayed as ";" - only the second one will be) +#: ../../po/../src/seltrans.cpp:984 +#, c-format +msgid "Skew: %0.2f°; with Ctrl to snap angle" +msgstr "" + +#. TRANSLATORS: don't modify the first ";" (it will NOT be displayed as ";" - only the second one will be) +#: ../../po/../src/seltrans.cpp:1035 +#, c-format +msgid "Rotate: %0.2f°; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/seltrans.cpp:1090 +#, fuzzy, c-format +msgid "Move center to %s, %s" +msgstr "Lenke til %s" + +#: ../../po/../src/slideshow.cpp:90 +#, fuzzy +msgid "Inkscape slideshow" +msgstr "Sodipodi: %s: XML-visning" + +#: ../../po/../src/sp-anchor.cpp:181 +#, fuzzy, c-format +msgid "Link to %s" +msgstr "Lenke til %s" + +#: ../../po/../src/sp-anchor.cpp:185 +#, fuzzy +msgid "Link without URI" +msgstr "Lenke til %s" + +#: ../../po/../src/sp-ellipse.cpp:438 ../../po/../src/sp-ellipse.cpp:870 +msgid "Ellipse" +msgstr "" + +#: ../../po/../src/sp-ellipse.cpp:583 +msgid "Circle" +msgstr "" + +#: ../../po/../src/sp-ellipse.cpp:865 +#, fuzzy +msgid "Segment" +msgstr "Rektangel" + +#: ../../po/../src/sp-ellipse.cpp:867 +msgid "Arc" +msgstr "" + +#. TRANSLATORS: "Flow region" is an area where text is allowed to flow +#: ../../po/../src/sp-flowregion.cpp:276 +#, fuzzy +msgid "Flow region" +msgstr "Følg lenke" + +#. TRANSLATORS: A region "cut out of" a flow region; text is not allowed to flow inside the +#. * flow excluded region. flowRegionExclude in SVG 1.2: see +#. * http://www.w3.org/TR/2004/WD-SVG12-20041027/flow.html#flowRegion-elem and +#. * http://www.w3.org/TR/2004/WD-SVG12-20041027/flow.html#flowRegionExclude-elem. +#: ../../po/../src/sp-flowregion.cpp:493 +msgid "Flow excluded region" +msgstr "" + +#: ../../po/../src/sp-flowtext.cpp:355 +#, c-format +msgid "Flowed text (%d characters)" +msgstr "" + +#: ../../po/../src/sp-flowtext.cpp:357 +#, c-format +msgid "Linked flowed text (%d characters)" +msgstr "" + +#: ../../po/../src/sp-guide.cpp:290 +#, fuzzy +msgid "vertical guideline" +msgstr "Sentrer vertikalt" + +#: ../../po/../src/sp-guide.cpp:292 +#, fuzzy +msgid "horizontal guideline" +msgstr "Vend valgte objekter horisontalt" + +#: ../../po/../src/sp-image.cpp:835 +msgid "embedded" +msgstr "" + +#: ../../po/../src/sp-image.cpp:839 +msgid "(null_pointer)" +msgstr "" + +#: ../../po/../src/sp-image.cpp:843 +#, fuzzy, c-format +msgid "Image with bad reference: %s" +msgstr "Bilde med ugyldig referanse: %s" + +#: ../../po/../src/sp-image.cpp:844 +#, fuzzy, c-format +msgid "Image %d × %d: %s" +msgstr "Fargebilde %d x %d: %s" + +#: ../../po/../src/sp-item-group.cpp:390 +#, fuzzy, c-format +msgid "Group of %d object" +msgid_plural "Group of %d objects" +msgstr[0] "Gruppe med %d objekter" +msgstr[1] "Gruppe med %d objekter" + +#: ../../po/../src/sp-item.cpp:720 +msgid "Object" +msgstr "Objekt" + +#: ../../po/../src/sp-line.cpp:202 +#, fuzzy +msgid "Line" +msgstr "Lenke til %s" + +#. TRANSLATORS COMMENT: %s is either "outset" or "inset" depending on sign +#: ../../po/../src/sp-offset.cpp:433 +#, c-format +msgid "Linked offset, %s by %f pt" +msgstr "" + +#: ../../po/../src/sp-offset.cpp:434 ../../po/../src/sp-offset.cpp:438 +#, fuzzy +msgid "outset" +msgstr "Sist valgte" + +#: ../../po/../src/sp-offset.cpp:434 ../../po/../src/sp-offset.cpp:438 +#, fuzzy +msgid "inset" +msgstr "Punkt" + +#. TRANSLATORS COMMENT: %s is either "outset" or "inset" depending on sign +#: ../../po/../src/sp-offset.cpp:437 +#, c-format +msgid "Dynamic offset, %s by %f pt" +msgstr "" + +#: ../../po/../src/sp-path.cpp:127 +#, fuzzy, c-format +msgid "Path (%i node)" +msgid_plural "Path (%i nodes)" +msgstr[0] "Lenke til %s" +msgstr[1] "Lenke til %s" + +#: ../../po/../src/sp-polygon.cpp:216 +#, fuzzy +msgid "Polygon" +msgstr "Rektangel" + +#: ../../po/../src/sp-polyline.cpp:179 +#, fuzzy +msgid "Polyline" +msgstr "Rektangel" + +#: ../../po/../src/sp-rect.cpp:250 +#, fuzzy +msgid "Rectangle" +msgstr "Rektangel" + +#. TRANSLATORS: since turn count isn't an integer, please adjust the +#. string as needed to deal with an localized plural forms. +#: ../../po/../src/sp-spiral.cpp:305 +#, c-format +msgid "Spiral with %3f turns" +msgstr "" + +#: ../../po/../src/sp-star.cpp:288 +#, c-format +msgid "Star with %d vertex" +msgid_plural "Star with %d vertices" +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/sp-star.cpp:292 +#, c-format +msgid "Polygon with %d vertex" +msgid_plural "Polygon with %d vertices" +msgstr[0] "" +msgstr[1] "" + +#. TRANSLATORS: For description of font with no name. +#: ../../po/../src/sp-text.cpp:420 +msgid "<no name found>" +msgstr "" + +#: ../../po/../src/sp-text.cpp:426 +#, fuzzy, c-format +msgid "Text on path (%s, %s)" +msgstr "Lenke til %s" + +#: ../../po/../src/sp-text.cpp:427 +#, fuzzy, c-format +msgid "Text (%s, %s)" +msgstr "Lenke til %s" + +#. TRANSLATORS: Used for statusbar description for long chains: +#. * "Clone of: Clone of: ... in Layer 1". +#: ../../po/../src/sp-use.cpp:317 +#, fuzzy +msgid "..." +msgstr "Åpne" + +#: ../../po/../src/sp-use.cpp:325 +#, fuzzy, c-format +msgid "Clone of: %s" +msgstr "Lenke til %s" + +#: ../../po/../src/sp-use.cpp:329 +msgid "Orphaned clone" +msgstr "" + +#: ../../po/../src/spiral-context.cpp:355 +msgid "Ctrl: snap angle" +msgstr "" + +#: ../../po/../src/spiral-context.cpp:357 +msgid "Alt: lock spiral radius" +msgstr "" + +#: ../../po/../src/spiral-context.cpp:469 +#, c-format +msgid "" +"Spiral: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/splivarot.cpp:106 +#, fuzzy +msgid "Select at least 2 paths to perform a boolean operation." +msgstr "Ingen gradienter i dokumentet" + +#: ../../po/../src/splivarot.cpp:112 +msgid "" +"Select exactly 2 paths to perform difference, XOR, division, or path " +"cut." +msgstr "" + +#: ../../po/../src/splivarot.cpp:129 ../../po/../src/splivarot.cpp:144 +msgid "" +"Unable to determine the z-order of the objects selected for " +"difference, XOR, division, or path cut." +msgstr "" + +#: ../../po/../src/splivarot.cpp:174 +#, fuzzy +msgid "" +"One of the objects is not a path, cannot perform boolean operation." +msgstr "Senk valgte objekter til bunnen" + +#. TRANSLATORS: "to outline" means "to convert stroke to path" +#: ../../po/../src/splivarot.cpp:554 +#, fuzzy +msgid "Select path(s) to outline." +msgstr "Klipp ut valgte objekter til utklippstavlen" + +#. TRANSLATORS: "to outline" means "to convert stroke to path" +#: ../../po/../src/splivarot.cpp:748 +msgid "No stroked paths to outline in the selection." +msgstr "" + +#: ../../po/../src/splivarot.cpp:832 +#, fuzzy +msgid "Selected object is not a path, cannot inset/outset." +msgstr "Senk valgte objekter til bunnen" + +#: ../../po/../src/splivarot.cpp:1040 +#, fuzzy +msgid "Select path(s) to inset/outset." +msgstr "Klipp ut valgte objekter til utklippstavlen" + +#: ../../po/../src/splivarot.cpp:1257 +msgid "No paths to inset/outset in the selection." +msgstr "" + +#: ../../po/../src/splivarot.cpp:1390 +#, fuzzy +msgid "Select path(s) to simplify." +msgstr "Klipp ut valgte objekter til utklippstavlen" + +#: ../../po/../src/splivarot.cpp:1417 +msgid "No paths to simplify in the selection." +msgstr "" + +#: ../../po/../src/star-context.cpp:362 +msgid "Ctrl: snap angle; keep rays radial" +msgstr "" + +#: ../../po/../src/star-context.cpp:470 +#, c-format +msgid "" +"Polygon: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/star-context.cpp:471 +#, c-format +msgid "Star: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/text-chemistry.cpp:90 +#, fuzzy +msgid "Select a text and a path to put text on path." +msgstr "Ingen gradienter i dokumentet" + +#: ../../po/../src/text-chemistry.cpp:95 +msgid "" +"This text object is already put to a path. Remove it from the path " +"first. Use Shift+D to look up its path." +msgstr "" + +#. rect is the only SPShape which is not yet, and thus SVG forbids us from putting text on it +#: ../../po/../src/text-chemistry.cpp:101 +msgid "" +"You cannot put text on a rectangle in this version. Convert rectangle to " +"path first." +msgstr "" + +#: ../../po/../src/text-chemistry.cpp:159 +#, fuzzy +msgid "Select a text on path to remove it from path." +msgstr "Ingen gradienter i dokumentet" + +#: ../../po/../src/text-chemistry.cpp:181 +#, fuzzy +msgid "No texts-on-paths in the selection." +msgstr "Klipp ut valgte objekter til utklippstavlen" + +#: ../../po/../src/text-chemistry.cpp:209 +#: ../../po/../src/text-chemistry.cpp:229 +#, fuzzy +msgid "Select text(s) to remove kerns from." +msgstr "Hev valgte objekter til toppen" + +#: ../../po/../src/text-chemistry.cpp:250 +#, fuzzy +msgid "" +"Select a text and one or more paths or shapes to flow text " +"into frame." +msgstr "Ingen gradienter i dokumentet" + +#: ../../po/../src/text-chemistry.cpp:322 +#, fuzzy +msgid "Select a flowed text to unflow it." +msgstr "Klipp ut valgte objekter til utklippstavlen" + +#: ../../po/../src/text-context.cpp:463 +msgid "Click to edit the text, drag to select part of the text." +msgstr "" + +#: ../../po/../src/text-context.cpp:465 +msgid "" +"Click to edit the flowed text, drag to select part of the text." +msgstr "" + +#: ../../po/../src/text-context.cpp:540 +msgid "Non-printable character" +msgstr "" + +#: ../../po/../src/text-context.cpp:589 +#, fuzzy, c-format +msgid "Unicode: %s: %s" +msgstr "Sodipodi: %s: %s: %d" + +#: ../../po/../src/text-context.cpp:591 ../../po/../src/text-context.cpp:855 +msgid "Unicode: " +msgstr "" + +#: ../../po/../src/text-context.cpp:615 +msgid "Current layer is hidden. Unhide it to be able to add text." +msgstr "" + +#: ../../po/../src/text-context.cpp:619 +msgid "Current layer is locked. Unlock it to be able to add text." +msgstr "" + +#: ../../po/../src/text-context.cpp:673 +#, c-format +msgid "Flowed text frame: %s × %s" +msgstr "" + +#: ../../po/../src/text-context.cpp:708 ../../po/../src/text-context.cpp:1464 +msgid "Type text; Enter to start new line." +msgstr "" + +#: ../../po/../src/text-context.cpp:719 +msgid "Flowed text is created." +msgstr "" + +#: ../../po/../src/text-context.cpp:722 +msgid "" +"The frame is too small for the current font size. Flowed text not " +"created." +msgstr "" + +#: ../../po/../src/text-context.cpp:841 +msgid "No-break space" +msgstr "" + +#: ../../po/../src/text-context.cpp:1462 +msgid "Type flowed text; Enter to start new paragraph." +msgstr "" + +#: ../../po/../src/text-context.cpp:1472 ../../po/../src/tools-switch.cpp:189 +msgid "" +"Click to select or create text, drag to create flowed text; " +"then type." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:141 +msgid "" +"To edit a path, click, Shift+click, or drag around " +"nodes to select them, then drag nodes and handles. Click on an " +"object to select." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:147 +msgid "" +"Drag to create a rectangle. Drag controls to round corners and " +"resize. Click to select." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:153 +msgid "" +"Drag to create an ellipse. Drag controls to make an arc or " +"segment. Click to select." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:159 +msgid "" +"Drag to create a star. Drag controls to edit the star shape. " +"Click to select." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:165 +msgid "" +"Drag to create a spiral. Drag controls to edit the spiral " +"shape. Click to select." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:171 +#, fuzzy +msgid "" +"Drag to create a freehand line. Start drawing with Shift to " +"append to selected path." +msgstr "Oppretter ny kurve. Trykk «+» for Ã¥ velge mellom Legg til/Ny." + +#: ../../po/../src/tools-switch.cpp:177 +#, fuzzy +msgid "" +"Click or click and drag to start a path; with Shift to " +"append to selected path." +msgstr "Oppretter ny kurve. Trykk «+» for Ã¥ velge mellom Legg til/Ny." + +#: ../../po/../src/tools-switch.cpp:183 +msgid "" +"Drag to paint a calligraphic stroke. Left/right arrow " +"keys adjust width, up/down adjust angle." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:195 +#, fuzzy +msgid "" +"Drag or double click to create a gradient on selected objects, " +"drag handles to adjust gradients." +msgstr "Oppretter ny kurve. Trykk «+» for Ã¥ velge mellom Legg til/Ny." + +#: ../../po/../src/tools-switch.cpp:201 +msgid "" +"Click or drag around an area to zoom in, Shift+click to " +"zoom out." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:213 +msgid "Click and drag between shapes to create a connector." +msgstr "" + +#: ../../po/../src/trace/potrace/inkscape-potrace.cpp:553 +#: ../../po/../src/trace/potrace/inkscape-potrace.cpp:654 +#, c-format +msgid "Trace: %d. %ld nodes" +msgstr "" + +#: ../../po/../src/trace/trace.cpp:53 ../../po/../src/trace/trace.cpp:62 +#: ../../po/../src/trace/trace.cpp:70 +#, fuzzy +msgid "Select an image to trace" +msgstr "Klipp ut valgte objekter til utklippstavlen" + +#: ../../po/../src/trace/trace.cpp:133 +#, fuzzy +msgid "Trace: No active document" +msgstr "Opprett nytt SVG-dokument" + +#: ../../po/../src/trace/trace.cpp:154 +msgid "Trace: Image has no bitmap data" +msgstr "" + +#: ../../po/../src/trace/trace.cpp:267 +#, fuzzy, c-format +msgid "Trace: Done. %ld nodes created" +msgstr "Sist valgte" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:59 ../../po/../src/verbs.cpp:2212 +msgid "About Inkscape" +msgstr "" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:66 +msgid "_Splash" +msgstr "" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:68 +msgid "_Authors" +msgstr "" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:69 +#, fuzzy +msgid "_Translators" +msgstr "Transformer:" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:70 +#, fuzzy +msgid "_License" +msgstr "Lenke" + +#. TRANSLATORS: This is the filename of the `About Inkscape' picture in +#. the `screens' directory. Thus the translation of "about.svg" should be +#. the filename of its translated version, e.g. about.zh.svg for Chinese. +#. +#. N.B. about.svg changes once per release. (We should probably rename +#. the original to about-0.40.svg etc. as soon as we have a translation. +#. If we do so, then add an item to release-checklist saying that the +#. string here should be changed.) +#. FIXME? INKSCAPE_SCREENSDIR and "about.svg" are in UTF-8, not the +#. native filename encoding... and the filename passed to sp_document_new +#. should be in UTF-*8.. +#: ../../po/../src/ui/dialog/aboutbox.cpp:114 +msgid "about.svg" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:464 +msgid "Minimum horizontal gap (in px units) between bounding boxes" +msgstr "" + +#. TRANSLATORS: Horizontal gap +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:466 +#: ../../po/../src/widgets/toolbox.cpp:1556 +msgid "H:" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:474 +msgid "Minimum vertical gap (in px units) between bounding boxes" +msgstr "" + +#. TRANSLATORS: Vertical gap +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:476 +msgid "V:" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:734 +#, fuzzy +msgid "Align" +msgstr "Linjestill:" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:735 +#, fuzzy +msgid "Distribute" +msgstr "Distribuer" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:736 +msgid "Remove overlaps" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:737 +#, fuzzy +msgid "Nodes" +msgstr "Noder" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:742 +#, fuzzy +msgid "Relative to: " +msgstr "Relativ flytting" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:747 +#, fuzzy +msgid "Align right sides of objects to left side of anchor" +msgstr "Høyre side av linjestilte objekter til venstre side av anker " + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:750 +#, fuzzy +msgid "Align left sides" +msgstr "Juster objekter" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:753 +#, fuzzy +msgid "Center on vertical axis" +msgstr "Sentrer vertikalt" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:756 +#, fuzzy +msgid "Align right sides" +msgstr "Juster objekter" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:759 +#, fuzzy +msgid "Align left sides of objects to right side of anchor" +msgstr "Venstre side av linjestilte objekter til høyre side av anker" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:762 +#, fuzzy +msgid "Align bottoms of objects to top of anchor" +msgstr "Bunn av linjestilte objekter til topp av anker" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:765 +#, fuzzy +msgid "Align tops" +msgstr "Juster objekter" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:768 +#, fuzzy +msgid "Center on horizontal axis" +msgstr "Vend valgte objekter horisontalt" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:771 +#, fuzzy +msgid "Align bottoms" +msgstr "Juster objekter" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:774 +#, fuzzy +msgid "Align tops of objects to bottom of anchor" +msgstr "Kopier linjestilte objekter til utklippstavlen" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:779 +#, fuzzy +msgid "Align baseline anchors of texts vertically" +msgstr "Vend valgte objekter vertikalt" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:782 +#, fuzzy +msgid "Align baseline anchors of texts horizontally" +msgstr "Vend valgte objekter horisontalt" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:787 +#, fuzzy +msgid "Make horizontal gaps between objects equal" +msgstr "Distribuer horisontalt mellomrom mellom objekter jevnt" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:791 +#, fuzzy +msgid "Distribute left sides equidistantly" +msgstr "Fordel venstre side av objekter pÃ¥ med jevne mellomrom" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:794 +#, fuzzy +msgid "Distribute centers equidistantly horizontally" +msgstr "Fordel senter av objekter med jevne mellomrom" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:797 +#, fuzzy +msgid "Distribute right sides equidistantly" +msgstr "Distribuer høyre side av objekter med jevne mellomrom" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:801 +#, fuzzy +msgid "Make vertical gaps between objects equal" +msgstr "Distribuer vertikalt mellomrom mellom objekter jevnt" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:805 +#, fuzzy +msgid "Distribute tops equidistantly" +msgstr "Distribuer senter av objekter med jevne mellomrom vertikalt" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:808 +#, fuzzy +msgid "Distribute centers equidistantly vertically" +msgstr "Distribuer senter av objekter med jevne mellomrom vertikalt" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:811 +#, fuzzy +msgid "Distribute bottoms equidistantly" +msgstr "Distribuer bunn sider av objekter med jevne mellomrom" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:816 +#, fuzzy +msgid "Distribute baseline anchors of texts horizontally" +msgstr "Vend valgte objekter horisontalt" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:819 +#, fuzzy +msgid "Distribute baseline anchors of texts vertically" +msgstr "Distribuer senter av objekter med jevne mellomrom vertikalt" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:824 +msgid "Randomize centers in both dimensions" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:827 +msgid "Unclump objects: try to equalize edge-to-edge distances" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:832 +msgid "" +"Move objects as little as possible so that their bounding boxes do not " +"overlap" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:837 +#, fuzzy +msgid "Align selected nodes horizontally" +msgstr "Vend valgte objekter horisontalt" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:840 +#, fuzzy +msgid "Align selected nodes vertically" +msgstr "Vend valgte objekter vertikalt" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:843 +#, fuzzy +msgid "Distribute selected nodes horizontally" +msgstr "Vend valgte objekter horisontalt" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:846 +#, fuzzy +msgid "Distribute selected nodes vertically" +msgstr "Distribuer senter av objekter med jevne mellomrom vertikalt" + +#. Rest of the widgetry +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:851 +msgid "Last selected" +msgstr "Sist valgte" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:852 +msgid "First selected" +msgstr "Først valgte" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:853 +msgid "Biggest item" +msgstr "Største oppføring" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:854 +msgid "Smallest item" +msgstr "Minste oppføring" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:856 +#: ../../po/../src/widgets/desktop-widget.cpp:1065 +msgid "Drawing" +msgstr "Tegning" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:91 +msgid "Metadata 1" +msgstr "" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:92 +msgid "Metadata 2" +msgstr "" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:187 +#, fuzzy +msgid "X coordinate of grid origin" +msgstr "Mellomrom X:" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:189 +#, fuzzy +msgid "Y coordinate of grid origin" +msgstr "Mellomrom X:" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:191 +#, fuzzy +msgid "Distance of vertical grid lines" +msgstr "Sentrer vertikalt" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:193 +#, fuzzy +msgid "Distance of horizontal grid lines" +msgstr "Vend valgte objekter horisontalt" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:197 +msgid "Max. snapping distance from grid" +msgstr "" + +#: ../../po/../src/ui/dialog/export.cpp:34 +msgid "Export" +msgstr "Eksporter" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:36 +msgid "Fill" +msgstr "Fyll" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:37 +#, fuzzy +msgid "Stroke Paint" +msgstr "Ingen maling" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:38 +#, fuzzy +msgid "Stroke Style" +msgstr "Innstillinger for strøk" + +#: ../../po/../src/ui/dialog/find.cpp:34 +#, fuzzy +msgid "Find" +msgstr "Rutenett" + +#: ../../po/../src/ui/dialog/memory.cpp:96 +msgid "Heap" +msgstr "" + +#: ../../po/../src/ui/dialog/memory.cpp:97 +#, fuzzy +msgid "In Use" +msgstr "Punkt" + +#. TRANSLATORS: "Slack" refers to memory which is in the heap but currently unused. +#. More typical usage is to call this memory "free" rather than "slack". +#: ../../po/../src/ui/dialog/memory.cpp:100 +#, fuzzy +msgid "Slack" +msgstr "Stjerne" + +#: ../../po/../src/ui/dialog/memory.cpp:101 +#, fuzzy +msgid "Total" +msgstr "Tittel:" + +#: ../../po/../src/ui/dialog/memory.cpp:141 +#: ../../po/../src/ui/dialog/memory.cpp:147 +#: ../../po/../src/ui/dialog/memory.cpp:154 +#: ../../po/../src/ui/dialog/memory.cpp:186 +msgid "Unknown" +msgstr "Ukjent" + +#: ../../po/../src/ui/dialog/memory.cpp:167 +#, fuzzy +msgid "Combined" +msgstr "Kombiner" + +#: ../../po/../src/ui/dialog/memory.cpp:209 +#, fuzzy +msgid "Recalculate" +msgstr "Rektangel" + +#: ../../po/../src/ui/dialog/messages.cpp:74 +#, fuzzy +msgid "Ready." +msgstr "Rød:" + +#: ../../po/../src/ui/dialog/messages.cpp:75 +msgid "" +"Enable log display by setting dialogs.debug 'redirect' attribute to 1 in " +"preferences.xml" +msgstr "" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:184 +msgid "_Execute Python" +msgstr "" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:186 +msgid "_Execute Perl" +msgstr "" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:195 +msgid "Script" +msgstr "" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:205 +#, fuzzy +msgid "Output" +msgstr "Klipp ut" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:215 +msgid "Errors" +msgstr "" + +#. Dialog organization +#: ../../po/../src/ui/dialog/session-player.cpp:73 +#, fuzzy +msgid "Session file" +msgstr "Lagre fil" + +#: ../../po/../src/ui/dialog/session-player.cpp:74 +#, fuzzy +msgid "Playback controls" +msgstr "Alternativer for verktøy" + +#: ../../po/../src/ui/dialog/session-player.cpp:75 +#, fuzzy +msgid "Message information" +msgstr "Nullstill transformasjon" + +#. Active session file display +#. fixme: Does this mean the active file for the session, or the file for the active session? +#. Please indicate which with a TRANSLATORS comment. +#: ../../po/../src/ui/dialog/session-player.cpp:85 +msgid "Active session file:" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:86 +msgid "Delay (milliseconds):" +msgstr "" + +#. Unload/load buttons +#: ../../po/../src/ui/dialog/session-player.cpp:94 +#, fuzzy +msgid "Close file" +msgstr "Lukk" + +#: ../../po/../src/ui/dialog/session-player.cpp:95 +msgid "Open new file" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:96 +#, fuzzy +msgid "Set delay" +msgstr "Sett som forvalg" + +#: ../../po/../src/ui/dialog/session-player.cpp:138 +#, fuzzy +msgid "Rewind" +msgstr "Rød:" + +#: ../../po/../src/ui/dialog/session-player.cpp:139 +msgid "Go back one change" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:140 +#, fuzzy +msgid "Pause" +msgstr "Lim inn" + +#: ../../po/../src/ui/dialog/session-player.cpp:141 +msgid "Go forward one change" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:142 +msgid "Play" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:177 +#: ../../po/../src/verbs.cpp:1573 +msgid "Open session file" +msgstr "" + +#. ##Set up the Potrace panel +#. #### brightness #### +#. #### Multiple scanning#### +#. ----Hbox1 +#: ../../po/../src/ui/dialog/tracedialog.cpp:345 +#: ../../po/../src/ui/dialog/tracedialog.cpp:428 +#, fuzzy +msgid "Brightness" +msgstr "Høyde:" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:348 +msgid "Trace by a given brightness level" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:355 +msgid "Brightness cutoff for black/white" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:362 +#, fuzzy +msgid "Image Brightness" +msgstr "Egenskaper for bilde" + +#. #### canny edge detection #### +#. TRANSLATORS: "Canny" is the name of the inventor of this edge detection method +#: ../../po/../src/ui/dialog/tracedialog.cpp:369 +msgid "Optimal Edge Detection (Canny)" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:372 +msgid "Trace with edge detection by J. Canny's algorithm" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:388 +msgid "Brightness cutoff for adjacent pixels (determines edge thickness)" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:395 +#, fuzzy +msgid "Edge Detection" +msgstr "Valg" + +#. #### quantization #### +#. TRANSLATORS: Color Quantization: the process of reducing the number of colors +#. in an image by selecting an optimized set of representative colors and then +#. re-applying this reduced set to the original image. +#: ../../po/../src/ui/dialog/tracedialog.cpp:404 +#, fuzzy +msgid "Color Quantization" +msgstr "Fargemaling" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:407 +msgid "Trace along the boundaries of reduced colors" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:414 +msgid "The number of reduced colors" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:416 +#, fuzzy +msgid "Colors:" +msgstr "Lukk" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:421 +msgid "Quantization / Reduction" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:431 +msgid "Trace the given number of brightness levels" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:438 +#, fuzzy +msgid "Scans:" +msgstr "Form" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:440 +msgid "The desired number of scans" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:448 +msgid "Trace the given number of reduced colors" +msgstr "" + +#. ---Hbox3 +#: ../../po/../src/ui/dialog/tracedialog.cpp:454 +msgid "Monochrome" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:457 +msgid "Same as Color, but convert result to grayscale" +msgstr "" + +#. TRANSLATORS: "Stack" is a verb here +#: ../../po/../src/ui/dialog/tracedialog.cpp:460 +#, fuzzy +msgid "Stack" +msgstr "Stjerne" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:463 +msgid "" +"Stack scans vertically (no gaps) or tile horizontally (usually with gaps)" +msgstr "" + +#. TRANSLATORS: "Smooth" is a verb here +#: ../../po/../src/ui/dialog/tracedialog.cpp:466 +msgid "Smooth" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:469 +msgid "Apply Gaussian blur to the bitmap before tracing" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:473 +msgid "Multiple Scanning" +msgstr "" + +#. #### Preview #### +#: ../../po/../src/ui/dialog/tracedialog.cpp:479 +#: ../../po/../src/ui/dialog/tracedialog.cpp:489 +#, fuzzy +msgid "Preview" +msgstr "Ny forhÃ¥ndsvisning" + +#. do not expand +#: ../../po/../src/ui/dialog/tracedialog.cpp:483 +msgid "Preview the result without actual tracing" +msgstr "" + +#. #### swap black and white #### +#: ../../po/../src/ui/dialog/tracedialog.cpp:495 +msgid "Invert" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:499 +msgid "Invert black and white regions for single traces" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:503 +msgid "Thanks to Peter Selinger, http://potrace.sourceforge.net" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:506 +#, fuzzy +msgid "Credits" +msgstr "Hjørner:" + +#. done +#. TRANSLATORS: Potrace is an application for transforming bitmaps into +#. vector graphics (http://potrace.sourceforge.net/) +#: ../../po/../src/ui/dialog/tracedialog.cpp:514 +#, fuzzy +msgid "Potrace" +msgstr "Spor" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:527 +#, fuzzy +msgid "Abort a trace in progress" +msgstr "Eksporter omrÃ¥de" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:531 +msgid "Execute the trace" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:80 +#: ../../po/../src/ui/dialog/transformation.cpp:90 +#, fuzzy +msgid "_Horizontal" +msgstr "Vend valgte objekter horisontalt" + +#: ../../po/../src/ui/dialog/transformation.cpp:80 +msgid "Horizontal displacement (relative) or position (absolute)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:82 +#: ../../po/../src/ui/dialog/transformation.cpp:92 +#, fuzzy +msgid "_Vertical" +msgstr "Sentrer vertikalt" + +#: ../../po/../src/ui/dialog/transformation.cpp:82 +msgid "Vertical displacement (relative) or position (absolute)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:84 +#, fuzzy +msgid "_Width" +msgstr "Bredde:" + +#: ../../po/../src/ui/dialog/transformation.cpp:84 +msgid "Horizontal size increment (absolute or percentage)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:86 +#, fuzzy +msgid "_Height" +msgstr "Høyde:" + +#: ../../po/../src/ui/dialog/transformation.cpp:86 +msgid "Vertical size increment (absolute or percentage)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:88 +#, fuzzy +msgid "A_ngle" +msgstr "Vinkel" + +#: ../../po/../src/ui/dialog/transformation.cpp:88 +#, fuzzy +msgid "Rotation angle (positive = counterclockwise)" +msgstr "Roter objekt 90° med klokken" + +#: ../../po/../src/ui/dialog/transformation.cpp:90 +msgid "" +"Horizontal skew angle (positive = counterclockwise), or absolute " +"displacement, or percentage displacement" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:92 +msgid "" +"Vertical skew angle (positive = counterclockwise), or absolute displacement, " +"or percentage displacement" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:95 +#, fuzzy +msgid "Transformation matrix element A" +msgstr "Transformasjonsmatrise" + +#: ../../po/../src/ui/dialog/transformation.cpp:96 +#, fuzzy +msgid "Transformation matrix element B" +msgstr "Transformasjonsmatrise" + +#: ../../po/../src/ui/dialog/transformation.cpp:97 +#, fuzzy +msgid "Transformation matrix element C" +msgstr "Transformasjonsmatrise" + +#: ../../po/../src/ui/dialog/transformation.cpp:98 +#, fuzzy +msgid "Transformation matrix element D" +msgstr "Transformasjonsmatrise" + +#: ../../po/../src/ui/dialog/transformation.cpp:99 +#, fuzzy +msgid "Transformation matrix element E" +msgstr "Transformasjonsmatrise" + +#: ../../po/../src/ui/dialog/transformation.cpp:100 +#, fuzzy +msgid "Transformation matrix element F" +msgstr "Transformasjonsmatrise" + +#: ../../po/../src/ui/dialog/transformation.cpp:102 +#, fuzzy +msgid "Rela_tive move" +msgstr "Relativ flytting" + +#: ../../po/../src/ui/dialog/transformation.cpp:102 +msgid "" +"Add the specified relative displacement to the current position; otherwise, " +"edit the current absolute position directly" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:103 +msgid "Scale proportionally" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:103 +msgid "Preserve the width/height ratio of the scaled objects" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:104 +msgid "Apply to each _object separately" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:104 +msgid "" +"Apply the scale/rotate/skew to each selected object separately; otherwise, " +"transform the selection as a whole" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:105 +msgid "Edit c_urrent matrix" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:105 +msgid "" +"Edit the current transform= matrix; otherwise, post-multiply transform= by " +"this matrix" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:115 +#, fuzzy +msgid "_Move" +msgstr "Flytt" + +#: ../../po/../src/ui/dialog/transformation.cpp:118 +#, fuzzy +msgid "_Scale" +msgstr "Skaler" + +#: ../../po/../src/ui/dialog/transformation.cpp:121 +#, fuzzy +msgid "_Rotate" +msgstr "Roter" + +#: ../../po/../src/ui/dialog/transformation.cpp:124 +#, fuzzy +msgid "Ske_w" +msgstr "Ingen maling" + +#: ../../po/../src/ui/dialog/transformation.cpp:127 +msgid "Matri_x" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:141 +msgid "Reset the values on the current tab to defaults" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:148 +#, fuzzy +msgid "Apply transformation to selection" +msgstr "Utvalgsverktøy - velg og transformer objekter" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:43 +msgid "_Use SSL" +msgstr "" + +#. Construct dialog interface +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:68 +#, fuzzy +msgid "_Server:" +msgstr "Fil" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:69 +#, fuzzy +msgid "_Username:" +msgstr "Fil" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:70 +msgid "_Password:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:71 +msgid "P_ort:" +msgstr "" + +#. Buttons +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:99 +#, fuzzy +msgid "Connect" +msgstr "Lukk" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:126 +msgid "Establishing connection to Jabber server %1 as user %2" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:131 +msgid "Failed to establish connection to Jabber server %1" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:136 +msgid "Authentication failed on Jabber server %1 as %2" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:141 +msgid "SSL initialization failed when connecting to Jabber server %1" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:147 +msgid "Connected to Jabber server %1 as %2" +msgstr "" + +#. Construct labels +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:75 +msgid "Chatroom _name:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:76 +msgid "Chatroom _server:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:77 +msgid "Chatroom _password:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:78 +msgid "Chatroom _handle:" +msgstr "" + +#. Button setup and callback registration +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:97 +msgid "Connect to chatroom" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:132 +msgid "Synchronizing with chatroom %1@%2 using the handle %3" +msgstr "" + +#. Construct dialog interface +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:78 +msgid "_User's Jabber ID:" +msgstr "" + +#. Buttons +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:82 +msgid "_Invite user" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:83 +#, fuzzy +msgid "_Cancel" +msgstr "Avbryt" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:94 +msgid "Buddy List" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:170 +msgid "Sending whiteboard invitation to %1" +msgstr "" + +#. FIXME: strings are replaced by placeholders, NOT to be translated until the code is enabled +#. See http://sourceforge.net/mailarchive/message.php?msg_id=11746016 for details +#. File menu +#. Edit menu +#. View menu +#. Layer menu +#. Object menu +#. Path menu +#. add(Gtk::StockItem(CLEANUP, _("PLACEHOLDER, do not translate"))); (using Gtk::Stock::CLEAR) +#. Text menu +#. About menu +#. Tools toolbox +#. Select Tool controls +#. Node Tool controls +#. Calligraphy Tool controls +#. Session playback controls +#: ../../po/../src/ui/stock-items.cpp:34 ../../po/../src/ui/stock-items.cpp:35 +#: ../../po/../src/ui/stock-items.cpp:36 ../../po/../src/ui/stock-items.cpp:37 +#: ../../po/../src/ui/stock-items.cpp:38 ../../po/../src/ui/stock-items.cpp:39 +#: ../../po/../src/ui/stock-items.cpp:40 ../../po/../src/ui/stock-items.cpp:41 +#: ../../po/../src/ui/stock-items.cpp:42 ../../po/../src/ui/stock-items.cpp:43 +#: ../../po/../src/ui/stock-items.cpp:46 ../../po/../src/ui/stock-items.cpp:47 +#: ../../po/../src/ui/stock-items.cpp:48 ../../po/../src/ui/stock-items.cpp:49 +#: ../../po/../src/ui/stock-items.cpp:50 ../../po/../src/ui/stock-items.cpp:51 +#: ../../po/../src/ui/stock-items.cpp:52 ../../po/../src/ui/stock-items.cpp:53 +#: ../../po/../src/ui/stock-items.cpp:54 ../../po/../src/ui/stock-items.cpp:55 +#: ../../po/../src/ui/stock-items.cpp:56 ../../po/../src/ui/stock-items.cpp:57 +#: ../../po/../src/ui/stock-items.cpp:58 ../../po/../src/ui/stock-items.cpp:59 +#: ../../po/../src/ui/stock-items.cpp:62 ../../po/../src/ui/stock-items.cpp:63 +#: ../../po/../src/ui/stock-items.cpp:64 ../../po/../src/ui/stock-items.cpp:65 +#: ../../po/../src/ui/stock-items.cpp:66 ../../po/../src/ui/stock-items.cpp:67 +#: ../../po/../src/ui/stock-items.cpp:68 ../../po/../src/ui/stock-items.cpp:69 +#: ../../po/../src/ui/stock-items.cpp:70 ../../po/../src/ui/stock-items.cpp:71 +#: ../../po/../src/ui/stock-items.cpp:72 ../../po/../src/ui/stock-items.cpp:73 +#: ../../po/../src/ui/stock-items.cpp:74 ../../po/../src/ui/stock-items.cpp:75 +#: ../../po/../src/ui/stock-items.cpp:76 ../../po/../src/ui/stock-items.cpp:77 +#: ../../po/../src/ui/stock-items.cpp:78 ../../po/../src/ui/stock-items.cpp:79 +#: ../../po/../src/ui/stock-items.cpp:80 ../../po/../src/ui/stock-items.cpp:81 +#: ../../po/../src/ui/stock-items.cpp:82 ../../po/../src/ui/stock-items.cpp:83 +#: ../../po/../src/ui/stock-items.cpp:84 ../../po/../src/ui/stock-items.cpp:85 +#: ../../po/../src/ui/stock-items.cpp:86 ../../po/../src/ui/stock-items.cpp:87 +#: ../../po/../src/ui/stock-items.cpp:88 ../../po/../src/ui/stock-items.cpp:89 +#: ../../po/../src/ui/stock-items.cpp:92 ../../po/../src/ui/stock-items.cpp:93 +#: ../../po/../src/ui/stock-items.cpp:94 ../../po/../src/ui/stock-items.cpp:95 +#: ../../po/../src/ui/stock-items.cpp:96 ../../po/../src/ui/stock-items.cpp:97 +#: ../../po/../src/ui/stock-items.cpp:98 ../../po/../src/ui/stock-items.cpp:99 +#: ../../po/../src/ui/stock-items.cpp:100 +#: ../../po/../src/ui/stock-items.cpp:101 +#: ../../po/../src/ui/stock-items.cpp:102 +#: ../../po/../src/ui/stock-items.cpp:103 +#: ../../po/../src/ui/stock-items.cpp:104 +#: ../../po/../src/ui/stock-items.cpp:105 +#: ../../po/../src/ui/stock-items.cpp:108 +#: ../../po/../src/ui/stock-items.cpp:109 +#: ../../po/../src/ui/stock-items.cpp:110 +#: ../../po/../src/ui/stock-items.cpp:111 +#: ../../po/../src/ui/stock-items.cpp:112 +#: ../../po/../src/ui/stock-items.cpp:113 +#: ../../po/../src/ui/stock-items.cpp:114 +#: ../../po/../src/ui/stock-items.cpp:115 +#: ../../po/../src/ui/stock-items.cpp:116 +#: ../../po/../src/ui/stock-items.cpp:117 +#: ../../po/../src/ui/stock-items.cpp:118 +#: ../../po/../src/ui/stock-items.cpp:119 +#: ../../po/../src/ui/stock-items.cpp:120 +#: ../../po/../src/ui/stock-items.cpp:121 +#: ../../po/../src/ui/stock-items.cpp:122 +#: ../../po/../src/ui/stock-items.cpp:123 +#: ../../po/../src/ui/stock-items.cpp:124 +#: ../../po/../src/ui/stock-items.cpp:125 +#: ../../po/../src/ui/stock-items.cpp:126 +#: ../../po/../src/ui/stock-items.cpp:127 +#: ../../po/../src/ui/stock-items.cpp:130 +#: ../../po/../src/ui/stock-items.cpp:131 +#: ../../po/../src/ui/stock-items.cpp:132 +#: ../../po/../src/ui/stock-items.cpp:133 +#: ../../po/../src/ui/stock-items.cpp:134 +#: ../../po/../src/ui/stock-items.cpp:135 +#: ../../po/../src/ui/stock-items.cpp:136 +#: ../../po/../src/ui/stock-items.cpp:137 +#: ../../po/../src/ui/stock-items.cpp:138 +#: ../../po/../src/ui/stock-items.cpp:139 +#: ../../po/../src/ui/stock-items.cpp:140 +#: ../../po/../src/ui/stock-items.cpp:141 +#: ../../po/../src/ui/stock-items.cpp:142 +#: ../../po/../src/ui/stock-items.cpp:143 +#: ../../po/../src/ui/stock-items.cpp:144 +#: ../../po/../src/ui/stock-items.cpp:145 +#: ../../po/../src/ui/stock-items.cpp:146 +#: ../../po/../src/ui/stock-items.cpp:150 +#: ../../po/../src/ui/stock-items.cpp:151 +#: ../../po/../src/ui/stock-items.cpp:152 +#: ../../po/../src/ui/stock-items.cpp:153 +#: ../../po/../src/ui/stock-items.cpp:156 +#: ../../po/../src/ui/stock-items.cpp:157 +#: ../../po/../src/ui/stock-items.cpp:158 +#: ../../po/../src/ui/stock-items.cpp:161 +#: ../../po/../src/ui/stock-items.cpp:162 +#: ../../po/../src/ui/stock-items.cpp:163 +#: ../../po/../src/ui/stock-items.cpp:164 +#: ../../po/../src/ui/stock-items.cpp:165 +#: ../../po/../src/ui/stock-items.cpp:166 +#: ../../po/../src/ui/stock-items.cpp:167 +#: ../../po/../src/ui/stock-items.cpp:168 +#: ../../po/../src/ui/stock-items.cpp:169 +#: ../../po/../src/ui/stock-items.cpp:170 +#: ../../po/../src/ui/stock-items.cpp:171 +#: ../../po/../src/ui/stock-items.cpp:172 +#: ../../po/../src/ui/stock-items.cpp:175 +#: ../../po/../src/ui/stock-items.cpp:176 +#: ../../po/../src/ui/stock-items.cpp:177 +#: ../../po/../src/ui/stock-items.cpp:178 +#: ../../po/../src/ui/stock-items.cpp:181 +#: ../../po/../src/ui/stock-items.cpp:182 +#: ../../po/../src/ui/stock-items.cpp:183 +#: ../../po/../src/ui/stock-items.cpp:184 +#: ../../po/../src/ui/stock-items.cpp:185 +#: ../../po/../src/ui/stock-items.cpp:186 +#: ../../po/../src/ui/stock-items.cpp:187 +#: ../../po/../src/ui/stock-items.cpp:188 +#: ../../po/../src/ui/stock-items.cpp:189 +#: ../../po/../src/ui/stock-items.cpp:190 +#: ../../po/../src/ui/stock-items.cpp:191 +#: ../../po/../src/ui/stock-items.cpp:194 +#: ../../po/../src/ui/stock-items.cpp:195 +#: ../../po/../src/ui/stock-items.cpp:198 +#: ../../po/../src/ui/stock-items.cpp:199 +#: ../../po/../src/ui/stock-items.cpp:200 +#: ../../po/../src/ui/stock-items.cpp:201 +#: ../../po/../src/ui/stock-items.cpp:202 +msgid "PLACEHOLDER, do not translate" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:88 +msgid "small" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:89 +msgid "medium" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:90 +#, fuzzy +msgid "large" +msgstr "MÃ¥l:" + +#: ../../po/../src/ui/widget/panel.cpp:91 +msgid "huge" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:106 +#, fuzzy +msgid "List" +msgstr "Punkt" + +#: ../../po/../src/ui/widget/selected-style.cpp:67 +msgid "F:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:68 +msgid "S:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:69 +msgid "O:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:95 +msgid "N/A" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:98 +#: ../../po/../src/ui/widget/selected-style.cpp:712 +#, fuzzy +msgid "Nothing selected" +msgstr "Slett valgte objekter" + +#: ../../po/../src/ui/widget/selected-style.cpp:103 +msgid "No fill" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:103 +#, fuzzy +msgid "No stroke" +msgstr "Ingen maling" + +#: ../../po/../src/ui/widget/selected-style.cpp:105 +#: ../../po/../src/widgets/paint-selector.cpp:190 +#, fuzzy +msgid "Pattern" +msgstr "Mønster:" + +#: ../../po/../src/ui/widget/selected-style.cpp:108 +#: ../../po/../src/widgets/paint-selector.cpp:885 +#, fuzzy +msgid "Pattern fill" +msgstr "Mønster:" + +#: ../../po/../src/ui/widget/selected-style.cpp:108 +#, fuzzy +msgid "Pattern stroke" +msgstr "Valgte objekter" + +#: ../../po/../src/ui/widget/selected-style.cpp:110 +#, fuzzy +msgid "L Gradient" +msgstr "Gradientvektor" + +#: ../../po/../src/ui/widget/selected-style.cpp:113 +#, fuzzy +msgid "Linear gradient fill" +msgstr "Lineær gradient" + +#: ../../po/../src/ui/widget/selected-style.cpp:113 +#, fuzzy +msgid "Linear gradient stroke" +msgstr "Lineær gradient" + +#: ../../po/../src/ui/widget/selected-style.cpp:115 +#, fuzzy +msgid "R Gradient" +msgstr "Gradientvektor" + +#: ../../po/../src/ui/widget/selected-style.cpp:118 +#, fuzzy +msgid "Radial gradient fill" +msgstr "Radial gradient" + +#: ../../po/../src/ui/widget/selected-style.cpp:118 +#, fuzzy +msgid "Radial gradient stroke" +msgstr "Radial gradient" + +#: ../../po/../src/ui/widget/selected-style.cpp:120 +#, fuzzy +msgid "Different" +msgstr "Prosent" + +#: ../../po/../src/ui/widget/selected-style.cpp:123 +msgid "Different fills" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:123 +msgid "Different strokes" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:125 +#, fuzzy +msgid "Unset" +msgstr "Punkt" + +#. TRANSLATORS COMMENT: unset is a verb here +#: ../../po/../src/ui/widget/selected-style.cpp:128 +#: ../../po/../src/ui/widget/selected-style.cpp:182 +#, fuzzy +msgid "Unset fill" +msgstr "Uten navn" + +#: ../../po/../src/ui/widget/selected-style.cpp:128 +#: ../../po/../src/ui/widget/selected-style.cpp:182 +msgid "Unset stroke" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:131 +#, fuzzy +msgid "Flat color fill" +msgstr "Sluttfarge" + +#: ../../po/../src/ui/widget/selected-style.cpp:131 +#, fuzzy +msgid "Flat color stroke" +msgstr "Sluttfarge" + +#. TRANSLATOR COMMENT: A means "Averaged" +#: ../../po/../src/ui/widget/selected-style.cpp:134 +msgid "A" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:137 +#, fuzzy +msgid "Fill is averaged over selected objects" +msgstr "Slett valgte objekter" + +#: ../../po/../src/ui/widget/selected-style.cpp:137 +#, fuzzy +msgid "Stroke is averaged over selected objects" +msgstr "Slett valgte objekter" + +#. TRANSLATOR COMMENT: M means "Multiple" +#: ../../po/../src/ui/widget/selected-style.cpp:140 +msgid "M" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:143 +#, fuzzy +msgid "Multiple selected objects have the same fill" +msgstr "Vend valgte objekter vertikalt" + +#: ../../po/../src/ui/widget/selected-style.cpp:143 +#, fuzzy +msgid "Multiple selected objects have the same stroke" +msgstr "Vend valgte objekter vertikalt" + +#: ../../po/../src/ui/widget/selected-style.cpp:145 +#, fuzzy +msgid "Edit fill..." +msgstr "Rediger" + +#: ../../po/../src/ui/widget/selected-style.cpp:145 +#, fuzzy +msgid "Edit stroke..." +msgstr "Rediger" + +#: ../../po/../src/ui/widget/selected-style.cpp:149 +#, fuzzy +msgid "Last set color" +msgstr "Sluttfarge" + +#: ../../po/../src/ui/widget/selected-style.cpp:153 +#, fuzzy +msgid "Last selected color" +msgstr "Sist valgte" + +#: ../../po/../src/ui/widget/selected-style.cpp:157 +msgid "White" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:161 +#: ../../po/../src/widgets/sp-color-scales.cpp:461 +#: ../../po/../src/widgets/sp-color-scales.cpp:462 +#, fuzzy +msgid "Black" +msgstr "Sort:" + +#: ../../po/../src/ui/widget/selected-style.cpp:165 +#, fuzzy +msgid "Copy color" +msgstr "Startfarge" + +#: ../../po/../src/ui/widget/selected-style.cpp:169 +#, fuzzy +msgid "Paste color" +msgstr "Sluttfarge" + +#: ../../po/../src/ui/widget/selected-style.cpp:173 +#, fuzzy +msgid "Swap fill and stroke" +msgstr "Fyll og strøk" + +#: ../../po/../src/ui/widget/selected-style.cpp:177 +msgid "Make fill opaque" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:177 +msgid "Make stroke opaque" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:186 +#, fuzzy +msgid "Remove fill" +msgstr "Fjern lenke" + +#: ../../po/../src/ui/widget/selected-style.cpp:186 +#, fuzzy +msgid "Remove stroke" +msgstr "Fjern lenke" + +#: ../../po/../src/ui/widget/selected-style.cpp:718 +#, fuzzy +msgid "Master opacity" +msgstr "Ugjennomsiktighet" + +#: ../../po/../src/ui/widget/selected-style.cpp:744 +msgid "0 (transparent)" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:768 +msgid "1.0 (opaque)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1046 +msgid "Moved to next layer." +msgstr "" + +#: ../../po/../src/verbs.cpp:1048 +msgid "Cannot move past last layer." +msgstr "" + +#: ../../po/../src/verbs.cpp:1057 +msgid "Moved to previous layer." +msgstr "" + +#: ../../po/../src/verbs.cpp:1059 +msgid "Cannot move past first layer." +msgstr "" + +#: ../../po/../src/verbs.cpp:1076 ../../po/../src/verbs.cpp:1150 +#, fuzzy +msgid "No current layer." +msgstr "Dokumentnavn:" + +#: ../../po/../src/verbs.cpp:1105 +#, fuzzy, c-format +msgid "Raised layer %s." +msgstr "Hev node" + +#: ../../po/../src/verbs.cpp:1109 +#, fuzzy, c-format +msgid "Lowered layer %s." +msgstr "Velg" + +#: ../../po/../src/verbs.cpp:1118 +msgid "Cannot move layer any further." +msgstr "" + +#. TRANSLATORS: this means "The layer has been deleted." +#: ../../po/../src/verbs.cpp:1148 +#, fuzzy +msgid "Deleted layer." +msgstr "Velg" + +#: ../../po/../src/verbs.cpp:1544 +msgid "" +"You need to connect to a Jabber server before sharing a document with " +"another user." +msgstr "" + +#: ../../po/../src/verbs.cpp:1559 +msgid "" +"You need to connect to a Jabber server before sharing a document with a " +"chatroom." +msgstr "" + +#: ../../po/../src/verbs.cpp:1569 +msgid "XML node tracker has not been initialized; nothing to dump" +msgstr "" + +#. TRANSLATORS: If you have translated the keys.svg file to your language, then +#. translate this string as "keys.LANG.svg" (where LANG is your language code); +#. otherwise leave as "keys.svg". +#: ../../po/../src/verbs.cpp:1631 +msgid "keys.svg" +msgstr "" + +#. TRANSLATORS: If you have translated the tutorial-basic.svg file to your language, +#. then translate this string as "tutorial-basic.LANG.svg" (where LANG is your language +#. code); otherwise leave as "tutorial-basic.svg". +#: ../../po/../src/verbs.cpp:1667 +msgid "tutorial-basic.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1671 +msgid "tutorial-shapes.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1675 +msgid "tutorial-advanced.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1679 +msgid "tutorial-tracing.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1683 +msgid "tutorial-calligraphy.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1687 +msgid "tutorial-elements.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1691 +msgid "tutorial-tips.svg" +msgstr "" + +#: ../../po/../src/verbs.cpp:1842 +msgid "Does nothing" +msgstr "" + +#. File +#: ../../po/../src/verbs.cpp:1845 +#, fuzzy +msgid "Default" +msgstr "Forvalg" + +#: ../../po/../src/verbs.cpp:1845 +#, fuzzy +msgid "Create new document from default template" +msgstr "Opprett nytt SVG-dokument" + +#: ../../po/../src/verbs.cpp:1847 +#, fuzzy +msgid "_Open..." +msgstr "Åpne" + +#: ../../po/../src/verbs.cpp:1848 +#, fuzzy +msgid "Open existing document" +msgstr "Åpne eksisterende SVG-dokument" + +#: ../../po/../src/verbs.cpp:1849 +msgid "Re_vert" +msgstr "" + +#: ../../po/../src/verbs.cpp:1850 +msgid "Revert to the last saved version of document (changes will be lost)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1851 +#, fuzzy +msgid "_Save" +msgstr "Lagre" + +#: ../../po/../src/verbs.cpp:1851 +msgid "Save document" +msgstr "Lagre dokument" + +#: ../../po/../src/verbs.cpp:1853 +#, fuzzy +msgid "Save _As..." +msgstr "Lagre som" + +#: ../../po/../src/verbs.cpp:1854 +msgid "Save document under new name" +msgstr "Lagre dokument med nytt navn" + +#: ../../po/../src/verbs.cpp:1855 +#, fuzzy +msgid "_Print..." +msgstr "Skriv ut" + +#: ../../po/../src/verbs.cpp:1855 +msgid "Print document" +msgstr "Skriv ut dokument" + +#. TRANSLATORS: "Vacuum Defs" means "Clean up defs" (so as to remove unused definitions) +#: ../../po/../src/verbs.cpp:1858 +msgid "Vac_uum Defs" +msgstr "" + +#: ../../po/../src/verbs.cpp:1858 +msgid "Remove unused predefined items from the <defs> of the document" +msgstr "" + +#: ../../po/../src/verbs.cpp:1860 +#, fuzzy +msgid "Print _Direct" +msgstr "Egenskaper for lenke" + +#: ../../po/../src/verbs.cpp:1861 +msgid "Print directly without prompting to a file or pipe" +msgstr "" + +#: ../../po/../src/verbs.cpp:1862 +#, fuzzy +msgid "Print Previe_w" +msgstr "ForhÃ¥ndsvisning av utskrift" + +#: ../../po/../src/verbs.cpp:1863 +msgid "Preview document printout" +msgstr "ForhÃ¥ndsvis utskrift av dokument" + +#: ../../po/../src/verbs.cpp:1864 +#, fuzzy +msgid "_Import..." +msgstr "Importer" + +#: ../../po/../src/verbs.cpp:1865 +msgid "Import bitmap or SVG image into document" +msgstr "Importer bitkart eller SVG-bilde i dokumentet" + +#: ../../po/../src/verbs.cpp:1866 +#, fuzzy +msgid "_Export Bitmap..." +msgstr "Eksporter bitkart" + +#: ../../po/../src/verbs.cpp:1867 +#, fuzzy +msgid "Export document or selection as a bitmap image" +msgstr "Eksporter dokument som et PNG-bitkart" + +#: ../../po/../src/verbs.cpp:1868 +#, fuzzy +msgid "N_ext Window" +msgstr "Ny visning" + +#: ../../po/../src/verbs.cpp:1869 +msgid "Switch to the next document window" +msgstr "" + +#: ../../po/../src/verbs.cpp:1870 +#, fuzzy +msgid "P_revious Window" +msgstr "Ny visning" + +#: ../../po/../src/verbs.cpp:1871 +msgid "Switch to the previous document window" +msgstr "" + +#: ../../po/../src/verbs.cpp:1872 +#, fuzzy +msgid "_Close" +msgstr "Lukk" + +#: ../../po/../src/verbs.cpp:1873 +#, fuzzy +msgid "Close window" +msgstr "Lukk visning" + +#: ../../po/../src/verbs.cpp:1874 +msgid "_Quit" +msgstr "" + +#: ../../po/../src/verbs.cpp:1874 +#, fuzzy +msgid "Quit Inkscape" +msgstr "Sodipodi: %s: XML-visning" + +#. Edit +#: ../../po/../src/verbs.cpp:1877 +#, fuzzy +msgid "_Undo" +msgstr "Angre" + +#: ../../po/../src/verbs.cpp:1877 +#, fuzzy +msgid "Undo last action" +msgstr "Forkast siste handling" + +#: ../../po/../src/verbs.cpp:1879 +#, fuzzy +msgid "_Redo" +msgstr "Gjenopprett" + +#: ../../po/../src/verbs.cpp:1880 +#, fuzzy +msgid "Do again last undone action" +msgstr "Gjenopprett angret handling" + +#: ../../po/../src/verbs.cpp:1881 +#, fuzzy +msgid "Cu_t" +msgstr "Klipp ut" + +#: ../../po/../src/verbs.cpp:1882 +#, fuzzy +msgid "Cut selection to clipboard" +msgstr "Klipp ut valgte objekter til utklippstavlen" + +#: ../../po/../src/verbs.cpp:1883 +#, fuzzy +msgid "_Copy" +msgstr "Kopier" + +#: ../../po/../src/verbs.cpp:1884 +#, fuzzy +msgid "Copy selection to clipboard" +msgstr "Kopier valgte objekter til utklippstavlen" + +#: ../../po/../src/verbs.cpp:1885 +#, fuzzy +msgid "_Paste" +msgstr "Lim inn" + +#: ../../po/../src/verbs.cpp:1886 +#, fuzzy +msgid "Paste objects from clipboard to mouse point" +msgstr "Lim inn objekter fra utklippstavlen" + +#: ../../po/../src/verbs.cpp:1887 +#, fuzzy +msgid "Paste _Style" +msgstr "Stil for strøk" + +#: ../../po/../src/verbs.cpp:1888 +#, fuzzy +msgid "Apply style of the copied object to selection" +msgstr "Kopier valgte objekter til utklippstavlen" + +#: ../../po/../src/verbs.cpp:1889 +#, fuzzy +msgid "Paste _In Place" +msgstr "Stil for strøk" + +#: ../../po/../src/verbs.cpp:1890 +#, fuzzy +msgid "Paste objects from clipboard to the original location" +msgstr "Hev valgte objekter til toppen" + +#: ../../po/../src/verbs.cpp:1891 +#, fuzzy +msgid "_Delete" +msgstr "Slett" + +#: ../../po/../src/verbs.cpp:1892 +#, fuzzy +msgid "Delete selection" +msgstr "Slett valgte noder" + +#: ../../po/../src/verbs.cpp:1893 +#, fuzzy +msgid "Duplic_ate" +msgstr "Dupliser" + +#: ../../po/../src/verbs.cpp:1894 +#, fuzzy +msgid "Duplicate selected objects" +msgstr "Dupliser valgte objekter" + +#: ../../po/../src/verbs.cpp:1895 +#, fuzzy +msgid "Clo_ne" +msgstr "Lukk" + +#: ../../po/../src/verbs.cpp:1896 +msgid "Create a clone of selected object (a copy linked to the original)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1897 +msgid "Unlin_k Clone" +msgstr "" + +#: ../../po/../src/verbs.cpp:1898 +msgid "Cut the clone's link to its original" +msgstr "" + +#: ../../po/../src/verbs.cpp:1899 +#, fuzzy +msgid "Select _Original" +msgstr "Velg" + +#: ../../po/../src/verbs.cpp:1900 +#, fuzzy +msgid "Select the object to which the clone is linked" +msgstr "Klipp ut valgte objekter til utklippstavlen" + +#. TRANSLATORS: Convert selection to a rectangle with tiled pattern fill +#: ../../po/../src/verbs.cpp:1902 +#, fuzzy +msgid "O_bjects to Pattern" +msgstr "Objekt-transformasjon" + +#: ../../po/../src/verbs.cpp:1903 +msgid "Convert selection to a rectangle with tiled pattern fill" +msgstr "" + +#. TRANSLATORS: Extract objects from a tiled pattern fill +#: ../../po/../src/verbs.cpp:1905 +#, fuzzy +msgid "Pattern to Ob_jects" +msgstr "Valgte objekter" + +#: ../../po/../src/verbs.cpp:1906 +msgid "Extract objects from a tiled pattern fill" +msgstr "" + +#: ../../po/../src/verbs.cpp:1907 +#, fuzzy +msgid "Clea_r All" +msgstr "Tøm alle" + +#: ../../po/../src/verbs.cpp:1908 +msgid "Delete all objects from document" +msgstr "" + +#: ../../po/../src/verbs.cpp:1909 +#, fuzzy +msgid "Select Al_l" +msgstr "Velg" + +#: ../../po/../src/verbs.cpp:1910 +#, fuzzy +msgid "Select all objects or all nodes" +msgstr "Ingen gradienter i dokumentet" + +#: ../../po/../src/verbs.cpp:1911 +#, fuzzy +msgid "Select All in All La_yers" +msgstr "Velg" + +#: ../../po/../src/verbs.cpp:1912 +#, fuzzy +msgid "Select all objects in all visible and unlocked layers" +msgstr "Ingen gradienter i dokumentet" + +#: ../../po/../src/verbs.cpp:1913 +#, fuzzy +msgid "In_vert Selection" +msgstr "Valg" + +#: ../../po/../src/verbs.cpp:1914 +msgid "Invert selection (unselect what is selected and select everything else)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1915 +msgid "Invert in All Layers" +msgstr "" + +#: ../../po/../src/verbs.cpp:1916 +msgid "Invert selection in all visible and unlocked layers" +msgstr "" + +#: ../../po/../src/verbs.cpp:1917 +#, fuzzy +msgid "D_eselect" +msgstr "Velg" + +#: ../../po/../src/verbs.cpp:1918 +#, fuzzy +msgid "Deselect any selected objects or nodes" +msgstr "Slett valgte objekter" + +#. Selection +#: ../../po/../src/verbs.cpp:1921 +#, fuzzy +msgid "Raise to _Top" +msgstr "Hev valgte objekter til toppen" + +#: ../../po/../src/verbs.cpp:1922 +#, fuzzy +msgid "Raise selection to top" +msgstr "Hev valgte objekter til toppen" + +#: ../../po/../src/verbs.cpp:1923 +#, fuzzy +msgid "Lower to _Bottom" +msgstr "Senk valgte objekter til bunnen" + +#: ../../po/../src/verbs.cpp:1924 +#, fuzzy +msgid "Lower selection to bottom" +msgstr "Senk valgte objekter til bunnen" + +#: ../../po/../src/verbs.cpp:1925 +#, fuzzy +msgid "_Raise" +msgstr "Hev" + +#: ../../po/../src/verbs.cpp:1926 +#, fuzzy +msgid "Raise selection one step" +msgstr "Hev valgte objekter til toppen" + +#: ../../po/../src/verbs.cpp:1927 +#, fuzzy +msgid "_Lower" +msgstr "Senk" + +#: ../../po/../src/verbs.cpp:1928 +#, fuzzy +msgid "Lower selection one step" +msgstr "Senk valgte objekter ett nivÃ¥" + +#: ../../po/../src/verbs.cpp:1929 +#, fuzzy +msgid "_Group" +msgstr "Grupper" + +#: ../../po/../src/verbs.cpp:1930 +msgid "Group selected objects" +msgstr "Grupper valgte objekter" + +#: ../../po/../src/verbs.cpp:1932 +#, fuzzy +msgid "Ungroup selected groups" +msgstr "Del opp valgt gruppe" + +#: ../../po/../src/verbs.cpp:1934 +#, fuzzy +msgid "_Put on Path" +msgstr "Senk valgte objekter til bunnen" + +#: ../../po/../src/verbs.cpp:1935 +#, fuzzy +msgid "Put text on path" +msgstr "Senk valgte objekter til bunnen" + +#: ../../po/../src/verbs.cpp:1936 +#, fuzzy +msgid "_Remove from Path" +msgstr "Nullstill transformasjon" + +#: ../../po/../src/verbs.cpp:1937 +#, fuzzy +msgid "Remove text from path" +msgstr "Senk valgte objekter til bunnen" + +#: ../../po/../src/verbs.cpp:1938 +msgid "Remove Manual _Kerns" +msgstr "" + +#. TRANSLATORS: "glyph": An image used in the visual representation of characters; +#. roughly speaking, how a character looks. A font is a set of glyphs. +#: ../../po/../src/verbs.cpp:1941 +#, fuzzy +msgid "Remove all manual kerns and glyph rotations from a text object" +msgstr "Fjern transformering" + +#: ../../po/../src/verbs.cpp:1943 +#, fuzzy +msgid "_Union" +msgstr "Angre" + +#: ../../po/../src/verbs.cpp:1944 +#, fuzzy +msgid "Union of selected objects" +msgstr "Grupper valgte objekter" + +#: ../../po/../src/verbs.cpp:1945 +#, fuzzy +msgid "_Intersection" +msgstr "Valg" + +#: ../../po/../src/verbs.cpp:1946 +#, fuzzy +msgid "Intersection of selected objects" +msgstr "Slett valgte objekter" + +#: ../../po/../src/verbs.cpp:1947 +msgid "_Difference" +msgstr "" + +#: ../../po/../src/verbs.cpp:1948 +#, fuzzy +msgid "Difference of selected objects (bottom minus top)" +msgstr "Slett valgte objekter" + +#: ../../po/../src/verbs.cpp:1949 +#, fuzzy +msgid "E_xclusion" +msgstr "Utvidelse" + +#: ../../po/../src/verbs.cpp:1950 +#, fuzzy +msgid "Exclusive OR of selected objects" +msgstr "Slett valgte objekter" + +#: ../../po/../src/verbs.cpp:1951 +msgid "Di_vision" +msgstr "" + +#: ../../po/../src/verbs.cpp:1952 +msgid "Cut the bottom object into pieces" +msgstr "" + +#. TRANSLATORS: "to cut a path" is not the same as "to break a path apart" - see the +#. Advanced tutorial for more info +#: ../../po/../src/verbs.cpp:1955 +#, fuzzy +msgid "Cut _Path" +msgstr "Sist valgte" + +#: ../../po/../src/verbs.cpp:1956 +msgid "Cut the bottom object's stroke into pieces, removing fill" +msgstr "" + +#. TRANSLATORS: "outset": expand a shape by offsetting the object's path, +#. i.e. by displacing it perpendicular to the path in each point. +#. See also the Advanced Tutorial for explanation. +#: ../../po/../src/verbs.cpp:1960 +#, fuzzy +msgid "Outs_et" +msgstr "Sist valgte" + +#: ../../po/../src/verbs.cpp:1961 +#, fuzzy +msgid "Outset selected paths" +msgstr "Sist valgte" + +#: ../../po/../src/verbs.cpp:1963 +#, fuzzy +msgid "O_utset Path by 1 px" +msgstr "Sist valgte" + +#: ../../po/../src/verbs.cpp:1964 +#, fuzzy +msgid "Outset selected paths by 1 px" +msgstr "Sist valgte" + +#: ../../po/../src/verbs.cpp:1966 +#, fuzzy +msgid "O_utset Path by 10 px" +msgstr "Sist valgte" + +#: ../../po/../src/verbs.cpp:1967 +#, fuzzy +msgid "Outset selected paths by 10 px" +msgstr "Sist valgte" + +#. TRANSLATORS: "inset": contract a shape by offsetting the object's path, +#. i.e. by displacing it perpendicular to the path in each point. +#. See also the Advanced Tutorial for explanation. +#: ../../po/../src/verbs.cpp:1971 +msgid "I_nset" +msgstr "" + +#: ../../po/../src/verbs.cpp:1972 +#, fuzzy +msgid "Inset selected paths" +msgstr "Senk valgte objekter til bunnen" + +#: ../../po/../src/verbs.cpp:1974 +#, fuzzy +msgid "I_nset Path by 1 px" +msgstr "Sist valgte" + +#: ../../po/../src/verbs.cpp:1975 +#, fuzzy +msgid "Inset selected paths by 1 px" +msgstr "Senk valgte objekter til bunnen" + +#: ../../po/../src/verbs.cpp:1977 +#, fuzzy +msgid "I_nset Path by 10 px" +msgstr "Sist valgte" + +#: ../../po/../src/verbs.cpp:1978 +#, fuzzy +msgid "Inset selected paths by 10 px" +msgstr "Senk valgte objekter til bunnen" + +#: ../../po/../src/verbs.cpp:1980 +msgid "D_ynamic Offset" +msgstr "" + +#: ../../po/../src/verbs.cpp:1980 +msgid "Create a dynamic offset object" +msgstr "" + +#: ../../po/../src/verbs.cpp:1982 +msgid "_Linked Offset" +msgstr "" + +#: ../../po/../src/verbs.cpp:1983 +msgid "Create a dynamic offset object linked to the original path" +msgstr "" + +#: ../../po/../src/verbs.cpp:1985 +#, fuzzy +msgid "_Stroke to Path" +msgstr "Bredde pÃ¥ strøk" + +#: ../../po/../src/verbs.cpp:1986 +#, fuzzy +msgid "Convert selected strokes to paths" +msgstr "Senk valgte objekter til bunnen" + +#: ../../po/../src/verbs.cpp:1987 +msgid "Si_mplify" +msgstr "" + +#: ../../po/../src/verbs.cpp:1988 +msgid "Simplify selected paths by removing extra nodes" +msgstr "" + +#: ../../po/../src/verbs.cpp:1989 +#, fuzzy +msgid "_Reverse" +msgstr "Fil" + +#: ../../po/../src/verbs.cpp:1990 +#, fuzzy +msgid "Reverses the direction of selected paths; useful for flipping markers" +msgstr "Slett valgte objekter" + +#. TRANSLATORS: "to trace" means "to convert a bitmap to vector graphics" (to vectorize) +#: ../../po/../src/verbs.cpp:1992 +#, fuzzy +msgid "_Trace Bitmap" +msgstr "Eksporter bitkart" + +#: ../../po/../src/verbs.cpp:1993 +#, fuzzy +msgid "Convert bitmap object to paths" +msgstr "Senk valgte objekter til bunnen" + +#: ../../po/../src/verbs.cpp:1994 +#, fuzzy +msgid "_Make a Bitmap Copy" +msgstr "Eksporter bitkart" + +#: ../../po/../src/verbs.cpp:1995 +#, fuzzy +msgid "Export selection to a bitmap and insert it into document" +msgstr "Importer bitkart eller SVG-bilde i dokumentet" + +#: ../../po/../src/verbs.cpp:1996 +#, fuzzy +msgid "_Combine" +msgstr "Kombiner" + +#: ../../po/../src/verbs.cpp:1997 +msgid "Combine several paths into one" +msgstr "" + +#. TRANSLATORS: "to cut a path" is not the same as "to break a path apart" - see the +#. Advanced tutorial for more info +#: ../../po/../src/verbs.cpp:2000 +#, fuzzy +msgid "Break _Apart" +msgstr "Bryt opp" + +#: ../../po/../src/verbs.cpp:2001 +#, fuzzy +msgid "Break selected paths into subpaths" +msgstr "Bryt opp valgt sti i understier" + +#: ../../po/../src/verbs.cpp:2002 +msgid "Gri_d Arrange..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2003 +msgid "Arrange selection in grid pattern" +msgstr "" + +#. Layer +#: ../../po/../src/verbs.cpp:2005 +#, fuzzy +msgid "_Add Layer..." +msgstr "Senk" + +#: ../../po/../src/verbs.cpp:2006 +#, fuzzy +msgid "Create a new layer" +msgstr "Opprett nytt SVG-dokument" + +#: ../../po/../src/verbs.cpp:2007 +#, fuzzy +msgid "Re_name Layer..." +msgstr "Hev node" + +#: ../../po/../src/verbs.cpp:2008 +#, fuzzy +msgid "Rename the current layer" +msgstr "Velg" + +#: ../../po/../src/verbs.cpp:2009 +#, fuzzy +msgid "Switch to Layer Abov_e" +msgstr "Senk valgte objekter til bunnen" + +#: ../../po/../src/verbs.cpp:2010 +msgid "Switch to the layer above the current" +msgstr "" + +#: ../../po/../src/verbs.cpp:2011 +#, fuzzy +msgid "Switch to Layer Belo_w" +msgstr "Senk valgte objekter ett nivÃ¥" + +#: ../../po/../src/verbs.cpp:2012 +msgid "Switch to the layer below the current" +msgstr "" + +#: ../../po/../src/verbs.cpp:2013 +#, fuzzy +msgid "Move Selection to Layer Abo_ve" +msgstr "Senk valgte objekter til bunnen" + +#: ../../po/../src/verbs.cpp:2014 +msgid "Move selection to the layer above the current" +msgstr "" + +#: ../../po/../src/verbs.cpp:2015 +#, fuzzy +msgid "Move Selection to Layer Bel_ow" +msgstr "Senk valgte objekter ett nivÃ¥" + +#: ../../po/../src/verbs.cpp:2016 +msgid "Move selection to the layer below the current" +msgstr "" + +#: ../../po/../src/verbs.cpp:2017 +#, fuzzy +msgid "Layer to _Top" +msgstr "Hev valgte objekter til toppen" + +#: ../../po/../src/verbs.cpp:2018 +#, fuzzy +msgid "Raise the current layer to the top" +msgstr "Hev valgte objekter til toppen" + +#: ../../po/../src/verbs.cpp:2019 +#, fuzzy +msgid "Layer to _Bottom" +msgstr "Senk valgte objekter til bunnen" + +#: ../../po/../src/verbs.cpp:2020 +#, fuzzy +msgid "Lower the current layer to the bottom" +msgstr "Senk valgte objekter til bunnen" + +#: ../../po/../src/verbs.cpp:2021 +#, fuzzy +msgid "_Raise Layer" +msgstr "Hev node" + +#: ../../po/../src/verbs.cpp:2022 +msgid "Raise the current layer" +msgstr "" + +#: ../../po/../src/verbs.cpp:2023 +#, fuzzy +msgid "_Lower Layer" +msgstr "Senk node" + +#: ../../po/../src/verbs.cpp:2024 +msgid "Lower the current layer" +msgstr "" + +#: ../../po/../src/verbs.cpp:2025 +#, fuzzy +msgid "_Delete Current Layer" +msgstr "Velg" + +#: ../../po/../src/verbs.cpp:2026 +#, fuzzy +msgid "Delete the current layer" +msgstr "Velg" + +#. Object +#: ../../po/../src/verbs.cpp:2029 +#, fuzzy +msgid "Rotate _90° CW" +msgstr "Roter objekt 90° med klokken" + +#: ../../po/../src/verbs.cpp:2030 +#, fuzzy +msgid "Rotate selection 90° clockwise" +msgstr "Roter objekt 90° med klokken" + +#: ../../po/../src/verbs.cpp:2031 +#, fuzzy +msgid "Rotate 9_0° CCW" +msgstr "Roter objekt 90° med klokken" + +#: ../../po/../src/verbs.cpp:2032 +#, fuzzy +msgid "Rotate selection 90° counter-clockwise" +msgstr "Roter objekt 90° med klokken" + +#: ../../po/../src/verbs.cpp:2033 +#, fuzzy +msgid "Remove _Transformations" +msgstr "Nullstill transformasjon" + +#: ../../po/../src/verbs.cpp:2034 +#, fuzzy +msgid "Remove transformations from object" +msgstr "Fjern transformering" + +#: ../../po/../src/verbs.cpp:2035 +#, fuzzy +msgid "_Object to Path" +msgstr "Objekt-transformasjon" + +#: ../../po/../src/verbs.cpp:2036 +#, fuzzy +msgid "Convert selected objects to paths" +msgstr "Senk valgte objekter til bunnen" + +#: ../../po/../src/verbs.cpp:2037 +msgid "_Flow into Frame" +msgstr "" + +#: ../../po/../src/verbs.cpp:2038 +#, fuzzy +msgid "Put text into frames" +msgstr "Senk valgte objekter til bunnen" + +#: ../../po/../src/verbs.cpp:2039 +#, fuzzy +msgid "_Unflow" +msgstr "Angre" + +#: ../../po/../src/verbs.cpp:2040 +msgid "Remove text from frame (creates a single-line text object)" +msgstr "" + +#: ../../po/../src/verbs.cpp:2041 +#, fuzzy +msgid "_Convert to Text" +msgstr "Senk valgte objekter til bunnen" + +#: ../../po/../src/verbs.cpp:2042 +#, fuzzy +msgid "Convert flowed text to regular text objects (preserves appearance)" +msgstr "Senk valgte objekter til bunnen" + +#: ../../po/../src/verbs.cpp:2044 +#, fuzzy +msgid "Flip _Horizontal" +msgstr "Vend valgte objekter horisontalt" + +#: ../../po/../src/verbs.cpp:2044 +#, fuzzy +msgid "Flips selected objects horizontally" +msgstr "Vend valgte objekter horisontalt" + +#: ../../po/../src/verbs.cpp:2047 +#, fuzzy +msgid "Flip _Vertical" +msgstr "Sentrer vertikalt" + +#: ../../po/../src/verbs.cpp:2047 +#, fuzzy +msgid "Flips selected objects vertically" +msgstr "Vend valgte objekter vertikalt" + +#. Tools +#: ../../po/../src/verbs.cpp:2051 +msgid "Select" +msgstr "Velg" + +#: ../../po/../src/verbs.cpp:2052 +#, fuzzy +msgid "Select and transform objects" +msgstr "Utvalgsverktøy - velg og transformer objekter" + +#: ../../po/../src/verbs.cpp:2053 +#, fuzzy +msgid "Node Edit" +msgstr "Node" + +#: ../../po/../src/verbs.cpp:2054 +#, fuzzy +msgid "Edit path nodes or control handles" +msgstr "Dupliser valgte objekter" + +#: ../../po/../src/verbs.cpp:2056 +msgid "Create rectangles and squares" +msgstr "" + +#: ../../po/../src/verbs.cpp:2058 +msgid "Create circles, ellipses, and arcs" +msgstr "" + +#: ../../po/../src/verbs.cpp:2060 +msgid "Create stars and polygons" +msgstr "" + +#: ../../po/../src/verbs.cpp:2062 +#, fuzzy +msgid "Create spirals" +msgstr "Opprett lenke" + +#: ../../po/../src/verbs.cpp:2064 +msgid "Draw freehand lines" +msgstr "" + +#: ../../po/../src/verbs.cpp:2066 +msgid "Draw Bezier curves and straight lines" +msgstr "" + +#: ../../po/../src/verbs.cpp:2068 +#, fuzzy +msgid "Draw calligraphic lines" +msgstr "Kalligrafisk linje" + +#: ../../po/../src/verbs.cpp:2070 +#, fuzzy +msgid "Create and edit text objects" +msgstr "Distribuer" + +#: ../../po/../src/verbs.cpp:2072 +#, fuzzy +msgid "Create and edit gradients" +msgstr "Distribuer" + +#: ../../po/../src/verbs.cpp:2074 +#, fuzzy +msgid "Zoom in or out" +msgstr "Zoom ut i tegning" + +#: ../../po/../src/verbs.cpp:2076 +msgid "Pick averaged colors from image" +msgstr "" + +#: ../../po/../src/verbs.cpp:2078 +#, fuzzy +msgid "Create connectors" +msgstr "Opprett nytt SVG-dokument" + +#. Tool prefs +#: ../../po/../src/verbs.cpp:2081 +msgid "Selector Preferences" +msgstr "" + +#: ../../po/../src/verbs.cpp:2082 +#, fuzzy +msgid "Open Preferences for the Selector tool" +msgstr "Sodipodi: %s: XML-visning" + +#: ../../po/../src/verbs.cpp:2083 +#, fuzzy +msgid "Node Tool Preferences" +msgstr "Manglende brukervalg for verktøy" + +#: ../../po/../src/verbs.cpp:2084 +#, fuzzy +msgid "Open Preferences for the Node tool" +msgstr "Sodipodi: %s: XML-visning" + +#: ../../po/../src/verbs.cpp:2085 +#, fuzzy +msgid "Rectangle Preferences" +msgstr "Egenskaper for rektangel" + +#: ../../po/../src/verbs.cpp:2086 +#, fuzzy +msgid "Open Preferences for the Rectangle tool" +msgstr "Sodipodi: %s: XML-visning" + +#: ../../po/../src/verbs.cpp:2087 +#, fuzzy +msgid "Ellipse Preferences" +msgstr "Oppføring er referanse" + +#: ../../po/../src/verbs.cpp:2088 +#, fuzzy +msgid "Open Preferences for the Ellipse tool" +msgstr "Sodipodi: %s: XML-visning" + +#: ../../po/../src/verbs.cpp:2089 +#, fuzzy +msgid "Star Preferences" +msgstr "Egenskaper for stjerne" + +#: ../../po/../src/verbs.cpp:2090 +#, fuzzy +msgid "Open Preferences for the Star tool" +msgstr "Sodipodi: %s: XML-visning" + +#: ../../po/../src/verbs.cpp:2091 +#, fuzzy +msgid "Spiral Preferences" +msgstr "Egenskaper for spiral" + +#: ../../po/../src/verbs.cpp:2092 +#, fuzzy +msgid "Open Preferences for the Spiral tool" +msgstr "Sodipodi: %s: XML-visning" + +#: ../../po/../src/verbs.cpp:2093 +#, fuzzy +msgid "Pencil Preferences" +msgstr "Oppføring er referanse" + +#: ../../po/../src/verbs.cpp:2094 +#, fuzzy +msgid "Open Preferences for the Pencil tool" +msgstr "Sodipodi: %s: XML-visning" + +#: ../../po/../src/verbs.cpp:2095 +#, fuzzy +msgid "Pen Preferences" +msgstr "Oppføring er referanse" + +#: ../../po/../src/verbs.cpp:2096 +#, fuzzy +msgid "Open Preferences for the Pen tool" +msgstr "Sodipodi: %s: XML-visning" + +#: ../../po/../src/verbs.cpp:2097 +#, fuzzy +msgid "Calligraphic Preferences" +msgstr "Kalligrafisk linje" + +#: ../../po/../src/verbs.cpp:2098 +#, fuzzy +msgid "Open Preferences for the Calligraphy tool" +msgstr "Sodipodi: %s: XML-visning" + +#: ../../po/../src/verbs.cpp:2099 +#, fuzzy +msgid "Text Preferences" +msgstr "Oppføring er referanse" + +#: ../../po/../src/verbs.cpp:2100 +#, fuzzy +msgid "Open Preferences for the Text tool" +msgstr "Sodipodi: %s: XML-visning" + +#: ../../po/../src/verbs.cpp:2101 +#, fuzzy +msgid "Gradient Preferences" +msgstr "Oppføring er referanse" + +#: ../../po/../src/verbs.cpp:2102 +#, fuzzy +msgid "Open Preferences for the Gradient tool" +msgstr "Sodipodi: %s: XML-visning" + +#: ../../po/../src/verbs.cpp:2103 +#, fuzzy +msgid "Zoom Preferences" +msgstr "Oppføring er referanse" + +#: ../../po/../src/verbs.cpp:2104 +#, fuzzy +msgid "Open Preferences for the Zoom tool" +msgstr "Sodipodi: %s: XML-visning" + +#: ../../po/../src/verbs.cpp:2105 +#, fuzzy +msgid "Dropper Preferences" +msgstr "Sodipodi: %s: XML-visning" + +#: ../../po/../src/verbs.cpp:2106 +#, fuzzy +msgid "Open Preferences for the Dropper tool" +msgstr "Sodipodi: %s: XML-visning" + +#: ../../po/../src/verbs.cpp:2107 +#, fuzzy +msgid "Connector Preferences" +msgstr "Egenskaper for stjerne" + +#: ../../po/../src/verbs.cpp:2108 +#, fuzzy +msgid "Open Preferences for the Connector tool" +msgstr "Sodipodi: %s: XML-visning" + +#. Zoom/View +#: ../../po/../src/verbs.cpp:2111 +#, fuzzy +msgid "Zoom In" +msgstr "Zoom" + +#: ../../po/../src/verbs.cpp:2111 +#, fuzzy +msgid "Zoom in" +msgstr "Zoom" + +#: ../../po/../src/verbs.cpp:2112 +#, fuzzy +msgid "Zoom Out" +msgstr "Zoom ut i tegning" + +#: ../../po/../src/verbs.cpp:2112 +#, fuzzy +msgid "Zoom out" +msgstr "Zoom ut i tegning" + +#: ../../po/../src/verbs.cpp:2113 +#, fuzzy +msgid "_Rulers" +msgstr "Fil" + +#: ../../po/../src/verbs.cpp:2113 +#, fuzzy +msgid "Show or hide the canvas rulers" +msgstr "Vis rutenett" + +#: ../../po/../src/verbs.cpp:2114 +msgid "Scroll_bars" +msgstr "" + +#: ../../po/../src/verbs.cpp:2114 +#, fuzzy +msgid "Show or hide the canvas scrollbars" +msgstr "Vis rutenett" + +#: ../../po/../src/verbs.cpp:2115 +#, fuzzy +msgid "_Grid" +msgstr "Rutenett" + +#: ../../po/../src/verbs.cpp:2116 +#, fuzzy +msgid "G_uides" +msgstr "Rettesnorer" + +#: ../../po/../src/verbs.cpp:2117 +msgid "Nex_t Zoom" +msgstr "" + +#: ../../po/../src/verbs.cpp:2117 +msgid "Next zoom (from the history of zooms)" +msgstr "" + +#: ../../po/../src/verbs.cpp:2119 +msgid "Pre_vious Zoom" +msgstr "" + +#: ../../po/../src/verbs.cpp:2119 +msgid "Previous zoom (from the history of zooms)" +msgstr "" + +#: ../../po/../src/verbs.cpp:2121 +#, fuzzy +msgid "Zoom 1:_1" +msgstr "Sett zoom-faktor til 1:1" + +#: ../../po/../src/verbs.cpp:2121 +#, fuzzy +msgid "Zoom to 1:1" +msgstr "Sett zoom-faktor til 1:1" + +#: ../../po/../src/verbs.cpp:2123 +#, fuzzy +msgid "Zoom 1:_2" +msgstr "Sett zoom-faktor til 1:2" + +#: ../../po/../src/verbs.cpp:2123 +#, fuzzy +msgid "Zoom to 1:2" +msgstr "Sett zoom-faktor til 1:2" + +#: ../../po/../src/verbs.cpp:2125 +#, fuzzy +msgid "_Zoom 2:1" +msgstr "Sett zoom-faktor til 2:1" + +#: ../../po/../src/verbs.cpp:2125 +#, fuzzy +msgid "Zoom to 2:1" +msgstr "Sett zoom-faktor til 2:1" + +#: ../../po/../src/verbs.cpp:2128 +msgid "_Fullscreen" +msgstr "" + +#: ../../po/../src/verbs.cpp:2128 +msgid "Stretch this document window to full screen" +msgstr "" + +#: ../../po/../src/verbs.cpp:2131 +#, fuzzy +msgid "Duplic_ate Window" +msgstr "Duplisert node" + +#: ../../po/../src/verbs.cpp:2131 +#, fuzzy +msgid "Open a new window with the same document" +msgstr "Åpne eksisterende SVG-dokument" + +#: ../../po/../src/verbs.cpp:2133 +#, fuzzy +msgid "_New View Preview" +msgstr "Ny forhÃ¥ndsvisning" + +#: ../../po/../src/verbs.cpp:2134 +#, fuzzy +msgid "New View Preview" +msgstr "Ny forhÃ¥ndsvisning" + +#. "view_new_preview" +#: ../../po/../src/verbs.cpp:2136 +msgid "_Normal" +msgstr "" + +#: ../../po/../src/verbs.cpp:2137 +msgid "Switch to normal display mode" +msgstr "" + +#: ../../po/../src/verbs.cpp:2138 +#, fuzzy +msgid "_Outline" +msgstr "Vis omriss" + +#: ../../po/../src/verbs.cpp:2139 +msgid "Switch to outline (wireframe) display mode" +msgstr "" + +#: ../../po/../src/verbs.cpp:2141 +#, fuzzy +msgid "Ico_n Preview" +msgstr "Ny forhÃ¥ndsvisning" + +#: ../../po/../src/verbs.cpp:2142 +msgid "Open a window to preview items at different icon resolutions" +msgstr "" + +#: ../../po/../src/verbs.cpp:2144 +#, fuzzy +msgid "Zoom to fit page in window" +msgstr "Redigeringsvindu" + +#: ../../po/../src/verbs.cpp:2145 +msgid "Page _Width" +msgstr "" + +#: ../../po/../src/verbs.cpp:2146 +#, fuzzy +msgid "Zoom to fit page width in window" +msgstr "Redigeringsvindu" + +#: ../../po/../src/verbs.cpp:2148 +#, fuzzy +msgid "Zoom to fit drawing in window" +msgstr "Redigeringsvindu" + +#: ../../po/../src/verbs.cpp:2150 +msgid "Zoom to fit selection in window" +msgstr "" + +#. Dialogs +#: ../../po/../src/verbs.cpp:2153 +#, fuzzy +msgid "In_kscape Preferences..." +msgstr "Sodipodi: %s: XML-visning" + +#: ../../po/../src/verbs.cpp:2154 +#, fuzzy +msgid "Global Inkscape preferences" +msgstr "Skjerminstillinger" + +#: ../../po/../src/verbs.cpp:2155 +msgid "_Document Preferences..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2156 +#, fuzzy +msgid "Preferences saved with the document" +msgstr "Åpne eksisterende SVG-dokument" + +#: ../../po/../src/verbs.cpp:2157 +#, fuzzy +msgid "_Fill and Stroke..." +msgstr "Fyll og strøk" + +#: ../../po/../src/verbs.cpp:2158 +#, fuzzy +msgid "Fill and Stroke dialog" +msgstr "Fyll og strøk" + +#. TRANSLATORS: "Swatches" means: color samples +#: ../../po/../src/verbs.cpp:2160 +#, fuzzy +msgid "S_watches..." +msgstr "Lagre som" + +#: ../../po/../src/verbs.cpp:2161 +msgid "View color swatches" +msgstr "" + +#: ../../po/../src/verbs.cpp:2162 +#, fuzzy +msgid "Transfor_m..." +msgstr "Transformer:" + +#: ../../po/../src/verbs.cpp:2163 +#, fuzzy +msgid "Transform dialog" +msgstr "Transformasjoner" + +#: ../../po/../src/verbs.cpp:2164 +#, fuzzy +msgid "_Align and Distribute..." +msgstr "Distribuer" + +#: ../../po/../src/verbs.cpp:2165 +#, fuzzy +msgid "Align and Distribute dialog" +msgstr "Distribuer" + +#: ../../po/../src/verbs.cpp:2166 +#, fuzzy +msgid "_Text and Font..." +msgstr "Tekst og skrift" + +#: ../../po/../src/verbs.cpp:2167 +#, fuzzy +msgid "Text and Font dialog" +msgstr "Tekst og skrift" + +#: ../../po/../src/verbs.cpp:2168 +#, fuzzy +msgid "_XML Editor..." +msgstr "XML-redigering" + +#: ../../po/../src/verbs.cpp:2169 +msgid "XML Editor" +msgstr "XML-redigering" + +#: ../../po/../src/verbs.cpp:2170 +#, fuzzy +msgid "_Find..." +msgstr "Skriv ut" + +#: ../../po/../src/verbs.cpp:2171 +#, fuzzy +msgid "Find objects in document" +msgstr "Ingen gradienter i dokumentet" + +#: ../../po/../src/verbs.cpp:2172 +msgid "_Messages..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2173 +msgid "View debug messages" +msgstr "" + +#: ../../po/../src/verbs.cpp:2174 +#, fuzzy +msgid "S_cripts..." +msgstr "Skriv ut" + +#: ../../po/../src/verbs.cpp:2175 +msgid "Run scripts" +msgstr "" + +#: ../../po/../src/verbs.cpp:2176 +#, fuzzy +msgid "Show/Hide D_ialogs" +msgstr "Vis rutenett" + +#: ../../po/../src/verbs.cpp:2177 +msgid "Show or hide all active dialogs" +msgstr "" + +#. TRANSLATORS: "Tile clones" means: "Create tiled clones" +#: ../../po/../src/verbs.cpp:2179 +msgid "Tile clones..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2180 +msgid "Create and arrange multiple clones of selection" +msgstr "" + +#: ../../po/../src/verbs.cpp:2181 +#, fuzzy +msgid "_Object Properties..." +msgstr "Egenskaper for rektangel" + +#: ../../po/../src/verbs.cpp:2182 +#, fuzzy +msgid "Object Properties dialog" +msgstr "Egenskaper for rektangel" + +#: ../../po/../src/verbs.cpp:2185 +msgid "_Connect to Jabber server..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2185 +msgid "Connect to a Jabber server" +msgstr "" + +#: ../../po/../src/verbs.cpp:2187 +#, fuzzy +msgid "Share with _user..." +msgstr "Lagre som" + +#: ../../po/../src/verbs.cpp:2187 +msgid "Establish a whiteboard session with another Jabber user" +msgstr "" + +#: ../../po/../src/verbs.cpp:2189 +msgid "Share with _chatroom..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2189 +msgid "" +"Join a chatroom to start a new whiteboard session or join one in progress" +msgstr "" + +#: ../../po/../src/verbs.cpp:2191 +msgid "_Dump XML node tracker" +msgstr "" + +#: ../../po/../src/verbs.cpp:2191 +msgid "Dump the contents of the XML tracker to the console" +msgstr "" + +#: ../../po/../src/verbs.cpp:2193 +msgid "_Open session file..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2193 +msgid "Open and browse through records of past whiteboard sessions" +msgstr "" + +#: ../../po/../src/verbs.cpp:2195 +msgid "Session file playback" +msgstr "" + +#: ../../po/../src/verbs.cpp:2197 +msgid "_Disconnect from session" +msgstr "" + +#: ../../po/../src/verbs.cpp:2199 +msgid "Disconnect from _server" +msgstr "" + +#: ../../po/../src/verbs.cpp:2201 +msgid "_Input Devices..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2202 +msgid "Configure extended input devices" +msgstr "" + +#. Help +#: ../../po/../src/verbs.cpp:2205 +msgid "_Keys and Mouse" +msgstr "" + +#: ../../po/../src/verbs.cpp:2206 +msgid "Key and mouse shortcuts reference" +msgstr "" + +#: ../../po/../src/verbs.cpp:2207 +#, fuzzy +msgid "About E_xtensions" +msgstr "Utvidelse" + +#: ../../po/../src/verbs.cpp:2208 +#, fuzzy +msgid "About Extensions..." +msgstr "Utvidelse" + +#: ../../po/../src/verbs.cpp:2209 +#, fuzzy +msgid "About _Memory" +msgstr "Utvidelse" + +#: ../../po/../src/verbs.cpp:2210 +#, fuzzy +msgid "About Memory..." +msgstr "Utvidelse" + +#: ../../po/../src/verbs.cpp:2211 +msgid "_About Inkscape" +msgstr "" + +#. "help_about" +#. new HelpVerb(SP_VERB_SHOW_LICENSE, "ShowLicense", N_("Modifying or Redistributing Inkscape"), +#. N_("Show license to modify and/or redistribute Inkscape: GNU GPL"), NULL), +#. Tutorials +#: ../../po/../src/verbs.cpp:2217 +#, fuzzy +msgid "Inkscape: _Basic" +msgstr "Sodipodi: %s: XML-visning" + +#: ../../po/../src/verbs.cpp:2218 +msgid "Getting started with Inkscape" +msgstr "" + +#. "tutorial_basic" +#: ../../po/../src/verbs.cpp:2219 +#, fuzzy +msgid "Inkscape: _Shapes" +msgstr "Sodipodi: %s: XML-visning" + +#: ../../po/../src/verbs.cpp:2220 +msgid "Using shape tools to create and edit shapes" +msgstr "" + +#: ../../po/../src/verbs.cpp:2221 +#, fuzzy +msgid "Inkscape: _Advanced" +msgstr "Sodipodi: %s: XML-visning" + +#: ../../po/../src/verbs.cpp:2222 +#, fuzzy +msgid "Advanced Inkscape topics" +msgstr "Sodipodi: %s: XML-visning" + +#. "tutorial_advanced" +#. TRANSLATORS: "to trace" means "to convert a bitmap to vector graphics" (to vectorize) +#: ../../po/../src/verbs.cpp:2224 +#, fuzzy +msgid "Inkscape: T_racing" +msgstr "Sodipodi: %s: XML-visning" + +#: ../../po/../src/verbs.cpp:2225 +#, fuzzy +msgid "Using bitmap tracing" +msgstr "Størrelse pÃ¥ bitkart" + +#. "tutorial_tracing" +#: ../../po/../src/verbs.cpp:2226 +#, fuzzy +msgid "Inkscape: _Calligraphy" +msgstr "Sodipodi: %s: XML-visning" + +#: ../../po/../src/verbs.cpp:2227 +msgid "Using the Calligraphy pen tool" +msgstr "" + +#: ../../po/../src/verbs.cpp:2228 +msgid "_Elements of Design" +msgstr "" + +#: ../../po/../src/verbs.cpp:2229 +msgid "Principles of design in the tutorial form" +msgstr "" + +#. "tutorial_design" +#: ../../po/../src/verbs.cpp:2230 +msgid "_Tips and Tricks" +msgstr "" + +#: ../../po/../src/verbs.cpp:2231 +msgid "Miscellaneous tips and tricks" +msgstr "" + +#. "tutorial_tips" +#. Effect +#: ../../po/../src/verbs.cpp:2234 +msgid "Previous Effect" +msgstr "" + +#: ../../po/../src/verbs.cpp:2235 +msgid "Repeat the last effect with the same settings" +msgstr "" + +#. "tutorial_tips" +#: ../../po/../src/verbs.cpp:2236 +msgid "Previous Effect Settings..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2237 +msgid "Repeat the last effect with new settings" +msgstr "" + +#: ../../po/../src/widgets/dash-selector.cpp:106 +#, fuzzy +msgid "Dash pattern" +msgstr "Ingen maling" + +#: ../../po/../src/widgets/dash-selector.cpp:121 +#, fuzzy +msgid "Pattern offset" +msgstr "Valgte objekter" + +#: ../../po/../src/widgets/desktop-widget.cpp:240 +#, fuzzy +msgid "Zoom drawing if window size changes" +msgstr "Redigeringsvindu" + +#: ../../po/../src/widgets/desktop-widget.cpp:298 +msgid "Cursor coordinates" +msgstr "" + +#. display the initial welcome message in the statusbar +#: ../../po/../src/widgets/desktop-widget.cpp:324 +msgid "" +"Welcome to Inkscape! Use shape or freehand tools to create objects; " +"use selector (arrow) to move or transform them." +msgstr "" + +#: ../../po/../src/widgets/desktop-widget.cpp:372 +#, c-format +msgid "%s: %d - Inkscape" +msgstr "" + +#: ../../po/../src/widgets/desktop-widget.cpp:374 +#, c-format +msgid "%s - Inkscape" +msgstr "" + +#: ../../po/../src/widgets/desktop-widget.cpp:532 +#, c-format +msgid "" +"Save changes to document \"%s\" before " +"closing?\n" +"\n" +"If you close without saving, your changes will be discarded." +msgstr "" + +#: ../../po/../src/widgets/desktop-widget.cpp:548 +#: ../../po/../src/widgets/desktop-widget.cpp:612 +msgid "Close _without saving" +msgstr "" + +#: ../../po/../src/widgets/desktop-widget.cpp:595 +#, c-format +msgid "" +"The file \"%s\" was saved with a " +"format (%s) that may cause data loss!\n" +"\n" +"Do you want to save this file in another format?" +msgstr "" + +#. Family frame +#: ../../po/../src/widgets/font-selector.cpp:156 +msgid "Font family" +msgstr "Skriftfamilie" + +#. Style frame +#: ../../po/../src/widgets/font-selector.cpp:184 +msgid "Style" +msgstr "Stil" + +#: ../../po/../src/widgets/font-selector.cpp:219 +msgid "Font size:" +msgstr "Skriftstørrelse" + +#. TRANSLATORS: Test string used in text and font dialog (when no +#. * text has been entered) to get a preview of the font. Choose +#. * some representative characters that users of your locale will be +#. * interested in. +#: ../../po/../src/widgets/font-selector.cpp:554 +msgid "AaBbCcIiPpQq12368.;/()" +msgstr "AaBbCcIiPpQq12368.;/()" + +#: ../../po/../src/widgets/gradient-selector.cpp:137 +#: ../../po/../src/widgets/gradient-toolbar.cpp:524 +#, fuzzy +msgid "Duplicate" +msgstr "Dupliser" + +#: ../../po/../src/widgets/gradient-selector.cpp:142 +#: ../../po/../src/widgets/gradient-toolbar.cpp:535 +#, fuzzy +msgid "Edit..." +msgstr "Rediger" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/pservers.html#LinearGradientSpreadMethodAttribute +#: ../../po/../src/widgets/gradient-selector.cpp:159 +msgid "" +"Whether to fill with flat color beyond the ends of the gradient vector " +"(spreadMethod=\"pad\"), or repeat the gradient in the same direction " +"(spreadMethod=\"repeat\"), or repeat the gradient in alternating opposite " +"directions (spreadMethod=\"reflect\")" +msgstr "" + +#: ../../po/../src/widgets/gradient-selector.cpp:165 +#, fuzzy +msgid "none" +msgstr "Ingen" + +#: ../../po/../src/widgets/gradient-selector.cpp:169 +#, fuzzy +msgid "reflected" +msgstr "Først valgte" + +#: ../../po/../src/widgets/gradient-selector.cpp:173 +#, fuzzy +msgid "direct" +msgstr "Rektangel" + +#: ../../po/../src/widgets/gradient-selector.cpp:181 +msgid "Repeat:" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:217 +msgid "No gradients" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:226 +#, fuzzy +msgid "Nothing selected" +msgstr "Sist valgte" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:237 +#, fuzzy +msgid "No gradients in selection" +msgstr "Ingen gradient valgt" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:247 +msgid "Multiple gradients" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:525 +msgid "" +"If the gradient is used by more than one object, create a copy of it for the " +"selected object(s)" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:536 +#, fuzzy +msgid "Edit the stops of the gradient" +msgstr "Lineær gradient" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:593 +#: ../../po/../src/widgets/toolbox.cpp:1103 +#: ../../po/../src/widgets/toolbox.cpp:1192 +#: ../../po/../src/widgets/toolbox.cpp:1485 +#: ../../po/../src/widgets/toolbox.cpp:1534 +#: ../../po/../src/widgets/toolbox.cpp:1766 +#: ../../po/../src/widgets/toolbox.cpp:1801 +#: ../../po/../src/widgets/toolbox.cpp:2331 +#: ../../po/../src/widgets/toolbox.cpp:2370 +msgid "New:" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:606 +#, fuzzy +msgid "Create linear gradient" +msgstr "Lineær gradient" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:620 +msgid "Create radial (elliptic or circular) gradient" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:635 +#, fuzzy +msgid "on" +msgstr "Ingen" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:648 +#, fuzzy +msgid "Create gradient in the fill" +msgstr "Gradientvektor" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:662 +msgid "Create gradient in the stroke" +msgstr "" + +#. FIXME: implement averaging of all parameters for multiple selected stars +#. gtk_label_set_markup(GTK_LABEL(l), _("Average:")); +#. FIXME: implement averaging of all parameters for multiple selected +#. gtk_label_set_markup(GTK_LABEL(l), _("Average:")); +#: ../../po/../src/widgets/gradient-toolbar.cpp:676 +#: ../../po/../src/widgets/toolbox.cpp:1105 +#: ../../po/../src/widgets/toolbox.cpp:1124 +#: ../../po/../src/widgets/toolbox.cpp:1493 +#: ../../po/../src/widgets/toolbox.cpp:1518 +#: ../../po/../src/widgets/toolbox.cpp:1768 +#: ../../po/../src/widgets/toolbox.cpp:1787 +#: ../../po/../src/widgets/toolbox.cpp:2334 +#: ../../po/../src/widgets/toolbox.cpp:2354 +msgid "Change:" +msgstr "" + +#: ../../po/../src/widgets/gradient-vector.cpp:269 +msgid "No gradients in document" +msgstr "Ingen gradienter i dokumentet" + +#: ../../po/../src/widgets/gradient-vector.cpp:275 +msgid "No gradient selected" +msgstr "Ingen gradient valgt" + +#: ../../po/../src/widgets/gradient-vector.cpp:532 +#, fuzzy +msgid "No stops in gradient" +msgstr "Lineær gradient" + +#. TRANSLATORS: "Stop" means: a "phase" of a gradient +#: ../../po/../src/widgets/gradient-vector.cpp:794 +msgid "Add stop" +msgstr "" + +#: ../../po/../src/widgets/gradient-vector.cpp:797 +msgid "Add another control stop to gradient" +msgstr "" + +#: ../../po/../src/widgets/gradient-vector.cpp:799 +#, fuzzy +msgid "Delete stop" +msgstr "Slett node" + +#: ../../po/../src/widgets/gradient-vector.cpp:802 +msgid "Delete current control stop from gradient" +msgstr "" + +#. Label +#: ../../po/../src/widgets/gradient-vector.cpp:813 +msgid "Offset:" +msgstr "" + +#. TRANSLATORS: "Stop" means: a "phase" of a gradient +#: ../../po/../src/widgets/gradient-vector.cpp:858 +#, fuzzy +msgid "Stop Color" +msgstr "Startfarge" + +#: ../../po/../src/widgets/gradient-vector.cpp:887 +#, fuzzy +msgid "Gradient editor" +msgstr "Gradientvektor" + +#: ../../po/../src/widgets/layer-selector.cpp:119 +#, fuzzy +msgid "Toggle current layer visibility" +msgstr "Dokumentnavn:" + +#: ../../po/../src/widgets/layer-selector.cpp:139 +#, fuzzy +msgid "Lock or unlock current layer" +msgstr "Dokumentnavn:" + +#: ../../po/../src/widgets/layer-selector.cpp:142 +#, fuzzy +msgid "Current layer" +msgstr "Dokumentnavn:" + +#: ../../po/../src/widgets/layer-selector.cpp:553 +msgid "(root)" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:182 +#: ../../po/../src/widgets/paint-selector.cpp:561 +msgid "No paint" +msgstr "Ingen maling" + +#: ../../po/../src/widgets/paint-selector.cpp:184 +#: ../../po/../src/widgets/paint-selector.cpp:629 +#, fuzzy +msgid "Flat color" +msgstr "Sluttfarge" + +#: ../../po/../src/widgets/paint-selector.cpp:186 +#: ../../po/../src/widgets/paint-selector.cpp:696 +msgid "Linear gradient" +msgstr "Lineær gradient" + +#: ../../po/../src/widgets/paint-selector.cpp:188 +#: ../../po/../src/widgets/paint-selector.cpp:699 +msgid "Radial gradient" +msgstr "Radial gradient" + +#: ../../po/../src/widgets/paint-selector.cpp:192 +msgid "Unset paint (make it undefined so it can be inherited)" +msgstr "" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/painting.html#FillRuleProperty +#: ../../po/../src/widgets/paint-selector.cpp:204 +msgid "" +"Any path self-intersections or subpaths create holes in the fill (fill-rule: " +"evenodd)" +msgstr "" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/painting.html#FillRuleProperty +#: ../../po/../src/widgets/paint-selector.cpp:215 +msgid "" +"Fill is solid unless a subpath is counterdirectional (fill-rule: nonzero)" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:528 +msgid "No objects" +msgstr "Ingen objekter" + +#: ../../po/../src/widgets/paint-selector.cpp:539 +msgid "Multiple styles" +msgstr "Flere stiler" + +#: ../../po/../src/widgets/paint-selector.cpp:550 +msgid "Paint is undefined" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:757 +#, fuzzy +msgid "No patterns in document" +msgstr "Ingen gradienter i dokumentet" + +#: ../../po/../src/widgets/paint-selector.cpp:872 +msgid "" +"Use Edit > Object(s) to Pattern to create a new pattern from " +"selection." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:426 +msgid "Now stroke width is scaled when objects are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:428 +msgid "Now stroke width is not scaled when objects are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:436 +msgid "" +"Now rounded rectangle corners are scaled when rectangles are " +"scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:438 +msgid "" +"Now rounded rectangle corners are not scaled when rectangles " +"are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:446 +msgid "" +"Now gradients are transformed along with their objects when " +"those are transformed (moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:448 +msgid "" +"Now gradients remain fixed when objects are transformed " +"(moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:456 +msgid "" +"Now patterns are transformed along with their objects when " +"those are transformed (moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:458 +msgid "" +"Now patterns remain fixed when objects are transformed (moved, " +"scaled, rotated, or skewed)." +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:506 +#, fuzzy +msgid "select_toolbar|X" +msgstr "Velg" + +#: ../../po/../src/widgets/select-toolbar.cpp:506 +msgid "Horizontal coordinate of selection" +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:511 +#, fuzzy +msgid "select_toolbar|Y" +msgstr "Velg" + +#: ../../po/../src/widgets/select-toolbar.cpp:511 +msgid "Vertical coordinate of selection" +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:517 +#, fuzzy +msgid "select_toolbar|W" +msgstr "Velg" + +#: ../../po/../src/widgets/select-toolbar.cpp:517 +msgid "Width of selection" +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:525 +msgid "Change both width and height by the same proportion" +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:534 +#, fuzzy +msgid "select_toolbar|H" +msgstr "Velg" + +#: ../../po/../src/widgets/select-toolbar.cpp:534 +msgid "Height of selection" +msgstr "" + +#: ../../po/../src/widgets/sp-color-gtkselector.cpp:62 +msgid "System" +msgstr "" + +#: ../../po/../src/widgets/sp-color-notebook.cpp:322 +#, fuzzy +msgid "RGBA_:" +msgstr "RGB" + +#: ../../po/../src/widgets/sp-color-notebook.cpp:330 +msgid "Hexadecimal RGBA value of the color" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "RGB" +msgstr "RGB" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +#, fuzzy +msgid "HSL" +msgstr "HSV" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "CMYK" +msgstr "CMYK" + +#: ../../po/../src/widgets/sp-color-scales.cpp:397 +msgid "_R" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:398 +#: ../../po/../src/widgets/sp-color-scales.cpp:399 +#, fuzzy +msgid "Red" +msgstr "Rød:" + +#: ../../po/../src/widgets/sp-color-scales.cpp:400 +msgid "_G" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:401 +#: ../../po/../src/widgets/sp-color-scales.cpp:402 +#, fuzzy +msgid "Green" +msgstr "Grønn:" + +#: ../../po/../src/widgets/sp-color-scales.cpp:403 +msgid "_B" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:404 +#: ../../po/../src/widgets/sp-color-scales.cpp:405 +#, fuzzy +msgid "Blue" +msgstr "BlÃ¥:" + +#. Label +#: ../../po/../src/widgets/sp-color-scales.cpp:406 +#: ../../po/../src/widgets/sp-color-scales.cpp:432 +#: ../../po/../src/widgets/sp-color-scales.cpp:463 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:141 +msgid "_A" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:407 +#: ../../po/../src/widgets/sp-color-scales.cpp:408 +#: ../../po/../src/widgets/sp-color-scales.cpp:433 +#: ../../po/../src/widgets/sp-color-scales.cpp:434 +#: ../../po/../src/widgets/sp-color-scales.cpp:464 +#: ../../po/../src/widgets/sp-color-scales.cpp:465 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:151 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:163 +msgid "Alpha (opacity)" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:423 +msgid "_H" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:424 +#: ../../po/../src/widgets/sp-color-scales.cpp:425 +#, fuzzy +msgid "Hue" +msgstr "Glød:" + +#: ../../po/../src/widgets/sp-color-scales.cpp:426 +msgid "_S" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:427 +#: ../../po/../src/widgets/sp-color-scales.cpp:428 +#, fuzzy +msgid "Saturation" +msgstr "Metning:" + +#: ../../po/../src/widgets/sp-color-scales.cpp:429 +msgid "_L" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:430 +#: ../../po/../src/widgets/sp-color-scales.cpp:431 +#, fuzzy +msgid "Lightness" +msgstr "Høyde:" + +#: ../../po/../src/widgets/sp-color-scales.cpp:451 +msgid "_C" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:452 +#: ../../po/../src/widgets/sp-color-scales.cpp:453 +#, fuzzy +msgid "Cyan" +msgstr "Cyan:" + +#: ../../po/../src/widgets/sp-color-scales.cpp:454 +msgid "_M" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:455 +#: ../../po/../src/widgets/sp-color-scales.cpp:456 +#, fuzzy +msgid "Magenta" +msgstr "Magenta:" + +#: ../../po/../src/widgets/sp-color-scales.cpp:457 +msgid "_Y" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:458 +#: ../../po/../src/widgets/sp-color-scales.cpp:459 +#, fuzzy +msgid "Yellow" +msgstr "Gul:" + +#: ../../po/../src/widgets/sp-color-scales.cpp:460 +msgid "_K" +msgstr "" + +#: ../../po/../src/widgets/sp-color-selector.cpp:71 +msgid "Unnamed" +msgstr "" + +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:68 +msgid "Wheel" +msgstr "" + +#: ../../po/../src/widgets/sp-xmlview-attr-list.cpp:53 +msgid "Attribute" +msgstr "Attributt" + +#: ../../po/../src/widgets/sp-xmlview-attr-list.cpp:54 +msgid "Value" +msgstr "Verdi" + +#: ../../po/../src/widgets/toolbox.cpp:424 +msgid "Insert new nodes into selected segments" +msgstr "Sett inn nye noder i valgte segmenter" + +#: ../../po/../src/widgets/toolbox.cpp:426 +msgid "Delete selected nodes" +msgstr "Slett valgte noder" + +#: ../../po/../src/widgets/toolbox.cpp:431 +#, fuzzy +msgid "Join paths at selected nodes" +msgstr "SlÃ¥ sammen linjer ved valgte noder" + +#: ../../po/../src/widgets/toolbox.cpp:433 +#, fuzzy +msgid "Join paths at selected nodes with new segment" +msgstr "SlÃ¥ sammen linjer ved valgte noder" + +#: ../../po/../src/widgets/toolbox.cpp:436 +msgid "Split path between two non-endpoint nodes" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:439 +#, fuzzy +msgid "Break path at selected nodes" +msgstr "Bryt linje ved valgte noder" + +#: ../../po/../src/widgets/toolbox.cpp:444 +msgid "Make selected nodes corner" +msgstr "Gjør valgte noder til hjørne" + +#: ../../po/../src/widgets/toolbox.cpp:447 +msgid "Make selected nodes smooth" +msgstr "Jevn ut valgte noder" + +#: ../../po/../src/widgets/toolbox.cpp:450 +#, fuzzy +msgid "Make selected nodes symmetric" +msgstr "Jevn ut valgte noder" + +#: ../../po/../src/widgets/toolbox.cpp:455 +msgid "Make selected segments lines" +msgstr "Gjør valgte segmenter til linjer" + +#: ../../po/../src/widgets/toolbox.cpp:458 +msgid "Make selected segments curves" +msgstr "Gjør valgte noder om til kurver" + +#: ../../po/../src/widgets/toolbox.cpp:1199 +msgid "Polygon" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1206 +msgid "Regular polygon (with one handle) instead of a star" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1218 +msgid "Corners:" +msgstr "Hjørner:" + +#: ../../po/../src/widgets/toolbox.cpp:1218 +msgid "Number of corners of a polygon or star" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1228 +#, fuzzy +msgid "Spoke ratio:" +msgstr "Proporsjon:" + +#. TRANSLATORS: Tip radius of a star is the distance from the center to the farthest handle. +#. Base radius is the same for the closest handle. +#: ../../po/../src/widgets/toolbox.cpp:1231 +msgid "Base radius to tip radius ratio" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1246 +#, fuzzy +msgid "Rounded:" +msgstr "Rolle:" + +#: ../../po/../src/widgets/toolbox.cpp:1246 +msgid "How much rounded are the corners (0 for sharp)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1256 +msgid "Randomized:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1256 +msgid "Scatter randomly the corners and angles" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1269 +#: ../../po/../src/widgets/toolbox.cpp:1838 +#: ../../po/../src/widgets/toolbox.cpp:2061 +msgid "Defaults" +msgstr "Forvalg" + +#: ../../po/../src/widgets/toolbox.cpp:1270 +#: ../../po/../src/widgets/toolbox.cpp:1839 +#: ../../po/../src/widgets/toolbox.cpp:2062 +msgid "" +"Reset shape parameters to defaults (use Inkscape Preferences > Tools to " +"change defaults)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1544 +msgid "W:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1544 +#, fuzzy +msgid "Width of rectangle" +msgstr "Rektangel" + +#: ../../po/../src/widgets/toolbox.cpp:1556 +#, fuzzy +msgid "Height of rectangle" +msgstr "Rektangel" + +#: ../../po/../src/widgets/toolbox.cpp:1568 +#, fuzzy +msgid "Rx:" +msgstr "x0:" + +#: ../../po/../src/widgets/toolbox.cpp:1568 +msgid "Horizontal radius of rounded corners" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1578 +#, fuzzy +msgid "Ry:" +msgstr "y0:" + +#: ../../po/../src/widgets/toolbox.cpp:1578 +msgid "Vertical radius of rounded corners" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1594 +msgid "Not rounded" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1596 +msgid "Make corners sharp" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1805 +#, fuzzy +msgid "Turns:" +msgstr "Transformer:" + +#: ../../po/../src/widgets/toolbox.cpp:1805 +msgid "Number of revolutions" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1815 +msgid "Divergence:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1815 +msgid "How much denser/sparser are outer revolutions; 1 = uniform" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1825 +msgid "Inner radius:" +msgstr "Indre radius:" + +#: ../../po/../src/widgets/toolbox.cpp:1825 +msgid "Radius of the innermost revolution (relative to the spiral size)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1957 +msgid "The width of the calligraphic pen (relative to the visible canvas area)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1967 +#, fuzzy +msgid "Thinning:" +msgstr "Rendering" + +#: ../../po/../src/widgets/toolbox.cpp:1967 +msgid "" +"How much velocity thins the stroke (> 0 makes fast strokes thinner, < 0 " +"makes them broader, 0 makes width independent of velocity)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1980 +msgid "Angle:" +msgstr "Vinkel:" + +#: ../../po/../src/widgets/toolbox.cpp:1980 +msgid "" +"The angle of the pen's nib (in degrees; 0 = horizontal; has no effect if " +"fixation = 0)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1990 +#, fuzzy +msgid "Fixation:" +msgstr "Orientering:" + +#: ../../po/../src/widgets/toolbox.cpp:1990 +msgid "" +"How fixed is the pen angle (0 = always perpendicular to stroke direction, 1 " +"= fixed)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2003 +msgid "Mass:" +msgstr "Masse:" + +#: ../../po/../src/widgets/toolbox.cpp:2003 +msgid "How much inertia affects the movement of the pen" +msgstr "" + +#. TRANSLATORS: "drag" means "resistance" here +#: ../../po/../src/widgets/toolbox.cpp:2014 +msgid "Drag:" +msgstr "Dra:" + +#: ../../po/../src/widgets/toolbox.cpp:2014 +msgid "How much resistance affects the movement of the pen" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2034 +msgid "Use the pressure of the input device to alter the width of the pen" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2047 +msgid "Use the tilt of the input device to alter the angle of the pen's nib" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2374 +#, fuzzy +msgid "Start:" +msgstr "Stjerne" + +#: ../../po/../src/widgets/toolbox.cpp:2374 +msgid "The angle (in degrees) from the horizontal to the arc's start point" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2384 +msgid "End:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2384 +msgid "The angle (in degrees) from the horizontal to the arc's end point" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2395 +#, fuzzy +msgid "Open arc" +msgstr "Åpne" + +#: ../../po/../src/widgets/toolbox.cpp:2396 +msgid "" +"Switch between arc (unclosed shape) and segment (closed shape with two radii)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2415 +msgid "Make whole" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2417 +msgid "Make the shape a whole ellipse, not arc or segment" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2644 +msgid "" +"When pressed, picks visible color without alpha and when not pressed, picks " +"color including its alpha" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:3039 +#, fuzzy +msgid "Make connectors avoid selected objects" +msgstr "Slett valgte objekter" + +#: ../../po/../src/widgets/toolbox.cpp:3043 +#, fuzzy +msgid "Make connectors ignore selected objects" +msgstr "Slett valgte objekter" + +#. +#. 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 : +#: ../share/extensions/addnodes.inx.h:1 +#, fuzzy +msgid "Add Nodes" +msgstr "Noder" + +#: ../share/extensions/addnodes.inx.h:2 +msgid "Maximum Segment Length" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:1 +#, fuzzy +msgid "AI Input" +msgstr "Inndata" + +#: ../share/extensions/ai_input.inx.h:2 ../share/extensions/ai_output.inx.h:2 +msgid "Adobe Illustrator (*.ai)" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:3 +msgid "Open files saved with Adobe Illustrator" +msgstr "" + +#: ../share/extensions/ai_output.inx.h:1 +#, fuzzy +msgid "AI Output" +msgstr "Klipp ut" + +#: ../share/extensions/ai_output.inx.h:3 +#, fuzzy +msgid "Write Adobe Illustrator" +msgstr "Vektorillustrator" + +#: ../share/extensions/dia.inx.h:1 +msgid "A diagram created with the program Dia" +msgstr "" + +#: ../share/extensions/dia.inx.h:2 +msgid "Dia Diagram (*.dia)" +msgstr "" + +#: ../share/extensions/dia.inx.h:3 +#, fuzzy +msgid "Dia Input" +msgstr "Inndata" + +#: ../share/extensions/dia.inx.h:4 +msgid "" +"In order to import Dia files, Dia itself must be installed. You can get Dia " +"at http://www.gnome.org/projects/dia/" +msgstr "" + +#: ../share/extensions/dia.inx.h:5 +msgid "" +"The dia2svg.sh script should be installed with your Inkscape distribution. " +"If you do not have it, there is likely to be something wrong with your " +"Inkscape installation." +msgstr "" + +#: ../share/extensions/dots.inx.h:1 +#, fuzzy +msgid "Connect the Dots" +msgstr "Hjørner:" + +#: ../share/extensions/dots.inx.h:2 +#, fuzzy +msgid "Dot Size" +msgstr "Sider:" + +#: ../share/extensions/dots.inx.h:3 +#, fuzzy +msgid "Font Size" +msgstr "Skriftstørrelse" + +#: ../share/extensions/dropshadow.inx.h:1 +msgid "Color of shadow" +msgstr "" + +#: ../share/extensions/dropshadow.inx.h:2 +msgid "Dropshadow" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:1 +#: ../share/extensions/dxf_output.inx.h:1 +msgid "AutoCAD DXF (*.dxf)" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:2 +#, fuzzy +msgid "DXF Input" +msgstr "Inndata" + +#: ../share/extensions/dxf_input.inx.h:3 +msgid "Import AutoCAD's Document Exchange Format" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:4 +msgid "" +"dxf2svg may come with Inkscape, but is also at http://dxf-svg-convert." +"sourceforge.net/" +msgstr "" + +#: ../share/extensions/dxf_output.inx.h:2 +#, fuzzy +msgid "DXF Output" +msgstr "Klipp ut" + +#: ../share/extensions/dxf_output.inx.h:3 +msgid "DXF file written by pstoedit" +msgstr "" + +#: ../share/extensions/dxf_output.inx.h:4 +msgid "pstoedit must be installed to run see http://www.pstoedit.net/pstoedit" +msgstr "" + +#: ../share/extensions/embedimage.inx.h:1 +#, fuzzy +msgid "Embed Images" +msgstr "Bilde" + +#: ../share/extensions/eps_input.inx.h:1 +#, fuzzy +msgid "EPS Input" +msgstr "Inndata" + +#: ../share/extensions/eps_input.inx.h:2 +msgid "Encapsulated Postscript" +msgstr "" + +#: ../share/extensions/eps_input.inx.h:3 +msgid "Encapsulated Postscript (*.eps)" +msgstr "" + +#: ../share/extensions/epsi_output.inx.h:1 +#, fuzzy +msgid "EPSI Output" +msgstr "Klipp ut" + +#: ../share/extensions/epsi_output.inx.h:2 +msgid "Encapsulated Postscript Interchange (*.epsi)" +msgstr "" + +#: ../share/extensions/epsi_output.inx.h:3 +msgid "Encapsulated Postscript with a thumbnail" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:1 ../share/extensions/ffms.inx.h:1 +#: ../share/extensions/ffset.inx.h:1 ../share/extensions/ffss.inx.h:1 +#, fuzzy +msgid "Bridge Width" +msgstr "Bredde:" + +#: ../share/extensions/ffmet.inx.h:2 ../share/extensions/ffms.inx.h:2 +msgid "First String Length" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:3 +msgid "FretFind Multi Length ET" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:4 ../share/extensions/ffms.inx.h:4 +#: ../share/extensions/ffset.inx.h:3 ../share/extensions/ffss.inx.h:3 +msgid "Fretboard Edges" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:5 ../share/extensions/ffms.inx.h:5 +msgid "Last String Length" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:6 ../share/extensions/ffms.inx.h:6 +#: ../share/extensions/ffset.inx.h:4 ../share/extensions/ffss.inx.h:4 +msgid "Number of Frets" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:7 ../share/extensions/ffms.inx.h:7 +#: ../share/extensions/ffset.inx.h:5 ../share/extensions/ffss.inx.h:5 +msgid "Number of Strings" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:8 ../share/extensions/ffms.inx.h:8 +#: ../share/extensions/ffset.inx.h:6 ../share/extensions/ffss.inx.h:6 +#, fuzzy +msgid "Nut Width" +msgstr "Bredde:" + +#: ../share/extensions/ffmet.inx.h:9 ../share/extensions/ffms.inx.h:10 +msgid "Perpendicular Distance" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:10 ../share/extensions/ffset.inx.h:7 +msgid "Scale Base (2 for Octave)" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:11 ../share/extensions/ffset.inx.h:9 +msgid "Tones in Scale" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:12 ../share/extensions/ffms.inx.h:12 +#: ../share/extensions/ffset.inx.h:10 ../share/extensions/ffss.inx.h:10 +msgid "px per Unit" +msgstr "" + +#: ../share/extensions/ffms.inx.h:3 +msgid "FretFind Multi Length Scala" +msgstr "" + +#: ../share/extensions/ffms.inx.h:9 ../share/extensions/ffss.inx.h:7 +msgid "Path to Scala *.scl File" +msgstr "" + +#: ../share/extensions/ffms.inx.h:11 +msgid "Tuning (scale step for each string seperated by semicolons)" +msgstr "" + +#: ../share/extensions/ffset.inx.h:2 +msgid "FretFind Single Length ET" +msgstr "" + +#: ../share/extensions/ffset.inx.h:8 ../share/extensions/ffss.inx.h:8 +msgid "Scale Length" +msgstr "" + +#: ../share/extensions/ffss.inx.h:2 +msgid "FretFind Single Length Scala" +msgstr "" + +#: ../share/extensions/ffss.inx.h:9 +msgid "Tuning (Scale step for each string seperated by semicolons)" +msgstr "" + +#: ../share/extensions/handles.inx.h:1 +msgid "Draw Handles" +msgstr "" + +#: ../share/extensions/interp.inx.h:1 +#, fuzzy +msgid "Duplicate Endpaths" +msgstr "Duplisert node" + +#: ../share/extensions/interp.inx.h:2 +#, fuzzy +msgid "Exponent" +msgstr "Eksporter" + +#: ../share/extensions/interp.inx.h:3 +msgid "Interpolate" +msgstr "" + +#: ../share/extensions/interp.inx.h:4 +msgid "Interpolate Style (Experimental)" +msgstr "" + +#: ../share/extensions/interp.inx.h:5 +msgid "Interpolation Method" +msgstr "" + +#: ../share/extensions/interp.inx.h:6 +msgid "Interpolation Steps" +msgstr "" + +#: ../share/extensions/kochify.inx.h:1 +msgid "Kochify" +msgstr "" + +#: ../share/extensions/kochify_load.inx.h:1 +msgid "Kochify (Load)" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:1 +msgid "Angle" +msgstr "Vinkel" + +#: ../share/extensions/lindenmayer.inx.h:2 +msgid "Axiom" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:3 +#, fuzzy +msgid "Lindenmayer" +msgstr "Hev node" + +#: ../share/extensions/lindenmayer.inx.h:4 +msgid "Order" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:5 +#, fuzzy +msgid "Rules" +msgstr "Fil" + +#: ../share/extensions/lindenmayer.inx.h:6 +#, fuzzy +msgid "Step" +msgstr "Stil" + +#: ../share/extensions/motion.inx.h:1 +#, fuzzy +msgid "Direction" +msgstr "Valg" + +#: ../share/extensions/motion.inx.h:2 +#, fuzzy +msgid "Magnitude" +msgstr "Magenta:" + +#: ../share/extensions/motion.inx.h:3 +#, fuzzy +msgid "Motion" +msgstr "Vending:" + +#: ../share/extensions/pdf_output.inx.h:1 +msgid "Adobe PDF (*.pdf)" +msgstr "" + +#: ../share/extensions/pdf_output.inx.h:2 +msgid "Adobe Portable Document Format" +msgstr "" + +#: ../share/extensions/pdf_output.inx.h:3 +#, fuzzy +msgid "PDF Output" +msgstr "Klipp ut" + +#: ../share/extensions/ps_input.inx.h:1 +#, fuzzy +msgid "Postscript" +msgstr "Punkt" + +#: ../share/extensions/ps_input.inx.h:2 +msgid "Postscript (*.ps)" +msgstr "" + +#: ../share/extensions/ps_input.inx.h:3 +msgid "Postscript Input" +msgstr "" + +#: ../share/extensions/radiusrand.inx.h:1 +#, fuzzy +msgid "Radius" +msgstr "Radius:" + +#: ../share/extensions/radiusrand.inx.h:2 +#, fuzzy +msgid "Radius Randomize" +msgstr "Hev node" + +#: ../share/extensions/radiusrand.inx.h:3 +msgid "Randomize Control Points" +msgstr "" + +#: ../share/extensions/radiusrand.inx.h:4 +#, fuzzy +msgid "Randomize Nodes" +msgstr "Hev node" + +#: ../share/extensions/rtree.inx.h:1 +#, fuzzy +msgid "Initial Size" +msgstr "Størrelse pÃ¥ bitkart" + +#: ../share/extensions/rtree.inx.h:2 +msgid "Minimum Size" +msgstr "" + +#: ../share/extensions/rtree.inx.h:3 +msgid "Random Tree" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:1 +msgid "A diagram created with the program Sketch" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:2 +msgid "Sketch Diagram (*.sk)" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:3 +msgid "Sketch Input" +msgstr "" + +#: ../share/extensions/straightseg.inx.h:1 +msgid "Behavior" +msgstr "" + +#: ../share/extensions/straightseg.inx.h:3 +msgid "Segment Straightener" +msgstr "" + +#: ../share/extensions/summersnight.inx.h:1 +msgid "Summer's Night" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:1 +#: ../share/extensions/svgz_output.inx.h:1 +msgid "Compressed Inkscape SVG (*.svgz)" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:2 +#: ../share/extensions/svgz_output.inx.h:2 +msgid "Inkscape's native file format compressed with GZip" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:3 +#, fuzzy +msgid "SVGZ Input" +msgstr "Inndata" + +#: ../share/extensions/svgz_output.inx.h:3 +#, fuzzy +msgid "SVGZ Output" +msgstr "Klipp ut" + +#: ../share/extensions/txt2svg.inx.h:1 +msgid "ASCII Text" +msgstr "" + +#: ../share/extensions/txt2svg.inx.h:2 +msgid "Text File (*.txt)" +msgstr "" + +#: ../share/extensions/txt2svg.inx.h:3 +#, fuzzy +msgid "Text Input" +msgstr "Inndata" + +#: ../share/extensions/wavy.inx.h:1 +msgid "Calculate first derivative numerically" +msgstr "" + +#: ../share/extensions/wavy.inx.h:2 +msgid "First derivative" +msgstr "" + +#: ../share/extensions/wavy.inx.h:3 +msgid "Function" +msgstr "" + +#: ../share/extensions/wavy.inx.h:4 +msgid "Function Plotter" +msgstr "" + +#: ../share/extensions/wavy.inx.h:5 +msgid "Nodes per period" +msgstr "" + +#: ../share/extensions/wavy.inx.h:6 +msgid "Periods (2*Pi each)" +msgstr "" + +#: ../share/extensions/whirl.inx.h:1 +msgid "Amount of Whirl" +msgstr "" + +#: ../share/extensions/whirl.inx.h:2 +#, fuzzy +msgid "Center X" +msgstr "Senter X:" + +#: ../share/extensions/whirl.inx.h:3 +#, fuzzy +msgid "Center Y" +msgstr "Senter Y:" + +#: ../share/extensions/whirl.inx.h:4 +#, fuzzy +msgid "Direction of Rotation" +msgstr "Senk valgte objekter til bunnen" + +#: ../share/extensions/whirl.inx.h:5 +msgid "Whirl" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:1 +msgid "A popular graphics file format for clipart" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:2 +msgid "Windows Metafile (*.wmf)" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:3 +msgid "Windows Metafile Input" +msgstr "" + +#, fuzzy +#~ msgid "Canvas size:" +#~ msgstr "Skriftstørrelse" + +#, fuzzy +#~ msgid "Custom canvas" +#~ msgstr "Egendefinert papir" + +#, fuzzy +#~ msgid "Current style" +#~ msgstr "Innstillinger for strøk" + +#, fuzzy +#~ msgid "Arrange Objects" +#~ msgstr "Juster objekter" + +#~ msgid "deg" +#~ msgstr "grad" + +#, fuzzy +#~ msgid "_Credits" +#~ msgstr "Hjørner:" + +#, fuzzy +#~ msgid "Grab sensitivity" +#~ msgstr "Gjør sensitiv" + +#, fuzzy +#~ msgid "Acceleration" +#~ msgstr "Valg" + +#, fuzzy +#~ msgid "Speed" +#~ msgstr "Rød:" + +#, fuzzy +#~ msgid "Zoom in/out by" +#~ msgstr "Zoom ut i tegning" + +#, fuzzy +#~ msgid "Transform" +#~ msgstr "Transformer:" + +#, fuzzy +#~ msgid "Rotate _90 deg CW" +#~ msgstr "Roter objekt 90° med klokken" + +#, fuzzy +#~ msgid "Rotate 9_0 deg CCW" +#~ msgstr "Roter objekt 90° med klokken" + +#, fuzzy +#~ msgid "Flip selection horizontally" +#~ msgstr "Vend valgte objekter horisontalt" + +#, fuzzy +#~ msgid "Flip selection vertically" +#~ msgstr "Vend valgte objekter vertikalt" + +#~ msgid "Edit" +#~ msgstr "Rediger" + +#~ msgid "Add" +#~ msgstr "Legg til" + +#, fuzzy +#~ msgid "C_reate" +#~ msgstr "Opprett" + +#, fuzzy +#~ msgid "Automatically scale Rows to fit selected objects." +#~ msgstr "Slett valgte objekter" + +#, fuzzy +#~ msgid "Go to root" +#~ msgstr "Rediger" + +#, fuzzy +#~ msgid "X" +#~ msgstr "X:" + +#, fuzzy +#~ msgid "Y" +#~ msgstr "Y:" + +#~ msgid "Sides:" +#~ msgstr "Sider:" + +#~ msgid "R1:" +#~ msgstr "R1:" + +#~ msgid "R2:" +#~ msgstr "R2:" + +#~ msgid "ARG1:" +#~ msgstr "ARG1:" + +#~ msgid "ARG2:" +#~ msgstr "ARG2:" + +#, fuzzy +#~ msgid "Flatsides:" +#~ msgstr "Sider:" + +#, fuzzy +#~ msgid "Radius X:" +#~ msgstr "Radius:" + +#, fuzzy +#~ msgid "Radius Y:" +#~ msgstr "Radius:" + +#, fuzzy +#~ msgid "Start Angle:" +#~ msgstr "Stjerne" + +#, fuzzy +#~ msgid "End Angle:" +#~ msgstr "Vinkel:" + +#, fuzzy +#~ msgid "Open:" +#~ msgstr "Åpne" + +#~ msgid "Expansion:" +#~ msgstr "Utvidelse:" + +#, fuzzy +#~ msgid "Revolutions:" +#~ msgstr "Vending:" + +#~ msgid "Argument:" +#~ msgstr "Argument:" + +#~ msgid "T0:" +#~ msgstr "TIL:" + +#~ msgid "RX:" +#~ msgstr "RX:" + +#~ msgid "RY:" +#~ msgstr "RY:" + +#, fuzzy +#~ msgid "Rectangle _Properties" +#~ msgstr "Egenskaper for rektangel" + +#, fuzzy +#~ msgid "Star _Properties" +#~ msgstr "Egenskaper for stjerne" + +#, fuzzy +#~ msgid "Ellipse _Properties" +#~ msgstr "Egenskaper for lenke" + +#, fuzzy +#~ msgid "Spiral _Properties" +#~ msgstr "Egenskaper for spiral" + +#, fuzzy +#~ msgid "Document Preferences" +#~ msgstr "Oppføring er referanse" + +#, fuzzy +#~ msgid "Extensions Editor" +#~ msgstr "Utvidelse" + +#, fuzzy +#~ msgid "Preferences" +#~ msgstr "Oppføring er referanse" + +#, fuzzy +#~ msgid "Layer Editor" +#~ msgstr "XML-redigering" + +#, fuzzy +#~ msgid "Text Properties" +#~ msgstr "Egenskaper for tekst" + +#, fuzzy +#~ msgid "Transformation" +#~ msgstr "Transformasjonsmatrise" + +#, fuzzy +#~ msgid "_Export..." +#~ msgstr "Importer" + +#, fuzzy +#~ msgid "_Document Properties" +#~ msgstr "Innstillinger for dokument" + +#, fuzzy +#~ msgid "In_kscape Preferences" +#~ msgstr "Sodipodi: %s: XML-visning" + +#, fuzzy +#~ msgid "Select _Original Clone" +#~ msgstr "Velg" + +#, fuzzy +#~ msgid "Tile" +#~ msgstr "Tittel:" + +#, fuzzy +#~ msgid "Select A_ll" +#~ msgstr "Velg" + +#, fuzzy +#~ msgid "Select Non_e" +#~ msgstr "Valg" + +#, fuzzy +#~ msgid "Zoom _In" +#~ msgstr "Zoom" + +#, fuzzy +#~ msgid "Zoom _Out" +#~ msgstr "Zoom ut i tegning" + +#, fuzzy +#~ msgid "Pre_vious" +#~ msgstr "Ny visning" + +#, fuzzy +#~ msgid "Nex_t" +#~ msgstr "Tekst" + +#, fuzzy +#~ msgid "Tool Co_ntrols bar" +#~ msgstr "Alternativer for verktøy" + +#, fuzzy +#~ msgid "R_ename Layer..." +#~ msgstr "Hev node" + +#, fuzzy +#~ msgid "D_uplicate Layer" +#~ msgstr "Duplisert node" + +#, fuzzy +#~ msgid "_Anchor Layer" +#~ msgstr "Senk node" + +#, fuzzy +#~ msgid "_Delete Layer" +#~ msgstr "Velg" + +#, fuzzy +#~ msgid "Select Ne_xt Layer" +#~ msgstr "Velg" + +#, fuzzy +#~ msgid "Select Pre_vious Layer" +#~ msgstr "Velg skriver" + +#, fuzzy +#~ msgid "Select To_p Layer" +#~ msgstr "Velg skriver" + +#, fuzzy +#~ msgid "Move to Ne_w Layer" +#~ msgstr "Opprett nytt SVG-dokument" + +#, fuzzy +#~ msgid "Move to B_ottom Layer" +#~ msgstr "Senk valgte objekter til bunnen" + +#, fuzzy +#~ msgid "_Trace Bitmap..." +#~ msgstr "Eksporter bitkart" + +#, fuzzy +#~ msgid "_Put Text on Path" +#~ msgstr "Senk valgte objekter til bunnen" + +#, fuzzy +#~ msgid "_Remove Text from Path" +#~ msgstr "Senk valgte objekter til bunnen" + +#~ msgid "Arc" +#~ msgstr "Bue" + +#, fuzzy +#~ msgid "Freehand" +#~ msgstr "FrihÃ¥nd og penn" + +#, fuzzy +#~ msgid "DynaDraw" +#~ msgstr "Tegn" + +#, fuzzy +#~ msgid "Corners" +#~ msgstr "Hjørner:" + +#, fuzzy +#~ msgid "Delete" +#~ msgstr "Slett" + +#, fuzzy +#~ msgid "Join" +#~ msgstr "SlÃ¥ sammen:" + +#, fuzzy +#~ msgid "Delete Segment" +#~ msgstr "Slett valgte noder" + +#, fuzzy +#~ msgid "Break" +#~ msgstr "Sort:" + +#, fuzzy +#~ msgid "New" +#~ msgstr "Ny" + +#, fuzzy +#~ msgid "Revert to Saved" +#~ msgstr "Konverter objekt til kurve" + +#, fuzzy +#~ msgid "Save" +#~ msgstr "Lagre" + +#, fuzzy +#~ msgid "Save As..." +#~ msgstr "Lagre som" + +#, fuzzy +#~ msgid "Import..." +#~ msgstr "Importer" + +#, fuzzy +#~ msgid "Export..." +#~ msgstr "Eksporter" + +#, fuzzy +#~ msgid "Print..." +#~ msgstr "Skriv ut" + +#, fuzzy +#~ msgid "Global Inkscape preferences (Shift+Ctrl+P)" +#~ msgstr "Skjerminstillinger" + +#, fuzzy +#~ msgid "Undo" +#~ msgstr "Angre" + +#, fuzzy +#~ msgid "Redo" +#~ msgstr "Gjenopprett" + +#, fuzzy +#~ msgid "Cut" +#~ msgstr "Klipp ut" + +#, fuzzy +#~ msgid "Copy" +#~ msgstr "Kopier" + +#, fuzzy +#~ msgid "Duplicate selected object(s) (Ctrl+D)" +#~ msgstr "Dupliser valgte objekter" + +#, fuzzy +#~ msgid "Clone selected object (Alt+D)" +#~ msgstr "Dupliser valgte objekter" + +#, fuzzy +#~ msgid "Zoom in (+)" +#~ msgstr "Zoom" + +#, fuzzy +#~ msgid "Zoom out (-)" +#~ msgstr "Zoom ut i tegning" + +#, fuzzy +#~ msgid "Zoom to 1:1 (100%) (1)" +#~ msgstr "Sett zoom-faktor til 1:1" + +#, fuzzy +#~ msgid "Zoom to 1:2 (50%) (2)" +#~ msgstr "Sett zoom-faktor til 1:2" + +#, fuzzy +#~ msgid "Zoom to 2:1 (200%) (0)" +#~ msgstr "Sett zoom-faktor til 2:1" + +#, fuzzy +#~ msgid "Zoom to fit selection in window (3)" +#~ msgstr "Redigeringsvindu" + +#, fuzzy +#~ msgid "Zoom to fit drawing in window (4)" +#~ msgstr "Redigeringsvindu" + +#, fuzzy +#~ msgid "Zoom to fit page in window (5)" +#~ msgstr "Redigeringsvindu" + +#, fuzzy +#~ msgid "Zoom to fit page width in window (6)" +#~ msgstr "Redigeringsvindu" + +#, fuzzy +#~ msgid "Fill and Stroke dialog (Shift+Ctrl+F)" +#~ msgstr "Fyll og strøk" + +#, fuzzy +#~ msgid "Group selected objects (Ctrl+G)" +#~ msgstr "Grupper valgte objekter" + +#, fuzzy +#~ msgid "Ungroup selected group(s) (Ctrl+U)" +#~ msgstr "Del opp valgt gruppe" + +#, fuzzy +#~ msgid "Raise selection up one step (PgUp)" +#~ msgstr "Hev valgte objekter til toppen" + +#, fuzzy +#~ msgid "Lower selection down one step (PgDn)" +#~ msgstr "Senk valgte objekter ett nivÃ¥" + +#, fuzzy +#~ msgid "Raise selection to top (Home)" +#~ msgstr "Hev valgte objekter til toppen" + +#, fuzzy +#~ msgid "Lower selection to bottom (End)" +#~ msgstr "Senk valgte objekter til bunnen" + +#, fuzzy +#~ msgid "Move selection to new layer" +#~ msgstr "Senk valgte objekter ett nivÃ¥" + +#, fuzzy +#~ msgid "Move selection to next layer" +#~ msgstr "Senk valgte objekter ett nivÃ¥" + +#, fuzzy +#~ msgid "Move selection to previous layer" +#~ msgstr "Kopier valgte objekter til utklippstavlen" + +#, fuzzy +#~ msgid "Move selection to top layer" +#~ msgstr "Hev valgte objekter til toppen" + +#, fuzzy +#~ msgid "Move selection to bottom layer" +#~ msgstr "Senk valgte objekter til bunnen" + +#, fuzzy +#~ msgid "Rotate selection 90° clockwise (Shift+Ctrl+Right)" +#~ msgstr "Roter objekt 90° med klokken" + +#, fuzzy +#~ msgid "Rotate selection 90° counter-clockwise (Shift+Ctrl+Left)" +#~ msgstr "Roter objekt 90° med klokken" + +#, fuzzy +#~ msgid "Flip selection horizontally (H)" +#~ msgstr "Vend valgte objekter horisontalt" + +#, fuzzy +#~ msgid "Flip selection vertically (V)" +#~ msgstr "Vend valgte objekter vertikalt" + +#, fuzzy +#~ msgid "Align and Distribute dialog (Shift+Ctrl+A)" +#~ msgstr "Distribuer" + +#, fuzzy +#~ msgid "Convert selected object(s) to path(s) (Shift+Ctrl+C)" +#~ msgstr "Senk valgte objekter til bunnen" + +#, fuzzy +#~ msgid "Convert selected stroke(s) to path(s) (Ctrl+Alt+C)" +#~ msgstr "Senk valgte objekter til bunnen" + +#, fuzzy +#~ msgid "Cl_eanup" +#~ msgstr "Rydd opp" + +#, fuzzy +#~ msgid "Text and Font dialog (Shift+Ctrl+T)" +#~ msgstr "Tekst og skrift" + +#, fuzzy +#~ msgid "Node tool" +#~ msgstr "Ingen aktive verktøy" + +#, fuzzy +#~ msgid "Zoom tool" +#~ msgstr "Zoom ut i tegning" + +#~ msgid "Rectangle tool" +#~ msgstr "Rektangelverktøy" + +#~ msgid "Arc tool" +#~ msgstr "Bueverktøy" + +#~ msgid "Star tool" +#~ msgstr "Stjerneverktøy" + +#~ msgid "Spiral tool" +#~ msgstr "Spiralverktøy" + +#, fuzzy +#~ msgid "Freehand tool" +#~ msgstr "FrihÃ¥nd og penn" + +#, fuzzy +#~ msgid "Pen tool" +#~ msgstr "Rektangelverktøy" + +#, fuzzy +#~ msgid "Calligraphy tool" +#~ msgstr "Kalligrafisk linje" + +#, fuzzy +#~ msgid "Text tool" +#~ msgstr "Stjerneverktøy" + +#, fuzzy +#~ msgid "Dropper tool" +#~ msgstr "Spiralverktøy" + +#, fuzzy +#~ msgid "Delete segment between two nodes" +#~ msgstr "Slett valgte noder" + +#, fuzzy +#~ msgid "URI:" +#~ msgstr "URL:" + +#, fuzzy +#~ msgid "Select All in All Layers" +#~ msgstr "Velg" + +#, fuzzy +#~ msgid "Invert Selection" +#~ msgstr "Valg" + +#, fuzzy +#~ msgid "Clean up selected path(s)" +#~ msgstr "Senk valgte objekter til bunnen" + +#, fuzzy +#~ msgid "_Scripts..." +#~ msgstr "Skriv ut" + +#, fuzzy +#~ msgid "Align and Distribute" +#~ msgstr "Distribuer" + +#, fuzzy +#~ msgid "Align and Distribute Dialog" +#~ msgstr "Distribuer" + +#, fuzzy +#~ msgid "Export Dialog" +#~ msgstr "Eksporter omrÃ¥de" + +#, fuzzy +#~ msgid "Fill and Stroke Dialog" +#~ msgstr "Fyll og strøk" + +#, fuzzy +#~ msgid "Find Dialog" +#~ msgstr "Fyll og strøk" + +#, fuzzy +#~ msgid "Inkscape Preferences" +#~ msgstr "Sodipodi: %s: XML-visning" + +#, fuzzy +#~ msgid "Inkscape Preferences Dialog" +#~ msgstr "Sodipodi: %s: XML-visning" + +#, fuzzy +#~ msgid "Layer Editor Dialog" +#~ msgstr "Hev valgte objekter til toppen" + +#, fuzzy +#~ msgid "Text Properties Dialog" +#~ msgstr "Egenskaper for rektangel" + +#, fuzzy +#~ msgid "Transformation Dialog" +#~ msgstr "Transformasjoner" + +#, fuzzy +#~ msgid "Tree Editor" +#~ msgstr "XML-redigering" + +#, fuzzy +#~ msgid "XML Editor Dialog" +#~ msgstr "XML-redigering" + +#, fuzzy +#~ msgid "Row height:" +#~ msgstr "Høyde:" + +#, fuzzy +#~ msgid "Column width:" +#~ msgstr "Lukk" + +#, fuzzy +#~ msgid "EPS Output Settings" +#~ msgstr "Innstillinger for dokument" + +#, fuzzy +#~ msgid "Inkscape" +#~ msgstr "Sodipodi: %s: XML-visning" + +#~ msgid "Left side of aligned objects to left side of anchor" +#~ msgstr "Venstre side av linjestilte objekter til venstre side av anker" + +#~ msgid "Right side of aligned objects to right side of anchor" +#~ msgstr "Høyre side av linjestilte objekter til høyre side av anker" + +#, fuzzy +#~ msgid "Top of aligned objects to top of anchor" +#~ msgstr "Kopier linjestilte objekter til utklippstavlen" + +#~ msgid "Bottom of aligned objects to bottom of anchor" +#~ msgstr "Bunn av linjestilte objekter til bunn av anker" + +#~ msgid "Distribute top sides of objects at even distances" +#~ msgstr "Distribuer top sider av objekter med jevne mellomrom" + +#, fuzzy +#~ msgid "Alternate sign" +#~ msgstr "Metning:" + +#, fuzzy +#~ msgid "Minor grid line color:" +#~ msgstr "Farge pÃ¥ retningslinje" + +#~ msgid "Grid color" +#~ msgstr "Farge pÃ¥ rutenett" + +#, fuzzy +#~ msgid "Grid emphasis color" +#~ msgstr "Farge pÃ¥ rutenett" + +#, fuzzy +#~ msgid "Background (also for export):" +#~ msgstr "Sluttfarge" + +#, fuzzy +#~ msgid "Picking colors:" +#~ msgstr "Merk farge:" + +#~ msgid "Fill style" +#~ msgstr "Fyllstil" + +#, fuzzy +#~ msgid "Fill:" +#~ msgstr "Fyll" + +#, fuzzy +#~ msgid "winding" +#~ msgstr "Rendering" + +#, fuzzy +#~ msgid "alternating" +#~ msgstr "Metning:" + +#, fuzzy +#~ msgid "Update Properties" +#~ msgstr "Egenskaper for oppføring" + +#, fuzzy +#~ msgid "Label invalid" +#~ msgstr "IDen er gyldig" + +#, fuzzy +#~ msgid "executable" +#~ msgstr "Rektangel" + +#, fuzzy +#~ msgid "file" +#~ msgstr "Fil" + +#, fuzzy +#~ msgid "extension" +#~ msgstr "Utvidelse" + +#, fuzzy +#~ msgid "path" +#~ msgstr "pt" + +#, fuzzy +#~ msgid "absolute" +#~ msgstr "Verdi" + +#~ msgid "Could not create sodipodi-svg-doc factory" +#~ msgstr "Kunne ikke opprette sodipodi-svg-doc factory" + +#~ msgid "Plain SVG" +#~ msgstr "Vanlig SVG" + +#, fuzzy +#~ msgid "Make s_ensitive" +#~ msgstr "Gjør sensitiv" + +#, fuzzy +#~ msgid "Make i_nsensitive" +#~ msgstr "Gjør insensitiv" + +#, fuzzy +#~ msgid "Layer Properties" +#~ msgstr "Egenskaper for stjerne" + +#, fuzzy +#~ msgid "Select object(s) to tile." +#~ msgstr "Klipp ut valgte objekter til utklippstavlen" + +#, fuzzy +#~ msgid "Apply" +#~ msgstr "Bruk pÃ¥:" + +#~ msgid "Sensitive" +#~ msgstr "Sensitiv" + +#~ msgid "Active" +#~ msgstr "Aktiv" + +#~ msgid "Printable" +#~ msgstr "Utskrivbar" + +#~ msgid "Trace" +#~ msgstr "Spor" + +#, fuzzy +#~ msgid "Error writing %s: %s" +#~ msgstr "Feil ved skriving av %s: %s" + +#~ msgid "Untitled" +#~ msgstr "Uten navn" + +#~ msgid "Document Name:" +#~ msgstr "Dokumentnavn:" + +#~ msgid "Image URI:" +#~ msgstr "Bilde-URI:" + +#~ msgid "Visible" +#~ msgstr "Synlig" + +#, fuzzy +#~ msgid "Drag to paint a calligraphic stroke." +#~ msgstr "Kalligrafisk linje" + +#, fuzzy +#~ msgid "Flatness:" +#~ msgstr "Sider:" + +#, fuzzy +#~ msgid "Other" +#~ msgstr "Rekkefølge" + +#, fuzzy +#~ msgid "Trace: Selected object is not an image" +#~ msgstr "Hev valgte objekter ett nivÃ¥" + +#, fuzzy +#~ msgid "object" +#~ msgstr "Objekt" + +#, fuzzy +#~ msgid "user space" +#~ msgstr "BrukeromrÃ¥deenhet" + +#, fuzzy +#~ msgid "Coordinates:" +#~ msgstr "Hjørner:" + +#, fuzzy +#~ msgid "" +#~ "Distribute centers of objects of objects at even distances horizontally" +#~ msgstr "Fordel senter av objekter med jevne mellomrom" + +#~ msgid "Alignment:" +#~ msgstr "Justering:" + +#~ msgid "Text and font" +#~ msgstr "Tekst og skrift" + +#~ msgid "All shape tools" +#~ msgstr "Alle formverktøy" + +#, fuzzy +#~ msgid "Move by %s, %s" +#~ msgstr "Flytt" + +#, fuzzy +#~ msgid "Active group" +#~ msgstr "Aktiv" + +#, fuzzy +#~ msgid "typeset object" +#~ msgstr "Tekstobjekt" + +#, fuzzy +#~ msgid "Pattern Fill" +#~ msgstr "Mønster:" + +#~ msgid "Snap to grid" +#~ msgstr "Fest til rutenett" + +#~ msgid "Snap to guides" +#~ msgstr "Fest til guider" + +#, fuzzy +#~ msgid "_Menu" +#~ msgstr "Rydd opp" + +#, fuzzy +#~ msgid "Snap points to the grid" +#~ msgstr "Fest til rutenett" + +#, fuzzy +#~ msgid "Rect" +#~ msgstr "Rektangel" + +#~ msgid "meters" +#~ msgstr "meter" + +#~ msgid "Userspace unit" +#~ msgstr "BrukeromrÃ¥deenhet" + +#~ msgid "User" +#~ msgstr "Bruker" + +#~ msgid "Userspace units" +#~ msgstr "BrukeromrÃ¥deenheter" + +#, fuzzy +#~ msgid "Ru_lers" +#~ msgstr "Fil" + +#, fuzzy +#~ msgid "Show or hide rulers" +#~ msgstr "Vis rutenett" + +#~ msgid "Mode:" +#~ msgstr "Modus:" + +#~ msgid "Alpha:" +#~ msgstr "Alpha:" + +#~ msgid "Value:" +#~ msgstr "Verdi:" + +#~ msgid "Stroke settings" +#~ msgstr "Innstillinger for strøk" + +#~ msgid "Item properties" +#~ msgstr "Egenskaper for oppføring" + +#~ msgid "Combine multiple paths" +#~ msgstr "Kombiner flere stier" + +#, fuzzy +#~ msgid "New View" +#~ msgstr "Ny visning" + +#, fuzzy +#~ msgid "Fill and stroke settings" +#~ msgstr "Innstillinger for strøk" + +#~ msgid "Object transformations" +#~ msgstr "Objekt-transformasjon" + +#, fuzzy +#~ msgid "Text editing and font settings" +#~ msgstr "Innstillinger for tekst og skrift" + +#~ msgid "Fill Rule" +#~ msgstr "Fyllregel" + +#~ msgid "Tool has no options" +#~ msgstr "Verktøy har ingen alternativer" + +#~ msgid "Visual transformation" +#~ msgstr "Visuell transformasjon" + +#~ msgid "Show content" +#~ msgstr "Vis innhold" + +#, fuzzy +#~ msgid "Selected object has no curve, cannot outline." +#~ msgstr "Klipp ut valgte objekter til utklippstavlen" + +#, fuzzy +#~ msgid "Inkscape _Options" +#~ msgstr "Sodipodi: %s: XML-visning" + +#, fuzzy +#~ msgid "Tool Optio_ns" +#~ msgstr "Alternativer for verktøy" + +#~ msgid "gradientUnits" +#~ msgstr "gradientUnits" + +#~ msgid "gradientSpread" +#~ msgstr "gradientSpread" + +#~ msgid "nonzero" +#~ msgstr "ikke-null" + +#, fuzzy +#~ msgid "" +#~ "%s is not regular file.\n" +#~ "Although inkscape will run, you can\n" +#~ "neither load nor save preferences\n" +#~ msgstr "" +#~ "%s er ikke en vanlig fil.\n" +#~ "Selv om sodipodi vil kjøre vil du\n" +#~ "ikke kunne lagre eller laste brukervalg\n" + +#, fuzzy +#~ msgid "" +#~ "%s either is not valid xml file or\n" +#~ "you do not have read premissions on it.\n" +#~ "Although inkscape will run, you\n" +#~ "are neither able to load nor save\n" +#~ "preferences." +#~ msgstr "" +#~ "%s er enten ikke en gyldig xml-fil eller\n" +#~ "sÃ¥ har du ikke leserettigheter til den.\n" +#~ "Selv om sodipodi vil kjøre vil du\n" +#~ "ikke kunne laste eller lagre brukervalg" + +#, fuzzy +#~ msgid "" +#~ "%s is not valid inkscape preferences file.\n" +#~ "Although inkscape will run, you\n" +#~ "are neither able to load nor save\n" +#~ "preferences." +#~ msgstr "" +#~ "%s er ikke en gyldig sodipodi brukervalg-fil.\n" +#~ "Selv om sodipodi vil kjøre vil du\n" +#~ "ikke kunne laste eller lagre brukervalg." + +#, fuzzy +#~ msgid "" +#~ "Cannot create directory %s.\n" +#~ "Although inkscape will run, you\n" +#~ "are neither able to load nor save\n" +#~ "%s." +#~ msgstr "" +#~ "Kan ikke opprette katalog %s.\n" +#~ "Selv om sodipodi vil kjøre vil du\n" +#~ "ikke kunne laste eller lagre\n" +#~ "brukervalg." + +#, fuzzy +#~ msgid "" +#~ "%s is not a valid directory.\n" +#~ "Although inkscape will run, you\n" +#~ "are neither able to load nor save\n" +#~ "preferences." +#~ msgstr "" +#~ "%s er ikke en gyldig katalog.\n" +#~ "Selv om sodipodi vil kjøre vil du\n" +#~ "ikke kunne laste eller lagre\n" +#~ "brukervalg." + +#, fuzzy +#~ msgid "" +#~ "Cannot create file %s.\n" +#~ "Although inkscape will run, you\n" +#~ "are neither able to load nor save\n" +#~ "preferences." +#~ msgstr "" +#~ "Kan ikke opprette fil %s.\n" +#~ "Selv om sodipodi vil kjøre vil\n" +#~ "du ikke kunne laste eller lagre\n" +#~ "brukervalg." + +#, fuzzy +#~ msgid "" +#~ "Cannot write file %s.\n" +#~ "Although inkscape will run, you\n" +#~ "are neither able to load nor save\n" +#~ "preferences." +#~ msgstr "" +#~ "Kan ikke skrive til fil %s.\n" +#~ "Selv om sodipodi vil kjøre vil\n" +#~ "du ikke kunne laste eller lagre\n" +#~ "brukervalg." + +#~ msgid "Make sides flat" +#~ msgstr "Gjør sidene flate" + +#, fuzzy +#~ msgid "Bring to _Front" +#~ msgstr "Hent frem" + +#, fuzzy +#~ msgid "Send to _Back" +#~ msgstr "Send til bakgrunn" + +#~ msgid "Document %s has unsaved changes, save them?" +#~ msgstr "Dokument %s har ikke-lagrede endringer, lagre dem?" + +#, fuzzy +#~ msgid "Object Size and Position" +#~ msgstr "Objektstørrelse og posisjon" + +#~ msgid "Size and Position" +#~ msgstr " Størrelse og posisjon" + +#~ msgid "Tool attributes" +#~ msgstr "Verktøyattributter" + +#~ msgid "Inner radius" +#~ msgstr "Indre radius" + +#~ msgid "Proportion" +#~ msgstr "Proporsjon" + +#~ msgid "Tool has no attributes" +#~ msgstr "Verktøy har ingen attributter" + +#~ msgid "Item" +#~ msgstr "Oppføring" + +#~ msgid "Group Properties" +#~ msgstr "Egenskaper for gruppe" + +#~ msgid "Fill settings" +#~ msgstr "Innstillinger for fyll" + +#, fuzzy +#~ msgid "Lower selected objects one position" +#~ msgstr "Senk valgte objekter til bunnen" + +#, fuzzy +#~ msgid "In" +#~ msgstr "Tomme" + +#, fuzzy +#~ msgid "Toggle grid" +#~ msgstr "Vis rutenett" + +#, fuzzy +#~ msgid "Toggle guides" +#~ msgstr "Vis rutenett" + +#~ msgid "1:1" +#~ msgstr "1:1" + +#~ msgid "1:2" +#~ msgstr "1:2" + +#~ msgid "2:1" +#~ msgstr "2:1" + +#~ msgid "Editing Window" +#~ msgstr "Redigeringsvindu" + +#, fuzzy +#~ msgid "Editing window properties" +#~ msgstr "Redigeringsvindu" + +#~ msgid "Tool Attributes" +#~ msgstr "Verktøyattributter" + +#~ msgid "Sodipodi" +#~ msgstr "Sodipodi" + +#~ msgid "Desktop settings" +#~ msgstr "Innstillinger for skrivebord" + +#, fuzzy +#~ msgid "Iso grid" +#~ msgstr "Vis rutenett" + +#~ msgid "Display settings" +#~ msgstr "Skjerminstillinger" + +#~ msgid "Export png file" +#~ msgstr "Eksporter png-fil" + +#~ msgid "Object style" +#~ msgstr "Objektstil" + +#, fuzzy +#~ msgid "Inkscape: %s : XML View" +#~ msgstr "Sodipodi: %s: XML-visning" + +#, fuzzy +#~ msgid "Appending to selection. Press 'a' to toggle Append/New." +#~ msgstr "Legger til i utvalg. Trykk «+» for Ã¥ velge mellom Legg til/Ny." + +#~ msgid "Exit Program" +#~ msgstr "Avslutt programmet" + +#~ msgid "Drawing Mode" +#~ msgstr "Tegnemodus" + +#, fuzzy +#~ msgid "" +#~ "%s is not regular file.\n" +#~ "Although inkscape will run, you are\n" +#~ "not able to use extensions (plugins)\n" +#~ msgstr "" +#~ "%s er ikke en vanlig fil.\n" +#~ "Selv om sodipodi vil kjøre vil du\n" +#~ "ikke kunne lagre eller laste brukervalg\n" + +#, fuzzy +#~ msgid "" +#~ "%s either is not valid xml file or\n" +#~ "you do not have read premissions on it.\n" +#~ "Although inkscape will run, you are\n" +#~ "not able to use extensions (plugins)\n" +#~ msgstr "" +#~ "%s er enten ikke en gyldig xml-fil eller\n" +#~ "sÃ¥ har du ikke leserettigheter til den.\n" +#~ "Selv om sodipodi vil kjøre vil du\n" +#~ "ikke kunne laste eller lagre brukervalg" + +#, fuzzy +#~ msgid "" +#~ "%s is not valid inkscape extensions file.\n" +#~ "Although inkscape will run, you are\n" +#~ "not able to use extensions (plugins)\n" +#~ msgstr "" +#~ "%s er ikke en gyldig sodipodi brukervalg-fil.\n" +#~ "Selv om sodipodi vil kjøre vil du\n" +#~ "ikke kunne laste eller lagre brukervalg." + +#, fuzzy +#~ msgid "" +#~ "Cannot create directory %s.\n" +#~ "Although inkscape will run, you are\n" +#~ "not able to use extensions (plugins)\n" +#~ msgstr "" +#~ "Kan ikke opprette katalog %s.\n" +#~ "Selv om sodipodi vil kjøre vil du\n" +#~ "ikke kunne laste eller lagre\n" +#~ "brukervalg." + +#, fuzzy +#~ msgid "" +#~ "%s is not a valid directory.\n" +#~ "Although inkscape will run, you are\n" +#~ "not able to use extensions (plugins)\n" +#~ msgstr "" +#~ "%s er ikke en gyldig katalog.\n" +#~ "Selv om sodipodi vil kjøre vil du\n" +#~ "ikke kunne laste eller lagre\n" +#~ "brukervalg." + +#, fuzzy +#~ msgid "" +#~ "Cannot create file %s.\n" +#~ "Although inkscape will run, you are\n" +#~ "not able to use extensions (plugins)\n" +#~ msgstr "" +#~ "Kan ikke opprette fil %s.\n" +#~ "Selv om sodipodi vil kjøre vil\n" +#~ "du ikke kunne laste eller lagre\n" +#~ "brukervalg." + +#, fuzzy +#~ msgid "" +#~ "Cannot write file %s.\n" +#~ "Although inkscape will run, you are\n" +#~ "not able to use extensions (plugins)\n" +#~ msgstr "" +#~ "Kan ikke skrive til fil %s.\n" +#~ "Selv om sodipodi vil kjøre vil\n" +#~ "du ikke kunne laste eller lagre\n" +#~ "brukervalg." + +#~ msgid "Unknown item :-(" +#~ msgstr "Ukjent oppføring :-(" + +#~ msgid "Text and font settings" +#~ msgstr "Innstillinger for tekst og skrift" + +#~ msgid "Zoom in drawing" +#~ msgstr "Zoom i tegning" + +#~ msgid "Document" +#~ msgstr "Dokument" + +#, fuzzy +#~ msgid "Document variant:" +#~ msgstr "Dokumentnavn:" + +#, fuzzy +#~ msgid "Save document as" +#~ msgstr "Lagre dokument" + +#~ msgid "About sodipodi" +#~ msgstr "Om Sodipodi" + +#~ msgid "About Sodipodi" +#~ msgstr "Om Sodipodi" + +#~ msgid "The SVG ID of item" +#~ msgstr "SVG ID for oppføringen" + +#~ msgid "The ID is not valid" +#~ msgstr "IDen er ikke gyldig" + +#~ msgid "The ID is already defined" +#~ msgstr "IDen er allerede definert" + +#~ msgid "Object position and size" +#~ msgstr "Posisjon og størrelse for objekt" + +#~ msgid "Position and size" +#~ msgstr "Posisjon og størrelse" + +#~ msgid "Dynahand" +#~ msgstr "Dynahand" + +#~ msgid "Text Editing" +#~ msgstr "Tekstredigering" + +#~ msgid "Display Properties" +#~ msgstr "Egenskaper for visning" + +#~ msgid "Node tool - modify different aspects of existing objects" +#~ msgstr "Nodeverktøy - endre forskjellige aspekter ved eksisterende objekter" + +#~ msgid "Save as:" +#~ msgstr "Lagre som:" + +#~ msgid "A path - whatever it means" +#~ msgstr "En sti - hva nÃ¥ enn det betyr" diff --git a/po/nl.po b/po/nl.po new file mode 100644 index 000000000..7d8ce1801 --- /dev/null +++ b/po/nl.po @@ -0,0 +1,9647 @@ +# Dutch translation of Inkscape. +# Copyright (C) 2003 THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# Vincent van Adrighem , 2003. +# Jeroen van der Vegt , 2003, 2005. +# +msgid "" +msgstr "" +"Project-Id-Version: Inkscape cvs\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2005-12-04 11:51-0800\n" +"PO-Revision-Date: 2005-11-07 22:42+0100\n" +"Last-Translator: Jeroen van der Vegt \n" +"Language-Team: Dutch \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../inkscape.desktop.in.h:1 +msgid "Create and edit Scalable Vector Graphics images" +msgstr "'Scalable Vector Graphics (SVG) '-tekeningen maken en bewerken" + +#: ../inkscape.desktop.in.h:2 +msgid "Inkscape SVG Vector Illustrator" +msgstr "Inkscape SVG vector illustrator" + +#: ../../po/../src/arc-context.cpp:350 +msgid "" +"Ctrl: make circle or integer-ratio ellipse, snap arc/segment angle" +msgstr "" +"Ctrl: maak een cirkel of een 'gehele verhouding'-ellips; draai de " +"hoek van de taartpunt/arc in stappen" + +#: ../../po/../src/arc-context.cpp:351 ../../po/../src/rect-context.cpp:388 +msgid "Shift: draw around the starting point" +msgstr "Shift: teken rondom het beginpunt" + +#: ../../po/../src/arc-context.cpp:413 +#: ../../po/../src/connector-context.cpp:493 +#: ../../po/../src/dyna-draw-context.cpp:506 +#: ../../po/../src/pen-context.cpp:329 ../../po/../src/pencil-context.cpp:208 +#: ../../po/../src/rect-context.cpp:452 ../../po/../src/spiral-context.cpp:421 +#: ../../po/../src/star-context.cpp:427 +msgid "Current layer is hidden. Unhide it to be able to draw on it." +msgstr "" +"De huidige laag is verborgen. Toon hem om er op te kunnen tekenen." + +#: ../../po/../src/arc-context.cpp:417 +#: ../../po/../src/connector-context.cpp:497 +#: ../../po/../src/dyna-draw-context.cpp:510 +#: ../../po/../src/pen-context.cpp:336 ../../po/../src/pencil-context.cpp:212 +#: ../../po/../src/rect-context.cpp:456 ../../po/../src/spiral-context.cpp:426 +#: ../../po/../src/star-context.cpp:431 +msgid "Current layer is locked. Unlock it to be able to draw on it." +msgstr "" +"De huidige laag is vergrendeld. Ontgrendel hem om er op te kunnen " +"tekenen." + +#: ../../po/../src/arc-context.cpp:496 +#, c-format +msgid "" +"Ellipse: %s × %s; with Ctrl to make circle or integer-" +"ratio ellipse; with Shift to draw around the starting point" +msgstr "" +"Ellips: %s × %s; druk Ctrl in om een cirkel of een " +"'gehele-verhouding' ellips te maken; druk Shift in om rondom het " +"beginpunt te tekenen" + +#: ../../po/../src/connector-context.cpp:518 +msgid "Creating new connector" +msgstr "Nieuwe verbinder" + +#: ../../po/../src/connector-context.cpp:939 +msgid "Finishing connector" +msgstr "Klaar met verbinder" + +#: ../../po/../src/connector-context.cpp:1108 +#, fuzzy +msgid "Connection point: click or drag to create a new connector" +msgstr "" +"Verbindingspunt: klik of sleep om een nieuwe verbinding te maken" + +#: ../../po/../src/connector-context.cpp:1185 +#, fuzzy +msgid "Connector endpoint: drag to reroute or connect to new shapes" +msgstr "" +"Verbindings eindpunt: sleep om verbinding te wijzigen of om nieuwe " +"vormen te verbinden." + +#: ../../po/../src/connector-context.cpp:1278 +msgid "Select at least one non-connector object." +msgstr "Selecteer tenminste één object dat geen verbindingsobject is." + +#: ../../po/../src/desktop-events.cpp:238 +#, c-format +msgid "%s at %s" +msgstr "%s op %s" + +#. TRANSLATORS: This string appears when double-clicking on a guide. +#. This is the distance by which the guide is to be moved. +#: ../../po/../src/desktop-events.cpp:277 +msgid " relative by " +msgstr " relatief met " + +#. TRANSLATORS: This string appears when double-clicking on a guide. +#. This is the target location where the guide is to be moved. +#: ../../po/../src/desktop-events.cpp:282 +#: ../../po/../src/desktop-events.cpp:395 +msgid " absolute to " +msgstr "absoluut ten opzichte van" + +#. create dialog +#: ../../po/../src/desktop-events.cpp:348 +msgid "Guideline" +msgstr "Hulplijn" + +#: ../../po/../src/desktop-events.cpp:432 +#, c-format +msgid "Move %s" +msgstr "%s verplaatsen" + +#: ../../po/../src/desktop.cpp:678 +msgid "No previous zoom." +msgstr "Geen vorige zoom niveau." + +#: ../../po/../src/desktop.cpp:703 +msgid "No next zoom." +msgstr "Geen volgend zoom niveau." + +#: ../../po/../src/dialogs/clonetiler.cpp:182 +msgid "Nothing selected." +msgstr "Niets geselecteerd." + +#: ../../po/../src/dialogs/clonetiler.cpp:188 +msgid "More than one object selected." +msgstr "Meer dan één object geselecteerd." + +#: ../../po/../src/dialogs/clonetiler.cpp:195 +#, c-format +msgid "Object has %d tiled clones." +msgstr "Het object heeft %d getegelde klonen." + +#: ../../po/../src/dialogs/clonetiler.cpp:200 +msgid "Object has no tiled clones." +msgstr "Het object heeft geen getegelde klonen." + +#: ../../po/../src/dialogs/clonetiler.cpp:865 +msgid "Select one object whose tiled clones to unclump." +msgstr "Selecteer één object wiens klonen ontklonterd moeten worden." + +#: ../../po/../src/dialogs/clonetiler.cpp:916 +msgid "Select one object whose tiled clones to remove." +msgstr "Selecteer één object wiens klonen verwijderd moeten worden." + +#: ../../po/../src/dialogs/clonetiler.cpp:984 +#: ../../po/../src/selection-chemistry.cpp:1774 +msgid "Select an object to clone." +msgstr "Selecteer een object om te klonen." + +#: ../../po/../src/dialogs/clonetiler.cpp:990 +#: ../../po/../src/selection-chemistry.cpp:1780 +msgid "" +"If you want to clone several objects, group them and clone the " +"group." +msgstr "" +"Als u meerdere objecten wilt klonen, groepeer ze dan en kloon de " +"groep." + +#: ../../po/../src/dialogs/clonetiler.cpp:1484 +msgid "Per row:" +msgstr "Per rij:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1497 +msgid "Per column:" +msgstr "Per kolom:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1505 +msgid "Randomize:" +msgstr "Willekeurig:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1656 +msgid "_Symmetry" +msgstr "_Symmetrie" + +#. TRANSLATORS: For the following 17 symmetry groups, see +#. * http://www.bib.ulb.ac.be/coursmath/doc/17.htm (visual examples); +#. * http://www.clarku.edu/~djoyce/wallpaper/seventeen.html (English vocabulary); or +#. * http://membres.lycos.fr/villemingerard/Geometri/Sym1D.htm (French vocabulary). +#. +#: ../../po/../src/dialogs/clonetiler.cpp:1664 +msgid "Select one of the 17 symmetry groups for the tiling" +msgstr "Selecteer één van de 17 symmetrie groepen voor het tegelen" + +#. TRANSLATORS: "translation" means "shift" / "displacement" here. +#: ../../po/../src/dialogs/clonetiler.cpp:1675 +msgid "P1: simple translation" +msgstr "P1: eenvoudige verplaatsing" + +#: ../../po/../src/dialogs/clonetiler.cpp:1676 +msgid "P2: 180° rotation" +msgstr "P2: 180° draaiing" + +#: ../../po/../src/dialogs/clonetiler.cpp:1677 +msgid "PM: reflection" +msgstr "PM: spiegeling" + +#. TRANSLATORS: "glide reflection" is a reflection and a translation combined. +#. For more info, see http://mathforum.org/sum95/suzanne/symsusan.html +#: ../../po/../src/dialogs/clonetiler.cpp:1680 +msgid "PG: glide reflection" +msgstr "PG: verschoven spiegeling" + +#: ../../po/../src/dialogs/clonetiler.cpp:1681 +msgid "CM: reflection + glide reflection" +msgstr "CM: spiegeling + verschoven spiegeling" + +#: ../../po/../src/dialogs/clonetiler.cpp:1682 +msgid "PMM: reflection + reflection" +msgstr "PMM: spiegeling + spiegeling" + +#: ../../po/../src/dialogs/clonetiler.cpp:1683 +msgid "PMG: reflection + 180° rotation" +msgstr "PMG: spiegeling + 180° draaiing" + +#: ../../po/../src/dialogs/clonetiler.cpp:1684 +msgid "PGG: glide reflection + 180° rotation" +msgstr "PGG: verschoven spiegeling + 180° draaiing" + +#: ../../po/../src/dialogs/clonetiler.cpp:1685 +msgid "CMM: reflection + reflection + 180° rotation" +msgstr "CMM: spiegeling + spiegeling + 180° draaiing" + +#: ../../po/../src/dialogs/clonetiler.cpp:1686 +msgid "P4: 90° rotation" +msgstr "P4: 90° draaiing" + +#: ../../po/../src/dialogs/clonetiler.cpp:1687 +msgid "P4M: 90° rotation + 45° reflection" +msgstr "P4M: 90° draaiing + 45° spiegeling" + +#: ../../po/../src/dialogs/clonetiler.cpp:1688 +msgid "P4G: 90° rotation + 90° reflection" +msgstr "P4G: 90° draaiing + 90° spiegeling" + +#: ../../po/../src/dialogs/clonetiler.cpp:1689 +msgid "P3: 120° rotation" +msgstr "P3: 120° draaiing" + +#: ../../po/../src/dialogs/clonetiler.cpp:1690 +msgid "P31M: reflection + 120° rotation, dense" +msgstr "P31M: spiegeling + 120° draaiing, druk" + +#: ../../po/../src/dialogs/clonetiler.cpp:1691 +msgid "P3M1: reflection + 120° rotation, sparse" +msgstr "P3M1: spiegeling + 120° draaiing, rustig" + +#: ../../po/../src/dialogs/clonetiler.cpp:1692 +msgid "P6: 60° rotation" +msgstr "P6: 60° draaiing" + +#: ../../po/../src/dialogs/clonetiler.cpp:1693 +msgid "P6M: reflection + 60° rotation" +msgstr "P6M: spiegeling + 60° draaiing" + +#: ../../po/../src/dialogs/clonetiler.cpp:1721 +msgid "S_hift" +msgstr "Ver_plaatsing" + +#. TRANSLATORS: "shift" means: the tiles will be shifted (offset) horizontally by this amount +#: ../../po/../src/dialogs/clonetiler.cpp:1731 +#, no-c-format +msgid "Shift X:" +msgstr "X-verplaatsing:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1739 +#, no-c-format +msgid "Horizontal shift per row (in % of tile width)" +msgstr "Horizontale verplaatsing voor elke rij (in % van de tegel breedte)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1747 +#, no-c-format +msgid "Horizontal shift per column (in % of tile width)" +msgstr "Horizontale verplaatsing voor elke kolom (in % van de tegel breedte)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1754 +msgid "Randomize the horizontal shift by this percentage" +msgstr "De horizontale verschuiving willekeurig aanpassen met dit percentage" + +#. TRANSLATORS: "shift" means: the tiles will be shifted (offset) vertically by this amount +#: ../../po/../src/dialogs/clonetiler.cpp:1764 +#, no-c-format +msgid "Shift Y:" +msgstr "Y-verplaatsing:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1772 +#, no-c-format +msgid "Vertical shift per row (in % of tile height)" +msgstr "Verticale verplaatsing voor elke rij (in % van de tegel hoogte)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1780 +#, no-c-format +msgid "Vertical shift per column (in % of tile height)" +msgstr "Verticale verplaatsing voor elke kolom (in % van de tegel hoogte)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1787 +msgid "Randomize the vertical shift by this percentage" +msgstr "De verticale verschuiving willekeurig aanpassen met dit percentage" + +#: ../../po/../src/dialogs/clonetiler.cpp:1795 +msgid "Exponent:" +msgstr "Exponent:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1802 +msgid "Whether rows are spaced evenly (1), converge (<1) or diverge (>1)" +msgstr "Of de rij-afstand gelijk blijft (1), afneemt (<1) of toeneemt (>1)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1809 +msgid "Whether columns are spaced evenly (1), converge (<1) or diverge (>1)" +msgstr "Of de kolom-afstand gelijk blijft (1), afneemt (<1) of toeneemt (>1)" + +#. TRANSLATORS: "Alternate" is a verb here +#: ../../po/../src/dialogs/clonetiler.cpp:1817 +#: ../../po/../src/dialogs/clonetiler.cpp:1907 +#: ../../po/../src/dialogs/clonetiler.cpp:1966 +#: ../../po/../src/dialogs/clonetiler.cpp:2022 +#: ../../po/../src/dialogs/clonetiler.cpp:2153 +msgid "Alternate:" +msgstr "Afwisselen:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1823 +msgid "Alternate the sign of shifts for each row" +msgstr "De verplaatsingen voor elke rij om-en-om afwisselen" + +#: ../../po/../src/dialogs/clonetiler.cpp:1828 +msgid "Alternate the sign of shifts for each column" +msgstr "De verplaatsingen voor elke kolom om-en-om afwisselen" + +#: ../../po/../src/dialogs/clonetiler.cpp:1837 +msgid "Sc_ale" +msgstr "Ver_groting" + +#: ../../po/../src/dialogs/clonetiler.cpp:1845 +msgid "Scale X:" +msgstr "X-vergroting:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1853 +#, no-c-format +msgid "Horizontal scale per row (in % of tile width)" +msgstr "Horizontale vergroting voor elke rij (in % van de tegel breedte)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1861 +#, no-c-format +msgid "Horizontal scale per column (in % of tile width)" +msgstr "Horizontale vergroting voor elke kolom (in % van de tegel breedte)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1868 +msgid "Randomize the horizontal scale by this percentage" +msgstr "De horizontale verschuiving willekeurig aanpassen met dit percentage" + +#: ../../po/../src/dialogs/clonetiler.cpp:1876 +msgid "Scale Y:" +msgstr "Y-vergroting:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1884 +#, no-c-format +msgid "Vertical scale per row (in % of tile height)" +msgstr "Verticale vergroting voor elke rij (in % van de tegel hoogte)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1892 +#, no-c-format +msgid "Vertical scale per column (in % of tile height)" +msgstr "Verticale vergroting voor elke kolom (in % van de tegel hoogte)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1899 +msgid "Randomize the vertical scale by this percentage" +msgstr "De verticale vergroting willekeurig aanpassen met dit percentage" + +#: ../../po/../src/dialogs/clonetiler.cpp:1913 +msgid "Alternate the sign of scales for each row" +msgstr "De vergroting voor elke rij om-en-om afwisselen" + +#: ../../po/../src/dialogs/clonetiler.cpp:1918 +msgid "Alternate the sign of scales for each column" +msgstr "De vergroting voor elke kolom om-en-om afwisselen" + +#: ../../po/../src/dialogs/clonetiler.cpp:1927 +msgid "_Rotation" +msgstr "_Draaiing" + +#: ../../po/../src/dialogs/clonetiler.cpp:1935 +msgid "Angle:" +msgstr "Hoek:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1943 +#, no-c-format +msgid "Rotate tiles by this angle for each row" +msgstr "De tegels onder deze hoek draaien voor elke rij" + +#: ../../po/../src/dialogs/clonetiler.cpp:1951 +#, no-c-format +msgid "Rotate tiles by this angle for each column" +msgstr "De tegels onder deze hoek draaien voor elke kolom" + +#: ../../po/../src/dialogs/clonetiler.cpp:1958 +msgid "Randomize the rotation angle by this percentage" +msgstr "De draai-hoek willekeurig aanpassen met dit percentage" + +#: ../../po/../src/dialogs/clonetiler.cpp:1972 +msgid "Alternate the rotation direction for each row" +msgstr "De draai-richting voor elke rij om-en-om afwisselen " + +#: ../../po/../src/dialogs/clonetiler.cpp:1977 +msgid "Alternate the rotation direction for each column" +msgstr "De draai-richting voor elke kolom om-en-om afwisselen " + +#: ../../po/../src/dialogs/clonetiler.cpp:1985 +msgid "_Opacity" +msgstr "_Ondoorzichtigheid" + +#: ../../po/../src/dialogs/clonetiler.cpp:1993 +msgid "Fade out:" +msgstr "Oplossen:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2000 +msgid "Decrease tile opacity by this percentage for each row" +msgstr "Verminder de ondoorzichtigheid met dit percentage voor elke rij" + +#: ../../po/../src/dialogs/clonetiler.cpp:2007 +msgid "Decrease tile opacity by this percentage for each column" +msgstr "Verminder de ondoorzichtigheid met dit percentage voor elke kolom" + +#: ../../po/../src/dialogs/clonetiler.cpp:2014 +msgid "Randomize the tile opacity by this percentage" +msgstr "De ondoorzichtigheid willekeurig aanpassen met dit percentage" + +#: ../../po/../src/dialogs/clonetiler.cpp:2028 +msgid "Alternate the sign of opacity change for each row" +msgstr "De doorzichtigheid voor elke rij om-en-om afwisselen " + +#: ../../po/../src/dialogs/clonetiler.cpp:2033 +msgid "Alternate the sign of opacity change for each column" +msgstr "De doorzichtigheid voor elke kolom om-en-om afwisselen " + +#: ../../po/../src/dialogs/clonetiler.cpp:2041 +msgid "Co_lor" +msgstr "_Kleur" + +#: ../../po/../src/dialogs/clonetiler.cpp:2046 +msgid "Initial color: " +msgstr "Begin kleur:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2050 +msgid "Initial color of tiled clones" +msgstr "Begin kleur van getegelde klonen" + +#: ../../po/../src/dialogs/clonetiler.cpp:2050 +msgid "" +"Initial color for clones (works only if the original has unset fill or " +"stroke)" +msgstr "" +"Begin kleur van klonen (werkt alleen als de kleur van de lijnen of de " +"vulling van het origineel verwijderd is)" + +#: ../../po/../src/dialogs/clonetiler.cpp:2065 +msgid "H:" +msgstr "K:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2072 +msgid "Change the tile hue by this percentage for each row" +msgstr "Verander de kleurtoon met dit percentage voor elke rij" + +#: ../../po/../src/dialogs/clonetiler.cpp:2079 +msgid "Change the tile hue by this percentage for each column" +msgstr "Verander de kleurtoon met dit percentage voor elke kolom" + +#: ../../po/../src/dialogs/clonetiler.cpp:2086 +msgid "Randomize the tile hue by this percentage" +msgstr "De kleurtoon willekeurig aanpassen met dit percentage" + +#: ../../po/../src/dialogs/clonetiler.cpp:2095 +msgid "S:" +msgstr "V:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2102 +msgid "Change the color saturation by this percentage for each row" +msgstr "Verander de verzadiging met dit percentage voor elke rij" + +#: ../../po/../src/dialogs/clonetiler.cpp:2109 +msgid "Change the color saturation by this percentage for each column" +msgstr "Verander de verzadiging met dit percentage voor elke kolom" + +#: ../../po/../src/dialogs/clonetiler.cpp:2116 +msgid "Randomize the color saturation by this percentage" +msgstr "De verzadiging willekeurig aanpassen met dit percentage" + +#: ../../po/../src/dialogs/clonetiler.cpp:2124 +msgid "L:" +msgstr "W:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2131 +msgid "Change the color lightness by this percentage for each row" +msgstr "Verander de kleur-waarde met dit percentage voor elke rij" + +#: ../../po/../src/dialogs/clonetiler.cpp:2138 +msgid "Change the color lightness by this percentage for each column" +msgstr "Verander de kleur-waarde met dit percentage voor elke kolom" + +#: ../../po/../src/dialogs/clonetiler.cpp:2145 +msgid "Randomize the color lightness by this percentage" +msgstr "De waarde willekeurig aanpassen met dit percentage" + +#: ../../po/../src/dialogs/clonetiler.cpp:2159 +msgid "Alternate the sign of color changes for each row" +msgstr "De kleur-wijzigingen voor elke rij om-en-om afwisselen " + +#: ../../po/../src/dialogs/clonetiler.cpp:2164 +msgid "Alternate the sign of color changes for each column" +msgstr "De kleur-wijzigingen voor elke kolom om-en-om afwisselen " + +#: ../../po/../src/dialogs/clonetiler.cpp:2172 +msgid "_Trace" +msgstr "_Overtrekken" + +#: ../../po/../src/dialogs/clonetiler.cpp:2179 +msgid "Trace the drawing under the tiles" +msgstr "De tekening onder de tegels gebruiken" + +#: ../../po/../src/dialogs/clonetiler.cpp:2183 +msgid "" +"For each clone, pick a value from the drawing in that clone's location and " +"apply it to the clone" +msgstr "" +"Voor elke kloon een eigenschap van de tekening op dat punt gebruiken om die " +"kloon te beïnvloeden." + +#: ../../po/../src/dialogs/clonetiler.cpp:2197 +msgid "1. Pick from the drawing:" +msgstr "1. Kies een eigenschap uit de tekening:" + +#. ----Hbox2 +#: ../../po/../src/dialogs/clonetiler.cpp:2208 +#: ../../po/../src/dialogs/clonetiler.cpp:2355 +#: ../../po/../src/ui/dialog/tracedialog.cpp:445 +msgid "Color" +msgstr "Kleur" + +#: ../../po/../src/dialogs/clonetiler.cpp:2209 +msgid "Pick the visible color and opacity" +msgstr "Selecteer de zichtbare kleur en de ondoorzichtigheid" + +#: ../../po/../src/dialogs/clonetiler.cpp:2216 +#: ../../po/../src/dialogs/clonetiler.cpp:2365 +#: ../share/extensions/dropshadow.inx.h:3 +msgid "Opacity" +msgstr "Ondoorzichtigheid" + +#: ../../po/../src/dialogs/clonetiler.cpp:2217 +msgid "Pick the total accumulated opacity" +msgstr "Selecteer de gesommeerde ondoorzichtigheid" + +#: ../../po/../src/dialogs/clonetiler.cpp:2224 +msgid "R" +msgstr "Rood" + +#: ../../po/../src/dialogs/clonetiler.cpp:2225 +msgid "Pick the Red component of the color" +msgstr "Selecteer de rood-component van de kleur" + +#: ../../po/../src/dialogs/clonetiler.cpp:2232 +msgid "G" +msgstr "Groen" + +#: ../../po/../src/dialogs/clonetiler.cpp:2233 +msgid "Pick the Green component of the color" +msgstr "Selecteer de groen-component van de kleur" + +#: ../../po/../src/dialogs/clonetiler.cpp:2240 +msgid "B" +msgstr "Blauw" + +#: ../../po/../src/dialogs/clonetiler.cpp:2241 +msgid "Pick the Blue component of the color" +msgstr "Selecteer de blauw-component van de kleur" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2250 +msgid "clonetiler|H" +msgstr "Kleurtoon" + +#: ../../po/../src/dialogs/clonetiler.cpp:2251 +msgid "Pick the hue of the color" +msgstr "De kleurtoon van de kleur kiezen" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2260 +msgid "clonetiler|S" +msgstr "Verzadiging" + +#: ../../po/../src/dialogs/clonetiler.cpp:2261 +msgid "Pick the saturation of the color" +msgstr "De verzadiging van de kleur kiezen" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2270 +msgid "clonetiler|L" +msgstr "Waarde" + +#: ../../po/../src/dialogs/clonetiler.cpp:2271 +msgid "Pick the lightness of the color" +msgstr "De waarde van de kleur kiezen" + +#: ../../po/../src/dialogs/clonetiler.cpp:2281 +msgid "2. Tweak the picked value:" +msgstr "2. De geselecteerde eigenschap fijnafstemmen:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2291 +msgid "Gamma-correct:" +msgstr "Gamma-correctie:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2296 +msgid "Shift the mid-range of the picked value upwards (>0) or downwards (<0)" +msgstr "" +"Het midden gebied van de gekozen eigenschap omlaag (>0) of omhoog (<0) " +"verplaatsen" + +#: ../../po/../src/dialogs/clonetiler.cpp:2303 +msgid "Randomize:" +msgstr "Willekeur:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2308 +msgid "Randomize the picked value by this percentage" +msgstr "De geselecteerde eigenschap willekeurig aanpassen met dit percentage" + +#: ../../po/../src/dialogs/clonetiler.cpp:2315 +msgid "Invert:" +msgstr "Omdraaien:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2319 +msgid "Invert the picked value" +msgstr "Draai de geselecteerde eigenschap om" + +#: ../../po/../src/dialogs/clonetiler.cpp:2325 +msgid "3. Apply the value to the clones':" +msgstr "3. De relatie tussen de eigenschap en de klonen:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2335 +msgid "Presence" +msgstr "Aanwezigheid" + +#: ../../po/../src/dialogs/clonetiler.cpp:2338 +msgid "" +"Each clone is created with the probability determined by the picked value in " +"that point" +msgstr "" +"De kans dat een kloon op een plek wordt gemaakt is afhankelijk van de waarde " +"van de geselecteerde eigenschap op dat punt." + +#: ../../po/../src/dialogs/clonetiler.cpp:2345 +msgid "Size" +msgstr "Afmeting" + +#: ../../po/../src/dialogs/clonetiler.cpp:2348 +msgid "Each clone's size is determined by the picked value in that point" +msgstr "" +"De grootte van een kloon is afhankelijk van de waarde van de geselecteerde " +"eigenschap op dat punt" + +#: ../../po/../src/dialogs/clonetiler.cpp:2358 +msgid "" +"Each clone is painted by the picked color (the original must have unset fill " +"or stroke)" +msgstr "" +"Klonen worden getekend in de geselecteerde kleur (werkt alleen als de kleur " +"van de lijnen of de vulling van het origineel verwijderd is)" + +#: ../../po/../src/dialogs/clonetiler.cpp:2368 +msgid "Each clone's opacity is determined by the picked value in that point" +msgstr "" +"De ondoorzichtigheid van een kloon is afhankelijk van de waarde van de " +"geselecteerde eigenschap op dat punt" + +#: ../../po/../src/dialogs/clonetiler.cpp:2395 +msgid "How many rows in the tiling" +msgstr "Hoeveel rijen er betegeld moeten worden" + +#: ../../po/../src/dialogs/clonetiler.cpp:2415 +msgid "How many columns in the tiling" +msgstr "Hoeveel kolommen er betegeld moeten worden" + +#: ../../po/../src/dialogs/clonetiler.cpp:2445 +msgid "Width of the rectangle to be filled" +msgstr "Breedte van de rechthoek die gevuld moet worden" + +#: ../../po/../src/dialogs/clonetiler.cpp:2470 +msgid "Height of the rectangle to be filled" +msgstr "Hoogte van de rechthoek die gevuld moet worden" + +#: ../../po/../src/dialogs/clonetiler.cpp:2485 +msgid "Rows, columns: " +msgstr "Rijen, kolommen:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2486 +msgid "Create the specified number of rows and columns" +msgstr "Het opgegeven aantal rijen en kolommen aanmaken" + +#: ../../po/../src/dialogs/clonetiler.cpp:2495 +msgid "Width, height: " +msgstr "Breedte, hoogte:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2496 +msgid "Fill the specified width and height with the tiling" +msgstr "Vul een gebied met opgegeven breedte en hoogte met de betegeling" + +#: ../../po/../src/dialogs/clonetiler.cpp:2512 +msgid "Use saved size and position of the tile" +msgstr "De opgeslagen grootte en positie van de tegel gebruiken" + +#: ../../po/../src/dialogs/clonetiler.cpp:2515 +msgid "" +"Pretend that the size and position of the tile are the same as the last time " +"you tiled it (if any), instead of using the current size" +msgstr "" +"Doe alsof de grootte en de positie van de tegel hetzelfde zijn als de " +"laatste keer dat u er mee tegelde, in plaats van de huidige grootte en " +"positie te gebruiken." + +#: ../../po/../src/dialogs/clonetiler.cpp:2539 +msgid " _Create " +msgstr "_Aanmaken" + +#: ../../po/../src/dialogs/clonetiler.cpp:2541 +msgid "Create and tile the clones of the selection" +msgstr "Maak klonen van de selectie en gebruik ze als betegeling" + +#. TRANSLATORS: if a group of objects are "clumped" together, then they +#. are unevenly spread in the given amount of space - as shown in the +#. diagrams on the left in the following screenshot: +#. http://www.inkscape.org/screenshots/gallery/inkscape-0.42-CVS-tiles-unclump.png +#. So unclumping is the process of spreading a number of objects out more evenly. +#: ../../po/../src/dialogs/clonetiler.cpp:2556 +msgid " _Unclump " +msgstr "_Ontklonteren" + +#: ../../po/../src/dialogs/clonetiler.cpp:2557 +msgid "Spread out clones to reduce clumping; can be applied repeatedly" +msgstr "" +"De klonen verspreiden om ze te ontklonteren; kan herhaaldelijk worden " +"toegepast" + +#: ../../po/../src/dialogs/clonetiler.cpp:2563 +msgid " Re_move " +msgstr "_Verwijderen" + +#: ../../po/../src/dialogs/clonetiler.cpp:2564 +msgid "Remove existing tiled clones of the selected object (siblings only)" +msgstr "Verwijder bestaande getegelde klonen van het geselecteerde object" + +#: ../../po/../src/dialogs/clonetiler.cpp:2580 +msgid " R_eset " +msgstr "_Opnieuw" + +#. TRANSLATORS: "change" is a noun here +#: ../../po/../src/dialogs/clonetiler.cpp:2582 +msgid "" +"Reset all shifts, scales, rotates, opacity and color changes in the dialog " +"to zero" +msgstr "" +"Zet alle verplaatsingen, vergrotingen, verdraaiingen in het venster e.d. op " +"nul." + +#: ../../po/../src/dialogs/color-picker.cpp:280 +msgid "Close" +msgstr "Sluiten" + +#: ../../po/../src/dialogs/debugdialog.cpp:138 +msgid "Messages" +msgstr "Berichten" + +#. ## Add a menu for clear() +#: ../../po/../src/dialogs/debugdialog.cpp:144 +#: ../../po/../src/menus-skeleton.h:16 +#: ../../po/../src/ui/dialog/messages.cpp:56 +#: ../../po/../src/ui/dialog/scriptdialog.cpp:181 +msgid "_File" +msgstr "_Bestand" + +#. TRANSLATORS: "Clear" is a verb here +#: ../../po/../src/dialogs/debugdialog.cpp:145 +#: ../../po/../src/dialogs/find.cpp:753 +#: ../../po/../src/ui/dialog/messages.cpp:57 +#: ../../po/../src/ui/dialog/scriptdialog.cpp:182 +msgid "_Clear" +msgstr "_Leegmaken" + +#: ../../po/../src/dialogs/debugdialog.cpp:147 +#: ../../po/../src/ui/dialog/messages.cpp:59 +msgid "Capture log messages" +msgstr "Log berichten bewaren" + +#: ../../po/../src/dialogs/debugdialog.cpp:149 +#: ../../po/../src/ui/dialog/messages.cpp:61 +msgid "Release log messages" +msgstr "Log berichten negeren" + +#. Notebook tab +#: ../../po/../src/dialogs/desktop-properties.cpp:909 +#: ../../po/../src/ui/dialog/document-preferences.cpp:89 +#: ../../po/../src/ui/widget/panel.cpp:107 +msgid "Grid" +msgstr "Raster" + +#. Checkbuttons +#. / \todo FIXME: gray out snapping when grid is off +#. / \todo FIXME: gray out snapping when grid is off. +#. / Dissenting view: you want snapping without grid. +#: ../../po/../src/dialogs/desktop-properties.cpp:917 +#: ../../po/../src/ui/dialog/document-preferences.cpp:179 +msgid "Show grid" +msgstr "Raster weergeven" + +#: ../../po/../src/dialogs/desktop-properties.cpp:917 +#: ../../po/../src/ui/dialog/document-preferences.cpp:179 +#: ../../po/../src/verbs.cpp:2115 +msgid "Show or hide grid" +msgstr "Raster weergeven of verbergen" + +#: ../../po/../src/dialogs/desktop-properties.cpp:918 +#: ../../po/../src/ui/dialog/document-preferences.cpp:180 +msgid "Snap bounding boxes to grid" +msgstr "Het raster is magnetisch voor omhullenden" + +#: ../../po/../src/dialogs/desktop-properties.cpp:918 +#: ../../po/../src/dialogs/desktop-properties.cpp:1001 +#: ../../po/../src/ui/dialog/document-preferences.cpp:181 +#: ../../po/../src/ui/dialog/document-preferences.cpp:236 +msgid "Snap the edges of the object bounding boxes" +msgstr "Omhullenden van objecten worden aangetrokken " + +#: ../../po/../src/dialogs/desktop-properties.cpp:919 +#: ../../po/../src/ui/dialog/document-preferences.cpp:183 +msgid "Snap nodes to grid" +msgstr "Het raster is magnetisch voor knooppunten" + +#: ../../po/../src/dialogs/desktop-properties.cpp:919 +#: ../../po/../src/dialogs/desktop-properties.cpp:1002 +#: ../../po/../src/ui/dialog/document-preferences.cpp:184 +#: ../../po/../src/ui/dialog/document-preferences.cpp:239 +msgid "Snap path nodes, text baselines, ellipse centers, etc." +msgstr "Knooppunten, teksten en en cirkel-middens e.d. worden aangetrokken" + +#: ../../po/../src/dialogs/desktop-properties.cpp:937 +#: ../../po/../src/ui/dialog/document-preferences.cpp:186 +msgid "Grid units:" +msgstr "Rastereenheden:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:939 +#: ../../po/../src/ui/dialog/document-preferences.cpp:187 +msgid "Origin X:" +msgstr "X-oorsprong: " + +#: ../../po/../src/dialogs/desktop-properties.cpp:942 +#: ../../po/../src/ui/dialog/document-preferences.cpp:189 +msgid "Origin Y:" +msgstr "Y-oorsprong:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:945 +#: ../../po/../src/ui/dialog/document-preferences.cpp:191 +msgid "Spacing X:" +msgstr "X tussenafstand:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:948 +#: ../../po/../src/ui/dialog/document-preferences.cpp:193 +msgid "Spacing Y:" +msgstr "Y tussenafstand:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:952 +#: ../../po/../src/dialogs/desktop-properties.cpp:1013 +#: ../../po/../src/ui/dialog/document-preferences.cpp:195 +#: ../../po/../src/ui/dialog/document-preferences.cpp:241 +msgid "Snap units:" +msgstr "Eenheden voor magnetisme" + +#: ../../po/../src/dialogs/desktop-properties.cpp:955 +#: ../../po/../src/dialogs/desktop-properties.cpp:1016 +#: ../../po/../src/ui/dialog/document-preferences.cpp:196 +#: ../../po/../src/ui/dialog/document-preferences.cpp:242 +msgid "Snap distance:" +msgstr "Magnetisme werkt tot:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:958 +#: ../../po/../src/ui/dialog/document-preferences.cpp:199 +msgid "Grid line color:" +msgstr "Kleur van hulplijnen:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:959 +#: ../../po/../src/ui/dialog/document-preferences.cpp:199 +msgid "Grid line color" +msgstr "Kleur van hulplijnen" + +#: ../../po/../src/dialogs/desktop-properties.cpp:959 +#: ../../po/../src/ui/dialog/document-preferences.cpp:200 +msgid "Color of grid lines" +msgstr "De kleur van de hulplijnen" + +#: ../../po/../src/dialogs/desktop-properties.cpp:961 +#: ../../po/../src/ui/dialog/document-preferences.cpp:201 +msgid "Major grid line color:" +msgstr "Kleur van raster-hoofdlijnen:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:962 +#: ../../po/../src/ui/dialog/document-preferences.cpp:201 +msgid "Major grid line color" +msgstr "Kleur van raster-hoofdlijnen" + +#: ../../po/../src/dialogs/desktop-properties.cpp:962 +#: ../../po/../src/ui/dialog/document-preferences.cpp:202 +msgid "Color of the major (highlighted) grid lines" +msgstr "De kleur van de geselecteerde raster-hoofdlijnen" + +#: ../../po/../src/dialogs/desktop-properties.cpp:965 +#: ../../po/../src/ui/dialog/document-preferences.cpp:204 +msgid "Major grid line every:" +msgstr "Een raster-hoofdlijn elke:" + +#. TRANSLATORS: This belongs to the "Major grid line every:" string, +#. see grid settings in the "Document Preferences" dialog +#: ../../po/../src/dialogs/desktop-properties.cpp:977 +#: ../../po/../src/ui/dialog/document-preferences.cpp:204 +msgid "lines" +msgstr "rasterlijnen" + +#. Guidelines page +#: ../../po/../src/dialogs/desktop-properties.cpp:991 +#: ../../po/../src/ui/dialog/document-preferences.cpp:90 +msgid "Guides" +msgstr "Hulplijnen" + +#. / \todo FIXME: gray out snapping when guides are off +#. / Dissenting view: you want snapping without guides. +#: ../../po/../src/dialogs/desktop-properties.cpp:1000 +#: ../../po/../src/ui/dialog/document-preferences.cpp:234 +msgid "Show guides" +msgstr "Hulplijnen weergeven" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1000 +#: ../../po/../src/ui/dialog/document-preferences.cpp:234 +#: ../../po/../src/verbs.cpp:2116 +msgid "Show or hide guides" +msgstr "Hulplijnen weergeven of verbergen" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1001 +#: ../../po/../src/ui/dialog/document-preferences.cpp:235 +msgid "Snap bounding boxes to guides" +msgstr "Hulplijnen zijn magnetisch voor omhullenden" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1002 +#: ../../po/../src/ui/dialog/document-preferences.cpp:238 +msgid "Snap points to guides" +msgstr "Hulplijnen zijn magnetisch voor punten" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1020 +#: ../../po/../src/ui/dialog/document-preferences.cpp:243 +msgid "Guide color:" +msgstr "Kleur van hulplijnen:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1021 +#: ../../po/../src/ui/dialog/document-preferences.cpp:243 +msgid "Guideline color" +msgstr "Kleur van hulplijnen" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1021 +#: ../../po/../src/ui/dialog/document-preferences.cpp:244 +msgid "Color of guidelines" +msgstr "Kleur van de hulplijnen" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1023 +#: ../../po/../src/ui/dialog/document-preferences.cpp:245 +msgid "Highlight color:" +msgstr "Oplichtende kleur:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1024 +#: ../../po/../src/ui/dialog/document-preferences.cpp:245 +msgid "Highlighted guideline color" +msgstr "Kleur van oplichtende hulplijn" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1024 +#: ../../po/../src/ui/dialog/document-preferences.cpp:246 +msgid "Color of a guideline when it is under mouse" +msgstr "Kleur van een hulplijn als de muis erover heen beweegt" + +#. Page page +#: ../../po/../src/dialogs/desktop-properties.cpp:1029 +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:855 +#: ../../po/../src/ui/dialog/document-preferences.cpp:88 +#: ../../po/../src/widgets/desktop-widget.cpp:1061 +msgid "Page" +msgstr "Pagina" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1039 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +msgid "Background:" +msgstr "Achtergrondkleur:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1040 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +msgid "Background color" +msgstr "Achtergrondkleur" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1041 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +msgid "" +"Color and transparency of the page background (also used for bitmap export)" +msgstr "" +"De kleur en doorzichtigheid van de pagina achtergrond (wordt ook gebruikt " +"voor het exporteren naar een bitmap)." + +#: ../../po/../src/dialogs/desktop-properties.cpp:1045 +#: ../../po/../src/ui/dialog/document-preferences.cpp:147 +#, fuzzy +msgid "Show page border" +msgstr "Canvasrand weergeven" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1049 +#: ../../po/../src/ui/dialog/document-preferences.cpp:148 +msgid "Border on top of drawing" +msgstr "Rand aan de bovenkant van de tekening" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1052 +#: ../../po/../src/ui/dialog/document-preferences.cpp:149 +msgid "Border color:" +msgstr "Omrandingskleur:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1053 +#: ../../po/../src/ui/dialog/document-preferences.cpp:149 +#, fuzzy +msgid "Page border color" +msgstr "Kleur van de canvasrand" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1054 +#: ../../po/../src/ui/dialog/document-preferences.cpp:150 +#, fuzzy +msgid "Color of the page border" +msgstr "Kleur van de canvasrand" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1059 +#: ../../po/../src/ui/dialog/document-preferences.cpp:152 +msgid "Show page shadow" +msgstr "Pagina schaduw weergeven" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1063 +#: ../../po/../src/ui/dialog/document-preferences.cpp:153 +msgid "Default units:" +msgstr "Standaard eenheden:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1069 +msgid "Units for the tool controls, ruler, and the statusbar" +msgstr "Eenheden voor gereedschappen, linealen en de statusbalk" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1086 +#: ../../po/../src/ui/widget/page-sizer.cpp:209 +#, fuzzy +msgid "Page size:" +msgstr "Canvas grootte:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1110 +#: ../../po/../src/ui/widget/page-sizer.cpp:219 +msgid "Custom" +msgstr "Aangepast" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1121 +#: ../../po/../src/ui/widget/page-sizer.cpp:225 +#, fuzzy +msgid "Page orientation:" +msgstr "Canvas oriëntatie:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1133 +#: ../../po/../src/ui/widget/page-sizer.cpp:232 +msgid "Landscape" +msgstr "Landschap" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1139 +#: ../../po/../src/ui/widget/page-sizer.cpp:234 +msgid "Portrait" +msgstr "Portret" + +#. Custom paper frame +#: ../../po/../src/dialogs/desktop-properties.cpp:1148 +#: ../../po/../src/ui/widget/page-sizer.cpp:249 +#, fuzzy +msgid "Custom size" +msgstr "Aangepast" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1160 +#: ../../po/../src/dialogs/export.cpp:269 +#: ../../po/../src/ui/widget/page-sizer.cpp:261 +msgid "Units:" +msgstr "Eenheden:" + +#. Stroke width +#: ../../po/../src/dialogs/desktop-properties.cpp:1162 +#: ../../po/../src/dialogs/export.cpp:310 +#: ../../po/../src/dialogs/object-attributes.cpp:55 +#: ../../po/../src/dialogs/stroke-style.cpp:985 +#: ../../po/../src/ui/widget/page-sizer.cpp:262 +#: ../../po/../src/widgets/toolbox.cpp:1957 +msgid "Width:" +msgstr "Breedte:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1183 +#: ../../po/../src/dialogs/export.cpp:326 +#: ../../po/../src/dialogs/export.cpp:431 +#: ../../po/../src/dialogs/object-attributes.cpp:56 +#: ../../po/../src/ui/widget/page-sizer.cpp:263 +msgid "Height:" +msgstr "Hoogte:" + +#. +#. * Ownership metadata tab +#. +#: ../../po/../src/dialogs/desktop-properties.cpp:1206 +msgid "Metadata" +msgstr "Document eigenschappen" + +#. add license selector pull-down +#: ../../po/../src/dialogs/desktop-properties.cpp:1225 +msgid "License" +msgstr "Licentie" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1255 +msgid "Proprietary" +msgstr "Niet vrij" + +#: ../../po/../src/dialogs/display-settings.cpp:212 +msgid "When transforming, show:" +msgstr "Bij het transformeren weergeven:" + +#: ../../po/../src/dialogs/display-settings.cpp:223 +msgid "Objects" +msgstr "Objecten" + +#: ../../po/../src/dialogs/display-settings.cpp:224 +msgid "Show the actual objects when moving or transforming" +msgstr "De werkelijke objecten weergeven bij verplaatsten en transformeren" + +#: ../../po/../src/dialogs/display-settings.cpp:231 +msgid "Box outline" +msgstr "Omhullende weergeven" + +#: ../../po/../src/dialogs/display-settings.cpp:232 +msgid "Show only a box outline of the objects when moving or transforming" +msgstr "" +"Alleen een rechthoekige omhullende weergeven bij verplaatsten en " +"transformeren" + +#: ../../po/../src/dialogs/display-settings.cpp:238 +msgid "Per-object selection cue:" +msgstr "Selectie-aanduiding per object:" + +#. sorationsnapsperpi == 0 means no snapping +#: ../../po/../src/dialogs/display-settings.cpp:249 +#: ../../po/../src/dialogs/display-settings.cpp:386 +#: ../../po/../src/dialogs/display-settings.cpp:441 +#: ../../po/../src/dialogs/display-settings.cpp:1482 +#: ../../po/../src/dialogs/stroke-style.cpp:791 +#: ../../po/../src/interface.cpp:741 +#: ../../po/../src/ui/widget/selected-style.cpp:100 +#: ../../po/../src/verbs.cpp:1842 +msgid "None" +msgstr "Geen" + +#: ../../po/../src/dialogs/display-settings.cpp:250 +msgid "No per-object selection indication" +msgstr "Geen aanduiding van selectie per object" + +#: ../../po/../src/dialogs/display-settings.cpp:256 +msgid "Mark" +msgstr "Markeren" + +#: ../../po/../src/dialogs/display-settings.cpp:257 +msgid "Each selected object has a diamond mark in the top left corner" +msgstr "Elk geselecteerd object heeft een ruit-markering in de linkerbovenhoek" + +#: ../../po/../src/dialogs/display-settings.cpp:264 +msgid "Box" +msgstr "Omhullende" + +#: ../../po/../src/dialogs/display-settings.cpp:265 +msgid "Each selected object displays its bounding box" +msgstr "Elk geselecteerde object heeft een eigen omhullende" + +#: ../../po/../src/dialogs/display-settings.cpp:270 +msgid "Default scale origin:" +msgstr "Standaard schaal-oorsprong:" + +#: ../../po/../src/dialogs/display-settings.cpp:281 +msgid "Opposite bounding box edge" +msgstr "Tegenoverliggende zijde van de omhullende." + +#: ../../po/../src/dialogs/display-settings.cpp:282 +msgid "Default scale origin will be on the bounding box of the item" +msgstr "De omhullende zal worden gebruikt als standaard schaal-oorsprong" + +#: ../../po/../src/dialogs/display-settings.cpp:288 +msgid "Farthest opposite node" +msgstr "Het verst tegenoverliggende knooppunt" + +#: ../../po/../src/dialogs/display-settings.cpp:289 +msgid "Default scale origin will be on the bounding box of the item's points" +msgstr "" +"De omhullende van de knooppunten zal worden gebruikt als standaard schaal-" +"oorsprong" + +#: ../../po/../src/dialogs/display-settings.cpp:341 +msgid "degrees" +msgstr "graden" + +#: ../../po/../src/dialogs/display-settings.cpp:350 +msgid "" +"Rotating with Ctrl pressed snaps every that much degrees; also, pressing " +"[ or ] rotates by this amount" +msgstr "" +"Het aantal graden dat per stap wanneer Ctrl (of [ of ])ingedrukt wordt " +"tijdens het draaien" + +#: ../../po/../src/dialogs/display-settings.cpp:407 +msgid "Rotation snaps every:" +msgstr "Draaien in stappen van:" + +#: ../../po/../src/dialogs/display-settings.cpp:430 +msgid "" +"None: dialogs are treated as regular windows; Normal: dialogs stay on top of " +"document windows; Aggressive: same as Normal but may work better with some " +"window managers." +msgstr "" +"Geen: dialogen worden behandeld als gewone vensters; Normaal: dialogen " +"blijven boven bewerkingsvensters; Agressief: hetzelfde als 'normaal', maar " +"het werkt misschien beter met sommige Window Managers." + +#: ../../po/../src/dialogs/display-settings.cpp:451 +msgid "Normal" +msgstr "Normaal" + +#: ../../po/../src/dialogs/display-settings.cpp:461 +msgid "Aggressive" +msgstr "Agressief" + +#: ../../po/../src/dialogs/display-settings.cpp:475 +msgid "Dialogs on top:" +msgstr "Plaatsing van dialogen :" + +#: ../../po/../src/dialogs/display-settings.cpp:645 +msgid "Show selection cue" +msgstr "Selectie-aanduiding tonen" + +#: ../../po/../src/dialogs/display-settings.cpp:646 +msgid "" +"Whether selected objects display a selection cue (the same as in selector)" +msgstr "" +"Verberg de selectie-aanduiding voor objecten (hetzelfde als bij 'selecteren')" + +#: ../../po/../src/dialogs/display-settings.cpp:657 +msgid "Enable gradient editing" +msgstr "Toestaan kleurverlopen aan te passen" + +#: ../../po/../src/dialogs/display-settings.cpp:658 +msgid "Whether selected objects display gradient editing controls" +msgstr "Verberg kleurverloop-gereedschappen voor geselecteerde objecten" + +#: ../../po/../src/dialogs/display-settings.cpp:719 +msgid "No objects selected to take the style from." +msgstr "Geen objecten geselecteerd om de stijl van over te nemen" + +#: ../../po/../src/dialogs/display-settings.cpp:728 +msgid "" +"More than one object selected. Cannot take style from multiple " +"objects." +msgstr "" +"Meer dan één object geselecteerd. De stijl kan niet van meerdere " +"objectentegelijk worden overgenomen." + +#: ../../po/../src/dialogs/display-settings.cpp:767 +msgid "Create new objects with:" +msgstr "Nieuwe objecten aanmaken met:" + +#: ../../po/../src/dialogs/display-settings.cpp:777 +msgid "Take from selection" +msgstr "Overnemen ven selectie" + +#: ../../po/../src/dialogs/display-settings.cpp:778 +msgid "Remember the style of the (first) selected object as this tool's style" +msgstr "" +"De stijl van het (eerst) geselecteerde object onthouden als stijl voor dit " +"gereedschap" + +#: ../../po/../src/dialogs/display-settings.cpp:782 +#, fuzzy +msgid "Last used style" +msgstr "Plak _stijl" + +#: ../../po/../src/dialogs/display-settings.cpp:782 +msgid "Apply the style you last set on an object" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:790 +msgid "This tool's own style:" +msgstr "Stijl van dit gereedschap:" + +#: ../../po/../src/dialogs/display-settings.cpp:790 +msgid "" +"Each tool may store its own style to apply to the newly created objects. Use " +"the button below to set it." +msgstr "" +"Elk gereedschap kan zijn eigen stijl opslaan die gebruikt wordt voor " +"nieuweobjecten. Gebruik de knop hieronder om de stijl in te stellen." + +#. Mouse +#: ../../po/../src/dialogs/display-settings.cpp:877 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:55 +msgid "Mouse" +msgstr "Muis\t" + +#. TRANSLATORS: "Grab" is a noun here. "Grab sensitivity" is intended to mean how +#. * close on the screen you need to be to an object to be able to grab it with mouse (in +#. * pixels). +#: ../../po/../src/dialogs/display-settings.cpp:883 +msgid "Grab sensitivity:" +msgstr "Klik-gevoeligheid:" + +#: ../../po/../src/dialogs/display-settings.cpp:884 +msgid "" +"How close on the screen you need to be to an object to be able to grab it " +"with mouse (in screen pixels)" +msgstr "" +"Hoe dicht u naast een object moet klikken om het te selecteren met de muis " +"(in pixels)" + +#: ../../po/../src/dialogs/display-settings.cpp:885 +#: ../../po/../src/dialogs/display-settings.cpp:897 +#: ../../po/../src/dialogs/display-settings.cpp:912 +#: ../../po/../src/dialogs/display-settings.cpp:930 +#: ../../po/../src/dialogs/display-settings.cpp:970 +msgid "pixels" +msgstr "beeldpunten" + +#: ../../po/../src/dialogs/display-settings.cpp:895 +msgid "Click/drag threshold:" +msgstr "Klikken-of-slepen grenswaarde:" + +#: ../../po/../src/dialogs/display-settings.cpp:896 +msgid "" +"Maximum mouse drag (in screen pixels) which is considered a click, not a drag" +msgstr "" +"Maximale verschuiving van de muis (in pixels) die nog als klikken en niet " +"als slepenmoet worden geinterpreteerd." + +#. Scrolling +#: ../../po/../src/dialogs/display-settings.cpp:907 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:56 +msgid "Scrolling" +msgstr "Verschuiven" + +#: ../../po/../src/dialogs/display-settings.cpp:910 +msgid "Mouse wheel scrolls by:" +msgstr "Het muiswiel verschuift met:" + +#: ../../po/../src/dialogs/display-settings.cpp:911 +msgid "" +"One mouse wheel notch scrolls by this distance in screen pixels " +"(horizontally with Shift)" +msgstr "" +"Elke muiswiel-stap verschuift het beeld zoveel (houd shift ingedruktom " +"horizontaal te verschuiven)" + +#: ../../po/../src/dialogs/display-settings.cpp:920 +msgid "Ctrl+arrows" +msgstr "Ctrl-pijltjes toetsen" + +#: ../../po/../src/dialogs/display-settings.cpp:928 +msgid "Scroll by:" +msgstr "Verschuiven met:" + +#: ../../po/../src/dialogs/display-settings.cpp:929 +msgid "Pressing Ctrl+arrow key scrolls by this distance (in screen pixels)" +msgstr "Ctrl indrukken met een pijltjestoets verschuift zoveel beeldpunten" + +#: ../../po/../src/dialogs/display-settings.cpp:939 +msgid "Acceleration:" +msgstr "Versnelling:" + +#: ../../po/../src/dialogs/display-settings.cpp:940 +msgid "" +"Pressing and holding Ctrl+arrow will gradually speed up scrolling (0 for no " +"acceleration)" +msgstr "" +"Ctrl en een pijltjes toets ingedrukt houden zal versnellend verschuiven(0 " +"voor geen versnelling)" + +#: ../../po/../src/dialogs/display-settings.cpp:949 +msgid "Autoscrolling" +msgstr "Automatisch verschuiven" + +#: ../../po/../src/dialogs/display-settings.cpp:957 +msgid "Speed:" +msgstr "Snelheid:" + +#: ../../po/../src/dialogs/display-settings.cpp:958 +msgid "" +"How fast the canvas autoscrolls when you drag beyond canvas edge (0 to turn " +"autoscroll off)" +msgstr "" +"Hoe snel het canvas automatisch verschuift wanneer u voorbij de paginarand " +"sleept (0 om dit uit te schakelen)" + +#: ../../po/../src/dialogs/display-settings.cpp:968 +#: ../../po/../src/ui/dialog/tracedialog.cpp:357 +#: ../../po/../src/ui/dialog/tracedialog.cpp:390 +msgid "Threshold:" +msgstr "Grenswaarde:" + +#: ../../po/../src/dialogs/display-settings.cpp:969 +msgid "" +"How far (in screen pixels) you need to be from the canvas edge to trigger " +"autoscroll; positive is outside the canvas, negative is within the canvas" +msgstr "" +"Hoe ver de cursor van de canvasrand moet zijn verwijderd om het automatisch " +"verschuiven te activeren; positieve getallen voor buiten het canvas, " +"negatieve voor er binnen" + +#. Steps +#: ../../po/../src/dialogs/display-settings.cpp:979 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:57 +msgid "Steps" +msgstr "Stappen" + +#: ../../po/../src/dialogs/display-settings.cpp:982 +msgid "Arrow keys move by:" +msgstr "Pijltjes toetsen verschuiven met:" + +#: ../../po/../src/dialogs/display-settings.cpp:983 +msgid "" +"Pressing an arrow key moves selected object(s) or node(s) by this distance " +"(in px units)" +msgstr "" +"Een pijltjes toets indrukken verplaatst de geselecteerde objecten of " +"knooppunten zoveel (in pixels)" + +#: ../../po/../src/dialogs/display-settings.cpp:984 +#: ../../po/../src/dialogs/display-settings.cpp:995 +#: ../../po/../src/dialogs/display-settings.cpp:1006 +#: ../../po/../src/helper/units.cpp:42 +msgid "px" +msgstr "px" + +#: ../../po/../src/dialogs/display-settings.cpp:993 +msgid "> and < scale by:" +msgstr "> en < schalen met:" + +#: ../../po/../src/dialogs/display-settings.cpp:994 +msgid "" +"Pressing > or < scales selection up or down by this increment (in px units)" +msgstr "Op > of < drukken vergroot of verkleind de selectie met zoveel pixels" + +#: ../../po/../src/dialogs/display-settings.cpp:1004 +msgid "Inset/Outset by:" +msgstr "Binnen-/buitenrand met:" + +#: ../../po/../src/dialogs/display-settings.cpp:1005 +msgid "" +"Inset and Outset commands displace the path by this distance (in px units)" +msgstr "Binnen- en buitenrand opdrachten passen het pad aan met zoveel pixels" + +#: ../../po/../src/dialogs/display-settings.cpp:1017 +msgid "Compass-like display of angles" +msgstr "Hoeken weergeven als een kompas" + +#. TRANSLATORS: "positive clockwise" means "increasing in clockwise direction" +#: ../../po/../src/dialogs/display-settings.cpp:1019 +msgid "" +"When on, angles are displayed with 0 at north, 0 to 360 range, positive " +"clockwise; otherwise with 0 at east, -180 to 180 range, positive " +"counterclockwise" +msgstr "" +"Wanneer dit aan wijst 0 naar het noorden, en lopen hoeken van 0 tot 360 " +"graden met de klok mee. Wanneer dit uit staat wijst 0 naar het oosten, en " +"lopen hoeken van -180 tot 180 graden, tegen de klok in." + +#: ../../po/../src/dialogs/display-settings.cpp:1026 +msgid "Zoom in/out by:" +msgstr "In- en uitzoomen met:" + +#: ../../po/../src/dialogs/display-settings.cpp:1027 +msgid "" +"Zoom tool click, +/- keys, and middle click zoom in and out by this " +"multiplier" +msgstr "" +"Klikken op het vergrootglas, gebruik van de +/- toetsen en zoomen met de " +"middelste muisknop gebruiken deze factor." + +#: ../../po/../src/dialogs/display-settings.cpp:1028 +#: ../../po/../src/helper/units.cpp:44 +msgid "%" +msgstr "%" + +#. Tools +#: ../../po/../src/dialogs/display-settings.cpp:1037 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:58 +msgid "Tools" +msgstr "Gereedschappen" + +#: ../../po/../src/dialogs/display-settings.cpp:1045 +msgid "Selector" +msgstr "Selecteren" + +#: ../../po/../src/dialogs/display-settings.cpp:1056 +msgid "Node" +msgstr "Knooppunten" + +#: ../../po/../src/dialogs/display-settings.cpp:1064 +#: ../../po/../src/verbs.cpp:2073 +#: ../../po/../src/widgets/desktop-widget.cpp:277 +msgid "Zoom" +msgstr "Zoomen" + +#. The 4 shape tools +#: ../../po/../src/dialogs/display-settings.cpp:1071 +msgid "Shapes" +msgstr "Vormen" + +#: ../../po/../src/dialogs/display-settings.cpp:1079 +#: ../../po/../src/verbs.cpp:2055 +msgid "Rectangle" +msgstr "Rechthoek" + +#: ../../po/../src/dialogs/display-settings.cpp:1085 +#: ../../po/../src/verbs.cpp:2057 +msgid "Ellipse" +msgstr "Ellips" + +#: ../../po/../src/dialogs/display-settings.cpp:1091 +#: ../../po/../src/verbs.cpp:2059 +msgid "Star" +msgstr "Ster" + +#: ../../po/../src/dialogs/display-settings.cpp:1097 +#: ../../po/../src/verbs.cpp:2061 +msgid "Spiral" +msgstr "Spiraal" + +#: ../../po/../src/dialogs/display-settings.cpp:1111 +#: ../../po/../src/verbs.cpp:2063 +msgid "Pencil" +msgstr "Pen" + +#: ../../po/../src/dialogs/display-settings.cpp:1114 +msgid "Tolerance:" +msgstr "Tolerantie:" + +#: ../../po/../src/dialogs/display-settings.cpp:1115 +msgid "" +"This value affects the amount of smoothing applied to freehand lines; lower " +"values produce more uneven paths with more nodes" +msgstr "" +"Dit beinvloed de manier waarop lijnen uit de vrije hand worden afgerond; " +"lagere waarden leveren hoekerige lijnen op" + +#: ../../po/../src/dialogs/display-settings.cpp:1131 +#: ../../po/../src/verbs.cpp:2065 +msgid "Pen" +msgstr "Lijnen" + +#: ../../po/../src/dialogs/display-settings.cpp:1140 +#: ../../po/../src/verbs.cpp:2067 +msgid "Calligraphy" +msgstr "Kalligrafie" + +#: ../../po/../src/dialogs/display-settings.cpp:1147 +#: ../../po/../src/dialogs/text-edit.cpp:353 +#: ../../po/../src/ui/dialog/text-properties.cpp:37 +#: ../../po/../src/verbs.cpp:2069 +msgid "Text" +msgstr "Tekst" + +#: ../../po/../src/dialogs/display-settings.cpp:1157 +#: ../../po/../src/verbs.cpp:2071 +msgid "Gradient" +msgstr "Kleurverloop" + +#: ../../po/../src/dialogs/display-settings.cpp:1164 +#: ../../po/../src/verbs.cpp:2077 +msgid "Connector" +msgstr "Verbinder" + +#: ../../po/../src/dialogs/display-settings.cpp:1171 +#: ../../po/../src/verbs.cpp:2075 +msgid "Dropper" +msgstr "Pipet" + +#. Windows +#: ../../po/../src/dialogs/display-settings.cpp:1183 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:59 +msgid "Windows" +msgstr "Vensters" + +#: ../../po/../src/dialogs/display-settings.cpp:1188 +msgid "Save window geometry" +msgstr "Venster posities opslaan" + +#: ../../po/../src/dialogs/display-settings.cpp:1189 +msgid "" +"Save the window size and position with each document (only for Inkscape SVG " +"format)" +msgstr "" +"De positie en grootte van vensters opslaan bij elk document in Inkscape SVG-" +"formaat" + +#: ../../po/../src/dialogs/display-settings.cpp:1196 +msgid "Dialogs are hidden in taskbar" +msgstr "Dialogen zijn verborgen in de taakbalk" + +#: ../../po/../src/dialogs/display-settings.cpp:1197 +msgid "Whether dialog windows are to be hidden in the window manager taskbar" +msgstr "Verberg dialoogvensters in de taakbalk" + +#: ../../po/../src/dialogs/display-settings.cpp:1204 +msgid "Zoom when window is resized" +msgstr "Zoomen wanneer de venstergrootte verandert" + +#: ../../po/../src/dialogs/display-settings.cpp:1205 +msgid "" +"Zoom drawing when document window is resized, to keep the same area visible " +"(this is the default which can be changed in any window using the button " +"above the right scrollbar)" +msgstr "" +"In- of uitzoomen wanneer het venster van grootte verandert, om het zichtbare " +"gebied gelijk te houden (hier geeft u het standaard gedrag op; elk venster " +"heeft de mogelijkheid dit aan te passen boven de rechter schuifbalk)" + +#. Clones +#: ../../po/../src/dialogs/display-settings.cpp:1213 +#: ../../po/../src/dialogs/find.cpp:624 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:60 +msgid "Clones" +msgstr "Klonen" + +#: ../../po/../src/dialogs/display-settings.cpp:1217 +msgid "When the original moves, its clones and linked offsets:" +msgstr "Gedrag van klonen bij het verplaatsen van het origineel:" + +#: ../../po/../src/dialogs/display-settings.cpp:1229 +msgid "Move in parallel" +msgstr "Parallel mee verplaatsen" + +#: ../../po/../src/dialogs/display-settings.cpp:1230 +msgid "Clones are translated by the same vector as their original." +msgstr "Klonen worden op dezelfde manier verplaatst als het origineel." + +#: ../../po/../src/dialogs/display-settings.cpp:1237 +msgid "Stay unmoved" +msgstr "Laten staan" + +#: ../../po/../src/dialogs/display-settings.cpp:1238 +msgid "Clones preserve their positions when their original is moved." +msgstr "Klonen blijven op hun plek staan als het origineel wordt verplaatst." + +#: ../../po/../src/dialogs/display-settings.cpp:1245 +msgid "Move according to transform" +msgstr "Verplaatsen volgens transformatie" + +#: ../../po/../src/dialogs/display-settings.cpp:1246 +msgid "" +"Each clone moves according to the value of its transform= attribute. For " +"example, a rotated clone will move in a different direction than its " +"original." +msgstr "" +"Elke kloon verplaatst volgens zijn eigen 'transform='-waarde. Een gedraaide " +"kloon zal bijvoorbeeld in een andere richting verplaatsen dan zijn origineel." + +#: ../../po/../src/dialogs/display-settings.cpp:1255 +msgid "When the original is deleted, its clones:" +msgstr "Gedrag van klonen bij het verwijderen van het origineel:" + +#: ../../po/../src/dialogs/display-settings.cpp:1267 +msgid "Are unlinked" +msgstr "Ontkoppelen" + +#: ../../po/../src/dialogs/display-settings.cpp:1267 +msgid "Orphaned clones are converted to regular objects." +msgstr "Ontkoppelde klonen worden omgezet naar normale objecten" + +#: ../../po/../src/dialogs/display-settings.cpp:1273 +msgid "Are deleted" +msgstr "Verwijderen" + +#: ../../po/../src/dialogs/display-settings.cpp:1273 +msgid "Orphaned clones are deleted along with their original." +msgstr "Ontkoppelde klonen worden verwijderd samen met hun origineel" + +#. Transforms +#. TRANSLATORS: Noun, i.e. transformations. +#: ../../po/../src/dialogs/display-settings.cpp:1289 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:61 +msgid "Transforms" +msgstr "Transformaties" + +#: ../../po/../src/dialogs/display-settings.cpp:1292 +msgid "Scale stroke width" +msgstr "Lijndikte mee schalen" + +#: ../../po/../src/dialogs/display-settings.cpp:1293 +#: ../../po/../src/widgets/select-toolbar.cpp:568 +msgid "When scaling objects, scale the stroke width by the same proportion" +msgstr "" +"Wanneer objecten worden vergroot of verkleind, de lijndikte evenveel mee " +"vergroten of verkleinen" + +#: ../../po/../src/dialogs/display-settings.cpp:1300 +msgid "Scale rounded corners in rectangles" +msgstr "Afgeronding van hoeken mee schalen" + +#: ../../po/../src/dialogs/display-settings.cpp:1301 +#: ../../po/../src/widgets/select-toolbar.cpp:580 +msgid "When scaling rectangles, scale the radii of rounded corners" +msgstr "" +"Wanneer rechthoeken worden vergroot of verkleind, de straal van de hoek mee " +"vergroten of verkleinen" + +#: ../../po/../src/dialogs/display-settings.cpp:1308 +msgid "Transform gradients" +msgstr "Kleurverlopen transformeren" + +#: ../../po/../src/dialogs/display-settings.cpp:1309 +#: ../../po/../src/widgets/select-toolbar.cpp:592 +msgid "Transform gradients (in fill or stroke) along with the objects" +msgstr "Kleurverlopen (op lijnen of vlakken) mee transformeren met de objecten" + +#: ../../po/../src/dialogs/display-settings.cpp:1316 +msgid "Transform patterns" +msgstr "Patronen transformeren" + +#: ../../po/../src/dialogs/display-settings.cpp:1317 +#: ../../po/../src/widgets/select-toolbar.cpp:604 +msgid "Transform patterns (in fill or stroke) along with the objects" +msgstr "Patronen (op lijnen of vlakken) mee transformeren met de objecten" + +#. TRANSLATORS: How to specify the affine transformation in the SVG file. +#: ../../po/../src/dialogs/display-settings.cpp:1327 +msgid "Store transformation:" +msgstr "Transformaties opslaan:" + +#: ../../po/../src/dialogs/display-settings.cpp:1338 +msgid "Optimized" +msgstr "Optimaliseren" + +#: ../../po/../src/dialogs/display-settings.cpp:1339 +msgid "" +"If possible, apply transformation to objects without adding a transform= " +"attribute" +msgstr "" +"Pas, indien mogelijk, transformaties op objecten toe zonder een 'transform='-" +"waarde toe te voegen" + +#: ../../po/../src/dialogs/display-settings.cpp:1346 +msgid "Preserved" +msgstr "Behouden" + +#: ../../po/../src/dialogs/display-settings.cpp:1347 +msgid "Always store transformation as a transform= attribute on objects" +msgstr "" +"Transformaties altijd opslaan als een 'transform='-waarde bij objecten." + +#. Selecting +#: ../../po/../src/dialogs/display-settings.cpp:1355 +msgid "Selecting" +msgstr "Selecteren" + +#: ../../po/../src/dialogs/display-settings.cpp:1357 +msgid "Ctrl+A, Tab, Shift+Tab:" +msgstr "Ctrl+A, Tab, Shift+Tab:" + +#: ../../po/../src/dialogs/display-settings.cpp:1366 +msgid "Select only within current layer" +msgstr "Selecteren alleen binnen de huidige laag" + +#: ../../po/../src/dialogs/display-settings.cpp:1367 +msgid "" +"Uncheck this to make keyboard selection commands work on objects in all " +"layers" +msgstr "" +"Deselecteer dit om selecteer-opdrachten via het toetsenbord van toepassing " +"te laten zijn op alle objecten in alle lagen" + +#: ../../po/../src/dialogs/display-settings.cpp:1374 +msgid "Ignore hidden objects" +msgstr "Negeer verborgen objecten" + +#: ../../po/../src/dialogs/display-settings.cpp:1375 +msgid "" +"Uncheck this to be able to select objects that are hidden (either by " +"themselves or by being in a hidden group or layer)" +msgstr "" +"Deselecteer dit om objecten te kunnen selecteren die verborgen zijn (of die " +"in een verborgen groep of laag zitten)" + +#: ../../po/../src/dialogs/display-settings.cpp:1382 +msgid "Ignore locked objects" +msgstr "Negeer vergrendelde objecten" + +#: ../../po/../src/dialogs/display-settings.cpp:1383 +msgid "" +"Uncheck this to be able to select objects that are locked (either by " +"themselves or by being in a locked group or layer)" +msgstr "" +"Deselecteer dit om objecten te kunnen selecteren die vergrendeld zijn (of " +"die in een vergrendelde groep of laag zitten)" + +#. To be broken into: Display, Save, Export, SVG, Commands +#: ../../po/../src/dialogs/display-settings.cpp:1391 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:62 +msgid "Misc" +msgstr "Overig" + +#: ../../po/../src/dialogs/display-settings.cpp:1394 +msgid "Default export resolution:" +msgstr "Standaard resolutie voor exporteren:" + +#: ../../po/../src/dialogs/display-settings.cpp:1395 +msgid "Default bitmap resolution (in dots per inch) in the Export dialog" +msgstr "" +"Standaard resolutie voor bitmaps (in punten per inch) in het 'Bitmap " +"exporteren' dialoogvenster" + +#. FIXME: add "Used for new exports; once exported, documents remember this value on per-object basis" when implemented +#: ../../po/../src/dialogs/display-settings.cpp:1396 +#: ../../po/../src/dialogs/export.cpp:442 +msgid "dpi" +msgstr "dpi" + +#. TRANSLATORS: When on, an imported bitmap creates an element; otherwise it is a +#. * rectangle with bitmap fill. +#: ../../po/../src/dialogs/display-settings.cpp:1407 +msgid "Import bitmap as " +msgstr "Bitmaps in het document importeren als -element" + +#: ../../po/../src/dialogs/display-settings.cpp:1408 +msgid "" +"When on, an imported bitmap creates an element; otherwise it is a " +"rectangle with bitmap fill" +msgstr "" +"Wanneer geselecteerd wordt voor geïmporteerde bitmaps een -element " +"aangemaakt; anders wordt het een rechthoek met een bitmap-vulling" + +#. TRANSLATORS: When on, the print out (currently Postscript) will have +#. * a comment with the each object's label visible, marking the section +#. * of the printing commands that represent the given object. +#: ../../po/../src/dialogs/display-settings.cpp:1418 +msgid "Add label comments to printing output" +msgstr "Commentaar-velden toevoegen aan printer-uitvoer" + +#: ../../po/../src/dialogs/display-settings.cpp:1419 +msgid "" +"When on, a comment will be added to the raw print output, marking the " +"rendered output for an object with its label" +msgstr "" +"Wanneer geselecteerd zal commentaar worden toegevoegd aan de afdruk, waar " +"het label van een object in staat vermeld." + +#. TRANSLATORS: When on, enable the effects menu, default is off +#: ../../po/../src/dialogs/display-settings.cpp:1427 +msgid "Enable script effects (requires restart) - EXPERIMENTAL" +msgstr "Script-effecten inschakelen (herstart noodzakelijk) - EXPERIMENTEEL" + +#: ../../po/../src/dialogs/display-settings.cpp:1428 +msgid "" +"When on, the effects menu is enabled, allowing external effect scripts to be " +"called, requires restart before effective - EXPERIMENTAL" +msgstr "" +"Wanneer geselecteerd wordt het effecten-menu actief, wat het gebruik van " +"externe script-effecten mogelijk maakt. Inkscape moet opnieuw gestart worden " +"voordat dit werkt - EXPERIMENTEEL" + +#. TRANSLATORS: The maximum length of the Open Recent list in the File menu. +#: ../../po/../src/dialogs/display-settings.cpp:1436 +msgid "Max recent documents:" +msgstr "Maximum aantal te onthouden recente bestanden:" + +#: ../../po/../src/dialogs/display-settings.cpp:1437 +msgid "The maximum length of the Open Recent list in the File menu" +msgstr "" +"Het maximum aantal bestandsnamen in 'Recente bestanden' in het 'Bestand'-menu" + +#: ../../po/../src/dialogs/display-settings.cpp:1447 +msgid "Simplification threshold:" +msgstr "Simplificatie grenswaarde:" + +#: ../../po/../src/dialogs/display-settings.cpp:1448 +msgid "" +"How strong is the Simplify command by default. If you invoke this command " +"several times in quick succession, it will act more and more aggressively; " +"invoking it again after a pause restores the default threshold." +msgstr "" +"Hoe sterk de 'vereenvoudigen' opdracht is. Als u deze opdracht enkele malen " +"vlak na elkaar uitvoert, zal dat steeds meer effect hebben; na een korte " +"pauze wordt de standaard grenswaarde hersteld." + +#: ../../po/../src/dialogs/display-settings.cpp:1469 +msgid "Oversample bitmaps:" +msgstr "Bitmaps oversampelen:" + +#: ../../po/../src/dialogs/display-settings.cpp:1488 +msgid "2x2" +msgstr "2x2" + +#: ../../po/../src/dialogs/display-settings.cpp:1494 +msgid "4x4" +msgstr "4x4" + +#: ../../po/../src/dialogs/display-settings.cpp:1500 +msgid "8x8" +msgstr "8x8" + +#: ../../po/../src/dialogs/display-settings.cpp:1506 +msgid "16x16" +msgstr "16x16" + +#. "view_icon_preview" +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2143 +msgid "_Page" +msgstr "_Pagina" + +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2147 +msgid "_Drawing" +msgstr "_Tekening" + +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2149 +msgid "_Selection" +msgstr "_Selectie" + +#: ../../po/../src/dialogs/export.cpp:133 +msgid "_Custom" +msgstr "_Aangepast" + +#: ../../po/../src/dialogs/export.cpp:254 +msgid "Export area" +msgstr "Gebied exporteren" + +#: ../../po/../src/dialogs/export.cpp:300 +msgid "_x0:" +msgstr "_x0:" + +#: ../../po/../src/dialogs/export.cpp:305 +msgid "x_1:" +msgstr "x_1:" + +#: ../../po/../src/dialogs/export.cpp:316 +msgid "_y0:" +msgstr "_y0:" + +#: ../../po/../src/dialogs/export.cpp:321 +msgid "y_1:" +msgstr "y_1:" + +#: ../../po/../src/dialogs/export.cpp:406 +msgid "Bitmap size" +msgstr "Bitmap afmeting" + +#: ../../po/../src/dialogs/export.cpp:416 +msgid "_Width:" +msgstr "_Breedte:" + +#: ../../po/../src/dialogs/export.cpp:416 +#: ../../po/../src/dialogs/export.cpp:431 +msgid "pixels at" +msgstr "beeldpunten bij" + +#: ../../po/../src/dialogs/export.cpp:426 +msgid "dp_i" +msgstr "dp_i" + +#: ../../po/../src/dialogs/export.cpp:448 +msgid "_Filename" +msgstr "_Bestandsnaam" + +#: ../../po/../src/dialogs/export.cpp:512 +msgid "_Browse..." +msgstr "_Bladeren..." + +#: ../../po/../src/dialogs/export.cpp:539 +msgid " _Export " +msgstr "_Exporteren" + +#: ../../po/../src/dialogs/export.cpp:541 +msgid "Export the bitmap file with these settings" +msgstr "Exporteren naar een bitmap-afbeelding met deze instellingen" + +#: ../../po/../src/dialogs/export.cpp:968 +msgid "You have to enter a filename" +msgstr "Vul alstublieft een bestandsnaam in" + +#: ../../po/../src/dialogs/export.cpp:973 +msgid "The chosen area to be exported is invalid" +msgstr "Het geselecteerde gebied is ongeldig voor exporten" + +#: ../../po/../src/dialogs/export.cpp:982 +#, c-format +msgid "Directory %s does not exist or is not a directory.\n" +msgstr "Map %s bestaat niet of is geen map.\n" + +#: ../../po/../src/dialogs/export.cpp:998 +msgid "Export in progress" +msgstr "Bezig met exporteren" + +#: ../../po/../src/dialogs/export.cpp:1004 +#, c-format +msgid "Exporting %s (%d x %d)" +msgstr "Bezig met exporteren %s (%d x %d)" + +#: ../../po/../src/dialogs/export.cpp:1031 +#, c-format +msgid "Could not export to filename %s.\n" +msgstr "Fout bij het exporteren naar bestand %s.\n" + +#: ../../po/../src/dialogs/export.cpp:1137 +msgid "Select a filename for exporting" +msgstr "Selecteer een bestandsnaam om naar exporteren" + +#: ../../po/../src/dialogs/filedialog.cpp:367 +msgid "No preview" +msgstr "Geen voorbeeld" + +#: ../../po/../src/dialogs/filedialog.cpp:468 +msgid "too large for preview" +msgstr "Te groot voor een voorbeeld" + +#: ../../po/../src/dialogs/filedialog.cpp:762 +#: ../../po/../src/dialogs/filedialog.cpp:763 +msgid "All Images" +msgstr "Alle afbeeldingen" + +#: ../../po/../src/dialogs/filedialog.cpp:767 +#: ../../po/../src/dialogs/filedialog.cpp:768 +msgid "All Files" +msgstr "Alle bestanden" + +#: ../../po/../src/dialogs/filedialog.cpp:774 +#: ../../po/../src/dialogs/filedialog.cpp:775 +msgid "All Inkscape Files" +msgstr "Alle Inkscape bestanden" + +#: ../../po/../src/dialogs/filedialog.cpp:1176 +msgid "Guess from extension" +msgstr "Kies op basis van extentie" + +#. ###### Add the file types menu +#. createFilterMenu(); +#. ###### Do we want the .xxx extension automatically added? +#: ../../po/../src/dialogs/filedialog.cpp:1261 +msgid "Append filename extension automatically" +msgstr "Automatisch de bestandsnaam extensie toevoegen" + +#. TRANSLATORS: "%s" is replaced with "exact" or "partial" when this string is displayed +#: ../../po/../src/dialogs/find.cpp:378 +#, fuzzy, c-format +msgid "%d object found (out of %d), %s match." +msgid_plural "%d objects found (out of %d), %s match." +msgstr[0] "%d objecten gevonden (van %d), %s overeenkomst" +msgstr[1] "%d objecten gevonden (van %d), %s overeenkomst" + +#: ../../po/../src/dialogs/find.cpp:381 +msgid "exact" +msgstr "precieze" + +#: ../../po/../src/dialogs/find.cpp:381 +msgid "partial" +msgstr "gedeeltelijke" + +#: ../../po/../src/dialogs/find.cpp:388 +msgid "No objects found" +msgstr "Geen objecten gevonden" + +#: ../../po/../src/dialogs/find.cpp:546 +msgid "T_ype: " +msgstr "S_oort:" + +#: ../../po/../src/dialogs/find.cpp:553 +msgid "Search in all object types" +msgstr "Doorzoek alle soorten objecten" + +#: ../../po/../src/dialogs/find.cpp:553 +msgid "All types" +msgstr "Alle soorten" + +#: ../../po/../src/dialogs/find.cpp:564 +msgid "Search all shapes" +msgstr "Doorzoek alle vormen" + +#: ../../po/../src/dialogs/find.cpp:564 +msgid "All shapes" +msgstr "Alle vormen" + +#: ../../po/../src/dialogs/find.cpp:581 +msgid "Search rectangles" +msgstr "Doorzoek rechthoeken" + +#: ../../po/../src/dialogs/find.cpp:581 +msgid "Rectangles" +msgstr "Rechthoeken" + +#: ../../po/../src/dialogs/find.cpp:586 +msgid "Search ellipses, arcs, circles" +msgstr "Doorzoek ellipsen, veelhoeken en cirkels." + +#: ../../po/../src/dialogs/find.cpp:586 +msgid "Ellipses" +msgstr "Ellipsen" + +#: ../../po/../src/dialogs/find.cpp:591 +msgid "Search stars and polygons" +msgstr "Doorzoek sterren en veelhoeken" + +#: ../../po/../src/dialogs/find.cpp:591 +msgid "Stars" +msgstr "Sterren" + +#: ../../po/../src/dialogs/find.cpp:596 +msgid "Search spirals" +msgstr "Doorzoek spiralen" + +#: ../../po/../src/dialogs/find.cpp:596 +msgid "Spirals" +msgstr "Spiralen" + +#. TRANSLATORS: polyline is a set of connected straight line segments +#. http://www.w3.org/TR/SVG11/shapes.html#PolylineElement +#: ../../po/../src/dialogs/find.cpp:609 +msgid "Search paths, lines, polylines" +msgstr "Doorzoek paden, lijnen en poly-lijnen" + +#: ../../po/../src/dialogs/find.cpp:609 +msgid "Paths" +msgstr "Paden" + +#: ../../po/../src/dialogs/find.cpp:614 +msgid "Search text objects" +msgstr "Doorzoek tekst-objecten" + +#: ../../po/../src/dialogs/find.cpp:614 +msgid "Texts" +msgstr "Tekst" + +#: ../../po/../src/dialogs/find.cpp:619 +msgid "Search groups" +msgstr "Doorzoek groepen" + +#: ../../po/../src/dialogs/find.cpp:619 +msgid "Groups" +msgstr "Groepen" + +#: ../../po/../src/dialogs/find.cpp:624 +msgid "Search clones" +msgstr "Doorzoek klonen" + +#: ../../po/../src/dialogs/find.cpp:629 +msgid "Search images" +msgstr "Doorzoek afbeeldingen" + +#: ../../po/../src/dialogs/find.cpp:629 +msgid "Images" +msgstr "Afbeeldingen" + +#: ../../po/../src/dialogs/find.cpp:634 +msgid "Search offset objects" +msgstr "Rand-objecten zoeken" + +#: ../../po/../src/dialogs/find.cpp:634 +msgid "Offsets" +msgstr "Randen" + +#: ../../po/../src/dialogs/find.cpp:694 +msgid "_Text: " +msgstr "_Tekst:" + +#: ../../po/../src/dialogs/find.cpp:694 +msgid "Find objects by their text content (exact or partial match)" +msgstr "" +"Zoek objecten op hun tekst inhoud (precieze of gedeeltelijke overeenkomst)" + +#: ../../po/../src/dialogs/find.cpp:695 +msgid "_ID: " +msgstr "_ID:" + +#: ../../po/../src/dialogs/find.cpp:695 +msgid "Find objects by the value of the id attribute (exact or partial match)" +msgstr "" +"Zoek objecten op naam of op het ID-attribuut (precieze of gedeeltelijke " +"overeenkomst)" + +#: ../../po/../src/dialogs/find.cpp:696 +msgid "_Style: " +msgstr "_Stijl:" + +#: ../../po/../src/dialogs/find.cpp:696 +msgid "" +"Find objects by the value of the style attribute (exact or partial match)" +msgstr "" +"Zoek objecten op naam of op het stijl-attribuut (precieze of gedeeltelijke " +"overeenkomst)" + +#: ../../po/../src/dialogs/find.cpp:697 +msgid "_Attribute: " +msgstr "_Attribuut:" + +#: ../../po/../src/dialogs/find.cpp:697 +msgid "Find objects by the name of an attribute (exact or partial match)" +msgstr "" +"Zoek objecten op naam of op attribuut (precieze of gedeeltelijke " +"overeenkomst)" + +#: ../../po/../src/dialogs/find.cpp:711 +msgid "Search in s_election" +msgstr "Doorzoek de s_electie" + +#: ../../po/../src/dialogs/find.cpp:715 +msgid "Limit search to the current selection" +msgstr "Beperk het zoeken tot de selectie" + +#: ../../po/../src/dialogs/find.cpp:720 +msgid "Search in current _layer" +msgstr "Doorzoek de huidige _laag" + +#: ../../po/../src/dialogs/find.cpp:724 +msgid "Limit search to the current layer" +msgstr "Beperk het zoeken tot de huidige laag" + +#: ../../po/../src/dialogs/find.cpp:729 +msgid "Include _hidden" +msgstr "Doorzoek ver_borgen objecten" + +#: ../../po/../src/dialogs/find.cpp:733 +msgid "Include hidden objects in search" +msgstr "Doorzoek ook verborgen objecten" + +#: ../../po/../src/dialogs/find.cpp:738 +msgid "Include l_ocked" +msgstr "Doorzoek ver_grendelde objecten" + +#: ../../po/../src/dialogs/find.cpp:742 +msgid "Include locked objects in search" +msgstr "Doorzoek ook vergrendelde objecten" + +#: ../../po/../src/dialogs/find.cpp:753 +msgid "Clear values" +msgstr "Maak alle invoervelden leeg om een nieuwe zoekopdracht te beginnen" + +#: ../../po/../src/dialogs/find.cpp:754 +msgid "_Find" +msgstr "_Zoeken" + +#: ../../po/../src/dialogs/find.cpp:754 +msgid "Select objects matching all of the fields you filled in" +msgstr "Selecteer alle objecten met de hierboven ingevulde eigenschappen" + +#: ../../po/../src/dialogs/iconpreview.cpp:145 +#, c-format +msgid "%d x %d" +msgstr "%d x %d" + +#: ../../po/../src/dialogs/iconpreview.cpp:193 +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:857 +#: ../../po/../src/widgets/desktop-widget.cpp:1069 +msgid "Selection" +msgstr "Selectie" + +#: ../../po/../src/dialogs/iconpreview.cpp:195 +msgid "Selection only or whole document" +msgstr "Alleen selectie of gehele document" + +#: ../../po/../src/dialogs/iconpreview.cpp:203 +msgid "Refresh the icons" +msgstr "De pictogrammen verversen" + +#. Create the label for the object id +#: ../../po/../src/dialogs/item-properties.cpp:126 +#: ../../po/../src/dialogs/item-properties.cpp:327 +#: ../../po/../src/dialogs/item-properties.cpp:396 +#: ../../po/../src/dialogs/item-properties.cpp:403 +msgid "_Id" +msgstr "_ID" + +#: ../../po/../src/dialogs/item-properties.cpp:135 +msgid "" +"The id= attribute (only letters, digits, and the characters .-_: allowed)" +msgstr "" +"Het 'id='-attribuut (alleen letters, cijfers en de tekens .-_: zijn " +"toegestaan)" + +#. Button for setting the object's id, label, title and description. +#: ../../po/../src/dialogs/item-properties.cpp:149 +msgid "_Set" +msgstr "_Instellen" + +#. Create the label for the object label +#: ../../po/../src/dialogs/item-properties.cpp:158 +msgid "_Label" +msgstr "_Label" + +#: ../../po/../src/dialogs/item-properties.cpp:167 +msgid "A freeform label for the object" +msgstr "Een vrij te kiezen label" + +#. Create the label for the object title +#: ../../po/../src/dialogs/item-properties.cpp:179 +#: ../../po/../src/dialogs/rdf.cpp:243 +msgid "Title" +msgstr "Titel" + +#. Create the frame for the object description +#: ../../po/../src/dialogs/item-properties.cpp:196 +#: ../../po/../src/dialogs/rdf.cpp:287 +msgid "Description" +msgstr "Beschrijving" + +#. Hide +#: ../../po/../src/dialogs/item-properties.cpp:223 +msgid "_Hide" +msgstr "_Verbergen" + +#: ../../po/../src/dialogs/item-properties.cpp:224 +msgid "Check to make the object invisible" +msgstr "Selecteer dit om het object onzichtbaar te maken" + +#. Lock +#. TRANSLATORS: "Lock" is a verb here +#: ../../po/../src/dialogs/item-properties.cpp:233 +msgid "L_ock" +msgstr "Ver_grendelen" + +#: ../../po/../src/dialogs/item-properties.cpp:234 +msgid "Check to make the object insensitive (not selectable by mouse)" +msgstr "" +"Selecteer dit om het object ongevoelig te maken (niet selecteerbaar met de " +"muis)" + +#: ../../po/../src/dialogs/item-properties.cpp:310 +#: ../../po/../src/dialogs/item-properties.cpp:317 +msgid "Ref" +msgstr "Referentie" + +#: ../../po/../src/dialogs/item-properties.cpp:398 +msgid "Id invalid! " +msgstr "Ongeldig ID!" + +#: ../../po/../src/dialogs/item-properties.cpp:400 +msgid "Id exists! " +msgstr "ID bestaat al!" + +#: ../../po/../src/dialogs/layer-properties.cpp:50 +msgid "Layer name:" +msgstr "Naam van de laag:" + +#: ../../po/../src/dialogs/layer-properties.cpp:133 +msgid "Rename Layer" +msgstr "Laag hernoemen" + +#: ../../po/../src/dialogs/layer-properties.cpp:136 +msgid "_Rename" +msgstr "_Hernoemen" + +#. TRANSLATORS: This means "The layer has been renamed" +#: ../../po/../src/dialogs/layer-properties.cpp:147 +msgid "Renamed layer" +msgstr "De laag is hernoemd" + +#: ../../po/../src/dialogs/layer-properties.cpp:151 +msgid "Add Layer" +msgstr "Laag toevoegen" + +#: ../../po/../src/dialogs/layer-properties.cpp:153 +msgid "_Add" +msgstr "_Toevoegen" + +#: ../../po/../src/dialogs/layer-properties.cpp:167 +msgid "New layer created." +msgstr "De nieuwe laag is gemaakt." + +#: ../../po/../src/dialogs/object-attributes.cpp:34 +msgid "Href:" +msgstr "Href:" + +#: ../../po/../src/dialogs/object-attributes.cpp:35 +msgid "Target:" +msgstr "Doel:" + +#: ../../po/../src/dialogs/object-attributes.cpp:36 +msgid "Type:" +msgstr "Type:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkRoleAttribute +#. Identifies the type of the related resource with an absolute URI +#: ../../po/../src/dialogs/object-attributes.cpp:39 +msgid "Role:" +msgstr "Rol:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkArcRoleAttribute +#. For situations where the nature/role alone isn't enough, this offers an additional URI defining the purpose of the link. +#: ../../po/../src/dialogs/object-attributes.cpp:42 +#, fuzzy +msgid "Arcrole:" +msgstr "Arcrole:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkTitleAttribute +#: ../../po/../src/dialogs/object-attributes.cpp:44 +msgid "Title:" +msgstr "Titel:" + +#: ../../po/../src/dialogs/object-attributes.cpp:45 +msgid "Show:" +msgstr "Tonen:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkActuateAttribute +#: ../../po/../src/dialogs/object-attributes.cpp:47 +msgid "Actuate:" +msgstr "Nauwkeurigheid:" + +#: ../../po/../src/dialogs/object-attributes.cpp:52 +msgid "URL:" +msgstr "URL:" + +#: ../../po/../src/dialogs/object-attributes.cpp:53 +msgid "X:" +msgstr "X:" + +#: ../../po/../src/dialogs/object-attributes.cpp:54 +msgid "Y:" +msgstr "Y:" + +#: ../../po/../src/dialogs/object-attributes.cpp:98 +#, c-format +msgid "%s attributes" +msgstr "%s eigenschappen" + +#: ../../po/../src/dialogs/object-properties.cpp:158 +msgid "_Fill" +msgstr "_Vullen" + +#: ../../po/../src/dialogs/object-properties.cpp:165 +msgid "Stroke _paint" +msgstr "_Lijnkleur" + +#: ../../po/../src/dialogs/object-properties.cpp:172 +msgid "Stroke st_yle" +msgstr "Lijn_stijl" + +#: ../../po/../src/dialogs/object-properties.cpp:183 +msgid "Master _opacity" +msgstr "Hoofd-_ondoorzichtigheid" + +#: ../../po/../src/dialogs/rdf.cpp:244 +msgid "Name by which this document is formally known." +msgstr "De naam waaronder dit document ook wel bekend is" + +#: ../../po/../src/dialogs/rdf.cpp:246 +msgid "Date" +msgstr "Datum" + +#: ../../po/../src/dialogs/rdf.cpp:247 +msgid "Date associated with the creation of this document (YYYY-MM-DD)." +msgstr "Datum waarop dit document is aangemaakt (JJJJ-MM-DD)" + +#: ../../po/../src/dialogs/rdf.cpp:249 +msgid "Format" +msgstr "Formaat" + +#: ../../po/../src/dialogs/rdf.cpp:250 +msgid "The physical or digital manifestation of this document (MIME type)." +msgstr "De fysieke of digitale verschijningsvorm van dit document (MIME-type)" + +#: ../../po/../src/dialogs/rdf.cpp:252 +msgid "Type" +msgstr "Type" + +#: ../../po/../src/dialogs/rdf.cpp:253 +msgid "Type of document (DCMI Type)." +msgstr "Document type (DCMI type)." + +#: ../../po/../src/dialogs/rdf.cpp:256 +msgid "Creator" +msgstr "Ontwerper" + +#: ../../po/../src/dialogs/rdf.cpp:257 +msgid "" +"Name of entity primarily responsible for making the content of this document." +msgstr "Naam van de eindverantwoordelijke van dit document." + +#: ../../po/../src/dialogs/rdf.cpp:259 +msgid "Rights" +msgstr "Rechten" + +#: ../../po/../src/dialogs/rdf.cpp:260 +msgid "" +"Name of entity with rights to the Intellectual Property of this document." +msgstr "Naam van degene die het Intellectueel Eigendom van dit document bezit." + +#: ../../po/../src/dialogs/rdf.cpp:262 +msgid "Publisher" +msgstr "Uitgever" + +#: ../../po/../src/dialogs/rdf.cpp:263 +msgid "Name of entity responsible for making this document available." +msgstr "" +"Naam van de instantie die verantwoordelijk is voor publicatie van dit " +"document." + +#: ../../po/../src/dialogs/rdf.cpp:266 +msgid "Identifier" +msgstr "Identificatie" + +#: ../../po/../src/dialogs/rdf.cpp:267 +msgid "Unique URI to reference this document." +msgstr "Een uniek URI voor referentie naar dit document." + +#: ../../po/../src/dialogs/rdf.cpp:269 +msgid "Source" +msgstr "Bron" + +#: ../../po/../src/dialogs/rdf.cpp:270 +msgid "Unique URI to reference the source of this document." +msgstr "Een uniek URI voor referentie naar de bron van dit document." + +#: ../../po/../src/dialogs/rdf.cpp:272 +msgid "Relation" +msgstr "Gerelateerd aan" + +#: ../../po/../src/dialogs/rdf.cpp:273 +msgid "Unique URI to a related document." +msgstr "Een uniek URI naar een gerelateerd document." + +#: ../../po/../src/dialogs/rdf.cpp:275 +msgid "Language" +msgstr "Taal" + +#: ../../po/../src/dialogs/rdf.cpp:276 +msgid "" +"Two-letter language tag with optional subtags for the language of this " +"document. (e.g. 'en-GB')" +msgstr "" +"Een twee-letterige aanduiding (met optionele sub-aanduiding) voor de taal " +"van dit document (bv. 'nl-NL')." + +#: ../../po/../src/dialogs/rdf.cpp:278 +msgid "Keywords" +msgstr "Sleutelwoorden" + +#: ../../po/../src/dialogs/rdf.cpp:279 +msgid "" +"The topic of this document as comma-separated key words, phrases, or " +"classifications." +msgstr "" +"Het onderwerp van dit document als losse woorden of zinnen, gescheiden door " +"komma's." + +#. TRANSLATORS: "Coverage": the spatial or temporal characteristics of the content. +#. For info, see Appendix D of http://www.w3.org/TR/1998/WD-rdf-schema-19980409/ +#: ../../po/../src/dialogs/rdf.cpp:283 +msgid "Coverage" +msgstr "Dekking" + +#: ../../po/../src/dialogs/rdf.cpp:284 +msgid "Extent or scope of this document." +msgstr "Dekking of lading van dit document." + +#: ../../po/../src/dialogs/rdf.cpp:288 +msgid "A short account of the content of this document." +msgstr "Een korte samenvatting van de samenvatting van dit document." + +#. FIXME: need to handle 1 agent per line of input +#: ../../po/../src/dialogs/rdf.cpp:292 +msgid "Contributors" +msgstr "Met dank aan" + +#: ../../po/../src/dialogs/rdf.cpp:293 +msgid "" +"Names of entities responsible for making contributions to the content of " +"this document." +msgstr "" +"Naam van degenen die bijdragen hebben geleverd aan de inhoud van dit " +"document." + +#. TRANSLATORS: URL to a page that defines the license for the document +#: ../../po/../src/dialogs/rdf.cpp:297 +msgid "URI" +msgstr "URI" + +#. TRANSLATORS: this is where you put a URL to a page that defines the license +#: ../../po/../src/dialogs/rdf.cpp:299 +msgid "URI to this document's license's namespace definition." +msgstr "URI naar de namespace-definitie van de licentie van dit document" + +#. TRANSLATORS: fragment of XML representing the license of the document +#: ../../po/../src/dialogs/rdf.cpp:303 +msgid "Fragment" +msgstr "Onderdeel" + +#: ../../po/../src/dialogs/rdf.cpp:304 +msgid "XML fragment for the RDF 'License' section." +msgstr "XML onderdeel voor het RDF 'licentie'-deel." + +#: ../../po/../src/dialogs/stroke-style.cpp:774 +#: ../../po/../src/widgets/gradient-vector.cpp:263 +#: ../../po/../src/widgets/paint-selector.cpp:751 +msgid "No document selected" +msgstr "Geen document geselecteerd" + +#: ../../po/../src/dialogs/stroke-style.cpp:992 +msgid "Stroke width" +msgstr "Lijn breedte" + +#. Join type +#. TRANSLATORS: The line join style specifies the shape to be used at the +#. corners of paths. It can be "miter", "round" or "bevel". +#: ../../po/../src/dialogs/stroke-style.cpp:1015 +msgid "Join:" +msgstr "Samenvoegen:" + +#. TRANSLATORS: Miter join: joining lines with a sharp (pointed) corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1027 +msgid "Miter join" +msgstr "Scherpe hoek" + +#. TRANSLATORS: Round join: joining lines with a rounded corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1035 +msgid "Round join" +msgstr "Afgeronde hoek" + +#. TRANSLATORS: Bevel join: joining lines with a blunted (flattened) corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1043 +msgid "Bevel join" +msgstr "Platte hoek" + +#. Miterlimit +#. TRANSLATORS: Miter limit: only for "miter join", this limits the length +#. of the sharp "spike" when the lines connect at too sharp an angle. +#. When two line segments meet at a sharp angle, a miter join results in a +#. spike that extends well beyond the connection point. The purpose of the +#. miter limit is to cut off such spikes (i.e. convert them into bevels) +#. when they become too long. +#: ../../po/../src/dialogs/stroke-style.cpp:1054 +msgid "Miter limit:" +msgstr "Hoek limiet:" + +#: ../../po/../src/dialogs/stroke-style.cpp:1062 +msgid "Maximum length of the miter (in units of stroke width)" +msgstr "" +"Maximale lengte van de punt die kan ontstaan bij scherpe hoeken (aantal maal " +"de lijn breedte)" + +#. Cap type +#. TRANSLATORS: cap type specifies the shape for the ends of lines +#: ../../po/../src/dialogs/stroke-style.cpp:1075 +msgid "Cap:" +msgstr "Uiteinde:" + +#. TRANSLATORS: Butt cap: the line shape does not extend beyond the end point +#. of the line; the ends of the line are square +#: ../../po/../src/dialogs/stroke-style.cpp:1086 +msgid "Butt cap" +msgstr "Afgekapt einde" + +#. TRANSLATORS: Round cap: the line shape extends beyond the end point of the +#. line; the ends of the line are rounded +#: ../../po/../src/dialogs/stroke-style.cpp:1093 +msgid "Round cap" +msgstr "Rond einde" + +#. TRANSLATORS: Square cap: the line shape extends beyond the end point of the +#. line; the ends of the line are square +#: ../../po/../src/dialogs/stroke-style.cpp:1100 +msgid "Square cap" +msgstr "Vierkant einde" + +#. Dash +#: ../../po/../src/dialogs/stroke-style.cpp:1106 +msgid "Dashes:" +msgstr "Markering:" + +#. TRANSLATORS: Path markers are an SVG feature that allows you to attach arbitrary shapes +#. (arrowheads, bullets, faces, whatever) to the start, end, or middle nodes of a path. +#: ../../po/../src/dialogs/stroke-style.cpp:1127 +msgid "Start Markers:" +msgstr "Begin markering:" + +#: ../../po/../src/dialogs/stroke-style.cpp:1137 +msgid "Mid Markers:" +msgstr "Midden markering:" + +#: ../../po/../src/dialogs/stroke-style.cpp:1148 +msgid "End Markers:" +msgstr "Eind markering:" + +#: ../../po/../src/dialogs/swatches.cpp:424 +#, c-format +msgid "Palettes directory (%s) is unavailable." +msgstr "De map met paletten (%s) is niet beschikbaar." + +#. TODO: Insert widgets +#: ../../po/../src/dialogs/text-edit.cpp:199 +#: ../../po/../src/ui/dialog/text-properties.cpp:36 +msgid "Font" +msgstr "Lettertype" + +#: ../../po/../src/dialogs/text-edit.cpp:216 +msgid "Layout" +msgstr "Uitlijnen en verdelen" + +#: ../../po/../src/dialogs/text-edit.cpp:229 +msgid "Align lines left" +msgstr "Regels links uitlijnen" + +#. TRANSLATORS: `Center' here is a verb. +#: ../../po/../src/dialogs/text-edit.cpp:243 +msgid "Center lines" +msgstr "Regels centreren" + +#: ../../po/../src/dialogs/text-edit.cpp:256 +msgid "Align lines right" +msgstr "Regels rechts uitlijnen" + +#: ../../po/../src/dialogs/text-edit.cpp:278 +msgid "Horizontal text" +msgstr "Horizontale tekst" + +#: ../../po/../src/dialogs/text-edit.cpp:292 +msgid "Vertical text" +msgstr "Verticale tekst" + +#: ../../po/../src/dialogs/text-edit.cpp:307 +msgid "Line spacing:" +msgstr "Regelafstand:" + +#: ../../po/../src/dialogs/text-edit.cpp:400 +msgid "Set as default" +msgstr "Instellen als standaard" + +#: ../../po/../src/dialogs/tiledialog.cpp:603 +msgid "Rows:" +msgstr "Rijen:" + +#: ../../po/../src/dialogs/tiledialog.cpp:613 +msgid "Number of rows" +msgstr "Aantal rijen" + +#: ../../po/../src/dialogs/tiledialog.cpp:617 +msgid "Equal height" +msgstr "Gelijke hoogte" + +#: ../../po/../src/dialogs/tiledialog.cpp:627 +msgid "If not set, each row has the height of the tallest object in it" +msgstr "" +"Wanneer niet ingesteld, krijgt elke rij de hoogte van het hoogste object erin" + +#. #### Radio buttons to control vertical alignment #### +#. #### Radio buttons to control horizontal alignment #### +#: ../../po/../src/dialogs/tiledialog.cpp:637 +#: ../../po/../src/dialogs/tiledialog.cpp:708 +msgid "Align:" +msgstr "Uitlijnen:" + +#: ../../po/../src/dialogs/tiledialog.cpp:672 +msgid " X " +msgstr " X " + +#. #### Number of columns #### +#: ../../po/../src/dialogs/tiledialog.cpp:678 +msgid "Columns:" +msgstr "Kolommen:" + +#: ../../po/../src/dialogs/tiledialog.cpp:688 +msgid "Number of columns" +msgstr "Aantal kolommen" + +#: ../../po/../src/dialogs/tiledialog.cpp:692 +msgid "Equal width" +msgstr "Gelijke breedte" + +#: ../../po/../src/dialogs/tiledialog.cpp:701 +msgid "If not set, each column has the width of the widest object in it" +msgstr "" +"Wanneer niet ingesteld, krijgt elke kolom de breedte van het breedste object " +"erin" + +#. #### Radio buttons to control spacing manually or to fit selection bbox #### +#: ../../po/../src/dialogs/tiledialog.cpp:746 +msgid "Fit into selection box" +msgstr "In selectie-box passen" + +#: ../../po/../src/dialogs/tiledialog.cpp:753 +msgid "Set spacing:" +msgstr "Tussen afstand:" + +#. #### Y Padding #### +#: ../../po/../src/dialogs/tiledialog.cpp:777 +msgid "Row spacing: " +msgstr "Rij afstand:" + +#: ../../po/../src/dialogs/tiledialog.cpp:786 +msgid "Vertical spacing between rows" +msgstr "Verticale ruimte tussen rijen" + +#. #### X padding #### +#: ../../po/../src/dialogs/tiledialog.cpp:795 +msgid "Column spacing:" +msgstr "Kolom afstand:" + +#: ../../po/../src/dialogs/tiledialog.cpp:804 +msgid "Horizontal spacing between columns" +msgstr "Horizontale ruimte tussen kolommen" + +#: ../../po/../src/dialogs/tiledialog.cpp:818 +#, fuzzy +msgid "Arrange selected objects" +msgstr "De geselecteerde objecten groeperen" + +#: ../../po/../src/dialogs/xml-tree.cpp:178 +msgid "Click to select nodes, drag to rearrange." +msgstr "" +"Klik om een item te selecteren, sleep om het te verplaatsen" + +#: ../../po/../src/dialogs/xml-tree.cpp:189 +msgid "Click attribute to edit." +msgstr "Klik op een attribuut om het te wijzigen." + +#: ../../po/../src/dialogs/xml-tree.cpp:193 +#, c-format +msgid "" +"Attribute %s selected. Press Ctrl+Enter when done editing to " +"commit changes." +msgstr "" +"Attribuut %s geselecteerd. Druk Ctrl+Enter om de wijzigingen " +"door te voeren." + +#: ../../po/../src/dialogs/xml-tree.cpp:284 +msgid "Drag to reorder nodes" +msgstr "Sleep om de items te herschikken" + +#: ../../po/../src/dialogs/xml-tree.cpp:304 +msgid "New element node" +msgstr "Nieuw element-item" + +#: ../../po/../src/dialogs/xml-tree.cpp:326 +msgid "New text node" +msgstr "Nieuwe tekst-item" + +#: ../../po/../src/dialogs/xml-tree.cpp:347 +msgid "Duplicate node" +msgstr "Item dupliceren" + +#: ../../po/../src/dialogs/xml-tree.cpp:368 +msgid "Delete node" +msgstr "Item verwijderen" + +#: ../../po/../src/dialogs/xml-tree.cpp:384 +msgid "Unindent node" +msgstr "Item minder inspringen" + +#: ../../po/../src/dialogs/xml-tree.cpp:399 +msgid "Indent node" +msgstr "Item meer inspringen" + +#: ../../po/../src/dialogs/xml-tree.cpp:411 +msgid "Raise node" +msgstr "Item omhoog brengen" + +#: ../../po/../src/dialogs/xml-tree.cpp:423 +msgid "Lower node" +msgstr "Item omlaag brengen" + +#: ../../po/../src/dialogs/xml-tree.cpp:468 +msgid "Delete attribute" +msgstr "Attribuut verwijderen" + +#. TRANSLATORS: "Attribute" is a noun here +#: ../../po/../src/dialogs/xml-tree.cpp:513 +msgid "Attribute name" +msgstr "Attribuut naam" + +#. TRANSLATORS: "Set" is a verb here +#: ../../po/../src/dialogs/xml-tree.cpp:533 +msgid "Set attribute" +msgstr "Attribuut instellen" + +#. TRANSLATORS: "Set" is a verb here +#: ../../po/../src/dialogs/xml-tree.cpp:535 +msgid "Set" +msgstr "Instellen" + +#. TRANSLATORS: "Attribute" is a noun here +#: ../../po/../src/dialogs/xml-tree.cpp:558 +msgid "Attribute value" +msgstr "Attribuut waarde" + +#: ../../po/../src/dialogs/xml-tree.cpp:1318 +msgid "New element node..." +msgstr "Nieuw item toevoegen..." + +#: ../../po/../src/dialogs/xml-tree.cpp:1339 +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:100 +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:98 +msgid "Cancel" +msgstr "Annuleren" + +#: ../../po/../src/dialogs/xml-tree.cpp:1345 +msgid "Create" +msgstr "Aanmaken" + +#: ../../po/../src/dialogs/xml-tree.cpp:1458 +#, c-format +msgid "" +"Cannot set %s: Another element with value %s already exists!" +msgstr "" +"Kan %s niet instellen: er bestaat al een element met de waarde %s!" + +#: ../../po/../src/document.cpp:369 +#, c-format +msgid "New document %d" +msgstr "Nieuw document %d" + +#: ../../po/../src/document.cpp:401 +#, c-format +msgid "Memory document %d" +msgstr "Omvang van document in het geheugen %d" + +#: ../../po/../src/document.cpp:524 +#, c-format +msgid "Unnamed document %d" +msgstr "Naamloos document %d" + +#. We hit green anchor, closing Green-Blue-Red +#: ../../po/../src/draw-context.cpp:441 +msgid "Path is closed." +msgstr "Het pad is gesloten." + +#. We hit bot start and end of single curve, closing paths +#: ../../po/../src/draw-context.cpp:456 +msgid "Closing path." +msgstr "Het pad wordt gesloten." + +#. alpha of color under cursor, to show in the statusbar +#. locale-sensitive printf is OK, since this goes to the UI, not into SVG +#: ../../po/../src/dropper-context.cpp:354 +#, c-format +msgid " alpha %.3g" +msgstr "Ondoorzichtigheid (alpha) %.3g" + +#. where the color is picked, to show in the statusbar +#: ../../po/../src/dropper-context.cpp:356 +#, c-format +msgid ", averaged with radius %d" +msgstr ", het gemiddelde in een cirkel met straal %d" + +#: ../../po/../src/dropper-context.cpp:356 +msgid " under cursor" +msgstr " onder de cursor" + +#. message, to show in the statusbar +#: ../../po/../src/dropper-context.cpp:358 +msgid "Release mouse to set color." +msgstr "De muisknop los laten om de kleur te selecteren." + +#: ../../po/../src/dropper-context.cpp:358 +#: ../../po/../src/tools-switch.cpp:207 +msgid "" +"Click to set fill, Shift+click to set stroke; drag to " +"average color in area; with Alt to pick inverse color; Ctrl+C " +"to copy the color under mouse to clipboard" +msgstr "" +"Klik om de vulkleur te kiezen, shift-klik voor lijnkleur, " +"sleep voor gemiddelde kleur van een gebied, alt voor " +"geïnverteerde kleur, ctrl+C om kleur naar het klembord te kopiëren." + +#: ../../po/../src/extension/dependency.cpp:244 +msgid "Dependency::" +msgstr "Afhankelijkheid:" + +#: ../../po/../src/extension/dependency.cpp:245 +msgid " type: " +msgstr " bestandstype:" + +#: ../../po/../src/extension/dependency.cpp:246 +msgid " location: " +msgstr "Lokatie:" + +#: ../../po/../src/extension/dependency.cpp:247 +msgid " string: " +msgstr " tekst:" + +#: ../../po/../src/extension/dependency.cpp:250 +msgid " description: " +msgstr " beschrijving:" + +#. static int i = 0; +#. std::cout << "Checking module[" << i++ << "]: " << name << std::endl; +#: ../../po/../src/extension/extension.cpp:244 +msgid "" +" This is caused by an improper .inx file for this extension. An improper ." +"inx file could have been caused by a faulty installation of Inkscape." +msgstr "" +" Dit wordt veroorzaakt door een foutief .inx-bestand voor deze uitbreiding. " +"Een foutief .inx-bestand kan worden veroorzaakt door een fout tijdens de " +"installatie van Inkscape." + +#: ../../po/../src/extension/extension.cpp:247 +msgid "an ID was not defined for it." +msgstr "er geen ID voor gedefinieerd is." + +#: ../../po/../src/extension/extension.cpp:251 +msgid "there was no name defined for it." +msgstr "er geen naam voor gedefinieerd is." + +#: ../../po/../src/extension/extension.cpp:255 +msgid "the XML description of it got lost." +msgstr "de XML-beschrijving ervoor is verdwenen." + +#: ../../po/../src/extension/extension.cpp:259 +msgid "no implementation was defined for the extension." +msgstr "er geen implementatie is gedefinieerd voor deze uitbreiding." + +#. std::cout << "Failed: " << *(_deps[i]) << std::endl; +#: ../../po/../src/extension/extension.cpp:266 +msgid "a dependency was not met." +msgstr "er was niet voldaan aan een afhankelijkheid." + +#: ../../po/../src/extension/extension.cpp:286 +msgid "Extension \"" +msgstr "Uitbreiding \"" + +#: ../../po/../src/extension/extension.cpp:286 +msgid "\" failed to load because " +msgstr "\" kon niet worden geladen omdat " + +#: ../../po/../src/extension/extension.cpp:565 +#, c-format +msgid "Could not create extension error log file '%s'" +msgstr "" +"Het fouten-logboekbestand '%s' voor uitbreidingen kon niet worden aangemaakt" + +#. This is some filler text, needs to change before relase +#: ../../po/../src/extension/error-file.cpp:56 +msgid "" +"One or more extensions failed to load\n" +"\n" +"The failed extensions have been skipped. Inkscape will continue to run " +"normally but those extensions will be unavailable. For details to " +"troubleshoot this problem, please refer to the error log located at: " +msgstr "" +"Bij het laden van sommige " +"uitbreidingen ging iets mis\n" +"\n" +"De uitbreidingen waarbij iets mis ging zijn overgeslagen. Inkscape zal " +"gewoon werken, maar deze uitbreidingen zijn niet te gebruiken. Zie dit " +"fouten-logboek voor meer details:" + +#. This is some filler text, needs to change before relase +#: ../../po/../src/extension/error-file.cpp:65 +msgid "Show dialog on startup" +msgstr "Dit venster tonen bij het opstarten" + +#: ../../po/../src/extension/implementation/script.cpp:845 +msgid "" +"Inkscape has received an error from the script that it called. The text " +"returned with the error is included below. Inkscape will continue working, " +"but the action you requested has been cancelled." +msgstr "" +"Inkscape kreeg een foutmelding van het script dat was aangeroepen. De tekst " +"die met de foutmelding meekwam staat hieronder. Inkscape zal blijven werken, " +"maar de gevraagde actie is geannuleerd." + +#: ../../po/../src/extension/implementation/script.cpp:858 +msgid "" +"Inkscape has received additional data from the script executed. The script " +"did not return an error, but this may indicate the results will not be as " +"expected." +msgstr "" +"Inkscape heeft extra informatie ontvangen van het script dat was " +"aangeroepen. Het script gaf geen foutmelding, maar dit zou kunnen betekenen " +"dat de resultaten anders zijn dan verwacht." + +#: ../../po/../src/extension/init.cpp:173 +msgid "Null external module directory name. Modules will not be loaded." +msgstr "" +"Geen map-naam gevonden voor de uitbreidingen. De uitbreidingen worden niet " +"geladen." + +#: ../../po/../src/extension/init.cpp:187 +#, c-format +msgid "" +"Modules directory (%s) is unavailable. External modules in that directory " +"will not be loaded." +msgstr "" +"De uitbreidingen-map (%s) is niet beschikbaar. Uitbreidingen in die map " +"zullen niet worden geladen." + +#: ../../po/../src/extension/internal/gnome.cpp:80 +msgid "Select printer" +msgstr "Printer selecteren" + +#: ../../po/../src/extension/internal/gnome.cpp:131 +msgid "Inkscape: Print Preview" +msgstr "Inkscape: afdrukvoorbeeld" + +#: ../../po/../src/extension/internal/grid.cpp:213 +msgid "Line Width" +msgstr "Lijnbreedte" + +#: ../../po/../src/extension/internal/grid.cpp:214 +msgid "Horizontal Spacing" +msgstr "Horizontale tussenruimte" + +#: ../../po/../src/extension/internal/grid.cpp:215 +msgid "Vertical Spacing" +msgstr "Verticale tussenruimte" + +#: ../../po/../src/extension/internal/grid.cpp:216 +msgid "Horizontal Offset" +msgstr "Horizontale inspring" + +#: ../../po/../src/extension/internal/grid.cpp:217 +msgid "Vertical Offset" +msgstr "Verticale inspring" + +#: ../../po/../src/extension/internal/ps.cpp:123 +msgid "Print Destination" +msgstr "Afdrukbestemming" + +#. Print properties frame +#: ../../po/../src/extension/internal/ps.cpp:138 +msgid "Print properties" +msgstr "Afdruk eigenschappen" + +#: ../../po/../src/extension/internal/ps.cpp:145 +msgid "Print using PostScript operators" +msgstr "Afdrukken met Postscript bewerkingen" + +#: ../../po/../src/extension/internal/ps.cpp:147 +msgid "" +"Use PostScript vector operators. The resulting image is usually smaller in " +"file size and can be arbitrarily scaled, but alpha transparency and patterns " +"will be lost." +msgstr "" +"Postscript bewerkingen gebruiken. De resulterende afbeelding zal gewoonlijk " +"kleiner en beter schaalbaar zijn. Transparantie, kleurverlopen en patronen " +"zullen echter verloren gaan." + +#: ../../po/../src/extension/internal/ps.cpp:152 +msgid "Print as bitmap" +msgstr "Afdrukken als bitmap" + +#: ../../po/../src/extension/internal/ps.cpp:154 +msgid "" +"Print everything as bitmap. The resulting image is usually larger in file " +"size and cannot be arbitrarily scaled without quality loss, but all objects " +"will be rendered exactly as displayed." +msgstr "" +"Alles afdrukken als bitmap. De resulterende afbeelding zal gewoonlijk groter " +"zijn, en de kwaliteit hangt af van de zoom-factor. De afbeelding zal er wel " +"altijd precies zo uitzien als op het scherm." + +#: ../../po/../src/extension/internal/ps.cpp:168 +msgid "Preferred resolution (dots per inch) of bitmap" +msgstr "Gewenste resolutie van de bitmap (in punten per inch)" + +#: ../../po/../src/extension/internal/ps.cpp:182 +msgid "Resolution:" +msgstr "Resolutie:" + +#. Print destination frame +#: ../../po/../src/extension/internal/ps.cpp:186 +msgid "Print destination" +msgstr "Afdrukbestemming" + +#: ../../po/../src/extension/internal/ps.cpp:192 +msgid "" +"Use '> filename' to print to file.\n" +"Use '| prog arg...' to pipe to a program." +msgstr "" +"Geef de doel lpr-wachtrij. Gebruik '> bestandsnaam' om\n" +"af te drukken naar een bestand, of '| programma argument....' \n" +"om het naar een programma te sturen." + +#: ../../po/../src/extension/internal/ps.cpp:1227 +msgid "write error occurred" +msgstr "Er vond een schrijffout plaats" + +#: ../../po/../src/extension/prefdialog.cpp:21 +msgid " Preferences" +msgstr "Voorkeuren" + +#. We can't call sp_ui_error_dialog because we may be +#. running from the console, in which case calling sp_ui +#. routines will cause a segfault. See bug 1000350 - bryce +#. sp_ui_error_dialog(_("Format autodetect failed. The file is being opened as SVG.")); +#: ../../po/../src/extension/system.cpp:105 +msgid "Format autodetect failed. The file is being opened as SVG." +msgstr "" +"Het automatisch detecteren van de bestandsindeling is mislukt. Het bestand " +"wordt geopend als SVG." + +#. TRANSLATORS: default.svg is localizable - this is the name of the default document +#. template. This way you can localize the default pagesize, translate the name of +#. the default layer, etc. If you wish to localize this file, please create a +#. localized share/templates/default.xx.svg file, where xx is your language code. +#: ../../po/../src/file.cpp:133 +msgid "default.svg" +msgstr "standaard.svg" + +#: ../../po/../src/file.cpp:215 ../../po/../src/file.cpp:900 +#, c-format +msgid "Failed to load the requested file %s" +msgstr "Het lukte niet om het bestand %s te laden" + +#: ../../po/../src/file.cpp:240 +msgid "Document not saved yet. Cannot revert." +msgstr "Het bestand is nog niet opgeslagen, kan niet terugdraaien." + +#: ../../po/../src/file.cpp:246 +#, c-format +msgid "Changes will be lost! Are you sure you want to reload document %s?" +msgstr "" +"Wijzigingen zullen verloren gaan! Weet u zeker dat u het bestand %s opnieuw " +"wilt laden?" + +#: ../../po/../src/file.cpp:266 +msgid "Document reverted." +msgstr "Het bestand is teruggezet." + +#: ../../po/../src/file.cpp:268 +msgid "Document not reverted." +msgstr "Het bestand is niet teruggezet." + +#: ../../po/../src/file.cpp:382 +msgid "Select file to open" +msgstr "Selecteer een bestand om te openen" + +#: ../../po/../src/file.cpp:518 +#, fuzzy, c-format +msgid "Removed %i unused definition in <defs>." +msgid_plural "Removed %i unused definitions in <defs>." +msgstr[0] "%i ongebruikte definities verwijderd uit <defs>." +msgstr[1] "%i ongebruikte definities verwijderd uit <defs>." + +#: ../../po/../src/file.cpp:523 +msgid "No unused definitions in <defs>." +msgstr "Er zijn geen ongebruikte definities in <defs>." + +#: ../../po/../src/file.cpp:548 +#, c-format +msgid "" +"No Inkscape extension found to save document (%s). This may have been " +"caused by an unknown filename extension." +msgstr "" +"Er werden geen Inkscape extenties aangetroffen om het bestand (%s) op te " +"slaan. Dit kan komen door een onbekende bestands-extentie." + +#: ../../po/../src/file.cpp:549 ../../po/../src/file.cpp:557 +msgid "Document not saved." +msgstr "Document niet opgeslagen." + +#: ../../po/../src/file.cpp:556 +#, c-format +msgid "File %s could not be saved." +msgstr "Bestand %s kon niet worden opgeslagen." + +#: ../../po/../src/file.cpp:566 +msgid "Document saved." +msgstr "Document opgeslagen." + +#: ../../po/../src/file.cpp:614 +#, c-format +msgid "drawing%s" +msgstr "Tekening%s" + +#: ../../po/../src/file.cpp:620 +#, c-format +msgid "drawing-%d%s" +msgstr "Tekening-%d%s" + +#: ../../po/../src/file.cpp:655 +msgid "Select file to save to" +msgstr "Selecteer een bestand om in op te slaan" + +#: ../../po/../src/file.cpp:739 +msgid "No changes need to be saved." +msgstr "Er zijn geen wijzigingen die opgeslagen hoeven te worden." + +#: ../../po/../src/file.cpp:926 +msgid "Select file to import" +msgstr "Selecteer een bestand om te importeren" + +#: ../../po/../src/gradient-context.cpp:263 +msgid "Ctrl: snap gradient angle" +msgstr "Ctrl: draait kleurverloop in stappen" + +#: ../../po/../src/gradient-context.cpp:264 +msgid "Shift: draw gradient around the starting point" +msgstr "Shift: teken kleurverloop rondom het beginpunt" + +#. We did an undoable action, but sp_document_done will be called by the knot when released +#. status text; we do not track coords because this branch is run once, not all the time +#. during drag +#: ../../po/../src/gradient-context.cpp:462 +#, c-format +msgid "Gradient for %d objects; with Ctrl to snap angle" +msgstr "Kleurverloop voor %d objecten; ctrl draait in stappen" + +#: ../../po/../src/gradient-context.cpp:464 +msgid "Select objects on which to create gradient." +msgstr "Selecteer objecten om een kleurverloop voor te maken." + +#: ../../po/../src/gradient-drag.cpp:65 +msgid "Linear gradient start" +msgstr "Begin van lineair kleurverloop" + +#. POINT_LG_P1 +#: ../../po/../src/gradient-drag.cpp:66 +msgid "Linear gradient end" +msgstr "Einde van lineair kleurverloop" + +#: ../../po/../src/gradient-drag.cpp:67 +msgid "Radial gradient center" +msgstr "Midden van cirkelvormig kleurverloop" + +#: ../../po/../src/gradient-drag.cpp:68 ../../po/../src/gradient-drag.cpp:69 +msgid "Radial gradient radius" +msgstr "Straal van cirkelvormig kleurverloop" + +#: ../../po/../src/gradient-drag.cpp:70 +msgid "Radial gradient focus" +msgstr "Brandpunt van cirkelvormig kleurverloop" + +#: ../../po/../src/gradient-drag.cpp:659 +#, c-format +msgid "" +"%s for: %s%s; drag with Ctrl to snap angle, with Ctrl+Alt to " +"preserve angle, with Ctrl+Shift to scale around center" +msgstr "" +"%s voor: %s%s; Ctrl draait in stappen, Ctrl+Alt behoudt de " +"hoek, Ctrl+Shift vergroot rondom het midden" + +#: ../../po/../src/gradient-drag.cpp:662 +msgid " (stroke)" +msgstr "(lijn)" + +#: ../../po/../src/gradient-drag.cpp:665 +msgid "" +"Radial gradient center and focus; drag with Shift to " +"separate focus" +msgstr "" +"Het midden en het brandpunt van het cirkelvormige kleurverloop;" +"sleep met Shift om het brandpunt los te koppelen" + +#: ../../po/../src/gradient-drag.cpp:667 +#, c-format +msgid "" +"Gradient point shared by %d gradients; drag with Shift to " +"separate" +msgstr "" +"Kleurverloop-punt gedeeld door %d verlopen; sleep met shift om " +"ze te splitsen." + +#: ../../po/../src/helper/units.cpp:40 +msgid "Unit" +msgstr "Eenheid" + +#: ../../po/../src/helper/units.cpp:40 +msgid "Units" +msgstr "Eenheden" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Point" +msgstr "Punt" + +#: ../../po/../src/helper/units.cpp:41 +msgid "pt" +msgstr "pt" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Points" +msgstr "Punten" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Pt" +msgstr "Pt" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Pixel" +msgstr "Pixel" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Pixels" +msgstr "Beeldpunten" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Px" +msgstr "Px" + +#. You can add new elements from this point forward +#: ../../po/../src/helper/units.cpp:44 ../share/extensions/straightseg.inx.h:2 +msgid "Percent" +msgstr "Percentage" + +#: ../../po/../src/helper/units.cpp:44 +msgid "Percents" +msgstr "Procenten" + +#: ../../po/../src/helper/units.cpp:45 +msgid "Millimeter" +msgstr "Millimeter" + +#: ../../po/../src/helper/units.cpp:45 +msgid "mm" +msgstr "mm" + +#: ../../po/../src/helper/units.cpp:45 +msgid "Millimeters" +msgstr "Millimeter" + +#: ../../po/../src/helper/units.cpp:46 +msgid "Centimeter" +msgstr "Centimeter" + +#: ../../po/../src/helper/units.cpp:46 +msgid "cm" +msgstr "cm" + +#: ../../po/../src/helper/units.cpp:46 +msgid "Centimeters" +msgstr "Centimeter" + +#: ../../po/../src/helper/units.cpp:47 +msgid "Meter" +msgstr "Meter" + +#: ../../po/../src/helper/units.cpp:47 +msgid "m" +msgstr "m" + +#: ../../po/../src/helper/units.cpp:47 +msgid "Meters" +msgstr "Meters" + +#. no svg_unit +#: ../../po/../src/helper/units.cpp:48 +msgid "Inch" +msgstr "Inch" + +#: ../../po/../src/helper/units.cpp:48 +msgid "in" +msgstr "in" + +#: ../../po/../src/helper/units.cpp:48 +msgid "Inches" +msgstr "Inch" + +#. Volatiles do not have default, so there are none here +#. TRANSLATORS: for info, see http://www.w3.org/TR/REC-CSS2/syndata.html#length-units +#: ../../po/../src/helper/units.cpp:51 +msgid "Em square" +msgstr "'M' vierkantje" + +#: ../../po/../src/helper/units.cpp:51 +msgid "em" +msgstr "'M' breedte" + +#: ../../po/../src/helper/units.cpp:51 +msgid "Em squares" +msgstr "'M' vierkantjes" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/REC-CSS2/syndata.html#length-units +#: ../../po/../src/helper/units.cpp:53 +msgid "Ex square" +msgstr "'x' vierkantje" + +#: ../../po/../src/helper/units.cpp:53 +msgid "ex" +msgstr "x hoogte" + +#: ../../po/../src/helper/units.cpp:53 +msgid "Ex squares" +msgstr "'x' vierkantjes" + +#: ../../po/../src/inkscape.cpp:468 +msgid "Untitled document" +msgstr "Naamloos document" + +#. Show nice dialog box +#: ../../po/../src/inkscape.cpp:497 +msgid "Inkscape encountered an internal error and will close now.\n" +msgstr "" +"Er is een fout op getreden in Inkscape, en het zal nu worden afgesloten.\n" + +#: ../../po/../src/inkscape.cpp:498 +msgid "" +"Automatic backups of unsaved documents were done to the following " +"locations:\n" +msgstr "" +"Automatische reservekopieën van niet opgeslagen documenten werden gemaakt op " +"de volgende lokaties:\n" + +#: ../../po/../src/inkscape.cpp:499 +msgid "Automatic backup of the following documents failed:\n" +msgstr "" +"Het automatisch maken van een reservekopie is mislukt voor de volgende " +"bestanden:\n" + +#: ../../po/../src/inkscape.cpp:634 +#, c-format +msgid "" +"Cannot create directory %s.\n" +"%s" +msgstr "" +"De map %s kon niet worden aangemaakt.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:635 +#, c-format +msgid "" +"%s is not a valid directory.\n" +"%s" +msgstr "" +"%s is geen een geldige map.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:636 +#, c-format +msgid "" +"Cannot create file %s.\n" +"%s" +msgstr "" +"Het bestand %s kan niet worden aangemaakt.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:637 +#, c-format +msgid "" +"Cannot write file %s.\n" +"%s" +msgstr "" +"Kan niet schrijven naar bestand %s.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:638 +msgid "" +"Although Inkscape will run, it will use default settings,\n" +"and any changes made in preferences will not be saved." +msgstr "" +"Inkscape zal nu welliswaar starten met de standaard instellingen,\n" +"maar wijzigingen in de voorkeuren zullen niet worden opgeslagen." + +#: ../../po/../src/inkscape.cpp:708 +#, c-format +msgid "" +"%s is not a regular file.\n" +"%s" +msgstr "" +"%s is geen normaal bestand.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:709 +#, c-format +msgid "" +"%s not a valid XML file, or\n" +"you don't have read permissions on it.\n" +"%s" +msgstr "" +"%s is geen geldig XML bestand,of\n" +"u heeft niet het recht om het te lezen.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:711 +#, c-format +msgid "" +"%s is not a valid menus file.\n" +"%s" +msgstr "" +"%s is geen geldig menu bestand.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:712 +msgid "" +"Inkscape will run with default menus.\n" +"New menus will not be saved." +msgstr "" +"Inkscape zal starten met de standaard menu's.\n" +"Nieuwe menu's worden niet opgeslagen." + +#. sp_ui_menu_append_check_item_from_verb(m, view, _("_Menu"), _("Show or hide the menu bar"), "menu", +#. checkitem_toggled, checkitem_update, 0); +#: ../../po/../src/interface.cpp:753 +msgid "Commands Bar" +msgstr "Opdrachtenbalk" + +#: ../../po/../src/interface.cpp:753 +msgid "Show or hide the Commands bar (under the menu)" +msgstr "Opdrachtenbalk weergeven of verbergen (onder de menubalk)" + +#: ../../po/../src/interface.cpp:755 +msgid "Tool Controls" +msgstr "Gereedschap eigenschappen" + +#: ../../po/../src/interface.cpp:755 +msgid "Show or hide the Tool Controls panel" +msgstr "'Gereedschap eigenschappen'-balk weergeven of verbergen" + +#: ../../po/../src/interface.cpp:757 +msgid "_Toolbox" +msgstr "_Gereedschappen" + +#: ../../po/../src/interface.cpp:757 +msgid "Show or hide the main toolbox (on the left)" +msgstr "Gereedschappen weergeven of verbergen (aan de linker kant)" + +#: ../../po/../src/interface.cpp:763 +msgid "_Statusbar" +msgstr "_Statusbalk" + +#: ../../po/../src/interface.cpp:763 +msgid "Show or hide the statusbar (at the bottom of the window)" +msgstr "Statusbalk weergeven of verbergen (onderaan het scherm)" + +#: ../../po/../src/interface.cpp:820 +#, c-format +msgid "Verb \"%s\" Unknown" +msgstr "Werkwoord \"%s\" is onbekend" + +#. TRANSLATORS: #%s is the id of the group e.g. , not a number. +#: ../../po/../src/interface.cpp:930 +#, c-format +msgid "Enter group #%s" +msgstr "Groep #%s binnengaan" + +#: ../../po/../src/interface.cpp:941 +msgid "Go to parent" +msgstr "Ga naar de ouder" + +#: ../../po/../src/interface.cpp:972 +msgid "Could not parse SVG data" +msgstr "De SVG gegevens konden niet worden verwerkt." + +#: ../../po/../src/interface.cpp:1135 +#, c-format +msgid "Overwrite %s" +msgstr "%s overschrijven" + +#: ../../po/../src/interface.cpp:1153 +#, c-format +msgid "" +"The file %s already exists. Do you want to overwrite that file with the " +"current document?" +msgstr "" +"Het bestand %s bestaat al. Wilt u dat bestand overschrijven met het huidige " +"bestand?" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:59 +msgid "Jabber connection lost." +msgstr "Jabber verbinding verbroken." + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:72 +#, fuzzy, c-format +msgid "Sending message; %u message remaining in send queue." +msgid_plural "Sending message; %u messages remaining in send queue." +msgstr[0] "" +"Bericht wordt verzonden; %u berichten staan in de wachtrij voor verzending." +msgstr[1] "" +"Bericht wordt verzonden; %u berichten staan in de wachtrij voor verzending." + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:78 +msgid "Receive queue empty." +msgstr "Ontvangst-rij leeg." + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:154 +#, fuzzy, c-format +msgid "Receiving change; %u change left to process." +msgid_plural "Receiving change; %u changes left to process." +msgstr[0] "" +"Bezig met ontvangen van een wijziging; nog %u wijziging te verwerken" +msgstr[1] "" +"Bezig met ontvangen van een wijziging; nog %u wijziging te verwerken" + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:157 +#, c-format +msgid "%s has left the chatroom." +msgstr "%s heeft de ruimte verlaten." + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:221 +msgid "Nickname %1 is already in use. Please choose a different nickname." +msgstr "Bijnaam %1 wordt al gebruikt. Kies alstublieft een andere bijnaam." + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:225 +msgid "An error was encountered while attempting to connect to the server." +msgstr "Het opzetten van een verbinding met de server ging mis." + +#. Check to see if the user made any modifications to this document. If so, +#. we want to give them the option of (1) letting us clear their document or (2) +#. opening a new, blank document for the whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:131 +msgid "%1 has invited you to a whiteboard session." +msgstr "%1 heeft u uitgenodigd voor een whiteboard sessie." + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:132 +msgid "Incoming whiteboard invitation from %1" +msgstr "Binnenkomende uitnodiging van %1" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:135 +msgid "Do you wish to accept %1's whiteboard session invitation?" +msgstr "" +"Wilt u de uitnodiging van %1 voor een whiteboard sessie accepteren?" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:137 +msgid "" +"Would you like to accept %1's invitation in a new document window?\n" +"Accepting the invitation in your current window will discard unsaved changes." +msgstr "" +"Wilt u de uitnodiging van %1 accepteren in een nieuw venster?\n" +"Als de uitnodiging in het huidige venster accepteert, gaan niet-opgeslagen " +"wijzigingen verloren." + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:143 +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:198 +msgid "Accept invitation" +msgstr "Uitnodiging accepteren" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:144 +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:199 +msgid "Decline invitation" +msgstr "Uitnodiging afslaan" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:145 +msgid "Accept invitation in new document window" +msgstr "Uitnodiging accepteren in een nieuw venster" + +#. We could not create a new desktop; ask the user if she or he wants to +#. replace the current document and accept the invitation, or reject the invitation. +#. TRANSLATORS: %1 is a userid here +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:196 +msgid "" +"A new document window could not be opened for a whiteboard session with %" +"1" +msgstr "" +"Er kon geen nieuw document venster worden geopend voor een whiteboard sessie " +"met %1" + +#. TRANSLATORS: %1 is the peer whom refused our invitation. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:238 +msgid "" +"The user %1 has refused your " +"whiteboard invitation.\n" +"\n" +msgstr "" +"De gebruiker %1 heeft uw " +"whiteboard uitnodiging geweigerd.\n" +"\n" + +#. TRANSLATORS: %1 is the peer whom refused our invitation, %2 is our Jabber identity. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:241 +msgid "" +"You are still connected to a Jabber server as %2, and may send an " +"invitation to %1 again, or you may send an invitation to a different " +"user." +msgstr "" +"U bent nog steeds verbonden met Jabber als %2, en u kunt %1 " +"nogmaals uitnodigen, of iemand anders." + +#. TRANSLATORS: %1 is the peer whom we tried to contact, but is already in a whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:252 +msgid "" +"The user %1 is already in a " +"whiteboard session.\n" +"\n" +msgstr "" +"De gebruiker %1 is al aanwezig " +"in een whiteboard sessie.\n" +"\n" + +#. TRANSLATORS: %1 is the peer whom we tried to contact, but is already in a whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:255 +msgid "" +"You are still connected to a Jabber server as %1, and may send an " +"invitation to a different user." +msgstr "" +"U bent nog steeds verbonden met Jabber als %1, en u kunt andere " +"gebruikers uitnodigen." + +#: ../../po/../src/jabber_whiteboard/invitation-confirm-dialog.cpp:26 +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:24 +msgid "_Write session file:" +msgstr "_Sessie bestand opslaan:" + +#: ../../po/../src/jabber_whiteboard/message-processors.cpp:145 +#, c-format +msgid "%s has joined the chatroom." +msgstr "%s is de ruimte binnengekomen." + +#: ../../po/../src/jabber_whiteboard/message-queue.cpp:87 +#, fuzzy, c-format +msgid "%u change in receive queue." +msgid_plural "%u changes in receive queue." +msgstr[0] "%u wijzigingen in de ontvangstwachtrij." +msgstr[1] "%u wijzigingen in de ontvangstwachtrij." + +#: ../../po/../src/jabber_whiteboard/message-queue.cpp:117 +#, fuzzy, c-format +msgid "%u change in send queue." +msgid_plural "%u changes in send queue." +msgstr[0] "%u wijzigingen in de verzendwachtrij." +msgstr[1] "%u wijzigingen in de verzendwachtrij." + +#. if ID is NULL, then we have a real problem -- we were not able to find a key +#. nor generate one. The only thing we can really do here is abort, since we have +#. no way to let the other client(s) uniquely identify this object. +#. FIXME: If this indicates a programming bug, then don't request translation with +#. * _(...): it is most useful in untranslated form so that developers may search for +#. * it when someone reports it in a bug report (as we want users to do for all bugs, +#. * as indicated by it being a g_warning string). +#. * +#. * Otherwise, if it is not a programming bug but a network error or a bug in the +#. * remote peer (perhaps running different software) or whatever, then present it in +#. * an alert box, and avoid use of technical jargon `NULL'. +#. +#: ../../po/../src/jabber_whiteboard/message-utilities.cpp:171 +msgid "" +"ID for new object is NULL even after generation and lookup attempts: the new " +"object will NOT be sent, nor will any of its child objects!" +msgstr "" +"Het nieuwe object heeft geen ID, en het kan niet worden aangemaakt of " +"opgezocht. Het nieuwe object (en eventuele kinderen) wordt NIET verzonden!" + +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:60 +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:995 +msgid "Select a location and filename" +msgstr "Selecteer een locatie en een bestandnaam" + +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:62 +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:997 +msgid "Set filename" +msgstr "Bestandsnaam instellen" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:301 +msgid "No SSL certificate was found." +msgstr "Er kon geen SSL certificaat worden gevonden." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:304 +msgid "The SSL certificate provided by the Jabber server is untrusted." +msgstr "Het SSL certificaat van de Jabber server is niet te vertrouwen." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:307 +msgid "The SSL certificate provided by the Jabber server is expired." +msgstr "Het SSL certificaat van de Jabber server is niet langer houdbaar." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:310 +msgid "" +"The SSL certificate provided by the Jabber server has not been activated." +msgstr "Het SSL certificaat van de Jabber server is niet geactiveerd." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:313 +msgid "" +"The SSL certificate provided by the Jabber server contains a hostname that " +"does not match the Jabber server's hostname." +msgstr "" +"Het SSL certificaat van de Jabber server bevat een andere computernaam dan " +"die van de Jabber server." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:316 +msgid "" +"The SSL certificate provided by the Jabber server contains an invalid " +"fingerprint." +msgstr "" +"Het SSL certificaat van de Jabber server bevat een ongeldige vingerafdruk." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:319 +msgid "An unknown error occurred while setting up the SSL connection." +msgstr "Er trad een onbekende fout op bij het opzetten van de SSL verbinding." + +#. TRANSLATORS: %1 is the message that describes the specific error that occurred when +#. establishing the SSL connection. +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:325 +msgid "" +"%1\n" +"\n" +"Do you wish to continue connecting to the Jabber server?" +msgstr "" +"%1\n" +"\n" +"Wilt u de verbinding met de Jabber server als nog opzetten?" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:328 +msgid "Continue connecting and ignore further errors" +msgstr "De verbinding alsnog opgezetten en fouten negeren" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:329 +msgid "Continue connecting, but warn me of further errors" +msgstr "De verbinding alsnog opgezetten, maar waarschuwen bij fouten" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:330 +msgid "Cancel connection" +msgstr "De verbinding verbreken" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:777 +#, c-format +msgid "Established whiteboard session with %s." +msgstr "Whiteboard sessie opgezet met %s." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:785 +#, c-format +msgid "%s has left the whiteboard session." +msgstr "%s heeft de whiteboard sessie verlaten." + +#. Inform the user +#. TRANSLATORS: %1 is the name of the user that disconnected, %2 is the name of the user whom the disconnected user disconnected from. +#. This message is not used in a chatroom context. +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:790 +msgid "" +"The user %1 has left the " +"whiteboard session.\n" +"\n" +msgstr "" +"Gebruiker %1 heeft dewhiteboard " +"sessie verlaten.\n" +"\n" + +#. TRANSLATORS: %1 and %2 are userids +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:792 +msgid "" +"You are still connected to a Jabber server as %2, and may establish a " +"new session to %1 or a different user." +msgstr "" +"U bent nog steeds verbonden met Jabber als %2, en u kunt een nieuwe " +"sessie opzetten met %1, of met iemand anders." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:988 +msgid "" +"Could not open file %1 for session recording.\n" +"The error encountered was: %2.\n" +"\n" +"You may select a different location to record the session, or you may opt to " +"not record this session." +msgstr "" +"Het bestand %1 kon niet worden geopend op de sessie op te nemen.\n" +"De foutmelding was: %2.\n" +"\n" +"U kunt een andere plek kiezen op de sessie op te slaan, of u kunt kiezen de " +"sessie niet op te slaan." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:990 +msgid "Choose a different location" +msgstr "Een andere plek kiezen" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:991 +msgid "Skip session recording" +msgstr "De sessie niet opslaan" + +#: ../../po/../src/knot.cpp:673 +msgid "Node or handle drag canceled." +msgstr "Het slepen van het knooppunt of handvat is afgebroken." + +#: ../../po/../src/libnrtype/FontFactory.cpp:358 +msgid "Ignoring font without family that will crash Pango" +msgstr "Lettertype zonder familie (welke Pango doet crashen) wordt genegeerd" + +#: ../../po/../src/main.cpp:395 +msgid "Print the Inkscape version number" +msgstr "Het Inkscape versienummer tonen." + +#: ../../po/../src/main.cpp:400 +msgid "Do not use X server (only process files from console)" +msgstr "X-server niet gebruiken (verwerk alleen bestanden van de terminal)" + +#: ../../po/../src/main.cpp:405 +msgid "Try to use X server (even if $DISPLAY is not set)" +msgstr "Probeer X-server te gebruiken (zelfs als $DISPLAY geen waarde heeft)" + +#: ../../po/../src/main.cpp:410 +msgid "Open specified document(s) (option string may be excluded)" +msgstr "" +"Open de aangeduidde documenten (optie-tekenreeks hoeft niet te worden " +"opgegeven)" + +#: ../../po/../src/main.cpp:411 ../../po/../src/main.cpp:416 +#: ../../po/../src/main.cpp:421 ../../po/../src/main.cpp:483 +#: ../../po/../src/main.cpp:488 ../../po/../src/main.cpp:493 +msgid "FILENAME" +msgstr "BESTANDSNAAM" + +#: ../../po/../src/main.cpp:415 +msgid "Print document(s) to specified output file (use '| program' for pipe)" +msgstr "" +"Druk de documenten af naar het opgegeven bestand (gebruik '| programma' voor " +"een pipe)" + +#: ../../po/../src/main.cpp:420 +msgid "Export document to a PNG file" +msgstr "Document exporteren naar .png bestand" + +#: ../../po/../src/main.cpp:425 +msgid "The resolution used for exporting SVG into bitmap (default 90)" +msgstr "" +"De resolutie die gebruikt wordt om SVG naar bitmap te exporteren (standaard " +"90)" + +#: ../../po/../src/main.cpp:426 +msgid "DPI" +msgstr "DPI" + +#: ../../po/../src/main.cpp:430 +msgid "" +"Exported area in SVG user units (default is the canvas; 0,0 is lower-left " +"corner)" +msgstr "" +"Geëxporteerde oppervlakte in SVG pixels (standaard het hele document; 0,0 is " +"de hoek links-onder)" + +#: ../../po/../src/main.cpp:431 +msgid "x0:y0:x1:y1" +msgstr "x0:y0:x1:y1" + +#: ../../po/../src/main.cpp:435 +msgid "Exported area is the entire drawing (not canvas)" +msgstr "De gehele tekening (niet het canvas) is geëxporteerd" + +#: ../../po/../src/main.cpp:440 +msgid "" +"Snap the bitmap export area outwards to the nearest integer values (in SVG " +"user units)" +msgstr "" +"De grootte van het te exporteren bitmap-gebied naar buiten afronden (in SVG " +"eenheden)" + +#: ../../po/../src/main.cpp:445 +msgid "The width of exported bitmap in pixels (overrides export-dpi)" +msgstr "" +"De breedte van de gegenereerde bitmap in pixels (dit overschrijft de DPI)" + +#: ../../po/../src/main.cpp:446 +msgid "WIDTH" +msgstr "BREEDTE" + +#: ../../po/../src/main.cpp:450 +msgid "The height of exported bitmap in pixels (overrides export-dpi)" +msgstr "" +"De hoogte van de gegenereerde bitmap in pixels (dit overschrijft de DPI)" + +#: ../../po/../src/main.cpp:451 +msgid "HEIGHT" +msgstr "HOOGTE" + +#: ../../po/../src/main.cpp:455 +msgid "The ID of the object to export (overrides export-area)" +msgstr "" +"Het ID van het te exporteren object (dit overschrijft het te exporteren " +"gebied)" + +#: ../../po/../src/main.cpp:456 ../../po/../src/main.cpp:532 +msgid "ID" +msgstr "ID" + +#. TRANSLATORS: this means: "Only export the object whose id is given in --export-id". +#. See "man inkscape" for details. +#: ../../po/../src/main.cpp:462 +msgid "" +"Export just the object with export-id, hide all others (only with export-id)" +msgstr "" +"Exporteer alleen het object met het opgegeven object-id, verberg alle andere " +"objecten" + +#: ../../po/../src/main.cpp:467 +msgid "Use stored filename and DPI hints when exporting (only with export-id)" +msgstr "" +"Gebruik de opgeslagen bestandsnaam en DPI instellingen bij het exporteren" +"(alleen met export-id)" + +#: ../../po/../src/main.cpp:472 +msgid "Background color of exported bitmap (any SVG-supported color string)" +msgstr "" +"Achtergrondkleur van de geëxporteerde bitmap (kan iedere door SVG " +"ondersteunde kleur zijn)" + +#: ../../po/../src/main.cpp:473 +msgid "COLOR" +msgstr "KLEUR" + +#: ../../po/../src/main.cpp:477 +msgid "Background opacity of exported bitmap (either 0.0 to 1.0, or 1 to 255)" +msgstr "" +"Achtergrond ondoorzichtigheid van de geëxporteerde bitmap (ofwel tussen 0.0 " +"en 1.0, of tussen 1 en 255)" + +#: ../../po/../src/main.cpp:478 +msgid "VALUE" +msgstr "WAARDE" + +#: ../../po/../src/main.cpp:482 +msgid "Export document to plain SVG file (no sodipodi or inkscape namespaces)" +msgstr "" +"Document exporteren naar gewoon SVG bestand (geen sodipodi- of inkscape-" +"naamruimte)" + +#: ../../po/../src/main.cpp:487 +msgid "Export document to a PS file" +msgstr "Document exporteren naar PS bestand" + +#: ../../po/../src/main.cpp:492 +msgid "Export document to an EPS file" +msgstr "Document exporteren naar EPS bestand" + +#: ../../po/../src/main.cpp:497 +msgid "Convert text object to paths on export (EPS)" +msgstr "Tekst omzetten naar paden bij het exporteren (EPS)" + +#: ../../po/../src/main.cpp:502 +msgid "Export files with the bounding box set to the page size (EPS)" +msgstr "" +"Pagina grootte als omhullende gebruiken bij het exporteren van EPS bestanden" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:508 +msgid "" +"Query the X coordinate of the drawing or, if specified, of the object with --" +"query-id" +msgstr "" +"De X-coördinaat van de tekening opvragen, of - indien opgegeven met --query-" +"id - van het object" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:514 +msgid "" +"Query the Y coordinate of the drawing or, if specified, of the object with --" +"query-id" +msgstr "" +"De Y-coördinaat van de tekening opvragen, of - indien opgegeven met --query-" +"id - van het object" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:520 +msgid "" +"Query the width of the drawing or, if specified, of the object with --query-" +"id" +msgstr "" +"De breedte van de tekening opvragen, of - indien opgegeven met --query-id - " +"van het object" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:526 +msgid "" +"Query the height of the drawing or, if specified, of the object with --query-" +"id" +msgstr "" +"De hoogte van de tekening opvragen, of - indien opgegeven met --query-id - " +"van het object" + +#: ../../po/../src/main.cpp:531 +msgid "The ID of the object whose dimensions are queried" +msgstr "Het ID van het object waarvan de informatie wordt opgevraagd" + +#. TRANSLATORS: this option makes Inkscape print the name (path) of the extension directory +#: ../../po/../src/main.cpp:537 +msgid "Print out the extension directory and exit" +msgstr "Geef de " + +#: ../../po/../src/main.cpp:542 +msgid "Show given files one-by-one, switch to next on any key/mouse event" +msgstr "" +"De geselecteerde bestanden één voor één weergeven, en naar de volgende gaan " +"bij muisklik of toetsenbord gebruik" + +#: ../../po/../src/main.cpp:547 +msgid "Use the new Gtkmm GUI interface" +msgstr "Gebruik de nieuwe Gtkmm gebruikers interface" + +#: ../../po/../src/main.cpp:552 +msgid "Remove unused definitions from the defs section(s) of the document" +msgstr "Ongebruikte definities uit het defs-onderdeel van het bestand halen" + +#: ../../po/../src/main.cpp:741 +msgid "" +"[OPTIONS...] [FILE...]\n" +"\n" +"Available options:" +msgstr "" +"[OPTIES...] [BESTAND...]\n" +"\n" +"Beschikbare opties:" + +#: ../../po/../src/menus-skeleton.h:17 +msgid "_New" +msgstr "_Nieuw" + +#: ../../po/../src/menus-skeleton.h:22 +msgid "Open _Recent" +msgstr "_Recente bestanden" + +#: ../../po/../src/menus-skeleton.h:53 +msgid "_Edit" +msgstr "Be_werken" + +#: ../../po/../src/menus-skeleton.h:84 +msgid "_View" +msgstr "Beel_d" + +#: ../../po/../src/menus-skeleton.h:85 +#, fuzzy +msgid "_Zoom" +msgstr "Zoomen" + +#: ../../po/../src/menus-skeleton.h:102 +msgid "Show/Hide" +msgstr "Weergeven/verbergen" + +#: ../../po/../src/menus-skeleton.h:107 +msgid "_Display mode" +msgstr "" + +#: ../../po/../src/menus-skeleton.h:126 +msgid "_Layer" +msgstr "_Laag" + +#: ../../po/../src/menus-skeleton.h:143 +msgid "_Object" +msgstr "_Object" + +#: ../../po/../src/menus-skeleton.h:165 +msgid "_Path" +msgstr "_Paden" + +#: ../../po/../src/menus-skeleton.h:188 +msgid "_Text" +msgstr "_Tekst" + +#: ../../po/../src/menus-skeleton.h:200 +msgid "Effects" +msgstr "Effecten" + +#: ../../po/../src/menus-skeleton.h:207 +msgid "Whiteboa_rd" +msgstr "Whiteboa_rd" + +#: ../../po/../src/menus-skeleton.h:220 +msgid "_Help" +msgstr "_Hulp" + +#: ../../po/../src/menus-skeleton.h:222 +msgid "Tutorials" +msgstr "Handleidingen" + +#: ../../po/../src/node-context.cpp:382 +msgid "" +"Ctrl: toggle node type, snap handle angle, move hor/vert; Ctrl" +"+Alt: move along handles" +msgstr "" +"Ctrl: kies knooppunt type, draai in stappen, verplaats horizontaal/" +"verticaal; Ctrl+Alt: verplaatsen in de richting van de handvatten" + +#: ../../po/../src/node-context.cpp:383 +msgid "" +"Shift: toggle node selection, disable snapping, rotate both handles" +msgstr "" +"Shift: wissel knooppunt selectie, magnetisch raster uit te zetten, " +"draai beide handvatten" + +#: ../../po/../src/node-context.cpp:384 +msgid "Alt: lock handle length; Ctrl+Alt: move along handles" +msgstr "" +"Alt: vergrendel handvat lengte; Ctrl+Alt: verplaatsen in de " +"richting van de handvatten" + +#: ../../po/../src/nodepath.cpp:1399 ../../po/../src/nodepath.cpp:1411 +#: ../../po/../src/nodepath.cpp:1492 ../../po/../src/nodepath.cpp:1504 +msgid "To join, you must have two endnodes selected." +msgstr "Om samen te voegen moeten u twee eindpunten selecteren." + +#: ../../po/../src/nodepath.cpp:1633 ../../po/../src/nodepath.cpp:1647 +msgid "" +"Select two non-endpoint nodes on a path between which to delete " +"segments." +msgstr "" +"Selecteer twee tussen-knooppunten op een pad waar tussen de lijn moet " +"worden verwijderd." + +#: ../../po/../src/nodepath.cpp:1743 +msgid "Cannot find path between nodes." +msgstr "Geen pad gevonden tussen de knooppunten" + +#: ../../po/../src/nodepath.cpp:2822 +#, c-format +msgid "" +"Node handle: angle %0.2f°, length %s; with Ctrl to snap " +"angle; with Alt to lock length; with Shift to rotate both " +"handles" +msgstr "" +"Knooppunt handvat: hoek %0.2f°, lengte %s; Ctrl draait in " +"stappen; Alt vergrendelt de lengte; Shift draait ook het " +"andere handvat" + +#: ../../po/../src/nodepath.cpp:3351 +msgid "" +"Node: drag to edit the path; with Ctrl to snap to horizontal/" +"vertical; with Ctrl+Alt to snap to handles' directions" +msgstr "" +"Knooppunt: sleep om het pad te wijzigen; met Ctrl beperkt de " +"beweging tot horizontaal/verticaal; Ctrl+Alt beperkt in handvat-" +"richting" + +#: ../../po/../src/nodepath.cpp:3375 +msgid "" +"Node handle: drag to shape the curve; with Ctrl to snap angle; " +"with Alt to lock length; with Shift to rotate both handles" +msgstr "" +"Knooppunt handvat: sleep om de ronding te vormen; Ctrl draait " +"in stappen; Alt vergrendelt de lengte; Shift draait ook het " +"andere handvat" + +#: ../../po/../src/nodepath.cpp:3399 +msgid "" +"Node handle: drag to shape the curve; with Ctrl to snap angle; " +"with Alt to lock length; with Shift to rotate the opposite " +"handle in sync" +msgstr "" +"Knooppunt handvat: sleep om de ronding te vormen; Ctrl draait " +"in stappen; Alt vergrendelt de lengte; Shift draait ook het " +"andere handvat" + +#. TRANSLATORS: "end" is an adjective here (NOT a verb) +#: ../../po/../src/nodepath.cpp:3591 +msgid "end node" +msgstr "eind-knooppunt" + +#. TRANSLATORS: "cusp" means "sharp" (cusp node); see also the Advanced Tutorial +#: ../../po/../src/nodepath.cpp:3596 +msgid "cusp" +msgstr "hoekig" + +#. TRANSLATORS: "smooth" is an adjective here +#: ../../po/../src/nodepath.cpp:3599 +msgid "smooth" +msgstr "glad" + +#: ../../po/../src/nodepath.cpp:3601 +msgid "symmetric" +msgstr "symmetrisch" + +#. TRANSLATORS: "end" is an adjective here (NOT a verb) +#: ../../po/../src/nodepath.cpp:3607 +msgid "end node, handle retracted (drag with Shift to extend)" +msgstr "" +"eind-knooppunt, handvat ingetrokken (sleep met shift om het uit te " +"trekken)" + +#: ../../po/../src/nodepath.cpp:3609 +msgid "one handle retracted (drag with Shift to extend)" +msgstr "één handvat ingetrokken (sleep met shift om het uit te trekken)" + +#: ../../po/../src/nodepath.cpp:3612 +msgid "both handles retracted (drag with Shift to extend)" +msgstr "" +"beide handvatten ingetrokken (sleep met shift om ze uit te trekken)" + +#: ../../po/../src/nodepath.cpp:3624 +msgid "Drag nodes or node handles; arrow keys to move nodes" +msgstr "" +"Versleep knooppunten of -handvatten;pijltjes-toetsen om de " +"knooppunten te verplaatsen" + +#: ../../po/../src/nodepath.cpp:3625 +msgid "Drag the node or its handles; arrow keys to move the node" +msgstr "" +"Sleep het knooppunt of zijn handvatten; pijltjes-toetsen om " +"het knooppunt te verplaatsen" + +#: ../../po/../src/nodepath.cpp:3651 ../../po/../src/nodepath.cpp:3663 +msgid "Select a single object to edit its nodes or handles." +msgstr "" +"Selecteer één enkel object om zijn knooppunten of handvatten te wijzigen." + +#: ../../po/../src/nodepath.cpp:3655 +#, fuzzy, c-format +msgid "" +"0 out of %i node selected. Click, Shift+click, " +"or drag around nodes to select." +msgid_plural "" +"0 out of %i nodes selected. Click, Shift+click, " +"or drag around nodes to select." +msgstr[0] "" +"Er zijn geen objecten geselecteerd. Klik, shift-klik of sleep om objecten te " +"selecteren." +msgstr[1] "" +"Er zijn geen objecten geselecteerd. Klik, shift-klik of sleep om objecten te " +"selecteren." + +#: ../../po/../src/nodepath.cpp:3661 +msgid "Drag the handles of the object to modify it." +msgstr "Sleep de handvatten van het object om het te wijzigen." + +#: ../../po/../src/nodepath.cpp:3669 +#, fuzzy, c-format +msgid "%i of %i node selected; %s. %s." +msgid_plural "%i of %i nodes selected; %s. %s." +msgstr[0] "%i van %i knooppunt geselecteerd; %s. %s." +msgstr[1] "%i van %i knooppunt geselecteerd; %s. %s." + +#: ../../po/../src/nodepath.cpp:3675 +#, fuzzy, c-format +msgid "%i of %i node selected. %s." +msgid_plural "%i of %i nodes selected. %s." +msgstr[0] "%i van %i knooppunt geselecteerd. %s." +msgstr[1] "%i van %i knooppunt geselecteerd. %s." + +#: ../../po/../src/object-edit.cpp:493 +msgid "" +"Adjust the horizontal rounding radius; with Ctrl to make the " +"vertical radius the same" +msgstr "" +"De straal van de horizontale afronding van hoeken instellen; gebruik " +"Ctrl om de verticale straal gelijk te maken" + +#: ../../po/../src/object-edit.cpp:499 +msgid "" +"Adjust the vertical rounding radius; with Ctrl to make the " +"horizontal radius the same" +msgstr "" +"De straal van de verticale afronding van hoeken instellen; gebruik " +"Ctrl om de horizontale straal gelijk te maken" + +#: ../../po/../src/object-edit.cpp:506 ../../po/../src/object-edit.cpp:513 +msgid "" +"Adjust the width and height of the rectangle; with Ctrl to " +"lock ratio or stretch in one dimension only" +msgstr "" +"De hoogte en breedte van de rechthoek aanpassen; gebruik Ctrlom de verhouding te vergrendelen of om in een dimensie te schalen" + +#: ../../po/../src/object-edit.cpp:686 +msgid "Adjust ellipse width, with Ctrl to make circle" +msgstr "" +"De breedte van de ellips aanpassen; druk ctrl om een cirkel te " +"maken" + +#: ../../po/../src/object-edit.cpp:689 +msgid "Adjust ellipse height, with Ctrl to make circle" +msgstr "" +"De hoogte van de ellips aanpassen; druk ctrl om een cirkel te " +"maken" + +#: ../../po/../src/object-edit.cpp:692 +msgid "" +"Position the start point of the arc or segment; with Ctrl to " +"snap angle; drag inside the ellipse for arc, outside for " +"segment" +msgstr "" +"Plaats het beginpunt van de arc of de taartpunt; Ctrl om te " +"draaien in stappen; Sleep binnen de ellips voor een arc, er " +"buiten voor een taartpunt" + +#: ../../po/../src/object-edit.cpp:695 +msgid "" +"Position the end point of the arc or segment; with Ctrl to " +"snap angle; drag inside the ellipse for arc, outside for " +"segment" +msgstr "" +"Plaats het eindpunt van de arc of de taartpunt; Ctrl om te " +"draaien in stappen; Sleep binnen de ellips voor een arc, er " +"buiten voor een taartpunt" + +#: ../../po/../src/object-edit.cpp:800 +msgid "" +"Adjust the tip radius of the star or polygon; with Shift to " +"round; with Alt to randomize" +msgstr "" +"De punt straal van de ster of het polygoon aanpassen; Shift om " +"af te ronden; Alt om te verspreiden" + +#: ../../po/../src/object-edit.cpp:803 +msgid "" +"Adjust the base radius of the star; with Ctrl to keep star " +"rays radial (no skew); with Shift to round; with Alt to " +"randomize" +msgstr "" +"De binnen straal van de ster of het polygoon aanpassen; Ctrl " +"om de 'punten' recht te houden (geen draaiingen); Shift om af te " +"ronden; Alt om te verspreiden" + +#: ../../po/../src/object-edit.cpp:967 +msgid "" +"Roll/unroll the spiral from inside; with Ctrl to snap angle; " +"with Alt to converge/diverge" +msgstr "" +"De spiraal op- of afrollen van de binnenkant; Ctrl om te " +"draaien in stappen; Alt om te convergeren/divergeren" + +#: ../../po/../src/object-edit.cpp:969 +msgid "" +"Roll/unroll the spiral from outside; with Ctrl to snap angle; " +"with Shift to scale/rotate" +msgstr "" +"De spiraal op- of afrollen van de buitenkant; Ctrl om te " +"draaien in stappen; Shift om te draaien/vergroten/verkleinen" + +#: ../../po/../src/object-edit.cpp:1006 +msgid "Adjust the offset distance" +msgstr "De rand afstand aanpassen" + +#. TRANSLATORS: This refers to the pattern that's inside the object +#: ../../po/../src/object-edit.cpp:1036 +msgid "Move the pattern fill inside the object" +msgstr "De patroonvulling van het object verplaatsen" + +#: ../../po/../src/object-edit.cpp:1038 +msgid "Scale the pattern fill uniformly" +msgstr "De patroonvulling van het object vergroten/verkleinen" + +#: ../../po/../src/object-edit.cpp:1040 +msgid "Rotate the pattern fill; with Ctrl to snap angle" +msgstr "" +"De patroonvulling van het object draaien; Ctrl om te draaien " +"in stappen" + +#: ../../po/../src/object-edit.cpp:1065 +msgid "Drag to resize the flowed text frame" +msgstr "" +"Sleep om de grootte van het frame van de gevormde tekst aan te " +"passen" + +#. Item dialog +#: ../../po/../src/object-ui.cpp:106 +msgid "Object _Properties" +msgstr "Object _eigenschappen" + +#. Select item +#: ../../po/../src/object-ui.cpp:116 +msgid "_Select This" +msgstr "Dit _selecteren" + +#. Create link +#: ../../po/../src/object-ui.cpp:126 +msgid "_Create Link" +msgstr "Koppeling _maken" + +#. "Ungroup" +#: ../../po/../src/object-ui.cpp:199 ../../po/../src/verbs.cpp:1931 +msgid "_Ungroup" +msgstr "Groep _opheffen" + +#. Link dialog +#: ../../po/../src/object-ui.cpp:239 +msgid "Link _Properties" +msgstr "Koppel _eigenschappen" + +#. Select item +#: ../../po/../src/object-ui.cpp:249 +msgid "_Follow Link" +msgstr "_Koppeling volgen" + +#. Reset transformations +#: ../../po/../src/object-ui.cpp:254 +msgid "_Remove Link" +msgstr "Koppeling verwijder" + +#. Link dialog +#: ../../po/../src/object-ui.cpp:303 +msgid "Image _Properties" +msgstr "_Afbeeldingseigenschappen" + +#. Item dialog +#: ../../po/../src/object-ui.cpp:344 +msgid "_Fill and Stroke" +msgstr "_Opvulling en lijnen" + +#: ../../po/../src/path-chemistry.cpp:58 +msgid "Select at least two objects to combine." +msgstr "Selecteer tenminste twee objecten om te combineren." + +#: ../../po/../src/path-chemistry.cpp:65 +msgid "At least one of the objects is not a path, cannot combine." +msgstr "Tenminste één van de objecten is geen pad, combineren mislukt." + +#: ../../po/../src/path-chemistry.cpp:73 +msgid "" +"You cannot combine objects from different groups or layers." +msgstr "" +"U kunt geen objecten combineren uit verschillen groepen of lagen" + +#: ../../po/../src/path-chemistry.cpp:155 +msgid "Select path(s) to break apart." +msgstr "Selecteer (een) pad(en) om in stukken te breken." + +#: ../../po/../src/path-chemistry.cpp:231 +msgid "No path(s) to break apart in the selection." +msgstr "Geen pad(en) in de selectie om in stukken te breken." + +#: ../../po/../src/path-chemistry.cpp:252 +msgid "Select object(s) to convert to path." +msgstr "Selecteer (een) object(en) om te converteren naar een pad." + +#: ../../po/../src/path-chemistry.cpp:297 +msgid "No objects to convert to path in the selection." +msgstr "Geen pad(en) in de selectie om te converteren naar een pad." + +#: ../../po/../src/path-chemistry.cpp:345 +msgid "Select path(s) to reverse." +msgstr "Selecteer (een) pad(en) om om te keren." + +#: ../../po/../src/path-chemistry.cpp:370 +msgid "No paths to reverse in the selection." +msgstr "Geen pad(en) in de selectie om om te keren." + +#: ../../po/../src/pen-context.cpp:379 ../../po/../src/pencil-context.cpp:233 +msgid "Continuing selected path" +msgstr "Huidig pad wordt voortgezet" + +#: ../../po/../src/pen-context.cpp:390 ../../po/../src/pencil-context.cpp:242 +msgid "Creating new path" +msgstr "Nieuw pad maken" + +#: ../../po/../src/pen-context.cpp:394 ../../po/../src/pencil-context.cpp:246 +msgid "Appending to selected path" +msgstr "Toevoegen aan het geselecteerde pad" + +#: ../../po/../src/pen-context.cpp:538 +msgid "Click or click and drag to close and finish the path." +msgstr "Klik of klik en sleep om een pad te sluiten." + +#: ../../po/../src/pen-context.cpp:548 +msgid "" +"Click or click and drag to continue the path from this point." +msgstr "" +"Klik of klik en sleep om vanaf daar het pad voort te zetten." + +#: ../../po/../src/pen-context.cpp:857 +#, c-format +msgid "" +"%s: angle %3.2f°, distance %s; with Ctrl to snap angle, " +"Enter to finish the path" +msgstr "" +"%s: hoek %3.2f°, afstand %s; Ctrl draait in stappen, " +"Enter om het pad af te maken" + +#: ../../po/../src/pen-context.cpp:882 +#, c-format +msgid "" +"Curve handle: angle %3.2f°, length %s; with Ctrl to snap " +"angle" +msgstr "" +"Afrond handvat: %3.2f°; lengte %s; ctrl draait in stappen" + +#: ../../po/../src/pen-context.cpp:912 +#, c-format +msgid "" +"%s: angle %3.2f°, length %s; with Ctrl to snap angle, " +"with Shift to move this handle only" +msgstr "" +"%s: hoek 3%02f°, lengte %s; Ctrl draait in stappen; " +"Shift draait allen dit handvat" + +#: ../../po/../src/pen-context.cpp:946 +msgid "Finishing pen" +msgstr "Klaar met het trekken van lijnen" + +#: ../../po/../src/pencil-context.cpp:320 +msgid "Release here to close and finish the path." +msgstr "Laat hier los om het pad te sluiten." + +#: ../../po/../src/pencil-context.cpp:326 +msgid "Drawing a freehand path" +msgstr "Lijnen uit de losse pols aan het tekenen" + +#: ../../po/../src/pencil-context.cpp:331 +msgid "Drag to continue the path from this point." +msgstr "Sleep om vanaf hier verder te gaan met een pad." + +#. Write curves to object +#: ../../po/../src/pencil-context.cpp:390 +msgid "Finishing freehand" +msgstr "Klaar met tekenen uit de losse pols" + +#: ../../po/../src/rect-context.cpp:387 +msgid "" +"Ctrl: make square or integer-ratio rect, lock a rounded corner " +"circular" +msgstr "" +"Ctrl: maak een vierkant of 'gehele verhouding'-rechthoek, vergrendel " +"de afronding van afgeronde hoek" + +#: ../../po/../src/rect-context.cpp:549 +#, c-format +msgid "" +"Rectangle: %s × %s; with Ctrl to make square or integer-" +"ratio rectangle; with Shift to draw around the starting point" +msgstr "" +"Rechthoek: %s × %s; ctrl om een 'gehele verhouding'-" +"rechthoek te maken; shift om rondom het beginpunt te tekenen" + +#: ../../po/../src/select-context.cpp:243 +msgid "Move canceled." +msgstr "Verplaatsen afgebroken." + +#: ../../po/../src/select-context.cpp:252 +msgid "Selection canceled." +msgstr "Selecteren afgebroken." + +#: ../../po/../src/select-context.cpp:642 +msgid "Ctrl: select in groups, move hor/vert" +msgstr "" +"Ctrl: selecteer binnenin groepen, verplaats horizontaal/verticaal" + +#: ../../po/../src/select-context.cpp:643 +msgid "Shift: toggle select, force rubberband, disable snapping" +msgstr "" +"Shift: wissel selectie, force rubberband, magnetisch raster uit te " +"zetten." + +#: ../../po/../src/select-context.cpp:644 +msgid "Alt: select under, move selected" +msgstr "" +"Alt: Selecteer object onder de muiscursor, verplaats de selectie." + +#: ../../po/../src/select-context.cpp:798 +#, fuzzy +msgid "Selected object is not a group. Cannot enter." +msgstr "" +"Het geselecteerde object is geen pad, en dus kan er geen buiten- of " +"binnenrand aan worden toegevoegd." + +#: ../../po/../src/select-context.cpp:876 +#, c-format +msgid "" +"Move by %s, %s; with Ctrl to restrict to horizontal/vertical; " +"with Shift to disable snapping" +msgstr "" +"Verplaatsen met %s, %s; druk Ctrl om het te beperken tot " +"horizontaal en verticaal, druk Shift om magnetisch raster uit te " +"zetten." + +#: ../../po/../src/selection-chemistry.cpp:228 +msgid "Nothing was deleted." +msgstr "Er is niets verwijderd." + +#: ../../po/../src/selection-chemistry.cpp:259 +msgid "Select object(s) to duplicate." +msgstr "Selecteer (een) object(en) om te dupliceren." + +#: ../../po/../src/selection-chemistry.cpp:420 +msgid "Select two or more objects to group." +msgstr "Selecteer twee objecten of meer objecten om te groeperen." + +#: ../../po/../src/selection-chemistry.cpp:428 +msgid "Select at least two objects to group." +msgstr "Selecteer tenminste twee objecten om te groeperen." + +#: ../../po/../src/selection-chemistry.cpp:513 +msgid "Select a group to ungroup." +msgstr "Selecteer een groep om te degroeperen" + +#: ../../po/../src/selection-chemistry.cpp:554 +msgid "No groups to ungroup in the selection." +msgstr "Er zijn geen groepen in de selectie om te degroeperen." + +#: ../../po/../src/selection-chemistry.cpp:623 +msgid "Select objects to raise." +msgstr "Selecteer objecten om naar boven te brengen." + +#: ../../po/../src/selection-chemistry.cpp:629 +#: ../../po/../src/selection-chemistry.cpp:681 +#: ../../po/../src/selection-chemistry.cpp:715 +#: ../../po/../src/selection-chemistry.cpp:773 +msgid "" +"You cannot raise/lower objects from different groups or layers." +msgstr "" +"U kunt geen object uit verschillende groepen of lagen naar " +"boven brengen of naar onder sturen." + +#: ../../po/../src/selection-chemistry.cpp:673 +msgid "Select object(s) to raise to top." +msgstr "Selecteer objecten die u helemaal naar boven wilt brengen." + +#: ../../po/../src/selection-chemistry.cpp:709 +msgid "Select object(s) to lower." +msgstr "Selecteer objecten die u naar onderen wilt brengen." + +#: ../../po/../src/selection-chemistry.cpp:765 +msgid "Select object(s) to lower to bottom." +msgstr "" +"Selecteer objecten die u naar helemaal naar onderen wilt sturen." + +#: ../../po/../src/selection-chemistry.cpp:806 +msgid "Nothing to undo." +msgstr "Er is niets om ongedaan te maken." + +#: ../../po/../src/selection-chemistry.cpp:813 +msgid "Nothing to redo." +msgstr "Er is niets om opnieuw te doen." + +#: ../../po/../src/selection-chemistry.cpp:969 +msgid "Nothing was copied." +msgstr "Er is niets gekopieerd." + +#: ../../po/../src/selection-chemistry.cpp:1051 +msgid "Current layer is hidden. Unhide it to be able to paste to it." +msgstr "" +"De huidige laag is verborgen. U moet hem weer zichtbaar maken om er " +"in te kunnen plakken." + +#: ../../po/../src/selection-chemistry.cpp:1055 +msgid "Current layer is locked. Unlock it to be able to paste to it." +msgstr "" +"De huidige laag is vergrendeld. U moet hem ontgrendelen om er in te " +"kunnen plakken." + +#: ../../po/../src/selection-chemistry.cpp:1068 +#: ../../po/../src/selection-chemistry.cpp:1103 +msgid "Nothing on the clipboard." +msgstr "Er staat niets op het klembord." + +#: ../../po/../src/selection-chemistry.cpp:1109 +msgid "Select object(s) to paste style to." +msgstr "Selecteer objecten om de stijl op toe te passen." + +#: ../../po/../src/selection-chemistry.cpp:1128 +msgid "Select object(s) to move to the layer above." +msgstr "" +"Selecteer objecten om naar de bovenliggende laag te verplaatsen." + +#: ../../po/../src/selection-chemistry.cpp:1146 +msgid "No more layers above." +msgstr "Er zijn geen bovenliggende lagen." + +#: ../../po/../src/selection-chemistry.cpp:1160 +msgid "Select object(s) to move to the layer below." +msgstr "" +"Selecteer objecten om naar de onderliggende laag te verplaatsen." + +#: ../../po/../src/selection-chemistry.cpp:1178 +msgid "No more layers below." +msgstr "Er zijn geen onderliggende lagen." + +#: ../../po/../src/selection-chemistry.cpp:1811 +msgid "Select a clone to unlink." +msgstr "Selecteer een kloon om te ontkoppelen." + +#: ../../po/../src/selection-chemistry.cpp:1842 +msgid "No clones to unlink in the selection." +msgstr "Er zijn geen klonen om te ontkoppelen geselecteerd." + +#: ../../po/../src/selection-chemistry.cpp:1859 +#, fuzzy +msgid "" +"Select a clone to go to its original. Select a linked offset " +"to go to its source. Select a text on path to go to the path. Select " +"a flowed text to go to its frame." +msgstr "" +"Selecteer een kloon om naar zijn origineel te gaan. Selecteer een " +"gekoppelde XXX om naar zijn bron te gaan. Selecteer tekst op een " +"pad om naar het pad te gaan." + +#: ../../po/../src/selection-chemistry.cpp:1882 +#, fuzzy +msgid "" +"Cannot find the object to select (orphaned clone, offset, textpath, " +"flowed text?)" +msgstr "" +"Kan het te selecteren object niet vinden (een wees-kloon, -XXX, of " +"tekst?)" + +#: ../../po/../src/selection-chemistry.cpp:1888 +msgid "" +"The object you're trying to select is not visible (it is in <" +"defs>)" +msgstr "" +"Het object dat u probeert te selecteren is niet zichtbaar (het staat in <" +"defs>)" + +#: ../../po/../src/selection-chemistry.cpp:1915 +msgid "Select object(s) to convert to pattern." +msgstr "Selecteer objecten om te gebruiken als patroon." + +#: ../../po/../src/selection-chemistry.cpp:2006 +msgid "Select an object with pattern fill to extract objects from." +msgstr "Selecteer objecten met patroonvulling om objecten uit te halen." + +#: ../../po/../src/selection-chemistry.cpp:2059 +msgid "No pattern fills in the selection." +msgstr "Er zijn geen objecten met patroonvulling geselecteerd." + +#: ../../po/../src/selection-chemistry.cpp:2079 +msgid "Select object(s) to make a bitmap copy." +msgstr "Selecteer objecten om een bitmap kopie van te maken." + +#: ../../po/../src/selection-describer.cpp:37 +msgid "Click selection to toggle scale/rotation handles" +msgstr "" +"Klik op de selectie om te wisselen tussen draaien en vergroten/verkleinen" + +#. no items +#: ../../po/../src/selection-describer.cpp:39 +msgid "" +"No objects selected. Click, Shift+click, or drag around objects to select." +msgstr "" +"Er zijn geen objecten geselecteerd. Klik, shift-klik of sleep om objecten te " +"selecteren." + +#: ../../po/../src/selection-describer.cpp:51 +#, c-format +msgid " in layer %s" +msgstr " in laag %s" + +#: ../../po/../src/selection-describer.cpp:54 +#, c-format +msgid " in layer %s" +msgstr " in laag %s" + +#: ../../po/../src/selection-describer.cpp:66 +msgid "Use Shift+D to look up original" +msgstr "Gebruik shift+D om het origineel te vinden" + +#: ../../po/../src/selection-describer.cpp:70 +msgid "Use Shift+D to look up path" +msgstr "Gebruik shift+D om het pad te vinden" + +#: ../../po/../src/selection-describer.cpp:74 +msgid "Use Shift+D to look up frame" +msgstr "Gebruik shift+D om het frame te vinden" + +#: ../../po/../src/selection-describer.cpp:84 +#, fuzzy, c-format +msgid "%i object selected" +msgid_plural "%i objects selected" +msgstr[0] "%i object geselecteerd" +msgstr[1] "%i object geselecteerd" + +#: ../../po/../src/selection-describer.cpp:90 +#, c-format +msgid "%s%s. %s." +msgstr "%s%s. %s." + +#: ../../po/../src/selection-describer.cpp:94 +#, fuzzy, c-format +msgid "%s in %i layer. %s." +msgid_plural "%s in %i layers. %s." +msgstr[0] "%s in %i laag. %s." +msgstr[1] "%s in %i laag. %s." + +#: ../../po/../src/seltrans.cpp:498 +msgid "" +"Center of rotation and skewing: drag to reposition; scaling with " +"Shift also uses this center" +msgstr "" +"Het midden van draaien en schuintrekken: sleep om te verplaatsen; " +"vergroten/verkleinen met shift gebruikt ook dit midden." + +#: ../../po/../src/seltrans.cpp:514 +msgid "" +"Squeeze or stretch selection; with Ctrl to scale uniformly; " +"with Shift to scale around rotation center" +msgstr "" +"De selectie samendrukken of uitrekken; Ctrl behoudt de " +"verhoudingen; Shift vergroot/verkleint om het draaiings-middelpunt" + +#: ../../po/../src/seltrans.cpp:515 +msgid "" +"Scale selection; with Ctrl to scale uniformly; with Shift to scale around rotation center" +msgstr "" +"De selectie vergroten of verkleinen; Ctrl behoudt de " +"verhoudingen; Shift vergroot/verkleint om het draaiings-middelpunt" + +#: ../../po/../src/seltrans.cpp:519 +msgid "" +"Skew selection; with Ctrl to snap angle; with Shift to " +"skew around the opposite side" +msgstr "" +"De selectie schuintrekken; ctrl trekt in stappen, shift " +"trekt om de tegenoverliggende hoek" + +#: ../../po/../src/seltrans.cpp:520 +msgid "" +"Rotate selection; with Ctrl to snap angle; with Shift " +"to rotate around the opposite corner" +msgstr "" +"De selectie draaien; ctrl draait in stappen, shift " +"draait om de tegenoverliggende hoek" + +#: ../../po/../src/seltrans.cpp:829 ../../po/../src/seltrans.cpp:909 +#, c-format +msgid "Scale: %0.2f%% x %0.2f%%; with Ctrl to lock ratio" +msgstr "" +"Vergroten/verkleinen: %0.2f%% x %0.2f%%; ctrl om de " +"verhouding te vergrendelen" + +#. TRANSLATORS: don't modify the first ";" (it will NOT be displayed as ";" - only the second one will be) +#: ../../po/../src/seltrans.cpp:984 +#, c-format +msgid "Skew: %0.2f°; with Ctrl to snap angle" +msgstr "Schuintrekken: %0.2f°; ctrl trekt in stappen" + +#. TRANSLATORS: don't modify the first ";" (it will NOT be displayed as ";" - only the second one will be) +#: ../../po/../src/seltrans.cpp:1035 +#, c-format +msgid "Rotate: %0.2f°; with Ctrl to snap angle" +msgstr "Draaien: %0.2f°; ctrl draait in stappen" + +#: ../../po/../src/seltrans.cpp:1090 +#, c-format +msgid "Move center to %s, %s" +msgstr "Midden verplaatsen naar %s, %s" + +#: ../../po/../src/slideshow.cpp:90 +msgid "Inkscape slideshow" +msgstr "Inkscape diavoorstelling" + +#: ../../po/../src/sp-anchor.cpp:181 +#, c-format +msgid "Link to %s" +msgstr "Koppeling naar %s" + +#: ../../po/../src/sp-anchor.cpp:185 +msgid "Link without URI" +msgstr "Koppeling zonder URI" + +#: ../../po/../src/sp-ellipse.cpp:438 ../../po/../src/sp-ellipse.cpp:870 +msgid "Ellipse" +msgstr "Ellips" + +#: ../../po/../src/sp-ellipse.cpp:583 +msgid "Circle" +msgstr "Cirkel" + +#: ../../po/../src/sp-ellipse.cpp:865 +msgid "Segment" +msgstr "Taartpunt" + +#: ../../po/../src/sp-ellipse.cpp:867 +msgid "Arc" +msgstr "Arc" + +#. TRANSLATORS: "Flow region" is an area where text is allowed to flow +#: ../../po/../src/sp-flowregion.cpp:276 +msgid "Flow region" +msgstr "Gebied met tekst-vormen" + +#. TRANSLATORS: A region "cut out of" a flow region; text is not allowed to flow inside the +#. * flow excluded region. flowRegionExclude in SVG 1.2: see +#. * http://www.w3.org/TR/2004/WD-SVG12-20041027/flow.html#flowRegion-elem and +#. * http://www.w3.org/TR/2004/WD-SVG12-20041027/flow.html#flowRegionExclude-elem. +#: ../../po/../src/sp-flowregion.cpp:493 +msgid "Flow excluded region" +msgstr "Gebied zonder tekst-vormen" + +#: ../../po/../src/sp-flowtext.cpp:355 +#, c-format +msgid "Flowed text (%d characters)" +msgstr "Gevormde tekst (%d tekens)" + +#: ../../po/../src/sp-flowtext.cpp:357 +#, c-format +msgid "Linked flowed text (%d characters)" +msgstr "Gekoppelde gevormde tekst (%d tekens)" + +#: ../../po/../src/sp-guide.cpp:290 +msgid "vertical guideline" +msgstr "verticale hulplijn" + +#: ../../po/../src/sp-guide.cpp:292 +msgid "horizontal guideline" +msgstr "horizontale hulplijn" + +#: ../../po/../src/sp-image.cpp:835 +msgid "embedded" +msgstr "ingevoegd" + +#: ../../po/../src/sp-image.cpp:839 +msgid "(null_pointer)" +msgstr "" + +#: ../../po/../src/sp-image.cpp:843 +#, c-format +msgid "Image with bad reference: %s" +msgstr "Afbeelding met slechte referentie: %s" + +#: ../../po/../src/sp-image.cpp:844 +#, c-format +msgid "Image %d × %d: %s" +msgstr "Afbeelding %d × %d: %s" + +#: ../../po/../src/sp-item-group.cpp:390 +#, fuzzy, c-format +msgid "Group of %d object" +msgid_plural "Group of %d objects" +msgstr[0] "Groep van %d object" +msgstr[1] "Groep van %d object" + +#: ../../po/../src/sp-item.cpp:720 +msgid "Object" +msgstr "Object" + +#: ../../po/../src/sp-line.cpp:202 +msgid "Line" +msgstr "Lijn" + +#. TRANSLATORS COMMENT: %s is either "outset" or "inset" depending on sign +#: ../../po/../src/sp-offset.cpp:433 +#, c-format +msgid "Linked offset, %s by %f pt" +msgstr "Gekoppelde rand, %s met %f pt" + +#: ../../po/../src/sp-offset.cpp:434 ../../po/../src/sp-offset.cpp:438 +msgid "outset" +msgstr "buitenrand" + +#: ../../po/../src/sp-offset.cpp:434 ../../po/../src/sp-offset.cpp:438 +msgid "inset" +msgstr "binnenrand" + +#. TRANSLATORS COMMENT: %s is either "outset" or "inset" depending on sign +#: ../../po/../src/sp-offset.cpp:437 +#, c-format +msgid "Dynamic offset, %s by %f pt" +msgstr "Dynamische rand: %s met %f pt" + +#: ../../po/../src/sp-path.cpp:127 +#, fuzzy, c-format +msgid "Path (%i node)" +msgid_plural "Path (%i nodes)" +msgstr[0] "Pad (%i knooppunt)" +msgstr[1] "Pad (%i knooppunt)" + +#: ../../po/../src/sp-polygon.cpp:216 +msgid "Polygon" +msgstr "Veelhoek" + +#: ../../po/../src/sp-polyline.cpp:179 +#, fuzzy +msgid "Polyline" +msgstr "Ellips" + +#: ../../po/../src/sp-rect.cpp:250 +msgid "Rectangle" +msgstr "Rechthoek" + +#. TRANSLATORS: since turn count isn't an integer, please adjust the +#. string as needed to deal with an localized plural forms. +#: ../../po/../src/sp-spiral.cpp:305 +#, c-format +msgid "Spiral with %3f turns" +msgstr "Spiraal met %3f omwentelingen" + +#: ../../po/../src/sp-star.cpp:288 +#, fuzzy, c-format +msgid "Star with %d vertex" +msgid_plural "Star with %d vertices" +msgstr[0] "Ster met %d punt" +msgstr[1] "Ster met %d punt" + +#: ../../po/../src/sp-star.cpp:292 +#, fuzzy, c-format +msgid "Polygon with %d vertex" +msgid_plural "Polygon with %d vertices" +msgstr[0] "Veelhoek met %d hoek" +msgstr[1] "Veelhoek met %d hoek" + +#. TRANSLATORS: For description of font with no name. +#: ../../po/../src/sp-text.cpp:420 +msgid "<no name found>" +msgstr "<geen naam gevonden>" + +#: ../../po/../src/sp-text.cpp:426 +#, c-format +msgid "Text on path (%s, %s)" +msgstr "Tekst op een pad (%s, %s)" + +#: ../../po/../src/sp-text.cpp:427 +#, c-format +msgid "Text (%s, %s)" +msgstr "Tekst (%s, %s)" + +#. TRANSLATORS: Used for statusbar description for long chains: +#. * "Clone of: Clone of: ... in Layer 1". +#: ../../po/../src/sp-use.cpp:317 +msgid "..." +msgstr "..." + +#: ../../po/../src/sp-use.cpp:325 +#, c-format +msgid "Clone of: %s" +msgstr "Kloon van %s" + +#: ../../po/../src/sp-use.cpp:329 +msgid "Orphaned clone" +msgstr "Wees-kloon" + +#: ../../po/../src/spiral-context.cpp:355 +msgid "Ctrl: snap angle" +msgstr "Ctrl: draait in stappen" + +#: ../../po/../src/spiral-context.cpp:357 +msgid "Alt: lock spiral radius" +msgstr "Alt: vergrendelt de spiraal-straal" + +#: ../../po/../src/spiral-context.cpp:469 +#, c-format +msgid "" +"Spiral: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" +"Spiraal: straal %s, hoek %5g°; ctrl draait in stappen" + +#: ../../po/../src/splivarot.cpp:106 +msgid "Select at least 2 paths to perform a boolean operation." +msgstr "" +"Selecteer tenminste 2 paden om een booleaansche bewerking uit te " +"voeren." + +#: ../../po/../src/splivarot.cpp:112 +msgid "" +"Select exactly 2 paths to perform difference, XOR, division, or path " +"cut." +msgstr "" +"Selecteer precies 2 paden om een verschil, uitsluiting, splitsing of " +"pad-snijding uit te voeren." + +#: ../../po/../src/splivarot.cpp:129 ../../po/../src/splivarot.cpp:144 +msgid "" +"Unable to determine the z-order of the objects selected for " +"difference, XOR, division, or path cut." +msgstr "" +"Er kon niet worden bepaald welk object boven de andere lag om een " +"verschil, uitsluiting, splitsing of pad-snijding uit te voeren." + +#: ../../po/../src/splivarot.cpp:174 +msgid "" +"One of the objects is not a path, cannot perform boolean operation." +msgstr "" +"Een van de geselecteerde objecten is geen pad, de booleaansche " +"bewerking kan niet worden uitgevoerd." + +#. TRANSLATORS: "to outline" means "to convert stroke to path" +#: ../../po/../src/splivarot.cpp:554 +msgid "Select path(s) to outline." +msgstr "Selecteer paden om een buitenrand aan toe te voegen." + +#. TRANSLATORS: "to outline" means "to convert stroke to path" +#: ../../po/../src/splivarot.cpp:748 +msgid "No stroked paths to outline in the selection." +msgstr "" + +#: ../../po/../src/splivarot.cpp:832 +msgid "Selected object is not a path, cannot inset/outset." +msgstr "" +"Het geselecteerde object is geen pad, en dus kan er geen buiten- of " +"binnenrand aan worden toegevoegd." + +#: ../../po/../src/splivarot.cpp:1040 +msgid "Select path(s) to inset/outset." +msgstr "Selecteer paden om een buiten- of binnenrand aan toe te voegen." + +#: ../../po/../src/splivarot.cpp:1257 +msgid "No paths to inset/outset in the selection." +msgstr "" +"Geen paden geselecteerd om een buiten- of binnenrand aan toe te " +"voegen." + +#: ../../po/../src/splivarot.cpp:1390 +msgid "Select path(s) to simplify." +msgstr "Selecteer paden om te vereenvoudigen." + +#: ../../po/../src/splivarot.cpp:1417 +msgid "No paths to simplify in the selection." +msgstr "Geen paden geselecteerd om te vereenvoudigen." + +#: ../../po/../src/star-context.cpp:362 +msgid "Ctrl: snap angle; keep rays radial" +msgstr "Ctrl: draai in stappen; houdt de punten radiaal" + +#: ../../po/../src/star-context.cpp:470 +#, c-format +msgid "" +"Polygon: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" +"Veelhoek: straal %s, hoek %5g°; Ctrl draait in stappen" + +#: ../../po/../src/star-context.cpp:471 +#, c-format +msgid "Star: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "Ster: straal %s, hoek %5g°; Ctrl draait in stappen" + +#: ../../po/../src/text-chemistry.cpp:90 +msgid "Select a text and a path to put text on path." +msgstr "" +"Selecteer een tekst en een pad om de tekst op het pad te zetten." + +#: ../../po/../src/text-chemistry.cpp:95 +msgid "" +"This text object is already put to a path. Remove it from the path " +"first. Use Shift+D to look up its path." +msgstr "" +"Dit tekst object staat al op een pad; haal het eerst van dat pad af. " +"Gebruik shift+D om het pad te vinden." + +#. rect is the only SPShape which is not yet, and thus SVG forbids us from putting text on it +#: ../../po/../src/text-chemistry.cpp:101 +msgid "" +"You cannot put text on a rectangle in this version. Convert rectangle to " +"path first." +msgstr "" +"U kunt tekst niet op een rechthoek plaatsten met deze versie van Inkscape. " +"Converteer de rechthoek eerst naar een pad om de tekst er op te zetten." + +#: ../../po/../src/text-chemistry.cpp:159 +msgid "Select a text on path to remove it from path." +msgstr "Selecteer een tekst op een pad om het van het pad af te halen." + +#: ../../po/../src/text-chemistry.cpp:181 +msgid "No texts-on-paths in the selection." +msgstr "Geen tekst op een pad geselecteerd." + +#: ../../po/../src/text-chemistry.cpp:209 +#: ../../po/../src/text-chemistry.cpp:229 +msgid "Select text(s) to remove kerns from." +msgstr "" +"Selecteer één of meer teksten om de tekenspatiëring van te " +"verwijderen." + +#: ../../po/../src/text-chemistry.cpp:250 +msgid "" +"Select a text and one or more paths or shapes to flow text " +"into frame." +msgstr "" +"Selecteer een tekst en één of meer paden of vormen om de tekst " +"in een vorm te zetten." + +#: ../../po/../src/text-chemistry.cpp:322 +msgid "Select a flowed text to unflow it." +msgstr "Selecteer gevormde tekst om het uit de vorm te halen." + +#: ../../po/../src/text-context.cpp:463 +msgid "Click to edit the text, drag to select part of the text." +msgstr "" +"Klik om de tekst te bewerken, sleep om een deel ven de tekst " +"te selecteren." + +#: ../../po/../src/text-context.cpp:465 +msgid "" +"Click to edit the flowed text, drag to select part of the text." +msgstr "" +"Klik om de gevormde tekst aan te passen, sleep om een gedeelte " +"te selecteren." + +#: ../../po/../src/text-context.cpp:540 +msgid "Non-printable character" +msgstr "Niet-afdrukbaar teken" + +#: ../../po/../src/text-context.cpp:589 +#, c-format +msgid "Unicode: %s: %s" +msgstr "Unicode: %s: %s." + +#: ../../po/../src/text-context.cpp:591 ../../po/../src/text-context.cpp:855 +msgid "Unicode: " +msgstr "Unicode: " + +#: ../../po/../src/text-context.cpp:615 +msgid "Current layer is hidden. Unhide it to be able to add text." +msgstr "" +"De huidige laag is verborgen. Maak hem zichtbaar om er tekst aan toe " +"te voegen." + +#: ../../po/../src/text-context.cpp:619 +msgid "Current layer is locked. Unlock it to be able to add text." +msgstr "" +"De huidige laag is vergrendeld. Ontgrendel hem om er tekst aan toe te " +"voegen." + +#: ../../po/../src/text-context.cpp:673 +#, c-format +msgid "Flowed text frame: %s × %s" +msgstr "Frame voor gevormde tekst: %s × %s" + +#: ../../po/../src/text-context.cpp:708 ../../po/../src/text-context.cpp:1464 +msgid "Type text; Enter to start new line." +msgstr "Tik uw tekst; enter begint een nieuwe regel." + +#: ../../po/../src/text-context.cpp:719 +msgid "Flowed text is created." +msgstr "Gevormde tekst is aangemaakt." + +#: ../../po/../src/text-context.cpp:722 +msgid "" +"The frame is too small for the current font size. Flowed text not " +"created." +msgstr "" +"Het frame is te klein voor de grootte van het huidige lettertype. Er " +"is geen gevormde tekst aangemaakt." + +#: ../../po/../src/text-context.cpp:841 +msgid "No-break space" +msgstr "harde spatie" + +#: ../../po/../src/text-context.cpp:1462 +msgid "Type flowed text; Enter to start new paragraph." +msgstr "Tik de tekst om te vormen; enter begint een nieuwe paragraaf." + +#: ../../po/../src/text-context.cpp:1472 ../../po/../src/tools-switch.cpp:189 +msgid "" +"Click to select or create text, drag to create flowed text; " +"then type." +msgstr "" +"Klik om een tekst te beginnen of te selecteren, sleep om " +"gevormde tekst te maken; ga dan tikken." + +#: ../../po/../src/tools-switch.cpp:141 +msgid "" +"To edit a path, click, Shift+click, or drag around " +"nodes to select them, then drag nodes and handles. Click on an " +"object to select." +msgstr "" +"Klik, Shift+klik, of sleep er omheen om knooppunten op " +"een pad te selecteren, en versleep ze daarna. Klik op een " +"object om het te selecteren." + +#: ../../po/../src/tools-switch.cpp:147 +msgid "" +"Drag to create a rectangle. Drag controls to round corners and " +"resize. Click to select." +msgstr "" +"Sleep om een rechthoek te maken. Versleep handvatten om hoeken " +"af te ronden en om de grootte aan te passen. Klik om te selecteren." + +#: ../../po/../src/tools-switch.cpp:153 +msgid "" +"Drag to create an ellipse. Drag controls to make an arc or " +"segment. Click to select." +msgstr "" +"Sleep om een ellips te maken. Versleep handvatten om een arc " +"of taartpunt te maken. Klik om te selecteren." + +#: ../../po/../src/tools-switch.cpp:159 +msgid "" +"Drag to create a star. Drag controls to edit the star shape. " +"Click to select." +msgstr "" +"Sleep om een ster te maken. Versleep handvatten om de vorm van " +"de ster aan te passen. Klik om te selecteren." + +#: ../../po/../src/tools-switch.cpp:165 +msgid "" +"Drag to create a spiral. Drag controls to edit the spiral " +"shape. Click to select." +msgstr "" +"Sleep om een spiraal te maken. Versleep handvatten om de vorm " +"van de spiraal aan te passen. Klik om te selecteren." + +#: ../../po/../src/tools-switch.cpp:171 +msgid "" +"Drag to create a freehand line. Start drawing with Shift to " +"append to selected path." +msgstr "" +"Sleep om een lijn te tekenen. Druk op Shift om toe te voegen " +"aan het geselecteerde pad." + +#: ../../po/../src/tools-switch.cpp:177 +msgid "" +"Click or click and drag to start a path; with Shift to " +"append to selected path." +msgstr "" +"Klik of klik en sleep om een pad te beginnen; druk op " +"Shift om toe te voegen aan het geselecteerde pad." + +#: ../../po/../src/tools-switch.cpp:183 +msgid "" +"Drag to paint a calligraphic stroke. Left/right arrow " +"keys adjust width, up/down adjust angle." +msgstr "" +"Sleep om met een kalligrafische pen te tekenen. De pijltjes naar " +"links en rechts veranderen de breedte, omhoog en " +"omlaag veranderen de hoek." + +#: ../../po/../src/tools-switch.cpp:195 +msgid "" +"Drag or double click to create a gradient on selected objects, " +"drag handles to adjust gradients." +msgstr "" +"Sleep of dubbelklikom een kleurverloop toe te voegen aan de " +"geselecteerde objecten, gebruik de handvatten om de kleurverlopen aan " +"te passen" + +#: ../../po/../src/tools-switch.cpp:201 +msgid "" +"Click or drag around an area to zoom in, Shift+click to " +"zoom out." +msgstr "" +"Klik of selecteer een gebied om in te zoomen, shift+klik om uit te zoomen." + +#: ../../po/../src/tools-switch.cpp:213 +msgid "Click and drag between shapes to create a connector." +msgstr "Klik en sleep tussen vormen om een verbinder te maken." + +#: ../../po/../src/trace/potrace/inkscape-potrace.cpp:553 +#: ../../po/../src/trace/potrace/inkscape-potrace.cpp:654 +#, c-format +msgid "Trace: %d. %ld nodes" +msgstr "Overtrekken: %d. %ld knooppunten" + +#: ../../po/../src/trace/trace.cpp:53 ../../po/../src/trace/trace.cpp:62 +#: ../../po/../src/trace/trace.cpp:70 +msgid "Select an image to trace" +msgstr "Selecteer een afbeelding om over te trekken" + +#: ../../po/../src/trace/trace.cpp:133 +msgid "Trace: No active document" +msgstr "Overtrekken: geen actief document" + +#: ../../po/../src/trace/trace.cpp:154 +msgid "Trace: Image has no bitmap data" +msgstr "Overtrekken: afbeelding heeft geen bitmap gegevens" + +#: ../../po/../src/trace/trace.cpp:267 +#, c-format +msgid "Trace: Done. %ld nodes created" +msgstr "Overtrekken: klaar. %ld knooppunten gemaakt" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:59 ../../po/../src/verbs.cpp:2212 +msgid "About Inkscape" +msgstr "Over Inkscape" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:66 +msgid "_Splash" +msgstr "" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:68 +#, fuzzy +msgid "_Authors" +msgstr "Auteurs" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:69 +#, fuzzy +msgid "_Translators" +msgstr "Vertalers" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:70 +msgid "_License" +msgstr "_Licentie" + +#. TRANSLATORS: This is the filename of the `About Inkscape' picture in +#. the `screens' directory. Thus the translation of "about.svg" should be +#. the filename of its translated version, e.g. about.zh.svg for Chinese. +#. +#. N.B. about.svg changes once per release. (We should probably rename +#. the original to about-0.40.svg etc. as soon as we have a translation. +#. If we do so, then add an item to release-checklist saying that the +#. string here should be changed.) +#. FIXME? INKSCAPE_SCREENSDIR and "about.svg" are in UTF-8, not the +#. native filename encoding... and the filename passed to sp_document_new +#. should be in UTF-*8.. +#: ../../po/../src/ui/dialog/aboutbox.cpp:114 +msgid "about.svg" +msgstr "about.svg" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:464 +msgid "Minimum horizontal gap (in px units) between bounding boxes" +msgstr "" + +#. TRANSLATORS: Horizontal gap +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:466 +#: ../../po/../src/widgets/toolbox.cpp:1556 +msgid "H:" +msgstr "H:" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:474 +msgid "Minimum vertical gap (in px units) between bounding boxes" +msgstr "" + +#. TRANSLATORS: Vertical gap +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:476 +msgid "V:" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:734 +msgid "Align" +msgstr "Uitlijnen" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:735 +msgid "Distribute" +msgstr "Verdelen" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:736 +msgid "Remove overlaps" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:737 +msgid "Nodes" +msgstr "Knooppunten" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:742 +msgid "Relative to: " +msgstr "Relatief ten opzichte van:" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:747 +msgid "Align right sides of objects to left side of anchor" +msgstr "Rechterkant van de objecten uitlijnen op de linkerkant van het anker" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:750 +msgid "Align left sides" +msgstr "Linkerkanten uitlijnen" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:753 +msgid "Center on vertical axis" +msgstr "Verticaal centreren" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:756 +msgid "Align right sides" +msgstr "Rechterkanten uitlijnen" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:759 +msgid "Align left sides of objects to right side of anchor" +msgstr "Linkerkant van de objecten uitlijnen op de rechterkant van het anker" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:762 +msgid "Align bottoms of objects to top of anchor" +msgstr "Onderkant van de objecten uitlijnen op de bovenkant van het anker" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:765 +msgid "Align tops" +msgstr "Bovenkanten uitlijnen" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:768 +msgid "Center on horizontal axis" +msgstr "Centreren om de horizontale as" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:771 +msgid "Align bottoms" +msgstr "Onderkanten uitlijnen" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:774 +msgid "Align tops of objects to bottom of anchor" +msgstr "Bovenkant van de objecten uitlijnen op de onderkant van het anker" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:779 +msgid "Align baseline anchors of texts vertically" +msgstr "Teksten verticaal uitlijnen" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:782 +msgid "Align baseline anchors of texts horizontally" +msgstr "Teksten horizontaal uitlijnen" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:787 +msgid "Make horizontal gaps between objects equal" +msgstr "De horizontale afstand tussen objecten gelijk maken" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:791 +msgid "Distribute left sides equidistantly" +msgstr "De afstand tussen de linkerzijden van de objecten gelijkmatig verdelen" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:794 +msgid "Distribute centers equidistantly horizontally" +msgstr "" +"De middens van de objecten gelijkmatig verdelen in horizontale richting" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:797 +msgid "Distribute right sides equidistantly" +msgstr "" +"De afstand tussen de rechterzijden van de objecten gelijkmatig verdelen" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:801 +msgid "Make vertical gaps between objects equal" +msgstr "De verticale afstand tussen de objecten gelijk maken" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:805 +msgid "Distribute tops equidistantly" +msgstr "De afstand tussen de bovenkanten van de objecten gelijkmatig verdelen" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:808 +msgid "Distribute centers equidistantly vertically" +msgstr "De middens van de objecten gelijkmatig in verticale richting verdelen" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:811 +msgid "Distribute bottoms equidistantly" +msgstr "De afstand tussen de onderkanten van de objecten gelijkmatig verdelen" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:816 +msgid "Distribute baseline anchors of texts horizontally" +msgstr "De geselecteerde teksten horizontaal verdelen" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:819 +msgid "Distribute baseline anchors of texts vertically" +msgstr "De geselecteerde teksten verticaal verdelen" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:824 +msgid "Randomize centers in both dimensions" +msgstr "Middens in beide richtingen willekeurig aanpassen." + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:827 +msgid "Unclump objects: try to equalize edge-to-edge distances" +msgstr "" +"Objecten ontklonteren; proberen de rand-tot-rand afstanden gelijk te maken" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:832 +msgid "" +"Move objects as little as possible so that their bounding boxes do not " +"overlap" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:837 +msgid "Align selected nodes horizontally" +msgstr "De geselecteerde knopen horizontaal uitlijnen" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:840 +msgid "Align selected nodes vertically" +msgstr "De geselecteerde knopen verticaal uitlijnen" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:843 +msgid "Distribute selected nodes horizontally" +msgstr "De geselecteerde knopen horizontaal verdelen" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:846 +msgid "Distribute selected nodes vertically" +msgstr "De geselecteerde knopen verticaal verdelen" + +#. Rest of the widgetry +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:851 +msgid "Last selected" +msgstr "Laatst geselecteerde" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:852 +msgid "First selected" +msgstr "Eerst geselecteerde" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:853 +msgid "Biggest item" +msgstr "Grootste onderdeel" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:854 +msgid "Smallest item" +msgstr "Kleinste onderdeel" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:856 +#: ../../po/../src/widgets/desktop-widget.cpp:1065 +msgid "Drawing" +msgstr "Tekening" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:91 +#, fuzzy +msgid "Metadata 1" +msgstr "Document eigenschappen" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:92 +#, fuzzy +msgid "Metadata 2" +msgstr "Document eigenschappen" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:187 +#, fuzzy +msgid "X coordinate of grid origin" +msgstr "Verticale coördinaat van de selectie" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:189 +#, fuzzy +msgid "Y coordinate of grid origin" +msgstr "Verticale coördinaat van de selectie" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:191 +#, fuzzy +msgid "Distance of vertical grid lines" +msgstr "verticale hulplijn" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:193 +#, fuzzy +msgid "Distance of horizontal grid lines" +msgstr "horizontale hulplijn" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:197 +msgid "Max. snapping distance from grid" +msgstr "" + +#: ../../po/../src/ui/dialog/export.cpp:34 +msgid "Export" +msgstr "Exporteren" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:36 +msgid "Fill" +msgstr "Vullen" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:37 +msgid "Stroke Paint" +msgstr "Lijnkleur" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:38 +msgid "Stroke Style" +msgstr "Lijnstijl" + +#: ../../po/../src/ui/dialog/find.cpp:34 +msgid "Find" +msgstr "Zoeken" + +#: ../../po/../src/ui/dialog/memory.cpp:96 +msgid "Heap" +msgstr "Heap" + +#: ../../po/../src/ui/dialog/memory.cpp:97 +msgid "In Use" +msgstr "In gebruik" + +#. TRANSLATORS: "Slack" refers to memory which is in the heap but currently unused. +#. More typical usage is to call this memory "free" rather than "slack". +#: ../../po/../src/ui/dialog/memory.cpp:100 +msgid "Slack" +msgstr "Slack" + +#: ../../po/../src/ui/dialog/memory.cpp:101 +msgid "Total" +msgstr "Totaal" + +#: ../../po/../src/ui/dialog/memory.cpp:141 +#: ../../po/../src/ui/dialog/memory.cpp:147 +#: ../../po/../src/ui/dialog/memory.cpp:154 +#: ../../po/../src/ui/dialog/memory.cpp:186 +msgid "Unknown" +msgstr "Onbekend" + +#: ../../po/../src/ui/dialog/memory.cpp:167 +msgid "Combined" +msgstr "Gecombineerd" + +#: ../../po/../src/ui/dialog/memory.cpp:209 +msgid "Recalculate" +msgstr "Herberekenen" + +#: ../../po/../src/ui/dialog/messages.cpp:74 +msgid "Ready." +msgstr "Klaar." + +#: ../../po/../src/ui/dialog/messages.cpp:75 +msgid "" +"Enable log display by setting dialogs.debug 'redirect' attribute to 1 in " +"preferences.xml" +msgstr "" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:184 +msgid "_Execute Python" +msgstr "_Python uitvoeren" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:186 +msgid "_Execute Perl" +msgstr "_Perl uitvoeren" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:195 +msgid "Script" +msgstr "Script" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:205 +msgid "Output" +msgstr "Uitvoer" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:215 +msgid "Errors" +msgstr "Fouten" + +#. Dialog organization +#: ../../po/../src/ui/dialog/session-player.cpp:73 +msgid "Session file" +msgstr "Sessie bestand" + +#: ../../po/../src/ui/dialog/session-player.cpp:74 +msgid "Playback controls" +msgstr "Bediening voor terugspelen" + +#: ../../po/../src/ui/dialog/session-player.cpp:75 +msgid "Message information" +msgstr "Bericht informatie" + +#. Active session file display +#. fixme: Does this mean the active file for the session, or the file for the active session? +#. Please indicate which with a TRANSLATORS comment. +#: ../../po/../src/ui/dialog/session-player.cpp:85 +msgid "Active session file:" +msgstr "Actief sessie bestand:" + +#: ../../po/../src/ui/dialog/session-player.cpp:86 +msgid "Delay (milliseconds):" +msgstr "Vertraging (milliseconden):" + +#. Unload/load buttons +#: ../../po/../src/ui/dialog/session-player.cpp:94 +msgid "Close file" +msgstr "Bestand sluiten" + +#: ../../po/../src/ui/dialog/session-player.cpp:95 +msgid "Open new file" +msgstr "Nieuw bestand openen" + +#: ../../po/../src/ui/dialog/session-player.cpp:96 +msgid "Set delay" +msgstr "Vertraging instellen" + +#: ../../po/../src/ui/dialog/session-player.cpp:138 +msgid "Rewind" +msgstr "Terugspoelen" + +#: ../../po/../src/ui/dialog/session-player.cpp:139 +msgid "Go back one change" +msgstr "Eén wijziging terug gaan" + +#: ../../po/../src/ui/dialog/session-player.cpp:140 +msgid "Pause" +msgstr "Pauzeren" + +#: ../../po/../src/ui/dialog/session-player.cpp:141 +msgid "Go forward one change" +msgstr "Eén wijziging verder gaan" + +#: ../../po/../src/ui/dialog/session-player.cpp:142 +msgid "Play" +msgstr "Afspelen" + +#: ../../po/../src/ui/dialog/session-player.cpp:177 +#: ../../po/../src/verbs.cpp:1573 +msgid "Open session file" +msgstr "Sessie bestand openen" + +#. ##Set up the Potrace panel +#. #### brightness #### +#. #### Multiple scanning#### +#. ----Hbox1 +#: ../../po/../src/ui/dialog/tracedialog.cpp:345 +#: ../../po/../src/ui/dialog/tracedialog.cpp:428 +msgid "Brightness" +msgstr "Helderheid" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:348 +msgid "Trace by a given brightness level" +msgstr "Overtrekken volgens een bepaald helderheid niveau" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:355 +msgid "Brightness cutoff for black/white" +msgstr "Helderheid grenswaarde voor zwart/wit" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:362 +msgid "Image Brightness" +msgstr "Afbeeldingshelderheid" + +#. #### canny edge detection #### +#. TRANSLATORS: "Canny" is the name of the inventor of this edge detection method +#: ../../po/../src/ui/dialog/tracedialog.cpp:369 +msgid "Optimal Edge Detection (Canny)" +msgstr "Optimale randherkenning (Canny)" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:372 +msgid "Trace with edge detection by J. Canny's algorithm" +msgstr "Overtrekken met randherkenning volgens de methode van J. Canny." + +#: ../../po/../src/ui/dialog/tracedialog.cpp:388 +msgid "Brightness cutoff for adjacent pixels (determines edge thickness)" +msgstr "" +"Helderheid grenswaarde voor nabuurige pixels (dit bepaalt de grensbreedte)" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:395 +msgid "Edge Detection" +msgstr "Randherkenning" + +#. #### quantization #### +#. TRANSLATORS: Color Quantization: the process of reducing the number of colors +#. in an image by selecting an optimized set of representative colors and then +#. re-applying this reduced set to the original image. +#: ../../po/../src/ui/dialog/tracedialog.cpp:404 +msgid "Color Quantization" +msgstr "Kleur reductie" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:407 +msgid "Trace along the boundaries of reduced colors" +msgstr "Overtrekken aan de hand van grenzen tussen gereduceerde kleuren" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:414 +msgid "The number of reduced colors" +msgstr "Het aantal gereduceerde kleuren" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:416 +msgid "Colors:" +msgstr "Kleuren:" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:421 +msgid "Quantization / Reduction" +msgstr "Kwantisatie / reductie" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:431 +msgid "Trace the given number of brightness levels" +msgstr "Overtrekken in het opgegeven aantal helderheidsniveaus" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:438 +msgid "Scans:" +msgstr "Niveaus:" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:440 +msgid "The desired number of scans" +msgstr "Het gewenste aantal niveaus" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:448 +msgid "Trace the given number of reduced colors" +msgstr "Overtrekken in het opgegeven aantal kleuren" + +#. ---Hbox3 +#: ../../po/../src/ui/dialog/tracedialog.cpp:454 +msgid "Monochrome" +msgstr "Zwart/wit" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:457 +msgid "Same as Color, but convert result to grayscale" +msgstr "Hetzelfde als 'Kleur', maar dan omgezet naar zwart/wit" + +#. TRANSLATORS: "Stack" is a verb here +#: ../../po/../src/ui/dialog/tracedialog.cpp:460 +msgid "Stack" +msgstr "Stapelen" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:463 +msgid "" +"Stack scans vertically (no gaps) or tile horizontally (usually with gaps)" +msgstr "" +"Stapel de niveaus (geen gaten) of leg ze naast elkaar (gewoonlijk met gaten)" + +#. TRANSLATORS: "Smooth" is a verb here +#: ../../po/../src/ui/dialog/tracedialog.cpp:466 +msgid "Smooth" +msgstr "Glad maken" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:469 +msgid "Apply Gaussian blur to the bitmap before tracing" +msgstr "De afbeelding vervagen alvorens hem over te trekken." + +#: ../../po/../src/ui/dialog/tracedialog.cpp:473 +msgid "Multiple Scanning" +msgstr "Meerdere niveaus" + +#. #### Preview #### +#: ../../po/../src/ui/dialog/tracedialog.cpp:479 +#: ../../po/../src/ui/dialog/tracedialog.cpp:489 +msgid "Preview" +msgstr "Voorbeeld" + +#. do not expand +#: ../../po/../src/ui/dialog/tracedialog.cpp:483 +msgid "Preview the result without actual tracing" +msgstr "Een voorbeeld van het resultaat zonder echt over te trekken" + +#. #### swap black and white #### +#: ../../po/../src/ui/dialog/tracedialog.cpp:495 +msgid "Invert" +msgstr "Omdraaien" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:499 +msgid "Invert black and white regions for single traces" +msgstr "Zwart en wit omdraaien voor enkelvoudige scans" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:503 +msgid "Thanks to Peter Selinger, http://potrace.sourceforge.net" +msgstr "Peter Selinger, http://potrace.sourceforge.net" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:506 +msgid "Credits" +msgstr "Met dank aan" + +#. done +#. TRANSLATORS: Potrace is an application for transforming bitmaps into +#. vector graphics (http://potrace.sourceforge.net/) +#: ../../po/../src/ui/dialog/tracedialog.cpp:514 +msgid "Potrace" +msgstr "Potrace" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:527 +msgid "Abort a trace in progress" +msgstr "Overtrekken afbreken" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:531 +msgid "Execute the trace" +msgstr "Start het overtrekken" + +#: ../../po/../src/ui/dialog/transformation.cpp:80 +#: ../../po/../src/ui/dialog/transformation.cpp:90 +#, fuzzy +msgid "_Horizontal" +msgstr "Horizontaal" + +#: ../../po/../src/ui/dialog/transformation.cpp:80 +msgid "Horizontal displacement (relative) or position (absolute)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:82 +#: ../../po/../src/ui/dialog/transformation.cpp:92 +#, fuzzy +msgid "_Vertical" +msgstr "Verticaal" + +#: ../../po/../src/ui/dialog/transformation.cpp:82 +msgid "Vertical displacement (relative) or position (absolute)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:84 +#, fuzzy +msgid "_Width" +msgstr "_Breedte:" + +#: ../../po/../src/ui/dialog/transformation.cpp:84 +msgid "Horizontal size increment (absolute or percentage)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:86 +#, fuzzy +msgid "_Height" +msgstr "Hoogte" + +#: ../../po/../src/ui/dialog/transformation.cpp:86 +msgid "Vertical size increment (absolute or percentage)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:88 +#, fuzzy +msgid "A_ngle" +msgstr "Hoek:" + +#: ../../po/../src/ui/dialog/transformation.cpp:88 +#, fuzzy +msgid "Rotation angle (positive = counterclockwise)" +msgstr "De selectie 90 graden tegen de klok in draaien" + +#: ../../po/../src/ui/dialog/transformation.cpp:90 +msgid "" +"Horizontal skew angle (positive = counterclockwise), or absolute " +"displacement, or percentage displacement" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:92 +msgid "" +"Vertical skew angle (positive = counterclockwise), or absolute displacement, " +"or percentage displacement" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:95 +#, fuzzy +msgid "Transformation matrix element A" +msgstr "Transformatie matrix" + +#: ../../po/../src/ui/dialog/transformation.cpp:96 +#, fuzzy +msgid "Transformation matrix element B" +msgstr "Transformatie matrix" + +#: ../../po/../src/ui/dialog/transformation.cpp:97 +#, fuzzy +msgid "Transformation matrix element C" +msgstr "Transformatie matrix" + +#: ../../po/../src/ui/dialog/transformation.cpp:98 +#, fuzzy +msgid "Transformation matrix element D" +msgstr "Transformatie matrix" + +#: ../../po/../src/ui/dialog/transformation.cpp:99 +#, fuzzy +msgid "Transformation matrix element E" +msgstr "Transformatie matrix" + +#: ../../po/../src/ui/dialog/transformation.cpp:100 +#, fuzzy +msgid "Transformation matrix element F" +msgstr "Transformatie matrix" + +#: ../../po/../src/ui/dialog/transformation.cpp:102 +#, fuzzy +msgid "Rela_tive move" +msgstr "Relatieve verplaatsing" + +#: ../../po/../src/ui/dialog/transformation.cpp:102 +msgid "" +"Add the specified relative displacement to the current position; otherwise, " +"edit the current absolute position directly" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:103 +msgid "Scale proportionally" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:103 +msgid "Preserve the width/height ratio of the scaled objects" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:104 +msgid "Apply to each _object separately" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:104 +msgid "" +"Apply the scale/rotate/skew to each selected object separately; otherwise, " +"transform the selection as a whole" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:105 +#, fuzzy +msgid "Edit c_urrent matrix" +msgstr "De huidige laag één niveau omhoog brengen" + +#: ../../po/../src/ui/dialog/transformation.cpp:105 +msgid "" +"Edit the current transform= matrix; otherwise, post-multiply transform= by " +"this matrix" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:115 +#, fuzzy +msgid "_Move" +msgstr "Verplaatsen" + +#: ../../po/../src/ui/dialog/transformation.cpp:118 +#, fuzzy +msgid "_Scale" +msgstr "Schalen" + +#: ../../po/../src/ui/dialog/transformation.cpp:121 +#, fuzzy +msgid "_Rotate" +msgstr "Roteren" + +#: ../../po/../src/ui/dialog/transformation.cpp:124 +#, fuzzy +msgid "Ske_w" +msgstr "Schuintrekken" + +#: ../../po/../src/ui/dialog/transformation.cpp:127 +msgid "Matri_x" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:141 +msgid "Reset the values on the current tab to defaults" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:148 +#, fuzzy +msgid "Apply transformation to selection" +msgstr "Transformatie toepassen op object" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:43 +msgid "_Use SSL" +msgstr "SSL gebr_uiken" + +#. Construct dialog interface +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:68 +msgid "_Server:" +msgstr "_Server:" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:69 +msgid "_Username:" +msgstr "_Gebruikersnaam:" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:70 +msgid "_Password:" +msgstr "_Wachtwoord:" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:71 +msgid "P_ort:" +msgstr "P_oort:" + +#. Buttons +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:99 +msgid "Connect" +msgstr "Verbinden" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:126 +msgid "Establishing connection to Jabber server %1 as user %2" +msgstr "Bezig met verbinden met Jabber server %1 als %2" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:131 +msgid "Failed to establish connection to Jabber server %1" +msgstr "Het lukte niet een verbinding op te zetten met Jabber server %1" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:136 +msgid "Authentication failed on Jabber server %1 as %2" +msgstr "Authenticatie bij Jabber server %1 als %s mislukt" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:141 +msgid "SSL initialization failed when connecting to Jabber server %1" +msgstr "" +"SSL initialisatie mislukt bij het verbinden met Jabber server %1" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:147 +msgid "Connected to Jabber server %1 as %2" +msgstr "Verbonden met Jabber server %1 als %2" + +#. Construct labels +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:75 +msgid "Chatroom _name:" +msgstr "_Naam van de ruimte:" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:76 +msgid "Chatroom _server:" +msgstr "_Server waar de ruimte zich bevindt:" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:77 +msgid "Chatroom _password:" +msgstr "_Wachtwoord van de ruimte:" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:78 +msgid "Chatroom _handle:" +msgstr "_Handle van de ruimte:" + +#. Button setup and callback registration +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:97 +msgid "Connect to chatroom" +msgstr "Verbinden met ruimte" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:132 +msgid "Synchronizing with chatroom %1@%2 using the handle %3" +msgstr "Bezig met synchroniseren met ruimte %1@%2 met handle %3" + +#. Construct dialog interface +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:78 +msgid "_User's Jabber ID:" +msgstr "Jabber-ID van de gebruiker:" + +#. Buttons +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:82 +msgid "_Invite user" +msgstr "_Gebruiker uitnodigen" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:83 +msgid "_Cancel" +msgstr "_Annuleren" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:94 +msgid "Buddy List" +msgstr "Vriendenlijst" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:170 +msgid "Sending whiteboard invitation to %1" +msgstr "Bezig met verzenden van whiteboard uitnodiging naar %1" + +#. FIXME: strings are replaced by placeholders, NOT to be translated until the code is enabled +#. See http://sourceforge.net/mailarchive/message.php?msg_id=11746016 for details +#. File menu +#. Edit menu +#. View menu +#. Layer menu +#. Object menu +#. Path menu +#. add(Gtk::StockItem(CLEANUP, _("PLACEHOLDER, do not translate"))); (using Gtk::Stock::CLEAR) +#. Text menu +#. About menu +#. Tools toolbox +#. Select Tool controls +#. Node Tool controls +#. Calligraphy Tool controls +#. Session playback controls +#: ../../po/../src/ui/stock-items.cpp:34 ../../po/../src/ui/stock-items.cpp:35 +#: ../../po/../src/ui/stock-items.cpp:36 ../../po/../src/ui/stock-items.cpp:37 +#: ../../po/../src/ui/stock-items.cpp:38 ../../po/../src/ui/stock-items.cpp:39 +#: ../../po/../src/ui/stock-items.cpp:40 ../../po/../src/ui/stock-items.cpp:41 +#: ../../po/../src/ui/stock-items.cpp:42 ../../po/../src/ui/stock-items.cpp:43 +#: ../../po/../src/ui/stock-items.cpp:46 ../../po/../src/ui/stock-items.cpp:47 +#: ../../po/../src/ui/stock-items.cpp:48 ../../po/../src/ui/stock-items.cpp:49 +#: ../../po/../src/ui/stock-items.cpp:50 ../../po/../src/ui/stock-items.cpp:51 +#: ../../po/../src/ui/stock-items.cpp:52 ../../po/../src/ui/stock-items.cpp:53 +#: ../../po/../src/ui/stock-items.cpp:54 ../../po/../src/ui/stock-items.cpp:55 +#: ../../po/../src/ui/stock-items.cpp:56 ../../po/../src/ui/stock-items.cpp:57 +#: ../../po/../src/ui/stock-items.cpp:58 ../../po/../src/ui/stock-items.cpp:59 +#: ../../po/../src/ui/stock-items.cpp:62 ../../po/../src/ui/stock-items.cpp:63 +#: ../../po/../src/ui/stock-items.cpp:64 ../../po/../src/ui/stock-items.cpp:65 +#: ../../po/../src/ui/stock-items.cpp:66 ../../po/../src/ui/stock-items.cpp:67 +#: ../../po/../src/ui/stock-items.cpp:68 ../../po/../src/ui/stock-items.cpp:69 +#: ../../po/../src/ui/stock-items.cpp:70 ../../po/../src/ui/stock-items.cpp:71 +#: ../../po/../src/ui/stock-items.cpp:72 ../../po/../src/ui/stock-items.cpp:73 +#: ../../po/../src/ui/stock-items.cpp:74 ../../po/../src/ui/stock-items.cpp:75 +#: ../../po/../src/ui/stock-items.cpp:76 ../../po/../src/ui/stock-items.cpp:77 +#: ../../po/../src/ui/stock-items.cpp:78 ../../po/../src/ui/stock-items.cpp:79 +#: ../../po/../src/ui/stock-items.cpp:80 ../../po/../src/ui/stock-items.cpp:81 +#: ../../po/../src/ui/stock-items.cpp:82 ../../po/../src/ui/stock-items.cpp:83 +#: ../../po/../src/ui/stock-items.cpp:84 ../../po/../src/ui/stock-items.cpp:85 +#: ../../po/../src/ui/stock-items.cpp:86 ../../po/../src/ui/stock-items.cpp:87 +#: ../../po/../src/ui/stock-items.cpp:88 ../../po/../src/ui/stock-items.cpp:89 +#: ../../po/../src/ui/stock-items.cpp:92 ../../po/../src/ui/stock-items.cpp:93 +#: ../../po/../src/ui/stock-items.cpp:94 ../../po/../src/ui/stock-items.cpp:95 +#: ../../po/../src/ui/stock-items.cpp:96 ../../po/../src/ui/stock-items.cpp:97 +#: ../../po/../src/ui/stock-items.cpp:98 ../../po/../src/ui/stock-items.cpp:99 +#: ../../po/../src/ui/stock-items.cpp:100 +#: ../../po/../src/ui/stock-items.cpp:101 +#: ../../po/../src/ui/stock-items.cpp:102 +#: ../../po/../src/ui/stock-items.cpp:103 +#: ../../po/../src/ui/stock-items.cpp:104 +#: ../../po/../src/ui/stock-items.cpp:105 +#: ../../po/../src/ui/stock-items.cpp:108 +#: ../../po/../src/ui/stock-items.cpp:109 +#: ../../po/../src/ui/stock-items.cpp:110 +#: ../../po/../src/ui/stock-items.cpp:111 +#: ../../po/../src/ui/stock-items.cpp:112 +#: ../../po/../src/ui/stock-items.cpp:113 +#: ../../po/../src/ui/stock-items.cpp:114 +#: ../../po/../src/ui/stock-items.cpp:115 +#: ../../po/../src/ui/stock-items.cpp:116 +#: ../../po/../src/ui/stock-items.cpp:117 +#: ../../po/../src/ui/stock-items.cpp:118 +#: ../../po/../src/ui/stock-items.cpp:119 +#: ../../po/../src/ui/stock-items.cpp:120 +#: ../../po/../src/ui/stock-items.cpp:121 +#: ../../po/../src/ui/stock-items.cpp:122 +#: ../../po/../src/ui/stock-items.cpp:123 +#: ../../po/../src/ui/stock-items.cpp:124 +#: ../../po/../src/ui/stock-items.cpp:125 +#: ../../po/../src/ui/stock-items.cpp:126 +#: ../../po/../src/ui/stock-items.cpp:127 +#: ../../po/../src/ui/stock-items.cpp:130 +#: ../../po/../src/ui/stock-items.cpp:131 +#: ../../po/../src/ui/stock-items.cpp:132 +#: ../../po/../src/ui/stock-items.cpp:133 +#: ../../po/../src/ui/stock-items.cpp:134 +#: ../../po/../src/ui/stock-items.cpp:135 +#: ../../po/../src/ui/stock-items.cpp:136 +#: ../../po/../src/ui/stock-items.cpp:137 +#: ../../po/../src/ui/stock-items.cpp:138 +#: ../../po/../src/ui/stock-items.cpp:139 +#: ../../po/../src/ui/stock-items.cpp:140 +#: ../../po/../src/ui/stock-items.cpp:141 +#: ../../po/../src/ui/stock-items.cpp:142 +#: ../../po/../src/ui/stock-items.cpp:143 +#: ../../po/../src/ui/stock-items.cpp:144 +#: ../../po/../src/ui/stock-items.cpp:145 +#: ../../po/../src/ui/stock-items.cpp:146 +#: ../../po/../src/ui/stock-items.cpp:150 +#: ../../po/../src/ui/stock-items.cpp:151 +#: ../../po/../src/ui/stock-items.cpp:152 +#: ../../po/../src/ui/stock-items.cpp:153 +#: ../../po/../src/ui/stock-items.cpp:156 +#: ../../po/../src/ui/stock-items.cpp:157 +#: ../../po/../src/ui/stock-items.cpp:158 +#: ../../po/../src/ui/stock-items.cpp:161 +#: ../../po/../src/ui/stock-items.cpp:162 +#: ../../po/../src/ui/stock-items.cpp:163 +#: ../../po/../src/ui/stock-items.cpp:164 +#: ../../po/../src/ui/stock-items.cpp:165 +#: ../../po/../src/ui/stock-items.cpp:166 +#: ../../po/../src/ui/stock-items.cpp:167 +#: ../../po/../src/ui/stock-items.cpp:168 +#: ../../po/../src/ui/stock-items.cpp:169 +#: ../../po/../src/ui/stock-items.cpp:170 +#: ../../po/../src/ui/stock-items.cpp:171 +#: ../../po/../src/ui/stock-items.cpp:172 +#: ../../po/../src/ui/stock-items.cpp:175 +#: ../../po/../src/ui/stock-items.cpp:176 +#: ../../po/../src/ui/stock-items.cpp:177 +#: ../../po/../src/ui/stock-items.cpp:178 +#: ../../po/../src/ui/stock-items.cpp:181 +#: ../../po/../src/ui/stock-items.cpp:182 +#: ../../po/../src/ui/stock-items.cpp:183 +#: ../../po/../src/ui/stock-items.cpp:184 +#: ../../po/../src/ui/stock-items.cpp:185 +#: ../../po/../src/ui/stock-items.cpp:186 +#: ../../po/../src/ui/stock-items.cpp:187 +#: ../../po/../src/ui/stock-items.cpp:188 +#: ../../po/../src/ui/stock-items.cpp:189 +#: ../../po/../src/ui/stock-items.cpp:190 +#: ../../po/../src/ui/stock-items.cpp:191 +#: ../../po/../src/ui/stock-items.cpp:194 +#: ../../po/../src/ui/stock-items.cpp:195 +#: ../../po/../src/ui/stock-items.cpp:198 +#: ../../po/../src/ui/stock-items.cpp:199 +#: ../../po/../src/ui/stock-items.cpp:200 +#: ../../po/../src/ui/stock-items.cpp:201 +#: ../../po/../src/ui/stock-items.cpp:202 +msgid "PLACEHOLDER, do not translate" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:88 +msgid "small" +msgstr "klein" + +#: ../../po/../src/ui/widget/panel.cpp:89 +msgid "medium" +msgstr "middel" + +#: ../../po/../src/ui/widget/panel.cpp:90 +msgid "large" +msgstr "groot" + +#: ../../po/../src/ui/widget/panel.cpp:91 +msgid "huge" +msgstr "gigantisch" + +#: ../../po/../src/ui/widget/panel.cpp:106 +msgid "List" +msgstr "Lijst" + +#: ../../po/../src/ui/widget/selected-style.cpp:67 +msgid "F:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:68 +msgid "S:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:69 +msgid "O:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:95 +msgid "N/A" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:98 +#: ../../po/../src/ui/widget/selected-style.cpp:712 +#, fuzzy +msgid "Nothing selected" +msgstr "Geen kleurverloop geselecteerd" + +#: ../../po/../src/ui/widget/selected-style.cpp:103 +msgid "No fill" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:103 +#, fuzzy +msgid "No stroke" +msgstr "(lijn)" + +#: ../../po/../src/ui/widget/selected-style.cpp:105 +#: ../../po/../src/widgets/paint-selector.cpp:190 +msgid "Pattern" +msgstr "Patroon" + +#: ../../po/../src/ui/widget/selected-style.cpp:108 +#: ../../po/../src/widgets/paint-selector.cpp:885 +msgid "Pattern fill" +msgstr "Patroon vulling" + +#: ../../po/../src/ui/widget/selected-style.cpp:108 +#, fuzzy +msgid "Pattern stroke" +msgstr "Patroon inspring" + +#: ../../po/../src/ui/widget/selected-style.cpp:110 +#, fuzzy +msgid "L Gradient" +msgstr "Kleurverloop" + +#: ../../po/../src/ui/widget/selected-style.cpp:113 +#, fuzzy +msgid "Linear gradient fill" +msgstr "Lineair kleurverloop" + +#: ../../po/../src/ui/widget/selected-style.cpp:113 +#, fuzzy +msgid "Linear gradient stroke" +msgstr "Lineair kleurverloop" + +#: ../../po/../src/ui/widget/selected-style.cpp:115 +#, fuzzy +msgid "R Gradient" +msgstr "Kleurverloop" + +#: ../../po/../src/ui/widget/selected-style.cpp:118 +#, fuzzy +msgid "Radial gradient fill" +msgstr "Cirkelvormig kleurverloop" + +#: ../../po/../src/ui/widget/selected-style.cpp:118 +#, fuzzy +msgid "Radial gradient stroke" +msgstr "Cirkelvormig kleurverloop" + +#: ../../po/../src/ui/widget/selected-style.cpp:120 +#, fuzzy +msgid "Different" +msgstr "_Verschil" + +#: ../../po/../src/ui/widget/selected-style.cpp:123 +#, fuzzy +msgid "Different fills" +msgstr "_Verschil" + +#: ../../po/../src/ui/widget/selected-style.cpp:123 +#, fuzzy +msgid "Different strokes" +msgstr "_Verschil" + +#: ../../po/../src/ui/widget/selected-style.cpp:125 +#, fuzzy +msgid "Unset" +msgstr "binnenrand" + +#. TRANSLATORS COMMENT: unset is a verb here +#: ../../po/../src/ui/widget/selected-style.cpp:128 +#: ../../po/../src/ui/widget/selected-style.cpp:182 +msgid "Unset fill" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:128 +#: ../../po/../src/ui/widget/selected-style.cpp:182 +#, fuzzy +msgid "Unset stroke" +msgstr "(lijn)" + +#: ../../po/../src/ui/widget/selected-style.cpp:131 +#, fuzzy +msgid "Flat color fill" +msgstr "Egale kleur" + +#: ../../po/../src/ui/widget/selected-style.cpp:131 +#, fuzzy +msgid "Flat color stroke" +msgstr "Egale kleur" + +#. TRANSLATOR COMMENT: A means "Averaged" +#: ../../po/../src/ui/widget/selected-style.cpp:134 +#, fuzzy +msgid "A" +msgstr "_A" + +#: ../../po/../src/ui/widget/selected-style.cpp:137 +#, fuzzy +msgid "Fill is averaged over selected objects" +msgstr "'Exclusive-OR' van de geselecteerde objecten" + +#: ../../po/../src/ui/widget/selected-style.cpp:137 +#, fuzzy +msgid "Stroke is averaged over selected objects" +msgstr "Zorg dat verbinders de geselecteerde objecten ontwijken" + +#. TRANSLATOR COMMENT: M means "Multiple" +#: ../../po/../src/ui/widget/selected-style.cpp:140 +#, fuzzy +msgid "M" +msgstr "_M" + +#: ../../po/../src/ui/widget/selected-style.cpp:143 +#, fuzzy +msgid "Multiple selected objects have the same fill" +msgstr "De geselecteerde knopen verticaal uitlijnen" + +#: ../../po/../src/ui/widget/selected-style.cpp:143 +#, fuzzy +msgid "Multiple selected objects have the same stroke" +msgstr "De geselecteerde knopen verticaal uitlijnen" + +#: ../../po/../src/ui/widget/selected-style.cpp:145 +#, fuzzy +msgid "Edit fill..." +msgstr "Bewerken..." + +#: ../../po/../src/ui/widget/selected-style.cpp:145 +#, fuzzy +msgid "Edit stroke..." +msgstr "Bewerken..." + +#: ../../po/../src/ui/widget/selected-style.cpp:149 +#, fuzzy +msgid "Last set color" +msgstr "Egale kleur" + +#: ../../po/../src/ui/widget/selected-style.cpp:153 +#, fuzzy +msgid "Last selected color" +msgstr "Laatst geselecteerde" + +#: ../../po/../src/ui/widget/selected-style.cpp:157 +#, fuzzy +msgid "White" +msgstr "Whiteboa_rd" + +#: ../../po/../src/ui/widget/selected-style.cpp:161 +#: ../../po/../src/widgets/sp-color-scales.cpp:461 +#: ../../po/../src/widgets/sp-color-scales.cpp:462 +msgid "Black" +msgstr "Zwart (K)" + +#: ../../po/../src/ui/widget/selected-style.cpp:165 +#, fuzzy +msgid "Copy color" +msgstr "Overgangskleur" + +#: ../../po/../src/ui/widget/selected-style.cpp:169 +#, fuzzy +msgid "Paste color" +msgstr "Egale kleur" + +#: ../../po/../src/ui/widget/selected-style.cpp:173 +#, fuzzy +msgid "Swap fill and stroke" +msgstr "_Opvulling en lijnen" + +#: ../../po/../src/ui/widget/selected-style.cpp:177 +msgid "Make fill opaque" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:177 +msgid "Make stroke opaque" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:186 +#, fuzzy +msgid "Remove fill" +msgstr "_Verwijderen" + +#: ../../po/../src/ui/widget/selected-style.cpp:186 +#, fuzzy +msgid "Remove stroke" +msgstr "Koppeling verwijder" + +#: ../../po/../src/ui/widget/selected-style.cpp:718 +#, fuzzy +msgid "Master opacity" +msgstr "Hoofd-_ondoorzichtigheid" + +#: ../../po/../src/ui/widget/selected-style.cpp:744 +msgid "0 (transparent)" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:768 +msgid "1.0 (opaque)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1046 +msgid "Moved to next layer." +msgstr "Verplaatst naar de volgende laag." + +#: ../../po/../src/verbs.cpp:1048 +#, fuzzy +msgid "Cannot move past last layer." +msgstr "Kan niet voorbij de laatste laag verplaatsen." + +#: ../../po/../src/verbs.cpp:1057 +msgid "Moved to previous layer." +msgstr "Verplaatst naar de vorige laag." + +#: ../../po/../src/verbs.cpp:1059 +#, fuzzy +msgid "Cannot move past first layer." +msgstr "Kan niet voorbij de eerste laag verplaatsen." + +#: ../../po/../src/verbs.cpp:1076 ../../po/../src/verbs.cpp:1150 +msgid "No current layer." +msgstr "Geen huidige laag." + +#: ../../po/../src/verbs.cpp:1105 +#, c-format +msgid "Raised layer %s." +msgstr "Laag %s is naar boven gebracht." + +#: ../../po/../src/verbs.cpp:1109 +#, c-format +msgid "Lowered layer %s." +msgstr "Laag %s is omlaag gebracht." + +#: ../../po/../src/verbs.cpp:1118 +#, fuzzy +msgid "Cannot move layer any further." +msgstr "De laag kan niet verder worden verplaatst." + +#. TRANSLATORS: this means "The layer has been deleted." +#: ../../po/../src/verbs.cpp:1148 +msgid "Deleted layer." +msgstr "De laag is verwijderd." + +#: ../../po/../src/verbs.cpp:1544 +msgid "" +"You need to connect to a Jabber server before sharing a document with " +"another user." +msgstr "" +"U moet verbonden zijn met een Jabber server voordat u een document kunt " +"delen met een andere gebruiker." + +#: ../../po/../src/verbs.cpp:1559 +msgid "" +"You need to connect to a Jabber server before sharing a document with a " +"chatroom." +msgstr "" +"U moet verbonden zijn met een Jabber server voordat u een document kunt " +"delen met een ruimte." + +#: ../../po/../src/verbs.cpp:1569 +msgid "XML node tracker has not been initialized; nothing to dump" +msgstr "" + +#. TRANSLATORS: If you have translated the keys.svg file to your language, then +#. translate this string as "keys.LANG.svg" (where LANG is your language code); +#. otherwise leave as "keys.svg". +#: ../../po/../src/verbs.cpp:1631 +msgid "keys.svg" +msgstr "" + +#. TRANSLATORS: If you have translated the tutorial-basic.svg file to your language, +#. then translate this string as "tutorial-basic.LANG.svg" (where LANG is your language +#. code); otherwise leave as "tutorial-basic.svg". +#: ../../po/../src/verbs.cpp:1667 +msgid "tutorial-basic.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1671 +msgid "tutorial-shapes.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1675 +msgid "tutorial-advanced.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1679 +msgid "tutorial-tracing.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1683 +msgid "tutorial-calligraphy.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1687 +msgid "tutorial-elements.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1691 +msgid "tutorial-tips.svg" +msgstr "" + +#: ../../po/../src/verbs.cpp:1842 +msgid "Does nothing" +msgstr "(Doet niets)" + +#. File +#: ../../po/../src/verbs.cpp:1845 +msgid "Default" +msgstr "Normaal" + +#: ../../po/../src/verbs.cpp:1845 +msgid "Create new document from default template" +msgstr "Maak een nieuw document volgens het standaard sjabloon" + +#: ../../po/../src/verbs.cpp:1847 +msgid "_Open..." +msgstr "_Openen..." + +#: ../../po/../src/verbs.cpp:1848 +msgid "Open existing document" +msgstr "Open een bestaand document" + +#: ../../po/../src/verbs.cpp:1849 +msgid "Re_vert" +msgstr "_Terugdraaien" + +#: ../../po/../src/verbs.cpp:1850 +msgid "Revert to the last saved version of document (changes will be lost)" +msgstr "Terugkeren naar de laatste-opgeslagen versie van het document" + +#: ../../po/../src/verbs.cpp:1851 +msgid "_Save" +msgstr "Op_slaan" + +#: ../../po/../src/verbs.cpp:1851 +msgid "Save document" +msgstr "Document opslaan" + +#: ../../po/../src/verbs.cpp:1853 +msgid "Save _As..." +msgstr "Opslaan _als..." + +#: ../../po/../src/verbs.cpp:1854 +msgid "Save document under new name" +msgstr "Document opslaan onder een nieuw naam" + +#: ../../po/../src/verbs.cpp:1855 +msgid "_Print..." +msgstr "Af_drukken..." + +#: ../../po/../src/verbs.cpp:1855 +msgid "Print document" +msgstr "Document afdrukken" + +#. TRANSLATORS: "Vacuum Defs" means "Clean up defs" (so as to remove unused definitions) +#: ../../po/../src/verbs.cpp:1858 +msgid "Vac_uum Defs" +msgstr "_Definities opruimen" + +#: ../../po/../src/verbs.cpp:1858 +#, fuzzy +msgid "Remove unused predefined items from the <defs> of the document" +msgstr "Ongebruikte items uit het <defs>-onderdeel van het bestand halen" + +#: ../../po/../src/verbs.cpp:1860 +msgid "Print _Direct" +msgstr "_Direct afdrukken" + +#: ../../po/../src/verbs.cpp:1861 +#, fuzzy +msgid "Print directly without prompting to a file or pipe" +msgstr "Direct afdrukken naar een pipe of een bestand" + +#: ../../po/../src/verbs.cpp:1862 +msgid "Print Previe_w" +msgstr "Afdruk_voorbeeld" + +#: ../../po/../src/verbs.cpp:1863 +msgid "Preview document printout" +msgstr "Afdrukvoorbeeld" + +#: ../../po/../src/verbs.cpp:1864 +msgid "_Import..." +msgstr "_Importeren..." + +#: ../../po/../src/verbs.cpp:1865 +msgid "Import bitmap or SVG image into document" +msgstr "Bitmap of SVG-bestand in het document importeren" + +#: ../../po/../src/verbs.cpp:1866 +msgid "_Export Bitmap..." +msgstr "Bitmap _exporteren..." + +#: ../../po/../src/verbs.cpp:1867 +#, fuzzy +msgid "Export document or selection as a bitmap image" +msgstr "Document of selectie als PNG bitmap exporteren" + +#: ../../po/../src/verbs.cpp:1868 +msgid "N_ext Window" +msgstr "_Volgende vensters" + +#: ../../po/../src/verbs.cpp:1869 +msgid "Switch to the next document window" +msgstr "Wisselen naar het volgende document-venster" + +#: ../../po/../src/verbs.cpp:1870 +msgid "P_revious Window" +msgstr "V_orige venster" + +#: ../../po/../src/verbs.cpp:1871 +msgid "Switch to the previous document window" +msgstr "Wisselen naar het vorige document-venster" + +#: ../../po/../src/verbs.cpp:1872 +msgid "_Close" +msgstr "Sl_uiten" + +#: ../../po/../src/verbs.cpp:1873 +msgid "Close window" +msgstr "Venster sluiten" + +#: ../../po/../src/verbs.cpp:1874 +msgid "_Quit" +msgstr "A_fsluiten" + +#: ../../po/../src/verbs.cpp:1874 +msgid "Quit Inkscape" +msgstr "Inkscape afsluien" + +#. Edit +#: ../../po/../src/verbs.cpp:1877 +msgid "_Undo" +msgstr "_Ongedaan maken" + +#: ../../po/../src/verbs.cpp:1877 +msgid "Undo last action" +msgstr "De laatste bewerking ongedaan maken" + +#: ../../po/../src/verbs.cpp:1879 +msgid "_Redo" +msgstr "O_pnieuw" + +#: ../../po/../src/verbs.cpp:1880 +msgid "Do again last undone action" +msgstr "De ongedaan gemaakte actie opnieuw uitvoeren" + +#: ../../po/../src/verbs.cpp:1881 +msgid "Cu_t" +msgstr "K_nippen" + +#: ../../po/../src/verbs.cpp:1882 +msgid "Cut selection to clipboard" +msgstr "De selectie knippen en op het klembord plaatsen" + +#: ../../po/../src/verbs.cpp:1883 +msgid "_Copy" +msgstr "_Kopiëren" + +#: ../../po/../src/verbs.cpp:1884 +msgid "Copy selection to clipboard" +msgstr "De selectie kopiëren en op het klembord plaatsen" + +#: ../../po/../src/verbs.cpp:1885 +msgid "_Paste" +msgstr "_Plakken" + +#: ../../po/../src/verbs.cpp:1886 +#, fuzzy +msgid "Paste objects from clipboard to mouse point" +msgstr "Objecten plakken van het klembord naar waar de muis staat" + +#: ../../po/../src/verbs.cpp:1887 +msgid "Paste _Style" +msgstr "Plak _stijl" + +#: ../../po/../src/verbs.cpp:1888 +msgid "Apply style of the copied object to selection" +msgstr "De stijl van het gekopieerde object op de selectie toepassen." + +#: ../../po/../src/verbs.cpp:1889 +msgid "Paste _In Place" +msgstr "Plak _op positie" + +#: ../../po/../src/verbs.cpp:1890 +#, fuzzy +msgid "Paste objects from clipboard to the original location" +msgstr "Objecten plakken van het klembord naar hun originele locatie" + +#: ../../po/../src/verbs.cpp:1891 +msgid "_Delete" +msgstr "_Verwijderen" + +#: ../../po/../src/verbs.cpp:1892 +msgid "Delete selection" +msgstr "De selectie verwijderen" + +#: ../../po/../src/verbs.cpp:1893 +msgid "Duplic_ate" +msgstr "_Dupliceren" + +#: ../../po/../src/verbs.cpp:1894 +#, fuzzy +msgid "Duplicate selected objects" +msgstr "Geselecteerde object(en) dupliceren" + +#: ../../po/../src/verbs.cpp:1895 +msgid "Clo_ne" +msgstr "_Klonen" + +#: ../../po/../src/verbs.cpp:1896 +msgid "Create a clone of selected object (a copy linked to the original)" +msgstr "" +"Een kloon (een kopie die aan het origineel gekoppeld is) maken van de " +"selectie" + +#: ../../po/../src/verbs.cpp:1897 +msgid "Unlin_k Clone" +msgstr "Kloo_n ontkoppelen" + +#: ../../po/../src/verbs.cpp:1898 +msgid "Cut the clone's link to its original" +msgstr "De koppeling van de kloon naar zijn origineel verwijderen" + +#: ../../po/../src/verbs.cpp:1899 +msgid "Select _Original" +msgstr "_Origineel selecteren" + +#: ../../po/../src/verbs.cpp:1900 +msgid "Select the object to which the clone is linked" +msgstr "Selecteer het object waaraan de kloon is gekoppeld" + +#. TRANSLATORS: Convert selection to a rectangle with tiled pattern fill +#: ../../po/../src/verbs.cpp:1902 +msgid "O_bjects to Pattern" +msgstr "O_bjecten naar patroon" + +#: ../../po/../src/verbs.cpp:1903 +msgid "Convert selection to a rectangle with tiled pattern fill" +msgstr "Zet de selectie om naar een rechthoek gevuld met een getegeld patroon" + +#. TRANSLATORS: Extract objects from a tiled pattern fill +#: ../../po/../src/verbs.cpp:1905 +msgid "Pattern to Ob_jects" +msgstr "Patroon naar objecten" + +#: ../../po/../src/verbs.cpp:1906 +msgid "Extract objects from a tiled pattern fill" +msgstr "Objecten uit een getegeld patroon extraheren" + +#: ../../po/../src/verbs.cpp:1907 +msgid "Clea_r All" +msgstr "Alles verwijderen" + +#: ../../po/../src/verbs.cpp:1908 +msgid "Delete all objects from document" +msgstr "Alle objecten van het document verwijderen" + +#: ../../po/../src/verbs.cpp:1909 +msgid "Select Al_l" +msgstr "A_lles selecteren" + +#: ../../po/../src/verbs.cpp:1910 +msgid "Select all objects or all nodes" +msgstr "Alle objecten of knooppunten selecteren" + +#: ../../po/../src/verbs.cpp:1911 +msgid "Select All in All La_yers" +msgstr "Alles selecteren in alle lagen" + +#: ../../po/../src/verbs.cpp:1912 +msgid "Select all objects in all visible and unlocked layers" +msgstr "Alle objecten in alle zichtbare en niet-vergrendelde lagen selecteren" + +#: ../../po/../src/verbs.cpp:1913 +msgid "In_vert Selection" +msgstr "Selectie inverteren" + +#: ../../po/../src/verbs.cpp:1914 +msgid "Invert selection (unselect what is selected and select everything else)" +msgstr "" +"De selectie omkeren (alleen dat selecteren wat nu niet geselecteerd is)" + +#: ../../po/../src/verbs.cpp:1915 +msgid "Invert in All Layers" +msgstr "Omdraaien in alle lagen" + +#: ../../po/../src/verbs.cpp:1916 +msgid "Invert selection in all visible and unlocked layers" +msgstr "De selectie omkeren in alle zichtbare en niet-vergrendelde lagen" + +#: ../../po/../src/verbs.cpp:1917 +msgid "D_eselect" +msgstr "S_electie opheffen" + +#: ../../po/../src/verbs.cpp:1918 +msgid "Deselect any selected objects or nodes" +msgstr "Zorg dat niets meer geselecteerd is" + +#. Selection +#: ../../po/../src/verbs.cpp:1921 +msgid "Raise to _Top" +msgstr "_Bovenaan" + +#: ../../po/../src/verbs.cpp:1922 +msgid "Raise selection to top" +msgstr "De selectie boven alle anderen plaatsen" + +#: ../../po/../src/verbs.cpp:1923 +msgid "Lower to _Bottom" +msgstr "_Onderaan" + +#: ../../po/../src/verbs.cpp:1924 +msgid "Lower selection to bottom" +msgstr "De selectie onder alle anderen plaatsen" + +#: ../../po/../src/verbs.cpp:1925 +msgid "_Raise" +msgstr "Om_hoog" + +#: ../../po/../src/verbs.cpp:1926 +msgid "Raise selection one step" +msgstr "De selectie één niveau omhoog halen" + +#: ../../po/../src/verbs.cpp:1927 +msgid "_Lower" +msgstr "Om_laag" + +#: ../../po/../src/verbs.cpp:1928 +msgid "Lower selection one step" +msgstr "De selectie één niveau omlaag brengen" + +#: ../../po/../src/verbs.cpp:1929 +msgid "_Group" +msgstr "_Groeperen" + +#: ../../po/../src/verbs.cpp:1930 +msgid "Group selected objects" +msgstr "De geselecteerde objecten groeperen" + +#: ../../po/../src/verbs.cpp:1932 +#, fuzzy +msgid "Ungroup selected groups" +msgstr "De geselecteerde groep(en) degroeperen" + +#: ../../po/../src/verbs.cpp:1934 +msgid "_Put on Path" +msgstr "Op _pad plaatsen" + +#: ../../po/../src/verbs.cpp:1935 +msgid "Put text on path" +msgstr "Tekst op een pad plaatsen" + +#: ../../po/../src/verbs.cpp:1936 +msgid "_Remove from Path" +msgstr "Van pad _verwijderen" + +#: ../../po/../src/verbs.cpp:1937 +msgid "Remove text from path" +msgstr "Tekst van een pad verwijderen" + +#: ../../po/../src/verbs.cpp:1938 +msgid "Remove Manual _Kerns" +msgstr "_Tekenspatiëring herstellen" + +#. TRANSLATORS: "glyph": An image used in the visual representation of characters; +#. roughly speaking, how a character looks. A font is a set of glyphs. +#: ../../po/../src/verbs.cpp:1941 +msgid "Remove all manual kerns and glyph rotations from a text object" +msgstr "Tekenspatiëring en karakter-rotaties van het tekstobject herstellen" + +#: ../../po/../src/verbs.cpp:1943 +msgid "_Union" +msgstr "_Vereniging" + +#: ../../po/../src/verbs.cpp:1944 +msgid "Union of selected objects" +msgstr "Samensmelting van de geselecteerde objecten" + +#: ../../po/../src/verbs.cpp:1945 +msgid "_Intersection" +msgstr "_Overlap" + +#: ../../po/../src/verbs.cpp:1946 +msgid "Intersection of selected objects" +msgstr "De overlap tussen de geselecteerde objecten" + +#: ../../po/../src/verbs.cpp:1947 +msgid "_Difference" +msgstr "_Verschil" + +#: ../../po/../src/verbs.cpp:1948 +msgid "Difference of selected objects (bottom minus top)" +msgstr "" +"Het verschil tussen de geselecteerde objecten (de onderste minus de bovenste)" + +#: ../../po/../src/verbs.cpp:1949 +msgid "E_xclusion" +msgstr "_Uitsluiting" + +#: ../../po/../src/verbs.cpp:1950 +msgid "Exclusive OR of selected objects" +msgstr "'Exclusive-OR' van de geselecteerde objecten" + +#: ../../po/../src/verbs.cpp:1951 +msgid "Di_vision" +msgstr "_Splitsing" + +#: ../../po/../src/verbs.cpp:1952 +msgid "Cut the bottom object into pieces" +msgstr "Splits het onderste object in stukken" + +#. TRANSLATORS: "to cut a path" is not the same as "to break a path apart" - see the +#. Advanced tutorial for more info +#: ../../po/../src/verbs.cpp:1955 +msgid "Cut _Path" +msgstr "_Pad snijden" + +#: ../../po/../src/verbs.cpp:1956 +msgid "Cut the bottom object's stroke into pieces, removing fill" +msgstr "" +"Snij de omlijning van het onderste object in stukken (de vulling gaat " +"verloren)" + +#. TRANSLATORS: "outset": expand a shape by offsetting the object's path, +#. i.e. by displacing it perpendicular to the path in each point. +#. See also the Advanced Tutorial for explanation. +#: ../../po/../src/verbs.cpp:1960 +msgid "Outs_et" +msgstr "Buit_enrand" + +#: ../../po/../src/verbs.cpp:1961 +#, fuzzy +msgid "Outset selected paths" +msgstr "De geselecteerde paden vergroten met een buitenrand" + +#: ../../po/../src/verbs.cpp:1963 +msgid "O_utset Path by 1 px" +msgstr "B_uitenrand van 1 pixel toevoegen" + +#: ../../po/../src/verbs.cpp:1964 +#, fuzzy +msgid "Outset selected paths by 1 px" +msgstr "De geselecteerde paden vergroten met een buitenrand van 1 pixel" + +#: ../../po/../src/verbs.cpp:1966 +msgid "O_utset Path by 10 px" +msgstr "B_uitenrand van 10 pixels toevoegen" + +#: ../../po/../src/verbs.cpp:1967 +#, fuzzy +msgid "Outset selected paths by 10 px" +msgstr "De geselecteerde paden vergroten met een buitenrand van 10 pixels" + +#. TRANSLATORS: "inset": contract a shape by offsetting the object's path, +#. i.e. by displacing it perpendicular to the path in each point. +#. See also the Advanced Tutorial for explanation. +#: ../../po/../src/verbs.cpp:1971 +msgid "I_nset" +msgstr "Bi_nnenrand" + +#: ../../po/../src/verbs.cpp:1972 +#, fuzzy +msgid "Inset selected paths" +msgstr "De geselecteerde paden verkleinen met een binnenrand" + +#: ../../po/../src/verbs.cpp:1974 +msgid "I_nset Path by 1 px" +msgstr "Bi_nnenrand van 1 pixel verwijderen" + +#: ../../po/../src/verbs.cpp:1975 +#, fuzzy +msgid "Inset selected paths by 1 px" +msgstr "De geselecteerde paden verkleinen met een binnenrand van 1 pixel" + +#: ../../po/../src/verbs.cpp:1977 +msgid "I_nset Path by 10 px" +msgstr "Bi_nnenrand van 10 pixels verwijderen" + +#: ../../po/../src/verbs.cpp:1978 +#, fuzzy +msgid "Inset selected paths by 10 px" +msgstr "De geselecteerde paden verkleinen met een binnenrand van 10 pixels" + +#: ../../po/../src/verbs.cpp:1980 +msgid "D_ynamic Offset" +msgstr "D_ynamische rand" + +#: ../../po/../src/verbs.cpp:1980 +msgid "Create a dynamic offset object" +msgstr "Een 'dynamische rand'-object aanmaken" + +#: ../../po/../src/verbs.cpp:1982 +msgid "_Linked Offset" +msgstr "_Gekoppelde rand" + +#: ../../po/../src/verbs.cpp:1983 +msgid "Create a dynamic offset object linked to the original path" +msgstr "Maak een 'dynamische rand'-object, gekoppeld aan het originele pad" + +#: ../../po/../src/verbs.cpp:1985 +msgid "_Stroke to Path" +msgstr "_Lijn naar pad" + +#: ../../po/../src/verbs.cpp:1986 +#, fuzzy +msgid "Convert selected strokes to paths" +msgstr "De geselecteerde lijn(en) omzetten naar pad(en)" + +#: ../../po/../src/verbs.cpp:1987 +msgid "Si_mplify" +msgstr "_Vereenvoudigen" + +#: ../../po/../src/verbs.cpp:1988 +#, fuzzy +msgid "Simplify selected paths by removing extra nodes" +msgstr "Vereenvoudig de geselecteerde paden door knooppunten te verwijderen" + +#: ../../po/../src/verbs.cpp:1989 +msgid "_Reverse" +msgstr "_Omdraaien" + +#: ../../po/../src/verbs.cpp:1990 +#, fuzzy +msgid "Reverses the direction of selected paths; useful for flipping markers" +msgstr "" +"De richting van de geselecteerde paden omdraaien; handig om markeringen om " +"te draaien" + +#. TRANSLATORS: "to trace" means "to convert a bitmap to vector graphics" (to vectorize) +#: ../../po/../src/verbs.cpp:1992 +msgid "_Trace Bitmap" +msgstr "Bitmap _overtrekken" + +#: ../../po/../src/verbs.cpp:1993 +msgid "Convert bitmap object to paths" +msgstr "Een bitmap overtrekken en omzetten naar paden" + +#: ../../po/../src/verbs.cpp:1994 +msgid "_Make a Bitmap Copy" +msgstr "Kopieer als bitmap" + +#: ../../po/../src/verbs.cpp:1995 +msgid "Export selection to a bitmap and insert it into document" +msgstr "De selectie omzetten naar een bitmap en in het document importeren" + +#: ../../po/../src/verbs.cpp:1996 +msgid "_Combine" +msgstr "_Combineren" + +#: ../../po/../src/verbs.cpp:1997 +msgid "Combine several paths into one" +msgstr "Verschillende paden combineren tot één pad" + +#. TRANSLATORS: "to cut a path" is not the same as "to break a path apart" - see the +#. Advanced tutorial for more info +#: ../../po/../src/verbs.cpp:2000 +msgid "Break _Apart" +msgstr "_Los maken" + +#: ../../po/../src/verbs.cpp:2001 +#, fuzzy +msgid "Break selected paths into subpaths" +msgstr "Splits de geselecteerde paden in subpaden" + +#: ../../po/../src/verbs.cpp:2002 +msgid "Gri_d Arrange..." +msgstr "Rangschikken in rooster..." + +#: ../../po/../src/verbs.cpp:2003 +msgid "Arrange selection in grid pattern" +msgstr "De selectie rangschikken in een rooster" + +#. Layer +#: ../../po/../src/verbs.cpp:2005 +msgid "_Add Layer..." +msgstr "_Nieuwe laag..." + +#: ../../po/../src/verbs.cpp:2006 +msgid "Create a new layer" +msgstr "Een nieuwe laag maken" + +#: ../../po/../src/verbs.cpp:2007 +msgid "Re_name Layer..." +msgstr "Laag hernoe_men..." + +#: ../../po/../src/verbs.cpp:2008 +msgid "Rename the current layer" +msgstr "De huidige laag hernoemen" + +#: ../../po/../src/verbs.cpp:2009 +msgid "Switch to Layer Abov_e" +msgstr "_Wisselen naar de laag erboven" + +#: ../../po/../src/verbs.cpp:2010 +msgid "Switch to the layer above the current" +msgstr "Wisselen naar de laag in het document die boven de huidige ligt" + +#: ../../po/../src/verbs.cpp:2011 +msgid "Switch to Layer Belo_w" +msgstr "W_isselen naar de laag eronder" + +#: ../../po/../src/verbs.cpp:2012 +msgid "Switch to the layer below the current" +msgstr "Wisselen naar de laag in het document die onder de huidige ligt" + +#: ../../po/../src/verbs.cpp:2013 +msgid "Move Selection to Layer Abo_ve" +msgstr "_Selectie omhoog verplaatsen" + +#: ../../po/../src/verbs.cpp:2014 +msgid "Move selection to the layer above the current" +msgstr "De geselecteerde objecten naar de laag boven de huidige verplaatsen" + +#: ../../po/../src/verbs.cpp:2015 +msgid "Move Selection to Layer Bel_ow" +msgstr "S_electie omlaag verplaatsen" + +#: ../../po/../src/verbs.cpp:2016 +msgid "Move selection to the layer below the current" +msgstr "De geselecteerde objecten naar de laag onder de huidige verplaatsen" + +#: ../../po/../src/verbs.cpp:2017 +msgid "Layer to _Top" +msgstr "Laag _bovenaan" + +#: ../../po/../src/verbs.cpp:2018 +msgid "Raise the current layer to the top" +msgstr "De huidige laag boven alle andere plaatsen" + +#: ../../po/../src/verbs.cpp:2019 +msgid "Layer to _Bottom" +msgstr "Laag _onderaan" + +#: ../../po/../src/verbs.cpp:2020 +msgid "Lower the current layer to the bottom" +msgstr "De huidige laag onder alle onderen plaatsen" + +#: ../../po/../src/verbs.cpp:2021 +msgid "_Raise Layer" +msgstr "Laag om_hoog" + +#: ../../po/../src/verbs.cpp:2022 +msgid "Raise the current layer" +msgstr "De huidige laag één niveau omhoog brengen" + +#: ../../po/../src/verbs.cpp:2023 +msgid "_Lower Layer" +msgstr "Laag om_laag" + +#: ../../po/../src/verbs.cpp:2024 +msgid "Lower the current layer" +msgstr "De huidige laag één niveau omlaag brengen" + +#: ../../po/../src/verbs.cpp:2025 +msgid "_Delete Current Layer" +msgstr "Laag _verwijderen" + +#: ../../po/../src/verbs.cpp:2026 +msgid "Delete the current layer" +msgstr "De huidige laag verwijderen" + +#. Object +#: ../../po/../src/verbs.cpp:2029 +#, fuzzy +msgid "Rotate _90° CW" +msgstr "_90 graden draaien MKM" + +#: ../../po/../src/verbs.cpp:2030 +#, fuzzy +msgid "Rotate selection 90° clockwise" +msgstr "De selectie 90 graden met de klok mee draaien" + +#: ../../po/../src/verbs.cpp:2031 +#, fuzzy +msgid "Rotate 9_0° CCW" +msgstr "9_0 graden draaien TKI" + +#: ../../po/../src/verbs.cpp:2032 +#, fuzzy +msgid "Rotate selection 90° counter-clockwise" +msgstr "De selectie 90 graden tegen de klok in draaien" + +#: ../../po/../src/verbs.cpp:2033 +msgid "Remove _Transformations" +msgstr "_Transformaties verwijderen" + +#: ../../po/../src/verbs.cpp:2034 +msgid "Remove transformations from object" +msgstr "Transformaties verwijderen van het object" + +#: ../../po/../src/verbs.cpp:2035 +msgid "_Object to Path" +msgstr "_Object naar pad" + +#: ../../po/../src/verbs.cpp:2036 +#, fuzzy +msgid "Convert selected objects to paths" +msgstr "De selectie omzetten naar paden" + +#: ../../po/../src/verbs.cpp:2037 +msgid "_Flow into Frame" +msgstr "Naar object _vormen" + +#: ../../po/../src/verbs.cpp:2038 +#, fuzzy +msgid "Put text into frames" +msgstr "Tekst vormen naar een object" + +#: ../../po/../src/verbs.cpp:2039 +msgid "_Unflow" +msgstr "Vorm _herstellen" + +#: ../../po/../src/verbs.cpp:2040 +msgid "Remove text from frame (creates a single-line text object)" +msgstr "" +"Tekst niet langer naar een object vormen (resulteert in een tekstobject met " +"één regel)" + +#: ../../po/../src/verbs.cpp:2041 +msgid "_Convert to Text" +msgstr "_Omzetten naar tekst" + +#: ../../po/../src/verbs.cpp:2042 +#, fuzzy +msgid "Convert flowed text to regular text objects (preserves appearance)" +msgstr "" +"De gevormde tekst converteren naar een normaal tekstobject met behoud van " +"uiterlijk" + +#: ../../po/../src/verbs.cpp:2044 +msgid "Flip _Horizontal" +msgstr "_Tuimelen" + +#: ../../po/../src/verbs.cpp:2044 +#, fuzzy +msgid "Flips selected objects horizontally" +msgstr "De geselecteerde knopen horizontaal uitlijnen" + +#: ../../po/../src/verbs.cpp:2047 +msgid "Flip _Vertical" +msgstr "_Spiegelen" + +#: ../../po/../src/verbs.cpp:2047 +#, fuzzy +msgid "Flips selected objects vertically" +msgstr "De geselecteerde knopen verticaal uitlijnen" + +#. Tools +#: ../../po/../src/verbs.cpp:2051 +msgid "Select" +msgstr "Selecteren" + +#: ../../po/../src/verbs.cpp:2052 +msgid "Select and transform objects" +msgstr "Selecteer en transformeer objecten" + +#: ../../po/../src/verbs.cpp:2053 +msgid "Node Edit" +msgstr "Knooppunten wijzigen" + +#: ../../po/../src/verbs.cpp:2054 +msgid "Edit path nodes or control handles" +msgstr "Knooppunten of handvatten wijzigen" + +#: ../../po/../src/verbs.cpp:2056 +msgid "Create rectangles and squares" +msgstr "Rechthoeken en vierkanten maken" + +#: ../../po/../src/verbs.cpp:2058 +msgid "Create circles, ellipses, and arcs" +msgstr "Cirkels, ellipsen en arcs maken" + +#: ../../po/../src/verbs.cpp:2060 +msgid "Create stars and polygons" +msgstr "Sterren en veelhoeken maken" + +#: ../../po/../src/verbs.cpp:2062 +msgid "Create spirals" +msgstr "Spiralen maken" + +#: ../../po/../src/verbs.cpp:2064 +msgid "Draw freehand lines" +msgstr "Lijnen uit de losse hand tekenen" + +#: ../../po/../src/verbs.cpp:2066 +msgid "Draw Bezier curves and straight lines" +msgstr "Bezier-rondingen en rechte lijnen tekenen" + +#: ../../po/../src/verbs.cpp:2068 +msgid "Draw calligraphic lines" +msgstr "Kalligrafisch lijnen tekenen" + +#: ../../po/../src/verbs.cpp:2070 +msgid "Create and edit text objects" +msgstr "Tekstobjecten maken en aanpassen" + +#: ../../po/../src/verbs.cpp:2072 +msgid "Create and edit gradients" +msgstr "Kleurverlopen maken en aanpassen" + +#: ../../po/../src/verbs.cpp:2074 +msgid "Zoom in or out" +msgstr "In- of uit zoomen" + +#: ../../po/../src/verbs.cpp:2076 +msgid "Pick averaged colors from image" +msgstr "Selecteer gemiddelde kleuren van de afbeelding" + +#: ../../po/../src/verbs.cpp:2078 +msgid "Create connectors" +msgstr "Maak een nieuwe verbinders" + +#. Tool prefs +#: ../../po/../src/verbs.cpp:2081 +msgid "Selector Preferences" +msgstr "Voorkeuren voor verbinders" + +#: ../../po/../src/verbs.cpp:2082 +#, fuzzy +msgid "Open Preferences for the Selector tool" +msgstr "De Inkscape voorkeuren voor verbinders openen" + +#: ../../po/../src/verbs.cpp:2083 +msgid "Node Tool Preferences" +msgstr "Voorkeuren voor knooppunten" + +#: ../../po/../src/verbs.cpp:2084 +#, fuzzy +msgid "Open Preferences for the Node tool" +msgstr "De Inkscape voorkeuren voor het knooppunten-gereedschap openen" + +#: ../../po/../src/verbs.cpp:2085 +msgid "Rectangle Preferences" +msgstr "Voorkeuren voor rechthoeken" + +#: ../../po/../src/verbs.cpp:2086 +#, fuzzy +msgid "Open Preferences for the Rectangle tool" +msgstr "De Inkscape voorkeuren voor het rechthoek-gereedschap openen" + +#: ../../po/../src/verbs.cpp:2087 +msgid "Ellipse Preferences" +msgstr "Voorkeuren voor ellipsen" + +#: ../../po/../src/verbs.cpp:2088 +#, fuzzy +msgid "Open Preferences for the Ellipse tool" +msgstr "De Inkscape voorkeuren voor het ellips-gereedschap openen" + +#: ../../po/../src/verbs.cpp:2089 +msgid "Star Preferences" +msgstr "Voorkeuren voor sterren" + +#: ../../po/../src/verbs.cpp:2090 +#, fuzzy +msgid "Open Preferences for the Star tool" +msgstr "De Inkscape voorkeuren voor het ster-gereedschap openen" + +#: ../../po/../src/verbs.cpp:2091 +msgid "Spiral Preferences" +msgstr "Voorkeuren voor spiralen" + +#: ../../po/../src/verbs.cpp:2092 +#, fuzzy +msgid "Open Preferences for the Spiral tool" +msgstr "De Inkscape voorkeuren voor het spiraal-gereedschap openen" + +#: ../../po/../src/verbs.cpp:2093 +msgid "Pencil Preferences" +msgstr "Penseel voorkeuren" + +#: ../../po/../src/verbs.cpp:2094 +#, fuzzy +msgid "Open Preferences for the Pencil tool" +msgstr "De Inkscape voorkeuren voor het penseel-gereedschap openen" + +#: ../../po/../src/verbs.cpp:2095 +msgid "Pen Preferences" +msgstr "Pen voorkeuren" + +#: ../../po/../src/verbs.cpp:2096 +#, fuzzy +msgid "Open Preferences for the Pen tool" +msgstr "De Inkscape voorkeuren voor het pen-gereedschap openen" + +#: ../../po/../src/verbs.cpp:2097 +msgid "Calligraphic Preferences" +msgstr "Kalligrafie voorkeuren" + +#: ../../po/../src/verbs.cpp:2098 +#, fuzzy +msgid "Open Preferences for the Calligraphy tool" +msgstr "De Inkscape voorkeuren voor het Kalligrafie gereedschap openen" + +#: ../../po/../src/verbs.cpp:2099 +msgid "Text Preferences" +msgstr "Tekst voorkeuren" + +#: ../../po/../src/verbs.cpp:2100 +#, fuzzy +msgid "Open Preferences for the Text tool" +msgstr "De Inkscape voorkeuren voor het tekst-gereedschap openen" + +#: ../../po/../src/verbs.cpp:2101 +msgid "Gradient Preferences" +msgstr "Kleurverloop voorkeuren" + +#: ../../po/../src/verbs.cpp:2102 +#, fuzzy +msgid "Open Preferences for the Gradient tool" +msgstr "De Inkscape voorkeuren voor het kleurverloop-gereedschap openen" + +#: ../../po/../src/verbs.cpp:2103 +msgid "Zoom Preferences" +msgstr "Zoom voorkeuren" + +#: ../../po/../src/verbs.cpp:2104 +#, fuzzy +msgid "Open Preferences for the Zoom tool" +msgstr "De Inkscape voorkeuren voor het zoom-gereedschap openen" + +#: ../../po/../src/verbs.cpp:2105 +msgid "Dropper Preferences" +msgstr "Pipet voorkeuren" + +#: ../../po/../src/verbs.cpp:2106 +#, fuzzy +msgid "Open Preferences for the Dropper tool" +msgstr "De Inkscape voorkeuren voor het pipet-gereedschap openen" + +#: ../../po/../src/verbs.cpp:2107 +msgid "Connector Preferences" +msgstr "Voorkeuren voor verbinders" + +#: ../../po/../src/verbs.cpp:2108 +#, fuzzy +msgid "Open Preferences for the Connector tool" +msgstr "De Inkscape voorkeuren voor verbinder-gereedschap openen" + +#. Zoom/View +#: ../../po/../src/verbs.cpp:2111 +msgid "Zoom In" +msgstr "Inzoomen" + +#: ../../po/../src/verbs.cpp:2111 +msgid "Zoom in" +msgstr "Inzoomen" + +#: ../../po/../src/verbs.cpp:2112 +msgid "Zoom Out" +msgstr "Uitzoomen" + +#: ../../po/../src/verbs.cpp:2112 +msgid "Zoom out" +msgstr "Uitzoomen" + +#: ../../po/../src/verbs.cpp:2113 +msgid "_Rulers" +msgstr "_Linialen" + +#: ../../po/../src/verbs.cpp:2113 +msgid "Show or hide the canvas rulers" +msgstr "Linialen van het canvas weergeven of verbergen" + +#: ../../po/../src/verbs.cpp:2114 +msgid "Scroll_bars" +msgstr "Schuif_balken" + +#: ../../po/../src/verbs.cpp:2114 +msgid "Show or hide the canvas scrollbars" +msgstr "Schuifbalken weergeven of verbergen" + +#: ../../po/../src/verbs.cpp:2115 +msgid "_Grid" +msgstr "_Raster" + +#: ../../po/../src/verbs.cpp:2116 +msgid "G_uides" +msgstr "_Hulplijnen" + +#: ../../po/../src/verbs.cpp:2117 +msgid "Nex_t Zoom" +msgstr "V_olgende zoom niveau" + +#: ../../po/../src/verbs.cpp:2117 +msgid "Next zoom (from the history of zooms)" +msgstr "Volgende zoom niveau (uit de zoom-geschiedenis)" + +#: ../../po/../src/verbs.cpp:2119 +msgid "Pre_vious Zoom" +msgstr "Vo_rige zoom niveau" + +#: ../../po/../src/verbs.cpp:2119 +msgid "Previous zoom (from the history of zooms)" +msgstr "Vorige zoom niveau (uit de zoom-geschiedenis)" + +#: ../../po/../src/verbs.cpp:2121 +msgid "Zoom 1:_1" +msgstr "Zoom 1:_1" + +#: ../../po/../src/verbs.cpp:2121 +msgid "Zoom to 1:1" +msgstr "Zoomfactor instellen op 1:1" + +#: ../../po/../src/verbs.cpp:2123 +msgid "Zoom 1:_2" +msgstr "Zoom 1:_2" + +#: ../../po/../src/verbs.cpp:2123 +msgid "Zoom to 1:2" +msgstr "Zoomfactor instellen op 1:2" + +#: ../../po/../src/verbs.cpp:2125 +msgid "_Zoom 2:1" +msgstr "_Zoom 2:1" + +#: ../../po/../src/verbs.cpp:2125 +msgid "Zoom to 2:1" +msgstr "Zoomfactor instellen op 2:1" + +#: ../../po/../src/verbs.cpp:2128 +msgid "_Fullscreen" +msgstr "_Volledig scherm" + +#: ../../po/../src/verbs.cpp:2128 +msgid "Stretch this document window to full screen" +msgstr "Dit documentvenster vergroten tot de volledige schermgrootte" + +#: ../../po/../src/verbs.cpp:2131 +msgid "Duplic_ate Window" +msgstr "Venster _dupliceren" + +#: ../../po/../src/verbs.cpp:2131 +msgid "Open a new window with the same document" +msgstr "Een nieuw venster met hetzelfde document openen" + +#: ../../po/../src/verbs.cpp:2133 +msgid "_New View Preview" +msgstr "_Nieuw voorbeeld weergeven" + +#: ../../po/../src/verbs.cpp:2134 +msgid "New View Preview" +msgstr "Nieuw voorbeeld weergeven" + +#. "view_new_preview" +#: ../../po/../src/verbs.cpp:2136 +#, fuzzy +msgid "_Normal" +msgstr "Normaal" + +#: ../../po/../src/verbs.cpp:2137 +msgid "Switch to normal display mode" +msgstr "" + +#: ../../po/../src/verbs.cpp:2138 +#, fuzzy +msgid "_Outline" +msgstr "Omhullende weergeven" + +#: ../../po/../src/verbs.cpp:2139 +msgid "Switch to outline (wireframe) display mode" +msgstr "" + +#: ../../po/../src/verbs.cpp:2141 +msgid "Ico_n Preview" +msgstr "_Pictogramvoorbeeld" + +#: ../../po/../src/verbs.cpp:2142 +msgid "Open a window to preview items at different icon resolutions" +msgstr "" +"Een venster openen om objecten te bekijken op verschillende pictogram " +"groottes." + +#: ../../po/../src/verbs.cpp:2144 +msgid "Zoom to fit page in window" +msgstr "De pagina in het scherm passen" + +#: ../../po/../src/verbs.cpp:2145 +msgid "Page _Width" +msgstr "Pagine _breedte" + +#: ../../po/../src/verbs.cpp:2146 +msgid "Zoom to fit page width in window" +msgstr "De paginabreedte in het scherm passen" + +#: ../../po/../src/verbs.cpp:2148 +msgid "Zoom to fit drawing in window" +msgstr "De hele tekening in het scherm passen" + +#: ../../po/../src/verbs.cpp:2150 +msgid "Zoom to fit selection in window" +msgstr "De hele selectie in het scherm passen" + +#. Dialogs +#: ../../po/../src/verbs.cpp:2153 +msgid "In_kscape Preferences..." +msgstr "In_kscape voorkeuren..." + +#: ../../po/../src/verbs.cpp:2154 +msgid "Global Inkscape preferences" +msgstr "Algemene Inkscape voorkeuren" + +#: ../../po/../src/verbs.cpp:2155 +msgid "_Document Preferences..." +msgstr "_Document voorkeuren..." + +#: ../../po/../src/verbs.cpp:2156 +msgid "Preferences saved with the document" +msgstr "Voorkeuren opgeslagen in dit document" + +#: ../../po/../src/verbs.cpp:2157 +msgid "_Fill and Stroke..." +msgstr "_Opvulling en lijnen..." + +#: ../../po/../src/verbs.cpp:2158 +msgid "Fill and Stroke dialog" +msgstr "Opvulling en lijnen dialoogvenster" + +#. TRANSLATORS: "Swatches" means: color samples +#: ../../po/../src/verbs.cpp:2160 +msgid "S_watches..." +msgstr "_Paletten..." + +#: ../../po/../src/verbs.cpp:2161 +msgid "View color swatches" +msgstr "Kleurenpaletten weergeven" + +#: ../../po/../src/verbs.cpp:2162 +msgid "Transfor_m..." +msgstr "Trans_formeren..." + +#: ../../po/../src/verbs.cpp:2163 +msgid "Transform dialog" +msgstr "Transformatie dialoogvenster" + +#: ../../po/../src/verbs.cpp:2164 +msgid "_Align and Distribute..." +msgstr "_Uitlijnen en verdelen..." + +#: ../../po/../src/verbs.cpp:2165 +msgid "Align and Distribute dialog" +msgstr "Uitlijnen en verdelen dialoogvenster" + +#: ../../po/../src/verbs.cpp:2166 +msgid "_Text and Font..." +msgstr "_Tekst en lettertype" + +#: ../../po/../src/verbs.cpp:2167 +msgid "Text and Font dialog" +msgstr "Tekst en lettertype dialoogvenster" + +#: ../../po/../src/verbs.cpp:2168 +msgid "_XML Editor..." +msgstr "_XML weergave..." + +#: ../../po/../src/verbs.cpp:2169 +msgid "XML Editor" +msgstr "XML weergave" + +#: ../../po/../src/verbs.cpp:2170 +msgid "_Find..." +msgstr "_Zoeken..." + +#: ../../po/../src/verbs.cpp:2171 +msgid "Find objects in document" +msgstr "Zoek objecten in het document" + +#: ../../po/../src/verbs.cpp:2172 +msgid "_Messages..." +msgstr "_Berichten..." + +#: ../../po/../src/verbs.cpp:2173 +msgid "View debug messages" +msgstr "" + +#: ../../po/../src/verbs.cpp:2174 +msgid "S_cripts..." +msgstr "S_cripts..." + +#: ../../po/../src/verbs.cpp:2175 +msgid "Run scripts" +msgstr "Scripts uitvoeren" + +#: ../../po/../src/verbs.cpp:2176 +msgid "Show/Hide D_ialogs" +msgstr "D_ialogen weergeven/verbergen" + +#: ../../po/../src/verbs.cpp:2177 +msgid "Show or hide all active dialogs" +msgstr "Alle actieve dialogen verbergen of weergeven" + +#. TRANSLATORS: "Tile clones" means: "Create tiled clones" +#: ../../po/../src/verbs.cpp:2179 +msgid "Tile clones..." +msgstr "Tegelen met klonen..." + +#: ../../po/../src/verbs.cpp:2180 +msgid "Create and arrange multiple clones of selection" +msgstr "Maak en plaats meerdere klonen van de selectie" + +#: ../../po/../src/verbs.cpp:2181 +msgid "_Object Properties..." +msgstr "Object _eigenschappen..." + +#: ../../po/../src/verbs.cpp:2182 +msgid "Object Properties dialog" +msgstr "Object-eigenschappen dialoogvenster" + +#: ../../po/../src/verbs.cpp:2185 +msgid "_Connect to Jabber server..." +msgstr "_Verbinden met Jabber server..." + +#: ../../po/../src/verbs.cpp:2185 +msgid "Connect to a Jabber server" +msgstr "Verbinden met een Jabber server" + +#: ../../po/../src/verbs.cpp:2187 +msgid "Share with _user..." +msgstr "Delen met gebruiker...." + +#: ../../po/../src/verbs.cpp:2187 +msgid "Establish a whiteboard session with another Jabber user" +msgstr "Een whiteboard sessie beginnen met een andere Jabber gebruiker" + +#: ../../po/../src/verbs.cpp:2189 +msgid "Share with _chatroom..." +msgstr "Delen met ruimte...." + +#: ../../po/../src/verbs.cpp:2189 +msgid "" +"Join a chatroom to start a new whiteboard session or join one in progress" +msgstr "" +"Je in een ruimte begeven om een whiteboard sessie te beginnen of om er aan " +"eentje mee te doen" + +#: ../../po/../src/verbs.cpp:2191 +msgid "_Dump XML node tracker" +msgstr "" + +#: ../../po/../src/verbs.cpp:2191 +msgid "Dump the contents of the XML tracker to the console" +msgstr "" + +#: ../../po/../src/verbs.cpp:2193 +msgid "_Open session file..." +msgstr "Sessie bestand _openen..." + +#: ../../po/../src/verbs.cpp:2193 +msgid "Open and browse through records of past whiteboard sessions" +msgstr "Door opnames van whiteboard sessies bladeren" + +#: ../../po/../src/verbs.cpp:2195 +msgid "Session file playback" +msgstr "Sessie bestand afspelen" + +#: ../../po/../src/verbs.cpp:2197 +msgid "_Disconnect from session" +msgstr "_Verbinding met sessie verbreken" + +#: ../../po/../src/verbs.cpp:2199 +msgid "Disconnect from _server" +msgstr "Verbinding met _server verbreken" + +#: ../../po/../src/verbs.cpp:2201 +msgid "_Input Devices..." +msgstr "_Invoer apparaten..." + +#: ../../po/../src/verbs.cpp:2202 +msgid "Configure extended input devices" +msgstr "Externe invoer-apparaten configureren" + +#. Help +#: ../../po/../src/verbs.cpp:2205 +msgid "_Keys and Mouse" +msgstr "_Toetsen en muis" + +#: ../../po/../src/verbs.cpp:2206 +msgid "Key and mouse shortcuts reference" +msgstr "Toetsenbord en muis handleiding" + +#: ../../po/../src/verbs.cpp:2207 +msgid "About E_xtensions" +msgstr "Over _uitbreidingen" + +#: ../../po/../src/verbs.cpp:2208 +msgid "About Extensions..." +msgstr "Over uitbreidingen..." + +#: ../../po/../src/verbs.cpp:2209 +msgid "About _Memory" +msgstr "Over _geheugengebruik" + +#: ../../po/../src/verbs.cpp:2210 +msgid "About Memory..." +msgstr "Over geheugengebruik..." + +#: ../../po/../src/verbs.cpp:2211 +msgid "_About Inkscape" +msgstr "_Over Inkscape" + +#. "help_about" +#. new HelpVerb(SP_VERB_SHOW_LICENSE, "ShowLicense", N_("Modifying or Redistributing Inkscape"), +#. N_("Show license to modify and/or redistribute Inkscape: GNU GPL"), NULL), +#. Tutorials +#: ../../po/../src/verbs.cpp:2217 +msgid "Inkscape: _Basic" +msgstr "Inkscape: _Basis" + +#: ../../po/../src/verbs.cpp:2218 +msgid "Getting started with Inkscape" +msgstr "Aan de slag met Inkscape" + +#. "tutorial_basic" +#: ../../po/../src/verbs.cpp:2219 +msgid "Inkscape: _Shapes" +msgstr "Inkscape: _Vormen" + +#: ../../po/../src/verbs.cpp:2220 +msgid "Using shape tools to create and edit shapes" +msgstr "Gebruik het vorm-gereedschap om vormen te maken en te wijzigen" + +#: ../../po/../src/verbs.cpp:2221 +msgid "Inkscape: _Advanced" +msgstr "Inkscape: Ge_avanceerd" + +#: ../../po/../src/verbs.cpp:2222 +msgid "Advanced Inkscape topics" +msgstr "Geavanceerde Inkscape onderwerpen" + +#. "tutorial_advanced" +#. TRANSLATORS: "to trace" means "to convert a bitmap to vector graphics" (to vectorize) +#: ../../po/../src/verbs.cpp:2224 +msgid "Inkscape: T_racing" +msgstr "Inkscape: _Overtrekken" + +#: ../../po/../src/verbs.cpp:2225 +msgid "Using bitmap tracing" +msgstr "Bitmaps 'overtrekken' om een lijntekening te krijgen" + +#. "tutorial_tracing" +#: ../../po/../src/verbs.cpp:2226 +msgid "Inkscape: _Calligraphy" +msgstr "Inkscape: _Kalligrafie" + +#: ../../po/../src/verbs.cpp:2227 +msgid "Using the Calligraphy pen tool" +msgstr "Gebruik van het kalligrafie gereedschap" + +#: ../../po/../src/verbs.cpp:2228 +msgid "_Elements of Design" +msgstr "_Ontwerp theorieën" + +#: ../../po/../src/verbs.cpp:2229 +msgid "Principles of design in the tutorial form" +msgstr "Een handleiding over de principes en theorieën van ontwerpen" + +#. "tutorial_design" +#: ../../po/../src/verbs.cpp:2230 +msgid "_Tips and Tricks" +msgstr "_Tips en ideeën" + +#: ../../po/../src/verbs.cpp:2231 +msgid "Miscellaneous tips and tricks" +msgstr "Verschillende tips en ideeën" + +#. "tutorial_tips" +#. Effect +#: ../../po/../src/verbs.cpp:2234 +msgid "Previous Effect" +msgstr "Vorig effect" + +#: ../../po/../src/verbs.cpp:2235 +msgid "Repeat the last effect with the same settings" +msgstr "Herhaal het laatste effect met dezelfde instellingen" + +#. "tutorial_tips" +#: ../../po/../src/verbs.cpp:2236 +msgid "Previous Effect Settings..." +msgstr "Instellingen van het vorig effect..." + +#: ../../po/../src/verbs.cpp:2237 +msgid "Repeat the last effect with new settings" +msgstr "Herhaal het laatste effect met de nieuwe instellingen" + +#: ../../po/../src/widgets/dash-selector.cpp:106 +msgid "Dash pattern" +msgstr "Streepjes patroon" + +#: ../../po/../src/widgets/dash-selector.cpp:121 +msgid "Pattern offset" +msgstr "Patroon inspring" + +#: ../../po/../src/widgets/desktop-widget.cpp:240 +msgid "Zoom drawing if window size changes" +msgstr "Tekening schalen wanneer de schermgrootte veranderd" + +#: ../../po/../src/widgets/desktop-widget.cpp:298 +msgid "Cursor coordinates" +msgstr "Cursor coördinaten" + +#. display the initial welcome message in the statusbar +#: ../../po/../src/widgets/desktop-widget.cpp:324 +msgid "" +"Welcome to Inkscape! Use shape or freehand tools to create objects; " +"use selector (arrow) to move or transform them." +msgstr "" +"Welkom bij Inkscape! Gebruik vorm- of potlood gereedschappen om " +"objecten te maken, gebruik de muiscursor om ze te verplaatsen of " +"transformeren." + +#: ../../po/../src/widgets/desktop-widget.cpp:372 +#, c-format +msgid "%s: %d - Inkscape" +msgstr "%s: %d - Inkscape" + +#: ../../po/../src/widgets/desktop-widget.cpp:374 +#, c-format +msgid "%s - Inkscape" +msgstr "%s - Inkscape" + +#: ../../po/../src/widgets/desktop-widget.cpp:532 +#, c-format +msgid "" +"Save changes to document \"%s\" before " +"closing?\n" +"\n" +"If you close without saving, your changes will be discarded." +msgstr "" +"Wijzigingen in het document \"%s\" " +"opslaan voor het afsluiten?\n" +"\n" +"Als u afsluit zonder op te slaan, zullen de wijzigingen verloren gaan." + +#: ../../po/../src/widgets/desktop-widget.cpp:548 +#: ../../po/../src/widgets/desktop-widget.cpp:612 +msgid "Close _without saving" +msgstr "Sluiten _zonder opslaan" + +#: ../../po/../src/widgets/desktop-widget.cpp:595 +#, c-format +msgid "" +"The file \"%s\" was saved with a " +"format (%s) that may cause data loss!\n" +"\n" +"Do you want to save this file in another format?" +msgstr "" +"Het bestand \"%s\" was opgeslagen in " +"een formaat (%s), wat data verlies tot gevolg kan hebben!\n" +"\n" +"Wilt u dit bestand opslaan in een ander formaat?" + +#. Family frame +#: ../../po/../src/widgets/font-selector.cpp:156 +msgid "Font family" +msgstr "Lettertype" + +#. Style frame +#: ../../po/../src/widgets/font-selector.cpp:184 +msgid "Style" +msgstr "Stijl" + +#: ../../po/../src/widgets/font-selector.cpp:219 +msgid "Font size:" +msgstr "Grootte:" + +#. TRANSLATORS: Test string used in text and font dialog (when no +#. * text has been entered) to get a preview of the font. Choose +#. * some representative characters that users of your locale will be +#. * interested in. +#: ../../po/../src/widgets/font-selector.cpp:554 +msgid "AaBbCcIiPpQq12368.;/()" +msgstr "AaBbCcIiPpQqWw12368.;/()" + +#: ../../po/../src/widgets/gradient-selector.cpp:137 +#: ../../po/../src/widgets/gradient-toolbar.cpp:524 +msgid "Duplicate" +msgstr "Dupliceren" + +#: ../../po/../src/widgets/gradient-selector.cpp:142 +#: ../../po/../src/widgets/gradient-toolbar.cpp:535 +msgid "Edit..." +msgstr "Bewerken..." + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/pservers.html#LinearGradientSpreadMethodAttribute +#: ../../po/../src/widgets/gradient-selector.cpp:159 +msgid "" +"Whether to fill with flat color beyond the ends of the gradient vector " +"(spreadMethod=\"pad\"), or repeat the gradient in the same direction " +"(spreadMethod=\"repeat\"), or repeat the gradient in alternating opposite " +"directions (spreadMethod=\"reflect\")" +msgstr "" +"Of het kleurverloop met een egale kleur moet worden aangevuld voorbij het " +"einde van de verloop-vector (spreadMethod=\"pad\"), of dat het verloop moet " +"worden herhaald (spreadMethod=\"repeat\"), of dat het verloop gespiegeld " +"moet worden herhaald (spreadMethod=\"reflect\")" + +#: ../../po/../src/widgets/gradient-selector.cpp:165 +msgid "none" +msgstr "Geen" + +#: ../../po/../src/widgets/gradient-selector.cpp:169 +msgid "reflected" +msgstr "Gespiegeld" + +#: ../../po/../src/widgets/gradient-selector.cpp:173 +msgid "direct" +msgstr "Normaal" + +#: ../../po/../src/widgets/gradient-selector.cpp:181 +msgid "Repeat:" +msgstr "Herhalen:" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:217 +msgid "No gradients" +msgstr "Geen kleurverlopen" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:226 +msgid "Nothing selected" +msgstr "Er is niet geselecteerd" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:237 +msgid "No gradients in selection" +msgstr "Geen kleurverloop geselecteerd" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:247 +msgid "Multiple gradients" +msgstr "Meerdere kleurverlopen" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:525 +msgid "" +"If the gradient is used by more than one object, create a copy of it for the " +"selected object(s)" +msgstr "" +"Als het kleurverloop door meer dan een object wordt gebruikt, maak er dan " +"een kopie van voor de geselecteerde objecten" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:536 +msgid "Edit the stops of the gradient" +msgstr "De overgangen in het kleurverloop aanpassen" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:593 +#: ../../po/../src/widgets/toolbox.cpp:1103 +#: ../../po/../src/widgets/toolbox.cpp:1192 +#: ../../po/../src/widgets/toolbox.cpp:1485 +#: ../../po/../src/widgets/toolbox.cpp:1534 +#: ../../po/../src/widgets/toolbox.cpp:1766 +#: ../../po/../src/widgets/toolbox.cpp:1801 +#: ../../po/../src/widgets/toolbox.cpp:2331 +#: ../../po/../src/widgets/toolbox.cpp:2370 +msgid "New:" +msgstr "Nieuw:" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:606 +msgid "Create linear gradient" +msgstr "Lineair kleurverloop maken" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:620 +msgid "Create radial (elliptic or circular) gradient" +msgstr "Cirkelvormig kleurverloop maken" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:635 +msgid "on" +msgstr "op" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:648 +msgid "Create gradient in the fill" +msgstr "Kleurverlopen maken voor vulling" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:662 +msgid "Create gradient in the stroke" +msgstr "Kleurverlopen maken voor lijnen" + +#. FIXME: implement averaging of all parameters for multiple selected stars +#. gtk_label_set_markup(GTK_LABEL(l), _("Average:")); +#. FIXME: implement averaging of all parameters for multiple selected +#. gtk_label_set_markup(GTK_LABEL(l), _("Average:")); +#: ../../po/../src/widgets/gradient-toolbar.cpp:676 +#: ../../po/../src/widgets/toolbox.cpp:1105 +#: ../../po/../src/widgets/toolbox.cpp:1124 +#: ../../po/../src/widgets/toolbox.cpp:1493 +#: ../../po/../src/widgets/toolbox.cpp:1518 +#: ../../po/../src/widgets/toolbox.cpp:1768 +#: ../../po/../src/widgets/toolbox.cpp:1787 +#: ../../po/../src/widgets/toolbox.cpp:2334 +#: ../../po/../src/widgets/toolbox.cpp:2354 +msgid "Change:" +msgstr "Wijzigen:" + +#: ../../po/../src/widgets/gradient-vector.cpp:269 +msgid "No gradients in document" +msgstr "Geen kleurverlopen in het document" + +#: ../../po/../src/widgets/gradient-vector.cpp:275 +msgid "No gradient selected" +msgstr "Geen kleurverloop geselecteerd" + +#: ../../po/../src/widgets/gradient-vector.cpp:532 +msgid "No stops in gradient" +msgstr "Geen overgangen in het kleurverloop" + +#. TRANSLATORS: "Stop" means: a "phase" of a gradient +#: ../../po/../src/widgets/gradient-vector.cpp:794 +msgid "Add stop" +msgstr "Overgang toevoegen" + +#: ../../po/../src/widgets/gradient-vector.cpp:797 +msgid "Add another control stop to gradient" +msgstr "Een nieuwe overgang toevoegen aan het kleurverloop" + +#: ../../po/../src/widgets/gradient-vector.cpp:799 +msgid "Delete stop" +msgstr "Overgang verwijderen" + +#: ../../po/../src/widgets/gradient-vector.cpp:802 +msgid "Delete current control stop from gradient" +msgstr "De huidige overgang verwijderen van het kleurverloop" + +#. Label +#: ../../po/../src/widgets/gradient-vector.cpp:813 +msgid "Offset:" +msgstr "Beginpunt:" + +#. TRANSLATORS: "Stop" means: a "phase" of a gradient +#: ../../po/../src/widgets/gradient-vector.cpp:858 +msgid "Stop Color" +msgstr "Overgangskleur" + +#: ../../po/../src/widgets/gradient-vector.cpp:887 +msgid "Gradient editor" +msgstr "Kleurverloop editor" + +#: ../../po/../src/widgets/layer-selector.cpp:119 +msgid "Toggle current layer visibility" +msgstr "Wissel (on)zichtbaarheid van de huidige laag " + +#: ../../po/../src/widgets/layer-selector.cpp:139 +msgid "Lock or unlock current layer" +msgstr "Huidige laag vergrendelen of ontgrendelen" + +#: ../../po/../src/widgets/layer-selector.cpp:142 +msgid "Current layer" +msgstr "Huidige laag" + +#: ../../po/../src/widgets/layer-selector.cpp:553 +msgid "(root)" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:182 +#: ../../po/../src/widgets/paint-selector.cpp:561 +msgid "No paint" +msgstr "Geen opvulling" + +#: ../../po/../src/widgets/paint-selector.cpp:184 +#: ../../po/../src/widgets/paint-selector.cpp:629 +msgid "Flat color" +msgstr "Egale kleur" + +#: ../../po/../src/widgets/paint-selector.cpp:186 +#: ../../po/../src/widgets/paint-selector.cpp:696 +msgid "Linear gradient" +msgstr "Lineair kleurverloop" + +#: ../../po/../src/widgets/paint-selector.cpp:188 +#: ../../po/../src/widgets/paint-selector.cpp:699 +msgid "Radial gradient" +msgstr "Cirkelvormig kleurverloop" + +#: ../../po/../src/widgets/paint-selector.cpp:192 +msgid "Unset paint (make it undefined so it can be inherited)" +msgstr "" +"Vulling verwijderen (maak het niet-gedefinieerd zodat het niet overgenomen " +"kan worden)" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/painting.html#FillRuleProperty +#: ../../po/../src/widgets/paint-selector.cpp:204 +msgid "" +"Any path self-intersections or subpaths create holes in the fill (fill-rule: " +"evenodd)" +msgstr "Wanneer een pad zichzelf snijdt, ontstaat een gat (vulregel: evenodd)" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/painting.html#FillRuleProperty +#: ../../po/../src/widgets/paint-selector.cpp:215 +msgid "" +"Fill is solid unless a subpath is counterdirectional (fill-rule: nonzero)" +msgstr "Vulling is zonder gaten (vulregel: nonzero)" + +#: ../../po/../src/widgets/paint-selector.cpp:528 +msgid "No objects" +msgstr "Geen objecten" + +#: ../../po/../src/widgets/paint-selector.cpp:539 +msgid "Multiple styles" +msgstr "Meerdere stijlen" + +#: ../../po/../src/widgets/paint-selector.cpp:550 +msgid "Paint is undefined" +msgstr "Vulling is niet gedefinieerd" + +#: ../../po/../src/widgets/paint-selector.cpp:757 +msgid "No patterns in document" +msgstr "Geen patronen in het document" + +#: ../../po/../src/widgets/paint-selector.cpp:872 +msgid "" +"Use Edit > Object(s) to Pattern to create a new pattern from " +"selection." +msgstr "" +"Gebruik Bewerken > Object(en) naar patroon om een nieuw patroon te " +"maken van de huidige selectie." + +#: ../../po/../src/widgets/select-toolbar.cpp:426 +msgid "Now stroke width is scaled when objects are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:428 +msgid "Now stroke width is not scaled when objects are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:436 +msgid "" +"Now rounded rectangle corners are scaled when rectangles are " +"scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:438 +msgid "" +"Now rounded rectangle corners are not scaled when rectangles " +"are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:446 +msgid "" +"Now gradients are transformed along with their objects when " +"those are transformed (moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:448 +msgid "" +"Now gradients remain fixed when objects are transformed " +"(moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:456 +msgid "" +"Now patterns are transformed along with their objects when " +"those are transformed (moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:458 +msgid "" +"Now patterns remain fixed when objects are transformed (moved, " +"scaled, rotated, or skewed)." +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:506 +msgid "select_toolbar|X" +msgstr "Selectie-gereedschap|X" + +#: ../../po/../src/widgets/select-toolbar.cpp:506 +msgid "Horizontal coordinate of selection" +msgstr "Horizontale coördinaat van de selectie" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:511 +msgid "select_toolbar|Y" +msgstr "Selectie-gereedschap|Y" + +#: ../../po/../src/widgets/select-toolbar.cpp:511 +msgid "Vertical coordinate of selection" +msgstr "Verticale coördinaat van de selectie" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:517 +msgid "select_toolbar|W" +msgstr "Selectie-gereedschap|B" + +#: ../../po/../src/widgets/select-toolbar.cpp:517 +msgid "Width of selection" +msgstr "Breedte van de selectie" + +#: ../../po/../src/widgets/select-toolbar.cpp:525 +msgid "Change both width and height by the same proportion" +msgstr "Wijzig de breedte en hoogte in dezelfde verhouding" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:534 +msgid "select_toolbar|H" +msgstr "Selectie-gereedschap|H" + +#: ../../po/../src/widgets/select-toolbar.cpp:534 +msgid "Height of selection" +msgstr "Hoogte van de selectie" + +#: ../../po/../src/widgets/sp-color-gtkselector.cpp:62 +msgid "System" +msgstr "Systeem" + +#: ../../po/../src/widgets/sp-color-notebook.cpp:322 +msgid "RGBA_:" +msgstr "RGBA_:" + +#: ../../po/../src/widgets/sp-color-notebook.cpp:330 +msgid "Hexadecimal RGBA value of the color" +msgstr "Hexadecimale RGBA waarde van de kleur" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "RGB" +msgstr "RGB" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "HSL" +msgstr "KVW" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "CMYK" +msgstr "CMYK" + +#: ../../po/../src/widgets/sp-color-scales.cpp:397 +msgid "_R" +msgstr "_R" + +#: ../../po/../src/widgets/sp-color-scales.cpp:398 +#: ../../po/../src/widgets/sp-color-scales.cpp:399 +msgid "Red" +msgstr "Rood" + +#: ../../po/../src/widgets/sp-color-scales.cpp:400 +msgid "_G" +msgstr "_G" + +#: ../../po/../src/widgets/sp-color-scales.cpp:401 +#: ../../po/../src/widgets/sp-color-scales.cpp:402 +msgid "Green" +msgstr "Groen" + +#: ../../po/../src/widgets/sp-color-scales.cpp:403 +msgid "_B" +msgstr "_B" + +#: ../../po/../src/widgets/sp-color-scales.cpp:404 +#: ../../po/../src/widgets/sp-color-scales.cpp:405 +msgid "Blue" +msgstr "Blauw" + +#. Label +#: ../../po/../src/widgets/sp-color-scales.cpp:406 +#: ../../po/../src/widgets/sp-color-scales.cpp:432 +#: ../../po/../src/widgets/sp-color-scales.cpp:463 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:141 +msgid "_A" +msgstr "_A" + +#: ../../po/../src/widgets/sp-color-scales.cpp:407 +#: ../../po/../src/widgets/sp-color-scales.cpp:408 +#: ../../po/../src/widgets/sp-color-scales.cpp:433 +#: ../../po/../src/widgets/sp-color-scales.cpp:434 +#: ../../po/../src/widgets/sp-color-scales.cpp:464 +#: ../../po/../src/widgets/sp-color-scales.cpp:465 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:151 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:163 +msgid "Alpha (opacity)" +msgstr "Alpha (ondoorzichtigheid)" + +#: ../../po/../src/widgets/sp-color-scales.cpp:423 +msgid "_H" +msgstr "_K" + +#: ../../po/../src/widgets/sp-color-scales.cpp:424 +#: ../../po/../src/widgets/sp-color-scales.cpp:425 +msgid "Hue" +msgstr "Kleurtoon" + +#: ../../po/../src/widgets/sp-color-scales.cpp:426 +msgid "_S" +msgstr "_V" + +#: ../../po/../src/widgets/sp-color-scales.cpp:427 +#: ../../po/../src/widgets/sp-color-scales.cpp:428 +msgid "Saturation" +msgstr "Verzadiging" + +#: ../../po/../src/widgets/sp-color-scales.cpp:429 +msgid "_L" +msgstr "_W" + +#: ../../po/../src/widgets/sp-color-scales.cpp:430 +#: ../../po/../src/widgets/sp-color-scales.cpp:431 +msgid "Lightness" +msgstr "Waarde" + +#: ../../po/../src/widgets/sp-color-scales.cpp:451 +msgid "_C" +msgstr "_C" + +#: ../../po/../src/widgets/sp-color-scales.cpp:452 +#: ../../po/../src/widgets/sp-color-scales.cpp:453 +msgid "Cyan" +msgstr "Cyaan" + +#: ../../po/../src/widgets/sp-color-scales.cpp:454 +msgid "_M" +msgstr "_M" + +#: ../../po/../src/widgets/sp-color-scales.cpp:455 +#: ../../po/../src/widgets/sp-color-scales.cpp:456 +msgid "Magenta" +msgstr "Magenta" + +#: ../../po/../src/widgets/sp-color-scales.cpp:457 +msgid "_Y" +msgstr "_Y" + +#: ../../po/../src/widgets/sp-color-scales.cpp:458 +#: ../../po/../src/widgets/sp-color-scales.cpp:459 +msgid "Yellow" +msgstr "Geel (Y)" + +#: ../../po/../src/widgets/sp-color-scales.cpp:460 +msgid "_K" +msgstr "_K" + +#: ../../po/../src/widgets/sp-color-selector.cpp:71 +msgid "Unnamed" +msgstr "Naamloos" + +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:68 +msgid "Wheel" +msgstr "Wiel" + +#: ../../po/../src/widgets/sp-xmlview-attr-list.cpp:53 +msgid "Attribute" +msgstr "Attribuut" + +#: ../../po/../src/widgets/sp-xmlview-attr-list.cpp:54 +msgid "Value" +msgstr "Waarde" + +#: ../../po/../src/widgets/toolbox.cpp:424 +msgid "Insert new nodes into selected segments" +msgstr "Nieuwe knooppunten invoegen in de geselecteerde segmenten" + +#: ../../po/../src/widgets/toolbox.cpp:426 +msgid "Delete selected nodes" +msgstr "De geselecteerde knooppunten verwijderen" + +#: ../../po/../src/widgets/toolbox.cpp:431 +msgid "Join paths at selected nodes" +msgstr "Paden op de geselecteerde knooppunten samenvoegen" + +#: ../../po/../src/widgets/toolbox.cpp:433 +msgid "Join paths at selected nodes with new segment" +msgstr "" +"Paden op de geselecteerde knooppunten samenvoegen met een nieuw segment" + +#: ../../po/../src/widgets/toolbox.cpp:436 +msgid "Split path between two non-endpoint nodes" +msgstr "Splijt het pad tussen twee knooppunten" + +#: ../../po/../src/widgets/toolbox.cpp:439 +msgid "Break path at selected nodes" +msgstr "Het pad op de geselecteerde knooppunten verbreken" + +#: ../../po/../src/widgets/toolbox.cpp:444 +msgid "Make selected nodes corner" +msgstr "De geselecteerde knooppunten hoekig maken" + +#: ../../po/../src/widgets/toolbox.cpp:447 +msgid "Make selected nodes smooth" +msgstr "De geselecteerde knopen glad maken" + +#: ../../po/../src/widgets/toolbox.cpp:450 +msgid "Make selected nodes symmetric" +msgstr "De geselecteerde knopen symmetrisch maken" + +#: ../../po/../src/widgets/toolbox.cpp:455 +msgid "Make selected segments lines" +msgstr "De geselecteerde segmenten omzetten naar rechte lijnen" + +#: ../../po/../src/widgets/toolbox.cpp:458 +msgid "Make selected segments curves" +msgstr "De geselecteerde segmenten omzetten naar rondingen" + +#: ../../po/../src/widgets/toolbox.cpp:1199 +msgid "Polygon" +msgstr "Veelhoek" + +#: ../../po/../src/widgets/toolbox.cpp:1206 +msgid "Regular polygon (with one handle) instead of a star" +msgstr "Gewone veelhoek (met één handvat) in plaats van een ster" + +#: ../../po/../src/widgets/toolbox.cpp:1218 +msgid "Corners:" +msgstr "Hoeken:" + +#: ../../po/../src/widgets/toolbox.cpp:1218 +msgid "Number of corners of a polygon or star" +msgstr "Aantal hoeken van een veelhoek of een ster" + +#: ../../po/../src/widgets/toolbox.cpp:1228 +msgid "Spoke ratio:" +msgstr "Spaak-verhouding:" + +#. TRANSLATORS: Tip radius of a star is the distance from the center to the farthest handle. +#. Base radius is the same for the closest handle. +#: ../../po/../src/widgets/toolbox.cpp:1231 +msgid "Base radius to tip radius ratio" +msgstr "Verhouding tussen de straal en de lengte van een spaak" + +#: ../../po/../src/widgets/toolbox.cpp:1246 +msgid "Rounded:" +msgstr "Afgerond:" + +#: ../../po/../src/widgets/toolbox.cpp:1246 +msgid "How much rounded are the corners (0 for sharp)" +msgstr "Hoeveel hoeken worden afgerond (0 voor scherpe hoeken)" + +#: ../../po/../src/widgets/toolbox.cpp:1256 +msgid "Randomized:" +msgstr "Willekeur:" + +#: ../../po/../src/widgets/toolbox.cpp:1256 +msgid "Scatter randomly the corners and angles" +msgstr "Verspreidt de punten en hoeken willkeurig" + +#: ../../po/../src/widgets/toolbox.cpp:1269 +#: ../../po/../src/widgets/toolbox.cpp:1838 +#: ../../po/../src/widgets/toolbox.cpp:2061 +msgid "Defaults" +msgstr "Standaardwaarden" + +#: ../../po/../src/widgets/toolbox.cpp:1270 +#: ../../po/../src/widgets/toolbox.cpp:1839 +#: ../../po/../src/widgets/toolbox.cpp:2062 +msgid "" +"Reset shape parameters to defaults (use Inkscape Preferences > Tools to " +"change defaults)" +msgstr "" +"Zet de instellingen van de vorm terug naar de standaard instellingen " +"(gebruik Bestand -> Inkscape voorkeuren -> Gereedschappen om de standaard " +"instellingen te wijzigen)" + +#: ../../po/../src/widgets/toolbox.cpp:1544 +msgid "W:" +msgstr "B:" + +#: ../../po/../src/widgets/toolbox.cpp:1544 +msgid "Width of rectangle" +msgstr "Breedte van de rechthoek" + +#: ../../po/../src/widgets/toolbox.cpp:1556 +msgid "Height of rectangle" +msgstr "Hoogte van de rechthoek" + +#: ../../po/../src/widgets/toolbox.cpp:1568 +msgid "Rx:" +msgstr "Rx:" + +#: ../../po/../src/widgets/toolbox.cpp:1568 +msgid "Horizontal radius of rounded corners" +msgstr "Horizontale straal van afgeronde hoeken" + +#: ../../po/../src/widgets/toolbox.cpp:1578 +msgid "Ry:" +msgstr "Ry:" + +#: ../../po/../src/widgets/toolbox.cpp:1578 +msgid "Vertical radius of rounded corners" +msgstr "Verticale straal van afgeronde hoeken" + +#: ../../po/../src/widgets/toolbox.cpp:1594 +msgid "Not rounded" +msgstr "Niet afgerond" + +#: ../../po/../src/widgets/toolbox.cpp:1596 +msgid "Make corners sharp" +msgstr "De hoeken weer scherp maken" + +#: ../../po/../src/widgets/toolbox.cpp:1805 +msgid "Turns:" +msgstr "Omwentelingen:" + +#: ../../po/../src/widgets/toolbox.cpp:1805 +msgid "Number of revolutions" +msgstr "Aantal omwentelingen" + +#: ../../po/../src/widgets/toolbox.cpp:1815 +msgid "Divergence:" +msgstr "Uitwaaieren:" + +#: ../../po/../src/widgets/toolbox.cpp:1815 +msgid "How much denser/sparser are outer revolutions; 1 = uniform" +msgstr "Hoeveel de buitenste omwentelingen uitwaaieren; 1=gelijkmatig" + +#: ../../po/../src/widgets/toolbox.cpp:1825 +msgid "Inner radius:" +msgstr "Binnen straal:" + +#: ../../po/../src/widgets/toolbox.cpp:1825 +msgid "Radius of the innermost revolution (relative to the spiral size)" +msgstr "" +"Straal van de binnenste omwenteling (relatief ten opzichte van de spiraal " +"grootte)" + +#: ../../po/../src/widgets/toolbox.cpp:1957 +msgid "The width of the calligraphic pen (relative to the visible canvas area)" +msgstr "" +"De breedte van de kalligrafische-pen (relatief ten opzichte van het canvas)" + +#: ../../po/../src/widgets/toolbox.cpp:1967 +msgid "Thinning:" +msgstr "Versmalling:" + +#: ../../po/../src/widgets/toolbox.cpp:1967 +msgid "" +"How much velocity thins the stroke (> 0 makes fast strokes thinner, < 0 " +"makes them broader, 0 makes width independent of velocity)" +msgstr "" +"De invloed van versnelling op de breedte van de lijn ( >0 maakte snelle " +"lijnen smaller, <0 maakt ze breeder, 0 maakt de breedte onafhankelijk van de " +"snelheid)" + +#: ../../po/../src/widgets/toolbox.cpp:1980 +msgid "Angle:" +msgstr "Hoek:" + +#: ../../po/../src/widgets/toolbox.cpp:1980 +msgid "" +"The angle of the pen's nib (in degrees; 0 = horizontal; has no effect if " +"fixation = 0)" +msgstr "" +"De hoek van de punt van de pen (in graden; 0 = horizontaal. Heeft geen " +"invloed als de oriëntatie 0 is)." + +#: ../../po/../src/widgets/toolbox.cpp:1990 +msgid "Fixation:" +msgstr "Oriëntatie:" + +#: ../../po/../src/widgets/toolbox.cpp:1990 +msgid "" +"How fixed is the pen angle (0 = always perpendicular to stroke direction, 1 " +"= fixed)" +msgstr "" +"Oriëntatie van de pen (in graden; 0 = altijd loodrecht op de teken-richting, " +"1 = vaste oriëntatie)" + +#: ../../po/../src/widgets/toolbox.cpp:2003 +msgid "Mass:" +msgstr "Massa:" + +#: ../../po/../src/widgets/toolbox.cpp:2003 +msgid "How much inertia affects the movement of the pen" +msgstr "De invloed van traagheid op de beweging van de pen" + +#. TRANSLATORS: "drag" means "resistance" here +#: ../../po/../src/widgets/toolbox.cpp:2014 +msgid "Drag:" +msgstr "Weerstand:" + +#: ../../po/../src/widgets/toolbox.cpp:2014 +msgid "How much resistance affects the movement of the pen" +msgstr "De invloed van weerstand op de beweging van de pen" + +#: ../../po/../src/widgets/toolbox.cpp:2034 +msgid "Use the pressure of the input device to alter the width of the pen" +msgstr "" +"Gebruik de druk die op het invoer apparaat wordt uitgeoefend om de pen-" +"breedte te variëren" + +#: ../../po/../src/widgets/toolbox.cpp:2047 +msgid "Use the tilt of the input device to alter the angle of the pen's nib" +msgstr "" +"Gebruik de hoek waaronder het invoer apparaat wordt gehouden om de pen-hoek " +"te variëren" + +#: ../../po/../src/widgets/toolbox.cpp:2374 +msgid "Start:" +msgstr "Start:" + +#: ../../po/../src/widgets/toolbox.cpp:2374 +msgid "The angle (in degrees) from the horizontal to the arc's start point" +msgstr "" +"De hoek (in graden) tussen een horizontale lijn en het begin van de taartpunt" + +#: ../../po/../src/widgets/toolbox.cpp:2384 +msgid "End:" +msgstr "Einde:" + +#: ../../po/../src/widgets/toolbox.cpp:2384 +msgid "The angle (in degrees) from the horizontal to the arc's end point" +msgstr "" +"De hoek (in graden) tussen een horizontale lijn en het einde van de taartpunt" + +#: ../../po/../src/widgets/toolbox.cpp:2395 +msgid "Open arc" +msgstr "Taartpunt openen" + +#: ../../po/../src/widgets/toolbox.cpp:2396 +msgid "" +"Switch between arc (unclosed shape) and segment (closed shape with two radii)" +msgstr "Wissel tussen arc (open vorm) en taartpunt (gesloten vorm)" + +#: ../../po/../src/widgets/toolbox.cpp:2415 +msgid "Make whole" +msgstr "Ellips herstellen" + +#: ../../po/../src/widgets/toolbox.cpp:2417 +msgid "Make the shape a whole ellipse, not arc or segment" +msgstr "Maak weer een ellips van de figuur, geen arc of taartpunt " + +#: ../../po/../src/widgets/toolbox.cpp:2644 +msgid "" +"When pressed, picks visible color without alpha and when not pressed, picks " +"color including its alpha" +msgstr "" +"Wanneer ingedrukt wordt de kleur zonder doorzichtigheid gekozen, wanneer " +"niet ingedrukt wordt de kleur met doorzichtigheid gekozen." + +#: ../../po/../src/widgets/toolbox.cpp:3039 +msgid "Make connectors avoid selected objects" +msgstr "Zorg dat verbinders de geselecteerde objecten ontwijken" + +#: ../../po/../src/widgets/toolbox.cpp:3043 +msgid "Make connectors ignore selected objects" +msgstr "Zorg dat verbinders de geselecteerde objecten negeren" + +#. +#. 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 : +#: ../share/extensions/addnodes.inx.h:1 +#, fuzzy +msgid "Add Nodes" +msgstr "Knooppunten" + +#: ../share/extensions/addnodes.inx.h:2 +msgid "Maximum Segment Length" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:1 +msgid "AI Input" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:2 ../share/extensions/ai_output.inx.h:2 +msgid "Adobe Illustrator (*.ai)" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:3 +msgid "Open files saved with Adobe Illustrator" +msgstr "" + +#: ../share/extensions/ai_output.inx.h:1 +#, fuzzy +msgid "AI Output" +msgstr "Uitvoer" + +#: ../share/extensions/ai_output.inx.h:3 +msgid "Write Adobe Illustrator" +msgstr "" + +#: ../share/extensions/dia.inx.h:1 +msgid "A diagram created with the program Dia" +msgstr "" + +#: ../share/extensions/dia.inx.h:2 +msgid "Dia Diagram (*.dia)" +msgstr "" + +#: ../share/extensions/dia.inx.h:3 +msgid "Dia Input" +msgstr "" + +#: ../share/extensions/dia.inx.h:4 +msgid "" +"In order to import Dia files, Dia itself must be installed. You can get Dia " +"at http://www.gnome.org/projects/dia/" +msgstr "" + +#: ../share/extensions/dia.inx.h:5 +msgid "" +"The dia2svg.sh script should be installed with your Inkscape distribution. " +"If you do not have it, there is likely to be something wrong with your " +"Inkscape installation." +msgstr "" + +#: ../share/extensions/dots.inx.h:1 +#, fuzzy +msgid "Connect the Dots" +msgstr "Verbinder" + +#: ../share/extensions/dots.inx.h:2 +#, fuzzy +msgid "Dot Size" +msgstr "Afmeting" + +#: ../share/extensions/dots.inx.h:3 +#, fuzzy +msgid "Font Size" +msgstr "Grootte:" + +#: ../share/extensions/dropshadow.inx.h:1 +msgid "Color of shadow" +msgstr "" + +#: ../share/extensions/dropshadow.inx.h:2 +#, fuzzy +msgid "Dropshadow" +msgstr "Pagina schaduw weergeven" + +#: ../share/extensions/dxf_input.inx.h:1 +#: ../share/extensions/dxf_output.inx.h:1 +msgid "AutoCAD DXF (*.dxf)" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:2 +msgid "DXF Input" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:3 +msgid "Import AutoCAD's Document Exchange Format" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:4 +msgid "" +"dxf2svg may come with Inkscape, but is also at http://dxf-svg-convert." +"sourceforge.net/" +msgstr "" + +#: ../share/extensions/dxf_output.inx.h:2 +#, fuzzy +msgid "DXF Output" +msgstr "Uitvoer" + +#: ../share/extensions/dxf_output.inx.h:3 +msgid "DXF file written by pstoedit" +msgstr "" + +#: ../share/extensions/dxf_output.inx.h:4 +msgid "pstoedit must be installed to run see http://www.pstoedit.net/pstoedit" +msgstr "" + +#: ../share/extensions/embedimage.inx.h:1 +#, fuzzy +msgid "Embed Images" +msgstr "Afbeeldingen" + +#: ../share/extensions/eps_input.inx.h:1 +msgid "EPS Input" +msgstr "" + +#: ../share/extensions/eps_input.inx.h:2 +msgid "Encapsulated Postscript" +msgstr "" + +#: ../share/extensions/eps_input.inx.h:3 +msgid "Encapsulated Postscript (*.eps)" +msgstr "" + +#: ../share/extensions/epsi_output.inx.h:1 +#, fuzzy +msgid "EPSI Output" +msgstr "Uitvoer" + +#: ../share/extensions/epsi_output.inx.h:2 +msgid "Encapsulated Postscript Interchange (*.epsi)" +msgstr "" + +#: ../share/extensions/epsi_output.inx.h:3 +msgid "Encapsulated Postscript with a thumbnail" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:1 ../share/extensions/ffms.inx.h:1 +#: ../share/extensions/ffset.inx.h:1 ../share/extensions/ffss.inx.h:1 +#, fuzzy +msgid "Bridge Width" +msgstr "Lijnbreedte" + +#: ../share/extensions/ffmet.inx.h:2 ../share/extensions/ffms.inx.h:2 +msgid "First String Length" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:3 +msgid "FretFind Multi Length ET" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:4 ../share/extensions/ffms.inx.h:4 +#: ../share/extensions/ffset.inx.h:3 ../share/extensions/ffss.inx.h:3 +msgid "Fretboard Edges" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:5 ../share/extensions/ffms.inx.h:5 +msgid "Last String Length" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:6 ../share/extensions/ffms.inx.h:6 +#: ../share/extensions/ffset.inx.h:4 ../share/extensions/ffss.inx.h:4 +#, fuzzy +msgid "Number of Frets" +msgstr "Aantal rijen" + +#: ../share/extensions/ffmet.inx.h:7 ../share/extensions/ffms.inx.h:7 +#: ../share/extensions/ffset.inx.h:5 ../share/extensions/ffss.inx.h:5 +#, fuzzy +msgid "Number of Strings" +msgstr "Aantal rijen" + +#: ../share/extensions/ffmet.inx.h:8 ../share/extensions/ffms.inx.h:8 +#: ../share/extensions/ffset.inx.h:6 ../share/extensions/ffss.inx.h:6 +#, fuzzy +msgid "Nut Width" +msgstr "Breedte" + +#: ../share/extensions/ffmet.inx.h:9 ../share/extensions/ffms.inx.h:10 +msgid "Perpendicular Distance" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:10 ../share/extensions/ffset.inx.h:7 +msgid "Scale Base (2 for Octave)" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:11 ../share/extensions/ffset.inx.h:9 +msgid "Tones in Scale" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:12 ../share/extensions/ffms.inx.h:12 +#: ../share/extensions/ffset.inx.h:10 ../share/extensions/ffss.inx.h:10 +msgid "px per Unit" +msgstr "" + +#: ../share/extensions/ffms.inx.h:3 +msgid "FretFind Multi Length Scala" +msgstr "" + +#: ../share/extensions/ffms.inx.h:9 ../share/extensions/ffss.inx.h:7 +msgid "Path to Scala *.scl File" +msgstr "" + +#: ../share/extensions/ffms.inx.h:11 +msgid "Tuning (scale step for each string seperated by semicolons)" +msgstr "" + +#: ../share/extensions/ffset.inx.h:2 +msgid "FretFind Single Length ET" +msgstr "" + +#: ../share/extensions/ffset.inx.h:8 ../share/extensions/ffss.inx.h:8 +msgid "Scale Length" +msgstr "" + +#: ../share/extensions/ffss.inx.h:2 +msgid "FretFind Single Length Scala" +msgstr "" + +#: ../share/extensions/ffss.inx.h:9 +msgid "Tuning (Scale step for each string seperated by semicolons)" +msgstr "" + +#: ../share/extensions/handles.inx.h:1 +#, fuzzy +msgid "Draw Handles" +msgstr "Lijnen uit de losse hand tekenen" + +#: ../share/extensions/interp.inx.h:1 +#, fuzzy +msgid "Duplicate Endpaths" +msgstr "Item dupliceren" + +#: ../share/extensions/interp.inx.h:2 +#, fuzzy +msgid "Exponent" +msgstr "Exporteren" + +#: ../share/extensions/interp.inx.h:3 +msgid "Interpolate" +msgstr "" + +#: ../share/extensions/interp.inx.h:4 +msgid "Interpolate Style (Experimental)" +msgstr "" + +#: ../share/extensions/interp.inx.h:5 +msgid "Interpolation Method" +msgstr "" + +#: ../share/extensions/interp.inx.h:6 +msgid "Interpolation Steps" +msgstr "" + +#: ../share/extensions/kochify.inx.h:1 +msgid "Kochify" +msgstr "" + +#: ../share/extensions/kochify_load.inx.h:1 +msgid "Kochify (Load)" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:1 +#, fuzzy +msgid "Angle" +msgstr "Hoek:" + +#: ../share/extensions/lindenmayer.inx.h:2 +msgid "Axiom" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:3 +#, fuzzy +msgid "Lindenmayer" +msgstr "Laag hernoemen" + +#: ../share/extensions/lindenmayer.inx.h:4 +msgid "Order" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:5 +#, fuzzy +msgid "Rules" +msgstr "_Linialen" + +#: ../share/extensions/lindenmayer.inx.h:6 +#, fuzzy +msgid "Step" +msgstr "Stappen" + +#: ../share/extensions/motion.inx.h:1 +#, fuzzy +msgid "Direction" +msgstr "Beschrijving" + +#: ../share/extensions/motion.inx.h:2 +#, fuzzy +msgid "Magnitude" +msgstr "Magenta" + +#: ../share/extensions/motion.inx.h:3 +#, fuzzy +msgid "Motion" +msgstr "_Draaiing" + +#: ../share/extensions/pdf_output.inx.h:1 +msgid "Adobe PDF (*.pdf)" +msgstr "" + +#: ../share/extensions/pdf_output.inx.h:2 +msgid "Adobe Portable Document Format" +msgstr "" + +#: ../share/extensions/pdf_output.inx.h:3 +#, fuzzy +msgid "PDF Output" +msgstr "Uitvoer" + +#: ../share/extensions/ps_input.inx.h:1 +#, fuzzy +msgid "Postscript" +msgstr "Portret" + +#: ../share/extensions/ps_input.inx.h:2 +msgid "Postscript (*.ps)" +msgstr "" + +#: ../share/extensions/ps_input.inx.h:3 +msgid "Postscript Input" +msgstr "" + +#: ../share/extensions/radiusrand.inx.h:1 +#, fuzzy +msgid "Radius" +msgstr "Om_hoog" + +#: ../share/extensions/radiusrand.inx.h:2 +#, fuzzy +msgid "Radius Randomize" +msgstr "Willekeur:" + +#: ../share/extensions/radiusrand.inx.h:3 +msgid "Randomize Control Points" +msgstr "" + +#: ../share/extensions/radiusrand.inx.h:4 +#, fuzzy +msgid "Randomize Nodes" +msgstr "Willekeur:" + +#: ../share/extensions/rtree.inx.h:1 +#, fuzzy +msgid "Initial Size" +msgstr "Bitmap afmeting" + +#: ../share/extensions/rtree.inx.h:2 +msgid "Minimum Size" +msgstr "" + +#: ../share/extensions/rtree.inx.h:3 +#, fuzzy +msgid "Random Tree" +msgstr "Willekeur:" + +#: ../share/extensions/sk_input.inx.h:1 +msgid "A diagram created with the program Sketch" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:2 +msgid "Sketch Diagram (*.sk)" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:3 +msgid "Sketch Input" +msgstr "" + +#: ../share/extensions/straightseg.inx.h:1 +msgid "Behavior" +msgstr "" + +#: ../share/extensions/straightseg.inx.h:3 +msgid "Segment Straightener" +msgstr "" + +#: ../share/extensions/summersnight.inx.h:1 +msgid "Summer's Night" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:1 +#: ../share/extensions/svgz_output.inx.h:1 +msgid "Compressed Inkscape SVG (*.svgz)" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:2 +#: ../share/extensions/svgz_output.inx.h:2 +msgid "Inkscape's native file format compressed with GZip" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:3 +msgid "SVGZ Input" +msgstr "" + +#: ../share/extensions/svgz_output.inx.h:3 +#, fuzzy +msgid "SVGZ Output" +msgstr "Uitvoer" + +#: ../share/extensions/txt2svg.inx.h:1 +msgid "ASCII Text" +msgstr "" + +#: ../share/extensions/txt2svg.inx.h:2 +msgid "Text File (*.txt)" +msgstr "" + +#: ../share/extensions/txt2svg.inx.h:3 +msgid "Text Input" +msgstr "" + +#: ../share/extensions/wavy.inx.h:1 +msgid "Calculate first derivative numerically" +msgstr "" + +#: ../share/extensions/wavy.inx.h:2 +msgid "First derivative" +msgstr "" + +#: ../share/extensions/wavy.inx.h:3 +msgid "Function" +msgstr "" + +#: ../share/extensions/wavy.inx.h:4 +msgid "Function Plotter" +msgstr "" + +#: ../share/extensions/wavy.inx.h:5 +msgid "Nodes per period" +msgstr "" + +#: ../share/extensions/wavy.inx.h:6 +msgid "Periods (2*Pi each)" +msgstr "" + +#: ../share/extensions/whirl.inx.h:1 +msgid "Amount of Whirl" +msgstr "" + +#: ../share/extensions/whirl.inx.h:2 +#, fuzzy +msgid "Center X" +msgstr "Regels centreren" + +#: ../share/extensions/whirl.inx.h:3 +#, fuzzy +msgid "Center Y" +msgstr "Regels centreren" + +#: ../share/extensions/whirl.inx.h:4 +#, fuzzy +msgid "Direction of Rotation" +msgstr "Uitnodiging afslaan" + +#: ../share/extensions/whirl.inx.h:5 +msgid "Whirl" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:1 +msgid "A popular graphics file format for clipart" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:2 +msgid "Windows Metafile (*.wmf)" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:3 +msgid "Windows Metafile Input" +msgstr "" + +#~ msgid "Custom canvas" +#~ msgstr "Eigen canvasformaat" + +#~ msgid "Current style" +#~ msgstr "Huidige stijl" + +#~ msgid "" +#~ "Current style is updated every time you change the style of any object " +#~ "(its fill, stroke, transparency, etc.)" +#~ msgstr "" +#~ "De huidige stijl bijwerken bij iedere aanpassing van de stijl van een " +#~ "object, zoals opvulling, lijnen en doorzichtigheid" + +#~ msgid "Arrange Objects" +#~ msgstr "Objecten verdelen" + +#~ msgid "deg" +#~ msgstr "grd" + +#~ msgid "" +#~ "%s is not a valid preferences file.\n" +#~ "%s" +#~ msgstr "" +#~ "%s is geen geldig voorkeuren bestand.\n" +#~ "%s" + +#~ msgid "" +#~ "Inkscape will run with default settings.\n" +#~ "New settings will not be saved." +#~ msgstr "" +#~ "Inkscape zal starten met de standaard instellingen.\n" +#~ "Nieuwe instellingen worden niet opgeslagen." + +#~ msgid "_Credits" +#~ msgstr "_Met dank aan" + +#, fuzzy +#~ msgid "Grab sensitivity" +#~ msgstr "Maak gevoellig" + +#~ msgid "Click/drag threshold" +#~ msgstr "Klikken/slepen grenswaarde" + +#~ msgid "Mouse wheel scrolls by" +#~ msgstr "Muiswiel schuift met" + +#~ msgid "Scroll by" +#~ msgstr "Schuiven met" + +#~ msgid "Acceleration" +#~ msgstr "Versnelling" + +#~ msgid "Speed" +#~ msgstr "Snelheid" + +#~ msgid "Threshold" +#~ msgstr "Drempelwaarde" + +#~ msgid "Arrow keys move by" +#~ msgstr "Cursor-toetsen verplaatsen met" + +#~ msgid "> and < scale by" +#~ msgstr "> en < schalen met" + +#~ msgid "Inset/Outset by" +#~ msgstr "Binnen-/buitenrand met" + +#~ msgid "Rotation snaps every" +#~ msgstr "Draaien in stappen van" + +#~ msgid "Zoom in/out by" +#~ msgstr "In- of uitzoomen met" + +#~ msgid "Transform" +#~ msgstr "Transformatie" + +#~ msgid "" +#~ "0 out of %i node selected. Click, Shift+click, or drag around nodes to select.0 out of %i nodes " +#~ "selected. Click, Shift+click, or drag around nodes " +#~ "to select." +#~ msgstr "" +#~ "0 van %i knooppunt geselecteerd. Klik, shift-" +#~ "klik of sleep om knooppunten te selecteren.0 van %i knooppunten geselecteerd. Klik, shift-klik of sleep om knooppunten te selecteren." + +#~ msgid "Flip selection horizontally" +#~ msgstr "De selectie horizontaal tuimelen" + +#~ msgid "Flip selection vertically" +#~ msgstr "De selectie verticaal spiegelen" diff --git a/po/nn.po b/po/nn.po new file mode 100644 index 000000000..763dc0fd7 --- /dev/null +++ b/po/nn.po @@ -0,0 +1,9552 @@ +# Translation of nn to Norwegian Nynorsk +# Norwegian Nynorsk translation of Inkscape. +# Omsetjing av Inkscape til nynorsk. +# Copyright © 2004 Karl Ove Hufthammer. +# +# Merk: Alle statuslinjemeldingar skal slutta pÃ¥ «.» pÃ¥ nynorsk, +# sjølv om dei ikkje gjer det pÃ¥ engelsk. Koordinatar skal ha +# mellomrom mellom seg (eks. (34, 78)), og «×» er gongeteikn. +# Karl Ove Hufthammer , 2004, 2005. +# +msgid "" +msgstr "" +"Project-Id-Version: nn\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2005-12-04 11:51-0800\n" +"PO-Revision-Date: 2005-07-14 20:29+0200\n" +"Last-Translator: Karl Ove Hufthammer \n" +"Language-Team: Norwegian Nynorsk \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 1.10.1\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: ../inkscape.desktop.in.h:1 +msgid "Create and edit Scalable Vector Graphics images" +msgstr "Lag og rediger skalerbare vektorbilete (SVG)" + +#: ../inkscape.desktop.in.h:2 +msgid "Inkscape SVG Vector Illustrator" +msgstr "Inkscape SVG-vektorteikneprogram" + +#: ../../po/../src/arc-context.cpp:350 +msgid "" +"Ctrl: make circle or integer-ratio ellipse, snap arc/segment angle" +msgstr "Ctrl: Lag sirkel eller heiltalsellipse. Endra vinkel i steg." + +#: ../../po/../src/arc-context.cpp:351 ../../po/../src/rect-context.cpp:388 +msgid "Shift: draw around the starting point" +msgstr "Shift: Teikn rundt startpunktet." + +#: ../../po/../src/arc-context.cpp:413 +#: ../../po/../src/connector-context.cpp:493 +#: ../../po/../src/dyna-draw-context.cpp:506 +#: ../../po/../src/pen-context.cpp:329 ../../po/../src/pencil-context.cpp:208 +#: ../../po/../src/rect-context.cpp:452 ../../po/../src/spiral-context.cpp:421 +#: ../../po/../src/star-context.cpp:427 +msgid "Current layer is hidden. Unhide it to be able to draw on it." +msgstr "Laget er skjult. Du mÃ¥ visa det før du kan teikna pÃ¥ det." + +#: ../../po/../src/arc-context.cpp:417 +#: ../../po/../src/connector-context.cpp:497 +#: ../../po/../src/dyna-draw-context.cpp:510 +#: ../../po/../src/pen-context.cpp:336 ../../po/../src/pencil-context.cpp:212 +#: ../../po/../src/rect-context.cpp:456 ../../po/../src/spiral-context.cpp:426 +#: ../../po/../src/star-context.cpp:431 +msgid "Current layer is locked. Unlock it to be able to draw on it." +msgstr "Laget er lÃ¥st. Du mÃ¥ lÃ¥sa det opp før du kan teikna pÃ¥ det." + +#: ../../po/../src/arc-context.cpp:496 +#, c-format +msgid "" +"Ellipse: %s × %s; with Ctrl to make circle or integer-" +"ratio ellipse; with Shift to draw around the starting point" +msgstr "" +"Ellipse: %s × %s, med Ctrl for Ã¥ laga sirkel eller " +"heiltalsellipse, og med Shift for Ã¥ teikna rundt startpunktet." + +#: ../../po/../src/connector-context.cpp:518 +#, fuzzy +msgid "Creating new connector" +msgstr "Lagar ny bane" + +#: ../../po/../src/connector-context.cpp:939 +#, fuzzy +msgid "Finishing connector" +msgstr "Fullfører penn" + +#: ../../po/../src/connector-context.cpp:1108 +msgid "Connection point: click or drag to create a new connector" +msgstr "" + +#: ../../po/../src/connector-context.cpp:1185 +msgid "Connector endpoint: drag to reroute or connect to new shapes" +msgstr "" + +#: ../../po/../src/connector-context.cpp:1278 +#, fuzzy +msgid "Select at least one non-connector object." +msgstr "Merk minst to objekt du vil gruppera." + +#: ../../po/../src/desktop-events.cpp:238 +#, c-format +msgid "%s at %s" +msgstr "%s pÃ¥ %s" + +#. TRANSLATORS: This string appears when double-clicking on a guide. +#. This is the distance by which the guide is to be moved. +#: ../../po/../src/desktop-events.cpp:277 +msgid " relative by " +msgstr " relativt til " + +#. TRANSLATORS: This string appears when double-clicking on a guide. +#. This is the target location where the guide is to be moved. +#: ../../po/../src/desktop-events.cpp:282 +#: ../../po/../src/desktop-events.cpp:395 +msgid " absolute to " +msgstr " absolutt til " + +#. create dialog +#: ../../po/../src/desktop-events.cpp:348 +msgid "Guideline" +msgstr "Hjelpelinje" + +#: ../../po/../src/desktop-events.cpp:432 +#, c-format +msgid "Move %s" +msgstr "Flytt %s" + +#: ../../po/../src/desktop.cpp:678 +msgid "No previous zoom." +msgstr "Inga førre forstørring." + +#: ../../po/../src/desktop.cpp:703 +msgid "No next zoom." +msgstr "Inga neste forstørring." + +#: ../../po/../src/dialogs/clonetiler.cpp:182 +msgid "Nothing selected." +msgstr "Ingenting merkt." + +#: ../../po/../src/dialogs/clonetiler.cpp:188 +msgid "More than one object selected." +msgstr "Meir enn eitt objekt merkt." + +#: ../../po/../src/dialogs/clonetiler.cpp:195 +#, c-format +msgid "Object has %d tiled clones." +msgstr "Objektet har %d flislagte klonar." + +#: ../../po/../src/dialogs/clonetiler.cpp:200 +msgid "Object has no tiled clones." +msgstr "Objektet har ingen flislagte klonar." + +#: ../../po/../src/dialogs/clonetiler.cpp:865 +msgid "Select one object whose tiled clones to unclump." +msgstr "Merk objektet du vil fjerna klumping i flislagte klonar til." + +#: ../../po/../src/dialogs/clonetiler.cpp:916 +msgid "Select one object whose tiled clones to remove." +msgstr "Merk objektet du vil fjerna klonane til." + +#: ../../po/../src/dialogs/clonetiler.cpp:984 +#: ../../po/../src/selection-chemistry.cpp:1774 +msgid "Select an object to clone." +msgstr "Merk objektet du vil klona." + +#: ../../po/../src/dialogs/clonetiler.cpp:990 +#: ../../po/../src/selection-chemistry.cpp:1780 +msgid "" +"If you want to clone several objects, group them and clone the " +"group." +msgstr "" +"Vil du klona fleire objekt, kan du gruppera dei og sÃ¥ klona " +"gruppa." + +#: ../../po/../src/dialogs/clonetiler.cpp:1484 +msgid "Per row:" +msgstr "Per rad:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1497 +msgid "Per column:" +msgstr "Per kolonne:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1505 +msgid "Randomize:" +msgstr "Slumpverdi:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1656 +msgid "_Symmetry" +msgstr "_Symmetri" + +#. TRANSLATORS: For the following 17 symmetry groups, see +#. * http://www.bib.ulb.ac.be/coursmath/doc/17.htm (visual examples); +#. * http://www.clarku.edu/~djoyce/wallpaper/seventeen.html (English vocabulary); or +#. * http://membres.lycos.fr/villemingerard/Geometri/Sym1D.htm (French vocabulary). +#. +#: ../../po/../src/dialogs/clonetiler.cpp:1664 +msgid "Select one of the 17 symmetry groups for the tiling" +msgstr "Vel éi av 17 symmetrigrupper for flisleggjinga." + +#. TRANSLATORS: "translation" means "shift" / "displacement" here. +#: ../../po/../src/dialogs/clonetiler.cpp:1675 +msgid "P1: simple translation" +msgstr "P1: enkel omforming" + +#: ../../po/../src/dialogs/clonetiler.cpp:1676 +msgid "P2: 180° rotation" +msgstr "P2: 180° rotering" + +#: ../../po/../src/dialogs/clonetiler.cpp:1677 +msgid "PM: reflection" +msgstr "PM: refleksjon" + +#. TRANSLATORS: "glide reflection" is a reflection and a translation combined. +#. For more info, see http://mathforum.org/sum95/suzanne/symsusan.html +#: ../../po/../src/dialogs/clonetiler.cpp:1680 +msgid "PG: glide reflection" +msgstr "PG: gliderefleksjon" + +#: ../../po/../src/dialogs/clonetiler.cpp:1681 +msgid "CM: reflection + glide reflection" +msgstr "CM: refleksjon + gliderefleksjon" + +#: ../../po/../src/dialogs/clonetiler.cpp:1682 +msgid "PMM: reflection + reflection" +msgstr "PMM: refleksjon + refleksjon" + +#: ../../po/../src/dialogs/clonetiler.cpp:1683 +msgid "PMG: reflection + 180° rotation" +msgstr "PMG: refleksjon + 180° rotering" + +#: ../../po/../src/dialogs/clonetiler.cpp:1684 +msgid "PGG: glide reflection + 180° rotation" +msgstr "PGG: gliderefleksjon + 180° rotering" + +#: ../../po/../src/dialogs/clonetiler.cpp:1685 +msgid "CMM: reflection + reflection + 180° rotation" +msgstr "CMM: refleksjon + refleksjon + 180° rotering" + +#: ../../po/../src/dialogs/clonetiler.cpp:1686 +msgid "P4: 90° rotation" +msgstr "P4: 90° rotering" + +#: ../../po/../src/dialogs/clonetiler.cpp:1687 +msgid "P4M: 90° rotation + 45° reflection" +msgstr "P4M: 90° rotering + 45° refleksjon" + +#: ../../po/../src/dialogs/clonetiler.cpp:1688 +msgid "P4G: 90° rotation + 90° reflection" +msgstr "P4G: 90° rotering + 90° refleksjon" + +#: ../../po/../src/dialogs/clonetiler.cpp:1689 +msgid "P3: 120° rotation" +msgstr "P3: 120° rotering" + +#: ../../po/../src/dialogs/clonetiler.cpp:1690 +msgid "P31M: reflection + 120° rotation, dense" +msgstr "P31M: reflektering + 120° rotering (tett)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1691 +msgid "P3M1: reflection + 120° rotation, sparse" +msgstr "P31M: reflektering + 120° rotering (spreidd)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1692 +msgid "P6: 60° rotation" +msgstr "P6: 60° rotering" + +#: ../../po/../src/dialogs/clonetiler.cpp:1693 +msgid "P6M: reflection + 60° rotation" +msgstr "P6M: refleksjon + 60° rotering" + +#: ../../po/../src/dialogs/clonetiler.cpp:1721 +msgid "S_hift" +msgstr "S_hift" + +#. TRANSLATORS: "shift" means: the tiles will be shifted (offset) horizontally by this amount +#: ../../po/../src/dialogs/clonetiler.cpp:1731 +#, no-c-format +msgid "Shift X:" +msgstr "X-forskyving:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1739 +#, no-c-format +msgid "Horizontal shift per row (in % of tile width)" +msgstr "Vassrett forskyving per rad (i prosent av flisbreidd)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1747 +#, no-c-format +msgid "Horizontal shift per column (in % of tile width)" +msgstr "Vassrett forskyving per kolonne (i prosent av flisbreidd)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1754 +msgid "Randomize the horizontal shift by this percentage" +msgstr "Randomiser vassrett forskyving med dette prosenttalet." + +#. TRANSLATORS: "shift" means: the tiles will be shifted (offset) vertically by this amount +#: ../../po/../src/dialogs/clonetiler.cpp:1764 +#, no-c-format +msgid "Shift Y:" +msgstr "Y-forskyving:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1772 +#, no-c-format +msgid "Vertical shift per row (in % of tile height)" +msgstr "Loddrett forskyving per rad (i prosent av flishøgd)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1780 +#, no-c-format +msgid "Vertical shift per column (in % of tile height)" +msgstr "Vassrett forskyving per kolonne (i prosent av flishøgd)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1787 +msgid "Randomize the vertical shift by this percentage" +msgstr "Randomiser loddrett forskyving med dette prosenttalet." + +#: ../../po/../src/dialogs/clonetiler.cpp:1795 +msgid "Exponent:" +msgstr "Eksponent:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1802 +msgid "Whether rows are spaced evenly (1), converge (<1) or diverge (>1)" +msgstr "" +"Om rader skal ha jamn avstand (1), konvergera (<1) eller divergera (>1). " + +#: ../../po/../src/dialogs/clonetiler.cpp:1809 +msgid "Whether columns are spaced evenly (1), converge (<1) or diverge (>1)" +msgstr "" +"Om kolonnar skal ha jamn avstand (1), konvergera (<1) eller divergera (>1). " + +#. TRANSLATORS: "Alternate" is a verb here +#: ../../po/../src/dialogs/clonetiler.cpp:1817 +#: ../../po/../src/dialogs/clonetiler.cpp:1907 +#: ../../po/../src/dialogs/clonetiler.cpp:1966 +#: ../../po/../src/dialogs/clonetiler.cpp:2022 +#: ../../po/../src/dialogs/clonetiler.cpp:2153 +msgid "Alternate:" +msgstr "Alternater:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1823 +msgid "Alternate the sign of shifts for each row" +msgstr "Alterner forteiknet til forskyvinga for kvar rad." + +#: ../../po/../src/dialogs/clonetiler.cpp:1828 +msgid "Alternate the sign of shifts for each column" +msgstr "Alterner forteiknet til forskyvinga for kvar kolonne." + +#: ../../po/../src/dialogs/clonetiler.cpp:1837 +msgid "Sc_ale" +msgstr "_Skaler" + +#: ../../po/../src/dialogs/clonetiler.cpp:1845 +msgid "Scale X:" +msgstr "X-skalering:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1853 +#, no-c-format +msgid "Horizontal scale per row (in % of tile width)" +msgstr "Vassrett skalering per rad (i % av flisbreidd)." + +#: ../../po/../src/dialogs/clonetiler.cpp:1861 +#, no-c-format +msgid "Horizontal scale per column (in % of tile width)" +msgstr "Vassrett skalering per kolonne (i % av flisbreidd)." + +#: ../../po/../src/dialogs/clonetiler.cpp:1868 +msgid "Randomize the horizontal scale by this percentage" +msgstr "Randomiser vassrett skalering med dette prosenttalet." + +#: ../../po/../src/dialogs/clonetiler.cpp:1876 +msgid "Scale Y:" +msgstr "Y-skalering:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1884 +#, no-c-format +msgid "Vertical scale per row (in % of tile height)" +msgstr "Loddrett skalering per rad (i % av flishøgd)." + +#: ../../po/../src/dialogs/clonetiler.cpp:1892 +#, no-c-format +msgid "Vertical scale per column (in % of tile height)" +msgstr "Loddrett skalering per kolonne (i % av flishøgd)." + +#: ../../po/../src/dialogs/clonetiler.cpp:1899 +msgid "Randomize the vertical scale by this percentage" +msgstr "Randomiser vassrett skalering med dette prosenttalet." + +#: ../../po/../src/dialogs/clonetiler.cpp:1913 +msgid "Alternate the sign of scales for each row" +msgstr "Alterner forteiknet til skaleringa for kvar rad." + +#: ../../po/../src/dialogs/clonetiler.cpp:1918 +msgid "Alternate the sign of scales for each column" +msgstr "Alterner forteiknet til skaleringa for kvar kolonne." + +#: ../../po/../src/dialogs/clonetiler.cpp:1927 +msgid "_Rotation" +msgstr "_Rotering" + +#: ../../po/../src/dialogs/clonetiler.cpp:1935 +msgid "Angle:" +msgstr "Vinkel:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1943 +#, no-c-format +msgid "Rotate tiles by this angle for each row" +msgstr "Roter fliser med denne vinkelen for kvar rad." + +#: ../../po/../src/dialogs/clonetiler.cpp:1951 +#, no-c-format +msgid "Rotate tiles by this angle for each column" +msgstr "Roter fliser med denne vinkelen for kvar kolonne." + +#: ../../po/../src/dialogs/clonetiler.cpp:1958 +msgid "Randomize the rotation angle by this percentage" +msgstr "Randomiser rotasjonsvinkelen med dette prosenttalet." + +#: ../../po/../src/dialogs/clonetiler.cpp:1972 +msgid "Alternate the rotation direction for each row" +msgstr "Alterner rotasjonsretninga for kvar rad." + +#: ../../po/../src/dialogs/clonetiler.cpp:1977 +msgid "Alternate the rotation direction for each column" +msgstr "Alterner rotasjonsretninga for kvar kolonne." + +#: ../../po/../src/dialogs/clonetiler.cpp:1985 +msgid "_Opacity" +msgstr "_Gjennomsikt" + +#: ../../po/../src/dialogs/clonetiler.cpp:1993 +msgid "Fade out:" +msgstr "Ton ut:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2000 +msgid "Decrease tile opacity by this percentage for each row" +msgstr "Auk flisugjennomsikta med dette prosenttalet for kvar rad." + +#: ../../po/../src/dialogs/clonetiler.cpp:2007 +msgid "Decrease tile opacity by this percentage for each column" +msgstr "Auk flisugjennomsikta med dette prosenttalet for kvar kolonne." + +#: ../../po/../src/dialogs/clonetiler.cpp:2014 +msgid "Randomize the tile opacity by this percentage" +msgstr "Randomiser flisugjennomsikta med dette prosenttalet for kvar rad." + +#: ../../po/../src/dialogs/clonetiler.cpp:2028 +msgid "Alternate the sign of opacity change for each row" +msgstr "Alterner forteiknet til endringa av gjennomsikta for kvar rad." + +#: ../../po/../src/dialogs/clonetiler.cpp:2033 +msgid "Alternate the sign of opacity change for each column" +msgstr "Alterner forteiknet til endringa av gjennomsikta for kvar kolonne." + +#: ../../po/../src/dialogs/clonetiler.cpp:2041 +msgid "Co_lor" +msgstr "_Fargar" + +#: ../../po/../src/dialogs/clonetiler.cpp:2046 +msgid "Initial color: " +msgstr "Startfarge:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2050 +msgid "Initial color of tiled clones" +msgstr "Startfarge til flislagde klonar." + +#: ../../po/../src/dialogs/clonetiler.cpp:2050 +msgid "" +"Initial color for clones (works only if the original has unset fill or " +"stroke)" +msgstr "" +"Startfarge til flislagde klonar (fungerer berre viss opphavet ikkje har fyll " +"eller strek)." + +#: ../../po/../src/dialogs/clonetiler.cpp:2065 +msgid "H:" +msgstr "N:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2072 +msgid "Change the tile hue by this percentage for each row" +msgstr "Endra fargenyansen til flisa med dette prosenttalet for kvar rad." + +#: ../../po/../src/dialogs/clonetiler.cpp:2079 +msgid "Change the tile hue by this percentage for each column" +msgstr "Endra fargenyansen til flisa med dette prosenttalet for kvar kolonne." + +#: ../../po/../src/dialogs/clonetiler.cpp:2086 +msgid "Randomize the tile hue by this percentage" +msgstr "Randomiser fargenyansen til flisa med dette prosenttalet." + +#: ../../po/../src/dialogs/clonetiler.cpp:2095 +msgid "S:" +msgstr "M:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2102 +msgid "Change the color saturation by this percentage for each row" +msgstr "Endra fargemettinga til flisa med dette prosenttalet for kvar rad." + +#: ../../po/../src/dialogs/clonetiler.cpp:2109 +msgid "Change the color saturation by this percentage for each column" +msgstr "Endra fargemettinga til flisa med dette prosenttalet for kvar kolonne." + +#: ../../po/../src/dialogs/clonetiler.cpp:2116 +msgid "Randomize the color saturation by this percentage" +msgstr "Randomiser fargemettinga til flisa med dette prosenttalet." + +#: ../../po/../src/dialogs/clonetiler.cpp:2124 +msgid "L:" +msgstr "L:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2131 +msgid "Change the color lightness by this percentage for each row" +msgstr "Endra lysstyrken til flisa med dette prosenttalet for kvar rad." + +#: ../../po/../src/dialogs/clonetiler.cpp:2138 +msgid "Change the color lightness by this percentage for each column" +msgstr "Endra lysstyrken til flisa med dette prosenttalet for kvar kolonne." + +#: ../../po/../src/dialogs/clonetiler.cpp:2145 +msgid "Randomize the color lightness by this percentage" +msgstr "Randomiser lysstyrken til flisa med dette prosenttalet." + +#: ../../po/../src/dialogs/clonetiler.cpp:2159 +msgid "Alternate the sign of color changes for each row" +msgstr "Alterner forteiknet til fargeendringa for kvar rad." + +#: ../../po/../src/dialogs/clonetiler.cpp:2164 +msgid "Alternate the sign of color changes for each column" +msgstr "Alterner forteiknet til fargeendringa for kvar kolonne." + +#: ../../po/../src/dialogs/clonetiler.cpp:2172 +msgid "_Trace" +msgstr "_Teikn av" + +#: ../../po/../src/dialogs/clonetiler.cpp:2179 +msgid "Trace the drawing under the tiles" +msgstr "Teikn av teikninga under flisene." + +#: ../../po/../src/dialogs/clonetiler.cpp:2183 +msgid "" +"For each clone, pick a value from the drawing in that clone's location and " +"apply it to the clone" +msgstr "" +"For kvar klon, vel ein verdi frÃ¥ teikninga under klonen, og bruk denne pÃ¥ " +"klonen." + +#: ../../po/../src/dialogs/clonetiler.cpp:2197 +msgid "1. Pick from the drawing:" +msgstr "1 Hent frÃ¥ teikning:" + +#. ----Hbox2 +#: ../../po/../src/dialogs/clonetiler.cpp:2208 +#: ../../po/../src/dialogs/clonetiler.cpp:2355 +#: ../../po/../src/ui/dialog/tracedialog.cpp:445 +msgid "Color" +msgstr "Farge" + +#: ../../po/../src/dialogs/clonetiler.cpp:2209 +msgid "Pick the visible color and opacity" +msgstr "Hent synleg farge og gjennomsikt." + +#: ../../po/../src/dialogs/clonetiler.cpp:2216 +#: ../../po/../src/dialogs/clonetiler.cpp:2365 +#: ../share/extensions/dropshadow.inx.h:3 +msgid "Opacity" +msgstr "Gjennomsikt" + +#: ../../po/../src/dialogs/clonetiler.cpp:2217 +msgid "Pick the total accumulated opacity" +msgstr "Hent oppsamla gjennomsikt." + +#: ../../po/../src/dialogs/clonetiler.cpp:2224 +msgid "R" +msgstr "R" + +#: ../../po/../src/dialogs/clonetiler.cpp:2225 +msgid "Pick the Red component of the color" +msgstr "Hent raudkomponenten av fargen." + +#: ../../po/../src/dialogs/clonetiler.cpp:2232 +msgid "G" +msgstr "G" + +#: ../../po/../src/dialogs/clonetiler.cpp:2233 +msgid "Pick the Green component of the color" +msgstr "Hent grønkomponenten av fargen." + +#: ../../po/../src/dialogs/clonetiler.cpp:2240 +msgid "B" +msgstr "B" + +#: ../../po/../src/dialogs/clonetiler.cpp:2241 +msgid "Pick the Blue component of the color" +msgstr "Hent blÃ¥komponenten av fargen." + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2250 +msgid "clonetiler|H" +msgstr "clonetiler|N" + +#: ../../po/../src/dialogs/clonetiler.cpp:2251 +msgid "Pick the hue of the color" +msgstr "Hent nyansen til fargen." + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2260 +msgid "clonetiler|S" +msgstr "clonetiler|M" + +#: ../../po/../src/dialogs/clonetiler.cpp:2261 +msgid "Pick the saturation of the color" +msgstr "Hent mettinga til fargen." + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2270 +msgid "clonetiler|L" +msgstr "clonetiler|L" + +#: ../../po/../src/dialogs/clonetiler.cpp:2271 +msgid "Pick the lightness of the color" +msgstr "Hent lysstyrken til fargen." + +#: ../../po/../src/dialogs/clonetiler.cpp:2281 +msgid "2. Tweak the picked value:" +msgstr "2 Endra vald verdi:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2291 +msgid "Gamma-correct:" +msgstr "Gammakorriger:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2296 +msgid "Shift the mid-range of the picked value upwards (>0) or downwards (<0)" +msgstr "Forskyv midtverdiane til vald farge oppover (>0) eller nedover (<0)." + +#: ../../po/../src/dialogs/clonetiler.cpp:2303 +msgid "Randomize:" +msgstr "Slumpverdi:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2308 +msgid "Randomize the picked value by this percentage" +msgstr "Randomiser vald verdi med dette prosenttalet." + +#: ../../po/../src/dialogs/clonetiler.cpp:2315 +msgid "Invert:" +msgstr "Inverter:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2319 +msgid "Invert the picked value" +msgstr "Inverter vald verdi." + +#: ../../po/../src/dialogs/clonetiler.cpp:2325 +msgid "3. Apply the value to the clones':" +msgstr "3 Bruk verdien pÃ¥ klonene:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2335 +msgid "Presence" +msgstr "Nærvær" + +#: ../../po/../src/dialogs/clonetiler.cpp:2338 +msgid "" +"Each clone is created with the probability determined by the picked value in " +"that point" +msgstr "Kvar klon vert laga med eit sannsyn fastsett av vald verdi i punktet." + +#: ../../po/../src/dialogs/clonetiler.cpp:2345 +msgid "Size" +msgstr "Storleik" + +#: ../../po/../src/dialogs/clonetiler.cpp:2348 +msgid "Each clone's size is determined by the picked value in that point" +msgstr "Storleik til kvar klon vert fastsett av vald verdi i punktet." + +#: ../../po/../src/dialogs/clonetiler.cpp:2358 +msgid "" +"Each clone is painted by the picked color (the original must have unset fill " +"or stroke)" +msgstr "" +"Kvar klon vert teikna med vald farge (fungerer berre viss opphavet ikkje har " +"fyll eller strek)." + +#: ../../po/../src/dialogs/clonetiler.cpp:2368 +msgid "Each clone's opacity is determined by the picked value in that point" +msgstr "Gjennomsikt til kvar klon vert fastsett av vald verdi i punktet." + +#: ../../po/../src/dialogs/clonetiler.cpp:2395 +msgid "How many rows in the tiling" +msgstr "Kor mange rader det skal vera i flisleggjinga." + +#: ../../po/../src/dialogs/clonetiler.cpp:2415 +msgid "How many columns in the tiling" +msgstr "Kor mange kolonner det skal vera i flisleggjinga." + +#: ../../po/../src/dialogs/clonetiler.cpp:2445 +msgid "Width of the rectangle to be filled" +msgstr "Breidda pÃ¥ rektangelet som skal fyllast." + +#: ../../po/../src/dialogs/clonetiler.cpp:2470 +msgid "Height of the rectangle to be filled" +msgstr "Høgda pÃ¥ rektangelet som skal fyllast." + +#: ../../po/../src/dialogs/clonetiler.cpp:2485 +msgid "Rows, columns: " +msgstr "Rader, kolonnar: " + +#: ../../po/../src/dialogs/clonetiler.cpp:2486 +msgid "Create the specified number of rows and columns" +msgstr "Lag sÃ¥ mange rader og kolonnar." + +#: ../../po/../src/dialogs/clonetiler.cpp:2495 +msgid "Width, height: " +msgstr "Breidd, høgd: " + +#: ../../po/../src/dialogs/clonetiler.cpp:2496 +msgid "Fill the specified width and height with the tiling" +msgstr "Fyll vald breidd og høgd med fliser." + +#: ../../po/../src/dialogs/clonetiler.cpp:2512 +msgid "Use saved size and position of the tile" +msgstr "Bruka lagra storleik og plasseringa av flisa." + +#: ../../po/../src/dialogs/clonetiler.cpp:2515 +msgid "" +"Pretend that the size and position of the tile are the same as the last time " +"you tiled it (if any), instead of using the current size" +msgstr "" +"Lat som storleiken og plasseringa til flisa er dei same som ved sist " +"flisleggjing, og ikkje bruk gjeldande storleik." + +#: ../../po/../src/dialogs/clonetiler.cpp:2539 +msgid " _Create " +msgstr "_Lag " + +#: ../../po/../src/dialogs/clonetiler.cpp:2541 +msgid "Create and tile the clones of the selection" +msgstr "Lag og flislegg klonar av utvalet." + +#. TRANSLATORS: if a group of objects are "clumped" together, then they +#. are unevenly spread in the given amount of space - as shown in the +#. diagrams on the left in the following screenshot: +#. http://www.inkscape.org/screenshots/gallery/inkscape-0.42-CVS-tiles-unclump.png +#. So unclumping is the process of spreading a number of objects out more evenly. +#: ../../po/../src/dialogs/clonetiler.cpp:2556 +msgid " _Unclump " +msgstr "_Avklump " + +#: ../../po/../src/dialogs/clonetiler.cpp:2557 +msgid "Spread out clones to reduce clumping; can be applied repeatedly" +msgstr "" +"Sprei ut klonane for Ã¥ redusera klumping. Du kan bruka funksjonen fleire " +"gongar." + +#: ../../po/../src/dialogs/clonetiler.cpp:2563 +msgid " Re_move " +msgstr " _Fjern " + +#: ../../po/../src/dialogs/clonetiler.cpp:2564 +msgid "Remove existing tiled clones of the selected object (siblings only)" +msgstr "Fjern flislagde klonar av vald objekt (berre sysken)." + +#: ../../po/../src/dialogs/clonetiler.cpp:2580 +msgid " R_eset " +msgstr " _Nullstill " + +#. TRANSLATORS: "change" is a noun here +#: ../../po/../src/dialogs/clonetiler.cpp:2582 +msgid "" +"Reset all shifts, scales, rotates, opacity and color changes in the dialog " +"to zero" +msgstr "" +"Nullstill alle forskyvingar, skaleringar, roteringar, gjennomsikts- og " +"fargeendringar." + +#: ../../po/../src/dialogs/color-picker.cpp:280 +msgid "Close" +msgstr "Lukk" + +#: ../../po/../src/dialogs/debugdialog.cpp:138 +msgid "Messages" +msgstr "Meldingar" + +#. ## Add a menu for clear() +#: ../../po/../src/dialogs/debugdialog.cpp:144 +#: ../../po/../src/menus-skeleton.h:16 +#: ../../po/../src/ui/dialog/messages.cpp:56 +#: ../../po/../src/ui/dialog/scriptdialog.cpp:181 +msgid "_File" +msgstr "_Fil" + +#. TRANSLATORS: "Clear" is a verb here +#: ../../po/../src/dialogs/debugdialog.cpp:145 +#: ../../po/../src/dialogs/find.cpp:753 +#: ../../po/../src/ui/dialog/messages.cpp:57 +#: ../../po/../src/ui/dialog/scriptdialog.cpp:182 +msgid "_Clear" +msgstr "_Tøm" + +#: ../../po/../src/dialogs/debugdialog.cpp:147 +#: ../../po/../src/ui/dialog/messages.cpp:59 +msgid "Capture log messages" +msgstr "Lagra loggmeldingar" + +#: ../../po/../src/dialogs/debugdialog.cpp:149 +#: ../../po/../src/ui/dialog/messages.cpp:61 +msgid "Release log messages" +msgstr "Tøm loggmeldingar" + +#. Notebook tab +#: ../../po/../src/dialogs/desktop-properties.cpp:909 +#: ../../po/../src/ui/dialog/document-preferences.cpp:89 +#: ../../po/../src/ui/widget/panel.cpp:107 +msgid "Grid" +msgstr "Rutenett" + +#. Checkbuttons +#. / \todo FIXME: gray out snapping when grid is off +#. / \todo FIXME: gray out snapping when grid is off. +#. / Dissenting view: you want snapping without grid. +#: ../../po/../src/dialogs/desktop-properties.cpp:917 +#: ../../po/../src/ui/dialog/document-preferences.cpp:179 +msgid "Show grid" +msgstr "Vis rutenett" + +#: ../../po/../src/dialogs/desktop-properties.cpp:917 +#: ../../po/../src/ui/dialog/document-preferences.cpp:179 +#: ../../po/../src/verbs.cpp:2115 +msgid "Show or hide grid" +msgstr "Vis eller skjul rutenett." + +#: ../../po/../src/dialogs/desktop-properties.cpp:918 +#: ../../po/../src/ui/dialog/document-preferences.cpp:180 +msgid "Snap bounding boxes to grid" +msgstr "Fest avgrensingsboksar til rutenett" + +#: ../../po/../src/dialogs/desktop-properties.cpp:918 +#: ../../po/../src/dialogs/desktop-properties.cpp:1001 +#: ../../po/../src/ui/dialog/document-preferences.cpp:181 +#: ../../po/../src/ui/dialog/document-preferences.cpp:236 +msgid "Snap the edges of the object bounding boxes" +msgstr "Fest automatisk kantane til avgrensingsboksar til rutenettet." + +#: ../../po/../src/dialogs/desktop-properties.cpp:919 +#: ../../po/../src/ui/dialog/document-preferences.cpp:183 +#, fuzzy +msgid "Snap nodes to grid" +msgstr "Fest punkt til rutenett" + +#: ../../po/../src/dialogs/desktop-properties.cpp:919 +#: ../../po/../src/dialogs/desktop-properties.cpp:1002 +#: ../../po/../src/ui/dialog/document-preferences.cpp:184 +#: ../../po/../src/ui/dialog/document-preferences.cpp:239 +msgid "Snap path nodes, text baselines, ellipse centers, etc." +msgstr "" +"Fest automatisk banenodar, tekstgrunnlinjer, ellipsesenter og anna til " +"rutenettet." + +#: ../../po/../src/dialogs/desktop-properties.cpp:937 +#: ../../po/../src/ui/dialog/document-preferences.cpp:186 +msgid "Grid units:" +msgstr "Eining for rutenett:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:939 +#: ../../po/../src/ui/dialog/document-preferences.cpp:187 +msgid "Origin X:" +msgstr "X-origo:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:942 +#: ../../po/../src/ui/dialog/document-preferences.cpp:189 +msgid "Origin Y:" +msgstr "Y-origo:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:945 +#: ../../po/../src/ui/dialog/document-preferences.cpp:191 +msgid "Spacing X:" +msgstr "X-mellomrom:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:948 +#: ../../po/../src/ui/dialog/document-preferences.cpp:193 +msgid "Spacing Y:" +msgstr "Y-mellomrom:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:952 +#: ../../po/../src/dialogs/desktop-properties.cpp:1013 +#: ../../po/../src/ui/dialog/document-preferences.cpp:195 +#: ../../po/../src/ui/dialog/document-preferences.cpp:241 +msgid "Snap units:" +msgstr "Festeeining:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:955 +#: ../../po/../src/dialogs/desktop-properties.cpp:1016 +#: ../../po/../src/ui/dialog/document-preferences.cpp:196 +#: ../../po/../src/ui/dialog/document-preferences.cpp:242 +msgid "Snap distance:" +msgstr "Festeavstand:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:958 +#: ../../po/../src/ui/dialog/document-preferences.cpp:199 +msgid "Grid line color:" +msgstr "Farge for rutenett:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:959 +#: ../../po/../src/ui/dialog/document-preferences.cpp:199 +msgid "Grid line color" +msgstr "Farge for rutenett." + +#: ../../po/../src/dialogs/desktop-properties.cpp:959 +#: ../../po/../src/ui/dialog/document-preferences.cpp:200 +msgid "Color of grid lines" +msgstr "Farge pÃ¥ rutenett." + +#: ../../po/../src/dialogs/desktop-properties.cpp:961 +#: ../../po/../src/ui/dialog/document-preferences.cpp:201 +msgid "Major grid line color:" +msgstr "Farge pÃ¥ hovudlinjer:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:962 +#: ../../po/../src/ui/dialog/document-preferences.cpp:201 +msgid "Major grid line color" +msgstr "Farge pÃ¥ hovudlinjer." + +#: ../../po/../src/dialogs/desktop-properties.cpp:962 +#: ../../po/../src/ui/dialog/document-preferences.cpp:202 +msgid "Color of the major (highlighted) grid lines" +msgstr "Farge pÃ¥ hovudlinjer (tjukke linjer)." + +#: ../../po/../src/dialogs/desktop-properties.cpp:965 +#: ../../po/../src/ui/dialog/document-preferences.cpp:204 +msgid "Major grid line every:" +msgstr "Bruk hovudlinjer pÃ¥ kvar" + +#. TRANSLATORS: This belongs to the "Major grid line every:" string, +#. see grid settings in the "Document Preferences" dialog +#: ../../po/../src/dialogs/desktop-properties.cpp:977 +#: ../../po/../src/ui/dialog/document-preferences.cpp:204 +msgid "lines" +msgstr "linje" + +#. Guidelines page +#: ../../po/../src/dialogs/desktop-properties.cpp:991 +#: ../../po/../src/ui/dialog/document-preferences.cpp:90 +msgid "Guides" +msgstr "Hjelpelinjer" + +#. / \todo FIXME: gray out snapping when guides are off +#. / Dissenting view: you want snapping without guides. +#: ../../po/../src/dialogs/desktop-properties.cpp:1000 +#: ../../po/../src/ui/dialog/document-preferences.cpp:234 +msgid "Show guides" +msgstr "Vis hjelpelinjer" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1000 +#: ../../po/../src/ui/dialog/document-preferences.cpp:234 +#: ../../po/../src/verbs.cpp:2116 +msgid "Show or hide guides" +msgstr "Vis eller skjul hjelpelinjer." + +#: ../../po/../src/dialogs/desktop-properties.cpp:1001 +#: ../../po/../src/ui/dialog/document-preferences.cpp:235 +msgid "Snap bounding boxes to guides" +msgstr "Fest avgrensingsboks til hjelpelinjer" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1002 +#: ../../po/../src/ui/dialog/document-preferences.cpp:238 +msgid "Snap points to guides" +msgstr "Fest punkt til hjelpelinjer" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1020 +#: ../../po/../src/ui/dialog/document-preferences.cpp:243 +msgid "Guide color:" +msgstr "Hjelpelinjefarge:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1021 +#: ../../po/../src/ui/dialog/document-preferences.cpp:243 +msgid "Guideline color" +msgstr "Farge for hjelpelinjer." + +#: ../../po/../src/dialogs/desktop-properties.cpp:1021 +#: ../../po/../src/ui/dialog/document-preferences.cpp:244 +msgid "Color of guidelines" +msgstr "Farge for hjelpelinjer." + +#: ../../po/../src/dialogs/desktop-properties.cpp:1023 +#: ../../po/../src/ui/dialog/document-preferences.cpp:245 +msgid "Highlight color:" +msgstr "Framhevingsfarge:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1024 +#: ../../po/../src/ui/dialog/document-preferences.cpp:245 +msgid "Highlighted guideline color" +msgstr "Farge for framheva hjelpelinjer." + +#: ../../po/../src/dialogs/desktop-properties.cpp:1024 +#: ../../po/../src/ui/dialog/document-preferences.cpp:246 +msgid "Color of a guideline when it is under mouse" +msgstr "Farge pÃ¥ hjelpelinje under musepeikaren." + +#. Page page +#: ../../po/../src/dialogs/desktop-properties.cpp:1029 +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:855 +#: ../../po/../src/ui/dialog/document-preferences.cpp:88 +#: ../../po/../src/widgets/desktop-widget.cpp:1061 +msgid "Page" +msgstr "Side" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1039 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +msgid "Background:" +msgstr "Bakgrunnsfarge:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1040 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +msgid "Background color" +msgstr "Bakgrunnsfarge." + +#: ../../po/../src/dialogs/desktop-properties.cpp:1041 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +msgid "" +"Color and transparency of the page background (also used for bitmap export)" +msgstr "" +"Farge og gjennomsikt til sidebakgrunnen. Denne vert òg brukt ved " +"eksportering til punktbilete." + +#: ../../po/../src/dialogs/desktop-properties.cpp:1045 +#: ../../po/../src/ui/dialog/document-preferences.cpp:147 +#, fuzzy +msgid "Show page border" +msgstr "Vis kantlinje rundt lerretet" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1049 +#: ../../po/../src/ui/dialog/document-preferences.cpp:148 +msgid "Border on top of drawing" +msgstr "Kantlinje øvst pÃ¥ teikninga" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1052 +#: ../../po/../src/ui/dialog/document-preferences.cpp:149 +msgid "Border color:" +msgstr "Kantlinjefarge:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1053 +#: ../../po/../src/ui/dialog/document-preferences.cpp:149 +#, fuzzy +msgid "Page border color" +msgstr "Farge pÃ¥ kantlinje" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1054 +#: ../../po/../src/ui/dialog/document-preferences.cpp:150 +#, fuzzy +msgid "Color of the page border" +msgstr "Farge pÃ¥ kantlinje rundt lerretet" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1059 +#: ../../po/../src/ui/dialog/document-preferences.cpp:152 +msgid "Show page shadow" +msgstr "Vis sideskugge" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1063 +#: ../../po/../src/ui/dialog/document-preferences.cpp:153 +msgid "Default units:" +msgstr "Standardeiningar:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1069 +msgid "Units for the tool controls, ruler, and the statusbar" +msgstr "Eining for verktøykontrollar, linjal og statuslinje." + +#: ../../po/../src/dialogs/desktop-properties.cpp:1086 +#: ../../po/../src/ui/widget/page-sizer.cpp:209 +#, fuzzy +msgid "Page size:" +msgstr "Lerretstorleik" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1110 +#: ../../po/../src/ui/widget/page-sizer.cpp:219 +msgid "Custom" +msgstr "Brukarvald" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1121 +#: ../../po/../src/ui/widget/page-sizer.cpp:225 +#, fuzzy +msgid "Page orientation:" +msgstr "Lerretretning" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1133 +#: ../../po/../src/ui/widget/page-sizer.cpp:232 +msgid "Landscape" +msgstr "Liggjande" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1139 +#: ../../po/../src/ui/widget/page-sizer.cpp:234 +msgid "Portrait" +msgstr "StÃ¥ande" + +#. Custom paper frame +#: ../../po/../src/dialogs/desktop-properties.cpp:1148 +#: ../../po/../src/ui/widget/page-sizer.cpp:249 +#, fuzzy +msgid "Custom size" +msgstr "Brukarvald" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1160 +#: ../../po/../src/dialogs/export.cpp:269 +#: ../../po/../src/ui/widget/page-sizer.cpp:261 +msgid "Units:" +msgstr "Eining:" + +#. Stroke width +#: ../../po/../src/dialogs/desktop-properties.cpp:1162 +#: ../../po/../src/dialogs/export.cpp:310 +#: ../../po/../src/dialogs/object-attributes.cpp:55 +#: ../../po/../src/dialogs/stroke-style.cpp:985 +#: ../../po/../src/ui/widget/page-sizer.cpp:262 +#: ../../po/../src/widgets/toolbox.cpp:1957 +msgid "Width:" +msgstr "Breidd:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1183 +#: ../../po/../src/dialogs/export.cpp:326 +#: ../../po/../src/dialogs/export.cpp:431 +#: ../../po/../src/dialogs/object-attributes.cpp:56 +#: ../../po/../src/ui/widget/page-sizer.cpp:263 +msgid "Height:" +msgstr "Høgd:" + +#. +#. * Ownership metadata tab +#. +#: ../../po/../src/dialogs/desktop-properties.cpp:1206 +msgid "Metadata" +msgstr "Metadata" + +#. add license selector pull-down +#: ../../po/../src/dialogs/desktop-properties.cpp:1225 +msgid "License" +msgstr "Lisensavtale" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1255 +msgid "Proprietary" +msgstr "Godseigd" + +#: ../../po/../src/dialogs/display-settings.cpp:212 +msgid "When transforming, show:" +msgstr "Vis ved omforming:" + +#: ../../po/../src/dialogs/display-settings.cpp:223 +msgid "Objects" +msgstr "Objekt" + +#: ../../po/../src/dialogs/display-settings.cpp:224 +msgid "Show the actual objects when moving or transforming" +msgstr "Vis objekt ved flytting og omforming." + +#: ../../po/../src/dialogs/display-settings.cpp:231 +msgid "Box outline" +msgstr "Boksomriss" + +#: ../../po/../src/dialogs/display-settings.cpp:232 +msgid "Show only a box outline of the objects when moving or transforming" +msgstr "Vis berre eit boksomriss av objekt ved flytting og omforming." + +#: ../../po/../src/dialogs/display-settings.cpp:238 +msgid "Per-object selection cue:" +msgstr "Objektmerke:" + +#. sorationsnapsperpi == 0 means no snapping +#: ../../po/../src/dialogs/display-settings.cpp:249 +#: ../../po/../src/dialogs/display-settings.cpp:386 +#: ../../po/../src/dialogs/display-settings.cpp:441 +#: ../../po/../src/dialogs/display-settings.cpp:1482 +#: ../../po/../src/dialogs/stroke-style.cpp:791 +#: ../../po/../src/interface.cpp:741 +#: ../../po/../src/ui/widget/selected-style.cpp:100 +#: ../../po/../src/verbs.cpp:1842 +msgid "None" +msgstr "Ingen" + +#: ../../po/../src/dialogs/display-settings.cpp:250 +msgid "No per-object selection indication" +msgstr "Inga objektmerke" + +#: ../../po/../src/dialogs/display-settings.cpp:256 +msgid "Mark" +msgstr "Rutemerke" + +#: ../../po/../src/dialogs/display-settings.cpp:257 +msgid "Each selected object has a diamond mark in the top left corner" +msgstr "Kvart merkte objekt har eit rutemerke øvst i venstre hjørne." + +#: ../../po/../src/dialogs/display-settings.cpp:264 +msgid "Box" +msgstr "Boks" + +#: ../../po/../src/dialogs/display-settings.cpp:265 +msgid "Each selected object displays its bounding box" +msgstr "Kvart merkte objekt har ein synleg avgrensingsboks" + +#: ../../po/../src/dialogs/display-settings.cpp:270 +msgid "Default scale origin:" +msgstr "Standard skaleringsbase:" + +#: ../../po/../src/dialogs/display-settings.cpp:281 +msgid "Opposite bounding box edge" +msgstr "Overfor avgrensingsbokskant" + +#: ../../po/../src/dialogs/display-settings.cpp:282 +msgid "Default scale origin will be on the bounding box of the item" +msgstr "Standard skaleringsbase er pÃ¥ avgrensingsboksen til objektet." + +#: ../../po/../src/dialogs/display-settings.cpp:288 +msgid "Farthest opposite node" +msgstr "Den ytste noden" + +#: ../../po/../src/dialogs/display-settings.cpp:289 +msgid "Default scale origin will be on the bounding box of the item's points" +msgstr "" +"Standard skaleringsbase er pÃ¥ avgrensingsboksen til punkta til objektet." + +#: ../../po/../src/dialogs/display-settings.cpp:341 +msgid "degrees" +msgstr "gradar" + +#: ../../po/../src/dialogs/display-settings.cpp:350 +msgid "" +"Rotating with Ctrl pressed snaps every that much degrees; also, pressing " +"[ or ] rotates by this amount" +msgstr "" +"Roterer i steg pÃ¥ denne verdien nÃ¥r du held Ctrl inne. Du kan òg " +"bruka [ og ] for Ã¥ rotera i steg." + +#: ../../po/../src/dialogs/display-settings.cpp:407 +msgid "Rotation snaps every:" +msgstr "Roteringssteg:" + +#: ../../po/../src/dialogs/display-settings.cpp:430 +msgid "" +"None: dialogs are treated as regular windows; Normal: dialogs stay on top of " +"document windows; Aggressive: same as Normal but may work better with some " +"window managers." +msgstr "" +"Ingen: Dialogar vert handtert som vanlege vindauge.\n" +"Vanleg: Dialogar vert liggjande over dokumentvindauge.\n" +"Aggressiv: Same som vanleg, men kan verka betre med nokre " +"vindaugsbehandlarar." + +#: ../../po/../src/dialogs/display-settings.cpp:451 +msgid "Normal" +msgstr "Vanleg" + +#: ../../po/../src/dialogs/display-settings.cpp:461 +msgid "Aggressive" +msgstr "Aggressiv" + +#: ../../po/../src/dialogs/display-settings.cpp:475 +msgid "Dialogs on top:" +msgstr "Dialogar øvst:" + +#: ../../po/../src/dialogs/display-settings.cpp:645 +msgid "Show selection cue" +msgstr "Vis objektmerke" + +#: ../../po/../src/dialogs/display-settings.cpp:646 +msgid "" +"Whether selected objects display a selection cue (the same as in selector)" +msgstr "" +"Om merkte objekt skal visa ei objektmerke (same som under «Objektveljar»)." + +#: ../../po/../src/dialogs/display-settings.cpp:657 +msgid "Enable gradient editing" +msgstr "Bruk Fargeovergangredigering" + +#: ../../po/../src/dialogs/display-settings.cpp:658 +msgid "Whether selected objects display gradient editing controls" +msgstr "Om merkte objekt skal visa kontrollar for fargeovergangar." + +#: ../../po/../src/dialogs/display-settings.cpp:719 +msgid "No objects selected to take the style from." +msgstr "Ingen merkte objekt Ã¥ henta stil frÃ¥." + +#: ../../po/../src/dialogs/display-settings.cpp:728 +msgid "" +"More than one object selected. Cannot take style from multiple " +"objects." +msgstr "" +"Meir enn eitt merkt objekt. Kan ikkje henta stil frÃ¥ fleirutval." + +#: ../../po/../src/dialogs/display-settings.cpp:767 +msgid "Create new objects with:" +msgstr "Lag nytt objekt med:" + +#: ../../po/../src/dialogs/display-settings.cpp:777 +msgid "Take from selection" +msgstr "Hent frÃ¥ utvalet" + +#: ../../po/../src/dialogs/display-settings.cpp:778 +msgid "Remember the style of the (first) selected object as this tool's style" +msgstr "" +"Bruk stil til det først merkte objektet som standardstil for dette verktøyet." + +#: ../../po/../src/dialogs/display-settings.cpp:782 +#, fuzzy +msgid "Last used style" +msgstr "Lim inn st_il" + +#: ../../po/../src/dialogs/display-settings.cpp:782 +msgid "Apply the style you last set on an object" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:790 +msgid "This tool's own style:" +msgstr "Eigen stil for dette verktøyet:" + +#: ../../po/../src/dialogs/display-settings.cpp:790 +msgid "" +"Each tool may store its own style to apply to the newly created objects. Use " +"the button below to set it." +msgstr "" +"Kvart verktøy kan ha sin eigen standardstil som vert brukt pÃ¥ nye objekt. " +"Bruk knappen nedanfor for Ã¥ velja standardstil." + +#. Mouse +#: ../../po/../src/dialogs/display-settings.cpp:877 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:55 +msgid "Mouse" +msgstr "Mus" + +#. TRANSLATORS: "Grab" is a noun here. "Grab sensitivity" is intended to mean how +#. * close on the screen you need to be to an object to be able to grab it with mouse (in +#. * pixels). +#: ../../po/../src/dialogs/display-settings.cpp:883 +msgid "Grab sensitivity:" +msgstr "Plukkfølsemd:" + +#: ../../po/../src/dialogs/display-settings.cpp:884 +msgid "" +"How close on the screen you need to be to an object to be able to grab it " +"with mouse (in screen pixels)" +msgstr "" +"Kor nært (i skjermpikslar) du mÃ¥ vera eit objekt for Ã¥ kunna plukka det opp " +"med musa." + +#: ../../po/../src/dialogs/display-settings.cpp:885 +#: ../../po/../src/dialogs/display-settings.cpp:897 +#: ../../po/../src/dialogs/display-settings.cpp:912 +#: ../../po/../src/dialogs/display-settings.cpp:930 +#: ../../po/../src/dialogs/display-settings.cpp:970 +msgid "pixels" +msgstr "pikslar" + +#: ../../po/../src/dialogs/display-settings.cpp:895 +msgid "Click/drag threshold:" +msgstr "Klikk/dra-grense:" + +#: ../../po/../src/dialogs/display-settings.cpp:896 +msgid "" +"Maximum mouse drag (in screen pixels) which is considered a click, not a drag" +msgstr "" +"Lengste musedrag (i pikslar) som skal hanterast som klikk i staden for drag." + +#. Scrolling +#: ../../po/../src/dialogs/display-settings.cpp:907 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:56 +msgid "Scrolling" +msgstr "Rulling" + +#: ../../po/../src/dialogs/display-settings.cpp:910 +msgid "Mouse wheel scrolls by:" +msgstr "Musehjul rullar med:" + +#: ../../po/../src/dialogs/display-settings.cpp:911 +msgid "" +"One mouse wheel notch scrolls by this distance in screen pixels " +"(horizontally with Shift)" +msgstr "" +"Eitt rull pÃ¥ mushjulet rullar sÃ¥ langt i pikslar (vassrett om du held inne " +"Shift)." + +#: ../../po/../src/dialogs/display-settings.cpp:920 +msgid "Ctrl+arrows" +msgstr "Ctrl + piltastar" + +#: ../../po/../src/dialogs/display-settings.cpp:928 +msgid "Scroll by:" +msgstr "Rull med:" + +#: ../../po/../src/dialogs/display-settings.cpp:929 +msgid "Pressing Ctrl+arrow key scrolls by this distance (in screen pixels)" +msgstr "Trykk Ctrl + piltastar for Ã¥ rulla sÃ¥ mykje (i skjermpikslar)." + +#: ../../po/../src/dialogs/display-settings.cpp:939 +msgid "Acceleration:" +msgstr "Akselerasjon:" + +#: ../../po/../src/dialogs/display-settings.cpp:940 +msgid "" +"Pressing and holding Ctrl+arrow will gradually speed up scrolling (0 for no " +"acceleration)" +msgstr "" +"Om du trykkjer og held nede Ctrl + piltastar vil du gradvis rulla " +"raskare (0 for inga akselerasjon)." + +#: ../../po/../src/dialogs/display-settings.cpp:949 +msgid "Autoscrolling" +msgstr "Autorulling" + +#: ../../po/../src/dialogs/display-settings.cpp:957 +msgid "Speed:" +msgstr "Fart:" + +#: ../../po/../src/dialogs/display-settings.cpp:958 +msgid "" +"How fast the canvas autoscrolls when you drag beyond canvas edge (0 to turn " +"autoscroll off)" +msgstr "" +"Kor raskt lerret skal rulla automatisk nÃ¥r du dreg utanfor kanten (0 for Ã¥ " +"slÃ¥ av automatisk rulling)." + +#: ../../po/../src/dialogs/display-settings.cpp:968 +#: ../../po/../src/ui/dialog/tracedialog.cpp:357 +#: ../../po/../src/ui/dialog/tracedialog.cpp:390 +msgid "Threshold:" +msgstr "Terskel:" + +#: ../../po/../src/dialogs/display-settings.cpp:969 +msgid "" +"How far (in screen pixels) you need to be from the canvas edge to trigger " +"autoscroll; positive is outside the canvas, negative is within the canvas" +msgstr "" +"Kor langt (i skjermpikslar) du mÃ¥ vera frÃ¥ kanten pÃ¥ lerretet for Ã¥ setja i " +"gong automatisk rulling. Positive verdiar gjeld utanfor lerretet og negative " +"innanfor." + +#. Steps +#: ../../po/../src/dialogs/display-settings.cpp:979 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:57 +msgid "Steps" +msgstr "Steg" + +#: ../../po/../src/dialogs/display-settings.cpp:982 +msgid "Arrow keys move by:" +msgstr "Piltastar flyttar:" + +#: ../../po/../src/dialogs/display-settings.cpp:983 +msgid "" +"Pressing an arrow key moves selected object(s) or node(s) by this distance " +"(in px units)" +msgstr "" +"Trykk ein piltast for Ã¥ flytta objektet/objekta eller noden/nodane sÃ¥ mykje " +"(i px-einingar)." + +#: ../../po/../src/dialogs/display-settings.cpp:984 +#: ../../po/../src/dialogs/display-settings.cpp:995 +#: ../../po/../src/dialogs/display-settings.cpp:1006 +#: ../../po/../src/helper/units.cpp:42 +msgid "px" +msgstr "pikslar" + +#: ../../po/../src/dialogs/display-settings.cpp:993 +msgid "> and < scale by:" +msgstr "«>» og «<» skalerer:" + +#: ../../po/../src/dialogs/display-settings.cpp:994 +msgid "" +"Pressing > or < scales selection up or down by this increment (in px units)" +msgstr "" +"Trykk «>» eller «<» for Ã¥ skalera utvalet opp eller ned sÃ¥ mykje (i px-" +"einingar)." + +#: ../../po/../src/dialogs/display-settings.cpp:1004 +msgid "Inset/Outset by:" +msgstr "Skubb inn/ut med:" + +#: ../../po/../src/dialogs/display-settings.cpp:1005 +msgid "" +"Inset and Outset commands displace the path by this distance (in px units)" +msgstr "" +"Kor langt (i px-einingar) «Skubb inn»- og «Skubb ut»-kommandoane skal skubba " +"bana inn eller ut." + +#: ../../po/../src/dialogs/display-settings.cpp:1017 +msgid "Compass-like display of angles" +msgstr "" + +#. TRANSLATORS: "positive clockwise" means "increasing in clockwise direction" +#: ../../po/../src/dialogs/display-settings.cpp:1019 +msgid "" +"When on, angles are displayed with 0 at north, 0 to 360 range, positive " +"clockwise; otherwise with 0 at east, -180 to 180 range, positive " +"counterclockwise" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1026 +msgid "Zoom in/out by:" +msgstr "Forstørr inn/ut:" + +#: ../../po/../src/dialogs/display-settings.cpp:1027 +msgid "" +"Zoom tool click, +/- keys, and middle click zoom in and out by this " +"multiplier" +msgstr "" +"Forstørringsverktøyet, «+» og «-»-tastane, samt forstørring med midtknappen " +"forstørrer sÃ¥ mykje." + +#: ../../po/../src/dialogs/display-settings.cpp:1028 +#: ../../po/../src/helper/units.cpp:44 +msgid "%" +msgstr " %" + +#. Tools +#: ../../po/../src/dialogs/display-settings.cpp:1037 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:58 +msgid "Tools" +msgstr "Verktøy" + +#: ../../po/../src/dialogs/display-settings.cpp:1045 +msgid "Selector" +msgstr "Objektveljar" + +#: ../../po/../src/dialogs/display-settings.cpp:1056 +msgid "Node" +msgstr "Node" + +#: ../../po/../src/dialogs/display-settings.cpp:1064 +#: ../../po/../src/verbs.cpp:2073 +#: ../../po/../src/widgets/desktop-widget.cpp:277 +msgid "Zoom" +msgstr "Forstørr" + +#. The 4 shape tools +#: ../../po/../src/dialogs/display-settings.cpp:1071 +msgid "Shapes" +msgstr "Figurar" + +#: ../../po/../src/dialogs/display-settings.cpp:1079 +#: ../../po/../src/verbs.cpp:2055 +msgid "Rectangle" +msgstr "Rektangel" + +#: ../../po/../src/dialogs/display-settings.cpp:1085 +#: ../../po/../src/verbs.cpp:2057 +msgid "Ellipse" +msgstr "Ellipse" + +#: ../../po/../src/dialogs/display-settings.cpp:1091 +#: ../../po/../src/verbs.cpp:2059 +msgid "Star" +msgstr "Stjerne" + +#: ../../po/../src/dialogs/display-settings.cpp:1097 +#: ../../po/../src/verbs.cpp:2061 +msgid "Spiral" +msgstr "Spiral" + +#: ../../po/../src/dialogs/display-settings.cpp:1111 +#: ../../po/../src/verbs.cpp:2063 +msgid "Pencil" +msgstr "Blyant" + +#: ../../po/../src/dialogs/display-settings.cpp:1114 +msgid "Tolerance:" +msgstr "Følsemd:" + +#: ../../po/../src/dialogs/display-settings.cpp:1115 +msgid "" +"This value affects the amount of smoothing applied to freehand lines; lower " +"values produce more uneven paths with more nodes" +msgstr "" +"Kor glatte handteikna linjer skal gjerast. LÃ¥gare verdiare gjev meir ujamne " +"baner med fleire nodar." + +#: ../../po/../src/dialogs/display-settings.cpp:1131 +#: ../../po/../src/verbs.cpp:2065 +msgid "Pen" +msgstr "Penn" + +#: ../../po/../src/dialogs/display-settings.cpp:1140 +#: ../../po/../src/verbs.cpp:2067 +msgid "Calligraphy" +msgstr "Kalligrafi" + +#: ../../po/../src/dialogs/display-settings.cpp:1147 +#: ../../po/../src/dialogs/text-edit.cpp:353 +#: ../../po/../src/ui/dialog/text-properties.cpp:37 +#: ../../po/../src/verbs.cpp:2069 +msgid "Text" +msgstr "Tekst" + +#: ../../po/../src/dialogs/display-settings.cpp:1157 +#: ../../po/../src/verbs.cpp:2071 +msgid "Gradient" +msgstr "Fargeovergang" + +#: ../../po/../src/dialogs/display-settings.cpp:1164 +#: ../../po/../src/verbs.cpp:2077 +#, fuzzy +msgid "Connector" +msgstr "Opphavsmann" + +#: ../../po/../src/dialogs/display-settings.cpp:1171 +#: ../../po/../src/verbs.cpp:2075 +msgid "Dropper" +msgstr "Fargeplukkar" + +#. Windows +#: ../../po/../src/dialogs/display-settings.cpp:1183 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:59 +msgid "Windows" +msgstr "Vindauge" + +#: ../../po/../src/dialogs/display-settings.cpp:1188 +msgid "Save window geometry" +msgstr "Lagra vindaugeoppsett" + +#: ../../po/../src/dialogs/display-settings.cpp:1189 +msgid "" +"Save the window size and position with each document (only for Inkscape SVG " +"format)" +msgstr "" +"Lagra vindaugestorleik og plassering i dokumenta (berre for Inkscapes SVG-" +"format)." + +#: ../../po/../src/dialogs/display-settings.cpp:1196 +msgid "Dialogs are hidden in taskbar" +msgstr "Ikkje vis dialogvindauge i oppgÃ¥velinja" + +#: ../../po/../src/dialogs/display-settings.cpp:1197 +msgid "Whether dialog windows are to be hidden in the window manager taskbar" +msgstr "" +"Om dialogvindauge skal skjulast frÃ¥ oppgÃ¥velinja i vindaugshandteraren." + +#: ../../po/../src/dialogs/display-settings.cpp:1204 +msgid "Zoom when window is resized" +msgstr "Forstørr ved endring av vindaugestorleik" + +#: ../../po/../src/dialogs/display-settings.cpp:1205 +msgid "" +"Zoom drawing when document window is resized, to keep the same area visible " +"(this is the default which can be changed in any window using the button " +"above the right scrollbar)" +msgstr "" +"Forstørr teikninga ved endring av vindaugestorleiken, slik at same omrÃ¥de er " +"synleg heile tida (dette er standard, og kan endrast med knappen over " +"rullefeltet)." + +#. Clones +#: ../../po/../src/dialogs/display-settings.cpp:1213 +#: ../../po/../src/dialogs/find.cpp:624 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:60 +msgid "Clones" +msgstr "Klonar" + +#: ../../po/../src/dialogs/display-settings.cpp:1217 +msgid "When the original moves, its clones and linked offsets:" +msgstr "Ved flytting av opphavet skal klonane og lenkja forskyvingar:" + +#: ../../po/../src/dialogs/display-settings.cpp:1229 +msgid "Move in parallel" +msgstr "Flyttast parallelt" + +#: ../../po/../src/dialogs/display-settings.cpp:1230 +msgid "Clones are translated by the same vector as their original." +msgstr "Flytt klonar med same vektor som opphavet." + +#: ../../po/../src/dialogs/display-settings.cpp:1237 +msgid "Stay unmoved" +msgstr "StÃ¥ i ro" + +#: ../../po/../src/dialogs/display-settings.cpp:1238 +msgid "Clones preserve their positions when their original is moved." +msgstr "Ikkje flytt klonane nÃ¥r opphavet vert flytta." + +#: ../../po/../src/dialogs/display-settings.cpp:1245 +msgid "Move according to transform" +msgstr "Flyttast etter omforming" + +#: ../../po/../src/dialogs/display-settings.cpp:1246 +msgid "" +"Each clone moves according to the value of its transform= attribute. For " +"example, a rotated clone will move in a different direction than its " +"original." +msgstr "" +"Flytt kvar klon etter innhaldet i «transform»-attributtet. For eksempel vil " +"ein rotert klon flytta i ei anna retning enn opphavet." + +#: ../../po/../src/dialogs/display-settings.cpp:1255 +msgid "When the original is deleted, its clones:" +msgstr "NÃ¥r opphavet vert sletta skal klonane:" + +#: ../../po/../src/dialogs/display-settings.cpp:1267 +msgid "Are unlinked" +msgstr "Koplast laus" + +#: ../../po/../src/dialogs/display-settings.cpp:1267 +msgid "Orphaned clones are converted to regular objects." +msgstr "Gjer klonane om til vanlege objekt." + +#: ../../po/../src/dialogs/display-settings.cpp:1273 +msgid "Are deleted" +msgstr "Slettast" + +#: ../../po/../src/dialogs/display-settings.cpp:1273 +msgid "Orphaned clones are deleted along with their original." +msgstr "Slett bÃ¥de opphavet og klonane." + +#. Transforms +#. TRANSLATORS: Noun, i.e. transformations. +#: ../../po/../src/dialogs/display-settings.cpp:1289 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:61 +msgid "Transforms" +msgstr "Omformingar" + +#: ../../po/../src/dialogs/display-settings.cpp:1292 +msgid "Scale stroke width" +msgstr "Skaler strekbreidd" + +#: ../../po/../src/dialogs/display-settings.cpp:1293 +#: ../../po/../src/widgets/select-toolbar.cpp:568 +msgid "When scaling objects, scale the stroke width by the same proportion" +msgstr "Skaler strekbreidda proporsjonalt med storleiken pÃ¥ objekta." + +#: ../../po/../src/dialogs/display-settings.cpp:1300 +msgid "Scale rounded corners in rectangles" +msgstr "Skaler avrunda hjørne i rektangel" + +#: ../../po/../src/dialogs/display-settings.cpp:1301 +#: ../../po/../src/widgets/select-toolbar.cpp:580 +msgid "When scaling rectangles, scale the radii of rounded corners" +msgstr "Skaler òg radiane pÃ¥ avrunda hjørne ved skalering av rektangel." + +#: ../../po/../src/dialogs/display-settings.cpp:1308 +msgid "Transform gradients" +msgstr "Form om fargeovergangar" + +#: ../../po/../src/dialogs/display-settings.cpp:1309 +#: ../../po/../src/widgets/select-toolbar.cpp:592 +msgid "Transform gradients (in fill or stroke) along with the objects" +msgstr "Form òg om fargeovergangar (i fyll og strek)." + +#: ../../po/../src/dialogs/display-settings.cpp:1316 +msgid "Transform patterns" +msgstr "Form om mønster" + +#: ../../po/../src/dialogs/display-settings.cpp:1317 +#: ../../po/../src/widgets/select-toolbar.cpp:604 +msgid "Transform patterns (in fill or stroke) along with the objects" +msgstr "Form òg om mønster (i fyll og strek)." + +#. TRANSLATORS: How to specify the affine transformation in the SVG file. +#: ../../po/../src/dialogs/display-settings.cpp:1327 +msgid "Store transformation:" +msgstr "Lagra omforming:" + +#: ../../po/../src/dialogs/display-settings.cpp:1338 +msgid "Optimized" +msgstr "Optimert" + +#: ../../po/../src/dialogs/display-settings.cpp:1339 +msgid "" +"If possible, apply transformation to objects without adding a transform= " +"attribute" +msgstr "" +"Bruk om mogleg omformingar pÃ¥ objekt utan Ã¥ leggja til eit «transform»-" +"attributt." + +#: ../../po/../src/dialogs/display-settings.cpp:1346 +msgid "Preserved" +msgstr "Bevart" + +#: ../../po/../src/dialogs/display-settings.cpp:1347 +msgid "Always store transformation as a transform= attribute on objects" +msgstr "Lagra alltid omformingar av objekt som «transform»-attributt." + +#. Selecting +#: ../../po/../src/dialogs/display-settings.cpp:1355 +msgid "Selecting" +msgstr "Utval" + +#: ../../po/../src/dialogs/display-settings.cpp:1357 +msgid "Ctrl+A, Tab, Shift+Tab:" +msgstr "«Ctrl + A», «Tab», «Shift + Tab»:" + +#: ../../po/../src/dialogs/display-settings.cpp:1366 +msgid "Select only within current layer" +msgstr "Berre merk objekt i gjeldande lag" + +#: ../../po/../src/dialogs/display-settings.cpp:1367 +msgid "" +"Uncheck this to make keyboard selection commands work on objects in all " +"layers" +msgstr "" +"Fjern merkinga her om du vil at snøggtastane skal verka pÃ¥ objekt i alle lag." + +#: ../../po/../src/dialogs/display-settings.cpp:1374 +msgid "Ignore hidden objects" +msgstr "Hopp over skjulte objekt" + +#: ../../po/../src/dialogs/display-settings.cpp:1375 +msgid "" +"Uncheck this to be able to select objects that are hidden (either by " +"themselves or by being in a hidden group or layer)" +msgstr "" +"Fjern merkinga her om du vil kunna merkja skjulte objekt (anten Ã¥leine eller " +"som del av ei skjult gruppe eller eit skjult lag)." + +#: ../../po/../src/dialogs/display-settings.cpp:1382 +msgid "Ignore locked objects" +msgstr "Hopp over lÃ¥ste objekt" + +#: ../../po/../src/dialogs/display-settings.cpp:1383 +msgid "" +"Uncheck this to be able to select objects that are locked (either by " +"themselves or by being in a locked group or layer)" +msgstr "" +"Fjern merkinga her om du vil kunna merkja lÃ¥ste objekt (anten Ã¥leine eller " +"som del av ei lÃ¥st gruppe eller eit lÃ¥st lag)." + +#. To be broken into: Display, Save, Export, SVG, Commands +#: ../../po/../src/dialogs/display-settings.cpp:1391 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:62 +msgid "Misc" +msgstr "Ymse" + +#: ../../po/../src/dialogs/display-settings.cpp:1394 +msgid "Default export resolution:" +msgstr "Standard eksportoppløysing:" + +#: ../../po/../src/dialogs/display-settings.cpp:1395 +msgid "Default bitmap resolution (in dots per inch) in the Export dialog" +msgstr "" +"Standardoppløysing for punktbilete (i punkt per tomme) i " +"eksporteringsdialogen." + +#. FIXME: add "Used for new exports; once exported, documents remember this value on per-object basis" when implemented +#: ../../po/../src/dialogs/display-settings.cpp:1396 +#: ../../po/../src/dialogs/export.cpp:442 +msgid "dpi" +msgstr "ppt." + +#. TRANSLATORS: When on, an imported bitmap creates an element; otherwise it is a +#. * rectangle with bitmap fill. +#: ../../po/../src/dialogs/display-settings.cpp:1407 +msgid "Import bitmap as " +msgstr "Importer bilete som -element" + +#: ../../po/../src/dialogs/display-settings.cpp:1408 +msgid "" +"When on, an imported bitmap creates an element; otherwise it is a " +"rectangle with bitmap fill" +msgstr "" +"Viss pÃ¥ vil importert punktbilete leggjast som eigne -element, og " +"elles vil dei leggjast som rektangel med biletfyll." + +#. TRANSLATORS: When on, the print out (currently Postscript) will have +#. * a comment with the each object's label visible, marking the section +#. * of the printing commands that represent the given object. +#: ../../po/../src/dialogs/display-settings.cpp:1418 +msgid "Add label comments to printing output" +msgstr "Legg merkelappmerknader til utskrift" + +#: ../../po/../src/dialogs/display-settings.cpp:1419 +msgid "" +"When on, a comment will be added to the raw print output, marking the " +"rendered output for an object with its label" +msgstr "" +"Legg ein merknad til rÃ¥utskriftsdataa som markerer teiknekoden for eit " +"objekt med merkelappen til objektet." + +#. TRANSLATORS: When on, enable the effects menu, default is off +#: ../../po/../src/dialogs/display-settings.cpp:1427 +msgid "Enable script effects (requires restart) - EXPERIMENTAL" +msgstr "Bruk skripteffektar (krev omstart) – EKSPERIMENTELL" + +#: ../../po/../src/dialogs/display-settings.cpp:1428 +msgid "" +"When on, the effects menu is enabled, allowing external effect scripts to be " +"called, requires restart before effective - EXPERIMENTAL" +msgstr "" +"Vis effektmenyen, som gjer det mogleg Ã¥ køyra eksterne skript. Obs: " +"Funksjonen er EKSPERIMENTELL og krev omstart." + +#. TRANSLATORS: The maximum length of the Open Recent list in the File menu. +#: ../../po/../src/dialogs/display-settings.cpp:1436 +msgid "Max recent documents:" +msgstr "Største tal pÃ¥ nyleg brukte dokument:" + +#: ../../po/../src/dialogs/display-settings.cpp:1437 +msgid "The maximum length of the Open Recent list in the File menu" +msgstr "Den største lengda «Nyleg brukt»-menyen kan ha." + +#: ../../po/../src/dialogs/display-settings.cpp:1447 +msgid "Simplification threshold:" +msgstr "Forenklingsterskel:" + +#: ../../po/../src/dialogs/display-settings.cpp:1448 +msgid "" +"How strong is the Simplify command by default. If you invoke this command " +"several times in quick succession, it will act more and more aggressively; " +"invoking it again after a pause restores the default threshold." +msgstr "" +"Kor sterk «Forenkla»-kommandoen skal vera som standard. Viss du køyrer " +"kommandoen fleire gongar raskt etter kvarandre, vil han verka meir og meir " +"aggressiv. Men viss du ventar litt med Ã¥ køyra han, vil han gÃ¥ tilbake til " +"denne forenklingsterskelen." + +#: ../../po/../src/dialogs/display-settings.cpp:1469 +msgid "Oversample bitmaps:" +msgstr "Overskaler punktbilete:" + +#: ../../po/../src/dialogs/display-settings.cpp:1488 +msgid "2x2" +msgstr "2 × 2" + +#: ../../po/../src/dialogs/display-settings.cpp:1494 +msgid "4x4" +msgstr "4 × 4" + +#: ../../po/../src/dialogs/display-settings.cpp:1500 +msgid "8x8" +msgstr "8 × 8" + +#: ../../po/../src/dialogs/display-settings.cpp:1506 +msgid "16x16" +msgstr "16 × 16" + +#. "view_icon_preview" +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2143 +msgid "_Page" +msgstr "_Side" + +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2147 +msgid "_Drawing" +msgstr "_Teikning" + +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2149 +msgid "_Selection" +msgstr "_Utval" + +#: ../../po/../src/dialogs/export.cpp:133 +msgid "_Custom" +msgstr "_Brukarvalt" + +#: ../../po/../src/dialogs/export.cpp:254 +msgid "Export area" +msgstr "EksporteringsomrÃ¥de" + +#: ../../po/../src/dialogs/export.cpp:300 +msgid "_x0:" +msgstr "_x0:" + +#: ../../po/../src/dialogs/export.cpp:305 +msgid "x_1:" +msgstr "x_1:" + +#: ../../po/../src/dialogs/export.cpp:316 +msgid "_y0:" +msgstr "_y0:" + +#: ../../po/../src/dialogs/export.cpp:321 +msgid "y_1:" +msgstr "y_1:" + +#: ../../po/../src/dialogs/export.cpp:406 +msgid "Bitmap size" +msgstr "Storleik pÃ¥ punktbilete" + +#: ../../po/../src/dialogs/export.cpp:416 +msgid "_Width:" +msgstr "_Breidd:" + +#: ../../po/../src/dialogs/export.cpp:416 +#: ../../po/../src/dialogs/export.cpp:431 +msgid "pixels at" +msgstr "pikslar ved" + +#: ../../po/../src/dialogs/export.cpp:426 +msgid "dp_i" +msgstr "_ppt." + +#: ../../po/../src/dialogs/export.cpp:448 +msgid "_Filename" +msgstr "_Filnamn" + +#: ../../po/../src/dialogs/export.cpp:512 +msgid "_Browse..." +msgstr "_Bla gjennom …" + +#: ../../po/../src/dialogs/export.cpp:539 +msgid " _Export " +msgstr " _Eksporter " + +#: ../../po/../src/dialogs/export.cpp:541 +msgid "Export the bitmap file with these settings" +msgstr "Eksporter til punktbilete med desse innstillingane." + +#: ../../po/../src/dialogs/export.cpp:968 +msgid "You have to enter a filename" +msgstr "Du mÃ¥ skriva inn eit filnamn." + +#: ../../po/../src/dialogs/export.cpp:973 +msgid "The chosen area to be exported is invalid" +msgstr "EksporteringsomrÃ¥det er ugyldig." + +#: ../../po/../src/dialogs/export.cpp:982 +#, c-format +msgid "Directory %s does not exist or is not a directory.\n" +msgstr "Mappa «%s» finst ikkje, eller er ikkje ei mappe.\n" + +#: ../../po/../src/dialogs/export.cpp:998 +msgid "Export in progress" +msgstr "Eksporterer" + +#: ../../po/../src/dialogs/export.cpp:1004 +#, c-format +msgid "Exporting %s (%d x %d)" +msgstr "Eksporterer %s (%d × %d)" + +#: ../../po/../src/dialogs/export.cpp:1031 +#, c-format +msgid "Could not export to filename %s.\n" +msgstr "Klarte ikkje eksportera til fila «%s».\n" + +#: ../../po/../src/dialogs/export.cpp:1137 +msgid "Select a filename for exporting" +msgstr "Vel filnamn for eksportering" + +#: ../../po/../src/dialogs/filedialog.cpp:367 +msgid "No preview" +msgstr "Inga førehandsvising" + +#: ../../po/../src/dialogs/filedialog.cpp:468 +msgid "too large for preview" +msgstr "for stor for førehandsvising" + +#: ../../po/../src/dialogs/filedialog.cpp:762 +#: ../../po/../src/dialogs/filedialog.cpp:763 +msgid "All Images" +msgstr "Alle bilete" + +#: ../../po/../src/dialogs/filedialog.cpp:767 +#: ../../po/../src/dialogs/filedialog.cpp:768 +msgid "All Files" +msgstr "Alle filer" + +#: ../../po/../src/dialogs/filedialog.cpp:774 +#: ../../po/../src/dialogs/filedialog.cpp:775 +msgid "All Inkscape Files" +msgstr "Alle Inkscape-filer" + +#: ../../po/../src/dialogs/filedialog.cpp:1176 +msgid "Guess from extension" +msgstr "Gjett frÃ¥ etternamn" + +#. ###### Add the file types menu +#. createFilterMenu(); +#. ###### Do we want the .xxx extension automatically added? +#: ../../po/../src/dialogs/filedialog.cpp:1261 +msgid "Append filename extension automatically" +msgstr "Legg automatisk til rett filetternamn" + +#. TRANSLATORS: "%s" is replaced with "exact" or "partial" when this string is displayed +#: ../../po/../src/dialogs/find.cpp:378 +#, c-format +msgid "%d object found (out of %d), %s match." +msgid_plural "%d objects found (out of %d), %s match." +msgstr[0] "Fann %d objekt (av %d), med %s samsvar." +msgstr[1] "Fann %d objekt (av %d), med %s samsvar." + +#: ../../po/../src/dialogs/find.cpp:381 +msgid "exact" +msgstr "nøyaktig" + +#: ../../po/../src/dialogs/find.cpp:381 +msgid "partial" +msgstr "delvis" + +#: ../../po/../src/dialogs/find.cpp:388 +msgid "No objects found" +msgstr "Fann ikkje noko objekt." + +#: ../../po/../src/dialogs/find.cpp:546 +msgid "T_ype: " +msgstr "T_ype: " + +#: ../../po/../src/dialogs/find.cpp:553 +msgid "Search in all object types" +msgstr "Søk etter alle objekttypar." + +#: ../../po/../src/dialogs/find.cpp:553 +msgid "All types" +msgstr "Alle typar" + +#: ../../po/../src/dialogs/find.cpp:564 +msgid "Search all shapes" +msgstr "Søk etter alle figurar" + +#: ../../po/../src/dialogs/find.cpp:564 +msgid "All shapes" +msgstr "Alle figurar" + +#: ../../po/../src/dialogs/find.cpp:581 +msgid "Search rectangles" +msgstr "Søk etter rektangel" + +#: ../../po/../src/dialogs/find.cpp:581 +msgid "Rectangles" +msgstr "Rektangel" + +#: ../../po/../src/dialogs/find.cpp:586 +msgid "Search ellipses, arcs, circles" +msgstr "Søk etter ellipsar, bogar og sirklar" + +#: ../../po/../src/dialogs/find.cpp:586 +msgid "Ellipses" +msgstr "Ellipsar" + +#: ../../po/../src/dialogs/find.cpp:591 +msgid "Search stars and polygons" +msgstr "Søk etter stjerner og mangekantar" + +#: ../../po/../src/dialogs/find.cpp:591 +msgid "Stars" +msgstr "Stjerner" + +#: ../../po/../src/dialogs/find.cpp:596 +msgid "Search spirals" +msgstr "Søk etter spiralar" + +#: ../../po/../src/dialogs/find.cpp:596 +msgid "Spirals" +msgstr "Spiralar" + +#. TRANSLATORS: polyline is a set of connected straight line segments +#. http://www.w3.org/TR/SVG11/shapes.html#PolylineElement +#: ../../po/../src/dialogs/find.cpp:609 +msgid "Search paths, lines, polylines" +msgstr "Søk etter baner, linjer og fleirlinjer" + +#: ../../po/../src/dialogs/find.cpp:609 +msgid "Paths" +msgstr "Baner" + +#: ../../po/../src/dialogs/find.cpp:614 +msgid "Search text objects" +msgstr "Søk etter tekstobjekt" + +#: ../../po/../src/dialogs/find.cpp:614 +msgid "Texts" +msgstr "Tekstar" + +#: ../../po/../src/dialogs/find.cpp:619 +msgid "Search groups" +msgstr "Søk etter grupper" + +#: ../../po/../src/dialogs/find.cpp:619 +msgid "Groups" +msgstr "Grupper" + +#: ../../po/../src/dialogs/find.cpp:624 +msgid "Search clones" +msgstr "Søk etter klonar" + +#: ../../po/../src/dialogs/find.cpp:629 +msgid "Search images" +msgstr "Søk etter bilete" + +#: ../../po/../src/dialogs/find.cpp:629 +msgid "Images" +msgstr "Bilete" + +#: ../../po/../src/dialogs/find.cpp:634 +msgid "Search offset objects" +msgstr "Søk etter forskyvde objekt" + +#: ../../po/../src/dialogs/find.cpp:634 +msgid "Offsets" +msgstr "Forskyving" + +#: ../../po/../src/dialogs/find.cpp:694 +msgid "_Text: " +msgstr "_Tekst: " + +#: ../../po/../src/dialogs/find.cpp:694 +msgid "Find objects by their text content (exact or partial match)" +msgstr "" +"Søk etter objekt ved hjelp av tekstinnhaldet (nøyaktig eller delvis samsvar)." + +#: ../../po/../src/dialogs/find.cpp:695 +msgid "_ID: " +msgstr "_ID: " + +#: ../../po/../src/dialogs/find.cpp:695 +msgid "Find objects by the value of the id attribute (exact or partial match)" +msgstr "" +"Søk etter objekt ved hjelp av ID-verdiane (nøyaktig eller delvis samsvar)." + +#: ../../po/../src/dialogs/find.cpp:696 +msgid "_Style: " +msgstr "_Stil: " + +#: ../../po/../src/dialogs/find.cpp:696 +msgid "" +"Find objects by the value of the style attribute (exact or partial match)" +msgstr "" +"Søk etter objekt basert pÃ¥ verdien til «style»-attributtet (nøyaktig eller " +"delvis samsvar)." + +#: ../../po/../src/dialogs/find.cpp:697 +msgid "_Attribute: " +msgstr "_Attributt: " + +#: ../../po/../src/dialogs/find.cpp:697 +msgid "Find objects by the name of an attribute (exact or partial match)" +msgstr "" +"Søk etter objekt basert pÃ¥ namnet pÃ¥ eit attributt (nøyaktig eller delvis " +"samsvar)." + +#: ../../po/../src/dialogs/find.cpp:711 +msgid "Search in s_election" +msgstr "Søk i _utval" + +#: ../../po/../src/dialogs/find.cpp:715 +msgid "Limit search to the current selection" +msgstr "Avgrens søket til gjeldande utval." + +#: ../../po/../src/dialogs/find.cpp:720 +msgid "Search in current _layer" +msgstr "Søk i gjeldande _laget" + +#: ../../po/../src/dialogs/find.cpp:724 +msgid "Limit search to the current layer" +msgstr "Avgrens søket til gjeldande lag." + +#: ../../po/../src/dialogs/find.cpp:729 +msgid "Include _hidden" +msgstr "Ta med _skjulte" + +#: ../../po/../src/dialogs/find.cpp:733 +msgid "Include hidden objects in search" +msgstr "Ta med skjulte objekt i søket." + +#: ../../po/../src/dialogs/find.cpp:738 +msgid "Include l_ocked" +msgstr "Ta med lÃ¥_ste" + +#: ../../po/../src/dialogs/find.cpp:742 +msgid "Include locked objects in search" +msgstr "Ta med lÃ¥ste objekt i søket." + +#: ../../po/../src/dialogs/find.cpp:753 +msgid "Clear values" +msgstr "Tøm felta." + +#: ../../po/../src/dialogs/find.cpp:754 +msgid "_Find" +msgstr "_Finn" + +#: ../../po/../src/dialogs/find.cpp:754 +msgid "Select objects matching all of the fields you filled in" +msgstr "Merk alle objekta som samsvarer med dei utfylte felta." + +#: ../../po/../src/dialogs/iconpreview.cpp:145 +#, c-format +msgid "%d x %d" +msgstr "" + +#: ../../po/../src/dialogs/iconpreview.cpp:193 +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:857 +#: ../../po/../src/widgets/desktop-widget.cpp:1069 +msgid "Selection" +msgstr "Utval" + +#: ../../po/../src/dialogs/iconpreview.cpp:195 +#, fuzzy +msgid "Selection only or whole document" +msgstr "Berre merk objekt i gjeldande lag" + +#: ../../po/../src/dialogs/iconpreview.cpp:203 +msgid "Refresh the icons" +msgstr "Oppdater ikona" + +#. Create the label for the object id +#: ../../po/../src/dialogs/item-properties.cpp:126 +#: ../../po/../src/dialogs/item-properties.cpp:327 +#: ../../po/../src/dialogs/item-properties.cpp:396 +#: ../../po/../src/dialogs/item-properties.cpp:403 +msgid "_Id" +msgstr "_ID" + +#: ../../po/../src/dialogs/item-properties.cpp:135 +msgid "" +"The id= attribute (only letters, digits, and the characters .-_: allowed)" +msgstr "" +"Attributtet «id=» (berre bokstavane a til z, siffer og teikna .-_: er " +"lovlege Ã¥ bruka)." + +#. Button for setting the object's id, label, title and description. +#: ../../po/../src/dialogs/item-properties.cpp:149 +msgid "_Set" +msgstr "_Set" + +#. Create the label for the object label +#: ../../po/../src/dialogs/item-properties.cpp:158 +msgid "_Label" +msgstr "_Merkelapp" + +#: ../../po/../src/dialogs/item-properties.cpp:167 +msgid "A freeform label for the object" +msgstr "Ein fri merkelapp for objektet." + +#. Create the label for the object title +#: ../../po/../src/dialogs/item-properties.cpp:179 +#: ../../po/../src/dialogs/rdf.cpp:243 +msgid "Title" +msgstr "Tittel" + +#. Create the frame for the object description +#: ../../po/../src/dialogs/item-properties.cpp:196 +#: ../../po/../src/dialogs/rdf.cpp:287 +msgid "Description" +msgstr "Skildring" + +#. Hide +#: ../../po/../src/dialogs/item-properties.cpp:223 +msgid "_Hide" +msgstr "_Skjul" + +#: ../../po/../src/dialogs/item-properties.cpp:224 +msgid "Check to make the object invisible" +msgstr "Merk av for Ã¥ gjera objektet usynleg." + +#. Lock +#. TRANSLATORS: "Lock" is a verb here +#: ../../po/../src/dialogs/item-properties.cpp:233 +msgid "L_ock" +msgstr "_LÃ¥s" + +#: ../../po/../src/dialogs/item-properties.cpp:234 +msgid "Check to make the object insensitive (not selectable by mouse)" +msgstr "Merk av for Ã¥ gjera objektet urørbar (ikkje merkbar med musa)." + +#: ../../po/../src/dialogs/item-properties.cpp:310 +#: ../../po/../src/dialogs/item-properties.cpp:317 +msgid "Ref" +msgstr "Ref" + +#: ../../po/../src/dialogs/item-properties.cpp:398 +msgid "Id invalid! " +msgstr "Ugyldig ID." + +#: ../../po/../src/dialogs/item-properties.cpp:400 +msgid "Id exists! " +msgstr "ID-en finst allereie." + +#: ../../po/../src/dialogs/layer-properties.cpp:50 +msgid "Layer name:" +msgstr "Lagnamn:" + +#: ../../po/../src/dialogs/layer-properties.cpp:133 +msgid "Rename Layer" +msgstr "Endra namn pÃ¥ lag" + +#: ../../po/../src/dialogs/layer-properties.cpp:136 +msgid "_Rename" +msgstr "_Endra namn" + +#. TRANSLATORS: This means "The layer has been renamed" +#: ../../po/../src/dialogs/layer-properties.cpp:147 +msgid "Renamed layer" +msgstr "Endra namn pÃ¥ lag" + +#: ../../po/../src/dialogs/layer-properties.cpp:151 +msgid "Add Layer" +msgstr "Legg til lag" + +#: ../../po/../src/dialogs/layer-properties.cpp:153 +msgid "_Add" +msgstr "_Legg til" + +#: ../../po/../src/dialogs/layer-properties.cpp:167 +msgid "New layer created." +msgstr "Laga nytt lag." + +#: ../../po/../src/dialogs/object-attributes.cpp:34 +msgid "Href:" +msgstr "Href:" + +#: ../../po/../src/dialogs/object-attributes.cpp:35 +msgid "Target:" +msgstr "MÃ¥l:" + +#: ../../po/../src/dialogs/object-attributes.cpp:36 +msgid "Type:" +msgstr "Type:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkRoleAttribute +#. Identifies the type of the related resource with an absolute URI +#: ../../po/../src/dialogs/object-attributes.cpp:39 +msgid "Role:" +msgstr "Rolle:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkArcRoleAttribute +#. For situations where the nature/role alone isn't enough, this offers an additional URI defining the purpose of the link. +#: ../../po/../src/dialogs/object-attributes.cpp:42 +msgid "Arcrole:" +msgstr "Bogerolle:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkTitleAttribute +#: ../../po/../src/dialogs/object-attributes.cpp:44 +msgid "Title:" +msgstr "Tittel:" + +#: ../../po/../src/dialogs/object-attributes.cpp:45 +msgid "Show:" +msgstr "Vis:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkActuateAttribute +#: ../../po/../src/dialogs/object-attributes.cpp:47 +msgid "Actuate:" +msgstr "Utløys:" + +#: ../../po/../src/dialogs/object-attributes.cpp:52 +msgid "URL:" +msgstr "URI:" + +#: ../../po/../src/dialogs/object-attributes.cpp:53 +msgid "X:" +msgstr "X:" + +#: ../../po/../src/dialogs/object-attributes.cpp:54 +msgid "Y:" +msgstr "Y:" + +#: ../../po/../src/dialogs/object-attributes.cpp:98 +#, c-format +msgid "%s attributes" +msgstr "%s attributt" + +#: ../../po/../src/dialogs/object-properties.cpp:158 +msgid "_Fill" +msgstr "_Fyll" + +#: ../../po/../src/dialogs/object-properties.cpp:165 +msgid "Stroke _paint" +msgstr "Strek_farge" + +#: ../../po/../src/dialogs/object-properties.cpp:172 +msgid "Stroke st_yle" +msgstr "Streks_til" + +#: ../../po/../src/dialogs/object-properties.cpp:183 +msgid "Master _opacity" +msgstr "Hovud_gjennomsikt" + +#: ../../po/../src/dialogs/rdf.cpp:244 +msgid "Name by which this document is formally known." +msgstr "Namnet som dokumentet formelt er kjend under." + +#: ../../po/../src/dialogs/rdf.cpp:246 +msgid "Date" +msgstr "Dato" + +#: ../../po/../src/dialogs/rdf.cpp:247 +msgid "Date associated with the creation of this document (YYYY-MM-DD)." +msgstr "" +"Datoen knytta til tidspunktet dokumentet vart oppretta (format: ÅÅÅÅ-MM-DD)." + +#: ../../po/../src/dialogs/rdf.cpp:249 +msgid "Format" +msgstr "Format" + +#: ../../po/../src/dialogs/rdf.cpp:250 +msgid "The physical or digital manifestation of this document (MIME type)." +msgstr "Det fysiske eller digitale formatet til dokumentet (MIME-type)." + +#: ../../po/../src/dialogs/rdf.cpp:252 +msgid "Type" +msgstr "Type" + +#: ../../po/../src/dialogs/rdf.cpp:253 +msgid "Type of document (DCMI Type)." +msgstr "Dokumenttype (DCMI-type)." + +#: ../../po/../src/dialogs/rdf.cpp:256 +msgid "Creator" +msgstr "Opphavsmann" + +#: ../../po/../src/dialogs/rdf.cpp:257 +msgid "" +"Name of entity primarily responsible for making the content of this document." +msgstr "Namnet pÃ¥ eininga som er hovudansvarleg for utforminga av dokumentet." + +#: ../../po/../src/dialogs/rdf.cpp:259 +msgid "Rights" +msgstr "Rettar" + +#: ../../po/../src/dialogs/rdf.cpp:260 +msgid "" +"Name of entity with rights to the Intellectual Property of this document." +msgstr "Namnet pÃ¥ eininga med rettar til dokumentet." + +#: ../../po/../src/dialogs/rdf.cpp:262 +msgid "Publisher" +msgstr "Utgjevar" + +#: ../../po/../src/dialogs/rdf.cpp:263 +msgid "Name of entity responsible for making this document available." +msgstr "" +"Namnet pÃ¥ eininga som er ansvarleg for Ã¥ ha gjort dokumentet tilgjengeleg." + +#: ../../po/../src/dialogs/rdf.cpp:266 +msgid "Identifier" +msgstr "Identifikator" + +#: ../../po/../src/dialogs/rdf.cpp:267 +msgid "Unique URI to reference this document." +msgstr "Ein eintydig URI til dokumentet." + +#: ../../po/../src/dialogs/rdf.cpp:269 +msgid "Source" +msgstr "Kjelde" + +#: ../../po/../src/dialogs/rdf.cpp:270 +msgid "Unique URI to reference the source of this document." +msgstr "Ein eintydig URI til kjelda til dokumentet." + +#: ../../po/../src/dialogs/rdf.cpp:272 +msgid "Relation" +msgstr "Relasjon" + +#: ../../po/../src/dialogs/rdf.cpp:273 +msgid "Unique URI to a related document." +msgstr "Ein eintydig URI til eit nærskyld dokument." + +#: ../../po/../src/dialogs/rdf.cpp:275 +msgid "Language" +msgstr "SprÃ¥k" + +#: ../../po/../src/dialogs/rdf.cpp:276 +msgid "" +"Two-letter language tag with optional subtags for the language of this " +"document. (e.g. 'en-GB')" +msgstr "" +"Ein RFC 3066-basert sprÃ¥kkode, eksempelvis «nn» for nynorsk, «nb» for bokmÃ¥l " +"og «en-GB» for britisk." + +#: ../../po/../src/dialogs/rdf.cpp:278 +msgid "Keywords" +msgstr "Stikkord" + +#: ../../po/../src/dialogs/rdf.cpp:279 +msgid "" +"The topic of this document as comma-separated key words, phrases, or " +"classifications." +msgstr "" +"Emnet til dokumentet – ei kommadelt liste med stikkord og " +"klassifikasjonskodar." + +#. TRANSLATORS: "Coverage": the spatial or temporal characteristics of the content. +#. For info, see Appendix D of http://www.w3.org/TR/1998/WD-rdf-schema-19980409/ +#: ../../po/../src/dialogs/rdf.cpp:283 +msgid "Coverage" +msgstr "Omfang" + +#: ../../po/../src/dialogs/rdf.cpp:284 +msgid "Extent or scope of this document." +msgstr "Omfanget til dokumentet." + +#: ../../po/../src/dialogs/rdf.cpp:288 +msgid "A short account of the content of this document." +msgstr "Ei kort beskriving av innhaldet i dokumentet." + +#. FIXME: need to handle 1 agent per line of input +#: ../../po/../src/dialogs/rdf.cpp:292 +msgid "Contributors" +msgstr "Bidragsytarar" + +#: ../../po/../src/dialogs/rdf.cpp:293 +msgid "" +"Names of entities responsible for making contributions to the content of " +"this document." +msgstr "Namnet pÃ¥ einingar som har bidratt med Ã¥ utvikla dokumentet." + +#. TRANSLATORS: URL to a page that defines the license for the document +#: ../../po/../src/dialogs/rdf.cpp:297 +msgid "URI" +msgstr "URI" + +#. TRANSLATORS: this is where you put a URL to a page that defines the license +#: ../../po/../src/dialogs/rdf.cpp:299 +msgid "URI to this document's license's namespace definition." +msgstr "Ein URI til namneromdefinisjonen til lisensvilkÃ¥ra til dokumentet." + +#. TRANSLATORS: fragment of XML representing the license of the document +#: ../../po/../src/dialogs/rdf.cpp:303 +msgid "Fragment" +msgstr "Fragment" + +#: ../../po/../src/dialogs/rdf.cpp:304 +msgid "XML fragment for the RDF 'License' section." +msgstr "XML-fragment for den RDF-baserte «License»-blokka." + +#: ../../po/../src/dialogs/stroke-style.cpp:774 +#: ../../po/../src/widgets/gradient-vector.cpp:263 +#: ../../po/../src/widgets/paint-selector.cpp:751 +msgid "No document selected" +msgstr "Ingen dokument valt" + +#: ../../po/../src/dialogs/stroke-style.cpp:992 +msgid "Stroke width" +msgstr "Strekbreidd" + +#. Join type +#. TRANSLATORS: The line join style specifies the shape to be used at the +#. corners of paths. It can be "miter", "round" or "bevel". +#: ../../po/../src/dialogs/stroke-style.cpp:1015 +msgid "Join:" +msgstr "Hjørne:" + +#. TRANSLATORS: Miter join: joining lines with a sharp (pointed) corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1027 +msgid "Miter join" +msgstr "Spist hjørne" + +#. TRANSLATORS: Round join: joining lines with a rounded corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1035 +msgid "Round join" +msgstr "Rundt hjørne" + +#. TRANSLATORS: Bevel join: joining lines with a blunted (flattened) corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1043 +msgid "Bevel join" +msgstr "SkrÃ¥tt hjørne" + +#. Miterlimit +#. TRANSLATORS: Miter limit: only for "miter join", this limits the length +#. of the sharp "spike" when the lines connect at too sharp an angle. +#. When two line segments meet at a sharp angle, a miter join results in a +#. spike that extends well beyond the connection point. The purpose of the +#. miter limit is to cut off such spikes (i.e. convert them into bevels) +#. when they become too long. +#: ../../po/../src/dialogs/stroke-style.cpp:1054 +msgid "Miter limit:" +msgstr "Største spisslengd:" + +#: ../../po/../src/dialogs/stroke-style.cpp:1062 +msgid "Maximum length of the miter (in units of stroke width)" +msgstr "Største lengd ein spiss kan ha (i same einingar om strekbreidda)" + +#. Cap type +#. TRANSLATORS: cap type specifies the shape for the ends of lines +#: ../../po/../src/dialogs/stroke-style.cpp:1075 +msgid "Cap:" +msgstr "Ende:" + +#. TRANSLATORS: Butt cap: the line shape does not extend beyond the end point +#. of the line; the ends of the line are square +#: ../../po/../src/dialogs/stroke-style.cpp:1086 +msgid "Butt cap" +msgstr "Kort ende" + +#. TRANSLATORS: Round cap: the line shape extends beyond the end point of the +#. line; the ends of the line are rounded +#: ../../po/../src/dialogs/stroke-style.cpp:1093 +msgid "Round cap" +msgstr "Avrunda ende" + +#. TRANSLATORS: Square cap: the line shape extends beyond the end point of the +#. line; the ends of the line are square +#: ../../po/../src/dialogs/stroke-style.cpp:1100 +msgid "Square cap" +msgstr "Firkanta ende" + +#. Dash +#: ../../po/../src/dialogs/stroke-style.cpp:1106 +msgid "Dashes:" +msgstr "Stipla linje:" + +#. TRANSLATORS: Path markers are an SVG feature that allows you to attach arbitrary shapes +#. (arrowheads, bullets, faces, whatever) to the start, end, or middle nodes of a path. +#: ../../po/../src/dialogs/stroke-style.cpp:1127 +msgid "Start Markers:" +msgstr "Startmerke:" + +#: ../../po/../src/dialogs/stroke-style.cpp:1137 +msgid "Mid Markers:" +msgstr "Midtmerke:" + +#: ../../po/../src/dialogs/stroke-style.cpp:1148 +msgid "End Markers:" +msgstr "Sluttmerke:" + +#: ../../po/../src/dialogs/swatches.cpp:424 +#, c-format +msgid "Palettes directory (%s) is unavailable." +msgstr "Fargesamlingsmappa («%s») er ikkje tilgjengeleg." + +#. TODO: Insert widgets +#: ../../po/../src/dialogs/text-edit.cpp:199 +#: ../../po/../src/ui/dialog/text-properties.cpp:36 +msgid "Font" +msgstr "Skrift" + +#: ../../po/../src/dialogs/text-edit.cpp:216 +msgid "Layout" +msgstr "Oppsett" + +#: ../../po/../src/dialogs/text-edit.cpp:229 +msgid "Align lines left" +msgstr "Venstrejuster linjer" + +#. TRANSLATORS: `Center' here is a verb. +#: ../../po/../src/dialogs/text-edit.cpp:243 +msgid "Center lines" +msgstr "Midtlinjer" + +#: ../../po/../src/dialogs/text-edit.cpp:256 +msgid "Align lines right" +msgstr "Høgrejuster linjer" + +#: ../../po/../src/dialogs/text-edit.cpp:278 +msgid "Horizontal text" +msgstr "Vassrett tekst" + +#: ../../po/../src/dialogs/text-edit.cpp:292 +msgid "Vertical text" +msgstr "Loddrett tekst" + +#: ../../po/../src/dialogs/text-edit.cpp:307 +msgid "Line spacing:" +msgstr "Linjeavstand:" + +#: ../../po/../src/dialogs/text-edit.cpp:400 +msgid "Set as default" +msgstr "Set som standard" + +#: ../../po/../src/dialogs/tiledialog.cpp:603 +msgid "Rows:" +msgstr "Rader:" + +#: ../../po/../src/dialogs/tiledialog.cpp:613 +msgid "Number of rows" +msgstr "Talet pÃ¥ rader." + +#: ../../po/../src/dialogs/tiledialog.cpp:617 +msgid "Equal height" +msgstr "Lik høgd" + +#: ../../po/../src/dialogs/tiledialog.cpp:627 +msgid "If not set, each row has the height of the tallest object in it" +msgstr "" +"Viss ikkje vald, vil kvar rad har høgda til det høgaste objektet i ho " +"inneheld." + +#. #### Radio buttons to control vertical alignment #### +#. #### Radio buttons to control horizontal alignment #### +#: ../../po/../src/dialogs/tiledialog.cpp:637 +#: ../../po/../src/dialogs/tiledialog.cpp:708 +msgid "Align:" +msgstr "Juster:" + +#: ../../po/../src/dialogs/tiledialog.cpp:672 +msgid " X " +msgstr " × " + +#. #### Number of columns #### +#: ../../po/../src/dialogs/tiledialog.cpp:678 +msgid "Columns:" +msgstr "Kolonnar:" + +#: ../../po/../src/dialogs/tiledialog.cpp:688 +msgid "Number of columns" +msgstr "Talet pÃ¥ kolonnar" + +#: ../../po/../src/dialogs/tiledialog.cpp:692 +msgid "Equal width" +msgstr "Lik breidd" + +#: ../../po/../src/dialogs/tiledialog.cpp:701 +msgid "If not set, each column has the width of the widest object in it" +msgstr "" +"Viss ikkje vald, vil kvar kolonne har breidda til det høgaste objektet i han " +"inneheld." + +#. #### Radio buttons to control spacing manually or to fit selection bbox #### +#: ../../po/../src/dialogs/tiledialog.cpp:746 +msgid "Fit into selection box" +msgstr "Tilpass til utvalsboks" + +#: ../../po/../src/dialogs/tiledialog.cpp:753 +msgid "Set spacing:" +msgstr "Vel mellomrom:" + +#. #### Y Padding #### +#: ../../po/../src/dialogs/tiledialog.cpp:777 +msgid "Row spacing: " +msgstr "Radavstand:" + +#: ../../po/../src/dialogs/tiledialog.cpp:786 +msgid "Vertical spacing between rows" +msgstr "Loddrett avstand mellom rader." + +#. #### X padding #### +#: ../../po/../src/dialogs/tiledialog.cpp:795 +msgid "Column spacing:" +msgstr "Kolonneavstand:" + +#: ../../po/../src/dialogs/tiledialog.cpp:804 +msgid "Horizontal spacing between columns" +msgstr "Vassrett avstand mellom kolonnar." + +#: ../../po/../src/dialogs/tiledialog.cpp:818 +#, fuzzy +msgid "Arrange selected objects" +msgstr "Grupper merkte objekt." + +#: ../../po/../src/dialogs/xml-tree.cpp:178 +msgid "Click to select nodes, drag to rearrange." +msgstr "Trykk for Ã¥ merkja nodar, eller dra for flytta." + +#: ../../po/../src/dialogs/xml-tree.cpp:189 +msgid "Click attribute to edit." +msgstr "Trykk pÃ¥ attributt for Ã¥ redigera." + +#: ../../po/../src/dialogs/xml-tree.cpp:193 +#, c-format +msgid "" +"Attribute %s selected. Press Ctrl+Enter when done editing to " +"commit changes." +msgstr "" +"Attributtet %s er valt. Trykk Ctrl + Enter nÃ¥r du er ferdig " +"med endringane." + +#: ../../po/../src/dialogs/xml-tree.cpp:284 +msgid "Drag to reorder nodes" +msgstr "Dra for Ã¥ endra rekkjefølgja pÃ¥ nodane" + +#: ../../po/../src/dialogs/xml-tree.cpp:304 +msgid "New element node" +msgstr "Ny elementnode" + +#: ../../po/../src/dialogs/xml-tree.cpp:326 +msgid "New text node" +msgstr "Ny tekstnode" + +#: ../../po/../src/dialogs/xml-tree.cpp:347 +msgid "Duplicate node" +msgstr "Lag kopi av node" + +#: ../../po/../src/dialogs/xml-tree.cpp:368 +msgid "Delete node" +msgstr "Slett node" + +#: ../../po/../src/dialogs/xml-tree.cpp:384 +msgid "Unindent node" +msgstr "Rykk ut node" + +#: ../../po/../src/dialogs/xml-tree.cpp:399 +msgid "Indent node" +msgstr "Rykk inn node" + +#: ../../po/../src/dialogs/xml-tree.cpp:411 +msgid "Raise node" +msgstr "Hev node" + +#: ../../po/../src/dialogs/xml-tree.cpp:423 +msgid "Lower node" +msgstr "Senk node" + +#: ../../po/../src/dialogs/xml-tree.cpp:468 +msgid "Delete attribute" +msgstr "Slett attributt" + +#. TRANSLATORS: "Attribute" is a noun here +#: ../../po/../src/dialogs/xml-tree.cpp:513 +msgid "Attribute name" +msgstr "Attributtnamn" + +#. TRANSLATORS: "Set" is a verb here +#: ../../po/../src/dialogs/xml-tree.cpp:533 +msgid "Set attribute" +msgstr "Set attributt" + +#. TRANSLATORS: "Set" is a verb here +#: ../../po/../src/dialogs/xml-tree.cpp:535 +msgid "Set" +msgstr "Set" + +#. TRANSLATORS: "Attribute" is a noun here +#: ../../po/../src/dialogs/xml-tree.cpp:558 +msgid "Attribute value" +msgstr "Attributtverdi" + +#: ../../po/../src/dialogs/xml-tree.cpp:1318 +msgid "New element node..." +msgstr "Ny elementnode ..." + +#: ../../po/../src/dialogs/xml-tree.cpp:1339 +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:100 +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:98 +msgid "Cancel" +msgstr "Avbryt" + +#: ../../po/../src/dialogs/xml-tree.cpp:1345 +msgid "Create" +msgstr "Lag" + +#: ../../po/../src/dialogs/xml-tree.cpp:1458 +#, c-format +msgid "" +"Cannot set %s: Another element with value %s already exists!" +msgstr "" +"Kan ikkje setja %s: Det finst allereie eit element med verdien %s." + +#: ../../po/../src/document.cpp:369 +#, c-format +msgid "New document %d" +msgstr "Nytt dokument %d" + +#: ../../po/../src/document.cpp:401 +#, c-format +msgid "Memory document %d" +msgstr "Dokument i minne %d" + +#: ../../po/../src/document.cpp:524 +#, c-format +msgid "Unnamed document %d" +msgstr "Namnlaust dokument %d" + +#. We hit green anchor, closing Green-Blue-Red +#: ../../po/../src/draw-context.cpp:441 +msgid "Path is closed." +msgstr "Bana er lukka." + +#. We hit bot start and end of single curve, closing paths +#: ../../po/../src/draw-context.cpp:456 +msgid "Closing path." +msgstr "Lukkar bane." + +#. alpha of color under cursor, to show in the statusbar +#. locale-sensitive printf is OK, since this goes to the UI, not into SVG +#: ../../po/../src/dropper-context.cpp:354 +#, c-format +msgid " alpha %.3g" +msgstr " alfa %.3g" + +#. where the color is picked, to show in the statusbar +#: ../../po/../src/dropper-context.cpp:356 +#, c-format +msgid ", averaged with radius %d" +msgstr ", med snittradius %d" + +#: ../../po/../src/dropper-context.cpp:356 +msgid " under cursor" +msgstr " under peikar" + +#. message, to show in the statusbar +#: ../../po/../src/dropper-context.cpp:358 +msgid "Release mouse to set color." +msgstr "Slepp museknappen for Ã¥ bruka fargen." + +#: ../../po/../src/dropper-context.cpp:358 +#: ../../po/../src/tools-switch.cpp:207 +msgid "" +"Click to set fill, Shift+click to set stroke; drag to " +"average color in area; with Alt to pick inverse color; Ctrl+C " +"to copy the color under mouse to clipboard" +msgstr "" +"Klikk for Ã¥ velja fyllfarge, og bruk Shift + klikk for Ã¥ velja " +"strekfarge. Klikk og dra for Ã¥ henta gjennomsnittsfargen i eit " +"omrÃ¥de, med Alt for invers farge. Bruk Ctrl + C for Ã¥ kopiera " +"fargen under peikaren til utklippstavla." + +#: ../../po/../src/extension/dependency.cpp:244 +msgid "Dependency::" +msgstr "Avhengnad:" + +#: ../../po/../src/extension/dependency.cpp:245 +msgid " type: " +msgstr " type: " + +#: ../../po/../src/extension/dependency.cpp:246 +msgid " location: " +msgstr " plassering: " + +#: ../../po/../src/extension/dependency.cpp:247 +msgid " string: " +msgstr " tekst: " + +#: ../../po/../src/extension/dependency.cpp:250 +msgid " description: " +msgstr " skildring: " + +#. static int i = 0; +#. std::cout << "Checking module[" << i++ << "]: " << name << std::endl; +#: ../../po/../src/extension/extension.cpp:244 +msgid "" +" This is caused by an improper .inx file for this extension. An improper ." +"inx file could have been caused by a faulty installation of Inkscape." +msgstr "" +" Grunnen er ei ugyldig .inx-fil for denne utvidinga. Ugyldige .inx-filer " +"kan skuldast feil ved installeringa av Inkscape." + +#: ../../po/../src/extension/extension.cpp:247 +msgid "an ID was not defined for it." +msgstr "inkje ID var definert." + +#: ../../po/../src/extension/extension.cpp:251 +msgid "there was no name defined for it." +msgstr "inkje namn var definert." + +#: ../../po/../src/extension/extension.cpp:255 +msgid "the XML description of it got lost." +msgstr "XML-skildringa gjekk tapt." + +#: ../../po/../src/extension/extension.cpp:259 +msgid "no implementation was defined for the extension." +msgstr "det finst ikkje er definert noko implementering av utvidinga." + +#. std::cout << "Failed: " << *(_deps[i]) << std::endl; +#: ../../po/../src/extension/extension.cpp:266 +msgid "a dependency was not met." +msgstr "ein avhengnad ikkje var oppfyld." + +#: ../../po/../src/extension/extension.cpp:286 +msgid "Extension \"" +msgstr "Utvidinga «" + +#: ../../po/../src/extension/extension.cpp:286 +msgid "\" failed to load because " +msgstr "» kunne ikkje opnast fordi " + +#: ../../po/../src/extension/extension.cpp:565 +#, c-format +msgid "Could not create extension error log file '%s'" +msgstr "Klarte ikkje laga feilloggen «%s» for utvidinga." + +#. This is some filler text, needs to change before relase +#: ../../po/../src/extension/error-file.cpp:56 +msgid "" +"One or more extensions failed to load\n" +"\n" +"The failed extensions have been skipped. Inkscape will continue to run " +"normally but those extensions will be unavailable. For details to " +"troubleshoot this problem, please refer to the error log located at: " +msgstr "" +"Feil ved opning av éi eller fleire " +"utvidingar\n" +"\n" +"Desse utvidingane vert derfor ikkje brukt. Inkscape vil fungera normalt, men " +"utvidingane vert ikkje tilgjengelege. SjÃ¥ loggfila for meir informasjon: " + +#. This is some filler text, needs to change before relase +#: ../../po/../src/extension/error-file.cpp:65 +msgid "Show dialog on startup" +msgstr "Vis denne meldinga ved oppstart" + +#: ../../po/../src/extension/implementation/script.cpp:845 +msgid "" +"Inkscape has received an error from the script that it called. The text " +"returned with the error is included below. Inkscape will continue working, " +"but the action you requested has been cancelled." +msgstr "" +"Inkscape har motteke ein feil frÃ¥ eit skript. Feilmeldingsteksten vert vist " +"neanfor. Inkscape vil halda fram Ã¥ køyra, men handlinga du valde er avbroten." + +#: ../../po/../src/extension/implementation/script.cpp:858 +msgid "" +"Inkscape has received additional data from the script executed. The script " +"did not return an error, but this may indicate the results will not be as " +"expected." +msgstr "" +"Inkscape har motteke ekstrainformasjon frÃ¥ eit skript. Det oppstod ikkje ein " +"køyrefeil, men meldinga kan visa at resultatet ikkje vart som forventa." + +#: ../../po/../src/extension/init.cpp:173 +msgid "Null external module directory name. Modules will not be loaded." +msgstr "Inga namn pÃ¥ mappe for eksterne modular. Ingen modular vert lasta." + +#: ../../po/../src/extension/init.cpp:187 +#, c-format +msgid "" +"Modules directory (%s) is unavailable. External modules in that directory " +"will not be loaded." +msgstr "" +"Modulmappa («%s») er ikkje tilgjengeleg. Eksterne modular i denne mappa vert " +"ikkje lasta." + +#: ../../po/../src/extension/internal/gnome.cpp:80 +msgid "Select printer" +msgstr "Vel skrivar" + +#: ../../po/../src/extension/internal/gnome.cpp:131 +msgid "Inkscape: Print Preview" +msgstr "Inkscape: Førehandsvising" + +#: ../../po/../src/extension/internal/grid.cpp:213 +msgid "Line Width" +msgstr "Linjebreidd" + +#: ../../po/../src/extension/internal/grid.cpp:214 +msgid "Horizontal Spacing" +msgstr "Vassrett luft" + +#: ../../po/../src/extension/internal/grid.cpp:215 +msgid "Vertical Spacing" +msgstr "Loddrett luft" + +#: ../../po/../src/extension/internal/grid.cpp:216 +msgid "Horizontal Offset" +msgstr "Vassrett forskyving" + +#: ../../po/../src/extension/internal/grid.cpp:217 +msgid "Vertical Offset" +msgstr "Loddrett forskyving" + +#: ../../po/../src/extension/internal/ps.cpp:123 +msgid "Print Destination" +msgstr "UtskriftsmÃ¥l" + +#. Print properties frame +#: ../../po/../src/extension/internal/ps.cpp:138 +msgid "Print properties" +msgstr "Utskriftseigenskapar" + +#: ../../po/../src/extension/internal/ps.cpp:145 +msgid "Print using PostScript operators" +msgstr "Skriv ut med PostScript-operatorar" + +#: ../../po/../src/extension/internal/ps.cpp:147 +msgid "" +"Use PostScript vector operators. The resulting image is usually smaller in " +"file size and can be arbitrarily scaled, but alpha transparency and patterns " +"will be lost." +msgstr "" +"Bruk PostScript-baserte vektoroperatorar. Fila vert vanlegvis mindre, og kan " +"skalerast fritt, men eventuell gjennomsikt, fargeovergangar og mønster vil " +"gÃ¥ tapt." + +#: ../../po/../src/extension/internal/ps.cpp:152 +msgid "Print as bitmap" +msgstr "Skriv ut som punktbilete" + +#: ../../po/../src/extension/internal/ps.cpp:154 +msgid "" +"Print everything as bitmap. The resulting image is usually larger in file " +"size and cannot be arbitrarily scaled without quality loss, but all objects " +"will be rendered exactly as displayed." +msgstr "" +"Skriv ut alt som punktbilete. Fila vert vanlegvis større, og kan ikkje " +"skalerast utan kvalitetstap, men alle objekta vert sjÃ¥ande nøyaktig ut som " +"pÃ¥ skjermen." + +#: ../../po/../src/extension/internal/ps.cpp:168 +msgid "Preferred resolution (dots per inch) of bitmap" +msgstr "Føretrekt oppløysing (i punkt per tomme) for punktbiletet." + +#: ../../po/../src/extension/internal/ps.cpp:182 +msgid "Resolution:" +msgstr "Oppløysing:" + +#. Print destination frame +#: ../../po/../src/extension/internal/ps.cpp:186 +msgid "Print destination" +msgstr "UtskriftsmÃ¥l" + +#: ../../po/../src/extension/internal/ps.cpp:192 +msgid "" +"Use '> filename' to print to file.\n" +"Use '| prog arg...' to pipe to a program." +msgstr "" +"Bruk «> filnamn» for Ã¥ lagra utskrifta i ei fil.\n" +"Bruk «| prog arg ...» for Ã¥ senda ho vidare til eit program." + +#: ../../po/../src/extension/internal/ps.cpp:1227 +msgid "write error occurred" +msgstr "Det oppstod ein skrivefeil." + +#: ../../po/../src/extension/prefdialog.cpp:21 +msgid " Preferences" +msgstr " Innstillingar" + +#. We can't call sp_ui_error_dialog because we may be +#. running from the console, in which case calling sp_ui +#. routines will cause a segfault. See bug 1000350 - bryce +#. sp_ui_error_dialog(_("Format autodetect failed. The file is being opened as SVG.")); +#: ../../po/../src/extension/system.cpp:105 +msgid "Format autodetect failed. The file is being opened as SVG." +msgstr "Klarte ikkje finna rett format automatisk. Fila vert opna som SVG." + +#. TRANSLATORS: default.svg is localizable - this is the name of the default document +#. template. This way you can localize the default pagesize, translate the name of +#. the default layer, etc. If you wish to localize this file, please create a +#. localized share/templates/default.xx.svg file, where xx is your language code. +#: ../../po/../src/file.cpp:133 +msgid "default.svg" +msgstr "default.svg" + +#: ../../po/../src/file.cpp:215 ../../po/../src/file.cpp:900 +#, c-format +msgid "Failed to load the requested file %s" +msgstr "Klarte ikkje opna fila «%s»." + +#: ../../po/../src/file.cpp:240 +msgid "Document not saved yet. Cannot revert." +msgstr "Kan ikkje opna dokumentet pÃ¥ nytt att, dÃ¥ det ikkje er lagra enno." + +#: ../../po/../src/file.cpp:246 +#, c-format +msgid "Changes will be lost! Are you sure you want to reload document %s?" +msgstr "" +"Alle endringar gÃ¥r tapt. Er du sikker pÃ¥ at du vil lasta dokumentet «%s» om " +"att?" + +#: ../../po/../src/file.cpp:266 +msgid "Document reverted." +msgstr "Dokumentet er lasta om att." + +#: ../../po/../src/file.cpp:268 +msgid "Document not reverted." +msgstr "Dokumentet er ikkje lasta om att." + +#: ../../po/../src/file.cpp:382 +msgid "Select file to open" +msgstr "Vel fila du vil opna" + +#: ../../po/../src/file.cpp:518 +#, c-format +msgid "Removed %i unused definition in <defs>." +msgid_plural "Removed %i unused definitions in <defs>." +msgstr[0] "Fjerna %i ubrukt definisjon i <defs>." +msgstr[1] "Fjerna %i ubrukte definisjonar i <defs>." + +#: ../../po/../src/file.cpp:523 +msgid "No unused definitions in <defs>." +msgstr "Det finst ingen ubrukte definisjonar i <defs>." + +#: ../../po/../src/file.cpp:548 +#, c-format +msgid "" +"No Inkscape extension found to save document (%s). This may have been " +"caused by an unknown filename extension." +msgstr "" +"Fann inga Inkscape-tillegg for Ã¥ lagra dokumentet (%s). Dette kan skuldast " +"eit ukjent filetternamn." + +#: ../../po/../src/file.cpp:549 ../../po/../src/file.cpp:557 +msgid "Document not saved." +msgstr "Dokumentet er ikkje lagra." + +#: ../../po/../src/file.cpp:556 +#, c-format +msgid "File %s could not be saved." +msgstr "Klarte ikkje lagra fila «%s»." + +#: ../../po/../src/file.cpp:566 +msgid "Document saved." +msgstr "Dokumentet er lagra." + +#: ../../po/../src/file.cpp:614 +#, c-format +msgid "drawing%s" +msgstr "teikning%s" + +#: ../../po/../src/file.cpp:620 +#, c-format +msgid "drawing-%d%s" +msgstr "teikning-%d%s" + +#: ../../po/../src/file.cpp:655 +msgid "Select file to save to" +msgstr "Vel fila du vil lagra til" + +#: ../../po/../src/file.cpp:739 +msgid "No changes need to be saved." +msgstr "Ingen endringar treng lagrast." + +#: ../../po/../src/file.cpp:926 +msgid "Select file to import" +msgstr "Vel fila du vil importera" + +#: ../../po/../src/gradient-context.cpp:263 +msgid "Ctrl: snap gradient angle" +msgstr "Ctrl: Stegrotering." + +#: ../../po/../src/gradient-context.cpp:264 +msgid "Shift: draw gradient around the starting point" +msgstr "Shift: Teikn fargeovergang rundt startpunktet." + +#. We did an undoable action, but sp_document_done will be called by the knot when released +#. status text; we do not track coords because this branch is run once, not all the time +#. during drag +#: ../../po/../src/gradient-context.cpp:462 +#, c-format +msgid "Gradient for %d objects; with Ctrl to snap angle" +msgstr "Fargeovergang for %d objekt. Bruk Ctrl for stegvinkel." + +#: ../../po/../src/gradient-context.cpp:464 +msgid "Select objects on which to create gradient." +msgstr "Merk objekta du vil laga fargeovergang for." + +#: ../../po/../src/gradient-drag.cpp:65 +msgid "Linear gradient start" +msgstr "Start pÃ¥ lineær fargeovergang." + +#. POINT_LG_P1 +#: ../../po/../src/gradient-drag.cpp:66 +msgid "Linear gradient end" +msgstr "Slutt pÃ¥ lineær fargeovergang." + +#: ../../po/../src/gradient-drag.cpp:67 +msgid "Radial gradient center" +msgstr "Midten av hjulovergang." + +#: ../../po/../src/gradient-drag.cpp:68 ../../po/../src/gradient-drag.cpp:69 +msgid "Radial gradient radius" +msgstr "Radius til hjulovergang." + +#: ../../po/../src/gradient-drag.cpp:70 +msgid "Radial gradient focus" +msgstr "Fokus til hjulovergang." + +#: ../../po/../src/gradient-drag.cpp:659 +#, c-format +msgid "" +"%s for: %s%s; drag with Ctrl to snap angle, with Ctrl+Alt to " +"preserve angle, with Ctrl+Shift to scale around center" +msgstr "" +"%s for %s%s. Bruk Ctrl for stegvinkel, Ctrl + Alt for Ã¥ halda " +"vinkel fast og Ctrl + Shift for Ã¥ skalera rundt midtpunkt." + +#: ../../po/../src/gradient-drag.cpp:662 +msgid " (stroke)" +msgstr " (strek)" + +#: ../../po/../src/gradient-drag.cpp:665 +msgid "" +"Radial gradient center and focus; drag with Shift to " +"separate focus" +msgstr "" +"Midtpunkt og fokus til hjulovergang. Dra med Shift for " +"Ã¥ skilja fokus." + +#: ../../po/../src/gradient-drag.cpp:667 +#, c-format +msgid "" +"Gradient point shared by %d gradients; drag with Shift to " +"separate" +msgstr "" +"Fargeovergangspunkt delt av %d overgangar. Dra med Shift for Ã¥ " +"skilja." + +#: ../../po/../src/helper/units.cpp:40 +msgid "Unit" +msgstr "Eining" + +#: ../../po/../src/helper/units.cpp:40 +msgid "Units" +msgstr "Eininar" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Point" +msgstr "Punkt" + +#: ../../po/../src/helper/units.cpp:41 +msgid "pt" +msgstr "punkt" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Points" +msgstr "Punkt" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Pt" +msgstr "Pt" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Pixel" +msgstr "Piksel" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Pixels" +msgstr "Pikslar" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Px" +msgstr "Pk" + +#. You can add new elements from this point forward +#: ../../po/../src/helper/units.cpp:44 ../share/extensions/straightseg.inx.h:2 +msgid "Percent" +msgstr "Prosent" + +#: ../../po/../src/helper/units.cpp:44 +msgid "Percents" +msgstr "Prosent" + +#: ../../po/../src/helper/units.cpp:45 +msgid "Millimeter" +msgstr "Millimeter" + +#: ../../po/../src/helper/units.cpp:45 +msgid "mm" +msgstr "mm" + +#: ../../po/../src/helper/units.cpp:45 +msgid "Millimeters" +msgstr "Millimeter" + +#: ../../po/../src/helper/units.cpp:46 +msgid "Centimeter" +msgstr "Centimeter" + +#: ../../po/../src/helper/units.cpp:46 +msgid "cm" +msgstr "cm" + +#: ../../po/../src/helper/units.cpp:46 +msgid "Centimeters" +msgstr "Centimeter" + +#: ../../po/../src/helper/units.cpp:47 +msgid "Meter" +msgstr "Meter" + +#: ../../po/../src/helper/units.cpp:47 +msgid "m" +msgstr "m" + +#: ../../po/../src/helper/units.cpp:47 +msgid "Meters" +msgstr "Meter" + +#. no svg_unit +#: ../../po/../src/helper/units.cpp:48 +msgid "Inch" +msgstr "Tomme" + +#: ../../po/../src/helper/units.cpp:48 +msgid "in" +msgstr "tm" + +#: ../../po/../src/helper/units.cpp:48 +msgid "Inches" +msgstr "Tommar" + +#. Volatiles do not have default, so there are none here +#. TRANSLATORS: for info, see http://www.w3.org/TR/REC-CSS2/syndata.html#length-units +#: ../../po/../src/helper/units.cpp:51 +msgid "Em square" +msgstr "Em-kvadrat" + +#: ../../po/../src/helper/units.cpp:51 +msgid "em" +msgstr "em" + +#: ../../po/../src/helper/units.cpp:51 +msgid "Em squares" +msgstr "Em-kvadrat" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/REC-CSS2/syndata.html#length-units +#: ../../po/../src/helper/units.cpp:53 +msgid "Ex square" +msgstr "Ex-kvadrat" + +#: ../../po/../src/helper/units.cpp:53 +msgid "ex" +msgstr "ex" + +#: ../../po/../src/helper/units.cpp:53 +msgid "Ex squares" +msgstr "Ex-kvadrat" + +#: ../../po/../src/inkscape.cpp:468 +msgid "Untitled document" +msgstr "Namnlaus" + +#. Show nice dialog box +#: ../../po/../src/inkscape.cpp:497 +msgid "Inkscape encountered an internal error and will close now.\n" +msgstr "" +"Det oppstod ein intern feil i Inkscape. Programmet vert derfor lukka.\n" + +#: ../../po/../src/inkscape.cpp:498 +msgid "" +"Automatic backups of unsaved documents were done to the following " +"locations:\n" +msgstr "" +"Automatiske sikkerhetskopier av dokumenter som ikke er lagret ble utført til " +"følgende lokasjoner:\n" + +#: ../../po/../src/inkscape.cpp:499 +msgid "Automatic backup of the following documents failed:\n" +msgstr "Klarte ikkje ta automatisk reservekopi av desse dokumenta:\n" + +#: ../../po/../src/inkscape.cpp:634 +#, c-format +msgid "" +"Cannot create directory %s.\n" +"%s" +msgstr "" +"Klarte ikkje laga mappa «%s».\n" +"%s" + +#: ../../po/../src/inkscape.cpp:635 +#, c-format +msgid "" +"%s is not a valid directory.\n" +"%s" +msgstr "" +"«%s» er ikkje ei gyldig mappe.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:636 +#, c-format +msgid "" +"Cannot create file %s.\n" +"%s" +msgstr "" +"Klarte ikkje laga fila %s.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:637 +#, c-format +msgid "" +"Cannot write file %s.\n" +"%s" +msgstr "" +"Klarte ikkje lagra fila «%s».\n" +"%s" + +#: ../../po/../src/inkscape.cpp:638 +msgid "" +"Although Inkscape will run, it will use default settings,\n" +"and any changes made in preferences will not be saved." +msgstr "" +"Sjølv om Inkscape køyrer, vil programmet bruka standardoppsettet.\n" +"Eventuelle endringar vil heller ikkje lagrast." + +#: ../../po/../src/inkscape.cpp:708 +#, c-format +msgid "" +"%s is not a regular file.\n" +"%s" +msgstr "" +"%s er ikkje ei vanleg fil.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:709 +#, c-format +msgid "" +"%s not a valid XML file, or\n" +"you don't have read permissions on it.\n" +"%s" +msgstr "" +"«%s» er ikkje ei gyldig XML-fil. Eventuelt\n" +"kan det vera du ikkje har løyve til Ã¥ lesa fila.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:711 +#, fuzzy, c-format +msgid "" +"%s is not a valid menus file.\n" +"%s" +msgstr "" +"«%s» er ikkje ei gyldig oppsettfil.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:712 +#, fuzzy +msgid "" +"Inkscape will run with default menus.\n" +"New menus will not be saved." +msgstr "" +"Inkscape køyrer med standardoppsettet.\n" +"Ny innstillingar vert ikkje lagra." + +#. sp_ui_menu_append_check_item_from_verb(m, view, _("_Menu"), _("Show or hide the menu bar"), "menu", +#. checkitem_toggled, checkitem_update, 0); +#: ../../po/../src/interface.cpp:753 +msgid "Commands Bar" +msgstr "Kommandolinje" + +#: ../../po/../src/interface.cpp:753 +msgid "Show or hide the Commands bar (under the menu)" +msgstr "Vis eller skjul kommandolinja (under menyen)." + +#: ../../po/../src/interface.cpp:755 +msgid "Tool Controls" +msgstr "Verktøykontroll" + +#: ../../po/../src/interface.cpp:755 +msgid "Show or hide the Tool Controls panel" +msgstr "Vis eller skjul verktøykontrollpanelet." + +#: ../../po/../src/interface.cpp:757 +msgid "_Toolbox" +msgstr "_Verktøyboks" + +#: ../../po/../src/interface.cpp:757 +msgid "Show or hide the main toolbox (on the left)" +msgstr "Vis eller skjul hovudverktøylinja (til venstre)." + +#: ../../po/../src/interface.cpp:763 +msgid "_Statusbar" +msgstr "_Statuslinje" + +#: ../../po/../src/interface.cpp:763 +msgid "Show or hide the statusbar (at the bottom of the window)" +msgstr "Vis eller skjul statuslinja (nedst i vindauget)." + +#: ../../po/../src/interface.cpp:820 +#, c-format +msgid "Verb \"%s\" Unknown" +msgstr "" + +#. TRANSLATORS: #%s is the id of the group e.g. , not a number. +#: ../../po/../src/interface.cpp:930 +#, c-format +msgid "Enter group #%s" +msgstr "Rediger gruppe nr. %s" + +#: ../../po/../src/interface.cpp:941 +msgid "Go to parent" +msgstr "GÃ¥ til forelder" + +#: ../../po/../src/interface.cpp:972 +msgid "Could not parse SVG data" +msgstr "Klarte ikkje tolka SVG-data" + +#: ../../po/../src/interface.cpp:1135 +#, c-format +msgid "Overwrite %s" +msgstr "Skriv over «%s»" + +#: ../../po/../src/interface.cpp:1153 +#, c-format +msgid "" +"The file %s already exists. Do you want to overwrite that file with the " +"current document?" +msgstr "Fila «%s» finst frÃ¥ før. Vil du skriva over ho?" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:59 +msgid "Jabber connection lost." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:72 +#, c-format +msgid "Sending message; %u message remaining in send queue." +msgid_plural "Sending message; %u messages remaining in send queue." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:78 +msgid "Receive queue empty." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:154 +#, c-format +msgid "Receiving change; %u change left to process." +msgid_plural "Receiving change; %u changes left to process." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:157 +#, c-format +msgid "%s has left the chatroom." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:221 +msgid "Nickname %1 is already in use. Please choose a different nickname." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:225 +msgid "An error was encountered while attempting to connect to the server." +msgstr "" + +#. Check to see if the user made any modifications to this document. If so, +#. we want to give them the option of (1) letting us clear their document or (2) +#. opening a new, blank document for the whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:131 +msgid "%1 has invited you to a whiteboard session." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:132 +msgid "Incoming whiteboard invitation from %1" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:135 +msgid "Do you wish to accept %1's whiteboard session invitation?" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:137 +msgid "" +"Would you like to accept %1's invitation in a new document window?\n" +"Accepting the invitation in your current window will discard unsaved changes." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:143 +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:198 +#, fuzzy +msgid "Accept invitation" +msgstr "Akselerasjon" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:144 +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:199 +msgid "Decline invitation" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:145 +#, fuzzy +msgid "Accept invitation in new document window" +msgstr "Lag eit nytt dokument." + +#. We could not create a new desktop; ask the user if she or he wants to +#. replace the current document and accept the invitation, or reject the invitation. +#. TRANSLATORS: %1 is a userid here +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:196 +msgid "" +"A new document window could not be opened for a whiteboard session with %" +"1" +msgstr "" + +#. TRANSLATORS: %1 is the peer whom refused our invitation. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:238 +msgid "" +"The user %1 has refused your " +"whiteboard invitation.\n" +"\n" +msgstr "" + +#. TRANSLATORS: %1 is the peer whom refused our invitation, %2 is our Jabber identity. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:241 +msgid "" +"You are still connected to a Jabber server as %2, and may send an " +"invitation to %1 again, or you may send an invitation to a different " +"user." +msgstr "" + +#. TRANSLATORS: %1 is the peer whom we tried to contact, but is already in a whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:252 +msgid "" +"The user %1 is already in a " +"whiteboard session.\n" +"\n" +msgstr "" + +#. TRANSLATORS: %1 is the peer whom we tried to contact, but is already in a whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:255 +msgid "" +"You are still connected to a Jabber server as %1, and may send an " +"invitation to a different user." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/invitation-confirm-dialog.cpp:26 +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:24 +msgid "_Write session file:" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/message-processors.cpp:145 +#, c-format +msgid "%s has joined the chatroom." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/message-queue.cpp:87 +#, fuzzy, c-format +msgid "%u change in receive queue." +msgid_plural "%u changes in receive queue." +msgstr[0] "Ingen endringar treng lagrast." +msgstr[1] "Ingen endringar treng lagrast." + +#: ../../po/../src/jabber_whiteboard/message-queue.cpp:117 +#, fuzzy, c-format +msgid "%u change in send queue." +msgid_plural "%u changes in send queue." +msgstr[0] "Ingen endringar treng lagrast." +msgstr[1] "Ingen endringar treng lagrast." + +#. if ID is NULL, then we have a real problem -- we were not able to find a key +#. nor generate one. The only thing we can really do here is abort, since we have +#. no way to let the other client(s) uniquely identify this object. +#. FIXME: If this indicates a programming bug, then don't request translation with +#. * _(...): it is most useful in untranslated form so that developers may search for +#. * it when someone reports it in a bug report (as we want users to do for all bugs, +#. * as indicated by it being a g_warning string). +#. * +#. * Otherwise, if it is not a programming bug but a network error or a bug in the +#. * remote peer (perhaps running different software) or whatever, then present it in +#. * an alert box, and avoid use of technical jargon `NULL'. +#. +#: ../../po/../src/jabber_whiteboard/message-utilities.cpp:171 +msgid "" +"ID for new object is NULL even after generation and lookup attempts: the new " +"object will NOT be sent, nor will any of its child objects!" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:60 +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:995 +msgid "Select a location and filename" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:62 +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:997 +#, fuzzy +msgid "Set filename" +msgstr "_Filnamn" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:301 +msgid "No SSL certificate was found." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:304 +msgid "The SSL certificate provided by the Jabber server is untrusted." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:307 +msgid "The SSL certificate provided by the Jabber server is expired." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:310 +msgid "" +"The SSL certificate provided by the Jabber server has not been activated." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:313 +msgid "" +"The SSL certificate provided by the Jabber server contains a hostname that " +"does not match the Jabber server's hostname." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:316 +msgid "" +"The SSL certificate provided by the Jabber server contains an invalid " +"fingerprint." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:319 +msgid "An unknown error occurred while setting up the SSL connection." +msgstr "" + +#. TRANSLATORS: %1 is the message that describes the specific error that occurred when +#. establishing the SSL connection. +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:325 +msgid "" +"%1\n" +"\n" +"Do you wish to continue connecting to the Jabber server?" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:328 +msgid "Continue connecting and ignore further errors" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:329 +msgid "Continue connecting, but warn me of further errors" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:330 +#, fuzzy +msgid "Cancel connection" +msgstr "Utval" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:777 +#, c-format +msgid "Established whiteboard session with %s." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:785 +#, c-format +msgid "%s has left the whiteboard session." +msgstr "" + +#. Inform the user +#. TRANSLATORS: %1 is the name of the user that disconnected, %2 is the name of the user whom the disconnected user disconnected from. +#. This message is not used in a chatroom context. +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:790 +msgid "" +"The user %1 has left the " +"whiteboard session.\n" +"\n" +msgstr "" + +#. TRANSLATORS: %1 and %2 are userids +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:792 +msgid "" +"You are still connected to a Jabber server as %2, and may establish a " +"new session to %1 or a different user." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:988 +msgid "" +"Could not open file %1 for session recording.\n" +"The error encountered was: %2.\n" +"\n" +"You may select a different location to record the session, or you may opt to " +"not record this session." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:990 +msgid "Choose a different location" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:991 +msgid "Skip session recording" +msgstr "" + +#: ../../po/../src/knot.cpp:673 +msgid "Node or handle drag canceled." +msgstr "Avbrote node- eller kontrollpunktdraging." + +#: ../../po/../src/libnrtype/FontFactory.cpp:358 +msgid "Ignoring font without family that will crash Pango" +msgstr "Hopp over skrift utan famile som vil krasja Pango" + +#: ../../po/../src/main.cpp:395 +msgid "Print the Inkscape version number" +msgstr "Skriv ut versjonsnummer til Inkscape" + +#: ../../po/../src/main.cpp:400 +msgid "Do not use X server (only process files from console)" +msgstr "Bruk ikkje X-tenaren (handter filer gjennom konsollen)" + +#: ../../po/../src/main.cpp:405 +msgid "Try to use X server (even if $DISPLAY is not set)" +msgstr "Prøv Ã¥ bruka X-tenar (sjølv om $DISPLAY er valt til noko anna)" + +#: ../../po/../src/main.cpp:410 +msgid "Open specified document(s) (option string may be excluded)" +msgstr "Opna dokument(a)" + +#: ../../po/../src/main.cpp:411 ../../po/../src/main.cpp:416 +#: ../../po/../src/main.cpp:421 ../../po/../src/main.cpp:483 +#: ../../po/../src/main.cpp:488 ../../po/../src/main.cpp:493 +msgid "FILENAME" +msgstr "FILNAMN" + +#: ../../po/../src/main.cpp:415 +msgid "Print document(s) to specified output file (use '| program' for pipe)" +msgstr "Skriv ut dokument(a) til valt fil (bruk «| program» for vidaresending)" + +#: ../../po/../src/main.cpp:420 +msgid "Export document to a PNG file" +msgstr "Eksporter dokument til PNG-fil" + +#: ../../po/../src/main.cpp:425 +msgid "The resolution used for exporting SVG into bitmap (default 90)" +msgstr "Oppløysing for lagring av SVG som punktbilete (standard: 90)." + +#: ../../po/../src/main.cpp:426 +msgid "DPI" +msgstr "PPT" + +#: ../../po/../src/main.cpp:430 +#, fuzzy +msgid "" +"Exported area in SVG user units (default is the canvas; 0,0 is lower-left " +"corner)" +msgstr "" +"Eksportert omrÃ¥de i SVG-pikslar (standard er heile dokumentet, og 0,0 er " +"nedre venstre hjørne)." + +#: ../../po/../src/main.cpp:431 +msgid "x0:y0:x1:y1" +msgstr "x0:y0:x1:y1" + +#: ../../po/../src/main.cpp:435 +msgid "Exported area is the entire drawing (not canvas)" +msgstr "Eksportert omrÃ¥de er heile teikninga (ikkje heile lerretet)" + +#: ../../po/../src/main.cpp:440 +msgid "" +"Snap the bitmap export area outwards to the nearest integer values (in SVG " +"user units)" +msgstr "" + +#: ../../po/../src/main.cpp:445 +msgid "The width of exported bitmap in pixels (overrides export-dpi)" +msgstr "Breidda pÃ¥ lagra punktbilete i pikslar (overstyrer PPT-innstillingen)" + +#: ../../po/../src/main.cpp:446 +msgid "WIDTH" +msgstr "BREIDD" + +#: ../../po/../src/main.cpp:450 +msgid "The height of exported bitmap in pixels (overrides export-dpi)" +msgstr "Høgda pÃ¥ lagra punktbilete i pikslar (overstyrer PPT-innstillingen)" + +#: ../../po/../src/main.cpp:451 +msgid "HEIGHT" +msgstr "HØGD" + +#: ../../po/../src/main.cpp:455 +msgid "The ID of the object to export (overrides export-area)" +msgstr "Breidda pÃ¥ lagra punktbilete i pikslar (overstyrer PPT-innstillingen)" + +#: ../../po/../src/main.cpp:456 ../../po/../src/main.cpp:532 +msgid "ID" +msgstr "ID" + +#. TRANSLATORS: this means: "Only export the object whose id is given in --export-id". +#. See "man inkscape" for details. +#: ../../po/../src/main.cpp:462 +msgid "" +"Export just the object with export-id, hide all others (only with export-id)" +msgstr "Eksporter berre objektet med ID lik «--export-id», og skjul andre" + +#: ../../po/../src/main.cpp:467 +msgid "Use stored filename and DPI hints when exporting (only with export-id)" +msgstr "Bruk lagra filnamn og PPT-hint ved eksport (berre med «export-id»)." + +#: ../../po/../src/main.cpp:472 +msgid "Background color of exported bitmap (any SVG-supported color string)" +msgstr "" +"Bakgrunnsfarge til lagra punktbilete (du kan bruka alle gyldige SVG-" +"fargekodar)." + +#: ../../po/../src/main.cpp:473 +msgid "COLOR" +msgstr "FARGE" + +#: ../../po/../src/main.cpp:477 +msgid "Background opacity of exported bitmap (either 0.0 to 1.0, or 1 to 255)" +msgstr "" +"Bakgrunnsfarge til lagra punktbilete (du kan bruka alle gyldige SVG-" +"fargekodar)." + +#: ../../po/../src/main.cpp:478 +msgid "VALUE" +msgstr "VERDI" + +#: ../../po/../src/main.cpp:482 +msgid "Export document to plain SVG file (no sodipodi or inkscape namespaces)" +msgstr "" +"Eksporter dokument til en vanlig SVG-fil (ingen «xmlns:sodipodi» navneomrÃ¥de)" + +#: ../../po/../src/main.cpp:487 +msgid "Export document to a PS file" +msgstr "Eksporter dokument til PS-fil" + +#: ../../po/../src/main.cpp:492 +msgid "Export document to an EPS file" +msgstr "Eksporter dokument til EPS-fil" + +#: ../../po/../src/main.cpp:497 +msgid "Convert text object to paths on export (EPS)" +msgstr "Gjer punktbilete om til baner ved eksportering (EPS)" + +#: ../../po/../src/main.cpp:502 +msgid "Export files with the bounding box set to the page size (EPS)" +msgstr "Eksporter filer med avgrensingsboks sett lik sidestorleiken (EPS)." + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:508 +msgid "" +"Query the X coordinate of the drawing or, if specified, of the object with --" +"query-id" +msgstr "" +"Spør etter X-koordinaten til teikninga, eller, om vald, til objektet med «--" +"query-id»." + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:514 +msgid "" +"Query the Y coordinate of the drawing or, if specified, of the object with --" +"query-id" +msgstr "" +"Spør etter Y-koordinaten til teikninga, eller, om vald, til objektet med «--" +"query-id»." + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:520 +msgid "" +"Query the width of the drawing or, if specified, of the object with --query-" +"id" +msgstr "" +"Spør etter breidda til teikninga, eller, om vald, til objektet med «--query-" +"id»." + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:526 +msgid "" +"Query the height of the drawing or, if specified, of the object with --query-" +"id" +msgstr "" +"Spør etter høgda til teikninga, eller, om vald, til objektet med «--query-" +"id»." + +#: ../../po/../src/main.cpp:531 +msgid "The ID of the object whose dimensions are queried" +msgstr "ID-en til objekta som skal spørjast om dimensjonar." + +#. TRANSLATORS: this option makes Inkscape print the name (path) of the extension directory +#: ../../po/../src/main.cpp:537 +msgid "Print out the extension directory and exit" +msgstr "Vis utvidingsmappe og avslutt." + +#: ../../po/../src/main.cpp:542 +msgid "Show given files one-by-one, switch to next on any key/mouse event" +msgstr "" +"Vis filer etter kvarandre. Byt til neste ved tastatur- eller mushending." + +#: ../../po/../src/main.cpp:547 +msgid "Use the new Gtkmm GUI interface" +msgstr "Bruk det nye Gtkmm-baserte grafiske brukargrensesnittet" + +#: ../../po/../src/main.cpp:552 +msgid "Remove unused definitions from the defs section(s) of the document" +msgstr "Fjern ubrukte definisjonar frÃ¥ -delen av dokumentet." + +#: ../../po/../src/main.cpp:741 +msgid "" +"[OPTIONS...] [FILE...]\n" +"\n" +"Available options:" +msgstr "" +"[VAL ...] [FIL ...]\n" +"\n" +"Tilgjengelege val:" + +#: ../../po/../src/menus-skeleton.h:17 +msgid "_New" +msgstr "_Nytt" + +#: ../../po/../src/menus-skeleton.h:22 +msgid "Open _Recent" +msgstr "Nyleg _brukt" + +#: ../../po/../src/menus-skeleton.h:53 +msgid "_Edit" +msgstr "_Rediger" + +#: ../../po/../src/menus-skeleton.h:84 +msgid "_View" +msgstr "_Vis" + +#: ../../po/../src/menus-skeleton.h:85 +#, fuzzy +msgid "_Zoom" +msgstr "Forstørr" + +#: ../../po/../src/menus-skeleton.h:102 +#, fuzzy +msgid "Show/Hide" +msgstr "_Vis/skjul" + +#: ../../po/../src/menus-skeleton.h:107 +msgid "_Display mode" +msgstr "" + +#: ../../po/../src/menus-skeleton.h:126 +msgid "_Layer" +msgstr "_Lag" + +#: ../../po/../src/menus-skeleton.h:143 +msgid "_Object" +msgstr "_Objekt" + +#: ../../po/../src/menus-skeleton.h:165 +msgid "_Path" +msgstr "_Bane" + +#: ../../po/../src/menus-skeleton.h:188 +msgid "_Text" +msgstr "_Tekst" + +#: ../../po/../src/menus-skeleton.h:200 +msgid "Effects" +msgstr "Effektar" + +#: ../../po/../src/menus-skeleton.h:207 +msgid "Whiteboa_rd" +msgstr "" + +#: ../../po/../src/menus-skeleton.h:220 +msgid "_Help" +msgstr "_Hjelp" + +#: ../../po/../src/menus-skeleton.h:222 +#, fuzzy +msgid "Tutorials" +msgstr "_Innføringar" + +#: ../../po/../src/node-context.cpp:382 +msgid "" +"Ctrl: toggle node type, snap handle angle, move hor/vert; Ctrl" +"+Alt: move along handles" +msgstr "" +"Ctrl: Byt mellom nodetypar, endra vinkel i steg, flytt vassrett/" +"loddrett. Ctrl + Alt: Flytt mellom kontrollpunkt." + +#: ../../po/../src/node-context.cpp:383 +msgid "" +"Shift: toggle node selection, disable snapping, rotate both handles" +msgstr "" +"Shift: Merk eller fjern merking, slÃ¥ av stegkontroll eller roter " +"begge kontrollpunkta." + +#: ../../po/../src/node-context.cpp:384 +msgid "Alt: lock handle length; Ctrl+Alt: move along handles" +msgstr "Alt: LÃ¥s styrke. Ctrl + Alt: Flytt mellom kontrollpunkt." + +#: ../../po/../src/nodepath.cpp:1399 ../../po/../src/nodepath.cpp:1411 +#: ../../po/../src/nodepath.cpp:1492 ../../po/../src/nodepath.cpp:1504 +msgid "To join, you must have two endnodes selected." +msgstr "Du mÃ¥ ha merkt to sluttnodar for Ã¥ kunna slÃ¥ dei saman." + +#: ../../po/../src/nodepath.cpp:1633 ../../po/../src/nodepath.cpp:1647 +msgid "" +"Select two non-endpoint nodes on a path between which to delete " +"segments." +msgstr "" +"Du mÃ¥ merkja dei to ikkje-sluttnodane du vil sletta kakestykke mellom." + +#: ../../po/../src/nodepath.cpp:1743 +msgid "Cannot find path between nodes." +msgstr "Klarte ikkje finna noko bane mllom nodane." + +#: ../../po/../src/nodepath.cpp:2822 +#, fuzzy, c-format +msgid "" +"Node handle: angle %0.2f°, length %s; with Ctrl to snap " +"angle; with Alt to lock length; with Shift to rotate both " +"handles" +msgstr "" +"Kontrollpunkt: Ved %0.2f°, lengde %s. Bruk Ctrl for " +"stegvinkel, Alt for Ã¥ lÃ¥sa lengda og Shift for Ã¥ rotera begge " +"kontrollpunkta samtidig." + +#: ../../po/../src/nodepath.cpp:3351 +msgid "" +"Node: drag to edit the path; with Ctrl to snap to horizontal/" +"vertical; with Ctrl+Alt to snap to handles' directions" +msgstr "" +"Node: Dra noden for Ã¥ redigera bana. Bruk Ctrl for Ã¥ avgrensa " +"til vassrett og loddrett, og Ctrl + Alt for Ã¥ avgrensa til " +"kontrollpunktretningane." + +#: ../../po/../src/nodepath.cpp:3375 +msgid "" +"Node handle: drag to shape the curve; with Ctrl to snap angle; " +"with Alt to lock length; with Shift to rotate both handles" +msgstr "" +"Kontrollpunkt: Dra for Ã¥ endra forma. Bruk Ctrl for " +"stegrotering, Alt for Ã¥ lÃ¥sa lengda og Shift for Ã¥ rotera " +"begge kontrollpunkta samtidig." + +#: ../../po/../src/nodepath.cpp:3399 +msgid "" +"Node handle: drag to shape the curve; with Ctrl to snap angle; " +"with Alt to lock length; with Shift to rotate the opposite " +"handle in sync" +msgstr "" +"Kontrollpunkt: Dra for Ã¥ endra forma. Bruk Ctrl for " +"stegrotering, Alt for Ã¥ lÃ¥sa lengda og Shift for Ã¥ rotera " +"rundt motstÃ¥ande kontrollpunkt samtidig." + +#. TRANSLATORS: "end" is an adjective here (NOT a verb) +#: ../../po/../src/nodepath.cpp:3591 +msgid "end node" +msgstr "sluttnode" + +#. TRANSLATORS: "cusp" means "sharp" (cusp node); see also the Advanced Tutorial +#: ../../po/../src/nodepath.cpp:3596 +msgid "cusp" +msgstr "spiss" + +#. TRANSLATORS: "smooth" is an adjective here +#: ../../po/../src/nodepath.cpp:3599 +msgid "smooth" +msgstr "jamn" + +#: ../../po/../src/nodepath.cpp:3601 +msgid "symmetric" +msgstr "symmetrisk" + +#. TRANSLATORS: "end" is an adjective here (NOT a verb) +#: ../../po/../src/nodepath.cpp:3607 +msgid "end node, handle retracted (drag with Shift to extend)" +msgstr "sluttnode, kontrollpunkt trekt inn (dra med Shift for Ã¥ utvida)" + +#: ../../po/../src/nodepath.cpp:3609 +msgid "one handle retracted (drag with Shift to extend)" +msgstr "eitt kontrollpunkt trekt inn (dra med Shift for Ã¥ utvida)" + +#: ../../po/../src/nodepath.cpp:3612 +msgid "both handles retracted (drag with Shift to extend)" +msgstr "begge kontrollpunkta trekt inn (dra med Shift for Ã¥ utvida)" + +#: ../../po/../src/nodepath.cpp:3624 +msgid "Drag nodes or node handles; arrow keys to move nodes" +msgstr "" +"Dra nodar eller kontrollpunkt. Bruk piltastar for Ã¥ flytta " +"nodane." + +#: ../../po/../src/nodepath.cpp:3625 +msgid "Drag the node or its handles; arrow keys to move the node" +msgstr "" +"Dra noden eller kontrollpunkta. Bruk piltastar for Ã¥ flytta " +"noden." + +#: ../../po/../src/nodepath.cpp:3651 ../../po/../src/nodepath.cpp:3663 +msgid "Select a single object to edit its nodes or handles." +msgstr "Merk eit einskildobjekt for Ã¥ redigera nodar og kontrollpunkt." + +#: ../../po/../src/nodepath.cpp:3655 +#, c-format +msgid "" +"0 out of %i node selected. Click, Shift+click, " +"or drag around nodes to select." +msgid_plural "" +"0 out of %i nodes selected. Click, Shift+click, " +"or drag around nodes to select." +msgstr[0] "" +"0 av %i node vald. Klikk, Shift + klikk eller " +"dra rundt nodar for Ã¥ velja." +msgstr[1] "" +"0 av %i nodar valde. Klikk, Shift + klikk eller " +"dra rundt nodar for Ã¥ velja." + +#: ../../po/../src/nodepath.cpp:3661 +msgid "Drag the handles of the object to modify it." +msgstr "Dra kontrollpunkta til objektet for Ã¥ endra det." + +#: ../../po/../src/nodepath.cpp:3669 +#, c-format +msgid "%i of %i node selected; %s. %s." +msgid_plural "%i of %i nodes selected; %s. %s." +msgstr[0] "%i av %i node vald. %s. %s." +msgstr[1] "%i av %i nodar valde. %s. %s." + +#: ../../po/../src/nodepath.cpp:3675 +#, c-format +msgid "%i of %i node selected. %s." +msgid_plural "%i of %i nodes selected. %s." +msgstr[0] "%i av %i node vald. %s." +msgstr[1] "%i av %i nodar valde. %s." + +#: ../../po/../src/object-edit.cpp:493 +msgid "" +"Adjust the horizontal rounding radius; with Ctrl to make the " +"vertical radius the same" +msgstr "" +"Endra vassrett avrundingsradius. Bruk Ctrl for Ã¥ gjera " +"loddrett radius lik." + +#: ../../po/../src/object-edit.cpp:499 +msgid "" +"Adjust the vertical rounding radius; with Ctrl to make the " +"horizontal radius the same" +msgstr "" +"Endra loddrett avrundingsradius. Bruk Ctrl for Ã¥ gjera " +"vassrett radius lik." + +#: ../../po/../src/object-edit.cpp:506 ../../po/../src/object-edit.cpp:513 +msgid "" +"Adjust the width and height of the rectangle; with Ctrl to " +"lock ratio or stretch in one dimension only" +msgstr "" +"Endra breidd og høgd til rektangelet. Bruk Ctrl for Ã¥ lÃ¥sa " +"breidd/høgd-forholdet eller berre strekkja i éi retning." + +#: ../../po/../src/object-edit.cpp:686 +msgid "Adjust ellipse width, with Ctrl to make circle" +msgstr "" +"Endra breidd og høgd til ellipsen. Bruk Ctrl for Ã¥ laga " +"sirkel." + +#: ../../po/../src/object-edit.cpp:689 +msgid "Adjust ellipse height, with Ctrl to make circle" +msgstr "Endra breidd til ellipsen. Bruk Ctrl for Ã¥ laga sirkel." + +#: ../../po/../src/object-edit.cpp:692 +msgid "" +"Position the start point of the arc or segment; with Ctrl to " +"snap angle; drag inside the ellipse for arc, outside for " +"segment" +msgstr "" +"Plasser startpunktet til bogen eller kakestykket. Bruk Ctrl " +"for stegflytting. Dra inni ellipsen for boge og utanfor for " +"kakestykke." + +#: ../../po/../src/object-edit.cpp:695 +msgid "" +"Position the end point of the arc or segment; with Ctrl to " +"snap angle; drag inside the ellipse for arc, outside for " +"segment" +msgstr "" +"Plasser sluttpunktet til bogen eller kakestykket. Bruk Ctrl " +"for stegflytting. Dra inni ellipsen for boge og utanfor for " +"kakestykke." + +#: ../../po/../src/object-edit.cpp:800 +msgid "" +"Adjust the tip radius of the star or polygon; with Shift to " +"round; with Alt to randomize" +msgstr "" +"Endra spissradius til stjerna eller mangenkanten. Bruk Shift " +"for avrunding og Alt for Ã¥ randomisera." + +#: ../../po/../src/object-edit.cpp:803 +msgid "" +"Adjust the base radius of the star; with Ctrl to keep star " +"rays radial (no skew); with Shift to round; with Alt to " +"randomize" +msgstr "" +"Endra grunnradien til stjerna. Bruk Ctrl for Ã¥ halda " +"stjernestrÃ¥lene rette, Shift for avrunding, og Alt for Ã¥ " +"randomisera." + +#: ../../po/../src/object-edit.cpp:967 +msgid "" +"Roll/unroll the spiral from inside; with Ctrl to snap angle; " +"with Alt to converge/diverge" +msgstr "" +"Rull ut/inn spiralen frÃ¥ innsida. Bruk Ctrl for stegrulling og " +"Alt for konvergering/divergering." + +#: ../../po/../src/object-edit.cpp:969 +msgid "" +"Roll/unroll the spiral from outside; with Ctrl to snap angle; " +"with Shift to scale/rotate" +msgstr "" +"Rull ut/inn spiralen frÃ¥ utsida. Bruk Ctrl for stegrulling og " +"Alt for konvergering/divergering." + +#: ../../po/../src/object-edit.cpp:1006 +msgid "Adjust the offset distance" +msgstr "Endra forskyvingsavstanden." + +#. TRANSLATORS: This refers to the pattern that's inside the object +#: ../../po/../src/object-edit.cpp:1036 +msgid "Move the pattern fill inside the object" +msgstr "Plasser mønsterfyllet i objektet." + +#: ../../po/../src/object-edit.cpp:1038 +msgid "Scale the pattern fill uniformly" +msgstr "Skaler mønsterfyllet jamt." + +#: ../../po/../src/object-edit.cpp:1040 +msgid "Rotate the pattern fill; with Ctrl to snap angle" +msgstr "Roter mønsterfyllet. Bruk Ctrl for stegrotering." + +#: ../../po/../src/object-edit.cpp:1065 +msgid "Drag to resize the flowed text frame" +msgstr "Dra for Ã¥ endra storleiken pÃ¥ flyttekstramma." + +#. Item dialog +#: ../../po/../src/object-ui.cpp:106 +msgid "Object _Properties" +msgstr "_Objekteigenskapar" + +#. Select item +#: ../../po/../src/object-ui.cpp:116 +msgid "_Select This" +msgstr "_Merk denne" + +#. Create link +#: ../../po/../src/object-ui.cpp:126 +msgid "_Create Link" +msgstr "_Lag lenkje" + +#. "Ungroup" +#: ../../po/../src/object-ui.cpp:199 ../../po/../src/verbs.cpp:1931 +msgid "_Ungroup" +msgstr "Løys o_pp gruppe" + +#. Link dialog +#: ../../po/../src/object-ui.cpp:239 +msgid "Link _Properties" +msgstr "Lenkje_eigenskapar" + +#. Select item +#: ../../po/../src/object-ui.cpp:249 +msgid "_Follow Link" +msgstr "_Følg lenkje" + +#. Reset transformations +#: ../../po/../src/object-ui.cpp:254 +msgid "_Remove Link" +msgstr "_Fjern lenkje" + +#. Link dialog +#: ../../po/../src/object-ui.cpp:303 +msgid "Image _Properties" +msgstr "Bilet_eigenskapar" + +#. Item dialog +#: ../../po/../src/object-ui.cpp:344 +msgid "_Fill and Stroke" +msgstr "F_yll og strek" + +#: ../../po/../src/path-chemistry.cpp:58 +msgid "Select at least two objects to combine." +msgstr "Du mÃ¥ merkja minst to objekt for Ã¥ kunna slÃ¥ dei saman." + +#: ../../po/../src/path-chemistry.cpp:65 +msgid "At least one of the objects is not a path, cannot combine." +msgstr "Kan ikkje kombinera objekta, dÃ¥ eitt av dei ikkje er ei bane." + +#: ../../po/../src/path-chemistry.cpp:73 +msgid "" +"You cannot combine objects from different groups or layers." +msgstr "" +"Du kan ikkje kombinera objekt frÃ¥ forskjellige grupper eller lag." + +#: ../../po/../src/path-chemistry.cpp:155 +msgid "Select path(s) to break apart." +msgstr "Merk banene du vil bryta opp." + +#: ../../po/../src/path-chemistry.cpp:231 +msgid "No path(s) to break apart in the selection." +msgstr "Det finst ingen baner du kan bryta opp i utvalet." + +#: ../../po/../src/path-chemistry.cpp:252 +msgid "Select object(s) to convert to path." +msgstr "Merk objekta du vil gjera om til baner." + +#: ../../po/../src/path-chemistry.cpp:297 +msgid "No objects to convert to path in the selection." +msgstr "Det finst ingen objekt du kan gjera om til baner i utvalet." + +#: ../../po/../src/path-chemistry.cpp:345 +msgid "Select path(s) to reverse." +msgstr "Merk éi eller fleire bane(r) du vil snu retninga pÃ¥." + +#: ../../po/../src/path-chemistry.cpp:370 +msgid "No paths to reverse in the selection." +msgstr "Det finst ingen baner du kan snu retninga pÃ¥ i utvalet." + +#: ../../po/../src/pen-context.cpp:379 ../../po/../src/pencil-context.cpp:233 +msgid "Continuing selected path" +msgstr "Held fram merkt bane" + +#: ../../po/../src/pen-context.cpp:390 ../../po/../src/pencil-context.cpp:242 +msgid "Creating new path" +msgstr "Lagar ny bane" + +#: ../../po/../src/pen-context.cpp:394 ../../po/../src/pencil-context.cpp:246 +msgid "Appending to selected path" +msgstr "Legg til merkt bane" + +#: ../../po/../src/pen-context.cpp:538 +#, fuzzy +msgid "Click or click and drag to close and finish the path." +msgstr "" +"Trykk for Ã¥ redigera teksten, eller dra for Ã¥ merkja delar av " +"teksten." + +#: ../../po/../src/pen-context.cpp:548 +#, fuzzy +msgid "" +"Click or click and drag to continue the path from this point." +msgstr "" +"Trykk for Ã¥ redigera teksten, eller dra for Ã¥ merkja delar av " +"teksten." + +#: ../../po/../src/pen-context.cpp:857 +#, fuzzy, c-format +msgid "" +"%s: angle %3.2f°, distance %s; with Ctrl to snap angle, " +"Enter to finish the path" +msgstr "" +"Kontrollpunkt: Ved %0.2f°, lengde %s. Bruk Ctrl for " +"stegvinkel, Alt for Ã¥ lÃ¥sa lengda og Shift for Ã¥ rotera begge " +"kontrollpunkta samtidig." + +#: ../../po/../src/pen-context.cpp:882 +#, fuzzy, c-format +msgid "" +"Curve handle: angle %3.2f°, length %s; with Ctrl to snap " +"angle" +msgstr "Roter: %0.2f°. Bruk Ctrl for stegrotering." + +#: ../../po/../src/pen-context.cpp:912 +#, fuzzy, c-format +msgid "" +"%s: angle %3.2f°, length %s; with Ctrl to snap angle, " +"with Shift to move this handle only" +msgstr "" +"Kontrollpunkt: Ved %0.2f°, lengde %s. Bruk Ctrl for " +"stegvinkel, Alt for Ã¥ lÃ¥sa lengda og Shift for Ã¥ rotera begge " +"kontrollpunkta samtidig." + +#: ../../po/../src/pen-context.cpp:946 +msgid "Finishing pen" +msgstr "Fullfører penn" + +#: ../../po/../src/pencil-context.cpp:320 +msgid "Release here to close and finish the path." +msgstr "" + +#: ../../po/../src/pencil-context.cpp:326 +#, fuzzy +msgid "Drawing a freehand path" +msgstr "Teikn frihandslinjer." + +#: ../../po/../src/pencil-context.cpp:331 +msgid "Drag to continue the path from this point." +msgstr "" + +#. Write curves to object +#: ../../po/../src/pencil-context.cpp:390 +msgid "Finishing freehand" +msgstr "Fullført frihandsteikning" + +#: ../../po/../src/rect-context.cpp:387 +msgid "" +"Ctrl: make square or integer-ratio rect, lock a rounded corner " +"circular" +msgstr "" +"Ctrl: Lag kvadrat eller rektangel med heiltalsbasert høgd/breidd-" +"forhold, lÃ¥s avrunda hjørne som sirkelforma." + +#: ../../po/../src/rect-context.cpp:549 +#, c-format +msgid "" +"Rectangle: %s × %s; with Ctrl to make square or integer-" +"ratio rectangle; with Shift to draw around the starting point" +msgstr "" +"Rektangel: %s × %s, med Ctrl for kvadrat eller heiltalsbasert " +"høgd/breidd-forhold. Bruk Shift for Ã¥ teikna rundt startpunktet." + +#: ../../po/../src/select-context.cpp:243 +msgid "Move canceled." +msgstr "Avbrote flytting." + +#: ../../po/../src/select-context.cpp:252 +msgid "Selection canceled." +msgstr "Avbrote utval." + +#: ../../po/../src/select-context.cpp:642 +msgid "Ctrl: select in groups, move hor/vert" +msgstr "Ctrl: Merk objekt inni grupper. Flytt vassrett/loddrett." + +#: ../../po/../src/select-context.cpp:643 +msgid "Shift: toggle select, force rubberband, disable snapping" +msgstr "" +"Shift: Merk eller fjern merking. Bruk gummibandmerking. Ikkje bruk " +"stegkontroll." + +#: ../../po/../src/select-context.cpp:644 +msgid "Alt: select under, move selected" +msgstr "Alt: Merk objekt under. Flytt merkte objekt." + +#: ../../po/../src/select-context.cpp:798 +#, fuzzy +msgid "Selected object is not a group. Cannot enter." +msgstr "" +"Kan ikkje skubba inn eller ut, dÃ¥ det merkte objektet ikkje er ei bane." + +#: ../../po/../src/select-context.cpp:876 +#, c-format +msgid "" +"Move by %s, %s; with Ctrl to restrict to horizontal/vertical; " +"with Shift to disable snapping" +msgstr "" +"Flytt %s, %s, med Ctrl for Ã¥ avgrensa til vassrett og " +"loddrett. Bruk Shift for Ã¥ ikkje bruka stegkontroll." + +#: ../../po/../src/selection-chemistry.cpp:228 +msgid "Nothing was deleted." +msgstr "Ingenting vart sletta." + +#: ../../po/../src/selection-chemistry.cpp:259 +msgid "Select object(s) to duplicate." +msgstr "Merk objekta du vil laga kopi av." + +#: ../../po/../src/selection-chemistry.cpp:420 +msgid "Select two or more objects to group." +msgstr "Merk to eller fleire objekt du vil gruppera." + +#: ../../po/../src/selection-chemistry.cpp:428 +msgid "Select at least two objects to group." +msgstr "Merk minst to objekt du vil gruppera." + +#: ../../po/../src/selection-chemistry.cpp:513 +msgid "Select a group to ungroup." +msgstr "Merk gruppa du vil løysa opp." + +#: ../../po/../src/selection-chemistry.cpp:554 +msgid "No groups to ungroup in the selection." +msgstr "Det finst ingen grupper i utvalet som du kan løysa opp." + +#: ../../po/../src/selection-chemistry.cpp:623 +msgid "Select objects to raise." +msgstr "Merk objekta du vil heva." + +#: ../../po/../src/selection-chemistry.cpp:629 +#: ../../po/../src/selection-chemistry.cpp:681 +#: ../../po/../src/selection-chemistry.cpp:715 +#: ../../po/../src/selection-chemistry.cpp:773 +msgid "" +"You cannot raise/lower objects from different groups or layers." +msgstr "" +"Du kan ikkje heva eller senka objekt frÃ¥ forskjellige grupper eller " +"lag." + +#: ../../po/../src/selection-chemistry.cpp:673 +msgid "Select object(s) to raise to top." +msgstr "Merk objekta du vil senda fremst." + +#: ../../po/../src/selection-chemistry.cpp:709 +msgid "Select object(s) to lower." +msgstr "Merk objekta du vil senka." + +#: ../../po/../src/selection-chemistry.cpp:765 +msgid "Select object(s) to lower to bottom." +msgstr "Merk objekta du vil senda bakarst." + +#: ../../po/../src/selection-chemistry.cpp:806 +msgid "Nothing to undo." +msgstr "Ingenting Ã¥ angra." + +#: ../../po/../src/selection-chemistry.cpp:813 +msgid "Nothing to redo." +msgstr "Ingenting Ã¥ gjera om." + +#: ../../po/../src/selection-chemistry.cpp:969 +msgid "Nothing was copied." +msgstr "Ingenting vart kopiert." + +#: ../../po/../src/selection-chemistry.cpp:1051 +msgid "Current layer is hidden. Unhide it to be able to paste to it." +msgstr "Laget er skjult. Du mÃ¥ visa det før du kan lima inn i det." + +#: ../../po/../src/selection-chemistry.cpp:1055 +msgid "Current layer is locked. Unlock it to be able to paste to it." +msgstr "Laget er lÃ¥st. Du mÃ¥ lÃ¥sa det opp før du kan lima inn i det." + +#: ../../po/../src/selection-chemistry.cpp:1068 +#: ../../po/../src/selection-chemistry.cpp:1103 +msgid "Nothing on the clipboard." +msgstr "Ingenting pÃ¥ utklippstavla." + +#: ../../po/../src/selection-chemistry.cpp:1109 +msgid "Select object(s) to paste style to." +msgstr "Merk objekta du vil lim inn stilen pÃ¥." + +#: ../../po/../src/selection-chemistry.cpp:1128 +msgid "Select object(s) to move to the layer above." +msgstr "Merk objekta du vil senda til laget over." + +#: ../../po/../src/selection-chemistry.cpp:1146 +msgid "No more layers above." +msgstr "Ingen fleire lag over dette." + +#: ../../po/../src/selection-chemistry.cpp:1160 +msgid "Select object(s) to move to the layer below." +msgstr "Merk objekta du vil senda til laget under." + +#: ../../po/../src/selection-chemistry.cpp:1178 +msgid "No more layers below." +msgstr "Ingen fleire lag under dette." + +#: ../../po/../src/selection-chemistry.cpp:1811 +msgid "Select a clone to unlink." +msgstr "Merk klonen du vil kopla laus." + +#: ../../po/../src/selection-chemistry.cpp:1842 +msgid "No clones to unlink in the selection." +msgstr "Det finst ingen klonar som kan koplast laus i dette utvalet." + +#: ../../po/../src/selection-chemistry.cpp:1859 +msgid "" +"Select a clone to go to its original. Select a linked offset " +"to go to its source. Select a text on path to go to the path. Select " +"a flowed text to go to its frame." +msgstr "" +"Merk ein klon for Ã¥ gÃ¥ til opphavet. Merk ei lenkja forskyving " +"for Ã¥ gÃ¥ til kjelda. Merk ein tekst pÃ¥ bane for Ã¥ gÃ¥ til bana. Merk " +"ein flyttekst for Ã¥ gÃ¥ til ramma." + +#: ../../po/../src/selection-chemistry.cpp:1882 +msgid "" +"Cannot find the object to select (orphaned clone, offset, textpath, " +"flowed text?)" +msgstr "" +"Finn ikkje objektet som skal merkjast (foreldrelaus klon, forskyving, " +"tekstbane eller flyttekst?)." + +#: ../../po/../src/selection-chemistry.cpp:1888 +msgid "" +"The object you're trying to select is not visible (it is in <" +"defs>)" +msgstr "" +"Objektet er prøver Ã¥ velja ikkje synleg (det er i <defs>)." + +#: ../../po/../src/selection-chemistry.cpp:1915 +msgid "Select object(s) to convert to pattern." +msgstr "Merk objekta du vil gjera om til mønster." + +#: ../../po/../src/selection-chemistry.cpp:2006 +msgid "Select an object with pattern fill to extract objects from." +msgstr "Merk objektet med mønster som du vil henta objekt frÃ¥." + +#: ../../po/../src/selection-chemistry.cpp:2059 +msgid "No pattern fills in the selection." +msgstr "Det finst ingen mønsterfyll i utvalet." + +#: ../../po/../src/selection-chemistry.cpp:2079 +msgid "Select object(s) to make a bitmap copy." +msgstr "Merk objekta du vil laga ein punktbiletkopi av." + +#: ../../po/../src/selection-describer.cpp:37 +msgid "Click selection to toggle scale/rotation handles" +msgstr "Trykk pÃ¥ utvalet for Ã¥ byta mellom skalerings- og roteringskontrollar" + +#. no items +#: ../../po/../src/selection-describer.cpp:39 +msgid "" +"No objects selected. Click, Shift+click, or drag around objects to select." +msgstr "" +"Ingen objekt er valt. Klikk, Shift + klikk eller dra objekta " +"rundt for Ã¥ velja dei." + +#: ../../po/../src/selection-describer.cpp:51 +#, c-format +msgid " in layer %s" +msgstr " i laget %s" + +#: ../../po/../src/selection-describer.cpp:54 +#, c-format +msgid " in layer %s" +msgstr " i laget %s" + +#: ../../po/../src/selection-describer.cpp:66 +msgid "Use Shift+D to look up original" +msgstr "Bruk Shift + D for Ã¥ gÃ¥ til opphavet" + +#: ../../po/../src/selection-describer.cpp:70 +msgid "Use Shift+D to look up path" +msgstr "Bruk Shift + D for Ã¥ slÃ¥ opp bane" + +#: ../../po/../src/selection-describer.cpp:74 +msgid "Use Shift+D to look up frame" +msgstr "Bruk Shift + D for Ã¥ slÃ¥ opp ramme" + +#: ../../po/../src/selection-describer.cpp:84 +#, c-format +msgid "%i object selected" +msgid_plural "%i objects selected" +msgstr[0] "%i merkt objekt." +msgstr[1] "%i merkte objekt." + +#: ../../po/../src/selection-describer.cpp:90 +#, c-format +msgid "%s%s. %s." +msgstr "%s%s. %s." + +#: ../../po/../src/selection-describer.cpp:94 +#, c-format +msgid "%s in %i layer. %s." +msgid_plural "%s in %i layers. %s." +msgstr[0] "%s i %i lag. %s." +msgstr[1] "%s i %i lag. %s." + +#: ../../po/../src/seltrans.cpp:498 +msgid "" +"Center of rotation and skewing: drag to reposition; scaling with " +"Shift also uses this center" +msgstr "" +"Midtpunkt for rotering og forskyving. Dra for Ã¥ flytta. Skalering med " +"Shift brukar òg dette punktet." + +#: ../../po/../src/seltrans.cpp:514 +msgid "" +"Squeeze or stretch selection; with Ctrl to scale uniformly; " +"with Shift to scale around rotation center" +msgstr "" +"Trykk saman eller utvid utvalet. Bruk Ctrl for Ã¥ halda pÃ¥ høgd/" +"breidd-forholdet og Shift for Ã¥ skalera rundt roteringsmidtpunktet." + +#: ../../po/../src/seltrans.cpp:515 +msgid "" +"Scale selection; with Ctrl to scale uniformly; with Shift to scale around rotation center" +msgstr "" +"Skaler utvalet. Bruk Ctrl for Ã¥ halda pÃ¥ høgd/breidd-forholdet " +"og Shift for Ã¥ skalera rundt roteringsmidtpunktet." + +#: ../../po/../src/seltrans.cpp:519 +msgid "" +"Skew selection; with Ctrl to snap angle; with Shift to " +"skew around the opposite side" +msgstr "" +"Vri utvalet. Bruk Ctrl for stegrotering og Shift for Ã¥ " +"vri rundt motstÃ¥ande hjørne." + +#: ../../po/../src/seltrans.cpp:520 +msgid "" +"Rotate selection; with Ctrl to snap angle; with Shift " +"to rotate around the opposite corner" +msgstr "" +"Roter utvalet. Bruk Ctrl for stegrotering og Shift for " +"Ã¥ rotera rundt motstÃ¥ande hjørne." + +#: ../../po/../src/seltrans.cpp:829 ../../po/../src/seltrans.cpp:909 +#, c-format +msgid "Scale: %0.2f%% x %0.2f%%; with Ctrl to lock ratio" +msgstr "" +"Skaler: %0.2f%% × %0.2f%%. Bruk Ctrl for Ã¥ lesa breidd/høgd-" +"forhold." + +#. TRANSLATORS: don't modify the first ";" (it will NOT be displayed as ";" - only the second one will be) +#: ../../po/../src/seltrans.cpp:984 +#, c-format +msgid "Skew: %0.2f°; with Ctrl to snap angle" +msgstr "Vri: %0.2f°. Bruk Ctrl for stegvriing." + +#. TRANSLATORS: don't modify the first ";" (it will NOT be displayed as ";" - only the second one will be) +#: ../../po/../src/seltrans.cpp:1035 +#, c-format +msgid "Rotate: %0.2f°; with Ctrl to snap angle" +msgstr "Roter: %0.2f°. Bruk Ctrl for stegrotering." + +#: ../../po/../src/seltrans.cpp:1090 +#, c-format +msgid "Move center to %s, %s" +msgstr "Flytt midten til %s, %s" + +#: ../../po/../src/slideshow.cpp:90 +msgid "Inkscape slideshow" +msgstr "Lysbiletframvising" + +#: ../../po/../src/sp-anchor.cpp:181 +#, c-format +msgid "Link to %s" +msgstr "Lenkje til %s" + +#: ../../po/../src/sp-anchor.cpp:185 +msgid "Link without URI" +msgstr "Lenkje utan URI" + +#: ../../po/../src/sp-ellipse.cpp:438 ../../po/../src/sp-ellipse.cpp:870 +msgid "Ellipse" +msgstr "Ellipse" + +#: ../../po/../src/sp-ellipse.cpp:583 +msgid "Circle" +msgstr "Sirkel" + +#: ../../po/../src/sp-ellipse.cpp:865 +msgid "Segment" +msgstr "Boge" + +#: ../../po/../src/sp-ellipse.cpp:867 +msgid "Arc" +msgstr "Boge" + +#. TRANSLATORS: "Flow region" is an area where text is allowed to flow +#: ../../po/../src/sp-flowregion.cpp:276 +msgid "Flow region" +msgstr "Flyt omrÃ¥de" + +#. TRANSLATORS: A region "cut out of" a flow region; text is not allowed to flow inside the +#. * flow excluded region. flowRegionExclude in SVG 1.2: see +#. * http://www.w3.org/TR/2004/WD-SVG12-20041027/flow.html#flowRegion-elem and +#. * http://www.w3.org/TR/2004/WD-SVG12-20041027/flow.html#flowRegionExclude-elem. +#: ../../po/../src/sp-flowregion.cpp:493 +msgid "Flow excluded region" +msgstr "Flyt ekskludert omrÃ¥de" + +#: ../../po/../src/sp-flowtext.cpp:355 +#, c-format +msgid "Flowed text (%d characters)" +msgstr "Flyttekst (%d teikn)" + +#: ../../po/../src/sp-flowtext.cpp:357 +#, c-format +msgid "Linked flowed text (%d characters)" +msgstr "Lenkje flyttekst (%d teikn)" + +#: ../../po/../src/sp-guide.cpp:290 +msgid "vertical guideline" +msgstr "loddrett hjelpelinje" + +#: ../../po/../src/sp-guide.cpp:292 +msgid "horizontal guideline" +msgstr "vassrett hjelpelinje" + +#: ../../po/../src/sp-image.cpp:835 +msgid "embedded" +msgstr "innebygd" + +#: ../../po/../src/sp-image.cpp:839 +msgid "(null_pointer)" +msgstr "(null-peikar)" + +#: ../../po/../src/sp-image.cpp:843 +#, c-format +msgid "Image with bad reference: %s" +msgstr "Bilete med ugyldig referanse: %s" + +#: ../../po/../src/sp-image.cpp:844 +#, c-format +msgid "Image %d × %d: %s" +msgstr "Bilete %d × %d: %s" + +#: ../../po/../src/sp-item-group.cpp:390 +#, c-format +msgid "Group of %d object" +msgid_plural "Group of %d objects" +msgstr[0] "Gruppe pÃ¥ %d objekt" +msgstr[1] "Gruppe pÃ¥ %d objekt" + +#: ../../po/../src/sp-item.cpp:720 +msgid "Object" +msgstr "Objekt" + +#: ../../po/../src/sp-line.cpp:202 +msgid "Line" +msgstr "Linje" + +#. TRANSLATORS COMMENT: %s is either "outset" or "inset" depending on sign +#: ../../po/../src/sp-offset.cpp:433 +#, c-format +msgid "Linked offset, %s by %f pt" +msgstr "Dynamisk forskyving, %s pÃ¥ %f punkt" + +#: ../../po/../src/sp-offset.cpp:434 ../../po/../src/sp-offset.cpp:438 +msgid "outset" +msgstr "utskyving" + +#: ../../po/../src/sp-offset.cpp:434 ../../po/../src/sp-offset.cpp:438 +msgid "inset" +msgstr "innskyving" + +#. TRANSLATORS COMMENT: %s is either "outset" or "inset" depending on sign +#: ../../po/../src/sp-offset.cpp:437 +#, c-format +msgid "Dynamic offset, %s by %f pt" +msgstr "Dynamisk forskyving, %s pÃ¥ %f punkt." + +#: ../../po/../src/sp-path.cpp:127 +#, c-format +msgid "Path (%i node)" +msgid_plural "Path (%i nodes)" +msgstr[0] "Bane (%i node)" +msgstr[1] "Bane (%i nodar)" + +#: ../../po/../src/sp-polygon.cpp:216 +msgid "Polygon" +msgstr "Mangekant" + +#: ../../po/../src/sp-polyline.cpp:179 +msgid "Polyline" +msgstr "Fleirlinje" + +#: ../../po/../src/sp-rect.cpp:250 +msgid "Rectangle" +msgstr "Rektangel" + +#. TRANSLATORS: since turn count isn't an integer, please adjust the +#. string as needed to deal with an localized plural forms. +#: ../../po/../src/sp-spiral.cpp:305 +#, c-format +msgid "Spiral with %3f turns" +msgstr "Spiral med %3f rundar" + +#: ../../po/../src/sp-star.cpp:288 +#, c-format +msgid "Star with %d vertex" +msgid_plural "Star with %d vertices" +msgstr[0] "Stjerne med %d spiss" +msgstr[1] "Stjerne med %d spissar" + +#: ../../po/../src/sp-star.cpp:292 +#, c-format +msgid "Polygon with %d vertex" +msgid_plural "Polygon with %d vertices" +msgstr[0] "Mangekant med %d hjørne" +msgstr[1] "Mangekant med %d hjørne" + +#. TRANSLATORS: For description of font with no name. +#: ../../po/../src/sp-text.cpp:420 +msgid "<no name found>" +msgstr "<fann ingen namn>" + +#: ../../po/../src/sp-text.cpp:426 +#, c-format +msgid "Text on path (%s, %s)" +msgstr "Tekst pÃ¥ bane (%s, %s)" + +#: ../../po/../src/sp-text.cpp:427 +#, c-format +msgid "Text (%s, %s)" +msgstr "Tekst (%s, %s)" + +#. TRANSLATORS: Used for statusbar description for long chains: +#. * "Clone of: Clone of: ... in Layer 1". +#: ../../po/../src/sp-use.cpp:317 +msgid "..." +msgstr "…" + +#: ../../po/../src/sp-use.cpp:325 +#, c-format +msgid "Clone of: %s" +msgstr "Klon av: %s" + +#: ../../po/../src/sp-use.cpp:329 +msgid "Orphaned clone" +msgstr "Foreldrelaus klon" + +#: ../../po/../src/spiral-context.cpp:355 +msgid "Ctrl: snap angle" +msgstr "Ctrl: Stegrotering." + +#: ../../po/../src/spiral-context.cpp:357 +msgid "Alt: lock spiral radius" +msgstr "Alt: LÃ¥s spiralradius." + +#: ../../po/../src/spiral-context.cpp:469 +#, c-format +msgid "" +"Spiral: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" +"Spiral: Radius %s, vinkel %5g°. Bruk Ctrl for stegvinkel." + +#: ../../po/../src/splivarot.cpp:106 +msgid "Select at least 2 paths to perform a boolean operation." +msgstr "" +"Du mÃ¥ merkja minst to baner for Ã¥ kunna utføra ein boolsk operasjon." + +#: ../../po/../src/splivarot.cpp:112 +msgid "" +"Select exactly 2 paths to perform difference, XOR, division, or path " +"cut." +msgstr "" +"Du mÃ¥ merkja nøyaktig to baner for Ã¥ kunna utføra ein differanse, ein " +"eksklusjon, ei oppdeling eller ei baneoppdeling." + +#: ../../po/../src/splivarot.cpp:129 ../../po/../src/splivarot.cpp:144 +msgid "" +"Unable to determine the z-order of the objects selected for " +"difference, XOR, division, or path cut." +msgstr "" +"Klarte ikkje fastsetja z-ordninga av objekta for differanse, " +"eksklusjon, oppdeling eller baneoppdeling." + +#: ../../po/../src/splivarot.cpp:174 +msgid "" +"One of the objects is not a path, cannot perform boolean operation." +msgstr "" +"Kan ikkje utføra boolsk operasjon, dÃ¥ eitt av objekta ikkje er ei bane." + +#. TRANSLATORS: "to outline" means "to convert stroke to path" +#: ../../po/../src/splivarot.cpp:554 +msgid "Select path(s) to outline." +msgstr "Merk objekta der du vil gjera strekane om til baner." + +#. TRANSLATORS: "to outline" means "to convert stroke to path" +#: ../../po/../src/splivarot.cpp:748 +msgid "No stroked paths to outline in the selection." +msgstr "Det finst ingen objekt med strekar i utvalet." + +#: ../../po/../src/splivarot.cpp:832 +msgid "Selected object is not a path, cannot inset/outset." +msgstr "" +"Kan ikkje skubba inn eller ut, dÃ¥ det merkte objektet ikkje er ei bane." + +#: ../../po/../src/splivarot.cpp:1040 +msgid "Select path(s) to inset/outset." +msgstr "Merk banene du vil skubba inn eller ut." + +#: ../../po/../src/splivarot.cpp:1257 +msgid "No paths to inset/outset in the selection." +msgstr "Det finst ingen baner Ã¥ skubba inn eller ut i utvalet." + +#: ../../po/../src/splivarot.cpp:1390 +msgid "Select path(s) to simplify." +msgstr "Merk banene du vil forenkla." + +#: ../../po/../src/splivarot.cpp:1417 +msgid "No paths to simplify in the selection." +msgstr "Det finst ingen baner Ã¥ forenkla i utvalet." + +#: ../../po/../src/star-context.cpp:362 +msgid "Ctrl: snap angle; keep rays radial" +msgstr "Ctrl: Stegvinkelsnap eller held strÃ¥lene rette." + +#: ../../po/../src/star-context.cpp:470 +#, c-format +msgid "" +"Polygon: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" +"Mangekant: Radius %s, vinkel %5g°. Bruk Ctrl for " +"stegvinkel." + +#: ../../po/../src/star-context.cpp:471 +#, c-format +msgid "Star: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" +"Stjerne: Radius %s, vinkel %5g°. Bruk Ctrl for stegvinkel." + +#: ../../po/../src/text-chemistry.cpp:90 +msgid "Select a text and a path to put text on path." +msgstr "Merk ein tekst og ei bane for Ã¥ leggja teksten pÃ¥ bana." + +#: ../../po/../src/text-chemistry.cpp:95 +msgid "" +"This text object is already put to a path. Remove it from the path " +"first. Use Shift+D to look up its path." +msgstr "" +"Tekstobjektet ligg allereie pÃ¥ ei bane. Du mÃ¥ derfor først kopla det " +"laus. Bruk Shift + D for Ã¥ gÃ¥ til bana." + +#. rect is the only SPShape which is not yet, and thus SVG forbids us from putting text on it +#: ../../po/../src/text-chemistry.cpp:101 +msgid "" +"You cannot put text on a rectangle in this version. Convert rectangle to " +"path first." +msgstr "" +"Du kan ikkje leggja tekst i rektangel i denne versjonen. Prøv Ã¥ gjera " +"rektangelen om til ei bane først." + +#: ../../po/../src/text-chemistry.cpp:159 +msgid "Select a text on path to remove it from path." +msgstr "Merk ein tekst pÃ¥ ei bane for Ã¥ fjerna han frÃ¥ bana." + +#: ../../po/../src/text-chemistry.cpp:181 +msgid "No texts-on-paths in the selection." +msgstr "Det finst ikkje nokon tekstar pÃ¥ baner i utvalet." + +#: ../../po/../src/text-chemistry.cpp:209 +#: ../../po/../src/text-chemistry.cpp:229 +msgid "Select text(s) to remove kerns from." +msgstr "Merk tekstobjekta du vil fjerna kniping frÃ¥." + +#: ../../po/../src/text-chemistry.cpp:250 +msgid "" +"Select a text and one or more paths or shapes to flow text " +"into frame." +msgstr "" +"Merk ein tekst og éi eller fleire baner eller figurar for Ã¥ " +"flyta teksten i ramma." + +#: ../../po/../src/text-chemistry.cpp:322 +msgid "Select a flowed text to unflow it." +msgstr "Merk ein flyttekst for Ã¥ fiksera han." + +#: ../../po/../src/text-context.cpp:463 +msgid "Click to edit the text, drag to select part of the text." +msgstr "" +"Trykk for Ã¥ redigera teksten, eller dra for Ã¥ merkja delar av " +"teksten." + +#: ../../po/../src/text-context.cpp:465 +msgid "" +"Click to edit the flowed text, drag to select part of the text." +msgstr "" +"Trykk for Ã¥ redigera flytteksten, eller dra for Ã¥ merkja delar " +"av teksten." + +#: ../../po/../src/text-context.cpp:540 +msgid "Non-printable character" +msgstr "Usynleg teikn" + +#: ../../po/../src/text-context.cpp:589 +#, c-format +msgid "Unicode: %s: %s" +msgstr "Unicode: %s: %s" + +#: ../../po/../src/text-context.cpp:591 ../../po/../src/text-context.cpp:855 +msgid "Unicode: " +msgstr "Unicode: " + +#: ../../po/../src/text-context.cpp:615 +msgid "Current layer is hidden. Unhide it to be able to add text." +msgstr "Laget er skjult. Du mÃ¥ visa det før du kan leggja pÃ¥ tekst." + +#: ../../po/../src/text-context.cpp:619 +msgid "Current layer is locked. Unlock it to be able to add text." +msgstr "Laget er lÃ¥st. Du mÃ¥ visa det før du kan leggja pÃ¥ tekst." + +#: ../../po/../src/text-context.cpp:673 +#, c-format +msgid "Flowed text frame: %s × %s" +msgstr "Flyttekst-ramme: %s × %s" + +#: ../../po/../src/text-context.cpp:708 ../../po/../src/text-context.cpp:1464 +msgid "Type text; Enter to start new line." +msgstr "Skriv inn tekst. Bruk Enter for Ã¥ begynna pÃ¥ ny linje." + +#: ../../po/../src/text-context.cpp:719 +msgid "Flowed text is created." +msgstr "Flytteksten er lagt til." + +#: ../../po/../src/text-context.cpp:722 +msgid "" +"The frame is too small for the current font size. Flowed text not " +"created." +msgstr "" +"Ramme er for lita for gjeldande skriftstorleik. Flytteksten vart " +"ikkje lagt til." + +#: ../../po/../src/text-context.cpp:841 +msgid "No-break space" +msgstr "Hardt mellomrom" + +#: ../../po/../src/text-context.cpp:1462 +msgid "Type flowed text; Enter to start new paragraph." +msgstr "Skriv inn tekst. Bruk Enter for Ã¥ begynna pÃ¥ nytt avsnitt." + +#: ../../po/../src/text-context.cpp:1472 ../../po/../src/tools-switch.cpp:189 +msgid "" +"Click to select or create text, drag to create flowed text; " +"then type." +msgstr "" +"Trykk for Ã¥ merkja eller laga tekst, dra for Ã¥ laga flyttekst, " +"og skriv sÃ¥ inn teksten." + +#: ../../po/../src/tools-switch.cpp:141 +msgid "" +"To edit a path, click, Shift+click, or drag around " +"nodes to select them, then drag nodes and handles. Click on an " +"object to select." +msgstr "" +"Klikk for Ã¥ endra bana, Shift + klikk eller dra nodane for Ã¥ merkja. " +"Dra kontrollane for Ã¥ endra ein figur." + +#: ../../po/../src/tools-switch.cpp:147 +msgid "" +"Drag to create a rectangle. Drag controls to round corners and " +"resize. Click to select." +msgstr "" +"Dra for Ã¥ laga eit rektangel. Dra kontrollpunkta for skalering " +"og avrunda hjørner. Trykk for Ã¥ merkja." + +#: ../../po/../src/tools-switch.cpp:153 +msgid "" +"Drag to create an ellipse. Drag controls to make an arc or " +"segment. Click to select." +msgstr "" +"Dra for Ã¥ laga ein ellipse. Dra kontrollpunkta for Ã¥ laga ein " +"boge eller eit kakestykke. Trykk for Ã¥ merkja." + +#: ../../po/../src/tools-switch.cpp:159 +msgid "" +"Drag to create a star. Drag controls to edit the star shape. " +"Click to select." +msgstr "" +"Dra for Ã¥ laga ei stjerne. Dra kontrollpunkta for Ã¥ endra " +"stjerneforma. Trykk for Ã¥ merkja." + +#: ../../po/../src/tools-switch.cpp:165 +msgid "" +"Drag to create a spiral. Drag controls to edit the spiral " +"shape. Click to select." +msgstr "" +"Dra for Ã¥ laga ein spiral. Dra kontrollpunkta for Ã¥ endra " +"spiralforma. Trykk for Ã¥ merkja." + +#: ../../po/../src/tools-switch.cpp:171 +msgid "" +"Drag to create a freehand line. Start drawing with Shift to " +"append to selected path." +msgstr "" +"Dra for Ã¥ teikna ei frihandslinje. Start teikninga med Shift " +"for Ã¥ leggja til merkt bane." + +#: ../../po/../src/tools-switch.cpp:177 +#, fuzzy +msgid "" +"Click or click and drag to start a path; with Shift to " +"append to selected path." +msgstr "" +"Trykk for Ã¥ laga ein ny node. Trykk og dra for Ã¥ laga ein jamn " +"node. Start teikninga med Shift for Ã¥ leggja til merkt bane." + +#: ../../po/../src/tools-switch.cpp:183 +msgid "" +"Drag to paint a calligraphic stroke. Left/right arrow " +"keys adjust width, up/down adjust angle." +msgstr "" +"Dra for Ã¥ teikna kalligrafiske strøk. Venstre- og høgre-" +"piltastane justerer breidda, mens opp og ned justerer vinkelen." + +#: ../../po/../src/tools-switch.cpp:195 +msgid "" +"Drag or double click to create a gradient on selected objects, " +"drag handles to adjust gradients." +msgstr "" +"Dra eller dobbeltklikk for Ã¥ teikna ein fargeovergang pÃ¥ " +"merkte objekt. Dra kontrollpunkt for Ã¥ justera fargeovergangar." + +#: ../../po/../src/tools-switch.cpp:201 +msgid "" +"Click or drag around an area to zoom in, Shift+click to " +"zoom out." +msgstr "" +"Klikk eller dra rundt eit omrÃ¥de for Ã¥ forstørra. Shift + " +"klikk for Ã¥ forstørra ut." + +#: ../../po/../src/tools-switch.cpp:213 +msgid "Click and drag between shapes to create a connector." +msgstr "" + +#: ../../po/../src/trace/potrace/inkscape-potrace.cpp:553 +#: ../../po/../src/trace/potrace/inkscape-potrace.cpp:654 +#, c-format +msgid "Trace: %d. %ld nodes" +msgstr "Avteikningar: %d. %ld nodar" + +#: ../../po/../src/trace/trace.cpp:53 ../../po/../src/trace/trace.cpp:62 +#: ../../po/../src/trace/trace.cpp:70 +msgid "Select an image to trace" +msgstr "Merk biletet du vil teikna av." + +#: ../../po/../src/trace/trace.cpp:133 +msgid "Trace: No active document" +msgstr "Avteikning: Ingen aktive dokument." + +#: ../../po/../src/trace/trace.cpp:154 +msgid "Trace: Image has no bitmap data" +msgstr "Avteikning: Biletet inneheld ingen punktdata." + +#: ../../po/../src/trace/trace.cpp:267 +#, c-format +msgid "Trace: Done. %ld nodes created" +msgstr "Avteikning: Ferdig. Laga %ld nodar." + +#: ../../po/../src/ui/dialog/aboutbox.cpp:59 ../../po/../src/verbs.cpp:2212 +msgid "About Inkscape" +msgstr "Om Inkscape." + +#: ../../po/../src/ui/dialog/aboutbox.cpp:66 +msgid "_Splash" +msgstr "" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:68 +msgid "_Authors" +msgstr "" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:69 +#, fuzzy +msgid "_Translators" +msgstr "Omformingar" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:70 +#, fuzzy +msgid "_License" +msgstr "Lisensavtale" + +#. TRANSLATORS: This is the filename of the `About Inkscape' picture in +#. the `screens' directory. Thus the translation of "about.svg" should be +#. the filename of its translated version, e.g. about.zh.svg for Chinese. +#. +#. N.B. about.svg changes once per release. (We should probably rename +#. the original to about-0.40.svg etc. as soon as we have a translation. +#. If we do so, then add an item to release-checklist saying that the +#. string here should be changed.) +#. FIXME? INKSCAPE_SCREENSDIR and "about.svg" are in UTF-8, not the +#. native filename encoding... and the filename passed to sp_document_new +#. should be in UTF-*8.. +#: ../../po/../src/ui/dialog/aboutbox.cpp:114 +msgid "about.svg" +msgstr "about.svg" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:464 +msgid "Minimum horizontal gap (in px units) between bounding boxes" +msgstr "" + +#. TRANSLATORS: Horizontal gap +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:466 +#: ../../po/../src/widgets/toolbox.cpp:1556 +msgid "H:" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:474 +msgid "Minimum vertical gap (in px units) between bounding boxes" +msgstr "" + +#. TRANSLATORS: Vertical gap +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:476 +msgid "V:" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:734 +msgid "Align" +msgstr "Juster" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:735 +msgid "Distribute" +msgstr "Fordel" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:736 +msgid "Remove overlaps" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:737 +msgid "Nodes" +msgstr "Nodar" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:742 +msgid "Relative to: " +msgstr "Relativt til: " + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:747 +msgid "Align right sides of objects to left side of anchor" +msgstr "Juster høgresider av objekt til venstre side av anker." + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:750 +msgid "Align left sides" +msgstr "Juster venstresider." + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:753 +msgid "Center on vertical axis" +msgstr "Sentrer loddrett." + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:756 +msgid "Align right sides" +msgstr "Juster høgresider." + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:759 +msgid "Align left sides of objects to right side of anchor" +msgstr "Juster venstresider av objekt til høgre side av anker." + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:762 +msgid "Align bottoms of objects to top of anchor" +msgstr "Juster botnen av objekt til toppen av anker." + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:765 +msgid "Align tops" +msgstr "Juster toppar." + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:768 +msgid "Center on horizontal axis" +msgstr "Sentrer vassrett." + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:771 +msgid "Align bottoms" +msgstr "Juster botnar." + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:774 +msgid "Align tops of objects to bottom of anchor" +msgstr "Juster toppen av objekt til botn av anker." + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:779 +msgid "Align baseline anchors of texts vertically" +msgstr "Juster grunnlinjeanker til tekst loddrett." + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:782 +msgid "Align baseline anchors of texts horizontally" +msgstr "Juster grunnlinjeanker til tekst vassrett." + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:787 +msgid "Make horizontal gaps between objects equal" +msgstr "Fordel vassrett luft jamnt mellom objekt." + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:791 +msgid "Distribute left sides equidistantly" +msgstr "Fordel venstresider av objekt med jamne mellomrom." + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:794 +msgid "Distribute centers equidistantly horizontally" +msgstr "Fordel midten av objekt med jamne mellomrom vassrett." + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:797 +msgid "Distribute right sides equidistantly" +msgstr "Fordel høgresider av objekt med jamne mellomrom." + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:801 +msgid "Make vertical gaps between objects equal" +msgstr "Fordel loddrett luft jamnt mellom objekt." + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:805 +msgid "Distribute tops equidistantly" +msgstr "Fordel toppen av objekt med jamne mellomrom." + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:808 +msgid "Distribute centers equidistantly vertically" +msgstr "Fordel midten av objekt med jamne mellomrom loddrett" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:811 +msgid "Distribute bottoms equidistantly" +msgstr "Fordel botnen av objekt med jamne mellomrom." + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:816 +msgid "Distribute baseline anchors of texts horizontally" +msgstr "Fordel grunnlinjeanker til tekst vassrett." + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:819 +msgid "Distribute baseline anchors of texts vertically" +msgstr "Fordel grunnlinjeanker til tekst loddrett." + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:824 +msgid "Randomize centers in both dimensions" +msgstr "Vel tilfeldige midtpunkt bÃ¥de vassrett og loddrett." + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:827 +msgid "Unclump objects: try to equalize edge-to-edge distances" +msgstr "Hindra klumping av objekt. Prøv Ã¥ gjera kant til kant-avstandane like." + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:832 +msgid "" +"Move objects as little as possible so that their bounding boxes do not " +"overlap" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:837 +msgid "Align selected nodes horizontally" +msgstr "Juster merkte nodar vassrett" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:840 +msgid "Align selected nodes vertically" +msgstr "Juster merkte nodar loddrett" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:843 +msgid "Distribute selected nodes horizontally" +msgstr "Fordel merkte nodar vassrett" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:846 +msgid "Distribute selected nodes vertically" +msgstr "Fordel merkte nodar loddrett" + +#. Rest of the widgetry +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:851 +msgid "Last selected" +msgstr "Sist valte" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:852 +msgid "First selected" +msgstr "Først valte" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:853 +msgid "Biggest item" +msgstr "Største element" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:854 +msgid "Smallest item" +msgstr "Minste element" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:856 +#: ../../po/../src/widgets/desktop-widget.cpp:1065 +msgid "Drawing" +msgstr "Teikning" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:91 +#, fuzzy +msgid "Metadata 1" +msgstr "Metadata" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:92 +#, fuzzy +msgid "Metadata 2" +msgstr "Metadata" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:187 +#, fuzzy +msgid "X coordinate of grid origin" +msgstr "Loddrett koordinat til utvalet." + +#: ../../po/../src/ui/dialog/document-preferences.cpp:189 +#, fuzzy +msgid "Y coordinate of grid origin" +msgstr "Loddrett koordinat til utvalet." + +#: ../../po/../src/ui/dialog/document-preferences.cpp:191 +#, fuzzy +msgid "Distance of vertical grid lines" +msgstr "loddrett hjelpelinje" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:193 +#, fuzzy +msgid "Distance of horizontal grid lines" +msgstr "vassrett hjelpelinje" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:197 +msgid "Max. snapping distance from grid" +msgstr "" + +#: ../../po/../src/ui/dialog/export.cpp:34 +msgid "Export" +msgstr "Eksporter" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:36 +msgid "Fill" +msgstr "Fyll" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:37 +msgid "Stroke Paint" +msgstr "Strekfarge" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:38 +msgid "Stroke Style" +msgstr "Strekstil" + +#: ../../po/../src/ui/dialog/find.cpp:34 +msgid "Find" +msgstr "Finn" + +#: ../../po/../src/ui/dialog/memory.cpp:96 +msgid "Heap" +msgstr "Haug" + +#: ../../po/../src/ui/dialog/memory.cpp:97 +msgid "In Use" +msgstr "I bruk" + +#. TRANSLATORS: "Slack" refers to memory which is in the heap but currently unused. +#. More typical usage is to call this memory "free" rather than "slack". +#: ../../po/../src/ui/dialog/memory.cpp:100 +msgid "Slack" +msgstr "Slakk" + +#: ../../po/../src/ui/dialog/memory.cpp:101 +msgid "Total" +msgstr "Totalt" + +#: ../../po/../src/ui/dialog/memory.cpp:141 +#: ../../po/../src/ui/dialog/memory.cpp:147 +#: ../../po/../src/ui/dialog/memory.cpp:154 +#: ../../po/../src/ui/dialog/memory.cpp:186 +msgid "Unknown" +msgstr "Ukjend" + +#: ../../po/../src/ui/dialog/memory.cpp:167 +msgid "Combined" +msgstr "Kombinert" + +#: ../../po/../src/ui/dialog/memory.cpp:209 +msgid "Recalculate" +msgstr "Rekna ut pÃ¥ nytt" + +#: ../../po/../src/ui/dialog/messages.cpp:74 +#, fuzzy +msgid "Ready." +msgstr "Raud" + +#: ../../po/../src/ui/dialog/messages.cpp:75 +msgid "" +"Enable log display by setting dialogs.debug 'redirect' attribute to 1 in " +"preferences.xml" +msgstr "" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:184 +msgid "_Execute Python" +msgstr "_Køyr Python" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:186 +msgid "_Execute Perl" +msgstr "_Køyr Perl" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:195 +msgid "Script" +msgstr "Skri_pt" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:205 +msgid "Output" +msgstr "Utdata" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:215 +msgid "Errors" +msgstr "Feil" + +#. Dialog organization +#: ../../po/../src/ui/dialog/session-player.cpp:73 +msgid "Session file" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:74 +#, fuzzy +msgid "Playback controls" +msgstr "Verktøykontroll" + +#: ../../po/../src/ui/dialog/session-player.cpp:75 +#, fuzzy +msgid "Message information" +msgstr "Fjern _omformingar" + +#. Active session file display +#. fixme: Does this mean the active file for the session, or the file for the active session? +#. Please indicate which with a TRANSLATORS comment. +#: ../../po/../src/ui/dialog/session-player.cpp:85 +msgid "Active session file:" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:86 +msgid "Delay (milliseconds):" +msgstr "" + +#. Unload/load buttons +#: ../../po/../src/ui/dialog/session-player.cpp:94 +#, fuzzy +msgid "Close file" +msgstr "Lukk" + +#: ../../po/../src/ui/dialog/session-player.cpp:95 +msgid "Open new file" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:96 +#, fuzzy +msgid "Set delay" +msgstr "Set som standard" + +#: ../../po/../src/ui/dialog/session-player.cpp:138 +#, fuzzy +msgid "Rewind" +msgstr "Raud" + +#: ../../po/../src/ui/dialog/session-player.cpp:139 +msgid "Go back one change" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:140 +#, fuzzy +msgid "Pause" +msgstr "_Lim inn" + +#: ../../po/../src/ui/dialog/session-player.cpp:141 +msgid "Go forward one change" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:142 +msgid "Play" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:177 +#: ../../po/../src/verbs.cpp:1573 +msgid "Open session file" +msgstr "" + +#. ##Set up the Potrace panel +#. #### brightness #### +#. #### Multiple scanning#### +#. ----Hbox1 +#: ../../po/../src/ui/dialog/tracedialog.cpp:345 +#: ../../po/../src/ui/dialog/tracedialog.cpp:428 +msgid "Brightness" +msgstr "Lysstyrke" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:348 +msgid "Trace by a given brightness level" +msgstr "Teikn av etter ein viss lysstyrke." + +#: ../../po/../src/ui/dialog/tracedialog.cpp:355 +msgid "Brightness cutoff for black/white" +msgstr "Lysstyrketerskel for Ã¥ skilja mellom svart og kvit." + +#: ../../po/../src/ui/dialog/tracedialog.cpp:362 +msgid "Image Brightness" +msgstr "Lysstyrke" + +#. #### canny edge detection #### +#. TRANSLATORS: "Canny" is the name of the inventor of this edge detection method +#: ../../po/../src/ui/dialog/tracedialog.cpp:369 +msgid "Optimal Edge Detection (Canny)" +msgstr "Optimal kantattkjenning" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:372 +msgid "Trace with edge detection by J. Canny's algorithm" +msgstr "Teikn av med kantattkjenningsalgoritmen til J. Canny." + +#: ../../po/../src/ui/dialog/tracedialog.cpp:388 +msgid "Brightness cutoff for adjacent pixels (determines edge thickness)" +msgstr "Brotspunkt for nabopikslar (avgjer kor tjukk kantane vart)." + +#: ../../po/../src/ui/dialog/tracedialog.cpp:395 +msgid "Edge Detection" +msgstr "Kantattkjenning" + +#. #### quantization #### +#. TRANSLATORS: Color Quantization: the process of reducing the number of colors +#. in an image by selecting an optimized set of representative colors and then +#. re-applying this reduced set to the original image. +#: ../../po/../src/ui/dialog/tracedialog.cpp:404 +msgid "Color Quantization" +msgstr "Fargeredusering" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:407 +msgid "Trace along the boundaries of reduced colors" +msgstr "Teikn av ei fargeredusert utgÃ¥ve av biletet." + +#: ../../po/../src/ui/dialog/tracedialog.cpp:414 +msgid "The number of reduced colors" +msgstr "Talet pÃ¥ fargar biletet skal reduserast til." + +#: ../../po/../src/ui/dialog/tracedialog.cpp:416 +msgid "Colors:" +msgstr "Fargar:" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:421 +msgid "Quantization / Reduction" +msgstr "Fargeredusering" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:431 +msgid "Trace the given number of brightness levels" +msgstr "Teikn av etter sÃ¥ mange lysstyrkenivÃ¥." + +#: ../../po/../src/ui/dialog/tracedialog.cpp:438 +msgid "Scans:" +msgstr "Avteikningar:" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:440 +msgid "The desired number of scans" +msgstr "Talet pÃ¥ avteikningar." + +#: ../../po/../src/ui/dialog/tracedialog.cpp:448 +msgid "Trace the given number of reduced colors" +msgstr "Teikn av sÃ¥ mange reduserte fargar." + +#. ---Hbox3 +#: ../../po/../src/ui/dialog/tracedialog.cpp:454 +msgid "Monochrome" +msgstr "Svartkvitt" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:457 +msgid "Same as Color, but convert result to grayscale" +msgstr "Same som «Fargar», med gjer om resultatet til svartkvitt." + +#. TRANSLATORS: "Stack" is a verb here +#: ../../po/../src/ui/dialog/tracedialog.cpp:460 +msgid "Stack" +msgstr "Stabla" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:463 +msgid "" +"Stack scans vertically (no gaps) or tile horizontally (usually with gaps)" +msgstr "" +"Stabla avteikningane loddrett (utan hol) eller legg dei vassrett (vanlegvis " +"med hol)." + +#. TRANSLATORS: "Smooth" is a verb here +#: ../../po/../src/ui/dialog/tracedialog.cpp:466 +msgid "Smooth" +msgstr "Jamn" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:469 +msgid "Apply Gaussian blur to the bitmap before tracing" +msgstr "Køyr uskarpheitsfilter pÃ¥ punktbiletet før avteikning." + +#: ../../po/../src/ui/dialog/tracedialog.cpp:473 +msgid "Multiple Scanning" +msgstr "Fleire avteikningar" + +#. #### Preview #### +#: ../../po/../src/ui/dialog/tracedialog.cpp:479 +#: ../../po/../src/ui/dialog/tracedialog.cpp:489 +msgid "Preview" +msgstr "Førehandsvising" + +#. do not expand +#: ../../po/../src/ui/dialog/tracedialog.cpp:483 +msgid "Preview the result without actual tracing" +msgstr "Førehandsvis resultatet utan Ã¥ teikna av heile biletet først." + +#. #### swap black and white #### +#: ../../po/../src/ui/dialog/tracedialog.cpp:495 +msgid "Invert" +msgstr "Inverter" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:499 +msgid "Invert black and white regions for single traces" +msgstr "Byt om pÃ¥ svarte og kvite omrÃ¥de for enkeltavteikningar." + +#: ../../po/../src/ui/dialog/tracedialog.cpp:503 +msgid "Thanks to Peter Selinger, http://potrace.sourceforge.net" +msgstr "Takk til Peter Selinger (http://potrace.sourceforge.net)." + +#: ../../po/../src/ui/dialog/tracedialog.cpp:506 +msgid "Credits" +msgstr "Bidragsytarar" + +#. done +#. TRANSLATORS: Potrace is an application for transforming bitmaps into +#. vector graphics (http://potrace.sourceforge.net/) +#: ../../po/../src/ui/dialog/tracedialog.cpp:514 +msgid "Potrace" +msgstr "Potrace" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:527 +msgid "Abort a trace in progress" +msgstr "Avbryt avteikninga." + +#: ../../po/../src/ui/dialog/tracedialog.cpp:531 +msgid "Execute the trace" +msgstr "Teikn av biletet." + +#: ../../po/../src/ui/dialog/transformation.cpp:80 +#: ../../po/../src/ui/dialog/transformation.cpp:90 +#, fuzzy +msgid "_Horizontal" +msgstr "Vassrett tekst" + +#: ../../po/../src/ui/dialog/transformation.cpp:80 +msgid "Horizontal displacement (relative) or position (absolute)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:82 +#: ../../po/../src/ui/dialog/transformation.cpp:92 +#, fuzzy +msgid "_Vertical" +msgstr "Loddrett tekst" + +#: ../../po/../src/ui/dialog/transformation.cpp:82 +msgid "Vertical displacement (relative) or position (absolute)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:84 +#, fuzzy +msgid "_Width" +msgstr "_Breidd:" + +#: ../../po/../src/ui/dialog/transformation.cpp:84 +msgid "Horizontal size increment (absolute or percentage)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:86 +#, fuzzy +msgid "_Height" +msgstr "Høgd:" + +#: ../../po/../src/ui/dialog/transformation.cpp:86 +msgid "Vertical size increment (absolute or percentage)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:88 +#, fuzzy +msgid "A_ngle" +msgstr "Vinkel:" + +#: ../../po/../src/ui/dialog/transformation.cpp:88 +#, fuzzy +msgid "Rotation angle (positive = counterclockwise)" +msgstr "Roter utvalet 90° mot klokka." + +#: ../../po/../src/ui/dialog/transformation.cpp:90 +msgid "" +"Horizontal skew angle (positive = counterclockwise), or absolute " +"displacement, or percentage displacement" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:92 +msgid "" +"Vertical skew angle (positive = counterclockwise), or absolute displacement, " +"or percentage displacement" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:95 +#, fuzzy +msgid "Transformation matrix element A" +msgstr "Omformingssmatrise" + +#: ../../po/../src/ui/dialog/transformation.cpp:96 +#, fuzzy +msgid "Transformation matrix element B" +msgstr "Omformingssmatrise" + +#: ../../po/../src/ui/dialog/transformation.cpp:97 +#, fuzzy +msgid "Transformation matrix element C" +msgstr "Omformingssmatrise" + +#: ../../po/../src/ui/dialog/transformation.cpp:98 +#, fuzzy +msgid "Transformation matrix element D" +msgstr "Omformingssmatrise" + +#: ../../po/../src/ui/dialog/transformation.cpp:99 +#, fuzzy +msgid "Transformation matrix element E" +msgstr "Omformingssmatrise" + +#: ../../po/../src/ui/dialog/transformation.cpp:100 +#, fuzzy +msgid "Transformation matrix element F" +msgstr "Omformingssmatrise" + +#: ../../po/../src/ui/dialog/transformation.cpp:102 +#, fuzzy +msgid "Rela_tive move" +msgstr "Relativ flytting" + +#: ../../po/../src/ui/dialog/transformation.cpp:102 +msgid "" +"Add the specified relative displacement to the current position; otherwise, " +"edit the current absolute position directly" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:103 +msgid "Scale proportionally" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:103 +msgid "Preserve the width/height ratio of the scaled objects" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:104 +msgid "Apply to each _object separately" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:104 +msgid "" +"Apply the scale/rotate/skew to each selected object separately; otherwise, " +"transform the selection as a whole" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:105 +#, fuzzy +msgid "Edit c_urrent matrix" +msgstr "Hev dette laget." + +#: ../../po/../src/ui/dialog/transformation.cpp:105 +msgid "" +"Edit the current transform= matrix; otherwise, post-multiply transform= by " +"this matrix" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:115 +#, fuzzy +msgid "_Move" +msgstr "Flytt" + +#: ../../po/../src/ui/dialog/transformation.cpp:118 +#, fuzzy +msgid "_Scale" +msgstr "Skaler" + +#: ../../po/../src/ui/dialog/transformation.cpp:121 +#, fuzzy +msgid "_Rotate" +msgstr "Roter" + +#: ../../po/../src/ui/dialog/transformation.cpp:124 +#, fuzzy +msgid "Ske_w" +msgstr "Vri" + +#: ../../po/../src/ui/dialog/transformation.cpp:127 +msgid "Matri_x" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:141 +msgid "Reset the values on the current tab to defaults" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:148 +#, fuzzy +msgid "Apply transformation to selection" +msgstr "Form om objekt." + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:43 +msgid "_Use SSL" +msgstr "" + +#. Construct dialog interface +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:68 +#, fuzzy +msgid "_Server:" +msgstr "Snu _retning" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:69 +#, fuzzy +msgid "_Username:" +msgstr "_Endra namn" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:70 +msgid "_Password:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:71 +msgid "P_ort:" +msgstr "" + +#. Buttons +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:99 +#, fuzzy +msgid "Connect" +msgstr "Klonar" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:126 +msgid "Establishing connection to Jabber server %1 as user %2" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:131 +msgid "Failed to establish connection to Jabber server %1" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:136 +msgid "Authentication failed on Jabber server %1 as %2" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:141 +msgid "SSL initialization failed when connecting to Jabber server %1" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:147 +msgid "Connected to Jabber server %1 as %2" +msgstr "" + +#. Construct labels +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:75 +#, fuzzy +msgid "Chatroom _name:" +msgstr "Lagnamn:" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:76 +msgid "Chatroom _server:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:77 +msgid "Chatroom _password:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:78 +msgid "Chatroom _handle:" +msgstr "" + +#. Button setup and callback registration +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:97 +msgid "Connect to chatroom" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:132 +msgid "Synchronizing with chatroom %1@%2 using the handle %3" +msgstr "" + +#. Construct dialog interface +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:78 +msgid "_User's Jabber ID:" +msgstr "" + +#. Buttons +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:82 +msgid "_Invite user" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:83 +#, fuzzy +msgid "_Cancel" +msgstr "Avbryt" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:94 +msgid "Buddy List" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:170 +msgid "Sending whiteboard invitation to %1" +msgstr "" + +#. FIXME: strings are replaced by placeholders, NOT to be translated until the code is enabled +#. See http://sourceforge.net/mailarchive/message.php?msg_id=11746016 for details +#. File menu +#. Edit menu +#. View menu +#. Layer menu +#. Object menu +#. Path menu +#. add(Gtk::StockItem(CLEANUP, _("PLACEHOLDER, do not translate"))); (using Gtk::Stock::CLEAR) +#. Text menu +#. About menu +#. Tools toolbox +#. Select Tool controls +#. Node Tool controls +#. Calligraphy Tool controls +#. Session playback controls +#: ../../po/../src/ui/stock-items.cpp:34 ../../po/../src/ui/stock-items.cpp:35 +#: ../../po/../src/ui/stock-items.cpp:36 ../../po/../src/ui/stock-items.cpp:37 +#: ../../po/../src/ui/stock-items.cpp:38 ../../po/../src/ui/stock-items.cpp:39 +#: ../../po/../src/ui/stock-items.cpp:40 ../../po/../src/ui/stock-items.cpp:41 +#: ../../po/../src/ui/stock-items.cpp:42 ../../po/../src/ui/stock-items.cpp:43 +#: ../../po/../src/ui/stock-items.cpp:46 ../../po/../src/ui/stock-items.cpp:47 +#: ../../po/../src/ui/stock-items.cpp:48 ../../po/../src/ui/stock-items.cpp:49 +#: ../../po/../src/ui/stock-items.cpp:50 ../../po/../src/ui/stock-items.cpp:51 +#: ../../po/../src/ui/stock-items.cpp:52 ../../po/../src/ui/stock-items.cpp:53 +#: ../../po/../src/ui/stock-items.cpp:54 ../../po/../src/ui/stock-items.cpp:55 +#: ../../po/../src/ui/stock-items.cpp:56 ../../po/../src/ui/stock-items.cpp:57 +#: ../../po/../src/ui/stock-items.cpp:58 ../../po/../src/ui/stock-items.cpp:59 +#: ../../po/../src/ui/stock-items.cpp:62 ../../po/../src/ui/stock-items.cpp:63 +#: ../../po/../src/ui/stock-items.cpp:64 ../../po/../src/ui/stock-items.cpp:65 +#: ../../po/../src/ui/stock-items.cpp:66 ../../po/../src/ui/stock-items.cpp:67 +#: ../../po/../src/ui/stock-items.cpp:68 ../../po/../src/ui/stock-items.cpp:69 +#: ../../po/../src/ui/stock-items.cpp:70 ../../po/../src/ui/stock-items.cpp:71 +#: ../../po/../src/ui/stock-items.cpp:72 ../../po/../src/ui/stock-items.cpp:73 +#: ../../po/../src/ui/stock-items.cpp:74 ../../po/../src/ui/stock-items.cpp:75 +#: ../../po/../src/ui/stock-items.cpp:76 ../../po/../src/ui/stock-items.cpp:77 +#: ../../po/../src/ui/stock-items.cpp:78 ../../po/../src/ui/stock-items.cpp:79 +#: ../../po/../src/ui/stock-items.cpp:80 ../../po/../src/ui/stock-items.cpp:81 +#: ../../po/../src/ui/stock-items.cpp:82 ../../po/../src/ui/stock-items.cpp:83 +#: ../../po/../src/ui/stock-items.cpp:84 ../../po/../src/ui/stock-items.cpp:85 +#: ../../po/../src/ui/stock-items.cpp:86 ../../po/../src/ui/stock-items.cpp:87 +#: ../../po/../src/ui/stock-items.cpp:88 ../../po/../src/ui/stock-items.cpp:89 +#: ../../po/../src/ui/stock-items.cpp:92 ../../po/../src/ui/stock-items.cpp:93 +#: ../../po/../src/ui/stock-items.cpp:94 ../../po/../src/ui/stock-items.cpp:95 +#: ../../po/../src/ui/stock-items.cpp:96 ../../po/../src/ui/stock-items.cpp:97 +#: ../../po/../src/ui/stock-items.cpp:98 ../../po/../src/ui/stock-items.cpp:99 +#: ../../po/../src/ui/stock-items.cpp:100 +#: ../../po/../src/ui/stock-items.cpp:101 +#: ../../po/../src/ui/stock-items.cpp:102 +#: ../../po/../src/ui/stock-items.cpp:103 +#: ../../po/../src/ui/stock-items.cpp:104 +#: ../../po/../src/ui/stock-items.cpp:105 +#: ../../po/../src/ui/stock-items.cpp:108 +#: ../../po/../src/ui/stock-items.cpp:109 +#: ../../po/../src/ui/stock-items.cpp:110 +#: ../../po/../src/ui/stock-items.cpp:111 +#: ../../po/../src/ui/stock-items.cpp:112 +#: ../../po/../src/ui/stock-items.cpp:113 +#: ../../po/../src/ui/stock-items.cpp:114 +#: ../../po/../src/ui/stock-items.cpp:115 +#: ../../po/../src/ui/stock-items.cpp:116 +#: ../../po/../src/ui/stock-items.cpp:117 +#: ../../po/../src/ui/stock-items.cpp:118 +#: ../../po/../src/ui/stock-items.cpp:119 +#: ../../po/../src/ui/stock-items.cpp:120 +#: ../../po/../src/ui/stock-items.cpp:121 +#: ../../po/../src/ui/stock-items.cpp:122 +#: ../../po/../src/ui/stock-items.cpp:123 +#: ../../po/../src/ui/stock-items.cpp:124 +#: ../../po/../src/ui/stock-items.cpp:125 +#: ../../po/../src/ui/stock-items.cpp:126 +#: ../../po/../src/ui/stock-items.cpp:127 +#: ../../po/../src/ui/stock-items.cpp:130 +#: ../../po/../src/ui/stock-items.cpp:131 +#: ../../po/../src/ui/stock-items.cpp:132 +#: ../../po/../src/ui/stock-items.cpp:133 +#: ../../po/../src/ui/stock-items.cpp:134 +#: ../../po/../src/ui/stock-items.cpp:135 +#: ../../po/../src/ui/stock-items.cpp:136 +#: ../../po/../src/ui/stock-items.cpp:137 +#: ../../po/../src/ui/stock-items.cpp:138 +#: ../../po/../src/ui/stock-items.cpp:139 +#: ../../po/../src/ui/stock-items.cpp:140 +#: ../../po/../src/ui/stock-items.cpp:141 +#: ../../po/../src/ui/stock-items.cpp:142 +#: ../../po/../src/ui/stock-items.cpp:143 +#: ../../po/../src/ui/stock-items.cpp:144 +#: ../../po/../src/ui/stock-items.cpp:145 +#: ../../po/../src/ui/stock-items.cpp:146 +#: ../../po/../src/ui/stock-items.cpp:150 +#: ../../po/../src/ui/stock-items.cpp:151 +#: ../../po/../src/ui/stock-items.cpp:152 +#: ../../po/../src/ui/stock-items.cpp:153 +#: ../../po/../src/ui/stock-items.cpp:156 +#: ../../po/../src/ui/stock-items.cpp:157 +#: ../../po/../src/ui/stock-items.cpp:158 +#: ../../po/../src/ui/stock-items.cpp:161 +#: ../../po/../src/ui/stock-items.cpp:162 +#: ../../po/../src/ui/stock-items.cpp:163 +#: ../../po/../src/ui/stock-items.cpp:164 +#: ../../po/../src/ui/stock-items.cpp:165 +#: ../../po/../src/ui/stock-items.cpp:166 +#: ../../po/../src/ui/stock-items.cpp:167 +#: ../../po/../src/ui/stock-items.cpp:168 +#: ../../po/../src/ui/stock-items.cpp:169 +#: ../../po/../src/ui/stock-items.cpp:170 +#: ../../po/../src/ui/stock-items.cpp:171 +#: ../../po/../src/ui/stock-items.cpp:172 +#: ../../po/../src/ui/stock-items.cpp:175 +#: ../../po/../src/ui/stock-items.cpp:176 +#: ../../po/../src/ui/stock-items.cpp:177 +#: ../../po/../src/ui/stock-items.cpp:178 +#: ../../po/../src/ui/stock-items.cpp:181 +#: ../../po/../src/ui/stock-items.cpp:182 +#: ../../po/../src/ui/stock-items.cpp:183 +#: ../../po/../src/ui/stock-items.cpp:184 +#: ../../po/../src/ui/stock-items.cpp:185 +#: ../../po/../src/ui/stock-items.cpp:186 +#: ../../po/../src/ui/stock-items.cpp:187 +#: ../../po/../src/ui/stock-items.cpp:188 +#: ../../po/../src/ui/stock-items.cpp:189 +#: ../../po/../src/ui/stock-items.cpp:190 +#: ../../po/../src/ui/stock-items.cpp:191 +#: ../../po/../src/ui/stock-items.cpp:194 +#: ../../po/../src/ui/stock-items.cpp:195 +#: ../../po/../src/ui/stock-items.cpp:198 +#: ../../po/../src/ui/stock-items.cpp:199 +#: ../../po/../src/ui/stock-items.cpp:200 +#: ../../po/../src/ui/stock-items.cpp:201 +#: ../../po/../src/ui/stock-items.cpp:202 +msgid "PLACEHOLDER, do not translate" +msgstr "PLACEHOLDER, do not translate" + +#: ../../po/../src/ui/widget/panel.cpp:88 +msgid "small" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:89 +msgid "medium" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:90 +#, fuzzy +msgid "large" +msgstr "MÃ¥l:" + +#: ../../po/../src/ui/widget/panel.cpp:91 +msgid "huge" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:106 +#, fuzzy +msgid "List" +msgstr "innskyving" + +#: ../../po/../src/ui/widget/selected-style.cpp:67 +msgid "F:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:68 +msgid "S:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:69 +msgid "O:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:95 +msgid "N/A" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:98 +#: ../../po/../src/ui/widget/selected-style.cpp:712 +#, fuzzy +msgid "Nothing selected" +msgstr "Ingen fargeovergang valt" + +#: ../../po/../src/ui/widget/selected-style.cpp:103 +msgid "No fill" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:103 +#, fuzzy +msgid "No stroke" +msgstr " (strek)" + +#: ../../po/../src/ui/widget/selected-style.cpp:105 +#: ../../po/../src/widgets/paint-selector.cpp:190 +msgid "Pattern" +msgstr "Mønster" + +#: ../../po/../src/ui/widget/selected-style.cpp:108 +#: ../../po/../src/widgets/paint-selector.cpp:885 +msgid "Pattern fill" +msgstr "Mønsterfyll" + +#: ../../po/../src/ui/widget/selected-style.cpp:108 +#, fuzzy +msgid "Pattern stroke" +msgstr "Mønsterforskyving" + +#: ../../po/../src/ui/widget/selected-style.cpp:110 +#, fuzzy +msgid "L Gradient" +msgstr "Fargeovergang" + +#: ../../po/../src/ui/widget/selected-style.cpp:113 +#, fuzzy +msgid "Linear gradient fill" +msgstr "Lineær fargeovergang" + +#: ../../po/../src/ui/widget/selected-style.cpp:113 +#, fuzzy +msgid "Linear gradient stroke" +msgstr "Lineær fargeovergang" + +#: ../../po/../src/ui/widget/selected-style.cpp:115 +#, fuzzy +msgid "R Gradient" +msgstr "Fargeovergang" + +#: ../../po/../src/ui/widget/selected-style.cpp:118 +#, fuzzy +msgid "Radial gradient fill" +msgstr "Hjulovergang" + +#: ../../po/../src/ui/widget/selected-style.cpp:118 +#, fuzzy +msgid "Radial gradient stroke" +msgstr "Hjulovergang" + +#: ../../po/../src/ui/widget/selected-style.cpp:120 +#, fuzzy +msgid "Different" +msgstr "_Differanse" + +#: ../../po/../src/ui/widget/selected-style.cpp:123 +#, fuzzy +msgid "Different fills" +msgstr "_Differanse" + +#: ../../po/../src/ui/widget/selected-style.cpp:123 +#, fuzzy +msgid "Different strokes" +msgstr "_Differanse" + +#: ../../po/../src/ui/widget/selected-style.cpp:125 +#, fuzzy +msgid "Unset" +msgstr "innskyving" + +#. TRANSLATORS COMMENT: unset is a verb here +#: ../../po/../src/ui/widget/selected-style.cpp:128 +#: ../../po/../src/ui/widget/selected-style.cpp:182 +msgid "Unset fill" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:128 +#: ../../po/../src/ui/widget/selected-style.cpp:182 +#, fuzzy +msgid "Unset stroke" +msgstr " (strek)" + +#: ../../po/../src/ui/widget/selected-style.cpp:131 +#, fuzzy +msgid "Flat color fill" +msgstr "Heildekkjande farge" + +#: ../../po/../src/ui/widget/selected-style.cpp:131 +#, fuzzy +msgid "Flat color stroke" +msgstr "Heildekkjande farge" + +#. TRANSLATOR COMMENT: A means "Averaged" +#: ../../po/../src/ui/widget/selected-style.cpp:134 +#, fuzzy +msgid "A" +msgstr "_A" + +#: ../../po/../src/ui/widget/selected-style.cpp:137 +#, fuzzy +msgid "Fill is averaged over selected objects" +msgstr "Eksklusiv eller av dei merkte objekta." + +#: ../../po/../src/ui/widget/selected-style.cpp:137 +#, fuzzy +msgid "Stroke is averaged over selected objects" +msgstr "Snittet av dei merkte objekta." + +#. TRANSLATOR COMMENT: M means "Multiple" +#: ../../po/../src/ui/widget/selected-style.cpp:140 +#, fuzzy +msgid "M" +msgstr "_M" + +#: ../../po/../src/ui/widget/selected-style.cpp:143 +#, fuzzy +msgid "Multiple selected objects have the same fill" +msgstr "Juster merkte nodar loddrett" + +#: ../../po/../src/ui/widget/selected-style.cpp:143 +#, fuzzy +msgid "Multiple selected objects have the same stroke" +msgstr "Juster merkte nodar loddrett" + +#: ../../po/../src/ui/widget/selected-style.cpp:145 +#, fuzzy +msgid "Edit fill..." +msgstr "Rediger ..." + +#: ../../po/../src/ui/widget/selected-style.cpp:145 +#, fuzzy +msgid "Edit stroke..." +msgstr "Rediger ..." + +#: ../../po/../src/ui/widget/selected-style.cpp:149 +#, fuzzy +msgid "Last set color" +msgstr "Heildekkjande farge" + +#: ../../po/../src/ui/widget/selected-style.cpp:153 +#, fuzzy +msgid "Last selected color" +msgstr "Sist valte" + +#: ../../po/../src/ui/widget/selected-style.cpp:157 +msgid "White" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:161 +#: ../../po/../src/widgets/sp-color-scales.cpp:461 +#: ../../po/../src/widgets/sp-color-scales.cpp:462 +msgid "Black" +msgstr "Svart" + +#: ../../po/../src/ui/widget/selected-style.cpp:165 +#, fuzzy +msgid "Copy color" +msgstr "Stoppfarge" + +#: ../../po/../src/ui/widget/selected-style.cpp:169 +#, fuzzy +msgid "Paste color" +msgstr "Heildekkjande farge" + +#: ../../po/../src/ui/widget/selected-style.cpp:173 +#, fuzzy +msgid "Swap fill and stroke" +msgstr "F_yll og strek" + +#: ../../po/../src/ui/widget/selected-style.cpp:177 +msgid "Make fill opaque" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:177 +msgid "Make stroke opaque" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:186 +#, fuzzy +msgid "Remove fill" +msgstr " _Fjern " + +#: ../../po/../src/ui/widget/selected-style.cpp:186 +#, fuzzy +msgid "Remove stroke" +msgstr "_Fjern lenkje" + +#: ../../po/../src/ui/widget/selected-style.cpp:718 +#, fuzzy +msgid "Master opacity" +msgstr "Hovud_gjennomsikt" + +#: ../../po/../src/ui/widget/selected-style.cpp:744 +msgid "0 (transparent)" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:768 +msgid "1.0 (opaque)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1046 +msgid "Moved to next layer." +msgstr "Flytta til neste lag." + +#: ../../po/../src/verbs.cpp:1048 +#, fuzzy +msgid "Cannot move past last layer." +msgstr "Kan ikkje flytta forbi det siste laget." + +#: ../../po/../src/verbs.cpp:1057 +msgid "Moved to previous layer." +msgstr "Flytta til førre lag." + +#: ../../po/../src/verbs.cpp:1059 +#, fuzzy +msgid "Cannot move past first layer." +msgstr "Kan ikkje flytta forbi det første laget." + +#: ../../po/../src/verbs.cpp:1076 ../../po/../src/verbs.cpp:1150 +msgid "No current layer." +msgstr "Inga lag valt." + +#: ../../po/../src/verbs.cpp:1105 +#, c-format +msgid "Raised layer %s." +msgstr "Heva lag %s." + +#: ../../po/../src/verbs.cpp:1109 +#, c-format +msgid "Lowered layer %s." +msgstr "Senka lag %s." + +#: ../../po/../src/verbs.cpp:1118 +#, fuzzy +msgid "Cannot move layer any further." +msgstr "Kan ikkje flytta laga lenger." + +#. TRANSLATORS: this means "The layer has been deleted." +#: ../../po/../src/verbs.cpp:1148 +msgid "Deleted layer." +msgstr "Sletta lag." + +#: ../../po/../src/verbs.cpp:1544 +msgid "" +"You need to connect to a Jabber server before sharing a document with " +"another user." +msgstr "" + +#: ../../po/../src/verbs.cpp:1559 +msgid "" +"You need to connect to a Jabber server before sharing a document with a " +"chatroom." +msgstr "" + +#: ../../po/../src/verbs.cpp:1569 +msgid "XML node tracker has not been initialized; nothing to dump" +msgstr "" + +#. TRANSLATORS: If you have translated the keys.svg file to your language, then +#. translate this string as "keys.LANG.svg" (where LANG is your language code); +#. otherwise leave as "keys.svg". +#: ../../po/../src/verbs.cpp:1631 +msgid "keys.svg" +msgstr "keys.svg" + +#. TRANSLATORS: If you have translated the tutorial-basic.svg file to your language, +#. then translate this string as "tutorial-basic.LANG.svg" (where LANG is your language +#. code); otherwise leave as "tutorial-basic.svg". +#: ../../po/../src/verbs.cpp:1667 +msgid "tutorial-basic.svg" +msgstr "tutorial-basic.nn.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1671 +msgid "tutorial-shapes.svg" +msgstr "tutorial-shapes.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1675 +msgid "tutorial-advanced.svg" +msgstr "tutorial-advanced.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1679 +msgid "tutorial-tracing.svg" +msgstr "tutorial-tracing.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1683 +msgid "tutorial-calligraphy.svg" +msgstr "tutorial-calligraphy.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1687 +msgid "tutorial-elements.svg" +msgstr "tutorial-elements.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1691 +msgid "tutorial-tips.svg" +msgstr "tutorial-tips.svg" + +#: ../../po/../src/verbs.cpp:1842 +msgid "Does nothing" +msgstr "Gjer ingenting" + +#. File +#: ../../po/../src/verbs.cpp:1845 +msgid "Default" +msgstr "Standard" + +#: ../../po/../src/verbs.cpp:1845 +msgid "Create new document from default template" +msgstr "Lag eit nytt dokument frÃ¥ standardmalen." + +#: ../../po/../src/verbs.cpp:1847 +msgid "_Open..." +msgstr "_Opna ..." + +#: ../../po/../src/verbs.cpp:1848 +msgid "Open existing document" +msgstr "Opna eit gammalt dokument." + +#: ../../po/../src/verbs.cpp:1849 +msgid "Re_vert" +msgstr "Last om a_tt" + +#: ../../po/../src/verbs.cpp:1850 +msgid "Revert to the last saved version of document (changes will be lost)" +msgstr "" +"GÃ¥ tilbake til sist lagra versjon av dokumentet (alle endringar gÃ¥r tapt)." + +#: ../../po/../src/verbs.cpp:1851 +msgid "_Save" +msgstr "_Lagra" + +#: ../../po/../src/verbs.cpp:1851 +msgid "Save document" +msgstr "Lagra dokumentet." + +#: ../../po/../src/verbs.cpp:1853 +msgid "Save _As..." +msgstr "Lagra _som ..." + +#: ../../po/../src/verbs.cpp:1854 +msgid "Save document under new name" +msgstr "Lagra dokumentet under eit nytt namn." + +#: ../../po/../src/verbs.cpp:1855 +msgid "_Print..." +msgstr "Skriv _ut ..." + +#: ../../po/../src/verbs.cpp:1855 +msgid "Print document" +msgstr "Skriv ut dokument." + +#. TRANSLATORS: "Vacuum Defs" means "Clean up defs" (so as to remove unused definitions) +#: ../../po/../src/verbs.cpp:1858 +msgid "Vac_uum Defs" +msgstr "_Rydd opp i defs-ar" + +#: ../../po/../src/verbs.cpp:1858 +#, fuzzy +msgid "Remove unused predefined items from the <defs> of the document" +msgstr "Fjern ubrukte ting frÃ¥ <defs>-delen av dokumentet." + +#: ../../po/../src/verbs.cpp:1860 +msgid "Print _Direct" +msgstr "Skriv ut _direkte" + +#: ../../po/../src/verbs.cpp:1861 +#, fuzzy +msgid "Print directly without prompting to a file or pipe" +msgstr "Skriv ut dokumentet direkte til ei fil eller gjennom røyret." + +#: ../../po/../src/verbs.cpp:1862 +msgid "Print Previe_w" +msgstr "Førehands_vising" + +#: ../../po/../src/verbs.cpp:1863 +msgid "Preview document printout" +msgstr "Vis korleis dokumentet vil sjÃ¥ ut nÃ¥r det er skrive ut." + +#: ../../po/../src/verbs.cpp:1864 +msgid "_Import..." +msgstr "I_mporter ..." + +#: ../../po/../src/verbs.cpp:1865 +msgid "Import bitmap or SVG image into document" +msgstr "Importer punktbilete eller SVG-bilete i dokumentet." + +#: ../../po/../src/verbs.cpp:1866 +msgid "_Export Bitmap..." +msgstr "_Eksporter punktbilete ..." + +#: ../../po/../src/verbs.cpp:1867 +#, fuzzy +msgid "Export document or selection as a bitmap image" +msgstr "Eksporter dokumentet eller utvalet som eit PNG-bilete." + +#: ../../po/../src/verbs.cpp:1868 +msgid "N_ext Window" +msgstr "Neste _vindauge" + +#: ../../po/../src/verbs.cpp:1869 +msgid "Switch to the next document window" +msgstr "Byt til neste dokumentvindauge." + +#: ../../po/../src/verbs.cpp:1870 +msgid "P_revious Window" +msgstr "Førr_e vindauge" + +#: ../../po/../src/verbs.cpp:1871 +msgid "Switch to the previous document window" +msgstr "Byt til førre dokumentvindauge." + +#: ../../po/../src/verbs.cpp:1872 +msgid "_Close" +msgstr "Lu_kk" + +#: ../../po/../src/verbs.cpp:1873 +msgid "Close window" +msgstr "Lukk vindauget." + +#: ../../po/../src/verbs.cpp:1874 +msgid "_Quit" +msgstr "_Avslutt" + +#: ../../po/../src/verbs.cpp:1874 +msgid "Quit Inkscape" +msgstr "Avslutt Inkscape." + +#. Edit +#: ../../po/../src/verbs.cpp:1877 +msgid "_Undo" +msgstr "_Angra" + +#: ../../po/../src/verbs.cpp:1877 +msgid "Undo last action" +msgstr "Angra siste handling." + +#: ../../po/../src/verbs.cpp:1879 +msgid "_Redo" +msgstr "_Gjer om" + +#: ../../po/../src/verbs.cpp:1880 +msgid "Do again last undone action" +msgstr "Gjer om att sist angra handling." + +#: ../../po/../src/verbs.cpp:1881 +msgid "Cu_t" +msgstr "Klipp _ut" + +#: ../../po/../src/verbs.cpp:1882 +msgid "Cut selection to clipboard" +msgstr "Klipp ut utvalet til utklippstavla." + +#: ../../po/../src/verbs.cpp:1883 +msgid "_Copy" +msgstr "_Kopier" + +#: ../../po/../src/verbs.cpp:1884 +msgid "Copy selection to clipboard" +msgstr "Kopier utvalet til utklippstavla." + +#: ../../po/../src/verbs.cpp:1885 +msgid "_Paste" +msgstr "_Lim inn" + +#: ../../po/../src/verbs.cpp:1886 +#, fuzzy +msgid "Paste objects from clipboard to mouse point" +msgstr "Lim inn objekt frÃ¥ utklippstavla til peikarplasseringa." + +#: ../../po/../src/verbs.cpp:1887 +msgid "Paste _Style" +msgstr "Lim inn st_il" + +#: ../../po/../src/verbs.cpp:1888 +msgid "Apply style of the copied object to selection" +msgstr "Bruk stilen til det kopierte objektet pÃ¥ utvalet." + +#: ../../po/../src/verbs.cpp:1889 +msgid "Paste _In Place" +msgstr "Lim inn pÃ¥ p_lass" + +#: ../../po/../src/verbs.cpp:1890 +#, fuzzy +msgid "Paste objects from clipboard to the original location" +msgstr "Lim inn objekt frÃ¥ utklippstavla til opphavleg plassering." + +#: ../../po/../src/verbs.cpp:1891 +msgid "_Delete" +msgstr "_Slett" + +#: ../../po/../src/verbs.cpp:1892 +msgid "Delete selection" +msgstr "Slett utvalet." + +#: ../../po/../src/verbs.cpp:1893 +msgid "Duplic_ate" +msgstr "Lag ko_pi" + +#: ../../po/../src/verbs.cpp:1894 +#, fuzzy +msgid "Duplicate selected objects" +msgstr "Lag ein kopi av valt(e) objekt." + +#: ../../po/../src/verbs.cpp:1895 +msgid "Clo_ne" +msgstr "Klo_n" + +#: ../../po/../src/verbs.cpp:1896 +msgid "Create a clone of selected object (a copy linked to the original)" +msgstr "Lag ein klon av det valte objektet (ein kopi kopla til opphavet)." + +#: ../../po/../src/verbs.cpp:1897 +msgid "Unlin_k Clone" +msgstr "Kopla la_us klon" + +#: ../../po/../src/verbs.cpp:1898 +msgid "Cut the clone's link to its original" +msgstr "Fjern koplinga mellom klonen og opphavet." + +#: ../../po/../src/verbs.cpp:1899 +msgid "Select _Original" +msgstr "Merk _opphav" + +#: ../../po/../src/verbs.cpp:1900 +msgid "Select the object to which the clone is linked" +msgstr "Merk objektet som klonen er kopla til." + +#. TRANSLATORS: Convert selection to a rectangle with tiled pattern fill +#: ../../po/../src/verbs.cpp:1902 +#, fuzzy +msgid "O_bjects to Pattern" +msgstr "Objekt til møns_ter" + +#: ../../po/../src/verbs.cpp:1903 +msgid "Convert selection to a rectangle with tiled pattern fill" +msgstr "Gjer utvalet om til eit rektangel med mønsterfyll." + +#. TRANSLATORS: Extract objects from a tiled pattern fill +#: ../../po/../src/verbs.cpp:1905 +#, fuzzy +msgid "Pattern to Ob_jects" +msgstr "Mønster til ob_jekt" + +#: ../../po/../src/verbs.cpp:1906 +msgid "Extract objects from a tiled pattern fill" +msgstr "Hent ut objekt frÃ¥ eit mønsterfyll." + +#: ../../po/../src/verbs.cpp:1907 +msgid "Clea_r All" +msgstr "Slett _alle" + +#: ../../po/../src/verbs.cpp:1908 +msgid "Delete all objects from document" +msgstr "Slett alle objekta i dokumentet" + +#: ../../po/../src/verbs.cpp:1909 +msgid "Select Al_l" +msgstr "_Merk alt" + +#: ../../po/../src/verbs.cpp:1910 +msgid "Select all objects or all nodes" +msgstr "Merk alle objekta eller nodane." + +#: ../../po/../src/verbs.cpp:1911 +msgid "Select All in All La_yers" +msgstr "Merk alt i alle _lag" + +#: ../../po/../src/verbs.cpp:1912 +msgid "Select all objects in all visible and unlocked layers" +msgstr "Merk alle objekta i alle synlege og ulÃ¥ste lag." + +#: ../../po/../src/verbs.cpp:1913 +msgid "In_vert Selection" +msgstr "_Omvend utval" + +#: ../../po/../src/verbs.cpp:1914 +msgid "Invert selection (unselect what is selected and select everything else)" +msgstr "Omvend utval (fjern merkinga pÃ¥ det merkte, og vel alt anna)." + +#: ../../po/../src/verbs.cpp:1915 +msgid "Invert in All Layers" +msgstr "Omvend i alle lag" + +#: ../../po/../src/verbs.cpp:1916 +msgid "Invert selection in all visible and unlocked layers" +msgstr "Omvend merking i alle synlege og ulÃ¥ste lag." + +#: ../../po/../src/verbs.cpp:1917 +msgid "D_eselect" +msgstr "F_jern merking" + +#: ../../po/../src/verbs.cpp:1918 +msgid "Deselect any selected objects or nodes" +msgstr "Fjern merking frÃ¥ alle objekt og nodar." + +#. Selection +#: ../../po/../src/verbs.cpp:1921 +msgid "Raise to _Top" +msgstr "Send _fremst" + +#: ../../po/../src/verbs.cpp:1922 +msgid "Raise selection to top" +msgstr "Sendt utvalet fremst." + +#: ../../po/../src/verbs.cpp:1923 +msgid "Lower to _Bottom" +msgstr "Send _bakarst" + +#: ../../po/../src/verbs.cpp:1924 +msgid "Lower selection to bottom" +msgstr "Send utvalet bakarst." + +#: ../../po/../src/verbs.cpp:1925 +msgid "_Raise" +msgstr "_Hev" + +#: ../../po/../src/verbs.cpp:1926 +msgid "Raise selection one step" +msgstr "Hev utvalet eitt steg." + +#: ../../po/../src/verbs.cpp:1927 +msgid "_Lower" +msgstr "_Senk" + +#: ../../po/../src/verbs.cpp:1928 +msgid "Lower selection one step" +msgstr "Senk utvalet eitt steg." + +#: ../../po/../src/verbs.cpp:1929 +msgid "_Group" +msgstr "_Grupper" + +#: ../../po/../src/verbs.cpp:1930 +msgid "Group selected objects" +msgstr "Grupper merkte objekt." + +#: ../../po/../src/verbs.cpp:1932 +#, fuzzy +msgid "Ungroup selected groups" +msgstr "Løys opp gruppering av merkt(e) gruppe(r)." + +#: ../../po/../src/verbs.cpp:1934 +msgid "_Put on Path" +msgstr "_Legg pÃ¥ bane" + +#: ../../po/../src/verbs.cpp:1935 +msgid "Put text on path" +msgstr "Legg teksten pÃ¥ ei bane." + +#: ../../po/../src/verbs.cpp:1936 +msgid "_Remove from Path" +msgstr "_Fjern frÃ¥ bane" + +#: ../../po/../src/verbs.cpp:1937 +msgid "Remove text from path" +msgstr "Fjern teksten frÃ¥ bana." + +#: ../../po/../src/verbs.cpp:1938 +msgid "Remove Manual _Kerns" +msgstr "Fjern manuell _kniping" + +#. TRANSLATORS: "glyph": An image used in the visual representation of characters; +#. roughly speaking, how a character looks. A font is a set of glyphs. +#: ../../po/../src/verbs.cpp:1941 +msgid "Remove all manual kerns and glyph rotations from a text object" +msgstr "" +"Fjern alle manuelle bokstavknipingpar og glyffroteringar frÃ¥ tekstobjekt." + +#: ../../po/../src/verbs.cpp:1943 +msgid "_Union" +msgstr "_Union" + +#: ../../po/../src/verbs.cpp:1944 +msgid "Union of selected objects" +msgstr "Unionen av dei merkte objekta." + +#: ../../po/../src/verbs.cpp:1945 +msgid "_Intersection" +msgstr "_Snitt" + +#: ../../po/../src/verbs.cpp:1946 +msgid "Intersection of selected objects" +msgstr "Snittet av dei merkte objekta." + +#: ../../po/../src/verbs.cpp:1947 +msgid "_Difference" +msgstr "_Differanse" + +#: ../../po/../src/verbs.cpp:1948 +msgid "Difference of selected objects (bottom minus top)" +msgstr "Differansen mellom dei merkte objekta (botn minus topp)." + +#: ../../po/../src/verbs.cpp:1949 +msgid "E_xclusion" +msgstr "_Eksklusjon" + +#: ../../po/../src/verbs.cpp:1950 +msgid "Exclusive OR of selected objects" +msgstr "Eksklusiv eller av dei merkte objekta." + +#: ../../po/../src/verbs.cpp:1951 +msgid "Di_vision" +msgstr "_Objektoppdeling" + +#: ../../po/../src/verbs.cpp:1952 +msgid "Cut the bottom object into pieces" +msgstr "Del opp det nedste objektet i delar." + +#. TRANSLATORS: "to cut a path" is not the same as "to break a path apart" - see the +#. Advanced tutorial for more info +#: ../../po/../src/verbs.cpp:1955 +msgid "Cut _Path" +msgstr "_Baneoppdeling" + +#: ../../po/../src/verbs.cpp:1956 +msgid "Cut the bottom object's stroke into pieces, removing fill" +msgstr "Del bana til det nedste objektet opp i delar og fjern fyllet." + +#. TRANSLATORS: "outset": expand a shape by offsetting the object's path, +#. i.e. by displacing it perpendicular to the path in each point. +#. See also the Advanced Tutorial for explanation. +#: ../../po/../src/verbs.cpp:1960 +msgid "Outs_et" +msgstr "Skubb _ut" + +#: ../../po/../src/verbs.cpp:1961 +#, fuzzy +msgid "Outset selected paths" +msgstr "Skubb ut merkt bane." + +#: ../../po/../src/verbs.cpp:1963 +msgid "O_utset Path by 1 px" +msgstr "Skubb _ut bane 1 piksel" + +#: ../../po/../src/verbs.cpp:1964 +#, fuzzy +msgid "Outset selected paths by 1 px" +msgstr "Skubb ut merkt bane 1 piksel." + +#: ../../po/../src/verbs.cpp:1966 +msgid "O_utset Path by 10 px" +msgstr "Skubb _ut bane 10 pikslar" + +#: ../../po/../src/verbs.cpp:1967 +#, fuzzy +msgid "Outset selected paths by 10 px" +msgstr "Skubb ut merkt bane 10 pikslar." + +#. TRANSLATORS: "inset": contract a shape by offsetting the object's path, +#. i.e. by displacing it perpendicular to the path in each point. +#. See also the Advanced Tutorial for explanation. +#: ../../po/../src/verbs.cpp:1971 +msgid "I_nset" +msgstr "Skubb _inn" + +#: ../../po/../src/verbs.cpp:1972 +#, fuzzy +msgid "Inset selected paths" +msgstr "Skubb inn merkt bane." + +#: ../../po/../src/verbs.cpp:1974 +msgid "I_nset Path by 1 px" +msgstr "Skubb _inn bane 1 piksel" + +#: ../../po/../src/verbs.cpp:1975 +#, fuzzy +msgid "Inset selected paths by 1 px" +msgstr "Skubb inn merkt bane 1 piksel." + +#: ../../po/../src/verbs.cpp:1977 +msgid "I_nset Path by 10 px" +msgstr "Skubb _inn bane 10 pikslar" + +#: ../../po/../src/verbs.cpp:1978 +#, fuzzy +msgid "Inset selected paths by 10 px" +msgstr "Skubb inn merkt bane 10 pikslar." + +#: ../../po/../src/verbs.cpp:1980 +msgid "D_ynamic Offset" +msgstr "Dyna_misk forskyving" + +#: ../../po/../src/verbs.cpp:1980 +msgid "Create a dynamic offset object" +msgstr "Lag ei dynamisk forskyving." + +#: ../../po/../src/verbs.cpp:1982 +msgid "_Linked Offset" +msgstr "_Lenkja forskyving" + +#: ../../po/../src/verbs.cpp:1983 +msgid "Create a dynamic offset object linked to the original path" +msgstr "Lag ei dynamisk forskyving kopla til opphavsbana." + +#: ../../po/../src/verbs.cpp:1985 +msgid "_Stroke to Path" +msgstr "Strek til ba_ne" + +#: ../../po/../src/verbs.cpp:1986 +#, fuzzy +msgid "Convert selected strokes to paths" +msgstr "Gjer merkte strekar om til baner." + +#: ../../po/../src/verbs.cpp:1987 +msgid "Si_mplify" +msgstr "_Forenkla" + +#: ../../po/../src/verbs.cpp:1988 +#, fuzzy +msgid "Simplify selected paths by removing extra nodes" +msgstr "Forenkla merkt(e) bane(r) ved Ã¥ fjerna nodar." + +#: ../../po/../src/verbs.cpp:1989 +msgid "_Reverse" +msgstr "Snu _retning" + +#: ../../po/../src/verbs.cpp:1990 +#, fuzzy +msgid "Reverses the direction of selected paths; useful for flipping markers" +msgstr "" +"Snur retninga pÃ¥ merkt(e) bane(r). Dette er nyttig for Ã¥ endra retninga pÃ¥ " +"pilmarkørar." + +#. TRANSLATORS: "to trace" means "to convert a bitmap to vector graphics" (to vectorize) +#: ../../po/../src/verbs.cpp:1992 +msgid "_Trace Bitmap" +msgstr "_Teikn av punktbilete" + +#: ../../po/../src/verbs.cpp:1993 +msgid "Convert bitmap object to paths" +msgstr "Gjer om punktbilete til baner" + +#: ../../po/../src/verbs.cpp:1994 +msgid "_Make a Bitmap Copy" +msgstr "_Lag punktbiletkopi" + +#: ../../po/../src/verbs.cpp:1995 +msgid "Export selection to a bitmap and insert it into document" +msgstr "" +"Eksporter utvalet til eit punktbilete, og sett dette inni i dokumentet." + +#: ../../po/../src/verbs.cpp:1996 +msgid "_Combine" +msgstr "_SlÃ¥ saman" + +#: ../../po/../src/verbs.cpp:1997 +msgid "Combine several paths into one" +msgstr "SlÃ¥ saman fleire baner til éi." + +#. TRANSLATORS: "to cut a path" is not the same as "to break a path apart" - see the +#. Advanced tutorial for more info +#: ../../po/../src/verbs.cpp:2000 +msgid "Break _Apart" +msgstr "Br_yt opp" + +#: ../../po/../src/verbs.cpp:2001 +#, fuzzy +msgid "Break selected paths into subpaths" +msgstr "Bryt opp merkt(e) bane(r) til delbaner." + +#: ../../po/../src/verbs.cpp:2002 +msgid "Gri_d Arrange..." +msgstr "Or_dna i rutenett ..." + +#: ../../po/../src/verbs.cpp:2003 +msgid "Arrange selection in grid pattern" +msgstr "Ordna utvalet i eit rutemønster." + +#. Layer +#: ../../po/../src/verbs.cpp:2005 +msgid "_Add Layer..." +msgstr "_Legg til lag ..." + +#: ../../po/../src/verbs.cpp:2006 +msgid "Create a new layer" +msgstr "Lag eit nytt lag." + +#: ../../po/../src/verbs.cpp:2007 +msgid "Re_name Layer..." +msgstr "_Endra namn pÃ¥ lag ..." + +#: ../../po/../src/verbs.cpp:2008 +msgid "Rename the current layer" +msgstr "Endra namn pÃ¥ laget." + +#: ../../po/../src/verbs.cpp:2009 +msgid "Switch to Layer Abov_e" +msgstr "Byt til laget _over" + +#: ../../po/../src/verbs.cpp:2010 +msgid "Switch to the layer above the current" +msgstr "Byt til lag som ligg over dette." + +#: ../../po/../src/verbs.cpp:2011 +msgid "Switch to Layer Belo_w" +msgstr "Byt til laget _under" + +#: ../../po/../src/verbs.cpp:2012 +msgid "Switch to the layer below the current" +msgstr "Byt til laget som ligg under dette." + +#: ../../po/../src/verbs.cpp:2013 +msgid "Move Selection to Layer Abo_ve" +msgstr "Send utval til laget ov_er" + +#: ../../po/../src/verbs.cpp:2014 +msgid "Move selection to the layer above the current" +msgstr "Send utvalet til laget som ligg over dette." + +#: ../../po/../src/verbs.cpp:2015 +msgid "Move Selection to Layer Bel_ow" +msgstr "Send utval til laget u_nder" + +#: ../../po/../src/verbs.cpp:2016 +msgid "Move selection to the layer below the current" +msgstr "Send utvalet til laget som ligg under dette." + +#: ../../po/../src/verbs.cpp:2017 +msgid "Layer to _Top" +msgstr "Send lag _fremst" + +#: ../../po/../src/verbs.cpp:2018 +msgid "Raise the current layer to the top" +msgstr "Send dette laget fremst." + +#: ../../po/../src/verbs.cpp:2019 +msgid "Layer to _Bottom" +msgstr "Send lag _bakarst" + +#: ../../po/../src/verbs.cpp:2020 +msgid "Lower the current layer to the bottom" +msgstr "Send dette laget bakarst." + +#: ../../po/../src/verbs.cpp:2021 +msgid "_Raise Layer" +msgstr "_Hev lag" + +#: ../../po/../src/verbs.cpp:2022 +msgid "Raise the current layer" +msgstr "Hev dette laget." + +#: ../../po/../src/verbs.cpp:2023 +msgid "_Lower Layer" +msgstr "_Senk lag" + +#: ../../po/../src/verbs.cpp:2024 +msgid "Lower the current layer" +msgstr "Senk dette laget." + +#: ../../po/../src/verbs.cpp:2025 +msgid "_Delete Current Layer" +msgstr "_Slett lag" + +#: ../../po/../src/verbs.cpp:2026 +msgid "Delete the current layer" +msgstr "Slett laget." + +#. Object +#: ../../po/../src/verbs.cpp:2029 +#, fuzzy +msgid "Rotate _90° CW" +msgstr "Roter _90° mot høgre" + +#: ../../po/../src/verbs.cpp:2030 +#, fuzzy +msgid "Rotate selection 90° clockwise" +msgstr "Roter utvalet 90° med klokka." + +#: ../../po/../src/verbs.cpp:2031 +#, fuzzy +msgid "Rotate 9_0° CCW" +msgstr "Roter 9_0° mot venstre" + +#: ../../po/../src/verbs.cpp:2032 +#, fuzzy +msgid "Rotate selection 90° counter-clockwise" +msgstr "Roter utvalet 90° mot klokka." + +#: ../../po/../src/verbs.cpp:2033 +msgid "Remove _Transformations" +msgstr "Fjern _omformingar" + +#: ../../po/../src/verbs.cpp:2034 +msgid "Remove transformations from object" +msgstr "Fjern omformingar frÃ¥ objektet" + +#: ../../po/../src/verbs.cpp:2035 +msgid "_Object to Path" +msgstr "Objekt til b_ane" + +#: ../../po/../src/verbs.cpp:2036 +#, fuzzy +msgid "Convert selected objects to paths" +msgstr "Gjer merkt(e) objekt om til bane(r)." + +#: ../../po/../src/verbs.cpp:2037 +msgid "_Flow into Frame" +msgstr "La tekst flyta i _ramme" + +#: ../../po/../src/verbs.cpp:2038 +#, fuzzy +msgid "Put text into frames" +msgstr "Legg teksten i ramme(r)." + +#: ../../po/../src/verbs.cpp:2039 +msgid "_Unflow" +msgstr "Fikser _tekst" + +#: ../../po/../src/verbs.cpp:2040 +msgid "Remove text from frame (creates a single-line text object)" +msgstr "Fjern teksten frÃ¥ ramma (lagar tekstobjekt pÃ¥ éi linje)." + +#: ../../po/../src/verbs.cpp:2041 +msgid "_Convert to Text" +msgstr "_Gjer om til tekst" + +#: ../../po/../src/verbs.cpp:2042 +#, fuzzy +msgid "Convert flowed text to regular text objects (preserves appearance)" +msgstr "Gjer flyttekst om til eit vanlig tekstobjekt (lik utsjÃ¥nad)." + +#: ../../po/../src/verbs.cpp:2044 +#, fuzzy +msgid "Flip _Horizontal" +msgstr "Spegla _vassrett" + +#: ../../po/../src/verbs.cpp:2044 +#, fuzzy +msgid "Flips selected objects horizontally" +msgstr "Juster merkte nodar vassrett" + +#: ../../po/../src/verbs.cpp:2047 +#, fuzzy +msgid "Flip _Vertical" +msgstr "Spegla _loddrett" + +#: ../../po/../src/verbs.cpp:2047 +#, fuzzy +msgid "Flips selected objects vertically" +msgstr "Juster merkte nodar loddrett" + +#. Tools +#: ../../po/../src/verbs.cpp:2051 +msgid "Select" +msgstr "Vel" + +#: ../../po/../src/verbs.cpp:2052 +msgid "Select and transform objects" +msgstr "Merk og form om objekt." + +#: ../../po/../src/verbs.cpp:2053 +msgid "Node Edit" +msgstr "Noderedigering" + +#: ../../po/../src/verbs.cpp:2054 +msgid "Edit path nodes or control handles" +msgstr "Rediger banenodar og kontrollpunkt." + +#: ../../po/../src/verbs.cpp:2056 +msgid "Create rectangles and squares" +msgstr "Teikn rektangel og kvadrat." + +#: ../../po/../src/verbs.cpp:2058 +msgid "Create circles, ellipses, and arcs" +msgstr "Teikn sirklar, ellipsar og bogar." + +#: ../../po/../src/verbs.cpp:2060 +msgid "Create stars and polygons" +msgstr "Teikn stjerner og mangekantar." + +#: ../../po/../src/verbs.cpp:2062 +msgid "Create spirals" +msgstr "Teikn spiralar." + +#: ../../po/../src/verbs.cpp:2064 +msgid "Draw freehand lines" +msgstr "Teikn frihandslinjer." + +#: ../../po/../src/verbs.cpp:2066 +msgid "Draw Bezier curves and straight lines" +msgstr "Teikn Bezier-kurver og rette linjer." + +#: ../../po/../src/verbs.cpp:2068 +msgid "Draw calligraphic lines" +msgstr "Teikn kalligrafiske linjer." + +#: ../../po/../src/verbs.cpp:2070 +msgid "Create and edit text objects" +msgstr "Lag og endra tekstobjekt." + +#: ../../po/../src/verbs.cpp:2072 +msgid "Create and edit gradients" +msgstr "Lag og endra fargeovergangar." + +#: ../../po/../src/verbs.cpp:2074 +msgid "Zoom in or out" +msgstr "Forstørr inn og ut." + +#: ../../po/../src/verbs.cpp:2076 +msgid "Pick averaged colors from image" +msgstr "Plukk opp snittfargar frÃ¥ biletet." + +#: ../../po/../src/verbs.cpp:2078 +#, fuzzy +msgid "Create connectors" +msgstr "Lag eit nytt dokument." + +#. Tool prefs +#: ../../po/../src/verbs.cpp:2081 +msgid "Selector Preferences" +msgstr "_Veljaroppsett" + +#: ../../po/../src/verbs.cpp:2082 +#, fuzzy +msgid "Open Preferences for the Selector tool" +msgstr "Opna oppsettdialogen for objektveljarverktøyet." + +#: ../../po/../src/verbs.cpp:2083 +msgid "Node Tool Preferences" +msgstr "Nodeverktøyoppsett" + +#: ../../po/../src/verbs.cpp:2084 +#, fuzzy +msgid "Open Preferences for the Node tool" +msgstr "Opna oppsettdialogen for nodeverktøyet." + +#: ../../po/../src/verbs.cpp:2085 +msgid "Rectangle Preferences" +msgstr "Rektangeloppsett" + +#: ../../po/../src/verbs.cpp:2086 +#, fuzzy +msgid "Open Preferences for the Rectangle tool" +msgstr "Opna oppsettdialogen for rektangelverktøyet." + +#: ../../po/../src/verbs.cpp:2087 +msgid "Ellipse Preferences" +msgstr "Ellipseoppsett" + +#: ../../po/../src/verbs.cpp:2088 +#, fuzzy +msgid "Open Preferences for the Ellipse tool" +msgstr "Opna oppsettdialogen for ellipseverktøyet." + +#: ../../po/../src/verbs.cpp:2089 +msgid "Star Preferences" +msgstr "Stjerneoppsett" + +#: ../../po/../src/verbs.cpp:2090 +#, fuzzy +msgid "Open Preferences for the Star tool" +msgstr "Opna oppsettdialogen for stjerneverktøyet." + +#: ../../po/../src/verbs.cpp:2091 +msgid "Spiral Preferences" +msgstr "Spiraloppsett" + +#: ../../po/../src/verbs.cpp:2092 +#, fuzzy +msgid "Open Preferences for the Spiral tool" +msgstr "Opna oppsettdialogen for spiralverktøyet." + +#: ../../po/../src/verbs.cpp:2093 +msgid "Pencil Preferences" +msgstr "Blyantoppsett" + +#: ../../po/../src/verbs.cpp:2094 +#, fuzzy +msgid "Open Preferences for the Pencil tool" +msgstr "Opna oppsettdialogen for blyantverktøyet." + +#: ../../po/../src/verbs.cpp:2095 +msgid "Pen Preferences" +msgstr "Pennoppsett" + +#: ../../po/../src/verbs.cpp:2096 +#, fuzzy +msgid "Open Preferences for the Pen tool" +msgstr "Opna oppsettdialogen for pennverktøyet." + +#: ../../po/../src/verbs.cpp:2097 +msgid "Calligraphic Preferences" +msgstr "Kalligrafioppsett" + +#: ../../po/../src/verbs.cpp:2098 +#, fuzzy +msgid "Open Preferences for the Calligraphy tool" +msgstr "Opna oppsettdialogen for kalligrafiverktøyet." + +#: ../../po/../src/verbs.cpp:2099 +msgid "Text Preferences" +msgstr "Tekstoppsett" + +#: ../../po/../src/verbs.cpp:2100 +#, fuzzy +msgid "Open Preferences for the Text tool" +msgstr "Opna oppsettdialogen for tekstverktøyet." + +#: ../../po/../src/verbs.cpp:2101 +msgid "Gradient Preferences" +msgstr "Fargeovergangsoppsett" + +#: ../../po/../src/verbs.cpp:2102 +#, fuzzy +msgid "Open Preferences for the Gradient tool" +msgstr "Opna oppsettdialogen for fargeovergangar." + +#: ../../po/../src/verbs.cpp:2103 +msgid "Zoom Preferences" +msgstr "Forstørringsoppsett" + +#: ../../po/../src/verbs.cpp:2104 +#, fuzzy +msgid "Open Preferences for the Zoom tool" +msgstr "Opna oppsettdialogen for forstørringsverktøyet." + +#: ../../po/../src/verbs.cpp:2105 +msgid "Dropper Preferences" +msgstr "Fargeplukkaroppsett" + +#: ../../po/../src/verbs.cpp:2106 +#, fuzzy +msgid "Open Preferences for the Dropper tool" +msgstr "Opna oppsettdialogen for fargeplukkarverktøyet." + +#: ../../po/../src/verbs.cpp:2107 +#, fuzzy +msgid "Connector Preferences" +msgstr "_Veljaroppsett" + +#: ../../po/../src/verbs.cpp:2108 +#, fuzzy +msgid "Open Preferences for the Connector tool" +msgstr "Opna oppsettdialogen for objektveljarverktøyet." + +#. Zoom/View +#: ../../po/../src/verbs.cpp:2111 +msgid "Zoom In" +msgstr "Forstørr" + +#: ../../po/../src/verbs.cpp:2111 +msgid "Zoom in" +msgstr "Forstørr" + +#: ../../po/../src/verbs.cpp:2112 +msgid "Zoom Out" +msgstr "Forminsk." + +#: ../../po/../src/verbs.cpp:2112 +msgid "Zoom out" +msgstr "Forminsk" + +#: ../../po/../src/verbs.cpp:2113 +msgid "_Rulers" +msgstr "_Linjalar" + +#: ../../po/../src/verbs.cpp:2113 +msgid "Show or hide the canvas rulers" +msgstr "Vis eller skjul linjalar." + +#: ../../po/../src/verbs.cpp:2114 +msgid "Scroll_bars" +msgstr "_Rullefelt" + +#: ../../po/../src/verbs.cpp:2114 +msgid "Show or hide the canvas scrollbars" +msgstr "Vis eller skjul rullefelt." + +#: ../../po/../src/verbs.cpp:2115 +msgid "_Grid" +msgstr "_Rutenett" + +#: ../../po/../src/verbs.cpp:2116 +msgid "G_uides" +msgstr "_Hjelpelinjer" + +#: ../../po/../src/verbs.cpp:2117 +msgid "Nex_t Zoom" +msgstr "_Neste forstørring" + +#: ../../po/../src/verbs.cpp:2117 +msgid "Next zoom (from the history of zooms)" +msgstr "Neste forstørring (frÃ¥ forstørringsloggen)." + +#: ../../po/../src/verbs.cpp:2119 +msgid "Pre_vious Zoom" +msgstr "_Førre forstørring" + +#: ../../po/../src/verbs.cpp:2119 +msgid "Previous zoom (from the history of zooms)" +msgstr "Førre forstørring (frÃ¥ forstørringsloggen)." + +#: ../../po/../src/verbs.cpp:2121 +msgid "Zoom 1:_1" +msgstr "Forstørr 1:_1" + +#: ../../po/../src/verbs.cpp:2121 +msgid "Zoom to 1:1" +msgstr "Forstørr til 1:1." + +#: ../../po/../src/verbs.cpp:2123 +msgid "Zoom 1:_2" +msgstr "Forstørr 1:_2" + +#: ../../po/../src/verbs.cpp:2123 +msgid "Zoom to 1:2" +msgstr "Forstørr til 1:2." + +#: ../../po/../src/verbs.cpp:2125 +msgid "_Zoom 2:1" +msgstr "F_orstørr 2:1" + +#: ../../po/../src/verbs.cpp:2125 +msgid "Zoom to 2:1" +msgstr "Forstørr til 2:1." + +#: ../../po/../src/verbs.cpp:2128 +msgid "_Fullscreen" +msgstr "Fulls_kjerm" + +#: ../../po/../src/verbs.cpp:2128 +msgid "Stretch this document window to full screen" +msgstr "Strekk dokumentvindauget til Ã¥ dekkja heile skjermen." + +#: ../../po/../src/verbs.cpp:2131 +msgid "Duplic_ate Window" +msgstr "_Lag kopi av vindauge" + +#: ../../po/../src/verbs.cpp:2131 +msgid "Open a new window with the same document" +msgstr "Opna eit nytt vindauge med same dokumentet." + +#: ../../po/../src/verbs.cpp:2133 +msgid "_New View Preview" +msgstr "_Førehandsvising av ny vising" + +#: ../../po/../src/verbs.cpp:2134 +msgid "New View Preview" +msgstr "Førehandsvising av ny vising" + +#. "view_new_preview" +#: ../../po/../src/verbs.cpp:2136 +#, fuzzy +msgid "_Normal" +msgstr "Vanleg" + +#: ../../po/../src/verbs.cpp:2137 +msgid "Switch to normal display mode" +msgstr "" + +#: ../../po/../src/verbs.cpp:2138 +#, fuzzy +msgid "_Outline" +msgstr "Boksomriss" + +#: ../../po/../src/verbs.cpp:2139 +msgid "Switch to outline (wireframe) display mode" +msgstr "" + +#: ../../po/../src/verbs.cpp:2141 +msgid "Ico_n Preview" +msgstr "Føre_handsvis ikon" + +#: ../../po/../src/verbs.cpp:2142 +msgid "Open a window to preview items at different icon resolutions" +msgstr "" +"Opna eit vindauge for førehandsvising av vald objekt som ikon i fleire " +"storleikar." + +#: ../../po/../src/verbs.cpp:2144 +msgid "Zoom to fit page in window" +msgstr "Forstørr til Ã¥ visa heile sida i vindauget." + +#: ../../po/../src/verbs.cpp:2145 +msgid "Page _Width" +msgstr "Side_breidd" + +#: ../../po/../src/verbs.cpp:2146 +msgid "Zoom to fit page width in window" +msgstr "Forstørr til Ã¥ visa heile sidebreidda i vindauget." + +#: ../../po/../src/verbs.cpp:2148 +msgid "Zoom to fit drawing in window" +msgstr "Forstørr slik at teikninga dekkjer heile vindauget." + +#: ../../po/../src/verbs.cpp:2150 +msgid "Zoom to fit selection in window" +msgstr "Forstørr slik at utvalet dekkjer heile vindauget." + +#. Dialogs +#: ../../po/../src/verbs.cpp:2153 +msgid "In_kscape Preferences..." +msgstr "_Inkscape-oppsett ..." + +#: ../../po/../src/verbs.cpp:2154 +msgid "Global Inkscape preferences" +msgstr "Globale Inkscape-innstillingar." + +#: ../../po/../src/verbs.cpp:2155 +msgid "_Document Preferences..." +msgstr "_Dokumentoppsett" + +#: ../../po/../src/verbs.cpp:2156 +msgid "Preferences saved with the document" +msgstr "Innstillingar lagra i dokumentet." + +#: ../../po/../src/verbs.cpp:2157 +msgid "_Fill and Stroke..." +msgstr "_Fyll og strek ..." + +#: ../../po/../src/verbs.cpp:2158 +msgid "Fill and Stroke dialog" +msgstr "«Fyll og strek»-dialogen." + +#. TRANSLATORS: "Swatches" means: color samples +#: ../../po/../src/verbs.cpp:2160 +msgid "S_watches..." +msgstr "_Fargesamlingar ..." + +#: ../../po/../src/verbs.cpp:2161 +msgid "View color swatches" +msgstr "Vis fargesamlingar." + +#: ../../po/../src/verbs.cpp:2162 +msgid "Transfor_m..." +msgstr "Fo_rm om ..." + +#: ../../po/../src/verbs.cpp:2163 +msgid "Transform dialog" +msgstr "Omformingsdialog." + +#: ../../po/../src/verbs.cpp:2164 +msgid "_Align and Distribute..." +msgstr "_Juster og fordel ..." + +#: ../../po/../src/verbs.cpp:2165 +msgid "Align and Distribute dialog" +msgstr "«Juster og fordel»-dialogen." + +#: ../../po/../src/verbs.cpp:2166 +msgid "_Text and Font..." +msgstr "_Tekst og skrift ..." + +#: ../../po/../src/verbs.cpp:2167 +msgid "Text and Font dialog" +msgstr "«Tekst og skrift»-dialogen." + +#: ../../po/../src/verbs.cpp:2168 +msgid "_XML Editor..." +msgstr "_XML-redigering ..." + +#: ../../po/../src/verbs.cpp:2169 +msgid "XML Editor" +msgstr "XML-redigering." + +#: ../../po/../src/verbs.cpp:2170 +msgid "_Find..." +msgstr "_Finn ..." + +#: ../../po/../src/verbs.cpp:2171 +msgid "Find objects in document" +msgstr "Søk etter objekt i dokument." + +#: ../../po/../src/verbs.cpp:2172 +msgid "_Messages..." +msgstr "_Meldingar ..." + +#: ../../po/../src/verbs.cpp:2173 +msgid "View debug messages" +msgstr "Vis feilsøkingsmeldingar." + +#: ../../po/../src/verbs.cpp:2174 +msgid "S_cripts..." +msgstr "Skri_pt ..." + +#: ../../po/../src/verbs.cpp:2175 +msgid "Run scripts" +msgstr "Køyr skript." + +#: ../../po/../src/verbs.cpp:2176 +msgid "Show/Hide D_ialogs" +msgstr "V_is/skjul dialogar" + +#: ../../po/../src/verbs.cpp:2177 +msgid "Show or hide all active dialogs" +msgstr "Vis eller skjul alle aktive dialogar." + +#. TRANSLATORS: "Tile clones" means: "Create tiled clones" +#: ../../po/../src/verbs.cpp:2179 +msgid "Tile clones..." +msgstr "Flislegg klonar ..." + +#: ../../po/../src/verbs.cpp:2180 +msgid "Create and arrange multiple clones of selection" +msgstr "Lag og set opp fleire klonar av utvalet." + +#: ../../po/../src/verbs.cpp:2181 +msgid "_Object Properties..." +msgstr "_Objekteigenskapar ..." + +#: ../../po/../src/verbs.cpp:2182 +msgid "Object Properties dialog" +msgstr "«Objekteigenskapar»-dialogen." + +#: ../../po/../src/verbs.cpp:2185 +msgid "_Connect to Jabber server..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2185 +msgid "Connect to a Jabber server" +msgstr "" + +#: ../../po/../src/verbs.cpp:2187 +#, fuzzy +msgid "Share with _user..." +msgstr "Lagra _som ..." + +#: ../../po/../src/verbs.cpp:2187 +msgid "Establish a whiteboard session with another Jabber user" +msgstr "" + +#: ../../po/../src/verbs.cpp:2189 +msgid "Share with _chatroom..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2189 +msgid "" +"Join a chatroom to start a new whiteboard session or join one in progress" +msgstr "" + +#: ../../po/../src/verbs.cpp:2191 +msgid "_Dump XML node tracker" +msgstr "" + +#: ../../po/../src/verbs.cpp:2191 +msgid "Dump the contents of the XML tracker to the console" +msgstr "" + +#: ../../po/../src/verbs.cpp:2193 +msgid "_Open session file..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2193 +msgid "Open and browse through records of past whiteboard sessions" +msgstr "" + +#: ../../po/../src/verbs.cpp:2195 +msgid "Session file playback" +msgstr "" + +#: ../../po/../src/verbs.cpp:2197 +msgid "_Disconnect from session" +msgstr "" + +#: ../../po/../src/verbs.cpp:2199 +msgid "Disconnect from _server" +msgstr "" + +#: ../../po/../src/verbs.cpp:2201 +msgid "_Input Devices..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2202 +msgid "Configure extended input devices" +msgstr "" + +#. Help +#: ../../po/../src/verbs.cpp:2205 +msgid "_Keys and Mouse" +msgstr "_Tastatur og mus" + +#: ../../po/../src/verbs.cpp:2206 +msgid "Key and mouse shortcuts reference" +msgstr "Oversikt over snøggtastar og musebindingar." + +#: ../../po/../src/verbs.cpp:2207 +msgid "About E_xtensions" +msgstr "Om _utvidingar" + +#: ../../po/../src/verbs.cpp:2208 +msgid "About Extensions..." +msgstr "Om utvidingar ..." + +#: ../../po/../src/verbs.cpp:2209 +msgid "About _Memory" +msgstr "Om _minne" + +#: ../../po/../src/verbs.cpp:2210 +msgid "About Memory..." +msgstr "Om minne ..." + +#: ../../po/../src/verbs.cpp:2211 +msgid "_About Inkscape" +msgstr "_Om Inkscape" + +#. "help_about" +#. new HelpVerb(SP_VERB_SHOW_LICENSE, "ShowLicense", N_("Modifying or Redistributing Inkscape"), +#. N_("Show license to modify and/or redistribute Inkscape: GNU GPL"), NULL), +#. Tutorials +#: ../../po/../src/verbs.cpp:2217 +msgid "Inkscape: _Basic" +msgstr "Inkscape: _Det grunnleggjande" + +#: ../../po/../src/verbs.cpp:2218 +msgid "Getting started with Inkscape" +msgstr "Ei grunnleggjande innføring i Inkscape." + +#. "tutorial_basic" +#: ../../po/../src/verbs.cpp:2219 +msgid "Inkscape: _Shapes" +msgstr "Inkscape: _Figurarar" + +#: ../../po/../src/verbs.cpp:2220 +msgid "Using shape tools to create and edit shapes" +msgstr "Bruk av figurverktøya til Ã¥ laga og redigera figurar." + +#: ../../po/../src/verbs.cpp:2221 +msgid "Inkscape: _Advanced" +msgstr "Inkscape: _Avansert" + +#: ../../po/../src/verbs.cpp:2222 +msgid "Advanced Inkscape topics" +msgstr "Meir avanserte Inkscape-emne." + +#. "tutorial_advanced" +#. TRANSLATORS: "to trace" means "to convert a bitmap to vector graphics" (to vectorize) +#: ../../po/../src/verbs.cpp:2224 +msgid "Inkscape: T_racing" +msgstr "Inkscape: _Biletavteikning" + +#: ../../po/../src/verbs.cpp:2225 +msgid "Using bitmap tracing" +msgstr "Bruk av biletavteikningsfunksjonen." + +#. "tutorial_tracing" +#: ../../po/../src/verbs.cpp:2226 +msgid "Inkscape: _Calligraphy" +msgstr "Inkscape: _Kalligrafi" + +#: ../../po/../src/verbs.cpp:2227 +msgid "Using the Calligraphy pen tool" +msgstr "Bruk av kalligrafiverktøyet." + +#: ../../po/../src/verbs.cpp:2228 +msgid "_Elements of Design" +msgstr "_Grafisk formgjeving" + +#: ../../po/../src/verbs.cpp:2229 +msgid "Principles of design in the tutorial form" +msgstr "Grunnprinsippa i grafisk formgjeving." + +#. "tutorial_design" +#: ../../po/../src/verbs.cpp:2230 +msgid "_Tips and Tricks" +msgstr "_Tips og triks" + +#: ../../po/../src/verbs.cpp:2231 +msgid "Miscellaneous tips and tricks" +msgstr "Ymse tips og triks." + +#. "tutorial_tips" +#. Effect +#: ../../po/../src/verbs.cpp:2234 +msgid "Previous Effect" +msgstr "Førre effekt" + +#: ../../po/../src/verbs.cpp:2235 +msgid "Repeat the last effect with the same settings" +msgstr "Køyr førre effekt om att med same val." + +#. "tutorial_tips" +#: ../../po/../src/verbs.cpp:2236 +msgid "Previous Effect Settings..." +msgstr "Førre effekt-innstillingar ..." + +#: ../../po/../src/verbs.cpp:2237 +msgid "Repeat the last effect with new settings" +msgstr "Køyr førre effekt om att med nye val." + +#: ../../po/../src/widgets/dash-selector.cpp:106 +msgid "Dash pattern" +msgstr "Stiplingsmønster" + +#: ../../po/../src/widgets/dash-selector.cpp:121 +msgid "Pattern offset" +msgstr "Mønsterforskyving" + +#: ../../po/../src/widgets/desktop-widget.cpp:240 +msgid "Zoom drawing if window size changes" +msgstr "Forstørr teikninga ved endring av vindaugestorleik" + +#: ../../po/../src/widgets/desktop-widget.cpp:298 +msgid "Cursor coordinates" +msgstr "Peikarkoordinatar" + +#. display the initial welcome message in the statusbar +#: ../../po/../src/widgets/desktop-widget.cpp:324 +msgid "" +"Welcome to Inkscape! Use shape or freehand tools to create objects; " +"use selector (arrow) to move or transform them." +msgstr "" +"Velkommen til Inkscape! Du kan bruka ferdige figurar eller teikna nye " +"for hand. Bruk objektveljaren (pila) for Ã¥ flytta eller forma om objekta." + +#: ../../po/../src/widgets/desktop-widget.cpp:372 +#, c-format +msgid "%s: %d - Inkscape" +msgstr "%s: %d – Inkscape" + +#: ../../po/../src/widgets/desktop-widget.cpp:374 +#, c-format +msgid "%s - Inkscape" +msgstr "%s – Inkscape" + +#: ../../po/../src/widgets/desktop-widget.cpp:532 +#, c-format +msgid "" +"Save changes to document \"%s\" before " +"closing?\n" +"\n" +"If you close without saving, your changes will be discarded." +msgstr "" +"Vil du lagra endringane i «%s»?\n" +"\n" +"Du vil mista alle endringane dine om du lukkar utan Ã¥ lagra." + +#: ../../po/../src/widgets/desktop-widget.cpp:548 +#: ../../po/../src/widgets/desktop-widget.cpp:612 +msgid "Close _without saving" +msgstr "Lukk _utan Ã¥ lagra" + +#: ../../po/../src/widgets/desktop-widget.cpp:595 +#, c-format +msgid "" +"The file \"%s\" was saved with a " +"format (%s) that may cause data loss!\n" +"\n" +"Do you want to save this file in another format?" +msgstr "" +"Fila «%s» vart lagra i eit format («%" +"s») som kan medføra datatap.\n" +"\n" +"Vil du lagra fila i eit anna format?" + +#. Family frame +#: ../../po/../src/widgets/font-selector.cpp:156 +msgid "Font family" +msgstr "Skrifttype" + +#. Style frame +#: ../../po/../src/widgets/font-selector.cpp:184 +msgid "Style" +msgstr "Stil" + +#: ../../po/../src/widgets/font-selector.cpp:219 +msgid "Font size:" +msgstr "Skriftstorleik:" + +#. TRANSLATORS: Test string used in text and font dialog (when no +#. * text has been entered) to get a preview of the font. Choose +#. * some representative characters that users of your locale will be +#. * interested in. +#: ../../po/../src/widgets/font-selector.cpp:554 +msgid "AaBbCcIiPpQq12368.;/()" +msgstr "AaBbCcIiPpQqÆæØøÅå12368.;/()–«»" + +#: ../../po/../src/widgets/gradient-selector.cpp:137 +#: ../../po/../src/widgets/gradient-toolbar.cpp:524 +msgid "Duplicate" +msgstr "Lag kopi" + +#: ../../po/../src/widgets/gradient-selector.cpp:142 +#: ../../po/../src/widgets/gradient-toolbar.cpp:535 +msgid "Edit..." +msgstr "Rediger ..." + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/pservers.html#LinearGradientSpreadMethodAttribute +#: ../../po/../src/widgets/gradient-selector.cpp:159 +msgid "" +"Whether to fill with flat color beyond the ends of the gradient vector " +"(spreadMethod=\"pad\"), or repeat the gradient in the same direction " +"(spreadMethod=\"repeat\"), or repeat the gradient in alternating opposite " +"directions (spreadMethod=\"reflect\")" +msgstr "" +"Om det skal fyllast med ein einskildfarge utanfor fargeovergang " +"(spreadMethod=\"pad\"), om fargeovergangen skal gjentakast i same retning " +"(spreadMethod=\"repeat\") eller om fargeovergangen skal gjentakast i motsatt " +"retning (spreadMethod=\"reflect\")" + +#: ../../po/../src/widgets/gradient-selector.cpp:165 +msgid "none" +msgstr "ingen" + +#: ../../po/../src/widgets/gradient-selector.cpp:169 +msgid "reflected" +msgstr "reflektert" + +#: ../../po/../src/widgets/gradient-selector.cpp:173 +msgid "direct" +msgstr "retta" + +#: ../../po/../src/widgets/gradient-selector.cpp:181 +msgid "Repeat:" +msgstr "Gjenta:" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:217 +msgid "No gradients" +msgstr "Ingen fargeovergangar" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:226 +msgid "Nothing selected" +msgstr "Ingenting vald" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:237 +msgid "No gradients in selection" +msgstr "Ingen fargeovergangar i utvalet" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:247 +msgid "Multiple gradients" +msgstr "Fleire fargeovergangar" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:525 +msgid "" +"If the gradient is used by more than one object, create a copy of it for the " +"selected object(s)" +msgstr "" +"Lag ein kopi av fargeovergangen viss han vert brukt av meir enn eitt objekt." + +#: ../../po/../src/widgets/gradient-toolbar.cpp:536 +msgid "Edit the stops of the gradient" +msgstr "Endra stopp til fargeovergang" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:593 +#: ../../po/../src/widgets/toolbox.cpp:1103 +#: ../../po/../src/widgets/toolbox.cpp:1192 +#: ../../po/../src/widgets/toolbox.cpp:1485 +#: ../../po/../src/widgets/toolbox.cpp:1534 +#: ../../po/../src/widgets/toolbox.cpp:1766 +#: ../../po/../src/widgets/toolbox.cpp:1801 +#: ../../po/../src/widgets/toolbox.cpp:2331 +#: ../../po/../src/widgets/toolbox.cpp:2370 +msgid "New:" +msgstr "Ny:" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:606 +msgid "Create linear gradient" +msgstr "Lag lineær fargeovergang" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:620 +msgid "Create radial (elliptic or circular) gradient" +msgstr "Lag hjulovergang (elliptisk eller sirkelforma)" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:635 +msgid "on" +msgstr "pÃ¥" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:648 +msgid "Create gradient in the fill" +msgstr "Lag fargeovergang i fyllet" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:662 +msgid "Create gradient in the stroke" +msgstr "Lag fargeovergang i streken" + +#. FIXME: implement averaging of all parameters for multiple selected stars +#. gtk_label_set_markup(GTK_LABEL(l), _("Average:")); +#. FIXME: implement averaging of all parameters for multiple selected +#. gtk_label_set_markup(GTK_LABEL(l), _("Average:")); +#: ../../po/../src/widgets/gradient-toolbar.cpp:676 +#: ../../po/../src/widgets/toolbox.cpp:1105 +#: ../../po/../src/widgets/toolbox.cpp:1124 +#: ../../po/../src/widgets/toolbox.cpp:1493 +#: ../../po/../src/widgets/toolbox.cpp:1518 +#: ../../po/../src/widgets/toolbox.cpp:1768 +#: ../../po/../src/widgets/toolbox.cpp:1787 +#: ../../po/../src/widgets/toolbox.cpp:2334 +#: ../../po/../src/widgets/toolbox.cpp:2354 +msgid "Change:" +msgstr "Endra:" + +#: ../../po/../src/widgets/gradient-vector.cpp:269 +msgid "No gradients in document" +msgstr "Ingen fargeovergang i dokumentet" + +#: ../../po/../src/widgets/gradient-vector.cpp:275 +msgid "No gradient selected" +msgstr "Ingen fargeovergang valt" + +#: ../../po/../src/widgets/gradient-vector.cpp:532 +msgid "No stops in gradient" +msgstr "Ingen stoppar i fargeovergangen" + +#. TRANSLATORS: "Stop" means: a "phase" of a gradient +#: ../../po/../src/widgets/gradient-vector.cpp:794 +msgid "Add stop" +msgstr "Legg til stopp" + +#: ../../po/../src/widgets/gradient-vector.cpp:797 +msgid "Add another control stop to gradient" +msgstr "Legg endÃ¥ eit kontrollstopp til fargeovergangen" + +#: ../../po/../src/widgets/gradient-vector.cpp:799 +msgid "Delete stop" +msgstr "Slett stopp" + +#: ../../po/../src/widgets/gradient-vector.cpp:802 +msgid "Delete current control stop from gradient" +msgstr "Slett valt stopp frÃ¥ fargeovergangen" + +#. Label +#: ../../po/../src/widgets/gradient-vector.cpp:813 +msgid "Offset:" +msgstr "Forskyving:" + +#. TRANSLATORS: "Stop" means: a "phase" of a gradient +#: ../../po/../src/widgets/gradient-vector.cpp:858 +msgid "Stop Color" +msgstr "Stoppfarge" + +#: ../../po/../src/widgets/gradient-vector.cpp:887 +msgid "Gradient editor" +msgstr "Fargeovergangredigering" + +#: ../../po/../src/widgets/layer-selector.cpp:119 +msgid "Toggle current layer visibility" +msgstr "Vis/skjul gjeldande lag" + +#: ../../po/../src/widgets/layer-selector.cpp:139 +msgid "Lock or unlock current layer" +msgstr "LÃ¥s eller lÃ¥s opp gjeldande lag" + +#: ../../po/../src/widgets/layer-selector.cpp:142 +msgid "Current layer" +msgstr "Gjeldande lag" + +#: ../../po/../src/widgets/layer-selector.cpp:553 +msgid "(root)" +msgstr "(rot)" + +#: ../../po/../src/widgets/paint-selector.cpp:182 +#: ../../po/../src/widgets/paint-selector.cpp:561 +msgid "No paint" +msgstr "Ingen farge" + +#: ../../po/../src/widgets/paint-selector.cpp:184 +#: ../../po/../src/widgets/paint-selector.cpp:629 +msgid "Flat color" +msgstr "Heildekkjande farge" + +#: ../../po/../src/widgets/paint-selector.cpp:186 +#: ../../po/../src/widgets/paint-selector.cpp:696 +msgid "Linear gradient" +msgstr "Lineær fargeovergang" + +#: ../../po/../src/widgets/paint-selector.cpp:188 +#: ../../po/../src/widgets/paint-selector.cpp:699 +msgid "Radial gradient" +msgstr "Hjulovergang" + +#: ../../po/../src/widgets/paint-selector.cpp:192 +msgid "Unset paint (make it undefined so it can be inherited)" +msgstr "Fjern mÃ¥ling (gjer mÃ¥linga udefinert, slik at ho kan arva)." + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/painting.html#FillRuleProperty +#: ../../po/../src/widgets/paint-selector.cpp:204 +msgid "" +"Any path self-intersections or subpaths create holes in the fill (fill-rule: " +"evenodd)" +msgstr "" +"Der ei bane kryssar seg sjølv eller ei underbane vert det laga hol i fyllet " +"(«fill-rule: evenodd»)." + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/painting.html#FillRuleProperty +#: ../../po/../src/widgets/paint-selector.cpp:215 +msgid "" +"Fill is solid unless a subpath is counterdirectional (fill-rule: nonzero)" +msgstr "" +"Fyllet vert heildekkande, med mindre underbana gÃ¥r i motsett retning («fill-" +"rule: nonzero»)." + +#: ../../po/../src/widgets/paint-selector.cpp:528 +msgid "No objects" +msgstr "Ingen objekt" + +#: ../../po/../src/widgets/paint-selector.cpp:539 +msgid "Multiple styles" +msgstr "Fleire stilar" + +#: ../../po/../src/widgets/paint-selector.cpp:550 +msgid "Paint is undefined" +msgstr "MÃ¥linga er ikke definert." + +#: ../../po/../src/widgets/paint-selector.cpp:757 +msgid "No patterns in document" +msgstr "Ingen mønster i dokumentet." + +#: ../../po/../src/widgets/paint-selector.cpp:872 +msgid "" +"Use Edit > Object(s) to Pattern to create a new pattern from " +"selection." +msgstr "" +"Bruk Rediger | Objekt til mønster for Ã¥ laga eit nytt mønster av " +"utvalet." + +#: ../../po/../src/widgets/select-toolbar.cpp:426 +msgid "Now stroke width is scaled when objects are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:428 +msgid "Now stroke width is not scaled when objects are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:436 +msgid "" +"Now rounded rectangle corners are scaled when rectangles are " +"scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:438 +msgid "" +"Now rounded rectangle corners are not scaled when rectangles " +"are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:446 +msgid "" +"Now gradients are transformed along with their objects when " +"those are transformed (moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:448 +msgid "" +"Now gradients remain fixed when objects are transformed " +"(moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:456 +msgid "" +"Now patterns are transformed along with their objects when " +"those are transformed (moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:458 +msgid "" +"Now patterns remain fixed when objects are transformed (moved, " +"scaled, rotated, or skewed)." +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:506 +msgid "select_toolbar|X" +msgstr "select_toolbar|X" + +#: ../../po/../src/widgets/select-toolbar.cpp:506 +msgid "Horizontal coordinate of selection" +msgstr "Vassrett koordinat til utvalet." + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:511 +msgid "select_toolbar|Y" +msgstr "select_toolbar|Y" + +#: ../../po/../src/widgets/select-toolbar.cpp:511 +msgid "Vertical coordinate of selection" +msgstr "Loddrett koordinat til utvalet." + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:517 +msgid "select_toolbar|W" +msgstr "select_toolbar|B" + +#: ../../po/../src/widgets/select-toolbar.cpp:517 +msgid "Width of selection" +msgstr "Breidda til utvalet." + +#: ../../po/../src/widgets/select-toolbar.cpp:525 +msgid "Change both width and height by the same proportion" +msgstr "Endra bÃ¥de breidd og høgd proporsjonalt." + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:534 +msgid "select_toolbar|H" +msgstr "select_toolbar|H" + +#: ../../po/../src/widgets/select-toolbar.cpp:534 +msgid "Height of selection" +msgstr "Høgda til utvalet." + +#: ../../po/../src/widgets/sp-color-gtkselector.cpp:62 +msgid "System" +msgstr "System" + +#: ../../po/../src/widgets/sp-color-notebook.cpp:322 +msgid "RGBA_:" +msgstr "RGBA_:" + +#: ../../po/../src/widgets/sp-color-notebook.cpp:330 +msgid "Hexadecimal RGBA value of the color" +msgstr "RGBA-verdi til fargen (i sekstentalssystemet)" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "RGB" +msgstr "RGB" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "HSL" +msgstr "NML" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "CMYK" +msgstr "CMYK" + +#: ../../po/../src/widgets/sp-color-scales.cpp:397 +msgid "_R" +msgstr "_R" + +#: ../../po/../src/widgets/sp-color-scales.cpp:398 +#: ../../po/../src/widgets/sp-color-scales.cpp:399 +msgid "Red" +msgstr "Raud" + +#: ../../po/../src/widgets/sp-color-scales.cpp:400 +msgid "_G" +msgstr "_G" + +#: ../../po/../src/widgets/sp-color-scales.cpp:401 +#: ../../po/../src/widgets/sp-color-scales.cpp:402 +msgid "Green" +msgstr "Grøn" + +#: ../../po/../src/widgets/sp-color-scales.cpp:403 +msgid "_B" +msgstr "_B" + +#: ../../po/../src/widgets/sp-color-scales.cpp:404 +#: ../../po/../src/widgets/sp-color-scales.cpp:405 +msgid "Blue" +msgstr "BlÃ¥" + +#. Label +#: ../../po/../src/widgets/sp-color-scales.cpp:406 +#: ../../po/../src/widgets/sp-color-scales.cpp:432 +#: ../../po/../src/widgets/sp-color-scales.cpp:463 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:141 +msgid "_A" +msgstr "_A" + +#: ../../po/../src/widgets/sp-color-scales.cpp:407 +#: ../../po/../src/widgets/sp-color-scales.cpp:408 +#: ../../po/../src/widgets/sp-color-scales.cpp:433 +#: ../../po/../src/widgets/sp-color-scales.cpp:434 +#: ../../po/../src/widgets/sp-color-scales.cpp:464 +#: ../../po/../src/widgets/sp-color-scales.cpp:465 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:151 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:163 +msgid "Alpha (opacity)" +msgstr "Alfa (gjennomsikt)" + +#: ../../po/../src/widgets/sp-color-scales.cpp:423 +msgid "_H" +msgstr "_N" + +#: ../../po/../src/widgets/sp-color-scales.cpp:424 +#: ../../po/../src/widgets/sp-color-scales.cpp:425 +msgid "Hue" +msgstr "Nyanse" + +#: ../../po/../src/widgets/sp-color-scales.cpp:426 +msgid "_S" +msgstr "_M" + +#: ../../po/../src/widgets/sp-color-scales.cpp:427 +#: ../../po/../src/widgets/sp-color-scales.cpp:428 +msgid "Saturation" +msgstr "Metting" + +#: ../../po/../src/widgets/sp-color-scales.cpp:429 +msgid "_L" +msgstr "_L" + +#: ../../po/../src/widgets/sp-color-scales.cpp:430 +#: ../../po/../src/widgets/sp-color-scales.cpp:431 +msgid "Lightness" +msgstr "Lysstyrke" + +#: ../../po/../src/widgets/sp-color-scales.cpp:451 +msgid "_C" +msgstr "_C" + +#: ../../po/../src/widgets/sp-color-scales.cpp:452 +#: ../../po/../src/widgets/sp-color-scales.cpp:453 +msgid "Cyan" +msgstr "CyanblÃ¥" + +#: ../../po/../src/widgets/sp-color-scales.cpp:454 +msgid "_M" +msgstr "_M" + +#: ../../po/../src/widgets/sp-color-scales.cpp:455 +#: ../../po/../src/widgets/sp-color-scales.cpp:456 +msgid "Magenta" +msgstr "Magentaraud" + +#: ../../po/../src/widgets/sp-color-scales.cpp:457 +msgid "_Y" +msgstr "_G" + +#: ../../po/../src/widgets/sp-color-scales.cpp:458 +#: ../../po/../src/widgets/sp-color-scales.cpp:459 +msgid "Yellow" +msgstr "Gul" + +#: ../../po/../src/widgets/sp-color-scales.cpp:460 +msgid "_K" +msgstr "_S" + +#: ../../po/../src/widgets/sp-color-selector.cpp:71 +msgid "Unnamed" +msgstr "Namnlaus" + +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:68 +msgid "Wheel" +msgstr "Hjul" + +#: ../../po/../src/widgets/sp-xmlview-attr-list.cpp:53 +msgid "Attribute" +msgstr "Attributt" + +#: ../../po/../src/widgets/sp-xmlview-attr-list.cpp:54 +msgid "Value" +msgstr "Verdi" + +#: ../../po/../src/widgets/toolbox.cpp:424 +msgid "Insert new nodes into selected segments" +msgstr "Set inn ny node mellom merkte nodar." + +#: ../../po/../src/widgets/toolbox.cpp:426 +msgid "Delete selected nodes" +msgstr "Slett merkte nodar." + +#: ../../po/../src/widgets/toolbox.cpp:431 +msgid "Join paths at selected nodes" +msgstr "SlÃ¥ saman baner ved merkte nodar." + +#: ../../po/../src/widgets/toolbox.cpp:433 +msgid "Join paths at selected nodes with new segment" +msgstr "SlÃ¥ saman baner ved merkte nodar med ei ny kurve." + +#: ../../po/../src/widgets/toolbox.cpp:436 +msgid "Split path between two non-endpoint nodes" +msgstr "Del opp bane mellom to ikkje-sluttnodar." + +#: ../../po/../src/widgets/toolbox.cpp:439 +msgid "Break path at selected nodes" +msgstr "Bryt opp bane ved merkte nodar." + +#: ../../po/../src/widgets/toolbox.cpp:444 +msgid "Make selected nodes corner" +msgstr "Gjer merkte nodar om til hjørne." + +#: ../../po/../src/widgets/toolbox.cpp:447 +msgid "Make selected nodes smooth" +msgstr "Gjer merkte nodar glatte." + +#: ../../po/../src/widgets/toolbox.cpp:450 +msgid "Make selected nodes symmetric" +msgstr "Gjer merkte nodar symmetriske." + +#: ../../po/../src/widgets/toolbox.cpp:455 +msgid "Make selected segments lines" +msgstr "Gjer merkte stykke om til linjer." + +#: ../../po/../src/widgets/toolbox.cpp:458 +msgid "Make selected segments curves" +msgstr "Gjer merkte stykke om til kurver." + +#: ../../po/../src/widgets/toolbox.cpp:1199 +msgid "Polygon" +msgstr "Mangekant" + +#: ../../po/../src/widgets/toolbox.cpp:1206 +msgid "Regular polygon (with one handle) instead of a star" +msgstr "Regulær mangekant (med eitt kontrollpunkt) i staden for ei stjerne." + +#: ../../po/../src/widgets/toolbox.cpp:1218 +msgid "Corners:" +msgstr "Hjørne:" + +#: ../../po/../src/widgets/toolbox.cpp:1218 +msgid "Number of corners of a polygon or star" +msgstr "Talet pÃ¥ hjørne i ein mangekant eller ei stjerne." + +#: ../../po/../src/widgets/toolbox.cpp:1228 +msgid "Spoke ratio:" +msgstr "Spissforhold:" + +#. TRANSLATORS: Tip radius of a star is the distance from the center to the farthest handle. +#. Base radius is the same for the closest handle. +#: ../../po/../src/widgets/toolbox.cpp:1231 +msgid "Base radius to tip radius ratio" +msgstr "Grunnradius til spissradius-forhold." + +#: ../../po/../src/widgets/toolbox.cpp:1246 +msgid "Rounded:" +msgstr "Rundheit:" + +#: ../../po/../src/widgets/toolbox.cpp:1246 +msgid "How much rounded are the corners (0 for sharp)" +msgstr "Kor runde hjørnene skal vera (0 for heilt spisse)." + +#: ../../po/../src/widgets/toolbox.cpp:1256 +msgid "Randomized:" +msgstr "Slumpverdi:" + +#: ../../po/../src/widgets/toolbox.cpp:1256 +msgid "Scatter randomly the corners and angles" +msgstr "Sprei hjørna og vinklane tilfeldig." + +#: ../../po/../src/widgets/toolbox.cpp:1269 +#: ../../po/../src/widgets/toolbox.cpp:1838 +#: ../../po/../src/widgets/toolbox.cpp:2061 +msgid "Defaults" +msgstr "Standard" + +#: ../../po/../src/widgets/toolbox.cpp:1270 +#: ../../po/../src/widgets/toolbox.cpp:1839 +#: ../../po/../src/widgets/toolbox.cpp:2062 +msgid "" +"Reset shape parameters to defaults (use Inkscape Preferences > Tools to " +"change defaults)" +msgstr "" +"Nullstill figurparametrane til standard (bruk «Fil | Inkscape-oppsett | " +"Verktøy» for endra standardverdiane)." + +#: ../../po/../src/widgets/toolbox.cpp:1544 +msgid "W:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1544 +#, fuzzy +msgid "Width of rectangle" +msgstr "Breidda til utvalet." + +#: ../../po/../src/widgets/toolbox.cpp:1556 +#, fuzzy +msgid "Height of rectangle" +msgstr "Høgda til utvalet." + +#: ../../po/../src/widgets/toolbox.cpp:1568 +msgid "Rx:" +msgstr "Rx:" + +#: ../../po/../src/widgets/toolbox.cpp:1568 +msgid "Horizontal radius of rounded corners" +msgstr "Vassrett radius til avrunda hjørne." + +#: ../../po/../src/widgets/toolbox.cpp:1578 +msgid "Ry:" +msgstr "Ry:" + +#: ../../po/../src/widgets/toolbox.cpp:1578 +msgid "Vertical radius of rounded corners" +msgstr "Loddrett radius til avrunda hjørne." + +#: ../../po/../src/widgets/toolbox.cpp:1594 +msgid "Not rounded" +msgstr "Bruk rette hjørne" + +#: ../../po/../src/widgets/toolbox.cpp:1596 +msgid "Make corners sharp" +msgstr "Gjer hjørnene spisse." + +#: ../../po/../src/widgets/toolbox.cpp:1805 +msgid "Turns:" +msgstr "Rundar:" + +#: ../../po/../src/widgets/toolbox.cpp:1805 +msgid "Number of revolutions" +msgstr "Talet pÃ¥ rundar." + +#: ../../po/../src/widgets/toolbox.cpp:1815 +msgid "Divergence:" +msgstr "Divergens:" + +#: ../../po/../src/widgets/toolbox.cpp:1815 +msgid "How much denser/sparser are outer revolutions; 1 = uniform" +msgstr "" +"Kor mykje tettare eller lengre frÃ¥ kvarandre ytre rundar skal vera (1 = likt " +"for alle rundar)." + +#: ../../po/../src/widgets/toolbox.cpp:1825 +msgid "Inner radius:" +msgstr "Indre radius:" + +#: ../../po/../src/widgets/toolbox.cpp:1825 +msgid "Radius of the innermost revolution (relative to the spiral size)" +msgstr "Radius til indre runding (relativt til spiralstorleiken)." + +#: ../../po/../src/widgets/toolbox.cpp:1957 +msgid "The width of the calligraphic pen (relative to the visible canvas area)" +msgstr "" +"Breidda pÃ¥ den kalligrafiske pennen (relativt til synleg lerretomrÃ¥de)." + +#: ../../po/../src/widgets/toolbox.cpp:1967 +msgid "Thinning:" +msgstr "Fortynning:" + +#: ../../po/../src/widgets/toolbox.cpp:1967 +msgid "" +"How much velocity thins the stroke (> 0 makes fast strokes thinner, < 0 " +"makes them broader, 0 makes width independent of velocity)" +msgstr "" +"Kor mykje fart skal til for Ã¥ fortynna strøket (positive verdiar gjev raske " +"strøk tynnare, negative verdiar gjer dei tjukkare og 0 gjer dei uavhengig av " +"farten)." + +#: ../../po/../src/widgets/toolbox.cpp:1980 +msgid "Angle:" +msgstr "Vinkel:" + +#: ../../po/../src/widgets/toolbox.cpp:1980 +msgid "" +"The angle of the pen's nib (in degrees; 0 = horizontal; has no effect if " +"fixation = 0)" +msgstr "" +"Vinkelen pÃ¥ pennesplitten (i gradar, der 0 er vassrett). Dette har ingen " +"effekt om fikseringa er 0." + +#: ../../po/../src/widgets/toolbox.cpp:1990 +msgid "Fixation:" +msgstr "Fiksering:" + +#: ../../po/../src/widgets/toolbox.cpp:1990 +msgid "" +"How fixed is the pen angle (0 = always perpendicular to stroke direction, 1 " +"= fixed)" +msgstr "" +"Kor fast skal pennevinkelen vera (0: alltid normalt pÃ¥ strøkretninga, 1: " +"fast)." + +#: ../../po/../src/widgets/toolbox.cpp:2003 +msgid "Mass:" +msgstr "Masse:" + +#: ../../po/../src/widgets/toolbox.cpp:2003 +msgid "How much inertia affects the movement of the pen" +msgstr "Kor mykje tregleiken pÃ¥verkar rørsla av pennen." + +#. TRANSLATORS: "drag" means "resistance" here +#: ../../po/../src/widgets/toolbox.cpp:2014 +msgid "Drag:" +msgstr "Motstand:" + +#: ../../po/../src/widgets/toolbox.cpp:2014 +msgid "How much resistance affects the movement of the pen" +msgstr "Kor mykje motstanden pÃ¥verkar rørsla av pennen." + +#: ../../po/../src/widgets/toolbox.cpp:2034 +msgid "Use the pressure of the input device to alter the width of the pen" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2047 +msgid "Use the tilt of the input device to alter the angle of the pen's nib" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2374 +msgid "Start:" +msgstr "Start:" + +#: ../../po/../src/widgets/toolbox.cpp:2374 +msgid "The angle (in degrees) from the horizontal to the arc's start point" +msgstr "Vinkelen (i gradar) frÃ¥ vassrett til startpunktet til bogen." + +#: ../../po/../src/widgets/toolbox.cpp:2384 +msgid "End:" +msgstr "Slutt:" + +#: ../../po/../src/widgets/toolbox.cpp:2384 +msgid "The angle (in degrees) from the horizontal to the arc's end point" +msgstr "Vinkelen (i gradar) frÃ¥ vassrett til sluttpunktet til bogen." + +#: ../../po/../src/widgets/toolbox.cpp:2395 +msgid "Open arc" +msgstr "Open boge" + +#: ../../po/../src/widgets/toolbox.cpp:2396 +msgid "" +"Switch between arc (unclosed shape) and segment (closed shape with two radii)" +msgstr "" +"Byt mellom bogar (opne former) og kakestykke (lukka former med to radiar)." + +#: ../../po/../src/widgets/toolbox.cpp:2415 +msgid "Make whole" +msgstr "Gjer til heilellipse" + +#: ../../po/../src/widgets/toolbox.cpp:2417 +msgid "Make the shape a whole ellipse, not arc or segment" +msgstr "" +"Gjer om figuren til ein heil ellipse – ikkje ein boge eller eit kakestykke." + +#: ../../po/../src/widgets/toolbox.cpp:2644 +msgid "" +"When pressed, picks visible color without alpha and when not pressed, picks " +"color including its alpha" +msgstr "" +"Viss vald, hent synleg farge utan gjennomsikt. Viss ikkje vald, hent farge " +"inkludert gjennomsikt." + +#: ../../po/../src/widgets/toolbox.cpp:3039 +#, fuzzy +msgid "Make connectors avoid selected objects" +msgstr "Snittet av dei merkte objekta." + +#: ../../po/../src/widgets/toolbox.cpp:3043 +#, fuzzy +msgid "Make connectors ignore selected objects" +msgstr "Snittet av dei merkte objekta." + +#. +#. 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 : +#: ../share/extensions/addnodes.inx.h:1 +#, fuzzy +msgid "Add Nodes" +msgstr "Nodar" + +#: ../share/extensions/addnodes.inx.h:2 +msgid "Maximum Segment Length" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:1 +msgid "AI Input" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:2 ../share/extensions/ai_output.inx.h:2 +msgid "Adobe Illustrator (*.ai)" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:3 +msgid "Open files saved with Adobe Illustrator" +msgstr "" + +#: ../share/extensions/ai_output.inx.h:1 +#, fuzzy +msgid "AI Output" +msgstr "Utdata" + +#: ../share/extensions/ai_output.inx.h:3 +msgid "Write Adobe Illustrator" +msgstr "" + +#: ../share/extensions/dia.inx.h:1 +msgid "A diagram created with the program Dia" +msgstr "" + +#: ../share/extensions/dia.inx.h:2 +msgid "Dia Diagram (*.dia)" +msgstr "" + +#: ../share/extensions/dia.inx.h:3 +msgid "Dia Input" +msgstr "" + +#: ../share/extensions/dia.inx.h:4 +msgid "" +"In order to import Dia files, Dia itself must be installed. You can get Dia " +"at http://www.gnome.org/projects/dia/" +msgstr "" + +#: ../share/extensions/dia.inx.h:5 +msgid "" +"The dia2svg.sh script should be installed with your Inkscape distribution. " +"If you do not have it, there is likely to be something wrong with your " +"Inkscape installation." +msgstr "" + +#: ../share/extensions/dots.inx.h:1 +#, fuzzy +msgid "Connect the Dots" +msgstr "Opphavsmann" + +#: ../share/extensions/dots.inx.h:2 +#, fuzzy +msgid "Dot Size" +msgstr "Storleik" + +#: ../share/extensions/dots.inx.h:3 +#, fuzzy +msgid "Font Size" +msgstr "Skriftstorleik:" + +#: ../share/extensions/dropshadow.inx.h:1 +msgid "Color of shadow" +msgstr "" + +#: ../share/extensions/dropshadow.inx.h:2 +#, fuzzy +msgid "Dropshadow" +msgstr "Vis sideskugge" + +#: ../share/extensions/dxf_input.inx.h:1 +#: ../share/extensions/dxf_output.inx.h:1 +msgid "AutoCAD DXF (*.dxf)" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:2 +msgid "DXF Input" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:3 +msgid "Import AutoCAD's Document Exchange Format" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:4 +msgid "" +"dxf2svg may come with Inkscape, but is also at http://dxf-svg-convert." +"sourceforge.net/" +msgstr "" + +#: ../share/extensions/dxf_output.inx.h:2 +#, fuzzy +msgid "DXF Output" +msgstr "Utdata" + +#: ../share/extensions/dxf_output.inx.h:3 +msgid "DXF file written by pstoedit" +msgstr "" + +#: ../share/extensions/dxf_output.inx.h:4 +msgid "pstoedit must be installed to run see http://www.pstoedit.net/pstoedit" +msgstr "" + +#: ../share/extensions/embedimage.inx.h:1 +#, fuzzy +msgid "Embed Images" +msgstr "Bilete" + +#: ../share/extensions/eps_input.inx.h:1 +msgid "EPS Input" +msgstr "" + +#: ../share/extensions/eps_input.inx.h:2 +msgid "Encapsulated Postscript" +msgstr "" + +#: ../share/extensions/eps_input.inx.h:3 +msgid "Encapsulated Postscript (*.eps)" +msgstr "" + +#: ../share/extensions/epsi_output.inx.h:1 +#, fuzzy +msgid "EPSI Output" +msgstr "Utdata" + +#: ../share/extensions/epsi_output.inx.h:2 +msgid "Encapsulated Postscript Interchange (*.epsi)" +msgstr "" + +#: ../share/extensions/epsi_output.inx.h:3 +msgid "Encapsulated Postscript with a thumbnail" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:1 ../share/extensions/ffms.inx.h:1 +#: ../share/extensions/ffset.inx.h:1 ../share/extensions/ffss.inx.h:1 +#, fuzzy +msgid "Bridge Width" +msgstr "Linjebreidd" + +#: ../share/extensions/ffmet.inx.h:2 ../share/extensions/ffms.inx.h:2 +msgid "First String Length" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:3 +msgid "FretFind Multi Length ET" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:4 ../share/extensions/ffms.inx.h:4 +#: ../share/extensions/ffset.inx.h:3 ../share/extensions/ffss.inx.h:3 +msgid "Fretboard Edges" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:5 ../share/extensions/ffms.inx.h:5 +msgid "Last String Length" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:6 ../share/extensions/ffms.inx.h:6 +#: ../share/extensions/ffset.inx.h:4 ../share/extensions/ffss.inx.h:4 +#, fuzzy +msgid "Number of Frets" +msgstr "Talet pÃ¥ rader." + +#: ../share/extensions/ffmet.inx.h:7 ../share/extensions/ffms.inx.h:7 +#: ../share/extensions/ffset.inx.h:5 ../share/extensions/ffss.inx.h:5 +#, fuzzy +msgid "Number of Strings" +msgstr "Talet pÃ¥ rader." + +#: ../share/extensions/ffmet.inx.h:8 ../share/extensions/ffms.inx.h:8 +#: ../share/extensions/ffset.inx.h:6 ../share/extensions/ffss.inx.h:6 +#, fuzzy +msgid "Nut Width" +msgstr "Breidd:" + +#: ../share/extensions/ffmet.inx.h:9 ../share/extensions/ffms.inx.h:10 +msgid "Perpendicular Distance" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:10 ../share/extensions/ffset.inx.h:7 +msgid "Scale Base (2 for Octave)" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:11 ../share/extensions/ffset.inx.h:9 +msgid "Tones in Scale" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:12 ../share/extensions/ffms.inx.h:12 +#: ../share/extensions/ffset.inx.h:10 ../share/extensions/ffss.inx.h:10 +msgid "px per Unit" +msgstr "" + +#: ../share/extensions/ffms.inx.h:3 +msgid "FretFind Multi Length Scala" +msgstr "" + +#: ../share/extensions/ffms.inx.h:9 ../share/extensions/ffss.inx.h:7 +msgid "Path to Scala *.scl File" +msgstr "" + +#: ../share/extensions/ffms.inx.h:11 +msgid "Tuning (scale step for each string seperated by semicolons)" +msgstr "" + +#: ../share/extensions/ffset.inx.h:2 +msgid "FretFind Single Length ET" +msgstr "" + +#: ../share/extensions/ffset.inx.h:8 ../share/extensions/ffss.inx.h:8 +msgid "Scale Length" +msgstr "" + +#: ../share/extensions/ffss.inx.h:2 +msgid "FretFind Single Length Scala" +msgstr "" + +#: ../share/extensions/ffss.inx.h:9 +msgid "Tuning (Scale step for each string seperated by semicolons)" +msgstr "" + +#: ../share/extensions/handles.inx.h:1 +#, fuzzy +msgid "Draw Handles" +msgstr "Teikn frihandslinjer." + +#: ../share/extensions/interp.inx.h:1 +#, fuzzy +msgid "Duplicate Endpaths" +msgstr "Lag kopi av node" + +#: ../share/extensions/interp.inx.h:2 +#, fuzzy +msgid "Exponent" +msgstr "Eksporter" + +#: ../share/extensions/interp.inx.h:3 +msgid "Interpolate" +msgstr "" + +#: ../share/extensions/interp.inx.h:4 +msgid "Interpolate Style (Experimental)" +msgstr "" + +#: ../share/extensions/interp.inx.h:5 +msgid "Interpolation Method" +msgstr "" + +#: ../share/extensions/interp.inx.h:6 +msgid "Interpolation Steps" +msgstr "" + +#: ../share/extensions/kochify.inx.h:1 +msgid "Kochify" +msgstr "" + +#: ../share/extensions/kochify_load.inx.h:1 +msgid "Kochify (Load)" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:1 +#, fuzzy +msgid "Angle" +msgstr "Vinkel:" + +#: ../share/extensions/lindenmayer.inx.h:2 +msgid "Axiom" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:3 +#, fuzzy +msgid "Lindenmayer" +msgstr "Endra namn pÃ¥ lag" + +#: ../share/extensions/lindenmayer.inx.h:4 +msgid "Order" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:5 +#, fuzzy +msgid "Rules" +msgstr "_Linjalar" + +#: ../share/extensions/lindenmayer.inx.h:6 +#, fuzzy +msgid "Step" +msgstr "Steg" + +#: ../share/extensions/motion.inx.h:1 +#, fuzzy +msgid "Direction" +msgstr "Skildring" + +#: ../share/extensions/motion.inx.h:2 +#, fuzzy +msgid "Magnitude" +msgstr "Magentaraud" + +#: ../share/extensions/motion.inx.h:3 +#, fuzzy +msgid "Motion" +msgstr "_Rotering" + +#: ../share/extensions/pdf_output.inx.h:1 +msgid "Adobe PDF (*.pdf)" +msgstr "" + +#: ../share/extensions/pdf_output.inx.h:2 +msgid "Adobe Portable Document Format" +msgstr "" + +#: ../share/extensions/pdf_output.inx.h:3 +#, fuzzy +msgid "PDF Output" +msgstr "Utdata" + +#: ../share/extensions/ps_input.inx.h:1 +#, fuzzy +msgid "Postscript" +msgstr "StÃ¥ande" + +#: ../share/extensions/ps_input.inx.h:2 +msgid "Postscript (*.ps)" +msgstr "" + +#: ../share/extensions/ps_input.inx.h:3 +msgid "Postscript Input" +msgstr "" + +#: ../share/extensions/radiusrand.inx.h:1 +#, fuzzy +msgid "Radius" +msgstr "_Hev" + +#: ../share/extensions/radiusrand.inx.h:2 +#, fuzzy +msgid "Radius Randomize" +msgstr "Slumpverdi:" + +#: ../share/extensions/radiusrand.inx.h:3 +msgid "Randomize Control Points" +msgstr "" + +#: ../share/extensions/radiusrand.inx.h:4 +#, fuzzy +msgid "Randomize Nodes" +msgstr "Slumpverdi:" + +#: ../share/extensions/rtree.inx.h:1 +#, fuzzy +msgid "Initial Size" +msgstr "Storleik pÃ¥ punktbilete" + +#: ../share/extensions/rtree.inx.h:2 +msgid "Minimum Size" +msgstr "" + +#: ../share/extensions/rtree.inx.h:3 +#, fuzzy +msgid "Random Tree" +msgstr "Slumpverdi:" + +#: ../share/extensions/sk_input.inx.h:1 +msgid "A diagram created with the program Sketch" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:2 +msgid "Sketch Diagram (*.sk)" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:3 +msgid "Sketch Input" +msgstr "" + +#: ../share/extensions/straightseg.inx.h:1 +msgid "Behavior" +msgstr "" + +#: ../share/extensions/straightseg.inx.h:3 +msgid "Segment Straightener" +msgstr "" + +#: ../share/extensions/summersnight.inx.h:1 +msgid "Summer's Night" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:1 +#: ../share/extensions/svgz_output.inx.h:1 +msgid "Compressed Inkscape SVG (*.svgz)" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:2 +#: ../share/extensions/svgz_output.inx.h:2 +msgid "Inkscape's native file format compressed with GZip" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:3 +msgid "SVGZ Input" +msgstr "" + +#: ../share/extensions/svgz_output.inx.h:3 +#, fuzzy +msgid "SVGZ Output" +msgstr "Utdata" + +#: ../share/extensions/txt2svg.inx.h:1 +msgid "ASCII Text" +msgstr "" + +#: ../share/extensions/txt2svg.inx.h:2 +msgid "Text File (*.txt)" +msgstr "" + +#: ../share/extensions/txt2svg.inx.h:3 +msgid "Text Input" +msgstr "" + +#: ../share/extensions/wavy.inx.h:1 +msgid "Calculate first derivative numerically" +msgstr "" + +#: ../share/extensions/wavy.inx.h:2 +msgid "First derivative" +msgstr "" + +#: ../share/extensions/wavy.inx.h:3 +msgid "Function" +msgstr "" + +#: ../share/extensions/wavy.inx.h:4 +msgid "Function Plotter" +msgstr "" + +#: ../share/extensions/wavy.inx.h:5 +msgid "Nodes per period" +msgstr "" + +#: ../share/extensions/wavy.inx.h:6 +msgid "Periods (2*Pi each)" +msgstr "" + +#: ../share/extensions/whirl.inx.h:1 +msgid "Amount of Whirl" +msgstr "" + +#: ../share/extensions/whirl.inx.h:2 +#, fuzzy +msgid "Center X" +msgstr "Midtlinjer" + +#: ../share/extensions/whirl.inx.h:3 +#, fuzzy +msgid "Center Y" +msgstr "Midtlinjer" + +#: ../share/extensions/whirl.inx.h:4 +#, fuzzy +msgid "Direction of Rotation" +msgstr "Send utvalet bakarst." + +#: ../share/extensions/whirl.inx.h:5 +msgid "Whirl" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:1 +msgid "A popular graphics file format for clipart" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:2 +msgid "Windows Metafile (*.wmf)" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:3 +msgid "Windows Metafile Input" +msgstr "" + +#~ msgid "Custom canvas" +#~ msgstr "Eigedefinert lerret" + +#~ msgid "Current style" +#~ msgstr "Gjeldande stil" + +#~ msgid "" +#~ "Current style is updated every time you change the style of any object " +#~ "(its fill, stroke, transparency, etc.)" +#~ msgstr "" +#~ "Gjeldande stil vert oppdatert kvar gong du endrar stilen til eit objekt " +#~ "(fyll, strek eller gjennomsikt)." + +#~ msgid "Arrange Objects" +#~ msgstr "Ordna objekt" + +#~ msgid "deg" +#~ msgstr "gradar" + +#~ msgid "" +#~ "%s is not a valid preferences file.\n" +#~ "%s" +#~ msgstr "" +#~ "«%s» er ikkje ei gyldig oppsettfil.\n" +#~ "%s" + +#~ msgid "" +#~ "Inkscape will run with default settings.\n" +#~ "New settings will not be saved." +#~ msgstr "" +#~ "Inkscape køyrer med standardoppsettet.\n" +#~ "Ny innstillingar vert ikkje lagra." + +#, fuzzy +#~ msgid "_Credits" +#~ msgstr "Bidragsytarar" + +#~ msgid "Grab sensitivity" +#~ msgstr "Plukkfølsemd" + +#~ msgid "Click/drag threshold" +#~ msgstr "Klikk/dra-grense" + +#~ msgid "Mouse wheel scrolls by" +#~ msgstr "Musehjul rullar med" + +#~ msgid "Scroll by" +#~ msgstr "Rull med" + +#~ msgid "Acceleration" +#~ msgstr "Akselerasjon" + +#~ msgid "Speed" +#~ msgstr "Fart" + +#~ msgid "Threshold" +#~ msgstr "Terskel" + +#~ msgid "Arrow keys move by" +#~ msgstr "Piltastar flyttar" + +#~ msgid "> and < scale by" +#~ msgstr "«>» og «<» skalerer" + +#~ msgid "Inset/Outset by" +#~ msgstr "Skubb inn/ut med" + +#~ msgid "Rotation snaps every" +#~ msgstr "Roteringssteg" + +#~ msgid "Zoom in/out by" +#~ msgstr "Forstørr inn/ut" + +#~ msgid "Transform" +#~ msgstr "Form om" + +#~ msgid "PLACEHOLDER, DO NOT TRANSLATE" +#~ msgstr "PLACEHOLDER, DO NOT TRANSLATE" + +#~ msgid "Flip selection horizontally" +#~ msgstr "Spegla utvalet vassrett." + +#~ msgid "Flip selection vertically" +#~ msgstr "Spegla utvalet loddrett." + +#, fuzzy +#~ msgid "Could not read next message due to I/O error (error: %s)!" +#~ msgstr "Klarte ikkje laga feilloggen «%s» for utvidinga." + +#~ msgid "Open one of the recently visited documents" +#~ msgstr "Opna eit av dei nyleg brukte dokumenta." + +#~ msgid "" +#~ "Show or hide parts of the document window (differently for normal and " +#~ "fullscreen modes)" +#~ msgstr "" +#~ "Vis eller skjul delar av dokumentvindauget (forskjellig for vanleg og " +#~ "fullskjermmodus)." + +#~ msgid "Interactive Inkscape tutorials" +#~ msgstr "Interaktive Inkscape-innføringar." + +#~ msgid "gpl-2.svg" +#~ msgstr "gpl-2.svg" + +#~ msgid "Modifying or Redistributing Inkscape" +#~ msgstr "Endring og vidareformidling av Inkscape" + +#~ msgid "Show license to modify and/or redistribute Inkscape: GNU GPL" +#~ msgstr "" +#~ "Vis lisensvilkÃ¥ra for endring og vidareformidling av Inkscape (GNU GPL)." diff --git a/po/pa.po b/po/pa.po new file mode 100644 index 000000000..45f0fa0de --- /dev/null +++ b/po/pa.po @@ -0,0 +1,9129 @@ +# translation of pa.po to Punjabi +# This file is distributed under the same license as the PACKAGE package. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER. +# Amanpreet Singh Brar Alamwalia , 2005. +# Amanpreet Singh Brar , 2005. +# +msgid "" +msgstr "" +"Project-Id-Version: pa\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2005-12-04 11:51-0800\n" +"PO-Revision-Date: 2005-09-11 18:09+0530\n" +"Last-Translator: Amanpreet Singh Brar \n" +"Language-Team: Punjabi \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: KBabel 1.9.1\n" + +#: ../inkscape.desktop.in.h:1 +msgid "Create and edit Scalable Vector Graphics images" +msgstr "ਸਕੇਲੇਬਲ ਵੈਕਟਰ ਗਰਾਫਿਕਸ ਚਿੱਤਰ ਬਣਾਓ ਅਤੇ ਸੋਧੋ" + +#: ../inkscape.desktop.in.h:2 +msgid "Inkscape SVG Vector Illustrator" +msgstr "ਇੰਕਸਕੇਪੀ SVG ਵੈਕਟਰ ਚਿੱਤਰਕਾਰੀ" + +#: ../../po/../src/arc-context.cpp:350 +msgid "" +"Ctrl: make circle or integer-ratio ellipse, snap arc/segment angle" +msgstr "" + +#: ../../po/../src/arc-context.cpp:351 ../../po/../src/rect-context.cpp:388 +msgid "Shift: draw around the starting point" +msgstr "" + +#: ../../po/../src/arc-context.cpp:413 +#: ../../po/../src/connector-context.cpp:493 +#: ../../po/../src/dyna-draw-context.cpp:506 +#: ../../po/../src/pen-context.cpp:329 ../../po/../src/pencil-context.cpp:208 +#: ../../po/../src/rect-context.cpp:452 ../../po/../src/spiral-context.cpp:421 +#: ../../po/../src/star-context.cpp:427 +msgid "Current layer is hidden. Unhide it to be able to draw on it." +msgstr "ਮੌਜੂਦਾ ਪਰਤ ਲੁਕਵੀਂ ਹੈ। ਇਸ ਉੱਤੇ ਉਲੀਕਣ ਲਈ ਇਸ ਨੂੰ ਦਿੱਖ ਬਣਾਓ।" + +#: ../../po/../src/arc-context.cpp:417 +#: ../../po/../src/connector-context.cpp:497 +#: ../../po/../src/dyna-draw-context.cpp:510 +#: ../../po/../src/pen-context.cpp:336 ../../po/../src/pencil-context.cpp:212 +#: ../../po/../src/rect-context.cpp:456 ../../po/../src/spiral-context.cpp:426 +#: ../../po/../src/star-context.cpp:431 +msgid "Current layer is locked. Unlock it to be able to draw on it." +msgstr "ਮੌਜੂਦਾ ਪਰਤ ਤਾਲਾਬੰਦ ਹੈ। ਇਸ ਉੱਤੇ ਉਲੀਕਣ ਲਈ ਇਸ ਨੂੰ ਖੋਲੋ।" + +#: ../../po/../src/arc-context.cpp:496 +#, c-format +msgid "" +"Ellipse: %s × %s; with Ctrl to make circle or integer-" +"ratio ellipse; with Shift to draw around the starting point" +msgstr "" + +#: ../../po/../src/connector-context.cpp:518 +#, fuzzy +msgid "Creating new connector" +msgstr "ਨਵਾਂ ਮਾਰਗ ਬਣਾਇਆ ਜਾ ਰਿਹਾ ਹੈ" + +#: ../../po/../src/connector-context.cpp:939 +#, fuzzy +msgid "Finishing connector" +msgstr "ਪੈਨ ਖਤਮ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ" + +#: ../../po/../src/connector-context.cpp:1108 +msgid "Connection point: click or drag to create a new connector" +msgstr "" + +#: ../../po/../src/connector-context.cpp:1185 +msgid "Connector endpoint: drag to reroute or connect to new shapes" +msgstr "" + +#: ../../po/../src/connector-context.cpp:1278 +msgid "Select at least one non-connector object." +msgstr "" + +#: ../../po/../src/desktop-events.cpp:238 +#, c-format +msgid "%s at %s" +msgstr "%s, %s ਉੱਤੇ" + +#. TRANSLATORS: This string appears when double-clicking on a guide. +#. This is the distance by which the guide is to be moved. +#: ../../po/../src/desktop-events.cpp:277 +msgid " relative by " +msgstr " ਅਨੁਸਾਰੀ " + +#. TRANSLATORS: This string appears when double-clicking on a guide. +#. This is the target location where the guide is to be moved. +#: ../../po/../src/desktop-events.cpp:282 +#: ../../po/../src/desktop-events.cpp:395 +msgid " absolute to " +msgstr " ਸੰਖੇਪਤ " + +#. create dialog +#: ../../po/../src/desktop-events.cpp:348 +msgid "Guideline" +msgstr "ਗਾਈਡਲਾਇਨ" + +#: ../../po/../src/desktop-events.cpp:432 +#, c-format +msgid "Move %s" +msgstr "ਭੇਜੋ %s" + +#: ../../po/../src/desktop.cpp:678 +msgid "No previous zoom." +msgstr "ਕੋਈ ਪਿਛਲਾ ਜ਼ੂਮ ਨਹੀਂ ਹੈ।" + +#: ../../po/../src/desktop.cpp:703 +msgid "No next zoom." +msgstr "ਕੋਈ ਅੱਗੇ ਜ਼ੂਮ ਨਹੀਂ ਹੈ।" + +#: ../../po/../src/dialogs/clonetiler.cpp:182 +msgid "Nothing selected." +msgstr "ਕੁਝ ਨਹੀਂ ਚੁਣਿਆ ਗਿਆ।" + +#: ../../po/../src/dialogs/clonetiler.cpp:188 +msgid "More than one object selected." +msgstr "ਇੱਕ ਤੋਂ ਵਧੇਰੇ ਇਕਾਈਆਂ ਚੁਣੀਆਂ ਗਈਆਂ ਹਨ।" + +#: ../../po/../src/dialogs/clonetiler.cpp:195 +#, c-format +msgid "Object has %d tiled clones." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:200 +msgid "Object has no tiled clones." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:865 +msgid "Select one object whose tiled clones to unclump." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:916 +msgid "Select one object whose tiled clones to remove." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:984 +#: ../../po/../src/selection-chemistry.cpp:1774 +msgid "Select an object to clone." +msgstr "ਸਮਰੂਪ ਲਈ ਇੱਕ ਇਕਾਈ ਚੁਣੋ।" + +#: ../../po/../src/dialogs/clonetiler.cpp:990 +#: ../../po/../src/selection-chemistry.cpp:1780 +msgid "" +"If you want to clone several objects, group them and clone the " +"group." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1484 +msgid "Per row:" +msgstr "ਪ੍ਰਤੀ ਕਤਾਰ:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1497 +msgid "Per column:" +msgstr "ਪ੍ਰਤੀ ਕਾਲਮ:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1505 +msgid "Randomize:" +msgstr "ਰਲਵਾਂ:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1656 +msgid "_Symmetry" +msgstr "ਸਮਮਿਤੀ(_S)" + +#. TRANSLATORS: For the following 17 symmetry groups, see +#. * http://www.bib.ulb.ac.be/coursmath/doc/17.htm (visual examples); +#. * http://www.clarku.edu/~djoyce/wallpaper/seventeen.html (English vocabulary); or +#. * http://membres.lycos.fr/villemingerard/Geometri/Sym1D.htm (French vocabulary). +#. +#: ../../po/../src/dialogs/clonetiler.cpp:1664 +msgid "Select one of the 17 symmetry groups for the tiling" +msgstr "" + +#. TRANSLATORS: "translation" means "shift" / "displacement" here. +#: ../../po/../src/dialogs/clonetiler.cpp:1675 +msgid "P1: simple translation" +msgstr "P1: ਸਧਾਰਨ ਅਨੁਵਾਦ" + +#: ../../po/../src/dialogs/clonetiler.cpp:1676 +msgid "P2: 180° rotation" +msgstr "P2: 180° ਘੁੰਮਣ" + +#: ../../po/../src/dialogs/clonetiler.cpp:1677 +msgid "PM: reflection" +msgstr "PM: ਪਰਛਾਵਾਂ" + +#. TRANSLATORS: "glide reflection" is a reflection and a translation combined. +#. For more info, see http://mathforum.org/sum95/suzanne/symsusan.html +#: ../../po/../src/dialogs/clonetiler.cpp:1680 +msgid "PG: glide reflection" +msgstr "PG: ਤਿਲਕਣ ਪਰਛਾਵਾਂ" + +#: ../../po/../src/dialogs/clonetiler.cpp:1681 +msgid "CM: reflection + glide reflection" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1682 +msgid "PMM: reflection + reflection" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1683 +msgid "PMG: reflection + 180° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1684 +msgid "PGG: glide reflection + 180° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1685 +msgid "CMM: reflection + reflection + 180° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1686 +msgid "P4: 90° rotation" +msgstr "P4: 90° ਘੁੰਮਣ" + +#: ../../po/../src/dialogs/clonetiler.cpp:1687 +msgid "P4M: 90° rotation + 45° reflection" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1688 +msgid "P4G: 90° rotation + 90° reflection" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1689 +msgid "P3: 120° rotation" +msgstr "P3: 120° ਘੁੰਮਣ" + +#: ../../po/../src/dialogs/clonetiler.cpp:1690 +msgid "P31M: reflection + 120° rotation, dense" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1691 +msgid "P3M1: reflection + 120° rotation, sparse" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1692 +msgid "P6: 60° rotation" +msgstr "P6: 60° ਘੁੰਮਣ" + +#: ../../po/../src/dialogs/clonetiler.cpp:1693 +msgid "P6M: reflection + 60° rotation" +msgstr "P6M: ਪਰਿਵਰਤਤ + 60° ਘੁੰਮਣ" + +#: ../../po/../src/dialogs/clonetiler.cpp:1721 +msgid "S_hift" +msgstr "S_hift" + +#. TRANSLATORS: "shift" means: the tiles will be shifted (offset) horizontally by this amount +#: ../../po/../src/dialogs/clonetiler.cpp:1731 +#, no-c-format +msgid "Shift X:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1739 +#, no-c-format +msgid "Horizontal shift per row (in % of tile width)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1747 +#, no-c-format +msgid "Horizontal shift per column (in % of tile width)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1754 +msgid "Randomize the horizontal shift by this percentage" +msgstr "" + +#. TRANSLATORS: "shift" means: the tiles will be shifted (offset) vertically by this amount +#: ../../po/../src/dialogs/clonetiler.cpp:1764 +#, no-c-format +msgid "Shift Y:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1772 +#, no-c-format +msgid "Vertical shift per row (in % of tile height)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1780 +#, no-c-format +msgid "Vertical shift per column (in % of tile height)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1787 +msgid "Randomize the vertical shift by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1795 +msgid "Exponent:" +msgstr "ਐਕਸਪੋਨੈਟ:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1802 +msgid "Whether rows are spaced evenly (1), converge (<1) or diverge (>1)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1809 +msgid "Whether columns are spaced evenly (1), converge (<1) or diverge (>1)" +msgstr "" + +#. TRANSLATORS: "Alternate" is a verb here +#: ../../po/../src/dialogs/clonetiler.cpp:1817 +#: ../../po/../src/dialogs/clonetiler.cpp:1907 +#: ../../po/../src/dialogs/clonetiler.cpp:1966 +#: ../../po/../src/dialogs/clonetiler.cpp:2022 +#: ../../po/../src/dialogs/clonetiler.cpp:2153 +msgid "Alternate:" +msgstr "ਬਦਲ:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1823 +msgid "Alternate the sign of shifts for each row" +msgstr "ਹਰ ਕਤਾਰ ਲਈ ਬਦਲਣ ਦਾ ਬਦਲਵਾਂ ਨਿਸ਼ਾਨ" + +#: ../../po/../src/dialogs/clonetiler.cpp:1828 +msgid "Alternate the sign of shifts for each column" +msgstr "ਹਰ ਕਾਲਮ ਲਈ ਬਦਲਣ ਦਾ ਬਦਲਵਾਂ ਨਿਸ਼ਾਨ" + +#: ../../po/../src/dialogs/clonetiler.cpp:1837 +msgid "Sc_ale" +msgstr "ਪੈਮਾਨਾ(_a)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1845 +msgid "Scale X:" +msgstr "X ਪੈਮਾਨਾ:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1853 +#, no-c-format +msgid "Horizontal scale per row (in % of tile width)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1861 +#, no-c-format +msgid "Horizontal scale per column (in % of tile width)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1868 +msgid "Randomize the horizontal scale by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1876 +msgid "Scale Y:" +msgstr "Y ਪੈਮਾਨਾ:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1884 +#, no-c-format +msgid "Vertical scale per row (in % of tile height)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1892 +#, no-c-format +msgid "Vertical scale per column (in % of tile height)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1899 +msgid "Randomize the vertical scale by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1913 +msgid "Alternate the sign of scales for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1918 +msgid "Alternate the sign of scales for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1927 +msgid "_Rotation" +msgstr "ਘੁੰਮਾਓ(_R)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1935 +msgid "Angle:" +msgstr "ਕੋਣ:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1943 +#, no-c-format +msgid "Rotate tiles by this angle for each row" +msgstr "ਹਰ ਕਤਾਰ ਵਿੱਚ ਟਾਇਲਾਂ ਨੂੰ ਇਸ ਕੋਣ ਨਾਲ ਘੁੰਮਾਓ" + +#: ../../po/../src/dialogs/clonetiler.cpp:1951 +#, no-c-format +msgid "Rotate tiles by this angle for each column" +msgstr "ਹਰ ਕਾਲਮ ਵਿੱਚ ਟਾਇਲਾਂ ਨੂੰ ਇਸ ਕੋਣ ਨਾਲ ਘੁੰਮਾਓ" + +#: ../../po/../src/dialogs/clonetiler.cpp:1958 +msgid "Randomize the rotation angle by this percentage" +msgstr "ਇਸ ਫ਼ੀ-ਸਦੀ ਨਾਲ ਘੁੰਮਾਉਣ ਕੋਣ ਰਲਵਾਂ" + +#: ../../po/../src/dialogs/clonetiler.cpp:1972 +msgid "Alternate the rotation direction for each row" +msgstr "ਹਰ ਕਤਾਰ ਲਈ ਘੁੰਮਣ ਦਿਸ਼ਾ ਬਦਲਵੀਂ" + +#: ../../po/../src/dialogs/clonetiler.cpp:1977 +msgid "Alternate the rotation direction for each column" +msgstr "ਹਰ ਕਾਲਮ ਲਈ ਘੁੰਮਣ ਦਿਸ਼ਾ ਬਦਲਵੀਂ" + +#: ../../po/../src/dialogs/clonetiler.cpp:1985 +msgid "_Opacity" +msgstr "ਬਲੌਰੀ(_O)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1993 +msgid "Fade out:" +msgstr "ਫਿੱਕਾਪਨ ਵਾਧਾ:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2000 +msgid "Decrease tile opacity by this percentage for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2007 +msgid "Decrease tile opacity by this percentage for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2014 +msgid "Randomize the tile opacity by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2028 +msgid "Alternate the sign of opacity change for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2033 +msgid "Alternate the sign of opacity change for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2041 +msgid "Co_lor" +msgstr "ਰੰਗ(_l)" + +#: ../../po/../src/dialogs/clonetiler.cpp:2046 +msgid "Initial color: " +msgstr "ਸ਼ੁਰੂਆਤੀ ਰੰਗ: " + +#: ../../po/../src/dialogs/clonetiler.cpp:2050 +msgid "Initial color of tiled clones" +msgstr "ਟਾਇਲ ਕੋਨਾਂ ਦਾ ਸ਼ੁਰੂਆਤੀ ਰੰਗ" + +#: ../../po/../src/dialogs/clonetiler.cpp:2050 +msgid "" +"Initial color for clones (works only if the original has unset fill or " +"stroke)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2065 +msgid "H:" +msgstr "H:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2072 +msgid "Change the tile hue by this percentage for each row" +msgstr "ਹਰ ਕਤਾਰ ਲਈ ਇਸ ਫ਼ੀ-ਸਦੀ ਨਾਲ ਟਾਇਲ ਰੰਗਤ ਤਬਦੀਲ" + +#: ../../po/../src/dialogs/clonetiler.cpp:2079 +msgid "Change the tile hue by this percentage for each column" +msgstr "ਹਰ ਕਾਲਮ ਲਈ ਇਸ ਫ਼ੀ-ਸਦੀ ਨਾਲ ਟਾਇਲ ਰੰਗਤ ਤਬਦੀਲ" + +#: ../../po/../src/dialogs/clonetiler.cpp:2086 +msgid "Randomize the tile hue by this percentage" +msgstr "ਇਸ ਫ਼ੀ-ਸਦੀ ਨਾਲ ਟਾਇਲ ਰੰਗਤ ਰਲਾਓ" + +#: ../../po/../src/dialogs/clonetiler.cpp:2095 +msgid "S:" +msgstr "S:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2102 +msgid "Change the color saturation by this percentage for each row" +msgstr "ਹਰ ਕਤਾਰ ਲਈ ਇਸ ਫ਼ੀ-ਸਦੀ ਨਾਲ ਰੰਗ ਸੰਤਰਿਪਤਾ ਤਬਦੀਲ" + +#: ../../po/../src/dialogs/clonetiler.cpp:2109 +msgid "Change the color saturation by this percentage for each column" +msgstr "ਹਰ ਕਾਲਮ ਲਈ ਇਸ ਫ਼ੀ-ਸਦੀ ਨਾਲ ਰੰਗ ਸੰਤਰਿਪਤਾ ਤਬਦੀਲ" + +#: ../../po/../src/dialogs/clonetiler.cpp:2116 +msgid "Randomize the color saturation by this percentage" +msgstr "ਇਸ ਫ਼ੀ-ਸਦੀ ਨਾਲ ਰੰਗ ਸੰਤਰਿਪਤਾ ਰਲਾਓ" + +#: ../../po/../src/dialogs/clonetiler.cpp:2124 +msgid "L:" +msgstr "L:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2131 +msgid "Change the color lightness by this percentage for each row" +msgstr "ਹਰ ਕਤਾਰ ਲਈ ਰੰਗ ਦੀ ਚਮਕ ਇਹ ਫ਼ੀ-ਸਦੀ ਤਬਦੀਲ" + +#: ../../po/../src/dialogs/clonetiler.cpp:2138 +msgid "Change the color lightness by this percentage for each column" +msgstr "ਹਰ ਕਾਲਮ ਲਈ ਰੰਗ ਦੀ ਚਮਕ ਇਹ ਫ਼ੀ-ਸਦੀ ਤਬਦੀਲ" + +#: ../../po/../src/dialogs/clonetiler.cpp:2145 +msgid "Randomize the color lightness by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2159 +msgid "Alternate the sign of color changes for each row" +msgstr "ਹਰ ਕਤਾਰ ਲਈ ਰੰਗ ਤਬਦੀਲੀ ਦਾ ਨਿਸ਼ਾਨ ਬਦਲਵਾਂ" + +#: ../../po/../src/dialogs/clonetiler.cpp:2164 +msgid "Alternate the sign of color changes for each column" +msgstr "ਹਰ ਕਾਲਮ ਲਈ ਰੰਗ ਤਬਦੀਲੀ ਦਾ ਨਿਸ਼ਾਨ ਬਦਲਵਾਂ" + +#: ../../po/../src/dialogs/clonetiler.cpp:2172 +msgid "_Trace" +msgstr "ਪਿੱਛਾ ਖੋਜ(_T)" + +#: ../../po/../src/dialogs/clonetiler.cpp:2179 +msgid "Trace the drawing under the tiles" +msgstr "ਟਾਇਲਾਂ ਹੇਠ ਡਰਾਇੰਗ ਵਾਹੋ" + +#: ../../po/../src/dialogs/clonetiler.cpp:2183 +msgid "" +"For each clone, pick a value from the drawing in that clone's location and " +"apply it to the clone" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2197 +msgid "1. Pick from the drawing:" +msgstr "1. ਡਰਾਇੰਗ ਤੋਂ ਚੁਕੋ:" + +#. ----Hbox2 +#: ../../po/../src/dialogs/clonetiler.cpp:2208 +#: ../../po/../src/dialogs/clonetiler.cpp:2355 +#: ../../po/../src/ui/dialog/tracedialog.cpp:445 +msgid "Color" +msgstr "ਰੰਗ" + +#: ../../po/../src/dialogs/clonetiler.cpp:2209 +msgid "Pick the visible color and opacity" +msgstr "ਦਿੱਖ ਰੰਗ ਅਤੇ ਬਲੌਰੀਪਨ ਚੁਣੋ" + +#: ../../po/../src/dialogs/clonetiler.cpp:2216 +#: ../../po/../src/dialogs/clonetiler.cpp:2365 +#: ../share/extensions/dropshadow.inx.h:3 +msgid "Opacity" +msgstr "ਬਲੌਰੀਪਨ" + +#: ../../po/../src/dialogs/clonetiler.cpp:2217 +msgid "Pick the total accumulated opacity" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2224 +msgid "R" +msgstr "R" + +#: ../../po/../src/dialogs/clonetiler.cpp:2225 +msgid "Pick the Red component of the color" +msgstr "ਰੰਗ ਦਾ ਲਾਲ ਭਾਗ ਚੁਣੋ" + +#: ../../po/../src/dialogs/clonetiler.cpp:2232 +msgid "G" +msgstr "G" + +#: ../../po/../src/dialogs/clonetiler.cpp:2233 +msgid "Pick the Green component of the color" +msgstr "ਰੰਗ ਦਾ ਹਰਾ ਭਾਗ ਚੁਣੋ" + +#: ../../po/../src/dialogs/clonetiler.cpp:2240 +msgid "B" +msgstr "B" + +#: ../../po/../src/dialogs/clonetiler.cpp:2241 +msgid "Pick the Blue component of the color" +msgstr "ਰੰਗ ਦਾ ਨੀਲਾ ਭਾਗ ਚੁਣੋ" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2250 +msgid "clonetiler|H" +msgstr "H" + +#: ../../po/../src/dialogs/clonetiler.cpp:2251 +msgid "Pick the hue of the color" +msgstr "ਰੰਗ ਦੀ ਆਭਾ ਚੁਣੋ" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2260 +msgid "clonetiler|S" +msgstr "S" + +#: ../../po/../src/dialogs/clonetiler.cpp:2261 +msgid "Pick the saturation of the color" +msgstr "ਰੰਗ ਦੀ ਸੰਤਰਿਪਤਾ ਚੁਣੋ" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2270 +msgid "clonetiler|L" +msgstr "L" + +#: ../../po/../src/dialogs/clonetiler.cpp:2271 +msgid "Pick the lightness of the color" +msgstr "ਰੰਗ ਦੀ ਚਮਕ ਚੁਣੋ" + +#: ../../po/../src/dialogs/clonetiler.cpp:2281 +msgid "2. Tweak the picked value:" +msgstr "2. ਚੁਣੇ ਮੁੱਲ ਨੂੰ ਅਨੁਕੂਲ ਕਰੋ:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2291 +msgid "Gamma-correct:" +msgstr "ਗਾਮਾ-ਸੋਧ:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2296 +msgid "Shift the mid-range of the picked value upwards (>0) or downwards (<0)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2303 +msgid "Randomize:" +msgstr "ਰਲਵਾਂ:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2308 +msgid "Randomize the picked value by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2315 +msgid "Invert:" +msgstr "ਉਲਟ:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2319 +msgid "Invert the picked value" +msgstr "ਚੁਣੇ ਮੁੱਲ ਨੂੰ ਉਲਟਾਓ" + +#: ../../po/../src/dialogs/clonetiler.cpp:2325 +msgid "3. Apply the value to the clones':" +msgstr "3. ਸਮਰੂਪ 'ਤੇ ਮੁੱਲ ਲਾਗੂ ਕਰੋ':" + +#: ../../po/../src/dialogs/clonetiler.cpp:2335 +msgid "Presence" +msgstr "ਮੌਜੂਦਗੀ" + +#: ../../po/../src/dialogs/clonetiler.cpp:2338 +msgid "" +"Each clone is created with the probability determined by the picked value in " +"that point" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2345 +msgid "Size" +msgstr "ਅਕਾਰ" + +#: ../../po/../src/dialogs/clonetiler.cpp:2348 +msgid "Each clone's size is determined by the picked value in that point" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2358 +msgid "" +"Each clone is painted by the picked color (the original must have unset fill " +"or stroke)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2368 +msgid "Each clone's opacity is determined by the picked value in that point" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2395 +msgid "How many rows in the tiling" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2415 +msgid "How many columns in the tiling" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2445 +msgid "Width of the rectangle to be filled" +msgstr "ਚਤੁਰਭੁਜ ਭਰਨ ਲਈ ਚੌੜਾਈ" + +#: ../../po/../src/dialogs/clonetiler.cpp:2470 +msgid "Height of the rectangle to be filled" +msgstr "ਭਰਨ ਲਈ ਚਤੁਰਭੁਜ ਦੀ ਉਚਾਈ" + +#: ../../po/../src/dialogs/clonetiler.cpp:2485 +msgid "Rows, columns: " +msgstr "ਕਤਾਰਾਂ, ਕਾਲਮ: " + +#: ../../po/../src/dialogs/clonetiler.cpp:2486 +msgid "Create the specified number of rows and columns" +msgstr "ਦਿੱਤੀ ਕਤਾਰਾਂ ਅਤੇ ਕਾਲਮਾਂ ਨਾਲ ਬਣਾਓ" + +#: ../../po/../src/dialogs/clonetiler.cpp:2495 +msgid "Width, height: " +msgstr "ਚੌੜਾਈ, ਉਚਾਈ: " + +#: ../../po/../src/dialogs/clonetiler.cpp:2496 +msgid "Fill the specified width and height with the tiling" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2512 +msgid "Use saved size and position of the tile" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2515 +msgid "" +"Pretend that the size and position of the tile are the same as the last time " +"you tiled it (if any), instead of using the current size" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2539 +msgid " _Create " +msgstr " ਬਣਾਓ (_C) " + +#: ../../po/../src/dialogs/clonetiler.cpp:2541 +msgid "Create and tile the clones of the selection" +msgstr "ਚੋਣ ਦੇ ਸਮਰੂਪ ਬਣਾਓ ਅਤੇ ਟਾਇਲ" + +#. TRANSLATORS: if a group of objects are "clumped" together, then they +#. are unevenly spread in the given amount of space - as shown in the +#. diagrams on the left in the following screenshot: +#. http://www.inkscape.org/screenshots/gallery/inkscape-0.42-CVS-tiles-unclump.png +#. So unclumping is the process of spreading a number of objects out more evenly. +#: ../../po/../src/dialogs/clonetiler.cpp:2556 +msgid " _Unclump " +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2557 +msgid "Spread out clones to reduce clumping; can be applied repeatedly" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2563 +msgid " Re_move " +msgstr " ਹਟਾਓ(_m) " + +#: ../../po/../src/dialogs/clonetiler.cpp:2564 +msgid "Remove existing tiled clones of the selected object (siblings only)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2580 +msgid " R_eset " +msgstr " ਮੁੜ ਸੈਟ(_e) " + +#. TRANSLATORS: "change" is a noun here +#: ../../po/../src/dialogs/clonetiler.cpp:2582 +msgid "" +"Reset all shifts, scales, rotates, opacity and color changes in the dialog " +"to zero" +msgstr "" + +#: ../../po/../src/dialogs/color-picker.cpp:280 +msgid "Close" +msgstr "ਬੰਦ ਕਰੋ" + +#: ../../po/../src/dialogs/debugdialog.cpp:138 +msgid "Messages" +msgstr "ਸੁਨੇਹੇ" + +#. ## Add a menu for clear() +#: ../../po/../src/dialogs/debugdialog.cpp:144 +#: ../../po/../src/menus-skeleton.h:16 +#: ../../po/../src/ui/dialog/messages.cpp:56 +#: ../../po/../src/ui/dialog/scriptdialog.cpp:181 +msgid "_File" +msgstr "ਫਾਇਲ(_F)" + +#. TRANSLATORS: "Clear" is a verb here +#: ../../po/../src/dialogs/debugdialog.cpp:145 +#: ../../po/../src/dialogs/find.cpp:753 +#: ../../po/../src/ui/dialog/messages.cpp:57 +#: ../../po/../src/ui/dialog/scriptdialog.cpp:182 +msgid "_Clear" +msgstr "ਸਾਫ਼(_C)" + +#: ../../po/../src/dialogs/debugdialog.cpp:147 +#: ../../po/../src/ui/dialog/messages.cpp:59 +msgid "Capture log messages" +msgstr "ਲਾਗ ਸੁਨੇਹੇ ਫੜੋ" + +#: ../../po/../src/dialogs/debugdialog.cpp:149 +#: ../../po/../src/ui/dialog/messages.cpp:61 +msgid "Release log messages" +msgstr "ਲਾਗ ਸੁਨੇਹੇ ਛੱਡੋ" + +#. Notebook tab +#: ../../po/../src/dialogs/desktop-properties.cpp:909 +#: ../../po/../src/ui/dialog/document-preferences.cpp:89 +#: ../../po/../src/ui/widget/panel.cpp:107 +msgid "Grid" +msgstr "ਗਰਿੱਡ" + +#. Checkbuttons +#. / \todo FIXME: gray out snapping when grid is off +#. / \todo FIXME: gray out snapping when grid is off. +#. / Dissenting view: you want snapping without grid. +#: ../../po/../src/dialogs/desktop-properties.cpp:917 +#: ../../po/../src/ui/dialog/document-preferences.cpp:179 +msgid "Show grid" +msgstr "ਗਰਿੱਡ ਵੇਖਾਓ" + +#: ../../po/../src/dialogs/desktop-properties.cpp:917 +#: ../../po/../src/ui/dialog/document-preferences.cpp:179 +#: ../../po/../src/verbs.cpp:2115 +msgid "Show or hide grid" +msgstr "ਗਰਿੱਡ ਵੇਖਾਓ ਜਾਂ ਓਹਲੇ" + +#: ../../po/../src/dialogs/desktop-properties.cpp:918 +#: ../../po/../src/ui/dialog/document-preferences.cpp:180 +msgid "Snap bounding boxes to grid" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:918 +#: ../../po/../src/dialogs/desktop-properties.cpp:1001 +#: ../../po/../src/ui/dialog/document-preferences.cpp:181 +#: ../../po/../src/ui/dialog/document-preferences.cpp:236 +msgid "Snap the edges of the object bounding boxes" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:919 +#: ../../po/../src/ui/dialog/document-preferences.cpp:183 +msgid "Snap nodes to grid" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:919 +#: ../../po/../src/dialogs/desktop-properties.cpp:1002 +#: ../../po/../src/ui/dialog/document-preferences.cpp:184 +#: ../../po/../src/ui/dialog/document-preferences.cpp:239 +msgid "Snap path nodes, text baselines, ellipse centers, etc." +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:937 +#: ../../po/../src/ui/dialog/document-preferences.cpp:186 +msgid "Grid units:" +msgstr "ਗਰਿੱਡ ਇਕਾਈ:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:939 +#: ../../po/../src/ui/dialog/document-preferences.cpp:187 +msgid "Origin X:" +msgstr "ਧੁਰਾ X:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:942 +#: ../../po/../src/ui/dialog/document-preferences.cpp:189 +msgid "Origin Y:" +msgstr "ਧੁਰਾ Y:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:945 +#: ../../po/../src/ui/dialog/document-preferences.cpp:191 +msgid "Spacing X:" +msgstr "X ਦੂਰੀ:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:948 +#: ../../po/../src/ui/dialog/document-preferences.cpp:193 +msgid "Spacing Y:" +msgstr "Y ਦੂਰੀ:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:952 +#: ../../po/../src/dialogs/desktop-properties.cpp:1013 +#: ../../po/../src/ui/dialog/document-preferences.cpp:195 +#: ../../po/../src/ui/dialog/document-preferences.cpp:241 +msgid "Snap units:" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:955 +#: ../../po/../src/dialogs/desktop-properties.cpp:1016 +#: ../../po/../src/ui/dialog/document-preferences.cpp:196 +#: ../../po/../src/ui/dialog/document-preferences.cpp:242 +msgid "Snap distance:" +msgstr "ਸਨੇਪ ਦੂਰੀ:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:958 +#: ../../po/../src/ui/dialog/document-preferences.cpp:199 +msgid "Grid line color:" +msgstr "ਗਰਿੱਡ ਰੇਖਾ ਰੰਗ:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:959 +#: ../../po/../src/ui/dialog/document-preferences.cpp:199 +msgid "Grid line color" +msgstr "ਗਰਿੱਡ ਰੇਖਾ ਰੰਗ" + +#: ../../po/../src/dialogs/desktop-properties.cpp:959 +#: ../../po/../src/ui/dialog/document-preferences.cpp:200 +msgid "Color of grid lines" +msgstr "ਗਰਿੱਡ ਰੇਖਾਵਾਂ ਦਾ ਰੰਗ" + +#: ../../po/../src/dialogs/desktop-properties.cpp:961 +#: ../../po/../src/ui/dialog/document-preferences.cpp:201 +msgid "Major grid line color:" +msgstr "ਮੁੱਖ ਗਰਿੱਡ ਰੇਖਾ ਰੰਗ:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:962 +#: ../../po/../src/ui/dialog/document-preferences.cpp:201 +msgid "Major grid line color" +msgstr "ਮੁੱਖ ਗਰਿੱਡ ਰੇਖਾ ਰੰਗ" + +#: ../../po/../src/dialogs/desktop-properties.cpp:962 +#: ../../po/../src/ui/dialog/document-preferences.cpp:202 +msgid "Color of the major (highlighted) grid lines" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:965 +#: ../../po/../src/ui/dialog/document-preferences.cpp:204 +msgid "Major grid line every:" +msgstr "" + +#. TRANSLATORS: This belongs to the "Major grid line every:" string, +#. see grid settings in the "Document Preferences" dialog +#: ../../po/../src/dialogs/desktop-properties.cpp:977 +#: ../../po/../src/ui/dialog/document-preferences.cpp:204 +msgid "lines" +msgstr "ਰੇਖਾਵਾਂ" + +#. Guidelines page +#: ../../po/../src/dialogs/desktop-properties.cpp:991 +#: ../../po/../src/ui/dialog/document-preferences.cpp:90 +msgid "Guides" +msgstr "ਗਾਈਡ" + +#. / \todo FIXME: gray out snapping when guides are off +#. / Dissenting view: you want snapping without guides. +#: ../../po/../src/dialogs/desktop-properties.cpp:1000 +#: ../../po/../src/ui/dialog/document-preferences.cpp:234 +msgid "Show guides" +msgstr "ਗਰਿੱਡ ਵੇਖਾਓ" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1000 +#: ../../po/../src/ui/dialog/document-preferences.cpp:234 +#: ../../po/../src/verbs.cpp:2116 +msgid "Show or hide guides" +msgstr "ਗਾਈਡ ਵੇਖਾਓ ਜਾਂ ਓਹਲੇ" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1001 +#: ../../po/../src/ui/dialog/document-preferences.cpp:235 +msgid "Snap bounding boxes to guides" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1002 +#: ../../po/../src/ui/dialog/document-preferences.cpp:238 +msgid "Snap points to guides" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1020 +#: ../../po/../src/ui/dialog/document-preferences.cpp:243 +msgid "Guide color:" +msgstr "ਗਾਈਡ ਰੰਗ:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1021 +#: ../../po/../src/ui/dialog/document-preferences.cpp:243 +msgid "Guideline color" +msgstr "ਗਾਈਡ-ਰੇਖਾ ਰੰਗ" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1021 +#: ../../po/../src/ui/dialog/document-preferences.cpp:244 +msgid "Color of guidelines" +msgstr "ਗਾਈਡ-ਰੰਗ ਦਾ ਰੰਗ" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1023 +#: ../../po/../src/ui/dialog/document-preferences.cpp:245 +msgid "Highlight color:" +msgstr "ਉਘਾੜਨ ਰੰਗ:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1024 +#: ../../po/../src/ui/dialog/document-preferences.cpp:245 +msgid "Highlighted guideline color" +msgstr "ਉਘਾੜਨ ਗਾਈਡ ਰੰਗ" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1024 +#: ../../po/../src/ui/dialog/document-preferences.cpp:246 +msgid "Color of a guideline when it is under mouse" +msgstr "ਜਦੋਂ ਮਾਊਸ ਹੇਠ ਹੋਵੇ ਤਾਂ ਗਾਈਡ-ਰੇਖਾ ਦਾ ਰੰਗ" + +#. Page page +#: ../../po/../src/dialogs/desktop-properties.cpp:1029 +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:855 +#: ../../po/../src/ui/dialog/document-preferences.cpp:88 +#: ../../po/../src/widgets/desktop-widget.cpp:1061 +msgid "Page" +msgstr "ਸਫ਼ਾ" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1039 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +msgid "Background:" +msgstr "ਪਿੱਠਭੂਮੀ:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1040 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +msgid "Background color" +msgstr "ਪਿੱਠਭੂਮੀ ਰੰਗ" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1041 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +msgid "" +"Color and transparency of the page background (also used for bitmap export)" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1045 +#: ../../po/../src/ui/dialog/document-preferences.cpp:147 +#, fuzzy +msgid "Show page border" +msgstr "ਸਫ਼ਾ ਛਾਂ ਵੇਖਾਓ" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1049 +#: ../../po/../src/ui/dialog/document-preferences.cpp:148 +msgid "Border on top of drawing" +msgstr "ਡਰਾਇੰਗ ਦੇ ਕਿਨਾਰੇ 'ਤੇ ਹਾਸ਼ੀਆ" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1052 +#: ../../po/../src/ui/dialog/document-preferences.cpp:149 +msgid "Border color:" +msgstr "ਹਾਸ਼ੀਆ ਰੰਗ:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1053 +#: ../../po/../src/ui/dialog/document-preferences.cpp:149 +#, fuzzy +msgid "Page border color" +msgstr "ਹਾਸ਼ੀਆ ਰੰਗ:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1054 +#: ../../po/../src/ui/dialog/document-preferences.cpp:150 +#, fuzzy +msgid "Color of the page border" +msgstr "ਗਰਿੱਡ ਰੇਖਾਵਾਂ ਦਾ ਰੰਗ" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1059 +#: ../../po/../src/ui/dialog/document-preferences.cpp:152 +msgid "Show page shadow" +msgstr "ਸਫ਼ਾ ਛਾਂ ਵੇਖਾਓ" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1063 +#: ../../po/../src/ui/dialog/document-preferences.cpp:153 +msgid "Default units:" +msgstr "ਮੂਲ ਇਕਾਈ:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1069 +msgid "Units for the tool controls, ruler, and the statusbar" +msgstr "ਸੰਦ ਕੰਟਰੋਕ, ਪੈਮਾਨਾ ਅਤੇ ਹਾਲਤ-ਪੱਟੀ ਲਈ ਇਕਾਈ" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1086 +#: ../../po/../src/ui/widget/page-sizer.cpp:209 +msgid "Page size:" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1110 +#: ../../po/../src/ui/widget/page-sizer.cpp:219 +msgid "Custom" +msgstr "ਪਸੰਦੀਦਾ" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1121 +#: ../../po/../src/ui/widget/page-sizer.cpp:225 +#, fuzzy +msgid "Page orientation:" +msgstr "ਤਬਦੀਲੀਆਂ ਹਟਾਓ(_T)" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1133 +#: ../../po/../src/ui/widget/page-sizer.cpp:232 +msgid "Landscape" +msgstr "ਲੈਡਸਕੇਪ" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1139 +#: ../../po/../src/ui/widget/page-sizer.cpp:234 +msgid "Portrait" +msgstr "ਪੋਰਟਰੇਟ" + +#. Custom paper frame +#: ../../po/../src/dialogs/desktop-properties.cpp:1148 +#: ../../po/../src/ui/widget/page-sizer.cpp:249 +#, fuzzy +msgid "Custom size" +msgstr "ਪਸੰਦੀਦਾ" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1160 +#: ../../po/../src/dialogs/export.cpp:269 +#: ../../po/../src/ui/widget/page-sizer.cpp:261 +msgid "Units:" +msgstr "ਇਕਾਈਆਂ:" + +#. Stroke width +#: ../../po/../src/dialogs/desktop-properties.cpp:1162 +#: ../../po/../src/dialogs/export.cpp:310 +#: ../../po/../src/dialogs/object-attributes.cpp:55 +#: ../../po/../src/dialogs/stroke-style.cpp:985 +#: ../../po/../src/ui/widget/page-sizer.cpp:262 +#: ../../po/../src/widgets/toolbox.cpp:1957 +msgid "Width:" +msgstr "ਚੌੜਾਈ:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1183 +#: ../../po/../src/dialogs/export.cpp:326 +#: ../../po/../src/dialogs/export.cpp:431 +#: ../../po/../src/dialogs/object-attributes.cpp:56 +#: ../../po/../src/ui/widget/page-sizer.cpp:263 +msgid "Height:" +msgstr "ਉਚਾਈ:" + +#. +#. * Ownership metadata tab +#. +#: ../../po/../src/dialogs/desktop-properties.cpp:1206 +msgid "Metadata" +msgstr "ਮੈਟਾਡਾਟਾ" + +#. add license selector pull-down +#: ../../po/../src/dialogs/desktop-properties.cpp:1225 +msgid "License" +msgstr "ਲਾਈਸੈਂਸ" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1255 +msgid "Proprietary" +msgstr "ਨਿੱਜੀ" + +#: ../../po/../src/dialogs/display-settings.cpp:212 +msgid "When transforming, show:" +msgstr "ਜਦੋਂ ਤਬਦੀਲੀ ਹੋਵੇ ਤਾਂ, ਵੇਖਾਓ:" + +#: ../../po/../src/dialogs/display-settings.cpp:223 +msgid "Objects" +msgstr "ਇਕਾਈ" + +#: ../../po/../src/dialogs/display-settings.cpp:224 +msgid "Show the actual objects when moving or transforming" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:231 +msgid "Box outline" +msgstr "ਬਕਸਾ ਬਾਹਰੀ-ਰੇਖਾ" + +#: ../../po/../src/dialogs/display-settings.cpp:232 +msgid "Show only a box outline of the objects when moving or transforming" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:238 +msgid "Per-object selection cue:" +msgstr "" + +#. sorationsnapsperpi == 0 means no snapping +#: ../../po/../src/dialogs/display-settings.cpp:249 +#: ../../po/../src/dialogs/display-settings.cpp:386 +#: ../../po/../src/dialogs/display-settings.cpp:441 +#: ../../po/../src/dialogs/display-settings.cpp:1482 +#: ../../po/../src/dialogs/stroke-style.cpp:791 +#: ../../po/../src/interface.cpp:741 +#: ../../po/../src/ui/widget/selected-style.cpp:100 +#: ../../po/../src/verbs.cpp:1842 +msgid "None" +msgstr "ਕੋਈ ਨਹੀਂ" + +#: ../../po/../src/dialogs/display-settings.cpp:250 +msgid "No per-object selection indication" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:256 +msgid "Mark" +msgstr "ਨਿਸ਼ਾਨਬੱਧ" + +#: ../../po/../src/dialogs/display-settings.cpp:257 +msgid "Each selected object has a diamond mark in the top left corner" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:264 +msgid "Box" +msgstr "ਡੱਬਾ" + +#: ../../po/../src/dialogs/display-settings.cpp:265 +msgid "Each selected object displays its bounding box" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:270 +msgid "Default scale origin:" +msgstr "ਮੂਲ ਪੈਮਾਨਾ ਖੇਤਰ:" + +#: ../../po/../src/dialogs/display-settings.cpp:281 +msgid "Opposite bounding box edge" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:282 +msgid "Default scale origin will be on the bounding box of the item" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:288 +msgid "Farthest opposite node" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:289 +msgid "Default scale origin will be on the bounding box of the item's points" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:341 +msgid "degrees" +msgstr "ਡਿਗਰੀ" + +#: ../../po/../src/dialogs/display-settings.cpp:350 +msgid "" +"Rotating with Ctrl pressed snaps every that much degrees; also, pressing " +"[ or ] rotates by this amount" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:407 +msgid "Rotation snaps every:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:430 +msgid "" +"None: dialogs are treated as regular windows; Normal: dialogs stay on top of " +"document windows; Aggressive: same as Normal but may work better with some " +"window managers." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:451 +msgid "Normal" +msgstr "ਸਧਾਰਨ" + +#: ../../po/../src/dialogs/display-settings.cpp:461 +msgid "Aggressive" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:475 +msgid "Dialogs on top:" +msgstr "ਵਾਰਤਾਲਾਪ ਉੱਪਰ:" + +#: ../../po/../src/dialogs/display-settings.cpp:645 +msgid "Show selection cue" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:646 +msgid "" +"Whether selected objects display a selection cue (the same as in selector)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:657 +msgid "Enable gradient editing" +msgstr "ਢਾਲਵਾਂ ਸੋਧ ਯੋਗ" + +#: ../../po/../src/dialogs/display-settings.cpp:658 +msgid "Whether selected objects display gradient editing controls" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:719 +msgid "No objects selected to take the style from." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:728 +msgid "" +"More than one object selected. Cannot take style from multiple " +"objects." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:767 +msgid "Create new objects with:" +msgstr "ਨਵੀਆਂ ਇਕਾਈਆਂ ਬਣਾਓ:" + +#: ../../po/../src/dialogs/display-settings.cpp:777 +msgid "Take from selection" +msgstr "ਚੋਣ ਤੋਂ ਲਵੋ" + +#: ../../po/../src/dialogs/display-settings.cpp:778 +msgid "Remember the style of the (first) selected object as this tool's style" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:782 +#, fuzzy +msgid "Last used style" +msgstr "ਸ਼ੈਲੀ ਚੇਪੋ(_S)" + +#: ../../po/../src/dialogs/display-settings.cpp:782 +msgid "Apply the style you last set on an object" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:790 +msgid "This tool's own style:" +msgstr "ਇਹ ਸੰਦ ਦੀ ਆਪਣੇ ਸ਼ੈਲੀ:" + +#: ../../po/../src/dialogs/display-settings.cpp:790 +msgid "" +"Each tool may store its own style to apply to the newly created objects. Use " +"the button below to set it." +msgstr "" + +#. Mouse +#: ../../po/../src/dialogs/display-settings.cpp:877 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:55 +msgid "Mouse" +msgstr "ਮਾਊਸ" + +#. TRANSLATORS: "Grab" is a noun here. "Grab sensitivity" is intended to mean how +#. * close on the screen you need to be to an object to be able to grab it with mouse (in +#. * pixels). +#: ../../po/../src/dialogs/display-settings.cpp:883 +msgid "Grab sensitivity:" +msgstr "ਸੰਵੇਦਨਸ਼ੀਲਤਾ ਫੜੋ:" + +#: ../../po/../src/dialogs/display-settings.cpp:884 +msgid "" +"How close on the screen you need to be to an object to be able to grab it " +"with mouse (in screen pixels)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:885 +#: ../../po/../src/dialogs/display-settings.cpp:897 +#: ../../po/../src/dialogs/display-settings.cpp:912 +#: ../../po/../src/dialogs/display-settings.cpp:930 +#: ../../po/../src/dialogs/display-settings.cpp:970 +msgid "pixels" +msgstr "ਪਿਕਸਲ" + +#: ../../po/../src/dialogs/display-settings.cpp:895 +msgid "Click/drag threshold:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:896 +msgid "" +"Maximum mouse drag (in screen pixels) which is considered a click, not a drag" +msgstr "" + +#. Scrolling +#: ../../po/../src/dialogs/display-settings.cpp:907 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:56 +msgid "Scrolling" +msgstr "ਘੁੰਮਦਾ" + +#: ../../po/../src/dialogs/display-settings.cpp:910 +msgid "Mouse wheel scrolls by:" +msgstr "ਮਾਊਸ ਪਹੀਆ ਸਰਕੋਲ ਹੋਵੇ:" + +#: ../../po/../src/dialogs/display-settings.cpp:911 +msgid "" +"One mouse wheel notch scrolls by this distance in screen pixels " +"(horizontally with Shift)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:920 +msgid "Ctrl+arrows" +msgstr "Ctrl+ਤੀਰ" + +#: ../../po/../src/dialogs/display-settings.cpp:928 +msgid "Scroll by:" +msgstr "ਸਕਰੋਲ:" + +#: ../../po/../src/dialogs/display-settings.cpp:929 +msgid "Pressing Ctrl+arrow key scrolls by this distance (in screen pixels)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:939 +msgid "Acceleration:" +msgstr "ਪਰਵੇਸ਼:" + +#: ../../po/../src/dialogs/display-settings.cpp:940 +msgid "" +"Pressing and holding Ctrl+arrow will gradually speed up scrolling (0 for no " +"acceleration)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:949 +msgid "Autoscrolling" +msgstr "ਸਵੈ-ਸਕਰੋਲ" + +#: ../../po/../src/dialogs/display-settings.cpp:957 +msgid "Speed:" +msgstr "ਗਤੀ:" + +#: ../../po/../src/dialogs/display-settings.cpp:958 +msgid "" +"How fast the canvas autoscrolls when you drag beyond canvas edge (0 to turn " +"autoscroll off)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:968 +#: ../../po/../src/ui/dialog/tracedialog.cpp:357 +#: ../../po/../src/ui/dialog/tracedialog.cpp:390 +msgid "Threshold:" +msgstr "ਅਧਾਰ ਮੁੱਲ:" + +#: ../../po/../src/dialogs/display-settings.cpp:969 +msgid "" +"How far (in screen pixels) you need to be from the canvas edge to trigger " +"autoscroll; positive is outside the canvas, negative is within the canvas" +msgstr "" + +#. Steps +#: ../../po/../src/dialogs/display-settings.cpp:979 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:57 +msgid "Steps" +msgstr "ਪਗ਼" + +#: ../../po/../src/dialogs/display-settings.cpp:982 +msgid "Arrow keys move by:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:983 +msgid "" +"Pressing an arrow key moves selected object(s) or node(s) by this distance " +"(in px units)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:984 +#: ../../po/../src/dialogs/display-settings.cpp:995 +#: ../../po/../src/dialogs/display-settings.cpp:1006 +#: ../../po/../src/helper/units.cpp:42 +msgid "px" +msgstr "px" + +#: ../../po/../src/dialogs/display-settings.cpp:993 +msgid "> and < scale by:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:994 +msgid "" +"Pressing > or < scales selection up or down by this increment (in px units)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1004 +msgid "Inset/Outset by:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1005 +msgid "" +"Inset and Outset commands displace the path by this distance (in px units)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1017 +msgid "Compass-like display of angles" +msgstr "" + +#. TRANSLATORS: "positive clockwise" means "increasing in clockwise direction" +#: ../../po/../src/dialogs/display-settings.cpp:1019 +msgid "" +"When on, angles are displayed with 0 at north, 0 to 360 range, positive " +"clockwise; otherwise with 0 at east, -180 to 180 range, positive " +"counterclockwise" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1026 +msgid "Zoom in/out by:" +msgstr "ਜ਼ੂਮ ਅੰਦਰ/ਬਾਹਰ:" + +#: ../../po/../src/dialogs/display-settings.cpp:1027 +msgid "" +"Zoom tool click, +/- keys, and middle click zoom in and out by this " +"multiplier" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1028 +#: ../../po/../src/helper/units.cpp:44 +msgid "%" +msgstr "%" + +#. Tools +#: ../../po/../src/dialogs/display-settings.cpp:1037 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:58 +msgid "Tools" +msgstr "ਸੰਦ" + +#: ../../po/../src/dialogs/display-settings.cpp:1045 +msgid "Selector" +msgstr "ਚੋਣਕਾਰ" + +#: ../../po/../src/dialogs/display-settings.cpp:1056 +msgid "Node" +msgstr "ਨੋਡ" + +#: ../../po/../src/dialogs/display-settings.cpp:1064 +#: ../../po/../src/verbs.cpp:2073 +#: ../../po/../src/widgets/desktop-widget.cpp:277 +msgid "Zoom" +msgstr "ਜ਼ੂਮ" + +#. The 4 shape tools +#: ../../po/../src/dialogs/display-settings.cpp:1071 +msgid "Shapes" +msgstr "ਸ਼ਕਲ" + +#: ../../po/../src/dialogs/display-settings.cpp:1079 +#: ../../po/../src/verbs.cpp:2055 +msgid "Rectangle" +msgstr "ਚਤੁਰਭੁਜ" + +#: ../../po/../src/dialogs/display-settings.cpp:1085 +#: ../../po/../src/verbs.cpp:2057 +msgid "Ellipse" +msgstr "ਅੰਡਾਕਾਰ" + +#: ../../po/../src/dialogs/display-settings.cpp:1091 +#: ../../po/../src/verbs.cpp:2059 +msgid "Star" +msgstr "ਤਾਰਾ" + +#: ../../po/../src/dialogs/display-settings.cpp:1097 +#: ../../po/../src/verbs.cpp:2061 +msgid "Spiral" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1111 +#: ../../po/../src/verbs.cpp:2063 +msgid "Pencil" +msgstr "ਪਿਨਸਲ" + +#: ../../po/../src/dialogs/display-settings.cpp:1114 +msgid "Tolerance:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1115 +msgid "" +"This value affects the amount of smoothing applied to freehand lines; lower " +"values produce more uneven paths with more nodes" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1131 +#: ../../po/../src/verbs.cpp:2065 +msgid "Pen" +msgstr "ਪੈਨ" + +#: ../../po/../src/dialogs/display-settings.cpp:1140 +#: ../../po/../src/verbs.cpp:2067 +msgid "Calligraphy" +msgstr "ਕੈਲੀਗਰਾਫ਼" + +#: ../../po/../src/dialogs/display-settings.cpp:1147 +#: ../../po/../src/dialogs/text-edit.cpp:353 +#: ../../po/../src/ui/dialog/text-properties.cpp:37 +#: ../../po/../src/verbs.cpp:2069 +msgid "Text" +msgstr "ਪਾਠ" + +#: ../../po/../src/dialogs/display-settings.cpp:1157 +#: ../../po/../src/verbs.cpp:2071 +msgid "Gradient" +msgstr "ਢਾਲਵਾਂ" + +#: ../../po/../src/dialogs/display-settings.cpp:1164 +#: ../../po/../src/verbs.cpp:2077 +#, fuzzy +msgid "Connector" +msgstr "ਨਿਰਮਾਤਾ" + +#: ../../po/../src/dialogs/display-settings.cpp:1171 +#: ../../po/../src/verbs.cpp:2075 +msgid "Dropper" +msgstr "ਚੂਸਕ" + +#. Windows +#: ../../po/../src/dialogs/display-settings.cpp:1183 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:59 +msgid "Windows" +msgstr "ਝਰੋਖੇ" + +#: ../../po/../src/dialogs/display-settings.cpp:1188 +msgid "Save window geometry" +msgstr "ਝਰੋਖੇ ਜੁਮੈਟਰੀ ਵਿੱਚ ਸੰਭਾਲੋ" + +#: ../../po/../src/dialogs/display-settings.cpp:1189 +msgid "" +"Save the window size and position with each document (only for Inkscape SVG " +"format)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1196 +msgid "Dialogs are hidden in taskbar" +msgstr "ਕੰਮ-ਪੱਟੀ ਵਿੱਚ ਵਾਰਤਾਲਾਪ ਓਹਲੇ" + +#: ../../po/../src/dialogs/display-settings.cpp:1197 +msgid "Whether dialog windows are to be hidden in the window manager taskbar" +msgstr "ਕੀ ਝਰੋਖਾ ਪਰਬੰਧਕ ਕੰਮ-ਪੱਟੀ ਵਿੱਚ ਵਾਰਤਾਲਾਪ ਝਰੋਖਿਆਂ ਨੂੰ ਲੁਕਵਾਂ ਰੱਖਿਆ ਜਾਵੇ" + +#: ../../po/../src/dialogs/display-settings.cpp:1204 +msgid "Zoom when window is resized" +msgstr "ਜਦੋਂ ਝਰੋਖੇ ਦੇ ਅਕਾਰ ਨੂੰ ਤਬਦੀਲ ਕੀਤਾ ਜਾਵੇ ਤਾਂ ਜ਼ੂਮ" + +#: ../../po/../src/dialogs/display-settings.cpp:1205 +msgid "" +"Zoom drawing when document window is resized, to keep the same area visible " +"(this is the default which can be changed in any window using the button " +"above the right scrollbar)" +msgstr "" + +#. Clones +#: ../../po/../src/dialogs/display-settings.cpp:1213 +#: ../../po/../src/dialogs/find.cpp:624 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:60 +msgid "Clones" +msgstr "ਸਮਰੂਪ" + +#: ../../po/../src/dialogs/display-settings.cpp:1217 +msgid "When the original moves, its clones and linked offsets:" +msgstr "ਜਦੋਂ ਅਸਲੀ ਨੂੰ ਹਿਲਾਇਆ ਜਾਵੇ ਤਾਂ ਇਸ ਦੇ ਸਮਰੂਪ ਅਤੇ ਸਬੰਧਤ ਅੰਤਰਲੰਬ:" + +#: ../../po/../src/dialogs/display-settings.cpp:1229 +msgid "Move in parallel" +msgstr "ਸਮਾਂਤਰ ਹਿਲਾਓ" + +#: ../../po/../src/dialogs/display-settings.cpp:1230 +msgid "Clones are translated by the same vector as their original." +msgstr "ਸਮਰੂਪਾਂ ਨੂੰ ਉਸੇ ਵੈਕਟਰ ਅਨੁਸਾਰ ਤਬਦੀਲ, ਜਿਸ ਨਾਲ ਉਹਨਾਂ ਦੇ ਅਸਲੀ।" + +#: ../../po/../src/dialogs/display-settings.cpp:1237 +msgid "Stay unmoved" +msgstr "ਨਾ-ਹਿਲਾਏ ਰੱਖੋ" + +#: ../../po/../src/dialogs/display-settings.cpp:1238 +msgid "Clones preserve their positions when their original is moved." +msgstr "ਜਦੋਂ ਸਮਰੂਪਾਂ ਦੇ ਅਸਲੀ ਨੂੰ ਹਿਲਾਇਆ ਜਾਵੇ ਤਾਂ ਉਹ ਆਪਣਾ ਟਿਕਾਣਾ ਰੱਖੋ।" + +#: ../../po/../src/dialogs/display-settings.cpp:1245 +msgid "Move according to transform" +msgstr "ਸੰਚਾਰ ਦੇ ਅਨੁਸਾਰੀ ਭੇਜੋ" + +#: ../../po/../src/dialogs/display-settings.cpp:1246 +msgid "" +"Each clone moves according to the value of its transform= attribute. For " +"example, a rotated clone will move in a different direction than its " +"original." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1255 +msgid "When the original is deleted, its clones:" +msgstr "ਜਦੋਂ ਅਸਲੀ ਨੂੰ ਹਟਾਇਆ ਜਾਵੇ ਤਾਂ ਇਸ ਦੇ ਸਮਰੂਪ:" + +#: ../../po/../src/dialogs/display-settings.cpp:1267 +msgid "Are unlinked" +msgstr "ਚਾਪ ਨਾ-ਸਬੰਧਤ" + +#: ../../po/../src/dialogs/display-settings.cpp:1267 +msgid "Orphaned clones are converted to regular objects." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1273 +msgid "Are deleted" +msgstr "ਚਾਪ ਹਟਾਈ" + +#: ../../po/../src/dialogs/display-settings.cpp:1273 +msgid "Orphaned clones are deleted along with their original." +msgstr "" + +#. Transforms +#. TRANSLATORS: Noun, i.e. transformations. +#: ../../po/../src/dialogs/display-settings.cpp:1289 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:61 +msgid "Transforms" +msgstr "ਤਬਦੀਲ" + +#: ../../po/../src/dialogs/display-settings.cpp:1292 +msgid "Scale stroke width" +msgstr "ਪੈਮਾਨਾ ਛੋਹ ਚੌੜਾਈ" + +#: ../../po/../src/dialogs/display-settings.cpp:1293 +#: ../../po/../src/widgets/select-toolbar.cpp:568 +msgid "When scaling objects, scale the stroke width by the same proportion" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1300 +msgid "Scale rounded corners in rectangles" +msgstr "ਚਤੁਰਭੁਜ ਵਿੱਚ ਪੈਮਾਨਾ ਗੋਲ ਕੋਨੇ" + +#: ../../po/../src/dialogs/display-settings.cpp:1301 +#: ../../po/../src/widgets/select-toolbar.cpp:580 +msgid "When scaling rectangles, scale the radii of rounded corners" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1308 +msgid "Transform gradients" +msgstr "ਢਾਲਵਾਂ ਤਬਦੀਲ" + +#: ../../po/../src/dialogs/display-settings.cpp:1309 +#: ../../po/../src/widgets/select-toolbar.cpp:592 +msgid "Transform gradients (in fill or stroke) along with the objects" +msgstr "ਇਕਾਈਆਂ ਨਾਲ ਢਾਲਵਾਂ ਤਬਦੀਲ (ਭਰਨ ਜਾਂ ਛੋਹ)" + +#: ../../po/../src/dialogs/display-settings.cpp:1316 +msgid "Transform patterns" +msgstr "ਤਰਤੀਬਾਂ ਤਬਦੀਲ" + +#: ../../po/../src/dialogs/display-settings.cpp:1317 +#: ../../po/../src/widgets/select-toolbar.cpp:604 +msgid "Transform patterns (in fill or stroke) along with the objects" +msgstr "ਇਕਾਈਆਂ ਨਾਲ ਤਰਤੀਬਾਂ ਤਬਦੀਲ (ਭਰਨ ਜਾਂ ਛੋਹ)" + +#. TRANSLATORS: How to specify the affine transformation in the SVG file. +#: ../../po/../src/dialogs/display-settings.cpp:1327 +msgid "Store transformation:" +msgstr "ਤਬਦੀਲੀ ਸੰਭਾਲੋ:" + +#: ../../po/../src/dialogs/display-settings.cpp:1338 +msgid "Optimized" +msgstr "ਅਨੁਕੂਲ" + +#: ../../po/../src/dialogs/display-settings.cpp:1339 +msgid "" +"If possible, apply transformation to objects without adding a transform= " +"attribute" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1346 +msgid "Preserved" +msgstr "ਸੁਰੱਖਿਅਤ ਰੱਖਿਆ" + +#: ../../po/../src/dialogs/display-settings.cpp:1347 +msgid "Always store transformation as a transform= attribute on objects" +msgstr "" + +#. Selecting +#: ../../po/../src/dialogs/display-settings.cpp:1355 +msgid "Selecting" +msgstr "ਚੋਣ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ" + +#: ../../po/../src/dialogs/display-settings.cpp:1357 +msgid "Ctrl+A, Tab, Shift+Tab:" +msgstr "Ctrl+A, Tab, Shift+Tab:" + +#: ../../po/../src/dialogs/display-settings.cpp:1366 +msgid "Select only within current layer" +msgstr "ਸਿਰਫ਼ ਮੌਜੂਦਾ ਪਰਤ ਹੀ ਚੁਣੋ" + +#: ../../po/../src/dialogs/display-settings.cpp:1367 +msgid "" +"Uncheck this to make keyboard selection commands work on objects in all " +"layers" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1374 +msgid "Ignore hidden objects" +msgstr "ਲੁਕਵੀਆਂ ਇਕਾਈਆਂ ਅਣਡਿੱਠੀਆਂ" + +#: ../../po/../src/dialogs/display-settings.cpp:1375 +msgid "" +"Uncheck this to be able to select objects that are hidden (either by " +"themselves or by being in a hidden group or layer)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1382 +msgid "Ignore locked objects" +msgstr "ਤਾਲਾਬੰਦ ਇਕਾਈਆਂ ਅਣਡਿੱਠੀਆਂ" + +#: ../../po/../src/dialogs/display-settings.cpp:1383 +msgid "" +"Uncheck this to be able to select objects that are locked (either by " +"themselves or by being in a locked group or layer)" +msgstr "" + +#. To be broken into: Display, Save, Export, SVG, Commands +#: ../../po/../src/dialogs/display-settings.cpp:1391 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:62 +msgid "Misc" +msgstr "ਫੁਟਕਲ" + +#: ../../po/../src/dialogs/display-settings.cpp:1394 +msgid "Default export resolution:" +msgstr "ਮੂਲ ਨਿਰਯਾਤ ਰੈਜ਼ੋਲੇਸ਼ਨ:" + +#: ../../po/../src/dialogs/display-settings.cpp:1395 +msgid "Default bitmap resolution (in dots per inch) in the Export dialog" +msgstr "ਨਿਰਯਾਤ ਵਾਰਤਾਲਾਪ ਵਿੱਚ ਮੂਲ ਬਿੱਟਮੈਪ ਰੈਜ਼ੋਲੇਸ਼ਨ (ਪ੍ਰਤੀ ਇੰਚ ਬਿੰਦੂ)" + +#. FIXME: add "Used for new exports; once exported, documents remember this value on per-object basis" when implemented +#: ../../po/../src/dialogs/display-settings.cpp:1396 +#: ../../po/../src/dialogs/export.cpp:442 +msgid "dpi" +msgstr "dpi" + +#. TRANSLATORS: When on, an imported bitmap creates an element; otherwise it is a +#. * rectangle with bitmap fill. +#: ../../po/../src/dialogs/display-settings.cpp:1407 +msgid "Import bitmap as " +msgstr "ਬਿੱਟਮੈਪ ਵਾਂਗ ਅਯਾਤ" + +#: ../../po/../src/dialogs/display-settings.cpp:1408 +msgid "" +"When on, an imported bitmap creates an element; otherwise it is a " +"rectangle with bitmap fill" +msgstr "" + +#. TRANSLATORS: When on, the print out (currently Postscript) will have +#. * a comment with the each object's label visible, marking the section +#. * of the printing commands that represent the given object. +#: ../../po/../src/dialogs/display-settings.cpp:1418 +msgid "Add label comments to printing output" +msgstr "ਛਪਾਈ ਆਉਟਪੁੱਟ ਵਿੱਚ ਲੇਬਲ ਟਿੱਪਣੀਆਂ ਸ਼ਾਮਲ" + +#: ../../po/../src/dialogs/display-settings.cpp:1419 +msgid "" +"When on, a comment will be added to the raw print output, marking the " +"rendered output for an object with its label" +msgstr "" + +#. TRANSLATORS: When on, enable the effects menu, default is off +#: ../../po/../src/dialogs/display-settings.cpp:1427 +msgid "Enable script effects (requires restart) - EXPERIMENTAL" +msgstr "ਸਕਰਿਪਟ ਪਰਭਾਵ ਯੋਗ (ਮੁੜ-ਚਾਲੂ ਕਰਨਾ ਪਵੇਗਾ) - ਤਜਰਬੇ ਅਧੀਨ" + +#: ../../po/../src/dialogs/display-settings.cpp:1428 +msgid "" +"When on, the effects menu is enabled, allowing external effect scripts to be " +"called, requires restart before effective - EXPERIMENTAL" +msgstr "" + +#. TRANSLATORS: The maximum length of the Open Recent list in the File menu. +#: ../../po/../src/dialogs/display-settings.cpp:1436 +msgid "Max recent documents:" +msgstr "ਵੱਧੋ-ਵੱਧ ਤਾਜ਼ਾ ਦਸਤਾਵੇਜ਼:" + +#: ../../po/../src/dialogs/display-settings.cpp:1437 +msgid "The maximum length of the Open Recent list in the File menu" +msgstr "ਫਾਇਲ ਮੇਨੂ ਵਿੱਚ ਤਾਜ਼ਾ ਖੋਲੋ ਸੂਚੀ ਦੀ ਵੱਧੋ ਵੱਧ ਲੰਬਾਈ" + +#: ../../po/../src/dialogs/display-settings.cpp:1447 +msgid "Simplification threshold:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1448 +msgid "" +"How strong is the Simplify command by default. If you invoke this command " +"several times in quick succession, it will act more and more aggressively; " +"invoking it again after a pause restores the default threshold." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1469 +msgid "Oversample bitmaps:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1488 +msgid "2x2" +msgstr "2x2" + +#: ../../po/../src/dialogs/display-settings.cpp:1494 +msgid "4x4" +msgstr "4x4" + +#: ../../po/../src/dialogs/display-settings.cpp:1500 +msgid "8x8" +msgstr "8x8" + +#: ../../po/../src/dialogs/display-settings.cpp:1506 +msgid "16x16" +msgstr "16x16" + +#. "view_icon_preview" +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2143 +msgid "_Page" +msgstr "ਸਫ਼ਾ(_P)" + +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2147 +msgid "_Drawing" +msgstr "ਡਰਾਇੰਗ(_D)" + +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2149 +msgid "_Selection" +msgstr "ਚੋਣ(_S)" + +#: ../../po/../src/dialogs/export.cpp:133 +msgid "_Custom" +msgstr "ਪਸੰਦੀਦਾ(_C)" + +#: ../../po/../src/dialogs/export.cpp:254 +msgid "Export area" +msgstr "ਖੇਤਰ ਨਿਰਯਾਤ" + +#: ../../po/../src/dialogs/export.cpp:300 +msgid "_x0:" +msgstr "_x0:" + +#: ../../po/../src/dialogs/export.cpp:305 +msgid "x_1:" +msgstr "x_1:" + +#: ../../po/../src/dialogs/export.cpp:316 +msgid "_y0:" +msgstr "_y0:" + +#: ../../po/../src/dialogs/export.cpp:321 +msgid "y_1:" +msgstr "y_1:" + +#: ../../po/../src/dialogs/export.cpp:406 +msgid "Bitmap size" +msgstr "ਬਿੱਟਮੈਪ ਅਕਾਰ" + +#: ../../po/../src/dialogs/export.cpp:416 +msgid "_Width:" +msgstr "ਚੌੜਾਈ(_W):" + +#: ../../po/../src/dialogs/export.cpp:416 +#: ../../po/../src/dialogs/export.cpp:431 +msgid "pixels at" +msgstr "ਪਿਕਸਲ" + +#: ../../po/../src/dialogs/export.cpp:426 +msgid "dp_i" +msgstr "dp_i" + +#: ../../po/../src/dialogs/export.cpp:448 +msgid "_Filename" +msgstr "ਫਾਇਲ ਨਾਂ(_F)" + +#: ../../po/../src/dialogs/export.cpp:512 +msgid "_Browse..." +msgstr "ਝਲਕ(_B)..." + +#: ../../po/../src/dialogs/export.cpp:539 +msgid " _Export " +msgstr " ਨਿਰਯਾਤ(_E) " + +#: ../../po/../src/dialogs/export.cpp:541 +msgid "Export the bitmap file with these settings" +msgstr "ਇਸ ਸਥਾਪਨ ਨਾਲ ਬਿੱਟਮੈਪ ਫਾਇਲ ਨਿਰਯਾਤ" + +#: ../../po/../src/dialogs/export.cpp:968 +msgid "You have to enter a filename" +msgstr "ਤੁਹਾਨੂੰ ਇੱਕ ਫਾਇਲ ਨਾਂ ਦੇਣਾ ਚਾਹੀਦਾ ਹੈ।" + +#: ../../po/../src/dialogs/export.cpp:973 +msgid "The chosen area to be exported is invalid" +msgstr "ਨਿਰਯਾਤ ਲਈ ਚੁਣਿਆ ਖੇਤਰ ਗਲਤ ਹੈ" + +#: ../../po/../src/dialogs/export.cpp:982 +#, c-format +msgid "Directory %s does not exist or is not a directory.\n" +msgstr "ਡਾਇਰੈਕਟਰੀ %s ਮੌਜੂਦ ਨਹੀਂ ਹੈ ਜਾਂ ਇਹ ਇੱਕ ਡਾਇਰੈਕਟਰੀ ਨਹੀਂ ਹੈ।\n" + +#: ../../po/../src/dialogs/export.cpp:998 +msgid "Export in progress" +msgstr "ਨਿਰਯਾਤ ਜਾਰੀ ਹੈ" + +#: ../../po/../src/dialogs/export.cpp:1004 +#, c-format +msgid "Exporting %s (%d x %d)" +msgstr "ਨਿਰਯਾਤ ਜਾਰੀ %s (%d x %d)" + +#: ../../po/../src/dialogs/export.cpp:1031 +#, c-format +msgid "Could not export to filename %s.\n" +msgstr "ਫਾਇਲ ਨਾਂ %s ਨੂੰ ਨਿਰਯਾਤ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਿਆ।\n" + +#: ../../po/../src/dialogs/export.cpp:1137 +msgid "Select a filename for exporting" +msgstr "ਨਿਰਯਾਤ ਕਰਨ ਲਈ ਇੱਕ ਫਾਇਲ ਨਾਂ ਚੁਣੋ" + +#: ../../po/../src/dialogs/filedialog.cpp:367 +msgid "No preview" +msgstr "ਕੋਈ ਝਲਕ ਨਹੀਂ" + +#: ../../po/../src/dialogs/filedialog.cpp:468 +msgid "too large for preview" +msgstr "ਝਲਕ ਲਈ ਬਹੁਤ ਵੱਡਾ ਹੈ" + +#: ../../po/../src/dialogs/filedialog.cpp:762 +#: ../../po/../src/dialogs/filedialog.cpp:763 +msgid "All Images" +msgstr "ਸਭ ਚਿੱਤਰ" + +#: ../../po/../src/dialogs/filedialog.cpp:767 +#: ../../po/../src/dialogs/filedialog.cpp:768 +msgid "All Files" +msgstr "ਸਭ ਫਾਇਲਾਂ" + +#: ../../po/../src/dialogs/filedialog.cpp:774 +#: ../../po/../src/dialogs/filedialog.cpp:775 +msgid "All Inkscape Files" +msgstr "ਸਭ ਇੰਕਸਕੇਪੀ ਫਾਇਲਾਂ" + +#: ../../po/../src/dialogs/filedialog.cpp:1176 +msgid "Guess from extension" +msgstr "ਸਹਿਯੋਗ ਲਈ ਪਛਾਣ" + +#. ###### Add the file types menu +#. createFilterMenu(); +#. ###### Do we want the .xxx extension automatically added? +#: ../../po/../src/dialogs/filedialog.cpp:1261 +msgid "Append filename extension automatically" +msgstr "ਫਾਇਲ ਨਾਂ ਐਕਸ਼ਟੇਸ਼ਨ ਸਵੈ-ਚਾਲਤ ਹੀ ਜੋੜੋ" + +#. TRANSLATORS: "%s" is replaced with "exact" or "partial" when this string is displayed +#: ../../po/../src/dialogs/find.cpp:378 +#, c-format +msgid "%d object found (out of %d), %s match." +msgid_plural "%d objects found (out of %d), %s match." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/dialogs/find.cpp:381 +msgid "exact" +msgstr "ਠੀਕ" + +#: ../../po/../src/dialogs/find.cpp:381 +msgid "partial" +msgstr "ਅਧੂਰਾ" + +#: ../../po/../src/dialogs/find.cpp:388 +msgid "No objects found" +msgstr "ਕੋਈ ਇਕਾਈ ਨਹੀਂ ਮਿਲੀ" + +#: ../../po/../src/dialogs/find.cpp:546 +msgid "T_ype: " +msgstr "ਕਿਸਮ(_y): " + +#: ../../po/../src/dialogs/find.cpp:553 +msgid "Search in all object types" +msgstr "ਸਭ ਇਕਾਈ ਕਿਸਮਾਂ ਵਿੱਚ ਖੋਜ" + +#: ../../po/../src/dialogs/find.cpp:553 +msgid "All types" +msgstr "ਸਭ ਕਿਸਮਾਂ" + +#: ../../po/../src/dialogs/find.cpp:564 +msgid "Search all shapes" +msgstr "ਸਭ ਸ਼ਕਲਾਂ ਦੀ ਖੋਜ" + +#: ../../po/../src/dialogs/find.cpp:564 +msgid "All shapes" +msgstr "ਸਭ ਸ਼ਕਲਾਂ" + +#: ../../po/../src/dialogs/find.cpp:581 +msgid "Search rectangles" +msgstr "ਚਤੁਰਭੁਜ ਖੋਜ" + +#: ../../po/../src/dialogs/find.cpp:581 +msgid "Rectangles" +msgstr "ਚਤੁਰਭੁਜ" + +#: ../../po/../src/dialogs/find.cpp:586 +msgid "Search ellipses, arcs, circles" +msgstr "ਅੰਡਾਕਾਰ, ਚਾਪ ਅਤੇ ਚੱਕਰ ਖੋਜ" + +#: ../../po/../src/dialogs/find.cpp:586 +msgid "Ellipses" +msgstr "ਅੰਡਾਕਾਰ" + +#: ../../po/../src/dialogs/find.cpp:591 +msgid "Search stars and polygons" +msgstr "ਤਾਰੇ ਅਤੇ ਬਹੁ-ਭੁਜ ਖੋਜ" + +#: ../../po/../src/dialogs/find.cpp:591 +msgid "Stars" +msgstr "ਤਾਰੇ" + +#: ../../po/../src/dialogs/find.cpp:596 +msgid "Search spirals" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:596 +msgid "Spirals" +msgstr "" + +#. TRANSLATORS: polyline is a set of connected straight line segments +#. http://www.w3.org/TR/SVG11/shapes.html#PolylineElement +#: ../../po/../src/dialogs/find.cpp:609 +msgid "Search paths, lines, polylines" +msgstr "ਮਾਰਗ, ਰੇਖਾਵਾਂ, ਬਹੁ-ਭੁਜ ਖੋਜ" + +#: ../../po/../src/dialogs/find.cpp:609 +msgid "Paths" +msgstr "ਮਾਰਗ" + +#: ../../po/../src/dialogs/find.cpp:614 +msgid "Search text objects" +msgstr "ਪਾਠ ਇਕਾਈਆਂ ਖੋਜ" + +#: ../../po/../src/dialogs/find.cpp:614 +msgid "Texts" +msgstr "ਪਾਠ" + +#: ../../po/../src/dialogs/find.cpp:619 +msgid "Search groups" +msgstr "ਸਮੂਹ ਖੋਜ" + +#: ../../po/../src/dialogs/find.cpp:619 +msgid "Groups" +msgstr "ਸਮੂਹ" + +#: ../../po/../src/dialogs/find.cpp:624 +msgid "Search clones" +msgstr "ਸਮਰੂਪ ਖੋਜ" + +#: ../../po/../src/dialogs/find.cpp:629 +msgid "Search images" +msgstr "ਚਿੱਤਰ ਖੋਜ" + +#: ../../po/../src/dialogs/find.cpp:629 +msgid "Images" +msgstr "ਚਿੱਤਰ" + +#: ../../po/../src/dialogs/find.cpp:634 +msgid "Search offset objects" +msgstr "ਅੰਤਰ-ਲੰਭ ਇਕਾਈਆਂ ਖੋਜ" + +#: ../../po/../src/dialogs/find.cpp:634 +msgid "Offsets" +msgstr "ਅੰਤਰ-ਲੰਬ" + +#: ../../po/../src/dialogs/find.cpp:694 +msgid "_Text: " +msgstr "ਪਾਠ(_T): " + +#: ../../po/../src/dialogs/find.cpp:694 +msgid "Find objects by their text content (exact or partial match)" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:695 +msgid "_ID: " +msgstr "_ID: " + +#: ../../po/../src/dialogs/find.cpp:695 +msgid "Find objects by the value of the id attribute (exact or partial match)" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:696 +msgid "_Style: " +msgstr "ਸ਼ੈਲੀ(_S): " + +#: ../../po/../src/dialogs/find.cpp:696 +msgid "" +"Find objects by the value of the style attribute (exact or partial match)" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:697 +msgid "_Attribute: " +msgstr "ਗੁਣ(_A): " + +#: ../../po/../src/dialogs/find.cpp:697 +msgid "Find objects by the name of an attribute (exact or partial match)" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:711 +msgid "Search in s_election" +msgstr "ਚੋਣ ਵਿੱਚ ਖੋਜ(_e)" + +#: ../../po/../src/dialogs/find.cpp:715 +msgid "Limit search to the current selection" +msgstr "ਖੋਜ ਨੂੰ ਮੌਜੂਦ ਚੋਣ ਤੱਕ ਸੀਮਿਤ ਕਰੋ" + +#: ../../po/../src/dialogs/find.cpp:720 +msgid "Search in current _layer" +msgstr "ਮੌਜੂਦਾ ਪਰਤ ਵਿੱਚ ਖੋਜ(_l)" + +#: ../../po/../src/dialogs/find.cpp:724 +msgid "Limit search to the current layer" +msgstr "ਖੋਜ ਮੌਜੂਦਾ ਪਰਤ ਤੱਕ ਸੀਮਿਤ ਰੱਖੋ" + +#: ../../po/../src/dialogs/find.cpp:729 +msgid "Include _hidden" +msgstr "ਲੁਕਵੇਂ ਸ਼ਾਮਲ(_h)" + +#: ../../po/../src/dialogs/find.cpp:733 +msgid "Include hidden objects in search" +msgstr "ਖੋਜ ਵਿੱਚ ਲੁਕਵੀਆਂ ਇਕਾਈਆਂ ਵੀ ਸ਼ਾਮਲ" + +#: ../../po/../src/dialogs/find.cpp:738 +msgid "Include l_ocked" +msgstr "ਤਾਲਾਬੰਦ ਸ਼ਾਮਲ(_o)" + +#: ../../po/../src/dialogs/find.cpp:742 +msgid "Include locked objects in search" +msgstr "ਖੋਜ ਵਿੱਚ ਤਾਲਾਬੰਦ ਇਕਾਈਆਂ ਸ਼ਾਮਲ" + +#: ../../po/../src/dialogs/find.cpp:753 +msgid "Clear values" +msgstr "ਮੁੱਲ ਸਾਫ਼" + +#: ../../po/../src/dialogs/find.cpp:754 +msgid "_Find" +msgstr "ਖੋਜ(_F)" + +#: ../../po/../src/dialogs/find.cpp:754 +msgid "Select objects matching all of the fields you filled in" +msgstr "" + +#: ../../po/../src/dialogs/iconpreview.cpp:145 +#, c-format +msgid "%d x %d" +msgstr "" + +#: ../../po/../src/dialogs/iconpreview.cpp:193 +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:857 +#: ../../po/../src/widgets/desktop-widget.cpp:1069 +msgid "Selection" +msgstr "ਚੋਣ" + +#: ../../po/../src/dialogs/iconpreview.cpp:195 +#, fuzzy +msgid "Selection only or whole document" +msgstr "ਸਿਰਫ਼ ਮੌਜੂਦਾ ਪਰਤ ਹੀ ਚੁਣੋ" + +#: ../../po/../src/dialogs/iconpreview.cpp:203 +msgid "Refresh the icons" +msgstr "ਆਈਕਾਨ ਤਾਜ਼ਾ" + +#. Create the label for the object id +#: ../../po/../src/dialogs/item-properties.cpp:126 +#: ../../po/../src/dialogs/item-properties.cpp:327 +#: ../../po/../src/dialogs/item-properties.cpp:396 +#: ../../po/../src/dialogs/item-properties.cpp:403 +msgid "_Id" +msgstr "_Id" + +#: ../../po/../src/dialogs/item-properties.cpp:135 +msgid "" +"The id= attribute (only letters, digits, and the characters .-_: allowed)" +msgstr "" + +#. Button for setting the object's id, label, title and description. +#: ../../po/../src/dialogs/item-properties.cpp:149 +msgid "_Set" +msgstr "ਦਿਓ(_S)" + +#. Create the label for the object label +#: ../../po/../src/dialogs/item-properties.cpp:158 +msgid "_Label" +msgstr "ਲੇਬਲ(_L)" + +#: ../../po/../src/dialogs/item-properties.cpp:167 +msgid "A freeform label for the object" +msgstr "" + +#. Create the label for the object title +#: ../../po/../src/dialogs/item-properties.cpp:179 +#: ../../po/../src/dialogs/rdf.cpp:243 +msgid "Title" +msgstr "ਨਾਂ" + +#. Create the frame for the object description +#: ../../po/../src/dialogs/item-properties.cpp:196 +#: ../../po/../src/dialogs/rdf.cpp:287 +msgid "Description" +msgstr "ਵੇਰਵਾ" + +#. Hide +#: ../../po/../src/dialogs/item-properties.cpp:223 +msgid "_Hide" +msgstr "ਓਹਲੇ(_H)" + +#: ../../po/../src/dialogs/item-properties.cpp:224 +msgid "Check to make the object invisible" +msgstr "ਇਕਾਈ ਨੂੰ ਅਦਿੱਖ ਬਣਾਉਣ ਲਈ ਚੋਣ ਕਰੋ" + +#. Lock +#. TRANSLATORS: "Lock" is a verb here +#: ../../po/../src/dialogs/item-properties.cpp:233 +msgid "L_ock" +msgstr "ਤਾਲਾਬੰਦ(_o)" + +#: ../../po/../src/dialogs/item-properties.cpp:234 +msgid "Check to make the object insensitive (not selectable by mouse)" +msgstr "" + +#: ../../po/../src/dialogs/item-properties.cpp:310 +#: ../../po/../src/dialogs/item-properties.cpp:317 +msgid "Ref" +msgstr "ਹਵਾਲਾ" + +#: ../../po/../src/dialogs/item-properties.cpp:398 +msgid "Id invalid! " +msgstr "Id ਗਲਤ ਹੈ! " + +#: ../../po/../src/dialogs/item-properties.cpp:400 +msgid "Id exists! " +msgstr "Id ਮੌਜੂਦ ਹੈ! " + +#: ../../po/../src/dialogs/layer-properties.cpp:50 +msgid "Layer name:" +msgstr "ਪਰਤ ਨਾਂ:" + +#: ../../po/../src/dialogs/layer-properties.cpp:133 +msgid "Rename Layer" +msgstr "ਪਰਤ ਦਾ ਨਾਂ-ਤਬਦੀਲ" + +#: ../../po/../src/dialogs/layer-properties.cpp:136 +msgid "_Rename" +msgstr "ਨਾਂ-ਤਬਦੀਲ(_R)" + +#. TRANSLATORS: This means "The layer has been renamed" +#: ../../po/../src/dialogs/layer-properties.cpp:147 +msgid "Renamed layer" +msgstr "ਪਰਤ ਦਾ ਨਾਂ-ਤਬਦੀਲ ਹੋਇਆ" + +#: ../../po/../src/dialogs/layer-properties.cpp:151 +msgid "Add Layer" +msgstr "ਪਰਤ ਜੋੜ੍ਹੋ" + +#: ../../po/../src/dialogs/layer-properties.cpp:153 +msgid "_Add" +msgstr "ਸ਼ਾਮਲ(_A)" + +#: ../../po/../src/dialogs/layer-properties.cpp:167 +msgid "New layer created." +msgstr "ਨਵੀਂ ਪਰਤ ਬਣਾਈ ਗਈ ਹੈ।" + +#: ../../po/../src/dialogs/object-attributes.cpp:34 +msgid "Href:" +msgstr "" + +#: ../../po/../src/dialogs/object-attributes.cpp:35 +msgid "Target:" +msgstr "ਟਿਕਾਣਾ:" + +#: ../../po/../src/dialogs/object-attributes.cpp:36 +msgid "Type:" +msgstr "ਕਿਸਮ:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkRoleAttribute +#. Identifies the type of the related resource with an absolute URI +#: ../../po/../src/dialogs/object-attributes.cpp:39 +msgid "Role:" +msgstr "ਕੰਮ:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkArcRoleAttribute +#. For situations where the nature/role alone isn't enough, this offers an additional URI defining the purpose of the link. +#: ../../po/../src/dialogs/object-attributes.cpp:42 +msgid "Arcrole:" +msgstr "" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkTitleAttribute +#: ../../po/../src/dialogs/object-attributes.cpp:44 +msgid "Title:" +msgstr "ਸਿਰਲੇਖ:" + +#: ../../po/../src/dialogs/object-attributes.cpp:45 +msgid "Show:" +msgstr "ਵੇਖਾਓ:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkActuateAttribute +#: ../../po/../src/dialogs/object-attributes.cpp:47 +msgid "Actuate:" +msgstr "" + +#: ../../po/../src/dialogs/object-attributes.cpp:52 +msgid "URL:" +msgstr "URL:" + +#: ../../po/../src/dialogs/object-attributes.cpp:53 +msgid "X:" +msgstr "X:" + +#: ../../po/../src/dialogs/object-attributes.cpp:54 +msgid "Y:" +msgstr "Y:" + +#: ../../po/../src/dialogs/object-attributes.cpp:98 +#, c-format +msgid "%s attributes" +msgstr "%s ਗੁਣ" + +#: ../../po/../src/dialogs/object-properties.cpp:158 +msgid "_Fill" +msgstr "ਭਰੋ(_F)" + +#: ../../po/../src/dialogs/object-properties.cpp:165 +msgid "Stroke _paint" +msgstr "ਛੋਹ ਪੇਂਟ(_p)" + +#: ../../po/../src/dialogs/object-properties.cpp:172 +msgid "Stroke st_yle" +msgstr "ਛੋਹ ਸ਼ੈਲੀ(_y)" + +#: ../../po/../src/dialogs/object-properties.cpp:183 +msgid "Master _opacity" +msgstr "ਮਾਸਟਰ ਧੁੰਦਲਾਪਨ(_o)" + +#: ../../po/../src/dialogs/rdf.cpp:244 +msgid "Name by which this document is formally known." +msgstr "ਇਹ ਦਸਤਾਵੇਜ਼ ਦਾ ਨਾਂ ਹੈ, ਜਿਸ ਨਾਲ ਇਸ ਨੂੰ ਜਾਣਿਆ ਜਾਵੇਗਾ।" + +#: ../../po/../src/dialogs/rdf.cpp:246 +msgid "Date" +msgstr "ਮਿਤੀ" + +#: ../../po/../src/dialogs/rdf.cpp:247 +msgid "Date associated with the creation of this document (YYYY-MM-DD)." +msgstr "ਇਸ ਦਸਤਾਵੇਜ਼ ਬਣਾਉਣ ਨਾਲ ਸਬੰਧਤ ਮਿਤੀ (YYYY-MM-DD)" + +#: ../../po/../src/dialogs/rdf.cpp:249 +msgid "Format" +msgstr "ਫਾਰਮਿਟ" + +#: ../../po/../src/dialogs/rdf.cpp:250 +msgid "The physical or digital manifestation of this document (MIME type)." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:252 +msgid "Type" +msgstr "ਕਿਸਮ" + +#: ../../po/../src/dialogs/rdf.cpp:253 +msgid "Type of document (DCMI Type)." +msgstr "ਦਸਤਾਵੇਜ਼ ਦੀ ਕਿਸਮ (DCMI ਕਿਸਮ) ਹੈ।" + +#: ../../po/../src/dialogs/rdf.cpp:256 +msgid "Creator" +msgstr "ਨਿਰਮਾਤਾ" + +#: ../../po/../src/dialogs/rdf.cpp:257 +msgid "" +"Name of entity primarily responsible for making the content of this document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:259 +msgid "Rights" +msgstr "ਹੱਕ" + +#: ../../po/../src/dialogs/rdf.cpp:260 +msgid "" +"Name of entity with rights to the Intellectual Property of this document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:262 +msgid "Publisher" +msgstr "ਪਰਕਾਸ਼ਕ" + +#: ../../po/../src/dialogs/rdf.cpp:263 +msgid "Name of entity responsible for making this document available." +msgstr "ਇਸ ਦਸਤਾਵੇਜ਼ ਦੀ ਮੌਜੂਦਗੀ ਵੇਖਾਉਣ ਲਈ ਜੁੰਮੇਵਾਰ ਇਕਾਈ ਦਾ ਨਾਂ ਹੈ।" + +#: ../../po/../src/dialogs/rdf.cpp:266 +msgid "Identifier" +msgstr "ਪਛਾਣਕਰਤਾ" + +#: ../../po/../src/dialogs/rdf.cpp:267 +msgid "Unique URI to reference this document." +msgstr "ਇਸ ਦਸਤਾਵੇਜ਼ ਦੇ ਹਵਾਲੇ ਲਈ ਵਿਲੱਖਣ URI ਹੈ।" + +#: ../../po/../src/dialogs/rdf.cpp:269 +msgid "Source" +msgstr "ਸਰੋਤ" + +#: ../../po/../src/dialogs/rdf.cpp:270 +msgid "Unique URI to reference the source of this document." +msgstr "ਇਸ ਦਸਤਾਵੇਜ਼ ਦੇ ਸਰੋਤ ਦੇ ਹਵਾਲੇ ਲਈ ਵਿਲੱਖਣ URI ਹੈ।" + +#: ../../po/../src/dialogs/rdf.cpp:272 +msgid "Relation" +msgstr "ਸਬੰਧ" + +#: ../../po/../src/dialogs/rdf.cpp:273 +msgid "Unique URI to a related document." +msgstr "ਇੱਕ ਅਨੁਸਾਰੀ ਦਸਤਾਵੇਜ਼ ਲਈ ਵਿਲੱਖਣ URI ਹੈ।" + +#: ../../po/../src/dialogs/rdf.cpp:275 +msgid "Language" +msgstr "ਭਾਸ਼ਾ" + +#: ../../po/../src/dialogs/rdf.cpp:276 +msgid "" +"Two-letter language tag with optional subtags for the language of this " +"document. (e.g. 'en-GB')" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:278 +msgid "Keywords" +msgstr "ਸ਼ਬਦ" + +#: ../../po/../src/dialogs/rdf.cpp:279 +msgid "" +"The topic of this document as comma-separated key words, phrases, or " +"classifications." +msgstr "" + +#. TRANSLATORS: "Coverage": the spatial or temporal characteristics of the content. +#. For info, see Appendix D of http://www.w3.org/TR/1998/WD-rdf-schema-19980409/ +#: ../../po/../src/dialogs/rdf.cpp:283 +msgid "Coverage" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:284 +msgid "Extent or scope of this document." +msgstr "ਇਸ ਦਸਤਾਵੇਜ਼ ਦਾ ਭਾਗ ਜਾਂ ਸੀਮਾ ਹੈ।" + +#: ../../po/../src/dialogs/rdf.cpp:288 +msgid "A short account of the content of this document." +msgstr "" + +#. FIXME: need to handle 1 agent per line of input +#: ../../po/../src/dialogs/rdf.cpp:292 +msgid "Contributors" +msgstr "ਯੋਗਦਾਨ" + +#: ../../po/../src/dialogs/rdf.cpp:293 +msgid "" +"Names of entities responsible for making contributions to the content of " +"this document." +msgstr "" + +#. TRANSLATORS: URL to a page that defines the license for the document +#: ../../po/../src/dialogs/rdf.cpp:297 +msgid "URI" +msgstr "URI" + +#. TRANSLATORS: this is where you put a URL to a page that defines the license +#: ../../po/../src/dialogs/rdf.cpp:299 +msgid "URI to this document's license's namespace definition." +msgstr "" + +#. TRANSLATORS: fragment of XML representing the license of the document +#: ../../po/../src/dialogs/rdf.cpp:303 +msgid "Fragment" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:304 +msgid "XML fragment for the RDF 'License' section." +msgstr "" + +#: ../../po/../src/dialogs/stroke-style.cpp:774 +#: ../../po/../src/widgets/gradient-vector.cpp:263 +#: ../../po/../src/widgets/paint-selector.cpp:751 +msgid "No document selected" +msgstr "ਕੋਈ ਦਸਤਾਵੇਜ਼ ਨਹੀਂ ਚੁਣਿਆ" + +#: ../../po/../src/dialogs/stroke-style.cpp:992 +msgid "Stroke width" +msgstr "ਛੋਹ ਚੌੜਾਈ" + +#. Join type +#. TRANSLATORS: The line join style specifies the shape to be used at the +#. corners of paths. It can be "miter", "round" or "bevel". +#: ../../po/../src/dialogs/stroke-style.cpp:1015 +msgid "Join:" +msgstr "ਜੋੜ:" + +#. TRANSLATORS: Miter join: joining lines with a sharp (pointed) corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1027 +msgid "Miter join" +msgstr "ਮਿਟੀਰ ਜੋੜ" + +#. TRANSLATORS: Round join: joining lines with a rounded corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1035 +msgid "Round join" +msgstr "ਗੋਲ ਜੋੜ" + +#. TRANSLATORS: Bevel join: joining lines with a blunted (flattened) corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1043 +msgid "Bevel join" +msgstr "ਬੀਵੀਲ ਜੋੜ" + +#. Miterlimit +#. TRANSLATORS: Miter limit: only for "miter join", this limits the length +#. of the sharp "spike" when the lines connect at too sharp an angle. +#. When two line segments meet at a sharp angle, a miter join results in a +#. spike that extends well beyond the connection point. The purpose of the +#. miter limit is to cut off such spikes (i.e. convert them into bevels) +#. when they become too long. +#: ../../po/../src/dialogs/stroke-style.cpp:1054 +msgid "Miter limit:" +msgstr "ਮਿਟੀਰ ਸੀਮਾ:" + +#: ../../po/../src/dialogs/stroke-style.cpp:1062 +msgid "Maximum length of the miter (in units of stroke width)" +msgstr "" + +#. Cap type +#. TRANSLATORS: cap type specifies the shape for the ends of lines +#: ../../po/../src/dialogs/stroke-style.cpp:1075 +msgid "Cap:" +msgstr "ਅੰਤ:" + +#. TRANSLATORS: Butt cap: the line shape does not extend beyond the end point +#. of the line; the ends of the line are square +#: ../../po/../src/dialogs/stroke-style.cpp:1086 +msgid "Butt cap" +msgstr "" + +#. TRANSLATORS: Round cap: the line shape extends beyond the end point of the +#. line; the ends of the line are rounded +#: ../../po/../src/dialogs/stroke-style.cpp:1093 +msgid "Round cap" +msgstr "ਗੋਲ ਅੰਤ" + +#. TRANSLATORS: Square cap: the line shape extends beyond the end point of the +#. line; the ends of the line are square +#: ../../po/../src/dialogs/stroke-style.cpp:1100 +msgid "Square cap" +msgstr "ਵਰਗ ਅੰਤ" + +#. Dash +#: ../../po/../src/dialogs/stroke-style.cpp:1106 +msgid "Dashes:" +msgstr "ਧਾਰੀਆਂ:" + +#. TRANSLATORS: Path markers are an SVG feature that allows you to attach arbitrary shapes +#. (arrowheads, bullets, faces, whatever) to the start, end, or middle nodes of a path. +#: ../../po/../src/dialogs/stroke-style.cpp:1127 +msgid "Start Markers:" +msgstr "ਸ਼ੁਰੂ ਨਿਸ਼ਾਨ:" + +#: ../../po/../src/dialogs/stroke-style.cpp:1137 +msgid "Mid Markers:" +msgstr "ਮੱਧ ਨਿਸ਼ਾਨ:" + +#: ../../po/../src/dialogs/stroke-style.cpp:1148 +msgid "End Markers:" +msgstr "ਅੰਤ ਨਿਸ਼ਾਨ:" + +#: ../../po/../src/dialogs/swatches.cpp:424 +#, c-format +msgid "Palettes directory (%s) is unavailable." +msgstr "ਰੰਗ-ਪੱਟੀ ਡਾਇਰੈਕਟਰੀ (%s) ਉਪਲੱਬਧ ਨਹੀਂ ਹੈ।" + +#. TODO: Insert widgets +#: ../../po/../src/dialogs/text-edit.cpp:199 +#: ../../po/../src/ui/dialog/text-properties.cpp:36 +msgid "Font" +msgstr "ਫੋਂਟ" + +#: ../../po/../src/dialogs/text-edit.cpp:216 +msgid "Layout" +msgstr "ਖਾਕਾ" + +#: ../../po/../src/dialogs/text-edit.cpp:229 +msgid "Align lines left" +msgstr "ਰੇਖਾਵਾਂ ਖੱਬੇ ਪਾਸੇ ਇਕਸਾਰ" + +#. TRANSLATORS: `Center' here is a verb. +#: ../../po/../src/dialogs/text-edit.cpp:243 +msgid "Center lines" +msgstr "ਕੇਂਦਰੀ ਰੇਖਾਵਾਂ" + +#: ../../po/../src/dialogs/text-edit.cpp:256 +msgid "Align lines right" +msgstr "" + +#: ../../po/../src/dialogs/text-edit.cpp:278 +msgid "Horizontal text" +msgstr "ਖਿਤਿਜੀ ਪਾਠ" + +#: ../../po/../src/dialogs/text-edit.cpp:292 +msgid "Vertical text" +msgstr "ਲੰਬਕਾਰੀ ਪਾਠ" + +#: ../../po/../src/dialogs/text-edit.cpp:307 +msgid "Line spacing:" +msgstr "ਰੇਖਾ ਖਾਲੀ ਥਾਂ:" + +#: ../../po/../src/dialogs/text-edit.cpp:400 +msgid "Set as default" +msgstr "ਮੂਲ ਬਣਾਓ" + +#: ../../po/../src/dialogs/tiledialog.cpp:603 +msgid "Rows:" +msgstr "ਕਤਾਰਾਂ:" + +#: ../../po/../src/dialogs/tiledialog.cpp:613 +msgid "Number of rows" +msgstr "ਕਤਾਰਾਂ ਦੀ ਗਿਣਤੀ" + +#: ../../po/../src/dialogs/tiledialog.cpp:617 +msgid "Equal height" +msgstr "ਬਰਾਬਰ ਉਚਾਈ" + +#: ../../po/../src/dialogs/tiledialog.cpp:627 +msgid "If not set, each row has the height of the tallest object in it" +msgstr "" + +#. #### Radio buttons to control vertical alignment #### +#. #### Radio buttons to control horizontal alignment #### +#: ../../po/../src/dialogs/tiledialog.cpp:637 +#: ../../po/../src/dialogs/tiledialog.cpp:708 +msgid "Align:" +msgstr "ਤਰਤੀਬਵਾਰ:" + +#: ../../po/../src/dialogs/tiledialog.cpp:672 +msgid " X " +msgstr " X " + +#. #### Number of columns #### +#: ../../po/../src/dialogs/tiledialog.cpp:678 +msgid "Columns:" +msgstr "ਕਾਲਮ:" + +#: ../../po/../src/dialogs/tiledialog.cpp:688 +msgid "Number of columns" +msgstr "ਕਾਲਮਾਂ ਦੀ ਗਿਣਤੀ" + +#: ../../po/../src/dialogs/tiledialog.cpp:692 +msgid "Equal width" +msgstr "ਬਰਾਬਰ ਚੌੜਾਈ" + +#: ../../po/../src/dialogs/tiledialog.cpp:701 +msgid "If not set, each column has the width of the widest object in it" +msgstr "" + +#. #### Radio buttons to control spacing manually or to fit selection bbox #### +#: ../../po/../src/dialogs/tiledialog.cpp:746 +msgid "Fit into selection box" +msgstr "ਚੋਣ ਬਕਸੇ ਵਿੱਚ ਫਿੱਟ" + +#: ../../po/../src/dialogs/tiledialog.cpp:753 +msgid "Set spacing:" +msgstr "ਖਾਲੀ ਥਾਂ ਦਿਓ:" + +#. #### Y Padding #### +#: ../../po/../src/dialogs/tiledialog.cpp:777 +msgid "Row spacing: " +msgstr "ਕਤਾਰ ਖਾਲੀ ਥਾਂ: " + +#: ../../po/../src/dialogs/tiledialog.cpp:786 +msgid "Vertical spacing between rows" +msgstr "ਕਤਾਰਾਂ ਵਿੱਚ ਲੰਬਕਾਰੀ ਖਾਲੀ ਥਾਂ" + +#. #### X padding #### +#: ../../po/../src/dialogs/tiledialog.cpp:795 +msgid "Column spacing:" +msgstr "ਕਾਲਮ ਖਾਲੀ ਥਾਂ:" + +#: ../../po/../src/dialogs/tiledialog.cpp:804 +msgid "Horizontal spacing between columns" +msgstr "ਕਾਲਮਾਂ ਵਿੱਚ ਖਿਤਿਜੀ ਖਾਲੀ ਥਾਂ" + +#: ../../po/../src/dialogs/tiledialog.cpp:818 +#, fuzzy +msgid "Arrange selected objects" +msgstr "ਚੁਣੀਆਂ ਇਕਾਈ ਗਰੁੱਪ ਵਿੱਚ" + +#: ../../po/../src/dialogs/xml-tree.cpp:178 +msgid "Click to select nodes, drag to rearrange." +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:189 +msgid "Click attribute to edit." +msgstr "ਗੁਣ ਸੋਧਣ ਲਈ ਦਬਾਓ।" + +#: ../../po/../src/dialogs/xml-tree.cpp:193 +#, c-format +msgid "" +"Attribute %s selected. Press Ctrl+Enter when done editing to " +"commit changes." +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:284 +msgid "Drag to reorder nodes" +msgstr "ਨੋਡਾਂ ਮੁੜ-ਲੜੀਬੱਧ ਕਰਨ ਲਈ ਸੁੱਟੋ" + +#: ../../po/../src/dialogs/xml-tree.cpp:304 +msgid "New element node" +msgstr "ਨਵੀਂ ਇਕਾਈ ਨੋਡ" + +#: ../../po/../src/dialogs/xml-tree.cpp:326 +msgid "New text node" +msgstr "ਨਵੀਂ ਪਾਠ ਨੋਡ" + +#: ../../po/../src/dialogs/xml-tree.cpp:347 +msgid "Duplicate node" +msgstr "ਦੋਹਰੀ ਨੋਡ" + +#: ../../po/../src/dialogs/xml-tree.cpp:368 +msgid "Delete node" +msgstr "ਨੋਡ ਹਟਾਓ" + +#: ../../po/../src/dialogs/xml-tree.cpp:384 +msgid "Unindent node" +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:399 +msgid "Indent node" +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:411 +msgid "Raise node" +msgstr "ਨੋਡ ਉਭਾਰੋ" + +#: ../../po/../src/dialogs/xml-tree.cpp:423 +msgid "Lower node" +msgstr "ਨੋਡ ਹੇਠਾਂ" + +#: ../../po/../src/dialogs/xml-tree.cpp:468 +msgid "Delete attribute" +msgstr "ਗੁਣ ਹਟਾਓ" + +#. TRANSLATORS: "Attribute" is a noun here +#: ../../po/../src/dialogs/xml-tree.cpp:513 +msgid "Attribute name" +msgstr "ਗੁਣ ਨਾਂ" + +#. TRANSLATORS: "Set" is a verb here +#: ../../po/../src/dialogs/xml-tree.cpp:533 +msgid "Set attribute" +msgstr "ਗੁਣ ਦਿਓ" + +#. TRANSLATORS: "Set" is a verb here +#: ../../po/../src/dialogs/xml-tree.cpp:535 +msgid "Set" +msgstr "ਦਿਓ" + +#. TRANSLATORS: "Attribute" is a noun here +#: ../../po/../src/dialogs/xml-tree.cpp:558 +msgid "Attribute value" +msgstr "ਗੁਣ ਮੁੱਲ" + +#: ../../po/../src/dialogs/xml-tree.cpp:1318 +msgid "New element node..." +msgstr "ਨਵੀਂ ਇਕਾਈ ਨੋਡ..." + +#: ../../po/../src/dialogs/xml-tree.cpp:1339 +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:100 +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:98 +msgid "Cancel" +msgstr "ਰੱਦ ਕਰੋ" + +#: ../../po/../src/dialogs/xml-tree.cpp:1345 +msgid "Create" +msgstr "ਬਣਾਓ" + +#: ../../po/../src/dialogs/xml-tree.cpp:1458 +#, c-format +msgid "" +"Cannot set %s: Another element with value %s already exists!" +msgstr "%s ਦਿੱਤਾ ਨਹੀਂ ਜਾ ਸਕਿਆ: ਹੋਰ ਇਕਾਈ ਦਾ ਮੁੱਲ %s ਪਹਿਲਾਂ ਹੀ ਹੈ!" + +#: ../../po/../src/document.cpp:369 +#, c-format +msgid "New document %d" +msgstr "ਨਵਾਂ ਦਸਤਾਵੇਜ਼ %d" + +#: ../../po/../src/document.cpp:401 +#, c-format +msgid "Memory document %d" +msgstr "ਮੈਮੋਰੀ ਦਸਤਾਵੇਜ਼ %d" + +#: ../../po/../src/document.cpp:524 +#, c-format +msgid "Unnamed document %d" +msgstr "ਬਿਨਾਂ ਨਾਂ ਦਸਤਾਵੇਜ਼ %d" + +#. We hit green anchor, closing Green-Blue-Red +#: ../../po/../src/draw-context.cpp:441 +msgid "Path is closed." +msgstr "ਮਾਰਗ ਬੰਦ ਹੈ।" + +#. We hit bot start and end of single curve, closing paths +#: ../../po/../src/draw-context.cpp:456 +msgid "Closing path." +msgstr "ਬੰਦ ਕਰਨ ਵਾਲਾ ਮਾਰਗ ਹੈ।" + +#. alpha of color under cursor, to show in the statusbar +#. locale-sensitive printf is OK, since this goes to the UI, not into SVG +#: ../../po/../src/dropper-context.cpp:354 +#, c-format +msgid " alpha %.3g" +msgstr " ਐਲਫ਼ਾ %.3g" + +#. where the color is picked, to show in the statusbar +#: ../../po/../src/dropper-context.cpp:356 +#, c-format +msgid ", averaged with radius %d" +msgstr ", ਅਰਧਵਿਆਸ %d ਨਾਲ ਔਸਤ" + +#: ../../po/../src/dropper-context.cpp:356 +msgid " under cursor" +msgstr " ਕਰਸਰ ਹੇਠ" + +#. message, to show in the statusbar +#: ../../po/../src/dropper-context.cpp:358 +msgid "Release mouse to set color." +msgstr "ਰੰਗ ਚੁਣਨ ਲਈ ਮਾਊਸ ਛੱਡੋ।" + +#: ../../po/../src/dropper-context.cpp:358 +#: ../../po/../src/tools-switch.cpp:207 +msgid "" +"Click to set fill, Shift+click to set stroke; drag to " +"average color in area; with Alt to pick inverse color; Ctrl+C " +"to copy the color under mouse to clipboard" +msgstr "" + +#: ../../po/../src/extension/dependency.cpp:244 +msgid "Dependency::" +msgstr "ਨਿਰਭਰਤਾ::" + +#: ../../po/../src/extension/dependency.cpp:245 +msgid " type: " +msgstr " ਕਿਸਮ: " + +#: ../../po/../src/extension/dependency.cpp:246 +msgid " location: " +msgstr " ਟਿਕਾਣਾ: " + +#: ../../po/../src/extension/dependency.cpp:247 +msgid " string: " +msgstr " ਸਤਰ: " + +#: ../../po/../src/extension/dependency.cpp:250 +msgid " description: " +msgstr " ਵੇਰਵਾ: " + +#. static int i = 0; +#. std::cout << "Checking module[" << i++ << "]: " << name << std::endl; +#: ../../po/../src/extension/extension.cpp:244 +msgid "" +" This is caused by an improper .inx file for this extension. An improper ." +"inx file could have been caused by a faulty installation of Inkscape." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:247 +msgid "an ID was not defined for it." +msgstr "ਇਸ ਲਈ ਕੋਈ ID ਪਰਿਭਾਸ਼ਤ ਨਹੀਂ ਹੈ।" + +#: ../../po/../src/extension/extension.cpp:251 +msgid "there was no name defined for it." +msgstr "ਇਸ ਲਈ ਕੋਈ ਨਾਂ ਨਹੀਂ ਸੀ ਦਿੱਤਾ ਗਿਆ।" + +#: ../../po/../src/extension/extension.cpp:255 +msgid "the XML description of it got lost." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:259 +msgid "no implementation was defined for the extension." +msgstr "" + +#. std::cout << "Failed: " << *(_deps[i]) << std::endl; +#: ../../po/../src/extension/extension.cpp:266 +msgid "a dependency was not met." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:286 +msgid "Extension \"" +msgstr "ਸਹਿਯੋਗੀ \"" + +#: ../../po/../src/extension/extension.cpp:286 +msgid "\" failed to load because " +msgstr "\" ਲੋਡ ਕਰਨ ਲਈ ਅਸਫ਼ਲ, ਕਿਉਕਿ " + +#: ../../po/../src/extension/extension.cpp:565 +#, c-format +msgid "Could not create extension error log file '%s'" +msgstr "ਸਹਿਯੋਗੀ ਗਲਤੀ ਲਾਗ ਫਾਇਲ '%s' ਬਣਾਈ ਨਹੀਂ ਜਾ ਸਕੀ ਹੈ" + +#. This is some filler text, needs to change before relase +#: ../../po/../src/extension/error-file.cpp:56 +msgid "" +"One or more extensions failed to load\n" +"\n" +"The failed extensions have been skipped. Inkscape will continue to run " +"normally but those extensions will be unavailable. For details to " +"troubleshoot this problem, please refer to the error log located at: " +msgstr "" + +#. This is some filler text, needs to change before relase +#: ../../po/../src/extension/error-file.cpp:65 +msgid "Show dialog on startup" +msgstr "ਸ਼ੁਰੂ ਸਮੇਂ ਵਾਰਤਾਲਾਪ ਵੇਖਾਓ" + +#: ../../po/../src/extension/implementation/script.cpp:845 +msgid "" +"Inkscape has received an error from the script that it called. The text " +"returned with the error is included below. Inkscape will continue working, " +"but the action you requested has been cancelled." +msgstr "" + +#: ../../po/../src/extension/implementation/script.cpp:858 +msgid "" +"Inkscape has received additional data from the script executed. The script " +"did not return an error, but this may indicate the results will not be as " +"expected." +msgstr "" + +#: ../../po/../src/extension/init.cpp:173 +msgid "Null external module directory name. Modules will not be loaded." +msgstr "" + +#: ../../po/../src/extension/init.cpp:187 +#, c-format +msgid "" +"Modules directory (%s) is unavailable. External modules in that directory " +"will not be loaded." +msgstr "" + +#: ../../po/../src/extension/internal/gnome.cpp:80 +msgid "Select printer" +msgstr "ਪਰਿੰਟਰ ਚੁਣੋ" + +#: ../../po/../src/extension/internal/gnome.cpp:131 +msgid "Inkscape: Print Preview" +msgstr "ਇੰਕਸਕੇਪੀ: ਛਪਾਈ ਝਲਕ" + +#: ../../po/../src/extension/internal/grid.cpp:213 +msgid "Line Width" +msgstr "ਰੇਖਾ ਚੌੜਾਈ" + +#: ../../po/../src/extension/internal/grid.cpp:214 +msgid "Horizontal Spacing" +msgstr "ਖਿਤਿਜੀ ਖਾਲੀ ਥਾਂ" + +#: ../../po/../src/extension/internal/grid.cpp:215 +msgid "Vertical Spacing" +msgstr "ਲੰਬਕਾਰੀ ਖਾਲੀ ਥਾਂ" + +#: ../../po/../src/extension/internal/grid.cpp:216 +msgid "Horizontal Offset" +msgstr "ਖਿਤਿਜੀ ਅੰਤਰ-ਲੰਬ" + +#: ../../po/../src/extension/internal/grid.cpp:217 +msgid "Vertical Offset" +msgstr "ਲੰਬਕਾਰੀ ਅੰਤਰਲੰਭ" + +#: ../../po/../src/extension/internal/ps.cpp:123 +msgid "Print Destination" +msgstr "ਛਾਪਣ ਟਿਕਾਣਾ" + +#. Print properties frame +#: ../../po/../src/extension/internal/ps.cpp:138 +msgid "Print properties" +msgstr "ਛਾਪਣ ਵਿਸ਼ੇਸਤਾ" + +#: ../../po/../src/extension/internal/ps.cpp:145 +msgid "Print using PostScript operators" +msgstr "ਪੋਸਟ-ਸਕਰਿਪਟ ਚਾਲਕਾਂ ਦੀ ਵਰਤੋਂ ਕਰਕੇ ਛਾਪੋ" + +#: ../../po/../src/extension/internal/ps.cpp:147 +msgid "" +"Use PostScript vector operators. The resulting image is usually smaller in " +"file size and can be arbitrarily scaled, but alpha transparency and patterns " +"will be lost." +msgstr "" + +#: ../../po/../src/extension/internal/ps.cpp:152 +msgid "Print as bitmap" +msgstr "ਬਿੱਟਮੈਪ ਵਾਂਗ ਛਾਪੋ" + +#: ../../po/../src/extension/internal/ps.cpp:154 +msgid "" +"Print everything as bitmap. The resulting image is usually larger in file " +"size and cannot be arbitrarily scaled without quality loss, but all objects " +"will be rendered exactly as displayed." +msgstr "" + +#: ../../po/../src/extension/internal/ps.cpp:168 +msgid "Preferred resolution (dots per inch) of bitmap" +msgstr "ਬਿੱਟਮੈਪ ਦਾ ਪਸੰਦੀਦਾ ਰੈਜ਼ੋਲੇਸ਼ਨ (ਪ੍ਰਤੀ ਇੰਚ ਬਿੰਦੂ)" + +#: ../../po/../src/extension/internal/ps.cpp:182 +msgid "Resolution:" +msgstr "ਰੈਜ਼ੋਲੇਸ਼ਨ:" + +#. Print destination frame +#: ../../po/../src/extension/internal/ps.cpp:186 +msgid "Print destination" +msgstr "ਛਪਾਈ ਟਿਕਾਣਾ" + +#: ../../po/../src/extension/internal/ps.cpp:192 +msgid "" +"Use '> filename' to print to file.\n" +"Use '| prog arg...' to pipe to a program." +msgstr "" + +#: ../../po/../src/extension/internal/ps.cpp:1227 +msgid "write error occurred" +msgstr "ਲਿਖਣ ਗਲਤੀ ਆਈ ਹੈ" + +#: ../../po/../src/extension/prefdialog.cpp:21 +msgid " Preferences" +msgstr " ਮੇਰੀ ਪਸੰਦ" + +#. We can't call sp_ui_error_dialog because we may be +#. running from the console, in which case calling sp_ui +#. routines will cause a segfault. See bug 1000350 - bryce +#. sp_ui_error_dialog(_("Format autodetect failed. The file is being opened as SVG.")); +#: ../../po/../src/extension/system.cpp:105 +msgid "Format autodetect failed. The file is being opened as SVG." +msgstr "" + +#. TRANSLATORS: default.svg is localizable - this is the name of the default document +#. template. This way you can localize the default pagesize, translate the name of +#. the default layer, etc. If you wish to localize this file, please create a +#. localized share/templates/default.xx.svg file, where xx is your language code. +#: ../../po/../src/file.cpp:133 +msgid "default.svg" +msgstr "default.svg" + +#: ../../po/../src/file.cpp:215 ../../po/../src/file.cpp:900 +#, c-format +msgid "Failed to load the requested file %s" +msgstr "ਮੰਗੀ ਫਾਇਲ %s ਨੂੰ ਲੋਡ ਕਰਨ ਲਈ ਅਸਫ਼ਲ ਹੈ" + +#: ../../po/../src/file.cpp:240 +msgid "Document not saved yet. Cannot revert." +msgstr "ਦਸਤਾਵੇਜ਼ ਹਾਲੇ ਸੰਭਾਲਿਆ ਨਹੀਂ ਗਿਆ। ਮੁੜ-ਪਰਾਪਤ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ ਹੈ।" + +#: ../../po/../src/file.cpp:246 +#, c-format +msgid "Changes will be lost! Are you sure you want to reload document %s?" +msgstr "ਤਬਦੀਲੀਆਂ ਖਤਮ ਹੋ ਜਾਣਗੀਆਂ। ਕੀ ਤੁਸੀਂ %s ਦਸਤਾਵੇਜ਼ ਨੂੰ ਮੁੜ ਪਰਾਪਤ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ?" + +#: ../../po/../src/file.cpp:266 +msgid "Document reverted." +msgstr "ਦਸਤਾਵੇਜ਼ ਵਾਪਸ ਪਰਾਪਤ ਕੀਤਾ ਗਿਆ ਹੈ।" + +#: ../../po/../src/file.cpp:268 +msgid "Document not reverted." +msgstr "ਦਸਤਾਵੇਜ਼ ਵਾਪਸ ਪਰਾਪਤ ਨਹੀਂ ਕੀਤਾ ਗਿਆ ਹੈ।" + +#: ../../po/../src/file.cpp:382 +msgid "Select file to open" +msgstr "ਖੋਲਣ ਲਈ ਫਾਇਲ ਖੋਲੋ" + +#: ../../po/../src/file.cpp:518 +#, c-format +msgid "Removed %i unused definition in <defs>." +msgid_plural "Removed %i unused definitions in <defs>." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/file.cpp:523 +msgid "No unused definitions in <defs>." +msgstr "" + +#: ../../po/../src/file.cpp:548 +#, c-format +msgid "" +"No Inkscape extension found to save document (%s). This may have been " +"caused by an unknown filename extension." +msgstr "" + +#: ../../po/../src/file.cpp:549 ../../po/../src/file.cpp:557 +msgid "Document not saved." +msgstr "ਦਸਤਾਵੇਜ਼ ਸੰਭਾਲਿਆ ਨਹੀਂ ਗਿਆ ਹੈ।" + +#: ../../po/../src/file.cpp:556 +#, c-format +msgid "File %s could not be saved." +msgstr "ਫਾਇਲ %s ਨੂੰ ਸੰਭਾਲਿਆ ਨਹੀਂ ਜਾ ਸਕਿਆ ਹੈ।" + +#: ../../po/../src/file.cpp:566 +msgid "Document saved." +msgstr "ਦਸਤਾਵੇਜ਼ ਸੰਭਾਲਿਆ ਗਿਆ ਹੈ।" + +#: ../../po/../src/file.cpp:614 +#, c-format +msgid "drawing%s" +msgstr "ਡਰਾਇੰਗ%s" + +#: ../../po/../src/file.cpp:620 +#, c-format +msgid "drawing-%d%s" +msgstr "ਡਰਾਇੰਗ-%d%s" + +#: ../../po/../src/file.cpp:655 +msgid "Select file to save to" +msgstr "ਸੰਭਾਲਣ ਲਈ ਫਾਇਲ ਚੁਣੋ" + +#: ../../po/../src/file.cpp:739 +msgid "No changes need to be saved." +msgstr "ਕੋਈ ਤਬਦੀਲੀ ਸੰਭਾਲੀ ਨਹੀਂ ਗਈ ਹੈ।" + +#: ../../po/../src/file.cpp:926 +msgid "Select file to import" +msgstr "ਅਯਾਤ ਕਰਨ ਲਈ ਫਾਇਲ ਚੁਣੋ" + +#: ../../po/../src/gradient-context.cpp:263 +msgid "Ctrl: snap gradient angle" +msgstr "" + +#: ../../po/../src/gradient-context.cpp:264 +msgid "Shift: draw gradient around the starting point" +msgstr "" + +#. We did an undoable action, but sp_document_done will be called by the knot when released +#. status text; we do not track coords because this branch is run once, not all the time +#. during drag +#: ../../po/../src/gradient-context.cpp:462 +#, c-format +msgid "Gradient for %d objects; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/gradient-context.cpp:464 +msgid "Select objects on which to create gradient." +msgstr "" + +#: ../../po/../src/gradient-drag.cpp:65 +msgid "Linear gradient start" +msgstr "" + +#. POINT_LG_P1 +#: ../../po/../src/gradient-drag.cpp:66 +msgid "Linear gradient end" +msgstr "" + +#: ../../po/../src/gradient-drag.cpp:67 +msgid "Radial gradient center" +msgstr "" + +#: ../../po/../src/gradient-drag.cpp:68 ../../po/../src/gradient-drag.cpp:69 +msgid "Radial gradient radius" +msgstr "" + +#: ../../po/../src/gradient-drag.cpp:70 +msgid "Radial gradient focus" +msgstr "" + +#: ../../po/../src/gradient-drag.cpp:659 +#, c-format +msgid "" +"%s for: %s%s; drag with Ctrl to snap angle, with Ctrl+Alt to " +"preserve angle, with Ctrl+Shift to scale around center" +msgstr "" + +#: ../../po/../src/gradient-drag.cpp:662 +msgid " (stroke)" +msgstr " (ਛੋਹ)" + +#: ../../po/../src/gradient-drag.cpp:665 +msgid "" +"Radial gradient center and focus; drag with Shift to " +"separate focus" +msgstr "" + +#: ../../po/../src/gradient-drag.cpp:667 +#, c-format +msgid "" +"Gradient point shared by %d gradients; drag with Shift to " +"separate" +msgstr "" + +#: ../../po/../src/helper/units.cpp:40 +msgid "Unit" +msgstr "ਇਕਾਈ" + +#: ../../po/../src/helper/units.cpp:40 +msgid "Units" +msgstr "ਇਕਾਈ" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Point" +msgstr "ਬਿੰਦੂ" + +#: ../../po/../src/helper/units.cpp:41 +msgid "pt" +msgstr "ਬਿੰਦੂ" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Points" +msgstr "ਬਿੰਦੂ" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Pt" +msgstr "ਬਿੰਦੂ" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Pixel" +msgstr "ਪਿਕਸਲ" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Pixels" +msgstr "ਪਿਕਸਲ" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Px" +msgstr "Px" + +#. You can add new elements from this point forward +#: ../../po/../src/helper/units.cpp:44 ../share/extensions/straightseg.inx.h:2 +msgid "Percent" +msgstr "ਫ਼ੀ-ਸਦੀ" + +#: ../../po/../src/helper/units.cpp:44 +msgid "Percents" +msgstr "ਫ਼ੀ-ਸਦੀ" + +#: ../../po/../src/helper/units.cpp:45 +msgid "Millimeter" +msgstr "ਮਿਲੀਮੀਟਰ" + +#: ../../po/../src/helper/units.cpp:45 +msgid "mm" +msgstr "ਮਿਮੀ" + +#: ../../po/../src/helper/units.cpp:45 +msgid "Millimeters" +msgstr "ਮਿਲੀਮੀਟਰ" + +#: ../../po/../src/helper/units.cpp:46 +msgid "Centimeter" +msgstr "ਸੈਂਟੀਮੀਟਰ" + +#: ../../po/../src/helper/units.cpp:46 +msgid "cm" +msgstr "ਸੈਮੀ" + +#: ../../po/../src/helper/units.cpp:46 +msgid "Centimeters" +msgstr "ਸੈਂਟੀਮੀਟਰ" + +#: ../../po/../src/helper/units.cpp:47 +msgid "Meter" +msgstr "ਮੀਟਰ" + +#: ../../po/../src/helper/units.cpp:47 +msgid "m" +msgstr "ਮੀ" + +#: ../../po/../src/helper/units.cpp:47 +msgid "Meters" +msgstr "ਮੀਟਰ" + +#. no svg_unit +#: ../../po/../src/helper/units.cpp:48 +msgid "Inch" +msgstr "ਇੰਚ" + +#: ../../po/../src/helper/units.cpp:48 +msgid "in" +msgstr "ਵਿੱਚ" + +#: ../../po/../src/helper/units.cpp:48 +msgid "Inches" +msgstr "ਇੰਚ" + +#. Volatiles do not have default, so there are none here +#. TRANSLATORS: for info, see http://www.w3.org/TR/REC-CSS2/syndata.html#length-units +#: ../../po/../src/helper/units.cpp:51 +msgid "Em square" +msgstr "" + +#: ../../po/../src/helper/units.cpp:51 +msgid "em" +msgstr "" + +#: ../../po/../src/helper/units.cpp:51 +msgid "Em squares" +msgstr "" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/REC-CSS2/syndata.html#length-units +#: ../../po/../src/helper/units.cpp:53 +msgid "Ex square" +msgstr "" + +#: ../../po/../src/helper/units.cpp:53 +msgid "ex" +msgstr "" + +#: ../../po/../src/helper/units.cpp:53 +msgid "Ex squares" +msgstr "" + +#: ../../po/../src/inkscape.cpp:468 +msgid "Untitled document" +msgstr "ਬਿਨਾਂ-ਨਾਂ ਦਸਤਾਵੇਜ਼" + +#. Show nice dialog box +#: ../../po/../src/inkscape.cpp:497 +msgid "Inkscape encountered an internal error and will close now.\n" +msgstr "ਇੰਕਸਕੇਪੀ ਨੂੰ ਇੱਕ ਅੰਦਰੂਨੀ ਗਲਤੀ ਆਈ ਹੈ ਅਤੇ ਹੁਣ ਬੰਦ ਹੋ ਰਿਹਾ ਹੈ।\n" + +#: ../../po/../src/inkscape.cpp:498 +msgid "" +"Automatic backups of unsaved documents were done to the following " +"locations:\n" +msgstr "ਨਾ-ਸੰਭਾਲੇ ਦਸਤਾਵੇਜ਼ਾਂ ਦਾ ਸਵੈ-ਚਾਲਤ ਬੈਕਅੱਪ ਹੇਠ ਦਿੱਤੇ ਟਿਕਾਣਿਆਂ ਉੱਤੇ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ:\n" + +#: ../../po/../src/inkscape.cpp:499 +msgid "Automatic backup of the following documents failed:\n" +msgstr "ਹੇਠ ਦਿੱਤੇ ਦਸਤਾਵੇਜ਼ ਦਾ ਸਵੈ-ਚਾਲਤ ਬੈਕਅੱਪ ਅਸਫ਼ਲ ਰਿਹਾ ਹੈ:\n" + +#: ../../po/../src/inkscape.cpp:634 +#, c-format +msgid "" +"Cannot create directory %s.\n" +"%s" +msgstr "" +"ਡਾਇਰੈਕਟਰੀ %s ਬਣਾਈ ਨਹੀਂ ਜਾ ਸਕਦੀ ਹੈ।\n" +"%s" + +#: ../../po/../src/inkscape.cpp:635 +#, c-format +msgid "" +"%s is not a valid directory.\n" +"%s" +msgstr "" +"%s ਇੱਕ ਠੀਕ ਡਾਇਰੈਕਟਰੀ ਨਹੀਂ ਹੈ।\n" +"%s" + +#: ../../po/../src/inkscape.cpp:636 +#, c-format +msgid "" +"Cannot create file %s.\n" +"%s" +msgstr "" +"ਫਾਇਲ %s ਬਣਾਈ ਨਹੀਂ ਜਾ ਸਕਦੀ ਹੈ।\n" +"%s" + +#: ../../po/../src/inkscape.cpp:637 +#, c-format +msgid "" +"Cannot write file %s.\n" +"%s" +msgstr "" +"ਫਾਇਲ %s ਨੂੰ ਲਿਖਿਆ ਨਹੀਂ ਜਾ ਸਕਦਾ ਹੈ।\n" +"%s" + +#: ../../po/../src/inkscape.cpp:638 +msgid "" +"Although Inkscape will run, it will use default settings,\n" +"and any changes made in preferences will not be saved." +msgstr "" + +#: ../../po/../src/inkscape.cpp:708 +#, c-format +msgid "" +"%s is not a regular file.\n" +"%s" +msgstr "" +"%s ਇੱਕ ਨਿਯਮਤ ਫਾਇਲ ਨਹੀਂ ਹੈ।\n" +"%s" + +#: ../../po/../src/inkscape.cpp:709 +#, c-format +msgid "" +"%s not a valid XML file, or\n" +"you don't have read permissions on it.\n" +"%s" +msgstr "" +"%s ਇੱਕ ਠੀਕ XML ਫਾਇਲ ਨਹੀਂ ਹੈ ਜਾਂ\n" +"ਤੁਹਾਨੂੰ ਇਸ ਨੂੰ ਪੜਨ ਦਾ ਅਧਿਕਾਰ ਨਹੀਂ ਹੈ।\n" +"%s" + +#: ../../po/../src/inkscape.cpp:711 +#, c-format +msgid "" +"%s is not a valid menus file.\n" +"%s" +msgstr "" +"%s ਇੱਕ ਠੀਕ ਮੇਨੂ ਫਾਇਲ ਨਹੀਂ ਹੈ।\n" +"%s" + +#: ../../po/../src/inkscape.cpp:712 +msgid "" +"Inkscape will run with default menus.\n" +"New menus will not be saved." +msgstr "" +"ਇੰਕਸਕੇਪੀ ਨੂੰ ਮੂਲ ਮੇਨੂ ਨਾਲ ਹੀ ਚਲਾਇਆ ਜਾਵੇਗਾ।\n" +"ਨਵੇਂ ਮੇਨੂ ਸੰਭਾਲੇ ਨਹੀਂ ਜਾਣਗੇ।" + +#. sp_ui_menu_append_check_item_from_verb(m, view, _("_Menu"), _("Show or hide the menu bar"), "menu", +#. checkitem_toggled, checkitem_update, 0); +#: ../../po/../src/interface.cpp:753 +msgid "Commands Bar" +msgstr "ਕਮਾਂਡ ਪੱਟੀ" + +#: ../../po/../src/interface.cpp:753 +msgid "Show or hide the Commands bar (under the menu)" +msgstr "ਕਮਾਂਡ ਪੱਟੀ ਵੇਖਾਓ ਜਾਂ ਓਹਲੇ (ਮੇਨੂ ਦੇ ਹੇਠਾਂ)" + +#: ../../po/../src/interface.cpp:755 +msgid "Tool Controls" +msgstr "ਸੰਦ ਕੰਟਰੋਲ" + +#: ../../po/../src/interface.cpp:755 +msgid "Show or hide the Tool Controls panel" +msgstr "ਸੰਦ ਕੰਟਰੋਲ ਪੈਨਲ ਵੇਖਾਓ ਜਾਂ ਓਹਲੇ" + +#: ../../po/../src/interface.cpp:757 +msgid "_Toolbox" +msgstr "ਸੰਦ-ਪੱਟੀ(_T)" + +#: ../../po/../src/interface.cpp:757 +msgid "Show or hide the main toolbox (on the left)" +msgstr "ਮੁੱਖ ਸੰਦ-ਪੱਟੀ ਵੇਖਾਓ ਜਾਂ ਓਹਲੇ (ਖੱਬੇ ਪਾਸੇ)" + +#: ../../po/../src/interface.cpp:763 +msgid "_Statusbar" +msgstr "ਹਾਲਤ-ਪੱਟੀ(_S)" + +#: ../../po/../src/interface.cpp:763 +msgid "Show or hide the statusbar (at the bottom of the window)" +msgstr "ਹਾਲਤ-ਪੱਟੀ ਵੇਖਾਓ ਜਾਂ ਓਹਲੇ (ਝਰੋਖੇ ਦੇ ਤਲ ਉੱਤੇ)" + +#: ../../po/../src/interface.cpp:820 +#, c-format +msgid "Verb \"%s\" Unknown" +msgstr "ਵਰਬ \"%s\" ਅਣਜਾਣ" + +#. TRANSLATORS: #%s is the id of the group e.g. , not a number. +#: ../../po/../src/interface.cpp:930 +#, c-format +msgid "Enter group #%s" +msgstr "ਗਰੁੱਪ #%s ਦਿਓ" + +#: ../../po/../src/interface.cpp:941 +msgid "Go to parent" +msgstr "ਮੁੱਢਲੇ 'ਤੇ ਜਾਓ" + +#: ../../po/../src/interface.cpp:972 +msgid "Could not parse SVG data" +msgstr "SVG ਡਾਟਾ ਪਾਰਸ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਿਆ" + +#: ../../po/../src/interface.cpp:1135 +#, c-format +msgid "Overwrite %s" +msgstr "%s ਉੱਪਰ ਲਿਖੋ" + +#: ../../po/../src/interface.cpp:1153 +#, c-format +msgid "" +"The file %s already exists. Do you want to overwrite that file with the " +"current document?" +msgstr "" +"ਫਾਇਲ %s ਪਹਿਲਾਂ ਹੀ ਮੌਜੂਦ ਹੈ। ਕੀ ਤੁਸੀਂ ਉਸ ਫਾਇਲ ਨੂੰ ਇਸ ਦਸਤਾਵੇਜ਼ ਨਾਲ ਤਬਦੀਲ ਕਰਨਾ ਚਾਹੁੰਦੇ ਹੋ?" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:59 +msgid "Jabber connection lost." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:72 +#, c-format +msgid "Sending message; %u message remaining in send queue." +msgid_plural "Sending message; %u messages remaining in send queue." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:78 +msgid "Receive queue empty." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:154 +#, c-format +msgid "Receiving change; %u change left to process." +msgid_plural "Receiving change; %u changes left to process." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:157 +#, c-format +msgid "%s has left the chatroom." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:221 +msgid "Nickname %1 is already in use. Please choose a different nickname." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:225 +msgid "An error was encountered while attempting to connect to the server." +msgstr "" + +#. Check to see if the user made any modifications to this document. If so, +#. we want to give them the option of (1) letting us clear their document or (2) +#. opening a new, blank document for the whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:131 +msgid "%1 has invited you to a whiteboard session." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:132 +msgid "Incoming whiteboard invitation from %1" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:135 +msgid "Do you wish to accept %1's whiteboard session invitation?" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:137 +msgid "" +"Would you like to accept %1's invitation in a new document window?\n" +"Accepting the invitation in your current window will discard unsaved changes." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:143 +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:198 +#, fuzzy +msgid "Accept invitation" +msgstr "ਪਰਵੇਸ਼" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:144 +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:199 +msgid "Decline invitation" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:145 +#, fuzzy +msgid "Accept invitation in new document window" +msgstr "ਨਵੇਂ ਦਸਤਾਵੇਜ਼ ਝਰੋਖੇ ਲਈ ਤਬਦੀਲ" + +#. We could not create a new desktop; ask the user if she or he wants to +#. replace the current document and accept the invitation, or reject the invitation. +#. TRANSLATORS: %1 is a userid here +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:196 +msgid "" +"A new document window could not be opened for a whiteboard session with %" +"1" +msgstr "" + +#. TRANSLATORS: %1 is the peer whom refused our invitation. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:238 +msgid "" +"The user %1 has refused your " +"whiteboard invitation.\n" +"\n" +msgstr "" + +#. TRANSLATORS: %1 is the peer whom refused our invitation, %2 is our Jabber identity. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:241 +msgid "" +"You are still connected to a Jabber server as %2, and may send an " +"invitation to %1 again, or you may send an invitation to a different " +"user." +msgstr "" + +#. TRANSLATORS: %1 is the peer whom we tried to contact, but is already in a whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:252 +msgid "" +"The user %1 is already in a " +"whiteboard session.\n" +"\n" +msgstr "" + +#. TRANSLATORS: %1 is the peer whom we tried to contact, but is already in a whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:255 +msgid "" +"You are still connected to a Jabber server as %1, and may send an " +"invitation to a different user." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/invitation-confirm-dialog.cpp:26 +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:24 +#, fuzzy +msgid "_Write session file:" +msgstr "ਅਜਲਾਸ ਫਾਇਲ ਖੋਲੋ" + +#: ../../po/../src/jabber_whiteboard/message-processors.cpp:145 +#, c-format +msgid "%s has joined the chatroom." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/message-queue.cpp:87 +#, fuzzy, c-format +msgid "%u change in receive queue." +msgid_plural "%u changes in receive queue." +msgstr[0] "ਕੋਈ ਤਬਦੀਲੀ ਸੰਭਾਲੀ ਨਹੀਂ ਗਈ ਹੈ।" +msgstr[1] "ਕੋਈ ਤਬਦੀਲੀ ਸੰਭਾਲੀ ਨਹੀਂ ਗਈ ਹੈ।" + +#: ../../po/../src/jabber_whiteboard/message-queue.cpp:117 +#, fuzzy, c-format +msgid "%u change in send queue." +msgid_plural "%u changes in send queue." +msgstr[0] "ਕੋਈ ਤਬਦੀਲੀ ਸੰਭਾਲੀ ਨਹੀਂ ਗਈ ਹੈ।" +msgstr[1] "ਕੋਈ ਤਬਦੀਲੀ ਸੰਭਾਲੀ ਨਹੀਂ ਗਈ ਹੈ।" + +#. if ID is NULL, then we have a real problem -- we were not able to find a key +#. nor generate one. The only thing we can really do here is abort, since we have +#. no way to let the other client(s) uniquely identify this object. +#. FIXME: If this indicates a programming bug, then don't request translation with +#. * _(...): it is most useful in untranslated form so that developers may search for +#. * it when someone reports it in a bug report (as we want users to do for all bugs, +#. * as indicated by it being a g_warning string). +#. * +#. * Otherwise, if it is not a programming bug but a network error or a bug in the +#. * remote peer (perhaps running different software) or whatever, then present it in +#. * an alert box, and avoid use of technical jargon `NULL'. +#. +#: ../../po/../src/jabber_whiteboard/message-utilities.cpp:171 +msgid "" +"ID for new object is NULL even after generation and lookup attempts: the new " +"object will NOT be sent, nor will any of its child objects!" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:60 +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:995 +msgid "Select a location and filename" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:62 +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:997 +#, fuzzy +msgid "Set filename" +msgstr "ਫਾਇਲ ਨਾਂ(_F)" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:301 +msgid "No SSL certificate was found." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:304 +msgid "The SSL certificate provided by the Jabber server is untrusted." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:307 +msgid "The SSL certificate provided by the Jabber server is expired." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:310 +msgid "" +"The SSL certificate provided by the Jabber server has not been activated." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:313 +msgid "" +"The SSL certificate provided by the Jabber server contains a hostname that " +"does not match the Jabber server's hostname." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:316 +msgid "" +"The SSL certificate provided by the Jabber server contains an invalid " +"fingerprint." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:319 +msgid "An unknown error occurred while setting up the SSL connection." +msgstr "" + +#. TRANSLATORS: %1 is the message that describes the specific error that occurred when +#. establishing the SSL connection. +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:325 +msgid "" +"%1\n" +"\n" +"Do you wish to continue connecting to the Jabber server?" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:328 +msgid "Continue connecting and ignore further errors" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:329 +msgid "Continue connecting, but warn me of further errors" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:330 +#, fuzzy +msgid "Cancel connection" +msgstr "ਚੋਣ" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:777 +#, c-format +msgid "Established whiteboard session with %s." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:785 +#, c-format +msgid "%s has left the whiteboard session." +msgstr "" + +#. Inform the user +#. TRANSLATORS: %1 is the name of the user that disconnected, %2 is the name of the user whom the disconnected user disconnected from. +#. This message is not used in a chatroom context. +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:790 +msgid "" +"The user %1 has left the " +"whiteboard session.\n" +"\n" +msgstr "" + +#. TRANSLATORS: %1 and %2 are userids +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:792 +msgid "" +"You are still connected to a Jabber server as %2, and may establish a " +"new session to %1 or a different user." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:988 +msgid "" +"Could not open file %1 for session recording.\n" +"The error encountered was: %2.\n" +"\n" +"You may select a different location to record the session, or you may opt to " +"not record this session." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:990 +msgid "Choose a different location" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:991 +msgid "Skip session recording" +msgstr "" + +#: ../../po/../src/knot.cpp:673 +msgid "Node or handle drag canceled." +msgstr "" + +#: ../../po/../src/libnrtype/FontFactory.cpp:358 +msgid "Ignoring font without family that will crash Pango" +msgstr "" + +#: ../../po/../src/main.cpp:395 +msgid "Print the Inkscape version number" +msgstr "ਇੰਕਸਕੇਪੀ ਵਰਜਨ ਨੰਬਰ ਛਾਪੋ" + +#: ../../po/../src/main.cpp:400 +msgid "Do not use X server (only process files from console)" +msgstr "X ਸਰਵਰ ਨਾ ਵਰਤੋਂ (ਫਾਇਲਾਂ ਨੂੰ ਸਿਰਫ਼ ਕੰਨਸੋਲ ਤੋਂ ਹੀ ਵਰਤੋਂ)" + +#: ../../po/../src/main.cpp:405 +msgid "Try to use X server (even if $DISPLAY is not set)" +msgstr "X ਸਰਵਰ ਵਰਤਣ ਦੀ ਕੋਸ਼ਸ਼ (ਭਾਵੇਂ $DISPLAY ਨਹੀਂ ਦਿੱਤਾ ਹੈ)" + +#: ../../po/../src/main.cpp:410 +msgid "Open specified document(s) (option string may be excluded)" +msgstr "ਦਿੱਤਾ ਦਸਤਾਵੇਜ਼ ਖੋਲੋ (ਚੋਣ ਸਤਰ ਨੂੰ ਵੱਖ ਰੱਖਿਆ ਜਾ ਸਕਦਾ ਹੈ)" + +#: ../../po/../src/main.cpp:411 ../../po/../src/main.cpp:416 +#: ../../po/../src/main.cpp:421 ../../po/../src/main.cpp:483 +#: ../../po/../src/main.cpp:488 ../../po/../src/main.cpp:493 +msgid "FILENAME" +msgstr "ਫਾਇਲ ਨਾਂ" + +#: ../../po/../src/main.cpp:415 +msgid "Print document(s) to specified output file (use '| program' for pipe)" +msgstr "" + +#: ../../po/../src/main.cpp:420 +msgid "Export document to a PNG file" +msgstr "ਦਸਤਾਵੇਜ਼ ਨੂੰ PNG ਫਾਇਲ ਵਾਂਗ ਨਿਰਯਾਤ" + +#: ../../po/../src/main.cpp:425 +msgid "The resolution used for exporting SVG into bitmap (default 90)" +msgstr "" + +#: ../../po/../src/main.cpp:426 +msgid "DPI" +msgstr "DPI" + +#: ../../po/../src/main.cpp:430 +msgid "" +"Exported area in SVG user units (default is the canvas; 0,0 is lower-left " +"corner)" +msgstr "" + +#: ../../po/../src/main.cpp:431 +msgid "x0:y0:x1:y1" +msgstr "x0:y0:x1:y1" + +#: ../../po/../src/main.cpp:435 +msgid "Exported area is the entire drawing (not canvas)" +msgstr "" + +#: ../../po/../src/main.cpp:440 +msgid "" +"Snap the bitmap export area outwards to the nearest integer values (in SVG " +"user units)" +msgstr "" + +#: ../../po/../src/main.cpp:445 +msgid "The width of exported bitmap in pixels (overrides export-dpi)" +msgstr "" + +#: ../../po/../src/main.cpp:446 +msgid "WIDTH" +msgstr "ਚੌੜਾਈ" + +#: ../../po/../src/main.cpp:450 +msgid "The height of exported bitmap in pixels (overrides export-dpi)" +msgstr "" + +#: ../../po/../src/main.cpp:451 +msgid "HEIGHT" +msgstr "ਉਚਾਈ" + +#: ../../po/../src/main.cpp:455 +msgid "The ID of the object to export (overrides export-area)" +msgstr "" + +#: ../../po/../src/main.cpp:456 ../../po/../src/main.cpp:532 +msgid "ID" +msgstr "ID" + +#. TRANSLATORS: this means: "Only export the object whose id is given in --export-id". +#. See "man inkscape" for details. +#: ../../po/../src/main.cpp:462 +msgid "" +"Export just the object with export-id, hide all others (only with export-id)" +msgstr "" + +#: ../../po/../src/main.cpp:467 +msgid "Use stored filename and DPI hints when exporting (only with export-id)" +msgstr "" + +#: ../../po/../src/main.cpp:472 +msgid "Background color of exported bitmap (any SVG-supported color string)" +msgstr "" + +#: ../../po/../src/main.cpp:473 +msgid "COLOR" +msgstr "ਰੰਗ" + +#: ../../po/../src/main.cpp:477 +msgid "Background opacity of exported bitmap (either 0.0 to 1.0, or 1 to 255)" +msgstr "" + +#: ../../po/../src/main.cpp:478 +msgid "VALUE" +msgstr "ਮੁੱਲ" + +#: ../../po/../src/main.cpp:482 +msgid "Export document to plain SVG file (no sodipodi or inkscape namespaces)" +msgstr "" + +#: ../../po/../src/main.cpp:487 +msgid "Export document to a PS file" +msgstr "ਦਸਤਾਵੇਜ਼ ਨੂੰ PS ਫਾਇਲ ਵਾਂਗ ਨਿਰਯਾਤ" + +#: ../../po/../src/main.cpp:492 +msgid "Export document to an EPS file" +msgstr "ਦਸਤਾਵੇਜ਼ ਨੂੰ EPS ਫਾਇਲ ਵਾਂਗ ਨਿਰਯਾਤ" + +#: ../../po/../src/main.cpp:497 +msgid "Convert text object to paths on export (EPS)" +msgstr "" + +#: ../../po/../src/main.cpp:502 +msgid "Export files with the bounding box set to the page size (EPS)" +msgstr "" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:508 +msgid "" +"Query the X coordinate of the drawing or, if specified, of the object with --" +"query-id" +msgstr "" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:514 +msgid "" +"Query the Y coordinate of the drawing or, if specified, of the object with --" +"query-id" +msgstr "" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:520 +msgid "" +"Query the width of the drawing or, if specified, of the object with --query-" +"id" +msgstr "" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:526 +msgid "" +"Query the height of the drawing or, if specified, of the object with --query-" +"id" +msgstr "" + +#: ../../po/../src/main.cpp:531 +msgid "The ID of the object whose dimensions are queried" +msgstr "" + +#. TRANSLATORS: this option makes Inkscape print the name (path) of the extension directory +#: ../../po/../src/main.cpp:537 +msgid "Print out the extension directory and exit" +msgstr "ਸਹਿਯੋਗੀ ਡਾਇਰੈਕਟਰੀ ਛਾਪੋ ਅਤੇ ਬੰਦ ਕਰੋ" + +#: ../../po/../src/main.cpp:542 +msgid "Show given files one-by-one, switch to next on any key/mouse event" +msgstr "" + +#: ../../po/../src/main.cpp:547 +msgid "Use the new Gtkmm GUI interface" +msgstr "ਨਵਾਂ Gtkmm GUI ਇੰਟਰਫੇਸ ਵਰਤੋਂ" + +#: ../../po/../src/main.cpp:552 +msgid "Remove unused definitions from the defs section(s) of the document" +msgstr "" + +#: ../../po/../src/main.cpp:741 +msgid "" +"[OPTIONS...] [FILE...]\n" +"\n" +"Available options:" +msgstr "" +"[OPTIONS...] [FILE...]\n" +"\n" +"ਉਪਲੱਬਧ ਚੋਣਾਂ:" + +#: ../../po/../src/menus-skeleton.h:17 +msgid "_New" +msgstr "" + +#: ../../po/../src/menus-skeleton.h:22 +#, fuzzy +msgid "Open _Recent" +msgstr "ਖੁੱਲੀ ਚਾਪ" + +#: ../../po/../src/menus-skeleton.h:53 +#, fuzzy +msgid "_Edit" +msgstr "ਸੋਧ..." + +#: ../../po/../src/menus-skeleton.h:84 +#, fuzzy +msgid "_View" +msgstr "ਓਹਲੇ(_H)" + +#: ../../po/../src/menus-skeleton.h:85 +#, fuzzy +msgid "_Zoom" +msgstr "ਜ਼ੂਮ" + +#: ../../po/../src/menus-skeleton.h:102 +#, fuzzy +msgid "Show/Hide" +msgstr "ਗਰਿੱਡ ਵੇਖਾਓ" + +#: ../../po/../src/menus-skeleton.h:107 +msgid "_Display mode" +msgstr "" + +#: ../../po/../src/menus-skeleton.h:126 +#, fuzzy +msgid "_Layer" +msgstr "ਪਰਤ ਹੇਠਾਂ(_L)" + +#: ../../po/../src/menus-skeleton.h:143 +#, fuzzy +msgid "_Object" +msgstr "ਇਕਾਈ" + +#: ../../po/../src/menus-skeleton.h:165 +#, fuzzy +msgid "_Path" +msgstr "ਮਾਰਗ" + +#: ../../po/../src/menus-skeleton.h:188 +#, fuzzy +msgid "_Text" +msgstr "ਪਾਠ" + +#: ../../po/../src/menus-skeleton.h:200 +#, fuzzy +msgid "Effects" +msgstr "ਅੰਤਰ-ਲੰਬ" + +#: ../../po/../src/menus-skeleton.h:207 +msgid "Whiteboa_rd" +msgstr "" + +#: ../../po/../src/menus-skeleton.h:220 +#, fuzzy +msgid "_Help" +msgstr "ਭੰਡਾਰ" + +#: ../../po/../src/menus-skeleton.h:222 +#, fuzzy +msgid "Tutorials" +msgstr "tutorial-tips.svg" + +#: ../../po/../src/node-context.cpp:382 +msgid "" +"Ctrl: toggle node type, snap handle angle, move hor/vert; Ctrl" +"+Alt: move along handles" +msgstr "" + +#: ../../po/../src/node-context.cpp:383 +msgid "" +"Shift: toggle node selection, disable snapping, rotate both handles" +msgstr "" + +#: ../../po/../src/node-context.cpp:384 +msgid "Alt: lock handle length; Ctrl+Alt: move along handles" +msgstr "" + +#: ../../po/../src/nodepath.cpp:1399 ../../po/../src/nodepath.cpp:1411 +#: ../../po/../src/nodepath.cpp:1492 ../../po/../src/nodepath.cpp:1504 +msgid "To join, you must have two endnodes selected." +msgstr "" + +#: ../../po/../src/nodepath.cpp:1633 ../../po/../src/nodepath.cpp:1647 +msgid "" +"Select two non-endpoint nodes on a path between which to delete " +"segments." +msgstr "" + +#: ../../po/../src/nodepath.cpp:1743 +msgid "Cannot find path between nodes." +msgstr "ਨੋਡਾਂ ਵਿੱਚ ਮਾਰਗ ਨਹੀਂ ਖੋਜਿਆ ਜਾ ਸਕਦਾ ਹੈ।" + +#: ../../po/../src/nodepath.cpp:2822 +#, c-format +msgid "" +"Node handle: angle %0.2f°, length %s; with Ctrl to snap " +"angle; with Alt to lock length; with Shift to rotate both " +"handles" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3351 +msgid "" +"Node: drag to edit the path; with Ctrl to snap to horizontal/" +"vertical; with Ctrl+Alt to snap to handles' directions" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3375 +msgid "" +"Node handle: drag to shape the curve; with Ctrl to snap angle; " +"with Alt to lock length; with Shift to rotate both handles" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3399 +msgid "" +"Node handle: drag to shape the curve; with Ctrl to snap angle; " +"with Alt to lock length; with Shift to rotate the opposite " +"handle in sync" +msgstr "" + +#. TRANSLATORS: "end" is an adjective here (NOT a verb) +#: ../../po/../src/nodepath.cpp:3591 +msgid "end node" +msgstr "ਅੰਤ ਨੋਡ" + +#. TRANSLATORS: "cusp" means "sharp" (cusp node); see also the Advanced Tutorial +#: ../../po/../src/nodepath.cpp:3596 +msgid "cusp" +msgstr "" + +#. TRANSLATORS: "smooth" is an adjective here +#: ../../po/../src/nodepath.cpp:3599 +msgid "smooth" +msgstr "ਮੁਲਾਇਮ" + +#: ../../po/../src/nodepath.cpp:3601 +msgid "symmetric" +msgstr "ਸਮਮਿਤੀ" + +#. TRANSLATORS: "end" is an adjective here (NOT a verb) +#: ../../po/../src/nodepath.cpp:3607 +msgid "end node, handle retracted (drag with Shift to extend)" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3609 +msgid "one handle retracted (drag with Shift to extend)" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3612 +msgid "both handles retracted (drag with Shift to extend)" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3624 +msgid "Drag nodes or node handles; arrow keys to move nodes" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3625 +msgid "Drag the node or its handles; arrow keys to move the node" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3651 ../../po/../src/nodepath.cpp:3663 +msgid "Select a single object to edit its nodes or handles." +msgstr "" + +#: ../../po/../src/nodepath.cpp:3655 +#, c-format +msgid "" +"0 out of %i node selected. Click, Shift+click, " +"or drag around nodes to select." +msgid_plural "" +"0 out of %i nodes selected. Click, Shift+click, " +"or drag around nodes to select." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/nodepath.cpp:3661 +msgid "Drag the handles of the object to modify it." +msgstr "" + +#: ../../po/../src/nodepath.cpp:3669 +#, c-format +msgid "%i of %i node selected; %s. %s." +msgid_plural "%i of %i nodes selected; %s. %s." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/nodepath.cpp:3675 +#, c-format +msgid "%i of %i node selected. %s." +msgid_plural "%i of %i nodes selected. %s." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/object-edit.cpp:493 +msgid "" +"Adjust the horizontal rounding radius; with Ctrl to make the " +"vertical radius the same" +msgstr "" + +#: ../../po/../src/object-edit.cpp:499 +msgid "" +"Adjust the vertical rounding radius; with Ctrl to make the " +"horizontal radius the same" +msgstr "" + +#: ../../po/../src/object-edit.cpp:506 ../../po/../src/object-edit.cpp:513 +msgid "" +"Adjust the width and height of the rectangle; with Ctrl to " +"lock ratio or stretch in one dimension only" +msgstr "" + +#: ../../po/../src/object-edit.cpp:686 +msgid "Adjust ellipse width, with Ctrl to make circle" +msgstr "" + +#: ../../po/../src/object-edit.cpp:689 +msgid "Adjust ellipse height, with Ctrl to make circle" +msgstr "" + +#: ../../po/../src/object-edit.cpp:692 +msgid "" +"Position the start point of the arc or segment; with Ctrl to " +"snap angle; drag inside the ellipse for arc, outside for " +"segment" +msgstr "" + +#: ../../po/../src/object-edit.cpp:695 +msgid "" +"Position the end point of the arc or segment; with Ctrl to " +"snap angle; drag inside the ellipse for arc, outside for " +"segment" +msgstr "" + +#: ../../po/../src/object-edit.cpp:800 +msgid "" +"Adjust the tip radius of the star or polygon; with Shift to " +"round; with Alt to randomize" +msgstr "" + +#: ../../po/../src/object-edit.cpp:803 +msgid "" +"Adjust the base radius of the star; with Ctrl to keep star " +"rays radial (no skew); with Shift to round; with Alt to " +"randomize" +msgstr "" + +#: ../../po/../src/object-edit.cpp:967 +msgid "" +"Roll/unroll the spiral from inside; with Ctrl to snap angle; " +"with Alt to converge/diverge" +msgstr "" + +#: ../../po/../src/object-edit.cpp:969 +msgid "" +"Roll/unroll the spiral from outside; with Ctrl to snap angle; " +"with Shift to scale/rotate" +msgstr "" + +#: ../../po/../src/object-edit.cpp:1006 +msgid "Adjust the offset distance" +msgstr "" + +#. TRANSLATORS: This refers to the pattern that's inside the object +#: ../../po/../src/object-edit.cpp:1036 +msgid "Move the pattern fill inside the object" +msgstr "" + +#: ../../po/../src/object-edit.cpp:1038 +msgid "Scale the pattern fill uniformly" +msgstr "" + +#: ../../po/../src/object-edit.cpp:1040 +msgid "Rotate the pattern fill; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/object-edit.cpp:1065 +msgid "Drag to resize the flowed text frame" +msgstr "" + +#. Item dialog +#: ../../po/../src/object-ui.cpp:106 +msgid "Object _Properties" +msgstr "ਇਕਾਈ ਵਿਸ਼ੇਸਤਾ(_P)" + +#. Select item +#: ../../po/../src/object-ui.cpp:116 +msgid "_Select This" +msgstr "ਇਹ ਚੁਣੋ(_S)" + +#. Create link +#: ../../po/../src/object-ui.cpp:126 +msgid "_Create Link" +msgstr "ਸਬੰਧ ਬਣਾਓ(_C)" + +#. "Ungroup" +#: ../../po/../src/object-ui.cpp:199 ../../po/../src/verbs.cpp:1931 +msgid "_Ungroup" +msgstr "ਗਰੁੱਪ ਖੋਲੋ(_U)" + +#. Link dialog +#: ../../po/../src/object-ui.cpp:239 +msgid "Link _Properties" +msgstr "ਸਬੰਧ ਵਿਸ਼ੇਸਤਾ(_P)" + +#. Select item +#: ../../po/../src/object-ui.cpp:249 +msgid "_Follow Link" +msgstr "ਸਬੰਧ ਵੇਖੋ(_F)" + +#. Reset transformations +#: ../../po/../src/object-ui.cpp:254 +msgid "_Remove Link" +msgstr "ਸਬੰਧ ਹਟਾਓ(_R)" + +#. Link dialog +#: ../../po/../src/object-ui.cpp:303 +msgid "Image _Properties" +msgstr "ਚਿੱਤਰ ਵਿਸ਼ੇਸਤਾ(_P)" + +#. Item dialog +#: ../../po/../src/object-ui.cpp:344 +msgid "_Fill and Stroke" +msgstr "ਭਰਨ ਅਤੇ ਛੋਹ(_F)" + +#: ../../po/../src/path-chemistry.cpp:58 +msgid "Select at least two objects to combine." +msgstr "" + +#: ../../po/../src/path-chemistry.cpp:65 +msgid "At least one of the objects is not a path, cannot combine." +msgstr "" + +#: ../../po/../src/path-chemistry.cpp:73 +msgid "" +"You cannot combine objects from different groups or layers." +msgstr "" + +#: ../../po/../src/path-chemistry.cpp:155 +msgid "Select path(s) to break apart." +msgstr "" + +#: ../../po/../src/path-chemistry.cpp:231 +msgid "No path(s) to break apart in the selection." +msgstr "" + +#: ../../po/../src/path-chemistry.cpp:252 +msgid "Select object(s) to convert to path." +msgstr "" + +#: ../../po/../src/path-chemistry.cpp:297 +msgid "No objects to convert to path in the selection." +msgstr "" + +#: ../../po/../src/path-chemistry.cpp:345 +msgid "Select path(s) to reverse." +msgstr "ਉਲਟ ਲਈ ਮਾਰਗ ਚੁਣੋ।" + +#: ../../po/../src/path-chemistry.cpp:370 +msgid "No paths to reverse in the selection." +msgstr "" + +#: ../../po/../src/pen-context.cpp:379 ../../po/../src/pencil-context.cpp:233 +msgid "Continuing selected path" +msgstr "" + +#: ../../po/../src/pen-context.cpp:390 ../../po/../src/pencil-context.cpp:242 +msgid "Creating new path" +msgstr "ਨਵਾਂ ਮਾਰਗ ਬਣਾਇਆ ਜਾ ਰਿਹਾ ਹੈ" + +#: ../../po/../src/pen-context.cpp:394 ../../po/../src/pencil-context.cpp:246 +msgid "Appending to selected path" +msgstr "ਚੁਣੇ ਮਾਰਗ ਵਿੱਚ ਜੋੜਿਆ ਜਾ ਰਿਹਾ ਹੈ" + +#: ../../po/../src/pen-context.cpp:538 +msgid "Click or click and drag to close and finish the path." +msgstr "" + +#: ../../po/../src/pen-context.cpp:548 +msgid "" +"Click or click and drag to continue the path from this point." +msgstr "" + +#: ../../po/../src/pen-context.cpp:857 +#, c-format +msgid "" +"%s: angle %3.2f°, distance %s; with Ctrl to snap angle, " +"Enter to finish the path" +msgstr "" + +#: ../../po/../src/pen-context.cpp:882 +#, c-format +msgid "" +"Curve handle: angle %3.2f°, length %s; with Ctrl to snap " +"angle" +msgstr "" + +#: ../../po/../src/pen-context.cpp:912 +#, c-format +msgid "" +"%s: angle %3.2f°, length %s; with Ctrl to snap angle, " +"with Shift to move this handle only" +msgstr "" + +#: ../../po/../src/pen-context.cpp:946 +msgid "Finishing pen" +msgstr "ਪੈਨ ਖਤਮ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ" + +#: ../../po/../src/pencil-context.cpp:320 +msgid "Release here to close and finish the path." +msgstr "" + +#: ../../po/../src/pencil-context.cpp:326 +#, fuzzy +msgid "Drawing a freehand path" +msgstr "ਹੱਥ ਨਾਲ ਰੇਖਾਵਾਂ ਖਿੱਚੋ" + +#: ../../po/../src/pencil-context.cpp:331 +msgid "Drag to continue the path from this point." +msgstr "" + +#. Write curves to object +#: ../../po/../src/pencil-context.cpp:390 +msgid "Finishing freehand" +msgstr "ਹੱਥ ਨਾਲ ਕੰਮ ਖਤਮ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ" + +#: ../../po/../src/rect-context.cpp:387 +msgid "" +"Ctrl: make square or integer-ratio rect, lock a rounded corner " +"circular" +msgstr "" + +#: ../../po/../src/rect-context.cpp:549 +#, c-format +msgid "" +"Rectangle: %s × %s; with Ctrl to make square or integer-" +"ratio rectangle; with Shift to draw around the starting point" +msgstr "" + +#: ../../po/../src/select-context.cpp:243 +msgid "Move canceled." +msgstr "ਭੇਜਣਾ ਰੱਦ ਕੀਤਾ ਗਿਆ ਹੈ।" + +#: ../../po/../src/select-context.cpp:252 +msgid "Selection canceled." +msgstr "ਚੋਣ ਰੱਦ ਕੀਤੀ ਗਈ ਹੈ।" + +#: ../../po/../src/select-context.cpp:642 +msgid "Ctrl: select in groups, move hor/vert" +msgstr "" + +#: ../../po/../src/select-context.cpp:643 +msgid "Shift: toggle select, force rubberband, disable snapping" +msgstr "" + +#: ../../po/../src/select-context.cpp:644 +msgid "Alt: select under, move selected" +msgstr "" + +#: ../../po/../src/select-context.cpp:798 +msgid "Selected object is not a group. Cannot enter." +msgstr "" + +#: ../../po/../src/select-context.cpp:876 +#, c-format +msgid "" +"Move by %s, %s; with Ctrl to restrict to horizontal/vertical; " +"with Shift to disable snapping" +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:228 +msgid "Nothing was deleted." +msgstr "ਹਟਾਉਣ ਲਈ ਕੁਝ ਨਹੀਂ ਹੈ।" + +#: ../../po/../src/selection-chemistry.cpp:259 +msgid "Select object(s) to duplicate." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:420 +msgid "Select two or more objects to group." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:428 +msgid "Select at least two objects to group." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:513 +msgid "Select a group to ungroup." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:554 +msgid "No groups to ungroup in the selection." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:623 +msgid "Select objects to raise." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:629 +#: ../../po/../src/selection-chemistry.cpp:681 +#: ../../po/../src/selection-chemistry.cpp:715 +#: ../../po/../src/selection-chemistry.cpp:773 +msgid "" +"You cannot raise/lower objects from different groups or layers." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:673 +msgid "Select object(s) to raise to top." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:709 +msgid "Select object(s) to lower." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:765 +msgid "Select object(s) to lower to bottom." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:806 +msgid "Nothing to undo." +msgstr "ਵਾਪਸ ਕਰਨ ਲਈ ਕੁਝ ਨਹੀਂ ਹੈ।" + +#: ../../po/../src/selection-chemistry.cpp:813 +msgid "Nothing to redo." +msgstr "ਮੁੜ-ਵਾਪਸ ਕਰਨ ਲਈ ਕੁਝ ਨਹੀਂ ਹੈ।" + +#: ../../po/../src/selection-chemistry.cpp:969 +msgid "Nothing was copied." +msgstr "ਨਕਲ ਕਰਨ ਲਈ ਕੁਝ ਨਹੀਂ ਹੈ।" + +#: ../../po/../src/selection-chemistry.cpp:1051 +msgid "Current layer is hidden. Unhide it to be able to paste to it." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1055 +msgid "Current layer is locked. Unlock it to be able to paste to it." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1068 +#: ../../po/../src/selection-chemistry.cpp:1103 +msgid "Nothing on the clipboard." +msgstr "ਕਲਿੱਪਬੋਰਡ ਵਿੱਚ ਕੁਝ ਨਹੀਂ ਹੈ।" + +#: ../../po/../src/selection-chemistry.cpp:1109 +msgid "Select object(s) to paste style to." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1128 +msgid "Select object(s) to move to the layer above." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1146 +msgid "No more layers above." +msgstr "ਕੋਈ ਹੋਰ ਪਰਤ ਉੱਤੇ ਨਹੀਂ ਹਨ।" + +#: ../../po/../src/selection-chemistry.cpp:1160 +msgid "Select object(s) to move to the layer below." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1178 +msgid "No more layers below." +msgstr "ਕੋਈ ਹੋਰ ਪਰਤਾਂ ਹੇਠਾਂ ਨਹੀਂ ਹਨ।" + +#: ../../po/../src/selection-chemistry.cpp:1811 +msgid "Select a clone to unlink." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1842 +msgid "No clones to unlink in the selection." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1859 +msgid "" +"Select a clone to go to its original. Select a linked offset " +"to go to its source. Select a text on path to go to the path. Select " +"a flowed text to go to its frame." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1882 +msgid "" +"Cannot find the object to select (orphaned clone, offset, textpath, " +"flowed text?)" +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1888 +msgid "" +"The object you're trying to select is not visible (it is in <" +"defs>)" +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1915 +msgid "Select object(s) to convert to pattern." +msgstr "ਤਰਤੀਬ ਵਿੱਚ ਤਬਦੀਲ ਕਰਨ ਲਈ ਇਕਾਈ ਚੁਣੋ।" + +#: ../../po/../src/selection-chemistry.cpp:2006 +msgid "Select an object with pattern fill to extract objects from." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:2059 +msgid "No pattern fills in the selection." +msgstr "ਚੋਣ ਵਿੱਚ ਕੋਈ ਤਰਤੀਬ ਭਰਨ ਨਹੀਂ ਹੈ।" + +#: ../../po/../src/selection-chemistry.cpp:2079 +msgid "Select object(s) to make a bitmap copy." +msgstr "" + +#: ../../po/../src/selection-describer.cpp:37 +msgid "Click selection to toggle scale/rotation handles" +msgstr "" + +#. no items +#: ../../po/../src/selection-describer.cpp:39 +msgid "" +"No objects selected. Click, Shift+click, or drag around objects to select." +msgstr "" + +#: ../../po/../src/selection-describer.cpp:51 +#, c-format +msgid " in layer %s" +msgstr " ਪਰਤ %s ਵਿੱਚ" + +#: ../../po/../src/selection-describer.cpp:54 +#, c-format +msgid " in layer %s" +msgstr " ਪਰਤ %s ਵਿੱਚ" + +#: ../../po/../src/selection-describer.cpp:66 +msgid "Use Shift+D to look up original" +msgstr "" + +#: ../../po/../src/selection-describer.cpp:70 +msgid "Use Shift+D to look up path" +msgstr "" + +#: ../../po/../src/selection-describer.cpp:74 +msgid "Use Shift+D to look up frame" +msgstr "" + +#: ../../po/../src/selection-describer.cpp:84 +#, c-format +msgid "%i object selected" +msgid_plural "%i objects selected" +msgstr[0] "%i ਇਕਾਈ ਚੁਣੀ" +msgstr[1] "%i ਇਕਾਈਆਂ ਚੁਣੀਆਂ" + +#: ../../po/../src/selection-describer.cpp:90 +#, c-format +msgid "%s%s. %s." +msgstr "%s%s. %s." + +#: ../../po/../src/selection-describer.cpp:94 +#, c-format +msgid "%s in %i layer. %s." +msgid_plural "%s in %i layers. %s." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/seltrans.cpp:498 +msgid "" +"Center of rotation and skewing: drag to reposition; scaling with " +"Shift also uses this center" +msgstr "" + +#: ../../po/../src/seltrans.cpp:514 +msgid "" +"Squeeze or stretch selection; with Ctrl to scale uniformly; " +"with Shift to scale around rotation center" +msgstr "" + +#: ../../po/../src/seltrans.cpp:515 +msgid "" +"Scale selection; with Ctrl to scale uniformly; with Shift to scale around rotation center" +msgstr "" + +#: ../../po/../src/seltrans.cpp:519 +msgid "" +"Skew selection; with Ctrl to snap angle; with Shift to " +"skew around the opposite side" +msgstr "" + +#: ../../po/../src/seltrans.cpp:520 +msgid "" +"Rotate selection; with Ctrl to snap angle; with Shift " +"to rotate around the opposite corner" +msgstr "" + +#: ../../po/../src/seltrans.cpp:829 ../../po/../src/seltrans.cpp:909 +#, c-format +msgid "Scale: %0.2f%% x %0.2f%%; with Ctrl to lock ratio" +msgstr "" + +#. TRANSLATORS: don't modify the first ";" (it will NOT be displayed as ";" - only the second one will be) +#: ../../po/../src/seltrans.cpp:984 +#, c-format +msgid "Skew: %0.2f°; with Ctrl to snap angle" +msgstr "" + +#. TRANSLATORS: don't modify the first ";" (it will NOT be displayed as ";" - only the second one will be) +#: ../../po/../src/seltrans.cpp:1035 +#, c-format +msgid "Rotate: %0.2f°; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/seltrans.cpp:1090 +#, c-format +msgid "Move center to %s, %s" +msgstr "" + +#: ../../po/../src/slideshow.cpp:90 +msgid "Inkscape slideshow" +msgstr "ਇੰਕਸਕੇਪੀ ਸਲਾਇਡ-ਸ਼ੋ" + +#: ../../po/../src/sp-anchor.cpp:181 +#, c-format +msgid "Link to %s" +msgstr "%s ਨਾਲ ਸਬੰਧ" + +#: ../../po/../src/sp-anchor.cpp:185 +msgid "Link without URI" +msgstr "" + +#: ../../po/../src/sp-ellipse.cpp:438 ../../po/../src/sp-ellipse.cpp:870 +msgid "Ellipse" +msgstr "ਅੰਡਾਕਾਰ" + +#: ../../po/../src/sp-ellipse.cpp:583 +msgid "Circle" +msgstr "ਚੱਕਰ" + +#: ../../po/../src/sp-ellipse.cpp:865 +msgid "Segment" +msgstr "ਖੰਡ" + +#: ../../po/../src/sp-ellipse.cpp:867 +msgid "Arc" +msgstr "ਚਾਪ" + +#. TRANSLATORS: "Flow region" is an area where text is allowed to flow +#: ../../po/../src/sp-flowregion.cpp:276 +msgid "Flow region" +msgstr "ਵਹਾ ਖੇਤਰ" + +#. TRANSLATORS: A region "cut out of" a flow region; text is not allowed to flow inside the +#. * flow excluded region. flowRegionExclude in SVG 1.2: see +#. * http://www.w3.org/TR/2004/WD-SVG12-20041027/flow.html#flowRegion-elem and +#. * http://www.w3.org/TR/2004/WD-SVG12-20041027/flow.html#flowRegionExclude-elem. +#: ../../po/../src/sp-flowregion.cpp:493 +msgid "Flow excluded region" +msgstr "" + +#: ../../po/../src/sp-flowtext.cpp:355 +#, c-format +msgid "Flowed text (%d characters)" +msgstr "" + +#: ../../po/../src/sp-flowtext.cpp:357 +#, c-format +msgid "Linked flowed text (%d characters)" +msgstr "" + +#: ../../po/../src/sp-guide.cpp:290 +msgid "vertical guideline" +msgstr "ਲੰਬਕਾਰੀ ਖਿਤਿਜੀ" + +#: ../../po/../src/sp-guide.cpp:292 +msgid "horizontal guideline" +msgstr "ਖਿਤਿਜੀ ਗਾਈਡ" + +#: ../../po/../src/sp-image.cpp:835 +msgid "embedded" +msgstr "ਸ਼ਾਮਲ" + +#: ../../po/../src/sp-image.cpp:839 +msgid "(null_pointer)" +msgstr "(null_pointer)" + +#: ../../po/../src/sp-image.cpp:843 +#, c-format +msgid "Image with bad reference: %s" +msgstr "" + +#: ../../po/../src/sp-image.cpp:844 +#, c-format +msgid "Image %d × %d: %s" +msgstr "ਚਿੱਤਰ %d × %d: %s" + +#: ../../po/../src/sp-item-group.cpp:390 +#, c-format +msgid "Group of %d object" +msgid_plural "Group of %d objects" +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/sp-item.cpp:720 +msgid "Object" +msgstr "ਇਕਾਈ" + +#: ../../po/../src/sp-line.cpp:202 +msgid "Line" +msgstr "ਰੇਖਾ" + +#. TRANSLATORS COMMENT: %s is either "outset" or "inset" depending on sign +#: ../../po/../src/sp-offset.cpp:433 +#, c-format +msgid "Linked offset, %s by %f pt" +msgstr "" + +#: ../../po/../src/sp-offset.cpp:434 ../../po/../src/sp-offset.cpp:438 +msgid "outset" +msgstr "" + +#: ../../po/../src/sp-offset.cpp:434 ../../po/../src/sp-offset.cpp:438 +msgid "inset" +msgstr "" + +#. TRANSLATORS COMMENT: %s is either "outset" or "inset" depending on sign +#: ../../po/../src/sp-offset.cpp:437 +#, c-format +msgid "Dynamic offset, %s by %f pt" +msgstr "" + +#: ../../po/../src/sp-path.cpp:127 +#, c-format +msgid "Path (%i node)" +msgid_plural "Path (%i nodes)" +msgstr[0] "ਮਾਰਗ (%i ਨੋਡ)" +msgstr[1] "ਮਾਰਗ (%i ਨੋਡਾਂ)" + +#: ../../po/../src/sp-polygon.cpp:216 +msgid "Polygon" +msgstr "ਬਹੁਭੁਜ" + +#: ../../po/../src/sp-polyline.cpp:179 +msgid "Polyline" +msgstr "ਬਹੁ-ਰੇਖਾ" + +#: ../../po/../src/sp-rect.cpp:250 +msgid "Rectangle" +msgstr "ਚਤੁਰਭੁਜ" + +#. TRANSLATORS: since turn count isn't an integer, please adjust the +#. string as needed to deal with an localized plural forms. +#: ../../po/../src/sp-spiral.cpp:305 +#, c-format +msgid "Spiral with %3f turns" +msgstr "" + +#: ../../po/../src/sp-star.cpp:288 +#, c-format +msgid "Star with %d vertex" +msgid_plural "Star with %d vertices" +msgstr[0] "ਤਾਰਾ %d ਭੁਜਾ ਵਾਲਾ" +msgstr[1] "ਤਾਰਾ %d ਭੁਜਾਵਾਂ ਵਾਲਾ" + +#: ../../po/../src/sp-star.cpp:292 +#, c-format +msgid "Polygon with %d vertex" +msgid_plural "Polygon with %d vertices" +msgstr[0] "ਬਹੁਭੁਜ %d ਭੁਜਾ ਵਾਲੀ" +msgstr[1] "ਬਹੁਭੁਜ %d ਭੁਜਾਵਾਂ ਵਾਲੀ" + +#. TRANSLATORS: For description of font with no name. +#: ../../po/../src/sp-text.cpp:420 +msgid "<no name found>" +msgstr "<ਕੋਈ ਨਾਂ ਨਹੀਂ ਲੱਭਿਆ>" + +#: ../../po/../src/sp-text.cpp:426 +#, c-format +msgid "Text on path (%s, %s)" +msgstr "ਮਾਰਗ ਉੱਥੇ ਪਾਠ (%s, %s)" + +#: ../../po/../src/sp-text.cpp:427 +#, c-format +msgid "Text (%s, %s)" +msgstr "ਪਾਠ (%s, %s)" + +#. TRANSLATORS: Used for statusbar description for long chains: +#. * "Clone of: Clone of: ... in Layer 1". +#: ../../po/../src/sp-use.cpp:317 +msgid "..." +msgstr "..." + +#: ../../po/../src/sp-use.cpp:325 +#, c-format +msgid "Clone of: %s" +msgstr "" + +#: ../../po/../src/sp-use.cpp:329 +msgid "Orphaned clone" +msgstr "" + +#: ../../po/../src/spiral-context.cpp:355 +msgid "Ctrl: snap angle" +msgstr "" + +#: ../../po/../src/spiral-context.cpp:357 +msgid "Alt: lock spiral radius" +msgstr "" + +#: ../../po/../src/spiral-context.cpp:469 +#, c-format +msgid "" +"Spiral: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/splivarot.cpp:106 +msgid "Select at least 2 paths to perform a boolean operation." +msgstr "" + +#: ../../po/../src/splivarot.cpp:112 +msgid "" +"Select exactly 2 paths to perform difference, XOR, division, or path " +"cut." +msgstr "" + +#: ../../po/../src/splivarot.cpp:129 ../../po/../src/splivarot.cpp:144 +msgid "" +"Unable to determine the z-order of the objects selected for " +"difference, XOR, division, or path cut." +msgstr "" + +#: ../../po/../src/splivarot.cpp:174 +msgid "" +"One of the objects is not a path, cannot perform boolean operation." +msgstr "" + +#. TRANSLATORS: "to outline" means "to convert stroke to path" +#: ../../po/../src/splivarot.cpp:554 +msgid "Select path(s) to outline." +msgstr "" + +#. TRANSLATORS: "to outline" means "to convert stroke to path" +#: ../../po/../src/splivarot.cpp:748 +msgid "No stroked paths to outline in the selection." +msgstr "" + +#: ../../po/../src/splivarot.cpp:832 +msgid "Selected object is not a path, cannot inset/outset." +msgstr "" + +#: ../../po/../src/splivarot.cpp:1040 +msgid "Select path(s) to inset/outset." +msgstr "" + +#: ../../po/../src/splivarot.cpp:1257 +msgid "No paths to inset/outset in the selection." +msgstr "" + +#: ../../po/../src/splivarot.cpp:1390 +msgid "Select path(s) to simplify." +msgstr "" + +#: ../../po/../src/splivarot.cpp:1417 +msgid "No paths to simplify in the selection." +msgstr "" + +#: ../../po/../src/star-context.cpp:362 +msgid "Ctrl: snap angle; keep rays radial" +msgstr "" + +#: ../../po/../src/star-context.cpp:470 +#, c-format +msgid "" +"Polygon: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/star-context.cpp:471 +#, c-format +msgid "Star: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/text-chemistry.cpp:90 +msgid "Select a text and a path to put text on path." +msgstr "" + +#: ../../po/../src/text-chemistry.cpp:95 +msgid "" +"This text object is already put to a path. Remove it from the path " +"first. Use Shift+D to look up its path." +msgstr "" + +#. rect is the only SPShape which is not yet, and thus SVG forbids us from putting text on it +#: ../../po/../src/text-chemistry.cpp:101 +msgid "" +"You cannot put text on a rectangle in this version. Convert rectangle to " +"path first." +msgstr "" + +#: ../../po/../src/text-chemistry.cpp:159 +msgid "Select a text on path to remove it from path." +msgstr "" + +#: ../../po/../src/text-chemistry.cpp:181 +msgid "No texts-on-paths in the selection." +msgstr "" + +#: ../../po/../src/text-chemistry.cpp:209 +#: ../../po/../src/text-chemistry.cpp:229 +msgid "Select text(s) to remove kerns from." +msgstr "" + +#: ../../po/../src/text-chemistry.cpp:250 +msgid "" +"Select a text and one or more paths or shapes to flow text " +"into frame." +msgstr "" + +#: ../../po/../src/text-chemistry.cpp:322 +msgid "Select a flowed text to unflow it." +msgstr "" + +#: ../../po/../src/text-context.cpp:463 +msgid "Click to edit the text, drag to select part of the text." +msgstr "" + +#: ../../po/../src/text-context.cpp:465 +msgid "" +"Click to edit the flowed text, drag to select part of the text." +msgstr "" + +#: ../../po/../src/text-context.cpp:540 +msgid "Non-printable character" +msgstr "ਕੋਈ-ਛਪਣਯੋਗ ਅੱਖਰ" + +#: ../../po/../src/text-context.cpp:589 +#, c-format +msgid "Unicode: %s: %s" +msgstr "ਯੂਨੀਕੋਡ: %s: %s" + +#: ../../po/../src/text-context.cpp:591 ../../po/../src/text-context.cpp:855 +msgid "Unicode: " +msgstr "ਯੂਨੀਕੋਡ: " + +#: ../../po/../src/text-context.cpp:615 +msgid "Current layer is hidden. Unhide it to be able to add text." +msgstr "" + +#: ../../po/../src/text-context.cpp:619 +msgid "Current layer is locked. Unlock it to be able to add text." +msgstr "" + +#: ../../po/../src/text-context.cpp:673 +#, c-format +msgid "Flowed text frame: %s × %s" +msgstr "" + +#: ../../po/../src/text-context.cpp:708 ../../po/../src/text-context.cpp:1464 +msgid "Type text; Enter to start new line." +msgstr "ਪਾਠ ਲਿਖੋ, ਨਵੀਂ ਰੇਖਾ ਸ਼ੁਰੂ ਕਰਨ ਲਈ Enter ਦਬਾਓ।" + +#: ../../po/../src/text-context.cpp:719 +msgid "Flowed text is created." +msgstr "" + +#: ../../po/../src/text-context.cpp:722 +msgid "" +"The frame is too small for the current font size. Flowed text not " +"created." +msgstr "" + +#: ../../po/../src/text-context.cpp:841 +msgid "No-break space" +msgstr "" + +#: ../../po/../src/text-context.cpp:1462 +msgid "Type flowed text; Enter to start new paragraph." +msgstr "" + +#: ../../po/../src/text-context.cpp:1472 ../../po/../src/tools-switch.cpp:189 +msgid "" +"Click to select or create text, drag to create flowed text; " +"then type." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:141 +msgid "" +"To edit a path, click, Shift+click, or drag around " +"nodes to select them, then drag nodes and handles. Click on an " +"object to select." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:147 +msgid "" +"Drag to create a rectangle. Drag controls to round corners and " +"resize. Click to select." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:153 +msgid "" +"Drag to create an ellipse. Drag controls to make an arc or " +"segment. Click to select." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:159 +msgid "" +"Drag to create a star. Drag controls to edit the star shape. " +"Click to select." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:165 +msgid "" +"Drag to create a spiral. Drag controls to edit the spiral " +"shape. Click to select." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:171 +msgid "" +"Drag to create a freehand line. Start drawing with Shift to " +"append to selected path." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:177 +msgid "" +"Click or click and drag to start a path; with Shift to " +"append to selected path." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:183 +msgid "" +"Drag to paint a calligraphic stroke. Left/right arrow " +"keys adjust width, up/down adjust angle." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:195 +msgid "" +"Drag or double click to create a gradient on selected objects, " +"drag handles to adjust gradients." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:201 +msgid "" +"Click or drag around an area to zoom in, Shift+click to " +"zoom out." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:213 +msgid "Click and drag between shapes to create a connector." +msgstr "" + +#: ../../po/../src/trace/potrace/inkscape-potrace.cpp:553 +#: ../../po/../src/trace/potrace/inkscape-potrace.cpp:654 +#, c-format +msgid "Trace: %d. %ld nodes" +msgstr "ਜਾਂਚ: %d. %ld ਨੋਡਾਂ" + +#: ../../po/../src/trace/trace.cpp:53 ../../po/../src/trace/trace.cpp:62 +#: ../../po/../src/trace/trace.cpp:70 +msgid "Select an image to trace" +msgstr "ਜਾਂਚ ਲਈ ਇੱਕ ਚਿੱਤਰ ਚੁਣੋ" + +#: ../../po/../src/trace/trace.cpp:133 +msgid "Trace: No active document" +msgstr "ਜਾਂਚ: ਕੋਈ ਸਰਗਰਮ ਦਸਤਾਵੇਜ਼ ਨਹੀਂ" + +#: ../../po/../src/trace/trace.cpp:154 +msgid "Trace: Image has no bitmap data" +msgstr "ਜਾਂਚ: ਚਿੱਤਰ 'ਚ ਕੋਈ ਬਿੱਟਮੈਪ ਡਾਟਾ ਨਹੀਂ ਹੈ" + +#: ../../po/../src/trace/trace.cpp:267 +#, c-format +msgid "Trace: Done. %ld nodes created" +msgstr "ਜਾਂਚ: ਮੁਕੰਮਲ ਹੋਈ। %ld ਨੋਡਾਂ ਬਣਾਈਆਂ" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:59 ../../po/../src/verbs.cpp:2212 +msgid "About Inkscape" +msgstr "ਇੰਕਸਕੇਪੀ ਬਾਰੇ" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:66 +msgid "_Splash" +msgstr "" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:68 +msgid "_Authors" +msgstr "" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:69 +#, fuzzy +msgid "_Translators" +msgstr "ਤਬਦੀਲ" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:70 +#, fuzzy +msgid "_License" +msgstr "ਲਾਈਸੈਂਸ" + +#. TRANSLATORS: This is the filename of the `About Inkscape' picture in +#. the `screens' directory. Thus the translation of "about.svg" should be +#. the filename of its translated version, e.g. about.zh.svg for Chinese. +#. +#. N.B. about.svg changes once per release. (We should probably rename +#. the original to about-0.40.svg etc. as soon as we have a translation. +#. If we do so, then add an item to release-checklist saying that the +#. string here should be changed.) +#. FIXME? INKSCAPE_SCREENSDIR and "about.svg" are in UTF-8, not the +#. native filename encoding... and the filename passed to sp_document_new +#. should be in UTF-*8.. +#: ../../po/../src/ui/dialog/aboutbox.cpp:114 +msgid "about.svg" +msgstr "about.svg" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:464 +msgid "Minimum horizontal gap (in px units) between bounding boxes" +msgstr "" + +#. TRANSLATORS: Horizontal gap +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:466 +#: ../../po/../src/widgets/toolbox.cpp:1556 +msgid "H:" +msgstr "ਉ:" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:474 +msgid "Minimum vertical gap (in px units) between bounding boxes" +msgstr "" + +#. TRANSLATORS: Vertical gap +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:476 +msgid "V:" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:734 +msgid "Align" +msgstr "ਇਕਸਾਰ" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:735 +msgid "Distribute" +msgstr "ਵੰਡ" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:736 +msgid "Remove overlaps" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:737 +msgid "Nodes" +msgstr "ਨੋਡਾਂ" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:742 +msgid "Relative to: " +msgstr "ਅਨੁਸਾਰੀ: " + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:747 +msgid "Align right sides of objects to left side of anchor" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:750 +msgid "Align left sides" +msgstr "ਖੱਬੇ ਪਾਸੇ ਇਕਸਾਰ" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:753 +msgid "Center on vertical axis" +msgstr "ਖਿਤਿਜੀ ਧੁਰੇ ਉੱਤੇ ਕੇਂਦਰ" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:756 +msgid "Align right sides" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:759 +msgid "Align left sides of objects to right side of anchor" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:762 +msgid "Align bottoms of objects to top of anchor" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:765 +msgid "Align tops" +msgstr "ਉੱਤੇ ਇਕਸਾਰ" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:768 +msgid "Center on horizontal axis" +msgstr "ਖਿਤਿਜੀ ਧੁਰੇ ਉੱਤੇ ਕੇਂਦਰ" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:771 +msgid "Align bottoms" +msgstr "ਤਲ ਇਕਸਾਰ" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:774 +msgid "Align tops of objects to bottom of anchor" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:779 +msgid "Align baseline anchors of texts vertically" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:782 +msgid "Align baseline anchors of texts horizontally" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:787 +msgid "Make horizontal gaps between objects equal" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:791 +msgid "Distribute left sides equidistantly" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:794 +msgid "Distribute centers equidistantly horizontally" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:797 +msgid "Distribute right sides equidistantly" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:801 +msgid "Make vertical gaps between objects equal" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:805 +msgid "Distribute tops equidistantly" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:808 +msgid "Distribute centers equidistantly vertically" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:811 +msgid "Distribute bottoms equidistantly" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:816 +msgid "Distribute baseline anchors of texts horizontally" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:819 +msgid "Distribute baseline anchors of texts vertically" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:824 +msgid "Randomize centers in both dimensions" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:827 +msgid "Unclump objects: try to equalize edge-to-edge distances" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:832 +msgid "" +"Move objects as little as possible so that their bounding boxes do not " +"overlap" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:837 +msgid "Align selected nodes horizontally" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:840 +msgid "Align selected nodes vertically" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:843 +msgid "Distribute selected nodes horizontally" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:846 +msgid "Distribute selected nodes vertically" +msgstr "" + +#. Rest of the widgetry +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:851 +msgid "Last selected" +msgstr "ਆਖਰੀ ਚੁਣੀ" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:852 +msgid "First selected" +msgstr "ਪਹਿਲਾਂ ਚੁਣੀ" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:853 +msgid "Biggest item" +msgstr "ਸਭ ਤੋਂ ਵੱਡੀ ਇਕਾਈ" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:854 +msgid "Smallest item" +msgstr "ਸਭ ਤੋਂ ਛੋਟੀ ਇਕਾਈ" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:856 +#: ../../po/../src/widgets/desktop-widget.cpp:1065 +msgid "Drawing" +msgstr "ਡਰਾਇੰਗ" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:91 +#, fuzzy +msgid "Metadata 1" +msgstr "ਮੈਟਾਡਾਟਾ" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:92 +#, fuzzy +msgid "Metadata 2" +msgstr "ਮੈਟਾਡਾਟਾ" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:187 +#, fuzzy +msgid "X coordinate of grid origin" +msgstr "ਚੋਣ ਦਾ ਲੰਬਕਾਰੀ ਧੁਰਾ" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:189 +#, fuzzy +msgid "Y coordinate of grid origin" +msgstr "ਚੋਣ ਦਾ ਲੰਬਕਾਰੀ ਧੁਰਾ" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:191 +#, fuzzy +msgid "Distance of vertical grid lines" +msgstr "ਲੰਬਕਾਰੀ ਖਿਤਿਜੀ" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:193 +#, fuzzy +msgid "Distance of horizontal grid lines" +msgstr "ਖਿਤਿਜੀ ਗਾਈਡ" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:197 +msgid "Max. snapping distance from grid" +msgstr "" + +#: ../../po/../src/ui/dialog/export.cpp:34 +msgid "Export" +msgstr "ਨਿਰਯਾਤ" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:36 +msgid "Fill" +msgstr "ਭਰੋ" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:37 +msgid "Stroke Paint" +msgstr "ਛੋਹ ਪੇਂਟ" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:38 +msgid "Stroke Style" +msgstr "ਛੋਹ ਸ਼ੈਲੀ" + +#: ../../po/../src/ui/dialog/find.cpp:34 +msgid "Find" +msgstr "ਖੋਜ" + +#: ../../po/../src/ui/dialog/memory.cpp:96 +msgid "Heap" +msgstr "ਭੰਡਾਰ" + +#: ../../po/../src/ui/dialog/memory.cpp:97 +msgid "In Use" +msgstr "ਵਰਤੋਂ ਅਧੀਨ" + +#. TRANSLATORS: "Slack" refers to memory which is in the heap but currently unused. +#. More typical usage is to call this memory "free" rather than "slack". +#: ../../po/../src/ui/dialog/memory.cpp:100 +msgid "Slack" +msgstr "" + +#: ../../po/../src/ui/dialog/memory.cpp:101 +msgid "Total" +msgstr "ਕੁੱਲ" + +#: ../../po/../src/ui/dialog/memory.cpp:141 +#: ../../po/../src/ui/dialog/memory.cpp:147 +#: ../../po/../src/ui/dialog/memory.cpp:154 +#: ../../po/../src/ui/dialog/memory.cpp:186 +msgid "Unknown" +msgstr "ਅਣਜਾਣ" + +#: ../../po/../src/ui/dialog/memory.cpp:167 +msgid "Combined" +msgstr "ਜੁੜਿਆ" + +#: ../../po/../src/ui/dialog/memory.cpp:209 +msgid "Recalculate" +msgstr "ਮੁੜ-ਗਣਨਾ" + +#: ../../po/../src/ui/dialog/messages.cpp:74 +msgid "Ready." +msgstr "ਤਿਆਰ ਹੈ।" + +#: ../../po/../src/ui/dialog/messages.cpp:75 +msgid "" +"Enable log display by setting dialogs.debug 'redirect' attribute to 1 in " +"preferences.xml" +msgstr "" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:184 +msgid "_Execute Python" +msgstr "ਪਾਈਥਨ ਚਲਾਓ(_E)" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:186 +msgid "_Execute Perl" +msgstr "ਪਰਲ ਚਲਾਓ(_E)" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:195 +msgid "Script" +msgstr "ਸਕਰਿਪਟ" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:205 +msgid "Output" +msgstr "ਆਉਟਪੁੱਟ" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:215 +msgid "Errors" +msgstr "ਗਲਤੀਆਂ" + +#. Dialog organization +#: ../../po/../src/ui/dialog/session-player.cpp:73 +#, fuzzy +msgid "Session file" +msgstr "ਅਜਲਾਸ ਫਾਇਲ ਖੋਲੋ" + +#: ../../po/../src/ui/dialog/session-player.cpp:74 +#, fuzzy +msgid "Playback controls" +msgstr "ਸੰਦ ਕੰਟਰੋਲ" + +#: ../../po/../src/ui/dialog/session-player.cpp:75 +#, fuzzy +msgid "Message information" +msgstr "ਤਬਦੀਲੀਆਂ ਹਟਾਓ(_T)" + +#. Active session file display +#. fixme: Does this mean the active file for the session, or the file for the active session? +#. Please indicate which with a TRANSLATORS comment. +#: ../../po/../src/ui/dialog/session-player.cpp:85 +#, fuzzy +msgid "Active session file:" +msgstr "ਅਜਲਾਸ ਫਾਇਲ ਖੋਲੋ" + +#: ../../po/../src/ui/dialog/session-player.cpp:86 +msgid "Delay (milliseconds):" +msgstr "" + +#. Unload/load buttons +#: ../../po/../src/ui/dialog/session-player.cpp:94 +#, fuzzy +msgid "Close file" +msgstr "ਬੰਦ ਕਰੋ" + +#: ../../po/../src/ui/dialog/session-player.cpp:95 +#, fuzzy +msgid "Open new file" +msgstr "ਅਜਲਾਸ ਫਾਇਲ ਖੋਲੋ" + +#: ../../po/../src/ui/dialog/session-player.cpp:96 +#, fuzzy +msgid "Set delay" +msgstr "ਮੂਲ ਬਣਾਓ" + +#: ../../po/../src/ui/dialog/session-player.cpp:138 +#, fuzzy +msgid "Rewind" +msgstr "ਲਾਲ" + +#: ../../po/../src/ui/dialog/session-player.cpp:139 +msgid "Go back one change" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:140 +#, fuzzy +msgid "Pause" +msgstr "ਚੇਪੋ(_P)" + +#: ../../po/../src/ui/dialog/session-player.cpp:141 +msgid "Go forward one change" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:142 +msgid "Play" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:177 +#: ../../po/../src/verbs.cpp:1573 +msgid "Open session file" +msgstr "ਅਜਲਾਸ ਫਾਇਲ ਖੋਲੋ" + +#. ##Set up the Potrace panel +#. #### brightness #### +#. #### Multiple scanning#### +#. ----Hbox1 +#: ../../po/../src/ui/dialog/tracedialog.cpp:345 +#: ../../po/../src/ui/dialog/tracedialog.cpp:428 +msgid "Brightness" +msgstr "ਚਮਕ" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:348 +msgid "Trace by a given brightness level" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:355 +msgid "Brightness cutoff for black/white" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:362 +msgid "Image Brightness" +msgstr "ਚਿੱਤਰ ਚਮਕ" + +#. #### canny edge detection #### +#. TRANSLATORS: "Canny" is the name of the inventor of this edge detection method +#: ../../po/../src/ui/dialog/tracedialog.cpp:369 +msgid "Optimal Edge Detection (Canny)" +msgstr "ਅਨੁਕੂਲ ਕੰਢਾ ਖੋਜ (ਕੈਨੀ)" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:372 +msgid "Trace with edge detection by J. Canny's algorithm" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:388 +msgid "Brightness cutoff for adjacent pixels (determines edge thickness)" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:395 +msgid "Edge Detection" +msgstr "ਕੰਢਾ ਖੋਜ" + +#. #### quantization #### +#. TRANSLATORS: Color Quantization: the process of reducing the number of colors +#. in an image by selecting an optimized set of representative colors and then +#. re-applying this reduced set to the original image. +#: ../../po/../src/ui/dialog/tracedialog.cpp:404 +msgid "Color Quantization" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:407 +msgid "Trace along the boundaries of reduced colors" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:414 +msgid "The number of reduced colors" +msgstr "ਘਟਾਏ ਰੰਗਾਂ ਦੀ ਗਿਣਤੀ" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:416 +msgid "Colors:" +msgstr "ਰੰਗ:" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:421 +msgid "Quantization / Reduction" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:431 +msgid "Trace the given number of brightness levels" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:438 +msgid "Scans:" +msgstr "ਸਕੈਨ:" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:440 +msgid "The desired number of scans" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:448 +msgid "Trace the given number of reduced colors" +msgstr "" + +#. ---Hbox3 +#: ../../po/../src/ui/dialog/tracedialog.cpp:454 +msgid "Monochrome" +msgstr "ਇਕਹੇਰਾ ਰੰਗ" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:457 +msgid "Same as Color, but convert result to grayscale" +msgstr "" + +#. TRANSLATORS: "Stack" is a verb here +#: ../../po/../src/ui/dialog/tracedialog.cpp:460 +msgid "Stack" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:463 +msgid "" +"Stack scans vertically (no gaps) or tile horizontally (usually with gaps)" +msgstr "" + +#. TRANSLATORS: "Smooth" is a verb here +#: ../../po/../src/ui/dialog/tracedialog.cpp:466 +msgid "Smooth" +msgstr "ਮੁਲਾਇਮ" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:469 +msgid "Apply Gaussian blur to the bitmap before tracing" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:473 +msgid "Multiple Scanning" +msgstr "" + +#. #### Preview #### +#: ../../po/../src/ui/dialog/tracedialog.cpp:479 +#: ../../po/../src/ui/dialog/tracedialog.cpp:489 +msgid "Preview" +msgstr "ਝਲਕ" + +#. do not expand +#: ../../po/../src/ui/dialog/tracedialog.cpp:483 +msgid "Preview the result without actual tracing" +msgstr "" + +#. #### swap black and white #### +#: ../../po/../src/ui/dialog/tracedialog.cpp:495 +msgid "Invert" +msgstr "ਉਲਟ" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:499 +msgid "Invert black and white regions for single traces" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:503 +msgid "Thanks to Peter Selinger, http://potrace.sourceforge.net" +msgstr "ਪੀਟਰ ਸੀਲਿੰਗਰ ਦਾ ਧੰਨਵਾਦ ਹੈ, http://potrace.sourceforge.net" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:506 +msgid "Credits" +msgstr "ਮਾਣ" + +#. done +#. TRANSLATORS: Potrace is an application for transforming bitmaps into +#. vector graphics (http://potrace.sourceforge.net/) +#: ../../po/../src/ui/dialog/tracedialog.cpp:514 +msgid "Potrace" +msgstr "ਪੋਰਟਰੇਟ" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:527 +msgid "Abort a trace in progress" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:531 +msgid "Execute the trace" +msgstr "ਟਰੇਸ ਚਲਾਓ" + +#: ../../po/../src/ui/dialog/transformation.cpp:80 +#: ../../po/../src/ui/dialog/transformation.cpp:90 +#, fuzzy +msgid "_Horizontal" +msgstr "ਖਿਤਿਜੀ" + +#: ../../po/../src/ui/dialog/transformation.cpp:80 +msgid "Horizontal displacement (relative) or position (absolute)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:82 +#: ../../po/../src/ui/dialog/transformation.cpp:92 +#, fuzzy +msgid "_Vertical" +msgstr "ਲੰਬਕਾਰੀ" + +#: ../../po/../src/ui/dialog/transformation.cpp:82 +msgid "Vertical displacement (relative) or position (absolute)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:84 +#, fuzzy +msgid "_Width" +msgstr "ਚੌੜਾਈ(_W):" + +#: ../../po/../src/ui/dialog/transformation.cpp:84 +msgid "Horizontal size increment (absolute or percentage)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:86 +#, fuzzy +msgid "_Height" +msgstr "ਉਚਾਈ" + +#: ../../po/../src/ui/dialog/transformation.cpp:86 +msgid "Vertical size increment (absolute or percentage)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:88 +#, fuzzy +msgid "A_ngle" +msgstr "ਕੋਣ:" + +#: ../../po/../src/ui/dialog/transformation.cpp:88 +msgid "Rotation angle (positive = counterclockwise)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:90 +msgid "" +"Horizontal skew angle (positive = counterclockwise), or absolute " +"displacement, or percentage displacement" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:92 +msgid "" +"Vertical skew angle (positive = counterclockwise), or absolute displacement, " +"or percentage displacement" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:95 +#, fuzzy +msgid "Transformation matrix element A" +msgstr "ਤਬਦੀਲੀ ਸਾਰਣੀ" + +#: ../../po/../src/ui/dialog/transformation.cpp:96 +#, fuzzy +msgid "Transformation matrix element B" +msgstr "ਤਬਦੀਲੀ ਸਾਰਣੀ" + +#: ../../po/../src/ui/dialog/transformation.cpp:97 +#, fuzzy +msgid "Transformation matrix element C" +msgstr "ਤਬਦੀਲੀ ਸਾਰਣੀ" + +#: ../../po/../src/ui/dialog/transformation.cpp:98 +#, fuzzy +msgid "Transformation matrix element D" +msgstr "ਤਬਦੀਲੀ ਸਾਰਣੀ" + +#: ../../po/../src/ui/dialog/transformation.cpp:99 +#, fuzzy +msgid "Transformation matrix element E" +msgstr "ਤਬਦੀਲੀ ਸਾਰਣੀ" + +#: ../../po/../src/ui/dialog/transformation.cpp:100 +#, fuzzy +msgid "Transformation matrix element F" +msgstr "ਤਬਦੀਲੀ ਸਾਰਣੀ" + +#: ../../po/../src/ui/dialog/transformation.cpp:102 +#, fuzzy +msgid "Rela_tive move" +msgstr "ਅਨੁਸਾਰੀ ਚਾਲ" + +#: ../../po/../src/ui/dialog/transformation.cpp:102 +msgid "" +"Add the specified relative displacement to the current position; otherwise, " +"edit the current absolute position directly" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:103 +msgid "Scale proportionally" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:103 +msgid "Preserve the width/height ratio of the scaled objects" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:104 +msgid "Apply to each _object separately" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:104 +msgid "" +"Apply the scale/rotate/skew to each selected object separately; otherwise, " +"transform the selection as a whole" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:105 +#, fuzzy +msgid "Edit c_urrent matrix" +msgstr "ਮੌਜੂਦਾ ਪਰਤ ਉਭਾਰੋ" + +#: ../../po/../src/ui/dialog/transformation.cpp:105 +msgid "" +"Edit the current transform= matrix; otherwise, post-multiply transform= by " +"this matrix" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:115 +#, fuzzy +msgid "_Move" +msgstr "ਭੇਜੋ" + +#: ../../po/../src/ui/dialog/transformation.cpp:118 +#, fuzzy +msgid "_Scale" +msgstr "ਮਾਪ-ਜਾਂਚ" + +#: ../../po/../src/ui/dialog/transformation.cpp:121 +#, fuzzy +msgid "_Rotate" +msgstr "ਘੁੰਮਾਓ" + +#: ../../po/../src/ui/dialog/transformation.cpp:124 +#, fuzzy +msgid "Ske_w" +msgstr "ਤਿਰਛਾ" + +#: ../../po/../src/ui/dialog/transformation.cpp:127 +msgid "Matri_x" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:141 +msgid "Reset the values on the current tab to defaults" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:148 +#, fuzzy +msgid "Apply transformation to selection" +msgstr "ਇਕਾਈ ਲਈ ਤਬਦੀਲੀ ਲਾਗੂ" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:43 +msgid "_Use SSL" +msgstr "" + +#. Construct dialog interface +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:68 +#, fuzzy +msgid "_Server:" +msgstr "ਉਲਟ(_R)" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:69 +#, fuzzy +msgid "_Username:" +msgstr "ਨਾਂ-ਤਬਦੀਲ(_R)" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:70 +msgid "_Password:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:71 +msgid "P_ort:" +msgstr "" + +#. Buttons +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:99 +#, fuzzy +msgid "Connect" +msgstr "ਸਮਰੂਪ" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:126 +msgid "Establishing connection to Jabber server %1 as user %2" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:131 +msgid "Failed to establish connection to Jabber server %1" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:136 +msgid "Authentication failed on Jabber server %1 as %2" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:141 +msgid "SSL initialization failed when connecting to Jabber server %1" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:147 +#, fuzzy +msgid "Connected to Jabber server %1 as %2" +msgstr "ਜੱਬਰ ਸਰਵਰ ਨਾਲ ਜੁੜੋ(_C)..." + +#. Construct labels +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:75 +#, fuzzy +msgid "Chatroom _name:" +msgstr "ਪਰਤ ਨਾਂ:" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:76 +msgid "Chatroom _server:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:77 +msgid "Chatroom _password:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:78 +msgid "Chatroom _handle:" +msgstr "" + +#. Button setup and callback registration +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:97 +msgid "Connect to chatroom" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:132 +msgid "Synchronizing with chatroom %1@%2 using the handle %3" +msgstr "" + +#. Construct dialog interface +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:78 +msgid "_User's Jabber ID:" +msgstr "" + +#. Buttons +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:82 +msgid "_Invite user" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:83 +#, fuzzy +msgid "_Cancel" +msgstr "ਰੱਦ ਕਰੋ" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:94 +msgid "Buddy List" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:170 +msgid "Sending whiteboard invitation to %1" +msgstr "" + +#. FIXME: strings are replaced by placeholders, NOT to be translated until the code is enabled +#. See http://sourceforge.net/mailarchive/message.php?msg_id=11746016 for details +#. File menu +#. Edit menu +#. View menu +#. Layer menu +#. Object menu +#. Path menu +#. add(Gtk::StockItem(CLEANUP, _("PLACEHOLDER, do not translate"))); (using Gtk::Stock::CLEAR) +#. Text menu +#. About menu +#. Tools toolbox +#. Select Tool controls +#. Node Tool controls +#. Calligraphy Tool controls +#. Session playback controls +#: ../../po/../src/ui/stock-items.cpp:34 ../../po/../src/ui/stock-items.cpp:35 +#: ../../po/../src/ui/stock-items.cpp:36 ../../po/../src/ui/stock-items.cpp:37 +#: ../../po/../src/ui/stock-items.cpp:38 ../../po/../src/ui/stock-items.cpp:39 +#: ../../po/../src/ui/stock-items.cpp:40 ../../po/../src/ui/stock-items.cpp:41 +#: ../../po/../src/ui/stock-items.cpp:42 ../../po/../src/ui/stock-items.cpp:43 +#: ../../po/../src/ui/stock-items.cpp:46 ../../po/../src/ui/stock-items.cpp:47 +#: ../../po/../src/ui/stock-items.cpp:48 ../../po/../src/ui/stock-items.cpp:49 +#: ../../po/../src/ui/stock-items.cpp:50 ../../po/../src/ui/stock-items.cpp:51 +#: ../../po/../src/ui/stock-items.cpp:52 ../../po/../src/ui/stock-items.cpp:53 +#: ../../po/../src/ui/stock-items.cpp:54 ../../po/../src/ui/stock-items.cpp:55 +#: ../../po/../src/ui/stock-items.cpp:56 ../../po/../src/ui/stock-items.cpp:57 +#: ../../po/../src/ui/stock-items.cpp:58 ../../po/../src/ui/stock-items.cpp:59 +#: ../../po/../src/ui/stock-items.cpp:62 ../../po/../src/ui/stock-items.cpp:63 +#: ../../po/../src/ui/stock-items.cpp:64 ../../po/../src/ui/stock-items.cpp:65 +#: ../../po/../src/ui/stock-items.cpp:66 ../../po/../src/ui/stock-items.cpp:67 +#: ../../po/../src/ui/stock-items.cpp:68 ../../po/../src/ui/stock-items.cpp:69 +#: ../../po/../src/ui/stock-items.cpp:70 ../../po/../src/ui/stock-items.cpp:71 +#: ../../po/../src/ui/stock-items.cpp:72 ../../po/../src/ui/stock-items.cpp:73 +#: ../../po/../src/ui/stock-items.cpp:74 ../../po/../src/ui/stock-items.cpp:75 +#: ../../po/../src/ui/stock-items.cpp:76 ../../po/../src/ui/stock-items.cpp:77 +#: ../../po/../src/ui/stock-items.cpp:78 ../../po/../src/ui/stock-items.cpp:79 +#: ../../po/../src/ui/stock-items.cpp:80 ../../po/../src/ui/stock-items.cpp:81 +#: ../../po/../src/ui/stock-items.cpp:82 ../../po/../src/ui/stock-items.cpp:83 +#: ../../po/../src/ui/stock-items.cpp:84 ../../po/../src/ui/stock-items.cpp:85 +#: ../../po/../src/ui/stock-items.cpp:86 ../../po/../src/ui/stock-items.cpp:87 +#: ../../po/../src/ui/stock-items.cpp:88 ../../po/../src/ui/stock-items.cpp:89 +#: ../../po/../src/ui/stock-items.cpp:92 ../../po/../src/ui/stock-items.cpp:93 +#: ../../po/../src/ui/stock-items.cpp:94 ../../po/../src/ui/stock-items.cpp:95 +#: ../../po/../src/ui/stock-items.cpp:96 ../../po/../src/ui/stock-items.cpp:97 +#: ../../po/../src/ui/stock-items.cpp:98 ../../po/../src/ui/stock-items.cpp:99 +#: ../../po/../src/ui/stock-items.cpp:100 +#: ../../po/../src/ui/stock-items.cpp:101 +#: ../../po/../src/ui/stock-items.cpp:102 +#: ../../po/../src/ui/stock-items.cpp:103 +#: ../../po/../src/ui/stock-items.cpp:104 +#: ../../po/../src/ui/stock-items.cpp:105 +#: ../../po/../src/ui/stock-items.cpp:108 +#: ../../po/../src/ui/stock-items.cpp:109 +#: ../../po/../src/ui/stock-items.cpp:110 +#: ../../po/../src/ui/stock-items.cpp:111 +#: ../../po/../src/ui/stock-items.cpp:112 +#: ../../po/../src/ui/stock-items.cpp:113 +#: ../../po/../src/ui/stock-items.cpp:114 +#: ../../po/../src/ui/stock-items.cpp:115 +#: ../../po/../src/ui/stock-items.cpp:116 +#: ../../po/../src/ui/stock-items.cpp:117 +#: ../../po/../src/ui/stock-items.cpp:118 +#: ../../po/../src/ui/stock-items.cpp:119 +#: ../../po/../src/ui/stock-items.cpp:120 +#: ../../po/../src/ui/stock-items.cpp:121 +#: ../../po/../src/ui/stock-items.cpp:122 +#: ../../po/../src/ui/stock-items.cpp:123 +#: ../../po/../src/ui/stock-items.cpp:124 +#: ../../po/../src/ui/stock-items.cpp:125 +#: ../../po/../src/ui/stock-items.cpp:126 +#: ../../po/../src/ui/stock-items.cpp:127 +#: ../../po/../src/ui/stock-items.cpp:130 +#: ../../po/../src/ui/stock-items.cpp:131 +#: ../../po/../src/ui/stock-items.cpp:132 +#: ../../po/../src/ui/stock-items.cpp:133 +#: ../../po/../src/ui/stock-items.cpp:134 +#: ../../po/../src/ui/stock-items.cpp:135 +#: ../../po/../src/ui/stock-items.cpp:136 +#: ../../po/../src/ui/stock-items.cpp:137 +#: ../../po/../src/ui/stock-items.cpp:138 +#: ../../po/../src/ui/stock-items.cpp:139 +#: ../../po/../src/ui/stock-items.cpp:140 +#: ../../po/../src/ui/stock-items.cpp:141 +#: ../../po/../src/ui/stock-items.cpp:142 +#: ../../po/../src/ui/stock-items.cpp:143 +#: ../../po/../src/ui/stock-items.cpp:144 +#: ../../po/../src/ui/stock-items.cpp:145 +#: ../../po/../src/ui/stock-items.cpp:146 +#: ../../po/../src/ui/stock-items.cpp:150 +#: ../../po/../src/ui/stock-items.cpp:151 +#: ../../po/../src/ui/stock-items.cpp:152 +#: ../../po/../src/ui/stock-items.cpp:153 +#: ../../po/../src/ui/stock-items.cpp:156 +#: ../../po/../src/ui/stock-items.cpp:157 +#: ../../po/../src/ui/stock-items.cpp:158 +#: ../../po/../src/ui/stock-items.cpp:161 +#: ../../po/../src/ui/stock-items.cpp:162 +#: ../../po/../src/ui/stock-items.cpp:163 +#: ../../po/../src/ui/stock-items.cpp:164 +#: ../../po/../src/ui/stock-items.cpp:165 +#: ../../po/../src/ui/stock-items.cpp:166 +#: ../../po/../src/ui/stock-items.cpp:167 +#: ../../po/../src/ui/stock-items.cpp:168 +#: ../../po/../src/ui/stock-items.cpp:169 +#: ../../po/../src/ui/stock-items.cpp:170 +#: ../../po/../src/ui/stock-items.cpp:171 +#: ../../po/../src/ui/stock-items.cpp:172 +#: ../../po/../src/ui/stock-items.cpp:175 +#: ../../po/../src/ui/stock-items.cpp:176 +#: ../../po/../src/ui/stock-items.cpp:177 +#: ../../po/../src/ui/stock-items.cpp:178 +#: ../../po/../src/ui/stock-items.cpp:181 +#: ../../po/../src/ui/stock-items.cpp:182 +#: ../../po/../src/ui/stock-items.cpp:183 +#: ../../po/../src/ui/stock-items.cpp:184 +#: ../../po/../src/ui/stock-items.cpp:185 +#: ../../po/../src/ui/stock-items.cpp:186 +#: ../../po/../src/ui/stock-items.cpp:187 +#: ../../po/../src/ui/stock-items.cpp:188 +#: ../../po/../src/ui/stock-items.cpp:189 +#: ../../po/../src/ui/stock-items.cpp:190 +#: ../../po/../src/ui/stock-items.cpp:191 +#: ../../po/../src/ui/stock-items.cpp:194 +#: ../../po/../src/ui/stock-items.cpp:195 +#: ../../po/../src/ui/stock-items.cpp:198 +#: ../../po/../src/ui/stock-items.cpp:199 +#: ../../po/../src/ui/stock-items.cpp:200 +#: ../../po/../src/ui/stock-items.cpp:201 +#: ../../po/../src/ui/stock-items.cpp:202 +msgid "PLACEHOLDER, do not translate" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:88 +msgid "small" +msgstr "ਛੋਟਾ" + +#: ../../po/../src/ui/widget/panel.cpp:89 +msgid "medium" +msgstr "ਮੱਧਮ" + +#: ../../po/../src/ui/widget/panel.cpp:90 +msgid "large" +msgstr "ਵੱਡਾ" + +#: ../../po/../src/ui/widget/panel.cpp:91 +msgid "huge" +msgstr "ਵਿਰਾਟ" + +#: ../../po/../src/ui/widget/panel.cpp:106 +msgid "List" +msgstr "ਸੂਚੀ" + +#: ../../po/../src/ui/widget/selected-style.cpp:67 +msgid "F:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:68 +msgid "S:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:69 +msgid "O:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:95 +msgid "N/A" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:98 +#: ../../po/../src/ui/widget/selected-style.cpp:712 +#, fuzzy +msgid "Nothing selected" +msgstr "ਕੋਈ ਢਾਲਵਾਂ ਨਹੀਂ ਚੁਣਿਆ" + +#: ../../po/../src/ui/widget/selected-style.cpp:103 +msgid "No fill" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:103 +#, fuzzy +msgid "No stroke" +msgstr " (ਛੋਹ)" + +#: ../../po/../src/ui/widget/selected-style.cpp:105 +#: ../../po/../src/widgets/paint-selector.cpp:190 +msgid "Pattern" +msgstr "ਤਰਤੀਬ" + +#: ../../po/../src/ui/widget/selected-style.cpp:108 +#: ../../po/../src/widgets/paint-selector.cpp:885 +msgid "Pattern fill" +msgstr "ਤਰਤੀਬ ਭਰਨ" + +#: ../../po/../src/ui/widget/selected-style.cpp:108 +#, fuzzy +msgid "Pattern stroke" +msgstr "ਤਰਤੀਬ ਅੰਤਰਲੰਬ" + +#: ../../po/../src/ui/widget/selected-style.cpp:110 +#, fuzzy +msgid "L Gradient" +msgstr "ਢਾਲਵਾਂ" + +#: ../../po/../src/ui/widget/selected-style.cpp:113 +#, fuzzy +msgid "Linear gradient fill" +msgstr "ਰੇਖਿਕ ਢਾਲਵਾਂ" + +#: ../../po/../src/ui/widget/selected-style.cpp:113 +#, fuzzy +msgid "Linear gradient stroke" +msgstr "ਰੇਖਿਕ ਢਾਲਵਾਂ" + +#: ../../po/../src/ui/widget/selected-style.cpp:115 +#, fuzzy +msgid "R Gradient" +msgstr "ਢਾਲਵਾਂ" + +#: ../../po/../src/ui/widget/selected-style.cpp:118 +#, fuzzy +msgid "Radial gradient fill" +msgstr "ਭਰਨ ਵਿੱਚ ਢਾਲਵਾਂ ਬਣਾਓ" + +#: ../../po/../src/ui/widget/selected-style.cpp:118 +#, fuzzy +msgid "Radial gradient stroke" +msgstr "ਛੋਹ ਵਿੱਚ ਢਾਲਵਾਂ ਬਣਾਓ" + +#: ../../po/../src/ui/widget/selected-style.cpp:120 +#, fuzzy +msgid "Different" +msgstr "ਅੰਤਰ(_D)" + +#: ../../po/../src/ui/widget/selected-style.cpp:123 +#, fuzzy +msgid "Different fills" +msgstr "ਅੰਤਰ(_D)" + +#: ../../po/../src/ui/widget/selected-style.cpp:123 +#, fuzzy +msgid "Different strokes" +msgstr "ਅੰਤਰ(_D)" + +#: ../../po/../src/ui/widget/selected-style.cpp:125 +#, fuzzy +msgid "Unset" +msgstr "ਇਕਾਈ" + +#. TRANSLATORS COMMENT: unset is a verb here +#: ../../po/../src/ui/widget/selected-style.cpp:128 +#: ../../po/../src/ui/widget/selected-style.cpp:182 +msgid "Unset fill" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:128 +#: ../../po/../src/ui/widget/selected-style.cpp:182 +#, fuzzy +msgid "Unset stroke" +msgstr " (ਛੋਹ)" + +#: ../../po/../src/ui/widget/selected-style.cpp:131 +#, fuzzy +msgid "Flat color fill" +msgstr "ਸਮਤਲ ਰੰਗ" + +#: ../../po/../src/ui/widget/selected-style.cpp:131 +#, fuzzy +msgid "Flat color stroke" +msgstr "ਸਮਤਲ ਰੰਗ" + +#. TRANSLATOR COMMENT: A means "Averaged" +#: ../../po/../src/ui/widget/selected-style.cpp:134 +#, fuzzy +msgid "A" +msgstr "_A" + +#: ../../po/../src/ui/widget/selected-style.cpp:137 +#, fuzzy +msgid "Fill is averaged over selected objects" +msgstr "ਚੁਣੀਆਂ ਇਕਾਈਆਂ ਦੋਹਰੀਆਂ" + +#: ../../po/../src/ui/widget/selected-style.cpp:137 +#, fuzzy +msgid "Stroke is averaged over selected objects" +msgstr "ਚੁਣੀਆਂ ਇਕਾਈਆਂ ਦੀ ਕਾਟ" + +#. TRANSLATOR COMMENT: M means "Multiple" +#: ../../po/../src/ui/widget/selected-style.cpp:140 +#, fuzzy +msgid "M" +msgstr "_M" + +#: ../../po/../src/ui/widget/selected-style.cpp:143 +#, fuzzy +msgid "Multiple selected objects have the same fill" +msgstr "ਚੁਣੀਆਂ ਇਕਾਈ ਗਰੁੱਪ ਵਿੱਚ" + +#: ../../po/../src/ui/widget/selected-style.cpp:143 +#, fuzzy +msgid "Multiple selected objects have the same stroke" +msgstr "ਚੁਣੀਆਂ ਇਕਾਈ ਗਰੁੱਪ ਵਿੱਚ" + +#: ../../po/../src/ui/widget/selected-style.cpp:145 +#, fuzzy +msgid "Edit fill..." +msgstr "ਸੋਧ..." + +#: ../../po/../src/ui/widget/selected-style.cpp:145 +#, fuzzy +msgid "Edit stroke..." +msgstr "ਸੋਧ..." + +#: ../../po/../src/ui/widget/selected-style.cpp:149 +#, fuzzy +msgid "Last set color" +msgstr "ਸਮਤਲ ਰੰਗ" + +#: ../../po/../src/ui/widget/selected-style.cpp:153 +#, fuzzy +msgid "Last selected color" +msgstr "ਆਖਰੀ ਚੁਣੀ" + +#: ../../po/../src/ui/widget/selected-style.cpp:157 +msgid "White" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:161 +#: ../../po/../src/widgets/sp-color-scales.cpp:461 +#: ../../po/../src/widgets/sp-color-scales.cpp:462 +msgid "Black" +msgstr "ਕਾਲਾ" + +#: ../../po/../src/ui/widget/selected-style.cpp:165 +#, fuzzy +msgid "Copy color" +msgstr "ਰੰਗ ਰੋਕੋ" + +#: ../../po/../src/ui/widget/selected-style.cpp:169 +#, fuzzy +msgid "Paste color" +msgstr "ਸਮਤਲ ਰੰਗ" + +#: ../../po/../src/ui/widget/selected-style.cpp:173 +#, fuzzy +msgid "Swap fill and stroke" +msgstr "ਭਰਨ ਅਤੇ ਛੋਹ(_F)" + +#: ../../po/../src/ui/widget/selected-style.cpp:177 +msgid "Make fill opaque" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:177 +msgid "Make stroke opaque" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:186 +#, fuzzy +msgid "Remove fill" +msgstr " ਹਟਾਓ(_m) " + +#: ../../po/../src/ui/widget/selected-style.cpp:186 +#, fuzzy +msgid "Remove stroke" +msgstr "ਸਬੰਧ ਹਟਾਓ(_R)" + +#: ../../po/../src/ui/widget/selected-style.cpp:718 +#, fuzzy +msgid "Master opacity" +msgstr "ਮਾਸਟਰ ਧੁੰਦਲਾਪਨ(_o)" + +#: ../../po/../src/ui/widget/selected-style.cpp:744 +msgid "0 (transparent)" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:768 +msgid "1.0 (opaque)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1046 +msgid "Moved to next layer." +msgstr "ਅਗਲੀ ਪਰਤ ਲਈ ਭੇਜਿਆ ਗਿਆ ਹੈ।" + +#: ../../po/../src/verbs.cpp:1048 +#, fuzzy +msgid "Cannot move past last layer." +msgstr "ਪਰਤ ਨੂੰ ਹੋਰ ਹਲਾਇਆ ਨਹੀਂ ਜਾ ਸਕਦਾ ਹੈ।" + +#: ../../po/../src/verbs.cpp:1057 +msgid "Moved to previous layer." +msgstr "ਪਿਛਲੀ ਪਰਤ ਹਿਲਾਈ ਗਈ ਹੈ।" + +#: ../../po/../src/verbs.cpp:1059 +#, fuzzy +msgid "Cannot move past first layer." +msgstr "ਪਰਤ ਨੂੰ ਹੋਰ ਹਲਾਇਆ ਨਹੀਂ ਜਾ ਸਕਦਾ ਹੈ।" + +#: ../../po/../src/verbs.cpp:1076 ../../po/../src/verbs.cpp:1150 +msgid "No current layer." +msgstr "ਕੋਈ ਮੌਜੂਦਾ ਪਰਤ ਨਹੀਂ ਹੈ।" + +#: ../../po/../src/verbs.cpp:1105 +#, c-format +msgid "Raised layer %s." +msgstr "ਪਰਤ %s ਉੱਤੇ ਕੀਤੀ ਗਈ ਹੈ।" + +#: ../../po/../src/verbs.cpp:1109 +#, c-format +msgid "Lowered layer %s." +msgstr "ਪਰਤ %s ਹੇਠਾਂ ਕੀਤੀ ਗਈ ਹੈ।" + +#: ../../po/../src/verbs.cpp:1118 +#, fuzzy +msgid "Cannot move layer any further." +msgstr "ਪਰਤ ਨੂੰ ਹੋਰ ਹਲਾਇਆ ਨਹੀਂ ਜਾ ਸਕਦਾ ਹੈ।" + +#. TRANSLATORS: this means "The layer has been deleted." +#: ../../po/../src/verbs.cpp:1148 +msgid "Deleted layer." +msgstr "ਪਰਤ ਹਟਾਈ ਗਈ ਹੈ।" + +#: ../../po/../src/verbs.cpp:1544 +msgid "" +"You need to connect to a Jabber server before sharing a document with " +"another user." +msgstr "" + +#: ../../po/../src/verbs.cpp:1559 +msgid "" +"You need to connect to a Jabber server before sharing a document with a " +"chatroom." +msgstr "" + +#: ../../po/../src/verbs.cpp:1569 +msgid "XML node tracker has not been initialized; nothing to dump" +msgstr "" + +#. TRANSLATORS: If you have translated the keys.svg file to your language, then +#. translate this string as "keys.LANG.svg" (where LANG is your language code); +#. otherwise leave as "keys.svg". +#: ../../po/../src/verbs.cpp:1631 +msgid "keys.svg" +msgstr "keys.svg" + +#. TRANSLATORS: If you have translated the tutorial-basic.svg file to your language, +#. then translate this string as "tutorial-basic.LANG.svg" (where LANG is your language +#. code); otherwise leave as "tutorial-basic.svg". +#: ../../po/../src/verbs.cpp:1667 +msgid "tutorial-basic.svg" +msgstr "tutorial-basic.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1671 +msgid "tutorial-shapes.svg" +msgstr "tutorial-shapes.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1675 +msgid "tutorial-advanced.svg" +msgstr "tutorial-advanced.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1679 +msgid "tutorial-tracing.svg" +msgstr "tutorial-tracing.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1683 +msgid "tutorial-calligraphy.svg" +msgstr "tutorial-calligraphy.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1687 +msgid "tutorial-elements.svg" +msgstr "tutorial-elements.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1691 +msgid "tutorial-tips.svg" +msgstr "tutorial-tips.svg" + +#: ../../po/../src/verbs.cpp:1842 +msgid "Does nothing" +msgstr "ਕੁਝ ਨਾ ਕਰੋ" + +#. File +#: ../../po/../src/verbs.cpp:1845 +msgid "Default" +msgstr "ਮੂਲ" + +#: ../../po/../src/verbs.cpp:1845 +msgid "Create new document from default template" +msgstr "ਮੂਲ ਨਮੂਨੇ ਤੋਂ ਨਵਾਂ ਦਸਤਾਵੇਜ਼ ਬਣਾਓ" + +#: ../../po/../src/verbs.cpp:1847 +msgid "_Open..." +msgstr "ਖੋਲੋ(_O)..." + +#: ../../po/../src/verbs.cpp:1848 +msgid "Open existing document" +msgstr "ਮੌਜੂਦਾ ਦਸਤਾਵੇਜ਼ ਖੋਲੋ" + +#: ../../po/../src/verbs.cpp:1849 +msgid "Re_vert" +msgstr "ਮੁੜ-ਪਰਾਪਤ(_v)" + +#: ../../po/../src/verbs.cpp:1850 +msgid "Revert to the last saved version of document (changes will be lost)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1851 +msgid "_Save" +msgstr "ਸੰਭਾਲੋ(_S)" + +#: ../../po/../src/verbs.cpp:1851 +msgid "Save document" +msgstr "ਦਸਤਾਵੇਜ਼ ਸੰਭਾਲੋ" + +#: ../../po/../src/verbs.cpp:1853 +msgid "Save _As..." +msgstr "ਇੰਞ ਸੰਭਾਲੋ(_A)..." + +#: ../../po/../src/verbs.cpp:1854 +msgid "Save document under new name" +msgstr "ਦਸਤਾਵੇਜ਼ ਨੂੰ ਨਵੇਂ ਨਾਂ ਹੇਠ ਸੰਭਾਲੋ" + +#: ../../po/../src/verbs.cpp:1855 +msgid "_Print..." +msgstr "ਛਾਪੋ(_P)..." + +#: ../../po/../src/verbs.cpp:1855 +msgid "Print document" +msgstr "ਦਸਤਾਵੇਜ਼ ਛਾਪੋ" + +#. TRANSLATORS: "Vacuum Defs" means "Clean up defs" (so as to remove unused definitions) +#: ../../po/../src/verbs.cpp:1858 +msgid "Vac_uum Defs" +msgstr "" + +#: ../../po/../src/verbs.cpp:1858 +msgid "Remove unused predefined items from the <defs> of the document" +msgstr "" + +#: ../../po/../src/verbs.cpp:1860 +msgid "Print _Direct" +msgstr "ਸਿੱਧਾ ਛਾਪੋ(_D)" + +#: ../../po/../src/verbs.cpp:1861 +#, fuzzy +msgid "Print directly without prompting to a file or pipe" +msgstr "ਫਾਇਲ ਜਾਂ ਪਾਈਪ ਵਿੱਚ ਸਿੱਧਾ ਛਾਪੋ" + +#: ../../po/../src/verbs.cpp:1862 +msgid "Print Previe_w" +msgstr "ਛਾਪਾਈ ਝਲਕ(_w)" + +#: ../../po/../src/verbs.cpp:1863 +msgid "Preview document printout" +msgstr "ਦਸਤਾਵੇਜ਼ ਛਪਾਈ ਦੀ ਝਲਕ" + +#: ../../po/../src/verbs.cpp:1864 +msgid "_Import..." +msgstr "ਅਯਾਤ(_I)..." + +#: ../../po/../src/verbs.cpp:1865 +msgid "Import bitmap or SVG image into document" +msgstr "ਬਿੱਟਮੈਪ ਜਾਂ SVG ਚਿੱਤਰ ਨੂੰ ਦਸਤਾਵੇਜ਼ ਵਿੱਚ ਅਯਾਤ" + +#: ../../po/../src/verbs.cpp:1866 +msgid "_Export Bitmap..." +msgstr "ਬਿੱਟਮੈਪ ਨਿਰਯਾਤ(_E)..." + +#: ../../po/../src/verbs.cpp:1867 +#, fuzzy +msgid "Export document or selection as a bitmap image" +msgstr "ਦਸਤਾਵੇਜ਼ ਜਾਂ ਚੋਣ ਨੂੰ PNG ਬਿੱਟਮੈਪ ਦੇ ਤੌਰ 'ਤੇ ਨਿਰਯਾਤ" + +#: ../../po/../src/verbs.cpp:1868 +msgid "N_ext Window" +msgstr "ਨਵਾਂ ਝਰੋਖਾ(_e)" + +#: ../../po/../src/verbs.cpp:1869 +msgid "Switch to the next document window" +msgstr "ਨਵੇਂ ਦਸਤਾਵੇਜ਼ ਝਰੋਖੇ ਲਈ ਤਬਦੀਲ" + +#: ../../po/../src/verbs.cpp:1870 +msgid "P_revious Window" +msgstr "ਪਿਛਲਾ ਝਰੋਖਾ(_r)" + +#: ../../po/../src/verbs.cpp:1871 +msgid "Switch to the previous document window" +msgstr "" + +#: ../../po/../src/verbs.cpp:1872 +msgid "_Close" +msgstr "ਬੰਦ(_C)" + +#: ../../po/../src/verbs.cpp:1873 +msgid "Close window" +msgstr "ਝਰੋਖਾ ਬੰਦ ਕਰੋ" + +#: ../../po/../src/verbs.cpp:1874 +msgid "_Quit" +msgstr "ਬਾਹਰ(_Q)" + +#: ../../po/../src/verbs.cpp:1874 +msgid "Quit Inkscape" +msgstr "ਇੰਕਸਕੇਪੀ ਬੰਦ ਕਰੋ" + +#. Edit +#: ../../po/../src/verbs.cpp:1877 +msgid "_Undo" +msgstr "ਵਾਪਸ(_U)" + +#: ../../po/../src/verbs.cpp:1877 +msgid "Undo last action" +msgstr "ਆਖਰੀ ਕਾਰਵਾਈ ਕਰੋ" + +#: ../../po/../src/verbs.cpp:1879 +msgid "_Redo" +msgstr "ਮੁੜ-ਵਾਪਸ(_R)" + +#: ../../po/../src/verbs.cpp:1880 +msgid "Do again last undone action" +msgstr "ਆਖਰੀ ਵਾਪਸ ਲਈ ਕਾਰਵਾਈ ਮੁੜ ਕਰੋ" + +#: ../../po/../src/verbs.cpp:1881 +msgid "Cu_t" +msgstr "ਕੱਟੋ(_t)" + +#: ../../po/../src/verbs.cpp:1882 +msgid "Cut selection to clipboard" +msgstr "ਚੋਣ ਨੂੰ ਕਲਿੱਪਬੋਰਡ ਵਿੱਚ ਕੱਟੋ" + +#: ../../po/../src/verbs.cpp:1883 +msgid "_Copy" +msgstr "ਨਕਲ(_C)" + +#: ../../po/../src/verbs.cpp:1884 +msgid "Copy selection to clipboard" +msgstr "ਚੋਣ ਨੂੰ ਕਲਿੱਪਬੋਰਡ ਵਿੱਚ ਨਕਲ" + +#: ../../po/../src/verbs.cpp:1885 +msgid "_Paste" +msgstr "ਚੇਪੋ(_P)" + +#: ../../po/../src/verbs.cpp:1886 +msgid "Paste objects from clipboard to mouse point" +msgstr "" + +#: ../../po/../src/verbs.cpp:1887 +msgid "Paste _Style" +msgstr "ਸ਼ੈਲੀ ਚੇਪੋ(_S)" + +#: ../../po/../src/verbs.cpp:1888 +msgid "Apply style of the copied object to selection" +msgstr "" + +#: ../../po/../src/verbs.cpp:1889 +msgid "Paste _In Place" +msgstr "ਥਾਂ ਵਿੱਚ ਚੇਪੋ(_I)" + +#: ../../po/../src/verbs.cpp:1890 +msgid "Paste objects from clipboard to the original location" +msgstr "" + +#: ../../po/../src/verbs.cpp:1891 +msgid "_Delete" +msgstr "ਹਟਾਓ(_D)" + +#: ../../po/../src/verbs.cpp:1892 +msgid "Delete selection" +msgstr "ਚੋਣ ਹਟਾਓ" + +#: ../../po/../src/verbs.cpp:1893 +msgid "Duplic_ate" +msgstr "ਦੁਹਰਾ(_a)" + +#: ../../po/../src/verbs.cpp:1894 +#, fuzzy +msgid "Duplicate selected objects" +msgstr "ਚੁਣੀਆਂ ਇਕਾਈਆਂ ਦੋਹਰੀਆਂ" + +#: ../../po/../src/verbs.cpp:1895 +msgid "Clo_ne" +msgstr "ਸਮਰੂਪ(_n)" + +#: ../../po/../src/verbs.cpp:1896 +msgid "Create a clone of selected object (a copy linked to the original)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1897 +msgid "Unlin_k Clone" +msgstr "" + +#: ../../po/../src/verbs.cpp:1898 +msgid "Cut the clone's link to its original" +msgstr "" + +#: ../../po/../src/verbs.cpp:1899 +msgid "Select _Original" +msgstr "ਅਸਲੀ ਚੁਣੋ(_O)" + +#: ../../po/../src/verbs.cpp:1900 +msgid "Select the object to which the clone is linked" +msgstr "" + +#. TRANSLATORS: Convert selection to a rectangle with tiled pattern fill +#: ../../po/../src/verbs.cpp:1902 +#, fuzzy +msgid "O_bjects to Pattern" +msgstr "ਤਰਤੀਬ ਲਈ ਇਕਾਈਆਂ(_b)" + +#: ../../po/../src/verbs.cpp:1903 +msgid "Convert selection to a rectangle with tiled pattern fill" +msgstr "" + +#. TRANSLATORS: Extract objects from a tiled pattern fill +#: ../../po/../src/verbs.cpp:1905 +#, fuzzy +msgid "Pattern to Ob_jects" +msgstr "ਇਕਾਈਆਂ ਲਈ ਤਰਤੀਬ(_j)" + +#: ../../po/../src/verbs.cpp:1906 +msgid "Extract objects from a tiled pattern fill" +msgstr "" + +#: ../../po/../src/verbs.cpp:1907 +msgid "Clea_r All" +msgstr "ਸਭ ਸਾਫ਼(_r)" + +#: ../../po/../src/verbs.cpp:1908 +msgid "Delete all objects from document" +msgstr "ਦਸਤਾਵੇਜ਼ਾਂ ਤੋਂ ਸਭ ਇਕਾਈਆਂ ਹਟਾਓ" + +#: ../../po/../src/verbs.cpp:1909 +msgid "Select Al_l" +msgstr "ਸਭ ਚੁਣੋ(_L)" + +#: ../../po/../src/verbs.cpp:1910 +msgid "Select all objects or all nodes" +msgstr "ਸਭ ਇਕਾਈਆਂ ਜਾਂ ਸਭ ਨੋਡ ਚੁਣੋ" + +#: ../../po/../src/verbs.cpp:1911 +msgid "Select All in All La_yers" +msgstr "ਸਭ ਪਰਤਾਂ ਵਿੱਚ ਸਭ ਚੁਣੋ(_y)" + +#: ../../po/../src/verbs.cpp:1912 +msgid "Select all objects in all visible and unlocked layers" +msgstr "" + +#: ../../po/../src/verbs.cpp:1913 +msgid "In_vert Selection" +msgstr "ਉਲਟ ਚੋਣ(_v)" + +#: ../../po/../src/verbs.cpp:1914 +msgid "Invert selection (unselect what is selected and select everything else)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1915 +msgid "Invert in All Layers" +msgstr "" + +#: ../../po/../src/verbs.cpp:1916 +msgid "Invert selection in all visible and unlocked layers" +msgstr "" + +#: ../../po/../src/verbs.cpp:1917 +msgid "D_eselect" +msgstr "ਅਣ-ਚੁਣਿਆ(_e)" + +#: ../../po/../src/verbs.cpp:1918 +msgid "Deselect any selected objects or nodes" +msgstr "" + +#. Selection +#: ../../po/../src/verbs.cpp:1921 +msgid "Raise to _Top" +msgstr "" + +#: ../../po/../src/verbs.cpp:1922 +msgid "Raise selection to top" +msgstr "" + +#: ../../po/../src/verbs.cpp:1923 +msgid "Lower to _Bottom" +msgstr "" + +#: ../../po/../src/verbs.cpp:1924 +msgid "Lower selection to bottom" +msgstr "" + +#: ../../po/../src/verbs.cpp:1925 +msgid "_Raise" +msgstr "ਉਭਾਰੋ(_R)" + +#: ../../po/../src/verbs.cpp:1926 +msgid "Raise selection one step" +msgstr "" + +#: ../../po/../src/verbs.cpp:1927 +msgid "_Lower" +msgstr "ਹੇਠ(_L)" + +#: ../../po/../src/verbs.cpp:1928 +msgid "Lower selection one step" +msgstr "" + +#: ../../po/../src/verbs.cpp:1929 +msgid "_Group" +msgstr "ਗਰੁੱਪ(_G)" + +#: ../../po/../src/verbs.cpp:1930 +msgid "Group selected objects" +msgstr "ਚੁਣੀਆਂ ਇਕਾਈ ਗਰੁੱਪ ਵਿੱਚ" + +#: ../../po/../src/verbs.cpp:1932 +#, fuzzy +msgid "Ungroup selected groups" +msgstr "ਚੁਣੇ ਗਰੁੱਪ ਖਿਲਾਰੋ" + +#: ../../po/../src/verbs.cpp:1934 +msgid "_Put on Path" +msgstr "ਮਾਰਗ ਉੱਤੇ ਦਿਓ(_P)" + +#: ../../po/../src/verbs.cpp:1935 +msgid "Put text on path" +msgstr "ਮਾਰਗ ਉੱਤੇ ਪਾਠ ਦਿਓ" + +#: ../../po/../src/verbs.cpp:1936 +msgid "_Remove from Path" +msgstr "ਮਾਰਗ ਤੋਂ ਹਟਾਓ(_R)" + +#: ../../po/../src/verbs.cpp:1937 +msgid "Remove text from path" +msgstr "ਮਾਰਗ ਤੋਂ ਪਾਠ ਹਟਾਓ" + +#: ../../po/../src/verbs.cpp:1938 +msgid "Remove Manual _Kerns" +msgstr "" + +#. TRANSLATORS: "glyph": An image used in the visual representation of characters; +#. roughly speaking, how a character looks. A font is a set of glyphs. +#: ../../po/../src/verbs.cpp:1941 +msgid "Remove all manual kerns and glyph rotations from a text object" +msgstr "" + +#: ../../po/../src/verbs.cpp:1943 +msgid "_Union" +msgstr "ਸਾਂਝ(_U)" + +#: ../../po/../src/verbs.cpp:1944 +msgid "Union of selected objects" +msgstr "ਚੁਣੀਆਂ ਇਕਾਈਆਂ ਦੀ ਸਾਂਝ" + +#: ../../po/../src/verbs.cpp:1945 +msgid "_Intersection" +msgstr "ਕਾਟ(_I)" + +#: ../../po/../src/verbs.cpp:1946 +msgid "Intersection of selected objects" +msgstr "ਚੁਣੀਆਂ ਇਕਾਈਆਂ ਦੀ ਕਾਟ" + +#: ../../po/../src/verbs.cpp:1947 +msgid "_Difference" +msgstr "ਅੰਤਰ(_D)" + +#: ../../po/../src/verbs.cpp:1948 +msgid "Difference of selected objects (bottom minus top)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1949 +msgid "E_xclusion" +msgstr "" + +#: ../../po/../src/verbs.cpp:1950 +msgid "Exclusive OR of selected objects" +msgstr "" + +#: ../../po/../src/verbs.cpp:1951 +msgid "Di_vision" +msgstr "ਵੰਡ(_v)" + +#: ../../po/../src/verbs.cpp:1952 +msgid "Cut the bottom object into pieces" +msgstr "" + +#. TRANSLATORS: "to cut a path" is not the same as "to break a path apart" - see the +#. Advanced tutorial for more info +#: ../../po/../src/verbs.cpp:1955 +msgid "Cut _Path" +msgstr "ਮਾਰਗ ਕੱਟੋ(_P)" + +#: ../../po/../src/verbs.cpp:1956 +msgid "Cut the bottom object's stroke into pieces, removing fill" +msgstr "" + +#. TRANSLATORS: "outset": expand a shape by offsetting the object's path, +#. i.e. by displacing it perpendicular to the path in each point. +#. See also the Advanced Tutorial for explanation. +#: ../../po/../src/verbs.cpp:1960 +msgid "Outs_et" +msgstr "" + +#: ../../po/../src/verbs.cpp:1961 +#, fuzzy +msgid "Outset selected paths" +msgstr "ਚੁਣੇ ਮਾਰਗ ਵਿੱਚ ਜੋੜਿਆ ਜਾ ਰਿਹਾ ਹੈ" + +#: ../../po/../src/verbs.cpp:1963 +msgid "O_utset Path by 1 px" +msgstr "" + +#: ../../po/../src/verbs.cpp:1964 +msgid "Outset selected paths by 1 px" +msgstr "" + +#: ../../po/../src/verbs.cpp:1966 +msgid "O_utset Path by 10 px" +msgstr "" + +#: ../../po/../src/verbs.cpp:1967 +msgid "Outset selected paths by 10 px" +msgstr "" + +#. TRANSLATORS: "inset": contract a shape by offsetting the object's path, +#. i.e. by displacing it perpendicular to the path in each point. +#. See also the Advanced Tutorial for explanation. +#: ../../po/../src/verbs.cpp:1971 +msgid "I_nset" +msgstr "" + +#: ../../po/../src/verbs.cpp:1972 +#, fuzzy +msgid "Inset selected paths" +msgstr "ਚੁਣੇ ਮਾਰਗ ਵਿੱਚ ਜੋੜਿਆ ਜਾ ਰਿਹਾ ਹੈ" + +#: ../../po/../src/verbs.cpp:1974 +msgid "I_nset Path by 1 px" +msgstr "" + +#: ../../po/../src/verbs.cpp:1975 +msgid "Inset selected paths by 1 px" +msgstr "" + +#: ../../po/../src/verbs.cpp:1977 +msgid "I_nset Path by 10 px" +msgstr "" + +#: ../../po/../src/verbs.cpp:1978 +msgid "Inset selected paths by 10 px" +msgstr "" + +#: ../../po/../src/verbs.cpp:1980 +msgid "D_ynamic Offset" +msgstr "ਸਫ਼ਰੀ ਅੰਤਰਲੰਬ(_y)" + +#: ../../po/../src/verbs.cpp:1980 +msgid "Create a dynamic offset object" +msgstr "" + +#: ../../po/../src/verbs.cpp:1982 +msgid "_Linked Offset" +msgstr "ਸਬੰਧਤ ਅੰਤਰਲੰਬ(_L)" + +#: ../../po/../src/verbs.cpp:1983 +msgid "Create a dynamic offset object linked to the original path" +msgstr "" + +#: ../../po/../src/verbs.cpp:1985 +msgid "_Stroke to Path" +msgstr "ਮਾਰਗ ਲਈ ਛੋਹ(_S)" + +#: ../../po/../src/verbs.cpp:1986 +#, fuzzy +msgid "Convert selected strokes to paths" +msgstr "ਚੁਣੀਆਂ ਇਕਾਈਆਂ ਨੂੰ ਮਾਰਗ ਤਬਦੀਲ" + +#: ../../po/../src/verbs.cpp:1987 +msgid "Si_mplify" +msgstr "ਸਧਾਰਨ(_m)" + +#: ../../po/../src/verbs.cpp:1988 +msgid "Simplify selected paths by removing extra nodes" +msgstr "" + +#: ../../po/../src/verbs.cpp:1989 +msgid "_Reverse" +msgstr "ਉਲਟ(_R)" + +#: ../../po/../src/verbs.cpp:1990 +msgid "Reverses the direction of selected paths; useful for flipping markers" +msgstr "" + +#. TRANSLATORS: "to trace" means "to convert a bitmap to vector graphics" (to vectorize) +#: ../../po/../src/verbs.cpp:1992 +msgid "_Trace Bitmap" +msgstr "" + +#: ../../po/../src/verbs.cpp:1993 +msgid "Convert bitmap object to paths" +msgstr "" + +#: ../../po/../src/verbs.cpp:1994 +msgid "_Make a Bitmap Copy" +msgstr "" + +#: ../../po/../src/verbs.cpp:1995 +msgid "Export selection to a bitmap and insert it into document" +msgstr "" + +#: ../../po/../src/verbs.cpp:1996 +msgid "_Combine" +msgstr "ਜੋੜੋ(_C)" + +#: ../../po/../src/verbs.cpp:1997 +msgid "Combine several paths into one" +msgstr "" + +#. TRANSLATORS: "to cut a path" is not the same as "to break a path apart" - see the +#. Advanced tutorial for more info +#: ../../po/../src/verbs.cpp:2000 +msgid "Break _Apart" +msgstr "" + +#: ../../po/../src/verbs.cpp:2001 +#, fuzzy +msgid "Break selected paths into subpaths" +msgstr "ਚੁਣੀਆਂ ਇਕਾਈਆਂ ਨੂੰ ਮਾਰਗ ਤਬਦੀਲ" + +#: ../../po/../src/verbs.cpp:2002 +msgid "Gri_d Arrange..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2003 +msgid "Arrange selection in grid pattern" +msgstr "" + +#. Layer +#: ../../po/../src/verbs.cpp:2005 +msgid "_Add Layer..." +msgstr "ਪਰਤ ਸ਼ਾਮਲ(_A)..." + +#: ../../po/../src/verbs.cpp:2006 +msgid "Create a new layer" +msgstr "ਇੱਕ ਨਵੀਂ ਪਰਤ ਬਣਾਓ" + +#: ../../po/../src/verbs.cpp:2007 +msgid "Re_name Layer..." +msgstr "ਪਰਤ ਨਾਂ-ਤਬਦੀਲ(_n)..." + +#: ../../po/../src/verbs.cpp:2008 +msgid "Rename the current layer" +msgstr "ਮੌਜੂਦਾ ਪਰਤ ਦਾ ਨਾਂ-ਤਬਦੀਲ" + +#: ../../po/../src/verbs.cpp:2009 +msgid "Switch to Layer Abov_e" +msgstr "ਪਰਤ ਨੂੰ ਮੌਜੂਦਾ ਤੋਂ ਉੱਤੇ(_e)" + +#: ../../po/../src/verbs.cpp:2010 +msgid "Switch to the layer above the current" +msgstr "ਪਰਤ ਨੂੰ ਮੌਜੂਦਾ ਦੇ ਉੱਪਰ ਭੇਜੋ" + +#: ../../po/../src/verbs.cpp:2011 +msgid "Switch to Layer Belo_w" +msgstr "ਪਰਤ ਨੂੰ ਮੌਜੂਦਾ ਦੇ ਹੇਠਾਂ ਕਰੋ(_w)" + +#: ../../po/../src/verbs.cpp:2012 +msgid "Switch to the layer below the current" +msgstr "ਪਰਤ ਨੂੰ ਮੌਜੂਦਾ ਦੇ ਹੇਠ" + +#: ../../po/../src/verbs.cpp:2013 +msgid "Move Selection to Layer Abo_ve" +msgstr "" + +#: ../../po/../src/verbs.cpp:2014 +msgid "Move selection to the layer above the current" +msgstr "" + +#: ../../po/../src/verbs.cpp:2015 +msgid "Move Selection to Layer Bel_ow" +msgstr "" + +#: ../../po/../src/verbs.cpp:2016 +msgid "Move selection to the layer below the current" +msgstr "" + +#: ../../po/../src/verbs.cpp:2017 +msgid "Layer to _Top" +msgstr "ਪਰਤ ਉੱਤੇ(_T)" + +#: ../../po/../src/verbs.cpp:2018 +msgid "Raise the current layer to the top" +msgstr "ਮੌਜੂਦਾ ਪਰਤ ਨੂੰ ਉੱਤੇ ਭੇਜੋ" + +#: ../../po/../src/verbs.cpp:2019 +msgid "Layer to _Bottom" +msgstr "ਪਰਤ ਤਲ ਉੱਤੇ(_B)" + +#: ../../po/../src/verbs.cpp:2020 +msgid "Lower the current layer to the bottom" +msgstr "ਮੌਜੂਦਾ ਪਰਤ ਨੂੰ ਤਲ ਉੱਤੇ ਭੇਜੋ" + +#: ../../po/../src/verbs.cpp:2021 +msgid "_Raise Layer" +msgstr "ਪਰਤ ਉਭਾਰੋ(_R)" + +#: ../../po/../src/verbs.cpp:2022 +msgid "Raise the current layer" +msgstr "ਮੌਜੂਦਾ ਪਰਤ ਉਭਾਰੋ" + +#: ../../po/../src/verbs.cpp:2023 +msgid "_Lower Layer" +msgstr "ਪਰਤ ਹੇਠਾਂ(_L)" + +#: ../../po/../src/verbs.cpp:2024 +msgid "Lower the current layer" +msgstr "ਮੌਜੂਦਾ ਪਰਤ ਹੇਠਾਂ" + +#: ../../po/../src/verbs.cpp:2025 +msgid "_Delete Current Layer" +msgstr "ਮੌਜੂਦਾ ਪਰਤ ਹਟਾਓ(_D)" + +#: ../../po/../src/verbs.cpp:2026 +msgid "Delete the current layer" +msgstr "ਮੌਜੂਦਾ ਪਰਤ ਹਟਾਓ" + +#. Object +#: ../../po/../src/verbs.cpp:2029 +msgid "Rotate _90° CW" +msgstr "" + +#: ../../po/../src/verbs.cpp:2030 +msgid "Rotate selection 90° clockwise" +msgstr "" + +#: ../../po/../src/verbs.cpp:2031 +msgid "Rotate 9_0° CCW" +msgstr "" + +#: ../../po/../src/verbs.cpp:2032 +msgid "Rotate selection 90° counter-clockwise" +msgstr "" + +#: ../../po/../src/verbs.cpp:2033 +msgid "Remove _Transformations" +msgstr "ਤਬਦੀਲੀਆਂ ਹਟਾਓ(_T)" + +#: ../../po/../src/verbs.cpp:2034 +msgid "Remove transformations from object" +msgstr "ਇਕਾਈਆਂ ਤੋਂ ਤਬਦੀਲੀਆਂ ਹਟਾਓ" + +#: ../../po/../src/verbs.cpp:2035 +msgid "_Object to Path" +msgstr "ਇਕਾਈ ਤੋਂ ਮਾਰਗ(_O)" + +#: ../../po/../src/verbs.cpp:2036 +#, fuzzy +msgid "Convert selected objects to paths" +msgstr "ਚੁਣੀਆਂ ਇਕਾਈਆਂ ਨੂੰ ਮਾਰਗ ਤਬਦੀਲ" + +#: ../../po/../src/verbs.cpp:2037 +msgid "_Flow into Frame" +msgstr "ਫਰੇਮ ਵਿੱਚ ਵਹਾ(_F)" + +#: ../../po/../src/verbs.cpp:2038 +#, fuzzy +msgid "Put text into frames" +msgstr "ਪਾਠ ਨੂੰ ਫਰੇਮ ਵਿੱਚ ਰੱਖੋ" + +#: ../../po/../src/verbs.cpp:2039 +msgid "_Unflow" +msgstr "" + +#: ../../po/../src/verbs.cpp:2040 +msgid "Remove text from frame (creates a single-line text object)" +msgstr "" + +#: ../../po/../src/verbs.cpp:2041 +msgid "_Convert to Text" +msgstr "ਪਾਠ ਲਈ ਤਬਦੀਲ(_C)" + +#: ../../po/../src/verbs.cpp:2042 +msgid "Convert flowed text to regular text objects (preserves appearance)" +msgstr "" + +#: ../../po/../src/verbs.cpp:2044 +#, fuzzy +msgid "Flip _Horizontal" +msgstr "ਖਿਤਿਜੀ ਝਟਕੋ(_H):" + +#: ../../po/../src/verbs.cpp:2044 +#, fuzzy +msgid "Flips selected objects horizontally" +msgstr "ਚੁਣੀਆਂ ਇਕਾਈ ਗਰੁੱਪ ਵਿੱਚ" + +#: ../../po/../src/verbs.cpp:2047 +#, fuzzy +msgid "Flip _Vertical" +msgstr "ਲੰਬਕਾਰੀ ਝਟਕੋ(_V):" + +#: ../../po/../src/verbs.cpp:2047 +#, fuzzy +msgid "Flips selected objects vertically" +msgstr "ਚੁਣੀਆਂ ਇਕਾਈ ਗਰੁੱਪ ਵਿੱਚ" + +#. Tools +#: ../../po/../src/verbs.cpp:2051 +msgid "Select" +msgstr "ਚੋਣ" + +#: ../../po/../src/verbs.cpp:2052 +msgid "Select and transform objects" +msgstr "ਇਕਾਈਆਂ ਚੁਣੋ ਅਤੇ ਤਬਦੀਲ" + +#: ../../po/../src/verbs.cpp:2053 +msgid "Node Edit" +msgstr "ਨੋਡ ਸੋਧ" + +#: ../../po/../src/verbs.cpp:2054 +msgid "Edit path nodes or control handles" +msgstr "" + +#: ../../po/../src/verbs.cpp:2056 +msgid "Create rectangles and squares" +msgstr "ਚਤੁਰਭੁਜ ਅਤੇ ਵਰਗ ਬਣਾਓ" + +#: ../../po/../src/verbs.cpp:2058 +msgid "Create circles, ellipses, and arcs" +msgstr "ਚੱਕਰ, ਅੰਡਾਕਾਰ ਅਤੇ ਚਾਪਾਂ ਬਣਾਓ" + +#: ../../po/../src/verbs.cpp:2060 +msgid "Create stars and polygons" +msgstr "ਤਾਰਾ ਅਤੇ ਬਹੁਭੁਜ ਬਣਾਓ" + +#: ../../po/../src/verbs.cpp:2062 +msgid "Create spirals" +msgstr "" + +#: ../../po/../src/verbs.cpp:2064 +msgid "Draw freehand lines" +msgstr "ਹੱਥ ਨਾਲ ਰੇਖਾਵਾਂ ਖਿੱਚੋ" + +#: ../../po/../src/verbs.cpp:2066 +msgid "Draw Bezier curves and straight lines" +msgstr "" + +#: ../../po/../src/verbs.cpp:2068 +msgid "Draw calligraphic lines" +msgstr "" + +#: ../../po/../src/verbs.cpp:2070 +msgid "Create and edit text objects" +msgstr "ਪਾਠ ਇਕਾਈਆਂ ਬਣਾਓ ਅਤੇ ਸੋਧੋ" + +#: ../../po/../src/verbs.cpp:2072 +msgid "Create and edit gradients" +msgstr "ਢਾਲਵੇਂ ਬਣਾਓ ਅਤੇ ਸੋਧੋ" + +#: ../../po/../src/verbs.cpp:2074 +msgid "Zoom in or out" +msgstr "ਜ਼ੂਮ ਅੰਦਰ ਜਾਂ ਬਾਹਰ" + +#: ../../po/../src/verbs.cpp:2076 +msgid "Pick averaged colors from image" +msgstr "ਚਿੱਤਰ ਤੋਂ ਔਸਤ ਰੰਗ ਚੁਣੋ" + +#: ../../po/../src/verbs.cpp:2078 +msgid "Create connectors" +msgstr "" + +#. Tool prefs +#: ../../po/../src/verbs.cpp:2081 +msgid "Selector Preferences" +msgstr "ਚੋਣਕਾਰ ਪਸੰਦ" + +#: ../../po/../src/verbs.cpp:2082 +#, fuzzy +msgid "Open Preferences for the Selector tool" +msgstr "ਚੋਣਕਾਰ ਸੰਦ ਲਈ ਇੰਕਸਕੇਪੀ ਪਸੰਦ ਖੋਲੋ" + +#: ../../po/../src/verbs.cpp:2083 +msgid "Node Tool Preferences" +msgstr "ਨੋਡ ਸੰਦ ਪਸੰਦ" + +#: ../../po/../src/verbs.cpp:2084 +#, fuzzy +msgid "Open Preferences for the Node tool" +msgstr "ਨੋਡ ਸੰਦ ਲਈ ਇੰਕਸਕੇਪੀ ਪਸੰਦ ਖੋਲੋ" + +#: ../../po/../src/verbs.cpp:2085 +msgid "Rectangle Preferences" +msgstr "ਵਾਰਤਾਲਾਪ ਪਸੰਦ" + +#: ../../po/../src/verbs.cpp:2086 +#, fuzzy +msgid "Open Preferences for the Rectangle tool" +msgstr "ਚਤੁਰਭੁਜ ਸੰਦ ਲਈ ਇੰਕਸਕੇਪੀ ਪਸੰਦ ਖੋਲੋ" + +#: ../../po/../src/verbs.cpp:2087 +msgid "Ellipse Preferences" +msgstr "ਅੰਡਾਕਾਰ ਪਸੰਦ" + +#: ../../po/../src/verbs.cpp:2088 +#, fuzzy +msgid "Open Preferences for the Ellipse tool" +msgstr "ਅੰਡਾਕਾਰ ਸੰਦ ਲਈ ਇੰਕਸਕੇਪੀ ਪਸੰਦ ਖੋਲੋ" + +#: ../../po/../src/verbs.cpp:2089 +msgid "Star Preferences" +msgstr "ਤਾਰਾ ਪਸੰਦ" + +#: ../../po/../src/verbs.cpp:2090 +#, fuzzy +msgid "Open Preferences for the Star tool" +msgstr "ਤਾਰਾ ਸੰਦ ਲਈ ਇੰਕਸਕੇਪੀ ਪਸੰਦ ਖੋਲੋ" + +#: ../../po/../src/verbs.cpp:2091 +msgid "Spiral Preferences" +msgstr "" + +#: ../../po/../src/verbs.cpp:2092 +#, fuzzy +msgid "Open Preferences for the Spiral tool" +msgstr "ਤਾਰਾ ਸੰਦ ਲਈ ਇੰਕਸਕੇਪੀ ਪਸੰਦ ਖੋਲੋ" + +#: ../../po/../src/verbs.cpp:2093 +msgid "Pencil Preferences" +msgstr "ਪੈਨਸਿਲ ਪਸੰਦ" + +#: ../../po/../src/verbs.cpp:2094 +#, fuzzy +msgid "Open Preferences for the Pencil tool" +msgstr "ਪਿਨਸਲ ਸੰਦ ਲਈ ਇੰਕਸਕੇਪੀ ਪਸੰਦ ਖੋਲੋ" + +#: ../../po/../src/verbs.cpp:2095 +msgid "Pen Preferences" +msgstr "ਪੈਨ ਪਸੰਦ" + +#: ../../po/../src/verbs.cpp:2096 +#, fuzzy +msgid "Open Preferences for the Pen tool" +msgstr "ਪੈਨ ਸੰਦ ਲਈ ਇੰਕਸਕੇਪੀ ਪਸੰਦ ਖੋਲੋ" + +#: ../../po/../src/verbs.cpp:2097 +msgid "Calligraphic Preferences" +msgstr "ਕੈਲੀਗਰਾਫ਼ੀ ਪਸੰਦ" + +#: ../../po/../src/verbs.cpp:2098 +#, fuzzy +msgid "Open Preferences for the Calligraphy tool" +msgstr "ਕੈਲੀਗਰਾਫ਼ੀ ਸੰਦ ਲਈ ਇੰਕਸਕੇਪੀ ਪਸੰਦ ਖੋਲੋ" + +#: ../../po/../src/verbs.cpp:2099 +msgid "Text Preferences" +msgstr "ਪਾਠ ਪਸੰਦ" + +#: ../../po/../src/verbs.cpp:2100 +#, fuzzy +msgid "Open Preferences for the Text tool" +msgstr "ਪਾਠ ਸੰਦ ਲਈ ਇੰਕਸਕੇਪੀ ਪਸੰਦ ਖੋਲੋ" + +#: ../../po/../src/verbs.cpp:2101 +msgid "Gradient Preferences" +msgstr "ਢਾਲਵਾਂ ਪਸੰਦ" + +#: ../../po/../src/verbs.cpp:2102 +#, fuzzy +msgid "Open Preferences for the Gradient tool" +msgstr "ਢਾਲਵਾਂ ਸੰਦ ਲਈ ਇੰਕਸਕੇਪੀ ਪਸੰਦ ਖੋਲੋ" + +#: ../../po/../src/verbs.cpp:2103 +msgid "Zoom Preferences" +msgstr "ਜ਼ੂਮ ਪਸੰਦ" + +#: ../../po/../src/verbs.cpp:2104 +#, fuzzy +msgid "Open Preferences for the Zoom tool" +msgstr "ਜ਼ੂਮ ਸੰਦ ਲਈ ਇੰਕਸਕੇਪੀ ਪਸੰਦ ਖੋਲੋ" + +#: ../../po/../src/verbs.cpp:2105 +msgid "Dropper Preferences" +msgstr "ਚੂਸਕ ਪਸੰਦ" + +#: ../../po/../src/verbs.cpp:2106 +#, fuzzy +msgid "Open Preferences for the Dropper tool" +msgstr "ਚੂਸਕ ਸੰਦ ਲਈ ਇੰਕਸਕੇਪੀ ਪਸੰਦ ਖੋਲੋ" + +#: ../../po/../src/verbs.cpp:2107 +#, fuzzy +msgid "Connector Preferences" +msgstr "ਚੋਣਕਾਰ ਪਸੰਦ" + +#: ../../po/../src/verbs.cpp:2108 +#, fuzzy +msgid "Open Preferences for the Connector tool" +msgstr "ਚੋਣਕਾਰ ਸੰਦ ਲਈ ਇੰਕਸਕੇਪੀ ਪਸੰਦ ਖੋਲੋ" + +#. Zoom/View +#: ../../po/../src/verbs.cpp:2111 +msgid "Zoom In" +msgstr "ਜ਼ੂਮ ਅੰਦਰ" + +#: ../../po/../src/verbs.cpp:2111 +msgid "Zoom in" +msgstr "ਜ਼ੂਮ ਅੰਦਰ" + +#: ../../po/../src/verbs.cpp:2112 +msgid "Zoom Out" +msgstr "ਜ਼ੂਮ ਬਾਹਰ" + +#: ../../po/../src/verbs.cpp:2112 +msgid "Zoom out" +msgstr "ਜ਼ੂਮ ਬਾਹਰ" + +#: ../../po/../src/verbs.cpp:2113 +msgid "_Rulers" +msgstr "ਪੈਮਾਨਾ(_R)" + +#: ../../po/../src/verbs.cpp:2113 +msgid "Show or hide the canvas rulers" +msgstr "" + +#: ../../po/../src/verbs.cpp:2114 +msgid "Scroll_bars" +msgstr "ਸਕਰੋਲ ਪੱਟੀ(_b)" + +#: ../../po/../src/verbs.cpp:2114 +msgid "Show or hide the canvas scrollbars" +msgstr "" + +#: ../../po/../src/verbs.cpp:2115 +msgid "_Grid" +msgstr "ਗਰਿੱਡ(_G)" + +#: ../../po/../src/verbs.cpp:2116 +msgid "G_uides" +msgstr "ਗਾਈਡ(_u)" + +#: ../../po/../src/verbs.cpp:2117 +msgid "Nex_t Zoom" +msgstr "ਅੱਗੇ ਜ਼ੂਮ(_t)" + +#: ../../po/../src/verbs.cpp:2117 +msgid "Next zoom (from the history of zooms)" +msgstr "ਅੱਗੇ ਜ਼ੂਮ (ਜ਼ੂਮਾਂ ਦੇ ਅਤੀਤ ਤੋਂ)" + +#: ../../po/../src/verbs.cpp:2119 +msgid "Pre_vious Zoom" +msgstr "ਪਿੱਛੇ ਜ਼ੂਮ(_v)" + +#: ../../po/../src/verbs.cpp:2119 +msgid "Previous zoom (from the history of zooms)" +msgstr "ਪਿਛਲਾ ਜ਼ੂਮ (ਜ਼ੂਮਾਂ ਦੇ ਅਤੀਤ ਤੋਂ)" + +#: ../../po/../src/verbs.cpp:2121 +msgid "Zoom 1:_1" +msgstr "ਜ਼ੂਮ 1:_1" + +#: ../../po/../src/verbs.cpp:2121 +msgid "Zoom to 1:1" +msgstr "1:1 ਜ਼ੂਮ" + +#: ../../po/../src/verbs.cpp:2123 +msgid "Zoom 1:_2" +msgstr "ਜ਼ੂਮ 1:_2" + +#: ../../po/../src/verbs.cpp:2123 +msgid "Zoom to 1:2" +msgstr "1:2 ਲਈ ਜ਼ੂਮ" + +#: ../../po/../src/verbs.cpp:2125 +msgid "_Zoom 2:1" +msgstr "ਜ਼ੂਮ(_Z) 2:1" + +#: ../../po/../src/verbs.cpp:2125 +msgid "Zoom to 2:1" +msgstr "2:1 ਨਾਲ ਜ਼ੂਮ" + +#: ../../po/../src/verbs.cpp:2128 +msgid "_Fullscreen" +msgstr "ਪੂਰੇ ਪਰਦੇ 'ਤੇ(_F)" + +#: ../../po/../src/verbs.cpp:2128 +msgid "Stretch this document window to full screen" +msgstr "ਪੂਰੇ ਪਰਦੇ ਲਈ ਇਸ ਦਸਤਾਵੇਜ਼ ਝਰੋਖੇ ਨੂੰ ਤਾਣੋ" + +#: ../../po/../src/verbs.cpp:2131 +msgid "Duplic_ate Window" +msgstr "ਦੁਹਰਾ ਝਰੋਖਾ(_a)" + +#: ../../po/../src/verbs.cpp:2131 +msgid "Open a new window with the same document" +msgstr "ਨਵਾਂ ਝਰੋਖਾ ਉਸੇ ਦਸਤਾਵੇਜ਼ ਨਾਲ ਖੋਲੋ" + +#: ../../po/../src/verbs.cpp:2133 +msgid "_New View Preview" +msgstr "ਨਵੀਂ ਦਿੱਖ ਝਲਕ(_N)" + +#: ../../po/../src/verbs.cpp:2134 +msgid "New View Preview" +msgstr "ਨਵੀਂ ਦਿੱਖ ਝਲਕ" + +#. "view_new_preview" +#: ../../po/../src/verbs.cpp:2136 +#, fuzzy +msgid "_Normal" +msgstr "ਸਧਾਰਨ" + +#: ../../po/../src/verbs.cpp:2137 +msgid "Switch to normal display mode" +msgstr "" + +#: ../../po/../src/verbs.cpp:2138 +#, fuzzy +msgid "_Outline" +msgstr "ਬਕਸਾ ਬਾਹਰੀ-ਰੇਖਾ" + +#: ../../po/../src/verbs.cpp:2139 +msgid "Switch to outline (wireframe) display mode" +msgstr "" + +#: ../../po/../src/verbs.cpp:2141 +msgid "Ico_n Preview" +msgstr "ਆਈਕਾਨ ਝਲਕ(_n)" + +#: ../../po/../src/verbs.cpp:2142 +msgid "Open a window to preview items at different icon resolutions" +msgstr "ਵੱਖਰ ਆਈਕਾਨ ਰੈਜ਼ੋਲੇਸ਼ਨ ਨਾਲ ਇਕਾਈ ਝਲਕ ਵੇਖਾਉਣ ਲਈ ਇੱਕ ਝਰੋਖਾ ਖੋਲੋ" + +#: ../../po/../src/verbs.cpp:2144 +msgid "Zoom to fit page in window" +msgstr "ਝਰੋਖੇ ਵਿੱਚ ਜ਼ੂਮ ਨਾਲ ਸਫ਼ਾ ਫਿੱਟ" + +#: ../../po/../src/verbs.cpp:2145 +msgid "Page _Width" +msgstr "ਸਫ਼ਾ ਚੌੜਾਈ(_W)" + +#: ../../po/../src/verbs.cpp:2146 +msgid "Zoom to fit page width in window" +msgstr "ਝਰੋਖੇ ਵਿੱਚ ਜ਼ੂਮ ਨਾਲ ਸਫ਼ਾ ਚੌੜਾਈ ਫਿੱਟ" + +#: ../../po/../src/verbs.cpp:2148 +msgid "Zoom to fit drawing in window" +msgstr "ਝਰੋਖੇ ਵਿੱਚ ਜ਼ੂਮ ਨਾਲ ਡਰਾਇੰਗ ਫਿੱਟ" + +#: ../../po/../src/verbs.cpp:2150 +msgid "Zoom to fit selection in window" +msgstr "ਝਰੋਖੇ ਵਿੱਚ ਜ਼ੂਮ ਨਾਲ ਚੋਣ ਫਿੱਟ" + +#. Dialogs +#: ../../po/../src/verbs.cpp:2153 +msgid "In_kscape Preferences..." +msgstr "ਇੰਕਸਕੇਪੀ ਪਸੰਦ(_k)..." + +#: ../../po/../src/verbs.cpp:2154 +msgid "Global Inkscape preferences" +msgstr "ਗਲੋਬਲ ਇੰਕਸਕੇਪੀ ਪਸੰਦ" + +#: ../../po/../src/verbs.cpp:2155 +msgid "_Document Preferences..." +msgstr "ਦਸਤਾਵੇਜ਼ ਪਸੰਦ(_D)..." + +#: ../../po/../src/verbs.cpp:2156 +msgid "Preferences saved with the document" +msgstr "ਦਸਤਾਵੇਜ਼ ਨਾਲ ਪਸੰਦ ਸੰਭਾਲੋ" + +#: ../../po/../src/verbs.cpp:2157 +msgid "_Fill and Stroke..." +msgstr "ਭਰਨ ਅਤੇ ਛੋਹ(_F)..." + +#: ../../po/../src/verbs.cpp:2158 +msgid "Fill and Stroke dialog" +msgstr "ਭਰਨ ਅਤੇ ਛੋਹ ਵਾਰਤਾਲਾਪ" + +#. TRANSLATORS: "Swatches" means: color samples +#: ../../po/../src/verbs.cpp:2160 +msgid "S_watches..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2161 +msgid "View color swatches" +msgstr "" + +#: ../../po/../src/verbs.cpp:2162 +msgid "Transfor_m..." +msgstr "ਤਬਦੀਲ(_m)..." + +#: ../../po/../src/verbs.cpp:2163 +msgid "Transform dialog" +msgstr "ਤਬਦੀਲ ਵਾਰਤਾਲਾਪ" + +#: ../../po/../src/verbs.cpp:2164 +msgid "_Align and Distribute..." +msgstr "ਇਕਸਾਰ ਅਤੇ ਵੰਡ(_A)..." + +#: ../../po/../src/verbs.cpp:2165 +msgid "Align and Distribute dialog" +msgstr "ਇਕਸਾਰ ਅਤੇ ਵੰਡਣ ਵਾਰਤਾਲਾਪ" + +#: ../../po/../src/verbs.cpp:2166 +msgid "_Text and Font..." +msgstr "ਪਾਠ ਅਤੇ ਫੋਂਟ(_T)..." + +#: ../../po/../src/verbs.cpp:2167 +msgid "Text and Font dialog" +msgstr "ਪਾਠ ਅਤੇ ਫੋਂਟ ਵਾਰਤਾਲਾਪ" + +#: ../../po/../src/verbs.cpp:2168 +msgid "_XML Editor..." +msgstr "_XML ਸੰਪਾਦਕ..." + +#: ../../po/../src/verbs.cpp:2169 +msgid "XML Editor" +msgstr "XML ਸੰਪਾਦਕ" + +#: ../../po/../src/verbs.cpp:2170 +msgid "_Find..." +msgstr "ਖੋਜ(_F)..." + +#: ../../po/../src/verbs.cpp:2171 +msgid "Find objects in document" +msgstr "ਦਸਤਾਵੇਜ਼ ਵਿੱਚ ਇਕਾਈਆਂ ਖੋਜੋ" + +#: ../../po/../src/verbs.cpp:2172 +msgid "_Messages..." +msgstr "ਸੁਨੇਹੇ(_M)..." + +#: ../../po/../src/verbs.cpp:2173 +msgid "View debug messages" +msgstr "ਡੀਬੱਗ ਸੁਨੇਹੇ ਵੇਖਾਓ" + +#: ../../po/../src/verbs.cpp:2174 +msgid "S_cripts..." +msgstr "ਸਕਰਿਪਟਾਂ(_c)..." + +#: ../../po/../src/verbs.cpp:2175 +msgid "Run scripts" +msgstr "ਸਕਰਿਪਟਾਂ ਚਲਾਓ" + +#: ../../po/../src/verbs.cpp:2176 +msgid "Show/Hide D_ialogs" +msgstr "ਵਾਰਤਾਲਾਪ ਵੇਖਾਓ/ਓਹਲੇ(_i)" + +#: ../../po/../src/verbs.cpp:2177 +msgid "Show or hide all active dialogs" +msgstr "ਸਭ ਸਰਗਰਮ ਵਾਰਤਾਲਾਪ ਵੇਖਾਓ ਜਾਂ ਓਹਲੇ" + +#. TRANSLATORS: "Tile clones" means: "Create tiled clones" +#: ../../po/../src/verbs.cpp:2179 +msgid "Tile clones..." +msgstr "ਟਾਇਲ ਸਮਰੂਪ..." + +#: ../../po/../src/verbs.cpp:2180 +msgid "Create and arrange multiple clones of selection" +msgstr "ਚੋਣ ਦੇ ਬਹੁ-ਸਮਰੂਪ ਬਣਾਓ ਅਤੇ ਟਿਕਾਓ" + +#: ../../po/../src/verbs.cpp:2181 +msgid "_Object Properties..." +msgstr "ਇਕਾਈ ਵਿਸ਼ੇਸਤਾ(_O)..." + +#: ../../po/../src/verbs.cpp:2182 +msgid "Object Properties dialog" +msgstr "ਇਕਾਈ ਵਿਸ਼ੇਸਤਾ ਵਾਰਤਾਲਾਪ" + +#: ../../po/../src/verbs.cpp:2185 +msgid "_Connect to Jabber server..." +msgstr "ਜੱਬਰ ਸਰਵਰ ਨਾਲ ਜੁੜੋ(_C)..." + +#: ../../po/../src/verbs.cpp:2185 +msgid "Connect to a Jabber server" +msgstr "" + +#: ../../po/../src/verbs.cpp:2187 +msgid "Share with _user..." +msgstr "ਉਪਭੋਗੀ ਨਾਲ ਸਾਂਝੀ(_u)..." + +#: ../../po/../src/verbs.cpp:2187 +msgid "Establish a whiteboard session with another Jabber user" +msgstr "" + +#: ../../po/../src/verbs.cpp:2189 +msgid "Share with _chatroom..." +msgstr "ਗੱਲਬਾਤ-ਰੂਪ ਨਾਲ ਸਾਂਝ(_c)..." + +#: ../../po/../src/verbs.cpp:2189 +msgid "" +"Join a chatroom to start a new whiteboard session or join one in progress" +msgstr "" + +#: ../../po/../src/verbs.cpp:2191 +msgid "_Dump XML node tracker" +msgstr "" + +#: ../../po/../src/verbs.cpp:2191 +msgid "Dump the contents of the XML tracker to the console" +msgstr "" + +#: ../../po/../src/verbs.cpp:2193 +msgid "_Open session file..." +msgstr "ਅਜਲਾਸ ਫਾਇਲ ਖੋਲੋ(_O)..." + +#: ../../po/../src/verbs.cpp:2193 +msgid "Open and browse through records of past whiteboard sessions" +msgstr "" + +#: ../../po/../src/verbs.cpp:2195 +msgid "Session file playback" +msgstr "ਅਜਲਾਸ ਫਾਇਲ ਚਲਾਓ" + +#: ../../po/../src/verbs.cpp:2197 +msgid "_Disconnect from session" +msgstr "" + +#: ../../po/../src/verbs.cpp:2199 +msgid "Disconnect from _server" +msgstr "" + +#: ../../po/../src/verbs.cpp:2201 +msgid "_Input Devices..." +msgstr "ਇੰਪੁੱਟ ਜੰਤਰ(_I)..." + +#: ../../po/../src/verbs.cpp:2202 +msgid "Configure extended input devices" +msgstr "ਹੋਰ ਇੰਪੁੱਟ ਜੰਤਰ ਸੰਰਚਨਾ" + +#. Help +#: ../../po/../src/verbs.cpp:2205 +msgid "_Keys and Mouse" +msgstr "ਸਵਿੱਚਾਂ ਅਤੇ ਮਾਊਂਸ(_K)" + +#: ../../po/../src/verbs.cpp:2206 +msgid "Key and mouse shortcuts reference" +msgstr "ਸਵਿੱਚ ਅਤੇ ਮਾਊਸ ਸ਼ਾਰਟਕੱਟ ਹਵਾਲਾ" + +#: ../../po/../src/verbs.cpp:2207 +msgid "About E_xtensions" +msgstr "ਸਹਿਯੋਗੀਆਂ ਬਾਰੇ(_x)" + +#: ../../po/../src/verbs.cpp:2208 +msgid "About Extensions..." +msgstr "ਸਹਿਯੋਗੀਆਂ ਬਾਰੇ..." + +#: ../../po/../src/verbs.cpp:2209 +msgid "About _Memory" +msgstr "ਮੈਮੋਰੀ ਬਾਰੇ(_M)" + +#: ../../po/../src/verbs.cpp:2210 +msgid "About Memory..." +msgstr "ਮੈਮੋਰੀ ਬਾਰੇ..." + +#: ../../po/../src/verbs.cpp:2211 +msgid "_About Inkscape" +msgstr "ਇੰਕਸਕੇਪੀ ਬਾਰੇ(_A)" + +#. "help_about" +#. new HelpVerb(SP_VERB_SHOW_LICENSE, "ShowLicense", N_("Modifying or Redistributing Inkscape"), +#. N_("Show license to modify and/or redistribute Inkscape: GNU GPL"), NULL), +#. Tutorials +#: ../../po/../src/verbs.cpp:2217 +msgid "Inkscape: _Basic" +msgstr "ਇੰਕਸਕੇਪੀ: ਮੂਲ(_B)" + +#: ../../po/../src/verbs.cpp:2218 +msgid "Getting started with Inkscape" +msgstr "ਇੰਕਸਕੇਪੀ ਨਾਲ ਸ਼ੁਰੂ ਕਰੋ" + +#. "tutorial_basic" +#: ../../po/../src/verbs.cpp:2219 +msgid "Inkscape: _Shapes" +msgstr "ਇੰਕਸਕੇਪੀ: ਸ਼ਕਲਾਂ(_S)" + +#: ../../po/../src/verbs.cpp:2220 +msgid "Using shape tools to create and edit shapes" +msgstr "ਸ਼ਕਲਾਂ ਬਣਾਉਣ ਅਤੇ ਸੋਧ ਲਈ ਸ਼ਕਲ ਸੰਦ ਵਰਤੋਂ" + +#: ../../po/../src/verbs.cpp:2221 +msgid "Inkscape: _Advanced" +msgstr "ਇੰਕਸਕੇਪੀ: ਤਕਨੀਕੀ(_A)" + +#: ../../po/../src/verbs.cpp:2222 +msgid "Advanced Inkscape topics" +msgstr "ਤਕਨੀਕੀ ਇੰਕਸਕੇਪੀ ਵਿਸ਼ੇ" + +#. "tutorial_advanced" +#. TRANSLATORS: "to trace" means "to convert a bitmap to vector graphics" (to vectorize) +#: ../../po/../src/verbs.cpp:2224 +msgid "Inkscape: T_racing" +msgstr "ਇੰਨਸਕੇਪੀ: ਟਰੇਸ(_r)" + +#: ../../po/../src/verbs.cpp:2225 +msgid "Using bitmap tracing" +msgstr "ਬਿੱਟਮੈਪ ਟਰੇਸਿੰਗ ਵਰਤੋਂ" + +#. "tutorial_tracing" +#: ../../po/../src/verbs.cpp:2226 +msgid "Inkscape: _Calligraphy" +msgstr "ਇੰਕਸਕੇਪੀ: ਕੈਲੀਗਰਾਫ਼ੀ(_C)" + +#: ../../po/../src/verbs.cpp:2227 +msgid "Using the Calligraphy pen tool" +msgstr "ਕੈਲੀਗਰਾਫ਼ੀ ਪੈਨ ਸੰਦ ਦੀ ਵਰਤੋਂ ਕਰਕੇ" + +#: ../../po/../src/verbs.cpp:2228 +msgid "_Elements of Design" +msgstr "ਡਿਜ਼ਾਈਨ ਦੀਆਂ ਇਕਾਈਆਂ(_E)" + +#: ../../po/../src/verbs.cpp:2229 +msgid "Principles of design in the tutorial form" +msgstr "" + +#. "tutorial_design" +#: ../../po/../src/verbs.cpp:2230 +msgid "_Tips and Tricks" +msgstr "ਸੰਕੇਤ ਅਤੇ ਇਸ਼ਾਰੇ(_T)" + +#: ../../po/../src/verbs.cpp:2231 +msgid "Miscellaneous tips and tricks" +msgstr "ਫੁਟਕਲ ਇਸ਼ਾਰੇ ਅਤੇ ਸੰਕੇਤ" + +#. "tutorial_tips" +#. Effect +#: ../../po/../src/verbs.cpp:2234 +msgid "Previous Effect" +msgstr "ਪਿਛਲਾ ਪਰਭਾਵ" + +#: ../../po/../src/verbs.cpp:2235 +msgid "Repeat the last effect with the same settings" +msgstr "ਇਸੇ ਸਥਾਪਨ ਨਾਲ ਆਖਰੀ ਪਰਭਾਵ ਦੁਹਰਾਓ" + +#. "tutorial_tips" +#: ../../po/../src/verbs.cpp:2236 +msgid "Previous Effect Settings..." +msgstr "ਪਿਛਲੀ ਪਰਭਾਵ ਵਿਵਸਥਾ..." + +#: ../../po/../src/verbs.cpp:2237 +msgid "Repeat the last effect with new settings" +msgstr "ਨਵੀਂ ਵਿਵਸਥਾ ਵਿੱਚ ਆਖਰੀ ਪਰਭਾਵ ਦੁਹਰਾਓ" + +#: ../../po/../src/widgets/dash-selector.cpp:106 +msgid "Dash pattern" +msgstr "ਧੱਬੀਦਾਰ ਤਰਤੀਬ" + +#: ../../po/../src/widgets/dash-selector.cpp:121 +msgid "Pattern offset" +msgstr "ਤਰਤੀਬ ਅੰਤਰਲੰਬ" + +#: ../../po/../src/widgets/desktop-widget.cpp:240 +msgid "Zoom drawing if window size changes" +msgstr "ਜੇਕਰ ਝਰੋਖੇ ਦਾ ਅਕਾਰ ਬਦਲ ਤਾਂ ਡਰਾਇੰਗ ਜ਼ੂਮ" + +#: ../../po/../src/widgets/desktop-widget.cpp:298 +msgid "Cursor coordinates" +msgstr "ਕਰਸਰ ਧੁਰੇ" + +#. display the initial welcome message in the statusbar +#: ../../po/../src/widgets/desktop-widget.cpp:324 +msgid "" +"Welcome to Inkscape! Use shape or freehand tools to create objects; " +"use selector (arrow) to move or transform them." +msgstr "" +"ਇੰਕਸਕੇਪੀ ਵਲੋਂ ਜੀ ਆਇਆਂ ਨੂੰ! ਇਕਾਈਆਂ ਬਣਾਉਣ ਲਈ ਸ਼ਕਲ ਜਾਂ ਹੱਥਲੀ ਸੰਦ ਦੀ ਵਰਤੋਂ; ਏਧਰ ਓਧਰ ਕਰਨ " +"ਜਾਂ ਤਬਦੀਲ ਕਰਨ ਲਈ ਤੀਰ ਵਰਤੋਂ।" + +#: ../../po/../src/widgets/desktop-widget.cpp:372 +#, c-format +msgid "%s: %d - Inkscape" +msgstr "%s: %d - ਇੰਕਸਕੇਪੀ" + +#: ../../po/../src/widgets/desktop-widget.cpp:374 +#, c-format +msgid "%s - Inkscape" +msgstr "%s - ਇੰਕਸਕੇਪੀ" + +#: ../../po/../src/widgets/desktop-widget.cpp:532 +#, c-format +msgid "" +"Save changes to document \"%s\" before " +"closing?\n" +"\n" +"If you close without saving, your changes will be discarded." +msgstr "" + +#: ../../po/../src/widgets/desktop-widget.cpp:548 +#: ../../po/../src/widgets/desktop-widget.cpp:612 +msgid "Close _without saving" +msgstr "ਬਿਨਾਂ ਸੰਭਾਲੇ ਬੰਦ(_w)" + +#: ../../po/../src/widgets/desktop-widget.cpp:595 +#, c-format +msgid "" +"The file \"%s\" was saved with a " +"format (%s) that may cause data loss!\n" +"\n" +"Do you want to save this file in another format?" +msgstr "" + +#. Family frame +#: ../../po/../src/widgets/font-selector.cpp:156 +msgid "Font family" +msgstr "ਫੋਂਟ ਵਰਗ" + +#. Style frame +#: ../../po/../src/widgets/font-selector.cpp:184 +msgid "Style" +msgstr "ਸ਼ੈਲੀ" + +#: ../../po/../src/widgets/font-selector.cpp:219 +msgid "Font size:" +msgstr "ਫੋਂਟ ਆਕਾਰ:" + +#. TRANSLATORS: Test string used in text and font dialog (when no +#. * text has been entered) to get a preview of the font. Choose +#. * some representative characters that users of your locale will be +#. * interested in. +#: ../../po/../src/widgets/font-selector.cpp:554 +msgid "AaBbCcIiPpQq12368.;/()" +msgstr "AaBbCcIiPpQq12368.;/()" + +#: ../../po/../src/widgets/gradient-selector.cpp:137 +#: ../../po/../src/widgets/gradient-toolbar.cpp:524 +msgid "Duplicate" +msgstr "ਦੋਹਰੀ" + +#: ../../po/../src/widgets/gradient-selector.cpp:142 +#: ../../po/../src/widgets/gradient-toolbar.cpp:535 +msgid "Edit..." +msgstr "ਸੋਧ..." + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/pservers.html#LinearGradientSpreadMethodAttribute +#: ../../po/../src/widgets/gradient-selector.cpp:159 +msgid "" +"Whether to fill with flat color beyond the ends of the gradient vector " +"(spreadMethod=\"pad\"), or repeat the gradient in the same direction " +"(spreadMethod=\"repeat\"), or repeat the gradient in alternating opposite " +"directions (spreadMethod=\"reflect\")" +msgstr "" + +#: ../../po/../src/widgets/gradient-selector.cpp:165 +msgid "none" +msgstr "ਕੋਈ ਨਹੀਂ" + +#: ../../po/../src/widgets/gradient-selector.cpp:169 +msgid "reflected" +msgstr "ਪਰਿਵਰਤਤ" + +#: ../../po/../src/widgets/gradient-selector.cpp:173 +msgid "direct" +msgstr "ਸਿੱਧਾ" + +#: ../../po/../src/widgets/gradient-selector.cpp:181 +msgid "Repeat:" +msgstr "ਦੁਹਰਾਓ:" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:217 +msgid "No gradients" +msgstr "ਕੋਈ ਢਾਲਵਾਂ ਨਹੀਂ" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:226 +msgid "Nothing selected" +msgstr "ਕੁਝ ਵੀ ਚੁਣਿਆ ਨਹੀਂ" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:237 +msgid "No gradients in selection" +msgstr "ਚੋਣ ਵਿੱਚ ਕੋਈ ਢਾਲਵਾਂ ਨਹੀਂ" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:247 +msgid "Multiple gradients" +msgstr "ਬਹੁ ਢਾਲਵਾਂ" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:525 +msgid "" +"If the gradient is used by more than one object, create a copy of it for the " +"selected object(s)" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:536 +msgid "Edit the stops of the gradient" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:593 +#: ../../po/../src/widgets/toolbox.cpp:1103 +#: ../../po/../src/widgets/toolbox.cpp:1192 +#: ../../po/../src/widgets/toolbox.cpp:1485 +#: ../../po/../src/widgets/toolbox.cpp:1534 +#: ../../po/../src/widgets/toolbox.cpp:1766 +#: ../../po/../src/widgets/toolbox.cpp:1801 +#: ../../po/../src/widgets/toolbox.cpp:2331 +#: ../../po/../src/widgets/toolbox.cpp:2370 +msgid "New:" +msgstr "ਨਵਾਂ:" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:606 +msgid "Create linear gradient" +msgstr "ਰੇਖਿਕ ਢਾਲਵਾਂ ਬਣਾਓ" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:620 +msgid "Create radial (elliptic or circular) gradient" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:635 +msgid "on" +msgstr "ਚਾਲੂ" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:648 +msgid "Create gradient in the fill" +msgstr "ਭਰਨ ਵਿੱਚ ਢਾਲਵਾਂ ਬਣਾਓ" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:662 +msgid "Create gradient in the stroke" +msgstr "ਛੋਹ ਵਿੱਚ ਢਾਲਵਾਂ ਬਣਾਓ" + +#. FIXME: implement averaging of all parameters for multiple selected stars +#. gtk_label_set_markup(GTK_LABEL(l), _("Average:")); +#. FIXME: implement averaging of all parameters for multiple selected +#. gtk_label_set_markup(GTK_LABEL(l), _("Average:")); +#: ../../po/../src/widgets/gradient-toolbar.cpp:676 +#: ../../po/../src/widgets/toolbox.cpp:1105 +#: ../../po/../src/widgets/toolbox.cpp:1124 +#: ../../po/../src/widgets/toolbox.cpp:1493 +#: ../../po/../src/widgets/toolbox.cpp:1518 +#: ../../po/../src/widgets/toolbox.cpp:1768 +#: ../../po/../src/widgets/toolbox.cpp:1787 +#: ../../po/../src/widgets/toolbox.cpp:2334 +#: ../../po/../src/widgets/toolbox.cpp:2354 +msgid "Change:" +msgstr "ਤਬਦੀਲ:" + +#: ../../po/../src/widgets/gradient-vector.cpp:269 +msgid "No gradients in document" +msgstr "ਦਸਤਾਵੇਜ਼ ਵਿੱਚ ਕੋਈ ਢਾਲਵਾਂ ਨਹੀਂ" + +#: ../../po/../src/widgets/gradient-vector.cpp:275 +msgid "No gradient selected" +msgstr "ਕੋਈ ਢਾਲਵਾਂ ਨਹੀਂ ਚੁਣਿਆ" + +#: ../../po/../src/widgets/gradient-vector.cpp:532 +msgid "No stops in gradient" +msgstr "ਢਾਲਵੇਂ ਵਿੱਚ ਕੋਈ ਰੋਕ ਨਹੀਂ" + +#. TRANSLATORS: "Stop" means: a "phase" of a gradient +#: ../../po/../src/widgets/gradient-vector.cpp:794 +msgid "Add stop" +msgstr "ਰੋਕ ਜੋੜੋ" + +#: ../../po/../src/widgets/gradient-vector.cpp:797 +msgid "Add another control stop to gradient" +msgstr "ਢਾਲਵੇਂ ਵਿੱਚ ਹੋਰ ਕੰਟਰੋਲ ਰੋਕ ਜੋੜੋ" + +#: ../../po/../src/widgets/gradient-vector.cpp:799 +msgid "Delete stop" +msgstr "ਰੋਕ ਹਟਾਓ" + +#: ../../po/../src/widgets/gradient-vector.cpp:802 +msgid "Delete current control stop from gradient" +msgstr "ਢਾਲਵੇਂ ਤੋਂ ਮੌਜੂਦਾ ਕੰਟਰੋਲ ਰੋਕ ਹਟਾਓ" + +#. Label +#: ../../po/../src/widgets/gradient-vector.cpp:813 +msgid "Offset:" +msgstr "ਅੰਤਰਲੰਬ :" + +#. TRANSLATORS: "Stop" means: a "phase" of a gradient +#: ../../po/../src/widgets/gradient-vector.cpp:858 +msgid "Stop Color" +msgstr "ਰੰਗ ਰੋਕੋ" + +#: ../../po/../src/widgets/gradient-vector.cpp:887 +msgid "Gradient editor" +msgstr "ਢਾਲਵਾਂ ਸੰਪਾਦਕ" + +#: ../../po/../src/widgets/layer-selector.cpp:119 +msgid "Toggle current layer visibility" +msgstr "ਮੌਜੂਦਾ ਪਰਤ ਦੀ ਦਿੱਖ ਤਬਦੀਲ" + +#: ../../po/../src/widgets/layer-selector.cpp:139 +msgid "Lock or unlock current layer" +msgstr "ਮੌਜੂਦਾ ਪਰਤ ਤਾਲਾਬੰਦ ਜਾਂ ਖੋਲੋ" + +#: ../../po/../src/widgets/layer-selector.cpp:142 +msgid "Current layer" +msgstr "ਮੌਜੂਦਾ ਪਰਤ" + +#: ../../po/../src/widgets/layer-selector.cpp:553 +msgid "(root)" +msgstr "(root)" + +#: ../../po/../src/widgets/paint-selector.cpp:182 +#: ../../po/../src/widgets/paint-selector.cpp:561 +msgid "No paint" +msgstr "ਕੋਈ ਪੇਂਟ ਨਹੀਂ" + +#: ../../po/../src/widgets/paint-selector.cpp:184 +#: ../../po/../src/widgets/paint-selector.cpp:629 +msgid "Flat color" +msgstr "ਸਮਤਲ ਰੰਗ" + +#: ../../po/../src/widgets/paint-selector.cpp:186 +#: ../../po/../src/widgets/paint-selector.cpp:696 +msgid "Linear gradient" +msgstr "ਰੇਖਿਕ ਢਾਲਵਾਂ" + +#: ../../po/../src/widgets/paint-selector.cpp:188 +#: ../../po/../src/widgets/paint-selector.cpp:699 +msgid "Radial gradient" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:192 +msgid "Unset paint (make it undefined so it can be inherited)" +msgstr "" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/painting.html#FillRuleProperty +#: ../../po/../src/widgets/paint-selector.cpp:204 +msgid "" +"Any path self-intersections or subpaths create holes in the fill (fill-rule: " +"evenodd)" +msgstr "" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/painting.html#FillRuleProperty +#: ../../po/../src/widgets/paint-selector.cpp:215 +msgid "" +"Fill is solid unless a subpath is counterdirectional (fill-rule: nonzero)" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:528 +msgid "No objects" +msgstr "ਕੋਈ ਇਕਾਈਆਂ ਨਹੀਂ" + +#: ../../po/../src/widgets/paint-selector.cpp:539 +msgid "Multiple styles" +msgstr "ਬਹੁ-ਸ਼ੈਲੀਆਂ" + +#: ../../po/../src/widgets/paint-selector.cpp:550 +msgid "Paint is undefined" +msgstr "ਪੇਂਟ ਨਾ-ਪਰਿਭਾਸ਼ਤ ਨਹੀਂ" + +#: ../../po/../src/widgets/paint-selector.cpp:757 +msgid "No patterns in document" +msgstr "ਦਸਤਾਵੇਜ਼ ਵਿੱਚ ਕੋਈ ਤਰਤੀਬ ਨਹੀਂ" + +#: ../../po/../src/widgets/paint-selector.cpp:872 +msgid "" +"Use Edit > Object(s) to Pattern to create a new pattern from " +"selection." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:426 +msgid "Now stroke width is scaled when objects are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:428 +msgid "Now stroke width is not scaled when objects are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:436 +msgid "" +"Now rounded rectangle corners are scaled when rectangles are " +"scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:438 +msgid "" +"Now rounded rectangle corners are not scaled when rectangles " +"are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:446 +msgid "" +"Now gradients are transformed along with their objects when " +"those are transformed (moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:448 +msgid "" +"Now gradients remain fixed when objects are transformed " +"(moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:456 +msgid "" +"Now patterns are transformed along with their objects when " +"those are transformed (moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:458 +msgid "" +"Now patterns remain fixed when objects are transformed (moved, " +"scaled, rotated, or skewed)." +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:506 +msgid "select_toolbar|X" +msgstr "X" + +#: ../../po/../src/widgets/select-toolbar.cpp:506 +msgid "Horizontal coordinate of selection" +msgstr "ਚੋਣ ਦਾ ਖਿਤਿਜੀ ਧੁਰਾ" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:511 +msgid "select_toolbar|Y" +msgstr "Y" + +#: ../../po/../src/widgets/select-toolbar.cpp:511 +msgid "Vertical coordinate of selection" +msgstr "ਚੋਣ ਦਾ ਲੰਬਕਾਰੀ ਧੁਰਾ" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:517 +msgid "select_toolbar|W" +msgstr "W" + +#: ../../po/../src/widgets/select-toolbar.cpp:517 +msgid "Width of selection" +msgstr "ਚੋਣ ਦੀ ਉਚਾਈ" + +#: ../../po/../src/widgets/select-toolbar.cpp:525 +msgid "Change both width and height by the same proportion" +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:534 +msgid "select_toolbar|H" +msgstr "H" + +#: ../../po/../src/widgets/select-toolbar.cpp:534 +msgid "Height of selection" +msgstr "ਚੋਣ ਦੀ ਉਚਾਈ" + +#: ../../po/../src/widgets/sp-color-gtkselector.cpp:62 +msgid "System" +msgstr "ਸਿਸਟਮ" + +#: ../../po/../src/widgets/sp-color-notebook.cpp:322 +msgid "RGBA_:" +msgstr "RGBA_:" + +#: ../../po/../src/widgets/sp-color-notebook.cpp:330 +msgid "Hexadecimal RGBA value of the color" +msgstr "ਰੰਗ ਹੈਕਸਾ-ਡੈਸੀਮਲ RGBA ਮੁੱਲ" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "RGB" +msgstr "RGB" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "HSL" +msgstr "HSL" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "CMYK" +msgstr "CMYK" + +#: ../../po/../src/widgets/sp-color-scales.cpp:397 +msgid "_R" +msgstr "_R" + +#: ../../po/../src/widgets/sp-color-scales.cpp:398 +#: ../../po/../src/widgets/sp-color-scales.cpp:399 +msgid "Red" +msgstr "ਲਾਲ" + +#: ../../po/../src/widgets/sp-color-scales.cpp:400 +msgid "_G" +msgstr "_G" + +#: ../../po/../src/widgets/sp-color-scales.cpp:401 +#: ../../po/../src/widgets/sp-color-scales.cpp:402 +msgid "Green" +msgstr "ਹਰਾ" + +#: ../../po/../src/widgets/sp-color-scales.cpp:403 +msgid "_B" +msgstr "_B" + +#: ../../po/../src/widgets/sp-color-scales.cpp:404 +#: ../../po/../src/widgets/sp-color-scales.cpp:405 +msgid "Blue" +msgstr "ਨੀਲਾ" + +#. Label +#: ../../po/../src/widgets/sp-color-scales.cpp:406 +#: ../../po/../src/widgets/sp-color-scales.cpp:432 +#: ../../po/../src/widgets/sp-color-scales.cpp:463 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:141 +msgid "_A" +msgstr "_A" + +#: ../../po/../src/widgets/sp-color-scales.cpp:407 +#: ../../po/../src/widgets/sp-color-scales.cpp:408 +#: ../../po/../src/widgets/sp-color-scales.cpp:433 +#: ../../po/../src/widgets/sp-color-scales.cpp:434 +#: ../../po/../src/widgets/sp-color-scales.cpp:464 +#: ../../po/../src/widgets/sp-color-scales.cpp:465 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:151 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:163 +msgid "Alpha (opacity)" +msgstr "ਐਲਫਾ (ਧੁੰਦਲਾ)" + +#: ../../po/../src/widgets/sp-color-scales.cpp:423 +msgid "_H" +msgstr "_H" + +#: ../../po/../src/widgets/sp-color-scales.cpp:424 +#: ../../po/../src/widgets/sp-color-scales.cpp:425 +msgid "Hue" +msgstr "ਰੰਗਤ" + +#: ../../po/../src/widgets/sp-color-scales.cpp:426 +msgid "_S" +msgstr "_S" + +#: ../../po/../src/widgets/sp-color-scales.cpp:427 +#: ../../po/../src/widgets/sp-color-scales.cpp:428 +msgid "Saturation" +msgstr "ਸੰਤਰਿਪਤੀ" + +#: ../../po/../src/widgets/sp-color-scales.cpp:429 +msgid "_L" +msgstr "_L" + +#: ../../po/../src/widgets/sp-color-scales.cpp:430 +#: ../../po/../src/widgets/sp-color-scales.cpp:431 +msgid "Lightness" +msgstr "ਪਰਕਾਸ਼ਵੰਨਤਾ" + +#: ../../po/../src/widgets/sp-color-scales.cpp:451 +msgid "_C" +msgstr "_C" + +#: ../../po/../src/widgets/sp-color-scales.cpp:452 +#: ../../po/../src/widgets/sp-color-scales.cpp:453 +msgid "Cyan" +msgstr "ਨੀਲਾ" + +#: ../../po/../src/widgets/sp-color-scales.cpp:454 +msgid "_M" +msgstr "_M" + +#: ../../po/../src/widgets/sp-color-scales.cpp:455 +#: ../../po/../src/widgets/sp-color-scales.cpp:456 +msgid "Magenta" +msgstr "ਮੈਜ਼ੀਨਟਾ" + +#: ../../po/../src/widgets/sp-color-scales.cpp:457 +msgid "_Y" +msgstr "_Y" + +#: ../../po/../src/widgets/sp-color-scales.cpp:458 +#: ../../po/../src/widgets/sp-color-scales.cpp:459 +msgid "Yellow" +msgstr "ਪੀਲਾ" + +#: ../../po/../src/widgets/sp-color-scales.cpp:460 +msgid "_K" +msgstr "_K" + +#: ../../po/../src/widgets/sp-color-selector.cpp:71 +msgid "Unnamed" +msgstr "ਬੇ-ਨਾਂ" + +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:68 +msgid "Wheel" +msgstr "ਪਹੀਆ" + +#: ../../po/../src/widgets/sp-xmlview-attr-list.cpp:53 +msgid "Attribute" +msgstr "ਗੁਣ" + +#: ../../po/../src/widgets/sp-xmlview-attr-list.cpp:54 +msgid "Value" +msgstr "ਮੁੱਲ" + +#: ../../po/../src/widgets/toolbox.cpp:424 +msgid "Insert new nodes into selected segments" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:426 +msgid "Delete selected nodes" +msgstr "ਚੁਣੀਆਂ ਨੋਡਾਂ ਹਟਾਓ" + +#: ../../po/../src/widgets/toolbox.cpp:431 +msgid "Join paths at selected nodes" +msgstr "ਚੁਣੇ ਨੋਡਾਂ ਉਤੇ ਮਾਰਗ ਜੋੜੋ" + +#: ../../po/../src/widgets/toolbox.cpp:433 +msgid "Join paths at selected nodes with new segment" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:436 +msgid "Split path between two non-endpoint nodes" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:439 +msgid "Break path at selected nodes" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:444 +msgid "Make selected nodes corner" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:447 +msgid "Make selected nodes smooth" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:450 +msgid "Make selected nodes symmetric" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:455 +msgid "Make selected segments lines" +msgstr "ਚੁਣੇ ਖੰਡਾਂ ਦੀਆਂ ਰੇਖਾਵਾਂ ਬਣਾਓ" + +#: ../../po/../src/widgets/toolbox.cpp:458 +msgid "Make selected segments curves" +msgstr "ਚੁਣੇ ਖੰਡਾਂ ਨੂੰ ਗੋਲ ਬਣਾਓ" + +#: ../../po/../src/widgets/toolbox.cpp:1199 +msgid "Polygon" +msgstr "ਬਹੁਭੁਜ" + +#: ../../po/../src/widgets/toolbox.cpp:1206 +msgid "Regular polygon (with one handle) instead of a star" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1218 +msgid "Corners:" +msgstr "ਕੋਨੇ:" + +#: ../../po/../src/widgets/toolbox.cpp:1218 +msgid "Number of corners of a polygon or star" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1228 +msgid "Spoke ratio:" +msgstr "" + +#. TRANSLATORS: Tip radius of a star is the distance from the center to the farthest handle. +#. Base radius is the same for the closest handle. +#: ../../po/../src/widgets/toolbox.cpp:1231 +msgid "Base radius to tip radius ratio" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1246 +msgid "Rounded:" +msgstr "ਗੋਲਾਈ:" + +#: ../../po/../src/widgets/toolbox.cpp:1246 +msgid "How much rounded are the corners (0 for sharp)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1256 +msgid "Randomized:" +msgstr "ਰਲਵਾਂ:" + +#: ../../po/../src/widgets/toolbox.cpp:1256 +msgid "Scatter randomly the corners and angles" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1269 +#: ../../po/../src/widgets/toolbox.cpp:1838 +#: ../../po/../src/widgets/toolbox.cpp:2061 +msgid "Defaults" +msgstr "ਮੂਲ" + +#: ../../po/../src/widgets/toolbox.cpp:1270 +#: ../../po/../src/widgets/toolbox.cpp:1839 +#: ../../po/../src/widgets/toolbox.cpp:2062 +msgid "" +"Reset shape parameters to defaults (use Inkscape Preferences > Tools to " +"change defaults)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1544 +msgid "W:" +msgstr "ਚੌ:" + +#: ../../po/../src/widgets/toolbox.cpp:1544 +msgid "Width of rectangle" +msgstr "ਚਤੁਰਭੁਜ ਦੀ ਚੌੜਾਈ" + +#: ../../po/../src/widgets/toolbox.cpp:1556 +msgid "Height of rectangle" +msgstr "ਚਤੁਰਭੁਜ ਦੀ ਉਚਾਈ" + +#: ../../po/../src/widgets/toolbox.cpp:1568 +msgid "Rx:" +msgstr "Rx:" + +#: ../../po/../src/widgets/toolbox.cpp:1568 +msgid "Horizontal radius of rounded corners" +msgstr "ਗੋਲ ਕਿਨਾਰਿਆਂ ਦਾ ਖਿਤਿਜੀ ਅਰਧ-ਵਿਆਸ" + +#: ../../po/../src/widgets/toolbox.cpp:1578 +msgid "Ry:" +msgstr "Ry:" + +#: ../../po/../src/widgets/toolbox.cpp:1578 +msgid "Vertical radius of rounded corners" +msgstr "ਗੋਲ ਕਿਨਾਰਿਆਂ ਦਾ ਲੰਬਕਾਰੀ ਅਰਧ-ਵਿਆਸ" + +#: ../../po/../src/widgets/toolbox.cpp:1594 +msgid "Not rounded" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1596 +msgid "Make corners sharp" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1805 +msgid "Turns:" +msgstr "ਚੱਕਰ:" + +#: ../../po/../src/widgets/toolbox.cpp:1805 +msgid "Number of revolutions" +msgstr "ਚੱਕਰਾਂ ਦੀ ਗਿਣਤੀ" + +#: ../../po/../src/widgets/toolbox.cpp:1815 +msgid "Divergence:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1815 +msgid "How much denser/sparser are outer revolutions; 1 = uniform" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1825 +msgid "Inner radius:" +msgstr "ਅੰਦਰੂਨੀ ਅਰਧ-ਵਿਆਸ:" + +#: ../../po/../src/widgets/toolbox.cpp:1825 +msgid "Radius of the innermost revolution (relative to the spiral size)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1957 +msgid "The width of the calligraphic pen (relative to the visible canvas area)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1967 +msgid "Thinning:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1967 +msgid "" +"How much velocity thins the stroke (> 0 makes fast strokes thinner, < 0 " +"makes them broader, 0 makes width independent of velocity)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1980 +msgid "Angle:" +msgstr "ਕੋਣ:" + +#: ../../po/../src/widgets/toolbox.cpp:1980 +msgid "" +"The angle of the pen's nib (in degrees; 0 = horizontal; has no effect if " +"fixation = 0)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1990 +msgid "Fixation:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1990 +msgid "" +"How fixed is the pen angle (0 = always perpendicular to stroke direction, 1 " +"= fixed)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2003 +msgid "Mass:" +msgstr "ਭਾਰ:" + +#: ../../po/../src/widgets/toolbox.cpp:2003 +msgid "How much inertia affects the movement of the pen" +msgstr "" + +#. TRANSLATORS: "drag" means "resistance" here +#: ../../po/../src/widgets/toolbox.cpp:2014 +msgid "Drag:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2014 +msgid "How much resistance affects the movement of the pen" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2034 +msgid "Use the pressure of the input device to alter the width of the pen" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2047 +msgid "Use the tilt of the input device to alter the angle of the pen's nib" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2374 +msgid "Start:" +msgstr "ਸ਼ੁਰੂ:" + +#: ../../po/../src/widgets/toolbox.cpp:2374 +msgid "The angle (in degrees) from the horizontal to the arc's start point" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2384 +msgid "End:" +msgstr "ਅੰਤ:" + +#: ../../po/../src/widgets/toolbox.cpp:2384 +msgid "The angle (in degrees) from the horizontal to the arc's end point" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2395 +msgid "Open arc" +msgstr "ਖੁੱਲੀ ਚਾਪ" + +#: ../../po/../src/widgets/toolbox.cpp:2396 +msgid "" +"Switch between arc (unclosed shape) and segment (closed shape with two radii)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2415 +msgid "Make whole" +msgstr "ਪੂਰਾ ਬਣਾਓ" + +#: ../../po/../src/widgets/toolbox.cpp:2417 +msgid "Make the shape a whole ellipse, not arc or segment" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2644 +msgid "" +"When pressed, picks visible color without alpha and when not pressed, picks " +"color including its alpha" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:3039 +#, fuzzy +msgid "Make connectors avoid selected objects" +msgstr "ਚੁਣੀਆਂ ਇਕਾਈਆਂ ਦੀ ਕਾਟ" + +#: ../../po/../src/widgets/toolbox.cpp:3043 +#, fuzzy +msgid "Make connectors ignore selected objects" +msgstr "ਚੁਣੀਆਂ ਇਕਾਈਆਂ ਦੀ ਕਾਟ" + +#. +#. 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 : +#: ../share/extensions/addnodes.inx.h:1 +#, fuzzy +msgid "Add Nodes" +msgstr "ਨੋਡਾਂ" + +#: ../share/extensions/addnodes.inx.h:2 +msgid "Maximum Segment Length" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:1 +msgid "AI Input" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:2 ../share/extensions/ai_output.inx.h:2 +msgid "Adobe Illustrator (*.ai)" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:3 +msgid "Open files saved with Adobe Illustrator" +msgstr "" + +#: ../share/extensions/ai_output.inx.h:1 +#, fuzzy +msgid "AI Output" +msgstr "ਆਉਟਪੁੱਟ" + +#: ../share/extensions/ai_output.inx.h:3 +msgid "Write Adobe Illustrator" +msgstr "" + +#: ../share/extensions/dia.inx.h:1 +msgid "A diagram created with the program Dia" +msgstr "" + +#: ../share/extensions/dia.inx.h:2 +msgid "Dia Diagram (*.dia)" +msgstr "" + +#: ../share/extensions/dia.inx.h:3 +msgid "Dia Input" +msgstr "" + +#: ../share/extensions/dia.inx.h:4 +msgid "" +"In order to import Dia files, Dia itself must be installed. You can get Dia " +"at http://www.gnome.org/projects/dia/" +msgstr "" + +#: ../share/extensions/dia.inx.h:5 +msgid "" +"The dia2svg.sh script should be installed with your Inkscape distribution. " +"If you do not have it, there is likely to be something wrong with your " +"Inkscape installation." +msgstr "" + +#: ../share/extensions/dots.inx.h:1 +#, fuzzy +msgid "Connect the Dots" +msgstr "ਨਿਰਮਾਤਾ" + +#: ../share/extensions/dots.inx.h:2 +#, fuzzy +msgid "Dot Size" +msgstr "ਅਕਾਰ" + +#: ../share/extensions/dots.inx.h:3 +#, fuzzy +msgid "Font Size" +msgstr "ਫੋਂਟ ਆਕਾਰ:" + +#: ../share/extensions/dropshadow.inx.h:1 +msgid "Color of shadow" +msgstr "" + +#: ../share/extensions/dropshadow.inx.h:2 +#, fuzzy +msgid "Dropshadow" +msgstr "ਸਫ਼ਾ ਛਾਂ ਵੇਖਾਓ" + +#: ../share/extensions/dxf_input.inx.h:1 +#: ../share/extensions/dxf_output.inx.h:1 +msgid "AutoCAD DXF (*.dxf)" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:2 +msgid "DXF Input" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:3 +msgid "Import AutoCAD's Document Exchange Format" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:4 +msgid "" +"dxf2svg may come with Inkscape, but is also at http://dxf-svg-convert." +"sourceforge.net/" +msgstr "" + +#: ../share/extensions/dxf_output.inx.h:2 +#, fuzzy +msgid "DXF Output" +msgstr "ਆਉਟਪੁੱਟ" + +#: ../share/extensions/dxf_output.inx.h:3 +msgid "DXF file written by pstoedit" +msgstr "" + +#: ../share/extensions/dxf_output.inx.h:4 +msgid "pstoedit must be installed to run see http://www.pstoedit.net/pstoedit" +msgstr "" + +#: ../share/extensions/embedimage.inx.h:1 +#, fuzzy +msgid "Embed Images" +msgstr "ਚਿੱਤਰ" + +#: ../share/extensions/eps_input.inx.h:1 +msgid "EPS Input" +msgstr "" + +#: ../share/extensions/eps_input.inx.h:2 +msgid "Encapsulated Postscript" +msgstr "" + +#: ../share/extensions/eps_input.inx.h:3 +msgid "Encapsulated Postscript (*.eps)" +msgstr "" + +#: ../share/extensions/epsi_output.inx.h:1 +#, fuzzy +msgid "EPSI Output" +msgstr "ਆਉਟਪੁੱਟ" + +#: ../share/extensions/epsi_output.inx.h:2 +msgid "Encapsulated Postscript Interchange (*.epsi)" +msgstr "" + +#: ../share/extensions/epsi_output.inx.h:3 +msgid "Encapsulated Postscript with a thumbnail" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:1 ../share/extensions/ffms.inx.h:1 +#: ../share/extensions/ffset.inx.h:1 ../share/extensions/ffss.inx.h:1 +#, fuzzy +msgid "Bridge Width" +msgstr "ਰੇਖਾ ਚੌੜਾਈ" + +#: ../share/extensions/ffmet.inx.h:2 ../share/extensions/ffms.inx.h:2 +msgid "First String Length" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:3 +msgid "FretFind Multi Length ET" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:4 ../share/extensions/ffms.inx.h:4 +#: ../share/extensions/ffset.inx.h:3 ../share/extensions/ffss.inx.h:3 +msgid "Fretboard Edges" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:5 ../share/extensions/ffms.inx.h:5 +msgid "Last String Length" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:6 ../share/extensions/ffms.inx.h:6 +#: ../share/extensions/ffset.inx.h:4 ../share/extensions/ffss.inx.h:4 +#, fuzzy +msgid "Number of Frets" +msgstr "ਕਤਾਰਾਂ ਦੀ ਗਿਣਤੀ" + +#: ../share/extensions/ffmet.inx.h:7 ../share/extensions/ffms.inx.h:7 +#: ../share/extensions/ffset.inx.h:5 ../share/extensions/ffss.inx.h:5 +#, fuzzy +msgid "Number of Strings" +msgstr "ਕਤਾਰਾਂ ਦੀ ਗਿਣਤੀ" + +#: ../share/extensions/ffmet.inx.h:8 ../share/extensions/ffms.inx.h:8 +#: ../share/extensions/ffset.inx.h:6 ../share/extensions/ffss.inx.h:6 +#, fuzzy +msgid "Nut Width" +msgstr "ਚੌਡ਼ਾਈ" + +#: ../share/extensions/ffmet.inx.h:9 ../share/extensions/ffms.inx.h:10 +msgid "Perpendicular Distance" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:10 ../share/extensions/ffset.inx.h:7 +msgid "Scale Base (2 for Octave)" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:11 ../share/extensions/ffset.inx.h:9 +msgid "Tones in Scale" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:12 ../share/extensions/ffms.inx.h:12 +#: ../share/extensions/ffset.inx.h:10 ../share/extensions/ffss.inx.h:10 +msgid "px per Unit" +msgstr "" + +#: ../share/extensions/ffms.inx.h:3 +msgid "FretFind Multi Length Scala" +msgstr "" + +#: ../share/extensions/ffms.inx.h:9 ../share/extensions/ffss.inx.h:7 +msgid "Path to Scala *.scl File" +msgstr "" + +#: ../share/extensions/ffms.inx.h:11 +msgid "Tuning (scale step for each string seperated by semicolons)" +msgstr "" + +#: ../share/extensions/ffset.inx.h:2 +msgid "FretFind Single Length ET" +msgstr "" + +#: ../share/extensions/ffset.inx.h:8 ../share/extensions/ffss.inx.h:8 +msgid "Scale Length" +msgstr "" + +#: ../share/extensions/ffss.inx.h:2 +msgid "FretFind Single Length Scala" +msgstr "" + +#: ../share/extensions/ffss.inx.h:9 +msgid "Tuning (Scale step for each string seperated by semicolons)" +msgstr "" + +#: ../share/extensions/handles.inx.h:1 +#, fuzzy +msgid "Draw Handles" +msgstr "ਹੱਥ ਨਾਲ ਰੇਖਾਵਾਂ ਖਿੱਚੋ" + +#: ../share/extensions/interp.inx.h:1 +#, fuzzy +msgid "Duplicate Endpaths" +msgstr "ਦੋਹਰੀ ਨੋਡ" + +#: ../share/extensions/interp.inx.h:2 +#, fuzzy +msgid "Exponent" +msgstr "ਨਿਰਯਾਤ" + +#: ../share/extensions/interp.inx.h:3 +msgid "Interpolate" +msgstr "" + +#: ../share/extensions/interp.inx.h:4 +msgid "Interpolate Style (Experimental)" +msgstr "" + +#: ../share/extensions/interp.inx.h:5 +msgid "Interpolation Method" +msgstr "" + +#: ../share/extensions/interp.inx.h:6 +msgid "Interpolation Steps" +msgstr "" + +#: ../share/extensions/kochify.inx.h:1 +msgid "Kochify" +msgstr "" + +#: ../share/extensions/kochify_load.inx.h:1 +msgid "Kochify (Load)" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:1 +#, fuzzy +msgid "Angle" +msgstr "ਕੋਣ:" + +#: ../share/extensions/lindenmayer.inx.h:2 +msgid "Axiom" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:3 +#, fuzzy +msgid "Lindenmayer" +msgstr "ਪਰਤ ਦਾ ਨਾਂ-ਤਬਦੀਲ" + +#: ../share/extensions/lindenmayer.inx.h:4 +msgid "Order" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:5 +#, fuzzy +msgid "Rules" +msgstr "ਪੈਮਾਨਾ(_R)" + +#: ../share/extensions/lindenmayer.inx.h:6 +#, fuzzy +msgid "Step" +msgstr "ਪਗ਼" + +#: ../share/extensions/motion.inx.h:1 +#, fuzzy +msgid "Direction" +msgstr "ਵੇਰਵਾ" + +#: ../share/extensions/motion.inx.h:2 +#, fuzzy +msgid "Magnitude" +msgstr "ਮੈਜ਼ੀਨਟਾ" + +#: ../share/extensions/motion.inx.h:3 +#, fuzzy +msgid "Motion" +msgstr "ਘੁੰਮਾਓ(_R)" + +#: ../share/extensions/pdf_output.inx.h:1 +msgid "Adobe PDF (*.pdf)" +msgstr "" + +#: ../share/extensions/pdf_output.inx.h:2 +msgid "Adobe Portable Document Format" +msgstr "" + +#: ../share/extensions/pdf_output.inx.h:3 +#, fuzzy +msgid "PDF Output" +msgstr "ਆਉਟਪੁੱਟ" + +#: ../share/extensions/ps_input.inx.h:1 +#, fuzzy +msgid "Postscript" +msgstr "ਪੋਰਟਰੇਟ" + +#: ../share/extensions/ps_input.inx.h:2 +msgid "Postscript (*.ps)" +msgstr "" + +#: ../share/extensions/ps_input.inx.h:3 +msgid "Postscript Input" +msgstr "" + +#: ../share/extensions/radiusrand.inx.h:1 +#, fuzzy +msgid "Radius" +msgstr "ਉਭਾਰੋ(_R)" + +#: ../share/extensions/radiusrand.inx.h:2 +#, fuzzy +msgid "Radius Randomize" +msgstr "ਰਲਵਾਂ:" + +#: ../share/extensions/radiusrand.inx.h:3 +msgid "Randomize Control Points" +msgstr "" + +#: ../share/extensions/radiusrand.inx.h:4 +#, fuzzy +msgid "Randomize Nodes" +msgstr "ਰਲਵਾਂ:" + +#: ../share/extensions/rtree.inx.h:1 +#, fuzzy +msgid "Initial Size" +msgstr "ਬਿੱਟਮੈਪ ਅਕਾਰ" + +#: ../share/extensions/rtree.inx.h:2 +msgid "Minimum Size" +msgstr "" + +#: ../share/extensions/rtree.inx.h:3 +#, fuzzy +msgid "Random Tree" +msgstr "ਰਲਵਾਂ:" + +#: ../share/extensions/sk_input.inx.h:1 +msgid "A diagram created with the program Sketch" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:2 +msgid "Sketch Diagram (*.sk)" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:3 +msgid "Sketch Input" +msgstr "" + +#: ../share/extensions/straightseg.inx.h:1 +msgid "Behavior" +msgstr "" + +#: ../share/extensions/straightseg.inx.h:3 +msgid "Segment Straightener" +msgstr "" + +#: ../share/extensions/summersnight.inx.h:1 +msgid "Summer's Night" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:1 +#: ../share/extensions/svgz_output.inx.h:1 +msgid "Compressed Inkscape SVG (*.svgz)" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:2 +#: ../share/extensions/svgz_output.inx.h:2 +msgid "Inkscape's native file format compressed with GZip" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:3 +msgid "SVGZ Input" +msgstr "" + +#: ../share/extensions/svgz_output.inx.h:3 +#, fuzzy +msgid "SVGZ Output" +msgstr "ਆਉਟਪੁੱਟ" + +#: ../share/extensions/txt2svg.inx.h:1 +msgid "ASCII Text" +msgstr "" + +#: ../share/extensions/txt2svg.inx.h:2 +msgid "Text File (*.txt)" +msgstr "" + +#: ../share/extensions/txt2svg.inx.h:3 +msgid "Text Input" +msgstr "" + +#: ../share/extensions/wavy.inx.h:1 +msgid "Calculate first derivative numerically" +msgstr "" + +#: ../share/extensions/wavy.inx.h:2 +msgid "First derivative" +msgstr "" + +#: ../share/extensions/wavy.inx.h:3 +msgid "Function" +msgstr "" + +#: ../share/extensions/wavy.inx.h:4 +msgid "Function Plotter" +msgstr "" + +#: ../share/extensions/wavy.inx.h:5 +msgid "Nodes per period" +msgstr "" + +#: ../share/extensions/wavy.inx.h:6 +msgid "Periods (2*Pi each)" +msgstr "" + +#: ../share/extensions/whirl.inx.h:1 +msgid "Amount of Whirl" +msgstr "" + +#: ../share/extensions/whirl.inx.h:2 +#, fuzzy +msgid "Center X" +msgstr "ਕੇਂਦਰੀ ਰੇਖਾਵਾਂ" + +#: ../share/extensions/whirl.inx.h:3 +#, fuzzy +msgid "Center Y" +msgstr "ਕੇਂਦਰੀ ਰੇਖਾਵਾਂ" + +#: ../share/extensions/whirl.inx.h:4 +msgid "Direction of Rotation" +msgstr "" + +#: ../share/extensions/whirl.inx.h:5 +msgid "Whirl" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:1 +msgid "A popular graphics file format for clipart" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:2 +msgid "Windows Metafile (*.wmf)" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:3 +msgid "Windows Metafile Input" +msgstr "" + +#~ msgid "Current style" +#~ msgstr "ਮੌਜੂਦਾ ਸ਼ੈਲੀ" + +#~ msgid "Arrange Objects" +#~ msgstr "ਇਕਾਈਆਂ ਟਿਕਾਓ" + +#~ msgid "" +#~ "%s is not a valid preferences file.\n" +#~ "%s" +#~ msgstr "" +#~ "%s ਇੱਕ ਠੀਕ ਪਸੰਦ ਫਾਇਲ ਨਹੀਂ ਹੈ।\n" +#~ "%s" + +#~ msgid "" +#~ "Inkscape will run with default settings.\n" +#~ "New settings will not be saved." +#~ msgstr "" +#~ "ਇੰਕਸਕੇਪੀ ਮੂਲ ਸਥਾਪਨ ਨਾਲ ਹੀ ਚਲਾਇਆ ਜਾਵੇਗਾ।\n" +#~ "ਨਵਾਂ ਸਥਾਪਨ ਸੰਭਾਲਿਆ ਨਹੀਂ ਜਾਵੇਗਾ।" + +#, fuzzy +#~ msgid "_Credits" +#~ msgstr "ਮਾਣ" + +#~ msgid "Mouse wheel scrolls by" +#~ msgstr "ਮਾਊਸ ਪਹੀਆ ਸਕਰੋਲ" + +#~ msgid "Scroll by" +#~ msgstr "ਸਕਰੋਲ" + +#~ msgid "Acceleration" +#~ msgstr "ਪਰਵੇਸ਼" + +#~ msgid "Speed" +#~ msgstr "ਗਤੀ" + +#~ msgid "Threshold" +#~ msgstr "ਮੁੱਢਲਾ ਮੁੱਲ" + +#~ msgid "Zoom in/out by" +#~ msgstr "ਜ਼ੂਮ ਅੰਦਰ/ਬਾਹਰ" + +#~ msgid "Transform" +#~ msgstr "ਤਬਦੀਲ" + +#~ msgid "gpl-2.svg" +#~ msgstr "gpl-2.svg" + +#~ msgid "Modifying or Redistributing Inkscape" +#~ msgstr "ਇੰਕਸਕੇਪੀ ਸੋਧ ਜਾਂ ਮੁੜ-ਵੰਡਣਾ" + +#~ msgid "Show license to modify and/or redistribute Inkscape: GNU GPL" +#~ msgstr "ਇੰਕਸਕੇਪੀ ਨੂੰ ਸੋਧ ਅਤੇ/ਜਾਂ ਮੁੜ-ਵੰਡਣ ਲਈ ਲਾਈਸੈਂਸ ਵੇਖਾਓ: GNU GPL" diff --git a/po/pl.po b/po/pl.po new file mode 100644 index 000000000..dfd32775d --- /dev/null +++ b/po/pl.po @@ -0,0 +1,10368 @@ +# Copyright (C) 2001-2004 Free Software Foundation, Inc. +# -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +# Aktualną wersję tego pliku możesz odnaleźć w repozytorium cvs.gnome.pl +# (:pserver:anonymous@cvs.gnome.pl:/home/cvs, puste hasło) +# Jeśli masz jakiekolwiek uwagi odnoszące się do tłumaczenia lub chcesz +# pomóc w jego rozwijaniu i pielęgnowaniu, napisz do nas na adres: +# translators@gnome.pl +# -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +msgid "" +msgstr "" +"Project-Id-Version: Inkscape 0.42\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2005-12-04 11:51-0800\n" +"PO-Revision-Date: 2005-10-29 16:47+0100\n" +"Last-Translator: Przemysław Loesch \n" +"Language-Team: Polish \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Poedit-Language: Polish\n" +"X-Poedit-Country: POLAND\n" +"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 " +"|| n%100>=20) ? 1 : 2);\n" +"X-Poedit-Basepath: CVS/inkscape/src/\n" + +#: ../inkscape.desktop.in.h:1 +msgid "Create and edit Scalable Vector Graphics images" +msgstr "Utwórz i edytuj rysunki wektorowe SVG" + +#: ../inkscape.desktop.in.h:2 +msgid "Inkscape SVG Vector Illustrator" +msgstr "Inkscape program do grafiki wektorowej SVG" + +#: ../../po/../src/arc-context.cpp:350 +msgid "" +"Ctrl: make circle or integer-ratio ellipse, snap arc/segment angle" +msgstr "" +"Ctrl: koło lub całkowite proporcje, przyciąganie do kąta dla łuku/" +"wycinka" + +#: ../../po/../src/arc-context.cpp:351 ../../po/../src/rect-context.cpp:388 +msgid "Shift: draw around the starting point" +msgstr "Shift: rysowanie od środka we wszystkich kierunkach" + +#: ../../po/../src/arc-context.cpp:413 +#: ../../po/../src/connector-context.cpp:493 +#: ../../po/../src/dyna-draw-context.cpp:506 +#: ../../po/../src/pen-context.cpp:329 ../../po/../src/pencil-context.cpp:208 +#: ../../po/../src/rect-context.cpp:452 ../../po/../src/spiral-context.cpp:421 +#: ../../po/../src/star-context.cpp:427 +msgid "Current layer is hidden. Unhide it to be able to draw on it." +msgstr "" +"Aktywna warstwa jest ukryta. Aby móc na niej rysować włącz jej " +"widoczność." + +#: ../../po/../src/arc-context.cpp:417 +#: ../../po/../src/connector-context.cpp:497 +#: ../../po/../src/dyna-draw-context.cpp:510 +#: ../../po/../src/pen-context.cpp:336 ../../po/../src/pencil-context.cpp:212 +#: ../../po/../src/rect-context.cpp:456 ../../po/../src/spiral-context.cpp:426 +#: ../../po/../src/star-context.cpp:431 +msgid "Current layer is locked. Unlock it to be able to draw on it." +msgstr "" +"Aktywna warstwa jest zablokowana. Aby móc na niej rysować odblokuj ją." + +#: ../../po/../src/arc-context.cpp:496 +#, c-format +msgid "" +"Ellipse: %s × %s; with Ctrl to make circle or integer-" +"ratio ellipse; with Shift to draw around the starting point" +msgstr "" +"Elipsa: %s × %s; z Ctrl koło lub elipsa o całkowitych " +"proporcjach; z Shift rysowanie od środka" + +#: ../../po/../src/connector-context.cpp:518 +msgid "Creating new connector" +msgstr "Tworzenie nowego łącznika" + +#: ../../po/../src/connector-context.cpp:939 +msgid "Finishing connector" +msgstr "Zakończono tworzenie łącznika" + +#: ../../po/../src/connector-context.cpp:1108 +msgid "Connection point: click or drag to create a new connector" +msgstr "" +"Punkt połączenia: klinknij lub przeciągnij aby utworzyć nowy łącznik" + +#: ../../po/../src/connector-context.cpp:1185 +msgid "Connector endpoint: drag to reroute or connect to new shapes" +msgstr "" +"Punkt końcowy łącznika: przeciągnij aby przestawić lub połącz z nowym " +"kształtem" + +#: ../../po/../src/connector-context.cpp:1278 +msgid "Select at least one non-connector object." +msgstr "Zaznacz co najmniej jeden obiekt nie będący łącznikiem." + +#: ../../po/../src/desktop-events.cpp:238 +#, c-format +msgid "%s at %s" +msgstr "%s na pozycji %s" + +#. TRANSLATORS: This string appears when double-clicking on a guide. +#. This is the distance by which the guide is to be moved. +#: ../../po/../src/desktop-events.cpp:277 +msgid " relative by " +msgstr " przesunięcie " + +#. TRANSLATORS: This string appears when double-clicking on a guide. +#. This is the target location where the guide is to be moved. +#: ../../po/../src/desktop-events.cpp:282 +#: ../../po/../src/desktop-events.cpp:395 +msgid " absolute to " +msgstr " pozycja " + +#. create dialog +#: ../../po/../src/desktop-events.cpp:348 +msgid "Guideline" +msgstr "Kolor prowadnic" + +#: ../../po/../src/desktop-events.cpp:432 +#, c-format +msgid "Move %s" +msgstr "Przesunięcie %s" + +#: ../../po/../src/desktop.cpp:678 +msgid "No previous zoom." +msgstr "Brak poprzedniego powiększenia." + +#: ../../po/../src/desktop.cpp:703 +msgid "No next zoom." +msgstr "Brak następnego powiększenia." + +#: ../../po/../src/dialogs/clonetiler.cpp:182 +msgid "Nothing selected." +msgstr "Nic nie wybrano." + +#: ../../po/../src/dialogs/clonetiler.cpp:188 +msgid "More than one object selected." +msgstr "Wybrano więcej niż jeden obiekt." + +#: ../../po/../src/dialogs/clonetiler.cpp:195 +#, c-format +msgid "Object has %d tiled clones." +msgstr "Obiekt posiada %d rozmieszczonych klonów." + +#: ../../po/../src/dialogs/clonetiler.cpp:200 +msgid "Object has no tiled clones." +msgstr "Obiekt nie posiada rozmieszczonych klonów." + +#: ../../po/../src/dialogs/clonetiler.cpp:865 +msgid "Select one object whose tiled clones to unclump." +msgstr "Wybierz jeden obiekt którego klony mają zostać rozproszone." + +#: ../../po/../src/dialogs/clonetiler.cpp:916 +msgid "Select one object whose tiled clones to remove." +msgstr "" +"Wybierz jeden obiekt, który posiada sklonowane kopie do usunięcia." + +#: ../../po/../src/dialogs/clonetiler.cpp:984 +#: ../../po/../src/selection-chemistry.cpp:1774 +msgid "Select an object to clone." +msgstr "Wybierz obiekt do klonowania" + +#: ../../po/../src/dialogs/clonetiler.cpp:990 +#: ../../po/../src/selection-chemistry.cpp:1780 +msgid "" +"If you want to clone several objects, group them and clone the " +"group." +msgstr "" +"Jeśli chcesz sklonować kilka obiektów, zgrupuj je najpierw, a " +"następnie sklonuj grupę." + +#: ../../po/../src/dialogs/clonetiler.cpp:1484 +msgid "Per row:" +msgstr "Dla rzędu:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1497 +msgid "Per column:" +msgstr "Dla kolumny:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1505 +msgid "Randomize:" +msgstr "Zmiana losowa:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1656 +msgid "_Symmetry" +msgstr "_Symetria" + +#. TRANSLATORS: For the following 17 symmetry groups, see +#. * http://www.bib.ulb.ac.be/coursmath/doc/17.htm (visual examples); +#. * http://www.clarku.edu/~djoyce/wallpaper/seventeen.html (English vocabulary); or +#. * http://membres.lycos.fr/villemingerard/Geometri/Sym1D.htm (French vocabulary). +#. +#: ../../po/../src/dialogs/clonetiler.cpp:1664 +msgid "Select one of the 17 symmetry groups for the tiling" +msgstr "Wybierz jedną z 17 grup symetrii do klonowania" + +#. TRANSLATORS: "translation" means "shift" / "displacement" here. +#: ../../po/../src/dialogs/clonetiler.cpp:1675 +msgid "P1: simple translation" +msgstr "P1: proste przesunięcie" + +#: ../../po/../src/dialogs/clonetiler.cpp:1676 +msgid "P2: 180° rotation" +msgstr "P2: 180° obrót" + +#: ../../po/../src/dialogs/clonetiler.cpp:1677 +msgid "PM: reflection" +msgstr "PM: odbicie" + +#. TRANSLATORS: "glide reflection" is a reflection and a translation combined. +#. For more info, see http://mathforum.org/sum95/suzanne/symsusan.html +#: ../../po/../src/dialogs/clonetiler.cpp:1680 +msgid "PG: glide reflection" +msgstr "PG: odbicie z przesunięciem" + +#: ../../po/../src/dialogs/clonetiler.cpp:1681 +msgid "CM: reflection + glide reflection" +msgstr "CM: odbicie + odbicie z przesunięciem" + +#: ../../po/../src/dialogs/clonetiler.cpp:1682 +msgid "PMM: reflection + reflection" +msgstr "PMM: odbicie w obu kierunkach" + +#: ../../po/../src/dialogs/clonetiler.cpp:1683 +msgid "PMG: reflection + 180° rotation" +msgstr "PMG: odbicie + obrót o 180°" + +#: ../../po/../src/dialogs/clonetiler.cpp:1684 +msgid "PGG: glide reflection + 180° rotation" +msgstr "PGG: odbicie z przesunięciem + obrót o 180°" + +#: ../../po/../src/dialogs/clonetiler.cpp:1685 +msgid "CMM: reflection + reflection + 180° rotation" +msgstr "CMM: odbicie + odbicie + obrót o 180°" + +#: ../../po/../src/dialogs/clonetiler.cpp:1686 +msgid "P4: 90° rotation" +msgstr "P4: obrót o 90°" + +#: ../../po/../src/dialogs/clonetiler.cpp:1687 +msgid "P4M: 90° rotation + 45° reflection" +msgstr "P4M: obrót o 90° + odbicie 45°" + +#: ../../po/../src/dialogs/clonetiler.cpp:1688 +msgid "P4G: 90° rotation + 90° reflection" +msgstr "P4G: obrót o 90° + odbicie 90°" + +#: ../../po/../src/dialogs/clonetiler.cpp:1689 +msgid "P3: 120° rotation" +msgstr "P3: obrót o 120°" + +#: ../../po/../src/dialogs/clonetiler.cpp:1690 +msgid "P31M: reflection + 120° rotation, dense" +msgstr "P31M: odbicie + obrót o 120°, gęsto" + +#: ../../po/../src/dialogs/clonetiler.cpp:1691 +msgid "P3M1: reflection + 120° rotation, sparse" +msgstr "P3M1: odbicie + obrót o 120°, rzadko" + +#: ../../po/../src/dialogs/clonetiler.cpp:1692 +msgid "P6: 60° rotation" +msgstr "P6: obrót o 60°" + +#: ../../po/../src/dialogs/clonetiler.cpp:1693 +msgid "P6M: reflection + 60° rotation" +msgstr "P6M: odbicie + obrót o 60°" + +#: ../../po/../src/dialogs/clonetiler.cpp:1721 +msgid "S_hift" +msgstr "_Przesunięcie" + +#. TRANSLATORS: "shift" means: the tiles will be shifted (offset) horizontally by this amount +#: ../../po/../src/dialogs/clonetiler.cpp:1731 +#, no-c-format +msgid "Shift X:" +msgstr "Przesunięcie X:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1739 +#, no-c-format +msgid "Horizontal shift per row (in % of tile width)" +msgstr "Przesunięcie w poziome dla każdego rzędu (w % szerokości elementu)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1747 +#, no-c-format +msgid "Horizontal shift per column (in % of tile width)" +msgstr "Przesunięcie w poziomie dla każdej kolumny (w % szerokości elementu)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1754 +msgid "Randomize the horizontal shift by this percentage" +msgstr "Zmiana losowa poziomego przesunięcia o wybraną wartość procentową" + +#. TRANSLATORS: "shift" means: the tiles will be shifted (offset) vertically by this amount +#: ../../po/../src/dialogs/clonetiler.cpp:1764 +#, no-c-format +msgid "Shift Y:" +msgstr "Przesunięcie Y:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1772 +#, no-c-format +msgid "Vertical shift per row (in % of tile height)" +msgstr "Przesunięcie w pionie dla każdego rzędu (w % wysokości elementu)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1780 +#, no-c-format +msgid "Vertical shift per column (in % of tile height)" +msgstr "Przesunięcie w pionie dla każdej kolumny (w % wysokości elementu)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1787 +msgid "Randomize the vertical shift by this percentage" +msgstr "Zmiana losowa pionowego przesunięcia o wybraną wartość procentową" + +#: ../../po/../src/dialogs/clonetiler.cpp:1795 +msgid "Exponent:" +msgstr "Przyrost:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1802 +msgid "Whether rows are spaced evenly (1), converge (<1) or diverge (>1)" +msgstr "Rozmieszczenie rzędów równomierne (1), zbieżne (<1) lub rozbieżne (>1)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1809 +msgid "Whether columns are spaced evenly (1), converge (<1) or diverge (>1)" +msgstr "Rozmieszczenie kolumn równomierne (1), zbieżne (<1) lub rozbieżne (>1)" + +#. TRANSLATORS: "Alternate" is a verb here +#: ../../po/../src/dialogs/clonetiler.cpp:1817 +#: ../../po/../src/dialogs/clonetiler.cpp:1907 +#: ../../po/../src/dialogs/clonetiler.cpp:1966 +#: ../../po/../src/dialogs/clonetiler.cpp:2022 +#: ../../po/../src/dialogs/clonetiler.cpp:2153 +msgid "Alternate:" +msgstr "Zmiana znaku:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1823 +msgid "Alternate the sign of shifts for each row" +msgstr "Zamiana znaku dla przesunięcia w kolejnych rzędach" + +#: ../../po/../src/dialogs/clonetiler.cpp:1828 +msgid "Alternate the sign of shifts for each column" +msgstr "Zamiana znaku dla przesunięcia w kolejnych kolumnach" + +#: ../../po/../src/dialogs/clonetiler.cpp:1837 +msgid "Sc_ale" +msgstr "Ska_lowanie" + +#: ../../po/../src/dialogs/clonetiler.cpp:1845 +msgid "Scale X:" +msgstr "Skalowanie X:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1853 +#, no-c-format +msgid "Horizontal scale per row (in % of tile width)" +msgstr "Skalowanie w poziomie dla każdego rzędu (w % szerokości elementu)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1861 +#, no-c-format +msgid "Horizontal scale per column (in % of tile width)" +msgstr "Skalowanie w poziomie dla każdej kolumny (w % szerokości elementu)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1868 +msgid "Randomize the horizontal scale by this percentage" +msgstr "Zmiana losowa skalowania poziomego o wybraną wartość procentową" + +#: ../../po/../src/dialogs/clonetiler.cpp:1876 +msgid "Scale Y:" +msgstr "Skalowanie Y:Koło" + +#: ../../po/../src/dialogs/clonetiler.cpp:1884 +#, no-c-format +msgid "Vertical scale per row (in % of tile height)" +msgstr "Skalowanie w pionie dla każdego rzędu (w % wysokości elementu)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1892 +#, no-c-format +msgid "Vertical scale per column (in % of tile height)" +msgstr "Skalowanie w pionie dla każdej kolumny (w % wysokości elementu)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1899 +msgid "Randomize the vertical scale by this percentage" +msgstr "Zmiana losowa skalowania pionowego o wybraną wartość procentową" + +#: ../../po/../src/dialogs/clonetiler.cpp:1913 +msgid "Alternate the sign of scales for each row" +msgstr "Zamiana znaku dla skalowanie kolejnych rzędów" + +#: ../../po/../src/dialogs/clonetiler.cpp:1918 +msgid "Alternate the sign of scales for each column" +msgstr "Zamiana znaku dla skalowanie kolejnych kolumn" + +#: ../../po/../src/dialogs/clonetiler.cpp:1927 +msgid "_Rotation" +msgstr "_Obrót" + +#: ../../po/../src/dialogs/clonetiler.cpp:1935 +msgid "Angle:" +msgstr "Kąt:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1943 +#, no-c-format +msgid "Rotate tiles by this angle for each row" +msgstr "Kąt obrotu dla każdego rzędu" + +#: ../../po/../src/dialogs/clonetiler.cpp:1951 +#, no-c-format +msgid "Rotate tiles by this angle for each column" +msgstr "Kąt obrotu dla każdej kolumny" + +#: ../../po/../src/dialogs/clonetiler.cpp:1958 +msgid "Randomize the rotation angle by this percentage" +msgstr "Zmiana losowa kąta obrotu o wybraną wartość procentową" + +#: ../../po/../src/dialogs/clonetiler.cpp:1972 +msgid "Alternate the rotation direction for each row" +msgstr "Zamiana znaku dla kąta obrotu w kolejnych rzędach" + +#: ../../po/../src/dialogs/clonetiler.cpp:1977 +msgid "Alternate the rotation direction for each column" +msgstr "Zamiana znaku dla kąta obrotu w kolejnych kolumnach" + +#: ../../po/../src/dialogs/clonetiler.cpp:1985 +msgid "_Opacity" +msgstr "_Przezroczystość" + +#: ../../po/../src/dialogs/clonetiler.cpp:1993 +msgid "Fade out:" +msgstr "Przyrost:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2000 +msgid "Decrease tile opacity by this percentage for each row" +msgstr "Zmniejszenie procentowe nieprzepuszczalności dla każdego rzędu" + +#: ../../po/../src/dialogs/clonetiler.cpp:2007 +msgid "Decrease tile opacity by this percentage for each column" +msgstr "Zmniejszenie procentowe nieprzepuszczalności dla każdej kolumny" + +#: ../../po/../src/dialogs/clonetiler.cpp:2014 +msgid "Randomize the tile opacity by this percentage" +msgstr "Zmiana losowa przezroczystości o wybraną wartość procentową" + +#: ../../po/../src/dialogs/clonetiler.cpp:2028 +msgid "Alternate the sign of opacity change for each row" +msgstr "Zamiana znaku dla zmian przezroczystości w kolejnych rzędach" + +#: ../../po/../src/dialogs/clonetiler.cpp:2033 +msgid "Alternate the sign of opacity change for each column" +msgstr "Zamiana znaku dla zmian przezroczystości w kolejnych kolumnach" + +#: ../../po/../src/dialogs/clonetiler.cpp:2041 +msgid "Co_lor" +msgstr "_Kolor" + +#: ../../po/../src/dialogs/clonetiler.cpp:2046 +msgid "Initial color: " +msgstr "Kolor początkowy:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2050 +msgid "Initial color of tiled clones" +msgstr "Kolor początkowy klonów" + +#: ../../po/../src/dialogs/clonetiler.cpp:2050 +msgid "" +"Initial color for clones (works only if the original has unset fill or " +"stroke)" +msgstr "" +"Kolor początkowy tworzonych klonów (działa jedynie jeśli oryginał ma " +"wyzerowane wypełnienie lub kontur)" + +#: ../../po/../src/dialogs/clonetiler.cpp:2065 +msgid "H:" +msgstr "H:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2072 +msgid "Change the tile hue by this percentage for each row" +msgstr "Zmiana barwy obiektu o wybraną wartość procentową dla każdego rzędu" + +#: ../../po/../src/dialogs/clonetiler.cpp:2079 +msgid "Change the tile hue by this percentage for each column" +msgstr "Zmiana barwy obiektu o wybraną wartość procentową dla każdej kolumny" + +#: ../../po/../src/dialogs/clonetiler.cpp:2086 +msgid "Randomize the tile hue by this percentage" +msgstr "Zmiana losowa barwy o wybraną wartość procentową" + +#: ../../po/../src/dialogs/clonetiler.cpp:2095 +msgid "S:" +msgstr "S:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2102 +msgid "Change the color saturation by this percentage for each row" +msgstr "Zmiana nasycenia koloru o wybraną wartość procentową dla każdego rzędu" + +#: ../../po/../src/dialogs/clonetiler.cpp:2109 +msgid "Change the color saturation by this percentage for each column" +msgstr "" +"Zmiana nasycenia koloru o wybraną wartość procentową dla każdej kolumny" + +#: ../../po/../src/dialogs/clonetiler.cpp:2116 +msgid "Randomize the color saturation by this percentage" +msgstr "Zmiana losowa nasycenia o wybraną wartość procentową" + +#: ../../po/../src/dialogs/clonetiler.cpp:2124 +msgid "L:" +msgstr "L:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2131 +msgid "Change the color lightness by this percentage for each row" +msgstr "Zmiana jasności koloru o wybraną wartość procentową dla każdego rzędu" + +#: ../../po/../src/dialogs/clonetiler.cpp:2138 +msgid "Change the color lightness by this percentage for each column" +msgstr "Zmiana jasności koloru o wybraną wartość procentową dla każdej kolumny" + +#: ../../po/../src/dialogs/clonetiler.cpp:2145 +msgid "Randomize the color lightness by this percentage" +msgstr "Zmiana losowa jasności o wybraną wartość procentową" + +#: ../../po/../src/dialogs/clonetiler.cpp:2159 +msgid "Alternate the sign of color changes for each row" +msgstr "Zamiana znaku dla zmian koloru w kolejnych rzędach" + +#: ../../po/../src/dialogs/clonetiler.cpp:2164 +msgid "Alternate the sign of color changes for each column" +msgstr "Zamiana znaku dla zmian koloru w kolejnych kolumnach" + +#: ../../po/../src/dialogs/clonetiler.cpp:2172 +msgid "_Trace" +msgstr "Próbkowani_e" + +#: ../../po/../src/dialogs/clonetiler.cpp:2179 +msgid "Trace the drawing under the tiles" +msgstr "Próbowanie rysunku pod obiektami" + +#: ../../po/../src/dialogs/clonetiler.cpp:2183 +msgid "" +"For each clone, pick a value from the drawing in that clone's location and " +"apply it to the clone" +msgstr "" +"Przypisanie klonowi wartości z rysunku, dla każdego klonu z miejsca w którym " +"się znajduje" + +#: ../../po/../src/dialogs/clonetiler.cpp:2197 +msgid "1. Pick from the drawing:" +msgstr "1. Pobranie z rysunku:" + +#. ----Hbox2 +#: ../../po/../src/dialogs/clonetiler.cpp:2208 +#: ../../po/../src/dialogs/clonetiler.cpp:2355 +#: ../../po/../src/ui/dialog/tracedialog.cpp:445 +msgid "Color" +msgstr "Kolor" + +#: ../../po/../src/dialogs/clonetiler.cpp:2209 +msgid "Pick the visible color and opacity" +msgstr "Pobranie widocznego koloru i przezroczystości" + +#: ../../po/../src/dialogs/clonetiler.cpp:2216 +#: ../../po/../src/dialogs/clonetiler.cpp:2365 +#: ../share/extensions/dropshadow.inx.h:3 +msgid "Opacity" +msgstr "Przezroczystość" + +#: ../../po/../src/dialogs/clonetiler.cpp:2217 +msgid "Pick the total accumulated opacity" +msgstr "Pobranie zsumowanego stopnia krycia" + +#: ../../po/../src/dialogs/clonetiler.cpp:2224 +msgid "R" +msgstr "R" + +#: ../../po/../src/dialogs/clonetiler.cpp:2225 +msgid "Pick the Red component of the color" +msgstr "Pobranie czerwonego składnika koloru" + +#: ../../po/../src/dialogs/clonetiler.cpp:2232 +msgid "G" +msgstr "G" + +#: ../../po/../src/dialogs/clonetiler.cpp:2233 +msgid "Pick the Green component of the color" +msgstr "Pobranie zielonego składnika koloru" + +#: ../../po/../src/dialogs/clonetiler.cpp:2240 +msgid "B" +msgstr "B" + +#: ../../po/../src/dialogs/clonetiler.cpp:2241 +msgid "Pick the Blue component of the color" +msgstr "Pobranie niebieskiego składnika koloru" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2250 +msgid "clonetiler|H" +msgstr "H" + +#: ../../po/../src/dialogs/clonetiler.cpp:2251 +msgid "Pick the hue of the color" +msgstr "Pobranie barwy" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2260 +msgid "clonetiler|S" +msgstr "S" + +#: ../../po/../src/dialogs/clonetiler.cpp:2261 +msgid "Pick the saturation of the color" +msgstr "Pobranie nasycenia koloru" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2270 +msgid "clonetiler|L" +msgstr "L" + +#: ../../po/../src/dialogs/clonetiler.cpp:2271 +msgid "Pick the lightness of the color" +msgstr "Pobranie jasności koloru" + +#: ../../po/../src/dialogs/clonetiler.cpp:2281 +msgid "2. Tweak the picked value:" +msgstr "2. Korekta pobranej wartości:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2291 +msgid "Gamma-correct:" +msgstr "Korekcja gamma:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2296 +msgid "Shift the mid-range of the picked value upwards (>0) or downwards (<0)" +msgstr "" +"Przesunięcie zakresu środkowego pobranej wartości w górę (>0) lub w dół (<0)" + +#: ../../po/../src/dialogs/clonetiler.cpp:2303 +msgid "Randomize:" +msgstr "Wartość losowa:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2308 +msgid "Randomize the picked value by this percentage" +msgstr "Zmiana losowa pobranej wartości o wybraną wielkość procentową" + +#: ../../po/../src/dialogs/clonetiler.cpp:2315 +msgid "Invert:" +msgstr "Negacja:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2319 +msgid "Invert the picked value" +msgstr "Negacja pobranej wartości" + +#: ../../po/../src/dialogs/clonetiler.cpp:2325 +msgid "3. Apply the value to the clones':" +msgstr "3. Przypisanie pobranej wartości do klonów:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2335 +msgid "Presence" +msgstr "Obrecność" + +#: ../../po/../src/dialogs/clonetiler.cpp:2338 +msgid "" +"Each clone is created with the probability determined by the picked value in " +"that point" +msgstr "" +"Prawdopodobieństwo utworzenia klonu jest określane na podstawie wartości " +"pobranej w danym punkcie" + +#: ../../po/../src/dialogs/clonetiler.cpp:2345 +msgid "Size" +msgstr "Rozmiar" + +#: ../../po/../src/dialogs/clonetiler.cpp:2348 +msgid "Each clone's size is determined by the picked value in that point" +msgstr "" +"Rozmiar każdego klonu jest określany poprzez wartość pobraną w danym punkcie" + +#: ../../po/../src/dialogs/clonetiler.cpp:2358 +msgid "" +"Each clone is painted by the picked color (the original must have unset fill " +"or stroke)" +msgstr "" +"Każdy klon otrzymuje kolor pobrany w danym punkcie (oryginał musi mieć " +"wyzerowane wypełnienie lub kontur)" + +#: ../../po/../src/dialogs/clonetiler.cpp:2368 +msgid "Each clone's opacity is determined by the picked value in that point" +msgstr "" +"Każdy klon otrzymuje przezroczystość równą wartości pobranej w danym punkcie" + +#: ../../po/../src/dialogs/clonetiler.cpp:2395 +msgid "How many rows in the tiling" +msgstr "Ilość rzędów tworzonych przy klonowaniu" + +#: ../../po/../src/dialogs/clonetiler.cpp:2415 +msgid "How many columns in the tiling" +msgstr "Ilość kolumn tworzonych przy klonowaniu" + +#: ../../po/../src/dialogs/clonetiler.cpp:2445 +msgid "Width of the rectangle to be filled" +msgstr "Szerokość prostokąta do wypełnienia" + +#: ../../po/../src/dialogs/clonetiler.cpp:2470 +msgid "Height of the rectangle to be filled" +msgstr "Wysokość prostokąta do wypełnienia" + +#: ../../po/../src/dialogs/clonetiler.cpp:2485 +msgid "Rows, columns: " +msgstr "Rzędy, kolumny:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2486 +msgid "Create the specified number of rows and columns" +msgstr "Utworzenie określonej liczby rzędów i kolumn" + +#: ../../po/../src/dialogs/clonetiler.cpp:2495 +msgid "Width, height: " +msgstr "Szerokość, wysokość:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2496 +msgid "Fill the specified width and height with the tiling" +msgstr "Wypełnienie wybranej szerokości i wysokości" + +#: ../../po/../src/dialogs/clonetiler.cpp:2512 +msgid "Use saved size and position of the tile" +msgstr "Rozmiar i pozycja z poprzedniego klonowania" + +#: ../../po/../src/dialogs/clonetiler.cpp:2515 +msgid "" +"Pretend that the size and position of the tile are the same as the last time " +"you tiled it (if any), instead of using the current size" +msgstr "" +"Wykorzystanie rozmiaru i położenia elementu zapisanych przy poprzednim " + +#: ../../po/../src/dialogs/clonetiler.cpp:2539 +msgid " _Create " +msgstr "_Utwórz " + +#: ../../po/../src/dialogs/clonetiler.cpp:2541 +msgid "Create and tile the clones of the selection" +msgstr "Utwórz i rozmieść sklonowane kopie wybranych elementów" + +#. TRANSLATORS: if a group of objects are "clumped" together, then they +#. are unevenly spread in the given amount of space - as shown in the +#. diagrams on the left in the following screenshot: +#. http://www.inkscape.org/screenshots/gallery/inkscape-0.42-CVS-tiles-unclump.png +#. So unclumping is the process of spreading a number of objects out more evenly. +#: ../../po/../src/dialogs/clonetiler.cpp:2556 +msgid " _Unclump " +msgstr "_Rozproszenie" + +#: ../../po/../src/dialogs/clonetiler.cpp:2557 +msgid "Spread out clones to reduce clumping; can be applied repeatedly" +msgstr "" +"Rozsuwa klony zmiejszając równomierność ich rozłożenia; może być stosowane " +"wielokrotnie" + +#: ../../po/../src/dialogs/clonetiler.cpp:2563 +msgid " Re_move " +msgstr "U_suń " + +#: ../../po/../src/dialogs/clonetiler.cpp:2564 +msgid "Remove existing tiled clones of the selected object (siblings only)" +msgstr "Usuń istniejące klony wybranego obiektu (usuwa tylko kopie)" + +#: ../../po/../src/dialogs/clonetiler.cpp:2580 +msgid " R_eset " +msgstr "_Zresetuj " + +#. TRANSLATORS: "change" is a noun here +#: ../../po/../src/dialogs/clonetiler.cpp:2582 +msgid "" +"Reset all shifts, scales, rotates, opacity and color changes in the dialog " +"to zero" +msgstr "" +"Wyzerowanie wartości wszystkich przesunięć, skalowań, obrotów, zmian " +"przezroczystości i koloru w polach okna dialogowego." + +#: ../../po/../src/dialogs/color-picker.cpp:280 +msgid "Close" +msgstr "Zamknij" + +#: ../../po/../src/dialogs/debugdialog.cpp:138 +msgid "Messages" +msgstr "Komunikaty" + +#. ## Add a menu for clear() +#: ../../po/../src/dialogs/debugdialog.cpp:144 +#: ../../po/../src/menus-skeleton.h:16 +#: ../../po/../src/ui/dialog/messages.cpp:56 +#: ../../po/../src/ui/dialog/scriptdialog.cpp:181 +msgid "_File" +msgstr "_Plik" + +#. TRANSLATORS: "Clear" is a verb here +#: ../../po/../src/dialogs/debugdialog.cpp:145 +#: ../../po/../src/dialogs/find.cpp:753 +#: ../../po/../src/ui/dialog/messages.cpp:57 +#: ../../po/../src/ui/dialog/scriptdialog.cpp:182 +msgid "_Clear" +msgstr "_Wyczyść" + +#: ../../po/../src/dialogs/debugdialog.cpp:147 +#: ../../po/../src/ui/dialog/messages.cpp:59 +msgid "Capture log messages" +msgstr "_Rozpocznij przechwytywanie komunikatów" + +#: ../../po/../src/dialogs/debugdialog.cpp:149 +#: ../../po/../src/ui/dialog/messages.cpp:61 +msgid "Release log messages" +msgstr "_Zakończ przechwytywanie komunikatów" + +#. Notebook tab +#: ../../po/../src/dialogs/desktop-properties.cpp:909 +#: ../../po/../src/ui/dialog/document-preferences.cpp:89 +#: ../../po/../src/ui/widget/panel.cpp:107 +msgid "Grid" +msgstr "Siatka" + +#. Checkbuttons +#. / \todo FIXME: gray out snapping when grid is off +#. / \todo FIXME: gray out snapping when grid is off. +#. / Dissenting view: you want snapping without grid. +#: ../../po/../src/dialogs/desktop-properties.cpp:917 +#: ../../po/../src/ui/dialog/document-preferences.cpp:179 +msgid "Show grid" +msgstr "Wyświetlanie siatki" + +#: ../../po/../src/dialogs/desktop-properties.cpp:917 +#: ../../po/../src/ui/dialog/document-preferences.cpp:179 +#: ../../po/../src/verbs.cpp:2115 +msgid "Show or hide grid" +msgstr "Wyświetla lub ukrywa siatkę" + +#: ../../po/../src/dialogs/desktop-properties.cpp:918 +#: ../../po/../src/ui/dialog/document-preferences.cpp:180 +msgid "Snap bounding boxes to grid" +msgstr "Przyciąganie ramek do siatki" + +#: ../../po/../src/dialogs/desktop-properties.cpp:918 +#: ../../po/../src/dialogs/desktop-properties.cpp:1001 +#: ../../po/../src/ui/dialog/document-preferences.cpp:181 +#: ../../po/../src/ui/dialog/document-preferences.cpp:236 +msgid "Snap the edges of the object bounding boxes" +msgstr "Przyciąganie krawędzi ramek otaczających obiekty" + +#: ../../po/../src/dialogs/desktop-properties.cpp:919 +#: ../../po/../src/ui/dialog/document-preferences.cpp:183 +msgid "Snap nodes to grid" +msgstr "Przyciąganie węzłów do siatki" + +#: ../../po/../src/dialogs/desktop-properties.cpp:919 +#: ../../po/../src/dialogs/desktop-properties.cpp:1002 +#: ../../po/../src/ui/dialog/document-preferences.cpp:184 +#: ../../po/../src/ui/dialog/document-preferences.cpp:239 +msgid "Snap path nodes, text baselines, ellipse centers, etc." +msgstr "Przyciąganie do węzłów ścieżek, podstaw tekstów, środków elips, itd." + +#: ../../po/../src/dialogs/desktop-properties.cpp:937 +#: ../../po/../src/ui/dialog/document-preferences.cpp:186 +msgid "Grid units:" +msgstr "Jednostki siatki:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:939 +#: ../../po/../src/ui/dialog/document-preferences.cpp:187 +msgid "Origin X:" +msgstr "Początek X:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:942 +#: ../../po/../src/ui/dialog/document-preferences.cpp:189 +msgid "Origin Y:" +msgstr "Początek Y:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:945 +#: ../../po/../src/ui/dialog/document-preferences.cpp:191 +msgid "Spacing X:" +msgstr "Odstępy X:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:948 +#: ../../po/../src/ui/dialog/document-preferences.cpp:193 +msgid "Spacing Y:" +msgstr "Odstępy Y:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:952 +#: ../../po/../src/dialogs/desktop-properties.cpp:1013 +#: ../../po/../src/ui/dialog/document-preferences.cpp:195 +#: ../../po/../src/ui/dialog/document-preferences.cpp:241 +msgid "Snap units:" +msgstr "Jednostki przyciągania" + +#: ../../po/../src/dialogs/desktop-properties.cpp:955 +#: ../../po/../src/dialogs/desktop-properties.cpp:1016 +#: ../../po/../src/ui/dialog/document-preferences.cpp:196 +#: ../../po/../src/ui/dialog/document-preferences.cpp:242 +msgid "Snap distance:" +msgstr "Odległość przyciągania:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:958 +#: ../../po/../src/ui/dialog/document-preferences.cpp:199 +msgid "Grid line color:" +msgstr "Kolor prowadnic:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:959 +#: ../../po/../src/ui/dialog/document-preferences.cpp:199 +msgid "Grid line color" +msgstr "Kolor linii siatki" + +#: ../../po/../src/dialogs/desktop-properties.cpp:959 +#: ../../po/../src/ui/dialog/document-preferences.cpp:200 +msgid "Color of grid lines" +msgstr "Kolor linii siatki" + +#: ../../po/../src/dialogs/desktop-properties.cpp:961 +#: ../../po/../src/ui/dialog/document-preferences.cpp:201 +msgid "Major grid line color:" +msgstr "Kolor głównych linii:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:962 +#: ../../po/../src/ui/dialog/document-preferences.cpp:201 +msgid "Major grid line color" +msgstr "Kolor głównych linii" + +#: ../../po/../src/dialogs/desktop-properties.cpp:962 +#: ../../po/../src/ui/dialog/document-preferences.cpp:202 +msgid "Color of the major (highlighted) grid lines" +msgstr "Kolor głównych (podświetlonych) lini siatki" + +#: ../../po/../src/dialogs/desktop-properties.cpp:965 +#: ../../po/../src/ui/dialog/document-preferences.cpp:204 +msgid "Major grid line every:" +msgstr "Rozstaw głównych linii:" + +#. TRANSLATORS: This belongs to the "Major grid line every:" string, +#. see grid settings in the "Document Preferences" dialog +#: ../../po/../src/dialogs/desktop-properties.cpp:977 +#: ../../po/../src/ui/dialog/document-preferences.cpp:204 +msgid "lines" +msgstr "linii" + +#. Guidelines page +#: ../../po/../src/dialogs/desktop-properties.cpp:991 +#: ../../po/../src/ui/dialog/document-preferences.cpp:90 +msgid "Guides" +msgstr "Prowadnice" + +#. / \todo FIXME: gray out snapping when guides are off +#. / Dissenting view: you want snapping without guides. +#: ../../po/../src/dialogs/desktop-properties.cpp:1000 +#: ../../po/../src/ui/dialog/document-preferences.cpp:234 +msgid "Show guides" +msgstr "Wyświetlanie prowadnic" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1000 +#: ../../po/../src/ui/dialog/document-preferences.cpp:234 +#: ../../po/../src/verbs.cpp:2116 +msgid "Show or hide guides" +msgstr "Wyświetla lub ukrywa prowadnice" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1001 +#: ../../po/../src/ui/dialog/document-preferences.cpp:235 +msgid "Snap bounding boxes to guides" +msgstr "Przyciąganie ramek do prowadnic" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1002 +#: ../../po/../src/ui/dialog/document-preferences.cpp:238 +msgid "Snap points to guides" +msgstr "Przyciąganie punktów do prowadnic" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1020 +#: ../../po/../src/ui/dialog/document-preferences.cpp:243 +msgid "Guide color:" +msgstr "Kolor prowadnic:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1021 +#: ../../po/../src/ui/dialog/document-preferences.cpp:243 +msgid "Guideline color" +msgstr "Kolor prowadnic" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1021 +#: ../../po/../src/ui/dialog/document-preferences.cpp:244 +msgid "Color of guidelines" +msgstr "Kolor prowadnic" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1023 +#: ../../po/../src/ui/dialog/document-preferences.cpp:245 +msgid "Highlight color:" +msgstr "Kolor podświetlenia:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1024 +#: ../../po/../src/ui/dialog/document-preferences.cpp:245 +msgid "Highlighted guideline color" +msgstr "Kolor podświetlenia prowadnic" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1024 +#: ../../po/../src/ui/dialog/document-preferences.cpp:246 +msgid "Color of a guideline when it is under mouse" +msgstr "Kolor prowadnicy gdy znajduje się pod wskaźnikiem myszy" + +#. Page page +#: ../../po/../src/dialogs/desktop-properties.cpp:1029 +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:855 +#: ../../po/../src/ui/dialog/document-preferences.cpp:88 +#: ../../po/../src/widgets/desktop-widget.cpp:1061 +msgid "Page" +msgstr "Strona" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1039 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +msgid "Background:" +msgstr "Kolor tła:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1040 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +msgid "Background color" +msgstr "Kolor tła" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1041 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +msgid "" +"Color and transparency of the page background (also used for bitmap export)" +msgstr "" +"Kolor i przezroczystość tła strony (również przy eksportowaniu do bitmapy)" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1045 +#: ../../po/../src/ui/dialog/document-preferences.cpp:147 +#, fuzzy +msgid "Show page border" +msgstr "Wyświetlanie obrzeża strony" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1049 +#: ../../po/../src/ui/dialog/document-preferences.cpp:148 +msgid "Border on top of drawing" +msgstr "Obrzeże widoczne przez rysunek" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1052 +#: ../../po/../src/ui/dialog/document-preferences.cpp:149 +msgid "Border color:" +msgstr "Kolor obrzeża:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1053 +#: ../../po/../src/ui/dialog/document-preferences.cpp:149 +#, fuzzy +msgid "Page border color" +msgstr "Kolor obrzeża strony" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1054 +#: ../../po/../src/ui/dialog/document-preferences.cpp:150 +#, fuzzy +msgid "Color of the page border" +msgstr "Kolor obrzeża strony" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1059 +#: ../../po/../src/ui/dialog/document-preferences.cpp:152 +msgid "Show page shadow" +msgstr "Wyświetlanie cienia strony" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1063 +#: ../../po/../src/ui/dialog/document-preferences.cpp:153 +msgid "Default units:" +msgstr "Domyślne jednostki:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1069 +msgid "Units for the tool controls, ruler, and the statusbar" +msgstr "Jednostki wyświetlane dla narzędzi rysunkowych, linijki i pola statusu" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1086 +#: ../../po/../src/ui/widget/page-sizer.cpp:209 +#, fuzzy +msgid "Page size:" +msgstr "Rozmiar strony:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1110 +#: ../../po/../src/ui/widget/page-sizer.cpp:219 +msgid "Custom" +msgstr "Rozmiar użytkownika" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1121 +#: ../../po/../src/ui/widget/page-sizer.cpp:225 +#, fuzzy +msgid "Page orientation:" +msgstr "Orientacja strony:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1133 +#: ../../po/../src/ui/widget/page-sizer.cpp:232 +msgid "Landscape" +msgstr "Pozioma" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1139 +#: ../../po/../src/ui/widget/page-sizer.cpp:234 +msgid "Portrait" +msgstr "Pionowa" + +#. Custom paper frame +#: ../../po/../src/dialogs/desktop-properties.cpp:1148 +#: ../../po/../src/ui/widget/page-sizer.cpp:249 +#, fuzzy +msgid "Custom size" +msgstr "Rozmiar użytkownika" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1160 +#: ../../po/../src/dialogs/export.cpp:269 +#: ../../po/../src/ui/widget/page-sizer.cpp:261 +msgid "Units:" +msgstr "Jednostki:" + +#. Stroke width +#: ../../po/../src/dialogs/desktop-properties.cpp:1162 +#: ../../po/../src/dialogs/export.cpp:310 +#: ../../po/../src/dialogs/object-attributes.cpp:55 +#: ../../po/../src/dialogs/stroke-style.cpp:985 +#: ../../po/../src/ui/widget/page-sizer.cpp:262 +#: ../../po/../src/widgets/toolbox.cpp:1957 +msgid "Width:" +msgstr "Szerokość:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1183 +#: ../../po/../src/dialogs/export.cpp:326 +#: ../../po/../src/dialogs/export.cpp:431 +#: ../../po/../src/dialogs/object-attributes.cpp:56 +#: ../../po/../src/ui/widget/page-sizer.cpp:263 +msgid "Height:" +msgstr "Wysokość:" + +#. +#. * Ownership metadata tab +#. +#: ../../po/../src/dialogs/desktop-properties.cpp:1206 +msgid "Metadata" +msgstr "Metadane" + +#. add license selector pull-down +#: ../../po/../src/dialogs/desktop-properties.cpp:1225 +msgid "License" +msgstr "Licencja" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1255 +msgid "Proprietary" +msgstr "Własność autora" + +#: ../../po/../src/dialogs/display-settings.cpp:212 +msgid "When transforming, show:" +msgstr "Przy przekształcaniu wyświetlaj:" + +#: ../../po/../src/dialogs/display-settings.cpp:223 +msgid "Objects" +msgstr "Obiekty" + +#: ../../po/../src/dialogs/display-settings.cpp:224 +msgid "Show the actual objects when moving or transforming" +msgstr "Wyświetlanie obiektów podczas ich przemieszczania i przekształcania" + +#: ../../po/../src/dialogs/display-settings.cpp:231 +msgid "Box outline" +msgstr "Tylko ramki obiektów" + +#: ../../po/../src/dialogs/display-settings.cpp:232 +msgid "Show only a box outline of the objects when moving or transforming" +msgstr "" +"Wyświetlanie jedynie ramek obiektów podczas ich przemieszczania i " +"przekształcania" + +#: ../../po/../src/dialogs/display-settings.cpp:238 +msgid "Per-object selection cue:" +msgstr "Wyróżnianie obiektów wewnątrz selekcji:" + +#. sorationsnapsperpi == 0 means no snapping +#: ../../po/../src/dialogs/display-settings.cpp:249 +#: ../../po/../src/dialogs/display-settings.cpp:386 +#: ../../po/../src/dialogs/display-settings.cpp:441 +#: ../../po/../src/dialogs/display-settings.cpp:1482 +#: ../../po/../src/dialogs/stroke-style.cpp:791 +#: ../../po/../src/interface.cpp:741 +#: ../../po/../src/ui/widget/selected-style.cpp:100 +#: ../../po/../src/verbs.cpp:1842 +msgid "None" +msgstr "Brak" + +#: ../../po/../src/dialogs/display-settings.cpp:250 +msgid "No per-object selection indication" +msgstr "Obiekty wewnątrz selekcji nie są wyróżniane" + +#: ../../po/../src/dialogs/display-settings.cpp:256 +msgid "Mark" +msgstr "Uchwyt" + +#: ../../po/../src/dialogs/display-settings.cpp:257 +msgid "Each selected object has a diamond mark in the top left corner" +msgstr "" +"Każdy z wybranych obiektów posiada uchwyt w kształcie rombu w lewym górnym " +"rogu" + +#: ../../po/../src/dialogs/display-settings.cpp:264 +msgid "Box" +msgstr "Ramka" + +#: ../../po/../src/dialogs/display-settings.cpp:265 +msgid "Each selected object displays its bounding box" +msgstr "Każdy z wybranych obiektów zostaje otoczony ramką" + +#: ../../po/../src/dialogs/display-settings.cpp:270 +msgid "Default scale origin:" +msgstr "Domyślny środek skalowania:" + +#: ../../po/../src/dialogs/display-settings.cpp:281 +msgid "Opposite bounding box edge" +msgstr "Przeciwległa krawędź ramki" + +#: ../../po/../src/dialogs/display-settings.cpp:282 +msgid "Default scale origin will be on the bounding box of the item" +msgstr "Domyślny środek skalowania położony na ramce obiektu" + +#: ../../po/../src/dialogs/display-settings.cpp:288 +msgid "Farthest opposite node" +msgstr "Najdalszy przeciwległy węzeł" + +#: ../../po/../src/dialogs/display-settings.cpp:289 +msgid "Default scale origin will be on the bounding box of the item's points" +msgstr "" +"Domyślny środek skalowania położony na linii najbardziej oddalonego węzła" + +#: ../../po/../src/dialogs/display-settings.cpp:341 +msgid "degrees" +msgstr "stopnie" + +#: ../../po/../src/dialogs/display-settings.cpp:350 +msgid "" +"Rotating with Ctrl pressed snaps every that much degrees; also, pressing " +"[ or ] rotates by this amount" +msgstr "" +"Przy obrocie z klawiszem Ctrl przyciąganie do kąta będącego wielokrotnością " +"podanej wartości; również naciśnięcie [ lub ] obraca o tę wartość" + +#: ../../po/../src/dialogs/display-settings.cpp:407 +msgid "Rotation snaps every:" +msgstr "Zatrzymywanie obrotu co:" + +#: ../../po/../src/dialogs/display-settings.cpp:430 +msgid "" +"None: dialogs are treated as regular windows; Normal: dialogs stay on top of " +"document windows; Aggressive: same as Normal but may work better with some " +"window managers." +msgstr "" +"Brak: okna dialogowe traktowane są jak zwykłe okna; Normalne: okna dialogowe " +"pozostają na wierzchu okien dokumentu; Agresywne: jak Normalne, może działać " +"lepiej z niektórymi menadżerami okien" + +#: ../../po/../src/dialogs/display-settings.cpp:451 +msgid "Normal" +msgstr "Normalne" + +#: ../../po/../src/dialogs/display-settings.cpp:461 +msgid "Aggressive" +msgstr "Agresywne" + +#: ../../po/../src/dialogs/display-settings.cpp:475 +msgid "Dialogs on top:" +msgstr "Utrzymywanie okien dialogowych na wierzchu:" + +#: ../../po/../src/dialogs/display-settings.cpp:645 +msgid "Show selection cue" +msgstr "Wyróżnianie selekcji" + +#: ../../po/../src/dialogs/display-settings.cpp:646 +msgid "" +"Whether selected objects display a selection cue (the same as in selector)" +msgstr "" +"Decyduje o wyświetlaniu wyróżnienia wybranego obiektu (według ustawienia w " +"zakładce narzędzia Wskaźnik)" + +#: ../../po/../src/dialogs/display-settings.cpp:657 +msgid "Enable gradient editing" +msgstr "Edycja gradientu na obiekcie" + +#: ../../po/../src/dialogs/display-settings.cpp:658 +msgid "Whether selected objects display gradient editing controls" +msgstr "" +"Czy na wybranych obiektach wyświetlone zostaną uchwyty do edycji gradientu" + +#: ../../po/../src/dialogs/display-settings.cpp:719 +msgid "No objects selected to take the style from." +msgstr "Brak wybranych obiektów do pobrania stylu." + +#: ../../po/../src/dialogs/display-settings.cpp:728 +msgid "" +"More than one object selected. Cannot take style from multiple " +"objects." +msgstr "" +"Wybrano więcej niż jeden obiekt. Nie można pobrać stylu z wielu " +"obiektów." + +#: ../../po/../src/dialogs/display-settings.cpp:767 +msgid "Create new objects with:" +msgstr "Tworzenie nowych obiektów z zastosowaniem stylu:" + +#: ../../po/../src/dialogs/display-settings.cpp:777 +msgid "Take from selection" +msgstr "Pobierz z wybranego obiektu" + +#: ../../po/../src/dialogs/display-settings.cpp:778 +msgid "Remember the style of the (first) selected object as this tool's style" +msgstr "Zapisz styl wybranego obiektu jako domyślny dla tego narzędzia" + +#: ../../po/../src/dialogs/display-settings.cpp:782 +#, fuzzy +msgid "Last used style" +msgstr "Wklej _styl" + +#: ../../po/../src/dialogs/display-settings.cpp:782 +msgid "Apply the style you last set on an object" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:790 +msgid "This tool's own style:" +msgstr "Styl właściwy dla tego narzędzia:" + +#: ../../po/../src/dialogs/display-settings.cpp:790 +msgid "" +"Each tool may store its own style to apply to the newly created objects. Use " +"the button below to set it." +msgstr "" +"Każde narzędzie może zachowywać własny styl dla nowo tworzonych obiektów. " +"Przycisk poniżej pozwala ustawić własny styl narzędzia." + +#. Mouse +#: ../../po/../src/dialogs/display-settings.cpp:877 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:55 +msgid "Mouse" +msgstr "Mysz" + +#. TRANSLATORS: "Grab" is a noun here. "Grab sensitivity" is intended to mean how +#. * close on the screen you need to be to an object to be able to grab it with mouse (in +#. * pixels). +#: ../../po/../src/dialogs/display-settings.cpp:883 +msgid "Grab sensitivity:" +msgstr "Czułość chwytania:" + +#: ../../po/../src/dialogs/display-settings.cpp:884 +msgid "" +"How close on the screen you need to be to an object to be able to grab it " +"with mouse (in screen pixels)" +msgstr "" +"Przy jakiej odległości kursora myszy od obiektu (w pikselach ekranowych) " +"możliwe staje się manipulowanie nim" + +#: ../../po/../src/dialogs/display-settings.cpp:885 +#: ../../po/../src/dialogs/display-settings.cpp:897 +#: ../../po/../src/dialogs/display-settings.cpp:912 +#: ../../po/../src/dialogs/display-settings.cpp:930 +#: ../../po/../src/dialogs/display-settings.cpp:970 +msgid "pixels" +msgstr "piksele" + +#: ../../po/../src/dialogs/display-settings.cpp:895 +msgid "Click/drag threshold:" +msgstr "Próg kliknięcia/przeciągania:" + +#: ../../po/../src/dialogs/display-settings.cpp:896 +msgid "" +"Maximum mouse drag (in screen pixels) which is considered a click, not a drag" +msgstr "" +"Największa wartość przesunięcia myszy (w pikselach ekranu) traktowana " +"jeszcze jako kliknięcie, a nie przeciąganie" + +#. Scrolling +#: ../../po/../src/dialogs/display-settings.cpp:907 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:56 +msgid "Scrolling" +msgstr "Przewijanie" + +#: ../../po/../src/dialogs/display-settings.cpp:910 +msgid "Mouse wheel scrolls by:" +msgstr "Kółko myszy przewija o:" + +#: ../../po/../src/dialogs/display-settings.cpp:911 +msgid "" +"One mouse wheel notch scrolls by this distance in screen pixels " +"(horizontally with Shift)" +msgstr "" +"Jedna pozycja obrotu kółka przewija o wybraną ilość pikseli (przewijanie w " +"poziomie z klawiszem Shift)" + +#: ../../po/../src/dialogs/display-settings.cpp:920 +msgid "Ctrl+arrows" +msgstr "Ctrl+strzałki" + +#: ../../po/../src/dialogs/display-settings.cpp:928 +msgid "Scroll by:" +msgstr "Przewijanie o:" + +#: ../../po/../src/dialogs/display-settings.cpp:929 +msgid "Pressing Ctrl+arrow key scrolls by this distance (in screen pixels)" +msgstr "" +"Naciśnięcie Ctrl+strzałka przewija o wybraną odległość (w pikselach " +"ekranowych)" + +#: ../../po/../src/dialogs/display-settings.cpp:939 +msgid "Acceleration:" +msgstr "Przyspieszenie:" + +#: ../../po/../src/dialogs/display-settings.cpp:940 +msgid "" +"Pressing and holding Ctrl+arrow will gradually speed up scrolling (0 for no " +"acceleration)" +msgstr "" +"Przytrzymanie Ctrl+strzałka spowoduje stopniowe przyspieszenie przewijania " +"(0 - brak przyspieszania)" + +#: ../../po/../src/dialogs/display-settings.cpp:949 +msgid "Autoscrolling" +msgstr "Autoprzewijanie" + +#: ../../po/../src/dialogs/display-settings.cpp:957 +msgid "Speed:" +msgstr "Prędkość:" + +#: ../../po/../src/dialogs/display-settings.cpp:958 +msgid "" +"How fast the canvas autoscrolls when you drag beyond canvas edge (0 to turn " +"autoscroll off)" +msgstr "" +"Jak szybkie jest autoprzewijanie gdy obiekt zostaje przeciągnięty poza " +"obrzeże okna dokumentu (0 – autoprzewijanie wyłączone)" + +#: ../../po/../src/dialogs/display-settings.cpp:968 +#: ../../po/../src/ui/dialog/tracedialog.cpp:357 +#: ../../po/../src/ui/dialog/tracedialog.cpp:390 +msgid "Threshold:" +msgstr "Próg:" + +#: ../../po/../src/dialogs/display-settings.cpp:969 +msgid "" +"How far (in screen pixels) you need to be from the canvas edge to trigger " +"autoscroll; positive is outside the canvas, negative is within the canvas" +msgstr "" +"Odległość od obrzeża okna dokumentu przy której uruchamiane jest " +"autoprzewijanie; wartość dodatnia oznacza położenie poza oknem, ujemna " +"wewnątrz okna dokumentu" + +#. Steps +#: ../../po/../src/dialogs/display-settings.cpp:979 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:57 +msgid "Steps" +msgstr "Kroki" + +#: ../../po/../src/dialogs/display-settings.cpp:982 +msgid "Arrow keys move by:" +msgstr "Klawisze strzałek przesuwają o:" + +#: ../../po/../src/dialogs/display-settings.cpp:983 +msgid "" +"Pressing an arrow key moves selected object(s) or node(s) by this distance " +"(in px units)" +msgstr "" +"Naciśnięcie klawisza strzałki przesuwa wybrany obiekt(y) lub węzeł(y) o " +"wybraną wartość (w jednostkach px)" + +#: ../../po/../src/dialogs/display-settings.cpp:984 +#: ../../po/../src/dialogs/display-settings.cpp:995 +#: ../../po/../src/dialogs/display-settings.cpp:1006 +#: ../../po/../src/helper/units.cpp:42 +msgid "px" +msgstr "pks" + +#: ../../po/../src/dialogs/display-settings.cpp:993 +msgid "> and < scale by:" +msgstr "Klawisze > i < zmieniają rozmiar o:" + +#: ../../po/../src/dialogs/display-settings.cpp:994 +msgid "" +"Pressing > or < scales selection up or down by this increment (in px units)" +msgstr "" +"Naciśnięcie klawiszy > lub < odpowiednio powiększa lub pomniejsza rozmiar " +"selekcji o wybraną wartość (w jednostkach px)" + +#: ../../po/../src/dialogs/display-settings.cpp:1004 +msgid "Inset/Outset by:" +msgstr "Odsunięcie na zewnątrz/do środka:" + +#: ../../po/../src/dialogs/display-settings.cpp:1005 +msgid "" +"Inset and Outset commands displace the path by this distance (in px units)" +msgstr "" +"Polecenia odsunięcia na zewnątrz i do środka przesuwają ścieżkę o wybraną " +"odległość (w jednostkach px)" + +#: ../../po/../src/dialogs/display-settings.cpp:1017 +msgid "Compass-like display of angles" +msgstr "Wyświetlanie wartości kątów jak na kompasie" + +#. TRANSLATORS: "positive clockwise" means "increasing in clockwise direction" +#: ../../po/../src/dialogs/display-settings.cpp:1019 +msgid "" +"When on, angles are displayed with 0 at north, 0 to 360 range, positive " +"clockwise; otherwise with 0 at east, -180 to 180 range, positive " +"counterclockwise" +msgstr "" +"Opcja włączona - kąty są mierzone od kierunku \"północnego\", w zakresie 0-" +"360, rosnąco w kierunku zgodnym z ruchem wskazówek zegara; opcja wyłączona - " +"od kierunku \"wschodniego\", w zakresie -180 do 180; rosnąco w kierunku " +"przeciwnym do ruchu wskazówek zegara" + +#: ../../po/../src/dialogs/display-settings.cpp:1026 +msgid "Zoom in/out by:" +msgstr "Powiększenie/pomniejszenie o:" + +#: ../../po/../src/dialogs/display-settings.cpp:1027 +msgid "" +"Zoom tool click, +/- keys, and middle click zoom in and out by this " +"multiplier" +msgstr "" +"Współczynnik wykorzystywany przez narzędzie powiększania, klawisze +/-, " +"środkowy przycisk myszy, przy powiększaniu/pomniejszaniu widoku" + +#: ../../po/../src/dialogs/display-settings.cpp:1028 +#: ../../po/../src/helper/units.cpp:44 +msgid "%" +msgstr "%" + +#. Tools +#: ../../po/../src/dialogs/display-settings.cpp:1037 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:58 +msgid "Tools" +msgstr "Narzędzia" + +#: ../../po/../src/dialogs/display-settings.cpp:1045 +msgid "Selector" +msgstr "Wskaźnik" + +#: ../../po/../src/dialogs/display-settings.cpp:1056 +msgid "Node" +msgstr "Edycja węzłów" + +#: ../../po/../src/dialogs/display-settings.cpp:1064 +#: ../../po/../src/verbs.cpp:2073 +#: ../../po/../src/widgets/desktop-widget.cpp:277 +msgid "Zoom" +msgstr "Powiększenie" + +#. The 4 shape tools +#: ../../po/../src/dialogs/display-settings.cpp:1071 +msgid "Shapes" +msgstr "Figury" + +#: ../../po/../src/dialogs/display-settings.cpp:1079 +#: ../../po/../src/verbs.cpp:2055 +msgid "Rectangle" +msgstr "Prostokąt" + +#: ../../po/../src/dialogs/display-settings.cpp:1085 +#: ../../po/../src/verbs.cpp:2057 +msgid "Ellipse" +msgstr "Elipsa" + +#: ../../po/../src/dialogs/display-settings.cpp:1091 +#: ../../po/../src/verbs.cpp:2059 +msgid "Star" +msgstr "Gwiazda" + +#: ../../po/../src/dialogs/display-settings.cpp:1097 +#: ../../po/../src/verbs.cpp:2061 +msgid "Spiral" +msgstr "Spirala" + +#: ../../po/../src/dialogs/display-settings.cpp:1111 +#: ../../po/../src/verbs.cpp:2063 +msgid "Pencil" +msgstr "Ołówek" + +#: ../../po/../src/dialogs/display-settings.cpp:1114 +msgid "Tolerance:" +msgstr "Zaokrąglenie:" + +#: ../../po/../src/dialogs/display-settings.cpp:1115 +msgid "" +"This value affects the amount of smoothing applied to freehand lines; lower " +"values produce more uneven paths with more nodes" +msgstr "Wartość wpływa na wygładzenie i uproszczenie krzywej; " + +#: ../../po/../src/dialogs/display-settings.cpp:1131 +#: ../../po/../src/verbs.cpp:2065 +msgid "Pen" +msgstr "Pióro" + +#: ../../po/../src/dialogs/display-settings.cpp:1140 +#: ../../po/../src/verbs.cpp:2067 +msgid "Calligraphy" +msgstr "Kaligrafia" + +#: ../../po/../src/dialogs/display-settings.cpp:1147 +#: ../../po/../src/dialogs/text-edit.cpp:353 +#: ../../po/../src/ui/dialog/text-properties.cpp:37 +#: ../../po/../src/verbs.cpp:2069 +msgid "Text" +msgstr "Tekst" + +#: ../../po/../src/dialogs/display-settings.cpp:1157 +#: ../../po/../src/verbs.cpp:2071 +msgid "Gradient" +msgstr "Gradient" + +#: ../../po/../src/dialogs/display-settings.cpp:1164 +#: ../../po/../src/verbs.cpp:2077 +msgid "Connector" +msgstr "Łącznik" + +#: ../../po/../src/dialogs/display-settings.cpp:1171 +#: ../../po/../src/verbs.cpp:2075 +msgid "Dropper" +msgstr "Pipeta" + +#. Windows +#: ../../po/../src/dialogs/display-settings.cpp:1183 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:59 +msgid "Windows" +msgstr "Okna" + +#: ../../po/../src/dialogs/display-settings.cpp:1188 +msgid "Save window geometry" +msgstr "Zapisanie położenia okien" + +#: ../../po/../src/dialogs/display-settings.cpp:1189 +msgid "" +"Save the window size and position with each document (only for Inkscape SVG " +"format)" +msgstr "" +"Zapisanie wielkości i położenia okien z każdym dokumentem (tylko dla formatu " +"Inkscape SVG)" + +#: ../../po/../src/dialogs/display-settings.cpp:1196 +msgid "Dialogs are hidden in taskbar" +msgstr "Ukrycie okien dialogowych na pasku zadań" + +#: ../../po/../src/dialogs/display-settings.cpp:1197 +msgid "Whether dialog windows are to be hidden in the window manager taskbar" +msgstr "" +"Wyłącza wyświetlanie przycisków okien dialogowych na pasku zadań menadżera " +"okien" + +#: ../../po/../src/dialogs/display-settings.cpp:1204 +msgid "Zoom when window is resized" +msgstr "Zmiana powiększenia przy zmianie rozmiaru okna" + +#: ../../po/../src/dialogs/display-settings.cpp:1205 +msgid "" +"Zoom drawing when document window is resized, to keep the same area visible " +"(this is the default which can be changed in any window using the button " +"above the right scrollbar)" +msgstr "" +"Powoduje zmianę powiększenia wraz ze zmianą rozmiarów okna dokumentu, z " +"zachowaniem widocznego obszaru (ta opcja ustawia domyślne zachowanie, które " +"może być zmienione dla każdego okna przyciskiem nad paskiem przewijania po " +"prawej stronie)" + +#. Clones +#: ../../po/../src/dialogs/display-settings.cpp:1213 +#: ../../po/../src/dialogs/find.cpp:624 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:60 +msgid "Clones" +msgstr "Klonowanie" + +#: ../../po/../src/dialogs/display-settings.cpp:1217 +msgid "When the original moves, its clones and linked offsets:" +msgstr "Gdy oryginał jest przesuwany, jego klony i połączone odsunięcia:" + +#: ../../po/../src/dialogs/display-settings.cpp:1229 +msgid "Move in parallel" +msgstr "Przesuwają się równolegle" + +#: ../../po/../src/dialogs/display-settings.cpp:1230 +msgid "Clones are translated by the same vector as their original." +msgstr "Klony są przesuwane o ten sam wektor co oryginalny obiekt." + +#: ../../po/../src/dialogs/display-settings.cpp:1237 +msgid "Stay unmoved" +msgstr "Pozostają nieprzemieszczone" + +#: ../../po/../src/dialogs/display-settings.cpp:1238 +msgid "Clones preserve their positions when their original is moved." +msgstr "" +"Klony zachowują swoją pozycję, podczas gdy oryginalny obiekt zostaje " +"przesunięty" + +#: ../../po/../src/dialogs/display-settings.cpp:1245 +msgid "Move according to transform" +msgstr "Przemieszczają się zgodnie z przypisanym przekształceniem" + +#: ../../po/../src/dialogs/display-settings.cpp:1246 +msgid "" +"Each clone moves according to the value of its transform= attribute. For " +"example, a rotated clone will move in a different direction than its " +"original." +msgstr "" +"Każda ze sklonowanych kopii zostaje przemieszczona zgodnie z wartością " +"przypisanego do niej przekształcenia. Na przykład obrócony klon przesuwa się " +"w inny sposób niż oryginalny obiekt." + +#: ../../po/../src/dialogs/display-settings.cpp:1255 +msgid "When the original is deleted, its clones:" +msgstr "Gdy oryginał zostaje skasowany, jego klony:" + +#: ../../po/../src/dialogs/display-settings.cpp:1267 +msgid "Are unlinked" +msgstr "Zostają odłączone" + +#: ../../po/../src/dialogs/display-settings.cpp:1267 +msgid "Orphaned clones are converted to regular objects." +msgstr "Osierocone klony zostają zamienione na zwykłe obiekty." + +#: ../../po/../src/dialogs/display-settings.cpp:1273 +msgid "Are deleted" +msgstr "Zostają skasowane" + +#: ../../po/../src/dialogs/display-settings.cpp:1273 +msgid "Orphaned clones are deleted along with their original." +msgstr "Osierocone obiekty zostają skasowane razem z oryginalnym obiektem." + +#. Transforms +#. TRANSLATORS: Noun, i.e. transformations. +#: ../../po/../src/dialogs/display-settings.cpp:1289 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:61 +msgid "Transforms" +msgstr "Przekształcenia" + +#: ../../po/../src/dialogs/display-settings.cpp:1292 +msgid "Scale stroke width" +msgstr "Skalowanie grubości konturu" + +#: ../../po/../src/dialogs/display-settings.cpp:1293 +#: ../../po/../src/widgets/select-toolbar.cpp:568 +msgid "When scaling objects, scale the stroke width by the same proportion" +msgstr "Przy skalowaniu obiektów grubość konturu zmienia się proporcjonalnie" + +#: ../../po/../src/dialogs/display-settings.cpp:1300 +msgid "Scale rounded corners in rectangles" +msgstr "Skalowanie zaokrąglonych narożników prostokątów" + +#: ../../po/../src/dialogs/display-settings.cpp:1301 +#: ../../po/../src/widgets/select-toolbar.cpp:580 +msgid "When scaling rectangles, scale the radii of rounded corners" +msgstr "" +"Przy skalowaniu prostokątów promień zaokrąglenia ich narożników jest " +"odpowiednio zmieniany" + +#: ../../po/../src/dialogs/display-settings.cpp:1308 +msgid "Transform gradients" +msgstr "Przekształcanie gradientów" + +#: ../../po/../src/dialogs/display-settings.cpp:1309 +#: ../../po/../src/widgets/select-toolbar.cpp:592 +msgid "Transform gradients (in fill or stroke) along with the objects" +msgstr "Przekształcenie gradientu (w wypełnieniu i konturze) wraz z obiektami" + +#: ../../po/../src/dialogs/display-settings.cpp:1316 +msgid "Transform patterns" +msgstr "Przekształcanie deseni" + +#: ../../po/../src/dialogs/display-settings.cpp:1317 +#: ../../po/../src/widgets/select-toolbar.cpp:604 +msgid "Transform patterns (in fill or stroke) along with the objects" +msgstr "Przekształcenie deseni (w wypełnieniu i konturze) wraz z obiektami" + +#. TRANSLATORS: How to specify the affine transformation in the SVG file. +#: ../../po/../src/dialogs/display-settings.cpp:1327 +msgid "Store transformation:" +msgstr "Sposób zapisu przekształcenia:" + +#: ../../po/../src/dialogs/display-settings.cpp:1338 +msgid "Optimized" +msgstr "Zoptymalizowany" + +#: ../../po/../src/dialogs/display-settings.cpp:1339 +msgid "" +"If possible, apply transformation to objects without adding a transform= " +"attribute" +msgstr "" +"Gdy tylko możliwe przekształcenie zostanie wykonane na obiekcie bez " +"dodawania do jego definicji atrybutu 'transform='" + +#: ../../po/../src/dialogs/display-settings.cpp:1346 +msgid "Preserved" +msgstr "Zawsze zapisywane" + +#: ../../po/../src/dialogs/display-settings.cpp:1347 +msgid "Always store transformation as a transform= attribute on objects" +msgstr "" +"Przekształcenie jest zawsze zapisywane z obiektem w postaci atrybutu " +"'transform='" + +#. Selecting +#: ../../po/../src/dialogs/display-settings.cpp:1355 +msgid "Selecting" +msgstr "Zaznaczanie" + +#: ../../po/../src/dialogs/display-settings.cpp:1357 +msgid "Ctrl+A, Tab, Shift+Tab:" +msgstr "Działanie klawiszy Ctrl+A, Tab, Shift+Tab:" + +#: ../../po/../src/dialogs/display-settings.cpp:1366 +msgid "Select only within current layer" +msgstr "Zaznaczanie jedynie w obrębie aktywnej warstwy" + +#: ../../po/../src/dialogs/display-settings.cpp:1367 +msgid "" +"Uncheck this to make keyboard selection commands work on objects in all " +"layers" +msgstr "Wyłączenie tej opcji pozwala zaznaczyć obiekty na wszystkich " + +#: ../../po/../src/dialogs/display-settings.cpp:1374 +msgid "Ignore hidden objects" +msgstr "Pominięcie ukrytych obiektów" + +#: ../../po/../src/dialogs/display-settings.cpp:1375 +msgid "" +"Uncheck this to be able to select objects that are hidden (either by " +"themselves or by being in a hidden group or layer)" +msgstr "" +"Wyłącznie tej opcji pozwala zaznaczyć ukryte obiekty (zarówno te ustawione " +"jako ukryte, jak i znajdujące się w ukrytej grupie lub warstwie)" + +#: ../../po/../src/dialogs/display-settings.cpp:1382 +msgid "Ignore locked objects" +msgstr "Pominięcie zablokowanych obiektów" + +#: ../../po/../src/dialogs/display-settings.cpp:1383 +msgid "" +"Uncheck this to be able to select objects that are locked (either by " +"themselves or by being in a locked group or layer)" +msgstr "" +"Wyłącznie tej opcji pozwala zaznaczyć zablokowane obiekty (zarówno te " +"ustawione jako zablokowane, jak i znajdujące się w zablokowanej grupie lub " +"warstwie)" + +#. To be broken into: Display, Save, Export, SVG, Commands +#: ../../po/../src/dialogs/display-settings.cpp:1391 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:62 +msgid "Misc" +msgstr "Pozostałe" + +#: ../../po/../src/dialogs/display-settings.cpp:1394 +msgid "Default export resolution:" +msgstr "Domyślna rozdzielczość przy eksporcie:" + +#: ../../po/../src/dialogs/display-settings.cpp:1395 +msgid "Default bitmap resolution (in dots per inch) in the Export dialog" +msgstr "" +"Domyślna rozdzielczość przy eksporcie do bitmapy (w punktach na cal) " +"wyświetlana w oknie dialogowym eksportu" + +#. FIXME: add "Used for new exports; once exported, documents remember this value on per-object basis" when implemented +#: ../../po/../src/dialogs/display-settings.cpp:1396 +#: ../../po/../src/dialogs/export.cpp:442 +msgid "dpi" +msgstr "dpi" + +#. TRANSLATORS: When on, an imported bitmap creates an element; otherwise it is a +#. * rectangle with bitmap fill. +#: ../../po/../src/dialogs/display-settings.cpp:1407 +msgid "Import bitmap as " +msgstr "Importowanie bitmap jako obiektów " + +#: ../../po/../src/dialogs/display-settings.cpp:1408 +msgid "" +"When on, an imported bitmap creates an element; otherwise it is a " +"rectangle with bitmap fill" +msgstr "" +"Włączenie tej opcji powoduje utworzenie przy imporcie obiektu svg ; w " +"przeciwnym razie obraz jest wstawiany jako prostokąt z wypełnieniem bitmapą" + +#. TRANSLATORS: When on, the print out (currently Postscript) will have +#. * a comment with the each object's label visible, marking the section +#. * of the printing commands that represent the given object. +#: ../../po/../src/dialogs/display-settings.cpp:1418 +msgid "Add label comments to printing output" +msgstr "Dodanie komentarzy do pliku wyjściowego drukarki" + +#: ../../po/../src/dialogs/display-settings.cpp:1419 +msgid "" +"When on, a comment will be added to the raw print output, marking the " +"rendered output for an object with its label" +msgstr "" +"Włączenie tej opcji powoduje wstawienie do pliku wyjściowego drukarki " +"(Postscript) komentarzy opisujących każdy obiekt jego etykietą" + +#. TRANSLATORS: When on, enable the effects menu, default is off +#: ../../po/../src/dialogs/display-settings.cpp:1427 +msgid "Enable script effects (requires restart) - EXPERIMENTAL" +msgstr "Włączenie skryptów z efektami (wymaga restartu) - EKSPERYMENTALNE" + +#: ../../po/../src/dialogs/display-settings.cpp:1428 +msgid "" +"When on, the effects menu is enabled, allowing external effect scripts to be " +"called, requires restart before effective - EXPERIMENTAL" +msgstr "" +"Włączenie tej opcji udostępnia menu skryptów, pozwalając na wykonywanie " +"zewnętrznych skryptów z efektami, wymaga restartu programu - EKSPERYMENTALNE" + +#. TRANSLATORS: The maximum length of the Open Recent list in the File menu. +#: ../../po/../src/dialogs/display-settings.cpp:1436 +msgid "Max recent documents:" +msgstr "Liczba pozycji ostatnio otwieranych dokumentów:" + +#: ../../po/../src/dialogs/display-settings.cpp:1437 +msgid "The maximum length of the Open Recent list in the File menu" +msgstr "" +"Maksymalna liczba pozycji przechowywanych na liście ostatnio otwieranych " +"dokumentów w menu Plik" + +#: ../../po/../src/dialogs/display-settings.cpp:1447 +msgid "Simplification threshold:" +msgstr "Próg dla polecenia uproszczenia:" + +#: ../../po/../src/dialogs/display-settings.cpp:1448 +msgid "" +"How strong is the Simplify command by default. If you invoke this command " +"several times in quick succession, it will act more and more aggressively; " +"invoking it again after a pause restores the default threshold." +msgstr "" +"Domyślna wartość używana przez polecenie Uprość. Wywołanie tego polecenia " +"kilkakrotnie w krótkich odstępach czasu powoduje nasilenie jego działania. " +"Ponowne wykonanie po krótkiej przerwie przywraca wartość domyślną." + +#: ../../po/../src/dialogs/display-settings.cpp:1469 +msgid "Oversample bitmaps:" +msgstr "Nadpróbkowanie bitmap:" + +#: ../../po/../src/dialogs/display-settings.cpp:1488 +msgid "2x2" +msgstr "2x2" + +#: ../../po/../src/dialogs/display-settings.cpp:1494 +msgid "4x4" +msgstr "4x4" + +#: ../../po/../src/dialogs/display-settings.cpp:1500 +msgid "8x8" +msgstr "8x8" + +#: ../../po/../src/dialogs/display-settings.cpp:1506 +msgid "16x16" +msgstr "16x16" + +#. "view_icon_preview" +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2143 +msgid "_Page" +msgstr "Cała _strona" + +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2147 +msgid "_Drawing" +msgstr "Cały _rysunek" + +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2149 +msgid "_Selection" +msgstr "_Zaznaczenie" + +#: ../../po/../src/dialogs/export.cpp:133 +msgid "_Custom" +msgstr "Rozmiar _użytkownika" + +#: ../../po/../src/dialogs/export.cpp:254 +msgid "Export area" +msgstr "Obszar eksportowany" + +#: ../../po/../src/dialogs/export.cpp:300 +msgid "_x0:" +msgstr "_x0:" + +#: ../../po/../src/dialogs/export.cpp:305 +msgid "x_1:" +msgstr "x_1:" + +#: ../../po/../src/dialogs/export.cpp:316 +msgid "_y0:" +msgstr "_y0:" + +#: ../../po/../src/dialogs/export.cpp:321 +msgid "y_1:" +msgstr "y_1:" + +#: ../../po/../src/dialogs/export.cpp:406 +msgid "Bitmap size" +msgstr "Rozmiar bitmapy" + +#: ../../po/../src/dialogs/export.cpp:416 +msgid "_Width:" +msgstr "_Szerokość:" + +#: ../../po/../src/dialogs/export.cpp:416 +#: ../../po/../src/dialogs/export.cpp:431 +msgid "pixels at" +msgstr "pikseli przy" + +#: ../../po/../src/dialogs/export.cpp:426 +msgid "dp_i" +msgstr "dp_i" + +#: ../../po/../src/dialogs/export.cpp:448 +msgid "_Filename" +msgstr "_Nazwa pliku" + +#: ../../po/../src/dialogs/export.cpp:512 +msgid "_Browse..." +msgstr "_Przeglądaj..." + +#: ../../po/../src/dialogs/export.cpp:539 +msgid " _Export " +msgstr "_Eksportuj " + +#: ../../po/../src/dialogs/export.cpp:541 +msgid "Export the bitmap file with these settings" +msgstr "Eksportowanie bitmapy z wybranymi ustawieniami" + +#: ../../po/../src/dialogs/export.cpp:968 +msgid "You have to enter a filename" +msgstr "Nie podano nazwy pliku" + +#: ../../po/../src/dialogs/export.cpp:973 +msgid "The chosen area to be exported is invalid" +msgstr "Wybrany obszar eksportu jest nieprawidłowy" + +#: ../../po/../src/dialogs/export.cpp:982 +#, c-format +msgid "Directory %s does not exist or is not a directory.\n" +msgstr "Katalog %s nie istnieje lub wybrany plik nie jest katalogiem.\n" + +#: ../../po/../src/dialogs/export.cpp:998 +msgid "Export in progress" +msgstr "Postęp eksportu" + +#: ../../po/../src/dialogs/export.cpp:1004 +#, c-format +msgid "Exporting %s (%d x %d)" +msgstr "Eksportowanie %s (%d x %d)" + +#: ../../po/../src/dialogs/export.cpp:1031 +#, c-format +msgid "Could not export to filename %s.\n" +msgstr "Nie można wyeksportować do pliku %s.\n" + +#: ../../po/../src/dialogs/export.cpp:1137 +msgid "Select a filename for exporting" +msgstr "Wybierz nazwę eksportowanego pliku" + +#: ../../po/../src/dialogs/filedialog.cpp:367 +msgid "No preview" +msgstr " Brak podglądu" + +#: ../../po/../src/dialogs/filedialog.cpp:468 +msgid "too large for preview" +msgstr " Plik zbyt duży do podglądu" + +#: ../../po/../src/dialogs/filedialog.cpp:762 +#: ../../po/../src/dialogs/filedialog.cpp:763 +msgid "All Images" +msgstr "Pliki obrazów" + +#: ../../po/../src/dialogs/filedialog.cpp:767 +#: ../../po/../src/dialogs/filedialog.cpp:768 +msgid "All Files" +msgstr "Wszystkie pliki" + +#: ../../po/../src/dialogs/filedialog.cpp:774 +#: ../../po/../src/dialogs/filedialog.cpp:775 +msgid "All Inkscape Files" +msgstr "Wszystkie pliki Inkscape" + +#: ../../po/../src/dialogs/filedialog.cpp:1176 +msgid "Guess from extension" +msgstr "Według rozszerzenia" + +#. ###### Add the file types menu +#. createFilterMenu(); +#. ###### Do we want the .xxx extension automatically added? +#: ../../po/../src/dialogs/filedialog.cpp:1261 +msgid "Append filename extension automatically" +msgstr "Automatycznie dodaj rozszerzenie nazwy pliku" + +#. TRANSLATORS: "%s" is replaced with "exact" or "partial" when this string is displayed +#: ../../po/../src/dialogs/find.cpp:378 +#, c-format +msgid "%d object found (out of %d), %s match." +msgid_plural "%d objects found (out of %d), %s match." +msgstr[0] "Znaleziono %d obiekt (z %d), dopasowanie %s." +msgstr[1] "Znaleziono %d obiekty (z %d), dopasowanie %s." +msgstr[2] "Znaleziono %d obiektów (z %d), dopasowanie %s." + +#: ../../po/../src/dialogs/find.cpp:381 +msgid "exact" +msgstr "dokładne" + +#: ../../po/../src/dialogs/find.cpp:381 +msgid "partial" +msgstr "częściowe" + +#: ../../po/../src/dialogs/find.cpp:388 +msgid "No objects found" +msgstr "Nie znaleziono obiektów" + +#: ../../po/../src/dialogs/find.cpp:546 +msgid "T_ype: " +msgstr "Typ obiektu:" + +#: ../../po/../src/dialogs/find.cpp:553 +msgid "Search in all object types" +msgstr "Szukaj w obiektach wszystkich rodzajów" + +#: ../../po/../src/dialogs/find.cpp:553 +msgid "All types" +msgstr "Wszystkie typy" + +#: ../../po/../src/dialogs/find.cpp:564 +msgid "Search all shapes" +msgstr "Szukaj we wszystkich rodzajach figur" + +#: ../../po/../src/dialogs/find.cpp:564 +msgid "All shapes" +msgstr "Wszystkie figury" + +#: ../../po/../src/dialogs/find.cpp:581 +msgid "Search rectangles" +msgstr "Szukaj prostokątów" + +#: ../../po/../src/dialogs/find.cpp:581 +msgid "Rectangles" +msgstr "Prostokąty" + +#: ../../po/../src/dialogs/find.cpp:586 +msgid "Search ellipses, arcs, circles" +msgstr "Szukaj elips, łuków i okręgów" + +#: ../../po/../src/dialogs/find.cpp:586 +msgid "Ellipses" +msgstr "Elipsy" + +#: ../../po/../src/dialogs/find.cpp:591 +msgid "Search stars and polygons" +msgstr "Szukaj gwiazd i wielokątów" + +#: ../../po/../src/dialogs/find.cpp:591 +msgid "Stars" +msgstr "Gwiazdy" + +#: ../../po/../src/dialogs/find.cpp:596 +msgid "Search spirals" +msgstr "Szukaj spirali" + +#: ../../po/../src/dialogs/find.cpp:596 +msgid "Spirals" +msgstr "Spirale" + +#. TRANSLATORS: polyline is a set of connected straight line segments +#. http://www.w3.org/TR/SVG11/shapes.html#PolylineElement +#: ../../po/../src/dialogs/find.cpp:609 +msgid "Search paths, lines, polylines" +msgstr "Szukaj ścieżek, linii, polilinii" + +#: ../../po/../src/dialogs/find.cpp:609 +msgid "Paths" +msgstr "Ścieżki" + +#: ../../po/../src/dialogs/find.cpp:614 +msgid "Search text objects" +msgstr "Szukaj obiektów tekstowych" + +#: ../../po/../src/dialogs/find.cpp:614 +msgid "Texts" +msgstr "Teksty" + +#: ../../po/../src/dialogs/find.cpp:619 +msgid "Search groups" +msgstr "Szukaj grup obiektów" + +#: ../../po/../src/dialogs/find.cpp:619 +msgid "Groups" +msgstr "Grupy" + +#: ../../po/../src/dialogs/find.cpp:624 +msgid "Search clones" +msgstr "Szukaj sklonowanych obiektów" + +#: ../../po/../src/dialogs/find.cpp:629 +msgid "Search images" +msgstr "Szukaj obrazów" + +#: ../../po/../src/dialogs/find.cpp:629 +msgid "Images" +msgstr "Obrazy" + +#: ../../po/../src/dialogs/find.cpp:634 +msgid "Search offset objects" +msgstr "Szukaj obiektów powstałych przez odsunięcie" + +#: ../../po/../src/dialogs/find.cpp:634 +msgid "Offsets" +msgstr "Odsunięcia" + +#: ../../po/../src/dialogs/find.cpp:694 +msgid "_Text: " +msgstr "_Tekst: " + +#: ../../po/../src/dialogs/find.cpp:694 +msgid "Find objects by their text content (exact or partial match)" +msgstr "Znajdź obiekty zawierające tekst (lub jego fragment)" + +#: ../../po/../src/dialogs/find.cpp:695 +msgid "_ID: " +msgstr "_ID: " + +#: ../../po/../src/dialogs/find.cpp:695 +msgid "Find objects by the value of the id attribute (exact or partial match)" +msgstr "Znajdź obiekty na podstawie ich identyfikatorów (również fragmentów) " + +#: ../../po/../src/dialogs/find.cpp:696 +msgid "_Style: " +msgstr "Styl: " + +#: ../../po/../src/dialogs/find.cpp:696 +msgid "" +"Find objects by the value of the style attribute (exact or partial match)" +msgstr "" +"Znajdź obiekty na podstawie właściwości ich stylu (również częściowe " +"dopasowanie)" + +#: ../../po/../src/dialogs/find.cpp:697 +msgid "_Attribute: " +msgstr "_Atrybut: " + +#: ../../po/../src/dialogs/find.cpp:697 +msgid "Find objects by the name of an attribute (exact or partial match)" +msgstr "" +"Znajdź obiekty na podstawie ich właściwości (również częściowe dopasowanie)" + +#: ../../po/../src/dialogs/find.cpp:711 +msgid "Search in s_election" +msgstr "Szukaj w _zaznaczeniu" + +#: ../../po/../src/dialogs/find.cpp:715 +msgid "Limit search to the current selection" +msgstr "Ogranicz wyszukiwanie do aktualnie zazanczonych obiektów" + +#: ../../po/../src/dialogs/find.cpp:720 +msgid "Search in current _layer" +msgstr "Szukaj na aktywnej _warstwie" + +#: ../../po/../src/dialogs/find.cpp:724 +msgid "Limit search to the current layer" +msgstr "Ogranicz wyszukiwanie do aktywnej warstwy" + +#: ../../po/../src/dialogs/find.cpp:729 +msgid "Include _hidden" +msgstr "Uwzględnij _ukryte" + +#: ../../po/../src/dialogs/find.cpp:733 +msgid "Include hidden objects in search" +msgstr "Szukaj także wśród obiektów ukrytych" + +#: ../../po/../src/dialogs/find.cpp:738 +msgid "Include l_ocked" +msgstr "Uwzględnij za_blokowane" + +#: ../../po/../src/dialogs/find.cpp:742 +msgid "Include locked objects in search" +msgstr "Szukaj także wśród zablokowanych obiektów" + +#: ../../po/../src/dialogs/find.cpp:753 +msgid "Clear values" +msgstr "Wyczyść wszystko" + +#: ../../po/../src/dialogs/find.cpp:754 +msgid "_Find" +msgstr "_Szukaj" + +#: ../../po/../src/dialogs/find.cpp:754 +msgid "Select objects matching all of the fields you filled in" +msgstr "Zaznacza obiekty spełniające wszystkie wybrane kryteria" + +#: ../../po/../src/dialogs/iconpreview.cpp:145 +#, c-format +msgid "%d x %d" +msgstr "%d x %d" + +#: ../../po/../src/dialogs/iconpreview.cpp:193 +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:857 +#: ../../po/../src/widgets/desktop-widget.cpp:1069 +msgid "Selection" +msgstr "Zaznaczenie" + +#: ../../po/../src/dialogs/iconpreview.cpp:195 +msgid "Selection only or whole document" +msgstr "Tylko zaznaczenie lub cały dokument" + +#: ../../po/../src/dialogs/iconpreview.cpp:203 +msgid "Refresh the icons" +msgstr "Odśwież ikony" + +#. Create the label for the object id +#: ../../po/../src/dialogs/item-properties.cpp:126 +#: ../../po/../src/dialogs/item-properties.cpp:327 +#: ../../po/../src/dialogs/item-properties.cpp:396 +#: ../../po/../src/dialogs/item-properties.cpp:403 +msgid "_Id" +msgstr "_Id" + +#: ../../po/../src/dialogs/item-properties.cpp:135 +msgid "" +"The id= attribute (only letters, digits, and the characters .-_: allowed)" +msgstr "" +"Identyfikator, atrybut 'id=' obiektu (dozwolone jedynie litery, cyfry, oraz " +"znaki .-_: )" + +#. Button for setting the object's id, label, title and description. +#: ../../po/../src/dialogs/item-properties.cpp:149 +msgid "_Set" +msgstr "_Ustaw" + +#. Create the label for the object label +#: ../../po/../src/dialogs/item-properties.cpp:158 +msgid "_Label" +msgstr "_Etykieta" + +#: ../../po/../src/dialogs/item-properties.cpp:167 +msgid "A freeform label for the object" +msgstr "Dowolna etykieta tekstowa obiektu" + +#. Create the label for the object title +#: ../../po/../src/dialogs/item-properties.cpp:179 +#: ../../po/../src/dialogs/rdf.cpp:243 +msgid "Title" +msgstr "Tytuł" + +#. Create the frame for the object description +#: ../../po/../src/dialogs/item-properties.cpp:196 +#: ../../po/../src/dialogs/rdf.cpp:287 +msgid "Description" +msgstr "Opis" + +#. Hide +#: ../../po/../src/dialogs/item-properties.cpp:223 +msgid "_Hide" +msgstr "U_kryty" + +#: ../../po/../src/dialogs/item-properties.cpp:224 +msgid "Check to make the object invisible" +msgstr "Zaznaczenie powoduje, że obiekt staje się niewidoczny" + +#. Lock +#. TRANSLATORS: "Lock" is a verb here +#: ../../po/../src/dialogs/item-properties.cpp:233 +msgid "L_ock" +msgstr "_Zablokowany" + +#: ../../po/../src/dialogs/item-properties.cpp:234 +msgid "Check to make the object insensitive (not selectable by mouse)" +msgstr "Zaznaczenie powoduje, że obiektu nie da się wybrać myszą" + +#: ../../po/../src/dialogs/item-properties.cpp:310 +#: ../../po/../src/dialogs/item-properties.cpp:317 +msgid "Ref" +msgstr "" + +#: ../../po/../src/dialogs/item-properties.cpp:398 +msgid "Id invalid! " +msgstr "ID nieprawidłowy!" + +#: ../../po/../src/dialogs/item-properties.cpp:400 +msgid "Id exists! " +msgstr "Taki ID już istnieje!" + +#: ../../po/../src/dialogs/layer-properties.cpp:50 +msgid "Layer name:" +msgstr "Nazwa warstwy:" + +#: ../../po/../src/dialogs/layer-properties.cpp:133 +msgid "Rename Layer" +msgstr "Zmiana nazwy warstwy" + +#: ../../po/../src/dialogs/layer-properties.cpp:136 +msgid "_Rename" +msgstr "_Zmień" + +#. TRANSLATORS: This means "The layer has been renamed" +#: ../../po/../src/dialogs/layer-properties.cpp:147 +msgid "Renamed layer" +msgstr "Nazwa warstwy została zmieniona" + +#: ../../po/../src/dialogs/layer-properties.cpp:151 +msgid "Add Layer" +msgstr "Dodaj warstwę" + +#: ../../po/../src/dialogs/layer-properties.cpp:153 +msgid "_Add" +msgstr "_Dodaj" + +#: ../../po/../src/dialogs/layer-properties.cpp:167 +msgid "New layer created." +msgstr "Utworzono nową warstwę" + +#: ../../po/../src/dialogs/object-attributes.cpp:34 +msgid "Href:" +msgstr "Adres:" + +#: ../../po/../src/dialogs/object-attributes.cpp:35 +msgid "Target:" +msgstr "Cel:" + +#: ../../po/../src/dialogs/object-attributes.cpp:36 +msgid "Type:" +msgstr "Typ:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkRoleAttribute +#. Identifies the type of the related resource with an absolute URI +#: ../../po/../src/dialogs/object-attributes.cpp:39 +msgid "Role:" +msgstr "Rola:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkArcRoleAttribute +#. For situations where the nature/role alone isn't enough, this offers an additional URI defining the purpose of the link. +#: ../../po/../src/dialogs/object-attributes.cpp:42 +msgid "Arcrole:" +msgstr "" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkTitleAttribute +#: ../../po/../src/dialogs/object-attributes.cpp:44 +msgid "Title:" +msgstr "Tytuł:" + +#: ../../po/../src/dialogs/object-attributes.cpp:45 +msgid "Show:" +msgstr "Wyświetlanie:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkActuateAttribute +#: ../../po/../src/dialogs/object-attributes.cpp:47 +msgid "Actuate:" +msgstr "Pobudzenie:" + +#: ../../po/../src/dialogs/object-attributes.cpp:52 +msgid "URL:" +msgstr "URL:" + +#: ../../po/../src/dialogs/object-attributes.cpp:53 +msgid "X:" +msgstr "X:" + +#: ../../po/../src/dialogs/object-attributes.cpp:54 +msgid "Y:" +msgstr "Y:" + +#: ../../po/../src/dialogs/object-attributes.cpp:98 +#, c-format +msgid "%s attributes" +msgstr "Właściwości obiektu %s" + +#: ../../po/../src/dialogs/object-properties.cpp:158 +msgid "_Fill" +msgstr "_Wypełnienie" + +#: ../../po/../src/dialogs/object-properties.cpp:165 +msgid "Stroke _paint" +msgstr "_Kontur" + +#: ../../po/../src/dialogs/object-properties.cpp:172 +msgid "Stroke st_yle" +msgstr "_Styl konturu" + +#: ../../po/../src/dialogs/object-properties.cpp:183 +msgid "Master _opacity" +msgstr "_Ogólna nieprzepuszczalność" + +#: ../../po/../src/dialogs/rdf.cpp:244 +msgid "Name by which this document is formally known." +msgstr "Oficjalna nazwa dokumentu" + +#: ../../po/../src/dialogs/rdf.cpp:246 +msgid "Date" +msgstr "Data" + +#: ../../po/../src/dialogs/rdf.cpp:247 +msgid "Date associated with the creation of this document (YYYY-MM-DD)." +msgstr "Data utworzenia skojarzona z tym dokumentem, w formacie (RRRR-MM-DD)" + +#: ../../po/../src/dialogs/rdf.cpp:249 +msgid "Format" +msgstr "Format" + +#: ../../po/../src/dialogs/rdf.cpp:250 +msgid "The physical or digital manifestation of this document (MIME type)." +msgstr "Fizyczny lub cyfrowy wyróżnik tego dokumentu (typ MIME)" + +#: ../../po/../src/dialogs/rdf.cpp:252 +msgid "Type" +msgstr "Typ:" + +#: ../../po/../src/dialogs/rdf.cpp:253 +msgid "Type of document (DCMI Type)." +msgstr "Typ dokumentu (typ DCMI)" + +#: ../../po/../src/dialogs/rdf.cpp:256 +msgid "Creator" +msgstr "Autor" + +#: ../../po/../src/dialogs/rdf.cpp:257 +msgid "" +"Name of entity primarily responsible for making the content of this document." +msgstr "Nazwa jednostki odpowiedzialnej za zawartość tego dokumentu" + +#: ../../po/../src/dialogs/rdf.cpp:259 +msgid "Rights" +msgstr "Własność" + +#: ../../po/../src/dialogs/rdf.cpp:260 +msgid "" +"Name of entity with rights to the Intellectual Property of this document." +msgstr "Nazwa jednostki posiadającej prawa autorskie do tego dokumentu" + +#: ../../po/../src/dialogs/rdf.cpp:262 +msgid "Publisher" +msgstr "Wydawca" + +#: ../../po/../src/dialogs/rdf.cpp:263 +msgid "Name of entity responsible for making this document available." +msgstr "Nazwa jednostki udostępniającej ten dokument" + +#: ../../po/../src/dialogs/rdf.cpp:266 +msgid "Identifier" +msgstr "Identyfikator" + +#: ../../po/../src/dialogs/rdf.cpp:267 +msgid "Unique URI to reference this document." +msgstr "Specyficzny identyfikator (URI) opisujący dokument" + +#: ../../po/../src/dialogs/rdf.cpp:269 +msgid "Source" +msgstr "Źródło" + +#: ../../po/../src/dialogs/rdf.cpp:270 +msgid "Unique URI to reference the source of this document." +msgstr "Specyficzny identyfikator (URI) dla źródła dokumentu" + +#: ../../po/../src/dialogs/rdf.cpp:272 +msgid "Relation" +msgstr "Powiązanie" + +#: ../../po/../src/dialogs/rdf.cpp:273 +msgid "Unique URI to a related document." +msgstr "Identyfikator (URI) dla powiązanego dokumentu" + +#: ../../po/../src/dialogs/rdf.cpp:275 +msgid "Language" +msgstr "Język" + +#: ../../po/../src/dialogs/rdf.cpp:276 +msgid "" +"Two-letter language tag with optional subtags for the language of this " +"document. (e.g. 'en-GB')" +msgstr "" +"Dwuliterowy symbol języka z opcjonalnym rozszerzeniem, określający język " +"dokumentu (n.p. 'pl', 'en', 'en-GB')" + +#: ../../po/../src/dialogs/rdf.cpp:278 +msgid "Keywords" +msgstr "Słowa kluczowe" + +#: ../../po/../src/dialogs/rdf.cpp:279 +msgid "" +"The topic of this document as comma-separated key words, phrases, or " +"classifications." +msgstr "" +"Zagadnienia związane z tematem dokumentu, w postaci oddzielonych przecinkami " +"słów kluczowych, wyrażeń lub klasyfikacji" + +#. TRANSLATORS: "Coverage": the spatial or temporal characteristics of the content. +#. For info, see Appendix D of http://www.w3.org/TR/1998/WD-rdf-schema-19980409/ +#: ../../po/../src/dialogs/rdf.cpp:283 +msgid "Coverage" +msgstr "Tematyka" + +#: ../../po/../src/dialogs/rdf.cpp:284 +msgid "Extent or scope of this document." +msgstr "Tematyka lub zakres tego dokumentu" + +#: ../../po/../src/dialogs/rdf.cpp:288 +msgid "A short account of the content of this document." +msgstr "Krótkie podsumowanie zawartości dokumentu" + +#. FIXME: need to handle 1 agent per line of input +#: ../../po/../src/dialogs/rdf.cpp:292 +msgid "Contributors" +msgstr "Współautorzy" + +#: ../../po/../src/dialogs/rdf.cpp:293 +msgid "" +"Names of entities responsible for making contributions to the content of " +"this document." +msgstr "Nazwy jednostek biorących udział w tworzeniu zawartości tego dokumentu" + +#. TRANSLATORS: URL to a page that defines the license for the document +#: ../../po/../src/dialogs/rdf.cpp:297 +msgid "URI" +msgstr "URL" + +#. TRANSLATORS: this is where you put a URL to a page that defines the license +#: ../../po/../src/dialogs/rdf.cpp:299 +msgid "URI to this document's license's namespace definition." +msgstr "Adres URL do strony zawierającej definicję licencji tego dokumnetu" + +#. TRANSLATORS: fragment of XML representing the license of the document +#: ../../po/../src/dialogs/rdf.cpp:303 +msgid "Fragment" +msgstr "Fragment" + +#: ../../po/../src/dialogs/rdf.cpp:304 +msgid "XML fragment for the RDF 'License' section." +msgstr "Fragment XML zawierający sekcję licencji RDF" + +#: ../../po/../src/dialogs/stroke-style.cpp:774 +#: ../../po/../src/widgets/gradient-vector.cpp:263 +#: ../../po/../src/widgets/paint-selector.cpp:751 +msgid "No document selected" +msgstr "Nie wybrano dokumentu" + +#: ../../po/../src/dialogs/stroke-style.cpp:992 +msgid "Stroke width" +msgstr "Grubość konturu" + +#. Join type +#. TRANSLATORS: The line join style specifies the shape to be used at the +#. corners of paths. It can be "miter", "round" or "bevel". +#: ../../po/../src/dialogs/stroke-style.cpp:1015 +msgid "Join:" +msgstr "Połączenie:" + +#. TRANSLATORS: Miter join: joining lines with a sharp (pointed) corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1027 +msgid "Miter join" +msgstr "Narożnik" + +#. TRANSLATORS: Round join: joining lines with a rounded corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1035 +msgid "Round join" +msgstr "Zaokrąglenie" + +#. TRANSLATORS: Bevel join: joining lines with a blunted (flattened) corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1043 +msgid "Bevel join" +msgstr "Ścięcie" + +#. Miterlimit +#. TRANSLATORS: Miter limit: only for "miter join", this limits the length +#. of the sharp "spike" when the lines connect at too sharp an angle. +#. When two line segments meet at a sharp angle, a miter join results in a +#. spike that extends well beyond the connection point. The purpose of the +#. miter limit is to cut off such spikes (i.e. convert them into bevels) +#. when they become too long. +#: ../../po/../src/dialogs/stroke-style.cpp:1054 +msgid "Miter limit:" +msgstr "Limit narożników:" + +#: ../../po/../src/dialogs/stroke-style.cpp:1062 +msgid "Maximum length of the miter (in units of stroke width)" +msgstr "Limit długości narożników (jako wielokrotność grubości konturu)" + +#. Cap type +#. TRANSLATORS: cap type specifies the shape for the ends of lines +#: ../../po/../src/dialogs/stroke-style.cpp:1075 +msgid "Cap:" +msgstr "Końcówka:" + +#. TRANSLATORS: Butt cap: the line shape does not extend beyond the end point +#. of the line; the ends of the line are square +#: ../../po/../src/dialogs/stroke-style.cpp:1086 +msgid "Butt cap" +msgstr "Płaska" + +#. TRANSLATORS: Round cap: the line shape extends beyond the end point of the +#. line; the ends of the line are rounded +#: ../../po/../src/dialogs/stroke-style.cpp:1093 +msgid "Round cap" +msgstr "Zaokrąglona" + +#. TRANSLATORS: Square cap: the line shape extends beyond the end point of the +#. line; the ends of the line are square +#: ../../po/../src/dialogs/stroke-style.cpp:1100 +msgid "Square cap" +msgstr "Kwadratowa" + +#. Dash +#: ../../po/../src/dialogs/stroke-style.cpp:1106 +msgid "Dashes:" +msgstr "Wzór kreskowania:" + +#. TRANSLATORS: Path markers are an SVG feature that allows you to attach arbitrary shapes +#. (arrowheads, bullets, faces, whatever) to the start, end, or middle nodes of a path. +#: ../../po/../src/dialogs/stroke-style.cpp:1127 +msgid "Start Markers:" +msgstr "Znaczniki początkowe:" + +#: ../../po/../src/dialogs/stroke-style.cpp:1137 +msgid "Mid Markers:" +msgstr "Znaczniki środkowe:" + +#: ../../po/../src/dialogs/stroke-style.cpp:1148 +msgid "End Markers:" +msgstr "Znaczniki końcowe:" + +#: ../../po/../src/dialogs/swatches.cpp:424 +#, c-format +msgid "Palettes directory (%s) is unavailable." +msgstr "Katalog palet (%s) jest niedostępny." + +#. TODO: Insert widgets +#: ../../po/../src/dialogs/text-edit.cpp:199 +#: ../../po/../src/ui/dialog/text-properties.cpp:36 +msgid "Font" +msgstr "Czcionka" + +#: ../../po/../src/dialogs/text-edit.cpp:216 +msgid "Layout" +msgstr "Układ elementów" + +#: ../../po/../src/dialogs/text-edit.cpp:229 +msgid "Align lines left" +msgstr "Wyrównanie do lewej" + +#. TRANSLATORS: `Center' here is a verb. +#: ../../po/../src/dialogs/text-edit.cpp:243 +msgid "Center lines" +msgstr "Wyrównanie do środka" + +#: ../../po/../src/dialogs/text-edit.cpp:256 +msgid "Align lines right" +msgstr "Wyrównanie do prawej" + +#: ../../po/../src/dialogs/text-edit.cpp:278 +msgid "Horizontal text" +msgstr "Tekst poziomo" + +#: ../../po/../src/dialogs/text-edit.cpp:292 +msgid "Vertical text" +msgstr "Tekst pionowo" + +#: ../../po/../src/dialogs/text-edit.cpp:307 +msgid "Line spacing:" +msgstr "Odstęp międzywierszowy:" + +#: ../../po/../src/dialogs/text-edit.cpp:400 +msgid "Set as default" +msgstr "Zapisz jako domyślne" + +#: ../../po/../src/dialogs/tiledialog.cpp:603 +msgid "Rows:" +msgstr "Rzędy:" + +#: ../../po/../src/dialogs/tiledialog.cpp:613 +msgid "Number of rows" +msgstr "Liczba rzędów" + +#: ../../po/../src/dialogs/tiledialog.cpp:617 +msgid "Equal height" +msgstr "Jednakowa wysokość" + +#: ../../po/../src/dialogs/tiledialog.cpp:627 +msgid "If not set, each row has the height of the tallest object in it" +msgstr "" +"Jeśli nie ustawione każdy rząd ma wysokość najwyższego znajdującego się w " +"nim obiektu" + +#. #### Radio buttons to control vertical alignment #### +#. #### Radio buttons to control horizontal alignment #### +#: ../../po/../src/dialogs/tiledialog.cpp:637 +#: ../../po/../src/dialogs/tiledialog.cpp:708 +msgid "Align:" +msgstr "Wyrównanie:" + +#: ../../po/../src/dialogs/tiledialog.cpp:672 +msgid " X " +msgstr "X" + +#. #### Number of columns #### +#: ../../po/../src/dialogs/tiledialog.cpp:678 +msgid "Columns:" +msgstr "Kolumny:" + +#: ../../po/../src/dialogs/tiledialog.cpp:688 +msgid "Number of columns" +msgstr "Liczba kolumn" + +#: ../../po/../src/dialogs/tiledialog.cpp:692 +msgid "Equal width" +msgstr "Jednakowa szerokość" + +#: ../../po/../src/dialogs/tiledialog.cpp:701 +msgid "If not set, each column has the width of the widest object in it" +msgstr "" +"Jeśli nie ustawione, każda kolumna ma szerokość najszerszego znajdującego " +"się w niej obiektu" + +#. #### Radio buttons to control spacing manually or to fit selection bbox #### +#: ../../po/../src/dialogs/tiledialog.cpp:746 +msgid "Fit into selection box" +msgstr "Dopasowanie do ramki zaznaczenia" + +#: ../../po/../src/dialogs/tiledialog.cpp:753 +msgid "Set spacing:" +msgstr "Ustawienie odstępów:" + +#. #### Y Padding #### +#: ../../po/../src/dialogs/tiledialog.cpp:777 +msgid "Row spacing: " +msgstr "Odstęp wierszy:" + +#: ../../po/../src/dialogs/tiledialog.cpp:786 +msgid "Vertical spacing between rows" +msgstr "Odstępy pionowe pomiędzy wierszami" + +#. #### X padding #### +#: ../../po/../src/dialogs/tiledialog.cpp:795 +msgid "Column spacing:" +msgstr "Odstęp kolumn:" + +#: ../../po/../src/dialogs/tiledialog.cpp:804 +msgid "Horizontal spacing between columns" +msgstr "Odstępy poziome pomiędzy kolumnami" + +#: ../../po/../src/dialogs/tiledialog.cpp:818 +#, fuzzy +msgid "Arrange selected objects" +msgstr "Grupuje zaznaczone obiekty" + +#: ../../po/../src/dialogs/xml-tree.cpp:178 +msgid "Click to select nodes, drag to rearrange." +msgstr "" +"Kliknięcie wybiera węzeł, przeciągnęcie zmienia jego pozycję." + +#: ../../po/../src/dialogs/xml-tree.cpp:189 +msgid "Click attribute to edit." +msgstr "Kliknięcie rozpoczyna edycję atrybutu." + +#: ../../po/../src/dialogs/xml-tree.cpp:193 +#, c-format +msgid "" +"Attribute %s selected. Press Ctrl+Enter when done editing to " +"commit changes." +msgstr "" +"Wybrano atrybut %s. Naciśnięcie Ctrl+Enter wprowadza zmiany." + +#: ../../po/../src/dialogs/xml-tree.cpp:284 +msgid "Drag to reorder nodes" +msgstr "Przeciągnij aby zmienić położenie węzłów" + +#: ../../po/../src/dialogs/xml-tree.cpp:304 +msgid "New element node" +msgstr "Nowy węzeł elementu" + +#: ../../po/../src/dialogs/xml-tree.cpp:326 +msgid "New text node" +msgstr "Nowy węzeł tekstu" + +#: ../../po/../src/dialogs/xml-tree.cpp:347 +msgid "Duplicate node" +msgstr "Duplikuj węzeł" + +#: ../../po/../src/dialogs/xml-tree.cpp:368 +msgid "Delete node" +msgstr "Usuń węzeł" + +#: ../../po/../src/dialogs/xml-tree.cpp:384 +msgid "Unindent node" +msgstr "Usuń wcięcie" + +#: ../../po/../src/dialogs/xml-tree.cpp:399 +msgid "Indent node" +msgstr "Utwórz wcięcie" + +#: ../../po/../src/dialogs/xml-tree.cpp:411 +msgid "Raise node" +msgstr "Przenieś do góry" + +#: ../../po/../src/dialogs/xml-tree.cpp:423 +msgid "Lower node" +msgstr "Przenieś w dół" + +#: ../../po/../src/dialogs/xml-tree.cpp:468 +msgid "Delete attribute" +msgstr "Usuń atrybut" + +#. TRANSLATORS: "Attribute" is a noun here +#: ../../po/../src/dialogs/xml-tree.cpp:513 +msgid "Attribute name" +msgstr "Nazwa atrybutu" + +#. TRANSLATORS: "Set" is a verb here +#: ../../po/../src/dialogs/xml-tree.cpp:533 +msgid "Set attribute" +msgstr "Ustaw atrybut" + +#. TRANSLATORS: "Set" is a verb here +#: ../../po/../src/dialogs/xml-tree.cpp:535 +msgid "Set" +msgstr "Ustaw" + +#. TRANSLATORS: "Attribute" is a noun here +#: ../../po/../src/dialogs/xml-tree.cpp:558 +msgid "Attribute value" +msgstr "Wartość atrybutu" + +#: ../../po/../src/dialogs/xml-tree.cpp:1318 +msgid "New element node..." +msgstr "Nowy węzeł elementu..." + +#: ../../po/../src/dialogs/xml-tree.cpp:1339 +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:100 +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:98 +msgid "Cancel" +msgstr "Anuluj" + +#: ../../po/../src/dialogs/xml-tree.cpp:1345 +msgid "Create" +msgstr "Utwórz" + +#: ../../po/../src/dialogs/xml-tree.cpp:1458 +#, c-format +msgid "" +"Cannot set %s: Another element with value %s already exists!" +msgstr "" +"Nie można ustawić %s: inny element o wartości %s już istnieje!" + +#: ../../po/../src/document.cpp:369 +#, c-format +msgid "New document %d" +msgstr "Nowy dokument %d" + +#: ../../po/../src/document.cpp:401 +#, c-format +msgid "Memory document %d" +msgstr "Dokument w pamięci %d" + +#: ../../po/../src/document.cpp:524 +#, c-format +msgid "Unnamed document %d" +msgstr "Dokument bez nazwy %d" + +#. We hit green anchor, closing Green-Blue-Red +#: ../../po/../src/draw-context.cpp:441 +msgid "Path is closed." +msgstr "Ścieżka jest zamknięta." + +#. We hit bot start and end of single curve, closing paths +#: ../../po/../src/draw-context.cpp:456 +msgid "Closing path." +msgstr "Zamknięcie ścieżki." + +#. alpha of color under cursor, to show in the statusbar +#. locale-sensitive printf is OK, since this goes to the UI, not into SVG +#: ../../po/../src/dropper-context.cpp:354 +#, c-format +msgid " alpha %.3g" +msgstr " przezroczystość %.3g" + +#. where the color is picked, to show in the statusbar +#: ../../po/../src/dropper-context.cpp:356 +#, c-format +msgid ", averaged with radius %d" +msgstr ", uśredniona w promieniu %d" + +#: ../../po/../src/dropper-context.cpp:356 +msgid " under cursor" +msgstr " pod kursorem" + +#. message, to show in the statusbar +#: ../../po/../src/dropper-context.cpp:358 +msgid "Release mouse to set color." +msgstr "Zwolnij przycisk aby ustawić kolor." + +#: ../../po/../src/dropper-context.cpp:358 +#: ../../po/../src/tools-switch.cpp:207 +msgid "" +"Click to set fill, Shift+click to set stroke; drag to " +"average color in area; with Alt to pick inverse color; Ctrl+C " +"to copy the color under mouse to clipboard" +msgstr "" +"Kliknij aby ustawić kolor wypełnienia, kliknij+Shift kolor " +"konturu; przeciągnij aby pobrać uśredniony kolor z obszaru; z Alt negacja koloru; Ctrl+C kopiuje kolor pod kursorem do schowka" + +#: ../../po/../src/extension/dependency.cpp:244 +msgid "Dependency::" +msgstr "Zależności::" + +#: ../../po/../src/extension/dependency.cpp:245 +msgid " type: " +msgstr " typ: " + +#: ../../po/../src/extension/dependency.cpp:246 +msgid " location: " +msgstr " położenie: " + +#: ../../po/../src/extension/dependency.cpp:247 +msgid " string: " +msgstr " łańcuch tekstowy: " + +#: ../../po/../src/extension/dependency.cpp:250 +msgid " description: " +msgstr " opis: " + +#. static int i = 0; +#. std::cout << "Checking module[" << i++ << "]: " << name << std::endl; +#: ../../po/../src/extension/extension.cpp:244 +msgid "" +" This is caused by an improper .inx file for this extension. An improper ." +"inx file could have been caused by a faulty installation of Inkscape." +msgstr "" +" Spowodowane jest to niewłaściwym plikiem .inx dla tego rozszerzenia. " +"Przyczyną błędnego pliku .inx może być niewłaściwa instalacja Inkscape." + +#: ../../po/../src/extension/extension.cpp:247 +msgid "an ID was not defined for it." +msgstr "nie zdefiniowano dla niego identyfikatora ID." + +#: ../../po/../src/extension/extension.cpp:251 +msgid "there was no name defined for it." +msgstr "nie zdefioniowano dla niego nazwy." + +#: ../../po/../src/extension/extension.cpp:255 +msgid "the XML description of it got lost." +msgstr "jego opis w formacie XML został utracony." + +#: ../../po/../src/extension/extension.cpp:259 +msgid "no implementation was defined for the extension." +msgstr "nie zdefiniowano obsługi dla tego rozszerzenia." + +#. std::cout << "Failed: " << *(_deps[i]) << std::endl; +#: ../../po/../src/extension/extension.cpp:266 +msgid "a dependency was not met." +msgstr "nie zostały spełnione zależności." + +#: ../../po/../src/extension/extension.cpp:286 +msgid "Extension \"" +msgstr "Rozszerzenie \"" + +#: ../../po/../src/extension/extension.cpp:286 +msgid "\" failed to load because " +msgstr "\" nie zostało załadowane, ponieważ " + +#: ../../po/../src/extension/extension.cpp:565 +#, c-format +msgid "Could not create extension error log file '%s'" +msgstr "Nie udało się utworzyć pliku dziennika '%s' dla wtyczki" + +#. This is some filler text, needs to change before relase +#: ../../po/../src/extension/error-file.cpp:56 +msgid "" +"One or more extensions failed to load\n" +"\n" +"The failed extensions have been skipped. Inkscape will continue to run " +"normally but those extensions will be unavailable. For details to " +"troubleshoot this problem, please refer to the error log located at: " +msgstr "" +"Nie udało się załadować jednego lub " +"więcej roszerzeń\n" +"\n" +"Niewłaściwe rozszerzenia zostały pominięte. Inkscape zostanie uruchomiony " +"normalnie, ale rozszerzenia te nie będą dostępne. Szczegóły pomocne w " +"rozwiązaniu tego problemu zostały zapisane w dzienniku błędów, " +"zlokalizowanym w: " + +#. This is some filler text, needs to change before relase +#: ../../po/../src/extension/error-file.cpp:65 +msgid "Show dialog on startup" +msgstr "Pokazuj to okno przy starcie programu" + +#: ../../po/../src/extension/implementation/script.cpp:845 +msgid "" +"Inkscape has received an error from the script that it called. The text " +"returned with the error is included below. Inkscape will continue working, " +"but the action you requested has been cancelled." +msgstr "" +"Program Inkscape otrzymał komunikat błędu od skryptu, który został " +"uruchomiony. Treść komunikatu o błędzie znajduje się poniżej. Program będzie " +"kontynuował pracę, jednak żądana operacja została anulowana." + +#: ../../po/../src/extension/implementation/script.cpp:858 +msgid "" +"Inkscape has received additional data from the script executed. The script " +"did not return an error, but this may indicate the results will not be as " +"expected." +msgstr "" +"Program Inkscape otrzymał dodatkowe dane od skryptu, który został " +"uruchomiony. Skrypt nie zgłosił błędu, jednak możliwe, że wynik jego " +"działania jest inny niż spodziewany." + +#: ../../po/../src/extension/init.cpp:173 +msgid "Null external module directory name. Modules will not be loaded." +msgstr "" +"Pusta nazwa katalogu modułów zewnętrznych. Moduły nie zostaną załadowane." + +#: ../../po/../src/extension/init.cpp:187 +#, c-format +msgid "" +"Modules directory (%s) is unavailable. External modules in that directory " +"will not be loaded." +msgstr "" +"Katalog modułów (%s) jest niedostępny. Moduły zewnętrzne z tego katalogu " +"nie zostaną załadowane." + +#: ../../po/../src/extension/internal/gnome.cpp:80 +msgid "Select printer" +msgstr "Wybierz drukarkę" + +#: ../../po/../src/extension/internal/gnome.cpp:131 +msgid "Inkscape: Print Preview" +msgstr "Inkscape: Podgląd wydruku" + +#: ../../po/../src/extension/internal/grid.cpp:213 +msgid "Line Width" +msgstr "Grubość linii" + +#: ../../po/../src/extension/internal/grid.cpp:214 +msgid "Horizontal Spacing" +msgstr "Odstepy poziome" + +#: ../../po/../src/extension/internal/grid.cpp:215 +msgid "Vertical Spacing" +msgstr "Odstępy pionowe" + +#: ../../po/../src/extension/internal/grid.cpp:216 +msgid "Horizontal Offset" +msgstr "Przesunięcie poziome" + +#: ../../po/../src/extension/internal/grid.cpp:217 +msgid "Vertical Offset" +msgstr "Przesunięcie pionowe" + +#: ../../po/../src/extension/internal/ps.cpp:123 +msgid "Print Destination" +msgstr "Przeznaczenie wydruku" + +#. Print properties frame +#: ../../po/../src/extension/internal/ps.cpp:138 +msgid "Print properties" +msgstr "Właściwości wydruku" + +#: ../../po/../src/extension/internal/ps.cpp:145 +msgid "Print using PostScript operators" +msgstr "Drukuj używając poleceń PostScriptu" + +#: ../../po/../src/extension/internal/ps.cpp:147 +msgid "" +"Use PostScript vector operators. The resulting image is usually smaller in " +"file size and can be arbitrarily scaled, but alpha transparency and patterns " +"will be lost." +msgstr "" +"Zastosuj wektorowe polecenia PostScriptu. Plik wynikowy jest zwykle mniejszy " +"i można skalować zapisany w nim rysunek, ale zostaną utracone kanał alfa i " +"desenie." + +#: ../../po/../src/extension/internal/ps.cpp:152 +msgid "Print as bitmap" +msgstr "Drukuj jako bitmapę" + +#: ../../po/../src/extension/internal/ps.cpp:154 +msgid "" +"Print everything as bitmap. The resulting image is usually larger in file " +"size and cannot be arbitrarily scaled without quality loss, but all objects " +"will be rendered exactly as displayed." +msgstr "" +"Drukuj wszystko jako bitmapę. Plik wynikowy jest zwykle większy i nie można " +"skalować zapisanego w nim rysunku, ale wszystkie obiekty zostaną zobrazowane " +"dokładnie tak jak są wyświetlane na ekranie." + +#: ../../po/../src/extension/internal/ps.cpp:168 +msgid "Preferred resolution (dots per inch) of bitmap" +msgstr "Preferowana rozdzielczość (w DPI) bitmapy" + +#: ../../po/../src/extension/internal/ps.cpp:182 +msgid "Resolution:" +msgstr "Rozdzielczość:" + +#. Print destination frame +#: ../../po/../src/extension/internal/ps.cpp:186 +msgid "Print destination" +msgstr "Przeznaczenie wydruku" + +#: ../../po/../src/extension/internal/ps.cpp:192 +msgid "" +"Use '> filename' to print to file.\n" +"Use '| prog arg...' to pipe to a program." +msgstr "" +"Wpisz '> nazwa_pliku' aby wydrukować do pliku.\n" +"Wpisz '| program argument' aby przesłać do programu." + +#: ../../po/../src/extension/internal/ps.cpp:1227 +msgid "write error occurred" +msgstr "Wystapił błąd zapisu" + +#: ../../po/../src/extension/prefdialog.cpp:21 +msgid " Preferences" +msgstr " Ustawienia" + +#. We can't call sp_ui_error_dialog because we may be +#. running from the console, in which case calling sp_ui +#. routines will cause a segfault. See bug 1000350 - bryce +#. sp_ui_error_dialog(_("Format autodetect failed. The file is being opened as SVG.")); +#: ../../po/../src/extension/system.cpp:105 +msgid "Format autodetect failed. The file is being opened as SVG." +msgstr "" +"Nie udało się automatycznie rozpoznać formatu. Plik otwierany jako SVG." + +#. TRANSLATORS: default.svg is localizable - this is the name of the default document +#. template. This way you can localize the default pagesize, translate the name of +#. the default layer, etc. If you wish to localize this file, please create a +#. localized share/templates/default.xx.svg file, where xx is your language code. +#: ../../po/../src/file.cpp:133 +msgid "default.svg" +msgstr "default.pl.svg" + +#: ../../po/../src/file.cpp:215 ../../po/../src/file.cpp:900 +#, c-format +msgid "Failed to load the requested file %s" +msgstr "Nie udało się załadować wybranego pliku %s" + +#: ../../po/../src/file.cpp:240 +msgid "Document not saved yet. Cannot revert." +msgstr "Dokument nie jest jeszcze zapisany. Nie można przywrócić." + +#: ../../po/../src/file.cpp:246 +#, c-format +msgid "Changes will be lost! Are you sure you want to reload document %s?" +msgstr "Zmiany zostaną utracone! Czy na pewno załadować ponownie dokument %s?" + +#: ../../po/../src/file.cpp:266 +msgid "Document reverted." +msgstr "Przywrócono dokument." + +#: ../../po/../src/file.cpp:268 +msgid "Document not reverted." +msgstr "Dokumentu nie przywrócono." + +#: ../../po/../src/file.cpp:382 +msgid "Select file to open" +msgstr "Wybór pliku do odczytu" + +#: ../../po/../src/file.cpp:518 +#, c-format +msgid "Removed %i unused definition in <defs>." +msgid_plural "Removed %i unused definitions in <defs>." +msgstr[0] "Usunięto %i nieużywany element w <defs>." +msgstr[1] "Usunięto %i nieużywane elementy w <defs>." +msgstr[2] "Usunięto %i nieużywanych elementów elementy w <defs>." + +#: ../../po/../src/file.cpp:523 +msgid "No unused definitions in <defs>." +msgstr "Brak nieużywanych definicji w <defs>." + +#: ../../po/../src/file.cpp:548 +#, c-format +msgid "" +"No Inkscape extension found to save document (%s). This may have been " +"caused by an unknown filename extension." +msgstr "" +"Nie znaleziono rozszerzenia programu Inkscape obsługującego zapis dokumentu " +"(%s). Może być to spowodowane nieznanym rozszerzeniem pliku." + +#: ../../po/../src/file.cpp:549 ../../po/../src/file.cpp:557 +msgid "Document not saved." +msgstr "Dokument nie został zapisany" + +#: ../../po/../src/file.cpp:556 +#, c-format +msgid "File %s could not be saved." +msgstr "Plik %s nie mógł zostać zapisany." + +#: ../../po/../src/file.cpp:566 +msgid "Document saved." +msgstr "Dokument został zapisany." + +#: ../../po/../src/file.cpp:614 +#, c-format +msgid "drawing%s" +msgstr "Rysunek%s" + +#: ../../po/../src/file.cpp:620 +#, c-format +msgid "drawing-%d%s" +msgstr "Rysunek-%d%s" + +#: ../../po/../src/file.cpp:655 +msgid "Select file to save to" +msgstr "Wybór pliku do zapisania" + +#: ../../po/../src/file.cpp:739 +msgid "No changes need to be saved." +msgstr "Brak zmian do zapisania." + +#: ../../po/../src/file.cpp:926 +msgid "Select file to import" +msgstr "Wybór pliku do importu" + +#: ../../po/../src/gradient-context.cpp:263 +msgid "Ctrl: snap gradient angle" +msgstr "Ctrl: przyciąganie kąta gradientu" + +#: ../../po/../src/gradient-context.cpp:264 +msgid "Shift: draw gradient around the starting point" +msgstr "Shift: rysowanie gradientu wokół punktu początkowego" + +#. We did an undoable action, but sp_document_done will be called by the knot when released +#. status text; we do not track coords because this branch is run once, not all the time +#. during drag +#: ../../po/../src/gradient-context.cpp:462 +#, c-format +msgid "Gradient for %d objects; with Ctrl to snap angle" +msgstr "Gradient dla %d obiektów; z Ctrl przyciąganie do kąta" + +#: ../../po/../src/gradient-context.cpp:464 +msgid "Select objects on which to create gradient." +msgstr "Zaznacz obiekt(y) dla których utworzyć gradient." + +#: ../../po/../src/gradient-drag.cpp:65 +msgid "Linear gradient start" +msgstr "Punkt początkowy gradientu liniowego" + +#. POINT_LG_P1 +#: ../../po/../src/gradient-drag.cpp:66 +msgid "Linear gradient end" +msgstr "Punkt końcowy gradientu liniowego" + +#: ../../po/../src/gradient-drag.cpp:67 +msgid "Radial gradient center" +msgstr "Środek gradientu koncentrycznego" + +#: ../../po/../src/gradient-drag.cpp:68 ../../po/../src/gradient-drag.cpp:69 +msgid "Radial gradient radius" +msgstr "Promień gradientu koncentrycznego" + +#: ../../po/../src/gradient-drag.cpp:70 +msgid "Radial gradient focus" +msgstr "Ognisko gradientu koncentrycznego" + +#: ../../po/../src/gradient-drag.cpp:659 +#, c-format +msgid "" +"%s for: %s%s; drag with Ctrl to snap angle, with Ctrl+Alt to " +"preserve angle, with Ctrl+Shift to scale around center" +msgstr "" +"%s dla: %s%s; przeciągnij z Ctrl aby przyciągnąć do kąta, z Ctrl" +"+Alt zachowanie kąta, z Ctrl+Shift skalowanie od środka" + +#: ../../po/../src/gradient-drag.cpp:662 +msgid " (stroke)" +msgstr "(kontur)" + +#: ../../po/../src/gradient-drag.cpp:665 +msgid "" +"Radial gradient center and focus; drag with Shift to " +"separate focus" +msgstr "" +"Gradient koncentryczny: środek i ognisko; przeciągnij z " +"klawiszem Shift aby oddzielić ognisko" + +#: ../../po/../src/gradient-drag.cpp:667 +#, c-format +msgid "" +"Gradient point shared by %d gradients; drag with Shift to " +"separate" +msgstr "" +"Punkt gradientu wspólny dla %d gradientów; przeciągnij z Shift " +"aby je rozdzielić" + +#: ../../po/../src/helper/units.cpp:40 +msgid "Unit" +msgstr "Jednostka" + +#: ../../po/../src/helper/units.cpp:40 +msgid "Units" +msgstr "Jednostki" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Point" +msgstr "Punkt" + +#: ../../po/../src/helper/units.cpp:41 +msgid "pt" +msgstr "pkt" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Points" +msgstr "Punkty" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Pt" +msgstr "Pkt" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Pixel" +msgstr "Piksel" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Pixels" +msgstr "Piksele" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Px" +msgstr "Piks" + +#. You can add new elements from this point forward +#: ../../po/../src/helper/units.cpp:44 ../share/extensions/straightseg.inx.h:2 +msgid "Percent" +msgstr "Procent" + +#: ../../po/../src/helper/units.cpp:44 +msgid "Percents" +msgstr "Procenty" + +#: ../../po/../src/helper/units.cpp:45 +msgid "Millimeter" +msgstr "Milimetr" + +#: ../../po/../src/helper/units.cpp:45 +msgid "mm" +msgstr "mm" + +#: ../../po/../src/helper/units.cpp:45 +msgid "Millimeters" +msgstr "Milimetry" + +#: ../../po/../src/helper/units.cpp:46 +msgid "Centimeter" +msgstr "Centymetr" + +#: ../../po/../src/helper/units.cpp:46 +msgid "cm" +msgstr "cm" + +#: ../../po/../src/helper/units.cpp:46 +msgid "Centimeters" +msgstr "Centymetry" + +#: ../../po/../src/helper/units.cpp:47 +msgid "Meter" +msgstr "Metr" + +#: ../../po/../src/helper/units.cpp:47 +msgid "m" +msgstr "m" + +#: ../../po/../src/helper/units.cpp:47 +msgid "Meters" +msgstr "Metry" + +#. no svg_unit +#: ../../po/../src/helper/units.cpp:48 +msgid "Inch" +msgstr "Cal" + +#: ../../po/../src/helper/units.cpp:48 +msgid "in" +msgstr "cal" + +#: ../../po/../src/helper/units.cpp:48 +msgid "Inches" +msgstr "Cale" + +#. Volatiles do not have default, so there are none here +#. TRANSLATORS: for info, see http://www.w3.org/TR/REC-CSS2/syndata.html#length-units +#: ../../po/../src/helper/units.cpp:51 +msgid "Em square" +msgstr "" + +#: ../../po/../src/helper/units.cpp:51 +msgid "em" +msgstr "" + +#: ../../po/../src/helper/units.cpp:51 +msgid "Em squares" +msgstr "" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/REC-CSS2/syndata.html#length-units +#: ../../po/../src/helper/units.cpp:53 +msgid "Ex square" +msgstr "" + +#: ../../po/../src/helper/units.cpp:53 +msgid "ex" +msgstr "" + +#: ../../po/../src/helper/units.cpp:53 +msgid "Ex squares" +msgstr "" + +#: ../../po/../src/inkscape.cpp:468 +msgid "Untitled document" +msgstr "Dokument bez nazwy" + +#. Show nice dialog box +#: ../../po/../src/inkscape.cpp:497 +msgid "Inkscape encountered an internal error and will close now.\n" +msgstr "" +"W programie Inkscape wystąpił wewnętrzny błąd i nastąpi jego zamknięcie.\n" + +#: ../../po/../src/inkscape.cpp:498 +msgid "" +"Automatic backups of unsaved documents were done to the following " +"locations:\n" +msgstr "" +"Automatycznie utworzono kopie niezapisanych dokumentów w następujących " +"lokalizacjach:\n" + +#: ../../po/../src/inkscape.cpp:499 +msgid "Automatic backup of the following documents failed:\n" +msgstr "" +"Nie udało się utworzyć automatycznych kopii następujących dokumentów:\n" + +#: ../../po/../src/inkscape.cpp:634 +#, c-format +msgid "" +"Cannot create directory %s.\n" +"%s" +msgstr "" +"Nie można utworzyć katalogu %s.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:635 +#, c-format +msgid "" +"%s is not a valid directory.\n" +"%s" +msgstr "" +"%s nie jest poprawnym katalogiem.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:636 +#, c-format +msgid "" +"Cannot create file %s.\n" +"%s" +msgstr "" +"Nie można utworzyć pliku %s.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:637 +#, c-format +msgid "" +"Cannot write file %s.\n" +"%s" +msgstr "" +"Nie można zapisać do pliku %s.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:638 +msgid "" +"Although Inkscape will run, it will use default settings,\n" +"and any changes made in preferences will not be saved." +msgstr "" +"Mimo, że Inkscape zostanie uruchomiony, będzie korzystał z domyślnych\n" +"ustawień, a żadne zmiany dokonane w ustawieniach nie zostaną zapisane." + +#: ../../po/../src/inkscape.cpp:708 +#, c-format +msgid "" +"%s is not a regular file.\n" +"%s" +msgstr "" +"%s nie jest poprawnym plikiem.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:709 +#, c-format +msgid "" +"%s not a valid XML file, or\n" +"you don't have read permissions on it.\n" +"%s" +msgstr "" +"%s nie jest poprawnym plikiem XML, lub\n" +"nie masz praw do odczytu tego pliku.%s" + +#: ../../po/../src/inkscape.cpp:711 +#, c-format +msgid "" +"%s is not a valid menus file.\n" +"%s" +msgstr "" +"%s nie jest poprawnym plikiem menu.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:712 +msgid "" +"Inkscape will run with default menus.\n" +"New menus will not be saved." +msgstr "" +"Inkscape zostanie uruchomiony z domyślnym menu.\n" +"Nowe menu nie zostaną zapisane." + +#. sp_ui_menu_append_check_item_from_verb(m, view, _("_Menu"), _("Show or hide the menu bar"), "menu", +#. checkitem_toggled, checkitem_update, 0); +#: ../../po/../src/interface.cpp:753 +msgid "Commands Bar" +msgstr "Pasek poleceń" + +#: ../../po/../src/interface.cpp:753 +msgid "Show or hide the Commands bar (under the menu)" +msgstr "Wyświetla lub ukrywa pasek poleceń (pod menu)" + +#: ../../po/../src/interface.cpp:755 +msgid "Tool Controls" +msgstr "Opcje narzędzi" + +#: ../../po/../src/interface.cpp:755 +msgid "Show or hide the Tool Controls panel" +msgstr "Wyświetla lub ukrywa pasek z opcjami dla narzędzi" + +#: ../../po/../src/interface.cpp:757 +msgid "_Toolbox" +msgstr "Paleta narzędzi" + +#: ../../po/../src/interface.cpp:757 +msgid "Show or hide the main toolbox (on the left)" +msgstr "Wyświetla lub ukrywa paletę narzędzi (po lewej stronie)" + +#: ../../po/../src/interface.cpp:763 +msgid "_Statusbar" +msgstr "Pasek statusu" + +#: ../../po/../src/interface.cpp:763 +msgid "Show or hide the statusbar (at the bottom of the window)" +msgstr "Wyświetla lub ukrywa pasek statusu (na dole okna)" + +#: ../../po/../src/interface.cpp:820 +#, c-format +msgid "Verb \"%s\" Unknown" +msgstr "Polecenie \"%s\" Nieznane" + +#. TRANSLATORS: #%s is the id of the group e.g. , not a number. +#: ../../po/../src/interface.cpp:930 +#, c-format +msgid "Enter group #%s" +msgstr "Wejdź do grupy #%s" + +#: ../../po/../src/interface.cpp:941 +msgid "Go to parent" +msgstr "Przejdź do rodzica" + +#: ../../po/../src/interface.cpp:972 +msgid "Could not parse SVG data" +msgstr "Nie można odczytać danych SVG" + +#: ../../po/../src/interface.cpp:1135 +#, c-format +msgid "Overwrite %s" +msgstr "Nadpisanie %s" + +#: ../../po/../src/interface.cpp:1153 +#, c-format +msgid "" +"The file %s already exists. Do you want to overwrite that file with the " +"current document?" +msgstr "" +"Plik %s już istnieje. Czy zastapić istniejący plik bieżącym dokumentem?" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:59 +msgid "Jabber connection lost." +msgstr "Połączenie Jabbera utracone." + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:72 +#, c-format +msgid "Sending message; %u message remaining in send queue." +msgid_plural "Sending message; %u messages remaining in send queue." +msgstr[0] "Wysyłanie wiadomości; %u wiadomość oczekuje na wysłanie." +msgstr[1] "Wysyłanie wiadomości; %u wiadomości oczekują na wysłanie." +msgstr[2] "Wysyłanie wiadomości; %u wiadomości oczekuje na wysłanie." + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:78 +msgid "Receive queue empty." +msgstr "Kolejka otrzymanych pusta." + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:154 +#, c-format +msgid "Receiving change; %u change left to process." +msgid_plural "Receiving change; %u changes left to process." +msgstr[0] "Pobieranie zmian; pozostała %u zmiana do przetworzenia." +msgstr[1] "Pobieranie zmian; pozostały %u zmiany do przetworzenia." +msgstr[2] "Pobieranie zmian; pozostało %u zmian do przetworzenia." + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:157 +#, c-format +msgid "%s has left the chatroom." +msgstr "%s opuścił pokój." + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:221 +msgid "Nickname %1 is already in use. Please choose a different nickname." +msgstr "Pseudonim %1 jest już używany. Wybierz proszę inny." + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:225 +msgid "An error was encountered while attempting to connect to the server." +msgstr "Wystąpił błąd podczas próby połączenia się z serwerem." + +#. Check to see if the user made any modifications to this document. If so, +#. we want to give them the option of (1) letting us clear their document or (2) +#. opening a new, blank document for the whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:131 +msgid "%1 has invited you to a whiteboard session." +msgstr "%1 zaprosił cię do sesji wspólnej pracy na planszy." + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:132 +msgid "Incoming whiteboard invitation from %1" +msgstr "Nadchodzi zaproszenie do wspólnej pracy na planszy od %1." + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:135 +msgid "Do you wish to accept %1's whiteboard session invitation?" +msgstr "" +"Czy chcesz przyjąć zaproszenie do sesji wspólnej pracy na planszy od %1?" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:137 +msgid "" +"Would you like to accept %1's invitation in a new document window?\n" +"Accepting the invitation in your current window will discard unsaved changes." +msgstr "" +"Czy chcesz przyjąć zaproszenie użytkownika %1 w oknie nowego dokumentu?\n" +"Podjęcie zaproszenia w aktualnym oknie spowoduje odrzucenie niezapisanych " +"zmian. " + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:143 +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:198 +msgid "Accept invitation" +msgstr "Przyjmij zaproszenie" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:144 +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:199 +msgid "Decline invitation" +msgstr "Odrzuć zaproszenie" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:145 +msgid "Accept invitation in new document window" +msgstr "Przyjmij zaproszenie w oknie nowego dokumentu" + +#. We could not create a new desktop; ask the user if she or he wants to +#. replace the current document and accept the invitation, or reject the invitation. +#. TRANSLATORS: %1 is a userid here +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:196 +msgid "" +"A new document window could not be opened for a whiteboard session with %" +"1" +msgstr "Nie można otworzyć nowego okna do sesji wspólnej pracy z %1" + +#. TRANSLATORS: %1 is the peer whom refused our invitation. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:238 +msgid "" +"The user %1 has refused your " +"whiteboard invitation.\n" +"\n" +msgstr "" +"Użytkownik %1 nie przyjął " +"twojego zaproszenia do wspólnej pracy na planszy.\n" +"\n" + +#. TRANSLATORS: %1 is the peer whom refused our invitation, %2 is our Jabber identity. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:241 +msgid "" +"You are still connected to a Jabber server as %2, and may send an " +"invitation to %1 again, or you may send an invitation to a different " +"user." +msgstr "" +"Jesteś wciąż połączony z serwerem Jabbera jako %2, i możesz ponownie " +"wysłać zaproszenie do %1, lub wysłać zaproszenie do innego " +"użytkownika." + +#. TRANSLATORS: %1 is the peer whom we tried to contact, but is already in a whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:252 +msgid "" +"The user %1 is already in a " +"whiteboard session.\n" +"\n" +msgstr "" +"Użytkownik %1 uczestniczy już w " +"sesji wspólnej pracy na planszy.\n" +"\n" + +#. TRANSLATORS: %1 is the peer whom we tried to contact, but is already in a whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:255 +msgid "" +"You are still connected to a Jabber server as %1, and may send an " +"invitation to a different user." +msgstr "" +"Jesteś wciąż połączony z serwerem Jabbera jako %1 i możesz wysłać " +"zaproszenie do innego użytkownika." + +#: ../../po/../src/jabber_whiteboard/invitation-confirm-dialog.cpp:26 +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:24 +msgid "_Write session file:" +msgstr "_Zapisz plik sesji:" + +#: ../../po/../src/jabber_whiteboard/message-processors.cpp:145 +#, c-format +msgid "%s has joined the chatroom." +msgstr "%s wszedł do pokoju." + +#: ../../po/../src/jabber_whiteboard/message-queue.cpp:87 +#, c-format +msgid "%u change in receive queue." +msgid_plural "%u changes in receive queue." +msgstr[0] "%u zmiana w kolejce przychodzących." +msgstr[1] "%u zmiany w kolejce przychodzących." +msgstr[2] "%u zmian w kolejce przychodzących." + +#: ../../po/../src/jabber_whiteboard/message-queue.cpp:117 +#, c-format +msgid "%u change in send queue." +msgid_plural "%u changes in send queue." +msgstr[0] "%u zmiana w kolejce wysyłania." +msgstr[1] "%u zmiany w kolejce wysyłania." +msgstr[2] "%u zmian w kolejce wysyłania." + +#. if ID is NULL, then we have a real problem -- we were not able to find a key +#. nor generate one. The only thing we can really do here is abort, since we have +#. no way to let the other client(s) uniquely identify this object. +#. FIXME: If this indicates a programming bug, then don't request translation with +#. * _(...): it is most useful in untranslated form so that developers may search for +#. * it when someone reports it in a bug report (as we want users to do for all bugs, +#. * as indicated by it being a g_warning string). +#. * +#. * Otherwise, if it is not a programming bug but a network error or a bug in the +#. * remote peer (perhaps running different software) or whatever, then present it in +#. * an alert box, and avoid use of technical jargon `NULL'. +#. +#: ../../po/../src/jabber_whiteboard/message-utilities.cpp:171 +msgid "" +"ID for new object is NULL even after generation and lookup attempts: the new " +"object will NOT be sent, nor will any of its child objects!" +msgstr "" +"ID nowego obiektu nie ma wartości (NULL) pomimo wygenerowania i prób " +"sprawdzenia: nowy obiekt NIE zostanie wysłany, dotyczy to również wszystkich " +"jego obiektów potomnych!" + +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:60 +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:995 +msgid "Select a location and filename" +msgstr "Wybierz położenie i nazwę pliku" + +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:62 +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:997 +msgid "Set filename" +msgstr "Ustaw nazwę pliku" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:301 +msgid "No SSL certificate was found." +msgstr "Nie znaleziono certyfikatu SSL." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:304 +msgid "The SSL certificate provided by the Jabber server is untrusted." +msgstr "Certyfikat SSL dostarczony przez serwer Jabbera jest niepewny." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:307 +msgid "The SSL certificate provided by the Jabber server is expired." +msgstr "Ważność certyfikatu SSL dostarczonego przez serwer Jabbera wygasła." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:310 +msgid "" +"The SSL certificate provided by the Jabber server has not been activated." +msgstr "" +"Certyfikat SSL dostarczony przez serwer Jabbera jest nie został aktywowany." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:313 +msgid "" +"The SSL certificate provided by the Jabber server contains a hostname that " +"does not match the Jabber server's hostname." +msgstr "" +"Certyfikat SSL dostarczony przez serwer Jabbera zawiera nazwę hosta, która " +"nie jest zgodna z nazwą hosta serweru Jabbera." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:316 +msgid "" +"The SSL certificate provided by the Jabber server contains an invalid " +"fingerprint." +msgstr "" +"Certyfikat SSL dostarczony przez serwer Jabbera zawiera nieprawidłowy podpis." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:319 +msgid "An unknown error occurred while setting up the SSL connection." +msgstr "Wystąpił nieznany błąd podczas ustanawiania połączenia SSL." + +#. TRANSLATORS: %1 is the message that describes the specific error that occurred when +#. establishing the SSL connection. +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:325 +msgid "" +"%1\n" +"\n" +"Do you wish to continue connecting to the Jabber server?" +msgstr "" +"%1\n" +"\n" +"Czy chcesz kontynuować łączenie się z serwerem Jabbera?" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:328 +msgid "Continue connecting and ignore further errors" +msgstr "Kontynuuj łączenie i ignoruj dalsze błędy" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:329 +msgid "Continue connecting, but warn me of further errors" +msgstr "Kontynuuj łączenie, ale informuj mnie o dalszych błędach" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:330 +msgid "Cancel connection" +msgstr "Anuluj połączenie" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:777 +#, c-format +msgid "Established whiteboard session with %s." +msgstr "Ustanowiono połączenie do wspólnej pracy na planszy z %s." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:785 +#, c-format +msgid "%s has left the whiteboard session." +msgstr "%s opuścił sesję wspólnej pracy na planszy." + +#. Inform the user +#. TRANSLATORS: %1 is the name of the user that disconnected, %2 is the name of the user whom the disconnected user disconnected from. +#. This message is not used in a chatroom context. +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:790 +msgid "" +"The user %1 has left the " +"whiteboard session.\n" +"\n" +msgstr "" +"Użytkownik %1 has left the " +"whiteboard session.\n" +"\n" + +#. TRANSLATORS: %1 and %2 are userids +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:792 +msgid "" +"You are still connected to a Jabber server as %2, and may establish a " +"new session to %1 or a different user." +msgstr "" +"Jesteś wciąż połączony z serwerem Jabbera jako użytkownik %2, i " +"możesz ustanowić nowe połączenie z %1 lub innym użytkownikiem." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:988 +msgid "" +"Could not open file %1 for session recording.\n" +"The error encountered was: %2.\n" +"\n" +"You may select a different location to record the session, or you may opt to " +"not record this session." +msgstr "" +"Nie można otworzyć pliku %1 do zapisania sesji.\n" +"Błąd, który wystąpił: %2.\n" +"\n" +"Możesz wskazać inną lokalizację do zapisywania sesji, lub wybrać opcję nie " +"zapisywania jej." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:990 +msgid "Choose a different location" +msgstr "Wybierz inną lokalizację" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:991 +msgid "Skip session recording" +msgstr "Pomiń zapisywanie sesji" + +#: ../../po/../src/knot.cpp:673 +msgid "Node or handle drag canceled." +msgstr "Przeciąganie węzła lub uchwytu anulowane." + +#: ../../po/../src/libnrtype/FontFactory.cpp:358 +msgid "Ignoring font without family that will crash Pango" +msgstr "Pominięcie czcionki bez rodziny, która zawiesi biblitekę Pango" + +#: ../../po/../src/main.cpp:395 +msgid "Print the Inkscape version number" +msgstr "Wypisz numer wersji programu Inkscape" + +#: ../../po/../src/main.cpp:400 +msgid "Do not use X server (only process files from console)" +msgstr "Nie używaj X serwera (przetwarzaj jedynie pliki z poziomu konsoli)" + +#: ../../po/../src/main.cpp:405 +msgid "Try to use X server (even if $DISPLAY is not set)" +msgstr "Spróbuj używać X serwera (pomimo nie ustawionej zmiennej $DISPLAY)" + +#: ../../po/../src/main.cpp:410 +msgid "Open specified document(s) (option string may be excluded)" +msgstr "Otwiera podany(-e) dokument(y) (tekst opcji może zostać wyłączony)" + +#: ../../po/../src/main.cpp:411 ../../po/../src/main.cpp:416 +#: ../../po/../src/main.cpp:421 ../../po/../src/main.cpp:483 +#: ../../po/../src/main.cpp:488 ../../po/../src/main.cpp:493 +msgid "FILENAME" +msgstr "NAZWA_PLIKU" + +#: ../../po/../src/main.cpp:415 +msgid "Print document(s) to specified output file (use '| program' for pipe)" +msgstr "" +"Drukuje dokumenty do podanego pliku wyjściowego (zapis do potoku - \"| " +"program\")" + +#: ../../po/../src/main.cpp:420 +msgid "Export document to a PNG file" +msgstr "Eksportuje dokument do obrazu PNG" + +#: ../../po/../src/main.cpp:425 +msgid "The resolution used for exporting SVG into bitmap (default 90)" +msgstr "Rozdzielczość używana do konwersji SVG do bitmapy (domyślnie 90)" + +#: ../../po/../src/main.cpp:426 +msgid "DPI" +msgstr "DPI" + +#: ../../po/../src/main.cpp:430 +msgid "" +"Exported area in SVG user units (default is the canvas; 0,0 is lower-left " +"corner)" +msgstr "" +"Rozmiar eksportowanego obszaru jednostakch SVG użytkownika (domyślnie format " +"strony; 0,0 oznacza lewy doly róg)" + +#: ../../po/../src/main.cpp:431 +msgid "x0:y0:x1:y1" +msgstr "x0:y0:x1:y1" + +#: ../../po/../src/main.cpp:435 +msgid "Exported area is the entire drawing (not canvas)" +msgstr "" +"Obszar eksportu ograniczony jest przez wymiar rysunku (nie format strony)" + +#: ../../po/../src/main.cpp:440 +msgid "" +"Snap the bitmap export area outwards to the nearest integer values (in SVG " +"user units)" +msgstr "" +"Wyrównaj obszar eksportu bitmapy na zewnątrz do najbliższej pełnej wartości " +"(w jednostkach SVG użytkownika)" + +#: ../../po/../src/main.cpp:445 +msgid "The width of exported bitmap in pixels (overrides export-dpi)" +msgstr "Szerokość generowanej bitmapy w pikselach (przesłania dpi)" + +#: ../../po/../src/main.cpp:446 +msgid "WIDTH" +msgstr "SZEROKOŚĆ" + +#: ../../po/../src/main.cpp:450 +msgid "The height of exported bitmap in pixels (overrides export-dpi)" +msgstr "Wysokość generowanej bitmapy w pikselach (przesłania dpi)" + +#: ../../po/../src/main.cpp:451 +msgid "HEIGHT" +msgstr "WYSOKOŚĆ" + +#: ../../po/../src/main.cpp:455 +msgid "The ID of the object to export (overrides export-area)" +msgstr "Identyfikator ID eksportowanego obiektu (przesłania obszar eksportu)" + +#: ../../po/../src/main.cpp:456 ../../po/../src/main.cpp:532 +msgid "ID" +msgstr "ID" + +#. TRANSLATORS: this means: "Only export the object whose id is given in --export-id". +#. See "man inkscape" for details. +#: ../../po/../src/main.cpp:462 +msgid "" +"Export just the object with export-id, hide all others (only with export-id)" +msgstr "" +"Eksportuj tylko obiekty oznaczone identyfikatorem eksportu, ukryj pozostałe " +"(tylko przy 'export-id')" + +#: ../../po/../src/main.cpp:467 +msgid "Use stored filename and DPI hints when exporting (only with export-id)" +msgstr "" +"Zastosuj przy eksporcie zapisaną nazwę pliku i DPI (tylko przy 'export-id')" + +#: ../../po/../src/main.cpp:472 +msgid "Background color of exported bitmap (any SVG-supported color string)" +msgstr "" +"Kolor tła eksportowanej bitmapy (dowolny string koloru obsługiwany przez SVG)" + +#: ../../po/../src/main.cpp:473 +msgid "COLOR" +msgstr "KOLOR" + +#: ../../po/../src/main.cpp:477 +msgid "Background opacity of exported bitmap (either 0.0 to 1.0, or 1 to 255)" +msgstr "Nieprzejrzystość tła eksportowanej bitmapy (w formacie 0.0 do 1.0, " + +#: ../../po/../src/main.cpp:478 +msgid "VALUE" +msgstr "WARTOŚĆ" + +#: ../../po/../src/main.cpp:482 +msgid "Export document to plain SVG file (no sodipodi or inkscape namespaces)" +msgstr "" +"Exportuj dokument do czystego formatu SVG (bez przestrzeni nazw używanych " +"przez programy Sodipodi i Inkscape)" + +#: ../../po/../src/main.cpp:487 +msgid "Export document to a PS file" +msgstr "Eksportuje dokument do pliku PS" + +#: ../../po/../src/main.cpp:492 +msgid "Export document to an EPS file" +msgstr "Eksportuje dokument do pliku EPS" + +#: ../../po/../src/main.cpp:497 +msgid "Convert text object to paths on export (EPS)" +msgstr "Zamiana przy eksporcie obiektów tekstowych na ścieżki (EPS)" + +#: ../../po/../src/main.cpp:502 +msgid "Export files with the bounding box set to the page size (EPS)" +msgstr "" +"Eksportuj pliki z ramką ograniczającą ustawioną jak rozmiar strony (dla " +"plików EPS)" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:508 +msgid "" +"Query the X coordinate of the drawing or, if specified, of the object with --" +"query-id" +msgstr "" +"Pytaj o współrzędną X rysunku, lub obiektu jeśli jest podany za pomocą --" +"query-id" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:514 +msgid "" +"Query the Y coordinate of the drawing or, if specified, of the object with --" +"query-id" +msgstr "" +"Pytaj o współrzędną Y rysunku, lub obiektu jeśli jest podany za pomocą --" +"query-id" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:520 +msgid "" +"Query the width of the drawing or, if specified, of the object with --query-" +"id" +msgstr "" +"Pytaj o szerokość rysunku, lub obiektu jeśli jest podany za pomocą --query-id" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:526 +msgid "" +"Query the height of the drawing or, if specified, of the object with --query-" +"id" +msgstr "" +"Pytaj o wysokość rysunku, lub obiektu jeśli jest podany za pomocą --query-id" + +#: ../../po/../src/main.cpp:531 +msgid "The ID of the object whose dimensions are queried" +msgstr "Identyfikator ID obiektu, o którego wymiary zapytano" + +#. TRANSLATORS: this option makes Inkscape print the name (path) of the extension directory +#: ../../po/../src/main.cpp:537 +msgid "Print out the extension directory and exit" +msgstr "Wyświelt katalog rozszerzeń i zakończ" + +#: ../../po/../src/main.cpp:542 +msgid "Show given files one-by-one, switch to next on any key/mouse event" +msgstr "" +"Wyświetla kolejno podane pliki, przełączając na kolejny po jakiejkolwiek " +"akcji myszy lub klawiatury" + +#: ../../po/../src/main.cpp:547 +msgid "Use the new Gtkmm GUI interface" +msgstr "Korzystaj z nowego interfejsu opartego na Gtkmm" + +#: ../../po/../src/main.cpp:552 +msgid "Remove unused definitions from the defs section(s) of the document" +msgstr "Usuń nieużywane definicje z sekcji <defs> dokumentu" + +#: ../../po/../src/main.cpp:741 +msgid "" +"[OPTIONS...] [FILE...]\n" +"\n" +"Available options:" +msgstr "" +"[OPCJE...] [PLIK...]\n" +"\n" +"Dostępne opcje:" + +#: ../../po/../src/menus-skeleton.h:17 +msgid "_New" +msgstr "_Nowy" + +#: ../../po/../src/menus-skeleton.h:22 +msgid "Open _Recent" +msgstr "Otwórz ostatnio _używane" + +#: ../../po/../src/menus-skeleton.h:53 +msgid "_Edit" +msgstr "_Edycja" + +#: ../../po/../src/menus-skeleton.h:84 +msgid "_View" +msgstr "_Widok" + +#: ../../po/../src/menus-skeleton.h:85 +#, fuzzy +msgid "_Zoom" +msgstr "Powiększenie" + +#: ../../po/../src/menus-skeleton.h:102 +msgid "Show/Hide" +msgstr "Pokaż/Ukryj" + +#: ../../po/../src/menus-skeleton.h:107 +msgid "_Display mode" +msgstr "" + +#: ../../po/../src/menus-skeleton.h:126 +msgid "_Layer" +msgstr "W_arstwa" + +#: ../../po/../src/menus-skeleton.h:143 +msgid "_Object" +msgstr "_Obiekt" + +#: ../../po/../src/menus-skeleton.h:165 +msgid "_Path" +msgstr "Śc_ieżka" + +#: ../../po/../src/menus-skeleton.h:188 +msgid "_Text" +msgstr "_Tekst" + +#: ../../po/../src/menus-skeleton.h:200 +msgid "Effects" +msgstr "E_fekty" + +#: ../../po/../src/menus-skeleton.h:207 +msgid "Whiteboa_rd" +msgstr "Plansza robocza" + +#: ../../po/../src/menus-skeleton.h:220 +msgid "_Help" +msgstr "Pomo_c" + +#: ../../po/../src/menus-skeleton.h:222 +msgid "Tutorials" +msgstr "_Przewodniki" + +#: ../../po/../src/node-context.cpp:382 +msgid "" +"Ctrl: toggle node type, snap handle angle, move hor/vert; Ctrl" +"+Alt: move along handles" +msgstr "" +"Ctrl: przełącz typ węzła, przyciągaj uchwyt do kąta, prowadź poz/pion;" +"Ctrl+Alt: prowadź po linii uchwytu" + +#: ../../po/../src/node-context.cpp:383 +msgid "" +"Shift: toggle node selection, disable snapping, rotate both handles" +msgstr "" +"Shift: przełącz wybór węzła, wyłącz przyciąganie, obracaj oba uchwyty" + +#: ../../po/../src/node-context.cpp:384 +msgid "Alt: lock handle length; Ctrl+Alt: move along handles" +msgstr "" +"Alt: blokuj odległość uchwytu; Ctrl+Alt: prowadź po linii " +"uchwytu" + +#: ../../po/../src/nodepath.cpp:1399 ../../po/../src/nodepath.cpp:1411 +#: ../../po/../src/nodepath.cpp:1492 ../../po/../src/nodepath.cpp:1504 +msgid "To join, you must have two endnodes selected." +msgstr "Aby połączyć, należy wybrać dwa węzły końcowe." + +#: ../../po/../src/nodepath.cpp:1633 ../../po/../src/nodepath.cpp:1647 +msgid "" +"Select two non-endpoint nodes on a path between which to delete " +"segments." +msgstr "" +"Wybierz dwa nie końcowe węzły do usunięcia ścieżki pomiędzy nimi " + +#: ../../po/../src/nodepath.cpp:1743 +msgid "Cannot find path between nodes." +msgstr "Nie znaleziono ścieżki pomiędzy węzłami." + +#: ../../po/../src/nodepath.cpp:2822 +#, c-format +msgid "" +"Node handle: angle %0.2f°, length %s; with Ctrl to snap " +"angle; with Alt to lock length; with Shift to rotate both " +"handles" +msgstr "" +"Uchwyt węzła: kąt %0.2f°, długość %s; z Ctrl przyciąganie " +"do kąta; z Alt blokada odległości; z Shift obrót obu uchwytów" + +#: ../../po/../src/nodepath.cpp:3351 +msgid "" +"Node: drag to edit the path; with Ctrl to snap to horizontal/" +"vertical; with Ctrl+Alt to snap to handles' directions" +msgstr "" +"Węzeł: edytuj ścieżkę przeciągając; z Ctrl blokada poziomo/" +"pionowo; z Ctrl+Alt wzdłuż linii uchwytów" + +#: ../../po/../src/nodepath.cpp:3375 +msgid "" +"Node handle: drag to shape the curve; with Ctrl to snap angle; " +"with Alt to lock length; with Shift to rotate both handles" +msgstr "" +"Uchwyt węzła: przeciąganie edytuje ścieżkę; z Ctrl " +"przyciąganie do kąta; z Alt blokada odległości; z Shift obrót " +"obu uchwytów" + +#: ../../po/../src/nodepath.cpp:3399 +msgid "" +"Node handle: drag to shape the curve; with Ctrl to snap angle; " +"with Alt to lock length; with Shift to rotate the opposite " +"handle in sync" +msgstr "" +"Uchwyt węzła: przeciąganie edytuje ścieżkę; z Ctrl " +"przyciąganie do kąta; z Alt blokada odległości; z Shift obrót " +"obu uchwytów" + +#. TRANSLATORS: "end" is an adjective here (NOT a verb) +#: ../../po/../src/nodepath.cpp:3591 +msgid "end node" +msgstr "węzeł końcowy" + +#. TRANSLATORS: "cusp" means "sharp" (cusp node); see also the Advanced Tutorial +#: ../../po/../src/nodepath.cpp:3596 +msgid "cusp" +msgstr "ostry" + +#. TRANSLATORS: "smooth" is an adjective here +#: ../../po/../src/nodepath.cpp:3599 +msgid "smooth" +msgstr "gładki" + +#: ../../po/../src/nodepath.cpp:3601 +msgid "symmetric" +msgstr "symetrycznie" + +#. TRANSLATORS: "end" is an adjective here (NOT a verb) +#: ../../po/../src/nodepath.cpp:3607 +msgid "end node, handle retracted (drag with Shift to extend)" +msgstr "" +"węzeł końcowy, uchwyt zredukowany (przeciągnij z Shift aby go " +"odzyskać)" + +#: ../../po/../src/nodepath.cpp:3609 +msgid "one handle retracted (drag with Shift to extend)" +msgstr "" +"jeden z uchwytów zredukowany (przeciągnij z Shift aby go odzyskać)" + +#: ../../po/../src/nodepath.cpp:3612 +msgid "both handles retracted (drag with Shift to extend)" +msgstr "oba uchwyty zredukowane (przeciągnij z Shift aby je odzyskać)" + +#: ../../po/../src/nodepath.cpp:3624 +msgid "Drag nodes or node handles; arrow keys to move nodes" +msgstr "" +"Przeciągnij węzły lub ich uchwyty; klawisze strzałek " +"przesuwają węzły" + +#: ../../po/../src/nodepath.cpp:3625 +msgid "Drag the node or its handles; arrow keys to move the node" +msgstr "" +"Przeciągnij węze lub jego uchwyty; klawisze strzałek " +"przesuwają węzeł" + +#: ../../po/../src/nodepath.cpp:3651 ../../po/../src/nodepath.cpp:3663 +msgid "Select a single object to edit its nodes or handles." +msgstr "Zaznacz pojedynczy obiekt aby edytować jego węzły lub uchwyty" + +#: ../../po/../src/nodepath.cpp:3655 +#, c-format +msgid "" +"0 out of %i node selected. Click, Shift+click, " +"or drag around nodes to select." +msgid_plural "" +"0 out of %i nodes selected. Click, Shift+click, " +"or drag around nodes to select." +msgstr[0] "" +"Wybrano 0 z %i węzła. Kliknij, kliknij+Shift, " +"lub przeciągnij ramkę aby wybrać węzły." +msgstr[1] "" +"Wybrano 0 z %i węzłów. Kliknij, kliknij+Shift, " +"lub przeciągnij ramkę aby wybrać węzły." +msgstr[2] "" +"Wybrano 0 z %i węzłów. Kliknij, kliknij+Shift, " +"lub przeciągnij ramkę aby wybrać węzły." + +#: ../../po/../src/nodepath.cpp:3661 +msgid "Drag the handles of the object to modify it." +msgstr "Przeciągnij uchwyty obiektu aby go zmodyfikować." + +#: ../../po/../src/nodepath.cpp:3669 +#, c-format +msgid "%i of %i node selected; %s. %s." +msgid_plural "%i of %i nodes selected; %s. %s." +msgstr[0] "Wybrano %i z %i węzła; %s. %s." +msgstr[1] "Wybrano %i z %i węzłów; %s. %s." +msgstr[2] "Wybrano %i z %i węzłów; %s. %s." + +#: ../../po/../src/nodepath.cpp:3675 +#, c-format +msgid "%i of %i node selected. %s." +msgid_plural "%i of %i nodes selected. %s." +msgstr[0] "Wybrano %i z %i węzła; %s." +msgstr[1] "Wybrano %i z %i węzłów; %s." +msgstr[2] "Wybrano %i z %i węzłów; %s." + +#: ../../po/../src/object-edit.cpp:493 +msgid "" +"Adjust the horizontal rounding radius; with Ctrl to make the " +"vertical radius the same" +msgstr "" +"Ustaw poziomy promień zaokrąglenia; z Ctrl ta sama wartość dla " +"pionowego promienia" + +#: ../../po/../src/object-edit.cpp:499 +msgid "" +"Adjust the vertical rounding radius; with Ctrl to make the " +"horizontal radius the same" +msgstr "" +"Ustaw pionowy promień zaokrąglenia; z Ctrl ta sama wartość dla " +"poziomego promienia" + +#: ../../po/../src/object-edit.cpp:506 ../../po/../src/object-edit.cpp:513 +msgid "" +"Adjust the width and height of the rectangle; with Ctrl to " +"lock ratio or stretch in one dimension only" +msgstr "" +"Ustaw szerokość i wysokość prostokąta; z Ctrl blokada " +"proporcji lub zmiana tylko w jednym kierunku" + +#: ../../po/../src/object-edit.cpp:686 +msgid "Adjust ellipse width, with Ctrl to make circle" +msgstr "Ustaw szerokość elipsy, z Ctrl aby uzyskać koło" + +#: ../../po/../src/object-edit.cpp:689 +msgid "Adjust ellipse height, with Ctrl to make circle" +msgstr "Ustaw wysokość elipsy, z Ctrl aby uzyskać koło" + +#: ../../po/../src/object-edit.cpp:692 +msgid "" +"Position the start point of the arc or segment; with Ctrl to " +"snap angle; drag inside the ellipse for arc, outside for " +"segment" +msgstr "" +"Ustaw początek łuku lub wycinka; z Ctrl przyciąganie do kąta; " +"kursor wewnątrz daje łuk, na zewnątrz wycinek elipsy" + +#: ../../po/../src/object-edit.cpp:695 +msgid "" +"Position the end point of the arc or segment; with Ctrl to " +"snap angle; drag inside the ellipse for arc, outside for " +"segment" +msgstr "" +"Ustaw koniec łuku lub wycinka; z Ctrl przyciąganie do kąta; " +"kursor wewnątrz daje łuk, na zewnątrz wycinek elipsy" + +#: ../../po/../src/object-edit.cpp:800 +msgid "" +"Adjust the tip radius of the star or polygon; with Shift to " +"round; with Alt to randomize" +msgstr "" +"Ustaw promień wierzchołków gwiazdy lub wielokąta; z Shift " +"zaokrąglenie; z Alt zniekształcenie losowe" + +#: ../../po/../src/object-edit.cpp:803 +msgid "" +"Adjust the base radius of the star; with Ctrl to keep star " +"rays radial (no skew); with Shift to round; with Alt to " +"randomize" +msgstr "" +"Ustaw promień podstawy gwiazdy; z Ctrl zachowuje promienistość " +"(bez skręcenia); z Shift zaokrąglenie; z Alt zniekształcenie " +"losowe" + +#: ../../po/../src/object-edit.cpp:967 +msgid "" +"Roll/unroll the spiral from inside; with Ctrl to snap angle; " +"with Alt to converge/diverge" +msgstr "" +"Rozwiń/zwiń spiralę od środka; z Ctrl przyciąganie do kąta; z " +"Alt zwiększenie/zmniejszenie przyrostu" + +#: ../../po/../src/object-edit.cpp:969 +msgid "" +"Roll/unroll the spiral from outside; with Ctrl to snap angle; " +"with Shift to scale/rotate" +msgstr "" +"Rozwiń/zwiń spiralę od zewnątrz; z Ctrl przyciąganie do kąta; " +"z Shift skalowanie/obrót; z Alt bez zmiany promienia" + +#: ../../po/../src/object-edit.cpp:1006 +msgid "Adjust the offset distance" +msgstr "Ustawienie odległości odsunięcia" + +#. TRANSLATORS: This refers to the pattern that's inside the object +#: ../../po/../src/object-edit.cpp:1036 +msgid "Move the pattern fill inside the object" +msgstr "Przesuń deseń wypełnienia wewnątrz obiektu" + +#: ../../po/../src/object-edit.cpp:1038 +msgid "Scale the pattern fill uniformly" +msgstr "Skalowanie proporcjonalnie wzoru wypełenienia" + +#: ../../po/../src/object-edit.cpp:1040 +msgid "Rotate the pattern fill; with Ctrl to snap angle" +msgstr "Obracanie wzoru wypełnienia; z Ctrl przyciąganie do kąta" + +#: ../../po/../src/object-edit.cpp:1065 +msgid "Drag to resize the flowed text frame" +msgstr "Przeciągnij aby zmienić rozmiar ramki z tekstem" + +#. Item dialog +#: ../../po/../src/object-ui.cpp:106 +msgid "Object _Properties" +msgstr "Właściwości _obiektu" + +#. Select item +#: ../../po/../src/object-ui.cpp:116 +msgid "_Select This" +msgstr "_Zaznacz ten obiekt" + +#. Create link +#: ../../po/../src/object-ui.cpp:126 +msgid "_Create Link" +msgstr "_Utwórz odnośnik" + +#. "Ungroup" +#: ../../po/../src/object-ui.cpp:199 ../../po/../src/verbs.cpp:1931 +msgid "_Ungroup" +msgstr "_Rozgrupuj" + +#. Link dialog +#: ../../po/../src/object-ui.cpp:239 +msgid "Link _Properties" +msgstr "Wł_aściwości odnośnika" + +#. Select item +#: ../../po/../src/object-ui.cpp:249 +msgid "_Follow Link" +msgstr "Przejdź za odnośnikiem" + +#. Reset transformations +#: ../../po/../src/object-ui.cpp:254 +msgid "_Remove Link" +msgstr "Usuń odnośnik" + +#. Link dialog +#: ../../po/../src/object-ui.cpp:303 +msgid "Image _Properties" +msgstr "Wł_aściwości obrazu" + +#. Item dialog +#: ../../po/../src/object-ui.cpp:344 +msgid "_Fill and Stroke" +msgstr "Wypełnienie i _kontur" + +#: ../../po/../src/path-chemistry.cpp:58 +msgid "Select at least two objects to combine." +msgstr "Wybierz co najmniej dwa obiekty do połączenia." + +#: ../../po/../src/path-chemistry.cpp:65 +msgid "At least one of the objects is not a path, cannot combine." +msgstr "" +"Co najmniej jeden z obiektów nie jest ścieżką, nie można wykonać " +"połączenia." + +#: ../../po/../src/path-chemistry.cpp:73 +msgid "" +"You cannot combine objects from different groups or layers." +msgstr "Nie można połączyć obiektów z różnych grup lub warstw." + +#: ../../po/../src/path-chemistry.cpp:155 +msgid "Select path(s) to break apart." +msgstr "Wybierz jedną lub więcej ścieżek do rozbicia na części." + +#: ../../po/../src/path-chemistry.cpp:231 +msgid "No path(s) to break apart in the selection." +msgstr "W zaznaczeniu brak ścieżek do rozbicia na części." + +#: ../../po/../src/path-chemistry.cpp:252 +msgid "Select object(s) to convert to path." +msgstr "Wybierz obiekty do przekształcenia w ścieżki." + +#: ../../po/../src/path-chemistry.cpp:297 +msgid "No objects to convert to path in the selection." +msgstr "W zaznaczeniu brak obiektów do przekształcenia w ścieżki." + +#: ../../po/../src/path-chemistry.cpp:345 +msgid "Select path(s) to reverse." +msgstr "" +"Wybierz jedną lub więcej ścieżek, których kierunek zostanie odwrócony." + +#: ../../po/../src/path-chemistry.cpp:370 +msgid "No paths to reverse in the selection." +msgstr "" +"W zaznaczeniu brak ścieżek, dla których można odwrócić kierunek." + +#: ../../po/../src/pen-context.cpp:379 ../../po/../src/pencil-context.cpp:233 +msgid "Continuing selected path" +msgstr "Kontynuowanie zaznaczonej ścieżki" + +#: ../../po/../src/pen-context.cpp:390 ../../po/../src/pencil-context.cpp:242 +msgid "Creating new path" +msgstr "Tworzenie nowej ścieżki" + +#: ../../po/../src/pen-context.cpp:394 ../../po/../src/pencil-context.cpp:246 +msgid "Appending to selected path" +msgstr "Dodawanie segmentów do zaznaczonej ścieżki" + +#: ../../po/../src/pen-context.cpp:538 +msgid "Click or click and drag to close and finish the path." +msgstr "" +"Kliknij lub kliknij i przeciągnij aby zamknąć i zakończyć " +"ścieżkę." + +#: ../../po/../src/pen-context.cpp:548 +msgid "" +"Click or click and drag to continue the path from this point." +msgstr "" +"Kliknij lub kliknij i przeciągnij aby kontynuować ścieżkę od " +"tego punktu." + +#: ../../po/../src/pen-context.cpp:857 +#, c-format +msgid "" +"%s: angle %3.2f°, distance %s; with Ctrl to snap angle, " +"Enter to finish the path" +msgstr "" +"%s: kąt %3.2f°, odległość %s; z Ctrl przyciąganie do " +"kąta, Enter aby zakończyć ścieżkę" + +#: ../../po/../src/pen-context.cpp:882 +#, c-format +msgid "" +"Curve handle: angle %3.2f°, length %s; with Ctrl to snap " +"angle" +msgstr "" +"Uchwyt krzywej: kąt %3.2f°, odległość %s; z Ctrl " +"przyciąganie do kąta" + +#: ../../po/../src/pen-context.cpp:912 +#, c-format +msgid "" +"%s: angle %3.2f°, length %s; with Ctrl to snap angle, " +"with Shift to move this handle only" +msgstr "" +"%s: kąt %3.2f°, odległość %s; z Ctrl przyciąganie do " +"kąta, z Shift przesuwanie tylko tego uchwytu." + +#: ../../po/../src/pen-context.cpp:946 +msgid "Finishing pen" +msgstr "Zakończono rysowanie krzywej Beziera" + +#: ../../po/../src/pencil-context.cpp:320 +msgid "Release here to close and finish the path." +msgstr "Zwolnij przycisk w tym miejscu aby zamknąć i zakończyć ścieżkę." + +#: ../../po/../src/pencil-context.cpp:326 +msgid "Drawing a freehand path" +msgstr "Rysowanie krzywej odręcznej" + +#: ../../po/../src/pencil-context.cpp:331 +msgid "Drag to continue the path from this point." +msgstr "Przeciągnij aby kontynuować ścieżkę od tego punktu." + +#. Write curves to object +#: ../../po/../src/pencil-context.cpp:390 +msgid "Finishing freehand" +msgstr "Zakończono rysowanie krzywej" + +#: ../../po/../src/rect-context.cpp:387 +msgid "" +"Ctrl: make square or integer-ratio rect, lock a rounded corner " +"circular" +msgstr "Ctrl: kwadrat, lub prostokąt o całkowitych proporcjach, " + +#: ../../po/../src/rect-context.cpp:549 +#, c-format +msgid "" +"Rectangle: %s × %s; with Ctrl to make square or integer-" +"ratio rectangle; with Shift to draw around the starting point" +msgstr "" +"Prostokąt: %s × %s; z Ctrl kwadrat, lub prostokąt o " +"całkowitych proporcjach; z Shift rysowanie od środka" + +#: ../../po/../src/select-context.cpp:243 +msgid "Move canceled." +msgstr "Przesunięcie anulowane." + +#: ../../po/../src/select-context.cpp:252 +msgid "Selection canceled." +msgstr "Zaznaczanie anulowane." + +#: ../../po/../src/select-context.cpp:642 +msgid "Ctrl: select in groups, move hor/vert" +msgstr "Ctrl: zaznaczanie wewnątrz grup, przesuwanie poziome/pionowe" + +#: ../../po/../src/select-context.cpp:643 +msgid "Shift: toggle select, force rubberband, disable snapping" +msgstr "Shift: przełączenie zaznaczenia, wyłączenie przyciągania" + +#: ../../po/../src/select-context.cpp:644 +msgid "Alt: select under, move selected" +msgstr "" +"Alt: pozwala zaznaczyć zasłonięty obiekt, przesuwa bez utraty " +"zaznaczenia" + +#: ../../po/../src/select-context.cpp:798 +#, fuzzy +msgid "Selected object is not a group. Cannot enter." +msgstr "" +"Zaznaczony obiekt nie jest ścieżką, nie można wykonać odsunięcia do " +"wewnątrz/na zewnątrz." + +#: ../../po/../src/select-context.cpp:876 +#, c-format +msgid "" +"Move by %s, %s; with Ctrl to restrict to horizontal/vertical; " +"with Shift to disable snapping" +msgstr "" +"Przesunięcie o %s, %s; z Ctrl poziomo/pionowo; z Shift " +"wyłączenie przyciągania" + +#: ../../po/../src/selection-chemistry.cpp:228 +msgid "Nothing was deleted." +msgstr "Nic nie zostało skasowane." + +#: ../../po/../src/selection-chemistry.cpp:259 +msgid "Select object(s) to duplicate." +msgstr "Zaznacz obiekty do skopiowania." + +#: ../../po/../src/selection-chemistry.cpp:420 +msgid "Select two or more objects to group." +msgstr "Zaznacz dwa lub więcej obiektów do połączenia w grupę." + +#: ../../po/../src/selection-chemistry.cpp:428 +msgid "Select at least two objects to group." +msgstr "Zaznacz co najmniej dwa obiekty do połączenia w grupę." + +#: ../../po/../src/selection-chemistry.cpp:513 +msgid "Select a group to ungroup." +msgstr "Zaznacz grupę do rozgrupowania." + +#: ../../po/../src/selection-chemistry.cpp:554 +msgid "No groups to ungroup in the selection." +msgstr "W zaznaczeniu brak grup do rozgrupowania." + +#: ../../po/../src/selection-chemistry.cpp:623 +msgid "Select objects to raise." +msgstr "Zaznacz obiekt(y) do przeniesienia do przodu." + +#: ../../po/../src/selection-chemistry.cpp:629 +#: ../../po/../src/selection-chemistry.cpp:681 +#: ../../po/../src/selection-chemistry.cpp:715 +#: ../../po/../src/selection-chemistry.cpp:773 +msgid "" +"You cannot raise/lower objects from different groups or layers." +msgstr "" +"Nie można przenieść do przodu/tyłu obiektów należących do różnych grup lub warstw." + +#: ../../po/../src/selection-chemistry.cpp:673 +msgid "Select object(s) to raise to top." +msgstr "Zaznacz obiekt(y) do przeniesienia na wierzch." + +#: ../../po/../src/selection-chemistry.cpp:709 +msgid "Select object(s) to lower." +msgstr "Zaznacz obiekt(y) do przeniesienia do tyłu." + +#: ../../po/../src/selection-chemistry.cpp:765 +msgid "Select object(s) to lower to bottom." +msgstr "Zaznacz obiekt(y) do przeniesienia pod spód." + +#: ../../po/../src/selection-chemistry.cpp:806 +msgid "Nothing to undo." +msgstr "Brak zmian do cofnięcia." + +#: ../../po/../src/selection-chemistry.cpp:813 +msgid "Nothing to redo." +msgstr "Brak zmian do przywrócenia." + +#: ../../po/../src/selection-chemistry.cpp:969 +msgid "Nothing was copied." +msgstr "Nic nie zostało skopiowane." + +#: ../../po/../src/selection-chemistry.cpp:1051 +msgid "Current layer is hidden. Unhide it to be able to paste to it." +msgstr "" +"Aktywna warstwa jest ukryta. Włącz jej wyświetlanie aby można było " +"wklejać na nią obiekty." + +#: ../../po/../src/selection-chemistry.cpp:1055 +msgid "Current layer is locked. Unlock it to be able to paste to it." +msgstr "" +"Aktywna warstwa jest zablokowana. Odblokuj ją aby można było wklejać " +"na nią obiekty." + +#: ../../po/../src/selection-chemistry.cpp:1068 +#: ../../po/../src/selection-chemistry.cpp:1103 +msgid "Nothing on the clipboard." +msgstr "Schowek jest pusty." + +#: ../../po/../src/selection-chemistry.cpp:1109 +msgid "Select object(s) to paste style to." +msgstr "Zaznacz obiekt(s), do których wkleić styl." + +#: ../../po/../src/selection-chemistry.cpp:1128 +msgid "Select object(s) to move to the layer above." +msgstr "Wybierz obiekt(y) do przeniesienia na warstwę powyżej." + +#: ../../po/../src/selection-chemistry.cpp:1146 +msgid "No more layers above." +msgstr "Brak warstw powyżej." + +#: ../../po/../src/selection-chemistry.cpp:1160 +msgid "Select object(s) to move to the layer below." +msgstr "Wybierz obiekt(y) do przeniesienia na warstwę poniżej." + +#: ../../po/../src/selection-chemistry.cpp:1178 +msgid "No more layers below." +msgstr "Brak warstw poniżej." + +#: ../../po/../src/selection-chemistry.cpp:1811 +msgid "Select a clone to unlink." +msgstr "Wybierz klon do odłączenia. " + +#: ../../po/../src/selection-chemistry.cpp:1842 +msgid "No clones to unlink in the selection." +msgstr "W zaznaczeniu brak klonów do odłączenia." + +#: ../../po/../src/selection-chemistry.cpp:1859 +msgid "" +"Select a clone to go to its original. Select a linked offset " +"to go to its source. Select a text on path to go to the path. Select " +"a flowed text to go to its frame." +msgstr "" +"Zaznacz klon aby przejść do oryginału. Zaznacz połączone " +"odsunięcie aby przejść do jego źródła. Zaznacz tekst na ścieżce " +"aby przejść do ścieżki. Zaznacz dopasowany tekst aby przejść do jego " +"ramki." + +#: ../../po/../src/selection-chemistry.cpp:1882 +msgid "" +"Cannot find the object to select (orphaned clone, offset, textpath, " +"flowed text?)" +msgstr "" +"Nie można odnaleźć obiektu do zazanczenia (osierocony klon, " +"odsunięcie, tekst na ścieżce, tekst dopasowany?)" + +#: ../../po/../src/selection-chemistry.cpp:1888 +msgid "" +"The object you're trying to select is not visible (it is in <" +"defs>)" +msgstr "Obiekt, który próbujesz zaznaczyć jest niewidzialny " + +#: ../../po/../src/selection-chemistry.cpp:1915 +msgid "Select object(s) to convert to pattern." +msgstr "Zaznacz obiekt(y) do zamiany na deseń." + +#: ../../po/../src/selection-chemistry.cpp:2006 +msgid "Select an object with pattern fill to extract objects from." +msgstr "" +"Zaznacz obiekt z wypełnieniem wzorem, z którego wyodrębnione zostaną " +"obiekty." + +#: ../../po/../src/selection-chemistry.cpp:2059 +msgid "No pattern fills in the selection." +msgstr "W zaznaczeniu brak wzorów wypełnienia." + +#: ../../po/../src/selection-chemistry.cpp:2079 +msgid "Select object(s) to make a bitmap copy." +msgstr "Zaznacz obiekt(y) do skopiowania jako bitmapa." + +#: ../../po/../src/selection-describer.cpp:37 +msgid "Click selection to toggle scale/rotation handles" +msgstr "Kliknij na zaznaczenie aby przełączyć tryb skalowania/obracania" + +#. no items +#: ../../po/../src/selection-describer.cpp:39 +msgid "" +"No objects selected. Click, Shift+click, or drag around objects to select." +msgstr "" +"Nie zaznaczono obiektów. Kliknij, kliknij+Shift, lub przeciągnij obejmując " +"obiekty do zaznaczenia." + +#: ../../po/../src/selection-describer.cpp:51 +#, c-format +msgid " in layer %s" +msgstr " na warstwie %s" + +#: ../../po/../src/selection-describer.cpp:54 +#, c-format +msgid " in layer %s" +msgstr " na warstwie %s" + +#: ../../po/../src/selection-describer.cpp:66 +msgid "Use Shift+D to look up original" +msgstr "Naciśnij Shift+D aby odszukać oryginał." + +#: ../../po/../src/selection-describer.cpp:70 +msgid "Use Shift+D to look up path" +msgstr "Naciśnij Shift+D aby odszukać ścieżkę" + +#: ../../po/../src/selection-describer.cpp:74 +msgid "Use Shift+D to look up frame" +msgstr "Naciśnij Shift+D aby odszukać ramkę" + +#: ../../po/../src/selection-describer.cpp:84 +#, c-format +msgid "%i object selected" +msgid_plural "%i objects selected" +msgstr[0] "Wybrano %i obiekt" +msgstr[1] "Wybrano %i obiekty" +msgstr[2] "Wybrano %i obiektów" + +#: ../../po/../src/selection-describer.cpp:90 +#, c-format +msgid "%s%s. %s." +msgstr "%s%s. %s." + +#: ../../po/../src/selection-describer.cpp:94 +#, c-format +msgid "%s in %i layer. %s." +msgid_plural "%s in %i layers. %s." +msgstr[0] "%s na %i warstwie. %s." +msgstr[1] "%s na %i warstwach. %s." +msgstr[2] "%s na %i warstwach. %s." + +#: ../../po/../src/seltrans.cpp:498 +msgid "" +"Center of rotation and skewing: drag to reposition; scaling with " +"Shift also uses this center" +msgstr "" +"Środek obrotu i skręcenia: przeciągnij aby przesunąć; skalowanie z " +"Shift także wykorzystuje ten środek" + +#: ../../po/../src/seltrans.cpp:514 +msgid "" +"Squeeze or stretch selection; with Ctrl to scale uniformly; " +"with Shift to scale around rotation center" +msgstr "" +"Ścieśnij lub rozciągnij zaznaczenie; z Ctrl skalowanie " +"proporcjonalne; z Shift skalowanie od środka obrotu" + +#: ../../po/../src/seltrans.cpp:515 +msgid "" +"Scale selection; with Ctrl to scale uniformly; with Shift to scale around rotation center" +msgstr "" +"Skalowanie zaznaczenia; z Ctrl skalowanie proporcjonalne; z " +"Shift skalowanie od środka obrotu" + +#: ../../po/../src/seltrans.cpp:519 +msgid "" +"Skew selection; with Ctrl to snap angle; with Shift to " +"skew around the opposite side" +msgstr "" +"Skręcenie zaznaczenia; z Ctrl przyciąganie do kąta; z " +"Shift obrót wokół przeciwległego narożnika" + +#: ../../po/../src/seltrans.cpp:520 +msgid "" +"Rotate selection; with Ctrl to snap angle; with Shift " +"to rotate around the opposite corner" +msgstr "" +"Obrót zaznaczenie; z Ctrl przyciąganie do kąta; z Shift " +"obrót wokół przeciwległego narożnika" + +#: ../../po/../src/seltrans.cpp:829 ../../po/../src/seltrans.cpp:909 +#, c-format +msgid "Scale: %0.2f%% x %0.2f%%; with Ctrl to lock ratio" +msgstr "Skalowanie: %0.2f%% x %0.2f%%; z Ctrl blokada proporcji" + +#. TRANSLATORS: don't modify the first ";" (it will NOT be displayed as ";" - only the second one will be) +#: ../../po/../src/seltrans.cpp:984 +#, c-format +msgid "Skew: %0.2f°; with Ctrl to snap angle" +msgstr "Skręcenie: %0.2f°; z Ctrl przyciąganie do kąta" + +#. TRANSLATORS: don't modify the first ";" (it will NOT be displayed as ";" - only the second one will be) +#: ../../po/../src/seltrans.cpp:1035 +#, c-format +msgid "Rotate: %0.2f°; with Ctrl to snap angle" +msgstr "Obrót: %0.2f°; z Ctrl przyciąganie do kąta" + +#: ../../po/../src/seltrans.cpp:1090 +#, c-format +msgid "Move center to %s, %s" +msgstr "Przesunięcie środka do %s, %s" + +#: ../../po/../src/slideshow.cpp:90 +msgid "Inkscape slideshow" +msgstr "Pokaz slajdów Inkscape" + +#: ../../po/../src/sp-anchor.cpp:181 +#, c-format +msgid "Link to %s" +msgstr "Odnośnik do %s" + +#: ../../po/../src/sp-anchor.cpp:185 +msgid "Link without URI" +msgstr "Odnośnik bez identyfikatora URI" + +#: ../../po/../src/sp-ellipse.cpp:438 ../../po/../src/sp-ellipse.cpp:870 +msgid "Ellipse" +msgstr "Elipsa" + +#: ../../po/../src/sp-ellipse.cpp:583 +msgid "Circle" +msgstr "Koło" + +#: ../../po/../src/sp-ellipse.cpp:865 +msgid "Segment" +msgstr "Odcinek" + +#: ../../po/../src/sp-ellipse.cpp:867 +msgid "Arc" +msgstr "Łuk" + +#. TRANSLATORS: "Flow region" is an area where text is allowed to flow +#: ../../po/../src/sp-flowregion.cpp:276 +msgid "Flow region" +msgstr "Obszar wypełniony tekstem" + +#. TRANSLATORS: A region "cut out of" a flow region; text is not allowed to flow inside the +#. * flow excluded region. flowRegionExclude in SVG 1.2: see +#. * http://www.w3.org/TR/2004/WD-SVG12-20041027/flow.html#flowRegion-elem and +#. * http://www.w3.org/TR/2004/WD-SVG12-20041027/flow.html#flowRegionExclude-elem. +#: ../../po/../src/sp-flowregion.cpp:493 +msgid "Flow excluded region" +msgstr "Obszar niewypełniony tekstem" + +#: ../../po/../src/sp-flowtext.cpp:355 +#, c-format +msgid "Flowed text (%d characters)" +msgstr "Tekst dopasowany (%d znaków)" + +#: ../../po/../src/sp-flowtext.cpp:357 +#, c-format +msgid "Linked flowed text (%d characters)" +msgstr "Połączony tekst dopasowany (%d znaków)" + +#: ../../po/../src/sp-guide.cpp:290 +msgid "vertical guideline" +msgstr "Prowadnica pionowa" + +#: ../../po/../src/sp-guide.cpp:292 +msgid "horizontal guideline" +msgstr "Prowadnica pozioma" + +#: ../../po/../src/sp-image.cpp:835 +msgid "embedded" +msgstr "osadzony" + +#: ../../po/../src/sp-image.cpp:839 +msgid "(null_pointer)" +msgstr "(zerowy_wskaźnik)" + +#: ../../po/../src/sp-image.cpp:843 +#, c-format +msgid "Image with bad reference: %s" +msgstr "Obraz z niepoprawnym odwołaniem: %s" + +#: ../../po/../src/sp-image.cpp:844 +#, c-format +msgid "Image %d × %d: %s" +msgstr "Obraz %d × %d: %s" + +#: ../../po/../src/sp-item-group.cpp:390 +#, c-format +msgid "Group of %d object" +msgid_plural "Group of %d objects" +msgstr[0] "Grupa z %d obiektem" +msgstr[1] "Grupa %d obiektów" +msgstr[2] "Grupa %d obiektów" + +#: ../../po/../src/sp-item.cpp:720 +msgid "Object" +msgstr "Obiekt" + +#: ../../po/../src/sp-line.cpp:202 +msgid "Line" +msgstr "Linia" + +#. TRANSLATORS COMMENT: %s is either "outset" or "inset" depending on sign +#: ../../po/../src/sp-offset.cpp:433 +#, c-format +msgid "Linked offset, %s by %f pt" +msgstr "Połączone odsunięcie, %s o %f pkt" + +#: ../../po/../src/sp-offset.cpp:434 ../../po/../src/sp-offset.cpp:438 +msgid "outset" +msgstr "na zewnątrz" + +#: ../../po/../src/sp-offset.cpp:434 ../../po/../src/sp-offset.cpp:438 +msgid "inset" +msgstr "do wewnątrz" + +#. TRANSLATORS COMMENT: %s is either "outset" or "inset" depending on sign +#: ../../po/../src/sp-offset.cpp:437 +#, c-format +msgid "Dynamic offset, %s by %f pt" +msgstr "Odsunięcie dynamiczne, %s o %f pkt" + +#: ../../po/../src/sp-path.cpp:127 +#, c-format +msgid "Path (%i node)" +msgid_plural "Path (%i nodes)" +msgstr[0] "Ścieżka (%i węzeł)" +msgstr[1] "Ścieżka (%i węzły)" +msgstr[2] "Ścieżka (%i węzłów)" + +#: ../../po/../src/sp-polygon.cpp:216 +msgid "Polygon" +msgstr "Wielokąt:" + +#: ../../po/../src/sp-polyline.cpp:179 +msgid "Polyline" +msgstr "Polilinia" + +#: ../../po/../src/sp-rect.cpp:250 +msgid "Rectangle" +msgstr "Prostokąt" + +#. TRANSLATORS: since turn count isn't an integer, please adjust the +#. string as needed to deal with an localized plural forms. +#: ../../po/../src/sp-spiral.cpp:305 +#, c-format +msgid "Spiral with %3f turns" +msgstr "Spirala z %3f obrotami" + +#: ../../po/../src/sp-star.cpp:288 +#, c-format +msgid "Star with %d vertex" +msgid_plural "Star with %d vertices" +msgstr[0] "Gwiazda z %d ramieniem" +msgstr[1] "Gwiazda z %d ramionami" +msgstr[2] "Gwiazda z %d ramionami" + +#: ../../po/../src/sp-star.cpp:292 +#, c-format +msgid "Polygon with %d vertex" +msgid_plural "Polygon with %d vertices" +msgstr[0] "Wielokąt z %d wierzchołkiem" +msgstr[1] "Wielokąt z %d wierzchołkami" +msgstr[2] "Wielokąt z %d wierzchołkami" + +#. TRANSLATORS: For description of font with no name. +#: ../../po/../src/sp-text.cpp:420 +msgid "<no name found>" +msgstr "<nie znaleziono nazwy>" + +#: ../../po/../src/sp-text.cpp:426 +#, c-format +msgid "Text on path (%s, %s)" +msgstr "Tekst na ścieżce (%s, %s)" + +#: ../../po/../src/sp-text.cpp:427 +#, c-format +msgid "Text (%s, %s)" +msgstr "Tekst (%s, %s)" + +#. TRANSLATORS: Used for statusbar description for long chains: +#. * "Clone of: Clone of: ... in Layer 1". +#: ../../po/../src/sp-use.cpp:317 +msgid "..." +msgstr "..." + +#: ../../po/../src/sp-use.cpp:325 +#, c-format +msgid "Clone of: %s" +msgstr "Klon obiektu: %s" + +#: ../../po/../src/sp-use.cpp:329 +msgid "Orphaned clone" +msgstr "Osierocony klon" + +#: ../../po/../src/spiral-context.cpp:355 +msgid "Ctrl: snap angle" +msgstr "Ctrl: przyciąganie do kąta" + +#: ../../po/../src/spiral-context.cpp:357 +msgid "Alt: lock spiral radius" +msgstr "Alt: blokada promienia spirali" + +#: ../../po/../src/spiral-context.cpp:469 +#, c-format +msgid "" +"Spiral: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" +"Spirala: promień %s, %5g°; z Ctrl przyciąganie do kąta" + +#: ../../po/../src/splivarot.cpp:106 +msgid "Select at least 2 paths to perform a boolean operation." +msgstr "Zaznacz co najmniej 2 ścieżki aby wykonać operację." + +#: ../../po/../src/splivarot.cpp:112 +msgid "" +"Select exactly 2 paths to perform difference, XOR, division, or path " +"cut." +msgstr "" +"Zaznacz dokładnie 2 ścieżki aby wykonać operację różnicy, " +"wykluczenia, podziału, lub rozcięcia ścieżki." + +#: ../../po/../src/splivarot.cpp:129 ../../po/../src/splivarot.cpp:144 +msgid "" +"Unable to determine the z-order of the objects selected for " +"difference, XOR, division, or path cut." +msgstr "" +"Nie można rozpoznać kolejności obiektów zaznaczonych do różnicy, " +"wykluczenia, podziału, lub rozcięcia ścieżki." + +#: ../../po/../src/splivarot.cpp:174 +msgid "" +"One of the objects is not a path, cannot perform boolean operation." +msgstr "Jeden z obiektów nie jest ścieżką, nie można wykonać operacji." + +#. TRANSLATORS: "to outline" means "to convert stroke to path" +#: ../../po/../src/splivarot.cpp:554 +msgid "Select path(s) to outline." +msgstr "Zaznacz ścieżkę, którą przekształcić w obrys." + +#. TRANSLATORS: "to outline" means "to convert stroke to path" +#: ../../po/../src/splivarot.cpp:748 +msgid "No stroked paths to outline in the selection." +msgstr "W zaznaczeniu brak ścieżek z konturem do zamiany w obrys." + +#: ../../po/../src/splivarot.cpp:832 +msgid "Selected object is not a path, cannot inset/outset." +msgstr "" +"Zaznaczony obiekt nie jest ścieżką, nie można wykonać odsunięcia do " +"wewnątrz/na zewnątrz." + +#: ../../po/../src/splivarot.cpp:1040 +msgid "Select path(s) to inset/outset." +msgstr "Zaznacz ścieżkę(i) do odsunięcia do wewnątrz/na zewnątrz." + +#: ../../po/../src/splivarot.cpp:1257 +msgid "No paths to inset/outset in the selection." +msgstr "" +"W zaznaczeniu brak ścieżek do odsunięcia do wewnątrz/na zewnątrz." + +#: ../../po/../src/splivarot.cpp:1390 +msgid "Select path(s) to simplify." +msgstr "Zaznacz ścieżkę(i) do uproszczenia." + +#: ../../po/../src/splivarot.cpp:1417 +msgid "No paths to simplify in the selection." +msgstr "W zaznaczeniu brak ścieżek do uproszczenia." + +#: ../../po/../src/star-context.cpp:362 +msgid "Ctrl: snap angle; keep rays radial" +msgstr "Ctrl: przyciąganie do kąta; zachowanie promienistości" + +#: ../../po/../src/star-context.cpp:470 +#, c-format +msgid "" +"Polygon: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" +"Wielokąt: promień %s, kąt %5g°; z Ctrl przyciąganie do " +"kąta" + +#: ../../po/../src/star-context.cpp:471 +#, c-format +msgid "Star: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" +"Gwiazda: promień %s, kąt %5g°; z Ctrl przyciąganie do kąta" + +#: ../../po/../src/text-chemistry.cpp:90 +msgid "Select a text and a path to put text on path." +msgstr "Zaznacz tekst i ścieżkę aby wprowadzić tekst na ścieżkę." + +#: ../../po/../src/text-chemistry.cpp:95 +msgid "" +"This text object is already put to a path. Remove it from the path " +"first. Use Shift+D to look up its path." +msgstr "" +"Ten obiekt tekstowy jest już wprowadzony na ścieżkę. Zdejmij go " +"najpierw ze ścieżki. Użyj Shift+D aby odnaleźć jego ścieżkę." + +#. rect is the only SPShape which is not yet, and thus SVG forbids us from putting text on it +#: ../../po/../src/text-chemistry.cpp:101 +msgid "" +"You cannot put text on a rectangle in this version. Convert rectangle to " +"path first." +msgstr "" +"W tej wersji progrmau nie można wprowadzić tekstu na prostokąt. Dokonaj " +"najpierw konwersji prostokąta na ścieżkę." + +#: ../../po/../src/text-chemistry.cpp:159 +msgid "Select a text on path to remove it from path." +msgstr "Zaznacz tekst na ścieżce aby zdjąć go ze ścieżki." + +#: ../../po/../src/text-chemistry.cpp:181 +msgid "No texts-on-paths in the selection." +msgstr "W zaznaczeniu brak tekstów na ścieżce." + +#: ../../po/../src/text-chemistry.cpp:209 +#: ../../po/../src/text-chemistry.cpp:229 +msgid "Select text(s) to remove kerns from." +msgstr "Zaznacz tekst(y) do usunięcia kerningu ręcznego." + +#: ../../po/../src/text-chemistry.cpp:250 +msgid "" +"Select a text and one or more paths or shapes to flow text " +"into frame." +msgstr "" +"Zaznacz tekst i jedną lub więcej ścieżek lub kształtów aby " +"wprowadzić tekst do ramki." + +#: ../../po/../src/text-chemistry.cpp:322 +msgid "Select a flowed text to unflow it." +msgstr "Zazancz dopasowany tekst aby go uwolnić z ramki." + +#: ../../po/../src/text-context.cpp:463 +msgid "Click to edit the text, drag to select part of the text." +msgstr "" +"Kliknij aby edytować tekst, przeciągnij aby zaznaczyć jego " +"fragment." + +#: ../../po/../src/text-context.cpp:465 +msgid "" +"Click to edit the flowed text, drag to select part of the text." +msgstr "" +"Kliknij aby edytować dopasowany tekst, przeciągnij aby " +"zaznaczyć jego fragment." + +#: ../../po/../src/text-context.cpp:540 +msgid "Non-printable character" +msgstr "Znak niedrukowany" + +#: ../../po/../src/text-context.cpp:589 +#, c-format +msgid "Unicode: %s: %s" +msgstr "Unicode: %s: %s" + +#: ../../po/../src/text-context.cpp:591 ../../po/../src/text-context.cpp:855 +msgid "Unicode: " +msgstr "Unicode: " + +#: ../../po/../src/text-context.cpp:615 +msgid "Current layer is hidden. Unhide it to be able to add text." +msgstr "Aktywna warstwa jest ukryta. Włącz jej wyświetlanie aby " + +#: ../../po/../src/text-context.cpp:619 +msgid "Current layer is locked. Unlock it to be able to add text." +msgstr "" +"Aktywna warstwa jest zablokowana. Odblokuj ją aby dodanie do niej " +"tekstu było możliwe." + +#: ../../po/../src/text-context.cpp:673 +#, c-format +msgid "Flowed text frame: %s × %s" +msgstr "Ramka tekstu dopasowanego: %s × %s" + +#: ../../po/../src/text-context.cpp:708 ../../po/../src/text-context.cpp:1464 +msgid "Type text; Enter to start new line." +msgstr "Wprowadź tekst; Enter aby przejść do nowej linii." + +#: ../../po/../src/text-context.cpp:719 +msgid "Flowed text is created." +msgstr "Utworzono tekst dopasowany." + +#: ../../po/../src/text-context.cpp:722 +msgid "" +"The frame is too small for the current font size. Flowed text not " +"created." +msgstr "" +"Ramka jest zbyt mała dla wybranej wielkości czcionki. Nie utworzono " +"tekstu dopasowanego." + +#: ../../po/../src/text-context.cpp:841 +msgid "No-break space" +msgstr "Spacja nie łamiąca wiersza" + +#: ../../po/../src/text-context.cpp:1462 +msgid "Type flowed text; Enter to start new paragraph." +msgstr "Wprowadź tekst do obiektu; Enter aby rozpocząć nowy akapit." + +#: ../../po/../src/text-context.cpp:1472 ../../po/../src/tools-switch.cpp:189 +msgid "" +"Click to select or create text, drag to create flowed text; " +"then type." +msgstr "" +"Kliknij aby zaznaczyć lub utworzyć tekst, przeciągnij aby " +"utworzyć dopasowany tekst, następnie wprowadź treść." + +#: ../../po/../src/tools-switch.cpp:141 +msgid "" +"To edit a path, click, Shift+click, or drag around " +"nodes to select them, then drag nodes and handles. Click on an " +"object to select." +msgstr "" +"Aby edytować ścieżkę kliknij, kliknij+Shift, lub " +"przeciągnij obejmując węzły do zaznaczenia, następnie przeciągaj " +"węzły i uchwyty. Kliknij na obiekcie aby go zaznaczyć." + +#: ../../po/../src/tools-switch.cpp:147 +msgid "" +"Drag to create a rectangle. Drag controls to round corners and " +"resize. Click to select." +msgstr "" +"Przeciągnij aby utworzyć prostokąt. Przeciągaj uchwyty aby " +"zaokrąglić narożniki i zmienić rozmiar. Kliknij aby zaznaczyć." + +#: ../../po/../src/tools-switch.cpp:153 +msgid "" +"Drag to create an ellipse. Drag controls to make an arc or " +"segment. Click to select." +msgstr "" +"Przeciągnij aby utworzyć elipsę. Przeciągaj uchwyty aby " +"utworzyć łuk lub wycinek elipsy. Kliknij aby zaznaczyć." + +#: ../../po/../src/tools-switch.cpp:159 +msgid "" +"Drag to create a star. Drag controls to edit the star shape. " +"Click to select." +msgstr "" +"Przeciągnij aby utworzyć gwiazdę. Przeciągaj uchwyty aby " +"zmienić kształt gwiazdy. Kliknij aby zaznaczyć." + +#: ../../po/../src/tools-switch.cpp:165 +msgid "" +"Drag to create a spiral. Drag controls to edit the spiral " +"shape. Click to select." +msgstr "" +"Przeciągnij aby utworzyć spiralę. Przeciągaj uchwyty aby " +"zmienić kształt spirali. Kliknij aby zaznaczyć." + +#: ../../po/../src/tools-switch.cpp:171 +msgid "" +"Drag to create a freehand line. Start drawing with Shift to " +"append to selected path." +msgstr "" +"Przeciągnij aby utworzyć krzywą odręczną. Rozpocznij z Shift " +"aby dołączyć do wybranej ścieżki." + +#: ../../po/../src/tools-switch.cpp:177 +msgid "" +"Click or click and drag to start a path; with Shift to " +"append to selected path." +msgstr "" +"Kliknij lub kliknij i przeciągnij aby rozpocząć ścieżkę; z " +"Shift aby dołączyć do zaznaczonej ścieżki." + +#: ../../po/../src/tools-switch.cpp:183 +msgid "" +"Drag to paint a calligraphic stroke. Left/right arrow " +"keys adjust width, up/down adjust angle." +msgstr "" +"Przeciągnij aby utworzyć kaligrafię. Klawisze sztrzałek Lewa/" +"prawa zmieniają grubość, góra/dół ustawiają " + +#: ../../po/../src/tools-switch.cpp:195 +msgid "" +"Drag or double click to create a gradient on selected objects, " +"drag handles to adjust gradients." +msgstr "" +"Przeciągnij lub kliknij podwójnie aby utworzyć gradient na " +"wybranych obiektach, przeciągnij uchwyty aby edytować gradienty." + +#: ../../po/../src/tools-switch.cpp:201 +msgid "" +"Click or drag around an area to zoom in, Shift+click to " +"zoom out." +msgstr "" +"Kliknij lub przeciągnij zaznaczając obszar aby powiększyć, " +"kliknij+Shift aby pomniejszyć widok." + +#: ../../po/../src/tools-switch.cpp:213 +msgid "Click and drag between shapes to create a connector." +msgstr "Kliknij i przeciągnij pomiędzy kształtami aby utworzyć łącznik." + +#: ../../po/../src/trace/potrace/inkscape-potrace.cpp:553 +#: ../../po/../src/trace/potrace/inkscape-potrace.cpp:654 +#, c-format +msgid "Trace: %d. %ld nodes" +msgstr "Wektoryzacja: %d. %ld węzłów" + +#: ../../po/../src/trace/trace.cpp:53 ../../po/../src/trace/trace.cpp:62 +#: ../../po/../src/trace/trace.cpp:70 +msgid "Select an image to trace" +msgstr "Wybierz obraz do wektoryzacji" + +#: ../../po/../src/trace/trace.cpp:133 +msgid "Trace: No active document" +msgstr "Wektoryzacja: Brak aktywnego dokumentu" + +#: ../../po/../src/trace/trace.cpp:154 +msgid "Trace: Image has no bitmap data" +msgstr "Wektoryzacja: W obrazie nie ma danych rastrowych" + +#: ../../po/../src/trace/trace.cpp:267 +#, c-format +msgid "Trace: Done. %ld nodes created" +msgstr "Wektoryzacja: Zakończono. Utworzono %ld węzłów." + +#: ../../po/../src/ui/dialog/aboutbox.cpp:59 ../../po/../src/verbs.cpp:2212 +msgid "About Inkscape" +msgstr "Informacja o programie Inkscape" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:66 +msgid "_Splash" +msgstr "" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:68 +#, fuzzy +msgid "_Authors" +msgstr "Autorzy" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:69 +#, fuzzy +msgid "_Translators" +msgstr "Tłumacze" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:70 +msgid "_License" +msgstr "_Licencja" + +#. TRANSLATORS: This is the filename of the `About Inkscape' picture in +#. the `screens' directory. Thus the translation of "about.svg" should be +#. the filename of its translated version, e.g. about.zh.svg for Chinese. +#. +#. N.B. about.svg changes once per release. (We should probably rename +#. the original to about-0.40.svg etc. as soon as we have a translation. +#. If we do so, then add an item to release-checklist saying that the +#. string here should be changed.) +#. FIXME? INKSCAPE_SCREENSDIR and "about.svg" are in UTF-8, not the +#. native filename encoding... and the filename passed to sp_document_new +#. should be in UTF-*8.. +#: ../../po/../src/ui/dialog/aboutbox.cpp:114 +msgid "about.svg" +msgstr "about.svg" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:464 +msgid "Minimum horizontal gap (in px units) between bounding boxes" +msgstr "" + +#. TRANSLATORS: Horizontal gap +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:466 +#: ../../po/../src/widgets/toolbox.cpp:1556 +msgid "H:" +msgstr "W:" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:474 +msgid "Minimum vertical gap (in px units) between bounding boxes" +msgstr "" + +#. TRANSLATORS: Vertical gap +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:476 +msgid "V:" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:734 +msgid "Align" +msgstr "Wyrównaj" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:735 +msgid "Distribute" +msgstr "Rozłóż" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:736 +msgid "Remove overlaps" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:737 +msgid "Nodes" +msgstr "Węzły" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:742 +msgid "Relative to: " +msgstr "Względem: " + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:747 +msgid "Align right sides of objects to left side of anchor" +msgstr "Wyrównaj prawe krawędzie obiektów do lewej strony elementu sterującego" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:750 +msgid "Align left sides" +msgstr "Wyrównaj lewe krawędzie" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:753 +msgid "Center on vertical axis" +msgstr "Wyśrodkuj na osi pionowej" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:756 +msgid "Align right sides" +msgstr "Wyrównaj prawe krawędzie" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:759 +msgid "Align left sides of objects to right side of anchor" +msgstr "Wyrównaj lewe krawędzie obiektów do prawej strony elementu sterującego" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:762 +msgid "Align bottoms of objects to top of anchor" +msgstr "Wyrównaj dolne krawędzie obiektów do góry elementu sterującego" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:765 +msgid "Align tops" +msgstr "Wyrównaj górne krawędzie" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:768 +msgid "Center on horizontal axis" +msgstr "Wyśrodkuj na osi poziomej" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:771 +msgid "Align bottoms" +msgstr "Wyrównaj dolne krawędzie" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:774 +msgid "Align tops of objects to bottom of anchor" +msgstr "Wyrównaj górne krawędzie obiektów do dołu elementu sterującego" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:779 +msgid "Align baseline anchors of texts vertically" +msgstr "Wyrównaj kotwice tekstów do linii pionowej" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:782 +msgid "Align baseline anchors of texts horizontally" +msgstr "Wyrównaj kotwice tekstów do linii poziomej" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:787 +msgid "Make horizontal gaps between objects equal" +msgstr "Wyrównaj odstępy pomiędzy obiektami w poziomie" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:791 +msgid "Distribute left sides equidistantly" +msgstr "Rozłóż lewe krawędzie obiektów w równych odstępach" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:794 +msgid "Distribute centers equidistantly horizontally" +msgstr "Rozłóż środki obiektów w równych odstępach poziomo" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:797 +msgid "Distribute right sides equidistantly" +msgstr "Rozłóż prawe krawędzie obiektów w równych odstępach" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:801 +msgid "Make vertical gaps between objects equal" +msgstr "Wyrównaj odstępy pomiędzy obiektami w pionie" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:805 +msgid "Distribute tops equidistantly" +msgstr "Rozłóż górne krawędzie obiektów w równych odstępach" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:808 +msgid "Distribute centers equidistantly vertically" +msgstr "Rozłóż środki obiektów w równych odstępach w pionie" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:811 +msgid "Distribute bottoms equidistantly" +msgstr "Rozłóż dolne krawędzie obiektów w równych odstępach" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:816 +msgid "Distribute baseline anchors of texts horizontally" +msgstr "Rozłóż kotwice tekstów w równych odstępach w poziomie" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:819 +msgid "Distribute baseline anchors of texts vertically" +msgstr "Rozłóż kotwice tekstów w równych odstępach w pionie" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:824 +msgid "Randomize centers in both dimensions" +msgstr "Rozłóż losowo środki obiektów w obu kierunkach" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:827 +msgid "Unclump objects: try to equalize edge-to-edge distances" +msgstr "" +"Rozproszenie obiektów: staraj się wyrównać odległości pomiędzy krawędziami" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:832 +msgid "" +"Move objects as little as possible so that their bounding boxes do not " +"overlap" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:837 +msgid "Align selected nodes horizontally" +msgstr "Wyrównanie wybranych węzłów w poziomie" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:840 +msgid "Align selected nodes vertically" +msgstr "Wyrównanie wybranych węzłów w pionie" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:843 +msgid "Distribute selected nodes horizontally" +msgstr "Równe odstepy pomiędzy węzłami w poziomie" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:846 +msgid "Distribute selected nodes vertically" +msgstr "Równe odstępy pomiędzy węzłami w pionie" + +#. Rest of the widgetry +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:851 +msgid "Last selected" +msgstr "Ostatni zaznaczony" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:852 +msgid "First selected" +msgstr "Pierwszy zaznaczony" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:853 +msgid "Biggest item" +msgstr "Największy element" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:854 +msgid "Smallest item" +msgstr "Najmniejszy element" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:856 +#: ../../po/../src/widgets/desktop-widget.cpp:1065 +msgid "Drawing" +msgstr "Rysunek" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:91 +#, fuzzy +msgid "Metadata 1" +msgstr "Metadane" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:92 +#, fuzzy +msgid "Metadata 2" +msgstr "Metadane" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:187 +#, fuzzy +msgid "X coordinate of grid origin" +msgstr "Pionowa współrzędna zaznaczenia" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:189 +#, fuzzy +msgid "Y coordinate of grid origin" +msgstr "Pionowa współrzędna zaznaczenia" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:191 +#, fuzzy +msgid "Distance of vertical grid lines" +msgstr "Prowadnica pionowa" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:193 +#, fuzzy +msgid "Distance of horizontal grid lines" +msgstr "Prowadnica pozioma" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:197 +msgid "Max. snapping distance from grid" +msgstr "" + +#: ../../po/../src/ui/dialog/export.cpp:34 +msgid "Export" +msgstr "Eksport" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:36 +msgid "Fill" +msgstr "Wypełnienie" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:37 +msgid "Stroke Paint" +msgstr "Kontur" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:38 +msgid "Stroke Style" +msgstr "Styl konturu" + +#: ../../po/../src/ui/dialog/find.cpp:34 +msgid "Find" +msgstr "Znajdź" + +#: ../../po/../src/ui/dialog/memory.cpp:96 +msgid "Heap" +msgstr "Stos" + +#: ../../po/../src/ui/dialog/memory.cpp:97 +msgid "In Use" +msgstr "Używana" + +#. TRANSLATORS: "Slack" refers to memory which is in the heap but currently unused. +#. More typical usage is to call this memory "free" rather than "slack". +#: ../../po/../src/ui/dialog/memory.cpp:100 +msgid "Slack" +msgstr "Wolna" + +#: ../../po/../src/ui/dialog/memory.cpp:101 +msgid "Total" +msgstr "Całkowita" + +#: ../../po/../src/ui/dialog/memory.cpp:141 +#: ../../po/../src/ui/dialog/memory.cpp:147 +#: ../../po/../src/ui/dialog/memory.cpp:154 +#: ../../po/../src/ui/dialog/memory.cpp:186 +msgid "Unknown" +msgstr "Nieznane" + +#: ../../po/../src/ui/dialog/memory.cpp:167 +msgid "Combined" +msgstr "Łącznie" + +#: ../../po/../src/ui/dialog/memory.cpp:209 +msgid "Recalculate" +msgstr "Przelicz ponownie" + +#: ../../po/../src/ui/dialog/messages.cpp:74 +msgid "Ready." +msgstr "Gotowe." + +#: ../../po/../src/ui/dialog/messages.cpp:75 +msgid "" +"Enable log display by setting dialogs.debug 'redirect' attribute to 1 in " +"preferences.xml" +msgstr "" +"Włącz wyświetlanie dziennika ustawiając wartość dialogs.debug 'redirect' na " +"1, w pliku preferences.xml" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:184 +msgid "_Execute Python" +msgstr "Wykonaj skrypt _Python" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:186 +msgid "_Execute Perl" +msgstr "Wykonaj skrypt P_erl" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:195 +msgid "Script" +msgstr "Skrypt" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:205 +msgid "Output" +msgstr "Wyjście" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:215 +msgid "Errors" +msgstr "Błędy" + +#. Dialog organization +#: ../../po/../src/ui/dialog/session-player.cpp:73 +msgid "Session file" +msgstr "Plik sesji" + +#: ../../po/../src/ui/dialog/session-player.cpp:74 +msgid "Playback controls" +msgstr "Sterowanie odtwarzaniem" + +#: ../../po/../src/ui/dialog/session-player.cpp:75 +msgid "Message information" +msgstr "Informacja o wiadomości" + +#. Active session file display +#. fixme: Does this mean the active file for the session, or the file for the active session? +#. Please indicate which with a TRANSLATORS comment. +#: ../../po/../src/ui/dialog/session-player.cpp:85 +msgid "Active session file:" +msgstr "Aktywny plik sesji:" + +#: ../../po/../src/ui/dialog/session-player.cpp:86 +msgid "Delay (milliseconds):" +msgstr "Opóźnienie (milisekundy):" + +#. Unload/load buttons +#: ../../po/../src/ui/dialog/session-player.cpp:94 +msgid "Close file" +msgstr "Zamknij plik" + +#: ../../po/../src/ui/dialog/session-player.cpp:95 +msgid "Open new file" +msgstr "Otwórz nowy plik" + +#: ../../po/../src/ui/dialog/session-player.cpp:96 +msgid "Set delay" +msgstr "Ustaw opóźnienie" + +#: ../../po/../src/ui/dialog/session-player.cpp:138 +msgid "Rewind" +msgstr "Przewiń" + +#: ../../po/../src/ui/dialog/session-player.cpp:139 +msgid "Go back one change" +msgstr "Cofnij o jedną zmianę" + +#: ../../po/../src/ui/dialog/session-player.cpp:140 +msgid "Pause" +msgstr "Pauza" + +#: ../../po/../src/ui/dialog/session-player.cpp:141 +msgid "Go forward one change" +msgstr "Przejdź do przodu o jedną zmianę" + +#: ../../po/../src/ui/dialog/session-player.cpp:142 +msgid "Play" +msgstr "Odtwórz" + +#: ../../po/../src/ui/dialog/session-player.cpp:177 +#: ../../po/../src/verbs.cpp:1573 +msgid "Open session file" +msgstr "Otwórz plik sesji" + +#. ##Set up the Potrace panel +#. #### brightness #### +#. #### Multiple scanning#### +#. ----Hbox1 +#: ../../po/../src/ui/dialog/tracedialog.cpp:345 +#: ../../po/../src/ui/dialog/tracedialog.cpp:428 +msgid "Brightness" +msgstr "Jasność" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:348 +msgid "Trace by a given brightness level" +msgstr "Wektoryzacja w oparciu o jasność" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:355 +msgid "Brightness cutoff for black/white" +msgstr "Próg rozdzielenia czarny/biały" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:362 +msgid "Image Brightness" +msgstr "Jasność obrazu" + +#. #### canny edge detection #### +#. TRANSLATORS: "Canny" is the name of the inventor of this edge detection method +#: ../../po/../src/ui/dialog/tracedialog.cpp:369 +msgid "Optimal Edge Detection (Canny)" +msgstr "Optymalne wykrywanie krawędzi" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:372 +msgid "Trace with edge detection by J. Canny's algorithm" +msgstr "" +"Wektoryzacja z wykorzystaniem optymalnego wykrywania krawędzi, metodą J." +"Canny'ego" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:388 +msgid "Brightness cutoff for adjacent pixels (determines edge thickness)" +msgstr "Próg różnicy sąsiednich pikseli (decyduje o grubości krawędzi)" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:395 +msgid "Edge Detection" +msgstr "Wykrywanie krawędzi" + +#. #### quantization #### +#. TRANSLATORS: Color Quantization: the process of reducing the number of colors +#. in an image by selecting an optimized set of representative colors and then +#. re-applying this reduced set to the original image. +#: ../../po/../src/ui/dialog/tracedialog.cpp:404 +msgid "Color Quantization" +msgstr "Redukcja kolorów" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:407 +msgid "Trace along the boundaries of reduced colors" +msgstr "Wykrywanie obszarów po zredukowaniu liczby kolorów" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:414 +msgid "The number of reduced colors" +msgstr "Zredukowana liczba kolorów" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:416 +msgid "Colors:" +msgstr "Kolory:" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:421 +msgid "Quantization / Reduction" +msgstr "Przybliżenie / redukcja" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:431 +msgid "Trace the given number of brightness levels" +msgstr "Wykrywanie obszarów dla określonej liczby stopni jasności" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:438 +msgid "Scans:" +msgstr "Liczba przebiegów:" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:440 +msgid "The desired number of scans" +msgstr "Wybrana liczba przebiegów skanowania" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:448 +msgid "Trace the given number of reduced colors" +msgstr "Wykrywanie obszarów dla określonej liczby kolorów" + +#. ---Hbox3 +#: ../../po/../src/ui/dialog/tracedialog.cpp:454 +msgid "Monochrome" +msgstr "Monochromatycznie" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:457 +msgid "Same as Color, but convert result to grayscale" +msgstr "Jak dla koloru, ale z końcową konwersją do skali szarości" + +#. TRANSLATORS: "Stack" is a verb here +#: ../../po/../src/ui/dialog/tracedialog.cpp:460 +msgid "Stack" +msgstr "Nakładanie" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:463 +msgid "" +"Stack scans vertically (no gaps) or tile horizontally (usually with gaps)" +msgstr "" +"Nakładanie na siebie obszarów (brak prześwitów) lub złożenie wzdłuż krawędzi " +"(zwykle widoczne są prześwity)" + +#. TRANSLATORS: "Smooth" is a verb here +#: ../../po/../src/ui/dialog/tracedialog.cpp:466 +msgid "Smooth" +msgstr "Rozmycie" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:469 +msgid "Apply Gaussian blur to the bitmap before tracing" +msgstr "Wykonanie na bitmapie rozmycia Gaussa przed wektoryzacją" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:473 +msgid "Multiple Scanning" +msgstr "Wielokrotny przebieg" + +#. #### Preview #### +#: ../../po/../src/ui/dialog/tracedialog.cpp:479 +#: ../../po/../src/ui/dialog/tracedialog.cpp:489 +msgid "Preview" +msgstr "Podgląd" + +#. do not expand +#: ../../po/../src/ui/dialog/tracedialog.cpp:483 +msgid "Preview the result without actual tracing" +msgstr "Podgląd bez wykonywania wektoryzacji dla całego obrazu" + +#. #### swap black and white #### +#: ../../po/../src/ui/dialog/tracedialog.cpp:495 +msgid "Invert" +msgstr "Negatyw" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:499 +msgid "Invert black and white regions for single traces" +msgstr "Zamiana białego i czarnego koloru przy wektoryzacji jednoprzebiegowej" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:503 +msgid "Thanks to Peter Selinger, http://potrace.sourceforge.net" +msgstr "Peter Selinger, http://potrace.sourceforge.net" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:506 +msgid "Credits" +msgstr "Podziękowania" + +#. done +#. TRANSLATORS: Potrace is an application for transforming bitmaps into +#. vector graphics (http://potrace.sourceforge.net/) +#: ../../po/../src/ui/dialog/tracedialog.cpp:514 +msgid "Potrace" +msgstr "Potrace" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:527 +msgid "Abort a trace in progress" +msgstr "Przerwij wektoryzację" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:531 +msgid "Execute the trace" +msgstr "Wykonaj wektoryzację" + +#: ../../po/../src/ui/dialog/transformation.cpp:80 +#: ../../po/../src/ui/dialog/transformation.cpp:90 +#, fuzzy +msgid "_Horizontal" +msgstr "Poziomo" + +#: ../../po/../src/ui/dialog/transformation.cpp:80 +msgid "Horizontal displacement (relative) or position (absolute)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:82 +#: ../../po/../src/ui/dialog/transformation.cpp:92 +#, fuzzy +msgid "_Vertical" +msgstr "Pionowo" + +#: ../../po/../src/ui/dialog/transformation.cpp:82 +msgid "Vertical displacement (relative) or position (absolute)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:84 +#, fuzzy +msgid "_Width" +msgstr "_Szerokość:" + +#: ../../po/../src/ui/dialog/transformation.cpp:84 +msgid "Horizontal size increment (absolute or percentage)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:86 +#, fuzzy +msgid "_Height" +msgstr "Wysokość" + +#: ../../po/../src/ui/dialog/transformation.cpp:86 +msgid "Vertical size increment (absolute or percentage)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:88 +#, fuzzy +msgid "A_ngle" +msgstr "Kąt:" + +#: ../../po/../src/ui/dialog/transformation.cpp:88 +#, fuzzy +msgid "Rotation angle (positive = counterclockwise)" +msgstr "" +"Obraca zaznaczone obiekty o 90 stopni przeciwnie do ruchu wskazówek zegara" + +#: ../../po/../src/ui/dialog/transformation.cpp:90 +msgid "" +"Horizontal skew angle (positive = counterclockwise), or absolute " +"displacement, or percentage displacement" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:92 +msgid "" +"Vertical skew angle (positive = counterclockwise), or absolute displacement, " +"or percentage displacement" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:95 +#, fuzzy +msgid "Transformation matrix element A" +msgstr "Macierz przekształcenia" + +#: ../../po/../src/ui/dialog/transformation.cpp:96 +#, fuzzy +msgid "Transformation matrix element B" +msgstr "Macierz przekształcenia" + +#: ../../po/../src/ui/dialog/transformation.cpp:97 +#, fuzzy +msgid "Transformation matrix element C" +msgstr "Macierz przekształcenia" + +#: ../../po/../src/ui/dialog/transformation.cpp:98 +#, fuzzy +msgid "Transformation matrix element D" +msgstr "Macierz przekształcenia" + +#: ../../po/../src/ui/dialog/transformation.cpp:99 +#, fuzzy +msgid "Transformation matrix element E" +msgstr "Macierz przekształcenia" + +#: ../../po/../src/ui/dialog/transformation.cpp:100 +#, fuzzy +msgid "Transformation matrix element F" +msgstr "Macierz przekształcenia" + +#: ../../po/../src/ui/dialog/transformation.cpp:102 +#, fuzzy +msgid "Rela_tive move" +msgstr "Przesunięcie względne" + +#: ../../po/../src/ui/dialog/transformation.cpp:102 +msgid "" +"Add the specified relative displacement to the current position; otherwise, " +"edit the current absolute position directly" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:103 +msgid "Scale proportionally" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:103 +msgid "Preserve the width/height ratio of the scaled objects" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:104 +msgid "Apply to each _object separately" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:104 +msgid "" +"Apply the scale/rotate/skew to each selected object separately; otherwise, " +"transform the selection as a whole" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:105 +#, fuzzy +msgid "Edit c_urrent matrix" +msgstr "Przesuwa aktywną warstwę o jedną pozycję wyżej" + +#: ../../po/../src/ui/dialog/transformation.cpp:105 +msgid "" +"Edit the current transform= matrix; otherwise, post-multiply transform= by " +"this matrix" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:115 +#, fuzzy +msgid "_Move" +msgstr "Przesunięcie" + +# [cyba] - niejednoznaczność +# w icons/sodipodi.glade powinno być "Skala" +# w icons/transformation.glade.h powinno być "Skalowanie" +#: ../../po/../src/ui/dialog/transformation.cpp:118 +#, fuzzy +msgid "_Scale" +msgstr "Skalowanie" + +#: ../../po/../src/ui/dialog/transformation.cpp:121 +#, fuzzy +msgid "_Rotate" +msgstr "Obrót" + +#: ../../po/../src/ui/dialog/transformation.cpp:124 +#, fuzzy +msgid "Ske_w" +msgstr "Skręcenie" + +#: ../../po/../src/ui/dialog/transformation.cpp:127 +msgid "Matri_x" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:141 +msgid "Reset the values on the current tab to defaults" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:148 +#, fuzzy +msgid "Apply transformation to selection" +msgstr "Zastosuj przekształcenie do obiektu" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:43 +msgid "_Use SSL" +msgstr "_Użyj SSL" + +#. Construct dialog interface +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:68 +msgid "_Server:" +msgstr "_Serwer" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:69 +msgid "_Username:" +msgstr "_Nazwa użytkownika:" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:70 +msgid "_Password:" +msgstr "_Hasło:" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:71 +msgid "P_ort:" +msgstr "_Port:" + +#. Buttons +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:99 +msgid "Connect" +msgstr "Połącz" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:126 +msgid "Establishing connection to Jabber server %1 as user %2" +msgstr "Połącz się z serwerem Jabbera %1 jako użytkownik %2" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:131 +msgid "Failed to establish connection to Jabber server %1" +msgstr "Nie udało się połączyć z serwerem Jabbera %1" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:136 +msgid "Authentication failed on Jabber server %1 as %2" +msgstr "" +"Autoryzacja użytkownika %2 na serwerze Jabbera %1 nie powiodła " +"się" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:141 +msgid "SSL initialization failed when connecting to Jabber server %1" +msgstr "" +"Nie powiodła się inicjalizacja SSL podczas próby połączenia z serwerem " +"Jabbera %1" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:147 +msgid "Connected to Jabber server %1 as %2" +msgstr "Połączono z serwerem Jabbera %1 jako %2" + +#. Construct labels +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:75 +msgid "Chatroom _name:" +msgstr "Nazwa _pokoju:" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:76 +msgid "Chatroom _server:" +msgstr "_Serwer pokoju:" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:77 +msgid "Chatroom _password:" +msgstr "_Hasło pokoju:" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:78 +msgid "Chatroom _handle:" +msgstr "_Identyfikator pokoju:" + +#. Button setup and callback registration +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:97 +msgid "Connect to chatroom" +msgstr "Połącz się z pokojem" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:132 +msgid "Synchronizing with chatroom %1@%2 using the handle %3" +msgstr "" +"Synchronizacja z pokojem %1@%2, wykorzystanie identyfikatora %3" + +#. Construct dialog interface +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:78 +msgid "_User's Jabber ID:" +msgstr "_ID użytkownika Jabbera:" + +#. Buttons +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:82 +msgid "_Invite user" +msgstr "_Zaproś użytkownika" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:83 +msgid "_Cancel" +msgstr "_Anuluj" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:94 +msgid "Buddy List" +msgstr "Lista znajomych" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:170 +msgid "Sending whiteboard invitation to %1" +msgstr "Wysyłanie zaproszenia do wspólnej pracy na planszy do %1" + +#. FIXME: strings are replaced by placeholders, NOT to be translated until the code is enabled +#. See http://sourceforge.net/mailarchive/message.php?msg_id=11746016 for details +#. File menu +#. Edit menu +#. View menu +#. Layer menu +#. Object menu +#. Path menu +#. add(Gtk::StockItem(CLEANUP, _("PLACEHOLDER, do not translate"))); (using Gtk::Stock::CLEAR) +#. Text menu +#. About menu +#. Tools toolbox +#. Select Tool controls +#. Node Tool controls +#. Calligraphy Tool controls +#. Session playback controls +#: ../../po/../src/ui/stock-items.cpp:34 ../../po/../src/ui/stock-items.cpp:35 +#: ../../po/../src/ui/stock-items.cpp:36 ../../po/../src/ui/stock-items.cpp:37 +#: ../../po/../src/ui/stock-items.cpp:38 ../../po/../src/ui/stock-items.cpp:39 +#: ../../po/../src/ui/stock-items.cpp:40 ../../po/../src/ui/stock-items.cpp:41 +#: ../../po/../src/ui/stock-items.cpp:42 ../../po/../src/ui/stock-items.cpp:43 +#: ../../po/../src/ui/stock-items.cpp:46 ../../po/../src/ui/stock-items.cpp:47 +#: ../../po/../src/ui/stock-items.cpp:48 ../../po/../src/ui/stock-items.cpp:49 +#: ../../po/../src/ui/stock-items.cpp:50 ../../po/../src/ui/stock-items.cpp:51 +#: ../../po/../src/ui/stock-items.cpp:52 ../../po/../src/ui/stock-items.cpp:53 +#: ../../po/../src/ui/stock-items.cpp:54 ../../po/../src/ui/stock-items.cpp:55 +#: ../../po/../src/ui/stock-items.cpp:56 ../../po/../src/ui/stock-items.cpp:57 +#: ../../po/../src/ui/stock-items.cpp:58 ../../po/../src/ui/stock-items.cpp:59 +#: ../../po/../src/ui/stock-items.cpp:62 ../../po/../src/ui/stock-items.cpp:63 +#: ../../po/../src/ui/stock-items.cpp:64 ../../po/../src/ui/stock-items.cpp:65 +#: ../../po/../src/ui/stock-items.cpp:66 ../../po/../src/ui/stock-items.cpp:67 +#: ../../po/../src/ui/stock-items.cpp:68 ../../po/../src/ui/stock-items.cpp:69 +#: ../../po/../src/ui/stock-items.cpp:70 ../../po/../src/ui/stock-items.cpp:71 +#: ../../po/../src/ui/stock-items.cpp:72 ../../po/../src/ui/stock-items.cpp:73 +#: ../../po/../src/ui/stock-items.cpp:74 ../../po/../src/ui/stock-items.cpp:75 +#: ../../po/../src/ui/stock-items.cpp:76 ../../po/../src/ui/stock-items.cpp:77 +#: ../../po/../src/ui/stock-items.cpp:78 ../../po/../src/ui/stock-items.cpp:79 +#: ../../po/../src/ui/stock-items.cpp:80 ../../po/../src/ui/stock-items.cpp:81 +#: ../../po/../src/ui/stock-items.cpp:82 ../../po/../src/ui/stock-items.cpp:83 +#: ../../po/../src/ui/stock-items.cpp:84 ../../po/../src/ui/stock-items.cpp:85 +#: ../../po/../src/ui/stock-items.cpp:86 ../../po/../src/ui/stock-items.cpp:87 +#: ../../po/../src/ui/stock-items.cpp:88 ../../po/../src/ui/stock-items.cpp:89 +#: ../../po/../src/ui/stock-items.cpp:92 ../../po/../src/ui/stock-items.cpp:93 +#: ../../po/../src/ui/stock-items.cpp:94 ../../po/../src/ui/stock-items.cpp:95 +#: ../../po/../src/ui/stock-items.cpp:96 ../../po/../src/ui/stock-items.cpp:97 +#: ../../po/../src/ui/stock-items.cpp:98 ../../po/../src/ui/stock-items.cpp:99 +#: ../../po/../src/ui/stock-items.cpp:100 +#: ../../po/../src/ui/stock-items.cpp:101 +#: ../../po/../src/ui/stock-items.cpp:102 +#: ../../po/../src/ui/stock-items.cpp:103 +#: ../../po/../src/ui/stock-items.cpp:104 +#: ../../po/../src/ui/stock-items.cpp:105 +#: ../../po/../src/ui/stock-items.cpp:108 +#: ../../po/../src/ui/stock-items.cpp:109 +#: ../../po/../src/ui/stock-items.cpp:110 +#: ../../po/../src/ui/stock-items.cpp:111 +#: ../../po/../src/ui/stock-items.cpp:112 +#: ../../po/../src/ui/stock-items.cpp:113 +#: ../../po/../src/ui/stock-items.cpp:114 +#: ../../po/../src/ui/stock-items.cpp:115 +#: ../../po/../src/ui/stock-items.cpp:116 +#: ../../po/../src/ui/stock-items.cpp:117 +#: ../../po/../src/ui/stock-items.cpp:118 +#: ../../po/../src/ui/stock-items.cpp:119 +#: ../../po/../src/ui/stock-items.cpp:120 +#: ../../po/../src/ui/stock-items.cpp:121 +#: ../../po/../src/ui/stock-items.cpp:122 +#: ../../po/../src/ui/stock-items.cpp:123 +#: ../../po/../src/ui/stock-items.cpp:124 +#: ../../po/../src/ui/stock-items.cpp:125 +#: ../../po/../src/ui/stock-items.cpp:126 +#: ../../po/../src/ui/stock-items.cpp:127 +#: ../../po/../src/ui/stock-items.cpp:130 +#: ../../po/../src/ui/stock-items.cpp:131 +#: ../../po/../src/ui/stock-items.cpp:132 +#: ../../po/../src/ui/stock-items.cpp:133 +#: ../../po/../src/ui/stock-items.cpp:134 +#: ../../po/../src/ui/stock-items.cpp:135 +#: ../../po/../src/ui/stock-items.cpp:136 +#: ../../po/../src/ui/stock-items.cpp:137 +#: ../../po/../src/ui/stock-items.cpp:138 +#: ../../po/../src/ui/stock-items.cpp:139 +#: ../../po/../src/ui/stock-items.cpp:140 +#: ../../po/../src/ui/stock-items.cpp:141 +#: ../../po/../src/ui/stock-items.cpp:142 +#: ../../po/../src/ui/stock-items.cpp:143 +#: ../../po/../src/ui/stock-items.cpp:144 +#: ../../po/../src/ui/stock-items.cpp:145 +#: ../../po/../src/ui/stock-items.cpp:146 +#: ../../po/../src/ui/stock-items.cpp:150 +#: ../../po/../src/ui/stock-items.cpp:151 +#: ../../po/../src/ui/stock-items.cpp:152 +#: ../../po/../src/ui/stock-items.cpp:153 +#: ../../po/../src/ui/stock-items.cpp:156 +#: ../../po/../src/ui/stock-items.cpp:157 +#: ../../po/../src/ui/stock-items.cpp:158 +#: ../../po/../src/ui/stock-items.cpp:161 +#: ../../po/../src/ui/stock-items.cpp:162 +#: ../../po/../src/ui/stock-items.cpp:163 +#: ../../po/../src/ui/stock-items.cpp:164 +#: ../../po/../src/ui/stock-items.cpp:165 +#: ../../po/../src/ui/stock-items.cpp:166 +#: ../../po/../src/ui/stock-items.cpp:167 +#: ../../po/../src/ui/stock-items.cpp:168 +#: ../../po/../src/ui/stock-items.cpp:169 +#: ../../po/../src/ui/stock-items.cpp:170 +#: ../../po/../src/ui/stock-items.cpp:171 +#: ../../po/../src/ui/stock-items.cpp:172 +#: ../../po/../src/ui/stock-items.cpp:175 +#: ../../po/../src/ui/stock-items.cpp:176 +#: ../../po/../src/ui/stock-items.cpp:177 +#: ../../po/../src/ui/stock-items.cpp:178 +#: ../../po/../src/ui/stock-items.cpp:181 +#: ../../po/../src/ui/stock-items.cpp:182 +#: ../../po/../src/ui/stock-items.cpp:183 +#: ../../po/../src/ui/stock-items.cpp:184 +#: ../../po/../src/ui/stock-items.cpp:185 +#: ../../po/../src/ui/stock-items.cpp:186 +#: ../../po/../src/ui/stock-items.cpp:187 +#: ../../po/../src/ui/stock-items.cpp:188 +#: ../../po/../src/ui/stock-items.cpp:189 +#: ../../po/../src/ui/stock-items.cpp:190 +#: ../../po/../src/ui/stock-items.cpp:191 +#: ../../po/../src/ui/stock-items.cpp:194 +#: ../../po/../src/ui/stock-items.cpp:195 +#: ../../po/../src/ui/stock-items.cpp:198 +#: ../../po/../src/ui/stock-items.cpp:199 +#: ../../po/../src/ui/stock-items.cpp:200 +#: ../../po/../src/ui/stock-items.cpp:201 +#: ../../po/../src/ui/stock-items.cpp:202 +msgid "PLACEHOLDER, do not translate" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:88 +msgid "small" +msgstr "mały" + +#: ../../po/../src/ui/widget/panel.cpp:89 +msgid "medium" +msgstr "średni" + +#: ../../po/../src/ui/widget/panel.cpp:90 +msgid "large" +msgstr "duży" + +#: ../../po/../src/ui/widget/panel.cpp:91 +msgid "huge" +msgstr "wielki" + +#: ../../po/../src/ui/widget/panel.cpp:106 +msgid "List" +msgstr "Lista" + +#: ../../po/../src/ui/widget/selected-style.cpp:67 +msgid "F:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:68 +msgid "S:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:69 +msgid "O:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:95 +msgid "N/A" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:98 +#: ../../po/../src/ui/widget/selected-style.cpp:712 +#, fuzzy +msgid "Nothing selected" +msgstr "Zaznaczono klon obiektu" + +#: ../../po/../src/ui/widget/selected-style.cpp:103 +msgid "No fill" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:103 +#, fuzzy +msgid "No stroke" +msgstr "(kontur)" + +#: ../../po/../src/ui/widget/selected-style.cpp:105 +#: ../../po/../src/widgets/paint-selector.cpp:190 +msgid "Pattern" +msgstr "Deseń" + +#: ../../po/../src/ui/widget/selected-style.cpp:108 +#: ../../po/../src/widgets/paint-selector.cpp:885 +msgid "Pattern fill" +msgstr "Deseń" + +#: ../../po/../src/ui/widget/selected-style.cpp:108 +#, fuzzy +msgid "Pattern stroke" +msgstr "Przesunięcie wzoru" + +#: ../../po/../src/ui/widget/selected-style.cpp:110 +#, fuzzy +msgid "L Gradient" +msgstr "Gradient" + +#: ../../po/../src/ui/widget/selected-style.cpp:113 +#, fuzzy +msgid "Linear gradient fill" +msgstr "Gradient liniowy" + +#: ../../po/../src/ui/widget/selected-style.cpp:113 +#, fuzzy +msgid "Linear gradient stroke" +msgstr "Gradient liniowy" + +#: ../../po/../src/ui/widget/selected-style.cpp:115 +#, fuzzy +msgid "R Gradient" +msgstr "Gradient" + +#: ../../po/../src/ui/widget/selected-style.cpp:118 +#, fuzzy +msgid "Radial gradient fill" +msgstr "Gradient koncentryczny" + +#: ../../po/../src/ui/widget/selected-style.cpp:118 +#, fuzzy +msgid "Radial gradient stroke" +msgstr "Gradient koncentryczny" + +#: ../../po/../src/ui/widget/selected-style.cpp:120 +#, fuzzy +msgid "Different" +msgstr "_Różnica" + +#: ../../po/../src/ui/widget/selected-style.cpp:123 +#, fuzzy +msgid "Different fills" +msgstr "_Różnica" + +#: ../../po/../src/ui/widget/selected-style.cpp:123 +#, fuzzy +msgid "Different strokes" +msgstr "_Różnica" + +#: ../../po/../src/ui/widget/selected-style.cpp:125 +#, fuzzy +msgid "Unset" +msgstr "do wewnątrz" + +#. TRANSLATORS COMMENT: unset is a verb here +#: ../../po/../src/ui/widget/selected-style.cpp:128 +#: ../../po/../src/ui/widget/selected-style.cpp:182 +#, fuzzy +msgid "Unset fill" +msgstr "Jednostka" + +#: ../../po/../src/ui/widget/selected-style.cpp:128 +#: ../../po/../src/ui/widget/selected-style.cpp:182 +#, fuzzy +msgid "Unset stroke" +msgstr "(kontur)" + +#: ../../po/../src/ui/widget/selected-style.cpp:131 +#, fuzzy +msgid "Flat color fill" +msgstr "Jednolity kolor" + +#: ../../po/../src/ui/widget/selected-style.cpp:131 +#, fuzzy +msgid "Flat color stroke" +msgstr "Jednolity kolor" + +#. TRANSLATOR COMMENT: A means "Averaged" +#: ../../po/../src/ui/widget/selected-style.cpp:134 +#, fuzzy +msgid "A" +msgstr "_A" + +#: ../../po/../src/ui/widget/selected-style.cpp:137 +#, fuzzy +msgid "Fill is averaged over selected objects" +msgstr "" +"Różnica symetryczna wybranych obiektów (obszary nakładające się zostają " +"usunięte)" + +#: ../../po/../src/ui/widget/selected-style.cpp:137 +#, fuzzy +msgid "Stroke is averaged over selected objects" +msgstr "Omijanie zaznaczonych obiektów przez łączniki" + +#. TRANSLATOR COMMENT: M means "Multiple" +#: ../../po/../src/ui/widget/selected-style.cpp:140 +#, fuzzy +msgid "M" +msgstr "_M" + +#: ../../po/../src/ui/widget/selected-style.cpp:143 +#, fuzzy +msgid "Multiple selected objects have the same fill" +msgstr "Wyrównanie wybranych węzłów w pionie" + +#: ../../po/../src/ui/widget/selected-style.cpp:143 +#, fuzzy +msgid "Multiple selected objects have the same stroke" +msgstr "Wyrównanie wybranych węzłów w pionie" + +#: ../../po/../src/ui/widget/selected-style.cpp:145 +#, fuzzy +msgid "Edit fill..." +msgstr "Edytuj..." + +#: ../../po/../src/ui/widget/selected-style.cpp:145 +#, fuzzy +msgid "Edit stroke..." +msgstr "Edytuj..." + +#: ../../po/../src/ui/widget/selected-style.cpp:149 +#, fuzzy +msgid "Last set color" +msgstr "Jednolity kolor" + +#: ../../po/../src/ui/widget/selected-style.cpp:153 +#, fuzzy +msgid "Last selected color" +msgstr "Ostatni zaznaczony" + +#: ../../po/../src/ui/widget/selected-style.cpp:157 +#, fuzzy +msgid "White" +msgstr "Plansza robocza" + +#: ../../po/../src/ui/widget/selected-style.cpp:161 +#: ../../po/../src/widgets/sp-color-scales.cpp:461 +#: ../../po/../src/widgets/sp-color-scales.cpp:462 +msgid "Black" +msgstr "Czarny" + +#: ../../po/../src/ui/widget/selected-style.cpp:165 +#, fuzzy +msgid "Copy color" +msgstr "Kolor w punkcie" + +#: ../../po/../src/ui/widget/selected-style.cpp:169 +#, fuzzy +msgid "Paste color" +msgstr "Jednolity kolor" + +#: ../../po/../src/ui/widget/selected-style.cpp:173 +#, fuzzy +msgid "Swap fill and stroke" +msgstr "Wypełnienie i _kontur" + +#: ../../po/../src/ui/widget/selected-style.cpp:177 +msgid "Make fill opaque" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:177 +msgid "Make stroke opaque" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:186 +#, fuzzy +msgid "Remove fill" +msgstr "U_suń " + +#: ../../po/../src/ui/widget/selected-style.cpp:186 +#, fuzzy +msgid "Remove stroke" +msgstr "Usuń odnośnik" + +#: ../../po/../src/ui/widget/selected-style.cpp:718 +#, fuzzy +msgid "Master opacity" +msgstr "_Ogólna nieprzepuszczalność" + +#: ../../po/../src/ui/widget/selected-style.cpp:744 +msgid "0 (transparent)" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:768 +msgid "1.0 (opaque)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1046 +msgid "Moved to next layer." +msgstr "Przeniesiono do następnej warstwy." + +#: ../../po/../src/verbs.cpp:1048 +#, fuzzy +msgid "Cannot move past last layer." +msgstr "Nie można przenieść poza ostatnią warstwę." + +#: ../../po/../src/verbs.cpp:1057 +msgid "Moved to previous layer." +msgstr "Przeniesiono do poprzedniej warstwy." + +#: ../../po/../src/verbs.cpp:1059 +#, fuzzy +msgid "Cannot move past first layer." +msgstr "Nie można przenieść przed pierwszą warstwę." + +#: ../../po/../src/verbs.cpp:1076 ../../po/../src/verbs.cpp:1150 +msgid "No current layer." +msgstr "Brak aktywnej warstwy." + +#: ../../po/../src/verbs.cpp:1105 +#, c-format +msgid "Raised layer %s." +msgstr "Warstwa %s przeniesiona wyżej." + +#: ../../po/../src/verbs.cpp:1109 +#, c-format +msgid "Lowered layer %s." +msgstr "Warstwa %s przeniesiona niżej." + +#: ../../po/../src/verbs.cpp:1118 +#, fuzzy +msgid "Cannot move layer any further." +msgstr "Nie można przenieść warstwy dalej." + +#. TRANSLATORS: this means "The layer has been deleted." +#: ../../po/../src/verbs.cpp:1148 +msgid "Deleted layer." +msgstr "Warstwa usunięta." + +#: ../../po/../src/verbs.cpp:1544 +msgid "" +"You need to connect to a Jabber server before sharing a document with " +"another user." +msgstr "" +"Musisz najpierw połączyć się z serwerem Jabbera zanim zaczniesz współdzielić " +"dokument z innym użytkownikiem." + +#: ../../po/../src/verbs.cpp:1559 +msgid "" +"You need to connect to a Jabber server before sharing a document with a " +"chatroom." +msgstr "" +"Musisz najpierw połączyć się z serwerem Jabbera zanim zaczniesz współdzielić " +"dokument z pokojem." + +#: ../../po/../src/verbs.cpp:1569 +msgid "XML node tracker has not been initialized; nothing to dump" +msgstr "" +"Śledzenie węzłów XML nie zostało zainicjalizowane; brak informacji do " +"wyświetlenia" + +#. TRANSLATORS: If you have translated the keys.svg file to your language, then +#. translate this string as "keys.LANG.svg" (where LANG is your language code); +#. otherwise leave as "keys.svg". +#: ../../po/../src/verbs.cpp:1631 +msgid "keys.svg" +msgstr "" + +#. TRANSLATORS: If you have translated the tutorial-basic.svg file to your language, +#. then translate this string as "tutorial-basic.LANG.svg" (where LANG is your language +#. code); otherwise leave as "tutorial-basic.svg". +#: ../../po/../src/verbs.cpp:1667 +msgid "tutorial-basic.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1671 +msgid "tutorial-shapes.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1675 +msgid "tutorial-advanced.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1679 +msgid "tutorial-tracing.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1683 +msgid "tutorial-calligraphy.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1687 +msgid "tutorial-elements.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1691 +msgid "tutorial-tips.svg" +msgstr "" + +#: ../../po/../src/verbs.cpp:1842 +msgid "Does nothing" +msgstr "Nic nie wykonuje" + +#. File +#: ../../po/../src/verbs.cpp:1845 +msgid "Default" +msgstr "Domyślny" + +#: ../../po/../src/verbs.cpp:1845 +msgid "Create new document from default template" +msgstr "Tworzy nowy dokument na bazie domyślnego szablonu" + +#: ../../po/../src/verbs.cpp:1847 +msgid "_Open..." +msgstr "_Otwórz..." + +#: ../../po/../src/verbs.cpp:1848 +msgid "Open existing document" +msgstr "Otwiera istniejący dokument" + +#: ../../po/../src/verbs.cpp:1849 +msgid "Re_vert" +msgstr "_Przywróć" + +#: ../../po/../src/verbs.cpp:1850 +msgid "Revert to the last saved version of document (changes will be lost)" +msgstr "Przywraca ostatnio zapisaną wersję dokumentu (zmiany zostaną utracone)" + +#: ../../po/../src/verbs.cpp:1851 +msgid "_Save" +msgstr "_Zapisz" + +#: ../../po/../src/verbs.cpp:1851 +msgid "Save document" +msgstr "Zapisuje dokument" + +#: ../../po/../src/verbs.cpp:1853 +msgid "Save _As..." +msgstr "Z_apisz jako..." + +#: ../../po/../src/verbs.cpp:1854 +msgid "Save document under new name" +msgstr "Zapisuje dokument pod nową nazwą" + +#: ../../po/../src/verbs.cpp:1855 +msgid "_Print..." +msgstr "_Drukuj..." + +#: ../../po/../src/verbs.cpp:1855 +msgid "Print document" +msgstr "Drukuje dokument" + +#. TRANSLATORS: "Vacuum Defs" means "Clean up defs" (so as to remove unused definitions) +#: ../../po/../src/verbs.cpp:1858 +msgid "Vac_uum Defs" +msgstr "_Wyczyść definicje" + +#: ../../po/../src/verbs.cpp:1858 +#, fuzzy +msgid "Remove unused predefined items from the <defs> of the document" +msgstr "Usuwa nieużywane elementy z <defs> dokumentu" + +#: ../../po/../src/verbs.cpp:1860 +msgid "Print _Direct" +msgstr "Drukuj _bezpośrednio..." + +#: ../../po/../src/verbs.cpp:1861 +#, fuzzy +msgid "Print directly without prompting to a file or pipe" +msgstr "Drukuje bezpośrednio do pliku lub potoku" + +#: ../../po/../src/verbs.cpp:1862 +msgid "Print Previe_w" +msgstr "Podgląd _wydruku" + +#: ../../po/../src/verbs.cpp:1863 +msgid "Preview document printout" +msgstr "Wyświetla podgląd wydruku rysunku" + +#: ../../po/../src/verbs.cpp:1864 +msgid "_Import..." +msgstr "_Importuj" + +#: ../../po/../src/verbs.cpp:1865 +msgid "Import bitmap or SVG image into document" +msgstr "Importuje bitmapę lub rysunek SVG do dokumentu" + +#: ../../po/../src/verbs.cpp:1866 +msgid "_Export Bitmap..." +msgstr "_Eksportuj bitmapę..." + +#: ../../po/../src/verbs.cpp:1867 +#, fuzzy +msgid "Export document or selection as a bitmap image" +msgstr "Eksportuje dokument lub obszar zaznaczenia do bitmapy PNG" + +#: ../../po/../src/verbs.cpp:1868 +msgid "N_ext Window" +msgstr "Następne okno" + +#: ../../po/../src/verbs.cpp:1869 +msgid "Switch to the next document window" +msgstr "Przełącza do okna następnego dokumentu" + +#: ../../po/../src/verbs.cpp:1870 +msgid "P_revious Window" +msgstr "Poprzednie okno" + +#: ../../po/../src/verbs.cpp:1871 +msgid "Switch to the previous document window" +msgstr "Przełącza do okna poprzedniego dokumentu" + +#: ../../po/../src/verbs.cpp:1872 +msgid "_Close" +msgstr "Za_mknij" + +#: ../../po/../src/verbs.cpp:1873 +msgid "Close window" +msgstr "Zamyka okno bieżącego dokumentu" + +#: ../../po/../src/verbs.cpp:1874 +msgid "_Quit" +msgstr "Za_kończ" + +#: ../../po/../src/verbs.cpp:1874 +msgid "Quit Inkscape" +msgstr "Kończy działanie programu Inkscape" + +#. Edit +#: ../../po/../src/verbs.cpp:1877 +msgid "_Undo" +msgstr "_Cofnij" + +#: ../../po/../src/verbs.cpp:1877 +msgid "Undo last action" +msgstr "Cofa ostatnio wykonaną operację" + +#: ../../po/../src/verbs.cpp:1879 +msgid "_Redo" +msgstr "_Przywróć" + +#: ../../po/../src/verbs.cpp:1880 +msgid "Do again last undone action" +msgstr "Przywraca ostatnio cofniętą operację" + +#: ../../po/../src/verbs.cpp:1881 +msgid "Cu_t" +msgstr "Wy_tnij" + +#: ../../po/../src/verbs.cpp:1882 +msgid "Cut selection to clipboard" +msgstr "Wycina zaznaczone obiekty do schowka" + +#: ../../po/../src/verbs.cpp:1883 +msgid "_Copy" +msgstr "_Kopiuj" + +#: ../../po/../src/verbs.cpp:1884 +msgid "Copy selection to clipboard" +msgstr "Kopiuje zaznaczone obiekty do schowka" + +#: ../../po/../src/verbs.cpp:1885 +msgid "_Paste" +msgstr "_Wklej" + +#: ../../po/../src/verbs.cpp:1886 +#, fuzzy +msgid "Paste objects from clipboard to mouse point" +msgstr "Wkleja obiekty ze schowka na pozycji kursora myszy" + +#: ../../po/../src/verbs.cpp:1887 +msgid "Paste _Style" +msgstr "Wklej _styl" + +#: ../../po/../src/verbs.cpp:1888 +msgid "Apply style of the copied object to selection" +msgstr "Przypisuje zaznaczonym obiektom styl ze schowka" + +#: ../../po/../src/verbs.cpp:1889 +msgid "Paste _In Place" +msgstr "Wklej na _miejscu" + +#: ../../po/../src/verbs.cpp:1890 +#, fuzzy +msgid "Paste objects from clipboard to the original location" +msgstr "Wkleja obiekty ze schowka na oryginalną pozycję" + +#: ../../po/../src/verbs.cpp:1891 +msgid "_Delete" +msgstr "_Usuń" + +#: ../../po/../src/verbs.cpp:1892 +msgid "Delete selection" +msgstr "Usuwa zaznaczone obiekty" + +#: ../../po/../src/verbs.cpp:1893 +msgid "Duplic_ate" +msgstr "_Duplikuj" + +#: ../../po/../src/verbs.cpp:1894 +#, fuzzy +msgid "Duplicate selected objects" +msgstr "Duplikuje zaznaczone obiekty" + +#: ../../po/../src/verbs.cpp:1895 +msgid "Clo_ne" +msgstr "K_lonuj" + +#: ../../po/../src/verbs.cpp:1896 +msgid "Create a clone of selected object (a copy linked to the original)" +msgstr "Tworzy klon zaznaczonego obiektu (kopia połączona z oryginałem)" + +#: ../../po/../src/verbs.cpp:1897 +msgid "Unlin_k Clone" +msgstr "_Odłącz klon" + +#: ../../po/../src/verbs.cpp:1898 +msgid "Cut the clone's link to its original" +msgstr "Usuwa połącznie klonu z jego oryginalnym obiektem" + +#: ../../po/../src/verbs.cpp:1899 +msgid "Select _Original" +msgstr "Zaznacz ory_ginał" + +#: ../../po/../src/verbs.cpp:1900 +msgid "Select the object to which the clone is linked" +msgstr "Zaznacza oryginalny obiekt, z którym połączony jest klon" + +#. TRANSLATORS: Convert selection to a rectangle with tiled pattern fill +#: ../../po/../src/verbs.cpp:1902 +#, fuzzy +msgid "O_bjects to Pattern" +msgstr "Obiekt(y) _na deseń" + +#: ../../po/../src/verbs.cpp:1903 +msgid "Convert selection to a rectangle with tiled pattern fill" +msgstr "Zamienia zaznaczone obiekty w prostokąt z kafelką wzoru" + +#. TRANSLATORS: Extract objects from a tiled pattern fill +#: ../../po/../src/verbs.cpp:1905 +#, fuzzy +msgid "Pattern to Ob_jects" +msgstr "Deseń na ob_iekt(y)" + +#: ../../po/../src/verbs.cpp:1906 +msgid "Extract objects from a tiled pattern fill" +msgstr "Wyodrębnia obiekty z deseniu" + +#: ../../po/../src/verbs.cpp:1907 +msgid "Clea_r All" +msgstr "Wyczyść wszystko" + +#: ../../po/../src/verbs.cpp:1908 +msgid "Delete all objects from document" +msgstr "Usuwa wszystkie obiekty z dokumentu" + +#: ../../po/../src/verbs.cpp:1909 +msgid "Select Al_l" +msgstr "Z_aznacz wszystko" + +#: ../../po/../src/verbs.cpp:1910 +msgid "Select all objects or all nodes" +msgstr "Zaznacza wszystkie obiekty lub węzły" + +#: ../../po/../src/verbs.cpp:1911 +msgid "Select All in All La_yers" +msgstr "Zaznacz wszystko na wszystkich warstwach" + +#: ../../po/../src/verbs.cpp:1912 +msgid "Select all objects in all visible and unlocked layers" +msgstr "" +"Zaznacza wszystkie obiekty na wszystkich widocznych i odblokowanych warstwach" + +#: ../../po/../src/verbs.cpp:1913 +msgid "In_vert Selection" +msgstr "Odwróć zaznaczenie" + +#: ../../po/../src/verbs.cpp:1914 +msgid "Invert selection (unselect what is selected and select everything else)" +msgstr "Odwraca zaznaczenie (odznacza zaznaczone obiekty i zaznacza pozostałe)" + +#: ../../po/../src/verbs.cpp:1915 +msgid "Invert in All Layers" +msgstr "Odwróć na wszystkich warstwach" + +#: ../../po/../src/verbs.cpp:1916 +msgid "Invert selection in all visible and unlocked layers" +msgstr "Odwraca zaznaczenie na wszystkich widocznych i odblokowanych warstwach" + +#: ../../po/../src/verbs.cpp:1917 +msgid "D_eselect" +msgstr "Odznacz" + +#: ../../po/../src/verbs.cpp:1918 +msgid "Deselect any selected objects or nodes" +msgstr "Odznacza wszystkie zaznaczone obiekty lub węzły" + +#. Selection +#: ../../po/../src/verbs.cpp:1921 +msgid "Raise to _Top" +msgstr "Przenieś na _wierzch" + +#: ../../po/../src/verbs.cpp:1922 +msgid "Raise selection to top" +msgstr "Przenosi zaznaczone obiekty na wierzch" + +#: ../../po/../src/verbs.cpp:1923 +msgid "Lower to _Bottom" +msgstr "Przenieś pod _spód" + +#: ../../po/../src/verbs.cpp:1924 +msgid "Lower selection to bottom" +msgstr "Przenosi zaznaczone obiekty pod spód" + +#: ../../po/../src/verbs.cpp:1925 +msgid "_Raise" +msgstr "Przesuń do _przodu" + +#: ../../po/../src/verbs.cpp:1926 +msgid "Raise selection one step" +msgstr "Przesuwa zaznaczone obiekty o jedną pozycję do przodu" + +#: ../../po/../src/verbs.cpp:1927 +msgid "_Lower" +msgstr "Przesuń do _tyłu" + +#: ../../po/../src/verbs.cpp:1928 +msgid "Lower selection one step" +msgstr "Przesuwa zaznaczone obiekty o jedną pozycję do tyłu" + +#: ../../po/../src/verbs.cpp:1929 +msgid "_Group" +msgstr "_Grupuj" + +#: ../../po/../src/verbs.cpp:1930 +msgid "Group selected objects" +msgstr "Grupuje zaznaczone obiekty" + +#: ../../po/../src/verbs.cpp:1932 +#, fuzzy +msgid "Ungroup selected groups" +msgstr "Rozgrupowuje zaznaczone obiekty" + +#: ../../po/../src/verbs.cpp:1934 +msgid "_Put on Path" +msgstr "_Wstaw na ścieżkę" + +#: ../../po/../src/verbs.cpp:1935 +msgid "Put text on path" +msgstr "Wstawia tekst na ścieżkę" + +#: ../../po/../src/verbs.cpp:1936 +msgid "_Remove from Path" +msgstr "_Zdejmij ze ścieżki" + +#: ../../po/../src/verbs.cpp:1937 +msgid "Remove text from path" +msgstr "Zdejmuje tekst ze ścieżki" + +#: ../../po/../src/verbs.cpp:1938 +msgid "Remove Manual _Kerns" +msgstr "_Usuń ręczne podcięcie" + +#. TRANSLATORS: "glyph": An image used in the visual representation of characters; +#. roughly speaking, how a character looks. A font is a set of glyphs. +#: ../../po/../src/verbs.cpp:1941 +msgid "Remove all manual kerns and glyph rotations from a text object" +msgstr "Usuwa wprowadzone ręcznie podcięcie i obrót tekstu" + +#: ../../po/../src/verbs.cpp:1943 +msgid "_Union" +msgstr "_Suma" + +#: ../../po/../src/verbs.cpp:1944 +msgid "Union of selected objects" +msgstr "Łączy ze sobą zaznaczone obiekty" + +#: ../../po/../src/verbs.cpp:1945 +msgid "_Intersection" +msgstr "_Część wspólna" + +#: ../../po/../src/verbs.cpp:1946 +msgid "Intersection of selected objects" +msgstr "Pozostawia część wspólną zaznaczonych obiektów" + +#: ../../po/../src/verbs.cpp:1947 +msgid "_Difference" +msgstr "_Różnica" + +#: ../../po/../src/verbs.cpp:1948 +msgid "Difference of selected objects (bottom minus top)" +msgstr "Różnica zaznaczonych obiektów (dalszy odjąć bliższy)" + +#: ../../po/../src/verbs.cpp:1949 +msgid "E_xclusion" +msgstr "_Wykluczenie" + +#: ../../po/../src/verbs.cpp:1950 +msgid "Exclusive OR of selected objects" +msgstr "" +"Różnica symetryczna wybranych obiektów (obszary nakładające się zostają " +"usunięte)" + +#: ../../po/../src/verbs.cpp:1951 +msgid "Di_vision" +msgstr "_Podział" + +#: ../../po/../src/verbs.cpp:1952 +msgid "Cut the bottom object into pieces" +msgstr "Obiekt pod spodem zostaje rozcięty na części" + +#. TRANSLATORS: "to cut a path" is not the same as "to break a path apart" - see the +#. Advanced tutorial for more info +#: ../../po/../src/verbs.cpp:1955 +msgid "Cut _Path" +msgstr "Ro_zcięcie ścieżki" + +#: ../../po/../src/verbs.cpp:1956 +msgid "Cut the bottom object's stroke into pieces, removing fill" +msgstr "" +"Kontur obiektu pod spodem zostaje rozcięty na części z usunięciem wypełnienia" + +#. TRANSLATORS: "outset": expand a shape by offsetting the object's path, +#. i.e. by displacing it perpendicular to the path in each point. +#. See also the Advanced Tutorial for explanation. +#: ../../po/../src/verbs.cpp:1960 +msgid "Outs_et" +msgstr "Odsunięcie na zewnątrz" + +#: ../../po/../src/verbs.cpp:1961 +#, fuzzy +msgid "Outset selected paths" +msgstr "Odsuwa zaznaczone ścieżki na zewnątrz kształtu" + +#: ../../po/../src/verbs.cpp:1963 +msgid "O_utset Path by 1 px" +msgstr "Odsuń ścieżkę na zewnątrz o 1px" + +#: ../../po/../src/verbs.cpp:1964 +#, fuzzy +msgid "Outset selected paths by 1 px" +msgstr "Odsuwa zaznaczone ścieżki na zewnątrz kształtu o 1px" + +#: ../../po/../src/verbs.cpp:1966 +msgid "O_utset Path by 10 px" +msgstr "Odsuń ścieżkę na zewnątrz o 10px" + +#: ../../po/../src/verbs.cpp:1967 +#, fuzzy +msgid "Outset selected paths by 10 px" +msgstr "Odsuwa zaznaczone ścieżki na zewnątrz kształtu o 10px" + +#. TRANSLATORS: "inset": contract a shape by offsetting the object's path, +#. i.e. by displacing it perpendicular to the path in each point. +#. See also the Advanced Tutorial for explanation. +#: ../../po/../src/verbs.cpp:1971 +msgid "I_nset" +msgstr "Odsunięcie do wewnątrz" + +#: ../../po/../src/verbs.cpp:1972 +#, fuzzy +msgid "Inset selected paths" +msgstr "Odsuwa zaznaczone ścieżki do wewnątrz kształtu" + +#: ../../po/../src/verbs.cpp:1974 +msgid "I_nset Path by 1 px" +msgstr "Odsuń ścieżkę do wewnątrz o 1px" + +#: ../../po/../src/verbs.cpp:1975 +#, fuzzy +msgid "Inset selected paths by 1 px" +msgstr "Odsuwa zaznaczone ścieżki do wewnątrz kształtu o 1px" + +#: ../../po/../src/verbs.cpp:1977 +msgid "I_nset Path by 10 px" +msgstr "Odsuń ścieżkę do wewnątrz o 10px" + +#: ../../po/../src/verbs.cpp:1978 +#, fuzzy +msgid "Inset selected paths by 10 px" +msgstr "Odsuwa zaznaczone ścieżki do wewnątrz kształtu o 10px" + +#: ../../po/../src/verbs.cpp:1980 +msgid "D_ynamic Offset" +msgstr "Odsunięcie dynamiczne" + +#: ../../po/../src/verbs.cpp:1980 +msgid "Create a dynamic offset object" +msgstr "Tworzy dynamiczny obiekt odsunięcia" + +#: ../../po/../src/verbs.cpp:1982 +msgid "_Linked Offset" +msgstr "Odsunięcie połączone" + +#: ../../po/../src/verbs.cpp:1983 +msgid "Create a dynamic offset object linked to the original path" +msgstr "Tworzy dynamiczny obiekt odsunięcia połączony z oryginalną ścieżką" + +#: ../../po/../src/verbs.cpp:1985 +msgid "_Stroke to Path" +msgstr "_Kontur na ścieżkę" + +#: ../../po/../src/verbs.cpp:1986 +#, fuzzy +msgid "Convert selected strokes to paths" +msgstr "Zamienia zaznaczone kontury na ścieżki" + +#: ../../po/../src/verbs.cpp:1987 +msgid "Si_mplify" +msgstr "_Uprość" + +#: ../../po/../src/verbs.cpp:1988 +#, fuzzy +msgid "Simplify selected paths by removing extra nodes" +msgstr "Upraszacza zaznaczone ścieżki usuwając zbędne węzły" + +#: ../../po/../src/verbs.cpp:1989 +msgid "_Reverse" +msgstr "O_dwróć kierunek" + +#: ../../po/../src/verbs.cpp:1990 +#, fuzzy +msgid "Reverses the direction of selected paths; useful for flipping markers" +msgstr "" +"Odwraca kierunek zaznaczonych ścieżek; przydatne do odwracania znaczników " +"rozmieszczonych na konturze" + +#. TRANSLATORS: "to trace" means "to convert a bitmap to vector graphics" (to vectorize) +#: ../../po/../src/verbs.cpp:1992 +msgid "_Trace Bitmap" +msgstr "Wektoryzuj _bitmapę..." + +#: ../../po/../src/verbs.cpp:1993 +msgid "Convert bitmap object to paths" +msgstr "Tworzy z bitmapy ścieżki wektorowe" + +#: ../../po/../src/verbs.cpp:1994 +msgid "_Make a Bitmap Copy" +msgstr "Kopiuj jako _bitmapę" + +#: ../../po/../src/verbs.cpp:1995 +msgid "Export selection to a bitmap and insert it into document" +msgstr "Eksportuje zaznaczenie do bitmapy i wstawia do dokumentu jako obraz" + +#: ../../po/../src/verbs.cpp:1996 +msgid "_Combine" +msgstr "Połącz" + +#: ../../po/../src/verbs.cpp:1997 +msgid "Combine several paths into one" +msgstr "Łączy kilka ścieżek w jedną" + +#. TRANSLATORS: "to cut a path" is not the same as "to break a path apart" - see the +#. Advanced tutorial for more info +#: ../../po/../src/verbs.cpp:2000 +msgid "Break _Apart" +msgstr "Rozdziel" + +#: ../../po/../src/verbs.cpp:2001 +#, fuzzy +msgid "Break selected paths into subpaths" +msgstr "Rozdziela połączone ścieżki na poszczególne elementy" + +#: ../../po/../src/verbs.cpp:2002 +msgid "Gri_d Arrange..." +msgstr "Rozłóż na siatce..." + +#: ../../po/../src/verbs.cpp:2003 +msgid "Arrange selection in grid pattern" +msgstr "Rozmieszcza zaznaczone obiekty w układzie siatki" + +#. Layer +#: ../../po/../src/verbs.cpp:2005 +msgid "_Add Layer..." +msgstr "_Nowa warstwa..." + +#: ../../po/../src/verbs.cpp:2006 +msgid "Create a new layer" +msgstr "Tworzy nową warstwę" + +#: ../../po/../src/verbs.cpp:2007 +msgid "Re_name Layer..." +msgstr "_Zmień nazwę warstwy..." + +#: ../../po/../src/verbs.cpp:2008 +msgid "Rename the current layer" +msgstr "Zmienia nazwę aktywnej warstwy" + +#: ../../po/../src/verbs.cpp:2009 +msgid "Switch to Layer Abov_e" +msgstr "Przejdź na wyższą warstwę" + +#: ../../po/../src/verbs.cpp:2010 +msgid "Switch to the layer above the current" +msgstr "Przechodzi do warstwy położonej powyżej aktywnej warstwy" + +#: ../../po/../src/verbs.cpp:2011 +msgid "Switch to Layer Belo_w" +msgstr "Przejdź na niższą warstwę" + +#: ../../po/../src/verbs.cpp:2012 +msgid "Switch to the layer below the current" +msgstr "Przechodzi do warstwy położonej poniżej aktywnej warstwy" + +#: ../../po/../src/verbs.cpp:2013 +msgid "Move Selection to Layer Abo_ve" +msgstr "Przenieś zaznaczenie na wyższą warstwę" + +#: ../../po/../src/verbs.cpp:2014 +msgid "Move selection to the layer above the current" +msgstr "Przenosi zaznaczenie na warstwę ponad aktywną" + +#: ../../po/../src/verbs.cpp:2015 +msgid "Move Selection to Layer Bel_ow" +msgstr "Przenieś zaznaczenie na niższą warstwę" + +#: ../../po/../src/verbs.cpp:2016 +msgid "Move selection to the layer below the current" +msgstr "Przenosi zaznaczenie na warstwę poniżej aktywnej" + +#: ../../po/../src/verbs.cpp:2017 +msgid "Layer to _Top" +msgstr "Przenieś warstwę na _wierzch" + +#: ../../po/../src/verbs.cpp:2018 +msgid "Raise the current layer to the top" +msgstr "Przenosi aktywną warstwę ponad wszystkie pozostałe" + +#: ../../po/../src/verbs.cpp:2019 +msgid "Layer to _Bottom" +msgstr "Przenieś warstwę pod _spód" + +#: ../../po/../src/verbs.cpp:2020 +msgid "Lower the current layer to the bottom" +msgstr "Przenosi aktywną warstwę poniżej wszystkich pozostałych" + +#: ../../po/../src/verbs.cpp:2021 +msgid "_Raise Layer" +msgstr "Przesuń warstwę wyżej" + +#: ../../po/../src/verbs.cpp:2022 +msgid "Raise the current layer" +msgstr "Przesuwa aktywną warstwę o jedną pozycję wyżej" + +#: ../../po/../src/verbs.cpp:2023 +msgid "_Lower Layer" +msgstr "Przesuń warstwę niżej" + +#: ../../po/../src/verbs.cpp:2024 +msgid "Lower the current layer" +msgstr "Przesuwa aktywną warstwę o jedną pozycję niżej" + +#: ../../po/../src/verbs.cpp:2025 +msgid "_Delete Current Layer" +msgstr "_Usuń aktywną warstwę" + +#: ../../po/../src/verbs.cpp:2026 +msgid "Delete the current layer" +msgstr "Usuwa aktywną warstwę (wraz ze znajdującymi się na niej obiektami)" + +#. Object +#: ../../po/../src/verbs.cpp:2029 +#, fuzzy +msgid "Rotate _90° CW" +msgstr "_Obróć o 90 stopni w prawo" + +#: ../../po/../src/verbs.cpp:2030 +#, fuzzy +msgid "Rotate selection 90° clockwise" +msgstr "" +"Obraca zaznaczone obiekty o 90 stopni zgodnie z ruchem wskazówek zegara" + +#: ../../po/../src/verbs.cpp:2031 +#, fuzzy +msgid "Rotate 9_0° CCW" +msgstr "O_bróć o 90 stopni w lewo" + +#: ../../po/../src/verbs.cpp:2032 +#, fuzzy +msgid "Rotate selection 90° counter-clockwise" +msgstr "" +"Obraca zaznaczone obiekty o 90 stopni przeciwnie do ruchu wskazówek zegara" + +#: ../../po/../src/verbs.cpp:2033 +msgid "Remove _Transformations" +msgstr "Usuń przekształcenia" + +#: ../../po/../src/verbs.cpp:2034 +msgid "Remove transformations from object" +msgstr "Usuwa przekształcenia z obiektu" + +#: ../../po/../src/verbs.cpp:2035 +msgid "_Object to Path" +msgstr "_Obiekt na ścieżkę" + +#: ../../po/../src/verbs.cpp:2036 +#, fuzzy +msgid "Convert selected objects to paths" +msgstr "Zamienia zaznaczone obiekty na ścieżki" + +#: ../../po/../src/verbs.cpp:2037 +msgid "_Flow into Frame" +msgstr "Wprowadź tekst do _kształtu" + +#: ../../po/../src/verbs.cpp:2038 +#, fuzzy +msgid "Put text into frames" +msgstr "Dopasowuje tekst do zaznaczonych obiektów" + +#: ../../po/../src/verbs.cpp:2039 +msgid "_Unflow" +msgstr "_Uwolnij tekst" + +#: ../../po/../src/verbs.cpp:2040 +msgid "Remove text from frame (creates a single-line text object)" +msgstr "Usuń tekst tekst z ramki (tworzy tekst w pojedynczej linii)" + +#: ../../po/../src/verbs.cpp:2041 +msgid "_Convert to Text" +msgstr "Z_amień na zwykły tekst" + +#: ../../po/../src/verbs.cpp:2042 +#, fuzzy +msgid "Convert flowed text to regular text objects (preserves appearance)" +msgstr "" +"Zamienia tekst dopasowany do kształtu na zwykłe obiekty tekstowe (z " +"zachowaniem wyglądu)" + +#: ../../po/../src/verbs.cpp:2044 +#, fuzzy +msgid "Flip _Horizontal" +msgstr "Odbij po_ziomo" + +#: ../../po/../src/verbs.cpp:2044 +#, fuzzy +msgid "Flips selected objects horizontally" +msgstr "Wyrównanie wybranych węzłów w poziomie" + +#: ../../po/../src/verbs.cpp:2047 +#, fuzzy +msgid "Flip _Vertical" +msgstr "Odbij pio_nowo" + +#: ../../po/../src/verbs.cpp:2047 +#, fuzzy +msgid "Flips selected objects vertically" +msgstr "Wyrównanie wybranych węzłów w pionie" + +#. Tools +#: ../../po/../src/verbs.cpp:2051 +msgid "Select" +msgstr "Zaznaczenie" + +#: ../../po/../src/verbs.cpp:2052 +msgid "Select and transform objects" +msgstr "Zaznacza i przekształca obiekty" + +#: ../../po/../src/verbs.cpp:2053 +msgid "Node Edit" +msgstr "Edycja węzłów" + +#: ../../po/../src/verbs.cpp:2054 +msgid "Edit path nodes or control handles" +msgstr "Pozwala edytować węzły i uchwyty sterujące ścieżek" + +#: ../../po/../src/verbs.cpp:2056 +msgid "Create rectangles and squares" +msgstr "Tworzy prostokąty i kwadraty z opcjonalnie zaokrąglonymi narożnikami" + +#: ../../po/../src/verbs.cpp:2058 +msgid "Create circles, ellipses, and arcs" +msgstr "Tworzy okręgi, elipsy i łuki" + +#: ../../po/../src/verbs.cpp:2060 +msgid "Create stars and polygons" +msgstr "Tworzy gwiazdy i wielokąty" + +#: ../../po/../src/verbs.cpp:2062 +msgid "Create spirals" +msgstr "Tworzy spirale" + +#: ../../po/../src/verbs.cpp:2064 +msgid "Draw freehand lines" +msgstr "Rysuje krzywe odręczne" + +#: ../../po/../src/verbs.cpp:2066 +msgid "Draw Bezier curves and straight lines" +msgstr "Rysuje krzywe Beziera i linie proste" + +#: ../../po/../src/verbs.cpp:2068 +msgid "Draw calligraphic lines" +msgstr "Rysuje linie kaligraficzne" + +#: ../../po/../src/verbs.cpp:2070 +msgid "Create and edit text objects" +msgstr "Tworzy i modyfikuje obiekty tekstowe" + +#: ../../po/../src/verbs.cpp:2072 +msgid "Create and edit gradients" +msgstr "Tworzy i modyfikuje gradienty" + +#: ../../po/../src/verbs.cpp:2074 +msgid "Zoom in or out" +msgstr "Zmienia powiększenie rysunku" + +#: ../../po/../src/verbs.cpp:2076 +msgid "Pick averaged colors from image" +msgstr "Pobiera uśrednione kolory z rysunku" + +#: ../../po/../src/verbs.cpp:2078 +msgid "Create connectors" +msgstr "Tworzy łączniki" + +#. Tool prefs +#: ../../po/../src/verbs.cpp:2081 +msgid "Selector Preferences" +msgstr "Ustawienia wskaźnika" + +#: ../../po/../src/verbs.cpp:2082 +#, fuzzy +msgid "Open Preferences for the Selector tool" +msgstr "Otwiera okno ustawień programu Inkscape dla narzędzia wskaźnik" + +#: ../../po/../src/verbs.cpp:2083 +msgid "Node Tool Preferences" +msgstr "Ustawienia edycji węzłów" + +#: ../../po/../src/verbs.cpp:2084 +#, fuzzy +msgid "Open Preferences for the Node tool" +msgstr "Otwiera okno ustawień programu Inkscape dla narzędzia edycji węzłów" + +#: ../../po/../src/verbs.cpp:2085 +msgid "Rectangle Preferences" +msgstr "Ustawienia prostokąta" + +#: ../../po/../src/verbs.cpp:2086 +#, fuzzy +msgid "Open Preferences for the Rectangle tool" +msgstr "Otwiera okno ustawień programu Inkscape dla narzędzia prostokąt" + +#: ../../po/../src/verbs.cpp:2087 +msgid "Ellipse Preferences" +msgstr "Ustawienia elipsy" + +#: ../../po/../src/verbs.cpp:2088 +#, fuzzy +msgid "Open Preferences for the Ellipse tool" +msgstr "Otwiera okno ustawień programu Inkscape dla narzędzia elipsa" + +#: ../../po/../src/verbs.cpp:2089 +msgid "Star Preferences" +msgstr "Ustawienia gwiazdy" + +#: ../../po/../src/verbs.cpp:2090 +#, fuzzy +msgid "Open Preferences for the Star tool" +msgstr "Otwiera okno ustawień programu Inkscape dla narzędzia gwiazda" + +#: ../../po/../src/verbs.cpp:2091 +msgid "Spiral Preferences" +msgstr "Ustawienia spirali" + +#: ../../po/../src/verbs.cpp:2092 +#, fuzzy +msgid "Open Preferences for the Spiral tool" +msgstr "Otwiera okno ustawień programu Inkscape dla narzędzia spirala" + +#: ../../po/../src/verbs.cpp:2093 +msgid "Pencil Preferences" +msgstr "Ustawienia ołówka" + +#: ../../po/../src/verbs.cpp:2094 +#, fuzzy +msgid "Open Preferences for the Pencil tool" +msgstr "Otwiera okno ustawień programu Inkscape dla narzędzia ołówek" + +#: ../../po/../src/verbs.cpp:2095 +msgid "Pen Preferences" +msgstr "Ustawienia pióra" + +#: ../../po/../src/verbs.cpp:2096 +#, fuzzy +msgid "Open Preferences for the Pen tool" +msgstr "Otwiera okno ustawień programu Inkscape dla narzędzia pióro" + +#: ../../po/../src/verbs.cpp:2097 +msgid "Calligraphic Preferences" +msgstr "Ustawienia kaligrafi" + +#: ../../po/../src/verbs.cpp:2098 +#, fuzzy +msgid "Open Preferences for the Calligraphy tool" +msgstr "Otwiera okno ustawień programu Inkscape dla narzędzia kaligrafia" + +#: ../../po/../src/verbs.cpp:2099 +msgid "Text Preferences" +msgstr "Ustawienia tekstu" + +#: ../../po/../src/verbs.cpp:2100 +#, fuzzy +msgid "Open Preferences for the Text tool" +msgstr "Otwiera okno ustawień programu Inkscape dla narzędzia tekst" + +#: ../../po/../src/verbs.cpp:2101 +msgid "Gradient Preferences" +msgstr "Ustawienia Gradientu" + +#: ../../po/../src/verbs.cpp:2102 +#, fuzzy +msgid "Open Preferences for the Gradient tool" +msgstr "Otwiera okno ustawień programu Inkscape dla narzędzia Gradient" + +#: ../../po/../src/verbs.cpp:2103 +msgid "Zoom Preferences" +msgstr "Ustawienia powiększenia" + +#: ../../po/../src/verbs.cpp:2104 +#, fuzzy +msgid "Open Preferences for the Zoom tool" +msgstr "Otwiera okno ustawień programu Inkscape dla narzędzia powiększenie" + +#: ../../po/../src/verbs.cpp:2105 +msgid "Dropper Preferences" +msgstr "Ustawienia pipety" + +#: ../../po/../src/verbs.cpp:2106 +#, fuzzy +msgid "Open Preferences for the Dropper tool" +msgstr "Otwiera okno ustawień programu Inkscape dla narzędzia pipeta" + +#: ../../po/../src/verbs.cpp:2107 +msgid "Connector Preferences" +msgstr "Ustawienia łączników" + +#: ../../po/../src/verbs.cpp:2108 +#, fuzzy +msgid "Open Preferences for the Connector tool" +msgstr "Otwiera okno ustawień programu Inkscape dla narzędzia łącznik" + +#. Zoom/View +#: ../../po/../src/verbs.cpp:2111 +msgid "Zoom In" +msgstr "Powiększenie" + +#: ../../po/../src/verbs.cpp:2111 +msgid "Zoom in" +msgstr "Powiększenie" + +#: ../../po/../src/verbs.cpp:2112 +msgid "Zoom Out" +msgstr "Pomniejszenie" + +#: ../../po/../src/verbs.cpp:2112 +msgid "Zoom out" +msgstr "Pomniejszenie" + +#: ../../po/../src/verbs.cpp:2113 +msgid "_Rulers" +msgstr "_Linijki" + +#: ../../po/../src/verbs.cpp:2113 +msgid "Show or hide the canvas rulers" +msgstr "Wyświetla lub ukrywa linijki" + +#: ../../po/../src/verbs.cpp:2114 +msgid "Scroll_bars" +msgstr "Paski przewijania" + +#: ../../po/../src/verbs.cpp:2114 +msgid "Show or hide the canvas scrollbars" +msgstr "Wyświetla lub ukrywa paski przewijania" + +#: ../../po/../src/verbs.cpp:2115 +msgid "_Grid" +msgstr "Siatk_a" + +#: ../../po/../src/verbs.cpp:2116 +msgid "G_uides" +msgstr "Pr_owadnice" + +#: ../../po/../src/verbs.cpp:2117 +msgid "Nex_t Zoom" +msgstr "_Następne powiększenie" + +#: ../../po/../src/verbs.cpp:2117 +msgid "Next zoom (from the history of zooms)" +msgstr "Następne powiększenie (z listy zapamiętanych powiększeń)" + +#: ../../po/../src/verbs.cpp:2119 +msgid "Pre_vious Zoom" +msgstr "P_oprzednie powiększenie" + +#: ../../po/../src/verbs.cpp:2119 +msgid "Previous zoom (from the history of zooms)" +msgstr "Poprzednie powiększenie (z listy zapamiętanych powiększeń)" + +#: ../../po/../src/verbs.cpp:2121 +msgid "Zoom 1:_1" +msgstr "Powiększenie 1:_1" + +#: ../../po/../src/verbs.cpp:2121 +msgid "Zoom to 1:1" +msgstr "Ustawia współczynnik powiększenia na 1:1" + +#: ../../po/../src/verbs.cpp:2123 +msgid "Zoom 1:_2" +msgstr "Powiększenie 1:_2" + +#: ../../po/../src/verbs.cpp:2123 +msgid "Zoom to 1:2" +msgstr "Ustawia współczynnik powiększenia na 1:2" + +#: ../../po/../src/verbs.cpp:2125 +msgid "_Zoom 2:1" +msgstr "Powiększenie 2:1" + +#: ../../po/../src/verbs.cpp:2125 +msgid "Zoom to 2:1" +msgstr "Ustawia współczynnik powiększenia na 2:1" + +#: ../../po/../src/verbs.cpp:2128 +msgid "_Fullscreen" +msgstr "Pełny _ekran" + +#: ../../po/../src/verbs.cpp:2128 +msgid "Stretch this document window to full screen" +msgstr "Rozciąga okno dokumentu na cały ekran" + +#: ../../po/../src/verbs.cpp:2131 +msgid "Duplic_ate Window" +msgstr "_Duplikuj okno" + +#: ../../po/../src/verbs.cpp:2131 +msgid "Open a new window with the same document" +msgstr "Otwiera nowe okno z tym samym dokumentem" + +#: ../../po/../src/verbs.cpp:2133 +msgid "_New View Preview" +msgstr "Nowy podgląd widoku" + +#: ../../po/../src/verbs.cpp:2134 +msgid "New View Preview" +msgstr "Nowy podgląd widoku" + +#. "view_new_preview" +#: ../../po/../src/verbs.cpp:2136 +#, fuzzy +msgid "_Normal" +msgstr "Normalne" + +#: ../../po/../src/verbs.cpp:2137 +msgid "Switch to normal display mode" +msgstr "" + +#: ../../po/../src/verbs.cpp:2138 +#, fuzzy +msgid "_Outline" +msgstr "Tylko ramki obiektów" + +#: ../../po/../src/verbs.cpp:2139 +msgid "Switch to outline (wireframe) display mode" +msgstr "" + +#: ../../po/../src/verbs.cpp:2141 +msgid "Ico_n Preview" +msgstr "Podgląd ikon" + +#: ../../po/../src/verbs.cpp:2142 +msgid "Open a window to preview items at different icon resolutions" +msgstr "Otwiera okno z podglądem obiektów w rozdzielczościach ikon" + +#: ../../po/../src/verbs.cpp:2144 +msgid "Zoom to fit page in window" +msgstr "Dopasowuje rozmiar całej strony do okna" + +#: ../../po/../src/verbs.cpp:2145 +msgid "Page _Width" +msgstr "Szerokość s_trony" + +#: ../../po/../src/verbs.cpp:2146 +msgid "Zoom to fit page width in window" +msgstr "Dopasowuje szerokość strony do okna" + +#: ../../po/../src/verbs.cpp:2148 +msgid "Zoom to fit drawing in window" +msgstr "Dopasowuje rozmiar całego rysunku do okna" + +#: ../../po/../src/verbs.cpp:2150 +msgid "Zoom to fit selection in window" +msgstr "Dopasowuje rozmiar całego zaznaczenia do okna" + +#. Dialogs +#: ../../po/../src/verbs.cpp:2153 +msgid "In_kscape Preferences..." +msgstr "Us_tawienia Inkscape..." + +#: ../../po/../src/verbs.cpp:2154 +msgid "Global Inkscape preferences" +msgstr "Ustawienia programu Inkscape" + +#: ../../po/../src/verbs.cpp:2155 +msgid "_Document Preferences..." +msgstr "U_stawienia dokumentu..." + +#: ../../po/../src/verbs.cpp:2156 +msgid "Preferences saved with the document" +msgstr "Ustawienia zapisywane z dokumentem" + +#: ../../po/../src/verbs.cpp:2157 +msgid "_Fill and Stroke..." +msgstr "Wypełnienie i _kontur..." + +#: ../../po/../src/verbs.cpp:2158 +msgid "Fill and Stroke dialog" +msgstr "Wyświetla okno dialogowe Wypełnienie i kontur" + +#. TRANSLATORS: "Swatches" means: color samples +#: ../../po/../src/verbs.cpp:2160 +msgid "S_watches..." +msgstr "Palety kolorów..." + +#: ../../po/../src/verbs.cpp:2161 +msgid "View color swatches" +msgstr "Otwiera okno z wzornikami kolorów" + +#: ../../po/../src/verbs.cpp:2162 +msgid "Transfor_m..." +msgstr "Prz_ekształć..." + +#: ../../po/../src/verbs.cpp:2163 +msgid "Transform dialog" +msgstr "Wyświetla okno dialogowe Przekształcenia" + +#: ../../po/../src/verbs.cpp:2164 +msgid "_Align and Distribute..." +msgstr "Wyrówna_j i rozłóż..." + +#: ../../po/../src/verbs.cpp:2165 +msgid "Align and Distribute dialog" +msgstr "Wyświetla okno dialogowe Układ elementów" + +#: ../../po/../src/verbs.cpp:2166 +msgid "_Text and Font..." +msgstr "_Tekst i czcionka..." + +#: ../../po/../src/verbs.cpp:2167 +msgid "Text and Font dialog" +msgstr "Wyświetla okno dialogowe Tekst i czcionka" + +#: ../../po/../src/verbs.cpp:2168 +msgid "_XML Editor..." +msgstr "Edytor _XML-u" + +#: ../../po/../src/verbs.cpp:2169 +msgid "XML Editor" +msgstr "Edytor XML-u" + +#: ../../po/../src/verbs.cpp:2170 +msgid "_Find..." +msgstr "_Znajdź..." + +#: ../../po/../src/verbs.cpp:2171 +msgid "Find objects in document" +msgstr "Wyszukiwanie obiektów w dokumencie" + +#: ../../po/../src/verbs.cpp:2172 +msgid "_Messages..." +msgstr "_Komunikaty..." + +#: ../../po/../src/verbs.cpp:2173 +msgid "View debug messages" +msgstr "Wyświetla okno komunikatów programu" + +#: ../../po/../src/verbs.cpp:2174 +msgid "S_cripts..." +msgstr "Skrypt_y..." + +#: ../../po/../src/verbs.cpp:2175 +msgid "Run scripts" +msgstr "Otwiera okno do wykonywania skryptów" + +#: ../../po/../src/verbs.cpp:2176 +msgid "Show/Hide D_ialogs" +msgstr "Pokaż/_ukryj okna dialogowe" + +#: ../../po/../src/verbs.cpp:2177 +msgid "Show or hide all active dialogs" +msgstr "Pokazuje lub ukrywa wszystkie aktywne okna dialogowe" + +#. TRANSLATORS: "Tile clones" means: "Create tiled clones" +#: ../../po/../src/verbs.cpp:2179 +msgid "Tile clones..." +msgstr "Klonu_j wielokrotnie..." + +#: ../../po/../src/verbs.cpp:2180 +msgid "Create and arrange multiple clones of selection" +msgstr "Tworzy i rozmieszcza wielokrotne klony zaznaczonych obiektów" + +#: ../../po/../src/verbs.cpp:2181 +msgid "_Object Properties..." +msgstr "Właściwości _obiektu..." + +#: ../../po/../src/verbs.cpp:2182 +msgid "Object Properties dialog" +msgstr "Wyświetla okno dialogowe Właściwości obiektu" + +#: ../../po/../src/verbs.cpp:2185 +msgid "_Connect to Jabber server..." +msgstr "_Połącz się z serwerem Jabbera" + +#: ../../po/../src/verbs.cpp:2185 +msgid "Connect to a Jabber server" +msgstr "Połącz z serwerem Jabbera" + +#: ../../po/../src/verbs.cpp:2187 +msgid "Share with _user..." +msgstr "Współdziel z _użytkownikiem..." + +#: ../../po/../src/verbs.cpp:2187 +msgid "Establish a whiteboard session with another Jabber user" +msgstr "" +"Rozpocznij sesję wspólnej pracy na planszy z innym użytkownikiem Jabbera" + +#: ../../po/../src/verbs.cpp:2189 +msgid "Share with _chatroom..." +msgstr "Przyłącz się do pokoju..." + +#: ../../po/../src/verbs.cpp:2189 +msgid "" +"Join a chatroom to start a new whiteboard session or join one in progress" +msgstr "" +"Wejdź do pokoju aby rozpocząć wspólną pracę na planszy lub przyłącz się do " +"już rozpoczętej sesji" + +#: ../../po/../src/verbs.cpp:2191 +msgid "_Dump XML node tracker" +msgstr "_Raport analizatora węzłów XML" + +#: ../../po/../src/verbs.cpp:2191 +msgid "Dump the contents of the XML tracker to the console" +msgstr "Wyświetlenie w konsoli sprawozdania analizatora węzłów XML" + +#: ../../po/../src/verbs.cpp:2193 +msgid "_Open session file..." +msgstr "_Otwórz plik sesji..." + +#: ../../po/../src/verbs.cpp:2193 +msgid "Open and browse through records of past whiteboard sessions" +msgstr "Otwórz i przeglądaj zapis poprzednich sesji pracy na planszy" + +#: ../../po/../src/verbs.cpp:2195 +msgid "Session file playback" +msgstr "Odtwarzanie pliku sesji" + +#: ../../po/../src/verbs.cpp:2197 +msgid "_Disconnect from session" +msgstr "_Przerwij sesję pracy" + +#: ../../po/../src/verbs.cpp:2199 +msgid "Disconnect from _server" +msgstr "_Rozłącz się z serwerem" + +#: ../../po/../src/verbs.cpp:2201 +msgid "_Input Devices..." +msgstr "_Urządzenia wejściowe" + +#: ../../po/../src/verbs.cpp:2202 +msgid "Configure extended input devices" +msgstr "Skonfiguruj rozszerzone uządzenie wejściowe" + +#. Help +#: ../../po/../src/verbs.cpp:2205 +msgid "_Keys and Mouse" +msgstr "_Klawisze i mysz" + +#: ../../po/../src/verbs.cpp:2206 +msgid "Key and mouse shortcuts reference" +msgstr "Objaśnienia skrótów klawiszowych i przycisków myszy" + +#: ../../po/../src/verbs.cpp:2207 +msgid "About E_xtensions" +msgstr "Informacje o _rozszerzeniach..." + +#: ../../po/../src/verbs.cpp:2208 +msgid "About Extensions..." +msgstr "Wyświetla okno z informacjami o dostępnych rozszerzeniach programu" + +#: ../../po/../src/verbs.cpp:2209 +msgid "About _Memory" +msgstr "Informacje o pamięci..." + +#: ../../po/../src/verbs.cpp:2210 +msgid "About Memory..." +msgstr "Wyświetla okno z informacjami o pamięci" + +#: ../../po/../src/verbs.cpp:2211 +msgid "_About Inkscape" +msgstr "_O programie Inkscape..." + +#. "help_about" +#. new HelpVerb(SP_VERB_SHOW_LICENSE, "ShowLicense", N_("Modifying or Redistributing Inkscape"), +#. N_("Show license to modify and/or redistribute Inkscape: GNU GPL"), NULL), +#. Tutorials +#: ../../po/../src/verbs.cpp:2217 +msgid "Inkscape: _Basic" +msgstr "Inkscape: _Podstawy" + +#: ../../po/../src/verbs.cpp:2218 +msgid "Getting started with Inkscape" +msgstr "Pierwsze kroki z Inkscape" + +#. "tutorial_basic" +#: ../../po/../src/verbs.cpp:2219 +msgid "Inkscape: _Shapes" +msgstr "Inkscape: _Kształty" + +#: ../../po/../src/verbs.cpp:2220 +msgid "Using shape tools to create and edit shapes" +msgstr "Wykorzystanie narzędzi do tworzenia i edycji kształtów" + +#: ../../po/../src/verbs.cpp:2221 +msgid "Inkscape: _Advanced" +msgstr "Inkscape: _Zaawansowane" + +#: ../../po/../src/verbs.cpp:2222 +msgid "Advanced Inkscape topics" +msgstr "Zaawansowane zagadnienia związane z Inkscape" + +#. "tutorial_advanced" +#. TRANSLATORS: "to trace" means "to convert a bitmap to vector graphics" (to vectorize) +#: ../../po/../src/verbs.cpp:2224 +msgid "Inkscape: T_racing" +msgstr "Inkscape: _Wektoryzacja" + +#: ../../po/../src/verbs.cpp:2225 +msgid "Using bitmap tracing" +msgstr "Obsługa wektoryzacji bitmap" + +#. "tutorial_tracing" +#: ../../po/../src/verbs.cpp:2226 +msgid "Inkscape: _Calligraphy" +msgstr "Inkscape: Kali_grafia" + +#: ../../po/../src/verbs.cpp:2227 +msgid "Using the Calligraphy pen tool" +msgstr "Wykorzystanie narzędzia pisma kaligraficznego" + +#: ../../po/../src/verbs.cpp:2228 +msgid "_Elements of Design" +msgstr "_Elementy kompozycji" + +#: ../../po/../src/verbs.cpp:2229 +msgid "Principles of design in the tutorial form" +msgstr "Przewodnik po zasadach kształtowania kompozycji" + +#. "tutorial_design" +#: ../../po/../src/verbs.cpp:2230 +msgid "_Tips and Tricks" +msgstr "Porady i _sztuczki" + +#: ../../po/../src/verbs.cpp:2231 +msgid "Miscellaneous tips and tricks" +msgstr "Zbiór różnych porad i sztuczek" + +#. "tutorial_tips" +#. Effect +#: ../../po/../src/verbs.cpp:2234 +msgid "Previous Effect" +msgstr "Poprzedni efekt" + +#: ../../po/../src/verbs.cpp:2235 +msgid "Repeat the last effect with the same settings" +msgstr "Powtarza ostatni efekt z zachowaniem ustawień" + +#. "tutorial_tips" +#: ../../po/../src/verbs.cpp:2236 +msgid "Previous Effect Settings..." +msgstr "Ustawienia poprzedniego efektu..." + +#: ../../po/../src/verbs.cpp:2237 +msgid "Repeat the last effect with new settings" +msgstr "Powtarza ostatni efekt z nowymi ustawieniami" + +#: ../../po/../src/widgets/dash-selector.cpp:106 +msgid "Dash pattern" +msgstr "Wzór kreski" + +#: ../../po/../src/widgets/dash-selector.cpp:121 +msgid "Pattern offset" +msgstr "Przesunięcie wzoru" + +#: ../../po/../src/widgets/desktop-widget.cpp:240 +msgid "Zoom drawing if window size changes" +msgstr "Dopasowuje rozmiar całego rysunku do okna" + +#: ../../po/../src/widgets/desktop-widget.cpp:298 +msgid "Cursor coordinates" +msgstr "Współrzędne kursora" + +#. display the initial welcome message in the statusbar +#: ../../po/../src/widgets/desktop-widget.cpp:324 +msgid "" +"Welcome to Inkscape! Use shape or freehand tools to create objects; " +"use selector (arrow) to move or transform them." +msgstr "" +" Witaj w programie Inkscape! Wybierz z palety narzędzie do rysowania; " +"użyj wskaźnika (strzałki) do przekształceń." + +#: ../../po/../src/widgets/desktop-widget.cpp:372 +#, c-format +msgid "%s: %d - Inkscape" +msgstr "%s: %d - Inkscape" + +#: ../../po/../src/widgets/desktop-widget.cpp:374 +#, c-format +msgid "%s - Inkscape" +msgstr "%s - Inkscape" + +#: ../../po/../src/widgets/desktop-widget.cpp:532 +#, c-format +msgid "" +"Save changes to document \"%s\" before " +"closing?\n" +"\n" +"If you close without saving, your changes will be discarded." +msgstr "" +"Czy zapisać zmiany w dokumencie \"%s\" " +"przed zamknięciem programu?\n" +"\n" +"Zamknięcie bez zapisywania spowoduje utratę wprowadzonych zmian." + +#: ../../po/../src/widgets/desktop-widget.cpp:548 +#: ../../po/../src/widgets/desktop-widget.cpp:612 +msgid "Close _without saving" +msgstr "Zamknij _bez zapisywania" + +#: ../../po/../src/widgets/desktop-widget.cpp:595 +#, c-format +msgid "" +"The file \"%s\" was saved with a " +"format (%s) that may cause data loss!\n" +"\n" +"Do you want to save this file in another format?" +msgstr "" +"Plik \"%s\" został zapisany w formacie " +"(%s), który może spowodować utratę danych!\n" +"\n" +"Czy chcesz zapisać ten plik w innym formacie?" + +#. Family frame +#: ../../po/../src/widgets/font-selector.cpp:156 +msgid "Font family" +msgstr "Rodzina czcionek" + +#. Style frame +#: ../../po/../src/widgets/font-selector.cpp:184 +msgid "Style" +msgstr "Styl" + +#: ../../po/../src/widgets/font-selector.cpp:219 +msgid "Font size:" +msgstr "Rozmiar czcionki:" + +#. TRANSLATORS: Test string used in text and font dialog (when no +#. * text has been entered) to get a preview of the font. Choose +#. * some representative characters that users of your locale will be +#. * interested in. +#: ../../po/../src/widgets/font-selector.cpp:554 +msgid "AaBbCcIiPpQq12368.;/()" +msgstr "AaĄąBbCćĘęKkÓóŹź0123:/()" + +#: ../../po/../src/widgets/gradient-selector.cpp:137 +#: ../../po/../src/widgets/gradient-toolbar.cpp:524 +msgid "Duplicate" +msgstr "Duplikuj" + +#: ../../po/../src/widgets/gradient-selector.cpp:142 +#: ../../po/../src/widgets/gradient-toolbar.cpp:535 +msgid "Edit..." +msgstr "Edytuj..." + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/pservers.html#LinearGradientSpreadMethodAttribute +#: ../../po/../src/widgets/gradient-selector.cpp:159 +msgid "" +"Whether to fill with flat color beyond the ends of the gradient vector " +"(spreadMethod=\"pad\"), or repeat the gradient in the same direction " +"(spreadMethod=\"repeat\"), or repeat the gradient in alternating opposite " +"directions (spreadMethod=\"reflect\")" +msgstr "" +"Wygląd gradientu poza końcami definującego wektora:\n" +"'brak' = zastosowanie jednolitego koloru\n" +"'powtórzenie' = powtórzony gradient w tym samym kierunku\n" +"'odbicie' = powtórzony gradient w odwrotnym kierunku" + +#: ../../po/../src/widgets/gradient-selector.cpp:165 +msgid "none" +msgstr "brak" + +#: ../../po/../src/widgets/gradient-selector.cpp:169 +msgid "reflected" +msgstr "odbicie" + +#: ../../po/../src/widgets/gradient-selector.cpp:173 +msgid "direct" +msgstr "powtórzenie" + +#: ../../po/../src/widgets/gradient-selector.cpp:181 +msgid "Repeat:" +msgstr "Kontynuacja:" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:217 +msgid "No gradients" +msgstr "Brak gradientów" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:226 +msgid "Nothing selected" +msgstr "Niczego nie wybrano" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:237 +msgid "No gradients in selection" +msgstr "Brak gradientów w zaznaczeniu" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:247 +msgid "Multiple gradients" +msgstr "Wiele gradientów" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:525 +msgid "" +"If the gradient is used by more than one object, create a copy of it for the " +"selected object(s)" +msgstr "" +"Jeśli gradient jest używany przez więcej obiektów, utwórz jego kopię dla " +"każdego z zaznaczonych obiektów" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:536 +msgid "Edit the stops of the gradient" +msgstr "Edytuj punkty sterujące gradientu" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:593 +#: ../../po/../src/widgets/toolbox.cpp:1103 +#: ../../po/../src/widgets/toolbox.cpp:1192 +#: ../../po/../src/widgets/toolbox.cpp:1485 +#: ../../po/../src/widgets/toolbox.cpp:1534 +#: ../../po/../src/widgets/toolbox.cpp:1766 +#: ../../po/../src/widgets/toolbox.cpp:1801 +#: ../../po/../src/widgets/toolbox.cpp:2331 +#: ../../po/../src/widgets/toolbox.cpp:2370 +msgid "New:" +msgstr "Nowe:" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:606 +msgid "Create linear gradient" +msgstr "Utwórz gradient liniowy" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:620 +msgid "Create radial (elliptic or circular) gradient" +msgstr "Utwórz gradient koncentryczny (eliptyczny lub kołowy)" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:635 +msgid "on" +msgstr "na:" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:648 +msgid "Create gradient in the fill" +msgstr "Utwórz gradient w obszarze wypełnienia" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:662 +msgid "Create gradient in the stroke" +msgstr "Utwórz gradient w obszarze konturu" + +#. FIXME: implement averaging of all parameters for multiple selected stars +#. gtk_label_set_markup(GTK_LABEL(l), _("Average:")); +#. FIXME: implement averaging of all parameters for multiple selected +#. gtk_label_set_markup(GTK_LABEL(l), _("Average:")); +#: ../../po/../src/widgets/gradient-toolbar.cpp:676 +#: ../../po/../src/widgets/toolbox.cpp:1105 +#: ../../po/../src/widgets/toolbox.cpp:1124 +#: ../../po/../src/widgets/toolbox.cpp:1493 +#: ../../po/../src/widgets/toolbox.cpp:1518 +#: ../../po/../src/widgets/toolbox.cpp:1768 +#: ../../po/../src/widgets/toolbox.cpp:1787 +#: ../../po/../src/widgets/toolbox.cpp:2334 +#: ../../po/../src/widgets/toolbox.cpp:2354 +msgid "Change:" +msgstr "Zmiana:" + +#: ../../po/../src/widgets/gradient-vector.cpp:269 +msgid "No gradients in document" +msgstr "Brak gradientów w dokumencie" + +#: ../../po/../src/widgets/gradient-vector.cpp:275 +msgid "No gradient selected" +msgstr "Brak zaznaczonego gradientu" + +#: ../../po/../src/widgets/gradient-vector.cpp:532 +msgid "No stops in gradient" +msgstr "Brak punktów sterujących w gradiencie" + +#. TRANSLATORS: "Stop" means: a "phase" of a gradient +#: ../../po/../src/widgets/gradient-vector.cpp:794 +msgid "Add stop" +msgstr "Dodaj punkt" + +#: ../../po/../src/widgets/gradient-vector.cpp:797 +msgid "Add another control stop to gradient" +msgstr "Dodaje kolejny punkt sterujący do gradientu" + +#: ../../po/../src/widgets/gradient-vector.cpp:799 +msgid "Delete stop" +msgstr "Usuń punkt" + +#: ../../po/../src/widgets/gradient-vector.cpp:802 +msgid "Delete current control stop from gradient" +msgstr "Usuwa aktywny punkt sterujący z gradientu" + +#. Label +#: ../../po/../src/widgets/gradient-vector.cpp:813 +msgid "Offset:" +msgstr "Przesunięcie:" + +#. TRANSLATORS: "Stop" means: a "phase" of a gradient +#: ../../po/../src/widgets/gradient-vector.cpp:858 +msgid "Stop Color" +msgstr "Kolor w punkcie" + +#: ../../po/../src/widgets/gradient-vector.cpp:887 +msgid "Gradient editor" +msgstr "Edytor gradientu" + +#: ../../po/../src/widgets/layer-selector.cpp:119 +msgid "Toggle current layer visibility" +msgstr "Przełącza widocznośc aktywnej warstwy" + +#: ../../po/../src/widgets/layer-selector.cpp:139 +msgid "Lock or unlock current layer" +msgstr "Blokuje lub odblokowuje aktywną warstwę" + +#: ../../po/../src/widgets/layer-selector.cpp:142 +msgid "Current layer" +msgstr "Aktywna warstwa" + +#: ../../po/../src/widgets/layer-selector.cpp:553 +msgid "(root)" +msgstr "(root)" + +#: ../../po/../src/widgets/paint-selector.cpp:182 +#: ../../po/../src/widgets/paint-selector.cpp:561 +msgid "No paint" +msgstr "Bez rysowania" + +#: ../../po/../src/widgets/paint-selector.cpp:184 +#: ../../po/../src/widgets/paint-selector.cpp:629 +msgid "Flat color" +msgstr "Jednolity kolor" + +#: ../../po/../src/widgets/paint-selector.cpp:186 +#: ../../po/../src/widgets/paint-selector.cpp:696 +msgid "Linear gradient" +msgstr "Gradient liniowy" + +#: ../../po/../src/widgets/paint-selector.cpp:188 +#: ../../po/../src/widgets/paint-selector.cpp:699 +msgid "Radial gradient" +msgstr "Gradient koncentryczny" + +#: ../../po/../src/widgets/paint-selector.cpp:192 +msgid "Unset paint (make it undefined so it can be inherited)" +msgstr "" +"Wyzeruj wypełnienie (ustaw jako niezdefiniowane, co umożliwia późniejsze " +"dziedziczenie)" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/painting.html#FillRuleProperty +#: ../../po/../src/widgets/paint-selector.cpp:204 +msgid "" +"Any path self-intersections or subpaths create holes in the fill (fill-rule: " +"evenodd)" +msgstr "" +"Obszary nałożone lub ścieżki wewnątrz figury nie są wypełniane (zasada " +"nieparzystości)" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/painting.html#FillRuleProperty +#: ../../po/../src/widgets/paint-selector.cpp:215 +msgid "" +"Fill is solid unless a subpath is counterdirectional (fill-rule: nonzero)" +msgstr "" +"Wypełnienie przenika całą figurę, chyba że ścieżka składowa ma odwrócony " +"kierunek (zasada przenikania)" + +#: ../../po/../src/widgets/paint-selector.cpp:528 +msgid "No objects" +msgstr "Brak obiektów" + +#: ../../po/../src/widgets/paint-selector.cpp:539 +msgid "Multiple styles" +msgstr "Wiele stylów" + +#: ../../po/../src/widgets/paint-selector.cpp:550 +msgid "Paint is undefined" +msgstr "Wypełnienie niezdefiniowane" + +#: ../../po/../src/widgets/paint-selector.cpp:757 +msgid "No patterns in document" +msgstr "Brak deseni w dokumencie" + +#: ../../po/../src/widgets/paint-selector.cpp:872 +msgid "" +"Use Edit > Object(s) to Pattern to create a new pattern from " +"selection." +msgstr "" +"Użyj Edycja > Obiekt(y) na deseń aby utworzyć nowy wzór " +"wypełnienia z zaznaczonych obiektów." + +#: ../../po/../src/widgets/select-toolbar.cpp:426 +msgid "Now stroke width is scaled when objects are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:428 +msgid "Now stroke width is not scaled when objects are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:436 +msgid "" +"Now rounded rectangle corners are scaled when rectangles are " +"scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:438 +msgid "" +"Now rounded rectangle corners are not scaled when rectangles " +"are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:446 +msgid "" +"Now gradients are transformed along with their objects when " +"those are transformed (moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:448 +msgid "" +"Now gradients remain fixed when objects are transformed " +"(moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:456 +msgid "" +"Now patterns are transformed along with their objects when " +"those are transformed (moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:458 +msgid "" +"Now patterns remain fixed when objects are transformed (moved, " +"scaled, rotated, or skewed)." +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:506 +msgid "select_toolbar|X" +msgstr "X" + +#: ../../po/../src/widgets/select-toolbar.cpp:506 +msgid "Horizontal coordinate of selection" +msgstr "Pozioma współrzędna zaznaczenia" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:511 +msgid "select_toolbar|Y" +msgstr "Y" + +#: ../../po/../src/widgets/select-toolbar.cpp:511 +msgid "Vertical coordinate of selection" +msgstr "Pionowa współrzędna zaznaczenia" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:517 +msgid "select_toolbar|W" +msgstr "Szer." + +#: ../../po/../src/widgets/select-toolbar.cpp:517 +msgid "Width of selection" +msgstr "Szerokość zaznaczenia" + +#: ../../po/../src/widgets/select-toolbar.cpp:525 +msgid "Change both width and height by the same proportion" +msgstr "Zmiana szerokości i wysokości z zachowaniem proporcji" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:534 +msgid "select_toolbar|H" +msgstr "Wys." + +#: ../../po/../src/widgets/select-toolbar.cpp:534 +msgid "Height of selection" +msgstr "Wysokość zaznaczenia" + +#: ../../po/../src/widgets/sp-color-gtkselector.cpp:62 +msgid "System" +msgstr "System" + +#: ../../po/../src/widgets/sp-color-notebook.cpp:322 +msgid "RGBA_:" +msgstr "RGBA_:" + +#: ../../po/../src/widgets/sp-color-notebook.cpp:330 +msgid "Hexadecimal RGBA value of the color" +msgstr "Wartość szesnastkowa koloru RGBA" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "RGB" +msgstr "RGB" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "HSL" +msgstr "HSL" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "CMYK" +msgstr "CMYK" + +#: ../../po/../src/widgets/sp-color-scales.cpp:397 +msgid "_R" +msgstr "_R" + +#: ../../po/../src/widgets/sp-color-scales.cpp:398 +#: ../../po/../src/widgets/sp-color-scales.cpp:399 +msgid "Red" +msgstr "Czerwony" + +#: ../../po/../src/widgets/sp-color-scales.cpp:400 +msgid "_G" +msgstr "_G" + +#: ../../po/../src/widgets/sp-color-scales.cpp:401 +#: ../../po/../src/widgets/sp-color-scales.cpp:402 +msgid "Green" +msgstr "Zielony" + +#: ../../po/../src/widgets/sp-color-scales.cpp:403 +msgid "_B" +msgstr "_B" + +#: ../../po/../src/widgets/sp-color-scales.cpp:404 +#: ../../po/../src/widgets/sp-color-scales.cpp:405 +msgid "Blue" +msgstr "Niebieski" + +#. Label +#: ../../po/../src/widgets/sp-color-scales.cpp:406 +#: ../../po/../src/widgets/sp-color-scales.cpp:432 +#: ../../po/../src/widgets/sp-color-scales.cpp:463 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:141 +msgid "_A" +msgstr "_A" + +#: ../../po/../src/widgets/sp-color-scales.cpp:407 +#: ../../po/../src/widgets/sp-color-scales.cpp:408 +#: ../../po/../src/widgets/sp-color-scales.cpp:433 +#: ../../po/../src/widgets/sp-color-scales.cpp:434 +#: ../../po/../src/widgets/sp-color-scales.cpp:464 +#: ../../po/../src/widgets/sp-color-scales.cpp:465 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:151 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:163 +msgid "Alpha (opacity)" +msgstr "Alfa (przezroczystość)" + +#: ../../po/../src/widgets/sp-color-scales.cpp:423 +msgid "_H" +msgstr "_H" + +#: ../../po/../src/widgets/sp-color-scales.cpp:424 +#: ../../po/../src/widgets/sp-color-scales.cpp:425 +msgid "Hue" +msgstr "Odcień" + +#: ../../po/../src/widgets/sp-color-scales.cpp:426 +msgid "_S" +msgstr "_S" + +#: ../../po/../src/widgets/sp-color-scales.cpp:427 +#: ../../po/../src/widgets/sp-color-scales.cpp:428 +msgid "Saturation" +msgstr "Nasycenie" + +#: ../../po/../src/widgets/sp-color-scales.cpp:429 +msgid "_L" +msgstr "_L" + +#: ../../po/../src/widgets/sp-color-scales.cpp:430 +#: ../../po/../src/widgets/sp-color-scales.cpp:431 +msgid "Lightness" +msgstr "Jasność" + +#: ../../po/../src/widgets/sp-color-scales.cpp:451 +msgid "_C" +msgstr "_C" + +#: ../../po/../src/widgets/sp-color-scales.cpp:452 +#: ../../po/../src/widgets/sp-color-scales.cpp:453 +msgid "Cyan" +msgstr "Niebieskozielony" + +#: ../../po/../src/widgets/sp-color-scales.cpp:454 +msgid "_M" +msgstr "_M" + +#: ../../po/../src/widgets/sp-color-scales.cpp:455 +#: ../../po/../src/widgets/sp-color-scales.cpp:456 +msgid "Magenta" +msgstr "Purpurowy" + +#: ../../po/../src/widgets/sp-color-scales.cpp:457 +msgid "_Y" +msgstr "_Y" + +#: ../../po/../src/widgets/sp-color-scales.cpp:458 +#: ../../po/../src/widgets/sp-color-scales.cpp:459 +msgid "Yellow" +msgstr "Żółty" + +#: ../../po/../src/widgets/sp-color-scales.cpp:460 +msgid "_K" +msgstr "_K" + +#: ../../po/../src/widgets/sp-color-selector.cpp:71 +msgid "Unnamed" +msgstr "Nienazwany" + +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:68 +msgid "Wheel" +msgstr "Koło" + +#: ../../po/../src/widgets/sp-xmlview-attr-list.cpp:53 +msgid "Attribute" +msgstr "Atrybut" + +#: ../../po/../src/widgets/sp-xmlview-attr-list.cpp:54 +msgid "Value" +msgstr "Wartość" + +#: ../../po/../src/widgets/toolbox.cpp:424 +msgid "Insert new nodes into selected segments" +msgstr "Dołącza nowe węzły do zaznaczonych segmentów" + +#: ../../po/../src/widgets/toolbox.cpp:426 +msgid "Delete selected nodes" +msgstr "Usuwa zaznaczone węzły" + +#: ../../po/../src/widgets/toolbox.cpp:431 +msgid "Join paths at selected nodes" +msgstr "Łączy ścieżki w zaznaczonych węzłach" + +#: ../../po/../src/widgets/toolbox.cpp:433 +msgid "Join paths at selected nodes with new segment" +msgstr "Łączy ścieżki w zaznaczonych węzłach wstawiając nowy segment" + +#: ../../po/../src/widgets/toolbox.cpp:436 +msgid "Split path between two non-endpoint nodes" +msgstr "Dzieli ścieżkę pomiędzy dwoma nie końcowymi punktami" + +#: ../../po/../src/widgets/toolbox.cpp:439 +msgid "Break path at selected nodes" +msgstr "Rozcina ścieżkę w zaznaczonych węzłach" + +#: ../../po/../src/widgets/toolbox.cpp:444 +msgid "Make selected nodes corner" +msgstr "Zamienia zaznaczone węzły w ostre narożniki" + +#: ../../po/../src/widgets/toolbox.cpp:447 +msgid "Make selected nodes smooth" +msgstr "Zamienia zaznaczone węzły w gładkie zaokrąglenia" + +#: ../../po/../src/widgets/toolbox.cpp:450 +msgid "Make selected nodes symmetric" +msgstr "Ustawia symetrię zaznaczonych węzłów" + +#: ../../po/../src/widgets/toolbox.cpp:455 +msgid "Make selected segments lines" +msgstr "Zamienia zaznaczone segmenty na linie" + +#: ../../po/../src/widgets/toolbox.cpp:458 +msgid "Make selected segments curves" +msgstr "Zamienia zaznaczone segmenty na krzywe" + +#: ../../po/../src/widgets/toolbox.cpp:1199 +msgid "Polygon" +msgstr "Wielokąt" + +#: ../../po/../src/widgets/toolbox.cpp:1206 +msgid "Regular polygon (with one handle) instead of a star" +msgstr "Wielokąt foremny (z jednym uchwytem) zamiast gwiazdy" + +#: ../../po/../src/widgets/toolbox.cpp:1218 +msgid "Corners:" +msgstr "Narożniki:" + +#: ../../po/../src/widgets/toolbox.cpp:1218 +msgid "Number of corners of a polygon or star" +msgstr "Liczba narożników wielokąta lub gwiazdy" + +#: ../../po/../src/widgets/toolbox.cpp:1228 +msgid "Spoke ratio:" +msgstr "Proporcje ramion:" + +#. TRANSLATORS: Tip radius of a star is the distance from the center to the farthest handle. +#. Base radius is the same for the closest handle. +#: ../../po/../src/widgets/toolbox.cpp:1231 +msgid "Base radius to tip radius ratio" +msgstr "Stosunek promienia podstawy do promienia wierzchołków ramion" + +#: ../../po/../src/widgets/toolbox.cpp:1246 +msgid "Rounded:" +msgstr "Zaokrąglenie:" + +#: ../../po/../src/widgets/toolbox.cpp:1246 +msgid "How much rounded are the corners (0 for sharp)" +msgstr "Wartość zaokrąglenia narożników (0 dla ostrych)" + +#: ../../po/../src/widgets/toolbox.cpp:1256 +msgid "Randomized:" +msgstr "Deformacja losowa:" + +#: ../../po/../src/widgets/toolbox.cpp:1256 +msgid "Scatter randomly the corners and angles" +msgstr "Losowe zniekształcenie narożników i kątów" + +#: ../../po/../src/widgets/toolbox.cpp:1269 +#: ../../po/../src/widgets/toolbox.cpp:1838 +#: ../../po/../src/widgets/toolbox.cpp:2061 +msgid "Defaults" +msgstr "Domyślne" + +#: ../../po/../src/widgets/toolbox.cpp:1270 +#: ../../po/../src/widgets/toolbox.cpp:1839 +#: ../../po/../src/widgets/toolbox.cpp:2062 +msgid "" +"Reset shape parameters to defaults (use Inkscape Preferences > Tools to " +"change defaults)" +msgstr "" +"Przywraca domyślne ustawienia dla kształtu (użyj Ustawienia Inkscape > " +"Narzędzia aby zmienić domyślne wartości)" + +#: ../../po/../src/widgets/toolbox.cpp:1544 +msgid "W:" +msgstr "S:" + +#: ../../po/../src/widgets/toolbox.cpp:1544 +msgid "Width of rectangle" +msgstr "Szerokość prostokąta" + +#: ../../po/../src/widgets/toolbox.cpp:1556 +msgid "Height of rectangle" +msgstr "Wysokość prostokąta" + +#: ../../po/../src/widgets/toolbox.cpp:1568 +msgid "Rx:" +msgstr "Rx:" + +#: ../../po/../src/widgets/toolbox.cpp:1568 +msgid "Horizontal radius of rounded corners" +msgstr "Poziomy promień zaokrąglonych narożników" + +#: ../../po/../src/widgets/toolbox.cpp:1578 +msgid "Ry:" +msgstr "Ry:" + +#: ../../po/../src/widgets/toolbox.cpp:1578 +msgid "Vertical radius of rounded corners" +msgstr "Pionowy promień zaokrąglonych narożników" + +#: ../../po/../src/widgets/toolbox.cpp:1594 +msgid "Not rounded" +msgstr "Bez zaokrąglenia" + +#: ../../po/../src/widgets/toolbox.cpp:1596 +msgid "Make corners sharp" +msgstr "Ostre narożniki" + +#: ../../po/../src/widgets/toolbox.cpp:1805 +msgid "Turns:" +msgstr "Obroty:" + +#: ../../po/../src/widgets/toolbox.cpp:1805 +msgid "Number of revolutions" +msgstr "Liczba obrotów" + +#: ../../po/../src/widgets/toolbox.cpp:1815 +msgid "Divergence:" +msgstr "Zbieżność:" + +#: ../../po/../src/widgets/toolbox.cpp:1815 +msgid "How much denser/sparser are outer revolutions; 1 = uniform" +msgstr "Przyrost/zmniejszenie kroku w kolejnych obrotach; 1 = stały przyrost" + +#: ../../po/../src/widgets/toolbox.cpp:1825 +msgid "Inner radius:" +msgstr "Wewnętrzny promień:" + +#: ../../po/../src/widgets/toolbox.cpp:1825 +msgid "Radius of the innermost revolution (relative to the spiral size)" +msgstr "Promień wewnętrznego odcinka (względem wielkości spirali)" + +#: ../../po/../src/widgets/toolbox.cpp:1957 +msgid "The width of the calligraphic pen (relative to the visible canvas area)" +msgstr "Grubość pisma kaligraficznego (względem widocznego obszaru pracy)" + +#: ../../po/../src/widgets/toolbox.cpp:1967 +msgid "Thinning:" +msgstr "Pocienienie:" + +#: ../../po/../src/widgets/toolbox.cpp:1967 +msgid "" +"How much velocity thins the stroke (> 0 makes fast strokes thinner, < 0 " +"makes them broader, 0 makes width independent of velocity)" +msgstr "" +"W jakim stopniu prędkość wpływa na pocienienie konturu (> 0 pocienia szybkie " +"linie, < 0 pogrubia je, 0 uniezależnia grubość od prędkości)" + +#: ../../po/../src/widgets/toolbox.cpp:1980 +msgid "Angle:" +msgstr "Kąt:" + +#: ../../po/../src/widgets/toolbox.cpp:1980 +msgid "" +"The angle of the pen's nib (in degrees; 0 = horizontal; has no effect if " +"fixation = 0)" +msgstr "" +"Kąt stalówki pióra (w stopniach; 0 = poziomo; nie daje efektu jeśli Ułożenie " +"= 0)" + +#: ../../po/../src/widgets/toolbox.cpp:1990 +msgid "Fixation:" +msgstr "Ułożenie:" + +#: ../../po/../src/widgets/toolbox.cpp:1990 +msgid "" +"How fixed is the pen angle (0 = always perpendicular to stroke direction, 1 " +"= fixed)" +msgstr "" +"Zachowanie kąta stalówki (0 = zawsze prostopadle do kierunku linii, 1 = " +"zachowanie wybranego kąta)" + +#: ../../po/../src/widgets/toolbox.cpp:2003 +msgid "Mass:" +msgstr "Masa:" + +#: ../../po/../src/widgets/toolbox.cpp:2003 +msgid "How much inertia affects the movement of the pen" +msgstr "Wpływ bezwładności na ruch pióra" + +#. TRANSLATORS: "drag" means "resistance" here +#: ../../po/../src/widgets/toolbox.cpp:2014 +msgid "Drag:" +msgstr "Opór:" + +#: ../../po/../src/widgets/toolbox.cpp:2014 +msgid "How much resistance affects the movement of the pen" +msgstr "Wpływ oporu podłoża na ruch pióra" + +#: ../../po/../src/widgets/toolbox.cpp:2034 +msgid "Use the pressure of the input device to alter the width of the pen" +msgstr "Zastosuj siłę nacisku urządzenia wejściowego do zmiany grubości kreski" + +#: ../../po/../src/widgets/toolbox.cpp:2047 +msgid "Use the tilt of the input device to alter the angle of the pen's nib" +msgstr "" +"Zastosuj pochylenie urządzenia wejściowego do zmiany kąta ustawienia stalówki" + +#: ../../po/../src/widgets/toolbox.cpp:2374 +msgid "Start:" +msgstr "Początek:" + +#: ../../po/../src/widgets/toolbox.cpp:2374 +msgid "The angle (in degrees) from the horizontal to the arc's start point" +msgstr "Kąt (w stopniach) od poziomu do punktu początkowego łuku" + +#: ../../po/../src/widgets/toolbox.cpp:2384 +msgid "End:" +msgstr "Koniec:" + +#: ../../po/../src/widgets/toolbox.cpp:2384 +msgid "The angle (in degrees) from the horizontal to the arc's end point" +msgstr "Kąt (w stopniach) od poziomu do punktu końcowego łuku" + +#: ../../po/../src/widgets/toolbox.cpp:2395 +msgid "Open arc" +msgstr "Łuk otwarty" + +#: ../../po/../src/widgets/toolbox.cpp:2396 +msgid "" +"Switch between arc (unclosed shape) and segment (closed shape with two radii)" +msgstr "" +"Przełącza pomiędzy łukiem (otwartym kształtem) a wycinkiem elipsy " +"(zamkniętym kształtem z dwoma promienistymi odcinkami)" + +#: ../../po/../src/widgets/toolbox.cpp:2415 +msgid "Make whole" +msgstr "Pełny kształt" + +#: ../../po/../src/widgets/toolbox.cpp:2417 +msgid "Make the shape a whole ellipse, not arc or segment" +msgstr "Zamień na pełną elipsę, zamiast łuku lub wycinka elipsy" + +#: ../../po/../src/widgets/toolbox.cpp:2644 +msgid "" +"When pressed, picks visible color without alpha and when not pressed, picks " +"color including its alpha" +msgstr "" +"Wciśnięty przycisk oznacza pobieranie koloru widocznego, bez " +"przezroczystości; nie wciśnięty - koloru wraz z przezroczystością" + +#: ../../po/../src/widgets/toolbox.cpp:3039 +msgid "Make connectors avoid selected objects" +msgstr "Omijanie zaznaczonych obiektów przez łączniki" + +#: ../../po/../src/widgets/toolbox.cpp:3043 +msgid "Make connectors ignore selected objects" +msgstr "Przechodzenie łączników przez zaznaczone obiekty" + +#. +#. 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 : +#: ../share/extensions/addnodes.inx.h:1 +#, fuzzy +msgid "Add Nodes" +msgstr "Węzły" + +#: ../share/extensions/addnodes.inx.h:2 +msgid "Maximum Segment Length" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:1 +msgid "AI Input" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:2 ../share/extensions/ai_output.inx.h:2 +msgid "Adobe Illustrator (*.ai)" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:3 +msgid "Open files saved with Adobe Illustrator" +msgstr "" + +#: ../share/extensions/ai_output.inx.h:1 +#, fuzzy +msgid "AI Output" +msgstr "Wyjście" + +#: ../share/extensions/ai_output.inx.h:3 +#, fuzzy +msgid "Write Adobe Illustrator" +msgstr "Program do tworzenia ilustracji wektorowych" + +#: ../share/extensions/dia.inx.h:1 +msgid "A diagram created with the program Dia" +msgstr "" + +#: ../share/extensions/dia.inx.h:2 +msgid "Dia Diagram (*.dia)" +msgstr "" + +#: ../share/extensions/dia.inx.h:3 +msgid "Dia Input" +msgstr "" + +#: ../share/extensions/dia.inx.h:4 +msgid "" +"In order to import Dia files, Dia itself must be installed. You can get Dia " +"at http://www.gnome.org/projects/dia/" +msgstr "" + +#: ../share/extensions/dia.inx.h:5 +msgid "" +"The dia2svg.sh script should be installed with your Inkscape distribution. " +"If you do not have it, there is likely to be something wrong with your " +"Inkscape installation." +msgstr "" + +#: ../share/extensions/dots.inx.h:1 +#, fuzzy +msgid "Connect the Dots" +msgstr "Łącznik" + +#: ../share/extensions/dots.inx.h:2 +#, fuzzy +msgid "Dot Size" +msgstr "Rozmiar" + +#: ../share/extensions/dots.inx.h:3 +#, fuzzy +msgid "Font Size" +msgstr "Rozmiar czcionki:" + +#: ../share/extensions/dropshadow.inx.h:1 +msgid "Color of shadow" +msgstr "" + +#: ../share/extensions/dropshadow.inx.h:2 +#, fuzzy +msgid "Dropshadow" +msgstr "Wyświetlanie cienia strony" + +#: ../share/extensions/dxf_input.inx.h:1 +#: ../share/extensions/dxf_output.inx.h:1 +msgid "AutoCAD DXF (*.dxf)" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:2 +msgid "DXF Input" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:3 +msgid "Import AutoCAD's Document Exchange Format" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:4 +msgid "" +"dxf2svg may come with Inkscape, but is also at http://dxf-svg-convert." +"sourceforge.net/" +msgstr "" + +#: ../share/extensions/dxf_output.inx.h:2 +#, fuzzy +msgid "DXF Output" +msgstr "Wyjście" + +#: ../share/extensions/dxf_output.inx.h:3 +msgid "DXF file written by pstoedit" +msgstr "" + +#: ../share/extensions/dxf_output.inx.h:4 +msgid "pstoedit must be installed to run see http://www.pstoedit.net/pstoedit" +msgstr "" + +#: ../share/extensions/embedimage.inx.h:1 +#, fuzzy +msgid "Embed Images" +msgstr "Obrazy" + +#: ../share/extensions/eps_input.inx.h:1 +msgid "EPS Input" +msgstr "" + +#: ../share/extensions/eps_input.inx.h:2 +msgid "Encapsulated Postscript" +msgstr "" + +#: ../share/extensions/eps_input.inx.h:3 +msgid "Encapsulated Postscript (*.eps)" +msgstr "" + +#: ../share/extensions/epsi_output.inx.h:1 +#, fuzzy +msgid "EPSI Output" +msgstr "Wyjście" + +#: ../share/extensions/epsi_output.inx.h:2 +msgid "Encapsulated Postscript Interchange (*.epsi)" +msgstr "" + +#: ../share/extensions/epsi_output.inx.h:3 +msgid "Encapsulated Postscript with a thumbnail" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:1 ../share/extensions/ffms.inx.h:1 +#: ../share/extensions/ffset.inx.h:1 ../share/extensions/ffss.inx.h:1 +#, fuzzy +msgid "Bridge Width" +msgstr "Grubość linii" + +#: ../share/extensions/ffmet.inx.h:2 ../share/extensions/ffms.inx.h:2 +msgid "First String Length" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:3 +msgid "FretFind Multi Length ET" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:4 ../share/extensions/ffms.inx.h:4 +#: ../share/extensions/ffset.inx.h:3 ../share/extensions/ffss.inx.h:3 +msgid "Fretboard Edges" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:5 ../share/extensions/ffms.inx.h:5 +msgid "Last String Length" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:6 ../share/extensions/ffms.inx.h:6 +#: ../share/extensions/ffset.inx.h:4 ../share/extensions/ffss.inx.h:4 +#, fuzzy +msgid "Number of Frets" +msgstr "Liczba rzędów" + +#: ../share/extensions/ffmet.inx.h:7 ../share/extensions/ffms.inx.h:7 +#: ../share/extensions/ffset.inx.h:5 ../share/extensions/ffss.inx.h:5 +#, fuzzy +msgid "Number of Strings" +msgstr "Liczba rzędów" + +#: ../share/extensions/ffmet.inx.h:8 ../share/extensions/ffms.inx.h:8 +#: ../share/extensions/ffset.inx.h:6 ../share/extensions/ffss.inx.h:6 +#, fuzzy +msgid "Nut Width" +msgstr "Szerokość" + +#: ../share/extensions/ffmet.inx.h:9 ../share/extensions/ffms.inx.h:10 +msgid "Perpendicular Distance" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:10 ../share/extensions/ffset.inx.h:7 +msgid "Scale Base (2 for Octave)" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:11 ../share/extensions/ffset.inx.h:9 +msgid "Tones in Scale" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:12 ../share/extensions/ffms.inx.h:12 +#: ../share/extensions/ffset.inx.h:10 ../share/extensions/ffss.inx.h:10 +msgid "px per Unit" +msgstr "" + +#: ../share/extensions/ffms.inx.h:3 +msgid "FretFind Multi Length Scala" +msgstr "" + +#: ../share/extensions/ffms.inx.h:9 ../share/extensions/ffss.inx.h:7 +msgid "Path to Scala *.scl File" +msgstr "" + +#: ../share/extensions/ffms.inx.h:11 +msgid "Tuning (scale step for each string seperated by semicolons)" +msgstr "" + +#: ../share/extensions/ffset.inx.h:2 +msgid "FretFind Single Length ET" +msgstr "" + +#: ../share/extensions/ffset.inx.h:8 ../share/extensions/ffss.inx.h:8 +msgid "Scale Length" +msgstr "" + +#: ../share/extensions/ffss.inx.h:2 +msgid "FretFind Single Length Scala" +msgstr "" + +#: ../share/extensions/ffss.inx.h:9 +msgid "Tuning (Scale step for each string seperated by semicolons)" +msgstr "" + +#: ../share/extensions/handles.inx.h:1 +#, fuzzy +msgid "Draw Handles" +msgstr "Rysuje krzywe odręczne" + +#: ../share/extensions/interp.inx.h:1 +#, fuzzy +msgid "Duplicate Endpaths" +msgstr "Duplikuj węzeł" + +#: ../share/extensions/interp.inx.h:2 +#, fuzzy +msgid "Exponent" +msgstr "Eksport" + +#: ../share/extensions/interp.inx.h:3 +msgid "Interpolate" +msgstr "" + +#: ../share/extensions/interp.inx.h:4 +msgid "Interpolate Style (Experimental)" +msgstr "" + +#: ../share/extensions/interp.inx.h:5 +msgid "Interpolation Method" +msgstr "" + +#: ../share/extensions/interp.inx.h:6 +msgid "Interpolation Steps" +msgstr "" + +#: ../share/extensions/kochify.inx.h:1 +msgid "Kochify" +msgstr "" + +#: ../share/extensions/kochify_load.inx.h:1 +msgid "Kochify (Load)" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:1 +#, fuzzy +msgid "Angle" +msgstr "Kąt:" + +#: ../share/extensions/lindenmayer.inx.h:2 +msgid "Axiom" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:3 +#, fuzzy +msgid "Lindenmayer" +msgstr "Zmiana nazwy warstwy" + +#: ../share/extensions/lindenmayer.inx.h:4 +msgid "Order" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:5 +#, fuzzy +msgid "Rules" +msgstr "_Linijki" + +#: ../share/extensions/lindenmayer.inx.h:6 +#, fuzzy +msgid "Step" +msgstr "Kroki" + +#: ../share/extensions/motion.inx.h:1 +#, fuzzy +msgid "Direction" +msgstr "Opis" + +#: ../share/extensions/motion.inx.h:2 +#, fuzzy +msgid "Magnitude" +msgstr "Purpurowy" + +#: ../share/extensions/motion.inx.h:3 +#, fuzzy +msgid "Motion" +msgstr "_Obrót" + +#: ../share/extensions/pdf_output.inx.h:1 +msgid "Adobe PDF (*.pdf)" +msgstr "" + +#: ../share/extensions/pdf_output.inx.h:2 +msgid "Adobe Portable Document Format" +msgstr "" + +#: ../share/extensions/pdf_output.inx.h:3 +#, fuzzy +msgid "PDF Output" +msgstr "Wyjście" + +#: ../share/extensions/ps_input.inx.h:1 +#, fuzzy +msgid "Postscript" +msgstr "Pionowa" + +#: ../share/extensions/ps_input.inx.h:2 +msgid "Postscript (*.ps)" +msgstr "" + +#: ../share/extensions/ps_input.inx.h:3 +msgid "Postscript Input" +msgstr "" + +#: ../share/extensions/radiusrand.inx.h:1 +#, fuzzy +msgid "Radius" +msgstr "Promień:" + +#: ../share/extensions/radiusrand.inx.h:2 +#, fuzzy +msgid "Radius Randomize" +msgstr "Wartość losowa:" + +#: ../share/extensions/radiusrand.inx.h:3 +msgid "Randomize Control Points" +msgstr "" + +#: ../share/extensions/radiusrand.inx.h:4 +#, fuzzy +msgid "Randomize Nodes" +msgstr "Deformacja losowa:" + +#: ../share/extensions/rtree.inx.h:1 +#, fuzzy +msgid "Initial Size" +msgstr "Rozmiar bitmapy" + +#: ../share/extensions/rtree.inx.h:2 +msgid "Minimum Size" +msgstr "" + +#: ../share/extensions/rtree.inx.h:3 +#, fuzzy +msgid "Random Tree" +msgstr "Wartość losowa:" + +#: ../share/extensions/sk_input.inx.h:1 +msgid "A diagram created with the program Sketch" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:2 +msgid "Sketch Diagram (*.sk)" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:3 +msgid "Sketch Input" +msgstr "" + +#: ../share/extensions/straightseg.inx.h:1 +msgid "Behavior" +msgstr "" + +#: ../share/extensions/straightseg.inx.h:3 +msgid "Segment Straightener" +msgstr "" + +#: ../share/extensions/summersnight.inx.h:1 +msgid "Summer's Night" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:1 +#: ../share/extensions/svgz_output.inx.h:1 +msgid "Compressed Inkscape SVG (*.svgz)" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:2 +#: ../share/extensions/svgz_output.inx.h:2 +msgid "Inkscape's native file format compressed with GZip" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:3 +msgid "SVGZ Input" +msgstr "" + +#: ../share/extensions/svgz_output.inx.h:3 +#, fuzzy +msgid "SVGZ Output" +msgstr "Wyjście" + +#: ../share/extensions/txt2svg.inx.h:1 +msgid "ASCII Text" +msgstr "" + +#: ../share/extensions/txt2svg.inx.h:2 +msgid "Text File (*.txt)" +msgstr "" + +#: ../share/extensions/txt2svg.inx.h:3 +#, fuzzy +msgid "Text Input" +msgstr "_Następne powiększenie" + +#: ../share/extensions/wavy.inx.h:1 +msgid "Calculate first derivative numerically" +msgstr "" + +#: ../share/extensions/wavy.inx.h:2 +msgid "First derivative" +msgstr "" + +#: ../share/extensions/wavy.inx.h:3 +msgid "Function" +msgstr "" + +#: ../share/extensions/wavy.inx.h:4 +msgid "Function Plotter" +msgstr "" + +#: ../share/extensions/wavy.inx.h:5 +msgid "Nodes per period" +msgstr "" + +#: ../share/extensions/wavy.inx.h:6 +msgid "Periods (2*Pi each)" +msgstr "" + +#: ../share/extensions/whirl.inx.h:1 +msgid "Amount of Whirl" +msgstr "" + +#: ../share/extensions/whirl.inx.h:2 +#, fuzzy +msgid "Center X" +msgstr "Środek X:" + +#: ../share/extensions/whirl.inx.h:3 +#, fuzzy +msgid "Center Y" +msgstr "Środek Y:" + +#: ../share/extensions/whirl.inx.h:4 +#, fuzzy +msgid "Direction of Rotation" +msgstr "Odrzuć zaproszenie" + +#: ../share/extensions/whirl.inx.h:5 +msgid "Whirl" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:1 +msgid "A popular graphics file format for clipart" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:2 +msgid "Windows Metafile (*.wmf)" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:3 +msgid "Windows Metafile Input" +msgstr "" + +#~ msgid "Custom canvas" +#~ msgstr "Rozmiar użytkownika" + +#~ msgid "Current style" +#~ msgstr "Aktualny styl" + +#~ msgid "" +#~ "Current style is updated every time you change the style of any object " +#~ "(its fill, stroke, transparency, etc.)" +#~ msgstr "" +#~ "Aktualny styl jest zapisywany przy każdej zmianie stylu dowolnego obiektu " +#~ "(jego wypełnienia, konturu, przezroczystości, itd.)" + +#~ msgid "Arrange Objects" +#~ msgstr "Rozmieść obiekty" + +#~ msgid "deg" +#~ msgstr "stopnie" + +#~ msgid "" +#~ "%s is not a valid preferences file.\n" +#~ "%s" +#~ msgstr "" +#~ "%s nie jest poprawnym plikiem ustawień.\n" +#~ "%s" + +#~ msgid "" +#~ "Inkscape will run with default settings.\n" +#~ "New settings will not be saved." +#~ msgstr "" +#~ "Inkscape zostanie uruchomiony z domyślnymi ustawieniami.\n" +#~ "Nowe ustawienia nie zostaną zapisane." + +#~ msgid "_Credits" +#~ msgstr "_Podziękowania" + +#~ msgid "Grab sensitivity" +#~ msgstr "Czułość chwytania" + +#~ msgid "Click/drag threshold" +#~ msgstr "Próg kliknięcia/przeciągania" + +#~ msgid "Mouse wheel scrolls by" +#~ msgstr "Kółko myszy przewija o" + +#~ msgid "Scroll by" +#~ msgstr "Przewijanie o" + +#~ msgid "Acceleration" +#~ msgstr "Przyspieszenie" + +#~ msgid "Speed" +#~ msgstr "Prędkość" + +#~ msgid "Threshold" +#~ msgstr "Próg" + +#~ msgid "Arrow keys move by" +#~ msgstr "Klawisze strzałek przesuwają o" + +#~ msgid "> and < scale by" +#~ msgstr "Klawisze > i < zmieniają rozmiar o" + +#~ msgid "Inset/Outset by" +#~ msgstr "Odsunięcie na zewnątrz/do środka o" + +#~ msgid "Rotation snaps every" +#~ msgstr "Zatrzymywanie obrotu co" + +#~ msgid "Zoom in/out by" +#~ msgstr "Powiększenie/pomniejszenie o" + +#~ msgid "Transform" +#~ msgstr "Przekształcenie" + +#~ msgid "Rotate _90 deg CW" +#~ msgstr "_Obróć o 90 stopni w prawo" + +#~ msgid "Rotate 9_0 deg CCW" +#~ msgstr "O_bróć o 90 stopni w lewo" + +#~ msgid "Flip selection horizontally" +#~ msgstr "Odbija zaznaczone obiekty w poziomie" + +#~ msgid "Flip selection vertically" +#~ msgstr "Odbija zaznaczone obiekty w pionie" + +#, fuzzy +#~ msgid "Could not read next message due to I/O error (error: %s)!" +#~ msgstr "Nie udało się utworzyć pliku dziennika '%s' dla wtyczki" + +#~ msgid "Open one of the recently visited documents" +#~ msgstr "Otwiera jeden z ostatnio używanych dokumentów" + +#~ msgid "" +#~ "Show or hide parts of the document window (differently for normal and " +#~ "fullscreen modes)" +#~ msgstr "" +#~ "Wyświetla lub ukrywa elementy okna dokumentu (działa inaczej w trybie " +#~ "pełnoekranowym)" + +#~ msgid "Interactive Inkscape tutorials" +#~ msgstr "Interaktywne przewodniki po programie Inkscape" + +#~ msgid "Modifying or Redistributing Inkscape" +#~ msgstr "Modyfikowanie lub redystrybucja programu Inkscape" + +#~ msgid "Show license to modify and/or redistribute Inkscape: GNU GPL" +#~ msgstr "" +#~ "Pokaż licencję na modyfikowanie i/lub redystrybucję programu Inkscape: " +#~ "GNU GPL" + +#~ msgid "Edit" +#~ msgstr "Edycja" + +#~ msgid "Add" +#~ msgstr "Dodaj" + +#~ msgid "" +#~ "Select one path object with selector first, then switch back to node tool." +#~ msgstr "" +#~ "Wybierz najpierw jedną ścieżkę narzędziem 'wskaźnik', a następnie wróć do " +#~ "narzędzia edycji węzłów" + +#~ msgid "C_reate" +#~ msgstr "_Utwórz" + +#, fuzzy +#~ msgid "Automatically scale Rows to fit selected objects." +#~ msgstr "" +#~ "Różnica symetryczna wybranych obiektów (obszary nakładające się zostają " +#~ "usunięte)" + +#~ msgid "Go to root" +#~ msgstr "Przejdź do początku" + +#, fuzzy +#~ msgid "X" +#~ msgstr "X:" + +#, fuzzy +#~ msgid "Y" +#~ msgstr "Y:" + +#~ msgid "Sides:" +#~ msgstr "Ramiona:" + +#~ msgid "R1:" +#~ msgstr "R1:" + +#~ msgid "R2:" +#~ msgstr "R2:" + +#~ msgid "ARG1:" +#~ msgstr "ARG1:" + +#~ msgid "ARG2:" +#~ msgstr "ARG2:" + +#~ msgid "Flatsides:" +#~ msgstr "Płaskie boki:" + +#~ msgid "Radius X:" +#~ msgstr "Promień X:" + +#~ msgid "Radius Y:" +#~ msgstr "Promień Y:" + +#~ msgid "Start Angle:" +#~ msgstr "Kąt początkowy:" + +#~ msgid "End Angle:" +#~ msgstr "Kąt końcowy:" + +#~ msgid "Open:" +#~ msgstr "Otwarta:" + +#~ msgid "Expansion:" +#~ msgstr "Przyrost:" + +#~ msgid "Revolutions:" +#~ msgstr "Obroty:" + +#~ msgid "Argument:" +#~ msgstr "Argument::" + +#~ msgid "T0:" +#~ msgstr "T0:" + +#~ msgid "RX:" +#~ msgstr "RX:" + +#~ msgid "RY:" +#~ msgstr "RY:" + +#~ msgid "Rectangle _Properties" +#~ msgstr "Wł_aściwości prostokąta" + +#~ msgid "Star _Properties" +#~ msgstr "Wł_aściwości gwiazdy" + +#~ msgid "Ellipse _Properties" +#~ msgstr "Wł_aściwości elipsy" + +#~ msgid "Spiral _Properties" +#~ msgstr "Wł_aściwości spirali" + +#, fuzzy +#~ msgid "Document Preferences" +#~ msgstr "U_stawienia dokumentu..." + +#, fuzzy +#~ msgid "Extensions Editor" +#~ msgstr "Rozszerzenie \"" + +#, fuzzy +#~ msgid "Preferences" +#~ msgstr " Ustawienia" + +#, fuzzy +#~ msgid "Layer Editor" +#~ msgstr "Edytor XML-u" + +#, fuzzy +#~ msgid "Text Properties" +#~ msgstr "Właściwości _obiektu" + +#, fuzzy +#~ msgid "Transformation" +#~ msgstr "Macierz przekształcenia" + +#, fuzzy +#~ msgid "_Export..." +#~ msgstr "_Importuj" + +#, fuzzy +#~ msgid "_Document Properties" +#~ msgstr "Przywrócono dokument." + +#, fuzzy +#~ msgid "In_kscape Preferences" +#~ msgstr "Us_tawienia Inkscape..." + +#, fuzzy +#~ msgid "Select _Original Clone" +#~ msgstr "Zaznacz ory_ginał" + +#, fuzzy +#~ msgid "Tile" +#~ msgstr "Tytuł" + +#, fuzzy +#~ msgid "Select A_ll" +#~ msgstr "Z_aznacz wszystko" + +#, fuzzy +#~ msgid "Select Non_e" +#~ msgstr "Zaznaczenie" + +#, fuzzy +#~ msgid "Zoom _In" +#~ msgstr "Powiększenie" + +#, fuzzy +#~ msgid "Zoom _Out" +#~ msgstr "Pomniejszenie" + +#, fuzzy +#~ msgid "Pre_vious" +#~ msgstr "P_oprzednie powiększenie" + +#, fuzzy +#~ msgid "Nex_t" +#~ msgstr "_Następne powiększenie" + +#, fuzzy +#~ msgid "_Commands bar" +#~ msgstr "Pasek poleceń" + +#, fuzzy +#~ msgid "Tool Co_ntrols bar" +#~ msgstr "Opcje narzędzi" + +#, fuzzy +#~ msgid "_Tools bar" +#~ msgstr "Paleta narzędzi" + +#, fuzzy +#~ msgid "R_ename Layer..." +#~ msgstr "_Zmień nazwę warstwy..." + +#, fuzzy +#~ msgid "D_uplicate Layer" +#~ msgstr "Duplikuj węzeł" + +#, fuzzy +#~ msgid "_Anchor Layer" +#~ msgstr "Przesuń warstwę do _tyłu" + +#, fuzzy +#~ msgid "_Delete Layer" +#~ msgstr "Warstwa usunięta." + +#, fuzzy +#~ msgid "Select Ne_xt Layer" +#~ msgstr "Przejdź do n_astępnej warstwy" + +#, fuzzy +#~ msgid "Select Pre_vious Layer" +#~ msgstr "Przejdź do p_oprzedniej warstwy" + +#, fuzzy +#~ msgid "Select To_p Layer" +#~ msgstr "Wybierz drukarkę" + +#, fuzzy +#~ msgid "Move to Ne_w Layer" +#~ msgstr "Przeniesiono do następnej warstwy." + +#, fuzzy +#~ msgid "Move to Ne_xt Layer" +#~ msgstr "Przeniesiono do następnej warstwy." + +#, fuzzy +#~ msgid "Move to Pre_vious Layer" +#~ msgstr "Przeniesiono do poprzedniej warstwy." + +#, fuzzy +#~ msgid "Move to To_p Layer" +#~ msgstr "Przeniesiono do następnej warstwy." + +#, fuzzy +#~ msgid "Move to B_ottom Layer" +#~ msgstr "Przeniesiono do następnej warstwy." + +#, fuzzy +#~ msgid "_Trace Bitmap..." +#~ msgstr "Wektoryzuj _bitmapę..." + +#, fuzzy +#~ msgid "_Put Text on Path" +#~ msgstr "Wstawia tekst na ścieżkę" + +#, fuzzy +#~ msgid "_Remove Text from Path" +#~ msgstr "Zdejmuje tekst ze ścieżki" + +#, fuzzy +#~ msgid "Freehand" +#~ msgstr "Zakończono rysowanie krzywej" + +#, fuzzy +#~ msgid "Stroke" +#~ msgstr "Grubość konturu" + +#, fuzzy +#~ msgid "Corners" +#~ msgstr "Narożniki:" + +#, fuzzy +#~ msgid "Delete" +#~ msgstr "_Usuń" + +#, fuzzy +#~ msgid "Join" +#~ msgstr "Połączenie:" + +#, fuzzy +#~ msgid "Delete Segment" +#~ msgstr "Usuwa zaznaczone obiekty" + +#, fuzzy +#~ msgid "Break" +#~ msgstr "Czarny" + +#, fuzzy +#~ msgid "Symmetric" +#~ msgstr "symetrycznie" + +#, fuzzy +#~ msgid "Line" +#~ msgstr "Licencja" + +#, fuzzy +#~ msgid "New" +#~ msgstr "_Nowy" + +#, fuzzy +#~ msgid "Save" +#~ msgstr "_Zapisz" + +#, fuzzy +#~ msgid "Save As..." +#~ msgstr "Z_apisz jako..." + +#, fuzzy +#~ msgid "Import..." +#~ msgstr "_Importuj" + +#, fuzzy +#~ msgid "Export..." +#~ msgstr "Eksport" + +#, fuzzy +#~ msgid "Print..." +#~ msgstr "_Drukuj..." + +#, fuzzy +#~ msgid "Global Inkscape preferences (Shift+Ctrl+P)" +#~ msgstr "Ustawienia programu Inkscape" + +#, fuzzy +#~ msgid "Undo" +#~ msgstr "_Cofnij" + +#, fuzzy +#~ msgid "Redo" +#~ msgstr "_Przywróć" + +#, fuzzy +#~ msgid "Cut" +#~ msgstr "Wy_tnij" + +#, fuzzy +#~ msgid "Copy" +#~ msgstr "_Kopiuj" + +#, fuzzy +#~ msgid "Duplicate selected object(s) (Ctrl+D)" +#~ msgstr "Duplikuje zaznaczone obiekty" + +#, fuzzy +#~ msgid "Clone selected object (Alt+D)" +#~ msgstr "Duplikuje zaznaczone obiekty" + +#, fuzzy +#~ msgid "Zoom in (+)" +#~ msgstr "Powiększenie" + +#, fuzzy +#~ msgid "Zoom out (-)" +#~ msgstr "Pomniejszenie" + +#, fuzzy +#~ msgid "Zoom to 1:1 (100%) (1)" +#~ msgstr "Ustawia współczynnik powiększenia na 1:1" + +#, fuzzy +#~ msgid "Zoom to 1:2 (50%) (2)" +#~ msgstr "Ustawia współczynnik powiększenia na 1:2" + +#, fuzzy +#~ msgid "Zoom to 2:1 (200%) (0)" +#~ msgstr "Ustawia współczynnik powiększenia na 2:1" + +#, fuzzy +#~ msgid "Zoom to fit selection in window (3)" +#~ msgstr "Dopasowuje rozmiar całego zaznaczenia do okna" + +#, fuzzy +#~ msgid "Zoom to fit drawing in window (4)" +#~ msgstr "Dopasowuje rozmiar całego rysunku do okna" + +#, fuzzy +#~ msgid "Zoom to fit page in window (5)" +#~ msgstr "Dopasowuje rozmiar całej strony do okna" + +#, fuzzy +#~ msgid "Zoom to fit page width in window (6)" +#~ msgstr "Dopasowuje szerokość strony do okna" + +#, fuzzy +#~ msgid "Previous zoom (from history of zooms) (`)" +#~ msgstr "Poprzednie powiększenie (z listy zapamiętanych powiększeń)" + +#, fuzzy +#~ msgid "Next zoom (from history of zooms) (Shift+`)" +#~ msgstr "Następne powiększenie (z listy zapamiętanych powiększeń)" + +#, fuzzy +#~ msgid "Fill and Stroke dialog (Shift+Ctrl+F)" +#~ msgstr "Wyświetla okno dialogowe Wypełnienie i kontur" + +#, fuzzy +#~ msgid "Group selected objects (Ctrl+G)" +#~ msgstr "Grupuje zaznaczone obiekty" + +#, fuzzy +#~ msgid "Ungroup selected group(s) (Ctrl+U)" +#~ msgstr "Rozgrupowuje zaznaczone obiekty" + +#, fuzzy +#~ msgid "Raise selection up one step (PgUp)" +#~ msgstr "Przesuwa zaznaczone obiekty o jedną pozycję do przodu" + +#, fuzzy +#~ msgid "Lower selection down one step (PgDn)" +#~ msgstr "Przesuwa zaznaczone obiekty o jedną pozycję do tyłu" + +#, fuzzy +#~ msgid "Raise selection to top (Home)" +#~ msgstr "Przenosi zaznaczone obiekty na wierzch" + +#, fuzzy +#~ msgid "Lower selection to bottom (End)" +#~ msgstr "Przenosi zaznaczone obiekty pod spód" + +#, fuzzy +#~ msgid "Move selection to new layer" +#~ msgstr "Przesuwa zaznaczone obiekty o jedną pozycję do tyłu" + +#, fuzzy +#~ msgid "Move selection to next layer" +#~ msgstr "Przeniesiono do następnej warstwy." + +#, fuzzy +#~ msgid "Move selection to previous layer" +#~ msgstr "Przeniesiono do poprzedniej warstwy." + +#, fuzzy +#~ msgid "Move selection to top layer" +#~ msgstr "Przenosi zaznaczone obiekty na wierzch" + +#, fuzzy +#~ msgid "Move selection to bottom layer" +#~ msgstr "Przenosi zaznaczone obiekty pod spód" + +#, fuzzy +#~ msgid "Rotate selection 90° clockwise (Shift+Ctrl+Right)" +#~ msgstr "" +#~ "Obraca zaznaczone obiekty o 90 stopni zgodnie z ruchem wskazówek zegara" + +#, fuzzy +#~ msgid "Rotate selection 90° counter-clockwise (Shift+Ctrl+Left)" +#~ msgstr "" +#~ "Obraca zaznaczone obiekty o 90 stopni przeciwnie do ruchu wskazówek zegara" + +#, fuzzy +#~ msgid "Flip selection horizontally (H)" +#~ msgstr "Odbija zaznaczone obiekty w poziomie" + +#, fuzzy +#~ msgid "Flip selection vertically (V)" +#~ msgstr "Odbija zaznaczone obiekty w pionie" + +#, fuzzy +#~ msgid "Align and Distribute dialog (Shift+Ctrl+A)" +#~ msgstr "Wyświetla okno dialogowe Układ elementów" + +#, fuzzy +#~ msgid "Convert selected object(s) to path(s) (Shift+Ctrl+C)" +#~ msgstr "Zamienia zaznaczone obiekty na ścieżki" + +#, fuzzy +#~ msgid "Convert selected stroke(s) to path(s) (Ctrl+Alt+C)" +#~ msgstr "Zamienia zaznaczone kontury na ścieżki" + +#~ msgid "Cl_eanup" +#~ msgstr "W_yczyść" + +#, fuzzy +#~ msgid "Text and Font dialog (Shift+Ctrl+T)" +#~ msgstr "Wyświetla okno dialogowe Tekst i czcionka" + +#, fuzzy +#~ msgid "Node tool" +#~ msgstr "Edycja węzłów" + +#, fuzzy +#~ msgid "Zoom tool" +#~ msgstr "Pomniejszenie" + +#, fuzzy +#~ msgid "Rectangle tool" +#~ msgstr "Prostokąt" + +#, fuzzy +#~ msgid "Star tool" +#~ msgstr "Początek:" + +#, fuzzy +#~ msgid "Spiral tool" +#~ msgstr "Spirala" + +#, fuzzy +#~ msgid "Calligraphy tool" +#~ msgstr "Kaligrafia" + +#, fuzzy +#~ msgid "Dropper tool" +#~ msgstr "Pipeta" + +#, fuzzy +#~ msgid "When scaling objects, scale stroke width by same proportion" +#~ msgstr "" +#~ "Przy skalowaniu obiektów grubość konturu zmienia się proporcjonalnie" + +#, fuzzy +#~ msgid "When scaling rectangles, scale radii of rounded corners" +#~ msgstr "" +#~ "Przy skalowaniu prostokątów promień zaokrąglenia ich narożników jest " +#~ "odpowiednio zmieniany" + +#, fuzzy +#~ msgid "Transform gradients (in fill or stroke) along with objects" +#~ msgstr "" +#~ "Przekształcenie gradientu (w wypełnieniu i konturze) wraz z obiektami" + +#, fuzzy +#~ msgid "Transform patterns (in fill or stroke) along with objects" +#~ msgstr "Przekształcenie deseni (w wypełnieniu i konturze) wraz z obiektami" + +#, fuzzy +#~ msgid "Delete segment between two nodes" +#~ msgstr "Usuwa zaznaczone węzły" + +#, fuzzy +#~ msgid "URI:" +#~ msgstr "URL" + +#~ msgid "Select All in All Layers" +#~ msgstr "Zaznacz na wszystkich warstwac_h" + +#~ msgid "Invert Selection" +#~ msgstr "Odwróć zaznaczeni_e" + +#~ msgid "Clean up selected path(s)" +#~ msgstr "Porządkuje zaznaczone ścieżkę" + +#~ msgid "_Scripts..." +#~ msgstr "Skrypt_y..." + +#, fuzzy +#~ msgid "Align and Distribute" +#~ msgstr "Wyrówna_j i rozłóż..." + +#, fuzzy +#~ msgid "Align and Distribute Dialog" +#~ msgstr "Wyświetla okno dialogowe Układ elementów" + +#, fuzzy +#~ msgid "Export Dialog" +#~ msgstr "Obszar eksportowany" + +#, fuzzy +#~ msgid "Fill and Stroke Dialog" +#~ msgstr "Wyświetla okno dialogowe Wypełnienie i kontur" + +#, fuzzy +#~ msgid "Find Dialog" +#~ msgstr "Pokaż/_ukryj okna dialogowe" + +#, fuzzy +#~ msgid "Inkscape Preferences" +#~ msgstr "Us_tawienia Inkscape..." + +#, fuzzy +#~ msgid "Inkscape Preferences Dialog" +#~ msgstr "Us_tawienia Inkscape..." + +#, fuzzy +#~ msgid "Layer Editor Dialog" +#~ msgstr "Przenieś warstwę na _wierzch" + +#, fuzzy +#~ msgid "Text Properties Dialog" +#~ msgstr "Wyświetla okno dialogowe Właściwości obiektu" + +#, fuzzy +#~ msgid "Transformation Dialog" +#~ msgstr "Wyświetla okno dialogowe Przekształcenia" + +#, fuzzy +#~ msgid "Tree Editor" +#~ msgstr "Edytor XML-u" + +#, fuzzy +#~ msgid "XML Editor Dialog" +#~ msgstr "Edytor XML-u" + +#, fuzzy +#~ msgid "Row height:" +#~ msgstr "Wysokość:" + +#, fuzzy +#~ msgid "Column width:" +#~ msgstr "Kolumny:" + +#~ msgid "Creating anchor at (%g,%g)" +#~ msgstr "Utworzenie zakotwiczenia na pozycji (%g,%g)" + +#~ msgid "" +#~ "Click to pick fill color, Shift+click to pick stroke color. " +#~ "Drag to pick the average color of an area." +#~ msgstr "Przeciągnij aby uzyskać uśredniony kolor z obszaru." + +#~ msgid "EPS Output Settings" +#~ msgstr "Ustawienia zapisu plików EPS" + +#~ msgid "Make bounding box around full page" +#~ msgstr "Zaznacz obszar całej strony" + +#~ msgid "" +#~ "Skew selection; with Shift to skew around the opposite side" +#~ msgstr "" +#~ "Skręcenie zazanczenia; z Shift skręcenie względem " +#~ "przeciwległej krawędzi" + +#~ msgid "Skew: %0.2f%% x %0.2f%%" +#~ msgstr "Skręcenie: %0.2f%% x %0.2f%%" + +#, fuzzy +#~ msgid "Inkscape" +#~ msgstr "Kończy działanie programu Inkscape" + +#~ msgid "Left side of aligned objects to left side of anchor" +#~ msgstr "Lewa strona obiektów do lewej strony elementu sterującego" + +#~ msgid "Right side of aligned objects to right side of anchor" +#~ msgstr "Prawa strona obiektów do prawej strony elementu sterującego" + +#~ msgid "Top of aligned objects to top of anchor" +#~ msgstr "Góra obiektów do góry elementu sterującego" + +#~ msgid "Bottom of aligned objects to bottom of anchor" +#~ msgstr "Dół obiektów do dołu elementu sterującego" + +#~ msgid "Distribute top sides of objects at even distances" +#~ msgstr "Górne krawędzie obiektów w równych odstępach" + +#~ msgid "Per row:" +#~ msgstr "Dla rzędu:" + +#~ msgid "Alternate sign" +#~ msgstr "Zamień znak" + +#~ msgid "How much to randomize tile positions" +#~ msgstr "Wartość zmiany losowej przy pozycjonowaniu" + +#~ msgid "Horizontal scale per each row" +#~ msgstr "Przyrost poziomy dla każdego rzędu" + +#~ msgid "Vertical scale per each row" +#~ msgstr "Przyrost pionowy dla każdego rzędu" + +#~ msgid "Horizontal scale per each column" +#~ msgstr "Przyrost poziomy dla każdej kolumny" + +#~ msgid "Vertical scale per each column" +#~ msgstr "Przyrost pionowy dla każdej kolumny" + +#~ msgid "Alternate the sign of the scale increment for each row or column" +#~ msgstr "Zamiana znaku +/- dla przyrostu w kolejnych rzędach i kolumnach" + +#~ msgid "How much to randomize tile sizes" +#~ msgstr "Wartość zmiany losowej przyrostu" + +#~ msgid "How much to randomize tile rotation" +#~ msgstr "Wartość zmiany losowej kątów obrotu" + +#~ msgid "Dissolve:" +#~ msgstr "Rozmycie:" + +#~ msgid "How much to randomize tile opacity" +#~ msgstr "Wartość zmiany losowej przezroczystości" + +#~ msgid "Rows:" +#~ msgstr "Rzędy:" + +#~ msgid "Minor grid line color:" +#~ msgstr "Kolor linii siatki:" + +#~ msgid "Grid color" +#~ msgstr "Kolor siatki" + +#~ msgid "Grid emphasis color" +#~ msgstr "Kolor głównych linii siatki" + +#~ msgid "Background (also for export):" +#~ msgstr "Kolor tła (również dla eksportu):" + +#~ msgid "" +#~ "Pick the visible color under cursor, taking into account the page " +#~ "background and disregarding the transparency of objects" +#~ msgstr "" +#~ "Pobranie koloru widocznego pod kursorem, z uwzględnieniem koloru tła ale " +#~ "z pominięciem przezroczystości" + +#~ msgid "Pick objects' color (including alpha)" +#~ msgstr "Pobranie koloru obiektu (z przezroczystością)" + +#~ msgid "" +#~ "Pick the actual color of object(s) under cursor, including their " +#~ "accumulated transparency" +#~ msgstr "" +#~ "Pobranie koloru obiektu(ów) pod kursorem, z uwzględnieniem nakładających " +#~ "się przezroczystości" + +#~ msgid "Fill style" +#~ msgstr "Styl wypełnienia" + +#~ msgid "Fill:" +#~ msgstr "Nakładające się obszary:" + +#~ msgid "" +#~ "Specifies the method of filling overlapping areas when an object " +#~ "intersects itself. With the \"winding fill\" method (fill-rule:nonzero), " +#~ "all overlapping areas are filled; with the \"alternating fill\" method " +#~ "(fill-rule:evenodd), every other of them is filled." +#~ msgstr "" +#~ "Wybór sposobu nakładania wypełnienia w obiektach, które przecinają się " +#~ "same ze sobą. 'Wypełnianie' oznacza wypełnienie wszystkich nakładających " +#~ "się obszarów; 'Przełączanie' powoduje zmianę stanu wypełnienia przy " +#~ "każdym kolejnym nałożeniu obszarów – nieparzysta ich liczba daje " +#~ "wypełniony obszar." + +#~ msgid "winding" +#~ msgstr "wypełnianie" + +#~ msgid "alternating" +#~ msgstr "przełączanie" + +#~ msgid "Update Properties" +#~ msgstr "Zapisz zmiany" + +#~ msgid "Label invalid" +#~ msgstr "Niepoprawna etykieta" + +#~ msgid "" +#~ "You cannot group objects from different groups or layers." +#~ msgstr "" +#~ "Nie można połączyć w grupę obiektów należących do różnych grup lub " +#~ "warstw." + +#, fuzzy +#~ msgid "Messages Dialog" +#~ msgstr "Komunikaty" + +#~ msgid "Value (brightness)" +#~ msgstr "Wartość (jasność)" + +#~ msgid "Switch to the previous layer in the document" +#~ msgstr "Przechodzi do poprzedniej warstwy w dokumencie" diff --git a/po/pt.po b/po/pt.po new file mode 100644 index 000000000..cf336530a --- /dev/null +++ b/po/pt.po @@ -0,0 +1,11506 @@ +# Sodipodi Portuguese Translation. +# Copyright (C) 2001 sodipodi +# Distributed under the same licence as the sodipodi package +# Álvaro Lopes , 2001, 2002 +# Duarte Loreto 2002,2003 (Maintainer) +# +msgid "" +msgstr "" +"Project-Id-Version: 2.4\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2005-12-04 11:51-0800\n" +"PO-Revision-Date: 2003-07-28 23:20+0000\n" +"Last-Translator: Duarte Loreto \n" +"Language-Team: Portuguese \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../inkscape.desktop.in.h:1 +#, fuzzy +msgid "Create and edit Scalable Vector Graphics images" +msgstr "Formato Gráficos de Vector Escaláveis (SVG)" + +#: ../inkscape.desktop.in.h:2 +#, fuzzy +msgid "Inkscape SVG Vector Illustrator" +msgstr "Ilustrador de Vectores SVG" + +#: ../../po/../src/arc-context.cpp:350 +msgid "" +"Ctrl: make circle or integer-ratio ellipse, snap arc/segment angle" +msgstr "" + +#: ../../po/../src/arc-context.cpp:351 ../../po/../src/rect-context.cpp:388 +msgid "Shift: draw around the starting point" +msgstr "" + +#: ../../po/../src/arc-context.cpp:413 +#: ../../po/../src/connector-context.cpp:493 +#: ../../po/../src/dyna-draw-context.cpp:506 +#: ../../po/../src/pen-context.cpp:329 ../../po/../src/pencil-context.cpp:208 +#: ../../po/../src/rect-context.cpp:452 ../../po/../src/spiral-context.cpp:421 +#: ../../po/../src/star-context.cpp:427 +msgid "Current layer is hidden. Unhide it to be able to draw on it." +msgstr "" + +#: ../../po/../src/arc-context.cpp:417 +#: ../../po/../src/connector-context.cpp:497 +#: ../../po/../src/dyna-draw-context.cpp:510 +#: ../../po/../src/pen-context.cpp:336 ../../po/../src/pencil-context.cpp:212 +#: ../../po/../src/rect-context.cpp:456 ../../po/../src/spiral-context.cpp:426 +#: ../../po/../src/star-context.cpp:431 +msgid "Current layer is locked. Unlock it to be able to draw on it." +msgstr "" + +#: ../../po/../src/arc-context.cpp:496 +#, c-format +msgid "" +"Ellipse: %s × %s; with Ctrl to make circle or integer-" +"ratio ellipse; with Shift to draw around the starting point" +msgstr "" + +#: ../../po/../src/connector-context.cpp:518 +#, fuzzy +msgid "Creating new connector" +msgstr "Criar um novo documento SVG" + +#: ../../po/../src/connector-context.cpp:939 +#, fuzzy +msgid "Finishing connector" +msgstr "Mão livre" + +#: ../../po/../src/connector-context.cpp:1108 +msgid "Connection point: click or drag to create a new connector" +msgstr "" + +#: ../../po/../src/connector-context.cpp:1185 +msgid "Connector endpoint: drag to reroute or connect to new shapes" +msgstr "" + +#: ../../po/../src/connector-context.cpp:1278 +#, fuzzy +msgid "Select at least one non-connector object." +msgstr "Seleccionar todos os objectos no documento" + +#: ../../po/../src/desktop-events.cpp:238 +#, c-format +msgid "%s at %s" +msgstr "" + +#. TRANSLATORS: This string appears when double-clicking on a guide. +#. This is the distance by which the guide is to be moved. +#: ../../po/../src/desktop-events.cpp:277 +#, fuzzy +msgid " relative by " +msgstr "Movimento relativo" + +#. TRANSLATORS: This string appears when double-clicking on a guide. +#. This is the target location where the guide is to be moved. +#: ../../po/../src/desktop-events.cpp:282 +#: ../../po/../src/desktop-events.cpp:395 +#, fuzzy +msgid " absolute to " +msgstr "absoluto" + +#. create dialog +#: ../../po/../src/desktop-events.cpp:348 +#, fuzzy +msgid "Guideline" +msgstr "Cor das guias" + +#: ../../po/../src/desktop-events.cpp:432 +#, fuzzy, c-format +msgid "Move %s" +msgstr "Mover" + +#: ../../po/../src/desktop.cpp:678 +msgid "No previous zoom." +msgstr "" + +#: ../../po/../src/desktop.cpp:703 +msgid "No next zoom." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:182 +#, fuzzy +msgid "Nothing selected." +msgstr "Último seleccionado" + +#: ../../po/../src/dialogs/clonetiler.cpp:188 +msgid "More than one object selected." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:195 +#, c-format +msgid "Object has %d tiled clones." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:200 +msgid "Object has no tiled clones." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:865 +#, fuzzy +msgid "Select one object whose tiled clones to unclump." +msgstr "Cortar os objectos seleccionados para área de transferência" + +#: ../../po/../src/dialogs/clonetiler.cpp:916 +#, fuzzy +msgid "Select one object whose tiled clones to remove." +msgstr "Cortar os objectos seleccionados para área de transferência" + +#: ../../po/../src/dialogs/clonetiler.cpp:984 +#: ../../po/../src/selection-chemistry.cpp:1774 +#, fuzzy +msgid "Select an object to clone." +msgstr "Cortar os objectos seleccionados para área de transferência" + +#: ../../po/../src/dialogs/clonetiler.cpp:990 +#: ../../po/../src/selection-chemistry.cpp:1780 +msgid "" +"If you want to clone several objects, group them and clone the " +"group." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1484 +msgid "Per row:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1497 +#, fuzzy +msgid "Per column:" +msgstr "Nenhum gradiente seleccionado" + +#: ../../po/../src/dialogs/clonetiler.cpp:1505 +#, fuzzy +msgid "Randomize:" +msgstr "Último seleccionado" + +#: ../../po/../src/dialogs/clonetiler.cpp:1656 +#, fuzzy +msgid "_Symmetry" +msgstr "Simétrico" + +#. TRANSLATORS: For the following 17 symmetry groups, see +#. * http://www.bib.ulb.ac.be/coursmath/doc/17.htm (visual examples); +#. * http://www.clarku.edu/~djoyce/wallpaper/seventeen.html (English vocabulary); or +#. * http://membres.lycos.fr/villemingerard/Geometri/Sym1D.htm (French vocabulary). +#. +#: ../../po/../src/dialogs/clonetiler.cpp:1664 +msgid "Select one of the 17 symmetry groups for the tiling" +msgstr "" + +#. TRANSLATORS: "translation" means "shift" / "displacement" here. +#: ../../po/../src/dialogs/clonetiler.cpp:1675 +msgid "P1: simple translation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1676 +msgid "P2: 180° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1677 +msgid "PM: reflection" +msgstr "" + +#. TRANSLATORS: "glide reflection" is a reflection and a translation combined. +#. For more info, see http://mathforum.org/sum95/suzanne/symsusan.html +#: ../../po/../src/dialogs/clonetiler.cpp:1680 +msgid "PG: glide reflection" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1681 +msgid "CM: reflection + glide reflection" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1682 +msgid "PMM: reflection + reflection" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1683 +msgid "PMG: reflection + 180° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1684 +msgid "PGG: glide reflection + 180° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1685 +msgid "CMM: reflection + reflection + 180° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1686 +msgid "P4: 90° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1687 +msgid "P4M: 90° rotation + 45° reflection" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1688 +msgid "P4G: 90° rotation + 90° reflection" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1689 +msgid "P3: 120° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1690 +msgid "P31M: reflection + 120° rotation, dense" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1691 +msgid "P3M1: reflection + 120° rotation, sparse" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1692 +msgid "P6: 60° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1693 +msgid "P6M: reflection + 60° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1721 +msgid "S_hift" +msgstr "" + +#. TRANSLATORS: "shift" means: the tiles will be shifted (offset) horizontally by this amount +#: ../../po/../src/dialogs/clonetiler.cpp:1731 +#, fuzzy, no-c-format +msgid "Shift X:" +msgstr "Alterar" + +#: ../../po/../src/dialogs/clonetiler.cpp:1739 +#, no-c-format +msgid "Horizontal shift per row (in % of tile width)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1747 +#, no-c-format +msgid "Horizontal shift per column (in % of tile width)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1754 +msgid "Randomize the horizontal shift by this percentage" +msgstr "" + +#. TRANSLATORS: "shift" means: the tiles will be shifted (offset) vertically by this amount +#: ../../po/../src/dialogs/clonetiler.cpp:1764 +#, fuzzy, no-c-format +msgid "Shift Y:" +msgstr "Alterar" + +#: ../../po/../src/dialogs/clonetiler.cpp:1772 +#, no-c-format +msgid "Vertical shift per row (in % of tile height)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1780 +#, no-c-format +msgid "Vertical shift per column (in % of tile height)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1787 +msgid "Randomize the vertical shift by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1795 +#, fuzzy +msgid "Exponent:" +msgstr "Alterar" + +#: ../../po/../src/dialogs/clonetiler.cpp:1802 +msgid "Whether rows are spaced evenly (1), converge (<1) or diverge (>1)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1809 +msgid "Whether columns are spaced evenly (1), converge (<1) or diverge (>1)" +msgstr "" + +#. TRANSLATORS: "Alternate" is a verb here +#: ../../po/../src/dialogs/clonetiler.cpp:1817 +#: ../../po/../src/dialogs/clonetiler.cpp:1907 +#: ../../po/../src/dialogs/clonetiler.cpp:1966 +#: ../../po/../src/dialogs/clonetiler.cpp:2022 +#: ../../po/../src/dialogs/clonetiler.cpp:2153 +msgid "Alternate:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1823 +msgid "Alternate the sign of shifts for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1828 +msgid "Alternate the sign of shifts for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1837 +#, fuzzy +msgid "Sc_ale" +msgstr "Escala" + +#: ../../po/../src/dialogs/clonetiler.cpp:1845 +#, fuzzy +msgid "Scale X:" +msgstr "Alterar" + +#: ../../po/../src/dialogs/clonetiler.cpp:1853 +#, fuzzy, no-c-format +msgid "Horizontal scale per row (in % of tile width)" +msgstr "valor do escalamento horizontal" + +#: ../../po/../src/dialogs/clonetiler.cpp:1861 +#, fuzzy, no-c-format +msgid "Horizontal scale per column (in % of tile width)" +msgstr "valor do escalamento horizontal" + +#: ../../po/../src/dialogs/clonetiler.cpp:1868 +msgid "Randomize the horizontal scale by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1876 +#, fuzzy +msgid "Scale Y:" +msgstr "Alterar" + +#: ../../po/../src/dialogs/clonetiler.cpp:1884 +#, fuzzy, no-c-format +msgid "Vertical scale per row (in % of tile height)" +msgstr "valor do escalamento vertical" + +#: ../../po/../src/dialogs/clonetiler.cpp:1892 +#, fuzzy, no-c-format +msgid "Vertical scale per column (in % of tile height)" +msgstr "valor do escalamento vertical" + +#: ../../po/../src/dialogs/clonetiler.cpp:1899 +msgid "Randomize the vertical scale by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1913 +#, fuzzy +msgid "Alternate the sign of scales for each row" +msgstr "valor do escalamento vertical" + +#: ../../po/../src/dialogs/clonetiler.cpp:1918 +#, fuzzy +msgid "Alternate the sign of scales for each column" +msgstr "valor do escalamento vertical" + +#: ../../po/../src/dialogs/clonetiler.cpp:1927 +#, fuzzy +msgid "_Rotation" +msgstr "Resolução:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1935 +#, fuzzy +msgid "Angle:" +msgstr "Alterar" + +#: ../../po/../src/dialogs/clonetiler.cpp:1943 +#, no-c-format +msgid "Rotate tiles by this angle for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1951 +#, no-c-format +msgid "Rotate tiles by this angle for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1958 +msgid "Randomize the rotation angle by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1972 +msgid "Alternate the rotation direction for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1977 +msgid "Alternate the rotation direction for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1985 +#, fuzzy +msgid "_Opacity" +msgstr "Opacidade:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1993 +#, fuzzy +msgid "Fade out:" +msgstr "Alterar" + +#: ../../po/../src/dialogs/clonetiler.cpp:2000 +msgid "Decrease tile opacity by this percentage for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2007 +msgid "Decrease tile opacity by this percentage for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2014 +msgid "Randomize the tile opacity by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2028 +msgid "Alternate the sign of opacity change for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2033 +msgid "Alternate the sign of opacity change for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2041 +#, fuzzy +msgid "Co_lor" +msgstr "Cor:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2046 +#, fuzzy +msgid "Initial color: " +msgstr "Cor da grelha:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2050 +msgid "Initial color of tiled clones" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2050 +msgid "" +"Initial color for clones (works only if the original has unset fill or " +"stroke)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2065 +#, fuzzy +msgid "H:" +msgstr "Alterar" + +#: ../../po/../src/dialogs/clonetiler.cpp:2072 +msgid "Change the tile hue by this percentage for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2079 +msgid "Change the tile hue by this percentage for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2086 +msgid "Randomize the tile hue by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2095 +#, fuzzy +msgid "S:" +msgstr "Alterar" + +#: ../../po/../src/dialogs/clonetiler.cpp:2102 +msgid "Change the color saturation by this percentage for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2109 +msgid "Change the color saturation by this percentage for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2116 +msgid "Randomize the color saturation by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2124 +#, fuzzy +msgid "L:" +msgstr "Alterar" + +#: ../../po/../src/dialogs/clonetiler.cpp:2131 +msgid "Change the color lightness by this percentage for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2138 +msgid "Change the color lightness by this percentage for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2145 +msgid "Randomize the color lightness by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2159 +msgid "Alternate the sign of color changes for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2164 +msgid "Alternate the sign of color changes for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2172 +#, fuzzy +msgid "_Trace" +msgstr "Analisar" + +#: ../../po/../src/dialogs/clonetiler.cpp:2179 +msgid "Trace the drawing under the tiles" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2183 +msgid "" +"For each clone, pick a value from the drawing in that clone's location and " +"apply it to the clone" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2197 +msgid "1. Pick from the drawing:" +msgstr "" + +#. ----Hbox2 +#: ../../po/../src/dialogs/clonetiler.cpp:2208 +#: ../../po/../src/dialogs/clonetiler.cpp:2355 +#: ../../po/../src/ui/dialog/tracedialog.cpp:445 +#, fuzzy +msgid "Color" +msgstr "Cor:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2209 +msgid "Pick the visible color and opacity" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2216 +#: ../../po/../src/dialogs/clonetiler.cpp:2365 +#: ../share/extensions/dropshadow.inx.h:3 +#, fuzzy +msgid "Opacity" +msgstr "Opacidade:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2217 +msgid "Pick the total accumulated opacity" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2224 +msgid "R" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2225 +msgid "Pick the Red component of the color" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2232 +msgid "G" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2233 +msgid "Pick the Green component of the color" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2240 +msgid "B" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2241 +msgid "Pick the Blue component of the color" +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2250 +msgid "clonetiler|H" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2251 +#, fuzzy +msgid "Pick the hue of the color" +msgstr "Escolha a cor da rasura" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2260 +msgid "clonetiler|S" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2261 +#, fuzzy +msgid "Pick the saturation of the color" +msgstr "Escolha a cor da rasura" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2270 +msgid "clonetiler|L" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2271 +msgid "Pick the lightness of the color" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2281 +msgid "2. Tweak the picked value:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2291 +msgid "Gamma-correct:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2296 +msgid "Shift the mid-range of the picked value upwards (>0) or downwards (<0)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2303 +msgid "Randomize:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2308 +msgid "Randomize the picked value by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2315 +#, fuzzy +msgid "Invert:" +msgstr "Repor" + +#: ../../po/../src/dialogs/clonetiler.cpp:2319 +msgid "Invert the picked value" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2325 +msgid "3. Apply the value to the clones':" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2335 +#, fuzzy +msgid "Presence" +msgstr "Preservar" + +#: ../../po/../src/dialogs/clonetiler.cpp:2338 +msgid "" +"Each clone is created with the probability determined by the picked value in " +"that point" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2345 +#, fuzzy +msgid "Size" +msgstr "Lados:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2348 +msgid "Each clone's size is determined by the picked value in that point" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2358 +msgid "" +"Each clone is painted by the picked color (the original must have unset fill " +"or stroke)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2368 +msgid "Each clone's opacity is determined by the picked value in that point" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2395 +msgid "How many rows in the tiling" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2415 +msgid "How many columns in the tiling" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2445 +msgid "Width of the rectangle to be filled" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2470 +msgid "Height of the rectangle to be filled" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2485 +#, fuzzy +msgid "Rows, columns: " +msgstr "Alterar" + +#: ../../po/../src/dialogs/clonetiler.cpp:2486 +msgid "Create the specified number of rows and columns" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2495 +#, fuzzy +msgid "Width, height: " +msgstr "Altura: " + +#: ../../po/../src/dialogs/clonetiler.cpp:2496 +msgid "Fill the specified width and height with the tiling" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2512 +#, fuzzy +msgid "Use saved size and position of the tile" +msgstr "Tamanho e posição do objecto" + +#: ../../po/../src/dialogs/clonetiler.cpp:2515 +msgid "" +"Pretend that the size and position of the tile are the same as the last time " +"you tiled it (if any), instead of using the current size" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2539 +#, fuzzy +msgid " _Create " +msgstr "Alterar" + +#: ../../po/../src/dialogs/clonetiler.cpp:2541 +msgid "Create and tile the clones of the selection" +msgstr "" + +#. TRANSLATORS: if a group of objects are "clumped" together, then they +#. are unevenly spread in the given amount of space - as shown in the +#. diagrams on the left in the following screenshot: +#. http://www.inkscape.org/screenshots/gallery/inkscape-0.42-CVS-tiles-unclump.png +#. So unclumping is the process of spreading a number of objects out more evenly. +#: ../../po/../src/dialogs/clonetiler.cpp:2556 +msgid " _Unclump " +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2557 +msgid "Spread out clones to reduce clumping; can be applied repeatedly" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2563 +#, fuzzy +msgid " Re_move " +msgstr "Remover ligação" + +#: ../../po/../src/dialogs/clonetiler.cpp:2564 +msgid "Remove existing tiled clones of the selected object (siblings only)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2580 +#, fuzzy +msgid " R_eset " +msgstr "Remover ligação" + +#. TRANSLATORS: "change" is a noun here +#: ../../po/../src/dialogs/clonetiler.cpp:2582 +msgid "" +"Reset all shifts, scales, rotates, opacity and color changes in the dialog " +"to zero" +msgstr "" + +#: ../../po/../src/dialogs/color-picker.cpp:280 +msgid "Close" +msgstr "Fechar" + +#: ../../po/../src/dialogs/debugdialog.cpp:138 +msgid "Messages" +msgstr "" + +#. ## Add a menu for clear() +#: ../../po/../src/dialogs/debugdialog.cpp:144 +#: ../../po/../src/menus-skeleton.h:16 +#: ../../po/../src/ui/dialog/messages.cpp:56 +#: ../../po/../src/ui/dialog/scriptdialog.cpp:181 +msgid "_File" +msgstr "_Ficheiro" + +#. TRANSLATORS: "Clear" is a verb here +#: ../../po/../src/dialogs/debugdialog.cpp:145 +#: ../../po/../src/dialogs/find.cpp:753 +#: ../../po/../src/ui/dialog/messages.cpp:57 +#: ../../po/../src/ui/dialog/scriptdialog.cpp:182 +#, fuzzy +msgid "_Clear" +msgstr "Fechar" + +#: ../../po/../src/dialogs/debugdialog.cpp:147 +#: ../../po/../src/ui/dialog/messages.cpp:59 +msgid "Capture log messages" +msgstr "" + +#: ../../po/../src/dialogs/debugdialog.cpp:149 +#: ../../po/../src/ui/dialog/messages.cpp:61 +msgid "Release log messages" +msgstr "" + +#. Notebook tab +#: ../../po/../src/dialogs/desktop-properties.cpp:909 +#: ../../po/../src/ui/dialog/document-preferences.cpp:89 +#: ../../po/../src/ui/widget/panel.cpp:107 +msgid "Grid" +msgstr "Grelha" + +#. Checkbuttons +#. / \todo FIXME: gray out snapping when grid is off +#. / \todo FIXME: gray out snapping when grid is off. +#. / Dissenting view: you want snapping without grid. +#: ../../po/../src/dialogs/desktop-properties.cpp:917 +#: ../../po/../src/ui/dialog/document-preferences.cpp:179 +msgid "Show grid" +msgstr "Mostrar grelha" + +#: ../../po/../src/dialogs/desktop-properties.cpp:917 +#: ../../po/../src/ui/dialog/document-preferences.cpp:179 +#: ../../po/../src/verbs.cpp:2115 +#, fuzzy +msgid "Show or hide grid" +msgstr "Mostrar grelha" + +#: ../../po/../src/dialogs/desktop-properties.cpp:918 +#: ../../po/../src/ui/dialog/document-preferences.cpp:180 +#, fuzzy +msgid "Snap bounding boxes to grid" +msgstr "Ajustar à grelha" + +#: ../../po/../src/dialogs/desktop-properties.cpp:918 +#: ../../po/../src/dialogs/desktop-properties.cpp:1001 +#: ../../po/../src/ui/dialog/document-preferences.cpp:181 +#: ../../po/../src/ui/dialog/document-preferences.cpp:236 +msgid "Snap the edges of the object bounding boxes" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:919 +#: ../../po/../src/ui/dialog/document-preferences.cpp:183 +#, fuzzy +msgid "Snap nodes to grid" +msgstr "Ajustar à grelha" + +#: ../../po/../src/dialogs/desktop-properties.cpp:919 +#: ../../po/../src/dialogs/desktop-properties.cpp:1002 +#: ../../po/../src/ui/dialog/document-preferences.cpp:184 +#: ../../po/../src/ui/dialog/document-preferences.cpp:239 +msgid "Snap path nodes, text baselines, ellipse centers, etc." +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:937 +#: ../../po/../src/ui/dialog/document-preferences.cpp:186 +msgid "Grid units:" +msgstr "Unidades da grelha:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:939 +#: ../../po/../src/ui/dialog/document-preferences.cpp:187 +msgid "Origin X:" +msgstr "Origem X:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:942 +#: ../../po/../src/ui/dialog/document-preferences.cpp:189 +msgid "Origin Y:" +msgstr "Origem Y:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:945 +#: ../../po/../src/ui/dialog/document-preferences.cpp:191 +msgid "Spacing X:" +msgstr "Espaçamento X:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:948 +#: ../../po/../src/ui/dialog/document-preferences.cpp:193 +msgid "Spacing Y:" +msgstr "Espaçamento Y:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:952 +#: ../../po/../src/dialogs/desktop-properties.cpp:1013 +#: ../../po/../src/ui/dialog/document-preferences.cpp:195 +#: ../../po/../src/ui/dialog/document-preferences.cpp:241 +msgid "Snap units:" +msgstr "Unidade de ajuste:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:955 +#: ../../po/../src/dialogs/desktop-properties.cpp:1016 +#: ../../po/../src/ui/dialog/document-preferences.cpp:196 +#: ../../po/../src/ui/dialog/document-preferences.cpp:242 +msgid "Snap distance:" +msgstr "Distância de ajuste:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:958 +#: ../../po/../src/ui/dialog/document-preferences.cpp:199 +#, fuzzy +msgid "Grid line color:" +msgstr "Cor das guias" + +#: ../../po/../src/dialogs/desktop-properties.cpp:959 +#: ../../po/../src/ui/dialog/document-preferences.cpp:199 +#, fuzzy +msgid "Grid line color" +msgstr "Cor das guias" + +#: ../../po/../src/dialogs/desktop-properties.cpp:959 +#: ../../po/../src/ui/dialog/document-preferences.cpp:200 +#, fuzzy +msgid "Color of grid lines" +msgstr "Escolha a cor para as guias" + +#: ../../po/../src/dialogs/desktop-properties.cpp:961 +#: ../../po/../src/ui/dialog/document-preferences.cpp:201 +#, fuzzy +msgid "Major grid line color:" +msgstr "Cor das guias" + +#: ../../po/../src/dialogs/desktop-properties.cpp:962 +#: ../../po/../src/ui/dialog/document-preferences.cpp:201 +#, fuzzy +msgid "Major grid line color" +msgstr "Cor das guias" + +#: ../../po/../src/dialogs/desktop-properties.cpp:962 +#: ../../po/../src/ui/dialog/document-preferences.cpp:202 +#, fuzzy +msgid "Color of the major (highlighted) grid lines" +msgstr "Escolha a cor para as guias seleccionadas" + +#: ../../po/../src/dialogs/desktop-properties.cpp:965 +#: ../../po/../src/ui/dialog/document-preferences.cpp:204 +#, fuzzy +msgid "Major grid line every:" +msgstr "Cor das guias" + +#. TRANSLATORS: This belongs to the "Major grid line every:" string, +#. see grid settings in the "Document Preferences" dialog +#: ../../po/../src/dialogs/desktop-properties.cpp:977 +#: ../../po/../src/ui/dialog/document-preferences.cpp:204 +#, fuzzy +msgid "lines" +msgstr "Fechar" + +#. Guidelines page +#: ../../po/../src/dialogs/desktop-properties.cpp:991 +#: ../../po/../src/ui/dialog/document-preferences.cpp:90 +msgid "Guides" +msgstr "Guias" + +#. / \todo FIXME: gray out snapping when guides are off +#. / Dissenting view: you want snapping without guides. +#: ../../po/../src/dialogs/desktop-properties.cpp:1000 +#: ../../po/../src/ui/dialog/document-preferences.cpp:234 +msgid "Show guides" +msgstr "Mostar guias" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1000 +#: ../../po/../src/ui/dialog/document-preferences.cpp:234 +#: ../../po/../src/verbs.cpp:2116 +#, fuzzy +msgid "Show or hide guides" +msgstr "Mostar guias" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1001 +#: ../../po/../src/ui/dialog/document-preferences.cpp:235 +#, fuzzy +msgid "Snap bounding boxes to guides" +msgstr "Ajustar às guias" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1002 +#: ../../po/../src/ui/dialog/document-preferences.cpp:238 +#, fuzzy +msgid "Snap points to guides" +msgstr "Ajustar à grelha" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1020 +#: ../../po/../src/ui/dialog/document-preferences.cpp:243 +#, fuzzy +msgid "Guide color:" +msgstr "Cor das guias:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1021 +#: ../../po/../src/ui/dialog/document-preferences.cpp:243 +msgid "Guideline color" +msgstr "Cor das guias" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1021 +#: ../../po/../src/ui/dialog/document-preferences.cpp:244 +#, fuzzy +msgid "Color of guidelines" +msgstr "Escolha a cor para as guias" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1023 +#: ../../po/../src/ui/dialog/document-preferences.cpp:245 +msgid "Highlight color:" +msgstr "Cor de realce:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1024 +#: ../../po/../src/ui/dialog/document-preferences.cpp:245 +msgid "Highlighted guideline color" +msgstr "Cor de realce das guias" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1024 +#: ../../po/../src/ui/dialog/document-preferences.cpp:246 +msgid "Color of a guideline when it is under mouse" +msgstr "" + +#. Page page +#: ../../po/../src/dialogs/desktop-properties.cpp:1029 +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:855 +#: ../../po/../src/ui/dialog/document-preferences.cpp:88 +#: ../../po/../src/widgets/desktop-widget.cpp:1061 +msgid "Page" +msgstr "Página" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1039 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +#, fuzzy +msgid "Background:" +msgstr "Cor final" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1040 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +#, fuzzy +msgid "Background color" +msgstr "Cor final" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1041 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +msgid "" +"Color and transparency of the page background (also used for bitmap export)" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1045 +#: ../../po/../src/ui/dialog/document-preferences.cpp:147 +#, fuzzy +msgid "Show page border" +msgstr "Mostrar margem" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1049 +#: ../../po/../src/ui/dialog/document-preferences.cpp:148 +msgid "Border on top of drawing" +msgstr "Margem sobre o desenho" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1052 +#: ../../po/../src/ui/dialog/document-preferences.cpp:149 +#, fuzzy +msgid "Border color:" +msgstr "Cor da grelha:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1053 +#: ../../po/../src/ui/dialog/document-preferences.cpp:149 +#, fuzzy +msgid "Page border color" +msgstr "Cor da grelha:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1054 +#: ../../po/../src/ui/dialog/document-preferences.cpp:150 +#, fuzzy +msgid "Color of the page border" +msgstr "Mostrar margem" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1059 +#: ../../po/../src/ui/dialog/document-preferences.cpp:152 +msgid "Show page shadow" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1063 +#: ../../po/../src/ui/dialog/document-preferences.cpp:153 +#, fuzzy +msgid "Default units:" +msgstr "Por Omissão" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1069 +msgid "Units for the tool controls, ruler, and the statusbar" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1086 +#: ../../po/../src/ui/widget/page-sizer.cpp:209 +#, fuzzy +msgid "Page size:" +msgstr "Tamanho do papel:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1110 +#: ../../po/../src/ui/widget/page-sizer.cpp:219 +msgid "Custom" +msgstr "Costumizado" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1121 +#: ../../po/../src/ui/widget/page-sizer.cpp:225 +#, fuzzy +msgid "Page orientation:" +msgstr "Orientação:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1133 +#: ../../po/../src/ui/widget/page-sizer.cpp:232 +#, fuzzy +msgid "Landscape" +msgstr "Apresentação Sodipodi" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1139 +#: ../../po/../src/ui/widget/page-sizer.cpp:234 +#, fuzzy +msgid "Portrait" +msgstr "Ponto" + +#. Custom paper frame +#: ../../po/../src/dialogs/desktop-properties.cpp:1148 +#: ../../po/../src/ui/widget/page-sizer.cpp:249 +#, fuzzy +msgid "Custom size" +msgstr "Costumizado" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1160 +#: ../../po/../src/dialogs/export.cpp:269 +#: ../../po/../src/ui/widget/page-sizer.cpp:261 +msgid "Units:" +msgstr "Unidades:" + +#. Stroke width +#: ../../po/../src/dialogs/desktop-properties.cpp:1162 +#: ../../po/../src/dialogs/export.cpp:310 +#: ../../po/../src/dialogs/object-attributes.cpp:55 +#: ../../po/../src/dialogs/stroke-style.cpp:985 +#: ../../po/../src/ui/widget/page-sizer.cpp:262 +#: ../../po/../src/widgets/toolbox.cpp:1957 +msgid "Width:" +msgstr "Largura:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1183 +#: ../../po/../src/dialogs/export.cpp:326 +#: ../../po/../src/dialogs/export.cpp:431 +#: ../../po/../src/dialogs/object-attributes.cpp:56 +#: ../../po/../src/ui/widget/page-sizer.cpp:263 +msgid "Height:" +msgstr "Altura:" + +#. +#. * Ownership metadata tab +#. +#: ../../po/../src/dialogs/desktop-properties.cpp:1206 +msgid "Metadata" +msgstr "" + +#. add license selector pull-down +#: ../../po/../src/dialogs/desktop-properties.cpp:1225 +#, fuzzy +msgid "License" +msgstr "polegadas" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1255 +msgid "Proprietary" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:212 +#, fuzzy +msgid "When transforming, show:" +msgstr "Transformações de objecto" + +#: ../../po/../src/dialogs/display-settings.cpp:223 +#, fuzzy +msgid "Objects" +msgstr "Objecto" + +#: ../../po/../src/dialogs/display-settings.cpp:224 +msgid "Show the actual objects when moving or transforming" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:231 +#, fuzzy +msgid "Box outline" +msgstr "Mostar contorno" + +#: ../../po/../src/dialogs/display-settings.cpp:232 +msgid "Show only a box outline of the objects when moving or transforming" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:238 +msgid "Per-object selection cue:" +msgstr "" + +#. sorationsnapsperpi == 0 means no snapping +#: ../../po/../src/dialogs/display-settings.cpp:249 +#: ../../po/../src/dialogs/display-settings.cpp:386 +#: ../../po/../src/dialogs/display-settings.cpp:441 +#: ../../po/../src/dialogs/display-settings.cpp:1482 +#: ../../po/../src/dialogs/stroke-style.cpp:791 +#: ../../po/../src/interface.cpp:741 +#: ../../po/../src/ui/widget/selected-style.cpp:100 +#: ../../po/../src/verbs.cpp:1842 +msgid "None" +msgstr "Nenhum" + +#: ../../po/../src/dialogs/display-settings.cpp:250 +msgid "No per-object selection indication" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:256 +msgid "Mark" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:257 +msgid "Each selected object has a diamond mark in the top left corner" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:264 +msgid "Box" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:265 +msgid "Each selected object displays its bounding box" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:270 +#, fuzzy +msgid "Default scale origin:" +msgstr "Tolerância por omissão do cursor:" + +#: ../../po/../src/dialogs/display-settings.cpp:281 +#, fuzzy +msgid "Opposite bounding box edge" +msgstr "Ajustar à grelha" + +#: ../../po/../src/dialogs/display-settings.cpp:282 +msgid "Default scale origin will be on the bounding box of the item" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:288 +msgid "Farthest opposite node" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:289 +msgid "Default scale origin will be on the bounding box of the item's points" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:341 +#, fuzzy +msgid "degrees" +msgstr "graus" + +#: ../../po/../src/dialogs/display-settings.cpp:350 +msgid "" +"Rotating with Ctrl pressed snaps every that much degrees; also, pressing " +"[ or ] rotates by this amount" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:407 +msgid "Rotation snaps every:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:430 +msgid "" +"None: dialogs are treated as regular windows; Normal: dialogs stay on top of " +"document windows; Aggressive: same as Normal but may work better with some " +"window managers." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:451 +msgid "Normal" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:461 +msgid "Aggressive" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:475 +#, fuzzy +msgid "Dialogs on top:" +msgstr "Diálogos" + +#: ../../po/../src/dialogs/display-settings.cpp:645 +#, fuzzy +msgid "Show selection cue" +msgstr "Baixar selecção por uma camada" + +#: ../../po/../src/dialogs/display-settings.cpp:646 +msgid "" +"Whether selected objects display a selection cue (the same as in selector)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:657 +#, fuzzy +msgid "Enable gradient editing" +msgstr "Vector do gradiente" + +#: ../../po/../src/dialogs/display-settings.cpp:658 +msgid "Whether selected objects display gradient editing controls" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:719 +#, fuzzy +msgid "No objects selected to take the style from." +msgstr "Converter objecto seleccionado em caminho" + +#: ../../po/../src/dialogs/display-settings.cpp:728 +msgid "" +"More than one object selected. Cannot take style from multiple " +"objects." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:767 +#, fuzzy +msgid "Create new objects with:" +msgstr "Criar e editar objectos de texto" + +#: ../../po/../src/dialogs/display-settings.cpp:777 +#, fuzzy +msgid "Take from selection" +msgstr "Transformar selecção" + +#: ../../po/../src/dialogs/display-settings.cpp:778 +msgid "Remember the style of the (first) selected object as this tool's style" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:782 +#, fuzzy +msgid "Last used style" +msgstr "Estilo pincelada" + +#: ../../po/../src/dialogs/display-settings.cpp:782 +msgid "Apply the style you last set on an object" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:790 +msgid "This tool's own style:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:790 +msgid "" +"Each tool may store its own style to apply to the newly created objects. Use " +"the button below to set it." +msgstr "" + +#. Mouse +#: ../../po/../src/dialogs/display-settings.cpp:877 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:55 +#, fuzzy +msgid "Mouse" +msgstr "Mover" + +#. TRANSLATORS: "Grab" is a noun here. "Grab sensitivity" is intended to mean how +#. * close on the screen you need to be to an object to be able to grab it with mouse (in +#. * pixels). +#: ../../po/../src/dialogs/display-settings.cpp:883 +#, fuzzy +msgid "Grab sensitivity:" +msgstr "Tornar sensível" + +#: ../../po/../src/dialogs/display-settings.cpp:884 +msgid "" +"How close on the screen you need to be to an object to be able to grab it " +"with mouse (in screen pixels)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:885 +#: ../../po/../src/dialogs/display-settings.cpp:897 +#: ../../po/../src/dialogs/display-settings.cpp:912 +#: ../../po/../src/dialogs/display-settings.cpp:930 +#: ../../po/../src/dialogs/display-settings.cpp:970 +msgid "pixels" +msgstr "pixels" + +#: ../../po/../src/dialogs/display-settings.cpp:895 +msgid "Click/drag threshold:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:896 +msgid "" +"Maximum mouse drag (in screen pixels) which is considered a click, not a drag" +msgstr "" + +#. Scrolling +#: ../../po/../src/dialogs/display-settings.cpp:907 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:56 +msgid "Scrolling" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:910 +msgid "Mouse wheel scrolls by:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:911 +msgid "" +"One mouse wheel notch scrolls by this distance in screen pixels " +"(horizontally with Shift)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:920 +msgid "Ctrl+arrows" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:928 +msgid "Scroll by:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:929 +msgid "Pressing Ctrl+arrow key scrolls by this distance (in screen pixels)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:939 +#, fuzzy +msgid "Acceleration:" +msgstr "Selecção" + +#: ../../po/../src/dialogs/display-settings.cpp:940 +msgid "" +"Pressing and holding Ctrl+arrow will gradually speed up scrolling (0 for no " +"acceleration)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:949 +msgid "Autoscrolling" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:957 +#, fuzzy +msgid "Speed:" +msgstr "Vermelho:" + +#: ../../po/../src/dialogs/display-settings.cpp:958 +msgid "" +"How fast the canvas autoscrolls when you drag beyond canvas edge (0 to turn " +"autoscroll off)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:968 +#: ../../po/../src/ui/dialog/tracedialog.cpp:357 +#: ../../po/../src/ui/dialog/tracedialog.cpp:390 +msgid "Threshold:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:969 +msgid "" +"How far (in screen pixels) you need to be from the canvas edge to trigger " +"autoscroll; positive is outside the canvas, negative is within the canvas" +msgstr "" + +#. Steps +#: ../../po/../src/dialogs/display-settings.cpp:979 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:57 +#, fuzzy +msgid "Steps" +msgstr "Estilo" + +#: ../../po/../src/dialogs/display-settings.cpp:982 +msgid "Arrow keys move by:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:983 +msgid "" +"Pressing an arrow key moves selected object(s) or node(s) by this distance " +"(in px units)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:984 +#: ../../po/../src/dialogs/display-settings.cpp:995 +#: ../../po/../src/dialogs/display-settings.cpp:1006 +#: ../../po/../src/helper/units.cpp:42 +msgid "px" +msgstr "px" + +#: ../../po/../src/dialogs/display-settings.cpp:993 +msgid "> and < scale by:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:994 +msgid "" +"Pressing > or < scales selection up or down by this increment (in px units)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1004 +msgid "Inset/Outset by:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1005 +msgid "" +"Inset and Outset commands displace the path by this distance (in px units)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1017 +msgid "Compass-like display of angles" +msgstr "" + +#. TRANSLATORS: "positive clockwise" means "increasing in clockwise direction" +#: ../../po/../src/dialogs/display-settings.cpp:1019 +msgid "" +"When on, angles are displayed with 0 at north, 0 to 360 range, positive " +"clockwise; otherwise with 0 at east, -180 to 180 range, positive " +"counterclockwise" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1026 +#, fuzzy +msgid "Zoom in/out by:" +msgstr "Diminuir zoom" + +#: ../../po/../src/dialogs/display-settings.cpp:1027 +msgid "" +"Zoom tool click, +/- keys, and middle click zoom in and out by this " +"multiplier" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1028 +#: ../../po/../src/helper/units.cpp:44 +msgid "%" +msgstr "%" + +#. Tools +#: ../../po/../src/dialogs/display-settings.cpp:1037 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:58 +msgid "Tools" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1045 +#, fuzzy +msgid "Selector" +msgstr "Seleccionar" + +#: ../../po/../src/dialogs/display-settings.cpp:1056 +msgid "Node" +msgstr "Nó" + +#: ../../po/../src/dialogs/display-settings.cpp:1064 +#: ../../po/../src/verbs.cpp:2073 +#: ../../po/../src/widgets/desktop-widget.cpp:277 +msgid "Zoom" +msgstr "Zoom" + +#. The 4 shape tools +#: ../../po/../src/dialogs/display-settings.cpp:1071 +#, fuzzy +msgid "Shapes" +msgstr "Forma" + +#: ../../po/../src/dialogs/display-settings.cpp:1079 +#: ../../po/../src/verbs.cpp:2055 +msgid "Rectangle" +msgstr "Rectângulo" + +#: ../../po/../src/dialogs/display-settings.cpp:1085 +#: ../../po/../src/verbs.cpp:2057 +msgid "Ellipse" +msgstr "Elipse" + +#: ../../po/../src/dialogs/display-settings.cpp:1091 +#: ../../po/../src/verbs.cpp:2059 +msgid "Star" +msgstr "Estrela" + +#: ../../po/../src/dialogs/display-settings.cpp:1097 +#: ../../po/../src/verbs.cpp:2061 +msgid "Spiral" +msgstr "Espiral" + +#: ../../po/../src/dialogs/display-settings.cpp:1111 +#: ../../po/../src/verbs.cpp:2063 +msgid "Pencil" +msgstr "Lápis" + +#: ../../po/../src/dialogs/display-settings.cpp:1114 +#, fuzzy +msgid "Tolerance:" +msgstr "Analisar" + +#: ../../po/../src/dialogs/display-settings.cpp:1115 +msgid "" +"This value affects the amount of smoothing applied to freehand lines; lower " +"values produce more uneven paths with more nodes" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1131 +#: ../../po/../src/verbs.cpp:2065 +msgid "Pen" +msgstr "Caneta" + +#: ../../po/../src/dialogs/display-settings.cpp:1140 +#: ../../po/../src/verbs.cpp:2067 +msgid "Calligraphy" +msgstr "Caligrafia" + +#: ../../po/../src/dialogs/display-settings.cpp:1147 +#: ../../po/../src/dialogs/text-edit.cpp:353 +#: ../../po/../src/ui/dialog/text-properties.cpp:37 +#: ../../po/../src/verbs.cpp:2069 +msgid "Text" +msgstr "Texto" + +#: ../../po/../src/dialogs/display-settings.cpp:1157 +#: ../../po/../src/verbs.cpp:2071 +#, fuzzy +msgid "Gradient" +msgstr "Preencher com Gradiente" + +#: ../../po/../src/dialogs/display-settings.cpp:1164 +#: ../../po/../src/verbs.cpp:2077 +#, fuzzy +msgid "Connector" +msgstr "Cantos:" + +#: ../../po/../src/dialogs/display-settings.cpp:1171 +#: ../../po/../src/verbs.cpp:2075 +msgid "Dropper" +msgstr "Conta-Gotas" + +#. Windows +#: ../../po/../src/dialogs/display-settings.cpp:1183 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:59 +#, fuzzy +msgid "Windows" +msgstr "janela1" + +#: ../../po/../src/dialogs/display-settings.cpp:1188 +#, fuzzy +msgid "Save window geometry" +msgstr "Gravar documento" + +#: ../../po/../src/dialogs/display-settings.cpp:1189 +msgid "" +"Save the window size and position with each document (only for Inkscape SVG " +"format)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1196 +msgid "Dialogs are hidden in taskbar" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1197 +msgid "Whether dialog windows are to be hidden in the window manager taskbar" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1204 +#, fuzzy +msgid "Zoom when window is resized" +msgstr "Zoom do desenho se o tamanho da janela se alterar" + +#: ../../po/../src/dialogs/display-settings.cpp:1205 +msgid "" +"Zoom drawing when document window is resized, to keep the same area visible " +"(this is the default which can be changed in any window using the button " +"above the right scrollbar)" +msgstr "" + +#. Clones +#: ../../po/../src/dialogs/display-settings.cpp:1213 +#: ../../po/../src/dialogs/find.cpp:624 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:60 +#, fuzzy +msgid "Clones" +msgstr "Fechar" + +#: ../../po/../src/dialogs/display-settings.cpp:1217 +msgid "When the original moves, its clones and linked offsets:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1229 +msgid "Move in parallel" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1230 +msgid "Clones are translated by the same vector as their original." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1237 +msgid "Stay unmoved" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1238 +msgid "Clones preserve their positions when their original is moved." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1245 +msgid "Move according to transform" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1246 +msgid "" +"Each clone moves according to the value of its transform= attribute. For " +"example, a rotated clone will move in a different direction than its " +"original." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1255 +msgid "When the original is deleted, its clones:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1267 +msgid "Are unlinked" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1267 +msgid "Orphaned clones are converted to regular objects." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1273 +#, fuzzy +msgid "Are deleted" +msgstr "Primeiro seleccionado" + +#: ../../po/../src/dialogs/display-settings.cpp:1273 +msgid "Orphaned clones are deleted along with their original." +msgstr "" + +#. Transforms +#. TRANSLATORS: Noun, i.e. transformations. +#: ../../po/../src/dialogs/display-settings.cpp:1289 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:61 +#, fuzzy +msgid "Transforms" +msgstr "Transformações" + +#: ../../po/../src/dialogs/display-settings.cpp:1292 +#, fuzzy +msgid "Scale stroke width" +msgstr "Largura da rasura" + +#: ../../po/../src/dialogs/display-settings.cpp:1293 +#: ../../po/../src/widgets/select-toolbar.cpp:568 +msgid "When scaling objects, scale the stroke width by the same proportion" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1300 +msgid "Scale rounded corners in rectangles" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1301 +#: ../../po/../src/widgets/select-toolbar.cpp:580 +msgid "When scaling rectangles, scale the radii of rounded corners" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1308 +#, fuzzy +msgid "Transform gradients" +msgstr "Transformações" + +#: ../../po/../src/dialogs/display-settings.cpp:1309 +#: ../../po/../src/widgets/select-toolbar.cpp:592 +msgid "Transform gradients (in fill or stroke) along with the objects" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1316 +#, fuzzy +msgid "Transform patterns" +msgstr "Transformação" + +#: ../../po/../src/dialogs/display-settings.cpp:1317 +#: ../../po/../src/widgets/select-toolbar.cpp:604 +msgid "Transform patterns (in fill or stroke) along with the objects" +msgstr "" + +#. TRANSLATORS: How to specify the affine transformation in the SVG file. +#: ../../po/../src/dialogs/display-settings.cpp:1327 +#, fuzzy +msgid "Store transformation:" +msgstr "Transformação objecto" + +#: ../../po/../src/dialogs/display-settings.cpp:1338 +#, fuzzy +msgid "Optimized" +msgstr "Optimizar" + +#: ../../po/../src/dialogs/display-settings.cpp:1339 +msgid "" +"If possible, apply transformation to objects without adding a transform= " +"attribute" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1346 +#, fuzzy +msgid "Preserved" +msgstr "Preservar" + +#: ../../po/../src/dialogs/display-settings.cpp:1347 +msgid "Always store transformation as a transform= attribute on objects" +msgstr "" + +#. Selecting +#: ../../po/../src/dialogs/display-settings.cpp:1355 +#, fuzzy +msgid "Selecting" +msgstr "Selecção" + +#: ../../po/../src/dialogs/display-settings.cpp:1357 +msgid "Ctrl+A, Tab, Shift+Tab:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1366 +#, fuzzy +msgid "Select only within current layer" +msgstr "Seleccionar" + +#: ../../po/../src/dialogs/display-settings.cpp:1367 +msgid "" +"Uncheck this to make keyboard selection commands work on objects in all " +"layers" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1374 +msgid "Ignore hidden objects" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1375 +msgid "" +"Uncheck this to be able to select objects that are hidden (either by " +"themselves or by being in a hidden group or layer)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1382 +#, fuzzy +msgid "Ignore locked objects" +msgstr "Objectos seleccionados" + +#: ../../po/../src/dialogs/display-settings.cpp:1383 +msgid "" +"Uncheck this to be able to select objects that are locked (either by " +"themselves or by being in a locked group or layer)" +msgstr "" + +#. To be broken into: Display, Save, Export, SVG, Commands +#: ../../po/../src/dialogs/display-settings.cpp:1391 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:62 +msgid "Misc" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1394 +msgid "Default export resolution:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1395 +#, fuzzy +msgid "Default bitmap resolution (in dots per inch) in the Export dialog" +msgstr "Resolução preferida (pontos por polegada) do bitmap" + +#. FIXME: add "Used for new exports; once exported, documents remember this value on per-object basis" when implemented +#: ../../po/../src/dialogs/display-settings.cpp:1396 +#: ../../po/../src/dialogs/export.cpp:442 +msgid "dpi" +msgstr "dpi" + +#. TRANSLATORS: When on, an imported bitmap creates an element; otherwise it is a +#. * rectangle with bitmap fill. +#: ../../po/../src/dialogs/display-settings.cpp:1407 +#, fuzzy +msgid "Import bitmap as " +msgstr "Importar para o documento imagem SVG ou bitmap" + +#: ../../po/../src/dialogs/display-settings.cpp:1408 +msgid "" +"When on, an imported bitmap creates an element; otherwise it is a " +"rectangle with bitmap fill" +msgstr "" + +#. TRANSLATORS: When on, the print out (currently Postscript) will have +#. * a comment with the each object's label visible, marking the section +#. * of the printing commands that represent the given object. +#: ../../po/../src/dialogs/display-settings.cpp:1418 +msgid "Add label comments to printing output" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1419 +msgid "" +"When on, a comment will be added to the raw print output, marking the " +"rendered output for an object with its label" +msgstr "" + +#. TRANSLATORS: When on, enable the effects menu, default is off +#: ../../po/../src/dialogs/display-settings.cpp:1427 +msgid "Enable script effects (requires restart) - EXPERIMENTAL" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1428 +msgid "" +"When on, the effects menu is enabled, allowing external effect scripts to be " +"called, requires restart before effective - EXPERIMENTAL" +msgstr "" + +#. TRANSLATORS: The maximum length of the Open Recent list in the File menu. +#: ../../po/../src/dialogs/display-settings.cpp:1436 +#, fuzzy +msgid "Max recent documents:" +msgstr "Imprimir documento" + +#: ../../po/../src/dialogs/display-settings.cpp:1437 +msgid "The maximum length of the Open Recent list in the File menu" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1447 +msgid "Simplification threshold:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1448 +msgid "" +"How strong is the Simplify command by default. If you invoke this command " +"several times in quick succession, it will act more and more aggressively; " +"invoking it again after a pause restores the default threshold." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1469 +msgid "Oversample bitmaps:" +msgstr "Re-amostrar as imagens por:" + +#: ../../po/../src/dialogs/display-settings.cpp:1488 +msgid "2x2" +msgstr "2x2" + +#: ../../po/../src/dialogs/display-settings.cpp:1494 +msgid "4x4" +msgstr "4x4" + +#: ../../po/../src/dialogs/display-settings.cpp:1500 +msgid "8x8" +msgstr "8x8" + +#: ../../po/../src/dialogs/display-settings.cpp:1506 +msgid "16x16" +msgstr "16x16" + +#. "view_icon_preview" +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2143 +msgid "_Page" +msgstr "_Página" + +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2147 +msgid "_Drawing" +msgstr "_Desenho" + +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2149 +msgid "_Selection" +msgstr "_Selecção" + +#: ../../po/../src/dialogs/export.cpp:133 +#, fuzzy +msgid "_Custom" +msgstr "Costumizado" + +#: ../../po/../src/dialogs/export.cpp:254 +msgid "Export area" +msgstr "Exportar área" + +#: ../../po/../src/dialogs/export.cpp:300 +#, fuzzy +msgid "_x0:" +msgstr "x0:" + +#: ../../po/../src/dialogs/export.cpp:305 +#, fuzzy +msgid "x_1:" +msgstr "x1:" + +#: ../../po/../src/dialogs/export.cpp:316 +#, fuzzy +msgid "_y0:" +msgstr "y0:" + +#: ../../po/../src/dialogs/export.cpp:321 +#, fuzzy +msgid "y_1:" +msgstr "y1:" + +#: ../../po/../src/dialogs/export.cpp:406 +msgid "Bitmap size" +msgstr "Tamanho da imagem" + +#: ../../po/../src/dialogs/export.cpp:416 +#, fuzzy +msgid "_Width:" +msgstr "Largura:" + +#: ../../po/../src/dialogs/export.cpp:416 +#: ../../po/../src/dialogs/export.cpp:431 +#, fuzzy +msgid "pixels at" +msgstr "pixels" + +#: ../../po/../src/dialogs/export.cpp:426 +#, fuzzy +msgid "dp_i" +msgstr "dpi" + +#: ../../po/../src/dialogs/export.cpp:448 +#, fuzzy +msgid "_Filename" +msgstr "Ficheiro:" + +#: ../../po/../src/dialogs/export.cpp:512 +msgid "_Browse..." +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:539 +#, fuzzy +msgid " _Export " +msgstr "Alterar" + +#: ../../po/../src/dialogs/export.cpp:541 +msgid "Export the bitmap file with these settings" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:968 +#, fuzzy +msgid "You have to enter a filename" +msgstr "Gravar desenho com novo nome" + +#: ../../po/../src/dialogs/export.cpp:973 +msgid "The chosen area to be exported is invalid" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:982 +#, c-format +msgid "Directory %s does not exist or is not a directory.\n" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:998 +#, fuzzy +msgid "Export in progress" +msgstr "Exportar área" + +#: ../../po/../src/dialogs/export.cpp:1004 +#, fuzzy, c-format +msgid "Exporting %s (%d x %d)" +msgstr "Imagem colorida %d x %d: %s" + +#: ../../po/../src/dialogs/export.cpp:1031 +#, c-format +msgid "Could not export to filename %s.\n" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:1137 +#, fuzzy +msgid "Select a filename for exporting" +msgstr "Seleccione o ficheiro a importar" + +#: ../../po/../src/dialogs/filedialog.cpp:367 +#, fuzzy +msgid "No preview" +msgstr "Nova Antevisão" + +#: ../../po/../src/dialogs/filedialog.cpp:468 +msgid "too large for preview" +msgstr "" + +#: ../../po/../src/dialogs/filedialog.cpp:762 +#: ../../po/../src/dialogs/filedialog.cpp:763 +#, fuzzy +msgid "All Images" +msgstr "Imagem" + +#: ../../po/../src/dialogs/filedialog.cpp:767 +#: ../../po/../src/dialogs/filedialog.cpp:768 +#, fuzzy +msgid "All Files" +msgstr "Estilo preenchimento" + +#: ../../po/../src/dialogs/filedialog.cpp:774 +#: ../../po/../src/dialogs/filedialog.cpp:775 +#, fuzzy +msgid "All Inkscape Files" +msgstr "Apresentação Sodipodi" + +#: ../../po/../src/dialogs/filedialog.cpp:1176 +#, fuzzy +msgid "Guess from extension" +msgstr "Transformar selecção" + +#. ###### Add the file types menu +#. createFilterMenu(); +#. ###### Do we want the .xxx extension automatically added? +#: ../../po/../src/dialogs/filedialog.cpp:1261 +msgid "Append filename extension automatically" +msgstr "" + +#. TRANSLATORS: "%s" is replaced with "exact" or "partial" when this string is displayed +#: ../../po/../src/dialogs/find.cpp:378 +#, fuzzy, c-format +msgid "%d object found (out of %d), %s match." +msgid_plural "%d objects found (out of %d), %s match." +msgstr[0] "Juntar linhas nos nós seleccionados" +msgstr[1] "Juntar linhas nos nós seleccionados" + +#: ../../po/../src/dialogs/find.cpp:381 +#, fuzzy +msgid "exact" +msgstr "Texto" + +#: ../../po/../src/dialogs/find.cpp:381 +#, fuzzy +msgid "partial" +msgstr "Espiral" + +#: ../../po/../src/dialogs/find.cpp:388 +#, fuzzy +msgid "No objects found" +msgstr "Nenhum objecto" + +#: ../../po/../src/dialogs/find.cpp:546 +#, fuzzy +msgid "T_ype: " +msgstr "Tipo:" + +#: ../../po/../src/dialogs/find.cpp:553 +msgid "Search in all object types" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:553 +#, fuzzy +msgid "All types" +msgstr "Estilo preenchimento" + +#: ../../po/../src/dialogs/find.cpp:564 +msgid "Search all shapes" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:564 +#, fuzzy +msgid "All shapes" +msgstr "Todas as ferramentas de formas" + +#: ../../po/../src/dialogs/find.cpp:581 +#, fuzzy +msgid "Search rectangles" +msgstr "Rectângulo" + +#: ../../po/../src/dialogs/find.cpp:581 +#, fuzzy +msgid "Rectangles" +msgstr "Rectângulo" + +#: ../../po/../src/dialogs/find.cpp:586 +msgid "Search ellipses, arcs, circles" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:586 +#, fuzzy +msgid "Ellipses" +msgstr "Elipse" + +#: ../../po/../src/dialogs/find.cpp:591 +#, fuzzy +msgid "Search stars and polygons" +msgstr "Criar estrelas e polígonos" + +#: ../../po/../src/dialogs/find.cpp:591 +#, fuzzy +msgid "Stars" +msgstr "Estrela" + +#: ../../po/../src/dialogs/find.cpp:596 +#, fuzzy +msgid "Search spirals" +msgstr "Criar espirais" + +#: ../../po/../src/dialogs/find.cpp:596 +#, fuzzy +msgid "Spirals" +msgstr "Espiral" + +#. TRANSLATORS: polyline is a set of connected straight line segments +#. http://www.w3.org/TR/SVG11/shapes.html#PolylineElement +#: ../../po/../src/dialogs/find.cpp:609 +msgid "Search paths, lines, polylines" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:609 +msgid "Paths" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:614 +#, fuzzy +msgid "Search text objects" +msgstr "Objectos seleccionados" + +#: ../../po/../src/dialogs/find.cpp:614 +#, fuzzy +msgid "Texts" +msgstr "Texto" + +#: ../../po/../src/dialogs/find.cpp:619 +msgid "Search groups" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:619 +#, fuzzy +msgid "Groups" +msgstr "Agrupar" + +#: ../../po/../src/dialogs/find.cpp:624 +msgid "Search clones" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:629 +msgid "Search images" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:629 +#, fuzzy +msgid "Images" +msgstr "Imagem" + +#: ../../po/../src/dialogs/find.cpp:634 +#, fuzzy +msgid "Search offset objects" +msgstr "Criar e editar objectos de texto" + +#: ../../po/../src/dialogs/find.cpp:634 +msgid "Offsets" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:694 +#, fuzzy +msgid "_Text: " +msgstr "Texto" + +#: ../../po/../src/dialogs/find.cpp:694 +msgid "Find objects by their text content (exact or partial match)" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:695 +msgid "_ID: " +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:695 +msgid "Find objects by the value of the id attribute (exact or partial match)" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:696 +#, fuzzy +msgid "_Style: " +msgstr " Estilo " + +#: ../../po/../src/dialogs/find.cpp:696 +msgid "" +"Find objects by the value of the style attribute (exact or partial match)" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:697 +#, fuzzy +msgid "_Attribute: " +msgstr "Atributo:" + +#: ../../po/../src/dialogs/find.cpp:697 +msgid "Find objects by the name of an attribute (exact or partial match)" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:711 +#, fuzzy +msgid "Search in s_election" +msgstr "Zoom à selecção" + +#: ../../po/../src/dialogs/find.cpp:715 +msgid "Limit search to the current selection" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:720 +#, fuzzy +msgid "Search in current _layer" +msgstr "Seleccionar" + +#: ../../po/../src/dialogs/find.cpp:724 +#, fuzzy +msgid "Limit search to the current layer" +msgstr "Seleccionar" + +#: ../../po/../src/dialogs/find.cpp:729 +msgid "Include _hidden" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:733 +msgid "Include hidden objects in search" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:738 +msgid "Include l_ocked" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:742 +#, fuzzy +msgid "Include locked objects in search" +msgstr "Objectos seleccionados" + +#: ../../po/../src/dialogs/find.cpp:753 +#, fuzzy +msgid "Clear values" +msgstr "Limpar Tudo" + +#: ../../po/../src/dialogs/find.cpp:754 +#, fuzzy +msgid "_Find" +msgstr "Grelha" + +#: ../../po/../src/dialogs/find.cpp:754 +msgid "Select objects matching all of the fields you filled in" +msgstr "" + +#: ../../po/../src/dialogs/iconpreview.cpp:145 +#, c-format +msgid "%d x %d" +msgstr "" + +#: ../../po/../src/dialogs/iconpreview.cpp:193 +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:857 +#: ../../po/../src/widgets/desktop-widget.cpp:1069 +msgid "Selection" +msgstr "Selecção" + +#: ../../po/../src/dialogs/iconpreview.cpp:195 +#, fuzzy +msgid "Selection only or whole document" +msgstr "Seleccionar" + +#: ../../po/../src/dialogs/iconpreview.cpp:203 +msgid "Refresh the icons" +msgstr "" + +#. Create the label for the object id +#: ../../po/../src/dialogs/item-properties.cpp:126 +#: ../../po/../src/dialogs/item-properties.cpp:327 +#: ../../po/../src/dialogs/item-properties.cpp:396 +#: ../../po/../src/dialogs/item-properties.cpp:403 +msgid "_Id" +msgstr "" + +#: ../../po/../src/dialogs/item-properties.cpp:135 +msgid "" +"The id= attribute (only letters, digits, and the characters .-_: allowed)" +msgstr "" + +#. Button for setting the object's id, label, title and description. +#: ../../po/../src/dialogs/item-properties.cpp:149 +#, fuzzy +msgid "_Set" +msgstr "Seleccionar" + +#. Create the label for the object label +#: ../../po/../src/dialogs/item-properties.cpp:158 +#, fuzzy +msgid "_Label" +msgstr "Definir atributo" + +#: ../../po/../src/dialogs/item-properties.cpp:167 +msgid "A freeform label for the object" +msgstr "" + +#. Create the label for the object title +#: ../../po/../src/dialogs/item-properties.cpp:179 +#: ../../po/../src/dialogs/rdf.cpp:243 +#, fuzzy +msgid "Title" +msgstr "Título:" + +#. Create the frame for the object description +#: ../../po/../src/dialogs/item-properties.cpp:196 +#: ../../po/../src/dialogs/rdf.cpp:287 +#, fuzzy +msgid "Description" +msgstr "Posição" + +#. Hide +#: ../../po/../src/dialogs/item-properties.cpp:223 +#, fuzzy +msgid "_Hide" +msgstr "Lados:" + +#: ../../po/../src/dialogs/item-properties.cpp:224 +msgid "Check to make the object invisible" +msgstr "" + +#. Lock +#. TRANSLATORS: "Lock" is a verb here +#: ../../po/../src/dialogs/item-properties.cpp:233 +msgid "L_ock" +msgstr "" + +#: ../../po/../src/dialogs/item-properties.cpp:234 +msgid "Check to make the object insensitive (not selectable by mouse)" +msgstr "" + +#: ../../po/../src/dialogs/item-properties.cpp:310 +#: ../../po/../src/dialogs/item-properties.cpp:317 +msgid "Ref" +msgstr "" + +#: ../../po/../src/dialogs/item-properties.cpp:398 +#, fuzzy +msgid "Id invalid! " +msgstr "O identificador é válido" + +#: ../../po/../src/dialogs/item-properties.cpp:400 +msgid "Id exists! " +msgstr "" + +#: ../../po/../src/dialogs/layer-properties.cpp:50 +msgid "Layer name:" +msgstr "" + +#: ../../po/../src/dialogs/layer-properties.cpp:133 +#, fuzzy +msgid "Rename Layer" +msgstr "Elevar nó" + +#: ../../po/../src/dialogs/layer-properties.cpp:136 +#, fuzzy +msgid "_Rename" +msgstr "Ficheiro:" + +#. TRANSLATORS: This means "The layer has been renamed" +#: ../../po/../src/dialogs/layer-properties.cpp:147 +#, fuzzy +msgid "Renamed layer" +msgstr "Elevar nó" + +#: ../../po/../src/dialogs/layer-properties.cpp:151 +#, fuzzy +msgid "Add Layer" +msgstr "Baixar" + +#: ../../po/../src/dialogs/layer-properties.cpp:153 +#, fuzzy +msgid "_Add" +msgstr "Adicionar" + +#: ../../po/../src/dialogs/layer-properties.cpp:167 +msgid "New layer created." +msgstr "" + +#: ../../po/../src/dialogs/object-attributes.cpp:34 +msgid "Href:" +msgstr "Href:" + +#: ../../po/../src/dialogs/object-attributes.cpp:35 +msgid "Target:" +msgstr "Alvo:" + +#: ../../po/../src/dialogs/object-attributes.cpp:36 +msgid "Type:" +msgstr "Tipo:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkRoleAttribute +#. Identifies the type of the related resource with an absolute URI +#: ../../po/../src/dialogs/object-attributes.cpp:39 +msgid "Role:" +msgstr "Rolamento:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkArcRoleAttribute +#. For situations where the nature/role alone isn't enough, this offers an additional URI defining the purpose of the link. +#: ../../po/../src/dialogs/object-attributes.cpp:42 +msgid "Arcrole:" +msgstr "Arco rolamento:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkTitleAttribute +#: ../../po/../src/dialogs/object-attributes.cpp:44 +msgid "Title:" +msgstr "Título:" + +#: ../../po/../src/dialogs/object-attributes.cpp:45 +msgid "Show:" +msgstr "Mostrar:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkActuateAttribute +#: ../../po/../src/dialogs/object-attributes.cpp:47 +msgid "Actuate:" +msgstr "Actuar:" + +#: ../../po/../src/dialogs/object-attributes.cpp:52 +msgid "URL:" +msgstr "URL:" + +#: ../../po/../src/dialogs/object-attributes.cpp:53 +msgid "X:" +msgstr "X:" + +#: ../../po/../src/dialogs/object-attributes.cpp:54 +msgid "Y:" +msgstr "Y:" + +#: ../../po/../src/dialogs/object-attributes.cpp:98 +#, c-format +msgid "%s attributes" +msgstr "atributos %s" + +#: ../../po/../src/dialogs/object-properties.cpp:158 +#, fuzzy +msgid "_Fill" +msgstr "Preenchimento" + +#: ../../po/../src/dialogs/object-properties.cpp:165 +#, fuzzy +msgid "Stroke _paint" +msgstr "Largura da rasura" + +#: ../../po/../src/dialogs/object-properties.cpp:172 +#, fuzzy +msgid "Stroke st_yle" +msgstr "Preferências pincelada" + +#: ../../po/../src/dialogs/object-properties.cpp:183 +#, fuzzy +msgid "Master _opacity" +msgstr "Opacidade:" + +#: ../../po/../src/dialogs/rdf.cpp:244 +msgid "Name by which this document is formally known." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:246 +#, fuzzy +msgid "Date" +msgstr "Escrever texto" + +#: ../../po/../src/dialogs/rdf.cpp:247 +msgid "Date associated with the creation of this document (YYYY-MM-DD)." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:249 +msgid "Format" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:250 +msgid "The physical or digital manifestation of this document (MIME type)." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:252 +#, fuzzy +msgid "Type" +msgstr "Tipo:" + +#: ../../po/../src/dialogs/rdf.cpp:253 +msgid "Type of document (DCMI Type)." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:256 +#, fuzzy +msgid "Creator" +msgstr "Criar" + +#: ../../po/../src/dialogs/rdf.cpp:257 +msgid "" +"Name of entity primarily responsible for making the content of this document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:259 +#, fuzzy +msgid "Rights" +msgstr "Altura" + +#: ../../po/../src/dialogs/rdf.cpp:260 +msgid "" +"Name of entity with rights to the Intellectual Property of this document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:262 +msgid "Publisher" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:263 +msgid "Name of entity responsible for making this document available." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:266 +#, fuzzy +msgid "Identifier" +msgstr "Centrar" + +#: ../../po/../src/dialogs/rdf.cpp:267 +msgid "Unique URI to reference this document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:269 +msgid "Source" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:270 +msgid "Unique URI to reference the source of this document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:272 +#, fuzzy +msgid "Relation" +msgstr "Resolução:" + +#: ../../po/../src/dialogs/rdf.cpp:273 +#, fuzzy +msgid "Unique URI to a related document." +msgstr "Documento sem título" + +#: ../../po/../src/dialogs/rdf.cpp:275 +#, fuzzy +msgid "Language" +msgstr "ângulo" + +#: ../../po/../src/dialogs/rdf.cpp:276 +msgid "" +"Two-letter language tag with optional subtags for the language of this " +"document. (e.g. 'en-GB')" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:278 +msgid "Keywords" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:279 +msgid "" +"The topic of this document as comma-separated key words, phrases, or " +"classifications." +msgstr "" + +#. TRANSLATORS: "Coverage": the spatial or temporal characteristics of the content. +#. For info, see Appendix D of http://www.w3.org/TR/1998/WD-rdf-schema-19980409/ +#: ../../po/../src/dialogs/rdf.cpp:283 +msgid "Coverage" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:284 +msgid "Extent or scope of this document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:288 +msgid "A short account of the content of this document." +msgstr "" + +#. FIXME: need to handle 1 agent per line of input +#: ../../po/../src/dialogs/rdf.cpp:292 +#, fuzzy +msgid "Contributors" +msgstr "Centímetros" + +#: ../../po/../src/dialogs/rdf.cpp:293 +msgid "" +"Names of entities responsible for making contributions to the content of " +"this document." +msgstr "" + +#. TRANSLATORS: URL to a page that defines the license for the document +#: ../../po/../src/dialogs/rdf.cpp:297 +msgid "URI" +msgstr "" + +#. TRANSLATORS: this is where you put a URL to a page that defines the license +#: ../../po/../src/dialogs/rdf.cpp:299 +msgid "URI to this document's license's namespace definition." +msgstr "" + +#. TRANSLATORS: fragment of XML representing the license of the document +#: ../../po/../src/dialogs/rdf.cpp:303 +#, fuzzy +msgid "Fragment" +msgstr "Argumento:" + +#: ../../po/../src/dialogs/rdf.cpp:304 +msgid "XML fragment for the RDF 'License' section." +msgstr "" + +#: ../../po/../src/dialogs/stroke-style.cpp:774 +#: ../../po/../src/widgets/gradient-vector.cpp:263 +#: ../../po/../src/widgets/paint-selector.cpp:751 +msgid "No document selected" +msgstr "Nenhum documento seleccionado" + +#: ../../po/../src/dialogs/stroke-style.cpp:992 +#, fuzzy +msgid "Stroke width" +msgstr "Largura da rasura" + +#. Join type +#. TRANSLATORS: The line join style specifies the shape to be used at the +#. corners of paths. It can be "miter", "round" or "bevel". +#: ../../po/../src/dialogs/stroke-style.cpp:1015 +msgid "Join:" +msgstr "Ligação:" + +#. TRANSLATORS: Miter join: joining lines with a sharp (pointed) corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1027 +msgid "Miter join" +msgstr "Conexão em junta" + +#. TRANSLATORS: Round join: joining lines with a rounded corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1035 +msgid "Round join" +msgstr "Conexão arredondada" + +#. TRANSLATORS: Bevel join: joining lines with a blunted (flattened) corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1043 +msgid "Bevel join" +msgstr "Conexão hiperbólica" + +#. Miterlimit +#. TRANSLATORS: Miter limit: only for "miter join", this limits the length +#. of the sharp "spike" when the lines connect at too sharp an angle. +#. When two line segments meet at a sharp angle, a miter join results in a +#. spike that extends well beyond the connection point. The purpose of the +#. miter limit is to cut off such spikes (i.e. convert them into bevels) +#. when they become too long. +#: ../../po/../src/dialogs/stroke-style.cpp:1054 +#, fuzzy +msgid "Miter limit:" +msgstr "Conexão em junta" + +#: ../../po/../src/dialogs/stroke-style.cpp:1062 +msgid "Maximum length of the miter (in units of stroke width)" +msgstr "" + +#. Cap type +#. TRANSLATORS: cap type specifies the shape for the ends of lines +#: ../../po/../src/dialogs/stroke-style.cpp:1075 +msgid "Cap:" +msgstr "Capa:" + +#. TRANSLATORS: Butt cap: the line shape does not extend beyond the end point +#. of the line; the ends of the line are square +#: ../../po/../src/dialogs/stroke-style.cpp:1086 +msgid "Butt cap" +msgstr "" + +#. TRANSLATORS: Round cap: the line shape extends beyond the end point of the +#. line; the ends of the line are rounded +#: ../../po/../src/dialogs/stroke-style.cpp:1093 +#, fuzzy +msgid "Round cap" +msgstr "Conexão arredondada" + +#. TRANSLATORS: Square cap: the line shape extends beyond the end point of the +#. line; the ends of the line are square +#: ../../po/../src/dialogs/stroke-style.cpp:1100 +#, fuzzy +msgid "Square cap" +msgstr "Terminação quadrada" + +#. Dash +#: ../../po/../src/dialogs/stroke-style.cpp:1106 +#, fuzzy +msgid "Dashes:" +msgstr "Massa:" + +#. TRANSLATORS: Path markers are an SVG feature that allows you to attach arbitrary shapes +#. (arrowheads, bullets, faces, whatever) to the start, end, or middle nodes of a path. +#: ../../po/../src/dialogs/stroke-style.cpp:1127 +#, fuzzy +msgid "Start Markers:" +msgstr "Propriedades da Estrela" + +#: ../../po/../src/dialogs/stroke-style.cpp:1137 +msgid "Mid Markers:" +msgstr "" + +#: ../../po/../src/dialogs/stroke-style.cpp:1148 +msgid "End Markers:" +msgstr "" + +#: ../../po/../src/dialogs/swatches.cpp:424 +#, c-format +msgid "Palettes directory (%s) is unavailable." +msgstr "" + +#. TODO: Insert widgets +#: ../../po/../src/dialogs/text-edit.cpp:199 +#: ../../po/../src/ui/dialog/text-properties.cpp:36 +#, fuzzy +msgid "Font" +msgstr "Ponto" + +#: ../../po/../src/dialogs/text-edit.cpp:216 +msgid "Layout" +msgstr "Disposição" + +#: ../../po/../src/dialogs/text-edit.cpp:229 +#, fuzzy +msgid "Align lines left" +msgstr "Alinhar à esquerda em cima" + +#. TRANSLATORS: `Center' here is a verb. +#: ../../po/../src/dialogs/text-edit.cpp:243 +#, fuzzy +msgid "Center lines" +msgstr "Centrar Y:" + +#: ../../po/../src/dialogs/text-edit.cpp:256 +#, fuzzy +msgid "Align lines right" +msgstr "Alinhar à direita em cima" + +#: ../../po/../src/dialogs/text-edit.cpp:278 +#, fuzzy +msgid "Horizontal text" +msgstr "mover horizontalmente" + +#: ../../po/../src/dialogs/text-edit.cpp:292 +#, fuzzy +msgid "Vertical text" +msgstr "Valor vertical do centro" + +#: ../../po/../src/dialogs/text-edit.cpp:307 +msgid "Line spacing:" +msgstr "Espaçamento linha:" + +#: ../../po/../src/dialogs/text-edit.cpp:400 +msgid "Set as default" +msgstr "Definir por omissão" + +#: ../../po/../src/dialogs/tiledialog.cpp:603 +#, fuzzy +msgid "Rows:" +msgstr "Mostrar:" + +#: ../../po/../src/dialogs/tiledialog.cpp:613 +#, fuzzy +msgid "Number of rows" +msgstr "Número de cantos:" + +#: ../../po/../src/dialogs/tiledialog.cpp:617 +#, fuzzy +msgid "Equal height" +msgstr "Altura: " + +#: ../../po/../src/dialogs/tiledialog.cpp:627 +msgid "If not set, each row has the height of the tallest object in it" +msgstr "" + +#. #### Radio buttons to control vertical alignment #### +#. #### Radio buttons to control horizontal alignment #### +#: ../../po/../src/dialogs/tiledialog.cpp:637 +#: ../../po/../src/dialogs/tiledialog.cpp:708 +#, fuzzy +msgid "Align:" +msgstr "Alinhar" + +#: ../../po/../src/dialogs/tiledialog.cpp:672 +#, fuzzy +msgid " X " +msgstr "X +" + +#. #### Number of columns #### +#: ../../po/../src/dialogs/tiledialog.cpp:678 +#, fuzzy +msgid "Columns:" +msgstr "Alterar" + +#: ../../po/../src/dialogs/tiledialog.cpp:688 +#, fuzzy +msgid "Number of columns" +msgstr "Número de cantos:" + +#: ../../po/../src/dialogs/tiledialog.cpp:692 +#, fuzzy +msgid "Equal width" +msgstr "Largura:" + +#: ../../po/../src/dialogs/tiledialog.cpp:701 +msgid "If not set, each column has the width of the widest object in it" +msgstr "" + +#. #### Radio buttons to control spacing manually or to fit selection bbox #### +#: ../../po/../src/dialogs/tiledialog.cpp:746 +#, fuzzy +msgid "Fit into selection box" +msgstr "Cortar selecção" + +#: ../../po/../src/dialogs/tiledialog.cpp:753 +#, fuzzy +msgid "Set spacing:" +msgstr "Espaçamento Y:" + +#. #### Y Padding #### +#: ../../po/../src/dialogs/tiledialog.cpp:777 +#, fuzzy +msgid "Row spacing: " +msgstr "Espaçamento linha:" + +#: ../../po/../src/dialogs/tiledialog.cpp:786 +#, fuzzy +msgid "Vertical spacing between rows" +msgstr "Valor vertical do centro" + +#. #### X padding #### +#: ../../po/../src/dialogs/tiledialog.cpp:795 +#, fuzzy +msgid "Column spacing:" +msgstr "Espaçamento linha:" + +#: ../../po/../src/dialogs/tiledialog.cpp:804 +#, fuzzy +msgid "Horizontal spacing between columns" +msgstr "valor do escalamento horizontal" + +#: ../../po/../src/dialogs/tiledialog.cpp:818 +#, fuzzy +msgid "Arrange selected objects" +msgstr "Agrupar objectos seleccionados" + +#: ../../po/../src/dialogs/xml-tree.cpp:178 +msgid "Click to select nodes, drag to rearrange." +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:189 +msgid "Click attribute to edit." +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:193 +#, c-format +msgid "" +"Attribute %s selected. Press Ctrl+Enter when done editing to " +"commit changes." +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:284 +msgid "Drag to reorder nodes" +msgstr "Arrastar para reordenar nós" + +#: ../../po/../src/dialogs/xml-tree.cpp:304 +msgid "New element node" +msgstr "Novo nó de elemento" + +#: ../../po/../src/dialogs/xml-tree.cpp:326 +msgid "New text node" +msgstr "Novo nó de texto" + +#: ../../po/../src/dialogs/xml-tree.cpp:347 +msgid "Duplicate node" +msgstr "Duplicar nó" + +#: ../../po/../src/dialogs/xml-tree.cpp:368 +msgid "Delete node" +msgstr "Apagar nó" + +#: ../../po/../src/dialogs/xml-tree.cpp:384 +msgid "Unindent node" +msgstr "Desindentar nó" + +#: ../../po/../src/dialogs/xml-tree.cpp:399 +msgid "Indent node" +msgstr "Indentar nó" + +#: ../../po/../src/dialogs/xml-tree.cpp:411 +msgid "Raise node" +msgstr "Elevar nó" + +#: ../../po/../src/dialogs/xml-tree.cpp:423 +msgid "Lower node" +msgstr "Descer nó" + +#: ../../po/../src/dialogs/xml-tree.cpp:468 +msgid "Delete attribute" +msgstr "Apagar atributo" + +#. TRANSLATORS: "Attribute" is a noun here +#: ../../po/../src/dialogs/xml-tree.cpp:513 +msgid "Attribute name" +msgstr "Nome atributo" + +#. TRANSLATORS: "Set" is a verb here +#: ../../po/../src/dialogs/xml-tree.cpp:533 +msgid "Set attribute" +msgstr "Definir atributo" + +#. TRANSLATORS: "Set" is a verb here +#: ../../po/../src/dialogs/xml-tree.cpp:535 +#, fuzzy +msgid "Set" +msgstr "Seleccionar" + +#. TRANSLATORS: "Attribute" is a noun here +#: ../../po/../src/dialogs/xml-tree.cpp:558 +msgid "Attribute value" +msgstr "Valor atributo" + +#: ../../po/../src/dialogs/xml-tree.cpp:1318 +msgid "New element node..." +msgstr "Novo nó de elemento..." + +#: ../../po/../src/dialogs/xml-tree.cpp:1339 +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:100 +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:98 +msgid "Cancel" +msgstr "Cancelar" + +#: ../../po/../src/dialogs/xml-tree.cpp:1345 +msgid "Create" +msgstr "Criar" + +#: ../../po/../src/dialogs/xml-tree.cpp:1458 +#, c-format +msgid "" +"Cannot set %s: Another element with value %s already exists!" +msgstr "" + +#: ../../po/../src/document.cpp:369 +#, c-format +msgid "New document %d" +msgstr "Novo documento %d" + +#: ../../po/../src/document.cpp:401 +#, c-format +msgid "Memory document %d" +msgstr "Documento em memória %d" + +#: ../../po/../src/document.cpp:524 +#, c-format +msgid "Unnamed document %d" +msgstr "Documento sem nome %d" + +#. We hit green anchor, closing Green-Blue-Red +#: ../../po/../src/draw-context.cpp:441 +msgid "Path is closed." +msgstr "" + +#. We hit bot start and end of single curve, closing paths +#: ../../po/../src/draw-context.cpp:456 +msgid "Closing path." +msgstr "" + +#. alpha of color under cursor, to show in the statusbar +#. locale-sensitive printf is OK, since this goes to the UI, not into SVG +#: ../../po/../src/dropper-context.cpp:354 +#, c-format +msgid " alpha %.3g" +msgstr "" + +#. where the color is picked, to show in the statusbar +#: ../../po/../src/dropper-context.cpp:356 +#, c-format +msgid ", averaged with radius %d" +msgstr "" + +#: ../../po/../src/dropper-context.cpp:356 +msgid " under cursor" +msgstr "" + +#. message, to show in the statusbar +#: ../../po/../src/dropper-context.cpp:358 +msgid "Release mouse to set color." +msgstr "" + +#: ../../po/../src/dropper-context.cpp:358 +#: ../../po/../src/tools-switch.cpp:207 +msgid "" +"Click to set fill, Shift+click to set stroke; drag to " +"average color in area; with Alt to pick inverse color; Ctrl+C " +"to copy the color under mouse to clipboard" +msgstr "" + +#: ../../po/../src/extension/dependency.cpp:244 +msgid "Dependency::" +msgstr "" + +#: ../../po/../src/extension/dependency.cpp:245 +#, fuzzy +msgid " type: " +msgstr "Tipo ficheiro:" + +#: ../../po/../src/extension/dependency.cpp:246 +#, fuzzy +msgid " location: " +msgstr "Resolução:" + +#: ../../po/../src/extension/dependency.cpp:247 +msgid " string: " +msgstr "" + +#: ../../po/../src/extension/dependency.cpp:250 +#, fuzzy +msgid " description: " +msgstr "Posição" + +#. static int i = 0; +#. std::cout << "Checking module[" << i++ << "]: " << name << std::endl; +#: ../../po/../src/extension/extension.cpp:244 +msgid "" +" This is caused by an improper .inx file for this extension. An improper ." +"inx file could have been caused by a faulty installation of Inkscape." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:247 +msgid "an ID was not defined for it." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:251 +msgid "there was no name defined for it." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:255 +msgid "the XML description of it got lost." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:259 +msgid "no implementation was defined for the extension." +msgstr "" + +#. std::cout << "Failed: " << *(_deps[i]) << std::endl; +#: ../../po/../src/extension/extension.cpp:266 +msgid "a dependency was not met." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:286 +#, fuzzy +msgid "Extension \"" +msgstr "Extensão" + +#: ../../po/../src/extension/extension.cpp:286 +msgid "\" failed to load because " +msgstr "" + +#: ../../po/../src/extension/extension.cpp:565 +#, c-format +msgid "Could not create extension error log file '%s'" +msgstr "" + +#. This is some filler text, needs to change before relase +#: ../../po/../src/extension/error-file.cpp:56 +msgid "" +"One or more extensions failed to load\n" +"\n" +"The failed extensions have been skipped. Inkscape will continue to run " +"normally but those extensions will be unavailable. For details to " +"troubleshoot this problem, please refer to the error log located at: " +msgstr "" + +#. This is some filler text, needs to change before relase +#: ../../po/../src/extension/error-file.cpp:65 +msgid "Show dialog on startup" +msgstr "" + +#: ../../po/../src/extension/implementation/script.cpp:845 +msgid "" +"Inkscape has received an error from the script that it called. The text " +"returned with the error is included below. Inkscape will continue working, " +"but the action you requested has been cancelled." +msgstr "" + +#: ../../po/../src/extension/implementation/script.cpp:858 +msgid "" +"Inkscape has received additional data from the script executed. The script " +"did not return an error, but this may indicate the results will not be as " +"expected." +msgstr "" + +#: ../../po/../src/extension/init.cpp:173 +msgid "Null external module directory name. Modules will not be loaded." +msgstr "" + +#: ../../po/../src/extension/init.cpp:187 +#, c-format +msgid "" +"Modules directory (%s) is unavailable. External modules in that directory " +"will not be loaded." +msgstr "" + +#: ../../po/../src/extension/internal/gnome.cpp:80 +msgid "Select printer" +msgstr "Seleccionar impressora" + +#: ../../po/../src/extension/internal/gnome.cpp:131 +#, fuzzy +msgid "Inkscape: Print Preview" +msgstr "Sodipodi (documento %s..): Antever Impressão" + +#: ../../po/../src/extension/internal/grid.cpp:213 +#, fuzzy +msgid "Line Width" +msgstr "Largura" + +#: ../../po/../src/extension/internal/grid.cpp:214 +#, fuzzy +msgid "Horizontal Spacing" +msgstr "mover horizontalmente" + +#: ../../po/../src/extension/internal/grid.cpp:215 +#, fuzzy +msgid "Vertical Spacing" +msgstr "Valor vertical do centro" + +#: ../../po/../src/extension/internal/grid.cpp:216 +#, fuzzy +msgid "Horizontal Offset" +msgstr "mover horizontalmente" + +#: ../../po/../src/extension/internal/grid.cpp:217 +#, fuzzy +msgid "Vertical Offset" +msgstr "Valor vertical do centro" + +#: ../../po/../src/extension/internal/ps.cpp:123 +#, fuzzy +msgid "Print Destination" +msgstr "Destino impressão" + +#. Print properties frame +#: ../../po/../src/extension/internal/ps.cpp:138 +msgid "Print properties" +msgstr "Propriedades da impressão" + +#: ../../po/../src/extension/internal/ps.cpp:145 +msgid "Print using PostScript operators" +msgstr "Imprimir utilizando operadores PostScript" + +#: ../../po/../src/extension/internal/ps.cpp:147 +#, fuzzy +msgid "" +"Use PostScript vector operators. The resulting image is usually smaller in " +"file size and can be arbitrarily scaled, but alpha transparency and patterns " +"will be lost." +msgstr "" +"Utilizar operadores de vector PostScript, a imagem resultante será " +"(normalmente) menor e poderá ser arbitráriamente escalada, mas serão " +"perdidas a transparência, marcadores e padrões" + +#: ../../po/../src/extension/internal/ps.cpp:152 +msgid "Print as bitmap" +msgstr "Imprimir como bitmap" + +#: ../../po/../src/extension/internal/ps.cpp:154 +#, fuzzy +msgid "" +"Print everything as bitmap. The resulting image is usually larger in file " +"size and cannot be arbitrarily scaled without quality loss, but all objects " +"will be rendered exactly as displayed." +msgstr "" +"Imprimir tudo como bitmap, a imagem resultante será (normalmente) maior e a " +"sua qualidade dependerá do factor de zoom, mas todos os gráficos serão " +"renderizados de igual modo para o ecrã" + +#: ../../po/../src/extension/internal/ps.cpp:168 +msgid "Preferred resolution (dots per inch) of bitmap" +msgstr "Resolução preferida (pontos por polegada) do bitmap" + +#: ../../po/../src/extension/internal/ps.cpp:182 +msgid "Resolution:" +msgstr "Resolução:" + +#. Print destination frame +#: ../../po/../src/extension/internal/ps.cpp:186 +msgid "Print destination" +msgstr "Destino impressão" + +#: ../../po/../src/extension/internal/ps.cpp:192 +#, fuzzy +msgid "" +"Use '> filename' to print to file.\n" +"Use '| prog arg...' to pipe to a program." +msgstr "" +"Introduza fila lpr de destino.\n" +"Utilize '> nomeficheiro' para imprimir para ficheiro.\n" +"Utilize '| aplic arg...' para enviar para aplicação" + +#: ../../po/../src/extension/internal/ps.cpp:1227 +#, fuzzy +msgid "write error occurred" +msgstr "ocorreu erro na escrita" + +#: ../../po/../src/extension/prefdialog.cpp:21 +#, fuzzy +msgid " Preferences" +msgstr "O item é referência" + +#. We can't call sp_ui_error_dialog because we may be +#. running from the console, in which case calling sp_ui +#. routines will cause a segfault. See bug 1000350 - bryce +#. sp_ui_error_dialog(_("Format autodetect failed. The file is being opened as SVG.")); +#: ../../po/../src/extension/system.cpp:105 +msgid "Format autodetect failed. The file is being opened as SVG." +msgstr "" + +#. TRANSLATORS: default.svg is localizable - this is the name of the default document +#. template. This way you can localize the default pagesize, translate the name of +#. the default layer, etc. If you wish to localize this file, please create a +#. localized share/templates/default.xx.svg file, where xx is your language code. +#: ../../po/../src/file.cpp:133 +#, fuzzy +msgid "default.svg" +msgstr "Por Omissão" + +#: ../../po/../src/file.cpp:215 ../../po/../src/file.cpp:900 +#, c-format +msgid "Failed to load the requested file %s" +msgstr "" + +#: ../../po/../src/file.cpp:240 +#, fuzzy +msgid "Document not saved yet. Cannot revert." +msgstr "Nome Documento:" + +#: ../../po/../src/file.cpp:246 +#, c-format +msgid "Changes will be lost! Are you sure you want to reload document %s?" +msgstr "" + +#: ../../po/../src/file.cpp:266 +#, fuzzy +msgid "Document reverted." +msgstr "Nome Documento:" + +#: ../../po/../src/file.cpp:268 +#, fuzzy +msgid "Document not reverted." +msgstr "Nome Documento:" + +#: ../../po/../src/file.cpp:382 +msgid "Select file to open" +msgstr "Seleccione o ficheiro a abrir" + +#: ../../po/../src/file.cpp:518 +#, c-format +msgid "Removed %i unused definition in <defs>." +msgid_plural "Removed %i unused definitions in <defs>." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/file.cpp:523 +msgid "No unused definitions in <defs>." +msgstr "" + +#: ../../po/../src/file.cpp:548 +#, c-format +msgid "" +"No Inkscape extension found to save document (%s). This may have been " +"caused by an unknown filename extension." +msgstr "" + +#: ../../po/../src/file.cpp:549 ../../po/../src/file.cpp:557 +#, fuzzy +msgid "Document not saved." +msgstr "Nome Documento:" + +#: ../../po/../src/file.cpp:556 +#, c-format +msgid "File %s could not be saved." +msgstr "" + +#: ../../po/../src/file.cpp:566 +#, fuzzy +msgid "Document saved." +msgstr "Nome Documento:" + +#: ../../po/../src/file.cpp:614 +#, fuzzy, c-format +msgid "drawing%s" +msgstr "Desenho" + +#: ../../po/../src/file.cpp:620 +#, fuzzy, c-format +msgid "drawing-%d%s" +msgstr "Desenho" + +#: ../../po/../src/file.cpp:655 +#, fuzzy +msgid "Select file to save to" +msgstr "Seleccione o ficheiro a abrir" + +#: ../../po/../src/file.cpp:739 +msgid "No changes need to be saved." +msgstr "" + +#: ../../po/../src/file.cpp:926 +msgid "Select file to import" +msgstr "Seleccione o ficheiro a importar" + +#: ../../po/../src/gradient-context.cpp:263 +msgid "Ctrl: snap gradient angle" +msgstr "" + +#: ../../po/../src/gradient-context.cpp:264 +msgid "Shift: draw gradient around the starting point" +msgstr "" + +#. We did an undoable action, but sp_document_done will be called by the knot when released +#. status text; we do not track coords because this branch is run once, not all the time +#. during drag +#: ../../po/../src/gradient-context.cpp:462 +#, c-format +msgid "Gradient for %d objects; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/gradient-context.cpp:464 +#, fuzzy +msgid "Select objects on which to create gradient." +msgstr "Cortar os objectos seleccionados para área de transferência" + +#: ../../po/../src/gradient-drag.cpp:65 +#, fuzzy +msgid "Linear gradient start" +msgstr "Gradiente linear" + +#. POINT_LG_P1 +#: ../../po/../src/gradient-drag.cpp:66 +#, fuzzy +msgid "Linear gradient end" +msgstr "Gradiente linear" + +#: ../../po/../src/gradient-drag.cpp:67 +#, fuzzy +msgid "Radial gradient center" +msgstr "Gradiente radial" + +#: ../../po/../src/gradient-drag.cpp:68 ../../po/../src/gradient-drag.cpp:69 +#, fuzzy +msgid "Radial gradient radius" +msgstr "Gradiente radial" + +#: ../../po/../src/gradient-drag.cpp:70 +#, fuzzy +msgid "Radial gradient focus" +msgstr "Gradiente radial" + +#: ../../po/../src/gradient-drag.cpp:659 +#, c-format +msgid "" +"%s for: %s%s; drag with Ctrl to snap angle, with Ctrl+Alt to " +"preserve angle, with Ctrl+Shift to scale around center" +msgstr "" + +#: ../../po/../src/gradient-drag.cpp:662 +#, fuzzy +msgid " (stroke)" +msgstr "Rasurado" + +#: ../../po/../src/gradient-drag.cpp:665 +msgid "" +"Radial gradient center and focus; drag with Shift to " +"separate focus" +msgstr "" + +#: ../../po/../src/gradient-drag.cpp:667 +#, c-format +msgid "" +"Gradient point shared by %d gradients; drag with Shift to " +"separate" +msgstr "" + +#: ../../po/../src/helper/units.cpp:40 +msgid "Unit" +msgstr "Unidade" + +#: ../../po/../src/helper/units.cpp:40 +msgid "Units" +msgstr "Unidades" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Point" +msgstr "Ponto" + +#: ../../po/../src/helper/units.cpp:41 +msgid "pt" +msgstr "pt" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Points" +msgstr "Pontos" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Pt" +msgstr "Pt" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Pixel" +msgstr "Pixel" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Pixels" +msgstr "Pixels" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Px" +msgstr "Px" + +#. You can add new elements from this point forward +#: ../../po/../src/helper/units.cpp:44 ../share/extensions/straightseg.inx.h:2 +msgid "Percent" +msgstr "Percentagem" + +#: ../../po/../src/helper/units.cpp:44 +msgid "Percents" +msgstr "Percentagens" + +#: ../../po/../src/helper/units.cpp:45 +msgid "Millimeter" +msgstr "Milímetro" + +#: ../../po/../src/helper/units.cpp:45 +msgid "mm" +msgstr "mm" + +#: ../../po/../src/helper/units.cpp:45 +msgid "Millimeters" +msgstr "Milímetros" + +#: ../../po/../src/helper/units.cpp:46 +msgid "Centimeter" +msgstr "Centímetro" + +#: ../../po/../src/helper/units.cpp:46 +msgid "cm" +msgstr "cm" + +#: ../../po/../src/helper/units.cpp:46 +msgid "Centimeters" +msgstr "Centímetros" + +#: ../../po/../src/helper/units.cpp:47 +msgid "Meter" +msgstr "Metro" + +#: ../../po/../src/helper/units.cpp:47 +msgid "m" +msgstr "m" + +#: ../../po/../src/helper/units.cpp:47 +#, fuzzy +msgid "Meters" +msgstr "Metro" + +#. no svg_unit +#: ../../po/../src/helper/units.cpp:48 +msgid "Inch" +msgstr "Polegada" + +#: ../../po/../src/helper/units.cpp:48 +msgid "in" +msgstr "polegadas" + +#: ../../po/../src/helper/units.cpp:48 +msgid "Inches" +msgstr "Polegadas" + +#. Volatiles do not have default, so there are none here +#. TRANSLATORS: for info, see http://www.w3.org/TR/REC-CSS2/syndata.html#length-units +#: ../../po/../src/helper/units.cpp:51 +msgid "Em square" +msgstr "Quadrado em" + +#: ../../po/../src/helper/units.cpp:51 +msgid "em" +msgstr "em" + +#: ../../po/../src/helper/units.cpp:51 +msgid "Em squares" +msgstr "Quadrados em" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/REC-CSS2/syndata.html#length-units +#: ../../po/../src/helper/units.cpp:53 +msgid "Ex square" +msgstr "Quadrado ex" + +#: ../../po/../src/helper/units.cpp:53 +msgid "ex" +msgstr "ex" + +#: ../../po/../src/helper/units.cpp:53 +msgid "Ex squares" +msgstr "Quadrados ex" + +#: ../../po/../src/inkscape.cpp:468 +msgid "Untitled document" +msgstr "Documento sem título" + +#. Show nice dialog box +#: ../../po/../src/inkscape.cpp:497 +#, fuzzy +msgid "Inkscape encountered an internal error and will close now.\n" +msgstr "Sodipodi teve um erro interno e irá agora terminar.\n" + +#: ../../po/../src/inkscape.cpp:498 +#, fuzzy +msgid "" +"Automatic backups of unsaved documents were done to the following " +"locations:\n" +msgstr "" +"Cópias de segurança automáticas dos ficheiros por gravar foram feitas para o " +"seguinte local:\n" + +#: ../../po/../src/inkscape.cpp:499 +#, fuzzy +msgid "Automatic backup of the following documents failed:\n" +msgstr "Falhou a cópia de segurança automática dos seguintes documentos:\n" + +#: ../../po/../src/inkscape.cpp:634 +#, c-format +msgid "" +"Cannot create directory %s.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:635 +#, c-format +msgid "" +"%s is not a valid directory.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:636 +#, c-format +msgid "" +"Cannot create file %s.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:637 +#, c-format +msgid "" +"Cannot write file %s.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:638 +msgid "" +"Although Inkscape will run, it will use default settings,\n" +"and any changes made in preferences will not be saved." +msgstr "" + +#: ../../po/../src/inkscape.cpp:708 +#, c-format +msgid "" +"%s is not a regular file.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:709 +#, c-format +msgid "" +"%s not a valid XML file, or\n" +"you don't have read permissions on it.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:711 +#, c-format +msgid "" +"%s is not a valid menus file.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:712 +msgid "" +"Inkscape will run with default menus.\n" +"New menus will not be saved." +msgstr "" + +#. sp_ui_menu_append_check_item_from_verb(m, view, _("_Menu"), _("Show or hide the menu bar"), "menu", +#. checkitem_toggled, checkitem_update, 0); +#: ../../po/../src/interface.cpp:753 +msgid "Commands Bar" +msgstr "" + +#: ../../po/../src/interface.cpp:753 +#, fuzzy +msgid "Show or hide the Commands bar (under the menu)" +msgstr "Mostar guias" + +#: ../../po/../src/interface.cpp:755 +#, fuzzy +msgid "Tool Controls" +msgstr "Opções ferramentas" + +#: ../../po/../src/interface.cpp:755 +#, fuzzy +msgid "Show or hide the Tool Controls panel" +msgstr "Mostar guias" + +#: ../../po/../src/interface.cpp:757 +msgid "_Toolbox" +msgstr "" + +#: ../../po/../src/interface.cpp:757 +msgid "Show or hide the main toolbox (on the left)" +msgstr "" + +#: ../../po/../src/interface.cpp:763 +msgid "_Statusbar" +msgstr "" + +#: ../../po/../src/interface.cpp:763 +msgid "Show or hide the statusbar (at the bottom of the window)" +msgstr "" + +#: ../../po/../src/interface.cpp:820 +#, c-format +msgid "Verb \"%s\" Unknown" +msgstr "" + +#. TRANSLATORS: #%s is the id of the group e.g. , not a number. +#: ../../po/../src/interface.cpp:930 +#, fuzzy, c-format +msgid "Enter group #%s" +msgstr "Editar nós" + +#: ../../po/../src/interface.cpp:941 +#, fuzzy +msgid "Go to parent" +msgstr "Zoom ao tamanho da página" + +#: ../../po/../src/interface.cpp:972 +msgid "Could not parse SVG data" +msgstr "" + +#: ../../po/../src/interface.cpp:1135 +#, c-format +msgid "Overwrite %s" +msgstr "" + +#: ../../po/../src/interface.cpp:1153 +#, c-format +msgid "" +"The file %s already exists. Do you want to overwrite that file with the " +"current document?" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:59 +msgid "Jabber connection lost." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:72 +#, c-format +msgid "Sending message; %u message remaining in send queue." +msgid_plural "Sending message; %u messages remaining in send queue." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:78 +msgid "Receive queue empty." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:154 +#, c-format +msgid "Receiving change; %u change left to process." +msgid_plural "Receiving change; %u changes left to process." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:157 +#, c-format +msgid "%s has left the chatroom." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:221 +msgid "Nickname %1 is already in use. Please choose a different nickname." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:225 +msgid "An error was encountered while attempting to connect to the server." +msgstr "" + +#. Check to see if the user made any modifications to this document. If so, +#. we want to give them the option of (1) letting us clear their document or (2) +#. opening a new, blank document for the whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:131 +msgid "%1 has invited you to a whiteboard session." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:132 +msgid "Incoming whiteboard invitation from %1" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:135 +msgid "Do you wish to accept %1's whiteboard session invitation?" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:137 +msgid "" +"Would you like to accept %1's invitation in a new document window?\n" +"Accepting the invitation in your current window will discard unsaved changes." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:143 +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:198 +#, fuzzy +msgid "Accept invitation" +msgstr "Selecção" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:144 +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:199 +msgid "Decline invitation" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:145 +#, fuzzy +msgid "Accept invitation in new document window" +msgstr "Criar um novo documento SVG" + +#. We could not create a new desktop; ask the user if she or he wants to +#. replace the current document and accept the invitation, or reject the invitation. +#. TRANSLATORS: %1 is a userid here +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:196 +msgid "" +"A new document window could not be opened for a whiteboard session with %" +"1" +msgstr "" + +#. TRANSLATORS: %1 is the peer whom refused our invitation. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:238 +msgid "" +"The user %1 has refused your " +"whiteboard invitation.\n" +"\n" +msgstr "" + +#. TRANSLATORS: %1 is the peer whom refused our invitation, %2 is our Jabber identity. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:241 +msgid "" +"You are still connected to a Jabber server as %2, and may send an " +"invitation to %1 again, or you may send an invitation to a different " +"user." +msgstr "" + +#. TRANSLATORS: %1 is the peer whom we tried to contact, but is already in a whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:252 +msgid "" +"The user %1 is already in a " +"whiteboard session.\n" +"\n" +msgstr "" + +#. TRANSLATORS: %1 is the peer whom we tried to contact, but is already in a whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:255 +msgid "" +"You are still connected to a Jabber server as %1, and may send an " +"invitation to a different user." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/invitation-confirm-dialog.cpp:26 +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:24 +msgid "_Write session file:" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/message-processors.cpp:145 +#, c-format +msgid "%s has joined the chatroom." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/message-queue.cpp:87 +#, c-format +msgid "%u change in receive queue." +msgid_plural "%u changes in receive queue." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/jabber_whiteboard/message-queue.cpp:117 +#, c-format +msgid "%u change in send queue." +msgid_plural "%u changes in send queue." +msgstr[0] "" +msgstr[1] "" + +#. if ID is NULL, then we have a real problem -- we were not able to find a key +#. nor generate one. The only thing we can really do here is abort, since we have +#. no way to let the other client(s) uniquely identify this object. +#. FIXME: If this indicates a programming bug, then don't request translation with +#. * _(...): it is most useful in untranslated form so that developers may search for +#. * it when someone reports it in a bug report (as we want users to do for all bugs, +#. * as indicated by it being a g_warning string). +#. * +#. * Otherwise, if it is not a programming bug but a network error or a bug in the +#. * remote peer (perhaps running different software) or whatever, then present it in +#. * an alert box, and avoid use of technical jargon `NULL'. +#. +#: ../../po/../src/jabber_whiteboard/message-utilities.cpp:171 +msgid "" +"ID for new object is NULL even after generation and lookup attempts: the new " +"object will NOT be sent, nor will any of its child objects!" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:60 +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:995 +msgid "Select a location and filename" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:62 +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:997 +#, fuzzy +msgid "Set filename" +msgstr "Nome do ficheiro png" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:301 +msgid "No SSL certificate was found." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:304 +msgid "The SSL certificate provided by the Jabber server is untrusted." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:307 +msgid "The SSL certificate provided by the Jabber server is expired." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:310 +msgid "" +"The SSL certificate provided by the Jabber server has not been activated." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:313 +msgid "" +"The SSL certificate provided by the Jabber server contains a hostname that " +"does not match the Jabber server's hostname." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:316 +msgid "" +"The SSL certificate provided by the Jabber server contains an invalid " +"fingerprint." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:319 +msgid "An unknown error occurred while setting up the SSL connection." +msgstr "" + +#. TRANSLATORS: %1 is the message that describes the specific error that occurred when +#. establishing the SSL connection. +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:325 +msgid "" +"%1\n" +"\n" +"Do you wish to continue connecting to the Jabber server?" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:328 +msgid "Continue connecting and ignore further errors" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:329 +msgid "Continue connecting, but warn me of further errors" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:330 +#, fuzzy +msgid "Cancel connection" +msgstr "Selecção" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:777 +#, c-format +msgid "Established whiteboard session with %s." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:785 +#, c-format +msgid "%s has left the whiteboard session." +msgstr "" + +#. Inform the user +#. TRANSLATORS: %1 is the name of the user that disconnected, %2 is the name of the user whom the disconnected user disconnected from. +#. This message is not used in a chatroom context. +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:790 +msgid "" +"The user %1 has left the " +"whiteboard session.\n" +"\n" +msgstr "" + +#. TRANSLATORS: %1 and %2 are userids +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:792 +msgid "" +"You are still connected to a Jabber server as %2, and may establish a " +"new session to %1 or a different user." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:988 +msgid "" +"Could not open file %1 for session recording.\n" +"The error encountered was: %2.\n" +"\n" +"You may select a different location to record the session, or you may opt to " +"not record this session." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:990 +msgid "Choose a different location" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:991 +msgid "Skip session recording" +msgstr "" + +#: ../../po/../src/knot.cpp:673 +msgid "Node or handle drag canceled." +msgstr "" + +#: ../../po/../src/libnrtype/FontFactory.cpp:358 +msgid "Ignoring font without family that will crash Pango" +msgstr "" + +#: ../../po/../src/main.cpp:395 +msgid "Print the Inkscape version number" +msgstr "" + +#: ../../po/../src/main.cpp:400 +msgid "Do not use X server (only process files from console)" +msgstr "Não utilizar servidor X (apenas processar ficheiros da consola)" + +#: ../../po/../src/main.cpp:405 +#, fuzzy +msgid "Try to use X server (even if $DISPLAY is not set)" +msgstr "Tentar utilizar servidor X mesmo se $DISPLAY não estiver definido)" + +#: ../../po/../src/main.cpp:410 +msgid "Open specified document(s) (option string may be excluded)" +msgstr "" +"Abrir documento(s) especificados(s) (a opção do nome pode ser excluida)" + +#: ../../po/../src/main.cpp:411 ../../po/../src/main.cpp:416 +#: ../../po/../src/main.cpp:421 ../../po/../src/main.cpp:483 +#: ../../po/../src/main.cpp:488 ../../po/../src/main.cpp:493 +msgid "FILENAME" +msgstr "FICHEIRO" + +#: ../../po/../src/main.cpp:415 +msgid "Print document(s) to specified output file (use '| program' for pipe)" +msgstr "" +"Imprimir documento(s) para o ficheiro de saida especificado (utilize '| " +"aplicação' para pipe)" + +#: ../../po/../src/main.cpp:420 +#, fuzzy +msgid "Export document to a PNG file" +msgstr "Exportar documento para ficheiro png" + +#: ../../po/../src/main.cpp:425 +#, fuzzy +msgid "The resolution used for exporting SVG into bitmap (default 90)" +msgstr "A resolução utilizada para converter SVG em bitmap (por omissão 72.0)" + +#: ../../po/../src/main.cpp:426 +msgid "DPI" +msgstr "DPI" + +#: ../../po/../src/main.cpp:430 +#, fuzzy +msgid "" +"Exported area in SVG user units (default is the canvas; 0,0 is lower-left " +"corner)" +msgstr "" +"Área exportada em milímetros (por omissão o documento completo, 0,0 é o " +"canto inferior esquerdo)" + +#: ../../po/../src/main.cpp:431 +msgid "x0:y0:x1:y1" +msgstr "x0:y0:x1:y1" + +#: ../../po/../src/main.cpp:435 +msgid "Exported area is the entire drawing (not canvas)" +msgstr "" + +#: ../../po/../src/main.cpp:440 +msgid "" +"Snap the bitmap export area outwards to the nearest integer values (in SVG " +"user units)" +msgstr "" + +#: ../../po/../src/main.cpp:445 +#, fuzzy +msgid "The width of exported bitmap in pixels (overrides export-dpi)" +msgstr "A largura do bitmap gerado em pixels (sobrepõe dpi)" + +#: ../../po/../src/main.cpp:446 +msgid "WIDTH" +msgstr "LARGURA" + +#: ../../po/../src/main.cpp:450 +#, fuzzy +msgid "The height of exported bitmap in pixels (overrides export-dpi)" +msgstr "A altura do bitmap gerado em pixels (sobrepõe dpi)" + +#: ../../po/../src/main.cpp:451 +msgid "HEIGHT" +msgstr "ALTURA" + +#: ../../po/../src/main.cpp:455 +#, fuzzy +msgid "The ID of the object to export (overrides export-area)" +msgstr "A largura do bitmap gerado em pixels (sobrepõe dpi)" + +#: ../../po/../src/main.cpp:456 ../../po/../src/main.cpp:532 +#, fuzzy +msgid "ID" +msgstr "Identificação:" + +#. TRANSLATORS: this means: "Only export the object whose id is given in --export-id". +#. See "man inkscape" for details. +#: ../../po/../src/main.cpp:462 +msgid "" +"Export just the object with export-id, hide all others (only with export-id)" +msgstr "" + +#: ../../po/../src/main.cpp:467 +msgid "Use stored filename and DPI hints when exporting (only with export-id)" +msgstr "" + +#: ../../po/../src/main.cpp:472 +#, fuzzy +msgid "Background color of exported bitmap (any SVG-supported color string)" +msgstr "" +"Cor de fundo do bitmap exportado (qualquer expressão de cor suportada por " +"SVG)" + +#: ../../po/../src/main.cpp:473 +msgid "COLOR" +msgstr "COR" + +#: ../../po/../src/main.cpp:477 +#, fuzzy +msgid "Background opacity of exported bitmap (either 0.0 to 1.0, or 1 to 255)" +msgstr "" +"Cor de fundo do bitmap exportado (qualquer expressão de cor suportada por " +"SVG)" + +#: ../../po/../src/main.cpp:478 +msgid "VALUE" +msgstr "" + +#: ../../po/../src/main.cpp:482 +#, fuzzy +msgid "Export document to plain SVG file (no sodipodi or inkscape namespaces)" +msgstr "" +"Exportar documento para ficheiro SVG simples (sem namespace \"xmlns:sodipodi" +"\")" + +#: ../../po/../src/main.cpp:487 +#, fuzzy +msgid "Export document to a PS file" +msgstr "Exportar documento para ficheiro png" + +#: ../../po/../src/main.cpp:492 +#, fuzzy +msgid "Export document to an EPS file" +msgstr "Exportar documento para ficheiro png" + +#: ../../po/../src/main.cpp:497 +#, fuzzy +msgid "Convert text object to paths on export (EPS)" +msgstr "Converter objecto seleccionado em caminho" + +#: ../../po/../src/main.cpp:502 +msgid "Export files with the bounding box set to the page size (EPS)" +msgstr "" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:508 +msgid "" +"Query the X coordinate of the drawing or, if specified, of the object with --" +"query-id" +msgstr "" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:514 +msgid "" +"Query the Y coordinate of the drawing or, if specified, of the object with --" +"query-id" +msgstr "" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:520 +msgid "" +"Query the width of the drawing or, if specified, of the object with --query-" +"id" +msgstr "" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:526 +msgid "" +"Query the height of the drawing or, if specified, of the object with --query-" +"id" +msgstr "" + +#: ../../po/../src/main.cpp:531 +#, fuzzy +msgid "The ID of the object whose dimensions are queried" +msgstr "A largura do bitmap gerado em pixels (sobrepõe dpi)" + +#. TRANSLATORS: this option makes Inkscape print the name (path) of the extension directory +#: ../../po/../src/main.cpp:537 +msgid "Print out the extension directory and exit" +msgstr "" + +#: ../../po/../src/main.cpp:542 +msgid "Show given files one-by-one, switch to next on any key/mouse event" +msgstr "" +"Mostar os ficheiros especificados um a um, passando ao seguinte com qualquer " +"evento do teclado ou rato" + +#: ../../po/../src/main.cpp:547 +msgid "Use the new Gtkmm GUI interface" +msgstr "" + +#: ../../po/../src/main.cpp:552 +msgid "Remove unused definitions from the defs section(s) of the document" +msgstr "" + +#: ../../po/../src/main.cpp:741 +msgid "" +"[OPTIONS...] [FILE...]\n" +"\n" +"Available options:" +msgstr "" + +#: ../../po/../src/menus-skeleton.h:17 +msgid "_New" +msgstr "_Novo" + +#: ../../po/../src/menus-skeleton.h:22 +#, fuzzy +msgid "Open _Recent" +msgstr "Abrir" + +#: ../../po/../src/menus-skeleton.h:53 +#, fuzzy +msgid "_Edit" +msgstr "Editar" + +#: ../../po/../src/menus-skeleton.h:84 +#, fuzzy +msgid "_View" +msgstr "Vista" + +#: ../../po/../src/menus-skeleton.h:85 +#, fuzzy +msgid "_Zoom" +msgstr "Zoom" + +#: ../../po/../src/menus-skeleton.h:102 +#, fuzzy +msgid "Show/Hide" +msgstr "Mostar guias" + +#: ../../po/../src/menus-skeleton.h:107 +#, fuzzy +msgid "_Display mode" +msgstr "Ecrã" + +#: ../../po/../src/menus-skeleton.h:126 +#, fuzzy +msgid "_Layer" +msgstr "Baixar" + +#: ../../po/../src/menus-skeleton.h:143 +#, fuzzy +msgid "_Object" +msgstr "Objecto" + +#: ../../po/../src/menus-skeleton.h:165 +#, fuzzy +msgid "_Path" +msgstr "Colar" + +#: ../../po/../src/menus-skeleton.h:188 +#, fuzzy +msgid "_Text" +msgstr "Texto" + +#: ../../po/../src/menus-skeleton.h:200 +#, fuzzy +msgid "Effects" +msgstr "Objecto" + +#: ../../po/../src/menus-skeleton.h:207 +msgid "Whiteboa_rd" +msgstr "" + +#: ../../po/../src/menus-skeleton.h:220 +#, fuzzy +msgid "_Help" +msgstr "_Ajuda" + +#: ../../po/../src/menus-skeleton.h:222 +msgid "Tutorials" +msgstr "" + +#: ../../po/../src/node-context.cpp:382 +msgid "" +"Ctrl: toggle node type, snap handle angle, move hor/vert; Ctrl" +"+Alt: move along handles" +msgstr "" + +#: ../../po/../src/node-context.cpp:383 +msgid "" +"Shift: toggle node selection, disable snapping, rotate both handles" +msgstr "" + +#: ../../po/../src/node-context.cpp:384 +msgid "Alt: lock handle length; Ctrl+Alt: move along handles" +msgstr "" + +#: ../../po/../src/nodepath.cpp:1399 ../../po/../src/nodepath.cpp:1411 +#: ../../po/../src/nodepath.cpp:1492 ../../po/../src/nodepath.cpp:1504 +msgid "To join, you must have two endnodes selected." +msgstr "" + +#: ../../po/../src/nodepath.cpp:1633 ../../po/../src/nodepath.cpp:1647 +msgid "" +"Select two non-endpoint nodes on a path between which to delete " +"segments." +msgstr "" + +#: ../../po/../src/nodepath.cpp:1743 +#, fuzzy +msgid "Cannot find path between nodes." +msgstr "Juntar linhas nos nós seleccionados" + +#: ../../po/../src/nodepath.cpp:2822 +#, c-format +msgid "" +"Node handle: angle %0.2f°, length %s; with Ctrl to snap " +"angle; with Alt to lock length; with Shift to rotate both " +"handles" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3351 +msgid "" +"Node: drag to edit the path; with Ctrl to snap to horizontal/" +"vertical; with Ctrl+Alt to snap to handles' directions" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3375 +msgid "" +"Node handle: drag to shape the curve; with Ctrl to snap angle; " +"with Alt to lock length; with Shift to rotate both handles" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3399 +msgid "" +"Node handle: drag to shape the curve; with Ctrl to snap angle; " +"with Alt to lock length; with Shift to rotate the opposite " +"handle in sync" +msgstr "" + +#. TRANSLATORS: "end" is an adjective here (NOT a verb) +#: ../../po/../src/nodepath.cpp:3591 +#, fuzzy +msgid "end node" +msgstr "Indentar nó" + +#. TRANSLATORS: "cusp" means "sharp" (cusp node); see also the Advanced Tutorial +#: ../../po/../src/nodepath.cpp:3596 +#, fuzzy +msgid "cusp" +msgstr "us" + +#. TRANSLATORS: "smooth" is an adjective here +#: ../../po/../src/nodepath.cpp:3599 +msgid "smooth" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3601 +#, fuzzy +msgid "symmetric" +msgstr "Não Simétrico" + +#. TRANSLATORS: "end" is an adjective here (NOT a verb) +#: ../../po/../src/nodepath.cpp:3607 +msgid "end node, handle retracted (drag with Shift to extend)" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3609 +msgid "one handle retracted (drag with Shift to extend)" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3612 +msgid "both handles retracted (drag with Shift to extend)" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3624 +#, fuzzy +msgid "Drag nodes or node handles; arrow keys to move nodes" +msgstr "A criar nova curva. Prima 'a' para alternar Anexar/Novo." + +#: ../../po/../src/nodepath.cpp:3625 +#, fuzzy +msgid "Drag the node or its handles; arrow keys to move the node" +msgstr "A criar nova curva. Prima 'a' para alternar Anexar/Novo." + +#: ../../po/../src/nodepath.cpp:3651 ../../po/../src/nodepath.cpp:3663 +#, fuzzy +msgid "Select a single object to edit its nodes or handles." +msgstr "Seleccionar todos os objectos no documento" + +#: ../../po/../src/nodepath.cpp:3655 +#, c-format +msgid "" +"0 out of %i node selected. Click, Shift+click, " +"or drag around nodes to select." +msgid_plural "" +"0 out of %i nodes selected. Click, Shift+click, " +"or drag around nodes to select." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/nodepath.cpp:3661 +msgid "Drag the handles of the object to modify it." +msgstr "" + +#: ../../po/../src/nodepath.cpp:3669 +#, fuzzy, c-format +msgid "%i of %i node selected; %s. %s." +msgid_plural "%i of %i nodes selected; %s. %s." +msgstr[0] "Juntar linhas nos nós seleccionados" +msgstr[1] "Juntar linhas nos nós seleccionados" + +#: ../../po/../src/nodepath.cpp:3675 +#, fuzzy, c-format +msgid "%i of %i node selected. %s." +msgid_plural "%i of %i nodes selected. %s." +msgstr[0] "Juntar linhas nos nós seleccionados" +msgstr[1] "Juntar linhas nos nós seleccionados" + +#: ../../po/../src/object-edit.cpp:493 +msgid "" +"Adjust the horizontal rounding radius; with Ctrl to make the " +"vertical radius the same" +msgstr "" + +#: ../../po/../src/object-edit.cpp:499 +msgid "" +"Adjust the vertical rounding radius; with Ctrl to make the " +"horizontal radius the same" +msgstr "" + +#: ../../po/../src/object-edit.cpp:506 ../../po/../src/object-edit.cpp:513 +msgid "" +"Adjust the width and height of the rectangle; with Ctrl to " +"lock ratio or stretch in one dimension only" +msgstr "" + +#: ../../po/../src/object-edit.cpp:686 +msgid "Adjust ellipse width, with Ctrl to make circle" +msgstr "" + +#: ../../po/../src/object-edit.cpp:689 +msgid "Adjust ellipse height, with Ctrl to make circle" +msgstr "" + +#: ../../po/../src/object-edit.cpp:692 +msgid "" +"Position the start point of the arc or segment; with Ctrl to " +"snap angle; drag inside the ellipse for arc, outside for " +"segment" +msgstr "" + +#: ../../po/../src/object-edit.cpp:695 +msgid "" +"Position the end point of the arc or segment; with Ctrl to " +"snap angle; drag inside the ellipse for arc, outside for " +"segment" +msgstr "" + +#: ../../po/../src/object-edit.cpp:800 +msgid "" +"Adjust the tip radius of the star or polygon; with Shift to " +"round; with Alt to randomize" +msgstr "" + +#: ../../po/../src/object-edit.cpp:803 +msgid "" +"Adjust the base radius of the star; with Ctrl to keep star " +"rays radial (no skew); with Shift to round; with Alt to " +"randomize" +msgstr "" + +#: ../../po/../src/object-edit.cpp:967 +msgid "" +"Roll/unroll the spiral from inside; with Ctrl to snap angle; " +"with Alt to converge/diverge" +msgstr "" + +#: ../../po/../src/object-edit.cpp:969 +msgid "" +"Roll/unroll the spiral from outside; with Ctrl to snap angle; " +"with Shift to scale/rotate" +msgstr "" + +#: ../../po/../src/object-edit.cpp:1006 +msgid "Adjust the offset distance" +msgstr "" + +#. TRANSLATORS: This refers to the pattern that's inside the object +#: ../../po/../src/object-edit.cpp:1036 +msgid "Move the pattern fill inside the object" +msgstr "" + +#: ../../po/../src/object-edit.cpp:1038 +#, fuzzy +msgid "Scale the pattern fill uniformly" +msgstr "Cortar os objectos seleccionados para área de transferência" + +#: ../../po/../src/object-edit.cpp:1040 +msgid "Rotate the pattern fill; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/object-edit.cpp:1065 +msgid "Drag to resize the flowed text frame" +msgstr "" + +#. Item dialog +#: ../../po/../src/object-ui.cpp:106 +#, fuzzy +msgid "Object _Properties" +msgstr "propriedades do objecto" + +#. Select item +#: ../../po/../src/object-ui.cpp:116 +#, fuzzy +msgid "_Select This" +msgstr "Seleccionar este" + +#. Create link +#: ../../po/../src/object-ui.cpp:126 +#, fuzzy +msgid "_Create Link" +msgstr "Criar ligação" + +#. "Ungroup" +#: ../../po/../src/object-ui.cpp:199 ../../po/../src/verbs.cpp:1931 +msgid "_Ungroup" +msgstr "_Desagrupar" + +#. Link dialog +#: ../../po/../src/object-ui.cpp:239 +#, fuzzy +msgid "Link _Properties" +msgstr "Propriedades da Ligação" + +#. Select item +#: ../../po/../src/object-ui.cpp:249 +#, fuzzy +msgid "_Follow Link" +msgstr "Seguir ligação" + +#. Reset transformations +#: ../../po/../src/object-ui.cpp:254 +#, fuzzy +msgid "_Remove Link" +msgstr "Remover ligação" + +#. Link dialog +#: ../../po/../src/object-ui.cpp:303 +#, fuzzy +msgid "Image _Properties" +msgstr "Propriedades da Imagem" + +#. Item dialog +#: ../../po/../src/object-ui.cpp:344 +#, fuzzy +msgid "_Fill and Stroke" +msgstr "Enchimento e Pincel" + +#: ../../po/../src/path-chemistry.cpp:58 +#, fuzzy +msgid "Select at least two objects to combine." +msgstr "Seleccionar todos os objectos no documento" + +#: ../../po/../src/path-chemistry.cpp:65 +#, fuzzy +msgid "At least one of the objects is not a path, cannot combine." +msgstr "Converter objecto seleccionado em caminho" + +#: ../../po/../src/path-chemistry.cpp:73 +msgid "" +"You cannot combine objects from different groups or layers." +msgstr "" + +#: ../../po/../src/path-chemistry.cpp:155 +#, fuzzy +msgid "Select path(s) to break apart." +msgstr "Cortar os objectos seleccionados para área de transferência" + +#: ../../po/../src/path-chemistry.cpp:231 +msgid "No path(s) to break apart in the selection." +msgstr "" + +#: ../../po/../src/path-chemistry.cpp:252 +#, fuzzy +msgid "Select object(s) to convert to path." +msgstr "Cortar os objectos seleccionados para área de transferência" + +#: ../../po/../src/path-chemistry.cpp:297 +#, fuzzy +msgid "No objects to convert to path in the selection." +msgstr "Cortar os objectos seleccionados para área de transferência" + +#: ../../po/../src/path-chemistry.cpp:345 +#, fuzzy +msgid "Select path(s) to reverse." +msgstr "Elevar objectos seleccionados para o topo" + +#: ../../po/../src/path-chemistry.cpp:370 +msgid "No paths to reverse in the selection." +msgstr "" + +#: ../../po/../src/pen-context.cpp:379 ../../po/../src/pencil-context.cpp:233 +#, fuzzy +msgid "Continuing selected path" +msgstr "Combinar os caminhos seleccionados" + +#: ../../po/../src/pen-context.cpp:390 ../../po/../src/pencil-context.cpp:242 +#, fuzzy +msgid "Creating new path" +msgstr "Criar um novo documento SVG" + +#: ../../po/../src/pen-context.cpp:394 ../../po/../src/pencil-context.cpp:246 +#, fuzzy +msgid "Appending to selected path" +msgstr "Zoom à selecção" + +#: ../../po/../src/pen-context.cpp:538 +msgid "Click or click and drag to close and finish the path." +msgstr "" + +#: ../../po/../src/pen-context.cpp:548 +msgid "" +"Click or click and drag to continue the path from this point." +msgstr "" + +#: ../../po/../src/pen-context.cpp:857 +#, c-format +msgid "" +"%s: angle %3.2f°, distance %s; with Ctrl to snap angle, " +"Enter to finish the path" +msgstr "" + +#: ../../po/../src/pen-context.cpp:882 +#, c-format +msgid "" +"Curve handle: angle %3.2f°, length %s; with Ctrl to snap " +"angle" +msgstr "" + +#: ../../po/../src/pen-context.cpp:912 +#, c-format +msgid "" +"%s: angle %3.2f°, length %s; with Ctrl to snap angle, " +"with Shift to move this handle only" +msgstr "" + +#: ../../po/../src/pen-context.cpp:946 +#, fuzzy +msgid "Finishing pen" +msgstr "Mão livre" + +#: ../../po/../src/pencil-context.cpp:320 +msgid "Release here to close and finish the path." +msgstr "" + +#: ../../po/../src/pencil-context.cpp:326 +#, fuzzy +msgid "Drawing a freehand path" +msgstr "Desenhar linha em modo dinâmico" + +#: ../../po/../src/pencil-context.cpp:331 +msgid "Drag to continue the path from this point." +msgstr "" + +#. Write curves to object +#: ../../po/../src/pencil-context.cpp:390 +#, fuzzy +msgid "Finishing freehand" +msgstr "Mão livre" + +#: ../../po/../src/rect-context.cpp:387 +msgid "" +"Ctrl: make square or integer-ratio rect, lock a rounded corner " +"circular" +msgstr "" + +#: ../../po/../src/rect-context.cpp:549 +#, c-format +msgid "" +"Rectangle: %s × %s; with Ctrl to make square or integer-" +"ratio rectangle; with Shift to draw around the starting point" +msgstr "" + +#: ../../po/../src/select-context.cpp:243 +#, fuzzy +msgid "Move canceled." +msgstr "Selecção" + +#: ../../po/../src/select-context.cpp:252 +#, fuzzy +msgid "Selection canceled." +msgstr "Selecção" + +#: ../../po/../src/select-context.cpp:642 +msgid "Ctrl: select in groups, move hor/vert" +msgstr "" + +#: ../../po/../src/select-context.cpp:643 +msgid "Shift: toggle select, force rubberband, disable snapping" +msgstr "" + +#: ../../po/../src/select-context.cpp:644 +msgid "Alt: select under, move selected" +msgstr "" + +#: ../../po/../src/select-context.cpp:798 +#, fuzzy +msgid "Selected object is not a group. Cannot enter." +msgstr "Converter objecto seleccionado em caminho" + +#: ../../po/../src/select-context.cpp:876 +#, c-format +msgid "" +"Move by %s, %s; with Ctrl to restrict to horizontal/vertical; " +"with Shift to disable snapping" +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:228 +msgid "Nothing was deleted." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:259 +#, fuzzy +msgid "Select object(s) to duplicate." +msgstr "Cortar os objectos seleccionados para área de transferência" + +#: ../../po/../src/selection-chemistry.cpp:420 +#, fuzzy +msgid "Select two or more objects to group." +msgstr "Elevar objectos seleccionados para o topo" + +#: ../../po/../src/selection-chemistry.cpp:428 +#, fuzzy +msgid "Select at least two objects to group." +msgstr "Seleccionar todos os objectos no documento" + +#: ../../po/../src/selection-chemistry.cpp:513 +#, fuzzy +msgid "Select a group to ungroup." +msgstr "Elevar objectos seleccionados para o topo" + +#: ../../po/../src/selection-chemistry.cpp:554 +msgid "No groups to ungroup in the selection." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:623 +#, fuzzy +msgid "Select objects to raise." +msgstr "Cortar os objectos seleccionados para área de transferência" + +#: ../../po/../src/selection-chemistry.cpp:629 +#: ../../po/../src/selection-chemistry.cpp:681 +#: ../../po/../src/selection-chemistry.cpp:715 +#: ../../po/../src/selection-chemistry.cpp:773 +msgid "" +"You cannot raise/lower objects from different groups or layers." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:673 +#, fuzzy +msgid "Select object(s) to raise to top." +msgstr "Converter objecto seleccionado em caminho" + +#: ../../po/../src/selection-chemistry.cpp:709 +#, fuzzy +msgid "Select object(s) to lower." +msgstr "Cortar os objectos seleccionados para área de transferência" + +#: ../../po/../src/selection-chemistry.cpp:765 +#, fuzzy +msgid "Select object(s) to lower to bottom." +msgstr "Cortar os objectos seleccionados para área de transferência" + +#: ../../po/../src/selection-chemistry.cpp:806 +msgid "Nothing to undo." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:813 +msgid "Nothing to redo." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:969 +msgid "Nothing was copied." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1051 +msgid "Current layer is hidden. Unhide it to be able to paste to it." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1055 +msgid "Current layer is locked. Unlock it to be able to paste to it." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1068 +#: ../../po/../src/selection-chemistry.cpp:1103 +#, fuzzy +msgid "Nothing on the clipboard." +msgstr "Copiar selecção para o clipboard" + +#: ../../po/../src/selection-chemistry.cpp:1109 +#, fuzzy +msgid "Select object(s) to paste style to." +msgstr "Converter objecto seleccionado em caminho" + +#: ../../po/../src/selection-chemistry.cpp:1128 +#, fuzzy +msgid "Select object(s) to move to the layer above." +msgstr "Cortar os objectos seleccionados para área de transferência" + +#: ../../po/../src/selection-chemistry.cpp:1146 +#, fuzzy +msgid "No more layers above." +msgstr "Nome Documento:" + +#: ../../po/../src/selection-chemistry.cpp:1160 +#, fuzzy +msgid "Select object(s) to move to the layer below." +msgstr "Cortar os objectos seleccionados para área de transferência" + +#: ../../po/../src/selection-chemistry.cpp:1178 +#, fuzzy +msgid "No more layers below." +msgstr "Nome Documento:" + +#: ../../po/../src/selection-chemistry.cpp:1811 +#, fuzzy +msgid "Select a clone to unlink." +msgstr "Seleccione o ficheiro a abrir" + +#: ../../po/../src/selection-chemistry.cpp:1842 +msgid "No clones to unlink in the selection." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1859 +msgid "" +"Select a clone to go to its original. Select a linked offset " +"to go to its source. Select a text on path to go to the path. Select " +"a flowed text to go to its frame." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1882 +msgid "" +"Cannot find the object to select (orphaned clone, offset, textpath, " +"flowed text?)" +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1888 +msgid "" +"The object you're trying to select is not visible (it is in <" +"defs>)" +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1915 +#, fuzzy +msgid "Select object(s) to convert to pattern." +msgstr "Cortar os objectos seleccionados para área de transferência" + +#: ../../po/../src/selection-chemistry.cpp:2006 +#, fuzzy +msgid "Select an object with pattern fill to extract objects from." +msgstr "Cortar os objectos seleccionados para área de transferência" + +#: ../../po/../src/selection-chemistry.cpp:2059 +#, fuzzy +msgid "No pattern fills in the selection." +msgstr "Cortar os objectos seleccionados para área de transferência" + +#: ../../po/../src/selection-chemistry.cpp:2079 +#, fuzzy +msgid "Select object(s) to make a bitmap copy." +msgstr "Converter objecto seleccionado em caminho" + +#: ../../po/../src/selection-describer.cpp:37 +msgid "Click selection to toggle scale/rotation handles" +msgstr "" + +#. no items +#: ../../po/../src/selection-describer.cpp:39 +msgid "" +"No objects selected. Click, Shift+click, or drag around objects to select." +msgstr "" + +#: ../../po/../src/selection-describer.cpp:51 +#, fuzzy, c-format +msgid " in layer %s" +msgstr "Elevar nó" + +#: ../../po/../src/selection-describer.cpp:54 +#, fuzzy, c-format +msgid " in layer %s" +msgstr "Elevar nó" + +#: ../../po/../src/selection-describer.cpp:66 +msgid "Use Shift+D to look up original" +msgstr "" + +#: ../../po/../src/selection-describer.cpp:70 +msgid "Use Shift+D to look up path" +msgstr "" + +#: ../../po/../src/selection-describer.cpp:74 +msgid "Use Shift+D to look up frame" +msgstr "" + +#: ../../po/../src/selection-describer.cpp:84 +#, fuzzy, c-format +msgid "%i object selected" +msgid_plural "%i objects selected" +msgstr[0] "Juntar linhas nos nós seleccionados" +msgstr[1] "Juntar linhas nos nós seleccionados" + +#: ../../po/../src/selection-describer.cpp:90 +#, c-format +msgid "%s%s. %s." +msgstr "" + +#: ../../po/../src/selection-describer.cpp:94 +#, fuzzy, c-format +msgid "%s in %i layer. %s." +msgid_plural "%s in %i layers. %s." +msgstr[0] "Juntar linhas nos nós seleccionados" +msgstr[1] "Juntar linhas nos nós seleccionados" + +#: ../../po/../src/seltrans.cpp:498 +msgid "" +"Center of rotation and skewing: drag to reposition; scaling with " +"Shift also uses this center" +msgstr "" + +#: ../../po/../src/seltrans.cpp:514 +msgid "" +"Squeeze or stretch selection; with Ctrl to scale uniformly; " +"with Shift to scale around rotation center" +msgstr "" + +#: ../../po/../src/seltrans.cpp:515 +msgid "" +"Scale selection; with Ctrl to scale uniformly; with Shift to scale around rotation center" +msgstr "" + +#: ../../po/../src/seltrans.cpp:519 +msgid "" +"Skew selection; with Ctrl to snap angle; with Shift to " +"skew around the opposite side" +msgstr "" + +#: ../../po/../src/seltrans.cpp:520 +msgid "" +"Rotate selection; with Ctrl to snap angle; with Shift " +"to rotate around the opposite corner" +msgstr "" + +#: ../../po/../src/seltrans.cpp:829 ../../po/../src/seltrans.cpp:909 +#, c-format +msgid "Scale: %0.2f%% x %0.2f%%; with Ctrl to lock ratio" +msgstr "" + +#. TRANSLATORS: don't modify the first ";" (it will NOT be displayed as ";" - only the second one will be) +#: ../../po/../src/seltrans.cpp:984 +#, c-format +msgid "Skew: %0.2f°; with Ctrl to snap angle" +msgstr "" + +#. TRANSLATORS: don't modify the first ";" (it will NOT be displayed as ";" - only the second one will be) +#: ../../po/../src/seltrans.cpp:1035 +#, c-format +msgid "Rotate: %0.2f°; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/seltrans.cpp:1090 +#, fuzzy, c-format +msgid "Move center to %s, %s" +msgstr "Ligação a %s" + +#: ../../po/../src/slideshow.cpp:90 +#, fuzzy +msgid "Inkscape slideshow" +msgstr "Apresentação Sodipodi" + +#: ../../po/../src/sp-anchor.cpp:181 +#, fuzzy, c-format +msgid "Link to %s" +msgstr "Ligação a %s" + +#: ../../po/../src/sp-anchor.cpp:185 +#, fuzzy +msgid "Link without URI" +msgstr "Ligação a %s" + +#: ../../po/../src/sp-ellipse.cpp:438 ../../po/../src/sp-ellipse.cpp:870 +#, fuzzy +msgid "Ellipse" +msgstr "Elipse" + +#: ../../po/../src/sp-ellipse.cpp:583 +#, fuzzy +msgid "Circle" +msgstr "Alterar" + +#: ../../po/../src/sp-ellipse.cpp:865 +#, fuzzy +msgid "Segment" +msgstr "Alterar" + +#: ../../po/../src/sp-ellipse.cpp:867 +msgid "Arc" +msgstr "" + +#. TRANSLATORS: "Flow region" is an area where text is allowed to flow +#: ../../po/../src/sp-flowregion.cpp:276 +#, fuzzy +msgid "Flow region" +msgstr "Seguir ligação" + +#. TRANSLATORS: A region "cut out of" a flow region; text is not allowed to flow inside the +#. * flow excluded region. flowRegionExclude in SVG 1.2: see +#. * http://www.w3.org/TR/2004/WD-SVG12-20041027/flow.html#flowRegion-elem and +#. * http://www.w3.org/TR/2004/WD-SVG12-20041027/flow.html#flowRegionExclude-elem. +#: ../../po/../src/sp-flowregion.cpp:493 +msgid "Flow excluded region" +msgstr "" + +#: ../../po/../src/sp-flowtext.cpp:355 +#, c-format +msgid "Flowed text (%d characters)" +msgstr "" + +#: ../../po/../src/sp-flowtext.cpp:357 +#, c-format +msgid "Linked flowed text (%d characters)" +msgstr "" + +#: ../../po/../src/sp-guide.cpp:290 +#, fuzzy +msgid "vertical guideline" +msgstr "Valor vertical do centro" + +#: ../../po/../src/sp-guide.cpp:292 +#, fuzzy +msgid "horizontal guideline" +msgstr "mover horizontalmente" + +#: ../../po/../src/sp-image.cpp:835 +msgid "embedded" +msgstr "" + +#: ../../po/../src/sp-image.cpp:839 +msgid "(null_pointer)" +msgstr "" + +#: ../../po/../src/sp-image.cpp:843 +#, fuzzy, c-format +msgid "Image with bad reference: %s" +msgstr "Imagem com referência inválida: %s" + +#: ../../po/../src/sp-image.cpp:844 +#, fuzzy, c-format +msgid "Image %d × %d: %s" +msgstr "Imagem colorida %d x %d: %s" + +#: ../../po/../src/sp-item-group.cpp:390 +#, fuzzy, c-format +msgid "Group of %d object" +msgid_plural "Group of %d objects" +msgstr[0] "Grupo de %d objectos" +msgstr[1] "Grupo de %d objectos" + +#: ../../po/../src/sp-item.cpp:720 +msgid "Object" +msgstr "Objecto" + +#: ../../po/../src/sp-line.cpp:202 +#, fuzzy +msgid "Line" +msgstr "Alterar" + +#. TRANSLATORS COMMENT: %s is either "outset" or "inset" depending on sign +#: ../../po/../src/sp-offset.cpp:433 +#, c-format +msgid "Linked offset, %s by %f pt" +msgstr "" + +#: ../../po/../src/sp-offset.cpp:434 ../../po/../src/sp-offset.cpp:438 +#, fuzzy +msgid "outset" +msgstr "Combinar os caminhos seleccionados" + +#: ../../po/../src/sp-offset.cpp:434 ../../po/../src/sp-offset.cpp:438 +#, fuzzy +msgid "inset" +msgstr "polegadas" + +#. TRANSLATORS COMMENT: %s is either "outset" or "inset" depending on sign +#: ../../po/../src/sp-offset.cpp:437 +#, c-format +msgid "Dynamic offset, %s by %f pt" +msgstr "" + +#: ../../po/../src/sp-path.cpp:127 +#, fuzzy, c-format +msgid "Path (%i node)" +msgid_plural "Path (%i nodes)" +msgstr[0] "Ligação a %s" +msgstr[1] "Ligação a %s" + +#: ../../po/../src/sp-polygon.cpp:216 +#, fuzzy +msgid "Polygon" +msgstr "Alterar" + +#: ../../po/../src/sp-polyline.cpp:179 +#, fuzzy +msgid "Polyline" +msgstr "Elipse" + +#: ../../po/../src/sp-rect.cpp:250 +#, fuzzy +msgid "Rectangle" +msgstr "Alterar" + +#. TRANSLATORS: since turn count isn't an integer, please adjust the +#. string as needed to deal with an localized plural forms. +#: ../../po/../src/sp-spiral.cpp:305 +#, c-format +msgid "Spiral with %3f turns" +msgstr "" + +#: ../../po/../src/sp-star.cpp:288 +#, c-format +msgid "Star with %d vertex" +msgid_plural "Star with %d vertices" +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/sp-star.cpp:292 +#, c-format +msgid "Polygon with %d vertex" +msgid_plural "Polygon with %d vertices" +msgstr[0] "" +msgstr[1] "" + +#. TRANSLATORS: For description of font with no name. +#: ../../po/../src/sp-text.cpp:420 +msgid "<no name found>" +msgstr "" + +#: ../../po/../src/sp-text.cpp:426 +#, fuzzy, c-format +msgid "Text on path (%s, %s)" +msgstr "Ligação a %s" + +#: ../../po/../src/sp-text.cpp:427 +#, fuzzy, c-format +msgid "Text (%s, %s)" +msgstr "Ligação a %s" + +#. TRANSLATORS: Used for statusbar description for long chains: +#. * "Clone of: Clone of: ... in Layer 1". +#: ../../po/../src/sp-use.cpp:317 +#, fuzzy +msgid "..." +msgstr "Abrir..." + +#: ../../po/../src/sp-use.cpp:325 +#, fuzzy, c-format +msgid "Clone of: %s" +msgstr "Ligação a %s" + +#: ../../po/../src/sp-use.cpp:329 +#, fuzzy +msgid "Orphaned clone" +msgstr "Alterar" + +#: ../../po/../src/spiral-context.cpp:355 +msgid "Ctrl: snap angle" +msgstr "" + +#: ../../po/../src/spiral-context.cpp:357 +msgid "Alt: lock spiral radius" +msgstr "" + +#: ../../po/../src/spiral-context.cpp:469 +#, c-format +msgid "" +"Spiral: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/splivarot.cpp:106 +#, fuzzy +msgid "Select at least 2 paths to perform a boolean operation." +msgstr "Seleccionar todos os objectos no documento" + +#: ../../po/../src/splivarot.cpp:112 +msgid "" +"Select exactly 2 paths to perform difference, XOR, division, or path " +"cut." +msgstr "" + +#: ../../po/../src/splivarot.cpp:129 ../../po/../src/splivarot.cpp:144 +msgid "" +"Unable to determine the z-order of the objects selected for " +"difference, XOR, division, or path cut." +msgstr "" + +#: ../../po/../src/splivarot.cpp:174 +#, fuzzy +msgid "" +"One of the objects is not a path, cannot perform boolean operation." +msgstr "Converter objecto seleccionado em caminho" + +#. TRANSLATORS: "to outline" means "to convert stroke to path" +#: ../../po/../src/splivarot.cpp:554 +#, fuzzy +msgid "Select path(s) to outline." +msgstr "Cortar os objectos seleccionados para área de transferência" + +#. TRANSLATORS: "to outline" means "to convert stroke to path" +#: ../../po/../src/splivarot.cpp:748 +msgid "No stroked paths to outline in the selection." +msgstr "" + +#: ../../po/../src/splivarot.cpp:832 +#, fuzzy +msgid "Selected object is not a path, cannot inset/outset." +msgstr "Converter objecto seleccionado em caminho" + +#: ../../po/../src/splivarot.cpp:1040 +#, fuzzy +msgid "Select path(s) to inset/outset." +msgstr "Cortar os objectos seleccionados para área de transferência" + +#: ../../po/../src/splivarot.cpp:1257 +msgid "No paths to inset/outset in the selection." +msgstr "" + +#: ../../po/../src/splivarot.cpp:1390 +#, fuzzy +msgid "Select path(s) to simplify." +msgstr "Cortar os objectos seleccionados para área de transferência" + +#: ../../po/../src/splivarot.cpp:1417 +msgid "No paths to simplify in the selection." +msgstr "" + +#: ../../po/../src/star-context.cpp:362 +msgid "Ctrl: snap angle; keep rays radial" +msgstr "" + +#: ../../po/../src/star-context.cpp:470 +#, c-format +msgid "" +"Polygon: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/star-context.cpp:471 +#, c-format +msgid "Star: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/text-chemistry.cpp:90 +#, fuzzy +msgid "Select a text and a path to put text on path." +msgstr "Seleccionar todos os objectos no documento" + +#: ../../po/../src/text-chemistry.cpp:95 +msgid "" +"This text object is already put to a path. Remove it from the path " +"first. Use Shift+D to look up its path." +msgstr "" + +#. rect is the only SPShape which is not yet, and thus SVG forbids us from putting text on it +#: ../../po/../src/text-chemistry.cpp:101 +msgid "" +"You cannot put text on a rectangle in this version. Convert rectangle to " +"path first." +msgstr "" + +#: ../../po/../src/text-chemistry.cpp:159 +#, fuzzy +msgid "Select a text on path to remove it from path." +msgstr "Seleccionar todos os objectos no documento" + +#: ../../po/../src/text-chemistry.cpp:181 +#, fuzzy +msgid "No texts-on-paths in the selection." +msgstr "Cortar os objectos seleccionados para área de transferência" + +#: ../../po/../src/text-chemistry.cpp:209 +#: ../../po/../src/text-chemistry.cpp:229 +#, fuzzy +msgid "Select text(s) to remove kerns from." +msgstr "Elevar objectos seleccionados para o topo" + +#: ../../po/../src/text-chemistry.cpp:250 +#, fuzzy +msgid "" +"Select a text and one or more paths or shapes to flow text " +"into frame." +msgstr "Seleccionar todos os objectos no documento" + +#: ../../po/../src/text-chemistry.cpp:322 +#, fuzzy +msgid "Select a flowed text to unflow it." +msgstr "Cortar os objectos seleccionados para área de transferência" + +#: ../../po/../src/text-context.cpp:463 +msgid "Click to edit the text, drag to select part of the text." +msgstr "" + +#: ../../po/../src/text-context.cpp:465 +msgid "" +"Click to edit the flowed text, drag to select part of the text." +msgstr "" + +#: ../../po/../src/text-context.cpp:540 +msgid "Non-printable character" +msgstr "" + +#: ../../po/../src/text-context.cpp:589 +#, fuzzy, c-format +msgid "Unicode: %s: %s" +msgstr "Sodipodi: %s: %s: %d" + +#: ../../po/../src/text-context.cpp:591 ../../po/../src/text-context.cpp:855 +msgid "Unicode: " +msgstr "" + +#: ../../po/../src/text-context.cpp:615 +msgid "Current layer is hidden. Unhide it to be able to add text." +msgstr "" + +#: ../../po/../src/text-context.cpp:619 +msgid "Current layer is locked. Unlock it to be able to add text." +msgstr "" + +#: ../../po/../src/text-context.cpp:673 +#, c-format +msgid "Flowed text frame: %s × %s" +msgstr "" + +#: ../../po/../src/text-context.cpp:708 ../../po/../src/text-context.cpp:1464 +msgid "Type text; Enter to start new line." +msgstr "" + +#: ../../po/../src/text-context.cpp:719 +msgid "Flowed text is created." +msgstr "" + +#: ../../po/../src/text-context.cpp:722 +msgid "" +"The frame is too small for the current font size. Flowed text not " +"created." +msgstr "" + +#: ../../po/../src/text-context.cpp:841 +msgid "No-break space" +msgstr "" + +#: ../../po/../src/text-context.cpp:1462 +msgid "Type flowed text; Enter to start new paragraph." +msgstr "" + +#: ../../po/../src/text-context.cpp:1472 ../../po/../src/tools-switch.cpp:189 +msgid "" +"Click to select or create text, drag to create flowed text; " +"then type." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:141 +msgid "" +"To edit a path, click, Shift+click, or drag around " +"nodes to select them, then drag nodes and handles. Click on an " +"object to select." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:147 +#, fuzzy +msgid "" +"Drag to create a rectangle. Drag controls to round corners and " +"resize. Click to select." +msgstr "Criar rectângulos e quadrados com cantos arredondados opcionais" + +#: ../../po/../src/tools-switch.cpp:153 +msgid "" +"Drag to create an ellipse. Drag controls to make an arc or " +"segment. Click to select." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:159 +msgid "" +"Drag to create a star. Drag controls to edit the star shape. " +"Click to select." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:165 +msgid "" +"Drag to create a spiral. Drag controls to edit the spiral " +"shape. Click to select." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:171 +#, fuzzy +msgid "" +"Drag to create a freehand line. Start drawing with Shift to " +"append to selected path." +msgstr "A criar nova curva. Prima 'a' para alternar Anexar/Novo." + +#: ../../po/../src/tools-switch.cpp:177 +#, fuzzy +msgid "" +"Click or click and drag to start a path; with Shift to " +"append to selected path." +msgstr "A criar nova curva. Prima 'a' para alternar Anexar/Novo." + +#: ../../po/../src/tools-switch.cpp:183 +msgid "" +"Drag to paint a calligraphic stroke. Left/right arrow " +"keys adjust width, up/down adjust angle." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:195 +#, fuzzy +msgid "" +"Drag or double click to create a gradient on selected objects, " +"drag handles to adjust gradients." +msgstr "A criar nova curva. Prima 'a' para alternar Anexar/Novo." + +#: ../../po/../src/tools-switch.cpp:201 +msgid "" +"Click or drag around an area to zoom in, Shift+click to " +"zoom out." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:213 +msgid "Click and drag between shapes to create a connector." +msgstr "" + +#: ../../po/../src/trace/potrace/inkscape-potrace.cpp:553 +#: ../../po/../src/trace/potrace/inkscape-potrace.cpp:654 +#, c-format +msgid "Trace: %d. %ld nodes" +msgstr "" + +#: ../../po/../src/trace/trace.cpp:53 ../../po/../src/trace/trace.cpp:62 +#: ../../po/../src/trace/trace.cpp:70 +#, fuzzy +msgid "Select an image to trace" +msgstr "Cortar os objectos seleccionados para área de transferência" + +#: ../../po/../src/trace/trace.cpp:133 +#, fuzzy +msgid "Trace: No active document" +msgstr "Criar um novo documento SVG" + +#: ../../po/../src/trace/trace.cpp:154 +msgid "Trace: Image has no bitmap data" +msgstr "" + +#: ../../po/../src/trace/trace.cpp:267 +#, fuzzy, c-format +msgid "Trace: Done. %ld nodes created" +msgstr "Último seleccionado" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:59 ../../po/../src/verbs.cpp:2212 +msgid "About Inkscape" +msgstr "" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:66 +msgid "_Splash" +msgstr "" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:68 +msgid "_Authors" +msgstr "" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:69 +#, fuzzy +msgid "_Translators" +msgstr "Transformações" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:70 +#, fuzzy +msgid "_License" +msgstr "polegadas" + +#. TRANSLATORS: This is the filename of the `About Inkscape' picture in +#. the `screens' directory. Thus the translation of "about.svg" should be +#. the filename of its translated version, e.g. about.zh.svg for Chinese. +#. +#. N.B. about.svg changes once per release. (We should probably rename +#. the original to about-0.40.svg etc. as soon as we have a translation. +#. If we do so, then add an item to release-checklist saying that the +#. string here should be changed.) +#. FIXME? INKSCAPE_SCREENSDIR and "about.svg" are in UTF-8, not the +#. native filename encoding... and the filename passed to sp_document_new +#. should be in UTF-*8.. +#: ../../po/../src/ui/dialog/aboutbox.cpp:114 +msgid "about.svg" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:464 +msgid "Minimum horizontal gap (in px units) between bounding boxes" +msgstr "" + +#. TRANSLATORS: Horizontal gap +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:466 +#: ../../po/../src/widgets/toolbox.cpp:1556 +msgid "H:" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:474 +msgid "Minimum vertical gap (in px units) between bounding boxes" +msgstr "" + +#. TRANSLATORS: Vertical gap +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:476 +msgid "V:" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:734 +msgid "Align" +msgstr "Alinhar" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:735 +msgid "Distribute" +msgstr "Distribuir" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:736 +msgid "Remove overlaps" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:737 +msgid "Nodes" +msgstr "Nós" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:742 +#, fuzzy +msgid "Relative to: " +msgstr "Movimento relativo" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:747 +#, fuzzy +msgid "Align right sides of objects to left side of anchor" +msgstr "Lado direito dos objectos alinhados ao lado esquerdo da âncora" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:750 +#, fuzzy +msgid "Align left sides" +msgstr "Alinhar à esquerda no centro" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:753 +#, fuzzy +msgid "Center on vertical axis" +msgstr "Centrar verticalmente" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:756 +#, fuzzy +msgid "Align right sides" +msgstr "Alinhar à direita no centro" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:759 +#, fuzzy +msgid "Align left sides of objects to right side of anchor" +msgstr "Lado esquerdo dos objectos alinhados ao lado direito da âncora" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:762 +#, fuzzy +msgid "Align bottoms of objects to top of anchor" +msgstr "Fundo dos objectos alinhados ao topo da âncora" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:765 +#, fuzzy +msgid "Align tops" +msgstr "Alinhar objectos" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:768 +#, fuzzy +msgid "Center on horizontal axis" +msgstr "Centrar horizontalmente" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:771 +#, fuzzy +msgid "Align bottoms" +msgstr "Alinhar à esquerda em baixo" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:774 +#, fuzzy +msgid "Align tops of objects to bottom of anchor" +msgstr "Topo dos objectos alinhados ao topo da âncora" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:779 +#, fuzzy +msgid "Align baseline anchors of texts vertically" +msgstr "Inverter verticalmente os objectos seleccionados" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:782 +#, fuzzy +msgid "Align baseline anchors of texts horizontally" +msgstr "Inverter horizontalmente os objectos seleccionados" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:787 +#, fuzzy +msgid "Make horizontal gaps between objects equal" +msgstr "Distribuir distância horizontal entre objectos equitativamente" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:791 +#, fuzzy +msgid "Distribute left sides equidistantly" +msgstr "Distribuir lados esquerdos dos objectos a distâncias equivalentes" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:794 +#, fuzzy +msgid "Distribute centers equidistantly horizontally" +msgstr "" +"Distribuir centro dos objectos a distâncias horizontalmente equivalentes" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:797 +#, fuzzy +msgid "Distribute right sides equidistantly" +msgstr "Distribuir lados direitos dos objectos a distâncias equivalentes" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:801 +#, fuzzy +msgid "Make vertical gaps between objects equal" +msgstr "Distribuir distância vertical entre objectos equitativamente" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:805 +#, fuzzy +msgid "Distribute tops equidistantly" +msgstr "Distribuir centro dos objectos a distâncias verticalmente equivalentes" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:808 +#, fuzzy +msgid "Distribute centers equidistantly vertically" +msgstr "Distribuir centro dos objectos a distâncias verticalmente equivalentes" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:811 +#, fuzzy +msgid "Distribute bottoms equidistantly" +msgstr "Distribuir lados de fundo dos objectos a distâncias equivalentes" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:816 +#, fuzzy +msgid "Distribute baseline anchors of texts horizontally" +msgstr "Inverter horizontalmente os objectos seleccionados" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:819 +#, fuzzy +msgid "Distribute baseline anchors of texts vertically" +msgstr "Distribuir centro dos objectos a distâncias verticalmente equivalentes" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:824 +msgid "Randomize centers in both dimensions" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:827 +msgid "Unclump objects: try to equalize edge-to-edge distances" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:832 +msgid "" +"Move objects as little as possible so that their bounding boxes do not " +"overlap" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:837 +#, fuzzy +msgid "Align selected nodes horizontally" +msgstr "Inverter horizontalmente os objectos seleccionados" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:840 +#, fuzzy +msgid "Align selected nodes vertically" +msgstr "Inverter verticalmente os objectos seleccionados" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:843 +#, fuzzy +msgid "Distribute selected nodes horizontally" +msgstr "Inverter horizontalmente os objectos seleccionados" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:846 +#, fuzzy +msgid "Distribute selected nodes vertically" +msgstr "Distribuir centro dos objectos a distâncias verticalmente equivalentes" + +#. Rest of the widgetry +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:851 +msgid "Last selected" +msgstr "Último seleccionado" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:852 +msgid "First selected" +msgstr "Primeiro seleccionado" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:853 +msgid "Biggest item" +msgstr "Item maior" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:854 +msgid "Smallest item" +msgstr "Item menor" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:856 +#: ../../po/../src/widgets/desktop-widget.cpp:1065 +msgid "Drawing" +msgstr "Desenho" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:91 +msgid "Metadata 1" +msgstr "" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:92 +msgid "Metadata 2" +msgstr "" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:187 +#, fuzzy +msgid "X coordinate of grid origin" +msgstr "Escolha a cor para as guias" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:189 +#, fuzzy +msgid "Y coordinate of grid origin" +msgstr "Escolha a cor para as guias" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:191 +#, fuzzy +msgid "Distance of vertical grid lines" +msgstr "Especifica a distância entre as linhas verticais da grelha" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:193 +#, fuzzy +msgid "Distance of horizontal grid lines" +msgstr "Especifica a distância entre as linhas horizontais da grelha" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:197 +msgid "Max. snapping distance from grid" +msgstr "" + +#: ../../po/../src/ui/dialog/export.cpp:34 +msgid "Export" +msgstr "Exportar" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:36 +msgid "Fill" +msgstr "Preenchimento" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:37 +#, fuzzy +msgid "Stroke Paint" +msgstr "Largura da rasura" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:38 +#, fuzzy +msgid "Stroke Style" +msgstr "Preferências pincelada" + +#: ../../po/../src/ui/dialog/find.cpp:34 +#, fuzzy +msgid "Find" +msgstr "Grelha" + +#: ../../po/../src/ui/dialog/memory.cpp:96 +#, fuzzy +msgid "Heap" +msgstr "_Ajuda" + +#: ../../po/../src/ui/dialog/memory.cpp:97 +#, fuzzy +msgid "In Use" +msgstr "Repor" + +#. TRANSLATORS: "Slack" refers to memory which is in the heap but currently unused. +#. More typical usage is to call this memory "free" rather than "slack". +#: ../../po/../src/ui/dialog/memory.cpp:100 +#, fuzzy +msgid "Slack" +msgstr "Estrela" + +#: ../../po/../src/ui/dialog/memory.cpp:101 +#, fuzzy +msgid "Total" +msgstr "Título:" + +#: ../../po/../src/ui/dialog/memory.cpp:141 +#: ../../po/../src/ui/dialog/memory.cpp:147 +#: ../../po/../src/ui/dialog/memory.cpp:154 +#: ../../po/../src/ui/dialog/memory.cpp:186 +msgid "Unknown" +msgstr "Desconhecido" + +#: ../../po/../src/ui/dialog/memory.cpp:167 +#, fuzzy +msgid "Combined" +msgstr "Combinar" + +#: ../../po/../src/ui/dialog/memory.cpp:209 +#, fuzzy +msgid "Recalculate" +msgstr "Rectângulo" + +#: ../../po/../src/ui/dialog/messages.cpp:74 +#, fuzzy +msgid "Ready." +msgstr "Reler" + +#: ../../po/../src/ui/dialog/messages.cpp:75 +msgid "" +"Enable log display by setting dialogs.debug 'redirect' attribute to 1 in " +"preferences.xml" +msgstr "" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:184 +msgid "_Execute Python" +msgstr "" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:186 +msgid "_Execute Perl" +msgstr "" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:195 +msgid "Script" +msgstr "" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:205 +#, fuzzy +msgid "Output" +msgstr "Afastar" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:215 +msgid "Errors" +msgstr "" + +#. Dialog organization +#: ../../po/../src/ui/dialog/session-player.cpp:73 +#, fuzzy +msgid "Session file" +msgstr "Gravar ficheiro" + +#: ../../po/../src/ui/dialog/session-player.cpp:74 +#, fuzzy +msgid "Playback controls" +msgstr "Opções ferramentas" + +#: ../../po/../src/ui/dialog/session-player.cpp:75 +#, fuzzy +msgid "Message information" +msgstr "Repor transformação" + +#. Active session file display +#. fixme: Does this mean the active file for the session, or the file for the active session? +#. Please indicate which with a TRANSLATORS comment. +#: ../../po/../src/ui/dialog/session-player.cpp:85 +msgid "Active session file:" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:86 +msgid "Delay (milliseconds):" +msgstr "" + +#. Unload/load buttons +#: ../../po/../src/ui/dialog/session-player.cpp:94 +#, fuzzy +msgid "Close file" +msgstr "Cor do preenchimento" + +#: ../../po/../src/ui/dialog/session-player.cpp:95 +#, fuzzy +msgid "Open new file" +msgstr "Abrir novo desenho" + +#: ../../po/../src/ui/dialog/session-player.cpp:96 +#, fuzzy +msgid "Set delay" +msgstr "Definir por omissão" + +#: ../../po/../src/ui/dialog/session-player.cpp:138 +#, fuzzy +msgid "Rewind" +msgstr "Vermelho:" + +#: ../../po/../src/ui/dialog/session-player.cpp:139 +msgid "Go back one change" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:140 +#, fuzzy +msgid "Pause" +msgstr "Colar" + +#: ../../po/../src/ui/dialog/session-player.cpp:141 +msgid "Go forward one change" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:142 +msgid "Play" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:177 +#: ../../po/../src/verbs.cpp:1573 +msgid "Open session file" +msgstr "" + +#. ##Set up the Potrace panel +#. #### brightness #### +#. #### Multiple scanning#### +#. ----Hbox1 +#: ../../po/../src/ui/dialog/tracedialog.cpp:345 +#: ../../po/../src/ui/dialog/tracedialog.cpp:428 +#, fuzzy +msgid "Brightness" +msgstr "Altura" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:348 +msgid "Trace by a given brightness level" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:355 +msgid "Brightness cutoff for black/white" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:362 +#, fuzzy +msgid "Image Brightness" +msgstr "Tamanho da imagem" + +#. #### canny edge detection #### +#. TRANSLATORS: "Canny" is the name of the inventor of this edge detection method +#: ../../po/../src/ui/dialog/tracedialog.cpp:369 +msgid "Optimal Edge Detection (Canny)" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:372 +msgid "Trace with edge detection by J. Canny's algorithm" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:388 +msgid "Brightness cutoff for adjacent pixels (determines edge thickness)" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:395 +#, fuzzy +msgid "Edge Detection" +msgstr "Selecção" + +#. #### quantization #### +#. TRANSLATORS: Color Quantization: the process of reducing the number of colors +#. in an image by selecting an optimized set of representative colors and then +#. re-applying this reduced set to the original image. +#: ../../po/../src/ui/dialog/tracedialog.cpp:404 +#, fuzzy +msgid "Color Quantization" +msgstr "Pintura a cores" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:407 +msgid "Trace along the boundaries of reduced colors" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:414 +#, fuzzy +msgid "The number of reduced colors" +msgstr "Número de cantos:" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:416 +#, fuzzy +msgid "Colors:" +msgstr "Cor:" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:421 +msgid "Quantization / Reduction" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:431 +msgid "Trace the given number of brightness levels" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:438 +#, fuzzy +msgid "Scans:" +msgstr "Forma" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:440 +msgid "The desired number of scans" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:448 +msgid "Trace the given number of reduced colors" +msgstr "" + +#. ---Hbox3 +#: ../../po/../src/ui/dialog/tracedialog.cpp:454 +msgid "Monochrome" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:457 +msgid "Same as Color, but convert result to grayscale" +msgstr "" + +#. TRANSLATORS: "Stack" is a verb here +#: ../../po/../src/ui/dialog/tracedialog.cpp:460 +#, fuzzy +msgid "Stack" +msgstr "Estrela" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:463 +msgid "" +"Stack scans vertically (no gaps) or tile horizontally (usually with gaps)" +msgstr "" + +#. TRANSLATORS: "Smooth" is a verb here +#: ../../po/../src/ui/dialog/tracedialog.cpp:466 +msgid "Smooth" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:469 +msgid "Apply Gaussian blur to the bitmap before tracing" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:473 +msgid "Multiple Scanning" +msgstr "" + +#. #### Preview #### +#: ../../po/../src/ui/dialog/tracedialog.cpp:479 +#: ../../po/../src/ui/dialog/tracedialog.cpp:489 +#, fuzzy +msgid "Preview" +msgstr "Nova Antevisão" + +#. do not expand +#: ../../po/../src/ui/dialog/tracedialog.cpp:483 +msgid "Preview the result without actual tracing" +msgstr "" + +#. #### swap black and white #### +#: ../../po/../src/ui/dialog/tracedialog.cpp:495 +#, fuzzy +msgid "Invert" +msgstr "Repor" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:499 +msgid "Invert black and white regions for single traces" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:503 +msgid "Thanks to Peter Selinger, http://potrace.sourceforge.net" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:506 +#, fuzzy +msgid "Credits" +msgstr "Cantos:" + +#. done +#. TRANSLATORS: Potrace is an application for transforming bitmaps into +#. vector graphics (http://potrace.sourceforge.net/) +#: ../../po/../src/ui/dialog/tracedialog.cpp:514 +#, fuzzy +msgid "Potrace" +msgstr "Analisar" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:527 +#, fuzzy +msgid "Abort a trace in progress" +msgstr "Exportar área" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:531 +msgid "Execute the trace" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:80 +#: ../../po/../src/ui/dialog/transformation.cpp:90 +#, fuzzy +msgid "_Horizontal" +msgstr "mover horizontalmente" + +#: ../../po/../src/ui/dialog/transformation.cpp:80 +msgid "Horizontal displacement (relative) or position (absolute)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:82 +#: ../../po/../src/ui/dialog/transformation.cpp:92 +#, fuzzy +msgid "_Vertical" +msgstr "Valor vertical do centro" + +#: ../../po/../src/ui/dialog/transformation.cpp:82 +msgid "Vertical displacement (relative) or position (absolute)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:84 +#, fuzzy +msgid "_Width" +msgstr "Largura:" + +#: ../../po/../src/ui/dialog/transformation.cpp:84 +msgid "Horizontal size increment (absolute or percentage)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:86 +#, fuzzy +msgid "_Height" +msgstr "Altura:" + +#: ../../po/../src/ui/dialog/transformation.cpp:86 +msgid "Vertical size increment (absolute or percentage)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:88 +#, fuzzy +msgid "A_ngle" +msgstr "Ângulo" + +#: ../../po/../src/ui/dialog/transformation.cpp:88 +#, fuzzy +msgid "Rotation angle (positive = counterclockwise)" +msgstr "Rodar objecto 90 graus no sentido dos ponteiros" + +#: ../../po/../src/ui/dialog/transformation.cpp:90 +msgid "" +"Horizontal skew angle (positive = counterclockwise), or absolute " +"displacement, or percentage displacement" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:92 +msgid "" +"Vertical skew angle (positive = counterclockwise), or absolute displacement, " +"or percentage displacement" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:95 +#, fuzzy +msgid "Transformation matrix element A" +msgstr "Matriz transformação" + +#: ../../po/../src/ui/dialog/transformation.cpp:96 +#, fuzzy +msgid "Transformation matrix element B" +msgstr "Matriz transformação" + +#: ../../po/../src/ui/dialog/transformation.cpp:97 +#, fuzzy +msgid "Transformation matrix element C" +msgstr "Matriz transformação" + +#: ../../po/../src/ui/dialog/transformation.cpp:98 +#, fuzzy +msgid "Transformation matrix element D" +msgstr "Matriz transformação" + +#: ../../po/../src/ui/dialog/transformation.cpp:99 +#, fuzzy +msgid "Transformation matrix element E" +msgstr "Matriz transformação" + +#: ../../po/../src/ui/dialog/transformation.cpp:100 +#, fuzzy +msgid "Transformation matrix element F" +msgstr "Matriz transformação" + +#: ../../po/../src/ui/dialog/transformation.cpp:102 +#, fuzzy +msgid "Rela_tive move" +msgstr "Movimento relativo" + +#: ../../po/../src/ui/dialog/transformation.cpp:102 +msgid "" +"Add the specified relative displacement to the current position; otherwise, " +"edit the current absolute position directly" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:103 +msgid "Scale proportionally" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:103 +msgid "Preserve the width/height ratio of the scaled objects" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:104 +msgid "Apply to each _object separately" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:104 +msgid "" +"Apply the scale/rotate/skew to each selected object separately; otherwise, " +"transform the selection as a whole" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:105 +msgid "Edit c_urrent matrix" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:105 +msgid "" +"Edit the current transform= matrix; otherwise, post-multiply transform= by " +"this matrix" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:115 +#, fuzzy +msgid "_Move" +msgstr "Mover" + +#: ../../po/../src/ui/dialog/transformation.cpp:118 +#, fuzzy +msgid "_Scale" +msgstr "Escala" + +#: ../../po/../src/ui/dialog/transformation.cpp:121 +#, fuzzy +msgid "_Rotate" +msgstr "Rodar" + +#: ../../po/../src/ui/dialog/transformation.cpp:124 +#, fuzzy +msgid "Ske_w" +msgstr "Inclinar" + +#: ../../po/../src/ui/dialog/transformation.cpp:127 +msgid "Matri_x" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:141 +#, fuzzy +msgid "Reset the values on the current tab to defaults" +msgstr "Repor valores por defeito do diálogo- Ctl+r" + +#: ../../po/../src/ui/dialog/transformation.cpp:148 +#, fuzzy +msgid "Apply transformation to selection" +msgstr "Aplicar a transformação à cópia Ctl+m" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:43 +msgid "_Use SSL" +msgstr "" + +#. Construct dialog interface +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:68 +#, fuzzy +msgid "_Server:" +msgstr "Filtros" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:69 +#, fuzzy +msgid "_Username:" +msgstr "Ficheiro:" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:70 +msgid "_Password:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:71 +msgid "P_ort:" +msgstr "" + +#. Buttons +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:99 +#, fuzzy +msgid "Connect" +msgstr "Conteúdo" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:126 +msgid "Establishing connection to Jabber server %1 as user %2" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:131 +msgid "Failed to establish connection to Jabber server %1" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:136 +msgid "Authentication failed on Jabber server %1 as %2" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:141 +msgid "SSL initialization failed when connecting to Jabber server %1" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:147 +msgid "Connected to Jabber server %1 as %2" +msgstr "" + +#. Construct labels +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:75 +msgid "Chatroom _name:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:76 +msgid "Chatroom _server:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:77 +msgid "Chatroom _password:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:78 +msgid "Chatroom _handle:" +msgstr "" + +#. Button setup and callback registration +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:97 +msgid "Connect to chatroom" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:132 +msgid "Synchronizing with chatroom %1@%2 using the handle %3" +msgstr "" + +#. Construct dialog interface +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:78 +msgid "_User's Jabber ID:" +msgstr "" + +#. Buttons +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:82 +msgid "_Invite user" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:83 +#, fuzzy +msgid "_Cancel" +msgstr "Cancelar" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:94 +msgid "Buddy List" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:170 +msgid "Sending whiteboard invitation to %1" +msgstr "" + +#. FIXME: strings are replaced by placeholders, NOT to be translated until the code is enabled +#. See http://sourceforge.net/mailarchive/message.php?msg_id=11746016 for details +#. File menu +#. Edit menu +#. View menu +#. Layer menu +#. Object menu +#. Path menu +#. add(Gtk::StockItem(CLEANUP, _("PLACEHOLDER, do not translate"))); (using Gtk::Stock::CLEAR) +#. Text menu +#. About menu +#. Tools toolbox +#. Select Tool controls +#. Node Tool controls +#. Calligraphy Tool controls +#. Session playback controls +#: ../../po/../src/ui/stock-items.cpp:34 ../../po/../src/ui/stock-items.cpp:35 +#: ../../po/../src/ui/stock-items.cpp:36 ../../po/../src/ui/stock-items.cpp:37 +#: ../../po/../src/ui/stock-items.cpp:38 ../../po/../src/ui/stock-items.cpp:39 +#: ../../po/../src/ui/stock-items.cpp:40 ../../po/../src/ui/stock-items.cpp:41 +#: ../../po/../src/ui/stock-items.cpp:42 ../../po/../src/ui/stock-items.cpp:43 +#: ../../po/../src/ui/stock-items.cpp:46 ../../po/../src/ui/stock-items.cpp:47 +#: ../../po/../src/ui/stock-items.cpp:48 ../../po/../src/ui/stock-items.cpp:49 +#: ../../po/../src/ui/stock-items.cpp:50 ../../po/../src/ui/stock-items.cpp:51 +#: ../../po/../src/ui/stock-items.cpp:52 ../../po/../src/ui/stock-items.cpp:53 +#: ../../po/../src/ui/stock-items.cpp:54 ../../po/../src/ui/stock-items.cpp:55 +#: ../../po/../src/ui/stock-items.cpp:56 ../../po/../src/ui/stock-items.cpp:57 +#: ../../po/../src/ui/stock-items.cpp:58 ../../po/../src/ui/stock-items.cpp:59 +#: ../../po/../src/ui/stock-items.cpp:62 ../../po/../src/ui/stock-items.cpp:63 +#: ../../po/../src/ui/stock-items.cpp:64 ../../po/../src/ui/stock-items.cpp:65 +#: ../../po/../src/ui/stock-items.cpp:66 ../../po/../src/ui/stock-items.cpp:67 +#: ../../po/../src/ui/stock-items.cpp:68 ../../po/../src/ui/stock-items.cpp:69 +#: ../../po/../src/ui/stock-items.cpp:70 ../../po/../src/ui/stock-items.cpp:71 +#: ../../po/../src/ui/stock-items.cpp:72 ../../po/../src/ui/stock-items.cpp:73 +#: ../../po/../src/ui/stock-items.cpp:74 ../../po/../src/ui/stock-items.cpp:75 +#: ../../po/../src/ui/stock-items.cpp:76 ../../po/../src/ui/stock-items.cpp:77 +#: ../../po/../src/ui/stock-items.cpp:78 ../../po/../src/ui/stock-items.cpp:79 +#: ../../po/../src/ui/stock-items.cpp:80 ../../po/../src/ui/stock-items.cpp:81 +#: ../../po/../src/ui/stock-items.cpp:82 ../../po/../src/ui/stock-items.cpp:83 +#: ../../po/../src/ui/stock-items.cpp:84 ../../po/../src/ui/stock-items.cpp:85 +#: ../../po/../src/ui/stock-items.cpp:86 ../../po/../src/ui/stock-items.cpp:87 +#: ../../po/../src/ui/stock-items.cpp:88 ../../po/../src/ui/stock-items.cpp:89 +#: ../../po/../src/ui/stock-items.cpp:92 ../../po/../src/ui/stock-items.cpp:93 +#: ../../po/../src/ui/stock-items.cpp:94 ../../po/../src/ui/stock-items.cpp:95 +#: ../../po/../src/ui/stock-items.cpp:96 ../../po/../src/ui/stock-items.cpp:97 +#: ../../po/../src/ui/stock-items.cpp:98 ../../po/../src/ui/stock-items.cpp:99 +#: ../../po/../src/ui/stock-items.cpp:100 +#: ../../po/../src/ui/stock-items.cpp:101 +#: ../../po/../src/ui/stock-items.cpp:102 +#: ../../po/../src/ui/stock-items.cpp:103 +#: ../../po/../src/ui/stock-items.cpp:104 +#: ../../po/../src/ui/stock-items.cpp:105 +#: ../../po/../src/ui/stock-items.cpp:108 +#: ../../po/../src/ui/stock-items.cpp:109 +#: ../../po/../src/ui/stock-items.cpp:110 +#: ../../po/../src/ui/stock-items.cpp:111 +#: ../../po/../src/ui/stock-items.cpp:112 +#: ../../po/../src/ui/stock-items.cpp:113 +#: ../../po/../src/ui/stock-items.cpp:114 +#: ../../po/../src/ui/stock-items.cpp:115 +#: ../../po/../src/ui/stock-items.cpp:116 +#: ../../po/../src/ui/stock-items.cpp:117 +#: ../../po/../src/ui/stock-items.cpp:118 +#: ../../po/../src/ui/stock-items.cpp:119 +#: ../../po/../src/ui/stock-items.cpp:120 +#: ../../po/../src/ui/stock-items.cpp:121 +#: ../../po/../src/ui/stock-items.cpp:122 +#: ../../po/../src/ui/stock-items.cpp:123 +#: ../../po/../src/ui/stock-items.cpp:124 +#: ../../po/../src/ui/stock-items.cpp:125 +#: ../../po/../src/ui/stock-items.cpp:126 +#: ../../po/../src/ui/stock-items.cpp:127 +#: ../../po/../src/ui/stock-items.cpp:130 +#: ../../po/../src/ui/stock-items.cpp:131 +#: ../../po/../src/ui/stock-items.cpp:132 +#: ../../po/../src/ui/stock-items.cpp:133 +#: ../../po/../src/ui/stock-items.cpp:134 +#: ../../po/../src/ui/stock-items.cpp:135 +#: ../../po/../src/ui/stock-items.cpp:136 +#: ../../po/../src/ui/stock-items.cpp:137 +#: ../../po/../src/ui/stock-items.cpp:138 +#: ../../po/../src/ui/stock-items.cpp:139 +#: ../../po/../src/ui/stock-items.cpp:140 +#: ../../po/../src/ui/stock-items.cpp:141 +#: ../../po/../src/ui/stock-items.cpp:142 +#: ../../po/../src/ui/stock-items.cpp:143 +#: ../../po/../src/ui/stock-items.cpp:144 +#: ../../po/../src/ui/stock-items.cpp:145 +#: ../../po/../src/ui/stock-items.cpp:146 +#: ../../po/../src/ui/stock-items.cpp:150 +#: ../../po/../src/ui/stock-items.cpp:151 +#: ../../po/../src/ui/stock-items.cpp:152 +#: ../../po/../src/ui/stock-items.cpp:153 +#: ../../po/../src/ui/stock-items.cpp:156 +#: ../../po/../src/ui/stock-items.cpp:157 +#: ../../po/../src/ui/stock-items.cpp:158 +#: ../../po/../src/ui/stock-items.cpp:161 +#: ../../po/../src/ui/stock-items.cpp:162 +#: ../../po/../src/ui/stock-items.cpp:163 +#: ../../po/../src/ui/stock-items.cpp:164 +#: ../../po/../src/ui/stock-items.cpp:165 +#: ../../po/../src/ui/stock-items.cpp:166 +#: ../../po/../src/ui/stock-items.cpp:167 +#: ../../po/../src/ui/stock-items.cpp:168 +#: ../../po/../src/ui/stock-items.cpp:169 +#: ../../po/../src/ui/stock-items.cpp:170 +#: ../../po/../src/ui/stock-items.cpp:171 +#: ../../po/../src/ui/stock-items.cpp:172 +#: ../../po/../src/ui/stock-items.cpp:175 +#: ../../po/../src/ui/stock-items.cpp:176 +#: ../../po/../src/ui/stock-items.cpp:177 +#: ../../po/../src/ui/stock-items.cpp:178 +#: ../../po/../src/ui/stock-items.cpp:181 +#: ../../po/../src/ui/stock-items.cpp:182 +#: ../../po/../src/ui/stock-items.cpp:183 +#: ../../po/../src/ui/stock-items.cpp:184 +#: ../../po/../src/ui/stock-items.cpp:185 +#: ../../po/../src/ui/stock-items.cpp:186 +#: ../../po/../src/ui/stock-items.cpp:187 +#: ../../po/../src/ui/stock-items.cpp:188 +#: ../../po/../src/ui/stock-items.cpp:189 +#: ../../po/../src/ui/stock-items.cpp:190 +#: ../../po/../src/ui/stock-items.cpp:191 +#: ../../po/../src/ui/stock-items.cpp:194 +#: ../../po/../src/ui/stock-items.cpp:195 +#: ../../po/../src/ui/stock-items.cpp:198 +#: ../../po/../src/ui/stock-items.cpp:199 +#: ../../po/../src/ui/stock-items.cpp:200 +#: ../../po/../src/ui/stock-items.cpp:201 +#: ../../po/../src/ui/stock-items.cpp:202 +msgid "PLACEHOLDER, do not translate" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:88 +msgid "small" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:89 +msgid "medium" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:90 +#, fuzzy +msgid "large" +msgstr "Alvo:" + +#: ../../po/../src/ui/widget/panel.cpp:91 +msgid "huge" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:106 +#, fuzzy +msgid "List" +msgstr "polegadas" + +#: ../../po/../src/ui/widget/selected-style.cpp:67 +msgid "F:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:68 +msgid "S:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:69 +msgid "O:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:95 +msgid "N/A" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:98 +#: ../../po/../src/ui/widget/selected-style.cpp:712 +#, fuzzy +msgid "Nothing selected" +msgstr "Apagar objectos seleccionados" + +#: ../../po/../src/ui/widget/selected-style.cpp:103 +msgid "No fill" +msgstr "Sem preenchimento" + +#: ../../po/../src/ui/widget/selected-style.cpp:103 +#, fuzzy +msgid "No stroke" +msgstr "Rasurado" + +#: ../../po/../src/ui/widget/selected-style.cpp:105 +#: ../../po/../src/widgets/paint-selector.cpp:190 +#, fuzzy +msgid "Pattern" +msgstr "Padrão:" + +#: ../../po/../src/ui/widget/selected-style.cpp:108 +#: ../../po/../src/widgets/paint-selector.cpp:885 +#, fuzzy +msgid "Pattern fill" +msgstr "Padrão:" + +#: ../../po/../src/ui/widget/selected-style.cpp:108 +#, fuzzy +msgid "Pattern stroke" +msgstr "Preencher com padrão" + +#: ../../po/../src/ui/widget/selected-style.cpp:110 +#, fuzzy +msgid "L Gradient" +msgstr "Preencher com Gradiente" + +#: ../../po/../src/ui/widget/selected-style.cpp:113 +#, fuzzy +msgid "Linear gradient fill" +msgstr "Gradiente linear" + +#: ../../po/../src/ui/widget/selected-style.cpp:113 +#, fuzzy +msgid "Linear gradient stroke" +msgstr "Gradiente linear" + +#: ../../po/../src/ui/widget/selected-style.cpp:115 +#, fuzzy +msgid "R Gradient" +msgstr "Preencher com Gradiente" + +#: ../../po/../src/ui/widget/selected-style.cpp:118 +#, fuzzy +msgid "Radial gradient fill" +msgstr "Gradiente radial" + +#: ../../po/../src/ui/widget/selected-style.cpp:118 +#, fuzzy +msgid "Radial gradient stroke" +msgstr "Gradiente radial" + +#: ../../po/../src/ui/widget/selected-style.cpp:120 +#, fuzzy +msgid "Different" +msgstr "Grau" + +#: ../../po/../src/ui/widget/selected-style.cpp:123 +#, fuzzy +msgid "Different fills" +msgstr "Grau" + +#: ../../po/../src/ui/widget/selected-style.cpp:123 +#, fuzzy +msgid "Different strokes" +msgstr "Grau" + +#: ../../po/../src/ui/widget/selected-style.cpp:125 +#, fuzzy +msgid "Unset" +msgstr "polegadas" + +#. TRANSLATORS COMMENT: unset is a verb here +#: ../../po/../src/ui/widget/selected-style.cpp:128 +#: ../../po/../src/ui/widget/selected-style.cpp:182 +#, fuzzy +msgid "Unset fill" +msgstr "SemTitulo" + +#: ../../po/../src/ui/widget/selected-style.cpp:128 +#: ../../po/../src/ui/widget/selected-style.cpp:182 +#, fuzzy +msgid "Unset stroke" +msgstr "Rasurado" + +#: ../../po/../src/ui/widget/selected-style.cpp:131 +#, fuzzy +msgid "Flat color fill" +msgstr "Cor sólida" + +#: ../../po/../src/ui/widget/selected-style.cpp:131 +#, fuzzy +msgid "Flat color stroke" +msgstr "Cor sólida" + +#. TRANSLATOR COMMENT: A means "Averaged" +#: ../../po/../src/ui/widget/selected-style.cpp:134 +#, fuzzy +msgid "A" +msgstr "A4" + +#: ../../po/../src/ui/widget/selected-style.cpp:137 +#, fuzzy +msgid "Fill is averaged over selected objects" +msgstr "Editar posicionamento dos objectos seleccionados" + +#: ../../po/../src/ui/widget/selected-style.cpp:137 +#, fuzzy +msgid "Stroke is averaged over selected objects" +msgstr "Editar rasuramento dos objectos seleccionados" + +#. TRANSLATOR COMMENT: M means "Multiple" +#: ../../po/../src/ui/widget/selected-style.cpp:140 +msgid "M" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:143 +#, fuzzy +msgid "Multiple selected objects have the same fill" +msgstr "Inverter verticalmente os objectos seleccionados" + +#: ../../po/../src/ui/widget/selected-style.cpp:143 +#, fuzzy +msgid "Multiple selected objects have the same stroke" +msgstr "Inverter verticalmente os objectos seleccionados" + +#: ../../po/../src/ui/widget/selected-style.cpp:145 +#, fuzzy +msgid "Edit fill..." +msgstr "Editar..." + +#: ../../po/../src/ui/widget/selected-style.cpp:145 +#, fuzzy +msgid "Edit stroke..." +msgstr "Editar..." + +#: ../../po/../src/ui/widget/selected-style.cpp:149 +#, fuzzy +msgid "Last set color" +msgstr "Cor sólida" + +#: ../../po/../src/ui/widget/selected-style.cpp:153 +#, fuzzy +msgid "Last selected color" +msgstr "Último seleccionado" + +#: ../../po/../src/ui/widget/selected-style.cpp:157 +msgid "White" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:161 +#: ../../po/../src/widgets/sp-color-scales.cpp:461 +#: ../../po/../src/widgets/sp-color-scales.cpp:462 +#, fuzzy +msgid "Black" +msgstr "Preto:" + +#: ../../po/../src/ui/widget/selected-style.cpp:165 +#, fuzzy +msgid "Copy color" +msgstr "Cor inicial" + +#: ../../po/../src/ui/widget/selected-style.cpp:169 +#, fuzzy +msgid "Paste color" +msgstr "Cor sólida" + +#: ../../po/../src/ui/widget/selected-style.cpp:173 +#, fuzzy +msgid "Swap fill and stroke" +msgstr "Enchimento e Pincel" + +#: ../../po/../src/ui/widget/selected-style.cpp:177 +msgid "Make fill opaque" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:177 +msgid "Make stroke opaque" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:186 +#, fuzzy +msgid "Remove fill" +msgstr "Remover ligação" + +#: ../../po/../src/ui/widget/selected-style.cpp:186 +#, fuzzy +msgid "Remove stroke" +msgstr "Remover ligação" + +#: ../../po/../src/ui/widget/selected-style.cpp:718 +#, fuzzy +msgid "Master opacity" +msgstr "Opacidade:" + +#: ../../po/../src/ui/widget/selected-style.cpp:744 +msgid "0 (transparent)" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:768 +msgid "1.0 (opaque)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1046 +msgid "Moved to next layer." +msgstr "" + +#: ../../po/../src/verbs.cpp:1048 +msgid "Cannot move past last layer." +msgstr "" + +#: ../../po/../src/verbs.cpp:1057 +msgid "Moved to previous layer." +msgstr "" + +#: ../../po/../src/verbs.cpp:1059 +msgid "Cannot move past first layer." +msgstr "" + +#: ../../po/../src/verbs.cpp:1076 ../../po/../src/verbs.cpp:1150 +#, fuzzy +msgid "No current layer." +msgstr "Nome Documento:" + +#: ../../po/../src/verbs.cpp:1105 +#, fuzzy, c-format +msgid "Raised layer %s." +msgstr "Elevar nó" + +#: ../../po/../src/verbs.cpp:1109 +#, fuzzy, c-format +msgid "Lowered layer %s." +msgstr "Seleccionar" + +#: ../../po/../src/verbs.cpp:1118 +msgid "Cannot move layer any further." +msgstr "" + +#. TRANSLATORS: this means "The layer has been deleted." +#: ../../po/../src/verbs.cpp:1148 +#, fuzzy +msgid "Deleted layer." +msgstr "Seleccionar" + +#: ../../po/../src/verbs.cpp:1544 +msgid "" +"You need to connect to a Jabber server before sharing a document with " +"another user." +msgstr "" + +#: ../../po/../src/verbs.cpp:1559 +msgid "" +"You need to connect to a Jabber server before sharing a document with a " +"chatroom." +msgstr "" + +#: ../../po/../src/verbs.cpp:1569 +msgid "XML node tracker has not been initialized; nothing to dump" +msgstr "" + +#. TRANSLATORS: If you have translated the keys.svg file to your language, then +#. translate this string as "keys.LANG.svg" (where LANG is your language code); +#. otherwise leave as "keys.svg". +#: ../../po/../src/verbs.cpp:1631 +msgid "keys.svg" +msgstr "" + +#. TRANSLATORS: If you have translated the tutorial-basic.svg file to your language, +#. then translate this string as "tutorial-basic.LANG.svg" (where LANG is your language +#. code); otherwise leave as "tutorial-basic.svg". +#: ../../po/../src/verbs.cpp:1667 +msgid "tutorial-basic.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1671 +msgid "tutorial-shapes.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1675 +msgid "tutorial-advanced.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1679 +msgid "tutorial-tracing.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1683 +msgid "tutorial-calligraphy.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1687 +msgid "tutorial-elements.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1691 +msgid "tutorial-tips.svg" +msgstr "" + +#: ../../po/../src/verbs.cpp:1842 +msgid "Does nothing" +msgstr "Não fazer nada" + +#. File +#: ../../po/../src/verbs.cpp:1845 +#, fuzzy +msgid "Default" +msgstr "Por Omissão" + +#: ../../po/../src/verbs.cpp:1845 +#, fuzzy +msgid "Create new document from default template" +msgstr "Criar um novo documento SVG" + +#: ../../po/../src/verbs.cpp:1847 +#, fuzzy +msgid "_Open..." +msgstr "Abrir..." + +#: ../../po/../src/verbs.cpp:1848 +#, fuzzy +msgid "Open existing document" +msgstr "Abrir documento SVG existente" + +#: ../../po/../src/verbs.cpp:1849 +#, fuzzy +msgid "Re_vert" +msgstr "Repor" + +#: ../../po/../src/verbs.cpp:1850 +msgid "Revert to the last saved version of document (changes will be lost)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1851 +#, fuzzy +msgid "_Save" +msgstr "Gravar" + +#: ../../po/../src/verbs.cpp:1851 +msgid "Save document" +msgstr "Gravar documento" + +#: ../../po/../src/verbs.cpp:1853 +#, fuzzy +msgid "Save _As..." +msgstr "Gravar Como..." + +#: ../../po/../src/verbs.cpp:1854 +msgid "Save document under new name" +msgstr "Gravar documento com novo nome" + +#: ../../po/../src/verbs.cpp:1855 +#, fuzzy +msgid "_Print..." +msgstr "Imprimir..." + +#: ../../po/../src/verbs.cpp:1855 +msgid "Print document" +msgstr "Imprimir documento" + +#. TRANSLATORS: "Vacuum Defs" means "Clean up defs" (so as to remove unused definitions) +#: ../../po/../src/verbs.cpp:1858 +msgid "Vac_uum Defs" +msgstr "" + +#: ../../po/../src/verbs.cpp:1858 +msgid "Remove unused predefined items from the <defs> of the document" +msgstr "" + +#: ../../po/../src/verbs.cpp:1860 +#, fuzzy +msgid "Print _Direct" +msgstr "Imprimir Directo..." + +#: ../../po/../src/verbs.cpp:1861 +#, fuzzy +msgid "Print directly without prompting to a file or pipe" +msgstr "Imprimir directamente para ficheiro ou canal" + +#: ../../po/../src/verbs.cpp:1862 +#, fuzzy +msgid "Print Previe_w" +msgstr "Antever Impressão" + +#: ../../po/../src/verbs.cpp:1863 +msgid "Preview document printout" +msgstr "Antever a impressão do documento" + +#: ../../po/../src/verbs.cpp:1864 +#, fuzzy +msgid "_Import..." +msgstr "Importar" + +#: ../../po/../src/verbs.cpp:1865 +msgid "Import bitmap or SVG image into document" +msgstr "Importar para o documento imagem SVG ou bitmap" + +#: ../../po/../src/verbs.cpp:1866 +#, fuzzy +msgid "_Export Bitmap..." +msgstr "Exportar imagem" + +#: ../../po/../src/verbs.cpp:1867 +#, fuzzy +msgid "Export document or selection as a bitmap image" +msgstr "Exportar documento como bitmap PNG" + +#: ../../po/../src/verbs.cpp:1868 +#, fuzzy +msgid "N_ext Window" +msgstr "Fechar janela" + +#: ../../po/../src/verbs.cpp:1869 +msgid "Switch to the next document window" +msgstr "" + +#: ../../po/../src/verbs.cpp:1870 +#, fuzzy +msgid "P_revious Window" +msgstr "Fechar janela" + +#: ../../po/../src/verbs.cpp:1871 +msgid "Switch to the previous document window" +msgstr "" + +#: ../../po/../src/verbs.cpp:1872 +#, fuzzy +msgid "_Close" +msgstr "Fechar" + +#: ../../po/../src/verbs.cpp:1873 +#, fuzzy +msgid "Close window" +msgstr "Fechar Vista" + +#: ../../po/../src/verbs.cpp:1874 +#, fuzzy +msgid "_Quit" +msgstr "_Sair" + +#: ../../po/../src/verbs.cpp:1874 +#, fuzzy +msgid "Quit Inkscape" +msgstr "Apresentação Sodipodi" + +#. Edit +#: ../../po/../src/verbs.cpp:1877 +#, fuzzy +msgid "_Undo" +msgstr "Desfazer" + +#: ../../po/../src/verbs.cpp:1877 +#, fuzzy +msgid "Undo last action" +msgstr "Reverter última acção" + +#: ../../po/../src/verbs.cpp:1879 +#, fuzzy +msgid "_Redo" +msgstr "Refazer" + +#: ../../po/../src/verbs.cpp:1880 +#, fuzzy +msgid "Do again last undone action" +msgstr "Refazer acção desfeita" + +#: ../../po/../src/verbs.cpp:1881 +#, fuzzy +msgid "Cu_t" +msgstr "Cortar" + +#: ../../po/../src/verbs.cpp:1882 +#, fuzzy +msgid "Cut selection to clipboard" +msgstr "Cortar os objectos seleccionados para área de transferência" + +#: ../../po/../src/verbs.cpp:1883 +#, fuzzy +msgid "_Copy" +msgstr "Copiar" + +#: ../../po/../src/verbs.cpp:1884 +#, fuzzy +msgid "Copy selection to clipboard" +msgstr "Copiar objectos seleccionados para área de transferência" + +#: ../../po/../src/verbs.cpp:1885 +#, fuzzy +msgid "_Paste" +msgstr "Colar" + +#: ../../po/../src/verbs.cpp:1886 +#, fuzzy +msgid "Paste objects from clipboard to mouse point" +msgstr "Colar objectos da área de transferência" + +#: ../../po/../src/verbs.cpp:1887 +#, fuzzy +msgid "Paste _Style" +msgstr "Estilo pincelada" + +#: ../../po/../src/verbs.cpp:1888 +#, fuzzy +msgid "Apply style of the copied object to selection" +msgstr "Copiar objectos seleccionados para área de transferência" + +#: ../../po/../src/verbs.cpp:1889 +#, fuzzy +msgid "Paste _In Place" +msgstr "Estilo pincelada" + +#: ../../po/../src/verbs.cpp:1890 +#, fuzzy +msgid "Paste objects from clipboard to the original location" +msgstr "Alinhar objectos centrados na horizontal" + +#: ../../po/../src/verbs.cpp:1891 +#, fuzzy +msgid "_Delete" +msgstr "Apagar" + +#: ../../po/../src/verbs.cpp:1892 +#, fuzzy +msgid "Delete selection" +msgstr "Duplicar selecção" + +#: ../../po/../src/verbs.cpp:1893 +#, fuzzy +msgid "Duplic_ate" +msgstr "Duplicar" + +#: ../../po/../src/verbs.cpp:1894 +#, fuzzy +msgid "Duplicate selected objects" +msgstr "Duplicar objectos seleccionados" + +#: ../../po/../src/verbs.cpp:1895 +#, fuzzy +msgid "Clo_ne" +msgstr "Fechar" + +#: ../../po/../src/verbs.cpp:1896 +msgid "Create a clone of selected object (a copy linked to the original)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1897 +msgid "Unlin_k Clone" +msgstr "" + +#: ../../po/../src/verbs.cpp:1898 +msgid "Cut the clone's link to its original" +msgstr "" + +#: ../../po/../src/verbs.cpp:1899 +#, fuzzy +msgid "Select _Original" +msgstr "Seleccionar Tudo" + +#: ../../po/../src/verbs.cpp:1900 +#, fuzzy +msgid "Select the object to which the clone is linked" +msgstr "Cortar os objectos seleccionados para área de transferência" + +#. TRANSLATORS: Convert selection to a rectangle with tiled pattern fill +#: ../../po/../src/verbs.cpp:1902 +#, fuzzy +msgid "O_bjects to Pattern" +msgstr "Transformação objecto" + +#: ../../po/../src/verbs.cpp:1903 +msgid "Convert selection to a rectangle with tiled pattern fill" +msgstr "" + +#. TRANSLATORS: Extract objects from a tiled pattern fill +#: ../../po/../src/verbs.cpp:1905 +#, fuzzy +msgid "Pattern to Ob_jects" +msgstr "Alisar objecto" + +#: ../../po/../src/verbs.cpp:1906 +msgid "Extract objects from a tiled pattern fill" +msgstr "" + +#: ../../po/../src/verbs.cpp:1907 +#, fuzzy +msgid "Clea_r All" +msgstr "Limpar Tudo" + +#: ../../po/../src/verbs.cpp:1908 +msgid "Delete all objects from document" +msgstr "Apagar todos os objectos do documento" + +#: ../../po/../src/verbs.cpp:1909 +#, fuzzy +msgid "Select Al_l" +msgstr "Seleccionar Tudo" + +#: ../../po/../src/verbs.cpp:1910 +#, fuzzy +msgid "Select all objects or all nodes" +msgstr "Seleccionar todos os objectos no documento" + +#: ../../po/../src/verbs.cpp:1911 +#, fuzzy +msgid "Select All in All La_yers" +msgstr "Seleccionar" + +#: ../../po/../src/verbs.cpp:1912 +#, fuzzy +msgid "Select all objects in all visible and unlocked layers" +msgstr "Seleccionar todos os objectos no documento" + +#: ../../po/../src/verbs.cpp:1913 +#, fuzzy +msgid "In_vert Selection" +msgstr "Selecção" + +#: ../../po/../src/verbs.cpp:1914 +msgid "Invert selection (unselect what is selected and select everything else)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1915 +msgid "Invert in All Layers" +msgstr "" + +#: ../../po/../src/verbs.cpp:1916 +msgid "Invert selection in all visible and unlocked layers" +msgstr "" + +#: ../../po/../src/verbs.cpp:1917 +#, fuzzy +msgid "D_eselect" +msgstr "Seleccionar" + +#: ../../po/../src/verbs.cpp:1918 +#, fuzzy +msgid "Deselect any selected objects or nodes" +msgstr "Apagar objectos seleccionados" + +#. Selection +#: ../../po/../src/verbs.cpp:1921 +#, fuzzy +msgid "Raise to _Top" +msgstr "Trazer selecção para o topo" + +#: ../../po/../src/verbs.cpp:1922 +msgid "Raise selection to top" +msgstr "Trazer selecção para o topo" + +#: ../../po/../src/verbs.cpp:1923 +#, fuzzy +msgid "Lower to _Bottom" +msgstr "enviar selecção para o fundo" + +#: ../../po/../src/verbs.cpp:1924 +#, fuzzy +msgid "Lower selection to bottom" +msgstr "enviar selecção para o fundo" + +#: ../../po/../src/verbs.cpp:1925 +#, fuzzy +msgid "_Raise" +msgstr "Elevar" + +#: ../../po/../src/verbs.cpp:1926 +#, fuzzy +msgid "Raise selection one step" +msgstr "Trazer selecção para o topo" + +#: ../../po/../src/verbs.cpp:1927 +#, fuzzy +msgid "_Lower" +msgstr "Baixar" + +#: ../../po/../src/verbs.cpp:1928 +#, fuzzy +msgid "Lower selection one step" +msgstr "Baixar selecção por uma camada" + +#: ../../po/../src/verbs.cpp:1929 +msgid "_Group" +msgstr "_Agrupar" + +#: ../../po/../src/verbs.cpp:1930 +msgid "Group selected objects" +msgstr "Agrupar objectos seleccionados" + +#: ../../po/../src/verbs.cpp:1932 +#, fuzzy +msgid "Ungroup selected groups" +msgstr "Desagrupar objectos seleccionados" + +#: ../../po/../src/verbs.cpp:1934 +#, fuzzy +msgid "_Put on Path" +msgstr "Converter objecto seleccionado em caminho" + +#: ../../po/../src/verbs.cpp:1935 +#, fuzzy +msgid "Put text on path" +msgstr "Converter objecto seleccionado em caminho" + +#: ../../po/../src/verbs.cpp:1936 +#, fuzzy +msgid "_Remove from Path" +msgstr "Remover transformação" + +#: ../../po/../src/verbs.cpp:1937 +#, fuzzy +msgid "Remove text from path" +msgstr "Converter objecto seleccionado em caminho" + +#: ../../po/../src/verbs.cpp:1938 +msgid "Remove Manual _Kerns" +msgstr "" + +#. TRANSLATORS: "glyph": An image used in the visual representation of characters; +#. roughly speaking, how a character looks. A font is a set of glyphs. +#: ../../po/../src/verbs.cpp:1941 +#, fuzzy +msgid "Remove all manual kerns and glyph rotations from a text object" +msgstr "Remover transformações do objecto" + +#: ../../po/../src/verbs.cpp:1943 +#, fuzzy +msgid "_Union" +msgstr "nenhum" + +#: ../../po/../src/verbs.cpp:1944 +#, fuzzy +msgid "Union of selected objects" +msgstr "Desagrupar os objectos seleccionados" + +#: ../../po/../src/verbs.cpp:1945 +#, fuzzy +msgid "_Intersection" +msgstr "_Interactivo" + +#: ../../po/../src/verbs.cpp:1946 +#, fuzzy +msgid "Intersection of selected objects" +msgstr "Apagar objectos seleccionados" + +#: ../../po/../src/verbs.cpp:1947 +#, fuzzy +msgid "_Difference" +msgstr "Grau" + +#: ../../po/../src/verbs.cpp:1948 +#, fuzzy +msgid "Difference of selected objects (bottom minus top)" +msgstr "Apagar objectos seleccionados" + +#: ../../po/../src/verbs.cpp:1949 +#, fuzzy +msgid "E_xclusion" +msgstr "Expansão" + +#: ../../po/../src/verbs.cpp:1950 +#, fuzzy +msgid "Exclusive OR of selected objects" +msgstr "Editar posicionamento dos objectos seleccionados" + +#: ../../po/../src/verbs.cpp:1951 +#, fuzzy +msgid "Di_vision" +msgstr "Dimensões" + +#: ../../po/../src/verbs.cpp:1952 +msgid "Cut the bottom object into pieces" +msgstr "" + +#. TRANSLATORS: "to cut a path" is not the same as "to break a path apart" - see the +#. Advanced tutorial for more info +#: ../../po/../src/verbs.cpp:1955 +#, fuzzy +msgid "Cut _Path" +msgstr "Combinar os caminhos seleccionados" + +#: ../../po/../src/verbs.cpp:1956 +msgid "Cut the bottom object's stroke into pieces, removing fill" +msgstr "" + +#. TRANSLATORS: "outset": expand a shape by offsetting the object's path, +#. i.e. by displacing it perpendicular to the path in each point. +#. See also the Advanced Tutorial for explanation. +#: ../../po/../src/verbs.cpp:1960 +#, fuzzy +msgid "Outs_et" +msgstr "Combinar os caminhos seleccionados" + +#: ../../po/../src/verbs.cpp:1961 +#, fuzzy +msgid "Outset selected paths" +msgstr "Combinar os caminhos seleccionados" + +#: ../../po/../src/verbs.cpp:1963 +#, fuzzy +msgid "O_utset Path by 1 px" +msgstr "Combinar os caminhos seleccionados" + +#: ../../po/../src/verbs.cpp:1964 +#, fuzzy +msgid "Outset selected paths by 1 px" +msgstr "Combinar os caminhos seleccionados" + +#: ../../po/../src/verbs.cpp:1966 +#, fuzzy +msgid "O_utset Path by 10 px" +msgstr "Combinar os caminhos seleccionados" + +#: ../../po/../src/verbs.cpp:1967 +#, fuzzy +msgid "Outset selected paths by 10 px" +msgstr "Combinar os caminhos seleccionados" + +#. TRANSLATORS: "inset": contract a shape by offsetting the object's path, +#. i.e. by displacing it perpendicular to the path in each point. +#. See also the Advanced Tutorial for explanation. +#: ../../po/../src/verbs.cpp:1971 +msgid "I_nset" +msgstr "" + +#: ../../po/../src/verbs.cpp:1972 +#, fuzzy +msgid "Inset selected paths" +msgstr "Combinar os caminhos seleccionados" + +#: ../../po/../src/verbs.cpp:1974 +#, fuzzy +msgid "I_nset Path by 1 px" +msgstr "Combinar os caminhos seleccionados" + +#: ../../po/../src/verbs.cpp:1975 +#, fuzzy +msgid "Inset selected paths by 1 px" +msgstr "Combinar os caminhos seleccionados" + +#: ../../po/../src/verbs.cpp:1977 +#, fuzzy +msgid "I_nset Path by 10 px" +msgstr "Combinar os caminhos seleccionados" + +#: ../../po/../src/verbs.cpp:1978 +#, fuzzy +msgid "Inset selected paths by 10 px" +msgstr "Combinar os caminhos seleccionados" + +#: ../../po/../src/verbs.cpp:1980 +#, fuzzy +msgid "D_ynamic Offset" +msgstr "Preenchimento dinâmico" + +#: ../../po/../src/verbs.cpp:1980 +#, fuzzy +msgid "Create a dynamic offset object" +msgstr "Criar e editar objectos de texto" + +#: ../../po/../src/verbs.cpp:1982 +msgid "_Linked Offset" +msgstr "" + +#: ../../po/../src/verbs.cpp:1983 +msgid "Create a dynamic offset object linked to the original path" +msgstr "" + +#: ../../po/../src/verbs.cpp:1985 +#, fuzzy +msgid "_Stroke to Path" +msgstr "Tinta pincelada" + +#: ../../po/../src/verbs.cpp:1986 +#, fuzzy +msgid "Convert selected strokes to paths" +msgstr "Converter objecto seleccionado em caminho" + +#: ../../po/../src/verbs.cpp:1987 +#, fuzzy +msgid "Si_mplify" +msgstr "Combinar os caminhos seleccionados" + +#: ../../po/../src/verbs.cpp:1988 +#, fuzzy +msgid "Simplify selected paths by removing extra nodes" +msgstr "Combinar os caminhos seleccionados" + +#: ../../po/../src/verbs.cpp:1989 +#, fuzzy +msgid "_Reverse" +msgstr "Filtros" + +#: ../../po/../src/verbs.cpp:1990 +#, fuzzy +msgid "Reverses the direction of selected paths; useful for flipping markers" +msgstr "Apagar objectos seleccionados" + +#. TRANSLATORS: "to trace" means "to convert a bitmap to vector graphics" (to vectorize) +#: ../../po/../src/verbs.cpp:1992 +#, fuzzy +msgid "_Trace Bitmap" +msgstr "Imagem inválida" + +#: ../../po/../src/verbs.cpp:1993 +#, fuzzy +msgid "Convert bitmap object to paths" +msgstr "Converter objecto seleccionado em caminho" + +#: ../../po/../src/verbs.cpp:1994 +#, fuzzy +msgid "_Make a Bitmap Copy" +msgstr "Imagem inválida" + +#: ../../po/../src/verbs.cpp:1995 +#, fuzzy +msgid "Export selection to a bitmap and insert it into document" +msgstr "Importar para o documento imagem SVG ou bitmap" + +#: ../../po/../src/verbs.cpp:1996 +msgid "_Combine" +msgstr "_Combinar" + +#: ../../po/../src/verbs.cpp:1997 +msgid "Combine several paths into one" +msgstr "" + +#. TRANSLATORS: "to cut a path" is not the same as "to break a path apart" - see the +#. Advanced tutorial for more info +#: ../../po/../src/verbs.cpp:2000 +#, fuzzy +msgid "Break _Apart" +msgstr "Separar" + +#: ../../po/../src/verbs.cpp:2001 +#, fuzzy +msgid "Break selected paths into subpaths" +msgstr "Separar caminho seleccionado em subcaminhos" + +#: ../../po/../src/verbs.cpp:2002 +msgid "Gri_d Arrange..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2003 +msgid "Arrange selection in grid pattern" +msgstr "" + +#. Layer +#: ../../po/../src/verbs.cpp:2005 +#, fuzzy +msgid "_Add Layer..." +msgstr "Baixar" + +#: ../../po/../src/verbs.cpp:2006 +#, fuzzy +msgid "Create a new layer" +msgstr "Criar um novo documento SVG" + +#: ../../po/../src/verbs.cpp:2007 +#, fuzzy +msgid "Re_name Layer..." +msgstr "Elevar nó" + +#: ../../po/../src/verbs.cpp:2008 +#, fuzzy +msgid "Rename the current layer" +msgstr "Seleccionar" + +#: ../../po/../src/verbs.cpp:2009 +#, fuzzy +msgid "Switch to Layer Abov_e" +msgstr "Elevar selecção uma camada" + +#: ../../po/../src/verbs.cpp:2010 +msgid "Switch to the layer above the current" +msgstr "" + +#: ../../po/../src/verbs.cpp:2011 +#, fuzzy +msgid "Switch to Layer Belo_w" +msgstr "Elevar selecção uma camada" + +#: ../../po/../src/verbs.cpp:2012 +msgid "Switch to the layer below the current" +msgstr "" + +#: ../../po/../src/verbs.cpp:2013 +#, fuzzy +msgid "Move Selection to Layer Abo_ve" +msgstr "Elevar selecção uma camada" + +#: ../../po/../src/verbs.cpp:2014 +msgid "Move selection to the layer above the current" +msgstr "" + +#: ../../po/../src/verbs.cpp:2015 +#, fuzzy +msgid "Move Selection to Layer Bel_ow" +msgstr "Elevar selecção uma camada" + +#: ../../po/../src/verbs.cpp:2016 +msgid "Move selection to the layer below the current" +msgstr "" + +#: ../../po/../src/verbs.cpp:2017 +#, fuzzy +msgid "Layer to _Top" +msgstr "Trazer selecção para o topo" + +#: ../../po/../src/verbs.cpp:2018 +#, fuzzy +msgid "Raise the current layer to the top" +msgstr "Trazer selecção para o topo" + +#: ../../po/../src/verbs.cpp:2019 +#, fuzzy +msgid "Layer to _Bottom" +msgstr "enviar selecção para o fundo" + +#: ../../po/../src/verbs.cpp:2020 +#, fuzzy +msgid "Lower the current layer to the bottom" +msgstr "enviar selecção para o fundo" + +#: ../../po/../src/verbs.cpp:2021 +#, fuzzy +msgid "_Raise Layer" +msgstr "Elevar nó" + +#: ../../po/../src/verbs.cpp:2022 +msgid "Raise the current layer" +msgstr "" + +#: ../../po/../src/verbs.cpp:2023 +#, fuzzy +msgid "_Lower Layer" +msgstr "Descer nó" + +#: ../../po/../src/verbs.cpp:2024 +msgid "Lower the current layer" +msgstr "" + +#: ../../po/../src/verbs.cpp:2025 +#, fuzzy +msgid "_Delete Current Layer" +msgstr "Seleccionar" + +#: ../../po/../src/verbs.cpp:2026 +#, fuzzy +msgid "Delete the current layer" +msgstr "Seleccionar" + +#. Object +#: ../../po/../src/verbs.cpp:2029 +#, fuzzy +msgid "Rotate _90° CW" +msgstr "Rodar 90 graus" + +#: ../../po/../src/verbs.cpp:2030 +#, fuzzy +msgid "Rotate selection 90° clockwise" +msgstr "Rodar objecto 90 graus no sentido dos ponteiros" + +#: ../../po/../src/verbs.cpp:2031 +#, fuzzy +msgid "Rotate 9_0° CCW" +msgstr "Rodar 90 graus" + +#: ../../po/../src/verbs.cpp:2032 +#, fuzzy +msgid "Rotate selection 90° counter-clockwise" +msgstr "Rodar objecto 90 graus no sentido dos ponteiros" + +#: ../../po/../src/verbs.cpp:2033 +#, fuzzy +msgid "Remove _Transformations" +msgstr "Remover transformação" + +#: ../../po/../src/verbs.cpp:2034 +msgid "Remove transformations from object" +msgstr "Remover transformações do objecto" + +#: ../../po/../src/verbs.cpp:2035 +#, fuzzy +msgid "_Object to Path" +msgstr "Transformação objecto" + +#: ../../po/../src/verbs.cpp:2036 +#, fuzzy +msgid "Convert selected objects to paths" +msgstr "Converter objecto seleccionado em caminho" + +#: ../../po/../src/verbs.cpp:2037 +msgid "_Flow into Frame" +msgstr "" + +#: ../../po/../src/verbs.cpp:2038 +#, fuzzy +msgid "Put text into frames" +msgstr "Converter objecto seleccionado em caminho" + +#: ../../po/../src/verbs.cpp:2039 +#, fuzzy +msgid "_Unflow" +msgstr "Desfazer" + +#: ../../po/../src/verbs.cpp:2040 +msgid "Remove text from frame (creates a single-line text object)" +msgstr "" + +#: ../../po/../src/verbs.cpp:2041 +#, fuzzy +msgid "_Convert to Text" +msgstr "Converter objecto seleccionado em caminho" + +#: ../../po/../src/verbs.cpp:2042 +#, fuzzy +msgid "Convert flowed text to regular text objects (preserves appearance)" +msgstr "Converter os segmentos seleccionados para linhas" + +#: ../../po/../src/verbs.cpp:2044 +#, fuzzy +msgid "Flip _Horizontal" +msgstr "Inverter Horizontalmente" + +#: ../../po/../src/verbs.cpp:2044 +#, fuzzy +msgid "Flips selected objects horizontally" +msgstr "Inverter horizontalmente os objectos seleccionados" + +#: ../../po/../src/verbs.cpp:2047 +#, fuzzy +msgid "Flip _Vertical" +msgstr "Inverter Verticalmente" + +#: ../../po/../src/verbs.cpp:2047 +#, fuzzy +msgid "Flips selected objects vertically" +msgstr "Inverter verticalmente os objectos seleccionados" + +#. Tools +#: ../../po/../src/verbs.cpp:2051 +msgid "Select" +msgstr "Seleccionar" + +#: ../../po/../src/verbs.cpp:2052 +#, fuzzy +msgid "Select and transform objects" +msgstr "Seleccionar e tranformar objectos" + +#: ../../po/../src/verbs.cpp:2053 +#, fuzzy +msgid "Node Edit" +msgstr "Editar nó" + +#: ../../po/../src/verbs.cpp:2054 +#, fuzzy +msgid "Edit path nodes or control handles" +msgstr "Editar posicionamento dos objectos seleccionados" + +#: ../../po/../src/verbs.cpp:2056 +#, fuzzy +msgid "Create rectangles and squares" +msgstr "Criar rectângulos e quadrados com cantos arredondados opcionais" + +#: ../../po/../src/verbs.cpp:2058 +#, fuzzy +msgid "Create circles, ellipses, and arcs" +msgstr "Criar círculos, elipses e arcos" + +#: ../../po/../src/verbs.cpp:2060 +#, fuzzy +msgid "Create stars and polygons" +msgstr "Criar estrelas e polígonos" + +#: ../../po/../src/verbs.cpp:2062 +#, fuzzy +msgid "Create spirals" +msgstr "Criar espirais" + +#: ../../po/../src/verbs.cpp:2064 +#, fuzzy +msgid "Draw freehand lines" +msgstr "Desenhar linha em modo dinâmico" + +#: ../../po/../src/verbs.cpp:2066 +#, fuzzy +msgid "Draw Bezier curves and straight lines" +msgstr "Desenhar linhas em modo livre e rectas" + +#: ../../po/../src/verbs.cpp:2068 +#, fuzzy +msgid "Draw calligraphic lines" +msgstr "Desenhar linhas caligráficas" + +#: ../../po/../src/verbs.cpp:2070 +#, fuzzy +msgid "Create and edit text objects" +msgstr "Criar e editar objectos de texto" + +#: ../../po/../src/verbs.cpp:2072 +#, fuzzy +msgid "Create and edit gradients" +msgstr "Criar e editar objectos de texto" + +#: ../../po/../src/verbs.cpp:2074 +#, fuzzy +msgid "Zoom in or out" +msgstr "Diminuir zoom" + +#: ../../po/../src/verbs.cpp:2076 +#, fuzzy +msgid "Pick averaged colors from image" +msgstr "Obter cores médias da imagem" + +#: ../../po/../src/verbs.cpp:2078 +#, fuzzy +msgid "Create connectors" +msgstr "Criar um novo documento SVG" + +#. Tool prefs +#: ../../po/../src/verbs.cpp:2081 +msgid "Selector Preferences" +msgstr "" + +#: ../../po/../src/verbs.cpp:2082 +#, fuzzy +msgid "Open Preferences for the Selector tool" +msgstr "Apresentação Sodipodi" + +#: ../../po/../src/verbs.cpp:2083 +#, fuzzy +msgid "Node Tool Preferences" +msgstr "Preferências de ferramenta em falta" + +#: ../../po/../src/verbs.cpp:2084 +#, fuzzy +msgid "Open Preferences for the Node tool" +msgstr "Apresentação Sodipodi" + +#: ../../po/../src/verbs.cpp:2085 +#, fuzzy +msgid "Rectangle Preferences" +msgstr "Propriedades do Rectângulo" + +#: ../../po/../src/verbs.cpp:2086 +#, fuzzy +msgid "Open Preferences for the Rectangle tool" +msgstr "Apresentação Sodipodi" + +#: ../../po/../src/verbs.cpp:2087 +#, fuzzy +msgid "Ellipse Preferences" +msgstr "O item é referência" + +#: ../../po/../src/verbs.cpp:2088 +#, fuzzy +msgid "Open Preferences for the Ellipse tool" +msgstr "Apresentação Sodipodi" + +#: ../../po/../src/verbs.cpp:2089 +#, fuzzy +msgid "Star Preferences" +msgstr "Propriedades da Estrela" + +#: ../../po/../src/verbs.cpp:2090 +#, fuzzy +msgid "Open Preferences for the Star tool" +msgstr "Apresentação Sodipodi" + +#: ../../po/../src/verbs.cpp:2091 +#, fuzzy +msgid "Spiral Preferences" +msgstr "Propriedades da Espiral" + +#: ../../po/../src/verbs.cpp:2092 +#, fuzzy +msgid "Open Preferences for the Spiral tool" +msgstr "Apresentação Sodipodi" + +#: ../../po/../src/verbs.cpp:2093 +#, fuzzy +msgid "Pencil Preferences" +msgstr "O item é referência" + +#: ../../po/../src/verbs.cpp:2094 +#, fuzzy +msgid "Open Preferences for the Pencil tool" +msgstr "Apresentação Sodipodi" + +#: ../../po/../src/verbs.cpp:2095 +#, fuzzy +msgid "Pen Preferences" +msgstr "O item é referência" + +#: ../../po/../src/verbs.cpp:2096 +#, fuzzy +msgid "Open Preferences for the Pen tool" +msgstr "Apresentação Sodipodi" + +#: ../../po/../src/verbs.cpp:2097 +#, fuzzy +msgid "Calligraphic Preferences" +msgstr "Linha caligráfica" + +#: ../../po/../src/verbs.cpp:2098 +#, fuzzy +msgid "Open Preferences for the Calligraphy tool" +msgstr "Apresentação Sodipodi" + +#: ../../po/../src/verbs.cpp:2099 +#, fuzzy +msgid "Text Preferences" +msgstr "O item é referência" + +#: ../../po/../src/verbs.cpp:2100 +#, fuzzy +msgid "Open Preferences for the Text tool" +msgstr "Apresentação Sodipodi" + +#: ../../po/../src/verbs.cpp:2101 +#, fuzzy +msgid "Gradient Preferences" +msgstr "O item é referência" + +#: ../../po/../src/verbs.cpp:2102 +#, fuzzy +msgid "Open Preferences for the Gradient tool" +msgstr "Apresentação Sodipodi" + +#: ../../po/../src/verbs.cpp:2103 +#, fuzzy +msgid "Zoom Preferences" +msgstr "O item é referência" + +#: ../../po/../src/verbs.cpp:2104 +#, fuzzy +msgid "Open Preferences for the Zoom tool" +msgstr "Apresentação Sodipodi" + +#: ../../po/../src/verbs.cpp:2105 +#, fuzzy +msgid "Dropper Preferences" +msgstr "Apresentação Sodipodi" + +#: ../../po/../src/verbs.cpp:2106 +#, fuzzy +msgid "Open Preferences for the Dropper tool" +msgstr "Apresentação Sodipodi" + +#: ../../po/../src/verbs.cpp:2107 +#, fuzzy +msgid "Connector Preferences" +msgstr "Propriedades da Estrela" + +#: ../../po/../src/verbs.cpp:2108 +#, fuzzy +msgid "Open Preferences for the Connector tool" +msgstr "Apresentação Sodipodi" + +#. Zoom/View +#: ../../po/../src/verbs.cpp:2111 +#, fuzzy +msgid "Zoom In" +msgstr "Aumentar zoom" + +#: ../../po/../src/verbs.cpp:2111 +msgid "Zoom in" +msgstr "Aumentar zoom" + +#: ../../po/../src/verbs.cpp:2112 +#, fuzzy +msgid "Zoom Out" +msgstr "Diminuir zoom" + +#: ../../po/../src/verbs.cpp:2112 +msgid "Zoom out" +msgstr "Diminuir zoom" + +#: ../../po/../src/verbs.cpp:2113 +#, fuzzy +msgid "_Rulers" +msgstr "Filtros" + +#: ../../po/../src/verbs.cpp:2113 +#, fuzzy +msgid "Show or hide the canvas rulers" +msgstr "Mostar guias" + +#: ../../po/../src/verbs.cpp:2114 +msgid "Scroll_bars" +msgstr "" + +#: ../../po/../src/verbs.cpp:2114 +#, fuzzy +msgid "Show or hide the canvas scrollbars" +msgstr "Mostar guias" + +#: ../../po/../src/verbs.cpp:2115 +#, fuzzy +msgid "_Grid" +msgstr "Grelha" + +#: ../../po/../src/verbs.cpp:2116 +#, fuzzy +msgid "G_uides" +msgstr "Guias" + +#: ../../po/../src/verbs.cpp:2117 +msgid "Nex_t Zoom" +msgstr "" + +#: ../../po/../src/verbs.cpp:2117 +msgid "Next zoom (from the history of zooms)" +msgstr "" + +#: ../../po/../src/verbs.cpp:2119 +msgid "Pre_vious Zoom" +msgstr "" + +#: ../../po/../src/verbs.cpp:2119 +msgid "Previous zoom (from the history of zooms)" +msgstr "" + +#: ../../po/../src/verbs.cpp:2121 +#, fuzzy +msgid "Zoom 1:_1" +msgstr "Zoom a 1:1" + +#: ../../po/../src/verbs.cpp:2121 +msgid "Zoom to 1:1" +msgstr "Zoom a 1:1" + +#: ../../po/../src/verbs.cpp:2123 +#, fuzzy +msgid "Zoom 1:_2" +msgstr "Zoom a 1:2" + +#: ../../po/../src/verbs.cpp:2123 +msgid "Zoom to 1:2" +msgstr "Zoom a 1:2" + +#: ../../po/../src/verbs.cpp:2125 +#, fuzzy +msgid "_Zoom 2:1" +msgstr "Zoom a 2:1" + +#: ../../po/../src/verbs.cpp:2125 +msgid "Zoom to 2:1" +msgstr "Zoom a 2:1" + +#: ../../po/../src/verbs.cpp:2128 +msgid "_Fullscreen" +msgstr "" + +#: ../../po/../src/verbs.cpp:2128 +msgid "Stretch this document window to full screen" +msgstr "" + +#: ../../po/../src/verbs.cpp:2131 +#, fuzzy +msgid "Duplic_ate Window" +msgstr "Duplicar nó" + +#: ../../po/../src/verbs.cpp:2131 +#, fuzzy +msgid "Open a new window with the same document" +msgstr "Abrir documento SVG existente" + +#: ../../po/../src/verbs.cpp:2133 +#, fuzzy +msgid "_New View Preview" +msgstr "Nova Antevisão" + +#: ../../po/../src/verbs.cpp:2134 +#, fuzzy +msgid "New View Preview" +msgstr "Nova Antevisão" + +#. "view_new_preview" +#: ../../po/../src/verbs.cpp:2136 +msgid "_Normal" +msgstr "" + +#: ../../po/../src/verbs.cpp:2137 +msgid "Switch to normal display mode" +msgstr "" + +#: ../../po/../src/verbs.cpp:2138 +#, fuzzy +msgid "_Outline" +msgstr "Mostar contorno" + +#: ../../po/../src/verbs.cpp:2139 +msgid "Switch to outline (wireframe) display mode" +msgstr "" + +#: ../../po/../src/verbs.cpp:2141 +#, fuzzy +msgid "Ico_n Preview" +msgstr "Nova Antevisão" + +#: ../../po/../src/verbs.cpp:2142 +msgid "Open a window to preview items at different icon resolutions" +msgstr "" + +#: ../../po/../src/verbs.cpp:2144 +#, fuzzy +msgid "Zoom to fit page in window" +msgstr "Dimensionar a página inteira à janela" + +#: ../../po/../src/verbs.cpp:2145 +#, fuzzy +msgid "Page _Width" +msgstr "Alterar largura da página" + +#: ../../po/../src/verbs.cpp:2146 +#, fuzzy +msgid "Zoom to fit page width in window" +msgstr "Dimensionar a página inteira à janela" + +#: ../../po/../src/verbs.cpp:2148 +#, fuzzy +msgid "Zoom to fit drawing in window" +msgstr "Dimensionar o desenho inteiro à janela" + +#: ../../po/../src/verbs.cpp:2150 +#, fuzzy +msgid "Zoom to fit selection in window" +msgstr "Dimensionar a selecção inteira à janela" + +#. Dialogs +#: ../../po/../src/verbs.cpp:2153 +#, fuzzy +msgid "In_kscape Preferences..." +msgstr "Apresentação Sodipodi" + +#: ../../po/../src/verbs.cpp:2154 +#, fuzzy +msgid "Global Inkscape preferences" +msgstr "Preferências globais de visualização" + +#: ../../po/../src/verbs.cpp:2155 +msgid "_Document Preferences..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2156 +#, fuzzy +msgid "Preferences saved with the document" +msgstr "Abrir documento SVG existente" + +#: ../../po/../src/verbs.cpp:2157 +#, fuzzy +msgid "_Fill and Stroke..." +msgstr "Enchimento e Pincel" + +#: ../../po/../src/verbs.cpp:2158 +#, fuzzy +msgid "Fill and Stroke dialog" +msgstr "Enchimento e Pincel" + +#. TRANSLATORS: "Swatches" means: color samples +#: ../../po/../src/verbs.cpp:2160 +#, fuzzy +msgid "S_watches..." +msgstr "Gravar Como..." + +#: ../../po/../src/verbs.cpp:2161 +msgid "View color swatches" +msgstr "" + +#: ../../po/../src/verbs.cpp:2162 +#, fuzzy +msgid "Transfor_m..." +msgstr "Transformação:" + +#: ../../po/../src/verbs.cpp:2163 +#, fuzzy +msgid "Transform dialog" +msgstr "Diálogo de transformação" + +#: ../../po/../src/verbs.cpp:2164 +#, fuzzy +msgid "_Align and Distribute..." +msgstr "Alinhar e Distribuir" + +#: ../../po/../src/verbs.cpp:2165 +#, fuzzy +msgid "Align and Distribute dialog" +msgstr "Alinhar e Distribuir" + +#: ../../po/../src/verbs.cpp:2166 +#, fuzzy +msgid "_Text and Font..." +msgstr "Texto e Fonte" + +#: ../../po/../src/verbs.cpp:2167 +#, fuzzy +msgid "Text and Font dialog" +msgstr "Texto e fontes" + +#: ../../po/../src/verbs.cpp:2168 +#, fuzzy +msgid "_XML Editor..." +msgstr "Editor XML" + +#: ../../po/../src/verbs.cpp:2169 +msgid "XML Editor" +msgstr "Editor XML" + +#: ../../po/../src/verbs.cpp:2170 +#, fuzzy +msgid "_Find..." +msgstr "Imprimir..." + +#: ../../po/../src/verbs.cpp:2171 +#, fuzzy +msgid "Find objects in document" +msgstr "Nenhum gradiente no documento" + +#: ../../po/../src/verbs.cpp:2172 +msgid "_Messages..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2173 +msgid "View debug messages" +msgstr "" + +#: ../../po/../src/verbs.cpp:2174 +#, fuzzy +msgid "S_cripts..." +msgstr "Imprimir..." + +#: ../../po/../src/verbs.cpp:2175 +#, fuzzy +msgid "Run scripts" +msgstr "Conexão arredondada" + +#: ../../po/../src/verbs.cpp:2176 +#, fuzzy +msgid "Show/Hide D_ialogs" +msgstr "Fechar diálogo" + +#: ../../po/../src/verbs.cpp:2177 +msgid "Show or hide all active dialogs" +msgstr "" + +#. TRANSLATORS: "Tile clones" means: "Create tiled clones" +#: ../../po/../src/verbs.cpp:2179 +msgid "Tile clones..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2180 +msgid "Create and arrange multiple clones of selection" +msgstr "" + +#: ../../po/../src/verbs.cpp:2181 +#, fuzzy +msgid "_Object Properties..." +msgstr "propriedades do objecto" + +#: ../../po/../src/verbs.cpp:2182 +#, fuzzy +msgid "Object Properties dialog" +msgstr "propriedades do objecto" + +#: ../../po/../src/verbs.cpp:2185 +msgid "_Connect to Jabber server..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2185 +msgid "Connect to a Jabber server" +msgstr "" + +#: ../../po/../src/verbs.cpp:2187 +#, fuzzy +msgid "Share with _user..." +msgstr "Gravar Como..." + +#: ../../po/../src/verbs.cpp:2187 +msgid "Establish a whiteboard session with another Jabber user" +msgstr "" + +#: ../../po/../src/verbs.cpp:2189 +msgid "Share with _chatroom..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2189 +msgid "" +"Join a chatroom to start a new whiteboard session or join one in progress" +msgstr "" + +#: ../../po/../src/verbs.cpp:2191 +msgid "_Dump XML node tracker" +msgstr "" + +#: ../../po/../src/verbs.cpp:2191 +msgid "Dump the contents of the XML tracker to the console" +msgstr "" + +#: ../../po/../src/verbs.cpp:2193 +msgid "_Open session file..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2193 +msgid "Open and browse through records of past whiteboard sessions" +msgstr "" + +#: ../../po/../src/verbs.cpp:2195 +msgid "Session file playback" +msgstr "" + +#: ../../po/../src/verbs.cpp:2197 +msgid "_Disconnect from session" +msgstr "" + +#: ../../po/../src/verbs.cpp:2199 +msgid "Disconnect from _server" +msgstr "" + +#: ../../po/../src/verbs.cpp:2201 +msgid "_Input Devices..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2202 +msgid "Configure extended input devices" +msgstr "" + +#. Help +#: ../../po/../src/verbs.cpp:2205 +msgid "_Keys and Mouse" +msgstr "" + +#: ../../po/../src/verbs.cpp:2206 +msgid "Key and mouse shortcuts reference" +msgstr "" + +#: ../../po/../src/verbs.cpp:2207 +#, fuzzy +msgid "About E_xtensions" +msgstr "Extensão" + +#: ../../po/../src/verbs.cpp:2208 +#, fuzzy +msgid "About Extensions..." +msgstr "Extensão" + +#: ../../po/../src/verbs.cpp:2209 +#, fuzzy +msgid "About _Memory" +msgstr "Sobre Módulos" + +#: ../../po/../src/verbs.cpp:2210 +#, fuzzy +msgid "About Memory..." +msgstr "_Acerca de ..." + +#: ../../po/../src/verbs.cpp:2211 +msgid "_About Inkscape" +msgstr "" + +#. "help_about" +#. new HelpVerb(SP_VERB_SHOW_LICENSE, "ShowLicense", N_("Modifying or Redistributing Inkscape"), +#. N_("Show license to modify and/or redistribute Inkscape: GNU GPL"), NULL), +#. Tutorials +#: ../../po/../src/verbs.cpp:2217 +#, fuzzy +msgid "Inkscape: _Basic" +msgstr "Apresentação Sodipodi" + +#: ../../po/../src/verbs.cpp:2218 +msgid "Getting started with Inkscape" +msgstr "" + +#. "tutorial_basic" +#: ../../po/../src/verbs.cpp:2219 +#, fuzzy +msgid "Inkscape: _Shapes" +msgstr "Apresentação Sodipodi" + +#: ../../po/../src/verbs.cpp:2220 +msgid "Using shape tools to create and edit shapes" +msgstr "" + +#: ../../po/../src/verbs.cpp:2221 +#, fuzzy +msgid "Inkscape: _Advanced" +msgstr "Apresentação Sodipodi" + +#: ../../po/../src/verbs.cpp:2222 +#, fuzzy +msgid "Advanced Inkscape topics" +msgstr "Apresentação Sodipodi" + +#. "tutorial_advanced" +#. TRANSLATORS: "to trace" means "to convert a bitmap to vector graphics" (to vectorize) +#: ../../po/../src/verbs.cpp:2224 +#, fuzzy +msgid "Inkscape: T_racing" +msgstr "Apresentação Sodipodi" + +#: ../../po/../src/verbs.cpp:2225 +#, fuzzy +msgid "Using bitmap tracing" +msgstr "Tamanho da imagem" + +#. "tutorial_tracing" +#: ../../po/../src/verbs.cpp:2226 +#, fuzzy +msgid "Inkscape: _Calligraphy" +msgstr "Apresentação Sodipodi" + +#: ../../po/../src/verbs.cpp:2227 +msgid "Using the Calligraphy pen tool" +msgstr "" + +#: ../../po/../src/verbs.cpp:2228 +msgid "_Elements of Design" +msgstr "" + +#: ../../po/../src/verbs.cpp:2229 +msgid "Principles of design in the tutorial form" +msgstr "" + +#. "tutorial_design" +#: ../../po/../src/verbs.cpp:2230 +msgid "_Tips and Tricks" +msgstr "" + +#: ../../po/../src/verbs.cpp:2231 +msgid "Miscellaneous tips and tricks" +msgstr "" + +#. "tutorial_tips" +#. Effect +#: ../../po/../src/verbs.cpp:2234 +msgid "Previous Effect" +msgstr "" + +#: ../../po/../src/verbs.cpp:2235 +msgid "Repeat the last effect with the same settings" +msgstr "" + +#. "tutorial_tips" +#: ../../po/../src/verbs.cpp:2236 +msgid "Previous Effect Settings..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2237 +msgid "Repeat the last effect with new settings" +msgstr "" + +#: ../../po/../src/widgets/dash-selector.cpp:106 +#, fuzzy +msgid "Dash pattern" +msgstr "Largura da rasura" + +#: ../../po/../src/widgets/dash-selector.cpp:121 +#, fuzzy +msgid "Pattern offset" +msgstr "Preencher com padrão" + +#: ../../po/../src/widgets/desktop-widget.cpp:240 +#, fuzzy +msgid "Zoom drawing if window size changes" +msgstr "Dimensionar o desenho inteiro à janela" + +#: ../../po/../src/widgets/desktop-widget.cpp:298 +msgid "Cursor coordinates" +msgstr "" + +#. display the initial welcome message in the statusbar +#: ../../po/../src/widgets/desktop-widget.cpp:324 +msgid "" +"Welcome to Inkscape! Use shape or freehand tools to create objects; " +"use selector (arrow) to move or transform them." +msgstr "" + +#: ../../po/../src/widgets/desktop-widget.cpp:372 +#, c-format +msgid "%s: %d - Inkscape" +msgstr "" + +#: ../../po/../src/widgets/desktop-widget.cpp:374 +#, c-format +msgid "%s - Inkscape" +msgstr "" + +#: ../../po/../src/widgets/desktop-widget.cpp:532 +#, c-format +msgid "" +"Save changes to document \"%s\" before " +"closing?\n" +"\n" +"If you close without saving, your changes will be discarded." +msgstr "" + +#: ../../po/../src/widgets/desktop-widget.cpp:548 +#: ../../po/../src/widgets/desktop-widget.cpp:612 +msgid "Close _without saving" +msgstr "" + +#: ../../po/../src/widgets/desktop-widget.cpp:595 +#, c-format +msgid "" +"The file \"%s\" was saved with a " +"format (%s) that may cause data loss!\n" +"\n" +"Do you want to save this file in another format?" +msgstr "" + +#. Family frame +#: ../../po/../src/widgets/font-selector.cpp:156 +msgid "Font family" +msgstr "Família de fonte" + +#. Style frame +#: ../../po/../src/widgets/font-selector.cpp:184 +msgid "Style" +msgstr "Estilo" + +#: ../../po/../src/widgets/font-selector.cpp:219 +msgid "Font size:" +msgstr "Tamanho fonte:" + +#. TRANSLATORS: Test string used in text and font dialog (when no +#. * text has been entered) to get a preview of the font. Choose +#. * some representative characters that users of your locale will be +#. * interested in. +#: ../../po/../src/widgets/font-selector.cpp:554 +msgid "AaBbCcIiPpQq12368.;/()" +msgstr "AaBbCcIiPpQq12368.;/()" + +#: ../../po/../src/widgets/gradient-selector.cpp:137 +#: ../../po/../src/widgets/gradient-toolbar.cpp:524 +#, fuzzy +msgid "Duplicate" +msgstr "Duplicar" + +#: ../../po/../src/widgets/gradient-selector.cpp:142 +#: ../../po/../src/widgets/gradient-toolbar.cpp:535 +msgid "Edit..." +msgstr "Editar..." + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/pservers.html#LinearGradientSpreadMethodAttribute +#: ../../po/../src/widgets/gradient-selector.cpp:159 +msgid "" +"Whether to fill with flat color beyond the ends of the gradient vector " +"(spreadMethod=\"pad\"), or repeat the gradient in the same direction " +"(spreadMethod=\"repeat\"), or repeat the gradient in alternating opposite " +"directions (spreadMethod=\"reflect\")" +msgstr "" + +#: ../../po/../src/widgets/gradient-selector.cpp:165 +#, fuzzy +msgid "none" +msgstr "Nenhum" + +#: ../../po/../src/widgets/gradient-selector.cpp:169 +#, fuzzy +msgid "reflected" +msgstr "Primeiro seleccionado" + +#: ../../po/../src/widgets/gradient-selector.cpp:173 +#, fuzzy +msgid "direct" +msgstr "Rectângulo" + +#: ../../po/../src/widgets/gradient-selector.cpp:181 +#, fuzzy +msgid "Repeat:" +msgstr "Repor" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:217 +msgid "No gradients" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:226 +#, fuzzy +msgid "Nothing selected" +msgstr "Último seleccionado" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:237 +#, fuzzy +msgid "No gradients in selection" +msgstr "Nenhum gradiente seleccionado" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:247 +msgid "Multiple gradients" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:525 +msgid "" +"If the gradient is used by more than one object, create a copy of it for the " +"selected object(s)" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:536 +#, fuzzy +msgid "Edit the stops of the gradient" +msgstr "Gradiente linear" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:593 +#: ../../po/../src/widgets/toolbox.cpp:1103 +#: ../../po/../src/widgets/toolbox.cpp:1192 +#: ../../po/../src/widgets/toolbox.cpp:1485 +#: ../../po/../src/widgets/toolbox.cpp:1534 +#: ../../po/../src/widgets/toolbox.cpp:1766 +#: ../../po/../src/widgets/toolbox.cpp:1801 +#: ../../po/../src/widgets/toolbox.cpp:2331 +#: ../../po/../src/widgets/toolbox.cpp:2370 +msgid "New:" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:606 +#, fuzzy +msgid "Create linear gradient" +msgstr "Gradiente linear" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:620 +msgid "Create radial (elliptic or circular) gradient" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:635 +#, fuzzy +msgid "on" +msgstr "Nenhum" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:648 +#, fuzzy +msgid "Create gradient in the fill" +msgstr "Vector do gradiente" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:662 +msgid "Create gradient in the stroke" +msgstr "" + +#. FIXME: implement averaging of all parameters for multiple selected stars +#. gtk_label_set_markup(GTK_LABEL(l), _("Average:")); +#. FIXME: implement averaging of all parameters for multiple selected +#. gtk_label_set_markup(GTK_LABEL(l), _("Average:")); +#: ../../po/../src/widgets/gradient-toolbar.cpp:676 +#: ../../po/../src/widgets/toolbox.cpp:1105 +#: ../../po/../src/widgets/toolbox.cpp:1124 +#: ../../po/../src/widgets/toolbox.cpp:1493 +#: ../../po/../src/widgets/toolbox.cpp:1518 +#: ../../po/../src/widgets/toolbox.cpp:1768 +#: ../../po/../src/widgets/toolbox.cpp:1787 +#: ../../po/../src/widgets/toolbox.cpp:2334 +#: ../../po/../src/widgets/toolbox.cpp:2354 +#, fuzzy +msgid "Change:" +msgstr "Alterar" + +#: ../../po/../src/widgets/gradient-vector.cpp:269 +msgid "No gradients in document" +msgstr "Nenhum gradiente no documento" + +#: ../../po/../src/widgets/gradient-vector.cpp:275 +msgid "No gradient selected" +msgstr "Nenhum gradiente seleccionado" + +#: ../../po/../src/widgets/gradient-vector.cpp:532 +#, fuzzy +msgid "No stops in gradient" +msgstr "Gradiente linear" + +#. TRANSLATORS: "Stop" means: a "phase" of a gradient +#: ../../po/../src/widgets/gradient-vector.cpp:794 +#, fuzzy +msgid "Add stop" +msgstr "ambiente" + +#: ../../po/../src/widgets/gradient-vector.cpp:797 +msgid "Add another control stop to gradient" +msgstr "" + +#: ../../po/../src/widgets/gradient-vector.cpp:799 +#, fuzzy +msgid "Delete stop" +msgstr "Apagar selecção" + +#: ../../po/../src/widgets/gradient-vector.cpp:802 +msgid "Delete current control stop from gradient" +msgstr "" + +#. Label +#: ../../po/../src/widgets/gradient-vector.cpp:813 +msgid "Offset:" +msgstr "" + +#. TRANSLATORS: "Stop" means: a "phase" of a gradient +#: ../../po/../src/widgets/gradient-vector.cpp:858 +#, fuzzy +msgid "Stop Color" +msgstr "Cor inicial" + +#: ../../po/../src/widgets/gradient-vector.cpp:887 +#, fuzzy +msgid "Gradient editor" +msgstr "Vector do gradiente" + +#: ../../po/../src/widgets/layer-selector.cpp:119 +#, fuzzy +msgid "Toggle current layer visibility" +msgstr "Nome Documento:" + +#: ../../po/../src/widgets/layer-selector.cpp:139 +#, fuzzy +msgid "Lock or unlock current layer" +msgstr "Nome Documento:" + +#: ../../po/../src/widgets/layer-selector.cpp:142 +#, fuzzy +msgid "Current layer" +msgstr "Nome Documento:" + +#: ../../po/../src/widgets/layer-selector.cpp:553 +msgid "(root)" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:182 +#: ../../po/../src/widgets/paint-selector.cpp:561 +msgid "No paint" +msgstr "Nenhuma pintura" + +#: ../../po/../src/widgets/paint-selector.cpp:184 +#: ../../po/../src/widgets/paint-selector.cpp:629 +#, fuzzy +msgid "Flat color" +msgstr "Cor sólida" + +#: ../../po/../src/widgets/paint-selector.cpp:186 +#: ../../po/../src/widgets/paint-selector.cpp:696 +msgid "Linear gradient" +msgstr "Gradiente linear" + +#: ../../po/../src/widgets/paint-selector.cpp:188 +#: ../../po/../src/widgets/paint-selector.cpp:699 +msgid "Radial gradient" +msgstr "Gradiente radial" + +#: ../../po/../src/widgets/paint-selector.cpp:192 +msgid "Unset paint (make it undefined so it can be inherited)" +msgstr "" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/painting.html#FillRuleProperty +#: ../../po/../src/widgets/paint-selector.cpp:204 +msgid "" +"Any path self-intersections or subpaths create holes in the fill (fill-rule: " +"evenodd)" +msgstr "" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/painting.html#FillRuleProperty +#: ../../po/../src/widgets/paint-selector.cpp:215 +msgid "" +"Fill is solid unless a subpath is counterdirectional (fill-rule: nonzero)" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:528 +msgid "No objects" +msgstr "Nenhum objecto" + +#: ../../po/../src/widgets/paint-selector.cpp:539 +msgid "Multiple styles" +msgstr "Estilos múltiplos" + +#: ../../po/../src/widgets/paint-selector.cpp:550 +msgid "Paint is undefined" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:757 +#, fuzzy +msgid "No patterns in document" +msgstr "Nenhum gradiente no documento" + +#: ../../po/../src/widgets/paint-selector.cpp:872 +msgid "" +"Use Edit > Object(s) to Pattern to create a new pattern from " +"selection." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:426 +msgid "Now stroke width is scaled when objects are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:428 +msgid "Now stroke width is not scaled when objects are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:436 +msgid "" +"Now rounded rectangle corners are scaled when rectangles are " +"scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:438 +msgid "" +"Now rounded rectangle corners are not scaled when rectangles " +"are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:446 +msgid "" +"Now gradients are transformed along with their objects when " +"those are transformed (moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:448 +msgid "" +"Now gradients remain fixed when objects are transformed " +"(moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:456 +msgid "" +"Now patterns are transformed along with their objects when " +"those are transformed (moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:458 +msgid "" +"Now patterns remain fixed when objects are transformed (moved, " +"scaled, rotated, or skewed)." +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:506 +#, fuzzy +msgid "select_toolbar|X" +msgstr "Seleccionar" + +#: ../../po/../src/widgets/select-toolbar.cpp:506 +#, fuzzy +msgid "Horizontal coordinate of selection" +msgstr "Valor horizontal do centro" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:511 +#, fuzzy +msgid "select_toolbar|Y" +msgstr "Seleccionar" + +#: ../../po/../src/widgets/select-toolbar.cpp:511 +msgid "Vertical coordinate of selection" +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:517 +#, fuzzy +msgid "select_toolbar|W" +msgstr "Seleccionar" + +#: ../../po/../src/widgets/select-toolbar.cpp:517 +#, fuzzy +msgid "Width of selection" +msgstr "Cortar selecção" + +#: ../../po/../src/widgets/select-toolbar.cpp:525 +msgid "Change both width and height by the same proportion" +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:534 +#, fuzzy +msgid "select_toolbar|H" +msgstr "Seleccionar" + +#: ../../po/../src/widgets/select-toolbar.cpp:534 +#, fuzzy +msgid "Height of selection" +msgstr "Zoom à selecção" + +#: ../../po/../src/widgets/sp-color-gtkselector.cpp:62 +msgid "System" +msgstr "" + +#: ../../po/../src/widgets/sp-color-notebook.cpp:322 +#, fuzzy +msgid "RGBA_:" +msgstr "RGB" + +#: ../../po/../src/widgets/sp-color-notebook.cpp:330 +msgid "Hexadecimal RGBA value of the color" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "RGB" +msgstr "RGB" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +#, fuzzy +msgid "HSL" +msgstr "HSV" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "CMYK" +msgstr "CMYK" + +#: ../../po/../src/widgets/sp-color-scales.cpp:397 +msgid "_R" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:398 +#: ../../po/../src/widgets/sp-color-scales.cpp:399 +#, fuzzy +msgid "Red" +msgstr "Vermelho:" + +#: ../../po/../src/widgets/sp-color-scales.cpp:400 +msgid "_G" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:401 +#: ../../po/../src/widgets/sp-color-scales.cpp:402 +#, fuzzy +msgid "Green" +msgstr "Verde:" + +#: ../../po/../src/widgets/sp-color-scales.cpp:403 +msgid "_B" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:404 +#: ../../po/../src/widgets/sp-color-scales.cpp:405 +#, fuzzy +msgid "Blue" +msgstr "Azul:" + +#. Label +#: ../../po/../src/widgets/sp-color-scales.cpp:406 +#: ../../po/../src/widgets/sp-color-scales.cpp:432 +#: ../../po/../src/widgets/sp-color-scales.cpp:463 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:141 +msgid "_A" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:407 +#: ../../po/../src/widgets/sp-color-scales.cpp:408 +#: ../../po/../src/widgets/sp-color-scales.cpp:433 +#: ../../po/../src/widgets/sp-color-scales.cpp:434 +#: ../../po/../src/widgets/sp-color-scales.cpp:464 +#: ../../po/../src/widgets/sp-color-scales.cpp:465 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:151 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:163 +msgid "Alpha (opacity)" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:423 +msgid "_H" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:424 +#: ../../po/../src/widgets/sp-color-scales.cpp:425 +#, fuzzy +msgid "Hue" +msgstr "Tonalidade:" + +#: ../../po/../src/widgets/sp-color-scales.cpp:426 +msgid "_S" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:427 +#: ../../po/../src/widgets/sp-color-scales.cpp:428 +#, fuzzy +msgid "Saturation" +msgstr "Saturação:" + +#: ../../po/../src/widgets/sp-color-scales.cpp:429 +msgid "_L" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:430 +#: ../../po/../src/widgets/sp-color-scales.cpp:431 +#, fuzzy +msgid "Lightness" +msgstr "Altura" + +#: ../../po/../src/widgets/sp-color-scales.cpp:451 +msgid "_C" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:452 +#: ../../po/../src/widgets/sp-color-scales.cpp:453 +#, fuzzy +msgid "Cyan" +msgstr "Ciano:" + +#: ../../po/../src/widgets/sp-color-scales.cpp:454 +msgid "_M" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:455 +#: ../../po/../src/widgets/sp-color-scales.cpp:456 +#, fuzzy +msgid "Magenta" +msgstr "Magenta:" + +#: ../../po/../src/widgets/sp-color-scales.cpp:457 +msgid "_Y" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:458 +#: ../../po/../src/widgets/sp-color-scales.cpp:459 +#, fuzzy +msgid "Yellow" +msgstr "Amarelo:" + +#: ../../po/../src/widgets/sp-color-scales.cpp:460 +msgid "_K" +msgstr "" + +#: ../../po/../src/widgets/sp-color-selector.cpp:71 +#, fuzzy +msgid "Unnamed" +msgstr "nome" + +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:68 +msgid "Wheel" +msgstr "" + +#: ../../po/../src/widgets/sp-xmlview-attr-list.cpp:53 +msgid "Attribute" +msgstr "Atributo" + +#: ../../po/../src/widgets/sp-xmlview-attr-list.cpp:54 +msgid "Value" +msgstr "Valor" + +#: ../../po/../src/widgets/toolbox.cpp:424 +msgid "Insert new nodes into selected segments" +msgstr "Inserir novos nós nos segmentos seleccionados" + +#: ../../po/../src/widgets/toolbox.cpp:426 +msgid "Delete selected nodes" +msgstr "Apagar nós seleccionados" + +#: ../../po/../src/widgets/toolbox.cpp:431 +#, fuzzy +msgid "Join paths at selected nodes" +msgstr "Juntar linhas nos nós seleccionados" + +#: ../../po/../src/widgets/toolbox.cpp:433 +#, fuzzy +msgid "Join paths at selected nodes with new segment" +msgstr "Juntar linhas nos nós seleccionados" + +#: ../../po/../src/widgets/toolbox.cpp:436 +msgid "Split path between two non-endpoint nodes" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:439 +#, fuzzy +msgid "Break path at selected nodes" +msgstr "Quebrar o nó seleccionado" + +#: ../../po/../src/widgets/toolbox.cpp:444 +msgid "Make selected nodes corner" +msgstr "Converter nós seleccionados num canto" + +#: ../../po/../src/widgets/toolbox.cpp:447 +msgid "Make selected nodes smooth" +msgstr "Suavizar os nós seleccionados" + +#: ../../po/../src/widgets/toolbox.cpp:450 +#, fuzzy +msgid "Make selected nodes symmetric" +msgstr "Suavizar os nós seleccionados" + +#: ../../po/../src/widgets/toolbox.cpp:455 +msgid "Make selected segments lines" +msgstr "Converter segmentos seleccionados em linhas" + +#: ../../po/../src/widgets/toolbox.cpp:458 +msgid "Make selected segments curves" +msgstr "Converter segmentos seleccionados em curvas" + +#: ../../po/../src/widgets/toolbox.cpp:1199 +msgid "Polygon" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1206 +msgid "Regular polygon (with one handle) instead of a star" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1218 +msgid "Corners:" +msgstr "Cantos:" + +#: ../../po/../src/widgets/toolbox.cpp:1218 +#, fuzzy +msgid "Number of corners of a polygon or star" +msgstr "Número de cantos:" + +#: ../../po/../src/widgets/toolbox.cpp:1228 +#, fuzzy +msgid "Spoke ratio:" +msgstr "Bloquear aspecto" + +#. TRANSLATORS: Tip radius of a star is the distance from the center to the farthest handle. +#. Base radius is the same for the closest handle. +#: ../../po/../src/widgets/toolbox.cpp:1231 +msgid "Base radius to tip radius ratio" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1246 +#, fuzzy +msgid "Rounded:" +msgstr "Terminação arredondada" + +#: ../../po/../src/widgets/toolbox.cpp:1246 +msgid "How much rounded are the corners (0 for sharp)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1256 +msgid "Randomized:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1256 +msgid "Scatter randomly the corners and angles" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1269 +#: ../../po/../src/widgets/toolbox.cpp:1838 +#: ../../po/../src/widgets/toolbox.cpp:2061 +msgid "Defaults" +msgstr "Por Omissão" + +#: ../../po/../src/widgets/toolbox.cpp:1270 +#: ../../po/../src/widgets/toolbox.cpp:1839 +#: ../../po/../src/widgets/toolbox.cpp:2062 +msgid "" +"Reset shape parameters to defaults (use Inkscape Preferences > Tools to " +"change defaults)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1544 +msgid "W:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1544 +#, fuzzy +msgid "Width of rectangle" +msgstr "Cortar selecção" + +#: ../../po/../src/widgets/toolbox.cpp:1556 +#, fuzzy +msgid "Height of rectangle" +msgstr "Zoom à selecção" + +#: ../../po/../src/widgets/toolbox.cpp:1568 +#, fuzzy +msgid "Rx:" +msgstr "x0:" + +#: ../../po/../src/widgets/toolbox.cpp:1568 +#, fuzzy +msgid "Horizontal radius of rounded corners" +msgstr "Valor horizontal do centro" + +#: ../../po/../src/widgets/toolbox.cpp:1578 +#, fuzzy +msgid "Ry:" +msgstr "y0:" + +#: ../../po/../src/widgets/toolbox.cpp:1578 +#, fuzzy +msgid "Vertical radius of rounded corners" +msgstr "Valor horizontal do centro" + +#: ../../po/../src/widgets/toolbox.cpp:1594 +msgid "Not rounded" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1596 +msgid "Make corners sharp" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1805 +#, fuzzy +msgid "Turns:" +msgstr "Transformação:" + +#: ../../po/../src/widgets/toolbox.cpp:1805 +#, fuzzy +msgid "Number of revolutions" +msgstr "Número de cantos:" + +#: ../../po/../src/widgets/toolbox.cpp:1815 +#, fuzzy +msgid "Divergence:" +msgstr "Grau" + +#: ../../po/../src/widgets/toolbox.cpp:1815 +msgid "How much denser/sparser are outer revolutions; 1 = uniform" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1825 +msgid "Inner radius:" +msgstr "Raio interior:" + +#: ../../po/../src/widgets/toolbox.cpp:1825 +msgid "Radius of the innermost revolution (relative to the spiral size)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1957 +msgid "The width of the calligraphic pen (relative to the visible canvas area)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1967 +#, fuzzy +msgid "Thinning:" +msgstr "Renderizar" + +#: ../../po/../src/widgets/toolbox.cpp:1967 +msgid "" +"How much velocity thins the stroke (> 0 makes fast strokes thinner, < 0 " +"makes them broader, 0 makes width independent of velocity)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1980 +msgid "Angle:" +msgstr "Ângulo:" + +#: ../../po/../src/widgets/toolbox.cpp:1980 +msgid "" +"The angle of the pen's nib (in degrees; 0 = horizontal; has no effect if " +"fixation = 0)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1990 +#, fuzzy +msgid "Fixation:" +msgstr "Orientação:" + +#: ../../po/../src/widgets/toolbox.cpp:1990 +msgid "" +"How fixed is the pen angle (0 = always perpendicular to stroke direction, 1 " +"= fixed)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2003 +msgid "Mass:" +msgstr "Massa:" + +#: ../../po/../src/widgets/toolbox.cpp:2003 +msgid "How much inertia affects the movement of the pen" +msgstr "" + +#. TRANSLATORS: "drag" means "resistance" here +#: ../../po/../src/widgets/toolbox.cpp:2014 +msgid "Drag:" +msgstr "Arrastar:" + +#: ../../po/../src/widgets/toolbox.cpp:2014 +msgid "How much resistance affects the movement of the pen" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2034 +msgid "Use the pressure of the input device to alter the width of the pen" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2047 +msgid "Use the tilt of the input device to alter the angle of the pen's nib" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2374 +#, fuzzy +msgid "Start:" +msgstr "Estrela" + +#: ../../po/../src/widgets/toolbox.cpp:2374 +msgid "The angle (in degrees) from the horizontal to the arc's start point" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2384 +msgid "End:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2384 +msgid "The angle (in degrees) from the horizontal to the arc's end point" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2395 +#, fuzzy +msgid "Open arc" +msgstr "Abrir" + +#: ../../po/../src/widgets/toolbox.cpp:2396 +msgid "" +"Switch between arc (unclosed shape) and segment (closed shape with two radii)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2415 +msgid "Make whole" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2417 +msgid "Make the shape a whole ellipse, not arc or segment" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2644 +msgid "" +"When pressed, picks visible color without alpha and when not pressed, picks " +"color including its alpha" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:3039 +#, fuzzy +msgid "Make connectors avoid selected objects" +msgstr "Apagar objectos seleccionados" + +#: ../../po/../src/widgets/toolbox.cpp:3043 +#, fuzzy +msgid "Make connectors ignore selected objects" +msgstr "Apagar objectos seleccionados" + +#. +#. 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 : +#: ../share/extensions/addnodes.inx.h:1 +#, fuzzy +msgid "Add Nodes" +msgstr "Nós" + +#: ../share/extensions/addnodes.inx.h:2 +msgid "Maximum Segment Length" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:1 +#, fuzzy +msgid "AI Input" +msgstr "Entrada" + +#: ../share/extensions/ai_input.inx.h:2 ../share/extensions/ai_output.inx.h:2 +msgid "Adobe Illustrator (*.ai)" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:3 +msgid "Open files saved with Adobe Illustrator" +msgstr "" + +#: ../share/extensions/ai_output.inx.h:1 +#, fuzzy +msgid "AI Output" +msgstr "Afastar" + +#: ../share/extensions/ai_output.inx.h:3 +#, fuzzy +msgid "Write Adobe Illustrator" +msgstr "Ilustrador de Vectores SVG" + +#: ../share/extensions/dia.inx.h:1 +msgid "A diagram created with the program Dia" +msgstr "" + +#: ../share/extensions/dia.inx.h:2 +msgid "Dia Diagram (*.dia)" +msgstr "" + +#: ../share/extensions/dia.inx.h:3 +#, fuzzy +msgid "Dia Input" +msgstr "Entrada" + +#: ../share/extensions/dia.inx.h:4 +msgid "" +"In order to import Dia files, Dia itself must be installed. You can get Dia " +"at http://www.gnome.org/projects/dia/" +msgstr "" + +#: ../share/extensions/dia.inx.h:5 +msgid "" +"The dia2svg.sh script should be installed with your Inkscape distribution. " +"If you do not have it, there is likely to be something wrong with your " +"Inkscape installation." +msgstr "" + +#: ../share/extensions/dots.inx.h:1 +#, fuzzy +msgid "Connect the Dots" +msgstr "Cantos:" + +#: ../share/extensions/dots.inx.h:2 +#, fuzzy +msgid "Dot Size" +msgstr "Lados:" + +#: ../share/extensions/dots.inx.h:3 +#, fuzzy +msgid "Font Size" +msgstr "Tamanho fonte:" + +#: ../share/extensions/dropshadow.inx.h:1 +msgid "Color of shadow" +msgstr "" + +#: ../share/extensions/dropshadow.inx.h:2 +msgid "Dropshadow" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:1 +#: ../share/extensions/dxf_output.inx.h:1 +msgid "AutoCAD DXF (*.dxf)" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:2 +#, fuzzy +msgid "DXF Input" +msgstr "Entrada" + +#: ../share/extensions/dxf_input.inx.h:3 +msgid "Import AutoCAD's Document Exchange Format" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:4 +msgid "" +"dxf2svg may come with Inkscape, but is also at http://dxf-svg-convert." +"sourceforge.net/" +msgstr "" + +#: ../share/extensions/dxf_output.inx.h:2 +#, fuzzy +msgid "DXF Output" +msgstr "Afastar" + +#: ../share/extensions/dxf_output.inx.h:3 +msgid "DXF file written by pstoedit" +msgstr "" + +#: ../share/extensions/dxf_output.inx.h:4 +msgid "pstoedit must be installed to run see http://www.pstoedit.net/pstoedit" +msgstr "" + +#: ../share/extensions/embedimage.inx.h:1 +#, fuzzy +msgid "Embed Images" +msgstr "Imagem" + +#: ../share/extensions/eps_input.inx.h:1 +#, fuzzy +msgid "EPS Input" +msgstr "Entrada" + +#: ../share/extensions/eps_input.inx.h:2 +msgid "Encapsulated Postscript" +msgstr "" + +#: ../share/extensions/eps_input.inx.h:3 +msgid "Encapsulated Postscript (*.eps)" +msgstr "" + +#: ../share/extensions/epsi_output.inx.h:1 +#, fuzzy +msgid "EPSI Output" +msgstr "Afastar" + +#: ../share/extensions/epsi_output.inx.h:2 +msgid "Encapsulated Postscript Interchange (*.epsi)" +msgstr "" + +#: ../share/extensions/epsi_output.inx.h:3 +msgid "Encapsulated Postscript with a thumbnail" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:1 ../share/extensions/ffms.inx.h:1 +#: ../share/extensions/ffset.inx.h:1 ../share/extensions/ffss.inx.h:1 +#, fuzzy +msgid "Bridge Width" +msgstr "Largura" + +#: ../share/extensions/ffmet.inx.h:2 ../share/extensions/ffms.inx.h:2 +msgid "First String Length" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:3 +msgid "FretFind Multi Length ET" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:4 ../share/extensions/ffms.inx.h:4 +#: ../share/extensions/ffset.inx.h:3 ../share/extensions/ffss.inx.h:3 +msgid "Fretboard Edges" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:5 ../share/extensions/ffms.inx.h:5 +msgid "Last String Length" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:6 ../share/extensions/ffms.inx.h:6 +#: ../share/extensions/ffset.inx.h:4 ../share/extensions/ffss.inx.h:4 +#, fuzzy +msgid "Number of Frets" +msgstr "Número de cantos:" + +#: ../share/extensions/ffmet.inx.h:7 ../share/extensions/ffms.inx.h:7 +#: ../share/extensions/ffset.inx.h:5 ../share/extensions/ffss.inx.h:5 +#, fuzzy +msgid "Number of Strings" +msgstr "Número de cantos:" + +#: ../share/extensions/ffmet.inx.h:8 ../share/extensions/ffms.inx.h:8 +#: ../share/extensions/ffset.inx.h:6 ../share/extensions/ffss.inx.h:6 +#, fuzzy +msgid "Nut Width" +msgstr "Largura:" + +#: ../share/extensions/ffmet.inx.h:9 ../share/extensions/ffms.inx.h:10 +msgid "Perpendicular Distance" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:10 ../share/extensions/ffset.inx.h:7 +msgid "Scale Base (2 for Octave)" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:11 ../share/extensions/ffset.inx.h:9 +msgid "Tones in Scale" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:12 ../share/extensions/ffms.inx.h:12 +#: ../share/extensions/ffset.inx.h:10 ../share/extensions/ffss.inx.h:10 +msgid "px per Unit" +msgstr "" + +#: ../share/extensions/ffms.inx.h:3 +msgid "FretFind Multi Length Scala" +msgstr "" + +#: ../share/extensions/ffms.inx.h:9 ../share/extensions/ffss.inx.h:7 +msgid "Path to Scala *.scl File" +msgstr "" + +#: ../share/extensions/ffms.inx.h:11 +msgid "Tuning (scale step for each string seperated by semicolons)" +msgstr "" + +#: ../share/extensions/ffset.inx.h:2 +msgid "FretFind Single Length ET" +msgstr "" + +#: ../share/extensions/ffset.inx.h:8 ../share/extensions/ffss.inx.h:8 +msgid "Scale Length" +msgstr "" + +#: ../share/extensions/ffss.inx.h:2 +msgid "FretFind Single Length Scala" +msgstr "" + +#: ../share/extensions/ffss.inx.h:9 +msgid "Tuning (Scale step for each string seperated by semicolons)" +msgstr "" + +#: ../share/extensions/handles.inx.h:1 +#, fuzzy +msgid "Draw Handles" +msgstr "Desenhar linha em modo dinâmico" + +#: ../share/extensions/interp.inx.h:1 +#, fuzzy +msgid "Duplicate Endpaths" +msgstr "Duplicar nó" + +#: ../share/extensions/interp.inx.h:2 +#, fuzzy +msgid "Exponent" +msgstr "Exportar" + +#: ../share/extensions/interp.inx.h:3 +msgid "Interpolate" +msgstr "" + +#: ../share/extensions/interp.inx.h:4 +msgid "Interpolate Style (Experimental)" +msgstr "" + +#: ../share/extensions/interp.inx.h:5 +msgid "Interpolation Method" +msgstr "" + +#: ../share/extensions/interp.inx.h:6 +msgid "Interpolation Steps" +msgstr "" + +#: ../share/extensions/kochify.inx.h:1 +msgid "Kochify" +msgstr "" + +#: ../share/extensions/kochify_load.inx.h:1 +msgid "Kochify (Load)" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:1 +msgid "Angle" +msgstr "Ângulo" + +#: ../share/extensions/lindenmayer.inx.h:2 +msgid "Axiom" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:3 +#, fuzzy +msgid "Lindenmayer" +msgstr "Elevar nó" + +#: ../share/extensions/lindenmayer.inx.h:4 +msgid "Order" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:5 +#, fuzzy +msgid "Rules" +msgstr "Filtros" + +#: ../share/extensions/lindenmayer.inx.h:6 +#, fuzzy +msgid "Step" +msgstr "Estilo" + +#: ../share/extensions/motion.inx.h:1 +#, fuzzy +msgid "Direction" +msgstr "Posição" + +#: ../share/extensions/motion.inx.h:2 +#, fuzzy +msgid "Magnitude" +msgstr "Magenta:" + +#: ../share/extensions/motion.inx.h:3 +#, fuzzy +msgid "Motion" +msgstr "Resolução:" + +#: ../share/extensions/pdf_output.inx.h:1 +msgid "Adobe PDF (*.pdf)" +msgstr "" + +#: ../share/extensions/pdf_output.inx.h:2 +msgid "Adobe Portable Document Format" +msgstr "" + +#: ../share/extensions/pdf_output.inx.h:3 +#, fuzzy +msgid "PDF Output" +msgstr "Afastar" + +#: ../share/extensions/ps_input.inx.h:1 +#, fuzzy +msgid "Postscript" +msgstr "Ponto" + +#: ../share/extensions/ps_input.inx.h:2 +msgid "Postscript (*.ps)" +msgstr "" + +#: ../share/extensions/ps_input.inx.h:3 +msgid "Postscript Input" +msgstr "" + +#: ../share/extensions/radiusrand.inx.h:1 +#, fuzzy +msgid "Radius" +msgstr "Raio:" + +#: ../share/extensions/radiusrand.inx.h:2 +#, fuzzy +msgid "Radius Randomize" +msgstr "Elevar nó" + +#: ../share/extensions/radiusrand.inx.h:3 +msgid "Randomize Control Points" +msgstr "" + +#: ../share/extensions/radiusrand.inx.h:4 +#, fuzzy +msgid "Randomize Nodes" +msgstr "Elevar nó" + +#: ../share/extensions/rtree.inx.h:1 +#, fuzzy +msgid "Initial Size" +msgstr "Tamanho da imagem" + +#: ../share/extensions/rtree.inx.h:2 +msgid "Minimum Size" +msgstr "" + +#: ../share/extensions/rtree.inx.h:3 +msgid "Random Tree" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:1 +msgid "A diagram created with the program Sketch" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:2 +msgid "Sketch Diagram (*.sk)" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:3 +msgid "Sketch Input" +msgstr "" + +#: ../share/extensions/straightseg.inx.h:1 +msgid "Behavior" +msgstr "" + +#: ../share/extensions/straightseg.inx.h:3 +msgid "Segment Straightener" +msgstr "" + +#: ../share/extensions/summersnight.inx.h:1 +msgid "Summer's Night" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:1 +#: ../share/extensions/svgz_output.inx.h:1 +#, fuzzy +msgid "Compressed Inkscape SVG (*.svgz)" +msgstr "Tamanho sem compressão" + +#: ../share/extensions/svgz_input.inx.h:2 +#: ../share/extensions/svgz_output.inx.h:2 +#, fuzzy +msgid "Inkscape's native file format compressed with GZip" +msgstr "Formato de ficheiro nativo do Sodipodi e standard W3C" + +#: ../share/extensions/svgz_input.inx.h:3 +#, fuzzy +msgid "SVGZ Input" +msgstr "Entrada" + +#: ../share/extensions/svgz_output.inx.h:3 +#, fuzzy +msgid "SVGZ Output" +msgstr "Afastar" + +#: ../share/extensions/txt2svg.inx.h:1 +msgid "ASCII Text" +msgstr "" + +#: ../share/extensions/txt2svg.inx.h:2 +msgid "Text File (*.txt)" +msgstr "" + +#: ../share/extensions/txt2svg.inx.h:3 +#, fuzzy +msgid "Text Input" +msgstr "Entrada" + +#: ../share/extensions/wavy.inx.h:1 +msgid "Calculate first derivative numerically" +msgstr "" + +#: ../share/extensions/wavy.inx.h:2 +msgid "First derivative" +msgstr "" + +#: ../share/extensions/wavy.inx.h:3 +msgid "Function" +msgstr "" + +#: ../share/extensions/wavy.inx.h:4 +msgid "Function Plotter" +msgstr "" + +#: ../share/extensions/wavy.inx.h:5 +msgid "Nodes per period" +msgstr "" + +#: ../share/extensions/wavy.inx.h:6 +msgid "Periods (2*Pi each)" +msgstr "" + +#: ../share/extensions/whirl.inx.h:1 +msgid "Amount of Whirl" +msgstr "" + +#: ../share/extensions/whirl.inx.h:2 +#, fuzzy +msgid "Center X" +msgstr "Centrar X:" + +#: ../share/extensions/whirl.inx.h:3 +#, fuzzy +msgid "Center Y" +msgstr "Centrar Y:" + +#: ../share/extensions/whirl.inx.h:4 +#, fuzzy +msgid "Direction of Rotation" +msgstr "enviar selecção para o fundo" + +#: ../share/extensions/whirl.inx.h:5 +msgid "Whirl" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:1 +msgid "A popular graphics file format for clipart" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:2 +msgid "Windows Metafile (*.wmf)" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:3 +msgid "Windows Metafile Input" +msgstr "" + +#, fuzzy +#~ msgid "Canvas size:" +#~ msgstr "Tamanho fonte:" + +#, fuzzy +#~ msgid "Custom canvas" +#~ msgstr "Papel costumizado" + +#, fuzzy +#~ msgid "Current style" +#~ msgstr "Preferências pincelada" + +#, fuzzy +#~ msgid "Arrange Objects" +#~ msgstr "Alinhar Objectos" + +#~ msgid "deg" +#~ msgstr "graus" + +#, fuzzy +#~ msgid "_Credits" +#~ msgstr "Cantos:" + +#, fuzzy +#~ msgid "Grab sensitivity" +#~ msgstr "Tornar sensível" + +#, fuzzy +#~ msgid "Acceleration" +#~ msgstr "Selecção" + +#, fuzzy +#~ msgid "Speed" +#~ msgstr "Vermelho:" + +#, fuzzy +#~ msgid "Zoom in/out by" +#~ msgstr "Diminuir zoom" + +#, fuzzy +#~ msgid "Transform" +#~ msgstr "Transformações" + +#, fuzzy +#~ msgid "Rotate _90 deg CW" +#~ msgstr "Rodar 90 graus" + +#, fuzzy +#~ msgid "Rotate 9_0 deg CCW" +#~ msgstr "Rodar 90 graus" + +#, fuzzy +#~ msgid "Flip selection horizontally" +#~ msgstr "Inverter horizontalmente os objectos seleccionados" + +#, fuzzy +#~ msgid "Flip selection vertically" +#~ msgstr "Inverter verticalmente os objectos seleccionados" + +#~ msgid "Edit" +#~ msgstr "Editar" + +#~ msgid "Add" +#~ msgstr "Adicionar" + +#, fuzzy +#~ msgid "C_reate" +#~ msgstr "Criar" + +#, fuzzy +#~ msgid "Automatically scale Rows to fit selected objects." +#~ msgstr "Editar preenchimento dos objectos seleccionados" + +#, fuzzy +#~ msgid "Automatically scale Columns to fit selected objects." +#~ msgstr "Editar preenchimento dos objectos seleccionados" + +#, fuzzy +#~ msgid "Go to root" +#~ msgstr "Editar nós" + +#, fuzzy +#~ msgid "X" +#~ msgstr "X1" + +#, fuzzy +#~ msgid "Y" +#~ msgstr "Y1" + +#, fuzzy +#~ msgid " " +#~ msgstr "X +" + +#~ msgid "Sides:" +#~ msgstr "Lados:" + +#~ msgid "R1:" +#~ msgstr "R1:" + +#~ msgid "R2:" +#~ msgstr "R2:" + +#~ msgid "ARG1:" +#~ msgstr "ARG1:" + +#~ msgid "ARG2:" +#~ msgstr "ARG2:" + +#, fuzzy +#~ msgid "Flatsides:" +#~ msgstr "Lados:" + +#, fuzzy +#~ msgid "Radius X:" +#~ msgstr "Raio:" + +#, fuzzy +#~ msgid "Radius Y:" +#~ msgstr "Raio:" + +#, fuzzy +#~ msgid "Start Angle:" +#~ msgstr "Estrela" + +#, fuzzy +#~ msgid "End Angle:" +#~ msgstr "Ângulo:" + +#, fuzzy +#~ msgid "Open:" +#~ msgstr "_Abrir" + +#~ msgid "Expansion:" +#~ msgstr "Expansão:" + +#, fuzzy +#~ msgid "Revolutions:" +#~ msgstr "Revolução:" + +#~ msgid "Argument:" +#~ msgstr "Argumento:" + +#~ msgid "T0:" +#~ msgstr "T0:" + +#~ msgid "RX:" +#~ msgstr "RX:" + +#~ msgid "RY:" +#~ msgstr "RY:" + +#, fuzzy +#~ msgid "Rectangle _Properties" +#~ msgstr "Propriedades do Rectângulo" + +#, fuzzy +#~ msgid "Star _Properties" +#~ msgstr "Propriedades da Estrela" + +#, fuzzy +#~ msgid "Ellipse _Properties" +#~ msgstr "Propriedades da Ligação" + +#, fuzzy +#~ msgid "Spiral _Properties" +#~ msgstr "Propriedades da Espiral" + +#, fuzzy +#~ msgid "Document Preferences" +#~ msgstr "O item é referência" + +#, fuzzy +#~ msgid "Extensions Editor" +#~ msgstr "Extensão" + +#, fuzzy +#~ msgid "Preferences" +#~ msgstr "O item é referência" + +#, fuzzy +#~ msgid "Layer Editor" +#~ msgstr "Editor XML" + +#, fuzzy +#~ msgid "Text Properties" +#~ msgstr "Propriedades do texto" + +#, fuzzy +#~ msgid "Transformation" +#~ msgstr "Matriz transformação" + +#, fuzzy +#~ msgid "_Export..." +#~ msgstr "Importar" + +#, fuzzy +#~ msgid "_Document Properties" +#~ msgstr "Preferências do documento" + +#, fuzzy +#~ msgid "In_kscape Preferences" +#~ msgstr "Apresentação Sodipodi" + +#, fuzzy +#~ msgid "Select _Original Clone" +#~ msgstr "Seleccionar Tudo" + +#, fuzzy +#~ msgid "Tile" +#~ msgstr "Título:" + +#, fuzzy +#~ msgid "Select A_ll" +#~ msgstr "Seleccionar Tudo" + +#, fuzzy +#~ msgid "Select Non_e" +#~ msgstr "Selecção" + +#, fuzzy +#~ msgid "Zoom _In" +#~ msgstr "Aumentar zoom" + +#, fuzzy +#~ msgid "Zoom _Out" +#~ msgstr "Diminuir zoom" + +#, fuzzy +#~ msgid "Pre_vious" +#~ msgstr "Fechar janela" + +#, fuzzy +#~ msgid "Nex_t" +#~ msgstr "Texto" + +#, fuzzy +#~ msgid "Tool Co_ntrols bar" +#~ msgstr "Opções ferramentas" + +#, fuzzy +#~ msgid "R_ename Layer..." +#~ msgstr "Elevar nó" + +#, fuzzy +#~ msgid "D_uplicate Layer" +#~ msgstr "Duplicar nó" + +#, fuzzy +#~ msgid "_Anchor Layer" +#~ msgstr "Descer nó" + +#, fuzzy +#~ msgid "_Delete Layer" +#~ msgstr "Seleccionar" + +#, fuzzy +#~ msgid "Select Ne_xt Layer" +#~ msgstr "Seleccionar" + +#, fuzzy +#~ msgid "Select Pre_vious Layer" +#~ msgstr "Seleccionar impressora" + +#, fuzzy +#~ msgid "Select To_p Layer" +#~ msgstr "Seleccionar impressora" + +#, fuzzy +#~ msgid "Move to Ne_w Layer" +#~ msgstr "Criar um novo documento SVG" + +#, fuzzy +#~ msgid "Move to B_ottom Layer" +#~ msgstr "enviar selecção para o fundo" + +#, fuzzy +#~ msgid "_Trace Bitmap..." +#~ msgstr "Imagem inválida" + +#, fuzzy +#~ msgid "_Put Text on Path" +#~ msgstr "Converter objecto seleccionado em caminho" + +#, fuzzy +#~ msgid "_Remove Text from Path" +#~ msgstr "Converter objecto seleccionado em caminho" + +#~ msgid "Arc" +#~ msgstr "Arco" + +#, fuzzy +#~ msgid "Freehand" +#~ msgstr "Mão livre e caneta" + +#, fuzzy +#~ msgid "DynaDraw" +#~ msgstr "Desenhar" + +#~ msgid "Stroke" +#~ msgstr "Rasura" + +#, fuzzy +#~ msgid "Corners" +#~ msgstr "Cantos:" + +#, fuzzy +#~ msgid "Delete" +#~ msgstr "Apagar" + +#, fuzzy +#~ msgid "Join" +#~ msgstr "Ligação:" + +#, fuzzy +#~ msgid "Delete Segment" +#~ msgstr "Duplicar selecção" + +#, fuzzy +#~ msgid "Break" +#~ msgstr "Quebrar" + +#, fuzzy +#~ msgid "Symmetric" +#~ msgstr "Não Simétrico" + +#, fuzzy +#~ msgid "Line" +#~ msgstr "Linear" + +#~ msgid "New" +#~ msgstr "Novo" + +#, fuzzy +#~ msgid "Revert to Saved" +#~ msgstr "Converter em Curvas" + +#, fuzzy +#~ msgid "Save" +#~ msgstr "Gravar" + +#, fuzzy +#~ msgid "Save As..." +#~ msgstr "Gravar Como..." + +#, fuzzy +#~ msgid "Import..." +#~ msgstr "Importar" + +#, fuzzy +#~ msgid "Export..." +#~ msgstr "Exportar" + +#, fuzzy +#~ msgid "Print..." +#~ msgstr "Imprimir..." + +#, fuzzy +#~ msgid "Global Inkscape preferences (Shift+Ctrl+P)" +#~ msgstr "Preferências globais de visualização" + +#, fuzzy +#~ msgid "Undo" +#~ msgstr "Anular " + +#, fuzzy +#~ msgid "Redo" +#~ msgstr "Refazer" + +#, fuzzy +#~ msgid "Cut" +#~ msgstr "Cortar" + +#, fuzzy +#~ msgid "Copy" +#~ msgstr "Copiar" + +#, fuzzy +#~ msgid "Duplicate selected object(s) (Ctrl+D)" +#~ msgstr "Duplicar objectos seleccionados" + +#, fuzzy +#~ msgid "Clone selected object (Alt+D)" +#~ msgstr "Duplicar objectos seleccionados" + +#, fuzzy +#~ msgid "Zoom in (+)" +#~ msgstr "Aumentar zoom" + +#, fuzzy +#~ msgid "Zoom out (-)" +#~ msgstr "Diminuir zoom" + +#, fuzzy +#~ msgid "Zoom to 1:1 (100%) (1)" +#~ msgstr "Zoom a 1:1" + +#, fuzzy +#~ msgid "Zoom to 1:2 (50%) (2)" +#~ msgstr "Zoom a 1:2" + +#, fuzzy +#~ msgid "Zoom to 2:1 (200%) (0)" +#~ msgstr "Zoom a 2:1" + +#, fuzzy +#~ msgid "Zoom to fit selection in window (3)" +#~ msgstr "Dimensionar a selecção inteira à janela" + +#, fuzzy +#~ msgid "Zoom to fit drawing in window (4)" +#~ msgstr "Dimensionar o desenho inteiro à janela" + +#, fuzzy +#~ msgid "Zoom to fit page in window (5)" +#~ msgstr "Dimensionar a página inteira à janela" + +#, fuzzy +#~ msgid "Zoom to fit page width in window (6)" +#~ msgstr "Dimensionar a página inteira à janela" + +#, fuzzy +#~ msgid "Fill and Stroke dialog (Shift+Ctrl+F)" +#~ msgstr "Enchimento e Pincel" + +#, fuzzy +#~ msgid "Group selected objects (Ctrl+G)" +#~ msgstr "Agrupar objectos seleccionados" + +#, fuzzy +#~ msgid "Ungroup selected group(s) (Ctrl+U)" +#~ msgstr "Desagrupar objectos seleccionados" + +#, fuzzy +#~ msgid "Raise selection up one step (PgUp)" +#~ msgstr "Trazer selecção para o topo" + +#, fuzzy +#~ msgid "Lower selection down one step (PgDn)" +#~ msgstr "Baixar selecção por uma camada" + +#, fuzzy +#~ msgid "Raise selection to top (Home)" +#~ msgstr "Trazer selecção para o topo" + +#, fuzzy +#~ msgid "Lower selection to bottom (End)" +#~ msgstr "enviar selecção para o fundo" + +#, fuzzy +#~ msgid "Move selection to new layer" +#~ msgstr "Elevar selecção uma camada" + +#, fuzzy +#~ msgid "Move selection to next layer" +#~ msgstr "Elevar selecção uma camada" + +#, fuzzy +#~ msgid "Move selection to previous layer" +#~ msgstr "Elevar selecção uma camada" + +#, fuzzy +#~ msgid "Move selection to top layer" +#~ msgstr "Elevar selecção uma camada" + +#, fuzzy +#~ msgid "Move selection to bottom layer" +#~ msgstr "enviar selecção para o fundo" + +#, fuzzy +#~ msgid "Rotate selection 90° clockwise (Shift+Ctrl+Right)" +#~ msgstr "Rodar objecto 90 graus no sentido dos ponteiros" + +#, fuzzy +#~ msgid "Rotate selection 90° counter-clockwise (Shift+Ctrl+Left)" +#~ msgstr "Rodar objecto 90 graus no sentido dos ponteiros" + +#, fuzzy +#~ msgid "Flip selection horizontally (H)" +#~ msgstr "Inverter horizontalmente os objectos seleccionados" + +#, fuzzy +#~ msgid "Flip selection vertically (V)" +#~ msgstr "Inverter verticalmente os objectos seleccionados" + +#, fuzzy +#~ msgid "Align and Distribute dialog (Shift+Ctrl+A)" +#~ msgstr "Alinhar e Distribuir" + +#, fuzzy +#~ msgid "Convert selected object(s) to path(s) (Shift+Ctrl+C)" +#~ msgstr "Converter objecto seleccionado em caminho" + +#, fuzzy +#~ msgid "Convert selected stroke(s) to path(s) (Ctrl+Alt+C)" +#~ msgstr "Converter objecto seleccionado em caminho" + +#, fuzzy +#~ msgid "Cl_eanup" +#~ msgstr "Limpar" + +#, fuzzy +#~ msgid "Text and Font dialog (Shift+Ctrl+T)" +#~ msgstr "Texto e fontes" + +#, fuzzy +#~ msgid "Node tool" +#~ msgstr "Nenhuma ferramenta activa" + +#, fuzzy +#~ msgid "Zoom tool" +#~ msgstr "Diminuir zoom" + +#~ msgid "Rectangle tool" +#~ msgstr "Ferramenta rectângulo" + +#~ msgid "Arc tool" +#~ msgstr "Ferramenta arco" + +#~ msgid "Star tool" +#~ msgstr "Ferramenta estrela" + +#~ msgid "Spiral tool" +#~ msgstr "Ferramenta espiral" + +#, fuzzy +#~ msgid "Freehand tool" +#~ msgstr "Mão livre e caneta" + +#, fuzzy +#~ msgid "Pen tool" +#~ msgstr "Ferramenta rectângulo" + +#, fuzzy +#~ msgid "Calligraphy tool" +#~ msgstr "Caligrafia" + +#, fuzzy +#~ msgid "Text tool" +#~ msgstr "Ferramenta estrela" + +#, fuzzy +#~ msgid "Dropper tool" +#~ msgstr "Conta-Gotas" + +#, fuzzy +#~ msgid "When scaling rectangles, scale radii of rounded corners" +#~ msgstr "Valor horizontal do centro" + +#, fuzzy +#~ msgid "Delete segment between two nodes" +#~ msgstr "Apagar nós seleccionados" + +#, fuzzy +#~ msgid "URI:" +#~ msgstr "URL:" + +#, fuzzy +#~ msgid "Select All in All Layers" +#~ msgstr "Seleccionar" + +#, fuzzy +#~ msgid "Invert Selection" +#~ msgstr "Selecção" + +#, fuzzy +#~ msgid "Clean up selected path(s)" +#~ msgstr "Combinar os caminhos seleccionados" + +#, fuzzy +#~ msgid "_Scripts..." +#~ msgstr "Imprimir..." + +#, fuzzy +#~ msgid "Align and Distribute" +#~ msgstr "Alinhar e Distribuir" + +#, fuzzy +#~ msgid "Align and Distribute Dialog" +#~ msgstr "Alinhar e Distribuir" + +#, fuzzy +#~ msgid "Export Dialog" +#~ msgstr "Exportar como" + +#, fuzzy +#~ msgid "Fill and Stroke Dialog" +#~ msgstr "Enchimento e Pincel" + +#, fuzzy +#~ msgid "Find Dialog" +#~ msgstr "Diálogo de alinhamento" + +#, fuzzy +#~ msgid "Inkscape Preferences" +#~ msgstr "Apresentação Sodipodi" + +#, fuzzy +#~ msgid "Inkscape Preferences Dialog" +#~ msgstr "Apresentação Sodipodi" + +#, fuzzy +#~ msgid "Layer Editor Dialog" +#~ msgstr "Trazer selecção para o topo" + +#, fuzzy +#~ msgid "Text Properties Dialog" +#~ msgstr "propriedades do objecto" + +#, fuzzy +#~ msgid "Transformation Dialog" +#~ msgstr "Diálogo de transformação" + +#, fuzzy +#~ msgid "Tree Editor" +#~ msgstr "Editor XML" + +#, fuzzy +#~ msgid "XML Editor Dialog" +#~ msgstr "Editor XML" + +#, fuzzy +#~ msgid "Row height:" +#~ msgstr "Altura:" + +#, fuzzy +#~ msgid "Column width:" +#~ msgstr "Alterar" + +#, fuzzy +#~ msgid "Creating anchor at (%g,%g)" +#~ msgstr "Desenhar estrela" + +#, fuzzy +#~ msgid "EPS Output Settings" +#~ msgstr "Preferências do documento" + +#, fuzzy +#~ msgid "Inkscape" +#~ msgstr "Apresentação Sodipodi" + +#~ msgid "Left side of aligned objects to left side of anchor" +#~ msgstr "Lado esquerdo dos objectos alinhados ao lado esquerdo da âncora" + +#~ msgid "Right side of aligned objects to right side of anchor" +#~ msgstr "Lado direito dos objectos alinhados ao lado direito da âncora" + +#~ msgid "Top of aligned objects to top of anchor" +#~ msgstr "Topo dos objectos alinhados ao topo da âncora" + +#~ msgid "Bottom of aligned objects to bottom of anchor" +#~ msgstr "Fundo dos objectos alinhados ao fundo da âncora" + +#~ msgid "Distribute top sides of objects at even distances" +#~ msgstr "Distribuir lados de topo dos objectos a distâncias equivalentes" + +#, fuzzy +#~ msgid "Alternate sign" +#~ msgstr "Saturação:" + +#, fuzzy +#~ msgid "Rows:" +#~ msgstr "Elipse" + +#, fuzzy +#~ msgid "Minor grid line color:" +#~ msgstr "Cor das guias" + +#~ msgid "Grid color" +#~ msgstr "Cor da grelha" + +#, fuzzy +#~ msgid "Grid emphasis color" +#~ msgstr "Cor da grelha" + +#, fuzzy +#~ msgid "Major grid line spacing:" +#~ msgstr "Espaçamento linha:" + +#, fuzzy +#~ msgid "Background (also for export):" +#~ msgstr "Cor final" + +#, fuzzy +#~ msgid "Picking colors:" +#~ msgstr "Escolha a cor" + +#~ msgid "Fill style" +#~ msgstr "Estilo preenchimento" + +#, fuzzy +#~ msgid "Fill:" +#~ msgstr "Preenchimento" + +#, fuzzy +#~ msgid "winding" +#~ msgstr "Renderizar" + +#, fuzzy +#~ msgid "alternating" +#~ msgstr "Saturação:" + +#, fuzzy +#~ msgid "Update Properties" +#~ msgstr "Propriedades do Item" + +#, fuzzy +#~ msgid "Label invalid" +#~ msgstr "O identificador é válido" + +#, fuzzy +#~ msgid "executable" +#~ msgstr "Rectângulo" + +#, fuzzy +#~ msgid "file" +#~ msgstr "_Ficheiro" + +#, fuzzy +#~ msgid "extension" +#~ msgstr "Extensão" + +#, fuzzy +#~ msgid "path" +#~ msgstr "pt" + +#, fuzzy +#~ msgid "absolute" +#~ msgstr "absoluto" + +#~ msgid "Could not create sodipodi-svg-doc factory" +#~ msgstr "Não foi possível criar a fábrica sodipodi-svg-doc" + +#, fuzzy +#~ msgid "SVG Files" +#~ msgstr "Ficheiro" + +#~ msgid "Plain SVG" +#~ msgstr "SVG Simples" + +#, fuzzy +#~ msgid "Make s_ensitive" +#~ msgstr "Tornar sensível" + +#, fuzzy +#~ msgid "Make i_nsensitive" +#~ msgstr "Tornar insensível" + +#, fuzzy +#~ msgid "Layer Properties" +#~ msgstr "Propriedades da Estrela" + +#, fuzzy +#~ msgid "Select object(s) to tile." +#~ msgstr "Cortar os objectos seleccionados para área de transferência" + +#, fuzzy +#~ msgid "Apply" +#~ msgstr "Aplicar a:" + +#~ msgid "Sensitive" +#~ msgstr "Sensível" + +#~ msgid "Active" +#~ msgstr "Activo" + +#~ msgid "Printable" +#~ msgstr "Imprimível" + +#, fuzzy +#~ msgid "Prefer bitmap (XPM) icons to SVG ones" +#~ msgstr "Preferir ícones bitmap (xpm) a ícones SVG" + +#~ msgid "Trace" +#~ msgstr "Analisar" + +#, fuzzy +#~ msgid "Error writing %s: %s" +#~ msgstr "Erro ao escrever %s: %s" + +#~ msgid "Untitled" +#~ msgstr "SemTitulo" + +#~ msgid "Document Name:" +#~ msgstr "Nome Documento:" + +#~ msgid "Image URI:" +#~ msgstr "URI Imagem:" + +#~ msgid "Visible" +#~ msgstr "Visível" + +#, fuzzy +#~ msgid "Drag to paint a calligraphic stroke." +#~ msgstr "Desenhar linhas caligráficas" + +#, fuzzy +#~ msgid "Flatness:" +#~ msgstr "Lados:" + +#, fuzzy +#~ msgid "Other" +#~ msgstr "Ordenar" + +#, fuzzy +#~ msgid "Trace: Selected object is not an image" +#~ msgstr "Elevar objectos seleccionados uma posição" + +#, fuzzy +#~ msgid "object" +#~ msgstr "Objecto" + +#, fuzzy +#~ msgid "user space" +#~ msgstr "Espaço de utilizador" + +#, fuzzy +#~ msgid "Coordinates:" +#~ msgstr "Cantos:" + +#, fuzzy +#~ msgid "" +#~ "Distribute centers of objects of objects at even distances horizontally" +#~ msgstr "" +#~ "Distribuir centro dos objectos a distâncias horizontalmente equivalentes" + +#~ msgid "Alignment:" +#~ msgstr "Alinhamento:" + +#~ msgid "Text and font" +#~ msgstr "Texto e fontes" + +#, fuzzy +#~ msgid "Draw arc: %s x %s" +#~ msgstr "Desenhar arco" + +#~ msgid "All shape tools" +#~ msgstr "Todas as ferramentas de formas" + +#, fuzzy +#~ msgid "Draw rectangle: %s x %s" +#~ msgstr "Desenhar rectângulo" + +#, fuzzy +#~ msgid "Move by %s, %s" +#~ msgstr "Mover" + +#, fuzzy +#~ msgid "Active group" +#~ msgstr "Activo" + +#, fuzzy +#~ msgid "typeset object" +#~ msgstr "Objecto de texto" + +#, fuzzy +#~ msgid "Pattern Fill" +#~ msgstr "Padrão:" + +#~ msgid "Snap to grid" +#~ msgstr "Ajustar à grelha" + +#~ msgid "Snap to guides" +#~ msgstr "Ajustar às guias" + +#, fuzzy +#~ msgid "_Menu" +#~ msgstr "Limpar" + +#, fuzzy +#~ msgid "Snap points to the grid" +#~ msgstr "Ajustar à grelha" + +#, fuzzy +#~ msgid "Rect" +#~ msgstr "Rectângulo" + +#~ msgid "meters" +#~ msgstr "metros" + +#~ msgid "Userspace unit" +#~ msgstr "Unidade de espaço de utilizador" + +#~ msgid "User" +#~ msgstr "Utilizador" + +#~ msgid "Userspace units" +#~ msgstr "Unidades de espaço de utilizador" + +#, fuzzy +#~ msgid "Ru_lers" +#~ msgstr "Filtros" + +#, fuzzy +#~ msgid "Show or hide rulers" +#~ msgstr "Mostar guias" + +#, fuzzy +#~ msgid "_New Window" +#~ msgstr "Nova Vista" + +#~ msgid "Mode:" +#~ msgstr "Modo:" + +#~ msgid "RGB Colorspace" +#~ msgstr "Espaço de Cor RGB" + +#~ msgid "CMYK Colorspace" +#~ msgstr "Espaço de Cor CMYK" + +#~ msgid "Get from dropper" +#~ msgstr "Obter do conta-gotas" + +#~ msgid "Alpha:" +#~ msgstr "Alfa:" + +#~ msgid "Value:" +#~ msgstr "Valor:" + +#~ msgid "Stroke settings" +#~ msgstr "Preferências pincelada" + +#~ msgid "Item properties" +#~ msgstr "Propriedades do item" + +#, fuzzy +#~ msgid "Quit" +#~ msgstr "_Sair" + +#~ msgid "Combine multiple paths" +#~ msgstr "Combinar múltiplos caminhos" + +#, fuzzy +#~ msgid "New View" +#~ msgstr "Nova Vista" + +#~ msgid "Fill and stroke settings" +#~ msgstr "Definições do enchimento e pincel" + +#~ msgid "Object transformations" +#~ msgstr "Transformações de objecto" + +#, fuzzy +#~ msgid "Align and distribute objects" +#~ msgstr "Alinhar e distribuir" + +#~ msgid "Text editing and font settings" +#~ msgstr "Edição de texto e definições de fonte" + +#~ msgid "Fill Rule" +#~ msgstr "Regra Preenchimento" + +#~ msgid "Tool has no options" +#~ msgstr "Ferramenta não tem opções" + +#~ msgid "Roundness ratio for x:" +#~ msgstr "Rácio de arredondamento para x:" + +#~ msgid "Roundness ratio for y:" +#~ msgstr "Rácio de arredondamento para y:" + +#~ msgid "Visual transformation" +#~ msgstr "Transformação visual" + +#~ msgid "Show content" +#~ msgstr "Mostrar conteúdo" + +#, fuzzy +#~ msgid "Selected object has no curve, cannot outline." +#~ msgstr "Cortar os objectos seleccionados para área de transferência" + +#~ msgid "Proportion:" +#~ msgstr "Proporção:" + +#, fuzzy +#~ msgid "Inkscape _Options" +#~ msgstr "Apresentação Sodipodi" + +#, fuzzy +#~ msgid "Tool Optio_ns" +#~ msgstr "Opções Ferramentas" + +#~ msgid "gradientUnits" +#~ msgstr "UnidadesGradiente" + +#~ msgid "gradientSpread" +#~ msgstr "DispersãoGradiente" + +#~ msgid "nonzero" +#~ msgstr "não-zero" + +#~ msgid "evenodd" +#~ msgstr "par-ímpar" + +#, fuzzy +#~ msgid "" +#~ "%s is not regular file.\n" +#~ "Although inkscape will run, you can\n" +#~ "neither load nor save preferences\n" +#~ msgstr "" +#~ "%s não é um ficheiro normal.\n" +#~ "Apesar do sodipodi correr, não poderá\n" +#~ "nem abrir nem gravar preferências\n" + +#, fuzzy +#~ msgid "" +#~ "%s either is not valid xml file or\n" +#~ "you do not have read premissions on it.\n" +#~ "Although inkscape will run, you\n" +#~ "are neither able to load nor save\n" +#~ "preferences." +#~ msgstr "" +#~ "%s ou não é um ficheiro xml válido ou\n" +#~ "não possui permissões de leitura para o mesmo.\n" +#~ "Apesar do sodipodi correr, não poderá\n" +#~ "nem abrir nem gravar preferências." + +#, fuzzy +#~ msgid "" +#~ "%s is not valid inkscape preferences file.\n" +#~ "Although inkscape will run, you\n" +#~ "are neither able to load nor save\n" +#~ "preferences." +#~ msgstr "" +#~ "%s não é um ficheiro válido de preferências do sodipodi.\n" +#~ "Apesar do sodipodi correr, não poderá\n" +#~ "nem abrir nem gravar preferências." + +#, fuzzy +#~ msgid "" +#~ "Cannot create directory %s.\n" +#~ "Although inkscape will run, you\n" +#~ "are neither able to load nor save\n" +#~ "%s." +#~ msgstr "" +#~ "Incapaz de criar o directório %s.\n" +#~ "Apesar do sodipodi correr, não poderá\n" +#~ "nem abrir nem gravar\n" +#~ "%s." + +#, fuzzy +#~ msgid "" +#~ "%s is not a valid directory.\n" +#~ "Although inkscape will run, you\n" +#~ "are neither able to load nor save\n" +#~ "preferences." +#~ msgstr "" +#~ "%s não é um directório válido.\n" +#~ "Apesar do sodipodi correr, não poderá\n" +#~ "nem abrir nem gravar preferências." + +#, fuzzy +#~ msgid "" +#~ "Cannot create file %s.\n" +#~ "Although inkscape will run, you\n" +#~ "are neither able to load nor save\n" +#~ "preferences." +#~ msgstr "" +#~ "Incapaz de criar o ficheiro %s.\n" +#~ "Apesar do sodipodi correr, não poderá\n" +#~ "nem abrir nem gravar\n" +#~ "preferências." + +#, fuzzy +#~ msgid "" +#~ "Cannot write file %s.\n" +#~ "Although inkscape will run, you\n" +#~ "are neither able to load nor save\n" +#~ "preferences." +#~ msgstr "" +#~ "Incapaz de escrever no ficheiro %s.\n" +#~ "Apesar do sodipodi correr, não poderá\n" +#~ "nem abrir nem gravar\n" +#~ "preferências." + +#~ msgid "End color" +#~ msgstr "Cor final" + +#~ msgid "Make sides flat" +#~ msgstr "Tornar lados lisos" + +#~ msgid "Bring to _Front" +#~ msgstr "Trazer para a _Frente" + +#~ msgid "Send to _Back" +#~ msgstr "Enviar para _Trás" + +#~ msgid "Toggle separate window and main toolbox placement" +#~ msgstr "" +#~ "Alternar colocação de janela separada e caixa de ferramentas principal" + +#~ msgid "Document %s has unsaved changes, save them?" +#~ msgstr "O documento %s contém alterações por gravar, grava-las?" + +#, fuzzy +#~ msgid "Object Size and Position" +#~ msgstr "Tamanho e posição do objecto" + +#~ msgid "Size and Position" +#~ msgstr "Tamanho e Posição" + +#~ msgid "Tool attributes" +#~ msgstr "Atributos ferramenta" + +#~ msgid "Inner radius" +#~ msgstr "Raio interior" + +#~ msgid "Proportion" +#~ msgstr "Proporção" + +#~ msgid "Tool has no attributes" +#~ msgstr "Ferramenta não tem atributos" + +#~ msgid "Item" +#~ msgstr "Item" + +#~ msgid "Group Properties" +#~ msgstr "Propriedades do Grupo" + +#~ msgid "Ungroup" +#~ msgstr "Desagrupar" + +#~ msgid "Link" +#~ msgstr "Ligar" + +#~ msgid "Fill settings" +#~ msgstr "Definições preenchimento" + +#~ msgid "Break line at selected nodes" +#~ msgstr "Quebrar linha nos nós seleccionados" + +#~ msgid "Bring to Front" +#~ msgstr "Trazer para a Frente" + +#~ msgid "Send to Back" +#~ msgstr "Enviar para Trás" + +#~ msgid "Lower selected objects to bottom" +#~ msgstr "Baixar objectos seleccionados para o fundo" + +#~ msgid "Lower selected objects one position" +#~ msgstr "Baixar objectos seleccionados uma posição" + +#~ msgid "Draw freehand curves and straight lines" +#~ msgstr "Desenhar linhas em modo livre e rectas" + +#~ msgid "Zoom into precisely selected area" +#~ msgstr "Zoom precisamente na área seleccionada" + +#~ msgid "In" +#~ msgstr "Aproximar" + +#, fuzzy +#~ msgid "Toggle grid" +#~ msgstr "Alternar Margens" + +#, fuzzy +#~ msgid "Toggle guides" +#~ msgstr "Alternar Margens" + +#~ msgid "1:1" +#~ msgstr "1:1" + +#~ msgid "1:2" +#~ msgstr "1:2" + +#~ msgid "2:1" +#~ msgstr "2:1" + +#~ msgid "Editing Window" +#~ msgstr "Janela de Edição" + +#~ msgid "Editing window properties" +#~ msgstr "Propriedades da janela de edição" + +#~ msgid "Tool Attributes" +#~ msgstr "Atributos Ferramentas" + +#~ msgid "Sodipodi" +#~ msgstr "Sodipodi" + +#~ msgid "Desktop settings" +#~ msgstr "Preferências da área de trabalho" + +#, fuzzy +#~ msgid "Iso grid" +#~ msgstr "Mostrar grelha" + +#~ msgid "Display settings" +#~ msgstr "Preferências de visualização" + +#~ msgid "Export png file" +#~ msgstr "Exportar ficheiro png" + +#~ msgid "Object style" +#~ msgstr "Estilo objecto" + +#, fuzzy +#~ msgid "Inkscape: %s : XML View" +#~ msgstr "Sodipodi: %s: Vista XML" + +#~ msgid "Appending to selection. Press 'a' to toggle Append/New." +#~ msgstr "A anexar à selecção. Prima 'a' para alternar Anexar/Novo." + +#~ msgid "Scalable Vector Graphic (SVG)" +#~ msgstr "Gráfico de Vector Escalável (SVG)" + +#~ msgid "Exit Program" +#~ msgstr "Sair Aplicação" + +#~ msgid "New Toplevel Toolbox" +#~ msgstr "Nova Caixa de Ferramentas de Topo" + +#~ msgid "New Docked Toolbox" +#~ msgstr "Nova Caixa de Ferramentas Anexada" + +#~ msgid "Remove Docked Toolbox" +#~ msgstr "Remover Caixa de Ferramentas Anexada" + +#~ msgid "Drawing Mode" +#~ msgstr "Modo de Desenho" + +#~ msgid "SVG with \"xmlns:sodipodi\" namespace" +#~ msgstr "SVG com namespace \"xmlns:sodipodi\"" + +#, fuzzy +#~ msgid "Scalable Vector Graphics format with inkscape extensions" +#~ msgstr "Formato Gráficos de Vector Escaláveis (SVG) com extensões sodipodi" + +#, fuzzy +#~ msgid "" +#~ "%s is not regular file.\n" +#~ "Although inkscape will run, you are\n" +#~ "not able to use extensions (plugins)\n" +#~ msgstr "" +#~ "%s não é um ficheiro normal.\n" +#~ "Apesar do sodipodi correr, não poderá\n" +#~ "utilizar extensões (plugins)\n" + +#, fuzzy +#~ msgid "" +#~ "%s either is not valid xml file or\n" +#~ "you do not have read premissions on it.\n" +#~ "Although inkscape will run, you are\n" +#~ "not able to use extensions (plugins)\n" +#~ msgstr "" +#~ "%s ou não é um ficheiro xml válido ou\n" +#~ "não tem permissões de leitura para o mesmo.\n" +#~ "Apesar do sodipodi correr, não poderá\n" +#~ "utilizar extensões (plugins)\n" + +#, fuzzy +#~ msgid "" +#~ "%s is not valid inkscape extensions file.\n" +#~ "Although inkscape will run, you are\n" +#~ "not able to use extensions (plugins)\n" +#~ msgstr "" +#~ "%s não é um ficheiro válido de extensões sodipodi.\n" +#~ "Apesar do sodipodi correr, não poderá\n" +#~ "utilizar extensões (plugins)\n" + +#, fuzzy +#~ msgid "" +#~ "Cannot create directory %s.\n" +#~ "Although inkscape will run, you are\n" +#~ "not able to use extensions (plugins)\n" +#~ msgstr "" +#~ "Incapaz de criar o directório %s.\n" +#~ "Apesar do sodipodi correr, não poderá\n" +#~ "utilizar extensões (plugins)\n" + +#, fuzzy +#~ msgid "" +#~ "%s is not a valid directory.\n" +#~ "Although inkscape will run, you are\n" +#~ "not able to use extensions (plugins)\n" +#~ msgstr "" +#~ "%s não é um directório válido.\n" +#~ "Apesar do sodipodi correr, não poderá\n" +#~ "utilizar extensões (plugins)\n" + +#, fuzzy +#~ msgid "" +#~ "Cannot create file %s.\n" +#~ "Although inkscape will run, you are\n" +#~ "not able to use extensions (plugins)\n" +#~ msgstr "" +#~ "Incapaz de criar o ficheiro %s.\n" +#~ "Apesar do sodipodi correr, não poderá\n" +#~ "utilizar extensões (plugins)\n" + +#, fuzzy +#~ msgid "" +#~ "Cannot write file %s.\n" +#~ "Although inkscape will run, you are\n" +#~ "not able to use extensions (plugins)\n" +#~ msgstr "" +#~ "Incapaz de escrever no ficheiro %s.\n" +#~ "Apesar do sodipodi correr, não poderá\n" +#~ "utilizar extensões (plugins)\n" + +#~ msgid "Unknown item :-(" +#~ msgstr "Item desconhecido :-(" + +#~ msgid "Text and font settings" +#~ msgstr "Definições de texto e fontes" + +#~ msgid "Modify existing objects by control nodes" +#~ msgstr "Alterar objectos existentes pelos nós controladores" + +#~ msgid "Draw precisely positioned curved and straight lines" +#~ msgstr "Desenhar curvas posicionadas com precisão e rectas" + +#~ msgid "Zoom in drawing" +#~ msgstr "Aproximar zoom ao desenho" + +#~ msgid "Zoom out drawing" +#~ msgstr "Afastar zoom ao desenho" + +#~ msgid "Set zoom factor to 1:1" +#~ msgstr "Definir factor de zoom a 1:1" + +#~ msgid "Set zoom factor to 1:2" +#~ msgstr "Definir factor de zoom a 1:2" + +#~ msgid "Set zoom factor to 2:1" +#~ msgstr "Definir factor de zoom a 2:1" + +#~ msgid "Document" +#~ msgstr "Documento" + +#~ msgid "Page layout" +#~ msgstr "Disposição de página" + +#~ msgid "Document variant:" +#~ msgstr "Variante de documento:" + +#~ msgid "" +#~ "*.svg *.svgz|SVG files\n" +#~ "*.xml|XML files\n" +#~ "*|All files" +#~ msgstr "" +#~ "Ficheiros SVG | *.svg *.svgz\n" +#~ "Ficheiros XML | *.xml\n" +#~ "Todos ficheiros | *" + +#~ msgid "Save document as" +#~ msgstr "Gravar documento como" + +#~ msgid "About sodipodi" +#~ msgstr "Sobre sodipodi" + +#~ msgid "About Sodipodi" +#~ msgstr "Sobre Sodipodi" + +#~ msgid "The SVG ID of item" +#~ msgstr "Identificador do item SGV" + +#~ msgid "The ID is not valid" +#~ msgstr "O identificador não é válido" + +#~ msgid "The ID is already defined" +#~ msgstr "O identificador já está definido" + +#~ msgid "Object position and size" +#~ msgstr "Tamanho e posição objecto" + +#~ msgid "Position and size" +#~ msgstr "Tamanho e posição" + +#~ msgid "Dynahand" +#~ msgstr "Mão dinâmica" + +#~ msgid "Text Editing" +#~ msgstr "Editar Texto" + +#~ msgid "Display Properties" +#~ msgstr "Propriedades de Ecrã" + +#~ msgid "A path - whatever it means" +#~ msgstr "Um caminho - o que quer que isso signifique" + +#~ msgid "Welcome !" +#~ msgstr "Bem Vindo !" + +#~ msgid "Sodipodi SVG Document" +#~ msgstr "Documento SVG Sodipodi" + +#~ msgid "Sodipodi SVG Document factory" +#~ msgstr "Fábrica Sodipodi de Documento SVG" + +#~ msgid "Align objects to vertical mid" +#~ msgstr "Alinhar objectos centrados na vertical" + +#~ msgid "Align outside object to bottom border" +#~ msgstr "Alinhar objecto exterior à margem inferior" + +#~ msgid "Align outside object to left border" +#~ msgstr "Alinhar objecto exterior à margem esquerda" + +#~ msgid "Align outside object to right border" +#~ msgstr "Alinhar objecto exterior à margem direita" + +#~ msgid "Align outside object to top border" +#~ msgstr "Alinhar o objecto exterior à margem superior" + +#~ msgid "Alignment base" +#~ msgstr "Base de alinhamento" + +#~ msgid "Choose align type" +#~ msgstr "Escolha tipo alinhamento" + +#~ msgid "Parent X =" +#~ msgstr "Pai X =" + +#~ msgid "Parent Y =" +#~ msgstr "Pai Y =" + +#~ msgid "Y +" +#~ msgstr "Y +" + +#~ msgid " Color fill " +#~ msgstr " Cor do preenchimento " + +#~ msgid " General " +#~ msgstr " Geral " + +#~ msgid "Add new gradient" +#~ msgstr "Adicionar novo gradiente" + +#~ msgid "Behind fill" +#~ msgstr "Preenchimento de fundo" + +#~ msgid "Butt endpoints" +#~ msgstr "Terminação justa" + +#~ msgid "Choose fill color" +#~ msgstr "Escolha a cor para o preenchimento" + +#~ msgid "Choose stroke color" +#~ msgstr "Escolha a cor da rasura" + +#~ msgid "Endpoints:" +#~ msgstr "Terminações:" + +#~ msgid "Fill Color:" +#~ msgstr "Cor de preenchimento:" + +#~ msgid "Fractal fill" +#~ msgstr "Preencher com fractal" + +#~ msgid "Pick fill color" +#~ msgstr "Escolha a cor para o preenchimento" + +#~ msgid "Scale with object" +#~ msgstr "Escalar com o objecto" + +#~ msgid "centimeter" +#~ msgstr "centímetros" + +#~ msgid "color" +#~ msgstr "cor" + +#~ msgid "millimeters" +#~ msgstr "milímetros" + +#~ msgid "points" +#~ msgstr "pontos" + +#~ msgid "1.0MB" +#~ msgstr "1.0MB" + +#~ msgid "Back One" +#~ msgstr "Um passo para trás" + +#~ msgid "Convert selected segments to curves" +#~ msgstr "Converter os segmentos seleccionados para curvas" + +#~ msgid "Cusp line at selected nodes" +#~ msgstr "Remover suavização nos nós seleccionados" + +#~ msgid "Desktop" +#~ msgstr "Área de Trabalho" + +#~ msgid "Drawing Context" +#~ msgstr "Contexto de Desenho" + +#~ msgid "Export picture to png" +#~ msgstr "Exportar imagem para png" + +#~ msgid "Forward One" +#~ msgstr "Um passo para a frente" + +#~ msgid "Include one node into selected segments" +#~ msgstr "Incluir um nó nos segmentos seleccionados" + +#~ msgid "Join 2 selected endpoints" +#~ msgstr "Ligar dois extremos seleccionados" + +#~ msgid "Set dimensions" +#~ msgstr "Especificar dimensões" + +#~ msgid "Smooth line at selected nodes" +#~ msgstr "Suavizar linha nos nós seleccionados" + +#~ msgid "Where to export" +#~ msgstr "Exportar para onde" + +#~ msgid "X0" +#~ msgstr "X0" + +#~ msgid "XML Tree" +#~ msgstr "Árvore XML" + +#~ msgid "Y0" +#~ msgstr "Y0" + +#~ msgid "_Align" +#~ msgstr "_Alinhar" + +#~ msgid "Break apart selected paths" +#~ msgstr "Quebrar os caminhos seleccionados" + +#~ msgid "Drawing context" +#~ msgstr "Contexto de desenho" + +#~ msgid "Edit font style of selected objects" +#~ msgstr "Editar o estilo de texto dos objectos seleccionados" + +#~ msgid "Import " +#~ msgstr "Importar " + +#~ msgid "New drawing" +#~ msgstr "Novo desenho" + +#~ msgid "No I'd rather do some more cool vector drawing with sodipodi." +#~ msgstr "" +#~ "Não, quero estar aqui mais algum tempo a desenhar com o fabuloso sodipodi" + +#~ msgid "Nope !" +#~ msgstr "Nem pensar !" + +#~ msgid "Paste from clipboard" +#~ msgstr "Colar do clipboard" + +#~ msgid "Preview print drawing" +#~ msgstr "Pré-visualizar a impressão do desenho" + +#~ msgid "Quit or not quit ?" +#~ msgstr "Deseja mesmo sair ?" + +#~ msgid "Really wanna quit sodipodi ?" +#~ msgstr "Quer mesmo sair do sodipodi ?" + +#~ msgid "Rotate selected objects 90deg clockwise" +#~ msgstr "Rodar objectos seleccionados 90 graus no sentido dos ponteiros" + +#~ msgid "Save drawing " +#~ msgstr "Gravar desenho " + +#~ msgid "Yep !" +#~ msgstr "Claro !" + +#~ msgid "Yes quick! I want to leave sodipodi and come back later." +#~ msgstr "Rápido ! Quero sair já do sodipodi para voltar mais logo" + +#~ msgid "Align to bottom middle" +#~ msgstr "Alinhar ao meio em baixo" + +#~ msgid "Align to bottom right" +#~ msgstr "Alinhar à direita em baixo" + +#~ msgid "Align to center" +#~ msgstr "Alinhar ao centro" + +#~ msgid "Align to top middle" +#~ msgstr "Alinhar ao centro em cima" + +#~ msgid "Choose metric for center" +#~ msgstr "Escolha a unidade para o centro" + +#~ msgid "Close dialog - Ctl+c" +#~ msgstr "Fechar diálogo - Ctl+c" + +#~ msgid "Expand dialog - Ctl+e" +#~ msgstr "Expandir diálogo - Ctl+e" + +#~ msgid "Keep height of selection during transformation" +#~ msgstr "Manter altura da selecção durante a transformação" + +#~ msgid "Keep width of selection during transformation" +#~ msgstr "Manter largura da selecção durante a transformação" + +#~ msgid "Orig. Width: " +#~ msgstr "Largura da origem: " + +#~ msgid "Orig. X: " +#~ msgstr "Orig. X: " + +#~ msgid "Set angle to 0 degrees" +#~ msgstr "Colocar ângulo em 0 graus" + +#~ msgid "Set angle to 180 degrees" +#~ msgstr "Colocar ângulo em 180 graus" + +#~ msgid "Set angle to 270 degrees" +#~ msgstr "Colocar ângulo em 270 graus" + +#~ msgid "Start transformation - Ctl+a" +#~ msgstr "Começar transformação - Ctl+a" + +#~ msgid "Toggle center given in selection/desktop coordiantes" +#~ msgstr "Alternar as coordenadas do centro entre selecção e ambiente" + +#~ msgid "Use alignment during transformation" +#~ msgstr "Usar alinhamento durante a transformação" + +#~ msgid "Use center as transformation fixpoint" +#~ msgstr "Usar o centro como eixo de transformação" + +#~ msgid "Y: " +#~ msgstr "Y: " + +#~ msgid "keep aspect" +#~ msgstr "manter aspecto" + +#~ msgid "lock/unlock horizontal and vertical scale" +#~ msgstr "bloquear/desbloquear escala vertical e horizontal" + +#~ msgid "select direction" +#~ msgstr "seleccione a direcção" + +#~ msgid "select direction (horizontal/vertical skew)" +#~ msgstr "seleccionar direcção (inclinamento horizontal/vertical)" + +#~ msgid "select metric for scale" +#~ msgstr "seleccione a unidade para o escalamento" + +#~ msgid "select metric for values" +#~ msgstr "seleccione a unidade para os valores" + +#~ msgid "skew" +#~ msgstr "inclinar" + +#~ msgid "toggle absolute/relative move" +#~ msgstr "alternar movimento absoluto/relativo" + +#~ msgid "toggle absolute/relative scale" +#~ msgstr "alternar escalamento absoluto/relativo" + +#~ msgid "Change Attribute" +#~ msgstr "Alterar atributo" + +#~ msgid "Change Content" +#~ msgstr "Alterar Conteudo" + +#~ msgid "Do you want to delete attribute?" +#~ msgstr "Deseja apagar o atributo?" + +#~ msgid "Element:" +#~ msgstr "Elemento:" + +#~ msgid "Enter element name:" +#~ msgstr "Introduza nome elemento:" + +#~ msgid "Hierarchy" +#~ msgstr "Hierarquia" + +#~ msgid "Key" +#~ msgstr "Chave" + +#~ msgid "New Element" +#~ msgstr "Novo Elemento" + +#~ msgid "Don't save" +#~ msgstr "Não gravar" + +#~ msgid "Ok" +#~ msgstr "Ok" + +#~ msgid "You can't delete 'id' attribute!" +#~ msgstr "Não pode apagar o atributo 'id'!" + +#~ msgid "Do you want to delete attribute %s?" +#~ msgstr "Deseja apagar o atributo %s?" + +#~ msgid "Yes" +#~ msgstr "Sim" + +#~ msgid "No" +#~ msgstr "Não" + +#~ msgid "You can't delete element %s!" +#~ msgstr "Não pode apagar o elemento %s!" + +#~ msgid "Do you want to delete element %s?" +#~ msgstr "Deseja apagar o elemento %s?" + +#~ msgid "You can't cut element %s!" +#~ msgstr "Não pode cortar o elemento %s!" + +#~ msgid "\"" +#~ msgstr "\"" + +#~ msgid "Exported bitmap resolution in pixels per inch (default 72.0)" +#~ msgstr "" +#~ "Resolução do bitmap exportado em pixels por polegada (por omissão 72.0)" + +#~ msgid "Style to change:" +#~ msgstr "Estilo a alterar:" + +#~ msgid "Radial" +#~ msgstr "Radial" + +#~ msgid "Del" +#~ msgstr "Apagar" + +#~ msgid "Dup" +#~ msgstr "Duplicar" + +#~ msgid "Empty" +#~ msgstr "Vazio" + +#~ msgid "Could not initialize Bonobo" +#~ msgstr "Não foi possível inicializar o Bonobo" + +#~ msgid "Exit" +#~ msgstr "Sair" + +#~ msgid "Do not use GUI. NB! if exist, should be FIRST argument!" +#~ msgstr "" +#~ "Não usar o interface gráfico. Atenção! esta opção para funcionar tem que " +#~ "ser a primeira especificada!" + +#~ msgid "Draw ellipse" +#~ msgstr "Desenhar elipse" + +#~ msgid "Choose base unit system for grid" +#~ msgstr "Escolha a unidade base para a grelha" + +#~ msgid "Choose color for grid" +#~ msgstr "Escolha a cor para a grelha" + +#~ msgid "Choose unit system for grid snapping" +#~ msgstr "Escolha a unidade para o ajuste à grelha" + +#~ msgid "Choose unit system for guideline snapping" +#~ msgstr "Escolha a unidade para o ajuste às guias" + +#~ msgid "Set maximum distance for grid snapping" +#~ msgstr "Especifica a distância máxima para o ajuste à grelha" + +#~ msgid "Set maximum distance for guideline snapping" +#~ msgstr "Especifica a distância máxima para o ajuste às guias" + +#~ msgid "Set origin of page coordinate system" +#~ msgstr "Especificar origem das coordenadas da página" + +#~ msgid "Choose paper size" +#~ msgstr "Escolha o tamanho do papel" + +#~ msgid "Choose unit system" +#~ msgstr "Escolha a unidade de medida" + +#~ msgid "Set page height" +#~ msgstr "Alterar altura da página" + +#~ msgid "Millimeters\n" +#~ msgstr "Milímetros\n" + +#~ msgid "Pixels\n" +#~ msgstr "Pixels\n" + +#~ msgid "window2" +#~ msgstr "janela2" + +#~ msgid "First sel" +#~ msgstr "Primeiro seleccionado" diff --git a/po/pt_BR.po b/po/pt_BR.po new file mode 100644 index 000000000..b7e2e41b7 --- /dev/null +++ b/po/pt_BR.po @@ -0,0 +1,10586 @@ +# +# Juarez Rudsatz , 2004 +# +msgid "" +msgstr "" +"Project-Id-Version: Inkscape\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2005-12-04 11:51-0800\n" +"PO-Revision-Date: 2004-07-12 11:55+00:00\n" +"Last-Translator: Juarez Rudsatz \n" +"Language-Team: Brazillian Portuguese \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8-bit\n" + +#: ../inkscape.desktop.in.h:1 +msgid "Create and edit Scalable Vector Graphics images" +msgstr "" + +#: ../inkscape.desktop.in.h:2 +msgid "Inkscape SVG Vector Illustrator" +msgstr "Ilustrador Vetorial em SVG Inkscape " + +#: ../../po/../src/arc-context.cpp:350 +msgid "" +"Ctrl: make circle or integer-ratio ellipse, snap arc/segment angle" +msgstr "" +"Ctrl: faz círculo ou elipse de proporção-inteira, ajusta o ângulo do " +"arco/segmento" + +#: ../../po/../src/arc-context.cpp:351 ../../po/../src/rect-context.cpp:388 +msgid "Shift: draw around the starting point" +msgstr "Shift: desenhar ao redor do ponto inicial" + +#: ../../po/../src/arc-context.cpp:413 +#: ../../po/../src/connector-context.cpp:493 +#: ../../po/../src/dyna-draw-context.cpp:506 +#: ../../po/../src/pen-context.cpp:329 ../../po/../src/pencil-context.cpp:208 +#: ../../po/../src/rect-context.cpp:452 ../../po/../src/spiral-context.cpp:421 +#: ../../po/../src/star-context.cpp:427 +msgid "Current layer is hidden. Unhide it to be able to draw on it." +msgstr "" + +#: ../../po/../src/arc-context.cpp:417 +#: ../../po/../src/connector-context.cpp:497 +#: ../../po/../src/dyna-draw-context.cpp:510 +#: ../../po/../src/pen-context.cpp:336 ../../po/../src/pencil-context.cpp:212 +#: ../../po/../src/rect-context.cpp:456 ../../po/../src/spiral-context.cpp:426 +#: ../../po/../src/star-context.cpp:431 +msgid "Current layer is locked. Unlock it to be able to draw on it." +msgstr "" + +#: ../../po/../src/arc-context.cpp:496 +#, fuzzy, c-format +msgid "" +"Ellipse: %s × %s; with Ctrl to make circle or integer-" +"ratio ellipse; with Shift to draw around the starting point" +msgstr "" +"Elipse: %s x %s; com Ctrl para fazer círculo ou elipse de " +"proporção-inteira; com Shift para desenhar ao redor do ponto inicial" + +#: ../../po/../src/connector-context.cpp:518 +#, fuzzy +msgid "Creating new connector" +msgstr "Criando nova curva" + +#: ../../po/../src/connector-context.cpp:939 +#, fuzzy +msgid "Finishing connector" +msgstr "Finalizando caneta" + +#: ../../po/../src/connector-context.cpp:1108 +msgid "Connection point: click or drag to create a new connector" +msgstr "" + +#: ../../po/../src/connector-context.cpp:1185 +msgid "Connector endpoint: drag to reroute or connect to new shapes" +msgstr "" + +#: ../../po/../src/connector-context.cpp:1278 +#, fuzzy +msgid "Select at least one non-connector object." +msgstr "Selecione pelo menos dois objetos para agrupar." + +#: ../../po/../src/desktop-events.cpp:238 +#, c-format +msgid "%s at %s" +msgstr "%s em %s" + +#. TRANSLATORS: This string appears when double-clicking on a guide. +#. This is the distance by which the guide is to be moved. +#: ../../po/../src/desktop-events.cpp:277 +msgid " relative by " +msgstr " relativo em " + +#. TRANSLATORS: This string appears when double-clicking on a guide. +#. This is the target location where the guide is to be moved. +#: ../../po/../src/desktop-events.cpp:282 +#: ../../po/../src/desktop-events.cpp:395 +msgid " absolute to " +msgstr " absoluto à " + +#. create dialog +#: ../../po/../src/desktop-events.cpp:348 +msgid "Guideline" +msgstr "Linha guia" + +#: ../../po/../src/desktop-events.cpp:432 +#, c-format +msgid "Move %s" +msgstr "Mover %s" + +#: ../../po/../src/desktop.cpp:678 +msgid "No previous zoom." +msgstr "Nenhuma ampliação anterior" + +#: ../../po/../src/desktop.cpp:703 +msgid "No next zoom." +msgstr "Nenhuma ampliação posterior" + +#: ../../po/../src/dialogs/clonetiler.cpp:182 +#, fuzzy +msgid "Nothing selected." +msgstr "Nada foi apagado." + +#: ../../po/../src/dialogs/clonetiler.cpp:188 +#, fuzzy +msgid "More than one object selected." +msgstr "" +"Mais de um objeto selecionado. Não é possível obter o estilo a partir " +"de múltiplos objetos." + +#: ../../po/../src/dialogs/clonetiler.cpp:195 +#, c-format +msgid "Object has %d tiled clones." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:200 +msgid "Object has no tiled clones." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:865 +#, fuzzy +msgid "Select one object whose tiled clones to unclump." +msgstr "Selecione um objeto para clonar." + +#: ../../po/../src/dialogs/clonetiler.cpp:916 +#, fuzzy +msgid "Select one object whose tiled clones to remove." +msgstr "Selecione um objeto para clonar." + +#: ../../po/../src/dialogs/clonetiler.cpp:984 +#: ../../po/../src/selection-chemistry.cpp:1774 +msgid "Select an object to clone." +msgstr "Selecione um objeto para clonar." + +#: ../../po/../src/dialogs/clonetiler.cpp:990 +#: ../../po/../src/selection-chemistry.cpp:1780 +msgid "" +"If you want to clone several objects, group them and clone the " +"group." +msgstr "" +"Se você quiser clonar diversos objetos, agrupe-os e clone o grupo." + +#: ../../po/../src/dialogs/clonetiler.cpp:1484 +msgid "Per row:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1497 +#, fuzzy +msgid "Per column:" +msgstr "Nenhum gradiente selecionado" + +#: ../../po/../src/dialogs/clonetiler.cpp:1505 +#, fuzzy +msgid "Randomize:" +msgstr "Nada" + +#: ../../po/../src/dialogs/clonetiler.cpp:1656 +#, fuzzy +msgid "_Symmetry" +msgstr "simétrico" + +#. TRANSLATORS: For the following 17 symmetry groups, see +#. * http://www.bib.ulb.ac.be/coursmath/doc/17.htm (visual examples); +#. * http://www.clarku.edu/~djoyce/wallpaper/seventeen.html (English vocabulary); or +#. * http://membres.lycos.fr/villemingerard/Geometri/Sym1D.htm (French vocabulary). +#. +#: ../../po/../src/dialogs/clonetiler.cpp:1664 +msgid "Select one of the 17 symmetry groups for the tiling" +msgstr "" + +#. TRANSLATORS: "translation" means "shift" / "displacement" here. +#: ../../po/../src/dialogs/clonetiler.cpp:1675 +msgid "P1: simple translation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1676 +msgid "P2: 180° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1677 +msgid "PM: reflection" +msgstr "" + +#. TRANSLATORS: "glide reflection" is a reflection and a translation combined. +#. For more info, see http://mathforum.org/sum95/suzanne/symsusan.html +#: ../../po/../src/dialogs/clonetiler.cpp:1680 +msgid "PG: glide reflection" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1681 +msgid "CM: reflection + glide reflection" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1682 +msgid "PMM: reflection + reflection" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1683 +msgid "PMG: reflection + 180° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1684 +msgid "PGG: glide reflection + 180° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1685 +msgid "CMM: reflection + reflection + 180° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1686 +msgid "P4: 90° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1687 +msgid "P4M: 90° rotation + 45° reflection" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1688 +msgid "P4G: 90° rotation + 90° reflection" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1689 +msgid "P3: 120° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1690 +msgid "P31M: reflection + 120° rotation, dense" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1691 +msgid "P3M1: reflection + 120° rotation, sparse" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1692 +msgid "P6: 60° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1693 +msgid "P6M: reflection + 60° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1721 +msgid "S_hift" +msgstr "" + +#. TRANSLATORS: "shift" means: the tiles will be shifted (offset) horizontally by this amount +#: ../../po/../src/dialogs/clonetiler.cpp:1731 +#, fuzzy, no-c-format +msgid "Shift X:" +msgstr "Modificado:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1739 +#, no-c-format +msgid "Horizontal shift per row (in % of tile width)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1747 +#, no-c-format +msgid "Horizontal shift per column (in % of tile width)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1754 +msgid "Randomize the horizontal shift by this percentage" +msgstr "" + +#. TRANSLATORS: "shift" means: the tiles will be shifted (offset) vertically by this amount +#: ../../po/../src/dialogs/clonetiler.cpp:1764 +#, fuzzy, no-c-format +msgid "Shift Y:" +msgstr "Modificado:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1772 +#, no-c-format +msgid "Vertical shift per row (in % of tile height)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1780 +#, no-c-format +msgid "Vertical shift per column (in % of tile height)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1787 +msgid "Randomize the vertical shift by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1795 +#, fuzzy +msgid "Exponent:" +msgstr "Modificado:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1802 +msgid "Whether rows are spaced evenly (1), converge (<1) or diverge (>1)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1809 +msgid "Whether columns are spaced evenly (1), converge (<1) or diverge (>1)" +msgstr "" + +#. TRANSLATORS: "Alternate" is a verb here +#: ../../po/../src/dialogs/clonetiler.cpp:1817 +#: ../../po/../src/dialogs/clonetiler.cpp:1907 +#: ../../po/../src/dialogs/clonetiler.cpp:1966 +#: ../../po/../src/dialogs/clonetiler.cpp:2022 +#: ../../po/../src/dialogs/clonetiler.cpp:2153 +msgid "Alternate:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1823 +msgid "Alternate the sign of shifts for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1828 +msgid "Alternate the sign of shifts for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1837 +#, fuzzy +msgid "Sc_ale" +msgstr "Ampliar" + +#: ../../po/../src/dialogs/clonetiler.cpp:1845 +#, fuzzy +msgid "Scale X:" +msgstr "Círculo" + +#: ../../po/../src/dialogs/clonetiler.cpp:1853 +#, fuzzy, no-c-format +msgid "Horizontal scale per row (in % of tile width)" +msgstr "Coordenada horizontal da seleção" + +#: ../../po/../src/dialogs/clonetiler.cpp:1861 +#, fuzzy, no-c-format +msgid "Horizontal scale per column (in % of tile width)" +msgstr "Coordenada horizontal da seleção" + +#: ../../po/../src/dialogs/clonetiler.cpp:1868 +msgid "Randomize the horizontal scale by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1876 +#, fuzzy +msgid "Scale Y:" +msgstr "Círculo" + +#: ../../po/../src/dialogs/clonetiler.cpp:1884 +#, no-c-format +msgid "Vertical scale per row (in % of tile height)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1892 +#, no-c-format +msgid "Vertical scale per column (in % of tile height)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1899 +msgid "Randomize the vertical scale by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1913 +msgid "Alternate the sign of scales for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1918 +#, fuzzy +msgid "Alternate the sign of scales for each column" +msgstr "Coordenada horizontal da seleção" + +#: ../../po/../src/dialogs/clonetiler.cpp:1927 +#, fuzzy +msgid "_Rotation" +msgstr "Relação" + +#: ../../po/../src/dialogs/clonetiler.cpp:1935 +#, fuzzy +msgid "Angle:" +msgstr "Modificado:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1943 +#, no-c-format +msgid "Rotate tiles by this angle for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1951 +#, no-c-format +msgid "Rotate tiles by this angle for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1958 +msgid "Randomize the rotation angle by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1972 +msgid "Alternate the rotation direction for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1977 +msgid "Alternate the rotation direction for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1985 +msgid "_Opacity" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1993 +#, fuzzy +msgid "Fade out:" +msgstr "Modificado:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2000 +msgid "Decrease tile opacity by this percentage for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2007 +msgid "Decrease tile opacity by this percentage for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2014 +msgid "Randomize the tile opacity by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2028 +msgid "Alternate the sign of opacity change for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2033 +msgid "Alternate the sign of opacity change for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2041 +#, fuzzy +msgid "Co_lor" +msgstr "Cores" + +#: ../../po/../src/dialogs/clonetiler.cpp:2046 +#, fuzzy +msgid "Initial color: " +msgstr "Escolha de cores:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2050 +msgid "Initial color of tiled clones" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2050 +msgid "" +"Initial color for clones (works only if the original has unset fill or " +"stroke)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2065 +#, fuzzy +msgid "H:" +msgstr "Novo:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2072 +msgid "Change the tile hue by this percentage for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2079 +msgid "Change the tile hue by this percentage for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2086 +msgid "Randomize the tile hue by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2095 +#, fuzzy +msgid "S:" +msgstr "Novo:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2102 +msgid "Change the color saturation by this percentage for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2109 +msgid "Change the color saturation by this percentage for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2116 +msgid "Randomize the color saturation by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2124 +#, fuzzy +msgid "L:" +msgstr "Novo:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2131 +msgid "Change the color lightness by this percentage for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2138 +msgid "Change the color lightness by this percentage for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2145 +msgid "Randomize the color lightness by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2159 +msgid "Alternate the sign of color changes for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2164 +msgid "Alternate the sign of color changes for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2172 +msgid "_Trace" +msgstr "_Traçar" + +#: ../../po/../src/dialogs/clonetiler.cpp:2179 +msgid "Trace the drawing under the tiles" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2183 +msgid "" +"For each clone, pick a value from the drawing in that clone's location and " +"apply it to the clone" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2197 +msgid "1. Pick from the drawing:" +msgstr "" + +#. ----Hbox2 +#: ../../po/../src/dialogs/clonetiler.cpp:2208 +#: ../../po/../src/dialogs/clonetiler.cpp:2355 +#: ../../po/../src/ui/dialog/tracedialog.cpp:445 +#, fuzzy +msgid "Color" +msgstr "Cores" + +#: ../../po/../src/dialogs/clonetiler.cpp:2209 +#, fuzzy +msgid "Pick the visible color and opacity" +msgstr "Escolha a cor visível (nenhum alfa)" + +#: ../../po/../src/dialogs/clonetiler.cpp:2216 +#: ../../po/../src/dialogs/clonetiler.cpp:2365 +#: ../share/extensions/dropshadow.inx.h:3 +msgid "Opacity" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2217 +msgid "Pick the total accumulated opacity" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2224 +#, fuzzy +msgid "R" +msgstr "_R" + +#: ../../po/../src/dialogs/clonetiler.cpp:2225 +msgid "Pick the Red component of the color" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2232 +#, fuzzy +msgid "G" +msgstr "_G" + +#: ../../po/../src/dialogs/clonetiler.cpp:2233 +msgid "Pick the Green component of the color" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2240 +#, fuzzy +msgid "B" +msgstr "_B" + +#: ../../po/../src/dialogs/clonetiler.cpp:2241 +msgid "Pick the Blue component of the color" +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2250 +msgid "clonetiler|H" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2251 +#, fuzzy +msgid "Pick the hue of the color" +msgstr "Número de revoluções" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2260 +msgid "clonetiler|S" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2261 +msgid "Pick the saturation of the color" +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2270 +msgid "clonetiler|L" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2271 +msgid "Pick the lightness of the color" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2281 +msgid "2. Tweak the picked value:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2291 +msgid "Gamma-correct:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2296 +msgid "Shift the mid-range of the picked value upwards (>0) or downwards (<0)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2303 +#, fuzzy +msgid "Randomize:" +msgstr "Aleatorização:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2308 +msgid "Randomize the picked value by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2315 +#, fuzzy +msgid "Invert:" +msgstr "Inverter" + +#: ../../po/../src/dialogs/clonetiler.cpp:2319 +msgid "Invert the picked value" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2325 +msgid "3. Apply the value to the clones':" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2335 +#, fuzzy +msgid "Presence" +msgstr "Preservada" + +#: ../../po/../src/dialogs/clonetiler.cpp:2338 +msgid "" +"Each clone is created with the probability determined by the picked value in " +"that point" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2345 +#, fuzzy +msgid "Size" +msgstr "Lados:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2348 +msgid "Each clone's size is determined by the picked value in that point" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2358 +msgid "" +"Each clone is painted by the picked color (the original must have unset fill " +"or stroke)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2368 +msgid "Each clone's opacity is determined by the picked value in that point" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2395 +msgid "How many rows in the tiling" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2415 +msgid "How many columns in the tiling" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2445 +msgid "Width of the rectangle to be filled" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2470 +msgid "Height of the rectangle to be filled" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2485 +#, fuzzy +msgid "Rows, columns: " +msgstr "Círculo" + +#: ../../po/../src/dialogs/clonetiler.cpp:2486 +msgid "Create the specified number of rows and columns" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2495 +msgid "Width, height: " +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2496 +msgid "Fill the specified width and height with the tiling" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2512 +msgid "Use saved size and position of the tile" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2515 +msgid "" +"Pretend that the size and position of the tile are the same as the last time " +"you tiled it (if any), instead of using the current size" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2539 +#, fuzzy +msgid " _Create " +msgstr "Círculo" + +#: ../../po/../src/dialogs/clonetiler.cpp:2541 +msgid "Create and tile the clones of the selection" +msgstr "" + +#. TRANSLATORS: if a group of objects are "clumped" together, then they +#. are unevenly spread in the given amount of space - as shown in the +#. diagrams on the left in the following screenshot: +#. http://www.inkscape.org/screenshots/gallery/inkscape-0.42-CVS-tiles-unclump.png +#. So unclumping is the process of spreading a number of objects out more evenly. +#: ../../po/../src/dialogs/clonetiler.cpp:2556 +msgid " _Unclump " +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2557 +msgid "Spread out clones to reduce clumping; can be applied repeatedly" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2563 +#, fuzzy +msgid " Re_move " +msgstr "_Remover Ligação" + +#: ../../po/../src/dialogs/clonetiler.cpp:2564 +#, fuzzy +msgid "Remove existing tiled clones of the selected object (siblings only)" +msgstr "" +"Lembrar do estilo do (primeiro) objeto selecionado como estilo desta " +"ferramenta" + +#: ../../po/../src/dialogs/clonetiler.cpp:2580 +#, fuzzy +msgid " R_eset " +msgstr "_Remover Ligação" + +#. TRANSLATORS: "change" is a noun here +#: ../../po/../src/dialogs/clonetiler.cpp:2582 +msgid "" +"Reset all shifts, scales, rotates, opacity and color changes in the dialog " +"to zero" +msgstr "" + +#: ../../po/../src/dialogs/color-picker.cpp:280 +msgid "Close" +msgstr "Fechar" + +#: ../../po/../src/dialogs/debugdialog.cpp:138 +msgid "Messages" +msgstr "Mensagens" + +#. ## Add a menu for clear() +#: ../../po/../src/dialogs/debugdialog.cpp:144 +#: ../../po/../src/menus-skeleton.h:16 +#: ../../po/../src/ui/dialog/messages.cpp:56 +#: ../../po/../src/ui/dialog/scriptdialog.cpp:181 +msgid "_File" +msgstr "_Arquivo" + +#. TRANSLATORS: "Clear" is a verb here +#: ../../po/../src/dialogs/debugdialog.cpp:145 +#: ../../po/../src/dialogs/find.cpp:753 +#: ../../po/../src/ui/dialog/messages.cpp:57 +#: ../../po/../src/ui/dialog/scriptdialog.cpp:182 +msgid "_Clear" +msgstr "Li_mpar" + +#: ../../po/../src/dialogs/debugdialog.cpp:147 +#: ../../po/../src/ui/dialog/messages.cpp:59 +#, fuzzy +msgid "Capture log messages" +msgstr "Ver mensagens de depuração" + +#: ../../po/../src/dialogs/debugdialog.cpp:149 +#: ../../po/../src/ui/dialog/messages.cpp:61 +#, fuzzy +msgid "Release log messages" +msgstr "Ver mensagens de depuração" + +#. Notebook tab +#: ../../po/../src/dialogs/desktop-properties.cpp:909 +#: ../../po/../src/ui/dialog/document-preferences.cpp:89 +#: ../../po/../src/ui/widget/panel.cpp:107 +msgid "Grid" +msgstr "Grade" + +#. Checkbuttons +#. / \todo FIXME: gray out snapping when grid is off +#. / \todo FIXME: gray out snapping when grid is off. +#. / Dissenting view: you want snapping without grid. +#: ../../po/../src/dialogs/desktop-properties.cpp:917 +#: ../../po/../src/ui/dialog/document-preferences.cpp:179 +msgid "Show grid" +msgstr "Mostrar grade" + +#: ../../po/../src/dialogs/desktop-properties.cpp:917 +#: ../../po/../src/ui/dialog/document-preferences.cpp:179 +#: ../../po/../src/verbs.cpp:2115 +msgid "Show or hide grid" +msgstr "Mostrar ou esconder a grade da tela" + +#: ../../po/../src/dialogs/desktop-properties.cpp:918 +#: ../../po/../src/ui/dialog/document-preferences.cpp:180 +msgid "Snap bounding boxes to grid" +msgstr "Ajustar as bordas de limite na grade" + +#: ../../po/../src/dialogs/desktop-properties.cpp:918 +#: ../../po/../src/dialogs/desktop-properties.cpp:1001 +#: ../../po/../src/ui/dialog/document-preferences.cpp:181 +#: ../../po/../src/ui/dialog/document-preferences.cpp:236 +#, fuzzy +msgid "Snap the edges of the object bounding boxes" +msgstr "Cada objeto selecionado exibe sua caixa de limites" + +#: ../../po/../src/dialogs/desktop-properties.cpp:919 +#: ../../po/../src/ui/dialog/document-preferences.cpp:183 +#, fuzzy +msgid "Snap nodes to grid" +msgstr "Ajustar os pontos na grade" + +#: ../../po/../src/dialogs/desktop-properties.cpp:919 +#: ../../po/../src/dialogs/desktop-properties.cpp:1002 +#: ../../po/../src/ui/dialog/document-preferences.cpp:184 +#: ../../po/../src/ui/dialog/document-preferences.cpp:239 +msgid "Snap path nodes, text baselines, ellipse centers, etc." +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:937 +#: ../../po/../src/ui/dialog/document-preferences.cpp:186 +msgid "Grid units:" +msgstr "Unidade da grade:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:939 +#: ../../po/../src/ui/dialog/document-preferences.cpp:187 +msgid "Origin X:" +msgstr "X Original:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:942 +#: ../../po/../src/ui/dialog/document-preferences.cpp:189 +msgid "Origin Y:" +msgstr "Y Original:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:945 +#: ../../po/../src/ui/dialog/document-preferences.cpp:191 +msgid "Spacing X:" +msgstr "Espaçamento X:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:948 +#: ../../po/../src/ui/dialog/document-preferences.cpp:193 +msgid "Spacing Y:" +msgstr "Espaçamento Y:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:952 +#: ../../po/../src/dialogs/desktop-properties.cpp:1013 +#: ../../po/../src/ui/dialog/document-preferences.cpp:195 +#: ../../po/../src/ui/dialog/document-preferences.cpp:241 +msgid "Snap units:" +msgstr "Unidades de ajuste:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:955 +#: ../../po/../src/dialogs/desktop-properties.cpp:1016 +#: ../../po/../src/ui/dialog/document-preferences.cpp:196 +#: ../../po/../src/ui/dialog/document-preferences.cpp:242 +msgid "Snap distance:" +msgstr "Distância do ajuste:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:958 +#: ../../po/../src/ui/dialog/document-preferences.cpp:199 +#, fuzzy +msgid "Grid line color:" +msgstr "Cor da linha guia" + +#: ../../po/../src/dialogs/desktop-properties.cpp:959 +#: ../../po/../src/ui/dialog/document-preferences.cpp:199 +#, fuzzy +msgid "Grid line color" +msgstr "Cor da linha guia" + +#: ../../po/../src/dialogs/desktop-properties.cpp:959 +#: ../../po/../src/ui/dialog/document-preferences.cpp:200 +#, fuzzy +msgid "Color of grid lines" +msgstr "Espaçamento da linha de grade maior:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:961 +#: ../../po/../src/ui/dialog/document-preferences.cpp:201 +msgid "Major grid line color:" +msgstr "Cor da linha de grade maior:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:962 +#: ../../po/../src/ui/dialog/document-preferences.cpp:201 +#, fuzzy +msgid "Major grid line color" +msgstr "Cor da linha de grade maior:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:962 +#: ../../po/../src/ui/dialog/document-preferences.cpp:202 +msgid "Color of the major (highlighted) grid lines" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:965 +#: ../../po/../src/ui/dialog/document-preferences.cpp:204 +#, fuzzy +msgid "Major grid line every:" +msgstr "Cor da linha de grade maior:" + +#. TRANSLATORS: This belongs to the "Major grid line every:" string, +#. see grid settings in the "Document Preferences" dialog +#: ../../po/../src/dialogs/desktop-properties.cpp:977 +#: ../../po/../src/ui/dialog/document-preferences.cpp:204 +msgid "lines" +msgstr "linhas" + +#. Guidelines page +#: ../../po/../src/dialogs/desktop-properties.cpp:991 +#: ../../po/../src/ui/dialog/document-preferences.cpp:90 +msgid "Guides" +msgstr "Guias" + +#. / \todo FIXME: gray out snapping when guides are off +#. / Dissenting view: you want snapping without guides. +#: ../../po/../src/dialogs/desktop-properties.cpp:1000 +#: ../../po/../src/ui/dialog/document-preferences.cpp:234 +msgid "Show guides" +msgstr "Mostrar guias" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1000 +#: ../../po/../src/ui/dialog/document-preferences.cpp:234 +#: ../../po/../src/verbs.cpp:2116 +msgid "Show or hide guides" +msgstr "Mostrar ou esconder as guias" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1001 +#: ../../po/../src/ui/dialog/document-preferences.cpp:235 +msgid "Snap bounding boxes to guides" +msgstr "Ajustar bordas de limite às guias" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1002 +#: ../../po/../src/ui/dialog/document-preferences.cpp:238 +msgid "Snap points to guides" +msgstr "Ajustar pontos às guias" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1020 +#: ../../po/../src/ui/dialog/document-preferences.cpp:243 +msgid "Guide color:" +msgstr "Cor das guias:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1021 +#: ../../po/../src/ui/dialog/document-preferences.cpp:243 +msgid "Guideline color" +msgstr "Cor da linha guia" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1021 +#: ../../po/../src/ui/dialog/document-preferences.cpp:244 +#, fuzzy +msgid "Color of guidelines" +msgstr "linha guia horizontal" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1023 +#: ../../po/../src/ui/dialog/document-preferences.cpp:245 +msgid "Highlight color:" +msgstr "Cor de Destaque:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1024 +#: ../../po/../src/ui/dialog/document-preferences.cpp:245 +msgid "Highlighted guideline color" +msgstr "Cor da linha guia destacada" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1024 +#: ../../po/../src/ui/dialog/document-preferences.cpp:246 +msgid "Color of a guideline when it is under mouse" +msgstr "" + +#. Page page +#: ../../po/../src/dialogs/desktop-properties.cpp:1029 +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:855 +#: ../../po/../src/ui/dialog/document-preferences.cpp:88 +#: ../../po/../src/widgets/desktop-widget.cpp:1061 +msgid "Page" +msgstr "Página" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1039 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +#, fuzzy +msgid "Background:" +msgstr "Cor de plano de fundo" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1040 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +msgid "Background color" +msgstr "Cor de plano de fundo" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1041 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +msgid "" +"Color and transparency of the page background (also used for bitmap export)" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1045 +#: ../../po/../src/ui/dialog/document-preferences.cpp:147 +#, fuzzy +msgid "Show page border" +msgstr "Mostrar bordas da tela" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1049 +#: ../../po/../src/ui/dialog/document-preferences.cpp:148 +msgid "Border on top of drawing" +msgstr "Bordas no topo do desenho" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1052 +#: ../../po/../src/ui/dialog/document-preferences.cpp:149 +#, fuzzy +msgid "Border color:" +msgstr "Cor das bordas" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1053 +#: ../../po/../src/ui/dialog/document-preferences.cpp:149 +#, fuzzy +msgid "Page border color" +msgstr "Cor das bordas da tela" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1054 +#: ../../po/../src/ui/dialog/document-preferences.cpp:150 +#, fuzzy +msgid "Color of the page border" +msgstr "Mostrar bordas da tela" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1059 +#: ../../po/../src/ui/dialog/document-preferences.cpp:152 +msgid "Show page shadow" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1063 +#: ../../po/../src/ui/dialog/document-preferences.cpp:153 +#, fuzzy +msgid "Default units:" +msgstr "Padrões" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1069 +msgid "Units for the tool controls, ruler, and the statusbar" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1086 +#: ../../po/../src/ui/widget/page-sizer.cpp:209 +#, fuzzy +msgid "Page size:" +msgstr "Tamanho da tela" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1110 +#: ../../po/../src/ui/widget/page-sizer.cpp:219 +msgid "Custom" +msgstr "Personalizado" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1121 +#: ../../po/../src/ui/widget/page-sizer.cpp:225 +#, fuzzy +msgid "Page orientation:" +msgstr "Orientação da tela:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1133 +#: ../../po/../src/ui/widget/page-sizer.cpp:232 +msgid "Landscape" +msgstr "Paisagem" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1139 +#: ../../po/../src/ui/widget/page-sizer.cpp:234 +msgid "Portrait" +msgstr "Retrato" + +#. Custom paper frame +#: ../../po/../src/dialogs/desktop-properties.cpp:1148 +#: ../../po/../src/ui/widget/page-sizer.cpp:249 +#, fuzzy +msgid "Custom size" +msgstr "Personalizado" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1160 +#: ../../po/../src/dialogs/export.cpp:269 +#: ../../po/../src/ui/widget/page-sizer.cpp:261 +msgid "Units:" +msgstr "Unidades:" + +#. Stroke width +#: ../../po/../src/dialogs/desktop-properties.cpp:1162 +#: ../../po/../src/dialogs/export.cpp:310 +#: ../../po/../src/dialogs/object-attributes.cpp:55 +#: ../../po/../src/dialogs/stroke-style.cpp:985 +#: ../../po/../src/ui/widget/page-sizer.cpp:262 +#: ../../po/../src/widgets/toolbox.cpp:1957 +msgid "Width:" +msgstr "Largura:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1183 +#: ../../po/../src/dialogs/export.cpp:326 +#: ../../po/../src/dialogs/export.cpp:431 +#: ../../po/../src/dialogs/object-attributes.cpp:56 +#: ../../po/../src/ui/widget/page-sizer.cpp:263 +msgid "Height:" +msgstr "Altura:" + +#. +#. * Ownership metadata tab +#. +#: ../../po/../src/dialogs/desktop-properties.cpp:1206 +msgid "Metadata" +msgstr "Metadados" + +#. add license selector pull-down +#: ../../po/../src/dialogs/desktop-properties.cpp:1225 +msgid "License" +msgstr "Licensa" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1255 +msgid "Proprietary" +msgstr "Proprietário" + +#: ../../po/../src/dialogs/display-settings.cpp:212 +msgid "When transforming, show:" +msgstr "Enquanto tranformar, mostrar:" + +#: ../../po/../src/dialogs/display-settings.cpp:223 +msgid "Objects" +msgstr "Objetos" + +#: ../../po/../src/dialogs/display-settings.cpp:224 +msgid "Show the actual objects when moving or transforming" +msgstr "Mostrar os objetos atuais quando mover ou transformar" + +#: ../../po/../src/dialogs/display-settings.cpp:231 +msgid "Box outline" +msgstr "Contorno da caixa" + +#: ../../po/../src/dialogs/display-settings.cpp:232 +msgid "Show only a box outline of the objects when moving or transforming" +msgstr "" +"Mostrar somente um contorno de caixa dos objetos quando mover ou transformar" + +#: ../../po/../src/dialogs/display-settings.cpp:238 +msgid "Per-object selection cue:" +msgstr "Taco de seleção por objeto:" + +#. sorationsnapsperpi == 0 means no snapping +#: ../../po/../src/dialogs/display-settings.cpp:249 +#: ../../po/../src/dialogs/display-settings.cpp:386 +#: ../../po/../src/dialogs/display-settings.cpp:441 +#: ../../po/../src/dialogs/display-settings.cpp:1482 +#: ../../po/../src/dialogs/stroke-style.cpp:791 +#: ../../po/../src/interface.cpp:741 +#: ../../po/../src/ui/widget/selected-style.cpp:100 +#: ../../po/../src/verbs.cpp:1842 +msgid "None" +msgstr "Nenhum" + +#: ../../po/../src/dialogs/display-settings.cpp:250 +msgid "No per-object selection indication" +msgstr "Nenhuma indicação de seleção por objeto" + +#: ../../po/../src/dialogs/display-settings.cpp:256 +msgid "Mark" +msgstr "Marca" + +#: ../../po/../src/dialogs/display-settings.cpp:257 +msgid "Each selected object has a diamond mark in the top left corner" +msgstr "" +"Cada objeto selecionado tem um marca de diamante no canto esquerdo superior" + +#: ../../po/../src/dialogs/display-settings.cpp:264 +msgid "Box" +msgstr "Caixa" + +#: ../../po/../src/dialogs/display-settings.cpp:265 +msgid "Each selected object displays its bounding box" +msgstr "Cada objeto selecionado exibe sua caixa de limites" + +#: ../../po/../src/dialogs/display-settings.cpp:270 +msgid "Default scale origin:" +msgstr "Origem da escala padrão:" + +#: ../../po/../src/dialogs/display-settings.cpp:281 +msgid "Opposite bounding box edge" +msgstr "Margem oposta da caixa de limites" + +#: ../../po/../src/dialogs/display-settings.cpp:282 +msgid "Default scale origin will be on the bounding box of the item" +msgstr "A origem da escala padrão será na caixa de limites do item" + +#: ../../po/../src/dialogs/display-settings.cpp:288 +msgid "Farthest opposite node" +msgstr "Nó oposto mais distante" + +#: ../../po/../src/dialogs/display-settings.cpp:289 +msgid "Default scale origin will be on the bounding box of the item's points" +msgstr "A origem da escala padrão será na caixa de limite dos pontos do item" + +#: ../../po/../src/dialogs/display-settings.cpp:341 +msgid "degrees" +msgstr "graus" + +#: ../../po/../src/dialogs/display-settings.cpp:350 +msgid "" +"Rotating with Ctrl pressed snaps every that much degrees; also, pressing " +"[ or ] rotates by this amount" +msgstr "" +"Girando com Ctrl pressionado ajusta cada um neste ângulo. Pressionando, " +"também, [ ou ] gira nesta proporção" + +#: ../../po/../src/dialogs/display-settings.cpp:407 +msgid "Rotation snaps every:" +msgstr "Ajuste de giro a cada:" + +#: ../../po/../src/dialogs/display-settings.cpp:430 +msgid "" +"None: dialogs are treated as regular windows; Normal: dialogs stay on top of " +"document windows; Aggressive: same as Normal but may work better with some " +"window managers." +msgstr "" +"Nenhum: janelas são tratadas como janelas normais. Normal: janelas ficam no " +"topo de janelas de desenho; Agressivo: o mesmo que Normal porém funciona " +"melhor com alguns gerenciadores de janela." + +#: ../../po/../src/dialogs/display-settings.cpp:451 +msgid "Normal" +msgstr "Normal" + +#: ../../po/../src/dialogs/display-settings.cpp:461 +msgid "Aggressive" +msgstr "Agressivo" + +#: ../../po/../src/dialogs/display-settings.cpp:475 +msgid "Dialogs on top:" +msgstr "Janelas no top:" + +#: ../../po/../src/dialogs/display-settings.cpp:645 +msgid "Show selection cue" +msgstr "Mostrar taco de seleção" + +#: ../../po/../src/dialogs/display-settings.cpp:646 +msgid "" +"Whether selected objects display a selection cue (the same as in selector)" +msgstr "" +"Se os objetos selecionados exibem um taco de seleção (o mesmo do seletor)" + +#: ../../po/../src/dialogs/display-settings.cpp:657 +#, fuzzy +msgid "Enable gradient editing" +msgstr "Editor de Gradiente" + +#: ../../po/../src/dialogs/display-settings.cpp:658 +#, fuzzy +msgid "Whether selected objects display gradient editing controls" +msgstr "" +"Se os objetos selecionados exibem um taco de seleção (o mesmo do seletor)" + +#: ../../po/../src/dialogs/display-settings.cpp:719 +msgid "No objects selected to take the style from." +msgstr "Nenhum objeto selecionado para obter o estilo." + +#: ../../po/../src/dialogs/display-settings.cpp:728 +msgid "" +"More than one object selected. Cannot take style from multiple " +"objects." +msgstr "" +"Mais de um objeto selecionado. Não é possível obter o estilo a partir " +"de múltiplos objetos." + +#: ../../po/../src/dialogs/display-settings.cpp:767 +msgid "Create new objects with:" +msgstr "Criar novos objetos com:" + +#: ../../po/../src/dialogs/display-settings.cpp:777 +msgid "Take from selection" +msgstr "Obter da seleção" + +#: ../../po/../src/dialogs/display-settings.cpp:778 +msgid "Remember the style of the (first) selected object as this tool's style" +msgstr "" +"Lembrar do estilo do (primeiro) objeto selecionado como estilo desta " +"ferramenta" + +#: ../../po/../src/dialogs/display-settings.cpp:782 +#, fuzzy +msgid "Last used style" +msgstr "Colar E_stilo" + +#: ../../po/../src/dialogs/display-settings.cpp:782 +msgid "Apply the style you last set on an object" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:790 +msgid "This tool's own style:" +msgstr "O estilo próprio desta ferramenta:" + +#: ../../po/../src/dialogs/display-settings.cpp:790 +msgid "" +"Each tool may store its own style to apply to the newly created objects. Use " +"the button below to set it." +msgstr "" +"Cada ferramenta deve guardar seu próprio estilo para aplicar para objetos " +"recémcriados. Use o botão abaixo para ajustá-lo." + +#. Mouse +#: ../../po/../src/dialogs/display-settings.cpp:877 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:55 +msgid "Mouse" +msgstr "Mouse" + +#. TRANSLATORS: "Grab" is a noun here. "Grab sensitivity" is intended to mean how +#. * close on the screen you need to be to an object to be able to grab it with mouse (in +#. * pixels). +#: ../../po/../src/dialogs/display-settings.cpp:883 +msgid "Grab sensitivity:" +msgstr "Sensibilidade de agarrar:" + +#: ../../po/../src/dialogs/display-settings.cpp:884 +#, fuzzy +msgid "" +"How close on the screen you need to be to an object to be able to grab it " +"with mouse (in screen pixels)" +msgstr "" +"Quão perto da tela é preciso que o de um objeto esteja para ser " +"possívelagarrá-lo com o mouse (em pixels)" + +#: ../../po/../src/dialogs/display-settings.cpp:885 +#: ../../po/../src/dialogs/display-settings.cpp:897 +#: ../../po/../src/dialogs/display-settings.cpp:912 +#: ../../po/../src/dialogs/display-settings.cpp:930 +#: ../../po/../src/dialogs/display-settings.cpp:970 +msgid "pixels" +msgstr "pixels" + +#: ../../po/../src/dialogs/display-settings.cpp:895 +msgid "Click/drag threshold:" +msgstr "Limiar para clicar/arrastar:" + +#: ../../po/../src/dialogs/display-settings.cpp:896 +msgid "" +"Maximum mouse drag (in screen pixels) which is considered a click, not a drag" +msgstr "" +"Arrasto máximo do mouse (em pixels) que é considerado um clicar e não " +"arrastar" + +#. Scrolling +#: ../../po/../src/dialogs/display-settings.cpp:907 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:56 +msgid "Scrolling" +msgstr "Rolagem" + +#: ../../po/../src/dialogs/display-settings.cpp:910 +msgid "Mouse wheel scrolls by:" +msgstr "A roda do mouse rola em:" + +#: ../../po/../src/dialogs/display-settings.cpp:911 +msgid "" +"One mouse wheel notch scrolls by this distance in screen pixels " +"(horizontally with Shift)" +msgstr "" +"Uma roda do mouse rola por esta distância em pixels da tela (horizontalmente " +"com Shift)" + +#: ../../po/../src/dialogs/display-settings.cpp:920 +msgid "Ctrl+arrows" +msgstr "Ctrl+setas" + +#: ../../po/../src/dialogs/display-settings.cpp:928 +msgid "Scroll by:" +msgstr "Rolar em:" + +#: ../../po/../src/dialogs/display-settings.cpp:929 +#, fuzzy +msgid "Pressing Ctrl+arrow key scrolls by this distance (in screen pixels)" +msgstr "Pressionando Ctrl+seta rola por esta distância (em pixels)" + +#: ../../po/../src/dialogs/display-settings.cpp:939 +msgid "Acceleration:" +msgstr "Aceleração:" + +#: ../../po/../src/dialogs/display-settings.cpp:940 +msgid "" +"Pressing and holding Ctrl+arrow will gradually speed up scrolling (0 for no " +"acceleration)" +msgstr "" +"Pressionando e segurando Ctrl+seta aumentará gradualmente a velocidade de " +"rolagem (0 para nenhuma aceleração)" + +#: ../../po/../src/dialogs/display-settings.cpp:949 +msgid "Autoscrolling" +msgstr "Autorolagem" + +#: ../../po/../src/dialogs/display-settings.cpp:957 +msgid "Speed:" +msgstr "Velocidade:" + +#: ../../po/../src/dialogs/display-settings.cpp:958 +msgid "" +"How fast the canvas autoscrolls when you drag beyond canvas edge (0 to turn " +"autoscroll off)" +msgstr "" +"Quão rápido a tela rola quando é arrastada além da beira da tela (0 para " +"desligar a rolagem)" + +#: ../../po/../src/dialogs/display-settings.cpp:968 +#: ../../po/../src/ui/dialog/tracedialog.cpp:357 +#: ../../po/../src/ui/dialog/tracedialog.cpp:390 +msgid "Threshold:" +msgstr "Limiar:" + +#: ../../po/../src/dialogs/display-settings.cpp:969 +#, fuzzy +msgid "" +"How far (in screen pixels) you need to be from the canvas edge to trigger " +"autoscroll; positive is outside the canvas, negative is within the canvas" +msgstr "" +"Quão longe (em pixels) é preciso estar da beira da tela para disparar a " +"rolagem. Positivo é do lado de fora da tela e negativo é dentro da tela" + +#. Steps +#: ../../po/../src/dialogs/display-settings.cpp:979 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:57 +msgid "Steps" +msgstr "Passos" + +#: ../../po/../src/dialogs/display-settings.cpp:982 +msgid "Arrow keys move by:" +msgstr "Setas movem por:" + +#: ../../po/../src/dialogs/display-settings.cpp:983 +#, fuzzy +msgid "" +"Pressing an arrow key moves selected object(s) or node(s) by this distance " +"(in px units)" +msgstr "" +"Pressionando um seta move o(s) objeto(s) ou nó(s) selecionados por " +"estadistância (em pontos)" + +#: ../../po/../src/dialogs/display-settings.cpp:984 +#: ../../po/../src/dialogs/display-settings.cpp:995 +#: ../../po/../src/dialogs/display-settings.cpp:1006 +#: ../../po/../src/helper/units.cpp:42 +msgid "px" +msgstr "px" + +#: ../../po/../src/dialogs/display-settings.cpp:993 +msgid "> and < scale by:" +msgstr "> e < ampliam em:" + +#: ../../po/../src/dialogs/display-settings.cpp:994 +#, fuzzy +msgid "" +"Pressing > or < scales selection up or down by this increment (in px units)" +msgstr "" +"Pressionando > ou < amplia ou reduz a seleção por este valor (em pontos)" + +#: ../../po/../src/dialogs/display-settings.cpp:1004 +msgid "Inset/Outset by:" +msgstr "Avanço/Recuo em:" + +#: ../../po/../src/dialogs/display-settings.cpp:1005 +#, fuzzy +msgid "" +"Inset and Outset commands displace the path by this distance (in px units)" +msgstr "" +"Os comandos Avançar e Recuar deslocam o caminho por esta distância (em " +"pontos)" + +#: ../../po/../src/dialogs/display-settings.cpp:1017 +msgid "Compass-like display of angles" +msgstr "" + +#. TRANSLATORS: "positive clockwise" means "increasing in clockwise direction" +#: ../../po/../src/dialogs/display-settings.cpp:1019 +msgid "" +"When on, angles are displayed with 0 at north, 0 to 360 range, positive " +"clockwise; otherwise with 0 at east, -180 to 180 range, positive " +"counterclockwise" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1026 +msgid "Zoom in/out by:" +msgstr "Ampliar/Reduzir em:" + +#: ../../po/../src/dialogs/display-settings.cpp:1027 +msgid "" +"Zoom tool click, +/- keys, and middle click zoom in and out by this " +"multiplier" +msgstr "" +"Um clique na ferramenta Zoom, as teclas +/- e clique com botão do meio " +"ampliam e reduzem por este multiplicador" + +#: ../../po/../src/dialogs/display-settings.cpp:1028 +#: ../../po/../src/helper/units.cpp:44 +msgid "%" +msgstr "%" + +#. Tools +#: ../../po/../src/dialogs/display-settings.cpp:1037 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:58 +msgid "Tools" +msgstr "Ferramentas" + +#: ../../po/../src/dialogs/display-settings.cpp:1045 +msgid "Selector" +msgstr "Seletor" + +#: ../../po/../src/dialogs/display-settings.cpp:1056 +msgid "Node" +msgstr "Nó" + +#: ../../po/../src/dialogs/display-settings.cpp:1064 +#: ../../po/../src/verbs.cpp:2073 +#: ../../po/../src/widgets/desktop-widget.cpp:277 +msgid "Zoom" +msgstr "Ampliação" + +#. The 4 shape tools +#: ../../po/../src/dialogs/display-settings.cpp:1071 +msgid "Shapes" +msgstr "Formas" + +#: ../../po/../src/dialogs/display-settings.cpp:1079 +#: ../../po/../src/verbs.cpp:2055 +msgid "Rectangle" +msgstr "Retângulo" + +#: ../../po/../src/dialogs/display-settings.cpp:1085 +#: ../../po/../src/verbs.cpp:2057 +msgid "Ellipse" +msgstr "Elipse" + +#: ../../po/../src/dialogs/display-settings.cpp:1091 +#: ../../po/../src/verbs.cpp:2059 +msgid "Star" +msgstr "Estrela" + +#: ../../po/../src/dialogs/display-settings.cpp:1097 +#: ../../po/../src/verbs.cpp:2061 +msgid "Spiral" +msgstr "Espiral" + +#: ../../po/../src/dialogs/display-settings.cpp:1111 +#: ../../po/../src/verbs.cpp:2063 +msgid "Pencil" +msgstr "Lápis" + +#: ../../po/../src/dialogs/display-settings.cpp:1114 +msgid "Tolerance:" +msgstr "Tolerância:" + +#: ../../po/../src/dialogs/display-settings.cpp:1115 +msgid "" +"This value affects the amount of smoothing applied to freehand lines; lower " +"values produce more uneven paths with more nodes" +msgstr "" +"Este valor afeta a quantidade de suavidade aplicada a linhas de mão-livre." +"Valores menores produzem mais caminhos não-pares com mais nós" + +#: ../../po/../src/dialogs/display-settings.cpp:1131 +#: ../../po/../src/verbs.cpp:2065 +msgid "Pen" +msgstr "Caneta" + +#: ../../po/../src/dialogs/display-settings.cpp:1140 +#: ../../po/../src/verbs.cpp:2067 +msgid "Calligraphy" +msgstr "Caligrafia" + +#: ../../po/../src/dialogs/display-settings.cpp:1147 +#: ../../po/../src/dialogs/text-edit.cpp:353 +#: ../../po/../src/ui/dialog/text-properties.cpp:37 +#: ../../po/../src/verbs.cpp:2069 +msgid "Text" +msgstr "Texto" + +#: ../../po/../src/dialogs/display-settings.cpp:1157 +#: ../../po/../src/verbs.cpp:2071 +#, fuzzy +msgid "Gradient" +msgstr "Editor de Gradiente" + +#: ../../po/../src/dialogs/display-settings.cpp:1164 +#: ../../po/../src/verbs.cpp:2077 +#, fuzzy +msgid "Connector" +msgstr "Cantos:" + +#: ../../po/../src/dialogs/display-settings.cpp:1171 +#: ../../po/../src/verbs.cpp:2075 +msgid "Dropper" +msgstr "Borrão" + +#. Windows +#: ../../po/../src/dialogs/display-settings.cpp:1183 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:59 +msgid "Windows" +msgstr "Janelas" + +#: ../../po/../src/dialogs/display-settings.cpp:1188 +msgid "Save window geometry" +msgstr "Salvar posição das janelas" + +#: ../../po/../src/dialogs/display-settings.cpp:1189 +msgid "" +"Save the window size and position with each document (only for Inkscape SVG " +"format)" +msgstr "" +"Salva a posição e tamanho de cada desenho (somente para o formato SVG " +"doInkscape)" + +#: ../../po/../src/dialogs/display-settings.cpp:1196 +msgid "Dialogs are hidden in taskbar" +msgstr "Janelas são escondidas na barra de tarefas" + +#: ../../po/../src/dialogs/display-settings.cpp:1197 +msgid "Whether dialog windows are to be hidden in the window manager taskbar" +msgstr "Quando janelas de diálogo são escondidas na barra de tarefas" + +#: ../../po/../src/dialogs/display-settings.cpp:1204 +msgid "Zoom when window is resized" +msgstr "Ampliar quando janela for redimensionada" + +#: ../../po/../src/dialogs/display-settings.cpp:1205 +msgid "" +"Zoom drawing when document window is resized, to keep the same area visible " +"(this is the default which can be changed in any window using the button " +"above the right scrollbar)" +msgstr "" +"Ampliar desenho quando janela for redimensionada. Para manter a mesma área " +"visível (Este é o padrão que pode ser mudado em qualquer janela usando o " +"botão que está abaixo da barra de rolagem direita)" + +#. Clones +#: ../../po/../src/dialogs/display-settings.cpp:1213 +#: ../../po/../src/dialogs/find.cpp:624 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:60 +msgid "Clones" +msgstr "Clones" + +#: ../../po/../src/dialogs/display-settings.cpp:1217 +#, fuzzy +msgid "When the original moves, its clones and linked offsets:" +msgstr "Quando o original se move, seus clones:" + +#: ../../po/../src/dialogs/display-settings.cpp:1229 +msgid "Move in parallel" +msgstr "Se movem em paralelo" + +#: ../../po/../src/dialogs/display-settings.cpp:1230 +msgid "Clones are translated by the same vector as their original." +msgstr "Os clones são transladados pelo mesmo vetor do original." + +#: ../../po/../src/dialogs/display-settings.cpp:1237 +msgid "Stay unmoved" +msgstr "Ficam inertes" + +#: ../../po/../src/dialogs/display-settings.cpp:1238 +msgid "Clones preserve their positions when their original is moved." +msgstr "Os clones preservam suas posições quando o seu original é movido." + +#: ../../po/../src/dialogs/display-settings.cpp:1245 +msgid "Move according to transform" +msgstr "Mover de acordo com a tranformação" + +#: ../../po/../src/dialogs/display-settings.cpp:1246 +msgid "" +"Each clone moves according to the value of its transform= attribute. For " +"example, a rotated clone will move in a different direction than its " +"original." +msgstr "" +"Cada clone se move de acordo com o valor do seu atributo de transformação." +"Por exemplo, um clone girado se moverá numa direção diferente do seu " +"original." + +#: ../../po/../src/dialogs/display-settings.cpp:1255 +msgid "When the original is deleted, its clones:" +msgstr "Quando o original é apagado, seus clones:" + +#: ../../po/../src/dialogs/display-settings.cpp:1267 +msgid "Are unlinked" +msgstr "São desligados" + +#: ../../po/../src/dialogs/display-settings.cpp:1267 +msgid "Orphaned clones are converted to regular objects." +msgstr "Clones órfãos são convertidos para objetos regulares." + +#: ../../po/../src/dialogs/display-settings.cpp:1273 +msgid "Are deleted" +msgstr "São apagados" + +#: ../../po/../src/dialogs/display-settings.cpp:1273 +msgid "Orphaned clones are deleted along with their original." +msgstr "Clones órfãos são apagados juntamente com seu original." + +#. Transforms +#. TRANSLATORS: Noun, i.e. transformations. +#: ../../po/../src/dialogs/display-settings.cpp:1289 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:61 +msgid "Transforms" +msgstr "Transformações" + +#: ../../po/../src/dialogs/display-settings.cpp:1292 +msgid "Scale stroke width" +msgstr "Ampliar largura do traço" + +#: ../../po/../src/dialogs/display-settings.cpp:1293 +#: ../../po/../src/widgets/select-toolbar.cpp:568 +msgid "When scaling objects, scale the stroke width by the same proportion" +msgstr "Ao ampliar objetos, amplie a largura do traço pela mesma proporção" + +#: ../../po/../src/dialogs/display-settings.cpp:1300 +msgid "Scale rounded corners in rectangles" +msgstr "Ampliar canto arredondados em retângulos" + +#: ../../po/../src/dialogs/display-settings.cpp:1301 +#: ../../po/../src/widgets/select-toolbar.cpp:580 +msgid "When scaling rectangles, scale the radii of rounded corners" +msgstr "Ao ampliar retângulos, ampliar o raio dos cantos arredondados" + +#: ../../po/../src/dialogs/display-settings.cpp:1308 +msgid "Transform gradients" +msgstr "Transformar gradientes" + +#: ../../po/../src/dialogs/display-settings.cpp:1309 +#: ../../po/../src/widgets/select-toolbar.cpp:592 +msgid "Transform gradients (in fill or stroke) along with the objects" +msgstr "" +"Transformar gradientes (em preenchimento ou traço) junto com os objetos" + +#: ../../po/../src/dialogs/display-settings.cpp:1316 +msgid "Transform patterns" +msgstr "Transformar padrões de preenchimento" + +#: ../../po/../src/dialogs/display-settings.cpp:1317 +#: ../../po/../src/widgets/select-toolbar.cpp:604 +msgid "Transform patterns (in fill or stroke) along with the objects" +msgstr "" +"Transformar padrões de preenchimento (em preenchimento ou traço)junto com os " +"objetos" + +#. TRANSLATORS: How to specify the affine transformation in the SVG file. +#: ../../po/../src/dialogs/display-settings.cpp:1327 +msgid "Store transformation:" +msgstr "Armazenar a transformação:" + +#: ../../po/../src/dialogs/display-settings.cpp:1338 +msgid "Optimized" +msgstr "Otimizada" + +#: ../../po/../src/dialogs/display-settings.cpp:1339 +msgid "" +"If possible, apply transformation to objects without adding a transform= " +"attribute" +msgstr "" +"Se possível, aplicar a transformação para um objeto sem acrescentar um " +"atributo de transformação" + +#: ../../po/../src/dialogs/display-settings.cpp:1346 +msgid "Preserved" +msgstr "Preservada" + +#: ../../po/../src/dialogs/display-settings.cpp:1347 +msgid "Always store transformation as a transform= attribute on objects" +msgstr "" +"Sempre armazenar a transformação como um atributo de transformação em objetos" + +#. Selecting +#: ../../po/../src/dialogs/display-settings.cpp:1355 +#, fuzzy +msgid "Selecting" +msgstr "Seleção" + +#: ../../po/../src/dialogs/display-settings.cpp:1357 +msgid "Ctrl+A, Tab, Shift+Tab:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1366 +#, fuzzy +msgid "Select only within current layer" +msgstr "Apagar a camada atual" + +#: ../../po/../src/dialogs/display-settings.cpp:1367 +msgid "" +"Uncheck this to make keyboard selection commands work on objects in all " +"layers" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1374 +msgid "Ignore hidden objects" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1375 +msgid "" +"Uncheck this to be able to select objects that are hidden (either by " +"themselves or by being in a hidden group or layer)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1382 +#, fuzzy +msgid "Ignore locked objects" +msgstr "União dos objetos selecionados" + +#: ../../po/../src/dialogs/display-settings.cpp:1383 +msgid "" +"Uncheck this to be able to select objects that are locked (either by " +"themselves or by being in a locked group or layer)" +msgstr "" + +#. To be broken into: Display, Save, Export, SVG, Commands +#: ../../po/../src/dialogs/display-settings.cpp:1391 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:62 +msgid "Misc" +msgstr "Outros" + +#: ../../po/../src/dialogs/display-settings.cpp:1394 +msgid "Default export resolution:" +msgstr "Resolução padrão de exportação" + +#: ../../po/../src/dialogs/display-settings.cpp:1395 +msgid "Default bitmap resolution (in dots per inch) in the Export dialog" +msgstr "" +"Resolução padrão de figura (em pontos por polegada) na janela de exportação" + +#. FIXME: add "Used for new exports; once exported, documents remember this value on per-object basis" when implemented +#: ../../po/../src/dialogs/display-settings.cpp:1396 +#: ../../po/../src/dialogs/export.cpp:442 +msgid "dpi" +msgstr "dpi" + +#. TRANSLATORS: When on, an imported bitmap creates an element; otherwise it is a +#. * rectangle with bitmap fill. +#: ../../po/../src/dialogs/display-settings.cpp:1407 +msgid "Import bitmap as " +msgstr "Importar a figura como " + +#: ../../po/../src/dialogs/display-settings.cpp:1408 +msgid "" +"When on, an imported bitmap creates an element; otherwise it is a " +"rectangle with bitmap fill" +msgstr "" +"Quando ligado, uma figura importada cria um elemento . Senão cria " +"umretângulo com preenchimento de figura" + +#. TRANSLATORS: When on, the print out (currently Postscript) will have +#. * a comment with the each object's label visible, marking the section +#. * of the printing commands that represent the given object. +#: ../../po/../src/dialogs/display-settings.cpp:1418 +msgid "Add label comments to printing output" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1419 +msgid "" +"When on, a comment will be added to the raw print output, marking the " +"rendered output for an object with its label" +msgstr "" + +#. TRANSLATORS: When on, enable the effects menu, default is off +#: ../../po/../src/dialogs/display-settings.cpp:1427 +msgid "Enable script effects (requires restart) - EXPERIMENTAL" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1428 +msgid "" +"When on, the effects menu is enabled, allowing external effect scripts to be " +"called, requires restart before effective - EXPERIMENTAL" +msgstr "" + +#. TRANSLATORS: The maximum length of the Open Recent list in the File menu. +#: ../../po/../src/dialogs/display-settings.cpp:1436 +msgid "Max recent documents:" +msgstr "Máximo de desenhos recentes:" + +#: ../../po/../src/dialogs/display-settings.cpp:1437 +msgid "The maximum length of the Open Recent list in the File menu" +msgstr "O tamanho máximo para a lista de Abrir Recentes no menu Arquivo" + +#: ../../po/../src/dialogs/display-settings.cpp:1447 +msgid "Simplification threshold:" +msgstr "Limiar de simplificação:" + +#: ../../po/../src/dialogs/display-settings.cpp:1448 +msgid "" +"How strong is the Simplify command by default. If you invoke this command " +"several times in quick succession, it will act more and more aggressively; " +"invoking it again after a pause restores the default threshold." +msgstr "" +"Quão forte é o comando Simplificar por padrão. Se este comando for invocado " +"diversas vezes em sucessivamente, ele agirá mais agressivamente.Invocando-o " +"novamente após uma pausa restaura o limiar padrão." + +#: ../../po/../src/dialogs/display-settings.cpp:1469 +msgid "Oversample bitmaps:" +msgstr "Figuras sobrepostas" + +#: ../../po/../src/dialogs/display-settings.cpp:1488 +msgid "2x2" +msgstr "2x2" + +#: ../../po/../src/dialogs/display-settings.cpp:1494 +msgid "4x4" +msgstr "4x4" + +#: ../../po/../src/dialogs/display-settings.cpp:1500 +msgid "8x8" +msgstr "8x8" + +#: ../../po/../src/dialogs/display-settings.cpp:1506 +msgid "16x16" +msgstr "16x16" + +#. "view_icon_preview" +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2143 +msgid "_Page" +msgstr "_Página" + +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2147 +msgid "_Drawing" +msgstr "_Desenho" + +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2149 +msgid "_Selection" +msgstr "_Seleção" + +#: ../../po/../src/dialogs/export.cpp:133 +#, fuzzy +msgid "_Custom" +msgstr "Personalizado" + +#: ../../po/../src/dialogs/export.cpp:254 +msgid "Export area" +msgstr "Exportar área" + +#: ../../po/../src/dialogs/export.cpp:300 +#, fuzzy +msgid "_x0:" +msgstr "x0" + +#: ../../po/../src/dialogs/export.cpp:305 +#, fuzzy +msgid "x_1:" +msgstr "x1" + +#: ../../po/../src/dialogs/export.cpp:316 +#, fuzzy +msgid "_y0:" +msgstr "y0" + +#: ../../po/../src/dialogs/export.cpp:321 +#, fuzzy +msgid "y_1:" +msgstr "y1" + +#: ../../po/../src/dialogs/export.cpp:406 +msgid "Bitmap size" +msgstr "Tamanho da figura" + +#: ../../po/../src/dialogs/export.cpp:416 +#, fuzzy +msgid "_Width:" +msgstr "Largura:" + +#: ../../po/../src/dialogs/export.cpp:416 +#: ../../po/../src/dialogs/export.cpp:431 +#, fuzzy +msgid "pixels at" +msgstr "pixels" + +#: ../../po/../src/dialogs/export.cpp:426 +#, fuzzy +msgid "dp_i" +msgstr "dpi" + +#: ../../po/../src/dialogs/export.cpp:448 +#, fuzzy +msgid "_Filename" +msgstr "Nome do arquivo" + +#: ../../po/../src/dialogs/export.cpp:512 +#, fuzzy +msgid "_Browse..." +msgstr "Localizar..." + +#: ../../po/../src/dialogs/export.cpp:539 +#, fuzzy +msgid " _Export " +msgstr "Círculo" + +#: ../../po/../src/dialogs/export.cpp:541 +msgid "Export the bitmap file with these settings" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:968 +msgid "You have to enter a filename" +msgstr "Você deve informar um nome de arquivo" + +#: ../../po/../src/dialogs/export.cpp:973 +msgid "The chosen area to be exported is invalid" +msgstr "A área escolhida para ser exportada não é válida" + +#: ../../po/../src/dialogs/export.cpp:982 +#, c-format +msgid "Directory %s does not exist or is not a directory.\n" +msgstr "A pasta %s não existe ou não é uma pasta.\n" + +#: ../../po/../src/dialogs/export.cpp:998 +msgid "Export in progress" +msgstr "Exportação em progresso" + +#: ../../po/../src/dialogs/export.cpp:1004 +#, fuzzy, c-format +msgid "Exporting %s (%d x %d)" +msgstr "Exportando [%d x %d] %s" + +#: ../../po/../src/dialogs/export.cpp:1031 +#, c-format +msgid "Could not export to filename %s.\n" +msgstr "Não foi possível exportar para o arquivo %s.\n" + +#: ../../po/../src/dialogs/export.cpp:1137 +msgid "Select a filename for exporting" +msgstr "Selecione um nome de arquivo para exportar" + +#: ../../po/../src/dialogs/filedialog.cpp:367 +msgid "No preview" +msgstr "Nenhuma visualização" + +#: ../../po/../src/dialogs/filedialog.cpp:468 +msgid "too large for preview" +msgstr "muito grande para visualização" + +#: ../../po/../src/dialogs/filedialog.cpp:762 +#: ../../po/../src/dialogs/filedialog.cpp:763 +msgid "All Images" +msgstr "Todas as Imagens" + +#: ../../po/../src/dialogs/filedialog.cpp:767 +#: ../../po/../src/dialogs/filedialog.cpp:768 +msgid "All Files" +msgstr "Todos os arquivos" + +#: ../../po/../src/dialogs/filedialog.cpp:774 +#: ../../po/../src/dialogs/filedialog.cpp:775 +msgid "All Inkscape Files" +msgstr "Todos os arquivos do Inkscape" + +#: ../../po/../src/dialogs/filedialog.cpp:1176 +msgid "Guess from extension" +msgstr "Sugerir a partir da extensão" + +#. ###### Add the file types menu +#. createFilterMenu(); +#. ###### Do we want the .xxx extension automatically added? +#: ../../po/../src/dialogs/filedialog.cpp:1261 +msgid "Append filename extension automatically" +msgstr "Acrescentar extensão de arquivo automaticamente" + +#. TRANSLATORS: "%s" is replaced with "exact" or "partial" when this string is displayed +#: ../../po/../src/dialogs/find.cpp:378 +#, c-format +msgid "%d object found (out of %d), %s match." +msgid_plural "%d objects found (out of %d), %s match." +msgstr[0] "%d objeto(s) encontrados (de %d), %s casados." +msgstr[1] "%d objeto(s) encontrados (de %d), %s casados." + +#: ../../po/../src/dialogs/find.cpp:381 +msgid "exact" +msgstr "exato" + +#: ../../po/../src/dialogs/find.cpp:381 +msgid "partial" +msgstr "parcial" + +#: ../../po/../src/dialogs/find.cpp:388 +msgid "No objects found" +msgstr "Nenhum objeto encontrado" + +#: ../../po/../src/dialogs/find.cpp:546 +msgid "T_ype: " +msgstr "T_ipo:" + +#: ../../po/../src/dialogs/find.cpp:553 +msgid "Search in all object types" +msgstr "Procurar em todos os tipos de objeto" + +#: ../../po/../src/dialogs/find.cpp:553 +msgid "All types" +msgstr "Todos os tipos" + +#: ../../po/../src/dialogs/find.cpp:564 +msgid "Search all shapes" +msgstr "Procurar todas as formas" + +#: ../../po/../src/dialogs/find.cpp:564 +msgid "All shapes" +msgstr "Todas as formas" + +#: ../../po/../src/dialogs/find.cpp:581 +msgid "Search rectangles" +msgstr "Procurar retângulos" + +#: ../../po/../src/dialogs/find.cpp:581 +msgid "Rectangles" +msgstr "Retângulos" + +#: ../../po/../src/dialogs/find.cpp:586 +msgid "Search ellipses, arcs, circles" +msgstr "Procurar elipses, arcos e círculos" + +#: ../../po/../src/dialogs/find.cpp:586 +msgid "Ellipses" +msgstr "Elipses" + +#: ../../po/../src/dialogs/find.cpp:591 +msgid "Search stars and polygons" +msgstr "Procurar estrelas e polígonos" + +#: ../../po/../src/dialogs/find.cpp:591 +msgid "Stars" +msgstr "Estrelas" + +#: ../../po/../src/dialogs/find.cpp:596 +msgid "Search spirals" +msgstr "Procurar espirais" + +#: ../../po/../src/dialogs/find.cpp:596 +msgid "Spirals" +msgstr "Espirais" + +#. TRANSLATORS: polyline is a set of connected straight line segments +#. http://www.w3.org/TR/SVG11/shapes.html#PolylineElement +#: ../../po/../src/dialogs/find.cpp:609 +msgid "Search paths, lines, polylines" +msgstr "Procurar caminhos, linhas, polilinhas" + +#: ../../po/../src/dialogs/find.cpp:609 +msgid "Paths" +msgstr "Caminhos" + +#: ../../po/../src/dialogs/find.cpp:614 +msgid "Search text objects" +msgstr "Procurar objetos de texto" + +#: ../../po/../src/dialogs/find.cpp:614 +msgid "Texts" +msgstr "Textos" + +#: ../../po/../src/dialogs/find.cpp:619 +msgid "Search groups" +msgstr "Procurar grupos" + +#: ../../po/../src/dialogs/find.cpp:619 +msgid "Groups" +msgstr "Grupos" + +#: ../../po/../src/dialogs/find.cpp:624 +msgid "Search clones" +msgstr "Procurar clones" + +#: ../../po/../src/dialogs/find.cpp:629 +msgid "Search images" +msgstr "Procurar imagens" + +#: ../../po/../src/dialogs/find.cpp:629 +msgid "Images" +msgstr "Imagens" + +#: ../../po/../src/dialogs/find.cpp:634 +msgid "Search offset objects" +msgstr "Procurar objetos tipográficos" + +#: ../../po/../src/dialogs/find.cpp:634 +msgid "Offsets" +msgstr "Tipográficos" + +#: ../../po/../src/dialogs/find.cpp:694 +msgid "_Text: " +msgstr "_Texto: " + +#: ../../po/../src/dialogs/find.cpp:694 +msgid "Find objects by their text content (exact or partial match)" +msgstr "" +"Encontrar objetos pelo seu conteúdo de texto (por casamento exato ou parcial)" + +#: ../../po/../src/dialogs/find.cpp:695 +msgid "_ID: " +msgstr "_ID: " + +#: ../../po/../src/dialogs/find.cpp:695 +msgid "Find objects by the value of the id attribute (exact or partial match)" +msgstr "" +"Encontrar objetos pelo valor de seu atributo id (casamento exato ou parcial)" + +#: ../../po/../src/dialogs/find.cpp:696 +msgid "_Style: " +msgstr "E_stilo: " + +#: ../../po/../src/dialogs/find.cpp:696 +msgid "" +"Find objects by the value of the style attribute (exact or partial match)" +msgstr "" +"Encontrar objetos pelo valor do atributo estilo (casamento exato ou parcial)" + +#: ../../po/../src/dialogs/find.cpp:697 +msgid "_Attribute: " +msgstr "_Atributo: " + +#: ../../po/../src/dialogs/find.cpp:697 +msgid "Find objects by the name of an attribute (exact or partial match)" +msgstr "" +"Encontrar objetos pelo nome de um atributo (casamento exato ou parcial)" + +#: ../../po/../src/dialogs/find.cpp:711 +msgid "Search in s_election" +msgstr "Procurar na s_eleção" + +#: ../../po/../src/dialogs/find.cpp:715 +msgid "Limit search to the current selection" +msgstr "Limitar a busca na seleção atual" + +#: ../../po/../src/dialogs/find.cpp:720 +#, fuzzy +msgid "Search in current _layer" +msgstr "Abaixar a camada atual" + +#: ../../po/../src/dialogs/find.cpp:724 +#, fuzzy +msgid "Limit search to the current layer" +msgstr "Limitar a busca na seleção atual" + +#: ../../po/../src/dialogs/find.cpp:729 +msgid "Include _hidden" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:733 +msgid "Include hidden objects in search" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:738 +msgid "Include l_ocked" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:742 +msgid "Include locked objects in search" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:753 +msgid "Clear values" +msgstr "Limpar os valores" + +#: ../../po/../src/dialogs/find.cpp:754 +msgid "_Find" +msgstr "_Localizar" + +#: ../../po/../src/dialogs/find.cpp:754 +msgid "Select objects matching all of the fields you filled in" +msgstr "Busca por objetos casando com os valores que você preencheu" + +#: ../../po/../src/dialogs/iconpreview.cpp:145 +#, c-format +msgid "%d x %d" +msgstr "" + +#: ../../po/../src/dialogs/iconpreview.cpp:193 +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:857 +#: ../../po/../src/widgets/desktop-widget.cpp:1069 +msgid "Selection" +msgstr "Seleção" + +#: ../../po/../src/dialogs/iconpreview.cpp:195 +#, fuzzy +msgid "Selection only or whole document" +msgstr "Apagar a camada atual" + +#: ../../po/../src/dialogs/iconpreview.cpp:203 +msgid "Refresh the icons" +msgstr "" + +#. Create the label for the object id +#: ../../po/../src/dialogs/item-properties.cpp:126 +#: ../../po/../src/dialogs/item-properties.cpp:327 +#: ../../po/../src/dialogs/item-properties.cpp:396 +#: ../../po/../src/dialogs/item-properties.cpp:403 +msgid "_Id" +msgstr "" + +#: ../../po/../src/dialogs/item-properties.cpp:135 +msgid "" +"The id= attribute (only letters, digits, and the characters .-_: allowed)" +msgstr "" + +#. Button for setting the object's id, label, title and description. +#: ../../po/../src/dialogs/item-properties.cpp:149 +#, fuzzy +msgid "_Set" +msgstr "Selecionar" + +#. Create the label for the object label +#: ../../po/../src/dialogs/item-properties.cpp:158 +#, fuzzy +msgid "_Label" +msgstr "Ca_mada" + +#: ../../po/../src/dialogs/item-properties.cpp:167 +msgid "A freeform label for the object" +msgstr "" + +#. Create the label for the object title +#: ../../po/../src/dialogs/item-properties.cpp:179 +#: ../../po/../src/dialogs/rdf.cpp:243 +msgid "Title" +msgstr "Título" + +#. Create the frame for the object description +#: ../../po/../src/dialogs/item-properties.cpp:196 +#: ../../po/../src/dialogs/rdf.cpp:287 +msgid "Description" +msgstr "Descrição" + +#. Hide +#: ../../po/../src/dialogs/item-properties.cpp:223 +#, fuzzy +msgid "_Hide" +msgstr "Lados:" + +#: ../../po/../src/dialogs/item-properties.cpp:224 +msgid "Check to make the object invisible" +msgstr "" + +#. Lock +#. TRANSLATORS: "Lock" is a verb here +#: ../../po/../src/dialogs/item-properties.cpp:233 +msgid "L_ock" +msgstr "" + +#: ../../po/../src/dialogs/item-properties.cpp:234 +msgid "Check to make the object insensitive (not selectable by mouse)" +msgstr "" + +#: ../../po/../src/dialogs/item-properties.cpp:310 +#: ../../po/../src/dialogs/item-properties.cpp:317 +msgid "Ref" +msgstr "Ref" + +#: ../../po/../src/dialogs/item-properties.cpp:398 +#, fuzzy +msgid "Id invalid! " +msgstr "ID inválido" + +#: ../../po/../src/dialogs/item-properties.cpp:400 +#, fuzzy +msgid "Id exists! " +msgstr "ID existe" + +#: ../../po/../src/dialogs/layer-properties.cpp:50 +msgid "Layer name:" +msgstr "" + +#: ../../po/../src/dialogs/layer-properties.cpp:133 +#, fuzzy +msgid "Rename Layer" +msgstr "Levantar Camada" + +#: ../../po/../src/dialogs/layer-properties.cpp:136 +#, fuzzy +msgid "_Rename" +msgstr "Nome do arquivo" + +#. TRANSLATORS: This means "The layer has been renamed" +#: ../../po/../src/dialogs/layer-properties.cpp:147 +#, fuzzy +msgid "Renamed layer" +msgstr "Nó Levantado." + +#: ../../po/../src/dialogs/layer-properties.cpp:151 +#, fuzzy +msgid "Add Layer" +msgstr "Ca_mada" + +#: ../../po/../src/dialogs/layer-properties.cpp:153 +#, fuzzy +msgid "_Add" +msgstr "Acrescentar" + +#: ../../po/../src/dialogs/layer-properties.cpp:167 +msgid "New layer created." +msgstr "Nova camada criada." + +#: ../../po/../src/dialogs/object-attributes.cpp:34 +msgid "Href:" +msgstr "Href:" + +#: ../../po/../src/dialogs/object-attributes.cpp:35 +msgid "Target:" +msgstr "Alvo:" + +#: ../../po/../src/dialogs/object-attributes.cpp:36 +msgid "Type:" +msgstr "Tipo:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkRoleAttribute +#. Identifies the type of the related resource with an absolute URI +#: ../../po/../src/dialogs/object-attributes.cpp:39 +msgid "Role:" +msgstr "Cargo:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkArcRoleAttribute +#. For situations where the nature/role alone isn't enough, this offers an additional URI defining the purpose of the link. +#: ../../po/../src/dialogs/object-attributes.cpp:42 +msgid "Arcrole:" +msgstr "Arqui-cargo" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkTitleAttribute +#: ../../po/../src/dialogs/object-attributes.cpp:44 +msgid "Title:" +msgstr "Título:" + +#: ../../po/../src/dialogs/object-attributes.cpp:45 +msgid "Show:" +msgstr "Mostrar:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkActuateAttribute +#: ../../po/../src/dialogs/object-attributes.cpp:47 +msgid "Actuate:" +msgstr "Atuar:" + +#: ../../po/../src/dialogs/object-attributes.cpp:52 +msgid "URL:" +msgstr "URL:" + +#: ../../po/../src/dialogs/object-attributes.cpp:53 +msgid "X:" +msgstr "X:" + +#: ../../po/../src/dialogs/object-attributes.cpp:54 +msgid "Y:" +msgstr "Y:" + +#: ../../po/../src/dialogs/object-attributes.cpp:98 +#, c-format +msgid "%s attributes" +msgstr "%s atributos" + +#: ../../po/../src/dialogs/object-properties.cpp:158 +#, fuzzy +msgid "_Fill" +msgstr "Preenchimento" + +#: ../../po/../src/dialogs/object-properties.cpp:165 +#, fuzzy +msgid "Stroke _paint" +msgstr "Pintura de traço" + +#: ../../po/../src/dialogs/object-properties.cpp:172 +#, fuzzy +msgid "Stroke st_yle" +msgstr "Estilo de traço" + +#: ../../po/../src/dialogs/object-properties.cpp:183 +#, fuzzy +msgid "Master _opacity" +msgstr "Opacidade Mestre" + +#: ../../po/../src/dialogs/rdf.cpp:244 +msgid "Name by which this document is formally known." +msgstr "O nome pelo qual este desenho será formalmente conhecido." + +#: ../../po/../src/dialogs/rdf.cpp:246 +msgid "Date" +msgstr "Data" + +#: ../../po/../src/dialogs/rdf.cpp:247 +msgid "Date associated with the creation of this document (YYYY-MM-DD)." +msgstr "Data associada com a criação deste desenho (AAAA-MM-DD)." + +#: ../../po/../src/dialogs/rdf.cpp:249 +msgid "Format" +msgstr "Formato" + +#: ../../po/../src/dialogs/rdf.cpp:250 +msgid "The physical or digital manifestation of this document (MIME type)." +msgstr "A manifestação física ou digital deste desenho (tipo MIME)." + +#: ../../po/../src/dialogs/rdf.cpp:252 +msgid "Type" +msgstr "Tipo" + +#: ../../po/../src/dialogs/rdf.cpp:253 +msgid "Type of document (DCMI Type)." +msgstr "Tipo do desenho (tipo DCMI)." + +#: ../../po/../src/dialogs/rdf.cpp:256 +msgid "Creator" +msgstr "Criador" + +#: ../../po/../src/dialogs/rdf.cpp:257 +msgid "" +"Name of entity primarily responsible for making the content of this document." +msgstr "" +"Nome da entidade responsável pela elaboração do conteúdo deste desenho." + +#: ../../po/../src/dialogs/rdf.cpp:259 +msgid "Rights" +msgstr "Direitos" + +#: ../../po/../src/dialogs/rdf.cpp:260 +msgid "" +"Name of entity with rights to the Intellectual Property of this document." +msgstr "" +"Nome da entidade com os direitos de Propriedade Intelectual deste documento." + +#: ../../po/../src/dialogs/rdf.cpp:262 +msgid "Publisher" +msgstr "Publicador" + +#: ../../po/../src/dialogs/rdf.cpp:263 +msgid "Name of entity responsible for making this document available." +msgstr "Nome da entidade responsável por fazer este desenho disponível." + +#: ../../po/../src/dialogs/rdf.cpp:266 +msgid "Identifier" +msgstr "Identificador" + +#: ../../po/../src/dialogs/rdf.cpp:267 +msgid "Unique URI to reference this document." +msgstr "URL única para referenciar este desenho." + +#: ../../po/../src/dialogs/rdf.cpp:269 +msgid "Source" +msgstr "Fonte" + +#: ../../po/../src/dialogs/rdf.cpp:270 +msgid "Unique URI to reference the source of this document." +msgstr "URI única para referenciar a fonte deste desenho." + +#: ../../po/../src/dialogs/rdf.cpp:272 +msgid "Relation" +msgstr "Relação" + +#: ../../po/../src/dialogs/rdf.cpp:273 +msgid "Unique URI to a related document." +msgstr "URL única para um desenho relacionado." + +#: ../../po/../src/dialogs/rdf.cpp:275 +msgid "Language" +msgstr "Linguagem" + +#: ../../po/../src/dialogs/rdf.cpp:276 +msgid "" +"Two-letter language tag with optional subtags for the language of this " +"document. (e.g. 'en-GB')" +msgstr "Etiqueta de linguagem para a linguagem deste desenho. (ex: pt-BR)" + +#: ../../po/../src/dialogs/rdf.cpp:278 +msgid "Keywords" +msgstr "Palavras chave" + +#: ../../po/../src/dialogs/rdf.cpp:279 +#, fuzzy +msgid "" +"The topic of this document as comma-separated key words, phrases, or " +"classifications." +msgstr "O tópico deste desenho como palavras chaves, frases ou classificação." + +#. TRANSLATORS: "Coverage": the spatial or temporal characteristics of the content. +#. For info, see Appendix D of http://www.w3.org/TR/1998/WD-rdf-schema-19980409/ +#: ../../po/../src/dialogs/rdf.cpp:283 +msgid "Coverage" +msgstr "Cobertura" + +#: ../../po/../src/dialogs/rdf.cpp:284 +msgid "Extent or scope of this document." +msgstr "Extensão ou escopo deste documento." + +#: ../../po/../src/dialogs/rdf.cpp:288 +msgid "A short account of the content of this document." +msgstr "Uma esplicação curta para o conteúdo deste desenho." + +#. FIXME: need to handle 1 agent per line of input +#: ../../po/../src/dialogs/rdf.cpp:292 +msgid "Contributors" +msgstr "Contribuidores" + +#: ../../po/../src/dialogs/rdf.cpp:293 +msgid "" +"Names of entities responsible for making contributions to the content of " +"this document." +msgstr "" +"Nome das entidades responsáveis por contribuições ao conteúdo deste desenho." + +#. TRANSLATORS: URL to a page that defines the license for the document +#: ../../po/../src/dialogs/rdf.cpp:297 +msgid "URI" +msgstr "URL" + +#. TRANSLATORS: this is where you put a URL to a page that defines the license +#: ../../po/../src/dialogs/rdf.cpp:299 +msgid "URI to this document's license's namespace definition." +msgstr "URL da definição de espaço de nome da licensa deste desenho." + +#. TRANSLATORS: fragment of XML representing the license of the document +#: ../../po/../src/dialogs/rdf.cpp:303 +msgid "Fragment" +msgstr "Fragmento" + +#: ../../po/../src/dialogs/rdf.cpp:304 +msgid "XML fragment for the RDF 'License' section." +msgstr "Fragmento XML para a seção 'Licensa' RDF." + +#: ../../po/../src/dialogs/stroke-style.cpp:774 +#: ../../po/../src/widgets/gradient-vector.cpp:263 +#: ../../po/../src/widgets/paint-selector.cpp:751 +msgid "No document selected" +msgstr "Nenhum desenho selecionado" + +#: ../../po/../src/dialogs/stroke-style.cpp:992 +msgid "Stroke width" +msgstr "Largura do traço" + +#. Join type +#. TRANSLATORS: The line join style specifies the shape to be used at the +#. corners of paths. It can be "miter", "round" or "bevel". +#: ../../po/../src/dialogs/stroke-style.cpp:1015 +msgid "Join:" +msgstr "Juntar:" + +#. TRANSLATORS: Miter join: joining lines with a sharp (pointed) corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1027 +msgid "Miter join" +msgstr "Junção aguda" + +#. TRANSLATORS: Round join: joining lines with a rounded corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1035 +msgid "Round join" +msgstr "Junção Redonda" + +#. TRANSLATORS: Bevel join: joining lines with a blunted (flattened) corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1043 +msgid "Bevel join" +msgstr "Junção de Vinco" + +#. Miterlimit +#. TRANSLATORS: Miter limit: only for "miter join", this limits the length +#. of the sharp "spike" when the lines connect at too sharp an angle. +#. When two line segments meet at a sharp angle, a miter join results in a +#. spike that extends well beyond the connection point. The purpose of the +#. miter limit is to cut off such spikes (i.e. convert them into bevels) +#. when they become too long. +#: ../../po/../src/dialogs/stroke-style.cpp:1054 +msgid "Miter limit:" +msgstr "Limite de aguçamento:" + +#: ../../po/../src/dialogs/stroke-style.cpp:1062 +msgid "Maximum length of the miter (in units of stroke width)" +msgstr "Tamanho máximo do aguçamento (em unidades de largura de traço)" + +#. Cap type +#. TRANSLATORS: cap type specifies the shape for the ends of lines +#: ../../po/../src/dialogs/stroke-style.cpp:1075 +msgid "Cap:" +msgstr "Ponta:" + +#. TRANSLATORS: Butt cap: the line shape does not extend beyond the end point +#. of the line; the ends of the line are square +#: ../../po/../src/dialogs/stroke-style.cpp:1086 +msgid "Butt cap" +msgstr "Sem ponta" + +#. TRANSLATORS: Round cap: the line shape extends beyond the end point of the +#. line; the ends of the line are rounded +#: ../../po/../src/dialogs/stroke-style.cpp:1093 +msgid "Round cap" +msgstr "Ponta Redonda" + +#. TRANSLATORS: Square cap: the line shape extends beyond the end point of the +#. line; the ends of the line are square +#: ../../po/../src/dialogs/stroke-style.cpp:1100 +msgid "Square cap" +msgstr "Ponta quadrada" + +#. Dash +#: ../../po/../src/dialogs/stroke-style.cpp:1106 +msgid "Dashes:" +msgstr "Traços:" + +#. TRANSLATORS: Path markers are an SVG feature that allows you to attach arbitrary shapes +#. (arrowheads, bullets, faces, whatever) to the start, end, or middle nodes of a path. +#: ../../po/../src/dialogs/stroke-style.cpp:1127 +msgid "Start Markers:" +msgstr "Marcadores de Início:" + +#: ../../po/../src/dialogs/stroke-style.cpp:1137 +msgid "Mid Markers:" +msgstr "Marcadores centrais:" + +#: ../../po/../src/dialogs/stroke-style.cpp:1148 +msgid "End Markers:" +msgstr "Marcadores de fim:" + +#: ../../po/../src/dialogs/swatches.cpp:424 +#, c-format +msgid "Palettes directory (%s) is unavailable." +msgstr "" + +#. TODO: Insert widgets +#: ../../po/../src/dialogs/text-edit.cpp:199 +#: ../../po/../src/ui/dialog/text-properties.cpp:36 +msgid "Font" +msgstr "Fonte" + +#: ../../po/../src/dialogs/text-edit.cpp:216 +msgid "Layout" +msgstr "Arranjo" + +#: ../../po/../src/dialogs/text-edit.cpp:229 +msgid "Align lines left" +msgstr "Alinhar linhas à esquerda" + +#. TRANSLATORS: `Center' here is a verb. +#: ../../po/../src/dialogs/text-edit.cpp:243 +msgid "Center lines" +msgstr "Centralizar linhas" + +#: ../../po/../src/dialogs/text-edit.cpp:256 +msgid "Align lines right" +msgstr "Alinhar linhas à direita" + +#: ../../po/../src/dialogs/text-edit.cpp:278 +msgid "Horizontal text" +msgstr "Texto horizontal" + +#: ../../po/../src/dialogs/text-edit.cpp:292 +msgid "Vertical text" +msgstr "Texto vertical" + +#: ../../po/../src/dialogs/text-edit.cpp:307 +msgid "Line spacing:" +msgstr "Espaçamento de Linha:" + +#: ../../po/../src/dialogs/text-edit.cpp:400 +msgid "Set as default" +msgstr "Ajustar como padrão" + +#: ../../po/../src/dialogs/tiledialog.cpp:603 +#, fuzzy +msgid "Rows:" +msgstr "Mostrar:" + +#: ../../po/../src/dialogs/tiledialog.cpp:613 +#, fuzzy +msgid "Number of rows" +msgstr "Número de revoluções" + +#: ../../po/../src/dialogs/tiledialog.cpp:617 +#, fuzzy +msgid "Equal height" +msgstr "Altura:" + +#: ../../po/../src/dialogs/tiledialog.cpp:627 +msgid "If not set, each row has the height of the tallest object in it" +msgstr "" + +#. #### Radio buttons to control vertical alignment #### +#. #### Radio buttons to control horizontal alignment #### +#: ../../po/../src/dialogs/tiledialog.cpp:637 +#: ../../po/../src/dialogs/tiledialog.cpp:708 +#, fuzzy +msgid "Align:" +msgstr "Alinhar" + +#: ../../po/../src/dialogs/tiledialog.cpp:672 +msgid " X " +msgstr "" + +#. #### Number of columns #### +#: ../../po/../src/dialogs/tiledialog.cpp:678 +#, fuzzy +msgid "Columns:" +msgstr "Círculo" + +#: ../../po/../src/dialogs/tiledialog.cpp:688 +#, fuzzy +msgid "Number of columns" +msgstr "Número de revoluções" + +#: ../../po/../src/dialogs/tiledialog.cpp:692 +#, fuzzy +msgid "Equal width" +msgstr "Largura:" + +#: ../../po/../src/dialogs/tiledialog.cpp:701 +msgid "If not set, each column has the width of the widest object in it" +msgstr "" + +#. #### Radio buttons to control spacing manually or to fit selection bbox #### +#: ../../po/../src/dialogs/tiledialog.cpp:746 +#, fuzzy +msgid "Fit into selection box" +msgstr "Largura da seleção" + +#: ../../po/../src/dialogs/tiledialog.cpp:753 +#, fuzzy +msgid "Set spacing:" +msgstr "Espaçamento Y:" + +#. #### Y Padding #### +#: ../../po/../src/dialogs/tiledialog.cpp:777 +#, fuzzy +msgid "Row spacing: " +msgstr "Espaçamento de Linha:" + +#: ../../po/../src/dialogs/tiledialog.cpp:786 +#, fuzzy +msgid "Vertical spacing between rows" +msgstr "Texto vertical" + +#. #### X padding #### +#: ../../po/../src/dialogs/tiledialog.cpp:795 +#, fuzzy +msgid "Column spacing:" +msgstr "Espaçamento de Linha:" + +#: ../../po/../src/dialogs/tiledialog.cpp:804 +#, fuzzy +msgid "Horizontal spacing between columns" +msgstr "Coordenada horizontal da seleção" + +#: ../../po/../src/dialogs/tiledialog.cpp:818 +#, fuzzy +msgid "Arrange selected objects" +msgstr "Agrupa os objetos selecionados" + +#: ../../po/../src/dialogs/xml-tree.cpp:178 +#, fuzzy +msgid "Click to select nodes, drag to rearrange." +msgstr "" +"Clique para selecionar ou criar um objeto texto, e então pode digitar." + +#: ../../po/../src/dialogs/xml-tree.cpp:189 +msgid "Click attribute to edit." +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:193 +#, c-format +msgid "" +"Attribute %s selected. Press Ctrl+Enter when done editing to " +"commit changes." +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:284 +msgid "Drag to reorder nodes" +msgstr "Arraste para reordenar os nós" + +#: ../../po/../src/dialogs/xml-tree.cpp:304 +msgid "New element node" +msgstr "Novo nó de elemento" + +#: ../../po/../src/dialogs/xml-tree.cpp:326 +msgid "New text node" +msgstr "Novo nó de texto" + +#: ../../po/../src/dialogs/xml-tree.cpp:347 +msgid "Duplicate node" +msgstr "Duplicar nó" + +#: ../../po/../src/dialogs/xml-tree.cpp:368 +msgid "Delete node" +msgstr "Apagar nó" + +#: ../../po/../src/dialogs/xml-tree.cpp:384 +msgid "Unindent node" +msgstr "Desedentar nó" + +#: ../../po/../src/dialogs/xml-tree.cpp:399 +msgid "Indent node" +msgstr "Edentar nó" + +#: ../../po/../src/dialogs/xml-tree.cpp:411 +msgid "Raise node" +msgstr "Levantar nó" + +#: ../../po/../src/dialogs/xml-tree.cpp:423 +msgid "Lower node" +msgstr "Abaixar nó" + +#: ../../po/../src/dialogs/xml-tree.cpp:468 +msgid "Delete attribute" +msgstr "Apagar atributo" + +#. TRANSLATORS: "Attribute" is a noun here +#: ../../po/../src/dialogs/xml-tree.cpp:513 +msgid "Attribute name" +msgstr "Nome do atributo" + +#. TRANSLATORS: "Set" is a verb here +#: ../../po/../src/dialogs/xml-tree.cpp:533 +msgid "Set attribute" +msgstr "Ajustar atributo" + +#. TRANSLATORS: "Set" is a verb here +#: ../../po/../src/dialogs/xml-tree.cpp:535 +#, fuzzy +msgid "Set" +msgstr "Selecionar" + +#. TRANSLATORS: "Attribute" is a noun here +#: ../../po/../src/dialogs/xml-tree.cpp:558 +msgid "Attribute value" +msgstr "Valor do atributo" + +#: ../../po/../src/dialogs/xml-tree.cpp:1318 +msgid "New element node..." +msgstr "Novo nó de elemento..." + +#: ../../po/../src/dialogs/xml-tree.cpp:1339 +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:100 +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:98 +msgid "Cancel" +msgstr "Cancelar" + +#: ../../po/../src/dialogs/xml-tree.cpp:1345 +msgid "Create" +msgstr "Criar" + +#: ../../po/../src/dialogs/xml-tree.cpp:1458 +#, c-format +msgid "" +"Cannot set %s: Another element with value %s already exists!" +msgstr "" + +#: ../../po/../src/document.cpp:369 +#, c-format +msgid "New document %d" +msgstr "Novo desenho %d" + +#: ../../po/../src/document.cpp:401 +#, c-format +msgid "Memory document %d" +msgstr "Desenho de memória %d" + +#: ../../po/../src/document.cpp:524 +#, c-format +msgid "Unnamed document %d" +msgstr "Desenho sem nome %d" + +#. We hit green anchor, closing Green-Blue-Red +#: ../../po/../src/draw-context.cpp:441 +msgid "Path is closed." +msgstr "O caminho está fechado." + +#. We hit bot start and end of single curve, closing paths +#: ../../po/../src/draw-context.cpp:456 +msgid "Closing path." +msgstr "Fechando o caminho." + +#. alpha of color under cursor, to show in the statusbar +#. locale-sensitive printf is OK, since this goes to the UI, not into SVG +#: ../../po/../src/dropper-context.cpp:354 +#, c-format +msgid " alpha %.3g" +msgstr "alfa %.3g" + +#. where the color is picked, to show in the statusbar +#: ../../po/../src/dropper-context.cpp:356 +#, c-format +msgid ", averaged with radius %d" +msgstr ", médio com raio %d" + +#: ../../po/../src/dropper-context.cpp:356 +msgid " under cursor" +msgstr " sob cursor" + +#. message, to show in the statusbar +#: ../../po/../src/dropper-context.cpp:358 +msgid "Release mouse to set color." +msgstr "Libere o mouse para ajustar a cor." + +#: ../../po/../src/dropper-context.cpp:358 +#: ../../po/../src/tools-switch.cpp:207 +#, fuzzy +msgid "" +"Click to set fill, Shift+click to set stroke; drag to " +"average color in area; with Alt to pick inverse color; Ctrl+C " +"to copy the color under mouse to clipboard" +msgstr "" +"Clique para ajustar a cor de preenchimento. Clique com Shift " +"para ajustar a cor do traço. Clique e arraste para escolher a cor " +"média de uma área. UseCtrl+C para copiar a cor sob o mouse para a " +"área de transferência." + +#: ../../po/../src/extension/dependency.cpp:244 +msgid "Dependency::" +msgstr "" + +#: ../../po/../src/extension/dependency.cpp:245 +#, fuzzy +msgid " type: " +msgstr "T_ipo:" + +#: ../../po/../src/extension/dependency.cpp:246 +#, fuzzy +msgid " location: " +msgstr "Relação" + +#: ../../po/../src/extension/dependency.cpp:247 +msgid " string: " +msgstr "" + +#: ../../po/../src/extension/dependency.cpp:250 +#, fuzzy +msgid " description: " +msgstr "Descrição" + +#. static int i = 0; +#. std::cout << "Checking module[" << i++ << "]: " << name << std::endl; +#: ../../po/../src/extension/extension.cpp:244 +msgid "" +" This is caused by an improper .inx file for this extension. An improper ." +"inx file could have been caused by a faulty installation of Inkscape." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:247 +msgid "an ID was not defined for it." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:251 +msgid "there was no name defined for it." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:255 +msgid "the XML description of it got lost." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:259 +msgid "no implementation was defined for the extension." +msgstr "" + +#. std::cout << "Failed: " << *(_deps[i]) << std::endl; +#: ../../po/../src/extension/extension.cpp:266 +msgid "a dependency was not met." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:286 +#, fuzzy +msgid "Extension \"" +msgstr "Expansão:" + +#: ../../po/../src/extension/extension.cpp:286 +#, fuzzy +msgid "\" failed to load because " +msgstr "Falha ao carregar o arquivo %s" + +#: ../../po/../src/extension/extension.cpp:565 +#, fuzzy, c-format +msgid "Could not create extension error log file '%s'" +msgstr "Não foi possível exportar para o arquivo %s.\n" + +#. This is some filler text, needs to change before relase +#: ../../po/../src/extension/error-file.cpp:56 +msgid "" +"One or more extensions failed to load\n" +"\n" +"The failed extensions have been skipped. Inkscape will continue to run " +"normally but those extensions will be unavailable. For details to " +"troubleshoot this problem, please refer to the error log located at: " +msgstr "" + +#. This is some filler text, needs to change before relase +#: ../../po/../src/extension/error-file.cpp:65 +msgid "Show dialog on startup" +msgstr "" + +#: ../../po/../src/extension/implementation/script.cpp:845 +msgid "" +"Inkscape has received an error from the script that it called. The text " +"returned with the error is included below. Inkscape will continue working, " +"but the action you requested has been cancelled." +msgstr "" + +#: ../../po/../src/extension/implementation/script.cpp:858 +msgid "" +"Inkscape has received additional data from the script executed. The script " +"did not return an error, but this may indicate the results will not be as " +"expected." +msgstr "" + +#: ../../po/../src/extension/init.cpp:173 +#, fuzzy +msgid "Null external module directory name. Modules will not be loaded." +msgstr "" +"A pasta de módulos (%s) está indisponível. Módulos externos nesta pasta não " +"serão carregados." + +#: ../../po/../src/extension/init.cpp:187 +#, fuzzy, c-format +msgid "" +"Modules directory (%s) is unavailable. External modules in that directory " +"will not be loaded." +msgstr "" +"A pasta de módulos (%s) está indisponível. Módulos externos nesta pasta não " +"serão carregados." + +#: ../../po/../src/extension/internal/gnome.cpp:80 +msgid "Select printer" +msgstr "Selecionar impressora" + +#: ../../po/../src/extension/internal/gnome.cpp:131 +msgid "Inkscape: Print Preview" +msgstr "Inkscape: Visualizar impressão" + +#: ../../po/../src/extension/internal/grid.cpp:213 +#, fuzzy +msgid "Line Width" +msgstr "_Largura da Página" + +#: ../../po/../src/extension/internal/grid.cpp:214 +#, fuzzy +msgid "Horizontal Spacing" +msgstr "Texto horizontal" + +#: ../../po/../src/extension/internal/grid.cpp:215 +#, fuzzy +msgid "Vertical Spacing" +msgstr "Texto vertical" + +#: ../../po/../src/extension/internal/grid.cpp:216 +#, fuzzy +msgid "Horizontal Offset" +msgstr "Texto horizontal" + +#: ../../po/../src/extension/internal/grid.cpp:217 +#, fuzzy +msgid "Vertical Offset" +msgstr "Texto vertical" + +#: ../../po/../src/extension/internal/ps.cpp:123 +msgid "Print Destination" +msgstr "Destino da impressão" + +#. Print properties frame +#: ../../po/../src/extension/internal/ps.cpp:138 +msgid "Print properties" +msgstr "Propriedades da Impressão" + +#: ../../po/../src/extension/internal/ps.cpp:145 +msgid "Print using PostScript operators" +msgstr "Imprimir usando operadores PostScript" + +#: ../../po/../src/extension/internal/ps.cpp:147 +#, fuzzy +msgid "" +"Use PostScript vector operators. The resulting image is usually smaller in " +"file size and can be arbitrarily scaled, but alpha transparency and patterns " +"will be lost." +msgstr "" +"Use os operadores de vetores PostScript. A imagem resultante é geralmente " +"menor em tamanho e pode ser ampliada facilmente. Porém a transparência, os " +"gradientes e padrões são perdidos." + +#: ../../po/../src/extension/internal/ps.cpp:152 +msgid "Print as bitmap" +msgstr "Imprimir como figura" + +#: ../../po/../src/extension/internal/ps.cpp:154 +msgid "" +"Print everything as bitmap. The resulting image is usually larger in file " +"size and cannot be arbitrarily scaled without quality loss, but all objects " +"will be rendered exactly as displayed." +msgstr "" +"Imprimir tudo como figura. A imagem resultante é geralmente maior em tamanho " +"e não pode ser ampliada sem perda de qualidade. Porém todos os objetos são " +"gerados exatamente como mostrado." + +#: ../../po/../src/extension/internal/ps.cpp:168 +msgid "Preferred resolution (dots per inch) of bitmap" +msgstr "Resolução preferida para a figura (pontos por polegada)" + +#: ../../po/../src/extension/internal/ps.cpp:182 +msgid "Resolution:" +msgstr "Resolução:" + +#. Print destination frame +#: ../../po/../src/extension/internal/ps.cpp:186 +msgid "Print destination" +msgstr "Destino da impressão" + +#: ../../po/../src/extension/internal/ps.cpp:192 +msgid "" +"Use '> filename' to print to file.\n" +"Use '| prog arg...' to pipe to a program." +msgstr "" +"Use '> nomedearquivo.ext' para imprimir para um arquivo.\n" +"Use '| programa argumentos...' para direcionar para um programa." + +#: ../../po/../src/extension/internal/ps.cpp:1227 +msgid "write error occurred" +msgstr "Ocorreu um erro de escrita (qual eu não sei)" + +#: ../../po/../src/extension/prefdialog.cpp:21 +#, fuzzy +msgid " Preferences" +msgstr "Propriedades da Caneta" + +#. We can't call sp_ui_error_dialog because we may be +#. running from the console, in which case calling sp_ui +#. routines will cause a segfault. See bug 1000350 - bryce +#. sp_ui_error_dialog(_("Format autodetect failed. The file is being opened as SVG.")); +#: ../../po/../src/extension/system.cpp:105 +msgid "Format autodetect failed. The file is being opened as SVG." +msgstr "Detecção de formato falhou. O arquivo será aberto como SVG." + +#. TRANSLATORS: default.svg is localizable - this is the name of the default document +#. template. This way you can localize the default pagesize, translate the name of +#. the default layer, etc. If you wish to localize this file, please create a +#. localized share/templates/default.xx.svg file, where xx is your language code. +#: ../../po/../src/file.cpp:133 +#, fuzzy +msgid "default.svg" +msgstr "Padrões" + +#: ../../po/../src/file.cpp:215 ../../po/../src/file.cpp:900 +#, c-format +msgid "Failed to load the requested file %s" +msgstr "Falha ao carregar o arquivo %s" + +#: ../../po/../src/file.cpp:240 +msgid "Document not saved yet. Cannot revert." +msgstr "Desenho não foi salvo ainda. Não posso reverter." + +#: ../../po/../src/file.cpp:246 +#, c-format +msgid "Changes will be lost! Are you sure you want to reload document %s?" +msgstr "" +"As mudanças serão perdidas! Tem certeza que deseja recarregar o desenho %s?" + +#: ../../po/../src/file.cpp:266 +msgid "Document reverted." +msgstr "Desenho revertido." + +#: ../../po/../src/file.cpp:268 +msgid "Document not reverted." +msgstr "Desenho não foi revertido." + +#: ../../po/../src/file.cpp:382 +msgid "Select file to open" +msgstr "Selecionar um arquivo para abrir" + +#: ../../po/../src/file.cpp:518 +#, c-format +msgid "Removed %i unused definition in <defs>." +msgid_plural "Removed %i unused definitions in <defs>." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/file.cpp:523 +msgid "No unused definitions in <defs>." +msgstr "" + +#: ../../po/../src/file.cpp:548 +#, c-format +msgid "" +"No Inkscape extension found to save document (%s). This may have been " +"caused by an unknown filename extension." +msgstr "" +"Nenhum extensão do Inkscape foi encontrada para salvar o desenho (%s). Isto " +"deve ter sido causado por uma extensão de arquivo desconhecida." + +#: ../../po/../src/file.cpp:549 ../../po/../src/file.cpp:557 +msgid "Document not saved." +msgstr "Desenho não foi salvo." + +#: ../../po/../src/file.cpp:556 +#, c-format +msgid "File %s could not be saved." +msgstr "O arquivo %s não pode ser salvo." + +#: ../../po/../src/file.cpp:566 +msgid "Document saved." +msgstr "Desenho salvo." + +#: ../../po/../src/file.cpp:614 +#, c-format +msgid "drawing%s" +msgstr "desenho%s" + +#: ../../po/../src/file.cpp:620 +#, c-format +msgid "drawing-%d%s" +msgstr "desenho-%d%s" + +#: ../../po/../src/file.cpp:655 +msgid "Select file to save to" +msgstr "Selecionar um arquivo para salvar" + +#: ../../po/../src/file.cpp:739 +msgid "No changes need to be saved." +msgstr "Nenhuma mudança que precise ser salva." + +#: ../../po/../src/file.cpp:926 +msgid "Select file to import" +msgstr "Selecione o arquivo a importar" + +#: ../../po/../src/gradient-context.cpp:263 +#, fuzzy +msgid "Ctrl: snap gradient angle" +msgstr "Ctrl: agarra o ângulo" + +#: ../../po/../src/gradient-context.cpp:264 +#, fuzzy +msgid "Shift: draw gradient around the starting point" +msgstr "Shift: desenhar ao redor do ponto inicial" + +#. We did an undoable action, but sp_document_done will be called by the knot when released +#. status text; we do not track coords because this branch is run once, not all the time +#. during drag +#: ../../po/../src/gradient-context.cpp:462 +#, fuzzy, c-format +msgid "Gradient for %d objects; with Ctrl to snap angle" +msgstr "" +"Espiral: raio %s, ângulo %5g; com Ctrl para agarrar o ângulo" + +#: ../../po/../src/gradient-context.cpp:464 +#, fuzzy +msgid "Select objects on which to create gradient." +msgstr "Selecione algum objetos para levantar." + +#: ../../po/../src/gradient-drag.cpp:65 +#, fuzzy +msgid "Linear gradient start" +msgstr "Gradiente linear" + +#. POINT_LG_P1 +#: ../../po/../src/gradient-drag.cpp:66 +#, fuzzy +msgid "Linear gradient end" +msgstr "Gradiente linear" + +#: ../../po/../src/gradient-drag.cpp:67 +#, fuzzy +msgid "Radial gradient center" +msgstr "Gradiente radial" + +#: ../../po/../src/gradient-drag.cpp:68 ../../po/../src/gradient-drag.cpp:69 +#, fuzzy +msgid "Radial gradient radius" +msgstr "Gradiente radial" + +#: ../../po/../src/gradient-drag.cpp:70 +#, fuzzy +msgid "Radial gradient focus" +msgstr "Gradiente radial" + +#: ../../po/../src/gradient-drag.cpp:659 +#, fuzzy, c-format +msgid "" +"%s for: %s%s; drag with Ctrl to snap angle, with Ctrl+Alt to " +"preserve angle, with Ctrl+Shift to scale around center" +msgstr "" +"Enrolar/Desenrolar a espiral do interior; com Ctrl para " +"agarrar; com Alt para convergir/divergir" + +#: ../../po/../src/gradient-drag.cpp:662 +msgid " (stroke)" +msgstr "" + +#: ../../po/../src/gradient-drag.cpp:665 +msgid "" +"Radial gradient center and focus; drag with Shift to " +"separate focus" +msgstr "" + +#: ../../po/../src/gradient-drag.cpp:667 +#, c-format +msgid "" +"Gradient point shared by %d gradients; drag with Shift to " +"separate" +msgstr "" + +#: ../../po/../src/helper/units.cpp:40 +msgid "Unit" +msgstr "Unidade" + +#: ../../po/../src/helper/units.cpp:40 +msgid "Units" +msgstr "Unidades" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Point" +msgstr "Ponto" + +#: ../../po/../src/helper/units.cpp:41 +msgid "pt" +msgstr "pt" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Points" +msgstr "Pontos" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Pt" +msgstr "Pt" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Pixel" +msgstr "Pixel" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Pixels" +msgstr "Pixels" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Px" +msgstr "Px" + +#. You can add new elements from this point forward +#: ../../po/../src/helper/units.cpp:44 ../share/extensions/straightseg.inx.h:2 +msgid "Percent" +msgstr "Percentual" + +#: ../../po/../src/helper/units.cpp:44 +msgid "Percents" +msgstr "Percentuais" + +#: ../../po/../src/helper/units.cpp:45 +msgid "Millimeter" +msgstr "Milímetro" + +#: ../../po/../src/helper/units.cpp:45 +msgid "mm" +msgstr "mm" + +#: ../../po/../src/helper/units.cpp:45 +msgid "Millimeters" +msgstr "Milímetros" + +#: ../../po/../src/helper/units.cpp:46 +msgid "Centimeter" +msgstr "Centímetro" + +#: ../../po/../src/helper/units.cpp:46 +msgid "cm" +msgstr "cm" + +#: ../../po/../src/helper/units.cpp:46 +msgid "Centimeters" +msgstr "Centímetros" + +#: ../../po/../src/helper/units.cpp:47 +msgid "Meter" +msgstr "Metro" + +#: ../../po/../src/helper/units.cpp:47 +msgid "m" +msgstr "m" + +#: ../../po/../src/helper/units.cpp:47 +msgid "Meters" +msgstr "Metros" + +#. no svg_unit +#: ../../po/../src/helper/units.cpp:48 +msgid "Inch" +msgstr "Polegada" + +#: ../../po/../src/helper/units.cpp:48 +msgid "in" +msgstr "in" + +#: ../../po/../src/helper/units.cpp:48 +msgid "Inches" +msgstr "Polegadas" + +#. Volatiles do not have default, so there are none here +#. TRANSLATORS: for info, see http://www.w3.org/TR/REC-CSS2/syndata.html#length-units +#: ../../po/../src/helper/units.cpp:51 +msgid "Em square" +msgstr "Quadras Em" + +#: ../../po/../src/helper/units.cpp:51 +msgid "em" +msgstr "em" + +#: ../../po/../src/helper/units.cpp:51 +msgid "Em squares" +msgstr "Quadras Em" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/REC-CSS2/syndata.html#length-units +#: ../../po/../src/helper/units.cpp:53 +msgid "Ex square" +msgstr "Quadra Ex" + +#: ../../po/../src/helper/units.cpp:53 +msgid "ex" +msgstr "ex" + +#: ../../po/../src/helper/units.cpp:53 +msgid "Ex squares" +msgstr "Quadras Ex" + +#: ../../po/../src/inkscape.cpp:468 +msgid "Untitled document" +msgstr "Desenho sem título" + +#. Show nice dialog box +#: ../../po/../src/inkscape.cpp:497 +msgid "Inkscape encountered an internal error and will close now.\n" +msgstr "O Inkscape encontrou um erro interno e será fechado agora.\n" + +#: ../../po/../src/inkscape.cpp:498 +msgid "" +"Automatic backups of unsaved documents were done to the following " +"locations:\n" +msgstr "" +"Cópias de segurança de desenhos não salvos foram feitas para os seguintes " +"lugares:\n" + +#: ../../po/../src/inkscape.cpp:499 +msgid "Automatic backup of the following documents failed:\n" +msgstr "A cópia de segurança automática dos seguintes desenhos falhor:\n" + +#: ../../po/../src/inkscape.cpp:634 +#, c-format +msgid "" +"Cannot create directory %s.\n" +"%s" +msgstr "" +"Não foi possível criar a pasta %s.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:635 +#, c-format +msgid "" +"%s is not a valid directory.\n" +"%s" +msgstr "" +"%s não é uma pasta válida.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:636 +#, c-format +msgid "" +"Cannot create file %s.\n" +"%s" +msgstr "" +"Não foi possível criar o arquivo %s.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:637 +#, c-format +msgid "" +"Cannot write file %s.\n" +"%s" +msgstr "" +"Não foi possível modificar o arquivo %s.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:638 +msgid "" +"Although Inkscape will run, it will use default settings,\n" +"and any changes made in preferences will not be saved." +msgstr "" +"Embora o Inkscape funcionará, ele usará as configurações padrão,\n" +"e quaisquer mudanças feitas nelas não serão salvas." + +#: ../../po/../src/inkscape.cpp:708 +#, c-format +msgid "" +"%s is not a regular file.\n" +"%s" +msgstr "" +"%s não é um arquivo comum.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:709 +#, c-format +msgid "" +"%s not a valid XML file, or\n" +"you don't have read permissions on it.\n" +"%s" +msgstr "" +"%s não é um arquvio XML válido, ou\n" +"você não tem permissões de leitura nele.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:711 +#, fuzzy, c-format +msgid "" +"%s is not a valid menus file.\n" +"%s" +msgstr "" +"%s não é um arquivo de configurações válido.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:712 +#, fuzzy +msgid "" +"Inkscape will run with default menus.\n" +"New menus will not be saved." +msgstr "" +"O Inkscape funcionará com as configurações padrão.\n" +"Novas configurações não serão salvas." + +#. sp_ui_menu_append_check_item_from_verb(m, view, _("_Menu"), _("Show or hide the menu bar"), "menu", +#. checkitem_toggled, checkitem_update, 0); +#: ../../po/../src/interface.cpp:753 +msgid "Commands Bar" +msgstr "Barra de Comandos" + +#: ../../po/../src/interface.cpp:753 +msgid "Show or hide the Commands bar (under the menu)" +msgstr "Mostrar ou esconder a Barra de Comandos (sob o menu)" + +#: ../../po/../src/interface.cpp:755 +msgid "Tool Controls" +msgstr "_Controles de Ferramenta" + +#: ../../po/../src/interface.cpp:755 +msgid "Show or hide the Tool Controls panel" +msgstr "Mostra ou esconde o painel de Controle de Ferramentas" + +#: ../../po/../src/interface.cpp:757 +msgid "_Toolbox" +msgstr "Caixa de _Ferramentas" + +#: ../../po/../src/interface.cpp:757 +msgid "Show or hide the main toolbox (on the left)" +msgstr "Mostrar ou esconder a caixa de ferramentas principal (à esquerda)" + +#: ../../po/../src/interface.cpp:763 +msgid "_Statusbar" +msgstr "Barra de E_stado" + +#: ../../po/../src/interface.cpp:763 +msgid "Show or hide the statusbar (at the bottom of the window)" +msgstr "Mostra ou esconde a barra de estado (em baixo na janela)" + +#: ../../po/../src/interface.cpp:820 +#, c-format +msgid "Verb \"%s\" Unknown" +msgstr "" + +#. TRANSLATORS: #%s is the id of the group e.g. , not a number. +#: ../../po/../src/interface.cpp:930 +#, fuzzy, c-format +msgid "Enter group #%s" +msgstr "Alterar grupo #%s" + +#: ../../po/../src/interface.cpp:941 +#, fuzzy +msgid "Go to parent" +msgstr "Nenhuma pintura" + +#: ../../po/../src/interface.cpp:972 +msgid "Could not parse SVG data" +msgstr "Não foi possível interpretar os dados do SVG" + +#: ../../po/../src/interface.cpp:1135 +#, c-format +msgid "Overwrite %s" +msgstr "Sobrescrever %s" + +#: ../../po/../src/interface.cpp:1153 +#, c-format +msgid "" +"The file %s already exists. Do you want to overwrite that file with the " +"current document?" +msgstr "" +"O arquivo %s já existe. Você deseja sobrescrever este arquivo com o desenho " +"atual?" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:59 +msgid "Jabber connection lost." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:72 +#, c-format +msgid "Sending message; %u message remaining in send queue." +msgid_plural "Sending message; %u messages remaining in send queue." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:78 +msgid "Receive queue empty." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:154 +#, c-format +msgid "Receiving change; %u change left to process." +msgid_plural "Receiving change; %u changes left to process." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:157 +#, c-format +msgid "%s has left the chatroom." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:221 +msgid "Nickname %1 is already in use. Please choose a different nickname." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:225 +msgid "An error was encountered while attempting to connect to the server." +msgstr "" + +#. Check to see if the user made any modifications to this document. If so, +#. we want to give them the option of (1) letting us clear their document or (2) +#. opening a new, blank document for the whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:131 +msgid "%1 has invited you to a whiteboard session." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:132 +msgid "Incoming whiteboard invitation from %1" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:135 +msgid "Do you wish to accept %1's whiteboard session invitation?" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:137 +msgid "" +"Would you like to accept %1's invitation in a new document window?\n" +"Accepting the invitation in your current window will discard unsaved changes." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:143 +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:198 +#, fuzzy +msgid "Accept invitation" +msgstr "Aceleração:" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:144 +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:199 +msgid "Decline invitation" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:145 +#, fuzzy +msgid "Accept invitation in new document window" +msgstr "Cria um novo desenho" + +#. We could not create a new desktop; ask the user if she or he wants to +#. replace the current document and accept the invitation, or reject the invitation. +#. TRANSLATORS: %1 is a userid here +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:196 +msgid "" +"A new document window could not be opened for a whiteboard session with %" +"1" +msgstr "" + +#. TRANSLATORS: %1 is the peer whom refused our invitation. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:238 +msgid "" +"The user %1 has refused your " +"whiteboard invitation.\n" +"\n" +msgstr "" + +#. TRANSLATORS: %1 is the peer whom refused our invitation, %2 is our Jabber identity. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:241 +msgid "" +"You are still connected to a Jabber server as %2, and may send an " +"invitation to %1 again, or you may send an invitation to a different " +"user." +msgstr "" + +#. TRANSLATORS: %1 is the peer whom we tried to contact, but is already in a whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:252 +msgid "" +"The user %1 is already in a " +"whiteboard session.\n" +"\n" +msgstr "" + +#. TRANSLATORS: %1 is the peer whom we tried to contact, but is already in a whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:255 +msgid "" +"You are still connected to a Jabber server as %1, and may send an " +"invitation to a different user." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/invitation-confirm-dialog.cpp:26 +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:24 +msgid "_Write session file:" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/message-processors.cpp:145 +#, c-format +msgid "%s has joined the chatroom." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/message-queue.cpp:87 +#, fuzzy, c-format +msgid "%u change in receive queue." +msgid_plural "%u changes in receive queue." +msgstr[0] "Nenhuma mudança que precise ser salva." +msgstr[1] "Nenhuma mudança que precise ser salva." + +#: ../../po/../src/jabber_whiteboard/message-queue.cpp:117 +#, fuzzy, c-format +msgid "%u change in send queue." +msgid_plural "%u changes in send queue." +msgstr[0] "Nenhuma mudança que precise ser salva." +msgstr[1] "Nenhuma mudança que precise ser salva." + +#. if ID is NULL, then we have a real problem -- we were not able to find a key +#. nor generate one. The only thing we can really do here is abort, since we have +#. no way to let the other client(s) uniquely identify this object. +#. FIXME: If this indicates a programming bug, then don't request translation with +#. * _(...): it is most useful in untranslated form so that developers may search for +#. * it when someone reports it in a bug report (as we want users to do for all bugs, +#. * as indicated by it being a g_warning string). +#. * +#. * Otherwise, if it is not a programming bug but a network error or a bug in the +#. * remote peer (perhaps running different software) or whatever, then present it in +#. * an alert box, and avoid use of technical jargon `NULL'. +#. +#: ../../po/../src/jabber_whiteboard/message-utilities.cpp:171 +msgid "" +"ID for new object is NULL even after generation and lookup attempts: the new " +"object will NOT be sent, nor will any of its child objects!" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:60 +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:995 +msgid "Select a location and filename" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:62 +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:997 +#, fuzzy +msgid "Set filename" +msgstr "Nome do arquivo" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:301 +msgid "No SSL certificate was found." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:304 +msgid "The SSL certificate provided by the Jabber server is untrusted." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:307 +msgid "The SSL certificate provided by the Jabber server is expired." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:310 +msgid "" +"The SSL certificate provided by the Jabber server has not been activated." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:313 +msgid "" +"The SSL certificate provided by the Jabber server contains a hostname that " +"does not match the Jabber server's hostname." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:316 +msgid "" +"The SSL certificate provided by the Jabber server contains an invalid " +"fingerprint." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:319 +msgid "An unknown error occurred while setting up the SSL connection." +msgstr "" + +#. TRANSLATORS: %1 is the message that describes the specific error that occurred when +#. establishing the SSL connection. +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:325 +msgid "" +"%1\n" +"\n" +"Do you wish to continue connecting to the Jabber server?" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:328 +msgid "Continue connecting and ignore further errors" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:329 +msgid "Continue connecting, but warn me of further errors" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:330 +#, fuzzy +msgid "Cancel connection" +msgstr "Seleção" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:777 +#, c-format +msgid "Established whiteboard session with %s." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:785 +#, c-format +msgid "%s has left the whiteboard session." +msgstr "" + +#. Inform the user +#. TRANSLATORS: %1 is the name of the user that disconnected, %2 is the name of the user whom the disconnected user disconnected from. +#. This message is not used in a chatroom context. +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:790 +msgid "" +"The user %1 has left the " +"whiteboard session.\n" +"\n" +msgstr "" + +#. TRANSLATORS: %1 and %2 are userids +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:792 +msgid "" +"You are still connected to a Jabber server as %2, and may establish a " +"new session to %1 or a different user." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:988 +msgid "" +"Could not open file %1 for session recording.\n" +"The error encountered was: %2.\n" +"\n" +"You may select a different location to record the session, or you may opt to " +"not record this session." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:990 +msgid "Choose a different location" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:991 +msgid "Skip session recording" +msgstr "" + +#: ../../po/../src/knot.cpp:673 +msgid "Node or handle drag canceled." +msgstr "Arrasto de nó ou alça cancelado." + +#: ../../po/../src/libnrtype/FontFactory.cpp:358 +msgid "Ignoring font without family that will crash Pango" +msgstr "" + +#: ../../po/../src/main.cpp:395 +msgid "Print the Inkscape version number" +msgstr "Imprimir o número de versão do Inkscape" + +#: ../../po/../src/main.cpp:400 +msgid "Do not use X server (only process files from console)" +msgstr "Não usar o servidor X (somente arquivos de processos do console)" + +#: ../../po/../src/main.cpp:405 +msgid "Try to use X server (even if $DISPLAY is not set)" +msgstr "Tente usar o servidor X (mesmo se $DISPLAY não foi definido)" + +#: ../../po/../src/main.cpp:410 +msgid "Open specified document(s) (option string may be excluded)" +msgstr "" +"Abrir o(s) desenho(s) especificado(s) (frase de opção pode ser excluída)" + +#: ../../po/../src/main.cpp:411 ../../po/../src/main.cpp:416 +#: ../../po/../src/main.cpp:421 ../../po/../src/main.cpp:483 +#: ../../po/../src/main.cpp:488 ../../po/../src/main.cpp:493 +msgid "FILENAME" +msgstr "ARQUIVO" + +#: ../../po/../src/main.cpp:415 +msgid "Print document(s) to specified output file (use '| program' for pipe)" +msgstr "" +"Imprimir desenho(s) para arquivo especificado ( use '| programa' para " +"redirecionamento)" + +#: ../../po/../src/main.cpp:420 +msgid "Export document to a PNG file" +msgstr "Exportar desenho para um arquivo PNG" + +#: ../../po/../src/main.cpp:425 +#, fuzzy +msgid "The resolution used for exporting SVG into bitmap (default 90)" +msgstr "A resolução usada para converter o SVG numa figura (padrão 72)" + +#: ../../po/../src/main.cpp:426 +msgid "DPI" +msgstr "DPI" + +#: ../../po/../src/main.cpp:430 +#, fuzzy +msgid "" +"Exported area in SVG user units (default is the canvas; 0,0 is lower-left " +"corner)" +msgstr "" +"Área exportada em milímetros (padrão é todo o desenho, 0,0 é o canto " +"esquerdo inferior" + +#: ../../po/../src/main.cpp:431 +msgid "x0:y0:x1:y1" +msgstr "x0:y0:x1:y1" + +#: ../../po/../src/main.cpp:435 +msgid "Exported area is the entire drawing (not canvas)" +msgstr "" + +#: ../../po/../src/main.cpp:440 +msgid "" +"Snap the bitmap export area outwards to the nearest integer values (in SVG " +"user units)" +msgstr "" + +#: ../../po/../src/main.cpp:445 +msgid "The width of exported bitmap in pixels (overrides export-dpi)" +msgstr "A largura da figura exportada em pixels (sobrescreve export-dpi)" + +#: ../../po/../src/main.cpp:446 +msgid "WIDTH" +msgstr "LARGURA" + +#: ../../po/../src/main.cpp:450 +msgid "The height of exported bitmap in pixels (overrides export-dpi)" +msgstr "A altura da figura exportadaa em pixels (sobrescreve export-dpi)" + +#: ../../po/../src/main.cpp:451 +msgid "HEIGHT" +msgstr "ALTURA" + +#: ../../po/../src/main.cpp:455 +msgid "The ID of the object to export (overrides export-area)" +msgstr "O ID do objeto para exportar (sobrescreve área-de-exportação)" + +#: ../../po/../src/main.cpp:456 ../../po/../src/main.cpp:532 +msgid "ID" +msgstr "ID" + +#. TRANSLATORS: this means: "Only export the object whose id is given in --export-id". +#. See "man inkscape" for details. +#: ../../po/../src/main.cpp:462 +msgid "" +"Export just the object with export-id, hide all others (only with export-id)" +msgstr "" +"Exportar somente o objeto com id-exportação, esconder todos os outros " +"(somente com id-exportação)" + +#: ../../po/../src/main.cpp:467 +msgid "Use stored filename and DPI hints when exporting (only with export-id)" +msgstr "" +"Usar nome de arquivo armazenado e dicas de DPI ao exportar (somente com id-" +"exportação)" + +#: ../../po/../src/main.cpp:472 +msgid "Background color of exported bitmap (any SVG-supported color string)" +msgstr "Cor de fundo da figura exportada (qualquer palavra de cor do SVG)" + +#: ../../po/../src/main.cpp:473 +msgid "COLOR" +msgstr "COR" + +#: ../../po/../src/main.cpp:477 +msgid "Background opacity of exported bitmap (either 0.0 to 1.0, or 1 to 255)" +msgstr "Opacidado do fundo da figura exportada (De 0 a 1, ou 1 a 255)" + +#: ../../po/../src/main.cpp:478 +msgid "VALUE" +msgstr "VALOR" + +#: ../../po/../src/main.cpp:482 +msgid "Export document to plain SVG file (no sodipodi or inkscape namespaces)" +msgstr "" +"Exportar o desenho para um arquivo SVG simples (sem namespaces sodipodi ou " +"inkscape)" + +#: ../../po/../src/main.cpp:487 +#, fuzzy +msgid "Export document to a PS file" +msgstr "Exportar desenho para um arquivo PNG" + +#: ../../po/../src/main.cpp:492 +#, fuzzy +msgid "Export document to an EPS file" +msgstr "Exportar desenho para um arquivo PNG" + +#: ../../po/../src/main.cpp:497 +#, fuzzy +msgid "Convert text object to paths on export (EPS)" +msgstr "Converter objeto da figura para caminhos" + +#: ../../po/../src/main.cpp:502 +msgid "Export files with the bounding box set to the page size (EPS)" +msgstr "" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:508 +msgid "" +"Query the X coordinate of the drawing or, if specified, of the object with --" +"query-id" +msgstr "" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:514 +msgid "" +"Query the Y coordinate of the drawing or, if specified, of the object with --" +"query-id" +msgstr "" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:520 +msgid "" +"Query the width of the drawing or, if specified, of the object with --query-" +"id" +msgstr "" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:526 +msgid "" +"Query the height of the drawing or, if specified, of the object with --query-" +"id" +msgstr "" + +#: ../../po/../src/main.cpp:531 +#, fuzzy +msgid "The ID of the object whose dimensions are queried" +msgstr "O ID do objeto para exportar (sobrescreve área-de-exportação)" + +#. TRANSLATORS: this option makes Inkscape print the name (path) of the extension directory +#: ../../po/../src/main.cpp:537 +msgid "Print out the extension directory and exit" +msgstr "" + +#: ../../po/../src/main.cpp:542 +msgid "Show given files one-by-one, switch to next on any key/mouse event" +msgstr "" +"Mostrar os arquivo um a um e pula para o próximo em qualquer tecla ou clique" + +#: ../../po/../src/main.cpp:547 +msgid "Use the new Gtkmm GUI interface" +msgstr "" + +#: ../../po/../src/main.cpp:552 +#, fuzzy +msgid "Remove unused definitions from the defs section(s) of the document" +msgstr "Apagar coisas não usadas nos <defs> do desenho" + +#: ../../po/../src/main.cpp:741 +msgid "" +"[OPTIONS...] [FILE...]\n" +"\n" +"Available options:" +msgstr "" +"[OPÇÕES...] [ARQUIVO...]\n" +"\n" +"Opções disponíveis:" + +#: ../../po/../src/menus-skeleton.h:17 +msgid "_New" +msgstr "_Novo" + +#: ../../po/../src/menus-skeleton.h:22 +msgid "Open _Recent" +msgstr "Abrir _Recentes" + +#: ../../po/../src/menus-skeleton.h:53 +msgid "_Edit" +msgstr "_Editar" + +#: ../../po/../src/menus-skeleton.h:84 +msgid "_View" +msgstr "E_xibir" + +#: ../../po/../src/menus-skeleton.h:85 +#, fuzzy +msgid "_Zoom" +msgstr "Ampliação" + +#: ../../po/../src/menus-skeleton.h:102 +#, fuzzy +msgid "Show/Hide" +msgstr "Mo_strar/Esconder" + +#: ../../po/../src/menus-skeleton.h:107 +msgid "_Display mode" +msgstr "" + +#: ../../po/../src/menus-skeleton.h:126 +msgid "_Layer" +msgstr "Ca_mada" + +#: ../../po/../src/menus-skeleton.h:143 +msgid "_Object" +msgstr "_Objeto" + +#: ../../po/../src/menus-skeleton.h:165 +msgid "_Path" +msgstr "_Caminho" + +#: ../../po/../src/menus-skeleton.h:188 +msgid "_Text" +msgstr "_Texto" + +#: ../../po/../src/menus-skeleton.h:200 +#, fuzzy +msgid "Effects" +msgstr "Tipográficos" + +#: ../../po/../src/menus-skeleton.h:207 +msgid "Whiteboa_rd" +msgstr "" + +#: ../../po/../src/menus-skeleton.h:220 +msgid "_Help" +msgstr "Aj_uda" + +#: ../../po/../src/menus-skeleton.h:222 +#, fuzzy +msgid "Tutorials" +msgstr "_Tutoriais" + +#: ../../po/../src/node-context.cpp:382 +msgid "" +"Ctrl: toggle node type, snap handle angle, move hor/vert; Ctrl" +"+Alt: move along handles" +msgstr "" +"Ctrl: muda o tipo do nó, agarra o ângulo da alça, move hor/vert; " +"Ctrl+Alt: move ao longo da alça" + +#: ../../po/../src/node-context.cpp:383 +msgid "" +"Shift: toggle node selection, disable snapping, rotate both handles" +msgstr "" +"Shift: muda a seleção de nó, desabilitando agarramento, rodando ambas " +"as alças" + +#: ../../po/../src/node-context.cpp:384 +msgid "Alt: lock handle length; Ctrl+Alt: move along handles" +msgstr "" +"Alt: travar o tamanho da alça. Ctrl+Alt: mover ao longo da alça" + +#: ../../po/../src/nodepath.cpp:1399 ../../po/../src/nodepath.cpp:1411 +#: ../../po/../src/nodepath.cpp:1492 ../../po/../src/nodepath.cpp:1504 +msgid "To join, you must have two endnodes selected." +msgstr "Para juntar, você deve ter dois nós finais selecionados." + +#: ../../po/../src/nodepath.cpp:1633 ../../po/../src/nodepath.cpp:1647 +msgid "" +"Select two non-endpoint nodes on a path between which to delete " +"segments." +msgstr "" +"Você precisa selecionar dois pontos não finais num caminho para " +"apagar os segmentos" + +#: ../../po/../src/nodepath.cpp:1743 +msgid "Cannot find path between nodes." +msgstr "Não foi possível encontrar o caminho entre os nós." + +#: ../../po/../src/nodepath.cpp:2822 +#, fuzzy, c-format +msgid "" +"Node handle: angle %0.2f°, length %s; with Ctrl to snap " +"angle; with Alt to lock length; with Shift to rotate both " +"handles" +msgstr "" +"Alça do Nó: arraste para mudar a forma da curva; com Ctrl para " +"agarrar ao ângulo; com Alt para travar o tamanho; com Shift " +"para rodar a alça oposta em sincronia" + +#: ../../po/../src/nodepath.cpp:3351 +msgid "" +"Node: drag to edit the path; with Ctrl to snap to horizontal/" +"vertical; with Ctrl+Alt to snap to handles' directions" +msgstr "" +"Nó: arraste para alterar o caminho; com Ctrl para agarrar na " +"horizontal/vertical; Ctrl+Alt para agarrar nas direções das alças" + +#: ../../po/../src/nodepath.cpp:3375 +#, fuzzy +msgid "" +"Node handle: drag to shape the curve; with Ctrl to snap angle; " +"with Alt to lock length; with Shift to rotate both handles" +msgstr "" +"Alça do Nó: arraste para mudar a forma da curva; com Ctrl para " +"agarrar ao ângulo; com Alt para travar o tamanho; com Shift " +"para rodar a alça oposta em sincronia" + +#: ../../po/../src/nodepath.cpp:3399 +msgid "" +"Node handle: drag to shape the curve; with Ctrl to snap angle; " +"with Alt to lock length; with Shift to rotate the opposite " +"handle in sync" +msgstr "" +"Alça do Nó: arraste para mudar a forma da curva; com Ctrl para " +"agarrar ao ângulo; com Alt para travar o tamanho; com Shift " +"para rodar a alça oposta em sincronia" + +#. TRANSLATORS: "end" is an adjective here (NOT a verb) +#: ../../po/../src/nodepath.cpp:3591 +#, fuzzy +msgid "end node" +msgstr "Edentar nó" + +#. TRANSLATORS: "cusp" means "sharp" (cusp node); see also the Advanced Tutorial +#: ../../po/../src/nodepath.cpp:3596 +msgid "cusp" +msgstr "agudo" + +#. TRANSLATORS: "smooth" is an adjective here +#: ../../po/../src/nodepath.cpp:3599 +msgid "smooth" +msgstr "suave" + +#: ../../po/../src/nodepath.cpp:3601 +msgid "symmetric" +msgstr "simétrico" + +#. TRANSLATORS: "end" is an adjective here (NOT a verb) +#: ../../po/../src/nodepath.cpp:3607 +msgid "end node, handle retracted (drag with Shift to extend)" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3609 +msgid "one handle retracted (drag with Shift to extend)" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3612 +msgid "both handles retracted (drag with Shift to extend)" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3624 +#, fuzzy +msgid "Drag nodes or node handles; arrow keys to move nodes" +msgstr "Arraste os nós ou alças de controle para editar o caminho" + +#: ../../po/../src/nodepath.cpp:3625 +#, fuzzy +msgid "Drag the node or its handles; arrow keys to move the node" +msgstr "" +"Arraste para criar uma linha à mão-livre. Pressione a para " +"trocar entre Acrescentar/Novo." + +#: ../../po/../src/nodepath.cpp:3651 ../../po/../src/nodepath.cpp:3663 +#, fuzzy +msgid "Select a single object to edit its nodes or handles." +msgstr "Selecionar todos os objetos ou todos os nós" + +#: ../../po/../src/nodepath.cpp:3655 +#, fuzzy, c-format +msgid "" +"0 out of %i node selected. Click, Shift+click, " +"or drag around nodes to select." +msgid_plural "" +"0 out of %i nodes selected. Click, Shift+click, " +"or drag around nodes to select." +msgstr[0] "" +"0 de %i nós selecionados. Clique, Clique com Shift ou arraste " +"ao redor dos nós para selecionar." +msgstr[1] "" +"0 de %i nós selecionados. Clique, Clique com Shift ou arraste " +"ao redor dos nós para selecionar." + +#: ../../po/../src/nodepath.cpp:3661 +#, fuzzy +msgid "Drag the handles of the object to modify it." +msgstr "Cada objeto selecionado exibe sua caixa de limites" + +#: ../../po/../src/nodepath.cpp:3669 +#, fuzzy, c-format +msgid "%i of %i node selected; %s. %s." +msgid_plural "%i of %i nodes selected; %s. %s." +msgstr[0] "%i de %i nós selecionados; %s. %s." +msgstr[1] "%i de %i nós selecionados; %s. %s." + +#: ../../po/../src/nodepath.cpp:3675 +#, fuzzy, c-format +msgid "%i of %i node selected. %s." +msgid_plural "%i of %i nodes selected. %s." +msgstr[0] "%i de %i nós selecionados; %s." +msgstr[1] "%i de %i nós selecionados; %s." + +#: ../../po/../src/object-edit.cpp:493 +msgid "" +"Adjust the horizontal rounding radius; with Ctrl to make the " +"vertical radius the same" +msgstr "" +"Ajustar o raio de arredondamento horizontal; com Ctrl para " +"fazer no raio vertical o mesmo" + +#: ../../po/../src/object-edit.cpp:499 +msgid "" +"Adjust the vertical rounding radius; with Ctrl to make the " +"horizontal radius the same" +msgstr "" +"Ajustar o raio de arredondamento vertical; com Ctrl para fazer " +"no raio horizontal o mesmo" + +#: ../../po/../src/object-edit.cpp:506 ../../po/../src/object-edit.cpp:513 +msgid "" +"Adjust the width and height of the rectangle; with Ctrl to " +"lock ratio or stretch in one dimension only" +msgstr "" +"Ajustar a largura e altura do retângulo; com Ctrlpara travar a " +"proporção ou esticar somente numa dimensão" + +#: ../../po/../src/object-edit.cpp:686 +msgid "Adjust ellipse width, with Ctrl to make circle" +msgstr "" +"Ajustar a largura da elipse, com Ctrl para formar um círculo" + +#: ../../po/../src/object-edit.cpp:689 +msgid "Adjust ellipse height, with Ctrl to make circle" +msgstr "" +"Ajustar a altura da elipse, com Ctrl para formar um círculo" + +#: ../../po/../src/object-edit.cpp:692 +msgid "" +"Position the start point of the arc or segment; with Ctrl to " +"snap angle; drag inside the ellipse for arc, outside for " +"segment" +msgstr "" +"Posiciona o ponto inicial do arco ou segmento; com Ctrl para " +"agarrar o ângulo; arraste para dentro da elipse para um arco, para " +"fora para um segmento" + +#: ../../po/../src/object-edit.cpp:695 +msgid "" +"Position the end point of the arc or segment; with Ctrl to " +"snap angle; drag inside the ellipse for arc, outside for " +"segment" +msgstr "" +"Posicionar o ponto final do arco ou segment; com Ctrl para " +"agarrar ao ângulo; arraste para dentro da elipse para um arco, " +"para fora para um segmento" + +#: ../../po/../src/object-edit.cpp:800 +msgid "" +"Adjust the tip radius of the star or polygon; with Shift to " +"round; with Alt to randomize" +msgstr "" +"Ajusta o raio de dica da estrela ou polígono; com Shift para " +"arredondar; com Alt para aleatório" + +#: ../../po/../src/object-edit.cpp:803 +msgid "" +"Adjust the base radius of the star; with Ctrl to keep star " +"rays radial (no skew); with Shift to round; with Alt to " +"randomize" +msgstr "" +"Ajusta o raio de base da estrela ou polígono; com Ctrl para " +"manter os raios das estrelas radiais (nenhuma inclinação); com Shiftpara arredondar; com Alt para aleatório" + +#: ../../po/../src/object-edit.cpp:967 +msgid "" +"Roll/unroll the spiral from inside; with Ctrl to snap angle; " +"with Alt to converge/diverge" +msgstr "" +"Enrolar/Desenrolar a espiral do interior; com Ctrl para " +"agarrar; com Alt para convergir/divergir" + +#: ../../po/../src/object-edit.cpp:969 +msgid "" +"Roll/unroll the spiral from outside; with Ctrl to snap angle; " +"with Shift to scale/rotate" +msgstr "" +"Enrolar/Desenrolar a espiral do exterior; com Ctrl para " +"agarrar o ângulo; com Shift para dimensionar/girar" + +#: ../../po/../src/object-edit.cpp:1006 +msgid "Adjust the offset distance" +msgstr "Ajustar a distância de compensação" + +#. TRANSLATORS: This refers to the pattern that's inside the object +#: ../../po/../src/object-edit.cpp:1036 +msgid "Move the pattern fill inside the object" +msgstr "Mover o padrão de preenchimento para dentro do objeto" + +#: ../../po/../src/object-edit.cpp:1038 +msgid "Scale the pattern fill uniformly" +msgstr "Dimensionar o padrão de preenchimento uniformemente" + +#: ../../po/../src/object-edit.cpp:1040 +msgid "Rotate the pattern fill; with Ctrl to snap angle" +msgstr "" +"Girar o padrão de preenchimento; com Ctrl para agarrar o ângulo" + +#: ../../po/../src/object-edit.cpp:1065 +msgid "Drag to resize the flowed text frame" +msgstr "" + +#. Item dialog +#: ../../po/../src/object-ui.cpp:106 +#, fuzzy +msgid "Object _Properties" +msgstr "Propriedades do _Objeto" + +#. Select item +#: ../../po/../src/object-ui.cpp:116 +msgid "_Select This" +msgstr "_Selecionar Isto" + +#. Create link +#: ../../po/../src/object-ui.cpp:126 +msgid "_Create Link" +msgstr "_Criar Ligação" + +#. "Ungroup" +#: ../../po/../src/object-ui.cpp:199 ../../po/../src/verbs.cpp:1931 +msgid "_Ungroup" +msgstr "Desagr_upar" + +#. Link dialog +#: ../../po/../src/object-ui.cpp:239 +msgid "Link _Properties" +msgstr "Ligar _Propriedades" + +#. Select item +#: ../../po/../src/object-ui.cpp:249 +msgid "_Follow Link" +msgstr "Se_guir Ligação" + +#. Reset transformations +#: ../../po/../src/object-ui.cpp:254 +msgid "_Remove Link" +msgstr "_Remover Ligação" + +#. Link dialog +#: ../../po/../src/object-ui.cpp:303 +msgid "Image _Properties" +msgstr "_Propriedades da Imagem" + +#. Item dialog +#: ../../po/../src/object-ui.cpp:344 +msgid "_Fill and Stroke" +msgstr "_Preenchimento e Traço" + +#: ../../po/../src/path-chemistry.cpp:58 +msgid "Select at least two objects to combine." +msgstr "Selecione pelo menos dois objetos para combinar." + +#: ../../po/../src/path-chemistry.cpp:65 +msgid "At least one of the objects is not a path, cannot combine." +msgstr "" +"Pelo menos um dos objetos não é um caminho. Não é possível combinar." + +#: ../../po/../src/path-chemistry.cpp:73 +msgid "" +"You cannot combine objects from different groups or layers." +msgstr "Você não pode combinar objetos de grupos ou camadas diferentes." + +#: ../../po/../src/path-chemistry.cpp:155 +msgid "Select path(s) to break apart." +msgstr "Selecione algum(ns) caminho(s) para serem separados." + +#: ../../po/../src/path-chemistry.cpp:231 +msgid "No path(s) to break apart in the selection." +msgstr "Nenhum caminho para separar na seleção." + +#: ../../po/../src/path-chemistry.cpp:252 +msgid "Select object(s) to convert to path." +msgstr "Selecione algum(ns) objeto(s) para converter para um caminho." + +#: ../../po/../src/path-chemistry.cpp:297 +msgid "No objects to convert to path in the selection." +msgstr "Nenhum objeto para converter para um caminho na seleção." + +#: ../../po/../src/path-chemistry.cpp:345 +msgid "Select path(s) to reverse." +msgstr "Selecione um ou mais caminhos para reverter." + +#: ../../po/../src/path-chemistry.cpp:370 +msgid "No paths to reverse in the selection." +msgstr "Nenhum caminho para reverter na seleção." + +#: ../../po/../src/pen-context.cpp:379 ../../po/../src/pencil-context.cpp:233 +#, fuzzy +msgid "Continuing selected path" +msgstr "Avançar caminhos selecionados" + +#: ../../po/../src/pen-context.cpp:390 ../../po/../src/pencil-context.cpp:242 +#, fuzzy +msgid "Creating new path" +msgstr "Criando nova curva" + +#: ../../po/../src/pen-context.cpp:394 ../../po/../src/pencil-context.cpp:246 +#, fuzzy +msgid "Appending to selected path" +msgstr "Acrescentando à seleção" + +#: ../../po/../src/pen-context.cpp:538 +#, fuzzy +msgid "Click or click and drag to close and finish the path." +msgstr "" +"Clique para selecionar ou criar um objeto texto, e então pode digitar." + +#: ../../po/../src/pen-context.cpp:548 +#, fuzzy +msgid "" +"Click or click and drag to continue the path from this point." +msgstr "" +"Clique para selecionar ou criar um objeto texto, e então pode digitar." + +#: ../../po/../src/pen-context.cpp:857 +#, fuzzy, c-format +msgid "" +"%s: angle %3.2f°, distance %s; with Ctrl to snap angle, " +"Enter to finish the path" +msgstr "" +"Alça do Nó: arraste para mudar a forma da curva; com Ctrl para " +"agarrar ao ângulo; com Alt para travar o tamanho; com Shift " +"para rodar a alça oposta em sincronia" + +#: ../../po/../src/pen-context.cpp:882 +#, fuzzy, c-format +msgid "" +"Curve handle: angle %3.2f°, length %s; with Ctrl to snap " +"angle" +msgstr "Rodar: %0.2f graus; com Ctrl para agarrar o ângulo" + +#: ../../po/../src/pen-context.cpp:912 +#, fuzzy, c-format +msgid "" +"%s: angle %3.2f°, length %s; with Ctrl to snap angle, " +"with Shift to move this handle only" +msgstr "" +"Alça do Nó: arraste para mudar a forma da curva; com Ctrl para " +"agarrar ao ângulo; com Alt para travar o tamanho; com Shift " +"para rodar a alça oposta em sincronia" + +#: ../../po/../src/pen-context.cpp:946 +msgid "Finishing pen" +msgstr "Finalizando caneta" + +#: ../../po/../src/pencil-context.cpp:320 +msgid "Release here to close and finish the path." +msgstr "" + +#: ../../po/../src/pencil-context.cpp:326 +#, fuzzy +msgid "Drawing a freehand path" +msgstr "Desenhar linhas a mão-livre" + +#: ../../po/../src/pencil-context.cpp:331 +msgid "Drag to continue the path from this point." +msgstr "" + +#. Write curves to object +#: ../../po/../src/pencil-context.cpp:390 +msgid "Finishing freehand" +msgstr "Finalizando mão-livre" + +#: ../../po/../src/rect-context.cpp:387 +msgid "" +"Ctrl: make square or integer-ratio rect, lock a rounded corner " +"circular" +msgstr "Ctrl: faz o quadrado ou retângulo travar um canto arredondado" + +#: ../../po/../src/rect-context.cpp:549 +#, fuzzy, c-format +msgid "" +"Rectangle: %s × %s; with Ctrl to make square or integer-" +"ratio rectangle; with Shift to draw around the starting point" +msgstr "" +"Retângulo: %s x %s; com Ctrl para fazer um quadrado ou " +"retângulo; Shift para desenhar ao redor do ponto inicial" + +#: ../../po/../src/select-context.cpp:243 +msgid "Move canceled." +msgstr "Movimento cancelado." + +#: ../../po/../src/select-context.cpp:252 +msgid "Selection canceled." +msgstr "Seleção cancelada." + +#: ../../po/../src/select-context.cpp:642 +msgid "Ctrl: select in groups, move hor/vert" +msgstr "Ctrl: selecionar em grupos, mover hor/vert" + +#: ../../po/../src/select-context.cpp:643 +msgid "Shift: toggle select, force rubberband, disable snapping" +msgstr "" +"Shift: alternar entre selecionar, forçar elasticidade, desabilitar " +"agarramento" + +#: ../../po/../src/select-context.cpp:644 +msgid "Alt: select under, move selected" +msgstr "Alt: selecionar embaixo, mover seleção" + +#: ../../po/../src/select-context.cpp:798 +#, fuzzy +msgid "Selected object is not a group. Cannot enter." +msgstr "" +"O objeto selecionado não é um caminho. Não é possível avançar/recuar" + +#: ../../po/../src/select-context.cpp:876 +#, c-format +msgid "" +"Move by %s, %s; with Ctrl to restrict to horizontal/vertical; " +"with Shift to disable snapping" +msgstr "" +"Mover por %s, %s; com Ctrl para restringir na horizontal/" +"vertical com Shift para desabilitar o agarramento" + +#: ../../po/../src/selection-chemistry.cpp:228 +msgid "Nothing was deleted." +msgstr "Nada foi apagado." + +#: ../../po/../src/selection-chemistry.cpp:259 +msgid "Select object(s) to duplicate." +msgstr "Selecione alguns objetos para duplicar." + +#: ../../po/../src/selection-chemistry.cpp:420 +msgid "Select two or more objects to group." +msgstr "Selecione dois ou mais objetos para agrupar." + +#: ../../po/../src/selection-chemistry.cpp:428 +msgid "Select at least two objects to group." +msgstr "Selecione pelo menos dois objetos para agrupar." + +#: ../../po/../src/selection-chemistry.cpp:513 +msgid "Select a group to ungroup." +msgstr "Selecione um grupo para desagrupar." + +#: ../../po/../src/selection-chemistry.cpp:554 +msgid "No groups to ungroup in the selection." +msgstr "Nenhum grupo para desagrupar na seleção." + +#: ../../po/../src/selection-chemistry.cpp:623 +msgid "Select objects to raise." +msgstr "Selecione algum objetos para levantar." + +#: ../../po/../src/selection-chemistry.cpp:629 +#: ../../po/../src/selection-chemistry.cpp:681 +#: ../../po/../src/selection-chemistry.cpp:715 +#: ../../po/../src/selection-chemistry.cpp:773 +msgid "" +"You cannot raise/lower objects from different groups or layers." +msgstr "" +"Você não pode levantar/abaixar objetos de diferentes grupos ou camadas." + +#: ../../po/../src/selection-chemistry.cpp:673 +msgid "Select object(s) to raise to top." +msgstr "Selecione alguns objetos para levantar até o topo." + +#: ../../po/../src/selection-chemistry.cpp:709 +msgid "Select object(s) to lower." +msgstr "Selecione alguns objetos para abaixar." + +#: ../../po/../src/selection-chemistry.cpp:765 +msgid "Select object(s) to lower to bottom." +msgstr "Selecione alguns objetos para abaixar até o fundo." + +#: ../../po/../src/selection-chemistry.cpp:806 +msgid "Nothing to undo." +msgstr "Nada para desfazer." + +#: ../../po/../src/selection-chemistry.cpp:813 +msgid "Nothing to redo." +msgstr "Nada para refazer." + +#: ../../po/../src/selection-chemistry.cpp:969 +msgid "Nothing was copied." +msgstr "Nada foi copiado." + +#: ../../po/../src/selection-chemistry.cpp:1051 +msgid "Current layer is hidden. Unhide it to be able to paste to it." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1055 +msgid "Current layer is locked. Unlock it to be able to paste to it." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1068 +#: ../../po/../src/selection-chemistry.cpp:1103 +msgid "Nothing on the clipboard." +msgstr "Nada na área de transferência." + +#: ../../po/../src/selection-chemistry.cpp:1109 +msgid "Select object(s) to paste style to." +msgstr "Selecione os objetos para onde será colado o estilo." + +#: ../../po/../src/selection-chemistry.cpp:1128 +#, fuzzy +msgid "Select object(s) to move to the layer above." +msgstr "Selecione algum(ns) objeto(s) para converter para um caminho." + +#: ../../po/../src/selection-chemistry.cpp:1146 +#, fuzzy +msgid "No more layers above." +msgstr "Nenhuma camada no desenho." + +#: ../../po/../src/selection-chemistry.cpp:1160 +#, fuzzy +msgid "Select object(s) to move to the layer below." +msgstr "Selecione algum(ns) objeto(s) para converter para um caminho." + +#: ../../po/../src/selection-chemistry.cpp:1178 +#, fuzzy +msgid "No more layers below." +msgstr "Nenhuma camada no desenho." + +#: ../../po/../src/selection-chemistry.cpp:1811 +msgid "Select a clone to unlink." +msgstr "Selecionar um clone para romper a ligação." + +#: ../../po/../src/selection-chemistry.cpp:1842 +msgid "No clones to unlink in the selection." +msgstr "Nenhum clone para romper a ligação na seleção." + +#: ../../po/../src/selection-chemistry.cpp:1859 +#, fuzzy +msgid "" +"Select a clone to go to its original. Select a linked offset " +"to go to its source. Select a text on path to go to the path. Select " +"a flowed text to go to its frame." +msgstr "" +"Selecionar um clone para ir para seu original. Selecione uma " +"tipografia ligada para ir para sua fonte. Selecione um texto em " +"caminho pra ir para o caminho." + +#: ../../po/../src/selection-chemistry.cpp:1882 +#, fuzzy +msgid "" +"Cannot find the object to select (orphaned clone, offset, textpath, " +"flowed text?)" +msgstr "" +"Não foi encontrado o objeto para selecionar (clone órfão, tipografia " +"ou texto em caminho?)" + +#: ../../po/../src/selection-chemistry.cpp:1888 +msgid "" +"The object you're trying to select is not visible (it is in <" +"defs>)" +msgstr "" +"O objeto que você está tentando selecionar não está visível (está no " +"<defs>)" + +#: ../../po/../src/selection-chemistry.cpp:1915 +#, fuzzy +msgid "Select object(s) to convert to pattern." +msgstr "Selecione algum(ns) objeto(s) para converter para um caminho." + +#: ../../po/../src/selection-chemistry.cpp:2006 +#, fuzzy +msgid "Select an object with pattern fill to extract objects from." +msgstr "" +"Selecione um objeto com padrão de preenchimento para retirar a " +"repetição." + +#: ../../po/../src/selection-chemistry.cpp:2059 +#, fuzzy +msgid "No pattern fills in the selection." +msgstr "Nenhum padrão de preenchiento em ladrilho na seleção." + +#: ../../po/../src/selection-chemistry.cpp:2079 +msgid "Select object(s) to make a bitmap copy." +msgstr "Selecione alguns objetos para levantar até o topo." + +#: ../../po/../src/selection-describer.cpp:37 +msgid "Click selection to toggle scale/rotation handles" +msgstr "Clique na seleção para trocar as alças ampliar/girar" + +#. no items +#: ../../po/../src/selection-describer.cpp:39 +msgid "" +"No objects selected. Click, Shift+click, or drag around objects to select." +msgstr "" +"Nenhum objeto selecionado. Clique, clique com shift ou arraste ao redor dos " +"objetos para selecionar." + +#: ../../po/../src/selection-describer.cpp:51 +#, fuzzy, c-format +msgid " in layer %s" +msgstr "Nó Levantado." + +#: ../../po/../src/selection-describer.cpp:54 +#, fuzzy, c-format +msgid " in layer %s" +msgstr "Nó Levantado." + +#: ../../po/../src/selection-describer.cpp:66 +#, fuzzy +msgid "Use Shift+D to look up original" +msgstr "Clone de: %s. Use Shift+D para espiar o original" + +#: ../../po/../src/selection-describer.cpp:70 +#, fuzzy +msgid "Use Shift+D to look up path" +msgstr "Clone de: %s. Use Shift+D para espiar o original" + +#: ../../po/../src/selection-describer.cpp:74 +#, fuzzy +msgid "Use Shift+D to look up frame" +msgstr "Clone de: %s. Use Shift+D para espiar o original" + +#: ../../po/../src/selection-describer.cpp:84 +#, fuzzy, c-format +msgid "%i object selected" +msgid_plural "%i objects selected" +msgstr[0] "%i objetos selecionados. %s." +msgstr[1] "%i objetos selecionados. %s." + +#: ../../po/../src/selection-describer.cpp:90 +#, c-format +msgid "%s%s. %s." +msgstr "" + +#: ../../po/../src/selection-describer.cpp:94 +#, fuzzy, c-format +msgid "%s in %i layer. %s." +msgid_plural "%s in %i layers. %s." +msgstr[0] "%i objetos selecionados. %s." +msgstr[1] "%i objetos selecionados. %s." + +#: ../../po/../src/seltrans.cpp:498 +msgid "" +"Center of rotation and skewing: drag to reposition; scaling with " +"Shift also uses this center" +msgstr "" +"Centro de rotação e inclinação: arraste para reposicionar; " +"dimensionar com Shift também usa este centro" + +#: ../../po/../src/seltrans.cpp:514 +msgid "" +"Squeeze or stretch selection; with Ctrl to scale uniformly; " +"with Shift to scale around rotation center" +msgstr "" +"Espremer ou esticar a seleção; com Ctrl para dimensionar " +"uniformemente; com Shift para dimensionar ao redor do centro de " +"rotação" + +#: ../../po/../src/seltrans.cpp:515 +msgid "" +"Scale selection; with Ctrl to scale uniformly; with Shift to scale around rotation center" +msgstr "" +"Dimensionar a seleção; com Ctrl para dimensionar uniformemente;" +"com Shift para dimensionar ao redor do centro de rotação" + +#: ../../po/../src/seltrans.cpp:519 +#, fuzzy +msgid "" +"Skew selection; with Ctrl to snap angle; with Shift to " +"skew around the opposite side" +msgstr "" +"Rodar a seleção; com Ctrl para agarrar o ângulo; com Shift para rodar ao redor do canto oposto" + +#: ../../po/../src/seltrans.cpp:520 +msgid "" +"Rotate selection; with Ctrl to snap angle; with Shift " +"to rotate around the opposite corner" +msgstr "" +"Rodar a seleção; com Ctrl para agarrar o ângulo; com Shift para rodar ao redor do canto oposto" + +#: ../../po/../src/seltrans.cpp:829 ../../po/../src/seltrans.cpp:909 +#, c-format +msgid "Scale: %0.2f%% x %0.2f%%; with Ctrl to lock ratio" +msgstr "" +"Dimensionar: %0.2f%% x %0.2f%%; com Ctrl para travar a " +"proporção" + +#. TRANSLATORS: don't modify the first ";" (it will NOT be displayed as ";" - only the second one will be) +#: ../../po/../src/seltrans.cpp:984 +#, fuzzy, c-format +msgid "Skew: %0.2f°; with Ctrl to snap angle" +msgstr "Rodar: %0.2f graus; com Ctrl para agarrar o ângulo" + +#. TRANSLATORS: don't modify the first ";" (it will NOT be displayed as ";" - only the second one will be) +#: ../../po/../src/seltrans.cpp:1035 +#, fuzzy, c-format +msgid "Rotate: %0.2f°; with Ctrl to snap angle" +msgstr "Rodar: %0.2f graus; com Ctrl para agarrar o ângulo" + +#: ../../po/../src/seltrans.cpp:1090 +#, c-format +msgid "Move center to %s, %s" +msgstr "Move o centro para %s, %s" + +#: ../../po/../src/slideshow.cpp:90 +msgid "Inkscape slideshow" +msgstr "Apresentação de slides do Inkscape" + +#: ../../po/../src/sp-anchor.cpp:181 +#, c-format +msgid "Link to %s" +msgstr "Ligar em %s" + +#: ../../po/../src/sp-anchor.cpp:185 +#, fuzzy +msgid "Link without URI" +msgstr "Ligar em %s" + +#: ../../po/../src/sp-ellipse.cpp:438 ../../po/../src/sp-ellipse.cpp:870 +msgid "Ellipse" +msgstr "Elipse" + +#: ../../po/../src/sp-ellipse.cpp:583 +msgid "Circle" +msgstr "Círculo" + +#: ../../po/../src/sp-ellipse.cpp:865 +#, fuzzy +msgid "Segment" +msgstr "Novo:" + +#: ../../po/../src/sp-ellipse.cpp:867 +msgid "Arc" +msgstr "Arco" + +#. TRANSLATORS: "Flow region" is an area where text is allowed to flow +#: ../../po/../src/sp-flowregion.cpp:276 +#, fuzzy +msgid "Flow region" +msgstr "Se_guir Ligação" + +#. TRANSLATORS: A region "cut out of" a flow region; text is not allowed to flow inside the +#. * flow excluded region. flowRegionExclude in SVG 1.2: see +#. * http://www.w3.org/TR/2004/WD-SVG12-20041027/flow.html#flowRegion-elem and +#. * http://www.w3.org/TR/2004/WD-SVG12-20041027/flow.html#flowRegionExclude-elem. +#: ../../po/../src/sp-flowregion.cpp:493 +msgid "Flow excluded region" +msgstr "" + +#: ../../po/../src/sp-flowtext.cpp:355 +#, c-format +msgid "Flowed text (%d characters)" +msgstr "" + +#: ../../po/../src/sp-flowtext.cpp:357 +#, c-format +msgid "Linked flowed text (%d characters)" +msgstr "" + +#: ../../po/../src/sp-guide.cpp:290 +msgid "vertical guideline" +msgstr "linha guia vertical" + +#: ../../po/../src/sp-guide.cpp:292 +msgid "horizontal guideline" +msgstr "linha guia horizontal" + +#: ../../po/../src/sp-image.cpp:835 +msgid "embedded" +msgstr "" + +#: ../../po/../src/sp-image.cpp:839 +msgid "(null_pointer)" +msgstr "" + +#: ../../po/../src/sp-image.cpp:843 +#, c-format +msgid "Image with bad reference: %s" +msgstr "Imagem com referência inválida: %s" + +#: ../../po/../src/sp-image.cpp:844 +#, fuzzy, c-format +msgid "Image %d × %d: %s" +msgstr "Imagem %d x $d: %s" + +#: ../../po/../src/sp-item-group.cpp:390 +#, fuzzy, c-format +msgid "Group of %d object" +msgid_plural "Group of %d objects" +msgstr[0] "Grupo de %d objetos" +msgstr[1] "Grupo de %d objetos" + +#: ../../po/../src/sp-item.cpp:720 +msgid "Object" +msgstr "Objeto" + +#: ../../po/../src/sp-line.cpp:202 +#, fuzzy +msgid "Line" +msgstr "Novo:" + +#. TRANSLATORS COMMENT: %s is either "outset" or "inset" depending on sign +#: ../../po/../src/sp-offset.cpp:433 +#, fuzzy, c-format +msgid "Linked offset, %s by %f pt" +msgstr "Tipografia dinâmica, %s por %f pt" + +#: ../../po/../src/sp-offset.cpp:434 ../../po/../src/sp-offset.cpp:438 +msgid "outset" +msgstr "recuar" + +#: ../../po/../src/sp-offset.cpp:434 ../../po/../src/sp-offset.cpp:438 +msgid "inset" +msgstr "avançar" + +#. TRANSLATORS COMMENT: %s is either "outset" or "inset" depending on sign +#: ../../po/../src/sp-offset.cpp:437 +#, c-format +msgid "Dynamic offset, %s by %f pt" +msgstr "Tipografia dinâmica, %s por %f pt" + +#: ../../po/../src/sp-path.cpp:127 +#, fuzzy, c-format +msgid "Path (%i node)" +msgid_plural "Path (%i nodes)" +msgstr[0] "Caminho (%i nós)" +msgstr[1] "Caminho (%i nós)" + +#: ../../po/../src/sp-polygon.cpp:216 +#, fuzzy +msgid "Polygon" +msgstr "Círculo" + +#: ../../po/../src/sp-polyline.cpp:179 +#, fuzzy +msgid "Polyline" +msgstr "Elipse" + +#: ../../po/../src/sp-rect.cpp:250 +msgid "Rectangle" +msgstr "Retângulo" + +#. TRANSLATORS: since turn count isn't an integer, please adjust the +#. string as needed to deal with an localized plural forms. +#: ../../po/../src/sp-spiral.cpp:305 +#, c-format +msgid "Spiral with %3f turns" +msgstr "Espiral com %3f curvas" + +#: ../../po/../src/sp-star.cpp:288 +#, fuzzy, c-format +msgid "Star with %d vertex" +msgid_plural "Star with %d vertices" +msgstr[0] "Estrela de %d vértices" +msgstr[1] "Estrela de %d vértices" + +#: ../../po/../src/sp-star.cpp:292 +#, fuzzy, c-format +msgid "Polygon with %d vertex" +msgid_plural "Polygon with %d vertices" +msgstr[0] "Polígono de %d vértices" +msgstr[1] "Polígono de %d vértices" + +#. TRANSLATORS: For description of font with no name. +#: ../../po/../src/sp-text.cpp:420 +msgid "<no name found>" +msgstr "<nenhum nome encontrado>" + +#: ../../po/../src/sp-text.cpp:426 +#, fuzzy, c-format +msgid "Text on path (%s, %s)" +msgstr "Texto (%s, %.5gpt)" + +#: ../../po/../src/sp-text.cpp:427 +#, fuzzy, c-format +msgid "Text (%s, %s)" +msgstr "Texto (%s, %.5gpt)" + +#. TRANSLATORS: Used for statusbar description for long chains: +#. * "Clone of: Clone of: ... in Layer 1". +#: ../../po/../src/sp-use.cpp:317 +#, fuzzy +msgid "..." +msgstr "_Abrir..." + +#: ../../po/../src/sp-use.cpp:325 +#, fuzzy, c-format +msgid "Clone of: %s" +msgstr "Ligar em %s" + +#: ../../po/../src/sp-use.cpp:329 +msgid "Orphaned clone" +msgstr "Clone órfão" + +#: ../../po/../src/spiral-context.cpp:355 +msgid "Ctrl: snap angle" +msgstr "Ctrl: agarra o ângulo" + +#: ../../po/../src/spiral-context.cpp:357 +msgid "Alt: lock spiral radius" +msgstr "Alt: trava o raio da espiral" + +#: ../../po/../src/spiral-context.cpp:469 +#, fuzzy, c-format +msgid "" +"Spiral: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" +"Espiral: raio %s, ângulo %5g; com Ctrl para agarrar o ângulo" + +#: ../../po/../src/splivarot.cpp:106 +msgid "Select at least 2 paths to perform a boolean operation." +msgstr "" +"Selecione pelo menos dois caminhos para fazer uma operação booleana." + +#: ../../po/../src/splivarot.cpp:112 +msgid "" +"Select exactly 2 paths to perform difference, XOR, division, or path " +"cut." +msgstr "" +"Selecione exatamente dois caminhos para fazer diferença, ou-" +"exclusivo, divisão ou corte de caminho." + +#: ../../po/../src/splivarot.cpp:129 ../../po/../src/splivarot.cpp:144 +msgid "" +"Unable to determine the z-order of the objects selected for " +"difference, XOR, division, or path cut." +msgstr "" +"Incapaz de determinar a ordem-z dos objetos selecionados para " +"diferença,ou-exclusivo, divisão ou corte de caminho." + +#: ../../po/../src/splivarot.cpp:174 +msgid "" +"One of the objects is not a path, cannot perform boolean operation." +msgstr "" +"Um dos objetos não é um caminho, a operação booleana não pode ser " +"executada." + +#. TRANSLATORS: "to outline" means "to convert stroke to path" +#: ../../po/../src/splivarot.cpp:554 +msgid "Select path(s) to outline." +msgstr "Selecione algum caminho para contornar." + +#. TRANSLATORS: "to outline" means "to convert stroke to path" +#: ../../po/../src/splivarot.cpp:748 +msgid "No stroked paths to outline in the selection." +msgstr "Nenhum caminho com traço para contornar na seleção." + +#: ../../po/../src/splivarot.cpp:832 +msgid "Selected object is not a path, cannot inset/outset." +msgstr "" +"O objeto selecionado não é um caminho. Não é possível avançar/recuar" + +#: ../../po/../src/splivarot.cpp:1040 +msgid "Select path(s) to inset/outset." +msgstr "Selecione algum caminho para avançar/recuar" + +#: ../../po/../src/splivarot.cpp:1257 +msgid "No paths to inset/outset in the selection." +msgstr "Nenhum camimho para avançar/recuar na seleção" + +#: ../../po/../src/splivarot.cpp:1390 +msgid "Select path(s) to simplify." +msgstr "Selecione algum caminho para simplificar." + +#: ../../po/../src/splivarot.cpp:1417 +msgid "No paths to simplify in the selection." +msgstr "Nenhum caminho para simplificar na seleção." + +#: ../../po/../src/star-context.cpp:362 +msgid "Ctrl: snap angle; keep rays radial" +msgstr "Ctrl: agarrar o ângulo; preserva os raios radiais" + +#: ../../po/../src/star-context.cpp:470 +#, fuzzy, c-format +msgid "" +"Polygon: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" +"Polígono: raio %s, ângulo %5g; com Ctrl para agarrar o ângulo" + +#: ../../po/../src/star-context.cpp:471 +#, fuzzy, c-format +msgid "Star: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" +"Estrela: raio %s, ângulo %5g; com Ctrl para agarrar o ângulo" + +#: ../../po/../src/text-chemistry.cpp:90 +msgid "Select a text and a path to put text on path." +msgstr "Selecione um texto e um caminho para por o texto no camiho." + +#: ../../po/../src/text-chemistry.cpp:95 +msgid "" +"This text object is already put to a path. Remove it from the path " +"first. Use Shift+D to look up its path." +msgstr "" +"Este objeto de texto já foi posto no caminho. Remova-o do caminho " +"primeiro. Use Shift+D para espiar seu caminho." + +#. rect is the only SPShape which is not yet, and thus SVG forbids us from putting text on it +#: ../../po/../src/text-chemistry.cpp:101 +msgid "" +"You cannot put text on a rectangle in this version. Convert rectangle to " +"path first." +msgstr "" + +#: ../../po/../src/text-chemistry.cpp:159 +msgid "Select a text on path to remove it from path." +msgstr "Selecione um texto no caminhopara removê-lo do caminho." + +#: ../../po/../src/text-chemistry.cpp:181 +msgid "No texts-on-paths in the selection." +msgstr "Nenhum texto-no-caminho na seleção." + +#: ../../po/../src/text-chemistry.cpp:209 +#: ../../po/../src/text-chemistry.cpp:229 +#, fuzzy +msgid "Select text(s) to remove kerns from." +msgstr "Selecione um ou mais caminhos para reverter." + +#: ../../po/../src/text-chemistry.cpp:250 +#, fuzzy +msgid "" +"Select a text and one or more paths or shapes to flow text " +"into frame." +msgstr "Selecione um texto e um caminho para por o texto no camiho." + +#: ../../po/../src/text-chemistry.cpp:322 +#, fuzzy +msgid "Select a flowed text to unflow it." +msgstr "Selecione algum caminho para contornar." + +#: ../../po/../src/text-context.cpp:463 +#, fuzzy +msgid "Click to edit the text, drag to select part of the text." +msgstr "" +"Clique para selecionar ou criar um objeto texto, e então pode digitar." + +#: ../../po/../src/text-context.cpp:465 +#, fuzzy +msgid "" +"Click to edit the flowed text, drag to select part of the text." +msgstr "" +"Clique para selecionar ou criar um objeto texto, e então pode digitar." + +#: ../../po/../src/text-context.cpp:540 +msgid "Non-printable character" +msgstr "Caracter não imprimível" + +#: ../../po/../src/text-context.cpp:589 +#, fuzzy, c-format +msgid "Unicode: %s: %s" +msgstr "Unicode: " + +#: ../../po/../src/text-context.cpp:591 ../../po/../src/text-context.cpp:855 +msgid "Unicode: " +msgstr "Unicode: " + +#: ../../po/../src/text-context.cpp:615 +msgid "Current layer is hidden. Unhide it to be able to add text." +msgstr "" + +#: ../../po/../src/text-context.cpp:619 +msgid "Current layer is locked. Unlock it to be able to add text." +msgstr "" + +#: ../../po/../src/text-context.cpp:673 +#, c-format +msgid "Flowed text frame: %s × %s" +msgstr "" + +#: ../../po/../src/text-context.cpp:708 ../../po/../src/text-context.cpp:1464 +msgid "Type text; Enter to start new line." +msgstr "" + +#: ../../po/../src/text-context.cpp:719 +msgid "Flowed text is created." +msgstr "" + +#: ../../po/../src/text-context.cpp:722 +msgid "" +"The frame is too small for the current font size. Flowed text not " +"created." +msgstr "" + +#: ../../po/../src/text-context.cpp:841 +msgid "No-break space" +msgstr "Espaço sem quebras" + +#: ../../po/../src/text-context.cpp:1462 +msgid "Type flowed text; Enter to start new paragraph." +msgstr "" + +#: ../../po/../src/text-context.cpp:1472 ../../po/../src/tools-switch.cpp:189 +#, fuzzy +msgid "" +"Click to select or create text, drag to create flowed text; " +"then type." +msgstr "" +"Clique para selecionar ou criar um objeto texto, e então pode digitar." + +#: ../../po/../src/tools-switch.cpp:141 +msgid "" +"To edit a path, click, Shift+click, or drag around " +"nodes to select them, then drag nodes and handles. Click on an " +"object to select." +msgstr "" +"Para alterar um caminho, clique, clique com Shift ou " +"arraste ao redor dos nós para selecioná-los, e daí arrasteseus " +"nós e alças. Clique em um objeto para selecioná-lo." + +#: ../../po/../src/tools-switch.cpp:147 +msgid "" +"Drag to create a rectangle. Drag controls to round corners and " +"resize. Click to select." +msgstr "" +"Arraste para criar um retângulo. Arraste os controles para " +"arredondar os cantos e redimensionar. Clique para selecioná-lo." + +#: ../../po/../src/tools-switch.cpp:153 +msgid "" +"Drag to create an ellipse. Drag controls to make an arc or " +"segment. Click to select." +msgstr "" +"Arraste para criar uma elipse. Arraste as alças para fazer um " +"arco ou segmento. Clique para selecionar." + +#: ../../po/../src/tools-switch.cpp:159 +msgid "" +"Drag to create a star. Drag controls to edit the star shape. " +"Click to select." +msgstr "" +"Arraste para criar uma estrela. Arraste as alças para alterar " +"a forma da estrela. Clique para selecionar." + +#: ../../po/../src/tools-switch.cpp:165 +msgid "" +"Drag to create a spiral. Drag controls to edit the spiral " +"shape. Click to select." +msgstr "" +"Arraste para criar uma espiral. Arraste as alças para alterar " +"a forma da espiral. Clique para selecionar." + +#: ../../po/../src/tools-switch.cpp:171 +#, fuzzy +msgid "" +"Drag to create a freehand line. Start drawing with Shift to " +"append to selected path." +msgstr "" +"Arraste para criar uma linha à mão-livre. Pressione a para " +"trocar entre Acrescentar/Novo." + +#: ../../po/../src/tools-switch.cpp:177 +#, fuzzy +msgid "" +"Click or click and drag to start a path; with Shift to " +"append to selected path." +msgstr "" +"Clique para criar um nó. Clique e arraste para criar um nó " +"suave. Pressione a para trocar entre Acrescentar/Novo." + +#: ../../po/../src/tools-switch.cpp:183 +msgid "" +"Drag to paint a calligraphic stroke. Left/right arrow " +"keys adjust width, up/down adjust angle." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:195 +#, fuzzy +msgid "" +"Drag or double click to create a gradient on selected objects, " +"drag handles to adjust gradients." +msgstr "" +"Arraste para criar uma linha à mão-livre. Pressione a para " +"trocar entre Acrescentar/Novo." + +#: ../../po/../src/tools-switch.cpp:201 +msgid "" +"Click or drag around an area to zoom in, Shift+click to " +"zoom out." +msgstr "" +"Clique ou arraste ao redor de uma área para ampliá-la. Clique " +"com Shift para reduzi-la." + +#: ../../po/../src/tools-switch.cpp:213 +msgid "Click and drag between shapes to create a connector." +msgstr "" + +#: ../../po/../src/trace/potrace/inkscape-potrace.cpp:553 +#: ../../po/../src/trace/potrace/inkscape-potrace.cpp:654 +#, c-format +msgid "Trace: %d. %ld nodes" +msgstr "" + +#: ../../po/../src/trace/trace.cpp:53 ../../po/../src/trace/trace.cpp:62 +#: ../../po/../src/trace/trace.cpp:70 +msgid "Select an image to trace" +msgstr "Selecione uma imagem para traçar." + +#: ../../po/../src/trace/trace.cpp:133 +msgid "Trace: No active document" +msgstr "Traçar: Nenhum desenho ativo." + +#: ../../po/../src/trace/trace.cpp:154 +msgid "Trace: Image has no bitmap data" +msgstr "Traçar: A imagem não tem dados de figura." + +#: ../../po/../src/trace/trace.cpp:267 +#, c-format +msgid "Trace: Done. %ld nodes created" +msgstr "" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:59 ../../po/../src/verbs.cpp:2212 +msgid "About Inkscape" +msgstr "Sobre o Inkscape" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:66 +msgid "_Splash" +msgstr "" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:68 +msgid "_Authors" +msgstr "" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:69 +#, fuzzy +msgid "_Translators" +msgstr "Transformações" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:70 +#, fuzzy +msgid "_License" +msgstr "Licensa" + +#. TRANSLATORS: This is the filename of the `About Inkscape' picture in +#. the `screens' directory. Thus the translation of "about.svg" should be +#. the filename of its translated version, e.g. about.zh.svg for Chinese. +#. +#. N.B. about.svg changes once per release. (We should probably rename +#. the original to about-0.40.svg etc. as soon as we have a translation. +#. If we do so, then add an item to release-checklist saying that the +#. string here should be changed.) +#. FIXME? INKSCAPE_SCREENSDIR and "about.svg" are in UTF-8, not the +#. native filename encoding... and the filename passed to sp_document_new +#. should be in UTF-*8.. +#: ../../po/../src/ui/dialog/aboutbox.cpp:114 +msgid "about.svg" +msgstr "about.svg" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:464 +msgid "Minimum horizontal gap (in px units) between bounding boxes" +msgstr "" + +#. TRANSLATORS: Horizontal gap +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:466 +#: ../../po/../src/widgets/toolbox.cpp:1556 +#, fuzzy +msgid "H:" +msgstr "_H" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:474 +msgid "Minimum vertical gap (in px units) between bounding boxes" +msgstr "" + +#. TRANSLATORS: Vertical gap +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:476 +msgid "V:" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:734 +msgid "Align" +msgstr "Alinhar" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:735 +msgid "Distribute" +msgstr "Distribuir" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:736 +msgid "Remove overlaps" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:737 +#, fuzzy +msgid "Nodes" +msgstr "Nó" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:742 +msgid "Relative to: " +msgstr "Relativo a: " + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:747 +#, fuzzy +msgid "Align right sides of objects to left side of anchor" +msgstr "Lado direito dos objetos alinhados para o lado esquerdo da âncora" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:750 +#, fuzzy +msgid "Align left sides" +msgstr "Alinhar Nós" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:753 +#, fuzzy +msgid "Center on vertical axis" +msgstr "Centralizar verticalmente" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:756 +#, fuzzy +msgid "Align right sides" +msgstr "Alinhar linhas à direita" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:759 +#, fuzzy +msgid "Align left sides of objects to right side of anchor" +msgstr "Lado esquerdo dos objetos alinhados para o lado direito da âncora" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:762 +#, fuzzy +msgid "Align bottoms of objects to top of anchor" +msgstr "Lado inferior dos objetos alinhados para o topo da âncora" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:765 +#, fuzzy +msgid "Align tops" +msgstr "Alinhar Nós" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:768 +#, fuzzy +msgid "Center on horizontal axis" +msgstr "Centralizar horizontalmente" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:771 +#, fuzzy +msgid "Align bottoms" +msgstr "Alinhar Nós" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:774 +#, fuzzy +msgid "Align tops of objects to bottom of anchor" +msgstr "Topo dos objetos alinhados para o lado inferior da âncora" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:779 +#, fuzzy +msgid "Align baseline anchors of texts vertically" +msgstr "Alinhar nós selecionados verticalmente" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:782 +#, fuzzy +msgid "Align baseline anchors of texts horizontally" +msgstr "Alinhar nós selecionados horizontalmente" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:787 +#, fuzzy +msgid "Make horizontal gaps between objects equal" +msgstr "Distribuir a distância horizontal igualmente entre os objetos" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:791 +#, fuzzy +msgid "Distribute left sides equidistantly" +msgstr "Distribuir o lado esquerdo dos objetos à mesma distância" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:794 +#, fuzzy +msgid "Distribute centers equidistantly horizontally" +msgstr "Distribuir o centro dos objetos à mesma distância" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:797 +#, fuzzy +msgid "Distribute right sides equidistantly" +msgstr "Distribuir o lado direito dos objetos à mesma distância" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:801 +#, fuzzy +msgid "Make vertical gaps between objects equal" +msgstr "Distribuir a distância vertical igualmente entre os objetos" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:805 +#, fuzzy +msgid "Distribute tops equidistantly" +msgstr "Distribuir nós selecionados verticalmente" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:808 +#, fuzzy +msgid "Distribute centers equidistantly vertically" +msgstr "Distribuir o centro dos objetos à mesma distância verticalmente" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:811 +#, fuzzy +msgid "Distribute bottoms equidistantly" +msgstr "Distribuir o lado inferior dos objetos à mesma distância" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:816 +#, fuzzy +msgid "Distribute baseline anchors of texts horizontally" +msgstr "Distribuir nós selecionados horizontalmente" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:819 +#, fuzzy +msgid "Distribute baseline anchors of texts vertically" +msgstr "Distribuir nós selecionados verticalmente" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:824 +msgid "Randomize centers in both dimensions" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:827 +msgid "Unclump objects: try to equalize edge-to-edge distances" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:832 +msgid "" +"Move objects as little as possible so that their bounding boxes do not " +"overlap" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:837 +msgid "Align selected nodes horizontally" +msgstr "Alinhar nós selecionados horizontalmente" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:840 +msgid "Align selected nodes vertically" +msgstr "Alinhar nós selecionados verticalmente" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:843 +msgid "Distribute selected nodes horizontally" +msgstr "Distribuir nós selecionados horizontalmente" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:846 +msgid "Distribute selected nodes vertically" +msgstr "Distribuir nós selecionados verticalmente" + +#. Rest of the widgetry +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:851 +msgid "Last selected" +msgstr "Último selecionado" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:852 +msgid "First selected" +msgstr "Primeiro selecionado" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:853 +msgid "Biggest item" +msgstr "Maior item" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:854 +msgid "Smallest item" +msgstr "Menor item" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:856 +#: ../../po/../src/widgets/desktop-widget.cpp:1065 +msgid "Drawing" +msgstr "Desenho" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:91 +#, fuzzy +msgid "Metadata 1" +msgstr "Metadados" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:92 +#, fuzzy +msgid "Metadata 2" +msgstr "Metadados" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:187 +#, fuzzy +msgid "X coordinate of grid origin" +msgstr "Coordenada vertical da seleção" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:189 +#, fuzzy +msgid "Y coordinate of grid origin" +msgstr "Coordenada vertical da seleção" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:191 +#, fuzzy +msgid "Distance of vertical grid lines" +msgstr "linha guia vertical" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:193 +#, fuzzy +msgid "Distance of horizontal grid lines" +msgstr "linha guia horizontal" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:197 +msgid "Max. snapping distance from grid" +msgstr "" + +#: ../../po/../src/ui/dialog/export.cpp:34 +msgid "Export" +msgstr "Exportar" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:36 +msgid "Fill" +msgstr "Preenchimento" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:37 +#, fuzzy +msgid "Stroke Paint" +msgstr "Pintura de traço" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:38 +#, fuzzy +msgid "Stroke Style" +msgstr "Estilo de traço" + +#: ../../po/../src/ui/dialog/find.cpp:34 +#, fuzzy +msgid "Find" +msgstr "_Localizar" + +#: ../../po/../src/ui/dialog/memory.cpp:96 +#, fuzzy +msgid "Heap" +msgstr "Aj_uda" + +#: ../../po/../src/ui/dialog/memory.cpp:97 +#, fuzzy +msgid "In Use" +msgstr "Inverter" + +#. TRANSLATORS: "Slack" refers to memory which is in the heap but currently unused. +#. More typical usage is to call this memory "free" rather than "slack". +#: ../../po/../src/ui/dialog/memory.cpp:100 +#, fuzzy +msgid "Slack" +msgstr "Estrela" + +#: ../../po/../src/ui/dialog/memory.cpp:101 +#, fuzzy +msgid "Total" +msgstr "Título" + +#: ../../po/../src/ui/dialog/memory.cpp:141 +#: ../../po/../src/ui/dialog/memory.cpp:147 +#: ../../po/../src/ui/dialog/memory.cpp:154 +#: ../../po/../src/ui/dialog/memory.cpp:186 +msgid "Unknown" +msgstr "Desconhecido" + +#: ../../po/../src/ui/dialog/memory.cpp:167 +#, fuzzy +msgid "Combined" +msgstr "_Combinar" + +#: ../../po/../src/ui/dialog/memory.cpp:209 +#, fuzzy +msgid "Recalculate" +msgstr "Retângulo" + +#: ../../po/../src/ui/dialog/messages.cpp:74 +#, fuzzy +msgid "Ready." +msgstr "Vermelho" + +#: ../../po/../src/ui/dialog/messages.cpp:75 +msgid "" +"Enable log display by setting dialogs.debug 'redirect' attribute to 1 in " +"preferences.xml" +msgstr "" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:184 +msgid "_Execute Python" +msgstr "" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:186 +msgid "_Execute Perl" +msgstr "" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:195 +msgid "Script" +msgstr "" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:205 +#, fuzzy +msgid "Output" +msgstr "Ava_nçar" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:215 +msgid "Errors" +msgstr "" + +#. Dialog organization +#: ../../po/../src/ui/dialog/session-player.cpp:73 +msgid "Session file" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:74 +#, fuzzy +msgid "Playback controls" +msgstr "_Controles de Ferramenta" + +#: ../../po/../src/ui/dialog/session-player.cpp:75 +#, fuzzy +msgid "Message information" +msgstr "Reiniciar _Transformação" + +#. Active session file display +#. fixme: Does this mean the active file for the session, or the file for the active session? +#. Please indicate which with a TRANSLATORS comment. +#: ../../po/../src/ui/dialog/session-player.cpp:85 +msgid "Active session file:" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:86 +msgid "Delay (milliseconds):" +msgstr "" + +#. Unload/load buttons +#: ../../po/../src/ui/dialog/session-player.cpp:94 +#, fuzzy +msgid "Close file" +msgstr "Fechar" + +#: ../../po/../src/ui/dialog/session-player.cpp:95 +msgid "Open new file" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:96 +#, fuzzy +msgid "Set delay" +msgstr "Ajustar como padrão" + +#: ../../po/../src/ui/dialog/session-player.cpp:138 +#, fuzzy +msgid "Rewind" +msgstr "Vermelho" + +#: ../../po/../src/ui/dialog/session-player.cpp:139 +msgid "Go back one change" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:140 +#, fuzzy +msgid "Pause" +msgstr "Co_lar" + +#: ../../po/../src/ui/dialog/session-player.cpp:141 +msgid "Go forward one change" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:142 +msgid "Play" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:177 +#: ../../po/../src/verbs.cpp:1573 +msgid "Open session file" +msgstr "" + +#. ##Set up the Potrace panel +#. #### brightness #### +#. #### Multiple scanning#### +#. ----Hbox1 +#: ../../po/../src/ui/dialog/tracedialog.cpp:345 +#: ../../po/../src/ui/dialog/tracedialog.cpp:428 +msgid "Brightness" +msgstr "Brilho" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:348 +msgid "Trace by a given brightness level" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:355 +msgid "Brightness cutoff for black/white" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:362 +msgid "Image Brightness" +msgstr "Brilho da Imagem" + +#. #### canny edge detection #### +#. TRANSLATORS: "Canny" is the name of the inventor of this edge detection method +#: ../../po/../src/ui/dialog/tracedialog.cpp:369 +msgid "Optimal Edge Detection (Canny)" +msgstr "Detecção de Bordas Melhorada (experta)" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:372 +msgid "Trace with edge detection by J. Canny's algorithm" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:388 +msgid "Brightness cutoff for adjacent pixels (determines edge thickness)" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:395 +msgid "Edge Detection" +msgstr "Detecção de Bordas" + +#. #### quantization #### +#. TRANSLATORS: Color Quantization: the process of reducing the number of colors +#. in an image by selecting an optimized set of representative colors and then +#. re-applying this reduced set to the original image. +#: ../../po/../src/ui/dialog/tracedialog.cpp:404 +msgid "Color Quantization" +msgstr "Quantificação de Cor" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:407 +msgid "Trace along the boundaries of reduced colors" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:414 +#, fuzzy +msgid "The number of reduced colors" +msgstr "Número de revoluções" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:416 +#, fuzzy +msgid "Colors:" +msgstr "Cores" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:421 +msgid "Quantization / Reduction" +msgstr "Quantificação / Redução" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:431 +msgid "Trace the given number of brightness levels" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:438 +msgid "Scans:" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:440 +msgid "The desired number of scans" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:448 +msgid "Trace the given number of reduced colors" +msgstr "" + +#. ---Hbox3 +#: ../../po/../src/ui/dialog/tracedialog.cpp:454 +msgid "Monochrome" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:457 +msgid "Same as Color, but convert result to grayscale" +msgstr "" + +#. TRANSLATORS: "Stack" is a verb here +#: ../../po/../src/ui/dialog/tracedialog.cpp:460 +#, fuzzy +msgid "Stack" +msgstr "Estrela" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:463 +msgid "" +"Stack scans vertically (no gaps) or tile horizontally (usually with gaps)" +msgstr "" + +#. TRANSLATORS: "Smooth" is a verb here +#: ../../po/../src/ui/dialog/tracedialog.cpp:466 +#, fuzzy +msgid "Smooth" +msgstr "suave" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:469 +msgid "Apply Gaussian blur to the bitmap before tracing" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:473 +msgid "Multiple Scanning" +msgstr "" + +#. #### Preview #### +#: ../../po/../src/ui/dialog/tracedialog.cpp:479 +#: ../../po/../src/ui/dialog/tracedialog.cpp:489 +msgid "Preview" +msgstr "Visualização" + +#. do not expand +#: ../../po/../src/ui/dialog/tracedialog.cpp:483 +msgid "Preview the result without actual tracing" +msgstr "" + +#. #### swap black and white #### +#: ../../po/../src/ui/dialog/tracedialog.cpp:495 +msgid "Invert" +msgstr "Inverter" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:499 +msgid "Invert black and white regions for single traces" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:503 +msgid "Thanks to Peter Selinger, http://potrace.sourceforge.net" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:506 +msgid "Credits" +msgstr "Créditos" + +#. done +#. TRANSLATORS: Potrace is an application for transforming bitmaps into +#. vector graphics (http://potrace.sourceforge.net/) +#: ../../po/../src/ui/dialog/tracedialog.cpp:514 +msgid "Potrace" +msgstr "Potrace" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:527 +#, fuzzy +msgid "Abort a trace in progress" +msgstr "Exportação em progresso" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:531 +msgid "Execute the trace" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:80 +#: ../../po/../src/ui/dialog/transformation.cpp:90 +#, fuzzy +msgid "_Horizontal" +msgstr "Texto horizontal" + +#: ../../po/../src/ui/dialog/transformation.cpp:80 +msgid "Horizontal displacement (relative) or position (absolute)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:82 +#: ../../po/../src/ui/dialog/transformation.cpp:92 +#, fuzzy +msgid "_Vertical" +msgstr "Texto vertical" + +#: ../../po/../src/ui/dialog/transformation.cpp:82 +msgid "Vertical displacement (relative) or position (absolute)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:84 +#, fuzzy +msgid "_Width" +msgstr "Largura:" + +#: ../../po/../src/ui/dialog/transformation.cpp:84 +msgid "Horizontal size increment (absolute or percentage)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:86 +#, fuzzy +msgid "_Height" +msgstr "Altura:" + +#: ../../po/../src/ui/dialog/transformation.cpp:86 +msgid "Vertical size increment (absolute or percentage)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:88 +#, fuzzy +msgid "A_ngle" +msgstr "Ângulo:" + +#: ../../po/../src/ui/dialog/transformation.cpp:88 +#, fuzzy +msgid "Rotation angle (positive = counterclockwise)" +msgstr "Girar a seleção 90 graus no sentido anti-horário" + +#: ../../po/../src/ui/dialog/transformation.cpp:90 +msgid "" +"Horizontal skew angle (positive = counterclockwise), or absolute " +"displacement, or percentage displacement" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:92 +msgid "" +"Vertical skew angle (positive = counterclockwise), or absolute displacement, " +"or percentage displacement" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:95 +#, fuzzy +msgid "Transformation matrix element A" +msgstr "Matriz de transformação" + +#: ../../po/../src/ui/dialog/transformation.cpp:96 +#, fuzzy +msgid "Transformation matrix element B" +msgstr "Matriz de transformação" + +#: ../../po/../src/ui/dialog/transformation.cpp:97 +#, fuzzy +msgid "Transformation matrix element C" +msgstr "Matriz de transformação" + +#: ../../po/../src/ui/dialog/transformation.cpp:98 +#, fuzzy +msgid "Transformation matrix element D" +msgstr "Matriz de transformação" + +#: ../../po/../src/ui/dialog/transformation.cpp:99 +#, fuzzy +msgid "Transformation matrix element E" +msgstr "Matriz de transformação" + +#: ../../po/../src/ui/dialog/transformation.cpp:100 +#, fuzzy +msgid "Transformation matrix element F" +msgstr "Matriz de transformação" + +#: ../../po/../src/ui/dialog/transformation.cpp:102 +#, fuzzy +msgid "Rela_tive move" +msgstr "Movimento relativo" + +#: ../../po/../src/ui/dialog/transformation.cpp:102 +msgid "" +"Add the specified relative displacement to the current position; otherwise, " +"edit the current absolute position directly" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:103 +msgid "Scale proportionally" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:103 +msgid "Preserve the width/height ratio of the scaled objects" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:104 +msgid "Apply to each _object separately" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:104 +msgid "" +"Apply the scale/rotate/skew to each selected object separately; otherwise, " +"transform the selection as a whole" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:105 +#, fuzzy +msgid "Edit c_urrent matrix" +msgstr "Levantar a camada atual" + +#: ../../po/../src/ui/dialog/transformation.cpp:105 +msgid "" +"Edit the current transform= matrix; otherwise, post-multiply transform= by " +"this matrix" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:115 +#, fuzzy +msgid "_Move" +msgstr "Mover" + +#: ../../po/../src/ui/dialog/transformation.cpp:118 +#, fuzzy +msgid "_Scale" +msgstr "Ampliar" + +#: ../../po/../src/ui/dialog/transformation.cpp:121 +#, fuzzy +msgid "_Rotate" +msgstr "Girar" + +#: ../../po/../src/ui/dialog/transformation.cpp:124 +#, fuzzy +msgid "Ske_w" +msgstr "Largura do traço" + +#: ../../po/../src/ui/dialog/transformation.cpp:127 +msgid "Matri_x" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:141 +msgid "Reset the values on the current tab to defaults" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:148 +#, fuzzy +msgid "Apply transformation to selection" +msgstr "Selecionar e transformar objetos" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:43 +msgid "_Use SSL" +msgstr "" + +#. Construct dialog interface +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:68 +#, fuzzy +msgid "_Server:" +msgstr "_Reverso" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:69 +#, fuzzy +msgid "_Username:" +msgstr "Nome do arquivo" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:70 +msgid "_Password:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:71 +msgid "P_ort:" +msgstr "" + +#. Buttons +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:99 +#, fuzzy +msgid "Connect" +msgstr "Clones" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:126 +msgid "Establishing connection to Jabber server %1 as user %2" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:131 +msgid "Failed to establish connection to Jabber server %1" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:136 +msgid "Authentication failed on Jabber server %1 as %2" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:141 +msgid "SSL initialization failed when connecting to Jabber server %1" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:147 +msgid "Connected to Jabber server %1 as %2" +msgstr "" + +#. Construct labels +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:75 +msgid "Chatroom _name:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:76 +msgid "Chatroom _server:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:77 +msgid "Chatroom _password:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:78 +msgid "Chatroom _handle:" +msgstr "" + +#. Button setup and callback registration +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:97 +msgid "Connect to chatroom" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:132 +msgid "Synchronizing with chatroom %1@%2 using the handle %3" +msgstr "" + +#. Construct dialog interface +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:78 +msgid "_User's Jabber ID:" +msgstr "" + +#. Buttons +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:82 +msgid "_Invite user" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:83 +#, fuzzy +msgid "_Cancel" +msgstr "Cancelar" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:94 +msgid "Buddy List" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:170 +msgid "Sending whiteboard invitation to %1" +msgstr "" + +#. FIXME: strings are replaced by placeholders, NOT to be translated until the code is enabled +#. See http://sourceforge.net/mailarchive/message.php?msg_id=11746016 for details +#. File menu +#. Edit menu +#. View menu +#. Layer menu +#. Object menu +#. Path menu +#. add(Gtk::StockItem(CLEANUP, _("PLACEHOLDER, do not translate"))); (using Gtk::Stock::CLEAR) +#. Text menu +#. About menu +#. Tools toolbox +#. Select Tool controls +#. Node Tool controls +#. Calligraphy Tool controls +#. Session playback controls +#: ../../po/../src/ui/stock-items.cpp:34 ../../po/../src/ui/stock-items.cpp:35 +#: ../../po/../src/ui/stock-items.cpp:36 ../../po/../src/ui/stock-items.cpp:37 +#: ../../po/../src/ui/stock-items.cpp:38 ../../po/../src/ui/stock-items.cpp:39 +#: ../../po/../src/ui/stock-items.cpp:40 ../../po/../src/ui/stock-items.cpp:41 +#: ../../po/../src/ui/stock-items.cpp:42 ../../po/../src/ui/stock-items.cpp:43 +#: ../../po/../src/ui/stock-items.cpp:46 ../../po/../src/ui/stock-items.cpp:47 +#: ../../po/../src/ui/stock-items.cpp:48 ../../po/../src/ui/stock-items.cpp:49 +#: ../../po/../src/ui/stock-items.cpp:50 ../../po/../src/ui/stock-items.cpp:51 +#: ../../po/../src/ui/stock-items.cpp:52 ../../po/../src/ui/stock-items.cpp:53 +#: ../../po/../src/ui/stock-items.cpp:54 ../../po/../src/ui/stock-items.cpp:55 +#: ../../po/../src/ui/stock-items.cpp:56 ../../po/../src/ui/stock-items.cpp:57 +#: ../../po/../src/ui/stock-items.cpp:58 ../../po/../src/ui/stock-items.cpp:59 +#: ../../po/../src/ui/stock-items.cpp:62 ../../po/../src/ui/stock-items.cpp:63 +#: ../../po/../src/ui/stock-items.cpp:64 ../../po/../src/ui/stock-items.cpp:65 +#: ../../po/../src/ui/stock-items.cpp:66 ../../po/../src/ui/stock-items.cpp:67 +#: ../../po/../src/ui/stock-items.cpp:68 ../../po/../src/ui/stock-items.cpp:69 +#: ../../po/../src/ui/stock-items.cpp:70 ../../po/../src/ui/stock-items.cpp:71 +#: ../../po/../src/ui/stock-items.cpp:72 ../../po/../src/ui/stock-items.cpp:73 +#: ../../po/../src/ui/stock-items.cpp:74 ../../po/../src/ui/stock-items.cpp:75 +#: ../../po/../src/ui/stock-items.cpp:76 ../../po/../src/ui/stock-items.cpp:77 +#: ../../po/../src/ui/stock-items.cpp:78 ../../po/../src/ui/stock-items.cpp:79 +#: ../../po/../src/ui/stock-items.cpp:80 ../../po/../src/ui/stock-items.cpp:81 +#: ../../po/../src/ui/stock-items.cpp:82 ../../po/../src/ui/stock-items.cpp:83 +#: ../../po/../src/ui/stock-items.cpp:84 ../../po/../src/ui/stock-items.cpp:85 +#: ../../po/../src/ui/stock-items.cpp:86 ../../po/../src/ui/stock-items.cpp:87 +#: ../../po/../src/ui/stock-items.cpp:88 ../../po/../src/ui/stock-items.cpp:89 +#: ../../po/../src/ui/stock-items.cpp:92 ../../po/../src/ui/stock-items.cpp:93 +#: ../../po/../src/ui/stock-items.cpp:94 ../../po/../src/ui/stock-items.cpp:95 +#: ../../po/../src/ui/stock-items.cpp:96 ../../po/../src/ui/stock-items.cpp:97 +#: ../../po/../src/ui/stock-items.cpp:98 ../../po/../src/ui/stock-items.cpp:99 +#: ../../po/../src/ui/stock-items.cpp:100 +#: ../../po/../src/ui/stock-items.cpp:101 +#: ../../po/../src/ui/stock-items.cpp:102 +#: ../../po/../src/ui/stock-items.cpp:103 +#: ../../po/../src/ui/stock-items.cpp:104 +#: ../../po/../src/ui/stock-items.cpp:105 +#: ../../po/../src/ui/stock-items.cpp:108 +#: ../../po/../src/ui/stock-items.cpp:109 +#: ../../po/../src/ui/stock-items.cpp:110 +#: ../../po/../src/ui/stock-items.cpp:111 +#: ../../po/../src/ui/stock-items.cpp:112 +#: ../../po/../src/ui/stock-items.cpp:113 +#: ../../po/../src/ui/stock-items.cpp:114 +#: ../../po/../src/ui/stock-items.cpp:115 +#: ../../po/../src/ui/stock-items.cpp:116 +#: ../../po/../src/ui/stock-items.cpp:117 +#: ../../po/../src/ui/stock-items.cpp:118 +#: ../../po/../src/ui/stock-items.cpp:119 +#: ../../po/../src/ui/stock-items.cpp:120 +#: ../../po/../src/ui/stock-items.cpp:121 +#: ../../po/../src/ui/stock-items.cpp:122 +#: ../../po/../src/ui/stock-items.cpp:123 +#: ../../po/../src/ui/stock-items.cpp:124 +#: ../../po/../src/ui/stock-items.cpp:125 +#: ../../po/../src/ui/stock-items.cpp:126 +#: ../../po/../src/ui/stock-items.cpp:127 +#: ../../po/../src/ui/stock-items.cpp:130 +#: ../../po/../src/ui/stock-items.cpp:131 +#: ../../po/../src/ui/stock-items.cpp:132 +#: ../../po/../src/ui/stock-items.cpp:133 +#: ../../po/../src/ui/stock-items.cpp:134 +#: ../../po/../src/ui/stock-items.cpp:135 +#: ../../po/../src/ui/stock-items.cpp:136 +#: ../../po/../src/ui/stock-items.cpp:137 +#: ../../po/../src/ui/stock-items.cpp:138 +#: ../../po/../src/ui/stock-items.cpp:139 +#: ../../po/../src/ui/stock-items.cpp:140 +#: ../../po/../src/ui/stock-items.cpp:141 +#: ../../po/../src/ui/stock-items.cpp:142 +#: ../../po/../src/ui/stock-items.cpp:143 +#: ../../po/../src/ui/stock-items.cpp:144 +#: ../../po/../src/ui/stock-items.cpp:145 +#: ../../po/../src/ui/stock-items.cpp:146 +#: ../../po/../src/ui/stock-items.cpp:150 +#: ../../po/../src/ui/stock-items.cpp:151 +#: ../../po/../src/ui/stock-items.cpp:152 +#: ../../po/../src/ui/stock-items.cpp:153 +#: ../../po/../src/ui/stock-items.cpp:156 +#: ../../po/../src/ui/stock-items.cpp:157 +#: ../../po/../src/ui/stock-items.cpp:158 +#: ../../po/../src/ui/stock-items.cpp:161 +#: ../../po/../src/ui/stock-items.cpp:162 +#: ../../po/../src/ui/stock-items.cpp:163 +#: ../../po/../src/ui/stock-items.cpp:164 +#: ../../po/../src/ui/stock-items.cpp:165 +#: ../../po/../src/ui/stock-items.cpp:166 +#: ../../po/../src/ui/stock-items.cpp:167 +#: ../../po/../src/ui/stock-items.cpp:168 +#: ../../po/../src/ui/stock-items.cpp:169 +#: ../../po/../src/ui/stock-items.cpp:170 +#: ../../po/../src/ui/stock-items.cpp:171 +#: ../../po/../src/ui/stock-items.cpp:172 +#: ../../po/../src/ui/stock-items.cpp:175 +#: ../../po/../src/ui/stock-items.cpp:176 +#: ../../po/../src/ui/stock-items.cpp:177 +#: ../../po/../src/ui/stock-items.cpp:178 +#: ../../po/../src/ui/stock-items.cpp:181 +#: ../../po/../src/ui/stock-items.cpp:182 +#: ../../po/../src/ui/stock-items.cpp:183 +#: ../../po/../src/ui/stock-items.cpp:184 +#: ../../po/../src/ui/stock-items.cpp:185 +#: ../../po/../src/ui/stock-items.cpp:186 +#: ../../po/../src/ui/stock-items.cpp:187 +#: ../../po/../src/ui/stock-items.cpp:188 +#: ../../po/../src/ui/stock-items.cpp:189 +#: ../../po/../src/ui/stock-items.cpp:190 +#: ../../po/../src/ui/stock-items.cpp:191 +#: ../../po/../src/ui/stock-items.cpp:194 +#: ../../po/../src/ui/stock-items.cpp:195 +#: ../../po/../src/ui/stock-items.cpp:198 +#: ../../po/../src/ui/stock-items.cpp:199 +#: ../../po/../src/ui/stock-items.cpp:200 +#: ../../po/../src/ui/stock-items.cpp:201 +#: ../../po/../src/ui/stock-items.cpp:202 +msgid "PLACEHOLDER, do not translate" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:88 +msgid "small" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:89 +msgid "medium" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:90 +#, fuzzy +msgid "large" +msgstr "Alvo:" + +#: ../../po/../src/ui/widget/panel.cpp:91 +msgid "huge" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:106 +#, fuzzy +msgid "List" +msgstr "avançar" + +#: ../../po/../src/ui/widget/selected-style.cpp:67 +msgid "F:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:68 +#, fuzzy +msgid "S:" +msgstr "_S" + +#: ../../po/../src/ui/widget/selected-style.cpp:69 +msgid "O:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:95 +msgid "N/A" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:98 +#: ../../po/../src/ui/widget/selected-style.cpp:712 +#, fuzzy +msgid "Nothing selected" +msgstr "Clone Selecionado" + +#: ../../po/../src/ui/widget/selected-style.cpp:103 +msgid "No fill" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:103 +#, fuzzy +msgid "No stroke" +msgstr "Largura do traço" + +#: ../../po/../src/ui/widget/selected-style.cpp:105 +#: ../../po/../src/widgets/paint-selector.cpp:190 +msgid "Pattern" +msgstr "Preenchimento" + +#: ../../po/../src/ui/widget/selected-style.cpp:108 +#: ../../po/../src/widgets/paint-selector.cpp:885 +msgid "Pattern fill" +msgstr "Padrão de preenchimento" + +#: ../../po/../src/ui/widget/selected-style.cpp:108 +#, fuzzy +msgid "Pattern stroke" +msgstr "Padrão de Tipografia" + +#: ../../po/../src/ui/widget/selected-style.cpp:110 +#, fuzzy +msgid "L Gradient" +msgstr "Editor de Gradiente" + +#: ../../po/../src/ui/widget/selected-style.cpp:113 +#, fuzzy +msgid "Linear gradient fill" +msgstr "Gradiente linear" + +#: ../../po/../src/ui/widget/selected-style.cpp:113 +#, fuzzy +msgid "Linear gradient stroke" +msgstr "Gradiente linear" + +#: ../../po/../src/ui/widget/selected-style.cpp:115 +#, fuzzy +msgid "R Gradient" +msgstr "Editor de Gradiente" + +#: ../../po/../src/ui/widget/selected-style.cpp:118 +#, fuzzy +msgid "Radial gradient fill" +msgstr "Gradiente radial" + +#: ../../po/../src/ui/widget/selected-style.cpp:118 +#, fuzzy +msgid "Radial gradient stroke" +msgstr "Gradiente radial" + +#: ../../po/../src/ui/widget/selected-style.cpp:120 +#, fuzzy +msgid "Different" +msgstr "_Diferença" + +#: ../../po/../src/ui/widget/selected-style.cpp:123 +#, fuzzy +msgid "Different fills" +msgstr "_Diferença" + +#: ../../po/../src/ui/widget/selected-style.cpp:123 +#, fuzzy +msgid "Different strokes" +msgstr "_Diferença" + +#: ../../po/../src/ui/widget/selected-style.cpp:125 +#, fuzzy +msgid "Unset" +msgstr "avançar" + +#. TRANSLATORS COMMENT: unset is a verb here +#: ../../po/../src/ui/widget/selected-style.cpp:128 +#: ../../po/../src/ui/widget/selected-style.cpp:182 +#, fuzzy +msgid "Unset fill" +msgstr "Remo_ver Padrão Ladrilho" + +#: ../../po/../src/ui/widget/selected-style.cpp:128 +#: ../../po/../src/ui/widget/selected-style.cpp:182 +msgid "Unset stroke" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:131 +#, fuzzy +msgid "Flat color fill" +msgstr "Cor lisa" + +#: ../../po/../src/ui/widget/selected-style.cpp:131 +#, fuzzy +msgid "Flat color stroke" +msgstr "Cor lisa" + +#. TRANSLATOR COMMENT: A means "Averaged" +#: ../../po/../src/ui/widget/selected-style.cpp:134 +#, fuzzy +msgid "A" +msgstr "_A" + +#: ../../po/../src/ui/widget/selected-style.cpp:137 +#, fuzzy +msgid "Fill is averaged over selected objects" +msgstr "Ou exclusivo dos objetos selecionados" + +#: ../../po/../src/ui/widget/selected-style.cpp:137 +#, fuzzy +msgid "Stroke is averaged over selected objects" +msgstr "Intersecção dos objetos selecionados" + +#. TRANSLATOR COMMENT: M means "Multiple" +#: ../../po/../src/ui/widget/selected-style.cpp:140 +#, fuzzy +msgid "M" +msgstr "_M" + +#: ../../po/../src/ui/widget/selected-style.cpp:143 +#, fuzzy +msgid "Multiple selected objects have the same fill" +msgstr "Alinhar nós selecionados verticalmente" + +#: ../../po/../src/ui/widget/selected-style.cpp:143 +#, fuzzy +msgid "Multiple selected objects have the same stroke" +msgstr "Alinhar nós selecionados verticalmente" + +#: ../../po/../src/ui/widget/selected-style.cpp:145 +#, fuzzy +msgid "Edit fill..." +msgstr "Alterar" + +#: ../../po/../src/ui/widget/selected-style.cpp:145 +#, fuzzy +msgid "Edit stroke..." +msgstr "Alterar" + +#: ../../po/../src/ui/widget/selected-style.cpp:149 +#, fuzzy +msgid "Last set color" +msgstr "Cor lisa" + +#: ../../po/../src/ui/widget/selected-style.cpp:153 +#, fuzzy +msgid "Last selected color" +msgstr "Último selecionado" + +#: ../../po/../src/ui/widget/selected-style.cpp:157 +msgid "White" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:161 +#: ../../po/../src/widgets/sp-color-scales.cpp:461 +#: ../../po/../src/widgets/sp-color-scales.cpp:462 +msgid "Black" +msgstr "Preto" + +#: ../../po/../src/ui/widget/selected-style.cpp:165 +#, fuzzy +msgid "Copy color" +msgstr "Cor da Parada" + +#: ../../po/../src/ui/widget/selected-style.cpp:169 +#, fuzzy +msgid "Paste color" +msgstr "Cor lisa" + +#: ../../po/../src/ui/widget/selected-style.cpp:173 +#, fuzzy +msgid "Swap fill and stroke" +msgstr "_Preenchimento e Traço" + +#: ../../po/../src/ui/widget/selected-style.cpp:177 +msgid "Make fill opaque" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:177 +msgid "Make stroke opaque" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:186 +#, fuzzy +msgid "Remove fill" +msgstr "_Remover Ligação" + +#: ../../po/../src/ui/widget/selected-style.cpp:186 +#, fuzzy +msgid "Remove stroke" +msgstr "_Remover Ligação" + +#: ../../po/../src/ui/widget/selected-style.cpp:718 +#, fuzzy +msgid "Master opacity" +msgstr "Opacidade Mestre" + +#: ../../po/../src/ui/widget/selected-style.cpp:744 +msgid "0 (transparent)" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:768 +msgid "1.0 (opaque)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1046 +#, fuzzy +msgid "Moved to next layer." +msgstr "Mover para a Próxima Camada" + +#: ../../po/../src/verbs.cpp:1048 +#, fuzzy +msgid "Cannot move past last layer." +msgstr "Não foi possível mover a camada adiante" + +#: ../../po/../src/verbs.cpp:1057 +#, fuzzy +msgid "Moved to previous layer." +msgstr "Mover para a Camada Anterior" + +#: ../../po/../src/verbs.cpp:1059 +#, fuzzy +msgid "Cannot move past first layer." +msgstr "Não foi possível mover a camada adiante" + +#: ../../po/../src/verbs.cpp:1076 ../../po/../src/verbs.cpp:1150 +msgid "No current layer." +msgstr "Nenhuma camada no desenho." + +#: ../../po/../src/verbs.cpp:1105 +#, fuzzy, c-format +msgid "Raised layer %s." +msgstr "Nó Levantado." + +#: ../../po/../src/verbs.cpp:1109 +#, fuzzy, c-format +msgid "Lowered layer %s." +msgstr "Nó abaixado." + +#: ../../po/../src/verbs.cpp:1118 +#, fuzzy +msgid "Cannot move layer any further." +msgstr "Não foi possível mover a camada adiante" + +#. TRANSLATORS: this means "The layer has been deleted." +#: ../../po/../src/verbs.cpp:1148 +msgid "Deleted layer." +msgstr "Nó apagado." + +#: ../../po/../src/verbs.cpp:1544 +msgid "" +"You need to connect to a Jabber server before sharing a document with " +"another user." +msgstr "" + +#: ../../po/../src/verbs.cpp:1559 +msgid "" +"You need to connect to a Jabber server before sharing a document with a " +"chatroom." +msgstr "" + +#: ../../po/../src/verbs.cpp:1569 +msgid "XML node tracker has not been initialized; nothing to dump" +msgstr "" + +#. TRANSLATORS: If you have translated the keys.svg file to your language, then +#. translate this string as "keys.LANG.svg" (where LANG is your language code); +#. otherwise leave as "keys.svg". +#: ../../po/../src/verbs.cpp:1631 +msgid "keys.svg" +msgstr "keys.svg" + +#. TRANSLATORS: If you have translated the tutorial-basic.svg file to your language, +#. then translate this string as "tutorial-basic.LANG.svg" (where LANG is your language +#. code); otherwise leave as "tutorial-basic.svg". +#: ../../po/../src/verbs.cpp:1667 +msgid "tutorial-basic.svg" +msgstr "tutorial-basic.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1671 +msgid "tutorial-shapes.svg" +msgstr "tutorial-basic.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1675 +msgid "tutorial-advanced.svg" +msgstr "tutorial-advanced.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1679 +#, fuzzy +msgid "tutorial-tracing.svg" +msgstr "tutorial-basic.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1683 +#, fuzzy +msgid "tutorial-calligraphy.svg" +msgstr "tutorial-basic.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1687 +#, fuzzy +msgid "tutorial-elements.svg" +msgstr "tutorial-basic.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1691 +#, fuzzy +msgid "tutorial-tips.svg" +msgstr "tutorial-basic.svg" + +#: ../../po/../src/verbs.cpp:1842 +msgid "Does nothing" +msgstr "Não faz nada" + +#. File +#: ../../po/../src/verbs.cpp:1845 +msgid "Default" +msgstr "Padrões" + +#: ../../po/../src/verbs.cpp:1845 +msgid "Create new document from default template" +msgstr "Cria um novo desenho a partir do modelo padrão." + +#: ../../po/../src/verbs.cpp:1847 +msgid "_Open..." +msgstr "_Abrir..." + +#: ../../po/../src/verbs.cpp:1848 +msgid "Open existing document" +msgstr "Abre um desenho existente" + +#: ../../po/../src/verbs.cpp:1849 +msgid "Re_vert" +msgstr "Re_verter" + +#: ../../po/../src/verbs.cpp:1850 +msgid "Revert to the last saved version of document (changes will be lost)" +msgstr "" +"Reverte para a última versão salva do desenho (mudanças serão perdidas)" + +#: ../../po/../src/verbs.cpp:1851 +msgid "_Save" +msgstr "Salvar" + +#: ../../po/../src/verbs.cpp:1851 +msgid "Save document" +msgstr "Salvar o desenho" + +#: ../../po/../src/verbs.cpp:1853 +msgid "Save _As..." +msgstr "Salvar _Como..." + +#: ../../po/../src/verbs.cpp:1854 +msgid "Save document under new name" +msgstr "Salvar o documento com um outro nome" + +#: ../../po/../src/verbs.cpp:1855 +msgid "_Print..." +msgstr "Im_primir..." + +#: ../../po/../src/verbs.cpp:1855 +msgid "Print document" +msgstr "Imprimir o desenho" + +#. TRANSLATORS: "Vacuum Defs" means "Clean up defs" (so as to remove unused definitions) +#: ../../po/../src/verbs.cpp:1858 +msgid "Vac_uum Defs" +msgstr "Limpesa de defs" + +#: ../../po/../src/verbs.cpp:1858 +#, fuzzy +msgid "Remove unused predefined items from the <defs> of the document" +msgstr "Apagar coisas não usadas nos <defs> do desenho" + +#: ../../po/../src/verbs.cpp:1860 +msgid "Print _Direct" +msgstr "Imprimir _Diretamente" + +#: ../../po/../src/verbs.cpp:1861 +#, fuzzy +msgid "Print directly without prompting to a file or pipe" +msgstr "Imprimir diretamente para um arquivo ou redirecionamento" + +#: ../../po/../src/verbs.cpp:1862 +msgid "Print Previe_w" +msgstr "_Visualizar Impressão" + +#: ../../po/../src/verbs.cpp:1863 +msgid "Preview document printout" +msgstr "Visualizar o desenho como vai ser impresso" + +#: ../../po/../src/verbs.cpp:1864 +msgid "_Import..." +msgstr "_Importar..." + +#: ../../po/../src/verbs.cpp:1865 +msgid "Import bitmap or SVG image into document" +msgstr "Importar figura ou imagem SVG para dentro do desenho" + +#: ../../po/../src/verbs.cpp:1866 +msgid "_Export Bitmap..." +msgstr "_Exportar Figura..." + +#: ../../po/../src/verbs.cpp:1867 +#, fuzzy +msgid "Export document or selection as a bitmap image" +msgstr "Exporta o desenho ou a seleção como uma figura PNG" + +#: ../../po/../src/verbs.cpp:1868 +msgid "N_ext Window" +msgstr "Próxima Jan_ela" + +#: ../../po/../src/verbs.cpp:1869 +msgid "Switch to the next document window" +msgstr "Pula para a próxima janela de desenho" + +#: ../../po/../src/verbs.cpp:1870 +msgid "P_revious Window" +msgstr "Janela Ante_rior" + +#: ../../po/../src/verbs.cpp:1871 +msgid "Switch to the previous document window" +msgstr "Pula para a janela de desenho anterior" + +#: ../../po/../src/verbs.cpp:1872 +msgid "_Close" +msgstr "Fe_char" + +#: ../../po/../src/verbs.cpp:1873 +msgid "Close window" +msgstr "Fecha esta janela" + +#: ../../po/../src/verbs.cpp:1874 +msgid "_Quit" +msgstr "_Sair" + +#: ../../po/../src/verbs.cpp:1874 +msgid "Quit Inkscape" +msgstr "Sai do aplicativo Inkscape" + +#. Edit +#: ../../po/../src/verbs.cpp:1877 +msgid "_Undo" +msgstr "_Desfazer" + +#: ../../po/../src/verbs.cpp:1877 +msgid "Undo last action" +msgstr "Desfazer a última ação" + +#: ../../po/../src/verbs.cpp:1879 +msgid "_Redo" +msgstr "_Refazer" + +#: ../../po/../src/verbs.cpp:1880 +msgid "Do again last undone action" +msgstr "Fazer novamente a ação que foi desfeita" + +#: ../../po/../src/verbs.cpp:1881 +msgid "Cu_t" +msgstr "Cor_tar" + +#: ../../po/../src/verbs.cpp:1882 +msgid "Cut selection to clipboard" +msgstr "Cortar a seleção para a área de transferência" + +#: ../../po/../src/verbs.cpp:1883 +msgid "_Copy" +msgstr "_Copiar" + +#: ../../po/../src/verbs.cpp:1884 +msgid "Copy selection to clipboard" +msgstr "Copiar a seleção para a área de transferência" + +#: ../../po/../src/verbs.cpp:1885 +msgid "_Paste" +msgstr "Co_lar" + +#: ../../po/../src/verbs.cpp:1886 +#, fuzzy +msgid "Paste objects from clipboard to mouse point" +msgstr "Colar os objetos da área de transferência para a posição do cursor" + +#: ../../po/../src/verbs.cpp:1887 +msgid "Paste _Style" +msgstr "Colar E_stilo" + +#: ../../po/../src/verbs.cpp:1888 +msgid "Apply style of the copied object to selection" +msgstr "Aplica o estilo do objeto copiado para a seleção" + +#: ../../po/../src/verbs.cpp:1889 +msgid "Paste _In Place" +msgstr "Colar _No Lugar" + +#: ../../po/../src/verbs.cpp:1890 +#, fuzzy +msgid "Paste objects from clipboard to the original location" +msgstr "" +"Cola os objetos da área de transferência para o lugar original de onde foram " +"copiados" + +#: ../../po/../src/verbs.cpp:1891 +msgid "_Delete" +msgstr "Apa_gar" + +#: ../../po/../src/verbs.cpp:1892 +msgid "Delete selection" +msgstr "Apaga a seleção" + +#: ../../po/../src/verbs.cpp:1893 +msgid "Duplic_ate" +msgstr "Duplic_ar" + +#: ../../po/../src/verbs.cpp:1894 +#, fuzzy +msgid "Duplicate selected objects" +msgstr "Duplica os objetos selecionados" + +#: ../../po/../src/verbs.cpp:1895 +msgid "Clo_ne" +msgstr "Clo_nar" + +#: ../../po/../src/verbs.cpp:1896 +msgid "Create a clone of selected object (a copy linked to the original)" +msgstr "Cria um clone dos objetos selecionados (uma cópia ligada ao original)" + +#: ../../po/../src/verbs.cpp:1897 +msgid "Unlin_k Clone" +msgstr "Desl_igar Clone" + +#: ../../po/../src/verbs.cpp:1898 +msgid "Cut the clone's link to its original" +msgstr "Remove a ligação do clone com seu original" + +#: ../../po/../src/verbs.cpp:1899 +msgid "Select _Original" +msgstr "Selecionar _Original" + +#: ../../po/../src/verbs.cpp:1900 +msgid "Select the object to which the clone is linked" +msgstr "Seleciona o objeto com o qual o clone está ligado" + +#. TRANSLATORS: Convert selection to a rectangle with tiled pattern fill +#: ../../po/../src/verbs.cpp:1902 +#, fuzzy +msgid "O_bjects to Pattern" +msgstr "_Objeto para Caminho" + +#: ../../po/../src/verbs.cpp:1903 +msgid "Convert selection to a rectangle with tiled pattern fill" +msgstr "" +"Converter seleção para um retângulo com padrão de preenchimento ladrilho" + +#. TRANSLATORS: Extract objects from a tiled pattern fill +#: ../../po/../src/verbs.cpp:1905 +#, fuzzy +msgid "Pattern to Ob_jects" +msgstr "Padrão de Tipografia" + +#: ../../po/../src/verbs.cpp:1906 +msgid "Extract objects from a tiled pattern fill" +msgstr "Extrai dos objetos o padrão de preenchimento ladrilho" + +#: ../../po/../src/verbs.cpp:1907 +msgid "Clea_r All" +msgstr "Limpa_r Todos" + +#: ../../po/../src/verbs.cpp:1908 +msgid "Delete all objects from document" +msgstr "Apagar todos os objetos do desenho" + +#: ../../po/../src/verbs.cpp:1909 +msgid "Select Al_l" +msgstr "Se_lecionar Todos" + +#: ../../po/../src/verbs.cpp:1910 +msgid "Select all objects or all nodes" +msgstr "Selecionar todos os objetos ou todos os nós" + +#: ../../po/../src/verbs.cpp:1911 +#, fuzzy +msgid "Select All in All La_yers" +msgstr "Selecionar camada" + +#: ../../po/../src/verbs.cpp:1912 +#, fuzzy +msgid "Select all objects in all visible and unlocked layers" +msgstr "Selecionar todos os objetos ou todos os nós" + +#: ../../po/../src/verbs.cpp:1913 +#, fuzzy +msgid "In_vert Selection" +msgstr "Seleção" + +#: ../../po/../src/verbs.cpp:1914 +msgid "Invert selection (unselect what is selected and select everything else)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1915 +msgid "Invert in All Layers" +msgstr "" + +#: ../../po/../src/verbs.cpp:1916 +msgid "Invert selection in all visible and unlocked layers" +msgstr "" + +#: ../../po/../src/verbs.cpp:1917 +msgid "D_eselect" +msgstr "Remover S_eleção" + +#: ../../po/../src/verbs.cpp:1918 +msgid "Deselect any selected objects or nodes" +msgstr "Retira a seleção de qualquer objeto ou nó" + +#. Selection +#: ../../po/../src/verbs.cpp:1921 +msgid "Raise to _Top" +msgstr "Levantar no _Topo" + +#: ../../po/../src/verbs.cpp:1922 +msgid "Raise selection to top" +msgstr "Levanta a seleção para o topo" + +#: ../../po/../src/verbs.cpp:1923 +msgid "Lower to _Bottom" +msgstr "A_baixar para o Fundo" + +#: ../../po/../src/verbs.cpp:1924 +msgid "Lower selection to bottom" +msgstr "Abaixa a seleção até ficar em baixo de todos os outros elementos" + +#: ../../po/../src/verbs.cpp:1925 +msgid "_Raise" +msgstr "Levanta_r" + +#: ../../po/../src/verbs.cpp:1926 +msgid "Raise selection one step" +msgstr "Levanta a seleção um passo" + +#: ../../po/../src/verbs.cpp:1927 +msgid "_Lower" +msgstr "Abai_xar" + +#: ../../po/../src/verbs.cpp:1928 +msgid "Lower selection one step" +msgstr "Abaixa a seleção um passo" + +#: ../../po/../src/verbs.cpp:1929 +msgid "_Group" +msgstr "A_grupar" + +#: ../../po/../src/verbs.cpp:1930 +msgid "Group selected objects" +msgstr "Agrupa os objetos selecionados" + +#: ../../po/../src/verbs.cpp:1932 +#, fuzzy +msgid "Ungroup selected groups" +msgstr "Desagrupa os grupos selecionados" + +#: ../../po/../src/verbs.cpp:1934 +#, fuzzy +msgid "_Put on Path" +msgstr "_Por no caminho" + +#: ../../po/../src/verbs.cpp:1935 +msgid "Put text on path" +msgstr "Por texto no caminho" + +#: ../../po/../src/verbs.cpp:1936 +#, fuzzy +msgid "_Remove from Path" +msgstr "_Remover do caminho" + +#: ../../po/../src/verbs.cpp:1937 +msgid "Remove text from path" +msgstr "Remover texto do caminho" + +#: ../../po/../src/verbs.cpp:1938 +msgid "Remove Manual _Kerns" +msgstr "" + +#. TRANSLATORS: "glyph": An image used in the visual representation of characters; +#. roughly speaking, how a character looks. A font is a set of glyphs. +#: ../../po/../src/verbs.cpp:1941 +#, fuzzy +msgid "Remove all manual kerns and glyph rotations from a text object" +msgstr "Remover transformações do objeto selecionado" + +#: ../../po/../src/verbs.cpp:1943 +msgid "_Union" +msgstr "_União" + +#: ../../po/../src/verbs.cpp:1944 +msgid "Union of selected objects" +msgstr "União dos objetos selecionados" + +#: ../../po/../src/verbs.cpp:1945 +msgid "_Intersection" +msgstr "_Intersecção" + +#: ../../po/../src/verbs.cpp:1946 +msgid "Intersection of selected objects" +msgstr "Intersecção dos objetos selecionados" + +#: ../../po/../src/verbs.cpp:1947 +msgid "_Difference" +msgstr "_Diferença" + +#: ../../po/../src/verbs.cpp:1948 +msgid "Difference of selected objects (bottom minus top)" +msgstr "Diferença dos objetos selecionados (fundo menos topo)" + +#: ../../po/../src/verbs.cpp:1949 +msgid "E_xclusion" +msgstr "E_xclusão" + +#: ../../po/../src/verbs.cpp:1950 +msgid "Exclusive OR of selected objects" +msgstr "Ou exclusivo dos objetos selecionados" + +#: ../../po/../src/verbs.cpp:1951 +msgid "Di_vision" +msgstr "Di_visão" + +#: ../../po/../src/verbs.cpp:1952 +msgid "Cut the bottom object into pieces" +msgstr "Cortar o objeto do fundo em pedaços" + +#. TRANSLATORS: "to cut a path" is not the same as "to break a path apart" - see the +#. Advanced tutorial for more info +#: ../../po/../src/verbs.cpp:1955 +msgid "Cut _Path" +msgstr "Cortar Camin_ho" + +#: ../../po/../src/verbs.cpp:1956 +msgid "Cut the bottom object's stroke into pieces, removing fill" +msgstr "" +"Cortar o traço do objeto do fundo em pedaços, removendo o preenchimento" + +#. TRANSLATORS: "outset": expand a shape by offsetting the object's path, +#. i.e. by displacing it perpendicular to the path in each point. +#. See also the Advanced Tutorial for explanation. +#: ../../po/../src/verbs.cpp:1960 +#, fuzzy +msgid "Outs_et" +msgstr "Ava_nçar" + +#: ../../po/../src/verbs.cpp:1961 +#, fuzzy +msgid "Outset selected paths" +msgstr "Recuar o(s) caminho(s) selecionados" + +#: ../../po/../src/verbs.cpp:1963 +#, fuzzy +msgid "O_utset Path by 1 px" +msgstr "Recuar Cami_nho em 1px" + +#: ../../po/../src/verbs.cpp:1964 +#, fuzzy +msgid "Outset selected paths by 1 px" +msgstr "Recuar os caminhos selecionados em 1px" + +#: ../../po/../src/verbs.cpp:1966 +#, fuzzy +msgid "O_utset Path by 10 px" +msgstr "Recuar Ca_minho em 10px" + +#: ../../po/../src/verbs.cpp:1967 +#, fuzzy +msgid "Outset selected paths by 10 px" +msgstr "Recuar os caminhos selecionados em 10px" + +#. TRANSLATORS: "inset": contract a shape by offsetting the object's path, +#. i.e. by displacing it perpendicular to the path in each point. +#. See also the Advanced Tutorial for explanation. +#: ../../po/../src/verbs.cpp:1971 +msgid "I_nset" +msgstr "Ava_nçar" + +#: ../../po/../src/verbs.cpp:1972 +#, fuzzy +msgid "Inset selected paths" +msgstr "Avançar caminhos selecionados" + +#: ../../po/../src/verbs.cpp:1974 +#, fuzzy +msgid "I_nset Path by 1 px" +msgstr "Ava_nçar Caminho em 1px" + +#: ../../po/../src/verbs.cpp:1975 +#, fuzzy +msgid "Inset selected paths by 1 px" +msgstr "Avança o caminho selecionado em 1px" + +#: ../../po/../src/verbs.cpp:1977 +#, fuzzy +msgid "I_nset Path by 10 px" +msgstr "Ava_nçar Caminho em 10px" + +#: ../../po/../src/verbs.cpp:1978 +#, fuzzy +msgid "Inset selected paths by 10 px" +msgstr "Avança o caminho selecionado em 1px" + +#: ../../po/../src/verbs.cpp:1980 +msgid "D_ynamic Offset" +msgstr "Tipografia D_inâmica" + +#: ../../po/../src/verbs.cpp:1980 +msgid "Create a dynamic offset object" +msgstr "Criar um objeto tipográfico dinâmico" + +#: ../../po/../src/verbs.cpp:1982 +msgid "_Linked Offset" +msgstr "Tipografia _Ligada" + +#: ../../po/../src/verbs.cpp:1983 +msgid "Create a dynamic offset object linked to the original path" +msgstr "Cria um objeto tipográfico dinâmico ligado ao caminho original" + +#: ../../po/../src/verbs.cpp:1985 +msgid "_Stroke to Path" +msgstr "_Traço para caminho" + +#: ../../po/../src/verbs.cpp:1986 +#, fuzzy +msgid "Convert selected strokes to paths" +msgstr "Converte os traços selecionados em caminhos" + +#: ../../po/../src/verbs.cpp:1987 +msgid "Si_mplify" +msgstr "Si_mplificar" + +#: ../../po/../src/verbs.cpp:1988 +#, fuzzy +msgid "Simplify selected paths by removing extra nodes" +msgstr "Simplificar os caminhos selecionados removendo nós adicionais" + +#: ../../po/../src/verbs.cpp:1989 +msgid "_Reverse" +msgstr "_Reverso" + +#: ../../po/../src/verbs.cpp:1990 +#, fuzzy +msgid "Reverses the direction of selected paths; useful for flipping markers" +msgstr "" +"Reverte a direção do caminho selecionado. Útil para marcadores invertidos" + +#. TRANSLATORS: "to trace" means "to convert a bitmap to vector graphics" (to vectorize) +#: ../../po/../src/verbs.cpp:1992 +#, fuzzy +msgid "_Trace Bitmap" +msgstr "_Traçar figura" + +#: ../../po/../src/verbs.cpp:1993 +msgid "Convert bitmap object to paths" +msgstr "Converter objeto da figura para caminhos" + +#: ../../po/../src/verbs.cpp:1994 +#, fuzzy +msgid "_Make a Bitmap Copy" +msgstr "Fazer u_ma cópia da figura" + +#: ../../po/../src/verbs.cpp:1995 +msgid "Export selection to a bitmap and insert it into document" +msgstr "Exportar seleção para uma figura e inseri-la para dentro do desenho" + +#: ../../po/../src/verbs.cpp:1996 +msgid "_Combine" +msgstr "_Combinar" + +#: ../../po/../src/verbs.cpp:1997 +msgid "Combine several paths into one" +msgstr "Combina diversos caminhos em um" + +#. TRANSLATORS: "to cut a path" is not the same as "to break a path apart" - see the +#. Advanced tutorial for more info +#: ../../po/../src/verbs.cpp:2000 +msgid "Break _Apart" +msgstr "Sep_arar" + +#: ../../po/../src/verbs.cpp:2001 +#, fuzzy +msgid "Break selected paths into subpaths" +msgstr "Separar caminhos selecionados em outros caminhos" + +#: ../../po/../src/verbs.cpp:2002 +msgid "Gri_d Arrange..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2003 +msgid "Arrange selection in grid pattern" +msgstr "" + +#. Layer +#: ../../po/../src/verbs.cpp:2005 +#, fuzzy +msgid "_Add Layer..." +msgstr "Nova Camada" + +#: ../../po/../src/verbs.cpp:2006 +msgid "Create a new layer" +msgstr "Cria uma nova camada" + +#: ../../po/../src/verbs.cpp:2007 +#, fuzzy +msgid "Re_name Layer..." +msgstr "Levantar Camada" + +#: ../../po/../src/verbs.cpp:2008 +#, fuzzy +msgid "Rename the current layer" +msgstr "Levantar a camada atual" + +#: ../../po/../src/verbs.cpp:2009 +#, fuzzy +msgid "Switch to Layer Abov_e" +msgstr "Mudado para a próxima camada." + +#: ../../po/../src/verbs.cpp:2010 +#, fuzzy +msgid "Switch to the layer above the current" +msgstr "Pula para a próxima camada no desenho" + +#: ../../po/../src/verbs.cpp:2011 +#, fuzzy +msgid "Switch to Layer Belo_w" +msgstr "Mudado para a próxima camada." + +#: ../../po/../src/verbs.cpp:2012 +#, fuzzy +msgid "Switch to the layer below the current" +msgstr "Pula para a próxima camada no desenho" + +#: ../../po/../src/verbs.cpp:2013 +#, fuzzy +msgid "Move Selection to Layer Abo_ve" +msgstr "Mover para a Próxima Camada" + +#: ../../po/../src/verbs.cpp:2014 +msgid "Move selection to the layer above the current" +msgstr "" + +#: ../../po/../src/verbs.cpp:2015 +#, fuzzy +msgid "Move Selection to Layer Bel_ow" +msgstr "Mover para a Próxima Camada" + +#: ../../po/../src/verbs.cpp:2016 +msgid "Move selection to the layer below the current" +msgstr "" + +#: ../../po/../src/verbs.cpp:2017 +#, fuzzy +msgid "Layer to _Top" +msgstr "Camada no Topo" + +#: ../../po/../src/verbs.cpp:2018 +msgid "Raise the current layer to the top" +msgstr "Levanta a camada atual para o topo" + +#: ../../po/../src/verbs.cpp:2019 +#, fuzzy +msgid "Layer to _Bottom" +msgstr "Camada no Fundo" + +#: ../../po/../src/verbs.cpp:2020 +msgid "Lower the current layer to the bottom" +msgstr "Abaixa a camada atual para o fundo" + +#: ../../po/../src/verbs.cpp:2021 +#, fuzzy +msgid "_Raise Layer" +msgstr "Levantar Camada" + +#: ../../po/../src/verbs.cpp:2022 +msgid "Raise the current layer" +msgstr "Levantar a camada atual" + +#: ../../po/../src/verbs.cpp:2023 +#, fuzzy +msgid "_Lower Layer" +msgstr "Abaixar Camada" + +#: ../../po/../src/verbs.cpp:2024 +msgid "Lower the current layer" +msgstr "Abaixar a camada atual" + +#: ../../po/../src/verbs.cpp:2025 +#, fuzzy +msgid "_Delete Current Layer" +msgstr "Apagar Camada Atual" + +#: ../../po/../src/verbs.cpp:2026 +msgid "Delete the current layer" +msgstr "Apagar a camada atual" + +#. Object +#: ../../po/../src/verbs.cpp:2029 +#, fuzzy +msgid "Rotate _90° CW" +msgstr "Girar +_90 graus " + +#: ../../po/../src/verbs.cpp:2030 +#, fuzzy +msgid "Rotate selection 90° clockwise" +msgstr "Girar a seleção 90 graus no sentido hórario" + +#: ../../po/../src/verbs.cpp:2031 +#, fuzzy +msgid "Rotate 9_0° CCW" +msgstr "Girar -9_0 graus" + +#: ../../po/../src/verbs.cpp:2032 +#, fuzzy +msgid "Rotate selection 90° counter-clockwise" +msgstr "Girar a seleção 90 graus no sentido anti-horário" + +#: ../../po/../src/verbs.cpp:2033 +msgid "Remove _Transformations" +msgstr "Remover _Transformações" + +#: ../../po/../src/verbs.cpp:2034 +msgid "Remove transformations from object" +msgstr "Remover transformações do objeto selecionado" + +#: ../../po/../src/verbs.cpp:2035 +msgid "_Object to Path" +msgstr "_Objeto para Caminho" + +#: ../../po/../src/verbs.cpp:2036 +#, fuzzy +msgid "Convert selected objects to paths" +msgstr "Converte os objetos selecionados em caminhos" + +#: ../../po/../src/verbs.cpp:2037 +msgid "_Flow into Frame" +msgstr "" + +#: ../../po/../src/verbs.cpp:2038 +#, fuzzy +msgid "Put text into frames" +msgstr "Por texto no caminho" + +#: ../../po/../src/verbs.cpp:2039 +#, fuzzy +msgid "_Unflow" +msgstr "Fixar texto fl_utuante" + +#: ../../po/../src/verbs.cpp:2040 +msgid "Remove text from frame (creates a single-line text object)" +msgstr "" + +#: ../../po/../src/verbs.cpp:2041 +#, fuzzy +msgid "_Convert to Text" +msgstr "Converter texto para caminho" + +#: ../../po/../src/verbs.cpp:2042 +#, fuzzy +msgid "Convert flowed text to regular text objects (preserves appearance)" +msgstr "Converter o texto flutuante selecionado para um texto" + +#: ../../po/../src/verbs.cpp:2044 +#, fuzzy +msgid "Flip _Horizontal" +msgstr "Inverter _Horizontalmente" + +#: ../../po/../src/verbs.cpp:2044 +#, fuzzy +msgid "Flips selected objects horizontally" +msgstr "Alinhar nós selecionados horizontalmente" + +#: ../../po/../src/verbs.cpp:2047 +#, fuzzy +msgid "Flip _Vertical" +msgstr "Inverter _Verticalmente" + +#: ../../po/../src/verbs.cpp:2047 +#, fuzzy +msgid "Flips selected objects vertically" +msgstr "Alinhar nós selecionados verticalmente" + +#. Tools +#: ../../po/../src/verbs.cpp:2051 +msgid "Select" +msgstr "Selecionar" + +#: ../../po/../src/verbs.cpp:2052 +msgid "Select and transform objects" +msgstr "Selecionar e transformar objetos" + +#: ../../po/../src/verbs.cpp:2053 +msgid "Node Edit" +msgstr "Alterar Nó" + +#: ../../po/../src/verbs.cpp:2054 +msgid "Edit path nodes or control handles" +msgstr "Alterar nós do caminho ou alças de controle" + +#: ../../po/../src/verbs.cpp:2056 +msgid "Create rectangles and squares" +msgstr "Criar retângulos e quadrados" + +#: ../../po/../src/verbs.cpp:2058 +msgid "Create circles, ellipses, and arcs" +msgstr "Criar círculos, elipses e arcos" + +#: ../../po/../src/verbs.cpp:2060 +msgid "Create stars and polygons" +msgstr "Criar estrelas e polígonos" + +#: ../../po/../src/verbs.cpp:2062 +msgid "Create spirals" +msgstr "Criar espirais" + +#: ../../po/../src/verbs.cpp:2064 +msgid "Draw freehand lines" +msgstr "Desenhar linhas a mão-livre" + +#: ../../po/../src/verbs.cpp:2066 +msgid "Draw Bezier curves and straight lines" +msgstr "Desenhar curvas Bezier e linhas retas" + +#: ../../po/../src/verbs.cpp:2068 +msgid "Draw calligraphic lines" +msgstr "Desenhar linhas caligráficas" + +#: ../../po/../src/verbs.cpp:2070 +msgid "Create and edit text objects" +msgstr "Criar e alterar objetos texto" + +#: ../../po/../src/verbs.cpp:2072 +#, fuzzy +msgid "Create and edit gradients" +msgstr "Criar e alterar objetos texto" + +#: ../../po/../src/verbs.cpp:2074 +msgid "Zoom in or out" +msgstr "Ampliar ou Reduzir" + +#: ../../po/../src/verbs.cpp:2076 +msgid "Pick averaged colors from image" +msgstr "Escolher cores médias da imagem" + +#: ../../po/../src/verbs.cpp:2078 +#, fuzzy +msgid "Create connectors" +msgstr "Cria uma nova camada" + +#. Tool prefs +#: ../../po/../src/verbs.cpp:2081 +msgid "Selector Preferences" +msgstr "Propriedades do Seletor" + +#: ../../po/../src/verbs.cpp:2082 +#, fuzzy +msgid "Open Preferences for the Selector tool" +msgstr "Abre as propriedades da ferramenta Seletor" + +#: ../../po/../src/verbs.cpp:2083 +msgid "Node Tool Preferences" +msgstr "Propriedades da Ferramenta Nó" + +#: ../../po/../src/verbs.cpp:2084 +#, fuzzy +msgid "Open Preferences for the Node tool" +msgstr "Abre as propriedades da ferramenta Nó" + +#: ../../po/../src/verbs.cpp:2085 +msgid "Rectangle Preferences" +msgstr "Propriedades de Retângulos" + +#: ../../po/../src/verbs.cpp:2086 +#, fuzzy +msgid "Open Preferences for the Rectangle tool" +msgstr "Abre as propriedades da ferramenta Retângulo" + +#: ../../po/../src/verbs.cpp:2087 +msgid "Ellipse Preferences" +msgstr "Propriedades de Elipses" + +#: ../../po/../src/verbs.cpp:2088 +#, fuzzy +msgid "Open Preferences for the Ellipse tool" +msgstr "Abre as propriedades da ferramenta Elipse" + +#: ../../po/../src/verbs.cpp:2089 +msgid "Star Preferences" +msgstr "Propriedades de Estrelas" + +#: ../../po/../src/verbs.cpp:2090 +#, fuzzy +msgid "Open Preferences for the Star tool" +msgstr "Abre as propriedades da ferramenta Estrela" + +#: ../../po/../src/verbs.cpp:2091 +msgid "Spiral Preferences" +msgstr "Propriedades de Espirais" + +#: ../../po/../src/verbs.cpp:2092 +#, fuzzy +msgid "Open Preferences for the Spiral tool" +msgstr "Abre as propriedades da ferramenta Espiral" + +#: ../../po/../src/verbs.cpp:2093 +msgid "Pencil Preferences" +msgstr "Propriedades do Lápis" + +#: ../../po/../src/verbs.cpp:2094 +#, fuzzy +msgid "Open Preferences for the Pencil tool" +msgstr "Abre as propriedades da ferramenta Lápis" + +#: ../../po/../src/verbs.cpp:2095 +msgid "Pen Preferences" +msgstr "Propriedades da Caneta" + +#: ../../po/../src/verbs.cpp:2096 +#, fuzzy +msgid "Open Preferences for the Pen tool" +msgstr "Abre as propriedades da ferramenta Caneta" + +#: ../../po/../src/verbs.cpp:2097 +msgid "Calligraphic Preferences" +msgstr "Propriedades de Linhas Caligráficas" + +#: ../../po/../src/verbs.cpp:2098 +#, fuzzy +msgid "Open Preferences for the Calligraphy tool" +msgstr "" +"Abre as Configurações do Inkscape para a ferramenta Linhas Caligráficas" + +#: ../../po/../src/verbs.cpp:2099 +msgid "Text Preferences" +msgstr "Propriedades de Textos" + +#: ../../po/../src/verbs.cpp:2100 +#, fuzzy +msgid "Open Preferences for the Text tool" +msgstr "Abre as Configurações do Inkscape para a ferramenta Texto" + +#: ../../po/../src/verbs.cpp:2101 +#, fuzzy +msgid "Gradient Preferences" +msgstr "Propriedades da Caneta" + +#: ../../po/../src/verbs.cpp:2102 +#, fuzzy +msgid "Open Preferences for the Gradient tool" +msgstr "Abre as propriedades da ferramenta Caneta" + +#: ../../po/../src/verbs.cpp:2103 +msgid "Zoom Preferences" +msgstr "Propriedades de Ampliações" + +#: ../../po/../src/verbs.cpp:2104 +#, fuzzy +msgid "Open Preferences for the Zoom tool" +msgstr "Abre as Configurações do Inkscape para a ferramenta Ampliação" + +#: ../../po/../src/verbs.cpp:2105 +msgid "Dropper Preferences" +msgstr "Propriedades do Borrão" + +#: ../../po/../src/verbs.cpp:2106 +#, fuzzy +msgid "Open Preferences for the Dropper tool" +msgstr "Abre as Configurações do Inkscape para a ferramenta Borrão" + +#: ../../po/../src/verbs.cpp:2107 +#, fuzzy +msgid "Connector Preferences" +msgstr "Propriedades do Seletor" + +#: ../../po/../src/verbs.cpp:2108 +#, fuzzy +msgid "Open Preferences for the Connector tool" +msgstr "Abre as propriedades da ferramenta Seletor" + +#. Zoom/View +#: ../../po/../src/verbs.cpp:2111 +msgid "Zoom In" +msgstr "Ampliar" + +#: ../../po/../src/verbs.cpp:2111 +msgid "Zoom in" +msgstr "Ampliar" + +#: ../../po/../src/verbs.cpp:2112 +msgid "Zoom Out" +msgstr "Reduzir" + +#: ../../po/../src/verbs.cpp:2112 +msgid "Zoom out" +msgstr "Reduzir" + +#: ../../po/../src/verbs.cpp:2113 +msgid "_Rulers" +msgstr "_Réguas" + +#: ../../po/../src/verbs.cpp:2113 +msgid "Show or hide the canvas rulers" +msgstr "Mostrar ou esconder as réguas da tela" + +#: ../../po/../src/verbs.cpp:2114 +msgid "Scroll_bars" +msgstr "_Barras de Rolagem" + +#: ../../po/../src/verbs.cpp:2114 +msgid "Show or hide the canvas scrollbars" +msgstr "Mostrar ou esconder as barras de rolagem da tela" + +#: ../../po/../src/verbs.cpp:2115 +msgid "_Grid" +msgstr "_Grade" + +#: ../../po/../src/verbs.cpp:2116 +msgid "G_uides" +msgstr "G_uias" + +#: ../../po/../src/verbs.cpp:2117 +msgid "Nex_t Zoom" +msgstr "Pró_xima Ampliação" + +#: ../../po/../src/verbs.cpp:2117 +msgid "Next zoom (from the history of zooms)" +msgstr "Próxima ampliação (da lista de ampliações utilizadas)" + +#: ../../po/../src/verbs.cpp:2119 +msgid "Pre_vious Zoom" +msgstr "Amp_liação Anterior" + +#: ../../po/../src/verbs.cpp:2119 +msgid "Previous zoom (from the history of zooms)" +msgstr "Ampliação Anterior (da lista de ampliações utilizadas)" + +#: ../../po/../src/verbs.cpp:2121 +msgid "Zoom 1:_1" +msgstr "Ampliação 1:_1" + +#: ../../po/../src/verbs.cpp:2121 +msgid "Zoom to 1:1" +msgstr "Mostra do tamanho original do desenho" + +#: ../../po/../src/verbs.cpp:2123 +msgid "Zoom 1:_2" +msgstr "Ampliação 1:_2" + +#: ../../po/../src/verbs.cpp:2123 +msgid "Zoom to 1:2" +msgstr "Mostra no dobro do tamanho do desenho" + +#: ../../po/../src/verbs.cpp:2125 +msgid "_Zoom 2:1" +msgstr "Ampliaçã_o 2:1" + +#: ../../po/../src/verbs.cpp:2125 +msgid "Zoom to 2:1" +msgstr "Mostra na metade do tamanho do desenho" + +#: ../../po/../src/verbs.cpp:2128 +msgid "_Fullscreen" +msgstr "_Tela cheia" + +#: ../../po/../src/verbs.cpp:2128 +msgid "Stretch this document window to full screen" +msgstr "Alarga esta janela de desenho para ocupar todo o monitor" + +#: ../../po/../src/verbs.cpp:2131 +#, fuzzy +msgid "Duplic_ate Window" +msgstr "D_uplicar Janela" + +#: ../../po/../src/verbs.cpp:2131 +msgid "Open a new window with the same document" +msgstr "Abre uma novo janela com o mesmo desenho" + +#: ../../po/../src/verbs.cpp:2133 +msgid "_New View Preview" +msgstr "_Nova Visualização" + +#: ../../po/../src/verbs.cpp:2134 +msgid "New View Preview" +msgstr "Nova visualização" + +#. "view_new_preview" +#: ../../po/../src/verbs.cpp:2136 +#, fuzzy +msgid "_Normal" +msgstr "Normal" + +#: ../../po/../src/verbs.cpp:2137 +msgid "Switch to normal display mode" +msgstr "" + +#: ../../po/../src/verbs.cpp:2138 +#, fuzzy +msgid "_Outline" +msgstr "Contorno da caixa" + +#: ../../po/../src/verbs.cpp:2139 +msgid "Switch to outline (wireframe) display mode" +msgstr "" + +#: ../../po/../src/verbs.cpp:2141 +#, fuzzy +msgid "Ico_n Preview" +msgstr "Visualização" + +#: ../../po/../src/verbs.cpp:2142 +msgid "Open a window to preview items at different icon resolutions" +msgstr "" + +#: ../../po/../src/verbs.cpp:2144 +msgid "Zoom to fit page in window" +msgstr "Ampliar para caber a página na janela" + +#: ../../po/../src/verbs.cpp:2145 +msgid "Page _Width" +msgstr "_Largura da Página" + +#: ../../po/../src/verbs.cpp:2146 +msgid "Zoom to fit page width in window" +msgstr "Ampliar para caber a largura da página na janela" + +#: ../../po/../src/verbs.cpp:2148 +msgid "Zoom to fit drawing in window" +msgstr "Ampliar para caber o desenho na janela" + +#: ../../po/../src/verbs.cpp:2150 +msgid "Zoom to fit selection in window" +msgstr "Ampliar para caber a seleção na janela" + +#. Dialogs +#: ../../po/../src/verbs.cpp:2153 +msgid "In_kscape Preferences..." +msgstr "Configurações do In_kscape" + +#: ../../po/../src/verbs.cpp:2154 +msgid "Global Inkscape preferences" +msgstr "Configurações Globais do In_kscape" + +#: ../../po/../src/verbs.cpp:2155 +msgid "_Document Preferences..." +msgstr "Configurações do _Desenho" + +#: ../../po/../src/verbs.cpp:2156 +msgid "Preferences saved with the document" +msgstr "Configurações salvas como o desenho" + +#: ../../po/../src/verbs.cpp:2157 +msgid "_Fill and Stroke..." +msgstr "_Preenchimento e Traço..." + +#: ../../po/../src/verbs.cpp:2158 +msgid "Fill and Stroke dialog" +msgstr "Janela de Preenchimento e Traço" + +#. TRANSLATORS: "Swatches" means: color samples +#: ../../po/../src/verbs.cpp:2160 +#, fuzzy +msgid "S_watches..." +msgstr "Salvar _Como..." + +#: ../../po/../src/verbs.cpp:2161 +msgid "View color swatches" +msgstr "" + +#: ../../po/../src/verbs.cpp:2162 +msgid "Transfor_m..." +msgstr "Transfor_mação..." + +#: ../../po/../src/verbs.cpp:2163 +msgid "Transform dialog" +msgstr "Janela de Transformação" + +#: ../../po/../src/verbs.cpp:2164 +msgid "_Align and Distribute..." +msgstr "_Alinhar e Distribuir..." + +#: ../../po/../src/verbs.cpp:2165 +msgid "Align and Distribute dialog" +msgstr "Janela de alinhar e distribuir" + +#: ../../po/../src/verbs.cpp:2166 +#, fuzzy +msgid "_Text and Font..." +msgstr "Texto e _Fonte..." + +#: ../../po/../src/verbs.cpp:2167 +msgid "Text and Font dialog" +msgstr "Janela de Texto e Fonte" + +#: ../../po/../src/verbs.cpp:2168 +msgid "_XML Editor..." +msgstr "Editor _XML" + +#: ../../po/../src/verbs.cpp:2169 +msgid "XML Editor" +msgstr "Janela do Editor XML" + +#: ../../po/../src/verbs.cpp:2170 +msgid "_Find..." +msgstr "_Encontrar..." + +#: ../../po/../src/verbs.cpp:2171 +msgid "Find objects in document" +msgstr "Encontrar objetos no desenho" + +#: ../../po/../src/verbs.cpp:2172 +msgid "_Messages..." +msgstr "_Mensagens..." + +#: ../../po/../src/verbs.cpp:2173 +msgid "View debug messages" +msgstr "Ver mensagens de depuração" + +#: ../../po/../src/verbs.cpp:2174 +#, fuzzy +msgid "S_cripts..." +msgstr "Im_primir..." + +#: ../../po/../src/verbs.cpp:2175 +#, fuzzy +msgid "Run scripts" +msgstr "Ponta Redonda" + +#: ../../po/../src/verbs.cpp:2176 +#, fuzzy +msgid "Show/Hide D_ialogs" +msgstr "Mostrar/Esconder _Janelas" + +#: ../../po/../src/verbs.cpp:2177 +msgid "Show or hide all active dialogs" +msgstr "Mostrar ou esconder todas as janelas ativas" + +#. TRANSLATORS: "Tile clones" means: "Create tiled clones" +#: ../../po/../src/verbs.cpp:2179 +msgid "Tile clones..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2180 +msgid "Create and arrange multiple clones of selection" +msgstr "" + +#: ../../po/../src/verbs.cpp:2181 +msgid "_Object Properties..." +msgstr "Propriedades do _Objeto" + +#: ../../po/../src/verbs.cpp:2182 +msgid "Object Properties dialog" +msgstr "Janela de Propriedades do Objeto" + +#: ../../po/../src/verbs.cpp:2185 +msgid "_Connect to Jabber server..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2185 +msgid "Connect to a Jabber server" +msgstr "" + +#: ../../po/../src/verbs.cpp:2187 +#, fuzzy +msgid "Share with _user..." +msgstr "Salvar _Como..." + +#: ../../po/../src/verbs.cpp:2187 +msgid "Establish a whiteboard session with another Jabber user" +msgstr "" + +#: ../../po/../src/verbs.cpp:2189 +msgid "Share with _chatroom..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2189 +msgid "" +"Join a chatroom to start a new whiteboard session or join one in progress" +msgstr "" + +#: ../../po/../src/verbs.cpp:2191 +msgid "_Dump XML node tracker" +msgstr "" + +#: ../../po/../src/verbs.cpp:2191 +msgid "Dump the contents of the XML tracker to the console" +msgstr "" + +#: ../../po/../src/verbs.cpp:2193 +msgid "_Open session file..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2193 +msgid "Open and browse through records of past whiteboard sessions" +msgstr "" + +#: ../../po/../src/verbs.cpp:2195 +msgid "Session file playback" +msgstr "" + +#: ../../po/../src/verbs.cpp:2197 +msgid "_Disconnect from session" +msgstr "" + +#: ../../po/../src/verbs.cpp:2199 +msgid "Disconnect from _server" +msgstr "" + +#: ../../po/../src/verbs.cpp:2201 +msgid "_Input Devices..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2202 +msgid "Configure extended input devices" +msgstr "" + +#. Help +#: ../../po/../src/verbs.cpp:2205 +msgid "_Keys and Mouse" +msgstr "_Teclas e Cliques" + +#: ../../po/../src/verbs.cpp:2206 +msgid "Key and mouse shortcuts reference" +msgstr "Referência de atalhos do teclado e mouse" + +#: ../../po/../src/verbs.cpp:2207 +#, fuzzy +msgid "About E_xtensions" +msgstr "Expansão:" + +#: ../../po/../src/verbs.cpp:2208 +#, fuzzy +msgid "About Extensions..." +msgstr "Expansão:" + +#: ../../po/../src/verbs.cpp:2209 +#, fuzzy +msgid "About _Memory" +msgstr "Expansão:" + +#: ../../po/../src/verbs.cpp:2210 +#, fuzzy +msgid "About Memory..." +msgstr "Expansão:" + +#: ../../po/../src/verbs.cpp:2211 +msgid "_About Inkscape" +msgstr "_Sobre o Inkscape" + +#. "help_about" +#. new HelpVerb(SP_VERB_SHOW_LICENSE, "ShowLicense", N_("Modifying or Redistributing Inkscape"), +#. N_("Show license to modify and/or redistribute Inkscape: GNU GPL"), NULL), +#. Tutorials +#: ../../po/../src/verbs.cpp:2217 +msgid "Inkscape: _Basic" +msgstr "Inkscape: _Básico" + +#: ../../po/../src/verbs.cpp:2218 +msgid "Getting started with Inkscape" +msgstr "Iniciando no Inkscape" + +#. "tutorial_basic" +#: ../../po/../src/verbs.cpp:2219 +msgid "Inkscape: _Shapes" +msgstr "Inkscape: Forma_s" + +#: ../../po/../src/verbs.cpp:2220 +msgid "Using shape tools to create and edit shapes" +msgstr "Usar ferramentas de formas para criar e alterar formas" + +#: ../../po/../src/verbs.cpp:2221 +msgid "Inkscape: _Advanced" +msgstr "Inkscape: _Avançado" + +#: ../../po/../src/verbs.cpp:2222 +msgid "Advanced Inkscape topics" +msgstr "Tópicos Avançados do Inkscape" + +#. "tutorial_advanced" +#. TRANSLATORS: "to trace" means "to convert a bitmap to vector graphics" (to vectorize) +#: ../../po/../src/verbs.cpp:2224 +#, fuzzy +msgid "Inkscape: T_racing" +msgstr "Inkscape: _Básico" + +#: ../../po/../src/verbs.cpp:2225 +#, fuzzy +msgid "Using bitmap tracing" +msgstr "Traçado da figura" + +#. "tutorial_tracing" +#: ../../po/../src/verbs.cpp:2226 +#, fuzzy +msgid "Inkscape: _Calligraphy" +msgstr "Inkscape: _Básico" + +#: ../../po/../src/verbs.cpp:2227 +#, fuzzy +msgid "Using the Calligraphy pen tool" +msgstr "A largura da caneta caligráfica" + +#: ../../po/../src/verbs.cpp:2228 +msgid "_Elements of Design" +msgstr "_Elementos do Desenho" + +#: ../../po/../src/verbs.cpp:2229 +#, fuzzy +msgid "Principles of design in the tutorial form" +msgstr "Tutoriais de elementos do desenho" + +#. "tutorial_design" +#: ../../po/../src/verbs.cpp:2230 +msgid "_Tips and Tricks" +msgstr "Dicas e _Truques" + +#: ../../po/../src/verbs.cpp:2231 +#, fuzzy +msgid "Miscellaneous tips and tricks" +msgstr "Miscelânea de Dicas e truques" + +#. "tutorial_tips" +#. Effect +#: ../../po/../src/verbs.cpp:2234 +#, fuzzy +msgid "Previous Effect" +msgstr "Amp_liação Anterior" + +#: ../../po/../src/verbs.cpp:2235 +msgid "Repeat the last effect with the same settings" +msgstr "" + +#. "tutorial_tips" +#: ../../po/../src/verbs.cpp:2236 +#, fuzzy +msgid "Previous Effect Settings..." +msgstr "Amp_liação Anterior" + +#: ../../po/../src/verbs.cpp:2237 +msgid "Repeat the last effect with new settings" +msgstr "" + +#: ../../po/../src/widgets/dash-selector.cpp:106 +msgid "Dash pattern" +msgstr "Padrão de traço" + +#: ../../po/../src/widgets/dash-selector.cpp:121 +msgid "Pattern offset" +msgstr "Padrão de Tipografia" + +#: ../../po/../src/widgets/desktop-widget.cpp:240 +msgid "Zoom drawing if window size changes" +msgstr "Ajustar nível de zoom do desenho se o tamanho da janela mudar" + +#: ../../po/../src/widgets/desktop-widget.cpp:298 +msgid "Cursor coordinates" +msgstr "Coordenadas do cursor" + +#. display the initial welcome message in the statusbar +#: ../../po/../src/widgets/desktop-widget.cpp:324 +msgid "" +"Welcome to Inkscape! Use shape or freehand tools to create objects; " +"use selector (arrow) to move or transform them." +msgstr "" +"Bem vindo ao Inkscape! Use as ferramentas de forma ou mão-livre para " +"criar objetos. Use o seletor (seta) para mover ou transformá-los." + +#: ../../po/../src/widgets/desktop-widget.cpp:372 +#, c-format +msgid "%s: %d - Inkscape" +msgstr "%s: %d - Inkscape" + +#: ../../po/../src/widgets/desktop-widget.cpp:374 +#, c-format +msgid "%s - Inkscape" +msgstr "%s - Inkscape" + +#: ../../po/../src/widgets/desktop-widget.cpp:532 +#, c-format +msgid "" +"Save changes to document \"%s\" before " +"closing?\n" +"\n" +"If you close without saving, your changes will be discarded." +msgstr "" +"Salvar as modificações do desenho \"%s" +"\" antes de fechar?\n" +"\n" +"Se você fechar sem salvar, suas modificações serão descartadas." + +#: ../../po/../src/widgets/desktop-widget.cpp:548 +#: ../../po/../src/widgets/desktop-widget.cpp:612 +msgid "Close _without saving" +msgstr "Fechar _sem salvar" + +#: ../../po/../src/widgets/desktop-widget.cpp:595 +#, c-format +msgid "" +"The file \"%s\" was saved with a " +"format (%s) that may cause data loss!\n" +"\n" +"Do you want to save this file in another format?" +msgstr "" +"O arquivo \"%s\" foi salvo com um " +"formato (%s) que causará perda de dados!\n" +"\n" +"Deseja salvar este arquivo em outro formato?" + +#. Family frame +#: ../../po/../src/widgets/font-selector.cpp:156 +msgid "Font family" +msgstr "Família da fonte" + +#. Style frame +#: ../../po/../src/widgets/font-selector.cpp:184 +msgid "Style" +msgstr "Estilo" + +#: ../../po/../src/widgets/font-selector.cpp:219 +msgid "Font size:" +msgstr "Tamanho da Fonte" + +#. TRANSLATORS: Test string used in text and font dialog (when no +#. * text has been entered) to get a preview of the font. Choose +#. * some representative characters that users of your locale will be +#. * interested in. +#: ../../po/../src/widgets/font-selector.cpp:554 +msgid "AaBbCcIiPpQq12368.;/()" +msgstr "AaBbCcIiPpQq12368.;/()" + +#: ../../po/../src/widgets/gradient-selector.cpp:137 +#: ../../po/../src/widgets/gradient-toolbar.cpp:524 +#, fuzzy +msgid "Duplicate" +msgstr "Duplic_ar" + +#: ../../po/../src/widgets/gradient-selector.cpp:142 +#: ../../po/../src/widgets/gradient-toolbar.cpp:535 +#, fuzzy +msgid "Edit..." +msgstr "Alterar" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/pservers.html#LinearGradientSpreadMethodAttribute +#: ../../po/../src/widgets/gradient-selector.cpp:159 +msgid "" +"Whether to fill with flat color beyond the ends of the gradient vector " +"(spreadMethod=\"pad\"), or repeat the gradient in the same direction " +"(spreadMethod=\"repeat\"), or repeat the gradient in alternating opposite " +"directions (spreadMethod=\"reflect\")" +msgstr "" +"Se para preencher com uma cor além dos fins do vetor do gradiente " +"(spreadMethod=\"pad\"), ou repetir o gradiente na mesma direção(spreadMethod=" +"\"repeat\"), ou repetir o gradiente ao alternas direções opostas " +"(spreadMethod=\"reflect\")" + +#: ../../po/../src/widgets/gradient-selector.cpp:165 +msgid "none" +msgstr "nenhum" + +#: ../../po/../src/widgets/gradient-selector.cpp:169 +msgid "reflected" +msgstr "refletido" + +#: ../../po/../src/widgets/gradient-selector.cpp:173 +msgid "direct" +msgstr "direto" + +#: ../../po/../src/widgets/gradient-selector.cpp:181 +msgid "Repeat:" +msgstr "Repetir:" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:217 +msgid "No gradients" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:226 +msgid "Nothing selected" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:237 +#, fuzzy +msgid "No gradients in selection" +msgstr "Nenhum gradiente selecionado" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:247 +msgid "Multiple gradients" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:525 +msgid "" +"If the gradient is used by more than one object, create a copy of it for the " +"selected object(s)" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:536 +#, fuzzy +msgid "Edit the stops of the gradient" +msgstr "Nenhuma parada no gradiente" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:593 +#: ../../po/../src/widgets/toolbox.cpp:1103 +#: ../../po/../src/widgets/toolbox.cpp:1192 +#: ../../po/../src/widgets/toolbox.cpp:1485 +#: ../../po/../src/widgets/toolbox.cpp:1534 +#: ../../po/../src/widgets/toolbox.cpp:1766 +#: ../../po/../src/widgets/toolbox.cpp:1801 +#: ../../po/../src/widgets/toolbox.cpp:2331 +#: ../../po/../src/widgets/toolbox.cpp:2370 +msgid "New:" +msgstr "Novo:" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:606 +#, fuzzy +msgid "Create linear gradient" +msgstr "Gradiente linear" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:620 +msgid "Create radial (elliptic or circular) gradient" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:635 +#, fuzzy +msgid "on" +msgstr "nenhum" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:648 +#, fuzzy +msgid "Create gradient in the fill" +msgstr "Editor de Gradiente" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:662 +msgid "Create gradient in the stroke" +msgstr "" + +#. FIXME: implement averaging of all parameters for multiple selected stars +#. gtk_label_set_markup(GTK_LABEL(l), _("Average:")); +#. FIXME: implement averaging of all parameters for multiple selected +#. gtk_label_set_markup(GTK_LABEL(l), _("Average:")); +#: ../../po/../src/widgets/gradient-toolbar.cpp:676 +#: ../../po/../src/widgets/toolbox.cpp:1105 +#: ../../po/../src/widgets/toolbox.cpp:1124 +#: ../../po/../src/widgets/toolbox.cpp:1493 +#: ../../po/../src/widgets/toolbox.cpp:1518 +#: ../../po/../src/widgets/toolbox.cpp:1768 +#: ../../po/../src/widgets/toolbox.cpp:1787 +#: ../../po/../src/widgets/toolbox.cpp:2334 +#: ../../po/../src/widgets/toolbox.cpp:2354 +msgid "Change:" +msgstr "Modificado:" + +#: ../../po/../src/widgets/gradient-vector.cpp:269 +msgid "No gradients in document" +msgstr "Nenhum gradiente no desenho" + +#: ../../po/../src/widgets/gradient-vector.cpp:275 +msgid "No gradient selected" +msgstr "Nenhum gradiente selecionado" + +#: ../../po/../src/widgets/gradient-vector.cpp:532 +msgid "No stops in gradient" +msgstr "Nenhuma parada no gradiente" + +#. TRANSLATORS: "Stop" means: a "phase" of a gradient +#: ../../po/../src/widgets/gradient-vector.cpp:794 +msgid "Add stop" +msgstr "Acrescentar parada" + +#: ../../po/../src/widgets/gradient-vector.cpp:797 +msgid "Add another control stop to gradient" +msgstr "Acrescentar outra parada de controle no gradiente" + +#: ../../po/../src/widgets/gradient-vector.cpp:799 +msgid "Delete stop" +msgstr "Apagar parada" + +#: ../../po/../src/widgets/gradient-vector.cpp:802 +msgid "Delete current control stop from gradient" +msgstr "Apagar parada de controle atual do gradiente" + +#. Label +#: ../../po/../src/widgets/gradient-vector.cpp:813 +msgid "Offset:" +msgstr "Tipografia:" + +#. TRANSLATORS: "Stop" means: a "phase" of a gradient +#: ../../po/../src/widgets/gradient-vector.cpp:858 +msgid "Stop Color" +msgstr "Cor da Parada" + +#: ../../po/../src/widgets/gradient-vector.cpp:887 +msgid "Gradient editor" +msgstr "Editor de Gradiente" + +#: ../../po/../src/widgets/layer-selector.cpp:119 +#, fuzzy +msgid "Toggle current layer visibility" +msgstr "Nenhuma camada no desenho." + +#: ../../po/../src/widgets/layer-selector.cpp:139 +#, fuzzy +msgid "Lock or unlock current layer" +msgstr "Abaixar a camada atual" + +#: ../../po/../src/widgets/layer-selector.cpp:142 +#, fuzzy +msgid "Current layer" +msgstr "Nenhuma camada no desenho." + +#: ../../po/../src/widgets/layer-selector.cpp:553 +msgid "(root)" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:182 +#: ../../po/../src/widgets/paint-selector.cpp:561 +msgid "No paint" +msgstr "Nenhuma pintura" + +#: ../../po/../src/widgets/paint-selector.cpp:184 +#: ../../po/../src/widgets/paint-selector.cpp:629 +msgid "Flat color" +msgstr "Cor lisa" + +#: ../../po/../src/widgets/paint-selector.cpp:186 +#: ../../po/../src/widgets/paint-selector.cpp:696 +msgid "Linear gradient" +msgstr "Gradiente linear" + +#: ../../po/../src/widgets/paint-selector.cpp:188 +#: ../../po/../src/widgets/paint-selector.cpp:699 +msgid "Radial gradient" +msgstr "Gradiente radial" + +#: ../../po/../src/widgets/paint-selector.cpp:192 +msgid "Unset paint (make it undefined so it can be inherited)" +msgstr "" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/painting.html#FillRuleProperty +#: ../../po/../src/widgets/paint-selector.cpp:204 +msgid "" +"Any path self-intersections or subpaths create holes in the fill (fill-rule: " +"evenodd)" +msgstr "" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/painting.html#FillRuleProperty +#: ../../po/../src/widgets/paint-selector.cpp:215 +msgid "" +"Fill is solid unless a subpath is counterdirectional (fill-rule: nonzero)" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:528 +msgid "No objects" +msgstr "Nenhum objeto" + +#: ../../po/../src/widgets/paint-selector.cpp:539 +msgid "Multiple styles" +msgstr "Estilos múltiplos" + +#: ../../po/../src/widgets/paint-selector.cpp:550 +msgid "Paint is undefined" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:757 +msgid "No patterns in document" +msgstr "Nenhum padrão no documento" + +#: ../../po/../src/widgets/paint-selector.cpp:872 +msgid "" +"Use Edit > Object(s) to Pattern to create a new pattern from " +"selection." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:426 +msgid "Now stroke width is scaled when objects are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:428 +msgid "Now stroke width is not scaled when objects are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:436 +msgid "" +"Now rounded rectangle corners are scaled when rectangles are " +"scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:438 +msgid "" +"Now rounded rectangle corners are not scaled when rectangles " +"are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:446 +msgid "" +"Now gradients are transformed along with their objects when " +"those are transformed (moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:448 +msgid "" +"Now gradients remain fixed when objects are transformed " +"(moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:456 +msgid "" +"Now patterns are transformed along with their objects when " +"those are transformed (moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:458 +msgid "" +"Now patterns remain fixed when objects are transformed (moved, " +"scaled, rotated, or skewed)." +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:506 +#, fuzzy +msgid "select_toolbar|X" +msgstr "Seletor" + +#: ../../po/../src/widgets/select-toolbar.cpp:506 +msgid "Horizontal coordinate of selection" +msgstr "Coordenada horizontal da seleção" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:511 +#, fuzzy +msgid "select_toolbar|Y" +msgstr "Seletor" + +#: ../../po/../src/widgets/select-toolbar.cpp:511 +msgid "Vertical coordinate of selection" +msgstr "Coordenada vertical da seleção" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:517 +#, fuzzy +msgid "select_toolbar|W" +msgstr "Seletor" + +#: ../../po/../src/widgets/select-toolbar.cpp:517 +msgid "Width of selection" +msgstr "Largura da seleção" + +#: ../../po/../src/widgets/select-toolbar.cpp:525 +msgid "Change both width and height by the same proportion" +msgstr "Mudar ambas a largura e altura pela mesma proporção" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:534 +#, fuzzy +msgid "select_toolbar|H" +msgstr "Seletor" + +#: ../../po/../src/widgets/select-toolbar.cpp:534 +msgid "Height of selection" +msgstr "Altura da seleção" + +#: ../../po/../src/widgets/sp-color-gtkselector.cpp:62 +msgid "System" +msgstr "Sistema" + +#: ../../po/../src/widgets/sp-color-notebook.cpp:322 +#, fuzzy +msgid "RGBA_:" +msgstr "RGB" + +#: ../../po/../src/widgets/sp-color-notebook.cpp:330 +msgid "Hexadecimal RGBA value of the color" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "RGB" +msgstr "RGB" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +#, fuzzy +msgid "HSL" +msgstr "HSV" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "CMYK" +msgstr "CMYK" + +#: ../../po/../src/widgets/sp-color-scales.cpp:397 +msgid "_R" +msgstr "_R" + +#: ../../po/../src/widgets/sp-color-scales.cpp:398 +#: ../../po/../src/widgets/sp-color-scales.cpp:399 +msgid "Red" +msgstr "Vermelho" + +#: ../../po/../src/widgets/sp-color-scales.cpp:400 +msgid "_G" +msgstr "_G" + +#: ../../po/../src/widgets/sp-color-scales.cpp:401 +#: ../../po/../src/widgets/sp-color-scales.cpp:402 +msgid "Green" +msgstr "Verde" + +#: ../../po/../src/widgets/sp-color-scales.cpp:403 +msgid "_B" +msgstr "_B" + +#: ../../po/../src/widgets/sp-color-scales.cpp:404 +#: ../../po/../src/widgets/sp-color-scales.cpp:405 +msgid "Blue" +msgstr "Azul" + +#. Label +#: ../../po/../src/widgets/sp-color-scales.cpp:406 +#: ../../po/../src/widgets/sp-color-scales.cpp:432 +#: ../../po/../src/widgets/sp-color-scales.cpp:463 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:141 +msgid "_A" +msgstr "_A" + +#: ../../po/../src/widgets/sp-color-scales.cpp:407 +#: ../../po/../src/widgets/sp-color-scales.cpp:408 +#: ../../po/../src/widgets/sp-color-scales.cpp:433 +#: ../../po/../src/widgets/sp-color-scales.cpp:434 +#: ../../po/../src/widgets/sp-color-scales.cpp:464 +#: ../../po/../src/widgets/sp-color-scales.cpp:465 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:151 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:163 +msgid "Alpha (opacity)" +msgstr "Alfa (transparência)" + +#: ../../po/../src/widgets/sp-color-scales.cpp:423 +msgid "_H" +msgstr "_H" + +#: ../../po/../src/widgets/sp-color-scales.cpp:424 +#: ../../po/../src/widgets/sp-color-scales.cpp:425 +msgid "Hue" +msgstr "Contraste" + +#: ../../po/../src/widgets/sp-color-scales.cpp:426 +msgid "_S" +msgstr "_S" + +#: ../../po/../src/widgets/sp-color-scales.cpp:427 +#: ../../po/../src/widgets/sp-color-scales.cpp:428 +msgid "Saturation" +msgstr "Saturação" + +#: ../../po/../src/widgets/sp-color-scales.cpp:429 +msgid "_L" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:430 +#: ../../po/../src/widgets/sp-color-scales.cpp:431 +#, fuzzy +msgid "Lightness" +msgstr "Brilho" + +#: ../../po/../src/widgets/sp-color-scales.cpp:451 +msgid "_C" +msgstr "_C" + +#: ../../po/../src/widgets/sp-color-scales.cpp:452 +#: ../../po/../src/widgets/sp-color-scales.cpp:453 +msgid "Cyan" +msgstr "Ciano" + +#: ../../po/../src/widgets/sp-color-scales.cpp:454 +msgid "_M" +msgstr "_M" + +#: ../../po/../src/widgets/sp-color-scales.cpp:455 +#: ../../po/../src/widgets/sp-color-scales.cpp:456 +msgid "Magenta" +msgstr "Magenta" + +#: ../../po/../src/widgets/sp-color-scales.cpp:457 +msgid "_Y" +msgstr "_Y" + +#: ../../po/../src/widgets/sp-color-scales.cpp:458 +#: ../../po/../src/widgets/sp-color-scales.cpp:459 +msgid "Yellow" +msgstr "Amarelo" + +#: ../../po/../src/widgets/sp-color-scales.cpp:460 +msgid "_K" +msgstr "_K" + +#: ../../po/../src/widgets/sp-color-selector.cpp:71 +msgid "Unnamed" +msgstr "Não nomeado" + +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:68 +msgid "Wheel" +msgstr "Roda" + +#: ../../po/../src/widgets/sp-xmlview-attr-list.cpp:53 +msgid "Attribute" +msgstr "Atributo" + +#: ../../po/../src/widgets/sp-xmlview-attr-list.cpp:54 +msgid "Value" +msgstr "Valor" + +#: ../../po/../src/widgets/toolbox.cpp:424 +msgid "Insert new nodes into selected segments" +msgstr "Inserir novos nós dentro dos segmentos selecionados" + +#: ../../po/../src/widgets/toolbox.cpp:426 +msgid "Delete selected nodes" +msgstr "Apagar nós selecionados" + +#: ../../po/../src/widgets/toolbox.cpp:431 +msgid "Join paths at selected nodes" +msgstr "Juntar camimhos nos nós selecionados" + +#: ../../po/../src/widgets/toolbox.cpp:433 +msgid "Join paths at selected nodes with new segment" +msgstr "Juntar caminhos nos nós selecionados com novo segmento" + +#: ../../po/../src/widgets/toolbox.cpp:436 +msgid "Split path between two non-endpoint nodes" +msgstr "Separar caminho entre dois nós que não sejam pontos finais" + +#: ../../po/../src/widgets/toolbox.cpp:439 +msgid "Break path at selected nodes" +msgstr "Quebrar camiho nos nós selecionados" + +#: ../../po/../src/widgets/toolbox.cpp:444 +msgid "Make selected nodes corner" +msgstr "Tornar nós selecionados em um canto" + +#: ../../po/../src/widgets/toolbox.cpp:447 +msgid "Make selected nodes smooth" +msgstr "Suavizar nós selecionados" + +#: ../../po/../src/widgets/toolbox.cpp:450 +msgid "Make selected nodes symmetric" +msgstr "Tornar nós selecionados simétricos" + +#: ../../po/../src/widgets/toolbox.cpp:455 +msgid "Make selected segments lines" +msgstr "Converter segmentos selecionados em linhas" + +#: ../../po/../src/widgets/toolbox.cpp:458 +msgid "Make selected segments curves" +msgstr "Converter segmentos selecionados em curvas" + +#: ../../po/../src/widgets/toolbox.cpp:1199 +msgid "Polygon" +msgstr "Polígono" + +#: ../../po/../src/widgets/toolbox.cpp:1206 +msgid "Regular polygon (with one handle) instead of a star" +msgstr "Polígono regular (com uma alça) ao invés de uma estrela" + +#: ../../po/../src/widgets/toolbox.cpp:1218 +msgid "Corners:" +msgstr "Cantos:" + +#: ../../po/../src/widgets/toolbox.cpp:1218 +msgid "Number of corners of a polygon or star" +msgstr "Número de cantos de um polígono ou estrela" + +#: ../../po/../src/widgets/toolbox.cpp:1228 +msgid "Spoke ratio:" +msgstr "Proporção do raio:" + +#. TRANSLATORS: Tip radius of a star is the distance from the center to the farthest handle. +#. Base radius is the same for the closest handle. +#: ../../po/../src/widgets/toolbox.cpp:1231 +msgid "Base radius to tip radius ratio" +msgstr "Proporção do raio base para o raio externo" + +#: ../../po/../src/widgets/toolbox.cpp:1246 +#, fuzzy +msgid "Rounded:" +msgstr "Arredondamento:" + +#: ../../po/../src/widgets/toolbox.cpp:1246 +msgid "How much rounded are the corners (0 for sharp)" +msgstr "Quão redondos são os cantos (0 para agudo)" + +#: ../../po/../src/widgets/toolbox.cpp:1256 +#, fuzzy +msgid "Randomized:" +msgstr "Aleatorização:" + +#: ../../po/../src/widgets/toolbox.cpp:1256 +msgid "Scatter randomly the corners and angles" +msgstr "Difunde aleatoriamente os cantos e ângulos" + +#: ../../po/../src/widgets/toolbox.cpp:1269 +#: ../../po/../src/widgets/toolbox.cpp:1838 +#: ../../po/../src/widgets/toolbox.cpp:2061 +msgid "Defaults" +msgstr "Padrões" + +#: ../../po/../src/widgets/toolbox.cpp:1270 +#: ../../po/../src/widgets/toolbox.cpp:1839 +#: ../../po/../src/widgets/toolbox.cpp:2062 +msgid "" +"Reset shape parameters to defaults (use Inkscape Preferences > Tools to " +"change defaults)" +msgstr "" +"Reiniciar parâmetros da forma para padrões (use Inkscape Configurações > " +"Ferrametas para mudar os padrões)" + +#: ../../po/../src/widgets/toolbox.cpp:1544 +msgid "W:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1544 +#, fuzzy +msgid "Width of rectangle" +msgstr "Largura da seleção" + +#: ../../po/../src/widgets/toolbox.cpp:1556 +#, fuzzy +msgid "Height of rectangle" +msgstr "Altura da seleção" + +#: ../../po/../src/widgets/toolbox.cpp:1568 +msgid "Rx:" +msgstr "Rx:" + +#: ../../po/../src/widgets/toolbox.cpp:1568 +msgid "Horizontal radius of rounded corners" +msgstr "Raio horizontal de cantos arredondados" + +#: ../../po/../src/widgets/toolbox.cpp:1578 +msgid "Ry:" +msgstr "Ry:" + +#: ../../po/../src/widgets/toolbox.cpp:1578 +msgid "Vertical radius of rounded corners" +msgstr "Raio vertical de cantos arredondados" + +#: ../../po/../src/widgets/toolbox.cpp:1594 +msgid "Not rounded" +msgstr "Não arredondado" + +#: ../../po/../src/widgets/toolbox.cpp:1596 +msgid "Make corners sharp" +msgstr "Tornar cantos agudos" + +#: ../../po/../src/widgets/toolbox.cpp:1805 +msgid "Turns:" +msgstr "Rotação:" + +#: ../../po/../src/widgets/toolbox.cpp:1805 +msgid "Number of revolutions" +msgstr "Número de revoluções" + +#: ../../po/../src/widgets/toolbox.cpp:1815 +msgid "Divergence:" +msgstr "Divergência:" + +#: ../../po/../src/widgets/toolbox.cpp:1815 +msgid "How much denser/sparser are outer revolutions; 1 = uniform" +msgstr "Quão densas/esparsas são revoluções externas; 1 = uniforme" + +#: ../../po/../src/widgets/toolbox.cpp:1825 +msgid "Inner radius:" +msgstr "Raio interno:" + +#: ../../po/../src/widgets/toolbox.cpp:1825 +msgid "Radius of the innermost revolution (relative to the spiral size)" +msgstr "Raio da revolução mais interna (relativo ao tamanho da espiral)" + +#: ../../po/../src/widgets/toolbox.cpp:1957 +#, fuzzy +msgid "The width of the calligraphic pen (relative to the visible canvas area)" +msgstr "A largura da caneta caligráfica" + +#: ../../po/../src/widgets/toolbox.cpp:1967 +#, fuzzy +msgid "Thinning:" +msgstr "sinuoso" + +#: ../../po/../src/widgets/toolbox.cpp:1967 +msgid "" +"How much velocity thins the stroke (> 0 makes fast strokes thinner, < 0 " +"makes them broader, 0 makes width independent of velocity)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1980 +msgid "Angle:" +msgstr "Ângulo:" + +#: ../../po/../src/widgets/toolbox.cpp:1980 +msgid "" +"The angle of the pen's nib (in degrees; 0 = horizontal; has no effect if " +"fixation = 0)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1990 +#, fuzzy +msgid "Fixation:" +msgstr "Expansão:" + +#: ../../po/../src/widgets/toolbox.cpp:1990 +msgid "" +"How fixed is the pen angle (0 = always perpendicular to stroke direction, 1 " +"= fixed)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2003 +msgid "Mass:" +msgstr "Massa:" + +#: ../../po/../src/widgets/toolbox.cpp:2003 +msgid "How much inertia affects the movement of the pen" +msgstr "Quanto a inércia afeta o movimento da caneta" + +#. TRANSLATORS: "drag" means "resistance" here +#: ../../po/../src/widgets/toolbox.cpp:2014 +msgid "Drag:" +msgstr "Arrasto:" + +#: ../../po/../src/widgets/toolbox.cpp:2014 +msgid "How much resistance affects the movement of the pen" +msgstr "Quanto a resistência afeta o movimento da caneta" + +#: ../../po/../src/widgets/toolbox.cpp:2034 +msgid "Use the pressure of the input device to alter the width of the pen" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2047 +msgid "Use the tilt of the input device to alter the angle of the pen's nib" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2374 +msgid "Start:" +msgstr "Início:" + +#: ../../po/../src/widgets/toolbox.cpp:2374 +msgid "The angle (in degrees) from the horizontal to the arc's start point" +msgstr "O ângulo (em graus) do do horizontal para o ponto inicial do arco." + +#: ../../po/../src/widgets/toolbox.cpp:2384 +msgid "End:" +msgstr "Fim:" + +#: ../../po/../src/widgets/toolbox.cpp:2384 +msgid "The angle (in degrees) from the horizontal to the arc's end point" +msgstr "O ângulo (em graus) do do horizontal para o ponto final do arco." + +#: ../../po/../src/widgets/toolbox.cpp:2395 +msgid "Open arc" +msgstr "Abrir arco" + +#: ../../po/../src/widgets/toolbox.cpp:2396 +msgid "" +"Switch between arc (unclosed shape) and segment (closed shape with two radii)" +msgstr "" +"Trocar entre arco (forma não fechada) e segmento (forma fechada com dois " +"raios)" + +#: ../../po/../src/widgets/toolbox.cpp:2415 +msgid "Make whole" +msgstr "Tornar inteiro" + +#: ../../po/../src/widgets/toolbox.cpp:2417 +msgid "Make the shape a whole ellipse, not arc or segment" +msgstr "Tornar a forma uma elipse inteira e não um arco ou segmento" + +#: ../../po/../src/widgets/toolbox.cpp:2644 +msgid "" +"When pressed, picks visible color without alpha and when not pressed, picks " +"color including its alpha" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:3039 +#, fuzzy +msgid "Make connectors avoid selected objects" +msgstr "Intersecção dos objetos selecionados" + +#: ../../po/../src/widgets/toolbox.cpp:3043 +#, fuzzy +msgid "Make connectors ignore selected objects" +msgstr "Intersecção dos objetos selecionados" + +#. +#. 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 : +#: ../share/extensions/addnodes.inx.h:1 +#, fuzzy +msgid "Add Nodes" +msgstr "Nó" + +#: ../share/extensions/addnodes.inx.h:2 +msgid "Maximum Segment Length" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:1 +msgid "AI Input" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:2 ../share/extensions/ai_output.inx.h:2 +msgid "Adobe Illustrator (*.ai)" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:3 +msgid "Open files saved with Adobe Illustrator" +msgstr "" + +#: ../share/extensions/ai_output.inx.h:1 +#, fuzzy +msgid "AI Output" +msgstr "Ava_nçar" + +#: ../share/extensions/ai_output.inx.h:3 +#, fuzzy +msgid "Write Adobe Illustrator" +msgstr "Ilustrador Vetorial em SVG" + +#: ../share/extensions/dia.inx.h:1 +msgid "A diagram created with the program Dia" +msgstr "" + +#: ../share/extensions/dia.inx.h:2 +msgid "Dia Diagram (*.dia)" +msgstr "" + +#: ../share/extensions/dia.inx.h:3 +msgid "Dia Input" +msgstr "" + +#: ../share/extensions/dia.inx.h:4 +msgid "" +"In order to import Dia files, Dia itself must be installed. You can get Dia " +"at http://www.gnome.org/projects/dia/" +msgstr "" + +#: ../share/extensions/dia.inx.h:5 +msgid "" +"The dia2svg.sh script should be installed with your Inkscape distribution. " +"If you do not have it, there is likely to be something wrong with your " +"Inkscape installation." +msgstr "" + +#: ../share/extensions/dots.inx.h:1 +#, fuzzy +msgid "Connect the Dots" +msgstr "Cantos:" + +#: ../share/extensions/dots.inx.h:2 +#, fuzzy +msgid "Dot Size" +msgstr "Lados:" + +#: ../share/extensions/dots.inx.h:3 +#, fuzzy +msgid "Font Size" +msgstr "Tamanho da Fonte" + +#: ../share/extensions/dropshadow.inx.h:1 +msgid "Color of shadow" +msgstr "" + +#: ../share/extensions/dropshadow.inx.h:2 +msgid "Dropshadow" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:1 +#: ../share/extensions/dxf_output.inx.h:1 +msgid "AutoCAD DXF (*.dxf)" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:2 +msgid "DXF Input" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:3 +msgid "Import AutoCAD's Document Exchange Format" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:4 +msgid "" +"dxf2svg may come with Inkscape, but is also at http://dxf-svg-convert." +"sourceforge.net/" +msgstr "" + +#: ../share/extensions/dxf_output.inx.h:2 +#, fuzzy +msgid "DXF Output" +msgstr "Ava_nçar" + +#: ../share/extensions/dxf_output.inx.h:3 +msgid "DXF file written by pstoedit" +msgstr "" + +#: ../share/extensions/dxf_output.inx.h:4 +msgid "pstoedit must be installed to run see http://www.pstoedit.net/pstoedit" +msgstr "" + +#: ../share/extensions/embedimage.inx.h:1 +#, fuzzy +msgid "Embed Images" +msgstr "Imagens" + +#: ../share/extensions/eps_input.inx.h:1 +msgid "EPS Input" +msgstr "" + +#: ../share/extensions/eps_input.inx.h:2 +msgid "Encapsulated Postscript" +msgstr "" + +#: ../share/extensions/eps_input.inx.h:3 +msgid "Encapsulated Postscript (*.eps)" +msgstr "" + +#: ../share/extensions/epsi_output.inx.h:1 +#, fuzzy +msgid "EPSI Output" +msgstr "Ava_nçar" + +#: ../share/extensions/epsi_output.inx.h:2 +msgid "Encapsulated Postscript Interchange (*.epsi)" +msgstr "" + +#: ../share/extensions/epsi_output.inx.h:3 +msgid "Encapsulated Postscript with a thumbnail" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:1 ../share/extensions/ffms.inx.h:1 +#: ../share/extensions/ffset.inx.h:1 ../share/extensions/ffss.inx.h:1 +#, fuzzy +msgid "Bridge Width" +msgstr "_Largura da Página" + +#: ../share/extensions/ffmet.inx.h:2 ../share/extensions/ffms.inx.h:2 +msgid "First String Length" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:3 +msgid "FretFind Multi Length ET" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:4 ../share/extensions/ffms.inx.h:4 +#: ../share/extensions/ffset.inx.h:3 ../share/extensions/ffss.inx.h:3 +msgid "Fretboard Edges" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:5 ../share/extensions/ffms.inx.h:5 +msgid "Last String Length" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:6 ../share/extensions/ffms.inx.h:6 +#: ../share/extensions/ffset.inx.h:4 ../share/extensions/ffss.inx.h:4 +#, fuzzy +msgid "Number of Frets" +msgstr "Número de revoluções" + +#: ../share/extensions/ffmet.inx.h:7 ../share/extensions/ffms.inx.h:7 +#: ../share/extensions/ffset.inx.h:5 ../share/extensions/ffss.inx.h:5 +#, fuzzy +msgid "Number of Strings" +msgstr "Número de revoluções" + +#: ../share/extensions/ffmet.inx.h:8 ../share/extensions/ffms.inx.h:8 +#: ../share/extensions/ffset.inx.h:6 ../share/extensions/ffss.inx.h:6 +#, fuzzy +msgid "Nut Width" +msgstr "Largura:" + +#: ../share/extensions/ffmet.inx.h:9 ../share/extensions/ffms.inx.h:10 +msgid "Perpendicular Distance" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:10 ../share/extensions/ffset.inx.h:7 +msgid "Scale Base (2 for Octave)" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:11 ../share/extensions/ffset.inx.h:9 +msgid "Tones in Scale" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:12 ../share/extensions/ffms.inx.h:12 +#: ../share/extensions/ffset.inx.h:10 ../share/extensions/ffss.inx.h:10 +msgid "px per Unit" +msgstr "" + +#: ../share/extensions/ffms.inx.h:3 +msgid "FretFind Multi Length Scala" +msgstr "" + +#: ../share/extensions/ffms.inx.h:9 ../share/extensions/ffss.inx.h:7 +msgid "Path to Scala *.scl File" +msgstr "" + +#: ../share/extensions/ffms.inx.h:11 +msgid "Tuning (scale step for each string seperated by semicolons)" +msgstr "" + +#: ../share/extensions/ffset.inx.h:2 +msgid "FretFind Single Length ET" +msgstr "" + +#: ../share/extensions/ffset.inx.h:8 ../share/extensions/ffss.inx.h:8 +msgid "Scale Length" +msgstr "" + +#: ../share/extensions/ffss.inx.h:2 +msgid "FretFind Single Length Scala" +msgstr "" + +#: ../share/extensions/ffss.inx.h:9 +msgid "Tuning (Scale step for each string seperated by semicolons)" +msgstr "" + +#: ../share/extensions/handles.inx.h:1 +#, fuzzy +msgid "Draw Handles" +msgstr "Desenhar linhas a mão-livre" + +#: ../share/extensions/interp.inx.h:1 +#, fuzzy +msgid "Duplicate Endpaths" +msgstr "Duplicar nó" + +#: ../share/extensions/interp.inx.h:2 +#, fuzzy +msgid "Exponent" +msgstr "Exportar" + +#: ../share/extensions/interp.inx.h:3 +msgid "Interpolate" +msgstr "" + +#: ../share/extensions/interp.inx.h:4 +msgid "Interpolate Style (Experimental)" +msgstr "" + +#: ../share/extensions/interp.inx.h:5 +msgid "Interpolation Method" +msgstr "" + +#: ../share/extensions/interp.inx.h:6 +msgid "Interpolation Steps" +msgstr "" + +#: ../share/extensions/kochify.inx.h:1 +msgid "Kochify" +msgstr "" + +#: ../share/extensions/kochify_load.inx.h:1 +msgid "Kochify (Load)" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:1 +#, fuzzy +msgid "Angle" +msgstr "Ângulo:" + +#: ../share/extensions/lindenmayer.inx.h:2 +msgid "Axiom" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:3 +#, fuzzy +msgid "Lindenmayer" +msgstr "Levantar Camada" + +#: ../share/extensions/lindenmayer.inx.h:4 +msgid "Order" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:5 +#, fuzzy +msgid "Rules" +msgstr "_Réguas" + +#: ../share/extensions/lindenmayer.inx.h:6 +#, fuzzy +msgid "Step" +msgstr "Passos" + +#: ../share/extensions/motion.inx.h:1 +#, fuzzy +msgid "Direction" +msgstr "Descrição" + +#: ../share/extensions/motion.inx.h:2 +#, fuzzy +msgid "Magnitude" +msgstr "Magenta" + +#: ../share/extensions/motion.inx.h:3 +#, fuzzy +msgid "Motion" +msgstr "Relação" + +#: ../share/extensions/pdf_output.inx.h:1 +msgid "Adobe PDF (*.pdf)" +msgstr "" + +#: ../share/extensions/pdf_output.inx.h:2 +msgid "Adobe Portable Document Format" +msgstr "" + +#: ../share/extensions/pdf_output.inx.h:3 +#, fuzzy +msgid "PDF Output" +msgstr "Ava_nçar" + +#: ../share/extensions/ps_input.inx.h:1 +#, fuzzy +msgid "Postscript" +msgstr "Retrato" + +#: ../share/extensions/ps_input.inx.h:2 +msgid "Postscript (*.ps)" +msgstr "" + +#: ../share/extensions/ps_input.inx.h:3 +msgid "Postscript Input" +msgstr "" + +#: ../share/extensions/radiusrand.inx.h:1 +#, fuzzy +msgid "Radius" +msgstr "Raios:" + +#: ../share/extensions/radiusrand.inx.h:2 +#, fuzzy +msgid "Radius Randomize" +msgstr "Aleatorização:" + +#: ../share/extensions/radiusrand.inx.h:3 +msgid "Randomize Control Points" +msgstr "" + +#: ../share/extensions/radiusrand.inx.h:4 +#, fuzzy +msgid "Randomize Nodes" +msgstr "Aleatorização:" + +#: ../share/extensions/rtree.inx.h:1 +#, fuzzy +msgid "Initial Size" +msgstr "Tamanho da figura" + +#: ../share/extensions/rtree.inx.h:2 +msgid "Minimum Size" +msgstr "" + +#: ../share/extensions/rtree.inx.h:3 +#, fuzzy +msgid "Random Tree" +msgstr "Aleatorização:" + +#: ../share/extensions/sk_input.inx.h:1 +msgid "A diagram created with the program Sketch" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:2 +msgid "Sketch Diagram (*.sk)" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:3 +msgid "Sketch Input" +msgstr "" + +#: ../share/extensions/straightseg.inx.h:1 +msgid "Behavior" +msgstr "" + +#: ../share/extensions/straightseg.inx.h:3 +msgid "Segment Straightener" +msgstr "" + +#: ../share/extensions/summersnight.inx.h:1 +msgid "Summer's Night" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:1 +#: ../share/extensions/svgz_output.inx.h:1 +#, fuzzy +msgid "Compressed Inkscape SVG (*.svgz)" +msgstr "Arquivos SVG compactados" + +#: ../share/extensions/svgz_input.inx.h:2 +#: ../share/extensions/svgz_output.inx.h:2 +msgid "Inkscape's native file format compressed with GZip" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:3 +msgid "SVGZ Input" +msgstr "" + +#: ../share/extensions/svgz_output.inx.h:3 +#, fuzzy +msgid "SVGZ Output" +msgstr "Ava_nçar" + +#: ../share/extensions/txt2svg.inx.h:1 +msgid "ASCII Text" +msgstr "" + +#: ../share/extensions/txt2svg.inx.h:2 +msgid "Text File (*.txt)" +msgstr "" + +#: ../share/extensions/txt2svg.inx.h:3 +#, fuzzy +msgid "Text Input" +msgstr "Pró_xima Ampliação" + +#: ../share/extensions/wavy.inx.h:1 +msgid "Calculate first derivative numerically" +msgstr "" + +#: ../share/extensions/wavy.inx.h:2 +msgid "First derivative" +msgstr "" + +#: ../share/extensions/wavy.inx.h:3 +msgid "Function" +msgstr "" + +#: ../share/extensions/wavy.inx.h:4 +msgid "Function Plotter" +msgstr "" + +#: ../share/extensions/wavy.inx.h:5 +msgid "Nodes per period" +msgstr "" + +#: ../share/extensions/wavy.inx.h:6 +msgid "Periods (2*Pi each)" +msgstr "" + +#: ../share/extensions/whirl.inx.h:1 +msgid "Amount of Whirl" +msgstr "" + +#: ../share/extensions/whirl.inx.h:2 +#, fuzzy +msgid "Center X" +msgstr "Centro X:" + +#: ../share/extensions/whirl.inx.h:3 +#, fuzzy +msgid "Center Y" +msgstr "Centro Y:" + +#: ../share/extensions/whirl.inx.h:4 +#, fuzzy +msgid "Direction of Rotation" +msgstr "Abaixa a seleção até ficar em baixo de todos os outros elementos" + +#: ../share/extensions/whirl.inx.h:5 +msgid "Whirl" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:1 +msgid "A popular graphics file format for clipart" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:2 +msgid "Windows Metafile (*.wmf)" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:3 +msgid "Windows Metafile Input" +msgstr "" + +#~ msgid "Custom canvas" +#~ msgstr "Tela personalizada" + +#~ msgid "Current style" +#~ msgstr "Estilo atual" + +#~ msgid "" +#~ "Current style is updated every time you change the style of any object " +#~ "(its fill, stroke, transparency, etc.)" +#~ msgstr "" +#~ "O estilo atual é atualizado cada vez que você muda o estilo de qualquer " +#~ "objeto(seu preenchimento, traço, tranparência, etc.)" + +#, fuzzy +#~ msgid "Arrange Objects" +#~ msgstr "Objetos" + +#~ msgid "deg" +#~ msgstr "grau" + +#~ msgid "" +#~ "%s is not a valid preferences file.\n" +#~ "%s" +#~ msgstr "" +#~ "%s não é um arquivo de configurações válido.\n" +#~ "%s" + +#~ msgid "" +#~ "Inkscape will run with default settings.\n" +#~ "New settings will not be saved." +#~ msgstr "" +#~ "O Inkscape funcionará com as configurações padrão.\n" +#~ "Novas configurações não serão salvas." + +#, fuzzy +#~ msgid "_Credits" +#~ msgstr "Créditos" + +#, fuzzy +#~ msgid "Grab sensitivity" +#~ msgstr "Sensibilidade de agarrar:" + +#, fuzzy +#~ msgid "Click/drag threshold" +#~ msgstr "Limiar para clicar/arrastar:" + +#, fuzzy +#~ msgid "Mouse wheel scrolls by" +#~ msgstr "A roda do mouse rola em:" + +#, fuzzy +#~ msgid "Scroll by" +#~ msgstr "Rolar em:" + +#, fuzzy +#~ msgid "Acceleration" +#~ msgstr "Aceleração:" + +#, fuzzy +#~ msgid "Speed" +#~ msgstr "Velocidade:" + +#~ msgid "Threshold" +#~ msgstr "Limiar" + +#, fuzzy +#~ msgid "Arrow keys move by" +#~ msgstr "Setas movem por:" + +#, fuzzy +#~ msgid "> and < scale by" +#~ msgstr "> e < ampliam em:" + +#, fuzzy +#~ msgid "Inset/Outset by" +#~ msgstr "Avanço/Recuo em:" + +#, fuzzy +#~ msgid "Rotation snaps every" +#~ msgstr "Ajuste de giro a cada:" + +#, fuzzy +#~ msgid "Zoom in/out by" +#~ msgstr "Ampliar/Reduzir em:" + +#, fuzzy +#~ msgid "Transform" +#~ msgstr "Transformações" + +#~ msgid "Rotate _90 deg CW" +#~ msgstr "Girar +_90 graus " + +#~ msgid "Rotate 9_0 deg CCW" +#~ msgstr "Girar -9_0 graus" + +#~ msgid "Flip selection horizontally" +#~ msgstr "Inverter a posição da seleção horizontalmente" + +#~ msgid "Flip selection vertically" +#~ msgstr "Inverter a posição da seleção verticalmente" + +#, fuzzy +#~ msgid "Could not read next message due to I/O error (error: %s)!" +#~ msgstr "Não foi possível exportar para o arquivo %s.\n" + +#~ msgid "Open one of the recently visited documents" +#~ msgstr "Abrir um dos desenhos recentemente abertos" + +#~ msgid "" +#~ "Show or hide parts of the document window (differently for normal and " +#~ "fullscreen modes)" +#~ msgstr "" +#~ "Mostrar ou esconder partes de janelas de desenho (diferentemente para " +#~ "modos normal e tela cheia)" + +#~ msgid "Interactive Inkscape tutorials" +#~ msgstr "Tutorias interactivos do Inkscape" + +#~ msgid "Edit" +#~ msgstr "Alterar" + +#~ msgid "Add" +#~ msgstr "Acrescentar" + +#~ msgid "" +#~ "Select one path object with selector first, then switch back to node tool." +#~ msgstr "" +#~ "Selecione primeiro um objeto de caminho com o seletor e então volte à " +#~ "ferramenta de nó." + +#, fuzzy +#~ msgid "C_reate" +#~ msgstr "Criar" + +#, fuzzy +#~ msgid "Automatically scale Rows to fit selected objects." +#~ msgstr "Ou exclusivo dos objetos selecionados" + +#, fuzzy +#~ msgid "Go to root" +#~ msgstr "Alterar raiz" + +#, fuzzy +#~ msgid "X" +#~ msgstr "X:" + +#, fuzzy +#~ msgid "Y" +#~ msgstr "_Y" + +#~ msgid "Unicode: %c%c%c%c" +#~ msgstr "Unicode: %c%c%c%c" + +#~ msgid "Sides:" +#~ msgstr "Lados:" + +#~ msgid "R1:" +#~ msgstr "R1:" + +#~ msgid "R2:" +#~ msgstr "R2:" + +#~ msgid "ARG1:" +#~ msgstr "ARG1:" + +#~ msgid "ARG2:" +#~ msgstr "ARG2:" + +#~ msgid "Flatsides:" +#~ msgstr "Lados lisos:" + +#, fuzzy +#~ msgid "Radius X:" +#~ msgstr "Raios:" + +#, fuzzy +#~ msgid "Radius Y:" +#~ msgstr "Raios:" + +#, fuzzy +#~ msgid "Start Angle:" +#~ msgstr "Início:" + +#, fuzzy +#~ msgid "End Angle:" +#~ msgstr "Ângulo:" + +#, fuzzy +#~ msgid "Open:" +#~ msgstr "Abrir arco" + +#~ msgid "Expansion:" +#~ msgstr "Expansão:" + +#~ msgid "Revolutions:" +#~ msgstr "Revoluções:" + +#~ msgid "Argument:" +#~ msgstr "Argumento:" + +#~ msgid "T0:" +#~ msgstr "TO:" + +#~ msgid "RX:" +#~ msgstr "RX:" + +#~ msgid "RY:" +#~ msgstr "RY:" + +#~ msgid "Rectangle _Properties" +#~ msgstr "_Propriedades do Retângulo" + +#~ msgid "Star _Properties" +#~ msgstr "_Propriedades da Estrela" + +#, fuzzy +#~ msgid "Ellipse _Properties" +#~ msgstr "Ligar _Propriedades" + +#~ msgid "Spiral _Properties" +#~ msgstr "_Propriedades da Espiral" + +#, fuzzy +#~ msgid "Document Preferences" +#~ msgstr "Configurações do _Desenho" + +#, fuzzy +#~ msgid "Extensions Editor" +#~ msgstr "Expansão:" + +#, fuzzy +#~ msgid "Preferences" +#~ msgstr "Propriedades da Caneta" + +#, fuzzy +#~ msgid "Layer Editor" +#~ msgstr "Janela do Editor XML" + +#, fuzzy +#~ msgid "Text Properties" +#~ msgstr "Propriedades do _Objeto" + +#, fuzzy +#~ msgid "Transformation" +#~ msgstr "Matriz de transformação" + +#, fuzzy +#~ msgid "_Export..." +#~ msgstr "_Importar..." + +#, fuzzy +#~ msgid "_Document Properties" +#~ msgstr "Desenho revertido." + +#, fuzzy +#~ msgid "In_kscape Preferences" +#~ msgstr "Configurações do In_kscape" + +#, fuzzy +#~ msgid "Select _Original Clone" +#~ msgstr "Selecionar _Original" + +#, fuzzy +#~ msgid "Tile" +#~ msgstr "Título" + +#, fuzzy +#~ msgid "Select A_ll" +#~ msgstr "Se_lecionar Todos" + +#, fuzzy +#~ msgid "Select Non_e" +#~ msgstr "Seleção" + +#, fuzzy +#~ msgid "Zoom _In" +#~ msgstr "Ampliar" + +#, fuzzy +#~ msgid "Zoom _Out" +#~ msgstr "Reduzir" + +#, fuzzy +#~ msgid "Pre_vious" +#~ msgstr "Amp_liação Anterior" + +#, fuzzy +#~ msgid "Nex_t" +#~ msgstr "Pró_xima Ampliação" + +#, fuzzy +#~ msgid "_Commands bar" +#~ msgstr "Barra de Comandos" + +#, fuzzy +#~ msgid "Tool Co_ntrols bar" +#~ msgstr "_Controles de Ferramenta" + +#, fuzzy +#~ msgid "_Tools bar" +#~ msgstr "Caixa de _Ferramentas" + +#, fuzzy +#~ msgid "R_ename Layer..." +#~ msgstr "Levantar Camada" + +#, fuzzy +#~ msgid "D_uplicate Layer" +#~ msgstr "Duplicar nó" + +#, fuzzy +#~ msgid "_Anchor Layer" +#~ msgstr "Abaixar Camada" + +#, fuzzy +#~ msgid "_Delete Layer" +#~ msgstr "Nó apagado." + +#, fuzzy +#~ msgid "Select Ne_xt Layer" +#~ msgstr "Mudado para a próxima camada." + +#, fuzzy +#~ msgid "Select Pre_vious Layer" +#~ msgstr "Pula para a camada anterior." + +#, fuzzy +#~ msgid "Select To_p Layer" +#~ msgstr "Selecionar impressora" + +#, fuzzy +#~ msgid "Move to Ne_w Layer" +#~ msgstr "Mover para a Próxima Camada" + +#, fuzzy +#~ msgid "Move to Ne_xt Layer" +#~ msgstr "Mover para a Próxima Camada" + +#, fuzzy +#~ msgid "Move to Pre_vious Layer" +#~ msgstr "Mover para a Camada Anterior" + +#, fuzzy +#~ msgid "Move to To_p Layer" +#~ msgstr "Mover para a Próxima Camada" + +#, fuzzy +#~ msgid "Move to B_ottom Layer" +#~ msgstr "Mover para a Próxima Camada" + +#, fuzzy +#~ msgid "_Trace Bitmap..." +#~ msgstr "_Traçar figura" + +#, fuzzy +#~ msgid "_Put Text on Path" +#~ msgstr "Por texto no caminho" + +#, fuzzy +#~ msgid "_Remove Text from Path" +#~ msgstr "Remover texto do caminho" + +#, fuzzy +#~ msgid "Freehand" +#~ msgstr "Finalizando mão-livre" + +#, fuzzy +#~ msgid "Corners" +#~ msgstr "Cantos:" + +#, fuzzy +#~ msgid "Delete" +#~ msgstr "Apa_gar" + +#, fuzzy +#~ msgid "Join" +#~ msgstr "Juntar:" + +#, fuzzy +#~ msgid "Delete Segment" +#~ msgstr "Apaga a seleção" + +#, fuzzy +#~ msgid "Break" +#~ msgstr "Preto" + +#, fuzzy +#~ msgid "Symmetric" +#~ msgstr "simétrico" + +#, fuzzy +#~ msgid "Line" +#~ msgstr "Licensa" + +#, fuzzy +#~ msgid "New" +#~ msgstr "_Novo" + +#, fuzzy +#~ msgid "Save" +#~ msgstr "Salvar" + +#, fuzzy +#~ msgid "Save As..." +#~ msgstr "Salvar _Como..." + +#, fuzzy +#~ msgid "Import..." +#~ msgstr "_Importar..." + +#, fuzzy +#~ msgid "Export..." +#~ msgstr "Exportar" + +#, fuzzy +#~ msgid "Print..." +#~ msgstr "Im_primir..." + +#, fuzzy +#~ msgid "Global Inkscape preferences (Shift+Ctrl+P)" +#~ msgstr "Configurações Globais do In_kscape" + +#, fuzzy +#~ msgid "Undo" +#~ msgstr "_Desfazer" + +#, fuzzy +#~ msgid "Redo" +#~ msgstr "_Refazer" + +#, fuzzy +#~ msgid "Cut" +#~ msgstr "Cor_tar" + +#, fuzzy +#~ msgid "Copy" +#~ msgstr "_Copiar" + +#, fuzzy +#~ msgid "Duplicate selected object(s) (Ctrl+D)" +#~ msgstr "Duplica os objetos selecionados" + +#, fuzzy +#~ msgid "Clone selected object (Alt+D)" +#~ msgstr "Duplica os objetos selecionados" + +#, fuzzy +#~ msgid "Zoom in (+)" +#~ msgstr "Ampliar" + +#, fuzzy +#~ msgid "Zoom out (-)" +#~ msgstr "Reduzir" + +#, fuzzy +#~ msgid "Zoom to 1:1 (100%) (1)" +#~ msgstr "Mostra do tamanho original do desenho" + +#, fuzzy +#~ msgid "Zoom to 1:2 (50%) (2)" +#~ msgstr "Mostra no dobro do tamanho do desenho" + +#, fuzzy +#~ msgid "Zoom to 2:1 (200%) (0)" +#~ msgstr "Mostra na metade do tamanho do desenho" + +#, fuzzy +#~ msgid "Zoom to fit selection in window (3)" +#~ msgstr "Ampliar para caber a seleção na janela" + +#, fuzzy +#~ msgid "Zoom to fit drawing in window (4)" +#~ msgstr "Ampliar para caber o desenho na janela" + +#, fuzzy +#~ msgid "Zoom to fit page in window (5)" +#~ msgstr "Ampliar para caber a página na janela" + +#, fuzzy +#~ msgid "Zoom to fit page width in window (6)" +#~ msgstr "Ampliar para caber a largura da página na janela" + +#, fuzzy +#~ msgid "Previous zoom (from history of zooms) (`)" +#~ msgstr "Ampliação Anterior (da lista de ampliações utilizadas)" + +#, fuzzy +#~ msgid "Next zoom (from history of zooms) (Shift+`)" +#~ msgstr "Próxima ampliação (da lista de ampliações utilizadas)" + +#, fuzzy +#~ msgid "Fill and Stroke dialog (Shift+Ctrl+F)" +#~ msgstr "Janela de Preenchimento e Traço" + +#, fuzzy +#~ msgid "Group selected objects (Ctrl+G)" +#~ msgstr "Agrupa os objetos selecionados" + +#, fuzzy +#~ msgid "Ungroup selected group(s) (Ctrl+U)" +#~ msgstr "Desagrupa os grupos selecionados" + +#, fuzzy +#~ msgid "Raise selection up one step (PgUp)" +#~ msgstr "Levanta a seleção um passo" + +#, fuzzy +#~ msgid "Lower selection down one step (PgDn)" +#~ msgstr "Abaixa a seleção um passo" + +#, fuzzy +#~ msgid "Raise selection to top (Home)" +#~ msgstr "Levanta a seleção para o topo" + +#, fuzzy +#~ msgid "Lower selection to bottom (End)" +#~ msgstr "Abaixa a seleção até ficar em baixo de todos os outros elementos" + +#, fuzzy +#~ msgid "Move selection to new layer" +#~ msgstr "Abaixa a seleção um passo" + +#, fuzzy +#~ msgid "Move selection to next layer" +#~ msgstr "Mover para a Próxima Camada" + +#, fuzzy +#~ msgid "Move selection to previous layer" +#~ msgstr "Mover para a Camada Anterior" + +#, fuzzy +#~ msgid "Move selection to top layer" +#~ msgstr "Levanta a seleção para o topo" + +#, fuzzy +#~ msgid "Move selection to bottom layer" +#~ msgstr "Abaixa a seleção até ficar em baixo de todos os outros elementos" + +#, fuzzy +#~ msgid "Rotate selection 90° clockwise (Shift+Ctrl+Right)" +#~ msgstr "Girar a seleção 90 graus no sentido hórario" + +#, fuzzy +#~ msgid "Rotate selection 90° counter-clockwise (Shift+Ctrl+Left)" +#~ msgstr "Girar a seleção 90 graus no sentido anti-horário" + +#, fuzzy +#~ msgid "Flip selection horizontally (H)" +#~ msgstr "Inverter a posição da seleção horizontalmente" + +#, fuzzy +#~ msgid "Flip selection vertically (V)" +#~ msgstr "Inverter a posição da seleção verticalmente" + +#, fuzzy +#~ msgid "Align and Distribute dialog (Shift+Ctrl+A)" +#~ msgstr "Janela de alinhar e distribuir" + +#, fuzzy +#~ msgid "Convert selected object(s) to path(s) (Shift+Ctrl+C)" +#~ msgstr "Converte os objetos selecionados em caminhos" + +#, fuzzy +#~ msgid "Convert selected stroke(s) to path(s) (Ctrl+Alt+C)" +#~ msgstr "Converte os traços selecionados em caminhos" + +#~ msgid "Cl_eanup" +#~ msgstr "Limp_esa" + +#, fuzzy +#~ msgid "Text and Font dialog (Shift+Ctrl+T)" +#~ msgstr "Janela de Texto e Fonte" + +#, fuzzy +#~ msgid "Node tool" +#~ msgstr "Alterar Nó" + +#, fuzzy +#~ msgid "Zoom tool" +#~ msgstr "Reduzir" + +#, fuzzy +#~ msgid "Rectangle tool" +#~ msgstr "Retângulo" + +#, fuzzy +#~ msgid "Arc tool" +#~ msgstr "Arqui-cargo" + +#, fuzzy +#~ msgid "Star tool" +#~ msgstr "Início:" + +#, fuzzy +#~ msgid "Spiral tool" +#~ msgstr "Espiral" + +#, fuzzy +#~ msgid "Calligraphy tool" +#~ msgstr "Caligrafia" + +#, fuzzy +#~ msgid "Dropper tool" +#~ msgstr "Borrão" + +#, fuzzy +#~ msgid "When scaling objects, scale stroke width by same proportion" +#~ msgstr "Ao ampliar objetos, amplie a largura do traço pela mesma proporção" + +#, fuzzy +#~ msgid "When scaling rectangles, scale radii of rounded corners" +#~ msgstr "Ao ampliar retângulos, ampliar o raio dos cantos arredondados" + +#, fuzzy +#~ msgid "Transform gradients (in fill or stroke) along with objects" +#~ msgstr "" +#~ "Transformar gradientes (em preenchimento ou traço) junto com os objetos" + +#, fuzzy +#~ msgid "Transform patterns (in fill or stroke) along with objects" +#~ msgstr "" +#~ "Transformar padrões de preenchimento (em preenchimento ou traço)junto com " +#~ "os objetos" + +#, fuzzy +#~ msgid "Delete segment between two nodes" +#~ msgstr "Apagar nós selecionados" + +#, fuzzy +#~ msgid "URI:" +#~ msgstr "URL" + +#, fuzzy +#~ msgid "Select All in All Layers" +#~ msgstr "Selecionar camada" + +#, fuzzy +#~ msgid "Invert Selection" +#~ msgstr "Seleção" + +#~ msgid "Clean up selected path(s)" +#~ msgstr "Faz uma limpesa nos caminhos selecionados" + +#, fuzzy +#~ msgid "_Scripts..." +#~ msgstr "Im_primir..." + +#, fuzzy +#~ msgid "Align and Distribute" +#~ msgstr "_Alinhar e Distribuir..." + +#, fuzzy +#~ msgid "Align and Distribute Dialog" +#~ msgstr "Janela de alinhar e distribuir" + +#, fuzzy +#~ msgid "Export Dialog" +#~ msgstr "Exportar área" + +#, fuzzy +#~ msgid "Fill and Stroke Dialog" +#~ msgstr "Janela de Preenchimento e Traço" + +#, fuzzy +#~ msgid "Find Dialog" +#~ msgstr "Mostrar/Esconder _Janelas" + +#, fuzzy +#~ msgid "Inkscape Preferences" +#~ msgstr "Configurações do In_kscape" + +#, fuzzy +#~ msgid "Inkscape Preferences Dialog" +#~ msgstr "Configurações do In_kscape" + +#, fuzzy +#~ msgid "Layer Editor Dialog" +#~ msgstr "Camada no Topo" + +#, fuzzy +#~ msgid "Text Properties Dialog" +#~ msgstr "Janela de Propriedades do Objeto" + +#, fuzzy +#~ msgid "Transformation Dialog" +#~ msgstr "Janela de Transformação" + +#, fuzzy +#~ msgid "Tree Editor" +#~ msgstr "Janela do Editor XML" + +#, fuzzy +#~ msgid "XML Editor Dialog" +#~ msgstr "Janela do Editor XML" + +#, fuzzy +#~ msgid "Row height:" +#~ msgstr "Altura:" + +#, fuzzy +#~ msgid "Column width:" +#~ msgstr "Círculo" + +#~ msgid "Creating anchor at (%g,%g)" +#~ msgstr "Criando âncora em (%g,%g)" + +#~ msgid "" +#~ "Click to pick fill color, Shift+click to pick stroke color. " +#~ "Drag to pick the average color of an area." +#~ msgstr "" +#~ "Clique para escolher a cor de preenchimento. Shift+Clique " +#~ "para escolher a cor de traço. Arraste para escolher a cor média de " +#~ "uma área." + +#~ msgid "EPS Output Settings" +#~ msgstr "Configurações de exportação de EPS" + +#~ msgid "Make bounding box around full page" +#~ msgstr "Fazer caixa de limites ao redor de uma página inteira" + +#~ msgid "" +#~ "Skew selection; with Shift to skew around the opposite side" +#~ msgstr "" +#~ "Inclinar a seleção; com Shift para inclinar ao redor do " +#~ "lado oposto" + +#~ msgid "Skew: %0.2f%% x %0.2f%%" +#~ msgstr "Inclinar: %0.2f%% x %0.2f%%" + +#~ msgid "elementsofdesign.svg" +#~ msgstr "elementsofdesign.svg" + +#~ msgid "tipsandtricks.svg" +#~ msgstr "tipsandtricks.svg" + +#, fuzzy +#~ msgid "Inkscape" +#~ msgstr "SVG do Inkscape" + +#~ msgid "Left side of aligned objects to left side of anchor" +#~ msgstr "Lado esquerdo dos objetos alinhados para o lado esquerdo da âncora" + +#~ msgid "Right side of aligned objects to right side of anchor" +#~ msgstr "Lado direito dos objetos alinhados para o lado direito da âncora" + +#~ msgid "Top of aligned objects to top of anchor" +#~ msgstr "Topo dos objetos alinhados para o topo da âncora" + +#~ msgid "Bottom of aligned objects to bottom of anchor" +#~ msgstr "Lado inferior dos objetos alinhados para o lado inferior da âncora" + +#~ msgid "Distribute top sides of objects at even distances" +#~ msgstr "Distribuir o lado superior dos objetos à mesma distância" + +#, fuzzy +#~ msgid "Alternate sign" +#~ msgstr "alternado" + +#, fuzzy +#~ msgid "Rows:" +#~ msgstr "Novo:" + +#~ msgid "Minor grid line color:" +#~ msgstr "Cor da linha de grade menor:" + +#~ msgid "Grid color" +#~ msgstr "Cor da grade" + +#~ msgid "Grid emphasis color" +#~ msgstr "Cor de ênfase da grade" + +#, fuzzy +#~ msgid "Background (also for export):" +#~ msgstr "Plano de Fundo (também para exportar)" + +#~ msgid "" +#~ "Pick the visible color under cursor, taking into account the page " +#~ "background and disregarding the transparency of objects" +#~ msgstr "" +#~ "Escolha a cor visível sob o cursor, considerando a cor de fundo da página " +#~ "e desprezando a transparência dos objetos" + +#~ msgid "Pick objects' color (including alpha)" +#~ msgstr "Escolha a cor dos objetos (incluindo alfa)" + +#~ msgid "" +#~ "Pick the actual color of object(s) under cursor, including their " +#~ "accumulated transparency" +#~ msgstr "" +#~ "Escola a cor atual do(s) objeto(s) sob o cursor, incluindo sua " +#~ "transparência acumulada" + +#~ msgid "Fill style" +#~ msgstr "Estilo de preenchimento" + +#~ msgid "Fill:" +#~ msgstr "Preeenchimento:" + +#~ msgid "" +#~ "Specifies the method of filling overlapping areas when an object " +#~ "intersects itself. With the \"winding fill\" method (fill-rule:nonzero), " +#~ "all overlapping areas are filled; with the \"alternating fill\" method " +#~ "(fill-rule:evenodd), every other of them is filled." +#~ msgstr "" +#~ "Especifica o método de preenchimento sobrepondo áreas quando um objeto " +#~ "intersecciona a si próprio. Como o método\"preenchimento sinuoso\" (fill-" +#~ "rule:nonzero), todas as áreas sobrepostas são preenchidas. Com o método " +#~ "\"preenchimento alternado\" (fill-rule:evenodd), cada outro deles é " +#~ "preenchido." + +#~ msgid "winding" +#~ msgstr "sinuoso" + +#~ msgid "alternating" +#~ msgstr "alternado" + +#, fuzzy +#~ msgid "Update Properties" +#~ msgstr "_Propriedades do Item" + +#, fuzzy +#~ msgid "Label invalid" +#~ msgstr "ID inválido" + +#~ msgid "" +#~ "You cannot group objects from different groups or layers." +#~ msgstr "" +#~ "Você não pode agrupar objetos de grupos ou camadas diferentes." + +#, fuzzy +#~ msgid "Messages Dialog" +#~ msgstr "Mensagens" + +#~ msgid "_V" +#~ msgstr "_V" + +#~ msgid "Value (brightness)" +#~ msgstr "Valor (brilho)" + +#~ msgid "Switch to the previous layer in the document" +#~ msgstr "Pula para a camada anterior no desenho" + +#, fuzzy +#~ msgid "executable" +#~ msgstr "Retângulo" + +#, fuzzy +#~ msgid "file" +#~ msgstr "Repe_tir como ladrilho" + +#, fuzzy +#~ msgid "extension" +#~ msgstr "Expansão:" + +#, fuzzy +#~ msgid "path" +#~ msgstr "_Caminho" + +#, fuzzy +#~ msgid "absolute" +#~ msgstr " absoluto à " + +#~ msgid "Could not create sodipodi-svg-doc factory" +#~ msgstr "Impossível criar fábrica de objeto sodipodi-svg-doc" + +#~ msgid "SVG Files" +#~ msgstr "Arquivos SVG" + +#~ msgid "Plain SVG" +#~ msgstr "SVG Plano" + +#~ msgid "Autodetect" +#~ msgstr "Autodetectar" + +#~ msgid "Document not modified. No need to revert." +#~ msgstr "Desenho não alterado. Sem necessidade de reverter." + +#~ msgid "Make s_ensitive" +#~ msgstr "Tornar s_ensitivo" + +#~ msgid "Make i_nsensitive" +#~ msgstr "Tornar i_nsensitivo" + +#~ msgid "" +#~ "Linked offset, %s by %f pt. Use Shift+D to look up original" +#~ msgstr "" +#~ "Tipográfico ligado, %s em %f pt. Use Shift+D para espiar o " +#~ "original" + +#~ msgid "" +#~ "Text on path (%s, %.5gpt). Use Shift+D to look up the path" +#~ msgstr "" +#~ "Texto em caminho (%s, %.5gpt). Use Shift+D para ver o " +#~ "caminho" + +#~ msgid "Set ID" +#~ msgstr "Ajustar ID" + +#~ msgid "Sensitive" +#~ msgstr "Sensitivo" + +#~ msgid "Visible" +#~ msgstr "Visível" + +#~ msgid "Active" +#~ msgstr "Ativo" + +#~ msgid "Printable" +#~ msgstr "Imprimível" + +#~ msgid "Intermediate Bitmap" +#~ msgstr "Figura Intermediária" + +#~ msgid "Other" +#~ msgstr "Outro" + +#~ msgid "Edit parent group" +#~ msgstr "Alterar grupo pai" + +#~ msgid "Prefer bitmap (XPM) icons to SVG ones" +#~ msgstr "Preferir ícones de figura (XPM) aos do formato SVG" + +#~ msgid "Select object(s) to tile." +#~ msgstr "Selecione um objeto para repetir como ladrilho." + +#~ msgid "Trace" +#~ msgstr "Traçar" + +#~ msgid "Error writing %s: %s" +#~ msgstr "Erro gravando %s: %s" + +#~ msgid "Untitled" +#~ msgstr "Sem Título" + +#~ msgid "Document Name:" +#~ msgstr "Nome do Desenho:" + +#~ msgid "Image URI:" +#~ msgstr "URI da Imagem:" + +#~ msgid "The angle of the calligraphic pen (in degrees)" +#~ msgstr "O ângulo da caneta caligráfica (em graus)" + +#~ msgid "Drag to paint a calligraphic stroke." +#~ msgstr "Arraste para pintar um traço caligráfico." diff --git a/po/ru.po b/po/ru.po new file mode 100644 index 000000000..4dfe98fa6 --- /dev/null +++ b/po/ru.po @@ -0,0 +1,9565 @@ +# translation of ru.po to Russian +# Russian translation of Inkscape +# Copyright (C) 2000,2002, 2004, 2005 Free Software Foundation, Inc. +# This file is distributed under the same license as the Inkscape package. +# Valek Filippov , 2000, 2003. +# Vitaly Lipatov , 2002, 2004. +# Alexey Remizov , 2004. +# bulia byak , 2004. +# Alexandre Prokoudine , 2004, 2005. +# Alexandre Prokoudine , 2005. +# +# +msgid "" +msgstr "" +"Project-Id-Version: ru\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2005-12-04 11:51-0800\n" +"PO-Revision-Date: 2005-11-08 02:04+0300\n" +"Last-Translator: Alexandre Prokoudine \n" +"Language-Team: Russian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 1.10.2\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%" +"10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" +"X-Poedit-Language: Russian\n" + +#: ../inkscape.desktop.in.h:1 +msgid "Create and edit Scalable Vector Graphics images" +msgstr "Создавать и изменять изображения в SVG" + +#: ../inkscape.desktop.in.h:2 +msgid "Inkscape SVG Vector Illustrator" +msgstr "Редактор векторной графики в формате SVG" + +#: ../../po/../src/arc-context.cpp:350 +msgid "" +"Ctrl: make circle or integer-ratio ellipse, snap arc/segment angle" +msgstr "" +"Ctrl: создать круг или эллипс с целым отношением сторон, ограничить " +"угол дуги/сегмента" + +#: ../../po/../src/arc-context.cpp:351 ../../po/../src/rect-context.cpp:388 +msgid "Shift: draw around the starting point" +msgstr "Shift: рисовать вокруг начальной точки" + +#: ../../po/../src/arc-context.cpp:413 +#: ../../po/../src/connector-context.cpp:493 +#: ../../po/../src/dyna-draw-context.cpp:506 +#: ../../po/../src/pen-context.cpp:329 ../../po/../src/pencil-context.cpp:208 +#: ../../po/../src/rect-context.cpp:452 ../../po/../src/spiral-context.cpp:421 +#: ../../po/../src/star-context.cpp:427 +msgid "Current layer is hidden. Unhide it to be able to draw on it." +msgstr "" +"Текущий слой скрыт. Откройте его, чтобы на нем можно было рисовать." + +#: ../../po/../src/arc-context.cpp:417 +#: ../../po/../src/connector-context.cpp:497 +#: ../../po/../src/dyna-draw-context.cpp:510 +#: ../../po/../src/pen-context.cpp:336 ../../po/../src/pencil-context.cpp:212 +#: ../../po/../src/rect-context.cpp:456 ../../po/../src/spiral-context.cpp:426 +#: ../../po/../src/star-context.cpp:431 +msgid "Current layer is locked. Unlock it to be able to draw on it." +msgstr "" +"Текущий слой заперт. Отоприте его, чтобы на нем можно было рисовать." + +#: ../../po/../src/arc-context.cpp:496 +#, c-format +msgid "" +"Ellipse: %s × %s; with Ctrl to make circle or integer-" +"ratio ellipse; with Shift to draw around the starting point" +msgstr "" +"Эллипс: %s × %s; с нажатым Ctrl рисует круг или эллипс с " +"целым отношением сторон; с нажатым Shift рисует вокруг начальной точки" + +#: ../../po/../src/connector-context.cpp:518 +msgid "Creating new connector" +msgstr "Создание новой соединительной линии" + +#: ../../po/../src/connector-context.cpp:939 +msgid "Finishing connector" +msgstr "Линия соединения завершается" + +#: ../../po/../src/connector-context.cpp:1108 +msgid "Connection point: click or drag to create a new connector" +msgstr "" +"Точка соединения: щелкните мышкой или перетащите для создания новой " +"соединительной линии" + +#: ../../po/../src/connector-context.cpp:1185 +msgid "Connector endpoint: drag to reroute or connect to new shapes" +msgstr "" +"Конечная соединительная точка: перетащите для пересоединения или " +"соединения с новыми фигурами" + +#: ../../po/../src/connector-context.cpp:1278 +msgid "Select at least one non-connector object." +msgstr "Выделите как минимум один объект (не соединительную линию)." + +#: ../../po/../src/desktop-events.cpp:238 +#, c-format +msgid "%s at %s" +msgstr "%s в %s" + +#. TRANSLATORS: This string appears when double-clicking on a guide. +#. This is the distance by which the guide is to be moved. +#: ../../po/../src/desktop-events.cpp:277 +msgid " relative by " +msgstr " относительно на " + +#. TRANSLATORS: This string appears when double-clicking on a guide. +#. This is the target location where the guide is to be moved. +#: ../../po/../src/desktop-events.cpp:282 +#: ../../po/../src/desktop-events.cpp:395 +msgid " absolute to " +msgstr " абсолютно к " + +#. create dialog +#: ../../po/../src/desktop-events.cpp:348 +msgid "Guideline" +msgstr "Направляющая" + +#: ../../po/../src/desktop-events.cpp:432 +#, c-format +msgid "Move %s" +msgstr "Переместить в %s" + +#: ../../po/../src/desktop.cpp:678 +msgid "No previous zoom." +msgstr "Нет предыдущего масштаба." + +#: ../../po/../src/desktop.cpp:703 +msgid "No next zoom." +msgstr "Нет следующего масштаба." + +#: ../../po/../src/dialogs/clonetiler.cpp:182 +msgid "Nothing selected." +msgstr "Ничего не было выделено." + +#: ../../po/../src/dialogs/clonetiler.cpp:188 +msgid "More than one object selected." +msgstr "" +"Выделено больше одного объекта. Невозможно взять стиль от нескольких " +"объектов сразу." + +#: ../../po/../src/dialogs/clonetiler.cpp:195 +#, c-format +msgid "Object has %d tiled clones." +msgstr "У объекта узор из %d клонов." + +#: ../../po/../src/dialogs/clonetiler.cpp:200 +msgid "Object has no tiled clones." +msgstr "У объекта нет узора из клонов." + +#: ../../po/../src/dialogs/clonetiler.cpp:865 +msgid "Select one object whose tiled clones to unclump." +msgstr "Выделите один объект для сглаживания узора из его клонов." + +#: ../../po/../src/dialogs/clonetiler.cpp:916 +msgid "Select one object whose tiled clones to remove." +msgstr "Выделите один объект для удаления узора из его клонов." + +#: ../../po/../src/dialogs/clonetiler.cpp:984 +#: ../../po/../src/selection-chemistry.cpp:1774 +msgid "Select an object to clone." +msgstr "Выделите объект для клонирования." + +#: ../../po/../src/dialogs/clonetiler.cpp:990 +#: ../../po/../src/selection-chemistry.cpp:1780 +msgid "" +"If you want to clone several objects, group them and clone the " +"group." +msgstr "" +"Для клонирования нескольких объектов сгруппируйте их и клонируйте " +"группу." + +#: ../../po/../src/dialogs/clonetiler.cpp:1484 +msgid "Per row:" +msgstr "На строку:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1497 +msgid "Per column:" +msgstr "На столбец:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1505 +msgid "Randomize:" +msgstr "Случайно:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1656 +msgid "_Symmetry" +msgstr "С_имметрия" + +#. TRANSLATORS: For the following 17 symmetry groups, see +#. * http://www.bib.ulb.ac.be/coursmath/doc/17.htm (visual examples); +#. * http://www.clarku.edu/~djoyce/wallpaper/seventeen.html (English vocabulary); or +#. * http://membres.lycos.fr/villemingerard/Geometri/Sym1D.htm (French vocabulary). +#. +#: ../../po/../src/dialogs/clonetiler.cpp:1664 +msgid "Select one of the 17 symmetry groups for the tiling" +msgstr "Выберите одну из 17 групп симметрии для узора" + +#. TRANSLATORS: "translation" means "shift" / "displacement" here. +#: ../../po/../src/dialogs/clonetiler.cpp:1675 +msgid "P1: simple translation" +msgstr "P1: простое смещение" + +#: ../../po/../src/dialogs/clonetiler.cpp:1676 +msgid "P2: 180° rotation" +msgstr "P2: поворот на 180°" + +#: ../../po/../src/dialogs/clonetiler.cpp:1677 +msgid "PM: reflection" +msgstr "PM: отражение" + +#. TRANSLATORS: "glide reflection" is a reflection and a translation combined. +#. For more info, see http://mathforum.org/sum95/suzanne/symsusan.html +#: ../../po/../src/dialogs/clonetiler.cpp:1680 +msgid "PG: glide reflection" +msgstr "PG: отражение со сдвигом" + +#: ../../po/../src/dialogs/clonetiler.cpp:1681 +msgid "CM: reflection + glide reflection" +msgstr "CM: отражение + отражение со сдвигом" + +#: ../../po/../src/dialogs/clonetiler.cpp:1682 +msgid "PMM: reflection + reflection" +msgstr "PMM: отражение + отражение" + +#: ../../po/../src/dialogs/clonetiler.cpp:1683 +msgid "PMG: reflection + 180° rotation" +msgstr "PMG: отражение + поворот на 180°" + +#: ../../po/../src/dialogs/clonetiler.cpp:1684 +msgid "PGG: glide reflection + 180° rotation" +msgstr "PGG: отражение со сдвигом + поворот на 180°" + +#: ../../po/../src/dialogs/clonetiler.cpp:1685 +msgid "CMM: reflection + reflection + 180° rotation" +msgstr "CMM: отражение + отражение + поворот на 180°" + +#: ../../po/../src/dialogs/clonetiler.cpp:1686 +msgid "P4: 90° rotation" +msgstr "P4: поворот на 90°" + +#: ../../po/../src/dialogs/clonetiler.cpp:1687 +msgid "P4M: 90° rotation + 45° reflection" +msgstr "P4M: поворот на 90° + отражение на 45°" + +#: ../../po/../src/dialogs/clonetiler.cpp:1688 +msgid "P4G: 90° rotation + 90° reflection" +msgstr "P4G: поворот на 90° + отражение на 90°" + +#: ../../po/../src/dialogs/clonetiler.cpp:1689 +msgid "P3: 120° rotation" +msgstr "P3: поворот на 120°" + +#: ../../po/../src/dialogs/clonetiler.cpp:1690 +msgid "P31M: reflection + 120° rotation, dense" +msgstr "P31M: отражение + поворот на 120°, плотно" + +#: ../../po/../src/dialogs/clonetiler.cpp:1691 +msgid "P3M1: reflection + 120° rotation, sparse" +msgstr "P3M1: отражение + поворот на 120°, редко" + +#: ../../po/../src/dialogs/clonetiler.cpp:1692 +msgid "P6: 60° rotation" +msgstr "P6: поворот на 60°" + +#: ../../po/../src/dialogs/clonetiler.cpp:1693 +msgid "P6M: reflection + 60° rotation" +msgstr "P6M: отражение + поворот на 60°" + +#: ../../po/../src/dialogs/clonetiler.cpp:1721 +msgid "S_hift" +msgstr "Сме_щение" + +#. TRANSLATORS: "shift" means: the tiles will be shifted (offset) horizontally by this amount +#: ../../po/../src/dialogs/clonetiler.cpp:1731 +#, no-c-format +msgid "Shift X:" +msgstr "Смещение по X:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1739 +#, no-c-format +msgid "Horizontal shift per row (in % of tile width)" +msgstr "" +"Смещение по горизонтали на каждую строку\n" +"(в процентах от ширины элемента узора)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1747 +#, no-c-format +msgid "Horizontal shift per column (in % of tile width)" +msgstr "" +"Смещение по горизонтали на каждый столбец\n" +"(в процентах от ширины элемента узора)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1754 +msgid "Randomize the horizontal shift by this percentage" +msgstr "" +"Случайно менять смещение по горизонтали\n" +"на этот процент" + +#. TRANSLATORS: "shift" means: the tiles will be shifted (offset) vertically by this amount +#: ../../po/../src/dialogs/clonetiler.cpp:1764 +#, no-c-format +msgid "Shift Y:" +msgstr " Смещение по Y:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1772 +#, no-c-format +msgid "Vertical shift per row (in % of tile height)" +msgstr "" +"Смещение по вертикали на каждую строку\n" +"(в процентах от высоты элемента узора)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1780 +#, no-c-format +msgid "Vertical shift per column (in % of tile height)" +msgstr "" +"Смещение по вертикали на каждый столбец\n" +"(в процентах от высоты элемента узора)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1787 +msgid "Randomize the vertical shift by this percentage" +msgstr "" +"Случайно менять смещение по вертикали\n" +"на этот процент" + +#: ../../po/../src/dialogs/clonetiler.cpp:1795 +msgid "Exponent:" +msgstr "Экспонента:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1802 +msgid "Whether rows are spaced evenly (1), converge (<1) or diverge (>1)" +msgstr "" +"Располагать ли строки на одинаковом расстоянии (1), постепенно сдвигая (<1) " +"или раздвигая (>1)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1809 +msgid "Whether columns are spaced evenly (1), converge (<1) or diverge (>1)" +msgstr "" +"Располагать ли столбцы на одинаковом расстоянии (1), постепенно сдвигая (<1) " +"или раздвигая (>1)" + +#. TRANSLATORS: "Alternate" is a verb here +#: ../../po/../src/dialogs/clonetiler.cpp:1817 +#: ../../po/../src/dialogs/clonetiler.cpp:1907 +#: ../../po/../src/dialogs/clonetiler.cpp:1966 +#: ../../po/../src/dialogs/clonetiler.cpp:2022 +#: ../../po/../src/dialogs/clonetiler.cpp:2153 +msgid "Alternate:" +msgstr "Чередовать:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1823 +msgid "Alternate the sign of shifts for each row" +msgstr "Чередовать знак смещения для каждой строки" + +#: ../../po/../src/dialogs/clonetiler.cpp:1828 +msgid "Alternate the sign of shifts for each column" +msgstr "Чередовать знак смещения для каждого столбца" + +#: ../../po/../src/dialogs/clonetiler.cpp:1837 +msgid "Sc_ale" +msgstr "_Масштаб" + +#: ../../po/../src/dialogs/clonetiler.cpp:1845 +msgid "Scale X:" +msgstr "Масштаб по X:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1853 +#, no-c-format +msgid "Horizontal scale per row (in % of tile width)" +msgstr "" +"Масштабировать по горизонтали на каждую строку\n" +"(в процентах от ширины элемента узора)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1861 +#, no-c-format +msgid "Horizontal scale per column (in % of tile width)" +msgstr "" +"Масштабировать по горизонтали на каждый столбец\n" +"(в процентах от ширины элемента узора)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1868 +msgid "Randomize the horizontal scale by this percentage" +msgstr "" +"Случайным образом масштабировать \n" +"по горизонтали на этот процент" + +#: ../../po/../src/dialogs/clonetiler.cpp:1876 +msgid "Scale Y:" +msgstr "Масштаб по Y:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1884 +#, no-c-format +msgid "Vertical scale per row (in % of tile height)" +msgstr "" +"Масштабировать по вертикали на каждую строку\n" +"(в процентах от высоты элемента узора)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1892 +#, no-c-format +msgid "Vertical scale per column (in % of tile height)" +msgstr "" +"Масштабировать по вертикали на каждый столбец\n" +"(в процентах от высоты элемента узора)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1899 +msgid "Randomize the vertical scale by this percentage" +msgstr "" +"Случайным образом масштабировать\n" +"по вертикали на этот процент" + +#: ../../po/../src/dialogs/clonetiler.cpp:1913 +msgid "Alternate the sign of scales for each row" +msgstr "Чередовать знак масштаба для каждой строки" + +#: ../../po/../src/dialogs/clonetiler.cpp:1918 +msgid "Alternate the sign of scales for each column" +msgstr "Чередовать знак масштаба для каждого столбца" + +#: ../../po/../src/dialogs/clonetiler.cpp:1927 +msgid "_Rotation" +msgstr "_Поворот" + +#: ../../po/../src/dialogs/clonetiler.cpp:1935 +msgid "Angle:" +msgstr "Угол:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1943 +#, no-c-format +msgid "Rotate tiles by this angle for each row" +msgstr "Поворачивать элементы узора на этот угол в каждой строке" + +#: ../../po/../src/dialogs/clonetiler.cpp:1951 +#, no-c-format +msgid "Rotate tiles by this angle for each column" +msgstr "Поворачивать элементы узора на этот угол в каждом столбце" + +#: ../../po/../src/dialogs/clonetiler.cpp:1958 +msgid "Randomize the rotation angle by this percentage" +msgstr "" +"Случайным образом менять \n" +"угол поворота на этот процент" + +#: ../../po/../src/dialogs/clonetiler.cpp:1972 +msgid "Alternate the rotation direction for each row" +msgstr "Чередовать направление поворота для каждой строки" + +#: ../../po/../src/dialogs/clonetiler.cpp:1977 +msgid "Alternate the rotation direction for each column" +msgstr "Чередовать направление поворота для каждого столбца" + +#: ../../po/../src/dialogs/clonetiler.cpp:1985 +msgid "_Opacity" +msgstr "_Непрозрачность" + +#: ../../po/../src/dialogs/clonetiler.cpp:1993 +msgid "Fade out:" +msgstr "Прозрачнее на:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2000 +msgid "Decrease tile opacity by this percentage for each row" +msgstr "" +"Увеличить прозрачность элементов узора\n" +"на этот процент для каждой строки" + +#: ../../po/../src/dialogs/clonetiler.cpp:2007 +msgid "Decrease tile opacity by this percentage for each column" +msgstr "" +"Увеличить прозрачность элементов узора\n" +"на этот процент для каждого столбца" + +#: ../../po/../src/dialogs/clonetiler.cpp:2014 +msgid "Randomize the tile opacity by this percentage" +msgstr "Случайно менять прозрачность, максимум на данный процент" + +#: ../../po/../src/dialogs/clonetiler.cpp:2028 +msgid "Alternate the sign of opacity change for each row" +msgstr "" +"Чередовать знак изменения прозрачности\n" +"для каждой строки" + +#: ../../po/../src/dialogs/clonetiler.cpp:2033 +msgid "Alternate the sign of opacity change for each column" +msgstr "" +"Чередовать знак изменения прозрачности\n" +"для каждого столбца" + +#: ../../po/../src/dialogs/clonetiler.cpp:2041 +msgid "Co_lor" +msgstr "Цвет" + +#: ../../po/../src/dialogs/clonetiler.cpp:2046 +msgid "Initial color: " +msgstr "Исходный цвет:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2050 +msgid "Initial color of tiled clones" +msgstr "Исходный цвет элементов узора" + +#: ../../po/../src/dialogs/clonetiler.cpp:2050 +msgid "" +"Initial color for clones (works only if the original has unset fill or " +"stroke)" +msgstr "" +"Исходный цвет клонов (у оригинала должен быть сброшен цвет заполнения или " +"штриха)" + +#: ../../po/../src/dialogs/clonetiler.cpp:2065 +msgid "H:" +msgstr "H:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2072 +msgid "Change the tile hue by this percentage for each row" +msgstr "" +"Менять цветовой тон элементов узора\n" +"на этот процент для каждой строки" + +#: ../../po/../src/dialogs/clonetiler.cpp:2079 +msgid "Change the tile hue by this percentage for each column" +msgstr "" +"Менять цветовой тон элементов узора\n" +"на этот процент для каждого столбца" + +#: ../../po/../src/dialogs/clonetiler.cpp:2086 +msgid "Randomize the tile hue by this percentage" +msgstr "Случайно менять цветовой тон, максимум на этот процент" + +#: ../../po/../src/dialogs/clonetiler.cpp:2095 +msgid "S:" +msgstr "S:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2102 +msgid "Change the color saturation by this percentage for each row" +msgstr "" +"Менять насыщенность цвета элементов узора\n" +"на этот процент для каждой строки" + +#: ../../po/../src/dialogs/clonetiler.cpp:2109 +msgid "Change the color saturation by this percentage for each column" +msgstr "" +"Менять насыщенность цвета элементов узора\n" +"на этот процент для каждого столбца" + +#: ../../po/../src/dialogs/clonetiler.cpp:2116 +msgid "Randomize the color saturation by this percentage" +msgstr "Случайно менять насыщенность цвета, максимум на этот процент" + +#: ../../po/../src/dialogs/clonetiler.cpp:2124 +msgid "L:" +msgstr "L:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2131 +msgid "Change the color lightness by this percentage for each row" +msgstr "Менять яркость цвета на этот процент для каждой строки" + +#: ../../po/../src/dialogs/clonetiler.cpp:2138 +msgid "Change the color lightness by this percentage for each column" +msgstr "Менять яркость цвета на этот процент для каждого столбца" + +#: ../../po/../src/dialogs/clonetiler.cpp:2145 +msgid "Randomize the color lightness by this percentage" +msgstr "Случайно менять яркость цвета, максимум на данный процент" + +#: ../../po/../src/dialogs/clonetiler.cpp:2159 +msgid "Alternate the sign of color changes for each row" +msgstr "" +"Чередовать знак изменения цвета\n" +"для каждой строки" + +#: ../../po/../src/dialogs/clonetiler.cpp:2164 +msgid "Alternate the sign of color changes for each column" +msgstr "" +"Чередовать знак изменения цвета\n" +"для каждого столбца" + +#: ../../po/../src/dialogs/clonetiler.cpp:2172 +msgid "_Trace" +msgstr "_Обвести" + +#: ../../po/../src/dialogs/clonetiler.cpp:2179 +msgid "Trace the drawing under the tiles" +msgstr "Обвести узором рисунок под ним" + +#: ../../po/../src/dialogs/clonetiler.cpp:2183 +msgid "" +"For each clone, pick a value from the drawing in that clone's location and " +"apply it to the clone" +msgstr "" +"Для каждого клона в узоре взять значение под клоном и применить его к клону" + +#: ../../po/../src/dialogs/clonetiler.cpp:2197 +msgid "1. Pick from the drawing:" +msgstr "1. Взять значение:" + +#. ----Hbox2 +#: ../../po/../src/dialogs/clonetiler.cpp:2208 +#: ../../po/../src/dialogs/clonetiler.cpp:2355 +#: ../../po/../src/ui/dialog/tracedialog.cpp:445 +msgid "Color" +msgstr "Цвет" + +#: ../../po/../src/dialogs/clonetiler.cpp:2209 +msgid "Pick the visible color and opacity" +msgstr "Взять видимый цвет (без прозрачности) в каждой точке" + +#: ../../po/../src/dialogs/clonetiler.cpp:2216 +#: ../../po/../src/dialogs/clonetiler.cpp:2365 +#: ../share/extensions/dropshadow.inx.h:3 +msgid "Opacity" +msgstr "Непрозрачность" + +#: ../../po/../src/dialogs/clonetiler.cpp:2217 +msgid "Pick the total accumulated opacity" +msgstr "Взять суммарную непрозрачность в каждой точке" + +#: ../../po/../src/dialogs/clonetiler.cpp:2224 +msgid "R" +msgstr "R" + +#: ../../po/../src/dialogs/clonetiler.cpp:2225 +msgid "Pick the Red component of the color" +msgstr "Взять значение красного канала цвета" + +#: ../../po/../src/dialogs/clonetiler.cpp:2232 +msgid "G" +msgstr "G" + +#: ../../po/../src/dialogs/clonetiler.cpp:2233 +msgid "Pick the Green component of the color" +msgstr "Взять значение зеленого канала цвета" + +#: ../../po/../src/dialogs/clonetiler.cpp:2240 +msgid "B" +msgstr "B" + +#: ../../po/../src/dialogs/clonetiler.cpp:2241 +msgid "Pick the Blue component of the color" +msgstr "Взять значение синего канала цвета" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2250 +msgid "clonetiler|H" +msgstr "H" + +#: ../../po/../src/dialogs/clonetiler.cpp:2251 +msgid "Pick the hue of the color" +msgstr "Взять цветовой тон" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2260 +msgid "clonetiler|S" +msgstr "S" + +#: ../../po/../src/dialogs/clonetiler.cpp:2261 +msgid "Pick the saturation of the color" +msgstr "Взять насыщенность цвета" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2270 +msgid "clonetiler|L" +msgstr "L" + +#: ../../po/../src/dialogs/clonetiler.cpp:2271 +msgid "Pick the lightness of the color" +msgstr "Взять яркость цвета" + +#: ../../po/../src/dialogs/clonetiler.cpp:2281 +msgid "2. Tweak the picked value:" +msgstr "2. Изменить взятое значение:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2291 +msgid "Gamma-correct:" +msgstr "Гамма-коррекция:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2296 +msgid "Shift the mid-range of the picked value upwards (>0) or downwards (<0)" +msgstr "Сдвинуть середину диапазона снятых значений вверх (>0) или вниз (<0)" + +#: ../../po/../src/dialogs/clonetiler.cpp:2303 +msgid "Randomize:" +msgstr "Случайно:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2308 +msgid "Randomize the picked value by this percentage" +msgstr "Случайно менять взятое значение, максимум на данный процент" + +#: ../../po/../src/dialogs/clonetiler.cpp:2315 +msgid "Invert:" +msgstr "Инвертировать:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2319 +msgid "Invert the picked value" +msgstr "Инвертировать взятое значение" + +#: ../../po/../src/dialogs/clonetiler.cpp:2325 +msgid "3. Apply the value to the clones':" +msgstr "3. Применить это значение к клонам через:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2335 +msgid "Presence" +msgstr "Наличие" + +#: ../../po/../src/dialogs/clonetiler.cpp:2338 +msgid "" +"Each clone is created with the probability determined by the picked value in " +"that point" +msgstr "" +"Вероятность появления каждого клона определяется значением, взятым в данной " +"точке" + +#: ../../po/../src/dialogs/clonetiler.cpp:2345 +msgid "Size" +msgstr "Размер" + +#: ../../po/../src/dialogs/clonetiler.cpp:2348 +msgid "Each clone's size is determined by the picked value in that point" +msgstr "Размер каждого клона определяется значением, взятым в данной точке" + +#: ../../po/../src/dialogs/clonetiler.cpp:2358 +msgid "" +"Each clone is painted by the picked color (the original must have unset fill " +"or stroke)" +msgstr "" +"Каждый клон красится взятым в данной точке цветом (у оригинала должен быть " +"сброшен цвет заполнения или штриха)" + +#: ../../po/../src/dialogs/clonetiler.cpp:2368 +msgid "Each clone's opacity is determined by the picked value in that point" +msgstr "" +"Прозрачность каждого клона определяется значением, взятым в данной точке" + +#: ../../po/../src/dialogs/clonetiler.cpp:2395 +msgid "How many rows in the tiling" +msgstr "Количество строк в узоре" + +#: ../../po/../src/dialogs/clonetiler.cpp:2415 +msgid "How many columns in the tiling" +msgstr "Количество столбцов в узоре" + +#: ../../po/../src/dialogs/clonetiler.cpp:2445 +msgid "Width of the rectangle to be filled" +msgstr "Ширина заполняемой области" + +#: ../../po/../src/dialogs/clonetiler.cpp:2470 +msgid "Height of the rectangle to be filled" +msgstr "Высота заполняемой области" + +#: ../../po/../src/dialogs/clonetiler.cpp:2485 +msgid "Rows, columns: " +msgstr "Строк, столбцов: " + +#: ../../po/../src/dialogs/clonetiler.cpp:2486 +msgid "Create the specified number of rows and columns" +msgstr "Создать указанное количество строк и столбцов" + +#: ../../po/../src/dialogs/clonetiler.cpp:2495 +msgid "Width, height: " +msgstr "Ширина, высота: " + +#: ../../po/../src/dialogs/clonetiler.cpp:2496 +msgid "Fill the specified width and height with the tiling" +msgstr "Заполнить узором указанную область" + +#: ../../po/../src/dialogs/clonetiler.cpp:2512 +msgid "Use saved size and position of the tile" +msgstr "Использовать запомненный размер и позицию оригинала" + +#: ../../po/../src/dialogs/clonetiler.cpp:2515 +msgid "" +"Pretend that the size and position of the tile are the same as the last time " +"you tiled it (if any), instead of using the current size" +msgstr "" +"Использовать те же самые размер и позицию элемента узора,\n" +"что и в прошлый раз, когда вы делали\n" +"узор из этого же объекта (если делали),\n" +"вместо того чтобы использовать его настоящий размер/позицию" + +#: ../../po/../src/dialogs/clonetiler.cpp:2539 +msgid " _Create " +msgstr "_Создать" + +#: ../../po/../src/dialogs/clonetiler.cpp:2541 +msgid "Create and tile the clones of the selection" +msgstr "Создать узор из клонов выделенного объекта" + +#. TRANSLATORS: if a group of objects are "clumped" together, then they +#. are unevenly spread in the given amount of space - as shown in the +#. diagrams on the left in the following screenshot: +#. http://www.inkscape.org/screenshots/gallery/inkscape-0.42-CVS-tiles-unclump.png +#. So unclumping is the process of spreading a number of objects out more evenly. +#: ../../po/../src/dialogs/clonetiler.cpp:2556 +msgid " _Unclump " +msgstr " _Сгладить " + +#: ../../po/../src/dialogs/clonetiler.cpp:2557 +msgid "Spread out clones to reduce clumping; can be applied repeatedly" +msgstr "" +"Распределить клоны более равномерно, избавиться от комков; можно применять " +"несколько раз подряд" + +#: ../../po/../src/dialogs/clonetiler.cpp:2563 +msgid " Re_move " +msgstr " _Удалить " + +#: ../../po/../src/dialogs/clonetiler.cpp:2564 +msgid "Remove existing tiled clones of the selected object (siblings only)" +msgstr "" +"Удалить составляющие узор клоны выделенного объекта\n" +"(только в том же слое/группе)" + +#: ../../po/../src/dialogs/clonetiler.cpp:2580 +msgid " R_eset " +msgstr " С_бросить " + +#. TRANSLATORS: "change" is a noun here +#: ../../po/../src/dialogs/clonetiler.cpp:2582 +msgid "" +"Reset all shifts, scales, rotates, opacity and color changes in the dialog " +"to zero" +msgstr "" +"Обнулить все введенные значения смещения, масштабирования, поворотов, " +"непрозрачности и цвета" + +#: ../../po/../src/dialogs/color-picker.cpp:280 +msgid "Close" +msgstr "Закрыть" + +#: ../../po/../src/dialogs/debugdialog.cpp:138 +msgid "Messages" +msgstr "Сообщения" + +#. ## Add a menu for clear() +#: ../../po/../src/dialogs/debugdialog.cpp:144 +#: ../../po/../src/menus-skeleton.h:16 +#: ../../po/../src/ui/dialog/messages.cpp:56 +#: ../../po/../src/ui/dialog/scriptdialog.cpp:181 +msgid "_File" +msgstr "_Файл" + +#. TRANSLATORS: "Clear" is a verb here +#: ../../po/../src/dialogs/debugdialog.cpp:145 +#: ../../po/../src/dialogs/find.cpp:753 +#: ../../po/../src/ui/dialog/messages.cpp:57 +#: ../../po/../src/ui/dialog/scriptdialog.cpp:182 +msgid "_Clear" +msgstr "_Очистить" + +#: ../../po/../src/dialogs/debugdialog.cpp:147 +#: ../../po/../src/ui/dialog/messages.cpp:59 +msgid "Capture log messages" +msgstr "Сохранять отладочные сообщения" + +#: ../../po/../src/dialogs/debugdialog.cpp:149 +#: ../../po/../src/ui/dialog/messages.cpp:61 +msgid "Release log messages" +msgstr "Отключить сохранение отладочных сообщений" + +#. Notebook tab +#: ../../po/../src/dialogs/desktop-properties.cpp:909 +#: ../../po/../src/ui/dialog/document-preferences.cpp:89 +#: ../../po/../src/ui/widget/panel.cpp:107 +msgid "Grid" +msgstr "Сетка" + +#. Checkbuttons +#. / \todo FIXME: gray out snapping when grid is off +#. / \todo FIXME: gray out snapping when grid is off. +#. / Dissenting view: you want snapping without grid. +#: ../../po/../src/dialogs/desktop-properties.cpp:917 +#: ../../po/../src/ui/dialog/document-preferences.cpp:179 +msgid "Show grid" +msgstr "Показывать сетку" + +#: ../../po/../src/dialogs/desktop-properties.cpp:917 +#: ../../po/../src/ui/dialog/document-preferences.cpp:179 +#: ../../po/../src/verbs.cpp:2115 +msgid "Show or hide grid" +msgstr "Показать/скрыть сетку" + +#: ../../po/../src/dialogs/desktop-properties.cpp:918 +#: ../../po/../src/ui/dialog/document-preferences.cpp:180 +msgid "Snap bounding boxes to grid" +msgstr "Рамки объектов прилипают к сетке" + +#: ../../po/../src/dialogs/desktop-properties.cpp:918 +#: ../../po/../src/dialogs/desktop-properties.cpp:1001 +#: ../../po/../src/ui/dialog/document-preferences.cpp:181 +#: ../../po/../src/ui/dialog/document-preferences.cpp:236 +msgid "Snap the edges of the object bounding boxes" +msgstr "Включить прилипание для рамок объектов" + +#: ../../po/../src/dialogs/desktop-properties.cpp:919 +#: ../../po/../src/ui/dialog/document-preferences.cpp:183 +msgid "Snap nodes to grid" +msgstr "Узлы контуров прилипают к сетке" + +#: ../../po/../src/dialogs/desktop-properties.cpp:919 +#: ../../po/../src/dialogs/desktop-properties.cpp:1002 +#: ../../po/../src/ui/dialog/document-preferences.cpp:184 +#: ../../po/../src/ui/dialog/document-preferences.cpp:239 +msgid "Snap path nodes, text baselines, ellipse centers, etc." +msgstr "" +"Включить прилипание для узлов контуров, опорных точек текста, центров " +"эллипсов и т.д." + +#: ../../po/../src/dialogs/desktop-properties.cpp:937 +#: ../../po/../src/ui/dialog/document-preferences.cpp:186 +msgid "Grid units:" +msgstr "Единицы сетки:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:939 +#: ../../po/../src/ui/dialog/document-preferences.cpp:187 +msgid "Origin X:" +msgstr "Начало по X" + +#: ../../po/../src/dialogs/desktop-properties.cpp:942 +#: ../../po/../src/ui/dialog/document-preferences.cpp:189 +msgid "Origin Y:" +msgstr "Начало по Y" + +#: ../../po/../src/dialogs/desktop-properties.cpp:945 +#: ../../po/../src/ui/dialog/document-preferences.cpp:191 +msgid "Spacing X:" +msgstr "Интервал по X" + +#: ../../po/../src/dialogs/desktop-properties.cpp:948 +#: ../../po/../src/ui/dialog/document-preferences.cpp:193 +msgid "Spacing Y:" +msgstr "Интервал по Y" + +#: ../../po/../src/dialogs/desktop-properties.cpp:952 +#: ../../po/../src/dialogs/desktop-properties.cpp:1013 +#: ../../po/../src/ui/dialog/document-preferences.cpp:195 +#: ../../po/../src/ui/dialog/document-preferences.cpp:241 +msgid "Snap units:" +msgstr "Единицы:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:955 +#: ../../po/../src/dialogs/desktop-properties.cpp:1016 +#: ../../po/../src/ui/dialog/document-preferences.cpp:196 +#: ../../po/../src/ui/dialog/document-preferences.cpp:242 +msgid "Snap distance:" +msgstr "Зона прилипания:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:958 +#: ../../po/../src/ui/dialog/document-preferences.cpp:199 +msgid "Grid line color:" +msgstr "Цвет линий сетки:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:959 +#: ../../po/../src/ui/dialog/document-preferences.cpp:199 +msgid "Grid line color" +msgstr "Цвет линий сетки" + +#: ../../po/../src/dialogs/desktop-properties.cpp:959 +#: ../../po/../src/ui/dialog/document-preferences.cpp:200 +msgid "Color of grid lines" +msgstr "Цвет линий сетки" + +#: ../../po/../src/dialogs/desktop-properties.cpp:961 +#: ../../po/../src/ui/dialog/document-preferences.cpp:201 +msgid "Major grid line color:" +msgstr "Цвет основной линии:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:962 +#: ../../po/../src/ui/dialog/document-preferences.cpp:201 +msgid "Major grid line color" +msgstr "Цвет основной линии" + +#: ../../po/../src/dialogs/desktop-properties.cpp:962 +#: ../../po/../src/ui/dialog/document-preferences.cpp:202 +msgid "Color of the major (highlighted) grid lines" +msgstr "Цвет основных (активных) линий" + +#: ../../po/../src/dialogs/desktop-properties.cpp:965 +#: ../../po/../src/ui/dialog/document-preferences.cpp:204 +msgid "Major grid line every:" +msgstr "Основные линии через каждые:" + +#. TRANSLATORS: This belongs to the "Major grid line every:" string, +#. see grid settings in the "Document Preferences" dialog +#: ../../po/../src/dialogs/desktop-properties.cpp:977 +#: ../../po/../src/ui/dialog/document-preferences.cpp:204 +msgid "lines" +msgstr "линий" + +#. Guidelines page +#: ../../po/../src/dialogs/desktop-properties.cpp:991 +#: ../../po/../src/ui/dialog/document-preferences.cpp:90 +msgid "Guides" +msgstr "Направляющие" + +#. / \todo FIXME: gray out snapping when guides are off +#. / Dissenting view: you want snapping without guides. +#: ../../po/../src/dialogs/desktop-properties.cpp:1000 +#: ../../po/../src/ui/dialog/document-preferences.cpp:234 +msgid "Show guides" +msgstr "Показывать направляющие" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1000 +#: ../../po/../src/ui/dialog/document-preferences.cpp:234 +#: ../../po/../src/verbs.cpp:2116 +msgid "Show or hide guides" +msgstr "Показать/скрыть направляющие" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1001 +#: ../../po/../src/ui/dialog/document-preferences.cpp:235 +msgid "Snap bounding boxes to guides" +msgstr "Рамки объектов прилипают к направляющим" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1002 +#: ../../po/../src/ui/dialog/document-preferences.cpp:238 +msgid "Snap points to guides" +msgstr "Точки контуров прилипают к направляющим" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1020 +#: ../../po/../src/ui/dialog/document-preferences.cpp:243 +msgid "Guide color:" +msgstr "Цвет направляющих:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1021 +#: ../../po/../src/ui/dialog/document-preferences.cpp:243 +msgid "Guideline color" +msgstr "Цвет направляющих" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1021 +#: ../../po/../src/ui/dialog/document-preferences.cpp:244 +msgid "Color of guidelines" +msgstr "Цвет направляющих" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1023 +#: ../../po/../src/ui/dialog/document-preferences.cpp:245 +msgid "Highlight color:" +msgstr "Цвет активной:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1024 +#: ../../po/../src/ui/dialog/document-preferences.cpp:245 +msgid "Highlighted guideline color" +msgstr "Цвет активной направляющей" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1024 +#: ../../po/../src/ui/dialog/document-preferences.cpp:246 +msgid "Color of a guideline when it is under mouse" +msgstr "Цвет направляющей под курсором" + +#. Page page +#: ../../po/../src/dialogs/desktop-properties.cpp:1029 +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:855 +#: ../../po/../src/ui/dialog/document-preferences.cpp:88 +#: ../../po/../src/widgets/desktop-widget.cpp:1061 +msgid "Page" +msgstr "Страница" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1039 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +msgid "Background:" +msgstr "Фон:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1040 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +msgid "Background color" +msgstr "Цвет фона" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1041 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +msgid "" +"Color and transparency of the page background (also used for bitmap export)" +msgstr "Цвет или прозрачность фона страницы (учитывается при экспорте в растр)" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1045 +#: ../../po/../src/ui/dialog/document-preferences.cpp:147 +#, fuzzy +msgid "Show page border" +msgstr "Показывать рамку холста" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1049 +#: ../../po/../src/ui/dialog/document-preferences.cpp:148 +msgid "Border on top of drawing" +msgstr "Рамка холста всегда над рисунком" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1052 +#: ../../po/../src/ui/dialog/document-preferences.cpp:149 +msgid "Border color:" +msgstr "Цвет рамки:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1053 +#: ../../po/../src/ui/dialog/document-preferences.cpp:149 +#, fuzzy +msgid "Page border color" +msgstr "Цвет рамки" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1054 +#: ../../po/../src/ui/dialog/document-preferences.cpp:150 +#, fuzzy +msgid "Color of the page border" +msgstr "Цвет рамки холста" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1059 +#: ../../po/../src/ui/dialog/document-preferences.cpp:152 +msgid "Show page shadow" +msgstr "Показывать тень от страницы" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1063 +#: ../../po/../src/ui/dialog/document-preferences.cpp:153 +msgid "Default units:" +msgstr "Единица измерения по умолчанию:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1069 +msgid "Units for the tool controls, ruler, and the statusbar" +msgstr "" +"Единица измерения для опций инструментов,\n" +"линеек и статусной строки" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1086 +#: ../../po/../src/ui/widget/page-sizer.cpp:209 +#, fuzzy +msgid "Page size:" +msgstr "Размер холста:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1110 +#: ../../po/../src/ui/widget/page-sizer.cpp:219 +msgid "Custom" +msgstr "Нестандартный" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1121 +#: ../../po/../src/ui/widget/page-sizer.cpp:225 +#, fuzzy +msgid "Page orientation:" +msgstr "Расположение холста:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1133 +#: ../../po/../src/ui/widget/page-sizer.cpp:232 +msgid "Landscape" +msgstr "Ландшафт" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1139 +#: ../../po/../src/ui/widget/page-sizer.cpp:234 +msgid "Portrait" +msgstr "Портрет" + +#. Custom paper frame +#: ../../po/../src/dialogs/desktop-properties.cpp:1148 +#: ../../po/../src/ui/widget/page-sizer.cpp:249 +#, fuzzy +msgid "Custom size" +msgstr "Нестандартный" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1160 +#: ../../po/../src/dialogs/export.cpp:269 +#: ../../po/../src/ui/widget/page-sizer.cpp:261 +msgid "Units:" +msgstr "Единицы:" + +#. Stroke width +#: ../../po/../src/dialogs/desktop-properties.cpp:1162 +#: ../../po/../src/dialogs/export.cpp:310 +#: ../../po/../src/dialogs/object-attributes.cpp:55 +#: ../../po/../src/dialogs/stroke-style.cpp:985 +#: ../../po/../src/ui/widget/page-sizer.cpp:262 +#: ../../po/../src/widgets/toolbox.cpp:1957 +msgid "Width:" +msgstr "Ширина:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1183 +#: ../../po/../src/dialogs/export.cpp:326 +#: ../../po/../src/dialogs/export.cpp:431 +#: ../../po/../src/dialogs/object-attributes.cpp:56 +#: ../../po/../src/ui/widget/page-sizer.cpp:263 +msgid "Height:" +msgstr "Высота:" + +#. +#. * Ownership metadata tab +#. +#: ../../po/../src/dialogs/desktop-properties.cpp:1206 +msgid "Metadata" +msgstr "Метаданные" + +#. add license selector pull-down +#: ../../po/../src/dialogs/desktop-properties.cpp:1225 +msgid "License" +msgstr "Лицензия" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1255 +msgid "Proprietary" +msgstr "Коммерческая" + +#: ../../po/../src/dialogs/display-settings.cpp:212 +msgid "When transforming, show:" +msgstr "При трансформации показывать:" + +#: ../../po/../src/dialogs/display-settings.cpp:223 +msgid "Objects" +msgstr "Объекты" + +#: ../../po/../src/dialogs/display-settings.cpp:224 +msgid "Show the actual objects when moving or transforming" +msgstr "Показывать объекты полностью при перемещении или трансформации" + +#: ../../po/../src/dialogs/display-settings.cpp:231 +msgid "Box outline" +msgstr "Рамку" + +#: ../../po/../src/dialogs/display-settings.cpp:232 +msgid "Show only a box outline of the objects when moving or transforming" +msgstr "" +"Показывать только прямоугольную рамку объектов при перемещении или " +"трансформации" + +#: ../../po/../src/dialogs/display-settings.cpp:238 +msgid "Per-object selection cue:" +msgstr "Пометка выделенных объектов:" + +#. sorationsnapsperpi == 0 means no snapping +#: ../../po/../src/dialogs/display-settings.cpp:249 +#: ../../po/../src/dialogs/display-settings.cpp:386 +#: ../../po/../src/dialogs/display-settings.cpp:441 +#: ../../po/../src/dialogs/display-settings.cpp:1482 +#: ../../po/../src/dialogs/stroke-style.cpp:791 +#: ../../po/../src/interface.cpp:741 +#: ../../po/../src/ui/widget/selected-style.cpp:100 +#: ../../po/../src/verbs.cpp:1842 +msgid "None" +msgstr "Нет" + +#: ../../po/../src/dialogs/display-settings.cpp:250 +msgid "No per-object selection indication" +msgstr "Выделенные объекты никак не помечены" + +#: ../../po/../src/dialogs/display-settings.cpp:256 +msgid "Mark" +msgstr "Метка" + +#: ../../po/../src/dialogs/display-settings.cpp:257 +msgid "Each selected object has a diamond mark in the top left corner" +msgstr "" +"Каждый выделенный объект имеет метку в виде ромбика в левом верхнем углу" + +#: ../../po/../src/dialogs/display-settings.cpp:264 +msgid "Box" +msgstr "Рамка" + +#: ../../po/../src/dialogs/display-settings.cpp:265 +msgid "Each selected object displays its bounding box" +msgstr "Каждый выделенный объект помечен пунктирной рамкой" + +#: ../../po/../src/dialogs/display-settings.cpp:270 +msgid "Default scale origin:" +msgstr "Неподвижная точка при изменении размера:" + +#: ../../po/../src/dialogs/display-settings.cpp:281 +msgid "Opposite bounding box edge" +msgstr "Противоположный край" + +#: ../../po/../src/dialogs/display-settings.cpp:282 +msgid "Default scale origin will be on the bounding box of the item" +msgstr "" +"По умолчанию, селектор меняет размер объекта относительно противоположного " +"края" + +#: ../../po/../src/dialogs/display-settings.cpp:288 +msgid "Farthest opposite node" +msgstr "Противоположный узел контура" + +#: ../../po/../src/dialogs/display-settings.cpp:289 +msgid "Default scale origin will be on the bounding box of the item's points" +msgstr "" +"По умолчанию, селектор меняет размер объекта относительно противоположного " +"узла контура" + +#: ../../po/../src/dialogs/display-settings.cpp:341 +msgid "degrees" +msgstr "градусов" + +#: ../../po/../src/dialogs/display-settings.cpp:350 +msgid "" +"Rotating with Ctrl pressed snaps every that much degrees; also, pressing " +"[ or ] rotates by this amount" +msgstr "" +"Вращение с нажатым Ctrl ограничивает угол значениями, кратными выбранному; " +"нажатие [ или ] поворачивает на выбранный угол" + +#: ../../po/../src/dialogs/display-settings.cpp:407 +msgid "Rotation snaps every:" +msgstr "Ограничение вращения:" + +#: ../../po/../src/dialogs/display-settings.cpp:430 +msgid "" +"None: dialogs are treated as regular windows; Normal: dialogs stay on top of " +"document windows; Aggressive: same as Normal but may work better with some " +"window managers." +msgstr "" +"Нет: диалоги ведут себя как обычные окна; Обычно: диалоги остаются поверх " +"окон документа; Настойчиво: то же, что и Обычно, но лучше работает с " +"некоторыми оконными менеджерами." + +#: ../../po/../src/dialogs/display-settings.cpp:451 +msgid "Normal" +msgstr "Обычно" + +#: ../../po/../src/dialogs/display-settings.cpp:461 +msgid "Aggressive" +msgstr "Настойчиво" + +#: ../../po/../src/dialogs/display-settings.cpp:475 +msgid "Dialogs on top:" +msgstr "Диалоги поверх окна:" + +#: ../../po/../src/dialogs/display-settings.cpp:645 +msgid "Show selection cue" +msgstr "Показывать пометку выделения" + +#: ../../po/../src/dialogs/display-settings.cpp:646 +msgid "" +"Whether selected objects display a selection cue (the same as in selector)" +msgstr "Будет ли отображаться пометка выделения (как и в селекторе)" + +#: ../../po/../src/dialogs/display-settings.cpp:657 +msgid "Enable gradient editing" +msgstr "Включить правку градиентов" + +#: ../../po/../src/dialogs/display-settings.cpp:658 +msgid "Whether selected objects display gradient editing controls" +msgstr "Будут ли отображаться средства правки градиентов" + +#: ../../po/../src/dialogs/display-settings.cpp:719 +msgid "No objects selected to take the style from." +msgstr "Нет выделенных объектов, откуда можно было бы взять стиль." + +#: ../../po/../src/dialogs/display-settings.cpp:728 +msgid "" +"More than one object selected. Cannot take style from multiple " +"objects." +msgstr "" +"Выделено больше одного объекта. Невозможно взять стиль от нескольких " +"объектов сразу." + +#: ../../po/../src/dialogs/display-settings.cpp:767 +msgid "Create new objects with:" +msgstr "Создать новые объекты с:" + +#: ../../po/../src/dialogs/display-settings.cpp:777 +msgid "Take from selection" +msgstr "Взять от выделения" + +#: ../../po/../src/dialogs/display-settings.cpp:778 +msgid "Remember the style of the (first) selected object as this tool's style" +msgstr "" +"Запомнить стиль (первого) выделенного объекта как стиль данного инструмента" + +#: ../../po/../src/dialogs/display-settings.cpp:782 +#, fuzzy +msgid "Last used style" +msgstr "Вставить стиль" + +#: ../../po/../src/dialogs/display-settings.cpp:782 +msgid "Apply the style you last set on an object" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:790 +msgid "This tool's own style:" +msgstr "Собственный стиль инструмента:" + +#: ../../po/../src/dialogs/display-settings.cpp:790 +msgid "" +"Each tool may store its own style to apply to the newly created objects. Use " +"the button below to set it." +msgstr "" +"Каждый инструмент может использовать свой собственный стиль для создаваемых " +"объектов. Кнопка внизу устанавливает этот стиль." + +#. Mouse +#: ../../po/../src/dialogs/display-settings.cpp:877 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:55 +msgid "Mouse" +msgstr "Мышь" + +#. TRANSLATORS: "Grab" is a noun here. "Grab sensitivity" is intended to mean how +#. * close on the screen you need to be to an object to be able to grab it with mouse (in +#. * pixels). +#: ../../po/../src/dialogs/display-settings.cpp:883 +msgid "Grab sensitivity:" +msgstr "Радиус захвата:" + +#: ../../po/../src/dialogs/display-settings.cpp:884 +msgid "" +"How close on the screen you need to be to an object to be able to grab it " +"with mouse (in screen pixels)" +msgstr "" +"Насколько близко (в пикселах) нужно подвести курсор мыши к объекту, чтобы " +"ухватить его мышью" + +#: ../../po/../src/dialogs/display-settings.cpp:885 +#: ../../po/../src/dialogs/display-settings.cpp:897 +#: ../../po/../src/dialogs/display-settings.cpp:912 +#: ../../po/../src/dialogs/display-settings.cpp:930 +#: ../../po/../src/dialogs/display-settings.cpp:970 +msgid "pixels" +msgstr "пикселов" + +#: ../../po/../src/dialogs/display-settings.cpp:895 +msgid "Click/drag threshold:" +msgstr "Считать щелчком перетаскивание на:" + +#: ../../po/../src/dialogs/display-settings.cpp:896 +msgid "" +"Maximum mouse drag (in screen pixels) which is considered a click, not a drag" +msgstr "" +"Максимальное количество пикселов, перетаскивание на которое\n" +"воспринимается как щелчок, а не как перетаскивание" + +#. Scrolling +#: ../../po/../src/dialogs/display-settings.cpp:907 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:56 +msgid "Scrolling" +msgstr "Прокрутка" + +#: ../../po/../src/dialogs/display-settings.cpp:910 +msgid "Mouse wheel scrolls by:" +msgstr "Колесико мыши прокручивает на:" + +#: ../../po/../src/dialogs/display-settings.cpp:911 +msgid "" +"One mouse wheel notch scrolls by this distance in screen pixels " +"(horizontally with Shift)" +msgstr "" +"На это расстояние в пикселах изображение сдвигается одним щелчком\n" +"колесика мыши (с нажатой клавишей Shift - по горизонтали)" + +#: ../../po/../src/dialogs/display-settings.cpp:920 +msgid "Ctrl+arrows" +msgstr "Ctrl+стрелки" + +#: ../../po/../src/dialogs/display-settings.cpp:928 +msgid "Scroll by:" +msgstr "Шаг прокрутки:" + +#: ../../po/../src/dialogs/display-settings.cpp:929 +msgid "Pressing Ctrl+arrow key scrolls by this distance (in screen pixels)" +msgstr "" +"На это расстояние в пикселах изображение сдвигается при нажатии Ctrl+стрелки" + +#: ../../po/../src/dialogs/display-settings.cpp:939 +msgid "Acceleration:" +msgstr "Ускорение:" + +#: ../../po/../src/dialogs/display-settings.cpp:940 +msgid "" +"Pressing and holding Ctrl+arrow will gradually speed up scrolling (0 for no " +"acceleration)" +msgstr "" +"Если удерживать нажатыми Ctrl+стрелку, скорость прокрутки будет возрастать " +"(0 отменяет ускорение)" + +#: ../../po/../src/dialogs/display-settings.cpp:949 +msgid "Autoscrolling" +msgstr "Автопрокрутка" + +#: ../../po/../src/dialogs/display-settings.cpp:957 +msgid "Speed:" +msgstr "Скорость:" + +#: ../../po/../src/dialogs/display-settings.cpp:958 +msgid "" +"How fast the canvas autoscrolls when you drag beyond canvas edge (0 to turn " +"autoscroll off)" +msgstr "" +"С какой скоростью будет происходить прокрутка при перетаскивании объекта за " +"пределы окна (0 отменяет автопрокрутку)" + +#: ../../po/../src/dialogs/display-settings.cpp:968 +#: ../../po/../src/ui/dialog/tracedialog.cpp:357 +#: ../../po/../src/ui/dialog/tracedialog.cpp:390 +msgid "Threshold:" +msgstr "Порог:" + +#: ../../po/../src/dialogs/display-settings.cpp:969 +msgid "" +"How far (in screen pixels) you need to be from the canvas edge to trigger " +"autoscroll; positive is outside the canvas, negative is within the canvas" +msgstr "" +"Насколько далеко (в пикселах) нужно отстоять от края окна, чтобы\n" +"включилась автопрокрутка; положительные значения - за пределами окна,\n" +"отрицательные - внутри окна" + +#. Steps +#: ../../po/../src/dialogs/display-settings.cpp:979 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:57 +msgid "Steps" +msgstr "Шаги" + +#: ../../po/../src/dialogs/display-settings.cpp:982 +msgid "Arrow keys move by:" +msgstr "Стрелки двигают на:" + +#: ../../po/../src/dialogs/display-settings.cpp:983 +msgid "" +"Pressing an arrow key moves selected object(s) or node(s) by this distance " +"(in px units)" +msgstr "" +"На это расстояние (в SVG пикселах) выделенный объект или\n" +"узел перемещается по нажатию клавиши со стрелкой" + +#: ../../po/../src/dialogs/display-settings.cpp:984 +#: ../../po/../src/dialogs/display-settings.cpp:995 +#: ../../po/../src/dialogs/display-settings.cpp:1006 +#: ../../po/../src/helper/units.cpp:42 +msgid "px" +msgstr "px" + +#: ../../po/../src/dialogs/display-settings.cpp:993 +msgid "> and < scale by:" +msgstr "Шаг масштабирования по > и <:" + +#: ../../po/../src/dialogs/display-settings.cpp:994 +msgid "" +"Pressing > or < scales selection up or down by this increment (in px units)" +msgstr "" +"На эту величину (в SVG пикселах) изменяется размер выделения по нажатию " +"клавиш > и <" + +#: ../../po/../src/dialogs/display-settings.cpp:1004 +msgid "Inset/Outset by:" +msgstr "Втяжка или растяжка на:" + +#: ../../po/../src/dialogs/display-settings.cpp:1005 +msgid "" +"Inset and Outset commands displace the path by this distance (in px units)" +msgstr "" +"На это расстояние (в SVG пикселах) команды втяжки и растяжки смещают контур" + +#: ../../po/../src/dialogs/display-settings.cpp:1017 +msgid "Compass-like display of angles" +msgstr "Компасоподобное отображение углов" + +#. TRANSLATORS: "positive clockwise" means "increasing in clockwise direction" +#: ../../po/../src/dialogs/display-settings.cpp:1019 +msgid "" +"When on, angles are displayed with 0 at north, 0 to 360 range, positive " +"clockwise; otherwise with 0 at east, -180 to 180 range, positive " +"counterclockwise" +msgstr "" +"Если включено, угол со значением 0 показывает на север с диапазоном от 0 до " +"360, причем значение увеличивается по часовой стрелке. В противном случае 0 " +"показывает на восток, диапазон значений находится между -180 и 180, " +"приращение угла происходит против часовой стрелки." + +#: ../../po/../src/dialogs/display-settings.cpp:1026 +msgid "Zoom in/out by:" +msgstr "Шаг масштаба:" + +#: ../../po/../src/dialogs/display-settings.cpp:1027 +msgid "" +"Zoom tool click, +/- keys, and middle click zoom in and out by this " +"multiplier" +msgstr "" +"Шаг для щелчка инструментом масштаба,\n" +"нажатия клавиш +/- и щелчка средней клавишей мыши" + +#: ../../po/../src/dialogs/display-settings.cpp:1028 +#: ../../po/../src/helper/units.cpp:44 +msgid "%" +msgstr "%" + +#. Tools +#: ../../po/../src/dialogs/display-settings.cpp:1037 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:58 +msgid "Tools" +msgstr "Инструменты" + +#: ../../po/../src/dialogs/display-settings.cpp:1045 +msgid "Selector" +msgstr "Селектор" + +#: ../../po/../src/dialogs/display-settings.cpp:1056 +msgid "Node" +msgstr "Узлы" + +#: ../../po/../src/dialogs/display-settings.cpp:1064 +#: ../../po/../src/verbs.cpp:2073 +#: ../../po/../src/widgets/desktop-widget.cpp:277 +msgid "Zoom" +msgstr "Масштаб" + +#. The 4 shape tools +#: ../../po/../src/dialogs/display-settings.cpp:1071 +msgid "Shapes" +msgstr "Фигуры" + +#: ../../po/../src/dialogs/display-settings.cpp:1079 +#: ../../po/../src/verbs.cpp:2055 +msgid "Rectangle" +msgstr "Прямоугольник" + +#: ../../po/../src/dialogs/display-settings.cpp:1085 +#: ../../po/../src/verbs.cpp:2057 +msgid "Ellipse" +msgstr "Эллипс" + +#: ../../po/../src/dialogs/display-settings.cpp:1091 +#: ../../po/../src/verbs.cpp:2059 +msgid "Star" +msgstr "Звезда" + +#: ../../po/../src/dialogs/display-settings.cpp:1097 +#: ../../po/../src/verbs.cpp:2061 +msgid "Spiral" +msgstr "Спираль" + +#: ../../po/../src/dialogs/display-settings.cpp:1111 +#: ../../po/../src/verbs.cpp:2063 +msgid "Pencil" +msgstr "Карандаш" + +#: ../../po/../src/dialogs/display-settings.cpp:1114 +msgid "Tolerance:" +msgstr "Сглаживание:" + +#: ../../po/../src/dialogs/display-settings.cpp:1115 +msgid "" +"This value affects the amount of smoothing applied to freehand lines; lower " +"values produce more uneven paths with more nodes" +msgstr "" +"Это значение определяет степень сглаживания линий, \n" +"нарисованных от руки; чем меньше значение, тем точнее \n" +"соответствие движению руки, но тем больше узлов в контуре." + +#: ../../po/../src/dialogs/display-settings.cpp:1131 +#: ../../po/../src/verbs.cpp:2065 +msgid "Pen" +msgstr "Перо" + +#: ../../po/../src/dialogs/display-settings.cpp:1140 +#: ../../po/../src/verbs.cpp:2067 +msgid "Calligraphy" +msgstr "Каллиграфия" + +#: ../../po/../src/dialogs/display-settings.cpp:1147 +#: ../../po/../src/dialogs/text-edit.cpp:353 +#: ../../po/../src/ui/dialog/text-properties.cpp:37 +#: ../../po/../src/verbs.cpp:2069 +msgid "Text" +msgstr "Текст" + +#: ../../po/../src/dialogs/display-settings.cpp:1157 +#: ../../po/../src/verbs.cpp:2071 +msgid "Gradient" +msgstr "Градиент" + +#: ../../po/../src/dialogs/display-settings.cpp:1164 +#: ../../po/../src/verbs.cpp:2077 +msgid "Connector" +msgstr "Линия соединения" + +#: ../../po/../src/dialogs/display-settings.cpp:1171 +#: ../../po/../src/verbs.cpp:2075 +msgid "Dropper" +msgstr "Пипетка" + +#. Windows +#: ../../po/../src/dialogs/display-settings.cpp:1183 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:59 +msgid "Windows" +msgstr "Окна" + +#: ../../po/../src/dialogs/display-settings.cpp:1188 +msgid "Save window geometry" +msgstr "Сохранять геометрию окон" + +#: ../../po/../src/dialogs/display-settings.cpp:1189 +msgid "" +"Save the window size and position with each document (only for Inkscape SVG " +"format)" +msgstr "" +"Сохранять вместе с документом размер и расположение окна (только для формата " +"Inkscape SVG)" + +#: ../../po/../src/dialogs/display-settings.cpp:1196 +msgid "Dialogs are hidden in taskbar" +msgstr "Диалоги не видны на панели задач" + +#: ../../po/../src/dialogs/display-settings.cpp:1197 +msgid "Whether dialog windows are to be hidden in the window manager taskbar" +msgstr "Убирать ли диалоговые окна из панели задач оконного менеджера" + +#: ../../po/../src/dialogs/display-settings.cpp:1204 +msgid "Zoom when window is resized" +msgstr "Масштабировать при изменении размеров окна" + +#: ../../po/../src/dialogs/display-settings.cpp:1205 +msgid "" +"Zoom drawing when document window is resized, to keep the same area visible " +"(this is the default which can be changed in any window using the button " +"above the right scrollbar)" +msgstr "" +"Масштабировать рисунок при изменении размеров окна, чтобы сохранить видимую " +"область (для каждого окна это можно изменить с помощью кнопки над правой " +"полосой прокрутки)" + +#. Clones +#: ../../po/../src/dialogs/display-settings.cpp:1213 +#: ../../po/../src/dialogs/find.cpp:624 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:60 +msgid "Clones" +msgstr "Клоны" + +#: ../../po/../src/dialogs/display-settings.cpp:1217 +msgid "When the original moves, its clones and linked offsets:" +msgstr "Когда перемещается оригинал, его клоны и потомки:" + +#: ../../po/../src/dialogs/display-settings.cpp:1229 +msgid "Move in parallel" +msgstr "Двигаются параллельно" + +#: ../../po/../src/dialogs/display-settings.cpp:1230 +msgid "Clones are translated by the same vector as their original." +msgstr "Каждый клон сдвигается на тот же вектор, что и его оригинал." + +#: ../../po/../src/dialogs/display-settings.cpp:1237 +msgid "Stay unmoved" +msgstr "Остаются неподвижны" + +#: ../../po/../src/dialogs/display-settings.cpp:1238 +msgid "Clones preserve their positions when their original is moved." +msgstr "Клоны остаются на месте, когда двигаются их оригиналы." + +#: ../../po/../src/dialogs/display-settings.cpp:1245 +msgid "Move according to transform" +msgstr "Двигаются в соответствии с transform=" + +#: ../../po/../src/dialogs/display-settings.cpp:1246 +msgid "" +"Each clone moves according to the value of its transform= attribute. For " +"example, a rotated clone will move in a different direction than its " +"original." +msgstr "" +"Каждый клон двигается в соответствии со значением его атрибута transform=. " +"Например, повернутый клон будет перемещаться в ином направлении, нежели его " +"оригинал." + +#: ../../po/../src/dialogs/display-settings.cpp:1255 +msgid "When the original is deleted, its clones:" +msgstr "Когда оригинал удаляется, его клоны:" + +#: ../../po/../src/dialogs/display-settings.cpp:1267 +msgid "Are unlinked" +msgstr "Отсоединяются" + +#: ../../po/../src/dialogs/display-settings.cpp:1267 +msgid "Orphaned clones are converted to regular objects." +msgstr "Осиротевшие клоны преобразуются в обычные объекты." + +#: ../../po/../src/dialogs/display-settings.cpp:1273 +msgid "Are deleted" +msgstr "Удаляются" + +#: ../../po/../src/dialogs/display-settings.cpp:1273 +msgid "Orphaned clones are deleted along with their original." +msgstr "Осиротевшие клоны удаляются вместе с их оригиналом." + +#. Transforms +#. TRANSLATORS: Noun, i.e. transformations. +#: ../../po/../src/dialogs/display-settings.cpp:1289 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:61 +msgid "Transforms" +msgstr "Трансформации" + +#: ../../po/../src/dialogs/display-settings.cpp:1292 +msgid "Scale stroke width" +msgstr "Менять ширину штриха" + +#: ../../po/../src/dialogs/display-settings.cpp:1293 +#: ../../po/../src/widgets/select-toolbar.cpp:568 +msgid "When scaling objects, scale the stroke width by the same proportion" +msgstr "" +"При изменении размера объектов менять в той же пропорции и ширину штриха" + +#: ../../po/../src/dialogs/display-settings.cpp:1300 +msgid "Scale rounded corners in rectangles" +msgstr "Менять радиус закругленных углов" + +#: ../../po/../src/dialogs/display-settings.cpp:1301 +#: ../../po/../src/widgets/select-toolbar.cpp:580 +msgid "When scaling rectangles, scale the radii of rounded corners" +msgstr "" +"При изменении размера прямоугольников менять в той же пропорции и радиус " +"закругленных углов" + +#: ../../po/../src/dialogs/display-settings.cpp:1308 +msgid "Transform gradients" +msgstr "Трансформировать градиенты" + +#: ../../po/../src/dialogs/display-settings.cpp:1309 +#: ../../po/../src/widgets/select-toolbar.cpp:592 +msgid "Transform gradients (in fill or stroke) along with the objects" +msgstr "Трансформировать градиенты (в заливке или штрихе) вместе с объектом" + +#: ../../po/../src/dialogs/display-settings.cpp:1316 +msgid "Transform patterns" +msgstr "Трансформировать текстуры" + +#: ../../po/../src/dialogs/display-settings.cpp:1317 +#: ../../po/../src/widgets/select-toolbar.cpp:604 +msgid "Transform patterns (in fill or stroke) along with the objects" +msgstr "Трансформировать текстуры (в заливке или штрихе) вместе с объектом" + +#. TRANSLATORS: How to specify the affine transformation in the SVG file. +#: ../../po/../src/dialogs/display-settings.cpp:1327 +msgid "Store transformation:" +msgstr "Сохранение трансформации:" + +#: ../../po/../src/dialogs/display-settings.cpp:1338 +msgid "Optimized" +msgstr "С оптимизацией" + +#: ../../po/../src/dialogs/display-settings.cpp:1339 +msgid "" +"If possible, apply transformation to objects without adding a transform= " +"attribute" +msgstr "" +"По возможности применять трансформацию к объектам без добавления атрибута " +"transform=" + +#: ../../po/../src/dialogs/display-settings.cpp:1346 +msgid "Preserved" +msgstr "Без оптимизации" + +#: ../../po/../src/dialogs/display-settings.cpp:1347 +msgid "Always store transformation as a transform= attribute on objects" +msgstr "Всегда сохранять трансформацию в виде атрибута transform=" + +#. Selecting +#: ../../po/../src/dialogs/display-settings.cpp:1355 +msgid "Selecting" +msgstr "Выделение" + +#: ../../po/../src/dialogs/display-settings.cpp:1357 +msgid "Ctrl+A, Tab, Shift+Tab:" +msgstr "Ctrl+A, Tab, Shift+Tab:" + +#: ../../po/../src/dialogs/display-settings.cpp:1366 +msgid "Select only within current layer" +msgstr "Работают только в текущем слое" + +#: ../../po/../src/dialogs/display-settings.cpp:1367 +msgid "" +"Uncheck this to make keyboard selection commands work on objects in all " +"layers" +msgstr "" +"Отключите эту опцию, если хотите выделять с клавиатуры объекты во всех слоях " +"одновременно " + +#: ../../po/../src/dialogs/display-settings.cpp:1374 +msgid "Ignore hidden objects" +msgstr "Игнорируют скрытые объекты" + +#: ../../po/../src/dialogs/display-settings.cpp:1375 +msgid "" +"Uncheck this to be able to select objects that are hidden (either by " +"themselves or by being in a hidden group or layer)" +msgstr "Отключите эту опцию, если хотите выделять скрытые (невидимые) объекты " + +#: ../../po/../src/dialogs/display-settings.cpp:1382 +msgid "Ignore locked objects" +msgstr "Игнорируют запертые объекты" + +#: ../../po/../src/dialogs/display-settings.cpp:1383 +msgid "" +"Uncheck this to be able to select objects that are locked (either by " +"themselves or by being in a locked group or layer)" +msgstr "Отключите эту опцию, если хотите выделять запертые объекты " + +#. To be broken into: Display, Save, Export, SVG, Commands +#: ../../po/../src/dialogs/display-settings.cpp:1391 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:62 +msgid "Misc" +msgstr "Прочее" + +#: ../../po/../src/dialogs/display-settings.cpp:1394 +msgid "Default export resolution:" +msgstr "Разрешение для экспорта по умолчанию:" + +#: ../../po/../src/dialogs/display-settings.cpp:1395 +msgid "Default bitmap resolution (in dots per inch) in the Export dialog" +msgstr "Разрешение растра (в точках на дюйм) в диалоге экспорта по умолчанию" + +#. FIXME: add "Used for new exports; once exported, documents remember this value on per-object basis" when implemented +#: ../../po/../src/dialogs/display-settings.cpp:1396 +#: ../../po/../src/dialogs/export.cpp:442 +msgid "dpi" +msgstr "dpi" + +#. TRANSLATORS: When on, an imported bitmap creates an element; otherwise it is a +#. * rectangle with bitmap fill. +#: ../../po/../src/dialogs/display-settings.cpp:1407 +msgid "Import bitmap as " +msgstr "Импортировать растровые изображения как " + +#: ../../po/../src/dialogs/display-settings.cpp:1408 +msgid "" +"When on, an imported bitmap creates an element; otherwise it is a " +"rectangle with bitmap fill" +msgstr "" +"С этой опцией импортированное растровое изображение создает элемент ; " +"иначе создается прямоугольник с растровой заливкой" + +#. TRANSLATORS: When on, the print out (currently Postscript) will have +#. * a comment with the each object's label visible, marking the section +#. * of the printing commands that represent the given object. +#: ../../po/../src/dialogs/display-settings.cpp:1418 +msgid "Add label comments to printing output" +msgstr "Добавлять метки в виде комментариев при выводе на печать" + +#: ../../po/../src/dialogs/display-settings.cpp:1419 +msgid "" +"When on, a comment will be added to the raw print output, marking the " +"rendered output for an object with its label" +msgstr "" +"С этой опцией при выводе на печать будут добавляться комментарии, содержащие " +"метки для каждого объекта" + +#. TRANSLATORS: When on, enable the effects menu, default is off +#: ../../po/../src/dialogs/display-settings.cpp:1427 +msgid "Enable script effects (requires restart) - EXPERIMENTAL" +msgstr "Включить меню Эффекты" + +#: ../../po/../src/dialogs/display-settings.cpp:1428 +msgid "" +"When on, the effects menu is enabled, allowing external effect scripts to be " +"called, requires restart before effective - EXPERIMENTAL" +msgstr "" +"Включает меню Эффекты, через которое можно запускать внешние скрипты на " +"обработку документа. Требует перезапуска программы." + +#. TRANSLATORS: The maximum length of the Open Recent list in the File menu. +#: ../../po/../src/dialogs/display-settings.cpp:1436 +msgid "Max recent documents:" +msgstr "Недавних документов в меню:" + +#: ../../po/../src/dialogs/display-settings.cpp:1437 +msgid "The maximum length of the Open Recent list in the File menu" +msgstr "Максимальная длина подменю недавних документов в меню \"Файл\" " + +#: ../../po/../src/dialogs/display-settings.cpp:1447 +msgid "Simplification threshold:" +msgstr "Порог упрощения:" + +#: ../../po/../src/dialogs/display-settings.cpp:1448 +msgid "" +"How strong is the Simplify command by default. If you invoke this command " +"several times in quick succession, it will act more and more aggressively; " +"invoking it again after a pause restores the default threshold." +msgstr "" +"Степень упрощения по команде Упростить. Если вызывать эту команду несколько " +"раз подряд, она будет действовать с каждым разом все более агрессивно; чтобы " +"вернуться к значению по умолчанию, сделайте паузу перед очередным вызовом " +"команды." + +#: ../../po/../src/dialogs/display-settings.cpp:1469 +msgid "Oversample bitmaps:" +msgstr "Усреднять растр по точкам:" + +#: ../../po/../src/dialogs/display-settings.cpp:1488 +msgid "2x2" +msgstr "2x2" + +#: ../../po/../src/dialogs/display-settings.cpp:1494 +msgid "4x4" +msgstr "4x4" + +#: ../../po/../src/dialogs/display-settings.cpp:1500 +msgid "8x8" +msgstr "8x8" + +#: ../../po/../src/dialogs/display-settings.cpp:1506 +msgid "16x16" +msgstr "16x16" + +#. "view_icon_preview" +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2143 +msgid "_Page" +msgstr "_Страница" + +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2147 +msgid "_Drawing" +msgstr "_Рисунок" + +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2149 +msgid "_Selection" +msgstr "_Выделение" + +#: ../../po/../src/dialogs/export.cpp:133 +msgid "_Custom" +msgstr "Нестандартный" + +#: ../../po/../src/dialogs/export.cpp:254 +msgid "Export area" +msgstr "Экспорт области" + +#: ../../po/../src/dialogs/export.cpp:300 +msgid "_x0:" +msgstr "_x0" + +#: ../../po/../src/dialogs/export.cpp:305 +msgid "x_1:" +msgstr "x_1" + +#: ../../po/../src/dialogs/export.cpp:316 +msgid "_y0:" +msgstr "_y0" + +#: ../../po/../src/dialogs/export.cpp:321 +msgid "y_1:" +msgstr "y_1" + +#: ../../po/../src/dialogs/export.cpp:406 +msgid "Bitmap size" +msgstr "Размер изображения" + +#: ../../po/../src/dialogs/export.cpp:416 +msgid "_Width:" +msgstr "Ширина:" + +#: ../../po/../src/dialogs/export.cpp:416 +#: ../../po/../src/dialogs/export.cpp:431 +msgid "pixels at" +msgstr "пикселов при" + +#: ../../po/../src/dialogs/export.cpp:426 +msgid "dp_i" +msgstr "dp_i" + +#: ../../po/../src/dialogs/export.cpp:448 +msgid "_Filename" +msgstr "Имя файла" + +#: ../../po/../src/dialogs/export.cpp:512 +msgid "_Browse..." +msgstr "Выбрать..." + +#: ../../po/../src/dialogs/export.cpp:539 +msgid " _Export " +msgstr "Экспорт" + +#: ../../po/../src/dialogs/export.cpp:541 +msgid "Export the bitmap file with these settings" +msgstr "Экспортировать файл с этими установками" + +#: ../../po/../src/dialogs/export.cpp:968 +msgid "You have to enter a filename" +msgstr "Вы забыли ввести имя файла" + +#: ../../po/../src/dialogs/export.cpp:973 +msgid "The chosen area to be exported is invalid" +msgstr "Недопустимая область для экспорта" + +#: ../../po/../src/dialogs/export.cpp:982 +#, c-format +msgid "Directory %s does not exist or is not a directory.\n" +msgstr "Каталог %s не существует, либо это не каталог.\n" + +#: ../../po/../src/dialogs/export.cpp:998 +msgid "Export in progress" +msgstr "Идет экспорт..." + +#: ../../po/../src/dialogs/export.cpp:1004 +#, c-format +msgid "Exporting %s (%d x %d)" +msgstr "Экспорт %s (%d x %d)" + +#: ../../po/../src/dialogs/export.cpp:1031 +#, c-format +msgid "Could not export to filename %s.\n" +msgstr "Невозможно экспортировать в файл %s.\n" + +#: ../../po/../src/dialogs/export.cpp:1137 +msgid "Select a filename for exporting" +msgstr "Выберите имя файла для экспорта" + +#: ../../po/../src/dialogs/filedialog.cpp:367 +msgid "No preview" +msgstr "Нет предпросмотра" + +#: ../../po/../src/dialogs/filedialog.cpp:468 +msgid "too large for preview" +msgstr "слишком велик для просмотра" + +#: ../../po/../src/dialogs/filedialog.cpp:762 +#: ../../po/../src/dialogs/filedialog.cpp:763 +msgid "All Images" +msgstr "Все изображения" + +#: ../../po/../src/dialogs/filedialog.cpp:767 +#: ../../po/../src/dialogs/filedialog.cpp:768 +msgid "All Files" +msgstr "Все файлы" + +#: ../../po/../src/dialogs/filedialog.cpp:774 +#: ../../po/../src/dialogs/filedialog.cpp:775 +msgid "All Inkscape Files" +msgstr "Все файлы Inkscape" + +#: ../../po/../src/dialogs/filedialog.cpp:1176 +msgid "Guess from extension" +msgstr "Догадаться по расширению" + +#. ###### Add the file types menu +#. createFilterMenu(); +#. ###### Do we want the .xxx extension automatically added? +#: ../../po/../src/dialogs/filedialog.cpp:1261 +msgid "Append filename extension automatically" +msgstr "Добавлять расширение автоматически" + +#. TRANSLATORS: "%s" is replaced with "exact" or "partial" when this string is displayed +#: ../../po/../src/dialogs/find.cpp:378 +#, c-format +msgid "%d object found (out of %d), %s match." +msgid_plural "%d objects found (out of %d), %s match." +msgstr[0] "Найден %d объект (из %d), %s соответствие." +msgstr[1] "Найдено %d объекта (из %d), %s соответствия." +msgstr[2] "Найдено %d объектов (из %d), %s соответствий." + +#: ../../po/../src/dialogs/find.cpp:381 +msgid "exact" +msgstr "точное" + +#: ../../po/../src/dialogs/find.cpp:381 +msgid "partial" +msgstr "частичное" + +#: ../../po/../src/dialogs/find.cpp:388 +msgid "No objects found" +msgstr "Ничего не найдено" + +#: ../../po/../src/dialogs/find.cpp:546 +msgid "T_ype: " +msgstr "_Тип: " + +#: ../../po/../src/dialogs/find.cpp:553 +msgid "Search in all object types" +msgstr "Искать в объектах всех типов" + +#: ../../po/../src/dialogs/find.cpp:553 +msgid "All types" +msgstr "Все типы" + +#: ../../po/../src/dialogs/find.cpp:564 +msgid "Search all shapes" +msgstr "Искать среди всех фигур" + +#: ../../po/../src/dialogs/find.cpp:564 +msgid "All shapes" +msgstr "Все фигуры" + +#: ../../po/../src/dialogs/find.cpp:581 +msgid "Search rectangles" +msgstr "Искать в прямоугольниках" + +#: ../../po/../src/dialogs/find.cpp:581 +msgid "Rectangles" +msgstr "Прямоугольники" + +#: ../../po/../src/dialogs/find.cpp:586 +msgid "Search ellipses, arcs, circles" +msgstr "Искать в эллипсах, секторах, кругах" + +#: ../../po/../src/dialogs/find.cpp:586 +msgid "Ellipses" +msgstr "Эллипсы" + +#: ../../po/../src/dialogs/find.cpp:591 +msgid "Search stars and polygons" +msgstr "Искать в звездах и многоугольниках" + +#: ../../po/../src/dialogs/find.cpp:591 +msgid "Stars" +msgstr "Звезды" + +#: ../../po/../src/dialogs/find.cpp:596 +msgid "Search spirals" +msgstr "Искать в спиралях" + +#: ../../po/../src/dialogs/find.cpp:596 +msgid "Spirals" +msgstr "Спирали" + +#. TRANSLATORS: polyline is a set of connected straight line segments +#. http://www.w3.org/TR/SVG11/shapes.html#PolylineElement +#: ../../po/../src/dialogs/find.cpp:609 +msgid "Search paths, lines, polylines" +msgstr "Искать в контурах, линиях, полилиниях" + +#: ../../po/../src/dialogs/find.cpp:609 +msgid "Paths" +msgstr "Контуры" + +#: ../../po/../src/dialogs/find.cpp:614 +msgid "Search text objects" +msgstr "Искать в текстовых объектах" + +#: ../../po/../src/dialogs/find.cpp:614 +msgid "Texts" +msgstr "Тексты" + +#: ../../po/../src/dialogs/find.cpp:619 +msgid "Search groups" +msgstr "Искать в группах" + +#: ../../po/../src/dialogs/find.cpp:619 +msgid "Groups" +msgstr "Группы" + +#: ../../po/../src/dialogs/find.cpp:624 +msgid "Search clones" +msgstr "Искать в клонах" + +#: ../../po/../src/dialogs/find.cpp:629 +msgid "Search images" +msgstr "Искать в растрах" + +#: ../../po/../src/dialogs/find.cpp:629 +msgid "Images" +msgstr "Растры" + +#: ../../po/../src/dialogs/find.cpp:634 +msgid "Search offset objects" +msgstr "Искать в растяжках" + +#: ../../po/../src/dialogs/find.cpp:634 +msgid "Offsets" +msgstr "Растяжки" + +#: ../../po/../src/dialogs/find.cpp:694 +msgid "_Text: " +msgstr "_Текст: " + +#: ../../po/../src/dialogs/find.cpp:694 +msgid "Find objects by their text content (exact or partial match)" +msgstr "" +"Искать объекты по их текстовому содержанию (полное или частичное " +"соответствие)" + +#: ../../po/../src/dialogs/find.cpp:695 +msgid "_ID: " +msgstr "_ID: " + +#: ../../po/../src/dialogs/find.cpp:695 +msgid "Find objects by the value of the id attribute (exact or partial match)" +msgstr "" +"Искать объекты по значению атрибута id (полное или частичное соответствие)" + +#: ../../po/../src/dialogs/find.cpp:696 +msgid "_Style: " +msgstr "_Стиль: " + +#: ../../po/../src/dialogs/find.cpp:696 +msgid "" +"Find objects by the value of the style attribute (exact or partial match)" +msgstr "" +"Искать объекты по значению атрибута style (полное или частичное соответствие)" + +#: ../../po/../src/dialogs/find.cpp:697 +msgid "_Attribute: " +msgstr "_Атрибут: " + +#: ../../po/../src/dialogs/find.cpp:697 +msgid "Find objects by the name of an attribute (exact or partial match)" +msgstr "Искать объекты по имени атрибута (полное или частичное соответствие)" + +#: ../../po/../src/dialogs/find.cpp:711 +msgid "Search in s_election" +msgstr "Искать в _выделенном" + +#: ../../po/../src/dialogs/find.cpp:715 +msgid "Limit search to the current selection" +msgstr "Ограничить поиск текущим выделением" + +#: ../../po/../src/dialogs/find.cpp:720 +msgid "Search in current _layer" +msgstr "Искать в текущем _слое" + +#: ../../po/../src/dialogs/find.cpp:724 +msgid "Limit search to the current layer" +msgstr "Ограничить поиск текущим слоем" + +#: ../../po/../src/dialogs/find.cpp:729 +msgid "Include _hidden" +msgstr "Включая _скрытые" + +#: ../../po/../src/dialogs/find.cpp:733 +msgid "Include hidden objects in search" +msgstr "Искать среди скрытых объектов" + +#: ../../po/../src/dialogs/find.cpp:738 +msgid "Include l_ocked" +msgstr "Включая _запертые" + +#: ../../po/../src/dialogs/find.cpp:742 +msgid "Include locked objects in search" +msgstr "Искать среди запертых объектов" + +#: ../../po/../src/dialogs/find.cpp:753 +msgid "Clear values" +msgstr "Очистить значения" + +#: ../../po/../src/dialogs/find.cpp:754 +msgid "_Find" +msgstr "_Искать" + +#: ../../po/../src/dialogs/find.cpp:754 +msgid "Select objects matching all of the fields you filled in" +msgstr "Выделить объекты, подходящие по всем указанным критериям поиска" + +#: ../../po/../src/dialogs/iconpreview.cpp:145 +#, c-format +msgid "%d x %d" +msgstr "%d x %d" + +#: ../../po/../src/dialogs/iconpreview.cpp:193 +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:857 +#: ../../po/../src/widgets/desktop-widget.cpp:1069 +msgid "Selection" +msgstr "Выделение" + +#: ../../po/../src/dialogs/iconpreview.cpp:195 +msgid "Selection only or whole document" +msgstr "Либо только выделение, либо весь документ" + +#: ../../po/../src/dialogs/iconpreview.cpp:203 +msgid "Refresh the icons" +msgstr "Обновить пиктограммы" + +#. Create the label for the object id +#: ../../po/../src/dialogs/item-properties.cpp:126 +#: ../../po/../src/dialogs/item-properties.cpp:327 +#: ../../po/../src/dialogs/item-properties.cpp:396 +#: ../../po/../src/dialogs/item-properties.cpp:403 +msgid "_Id" +msgstr "_ID" + +#: ../../po/../src/dialogs/item-properties.cpp:135 +msgid "" +"The id= attribute (only letters, digits, and the characters .-_: allowed)" +msgstr "Атрибут id= (разрешены только латинские буквы, цифры и символы .-_:)" + +#. Button for setting the object's id, label, title and description. +#: ../../po/../src/dialogs/item-properties.cpp:149 +msgid "_Set" +msgstr "Установить" + +#. Create the label for the object label +#: ../../po/../src/dialogs/item-properties.cpp:158 +msgid "_Label" +msgstr "Метка" + +#: ../../po/../src/dialogs/item-properties.cpp:167 +msgid "A freeform label for the object" +msgstr "Произвольная метка объекта" + +#. Create the label for the object title +#: ../../po/../src/dialogs/item-properties.cpp:179 +#: ../../po/../src/dialogs/rdf.cpp:243 +msgid "Title" +msgstr "Название" + +#. Create the frame for the object description +#: ../../po/../src/dialogs/item-properties.cpp:196 +#: ../../po/../src/dialogs/rdf.cpp:287 +msgid "Description" +msgstr "Описание" + +#. Hide +#: ../../po/../src/dialogs/item-properties.cpp:223 +msgid "_Hide" +msgstr "Скрыть" + +#: ../../po/../src/dialogs/item-properties.cpp:224 +msgid "Check to make the object invisible" +msgstr "Сделать этот объект невидимым" + +#. Lock +#. TRANSLATORS: "Lock" is a verb here +#: ../../po/../src/dialogs/item-properties.cpp:233 +msgid "L_ock" +msgstr "Запереть" + +#: ../../po/../src/dialogs/item-properties.cpp:234 +msgid "Check to make the object insensitive (not selectable by mouse)" +msgstr "Сделать этот объект невыделяемым" + +#: ../../po/../src/dialogs/item-properties.cpp:310 +#: ../../po/../src/dialogs/item-properties.cpp:317 +msgid "Ref" +msgstr "Ref" + +#: ../../po/../src/dialogs/item-properties.cpp:398 +msgid "Id invalid! " +msgstr "ID неверен" + +#: ../../po/../src/dialogs/item-properties.cpp:400 +msgid "Id exists! " +msgstr "Такой ID уже есть" + +#: ../../po/../src/dialogs/layer-properties.cpp:50 +msgid "Layer name:" +msgstr "Имя слоя:" + +#: ../../po/../src/dialogs/layer-properties.cpp:133 +msgid "Rename Layer" +msgstr "Переименовать слой" + +#: ../../po/../src/dialogs/layer-properties.cpp:136 +msgid "_Rename" +msgstr "Пере_именовать" + +#. TRANSLATORS: This means "The layer has been renamed" +#: ../../po/../src/dialogs/layer-properties.cpp:147 +msgid "Renamed layer" +msgstr "Переименованный слой" + +#: ../../po/../src/dialogs/layer-properties.cpp:151 +msgid "Add Layer" +msgstr "Добавка слоя" + +#: ../../po/../src/dialogs/layer-properties.cpp:153 +msgid "_Add" +msgstr "_Добавить" + +#: ../../po/../src/dialogs/layer-properties.cpp:167 +msgid "New layer created." +msgstr "Новый слой создан." + +#: ../../po/../src/dialogs/object-attributes.cpp:34 +msgid "Href:" +msgstr "Href:" + +#: ../../po/../src/dialogs/object-attributes.cpp:35 +msgid "Target:" +msgstr "Target:" + +#: ../../po/../src/dialogs/object-attributes.cpp:36 +msgid "Type:" +msgstr "Type:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkRoleAttribute +#. Identifies the type of the related resource with an absolute URI +#: ../../po/../src/dialogs/object-attributes.cpp:39 +msgid "Role:" +msgstr "Role:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkArcRoleAttribute +#. For situations where the nature/role alone isn't enough, this offers an additional URI defining the purpose of the link. +#: ../../po/../src/dialogs/object-attributes.cpp:42 +msgid "Arcrole:" +msgstr "Arcrole:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkTitleAttribute +#: ../../po/../src/dialogs/object-attributes.cpp:44 +msgid "Title:" +msgstr "Title:" + +#: ../../po/../src/dialogs/object-attributes.cpp:45 +msgid "Show:" +msgstr "Show:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkActuateAttribute +#: ../../po/../src/dialogs/object-attributes.cpp:47 +msgid "Actuate:" +msgstr "Actuate:" + +#: ../../po/../src/dialogs/object-attributes.cpp:52 +msgid "URL:" +msgstr "URL:" + +#: ../../po/../src/dialogs/object-attributes.cpp:53 +msgid "X:" +msgstr "X:" + +#: ../../po/../src/dialogs/object-attributes.cpp:54 +msgid "Y:" +msgstr "Y:" + +#: ../../po/../src/dialogs/object-attributes.cpp:98 +#, c-format +msgid "%s attributes" +msgstr "%s атрибутов" + +#: ../../po/../src/dialogs/object-properties.cpp:158 +msgid "_Fill" +msgstr "З_аливка" + +#: ../../po/../src/dialogs/object-properties.cpp:165 +msgid "Stroke _paint" +msgstr "Цвет штриха" + +#: ../../po/../src/dialogs/object-properties.cpp:172 +msgid "Stroke st_yle" +msgstr "Стиль штриха" + +#: ../../po/../src/dialogs/object-properties.cpp:183 +msgid "Master _opacity" +msgstr "Общая прозрачность" + +#: ../../po/../src/dialogs/rdf.cpp:244 +msgid "Name by which this document is formally known." +msgstr "Название, под которым данный документ официально известен." + +#: ../../po/../src/dialogs/rdf.cpp:246 +msgid "Date" +msgstr "Дата" + +#: ../../po/../src/dialogs/rdf.cpp:247 +msgid "Date associated with the creation of this document (YYYY-MM-DD)." +msgstr "Дата, к которой относится создание данного документа (ГГГГ-ММ-ДД)." + +#: ../../po/../src/dialogs/rdf.cpp:249 +msgid "Format" +msgstr "Формат" + +#: ../../po/../src/dialogs/rdf.cpp:250 +msgid "The physical or digital manifestation of this document (MIME type)." +msgstr "Физическое или цифровое представление этого документа (MIME-тип)." + +#: ../../po/../src/dialogs/rdf.cpp:252 +msgid "Type" +msgstr "Тип" + +#: ../../po/../src/dialogs/rdf.cpp:253 +msgid "Type of document (DCMI Type)." +msgstr "Тип документа (тип DCMI)." + +#: ../../po/../src/dialogs/rdf.cpp:256 +msgid "Creator" +msgstr "Создатель" + +#: ../../po/../src/dialogs/rdf.cpp:257 +msgid "" +"Name of entity primarily responsible for making the content of this document." +msgstr "" +"Название организации, в первую очередь ответственной за создание этого " +"документа." + +#: ../../po/../src/dialogs/rdf.cpp:259 +msgid "Rights" +msgstr "Права" + +#: ../../po/../src/dialogs/rdf.cpp:260 +msgid "" +"Name of entity with rights to the Intellectual Property of this document." +msgstr "" +"Название организации, чьей интеллектуальной собственностью является этот " +"документ." + +#: ../../po/../src/dialogs/rdf.cpp:262 +msgid "Publisher" +msgstr "Издатель" + +#: ../../po/../src/dialogs/rdf.cpp:263 +msgid "Name of entity responsible for making this document available." +msgstr "Название организации, ответственной за публикацию этого документа." + +#: ../../po/../src/dialogs/rdf.cpp:266 +msgid "Identifier" +msgstr "Идентификатор" + +#: ../../po/../src/dialogs/rdf.cpp:267 +msgid "Unique URI to reference this document." +msgstr "Уникальный URI для ссылки на этот документ." + +#: ../../po/../src/dialogs/rdf.cpp:269 +msgid "Source" +msgstr "Источник" + +#: ../../po/../src/dialogs/rdf.cpp:270 +msgid "Unique URI to reference the source of this document." +msgstr "Уникальный URI для ссылки на источник этого документа." + +#: ../../po/../src/dialogs/rdf.cpp:272 +msgid "Relation" +msgstr "Смежный" + +#: ../../po/../src/dialogs/rdf.cpp:273 +msgid "Unique URI to a related document." +msgstr "Уникальный URI смежного документа." + +#: ../../po/../src/dialogs/rdf.cpp:275 +msgid "Language" +msgstr "Язык" + +#: ../../po/../src/dialogs/rdf.cpp:276 +msgid "" +"Two-letter language tag with optional subtags for the language of this " +"document. (e.g. 'en-GB')" +msgstr "Двухсимвольный тег языка, возможно с субтегами (например, ru-RU)" + +#: ../../po/../src/dialogs/rdf.cpp:278 +msgid "Keywords" +msgstr "Ключевые слова" + +#: ../../po/../src/dialogs/rdf.cpp:279 +msgid "" +"The topic of this document as comma-separated key words, phrases, or " +"classifications." +msgstr "" +"Тема этого документа в виде списка ключевых слов, фраз или классификаций " +"(через запятую)" + +#. TRANSLATORS: "Coverage": the spatial or temporal characteristics of the content. +#. For info, see Appendix D of http://www.w3.org/TR/1998/WD-rdf-schema-19980409/ +#: ../../po/../src/dialogs/rdf.cpp:283 +msgid "Coverage" +msgstr "Охват" + +#: ../../po/../src/dialogs/rdf.cpp:284 +msgid "Extent or scope of this document." +msgstr "Охват или тематические рамки этого документа." + +#: ../../po/../src/dialogs/rdf.cpp:288 +msgid "A short account of the content of this document." +msgstr "Краткое описание содержимого документа." + +#. FIXME: need to handle 1 agent per line of input +#: ../../po/../src/dialogs/rdf.cpp:292 +msgid "Contributors" +msgstr "Соавторы" + +#: ../../po/../src/dialogs/rdf.cpp:293 +msgid "" +"Names of entities responsible for making contributions to the content of " +"this document." +msgstr "Названия или имена тех, кто внес вклад в создание этого документа." + +#. TRANSLATORS: URL to a page that defines the license for the document +#: ../../po/../src/dialogs/rdf.cpp:297 +msgid "URI" +msgstr "URI" + +#. TRANSLATORS: this is where you put a URL to a page that defines the license +#: ../../po/../src/dialogs/rdf.cpp:299 +msgid "URI to this document's license's namespace definition." +msgstr "URI текста лицензии, применимой к данному документу." + +#. TRANSLATORS: fragment of XML representing the license of the document +#: ../../po/../src/dialogs/rdf.cpp:303 +msgid "Fragment" +msgstr "Фрагмент" + +#: ../../po/../src/dialogs/rdf.cpp:304 +msgid "XML fragment for the RDF 'License' section." +msgstr "XML-фрагмент RDF-раздела \"Лицензия\"." + +#: ../../po/../src/dialogs/stroke-style.cpp:774 +#: ../../po/../src/widgets/gradient-vector.cpp:263 +#: ../../po/../src/widgets/paint-selector.cpp:751 +msgid "No document selected" +msgstr "Документ не выбран" + +#: ../../po/../src/dialogs/stroke-style.cpp:992 +msgid "Stroke width" +msgstr "Толщина штриха" + +#. Join type +#. TRANSLATORS: The line join style specifies the shape to be used at the +#. corners of paths. It can be "miter", "round" or "bevel". +#: ../../po/../src/dialogs/stroke-style.cpp:1015 +msgid "Join:" +msgstr "Соединение:" + +#. TRANSLATORS: Miter join: joining lines with a sharp (pointed) corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1027 +msgid "Miter join" +msgstr "Острое" + +#. TRANSLATORS: Round join: joining lines with a rounded corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1035 +msgid "Round join" +msgstr "Скругленное" + +#. TRANSLATORS: Bevel join: joining lines with a blunted (flattened) corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1043 +msgid "Bevel join" +msgstr "Фаска" + +#. Miterlimit +#. TRANSLATORS: Miter limit: only for "miter join", this limits the length +#. of the sharp "spike" when the lines connect at too sharp an angle. +#. When two line segments meet at a sharp angle, a miter join results in a +#. spike that extends well beyond the connection point. The purpose of the +#. miter limit is to cut off such spikes (i.e. convert them into bevels) +#. when they become too long. +#: ../../po/../src/dialogs/stroke-style.cpp:1054 +msgid "Miter limit:" +msgstr "Предел острия:" + +#: ../../po/../src/dialogs/stroke-style.cpp:1062 +msgid "Maximum length of the miter (in units of stroke width)" +msgstr "Максимальная длина острия (в единицах толщины штриха)" + +#. Cap type +#. TRANSLATORS: cap type specifies the shape for the ends of lines +#: ../../po/../src/dialogs/stroke-style.cpp:1075 +msgid "Cap:" +msgstr "Концы:" + +#. TRANSLATORS: Butt cap: the line shape does not extend beyond the end point +#. of the line; the ends of the line are square +#: ../../po/../src/dialogs/stroke-style.cpp:1086 +msgid "Butt cap" +msgstr "Плоские" + +#. TRANSLATORS: Round cap: the line shape extends beyond the end point of the +#. line; the ends of the line are rounded +#: ../../po/../src/dialogs/stroke-style.cpp:1093 +msgid "Round cap" +msgstr "Круглые" + +#. TRANSLATORS: Square cap: the line shape extends beyond the end point of the +#. line; the ends of the line are square +#: ../../po/../src/dialogs/stroke-style.cpp:1100 +msgid "Square cap" +msgstr "Квадратные" + +#. Dash +#: ../../po/../src/dialogs/stroke-style.cpp:1106 +msgid "Dashes:" +msgstr "Пунктир:" + +#. TRANSLATORS: Path markers are an SVG feature that allows you to attach arbitrary shapes +#. (arrowheads, bullets, faces, whatever) to the start, end, or middle nodes of a path. +#: ../../po/../src/dialogs/stroke-style.cpp:1127 +msgid "Start Markers:" +msgstr "Начальные маркеры:" + +#: ../../po/../src/dialogs/stroke-style.cpp:1137 +msgid "Mid Markers:" +msgstr "Серединные маркеры:" + +#: ../../po/../src/dialogs/stroke-style.cpp:1148 +msgid "End Markers:" +msgstr "Конечные маркеры:" + +#: ../../po/../src/dialogs/swatches.cpp:424 +#, c-format +msgid "Palettes directory (%s) is unavailable." +msgstr "Каталог с палитрами (%s) недоступен." + +#. TODO: Insert widgets +#: ../../po/../src/dialogs/text-edit.cpp:199 +#: ../../po/../src/ui/dialog/text-properties.cpp:36 +msgid "Font" +msgstr "Шрифт" + +#: ../../po/../src/dialogs/text-edit.cpp:216 +msgid "Layout" +msgstr "Размещение" + +#: ../../po/../src/dialogs/text-edit.cpp:229 +msgid "Align lines left" +msgstr "Выровнять строки по левому краю" + +#. TRANSLATORS: `Center' here is a verb. +#: ../../po/../src/dialogs/text-edit.cpp:243 +msgid "Center lines" +msgstr "Центрировать строки" + +#: ../../po/../src/dialogs/text-edit.cpp:256 +msgid "Align lines right" +msgstr "Выровнять строки по правому краю" + +#: ../../po/../src/dialogs/text-edit.cpp:278 +msgid "Horizontal text" +msgstr "Горизонтальный текст" + +#: ../../po/../src/dialogs/text-edit.cpp:292 +msgid "Vertical text" +msgstr "Вертикальный текст" + +#: ../../po/../src/dialogs/text-edit.cpp:307 +msgid "Line spacing:" +msgstr "Межстрочный интервал:" + +#: ../../po/../src/dialogs/text-edit.cpp:400 +msgid "Set as default" +msgstr "Сохранить как умолчание" + +#: ../../po/../src/dialogs/tiledialog.cpp:603 +msgid "Rows:" +msgstr "Строк:" + +#: ../../po/../src/dialogs/tiledialog.cpp:613 +msgid "Number of rows" +msgstr "Количество строк" + +#: ../../po/../src/dialogs/tiledialog.cpp:617 +msgid "Equal height" +msgstr "Одинаковая высота" + +#: ../../po/../src/dialogs/tiledialog.cpp:627 +msgid "If not set, each row has the height of the tallest object in it" +msgstr "" +"Без этой опции каждая строка принимает высоту самого высокого в ней объекта" + +#. #### Radio buttons to control vertical alignment #### +#. #### Radio buttons to control horizontal alignment #### +#: ../../po/../src/dialogs/tiledialog.cpp:637 +#: ../../po/../src/dialogs/tiledialog.cpp:708 +msgid "Align:" +msgstr "Выровнять" + +#: ../../po/../src/dialogs/tiledialog.cpp:672 +msgid " X " +msgstr " X " + +#. #### Number of columns #### +#: ../../po/../src/dialogs/tiledialog.cpp:678 +msgid "Columns:" +msgstr "Столбцов:" + +#: ../../po/../src/dialogs/tiledialog.cpp:688 +msgid "Number of columns" +msgstr "Сколько столбцов в таблице" + +#: ../../po/../src/dialogs/tiledialog.cpp:692 +msgid "Equal width" +msgstr "Одинаковая ширина" + +#: ../../po/../src/dialogs/tiledialog.cpp:701 +msgid "If not set, each column has the width of the widest object in it" +msgstr "" +"Без этой опции каждый столбец принимает ширину самого широкого в нем объекта" + +#. #### Radio buttons to control spacing manually or to fit selection bbox #### +#: ../../po/../src/dialogs/tiledialog.cpp:746 +msgid "Fit into selection box" +msgstr "Сохранить ширину/высоту выделения" + +#: ../../po/../src/dialogs/tiledialog.cpp:753 +msgid "Set spacing:" +msgstr "Установить интервал:" + +#. #### Y Padding #### +#: ../../po/../src/dialogs/tiledialog.cpp:777 +msgid "Row spacing: " +msgstr "Между строк: " + +#: ../../po/../src/dialogs/tiledialog.cpp:786 +msgid "Vertical spacing between rows" +msgstr "Вертикальный интервал между строк" + +#. #### X padding #### +#: ../../po/../src/dialogs/tiledialog.cpp:795 +msgid "Column spacing:" +msgstr "Между столбцов:" + +#: ../../po/../src/dialogs/tiledialog.cpp:804 +msgid "Horizontal spacing between columns" +msgstr "Горизонтальный интервал между столбцами" + +#: ../../po/../src/dialogs/tiledialog.cpp:818 +#, fuzzy +msgid "Arrange selected objects" +msgstr "Сгруппировать выделенные объекты" + +#: ../../po/../src/dialogs/xml-tree.cpp:178 +msgid "Click to select nodes, drag to rearrange." +msgstr "" +"Щелкните мышкой для выделения ветви, перетаскивайте для " +"изменения порядка." + +#: ../../po/../src/dialogs/xml-tree.cpp:189 +msgid "Click attribute to edit." +msgstr "Щелкните мышкой по атрибуту для его редактирования." + +#: ../../po/../src/dialogs/xml-tree.cpp:193 +#, c-format +msgid "" +"Attribute %s selected. Press Ctrl+Enter when done editing to " +"commit changes." +msgstr "" +"Выбран атрибут %s. Нажмите Ctrl+Enter, когда закончите " +"редактирование." + +#: ../../po/../src/dialogs/xml-tree.cpp:284 +msgid "Drag to reorder nodes" +msgstr "Используйте мышь для перетаскивания ветвей" + +#: ../../po/../src/dialogs/xml-tree.cpp:304 +msgid "New element node" +msgstr "Создать ветвь элемента" + +#: ../../po/../src/dialogs/xml-tree.cpp:326 +msgid "New text node" +msgstr "Создать ветвь с текстом" + +#: ../../po/../src/dialogs/xml-tree.cpp:347 +msgid "Duplicate node" +msgstr "Дублировать ветвь" + +#: ../../po/../src/dialogs/xml-tree.cpp:368 +msgid "Delete node" +msgstr "Удалить ветвь" + +#: ../../po/../src/dialogs/xml-tree.cpp:384 +msgid "Unindent node" +msgstr "Переместить к корню" + +#: ../../po/../src/dialogs/xml-tree.cpp:399 +msgid "Indent node" +msgstr "Переместить от корня" + +#: ../../po/../src/dialogs/xml-tree.cpp:411 +msgid "Raise node" +msgstr "Поднять ветвь" + +#: ../../po/../src/dialogs/xml-tree.cpp:423 +msgid "Lower node" +msgstr "Опустить ветвь" + +#: ../../po/../src/dialogs/xml-tree.cpp:468 +msgid "Delete attribute" +msgstr "Удалить атрибут" + +#. TRANSLATORS: "Attribute" is a noun here +#: ../../po/../src/dialogs/xml-tree.cpp:513 +msgid "Attribute name" +msgstr "Имя атрибута" + +#. TRANSLATORS: "Set" is a verb here +#: ../../po/../src/dialogs/xml-tree.cpp:533 +msgid "Set attribute" +msgstr "Установить атрибут" + +#. TRANSLATORS: "Set" is a verb here +#: ../../po/../src/dialogs/xml-tree.cpp:535 +msgid "Set" +msgstr "Установить" + +#. TRANSLATORS: "Attribute" is a noun here +#: ../../po/../src/dialogs/xml-tree.cpp:558 +msgid "Attribute value" +msgstr "Значение атрибута" + +#: ../../po/../src/dialogs/xml-tree.cpp:1318 +msgid "New element node..." +msgstr "Создать ветвь элемента..." + +#: ../../po/../src/dialogs/xml-tree.cpp:1339 +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:100 +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:98 +msgid "Cancel" +msgstr "Отменить" + +#: ../../po/../src/dialogs/xml-tree.cpp:1345 +msgid "Create" +msgstr "Создать" + +#: ../../po/../src/dialogs/xml-tree.cpp:1458 +#, c-format +msgid "" +"Cannot set %s: Another element with value %s already exists!" +msgstr "" +"Невозможно установить %s: существует другой элемент со значением %" +"s!" + +#: ../../po/../src/document.cpp:369 +#, c-format +msgid "New document %d" +msgstr "Новый документ %d" + +#: ../../po/../src/document.cpp:401 +#, c-format +msgid "Memory document %d" +msgstr "Документ в памяти %d" + +#: ../../po/../src/document.cpp:524 +#, c-format +msgid "Unnamed document %d" +msgstr "Безымянный документ %d" + +#. We hit green anchor, closing Green-Blue-Red +#: ../../po/../src/draw-context.cpp:441 +msgid "Path is closed." +msgstr "Контур закрыт." + +#. We hit bot start and end of single curve, closing paths +#: ../../po/../src/draw-context.cpp:456 +msgid "Closing path." +msgstr "Закрываем контур" + +#. alpha of color under cursor, to show in the statusbar +#. locale-sensitive printf is OK, since this goes to the UI, not into SVG +#: ../../po/../src/dropper-context.cpp:354 +#, c-format +msgid " alpha %.3g" +msgstr " альфа %.3g" + +#. where the color is picked, to show in the statusbar +#: ../../po/../src/dropper-context.cpp:356 +#, c-format +msgid ", averaged with radius %d" +msgstr ", усредненный с радиусом %d" + +#: ../../po/../src/dropper-context.cpp:356 +msgid " under cursor" +msgstr " под курсором" + +#. message, to show in the statusbar +#: ../../po/../src/dropper-context.cpp:358 +msgid "Release mouse to set color." +msgstr "Отпустите кнопку мыши для установки цвета." + +#: ../../po/../src/dropper-context.cpp:358 +#: ../../po/../src/tools-switch.cpp:207 +msgid "" +"Click to set fill, Shift+click to set stroke; drag to " +"average color in area; with Alt to pick inverse color; Ctrl+C " +"to copy the color under mouse to clipboard" +msgstr "" +"Щелчок меняет цвет заполнения, Shift+щелчок меняет цвет " +"штриха. Перетаскивание вычисляет средний цвет области. Alt " +"берет инверсный цвет. Ctrl+C копирует в буфер цвет под курсором." + +#: ../../po/../src/extension/dependency.cpp:244 +msgid "Dependency::" +msgstr "Зависит от:" + +#: ../../po/../src/extension/dependency.cpp:245 +msgid " type: " +msgstr " tип: " + +#: ../../po/../src/extension/dependency.cpp:246 +msgid " location: " +msgstr " расположение:" + +#: ../../po/../src/extension/dependency.cpp:247 +msgid " string: " +msgstr " строка:" + +#: ../../po/../src/extension/dependency.cpp:250 +msgid " description: " +msgstr " описание:" + +#. static int i = 0; +#. std::cout << "Checking module[" << i++ << "]: " << name << std::endl; +#: ../../po/../src/extension/extension.cpp:244 +msgid "" +" This is caused by an improper .inx file for this extension. An improper ." +"inx file could have been caused by a faulty installation of Inkscape." +msgstr "" +"Это вызвано неправильным .inx файлом для данного расширения. Неправильный ." +"inx файл мог появиться из-за ошибки при инсталляции Inkscape." + +#: ../../po/../src/extension/extension.cpp:247 +msgid "an ID was not defined for it." +msgstr "ID не был определен." + +#: ../../po/../src/extension/extension.cpp:251 +msgid "there was no name defined for it." +msgstr "не было определено имени." + +#: ../../po/../src/extension/extension.cpp:255 +msgid "the XML description of it got lost." +msgstr "XML описание было потеряно." + +#: ../../po/../src/extension/extension.cpp:259 +msgid "no implementation was defined for the extension." +msgstr "для этого расширения не была определена реализация." + +#. std::cout << "Failed: " << *(_deps[i]) << std::endl; +#: ../../po/../src/extension/extension.cpp:266 +msgid "a dependency was not met." +msgstr "не установлен необходимый для выполнения сценария компонент." + +#: ../../po/../src/extension/extension.cpp:286 +msgid "Extension \"" +msgstr "Расширение \"" + +#: ../../po/../src/extension/extension.cpp:286 +msgid "\" failed to load because " +msgstr "\" не удалось загрузить, потому что " + +#: ../../po/../src/extension/extension.cpp:565 +#, c-format +msgid "Could not create extension error log file '%s'" +msgstr "Невозможно создать файл журнала %s." + +#. This is some filler text, needs to change before relase +#: ../../po/../src/extension/error-file.cpp:56 +msgid "" +"One or more extensions failed to load\n" +"\n" +"The failed extensions have been skipped. Inkscape will continue to run " +"normally but those extensions will be unavailable. For details to " +"troubleshoot this problem, please refer to the error log located at: " +msgstr "" +"Не удалось загрузить одно или " +"несколько расширений\n" +"\n" +"Незагруженные сценарии пропущены. Inkscape будет работать нормально, но эти " +"расширения будут недоступны. Подробности можно найти в файле журнала " +"событий, находящегося здесь:" + +#. This is some filler text, needs to change before relase +#: ../../po/../src/extension/error-file.cpp:65 +msgid "Show dialog on startup" +msgstr "Показывать диалог при запуске" + +#: ../../po/../src/extension/implementation/script.cpp:845 +msgid "" +"Inkscape has received an error from the script that it called. The text " +"returned with the error is included below. Inkscape will continue working, " +"but the action you requested has been cancelled." +msgstr "" +"Inkscape получил ошибку от вызванного им сценария. Возвращенный текст " +"приведен ниже. Inkscape продолжит работу, но запрошенное действие будет " +"отменено." + +#: ../../po/../src/extension/implementation/script.cpp:858 +msgid "" +"Inkscape has received additional data from the script executed. The script " +"did not return an error, but this may indicate the results will not be as " +"expected." +msgstr "" +"Inkscape получил дополнительные данные от выполненного сценария. Сценарий не " +"возвратил ошибки, но это может означать и то, что результаты будут " +"отличаться от ожидаемых." + +#: ../../po/../src/extension/init.cpp:173 +msgid "Null external module directory name. Modules will not be loaded." +msgstr "Нулевое имя каталога с внешними модулями. Модули не будут загружены." + +#: ../../po/../src/extension/init.cpp:187 +#, c-format +msgid "" +"Modules directory (%s) is unavailable. External modules in that directory " +"will not be loaded." +msgstr "" +"Каталог модулей (%s) недоступен. Внешние модули из этого каталога не будут " +"загружены." + +#: ../../po/../src/extension/internal/gnome.cpp:80 +msgid "Select printer" +msgstr "Выберите принтер" + +#: ../../po/../src/extension/internal/gnome.cpp:131 +msgid "Inkscape: Print Preview" +msgstr "Inkscape: Предпросмотр" + +#: ../../po/../src/extension/internal/grid.cpp:213 +msgid "Line Width" +msgstr "Ширина линии" + +#: ../../po/../src/extension/internal/grid.cpp:214 +msgid "Horizontal Spacing" +msgstr "Интервал по горизонтали" + +#: ../../po/../src/extension/internal/grid.cpp:215 +msgid "Vertical Spacing" +msgstr "Интервал по вертикали" + +#: ../../po/../src/extension/internal/grid.cpp:216 +msgid "Horizontal Offset" +msgstr "Сдвиг по горизонтали" + +#: ../../po/../src/extension/internal/grid.cpp:217 +msgid "Vertical Offset" +msgstr "Сдвиг по вертикали" + +#: ../../po/../src/extension/internal/ps.cpp:123 +msgid "Print Destination" +msgstr "Куда печатать" + +#. Print properties frame +#: ../../po/../src/extension/internal/ps.cpp:138 +msgid "Print properties" +msgstr "Свойства печати" + +#: ../../po/../src/extension/internal/ps.cpp:145 +msgid "Print using PostScript operators" +msgstr "Печатать в PostScript" + +#: ../../po/../src/extension/internal/ps.cpp:147 +msgid "" +"Use PostScript vector operators. The resulting image is usually smaller in " +"file size and can be arbitrarily scaled, but alpha transparency and patterns " +"will be lost." +msgstr "" +"Использовать PostScript. Итоговое изображение обычно имеет меньший размер " +"файла и свободно масштабируемо, но альфа-канал и текстуры будут потеряны." + +#: ../../po/../src/extension/internal/ps.cpp:152 +msgid "Print as bitmap" +msgstr "Печатать как растр" + +#: ../../po/../src/extension/internal/ps.cpp:154 +msgid "" +"Print everything as bitmap. The resulting image is usually larger in file " +"size and cannot be arbitrarily scaled without quality loss, but all objects " +"will be rendered exactly as displayed." +msgstr "" +"Напечатать как растр. Как правило, файл будет большего размера, и полученное " +"изображение нельзя будет произвольно масштабировать без потери качества. " +"Однако все графические элементы будут напечатаны так, как они выглядят на " +"экране." + +#: ../../po/../src/extension/internal/ps.cpp:168 +msgid "Preferred resolution (dots per inch) of bitmap" +msgstr "Обычное разрешение растрового изображения (в точках на дюйм)" + +#: ../../po/../src/extension/internal/ps.cpp:182 +msgid "Resolution:" +msgstr "Разрешение:" + +#. Print destination frame +#: ../../po/../src/extension/internal/ps.cpp:186 +msgid "Print destination" +msgstr "Куда печатать" + +#: ../../po/../src/extension/internal/ps.cpp:192 +msgid "" +"Use '> filename' to print to file.\n" +"Use '| prog arg...' to pipe to a program." +msgstr "" +"Используйте '> filename' для печати в файл. \n" +"Используйте '| prog arg' для передачи вывода другой программе." + +#: ../../po/../src/extension/internal/ps.cpp:1227 +msgid "write error occurred" +msgstr "произошла ошибка записи" + +#: ../../po/../src/extension/prefdialog.cpp:21 +msgid " Preferences" +msgstr "Настройки" + +#. We can't call sp_ui_error_dialog because we may be +#. running from the console, in which case calling sp_ui +#. routines will cause a segfault. See bug 1000350 - bryce +#. sp_ui_error_dialog(_("Format autodetect failed. The file is being opened as SVG.")); +#: ../../po/../src/extension/system.cpp:105 +msgid "Format autodetect failed. The file is being opened as SVG." +msgstr "Невозможно определить формат файла. Файл будет открыт как SVG." + +#. TRANSLATORS: default.svg is localizable - this is the name of the default document +#. template. This way you can localize the default pagesize, translate the name of +#. the default layer, etc. If you wish to localize this file, please create a +#. localized share/templates/default.xx.svg file, where xx is your language code. +#: ../../po/../src/file.cpp:133 +msgid "default.svg" +msgstr "default.svg" + +#: ../../po/../src/file.cpp:215 ../../po/../src/file.cpp:900 +#, c-format +msgid "Failed to load the requested file %s" +msgstr "Невозможно загрузить запрошенный файл %s" + +#: ../../po/../src/file.cpp:240 +msgid "Document not saved yet. Cannot revert." +msgstr "Документ еще не был сохранен. Вернуться к сохраненному невозможно." + +#: ../../po/../src/file.cpp:246 +#, c-format +msgid "Changes will be lost! Are you sure you want to reload document %s?" +msgstr "" +"Изменения будут потеряны! Вы уверены, что хотите загрузить документ %s " +"заново?" + +#: ../../po/../src/file.cpp:266 +msgid "Document reverted." +msgstr "Документ возвращен к последнему сохраненному состоянию." + +#: ../../po/../src/file.cpp:268 +msgid "Document not reverted." +msgstr "Документ не возвращен к сохраненному состоянию." + +#: ../../po/../src/file.cpp:382 +msgid "Select file to open" +msgstr "Выберите файл" + +#: ../../po/../src/file.cpp:518 +#, c-format +msgid "Removed %i unused definition in <defs>." +msgid_plural "Removed %i unused definitions in <defs>." +msgstr[0] "Удалено %i ненужное определение в <defs>." +msgstr[1] "Удалено %i ненужных определения в <defs>." +msgstr[2] "Удалено %i ненужных определений в <defs>." + +#: ../../po/../src/file.cpp:523 +msgid "No unused definitions in <defs>." +msgstr "Нет ненужных элементов в <defs>." + +#: ../../po/../src/file.cpp:548 +#, c-format +msgid "" +"No Inkscape extension found to save document (%s). This may have been " +"caused by an unknown filename extension." +msgstr "" +"Не найдено расширение Inkscape для сохранения документа (%s). Возможно, " +"задано неизвестное расширение имени файла." + +#: ../../po/../src/file.cpp:549 ../../po/../src/file.cpp:557 +msgid "Document not saved." +msgstr "Документ не сохранен." + +#: ../../po/../src/file.cpp:556 +#, c-format +msgid "File %s could not be saved." +msgstr "Невозможно сохранить файл %s." + +#: ../../po/../src/file.cpp:566 +msgid "Document saved." +msgstr "Документ сохранен." + +#: ../../po/../src/file.cpp:614 +#, c-format +msgid "drawing%s" +msgstr "рисунок%s" + +#: ../../po/../src/file.cpp:620 +#, c-format +msgid "drawing-%d%s" +msgstr "рисунок-%d%s" + +#: ../../po/../src/file.cpp:655 +msgid "Select file to save to" +msgstr "Выберите файл для сохранения" + +#: ../../po/../src/file.cpp:739 +msgid "No changes need to be saved." +msgstr "Файл не был изменен. Сохранение не требуется." + +#: ../../po/../src/file.cpp:926 +msgid "Select file to import" +msgstr "Выберите файл для импорта" + +#: ../../po/../src/gradient-context.cpp:263 +msgid "Ctrl: snap gradient angle" +msgstr "Ctrl: ограничить угол" + +#: ../../po/../src/gradient-context.cpp:264 +msgid "Shift: draw gradient around the starting point" +msgstr "Shift: рисовать градиент вокруг начальной точки" + +#. We did an undoable action, but sp_document_done will be called by the knot when released +#. status text; we do not track coords because this branch is run once, not all the time +#. during drag +#: ../../po/../src/gradient-context.cpp:462 +#, c-format +msgid "Gradient for %d objects; with Ctrl to snap angle" +msgstr "Градиент для %d объектов; Ctrl ограничивает угол" + +#: ../../po/../src/gradient-context.cpp:464 +msgid "Select objects on which to create gradient." +msgstr "Выделите объекты, к которым будет применен градиент." + +#: ../../po/../src/gradient-drag.cpp:65 +msgid "Linear gradient start" +msgstr "Линейный градиент: начало" + +#. POINT_LG_P1 +#: ../../po/../src/gradient-drag.cpp:66 +msgid "Linear gradient end" +msgstr "Линейный градиент: конец" + +#: ../../po/../src/gradient-drag.cpp:67 +msgid "Radial gradient center" +msgstr "Радиальный градиент: центр" + +#: ../../po/../src/gradient-drag.cpp:68 ../../po/../src/gradient-drag.cpp:69 +msgid "Radial gradient radius" +msgstr "Радиальный градиент: радиус" + +#: ../../po/../src/gradient-drag.cpp:70 +msgid "Radial gradient focus" +msgstr "Радиальный градиент: фокус" + +#: ../../po/../src/gradient-drag.cpp:659 +#, c-format +msgid "" +"%s for: %s%s; drag with Ctrl to snap angle, with Ctrl+Alt to " +"preserve angle, with Ctrl+Shift to scale around center" +msgstr "" +"%s для: %s%s; Ctrl ограничивает угол, Ctrl+Alt фиксирует " +"угол, Ctrl+Shift масштабирует вокруг центра" + +#: ../../po/../src/gradient-drag.cpp:662 +msgid " (stroke)" +msgstr "(штрих)" + +#: ../../po/../src/gradient-drag.cpp:665 +msgid "" +"Radial gradient center and focus; drag with Shift to " +"separate focus" +msgstr "" +"Центр и фокус радиального градиента; перетаскивание с " +"Shift отделяет фокус" + +#: ../../po/../src/gradient-drag.cpp:667 +#, c-format +msgid "" +"Gradient point shared by %d gradients; drag with Shift to " +"separate" +msgstr "" +"Точка градиента, общая для %d градиентов; перетаскивание с Shift разделяет точки" + +#: ../../po/../src/helper/units.cpp:40 +msgid "Unit" +msgstr "Единица" + +#: ../../po/../src/helper/units.cpp:40 +msgid "Units" +msgstr "Единицы" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Point" +msgstr "Пункт" + +#: ../../po/../src/helper/units.cpp:41 +msgid "pt" +msgstr "pt" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Points" +msgstr "Пункты" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Pt" +msgstr "Pt" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Pixel" +msgstr "Пиксел" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Pixels" +msgstr "Пиксели" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Px" +msgstr "Px" + +#. You can add new elements from this point forward +#: ../../po/../src/helper/units.cpp:44 ../share/extensions/straightseg.inx.h:2 +msgid "Percent" +msgstr "Процент" + +#: ../../po/../src/helper/units.cpp:44 +msgid "Percents" +msgstr "Проценты" + +#: ../../po/../src/helper/units.cpp:45 +msgid "Millimeter" +msgstr "Миллиметр" + +#: ../../po/../src/helper/units.cpp:45 +msgid "mm" +msgstr "mm" + +#: ../../po/../src/helper/units.cpp:45 +msgid "Millimeters" +msgstr "Миллиметры" + +#: ../../po/../src/helper/units.cpp:46 +msgid "Centimeter" +msgstr "Сантиметр" + +#: ../../po/../src/helper/units.cpp:46 +msgid "cm" +msgstr "cm" + +#: ../../po/../src/helper/units.cpp:46 +msgid "Centimeters" +msgstr "Сантиметры" + +#: ../../po/../src/helper/units.cpp:47 +msgid "Meter" +msgstr "Метр" + +#: ../../po/../src/helper/units.cpp:47 +msgid "m" +msgstr "m" + +#: ../../po/../src/helper/units.cpp:47 +msgid "Meters" +msgstr "Метры" + +#. no svg_unit +#: ../../po/../src/helper/units.cpp:48 +msgid "Inch" +msgstr "Дюйм" + +#: ../../po/../src/helper/units.cpp:48 +msgid "in" +msgstr "in" + +#: ../../po/../src/helper/units.cpp:48 +msgid "Inches" +msgstr "Дюймы" + +#. Volatiles do not have default, so there are none here +#. TRANSLATORS: for info, see http://www.w3.org/TR/REC-CSS2/syndata.html#length-units +#: ../../po/../src/helper/units.cpp:51 +msgid "Em square" +msgstr "Em square" + +#: ../../po/../src/helper/units.cpp:51 +msgid "em" +msgstr "em" + +#: ../../po/../src/helper/units.cpp:51 +msgid "Em squares" +msgstr "Em squares" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/REC-CSS2/syndata.html#length-units +#: ../../po/../src/helper/units.cpp:53 +msgid "Ex square" +msgstr "Ex square" + +#: ../../po/../src/helper/units.cpp:53 +msgid "ex" +msgstr "ex" + +#: ../../po/../src/helper/units.cpp:53 +msgid "Ex squares" +msgstr "Ex squares" + +#: ../../po/../src/inkscape.cpp:468 +msgid "Untitled document" +msgstr "Без названия" + +#. Show nice dialog box +#: ../../po/../src/inkscape.cpp:497 +msgid "Inkscape encountered an internal error and will close now.\n" +msgstr "Внутренняя ошибка. Inkscape придется закрыть.\n" + +#: ../../po/../src/inkscape.cpp:498 +msgid "" +"Automatic backups of unsaved documents were done to the following " +"locations:\n" +msgstr "" +"Выполнено автоматическое резервное копирование несохраненных документов:\n" + +#: ../../po/../src/inkscape.cpp:499 +msgid "Automatic backup of the following documents failed:\n" +msgstr "Не получилось сохранить резервную копию следующего документа:\n" + +#: ../../po/../src/inkscape.cpp:634 +#, c-format +msgid "" +"Cannot create directory %s.\n" +"%s" +msgstr "" +"Невозможно создать каталог %s.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:635 +#, c-format +msgid "" +"%s is not a valid directory.\n" +"%s" +msgstr "" +"%s не является каталогом.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:636 +#, c-format +msgid "" +"Cannot create file %s.\n" +"%s" +msgstr "" +"Невозможно создать файл %s.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:637 +#, c-format +msgid "" +"Cannot write file %s.\n" +"%s" +msgstr "" +"Невозможно записывать в файл %s.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:638 +msgid "" +"Although Inkscape will run, it will use default settings,\n" +"and any changes made in preferences will not be saved." +msgstr "" +"Inkscape будет работать с настройками по умолчанию. Измененные настройки не " +"будут сохранены." + +#: ../../po/../src/inkscape.cpp:708 +#, c-format +msgid "" +"%s is not a regular file.\n" +"%s" +msgstr "" +"%s не является обычным файлом.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:709 +#, c-format +msgid "" +"%s not a valid XML file, or\n" +"you don't have read permissions on it.\n" +"%s" +msgstr "" +"%s не является XML-файлом либо\n" +"у вас нет прав на его изменение.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:711 +#, c-format +msgid "" +"%s is not a valid menus file.\n" +"%s" +msgstr "" +"%s не является корректным файлом меню.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:712 +msgid "" +"Inkscape will run with default menus.\n" +"New menus will not be saved." +msgstr "" +"Inkscape будет использовать меню \n" +"по умолчанию. Измененные настройки\n" +" не будут сохранены." + +#. sp_ui_menu_append_check_item_from_verb(m, view, _("_Menu"), _("Show or hide the menu bar"), "menu", +#. checkitem_toggled, checkitem_update, 0); +#: ../../po/../src/interface.cpp:753 +msgid "Commands Bar" +msgstr "Панель команд" + +#: ../../po/../src/interface.cpp:753 +msgid "Show or hide the Commands bar (under the menu)" +msgstr "Показать/скрыть панель команд (под меню)" + +#: ../../po/../src/interface.cpp:755 +msgid "Tool Controls" +msgstr "Настройки инструментов" + +#: ../../po/../src/interface.cpp:755 +msgid "Show or hide the Tool Controls panel" +msgstr "Показать/скрыть панель с настройками инструментов" + +#: ../../po/../src/interface.cpp:757 +msgid "_Toolbox" +msgstr "_Панель инструментов" + +#: ../../po/../src/interface.cpp:757 +msgid "Show or hide the main toolbox (on the left)" +msgstr "Показать/скрыть главную панель инструментов (слева)" + +#: ../../po/../src/interface.cpp:763 +msgid "_Statusbar" +msgstr "_Строка состояния" + +#: ../../po/../src/interface.cpp:763 +msgid "Show or hide the statusbar (at the bottom of the window)" +msgstr "Показать/скрыть строку состояния (внизу окна)" + +#: ../../po/../src/interface.cpp:820 +#, c-format +msgid "Verb \"%s\" Unknown" +msgstr "" + +#. TRANSLATORS: #%s is the id of the group e.g. , not a number. +#: ../../po/../src/interface.cpp:930 +#, c-format +msgid "Enter group #%s" +msgstr "Войти в группу #%s" + +#: ../../po/../src/interface.cpp:941 +msgid "Go to parent" +msgstr "На уровень выше" + +#: ../../po/../src/interface.cpp:972 +msgid "Could not parse SVG data" +msgstr "Невозможно прочитать SVG-данные" + +#: ../../po/../src/interface.cpp:1135 +#, c-format +msgid "Overwrite %s" +msgstr "Переписать %s" + +#: ../../po/../src/interface.cpp:1153 +#, c-format +msgid "" +"The file %s already exists. Do you want to overwrite that file with the " +"current document?" +msgstr "Файл %s существует. Записать в этот файл текущий документ?" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:59 +msgid "Jabber connection lost." +msgstr "Jabber-соединение потеряно" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:72 +#, c-format +msgid "Sending message; %u message remaining in send queue." +msgid_plural "Sending message; %u messages remaining in send queue." +msgstr[0] "Посылается сообщение; %u оставшееся в очереди сообщение" +msgstr[1] "Посылается сообщение; %u оставшихся в очереди сообщения" +msgstr[2] "Посылается сообщение; %u оставшихся в очереди сообщений" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:78 +msgid "Receive queue empty." +msgstr "Очередь на прием пуста." + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:154 +#, c-format +msgid "Receiving change; %u change left to process." +msgid_plural "Receiving change; %u changes left to process." +msgstr[0] "Принимается изменение; %u оставшееся изменение для обработки." +msgstr[1] "Принимается изменение; %u оставшихся изменения для обработки." +msgstr[2] "Принимается изменение; %u оставшихся изменений для обработки." + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:157 +#, c-format +msgid "%s has left the chatroom." +msgstr "%s покинул комнату разговоров." + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:221 +msgid "Nickname %1 is already in use. Please choose a different nickname." +msgstr "Псевдоним %1 уже занят другим человеком. Выберите себе другой." + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:225 +msgid "An error was encountered while attempting to connect to the server." +msgstr "Произошла ошибка при попытке соединиться с сервером." + +#. Check to see if the user made any modifications to this document. If so, +#. we want to give them the option of (1) letting us clear their document or (2) +#. opening a new, blank document for the whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:131 +msgid "%1 has invited you to a whiteboard session." +msgstr "%1 пригласил вас на сессию совместного рисования." + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:132 +msgid "Incoming whiteboard invitation from %1" +msgstr "Пришло приглашение порисовать вместе от %1" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:135 +msgid "Do you wish to accept %1's whiteboard session invitation?" +msgstr "" +"Вы хотите принять приглашение %1 на сессию совместного рисования?" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:137 +msgid "" +"Would you like to accept %1's invitation in a new document window?\n" +"Accepting the invitation in your current window will discard unsaved changes." +msgstr "" +"Вы хотите открыть сессию совместного рисования с %1 в новом окне?\n" +"Рисование в текущем документе очистит всю историю изменений." + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:143 +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:198 +msgid "Accept invitation" +msgstr "Принять приглашение" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:144 +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:199 +msgid "Decline invitation" +msgstr "Отклонить приглашение" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:145 +msgid "Accept invitation in new document window" +msgstr "Принять приглашение в новом окне документа" + +#. We could not create a new desktop; ask the user if she or he wants to +#. replace the current document and accept the invitation, or reject the invitation. +#. TRANSLATORS: %1 is a userid here +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:196 +msgid "" +"A new document window could not be opened for a whiteboard session with %" +"1" +msgstr "" +"Не удалось открыть новое окно документа для сессии совместного рисования с " +"%1" + +#. TRANSLATORS: %1 is the peer whom refused our invitation. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:238 +msgid "" +"The user %1 has refused your " +"whiteboard invitation.\n" +"\n" +msgstr "" +"Пользователь %1 отклонил ваше " +"приглашение на сессию совместного рисования.\n" +"\n" + +#. TRANSLATORS: %1 is the peer whom refused our invitation, %2 is our Jabber identity. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:241 +msgid "" +"You are still connected to a Jabber server as %2, and may send an " +"invitation to %1 again, or you may send an invitation to a different " +"user." +msgstr "" +"Вы все еще соединены с Jabber-сервером как пользователь %2 и можете " +"послать приглашение пользователю %1 еще раз или пригласить другого " +"пользователя." + +#. TRANSLATORS: %1 is the peer whom we tried to contact, but is already in a whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:252 +msgid "" +"The user %1 is already in a " +"whiteboard session.\n" +"\n" +msgstr "" +"Пользователь %1 уже рисует с " +"вами.\n" +"\n" + +#. TRANSLATORS: %1 is the peer whom we tried to contact, but is already in a whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:255 +msgid "" +"You are still connected to a Jabber server as %1, and may send an " +"invitation to a different user." +msgstr "" +"Вы все еще соединены с Jabber-сервером как пользователь %1 и можете " +"послать приглашение другому пользователю." + +#: ../../po/../src/jabber_whiteboard/invitation-confirm-dialog.cpp:26 +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:24 +msgid "_Write session file:" +msgstr "_Записать файл сессии:" + +#: ../../po/../src/jabber_whiteboard/message-processors.cpp:145 +#, c-format +msgid "%s has joined the chatroom." +msgstr "%s зашел в комнату для разговоров." + +#: ../../po/../src/jabber_whiteboard/message-queue.cpp:87 +#, c-format +msgid "%u change in receive queue." +msgid_plural "%u changes in receive queue." +msgstr[0] "%u изменение в очереди на получение." +msgstr[1] "%u изменения в очереди на получение." +msgstr[2] "%u изменений в очереди на получение." + +#: ../../po/../src/jabber_whiteboard/message-queue.cpp:117 +#, c-format +msgid "%u change in send queue." +msgid_plural "%u changes in send queue." +msgstr[0] "%u изменение в очереди на отправку." +msgstr[1] "%u изменения в очереди на отправку." +msgstr[2] "%u изменений в очереди на отправку." + +#. if ID is NULL, then we have a real problem -- we were not able to find a key +#. nor generate one. The only thing we can really do here is abort, since we have +#. no way to let the other client(s) uniquely identify this object. +#. FIXME: If this indicates a programming bug, then don't request translation with +#. * _(...): it is most useful in untranslated form so that developers may search for +#. * it when someone reports it in a bug report (as we want users to do for all bugs, +#. * as indicated by it being a g_warning string). +#. * +#. * Otherwise, if it is not a programming bug but a network error or a bug in the +#. * remote peer (perhaps running different software) or whatever, then present it in +#. * an alert box, and avoid use of technical jargon `NULL'. +#. +#: ../../po/../src/jabber_whiteboard/message-utilities.cpp:171 +msgid "" +"ID for new object is NULL even after generation and lookup attempts: the new " +"object will NOT be sent, nor will any of its child objects!" +msgstr "" +"ID нового объекта является NULL даже после попыток создания и поиска: ни " +"новый объект, ни его потомки пересланы НЕ будут" + +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:60 +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:995 +msgid "Select a location and filename" +msgstr "Укажите местоположение и имя файла" + +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:62 +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:997 +msgid "Set filename" +msgstr "Укажите имя файла" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:301 +msgid "No SSL certificate was found." +msgstr "SSL-сертификат не найден" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:304 +msgid "The SSL certificate provided by the Jabber server is untrusted." +msgstr "SSl-сертификату, представленному Jabber-сервером, доверять нельзя." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:307 +msgid "The SSL certificate provided by the Jabber server is expired." +msgstr "Срок действия SSL-сертификата, представленного Jabber-сервером, истек." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:310 +msgid "" +"The SSL certificate provided by the Jabber server has not been activated." +msgstr "SSL-сертификат, представленный Jabber-сервером, не активирован." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:313 +msgid "" +"The SSL certificate provided by the Jabber server contains a hostname that " +"does not match the Jabber server's hostname." +msgstr "" +"SSL-сертификат, представленный Jabber-сервером, содержит имя узла, " +"несовпадающего с именем узла Jabber-сервера." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:316 +msgid "" +"The SSL certificate provided by the Jabber server contains an invalid " +"fingerprint." +msgstr "" +"SSL-сертификат, представленный Jabber-сервером, содержит некорректный " +"fingerprint." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:319 +msgid "An unknown error occurred while setting up the SSL connection." +msgstr "Произошла неизвестная ошибка при установлении SSL-соединения." + +#. TRANSLATORS: %1 is the message that describes the specific error that occurred when +#. establishing the SSL connection. +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:325 +msgid "" +"%1\n" +"\n" +"Do you wish to continue connecting to the Jabber server?" +msgstr "" +"%1\n" +"\n" +"Вы хотите оставить соединение с Jabber-сервером?" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:328 +msgid "Continue connecting and ignore further errors" +msgstr "Оставить соединение и игнорировать дальнейшие ошибки" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:329 +msgid "Continue connecting, but warn me of further errors" +msgstr "Оставить соединение и сообщать о дальнейших ошибках" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:330 +msgid "Cancel connection" +msgstr "Завершить соединение" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:777 +#, c-format +msgid "Established whiteboard session with %s." +msgstr "Установлена сессия совместного рисования с %s." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:785 +#, c-format +msgid "%s has left the whiteboard session." +msgstr "%s прекратил рисование с вами и ушел." + +#. Inform the user +#. TRANSLATORS: %1 is the name of the user that disconnected, %2 is the name of the user whom the disconnected user disconnected from. +#. This message is not used in a chatroom context. +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:790 +msgid "" +"The user %1 has left the " +"whiteboard session.\n" +"\n" +msgstr "" +"Пользователь %1 прекратил " +"рисование с вами и ушел.\n" +"\n" + +#. TRANSLATORS: %1 and %2 are userids +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:792 +msgid "" +"You are still connected to a Jabber server as %2, and may establish a " +"new session to %1 or a different user." +msgstr "" +"Вы все еще соединены с Jabber-сервером как %2 и можете установить " +"новую сессию совместного рисования с %1 или другим пользователем." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:988 +msgid "" +"Could not open file %1 for session recording.\n" +"The error encountered was: %2.\n" +"\n" +"You may select a different location to record the session, or you may opt to " +"not record this session." +msgstr "" +"Не удалось открыть файл %1 для записи сессии.\n" +"Обнаружена следующая ошибка: %2.\n" +"\n" +"Вы можете выбрать другое местоположение для записи сессии или не записывать " +"сессию вовсе." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:990 +msgid "Choose a different location" +msgstr "Выберите другой каталог" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:991 +msgid "Skip session recording" +msgstr "Пропустить запись сессии" + +#: ../../po/../src/knot.cpp:673 +msgid "Node or handle drag canceled." +msgstr "Перемещение отменено." + +#: ../../po/../src/libnrtype/FontFactory.cpp:358 +msgid "Ignoring font without family that will crash Pango" +msgstr "Игнорирование шрифта без гарнитуры приведет к обрушиванию Pango" + +#: ../../po/../src/main.cpp:395 +msgid "Print the Inkscape version number" +msgstr "Напечатать версию Inkscape" + +#: ../../po/../src/main.cpp:400 +msgid "Do not use X server (only process files from console)" +msgstr "Не использовать X сервер (допустимы только консольные операции)" + +#: ../../po/../src/main.cpp:405 +msgid "Try to use X server (even if $DISPLAY is not set)" +msgstr "" +"Пытаться использовать X сервер (даже если переменная $DISPLAY не установлена)" + +#: ../../po/../src/main.cpp:410 +msgid "Open specified document(s) (option string may be excluded)" +msgstr "Открыть указанные документы" + +#: ../../po/../src/main.cpp:411 ../../po/../src/main.cpp:416 +#: ../../po/../src/main.cpp:421 ../../po/../src/main.cpp:483 +#: ../../po/../src/main.cpp:488 ../../po/../src/main.cpp:493 +msgid "FILENAME" +msgstr "FILENAME" + +#: ../../po/../src/main.cpp:415 +msgid "Print document(s) to specified output file (use '| program' for pipe)" +msgstr "" +"Напечатать документ(ы) в указанный файл (используйте '| program' для " +"передачи программе)" + +#: ../../po/../src/main.cpp:420 +msgid "Export document to a PNG file" +msgstr "Экспортировать документ в файл PNG" + +#: ../../po/../src/main.cpp:425 +msgid "The resolution used for exporting SVG into bitmap (default 90)" +msgstr "Разрешение, используемое для экспорта SVG в растр (по умолчанию 90)" + +#: ../../po/../src/main.cpp:426 +msgid "DPI" +msgstr "DPI" + +#: ../../po/../src/main.cpp:430 +msgid "" +"Exported area in SVG user units (default is the canvas; 0,0 is lower-left " +"corner)" +msgstr "" +"Экспортируемая область в SVG пользовательских единицах измерения (по " +"умолчанию - вся канва; 0,0 - левый нижний угол)" + +#: ../../po/../src/main.cpp:431 +msgid "x0:y0:x1:y1" +msgstr "x0:y0:x1:y1" + +#: ../../po/../src/main.cpp:435 +msgid "Exported area is the entire drawing (not canvas)" +msgstr "Экспортируемая область включает в себя весь рисунок (а не страницу)" + +#: ../../po/../src/main.cpp:440 +msgid "" +"Snap the bitmap export area outwards to the nearest integer values (in SVG " +"user units)" +msgstr "" +"Расширить область экспортируемого растра до ближайших целых значений (в SVG " +"единицах)" + +#: ../../po/../src/main.cpp:445 +msgid "The width of exported bitmap in pixels (overrides export-dpi)" +msgstr "Ширина экспортируемого растра в точках (отменяет export-dpi)" + +#: ../../po/../src/main.cpp:446 +msgid "WIDTH" +msgstr "WIDTH" + +#: ../../po/../src/main.cpp:450 +msgid "The height of exported bitmap in pixels (overrides export-dpi)" +msgstr "Высота экспортируемого растра в точках (отменяет export-dpi)" + +#: ../../po/../src/main.cpp:451 +msgid "HEIGHT" +msgstr "HEIGHT" + +#: ../../po/../src/main.cpp:455 +msgid "The ID of the object to export (overrides export-area)" +msgstr "Идентификатор экспортируемого объекта (отменяет export-area)" + +#: ../../po/../src/main.cpp:456 ../../po/../src/main.cpp:532 +msgid "ID" +msgstr "ID" + +#. TRANSLATORS: this means: "Only export the object whose id is given in --export-id". +#. See "man inkscape" for details. +#: ../../po/../src/main.cpp:462 +msgid "" +"Export just the object with export-id, hide all others (only with export-id)" +msgstr "" +"Экспортировать только объект с заданным export-id, скрыв все прочие объекты " +"(только с опцией export-id)" + +#: ../../po/../src/main.cpp:467 +msgid "Use stored filename and DPI hints when exporting (only with export-id)" +msgstr "" +"Использовать сохраненное имя файла и разрешение при экспорте (только с " +"опцией export-id)" + +#: ../../po/../src/main.cpp:472 +msgid "Background color of exported bitmap (any SVG-supported color string)" +msgstr "" +"Фоновый цвет для экспорта растра (любая поддерживаемая в SVG цветовая строка)" + +#: ../../po/../src/main.cpp:473 +msgid "COLOR" +msgstr "COLOR" + +#: ../../po/../src/main.cpp:477 +msgid "Background opacity of exported bitmap (either 0.0 to 1.0, or 1 to 255)" +msgstr "" +"Непрозрачность фона для экспорта растра (от 0.0 до 1.0 либо от 1 до 255)" + +#: ../../po/../src/main.cpp:478 +msgid "VALUE" +msgstr "VALUE" + +#: ../../po/../src/main.cpp:482 +msgid "Export document to plain SVG file (no sodipodi or inkscape namespaces)" +msgstr "" +"Экспортировать документ в формат \"чистый SVG\" (без элементов sodipodi: или " +"inkscape:)" + +#: ../../po/../src/main.cpp:487 +msgid "Export document to a PS file" +msgstr "Экспортировать документ в файл PS" + +#: ../../po/../src/main.cpp:492 +msgid "Export document to an EPS file" +msgstr "Экспортировать документ в файл EPS" + +#: ../../po/../src/main.cpp:497 +msgid "Convert text object to paths on export (EPS)" +msgstr "Перевести текст в контуры при экспорте (EPS)" + +#: ../../po/../src/main.cpp:502 +msgid "Export files with the bounding box set to the page size (EPS)" +msgstr "" +"При экспорте установить значение BoundingBox равным размеру страницы, а не " +"рисунка (EPS)" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:508 +msgid "" +"Query the X coordinate of the drawing or, if specified, of the object with --" +"query-id" +msgstr "Запросить X координату рисунка или, если задано, объекта с --query-id" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:514 +msgid "" +"Query the Y coordinate of the drawing or, if specified, of the object with --" +"query-id" +msgstr "Запросить Y координату рисунка или, если задано, объекта с --query-id" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:520 +msgid "" +"Query the width of the drawing or, if specified, of the object with --query-" +"id" +msgstr "Запросить ширину рисунка или, если задано, объекта с --query-id" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:526 +msgid "" +"Query the height of the drawing or, if specified, of the object with --query-" +"id" +msgstr "Запросить высоту рисунка или, если задано, объекта с --query-id" + +#: ../../po/../src/main.cpp:531 +msgid "The ID of the object whose dimensions are queried" +msgstr "Идентификатор объекта для запроса" + +#. TRANSLATORS: this option makes Inkscape print the name (path) of the extension directory +#: ../../po/../src/main.cpp:537 +msgid "Print out the extension directory and exit" +msgstr "Вывести на экран каталог расширения и выйти" + +#: ../../po/../src/main.cpp:542 +msgid "Show given files one-by-one, switch to next on any key/mouse event" +msgstr "" +"Показать данные файлы один за другим, переключаясь на следующий по нажатию " +"любой клавиши или кнопки мыши" + +#: ../../po/../src/main.cpp:547 +msgid "Use the new Gtkmm GUI interface" +msgstr "Использовать новый GUI на Gtkmm" + +#: ../../po/../src/main.cpp:552 +msgid "Remove unused definitions from the defs section(s) of the document" +msgstr "Убрать лишние определения из раздела <defs> документа" + +#: ../../po/../src/main.cpp:741 +msgid "" +"[OPTIONS...] [FILE...]\n" +"\n" +"Available options:" +msgstr "" +"[ПАРАМЕТРЫ...] [ФАЙЛ...]\n" +"\n" +"Доступные параметры:" + +#: ../../po/../src/menus-skeleton.h:17 +msgid "_New" +msgstr "_Новый" + +#: ../../po/../src/menus-skeleton.h:22 +msgid "Open _Recent" +msgstr "Открыть _недавние" + +#: ../../po/../src/menus-skeleton.h:53 +msgid "_Edit" +msgstr "_Правка" + +#: ../../po/../src/menus-skeleton.h:84 +msgid "_View" +msgstr "_Вид" + +#: ../../po/../src/menus-skeleton.h:85 +#, fuzzy +msgid "_Zoom" +msgstr "Масштаб" + +#: ../../po/../src/menus-skeleton.h:102 +msgid "Show/Hide" +msgstr "Показать или спрятать" + +#: ../../po/../src/menus-skeleton.h:107 +msgid "_Display mode" +msgstr "" + +#: ../../po/../src/menus-skeleton.h:126 +msgid "_Layer" +msgstr "С_лой" + +#: ../../po/../src/menus-skeleton.h:143 +msgid "_Object" +msgstr "_Объект" + +#: ../../po/../src/menus-skeleton.h:165 +msgid "_Path" +msgstr "_Контуры" + +#: ../../po/../src/menus-skeleton.h:188 +msgid "_Text" +msgstr "_Текст" + +#: ../../po/../src/menus-skeleton.h:200 +msgid "Effects" +msgstr "Эффекты" + +#: ../../po/../src/menus-skeleton.h:207 +msgid "Whiteboa_rd" +msgstr "_Доска" + +#: ../../po/../src/menus-skeleton.h:220 +msgid "_Help" +msgstr "_Справка" + +#: ../../po/../src/menus-skeleton.h:222 +msgid "Tutorials" +msgstr "Учебники" + +#: ../../po/../src/node-context.cpp:382 +msgid "" +"Ctrl: toggle node type, snap handle angle, move hor/vert; Ctrl" +"+Alt: move along handles" +msgstr "" +"Ctrl: сменить тип узла, ограничить угол уса, двигать по горизонтали/" +"вертикали; Ctrl+Alt: двигать вдоль уса или прямого фрагмента" + +#: ../../po/../src/node-context.cpp:383 +msgid "" +"Shift: toggle node selection, disable snapping, rotate both handles" +msgstr "" +"Shift: выделить/развыделить узел, отключить прилипание, вращать оба " +"уса" + +#: ../../po/../src/node-context.cpp:384 +msgid "Alt: lock handle length; Ctrl+Alt: move along handles" +msgstr "" +"Alt: зафиксировать длину уса; Ctrl+Alt: двигать вдоль усов" + +#: ../../po/../src/nodepath.cpp:1399 ../../po/../src/nodepath.cpp:1411 +#: ../../po/../src/nodepath.cpp:1492 ../../po/../src/nodepath.cpp:1504 +msgid "To join, you must have two endnodes selected." +msgstr "Для соединения выделите два оконечных узла." + +#: ../../po/../src/nodepath.cpp:1633 ../../po/../src/nodepath.cpp:1647 +msgid "" +"Select two non-endpoint nodes on a path between which to delete " +"segments." +msgstr "" +"Выделите два неоконечных узла контура, чтобы удалить сегменты между " +"ними" + +#: ../../po/../src/nodepath.cpp:1743 +msgid "Cannot find path between nodes." +msgstr "Невозможно найти контур между узлами." + +#: ../../po/../src/nodepath.cpp:2822 +#, c-format +msgid "" +"Node handle: angle %0.2f°, length %s; with Ctrl to snap " +"angle; with Alt to lock length; with Shift to rotate both " +"handles" +msgstr "" +"Ус узла под углом %0.2f°, длина %s; перетаскивание с Ctrl " +"ограничивает угол; с Alt фиксирует длину; с Shift синхронно " +"вращает противоположный ус" + +#: ../../po/../src/nodepath.cpp:3351 +msgid "" +"Node: drag to edit the path; with Ctrl to snap to horizontal/" +"vertical; with Ctrl+Alt to snap to handles' directions" +msgstr "" +"Узел: перетаскивание при нажатой клавише Ctrl - с прилипанием " +"по горизонтали/вертикали; с Ctrl+Alt - вдоль усов" + +#: ../../po/../src/nodepath.cpp:3375 +msgid "" +"Node handle: drag to shape the curve; with Ctrl to snap angle; " +"with Alt to lock length; with Shift to rotate both handles" +msgstr "" +"Ус узла: перетаскивание с Ctrl ограничивает угол; с Alt " +"фиксирует длину; с Shift синхронно вращает противоположный ус" + +#: ../../po/../src/nodepath.cpp:3399 +msgid "" +"Node handle: drag to shape the curve; with Ctrl to snap angle; " +"with Alt to lock length; with Shift to rotate the opposite " +"handle in sync" +msgstr "" +"Ус узла: перетаскивание с Ctrl ограничивает угол; с Alt " +"фиксирует длину; с Shift синхронно вращает противоположный ус" + +#. TRANSLATORS: "end" is an adjective here (NOT a verb) +#: ../../po/../src/nodepath.cpp:3591 +msgid "end node" +msgstr "оконечный узел" + +#. TRANSLATORS: "cusp" means "sharp" (cusp node); see also the Advanced Tutorial +#: ../../po/../src/nodepath.cpp:3596 +msgid "cusp" +msgstr "острый" + +#. TRANSLATORS: "smooth" is an adjective here +#: ../../po/../src/nodepath.cpp:3599 +msgid "smooth" +msgstr "гладкий" + +#: ../../po/../src/nodepath.cpp:3601 +msgid "symmetric" +msgstr "симметричный" + +#. TRANSLATORS: "end" is an adjective here (NOT a verb) +#: ../../po/../src/nodepath.cpp:3607 +msgid "end node, handle retracted (drag with Shift to extend)" +msgstr "оконечный узел, ус втянут (вытаскивается с Shift)" + +#: ../../po/../src/nodepath.cpp:3609 +msgid "one handle retracted (drag with Shift to extend)" +msgstr "один ус втянут (вытаскивается с Shift)" + +#: ../../po/../src/nodepath.cpp:3612 +msgid "both handles retracted (drag with Shift to extend)" +msgstr "оба уса втянуты (вытаскиваются с Shift)" + +#: ../../po/../src/nodepath.cpp:3624 +msgid "Drag nodes or node handles; arrow keys to move nodes" +msgstr "Перетаскивайте узлы или усы; клавиши-стрелки двигают выделенные узлы" + +#: ../../po/../src/nodepath.cpp:3625 +msgid "Drag the node or its handles; arrow keys to move the node" +msgstr "Перетаскивайте узел или его усы; клавиши-стрелки двигают узел" + +#: ../../po/../src/nodepath.cpp:3651 ../../po/../src/nodepath.cpp:3663 +msgid "Select a single object to edit its nodes or handles." +msgstr "Выберите один объект для изменения его узлов или усов." + +#: ../../po/../src/nodepath.cpp:3655 +#, c-format +msgid "" +"0 out of %i node selected. Click, Shift+click, " +"or drag around nodes to select." +msgid_plural "" +"0 out of %i nodes selected. Click, Shift+click, " +"or drag around nodes to select." +msgstr[0] "" +"Выделен 0 из %i узлов. Чтобы выделить узлы, используйте " +"щелчок, Shift+щелчок, либо обведение рамкой." +msgstr[1] "" +"Выделено 0 из %i узлов. Чтобы выделить узлы, используйте " +"щелчок, Shift+щелчок, либо обведение рамкой." +msgstr[2] "" +"Выделено 0 из %i узлов. Чтобы выделить узлы, используйте " +"щелчок, Shift+щелчок, либо обведение рамкой." + +#: ../../po/../src/nodepath.cpp:3661 +msgid "Drag the handles of the object to modify it." +msgstr "Двигайте ручки фигуры, чтобы изменить ее." + +#: ../../po/../src/nodepath.cpp:3669 +#, c-format +msgid "%i of %i node selected; %s. %s." +msgid_plural "%i of %i nodes selected; %s. %s." +msgstr[0] "%i из %i узла выделен; %s. %s." +msgstr[1] "%i из %i узлов выделено; %s. %s." +msgstr[2] "%i из %i узлов выделено; %s. %s." + +#: ../../po/../src/nodepath.cpp:3675 +#, c-format +msgid "%i of %i node selected. %s." +msgid_plural "%i of %i nodes selected. %s." +msgstr[0] "%i из %i узла выделен. %s." +msgstr[1] "%i из %i узлов выделено. %s." +msgstr[2] "%i из %i узлов выделено. %s." + +#: ../../po/../src/object-edit.cpp:493 +msgid "" +"Adjust the horizontal rounding radius; with Ctrl to make the " +"vertical radius the same" +msgstr "" +"Менять горизонтальный радиус закругления. С Ctrl вертикальный " +"радиус будет таким же." + +#: ../../po/../src/object-edit.cpp:499 +msgid "" +"Adjust the vertical rounding radius; with Ctrl to make the " +"horizontal radius the same" +msgstr "" +"Менять вертикальный радиус закругления. С Ctrl горизонтальный " +"радиус будет таким же." + +#: ../../po/../src/object-edit.cpp:506 ../../po/../src/object-edit.cpp:513 +msgid "" +"Adjust the width and height of the rectangle; with Ctrl to " +"lock ratio or stretch in one dimension only" +msgstr "" +"Менять ширину и высоту прямоугольника. Ctrl фиксирует " +"отношение либо растягивает/сжимает только по одному измерению." + +#: ../../po/../src/object-edit.cpp:686 +msgid "Adjust ellipse width, with Ctrl to make circle" +msgstr "Менять большую ось эллипса. Ctrl дает круг." + +#: ../../po/../src/object-edit.cpp:689 +msgid "Adjust ellipse height, with Ctrl to make circle" +msgstr "Менять малую ось эллипса. Ctrl дает круг." + +#: ../../po/../src/object-edit.cpp:692 +msgid "" +"Position the start point of the arc or segment; with Ctrl to " +"snap angle; drag inside the ellipse for arc, outside for " +"segment" +msgstr "" +"Начальная точка сектора или дуги. Ctrl ограничивает угол. " +"Перетаскивание внутри дает дугу, снаружи - сектор." + +#: ../../po/../src/object-edit.cpp:695 +msgid "" +"Position the end point of the arc or segment; with Ctrl to " +"snap angle; drag inside the ellipse for arc, outside for " +"segment" +msgstr "" +"Конечная точка сектора или дуги. Ctrl ограничивает угол. " +"Перетаскивание внутри дает дугу, снаружи - сектор." + +#: ../../po/../src/object-edit.cpp:800 +msgid "" +"Adjust the tip radius of the star or polygon; with Shift to " +"round; with Alt to randomize" +msgstr "" +"Менять большой радиус звезды или многоугольника. Shift " +"закругляет, Alt искажает." + +#: ../../po/../src/object-edit.cpp:803 +msgid "" +"Adjust the base radius of the star; with Ctrl to keep star " +"rays radial (no skew); with Shift to round; with Alt to " +"randomize" +msgstr "" +"Менять малый радиус звезды или многоугольника. Shift " +"закругляет, Alt искажает." + +#: ../../po/../src/object-edit.cpp:967 +msgid "" +"Roll/unroll the spiral from inside; with Ctrl to snap angle; " +"with Alt to converge/diverge" +msgstr "" +"Удлинять или укорачивать спираль изнутри. Ctrl ограничивает угол. " +"Alt меняет нелинейность." + +#: ../../po/../src/object-edit.cpp:969 +msgid "" +"Roll/unroll the spiral from outside; with Ctrl to snap angle; " +"with Shift to scale/rotate" +msgstr "" +"Удлинять или укорачивать спираль снаружи. Ctrl ограничивает угол. " +"Shift растягивает/вращает как целое." + +#: ../../po/../src/object-edit.cpp:1006 +msgid "Adjust the offset distance" +msgstr "Менять расстояние втяжки" + +#. TRANSLATORS: This refers to the pattern that's inside the object +#: ../../po/../src/object-edit.cpp:1036 +msgid "Move the pattern fill inside the object" +msgstr "Двигать текстурную заливку внутри объекта" + +#: ../../po/../src/object-edit.cpp:1038 +msgid "Scale the pattern fill uniformly" +msgstr "Пропорционально масштабировать текстурную заливку" + +#: ../../po/../src/object-edit.cpp:1040 +msgid "Rotate the pattern fill; with Ctrl to snap angle" +msgstr "Вращать текстурную заливку, Ctrl ограничивает угол" + +#: ../../po/../src/object-edit.cpp:1065 +msgid "Drag to resize the flowed text frame" +msgstr "Изменять размер текстовой рамки" + +#. Item dialog +#: ../../po/../src/object-ui.cpp:106 +msgid "Object _Properties" +msgstr "_Свойства объекта" + +#. Select item +#: ../../po/../src/object-ui.cpp:116 +msgid "_Select This" +msgstr "_Выделить это" + +#. Create link +#: ../../po/../src/object-ui.cpp:126 +msgid "_Create Link" +msgstr "Создать ссылку" + +#. "Ungroup" +#: ../../po/../src/object-ui.cpp:199 ../../po/../src/verbs.cpp:1931 +msgid "_Ungroup" +msgstr "Разгр_уппировать" + +#. Link dialog +#: ../../po/../src/object-ui.cpp:239 +msgid "Link _Properties" +msgstr "_Свойства ссылки" + +#. Select item +#: ../../po/../src/object-ui.cpp:249 +msgid "_Follow Link" +msgstr "Перейти по ссылке" + +#. Reset transformations +#: ../../po/../src/object-ui.cpp:254 +msgid "_Remove Link" +msgstr "_Удалить ссылку" + +#. Link dialog +#: ../../po/../src/object-ui.cpp:303 +msgid "Image _Properties" +msgstr "_Свойства изображения" + +#. Item dialog +#: ../../po/../src/object-ui.cpp:344 +msgid "_Fill and Stroke" +msgstr "_Заливка и штрих" + +#: ../../po/../src/path-chemistry.cpp:58 +msgid "Select at least two objects to combine." +msgstr "Выделите как минимум два объекта для объединения." + +#: ../../po/../src/path-chemistry.cpp:65 +msgid "At least one of the objects is not a path, cannot combine." +msgstr "" +"Как минимум один из объектов не является контуром, поэтому " +"объединение невозможно." + +#: ../../po/../src/path-chemistry.cpp:73 +msgid "" +"You cannot combine objects from different groups or layers." +msgstr "Нельзя объединять объекты из разных групп или слоев." + +#: ../../po/../src/path-chemistry.cpp:155 +msgid "Select path(s) to break apart." +msgstr "Выделите контур(ы) для разбиения." + +#: ../../po/../src/path-chemistry.cpp:231 +msgid "No path(s) to break apart in the selection." +msgstr "В выделении нет разбиваемых контуров." + +#: ../../po/../src/path-chemistry.cpp:252 +msgid "Select object(s) to convert to path." +msgstr "Выделите объекты для преобразования в контур." + +#: ../../po/../src/path-chemistry.cpp:297 +msgid "No objects to convert to path in the selection." +msgstr "В выделении нет объектов, преобразуемых в контур." + +#: ../../po/../src/path-chemistry.cpp:345 +msgid "Select path(s) to reverse." +msgstr "Выделите контур(ы) для разворота." + +#: ../../po/../src/path-chemistry.cpp:370 +msgid "No paths to reverse in the selection." +msgstr "В выделении нет контуров для разворота." + +#: ../../po/../src/pen-context.cpp:379 ../../po/../src/pencil-context.cpp:233 +msgid "Continuing selected path" +msgstr "Продолжение выделенного контура" + +#: ../../po/../src/pen-context.cpp:390 ../../po/../src/pencil-context.cpp:242 +msgid "Creating new path" +msgstr "Создание нового контура" + +#: ../../po/../src/pen-context.cpp:394 ../../po/../src/pencil-context.cpp:246 +msgid "Appending to selected path" +msgstr "Добавление к выделенному контуру" + +#: ../../po/../src/pen-context.cpp:538 +msgid "Click or click and drag to close and finish the path." +msgstr "" +"Щелчок или щелчок + перетаскивание закрывают этот контур." + +#: ../../po/../src/pen-context.cpp:548 +msgid "" +"Click or click and drag to continue the path from this point." +msgstr "" +"Щелчок или щелчок + перетаскивание продолжает контур из этой " +"точки." + +#: ../../po/../src/pen-context.cpp:857 +#, c-format +msgid "" +"%s: angle %3.2f°, distance %s; with Ctrl to snap angle, " +"Enter to finish the path" +msgstr "" +"%s: угол %3.2f°, расстояние %s; Ctrl ограничивает угол, " +"Enter завершает контур" + +#: ../../po/../src/pen-context.cpp:882 +#, c-format +msgid "" +"Curve handle: angle %3.2f°, length %s; with Ctrl to snap " +"angle" +msgstr "" +"Ус узла кривой: угол %3.2f°, длина %s; Ctrl ограничивает " +"угол" + +#: ../../po/../src/pen-context.cpp:912 +#, c-format +msgid "" +"%s: angle %3.2f°, length %s; with Ctrl to snap angle, " +"with Shift to move this handle only" +msgstr "" +"%s: угол %3.2f°, длина %s; перетаскивание с Ctrl ограничивает " +"угол; с Shift синхронно вращает противоположный ус" + +#: ../../po/../src/pen-context.cpp:946 +msgid "Finishing pen" +msgstr "Контур создан" + +#: ../../po/../src/pencil-context.cpp:320 +msgid "Release here to close and finish the path." +msgstr "Отпустите здесь для закрытия и завершения контура." + +#: ../../po/../src/pencil-context.cpp:326 +msgid "Drawing a freehand path" +msgstr "Рисуется произвольный контур" + +#: ../../po/../src/pencil-context.cpp:331 +msgid "Drag to continue the path from this point." +msgstr "Перетащите для продолжения контура из этой точки." + +#. Write curves to object +#: ../../po/../src/pencil-context.cpp:390 +msgid "Finishing freehand" +msgstr "Завершается произвольный контур" + +#: ../../po/../src/rect-context.cpp:387 +msgid "" +"Ctrl: make square or integer-ratio rect, lock a rounded corner " +"circular" +msgstr "" +"Ctrl: квадрат или прямоугольник с целым соотношением сторон, " +"закругленные углы" + +#: ../../po/../src/rect-context.cpp:549 +#, c-format +msgid "" +"Rectangle: %s × %s; with Ctrl to make square or integer-" +"ratio rectangle; with Shift to draw around the starting point" +msgstr "" +"Прямоугольник: %s x %s; с Ctrl: квадрат или прямоугольник с " +"целым соотношением сторон, с Shift рисовать вокруг начальной точки" + +#: ../../po/../src/select-context.cpp:243 +msgid "Move canceled." +msgstr "Перемещение отменено." + +#: ../../po/../src/select-context.cpp:252 +msgid "Selection canceled." +msgstr "Выделение отменено." + +#: ../../po/../src/select-context.cpp:642 +msgid "Ctrl: select in groups, move hor/vert" +msgstr "Ctrl: выделять в группе, двигать по горизонтали/вертикали" + +#: ../../po/../src/select-context.cpp:643 +msgid "Shift: toggle select, force rubberband, disable snapping" +msgstr "" +"Shift: выделить/развыделить, форсировать рамку, отключить прилипание" + +#: ../../po/../src/select-context.cpp:644 +msgid "Alt: select under, move selected" +msgstr "Alt: выделять под выделенным, двигать выделение" + +#: ../../po/../src/select-context.cpp:798 +#, fuzzy +msgid "Selected object is not a group. Cannot enter." +msgstr "" +"Выделенный объект не является контуром, втяжка/растяжка невозможны." + +#: ../../po/../src/select-context.cpp:876 +#, c-format +msgid "" +"Move by %s, %s; with Ctrl to restrict to horizontal/vertical; " +"with Shift to disable snapping" +msgstr "" +"Перемещение на %s, %s; с Ctrl только по горизонтали/вертикали; " +"с Shift без прилипания" + +#: ../../po/../src/selection-chemistry.cpp:228 +msgid "Nothing was deleted." +msgstr "Ничего не было удалено." + +#: ../../po/../src/selection-chemistry.cpp:259 +msgid "Select object(s) to duplicate." +msgstr "Выделите объекты для дублирования." + +#: ../../po/../src/selection-chemistry.cpp:420 +msgid "Select two or more objects to group." +msgstr "Выделите два и более объекта для группирования." + +#: ../../po/../src/selection-chemistry.cpp:428 +msgid "Select at least two objects to group." +msgstr "Выделите как минимум два объекта для группирования." + +#: ../../po/../src/selection-chemistry.cpp:513 +msgid "Select a group to ungroup." +msgstr "Выделите группу для разгруппирования." + +#: ../../po/../src/selection-chemistry.cpp:554 +msgid "No groups to ungroup in the selection." +msgstr "В выделении нет групп для разгруппирования." + +#: ../../po/../src/selection-chemistry.cpp:623 +msgid "Select objects to raise." +msgstr "Выделите объекты для поднятия." + +#: ../../po/../src/selection-chemistry.cpp:629 +#: ../../po/../src/selection-chemistry.cpp:681 +#: ../../po/../src/selection-chemistry.cpp:715 +#: ../../po/../src/selection-chemistry.cpp:773 +msgid "" +"You cannot raise/lower objects from different groups or layers." +msgstr "" +"Нельзя поднять или опустить объекты из разных групп или слоев." + +#: ../../po/../src/selection-chemistry.cpp:673 +msgid "Select object(s) to raise to top." +msgstr "Выделите объект(ы) для поднятия на самый верх." + +#: ../../po/../src/selection-chemistry.cpp:709 +msgid "Select object(s) to lower." +msgstr "Выделите объект(ы) для опускания." + +#: ../../po/../src/selection-chemistry.cpp:765 +msgid "Select object(s) to lower to bottom." +msgstr "Выделите объект(ы) для опускания на самый низ." + +#: ../../po/../src/selection-chemistry.cpp:806 +msgid "Nothing to undo." +msgstr "Нет отменяемых операций." + +#: ../../po/../src/selection-chemistry.cpp:813 +msgid "Nothing to redo." +msgstr "Нет повторяемых операций." + +#: ../../po/../src/selection-chemistry.cpp:969 +msgid "Nothing was copied." +msgstr "Ничего не было скопировано." + +#: ../../po/../src/selection-chemistry.cpp:1051 +msgid "Current layer is hidden. Unhide it to be able to paste to it." +msgstr "" +"Текущий слой скрыт. Верните ему видимость, чтобы вставить в него " +"объекты." + +#: ../../po/../src/selection-chemistry.cpp:1055 +msgid "Current layer is locked. Unlock it to be able to paste to it." +msgstr "" +"Текущий слой заперт. Отоприте его, чтобы вставить в него объекты." + +#: ../../po/../src/selection-chemistry.cpp:1068 +#: ../../po/../src/selection-chemistry.cpp:1103 +msgid "Nothing on the clipboard." +msgstr "В буфере обмена ничего нет." + +#: ../../po/../src/selection-chemistry.cpp:1109 +msgid "Select object(s) to paste style to." +msgstr "Выделите объект(ы) для применения стиля." + +#: ../../po/../src/selection-chemistry.cpp:1128 +msgid "Select object(s) to move to the layer above." +msgstr "Выделите объект(ы) для перемещения на слой выше." + +#: ../../po/../src/selection-chemistry.cpp:1146 +msgid "No more layers above." +msgstr "Выше слоев нет." + +#: ../../po/../src/selection-chemistry.cpp:1160 +msgid "Select object(s) to move to the layer below." +msgstr "Выделите объект(ы) для перемещения на слой ниже." + +#: ../../po/../src/selection-chemistry.cpp:1178 +msgid "No more layers below." +msgstr "Ниже слоев нет." + +#: ../../po/../src/selection-chemistry.cpp:1811 +msgid "Select a clone to unlink." +msgstr "Выделите клон для отсоединения." + +#: ../../po/../src/selection-chemistry.cpp:1842 +msgid "No clones to unlink in the selection." +msgstr "В выделении нет клонов." + +#: ../../po/../src/selection-chemistry.cpp:1859 +msgid "" +"Select a clone to go to its original. Select a linked offset " +"to go to its source. Select a text on path to go to the path. Select " +"a flowed text to go to its frame." +msgstr "" +"Выделите клон, чтобы перейти к его оригиналу. Выделите связанную " +"втяжку, чтобы перейти к исходному контуру. Выделите текст по контуру, чтобы перейти к его контуру. Выделите текст в рамке, чтобы " +"перейти к рамке." + +#: ../../po/../src/selection-chemistry.cpp:1882 +msgid "" +"Cannot find the object to select (orphaned clone, offset, textpath, " +"flowed text?)" +msgstr "" +"Некуда перейти (осиротевший клон, втяжка, текст по контуру, текст в рамке?)" + +#: ../../po/../src/selection-chemistry.cpp:1888 +msgid "" +"The object you're trying to select is not visible (it is in <" +"defs>)" +msgstr "" +"Объект, который вы пытаетесь выделить, невидим (находится в <" +"defs>)" + +#: ../../po/../src/selection-chemistry.cpp:1915 +msgid "Select object(s) to convert to pattern." +msgstr "Выделите объект(ы) для преобразования в текстуру." + +#: ../../po/../src/selection-chemistry.cpp:2006 +msgid "Select an object with pattern fill to extract objects from." +msgstr "" +"Выделите объект с текстурной заливкой для извлечения из него объектов." + +#: ../../po/../src/selection-chemistry.cpp:2059 +msgid "No pattern fills in the selection." +msgstr "В выделении нет текстурной заливки." + +#: ../../po/../src/selection-chemistry.cpp:2079 +msgid "Select object(s) to make a bitmap copy." +msgstr "Выделите объект(ы) для создания растровой копии." + +#: ../../po/../src/selection-describer.cpp:37 +msgid "Click selection to toggle scale/rotation handles" +msgstr "Щелчок по объекту переключает стрелки масштабирования/вращения" + +#. no items +#: ../../po/../src/selection-describer.cpp:39 +msgid "" +"No objects selected. Click, Shift+click, or drag around objects to select." +msgstr "" +"Нет выделенных объектов. Используйте щелчок, Shift+щелчок или обведите рамку " +"вокруг выделяемых объектов." + +#: ../../po/../src/selection-describer.cpp:51 +#, c-format +msgid " in layer %s" +msgstr " в слое %s" + +#: ../../po/../src/selection-describer.cpp:54 +#, c-format +msgid " in layer %s" +msgstr " в слое %s" + +#: ../../po/../src/selection-describer.cpp:66 +msgid "Use Shift+D to look up original" +msgstr "Нажмите Shift+D, чтобы выделить оригинал" + +#: ../../po/../src/selection-describer.cpp:70 +msgid "Use Shift+D to look up path" +msgstr "Нажмите Shift+D, чтобы выделить контур" + +#: ../../po/../src/selection-describer.cpp:74 +msgid "Use Shift+D to look up frame" +msgstr "Нажмите Shift+D, чтобы выделить рамку" + +#: ../../po/../src/selection-describer.cpp:84 +#, c-format +msgid "%i object selected" +msgid_plural "%i objects selected" +msgstr[0] "%i объект выделен." +msgstr[1] "%i объекта выделено." +msgstr[2] "%i объектов выделено." + +#: ../../po/../src/selection-describer.cpp:90 +#, c-format +msgid "%s%s. %s." +msgstr "%s%s. %s." + +#: ../../po/../src/selection-describer.cpp:94 +#, c-format +msgid "%s in %i layer. %s." +msgid_plural "%s in %i layers. %s." +msgstr[0] "%s в %i слое. %s." +msgstr[1] "%s в %i слоях. %s." +msgstr[2] "%s в %i слоях. %s." + +#: ../../po/../src/seltrans.cpp:498 +msgid "" +"Center of rotation and skewing: drag to reposition; scaling with " +"Shift also uses this center" +msgstr "" +"Центр вращения и перекоса: его можно перетащить; изменение размера с " +"Shift также происходит относительно этого центра" + +#: ../../po/../src/seltrans.cpp:514 +msgid "" +"Squeeze or stretch selection; with Ctrl to scale uniformly; " +"with Shift to scale around rotation center" +msgstr "" +"Сжать или растянуть выделение; с Ctrl - сохранять пропорцию; с " +"Shift - вокруг центра вращения" + +#: ../../po/../src/seltrans.cpp:515 +msgid "" +"Scale selection; with Ctrl to scale uniformly; with Shift to scale around rotation center" +msgstr "" +"Менять размер выделения; с Ctrl - сохранять пропорцию; с " +"Shift - вокруг центра вращения" + +#: ../../po/../src/seltrans.cpp:519 +msgid "" +"Skew selection; with Ctrl to snap angle; with Shift to " +"skew around the opposite side" +msgstr "" +"Перекашивать выделение; с Ctrl - ограничивать угол; с " +"Shift - вокруг противоположной стороны" + +#: ../../po/../src/seltrans.cpp:520 +msgid "" +"Rotate selection; with Ctrl to snap angle; with Shift " +"to rotate around the opposite corner" +msgstr "" +"Вращать выделение; с Ctrl - ограничивать угол; с Shift " +"- вокруг противоположного угла" + +#: ../../po/../src/seltrans.cpp:829 ../../po/../src/seltrans.cpp:909 +#, c-format +msgid "Scale: %0.2f%% x %0.2f%%; with Ctrl to lock ratio" +msgstr "" +"Изменить размер: %0.2f%% x %0.2f%%; Ctrl сохраняет пропорцию" + +#. TRANSLATORS: don't modify the first ";" (it will NOT be displayed as ";" - only the second one will be) +#: ../../po/../src/seltrans.cpp:984 +#, c-format +msgid "Skew: %0.2f°; with Ctrl to snap angle" +msgstr "Перекашивание: %0.2f°; Ctrl ограничивает угол" + +#. TRANSLATORS: don't modify the first ";" (it will NOT be displayed as ";" - only the second one will be) +#: ../../po/../src/seltrans.cpp:1035 +#, c-format +msgid "Rotate: %0.2f°; with Ctrl to snap angle" +msgstr "Вращение: %0.2f°; Ctrl ограничивает угол" + +#: ../../po/../src/seltrans.cpp:1090 +#, c-format +msgid "Move center to %s, %s" +msgstr "Переместить центр в %s, %s" + +#: ../../po/../src/slideshow.cpp:90 +msgid "Inkscape slideshow" +msgstr "Показ слайдов" + +#: ../../po/../src/sp-anchor.cpp:181 +#, c-format +msgid "Link to %s" +msgstr "Ссылка на %s" + +#: ../../po/../src/sp-anchor.cpp:185 +msgid "Link without URI" +msgstr "Ссылка без URI" + +#: ../../po/../src/sp-ellipse.cpp:438 ../../po/../src/sp-ellipse.cpp:870 +msgid "Ellipse" +msgstr "Эллипс" + +#: ../../po/../src/sp-ellipse.cpp:583 +msgid "Circle" +msgstr "Окружность" + +#: ../../po/../src/sp-ellipse.cpp:865 +msgid "Segment" +msgstr "Сегмент" + +#: ../../po/../src/sp-ellipse.cpp:867 +msgid "Arc" +msgstr "Дуга" + +#. TRANSLATORS: "Flow region" is an area where text is allowed to flow +#: ../../po/../src/sp-flowregion.cpp:276 +msgid "Flow region" +msgstr "Рамка верстки" + +#. TRANSLATORS: A region "cut out of" a flow region; text is not allowed to flow inside the +#. * flow excluded region. flowRegionExclude in SVG 1.2: see +#. * http://www.w3.org/TR/2004/WD-SVG12-20041027/flow.html#flowRegion-elem and +#. * http://www.w3.org/TR/2004/WD-SVG12-20041027/flow.html#flowRegionExclude-elem. +#: ../../po/../src/sp-flowregion.cpp:493 +msgid "Flow excluded region" +msgstr "Область, исключенная из верстки" + +#: ../../po/../src/sp-flowtext.cpp:355 +#, c-format +msgid "Flowed text (%d characters)" +msgstr "Текст в рамке (символов: %d)" + +#: ../../po/../src/sp-flowtext.cpp:357 +#, c-format +msgid "Linked flowed text (%d characters)" +msgstr "Связанный текст в рамке (символов: %d)" + +#: ../../po/../src/sp-guide.cpp:290 +msgid "vertical guideline" +msgstr "вертикальная направляющая" + +#: ../../po/../src/sp-guide.cpp:292 +msgid "horizontal guideline" +msgstr "горизонтальная направляющая" + +#: ../../po/../src/sp-image.cpp:835 +msgid "embedded" +msgstr "включенное" + +#: ../../po/../src/sp-image.cpp:839 +msgid "(null_pointer)" +msgstr "(null_pointer)" + +#: ../../po/../src/sp-image.cpp:843 +#, c-format +msgid "Image with bad reference: %s" +msgstr "Изображение без ссылки: %s" + +#: ../../po/../src/sp-image.cpp:844 +#, c-format +msgid "Image %d × %d: %s" +msgstr "Изображение %d x %d: %s" + +#: ../../po/../src/sp-item-group.cpp:390 +#, c-format +msgid "Group of %d object" +msgid_plural "Group of %d objects" +msgstr[0] "Группа из %d объекта" +msgstr[1] "Группа из %d объектов" +msgstr[2] "Группа из %d объектов" + +#: ../../po/../src/sp-item.cpp:720 +msgid "Object" +msgstr "Объект" + +#: ../../po/../src/sp-line.cpp:202 +msgid "Line" +msgstr "Линия" + +#. TRANSLATORS COMMENT: %s is either "outset" or "inset" depending on sign +#: ../../po/../src/sp-offset.cpp:433 +#, c-format +msgid "Linked offset, %s by %f pt" +msgstr "Динамическая втяжка, %s на %f pt" + +#: ../../po/../src/sp-offset.cpp:434 ../../po/../src/sp-offset.cpp:438 +msgid "outset" +msgstr "оттянута" + +#: ../../po/../src/sp-offset.cpp:434 ../../po/../src/sp-offset.cpp:438 +msgid "inset" +msgstr "втянута" + +#. TRANSLATORS COMMENT: %s is either "outset" or "inset" depending on sign +#: ../../po/../src/sp-offset.cpp:437 +#, c-format +msgid "Dynamic offset, %s by %f pt" +msgstr "Динамическая втяжка, %s на %f pt" + +#: ../../po/../src/sp-path.cpp:127 +#, c-format +msgid "Path (%i node)" +msgid_plural "Path (%i nodes)" +msgstr[0] "Контур (%i узел)" +msgstr[1] "Контур (%i узла)" +msgstr[2] "Контур (%i узлов)" + +#: ../../po/../src/sp-polygon.cpp:216 +msgid "Polygon" +msgstr "Многоугольник" + +#: ../../po/../src/sp-polyline.cpp:179 +msgid "Polyline" +msgstr "Полилиния" + +#: ../../po/../src/sp-rect.cpp:250 +msgid "Rectangle" +msgstr "Прямоугольник" + +#. TRANSLATORS: since turn count isn't an integer, please adjust the +#. string as needed to deal with an localized plural forms. +#: ../../po/../src/sp-spiral.cpp:305 +#, c-format +msgid "Spiral with %3f turns" +msgstr "Спираль на %3f оборотов" + +#: ../../po/../src/sp-star.cpp:288 +#, c-format +msgid "Star with %d vertex" +msgid_plural "Star with %d vertices" +msgstr[0] "Звезда с %d лучом" +msgstr[1] "Звезда с %d лучами" +msgstr[2] "Звезда с %d лучами" + +#: ../../po/../src/sp-star.cpp:292 +#, c-format +msgid "Polygon with %d vertex" +msgid_plural "Polygon with %d vertices" +msgstr[0] "Многоугольник с %d вершиной" +msgstr[1] "Многоугольник с %d вершинами" +msgstr[2] "Многоугольник с %d вершинами" + +#. TRANSLATORS: For description of font with no name. +#: ../../po/../src/sp-text.cpp:420 +msgid "<no name found>" +msgstr "<нет имени>" + +#: ../../po/../src/sp-text.cpp:426 +#, c-format +msgid "Text on path (%s, %s)" +msgstr "Текст по контуру (%s, %s)" + +#: ../../po/../src/sp-text.cpp:427 +#, c-format +msgid "Text (%s, %s)" +msgstr "Текст (%s, %s)" + +#. TRANSLATORS: Used for statusbar description for long chains: +#. * "Clone of: Clone of: ... in Layer 1". +#: ../../po/../src/sp-use.cpp:317 +msgid "..." +msgstr "..." + +#: ../../po/../src/sp-use.cpp:325 +#, c-format +msgid "Clone of: %s" +msgstr "Клон: %s" + +#: ../../po/../src/sp-use.cpp:329 +msgid "Orphaned clone" +msgstr "Осиротевший клон" + +#: ../../po/../src/spiral-context.cpp:355 +msgid "Ctrl: snap angle" +msgstr "Ctrl: ограничить угол" + +#: ../../po/../src/spiral-context.cpp:357 +msgid "Alt: lock spiral radius" +msgstr "Alt: зафиксировать радиус спирали" + +#: ../../po/../src/spiral-context.cpp:469 +#, c-format +msgid "" +"Spiral: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" +"Спираль: радиус %s, угол %5g°; Ctrl ограничивает угол" + +#: ../../po/../src/splivarot.cpp:106 +msgid "Select at least 2 paths to perform a boolean operation." +msgstr "Для логической операции нужно выбрать не менее 2 контуров." + +#: ../../po/../src/splivarot.cpp:112 +msgid "" +"Select exactly 2 paths to perform difference, XOR, division, or path " +"cut." +msgstr "" +"Для операций разности, исключающего ИЛИ, деления и разрезания контура " +"выделите ровно 2 контура" + +#: ../../po/../src/splivarot.cpp:129 ../../po/../src/splivarot.cpp:144 +msgid "" +"Unable to determine the z-order of the objects selected for " +"difference, XOR, division, or path cut." +msgstr "" +"Невозможно определить порядок расположения друг над другом объектов, " +"выделенных для операций разности, исключающего ИЛИ, деления или разрезания " +"контура." + +#: ../../po/../src/splivarot.cpp:174 +msgid "" +"One of the objects is not a path, cannot perform boolean operation." +msgstr "" +"Один из объектов не является контуром, логическая операция невозможна." + +#. TRANSLATORS: "to outline" means "to convert stroke to path" +#: ../../po/../src/splivarot.cpp:554 +msgid "Select path(s) to outline." +msgstr "Выделите контур для оконтуривания штриха." + +#. TRANSLATORS: "to outline" means "to convert stroke to path" +#: ../../po/../src/splivarot.cpp:748 +msgid "No stroked paths to outline in the selection." +msgstr "В выделении нет контуров со штрихом для оконтуривания." + +#: ../../po/../src/splivarot.cpp:832 +msgid "Selected object is not a path, cannot inset/outset." +msgstr "" +"Выделенный объект не является контуром, втяжка/растяжка невозможны." + +#: ../../po/../src/splivarot.cpp:1040 +msgid "Select path(s) to inset/outset." +msgstr "Выделите контур для втяжки/растяжки." + +#: ../../po/../src/splivarot.cpp:1257 +msgid "No paths to inset/outset in the selection." +msgstr "В выделении нет контуров для втяжки/растяжки." + +#: ../../po/../src/splivarot.cpp:1390 +msgid "Select path(s) to simplify." +msgstr "Выделите контур(ы) для упрощения." + +#: ../../po/../src/splivarot.cpp:1417 +msgid "No paths to simplify in the selection." +msgstr "В выделении нет контуров для упрощения." + +#: ../../po/../src/star-context.cpp:362 +msgid "Ctrl: snap angle; keep rays radial" +msgstr "Ctrl: ограничивать угол; лучи по радиусу без перекоса" + +#: ../../po/../src/star-context.cpp:470 +#, c-format +msgid "" +"Polygon: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" +"Многоугольник: радиус %s, угол %5g°; Ctrl ограничивает " +"угол" + +#: ../../po/../src/star-context.cpp:471 +#, c-format +msgid "Star: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" +"Звезда: радиус %s, угол %5g°; Ctrl ограничивает угол" + +#: ../../po/../src/text-chemistry.cpp:90 +msgid "Select a text and a path to put text on path." +msgstr "Выделите текст и контур для размещения текста по контуру." + +#: ../../po/../src/text-chemistry.cpp:95 +msgid "" +"This text object is already put to a path. Remove it from the path " +"first. Use Shift+D to look up its path." +msgstr "" +"Текстовый объект уже размещен по контуру. Сначала снимите его с " +"контура. Нажмите Shift-D для перехода к его контуру." + +#. rect is the only SPShape which is not yet, and thus SVG forbids us from putting text on it +#: ../../po/../src/text-chemistry.cpp:101 +msgid "" +"You cannot put text on a rectangle in this version. Convert rectangle to " +"path first." +msgstr "" +"В этой версии программы нельзя разместить текст по контуру прямоугольника. " +"Преобразуйте прямоугольник в контур и попробуйте снова." + +#: ../../po/../src/text-chemistry.cpp:159 +msgid "Select a text on path to remove it from path." +msgstr "Выделите текст по контуру, чтобы снять его с контура." + +#: ../../po/../src/text-chemistry.cpp:181 +msgid "No texts-on-paths in the selection." +msgstr "В выделении нет текстов по контуру." + +#: ../../po/../src/text-chemistry.cpp:209 +#: ../../po/../src/text-chemistry.cpp:229 +msgid "Select text(s) to remove kerns from." +msgstr "Выделите текст для удаления ручного кернинга." + +#: ../../po/../src/text-chemistry.cpp:250 +msgid "" +"Select a text and one or more paths or shapes to flow text " +"into frame." +msgstr "" +"Выделите текст и контур или фигуру для заверстки текста в " +"рамку." + +#: ../../po/../src/text-chemistry.cpp:322 +msgid "Select a flowed text to unflow it." +msgstr "Выделите текст в рамке, чтобы вынуть его из рамки." + +#: ../../po/../src/text-context.cpp:463 +msgid "Click to edit the text, drag to select part of the text." +msgstr "Щелчок ставит курсор, перетаскивание выделяет текст." + +#: ../../po/../src/text-context.cpp:465 +msgid "" +"Click to edit the flowed text, drag to select part of the text." +msgstr "Щелчок ставит курсор, перетаскивание выделяет текст." + +#: ../../po/../src/text-context.cpp:540 +msgid "Non-printable character" +msgstr "Непечатаемый символ" + +#: ../../po/../src/text-context.cpp:589 +#, c-format +msgid "Unicode: %s: %s" +msgstr "Unicode: %s: %s" + +#: ../../po/../src/text-context.cpp:591 ../../po/../src/text-context.cpp:855 +msgid "Unicode: " +msgstr "Unicode: " + +#: ../../po/../src/text-context.cpp:615 +msgid "Current layer is hidden. Unhide it to be able to add text." +msgstr "" +"Текущий слой скрыт. Откройте его, чтобы можно было добавлять в него " +"текст." + +#: ../../po/../src/text-context.cpp:619 +msgid "Current layer is locked. Unlock it to be able to add text." +msgstr "" +"Текущий слой заперт. Отоприте его, чтобы можно было добавлять в него " +"текст." + +#: ../../po/../src/text-context.cpp:673 +#, c-format +msgid "Flowed text frame: %s × %s" +msgstr "Рамка для текста: %s × %s" + +#: ../../po/../src/text-context.cpp:708 ../../po/../src/text-context.cpp:1464 +msgid "Type text; Enter to start new line." +msgstr "Вводите текст; Enter начинает новый абзац." + +#: ../../po/../src/text-context.cpp:719 +msgid "Flowed text is created." +msgstr "Текст в рамке создан." + +#: ../../po/../src/text-context.cpp:722 +msgid "" +"The frame is too small for the current font size. Flowed text not " +"created." +msgstr "" +"Рамка слишком мала для текущего размера шрифта. Невозможно создать " +"текст в рамке." + +#: ../../po/../src/text-context.cpp:841 +msgid "No-break space" +msgstr "Неразрывный пробел" + +#: ../../po/../src/text-context.cpp:1462 +msgid "Type flowed text; Enter to start new paragraph." +msgstr "Набирайте текст в рамке; Enter начинает новый абзац" + +#: ../../po/../src/text-context.cpp:1472 ../../po/../src/tools-switch.cpp:189 +msgid "" +"Click to select or create text, drag to create flowed text; " +"then type." +msgstr "" +"Щелчок выделяет или создает текст, перетаскивание создает " +"текст в рамке; после этого можно набирать текст." + +#: ../../po/../src/tools-switch.cpp:141 +msgid "" +"To edit a path, click, Shift+click, or drag around " +"nodes to select them, then drag nodes and handles. Click on an " +"object to select." +msgstr "" +"Для правки контура выделите узлы с помощью щелчка, Shift+щелчка или обведения рамки, затем перетаскивайте узлы и усы. " +"Щелчок по объекту выделяет его." + +#: ../../po/../src/tools-switch.cpp:147 +msgid "" +"Drag to create a rectangle. Drag controls to round corners and " +"resize. Click to select." +msgstr "" +"Перетаскивание рисует прямоугольник. Перетаскивание ручек " +"меняет размер и закругляет углы. Щелчок по объекту выделяет его." + +#: ../../po/../src/tools-switch.cpp:153 +msgid "" +"Drag to create an ellipse. Drag controls to make an arc or " +"segment. Click to select." +msgstr "" +"Перетаскивание рисует эллипс. Перетаскивание ручек делает дугу " +"или сегмент. Щелчок по объекту выделяет его." + +#: ../../po/../src/tools-switch.cpp:159 +msgid "" +"Drag to create a star. Drag controls to edit the star shape. " +"Click to select." +msgstr "" +"Перетаскивание рисует звезду. Перетаскивание ручек меняет ее " +"форму. Щелчок по объекту выделяет его." + +#: ../../po/../src/tools-switch.cpp:165 +msgid "" +"Drag to create a spiral. Drag controls to edit the spiral " +"shape. Click to select." +msgstr "" +"Перетаскивание рисует спираль. Перетаскивание ручек меняет ее " +"форму. Щелчок по объекту выделяет его." + +#: ../../po/../src/tools-switch.cpp:171 +msgid "" +"Drag to create a freehand line. Start drawing with Shift to " +"append to selected path." +msgstr "" +"Произвольная линия рисуется перетаскиванием. С Shift линия " +"присоединяется к выделенному контуру." + +#: ../../po/../src/tools-switch.cpp:177 +msgid "" +"Click or click and drag to start a path; with Shift to " +"append to selected path." +msgstr "" +"Щелчок и щелчок с перетаскиванием создают узел. С Shift " +"линия добавляется к выделенному контуру." + +#: ../../po/../src/tools-switch.cpp:183 +msgid "" +"Drag to paint a calligraphic stroke. Left/right arrow " +"keys adjust width, up/down adjust angle." +msgstr "" +"Перетаскивание рисует каллиграфический штрих. Клавиши-стрелки меняют " +"ширину (влево/вправо) и угол (вверх/вниз) пера." + +#: ../../po/../src/tools-switch.cpp:195 +msgid "" +"Drag or double click to create a gradient on selected objects, " +"drag handles to adjust gradients." +msgstr "" +"Новый градиент для выделенного объекта создается перетаскиванием или " +"двойным щелчком и подстраивается перетаскиванием ручек." + +#: ../../po/../src/tools-switch.cpp:201 +msgid "" +"Click or drag around an area to zoom in, Shift+click to " +"zoom out." +msgstr "" +"Щелчок или обведение рамкой приближают, Shift+щелчок " +"отдаляет холст." + +#: ../../po/../src/tools-switch.cpp:213 +msgid "Click and drag between shapes to create a connector." +msgstr "" +"Щелчок с перетаскиванием между фигурами создают линию соединения." + +#: ../../po/../src/trace/potrace/inkscape-potrace.cpp:553 +#: ../../po/../src/trace/potrace/inkscape-potrace.cpp:654 +#, c-format +msgid "Trace: %d. %ld nodes" +msgstr "Векторизация: %d. Узлов - %ld" + +#: ../../po/../src/trace/trace.cpp:53 ../../po/../src/trace/trace.cpp:62 +#: ../../po/../src/trace/trace.cpp:70 +msgid "Select an image to trace" +msgstr "Выделите растровое изображение для векторизации" + +#: ../../po/../src/trace/trace.cpp:133 +msgid "Trace: No active document" +msgstr "Векторизация: Нет активного документа" + +#: ../../po/../src/trace/trace.cpp:154 +msgid "Trace: Image has no bitmap data" +msgstr "Векторизация: В изображении нет растровых данных" + +#: ../../po/../src/trace/trace.cpp:267 +#, c-format +msgid "Trace: Done. %ld nodes created" +msgstr "Векторизация: Готово. Создано узлов: %ld" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:59 ../../po/../src/verbs.cpp:2212 +msgid "About Inkscape" +msgstr "Об Inkscape" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:66 +msgid "_Splash" +msgstr "" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:68 +#, fuzzy +msgid "_Authors" +msgstr "Авторы" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:69 +#, fuzzy +msgid "_Translators" +msgstr "Переводчики" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:70 +msgid "_License" +msgstr "_Лицензия" + +#. TRANSLATORS: This is the filename of the `About Inkscape' picture in +#. the `screens' directory. Thus the translation of "about.svg" should be +#. the filename of its translated version, e.g. about.zh.svg for Chinese. +#. +#. N.B. about.svg changes once per release. (We should probably rename +#. the original to about-0.40.svg etc. as soon as we have a translation. +#. If we do so, then add an item to release-checklist saying that the +#. string here should be changed.) +#. FIXME? INKSCAPE_SCREENSDIR and "about.svg" are in UTF-8, not the +#. native filename encoding... and the filename passed to sp_document_new +#. should be in UTF-*8.. +#: ../../po/../src/ui/dialog/aboutbox.cpp:114 +msgid "about.svg" +msgstr "about.svg" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:464 +msgid "Minimum horizontal gap (in px units) between bounding boxes" +msgstr "" + +#. TRANSLATORS: Horizontal gap +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:466 +#: ../../po/../src/widgets/toolbox.cpp:1556 +msgid "H:" +msgstr "В:" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:474 +msgid "Minimum vertical gap (in px units) between bounding boxes" +msgstr "" + +#. TRANSLATORS: Vertical gap +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:476 +msgid "V:" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:734 +msgid "Align" +msgstr "Выровнять" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:735 +msgid "Distribute" +msgstr "Расставить" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:736 +msgid "Remove overlaps" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:737 +msgid "Nodes" +msgstr "Узлы" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:742 +msgid "Relative to: " +msgstr "Относительно: " + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:747 +msgid "Align right sides of objects to left side of anchor" +msgstr "Правые края объектов к левому краю якоря" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:750 +msgid "Align left sides" +msgstr "Выровнять по левым краям" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:753 +msgid "Center on vertical axis" +msgstr "Центрировать на вертикальной оси" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:756 +msgid "Align right sides" +msgstr "Выровнять по правым краям" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:759 +msgid "Align left sides of objects to right side of anchor" +msgstr "Левые края объектов к правому краю якоря" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:762 +msgid "Align bottoms of objects to top of anchor" +msgstr "Нижние края объектов к верхнему краю якоря" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:765 +msgid "Align tops" +msgstr "Выровнять по верхним краям" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:768 +msgid "Center on horizontal axis" +msgstr "Центрировать на горизонтальной оси" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:771 +msgid "Align bottoms" +msgstr "Выровнять по нижним краям" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:774 +msgid "Align tops of objects to bottom of anchor" +msgstr "Верхние края объектов к нижнему краю якоря" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:779 +msgid "Align baseline anchors of texts vertically" +msgstr "Выровнять текстовые опорные точки по вертикали" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:782 +msgid "Align baseline anchors of texts horizontally" +msgstr "Выровнять текстовые опорные точки по горизонтали" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:787 +msgid "Make horizontal gaps between objects equal" +msgstr "Выровнять интервалы между объектами по горизонтали" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:791 +msgid "Distribute left sides equidistantly" +msgstr "Равноудаленно расставить левые края объектов" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:794 +msgid "Distribute centers equidistantly horizontally" +msgstr "Равноудаленно расставить центры объектов по горизонтали" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:797 +msgid "Distribute right sides equidistantly" +msgstr "Равноудаленно расставить правые края объектов" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:801 +msgid "Make vertical gaps between objects equal" +msgstr "Выравнять интервалы между объектами по вертикали" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:805 +msgid "Distribute tops equidistantly" +msgstr "Равноудаленно расставить верхние края" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:808 +msgid "Distribute centers equidistantly vertically" +msgstr "Равноудаленно расставить центры объектов по вертикали" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:811 +msgid "Distribute bottoms equidistantly" +msgstr "Равноудаленно расставить нижние края объектов" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:816 +msgid "Distribute baseline anchors of texts horizontally" +msgstr "Распределить текстовые опорные точки по горизонтали" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:819 +msgid "Distribute baseline anchors of texts vertically" +msgstr "Распределить текстовые опорные точки по вертикали" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:824 +msgid "Randomize centers in both dimensions" +msgstr "Случайным образом расставить центры" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:827 +msgid "Unclump objects: try to equalize edge-to-edge distances" +msgstr "Попробовать выравнять расстояния между краями объектов" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:832 +msgid "" +"Move objects as little as possible so that their bounding boxes do not " +"overlap" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:837 +msgid "Align selected nodes horizontally" +msgstr "Выровнять выделенные узлы по горизонтали" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:840 +msgid "Align selected nodes vertically" +msgstr "Выровнять выделенные узлы по вертикали" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:843 +msgid "Distribute selected nodes horizontally" +msgstr "Распределить выделенные узлы по горизонтали" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:846 +msgid "Distribute selected nodes vertically" +msgstr "Распределить выделенные узлы по вертикали" + +#. Rest of the widgetry +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:851 +msgid "Last selected" +msgstr "Последнего выделенного" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:852 +msgid "First selected" +msgstr "Первого выделенного" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:853 +msgid "Biggest item" +msgstr "Наибольшего объекта" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:854 +msgid "Smallest item" +msgstr "Наименьшего объекта" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:856 +#: ../../po/../src/widgets/desktop-widget.cpp:1065 +msgid "Drawing" +msgstr "Рисунок" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:91 +#, fuzzy +msgid "Metadata 1" +msgstr "Метаданные" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:92 +#, fuzzy +msgid "Metadata 2" +msgstr "Метаданные" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:187 +#, fuzzy +msgid "X coordinate of grid origin" +msgstr "Вертикальная координата выделения" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:189 +#, fuzzy +msgid "Y coordinate of grid origin" +msgstr "Вертикальная координата выделения" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:191 +#, fuzzy +msgid "Distance of vertical grid lines" +msgstr "вертикальная направляющая" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:193 +#, fuzzy +msgid "Distance of horizontal grid lines" +msgstr "горизонтальная направляющая" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:197 +msgid "Max. snapping distance from grid" +msgstr "" + +#: ../../po/../src/ui/dialog/export.cpp:34 +msgid "Export" +msgstr "Экспорт" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:36 +msgid "Fill" +msgstr "Заливка" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:37 +msgid "Stroke Paint" +msgstr "Цвет штриха" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:38 +msgid "Stroke Style" +msgstr "Стиль штриха" + +#: ../../po/../src/ui/dialog/find.cpp:34 +msgid "Find" +msgstr "_Искать" + +#: ../../po/../src/ui/dialog/memory.cpp:96 +msgid "Heap" +msgstr "" + +#: ../../po/../src/ui/dialog/memory.cpp:97 +msgid "In Use" +msgstr "Используется" + +#. TRANSLATORS: "Slack" refers to memory which is in the heap but currently unused. +#. More typical usage is to call this memory "free" rather than "slack". +#: ../../po/../src/ui/dialog/memory.cpp:100 +msgid "Slack" +msgstr "" + +#: ../../po/../src/ui/dialog/memory.cpp:101 +msgid "Total" +msgstr "Всего" + +#: ../../po/../src/ui/dialog/memory.cpp:141 +#: ../../po/../src/ui/dialog/memory.cpp:147 +#: ../../po/../src/ui/dialog/memory.cpp:154 +#: ../../po/../src/ui/dialog/memory.cpp:186 +msgid "Unknown" +msgstr "Неизвестно" + +#: ../../po/../src/ui/dialog/memory.cpp:167 +msgid "Combined" +msgstr "Совокупно" + +#: ../../po/../src/ui/dialog/memory.cpp:209 +msgid "Recalculate" +msgstr "Пересчитать" + +#: ../../po/../src/ui/dialog/messages.cpp:74 +msgid "Ready." +msgstr "Готово." + +#: ../../po/../src/ui/dialog/messages.cpp:75 +msgid "" +"Enable log display by setting dialogs.debug 'redirect' attribute to 1 in " +"preferences.xml" +msgstr "" +"Включить отображение журнала установлением значения атрибута dialogs.debug " +"'redirect' как 1 в preferences.xml" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:184 +msgid "_Execute Python" +msgstr "Выполнить _сценарий на Python" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:186 +msgid "_Execute Perl" +msgstr "Выполнить сце_нарий на Perl" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:195 +msgid "Script" +msgstr "Сценарий" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:205 +msgid "Output" +msgstr "Вывод" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:215 +msgid "Errors" +msgstr "Ошибки" + +#. Dialog organization +#: ../../po/../src/ui/dialog/session-player.cpp:73 +msgid "Session file" +msgstr "Файл сессии" + +#: ../../po/../src/ui/dialog/session-player.cpp:74 +msgid "Playback controls" +msgstr "Кнопки управления сессией" + +#: ../../po/../src/ui/dialog/session-player.cpp:75 +msgid "Message information" +msgstr "Информация о сообщении" + +#. Active session file display +#. fixme: Does this mean the active file for the session, or the file for the active session? +#. Please indicate which with a TRANSLATORS comment. +#: ../../po/../src/ui/dialog/session-player.cpp:85 +msgid "Active session file:" +msgstr "Активный файл сессии:" + +#: ../../po/../src/ui/dialog/session-player.cpp:86 +msgid "Delay (milliseconds):" +msgstr "Задержка (в миллисекундах):" + +#. Unload/load buttons +#: ../../po/../src/ui/dialog/session-player.cpp:94 +msgid "Close file" +msgstr "Закрыть файл" + +#: ../../po/../src/ui/dialog/session-player.cpp:95 +msgid "Open new file" +msgstr "Открыть новый файл" + +#: ../../po/../src/ui/dialog/session-player.cpp:96 +msgid "Set delay" +msgstr "Установить задержку" + +#: ../../po/../src/ui/dialog/session-player.cpp:138 +msgid "Rewind" +msgstr "Перемотать назад" + +#: ../../po/../src/ui/dialog/session-player.cpp:139 +msgid "Go back one change" +msgstr "На одно изменение назад" + +#: ../../po/../src/ui/dialog/session-player.cpp:140 +msgid "Pause" +msgstr "Пауза" + +#: ../../po/../src/ui/dialog/session-player.cpp:141 +msgid "Go forward one change" +msgstr "На одно изменение вперед" + +#: ../../po/../src/ui/dialog/session-player.cpp:142 +msgid "Play" +msgstr "Воспроизвести" + +#: ../../po/../src/ui/dialog/session-player.cpp:177 +#: ../../po/../src/verbs.cpp:1573 +msgid "Open session file" +msgstr "Открыть файл сессии" + +#. ##Set up the Potrace panel +#. #### brightness #### +#. #### Multiple scanning#### +#. ----Hbox1 +#: ../../po/../src/ui/dialog/tracedialog.cpp:345 +#: ../../po/../src/ui/dialog/tracedialog.cpp:428 +msgid "Brightness" +msgstr "Яркость" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:348 +msgid "Trace by a given brightness level" +msgstr "Векторизовать по заданному уровню яркости" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:355 +msgid "Brightness cutoff for black/white" +msgstr "Порог яркости для черно-белого" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:362 +msgid "Image Brightness" +msgstr "Яркость изображения" + +#. #### canny edge detection #### +#. TRANSLATORS: "Canny" is the name of the inventor of this edge detection method +#: ../../po/../src/ui/dialog/tracedialog.cpp:369 +msgid "Optimal Edge Detection (Canny)" +msgstr "Оптимальное определение краев (Canny)" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:372 +msgid "Trace with edge detection by J. Canny's algorithm" +msgstr "Векторизовать с определением краев по алгоритму J. Canny" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:388 +msgid "Brightness cutoff for adjacent pixels (determines edge thickness)" +msgstr "Порог яркости для смежных пикселов (определяет толщину краев)" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:395 +msgid "Edge Detection" +msgstr "Определение краев" + +#. #### quantization #### +#. TRANSLATORS: Color Quantization: the process of reducing the number of colors +#. in an image by selecting an optimized set of representative colors and then +#. re-applying this reduced set to the original image. +#: ../../po/../src/ui/dialog/tracedialog.cpp:404 +msgid "Color Quantization" +msgstr "Квантование цветов" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:407 +msgid "Trace along the boundaries of reduced colors" +msgstr "Векторизовать вдоль границы сокращенных цветов" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:414 +msgid "The number of reduced colors" +msgstr "Количество цветов после сокращения" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:416 +msgid "Colors:" +msgstr "Цветов:" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:421 +msgid "Quantization / Reduction" +msgstr "Квантование / Сокращение" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:431 +msgid "Trace the given number of brightness levels" +msgstr "Трассировать указанное количество уровней яркости" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:438 +msgid "Scans:" +msgstr "Сканирований:" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:440 +msgid "The desired number of scans" +msgstr "Желаемое количество сканирований" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:448 +msgid "Trace the given number of reduced colors" +msgstr "Трассировать указанное количество цветов" + +#. ---Hbox3 +#: ../../po/../src/ui/dialog/tracedialog.cpp:454 +msgid "Monochrome" +msgstr "Черно-белое" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:457 +msgid "Same as Color, but convert result to grayscale" +msgstr "" +"То же, что и для \"В цвете\", но преобразовать\n" +"результат в черно-белое изображение" + +#. TRANSLATORS: "Stack" is a verb here +#: ../../po/../src/ui/dialog/tracedialog.cpp:460 +msgid "Stack" +msgstr "Стопкой" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:463 +msgid "" +"Stack scans vertically (no gaps) or tile horizontally (usually with gaps)" +msgstr "" +"Слои выкладываются стопкой один под другим (без щелей)\n" +"или встык (обычно с щелями)" + +#. TRANSLATORS: "Smooth" is a verb here +#: ../../po/../src/ui/dialog/tracedialog.cpp:466 +msgid "Smooth" +msgstr "Сгладить" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:469 +msgid "Apply Gaussian blur to the bitmap before tracing" +msgstr "Применить Гауссово размывание растра перед векторизацией" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:473 +msgid "Multiple Scanning" +msgstr "Многократное сканирование" + +#. #### Preview #### +#: ../../po/../src/ui/dialog/tracedialog.cpp:479 +#: ../../po/../src/ui/dialog/tracedialog.cpp:489 +msgid "Preview" +msgstr "Просмотреть" + +#. do not expand +#: ../../po/../src/ui/dialog/tracedialog.cpp:483 +msgid "Preview the result without actual tracing" +msgstr "Просмотреть результат перед собственно векторизацией" + +#. #### swap black and white #### +#: ../../po/../src/ui/dialog/tracedialog.cpp:495 +msgid "Invert" +msgstr "Инвертировать" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:499 +msgid "Invert black and white regions for single traces" +msgstr "" +"Поменять местами черные и белые области\n" +"для одиночного трассирования" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:503 +msgid "Thanks to Peter Selinger, http://potrace.sourceforge.net" +msgstr "Спасибо Питеру Селинджеру, http://potrace.sourceforge.net" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:506 +msgid "Credits" +msgstr "Благодарности" + +#. done +#. TRANSLATORS: Potrace is an application for transforming bitmaps into +#. vector graphics (http://potrace.sourceforge.net/) +#: ../../po/../src/ui/dialog/tracedialog.cpp:514 +msgid "Potrace" +msgstr "Potrace" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:527 +msgid "Abort a trace in progress" +msgstr "Прервать векторизацию" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:531 +msgid "Execute the trace" +msgstr "Векторизовать" + +#: ../../po/../src/ui/dialog/transformation.cpp:80 +#: ../../po/../src/ui/dialog/transformation.cpp:90 +#, fuzzy +msgid "_Horizontal" +msgstr "По горизонтали" + +#: ../../po/../src/ui/dialog/transformation.cpp:80 +msgid "Horizontal displacement (relative) or position (absolute)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:82 +#: ../../po/../src/ui/dialog/transformation.cpp:92 +#, fuzzy +msgid "_Vertical" +msgstr "По вертикали" + +#: ../../po/../src/ui/dialog/transformation.cpp:82 +msgid "Vertical displacement (relative) or position (absolute)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:84 +#, fuzzy +msgid "_Width" +msgstr "Ширина:" + +#: ../../po/../src/ui/dialog/transformation.cpp:84 +msgid "Horizontal size increment (absolute or percentage)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:86 +#, fuzzy +msgid "_Height" +msgstr "Высота" + +#: ../../po/../src/ui/dialog/transformation.cpp:86 +msgid "Vertical size increment (absolute or percentage)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:88 +#, fuzzy +msgid "A_ngle" +msgstr "Угол:" + +#: ../../po/../src/ui/dialog/transformation.cpp:88 +#, fuzzy +msgid "Rotation angle (positive = counterclockwise)" +msgstr "Повернуть выделенные объекты на 90° против часовой стрелки" + +#: ../../po/../src/ui/dialog/transformation.cpp:90 +msgid "" +"Horizontal skew angle (positive = counterclockwise), or absolute " +"displacement, or percentage displacement" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:92 +msgid "" +"Vertical skew angle (positive = counterclockwise), or absolute displacement, " +"or percentage displacement" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:95 +#, fuzzy +msgid "Transformation matrix element A" +msgstr "Матрица преобразования" + +#: ../../po/../src/ui/dialog/transformation.cpp:96 +#, fuzzy +msgid "Transformation matrix element B" +msgstr "Матрица преобразования" + +#: ../../po/../src/ui/dialog/transformation.cpp:97 +#, fuzzy +msgid "Transformation matrix element C" +msgstr "Матрица преобразования" + +#: ../../po/../src/ui/dialog/transformation.cpp:98 +#, fuzzy +msgid "Transformation matrix element D" +msgstr "Матрица преобразования" + +#: ../../po/../src/ui/dialog/transformation.cpp:99 +#, fuzzy +msgid "Transformation matrix element E" +msgstr "Матрица преобразования" + +#: ../../po/../src/ui/dialog/transformation.cpp:100 +#, fuzzy +msgid "Transformation matrix element F" +msgstr "Матрица преобразования" + +#: ../../po/../src/ui/dialog/transformation.cpp:102 +#, fuzzy +msgid "Rela_tive move" +msgstr "Относительные координаты" + +#: ../../po/../src/ui/dialog/transformation.cpp:102 +msgid "" +"Add the specified relative displacement to the current position; otherwise, " +"edit the current absolute position directly" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:103 +msgid "Scale proportionally" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:103 +msgid "Preserve the width/height ratio of the scaled objects" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:104 +msgid "Apply to each _object separately" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:104 +msgid "" +"Apply the scale/rotate/skew to each selected object separately; otherwise, " +"transform the selection as a whole" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:105 +#, fuzzy +msgid "Edit c_urrent matrix" +msgstr "Поднять текущий слой" + +#: ../../po/../src/ui/dialog/transformation.cpp:105 +msgid "" +"Edit the current transform= matrix; otherwise, post-multiply transform= by " +"this matrix" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:115 +#, fuzzy +msgid "_Move" +msgstr "Двигать" + +#: ../../po/../src/ui/dialog/transformation.cpp:118 +#, fuzzy +msgid "_Scale" +msgstr "Масштабировать" + +#: ../../po/../src/ui/dialog/transformation.cpp:121 +#, fuzzy +msgid "_Rotate" +msgstr "Вращать" + +#: ../../po/../src/ui/dialog/transformation.cpp:124 +#, fuzzy +msgid "Ske_w" +msgstr "Скос" + +#: ../../po/../src/ui/dialog/transformation.cpp:127 +msgid "Matri_x" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:141 +msgid "Reset the values on the current tab to defaults" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:148 +#, fuzzy +msgid "Apply transformation to selection" +msgstr "Применить эти изменения к объекту" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:43 +msgid "_Use SSL" +msgstr "_Использовать SSL" + +#. Construct dialog interface +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:68 +msgid "_Server:" +msgstr "_Сервер:" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:69 +msgid "_Username:" +msgstr "_Пользователь:" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:70 +msgid "_Password:" +msgstr "П_ароль:" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:71 +msgid "P_ort:" +msgstr "П_орт:" + +#. Buttons +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:99 +msgid "Connect" +msgstr "Соединиться" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:126 +msgid "Establishing connection to Jabber server %1 as user %2" +msgstr "" +"Устанавливается соединение с Jabber-сервером %1 под именем %2" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:131 +msgid "Failed to establish connection to Jabber server %1" +msgstr "Не удалось установить соединение с Jabber-сервером %1" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:136 +msgid "Authentication failed on Jabber server %1 as %2" +msgstr "" +"Не удалось пройти аутентификацию на Jabber-сервере %1 под именем %" +"2" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:141 +msgid "SSL initialization failed when connecting to Jabber server %1" +msgstr "Инициализация SSL не прошла при соединении с Jabber-сервером %1" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:147 +msgid "Connected to Jabber server %1 as %2" +msgstr "" +"Установлено соединение с Jabber-сервером %1 под именем %2" + +#. Construct labels +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:75 +msgid "Chatroom _name:" +msgstr "Имя _комнаты:" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:76 +msgid "Chatroom _server:" +msgstr "_Сервер комнаты:" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:77 +msgid "Chatroom _password:" +msgstr "_Пароль комнаты:" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:78 +msgid "Chatroom _handle:" +msgstr "_Прозвище в комнате:" + +#. Button setup and callback registration +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:97 +msgid "Connect to chatroom" +msgstr "Зайти в комнату" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:132 +msgid "Synchronizing with chatroom %1@%2 using the handle %3" +msgstr "Идет синхронизация с комнатой %1@%2 под прозвищем %3" + +#. Construct dialog interface +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:78 +msgid "_User's Jabber ID:" +msgstr "Jabber ID п_ользователя:" + +#. Buttons +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:82 +msgid "_Invite user" +msgstr "_Пригласить пользователя" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:83 +msgid "_Cancel" +msgstr "О_тменить" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:94 +msgid "Buddy List" +msgstr "Контактный список" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:170 +msgid "Sending whiteboard invitation to %1" +msgstr "" +"Пользователю %1 посылается приглашение на сессию совместного рисования" + +#. FIXME: strings are replaced by placeholders, NOT to be translated until the code is enabled +#. See http://sourceforge.net/mailarchive/message.php?msg_id=11746016 for details +#. File menu +#. Edit menu +#. View menu +#. Layer menu +#. Object menu +#. Path menu +#. add(Gtk::StockItem(CLEANUP, _("PLACEHOLDER, do not translate"))); (using Gtk::Stock::CLEAR) +#. Text menu +#. About menu +#. Tools toolbox +#. Select Tool controls +#. Node Tool controls +#. Calligraphy Tool controls +#. Session playback controls +#: ../../po/../src/ui/stock-items.cpp:34 ../../po/../src/ui/stock-items.cpp:35 +#: ../../po/../src/ui/stock-items.cpp:36 ../../po/../src/ui/stock-items.cpp:37 +#: ../../po/../src/ui/stock-items.cpp:38 ../../po/../src/ui/stock-items.cpp:39 +#: ../../po/../src/ui/stock-items.cpp:40 ../../po/../src/ui/stock-items.cpp:41 +#: ../../po/../src/ui/stock-items.cpp:42 ../../po/../src/ui/stock-items.cpp:43 +#: ../../po/../src/ui/stock-items.cpp:46 ../../po/../src/ui/stock-items.cpp:47 +#: ../../po/../src/ui/stock-items.cpp:48 ../../po/../src/ui/stock-items.cpp:49 +#: ../../po/../src/ui/stock-items.cpp:50 ../../po/../src/ui/stock-items.cpp:51 +#: ../../po/../src/ui/stock-items.cpp:52 ../../po/../src/ui/stock-items.cpp:53 +#: ../../po/../src/ui/stock-items.cpp:54 ../../po/../src/ui/stock-items.cpp:55 +#: ../../po/../src/ui/stock-items.cpp:56 ../../po/../src/ui/stock-items.cpp:57 +#: ../../po/../src/ui/stock-items.cpp:58 ../../po/../src/ui/stock-items.cpp:59 +#: ../../po/../src/ui/stock-items.cpp:62 ../../po/../src/ui/stock-items.cpp:63 +#: ../../po/../src/ui/stock-items.cpp:64 ../../po/../src/ui/stock-items.cpp:65 +#: ../../po/../src/ui/stock-items.cpp:66 ../../po/../src/ui/stock-items.cpp:67 +#: ../../po/../src/ui/stock-items.cpp:68 ../../po/../src/ui/stock-items.cpp:69 +#: ../../po/../src/ui/stock-items.cpp:70 ../../po/../src/ui/stock-items.cpp:71 +#: ../../po/../src/ui/stock-items.cpp:72 ../../po/../src/ui/stock-items.cpp:73 +#: ../../po/../src/ui/stock-items.cpp:74 ../../po/../src/ui/stock-items.cpp:75 +#: ../../po/../src/ui/stock-items.cpp:76 ../../po/../src/ui/stock-items.cpp:77 +#: ../../po/../src/ui/stock-items.cpp:78 ../../po/../src/ui/stock-items.cpp:79 +#: ../../po/../src/ui/stock-items.cpp:80 ../../po/../src/ui/stock-items.cpp:81 +#: ../../po/../src/ui/stock-items.cpp:82 ../../po/../src/ui/stock-items.cpp:83 +#: ../../po/../src/ui/stock-items.cpp:84 ../../po/../src/ui/stock-items.cpp:85 +#: ../../po/../src/ui/stock-items.cpp:86 ../../po/../src/ui/stock-items.cpp:87 +#: ../../po/../src/ui/stock-items.cpp:88 ../../po/../src/ui/stock-items.cpp:89 +#: ../../po/../src/ui/stock-items.cpp:92 ../../po/../src/ui/stock-items.cpp:93 +#: ../../po/../src/ui/stock-items.cpp:94 ../../po/../src/ui/stock-items.cpp:95 +#: ../../po/../src/ui/stock-items.cpp:96 ../../po/../src/ui/stock-items.cpp:97 +#: ../../po/../src/ui/stock-items.cpp:98 ../../po/../src/ui/stock-items.cpp:99 +#: ../../po/../src/ui/stock-items.cpp:100 +#: ../../po/../src/ui/stock-items.cpp:101 +#: ../../po/../src/ui/stock-items.cpp:102 +#: ../../po/../src/ui/stock-items.cpp:103 +#: ../../po/../src/ui/stock-items.cpp:104 +#: ../../po/../src/ui/stock-items.cpp:105 +#: ../../po/../src/ui/stock-items.cpp:108 +#: ../../po/../src/ui/stock-items.cpp:109 +#: ../../po/../src/ui/stock-items.cpp:110 +#: ../../po/../src/ui/stock-items.cpp:111 +#: ../../po/../src/ui/stock-items.cpp:112 +#: ../../po/../src/ui/stock-items.cpp:113 +#: ../../po/../src/ui/stock-items.cpp:114 +#: ../../po/../src/ui/stock-items.cpp:115 +#: ../../po/../src/ui/stock-items.cpp:116 +#: ../../po/../src/ui/stock-items.cpp:117 +#: ../../po/../src/ui/stock-items.cpp:118 +#: ../../po/../src/ui/stock-items.cpp:119 +#: ../../po/../src/ui/stock-items.cpp:120 +#: ../../po/../src/ui/stock-items.cpp:121 +#: ../../po/../src/ui/stock-items.cpp:122 +#: ../../po/../src/ui/stock-items.cpp:123 +#: ../../po/../src/ui/stock-items.cpp:124 +#: ../../po/../src/ui/stock-items.cpp:125 +#: ../../po/../src/ui/stock-items.cpp:126 +#: ../../po/../src/ui/stock-items.cpp:127 +#: ../../po/../src/ui/stock-items.cpp:130 +#: ../../po/../src/ui/stock-items.cpp:131 +#: ../../po/../src/ui/stock-items.cpp:132 +#: ../../po/../src/ui/stock-items.cpp:133 +#: ../../po/../src/ui/stock-items.cpp:134 +#: ../../po/../src/ui/stock-items.cpp:135 +#: ../../po/../src/ui/stock-items.cpp:136 +#: ../../po/../src/ui/stock-items.cpp:137 +#: ../../po/../src/ui/stock-items.cpp:138 +#: ../../po/../src/ui/stock-items.cpp:139 +#: ../../po/../src/ui/stock-items.cpp:140 +#: ../../po/../src/ui/stock-items.cpp:141 +#: ../../po/../src/ui/stock-items.cpp:142 +#: ../../po/../src/ui/stock-items.cpp:143 +#: ../../po/../src/ui/stock-items.cpp:144 +#: ../../po/../src/ui/stock-items.cpp:145 +#: ../../po/../src/ui/stock-items.cpp:146 +#: ../../po/../src/ui/stock-items.cpp:150 +#: ../../po/../src/ui/stock-items.cpp:151 +#: ../../po/../src/ui/stock-items.cpp:152 +#: ../../po/../src/ui/stock-items.cpp:153 +#: ../../po/../src/ui/stock-items.cpp:156 +#: ../../po/../src/ui/stock-items.cpp:157 +#: ../../po/../src/ui/stock-items.cpp:158 +#: ../../po/../src/ui/stock-items.cpp:161 +#: ../../po/../src/ui/stock-items.cpp:162 +#: ../../po/../src/ui/stock-items.cpp:163 +#: ../../po/../src/ui/stock-items.cpp:164 +#: ../../po/../src/ui/stock-items.cpp:165 +#: ../../po/../src/ui/stock-items.cpp:166 +#: ../../po/../src/ui/stock-items.cpp:167 +#: ../../po/../src/ui/stock-items.cpp:168 +#: ../../po/../src/ui/stock-items.cpp:169 +#: ../../po/../src/ui/stock-items.cpp:170 +#: ../../po/../src/ui/stock-items.cpp:171 +#: ../../po/../src/ui/stock-items.cpp:172 +#: ../../po/../src/ui/stock-items.cpp:175 +#: ../../po/../src/ui/stock-items.cpp:176 +#: ../../po/../src/ui/stock-items.cpp:177 +#: ../../po/../src/ui/stock-items.cpp:178 +#: ../../po/../src/ui/stock-items.cpp:181 +#: ../../po/../src/ui/stock-items.cpp:182 +#: ../../po/../src/ui/stock-items.cpp:183 +#: ../../po/../src/ui/stock-items.cpp:184 +#: ../../po/../src/ui/stock-items.cpp:185 +#: ../../po/../src/ui/stock-items.cpp:186 +#: ../../po/../src/ui/stock-items.cpp:187 +#: ../../po/../src/ui/stock-items.cpp:188 +#: ../../po/../src/ui/stock-items.cpp:189 +#: ../../po/../src/ui/stock-items.cpp:190 +#: ../../po/../src/ui/stock-items.cpp:191 +#: ../../po/../src/ui/stock-items.cpp:194 +#: ../../po/../src/ui/stock-items.cpp:195 +#: ../../po/../src/ui/stock-items.cpp:198 +#: ../../po/../src/ui/stock-items.cpp:199 +#: ../../po/../src/ui/stock-items.cpp:200 +#: ../../po/../src/ui/stock-items.cpp:201 +#: ../../po/../src/ui/stock-items.cpp:202 +msgid "PLACEHOLDER, do not translate" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:88 +msgid "small" +msgstr "Маленькие" + +#: ../../po/../src/ui/widget/panel.cpp:89 +msgid "medium" +msgstr "Средние" + +#: ../../po/../src/ui/widget/panel.cpp:90 +msgid "large" +msgstr "Большие" + +#: ../../po/../src/ui/widget/panel.cpp:91 +msgid "huge" +msgstr "Огромные" + +#: ../../po/../src/ui/widget/panel.cpp:106 +msgid "List" +msgstr "Список" + +#: ../../po/../src/ui/widget/selected-style.cpp:67 +msgid "F:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:68 +msgid "S:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:69 +msgid "O:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:95 +msgid "N/A" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:98 +#: ../../po/../src/ui/widget/selected-style.cpp:712 +#, fuzzy +msgid "Nothing selected" +msgstr "Градиент не выделен" + +#: ../../po/../src/ui/widget/selected-style.cpp:103 +msgid "No fill" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:103 +#, fuzzy +msgid "No stroke" +msgstr "(штрих)" + +#: ../../po/../src/ui/widget/selected-style.cpp:105 +#: ../../po/../src/widgets/paint-selector.cpp:190 +msgid "Pattern" +msgstr "Текстурная заливка" + +#: ../../po/../src/ui/widget/selected-style.cpp:108 +#: ../../po/../src/widgets/paint-selector.cpp:885 +msgid "Pattern fill" +msgstr "Текстурная заливка" + +#: ../../po/../src/ui/widget/selected-style.cpp:108 +#, fuzzy +msgid "Pattern stroke" +msgstr "Смещение пунктира" + +#: ../../po/../src/ui/widget/selected-style.cpp:110 +#, fuzzy +msgid "L Gradient" +msgstr "Градиент" + +#: ../../po/../src/ui/widget/selected-style.cpp:113 +#, fuzzy +msgid "Linear gradient fill" +msgstr "Линейный градиент" + +#: ../../po/../src/ui/widget/selected-style.cpp:113 +#, fuzzy +msgid "Linear gradient stroke" +msgstr "Линейный градиент" + +#: ../../po/../src/ui/widget/selected-style.cpp:115 +#, fuzzy +msgid "R Gradient" +msgstr "Градиент" + +#: ../../po/../src/ui/widget/selected-style.cpp:118 +#, fuzzy +msgid "Radial gradient fill" +msgstr "Радиальный градиент" + +#: ../../po/../src/ui/widget/selected-style.cpp:118 +#, fuzzy +msgid "Radial gradient stroke" +msgstr "Радиальный градиент" + +#: ../../po/../src/ui/widget/selected-style.cpp:120 +#, fuzzy +msgid "Different" +msgstr "_Разность" + +#: ../../po/../src/ui/widget/selected-style.cpp:123 +#, fuzzy +msgid "Different fills" +msgstr "_Разность" + +#: ../../po/../src/ui/widget/selected-style.cpp:123 +#, fuzzy +msgid "Different strokes" +msgstr "_Разность" + +#: ../../po/../src/ui/widget/selected-style.cpp:125 +#, fuzzy +msgid "Unset" +msgstr "втянута" + +#. TRANSLATORS COMMENT: unset is a verb here +#: ../../po/../src/ui/widget/selected-style.cpp:128 +#: ../../po/../src/ui/widget/selected-style.cpp:182 +msgid "Unset fill" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:128 +#: ../../po/../src/ui/widget/selected-style.cpp:182 +#, fuzzy +msgid "Unset stroke" +msgstr "(штрих)" + +#: ../../po/../src/ui/widget/selected-style.cpp:131 +#, fuzzy +msgid "Flat color fill" +msgstr "Плоский цвет" + +#: ../../po/../src/ui/widget/selected-style.cpp:131 +#, fuzzy +msgid "Flat color stroke" +msgstr "Плоский цвет" + +#. TRANSLATOR COMMENT: A means "Averaged" +#: ../../po/../src/ui/widget/selected-style.cpp:134 +#, fuzzy +msgid "A" +msgstr "_A" + +#: ../../po/../src/ui/widget/selected-style.cpp:137 +#, fuzzy +msgid "Fill is averaged over selected objects" +msgstr "Исключающее ИЛИ выделенных объектов" + +#: ../../po/../src/ui/widget/selected-style.cpp:137 +#, fuzzy +msgid "Stroke is averaged over selected objects" +msgstr "Линии обходят выделенные объекты" + +#. TRANSLATOR COMMENT: M means "Multiple" +#: ../../po/../src/ui/widget/selected-style.cpp:140 +#, fuzzy +msgid "M" +msgstr "_M" + +#: ../../po/../src/ui/widget/selected-style.cpp:143 +#, fuzzy +msgid "Multiple selected objects have the same fill" +msgstr "Отражает выделенные объекты по вертикали" + +#: ../../po/../src/ui/widget/selected-style.cpp:143 +#, fuzzy +msgid "Multiple selected objects have the same stroke" +msgstr "Отражает выделенные объекты по вертикали" + +#: ../../po/../src/ui/widget/selected-style.cpp:145 +#, fuzzy +msgid "Edit fill..." +msgstr "Правка..." + +#: ../../po/../src/ui/widget/selected-style.cpp:145 +#, fuzzy +msgid "Edit stroke..." +msgstr "Правка..." + +#: ../../po/../src/ui/widget/selected-style.cpp:149 +#, fuzzy +msgid "Last set color" +msgstr "Плоский цвет" + +#: ../../po/../src/ui/widget/selected-style.cpp:153 +#, fuzzy +msgid "Last selected color" +msgstr "Последнего выделенного" + +#: ../../po/../src/ui/widget/selected-style.cpp:157 +#, fuzzy +msgid "White" +msgstr "_Доска" + +#: ../../po/../src/ui/widget/selected-style.cpp:161 +#: ../../po/../src/widgets/sp-color-scales.cpp:461 +#: ../../po/../src/widgets/sp-color-scales.cpp:462 +msgid "Black" +msgstr "Черный" + +#: ../../po/../src/ui/widget/selected-style.cpp:165 +#, fuzzy +msgid "Copy color" +msgstr "Цвет опорной точки" + +#: ../../po/../src/ui/widget/selected-style.cpp:169 +#, fuzzy +msgid "Paste color" +msgstr "Плоский цвет" + +#: ../../po/../src/ui/widget/selected-style.cpp:173 +#, fuzzy +msgid "Swap fill and stroke" +msgstr "_Заливка и штрих" + +#: ../../po/../src/ui/widget/selected-style.cpp:177 +msgid "Make fill opaque" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:177 +msgid "Make stroke opaque" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:186 +#, fuzzy +msgid "Remove fill" +msgstr " _Удалить " + +#: ../../po/../src/ui/widget/selected-style.cpp:186 +#, fuzzy +msgid "Remove stroke" +msgstr "_Удалить ссылку" + +#: ../../po/../src/ui/widget/selected-style.cpp:718 +#, fuzzy +msgid "Master opacity" +msgstr "Общая прозрачность" + +#: ../../po/../src/ui/widget/selected-style.cpp:744 +msgid "0 (transparent)" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:768 +msgid "1.0 (opaque)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1046 +msgid "Moved to next layer." +msgstr "Перемещен на следующий слой." + +#: ../../po/../src/verbs.cpp:1048 +msgid "Cannot move past last layer." +msgstr "Невозможно переместить за последний слой." + +#: ../../po/../src/verbs.cpp:1057 +msgid "Moved to previous layer." +msgstr "Перемещен на предыдущий слой." + +#: ../../po/../src/verbs.cpp:1059 +msgid "Cannot move past first layer." +msgstr "Невозможно переместить выше первого слоя." + +#: ../../po/../src/verbs.cpp:1076 ../../po/../src/verbs.cpp:1150 +msgid "No current layer." +msgstr "Нет текущего слоя." + +#: ../../po/../src/verbs.cpp:1105 +#, c-format +msgid "Raised layer %s." +msgstr "Поднят слой %s." + +#: ../../po/../src/verbs.cpp:1109 +#, c-format +msgid "Lowered layer %s." +msgstr "Опущен слой %s." + +#: ../../po/../src/verbs.cpp:1118 +msgid "Cannot move layer any further." +msgstr "Невозможно переместить слой дальше." + +#. TRANSLATORS: this means "The layer has been deleted." +#: ../../po/../src/verbs.cpp:1148 +msgid "Deleted layer." +msgstr "Слой удален." + +#: ../../po/../src/verbs.cpp:1544 +msgid "" +"You need to connect to a Jabber server before sharing a document with " +"another user." +msgstr "" +"Необходимо сначала соединиться с Jabber-сервером для того, чтобы работать " +"над одним документом с другим пользователем." + +#: ../../po/../src/verbs.cpp:1559 +msgid "" +"You need to connect to a Jabber server before sharing a document with a " +"chatroom." +msgstr "" +"Необходимо сначала соединиться с Jabber-сервером для того, чтобы работать " +"над одним документом всей комнатой." + +#: ../../po/../src/verbs.cpp:1569 +msgid "XML node tracker has not been initialized; nothing to dump" +msgstr "" + +#. TRANSLATORS: If you have translated the keys.svg file to your language, then +#. translate this string as "keys.LANG.svg" (where LANG is your language code); +#. otherwise leave as "keys.svg". +#: ../../po/../src/verbs.cpp:1631 +msgid "keys.svg" +msgstr "keys.svg" + +#. TRANSLATORS: If you have translated the tutorial-basic.svg file to your language, +#. then translate this string as "tutorial-basic.LANG.svg" (where LANG is your language +#. code); otherwise leave as "tutorial-basic.svg". +#: ../../po/../src/verbs.cpp:1667 +msgid "tutorial-basic.svg" +msgstr "tutorial-basic.ru.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1671 +msgid "tutorial-shapes.svg" +msgstr "tutorial-shapes.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1675 +msgid "tutorial-advanced.svg" +msgstr "tutorial-advanced.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1679 +msgid "tutorial-tracing.svg" +msgstr "tutorial-tracing.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1683 +msgid "tutorial-calligraphy.svg" +msgstr "tutorial-calligraphy.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1687 +msgid "tutorial-elements.svg" +msgstr "tutorial-elements.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1691 +msgid "tutorial-tips.svg" +msgstr "tutorial-tips.svg" + +#: ../../po/../src/verbs.cpp:1842 +msgid "Does nothing" +msgstr "Нет действий" + +#. File +#: ../../po/../src/verbs.cpp:1845 +msgid "Default" +msgstr "По умолчанию" + +#: ../../po/../src/verbs.cpp:1845 +msgid "Create new document from default template" +msgstr "Создать новый документ из стандартного шаблона" + +#: ../../po/../src/verbs.cpp:1847 +msgid "_Open..." +msgstr "_Открыть..." + +#: ../../po/../src/verbs.cpp:1848 +msgid "Open existing document" +msgstr "Открыть существующий документ" + +#: ../../po/../src/verbs.cpp:1849 +msgid "Re_vert" +msgstr "Ве_рнуться к сохраненному" + +#: ../../po/../src/verbs.cpp:1850 +msgid "Revert to the last saved version of document (changes will be lost)" +msgstr "" +"Вернуться к последней сохраненной версии документа (изменения будут потеряны)" + +#: ../../po/../src/verbs.cpp:1851 +msgid "_Save" +msgstr "Со_хранить" + +#: ../../po/../src/verbs.cpp:1851 +msgid "Save document" +msgstr "Сохранить документ" + +#: ../../po/../src/verbs.cpp:1853 +msgid "Save _As..." +msgstr "Сохранить _как..." + +#: ../../po/../src/verbs.cpp:1854 +msgid "Save document under new name" +msgstr "Сохранить документ под другим именем" + +#: ../../po/../src/verbs.cpp:1855 +msgid "_Print..." +msgstr "На_печатать..." + +#: ../../po/../src/verbs.cpp:1855 +msgid "Print document" +msgstr "Напечатать документ" + +#. TRANSLATORS: "Vacuum Defs" means "Clean up defs" (so as to remove unused definitions) +#: ../../po/../src/verbs.cpp:1858 +msgid "Vac_uum Defs" +msgstr "О_чистить defs" + +#: ../../po/../src/verbs.cpp:1858 +msgid "Remove unused predefined items from the <defs> of the document" +msgstr "Убрать ненужное из <defs> документа" + +#: ../../po/../src/verbs.cpp:1860 +msgid "Print _Direct" +msgstr "П_рямая печать" + +#: ../../po/../src/verbs.cpp:1861 +msgid "Print directly without prompting to a file or pipe" +msgstr "Напечатать прямо в файл или передать другой программе" + +#: ../../po/../src/verbs.cpp:1862 +msgid "Print Previe_w" +msgstr "Предпросмотр печати" + +#: ../../po/../src/verbs.cpp:1863 +msgid "Preview document printout" +msgstr "Предварительный просмотр печати" + +#: ../../po/../src/verbs.cpp:1864 +msgid "_Import..." +msgstr "_Импортировать..." + +#: ../../po/../src/verbs.cpp:1865 +msgid "Import bitmap or SVG image into document" +msgstr "Импортировать растровое или SVG-изображение в документ" + +#: ../../po/../src/verbs.cpp:1866 +msgid "_Export Bitmap..." +msgstr "_Экспортировать в растр..." + +#: ../../po/../src/verbs.cpp:1867 +msgid "Export document or selection as a bitmap image" +msgstr "Экспортировать документ или выделенное в PNG" + +#: ../../po/../src/verbs.cpp:1868 +msgid "N_ext Window" +msgstr "Сл_едующее окно" + +#: ../../po/../src/verbs.cpp:1869 +msgid "Switch to the next document window" +msgstr "Переключиться в следующее окно документа" + +#: ../../po/../src/verbs.cpp:1870 +msgid "P_revious Window" +msgstr "_Предыдущее окно" + +#: ../../po/../src/verbs.cpp:1871 +msgid "Switch to the previous document window" +msgstr "Переключиться в предыдущее окно документа" + +#: ../../po/../src/verbs.cpp:1872 +msgid "_Close" +msgstr "_Закрыть" + +#: ../../po/../src/verbs.cpp:1873 +msgid "Close window" +msgstr "Закрыть окно" + +#: ../../po/../src/verbs.cpp:1874 +msgid "_Quit" +msgstr "В_ыйти" + +#: ../../po/../src/verbs.cpp:1874 +msgid "Quit Inkscape" +msgstr "Выйти из Inkscape" + +#. Edit +#: ../../po/../src/verbs.cpp:1877 +msgid "_Undo" +msgstr "_Отменить" + +#: ../../po/../src/verbs.cpp:1877 +msgid "Undo last action" +msgstr "Отменить последнее действие" + +#: ../../po/../src/verbs.cpp:1879 +msgid "_Redo" +msgstr "_Повторить" + +#: ../../po/../src/verbs.cpp:1880 +msgid "Do again last undone action" +msgstr "Повторить последнее отмененное действие" + +#: ../../po/../src/verbs.cpp:1881 +msgid "Cu_t" +msgstr "_Вырезать" + +#: ../../po/../src/verbs.cpp:1882 +msgid "Cut selection to clipboard" +msgstr "Вырезать выделение в буфер обмена" + +#: ../../po/../src/verbs.cpp:1883 +msgid "_Copy" +msgstr "С_копировать" + +#: ../../po/../src/verbs.cpp:1884 +msgid "Copy selection to clipboard" +msgstr "Скопировать выделение в буфер обмена" + +#: ../../po/../src/verbs.cpp:1885 +msgid "_Paste" +msgstr "Вст_авить" + +#: ../../po/../src/verbs.cpp:1886 +msgid "Paste objects from clipboard to mouse point" +msgstr "Вставить объект из буфера обмена под курсор" + +#: ../../po/../src/verbs.cpp:1887 +msgid "Paste _Style" +msgstr "Вставить стиль" + +#: ../../po/../src/verbs.cpp:1888 +msgid "Apply style of the copied object to selection" +msgstr "Применить стиль скопированного объекта к выделению" + +#: ../../po/../src/verbs.cpp:1889 +msgid "Paste _In Place" +msgstr "Вставить на место" + +#: ../../po/../src/verbs.cpp:1890 +msgid "Paste objects from clipboard to the original location" +msgstr "Вставить объекты из буфера обмена в их исходное метосположение" + +#: ../../po/../src/verbs.cpp:1891 +msgid "_Delete" +msgstr "У_далить" + +#: ../../po/../src/verbs.cpp:1892 +msgid "Delete selection" +msgstr "Удалить выделение" + +#: ../../po/../src/verbs.cpp:1893 +msgid "Duplic_ate" +msgstr "Проду_блировать" + +#: ../../po/../src/verbs.cpp:1894 +msgid "Duplicate selected objects" +msgstr "Продублировать выделенные объекты" + +#: ../../po/../src/verbs.cpp:1895 +msgid "Clo_ne" +msgstr "Кло_нировать" + +#: ../../po/../src/verbs.cpp:1896 +msgid "Create a clone of selected object (a copy linked to the original)" +msgstr "Создать клон выделенного объекта (копию, связанную с оригиналом)" + +#: ../../po/../src/verbs.cpp:1897 +msgid "Unlin_k Clone" +msgstr "О_тсоединить клон" + +#: ../../po/../src/verbs.cpp:1898 +msgid "Cut the clone's link to its original" +msgstr "Убрать ссылку клона на его оригинал" + +#: ../../po/../src/verbs.cpp:1899 +msgid "Select _Original" +msgstr "Выделить _оригинал" + +#: ../../po/../src/verbs.cpp:1900 +msgid "Select the object to which the clone is linked" +msgstr "Выделить объект, с которым связан клон" + +#. TRANSLATORS: Convert selection to a rectangle with tiled pattern fill +#: ../../po/../src/verbs.cpp:1902 +msgid "O_bjects to Pattern" +msgstr "_Объект(ы) в текстуру" + +#: ../../po/../src/verbs.cpp:1903 +msgid "Convert selection to a rectangle with tiled pattern fill" +msgstr "Преобразовать выделение в прямоугольник, заполненный текстурой" + +#. TRANSLATORS: Extract objects from a tiled pattern fill +#: ../../po/../src/verbs.cpp:1905 +msgid "Pattern to Ob_jects" +msgstr "Текстуру в о_бъект(ы)" + +#: ../../po/../src/verbs.cpp:1906 +msgid "Extract objects from a tiled pattern fill" +msgstr "Извлечь объекты из текстурной заливки" + +#: ../../po/../src/verbs.cpp:1907 +msgid "Clea_r All" +msgstr "О_чистить все" + +#: ../../po/../src/verbs.cpp:1908 +msgid "Delete all objects from document" +msgstr "Удалить все объекты из документа" + +#: ../../po/../src/verbs.cpp:1909 +msgid "Select Al_l" +msgstr "Выделить _все" + +#: ../../po/../src/verbs.cpp:1910 +msgid "Select all objects or all nodes" +msgstr "Выделить все объекты или все узлы" + +#: ../../po/../src/verbs.cpp:1911 +msgid "Select All in All La_yers" +msgstr "Выделить все во всех сло_ях" + +#: ../../po/../src/verbs.cpp:1912 +msgid "Select all objects in all visible and unlocked layers" +msgstr "Выделить все объекты во всех видимых и незапертых слоях" + +#: ../../po/../src/verbs.cpp:1913 +msgid "In_vert Selection" +msgstr "Инвертировать выделение" + +#: ../../po/../src/verbs.cpp:1914 +msgid "Invert selection (unselect what is selected and select everything else)" +msgstr "" +"Инвертировать выделение (выделить все кроме выделенного в настоящий момент)" + +#: ../../po/../src/verbs.cpp:1915 +msgid "Invert in All Layers" +msgstr "Инвертировать во всех слоях" + +#: ../../po/../src/verbs.cpp:1916 +msgid "Invert selection in all visible and unlocked layers" +msgstr "Инвертировать выделение во всех видимых и незапертых слоях" + +#: ../../po/../src/verbs.cpp:1917 +msgid "D_eselect" +msgstr "С_нять выделение" + +#: ../../po/../src/verbs.cpp:1918 +msgid "Deselect any selected objects or nodes" +msgstr "Снять выделение со всех объектов или узлов" + +#. Selection +#: ../../po/../src/verbs.cpp:1921 +msgid "Raise to _Top" +msgstr "Поднять на _передний план" + +#: ../../po/../src/verbs.cpp:1922 +msgid "Raise selection to top" +msgstr "Поднять выделение на передний план" + +#: ../../po/../src/verbs.cpp:1923 +msgid "Lower to _Bottom" +msgstr "Опустить на _задний план" + +#: ../../po/../src/verbs.cpp:1924 +msgid "Lower selection to bottom" +msgstr "Опустить выделение на задний план" + +#: ../../po/../src/verbs.cpp:1925 +msgid "_Raise" +msgstr "П_однять" + +#: ../../po/../src/verbs.cpp:1926 +msgid "Raise selection one step" +msgstr "Поднять выделение на один уровень" + +#: ../../po/../src/verbs.cpp:1927 +msgid "_Lower" +msgstr "Опу_стить" + +#: ../../po/../src/verbs.cpp:1928 +msgid "Lower selection one step" +msgstr "Опустить выделение на один уровень" + +#: ../../po/../src/verbs.cpp:1929 +msgid "_Group" +msgstr "С_группировать" + +#: ../../po/../src/verbs.cpp:1930 +msgid "Group selected objects" +msgstr "Сгруппировать выделенные объекты" + +#: ../../po/../src/verbs.cpp:1932 +msgid "Ungroup selected groups" +msgstr "Разгруппировать выделенные группы" + +#: ../../po/../src/verbs.cpp:1934 +msgid "_Put on Path" +msgstr "_Разместить по контуру" + +#: ../../po/../src/verbs.cpp:1935 +msgid "Put text on path" +msgstr "Разместить текст по контуру" + +#: ../../po/../src/verbs.cpp:1936 +msgid "_Remove from Path" +msgstr "_Снять с контура" + +#: ../../po/../src/verbs.cpp:1937 +msgid "Remove text from path" +msgstr "Снять текст с контура" + +#: ../../po/../src/verbs.cpp:1938 +msgid "Remove Manual _Kerns" +msgstr "Убрать ручной _кернинг" + +#. TRANSLATORS: "glyph": An image used in the visual representation of characters; +#. roughly speaking, how a character looks. A font is a set of glyphs. +#: ../../po/../src/verbs.cpp:1941 +msgid "Remove all manual kerns and glyph rotations from a text object" +msgstr "Удалить из текста все вертикальные и горизонтальные керны и вращения" + +#: ../../po/../src/verbs.cpp:1943 +msgid "_Union" +msgstr "С_умма" + +#: ../../po/../src/verbs.cpp:1944 +msgid "Union of selected objects" +msgstr "Сумма выделенных объектов" + +#: ../../po/../src/verbs.cpp:1945 +msgid "_Intersection" +msgstr "_Пересечение" + +#: ../../po/../src/verbs.cpp:1946 +msgid "Intersection of selected objects" +msgstr "Пересечение выделенных объектов" + +#: ../../po/../src/verbs.cpp:1947 +msgid "_Difference" +msgstr "_Разность" + +#: ../../po/../src/verbs.cpp:1948 +msgid "Difference of selected objects (bottom minus top)" +msgstr "Разность выделенных объектов (низ минус верх)" + +#: ../../po/../src/verbs.cpp:1949 +msgid "E_xclusion" +msgstr "_Исключающее ИЛИ" + +#: ../../po/../src/verbs.cpp:1950 +msgid "Exclusive OR of selected objects" +msgstr "Исключающее ИЛИ выделенных объектов" + +#: ../../po/../src/verbs.cpp:1951 +msgid "Di_vision" +msgstr "Разделить" + +#: ../../po/../src/verbs.cpp:1952 +msgid "Cut the bottom object into pieces" +msgstr "Разделить нижний объект на части верхним" + +#. TRANSLATORS: "to cut a path" is not the same as "to break a path apart" - see the +#. Advanced tutorial for more info +#: ../../po/../src/verbs.cpp:1955 +msgid "Cut _Path" +msgstr "Разрезать контур" + +#: ../../po/../src/verbs.cpp:1956 +msgid "Cut the bottom object's stroke into pieces, removing fill" +msgstr "Разрезать контур нижнего объекта на части с удалением заливки" + +#. TRANSLATORS: "outset": expand a shape by offsetting the object's path, +#. i.e. by displacing it perpendicular to the path in each point. +#. See also the Advanced Tutorial for explanation. +#: ../../po/../src/verbs.cpp:1960 +msgid "Outs_et" +msgstr "Вы_тянуть" + +#: ../../po/../src/verbs.cpp:1961 +msgid "Outset selected paths" +msgstr "Вытянуть выделенный контур" + +#: ../../po/../src/verbs.cpp:1963 +msgid "O_utset Path by 1 px" +msgstr "_Вытянуть контур на 1 px" + +#: ../../po/../src/verbs.cpp:1964 +msgid "Outset selected paths by 1 px" +msgstr "Вытянуть выделенный контур на 1 px" + +#: ../../po/../src/verbs.cpp:1966 +msgid "O_utset Path by 10 px" +msgstr "_Вытянуть контур на 10 px" + +#: ../../po/../src/verbs.cpp:1967 +msgid "Outset selected paths by 10 px" +msgstr "Вытянуть выделенный контур на 10 px" + +#. TRANSLATORS: "inset": contract a shape by offsetting the object's path, +#. i.e. by displacing it perpendicular to the path in each point. +#. See also the Advanced Tutorial for explanation. +#: ../../po/../src/verbs.cpp:1971 +msgid "I_nset" +msgstr "Втян_уть" + +#: ../../po/../src/verbs.cpp:1972 +msgid "Inset selected paths" +msgstr "Втянуть выделенный контур" + +#: ../../po/../src/verbs.cpp:1974 +msgid "I_nset Path by 1 px" +msgstr "Втян_уть контур на 1 px" + +#: ../../po/../src/verbs.cpp:1975 +msgid "Inset selected paths by 1 px" +msgstr "Втянуть выделенный контур на 1 px" + +#: ../../po/../src/verbs.cpp:1977 +msgid "I_nset Path by 10 px" +msgstr "Втян_уть контур на 10 px" + +#: ../../po/../src/verbs.cpp:1978 +msgid "Inset selected paths by 10 px" +msgstr "Втянуть выделенный контур на 10 px" + +#: ../../po/../src/verbs.cpp:1980 +msgid "D_ynamic Offset" +msgstr "_Динамическая втяжка" + +#: ../../po/../src/verbs.cpp:1980 +msgid "Create a dynamic offset object" +msgstr "Создать объект, втяжку/растяжку которого можно менять динамически" + +#: ../../po/../src/verbs.cpp:1982 +msgid "_Linked Offset" +msgstr "С_вязанная втяжка" + +#: ../../po/../src/verbs.cpp:1983 +msgid "Create a dynamic offset object linked to the original path" +msgstr "Создать втяжку/растяжку, динамически связанную с исходным контуром" + +#: ../../po/../src/verbs.cpp:1985 +msgid "_Stroke to Path" +msgstr "Оконтурить _штрих" + +#: ../../po/../src/verbs.cpp:1986 +msgid "Convert selected strokes to paths" +msgstr "Преобразовать выделенные штрихи в контуры" + +#: ../../po/../src/verbs.cpp:1987 +msgid "Si_mplify" +msgstr "_Упростить" + +#: ../../po/../src/verbs.cpp:1988 +msgid "Simplify selected paths by removing extra nodes" +msgstr "Упростить выделенные контуры удалением лишних узлов" + +#: ../../po/../src/verbs.cpp:1989 +msgid "_Reverse" +msgstr "_Развернуть" + +#: ../../po/../src/verbs.cpp:1990 +msgid "Reverses the direction of selected paths; useful for flipping markers" +msgstr "" +"Развернуть направление выделенных контуров; полезно для отражения маркеров" + +#. TRANSLATORS: "to trace" means "to convert a bitmap to vector graphics" (to vectorize) +#: ../../po/../src/verbs.cpp:1992 +msgid "_Trace Bitmap" +msgstr "_Векторизовать растр" + +#: ../../po/../src/verbs.cpp:1993 +msgid "Convert bitmap object to paths" +msgstr "Преобразовать растровый объект в контуры" + +#: ../../po/../src/verbs.cpp:1994 +msgid "_Make a Bitmap Copy" +msgstr "_Сделать растровую копию" + +#: ../../po/../src/verbs.cpp:1995 +msgid "Export selection to a bitmap and insert it into document" +msgstr "Экспортировать выделение в растр и вставить его в документ" + +#: ../../po/../src/verbs.cpp:1996 +msgid "_Combine" +msgstr "_Объединить" + +#: ../../po/../src/verbs.cpp:1997 +msgid "Combine several paths into one" +msgstr "Объединить несколько контуров в один" + +#. TRANSLATORS: "to cut a path" is not the same as "to break a path apart" - see the +#. Advanced tutorial for more info +#: ../../po/../src/verbs.cpp:2000 +msgid "Break _Apart" +msgstr "_Разбить" + +#: ../../po/../src/verbs.cpp:2001 +msgid "Break selected paths into subpaths" +msgstr "Разбить выделенные контуры на части" + +#: ../../po/../src/verbs.cpp:2002 +msgid "Gri_d Arrange..." +msgstr "_Распределить по сетке..." + +#: ../../po/../src/verbs.cpp:2003 +msgid "Arrange selection in grid pattern" +msgstr "Расставить выделенные объекты по сетке" + +#. Layer +#: ../../po/../src/verbs.cpp:2005 +msgid "_Add Layer..." +msgstr "_Новый слой..." + +#: ../../po/../src/verbs.cpp:2006 +msgid "Create a new layer" +msgstr "Создать новый слой" + +#: ../../po/../src/verbs.cpp:2007 +msgid "Re_name Layer..." +msgstr "_Переименовать слой..." + +#: ../../po/../src/verbs.cpp:2008 +msgid "Rename the current layer" +msgstr "Переименовать текущий слой" + +#: ../../po/../src/verbs.cpp:2009 +msgid "Switch to Layer Abov_e" +msgstr "Перейти на слой _выше" + +#: ../../po/../src/verbs.cpp:2010 +msgid "Switch to the layer above the current" +msgstr "Перейти на слой, находящийся выше текущего" + +#: ../../po/../src/verbs.cpp:2011 +msgid "Switch to Layer Belo_w" +msgstr "Перейти на слой _ниже" + +#: ../../po/../src/verbs.cpp:2012 +msgid "Switch to the layer below the current" +msgstr "Перейти на слой, находящийся под текущим" + +#: ../../po/../src/verbs.cpp:2013 +msgid "Move Selection to Layer Abo_ve" +msgstr "Перенести выделение в слой _выше" + +#: ../../po/../src/verbs.cpp:2014 +msgid "Move selection to the layer above the current" +msgstr "Перенести выделение в слой над текущим слоем" + +#: ../../po/../src/verbs.cpp:2015 +msgid "Move Selection to Layer Bel_ow" +msgstr "Перенести выделение в слой _ниже" + +#: ../../po/../src/verbs.cpp:2016 +msgid "Move selection to the layer below the current" +msgstr "Перенести выделение в слой ниже текущего слоя" + +#: ../../po/../src/verbs.cpp:2017 +msgid "Layer to _Top" +msgstr "Поднять до _верха" + +#: ../../po/../src/verbs.cpp:2018 +msgid "Raise the current layer to the top" +msgstr "Поднять текущий слой на самый верх" + +#: ../../po/../src/verbs.cpp:2019 +msgid "Layer to _Bottom" +msgstr "Опустить до _низа" + +#: ../../po/../src/verbs.cpp:2020 +msgid "Lower the current layer to the bottom" +msgstr "Опустить текущий слой на самый низ" + +#: ../../po/../src/verbs.cpp:2021 +msgid "_Raise Layer" +msgstr "П_однять слой" + +#: ../../po/../src/verbs.cpp:2022 +msgid "Raise the current layer" +msgstr "Поднять текущий слой" + +#: ../../po/../src/verbs.cpp:2023 +msgid "_Lower Layer" +msgstr "Опу_стить слой" + +#: ../../po/../src/verbs.cpp:2024 +msgid "Lower the current layer" +msgstr "Опустить текущий слой" + +#: ../../po/../src/verbs.cpp:2025 +msgid "_Delete Current Layer" +msgstr "_Удалить текущий слой" + +#: ../../po/../src/verbs.cpp:2026 +msgid "Delete the current layer" +msgstr "Удалить текущий слой" + +#. Object +#: ../../po/../src/verbs.cpp:2029 +#, fuzzy +msgid "Rotate _90° CW" +msgstr "Повернуть на _90° по часовой стрелке" + +#: ../../po/../src/verbs.cpp:2030 +#, fuzzy +msgid "Rotate selection 90° clockwise" +msgstr "Повернуть выделенные объекты на 90° по часовой стрелке" + +#: ../../po/../src/verbs.cpp:2031 +#, fuzzy +msgid "Rotate 9_0° CCW" +msgstr "Повернуть на 9_0° против часовой стрелки" + +#: ../../po/../src/verbs.cpp:2032 +#, fuzzy +msgid "Rotate selection 90° counter-clockwise" +msgstr "Повернуть выделенные объекты на 90° против часовой стрелки" + +#: ../../po/../src/verbs.cpp:2033 +msgid "Remove _Transformations" +msgstr "Убрать трансформацию" + +#: ../../po/../src/verbs.cpp:2034 +msgid "Remove transformations from object" +msgstr "Убрать неоптимизированную трансформацию объекта" + +#: ../../po/../src/verbs.cpp:2035 +msgid "_Object to Path" +msgstr "_Оконтурить" + +#: ../../po/../src/verbs.cpp:2036 +msgid "Convert selected objects to paths" +msgstr "Преобразовать выделенные объекты в контуры" + +#: ../../po/../src/verbs.cpp:2037 +msgid "_Flow into Frame" +msgstr "_Заверстать в рамку" + +#: ../../po/../src/verbs.cpp:2038 +msgid "Put text into frames" +msgstr "Заверстать текст в рамку" + +#: ../../po/../src/verbs.cpp:2039 +msgid "_Unflow" +msgstr "_Вынуть из рамки" + +#: ../../po/../src/verbs.cpp:2040 +msgid "Remove text from frame (creates a single-line text object)" +msgstr "Вынуть текст из рамки, создав обычный текстовый объект в одну строку" + +#: ../../po/../src/verbs.cpp:2041 +msgid "_Convert to Text" +msgstr "_Преобразовать в текст" + +#: ../../po/../src/verbs.cpp:2042 +msgid "Convert flowed text to regular text objects (preserves appearance)" +msgstr "" +"Преобразовать текст, заверстанный в рамку, в обычный текст, сохранив " +"форматирование)" + +#: ../../po/../src/verbs.cpp:2044 +msgid "Flip _Horizontal" +msgstr "Отразить _горизонтально" + +#: ../../po/../src/verbs.cpp:2044 +msgid "Flips selected objects horizontally" +msgstr "Отражает выделенные объекты по горизонтали" + +#: ../../po/../src/verbs.cpp:2047 +msgid "Flip _Vertical" +msgstr "Отразить _вертикально" + +#: ../../po/../src/verbs.cpp:2047 +msgid "Flips selected objects vertically" +msgstr "Отражает выделенные объекты по вертикали" + +#. Tools +#: ../../po/../src/verbs.cpp:2051 +msgid "Select" +msgstr "Селектор" + +#: ../../po/../src/verbs.cpp:2052 +msgid "Select and transform objects" +msgstr "Выделение и трансформация объектов" + +#: ../../po/../src/verbs.cpp:2053 +msgid "Node Edit" +msgstr "Инструмент узлов" + +#: ../../po/../src/verbs.cpp:2054 +msgid "Edit path nodes or control handles" +msgstr "Редактировать узлы контура или усы узлов" + +#: ../../po/../src/verbs.cpp:2056 +msgid "Create rectangles and squares" +msgstr "Рисовать прямоугольники и квадраты" + +#: ../../po/../src/verbs.cpp:2058 +msgid "Create circles, ellipses, and arcs" +msgstr "Рисовать круги, эллипсы и дуги" + +#: ../../po/../src/verbs.cpp:2060 +msgid "Create stars and polygons" +msgstr "Рисовать звезды и многоугольники" + +#: ../../po/../src/verbs.cpp:2062 +msgid "Create spirals" +msgstr "Рисовать спирали" + +#: ../../po/../src/verbs.cpp:2064 +msgid "Draw freehand lines" +msgstr "Рисовать произвольные контуры" + +#: ../../po/../src/verbs.cpp:2066 +msgid "Draw Bezier curves and straight lines" +msgstr "Рисовать кривые Безье и прямые линии" + +#: ../../po/../src/verbs.cpp:2068 +msgid "Draw calligraphic lines" +msgstr "Рисовать каллиграфическим пером" + +#: ../../po/../src/verbs.cpp:2070 +msgid "Create and edit text objects" +msgstr "Создавать и править текстовые объекты" + +#: ../../po/../src/verbs.cpp:2072 +msgid "Create and edit gradients" +msgstr "Создавать и править градиенты" + +#: ../../po/../src/verbs.cpp:2074 +msgid "Zoom in or out" +msgstr "Менять масштаб" + +#: ../../po/../src/verbs.cpp:2076 +msgid "Pick averaged colors from image" +msgstr "Брать усредненные цвета из изображения" + +#: ../../po/../src/verbs.cpp:2078 +msgid "Create connectors" +msgstr "Создать линии соединения" + +#. Tool prefs +#: ../../po/../src/verbs.cpp:2081 +msgid "Selector Preferences" +msgstr "Настройки инструмента выделения" + +#: ../../po/../src/verbs.cpp:2082 +msgid "Open Preferences for the Selector tool" +msgstr "Открыть окно настроек Inkscape для инструмента Выделение" + +#: ../../po/../src/verbs.cpp:2083 +msgid "Node Tool Preferences" +msgstr "Настройки инструмента узлов" + +#: ../../po/../src/verbs.cpp:2084 +msgid "Open Preferences for the Node tool" +msgstr "Открыть окно настроек Inkscape для инструмента Узлы" + +#: ../../po/../src/verbs.cpp:2085 +msgid "Rectangle Preferences" +msgstr "Настройки прямоугольника" + +#: ../../po/../src/verbs.cpp:2086 +msgid "Open Preferences for the Rectangle tool" +msgstr "Открыть окно настроек Inkscape для инструмента Прямоугольник" + +#: ../../po/../src/verbs.cpp:2087 +msgid "Ellipse Preferences" +msgstr "Настройки эллипса" + +#: ../../po/../src/verbs.cpp:2088 +msgid "Open Preferences for the Ellipse tool" +msgstr "Открыть окно настроек Inkscape для инструмента Эллипс" + +#: ../../po/../src/verbs.cpp:2089 +msgid "Star Preferences" +msgstr "Настройки звезды" + +#: ../../po/../src/verbs.cpp:2090 +msgid "Open Preferences for the Star tool" +msgstr "Открыть окно настроек Inkscape для инструмента Звезда" + +#: ../../po/../src/verbs.cpp:2091 +msgid "Spiral Preferences" +msgstr "Настройки спирали" + +#: ../../po/../src/verbs.cpp:2092 +msgid "Open Preferences for the Spiral tool" +msgstr "Открыть окно настроек Inkscape для инструмента Спираль" + +#: ../../po/../src/verbs.cpp:2093 +msgid "Pencil Preferences" +msgstr "Настройки карандаша" + +#: ../../po/../src/verbs.cpp:2094 +msgid "Open Preferences for the Pencil tool" +msgstr "Открыть окно настроек Inkscape для инструмента Карандаш" + +#: ../../po/../src/verbs.cpp:2095 +msgid "Pen Preferences" +msgstr "Настройки пера" + +#: ../../po/../src/verbs.cpp:2096 +msgid "Open Preferences for the Pen tool" +msgstr "Открыть окно настроек Inkscape для инструмента Перо" + +#: ../../po/../src/verbs.cpp:2097 +msgid "Calligraphic Preferences" +msgstr "Настройки каллиграфического пера" + +#: ../../po/../src/verbs.cpp:2098 +msgid "Open Preferences for the Calligraphy tool" +msgstr "Открыть окно настроек Inkscape для инструмента Каллиграфическое перо" + +#: ../../po/../src/verbs.cpp:2099 +msgid "Text Preferences" +msgstr "Настройки текста" + +#: ../../po/../src/verbs.cpp:2100 +msgid "Open Preferences for the Text tool" +msgstr "Открыть окно настроек Inkscape для инструмента Текст" + +#: ../../po/../src/verbs.cpp:2101 +msgid "Gradient Preferences" +msgstr "Настройки градиентов" + +#: ../../po/../src/verbs.cpp:2102 +msgid "Open Preferences for the Gradient tool" +msgstr "Открыть окно настроек Inkscape для инструмента Градиент" + +#: ../../po/../src/verbs.cpp:2103 +msgid "Zoom Preferences" +msgstr "Настройки инструмента масштаба" + +#: ../../po/../src/verbs.cpp:2104 +msgid "Open Preferences for the Zoom tool" +msgstr "Открыть окно настроек Inkscape для инструмента Масштаб" + +#: ../../po/../src/verbs.cpp:2105 +msgid "Dropper Preferences" +msgstr "Настройки пипетки" + +#: ../../po/../src/verbs.cpp:2106 +msgid "Open Preferences for the Dropper tool" +msgstr "Открыть окно настроек Inkscape для инструмента Пипетка" + +#: ../../po/../src/verbs.cpp:2107 +msgid "Connector Preferences" +msgstr "Настройки линий соединения" + +#: ../../po/../src/verbs.cpp:2108 +msgid "Open Preferences for the Connector tool" +msgstr "Открыть окно настроек Inkscape для линий соединения" + +#. Zoom/View +#: ../../po/../src/verbs.cpp:2111 +msgid "Zoom In" +msgstr "Увеличить" + +#: ../../po/../src/verbs.cpp:2111 +msgid "Zoom in" +msgstr "Увеличить" + +#: ../../po/../src/verbs.cpp:2112 +msgid "Zoom Out" +msgstr "Уменьшить" + +#: ../../po/../src/verbs.cpp:2112 +msgid "Zoom out" +msgstr "Уменьшить" + +#: ../../po/../src/verbs.cpp:2113 +msgid "_Rulers" +msgstr "_Линейки" + +#: ../../po/../src/verbs.cpp:2113 +msgid "Show or hide the canvas rulers" +msgstr "Показать/скрыть линейки холста" + +#: ../../po/../src/verbs.cpp:2114 +msgid "Scroll_bars" +msgstr "Полосы _прокрутки" + +#: ../../po/../src/verbs.cpp:2114 +msgid "Show or hide the canvas scrollbars" +msgstr "Показать/скрыть полосы прокрутки холста" + +#: ../../po/../src/verbs.cpp:2115 +msgid "_Grid" +msgstr "_Сетка" + +#: ../../po/../src/verbs.cpp:2116 +msgid "G_uides" +msgstr "_Направляющие" + +#: ../../po/../src/verbs.cpp:2117 +msgid "Nex_t Zoom" +msgstr "С_ледующий масштаб" + +#: ../../po/../src/verbs.cpp:2117 +msgid "Next zoom (from the history of zooms)" +msgstr "Следующий масштаб (из истории масштабирования)" + +#: ../../po/../src/verbs.cpp:2119 +msgid "Pre_vious Zoom" +msgstr "_Предыдущий масштаб" + +#: ../../po/../src/verbs.cpp:2119 +msgid "Previous zoom (from the history of zooms)" +msgstr "Предыдущий масштаб (из истории масштабирования)" + +#: ../../po/../src/verbs.cpp:2121 +msgid "Zoom 1:_1" +msgstr "Масштаб 1:_1" + +#: ../../po/../src/verbs.cpp:2121 +msgid "Zoom to 1:1" +msgstr "Масштаб 1:1" + +#: ../../po/../src/verbs.cpp:2123 +msgid "Zoom 1:_2" +msgstr "Масштаб 1:_2" + +#: ../../po/../src/verbs.cpp:2123 +msgid "Zoom to 1:2" +msgstr "Масштаб 1:2" + +#: ../../po/../src/verbs.cpp:2125 +msgid "_Zoom 2:1" +msgstr "_Масштаб 2:1" + +#: ../../po/../src/verbs.cpp:2125 +msgid "Zoom to 2:1" +msgstr "Масштаб 2:1" + +#: ../../po/../src/verbs.cpp:2128 +msgid "_Fullscreen" +msgstr "Во весь _экран" + +#: ../../po/../src/verbs.cpp:2128 +msgid "Stretch this document window to full screen" +msgstr "Развернуть окно документа на весь экран" + +#: ../../po/../src/verbs.cpp:2131 +msgid "Duplic_ate Window" +msgstr "Пов_торить окно" + +#: ../../po/../src/verbs.cpp:2131 +msgid "Open a new window with the same document" +msgstr "Открыть новое окно с этим же документом" + +#: ../../po/../src/verbs.cpp:2133 +msgid "_New View Preview" +msgstr "_Создать предварительный просмотр" + +#: ../../po/../src/verbs.cpp:2134 +msgid "New View Preview" +msgstr "Создать новое окно предварительного просмотра" + +#. "view_new_preview" +#: ../../po/../src/verbs.cpp:2136 +#, fuzzy +msgid "_Normal" +msgstr "Обычно" + +#: ../../po/../src/verbs.cpp:2137 +msgid "Switch to normal display mode" +msgstr "" + +#: ../../po/../src/verbs.cpp:2138 +#, fuzzy +msgid "_Outline" +msgstr "Рамку" + +#: ../../po/../src/verbs.cpp:2139 +msgid "Switch to outline (wireframe) display mode" +msgstr "" + +#: ../../po/../src/verbs.cpp:2141 +msgid "Ico_n Preview" +msgstr "Просмотреть как пи_ктограмму" + +#: ../../po/../src/verbs.cpp:2142 +msgid "Open a window to preview items at different icon resolutions" +msgstr "Просмотреть выделение как пиктограмму разных размеров" + +#: ../../po/../src/verbs.cpp:2144 +msgid "Zoom to fit page in window" +msgstr "Масштабировать так, чтобы целиком уместить страницу в окне" + +#: ../../po/../src/verbs.cpp:2145 +msgid "Page _Width" +msgstr "_Ширина страницы" + +#: ../../po/../src/verbs.cpp:2146 +msgid "Zoom to fit page width in window" +msgstr "Масштабировать так, чтобы уместить в окне страницу по ширине" + +#: ../../po/../src/verbs.cpp:2148 +msgid "Zoom to fit drawing in window" +msgstr "Масштабировать так, чтобы целиком уместить рисунок в окне" + +#: ../../po/../src/verbs.cpp:2150 +msgid "Zoom to fit selection in window" +msgstr "Масштабировать так, чтобы уместить в окне выделенную область" + +#. Dialogs +#: ../../po/../src/verbs.cpp:2153 +msgid "In_kscape Preferences..." +msgstr "Настройки Inkscape..." + +#: ../../po/../src/verbs.cpp:2154 +msgid "Global Inkscape preferences" +msgstr "Общие настройки Inkscape" + +#: ../../po/../src/verbs.cpp:2155 +msgid "_Document Preferences..." +msgstr "_Настройки документа..." + +#: ../../po/../src/verbs.cpp:2156 +msgid "Preferences saved with the document" +msgstr "Настройки, сохраняемые с документом" + +#: ../../po/../src/verbs.cpp:2157 +msgid "_Fill and Stroke..." +msgstr "_Заливка и штрих..." + +#: ../../po/../src/verbs.cpp:2158 +msgid "Fill and Stroke dialog" +msgstr "Диалог заливки и штриха" + +#. TRANSLATORS: "Swatches" means: color samples +#: ../../po/../src/verbs.cpp:2160 +msgid "S_watches..." +msgstr "Образцы _цветов..." + +#: ../../po/../src/verbs.cpp:2161 +msgid "View color swatches" +msgstr "Посмотреть образцы цветов" + +#: ../../po/../src/verbs.cpp:2162 +msgid "Transfor_m..." +msgstr "Транс_формировать..." + +#: ../../po/../src/verbs.cpp:2163 +msgid "Transform dialog" +msgstr "Диалог трансформации" + +#: ../../po/../src/verbs.cpp:2164 +msgid "_Align and Distribute..." +msgstr "_Выровнять..." + +#: ../../po/../src/verbs.cpp:2165 +msgid "Align and Distribute dialog" +msgstr "Диалог выравнивания" + +#: ../../po/../src/verbs.cpp:2166 +msgid "_Text and Font..." +msgstr "_Текст и шрифт..." + +#: ../../po/../src/verbs.cpp:2167 +msgid "Text and Font dialog" +msgstr "Диалог текста и выбора шрифта" + +#: ../../po/../src/verbs.cpp:2168 +msgid "_XML Editor..." +msgstr "Редактор _XML..." + +#: ../../po/../src/verbs.cpp:2169 +msgid "XML Editor" +msgstr "Редактор XML-дерева документа" + +#: ../../po/../src/verbs.cpp:2170 +msgid "_Find..." +msgstr "_Найти..." + +#: ../../po/../src/verbs.cpp:2171 +msgid "Find objects in document" +msgstr "Найти объекты в документе" + +#: ../../po/../src/verbs.cpp:2172 +msgid "_Messages..." +msgstr "_Сообщения..." + +#: ../../po/../src/verbs.cpp:2173 +msgid "View debug messages" +msgstr "Просмотреть отладочные сообщения" + +#: ../../po/../src/verbs.cpp:2174 +msgid "S_cripts..." +msgstr "С_ценарии..." + +#: ../../po/../src/verbs.cpp:2175 +msgid "Run scripts" +msgstr "Выполнить сценарии" + +#: ../../po/../src/verbs.cpp:2176 +msgid "Show/Hide D_ialogs" +msgstr "Показать/спря_тать диалоги" + +#: ../../po/../src/verbs.cpp:2177 +msgid "Show or hide all active dialogs" +msgstr "Показать или скрыть все активные диалоги" + +#. TRANSLATORS: "Tile clones" means: "Create tiled clones" +#: ../../po/../src/verbs.cpp:2179 +msgid "Tile clones..." +msgstr "Узор из клонов..." + +#: ../../po/../src/verbs.cpp:2180 +msgid "Create and arrange multiple clones of selection" +msgstr "Создать узор из клонов" + +#: ../../po/../src/verbs.cpp:2181 +msgid "_Object Properties..." +msgstr "_Свойства объекта..." + +#: ../../po/../src/verbs.cpp:2182 +msgid "Object Properties dialog" +msgstr "Диалог свойств объекта" + +#: ../../po/../src/verbs.cpp:2185 +msgid "_Connect to Jabber server..." +msgstr "_Соединиться с Jabber-сервером..." + +#: ../../po/../src/verbs.cpp:2185 +msgid "Connect to a Jabber server" +msgstr "Соединение с Jabber-сервером" + +#: ../../po/../src/verbs.cpp:2187 +msgid "Share with _user..." +msgstr "Поделиться с _пользователем..." + +#: ../../po/../src/verbs.cpp:2187 +msgid "Establish a whiteboard session with another Jabber user" +msgstr "Начать совместное рисование с другим пользователем Jabber" + +#: ../../po/../src/verbs.cpp:2189 +msgid "Share with _chatroom..." +msgstr "Поделиться с целой _комнатой..." + +#: ../../po/../src/verbs.cpp:2189 +msgid "" +"Join a chatroom to start a new whiteboard session or join one in progress" +msgstr "" +"Зайти в комнату для начала новой сессии рисования или присоединения к текущей" + +#: ../../po/../src/verbs.cpp:2191 +msgid "_Dump XML node tracker" +msgstr "" + +#: ../../po/../src/verbs.cpp:2191 +msgid "Dump the contents of the XML tracker to the console" +msgstr "" + +#: ../../po/../src/verbs.cpp:2193 +msgid "_Open session file..." +msgstr "_Открыть файл сессии..." + +#: ../../po/../src/verbs.cpp:2193 +msgid "Open and browse through records of past whiteboard sessions" +msgstr "Открыть и просмотреть записи предыдущих сессий рисования" + +#: ../../po/../src/verbs.cpp:2195 +msgid "Session file playback" +msgstr "Воспроизведение файла сессии" + +#: ../../po/../src/verbs.cpp:2197 +msgid "_Disconnect from session" +msgstr "О_тсоединиться от сессии" + +#: ../../po/../src/verbs.cpp:2199 +msgid "Disconnect from _server" +msgstr "Отсоединиться от с_ервера" + +#: ../../po/../src/verbs.cpp:2201 +msgid "_Input Devices..." +msgstr "_Устройства ввода..." + +#: ../../po/../src/verbs.cpp:2202 +msgid "Configure extended input devices" +msgstr "Настройка расширенных устройств ввода" + +#. Help +#: ../../po/../src/verbs.cpp:2205 +msgid "_Keys and Mouse" +msgstr "_Клавиатура и мышь" + +#: ../../po/../src/verbs.cpp:2206 +msgid "Key and mouse shortcuts reference" +msgstr "Справка по использованию клавиатуры и мыши" + +#: ../../po/../src/verbs.cpp:2207 +msgid "About E_xtensions" +msgstr "О р_асширениях" + +#: ../../po/../src/verbs.cpp:2208 +msgid "About Extensions..." +msgstr "О расширениях..." + +#: ../../po/../src/verbs.cpp:2209 +msgid "About _Memory" +msgstr "Об используемой _памяти" + +#: ../../po/../src/verbs.cpp:2210 +msgid "About Memory..." +msgstr "Об используемой приложением памяти..." + +#: ../../po/../src/verbs.cpp:2211 +msgid "_About Inkscape" +msgstr "_О программе" + +#. "help_about" +#. new HelpVerb(SP_VERB_SHOW_LICENSE, "ShowLicense", N_("Modifying or Redistributing Inkscape"), +#. N_("Show license to modify and/or redistribute Inkscape: GNU GPL"), NULL), +#. Tutorials +#: ../../po/../src/verbs.cpp:2217 +msgid "Inkscape: _Basic" +msgstr "Inkscape: _Начальный уровень" + +#: ../../po/../src/verbs.cpp:2218 +msgid "Getting started with Inkscape" +msgstr "Начинаем работу с Inkscape" + +#. "tutorial_basic" +#: ../../po/../src/verbs.cpp:2219 +msgid "Inkscape: _Shapes" +msgstr "Inkscape: _Фигуры" + +#: ../../po/../src/verbs.cpp:2220 +msgid "Using shape tools to create and edit shapes" +msgstr "Использование инструментов рисования и редактирования фигур" + +#: ../../po/../src/verbs.cpp:2221 +msgid "Inkscape: _Advanced" +msgstr "Inkscape: _Второй уровень" + +#: ../../po/../src/verbs.cpp:2222 +msgid "Advanced Inkscape topics" +msgstr "Дополнительные темы по Inkscape" + +#. "tutorial_advanced" +#. TRANSLATORS: "to trace" means "to convert a bitmap to vector graphics" (to vectorize) +#: ../../po/../src/verbs.cpp:2224 +msgid "Inkscape: T_racing" +msgstr "Inkscape: _Векторизация" + +#: ../../po/../src/verbs.cpp:2225 +msgid "Using bitmap tracing" +msgstr "Использование векторизации" + +#. "tutorial_tracing" +#: ../../po/../src/verbs.cpp:2226 +msgid "Inkscape: _Calligraphy" +msgstr "Inkscape: _Каллиграфия" + +#: ../../po/../src/verbs.cpp:2227 +msgid "Using the Calligraphy pen tool" +msgstr "Использование каллиграфического пера" + +#: ../../po/../src/verbs.cpp:2228 +msgid "_Elements of Design" +msgstr "_Элементы дизайна" + +#: ../../po/../src/verbs.cpp:2229 +msgid "Principles of design in the tutorial form" +msgstr "Самоучитель по элементам дизайна в виде урока" + +#. "tutorial_design" +#: ../../po/../src/verbs.cpp:2230 +msgid "_Tips and Tricks" +msgstr "_Советы и хитрости" + +#: ../../po/../src/verbs.cpp:2231 +msgid "Miscellaneous tips and tricks" +msgstr "Различные советы по использованию программы" + +#. "tutorial_tips" +#. Effect +#: ../../po/../src/verbs.cpp:2234 +msgid "Previous Effect" +msgstr "Повторить последний" + +#: ../../po/../src/verbs.cpp:2235 +msgid "Repeat the last effect with the same settings" +msgstr "Повторить последний эффект с теми же настройками" + +#. "tutorial_tips" +#: ../../po/../src/verbs.cpp:2236 +msgid "Previous Effect Settings..." +msgstr "Повторить с настройкой..." + +#: ../../po/../src/verbs.cpp:2237 +msgid "Repeat the last effect with new settings" +msgstr "Повторить последний эффект с новыми настройками" + +#: ../../po/../src/widgets/dash-selector.cpp:106 +msgid "Dash pattern" +msgstr "Пунктир" + +#: ../../po/../src/widgets/dash-selector.cpp:121 +msgid "Pattern offset" +msgstr "Смещение пунктира" + +#: ../../po/../src/widgets/desktop-widget.cpp:240 +msgid "Zoom drawing if window size changes" +msgstr "Изменять масштаб при изменении размеров окна" + +#: ../../po/../src/widgets/desktop-widget.cpp:298 +msgid "Cursor coordinates" +msgstr "Координаты курсора" + +#. display the initial welcome message in the statusbar +#: ../../po/../src/widgets/desktop-widget.cpp:324 +msgid "" +"Welcome to Inkscape! Use shape or freehand tools to create objects; " +"use selector (arrow) to move or transform them." +msgstr "" +"Добро пожаловать в Inkscape! Используйте инструменты фигур или " +"рисования для создания объектов; используйте селектор (стрелку) для их " +"перемещения и трансформации." + +#: ../../po/../src/widgets/desktop-widget.cpp:372 +#, c-format +msgid "%s: %d - Inkscape" +msgstr "%s: %d - Inkscape" + +#: ../../po/../src/widgets/desktop-widget.cpp:374 +#, c-format +msgid "%s - Inkscape" +msgstr "%s - Inkscape" + +#: ../../po/../src/widgets/desktop-widget.cpp:532 +#, c-format +msgid "" +"Save changes to document \"%s\" before " +"closing?\n" +"\n" +"If you close without saving, your changes will be discarded." +msgstr "" +"Сохранить изменения в документе \"%s" +"\"перед закрытием?\n" +"\n" +"Если вы закроете документ, не сохранив его, все изменения будут потеряны." + +#: ../../po/../src/widgets/desktop-widget.cpp:548 +#: ../../po/../src/widgets/desktop-widget.cpp:612 +msgid "Close _without saving" +msgstr "_Не сохранять" + +#: ../../po/../src/widgets/desktop-widget.cpp:595 +#, c-format +msgid "" +"The file \"%s\" was saved with a " +"format (%s) that may cause data loss!\n" +"\n" +"Do you want to save this file in another format?" +msgstr "" +"Файл %s был сохранен в формате (%s), " +"что может привести к частичной потере данных!\n" +"\n" +"Сохранить документ в другом формате?" + +#. Family frame +#: ../../po/../src/widgets/font-selector.cpp:156 +msgid "Font family" +msgstr "Шрифт" + +#. Style frame +#: ../../po/../src/widgets/font-selector.cpp:184 +msgid "Style" +msgstr "Начертание" + +#: ../../po/../src/widgets/font-selector.cpp:219 +msgid "Font size:" +msgstr "Размер:" + +#. TRANSLATORS: Test string used in text and font dialog (when no +#. * text has been entered) to get a preview of the font. Choose +#. * some representative characters that users of your locale will be +#. * interested in. +#: ../../po/../src/widgets/font-selector.cpp:554 +msgid "AaBbCcIiPpQq12368.;/()" +msgstr "АаБбВвIiPpQq12368.;/()" + +#: ../../po/../src/widgets/gradient-selector.cpp:137 +#: ../../po/../src/widgets/gradient-toolbar.cpp:524 +msgid "Duplicate" +msgstr "Дублировать" + +#: ../../po/../src/widgets/gradient-selector.cpp:142 +#: ../../po/../src/widgets/gradient-toolbar.cpp:535 +msgid "Edit..." +msgstr "Правка..." + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/pservers.html#LinearGradientSpreadMethodAttribute +#: ../../po/../src/widgets/gradient-selector.cpp:159 +msgid "" +"Whether to fill with flat color beyond the ends of the gradient vector " +"(spreadMethod=\"pad\"), or repeat the gradient in the same direction " +"(spreadMethod=\"repeat\"), or repeat the gradient in alternating opposite " +"directions (spreadMethod=\"reflect\")" +msgstr "" +"За границами градиента: заполнять плоским цветом, повторять исходный " +"градиент или повторять отраженный градиент" + +#: ../../po/../src/widgets/gradient-selector.cpp:165 +msgid "none" +msgstr "нет" + +#: ../../po/../src/widgets/gradient-selector.cpp:169 +msgid "reflected" +msgstr "отраженный" + +#: ../../po/../src/widgets/gradient-selector.cpp:173 +msgid "direct" +msgstr "повторный" + +#: ../../po/../src/widgets/gradient-selector.cpp:181 +msgid "Repeat:" +msgstr "Повтор:" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:217 +msgid "No gradients" +msgstr "Градиентов нет" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:226 +msgid "Nothing selected" +msgstr "Ничего не выделено" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:237 +msgid "No gradients in selection" +msgstr "Градиент не выделен" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:247 +msgid "Multiple gradients" +msgstr "Несколько градиентов" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:525 +msgid "" +"If the gradient is used by more than one object, create a copy of it for the " +"selected object(s)" +msgstr "" +"Если градиент используется для более чем одного объекта, создайте его копию " +"для выделенных объектов" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:536 +msgid "Edit the stops of the gradient" +msgstr "Изменить опорные точки в градиенте" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:593 +#: ../../po/../src/widgets/toolbox.cpp:1103 +#: ../../po/../src/widgets/toolbox.cpp:1192 +#: ../../po/../src/widgets/toolbox.cpp:1485 +#: ../../po/../src/widgets/toolbox.cpp:1534 +#: ../../po/../src/widgets/toolbox.cpp:1766 +#: ../../po/../src/widgets/toolbox.cpp:1801 +#: ../../po/../src/widgets/toolbox.cpp:2331 +#: ../../po/../src/widgets/toolbox.cpp:2370 +msgid "New:" +msgstr "Новый:" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:606 +msgid "Create linear gradient" +msgstr "Создать линейный градиент" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:620 +msgid "Create radial (elliptic or circular) gradient" +msgstr "Создать радиальный (эллиптический или круговой) градиент" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:635 +msgid "on" +msgstr "на" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:648 +msgid "Create gradient in the fill" +msgstr "Создать градиент в заливке" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:662 +msgid "Create gradient in the stroke" +msgstr "Создать градиент в штрихе" + +#. FIXME: implement averaging of all parameters for multiple selected stars +#. gtk_label_set_markup(GTK_LABEL(l), _("Average:")); +#. FIXME: implement averaging of all parameters for multiple selected +#. gtk_label_set_markup(GTK_LABEL(l), _("Average:")); +#: ../../po/../src/widgets/gradient-toolbar.cpp:676 +#: ../../po/../src/widgets/toolbox.cpp:1105 +#: ../../po/../src/widgets/toolbox.cpp:1124 +#: ../../po/../src/widgets/toolbox.cpp:1493 +#: ../../po/../src/widgets/toolbox.cpp:1518 +#: ../../po/../src/widgets/toolbox.cpp:1768 +#: ../../po/../src/widgets/toolbox.cpp:1787 +#: ../../po/../src/widgets/toolbox.cpp:2334 +#: ../../po/../src/widgets/toolbox.cpp:2354 +msgid "Change:" +msgstr "Менять:" + +#: ../../po/../src/widgets/gradient-vector.cpp:269 +msgid "No gradients in document" +msgstr "Документ не содержит градиентов" + +#: ../../po/../src/widgets/gradient-vector.cpp:275 +msgid "No gradient selected" +msgstr "Градиент не выделен" + +#: ../../po/../src/widgets/gradient-vector.cpp:532 +msgid "No stops in gradient" +msgstr "В градиенте нет опорных точек" + +#. TRANSLATORS: "Stop" means: a "phase" of a gradient +#: ../../po/../src/widgets/gradient-vector.cpp:794 +msgid "Add stop" +msgstr "Добавить опорную точку" + +#: ../../po/../src/widgets/gradient-vector.cpp:797 +msgid "Add another control stop to gradient" +msgstr "Добавить еще одну опорную точку в градиент" + +#: ../../po/../src/widgets/gradient-vector.cpp:799 +msgid "Delete stop" +msgstr "Удалить опорную точку" + +#: ../../po/../src/widgets/gradient-vector.cpp:802 +msgid "Delete current control stop from gradient" +msgstr "Удалить опорную точку градиента" + +#. Label +#: ../../po/../src/widgets/gradient-vector.cpp:813 +msgid "Offset:" +msgstr "Смещение" + +#. TRANSLATORS: "Stop" means: a "phase" of a gradient +#: ../../po/../src/widgets/gradient-vector.cpp:858 +msgid "Stop Color" +msgstr "Цвет опорной точки" + +#: ../../po/../src/widgets/gradient-vector.cpp:887 +msgid "Gradient editor" +msgstr "Редактор градиентов" + +#: ../../po/../src/widgets/layer-selector.cpp:119 +msgid "Toggle current layer visibility" +msgstr "Скрыть или открыть текущий слой" + +#: ../../po/../src/widgets/layer-selector.cpp:139 +msgid "Lock or unlock current layer" +msgstr "Запереть или отпереть текущий слой" + +#: ../../po/../src/widgets/layer-selector.cpp:142 +msgid "Current layer" +msgstr "Текущий слой" + +#: ../../po/../src/widgets/layer-selector.cpp:553 +msgid "(root)" +msgstr "(корень)" + +#: ../../po/../src/widgets/paint-selector.cpp:182 +#: ../../po/../src/widgets/paint-selector.cpp:561 +msgid "No paint" +msgstr "Нет заливки" + +#: ../../po/../src/widgets/paint-selector.cpp:184 +#: ../../po/../src/widgets/paint-selector.cpp:629 +msgid "Flat color" +msgstr "Плоский цвет" + +#: ../../po/../src/widgets/paint-selector.cpp:186 +#: ../../po/../src/widgets/paint-selector.cpp:696 +msgid "Linear gradient" +msgstr "Линейный градиент" + +#: ../../po/../src/widgets/paint-selector.cpp:188 +#: ../../po/../src/widgets/paint-selector.cpp:699 +msgid "Radial gradient" +msgstr "Радиальный градиент" + +#: ../../po/../src/widgets/paint-selector.cpp:192 +msgid "Unset paint (make it undefined so it can be inherited)" +msgstr "" +"Убрать заливку (сделать ее неопределенной, чтобы она могла наследоваться)" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/painting.html#FillRuleProperty +#: ../../po/../src/widgets/paint-selector.cpp:204 +msgid "" +"Any path self-intersections or subpaths create holes in the fill (fill-rule: " +"evenodd)" +msgstr "" +"Любые самопересечения или внутренние субконтуры образуют дыры в заливке " +"(fill-rule: evenodd)" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/painting.html#FillRuleProperty +#: ../../po/../src/widgets/paint-selector.cpp:215 +msgid "" +"Fill is solid unless a subpath is counterdirectional (fill-rule: nonzero)" +msgstr "" +"Заливка имеет дыру, только если внутренний субконтур направлен в " +"противоположную сторону относительно внешнего (fill-rule: nonzero)" + +#: ../../po/../src/widgets/paint-selector.cpp:528 +msgid "No objects" +msgstr "Нет объектов" + +#: ../../po/../src/widgets/paint-selector.cpp:539 +msgid "Multiple styles" +msgstr "Множественные стили" + +#: ../../po/../src/widgets/paint-selector.cpp:550 +msgid "Paint is undefined" +msgstr "Цвет не определен" + +#: ../../po/../src/widgets/paint-selector.cpp:757 +msgid "No patterns in document" +msgstr "В документе нет текстур" + +#: ../../po/../src/widgets/paint-selector.cpp:872 +msgid "" +"Use Edit > Object(s) to Pattern to create a new pattern from " +"selection." +msgstr "" +"Используйте Правка > Объект(ы) в текстуру, чтобы создать новую " +"текстуру из выделения." + +#: ../../po/../src/widgets/select-toolbar.cpp:426 +msgid "Now stroke width is scaled when objects are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:428 +msgid "Now stroke width is not scaled when objects are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:436 +msgid "" +"Now rounded rectangle corners are scaled when rectangles are " +"scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:438 +msgid "" +"Now rounded rectangle corners are not scaled when rectangles " +"are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:446 +msgid "" +"Now gradients are transformed along with their objects when " +"those are transformed (moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:448 +msgid "" +"Now gradients remain fixed when objects are transformed " +"(moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:456 +msgid "" +"Now patterns are transformed along with their objects when " +"those are transformed (moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:458 +msgid "" +"Now patterns remain fixed when objects are transformed (moved, " +"scaled, rotated, or skewed)." +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:506 +msgid "select_toolbar|X" +msgstr "X" + +#: ../../po/../src/widgets/select-toolbar.cpp:506 +msgid "Horizontal coordinate of selection" +msgstr "Горизонтальная координата выделения" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:511 +msgid "select_toolbar|Y" +msgstr "Y" + +#: ../../po/../src/widgets/select-toolbar.cpp:511 +msgid "Vertical coordinate of selection" +msgstr "Вертикальная координата выделения" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:517 +msgid "select_toolbar|W" +msgstr "Ш" + +#: ../../po/../src/widgets/select-toolbar.cpp:517 +msgid "Width of selection" +msgstr "Ширина выделения" + +#: ../../po/../src/widgets/select-toolbar.cpp:525 +msgid "Change both width and height by the same proportion" +msgstr "Пропорционально изменять ширину и высоту" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:534 +msgid "select_toolbar|H" +msgstr "В" + +#: ../../po/../src/widgets/select-toolbar.cpp:534 +msgid "Height of selection" +msgstr "Высота выделения" + +#: ../../po/../src/widgets/sp-color-gtkselector.cpp:62 +msgid "System" +msgstr "Системный" + +#: ../../po/../src/widgets/sp-color-notebook.cpp:322 +msgid "RGBA_:" +msgstr "RGBA_:" + +#: ../../po/../src/widgets/sp-color-notebook.cpp:330 +msgid "Hexadecimal RGBA value of the color" +msgstr "Шестнадцатеричное значение RGBA" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "RGB" +msgstr "RGB" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "HSL" +msgstr "HSL" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "CMYK" +msgstr "CMYK" + +#: ../../po/../src/widgets/sp-color-scales.cpp:397 +msgid "_R" +msgstr "_R" + +#: ../../po/../src/widgets/sp-color-scales.cpp:398 +#: ../../po/../src/widgets/sp-color-scales.cpp:399 +msgid "Red" +msgstr "Красный" + +#: ../../po/../src/widgets/sp-color-scales.cpp:400 +msgid "_G" +msgstr "_G" + +#: ../../po/../src/widgets/sp-color-scales.cpp:401 +#: ../../po/../src/widgets/sp-color-scales.cpp:402 +msgid "Green" +msgstr "Зеленый" + +#: ../../po/../src/widgets/sp-color-scales.cpp:403 +msgid "_B" +msgstr "_B" + +#: ../../po/../src/widgets/sp-color-scales.cpp:404 +#: ../../po/../src/widgets/sp-color-scales.cpp:405 +msgid "Blue" +msgstr "Синий" + +#. Label +#: ../../po/../src/widgets/sp-color-scales.cpp:406 +#: ../../po/../src/widgets/sp-color-scales.cpp:432 +#: ../../po/../src/widgets/sp-color-scales.cpp:463 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:141 +msgid "_A" +msgstr "_A" + +#: ../../po/../src/widgets/sp-color-scales.cpp:407 +#: ../../po/../src/widgets/sp-color-scales.cpp:408 +#: ../../po/../src/widgets/sp-color-scales.cpp:433 +#: ../../po/../src/widgets/sp-color-scales.cpp:434 +#: ../../po/../src/widgets/sp-color-scales.cpp:464 +#: ../../po/../src/widgets/sp-color-scales.cpp:465 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:151 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:163 +msgid "Alpha (opacity)" +msgstr "Альфа-канал (непрозрачность)" + +#: ../../po/../src/widgets/sp-color-scales.cpp:423 +msgid "_H" +msgstr "_H" + +#: ../../po/../src/widgets/sp-color-scales.cpp:424 +#: ../../po/../src/widgets/sp-color-scales.cpp:425 +msgid "Hue" +msgstr "Тон" + +#: ../../po/../src/widgets/sp-color-scales.cpp:426 +msgid "_S" +msgstr "_S" + +#: ../../po/../src/widgets/sp-color-scales.cpp:427 +#: ../../po/../src/widgets/sp-color-scales.cpp:428 +msgid "Saturation" +msgstr "Насыщенность" + +#: ../../po/../src/widgets/sp-color-scales.cpp:429 +msgid "_L" +msgstr "_L" + +#: ../../po/../src/widgets/sp-color-scales.cpp:430 +#: ../../po/../src/widgets/sp-color-scales.cpp:431 +msgid "Lightness" +msgstr "Яркость" + +#: ../../po/../src/widgets/sp-color-scales.cpp:451 +msgid "_C" +msgstr "_C" + +#: ../../po/../src/widgets/sp-color-scales.cpp:452 +#: ../../po/../src/widgets/sp-color-scales.cpp:453 +msgid "Cyan" +msgstr "Голубой" + +#: ../../po/../src/widgets/sp-color-scales.cpp:454 +msgid "_M" +msgstr "_M" + +#: ../../po/../src/widgets/sp-color-scales.cpp:455 +#: ../../po/../src/widgets/sp-color-scales.cpp:456 +msgid "Magenta" +msgstr "Пурпурный" + +#: ../../po/../src/widgets/sp-color-scales.cpp:457 +msgid "_Y" +msgstr "_Y" + +#: ../../po/../src/widgets/sp-color-scales.cpp:458 +#: ../../po/../src/widgets/sp-color-scales.cpp:459 +msgid "Yellow" +msgstr "Желтый" + +#: ../../po/../src/widgets/sp-color-scales.cpp:460 +msgid "_K" +msgstr "_K" + +#: ../../po/../src/widgets/sp-color-selector.cpp:71 +msgid "Unnamed" +msgstr "Безымянный" + +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:68 +msgid "Wheel" +msgstr "Круг" + +#: ../../po/../src/widgets/sp-xmlview-attr-list.cpp:53 +msgid "Attribute" +msgstr "Атрибут" + +#: ../../po/../src/widgets/sp-xmlview-attr-list.cpp:54 +msgid "Value" +msgstr "Значение" + +#: ../../po/../src/widgets/toolbox.cpp:424 +msgid "Insert new nodes into selected segments" +msgstr "Вставить новые узлы в выделенные сегменты" + +#: ../../po/../src/widgets/toolbox.cpp:426 +msgid "Delete selected nodes" +msgstr "Удалить выделенные узлы" + +#: ../../po/../src/widgets/toolbox.cpp:431 +msgid "Join paths at selected nodes" +msgstr "Соединить контуры в выделенных узлах" + +#: ../../po/../src/widgets/toolbox.cpp:433 +msgid "Join paths at selected nodes with new segment" +msgstr "Соединить контуры в выделенных узлах новым сегментом" + +#: ../../po/../src/widgets/toolbox.cpp:436 +msgid "Split path between two non-endpoint nodes" +msgstr "Разбить контур между двумя неоконечными узлами" + +#: ../../po/../src/widgets/toolbox.cpp:439 +msgid "Break path at selected nodes" +msgstr "Разорвать контур в выделенном узле" + +#: ../../po/../src/widgets/toolbox.cpp:444 +msgid "Make selected nodes corner" +msgstr "Сделать выделенные узлы острыми" + +#: ../../po/../src/widgets/toolbox.cpp:447 +msgid "Make selected nodes smooth" +msgstr "Сделать выделенные узлы сглаженными" + +#: ../../po/../src/widgets/toolbox.cpp:450 +msgid "Make selected nodes symmetric" +msgstr "Сделать выделенные узлы симметричными" + +#: ../../po/../src/widgets/toolbox.cpp:455 +msgid "Make selected segments lines" +msgstr "Сделать выделенные сегменты прямыми" + +#: ../../po/../src/widgets/toolbox.cpp:458 +msgid "Make selected segments curves" +msgstr "Сделать выделенные сегменты кривыми" + +#: ../../po/../src/widgets/toolbox.cpp:1199 +msgid "Polygon" +msgstr "Многоугольник" + +#: ../../po/../src/widgets/toolbox.cpp:1206 +msgid "Regular polygon (with one handle) instead of a star" +msgstr "Правильный многоугольник, а не звезда" + +#: ../../po/../src/widgets/toolbox.cpp:1218 +msgid "Corners:" +msgstr "Углы:" + +#: ../../po/../src/widgets/toolbox.cpp:1218 +msgid "Number of corners of a polygon or star" +msgstr "Количество углов (вершин) многоугольника или звезды" + +#: ../../po/../src/widgets/toolbox.cpp:1228 +msgid "Spoke ratio:" +msgstr "Отношение радиусов:" + +#. TRANSLATORS: Tip radius of a star is the distance from the center to the farthest handle. +#. Base radius is the same for the closest handle. +#: ../../po/../src/widgets/toolbox.cpp:1231 +msgid "Base radius to tip radius ratio" +msgstr "Отношение радиусов основания и вершины луча" + +#: ../../po/../src/widgets/toolbox.cpp:1246 +msgid "Rounded:" +msgstr "Закруглен:" + +#: ../../po/../src/widgets/toolbox.cpp:1246 +msgid "How much rounded are the corners (0 for sharp)" +msgstr "Насколько сглажены углы (0 - острые)" + +#: ../../po/../src/widgets/toolbox.cpp:1256 +msgid "Randomized:" +msgstr "Искажен:" + +#: ../../po/../src/widgets/toolbox.cpp:1256 +msgid "Scatter randomly the corners and angles" +msgstr "Случайным образом смещать вершины и вращать углы" + +#: ../../po/../src/widgets/toolbox.cpp:1269 +#: ../../po/../src/widgets/toolbox.cpp:1838 +#: ../../po/../src/widgets/toolbox.cpp:2061 +msgid "Defaults" +msgstr "По умолчанию" + +#: ../../po/../src/widgets/toolbox.cpp:1270 +#: ../../po/../src/widgets/toolbox.cpp:1839 +#: ../../po/../src/widgets/toolbox.cpp:2062 +msgid "" +"Reset shape parameters to defaults (use Inkscape Preferences > Tools to " +"change defaults)" +msgstr "" +"Сбросить параметры фигуры к значениям по умолчанию (параметры по умолчанию " +"можно изменить в настройках Inkscape)" + +#: ../../po/../src/widgets/toolbox.cpp:1544 +msgid "W:" +msgstr "Ш:" + +#: ../../po/../src/widgets/toolbox.cpp:1544 +msgid "Width of rectangle" +msgstr "Ширина прямоугольника" + +#: ../../po/../src/widgets/toolbox.cpp:1556 +msgid "Height of rectangle" +msgstr "Высота прямоугольника" + +#: ../../po/../src/widgets/toolbox.cpp:1568 +msgid "Rx:" +msgstr "Гор. радиус:" + +#: ../../po/../src/widgets/toolbox.cpp:1568 +msgid "Horizontal radius of rounded corners" +msgstr "Горизонтальный радиус закругленных углов" + +#: ../../po/../src/widgets/toolbox.cpp:1578 +msgid "Ry:" +msgstr "Верт. радиус:" + +#: ../../po/../src/widgets/toolbox.cpp:1578 +msgid "Vertical radius of rounded corners" +msgstr "Вертикальный радиус закругленных углов" + +#: ../../po/../src/widgets/toolbox.cpp:1594 +msgid "Not rounded" +msgstr "Не закруглен" + +#: ../../po/../src/widgets/toolbox.cpp:1596 +msgid "Make corners sharp" +msgstr "Убрать закругление углов" + +#: ../../po/../src/widgets/toolbox.cpp:1805 +msgid "Turns:" +msgstr "Витков:" + +#: ../../po/../src/widgets/toolbox.cpp:1805 +msgid "Number of revolutions" +msgstr "Количество витков" + +#: ../../po/../src/widgets/toolbox.cpp:1815 +msgid "Divergence:" +msgstr "Нелинейность:" + +#: ../../po/../src/widgets/toolbox.cpp:1815 +msgid "How much denser/sparser are outer revolutions; 1 = uniform" +msgstr "" +"Насколько постепенно увеличивать или уменьшать расстояния между витками; 1 = " +"равномерно" + +#: ../../po/../src/widgets/toolbox.cpp:1825 +msgid "Inner radius:" +msgstr "Внутренний радиус:" + +#: ../../po/../src/widgets/toolbox.cpp:1825 +msgid "Radius of the innermost revolution (relative to the spiral size)" +msgstr "Радиус первого изнутри витка (относительно размера спирали)" + +#: ../../po/../src/widgets/toolbox.cpp:1957 +msgid "The width of the calligraphic pen (relative to the visible canvas area)" +msgstr "Ширина каллиграфического пера (относительно видимой области холста)" + +#: ../../po/../src/widgets/toolbox.cpp:1967 +msgid "Thinning:" +msgstr "Сужение:" + +#: ../../po/../src/widgets/toolbox.cpp:1967 +msgid "" +"How much velocity thins the stroke (> 0 makes fast strokes thinner, < 0 " +"makes them broader, 0 makes width independent of velocity)" +msgstr "" +"Как сильно скорость сужает штрих (> 0: быстрые штрихи уже, < 0: быстрые " +"штрихи шире; при 0 ширина штриха не зависит от скорости)" + +#: ../../po/../src/widgets/toolbox.cpp:1980 +msgid "Angle:" +msgstr "Угол:" + +#: ../../po/../src/widgets/toolbox.cpp:1980 +msgid "" +"The angle of the pen's nib (in degrees; 0 = horizontal; has no effect if " +"fixation = 0)" +msgstr "" +"Угол пера (в градусах; 0 = горизонтально; при нулевой фиксации значения не " +"имеет)" + +#: ../../po/../src/widgets/toolbox.cpp:1990 +msgid "Fixation:" +msgstr "Фиксация:" + +#: ../../po/../src/widgets/toolbox.cpp:1990 +msgid "" +"How fixed is the pen angle (0 = always perpendicular to stroke direction, 1 " +"= fixed)" +msgstr "" +"Степень фиксации угла (0: всегда перпендикулярно штриху, 1: угол не меняется)" + +#: ../../po/../src/widgets/toolbox.cpp:2003 +msgid "Mass:" +msgstr "Масса:" + +#: ../../po/../src/widgets/toolbox.cpp:2003 +msgid "How much inertia affects the movement of the pen" +msgstr "Насколько инерция влияет на движение пера" + +#. TRANSLATORS: "drag" means "resistance" here +#: ../../po/../src/widgets/toolbox.cpp:2014 +msgid "Drag:" +msgstr "Торможение:" + +#: ../../po/../src/widgets/toolbox.cpp:2014 +msgid "How much resistance affects the movement of the pen" +msgstr "Насколько сопротивление бумаги влияет на движение пера" + +#: ../../po/../src/widgets/toolbox.cpp:2034 +msgid "Use the pressure of the input device to alter the width of the pen" +msgstr "Нажим (pressure) устройства ввода изменяет ширину пера" + +#: ../../po/../src/widgets/toolbox.cpp:2047 +msgid "Use the tilt of the input device to alter the angle of the pen's nib" +msgstr "Наклон (tilt) устройства ввода изменяет угол пера" + +#: ../../po/../src/widgets/toolbox.cpp:2374 +msgid "Start:" +msgstr "Начало:" + +#: ../../po/../src/widgets/toolbox.cpp:2374 +msgid "The angle (in degrees) from the horizontal to the arc's start point" +msgstr "Угол (в градусах) от горизонтали до начальной точки дуги" + +#: ../../po/../src/widgets/toolbox.cpp:2384 +msgid "End:" +msgstr "Конец:" + +#: ../../po/../src/widgets/toolbox.cpp:2384 +msgid "The angle (in degrees) from the horizontal to the arc's end point" +msgstr "Угол (в градусах) от горизонтали до конечной точки дуги" + +#: ../../po/../src/widgets/toolbox.cpp:2395 +msgid "Open arc" +msgstr "Открыть дугу" + +#: ../../po/../src/widgets/toolbox.cpp:2396 +msgid "" +"Switch between arc (unclosed shape) and segment (closed shape with two radii)" +msgstr "" +"Переключать между дугой (незакрытой фигурой) и сегментом (закрытой фигурой с " +"двумя радиусами)" + +#: ../../po/../src/widgets/toolbox.cpp:2415 +msgid "Make whole" +msgstr "Сделать целым" + +#: ../../po/../src/widgets/toolbox.cpp:2417 +msgid "Make the shape a whole ellipse, not arc or segment" +msgstr "Сделать фигуру целым эллипсом, а не дугой или сегментом" + +#: ../../po/../src/widgets/toolbox.cpp:2644 +msgid "" +"When pressed, picks visible color without alpha and when not pressed, picks " +"color including its alpha" +msgstr "" +"Включено: выбирает видимый цвет без альфа-канала; выключено: выбирает " +"видимый цвет, включая альфа-канал" + +#: ../../po/../src/widgets/toolbox.cpp:3039 +msgid "Make connectors avoid selected objects" +msgstr "Линии обходят выделенные объекты" + +#: ../../po/../src/widgets/toolbox.cpp:3043 +msgid "Make connectors ignore selected objects" +msgstr "Линии игнорируют выделенные объекты" + +#. +#. 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 : +#: ../share/extensions/addnodes.inx.h:1 +#, fuzzy +msgid "Add Nodes" +msgstr "Узлы" + +#: ../share/extensions/addnodes.inx.h:2 +msgid "Maximum Segment Length" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:1 +msgid "AI Input" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:2 ../share/extensions/ai_output.inx.h:2 +msgid "Adobe Illustrator (*.ai)" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:3 +msgid "Open files saved with Adobe Illustrator" +msgstr "" + +#: ../share/extensions/ai_output.inx.h:1 +#, fuzzy +msgid "AI Output" +msgstr "Вывод" + +#: ../share/extensions/ai_output.inx.h:3 +msgid "Write Adobe Illustrator" +msgstr "" + +#: ../share/extensions/dia.inx.h:1 +msgid "A diagram created with the program Dia" +msgstr "" + +#: ../share/extensions/dia.inx.h:2 +msgid "Dia Diagram (*.dia)" +msgstr "" + +#: ../share/extensions/dia.inx.h:3 +msgid "Dia Input" +msgstr "" + +#: ../share/extensions/dia.inx.h:4 +msgid "" +"In order to import Dia files, Dia itself must be installed. You can get Dia " +"at http://www.gnome.org/projects/dia/" +msgstr "" + +#: ../share/extensions/dia.inx.h:5 +msgid "" +"The dia2svg.sh script should be installed with your Inkscape distribution. " +"If you do not have it, there is likely to be something wrong with your " +"Inkscape installation." +msgstr "" + +#: ../share/extensions/dots.inx.h:1 +#, fuzzy +msgid "Connect the Dots" +msgstr "Линия соединения" + +#: ../share/extensions/dots.inx.h:2 +#, fuzzy +msgid "Dot Size" +msgstr "Размер" + +#: ../share/extensions/dots.inx.h:3 +#, fuzzy +msgid "Font Size" +msgstr "Размер:" + +#: ../share/extensions/dropshadow.inx.h:1 +msgid "Color of shadow" +msgstr "" + +#: ../share/extensions/dropshadow.inx.h:2 +#, fuzzy +msgid "Dropshadow" +msgstr "Показывать тень от страницы" + +#: ../share/extensions/dxf_input.inx.h:1 +#: ../share/extensions/dxf_output.inx.h:1 +msgid "AutoCAD DXF (*.dxf)" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:2 +msgid "DXF Input" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:3 +msgid "Import AutoCAD's Document Exchange Format" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:4 +msgid "" +"dxf2svg may come with Inkscape, but is also at http://dxf-svg-convert." +"sourceforge.net/" +msgstr "" + +#: ../share/extensions/dxf_output.inx.h:2 +#, fuzzy +msgid "DXF Output" +msgstr "Вывод" + +#: ../share/extensions/dxf_output.inx.h:3 +msgid "DXF file written by pstoedit" +msgstr "" + +#: ../share/extensions/dxf_output.inx.h:4 +msgid "pstoedit must be installed to run see http://www.pstoedit.net/pstoedit" +msgstr "" + +#: ../share/extensions/embedimage.inx.h:1 +#, fuzzy +msgid "Embed Images" +msgstr "Растры" + +#: ../share/extensions/eps_input.inx.h:1 +msgid "EPS Input" +msgstr "" + +#: ../share/extensions/eps_input.inx.h:2 +msgid "Encapsulated Postscript" +msgstr "" + +#: ../share/extensions/eps_input.inx.h:3 +msgid "Encapsulated Postscript (*.eps)" +msgstr "" + +#: ../share/extensions/epsi_output.inx.h:1 +#, fuzzy +msgid "EPSI Output" +msgstr "Вывод" + +#: ../share/extensions/epsi_output.inx.h:2 +msgid "Encapsulated Postscript Interchange (*.epsi)" +msgstr "" + +#: ../share/extensions/epsi_output.inx.h:3 +msgid "Encapsulated Postscript with a thumbnail" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:1 ../share/extensions/ffms.inx.h:1 +#: ../share/extensions/ffset.inx.h:1 ../share/extensions/ffss.inx.h:1 +#, fuzzy +msgid "Bridge Width" +msgstr "Ширина линии" + +#: ../share/extensions/ffmet.inx.h:2 ../share/extensions/ffms.inx.h:2 +msgid "First String Length" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:3 +msgid "FretFind Multi Length ET" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:4 ../share/extensions/ffms.inx.h:4 +#: ../share/extensions/ffset.inx.h:3 ../share/extensions/ffss.inx.h:3 +msgid "Fretboard Edges" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:5 ../share/extensions/ffms.inx.h:5 +msgid "Last String Length" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:6 ../share/extensions/ffms.inx.h:6 +#: ../share/extensions/ffset.inx.h:4 ../share/extensions/ffss.inx.h:4 +#, fuzzy +msgid "Number of Frets" +msgstr "Количество строк" + +#: ../share/extensions/ffmet.inx.h:7 ../share/extensions/ffms.inx.h:7 +#: ../share/extensions/ffset.inx.h:5 ../share/extensions/ffss.inx.h:5 +#, fuzzy +msgid "Number of Strings" +msgstr "Количество строк" + +#: ../share/extensions/ffmet.inx.h:8 ../share/extensions/ffms.inx.h:8 +#: ../share/extensions/ffset.inx.h:6 ../share/extensions/ffss.inx.h:6 +#, fuzzy +msgid "Nut Width" +msgstr "Ширина" + +#: ../share/extensions/ffmet.inx.h:9 ../share/extensions/ffms.inx.h:10 +msgid "Perpendicular Distance" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:10 ../share/extensions/ffset.inx.h:7 +msgid "Scale Base (2 for Octave)" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:11 ../share/extensions/ffset.inx.h:9 +msgid "Tones in Scale" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:12 ../share/extensions/ffms.inx.h:12 +#: ../share/extensions/ffset.inx.h:10 ../share/extensions/ffss.inx.h:10 +msgid "px per Unit" +msgstr "" + +#: ../share/extensions/ffms.inx.h:3 +msgid "FretFind Multi Length Scala" +msgstr "" + +#: ../share/extensions/ffms.inx.h:9 ../share/extensions/ffss.inx.h:7 +msgid "Path to Scala *.scl File" +msgstr "" + +#: ../share/extensions/ffms.inx.h:11 +msgid "Tuning (scale step for each string seperated by semicolons)" +msgstr "" + +#: ../share/extensions/ffset.inx.h:2 +msgid "FretFind Single Length ET" +msgstr "" + +#: ../share/extensions/ffset.inx.h:8 ../share/extensions/ffss.inx.h:8 +msgid "Scale Length" +msgstr "" + +#: ../share/extensions/ffss.inx.h:2 +msgid "FretFind Single Length Scala" +msgstr "" + +#: ../share/extensions/ffss.inx.h:9 +msgid "Tuning (Scale step for each string seperated by semicolons)" +msgstr "" + +#: ../share/extensions/handles.inx.h:1 +#, fuzzy +msgid "Draw Handles" +msgstr "Рисовать произвольные контуры" + +#: ../share/extensions/interp.inx.h:1 +#, fuzzy +msgid "Duplicate Endpaths" +msgstr "Дублировать ветвь" + +#: ../share/extensions/interp.inx.h:2 +#, fuzzy +msgid "Exponent" +msgstr "Экспорт" + +#: ../share/extensions/interp.inx.h:3 +msgid "Interpolate" +msgstr "" + +#: ../share/extensions/interp.inx.h:4 +msgid "Interpolate Style (Experimental)" +msgstr "" + +#: ../share/extensions/interp.inx.h:5 +msgid "Interpolation Method" +msgstr "" + +#: ../share/extensions/interp.inx.h:6 +msgid "Interpolation Steps" +msgstr "" + +#: ../share/extensions/kochify.inx.h:1 +msgid "Kochify" +msgstr "" + +#: ../share/extensions/kochify_load.inx.h:1 +msgid "Kochify (Load)" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:1 +#, fuzzy +msgid "Angle" +msgstr "Угол:" + +#: ../share/extensions/lindenmayer.inx.h:2 +msgid "Axiom" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:3 +#, fuzzy +msgid "Lindenmayer" +msgstr "Переименовать слой" + +#: ../share/extensions/lindenmayer.inx.h:4 +msgid "Order" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:5 +#, fuzzy +msgid "Rules" +msgstr "_Линейки" + +#: ../share/extensions/lindenmayer.inx.h:6 +#, fuzzy +msgid "Step" +msgstr "Шаги" + +#: ../share/extensions/motion.inx.h:1 +#, fuzzy +msgid "Direction" +msgstr "Описание" + +#: ../share/extensions/motion.inx.h:2 +#, fuzzy +msgid "Magnitude" +msgstr "Пурпурный" + +#: ../share/extensions/motion.inx.h:3 +#, fuzzy +msgid "Motion" +msgstr "_Поворот" + +#: ../share/extensions/pdf_output.inx.h:1 +msgid "Adobe PDF (*.pdf)" +msgstr "" + +#: ../share/extensions/pdf_output.inx.h:2 +msgid "Adobe Portable Document Format" +msgstr "" + +#: ../share/extensions/pdf_output.inx.h:3 +#, fuzzy +msgid "PDF Output" +msgstr "Вывод" + +#: ../share/extensions/ps_input.inx.h:1 +#, fuzzy +msgid "Postscript" +msgstr "Портрет" + +#: ../share/extensions/ps_input.inx.h:2 +msgid "Postscript (*.ps)" +msgstr "" + +#: ../share/extensions/ps_input.inx.h:3 +msgid "Postscript Input" +msgstr "" + +#: ../share/extensions/radiusrand.inx.h:1 +#, fuzzy +msgid "Radius" +msgstr "П_однять" + +#: ../share/extensions/radiusrand.inx.h:2 +#, fuzzy +msgid "Radius Randomize" +msgstr "Случайно:" + +#: ../share/extensions/radiusrand.inx.h:3 +msgid "Randomize Control Points" +msgstr "" + +#: ../share/extensions/radiusrand.inx.h:4 +#, fuzzy +msgid "Randomize Nodes" +msgstr "Искажен:" + +#: ../share/extensions/rtree.inx.h:1 +#, fuzzy +msgid "Initial Size" +msgstr "Размер изображения" + +#: ../share/extensions/rtree.inx.h:2 +msgid "Minimum Size" +msgstr "" + +#: ../share/extensions/rtree.inx.h:3 +#, fuzzy +msgid "Random Tree" +msgstr "Случайно:" + +#: ../share/extensions/sk_input.inx.h:1 +msgid "A diagram created with the program Sketch" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:2 +msgid "Sketch Diagram (*.sk)" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:3 +msgid "Sketch Input" +msgstr "" + +#: ../share/extensions/straightseg.inx.h:1 +msgid "Behavior" +msgstr "" + +#: ../share/extensions/straightseg.inx.h:3 +msgid "Segment Straightener" +msgstr "" + +#: ../share/extensions/summersnight.inx.h:1 +msgid "Summer's Night" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:1 +#: ../share/extensions/svgz_output.inx.h:1 +msgid "Compressed Inkscape SVG (*.svgz)" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:2 +#: ../share/extensions/svgz_output.inx.h:2 +msgid "Inkscape's native file format compressed with GZip" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:3 +msgid "SVGZ Input" +msgstr "" + +#: ../share/extensions/svgz_output.inx.h:3 +#, fuzzy +msgid "SVGZ Output" +msgstr "Вывод" + +#: ../share/extensions/txt2svg.inx.h:1 +msgid "ASCII Text" +msgstr "" + +#: ../share/extensions/txt2svg.inx.h:2 +msgid "Text File (*.txt)" +msgstr "" + +#: ../share/extensions/txt2svg.inx.h:3 +msgid "Text Input" +msgstr "" + +#: ../share/extensions/wavy.inx.h:1 +msgid "Calculate first derivative numerically" +msgstr "" + +#: ../share/extensions/wavy.inx.h:2 +msgid "First derivative" +msgstr "" + +#: ../share/extensions/wavy.inx.h:3 +msgid "Function" +msgstr "" + +#: ../share/extensions/wavy.inx.h:4 +msgid "Function Plotter" +msgstr "" + +#: ../share/extensions/wavy.inx.h:5 +msgid "Nodes per period" +msgstr "" + +#: ../share/extensions/wavy.inx.h:6 +msgid "Periods (2*Pi each)" +msgstr "" + +#: ../share/extensions/whirl.inx.h:1 +msgid "Amount of Whirl" +msgstr "" + +#: ../share/extensions/whirl.inx.h:2 +#, fuzzy +msgid "Center X" +msgstr "Центрировать строки" + +#: ../share/extensions/whirl.inx.h:3 +#, fuzzy +msgid "Center Y" +msgstr "Центрировать строки" + +#: ../share/extensions/whirl.inx.h:4 +#, fuzzy +msgid "Direction of Rotation" +msgstr "Отклонить приглашение" + +#: ../share/extensions/whirl.inx.h:5 +msgid "Whirl" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:1 +msgid "A popular graphics file format for clipart" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:2 +msgid "Windows Metafile (*.wmf)" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:3 +msgid "Windows Metafile Input" +msgstr "" + +#~ msgid "Custom canvas" +#~ msgstr "Нестандартный" + +#~ msgid "Current style" +#~ msgstr "Текущий стиль" + +#~ msgid "" +#~ "Current style is updated every time you change the style of any object " +#~ "(its fill, stroke, transparency, etc.)" +#~ msgstr "" +#~ "Текущий стиль сохраняет последний стиль, присвоенный какому-либо объекту " +#~ "(его заливку, штрих, прозрачность и т.д.)" + +#~ msgid "Arrange Objects" +#~ msgstr "Упорядочить объекты" + +#~ msgid "deg" +#~ msgstr "град" + +#~ msgid "" +#~ "%s is not a valid preferences file.\n" +#~ "%s" +#~ msgstr "" +#~ "%s не является файлом настроек.\n" +#~ "%s" + +#~ msgid "" +#~ "Inkscape will run with default settings.\n" +#~ "New settings will not be saved." +#~ msgstr "" +#~ "Inkscape будет использовать настройки по умолчанию. Измененные настройки " +#~ "не будут сохранены." + +#~ msgid "_Credits" +#~ msgstr "_Благодарности" + +#~ msgid "Grab sensitivity" +#~ msgstr "Радиус захвата" + +#~ msgid "Click/drag threshold" +#~ msgstr "Считать щелчком перетаскивание на" + +#~ msgid "Mouse wheel scrolls by" +#~ msgstr "Колесико мыши прокручивает на" + +#~ msgid "Scroll by" +#~ msgstr "Шаг прокрутки" + +#~ msgid "Acceleration" +#~ msgstr "Ускорение" + +#~ msgid "Speed" +#~ msgstr "Скорость" + +#~ msgid "Threshold" +#~ msgstr "Порог" + +#~ msgid "Arrow keys move by" +#~ msgstr "Стрелки двигают на" + +#~ msgid "> and < scale by" +#~ msgstr "Шаг масштабирования по > и <" + +#~ msgid "Inset/Outset by" +#~ msgstr "Втяжка/растяжка на" + +#~ msgid "Rotation snaps every" +#~ msgstr "Ограничение вращения" + +#~ msgid "Zoom in/out by" +#~ msgstr "Шаг масштаба" + +#~ msgid "Transform" +#~ msgstr "Матрица" diff --git a/po/sk.po b/po/sk.po new file mode 100644 index 000000000..e9802cb1b --- /dev/null +++ b/po/sk.po @@ -0,0 +1,10264 @@ +# translation of inkscape-sk-0.40.po to Slovak +# Copyright (C) 2002,2003, 2004 Free Software Foundation, Inc. +# This file is distributed under the same license as the sodipodi package. +# Zdenko Podobný , 2003, 2004. +# +msgid "" +msgstr "" +"Project-Id-Version: inkscape-sk-0.40\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2005-12-04 11:51-0800\n" +"PO-Revision-Date: 2005-02-13 17:05+0100\n" +"Last-Translator: Zdenko Podobný \n" +"Language-Team: Slovak <>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 1.3\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%" +"10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" +"10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" + +#: ../inkscape.desktop.in.h:1 +msgid "Create and edit Scalable Vector Graphics images" +msgstr "" + +#: ../inkscape.desktop.in.h:2 +msgid "Inkscape SVG Vector Illustrator" +msgstr "Inkscape SVG Vektorový ilustrátor" + +#: ../../po/../src/arc-context.cpp:350 +msgid "" +"Ctrl: make circle or integer-ratio ellipse, snap arc/segment angle" +msgstr "Ctrl: vytvoriÅ¥ kruh alebo elipsu, zlomený oblúk/segment uhla" + +#: ../../po/../src/arc-context.cpp:351 ../../po/../src/rect-context.cpp:388 +msgid "Shift: draw around the starting point" +msgstr "Shift: kresliÅ¥ okolo Å¡tartovacieho bodu" + +#: ../../po/../src/arc-context.cpp:413 +#: ../../po/../src/connector-context.cpp:493 +#: ../../po/../src/dyna-draw-context.cpp:506 +#: ../../po/../src/pen-context.cpp:329 ../../po/../src/pencil-context.cpp:208 +#: ../../po/../src/rect-context.cpp:452 ../../po/../src/spiral-context.cpp:421 +#: ../../po/../src/star-context.cpp:427 +msgid "Current layer is hidden. Unhide it to be able to draw on it." +msgstr "" + +#: ../../po/../src/arc-context.cpp:417 +#: ../../po/../src/connector-context.cpp:497 +#: ../../po/../src/dyna-draw-context.cpp:510 +#: ../../po/../src/pen-context.cpp:336 ../../po/../src/pencil-context.cpp:212 +#: ../../po/../src/rect-context.cpp:456 ../../po/../src/spiral-context.cpp:426 +#: ../../po/../src/star-context.cpp:431 +msgid "Current layer is locked. Unlock it to be able to draw on it." +msgstr "" + +#: ../../po/../src/arc-context.cpp:496 +#, fuzzy, c-format +msgid "" +"Ellipse: %s × %s; with Ctrl to make circle or integer-" +"ratio ellipse; with Shift to draw around the starting point" +msgstr "" +"Elipsa: %s x %s; s Ctrl na vytvorenie kruhu alebo celočíselnú " +"elipsu so Shift na kreslenie okolo Å¡tartovacieho bodu" + +#: ../../po/../src/connector-context.cpp:518 +#, fuzzy +msgid "Creating new connector" +msgstr "Tvorba novej krivky" + +#: ../../po/../src/connector-context.cpp:939 +#, fuzzy +msgid "Finishing connector" +msgstr "Dokončenie kreslenia perom" + +#: ../../po/../src/connector-context.cpp:1108 +msgid "Connection point: click or drag to create a new connector" +msgstr "" + +#: ../../po/../src/connector-context.cpp:1185 +msgid "Connector endpoint: drag to reroute or connect to new shapes" +msgstr "" + +#: ../../po/../src/connector-context.cpp:1278 +#, fuzzy +msgid "Select at least one non-connector object." +msgstr "Vyberte najmenej dva objekty, ktoré sa majú zoskupiÅ¥." + +#: ../../po/../src/desktop-events.cpp:238 +#, c-format +msgid "%s at %s" +msgstr "%s na %s" + +#. TRANSLATORS: This string appears when double-clicking on a guide. +#. This is the distance by which the guide is to be moved. +#: ../../po/../src/desktop-events.cpp:277 +msgid " relative by " +msgstr " relatívne o " + +#. TRANSLATORS: This string appears when double-clicking on a guide. +#. This is the target location where the guide is to be moved. +#: ../../po/../src/desktop-events.cpp:282 +#: ../../po/../src/desktop-events.cpp:395 +msgid " absolute to " +msgstr " absolútny k" + +#. create dialog +#: ../../po/../src/desktop-events.cpp:348 +msgid "Guideline" +msgstr "Vodítko" + +#: ../../po/../src/desktop-events.cpp:432 +#, c-format +msgid "Move %s" +msgstr "Presunúť %s" + +#: ../../po/../src/desktop.cpp:678 +msgid "No previous zoom." +msgstr "Žiadne predchádzajúce zobrazenie." + +#: ../../po/../src/desktop.cpp:703 +msgid "No next zoom." +msgstr "Žiadne nasledujúce zobrazenie." + +#: ../../po/../src/dialogs/clonetiler.cpp:182 +#, fuzzy +msgid "Nothing selected." +msgstr "Nič nebolo zmazané." + +#: ../../po/../src/dialogs/clonetiler.cpp:188 +msgid "More than one object selected." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:195 +#, c-format +msgid "Object has %d tiled clones." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:200 +msgid "Object has no tiled clones." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:865 +#, fuzzy +msgid "Select one object whose tiled clones to unclump." +msgstr "Vyberte objekt, ktorý sa má klonovaÅ¥." + +#: ../../po/../src/dialogs/clonetiler.cpp:916 +#, fuzzy +msgid "Select one object whose tiled clones to remove." +msgstr "Vyberte objekt, ktorý sa má klonovaÅ¥." + +#: ../../po/../src/dialogs/clonetiler.cpp:984 +#: ../../po/../src/selection-chemistry.cpp:1774 +msgid "Select an object to clone." +msgstr "Vyberte objekt, ktorý sa má klonovaÅ¥." + +#: ../../po/../src/dialogs/clonetiler.cpp:990 +#: ../../po/../src/selection-chemistry.cpp:1780 +msgid "" +"If you want to clone several objects, group them and clone the " +"group." +msgstr "" +"Ak chcete klonovaÅ¥ niekoľko objektov, zoskupte ich a vyklonujte " +"skupinu." + +#: ../../po/../src/dialogs/clonetiler.cpp:1484 +msgid "Per row:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1497 +#, fuzzy +msgid "Per column:" +msgstr "Žiadny prechod nebol zvolený" + +#: ../../po/../src/dialogs/clonetiler.cpp:1505 +#, fuzzy +msgid "Randomize:" +msgstr "Nič nebolo zmazané." + +#: ../../po/../src/dialogs/clonetiler.cpp:1656 +msgid "_Symmetry" +msgstr "_Symetria" + +#. TRANSLATORS: For the following 17 symmetry groups, see +#. * http://www.bib.ulb.ac.be/coursmath/doc/17.htm (visual examples); +#. * http://www.clarku.edu/~djoyce/wallpaper/seventeen.html (English vocabulary); or +#. * http://membres.lycos.fr/villemingerard/Geometri/Sym1D.htm (French vocabulary). +#. +#: ../../po/../src/dialogs/clonetiler.cpp:1664 +msgid "Select one of the 17 symmetry groups for the tiling" +msgstr "Vyberte jeden zo 17 symtrických skupín pre dláždenie" + +#. TRANSLATORS: "translation" means "shift" / "displacement" here. +#: ../../po/../src/dialogs/clonetiler.cpp:1675 +#, fuzzy +msgid "P1: simple translation" +msgstr "Tým prekladateľov GNOME" + +#: ../../po/../src/dialogs/clonetiler.cpp:1676 +msgid "P2: 180° rotation" +msgstr "P2: 180° rotácie" + +#: ../../po/../src/dialogs/clonetiler.cpp:1677 +msgid "PM: reflection" +msgstr "PM: odraz" + +#. TRANSLATORS: "glide reflection" is a reflection and a translation combined. +#. For more info, see http://mathforum.org/sum95/suzanne/symsusan.html +#: ../../po/../src/dialogs/clonetiler.cpp:1680 +#, fuzzy +msgid "PG: glide reflection" +msgstr "Povolí/zakáže mapovanie prostredia (odraz)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1681 +#, fuzzy +msgid "CM: reflection + glide reflection" +msgstr "Povolí/zakáže mapovanie prostredia (odraz)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1682 +#, fuzzy +msgid "PMM: reflection + reflection" +msgstr "PM: odraz" + +#: ../../po/../src/dialogs/clonetiler.cpp:1683 +msgid "PMG: reflection + 180° rotation" +msgstr "PMG: odraz + 180° rotácia" + +#: ../../po/../src/dialogs/clonetiler.cpp:1684 +msgid "PGG: glide reflection + 180° rotation" +msgstr "PGG: kĺzavý odraz + 180° rotácia" + +#: ../../po/../src/dialogs/clonetiler.cpp:1685 +msgid "CMM: reflection + reflection + 180° rotation" +msgstr "CMM: odraz + odraz + 180° rotácia" + +#: ../../po/../src/dialogs/clonetiler.cpp:1686 +msgid "P4: 90° rotation" +msgstr "P4: 90° rotácia" + +#: ../../po/../src/dialogs/clonetiler.cpp:1687 +msgid "P4M: 90° rotation + 45° reflection" +msgstr "P4M: 90° rotácia + 45° odraz" + +#: ../../po/../src/dialogs/clonetiler.cpp:1688 +msgid "P4G: 90° rotation + 90° reflection" +msgstr "P4G: 90° rotácia + 90° odraz" + +#: ../../po/../src/dialogs/clonetiler.cpp:1689 +msgid "P3: 120° rotation" +msgstr "P3: 120° rotácia" + +#: ../../po/../src/dialogs/clonetiler.cpp:1690 +msgid "P31M: reflection + 120° rotation, dense" +msgstr "P31M: odraz + 120° rotácia, hustý" + +#: ../../po/../src/dialogs/clonetiler.cpp:1691 +msgid "P3M1: reflection + 120° rotation, sparse" +msgstr "P3M1: odraz + 120° rotácia, riedky" + +#: ../../po/../src/dialogs/clonetiler.cpp:1692 +msgid "P6: 60° rotation" +msgstr "P6: 60° rotácia" + +#: ../../po/../src/dialogs/clonetiler.cpp:1693 +msgid "P6M: reflection + 60° rotation" +msgstr "P6M: odraz + 60° rotácia" + +#: ../../po/../src/dialogs/clonetiler.cpp:1721 +msgid "S_hift" +msgstr "" + +#. TRANSLATORS: "shift" means: the tiles will be shifted (offset) horizontally by this amount +#: ../../po/../src/dialogs/clonetiler.cpp:1731 +#, fuzzy, no-c-format +msgid "Shift X:" +msgstr "ZmeniÅ¥:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1739 +#, no-c-format +msgid "Horizontal shift per row (in % of tile width)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1747 +#, no-c-format +msgid "Horizontal shift per column (in % of tile width)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1754 +msgid "Randomize the horizontal shift by this percentage" +msgstr "" + +#. TRANSLATORS: "shift" means: the tiles will be shifted (offset) vertically by this amount +#: ../../po/../src/dialogs/clonetiler.cpp:1764 +#, fuzzy, no-c-format +msgid "Shift Y:" +msgstr "ZmeniÅ¥:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1772 +#, no-c-format +msgid "Vertical shift per row (in % of tile height)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1780 +#, no-c-format +msgid "Vertical shift per column (in % of tile height)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1787 +msgid "Randomize the vertical shift by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1795 +#, fuzzy +msgid "Exponent:" +msgstr "ZmeniÅ¥:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1802 +msgid "Whether rows are spaced evenly (1), converge (<1) or diverge (>1)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1809 +msgid "Whether columns are spaced evenly (1), converge (<1) or diverge (>1)" +msgstr "" + +#. TRANSLATORS: "Alternate" is a verb here +#: ../../po/../src/dialogs/clonetiler.cpp:1817 +#: ../../po/../src/dialogs/clonetiler.cpp:1907 +#: ../../po/../src/dialogs/clonetiler.cpp:1966 +#: ../../po/../src/dialogs/clonetiler.cpp:2022 +#: ../../po/../src/dialogs/clonetiler.cpp:2153 +msgid "Alternate:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1823 +msgid "Alternate the sign of shifts for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1828 +msgid "Alternate the sign of shifts for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1837 +msgid "Sc_ale" +msgstr "Mierk_a" + +#: ../../po/../src/dialogs/clonetiler.cpp:1845 +#, fuzzy +msgid "Scale X:" +msgstr "Kruh" + +#: ../../po/../src/dialogs/clonetiler.cpp:1853 +#, fuzzy, no-c-format +msgid "Horizontal scale per row (in % of tile width)" +msgstr "vodorovná hodnota mierky" + +#: ../../po/../src/dialogs/clonetiler.cpp:1861 +#, fuzzy, no-c-format +msgid "Horizontal scale per column (in % of tile width)" +msgstr "vodorovná hodnota mierky" + +#: ../../po/../src/dialogs/clonetiler.cpp:1868 +msgid "Randomize the horizontal scale by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1876 +#, fuzzy +msgid "Scale Y:" +msgstr "Kruh" + +#: ../../po/../src/dialogs/clonetiler.cpp:1884 +#, fuzzy, no-c-format +msgid "Vertical scale per row (in % of tile height)" +msgstr "zvislá hodnota mierky" + +#: ../../po/../src/dialogs/clonetiler.cpp:1892 +#, fuzzy, no-c-format +msgid "Vertical scale per column (in % of tile height)" +msgstr "zvislá hodnota mierky" + +#: ../../po/../src/dialogs/clonetiler.cpp:1899 +msgid "Randomize the vertical scale by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1913 +#, fuzzy +msgid "Alternate the sign of scales for each row" +msgstr "zvislá hodnota mierky" + +#: ../../po/../src/dialogs/clonetiler.cpp:1918 +#, fuzzy +msgid "Alternate the sign of scales for each column" +msgstr "zvislá hodnota mierky" + +#: ../../po/../src/dialogs/clonetiler.cpp:1927 +msgid "_Rotation" +msgstr "_Rotácia" + +#: ../../po/../src/dialogs/clonetiler.cpp:1935 +#, fuzzy +msgid "Angle:" +msgstr "ZmeniÅ¥:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1943 +#, no-c-format +msgid "Rotate tiles by this angle for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1951 +#, no-c-format +msgid "Rotate tiles by this angle for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1958 +msgid "Randomize the rotation angle by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1972 +msgid "Alternate the rotation direction for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1977 +msgid "Alternate the rotation direction for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1985 +msgid "_Opacity" +msgstr "_Krytie" + +#: ../../po/../src/dialogs/clonetiler.cpp:1993 +#, fuzzy +msgid "Fade out:" +msgstr "ZmeniÅ¥:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2000 +msgid "Decrease tile opacity by this percentage for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2007 +msgid "Decrease tile opacity by this percentage for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2014 +msgid "Randomize the tile opacity by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2028 +msgid "Alternate the sign of opacity change for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2033 +msgid "Alternate the sign of opacity change for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2041 +#, fuzzy +msgid "Co_lor" +msgstr "Farba" + +#: ../../po/../src/dialogs/clonetiler.cpp:2046 +#, fuzzy +msgid "Initial color: " +msgstr "Výber farieb:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2050 +msgid "Initial color of tiled clones" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2050 +msgid "" +"Initial color for clones (works only if the original has unset fill or " +"stroke)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2065 +#, fuzzy +msgid "H:" +msgstr "Nový:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2072 +msgid "Change the tile hue by this percentage for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2079 +msgid "Change the tile hue by this percentage for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2086 +msgid "Randomize the tile hue by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2095 +#, fuzzy +msgid "S:" +msgstr "Nový:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2102 +msgid "Change the color saturation by this percentage for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2109 +msgid "Change the color saturation by this percentage for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2116 +msgid "Randomize the color saturation by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2124 +#, fuzzy +msgid "L:" +msgstr "Nový:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2131 +msgid "Change the color lightness by this percentage for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2138 +msgid "Change the color lightness by this percentage for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2145 +msgid "Randomize the color lightness by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2159 +msgid "Alternate the sign of color changes for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2164 +msgid "Alternate the sign of color changes for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2172 +#, fuzzy +msgid "_Trace" +msgstr "_PrekresliÅ¥ bitmapu" + +#: ../../po/../src/dialogs/clonetiler.cpp:2179 +msgid "Trace the drawing under the tiles" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2183 +msgid "" +"For each clone, pick a value from the drawing in that clone's location and " +"apply it to the clone" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2197 +msgid "1. Pick from the drawing:" +msgstr "" + +#. ----Hbox2 +#: ../../po/../src/dialogs/clonetiler.cpp:2208 +#: ../../po/../src/dialogs/clonetiler.cpp:2355 +#: ../../po/../src/ui/dialog/tracedialog.cpp:445 +msgid "Color" +msgstr "Farba" + +#: ../../po/../src/dialogs/clonetiler.cpp:2209 +#, fuzzy +msgid "Pick the visible color and opacity" +msgstr "VybraÅ¥ viditeľnú farbu (bez alphy)" + +#: ../../po/../src/dialogs/clonetiler.cpp:2216 +#: ../../po/../src/dialogs/clonetiler.cpp:2365 +#: ../share/extensions/dropshadow.inx.h:3 +#, fuzzy +msgid "Opacity" +msgstr "_Krytie" + +#: ../../po/../src/dialogs/clonetiler.cpp:2217 +msgid "Pick the total accumulated opacity" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2224 +#, fuzzy +msgid "R" +msgstr "_R" + +#: ../../po/../src/dialogs/clonetiler.cpp:2225 +msgid "Pick the Red component of the color" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2232 +#, fuzzy +msgid "G" +msgstr "_G" + +#: ../../po/../src/dialogs/clonetiler.cpp:2233 +msgid "Pick the Green component of the color" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2240 +#, fuzzy +msgid "B" +msgstr "_B" + +#: ../../po/../src/dialogs/clonetiler.cpp:2241 +msgid "Pick the Blue component of the color" +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2250 +msgid "clonetiler|H" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2251 +#, fuzzy +msgid "Pick the hue of the color" +msgstr "Počet jedinečných farieb: %d" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2260 +msgid "clonetiler|S" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2261 +msgid "Pick the saturation of the color" +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2270 +msgid "clonetiler|L" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2271 +msgid "Pick the lightness of the color" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2281 +msgid "2. Tweak the picked value:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2291 +msgid "Gamma-correct:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2296 +msgid "Shift the mid-range of the picked value upwards (>0) or downwards (<0)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2303 +msgid "Randomize:" +msgstr "NáhodnosÅ¥:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2308 +msgid "Randomize the picked value by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2315 +#, fuzzy +msgid "Invert:" +msgstr "InvertovaÅ¥" + +#: ../../po/../src/dialogs/clonetiler.cpp:2319 +msgid "Invert the picked value" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2325 +msgid "3. Apply the value to the clones':" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2335 +#, fuzzy +msgid "Presence" +msgstr "Zabezpečene" + +#: ../../po/../src/dialogs/clonetiler.cpp:2338 +msgid "" +"Each clone is created with the probability determined by the picked value in " +"that point" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2345 +#, fuzzy +msgid "Size" +msgstr "Strany:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2348 +msgid "Each clone's size is determined by the picked value in that point" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2358 +msgid "" +"Each clone is painted by the picked color (the original must have unset fill " +"or stroke)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2368 +msgid "Each clone's opacity is determined by the picked value in that point" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2395 +#, fuzzy +msgid "How many rows in the tiling" +msgstr "Koľko riadkov v Å¡ablóne registra?" + +#: ../../po/../src/dialogs/clonetiler.cpp:2415 +#, fuzzy +msgid "How many columns in the tiling" +msgstr "Koľko riadkov v Å¡ablóne registra?" + +#: ../../po/../src/dialogs/clonetiler.cpp:2445 +msgid "Width of the rectangle to be filled" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2470 +msgid "Height of the rectangle to be filled" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2485 +#, fuzzy +msgid "Rows, columns: " +msgstr "Na stĺpec:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2486 +msgid "Create the specified number of rows and columns" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2495 +msgid "Width, height: " +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2496 +msgid "Fill the specified width and height with the tiling" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2512 +#, fuzzy +msgid "Use saved size and position of the tile" +msgstr "VeľkosÅ¥ objektu a pozícia" + +#: ../../po/../src/dialogs/clonetiler.cpp:2515 +msgid "" +"Pretend that the size and position of the tile are the same as the last time " +"you tiled it (if any), instead of using the current size" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2539 +msgid " _Create " +msgstr " _VytvoriÅ¥ " + +#: ../../po/../src/dialogs/clonetiler.cpp:2541 +msgid "Create and tile the clones of the selection" +msgstr "" + +#. TRANSLATORS: if a group of objects are "clumped" together, then they +#. are unevenly spread in the given amount of space - as shown in the +#. diagrams on the left in the following screenshot: +#. http://www.inkscape.org/screenshots/gallery/inkscape-0.42-CVS-tiles-unclump.png +#. So unclumping is the process of spreading a number of objects out more evenly. +#: ../../po/../src/dialogs/clonetiler.cpp:2556 +msgid " _Unclump " +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2557 +msgid "Spread out clones to reduce clumping; can be applied repeatedly" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2563 +msgid " Re_move " +msgstr "O_dstrániÅ¥" + +#: ../../po/../src/dialogs/clonetiler.cpp:2564 +#, fuzzy +msgid "Remove existing tiled clones of the selected object (siblings only)" +msgstr "PamätaÅ¥ si Å¡týl (prvého) zvoleného objektu ako Å¡týl tohoto nástroja" + +#: ../../po/../src/dialogs/clonetiler.cpp:2580 +msgid " R_eset " +msgstr "O_bnoviÅ¥" + +#. TRANSLATORS: "change" is a noun here +#: ../../po/../src/dialogs/clonetiler.cpp:2582 +msgid "" +"Reset all shifts, scales, rotates, opacity and color changes in the dialog " +"to zero" +msgstr "" + +#: ../../po/../src/dialogs/color-picker.cpp:280 +msgid "Close" +msgstr "ZatvoriÅ¥" + +#: ../../po/../src/dialogs/debugdialog.cpp:138 +msgid "Messages" +msgstr "Správy" + +#. ## Add a menu for clear() +#: ../../po/../src/dialogs/debugdialog.cpp:144 +#: ../../po/../src/menus-skeleton.h:16 +#: ../../po/../src/ui/dialog/messages.cpp:56 +#: ../../po/../src/ui/dialog/scriptdialog.cpp:181 +msgid "_File" +msgstr "_Súbor" + +#. TRANSLATORS: "Clear" is a verb here +#: ../../po/../src/dialogs/debugdialog.cpp:145 +#: ../../po/../src/dialogs/find.cpp:753 +#: ../../po/../src/ui/dialog/messages.cpp:57 +#: ../../po/../src/ui/dialog/scriptdialog.cpp:182 +msgid "_Clear" +msgstr "_ZmazaÅ¥" + +#: ../../po/../src/dialogs/debugdialog.cpp:147 +#: ../../po/../src/ui/dialog/messages.cpp:59 +msgid "Capture log messages" +msgstr "ZachytávaÅ¥ log správy" + +#: ../../po/../src/dialogs/debugdialog.cpp:149 +#: ../../po/../src/ui/dialog/messages.cpp:61 +#, fuzzy +msgid "Release log messages" +msgstr "ZobraziÅ¥ opakované správy" + +#. Notebook tab +#: ../../po/../src/dialogs/desktop-properties.cpp:909 +#: ../../po/../src/ui/dialog/document-preferences.cpp:89 +#: ../../po/../src/ui/widget/panel.cpp:107 +msgid "Grid" +msgstr "Mriežka" + +#. Checkbuttons +#. / \todo FIXME: gray out snapping when grid is off +#. / \todo FIXME: gray out snapping when grid is off. +#. / Dissenting view: you want snapping without grid. +#: ../../po/../src/dialogs/desktop-properties.cpp:917 +#: ../../po/../src/ui/dialog/document-preferences.cpp:179 +msgid "Show grid" +msgstr "ZobraziÅ¥ mriežku" + +#: ../../po/../src/dialogs/desktop-properties.cpp:917 +#: ../../po/../src/ui/dialog/document-preferences.cpp:179 +#: ../../po/../src/verbs.cpp:2115 +msgid "Show or hide grid" +msgstr "ZobraziÅ¥ alebo skryÅ¥ mriežku" + +#: ../../po/../src/dialogs/desktop-properties.cpp:918 +#: ../../po/../src/ui/dialog/document-preferences.cpp:180 +msgid "Snap bounding boxes to grid" +msgstr "PritiahnuÅ¥ ohraničenie k mriežke" + +#: ../../po/../src/dialogs/desktop-properties.cpp:918 +#: ../../po/../src/dialogs/desktop-properties.cpp:1001 +#: ../../po/../src/ui/dialog/document-preferences.cpp:181 +#: ../../po/../src/ui/dialog/document-preferences.cpp:236 +#, fuzzy +msgid "Snap the edges of the object bounding boxes" +msgstr "Každý zvolený objekt zobrazí svoje ohraničenie" + +#: ../../po/../src/dialogs/desktop-properties.cpp:919 +#: ../../po/../src/ui/dialog/document-preferences.cpp:183 +#, fuzzy +msgid "Snap nodes to grid" +msgstr "PritiahnuÅ¥ body k mriežke" + +#: ../../po/../src/dialogs/desktop-properties.cpp:919 +#: ../../po/../src/dialogs/desktop-properties.cpp:1002 +#: ../../po/../src/ui/dialog/document-preferences.cpp:184 +#: ../../po/../src/ui/dialog/document-preferences.cpp:239 +msgid "Snap path nodes, text baselines, ellipse centers, etc." +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:937 +#: ../../po/../src/ui/dialog/document-preferences.cpp:186 +msgid "Grid units:" +msgstr "Jednotky mriežky:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:939 +#: ../../po/../src/ui/dialog/document-preferences.cpp:187 +msgid "Origin X:" +msgstr "Začiatok X:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:942 +#: ../../po/../src/ui/dialog/document-preferences.cpp:189 +msgid "Origin Y:" +msgstr "Začiatok Y:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:945 +#: ../../po/../src/ui/dialog/document-preferences.cpp:191 +msgid "Spacing X:" +msgstr "Rozostup X:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:948 +#: ../../po/../src/ui/dialog/document-preferences.cpp:193 +msgid "Spacing Y:" +msgstr "Rozostup Y:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:952 +#: ../../po/../src/dialogs/desktop-properties.cpp:1013 +#: ../../po/../src/ui/dialog/document-preferences.cpp:195 +#: ../../po/../src/ui/dialog/document-preferences.cpp:241 +msgid "Snap units:" +msgstr "Jednotky pritiahnutia:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:955 +#: ../../po/../src/dialogs/desktop-properties.cpp:1016 +#: ../../po/../src/ui/dialog/document-preferences.cpp:196 +#: ../../po/../src/ui/dialog/document-preferences.cpp:242 +msgid "Snap distance:" +msgstr "VzdialenosÅ¥ pritiahnutia:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:958 +#: ../../po/../src/ui/dialog/document-preferences.cpp:199 +#, fuzzy +msgid "Grid line color:" +msgstr "Farba vodítok" + +#: ../../po/../src/dialogs/desktop-properties.cpp:959 +#: ../../po/../src/ui/dialog/document-preferences.cpp:199 +#, fuzzy +msgid "Grid line color" +msgstr "Farba vodítok" + +#: ../../po/../src/dialogs/desktop-properties.cpp:959 +#: ../../po/../src/ui/dialog/document-preferences.cpp:200 +#, fuzzy +msgid "Color of grid lines" +msgstr "Hlavná vzdialenosÅ¥ medzi čiarami mriežky" + +#: ../../po/../src/dialogs/desktop-properties.cpp:961 +#: ../../po/../src/ui/dialog/document-preferences.cpp:201 +msgid "Major grid line color:" +msgstr "Farba hlavnej čiary mriežky:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:962 +#: ../../po/../src/ui/dialog/document-preferences.cpp:201 +#, fuzzy +msgid "Major grid line color" +msgstr "Farba hlavnej čiary mriežky:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:962 +#: ../../po/../src/ui/dialog/document-preferences.cpp:202 +msgid "Color of the major (highlighted) grid lines" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:965 +#: ../../po/../src/ui/dialog/document-preferences.cpp:204 +#, fuzzy +msgid "Major grid line every:" +msgstr "Farba hlavnej čiary mriežky:" + +#. TRANSLATORS: This belongs to the "Major grid line every:" string, +#. see grid settings in the "Document Preferences" dialog +#: ../../po/../src/dialogs/desktop-properties.cpp:977 +#: ../../po/../src/ui/dialog/document-preferences.cpp:204 +msgid "lines" +msgstr "čiary" + +#. Guidelines page +#: ../../po/../src/dialogs/desktop-properties.cpp:991 +#: ../../po/../src/ui/dialog/document-preferences.cpp:90 +msgid "Guides" +msgstr "Vodítka" + +#. / \todo FIXME: gray out snapping when guides are off +#. / Dissenting view: you want snapping without guides. +#: ../../po/../src/dialogs/desktop-properties.cpp:1000 +#: ../../po/../src/ui/dialog/document-preferences.cpp:234 +msgid "Show guides" +msgstr "ZobraziÅ¥ vodítka" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1000 +#: ../../po/../src/ui/dialog/document-preferences.cpp:234 +#: ../../po/../src/verbs.cpp:2116 +msgid "Show or hide guides" +msgstr "ZobraziÅ¥ alebo skryÅ¥ vodítka" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1001 +#: ../../po/../src/ui/dialog/document-preferences.cpp:235 +msgid "Snap bounding boxes to guides" +msgstr "PritiahnuÅ¥ ohraničenie k vodítkam" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1002 +#: ../../po/../src/ui/dialog/document-preferences.cpp:238 +msgid "Snap points to guides" +msgstr "PritiahnuÅ¥ body k mriežke" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1020 +#: ../../po/../src/ui/dialog/document-preferences.cpp:243 +msgid "Guide color:" +msgstr "Farba vodítok:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1021 +#: ../../po/../src/ui/dialog/document-preferences.cpp:243 +msgid "Guideline color" +msgstr "Farba vodítok" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1021 +#: ../../po/../src/ui/dialog/document-preferences.cpp:244 +#, fuzzy +msgid "Color of guidelines" +msgstr "Vodorovné vodítko" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1023 +#: ../../po/../src/ui/dialog/document-preferences.cpp:245 +msgid "Highlight color:" +msgstr "Farba zvýraznenia:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1024 +#: ../../po/../src/ui/dialog/document-preferences.cpp:245 +msgid "Highlighted guideline color" +msgstr "Farba zvýraznenia vodítok" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1024 +#: ../../po/../src/ui/dialog/document-preferences.cpp:246 +msgid "Color of a guideline when it is under mouse" +msgstr "" + +#. Page page +#: ../../po/../src/dialogs/desktop-properties.cpp:1029 +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:855 +#: ../../po/../src/ui/dialog/document-preferences.cpp:88 +#: ../../po/../src/widgets/desktop-widget.cpp:1061 +msgid "Page" +msgstr "Stránka" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1039 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +#, fuzzy +msgid "Background:" +msgstr "Farba pozadia" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1040 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +msgid "Background color" +msgstr "Farba pozadia" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1041 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +msgid "" +"Color and transparency of the page background (also used for bitmap export)" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1045 +#: ../../po/../src/ui/dialog/document-preferences.cpp:147 +#, fuzzy +msgid "Show page border" +msgstr "ZobraziÅ¥ okraj plátna" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1049 +#: ../../po/../src/ui/dialog/document-preferences.cpp:148 +msgid "Border on top of drawing" +msgstr "Okraj na vrchole kresby" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1052 +#: ../../po/../src/ui/dialog/document-preferences.cpp:149 +msgid "Border color:" +msgstr "Farba okraja:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1053 +#: ../../po/../src/ui/dialog/document-preferences.cpp:149 +#, fuzzy +msgid "Page border color" +msgstr "Farba okraja plátna" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1054 +#: ../../po/../src/ui/dialog/document-preferences.cpp:150 +#, fuzzy +msgid "Color of the page border" +msgstr "ZobraziÅ¥ okraj plátna" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1059 +#: ../../po/../src/ui/dialog/document-preferences.cpp:152 +msgid "Show page shadow" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1063 +#: ../../po/../src/ui/dialog/document-preferences.cpp:153 +msgid "Default units:" +msgstr "Å tandardné jednotky:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1069 +msgid "Units for the tool controls, ruler, and the statusbar" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1086 +#: ../../po/../src/ui/widget/page-sizer.cpp:209 +#, fuzzy +msgid "Page size:" +msgstr "VeľkosÅ¥ plátna:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1110 +#: ../../po/../src/ui/widget/page-sizer.cpp:219 +msgid "Custom" +msgstr "Vlastné" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1121 +#: ../../po/../src/ui/widget/page-sizer.cpp:225 +#, fuzzy +msgid "Page orientation:" +msgstr "Orientácia plátna:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1133 +#: ../../po/../src/ui/widget/page-sizer.cpp:232 +msgid "Landscape" +msgstr "Na šírku" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1139 +#: ../../po/../src/ui/widget/page-sizer.cpp:234 +msgid "Portrait" +msgstr "Na výšku" + +#. Custom paper frame +#: ../../po/../src/dialogs/desktop-properties.cpp:1148 +#: ../../po/../src/ui/widget/page-sizer.cpp:249 +#, fuzzy +msgid "Custom size" +msgstr "Vlastné" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1160 +#: ../../po/../src/dialogs/export.cpp:269 +#: ../../po/../src/ui/widget/page-sizer.cpp:261 +msgid "Units:" +msgstr "Jednotky:" + +#. Stroke width +#: ../../po/../src/dialogs/desktop-properties.cpp:1162 +#: ../../po/../src/dialogs/export.cpp:310 +#: ../../po/../src/dialogs/object-attributes.cpp:55 +#: ../../po/../src/dialogs/stroke-style.cpp:985 +#: ../../po/../src/ui/widget/page-sizer.cpp:262 +#: ../../po/../src/widgets/toolbox.cpp:1957 +msgid "Width:" +msgstr "Šírka:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1183 +#: ../../po/../src/dialogs/export.cpp:326 +#: ../../po/../src/dialogs/export.cpp:431 +#: ../../po/../src/dialogs/object-attributes.cpp:56 +#: ../../po/../src/ui/widget/page-sizer.cpp:263 +msgid "Height:" +msgstr "Výška:" + +#. +#. * Ownership metadata tab +#. +#: ../../po/../src/dialogs/desktop-properties.cpp:1206 +msgid "Metadata" +msgstr "Metadáta" + +#. add license selector pull-down +#: ../../po/../src/dialogs/desktop-properties.cpp:1225 +msgid "License" +msgstr "Licencia" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1255 +msgid "Proprietary" +msgstr "Proprietárna" + +#: ../../po/../src/dialogs/display-settings.cpp:212 +msgid "When transforming, show:" +msgstr "Počas transformácie zobraziÅ¥:" + +#: ../../po/../src/dialogs/display-settings.cpp:223 +msgid "Objects" +msgstr "Objekty" + +#: ../../po/../src/dialogs/display-settings.cpp:224 +msgid "Show the actual objects when moving or transforming" +msgstr "ZobraziÅ¥ aktuálny objekt pri pohybe alebo transformácií" + +#: ../../po/../src/dialogs/display-settings.cpp:231 +msgid "Box outline" +msgstr "Obrys poľa" + +#: ../../po/../src/dialogs/display-settings.cpp:232 +msgid "Show only a box outline of the objects when moving or transforming" +msgstr "ZobraziÅ¥ iba obrys poľa objektu pri pohybe alebo transformácii" + +#: ../../po/../src/dialogs/display-settings.cpp:238 +msgid "Per-object selection cue:" +msgstr "Označenie zvoleného objektu:" + +#. sorationsnapsperpi == 0 means no snapping +#: ../../po/../src/dialogs/display-settings.cpp:249 +#: ../../po/../src/dialogs/display-settings.cpp:386 +#: ../../po/../src/dialogs/display-settings.cpp:441 +#: ../../po/../src/dialogs/display-settings.cpp:1482 +#: ../../po/../src/dialogs/stroke-style.cpp:791 +#: ../../po/../src/interface.cpp:741 +#: ../../po/../src/ui/widget/selected-style.cpp:100 +#: ../../po/../src/verbs.cpp:1842 +msgid "None" +msgstr "Žiadne" + +#: ../../po/../src/dialogs/display-settings.cpp:250 +msgid "No per-object selection indication" +msgstr "Žiadna indikácia pre zvolený objekt" + +#: ../../po/../src/dialogs/display-settings.cpp:256 +msgid "Mark" +msgstr "Značka" + +#: ../../po/../src/dialogs/display-settings.cpp:257 +msgid "Each selected object has a diamond mark in the top left corner" +msgstr "Každý vybraný objekt bude označený diamantom v ľavom hornom roku" + +#: ../../po/../src/dialogs/display-settings.cpp:264 +msgid "Box" +msgstr "Ohraničenie" + +#: ../../po/../src/dialogs/display-settings.cpp:265 +msgid "Each selected object displays its bounding box" +msgstr "Každý zvolený objekt zobrazí svoje ohraničenie" + +#: ../../po/../src/dialogs/display-settings.cpp:270 +msgid "Default scale origin:" +msgstr "Å tandardná počiatočná mierka:" + +#: ../../po/../src/dialogs/display-settings.cpp:281 +msgid "Opposite bounding box edge" +msgstr "Hrana protiľahlého ohraničenia" + +#: ../../po/../src/dialogs/display-settings.cpp:282 +msgid "Default scale origin will be on the bounding box of the item" +msgstr "Å tandardná počiatočná mierka bude na ohraničení položky" + +#: ../../po/../src/dialogs/display-settings.cpp:288 +msgid "Farthest opposite node" +msgstr "Najvzdialenejší protiľahlý uzol" + +#: ../../po/../src/dialogs/display-settings.cpp:289 +msgid "Default scale origin will be on the bounding box of the item's points" +msgstr "Å tandardná počiatočná mierka bude na ohraničení bodov položky" + +#: ../../po/../src/dialogs/display-settings.cpp:341 +msgid "degrees" +msgstr "stup." + +#: ../../po/../src/dialogs/display-settings.cpp:350 +msgid "" +"Rotating with Ctrl pressed snaps every that much degrees; also, pressing " +"[ or ] rotates by this amount" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:407 +msgid "Rotation snaps every:" +msgstr "Krok rotácie:" + +#: ../../po/../src/dialogs/display-settings.cpp:430 +msgid "" +"None: dialogs are treated as regular windows; Normal: dialogs stay on top of " +"document windows; Aggressive: same as Normal but may work better with some " +"window managers." +msgstr "" +"Žiadne: s dialógmi sa zaobchádza ako s bežnými oknami; Normálne: dialógy " +"zostávajú nad oknom dokumentu; Agresívne: rovnako ako pri Normálne, ale pri " +"niektorých správcoch okien môže lepÅ¡ie fungovaÅ¥." + +#: ../../po/../src/dialogs/display-settings.cpp:451 +msgid "Normal" +msgstr "Normálne" + +#: ../../po/../src/dialogs/display-settings.cpp:461 +msgid "Aggressive" +msgstr "Agresívne" + +#: ../../po/../src/dialogs/display-settings.cpp:475 +msgid "Dialogs on top:" +msgstr "Dialógy na vrchu:" + +#: ../../po/../src/dialogs/display-settings.cpp:645 +msgid "Show selection cue" +msgstr "ZobraziÅ¥ označenie výberu" + +#: ../../po/../src/dialogs/display-settings.cpp:646 +msgid "" +"Whether selected objects display a selection cue (the same as in selector)" +msgstr "" +"Či označené objekty budú zobrazovaÅ¥ znak výberu (rovnako ako pri Výbere)" + +#: ../../po/../src/dialogs/display-settings.cpp:657 +#, fuzzy +msgid "Enable gradient editing" +msgstr "Editor prechodov" + +#: ../../po/../src/dialogs/display-settings.cpp:658 +#, fuzzy +msgid "Whether selected objects display gradient editing controls" +msgstr "" +"Či označené objekty budú zobrazovaÅ¥ znak výberu (rovnako ako pri Výbere)" + +#: ../../po/../src/dialogs/display-settings.cpp:719 +msgid "No objects selected to take the style from." +msgstr "Neboli zvolené objekty, z ktorých sa ma vziaÅ¥ Å¡týl." + +#: ../../po/../src/dialogs/display-settings.cpp:728 +msgid "" +"More than one object selected. Cannot take style from multiple " +"objects." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:767 +msgid "Create new objects with:" +msgstr "VytvoriÅ¥ nové objekty s:" + +#: ../../po/../src/dialogs/display-settings.cpp:777 +msgid "Take from selection" +msgstr "ZobraÅ¥ z výberu" + +#: ../../po/../src/dialogs/display-settings.cpp:778 +msgid "Remember the style of the (first) selected object as this tool's style" +msgstr "PamätaÅ¥ si Å¡týl (prvého) zvoleného objektu ako Å¡týl tohoto nástroja" + +#: ../../po/../src/dialogs/display-settings.cpp:782 +#, fuzzy +msgid "Last used style" +msgstr "VložiÅ¥ Å¡_týl" + +#: ../../po/../src/dialogs/display-settings.cpp:782 +msgid "Apply the style you last set on an object" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:790 +msgid "This tool's own style:" +msgstr "Vlastný Å¡týl tohoto nástroja:" + +#: ../../po/../src/dialogs/display-settings.cpp:790 +msgid "" +"Each tool may store its own style to apply to the newly created objects. Use " +"the button below to set it." +msgstr "" +"Každý nastroj môže uložiÅ¥ svoj vlastný Å¡týl pre použitie na nové objekty. " +"Tlačtítkom dole ho nastavíte." + +#. Mouse +#: ../../po/../src/dialogs/display-settings.cpp:877 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:55 +msgid "Mouse" +msgstr "MyÅ¡" + +#. TRANSLATORS: "Grab" is a noun here. "Grab sensitivity" is intended to mean how +#. * close on the screen you need to be to an object to be able to grab it with mouse (in +#. * pixels). +#: ../../po/../src/dialogs/display-settings.cpp:883 +msgid "Grab sensitivity:" +msgstr "CitlivosÅ¥ zachytenia:" + +#: ../../po/../src/dialogs/display-settings.cpp:884 +#, fuzzy +msgid "" +"How close on the screen you need to be to an object to be able to grab it " +"with mouse (in screen pixels)" +msgstr "" +"Ako blízko na obrazovke musíte byÅ¥, aby ste boli schopný zachytiÅ¥ objekt " +"myÅ¡ou (v bodoch)" + +#: ../../po/../src/dialogs/display-settings.cpp:885 +#: ../../po/../src/dialogs/display-settings.cpp:897 +#: ../../po/../src/dialogs/display-settings.cpp:912 +#: ../../po/../src/dialogs/display-settings.cpp:930 +#: ../../po/../src/dialogs/display-settings.cpp:970 +msgid "pixels" +msgstr "bodov" + +#: ../../po/../src/dialogs/display-settings.cpp:895 +msgid "Click/drag threshold:" +msgstr "Prah kliknutia/Å¥ahania:" + +#: ../../po/../src/dialogs/display-settings.cpp:896 +msgid "" +"Maximum mouse drag (in screen pixels) which is considered a click, not a drag" +msgstr "" +"Maximálne Å¥ahanie myÅ¡ou, (v bodoch), ktoré je považované za kliknutie a nie " +"za Å¥ahanie" + +#. Scrolling +#: ../../po/../src/dialogs/display-settings.cpp:907 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:56 +msgid "Scrolling" +msgstr "Posúvanie" + +#: ../../po/../src/dialogs/display-settings.cpp:910 +msgid "Mouse wheel scrolls by:" +msgstr "Koliesko myÅ¡i posúva o:" + +#: ../../po/../src/dialogs/display-settings.cpp:911 +msgid "" +"One mouse wheel notch scrolls by this distance in screen pixels " +"(horizontally with Shift)" +msgstr "" +"Jeden pohyb kolieskom myÅ¡i posunie o túto vzdialenosÅ¥ v bodoch (vodorovne s " +"klávesom Shift)" + +#: ../../po/../src/dialogs/display-settings.cpp:920 +msgid "Ctrl+arrows" +msgstr "Ctrl+šípky" + +#: ../../po/../src/dialogs/display-settings.cpp:928 +msgid "Scroll by:" +msgstr "Posun o:" + +#: ../../po/../src/dialogs/display-settings.cpp:929 +#, fuzzy +msgid "Pressing Ctrl+arrow key scrolls by this distance (in screen pixels)" +msgstr "Stlačením Ctrl+šípok posuniete o túto vzdialenosÅ¥ (v bodoch)" + +#: ../../po/../src/dialogs/display-settings.cpp:939 +msgid "Acceleration:" +msgstr "Akcelerácia:" + +#: ../../po/../src/dialogs/display-settings.cpp:940 +msgid "" +"Pressing and holding Ctrl+arrow will gradually speed up scrolling (0 for no " +"acceleration)" +msgstr "" +"Stlačením a držaním Ctrl+šípok pozvoľna zvýšite rýchlosÅ¥ posunu (0 znamená " +"žiadne zrýchlenie)" + +#: ../../po/../src/dialogs/display-settings.cpp:949 +msgid "Autoscrolling" +msgstr "Automatické posúvanie" + +#: ../../po/../src/dialogs/display-settings.cpp:957 +msgid "Speed:" +msgstr "RýchlosÅ¥:" + +#: ../../po/../src/dialogs/display-settings.cpp:958 +msgid "" +"How fast the canvas autoscrolls when you drag beyond canvas edge (0 to turn " +"autoscroll off)" +msgstr "" +"Ako rýchlo sa bude posúvaÅ¥ plátno, keď budete Å¥ahaÅ¥ za okraj plátna (0 vypne " +"autmatické posúvanie)" + +#: ../../po/../src/dialogs/display-settings.cpp:968 +#: ../../po/../src/ui/dialog/tracedialog.cpp:357 +#: ../../po/../src/ui/dialog/tracedialog.cpp:390 +msgid "Threshold:" +msgstr "Prah:" + +#: ../../po/../src/dialogs/display-settings.cpp:969 +#, fuzzy +msgid "" +"How far (in screen pixels) you need to be from the canvas edge to trigger " +"autoscroll; positive is outside the canvas, negative is within the canvas" +msgstr "" +"Ako ďaleko (v bodoch) musíte byÅ¥ od okraju plátna, aby sa sputilo " +"automatické posúvanie; pozitívna hodnota je mimo plátna, negatívna je vo " +"vnútry plátna" + +#. Steps +#: ../../po/../src/dialogs/display-settings.cpp:979 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:57 +msgid "Steps" +msgstr "Kroky" + +#: ../../po/../src/dialogs/display-settings.cpp:982 +msgid "Arrow keys move by:" +msgstr "Šípky (klávesy) posunú o:" + +#: ../../po/../src/dialogs/display-settings.cpp:983 +#, fuzzy +msgid "" +"Pressing an arrow key moves selected object(s) or node(s) by this distance " +"(in px units)" +msgstr "" +"Stlačením šípiek (na klávesnici) posunie označené objekty alebo uzly o túto " +"vzdialenosÅ¥ (v bodoch)" + +#: ../../po/../src/dialogs/display-settings.cpp:984 +#: ../../po/../src/dialogs/display-settings.cpp:995 +#: ../../po/../src/dialogs/display-settings.cpp:1006 +#: ../../po/../src/helper/units.cpp:42 +msgid "px" +msgstr "bd" + +#: ../../po/../src/dialogs/display-settings.cpp:993 +msgid "> and < scale by:" +msgstr "> a < zmenia o:" + +#: ../../po/../src/dialogs/display-settings.cpp:994 +#, fuzzy +msgid "" +"Pressing > or < scales selection up or down by this increment (in px units)" +msgstr "" +"Stlačením > alebo < zmenšíte/zväčšíte výber o takýto prírastok (v bodoch)" + +#: ../../po/../src/dialogs/display-settings.cpp:1004 +msgid "Inset/Outset by:" +msgstr "Posun dnu/von o:" + +#: ../../po/../src/dialogs/display-settings.cpp:1005 +#, fuzzy +msgid "" +"Inset and Outset commands displace the path by this distance (in px units)" +msgstr "" +"Príkazy Posun dnu a Posun von posunú cestu o takúto vzdialenosÅ¥ (v bodoch)" + +#: ../../po/../src/dialogs/display-settings.cpp:1017 +msgid "Compass-like display of angles" +msgstr "" + +#. TRANSLATORS: "positive clockwise" means "increasing in clockwise direction" +#: ../../po/../src/dialogs/display-settings.cpp:1019 +msgid "" +"When on, angles are displayed with 0 at north, 0 to 360 range, positive " +"clockwise; otherwise with 0 at east, -180 to 180 range, positive " +"counterclockwise" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1026 +msgid "Zoom in/out by:" +msgstr "ZväčšiÅ¥/ZmenÅ¡iÅ¥ o:" + +#: ../../po/../src/dialogs/display-settings.cpp:1027 +msgid "" +"Zoom tool click, +/- keys, and middle click zoom in and out by this " +"multiplier" +msgstr "" +"Klinutie nástoja Zmena zobrazenia, klávesy +/-, kliknutie stredným tlačítkom " +"menia zobrazenie o takýto násobok" + +#: ../../po/../src/dialogs/display-settings.cpp:1028 +#: ../../po/../src/helper/units.cpp:44 +msgid "%" +msgstr "%" + +#. Tools +#: ../../po/../src/dialogs/display-settings.cpp:1037 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:58 +msgid "Tools" +msgstr "Nástroje" + +#: ../../po/../src/dialogs/display-settings.cpp:1045 +msgid "Selector" +msgstr "Výber" + +#: ../../po/../src/dialogs/display-settings.cpp:1056 +msgid "Node" +msgstr "Uzol" + +#: ../../po/../src/dialogs/display-settings.cpp:1064 +#: ../../po/../src/verbs.cpp:2073 +#: ../../po/../src/widgets/desktop-widget.cpp:277 +msgid "Zoom" +msgstr "Lupa" + +#. The 4 shape tools +#: ../../po/../src/dialogs/display-settings.cpp:1071 +msgid "Shapes" +msgstr "Tvary" + +#: ../../po/../src/dialogs/display-settings.cpp:1079 +#: ../../po/../src/verbs.cpp:2055 +msgid "Rectangle" +msgstr "Obdĺžnik" + +#: ../../po/../src/dialogs/display-settings.cpp:1085 +#: ../../po/../src/verbs.cpp:2057 +msgid "Ellipse" +msgstr "Elipsa" + +#: ../../po/../src/dialogs/display-settings.cpp:1091 +#: ../../po/../src/verbs.cpp:2059 +msgid "Star" +msgstr "Hviezda" + +#: ../../po/../src/dialogs/display-settings.cpp:1097 +#: ../../po/../src/verbs.cpp:2061 +msgid "Spiral" +msgstr "Å pirála" + +#: ../../po/../src/dialogs/display-settings.cpp:1111 +#: ../../po/../src/verbs.cpp:2063 +msgid "Pencil" +msgstr "Ceruzka" + +#: ../../po/../src/dialogs/display-settings.cpp:1114 +msgid "Tolerance:" +msgstr "Tolerancia:" + +#: ../../po/../src/dialogs/display-settings.cpp:1115 +msgid "" +"This value affects the amount of smoothing applied to freehand lines; lower " +"values produce more uneven paths with more nodes" +msgstr "" +"Táto hodnota vyjaduje hodnotu zjemnenia použitého na kreslenie čiar voľnou " +"rukou; nižšia hodnota vyprodukuje viac nerovnú čiaru s väčší počtom uzlov" + +#: ../../po/../src/dialogs/display-settings.cpp:1131 +#: ../../po/../src/verbs.cpp:2065 +msgid "Pen" +msgstr "Pero" + +#: ../../po/../src/dialogs/display-settings.cpp:1140 +#: ../../po/../src/verbs.cpp:2067 +msgid "Calligraphy" +msgstr "Kaligrafická čiara" + +#: ../../po/../src/dialogs/display-settings.cpp:1147 +#: ../../po/../src/dialogs/text-edit.cpp:353 +#: ../../po/../src/ui/dialog/text-properties.cpp:37 +#: ../../po/../src/verbs.cpp:2069 +msgid "Text" +msgstr "Text" + +#: ../../po/../src/dialogs/display-settings.cpp:1157 +#: ../../po/../src/verbs.cpp:2071 +#, fuzzy +msgid "Gradient" +msgstr "Editor prechodov" + +#: ../../po/../src/dialogs/display-settings.cpp:1164 +#: ../../po/../src/verbs.cpp:2077 +#, fuzzy +msgid "Connector" +msgstr "Rohy:" + +#: ../../po/../src/dialogs/display-settings.cpp:1171 +#: ../../po/../src/verbs.cpp:2075 +msgid "Dropper" +msgstr "Pipeta" + +#. Windows +#: ../../po/../src/dialogs/display-settings.cpp:1183 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:59 +msgid "Windows" +msgstr "Okná" + +#: ../../po/../src/dialogs/display-settings.cpp:1188 +msgid "Save window geometry" +msgstr "UložiÅ¥ geometriu okien" + +#: ../../po/../src/dialogs/display-settings.cpp:1189 +msgid "" +"Save the window size and position with each document (only for Inkscape SVG " +"format)" +msgstr "" +"Uloží veľkosÅ¥ okien a pozíciu s každým dokumentom (iba pre Inkscape SVG " +"formát)" + +#: ../../po/../src/dialogs/display-settings.cpp:1196 +msgid "Dialogs are hidden in taskbar" +msgstr "Dialógy sú skryté v panely úloh" + +#: ../../po/../src/dialogs/display-settings.cpp:1197 +msgid "Whether dialog windows are to be hidden in the window manager taskbar" +msgstr "Či je možné okná dialógov skryÅ¥ v pracovných úlohách správcu okien" + +#: ../../po/../src/dialogs/display-settings.cpp:1204 +msgid "Zoom when window is resized" +msgstr "Zmena veľkosti zobrazenia pri zmene veľkosti okna" + +#: ../../po/../src/dialogs/display-settings.cpp:1205 +msgid "" +"Zoom drawing when document window is resized, to keep the same area visible " +"(this is the default which can be changed in any window using the button " +"above the right scrollbar)" +msgstr "" +"ZmeniÅ¥ veľkosÅ¥ zobrazenia kresby, keď sa zmení dokument okna, aby zostala " +"zobrazená rovnaká oblasÅ¥ (toto je Å¡tandard, ktorý je možné zmeniÅ¥ v " +"ktoromkoľvek okne pomocou lupy nad posuvníkmi)" + +#. Clones +#: ../../po/../src/dialogs/display-settings.cpp:1213 +#: ../../po/../src/dialogs/find.cpp:624 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:60 +msgid "Clones" +msgstr "Klony" + +#: ../../po/../src/dialogs/display-settings.cpp:1217 +#, fuzzy +msgid "When the original moves, its clones and linked offsets:" +msgstr "Keď sa posunie originál, jeho klony:" + +#: ../../po/../src/dialogs/display-settings.cpp:1229 +msgid "Move in parallel" +msgstr "sa posúvajú paralelne" + +#: ../../po/../src/dialogs/display-settings.cpp:1230 +msgid "Clones are translated by the same vector as their original." +msgstr "Klony sú preložené rovnakým vektorom ako ich originál." + +#: ../../po/../src/dialogs/display-settings.cpp:1237 +msgid "Stay unmoved" +msgstr "zostanú nepohnuté" + +#: ../../po/../src/dialogs/display-settings.cpp:1238 +msgid "Clones preserve their positions when their original is moved." +msgstr "Klony si zachovajú svoju pozíciu, keď sa originál premiestni." + +#: ../../po/../src/dialogs/display-settings.cpp:1245 +msgid "Move according to transform" +msgstr "sa posúvajú podľa transformácie" + +#: ../../po/../src/dialogs/display-settings.cpp:1246 +msgid "" +"Each clone moves according to the value of its transform= attribute. For " +"example, a rotated clone will move in a different direction than its " +"original." +msgstr "" +"Každý klon sa posúva podľa hodnoty jeho atribútu transform=. Napríklad " +"otočený klon sa posunie iným smerom ako jeho originál." + +#: ../../po/../src/dialogs/display-settings.cpp:1255 +msgid "When the original is deleted, its clones:" +msgstr "Keď je originál zmazaný, jeho klony:" + +#: ../../po/../src/dialogs/display-settings.cpp:1267 +msgid "Are unlinked" +msgstr "sa odpoja" + +#: ../../po/../src/dialogs/display-settings.cpp:1267 +msgid "Orphaned clones are converted to regular objects." +msgstr "Osirotené klony sa skonvertujú na regulárne objekty." + +#: ../../po/../src/dialogs/display-settings.cpp:1273 +msgid "Are deleted" +msgstr "sú zmazané" + +#: ../../po/../src/dialogs/display-settings.cpp:1273 +msgid "Orphaned clones are deleted along with their original." +msgstr "Osirotené klony sú odstránené spolu so svojim originálom." + +#. Transforms +#. TRANSLATORS: Noun, i.e. transformations. +#: ../../po/../src/dialogs/display-settings.cpp:1289 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:61 +msgid "Transforms" +msgstr "Transformácie" + +#: ../../po/../src/dialogs/display-settings.cpp:1292 +msgid "Scale stroke width" +msgstr "ZmeniÅ¥ mierku šírky Å¥ahu" + +#: ../../po/../src/dialogs/display-settings.cpp:1293 +#: ../../po/../src/widgets/select-toolbar.cpp:568 +msgid "When scaling objects, scale the stroke width by the same proportion" +msgstr "Keď sa mení mierka objektov, rovnakou mierou sa mení aj šírka Å¥ahu" + +#: ../../po/../src/dialogs/display-settings.cpp:1300 +msgid "Scale rounded corners in rectangles" +msgstr "ZmeniÅ¥ mierku zaoblených rohov v pravouhloníkoch" + +#: ../../po/../src/dialogs/display-settings.cpp:1301 +#: ../../po/../src/widgets/select-toolbar.cpp:580 +msgid "When scaling rectangles, scale the radii of rounded corners" +msgstr "" +"Keď sa mení mierka pravouholníkov, rovnakou mierou sa mení aj polomer " +"zaokrúhlenia rohov" + +#: ../../po/../src/dialogs/display-settings.cpp:1308 +msgid "Transform gradients" +msgstr "Transformácia prechodov" + +#: ../../po/../src/dialogs/display-settings.cpp:1309 +#: ../../po/../src/widgets/select-toolbar.cpp:592 +msgid "Transform gradients (in fill or stroke) along with the objects" +msgstr "Trasformuje prechody (vo výplni a Å¥ahu) spolu s objektami" + +#: ../../po/../src/dialogs/display-settings.cpp:1316 +msgid "Transform patterns" +msgstr "Transformácia vzoriek" + +#: ../../po/../src/dialogs/display-settings.cpp:1317 +#: ../../po/../src/widgets/select-toolbar.cpp:604 +msgid "Transform patterns (in fill or stroke) along with the objects" +msgstr "Trasformuje vzorky (vo výplni a Å¥ahu) spolu s objektami" + +#. TRANSLATORS: How to specify the affine transformation in the SVG file. +#: ../../po/../src/dialogs/display-settings.cpp:1327 +msgid "Store transformation:" +msgstr "UložiÅ¥ transformáciu:" + +#: ../../po/../src/dialogs/display-settings.cpp:1338 +msgid "Optimized" +msgstr "Optimalizovane" + +#: ../../po/../src/dialogs/display-settings.cpp:1339 +msgid "" +"If possible, apply transformation to objects without adding a transform= " +"attribute" +msgstr "" +"Ak je možné, tak použiÅ¥ transformáciu na objekt bez pridania atribútu " +"transform=" + +#: ../../po/../src/dialogs/display-settings.cpp:1346 +msgid "Preserved" +msgstr "Zabezpečene" + +#: ../../po/../src/dialogs/display-settings.cpp:1347 +msgid "Always store transformation as a transform= attribute on objects" +msgstr "Vždy uložiÅ¥ transformáciu ako atribút objektu transform=" + +#. Selecting +#: ../../po/../src/dialogs/display-settings.cpp:1355 +msgid "Selecting" +msgstr "Výber" + +#: ../../po/../src/dialogs/display-settings.cpp:1357 +msgid "Ctrl+A, Tab, Shift+Tab:" +msgstr "Ctrl+A, Tab, Shift+Tab:" + +#: ../../po/../src/dialogs/display-settings.cpp:1366 +msgid "Select only within current layer" +msgstr "VyberaÅ¥ len v aktuálnej vrstve" + +#: ../../po/../src/dialogs/display-settings.cpp:1367 +msgid "" +"Uncheck this to make keyboard selection commands work on objects in all " +"layers" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1374 +msgid "Ignore hidden objects" +msgstr "IgnorovaÅ¥ skryté objekty" + +#: ../../po/../src/dialogs/display-settings.cpp:1375 +msgid "" +"Uncheck this to be able to select objects that are hidden (either by " +"themselves or by being in a hidden group or layer)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1382 +msgid "Ignore locked objects" +msgstr "IgnorovaÅ¥ zamknuté objekty" + +#: ../../po/../src/dialogs/display-settings.cpp:1383 +msgid "" +"Uncheck this to be able to select objects that are locked (either by " +"themselves or by being in a locked group or layer)" +msgstr "" + +#. To be broken into: Display, Save, Export, SVG, Commands +#: ../../po/../src/dialogs/display-settings.cpp:1391 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:62 +msgid "Misc" +msgstr "Rôzne" + +#: ../../po/../src/dialogs/display-settings.cpp:1394 +msgid "Default export resolution:" +msgstr "Å tandardné exportné rozlíšenie:" + +#: ../../po/../src/dialogs/display-settings.cpp:1395 +msgid "Default bitmap resolution (in dots per inch) in the Export dialog" +msgstr "Å tandardné rozlíšenie bitmapy (v bodoch na palec) v exportnom dialógu" + +#. FIXME: add "Used for new exports; once exported, documents remember this value on per-object basis" when implemented +#: ../../po/../src/dialogs/display-settings.cpp:1396 +#: ../../po/../src/dialogs/export.cpp:442 +msgid "dpi" +msgstr "dpi" + +#. TRANSLATORS: When on, an imported bitmap creates an element; otherwise it is a +#. * rectangle with bitmap fill. +#: ../../po/../src/dialogs/display-settings.cpp:1407 +msgid "Import bitmap as " +msgstr "ImportovaÅ¥ bitmapu ako " + +#: ../../po/../src/dialogs/display-settings.cpp:1408 +msgid "" +"When on, an imported bitmap creates an element; otherwise it is a " +"rectangle with bitmap fill" +msgstr "" +"Keď je zapnuté, tak importovaná bitmapa vytvorí prvok ; inak sa " +"vytvorí pravouholník s bitmapovou výplňou" + +#. TRANSLATORS: When on, the print out (currently Postscript) will have +#. * a comment with the each object's label visible, marking the section +#. * of the printing commands that represent the given object. +#: ../../po/../src/dialogs/display-settings.cpp:1418 +msgid "Add label comments to printing output" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1419 +msgid "" +"When on, a comment will be added to the raw print output, marking the " +"rendered output for an object with its label" +msgstr "" + +#. TRANSLATORS: When on, enable the effects menu, default is off +#: ../../po/../src/dialogs/display-settings.cpp:1427 +msgid "Enable script effects (requires restart) - EXPERIMENTAL" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1428 +msgid "" +"When on, the effects menu is enabled, allowing external effect scripts to be " +"called, requires restart before effective - EXPERIMENTAL" +msgstr "" + +#. TRANSLATORS: The maximum length of the Open Recent list in the File menu. +#: ../../po/../src/dialogs/display-settings.cpp:1436 +msgid "Max recent documents:" +msgstr "Maximum posledných dokumentov:" + +#: ../../po/../src/dialogs/display-settings.cpp:1437 +msgid "The maximum length of the Open Recent list in the File menu" +msgstr "Maximálna dĺžka zoznamu napsledy otvorených súborov v ponuke" + +#: ../../po/../src/dialogs/display-settings.cpp:1447 +msgid "Simplification threshold:" +msgstr "Prah zjednoduÅ¡enia" + +#: ../../po/../src/dialogs/display-settings.cpp:1448 +msgid "" +"How strong is the Simplify command by default. If you invoke this command " +"several times in quick succession, it will act more and more aggressively; " +"invoking it again after a pause restores the default threshold." +msgstr "" +"Ako silný je Å¡tandardne príkaz ZjednoduÅ¡enie. Ak vyvoláte tento príkaz " +"niekoľko krát rýchlo za sebou, bude sa správaÅ¥ viac a viac agresívne; " +"vyvolanie po pauze obnoví Å¡tandardný prah." + +#: ../../po/../src/dialogs/display-settings.cpp:1469 +msgid "Oversample bitmaps:" +msgstr "Prevzorkovanie bitmáp:" + +#: ../../po/../src/dialogs/display-settings.cpp:1488 +msgid "2x2" +msgstr "2x2" + +#: ../../po/../src/dialogs/display-settings.cpp:1494 +msgid "4x4" +msgstr "4x4" + +#: ../../po/../src/dialogs/display-settings.cpp:1500 +msgid "8x8" +msgstr "8x8" + +#: ../../po/../src/dialogs/display-settings.cpp:1506 +msgid "16x16" +msgstr "16x16" + +#. "view_icon_preview" +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2143 +msgid "_Page" +msgstr "_Stránka" + +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2147 +msgid "_Drawing" +msgstr "_Kresba" + +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2149 +msgid "_Selection" +msgstr "_Výber" + +#: ../../po/../src/dialogs/export.cpp:133 +#, fuzzy +msgid "_Custom" +msgstr "Vlastné" + +#: ../../po/../src/dialogs/export.cpp:254 +msgid "Export area" +msgstr "ExportovaÅ¥ oblasÅ¥" + +#: ../../po/../src/dialogs/export.cpp:300 +#, fuzzy +msgid "_x0:" +msgstr "x0:" + +#: ../../po/../src/dialogs/export.cpp:305 +#, fuzzy +msgid "x_1:" +msgstr "x1:" + +#: ../../po/../src/dialogs/export.cpp:316 +#, fuzzy +msgid "_y0:" +msgstr "y0:" + +#: ../../po/../src/dialogs/export.cpp:321 +#, fuzzy +msgid "y_1:" +msgstr "y1:" + +#: ../../po/../src/dialogs/export.cpp:406 +msgid "Bitmap size" +msgstr "VeľkosÅ¥ bitmapy" + +#: ../../po/../src/dialogs/export.cpp:416 +#, fuzzy +msgid "_Width:" +msgstr "Šírka:" + +#: ../../po/../src/dialogs/export.cpp:416 +#: ../../po/../src/dialogs/export.cpp:431 +#, fuzzy +msgid "pixels at" +msgstr "bodov" + +#: ../../po/../src/dialogs/export.cpp:426 +#, fuzzy +msgid "dp_i" +msgstr "dpi" + +#: ../../po/../src/dialogs/export.cpp:448 +#, fuzzy +msgid "_Filename" +msgstr "Názov súboru" + +#: ../../po/../src/dialogs/export.cpp:512 +#, fuzzy +msgid "_Browse..." +msgstr "PrezeraÅ¥..." + +#: ../../po/../src/dialogs/export.cpp:539 +#, fuzzy +msgid " _Export " +msgstr " _VytvoriÅ¥ " + +#: ../../po/../src/dialogs/export.cpp:541 +msgid "Export the bitmap file with these settings" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:968 +msgid "You have to enter a filename" +msgstr "Musíte vložiÅ¥ názov súboru." + +#: ../../po/../src/dialogs/export.cpp:973 +msgid "The chosen area to be exported is invalid" +msgstr "Zvolená oblasÅ¥ pre export nie je platná" + +#: ../../po/../src/dialogs/export.cpp:982 +#, c-format +msgid "Directory %s does not exist or is not a directory.\n" +msgstr "Prečinok %s neexistuje alebo nie je priečinok.\n" + +#: ../../po/../src/dialogs/export.cpp:998 +msgid "Export in progress" +msgstr "Vykonáva sa export" + +#: ../../po/../src/dialogs/export.cpp:1004 +#, fuzzy, c-format +msgid "Exporting %s (%d x %d)" +msgstr "Exportovanie [%d x %d] %s" + +#: ../../po/../src/dialogs/export.cpp:1031 +#, fuzzy, c-format +msgid "Could not export to filename %s.\n" +msgstr "Nepodarilo sa pripojiÅ¥ k hostiteľovi." + +#: ../../po/../src/dialogs/export.cpp:1137 +msgid "Select a filename for exporting" +msgstr "Voľba súboru pre export" + +#: ../../po/../src/dialogs/filedialog.cpp:367 +msgid "No preview" +msgstr "Bez náhľadu" + +#: ../../po/../src/dialogs/filedialog.cpp:468 +msgid "too large for preview" +msgstr "príliÅ¡ veľké pre náhľad" + +#: ../../po/../src/dialogs/filedialog.cpp:762 +#: ../../po/../src/dialogs/filedialog.cpp:763 +msgid "All Images" +msgstr "VÅ¡etky obrázky" + +#: ../../po/../src/dialogs/filedialog.cpp:767 +#: ../../po/../src/dialogs/filedialog.cpp:768 +msgid "All Files" +msgstr "VÅ¡etky súbory" + +#: ../../po/../src/dialogs/filedialog.cpp:774 +#: ../../po/../src/dialogs/filedialog.cpp:775 +msgid "All Inkscape Files" +msgstr "VÅ¡etky Inkscape súbory" + +#: ../../po/../src/dialogs/filedialog.cpp:1176 +msgid "Guess from extension" +msgstr "Odhadnúť podľa prípony" + +#. ###### Add the file types menu +#. createFilterMenu(); +#. ###### Do we want the .xxx extension automatically added? +#: ../../po/../src/dialogs/filedialog.cpp:1261 +msgid "Append filename extension automatically" +msgstr "Automatické pripojenie prípony" + +#. TRANSLATORS: "%s" is replaced with "exact" or "partial" when this string is displayed +#: ../../po/../src/dialogs/find.cpp:378 +#, fuzzy, c-format +msgid "%d object found (out of %d), %s match." +msgid_plural "%d objects found (out of %d), %s match." +msgstr[0] "Nájdena jedna približná položka" +msgstr[1] "%d objektov nájdených (z %d), %s zhodných." +msgstr[2] "%d objektov nájdených (z %d), %s zhodných." + +#: ../../po/../src/dialogs/find.cpp:381 +msgid "exact" +msgstr "presne" + +#: ../../po/../src/dialogs/find.cpp:381 +msgid "partial" +msgstr "čiastočne" + +#: ../../po/../src/dialogs/find.cpp:388 +msgid "No objects found" +msgstr "Bez objektov" + +#: ../../po/../src/dialogs/find.cpp:546 +msgid "T_ype: " +msgstr "T_yp: " + +#: ../../po/../src/dialogs/find.cpp:553 +msgid "Search in all object types" +msgstr "HľadaÅ¥ vo vÅ¡etkých typoch objektov" + +#: ../../po/../src/dialogs/find.cpp:553 +msgid "All types" +msgstr "VÅ¡etky typy" + +#: ../../po/../src/dialogs/find.cpp:564 +msgid "Search all shapes" +msgstr "HľadaÅ¥ vÅ¡etky tvary" + +#: ../../po/../src/dialogs/find.cpp:564 +msgid "All shapes" +msgstr "VÅ¡etkých tvary" + +#: ../../po/../src/dialogs/find.cpp:581 +msgid "Search rectangles" +msgstr "HľadaÅ¥ obdĺžniky" + +#: ../../po/../src/dialogs/find.cpp:581 +msgid "Rectangles" +msgstr "Obdĺžniky" + +#: ../../po/../src/dialogs/find.cpp:586 +msgid "Search ellipses, arcs, circles" +msgstr "HľadaÅ¥ elipsy, oblúky a kruhy" + +#: ../../po/../src/dialogs/find.cpp:586 +msgid "Ellipses" +msgstr "Elipsy" + +#: ../../po/../src/dialogs/find.cpp:591 +msgid "Search stars and polygons" +msgstr "HľadaÅ¥ hviezdy a mnohouholníky" + +#: ../../po/../src/dialogs/find.cpp:591 +msgid "Stars" +msgstr "Hviezdy" + +#: ../../po/../src/dialogs/find.cpp:596 +msgid "Search spirals" +msgstr "HľadaÅ¥ Å¡pirály" + +#: ../../po/../src/dialogs/find.cpp:596 +msgid "Spirals" +msgstr "Å pirály" + +#. TRANSLATORS: polyline is a set of connected straight line segments +#. http://www.w3.org/TR/SVG11/shapes.html#PolylineElement +#: ../../po/../src/dialogs/find.cpp:609 +msgid "Search paths, lines, polylines" +msgstr "HľadaÅ¥ cesty, čiary, viacnásobné čiary" + +#: ../../po/../src/dialogs/find.cpp:609 +msgid "Paths" +msgstr "Cesty" + +#: ../../po/../src/dialogs/find.cpp:614 +msgid "Search text objects" +msgstr "HľadaÅ¥ textové objekty" + +#: ../../po/../src/dialogs/find.cpp:614 +msgid "Texts" +msgstr "Texty" + +#: ../../po/../src/dialogs/find.cpp:619 +msgid "Search groups" +msgstr "HľadaÅ¥ skupiny" + +#: ../../po/../src/dialogs/find.cpp:619 +msgid "Groups" +msgstr "Skupiny" + +#: ../../po/../src/dialogs/find.cpp:624 +msgid "Search clones" +msgstr "HľadaÅ¥ klony" + +#: ../../po/../src/dialogs/find.cpp:629 +msgid "Search images" +msgstr "HľadaÅ¥ obrázky" + +#: ../../po/../src/dialogs/find.cpp:629 +msgid "Images" +msgstr "Obrázok" + +#: ../../po/../src/dialogs/find.cpp:634 +msgid "Search offset objects" +msgstr "HľadaÅ¥ posun objektov" + +#: ../../po/../src/dialogs/find.cpp:634 +msgid "Offsets" +msgstr "Posuny" + +#: ../../po/../src/dialogs/find.cpp:694 +msgid "_Text: " +msgstr "_Text: " + +#: ../../po/../src/dialogs/find.cpp:694 +msgid "Find objects by their text content (exact or partial match)" +msgstr "" +"HľadaÅ¥ objekty podľa ich textového obsahu (presná alebo čiastočná zhoda)" + +#: ../../po/../src/dialogs/find.cpp:695 +msgid "_ID: " +msgstr "_ID: " + +#: ../../po/../src/dialogs/find.cpp:695 +msgid "Find objects by the value of the id attribute (exact or partial match)" +msgstr "Hľadá objekty podľa hodnoty atribútu ID (presná alebo čiastočná zhoda)" + +#: ../../po/../src/dialogs/find.cpp:696 +msgid "_Style: " +msgstr "_Å týl: " + +#: ../../po/../src/dialogs/find.cpp:696 +msgid "" +"Find objects by the value of the style attribute (exact or partial match)" +msgstr "" +"Hľadá objekty podľa hodnoty atribútu Å¡týl (presná alebo čiastočná zhoda)" + +#: ../../po/../src/dialogs/find.cpp:697 +msgid "_Attribute: " +msgstr "_Atribút: " + +#: ../../po/../src/dialogs/find.cpp:697 +msgid "Find objects by the name of an attribute (exact or partial match)" +msgstr "Hľadá objekty podľa názvu atribútu (presná alebo čiastočná zhoda)" + +#: ../../po/../src/dialogs/find.cpp:711 +msgid "Search in s_election" +msgstr "HľadaÅ¥ vo výb_ere" + +#: ../../po/../src/dialogs/find.cpp:715 +msgid "Limit search to the current selection" +msgstr "ObmedziÅ¥ vyhľadávanie na aktuálny výber" + +#: ../../po/../src/dialogs/find.cpp:720 +msgid "Search in current _layer" +msgstr "HľadaÅ¥ v aktuálnej vrstve" + +#: ../../po/../src/dialogs/find.cpp:724 +#, fuzzy +msgid "Limit search to the current layer" +msgstr "OmbedziÅ¥ vyhľadávanie na aktuálny výber" + +#: ../../po/../src/dialogs/find.cpp:729 +msgid "Include _hidden" +msgstr "Vrátane skrytých" + +#: ../../po/../src/dialogs/find.cpp:733 +msgid "Include hidden objects in search" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:738 +msgid "Include l_ocked" +msgstr "Vrátane uzamknutých" + +#: ../../po/../src/dialogs/find.cpp:742 +#, fuzzy +msgid "Include locked objects in search" +msgstr "Zvolené objekty" + +#: ../../po/../src/dialogs/find.cpp:753 +msgid "Clear values" +msgstr "VymazaÅ¥ hodnoty" + +#: ../../po/../src/dialogs/find.cpp:754 +msgid "_Find" +msgstr "_HľadaÅ¥" + +#: ../../po/../src/dialogs/find.cpp:754 +msgid "Select objects matching all of the fields you filled in" +msgstr "Vyberie objekty, ktoré zodpovedajú vÅ¡etkým poliam, ktoré ste vyplnili." + +#: ../../po/../src/dialogs/iconpreview.cpp:145 +#, c-format +msgid "%d x %d" +msgstr "" + +#: ../../po/../src/dialogs/iconpreview.cpp:193 +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:857 +#: ../../po/../src/widgets/desktop-widget.cpp:1069 +msgid "Selection" +msgstr "Výber" + +#: ../../po/../src/dialogs/iconpreview.cpp:195 +#, fuzzy +msgid "Selection only or whole document" +msgstr "VyberaÅ¥ len v aktuálnej vrstve" + +#: ../../po/../src/dialogs/iconpreview.cpp:203 +msgid "Refresh the icons" +msgstr "" + +#. Create the label for the object id +#: ../../po/../src/dialogs/item-properties.cpp:126 +#: ../../po/../src/dialogs/item-properties.cpp:327 +#: ../../po/../src/dialogs/item-properties.cpp:396 +#: ../../po/../src/dialogs/item-properties.cpp:403 +#, fuzzy +msgid "_Id" +msgstr "ID" + +#: ../../po/../src/dialogs/item-properties.cpp:135 +msgid "" +"The id= attribute (only letters, digits, and the characters .-_: allowed)" +msgstr "" + +#. Button for setting the object's id, label, title and description. +#: ../../po/../src/dialogs/item-properties.cpp:149 +#, fuzzy +msgid "_Set" +msgstr "NastaviÅ¥" + +#. Create the label for the object label +#: ../../po/../src/dialogs/item-properties.cpp:158 +#, fuzzy +msgid "_Label" +msgstr "Popis" + +#: ../../po/../src/dialogs/item-properties.cpp:167 +#, fuzzy +msgid "A freeform label for the object" +msgstr "Ikona použitá pre tlačidlo objektu" + +#. Create the label for the object title +#: ../../po/../src/dialogs/item-properties.cpp:179 +#: ../../po/../src/dialogs/rdf.cpp:243 +msgid "Title" +msgstr "Titulok" + +#. Create the frame for the object description +#: ../../po/../src/dialogs/item-properties.cpp:196 +#: ../../po/../src/dialogs/rdf.cpp:287 +msgid "Description" +msgstr "Popis" + +#. Hide +#: ../../po/../src/dialogs/item-properties.cpp:223 +#, fuzzy +msgid "_Hide" +msgstr "SkryÅ¥" + +#: ../../po/../src/dialogs/item-properties.cpp:224 +msgid "Check to make the object invisible" +msgstr "" + +#. Lock +#. TRANSLATORS: "Lock" is a verb here +#: ../../po/../src/dialogs/item-properties.cpp:233 +#, fuzzy +msgid "L_ock" +msgstr "Zamknúť" + +#: ../../po/../src/dialogs/item-properties.cpp:234 +msgid "Check to make the object insensitive (not selectable by mouse)" +msgstr "" + +#: ../../po/../src/dialogs/item-properties.cpp:310 +#: ../../po/../src/dialogs/item-properties.cpp:317 +msgid "Ref" +msgstr "Odkaz" + +#: ../../po/../src/dialogs/item-properties.cpp:398 +#, fuzzy +msgid "Id invalid! " +msgstr "ID neplatné " + +#: ../../po/../src/dialogs/item-properties.cpp:400 +#, fuzzy +msgid "Id exists! " +msgstr "ID existuje" + +#: ../../po/../src/dialogs/layer-properties.cpp:50 +#, fuzzy +msgid "Layer name:" +msgstr "Názov vrstvy:" + +#: ../../po/../src/dialogs/layer-properties.cpp:133 +msgid "Rename Layer" +msgstr "PremenovaÅ¥ vrstvu" + +#: ../../po/../src/dialogs/layer-properties.cpp:136 +msgid "_Rename" +msgstr "Pre_menovaÅ¥" + +#. TRANSLATORS: This means "The layer has been renamed" +#: ../../po/../src/dialogs/layer-properties.cpp:147 +msgid "Renamed layer" +msgstr "PremenovaÅ¥ vrstvu" + +#: ../../po/../src/dialogs/layer-properties.cpp:151 +#, fuzzy +msgid "Add Layer" +msgstr "_Vrstva" + +#: ../../po/../src/dialogs/layer-properties.cpp:153 +#, fuzzy +msgid "_Add" +msgstr "PridaÅ¥" + +#: ../../po/../src/dialogs/layer-properties.cpp:167 +msgid "New layer created." +msgstr "Nová vrstva bola vytvorená." + +#: ../../po/../src/dialogs/object-attributes.cpp:34 +msgid "Href:" +msgstr "Href:" + +#: ../../po/../src/dialogs/object-attributes.cpp:35 +msgid "Target:" +msgstr "Cieľ:" + +#: ../../po/../src/dialogs/object-attributes.cpp:36 +msgid "Type:" +msgstr "Typ:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkRoleAttribute +#. Identifies the type of the related resource with an absolute URI +#: ../../po/../src/dialogs/object-attributes.cpp:39 +msgid "Role:" +msgstr "Rola:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkArcRoleAttribute +#. For situations where the nature/role alone isn't enough, this offers an additional URI defining the purpose of the link. +#: ../../po/../src/dialogs/object-attributes.cpp:42 +msgid "Arcrole:" +msgstr "Arcrole:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkTitleAttribute +#: ../../po/../src/dialogs/object-attributes.cpp:44 +msgid "Title:" +msgstr "Titulok:" + +#: ../../po/../src/dialogs/object-attributes.cpp:45 +msgid "Show:" +msgstr "ZobraziÅ¥:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkActuateAttribute +#: ../../po/../src/dialogs/object-attributes.cpp:47 +msgid "Actuate:" +msgstr "Riadenie:" + +#: ../../po/../src/dialogs/object-attributes.cpp:52 +msgid "URL:" +msgstr "URL:" + +#: ../../po/../src/dialogs/object-attributes.cpp:53 +msgid "X:" +msgstr "X:" + +#: ../../po/../src/dialogs/object-attributes.cpp:54 +msgid "Y:" +msgstr "Y:" + +#: ../../po/../src/dialogs/object-attributes.cpp:98 +#, c-format +msgid "%s attributes" +msgstr "%s atribútov" + +#: ../../po/../src/dialogs/object-properties.cpp:158 +#, fuzzy +msgid "_Fill" +msgstr "Výplň" + +#: ../../po/../src/dialogs/object-properties.cpp:165 +#, fuzzy +msgid "Stroke _paint" +msgstr "Farba Å¥ahu" + +#: ../../po/../src/dialogs/object-properties.cpp:172 +#, fuzzy +msgid "Stroke st_yle" +msgstr "Å týl Å¥ahu" + +#: ../../po/../src/dialogs/object-properties.cpp:183 +#, fuzzy +msgid "Master _opacity" +msgstr "Hlavná nepriesvitnosÅ¥" + +#: ../../po/../src/dialogs/rdf.cpp:244 +msgid "Name by which this document is formally known." +msgstr "Názov, pod ktorým bude dokument formálne známy." + +#: ../../po/../src/dialogs/rdf.cpp:246 +msgid "Date" +msgstr "Dátum" + +#: ../../po/../src/dialogs/rdf.cpp:247 +msgid "Date associated with the creation of this document (YYYY-MM-DD)." +msgstr "Dátum asociovaný s vytvorením dokumentu (RRRR-MM-DD)" + +#: ../../po/../src/dialogs/rdf.cpp:249 +msgid "Format" +msgstr "Formát" + +#: ../../po/../src/dialogs/rdf.cpp:250 +msgid "The physical or digital manifestation of this document (MIME type)." +msgstr "Fyzický alebo digitálny prejav tohoto dokumentu (MIME type)." + +#: ../../po/../src/dialogs/rdf.cpp:252 +msgid "Type" +msgstr "Typ" + +#: ../../po/../src/dialogs/rdf.cpp:253 +msgid "Type of document (DCMI Type)." +msgstr "Typ dokumentu (DCMI typ)" + +#: ../../po/../src/dialogs/rdf.cpp:256 +msgid "Creator" +msgstr "Tvorca" + +#: ../../po/../src/dialogs/rdf.cpp:257 +msgid "" +"Name of entity primarily responsible for making the content of this document." +msgstr "" +"Názov entity primárne zodpovednej za vytvorenie obsahu tohoto dokumentu." + +#: ../../po/../src/dialogs/rdf.cpp:259 +msgid "Rights" +msgstr "Práva" + +#: ../../po/../src/dialogs/rdf.cpp:260 +msgid "" +"Name of entity with rights to the Intellectual Property of this document." +msgstr "" +"Názov entity primárne s právami na Intelektuálne vlastníctvo tohoto " +"dokumentu.." + +#: ../../po/../src/dialogs/rdf.cpp:262 +msgid "Publisher" +msgstr "Vydavateľ" + +#: ../../po/../src/dialogs/rdf.cpp:263 +msgid "Name of entity responsible for making this document available." +msgstr "Názov entity zodpovednej za sprístupnenie tohoto dokumentu." + +#: ../../po/../src/dialogs/rdf.cpp:266 +msgid "Identifier" +msgstr "Identifikátor" + +#: ../../po/../src/dialogs/rdf.cpp:267 +msgid "Unique URI to reference this document." +msgstr "Jedinečné URI odkaz na tento dokument." + +#: ../../po/../src/dialogs/rdf.cpp:269 +msgid "Source" +msgstr "Zdroj" + +#: ../../po/../src/dialogs/rdf.cpp:270 +msgid "Unique URI to reference the source of this document." +msgstr "Jedinečné URI odkaz na zdroj tohoto dokumentu." + +#: ../../po/../src/dialogs/rdf.cpp:272 +msgid "Relation" +msgstr "vzÅ¥ah" + +#: ../../po/../src/dialogs/rdf.cpp:273 +msgid "Unique URI to a related document." +msgstr "Jedinečné URI vzÅ¥ahujúce sa k dokumentu" + +#: ../../po/../src/dialogs/rdf.cpp:275 +msgid "Language" +msgstr "Jazyk" + +#: ../../po/../src/dialogs/rdf.cpp:276 +msgid "" +"Two-letter language tag with optional subtags for the language of this " +"document. (e.g. 'en-GB')" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:278 +msgid "Keywords" +msgstr "Kľúčové slová" + +#: ../../po/../src/dialogs/rdf.cpp:279 +msgid "" +"The topic of this document as comma-separated key words, phrases, or " +"classifications." +msgstr "" + +#. TRANSLATORS: "Coverage": the spatial or temporal characteristics of the content. +#. For info, see Appendix D of http://www.w3.org/TR/1998/WD-rdf-schema-19980409/ +#: ../../po/../src/dialogs/rdf.cpp:283 +msgid "Coverage" +msgstr "Pokrytie" + +#: ../../po/../src/dialogs/rdf.cpp:284 +msgid "Extent or scope of this document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:288 +msgid "A short account of the content of this document." +msgstr "" + +#. FIXME: need to handle 1 agent per line of input +#: ../../po/../src/dialogs/rdf.cpp:292 +msgid "Contributors" +msgstr "Prispievatelia" + +#: ../../po/../src/dialogs/rdf.cpp:293 +msgid "" +"Names of entities responsible for making contributions to the content of " +"this document." +msgstr "" +"Názvy entít zodpovedných za vytvorenie príspevkov do obsahu tohoto dokumentu." + +#. TRANSLATORS: URL to a page that defines the license for the document +#: ../../po/../src/dialogs/rdf.cpp:297 +msgid "URI" +msgstr "URI" + +#. TRANSLATORS: this is where you put a URL to a page that defines the license +#: ../../po/../src/dialogs/rdf.cpp:299 +msgid "URI to this document's license's namespace definition." +msgstr "" + +#. TRANSLATORS: fragment of XML representing the license of the document +#: ../../po/../src/dialogs/rdf.cpp:303 +msgid "Fragment" +msgstr "Fragment" + +#: ../../po/../src/dialogs/rdf.cpp:304 +msgid "XML fragment for the RDF 'License' section." +msgstr "" + +#: ../../po/../src/dialogs/stroke-style.cpp:774 +#: ../../po/../src/widgets/gradient-vector.cpp:263 +#: ../../po/../src/widgets/paint-selector.cpp:751 +msgid "No document selected" +msgstr "Žiadny dokument nebol zvolený" + +#: ../../po/../src/dialogs/stroke-style.cpp:992 +msgid "Stroke width" +msgstr "Šírka Å¥ahu" + +#. Join type +#. TRANSLATORS: The line join style specifies the shape to be used at the +#. corners of paths. It can be "miter", "round" or "bevel". +#: ../../po/../src/dialogs/stroke-style.cpp:1015 +msgid "Join:" +msgstr "Spojnica:" + +#. TRANSLATORS: Miter join: joining lines with a sharp (pointed) corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1027 +msgid "Miter join" +msgstr "Ostrý spoj" + +#. TRANSLATORS: Round join: joining lines with a rounded corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1035 +msgid "Round join" +msgstr "Oblý spoj" + +#. TRANSLATORS: Bevel join: joining lines with a blunted (flattened) corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1043 +msgid "Bevel join" +msgstr "Å ikmý spoj" + +#. Miterlimit +#. TRANSLATORS: Miter limit: only for "miter join", this limits the length +#. of the sharp "spike" when the lines connect at too sharp an angle. +#. When two line segments meet at a sharp angle, a miter join results in a +#. spike that extends well beyond the connection point. The purpose of the +#. miter limit is to cut off such spikes (i.e. convert them into bevels) +#. when they become too long. +#: ../../po/../src/dialogs/stroke-style.cpp:1054 +msgid "Miter limit:" +msgstr "Limit ostré:" + +#: ../../po/../src/dialogs/stroke-style.cpp:1062 +msgid "Maximum length of the miter (in units of stroke width)" +msgstr "" + +#. Cap type +#. TRANSLATORS: cap type specifies the shape for the ends of lines +#: ../../po/../src/dialogs/stroke-style.cpp:1075 +msgid "Cap:" +msgstr "Zakončenie:" + +#. TRANSLATORS: Butt cap: the line shape does not extend beyond the end point +#. of the line; the ends of the line are square +#: ../../po/../src/dialogs/stroke-style.cpp:1086 +msgid "Butt cap" +msgstr "Tupé zakončenie" + +#. TRANSLATORS: Round cap: the line shape extends beyond the end point of the +#. line; the ends of the line are rounded +#: ../../po/../src/dialogs/stroke-style.cpp:1093 +msgid "Round cap" +msgstr "Oblé zakončenie" + +#. TRANSLATORS: Square cap: the line shape extends beyond the end point of the +#. line; the ends of the line are square +#: ../../po/../src/dialogs/stroke-style.cpp:1100 +msgid "Square cap" +msgstr "Å tvorcové zakončenie" + +#. Dash +#: ../../po/../src/dialogs/stroke-style.cpp:1106 +msgid "Dashes:" +msgstr "Čiarky:" + +#. TRANSLATORS: Path markers are an SVG feature that allows you to attach arbitrary shapes +#. (arrowheads, bullets, faces, whatever) to the start, end, or middle nodes of a path. +#: ../../po/../src/dialogs/stroke-style.cpp:1127 +msgid "Start Markers:" +msgstr "Začiatočná značka:" + +#: ../../po/../src/dialogs/stroke-style.cpp:1137 +msgid "Mid Markers:" +msgstr "Stredná značka:" + +#: ../../po/../src/dialogs/stroke-style.cpp:1148 +msgid "End Markers:" +msgstr "Koncová značka:" + +#: ../../po/../src/dialogs/swatches.cpp:424 +#, c-format +msgid "Palettes directory (%s) is unavailable." +msgstr "" + +#. TODO: Insert widgets +#: ../../po/../src/dialogs/text-edit.cpp:199 +#: ../../po/../src/ui/dialog/text-properties.cpp:36 +msgid "Font" +msgstr "Písmo" + +#: ../../po/../src/dialogs/text-edit.cpp:216 +msgid "Layout" +msgstr "Rozloženie" + +#: ../../po/../src/dialogs/text-edit.cpp:229 +msgid "Align lines left" +msgstr "ZarovnaÅ¥ čiary doľava" + +#. TRANSLATORS: `Center' here is a verb. +#: ../../po/../src/dialogs/text-edit.cpp:243 +msgid "Center lines" +msgstr "CentrovaÅ¥ čiary" + +#: ../../po/../src/dialogs/text-edit.cpp:256 +msgid "Align lines right" +msgstr "Zarovnanie čiar doprava" + +#: ../../po/../src/dialogs/text-edit.cpp:278 +msgid "Horizontal text" +msgstr "Vodorovný text" + +#: ../../po/../src/dialogs/text-edit.cpp:292 +msgid "Vertical text" +msgstr "Zvislý text" + +#: ../../po/../src/dialogs/text-edit.cpp:307 +msgid "Line spacing:" +msgstr "Riadkovanie:" + +#: ../../po/../src/dialogs/text-edit.cpp:400 +msgid "Set as default" +msgstr "NastaviÅ¥ ako Å¡tandardné" + +#: ../../po/../src/dialogs/tiledialog.cpp:603 +#, fuzzy +msgid "Rows:" +msgstr "ZobraziÅ¥:" + +#: ../../po/../src/dialogs/tiledialog.cpp:613 +#, fuzzy +msgid "Number of rows" +msgstr "Počet revolúcií" + +#: ../../po/../src/dialogs/tiledialog.cpp:617 +#, fuzzy +msgid "Equal height" +msgstr "Výška:" + +#: ../../po/../src/dialogs/tiledialog.cpp:627 +msgid "If not set, each row has the height of the tallest object in it" +msgstr "" + +#. #### Radio buttons to control vertical alignment #### +#. #### Radio buttons to control horizontal alignment #### +#: ../../po/../src/dialogs/tiledialog.cpp:637 +#: ../../po/../src/dialogs/tiledialog.cpp:708 +#, fuzzy +msgid "Align:" +msgstr "ZarovnaÅ¥" + +#: ../../po/../src/dialogs/tiledialog.cpp:672 +msgid " X " +msgstr "" + +#. #### Number of columns #### +#: ../../po/../src/dialogs/tiledialog.cpp:678 +#, fuzzy +msgid "Columns:" +msgstr "Stĺpce:" + +#: ../../po/../src/dialogs/tiledialog.cpp:688 +#, fuzzy +msgid "Number of columns" +msgstr "Počet revolúcií" + +#: ../../po/../src/dialogs/tiledialog.cpp:692 +#, fuzzy +msgid "Equal width" +msgstr "Šírka:" + +#: ../../po/../src/dialogs/tiledialog.cpp:701 +msgid "If not set, each column has the width of the widest object in it" +msgstr "" + +#. #### Radio buttons to control spacing manually or to fit selection bbox #### +#: ../../po/../src/dialogs/tiledialog.cpp:746 +#, fuzzy +msgid "Fit into selection box" +msgstr "Šírka výberu" + +#: ../../po/../src/dialogs/tiledialog.cpp:753 +#, fuzzy +msgid "Set spacing:" +msgstr "Rozostup Y:" + +#. #### Y Padding #### +#: ../../po/../src/dialogs/tiledialog.cpp:777 +#, fuzzy +msgid "Row spacing: " +msgstr "Riadkovanie:" + +#: ../../po/../src/dialogs/tiledialog.cpp:786 +#, fuzzy +msgid "Vertical spacing between rows" +msgstr "Vertikálne medzery" + +#. #### X padding #### +#: ../../po/../src/dialogs/tiledialog.cpp:795 +#, fuzzy +msgid "Column spacing:" +msgstr "Riadkovanie:" + +#: ../../po/../src/dialogs/tiledialog.cpp:804 +#, fuzzy +msgid "Horizontal spacing between columns" +msgstr "vodorovná hodnota mierky" + +#: ../../po/../src/dialogs/tiledialog.cpp:818 +#, fuzzy +msgid "Arrange selected objects" +msgstr "Zoskupí zvolené objekty" + +#: ../../po/../src/dialogs/xml-tree.cpp:178 +msgid "Click to select nodes, drag to rearrange." +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:189 +#, fuzzy +msgid "Click attribute to edit." +msgstr "Kliknutím vyberte cestu na upravovanie." + +#: ../../po/../src/dialogs/xml-tree.cpp:193 +#, c-format +msgid "" +"Attribute %s selected. Press Ctrl+Enter when done editing to " +"commit changes." +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:284 +msgid "Drag to reorder nodes" +msgstr "Ťahaním preusporiadate uzly" + +#: ../../po/../src/dialogs/xml-tree.cpp:304 +msgid "New element node" +msgstr "Nový uzol elementu" + +#: ../../po/../src/dialogs/xml-tree.cpp:326 +msgid "New text node" +msgstr "Nový textový uzol" + +#: ../../po/../src/dialogs/xml-tree.cpp:347 +msgid "Duplicate node" +msgstr "DuplikovaÅ¥ uzol" + +#: ../../po/../src/dialogs/xml-tree.cpp:368 +msgid "Delete node" +msgstr "ZmazaÅ¥ uzol" + +#: ../../po/../src/dialogs/xml-tree.cpp:384 +msgid "Unindent node" +msgstr "NeodsadiÅ¥ uzol" + +#: ../../po/../src/dialogs/xml-tree.cpp:399 +msgid "Indent node" +msgstr "Odsadí uzol" + +#: ../../po/../src/dialogs/xml-tree.cpp:411 +msgid "Raise node" +msgstr "Zvýši uzol" + +#: ../../po/../src/dialogs/xml-tree.cpp:423 +msgid "Lower node" +msgstr "Zníži uzol" + +#: ../../po/../src/dialogs/xml-tree.cpp:468 +msgid "Delete attribute" +msgstr "ZmazaÅ¥ atribút" + +#. TRANSLATORS: "Attribute" is a noun here +#: ../../po/../src/dialogs/xml-tree.cpp:513 +msgid "Attribute name" +msgstr "Názov atribútu" + +#. TRANSLATORS: "Set" is a verb here +#: ../../po/../src/dialogs/xml-tree.cpp:533 +msgid "Set attribute" +msgstr "Nastaví atribút" + +#. TRANSLATORS: "Set" is a verb here +#: ../../po/../src/dialogs/xml-tree.cpp:535 +msgid "Set" +msgstr "NastaviÅ¥" + +#. TRANSLATORS: "Attribute" is a noun here +#: ../../po/../src/dialogs/xml-tree.cpp:558 +msgid "Attribute value" +msgstr "Hodnota atribútu" + +#: ../../po/../src/dialogs/xml-tree.cpp:1318 +msgid "New element node..." +msgstr "Nový uzol elementu..." + +#: ../../po/../src/dialogs/xml-tree.cpp:1339 +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:100 +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:98 +msgid "Cancel" +msgstr "ZruÅ¡iÅ¥" + +#: ../../po/../src/dialogs/xml-tree.cpp:1345 +msgid "Create" +msgstr "VytvoriÅ¥" + +#: ../../po/../src/dialogs/xml-tree.cpp:1458 +#, c-format +msgid "" +"Cannot set %s: Another element with value %s already exists!" +msgstr "" + +#: ../../po/../src/document.cpp:369 +#, c-format +msgid "New document %d" +msgstr "Nový dokument %d" + +#: ../../po/../src/document.cpp:401 +#, c-format +msgid "Memory document %d" +msgstr "Pamäťový dokument %d" + +#: ../../po/../src/document.cpp:524 +#, c-format +msgid "Unnamed document %d" +msgstr "Nepomenovaný dokument %d" + +#. We hit green anchor, closing Green-Blue-Red +#: ../../po/../src/draw-context.cpp:441 +msgid "Path is closed." +msgstr "Cesta je uzatvorená." + +#. We hit bot start and end of single curve, closing paths +#: ../../po/../src/draw-context.cpp:456 +msgid "Closing path." +msgstr "Uzatváranie cesty." + +#. alpha of color under cursor, to show in the statusbar +#. locale-sensitive printf is OK, since this goes to the UI, not into SVG +#: ../../po/../src/dropper-context.cpp:354 +#, c-format +msgid " alpha %.3g" +msgstr " alpha %.3g" + +#. where the color is picked, to show in the statusbar +#: ../../po/../src/dropper-context.cpp:356 +#, c-format +msgid ", averaged with radius %d" +msgstr ", priemerný s polomerom %d" + +#: ../../po/../src/dropper-context.cpp:356 +msgid " under cursor" +msgstr " pod kurzorom" + +#. message, to show in the statusbar +#: ../../po/../src/dropper-context.cpp:358 +msgid "Release mouse to set color." +msgstr "Uvoľnite myÅ¡ na nastavenie farby." + +#: ../../po/../src/dropper-context.cpp:358 +#: ../../po/../src/tools-switch.cpp:207 +msgid "" +"Click to set fill, Shift+click to set stroke; drag to " +"average color in area; with Alt to pick inverse color; Ctrl+C " +"to copy the color under mouse to clipboard" +msgstr "" + +#: ../../po/../src/extension/dependency.cpp:244 +msgid "Dependency::" +msgstr "" + +#: ../../po/../src/extension/dependency.cpp:245 +#, fuzzy +msgid " type: " +msgstr "T_yp: " + +#: ../../po/../src/extension/dependency.cpp:246 +#, fuzzy +msgid " location: " +msgstr "vzÅ¥ah" + +#: ../../po/../src/extension/dependency.cpp:247 +msgid " string: " +msgstr "" + +#: ../../po/../src/extension/dependency.cpp:250 +#, fuzzy +msgid " description: " +msgstr "Popis" + +#. static int i = 0; +#. std::cout << "Checking module[" << i++ << "]: " << name << std::endl; +#: ../../po/../src/extension/extension.cpp:244 +msgid "" +" This is caused by an improper .inx file for this extension. An improper ." +"inx file could have been caused by a faulty installation of Inkscape." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:247 +msgid "an ID was not defined for it." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:251 +msgid "there was no name defined for it." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:255 +msgid "the XML description of it got lost." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:259 +msgid "no implementation was defined for the extension." +msgstr "" + +#. std::cout << "Failed: " << *(_deps[i]) << std::endl; +#: ../../po/../src/extension/extension.cpp:266 +msgid "a dependency was not met." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:286 +#, fuzzy +msgid "Extension \"" +msgstr "Rozpínanie:" + +#: ../../po/../src/extension/extension.cpp:286 +#, fuzzy +msgid "\" failed to load because " +msgstr "Nepodarilo sa načítaÅ¥ požadovaný súbor %s" + +#: ../../po/../src/extension/extension.cpp:565 +#, fuzzy, c-format +msgid "Could not create extension error log file '%s'" +msgstr "Nepodarilo sa pripojiÅ¥ k hostiteľovi." + +#. This is some filler text, needs to change before relase +#: ../../po/../src/extension/error-file.cpp:56 +msgid "" +"One or more extensions failed to load\n" +"\n" +"The failed extensions have been skipped. Inkscape will continue to run " +"normally but those extensions will be unavailable. For details to " +"troubleshoot this problem, please refer to the error log located at: " +msgstr "" + +#. This is some filler text, needs to change before relase +#: ../../po/../src/extension/error-file.cpp:65 +msgid "Show dialog on startup" +msgstr "" + +#: ../../po/../src/extension/implementation/script.cpp:845 +msgid "" +"Inkscape has received an error from the script that it called. The text " +"returned with the error is included below. Inkscape will continue working, " +"but the action you requested has been cancelled." +msgstr "" + +#: ../../po/../src/extension/implementation/script.cpp:858 +msgid "" +"Inkscape has received additional data from the script executed. The script " +"did not return an error, but this may indicate the results will not be as " +"expected." +msgstr "" + +#: ../../po/../src/extension/init.cpp:173 +msgid "Null external module directory name. Modules will not be loaded." +msgstr "" + +#: ../../po/../src/extension/init.cpp:187 +#, c-format +msgid "" +"Modules directory (%s) is unavailable. External modules in that directory " +"will not be loaded." +msgstr "" + +#: ../../po/../src/extension/internal/gnome.cpp:80 +msgid "Select printer" +msgstr "Výber tlačiarne" + +#: ../../po/../src/extension/internal/gnome.cpp:131 +msgid "Inkscape: Print Preview" +msgstr "Inkscape: Náhľad pre tlačou" + +#: ../../po/../src/extension/internal/grid.cpp:213 +msgid "Line Width" +msgstr "Šírka čiary" + +#: ../../po/../src/extension/internal/grid.cpp:214 +msgid "Horizontal Spacing" +msgstr "Horizontálne medzery" + +#: ../../po/../src/extension/internal/grid.cpp:215 +msgid "Vertical Spacing" +msgstr "Vertikálne medzery" + +#: ../../po/../src/extension/internal/grid.cpp:216 +msgid "Horizontal Offset" +msgstr "Horizontálny posun" + +#: ../../po/../src/extension/internal/grid.cpp:217 +msgid "Vertical Offset" +msgstr "Vertikálny posun" + +#: ../../po/../src/extension/internal/ps.cpp:123 +msgid "Print Destination" +msgstr "Cieľ tlače" + +#. Print properties frame +#: ../../po/../src/extension/internal/ps.cpp:138 +msgid "Print properties" +msgstr "Vlastnosti tlače" + +#: ../../po/../src/extension/internal/ps.cpp:145 +msgid "Print using PostScript operators" +msgstr "TlačiÅ¥ s pomocou Postcript operátorov" + +#: ../../po/../src/extension/internal/ps.cpp:147 +#, fuzzy +msgid "" +"Use PostScript vector operators. The resulting image is usually smaller in " +"file size and can be arbitrarily scaled, but alpha transparency and patterns " +"will be lost." +msgstr "" +"PoužívaÅ¥ vektorové operátory PostScript. Výsledný obrázok je zvyčajne menší " +"a je možné ľubovolne meniÅ¥ jeho veľkosÅ¥, avÅ¡ak sa stratí alfa priehľadnosÅ¥, " +"značky a vzory." + +#: ../../po/../src/extension/internal/ps.cpp:152 +msgid "Print as bitmap" +msgstr "TlačiÅ¥ ako bitmapu" + +#: ../../po/../src/extension/internal/ps.cpp:154 +msgid "" +"Print everything as bitmap. The resulting image is usually larger in file " +"size and cannot be arbitrarily scaled without quality loss, but all objects " +"will be rendered exactly as displayed." +msgstr "" +"TlačiÅ¥ vÅ¡etko ako bitmapu. Výsledný obrázok je zvyčajne väčší a nebude môcÅ¥ " +"byÅ¥ zmeneá vľkosÅ¥ jeho zobrazenia bez straty kvality; vÅ¡etky objekty budú " +"vykreslené tak, ako sú zobrazené." + +#: ../../po/../src/extension/internal/ps.cpp:168 +msgid "Preferred resolution (dots per inch) of bitmap" +msgstr "Preferované rozlíšenie bitmapy (v bodoch na palec)" + +#: ../../po/../src/extension/internal/ps.cpp:182 +msgid "Resolution:" +msgstr "Rozlíšenie:" + +#. Print destination frame +#: ../../po/../src/extension/internal/ps.cpp:186 +msgid "Print destination" +msgstr "Cieľ tlače" + +#: ../../po/../src/extension/internal/ps.cpp:192 +msgid "" +"Use '> filename' to print to file.\n" +"Use '| prog arg...' to pipe to a program." +msgstr "" +"Použite '> súbor', ak chcete tlačiÅ¥ do súboru.\n" +"Použite '| program argument', ak chcete presmerovaÅ¥ výstup do programu" + +#: ../../po/../src/extension/internal/ps.cpp:1227 +msgid "write error occurred" +msgstr "vyskytla sa chyba zápisu" + +#: ../../po/../src/extension/prefdialog.cpp:21 +#, fuzzy +msgid " Preferences" +msgstr "Nastavenia pera" + +#. We can't call sp_ui_error_dialog because we may be +#. running from the console, in which case calling sp_ui +#. routines will cause a segfault. See bug 1000350 - bryce +#. sp_ui_error_dialog(_("Format autodetect failed. The file is being opened as SVG.")); +#: ../../po/../src/extension/system.cpp:105 +msgid "Format autodetect failed. The file is being opened as SVG." +msgstr "Autodetekcia formát zlyhala. Súbor bude otvorený ako SVG." + +#. TRANSLATORS: default.svg is localizable - this is the name of the default document +#. template. This way you can localize the default pagesize, translate the name of +#. the default layer, etc. If you wish to localize this file, please create a +#. localized share/templates/default.xx.svg file, where xx is your language code. +#: ../../po/../src/file.cpp:133 +#, fuzzy +msgid "default.svg" +msgstr "Å tandardné" + +#: ../../po/../src/file.cpp:215 ../../po/../src/file.cpp:900 +#, c-format +msgid "Failed to load the requested file %s" +msgstr "Nepodarilo sa načítaÅ¥ požadovaný súbor %s" + +#: ../../po/../src/file.cpp:240 +msgid "Document not saved yet. Cannot revert." +msgstr "Dokument eÅ¡te nie je uložený, preto nie je možná obnova." + +#: ../../po/../src/file.cpp:246 +#, c-format +msgid "Changes will be lost! Are you sure you want to reload document %s?" +msgstr "" +"VÅ¡etky zmeny sa stratia! Ste si istý, že chcete znovu načítaÅ¥ dokument %s?" + +#: ../../po/../src/file.cpp:266 +msgid "Document reverted." +msgstr "Dokument bol obnovený." + +#: ../../po/../src/file.cpp:268 +msgid "Document not reverted." +msgstr "Dokument nebol obnovený." + +#: ../../po/../src/file.cpp:382 +msgid "Select file to open" +msgstr "Voľba súboru na otvorenie" + +#: ../../po/../src/file.cpp:518 +#, c-format +msgid "Removed %i unused definition in <defs>." +msgid_plural "Removed %i unused definitions in <defs>." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/file.cpp:523 +msgid "No unused definitions in <defs>." +msgstr "" + +#: ../../po/../src/file.cpp:548 +#, c-format +msgid "" +"No Inkscape extension found to save document (%s). This may have been " +"caused by an unknown filename extension." +msgstr "" + +#: ../../po/../src/file.cpp:549 ../../po/../src/file.cpp:557 +msgid "Document not saved." +msgstr "Dokument nebol uložený." + +#: ../../po/../src/file.cpp:556 +#, c-format +msgid "File %s could not be saved." +msgstr "Súbor %s nie je uložený." + +#: ../../po/../src/file.cpp:566 +msgid "Document saved." +msgstr "Dokument bol uložený." + +#: ../../po/../src/file.cpp:614 +#, c-format +msgid "drawing%s" +msgstr "kresba%s" + +#: ../../po/../src/file.cpp:620 +#, c-format +msgid "drawing-%d%s" +msgstr "kresba-%d%s" + +#: ../../po/../src/file.cpp:655 +msgid "Select file to save to" +msgstr "Voľba súboru na uloženie" + +#: ../../po/../src/file.cpp:739 +msgid "No changes need to be saved." +msgstr "Nie je potrebné uložiÅ¥ žiadne zmeny." + +#: ../../po/../src/file.cpp:926 +msgid "Select file to import" +msgstr "Voľba súboru na importovanie" + +#: ../../po/../src/gradient-context.cpp:263 +#, fuzzy +msgid "Ctrl: snap gradient angle" +msgstr "Ctrl: zlomiÅ¥ uhol" + +#: ../../po/../src/gradient-context.cpp:264 +#, fuzzy +msgid "Shift: draw gradient around the starting point" +msgstr "Shift: kresliÅ¥ okolo Å¡tartovacieho bodu" + +#. We did an undoable action, but sp_document_done will be called by the knot when released +#. status text; we do not track coords because this branch is run once, not all the time +#. during drag +#: ../../po/../src/gradient-context.cpp:462 +#, c-format +msgid "Gradient for %d objects; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/gradient-context.cpp:464 +#, fuzzy +msgid "Select objects on which to create gradient." +msgstr "Vyberte objekt, ktorý sa má presunúť vyÅ¡Å¡ie." + +#: ../../po/../src/gradient-drag.cpp:65 +#, fuzzy +msgid "Linear gradient start" +msgstr "Lineárny prechod" + +#. POINT_LG_P1 +#: ../../po/../src/gradient-drag.cpp:66 +#, fuzzy +msgid "Linear gradient end" +msgstr "Lineárny prechod" + +#: ../../po/../src/gradient-drag.cpp:67 +#, fuzzy +msgid "Radial gradient center" +msgstr "Radiálny prechod" + +#: ../../po/../src/gradient-drag.cpp:68 ../../po/../src/gradient-drag.cpp:69 +#, fuzzy +msgid "Radial gradient radius" +msgstr "Radiálny prechod" + +#: ../../po/../src/gradient-drag.cpp:70 +#, fuzzy +msgid "Radial gradient focus" +msgstr "Radiálny prechod" + +#: ../../po/../src/gradient-drag.cpp:659 +#, fuzzy, c-format +msgid "" +"%s for: %s%s; drag with Ctrl to snap angle, with Ctrl+Alt to " +"preserve angle, with Ctrl+Shift to scale around center" +msgstr "" +"Elipsa: %s x %s; s Ctrl na vytvorenie kruhu alebo celočíselnú " +"elipsu so Shift na kreslenie okolo Å¡tartovacieho bodu" + +#: ../../po/../src/gradient-drag.cpp:662 +msgid " (stroke)" +msgstr "" + +#: ../../po/../src/gradient-drag.cpp:665 +msgid "" +"Radial gradient center and focus; drag with Shift to " +"separate focus" +msgstr "" + +#: ../../po/../src/gradient-drag.cpp:667 +#, c-format +msgid "" +"Gradient point shared by %d gradients; drag with Shift to " +"separate" +msgstr "" + +#: ../../po/../src/helper/units.cpp:40 +msgid "Unit" +msgstr "Jednotka" + +#: ../../po/../src/helper/units.cpp:40 +msgid "Units" +msgstr "Jednotky" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Point" +msgstr "Bod" + +#: ../../po/../src/helper/units.cpp:41 +msgid "pt" +msgstr "bd" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Points" +msgstr "Body" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Pt" +msgstr "b." + +#: ../../po/../src/helper/units.cpp:42 +msgid "Pixel" +msgstr "Bod" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Pixels" +msgstr "Body" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Px" +msgstr "Bd" + +#. You can add new elements from this point forward +#: ../../po/../src/helper/units.cpp:44 ../share/extensions/straightseg.inx.h:2 +msgid "Percent" +msgstr "Percento" + +#: ../../po/../src/helper/units.cpp:44 +msgid "Percents" +msgstr "percent" + +#: ../../po/../src/helper/units.cpp:45 +msgid "Millimeter" +msgstr "Milimeter" + +#: ../../po/../src/helper/units.cpp:45 +msgid "mm" +msgstr "mm" + +#: ../../po/../src/helper/units.cpp:45 +msgid "Millimeters" +msgstr "Milimetre" + +#: ../../po/../src/helper/units.cpp:46 +msgid "Centimeter" +msgstr "Centimeter" + +#: ../../po/../src/helper/units.cpp:46 +msgid "cm" +msgstr "cm" + +#: ../../po/../src/helper/units.cpp:46 +msgid "Centimeters" +msgstr "Centimetre" + +#: ../../po/../src/helper/units.cpp:47 +msgid "Meter" +msgstr "meter" + +#: ../../po/../src/helper/units.cpp:47 +msgid "m" +msgstr "m" + +#: ../../po/../src/helper/units.cpp:47 +msgid "Meters" +msgstr "metre" + +#. no svg_unit +#: ../../po/../src/helper/units.cpp:48 +msgid "Inch" +msgstr "Palec" + +#: ../../po/../src/helper/units.cpp:48 +msgid "in" +msgstr "palec" + +#: ../../po/../src/helper/units.cpp:48 +msgid "Inches" +msgstr "Palce" + +#. Volatiles do not have default, so there are none here +#. TRANSLATORS: for info, see http://www.w3.org/TR/REC-CSS2/syndata.html#length-units +#: ../../po/../src/helper/units.cpp:51 +msgid "Em square" +msgstr "Em Å¡tvorec" + +#: ../../po/../src/helper/units.cpp:51 +msgid "em" +msgstr "em" + +#: ../../po/../src/helper/units.cpp:51 +msgid "Em squares" +msgstr "Em Å¡tvorce" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/REC-CSS2/syndata.html#length-units +#: ../../po/../src/helper/units.cpp:53 +msgid "Ex square" +msgstr "Ex Å¡tvorec" + +#: ../../po/../src/helper/units.cpp:53 +msgid "ex" +msgstr "ex" + +#: ../../po/../src/helper/units.cpp:53 +msgid "Ex squares" +msgstr "Ex Å¡tvorce" + +#: ../../po/../src/inkscape.cpp:468 +msgid "Untitled document" +msgstr "Nepomenovaný dokument" + +#. Show nice dialog box +#: ../../po/../src/inkscape.cpp:497 +msgid "Inkscape encountered an internal error and will close now.\n" +msgstr "Vyskytla sa interná chyba a program Inkscape bude teraz ukončený.\n" + +#: ../../po/../src/inkscape.cpp:498 +msgid "" +"Automatic backups of unsaved documents were done to the following " +"locations:\n" +msgstr "Automatické zálohovanie neuložených dokumentov bolo vykonané do:\n" + +#: ../../po/../src/inkscape.cpp:499 +msgid "Automatic backup of the following documents failed:\n" +msgstr "Nepodarilo sa automaticky zálohovaÅ¥ nasledujúce dokumenty:\n" + +#: ../../po/../src/inkscape.cpp:634 +#, c-format +msgid "" +"Cannot create directory %s.\n" +"%s" +msgstr "" +"Nie je možné vytvoriÅ¥ priečinok %s.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:635 +#, c-format +msgid "" +"%s is not a valid directory.\n" +"%s" +msgstr "" +"%s nie je platný priečinok.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:636 +#, c-format +msgid "" +"Cannot create file %s.\n" +"%s" +msgstr "" +"Nie je možné vytvoriÅ¥ súbor %s.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:637 +#, c-format +msgid "" +"Cannot write file %s.\n" +"%s" +msgstr "" +"Nie je možné zapísaÅ¥ súbor %s.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:638 +msgid "" +"Although Inkscape will run, it will use default settings,\n" +"and any changes made in preferences will not be saved." +msgstr "" + +#: ../../po/../src/inkscape.cpp:708 +#, c-format +msgid "" +"%s is not a regular file.\n" +"%s" +msgstr "" +"'%s' nie je regulárny súbor.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:709 +#, c-format +msgid "" +"%s not a valid XML file, or\n" +"you don't have read permissions on it.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:711 +#, fuzzy, c-format +msgid "" +"%s is not a valid menus file.\n" +"%s" +msgstr "" +"'%s' nie je platný súboru volieb.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:712 +msgid "" +"Inkscape will run with default menus.\n" +"New menus will not be saved." +msgstr "" + +#. sp_ui_menu_append_check_item_from_verb(m, view, _("_Menu"), _("Show or hide the menu bar"), "menu", +#. checkitem_toggled, checkitem_update, 0); +#: ../../po/../src/interface.cpp:753 +msgid "Commands Bar" +msgstr "Príkazový panel" + +#: ../../po/../src/interface.cpp:753 +msgid "Show or hide the Commands bar (under the menu)" +msgstr "ZobraziÅ¥ alebo skryÅ¥ Príkazový pane (pod ponukou)" + +#: ../../po/../src/interface.cpp:755 +msgid "Tool Controls" +msgstr "Ovládanie nástrojov" + +#: ../../po/../src/interface.cpp:755 +msgid "Show or hide the Tool Controls panel" +msgstr "ZobraziÅ¥ alebo skryÅ¥ panel pre ovládanie nástrojov" + +#: ../../po/../src/interface.cpp:757 +msgid "_Toolbox" +msgstr "_Nástrojový panel" + +#: ../../po/../src/interface.cpp:757 +msgid "Show or hide the main toolbox (on the left)" +msgstr "" + +#: ../../po/../src/interface.cpp:763 +msgid "_Statusbar" +msgstr "_Stavový riadok" + +#: ../../po/../src/interface.cpp:763 +msgid "Show or hide the statusbar (at the bottom of the window)" +msgstr "" + +#: ../../po/../src/interface.cpp:820 +#, c-format +msgid "Verb \"%s\" Unknown" +msgstr "" + +#. TRANSLATORS: #%s is the id of the group e.g. , not a number. +#: ../../po/../src/interface.cpp:930 +#, c-format +msgid "Enter group #%s" +msgstr "Zadajte skupinu #%s" + +#: ../../po/../src/interface.cpp:941 +#, fuzzy +msgid "Go to parent" +msgstr "O stupeň vyÅ¡Å¡ie" + +#: ../../po/../src/interface.cpp:972 +msgid "Could not parse SVG data" +msgstr "Nie je možné analyzovaÅ¥ SVG dáta" + +#: ../../po/../src/interface.cpp:1135 +#, c-format +msgid "Overwrite %s" +msgstr "PrepísaÅ¥ %s" + +#: ../../po/../src/interface.cpp:1153 +#, c-format +msgid "" +"The file %s already exists. Do you want to overwrite that file with the " +"current document?" +msgstr "Súbor %s už existuje. Chcete ho prepísaÅ¥ aktuálnym dokumentom?" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:59 +msgid "Jabber connection lost." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:72 +#, c-format +msgid "Sending message; %u message remaining in send queue." +msgid_plural "Sending message; %u messages remaining in send queue." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:78 +msgid "Receive queue empty." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:154 +#, c-format +msgid "Receiving change; %u change left to process." +msgid_plural "Receiving change; %u changes left to process." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:157 +#, c-format +msgid "%s has left the chatroom." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:221 +msgid "Nickname %1 is already in use. Please choose a different nickname." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:225 +msgid "An error was encountered while attempting to connect to the server." +msgstr "" + +#. Check to see if the user made any modifications to this document. If so, +#. we want to give them the option of (1) letting us clear their document or (2) +#. opening a new, blank document for the whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:131 +msgid "%1 has invited you to a whiteboard session." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:132 +msgid "Incoming whiteboard invitation from %1" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:135 +msgid "Do you wish to accept %1's whiteboard session invitation?" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:137 +msgid "" +"Would you like to accept %1's invitation in a new document window?\n" +"Accepting the invitation in your current window will discard unsaved changes." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:143 +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:198 +#, fuzzy +msgid "Accept invitation" +msgstr "Akcelerácia:" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:144 +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:199 +msgid "Decline invitation" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:145 +#, fuzzy +msgid "Accept invitation in new document window" +msgstr "VytvoriÅ¥ nový dokument" + +#. We could not create a new desktop; ask the user if she or he wants to +#. replace the current document and accept the invitation, or reject the invitation. +#. TRANSLATORS: %1 is a userid here +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:196 +msgid "" +"A new document window could not be opened for a whiteboard session with %" +"1" +msgstr "" + +#. TRANSLATORS: %1 is the peer whom refused our invitation. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:238 +msgid "" +"The user %1 has refused your " +"whiteboard invitation.\n" +"\n" +msgstr "" + +#. TRANSLATORS: %1 is the peer whom refused our invitation, %2 is our Jabber identity. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:241 +msgid "" +"You are still connected to a Jabber server as %2, and may send an " +"invitation to %1 again, or you may send an invitation to a different " +"user." +msgstr "" + +#. TRANSLATORS: %1 is the peer whom we tried to contact, but is already in a whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:252 +msgid "" +"The user %1 is already in a " +"whiteboard session.\n" +"\n" +msgstr "" + +#. TRANSLATORS: %1 is the peer whom we tried to contact, but is already in a whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:255 +msgid "" +"You are still connected to a Jabber server as %1, and may send an " +"invitation to a different user." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/invitation-confirm-dialog.cpp:26 +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:24 +msgid "_Write session file:" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/message-processors.cpp:145 +#, c-format +msgid "%s has joined the chatroom." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/message-queue.cpp:87 +#, fuzzy, c-format +msgid "%u change in receive queue." +msgid_plural "%u changes in receive queue." +msgstr[0] "Nie je potrebné uložiÅ¥ žiadne zmeny." +msgstr[1] "Nie je potrebné uložiÅ¥ žiadne zmeny." +msgstr[2] "Nie je potrebné uložiÅ¥ žiadne zmeny." + +#: ../../po/../src/jabber_whiteboard/message-queue.cpp:117 +#, fuzzy, c-format +msgid "%u change in send queue." +msgid_plural "%u changes in send queue." +msgstr[0] "Nie je potrebné uložiÅ¥ žiadne zmeny." +msgstr[1] "Nie je potrebné uložiÅ¥ žiadne zmeny." +msgstr[2] "Nie je potrebné uložiÅ¥ žiadne zmeny." + +#. if ID is NULL, then we have a real problem -- we were not able to find a key +#. nor generate one. The only thing we can really do here is abort, since we have +#. no way to let the other client(s) uniquely identify this object. +#. FIXME: If this indicates a programming bug, then don't request translation with +#. * _(...): it is most useful in untranslated form so that developers may search for +#. * it when someone reports it in a bug report (as we want users to do for all bugs, +#. * as indicated by it being a g_warning string). +#. * +#. * Otherwise, if it is not a programming bug but a network error or a bug in the +#. * remote peer (perhaps running different software) or whatever, then present it in +#. * an alert box, and avoid use of technical jargon `NULL'. +#. +#: ../../po/../src/jabber_whiteboard/message-utilities.cpp:171 +msgid "" +"ID for new object is NULL even after generation and lookup attempts: the new " +"object will NOT be sent, nor will any of its child objects!" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:60 +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:995 +msgid "Select a location and filename" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:62 +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:997 +#, fuzzy +msgid "Set filename" +msgstr "Názov súboru" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:301 +msgid "No SSL certificate was found." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:304 +msgid "The SSL certificate provided by the Jabber server is untrusted." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:307 +msgid "The SSL certificate provided by the Jabber server is expired." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:310 +msgid "" +"The SSL certificate provided by the Jabber server has not been activated." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:313 +msgid "" +"The SSL certificate provided by the Jabber server contains a hostname that " +"does not match the Jabber server's hostname." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:316 +msgid "" +"The SSL certificate provided by the Jabber server contains an invalid " +"fingerprint." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:319 +msgid "An unknown error occurred while setting up the SSL connection." +msgstr "" + +#. TRANSLATORS: %1 is the message that describes the specific error that occurred when +#. establishing the SSL connection. +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:325 +msgid "" +"%1\n" +"\n" +"Do you wish to continue connecting to the Jabber server?" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:328 +msgid "Continue connecting and ignore further errors" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:329 +msgid "Continue connecting, but warn me of further errors" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:330 +#, fuzzy +msgid "Cancel connection" +msgstr "Výber" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:777 +#, c-format +msgid "Established whiteboard session with %s." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:785 +#, c-format +msgid "%s has left the whiteboard session." +msgstr "" + +#. Inform the user +#. TRANSLATORS: %1 is the name of the user that disconnected, %2 is the name of the user whom the disconnected user disconnected from. +#. This message is not used in a chatroom context. +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:790 +msgid "" +"The user %1 has left the " +"whiteboard session.\n" +"\n" +msgstr "" + +#. TRANSLATORS: %1 and %2 are userids +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:792 +msgid "" +"You are still connected to a Jabber server as %2, and may establish a " +"new session to %1 or a different user." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:988 +msgid "" +"Could not open file %1 for session recording.\n" +"The error encountered was: %2.\n" +"\n" +"You may select a different location to record the session, or you may opt to " +"not record this session." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:990 +msgid "Choose a different location" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:991 +msgid "Skip session recording" +msgstr "" + +#: ../../po/../src/knot.cpp:673 +msgid "Node or handle drag canceled." +msgstr "" + +#: ../../po/../src/libnrtype/FontFactory.cpp:358 +msgid "Ignoring font without family that will crash Pango" +msgstr "" + +#: ../../po/../src/main.cpp:395 +msgid "Print the Inkscape version number" +msgstr "vytlačí číslo verzie Inkscape" + +#: ../../po/../src/main.cpp:400 +msgid "Do not use X server (only process files from console)" +msgstr "NepoužívaÅ¥ X server (iba spracovaÅ¥ súbory z konzoly)" + +#: ../../po/../src/main.cpp:405 +msgid "Try to use X server (even if $DISPLAY is not set)" +msgstr "PokúsiÅ¥ sa použiÅ¥ X server (aj keď $DISPLAY nie je nastavená)" + +#: ../../po/../src/main.cpp:410 +msgid "Open specified document(s) (option string may be excluded)" +msgstr "OtvoriÅ¥ určený dokument (reÅ¥azec s voľbami môže byÅ¥ vynechaný)" + +#: ../../po/../src/main.cpp:411 ../../po/../src/main.cpp:416 +#: ../../po/../src/main.cpp:421 ../../po/../src/main.cpp:483 +#: ../../po/../src/main.cpp:488 ../../po/../src/main.cpp:493 +msgid "FILENAME" +msgstr "NÁZOV_SÚBORU" + +#: ../../po/../src/main.cpp:415 +msgid "Print document(s) to specified output file (use '| program' for pipe)" +msgstr "" +"VytlačiÅ¥ súbor do určeného výstupného súboru (použite '| program' pre rúru)" + +#: ../../po/../src/main.cpp:420 +msgid "Export document to a PNG file" +msgstr "ExportovaÅ¥ dokument do png súboru" + +#: ../../po/../src/main.cpp:425 +#, fuzzy +msgid "The resolution used for exporting SVG into bitmap (default 90)" +msgstr "Rozlíšenie použité pre konverziu SVG na bitmapu (Å¡tandardne 72.0)" + +#: ../../po/../src/main.cpp:426 +msgid "DPI" +msgstr "DPI" + +#: ../../po/../src/main.cpp:430 +#, fuzzy +msgid "" +"Exported area in SVG user units (default is the canvas; 0,0 is lower-left " +"corner)" +msgstr "" +"ExportovaÅ¥ oblasÅ¥ v SVG bodoch (Å¡tandardne je to celý dokument, 0,0 je ľavý " +"dolný roh)" + +#: ../../po/../src/main.cpp:431 +msgid "x0:y0:x1:y1" +msgstr "x0:y0:x1:y1" + +#: ../../po/../src/main.cpp:435 +msgid "Exported area is the entire drawing (not canvas)" +msgstr "" + +#: ../../po/../src/main.cpp:440 +msgid "" +"Snap the bitmap export area outwards to the nearest integer values (in SVG " +"user units)" +msgstr "" + +#: ../../po/../src/main.cpp:445 +msgid "The width of exported bitmap in pixels (overrides export-dpi)" +msgstr "Šírka exportovanej bitmapy v pixeloch (prepíše export-dpi)" + +#: ../../po/../src/main.cpp:446 +msgid "WIDTH" +msgstr "ŠÍRKA" + +#: ../../po/../src/main.cpp:450 +msgid "The height of exported bitmap in pixels (overrides export-dpi)" +msgstr "Výška exportovanej bitmapy v pixeloch (prepíše export-dpi)" + +#: ../../po/../src/main.cpp:451 +msgid "HEIGHT" +msgstr "VÝŠKA" + +#: ../../po/../src/main.cpp:455 +msgid "The ID of the object to export (overrides export-area)" +msgstr "ID exportovaného objektu (prepíše export-area)" + +#: ../../po/../src/main.cpp:456 ../../po/../src/main.cpp:532 +msgid "ID" +msgstr "ID:" + +#. TRANSLATORS: this means: "Only export the object whose id is given in --export-id". +#. See "man inkscape" for details. +#: ../../po/../src/main.cpp:462 +msgid "" +"Export just the object with export-id, hide all others (only with export-id)" +msgstr "" + +#: ../../po/../src/main.cpp:467 +msgid "Use stored filename and DPI hints when exporting (only with export-id)" +msgstr "" + +#: ../../po/../src/main.cpp:472 +msgid "Background color of exported bitmap (any SVG-supported color string)" +msgstr "" +"Farba pozadia exportovanej bitmapy (akýkoľvek podporovaný SVG reÅ¥azec farby)" + +#: ../../po/../src/main.cpp:473 +msgid "COLOR" +msgstr "FARBA" + +#: ../../po/../src/main.cpp:477 +msgid "Background opacity of exported bitmap (either 0.0 to 1.0, or 1 to 255)" +msgstr "" +"NepriesvitnosÅ¥ pozadiaexportovanej bitmapy (buď od 0.0 po 1.0, alebo do 1 po " +"255)" + +#: ../../po/../src/main.cpp:478 +msgid "VALUE" +msgstr "HODNOTA" + +#: ../../po/../src/main.cpp:482 +msgid "Export document to plain SVG file (no sodipodi or inkscape namespaces)" +msgstr "" +"ExportovaÅ¥ dokument do obyčajného SVG súboru (bez sodipodi alebo inkscape " +"namespace)" + +#: ../../po/../src/main.cpp:487 +#, fuzzy +msgid "Export document to a PS file" +msgstr "ExportovaÅ¥ dokument do png súboru" + +#: ../../po/../src/main.cpp:492 +#, fuzzy +msgid "Export document to an EPS file" +msgstr "ExportovaÅ¥ dokument do png súboru" + +#: ../../po/../src/main.cpp:497 +#, fuzzy +msgid "Convert text object to paths on export (EPS)" +msgstr "KonvertovaÅ¥ bitmapový objekt na cestu" + +#: ../../po/../src/main.cpp:502 +msgid "Export files with the bounding box set to the page size (EPS)" +msgstr "" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:508 +msgid "" +"Query the X coordinate of the drawing or, if specified, of the object with --" +"query-id" +msgstr "" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:514 +msgid "" +"Query the Y coordinate of the drawing or, if specified, of the object with --" +"query-id" +msgstr "" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:520 +msgid "" +"Query the width of the drawing or, if specified, of the object with --query-" +"id" +msgstr "" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:526 +msgid "" +"Query the height of the drawing or, if specified, of the object with --query-" +"id" +msgstr "" + +#: ../../po/../src/main.cpp:531 +#, fuzzy +msgid "The ID of the object whose dimensions are queried" +msgstr "ID exportovaného objektu (prepíše export-area)" + +#. TRANSLATORS: this option makes Inkscape print the name (path) of the extension directory +#: ../../po/../src/main.cpp:537 +msgid "Print out the extension directory and exit" +msgstr "" + +#: ../../po/../src/main.cpp:542 +msgid "Show given files one-by-one, switch to next on any key/mouse event" +msgstr "" +"ZobraziÅ¥ dané súbory jeden po druhom, na nasledujúci prepnúť po akejkoľvek " +"udalosti klávesnice/myÅ¡i" + +#: ../../po/../src/main.cpp:547 +msgid "Use the new Gtkmm GUI interface" +msgstr "" + +#: ../../po/../src/main.cpp:552 +msgid "Remove unused definitions from the defs section(s) of the document" +msgstr "" + +#: ../../po/../src/main.cpp:741 +msgid "" +"[OPTIONS...] [FILE...]\n" +"\n" +"Available options:" +msgstr "" +"[PREPÍNAČ...] [SÚBOR]\n" +"\n" +"Dostupné prepínače:" + +#: ../../po/../src/menus-skeleton.h:17 +msgid "_New" +msgstr "_Nový" + +#: ../../po/../src/menus-skeleton.h:22 +msgid "Open _Recent" +msgstr "OtvoriÅ¥ ne_dávane" + +#: ../../po/../src/menus-skeleton.h:53 +msgid "_Edit" +msgstr "_UpraviÅ¥" + +#: ../../po/../src/menus-skeleton.h:84 +msgid "_View" +msgstr "_ZobraziÅ¥" + +#: ../../po/../src/menus-skeleton.h:85 +#, fuzzy +msgid "_Zoom" +msgstr "Lupa" + +#: ../../po/../src/menus-skeleton.h:102 +#, fuzzy +msgid "Show/Hide" +msgstr "Z_obraziÅ¥/SkryÅ¥" + +#: ../../po/../src/menus-skeleton.h:107 +msgid "_Display mode" +msgstr "" + +#: ../../po/../src/menus-skeleton.h:126 +msgid "_Layer" +msgstr "_Vrstva" + +#: ../../po/../src/menus-skeleton.h:143 +msgid "_Object" +msgstr "_Objekt" + +#: ../../po/../src/menus-skeleton.h:165 +msgid "_Path" +msgstr "_Cesta" + +#: ../../po/../src/menus-skeleton.h:188 +msgid "_Text" +msgstr "_Text" + +#: ../../po/../src/menus-skeleton.h:200 +msgid "Effects" +msgstr "Efekty" + +#: ../../po/../src/menus-skeleton.h:207 +msgid "Whiteboa_rd" +msgstr "" + +#: ../../po/../src/menus-skeleton.h:220 +msgid "_Help" +msgstr "_Pomocník" + +#: ../../po/../src/menus-skeleton.h:222 +#, fuzzy +msgid "Tutorials" +msgstr "_Návody" + +#: ../../po/../src/node-context.cpp:382 +msgid "" +"Ctrl: toggle node type, snap handle angle, move hor/vert; Ctrl" +"+Alt: move along handles" +msgstr "" + +#: ../../po/../src/node-context.cpp:383 +msgid "" +"Shift: toggle node selection, disable snapping, rotate both handles" +msgstr "" + +#: ../../po/../src/node-context.cpp:384 +msgid "Alt: lock handle length; Ctrl+Alt: move along handles" +msgstr "" + +#: ../../po/../src/nodepath.cpp:1399 ../../po/../src/nodepath.cpp:1411 +#: ../../po/../src/nodepath.cpp:1492 ../../po/../src/nodepath.cpp:1504 +msgid "To join, you must have two endnodes selected." +msgstr "" + +#: ../../po/../src/nodepath.cpp:1633 ../../po/../src/nodepath.cpp:1647 +msgid "" +"Select two non-endpoint nodes on a path between which to delete " +"segments." +msgstr "" + +#: ../../po/../src/nodepath.cpp:1743 +msgid "Cannot find path between nodes." +msgstr "Nemôžem nájsÅ¥ cestu medzi uzlami." + +#: ../../po/../src/nodepath.cpp:2822 +#, fuzzy, c-format +msgid "" +"Node handle: angle %0.2f°, length %s; with Ctrl to snap " +"angle; with Alt to lock length; with Shift to rotate both " +"handles" +msgstr "" +"Elipsa: %s x %s; s Ctrl na vytvorenie kruhu alebo celočíselnú " +"elipsu so Shift na kreslenie okolo Å¡tartovacieho bodu" + +#: ../../po/../src/nodepath.cpp:3351 +msgid "" +"Node: drag to edit the path; with Ctrl to snap to horizontal/" +"vertical; with Ctrl+Alt to snap to handles' directions" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3375 +msgid "" +"Node handle: drag to shape the curve; with Ctrl to snap angle; " +"with Alt to lock length; with Shift to rotate both handles" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3399 +msgid "" +"Node handle: drag to shape the curve; with Ctrl to snap angle; " +"with Alt to lock length; with Shift to rotate the opposite " +"handle in sync" +msgstr "" + +#. TRANSLATORS: "end" is an adjective here (NOT a verb) +#: ../../po/../src/nodepath.cpp:3591 +#, fuzzy +msgid "end node" +msgstr "Odsadí uzol" + +#. TRANSLATORS: "cusp" means "sharp" (cusp node); see also the Advanced Tutorial +#: ../../po/../src/nodepath.cpp:3596 +#, fuzzy +msgid "cusp" +msgstr "Hrotové ovládanie" + +#. TRANSLATORS: "smooth" is an adjective here +#: ../../po/../src/nodepath.cpp:3599 +msgid "smooth" +msgstr "hladké" + +#: ../../po/../src/nodepath.cpp:3601 +msgid "symmetric" +msgstr "symetricky" + +#. TRANSLATORS: "end" is an adjective here (NOT a verb) +#: ../../po/../src/nodepath.cpp:3607 +msgid "end node, handle retracted (drag with Shift to extend)" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3609 +msgid "one handle retracted (drag with Shift to extend)" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3612 +msgid "both handles retracted (drag with Shift to extend)" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3624 +#, fuzzy +msgid "Drag nodes or node handles; arrow keys to move nodes" +msgstr "" +"Ťahaním vytvoríte kaligrafickú čiaru. Stlačením 'a' na prepnete medzi " +"PridaÅ¥/Nový." + +#: ../../po/../src/nodepath.cpp:3625 +#, fuzzy +msgid "Drag the node or its handles; arrow keys to move the node" +msgstr "" +"Ťahaním vytvoríte kaligrafickú čiaru. Stlačením 'a' na prepnete medzi " +"PridaÅ¥/Nový." + +#: ../../po/../src/nodepath.cpp:3651 ../../po/../src/nodepath.cpp:3663 +#, fuzzy +msgid "Select a single object to edit its nodes or handles." +msgstr "VybraÅ¥ vÅ¡etky objekty alebo vÅ¡etky uzly" + +#: ../../po/../src/nodepath.cpp:3655 +#, c-format +msgid "" +"0 out of %i node selected. Click, Shift+click, " +"or drag around nodes to select." +msgid_plural "" +"0 out of %i nodes selected. Click, Shift+click, " +"or drag around nodes to select." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/nodepath.cpp:3661 +#, fuzzy +msgid "Drag the handles of the object to modify it." +msgstr "Každý zvolený objekt zobrazí svoje ohraničenie" + +#: ../../po/../src/nodepath.cpp:3669 +#, fuzzy, c-format +msgid "%i of %i node selected; %s. %s." +msgid_plural "%i of %i nodes selected; %s. %s." +msgstr[0] "Označené súbory:" +msgstr[1] "%i zo %i zvolených uzlov; %s. %s." +msgstr[2] "%i zo %i zvolených uzlov; %s. %s." + +#: ../../po/../src/nodepath.cpp:3675 +#, fuzzy, c-format +msgid "%i of %i node selected. %s." +msgid_plural "%i of %i nodes selected. %s." +msgstr[0] "Označené súbory:" +msgstr[1] "%i zo %i zvolených uzlov; %s." +msgstr[2] "%i zo %i zvolených uzlov; %s." + +#: ../../po/../src/object-edit.cpp:493 +msgid "" +"Adjust the horizontal rounding radius; with Ctrl to make the " +"vertical radius the same" +msgstr "" + +#: ../../po/../src/object-edit.cpp:499 +msgid "" +"Adjust the vertical rounding radius; with Ctrl to make the " +"horizontal radius the same" +msgstr "" + +#: ../../po/../src/object-edit.cpp:506 ../../po/../src/object-edit.cpp:513 +msgid "" +"Adjust the width and height of the rectangle; with Ctrl to " +"lock ratio or stretch in one dimension only" +msgstr "" + +#: ../../po/../src/object-edit.cpp:686 +msgid "Adjust ellipse width, with Ctrl to make circle" +msgstr "" + +#: ../../po/../src/object-edit.cpp:689 +msgid "Adjust ellipse height, with Ctrl to make circle" +msgstr "" + +#: ../../po/../src/object-edit.cpp:692 +msgid "" +"Position the start point of the arc or segment; with Ctrl to " +"snap angle; drag inside the ellipse for arc, outside for " +"segment" +msgstr "" + +#: ../../po/../src/object-edit.cpp:695 +msgid "" +"Position the end point of the arc or segment; with Ctrl to " +"snap angle; drag inside the ellipse for arc, outside for " +"segment" +msgstr "" + +#: ../../po/../src/object-edit.cpp:800 +msgid "" +"Adjust the tip radius of the star or polygon; with Shift to " +"round; with Alt to randomize" +msgstr "" + +#: ../../po/../src/object-edit.cpp:803 +msgid "" +"Adjust the base radius of the star; with Ctrl to keep star " +"rays radial (no skew); with Shift to round; with Alt to " +"randomize" +msgstr "" + +#: ../../po/../src/object-edit.cpp:967 +msgid "" +"Roll/unroll the spiral from inside; with Ctrl to snap angle; " +"with Alt to converge/diverge" +msgstr "" + +#: ../../po/../src/object-edit.cpp:969 +msgid "" +"Roll/unroll the spiral from outside; with Ctrl to snap angle; " +"with Shift to scale/rotate" +msgstr "" + +#: ../../po/../src/object-edit.cpp:1006 +msgid "Adjust the offset distance" +msgstr "PrispôsobiÅ¥ vzdialenosÅ¥ posunu" + +#. TRANSLATORS: This refers to the pattern that's inside the object +#: ../../po/../src/object-edit.cpp:1036 +#, fuzzy +msgid "Move the pattern fill inside the object" +msgstr "Vyberte objekty so vzorkou na oddláždenie." + +#: ../../po/../src/object-edit.cpp:1038 +msgid "Scale the pattern fill uniformly" +msgstr "Mierka vzorky vyplní rovnomerne." + +#: ../../po/../src/object-edit.cpp:1040 +msgid "Rotate the pattern fill; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/object-edit.cpp:1065 +msgid "Drag to resize the flowed text frame" +msgstr "" + +#. Item dialog +#: ../../po/../src/object-ui.cpp:106 +msgid "Object _Properties" +msgstr "_Vlastnosti objektu" + +#. Select item +#: ../../po/../src/object-ui.cpp:116 +msgid "_Select This" +msgstr "_VybraÅ¥ toto" + +#. Create link +#: ../../po/../src/object-ui.cpp:126 +msgid "_Create Link" +msgstr "VytvoriÅ¥ odkaz" + +#. "Ungroup" +#: ../../po/../src/object-ui.cpp:199 ../../po/../src/verbs.cpp:1931 +msgid "_Ungroup" +msgstr "Z_ruÅ¡iÅ¥ zoskupenie" + +#. Link dialog +#: ../../po/../src/object-ui.cpp:239 +msgid "Link _Properties" +msgstr "Nastavenie odkazu" + +#. Select item +#: ../../po/../src/object-ui.cpp:249 +msgid "_Follow Link" +msgstr "_NasledovaÅ¥ odkaz" + +#. Reset transformations +#: ../../po/../src/object-ui.cpp:254 +msgid "_Remove Link" +msgstr "Odst_rániÅ¥ odkaz" + +#. Link dialog +#: ../../po/../src/object-ui.cpp:303 +msgid "Image _Properties" +msgstr "Vlastnosti o_brázka" + +#. Item dialog +#: ../../po/../src/object-ui.cpp:344 +msgid "_Fill and Stroke" +msgstr "Výp_lň a Å¥ah" + +#: ../../po/../src/path-chemistry.cpp:58 +msgid "Select at least two objects to combine." +msgstr "Vyberte najmenej dva objekty pre kombináciu." + +#: ../../po/../src/path-chemistry.cpp:65 +msgid "At least one of the objects is not a path, cannot combine." +msgstr "" +"Minimálne jeden z objektov nie je cesta, kombinácia nie je možná." + +#: ../../po/../src/path-chemistry.cpp:73 +msgid "" +"You cannot combine objects from different groups or layers." +msgstr "" + +#: ../../po/../src/path-chemistry.cpp:155 +msgid "Select path(s) to break apart." +msgstr "Vyberte cestu, ktorá sa má zlomiÅ¥." + +#: ../../po/../src/path-chemistry.cpp:231 +#, fuzzy +msgid "No path(s) to break apart in the selection." +msgstr "Vo výbere nie sú objekty, ktoré je možné konvertovaÅ¥ na cesty." + +#: ../../po/../src/path-chemistry.cpp:252 +msgid "Select object(s) to convert to path." +msgstr "Vyberte objekt, ktorá sa má konvertovaÅ¥ na cestu." + +#: ../../po/../src/path-chemistry.cpp:297 +msgid "No objects to convert to path in the selection." +msgstr "Vo výbere nie sú objekty, ktoré je možné konvertovaÅ¥ na cesty." + +#: ../../po/../src/path-chemistry.cpp:345 +msgid "Select path(s) to reverse." +msgstr "Vyberte cestu, ktorá sa má obrátiÅ¥." + +#: ../../po/../src/path-chemistry.cpp:370 +#, fuzzy +msgid "No paths to reverse in the selection." +msgstr "Výber neobsahuje text na ceste." + +#: ../../po/../src/pen-context.cpp:379 ../../po/../src/pencil-context.cpp:233 +#, fuzzy +msgid "Continuing selected path" +msgstr "Posunúť zvolené cesty dnu" + +#: ../../po/../src/pen-context.cpp:390 ../../po/../src/pencil-context.cpp:242 +#, fuzzy +msgid "Creating new path" +msgstr "Tvorba novej krivky" + +#: ../../po/../src/pen-context.cpp:394 ../../po/../src/pencil-context.cpp:246 +#, fuzzy +msgid "Appending to selected path" +msgstr "PripojiÅ¥ k výberu" + +#: ../../po/../src/pen-context.cpp:538 +msgid "Click or click and drag to close and finish the path." +msgstr "" + +#: ../../po/../src/pen-context.cpp:548 +msgid "" +"Click or click and drag to continue the path from this point." +msgstr "" + +#: ../../po/../src/pen-context.cpp:857 +#, fuzzy, c-format +msgid "" +"%s: angle %3.2f°, distance %s; with Ctrl to snap angle, " +"Enter to finish the path" +msgstr "" +"Elipsa: %s x %s; s Ctrl na vytvorenie kruhu alebo celočíselnú " +"elipsu so Shift na kreslenie okolo Å¡tartovacieho bodu" + +#: ../../po/../src/pen-context.cpp:882 +#, c-format +msgid "" +"Curve handle: angle %3.2f°, length %s; with Ctrl to snap " +"angle" +msgstr "" + +#: ../../po/../src/pen-context.cpp:912 +#, fuzzy, c-format +msgid "" +"%s: angle %3.2f°, length %s; with Ctrl to snap angle, " +"with Shift to move this handle only" +msgstr "" +"Elipsa: %s x %s; s Ctrl na vytvorenie kruhu alebo celočíselnú " +"elipsu so Shift na kreslenie okolo Å¡tartovacieho bodu" + +#: ../../po/../src/pen-context.cpp:946 +msgid "Finishing pen" +msgstr "Dokončenie kreslenia perom" + +#: ../../po/../src/pencil-context.cpp:320 +msgid "Release here to close and finish the path." +msgstr "" + +#: ../../po/../src/pencil-context.cpp:326 +#, fuzzy +msgid "Drawing a freehand path" +msgstr "Kreslenie voľnou rukou" + +#: ../../po/../src/pencil-context.cpp:331 +msgid "Drag to continue the path from this point." +msgstr "" + +#. Write curves to object +#: ../../po/../src/pencil-context.cpp:390 +msgid "Finishing freehand" +msgstr "Dokončenie kreslenia voľnou rukou" + +#: ../../po/../src/rect-context.cpp:387 +msgid "" +"Ctrl: make square or integer-ratio rect, lock a rounded corner " +"circular" +msgstr "" + +#: ../../po/../src/rect-context.cpp:549 +#, fuzzy, c-format +msgid "" +"Rectangle: %s × %s; with Ctrl to make square or integer-" +"ratio rectangle; with Shift to draw around the starting point" +msgstr "" +"Elipsa: %s x %s; s Ctrl na vytvorenie kruhu alebo celočíselnú " +"elipsu so Shift na kreslenie okolo Å¡tartovacieho bodu" + +#: ../../po/../src/select-context.cpp:243 +msgid "Move canceled." +msgstr "Presun zruÅ¡ený." + +#: ../../po/../src/select-context.cpp:252 +msgid "Selection canceled." +msgstr "Výber zruÅ¡ený." + +#: ../../po/../src/select-context.cpp:642 +msgid "Ctrl: select in groups, move hor/vert" +msgstr "" + +#: ../../po/../src/select-context.cpp:643 +msgid "Shift: toggle select, force rubberband, disable snapping" +msgstr "" + +#: ../../po/../src/select-context.cpp:644 +msgid "Alt: select under, move selected" +msgstr "" + +#: ../../po/../src/select-context.cpp:798 +#, fuzzy +msgid "Selected object is not a group. Cannot enter." +msgstr "Zvolený objekt nie je cesta, nie je možné ho posunúť dnu/von." + +#: ../../po/../src/select-context.cpp:876 +#, c-format +msgid "" +"Move by %s, %s; with Ctrl to restrict to horizontal/vertical; " +"with Shift to disable snapping" +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:228 +msgid "Nothing was deleted." +msgstr "Nič nebolo zmazané." + +#: ../../po/../src/selection-chemistry.cpp:259 +msgid "Select object(s) to duplicate." +msgstr "Vyberte objekt, ktorá sa má duplikovaÅ¥." + +#: ../../po/../src/selection-chemistry.cpp:420 +msgid "Select two or more objects to group." +msgstr "Vyberte dva alebo viac objektov, ktoré sa majú zoskupiÅ¥." + +#: ../../po/../src/selection-chemistry.cpp:428 +msgid "Select at least two objects to group." +msgstr "Vyberte najmenej dva objekty, ktoré sa majú zoskupiÅ¥." + +#: ../../po/../src/selection-chemistry.cpp:513 +msgid "Select a group to ungroup." +msgstr "Vyberte skupinu, na odstránenie zoskupenia." + +#: ../../po/../src/selection-chemistry.cpp:554 +#, fuzzy +msgid "No groups to ungroup in the selection." +msgstr "Vo výbere nie sú objekty, ktoré je možné konvertovaÅ¥ na cesty." + +#: ../../po/../src/selection-chemistry.cpp:623 +msgid "Select objects to raise." +msgstr "Vyberte objekt, ktorý sa má presunúť vyÅ¡Å¡ie." + +#: ../../po/../src/selection-chemistry.cpp:629 +#: ../../po/../src/selection-chemistry.cpp:681 +#: ../../po/../src/selection-chemistry.cpp:715 +#: ../../po/../src/selection-chemistry.cpp:773 +msgid "" +"You cannot raise/lower objects from different groups or layers." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:673 +msgid "Select object(s) to raise to top." +msgstr "Vyberte objekt, ktorý sa má presunúť na vrchol." + +#: ../../po/../src/selection-chemistry.cpp:709 +msgid "Select object(s) to lower." +msgstr "Vyberte objekt, ktorý sa má presunúť nižšie." + +#: ../../po/../src/selection-chemistry.cpp:765 +msgid "Select object(s) to lower to bottom." +msgstr "Vyberte objekt, ktorý sa má presunúť dole." + +#: ../../po/../src/selection-chemistry.cpp:806 +msgid "Nothing to undo." +msgstr "Nie je čo vrátiÅ¥ späť." + +#: ../../po/../src/selection-chemistry.cpp:813 +msgid "Nothing to redo." +msgstr "Nie je čo opakovaÅ¥." + +#: ../../po/../src/selection-chemistry.cpp:969 +msgid "Nothing was copied." +msgstr "Nič nebolo skopírované." + +#: ../../po/../src/selection-chemistry.cpp:1051 +msgid "Current layer is hidden. Unhide it to be able to paste to it." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1055 +msgid "Current layer is locked. Unlock it to be able to paste to it." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1068 +#: ../../po/../src/selection-chemistry.cpp:1103 +msgid "Nothing on the clipboard." +msgstr "V schránke nič nie je." + +#: ../../po/../src/selection-chemistry.cpp:1109 +msgid "Select object(s) to paste style to." +msgstr "Vyberte objekt, na ktorý sa má použiÅ¥ Å¡týl." + +#: ../../po/../src/selection-chemistry.cpp:1128 +#, fuzzy +msgid "Select object(s) to move to the layer above." +msgstr "Vyberte objekt, ktorá sa má konvertovaÅ¥ na cestu." + +#: ../../po/../src/selection-chemistry.cpp:1146 +#, fuzzy +msgid "No more layers above." +msgstr "Neexistuje aktuálna vrstva." + +#: ../../po/../src/selection-chemistry.cpp:1160 +#, fuzzy +msgid "Select object(s) to move to the layer below." +msgstr "Vyberte objekt, ktorá sa má konvertovaÅ¥ na cestu." + +#: ../../po/../src/selection-chemistry.cpp:1178 +#, fuzzy +msgid "No more layers below." +msgstr "Neexistuje aktuálna vrstva." + +#: ../../po/../src/selection-chemistry.cpp:1811 +msgid "Select a clone to unlink." +msgstr "Vyberte klon, ktorý sa má odpojiÅ¥." + +#: ../../po/../src/selection-chemistry.cpp:1842 +#, fuzzy +msgid "No clones to unlink in the selection." +msgstr "Vo výbere nie sú objekty, ktoré je možné konvertovaÅ¥ na cesty." + +#: ../../po/../src/selection-chemistry.cpp:1859 +msgid "" +"Select a clone to go to its original. Select a linked offset " +"to go to its source. Select a text on path to go to the path. Select " +"a flowed text to go to its frame." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1882 +msgid "" +"Cannot find the object to select (orphaned clone, offset, textpath, " +"flowed text?)" +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1888 +msgid "" +"The object you're trying to select is not visible (it is in <" +"defs>)" +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1915 +#, fuzzy +msgid "Select object(s) to convert to pattern." +msgstr "Vyberte objekt, ktorá sa má konvertovaÅ¥ na cestu." + +#: ../../po/../src/selection-chemistry.cpp:2006 +#, fuzzy +msgid "Select an object with pattern fill to extract objects from." +msgstr "Vyberte objekty so vzorkou na oddláždenie." + +#: ../../po/../src/selection-chemistry.cpp:2059 +#, fuzzy +msgid "No pattern fills in the selection." +msgstr "Výber neobsahuje text na ceste." + +#: ../../po/../src/selection-chemistry.cpp:2079 +msgid "Select object(s) to make a bitmap copy." +msgstr "Vyberte objekt na vytvorenie bitmapovej kópie." + +#: ../../po/../src/selection-describer.cpp:37 +msgid "Click selection to toggle scale/rotation handles" +msgstr "Kliknutím na výber sa prepne ovládanie medzi zmenou mierky a rotáciou" + +#. no items +#: ../../po/../src/selection-describer.cpp:39 +msgid "" +"No objects selected. Click, Shift+click, or drag around objects to select." +msgstr "" + +#: ../../po/../src/selection-describer.cpp:51 +#, fuzzy, c-format +msgid " in layer %s" +msgstr "Chyba pri vytváraní vrstvy" + +#: ../../po/../src/selection-describer.cpp:54 +#, fuzzy, c-format +msgid " in layer %s" +msgstr "Chyba pri vytváraní vrstvy" + +#: ../../po/../src/selection-describer.cpp:66 +#, fuzzy +msgid "Use Shift+D to look up original" +msgstr "" +"Prepojený posun, %s o %f bd. Použite Shift+D na vyhľadanie " +"originálu" + +#: ../../po/../src/selection-describer.cpp:70 +#, fuzzy +msgid "Use Shift+D to look up path" +msgstr "" +"Prepojený posun, %s o %f bd. Použite Shift+D na vyhľadanie " +"originálu" + +#: ../../po/../src/selection-describer.cpp:74 +#, fuzzy +msgid "Use Shift+D to look up frame" +msgstr "" +"Prepojený posun, %s o %f bd. Použite Shift+D na vyhľadanie " +"originálu" + +#: ../../po/../src/selection-describer.cpp:84 +#, fuzzy, c-format +msgid "%i object selected" +msgid_plural "%i objects selected" +msgstr[0] "ZvýšiÅ¥ vybrané objekty" +msgstr[1] "%i zvolených objektov. %s." +msgstr[2] "%i zvolených objektov. %s." + +#: ../../po/../src/selection-describer.cpp:90 +#, c-format +msgid "%s%s. %s." +msgstr "%s%s. %s." + +#: ../../po/../src/selection-describer.cpp:94 +#, c-format +msgid "%s in %i layer. %s." +msgid_plural "%s in %i layers. %s." +msgstr[0] "%s v %i vrstve. %s." +msgstr[1] "%s v %i vrstvách. %s." +msgstr[2] "%s v %i vrstvách. %s." + +#: ../../po/../src/seltrans.cpp:498 +msgid "" +"Center of rotation and skewing: drag to reposition; scaling with " +"Shift also uses this center" +msgstr "" + +#: ../../po/../src/seltrans.cpp:514 +msgid "" +"Squeeze or stretch selection; with Ctrl to scale uniformly; " +"with Shift to scale around rotation center" +msgstr "" + +#: ../../po/../src/seltrans.cpp:515 +msgid "" +"Scale selection; with Ctrl to scale uniformly; with Shift to scale around rotation center" +msgstr "" + +#: ../../po/../src/seltrans.cpp:519 +#, fuzzy +msgid "" +"Skew selection; with Ctrl to snap angle; with Shift to " +"skew around the opposite side" +msgstr "" +"Elipsa: %s x %s; s Ctrl na vytvorenie kruhu alebo celočíselnú " +"elipsu so Shift na kreslenie okolo Å¡tartovacieho bodu" + +#: ../../po/../src/seltrans.cpp:520 +msgid "" +"Rotate selection; with Ctrl to snap angle; with Shift " +"to rotate around the opposite corner" +msgstr "" + +#: ../../po/../src/seltrans.cpp:829 ../../po/../src/seltrans.cpp:909 +#, c-format +msgid "Scale: %0.2f%% x %0.2f%%; with Ctrl to lock ratio" +msgstr "" + +#. TRANSLATORS: don't modify the first ";" (it will NOT be displayed as ";" - only the second one will be) +#: ../../po/../src/seltrans.cpp:984 +#, c-format +msgid "Skew: %0.2f°; with Ctrl to snap angle" +msgstr "" + +#. TRANSLATORS: don't modify the first ";" (it will NOT be displayed as ";" - only the second one will be) +#: ../../po/../src/seltrans.cpp:1035 +#, c-format +msgid "Rotate: %0.2f°; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/seltrans.cpp:1090 +#, c-format +msgid "Move center to %s, %s" +msgstr "Presunúť stred do %s, %s" + +#: ../../po/../src/slideshow.cpp:90 +msgid "Inkscape slideshow" +msgstr "Premietanie snímkov Inkscape" + +#: ../../po/../src/sp-anchor.cpp:181 +#, c-format +msgid "Link to %s" +msgstr "Odkaz na %s" + +#: ../../po/../src/sp-anchor.cpp:185 +#, fuzzy +msgid "Link without URI" +msgstr "Index aktuálneho URI" + +#: ../../po/../src/sp-ellipse.cpp:438 ../../po/../src/sp-ellipse.cpp:870 +msgid "Ellipse" +msgstr "Elipsa" + +#: ../../po/../src/sp-ellipse.cpp:583 +msgid "Circle" +msgstr "Kruh" + +#: ../../po/../src/sp-ellipse.cpp:865 +#, fuzzy +msgid "Segment" +msgstr "Nový:" + +#: ../../po/../src/sp-ellipse.cpp:867 +msgid "Arc" +msgstr "Oblúk" + +#. TRANSLATORS: "Flow region" is an area where text is allowed to flow +#: ../../po/../src/sp-flowregion.cpp:276 +#, fuzzy +msgid "Flow region" +msgstr "_NasledovaÅ¥ odkaz" + +#. TRANSLATORS: A region "cut out of" a flow region; text is not allowed to flow inside the +#. * flow excluded region. flowRegionExclude in SVG 1.2: see +#. * http://www.w3.org/TR/2004/WD-SVG12-20041027/flow.html#flowRegion-elem and +#. * http://www.w3.org/TR/2004/WD-SVG12-20041027/flow.html#flowRegionExclude-elem. +#: ../../po/../src/sp-flowregion.cpp:493 +msgid "Flow excluded region" +msgstr "" + +#: ../../po/../src/sp-flowtext.cpp:355 +#, c-format +msgid "Flowed text (%d characters)" +msgstr "" + +#: ../../po/../src/sp-flowtext.cpp:357 +#, c-format +msgid "Linked flowed text (%d characters)" +msgstr "" + +#: ../../po/../src/sp-guide.cpp:290 +msgid "vertical guideline" +msgstr "Zvislé vodítko" + +#: ../../po/../src/sp-guide.cpp:292 +msgid "horizontal guideline" +msgstr "Vodorovné vodítko" + +#: ../../po/../src/sp-image.cpp:835 +msgid "embedded" +msgstr "" + +#: ../../po/../src/sp-image.cpp:839 +msgid "(null_pointer)" +msgstr "" + +#: ../../po/../src/sp-image.cpp:843 +#, c-format +msgid "Image with bad reference: %s" +msgstr "Obrázok so zlým odkazom: %s" + +#: ../../po/../src/sp-image.cpp:844 +#, fuzzy, c-format +msgid "Image %d × %d: %s" +msgstr "Obrázok %d x %d: %s" + +#: ../../po/../src/sp-item-group.cpp:390 +#, fuzzy, c-format +msgid "Group of %d object" +msgid_plural "Group of %d objects" +msgstr[0] "Å tandardy objektu" +msgstr[1] "Zo_skupenie %d objektov" +msgstr[2] "Zo_skupenie %d objektov" + +#: ../../po/../src/sp-item.cpp:720 +msgid "Object" +msgstr "Objekt" + +#: ../../po/../src/sp-line.cpp:202 +#, fuzzy +msgid "Line" +msgstr "Nový:" + +#. TRANSLATORS COMMENT: %s is either "outset" or "inset" depending on sign +#: ../../po/../src/sp-offset.cpp:433 +#, fuzzy, c-format +msgid "Linked offset, %s by %f pt" +msgstr "Dynamický posun, %s o %f bd" + +#: ../../po/../src/sp-offset.cpp:434 ../../po/../src/sp-offset.cpp:438 +msgid "outset" +msgstr "posun von" + +#: ../../po/../src/sp-offset.cpp:434 ../../po/../src/sp-offset.cpp:438 +msgid "inset" +msgstr "posun dnu" + +#. TRANSLATORS COMMENT: %s is either "outset" or "inset" depending on sign +#: ../../po/../src/sp-offset.cpp:437 +#, c-format +msgid "Dynamic offset, %s by %f pt" +msgstr "Dynamický posun, %s o %f bd" + +#: ../../po/../src/sp-path.cpp:127 +#, fuzzy, c-format +msgid "Path (%i node)" +msgid_plural "Path (%i nodes)" +msgstr[0] "Centrum uzlov" +msgstr[1] "Cesta (%i uzly)" +msgstr[2] "Cesta (%i uzly)" + +#: ../../po/../src/sp-polygon.cpp:216 +#, fuzzy +msgid "Polygon" +msgstr "Mnohouholník" + +#: ../../po/../src/sp-polyline.cpp:179 +#, fuzzy +msgid "Polyline" +msgstr "Elipsa" + +#: ../../po/../src/sp-rect.cpp:250 +msgid "Rectangle" +msgstr "Obdĺžnik" + +#. TRANSLATORS: since turn count isn't an integer, please adjust the +#. string as needed to deal with an localized plural forms. +#: ../../po/../src/sp-spiral.cpp:305 +#, c-format +msgid "Spiral with %3f turns" +msgstr "Å pirála s %3f otočeniami" + +#: ../../po/../src/sp-star.cpp:288 +#, fuzzy, c-format +msgid "Star with %d vertex" +msgid_plural "Star with %d vertices" +msgstr[0] "Hviezda s %d vrcholmi" +msgstr[1] "Hviezda s %d vrcholmi" +msgstr[2] "Hviezda s %d vrcholmi" + +#: ../../po/../src/sp-star.cpp:292 +#, fuzzy, c-format +msgid "Polygon with %d vertex" +msgid_plural "Polygon with %d vertices" +msgstr[0] "Mnohouholník s %d vrcholmi" +msgstr[1] "Mnohouholník s %d vrcholmi" +msgstr[2] "Mnohouholník s %d vrcholmi" + +#. TRANSLATORS: For description of font with no name. +#: ../../po/../src/sp-text.cpp:420 +msgid "<no name found>" +msgstr "<názov nebol nájdený>" + +#: ../../po/../src/sp-text.cpp:426 +#, fuzzy, c-format +msgid "Text on path (%s, %s)" +msgstr "UmiestniÅ¥ text na cestu" + +#: ../../po/../src/sp-text.cpp:427 +#, c-format +msgid "Text (%s, %s)" +msgstr "Text (%s, %s)" + +#. TRANSLATORS: Used for statusbar description for long chains: +#. * "Clone of: Clone of: ... in Layer 1". +#: ../../po/../src/sp-use.cpp:317 +#, fuzzy +msgid "..." +msgstr "_OtvoriÅ¥..." + +#: ../../po/../src/sp-use.cpp:325 +#, c-format +msgid "Clone of: %s" +msgstr "Klonovanie of: %s" + +#: ../../po/../src/sp-use.cpp:329 +msgid "Orphaned clone" +msgstr "Osirotený klon" + +#: ../../po/../src/spiral-context.cpp:355 +msgid "Ctrl: snap angle" +msgstr "Ctrl: zlomiÅ¥ uhol" + +#: ../../po/../src/spiral-context.cpp:357 +msgid "Alt: lock spiral radius" +msgstr "" + +#: ../../po/../src/spiral-context.cpp:469 +#, c-format +msgid "" +"Spiral: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/splivarot.cpp:106 +msgid "Select at least 2 paths to perform a boolean operation." +msgstr "Vyberte najmenej 2 cesty na vykonanie logickej operácie." + +#: ../../po/../src/splivarot.cpp:112 +msgid "" +"Select exactly 2 paths to perform difference, XOR, division, or path " +"cut." +msgstr "" + +#: ../../po/../src/splivarot.cpp:129 ../../po/../src/splivarot.cpp:144 +msgid "" +"Unable to determine the z-order of the objects selected for " +"difference, XOR, division, or path cut." +msgstr "" + +#: ../../po/../src/splivarot.cpp:174 +msgid "" +"One of the objects is not a path, cannot perform boolean operation." +msgstr "" +"Jeden z objektov nie je cesta, nie je možné vykonaÅ¥ logickú operáciu." + +#. TRANSLATORS: "to outline" means "to convert stroke to path" +#: ../../po/../src/splivarot.cpp:554 +#, fuzzy +msgid "Select path(s) to outline." +msgstr "/Výber/Do cesty" + +#. TRANSLATORS: "to outline" means "to convert stroke to path" +#: ../../po/../src/splivarot.cpp:748 +msgid "No stroked paths to outline in the selection." +msgstr "" + +#: ../../po/../src/splivarot.cpp:832 +msgid "Selected object is not a path, cannot inset/outset." +msgstr "Zvolený objekt nie je cesta, nie je možné ho posunúť dnu/von." + +#: ../../po/../src/splivarot.cpp:1040 +msgid "Select path(s) to inset/outset." +msgstr "VybraÅ¥ cestu na posun dnu/von." + +#: ../../po/../src/splivarot.cpp:1257 +msgid "No paths to inset/outset in the selection." +msgstr "Výber neobsahuje cestu na posun dnu/von." + +#: ../../po/../src/splivarot.cpp:1390 +msgid "Select path(s) to simplify." +msgstr "VybraÅ¥ cestu na zjednoduÅ¡enie." + +#: ../../po/../src/splivarot.cpp:1417 +#, fuzzy +msgid "No paths to simplify in the selection." +msgstr "Výber neobsahuje text na ceste." + +#: ../../po/../src/star-context.cpp:362 +msgid "Ctrl: snap angle; keep rays radial" +msgstr "" + +#: ../../po/../src/star-context.cpp:470 +#, c-format +msgid "" +"Polygon: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/star-context.cpp:471 +#, c-format +msgid "Star: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/text-chemistry.cpp:90 +msgid "Select a text and a path to put text on path." +msgstr "VybraÅ¥ text a cestu na umiestnenie na cestu." + +#: ../../po/../src/text-chemistry.cpp:95 +msgid "" +"This text object is already put to a path. Remove it from the path " +"first. Use Shift+D to look up its path." +msgstr "" + +#. rect is the only SPShape which is not yet, and thus SVG forbids us from putting text on it +#: ../../po/../src/text-chemistry.cpp:101 +msgid "" +"You cannot put text on a rectangle in this version. Convert rectangle to " +"path first." +msgstr "" + +#: ../../po/../src/text-chemistry.cpp:159 +msgid "Select a text on path to remove it from path." +msgstr "VybraÅ¥ text a cestu na odstránenie z cesty." + +#: ../../po/../src/text-chemistry.cpp:181 +msgid "No texts-on-paths in the selection." +msgstr "Výber neobsahuje text na ceste." + +#: ../../po/../src/text-chemistry.cpp:209 +#: ../../po/../src/text-chemistry.cpp:229 +#, fuzzy +msgid "Select text(s) to remove kerns from." +msgstr "VybraÅ¥ text a cestu na odstránenie z cesty." + +#: ../../po/../src/text-chemistry.cpp:250 +#, fuzzy +msgid "" +"Select a text and one or more paths or shapes to flow text " +"into frame." +msgstr "VybraÅ¥ text a cestu na umiestnenie na cestu." + +#: ../../po/../src/text-chemistry.cpp:322 +#, fuzzy +msgid "Select a flowed text to unflow it." +msgstr "/Výber/Do cesty" + +#: ../../po/../src/text-context.cpp:463 +msgid "Click to edit the text, drag to select part of the text." +msgstr "" + +#: ../../po/../src/text-context.cpp:465 +msgid "" +"Click to edit the flowed text, drag to select part of the text." +msgstr "" + +#: ../../po/../src/text-context.cpp:540 +msgid "Non-printable character" +msgstr "Netlačiteľný znak" + +#: ../../po/../src/text-context.cpp:589 +#, fuzzy, c-format +msgid "Unicode: %s: %s" +msgstr "Unicode: " + +#: ../../po/../src/text-context.cpp:591 ../../po/../src/text-context.cpp:855 +msgid "Unicode: " +msgstr "Unicode: " + +#: ../../po/../src/text-context.cpp:615 +msgid "Current layer is hidden. Unhide it to be able to add text." +msgstr "" + +#: ../../po/../src/text-context.cpp:619 +msgid "Current layer is locked. Unlock it to be able to add text." +msgstr "" + +#: ../../po/../src/text-context.cpp:673 +#, c-format +msgid "Flowed text frame: %s × %s" +msgstr "" + +#: ../../po/../src/text-context.cpp:708 ../../po/../src/text-context.cpp:1464 +msgid "Type text; Enter to start new line." +msgstr "" + +#: ../../po/../src/text-context.cpp:719 +msgid "Flowed text is created." +msgstr "" + +#: ../../po/../src/text-context.cpp:722 +msgid "" +"The frame is too small for the current font size. Flowed text not " +"created." +msgstr "" + +#: ../../po/../src/text-context.cpp:841 +msgid "No-break space" +msgstr "Nezlomiteľná medzera" + +#: ../../po/../src/text-context.cpp:1462 +msgid "Type flowed text; Enter to start new paragraph." +msgstr "" + +#: ../../po/../src/text-context.cpp:1472 ../../po/../src/tools-switch.cpp:189 +msgid "" +"Click to select or create text, drag to create flowed text; " +"then type." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:141 +msgid "" +"To edit a path, click, Shift+click, or drag around " +"nodes to select them, then drag nodes and handles. Click on an " +"object to select." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:147 +msgid "" +"Drag to create a rectangle. Drag controls to round corners and " +"resize. Click to select." +msgstr "Tvorba obdĺžnikov a Å¡tvorcov s možnosÅ¥ou oblých hrán" + +#: ../../po/../src/tools-switch.cpp:153 +msgid "" +"Drag to create an ellipse. Drag controls to make an arc or " +"segment. Click to select." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:159 +msgid "" +"Drag to create a star. Drag controls to edit the star shape. " +"Click to select." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:165 +msgid "" +"Drag to create a spiral. Drag controls to edit the spiral " +"shape. Click to select." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:171 +#, fuzzy +msgid "" +"Drag to create a freehand line. Start drawing with Shift to " +"append to selected path." +msgstr "" +"Ťahaním vytvoríte kaligrafickú čiaru. Stlačením 'a' na prepnete medzi " +"PridaÅ¥/Nový." + +#: ../../po/../src/tools-switch.cpp:177 +#, fuzzy +msgid "" +"Click or click and drag to start a path; with Shift to " +"append to selected path." +msgstr "" +"Kliknutím vytvoríte uzol. Kliknutím a Å¥ahaním vytvoríte hladký uzol. " +"Stlačením 'a' na prepnete medzi PridaÅ¥/Nový." + +#: ../../po/../src/tools-switch.cpp:183 +msgid "" +"Drag to paint a calligraphic stroke. Left/right arrow " +"keys adjust width, up/down adjust angle." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:195 +#, fuzzy +msgid "" +"Drag or double click to create a gradient on selected objects, " +"drag handles to adjust gradients." +msgstr "" +"Ťahaním vytvoríte kaligrafickú čiaru. Stlačením 'a' na prepnete medzi " +"PridaÅ¥/Nový." + +#: ../../po/../src/tools-switch.cpp:201 +msgid "" +"Click or drag around an area to zoom in, Shift+click to " +"zoom out." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:213 +msgid "Click and drag between shapes to create a connector." +msgstr "" + +#: ../../po/../src/trace/potrace/inkscape-potrace.cpp:553 +#: ../../po/../src/trace/potrace/inkscape-potrace.cpp:654 +#, c-format +msgid "Trace: %d. %ld nodes" +msgstr "" + +#: ../../po/../src/trace/trace.cpp:53 ../../po/../src/trace/trace.cpp:62 +#: ../../po/../src/trace/trace.cpp:70 +#, fuzzy +msgid "Select an image to trace" +msgstr "/Výber/Do cesty" + +#: ../../po/../src/trace/trace.cpp:133 +msgid "Trace: No active document" +msgstr "Prekreslenie (trace): Nie je aktívny dokument" + +#: ../../po/../src/trace/trace.cpp:154 +msgid "Trace: Image has no bitmap data" +msgstr "Prekreslenie (trace): Obrázok nemá bitmapové dáta" + +#: ../../po/../src/trace/trace.cpp:267 +#, c-format +msgid "Trace: Done. %ld nodes created" +msgstr "" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:59 ../../po/../src/verbs.cpp:2212 +msgid "About Inkscape" +msgstr "O Inkscape" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:66 +msgid "_Splash" +msgstr "" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:68 +msgid "_Authors" +msgstr "" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:69 +#, fuzzy +msgid "_Translators" +msgstr "Transformácie" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:70 +#, fuzzy +msgid "_License" +msgstr "Licencia" + +#. TRANSLATORS: This is the filename of the `About Inkscape' picture in +#. the `screens' directory. Thus the translation of "about.svg" should be +#. the filename of its translated version, e.g. about.zh.svg for Chinese. +#. +#. N.B. about.svg changes once per release. (We should probably rename +#. the original to about-0.40.svg etc. as soon as we have a translation. +#. If we do so, then add an item to release-checklist saying that the +#. string here should be changed.) +#. FIXME? INKSCAPE_SCREENSDIR and "about.svg" are in UTF-8, not the +#. native filename encoding... and the filename passed to sp_document_new +#. should be in UTF-*8.. +#: ../../po/../src/ui/dialog/aboutbox.cpp:114 +msgid "about.svg" +msgstr "about.svg" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:464 +msgid "Minimum horizontal gap (in px units) between bounding boxes" +msgstr "" + +#. TRANSLATORS: Horizontal gap +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:466 +#: ../../po/../src/widgets/toolbox.cpp:1556 +#, fuzzy +msgid "H:" +msgstr "_H" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:474 +msgid "Minimum vertical gap (in px units) between bounding boxes" +msgstr "" + +#. TRANSLATORS: Vertical gap +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:476 +msgid "V:" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:734 +msgid "Align" +msgstr "ZarovnaÅ¥" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:735 +msgid "Distribute" +msgstr "RozmiestniÅ¥" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:736 +msgid "Remove overlaps" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:737 +#, fuzzy +msgid "Nodes" +msgstr "Uzol" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:742 +msgid "Relative to: " +msgstr "Relatívne k: " + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:747 +#, fuzzy +msgid "Align right sides of objects to left side of anchor" +msgstr "Pravá strana zarovnania objektov k ľavej strane ukotvenia" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:750 +#, fuzzy +msgid "Align left sides" +msgstr "Zarovnanie uzlov" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:753 +#, fuzzy +msgid "Center on vertical axis" +msgstr "CentrovaÅ¥ zvislo" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:756 +#, fuzzy +msgid "Align right sides" +msgstr "Zarovnanie čiar doprava" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:759 +#, fuzzy +msgid "Align left sides of objects to right side of anchor" +msgstr "Ľavá strana zarovnania objektov k pravej strane ukotvenia" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:762 +#, fuzzy +msgid "Align bottoms of objects to top of anchor" +msgstr "Spodná strana zarovnania objektov k hornej strane ukotvenia" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:765 +#, fuzzy +msgid "Align tops" +msgstr "Zarovnanie uzlov" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:768 +#, fuzzy +msgid "Center on horizontal axis" +msgstr "CentrovaÅ¥ vodorovne" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:771 +#, fuzzy +msgid "Align bottoms" +msgstr "Zarovnanie uzlov" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:774 +#, fuzzy +msgid "Align tops of objects to bottom of anchor" +msgstr "Horná strana zarovnania objektov k spodku ukotvenia" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:779 +#, fuzzy +msgid "Align baseline anchors of texts vertically" +msgstr "Zvislé zarovnanie niekoľko uzlov" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:782 +#, fuzzy +msgid "Align baseline anchors of texts horizontally" +msgstr "Vodorovné zarovnanie niekoľko uzlov" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:787 +#, fuzzy +msgid "Make horizontal gaps between objects equal" +msgstr "Rovnomerne vodorovne rozmiestniÅ¥ objekty" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:791 +#, fuzzy +msgid "Distribute left sides equidistantly" +msgstr "Rovnomerne rozmiestniÅ¥ ľavé strany objektov" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:794 +#, fuzzy +msgid "Distribute centers equidistantly horizontally" +msgstr "Rovnomerne vodorovne rozmiestniÅ¥ stredy objektov" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:797 +#, fuzzy +msgid "Distribute right sides equidistantly" +msgstr "Rovnomerne rozmiestniÅ¥ pravé strany objektov" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:801 +#, fuzzy +msgid "Make vertical gaps between objects equal" +msgstr "Rovnomerne zvislo rozmiestniÅ¥ objekty" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:805 +#, fuzzy +msgid "Distribute tops equidistantly" +msgstr "Zvislo rozmiestniÅ¥ zvolené uzly" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:808 +#, fuzzy +msgid "Distribute centers equidistantly vertically" +msgstr "Rovnomerne zvislo rozmiestniÅ¥ stredy objektov" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:811 +#, fuzzy +msgid "Distribute bottoms equidistantly" +msgstr "Rovnomerne rozmiestniÅ¥ dolné strany objektov" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:816 +#, fuzzy +msgid "Distribute baseline anchors of texts horizontally" +msgstr "Vodorovne rozmiestniÅ¥ zvolené uzly" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:819 +#, fuzzy +msgid "Distribute baseline anchors of texts vertically" +msgstr "Zvislo rozmiestniÅ¥ zvolené uzly" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:824 +msgid "Randomize centers in both dimensions" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:827 +msgid "Unclump objects: try to equalize edge-to-edge distances" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:832 +msgid "" +"Move objects as little as possible so that their bounding boxes do not " +"overlap" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:837 +msgid "Align selected nodes horizontally" +msgstr "Vodorovné zarovnanie niekoľko uzlov" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:840 +msgid "Align selected nodes vertically" +msgstr "Zvislé zarovnanie niekoľko uzlov" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:843 +msgid "Distribute selected nodes horizontally" +msgstr "Vodorovne rozmiestniÅ¥ zvolené uzly" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:846 +msgid "Distribute selected nodes vertically" +msgstr "Zvislo rozmiestniÅ¥ zvolené uzly" + +#. Rest of the widgetry +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:851 +msgid "Last selected" +msgstr "Naposledy zvolené" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:852 +msgid "First selected" +msgstr "Prvé zvolené" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:853 +msgid "Biggest item" +msgstr "Najväčšia položka" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:854 +msgid "Smallest item" +msgstr "NajmenÅ¡ia položka" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:856 +#: ../../po/../src/widgets/desktop-widget.cpp:1065 +msgid "Drawing" +msgstr "Kresba" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:91 +#, fuzzy +msgid "Metadata 1" +msgstr "Metadáta" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:92 +#, fuzzy +msgid "Metadata 2" +msgstr "Metadáta" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:187 +#, fuzzy +msgid "X coordinate of grid origin" +msgstr "Zvislé súradnice výberu" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:189 +#, fuzzy +msgid "Y coordinate of grid origin" +msgstr "Zvislé súradnice výberu" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:191 +#, fuzzy +msgid "Distance of vertical grid lines" +msgstr "Zvislé vodítko" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:193 +#, fuzzy +msgid "Distance of horizontal grid lines" +msgstr "Vodorovné vodítko" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:197 +msgid "Max. snapping distance from grid" +msgstr "" + +#: ../../po/../src/ui/dialog/export.cpp:34 +msgid "Export" +msgstr "Export" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:36 +msgid "Fill" +msgstr "Výplň" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:37 +#, fuzzy +msgid "Stroke Paint" +msgstr "Farba Å¥ahu" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:38 +#, fuzzy +msgid "Stroke Style" +msgstr "Å týl Å¥ahu" + +#: ../../po/../src/ui/dialog/find.cpp:34 +#, fuzzy +msgid "Find" +msgstr "_HľadaÅ¥" + +#: ../../po/../src/ui/dialog/memory.cpp:96 +#, fuzzy +msgid "Heap" +msgstr "_Pomocník" + +#: ../../po/../src/ui/dialog/memory.cpp:97 +#, fuzzy +msgid "In Use" +msgstr "InvertovaÅ¥" + +#. TRANSLATORS: "Slack" refers to memory which is in the heap but currently unused. +#. More typical usage is to call this memory "free" rather than "slack". +#: ../../po/../src/ui/dialog/memory.cpp:100 +#, fuzzy +msgid "Slack" +msgstr "Zásobník" + +#: ../../po/../src/ui/dialog/memory.cpp:101 +#, fuzzy +msgid "Total" +msgstr "Titulok" + +#: ../../po/../src/ui/dialog/memory.cpp:141 +#: ../../po/../src/ui/dialog/memory.cpp:147 +#: ../../po/../src/ui/dialog/memory.cpp:154 +#: ../../po/../src/ui/dialog/memory.cpp:186 +#, fuzzy +msgid "Unknown" +msgstr "Z_jednotenie" + +#: ../../po/../src/ui/dialog/memory.cpp:167 +#, fuzzy +msgid "Combined" +msgstr "_Kombinácia" + +#: ../../po/../src/ui/dialog/memory.cpp:209 +#, fuzzy +msgid "Recalculate" +msgstr "Obdĺžnik" + +#: ../../po/../src/ui/dialog/messages.cpp:74 +#, fuzzy +msgid "Ready." +msgstr "_Červená" + +#: ../../po/../src/ui/dialog/messages.cpp:75 +msgid "" +"Enable log display by setting dialogs.debug 'redirect' attribute to 1 in " +"preferences.xml" +msgstr "" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:184 +msgid "_Execute Python" +msgstr "_SpustiÅ¥ Python" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:186 +msgid "_Execute Perl" +msgstr "_SpustiÅ¥ Perl" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:195 +msgid "Script" +msgstr "Skript" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:205 +msgid "Output" +msgstr "Výstup" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:215 +msgid "Errors" +msgstr "Chyby" + +#. Dialog organization +#: ../../po/../src/ui/dialog/session-player.cpp:73 +msgid "Session file" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:74 +#, fuzzy +msgid "Playback controls" +msgstr "Ovládanie nástrojov" + +#: ../../po/../src/ui/dialog/session-player.cpp:75 +#, fuzzy +msgid "Message information" +msgstr "ZruÅ¡iÅ¥ _transformáciu" + +#. Active session file display +#. fixme: Does this mean the active file for the session, or the file for the active session? +#. Please indicate which with a TRANSLATORS comment. +#: ../../po/../src/ui/dialog/session-player.cpp:85 +msgid "Active session file:" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:86 +msgid "Delay (milliseconds):" +msgstr "" + +#. Unload/load buttons +#: ../../po/../src/ui/dialog/session-player.cpp:94 +#, fuzzy +msgid "Close file" +msgstr "ZatvoriÅ¥" + +#: ../../po/../src/ui/dialog/session-player.cpp:95 +msgid "Open new file" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:96 +#, fuzzy +msgid "Set delay" +msgstr "NastaviÅ¥ ako Å¡tandardné" + +#: ../../po/../src/ui/dialog/session-player.cpp:138 +#, fuzzy +msgid "Rewind" +msgstr "_Červená" + +#: ../../po/../src/ui/dialog/session-player.cpp:139 +msgid "Go back one change" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:140 +#, fuzzy +msgid "Pause" +msgstr "_VložiÅ¥" + +#: ../../po/../src/ui/dialog/session-player.cpp:141 +msgid "Go forward one change" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:142 +msgid "Play" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:177 +#: ../../po/../src/verbs.cpp:1573 +msgid "Open session file" +msgstr "" + +#. ##Set up the Potrace panel +#. #### brightness #### +#. #### Multiple scanning#### +#. ----Hbox1 +#: ../../po/../src/ui/dialog/tracedialog.cpp:345 +#: ../../po/../src/ui/dialog/tracedialog.cpp:428 +msgid "Brightness" +msgstr "Jas" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:348 +msgid "Trace by a given brightness level" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:355 +#, fuzzy +msgid "Brightness cutoff for black/white" +msgstr "Čiernobielo pre väčšie časti textov" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:362 +msgid "Image Brightness" +msgstr "Jas obrázku" + +#. #### canny edge detection #### +#. TRANSLATORS: "Canny" is the name of the inventor of this edge detection method +#: ../../po/../src/ui/dialog/tracedialog.cpp:369 +msgid "Optimal Edge Detection (Canny)" +msgstr "Optimálna detekcia hrán (canny)" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:372 +msgid "Trace with edge detection by J. Canny's algorithm" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:388 +msgid "Brightness cutoff for adjacent pixels (determines edge thickness)" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:395 +msgid "Edge Detection" +msgstr "Detekcia hrán" + +#. #### quantization #### +#. TRANSLATORS: Color Quantization: the process of reducing the number of colors +#. in an image by selecting an optimized set of representative colors and then +#. re-applying this reduced set to the original image. +#: ../../po/../src/ui/dialog/tracedialog.cpp:404 +msgid "Color Quantization" +msgstr "Kvantizácia farby" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:407 +msgid "Trace along the boundaries of reduced colors" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:414 +#, fuzzy +msgid "The number of reduced colors" +msgstr "Počet jedinečných farieb: %d" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:416 +msgid "Colors:" +msgstr "Farby:" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:421 +msgid "Quantization / Reduction" +msgstr "Kvantizácia/Redukcia" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:431 +msgid "Trace the given number of brightness levels" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:438 +msgid "Scans:" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:440 +#, fuzzy +msgid "The desired number of scans" +msgstr "Počet úrovní funkcie VrátiÅ¥ späť:" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:448 +msgid "Trace the given number of reduced colors" +msgstr "" + +#. ---Hbox3 +#: ../../po/../src/ui/dialog/tracedialog.cpp:454 +msgid "Monochrome" +msgstr "Monochromaticky" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:457 +msgid "Same as Color, but convert result to grayscale" +msgstr "" + +#. TRANSLATORS: "Stack" is a verb here +#: ../../po/../src/ui/dialog/tracedialog.cpp:460 +msgid "Stack" +msgstr "Zásobník" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:463 +msgid "" +"Stack scans vertically (no gaps) or tile horizontally (usually with gaps)" +msgstr "" + +#. TRANSLATORS: "Smooth" is a verb here +#: ../../po/../src/ui/dialog/tracedialog.cpp:466 +msgid "Smooth" +msgstr "Hladké" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:469 +msgid "Apply Gaussian blur to the bitmap before tracing" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:473 +#, fuzzy +msgid "Multiple Scanning" +msgstr "Prehľadávam sieÅ¥..." + +#. #### Preview #### +#: ../../po/../src/ui/dialog/tracedialog.cpp:479 +#: ../../po/../src/ui/dialog/tracedialog.cpp:489 +msgid "Preview" +msgstr "Náhľad" + +#. do not expand +#: ../../po/../src/ui/dialog/tracedialog.cpp:483 +msgid "Preview the result without actual tracing" +msgstr "" + +#. #### swap black and white #### +#: ../../po/../src/ui/dialog/tracedialog.cpp:495 +msgid "Invert" +msgstr "InvertovaÅ¥" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:499 +msgid "Invert black and white regions for single traces" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:503 +msgid "Thanks to Peter Selinger, http://potrace.sourceforge.net" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:506 +msgid "Credits" +msgstr "Poďakovanie" + +#. done +#. TRANSLATORS: Potrace is an application for transforming bitmaps into +#. vector graphics (http://potrace.sourceforge.net/) +#: ../../po/../src/ui/dialog/tracedialog.cpp:514 +msgid "Potrace" +msgstr "Potrace" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:527 +#, fuzzy +msgid "Abort a trace in progress" +msgstr "Prebieha inÅ¡talácia zavádzača" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:531 +#, fuzzy +msgid "Execute the trace" +msgstr "Fraktálové trasovanie" + +#: ../../po/../src/ui/dialog/transformation.cpp:80 +#: ../../po/../src/ui/dialog/transformation.cpp:90 +#, fuzzy +msgid "_Horizontal" +msgstr "Vodorovný text" + +#: ../../po/../src/ui/dialog/transformation.cpp:80 +msgid "Horizontal displacement (relative) or position (absolute)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:82 +#: ../../po/../src/ui/dialog/transformation.cpp:92 +#, fuzzy +msgid "_Vertical" +msgstr "Zvislý text" + +#: ../../po/../src/ui/dialog/transformation.cpp:82 +msgid "Vertical displacement (relative) or position (absolute)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:84 +#, fuzzy +msgid "_Width" +msgstr "Šírka:" + +#: ../../po/../src/ui/dialog/transformation.cpp:84 +msgid "Horizontal size increment (absolute or percentage)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:86 +#, fuzzy +msgid "_Height" +msgstr "Výška:" + +#: ../../po/../src/ui/dialog/transformation.cpp:86 +msgid "Vertical size increment (absolute or percentage)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:88 +#, fuzzy +msgid "A_ngle" +msgstr "Uhol:" + +#: ../../po/../src/ui/dialog/transformation.cpp:88 +#, fuzzy +msgid "Rotation angle (positive = counterclockwise)" +msgstr "Otočí objekt o 90° doľava" + +#: ../../po/../src/ui/dialog/transformation.cpp:90 +msgid "" +"Horizontal skew angle (positive = counterclockwise), or absolute " +"displacement, or percentage displacement" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:92 +msgid "" +"Vertical skew angle (positive = counterclockwise), or absolute displacement, " +"or percentage displacement" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:95 +#, fuzzy +msgid "Transformation matrix element A" +msgstr "Transformačná matica" + +#: ../../po/../src/ui/dialog/transformation.cpp:96 +#, fuzzy +msgid "Transformation matrix element B" +msgstr "Transformačná matica" + +#: ../../po/../src/ui/dialog/transformation.cpp:97 +#, fuzzy +msgid "Transformation matrix element C" +msgstr "Transformačná matica" + +#: ../../po/../src/ui/dialog/transformation.cpp:98 +#, fuzzy +msgid "Transformation matrix element D" +msgstr "Transformačná matica" + +#: ../../po/../src/ui/dialog/transformation.cpp:99 +#, fuzzy +msgid "Transformation matrix element E" +msgstr "Transformačná matica" + +#: ../../po/../src/ui/dialog/transformation.cpp:100 +#, fuzzy +msgid "Transformation matrix element F" +msgstr "Transformačná matica" + +#: ../../po/../src/ui/dialog/transformation.cpp:102 +#, fuzzy +msgid "Rela_tive move" +msgstr "Relatívny posun" + +#: ../../po/../src/ui/dialog/transformation.cpp:102 +msgid "" +"Add the specified relative displacement to the current position; otherwise, " +"edit the current absolute position directly" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:103 +msgid "Scale proportionally" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:103 +msgid "Preserve the width/height ratio of the scaled objects" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:104 +msgid "Apply to each _object separately" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:104 +msgid "" +"Apply the scale/rotate/skew to each selected object separately; otherwise, " +"transform the selection as a whole" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:105 +#, fuzzy +msgid "Edit c_urrent matrix" +msgstr "ZvýšiÅ¥ aktuálnu vrstvu" + +#: ../../po/../src/ui/dialog/transformation.cpp:105 +msgid "" +"Edit the current transform= matrix; otherwise, post-multiply transform= by " +"this matrix" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:115 +#, fuzzy +msgid "_Move" +msgstr "Presunúť" + +#: ../../po/../src/ui/dialog/transformation.cpp:118 +#, fuzzy +msgid "_Scale" +msgstr "VeľkosÅ¥" + +#: ../../po/../src/ui/dialog/transformation.cpp:121 +#, fuzzy +msgid "_Rotate" +msgstr "Otočenie" + +#: ../../po/../src/ui/dialog/transformation.cpp:124 +#, fuzzy +msgid "Ske_w" +msgstr "Šírka Å¥ahu" + +#: ../../po/../src/ui/dialog/transformation.cpp:127 +msgid "Matri_x" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:141 +msgid "Reset the values on the current tab to defaults" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:148 +#, fuzzy +msgid "Apply transformation to selection" +msgstr "Výber a transformácia objektov" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:43 +msgid "_Use SSL" +msgstr "" + +#. Construct dialog interface +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:68 +#, fuzzy +msgid "_Server:" +msgstr "_ObrátiÅ¥" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:69 +#, fuzzy +msgid "_Username:" +msgstr "Pre_menovaÅ¥" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:70 +msgid "_Password:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:71 +msgid "P_ort:" +msgstr "" + +#. Buttons +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:99 +#, fuzzy +msgid "Connect" +msgstr "Klony" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:126 +msgid "Establishing connection to Jabber server %1 as user %2" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:131 +msgid "Failed to establish connection to Jabber server %1" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:136 +msgid "Authentication failed on Jabber server %1 as %2" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:141 +msgid "SSL initialization failed when connecting to Jabber server %1" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:147 +msgid "Connected to Jabber server %1 as %2" +msgstr "" + +#. Construct labels +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:75 +#, fuzzy +msgid "Chatroom _name:" +msgstr "Názov vrstvy:" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:76 +msgid "Chatroom _server:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:77 +msgid "Chatroom _password:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:78 +msgid "Chatroom _handle:" +msgstr "" + +#. Button setup and callback registration +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:97 +msgid "Connect to chatroom" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:132 +msgid "Synchronizing with chatroom %1@%2 using the handle %3" +msgstr "" + +#. Construct dialog interface +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:78 +msgid "_User's Jabber ID:" +msgstr "" + +#. Buttons +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:82 +msgid "_Invite user" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:83 +#, fuzzy +msgid "_Cancel" +msgstr "ZruÅ¡iÅ¥" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:94 +msgid "Buddy List" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:170 +msgid "Sending whiteboard invitation to %1" +msgstr "" + +#. FIXME: strings are replaced by placeholders, NOT to be translated until the code is enabled +#. See http://sourceforge.net/mailarchive/message.php?msg_id=11746016 for details +#. File menu +#. Edit menu +#. View menu +#. Layer menu +#. Object menu +#. Path menu +#. add(Gtk::StockItem(CLEANUP, _("PLACEHOLDER, do not translate"))); (using Gtk::Stock::CLEAR) +#. Text menu +#. About menu +#. Tools toolbox +#. Select Tool controls +#. Node Tool controls +#. Calligraphy Tool controls +#. Session playback controls +#: ../../po/../src/ui/stock-items.cpp:34 ../../po/../src/ui/stock-items.cpp:35 +#: ../../po/../src/ui/stock-items.cpp:36 ../../po/../src/ui/stock-items.cpp:37 +#: ../../po/../src/ui/stock-items.cpp:38 ../../po/../src/ui/stock-items.cpp:39 +#: ../../po/../src/ui/stock-items.cpp:40 ../../po/../src/ui/stock-items.cpp:41 +#: ../../po/../src/ui/stock-items.cpp:42 ../../po/../src/ui/stock-items.cpp:43 +#: ../../po/../src/ui/stock-items.cpp:46 ../../po/../src/ui/stock-items.cpp:47 +#: ../../po/../src/ui/stock-items.cpp:48 ../../po/../src/ui/stock-items.cpp:49 +#: ../../po/../src/ui/stock-items.cpp:50 ../../po/../src/ui/stock-items.cpp:51 +#: ../../po/../src/ui/stock-items.cpp:52 ../../po/../src/ui/stock-items.cpp:53 +#: ../../po/../src/ui/stock-items.cpp:54 ../../po/../src/ui/stock-items.cpp:55 +#: ../../po/../src/ui/stock-items.cpp:56 ../../po/../src/ui/stock-items.cpp:57 +#: ../../po/../src/ui/stock-items.cpp:58 ../../po/../src/ui/stock-items.cpp:59 +#: ../../po/../src/ui/stock-items.cpp:62 ../../po/../src/ui/stock-items.cpp:63 +#: ../../po/../src/ui/stock-items.cpp:64 ../../po/../src/ui/stock-items.cpp:65 +#: ../../po/../src/ui/stock-items.cpp:66 ../../po/../src/ui/stock-items.cpp:67 +#: ../../po/../src/ui/stock-items.cpp:68 ../../po/../src/ui/stock-items.cpp:69 +#: ../../po/../src/ui/stock-items.cpp:70 ../../po/../src/ui/stock-items.cpp:71 +#: ../../po/../src/ui/stock-items.cpp:72 ../../po/../src/ui/stock-items.cpp:73 +#: ../../po/../src/ui/stock-items.cpp:74 ../../po/../src/ui/stock-items.cpp:75 +#: ../../po/../src/ui/stock-items.cpp:76 ../../po/../src/ui/stock-items.cpp:77 +#: ../../po/../src/ui/stock-items.cpp:78 ../../po/../src/ui/stock-items.cpp:79 +#: ../../po/../src/ui/stock-items.cpp:80 ../../po/../src/ui/stock-items.cpp:81 +#: ../../po/../src/ui/stock-items.cpp:82 ../../po/../src/ui/stock-items.cpp:83 +#: ../../po/../src/ui/stock-items.cpp:84 ../../po/../src/ui/stock-items.cpp:85 +#: ../../po/../src/ui/stock-items.cpp:86 ../../po/../src/ui/stock-items.cpp:87 +#: ../../po/../src/ui/stock-items.cpp:88 ../../po/../src/ui/stock-items.cpp:89 +#: ../../po/../src/ui/stock-items.cpp:92 ../../po/../src/ui/stock-items.cpp:93 +#: ../../po/../src/ui/stock-items.cpp:94 ../../po/../src/ui/stock-items.cpp:95 +#: ../../po/../src/ui/stock-items.cpp:96 ../../po/../src/ui/stock-items.cpp:97 +#: ../../po/../src/ui/stock-items.cpp:98 ../../po/../src/ui/stock-items.cpp:99 +#: ../../po/../src/ui/stock-items.cpp:100 +#: ../../po/../src/ui/stock-items.cpp:101 +#: ../../po/../src/ui/stock-items.cpp:102 +#: ../../po/../src/ui/stock-items.cpp:103 +#: ../../po/../src/ui/stock-items.cpp:104 +#: ../../po/../src/ui/stock-items.cpp:105 +#: ../../po/../src/ui/stock-items.cpp:108 +#: ../../po/../src/ui/stock-items.cpp:109 +#: ../../po/../src/ui/stock-items.cpp:110 +#: ../../po/../src/ui/stock-items.cpp:111 +#: ../../po/../src/ui/stock-items.cpp:112 +#: ../../po/../src/ui/stock-items.cpp:113 +#: ../../po/../src/ui/stock-items.cpp:114 +#: ../../po/../src/ui/stock-items.cpp:115 +#: ../../po/../src/ui/stock-items.cpp:116 +#: ../../po/../src/ui/stock-items.cpp:117 +#: ../../po/../src/ui/stock-items.cpp:118 +#: ../../po/../src/ui/stock-items.cpp:119 +#: ../../po/../src/ui/stock-items.cpp:120 +#: ../../po/../src/ui/stock-items.cpp:121 +#: ../../po/../src/ui/stock-items.cpp:122 +#: ../../po/../src/ui/stock-items.cpp:123 +#: ../../po/../src/ui/stock-items.cpp:124 +#: ../../po/../src/ui/stock-items.cpp:125 +#: ../../po/../src/ui/stock-items.cpp:126 +#: ../../po/../src/ui/stock-items.cpp:127 +#: ../../po/../src/ui/stock-items.cpp:130 +#: ../../po/../src/ui/stock-items.cpp:131 +#: ../../po/../src/ui/stock-items.cpp:132 +#: ../../po/../src/ui/stock-items.cpp:133 +#: ../../po/../src/ui/stock-items.cpp:134 +#: ../../po/../src/ui/stock-items.cpp:135 +#: ../../po/../src/ui/stock-items.cpp:136 +#: ../../po/../src/ui/stock-items.cpp:137 +#: ../../po/../src/ui/stock-items.cpp:138 +#: ../../po/../src/ui/stock-items.cpp:139 +#: ../../po/../src/ui/stock-items.cpp:140 +#: ../../po/../src/ui/stock-items.cpp:141 +#: ../../po/../src/ui/stock-items.cpp:142 +#: ../../po/../src/ui/stock-items.cpp:143 +#: ../../po/../src/ui/stock-items.cpp:144 +#: ../../po/../src/ui/stock-items.cpp:145 +#: ../../po/../src/ui/stock-items.cpp:146 +#: ../../po/../src/ui/stock-items.cpp:150 +#: ../../po/../src/ui/stock-items.cpp:151 +#: ../../po/../src/ui/stock-items.cpp:152 +#: ../../po/../src/ui/stock-items.cpp:153 +#: ../../po/../src/ui/stock-items.cpp:156 +#: ../../po/../src/ui/stock-items.cpp:157 +#: ../../po/../src/ui/stock-items.cpp:158 +#: ../../po/../src/ui/stock-items.cpp:161 +#: ../../po/../src/ui/stock-items.cpp:162 +#: ../../po/../src/ui/stock-items.cpp:163 +#: ../../po/../src/ui/stock-items.cpp:164 +#: ../../po/../src/ui/stock-items.cpp:165 +#: ../../po/../src/ui/stock-items.cpp:166 +#: ../../po/../src/ui/stock-items.cpp:167 +#: ../../po/../src/ui/stock-items.cpp:168 +#: ../../po/../src/ui/stock-items.cpp:169 +#: ../../po/../src/ui/stock-items.cpp:170 +#: ../../po/../src/ui/stock-items.cpp:171 +#: ../../po/../src/ui/stock-items.cpp:172 +#: ../../po/../src/ui/stock-items.cpp:175 +#: ../../po/../src/ui/stock-items.cpp:176 +#: ../../po/../src/ui/stock-items.cpp:177 +#: ../../po/../src/ui/stock-items.cpp:178 +#: ../../po/../src/ui/stock-items.cpp:181 +#: ../../po/../src/ui/stock-items.cpp:182 +#: ../../po/../src/ui/stock-items.cpp:183 +#: ../../po/../src/ui/stock-items.cpp:184 +#: ../../po/../src/ui/stock-items.cpp:185 +#: ../../po/../src/ui/stock-items.cpp:186 +#: ../../po/../src/ui/stock-items.cpp:187 +#: ../../po/../src/ui/stock-items.cpp:188 +#: ../../po/../src/ui/stock-items.cpp:189 +#: ../../po/../src/ui/stock-items.cpp:190 +#: ../../po/../src/ui/stock-items.cpp:191 +#: ../../po/../src/ui/stock-items.cpp:194 +#: ../../po/../src/ui/stock-items.cpp:195 +#: ../../po/../src/ui/stock-items.cpp:198 +#: ../../po/../src/ui/stock-items.cpp:199 +#: ../../po/../src/ui/stock-items.cpp:200 +#: ../../po/../src/ui/stock-items.cpp:201 +#: ../../po/../src/ui/stock-items.cpp:202 +msgid "PLACEHOLDER, do not translate" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:88 +msgid "small" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:89 +msgid "medium" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:90 +#, fuzzy +msgid "large" +msgstr "Cieľ:" + +#: ../../po/../src/ui/widget/panel.cpp:91 +msgid "huge" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:106 +#, fuzzy +msgid "List" +msgstr "posun dnu" + +#: ../../po/../src/ui/widget/selected-style.cpp:67 +msgid "F:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:68 +#, fuzzy +msgid "S:" +msgstr "_S" + +#: ../../po/../src/ui/widget/selected-style.cpp:69 +msgid "O:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:95 +msgid "N/A" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:98 +#: ../../po/../src/ui/widget/selected-style.cpp:712 +#, fuzzy +msgid "Nothing selected" +msgstr "Označené súbory:" + +#: ../../po/../src/ui/widget/selected-style.cpp:103 +msgid "No fill" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:103 +msgid "No stroke" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:105 +#: ../../po/../src/widgets/paint-selector.cpp:190 +msgid "Pattern" +msgstr "Vzorka" + +#: ../../po/../src/ui/widget/selected-style.cpp:108 +#: ../../po/../src/widgets/paint-selector.cpp:885 +msgid "Pattern fill" +msgstr "Vzorka výplne" + +#: ../../po/../src/ui/widget/selected-style.cpp:108 +#, fuzzy +msgid "Pattern stroke" +msgstr "Posun vzorky" + +#: ../../po/../src/ui/widget/selected-style.cpp:110 +#, fuzzy +msgid "L Gradient" +msgstr "Editor prechodov" + +#: ../../po/../src/ui/widget/selected-style.cpp:113 +#, fuzzy +msgid "Linear gradient fill" +msgstr "Lineárny prechod" + +#: ../../po/../src/ui/widget/selected-style.cpp:113 +#, fuzzy +msgid "Linear gradient stroke" +msgstr "Lineárny prechod" + +#: ../../po/../src/ui/widget/selected-style.cpp:115 +#, fuzzy +msgid "R Gradient" +msgstr "Editor prechodov" + +#: ../../po/../src/ui/widget/selected-style.cpp:118 +#, fuzzy +msgid "Radial gradient fill" +msgstr "Radiálny prechod" + +#: ../../po/../src/ui/widget/selected-style.cpp:118 +#, fuzzy +msgid "Radial gradient stroke" +msgstr "Radiálny prechod" + +#: ../../po/../src/ui/widget/selected-style.cpp:120 +#, fuzzy +msgid "Different" +msgstr "Roz_diel" + +#: ../../po/../src/ui/widget/selected-style.cpp:123 +#, fuzzy +msgid "Different fills" +msgstr "Roz_diel" + +#: ../../po/../src/ui/widget/selected-style.cpp:123 +#, fuzzy +msgid "Different strokes" +msgstr "Roz_diel" + +#: ../../po/../src/ui/widget/selected-style.cpp:125 +#, fuzzy +msgid "Unset" +msgstr "posun dnu" + +#. TRANSLATORS COMMENT: unset is a verb here +#: ../../po/../src/ui/widget/selected-style.cpp:128 +#: ../../po/../src/ui/widget/selected-style.cpp:182 +#, fuzzy +msgid "Unset fill" +msgstr "Jednotka" + +#: ../../po/../src/ui/widget/selected-style.cpp:128 +#: ../../po/../src/ui/widget/selected-style.cpp:182 +msgid "Unset stroke" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:131 +#, fuzzy +msgid "Flat color fill" +msgstr "Jednoduchá farba:" + +#: ../../po/../src/ui/widget/selected-style.cpp:131 +#, fuzzy +msgid "Flat color stroke" +msgstr "Jednoduchá farba:" + +#. TRANSLATOR COMMENT: A means "Averaged" +#: ../../po/../src/ui/widget/selected-style.cpp:134 +#, fuzzy +msgid "A" +msgstr "_A" + +#: ../../po/../src/ui/widget/selected-style.cpp:137 +#, fuzzy +msgid "Fill is averaged over selected objects" +msgstr "Exkluzívne OR zvolených objektov" + +#: ../../po/../src/ui/widget/selected-style.cpp:137 +#, fuzzy +msgid "Stroke is averaged over selected objects" +msgstr "Prienik zvolených objektov" + +#. TRANSLATOR COMMENT: M means "Multiple" +#: ../../po/../src/ui/widget/selected-style.cpp:140 +#, fuzzy +msgid "M" +msgstr "_M" + +#: ../../po/../src/ui/widget/selected-style.cpp:143 +#, fuzzy +msgid "Multiple selected objects have the same fill" +msgstr "Zvislé zarovnanie niekoľko uzlov" + +#: ../../po/../src/ui/widget/selected-style.cpp:143 +#, fuzzy +msgid "Multiple selected objects have the same stroke" +msgstr "Zvislé zarovnanie niekoľko uzlov" + +#: ../../po/../src/ui/widget/selected-style.cpp:145 +#, fuzzy +msgid "Edit fill..." +msgstr "UpraviÅ¥" + +#: ../../po/../src/ui/widget/selected-style.cpp:145 +#, fuzzy +msgid "Edit stroke..." +msgstr "UpraviÅ¥" + +#: ../../po/../src/ui/widget/selected-style.cpp:149 +#, fuzzy +msgid "Last set color" +msgstr "Jednoduchá farba:" + +#: ../../po/../src/ui/widget/selected-style.cpp:153 +#, fuzzy +msgid "Last selected color" +msgstr "Naposledy zvolené" + +#: ../../po/../src/ui/widget/selected-style.cpp:157 +msgid "White" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:161 +#: ../../po/../src/widgets/sp-color-scales.cpp:461 +#: ../../po/../src/widgets/sp-color-scales.cpp:462 +msgid "Black" +msgstr "Čierna" + +#: ../../po/../src/ui/widget/selected-style.cpp:165 +#, fuzzy +msgid "Copy color" +msgstr "Koncová farby" + +#: ../../po/../src/ui/widget/selected-style.cpp:169 +#, fuzzy +msgid "Paste color" +msgstr "Jednoduchá farba:" + +#: ../../po/../src/ui/widget/selected-style.cpp:173 +#, fuzzy +msgid "Swap fill and stroke" +msgstr "Výp_lň a Å¥ah" + +#: ../../po/../src/ui/widget/selected-style.cpp:177 +msgid "Make fill opaque" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:177 +msgid "Make stroke opaque" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:186 +#, fuzzy +msgid "Remove fill" +msgstr "O_dstrániÅ¥" + +#: ../../po/../src/ui/widget/selected-style.cpp:186 +#, fuzzy +msgid "Remove stroke" +msgstr "Odst_rániÅ¥ odkaz" + +#: ../../po/../src/ui/widget/selected-style.cpp:718 +#, fuzzy +msgid "Master opacity" +msgstr "Hlavná nepriesvitnosÅ¥" + +#: ../../po/../src/ui/widget/selected-style.cpp:744 +msgid "0 (transparent)" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:768 +msgid "1.0 (opaque)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1046 +msgid "Moved to next layer." +msgstr "Presunúť do nasledujúúcej vrstvy." + +#: ../../po/../src/verbs.cpp:1048 +#, fuzzy +msgid "Cannot move past last layer." +msgstr "Vrstvu nie je možné posunúť ďalej." + +#: ../../po/../src/verbs.cpp:1057 +#, fuzzy +msgid "Moved to previous layer." +msgstr "Presunúť do predchádzajúcej vrstvy" + +#: ../../po/../src/verbs.cpp:1059 +#, fuzzy +msgid "Cannot move past first layer." +msgstr "Vrstvu nie je možné posunúť ďalej." + +#: ../../po/../src/verbs.cpp:1076 ../../po/../src/verbs.cpp:1150 +msgid "No current layer." +msgstr "Neexistuje aktuálna vrstva." + +#: ../../po/../src/verbs.cpp:1105 +#, fuzzy, c-format +msgid "Raised layer %s." +msgstr "ZvýšiÅ¥ vrstvu." + +#: ../../po/../src/verbs.cpp:1109 +#, fuzzy, c-format +msgid "Lowered layer %s." +msgstr "ZnížiÅ¥ vrstvu." + +#: ../../po/../src/verbs.cpp:1118 +#, fuzzy +msgid "Cannot move layer any further." +msgstr "Vrstvu nie je možné posunúť ďalej." + +#. TRANSLATORS: this means "The layer has been deleted." +#: ../../po/../src/verbs.cpp:1148 +msgid "Deleted layer." +msgstr "OdstrániÅ¥ vrstvu." + +#: ../../po/../src/verbs.cpp:1544 +msgid "" +"You need to connect to a Jabber server before sharing a document with " +"another user." +msgstr "" + +#: ../../po/../src/verbs.cpp:1559 +msgid "" +"You need to connect to a Jabber server before sharing a document with a " +"chatroom." +msgstr "" + +#: ../../po/../src/verbs.cpp:1569 +msgid "XML node tracker has not been initialized; nothing to dump" +msgstr "" + +#. TRANSLATORS: If you have translated the keys.svg file to your language, then +#. translate this string as "keys.LANG.svg" (where LANG is your language code); +#. otherwise leave as "keys.svg". +#: ../../po/../src/verbs.cpp:1631 +msgid "keys.svg" +msgstr "keys.svg" + +#. TRANSLATORS: If you have translated the tutorial-basic.svg file to your language, +#. then translate this string as "tutorial-basic.LANG.svg" (where LANG is your language +#. code); otherwise leave as "tutorial-basic.svg". +#: ../../po/../src/verbs.cpp:1667 +msgid "tutorial-basic.svg" +msgstr "tutorial-basic.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1671 +msgid "tutorial-shapes.svg" +msgstr "tutorial-shapes.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1675 +msgid "tutorial-advanced.svg" +msgstr "tutorial-advanced.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1679 +msgid "tutorial-tracing.svg" +msgstr "tutorial-tracing.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1683 +msgid "tutorial-calligraphy.svg" +msgstr "tutorial-calligraphy.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1687 +#, fuzzy +msgid "tutorial-elements.svg" +msgstr "tutorial-shapes.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1691 +#, fuzzy +msgid "tutorial-tips.svg" +msgstr "tutorial-shapes.svg" + +#: ../../po/../src/verbs.cpp:1842 +msgid "Does nothing" +msgstr "Nerobí nič" + +#. File +#: ../../po/../src/verbs.cpp:1845 +msgid "Default" +msgstr "Å tandardné" + +#: ../../po/../src/verbs.cpp:1845 +msgid "Create new document from default template" +msgstr "VytvoriÅ¥ nový SVG dokument zo Å¡tandardnej Å¡ablóny" + +#: ../../po/../src/verbs.cpp:1847 +msgid "_Open..." +msgstr "_OtvoriÅ¥..." + +#: ../../po/../src/verbs.cpp:1848 +msgid "Open existing document" +msgstr "OtvoriÅ¥ existujúci SVG dokument" + +#: ../../po/../src/verbs.cpp:1849 +msgid "Re_vert" +msgstr "Obno_viÅ¥" + +#: ../../po/../src/verbs.cpp:1850 +msgid "Revert to the last saved version of document (changes will be lost)" +msgstr "NačítaÅ¥ poslednú uloženú verziu dokumentu (zmeny budú stratené)" + +#: ../../po/../src/verbs.cpp:1851 +msgid "_Save" +msgstr "_UložiÅ¥" + +#: ../../po/../src/verbs.cpp:1851 +msgid "Save document" +msgstr "UložiÅ¥ dokument" + +#: ../../po/../src/verbs.cpp:1853 +msgid "Save _As..." +msgstr "UložiÅ¥ ako..." + +#: ../../po/../src/verbs.cpp:1854 +msgid "Save document under new name" +msgstr "UložiÅ¥ dokument pod novým názvom" + +#: ../../po/../src/verbs.cpp:1855 +msgid "_Print..." +msgstr "_TlačiÅ¥..." + +#: ../../po/../src/verbs.cpp:1855 +msgid "Print document" +msgstr "VytlačiÅ¥ dokument" + +#. TRANSLATORS: "Vacuum Defs" means "Clean up defs" (so as to remove unused definitions) +#: ../../po/../src/verbs.cpp:1858 +msgid "Vac_uum Defs" +msgstr "" + +#: ../../po/../src/verbs.cpp:1858 +msgid "Remove unused predefined items from the <defs> of the document" +msgstr "" + +#: ../../po/../src/verbs.cpp:1860 +msgid "Print _Direct" +msgstr "TlačiÅ¥ p_riamo" + +#: ../../po/../src/verbs.cpp:1861 +#, fuzzy +msgid "Print directly without prompting to a file or pipe" +msgstr "TlačiÅ¥ priamo do súboru alebo rúry" + +#: ../../po/../src/verbs.cpp:1862 +msgid "Print Previe_w" +msgstr "Ukážka pred tlačou" + +#: ../../po/../src/verbs.cpp:1863 +msgid "Preview document printout" +msgstr "ZobraziÅ¥ náhľad na dokument pred tlačou" + +#: ../../po/../src/verbs.cpp:1864 +msgid "_Import..." +msgstr "_ImportovaÅ¥..." + +#: ../../po/../src/verbs.cpp:1865 +msgid "Import bitmap or SVG image into document" +msgstr "ImportovaÅ¥ bitmapu alebo SVG obrázok do dokumentu" + +#: ../../po/../src/verbs.cpp:1866 +msgid "_Export Bitmap..." +msgstr "_ExportovaÅ¥ bitmapu..." + +#: ../../po/../src/verbs.cpp:1867 +#, fuzzy +msgid "Export document or selection as a bitmap image" +msgstr "ExportovaÅ¥ dokument alebo výber ako PNG bitmapu" + +#: ../../po/../src/verbs.cpp:1868 +msgid "N_ext Window" +msgstr "Nasl_edujúce okno" + +#: ../../po/../src/verbs.cpp:1869 +msgid "Switch to the next document window" +msgstr "Prepnúť do nasledujúceho okna" + +#: ../../po/../src/verbs.cpp:1870 +msgid "P_revious Window" +msgstr "Predchádzajúce okno" + +#: ../../po/../src/verbs.cpp:1871 +msgid "Switch to the previous document window" +msgstr "Prepnúť do predchádzajúceho okna dokumentu" + +#: ../../po/../src/verbs.cpp:1872 +msgid "_Close" +msgstr "_ZatvoriÅ¥" + +#: ../../po/../src/verbs.cpp:1873 +msgid "Close window" +msgstr "ZatvoriÅ¥ okno" + +#: ../../po/../src/verbs.cpp:1874 +msgid "_Quit" +msgstr "_Koniec" + +#: ../../po/../src/verbs.cpp:1874 +msgid "Quit Inkscape" +msgstr "UkončiÅ¥ Inkscape" + +#. Edit +#: ../../po/../src/verbs.cpp:1877 +msgid "_Undo" +msgstr "_Späť" + +#: ../../po/../src/verbs.cpp:1877 +msgid "Undo last action" +msgstr "VrátiÅ¥ poslednú akciu" + +#: ../../po/../src/verbs.cpp:1879 +msgid "_Redo" +msgstr "_OpakovaÅ¥ vrátené" + +#: ../../po/../src/verbs.cpp:1880 +msgid "Do again last undone action" +msgstr "ZopakovaÅ¥ akciu vrátenú späť" + +#: ../../po/../src/verbs.cpp:1881 +msgid "Cu_t" +msgstr "Vys_trihnúť" + +#: ../../po/../src/verbs.cpp:1882 +msgid "Cut selection to clipboard" +msgstr "Vystrihnúť výber do schránky" + +#: ../../po/../src/verbs.cpp:1883 +msgid "_Copy" +msgstr "_KopírovaÅ¥" + +#: ../../po/../src/verbs.cpp:1884 +msgid "Copy selection to clipboard" +msgstr "SkopírovaÅ¥ výber do schránky" + +#: ../../po/../src/verbs.cpp:1885 +msgid "_Paste" +msgstr "_VložiÅ¥" + +#: ../../po/../src/verbs.cpp:1886 +#, fuzzy +msgid "Paste objects from clipboard to mouse point" +msgstr "VložiÅ¥ objekty zo schránky na miesto pod myÅ¡ou" + +#: ../../po/../src/verbs.cpp:1887 +msgid "Paste _Style" +msgstr "VložiÅ¥ Å¡_týl" + +#: ../../po/../src/verbs.cpp:1888 +msgid "Apply style of the copied object to selection" +msgstr "PoužiÅ¥ Å¡týl kopírovaných objektov na výber" + +#: ../../po/../src/verbs.cpp:1889 +msgid "Paste _In Place" +msgstr "VložiÅ¥ na miesto" + +#: ../../po/../src/verbs.cpp:1890 +#, fuzzy +msgid "Paste objects from clipboard to the original location" +msgstr "VložiÅ¥ objekt zo schránky na pôvodné umiestnenie" + +#: ../../po/../src/verbs.cpp:1891 +msgid "_Delete" +msgstr "_ZmazaÅ¥" + +#: ../../po/../src/verbs.cpp:1892 +msgid "Delete selection" +msgstr "ZmazaÅ¥ výber" + +#: ../../po/../src/verbs.cpp:1893 +msgid "Duplic_ate" +msgstr "Duplikov_aÅ¥" + +#: ../../po/../src/verbs.cpp:1894 +#, fuzzy +msgid "Duplicate selected objects" +msgstr "DuplikovaÅ¥ vybrané objekty" + +#: ../../po/../src/verbs.cpp:1895 +msgid "Clo_ne" +msgstr "Klo_novaÅ¥" + +#: ../../po/../src/verbs.cpp:1896 +msgid "Create a clone of selected object (a copy linked to the original)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1897 +msgid "Unlin_k Clone" +msgstr "OdpojiÅ¥ _klon" + +#: ../../po/../src/verbs.cpp:1898 +msgid "Cut the clone's link to its original" +msgstr "Odstrihnúť prepojenie klonu na jeho originál" + +#: ../../po/../src/verbs.cpp:1899 +msgid "Select _Original" +msgstr "VybraÅ¥ _originál" + +#: ../../po/../src/verbs.cpp:1900 +msgid "Select the object to which the clone is linked" +msgstr "VybraÅ¥ objekt, na ktorý je klon prepojený" + +#. TRANSLATORS: Convert selection to a rectangle with tiled pattern fill +#: ../../po/../src/verbs.cpp:1902 +#, fuzzy +msgid "O_bjects to Pattern" +msgstr "O_bjekt do vzorky" + +#: ../../po/../src/verbs.cpp:1903 +msgid "Convert selection to a rectangle with tiled pattern fill" +msgstr "KonvertovaÅ¥ výber na obdĺžnik vyplnený vzorkou" + +#. TRANSLATORS: Extract objects from a tiled pattern fill +#: ../../po/../src/verbs.cpp:1905 +#, fuzzy +msgid "Pattern to Ob_jects" +msgstr "Vzorka do objektu" + +#: ../../po/../src/verbs.cpp:1906 +msgid "Extract objects from a tiled pattern fill" +msgstr "ExtrahovaÅ¥ objekty z dláždenej vzorkovej výplne" + +#: ../../po/../src/verbs.cpp:1907 +msgid "Clea_r All" +msgstr "VÅ¡etko z_mazaÅ¥" + +#: ../../po/../src/verbs.cpp:1908 +msgid "Delete all objects from document" +msgstr "ZmazaÅ¥ vÅ¡etky objekty z dokumentu" + +#: ../../po/../src/verbs.cpp:1909 +msgid "Select Al_l" +msgstr "VybraÅ¥ _vÅ¡etko" + +#: ../../po/../src/verbs.cpp:1910 +msgid "Select all objects or all nodes" +msgstr "VybraÅ¥ vÅ¡etky objekty alebo vÅ¡etky uzly" + +#: ../../po/../src/verbs.cpp:1911 +#, fuzzy +msgid "Select All in All La_yers" +msgstr "VybraÅ¥ vÅ¡etky viditeľné vrstvy" + +#: ../../po/../src/verbs.cpp:1912 +#, fuzzy +msgid "Select all objects in all visible and unlocked layers" +msgstr "VybraÅ¥ vÅ¡etky objekty alebo vÅ¡etky uzly" + +#: ../../po/../src/verbs.cpp:1913 +#, fuzzy +msgid "In_vert Selection" +msgstr "Inverzný výber" + +#: ../../po/../src/verbs.cpp:1914 +msgid "Invert selection (unselect what is selected and select everything else)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1915 +msgid "Invert in All Layers" +msgstr "IvertovaÅ¥ vo vÅ¡etkých vrstvách" + +#: ../../po/../src/verbs.cpp:1916 +msgid "Invert selection in all visible and unlocked layers" +msgstr "" + +#: ../../po/../src/verbs.cpp:1917 +msgid "D_eselect" +msgstr "Odzn_ažiÅ¥" + +#: ../../po/../src/verbs.cpp:1918 +msgid "Deselect any selected objects or nodes" +msgstr "Zruší výber zvolených objektov" + +#. Selection +#: ../../po/../src/verbs.cpp:1921 +msgid "Raise to _Top" +msgstr "_Presunúť na vrchol" + +#: ../../po/../src/verbs.cpp:1922 +msgid "Raise selection to top" +msgstr "Presunúť výber na najvyÅ¡Å¡iu úroveň" + +#: ../../po/../src/verbs.cpp:1923 +msgid "Lower to _Bottom" +msgstr "P_resunúť výber na spodok" + +#: ../../po/../src/verbs.cpp:1924 +msgid "Lower selection to bottom" +msgstr "Presunúť výber na najnižšiu úroveň" + +#: ../../po/../src/verbs.cpp:1925 +msgid "_Raise" +msgstr "P_resunúť vyÅ¡Å¡ie" + +#: ../../po/../src/verbs.cpp:1926 +msgid "Raise selection one step" +msgstr "Presunúť výber o jednu úroveň" + +#: ../../po/../src/verbs.cpp:1927 +msgid "_Lower" +msgstr "Presu_núť nižšie" + +#: ../../po/../src/verbs.cpp:1928 +msgid "Lower selection one step" +msgstr "ZnížiÅ¥ výber o jednu úroveň" + +#: ../../po/../src/verbs.cpp:1929 +msgid "_Group" +msgstr "_ZoskupiÅ¥" + +#: ../../po/../src/verbs.cpp:1930 +msgid "Group selected objects" +msgstr "Zoskupí zvolené objekty" + +#: ../../po/../src/verbs.cpp:1932 +#, fuzzy +msgid "Ungroup selected groups" +msgstr "Zruší zoskupenie vybraných objektov" + +#: ../../po/../src/verbs.cpp:1934 +msgid "_Put on Path" +msgstr "UmiestniÅ¥ na _cestu" + +#: ../../po/../src/verbs.cpp:1935 +msgid "Put text on path" +msgstr "UmiestniÅ¥ text na cestu" + +#: ../../po/../src/verbs.cpp:1936 +msgid "_Remove from Path" +msgstr "Odst_rániÅ¥ z cesty" + +#: ../../po/../src/verbs.cpp:1937 +msgid "Remove text from path" +msgstr "OdstrániÅ¥ text z cesty" + +#: ../../po/../src/verbs.cpp:1938 +msgid "Remove Manual _Kerns" +msgstr "OdstrániÅ¥ manuálny \"kerning\"" + +#. TRANSLATORS: "glyph": An image used in the visual representation of characters; +#. roughly speaking, how a character looks. A font is a set of glyphs. +#: ../../po/../src/verbs.cpp:1941 +#, fuzzy +msgid "Remove all manual kerns and glyph rotations from a text object" +msgstr "OdstrániÅ¥ manuálny \"kerning\" z textových objektov" + +#: ../../po/../src/verbs.cpp:1943 +msgid "_Union" +msgstr "Z_jednotenie" + +#: ../../po/../src/verbs.cpp:1944 +msgid "Union of selected objects" +msgstr "Zjednotenie zvolených objektov" + +#: ../../po/../src/verbs.cpp:1945 +msgid "_Intersection" +msgstr "Pr_ienik" + +#: ../../po/../src/verbs.cpp:1946 +msgid "Intersection of selected objects" +msgstr "Prienik zvolených objektov" + +#: ../../po/../src/verbs.cpp:1947 +msgid "_Difference" +msgstr "Roz_diel" + +#: ../../po/../src/verbs.cpp:1948 +msgid "Difference of selected objects (bottom minus top)" +msgstr "Rozdiel zvolených objektov (nižší objekt mínus vyšší)" + +#: ../../po/../src/verbs.cpp:1949 +msgid "E_xclusion" +msgstr "_Vylúčenie" + +#: ../../po/../src/verbs.cpp:1950 +msgid "Exclusive OR of selected objects" +msgstr "Exkluzívne OR zvolených objektov" + +#: ../../po/../src/verbs.cpp:1951 +msgid "Di_vision" +msgstr "Ro_zdelenie" + +#: ../../po/../src/verbs.cpp:1952 +msgid "Cut the bottom object into pieces" +msgstr "Rostrihnutie dolného objektu na časti" + +#. TRANSLATORS: "to cut a path" is not the same as "to break a path apart" - see the +#. Advanced tutorial for more info +#: ../../po/../src/verbs.cpp:1955 +msgid "Cut _Path" +msgstr "Vys_trihnúť cestu" + +#: ../../po/../src/verbs.cpp:1956 +msgid "Cut the bottom object's stroke into pieces, removing fill" +msgstr "" + +#. TRANSLATORS: "outset": expand a shape by offsetting the object's path, +#. i.e. by displacing it perpendicular to the path in each point. +#. See also the Advanced Tutorial for explanation. +#: ../../po/../src/verbs.cpp:1960 +#, fuzzy +msgid "Outs_et" +msgstr "Posun _von" + +#: ../../po/../src/verbs.cpp:1961 +#, fuzzy +msgid "Outset selected paths" +msgstr "Posunúť zvolené cesty smerom von" + +#: ../../po/../src/verbs.cpp:1963 +#, fuzzy +msgid "O_utset Path by 1 px" +msgstr "Pos_unúť zvolené cesty o 1 bod von" + +#: ../../po/../src/verbs.cpp:1964 +#, fuzzy +msgid "Outset selected paths by 1 px" +msgstr "Posunúť zvolené cesty o 1 bod von" + +#: ../../po/../src/verbs.cpp:1966 +#, fuzzy +msgid "O_utset Path by 10 px" +msgstr "Posunúť zvolené cesty von o 10 bodov" + +#: ../../po/../src/verbs.cpp:1967 +#, fuzzy +msgid "Outset selected paths by 10 px" +msgstr "Pos_unúť zvolené cesty von o 10 bodov" + +#. TRANSLATORS: "inset": contract a shape by offsetting the object's path, +#. i.e. by displacing it perpendicular to the path in each point. +#. See also the Advanced Tutorial for explanation. +#: ../../po/../src/verbs.cpp:1971 +msgid "I_nset" +msgstr "Posu_núť dnu" + +#: ../../po/../src/verbs.cpp:1972 +#, fuzzy +msgid "Inset selected paths" +msgstr "Posunúť zvolené cesty dnu" + +#: ../../po/../src/verbs.cpp:1974 +#, fuzzy +msgid "I_nset Path by 1 px" +msgstr "Posunúť zvolené cesty dnu o _1 bod" + +#: ../../po/../src/verbs.cpp:1975 +#, fuzzy +msgid "Inset selected paths by 1 px" +msgstr "Posunúť zvolené cesty dnu o 1 bod" + +#: ../../po/../src/verbs.cpp:1977 +#, fuzzy +msgid "I_nset Path by 10 px" +msgstr "Posunúť zvolené cesty dnu o 1_0 bodov" + +#: ../../po/../src/verbs.cpp:1978 +#, fuzzy +msgid "Inset selected paths by 10 px" +msgstr "Posunúť zvolené cesty dnu o 10 bodov" + +#: ../../po/../src/verbs.cpp:1980 +msgid "D_ynamic Offset" +msgstr "D_ynamický posun" + +#: ../../po/../src/verbs.cpp:1980 +msgid "Create a dynamic offset object" +msgstr "VytvoriÅ¥ dynamický posun objektu" + +#: ../../po/../src/verbs.cpp:1982 +msgid "_Linked Offset" +msgstr "_Prepojený posun" + +#: ../../po/../src/verbs.cpp:1983 +msgid "Create a dynamic offset object linked to the original path" +msgstr "VytvoriÅ¥ dynamický posun objektu prepojený na originálnu cestu" + +#: ../../po/../src/verbs.cpp:1985 +msgid "_Stroke to Path" +msgstr "Ťah na ce_stu" + +#: ../../po/../src/verbs.cpp:1986 +#, fuzzy +msgid "Convert selected strokes to paths" +msgstr "KonvertovaÅ¥ zvolený Å¥ah na cestu" + +#: ../../po/../src/verbs.cpp:1987 +msgid "Si_mplify" +msgstr "Zj_ednoduÅ¡iÅ¥" + +#: ../../po/../src/verbs.cpp:1988 +#, fuzzy +msgid "Simplify selected paths by removing extra nodes" +msgstr "ZjednoduÅ¡iÅ¥ zvolené cesty odstránením extra uzlov" + +#: ../../po/../src/verbs.cpp:1989 +msgid "_Reverse" +msgstr "_ObrátiÅ¥" + +#: ../../po/../src/verbs.cpp:1990 +#, fuzzy +msgid "Reverses the direction of selected paths; useful for flipping markers" +msgstr "Obracia smer zvolených ciest; vhodné pre preklápanie značkovačov." + +#. TRANSLATORS: "to trace" means "to convert a bitmap to vector graphics" (to vectorize) +#: ../../po/../src/verbs.cpp:1992 +msgid "_Trace Bitmap" +msgstr "_PrekresliÅ¥ bitmapu" + +#: ../../po/../src/verbs.cpp:1993 +msgid "Convert bitmap object to paths" +msgstr "KonvertovaÅ¥ bitmapový objekt na cestu" + +#: ../../po/../src/verbs.cpp:1994 +msgid "_Make a Bitmap Copy" +msgstr "VytvoriÅ¥ bit_mapovú kópiu" + +#: ../../po/../src/verbs.cpp:1995 +msgid "Export selection to a bitmap and insert it into document" +msgstr "ExportovaÅ¥ výber do bitmapy alebo vložiÅ¥ do dokumentu" + +#: ../../po/../src/verbs.cpp:1996 +msgid "_Combine" +msgstr "_Kombinácia" + +#: ../../po/../src/verbs.cpp:1997 +msgid "Combine several paths into one" +msgstr "KombinovaÅ¥ niekoľko ciest do jednej" + +#. TRANSLATORS: "to cut a path" is not the same as "to break a path apart" - see the +#. Advanced tutorial for more info +#: ../../po/../src/verbs.cpp:2000 +msgid "Break _Apart" +msgstr "_RozdeliÅ¥" + +#: ../../po/../src/verbs.cpp:2001 +#, fuzzy +msgid "Break selected paths into subpaths" +msgstr "Rozdelí vybrané cesty na podcesty" + +#: ../../po/../src/verbs.cpp:2002 +msgid "Gri_d Arrange..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2003 +msgid "Arrange selection in grid pattern" +msgstr "" + +#. Layer +#: ../../po/../src/verbs.cpp:2005 +#, fuzzy +msgid "_Add Layer..." +msgstr "_Nová vrstva..." + +#: ../../po/../src/verbs.cpp:2006 +msgid "Create a new layer" +msgstr "VytvoriÅ¥ novú vrstvu" + +#: ../../po/../src/verbs.cpp:2007 +#, fuzzy +msgid "Re_name Layer..." +msgstr "Premenov_aÅ¥ vrstvu..." + +#: ../../po/../src/verbs.cpp:2008 +msgid "Rename the current layer" +msgstr "PremenovaÅ¥ aktuálnu vrstvu" + +#: ../../po/../src/verbs.cpp:2009 +#, fuzzy +msgid "Switch to Layer Abov_e" +msgstr "Prepnúť do nasledujúcej vrstvy" + +#: ../../po/../src/verbs.cpp:2010 +#, fuzzy +msgid "Switch to the layer above the current" +msgstr "Prepnúť do nasledujúcej vrstvy v dokumente" + +#: ../../po/../src/verbs.cpp:2011 +#, fuzzy +msgid "Switch to Layer Belo_w" +msgstr "Prepnúť do nasledujúcej vrstvy" + +#: ../../po/../src/verbs.cpp:2012 +#, fuzzy +msgid "Switch to the layer below the current" +msgstr "Prepnúť do nasledujúcej vrstvy v dokumente" + +#: ../../po/../src/verbs.cpp:2013 +#, fuzzy +msgid "Move Selection to Layer Abo_ve" +msgstr "Presunúť výber na najnižšiu úroveň" + +#: ../../po/../src/verbs.cpp:2014 +msgid "Move selection to the layer above the current" +msgstr "" + +#: ../../po/../src/verbs.cpp:2015 +#, fuzzy +msgid "Move Selection to Layer Bel_ow" +msgstr "ZnížiÅ¥ výber o jednu úroveň" + +#: ../../po/../src/verbs.cpp:2016 +msgid "Move selection to the layer below the current" +msgstr "" + +#: ../../po/../src/verbs.cpp:2017 +msgid "Layer to _Top" +msgstr "UmiestniÅ¥ vrs_tvu hore" + +#: ../../po/../src/verbs.cpp:2018 +msgid "Raise the current layer to the top" +msgstr "Presunúť aktuálnu vrstvu na vrchol" + +#: ../../po/../src/verbs.cpp:2019 +msgid "Layer to _Bottom" +msgstr "UmiestniÅ¥ vrstvu _dole" + +#: ../../po/../src/verbs.cpp:2020 +msgid "Lower the current layer to the bottom" +msgstr "Presunúť aktuálnu vrstvu na spodok" + +#: ../../po/../src/verbs.cpp:2021 +msgid "_Raise Layer" +msgstr "_Zdvihnúť vrstvu" + +#: ../../po/../src/verbs.cpp:2022 +msgid "Raise the current layer" +msgstr "ZvýšiÅ¥ aktuálnu vrstvu" + +#: ../../po/../src/verbs.cpp:2023 +msgid "_Lower Layer" +msgstr "Z_nížiÅ¥ vrstvu" + +#: ../../po/../src/verbs.cpp:2024 +msgid "Lower the current layer" +msgstr "ZnížiÅ¥ aktuálnu vrstvu" + +#: ../../po/../src/verbs.cpp:2025 +msgid "_Delete Current Layer" +msgstr "O_dstrániÅ¥ aktuálnu vrstvu" + +#: ../../po/../src/verbs.cpp:2026 +msgid "Delete the current layer" +msgstr "OdstrániÅ¥ aktuálnu vrstvu" + +# Object +#. Object +#: ../../po/../src/verbs.cpp:2029 +#, fuzzy +msgid "Rotate _90° CW" +msgstr "OtočiÅ¥ o _90 stupňov" + +#: ../../po/../src/verbs.cpp:2030 +#, fuzzy +msgid "Rotate selection 90° clockwise" +msgstr "Otočí objekt o 90° doprava" + +#: ../../po/../src/verbs.cpp:2031 +#, fuzzy +msgid "Rotate 9_0° CCW" +msgstr "OtočiÅ¥ o -_90 stupňov" + +#: ../../po/../src/verbs.cpp:2032 +#, fuzzy +msgid "Rotate selection 90° counter-clockwise" +msgstr "Otočí objekt o 90° doľava" + +#: ../../po/../src/verbs.cpp:2033 +msgid "Remove _Transformations" +msgstr "OdstrániÅ¥ _transformáciu" + +#: ../../po/../src/verbs.cpp:2034 +msgid "Remove transformations from object" +msgstr "OdstrániÅ¥ transformácie z objektu" + +#: ../../po/../src/verbs.cpp:2035 +msgid "_Object to Path" +msgstr "_Objekt na cestu" + +#: ../../po/../src/verbs.cpp:2036 +#, fuzzy +msgid "Convert selected objects to paths" +msgstr "KonvertovaÅ¥ zvolený objekt na cestu" + +#: ../../po/../src/verbs.cpp:2037 +#, fuzzy +msgid "_Flow into Frame" +msgstr "_Tok textu do tvaru" + +#: ../../po/../src/verbs.cpp:2038 +#, fuzzy +msgid "Put text into frames" +msgstr "UmiestniÅ¥ text na cestu" + +#: ../../po/../src/verbs.cpp:2039 +#, fuzzy +msgid "_Unflow" +msgstr "Zr_uÅ¡iÅ¥ tok textu" + +#: ../../po/../src/verbs.cpp:2040 +msgid "Remove text from frame (creates a single-line text object)" +msgstr "" + +#: ../../po/../src/verbs.cpp:2041 +#, fuzzy +msgid "_Convert to Text" +msgstr "KonvertovaÅ¥ text na cestu" + +#: ../../po/../src/verbs.cpp:2042 +#, fuzzy +msgid "Convert flowed text to regular text objects (preserves appearance)" +msgstr "KonvertovaÅ¥ zvolené textový tok na text" + +#: ../../po/../src/verbs.cpp:2044 +#, fuzzy +msgid "Flip _Horizontal" +msgstr "PreklopiÅ¥ v_odorovne" + +#: ../../po/../src/verbs.cpp:2044 +#, fuzzy +msgid "Flips selected objects horizontally" +msgstr "Vodorovné zarovnanie niekoľko uzlov" + +#: ../../po/../src/verbs.cpp:2047 +#, fuzzy +msgid "Flip _Vertical" +msgstr "PreklopiÅ¥ z_visle" + +#: ../../po/../src/verbs.cpp:2047 +#, fuzzy +msgid "Flips selected objects vertically" +msgstr "Zvislé zarovnanie niekoľko uzlov" + +#. Tools +#: ../../po/../src/verbs.cpp:2051 +msgid "Select" +msgstr "VybraÅ¥" + +#: ../../po/../src/verbs.cpp:2052 +msgid "Select and transform objects" +msgstr "Výber a transformácia objektov" + +#: ../../po/../src/verbs.cpp:2053 +msgid "Node Edit" +msgstr "UpraviÅ¥ uzol" + +#: ../../po/../src/verbs.cpp:2054 +msgid "Edit path nodes or control handles" +msgstr "UpraviÅ¥ cestu uzlov alebo rukoväť" + +#: ../../po/../src/verbs.cpp:2056 +msgid "Create rectangles and squares" +msgstr "Vytvorenie obdĺžnikov a Å¡tvorcov" + +#: ../../po/../src/verbs.cpp:2058 +msgid "Create circles, ellipses, and arcs" +msgstr "Vytvorenie kruhov, elíps a oblúkov" + +#: ../../po/../src/verbs.cpp:2060 +msgid "Create stars and polygons" +msgstr "Vytvorenie hviezd a mnohouholníkov" + +#: ../../po/../src/verbs.cpp:2062 +msgid "Create spirals" +msgstr "Vytvorenie Å¡pirál" + +#: ../../po/../src/verbs.cpp:2064 +msgid "Draw freehand lines" +msgstr "Kreslenie voľnou rukou" + +#: ../../po/../src/verbs.cpp:2066 +msgid "Draw Bezier curves and straight lines" +msgstr "Kreslenie Bezierových čiar a priamych čiar" + +#: ../../po/../src/verbs.cpp:2068 +msgid "Draw calligraphic lines" +msgstr "Kreslenie kaligrafických čiar" + +#: ../../po/../src/verbs.cpp:2070 +msgid "Create and edit text objects" +msgstr "Vytvorenie a úprava textových objektov" + +#: ../../po/../src/verbs.cpp:2072 +#, fuzzy +msgid "Create and edit gradients" +msgstr "Vytvorenie a úprava textových objektov" + +#: ../../po/../src/verbs.cpp:2074 +msgid "Zoom in or out" +msgstr "ZmenÅ¡iÅ¥ alebo zväčšiÅ¥" + +#: ../../po/../src/verbs.cpp:2076 +msgid "Pick averaged colors from image" +msgstr "Výber spriemerovaných farieb z obrázku" + +#: ../../po/../src/verbs.cpp:2078 +#, fuzzy +msgid "Create connectors" +msgstr "VytvoriÅ¥ vrstvu" + +#. Tool prefs +#: ../../po/../src/verbs.cpp:2081 +msgid "Selector Preferences" +msgstr "Nastavenie Výberu" + +#: ../../po/../src/verbs.cpp:2082 +#, fuzzy +msgid "Open Preferences for the Selector tool" +msgstr "OtvoriÅ¥ Inkscape nastavenia pre nástroj Výber" + +#: ../../po/../src/verbs.cpp:2083 +msgid "Node Tool Preferences" +msgstr "Nastavenie nástroja s uzlami" + +#: ../../po/../src/verbs.cpp:2084 +#, fuzzy +msgid "Open Preferences for the Node tool" +msgstr "OtvoriÅ¥ Inkscape nastavenia pre nástroj Uzol" + +#: ../../po/../src/verbs.cpp:2085 +msgid "Rectangle Preferences" +msgstr "Nastavenia obdĺžnika" + +#: ../../po/../src/verbs.cpp:2086 +#, fuzzy +msgid "Open Preferences for the Rectangle tool" +msgstr "Otvorí Inkscape nastavenia pre nástroj Obdĺžnik" + +#: ../../po/../src/verbs.cpp:2087 +msgid "Ellipse Preferences" +msgstr "Nastavenia elipsy" + +#: ../../po/../src/verbs.cpp:2088 +#, fuzzy +msgid "Open Preferences for the Ellipse tool" +msgstr "OtvoriÅ¥ Inkscape nastavenia pre nástroj Elipsa" + +#: ../../po/../src/verbs.cpp:2089 +msgid "Star Preferences" +msgstr "Nastavenia hviezdy" + +#: ../../po/../src/verbs.cpp:2090 +#, fuzzy +msgid "Open Preferences for the Star tool" +msgstr "OtvoriÅ¥ Inkscape nastavenia pre nástroj Hviezda" + +#: ../../po/../src/verbs.cpp:2091 +msgid "Spiral Preferences" +msgstr "Nastavenia Å¡pirály" + +#: ../../po/../src/verbs.cpp:2092 +#, fuzzy +msgid "Open Preferences for the Spiral tool" +msgstr "OtvoriÅ¥ Inkscape nastavenia pre nástroj Å pirála" + +#: ../../po/../src/verbs.cpp:2093 +msgid "Pencil Preferences" +msgstr "Nastavenia ceruzky" + +#: ../../po/../src/verbs.cpp:2094 +#, fuzzy +msgid "Open Preferences for the Pencil tool" +msgstr "OtvoriÅ¥ Inkscape nastavenia pre nástroj Ceruzka" + +#: ../../po/../src/verbs.cpp:2095 +msgid "Pen Preferences" +msgstr "Nastavenia pera" + +#: ../../po/../src/verbs.cpp:2096 +#, fuzzy +msgid "Open Preferences for the Pen tool" +msgstr "OtvoriÅ¥ Inkscape nastavenia pre nástroj Pero" + +#: ../../po/../src/verbs.cpp:2097 +msgid "Calligraphic Preferences" +msgstr "Nastavenia kaligrafickej čiary" + +#: ../../po/../src/verbs.cpp:2098 +#, fuzzy +msgid "Open Preferences for the Calligraphy tool" +msgstr "OtvoriÅ¥ Inkscape nastavenia pre nástroj Kaligrafia" + +#: ../../po/../src/verbs.cpp:2099 +msgid "Text Preferences" +msgstr "Nastavenie textu" + +#: ../../po/../src/verbs.cpp:2100 +#, fuzzy +msgid "Open Preferences for the Text tool" +msgstr "OtvoriÅ¥ Inkscape nastavenia pre nástroj Text" + +#: ../../po/../src/verbs.cpp:2101 +#, fuzzy +msgid "Gradient Preferences" +msgstr "Nastavenia pera" + +#: ../../po/../src/verbs.cpp:2102 +#, fuzzy +msgid "Open Preferences for the Gradient tool" +msgstr "OtvoriÅ¥ Inkscape nastavenia pre nástroj Pero" + +#: ../../po/../src/verbs.cpp:2103 +msgid "Zoom Preferences" +msgstr "Nastavenie zmeny zobrazenia" + +#: ../../po/../src/verbs.cpp:2104 +#, fuzzy +msgid "Open Preferences for the Zoom tool" +msgstr "OtvoriÅ¥ Inkscape nastavenia pre nástroj Zmena zobrazenia" + +#: ../../po/../src/verbs.cpp:2105 +msgid "Dropper Preferences" +msgstr "Nastavenie kvapkadla" + +#: ../../po/../src/verbs.cpp:2106 +#, fuzzy +msgid "Open Preferences for the Dropper tool" +msgstr "Otvorí Inkscape nastavenia pre nástroj Kvapkadlo" + +#: ../../po/../src/verbs.cpp:2107 +#, fuzzy +msgid "Connector Preferences" +msgstr "Nastavenie Výberu" + +#: ../../po/../src/verbs.cpp:2108 +#, fuzzy +msgid "Open Preferences for the Connector tool" +msgstr "OtvoriÅ¥ Inkscape nastavenia pre nástroj Výber" + +#. Zoom/View +#: ../../po/../src/verbs.cpp:2111 +msgid "Zoom In" +msgstr "ZväčšiÅ¥" + +#: ../../po/../src/verbs.cpp:2111 +msgid "Zoom in" +msgstr "ZväčšiÅ¥" + +#: ../../po/../src/verbs.cpp:2112 +msgid "Zoom Out" +msgstr "ZmenÅ¡iÅ¥" + +#: ../../po/../src/verbs.cpp:2112 +msgid "Zoom out" +msgstr "ZmenÅ¡iÅ¥" + +#: ../../po/../src/verbs.cpp:2113 +msgid "_Rulers" +msgstr "_Pravítka" + +#: ../../po/../src/verbs.cpp:2113 +msgid "Show or hide the canvas rulers" +msgstr "ZobraziÅ¥ alebo skryÅ¥ pravítka plátna" + +#: ../../po/../src/verbs.cpp:2114 +msgid "Scroll_bars" +msgstr "Po_suvníky" + +#: ../../po/../src/verbs.cpp:2114 +msgid "Show or hide the canvas scrollbars" +msgstr "ZobraziÅ¥ alebo skryÅ¥ posuvníky plátna" + +#: ../../po/../src/verbs.cpp:2115 +msgid "_Grid" +msgstr "M_riežka" + +#: ../../po/../src/verbs.cpp:2116 +msgid "G_uides" +msgstr "_Vodítka" + +#: ../../po/../src/verbs.cpp:2117 +msgid "Nex_t Zoom" +msgstr "Nasledujúca ve_ľkosÅ¥" + +#: ../../po/../src/verbs.cpp:2117 +msgid "Next zoom (from the history of zooms)" +msgstr "Nasledujúca veľkosÅ¥ zobrazenia (podľa histórie zmien zobrazenia)" + +#: ../../po/../src/verbs.cpp:2119 +msgid "Pre_vious Zoom" +msgstr "Predchádzajúca veľkosÅ¥" + +#: ../../po/../src/verbs.cpp:2119 +msgid "Previous zoom (from the history of zooms)" +msgstr "Predchádzajúca veľkosÅ¥ zobrazenia (podľa histórie zmien zobrazenia)" + +#: ../../po/../src/verbs.cpp:2121 +msgid "Zoom 1:_1" +msgstr "Mierka 1:_1" + +#: ../../po/../src/verbs.cpp:2121 +msgid "Zoom to 1:1" +msgstr "Mierka 1:1" + +#: ../../po/../src/verbs.cpp:2123 +msgid "Zoom 1:_2" +msgstr "Mierka 1:_2" + +#: ../../po/../src/verbs.cpp:2123 +msgid "Zoom to 1:2" +msgstr "Mierka 1:2" + +#: ../../po/../src/verbs.cpp:2125 +msgid "_Zoom 2:1" +msgstr "_Mierka 2:1" + +#: ../../po/../src/verbs.cpp:2125 +msgid "Zoom to 2:1" +msgstr "Mierka 2:1" + +#: ../../po/../src/verbs.cpp:2128 +msgid "_Fullscreen" +msgstr "Na _celú obrazovku" + +#: ../../po/../src/verbs.cpp:2128 +msgid "Stretch this document window to full screen" +msgstr "RoztiahnuÅ¥ okno tohoto dokumentu na celú obrazovku" + +#: ../../po/../src/verbs.cpp:2131 +#, fuzzy +msgid "Duplic_ate Window" +msgstr "D_uplikovaÅ¥ okno" + +#: ../../po/../src/verbs.cpp:2131 +msgid "Open a new window with the same document" +msgstr "OtvoriÅ¥ nové okno s rovnakým dokumentom" + +#: ../../po/../src/verbs.cpp:2133 +msgid "_New View Preview" +msgstr "_Nové zobrazenie náhľadu" + +#: ../../po/../src/verbs.cpp:2134 +msgid "New View Preview" +msgstr "Nové zobrazenie náhľadu" + +#. "view_new_preview" +#: ../../po/../src/verbs.cpp:2136 +#, fuzzy +msgid "_Normal" +msgstr "Normálne" + +#: ../../po/../src/verbs.cpp:2137 +msgid "Switch to normal display mode" +msgstr "" + +#: ../../po/../src/verbs.cpp:2138 +#, fuzzy +msgid "_Outline" +msgstr "Obrys poľa" + +#: ../../po/../src/verbs.cpp:2139 +msgid "Switch to outline (wireframe) display mode" +msgstr "" + +#: ../../po/../src/verbs.cpp:2141 +#, fuzzy +msgid "Ico_n Preview" +msgstr "Náhľad" + +#: ../../po/../src/verbs.cpp:2142 +msgid "Open a window to preview items at different icon resolutions" +msgstr "" + +#: ../../po/../src/verbs.cpp:2144 +msgid "Zoom to fit page in window" +msgstr "ZmeniÅ¥ veľkosÅ¥ zobrazenia tak, aby sa strana zmestila do okna" + +#: ../../po/../src/verbs.cpp:2145 +msgid "Page _Width" +msgstr "_Šírka strany" + +#: ../../po/../src/verbs.cpp:2146 +msgid "Zoom to fit page width in window" +msgstr "ZmeniÅ¥ veľkosÅ¥ zobrazenia podľa šírka strany" + +#: ../../po/../src/verbs.cpp:2148 +msgid "Zoom to fit drawing in window" +msgstr "ZmeniÅ¥ veľkosÅ¥ zobrazenia tak, aby sa kresba zmestila do okna" + +#: ../../po/../src/verbs.cpp:2150 +msgid "Zoom to fit selection in window" +msgstr "ZmeniÅ¥ veľkosÅ¥ zobrazenia tak, aby sa výber zmestil do okna" + +#. Dialogs +#: ../../po/../src/verbs.cpp:2153 +msgid "In_kscape Preferences..." +msgstr "In_kscape nastavenia..." + +#: ../../po/../src/verbs.cpp:2154 +msgid "Global Inkscape preferences" +msgstr "Globálne nastavenia Inkscape" + +#: ../../po/../src/verbs.cpp:2155 +msgid "_Document Preferences..." +msgstr "Vlastnosti _dokumentu..." + +#: ../../po/../src/verbs.cpp:2156 +msgid "Preferences saved with the document" +msgstr "Nastavenie uložené s dokumentom" + +#: ../../po/../src/verbs.cpp:2157 +msgid "_Fill and Stroke..." +msgstr "Výp_lň a Å¥ah..." + +#: ../../po/../src/verbs.cpp:2158 +msgid "Fill and Stroke dialog" +msgstr "Dialóg výplne a Å¥ahu" + +#. TRANSLATORS: "Swatches" means: color samples +#: ../../po/../src/verbs.cpp:2160 +#, fuzzy +msgid "S_watches..." +msgstr "UložiÅ¥ ako..." + +#: ../../po/../src/verbs.cpp:2161 +msgid "View color swatches" +msgstr "" + +#: ../../po/../src/verbs.cpp:2162 +msgid "Transfor_m..." +msgstr "Transfor_mácie..." + +#: ../../po/../src/verbs.cpp:2163 +msgid "Transform dialog" +msgstr "Dialóg transformácie" + +#: ../../po/../src/verbs.cpp:2164 +msgid "_Align and Distribute..." +msgstr "Z_arovnanie a umiestnenie..." + +#: ../../po/../src/verbs.cpp:2165 +msgid "Align and Distribute dialog" +msgstr "Dialóg zarovnania a umiestnenia" + +#: ../../po/../src/verbs.cpp:2166 +msgid "_Text and Font..." +msgstr "Text a pís_mo..." + +#: ../../po/../src/verbs.cpp:2167 +msgid "Text and Font dialog" +msgstr "Dialóg textu a písma" + +#: ../../po/../src/verbs.cpp:2168 +msgid "_XML Editor..." +msgstr "_XML Editor..." + +#: ../../po/../src/verbs.cpp:2169 +msgid "XML Editor" +msgstr "XML Editor" + +#: ../../po/../src/verbs.cpp:2170 +msgid "_Find..." +msgstr "_HľadaÅ¥..." + +#: ../../po/../src/verbs.cpp:2171 +msgid "Find objects in document" +msgstr "HľadaÅ¥ objekty v dokumente" + +#: ../../po/../src/verbs.cpp:2172 +msgid "_Messages..." +msgstr "Sprá_vy..." + +#: ../../po/../src/verbs.cpp:2173 +msgid "View debug messages" +msgstr "Zobrazenie ladiacich informácií" + +#: ../../po/../src/verbs.cpp:2174 +#, fuzzy +msgid "S_cripts..." +msgstr "_Skripty..." + +#: ../../po/../src/verbs.cpp:2175 +msgid "Run scripts" +msgstr "SpustiÅ¥ skripty" + +#: ../../po/../src/verbs.cpp:2176 +#, fuzzy +msgid "Show/Hide D_ialogs" +msgstr "Z_obraziÅ¥/SkryÅ¥ dialógy" + +#: ../../po/../src/verbs.cpp:2177 +msgid "Show or hide all active dialogs" +msgstr "ZobraziÅ¥ alebo skryÅ¥ vÅ¡etky aktívne dialógy" + +#. TRANSLATORS: "Tile clones" means: "Create tiled clones" +#: ../../po/../src/verbs.cpp:2179 +#, fuzzy +msgid "Tile clones..." +msgstr "HľadaÅ¥ klony" + +#: ../../po/../src/verbs.cpp:2180 +msgid "Create and arrange multiple clones of selection" +msgstr "" + +#: ../../po/../src/verbs.cpp:2181 +msgid "_Object Properties..." +msgstr "Nastavenia objektu..." + +#: ../../po/../src/verbs.cpp:2182 +msgid "Object Properties dialog" +msgstr "Dialóg nastavení objektu" + +#: ../../po/../src/verbs.cpp:2185 +msgid "_Connect to Jabber server..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2185 +msgid "Connect to a Jabber server" +msgstr "" + +#: ../../po/../src/verbs.cpp:2187 +#, fuzzy +msgid "Share with _user..." +msgstr "UložiÅ¥ ako..." + +#: ../../po/../src/verbs.cpp:2187 +msgid "Establish a whiteboard session with another Jabber user" +msgstr "" + +#: ../../po/../src/verbs.cpp:2189 +msgid "Share with _chatroom..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2189 +msgid "" +"Join a chatroom to start a new whiteboard session or join one in progress" +msgstr "" + +#: ../../po/../src/verbs.cpp:2191 +msgid "_Dump XML node tracker" +msgstr "" + +#: ../../po/../src/verbs.cpp:2191 +msgid "Dump the contents of the XML tracker to the console" +msgstr "" + +#: ../../po/../src/verbs.cpp:2193 +msgid "_Open session file..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2193 +msgid "Open and browse through records of past whiteboard sessions" +msgstr "" + +#: ../../po/../src/verbs.cpp:2195 +msgid "Session file playback" +msgstr "" + +#: ../../po/../src/verbs.cpp:2197 +msgid "_Disconnect from session" +msgstr "" + +#: ../../po/../src/verbs.cpp:2199 +msgid "Disconnect from _server" +msgstr "" + +#: ../../po/../src/verbs.cpp:2201 +msgid "_Input Devices..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2202 +msgid "Configure extended input devices" +msgstr "" + +#. Help +#: ../../po/../src/verbs.cpp:2205 +msgid "_Keys and Mouse" +msgstr "_Klávesnica a myÅ¡" + +#: ../../po/../src/verbs.cpp:2206 +msgid "Key and mouse shortcuts reference" +msgstr "Popis ovládaní s myÅ¡ou a klávesnicou" + +#: ../../po/../src/verbs.cpp:2207 +#, fuzzy +msgid "About E_xtensions" +msgstr "Rozpínanie:" + +#: ../../po/../src/verbs.cpp:2208 +msgid "About Extensions..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2209 +#, fuzzy +msgid "About _Memory" +msgstr "Rozpínanie:" + +#: ../../po/../src/verbs.cpp:2210 +msgid "About Memory..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2211 +msgid "_About Inkscape" +msgstr "_O Inkscape" + +#. "help_about" +#. new HelpVerb(SP_VERB_SHOW_LICENSE, "ShowLicense", N_("Modifying or Redistributing Inkscape"), +#. N_("Show license to modify and/or redistribute Inkscape: GNU GPL"), NULL), +#. Tutorials +#: ../../po/../src/verbs.cpp:2217 +msgid "Inkscape: _Basic" +msgstr "Inkscape: _Základy" + +#: ../../po/../src/verbs.cpp:2218 +msgid "Getting started with Inkscape" +msgstr "Úvod do Inkscape" + +#. "tutorial_basic" +#: ../../po/../src/verbs.cpp:2219 +msgid "Inkscape: _Shapes" +msgstr "Inkscape: _Tvary" + +#: ../../po/../src/verbs.cpp:2220 +msgid "Using shape tools to create and edit shapes" +msgstr "Používanie nástrojov na tvorbu a úpravu tvarov" + +#: ../../po/../src/verbs.cpp:2221 +msgid "Inkscape: _Advanced" +msgstr "Inkscape: _Pokročilé" + +#: ../../po/../src/verbs.cpp:2222 +msgid "Advanced Inkscape topics" +msgstr "Pokročilé témy Inkscape" + +#. "tutorial_advanced" +#. TRANSLATORS: "to trace" means "to convert a bitmap to vector graphics" (to vectorize) +#: ../../po/../src/verbs.cpp:2224 +#, fuzzy +msgid "Inkscape: T_racing" +msgstr "Inkscape: _Základy" + +#: ../../po/../src/verbs.cpp:2225 +#, fuzzy +msgid "Using bitmap tracing" +msgstr "TlačiÅ¥ ako bitmapu" + +#. "tutorial_tracing" +#: ../../po/../src/verbs.cpp:2226 +msgid "Inkscape: _Calligraphy" +msgstr "Inkscape: _Kaligrafia" + +#: ../../po/../src/verbs.cpp:2227 +#, fuzzy +msgid "Using the Calligraphy pen tool" +msgstr "Obkreslenie pomocou kresliaceho nástroja" + +#: ../../po/../src/verbs.cpp:2228 +msgid "_Elements of Design" +msgstr "_Prvky dizajnu" + +#: ../../po/../src/verbs.cpp:2229 +#, fuzzy +msgid "Principles of design in the tutorial form" +msgstr "Popis dizajnérskych prvkov" + +#. "tutorial_design" +#: ../../po/../src/verbs.cpp:2230 +msgid "_Tips and Tricks" +msgstr "_Tipy a triky" + +#: ../../po/../src/verbs.cpp:2231 +#, fuzzy +msgid "Miscellaneous tips and tricks" +msgstr "Rôzne symboly a šípky" + +#. "tutorial_tips" +#. Effect +#: ../../po/../src/verbs.cpp:2234 +msgid "Previous Effect" +msgstr "Predchádzajúci efekt" + +#: ../../po/../src/verbs.cpp:2235 +msgid "Repeat the last effect with the same settings" +msgstr "" + +#. "tutorial_tips" +#: ../../po/../src/verbs.cpp:2236 +#, fuzzy +msgid "Previous Effect Settings..." +msgstr "Predchádzajúci efekt..." + +#: ../../po/../src/verbs.cpp:2237 +msgid "Repeat the last effect with new settings" +msgstr "" + +#: ../../po/../src/widgets/dash-selector.cpp:106 +msgid "Dash pattern" +msgstr "Vzorka čiarkovania" + +#: ../../po/../src/widgets/dash-selector.cpp:121 +msgid "Pattern offset" +msgstr "Posun vzorky" + +#: ../../po/../src/widgets/desktop-widget.cpp:240 +msgid "Zoom drawing if window size changes" +msgstr "ZmeniÅ¥ veľkosÅ¥ zobrazenia, ak sa mení veľkosÅ¥ okna" + +#: ../../po/../src/widgets/desktop-widget.cpp:298 +msgid "Cursor coordinates" +msgstr "Súradnice kurzoru" + +# sp_set_font_size (dtw->select_status, STATUS_BAR_FONT_SIZE); // setting absolute size is bad, in some themes it ends up being larger! +# display the initial welcome message in the statusbar +#. display the initial welcome message in the statusbar +#: ../../po/../src/widgets/desktop-widget.cpp:324 +msgid "" +"Welcome to Inkscape! Use shape or freehand tools to create objects; " +"use selector (arrow) to move or transform them." +msgstr "" +"Vitajte v Inkscape! Použite dostupné nástroje na vytvorenie objektov; " +"použite Výber (šípku) na ich presun a transformáciu." + +#: ../../po/../src/widgets/desktop-widget.cpp:372 +#, c-format +msgid "%s: %d - Inkscape" +msgstr "%s: %d - Inkscape" + +#: ../../po/../src/widgets/desktop-widget.cpp:374 +#, c-format +msgid "%s - Inkscape" +msgstr "%s - Inkscape" + +#: ../../po/../src/widgets/desktop-widget.cpp:532 +#, c-format +msgid "" +"Save changes to document \"%s\" before " +"closing?\n" +"\n" +"If you close without saving, your changes will be discarded." +msgstr "" +"Uloženie zmien do dokumentu \"%s\" " +"pred skončením?\n" +"\n" +"Ak skončíte bez uloženia, vaÅ¡e zmeny sa nezachovajú." + +#: ../../po/../src/widgets/desktop-widget.cpp:548 +#: ../../po/../src/widgets/desktop-widget.cpp:612 +msgid "Close _without saving" +msgstr "ZatvoriÅ¥ _bez uloženia" + +#: ../../po/../src/widgets/desktop-widget.cpp:595 +#, c-format +msgid "" +"The file \"%s\" was saved with a " +"format (%s) that may cause data loss!\n" +"\n" +"Do you want to save this file in another format?" +msgstr "" +"The file \"%s\" bol uložený vo formáte " +"(%s), ktorý môže spôsobiÅ¥ stratu dát!\n" +"\n" +"Chcete uložiÅ¥ tento súbor v inom formáte?" + +#. Family frame +#: ../../po/../src/widgets/font-selector.cpp:156 +msgid "Font family" +msgstr "Rodina písma" + +#. Style frame +#: ../../po/../src/widgets/font-selector.cpp:184 +msgid "Style" +msgstr "Å týl" + +#: ../../po/../src/widgets/font-selector.cpp:219 +msgid "Font size:" +msgstr "VeľkosÅ¥ písma:" + +#. TRANSLATORS: Test string used in text and font dialog (when no +#. * text has been entered) to get a preview of the font. Choose +#. * some representative characters that users of your locale will be +#. * interested in. +#: ../../po/../src/widgets/font-selector.cpp:554 +msgid "AaBbCcIiPpQq12368.;/()" +msgstr "AaBbCcIiPpQqžšťď12368.;/()" + +#: ../../po/../src/widgets/gradient-selector.cpp:137 +#: ../../po/../src/widgets/gradient-toolbar.cpp:524 +#, fuzzy +msgid "Duplicate" +msgstr "Duplikov_aÅ¥" + +#: ../../po/../src/widgets/gradient-selector.cpp:142 +#: ../../po/../src/widgets/gradient-toolbar.cpp:535 +#, fuzzy +msgid "Edit..." +msgstr "UpraviÅ¥" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/pservers.html#LinearGradientSpreadMethodAttribute +#: ../../po/../src/widgets/gradient-selector.cpp:159 +msgid "" +"Whether to fill with flat color beyond the ends of the gradient vector " +"(spreadMethod=\"pad\"), or repeat the gradient in the same direction " +"(spreadMethod=\"repeat\"), or repeat the gradient in alternating opposite " +"directions (spreadMethod=\"reflect\")" +msgstr "" +"Či vyplniÅ¥ hladkou farbou konce vektorov prechodov (spreadMethod=\"pad\"), " +"alebo opakovaÅ¥ prechod v tom istom smere (spreadMethod=\"repeat\"), alebo " +"opakovaÅ¥ prechod v alternatívnom opačnom smere (spreadMethod=\"reflect\")" + +#: ../../po/../src/widgets/gradient-selector.cpp:165 +msgid "none" +msgstr "žiadne" + +#: ../../po/../src/widgets/gradient-selector.cpp:169 +msgid "reflected" +msgstr "odrazené" + +#: ../../po/../src/widgets/gradient-selector.cpp:173 +msgid "direct" +msgstr "priame" + +#: ../../po/../src/widgets/gradient-selector.cpp:181 +msgid "Repeat:" +msgstr "OpakovaÅ¥:" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:217 +msgid "No gradients" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:226 +msgid "Nothing selected" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:237 +#, fuzzy +msgid "No gradients in selection" +msgstr "Žiadny prechod nebol zvolený" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:247 +msgid "Multiple gradients" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:525 +msgid "" +"If the gradient is used by more than one object, create a copy of it for the " +"selected object(s)" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:536 +#, fuzzy +msgid "Edit the stops of the gradient" +msgstr "V prechode nie sú stopy" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:593 +#: ../../po/../src/widgets/toolbox.cpp:1103 +#: ../../po/../src/widgets/toolbox.cpp:1192 +#: ../../po/../src/widgets/toolbox.cpp:1485 +#: ../../po/../src/widgets/toolbox.cpp:1534 +#: ../../po/../src/widgets/toolbox.cpp:1766 +#: ../../po/../src/widgets/toolbox.cpp:1801 +#: ../../po/../src/widgets/toolbox.cpp:2331 +#: ../../po/../src/widgets/toolbox.cpp:2370 +msgid "New:" +msgstr "Nový:" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:606 +#, fuzzy +msgid "Create linear gradient" +msgstr "Lineárny prechod" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:620 +msgid "Create radial (elliptic or circular) gradient" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:635 +#, fuzzy +msgid "on" +msgstr "žiadne" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:648 +msgid "Create gradient in the fill" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:662 +msgid "Create gradient in the stroke" +msgstr "" + +#. FIXME: implement averaging of all parameters for multiple selected stars +#. gtk_label_set_markup(GTK_LABEL(l), _("Average:")); +#. FIXME: implement averaging of all parameters for multiple selected +#. gtk_label_set_markup(GTK_LABEL(l), _("Average:")); +#: ../../po/../src/widgets/gradient-toolbar.cpp:676 +#: ../../po/../src/widgets/toolbox.cpp:1105 +#: ../../po/../src/widgets/toolbox.cpp:1124 +#: ../../po/../src/widgets/toolbox.cpp:1493 +#: ../../po/../src/widgets/toolbox.cpp:1518 +#: ../../po/../src/widgets/toolbox.cpp:1768 +#: ../../po/../src/widgets/toolbox.cpp:1787 +#: ../../po/../src/widgets/toolbox.cpp:2334 +#: ../../po/../src/widgets/toolbox.cpp:2354 +msgid "Change:" +msgstr "ZmeniÅ¥:" + +#: ../../po/../src/widgets/gradient-vector.cpp:269 +msgid "No gradients in document" +msgstr "V dokumente nie je prechod" + +#: ../../po/../src/widgets/gradient-vector.cpp:275 +msgid "No gradient selected" +msgstr "Žiadny prechod nebol zvolený" + +#: ../../po/../src/widgets/gradient-vector.cpp:532 +msgid "No stops in gradient" +msgstr "V prechode nie sú stopy" + +#. TRANSLATORS: "Stop" means: a "phase" of a gradient +#: ../../po/../src/widgets/gradient-vector.cpp:794 +msgid "Add stop" +msgstr "PridaÅ¥ stop" + +#: ../../po/../src/widgets/gradient-vector.cpp:797 +msgid "Add another control stop to gradient" +msgstr "PridaÅ¥ ďalší kontrolný stop do prechodu" + +#: ../../po/../src/widgets/gradient-vector.cpp:799 +msgid "Delete stop" +msgstr "ZmazaÅ¥ stop" + +#: ../../po/../src/widgets/gradient-vector.cpp:802 +msgid "Delete current control stop from gradient" +msgstr "ZmazaÅ¥ aktuálny stop z prechodu" + +#. Label +#: ../../po/../src/widgets/gradient-vector.cpp:813 +msgid "Offset:" +msgstr "Posun:" + +#. TRANSLATORS: "Stop" means: a "phase" of a gradient +#: ../../po/../src/widgets/gradient-vector.cpp:858 +msgid "Stop Color" +msgstr "Koncová farby" + +#: ../../po/../src/widgets/gradient-vector.cpp:887 +msgid "Gradient editor" +msgstr "Editor prechodov" + +#: ../../po/../src/widgets/layer-selector.cpp:119 +#, fuzzy +msgid "Toggle current layer visibility" +msgstr "Prepnutie vytvárania novej vrstvy" + +#: ../../po/../src/widgets/layer-selector.cpp:139 +msgid "Lock or unlock current layer" +msgstr "Zamknúť alebo odomknúť aktuálnu vrstvu" + +#: ../../po/../src/widgets/layer-selector.cpp:142 +msgid "Current layer" +msgstr "Aktuálna vrstva" + +#: ../../po/../src/widgets/layer-selector.cpp:553 +msgid "(root)" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:182 +#: ../../po/../src/widgets/paint-selector.cpp:561 +msgid "No paint" +msgstr "Bez maľovania" + +#: ../../po/../src/widgets/paint-selector.cpp:184 +#: ../../po/../src/widgets/paint-selector.cpp:629 +msgid "Flat color" +msgstr "Jednoduchá farba:" + +#: ../../po/../src/widgets/paint-selector.cpp:186 +#: ../../po/../src/widgets/paint-selector.cpp:696 +msgid "Linear gradient" +msgstr "Lineárny prechod" + +#: ../../po/../src/widgets/paint-selector.cpp:188 +#: ../../po/../src/widgets/paint-selector.cpp:699 +msgid "Radial gradient" +msgstr "Radiálny prechod" + +#: ../../po/../src/widgets/paint-selector.cpp:192 +msgid "Unset paint (make it undefined so it can be inherited)" +msgstr "" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/painting.html#FillRuleProperty +#: ../../po/../src/widgets/paint-selector.cpp:204 +msgid "" +"Any path self-intersections or subpaths create holes in the fill (fill-rule: " +"evenodd)" +msgstr "" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/painting.html#FillRuleProperty +#: ../../po/../src/widgets/paint-selector.cpp:215 +msgid "" +"Fill is solid unless a subpath is counterdirectional (fill-rule: nonzero)" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:528 +msgid "No objects" +msgstr "Bez objektov" + +#: ../../po/../src/widgets/paint-selector.cpp:539 +msgid "Multiple styles" +msgstr "Viacnásobné Å¡týly" + +#: ../../po/../src/widgets/paint-selector.cpp:550 +msgid "Paint is undefined" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:757 +msgid "No patterns in document" +msgstr "V dokumente nie je vzorka" + +#: ../../po/../src/widgets/paint-selector.cpp:872 +msgid "" +"Use Edit > Object(s) to Pattern to create a new pattern from " +"selection." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:426 +msgid "Now stroke width is scaled when objects are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:428 +msgid "Now stroke width is not scaled when objects are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:436 +msgid "" +"Now rounded rectangle corners are scaled when rectangles are " +"scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:438 +msgid "" +"Now rounded rectangle corners are not scaled when rectangles " +"are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:446 +msgid "" +"Now gradients are transformed along with their objects when " +"those are transformed (moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:448 +msgid "" +"Now gradients remain fixed when objects are transformed " +"(moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:456 +msgid "" +"Now patterns are transformed along with their objects when " +"those are transformed (moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:458 +msgid "" +"Now patterns remain fixed when objects are transformed (moved, " +"scaled, rotated, or skewed)." +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:506 +#, fuzzy +msgid "select_toolbar|X" +msgstr "Výber" + +#: ../../po/../src/widgets/select-toolbar.cpp:506 +msgid "Horizontal coordinate of selection" +msgstr "Vodorovné súradnice výberu" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:511 +#, fuzzy +msgid "select_toolbar|Y" +msgstr "Výber" + +#: ../../po/../src/widgets/select-toolbar.cpp:511 +msgid "Vertical coordinate of selection" +msgstr "Zvislé súradnice výberu" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:517 +#, fuzzy +msgid "select_toolbar|W" +msgstr "Výber" + +#: ../../po/../src/widgets/select-toolbar.cpp:517 +msgid "Width of selection" +msgstr "Šírka výberu" + +#: ../../po/../src/widgets/select-toolbar.cpp:525 +msgid "Change both width and height by the same proportion" +msgstr "ZmeniÅ¥ šírku a výšku v rovnakom pomere" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:534 +#, fuzzy +msgid "select_toolbar|H" +msgstr "Výber" + +#: ../../po/../src/widgets/select-toolbar.cpp:534 +msgid "Height of selection" +msgstr "Výška výberu" + +#: ../../po/../src/widgets/sp-color-gtkselector.cpp:62 +msgid "System" +msgstr "Systém" + +#: ../../po/../src/widgets/sp-color-notebook.cpp:322 +#, fuzzy +msgid "RGBA_:" +msgstr "RGB" + +#: ../../po/../src/widgets/sp-color-notebook.cpp:330 +msgid "Hexadecimal RGBA value of the color" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "RGB" +msgstr "RGB" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +#, fuzzy +msgid "HSL" +msgstr "HSV" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "CMYK" +msgstr "CMYK" + +#: ../../po/../src/widgets/sp-color-scales.cpp:397 +msgid "_R" +msgstr "_R" + +#: ../../po/../src/widgets/sp-color-scales.cpp:398 +#: ../../po/../src/widgets/sp-color-scales.cpp:399 +msgid "Red" +msgstr "_Červená" + +#: ../../po/../src/widgets/sp-color-scales.cpp:400 +msgid "_G" +msgstr "_G" + +#: ../../po/../src/widgets/sp-color-scales.cpp:401 +#: ../../po/../src/widgets/sp-color-scales.cpp:402 +msgid "Green" +msgstr "Zelená" + +#: ../../po/../src/widgets/sp-color-scales.cpp:403 +msgid "_B" +msgstr "_B" + +#: ../../po/../src/widgets/sp-color-scales.cpp:404 +#: ../../po/../src/widgets/sp-color-scales.cpp:405 +msgid "Blue" +msgstr "Modrá" + +#. Label +#: ../../po/../src/widgets/sp-color-scales.cpp:406 +#: ../../po/../src/widgets/sp-color-scales.cpp:432 +#: ../../po/../src/widgets/sp-color-scales.cpp:463 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:141 +msgid "_A" +msgstr "_A" + +#: ../../po/../src/widgets/sp-color-scales.cpp:407 +#: ../../po/../src/widgets/sp-color-scales.cpp:408 +#: ../../po/../src/widgets/sp-color-scales.cpp:433 +#: ../../po/../src/widgets/sp-color-scales.cpp:434 +#: ../../po/../src/widgets/sp-color-scales.cpp:464 +#: ../../po/../src/widgets/sp-color-scales.cpp:465 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:151 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:163 +msgid "Alpha (opacity)" +msgstr "Alpha (nepriesvitnosÅ¥)" + +#: ../../po/../src/widgets/sp-color-scales.cpp:423 +msgid "_H" +msgstr "_H" + +#: ../../po/../src/widgets/sp-color-scales.cpp:424 +#: ../../po/../src/widgets/sp-color-scales.cpp:425 +msgid "Hue" +msgstr "Odtieň" + +#: ../../po/../src/widgets/sp-color-scales.cpp:426 +msgid "_S" +msgstr "_S" + +#: ../../po/../src/widgets/sp-color-scales.cpp:427 +#: ../../po/../src/widgets/sp-color-scales.cpp:428 +msgid "Saturation" +msgstr "SýtosÅ¥" + +#: ../../po/../src/widgets/sp-color-scales.cpp:429 +msgid "_L" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:430 +#: ../../po/../src/widgets/sp-color-scales.cpp:431 +#, fuzzy +msgid "Lightness" +msgstr "Jas" + +#: ../../po/../src/widgets/sp-color-scales.cpp:451 +msgid "_C" +msgstr "_C" + +#: ../../po/../src/widgets/sp-color-scales.cpp:452 +#: ../../po/../src/widgets/sp-color-scales.cpp:453 +msgid "Cyan" +msgstr "Azúrová" + +#: ../../po/../src/widgets/sp-color-scales.cpp:454 +msgid "_M" +msgstr "_M" + +#: ../../po/../src/widgets/sp-color-scales.cpp:455 +#: ../../po/../src/widgets/sp-color-scales.cpp:456 +msgid "Magenta" +msgstr "Fialová" + +#: ../../po/../src/widgets/sp-color-scales.cpp:457 +msgid "_Y" +msgstr "_Y" + +#: ../../po/../src/widgets/sp-color-scales.cpp:458 +#: ../../po/../src/widgets/sp-color-scales.cpp:459 +msgid "Yellow" +msgstr "Žltá" + +#: ../../po/../src/widgets/sp-color-scales.cpp:460 +msgid "_K" +msgstr "_K" + +#: ../../po/../src/widgets/sp-color-selector.cpp:71 +msgid "Unnamed" +msgstr "Nepomenovaný" + +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:68 +msgid "Wheel" +msgstr "Koleso" + +#: ../../po/../src/widgets/sp-xmlview-attr-list.cpp:53 +msgid "Attribute" +msgstr "Atribút" + +#: ../../po/../src/widgets/sp-xmlview-attr-list.cpp:54 +msgid "Value" +msgstr "Hodnota" + +#: ../../po/../src/widgets/toolbox.cpp:424 +msgid "Insert new nodes into selected segments" +msgstr "VložiÅ¥ nové uzly do vybraných segmentov" + +#: ../../po/../src/widgets/toolbox.cpp:426 +msgid "Delete selected nodes" +msgstr "ZmazaÅ¥ zvolené uzly" + +#: ../../po/../src/widgets/toolbox.cpp:431 +msgid "Join paths at selected nodes" +msgstr "SpojiÅ¥ cesty vo vybraných uzloch" + +#: ../../po/../src/widgets/toolbox.cpp:433 +msgid "Join paths at selected nodes with new segment" +msgstr "SpojiÅ¥ cesty vo vybraných uzloch s novým segmentom" + +#: ../../po/../src/widgets/toolbox.cpp:436 +msgid "Split path between two non-endpoint nodes" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:439 +msgid "Break path at selected nodes" +msgstr "RozdeliÅ¥ cestu v zvolenom uzle" + +#: ../../po/../src/widgets/toolbox.cpp:444 +msgid "Make selected nodes corner" +msgstr "KonvertovaÅ¥ vybrané uzly na rohy" + +#: ../../po/../src/widgets/toolbox.cpp:447 +msgid "Make selected nodes smooth" +msgstr "KonvertovaÅ¥ vybrané uzly na rovné" + +#: ../../po/../src/widgets/toolbox.cpp:450 +msgid "Make selected nodes symmetric" +msgstr "UrobiÅ¥ zvolené uzly symetrickými" + +#: ../../po/../src/widgets/toolbox.cpp:455 +msgid "Make selected segments lines" +msgstr "KonvertovaÅ¥ vybrané segmenty na čiary" + +#: ../../po/../src/widgets/toolbox.cpp:458 +msgid "Make selected segments curves" +msgstr "KonvertovaÅ¥ vybrané segmenty na krivky" + +#: ../../po/../src/widgets/toolbox.cpp:1199 +msgid "Polygon" +msgstr "Mnohouholník" + +#: ../../po/../src/widgets/toolbox.cpp:1206 +msgid "Regular polygon (with one handle) instead of a star" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1218 +msgid "Corners:" +msgstr "Rohy:" + +#: ../../po/../src/widgets/toolbox.cpp:1218 +msgid "Number of corners of a polygon or star" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1228 +msgid "Spoke ratio:" +msgstr "Koeficient paprskov:" + +#. TRANSLATORS: Tip radius of a star is the distance from the center to the farthest handle. +#. Base radius is the same for the closest handle. +#: ../../po/../src/widgets/toolbox.cpp:1231 +msgid "Base radius to tip radius ratio" +msgstr "Základný polomer k vrcholu koeficientu polomeru" + +#: ../../po/../src/widgets/toolbox.cpp:1246 +msgid "Rounded:" +msgstr "Nezaoblenie:" + +#: ../../po/../src/widgets/toolbox.cpp:1246 +msgid "How much rounded are the corners (0 for sharp)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1256 +msgid "Randomized:" +msgstr "NáhodnosÅ¥:" + +#: ../../po/../src/widgets/toolbox.cpp:1256 +msgid "Scatter randomly the corners and angles" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1269 +#: ../../po/../src/widgets/toolbox.cpp:1838 +#: ../../po/../src/widgets/toolbox.cpp:2061 +msgid "Defaults" +msgstr "Å tandardné" + +#: ../../po/../src/widgets/toolbox.cpp:1270 +#: ../../po/../src/widgets/toolbox.cpp:1839 +#: ../../po/../src/widgets/toolbox.cpp:2062 +msgid "" +"Reset shape parameters to defaults (use Inkscape Preferences > Tools to " +"change defaults)" +msgstr "" +"NastaviÅ¥ parametre tvaru na Å¡tandardné hodnoty (použite Inkscape Nastavenia " +"> Nástroje na zmenu Å¡tandardných hodnôt)" + +#: ../../po/../src/widgets/toolbox.cpp:1544 +msgid "W:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1544 +#, fuzzy +msgid "Width of rectangle" +msgstr "Šírka výberu" + +#: ../../po/../src/widgets/toolbox.cpp:1556 +#, fuzzy +msgid "Height of rectangle" +msgstr "Výška výberu" + +#: ../../po/../src/widgets/toolbox.cpp:1568 +msgid "Rx:" +msgstr "Rx:" + +#: ../../po/../src/widgets/toolbox.cpp:1568 +msgid "Horizontal radius of rounded corners" +msgstr "Vodorovný polomer zaokrúhlenia rohov" + +#: ../../po/../src/widgets/toolbox.cpp:1578 +msgid "Ry:" +msgstr "Ry:" + +#: ../../po/../src/widgets/toolbox.cpp:1578 +msgid "Vertical radius of rounded corners" +msgstr "Zvislý polomer zaokrúhlenia rohov" + +#: ../../po/../src/widgets/toolbox.cpp:1594 +msgid "Not rounded" +msgstr "Nezaoblený" + +#: ../../po/../src/widgets/toolbox.cpp:1596 +msgid "Make corners sharp" +msgstr "VytvoriÅ¥ ostré rohy" + +#: ../../po/../src/widgets/toolbox.cpp:1805 +msgid "Turns:" +msgstr "Otočenia:" + +#: ../../po/../src/widgets/toolbox.cpp:1805 +msgid "Number of revolutions" +msgstr "Počet revolúcií" + +#: ../../po/../src/widgets/toolbox.cpp:1815 +msgid "Divergence:" +msgstr "Divergencia:" + +#: ../../po/../src/widgets/toolbox.cpp:1815 +msgid "How much denser/sparser are outer revolutions; 1 = uniform" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1825 +msgid "Inner radius:" +msgstr "Vnútorný polomer:" + +#: ../../po/../src/widgets/toolbox.cpp:1825 +msgid "Radius of the innermost revolution (relative to the spiral size)" +msgstr "Polomer najvnútornejÅ¡ej revolúcie (relatívne k veľkosti Å¡pirály)" + +#: ../../po/../src/widgets/toolbox.cpp:1957 +#, fuzzy +msgid "The width of the calligraphic pen (relative to the visible canvas area)" +msgstr "Šírka kaligrafického pera" + +#: ../../po/../src/widgets/toolbox.cpp:1967 +msgid "Thinning:" +msgstr "ZtenÅ¡ovanie:" + +#: ../../po/../src/widgets/toolbox.cpp:1967 +msgid "" +"How much velocity thins the stroke (> 0 makes fast strokes thinner, < 0 " +"makes them broader, 0 makes width independent of velocity)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1980 +msgid "Angle:" +msgstr "Uhol:" + +#: ../../po/../src/widgets/toolbox.cpp:1980 +msgid "" +"The angle of the pen's nib (in degrees; 0 = horizontal; has no effect if " +"fixation = 0)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1990 +msgid "Fixation:" +msgstr "Fixácie:" + +#: ../../po/../src/widgets/toolbox.cpp:1990 +msgid "" +"How fixed is the pen angle (0 = always perpendicular to stroke direction, 1 " +"= fixed)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2003 +msgid "Mass:" +msgstr "Hmota:" + +#: ../../po/../src/widgets/toolbox.cpp:2003 +msgid "How much inertia affects the movement of the pen" +msgstr "" + +#. TRANSLATORS: "drag" means "resistance" here +#: ../../po/../src/widgets/toolbox.cpp:2014 +msgid "Drag:" +msgstr "ŤahaÅ¥:" + +#: ../../po/../src/widgets/toolbox.cpp:2014 +msgid "How much resistance affects the movement of the pen" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2034 +msgid "Use the pressure of the input device to alter the width of the pen" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2047 +msgid "Use the tilt of the input device to alter the angle of the pen's nib" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2374 +msgid "Start:" +msgstr "Začiatok:" + +#: ../../po/../src/widgets/toolbox.cpp:2374 +msgid "The angle (in degrees) from the horizontal to the arc's start point" +msgstr "Uhol (v stupňoch) z vodorovného počiatočného bodu oblúka" + +#: ../../po/../src/widgets/toolbox.cpp:2384 +msgid "End:" +msgstr "Koniec:" + +#: ../../po/../src/widgets/toolbox.cpp:2384 +msgid "The angle (in degrees) from the horizontal to the arc's end point" +msgstr "Uhol (v stupňoch) z vodorovného koncového bodu oblúka" + +#: ../../po/../src/widgets/toolbox.cpp:2395 +msgid "Open arc" +msgstr "Otvorený oblúk" + +#: ../../po/../src/widgets/toolbox.cpp:2396 +msgid "" +"Switch between arc (unclosed shape) and segment (closed shape with two radii)" +msgstr "" +"Prepína medzi oblúkom (neuzavretý tvar) a segmentom (uzavretý tvar s dvoma " +"polomermi)" + +#: ../../po/../src/widgets/toolbox.cpp:2415 +msgid "Make whole" +msgstr "VytvoriÅ¥ celok" + +#: ../../po/../src/widgets/toolbox.cpp:2417 +msgid "Make the shape a whole ellipse, not arc or segment" +msgstr "VytvoriÅ¥ tvar celej elipsy, nie oblúk alebo segment" + +#: ../../po/../src/widgets/toolbox.cpp:2644 +msgid "" +"When pressed, picks visible color without alpha and when not pressed, picks " +"color including its alpha" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:3039 +#, fuzzy +msgid "Make connectors avoid selected objects" +msgstr "Prienik zvolených objektov" + +#: ../../po/../src/widgets/toolbox.cpp:3043 +#, fuzzy +msgid "Make connectors ignore selected objects" +msgstr "Prienik zvolených objektov" + +#. +#. 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 : +#: ../share/extensions/addnodes.inx.h:1 +#, fuzzy +msgid "Add Nodes" +msgstr "Uzol" + +#: ../share/extensions/addnodes.inx.h:2 +msgid "Maximum Segment Length" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:1 +msgid "AI Input" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:2 ../share/extensions/ai_output.inx.h:2 +msgid "Adobe Illustrator (*.ai)" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:3 +msgid "Open files saved with Adobe Illustrator" +msgstr "" + +#: ../share/extensions/ai_output.inx.h:1 +#, fuzzy +msgid "AI Output" +msgstr "Výstup" + +#: ../share/extensions/ai_output.inx.h:3 +#, fuzzy +msgid "Write Adobe Illustrator" +msgstr "SVG Vektorový ilustrátor" + +#: ../share/extensions/dia.inx.h:1 +msgid "A diagram created with the program Dia" +msgstr "" + +#: ../share/extensions/dia.inx.h:2 +msgid "Dia Diagram (*.dia)" +msgstr "" + +#: ../share/extensions/dia.inx.h:3 +msgid "Dia Input" +msgstr "" + +#: ../share/extensions/dia.inx.h:4 +msgid "" +"In order to import Dia files, Dia itself must be installed. You can get Dia " +"at http://www.gnome.org/projects/dia/" +msgstr "" + +#: ../share/extensions/dia.inx.h:5 +msgid "" +"The dia2svg.sh script should be installed with your Inkscape distribution. " +"If you do not have it, there is likely to be something wrong with your " +"Inkscape installation." +msgstr "" + +#: ../share/extensions/dots.inx.h:1 +#, fuzzy +msgid "Connect the Dots" +msgstr "Rohy:" + +#: ../share/extensions/dots.inx.h:2 +#, fuzzy +msgid "Dot Size" +msgstr "Strany:" + +#: ../share/extensions/dots.inx.h:3 +#, fuzzy +msgid "Font Size" +msgstr "VeľkosÅ¥ písma:" + +#: ../share/extensions/dropshadow.inx.h:1 +msgid "Color of shadow" +msgstr "" + +#: ../share/extensions/dropshadow.inx.h:2 +msgid "Dropshadow" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:1 +#: ../share/extensions/dxf_output.inx.h:1 +msgid "AutoCAD DXF (*.dxf)" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:2 +msgid "DXF Input" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:3 +msgid "Import AutoCAD's Document Exchange Format" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:4 +msgid "" +"dxf2svg may come with Inkscape, but is also at http://dxf-svg-convert." +"sourceforge.net/" +msgstr "" + +#: ../share/extensions/dxf_output.inx.h:2 +#, fuzzy +msgid "DXF Output" +msgstr "Výstup" + +#: ../share/extensions/dxf_output.inx.h:3 +msgid "DXF file written by pstoedit" +msgstr "" + +#: ../share/extensions/dxf_output.inx.h:4 +msgid "pstoedit must be installed to run see http://www.pstoedit.net/pstoedit" +msgstr "" + +#: ../share/extensions/embedimage.inx.h:1 +#, fuzzy +msgid "Embed Images" +msgstr "Obrázok" + +#: ../share/extensions/eps_input.inx.h:1 +msgid "EPS Input" +msgstr "" + +#: ../share/extensions/eps_input.inx.h:2 +msgid "Encapsulated Postscript" +msgstr "" + +#: ../share/extensions/eps_input.inx.h:3 +msgid "Encapsulated Postscript (*.eps)" +msgstr "" + +#: ../share/extensions/epsi_output.inx.h:1 +#, fuzzy +msgid "EPSI Output" +msgstr "Výstup" + +#: ../share/extensions/epsi_output.inx.h:2 +msgid "Encapsulated Postscript Interchange (*.epsi)" +msgstr "" + +#: ../share/extensions/epsi_output.inx.h:3 +msgid "Encapsulated Postscript with a thumbnail" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:1 ../share/extensions/ffms.inx.h:1 +#: ../share/extensions/ffset.inx.h:1 ../share/extensions/ffss.inx.h:1 +#, fuzzy +msgid "Bridge Width" +msgstr "Šírka čiary" + +#: ../share/extensions/ffmet.inx.h:2 ../share/extensions/ffms.inx.h:2 +msgid "First String Length" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:3 +msgid "FretFind Multi Length ET" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:4 ../share/extensions/ffms.inx.h:4 +#: ../share/extensions/ffset.inx.h:3 ../share/extensions/ffss.inx.h:3 +msgid "Fretboard Edges" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:5 ../share/extensions/ffms.inx.h:5 +msgid "Last String Length" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:6 ../share/extensions/ffms.inx.h:6 +#: ../share/extensions/ffset.inx.h:4 ../share/extensions/ffss.inx.h:4 +#, fuzzy +msgid "Number of Frets" +msgstr "Počet revolúcií" + +#: ../share/extensions/ffmet.inx.h:7 ../share/extensions/ffms.inx.h:7 +#: ../share/extensions/ffset.inx.h:5 ../share/extensions/ffss.inx.h:5 +#, fuzzy +msgid "Number of Strings" +msgstr "Počet revolúcií" + +#: ../share/extensions/ffmet.inx.h:8 ../share/extensions/ffms.inx.h:8 +#: ../share/extensions/ffset.inx.h:6 ../share/extensions/ffss.inx.h:6 +#, fuzzy +msgid "Nut Width" +msgstr "Šírka:" + +#: ../share/extensions/ffmet.inx.h:9 ../share/extensions/ffms.inx.h:10 +msgid "Perpendicular Distance" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:10 ../share/extensions/ffset.inx.h:7 +msgid "Scale Base (2 for Octave)" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:11 ../share/extensions/ffset.inx.h:9 +msgid "Tones in Scale" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:12 ../share/extensions/ffms.inx.h:12 +#: ../share/extensions/ffset.inx.h:10 ../share/extensions/ffss.inx.h:10 +msgid "px per Unit" +msgstr "" + +#: ../share/extensions/ffms.inx.h:3 +msgid "FretFind Multi Length Scala" +msgstr "" + +#: ../share/extensions/ffms.inx.h:9 ../share/extensions/ffss.inx.h:7 +msgid "Path to Scala *.scl File" +msgstr "" + +#: ../share/extensions/ffms.inx.h:11 +msgid "Tuning (scale step for each string seperated by semicolons)" +msgstr "" + +#: ../share/extensions/ffset.inx.h:2 +msgid "FretFind Single Length ET" +msgstr "" + +#: ../share/extensions/ffset.inx.h:8 ../share/extensions/ffss.inx.h:8 +msgid "Scale Length" +msgstr "" + +#: ../share/extensions/ffss.inx.h:2 +msgid "FretFind Single Length Scala" +msgstr "" + +#: ../share/extensions/ffss.inx.h:9 +msgid "Tuning (Scale step for each string seperated by semicolons)" +msgstr "" + +#: ../share/extensions/handles.inx.h:1 +#, fuzzy +msgid "Draw Handles" +msgstr "Kreslenie voľnou rukou" + +#: ../share/extensions/interp.inx.h:1 +#, fuzzy +msgid "Duplicate Endpaths" +msgstr "DuplikovaÅ¥ uzol" + +#: ../share/extensions/interp.inx.h:2 +#, fuzzy +msgid "Exponent" +msgstr "Export" + +#: ../share/extensions/interp.inx.h:3 +msgid "Interpolate" +msgstr "" + +#: ../share/extensions/interp.inx.h:4 +msgid "Interpolate Style (Experimental)" +msgstr "" + +#: ../share/extensions/interp.inx.h:5 +msgid "Interpolation Method" +msgstr "" + +#: ../share/extensions/interp.inx.h:6 +msgid "Interpolation Steps" +msgstr "" + +#: ../share/extensions/kochify.inx.h:1 +msgid "Kochify" +msgstr "" + +#: ../share/extensions/kochify_load.inx.h:1 +msgid "Kochify (Load)" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:1 +#, fuzzy +msgid "Angle" +msgstr "Uhol:" + +#: ../share/extensions/lindenmayer.inx.h:2 +msgid "Axiom" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:3 +#, fuzzy +msgid "Lindenmayer" +msgstr "PremenovaÅ¥ vrstvu" + +#: ../share/extensions/lindenmayer.inx.h:4 +msgid "Order" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:5 +#, fuzzy +msgid "Rules" +msgstr "_Pravítka" + +#: ../share/extensions/lindenmayer.inx.h:6 +#, fuzzy +msgid "Step" +msgstr "Kroky" + +#: ../share/extensions/motion.inx.h:1 +#, fuzzy +msgid "Direction" +msgstr "Popis" + +#: ../share/extensions/motion.inx.h:2 +#, fuzzy +msgid "Magnitude" +msgstr "Fialová" + +#: ../share/extensions/motion.inx.h:3 +#, fuzzy +msgid "Motion" +msgstr "_Rotácia" + +#: ../share/extensions/pdf_output.inx.h:1 +msgid "Adobe PDF (*.pdf)" +msgstr "" + +#: ../share/extensions/pdf_output.inx.h:2 +msgid "Adobe Portable Document Format" +msgstr "" + +#: ../share/extensions/pdf_output.inx.h:3 +#, fuzzy +msgid "PDF Output" +msgstr "Výstup" + +#: ../share/extensions/ps_input.inx.h:1 +#, fuzzy +msgid "Postscript" +msgstr "Na výšku" + +#: ../share/extensions/ps_input.inx.h:2 +msgid "Postscript (*.ps)" +msgstr "" + +#: ../share/extensions/ps_input.inx.h:3 +msgid "Postscript Input" +msgstr "" + +#: ../share/extensions/radiusrand.inx.h:1 +#, fuzzy +msgid "Radius" +msgstr "Polomer:" + +#: ../share/extensions/radiusrand.inx.h:2 +#, fuzzy +msgid "Radius Randomize" +msgstr "NáhodnosÅ¥:" + +#: ../share/extensions/radiusrand.inx.h:3 +msgid "Randomize Control Points" +msgstr "" + +#: ../share/extensions/radiusrand.inx.h:4 +#, fuzzy +msgid "Randomize Nodes" +msgstr "NáhodnosÅ¥:" + +#: ../share/extensions/rtree.inx.h:1 +#, fuzzy +msgid "Initial Size" +msgstr "VeľkosÅ¥ bitmapy" + +#: ../share/extensions/rtree.inx.h:2 +msgid "Minimum Size" +msgstr "" + +#: ../share/extensions/rtree.inx.h:3 +#, fuzzy +msgid "Random Tree" +msgstr "NáhodnosÅ¥:" + +#: ../share/extensions/sk_input.inx.h:1 +msgid "A diagram created with the program Sketch" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:2 +msgid "Sketch Diagram (*.sk)" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:3 +msgid "Sketch Input" +msgstr "" + +#: ../share/extensions/straightseg.inx.h:1 +msgid "Behavior" +msgstr "" + +#: ../share/extensions/straightseg.inx.h:3 +msgid "Segment Straightener" +msgstr "" + +#: ../share/extensions/summersnight.inx.h:1 +msgid "Summer's Night" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:1 +#: ../share/extensions/svgz_output.inx.h:1 +msgid "Compressed Inkscape SVG (*.svgz)" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:2 +#: ../share/extensions/svgz_output.inx.h:2 +msgid "Inkscape's native file format compressed with GZip" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:3 +msgid "SVGZ Input" +msgstr "" + +#: ../share/extensions/svgz_output.inx.h:3 +#, fuzzy +msgid "SVGZ Output" +msgstr "Výstup" + +#: ../share/extensions/txt2svg.inx.h:1 +msgid "ASCII Text" +msgstr "" + +#: ../share/extensions/txt2svg.inx.h:2 +msgid "Text File (*.txt)" +msgstr "" + +#: ../share/extensions/txt2svg.inx.h:3 +#, fuzzy +msgid "Text Input" +msgstr "Nasledujúca ve_ľkosÅ¥" + +#: ../share/extensions/wavy.inx.h:1 +msgid "Calculate first derivative numerically" +msgstr "" + +#: ../share/extensions/wavy.inx.h:2 +msgid "First derivative" +msgstr "" + +#: ../share/extensions/wavy.inx.h:3 +msgid "Function" +msgstr "" + +#: ../share/extensions/wavy.inx.h:4 +msgid "Function Plotter" +msgstr "" + +#: ../share/extensions/wavy.inx.h:5 +msgid "Nodes per period" +msgstr "" + +#: ../share/extensions/wavy.inx.h:6 +msgid "Periods (2*Pi each)" +msgstr "" + +#: ../share/extensions/whirl.inx.h:1 +msgid "Amount of Whirl" +msgstr "" + +#: ../share/extensions/whirl.inx.h:2 +#, fuzzy +msgid "Center X" +msgstr "Stred X:" + +#: ../share/extensions/whirl.inx.h:3 +#, fuzzy +msgid "Center Y" +msgstr "Stred Y:" + +#: ../share/extensions/whirl.inx.h:4 +#, fuzzy +msgid "Direction of Rotation" +msgstr "Presunúť výber na najnižšiu úroveň" + +#: ../share/extensions/whirl.inx.h:5 +msgid "Whirl" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:1 +msgid "A popular graphics file format for clipart" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:2 +msgid "Windows Metafile (*.wmf)" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:3 +msgid "Windows Metafile Input" +msgstr "" + +#~ msgid "Custom canvas" +#~ msgstr "Vlastné plátno" + +#~ msgid "Current style" +#~ msgstr "Aktuálny Å¡týl" + +#~ msgid "" +#~ "Current style is updated every time you change the style of any object " +#~ "(its fill, stroke, transparency, etc.)" +#~ msgstr "" +#~ "Aktuálny Å¡týl je aktualizovaný vždy, keď zmeníte Å¡týl ktoréhokoÅ¡vek " +#~ "objektu (jeho výplň, Å¥ah, priesvitnosÅ¥, atď.)" + +#, fuzzy +#~ msgid "Arrange Objects" +#~ msgstr "Objekty" + +#~ msgid "deg" +#~ msgstr "stup." + +#~ msgid "" +#~ "%s is not a valid preferences file.\n" +#~ "%s" +#~ msgstr "" +#~ "'%s' nie je platný súboru volieb.\n" +#~ "%s" + +#, fuzzy +#~ msgid "_Credits" +#~ msgstr "Poďakovanie" + +#, fuzzy +#~ msgid "Grab sensitivity" +#~ msgstr "CitlivosÅ¥ zachytenia:" + +#, fuzzy +#~ msgid "Click/drag threshold" +#~ msgstr "Prah kliknutia/Å¥ahania:" + +#, fuzzy +#~ msgid "Mouse wheel scrolls by" +#~ msgstr "Koliesko myÅ¡i posúva o:" + +#, fuzzy +#~ msgid "Scroll by" +#~ msgstr "Posun o:" + +#, fuzzy +#~ msgid "Acceleration" +#~ msgstr "Akcelerácia:" + +#, fuzzy +#~ msgid "Speed" +#~ msgstr "RýchlosÅ¥:" + +#, fuzzy +#~ msgid "Threshold" +#~ msgstr "Prah:" + +#, fuzzy +#~ msgid "Arrow keys move by" +#~ msgstr "Šípky (klávesy) posunú o:" + +#, fuzzy +#~ msgid "> and < scale by" +#~ msgstr "> a < zmenia o:" + +#, fuzzy +#~ msgid "Inset/Outset by" +#~ msgstr "Posun dnu/von o:" + +#, fuzzy +#~ msgid "Rotation snaps every" +#~ msgstr "Krok rotácie:" + +#, fuzzy +#~ msgid "Zoom in/out by" +#~ msgstr "ZväčšiÅ¥/ZmenÅ¡iÅ¥ o:" + +#, fuzzy +#~ msgid "Transform" +#~ msgstr "Transformácie" + +# Object +#~ msgid "Rotate _90 deg CW" +#~ msgstr "OtočiÅ¥ o _90 stupňov" + +#~ msgid "Rotate 9_0 deg CCW" +#~ msgstr "OtočiÅ¥ o -_90 stupňov" + +#~ msgid "Flip selection horizontally" +#~ msgstr "PreklopiÅ¥ zvolené objekty vodorovne" + +#~ msgid "Flip selection vertically" +#~ msgstr "PreklopiÅ¥ zvolené objekty zvisle" + +#, fuzzy +#~ msgid "Could not read next message due to I/O error (error: %s)!" +#~ msgstr "Nepodarilo sa pripojiÅ¥ k hostiteľovi." + +#~ msgid "" +#~ "Show or hide parts of the document window (differently for normal and " +#~ "fullscreen modes)" +#~ msgstr "" +#~ "ZobraziÅ¥ a skryÅ¥ časti okna dokumentu (rôzne pre bežný a celoobrazovkový " +#~ "režim)" + +#~ msgid "Interactive Inkscape tutorials" +#~ msgstr "Interaktívne Inkscape návody" + +#~ msgid "Edit" +#~ msgstr "UpraviÅ¥" + +#~ msgid "Add" +#~ msgstr "PridaÅ¥" + +#~ msgid "" +#~ "Select one path object with selector first, then switch back to node tool." +#~ msgstr "" +#~ "Najskôr označte cestu s nástrojom Výber a potom si zvoľte nástroj Uzol." + +#~ msgid "C_reate" +#~ msgstr "_VytvoriÅ¥" + +#, fuzzy +#~ msgid "Automatically scale Rows to fit selected objects." +#~ msgstr "Exkluzívne OR zvolených objektov" + +#, fuzzy +#~ msgid "Go to root" +#~ msgstr "Choď: Domov" + +#, fuzzy +#~ msgid "X" +#~ msgstr "X:" + +#, fuzzy +#~ msgid "Y" +#~ msgstr "_Y" + +#~ msgid "Unicode: %c%c%c%c" +#~ msgstr "Unicode: %c%c%c%c" + +#~ msgid "Sides:" +#~ msgstr "Strany:" + +#~ msgid "R1:" +#~ msgstr "R1:" + +#~ msgid "R2:" +#~ msgstr "R2:" + +#~ msgid "ARG1:" +#~ msgstr "ARG1:" + +#~ msgid "ARG2:" +#~ msgstr "ARG2:" + +#~ msgid "Flatsides:" +#~ msgstr "Hladké strany:" + +#~ msgid "Radius X:" +#~ msgstr "Polomer X:" + +#~ msgid "Radius Y:" +#~ msgstr "Polomer Y:" + +#~ msgid "Start Angle:" +#~ msgstr "Počiatočný uhol:" + +#~ msgid "End Angle:" +#~ msgstr "Koncový uhol:" + +#~ msgid "Open:" +#~ msgstr "OtvoriÅ¥:" + +#~ msgid "Expansion:" +#~ msgstr "Rozpínanie:" + +#~ msgid "Revolutions:" +#~ msgstr "Revolúcie:" + +#~ msgid "Argument:" +#~ msgstr "Argument:" + +#~ msgid "T0:" +#~ msgstr "T0:" + +#~ msgid "RX:" +#~ msgstr "RX:" + +#~ msgid "RY:" +#~ msgstr "RY:" + +#~ msgid "Rectangle _Properties" +#~ msgstr "Nastavenia obdĺžnika" + +#~ msgid "Star _Properties" +#~ msgstr "Vlastnosti_ hviezdy" + +#, fuzzy +#~ msgid "Ellipse _Properties" +#~ msgstr "Nastavenia Diagramu" + +#~ msgid "Spiral _Properties" +#~ msgstr "Vlastnosti _Å¡pirály" + +#, fuzzy +#~ msgid "Document Preferences" +#~ msgstr "Vlastnosti _dokumentu..." + +#, fuzzy +#~ msgid "Extensions Editor" +#~ msgstr "Rozpínanie:" + +#, fuzzy +#~ msgid "Preferences" +#~ msgstr "Nastavenia pera" + +#, fuzzy +#~ msgid "Layer Editor" +#~ msgstr "XML Editor" + +#, fuzzy +#~ msgid "Text Properties" +#~ msgstr "_Vlastnosti objektu" + +#, fuzzy +#~ msgid "Transformation" +#~ msgstr "Transformačná matica" + +#, fuzzy +#~ msgid "_Export..." +#~ msgstr "_ImportovaÅ¥..." + +#, fuzzy +#~ msgid "_Document Properties" +#~ msgstr "Dokument bol obnovený." + +#, fuzzy +#~ msgid "In_kscape Preferences" +#~ msgstr "In_kscape nastavenia..." + +#, fuzzy +#~ msgid "Select _Original Clone" +#~ msgstr "VybraÅ¥ _originál" + +#, fuzzy +#~ msgid "Tile" +#~ msgstr "Titulok" + +#, fuzzy +#~ msgid "Select A_ll" +#~ msgstr "VybraÅ¥ _vÅ¡etko" + +#, fuzzy +#~ msgid "Select Non_e" +#~ msgstr "Výber" + +#, fuzzy +#~ msgid "Zoom _In" +#~ msgstr "ZväčšiÅ¥" + +#, fuzzy +#~ msgid "Zoom _Out" +#~ msgstr "ZmenÅ¡iÅ¥" + +#, fuzzy +#~ msgid "Pre_vious" +#~ msgstr "Predchádzajúca veľkosÅ¥" + +#, fuzzy +#~ msgid "Nex_t" +#~ msgstr "Nasledujúca ve_ľkosÅ¥" + +#, fuzzy +#~ msgid "_Commands bar" +#~ msgstr "Príkazový panel" + +#, fuzzy +#~ msgid "Tool Co_ntrols bar" +#~ msgstr "Ovládanie nástrojov" + +#, fuzzy +#~ msgid "_Tools bar" +#~ msgstr "_Nástrojový panel" + +#, fuzzy +#~ msgid "R_ename Layer..." +#~ msgstr "Premenov_aÅ¥ vrstvu..." + +#, fuzzy +#~ msgid "D_uplicate Layer" +#~ msgstr "DuplikovaÅ¥ uzol" + +#, fuzzy +#~ msgid "_Anchor Layer" +#~ msgstr "Z_nížiÅ¥ vrstvu" + +#, fuzzy +#~ msgid "_Delete Layer" +#~ msgstr "OdstrániÅ¥ vrstvu." + +#, fuzzy +#~ msgid "Select Ne_xt Layer" +#~ msgstr "Prepnúť do nasledujúcej vrstvy" + +#, fuzzy +#~ msgid "Select Pre_vious Layer" +#~ msgstr "Prepnúť do predchádzajúcej vrstvy" + +#, fuzzy +#~ msgid "Select To_p Layer" +#~ msgstr "Výber tlačiarne" + +#, fuzzy +#~ msgid "Move to Ne_w Layer" +#~ msgstr "Presunúť do nasledujúúcej vrstvy." + +#, fuzzy +#~ msgid "Move to Ne_xt Layer" +#~ msgstr "Presunúť do nasledujúúcej vrstvy." + +#, fuzzy +#~ msgid "Move to Pre_vious Layer" +#~ msgstr "Presunúť do predchádzajúcej vrstvy" + +#, fuzzy +#~ msgid "Move to To_p Layer" +#~ msgstr "Presunúť do nasledujúúcej vrstvy." + +#, fuzzy +#~ msgid "Move to B_ottom Layer" +#~ msgstr "Presunúť do nasledujúúcej vrstvy." + +#, fuzzy +#~ msgid "_Trace Bitmap..." +#~ msgstr "_PrekresliÅ¥ bitmapu" + +#, fuzzy +#~ msgid "_Put Text on Path" +#~ msgstr "UmiestniÅ¥ text na cestu" + +#, fuzzy +#~ msgid "_Remove Text from Path" +#~ msgstr "OdstrániÅ¥ text z cesty" + +#, fuzzy +#~ msgid "Freehand" +#~ msgstr "Dokončenie kreslenia voľnou rukou" + +#, fuzzy +#~ msgid "Corners" +#~ msgstr "Rohy:" + +#, fuzzy +#~ msgid "Delete" +#~ msgstr "_ZmazaÅ¥" + +#, fuzzy +#~ msgid "Join" +#~ msgstr "Spojnica:" + +#, fuzzy +#~ msgid "Delete Segment" +#~ msgstr "ZmazaÅ¥ výber" + +#, fuzzy +#~ msgid "Break" +#~ msgstr "Čierna" + +#, fuzzy +#~ msgid "Symmetric" +#~ msgstr "symetricky" + +#, fuzzy +#~ msgid "Line" +#~ msgstr "Licencia" + +#, fuzzy +#~ msgid "New" +#~ msgstr "_Nový" + +#, fuzzy +#~ msgid "Save" +#~ msgstr "_UložiÅ¥" + +#, fuzzy +#~ msgid "Save As..." +#~ msgstr "UložiÅ¥ ako..." + +#, fuzzy +#~ msgid "Import..." +#~ msgstr "_ImportovaÅ¥..." + +#, fuzzy +#~ msgid "Export..." +#~ msgstr "Export" + +#, fuzzy +#~ msgid "Print..." +#~ msgstr "_TlačiÅ¥..." + +#, fuzzy +#~ msgid "Global Inkscape preferences (Shift+Ctrl+P)" +#~ msgstr "Globálne nastavenia Inkscape" + +#, fuzzy +#~ msgid "Undo" +#~ msgstr "_Späť" + +#, fuzzy +#~ msgid "Redo" +#~ msgstr "_OpakovaÅ¥ vrátené" + +#, fuzzy +#~ msgid "Cut" +#~ msgstr "Vys_trihnúť" + +#, fuzzy +#~ msgid "Copy" +#~ msgstr "_KopírovaÅ¥" + +#, fuzzy +#~ msgid "Duplicate selected object(s) (Ctrl+D)" +#~ msgstr "DuplikovaÅ¥ vybrané objekty" + +#, fuzzy +#~ msgid "Clone selected object (Alt+D)" +#~ msgstr "DuplikovaÅ¥ vybrané objekty" + +#, fuzzy +#~ msgid "Zoom in (+)" +#~ msgstr "ZväčšiÅ¥" + +#, fuzzy +#~ msgid "Zoom out (-)" +#~ msgstr "ZmenÅ¡iÅ¥" + +#, fuzzy +#~ msgid "Zoom to 1:1 (100%) (1)" +#~ msgstr "Mierka 1:1" + +#, fuzzy +#~ msgid "Zoom to 1:2 (50%) (2)" +#~ msgstr "Mierka 1:2" + +#, fuzzy +#~ msgid "Zoom to 2:1 (200%) (0)" +#~ msgstr "Mierka 2:1" + +#, fuzzy +#~ msgid "Zoom to fit selection in window (3)" +#~ msgstr "ZmeniÅ¥ veľkosÅ¥ zobrazenia tak, aby sa výber zmestil do okna" + +#, fuzzy +#~ msgid "Zoom to fit drawing in window (4)" +#~ msgstr "ZmeniÅ¥ veľkosÅ¥ zobrazenia tak, aby sa kresba zmestila do okna" + +#, fuzzy +#~ msgid "Zoom to fit page in window (5)" +#~ msgstr "ZmeniÅ¥ veľkosÅ¥ zobrazenia tak, aby sa strana zmestila do okna" + +#, fuzzy +#~ msgid "Zoom to fit page width in window (6)" +#~ msgstr "ZmeniÅ¥ veľkosÅ¥ zobrazenia podľa šírka strany" + +#, fuzzy +#~ msgid "Previous zoom (from history of zooms) (`)" +#~ msgstr "Predchádzajúca veľkosÅ¥ zobrazenia (podľa histórie zmien zobrazenia)" + +#, fuzzy +#~ msgid "Next zoom (from history of zooms) (Shift+`)" +#~ msgstr "Nasledujúca veľkosÅ¥ zobrazenia (podľa histórie zmien zobrazenia)" + +#, fuzzy +#~ msgid "Fill and Stroke dialog (Shift+Ctrl+F)" +#~ msgstr "Dialóg výplne a Å¥ahu" + +#, fuzzy +#~ msgid "Group selected objects (Ctrl+G)" +#~ msgstr "Zoskupí zvolené objekty" + +#, fuzzy +#~ msgid "Ungroup selected group(s) (Ctrl+U)" +#~ msgstr "Zruší zoskupenie vybraných objektov" + +#, fuzzy +#~ msgid "Raise selection up one step (PgUp)" +#~ msgstr "Presunúť výber o jednu úroveň" + +#, fuzzy +#~ msgid "Lower selection down one step (PgDn)" +#~ msgstr "ZnížiÅ¥ výber o jednu úroveň" + +#, fuzzy +#~ msgid "Raise selection to top (Home)" +#~ msgstr "Presunúť výber na najvyÅ¡Å¡iu úroveň" + +#, fuzzy +#~ msgid "Lower selection to bottom (End)" +#~ msgstr "Presunúť výber na najnižšiu úroveň" + +#, fuzzy +#~ msgid "Move selection to new layer" +#~ msgstr "ZnížiÅ¥ výber o jednu úroveň" + +#, fuzzy +#~ msgid "Move selection to next layer" +#~ msgstr "Presunúť do nasledujúúcej vrstvy." + +#, fuzzy +#~ msgid "Move selection to previous layer" +#~ msgstr "Presunúť do predchádzajúcej vrstvy" + +#, fuzzy +#~ msgid "Move selection to top layer" +#~ msgstr "Presunúť výber na najvyÅ¡Å¡iu úroveň" + +#, fuzzy +#~ msgid "Move selection to bottom layer" +#~ msgstr "Presunúť výber na najnižšiu úroveň" + +#, fuzzy +#~ msgid "Rotate selection 90° clockwise (Shift+Ctrl+Right)" +#~ msgstr "Otočí objekt o 90° doprava" + +#, fuzzy +#~ msgid "Rotate selection 90° counter-clockwise (Shift+Ctrl+Left)" +#~ msgstr "Otočí objekt o 90° doľava" + +#, fuzzy +#~ msgid "Flip selection horizontally (H)" +#~ msgstr "PreklopiÅ¥ zvolené objekty vodorovne" + +#, fuzzy +#~ msgid "Flip selection vertically (V)" +#~ msgstr "PreklopiÅ¥ zvolené objekty zvisle" + +#, fuzzy +#~ msgid "Align and Distribute dialog (Shift+Ctrl+A)" +#~ msgstr "Dialóg zarovnania a umiestnenia" + +#, fuzzy +#~ msgid "Convert selected object(s) to path(s) (Shift+Ctrl+C)" +#~ msgstr "KonvertovaÅ¥ zvolený objekt na cestu" + +#, fuzzy +#~ msgid "Convert selected stroke(s) to path(s) (Ctrl+Alt+C)" +#~ msgstr "KonvertovaÅ¥ zvolený Å¥ah na cestu" + +#~ msgid "Cl_eanup" +#~ msgstr "_VyčistiÅ¥" + +#, fuzzy +#~ msgid "Text and Font dialog (Shift+Ctrl+T)" +#~ msgstr "Dialóg textu a písma" + +#, fuzzy +#~ msgid "Node tool" +#~ msgstr "UpraviÅ¥ uzol" + +#, fuzzy +#~ msgid "Zoom tool" +#~ msgstr "ZmenÅ¡iÅ¥" + +#, fuzzy +#~ msgid "Rectangle tool" +#~ msgstr "Obdĺžnik" + +#, fuzzy +#~ msgid "Arc tool" +#~ msgstr "Arcrole:" + +#, fuzzy +#~ msgid "Star tool" +#~ msgstr "Začiatok:" + +#, fuzzy +#~ msgid "Spiral tool" +#~ msgstr "Å pirála" + +#, fuzzy +#~ msgid "Calligraphy tool" +#~ msgstr "Kaligrafická čiara" + +#, fuzzy +#~ msgid "Dropper tool" +#~ msgstr "Pipeta" + +#, fuzzy +#~ msgid "When scaling objects, scale stroke width by same proportion" +#~ msgstr "Keď sa mení mierka objektov, rovnakou mierou sa mení aj šírka Å¥ahu" + +#, fuzzy +#~ msgid "When scaling rectangles, scale radii of rounded corners" +#~ msgstr "" +#~ "Keď sa mení mierka pravouholníkov, rovnakou mierou sa mení aj polomer " +#~ "zaokrúhlenia rohov" + +#, fuzzy +#~ msgid "Transform gradients (in fill or stroke) along with objects" +#~ msgstr "Trasformuje prechody (vo výplni a Å¥ahu) spolu s objektami" + +#, fuzzy +#~ msgid "Transform patterns (in fill or stroke) along with objects" +#~ msgstr "Trasformuje vzorky (vo výplni a Å¥ahu) spolu s objektami" + +#, fuzzy +#~ msgid "Delete segment between two nodes" +#~ msgstr "ZmazaÅ¥ zvolené uzly" + +#, fuzzy +#~ msgid "URI:" +#~ msgstr "URI" + +#, fuzzy +#~ msgid "Select All in All Layers" +#~ msgstr "VybraÅ¥ vÅ¡etky viditeľné vrstvy" + +#~ msgid "Invert Selection" +#~ msgstr "Inverzný výber" + +#~ msgid "Clean up selected path(s)" +#~ msgstr "OčistiÅ¥ zvolené cesty" + +#~ msgid "_Scripts..." +#~ msgstr "_Skripty..." + +#, fuzzy +#~ msgid "Align and Distribute" +#~ msgstr "Z_arovnanie a umiestnenie..." + +#, fuzzy +#~ msgid "Align and Distribute Dialog" +#~ msgstr "Dialóg zarovnania a umiestnenia" + +#, fuzzy +#~ msgid "Export Dialog" +#~ msgstr "ExportovaÅ¥ oblasÅ¥" + +#, fuzzy +#~ msgid "Fill and Stroke Dialog" +#~ msgstr "Dialóg výplne a Å¥ahu" + +#, fuzzy +#~ msgid "Find Dialog" +#~ msgstr "Z_obraziÅ¥/SkryÅ¥ dialógy" + +#, fuzzy +#~ msgid "Inkscape Preferences" +#~ msgstr "In_kscape nastavenia..." + +#, fuzzy +#~ msgid "Inkscape Preferences Dialog" +#~ msgstr "In_kscape nastavenia..." + +#, fuzzy +#~ msgid "Layer Editor Dialog" +#~ msgstr "UmiestniÅ¥ vrs_tvu hore" + +#, fuzzy +#~ msgid "Text Properties Dialog" +#~ msgstr "Dialóg nastavení objektu" + +#, fuzzy +#~ msgid "Transformation Dialog" +#~ msgstr "Dialóg transformácie" + +#, fuzzy +#~ msgid "Tree Editor" +#~ msgstr "XML Editor" + +#, fuzzy +#~ msgid "XML Editor Dialog" +#~ msgstr "XML Editor" + +#, fuzzy +#~ msgid "Row height:" +#~ msgstr "Výška:" + +#~ msgid "Creating anchor at (%g,%g)" +#~ msgstr "Vytvorenie kotvy na (%g,%g)" + +#~ msgid "EPS Output Settings" +#~ msgstr "Nastavenia EPS výstupu" + +#~ msgid "Make bounding box around full page" +#~ msgstr "VytvoriÅ¥ ohraničenie okolo celej strany" + +#~ msgid "Skew: %0.2f%% x %0.2f%%" +#~ msgstr "ZoÅ¡ikmenie: %0.2f%% x %0.2f%%" + +#~ msgid "elementsofdesign.svg" +#~ msgstr "elementsofdesign.svg" + +#~ msgid "tipsandtricks.svg" +#~ msgstr "tipsandtricks.svg" + +#~ msgid "Left side of aligned objects to left side of anchor" +#~ msgstr "Ľavá strana zarovnania objektov k ľavej strane ukotvenia" + +#~ msgid "Right side of aligned objects to right side of anchor" +#~ msgstr "Pravá strana zarovnania objektov k pravej strane ukotvenia" + +#~ msgid "Top of aligned objects to top of anchor" +#~ msgstr "Horná strana zarovnania objektov k hornej strane ukotvenia" + +#~ msgid "Bottom of aligned objects to bottom of anchor" +#~ msgstr "Dolná strana zarovnania objektov k dolnej strane ukotvenia" + +#~ msgid "Distribute top sides of objects at even distances" +#~ msgstr "Rovnomerne rozmiestniÅ¥ horné strany objektov" + +#~ msgid "Per row:" +#~ msgstr "Na riadok:" + +#~ msgid "Alternate sign" +#~ msgstr "Alternatívny znak" + +#~ msgid "Dissolve:" +#~ msgstr "Rozpustenie:" + +#~ msgid "Rows:" +#~ msgstr "Riadky:" + +#~ msgid "Minor grid line color:" +#~ msgstr "Farba vedľajÅ¡ej čiary mriežky:" + +#~ msgid "Grid color" +#~ msgstr "Farba mriežky" + +#~ msgid "Grid emphasis color" +#~ msgstr "Farba zvýraznenia mriežky" + +#~ msgid "Background (also for export):" +#~ msgstr "Pozadie (aj pre export):" + +#~ msgid "" +#~ "Pick the visible color under cursor, taking into account the page " +#~ "background and disregarding the transparency of objects" +#~ msgstr "" +#~ "VybraÅ¥ viditeľnú farbu pod kurzorom, vziaÅ¥ do úvahy pozadie stránky bez " +#~ "ohľadu na priesvitnosÅ¥ objektov" + +#~ msgid "Pick objects' color (including alpha)" +#~ msgstr "VybraÅ¥ farbu objektu (vrátane alphy)" + +#~ msgid "" +#~ "Pick the actual color of object(s) under cursor, including their " +#~ "accumulated transparency" +#~ msgstr "" +#~ "Vyberie aktuálnu farbu objektu pod kurzorom, vrátane jeho akumulovej " +#~ "priesvitnosti" + +#~ msgid "Fill style" +#~ msgstr "Å týl výplne" + +#~ msgid "Fill:" +#~ msgstr "Výplň:" + +#~ msgid "" +#~ "Specifies the method of filling overlapping areas when an object " +#~ "intersects itself. With the \"winding fill\" method (fill-rule:nonzero), " +#~ "all overlapping areas are filled; with the \"alternating fill\" method " +#~ "(fill-rule:evenodd), every other of them is filled." +#~ msgstr "" +#~ "Určuje metódu výplne prekrývajúcich sa oblastí jednotlivých častí toho " +#~ "istého objektu. Pri metóde výplne \"vinutie\" (pravidlo výplne:nenulové) " +#~ "vÅ¡etky prekrývajúce sa oblasti sú vyplnené; pri metóde \"alternovanie" +#~ "\" (pravidlo výplne:párne-nepárne) sú vyplnené iba neprekrývajúce sa " +#~ "oblasti." + +#~ msgid "winding" +#~ msgstr "vinutie" + +#~ msgid "alternating" +#~ msgstr "alternovanie" + +#~ msgid "Update Properties" +#~ msgstr "AktualizovaÅ¥ nastavenia" + +#~ msgid "Label invalid" +#~ msgstr "Neplatný popis" + +#~ msgid "Switch to the previous layer in the document" +#~ msgstr "Prepnúť do predchádzajúcej vrstvy v dokumente" + +#~ msgid "_V" +#~ msgstr "_V" + +#~ msgid "Value (brightness)" +#~ msgstr "Hodnota (jas)" diff --git a/po/sl.po b/po/sl.po new file mode 100644 index 000000000..bbd499f75 --- /dev/null +++ b/po/sl.po @@ -0,0 +1,9543 @@ +# translation of sl2.po to sl_SI +# translation of sl.po to sl_SI +# BoÅ¡tjan Å petič , 2004, 2005. +# Martin Srebotnjak, , 2005. +msgid "" +msgstr "" +"Project-Id-Version: sl2\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2005-12-04 11:51-0800\n" +"PO-Revision-Date: 2005-07-23 11:25+0200\n" +"Last-Translator: BoÅ¡tjan Å petič \n" +"Language-Team: sl_SI \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=4; plural=(n%100==1 ? 1 : n%100==2 ? 2 : n%100==3 || n" +"%100==4 ? 3 : 0);\n" +"X-Poedit-Language: Slovenian\n" +"X-Poedit-Country: SLOVENIA\n" +"X-Generator: KBabel 1.9.1\n" + +#: ../inkscape.desktop.in.h:1 +msgid "Create and edit Scalable Vector Graphics images" +msgstr "Ustvarjaj in urejaj SVG vektorske slike" + +#: ../inkscape.desktop.in.h:2 +msgid "Inkscape SVG Vector Illustrator" +msgstr "Ilustrator vektorjev SVG Inkscape" + +#: ../../po/../src/arc-context.cpp:350 +msgid "" +"Ctrl: make circle or integer-ratio ellipse, snap arc/segment angle" +msgstr "" +"Ctrl: nariÅ¡i krog ali elipso z razmerji celih Å¡tevil, odsek preskakuj " +"po kotih" + +#: ../../po/../src/arc-context.cpp:351 ../../po/../src/rect-context.cpp:388 +msgid "Shift: draw around the starting point" +msgstr "Shift: riÅ¡i okrog začetne točke" + +#: ../../po/../src/arc-context.cpp:413 +#: ../../po/../src/connector-context.cpp:493 +#: ../../po/../src/dyna-draw-context.cpp:506 +#: ../../po/../src/pen-context.cpp:329 ../../po/../src/pencil-context.cpp:208 +#: ../../po/../src/rect-context.cpp:452 ../../po/../src/spiral-context.cpp:421 +#: ../../po/../src/star-context.cpp:427 +msgid "Current layer is hidden. Unhide it to be able to draw on it." +msgstr "Trenutni sloj je skrit. Če želite risati po njem ga odkrijte." + +#: ../../po/../src/arc-context.cpp:417 +#: ../../po/../src/connector-context.cpp:497 +#: ../../po/../src/dyna-draw-context.cpp:510 +#: ../../po/../src/pen-context.cpp:336 ../../po/../src/pencil-context.cpp:212 +#: ../../po/../src/rect-context.cpp:456 ../../po/../src/spiral-context.cpp:426 +#: ../../po/../src/star-context.cpp:431 +msgid "Current layer is locked. Unlock it to be able to draw on it." +msgstr "" +"Trenutni sloj je zaklenjen. Če želite risati po njem ga odklenite." + +#: ../../po/../src/arc-context.cpp:496 +#, c-format +msgid "" +"Ellipse: %s × %s; with Ctrl to make circle or integer-" +"ratio ellipse; with Shift to draw around the starting point" +msgstr "" +"Elipsa: %s × %s; s Ctrl za risanje krogov ali elips v " +"razmerjih celih Å¡tevil; s Shift za risanje okrog začetne točke" + +#: ../../po/../src/connector-context.cpp:518 +#, fuzzy +msgid "Creating new connector" +msgstr "Ustari novo pot" + +#: ../../po/../src/connector-context.cpp:939 +#, fuzzy +msgid "Finishing connector" +msgstr "Dokončaj s peresom" + +#: ../../po/../src/connector-context.cpp:1108 +msgid "Connection point: click or drag to create a new connector" +msgstr "" + +#: ../../po/../src/connector-context.cpp:1185 +msgid "Connector endpoint: drag to reroute or connect to new shapes" +msgstr "" + +#: ../../po/../src/connector-context.cpp:1278 +#, fuzzy +msgid "Select at least one non-connector object." +msgstr "Za skupinjenje izberite vsaj dva predmeta." + +#: ../../po/../src/desktop-events.cpp:238 +#, c-format +msgid "%s at %s" +msgstr "%s pri %s" + +#. TRANSLATORS: This string appears when double-clicking on a guide. +#. This is the distance by which the guide is to be moved. +#: ../../po/../src/desktop-events.cpp:277 +msgid " relative by " +msgstr "relativno za" + +#. TRANSLATORS: This string appears when double-clicking on a guide. +#. This is the target location where the guide is to be moved. +#: ../../po/../src/desktop-events.cpp:282 +#: ../../po/../src/desktop-events.cpp:395 +msgid " absolute to " +msgstr "natančno na " + +#. create dialog +#: ../../po/../src/desktop-events.cpp:348 +msgid "Guideline" +msgstr "Vodilo" + +#: ../../po/../src/desktop-events.cpp:432 +#, c-format +msgid "Move %s" +msgstr "Premakni %s" + +#: ../../po/../src/desktop.cpp:678 +msgid "No previous zoom." +msgstr "Brez prejÅ¡nje povečave." + +#: ../../po/../src/desktop.cpp:703 +msgid "No next zoom." +msgstr "Brez naslednje povečave." + +#: ../../po/../src/dialogs/clonetiler.cpp:182 +msgid "Nothing selected." +msgstr "Nič ni izbrano." + +#: ../../po/../src/dialogs/clonetiler.cpp:188 +msgid "More than one object selected." +msgstr "Izbranih je več predmetov." + +#: ../../po/../src/dialogs/clonetiler.cpp:195 +#, c-format +msgid "Object has %d tiled clones." +msgstr "Predmet ima %d tlakovanih klonov. " + +#: ../../po/../src/dialogs/clonetiler.cpp:200 +msgid "Object has no tiled clones." +msgstr "Predmet nima tlakovanih klonov." + +#: ../../po/../src/dialogs/clonetiler.cpp:865 +msgid "Select one object whose tiled clones to unclump." +msgstr "Izberite predmet, katerega klone naj razložim." + +#: ../../po/../src/dialogs/clonetiler.cpp:916 +msgid "Select one object whose tiled clones to remove." +msgstr "Izberite predmet, ki naj mu odstranim tlakovane klone." + +#: ../../po/../src/dialogs/clonetiler.cpp:984 +#: ../../po/../src/selection-chemistry.cpp:1774 +msgid "Select an object to clone." +msgstr "Izberite predmet za kloniranje." + +#: ../../po/../src/dialogs/clonetiler.cpp:990 +#: ../../po/../src/selection-chemistry.cpp:1780 +msgid "" +"If you want to clone several objects, group them and clone the " +"group." +msgstr "" +"Če želite klonirati več predmetov jih skupinite in klonirajte skupino." + +#: ../../po/../src/dialogs/clonetiler.cpp:1484 +msgid "Per row:" +msgstr "V vrsti:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1497 +msgid "Per column:" +msgstr "V stolpcu:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1505 +msgid "Randomize:" +msgstr "Naključno:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1656 +msgid "_Symmetry" +msgstr "_Simetrija" + +#. TRANSLATORS: For the following 17 symmetry groups, see +#. * http://www.bib.ulb.ac.be/coursmath/doc/17.htm (visual examples); +#. * http://www.clarku.edu/~djoyce/wallpaper/seventeen.html (English vocabulary); or +#. * http://membres.lycos.fr/villemingerard/Geometri/Sym1D.htm (French vocabulary). +#. +#: ../../po/../src/dialogs/clonetiler.cpp:1664 +msgid "Select one of the 17 symmetry groups for the tiling" +msgstr "Izberite eno od 17 vrst tlakovanja" + +#. TRANSLATORS: "translation" means "shift" / "displacement" here. +#: ../../po/../src/dialogs/clonetiler.cpp:1675 +msgid "P1: simple translation" +msgstr "P1:·preprosto vrtenje" + +#: ../../po/../src/dialogs/clonetiler.cpp:1676 +msgid "P2: 180° rotation" +msgstr "P2:·180°Â·vrtenje" + +#: ../../po/../src/dialogs/clonetiler.cpp:1677 +msgid "PM: reflection" +msgstr "PM:·zrcaljenje" + +#. TRANSLATORS: "glide reflection" is a reflection and a translation combined. +#. For more info, see http://mathforum.org/sum95/suzanne/symsusan.html +#: ../../po/../src/dialogs/clonetiler.cpp:1680 +msgid "PG: glide reflection" +msgstr "PG:·glide·zracljenje" + +#: ../../po/../src/dialogs/clonetiler.cpp:1681 +msgid "CM: reflection + glide reflection" +msgstr "CM:·zrcaljenje·+·glide·zrcaljenje" + +#: ../../po/../src/dialogs/clonetiler.cpp:1682 +msgid "PMM: reflection + reflection" +msgstr "PMM:·zrcaljenje·+·zrcaljenje" + +#: ../../po/../src/dialogs/clonetiler.cpp:1683 +msgid "PMG: reflection + 180° rotation" +msgstr "PMG:·zrcaljenje·+·180°Â·vrtenje" + +#: ../../po/../src/dialogs/clonetiler.cpp:1684 +msgid "PGG: glide reflection + 180° rotation" +msgstr "PGG:·glide·zrcaljenje·+·180°Â·vrtenje" + +#: ../../po/../src/dialogs/clonetiler.cpp:1685 +msgid "CMM: reflection + reflection + 180° rotation" +msgstr "CMM:·zrcaljenje·+·zrcaljenje·+·180°Â·vrtenje" + +#: ../../po/../src/dialogs/clonetiler.cpp:1686 +msgid "P4: 90° rotation" +msgstr "P4:·90°Â·vrtenje" + +#: ../../po/../src/dialogs/clonetiler.cpp:1687 +msgid "P4M: 90° rotation + 45° reflection" +msgstr "P4M:·90°Â·vrtenje·+·45°Â·zrcaljenje" + +#: ../../po/../src/dialogs/clonetiler.cpp:1688 +msgid "P4G: 90° rotation + 90° reflection" +msgstr "P4G:·90°Â·vrtenje·+·90°Â·zrcaljenje" + +#: ../../po/../src/dialogs/clonetiler.cpp:1689 +msgid "P3: 120° rotation" +msgstr "P3:·120°Â·vrtenje" + +#: ../../po/../src/dialogs/clonetiler.cpp:1690 +msgid "P31M: reflection + 120° rotation, dense" +msgstr "P31M:·zrcaljenje·+·120°Â·vrtenje,·gosto" + +#: ../../po/../src/dialogs/clonetiler.cpp:1691 +msgid "P3M1: reflection + 120° rotation, sparse" +msgstr "P3M1:·zrcaljenje·+·120°Â·vrtenje,·široko" + +#: ../../po/../src/dialogs/clonetiler.cpp:1692 +msgid "P6: 60° rotation" +msgstr "P6:·60°Â·vrtenje" + +#: ../../po/../src/dialogs/clonetiler.cpp:1693 +msgid "P6M: reflection + 60° rotation" +msgstr "P6M:·zrcaljenje·+·60°Â·vrtenje" + +#: ../../po/../src/dialogs/clonetiler.cpp:1721 +msgid "S_hift" +msgstr "Za_makni" + +#. TRANSLATORS: "shift" means: the tiles will be shifted (offset) horizontally by this amount +#: ../../po/../src/dialogs/clonetiler.cpp:1731 +#, no-c-format +msgid "Shift X:" +msgstr "Zamik X:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1739 +#, no-c-format +msgid "Horizontal shift per row (in % of tile width)" +msgstr "Vodoraven zamik vsake vrste (v % Å¡irine tlakovca)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1747 +#, no-c-format +msgid "Horizontal shift per column (in % of tile width)" +msgstr "Vodoraven zamik vsakega stolpca (v % Å¡irine tlakovca)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1754 +msgid "Randomize the horizontal shift by this percentage" +msgstr "Vodoravni zamik naj bo naključen za toliko odstotkov" + +#. TRANSLATORS: "shift" means: the tiles will be shifted (offset) vertically by this amount +#: ../../po/../src/dialogs/clonetiler.cpp:1764 +#, no-c-format +msgid "Shift Y:" +msgstr "Zamik Y:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1772 +#, no-c-format +msgid "Vertical shift per row (in % of tile height)" +msgstr "Navpičen zamik vsake vrste (v % viÅ¡ine tlakovca)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1780 +#, no-c-format +msgid "Vertical shift per column (in % of tile height)" +msgstr "Navpičen zamik vsakega stolpca (v % viÅ¡ine tlakovca)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1787 +msgid "Randomize the vertical shift by this percentage" +msgstr "Navpični zamik naj bo naključen za toliko odstotkov" + +#: ../../po/../src/dialogs/clonetiler.cpp:1795 +msgid "Exponent:" +msgstr "Potenca:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1802 +msgid "Whether rows are spaced evenly (1), converge (<1) or diverge (>1)" +msgstr "" +"Ali naj bodo vrstice razmaknjene enakomerno (1), konvergentno (<1) ali " +"divergentno (>1)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1809 +msgid "Whether columns are spaced evenly (1), converge (<1) or diverge (>1)" +msgstr "" +"Ali naj bodo stolpci razmaknjeni enakomerno (1), konvergentno (<1) ali " +"divergentno (>1)" + +#. TRANSLATORS: "Alternate" is a verb here +#: ../../po/../src/dialogs/clonetiler.cpp:1817 +#: ../../po/../src/dialogs/clonetiler.cpp:1907 +#: ../../po/../src/dialogs/clonetiler.cpp:1966 +#: ../../po/../src/dialogs/clonetiler.cpp:2022 +#: ../../po/../src/dialogs/clonetiler.cpp:2153 +msgid "Alternate:" +msgstr "Izmenjujoče:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1823 +msgid "Alternate the sign of shifts for each row" +msgstr "Izmenjuj predznak zamika za vsako vrstico" + +#: ../../po/../src/dialogs/clonetiler.cpp:1828 +msgid "Alternate the sign of shifts for each column" +msgstr "Izmenjuj predznak zamika za vsak stolpec" + +#: ../../po/../src/dialogs/clonetiler.cpp:1837 +msgid "Sc_ale" +msgstr "Spremeni _velikost" + +#: ../../po/../src/dialogs/clonetiler.cpp:1845 +msgid "Scale X:" +msgstr "Umeri po X:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1853 +#, no-c-format +msgid "Horizontal scale per row (in % of tile width)" +msgstr "Vodoravna sprememba Å¡irine vsake vrste (v % Å¡irine tlakovca)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1861 +#, no-c-format +msgid "Horizontal scale per column (in % of tile width)" +msgstr "Vodoravna sprememba Å¡irine vsakega stolpca (v % Å¡irine tlakovca)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1868 +msgid "Randomize the horizontal scale by this percentage" +msgstr "Vodoravno spreminjanje Å¡irine naj bo naključno za toliko odstotkov" + +#: ../../po/../src/dialogs/clonetiler.cpp:1876 +msgid "Scale Y:" +msgstr "Umeri po Y:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1884 +#, no-c-format +msgid "Vertical scale per row (in % of tile height)" +msgstr "Navpično spreminjanje viÅ¡ine vsake vrste (v % viÅ¡ine tlakovca)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1892 +#, no-c-format +msgid "Vertical scale per column (in % of tile height)" +msgstr "Navpično spreminjanje viÅ¡ine vsakega stolpca (v % viÅ¡ine tlakovca)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1899 +msgid "Randomize the vertical scale by this percentage" +msgstr "Navpično spreminjanje viÅ¡ine naj bo naključno za toliko odstotkov" + +#: ../../po/../src/dialogs/clonetiler.cpp:1913 +msgid "Alternate the sign of scales for each row" +msgstr "Izmenjuj predznak umeritve v vsaki vrsti" + +#: ../../po/../src/dialogs/clonetiler.cpp:1918 +msgid "Alternate the sign of scales for each column" +msgstr "Izmenjuj predznak umeritve za vsak stolpec" + +#: ../../po/../src/dialogs/clonetiler.cpp:1927 +msgid "_Rotation" +msgstr "V_rtenje" + +#: ../../po/../src/dialogs/clonetiler.cpp:1935 +msgid "Angle:" +msgstr "Kot:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1943 +#, no-c-format +msgid "Rotate tiles by this angle for each row" +msgstr "Tlakovce v vsaki vrsti vrti za tak kot" + +#: ../../po/../src/dialogs/clonetiler.cpp:1951 +#, no-c-format +msgid "Rotate tiles by this angle for each column" +msgstr "Tlakovce v vsakem stolpcu vrti za ta kot" + +#: ../../po/../src/dialogs/clonetiler.cpp:1958 +msgid "Randomize the rotation angle by this percentage" +msgstr "Kot vrtenja naj bo naključen za toliko odstotkov" + +#: ../../po/../src/dialogs/clonetiler.cpp:1972 +msgid "Alternate the rotation direction for each row" +msgstr "Izmenjuj smer vrtenja v vsaki vrsti" + +#: ../../po/../src/dialogs/clonetiler.cpp:1977 +msgid "Alternate the rotation direction for each column" +msgstr "Izmenjuj smer vrtenja v vsakem stolpcu" + +#: ../../po/../src/dialogs/clonetiler.cpp:1985 +msgid "_Opacity" +msgstr "_Prosojnost" + +#: ../../po/../src/dialogs/clonetiler.cpp:1993 +msgid "Fade out:" +msgstr "Zatemnitev:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2000 +msgid "Decrease tile opacity by this percentage for each row" +msgstr "V vsaki vrsti povečaj prosojnost tlakovcev za ta %" + +#: ../../po/../src/dialogs/clonetiler.cpp:2007 +msgid "Decrease tile opacity by this percentage for each column" +msgstr "V vsakem stolpcu povečaj prosojnost tlakovcev za ta %" + +#: ../../po/../src/dialogs/clonetiler.cpp:2014 +msgid "Randomize the tile opacity by this percentage" +msgstr "Prosojnost tlakovcev naj bo naključna za ta %" + +#: ../../po/../src/dialogs/clonetiler.cpp:2028 +msgid "Alternate the sign of opacity change for each row" +msgstr "Izmenjuj predznak sprememb prosojnosti v vsaki vrsti" + +#: ../../po/../src/dialogs/clonetiler.cpp:2033 +msgid "Alternate the sign of opacity change for each column" +msgstr "Izmenjuj predznak sprememb prosojnosti v vsakem stolpcu" + +#: ../../po/../src/dialogs/clonetiler.cpp:2041 +msgid "Co_lor" +msgstr "Bar_va" + +#: ../../po/../src/dialogs/clonetiler.cpp:2046 +msgid "Initial color: " +msgstr "Začetna barva: " + +#: ../../po/../src/dialogs/clonetiler.cpp:2050 +msgid "Initial color of tiled clones" +msgstr "Začetna barva tlakovanih klonov" + +#: ../../po/../src/dialogs/clonetiler.cpp:2050 +msgid "" +"Initial color for clones (works only if the original has unset fill or " +"stroke)" +msgstr "" +"Začetna barva talkovanih klonov (deluje le, če izvirnik nima nastavljene " +"barve polnila ali obrobe)" + +#: ../../po/../src/dialogs/clonetiler.cpp:2065 +msgid "H:" +msgstr "H:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2072 +msgid "Change the tile hue by this percentage for each row" +msgstr "V vsaki vrsti spremeni odtenek tlakovcev za ta %" + +#: ../../po/../src/dialogs/clonetiler.cpp:2079 +msgid "Change the tile hue by this percentage for each column" +msgstr "V vsakem stolpcu spremeni odtenek tlakovcev za ta %" + +#: ../../po/../src/dialogs/clonetiler.cpp:2086 +msgid "Randomize the tile hue by this percentage" +msgstr "Odtenek tlakovcev naj bo naključen za toliko odstotkov" + +#: ../../po/../src/dialogs/clonetiler.cpp:2095 +msgid "S:" +msgstr "S:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2102 +msgid "Change the color saturation by this percentage for each row" +msgstr "V vsaki vrsti spremeni nasičenost tlakovcev za ta %" + +#: ../../po/../src/dialogs/clonetiler.cpp:2109 +msgid "Change the color saturation by this percentage for each column" +msgstr "V vsakem stolpcu spremeni nasičenost tlakovcev za ta %" + +#: ../../po/../src/dialogs/clonetiler.cpp:2116 +msgid "Randomize the color saturation by this percentage" +msgstr "Nasičenost tlakovcev naj bo naključna za toliko odstotkov" + +#: ../../po/../src/dialogs/clonetiler.cpp:2124 +msgid "L:" +msgstr "L:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2131 +msgid "Change the color lightness by this percentage for each row" +msgstr "V vsaki vrsti spremeni svetlost tlakovcev za ta %" + +#: ../../po/../src/dialogs/clonetiler.cpp:2138 +msgid "Change the color lightness by this percentage for each column" +msgstr "V vsakem stolpcu spremeni svetlost tlakovcev za ta %" + +#: ../../po/../src/dialogs/clonetiler.cpp:2145 +msgid "Randomize the color lightness by this percentage" +msgstr "Svetlost tlakovcev naj bo naključna za toliko odstotkov" + +#: ../../po/../src/dialogs/clonetiler.cpp:2159 +msgid "Alternate the sign of color changes for each row" +msgstr "Izmenjuj predznak sprememb barve v vsaki vrsti" + +#: ../../po/../src/dialogs/clonetiler.cpp:2164 +msgid "Alternate the sign of color changes for each column" +msgstr "Izmenjuj predznak sprememb barve v vsakem stolpcu" + +#: ../../po/../src/dialogs/clonetiler.cpp:2172 +msgid "_Trace" +msgstr "_Sledi" + +#: ../../po/../src/dialogs/clonetiler.cpp:2179 +msgid "Trace the drawing under the tiles" +msgstr "PreriÅ¡i risbo pod tlakovci" + +#: ../../po/../src/dialogs/clonetiler.cpp:2183 +msgid "" +"For each clone, pick a value from the drawing in that clone's location and " +"apply it to the clone" +msgstr "Vsakemu klonu priredi barvo, ki se nahaja v risbi v njegovi okolici" + +#: ../../po/../src/dialogs/clonetiler.cpp:2197 +msgid "1. Pick from the drawing:" +msgstr "1. Izberi iz risbe:" + +#. ----Hbox2 +#: ../../po/../src/dialogs/clonetiler.cpp:2208 +#: ../../po/../src/dialogs/clonetiler.cpp:2355 +#: ../../po/../src/ui/dialog/tracedialog.cpp:445 +msgid "Color" +msgstr "Barve" + +#: ../../po/../src/dialogs/clonetiler.cpp:2209 +msgid "Pick the visible color and opacity" +msgstr "Izberi vidno barvo in prosojnosti" + +#: ../../po/../src/dialogs/clonetiler.cpp:2216 +#: ../../po/../src/dialogs/clonetiler.cpp:2365 +#: ../share/extensions/dropshadow.inx.h:3 +msgid "Opacity" +msgstr "Prosojnost" + +#: ../../po/../src/dialogs/clonetiler.cpp:2217 +msgid "Pick the total accumulated opacity" +msgstr "Izberi skupno prosojnost" + +#: ../../po/../src/dialogs/clonetiler.cpp:2224 +msgid "R" +msgstr "R" + +#: ../../po/../src/dialogs/clonetiler.cpp:2225 +msgid "Pick the Red component of the color" +msgstr "Izberi rdečo sestavino barve" + +#: ../../po/../src/dialogs/clonetiler.cpp:2232 +msgid "G" +msgstr "G" + +#: ../../po/../src/dialogs/clonetiler.cpp:2233 +msgid "Pick the Green component of the color" +msgstr "Izberi zeleno sestavino barve" + +#: ../../po/../src/dialogs/clonetiler.cpp:2240 +msgid "B" +msgstr "B" + +#: ../../po/../src/dialogs/clonetiler.cpp:2241 +msgid "Pick the Blue component of the color" +msgstr "Izberi modro sestavino barve" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2250 +msgid "clonetiler|H" +msgstr "tlakovalec|H" + +#: ../../po/../src/dialogs/clonetiler.cpp:2251 +msgid "Pick the hue of the color" +msgstr "Izberi barvni odtenek" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2260 +msgid "clonetiler|S" +msgstr "tlakovalec|S " + +#: ../../po/../src/dialogs/clonetiler.cpp:2261 +msgid "Pick the saturation of the color" +msgstr "Izberi nasičenost" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2270 +msgid "clonetiler|L" +msgstr "tlakovalec|L" + +#: ../../po/../src/dialogs/clonetiler.cpp:2271 +msgid "Pick the lightness of the color" +msgstr "Izberi svetlost" + +#: ../../po/../src/dialogs/clonetiler.cpp:2281 +msgid "2. Tweak the picked value:" +msgstr "2) Popravi izbrano vrednost:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2291 +msgid "Gamma-correct:" +msgstr "Gamma popravek:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2296 +msgid "Shift the mid-range of the picked value upwards (>0) or downwards (<0)" +msgstr "Zamakni srednji del izbrane vrednost navzgor (>0) ali navzdol (<0)" + +#: ../../po/../src/dialogs/clonetiler.cpp:2303 +msgid "Randomize:" +msgstr "Naključno:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2308 +msgid "Randomize the picked value by this percentage" +msgstr "Izbrana vrednost naj bo naključna za toliko odstotkov" + +#: ../../po/../src/dialogs/clonetiler.cpp:2315 +msgid "Invert:" +msgstr "Zaobrni:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2319 +msgid "Invert the picked value" +msgstr "Zaobrni izbrano vrednost" + +#: ../../po/../src/dialogs/clonetiler.cpp:2325 +msgid "3. Apply the value to the clones':" +msgstr "3) Priredi vrednost klonom:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2335 +msgid "Presence" +msgstr "Prisotnost" + +#: ../../po/../src/dialogs/clonetiler.cpp:2338 +msgid "" +"Each clone is created with the probability determined by the picked value in " +"that point" +msgstr "Vsak klon ima verjetnost določeno z izbrano barvo v dani točki" + +#: ../../po/../src/dialogs/clonetiler.cpp:2345 +msgid "Size" +msgstr "Velikost" + +#: ../../po/../src/dialogs/clonetiler.cpp:2348 +msgid "Each clone's size is determined by the picked value in that point" +msgstr "Velikost vsakega klona je določena z izbrano vrednostjo v dani točki" + +#: ../../po/../src/dialogs/clonetiler.cpp:2358 +msgid "" +"Each clone is painted by the picked color (the original must have unset fill " +"or stroke)" +msgstr "" +"Vsak klon se izriÅ¡e z izbrano barvo (izvirnik mora imeti barvo polnila ali " +"obrobe nedoločeno)" + +#: ../../po/../src/dialogs/clonetiler.cpp:2368 +msgid "Each clone's opacity is determined by the picked value in that point" +msgstr "Prosojnost vsakega klona je določena z izbrano vrednostjo v dani točki" + +#: ../../po/../src/dialogs/clonetiler.cpp:2395 +msgid "How many rows in the tiling" +msgstr "Koliko vrst naj tlakujem" + +#: ../../po/../src/dialogs/clonetiler.cpp:2415 +msgid "How many columns in the tiling" +msgstr "Koliko stolpcev naj tlakujem" + +#: ../../po/../src/dialogs/clonetiler.cpp:2445 +msgid "Width of the rectangle to be filled" +msgstr "Å irina pravokotnika, ki naj se zapolni" + +#: ../../po/../src/dialogs/clonetiler.cpp:2470 +msgid "Height of the rectangle to be filled" +msgstr "ViÅ¡ina pravokotnika, ki naj se zapolni" + +#: ../../po/../src/dialogs/clonetiler.cpp:2485 +msgid "Rows, columns: " +msgstr "Vrstice, stolpci: " + +#: ../../po/../src/dialogs/clonetiler.cpp:2486 +msgid "Create the specified number of rows and columns" +msgstr "Ustvari dano Å¡tevilo stolpcev in vrstic" + +#: ../../po/../src/dialogs/clonetiler.cpp:2495 +msgid "Width, height: " +msgstr "Å irina, viÅ¡ina: " + +#: ../../po/../src/dialogs/clonetiler.cpp:2496 +msgid "Fill the specified width and height with the tiling" +msgstr "Tlakuj dano Å¡irino in viÅ¡ino" + +#: ../../po/../src/dialogs/clonetiler.cpp:2512 +msgid "Use saved size and position of the tile" +msgstr "Uporabi shranjeno velikost in položaj tlakovca" + +#: ../../po/../src/dialogs/clonetiler.cpp:2515 +msgid "" +"Pretend that the size and position of the tile are the same as the last time " +"you tiled it (if any), instead of using the current size" +msgstr "" +"Delajmo se, da sta položaj in velikost tlakovca enaka kot prejÅ¡njič ko ste " +"ga tlakovali (če), namesto da uporabimo sedanjo velikost." + +#: ../../po/../src/dialogs/clonetiler.cpp:2539 +msgid " _Create " +msgstr " _Ustvari " + +#: ../../po/../src/dialogs/clonetiler.cpp:2541 +msgid "Create and tile the clones of the selection" +msgstr "Ustvari in tlakuj nove klone izbranega predmeta" + +#. TRANSLATORS: if a group of objects are "clumped" together, then they +#. are unevenly spread in the given amount of space - as shown in the +#. diagrams on the left in the following screenshot: +#. http://www.inkscape.org/screenshots/gallery/inkscape-0.42-CVS-tiles-unclump.png +#. So unclumping is the process of spreading a number of objects out more evenly. +#: ../../po/../src/dialogs/clonetiler.cpp:2556 +msgid " _Unclump " +msgstr " _Ravnaj " + +#: ../../po/../src/dialogs/clonetiler.cpp:2557 +msgid "Spread out clones to reduce clumping; can be applied repeatedly" +msgstr "" +"Klone razporedi tako, da zmanjÅ¡aÅ¡ nepravilno razprÅ¡enost; to lahko uporabite " +"večkrat" + +#: ../../po/../src/dialogs/clonetiler.cpp:2563 +msgid " Re_move " +msgstr " Od_strani " + +#: ../../po/../src/dialogs/clonetiler.cpp:2564 +msgid "Remove existing tiled clones of the selected object (siblings only)" +msgstr "Odtrani obstoječe tlakovane klone izbranega predmeta (samo sorojence)" + +#: ../../po/../src/dialogs/clonetiler.cpp:2580 +msgid " R_eset " +msgstr " Po_nastavi " + +#. TRANSLATORS: "change" is a noun here +#: ../../po/../src/dialogs/clonetiler.cpp:2582 +msgid "" +"Reset all shifts, scales, rotates, opacity and color changes in the dialog " +"to zero" +msgstr "" +"Ponastavi vse premike, spremembe velikosti, vrtenja, barve in prosojnosti na " +"nič" + +#: ../../po/../src/dialogs/color-picker.cpp:280 +msgid "Close" +msgstr "Zapri" + +#: ../../po/../src/dialogs/debugdialog.cpp:138 +msgid "Messages" +msgstr "Sporočila" + +#. ## Add a menu for clear() +#: ../../po/../src/dialogs/debugdialog.cpp:144 +#: ../../po/../src/menus-skeleton.h:16 +#: ../../po/../src/ui/dialog/messages.cpp:56 +#: ../../po/../src/ui/dialog/scriptdialog.cpp:181 +msgid "_File" +msgstr "_Datoteka" + +#. TRANSLATORS: "Clear" is a verb here +#: ../../po/../src/dialogs/debugdialog.cpp:145 +#: ../../po/../src/dialogs/find.cpp:753 +#: ../../po/../src/ui/dialog/messages.cpp:57 +#: ../../po/../src/ui/dialog/scriptdialog.cpp:182 +msgid "_Clear" +msgstr "Po_čisti" + +#: ../../po/../src/dialogs/debugdialog.cpp:147 +#: ../../po/../src/ui/dialog/messages.cpp:59 +msgid "Capture log messages" +msgstr "Zajemi dnevniÅ¡ka sporočila" + +#: ../../po/../src/dialogs/debugdialog.cpp:149 +#: ../../po/../src/ui/dialog/messages.cpp:61 +msgid "Release log messages" +msgstr "Sprosti dnevniÅ¡ka sporočila" + +#. Notebook tab +#: ../../po/../src/dialogs/desktop-properties.cpp:909 +#: ../../po/../src/ui/dialog/document-preferences.cpp:89 +#: ../../po/../src/ui/widget/panel.cpp:107 +msgid "Grid" +msgstr "Mreža" + +#. Checkbuttons +#. / \todo FIXME: gray out snapping when grid is off +#. / \todo FIXME: gray out snapping when grid is off. +#. / Dissenting view: you want snapping without grid. +#: ../../po/../src/dialogs/desktop-properties.cpp:917 +#: ../../po/../src/ui/dialog/document-preferences.cpp:179 +msgid "Show grid" +msgstr "Prikaži mrežo" + +#: ../../po/../src/dialogs/desktop-properties.cpp:917 +#: ../../po/../src/ui/dialog/document-preferences.cpp:179 +#: ../../po/../src/verbs.cpp:2115 +msgid "Show or hide grid" +msgstr "Kaži ali skrij mrežo" + +#: ../../po/../src/dialogs/desktop-properties.cpp:918 +#: ../../po/../src/ui/dialog/document-preferences.cpp:180 +msgid "Snap bounding boxes to grid" +msgstr "Preskakuj z obrobo do mreže" + +#: ../../po/../src/dialogs/desktop-properties.cpp:918 +#: ../../po/../src/dialogs/desktop-properties.cpp:1001 +#: ../../po/../src/ui/dialog/document-preferences.cpp:181 +#: ../../po/../src/ui/dialog/document-preferences.cpp:236 +msgid "Snap the edges of the object bounding boxes" +msgstr "Preskakuj z robovi okvirja predmeta" + +#: ../../po/../src/dialogs/desktop-properties.cpp:919 +#: ../../po/../src/ui/dialog/document-preferences.cpp:183 +#, fuzzy +msgid "Snap nodes to grid" +msgstr "Preskakuj s točkami do mreže" + +#: ../../po/../src/dialogs/desktop-properties.cpp:919 +#: ../../po/../src/dialogs/desktop-properties.cpp:1002 +#: ../../po/../src/ui/dialog/document-preferences.cpp:184 +#: ../../po/../src/ui/dialog/document-preferences.cpp:239 +msgid "Snap path nodes, text baselines, ellipse centers, etc." +msgstr "Preskakuj vozlišča, osnove črte besedila, središča elips, itd." + +#: ../../po/../src/dialogs/desktop-properties.cpp:937 +#: ../../po/../src/ui/dialog/document-preferences.cpp:186 +msgid "Grid units:" +msgstr "Enote mreže:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:939 +#: ../../po/../src/ui/dialog/document-preferences.cpp:187 +msgid "Origin X:" +msgstr "Izhodišče X:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:942 +#: ../../po/../src/ui/dialog/document-preferences.cpp:189 +msgid "Origin Y:" +msgstr "Izhodišče Y:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:945 +#: ../../po/../src/ui/dialog/document-preferences.cpp:191 +msgid "Spacing X:" +msgstr "Presledek X:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:948 +#: ../../po/../src/ui/dialog/document-preferences.cpp:193 +msgid "Spacing Y:" +msgstr "Presledek Y:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:952 +#: ../../po/../src/dialogs/desktop-properties.cpp:1013 +#: ../../po/../src/ui/dialog/document-preferences.cpp:195 +#: ../../po/../src/ui/dialog/document-preferences.cpp:241 +msgid "Snap units:" +msgstr "Enote preskoka:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:955 +#: ../../po/../src/dialogs/desktop-properties.cpp:1016 +#: ../../po/../src/ui/dialog/document-preferences.cpp:196 +#: ../../po/../src/ui/dialog/document-preferences.cpp:242 +msgid "Snap distance:" +msgstr "Dolžina preskokov:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:958 +#: ../../po/../src/ui/dialog/document-preferences.cpp:199 +msgid "Grid line color:" +msgstr "Barva črte mreže:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:959 +#: ../../po/../src/ui/dialog/document-preferences.cpp:199 +msgid "Grid line color" +msgstr "Barva črt mreže" + +#: ../../po/../src/dialogs/desktop-properties.cpp:959 +#: ../../po/../src/ui/dialog/document-preferences.cpp:200 +msgid "Color of grid lines" +msgstr "Barva črt mreže" + +#: ../../po/../src/dialogs/desktop-properties.cpp:961 +#: ../../po/../src/ui/dialog/document-preferences.cpp:201 +msgid "Major grid line color:" +msgstr "Barva glavnih mrežnih črt:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:962 +#: ../../po/../src/ui/dialog/document-preferences.cpp:201 +msgid "Major grid line color" +msgstr "Barva glavnih mrežnih črt" + +#: ../../po/../src/dialogs/desktop-properties.cpp:962 +#: ../../po/../src/ui/dialog/document-preferences.cpp:202 +msgid "Color of the major (highlighted) grid lines" +msgstr "Barva glavnih (poudarjenih) črt mreže" + +#: ../../po/../src/dialogs/desktop-properties.cpp:965 +#: ../../po/../src/ui/dialog/document-preferences.cpp:204 +msgid "Major grid line every:" +msgstr "Razmik glavnih mrežnih črt:" + +#. TRANSLATORS: This belongs to the "Major grid line every:" string, +#. see grid settings in the "Document Preferences" dialog +#: ../../po/../src/dialogs/desktop-properties.cpp:977 +#: ../../po/../src/ui/dialog/document-preferences.cpp:204 +msgid "lines" +msgstr "črte" + +#. Guidelines page +#: ../../po/../src/dialogs/desktop-properties.cpp:991 +#: ../../po/../src/ui/dialog/document-preferences.cpp:90 +msgid "Guides" +msgstr "VodniÅ¡ke črte" + +#. / \todo FIXME: gray out snapping when guides are off +#. / Dissenting view: you want snapping without guides. +#: ../../po/../src/dialogs/desktop-properties.cpp:1000 +#: ../../po/../src/ui/dialog/document-preferences.cpp:234 +msgid "Show guides" +msgstr "Kaži vodniÅ¡ke črte" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1000 +#: ../../po/../src/ui/dialog/document-preferences.cpp:234 +#: ../../po/../src/verbs.cpp:2116 +msgid "Show or hide guides" +msgstr "Kaži ali skrij vodila" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1001 +#: ../../po/../src/ui/dialog/document-preferences.cpp:235 +msgid "Snap bounding boxes to guides" +msgstr "Preskakuj z obrobo do vodniÅ¡kih črt" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1002 +#: ../../po/../src/ui/dialog/document-preferences.cpp:238 +msgid "Snap points to guides" +msgstr "Preskakuj s točkami do vodil" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1020 +#: ../../po/../src/ui/dialog/document-preferences.cpp:243 +msgid "Guide color:" +msgstr "Barva vodil:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1021 +#: ../../po/../src/ui/dialog/document-preferences.cpp:243 +msgid "Guideline color" +msgstr "Barva vodniÅ¡kih črt" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1021 +#: ../../po/../src/ui/dialog/document-preferences.cpp:244 +msgid "Color of guidelines" +msgstr "Barva vodil" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1023 +#: ../../po/../src/ui/dialog/document-preferences.cpp:245 +msgid "Highlight color:" +msgstr "Osvetljena barva:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1024 +#: ../../po/../src/ui/dialog/document-preferences.cpp:245 +msgid "Highlighted guideline color" +msgstr "Barva osvetljenih vodil" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1024 +#: ../../po/../src/ui/dialog/document-preferences.cpp:246 +msgid "Color of a guideline when it is under mouse" +msgstr "Barva vodila, ko leži pod miÅ¡kinim kazalcem" + +#. Page page +#: ../../po/../src/dialogs/desktop-properties.cpp:1029 +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:855 +#: ../../po/../src/ui/dialog/document-preferences.cpp:88 +#: ../../po/../src/widgets/desktop-widget.cpp:1061 +msgid "Page" +msgstr "Stran" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1039 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +msgid "Background:" +msgstr "Ozadje:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1040 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +msgid "Background color" +msgstr "Barva ozadja" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1041 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +msgid "" +"Color and transparency of the page background (also used for bitmap export)" +msgstr "" +"Barva in prosojnost ozadnja strani (to se uporablja tudi pri izvozu slik)" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1045 +#: ../../po/../src/ui/dialog/document-preferences.cpp:147 +#, fuzzy +msgid "Show page border" +msgstr "Kaži rob strani" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1049 +#: ../../po/../src/ui/dialog/document-preferences.cpp:148 +msgid "Border on top of drawing" +msgstr "Rob nad risbo" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1052 +#: ../../po/../src/ui/dialog/document-preferences.cpp:149 +msgid "Border color:" +msgstr "Barva robu:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1053 +#: ../../po/../src/ui/dialog/document-preferences.cpp:149 +#, fuzzy +msgid "Page border color" +msgstr "Barva robu polja" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1054 +#: ../../po/../src/ui/dialog/document-preferences.cpp:150 +#, fuzzy +msgid "Color of the page border" +msgstr "Barva robu platna" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1059 +#: ../../po/../src/ui/dialog/document-preferences.cpp:152 +msgid "Show page shadow" +msgstr "Kaži senco strani" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1063 +#: ../../po/../src/ui/dialog/document-preferences.cpp:153 +msgid "Default units:" +msgstr "Privzete enote:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1069 +msgid "Units for the tool controls, ruler, and the statusbar" +msgstr "Enote za upravljanje orodij, ravnil in opravilne vrstice" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1086 +#: ../../po/../src/ui/widget/page-sizer.cpp:209 +#, fuzzy +msgid "Page size:" +msgstr "Velikost platna:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1110 +#: ../../po/../src/ui/widget/page-sizer.cpp:219 +msgid "Custom" +msgstr "Poljubno" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1121 +#: ../../po/../src/ui/widget/page-sizer.cpp:225 +#, fuzzy +msgid "Page orientation:" +msgstr "Usmerjenost platna:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1133 +#: ../../po/../src/ui/widget/page-sizer.cpp:232 +msgid "Landscape" +msgstr "Ležeče" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1139 +#: ../../po/../src/ui/widget/page-sizer.cpp:234 +msgid "Portrait" +msgstr "Pokončno" + +#. Custom paper frame +#: ../../po/../src/dialogs/desktop-properties.cpp:1148 +#: ../../po/../src/ui/widget/page-sizer.cpp:249 +#, fuzzy +msgid "Custom size" +msgstr "Poljubno" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1160 +#: ../../po/../src/dialogs/export.cpp:269 +#: ../../po/../src/ui/widget/page-sizer.cpp:261 +msgid "Units:" +msgstr "Enote:" + +#. Stroke width +#: ../../po/../src/dialogs/desktop-properties.cpp:1162 +#: ../../po/../src/dialogs/export.cpp:310 +#: ../../po/../src/dialogs/object-attributes.cpp:55 +#: ../../po/../src/dialogs/stroke-style.cpp:985 +#: ../../po/../src/ui/widget/page-sizer.cpp:262 +#: ../../po/../src/widgets/toolbox.cpp:1957 +msgid "Width:" +msgstr "Å irina:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1183 +#: ../../po/../src/dialogs/export.cpp:326 +#: ../../po/../src/dialogs/export.cpp:431 +#: ../../po/../src/dialogs/object-attributes.cpp:56 +#: ../../po/../src/ui/widget/page-sizer.cpp:263 +msgid "Height:" +msgstr "ViÅ¡ina:" + +#. +#. * Ownership metadata tab +#. +#: ../../po/../src/dialogs/desktop-properties.cpp:1206 +msgid "Metadata" +msgstr "Meta podatki" + +#. add license selector pull-down +#: ../../po/../src/dialogs/desktop-properties.cpp:1225 +msgid "License" +msgstr "Licenca" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1255 +msgid "Proprietary" +msgstr "Zaščiten" + +#: ../../po/../src/dialogs/display-settings.cpp:212 +msgid "When transforming, show:" +msgstr "Ob preoblikovanju kaži:" + +#: ../../po/../src/dialogs/display-settings.cpp:223 +msgid "Objects" +msgstr "Predmete" + +#: ../../po/../src/dialogs/display-settings.cpp:224 +msgid "Show the actual objects when moving or transforming" +msgstr "Ob premikanju in spreminjanju prikazuj dejanske predmete" + +#: ../../po/../src/dialogs/display-settings.cpp:231 +msgid "Box outline" +msgstr "Zgolj obroba" + +#: ../../po/../src/dialogs/display-settings.cpp:232 +msgid "Show only a box outline of the objects when moving or transforming" +msgstr "Pri premikanju in spreminjanju kaži le obrise predmetov" + +#: ../../po/../src/dialogs/display-settings.cpp:238 +msgid "Per-object selection cue:" +msgstr "Točka izbire na predmet:" + +#. sorationsnapsperpi == 0 means no snapping +#: ../../po/../src/dialogs/display-settings.cpp:249 +#: ../../po/../src/dialogs/display-settings.cpp:386 +#: ../../po/../src/dialogs/display-settings.cpp:441 +#: ../../po/../src/dialogs/display-settings.cpp:1482 +#: ../../po/../src/dialogs/stroke-style.cpp:791 +#: ../../po/../src/interface.cpp:741 +#: ../../po/../src/ui/widget/selected-style.cpp:100 +#: ../../po/../src/verbs.cpp:1842 +msgid "None" +msgstr "Brez" + +#: ../../po/../src/dialogs/display-settings.cpp:250 +msgid "No per-object selection indication" +msgstr "Brez kazalca izbire na predmet" + +#: ../../po/../src/dialogs/display-settings.cpp:256 +msgid "Mark" +msgstr "Oznaka" + +#: ../../po/../src/dialogs/display-settings.cpp:257 +msgid "Each selected object has a diamond mark in the top left corner" +msgstr "Vsak izbran predmet ima v zgornjem levem kotu karo oznako" + +#: ../../po/../src/dialogs/display-settings.cpp:264 +msgid "Box" +msgstr "Okvir" + +#: ../../po/../src/dialogs/display-settings.cpp:265 +msgid "Each selected object displays its bounding box" +msgstr "Vsak izbran predmet pokaže svoj okvir" + +#: ../../po/../src/dialogs/display-settings.cpp:270 +msgid "Default scale origin:" +msgstr "Privzet izvor raztega:" + +#: ../../po/../src/dialogs/display-settings.cpp:281 +msgid "Opposite bounding box edge" +msgstr "Nasprotni rob okvirja" + +#: ../../po/../src/dialogs/display-settings.cpp:282 +msgid "Default scale origin will be on the bounding box of the item" +msgstr "Privzet izvor raztega bo na okvirju predmeta" + +#: ../../po/../src/dialogs/display-settings.cpp:288 +msgid "Farthest opposite node" +msgstr "Najbolj nasprotno vozlišče" + +#: ../../po/../src/dialogs/display-settings.cpp:289 +msgid "Default scale origin will be on the bounding box of the item's points" +msgstr "Privzet izvor raztega bo na okvirju predmetovih točk" + +#: ../../po/../src/dialogs/display-settings.cpp:341 +msgid "degrees" +msgstr "stopinj" + +#: ../../po/../src/dialogs/display-settings.cpp:350 +msgid "" +"Rotating with Ctrl pressed snaps every that much degrees; also, pressing " +"[ or ] rotates by this amount" +msgstr "" +"Vrtenje ob držanju tipke Ctrl se ustavlja na vsakih toliko stopinj; tudi " +"pritiskanje [ or ] zavrti za toliko stopinj. " + +#: ../../po/../src/dialogs/display-settings.cpp:407 +msgid "Rotation snaps every:" +msgstr "Vrtenje se ustavi vsakih:" + +#: ../../po/../src/dialogs/display-settings.cpp:430 +msgid "" +"None: dialogs are treated as regular windows; Normal: dialogs stay on top of " +"document windows; Aggressive: same as Normal but may work better with some " +"window managers." +msgstr "" +"Brez: okna se odnaÅ¡ajo kot običajna okna; Običajno: okna ostajajo nad okni z " +"dokumenti; Agresivno: enako kot Običajno, toda dela bolje z nekaterimi " +"upravljalniki oken." + +#: ../../po/../src/dialogs/display-settings.cpp:451 +msgid "Normal" +msgstr "Običajno" + +#: ../../po/../src/dialogs/display-settings.cpp:461 +msgid "Aggressive" +msgstr "Agresivno" + +#: ../../po/../src/dialogs/display-settings.cpp:475 +msgid "Dialogs on top:" +msgstr "Pogovorna okna:" + +#: ../../po/../src/dialogs/display-settings.cpp:645 +msgid "Show selection cue" +msgstr "Kaži točko izbire" + +#: ../../po/../src/dialogs/display-settings.cpp:646 +msgid "" +"Whether selected objects display a selection cue (the same as in selector)" +msgstr "" +"Ali naj izbrani predmeti pokažejo točko izbire (enako kot pri izbirniku)" + +#: ../../po/../src/dialogs/display-settings.cpp:657 +msgid "Enable gradient editing" +msgstr "Omogoči urejejanje preliva" + +#: ../../po/../src/dialogs/display-settings.cpp:658 +msgid "Whether selected objects display gradient editing controls" +msgstr "Ali naj izbrani predmeti prikažejo kontrolnike urejanja preliva" + +#: ../../po/../src/dialogs/display-settings.cpp:719 +msgid "No objects selected to take the style from." +msgstr "Ni izbranih predmetov za povzemanje sloga." + +#: ../../po/../src/dialogs/display-settings.cpp:728 +msgid "" +"More than one object selected. Cannot take style from multiple " +"objects." +msgstr "" +"Izbranih je več predmetov. Ne morem povzeti sloga z večih predmetov." + +#: ../../po/../src/dialogs/display-settings.cpp:767 +msgid "Create new objects with:" +msgstr "Ustvari nove predmete z:" + +#: ../../po/../src/dialogs/display-settings.cpp:777 +msgid "Take from selection" +msgstr "Iz izbire" + +#: ../../po/../src/dialogs/display-settings.cpp:778 +msgid "Remember the style of the (first) selected object as this tool's style" +msgstr "" +"Zapomni si slog (prvega) izbranega predmeta, kot privzet slog tega orodja" + +#: ../../po/../src/dialogs/display-settings.cpp:782 +#, fuzzy +msgid "Last used style" +msgstr "Slog _lepljenja" + +#: ../../po/../src/dialogs/display-settings.cpp:782 +msgid "Apply the style you last set on an object" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:790 +msgid "This tool's own style:" +msgstr "Lasten slog orodja:" + +#: ../../po/../src/dialogs/display-settings.cpp:790 +msgid "" +"Each tool may store its own style to apply to the newly created objects. Use " +"the button below to set it." +msgstr "" +"Vsako orodje shrani lasten slog, ki ga uporabi za novo ustvarjene predmete. " +"Nastavite ga s spodnjim gumbom." + +#. Mouse +#: ../../po/../src/dialogs/display-settings.cpp:877 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:55 +msgid "Mouse" +msgstr "MiÅ¡ka" + +#. TRANSLATORS: "Grab" is a noun here. "Grab sensitivity" is intended to mean how +#. * close on the screen you need to be to an object to be able to grab it with mouse (in +#. * pixels). +#: ../../po/../src/dialogs/display-settings.cpp:883 +msgid "Grab sensitivity:" +msgstr "Občutljivost oprijema:" + +#: ../../po/../src/dialogs/display-settings.cpp:884 +msgid "" +"How close on the screen you need to be to an object to be able to grab it " +"with mouse (in screen pixels)" +msgstr "" +"Kako blizu predmetu morate priti s kazalcem, da ga lahko zagrabite (v " +"pikah). " + +#: ../../po/../src/dialogs/display-settings.cpp:885 +#: ../../po/../src/dialogs/display-settings.cpp:897 +#: ../../po/../src/dialogs/display-settings.cpp:912 +#: ../../po/../src/dialogs/display-settings.cpp:930 +#: ../../po/../src/dialogs/display-settings.cpp:970 +msgid "pixels" +msgstr "pikslov" + +#: ../../po/../src/dialogs/display-settings.cpp:895 +msgid "Click/drag threshold:" +msgstr "Natančnost miÅ¡ke:" + +#: ../../po/../src/dialogs/display-settings.cpp:896 +msgid "" +"Maximum mouse drag (in screen pixels) which is considered a click, not a drag" +msgstr "" +"NajdaljÅ¡i poteg kazalca (v pikah), ki se Å¡e obravnava kot klik in Å¡e ne " +"poteg. " + +#. Scrolling +#: ../../po/../src/dialogs/display-settings.cpp:907 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:56 +msgid "Scrolling" +msgstr "Kolešček" + +#: ../../po/../src/dialogs/display-settings.cpp:910 +msgid "Mouse wheel scrolls by:" +msgstr "Kolešček premika po:" + +#: ../../po/../src/dialogs/display-settings.cpp:911 +msgid "" +"One mouse wheel notch scrolls by this distance in screen pixels " +"(horizontally with Shift)" +msgstr "" +"Vsak premik koleščka povzroči premik v tem obsegu navpično (skupaj s Shiftom " +"vodoravno)" + +#: ../../po/../src/dialogs/display-settings.cpp:920 +msgid "Ctrl+arrows" +msgstr "Ctrl+smerniki" + +#: ../../po/../src/dialogs/display-settings.cpp:928 +msgid "Scroll by:" +msgstr "Preskakuj po:" + +#: ../../po/../src/dialogs/display-settings.cpp:929 +msgid "Pressing Ctrl+arrow key scrolls by this distance (in screen pixels)" +msgstr "Pritiskanje Ctrl in smernih tipk premika po sliki za toliko točk" + +#: ../../po/../src/dialogs/display-settings.cpp:939 +msgid "Acceleration:" +msgstr "PospeÅ¡evanje:" + +#: ../../po/../src/dialogs/display-settings.cpp:940 +msgid "" +"Pressing and holding Ctrl+arrow will gradually speed up scrolling (0 for no " +"acceleration)" +msgstr "" +"Tiščanje Ctrl in smerne tipke bo sčasoma pospeÅ¡evalo premikanje (0 za izklop " +"tega)" + +#: ../../po/../src/dialogs/display-settings.cpp:949 +msgid "Autoscrolling" +msgstr "Samosledenje" + +#: ../../po/../src/dialogs/display-settings.cpp:957 +msgid "Speed:" +msgstr "Hitrost:" + +#: ../../po/../src/dialogs/display-settings.cpp:958 +msgid "" +"How fast the canvas autoscrolls when you drag beyond canvas edge (0 to turn " +"autoscroll off)" +msgstr "" +"Kako hitro po dosegu robu, se bo slika sledila kazalcu (0 izključi to " +"možnost)" + +#: ../../po/../src/dialogs/display-settings.cpp:968 +#: ../../po/../src/ui/dialog/tracedialog.cpp:357 +#: ../../po/../src/ui/dialog/tracedialog.cpp:390 +msgid "Threshold:" +msgstr "Doseg:" + +#: ../../po/../src/dialogs/display-settings.cpp:969 +msgid "" +"How far (in screen pixels) you need to be from the canvas edge to trigger " +"autoscroll; positive is outside the canvas, negative is within the canvas" +msgstr "" +"Kako daleč (v točkah) od roba mora biti kazalec, da sproži samosledenje; " +"pozitivno za zunaj polja, negativno za znotraj" + +#. Steps +#: ../../po/../src/dialogs/display-settings.cpp:979 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:57 +msgid "Steps" +msgstr "Korakov" + +#: ../../po/../src/dialogs/display-settings.cpp:982 +msgid "Arrow keys move by:" +msgstr "Smerne tipke premikajo za:" + +#: ../../po/../src/dialogs/display-settings.cpp:983 +msgid "" +"Pressing an arrow key moves selected object(s) or node(s) by this distance " +"(in px units)" +msgstr "" +"Pritisk smerne tipke bo izbrane predmete ali vozlišča premaknil za toliko " +"točk (SVG točk)" + +#: ../../po/../src/dialogs/display-settings.cpp:984 +#: ../../po/../src/dialogs/display-settings.cpp:995 +#: ../../po/../src/dialogs/display-settings.cpp:1006 +#: ../../po/../src/helper/units.cpp:42 +msgid "px" +msgstr "pik" + +#: ../../po/../src/dialogs/display-settings.cpp:993 +msgid "> and < scale by:" +msgstr "> in < raztegujeta po:" + +#: ../../po/../src/dialogs/display-settings.cpp:994 +msgid "" +"Pressing > or < scales selection up or down by this increment (in px units)" +msgstr "" +"Pritiskanje na < ali > raztegne ali skrči izbrano za toliko točk (SVG točk)" + +#: ../../po/../src/dialogs/display-settings.cpp:1004 +msgid "Inset/Outset by:" +msgstr "RazÅ¡iri/zoži za:" + +#: ../../po/../src/dialogs/display-settings.cpp:1005 +msgid "" +"Inset and Outset commands displace the path by this distance (in px units)" +msgstr "Ukaza razÅ¡iri in zoži bosta na pot delovala za toliko točk (SVG točk)" + +#: ../../po/../src/dialogs/display-settings.cpp:1017 +msgid "Compass-like display of angles" +msgstr "" + +#. TRANSLATORS: "positive clockwise" means "increasing in clockwise direction" +#: ../../po/../src/dialogs/display-settings.cpp:1019 +msgid "" +"When on, angles are displayed with 0 at north, 0 to 360 range, positive " +"clockwise; otherwise with 0 at east, -180 to 180 range, positive " +"counterclockwise" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1026 +msgid "Zoom in/out by:" +msgstr "Povečava:" + +#: ../../po/../src/dialogs/display-settings.cpp:1027 +msgid "" +"Zoom tool click, +/- keys, and middle click zoom in and out by this " +"multiplier" +msgstr "" +"Orodje za povečavo, pritisk na +/-, približevanje s srednjim gumbom miÅ¡ke, " +"bodo delovali s tem faktorjem" + +#: ../../po/../src/dialogs/display-settings.cpp:1028 +#: ../../po/../src/helper/units.cpp:44 +msgid "%" +msgstr "%" + +#. Tools +#: ../../po/../src/dialogs/display-settings.cpp:1037 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:58 +msgid "Tools" +msgstr "Orodja" + +#: ../../po/../src/dialogs/display-settings.cpp:1045 +msgid "Selector" +msgstr "Izbirnik" + +#: ../../po/../src/dialogs/display-settings.cpp:1056 +msgid "Node" +msgstr "Vozlišče" + +#: ../../po/../src/dialogs/display-settings.cpp:1064 +#: ../../po/../src/verbs.cpp:2073 +#: ../../po/../src/widgets/desktop-widget.cpp:277 +msgid "Zoom" +msgstr "Povečava" + +#. The 4 shape tools +#: ../../po/../src/dialogs/display-settings.cpp:1071 +msgid "Shapes" +msgstr "Oblike" + +#: ../../po/../src/dialogs/display-settings.cpp:1079 +#: ../../po/../src/verbs.cpp:2055 +msgid "Rectangle" +msgstr "Pravokotnik" + +#: ../../po/../src/dialogs/display-settings.cpp:1085 +#: ../../po/../src/verbs.cpp:2057 +msgid "Ellipse" +msgstr "Elipsa" + +#: ../../po/../src/dialogs/display-settings.cpp:1091 +#: ../../po/../src/verbs.cpp:2059 +msgid "Star" +msgstr "Zvezda" + +#: ../../po/../src/dialogs/display-settings.cpp:1097 +#: ../../po/../src/verbs.cpp:2061 +msgid "Spiral" +msgstr "Spirala" + +#: ../../po/../src/dialogs/display-settings.cpp:1111 +#: ../../po/../src/verbs.cpp:2063 +msgid "Pencil" +msgstr "Svinčnik" + +#: ../../po/../src/dialogs/display-settings.cpp:1114 +msgid "Tolerance:" +msgstr "Strpnost:" + +#: ../../po/../src/dialogs/display-settings.cpp:1115 +msgid "" +"This value affects the amount of smoothing applied to freehand lines; lower " +"values produce more uneven paths with more nodes" +msgstr "" +"To določa količino mehčanja prostoročnih črt; manjÅ¡a količina pomeni manj " +"enotne poti z več vozlišči" + +#: ../../po/../src/dialogs/display-settings.cpp:1131 +#: ../../po/../src/verbs.cpp:2065 +msgid "Pen" +msgstr "Pero" + +#: ../../po/../src/dialogs/display-settings.cpp:1140 +#: ../../po/../src/verbs.cpp:2067 +msgid "Calligraphy" +msgstr "Kaligrafija" + +#: ../../po/../src/dialogs/display-settings.cpp:1147 +#: ../../po/../src/dialogs/text-edit.cpp:353 +#: ../../po/../src/ui/dialog/text-properties.cpp:37 +#: ../../po/../src/verbs.cpp:2069 +msgid "Text" +msgstr "Besedilo" + +#: ../../po/../src/dialogs/display-settings.cpp:1157 +#: ../../po/../src/verbs.cpp:2071 +msgid "Gradient" +msgstr "Preliv" + +#: ../../po/../src/dialogs/display-settings.cpp:1164 +#: ../../po/../src/verbs.cpp:2077 +#, fuzzy +msgid "Connector" +msgstr "Avtor" + +#: ../../po/../src/dialogs/display-settings.cpp:1171 +#: ../../po/../src/verbs.cpp:2075 +msgid "Dropper" +msgstr "Pipeta" + +#. Windows +#: ../../po/../src/dialogs/display-settings.cpp:1183 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:59 +msgid "Windows" +msgstr "Okna" + +#: ../../po/../src/dialogs/display-settings.cpp:1188 +msgid "Save window geometry" +msgstr "Shrani obliko okna" + +#: ../../po/../src/dialogs/display-settings.cpp:1189 +msgid "" +"Save the window size and position with each document (only for Inkscape SVG " +"format)" +msgstr "" +"Shrani velikost in položaj okna za vsak dokument (samo v Inkscape SVG " +"formatu)" + +#: ../../po/../src/dialogs/display-settings.cpp:1196 +msgid "Dialogs are hidden in taskbar" +msgstr "Skria pogovorna okna" + +#: ../../po/../src/dialogs/display-settings.cpp:1197 +msgid "Whether dialog windows are to be hidden in the window manager taskbar" +msgstr "Ali se pogovorna okna vidijo v opravilni vrstici upravljalnika oken" + +#: ../../po/../src/dialogs/display-settings.cpp:1204 +msgid "Zoom when window is resized" +msgstr "Približaj ob spremembi velikosti" + +#: ../../po/../src/dialogs/display-settings.cpp:1205 +msgid "" +"Zoom drawing when document window is resized, to keep the same area visible " +"(this is the default which can be changed in any window using the button " +"above the right scrollbar)" +msgstr "" +"Če se spremeni velikost okna približaj ali oddalji sliko tako, da bo vidno " +"enako področje (to je privzeta možnost, ki jo lahko v vsakem oknu spremenite " +"s klikom na gumb nad desnim drsnikom)" + +#. Clones +#: ../../po/../src/dialogs/display-settings.cpp:1213 +#: ../../po/../src/dialogs/find.cpp:624 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:60 +msgid "Clones" +msgstr "Kloni" + +#: ../../po/../src/dialogs/display-settings.cpp:1217 +msgid "When the original moves, its clones and linked offsets:" +msgstr "Če premaknem izvirnik, se njegovi kloni in povezani odmiki:" + +#: ../../po/../src/dialogs/display-settings.cpp:1229 +msgid "Move in parallel" +msgstr "Premaknejo vzporedno" + +#: ../../po/../src/dialogs/display-settings.cpp:1230 +msgid "Clones are translated by the same vector as their original." +msgstr "Kloni se premaknejo po istem vektorju kot izvirnik." + +#: ../../po/../src/dialogs/display-settings.cpp:1237 +msgid "Stay unmoved" +msgstr "Ostanejo pri miru" + +#: ../../po/../src/dialogs/display-settings.cpp:1238 +msgid "Clones preserve their positions when their original is moved." +msgstr "Kloni se ne premikajo, čeprav se njihov izvirnik." + +#: ../../po/../src/dialogs/display-settings.cpp:1245 +msgid "Move according to transform" +msgstr "Premaknejo v skladu s preobrazbo" + +#: ../../po/../src/dialogs/display-settings.cpp:1246 +msgid "" +"Each clone moves according to the value of its transform= attribute. For " +"example, a rotated clone will move in a different direction than its " +"original." +msgstr "" +"Vsak klon se premakne v skladu z nastavitvijo preoblikovanja. Zavrten klon " +"se bo premaknil drugače kot izvirnik." + +#: ../../po/../src/dialogs/display-settings.cpp:1255 +msgid "When the original is deleted, its clones:" +msgstr "Če pobriÅ¡em izvirnik, se kloni:" + +#: ../../po/../src/dialogs/display-settings.cpp:1267 +msgid "Are unlinked" +msgstr "Odvežejo" + +#: ../../po/../src/dialogs/display-settings.cpp:1267 +msgid "Orphaned clones are converted to regular objects." +msgstr "Kloni-sirote se pretvorijo v običajne predmete." + +#: ../../po/../src/dialogs/display-settings.cpp:1273 +msgid "Are deleted" +msgstr "so izbrisani" + +#: ../../po/../src/dialogs/display-settings.cpp:1273 +msgid "Orphaned clones are deleted along with their original." +msgstr "Kloni-sirote se pobriÅ¡ejo skupaj z zvirnikom." + +#. Transforms +#. TRANSLATORS: Noun, i.e. transformations. +#: ../../po/../src/dialogs/display-settings.cpp:1289 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:61 +msgid "Transforms" +msgstr "Preoblikovanja" + +#: ../../po/../src/dialogs/display-settings.cpp:1292 +msgid "Scale stroke width" +msgstr "Spremeni debelino črte" + +#: ../../po/../src/dialogs/display-settings.cpp:1293 +#: ../../po/../src/widgets/select-toolbar.cpp:568 +msgid "When scaling objects, scale the stroke width by the same proportion" +msgstr "" +"Pri raztegovanju predmetov razteguj tudi njihov debelino njihovega obrisa" + +#: ../../po/../src/dialogs/display-settings.cpp:1300 +msgid "Scale rounded corners in rectangles" +msgstr "Razteguj tudi zaobljene kote pravokotnikov" + +#: ../../po/../src/dialogs/display-settings.cpp:1301 +#: ../../po/../src/widgets/select-toolbar.cpp:580 +msgid "When scaling rectangles, scale the radii of rounded corners" +msgstr "" +"Pri raztegovanju pravokotnikov razteguj tudi polmer njihovih zaobljenih kotov" + +#: ../../po/../src/dialogs/display-settings.cpp:1308 +msgid "Transform gradients" +msgstr "Preoblikuje prelive" + +#: ../../po/../src/dialogs/display-settings.cpp:1309 +#: ../../po/../src/widgets/select-toolbar.cpp:592 +msgid "Transform gradients (in fill or stroke) along with the objects" +msgstr "Preoblikuj prelive (za polnilo ali potezo) skupaj s predmeti" + +#: ../../po/../src/dialogs/display-settings.cpp:1316 +msgid "Transform patterns" +msgstr "Preoblikuj vzorce" + +#: ../../po/../src/dialogs/display-settings.cpp:1317 +#: ../../po/../src/widgets/select-toolbar.cpp:604 +msgid "Transform patterns (in fill or stroke) along with the objects" +msgstr "Preoblikuj vzorce (za polnilo ali potezo) skupaj s predmeti" + +#. TRANSLATORS: How to specify the affine transformation in the SVG file. +#: ../../po/../src/dialogs/display-settings.cpp:1327 +msgid "Store transformation:" +msgstr "Shrani preoblikovanje:" + +#: ../../po/../src/dialogs/display-settings.cpp:1338 +msgid "Optimized" +msgstr "Učinkovite" + +#: ../../po/../src/dialogs/display-settings.cpp:1339 +msgid "" +"If possible, apply transformation to objects without adding a transform= " +"attribute" +msgstr "" +"Če je mogoče, preoblikuje predmete, ne da bi spreminjal lastnost " +"preoblikovanje" + +#: ../../po/../src/dialogs/display-settings.cpp:1346 +msgid "Preserved" +msgstr "Ohranjene" + +#: ../../po/../src/dialogs/display-settings.cpp:1347 +msgid "Always store transformation as a transform= attribute on objects" +msgstr "Vedno shrani preoblikovanja kot predmetovo lastnost preoblikovanje=" + +#. Selecting +#: ../../po/../src/dialogs/display-settings.cpp:1355 +msgid "Selecting" +msgstr "Izbiranje" + +#: ../../po/../src/dialogs/display-settings.cpp:1357 +msgid "Ctrl+A, Tab, Shift+Tab:" +msgstr "Ctrl+A, Tab, Shift+Tab:" + +#: ../../po/../src/dialogs/display-settings.cpp:1366 +msgid "Select only within current layer" +msgstr "Izbiraj samo po trenutnem sloju" + +#: ../../po/../src/dialogs/display-settings.cpp:1367 +msgid "" +"Uncheck this to make keyboard selection commands work on objects in all " +"layers" +msgstr "" +"Če to izklopite, bodo ukazi za izbiranje s tipkovnico učinkovali na " +"predmetih z vseh slojev" + +#: ../../po/../src/dialogs/display-settings.cpp:1374 +msgid "Ignore hidden objects" +msgstr "Ne upoÅ¡tevaj skritih predmetov" + +#: ../../po/../src/dialogs/display-settings.cpp:1375 +msgid "" +"Uncheck this to be able to select objects that are hidden (either by " +"themselves or by being in a hidden group or layer)" +msgstr "" +"Če to izključite, boste lahko izbirali tudi skrite predmete (ali same ali pa " +"kot dele skrite skupine ali sloja)" + +#: ../../po/../src/dialogs/display-settings.cpp:1382 +msgid "Ignore locked objects" +msgstr "Ne upoÅ¡tevaj zaklenjenih predmetov" + +#: ../../po/../src/dialogs/display-settings.cpp:1383 +msgid "" +"Uncheck this to be able to select objects that are locked (either by " +"themselves or by being in a locked group or layer)" +msgstr "" +"Če to izključite, boste lahko izbirali tudi zaklenjene predmete (ali same " +"ali pa kot dele zaklenjene skupine ali sloja)" + +#. To be broken into: Display, Save, Export, SVG, Commands +#: ../../po/../src/dialogs/display-settings.cpp:1391 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:62 +msgid "Misc" +msgstr "Razno" + +#: ../../po/../src/dialogs/display-settings.cpp:1394 +msgid "Default export resolution:" +msgstr "Privzeta ločljivost pri izvažanju:" + +#: ../../po/../src/dialogs/display-settings.cpp:1395 +msgid "Default bitmap resolution (in dots per inch) in the Export dialog" +msgstr "Privzeta ločljivost slik (v DPI) v pogovornem oknu Izvoz" + +#. FIXME: add "Used for new exports; once exported, documents remember this value on per-object basis" when implemented +#: ../../po/../src/dialogs/display-settings.cpp:1396 +#: ../../po/../src/dialogs/export.cpp:442 +msgid "dpi" +msgstr "pik na palec" + +#. TRANSLATORS: When on, an imported bitmap creates an element; otherwise it is a +#. * rectangle with bitmap fill. +#: ../../po/../src/dialogs/display-settings.cpp:1407 +msgid "Import bitmap as " +msgstr "Uvozi sliko kot " + +#: ../../po/../src/dialogs/display-settings.cpp:1408 +msgid "" +"When on, an imported bitmap creates an element; otherwise it is a " +"rectangle with bitmap fill" +msgstr "" +"Če izbrano bodo uvožene slike ustvarjene kot element, sicer pa kot " +"pravokotnik zapolnjen s sliko" + +#. TRANSLATORS: When on, the print out (currently Postscript) will have +#. * a comment with the each object's label visible, marking the section +#. * of the printing commands that represent the given object. +#: ../../po/../src/dialogs/display-settings.cpp:1418 +msgid "Add label comments to printing output" +msgstr "Dodaj oznake komentarjev k izhodu tiskanja" + +#: ../../po/../src/dialogs/display-settings.cpp:1419 +msgid "" +"When on, a comment will be added to the raw print output, marking the " +"rendered output for an object with its label" +msgstr "" +"Ko je vključeno, bo surovemu izhodu tiskanja dodan komentar, kar bo " +"predstavljeni izhod predmeta zaznamovalo z oznako" + +#. TRANSLATORS: When on, enable the effects menu, default is off +#: ../../po/../src/dialogs/display-settings.cpp:1427 +msgid "Enable script effects (requires restart) - EXPERIMENTAL" +msgstr "Vključi skriptne efekte (terja ponovni zagon) - TEST" + +#: ../../po/../src/dialogs/display-settings.cpp:1428 +msgid "" +"When on, the effects menu is enabled, allowing external effect scripts to be " +"called, requires restart before effective - EXPERIMENTAL" +msgstr "" +"Če to vključite bo omogočen meni \"efekti\", ki omogoča zagon razÅ¡iritvenih " +"skript. Pred tem morate Å¡e ponovno zagnati Inkscape - TEST" + +#. TRANSLATORS: The maximum length of the Open Recent list in the File menu. +#: ../../po/../src/dialogs/display-settings.cpp:1436 +msgid "Max recent documents:" +msgstr "Nedavnih dokumentov:" + +#: ../../po/../src/dialogs/display-settings.cpp:1437 +msgid "The maximum length of the Open Recent list in the File menu" +msgstr "Dolžina spiska nedavno odprtih dokumentov v meniju Datoteka" + +#: ../../po/../src/dialogs/display-settings.cpp:1447 +msgid "Simplification threshold:" +msgstr "Doseg poenostavljanja:" + +#: ../../po/../src/dialogs/display-settings.cpp:1448 +msgid "" +"How strong is the Simplify command by default. If you invoke this command " +"several times in quick succession, it will act more and more aggressively; " +"invoking it again after a pause restores the default threshold." +msgstr "" +"Kako močen je privzeto ukaz poenostavi. Če ga izberete večkrat zaporedoma, " +"se bo obnaÅ¡al agresivneje. Če ga izberete po krajÅ¡em premoru, bo spet " +"privzeto močen." + +#: ../../po/../src/dialogs/display-settings.cpp:1469 +msgid "Oversample bitmaps:" +msgstr "Prevzorči rastrske slike:" + +#: ../../po/../src/dialogs/display-settings.cpp:1488 +msgid "2x2" +msgstr "2x2" + +#: ../../po/../src/dialogs/display-settings.cpp:1494 +msgid "4x4" +msgstr "4x4" + +#: ../../po/../src/dialogs/display-settings.cpp:1500 +msgid "8x8" +msgstr "8x8" + +#: ../../po/../src/dialogs/display-settings.cpp:1506 +msgid "16x16" +msgstr "16x16" + +#. "view_icon_preview" +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2143 +msgid "_Page" +msgstr "_Stran" + +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2147 +msgid "_Drawing" +msgstr "_Risba" + +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2149 +msgid "_Selection" +msgstr "Izbira" + +#: ../../po/../src/dialogs/export.cpp:133 +msgid "_Custom" +msgstr "_Poljubno" + +#: ../../po/../src/dialogs/export.cpp:254 +msgid "Export area" +msgstr "Območje izvoza" + +#: ../../po/../src/dialogs/export.cpp:300 +msgid "_x0:" +msgstr "_x0:" + +#: ../../po/../src/dialogs/export.cpp:305 +msgid "x_1:" +msgstr "x_1:" + +#: ../../po/../src/dialogs/export.cpp:316 +msgid "_y0:" +msgstr "_y0:" + +#: ../../po/../src/dialogs/export.cpp:321 +msgid "y_1:" +msgstr "y_1:" + +#: ../../po/../src/dialogs/export.cpp:406 +msgid "Bitmap size" +msgstr "Velikost slike" + +#: ../../po/../src/dialogs/export.cpp:416 +msgid "_Width:" +msgstr "_Å irina:" + +#: ../../po/../src/dialogs/export.cpp:416 +#: ../../po/../src/dialogs/export.cpp:431 +msgid "pixels at" +msgstr "točke na" + +#: ../../po/../src/dialogs/export.cpp:426 +msgid "dp_i" +msgstr "dp_i" + +#: ../../po/../src/dialogs/export.cpp:448 +msgid "_Filename" +msgstr "_Ime datoteke" + +#: ../../po/../src/dialogs/export.cpp:512 +msgid "_Browse..." +msgstr "_Brskaj ..." + +#: ../../po/../src/dialogs/export.cpp:539 +msgid " _Export " +msgstr " _Izvoz " + +#: ../../po/../src/dialogs/export.cpp:541 +msgid "Export the bitmap file with these settings" +msgstr "Izvozi sliko s temi nastavitvami" + +#: ../../po/../src/dialogs/export.cpp:968 +msgid "You have to enter a filename" +msgstr "Vpisati morate ime datoteke" + +#: ../../po/../src/dialogs/export.cpp:973 +msgid "The chosen area to be exported is invalid" +msgstr "Območje izbrano za izvoz ni veljavno" + +#: ../../po/../src/dialogs/export.cpp:982 +#, c-format +msgid "Directory %s does not exist or is not a directory.\n" +msgstr "Mapa %s ne obstaja ali pa ni mapa.\n" + +#: ../../po/../src/dialogs/export.cpp:998 +msgid "Export in progress" +msgstr "Izvažam" + +#: ../../po/../src/dialogs/export.cpp:1004 +#, c-format +msgid "Exporting %s (%d x %d)" +msgstr "Izvažanje %s (%d x %d)" + +#: ../../po/../src/dialogs/export.cpp:1031 +#, c-format +msgid "Could not export to filename %s.\n" +msgstr "Nisem mogel izvoziti v datoteko %s.\n" + +#: ../../po/../src/dialogs/export.cpp:1137 +msgid "Select a filename for exporting" +msgstr "Izberi ime datoteke za izvoz" + +#: ../../po/../src/dialogs/filedialog.cpp:367 +msgid "No preview" +msgstr "Ni predogleda" + +#: ../../po/../src/dialogs/filedialog.cpp:468 +msgid "too large for preview" +msgstr "preveliko za predogled" + +#: ../../po/../src/dialogs/filedialog.cpp:762 +#: ../../po/../src/dialogs/filedialog.cpp:763 +msgid "All Images" +msgstr "Vse slike" + +#: ../../po/../src/dialogs/filedialog.cpp:767 +#: ../../po/../src/dialogs/filedialog.cpp:768 +msgid "All Files" +msgstr "Vse datoteke" + +#: ../../po/../src/dialogs/filedialog.cpp:774 +#: ../../po/../src/dialogs/filedialog.cpp:775 +msgid "All Inkscape Files" +msgstr "Vse Inkscape datoteke" + +#: ../../po/../src/dialogs/filedialog.cpp:1176 +msgid "Guess from extension" +msgstr "Ugani iz končnice" + +#. ###### Add the file types menu +#. createFilterMenu(); +#. ###### Do we want the .xxx extension automatically added? +#: ../../po/../src/dialogs/filedialog.cpp:1261 +msgid "Append filename extension automatically" +msgstr "Samodejno dodaj končnico datoteki" + +#. TRANSLATORS: "%s" is replaced with "exact" or "partial" when this string is displayed +#: ../../po/../src/dialogs/find.cpp:378 +#, c-format +msgid "%d object found (out of %d), %s match." +msgid_plural "%d objects found (out of %d), %s match." +msgstr[0] "%d najdenih predmet(ov) (od %d), %s jih ustreza." +msgstr[1] "%d najden predmet (od %d), %s ustreza." +msgstr[2] "%d najdena predmeta (od %d), %s ustreza(ta)." +msgstr[3] "%d najdeni predmeti (od %d), %s jih ustreza." + +#: ../../po/../src/dialogs/find.cpp:381 +msgid "exact" +msgstr "natanko" + +#: ../../po/../src/dialogs/find.cpp:381 +msgid "partial" +msgstr "delno" + +#: ../../po/../src/dialogs/find.cpp:388 +msgid "No objects found" +msgstr "Ni predmetov" + +#: ../../po/../src/dialogs/find.cpp:546 +msgid "T_ype: " +msgstr "_Vrsta: " + +#: ../../po/../src/dialogs/find.cpp:553 +msgid "Search in all object types" +msgstr "Išči po vseh vrstah predmetov" + +#: ../../po/../src/dialogs/find.cpp:553 +msgid "All types" +msgstr "Vse vrste" + +#: ../../po/../src/dialogs/find.cpp:564 +msgid "Search all shapes" +msgstr "Išči po vseh likih" + +#: ../../po/../src/dialogs/find.cpp:564 +msgid "All shapes" +msgstr "Vse oblike" + +#: ../../po/../src/dialogs/find.cpp:581 +msgid "Search rectangles" +msgstr "Išči pravokotnike" + +#: ../../po/../src/dialogs/find.cpp:581 +msgid "Rectangles" +msgstr "Pravokotniki" + +#: ../../po/../src/dialogs/find.cpp:586 +msgid "Search ellipses, arcs, circles" +msgstr "Išči elipse, loke, kroge" + +#: ../../po/../src/dialogs/find.cpp:586 +msgid "Ellipses" +msgstr "Elipse" + +#: ../../po/../src/dialogs/find.cpp:591 +msgid "Search stars and polygons" +msgstr "Išči zvezde in poligone" + +#: ../../po/../src/dialogs/find.cpp:591 +msgid "Stars" +msgstr "Zvezde" + +#: ../../po/../src/dialogs/find.cpp:596 +msgid "Search spirals" +msgstr "Išči spirale" + +#: ../../po/../src/dialogs/find.cpp:596 +msgid "Spirals" +msgstr "Spirale" + +#. TRANSLATORS: polyline is a set of connected straight line segments +#. http://www.w3.org/TR/SVG11/shapes.html#PolylineElement +#: ../../po/../src/dialogs/find.cpp:609 +msgid "Search paths, lines, polylines" +msgstr "Išči poti, črte, lomljene črte" + +#: ../../po/../src/dialogs/find.cpp:609 +msgid "Paths" +msgstr "Poti" + +#: ../../po/../src/dialogs/find.cpp:614 +msgid "Search text objects" +msgstr "Išči besedila" + +#: ../../po/../src/dialogs/find.cpp:614 +msgid "Texts" +msgstr "Besedila" + +#: ../../po/../src/dialogs/find.cpp:619 +msgid "Search groups" +msgstr "Išči skupine" + +#: ../../po/../src/dialogs/find.cpp:619 +msgid "Groups" +msgstr "Skupine" + +#: ../../po/../src/dialogs/find.cpp:624 +msgid "Search clones" +msgstr "Išči klone" + +#: ../../po/../src/dialogs/find.cpp:629 +msgid "Search images" +msgstr "Išči slike" + +#: ../../po/../src/dialogs/find.cpp:629 +msgid "Images" +msgstr "Slike" + +#: ../../po/../src/dialogs/find.cpp:634 +msgid "Search offset objects" +msgstr "Išči zamaknjene predmete" + +#: ../../po/../src/dialogs/find.cpp:634 +msgid "Offsets" +msgstr "Zamiki" + +#: ../../po/../src/dialogs/find.cpp:694 +msgid "_Text: " +msgstr "_Besedilo: " + +#: ../../po/../src/dialogs/find.cpp:694 +msgid "Find objects by their text content (exact or partial match)" +msgstr "" +"Najdi predmete po njihovih besedilnih kotekstih (natančno ali približno)" + +#: ../../po/../src/dialogs/find.cpp:695 +msgid "_ID: " +msgstr "_ID: " + +#: ../../po/../src/dialogs/find.cpp:695 +msgid "Find objects by the value of the id attribute (exact or partial match)" +msgstr "" +"Najdi predmete po njihovih zaporednih Å¡tevilkah (natančno ali približno)" + +#: ../../po/../src/dialogs/find.cpp:696 +msgid "_Style: " +msgstr "_Slog: " + +#: ../../po/../src/dialogs/find.cpp:696 +msgid "" +"Find objects by the value of the style attribute (exact or partial match)" +msgstr "Najdi predmete po njihovih slogih (natančno ali približno)" + +#: ../../po/../src/dialogs/find.cpp:697 +msgid "_Attribute: " +msgstr "_Lastnost: " + +#: ../../po/../src/dialogs/find.cpp:697 +msgid "Find objects by the name of an attribute (exact or partial match)" +msgstr "" +"Najdi predmete po njihovih imenih ali lastnostih (natančno ali približno)" + +#: ../../po/../src/dialogs/find.cpp:711 +msgid "Search in s_election" +msgstr "Išči med i_zbiro" + +#: ../../po/../src/dialogs/find.cpp:715 +msgid "Limit search to the current selection" +msgstr "Omejitev iskanja na trenutno izbiro" + +#: ../../po/../src/dialogs/find.cpp:720 +msgid "Search in current _layer" +msgstr "Išči po trenutnem _sloju" + +#: ../../po/../src/dialogs/find.cpp:724 +msgid "Limit search to the current layer" +msgstr "Omeji iskanje na trenutni sloj" + +#: ../../po/../src/dialogs/find.cpp:729 +msgid "Include _hidden" +msgstr "UpoÅ¡tevaj _skrite" + +#: ../../po/../src/dialogs/find.cpp:733 +msgid "Include hidden objects in search" +msgstr "V iskanje vključi tudi skrite predmete" + +#: ../../po/../src/dialogs/find.cpp:738 +msgid "Include l_ocked" +msgstr "UpoÅ¡tevaj _zaklenjene" + +#: ../../po/../src/dialogs/find.cpp:742 +msgid "Include locked objects in search" +msgstr "V iskanje vključi tudi zaklenjene predmete" + +#: ../../po/../src/dialogs/find.cpp:753 +msgid "Clear values" +msgstr "Počisti vrednosti" + +#: ../../po/../src/dialogs/find.cpp:754 +msgid "_Find" +msgstr "_Najdi" + +#: ../../po/../src/dialogs/find.cpp:754 +msgid "Select objects matching all of the fields you filled in" +msgstr "Izberi vse predmete, ki ustrezajo vsem izpolnjenim poljem." + +#: ../../po/../src/dialogs/iconpreview.cpp:145 +#, c-format +msgid "%d x %d" +msgstr "" + +#: ../../po/../src/dialogs/iconpreview.cpp:193 +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:857 +#: ../../po/../src/widgets/desktop-widget.cpp:1069 +msgid "Selection" +msgstr "Izbira" + +#: ../../po/../src/dialogs/iconpreview.cpp:195 +#, fuzzy +msgid "Selection only or whole document" +msgstr "Izbiraj samo po trenutnem sloju" + +#: ../../po/../src/dialogs/iconpreview.cpp:203 +msgid "Refresh the icons" +msgstr "Osveži ikone" + +#. Create the label for the object id +#: ../../po/../src/dialogs/item-properties.cpp:126 +#: ../../po/../src/dialogs/item-properties.cpp:327 +#: ../../po/../src/dialogs/item-properties.cpp:396 +#: ../../po/../src/dialogs/item-properties.cpp:403 +msgid "_Id" +msgstr "_Id" + +#: ../../po/../src/dialogs/item-properties.cpp:135 +msgid "" +"The id= attribute (only letters, digits, and the characters .-_: allowed)" +msgstr "Lastnost id= (dovoljene so samo črke, Å¡tevilke in znaki -_: )" + +#. Button for setting the object's id, label, title and description. +#: ../../po/../src/dialogs/item-properties.cpp:149 +msgid "_Set" +msgstr "_Nastavi" + +#. Create the label for the object label +#: ../../po/../src/dialogs/item-properties.cpp:158 +msgid "_Label" +msgstr "_Oznaka" + +#: ../../po/../src/dialogs/item-properties.cpp:167 +msgid "A freeform label for the object" +msgstr "Prosta oznaka predmeta" + +#. Create the label for the object title +#: ../../po/../src/dialogs/item-properties.cpp:179 +#: ../../po/../src/dialogs/rdf.cpp:243 +msgid "Title" +msgstr "Naslov" + +#. Create the frame for the object description +#: ../../po/../src/dialogs/item-properties.cpp:196 +#: ../../po/../src/dialogs/rdf.cpp:287 +msgid "Description" +msgstr "Opis" + +#. Hide +#: ../../po/../src/dialogs/item-properties.cpp:223 +msgid "_Hide" +msgstr "_Skrij" + +#: ../../po/../src/dialogs/item-properties.cpp:224 +msgid "Check to make the object invisible" +msgstr "Obkljukajte da skrijete predmet" + +#. Lock +#. TRANSLATORS: "Lock" is a verb here +#: ../../po/../src/dialogs/item-properties.cpp:233 +msgid "L_ock" +msgstr "_Zakleni" + +#: ../../po/../src/dialogs/item-properties.cpp:234 +msgid "Check to make the object insensitive (not selectable by mouse)" +msgstr "" +"Obkljukajte in predmet bo neobčutljiv (ne boste ga mogli izbrati z miÅ¡ko)" + +#: ../../po/../src/dialogs/item-properties.cpp:310 +#: ../../po/../src/dialogs/item-properties.cpp:317 +msgid "Ref" +msgstr "Ref" + +#: ../../po/../src/dialogs/item-properties.cpp:398 +msgid "Id invalid! " +msgstr "Oznaka ni veljavna!" + +#: ../../po/../src/dialogs/item-properties.cpp:400 +msgid "Id exists! " +msgstr "Oznaka obstaja!" + +#: ../../po/../src/dialogs/layer-properties.cpp:50 +msgid "Layer name:" +msgstr "Ime sloja:" + +#: ../../po/../src/dialogs/layer-properties.cpp:133 +msgid "Rename Layer" +msgstr "Preimenuj sloj" + +#: ../../po/../src/dialogs/layer-properties.cpp:136 +msgid "_Rename" +msgstr "P_reimenuj" + +#. TRANSLATORS: This means "The layer has been renamed" +#: ../../po/../src/dialogs/layer-properties.cpp:147 +msgid "Renamed layer" +msgstr "Preimenovan sloj" + +#: ../../po/../src/dialogs/layer-properties.cpp:151 +msgid "Add Layer" +msgstr "Dodaj sloj" + +#: ../../po/../src/dialogs/layer-properties.cpp:153 +msgid "_Add" +msgstr "_Dodaj" + +#: ../../po/../src/dialogs/layer-properties.cpp:167 +msgid "New layer created." +msgstr "Ustvarjen nov sloj." + +#: ../../po/../src/dialogs/object-attributes.cpp:34 +msgid "Href:" +msgstr "Href:" + +#: ../../po/../src/dialogs/object-attributes.cpp:35 +msgid "Target:" +msgstr "Cilj:" + +#: ../../po/../src/dialogs/object-attributes.cpp:36 +msgid "Type:" +msgstr "Vrsta:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkRoleAttribute +#. Identifies the type of the related resource with an absolute URI +#: ../../po/../src/dialogs/object-attributes.cpp:39 +msgid "Role:" +msgstr "Vloga:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkArcRoleAttribute +#. For situations where the nature/role alone isn't enough, this offers an additional URI defining the purpose of the link. +#: ../../po/../src/dialogs/object-attributes.cpp:42 +msgid "Arcrole:" +msgstr "Nadvloga:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkTitleAttribute +#: ../../po/../src/dialogs/object-attributes.cpp:44 +msgid "Title:" +msgstr "Naziv:" + +#: ../../po/../src/dialogs/object-attributes.cpp:45 +msgid "Show:" +msgstr "Kaži:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkActuateAttribute +#: ../../po/../src/dialogs/object-attributes.cpp:47 +msgid "Actuate:" +msgstr "V gibanju:" + +#: ../../po/../src/dialogs/object-attributes.cpp:52 +msgid "URL:" +msgstr "URL:" + +#: ../../po/../src/dialogs/object-attributes.cpp:53 +msgid "X:" +msgstr "X:" + +#: ../../po/../src/dialogs/object-attributes.cpp:54 +msgid "Y:" +msgstr "Y:" + +#: ../../po/../src/dialogs/object-attributes.cpp:98 +#, c-format +msgid "%s attributes" +msgstr "Lastnosti %s" + +#: ../../po/../src/dialogs/object-properties.cpp:158 +msgid "_Fill" +msgstr "_Zapolni" + +#: ../../po/../src/dialogs/object-properties.cpp:165 +msgid "Stroke _paint" +msgstr "_Barva črte" + +#: ../../po/../src/dialogs/object-properties.cpp:172 +msgid "Stroke st_yle" +msgstr "_Slog črte" + +#: ../../po/../src/dialogs/object-properties.cpp:183 +msgid "Master _opacity" +msgstr "Glavna _prosojnost" + +#: ../../po/../src/dialogs/rdf.cpp:244 +msgid "Name by which this document is formally known." +msgstr "Kako se temu dokumentu uradno reče." + +#: ../../po/../src/dialogs/rdf.cpp:246 +msgid "Date" +msgstr "Datum" + +#: ../../po/../src/dialogs/rdf.cpp:247 +msgid "Date associated with the creation of this document (YYYY-MM-DD)." +msgstr "Datum stvaritve tega dokumenta (LETO-MM-DD)." + +#: ../../po/../src/dialogs/rdf.cpp:249 +msgid "Format" +msgstr "Oblika" + +#: ../../po/../src/dialogs/rdf.cpp:250 +msgid "The physical or digital manifestation of this document (MIME type)." +msgstr "Fizična ali digitalna oblikovanost tega dokumenta (vrsta MIME)." + +#: ../../po/../src/dialogs/rdf.cpp:252 +msgid "Type" +msgstr "Vrsta" + +#: ../../po/../src/dialogs/rdf.cpp:253 +msgid "Type of document (DCMI Type)." +msgstr "Vrsta dokumenta (vrsta DCMI)." + +#: ../../po/../src/dialogs/rdf.cpp:256 +msgid "Creator" +msgstr "Avtor" + +#: ../../po/../src/dialogs/rdf.cpp:257 +msgid "" +"Name of entity primarily responsible for making the content of this document." +msgstr "Ime osebe, ki je najbolj odgovorna za vsebino tega dokumenta." + +#: ../../po/../src/dialogs/rdf.cpp:259 +msgid "Rights" +msgstr "Desne" + +#: ../../po/../src/dialogs/rdf.cpp:260 +msgid "" +"Name of entity with rights to the Intellectual Property of this document." +msgstr "Ime osebe s pravicami nad intelektualno lastnino tega dokumenta." + +#: ../../po/../src/dialogs/rdf.cpp:262 +msgid "Publisher" +msgstr "Založnik" + +#: ../../po/../src/dialogs/rdf.cpp:263 +msgid "Name of entity responsible for making this document available." +msgstr "Ime osebe, ki je odgovorna za dostopnost tega dokumenta." + +#: ../../po/../src/dialogs/rdf.cpp:266 +msgid "Identifier" +msgstr "Označevalec" + +#: ../../po/../src/dialogs/rdf.cpp:267 +msgid "Unique URI to reference this document." +msgstr "Unikatna URI za oznako tega dokumenta." + +#: ../../po/../src/dialogs/rdf.cpp:269 +msgid "Source" +msgstr "Izvor" + +#: ../../po/../src/dialogs/rdf.cpp:270 +msgid "Unique URI to reference the source of this document." +msgstr "Unikatna URI za oznako izvora tega dokumenta." + +#: ../../po/../src/dialogs/rdf.cpp:272 +msgid "Relation" +msgstr "Odnos" + +#: ../../po/../src/dialogs/rdf.cpp:273 +msgid "Unique URI to a related document." +msgstr "Unikatna URI do povezanega dokumenta." + +#: ../../po/../src/dialogs/rdf.cpp:275 +msgid "Language" +msgstr "Jezik" + +#: ../../po/../src/dialogs/rdf.cpp:276 +msgid "" +"Two-letter language tag with optional subtags for the language of this " +"document. (e.g. 'en-GB')" +msgstr "" +"Dvočrkovna oznaka z možno podoznako jezika tega dokumenta. (npr. 'en-GB')." + +#: ../../po/../src/dialogs/rdf.cpp:278 +msgid "Keywords" +msgstr "Ključne besede" + +#: ../../po/../src/dialogs/rdf.cpp:279 +msgid "" +"The topic of this document as comma-separated key words, phrases, or " +"classifications." +msgstr "" +"V ključnih besedah, frazah ali klasifikaciji povzeta tema tega dokumenta. " + +#. TRANSLATORS: "Coverage": the spatial or temporal characteristics of the content. +#. For info, see Appendix D of http://www.w3.org/TR/1998/WD-rdf-schema-19980409/ +#: ../../po/../src/dialogs/rdf.cpp:283 +msgid "Coverage" +msgstr "Pokritje" + +#: ../../po/../src/dialogs/rdf.cpp:284 +msgid "Extent or scope of this document." +msgstr "Obzorje ali doseg tega dokumenta." + +#: ../../po/../src/dialogs/rdf.cpp:288 +msgid "A short account of the content of this document." +msgstr "Kratek opis vsebine dokumenta." + +#. FIXME: need to handle 1 agent per line of input +#: ../../po/../src/dialogs/rdf.cpp:292 +msgid "Contributors" +msgstr "Prispevki" + +#: ../../po/../src/dialogs/rdf.cpp:293 +msgid "" +"Names of entities responsible for making contributions to the content of " +"this document." +msgstr "Imena oseb odgovornih za prispevke k temu dokumentu." + +#. TRANSLATORS: URL to a page that defines the license for the document +#: ../../po/../src/dialogs/rdf.cpp:297 +msgid "URI" +msgstr "URI" + +#. TRANSLATORS: this is where you put a URL to a page that defines the license +#: ../../po/../src/dialogs/rdf.cpp:299 +msgid "URI to this document's license's namespace definition." +msgstr "URI do definicije licence dokumenta." + +#. TRANSLATORS: fragment of XML representing the license of the document +#: ../../po/../src/dialogs/rdf.cpp:303 +msgid "Fragment" +msgstr "Delček" + +#: ../../po/../src/dialogs/rdf.cpp:304 +msgid "XML fragment for the RDF 'License' section." +msgstr "XML koščki za odsek RDF licenca." + +#: ../../po/../src/dialogs/stroke-style.cpp:774 +#: ../../po/../src/widgets/gradient-vector.cpp:263 +#: ../../po/../src/widgets/paint-selector.cpp:751 +msgid "No document selected" +msgstr "Izbran ni noben dokument" + +#: ../../po/../src/dialogs/stroke-style.cpp:992 +msgid "Stroke width" +msgstr "Debelina črte" + +#. Join type +#. TRANSLATORS: The line join style specifies the shape to be used at the +#. corners of paths. It can be "miter", "round" or "bevel". +#: ../../po/../src/dialogs/stroke-style.cpp:1015 +msgid "Join:" +msgstr "Spoj:" + +#. TRANSLATORS: Miter join: joining lines with a sharp (pointed) corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1027 +msgid "Miter join" +msgstr "Spoj pod kotom" + +#. TRANSLATORS: Round join: joining lines with a rounded corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1035 +msgid "Round join" +msgstr "Zaobljen spoj" + +#. TRANSLATORS: Bevel join: joining lines with a blunted (flattened) corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1043 +msgid "Bevel join" +msgstr "Nagnjen spoj" + +#. Miterlimit +#. TRANSLATORS: Miter limit: only for "miter join", this limits the length +#. of the sharp "spike" when the lines connect at too sharp an angle. +#. When two line segments meet at a sharp angle, a miter join results in a +#. spike that extends well beyond the connection point. The purpose of the +#. miter limit is to cut off such spikes (i.e. convert them into bevels) +#. when they become too long. +#: ../../po/../src/dialogs/stroke-style.cpp:1054 +msgid "Miter limit:" +msgstr "Spoj pod kotom:" + +#: ../../po/../src/dialogs/stroke-style.cpp:1062 +msgid "Maximum length of the miter (in units of stroke width)" +msgstr "NajdaljÅ¡a črta (v enotah kot debelina)" + +#. Cap type +#. TRANSLATORS: cap type specifies the shape for the ends of lines +#: ../../po/../src/dialogs/stroke-style.cpp:1075 +msgid "Cap:" +msgstr "Konec:" + +#. TRANSLATORS: Butt cap: the line shape does not extend beyond the end point +#. of the line; the ends of the line are square +#: ../../po/../src/dialogs/stroke-style.cpp:1086 +msgid "Butt cap" +msgstr "Kvadratast konec" + +#. TRANSLATORS: Round cap: the line shape extends beyond the end point of the +#. line; the ends of the line are rounded +#: ../../po/../src/dialogs/stroke-style.cpp:1093 +msgid "Round cap" +msgstr "Zaobljen konec" + +#. TRANSLATORS: Square cap: the line shape extends beyond the end point of the +#. line; the ends of the line are square +#: ../../po/../src/dialogs/stroke-style.cpp:1100 +msgid "Square cap" +msgstr "Kvadraten konec" + +#. Dash +#: ../../po/../src/dialogs/stroke-style.cpp:1106 +msgid "Dashes:" +msgstr "Črtice:" + +#. TRANSLATORS: Path markers are an SVG feature that allows you to attach arbitrary shapes +#. (arrowheads, bullets, faces, whatever) to the start, end, or middle nodes of a path. +#: ../../po/../src/dialogs/stroke-style.cpp:1127 +msgid "Start Markers:" +msgstr "Začetne oznake:" + +#: ../../po/../src/dialogs/stroke-style.cpp:1137 +msgid "Mid Markers:" +msgstr "Vmesne oznake" + +#: ../../po/../src/dialogs/stroke-style.cpp:1148 +msgid "End Markers:" +msgstr "Končne oznake:" + +#: ../../po/../src/dialogs/swatches.cpp:424 +#, c-format +msgid "Palettes directory (%s) is unavailable." +msgstr "Imenik s paletami (%s) ni dostopen." + +#. TODO: Insert widgets +#: ../../po/../src/dialogs/text-edit.cpp:199 +#: ../../po/../src/ui/dialog/text-properties.cpp:36 +msgid "Font" +msgstr "Pisava" + +#: ../../po/../src/dialogs/text-edit.cpp:216 +msgid "Layout" +msgstr "Postavitev" + +#: ../../po/../src/dialogs/text-edit.cpp:229 +msgid "Align lines left" +msgstr "Črte poravnaj levo" + +#. TRANSLATORS: `Center' here is a verb. +#: ../../po/../src/dialogs/text-edit.cpp:243 +msgid "Center lines" +msgstr "Črte poravnaj sredinsko" + +#: ../../po/../src/dialogs/text-edit.cpp:256 +msgid "Align lines right" +msgstr "Črte poravnaj desno" + +#: ../../po/../src/dialogs/text-edit.cpp:278 +msgid "Horizontal text" +msgstr "Vodoravno besedilo" + +#: ../../po/../src/dialogs/text-edit.cpp:292 +msgid "Vertical text" +msgstr "Navpično besedilo" + +#: ../../po/../src/dialogs/text-edit.cpp:307 +msgid "Line spacing:" +msgstr "Razmik vrstic:" + +#: ../../po/../src/dialogs/text-edit.cpp:400 +msgid "Set as default" +msgstr "Naj bo privzeto" + +#: ../../po/../src/dialogs/tiledialog.cpp:603 +msgid "Rows:" +msgstr "Vrstice:" + +#: ../../po/../src/dialogs/tiledialog.cpp:613 +msgid "Number of rows" +msgstr "Å tevilo vrstic" + +#: ../../po/../src/dialogs/tiledialog.cpp:617 +msgid "Equal height" +msgstr "Enaka viÅ¡ina" + +#: ../../po/../src/dialogs/tiledialog.cpp:627 +msgid "If not set, each row has the height of the tallest object in it" +msgstr "Če ni vključeno, ima vsaka vrstica viÅ¡ino največjega predmeta v njej" + +#. #### Radio buttons to control vertical alignment #### +#. #### Radio buttons to control horizontal alignment #### +#: ../../po/../src/dialogs/tiledialog.cpp:637 +#: ../../po/../src/dialogs/tiledialog.cpp:708 +msgid "Align:" +msgstr "Poravnava:" + +#: ../../po/../src/dialogs/tiledialog.cpp:672 +msgid " X " +msgstr " X " + +#. #### Number of columns #### +#: ../../po/../src/dialogs/tiledialog.cpp:678 +msgid "Columns:" +msgstr "Stolpci:" + +#: ../../po/../src/dialogs/tiledialog.cpp:688 +msgid "Number of columns" +msgstr "Å tevilo stolpcev" + +#: ../../po/../src/dialogs/tiledialog.cpp:692 +msgid "Equal width" +msgstr "Enaka Å¡irina" + +#: ../../po/../src/dialogs/tiledialog.cpp:701 +msgid "If not set, each column has the width of the widest object in it" +msgstr "Če ni vključeno, ima vsak stolpec Å¡irino največjega predmeta v njem" + +#. #### Radio buttons to control spacing manually or to fit selection bbox #### +#: ../../po/../src/dialogs/tiledialog.cpp:746 +msgid "Fit into selection box" +msgstr "Izbiro umeri v okvir" + +#: ../../po/../src/dialogs/tiledialog.cpp:753 +msgid "Set spacing:" +msgstr "Nastavi razmik:" + +#. #### Y Padding #### +#: ../../po/../src/dialogs/tiledialog.cpp:777 +msgid "Row spacing: " +msgstr "Razmik vrstic: " + +#: ../../po/../src/dialogs/tiledialog.cpp:786 +msgid "Vertical spacing between rows" +msgstr "Navpični razmiki med vrsticami" + +#. #### X padding #### +#: ../../po/../src/dialogs/tiledialog.cpp:795 +msgid "Column spacing:" +msgstr "Razmik vrstic:" + +#: ../../po/../src/dialogs/tiledialog.cpp:804 +msgid "Horizontal spacing between columns" +msgstr "Vodoravnen razmik med stolpc" + +#: ../../po/../src/dialogs/tiledialog.cpp:818 +#, fuzzy +msgid "Arrange selected objects" +msgstr "Združi izbrane predmete v skupino" + +#: ../../po/../src/dialogs/xml-tree.cpp:178 +msgid "Click to select nodes, drag to rearrange." +msgstr "" +"Kliknite da izberete vozlišča, povlecite da jih preuredite." + +#: ../../po/../src/dialogs/xml-tree.cpp:189 +msgid "Click attribute to edit." +msgstr "Kliknite lastnost, da jo spremenite." + +#: ../../po/../src/dialogs/xml-tree.cpp:193 +#, c-format +msgid "" +"Attribute %s selected. Press Ctrl+Enter when done editing to " +"commit changes." +msgstr "" +"Izbrana je lastnost %s. Ko končate pritisnite Ctrl+Enter, da " +"shranim spremembe." + +#: ../../po/../src/dialogs/xml-tree.cpp:284 +msgid "Drag to reorder nodes" +msgstr "Povlecite in preuredite vozlišča" + +#: ../../po/../src/dialogs/xml-tree.cpp:304 +msgid "New element node" +msgstr "Novo vozlišče" + +#: ../../po/../src/dialogs/xml-tree.cpp:326 +msgid "New text node" +msgstr "Novo besedilno vozlišče" + +#: ../../po/../src/dialogs/xml-tree.cpp:347 +msgid "Duplicate node" +msgstr "Podvoji vozlišče" + +#: ../../po/../src/dialogs/xml-tree.cpp:368 +msgid "Delete node" +msgstr "ZbriÅ¡i vozlišče" + +#: ../../po/../src/dialogs/xml-tree.cpp:384 +msgid "Unindent node" +msgstr "Primakni vozlišče" + +#: ../../po/../src/dialogs/xml-tree.cpp:399 +msgid "Indent node" +msgstr "Zamakni vozlišče" + +#: ../../po/../src/dialogs/xml-tree.cpp:411 +msgid "Raise node" +msgstr "Dvigni vozlišče" + +#: ../../po/../src/dialogs/xml-tree.cpp:423 +msgid "Lower node" +msgstr "Spusti vozlišče" + +#: ../../po/../src/dialogs/xml-tree.cpp:468 +msgid "Delete attribute" +msgstr "ZbriÅ¡i atribut" + +#. TRANSLATORS: "Attribute" is a noun here +#: ../../po/../src/dialogs/xml-tree.cpp:513 +msgid "Attribute name" +msgstr "Ime lastnosti" + +#. TRANSLATORS: "Set" is a verb here +#: ../../po/../src/dialogs/xml-tree.cpp:533 +msgid "Set attribute" +msgstr "Nastavi lastnost" + +#. TRANSLATORS: "Set" is a verb here +#: ../../po/../src/dialogs/xml-tree.cpp:535 +msgid "Set" +msgstr "Nastavi" + +#. TRANSLATORS: "Attribute" is a noun here +#: ../../po/../src/dialogs/xml-tree.cpp:558 +msgid "Attribute value" +msgstr "Lastnost" + +#: ../../po/../src/dialogs/xml-tree.cpp:1318 +msgid "New element node..." +msgstr "Novo vozlišče ..." + +#: ../../po/../src/dialogs/xml-tree.cpp:1339 +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:100 +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:98 +msgid "Cancel" +msgstr "Prekliči" + +#: ../../po/../src/dialogs/xml-tree.cpp:1345 +msgid "Create" +msgstr "Ustvari" + +#: ../../po/../src/dialogs/xml-tree.cpp:1458 +#, c-format +msgid "" +"Cannot set %s: Another element with value %s already exists!" +msgstr "" +"Ne morem nastaviti %s: nek obstoječ element že ima vrednost %s!" + +#: ../../po/../src/document.cpp:369 +#, c-format +msgid "New document %d" +msgstr "Nov dokument %d" + +#: ../../po/../src/document.cpp:401 +#, c-format +msgid "Memory document %d" +msgstr "PomnilniÅ¡ki dokument %d" + +#: ../../po/../src/document.cpp:524 +#, c-format +msgid "Unnamed document %d" +msgstr "Neimenovan dokument %d" + +#. We hit green anchor, closing Green-Blue-Red +#: ../../po/../src/draw-context.cpp:441 +msgid "Path is closed." +msgstr "Pot je sklenjena." + +#. We hit bot start and end of single curve, closing paths +#: ../../po/../src/draw-context.cpp:456 +msgid "Closing path." +msgstr "Zaključek poti." + +#. alpha of color under cursor, to show in the statusbar +#. locale-sensitive printf is OK, since this goes to the UI, not into SVG +#: ../../po/../src/dropper-context.cpp:354 +#, c-format +msgid " alpha %.3g" +msgstr " prosojnost %.3g" + +#. where the color is picked, to show in the statusbar +#: ../../po/../src/dropper-context.cpp:356 +#, c-format +msgid ", averaged with radius %d" +msgstr ", povprečno s polmerom %d" + +#: ../../po/../src/dropper-context.cpp:356 +msgid " under cursor" +msgstr " pod kazalcem" + +#. message, to show in the statusbar +#: ../../po/../src/dropper-context.cpp:358 +msgid "Release mouse to set color." +msgstr "Za izbiro barve sprostite miÅ¡ko." + +#: ../../po/../src/dropper-context.cpp:358 +#: ../../po/../src/tools-switch.cpp:207 +msgid "" +"Click to set fill, Shift+click to set stroke; drag to " +"average color in area; with Alt to pick inverse color; Ctrl+C " +"to copy the color under mouse to clipboard" +msgstr "" +"Pritisnite z miÅ¡ko za izbiro barve, držite shift in pritisnite, da nastavite barvo črte. Pritisnite in vlecite da izberete " +"povprečno barvo na območju. Ctrl+C da kopirate barvo pod kazalcem na " +"odložišče" + +#: ../../po/../src/extension/dependency.cpp:244 +msgid "Dependency::" +msgstr "Odvisnost::" + +#: ../../po/../src/extension/dependency.cpp:245 +msgid " type: " +msgstr " vrsta: " + +#: ../../po/../src/extension/dependency.cpp:246 +msgid " location: " +msgstr " položaj: " + +#: ../../po/../src/extension/dependency.cpp:247 +msgid " string: " +msgstr " niz: " + +#: ../../po/../src/extension/dependency.cpp:250 +msgid " description: " +msgstr " opis: " + +#. static int i = 0; +#. std::cout << "Checking module[" << i++ << "]: " << name << std::endl; +#: ../../po/../src/extension/extension.cpp:244 +msgid "" +" This is caused by an improper .inx file for this extension. An improper ." +"inx file could have been caused by a faulty installation of Inkscape." +msgstr "" +" To se zgodi zaradi napačne datoteke .inx za to razÅ¡iritev. To se je lahko " +"zgodilo zaradi neuspeÅ¡ne namestitve Inkscape-a." + +#: ../../po/../src/extension/extension.cpp:247 +msgid "an ID was not defined for it." +msgstr "ni določene oznake." + +#: ../../po/../src/extension/extension.cpp:251 +msgid "there was no name defined for it." +msgstr "ni določenega imena." + +#: ../../po/../src/extension/extension.cpp:255 +msgid "the XML description of it got lost." +msgstr "XML opis se je izgubil." + +#: ../../po/../src/extension/extension.cpp:259 +msgid "no implementation was defined for the extension." +msgstr "ni določene izvedbe za to razÅ¡iritev." + +#. std::cout << "Failed: " << *(_deps[i]) << std::endl; +#: ../../po/../src/extension/extension.cpp:266 +msgid "a dependency was not met." +msgstr "nezadoščena odvisnost." + +#: ../../po/../src/extension/extension.cpp:286 +msgid "Extension \"" +msgstr "RazÅ¡iritev \"" + +#: ../../po/../src/extension/extension.cpp:286 +msgid "\" failed to load because " +msgstr "\" se ni uspela naložiti zaradi " + +#: ../../po/../src/extension/extension.cpp:565 +#, c-format +msgid "Could not create extension error log file '%s'" +msgstr "Datoteke z zapisi o napakah razÅ¡irirtve '%s' ni mogoče ustvariti." + +#. This is some filler text, needs to change before relase +#: ../../po/../src/extension/error-file.cpp:56 +msgid "" +"One or more extensions failed to load\n" +"\n" +"The failed extensions have been skipped. Inkscape will continue to run " +"normally but those extensions will be unavailable. For details to " +"troubleshoot this problem, please refer to the error log located at: " +msgstr "" +"Najmanj ena razÅ¡iritev se ni uspela " +"naložiti.\n" +"\n" +"NeuspeÅ¡no naložene razÅ¡iritve so bile preskočene. Inkscape bo deloval " +"normalno, le nekatere razÅ¡iritve ne bodo omogočene. Za podrobnosti o težavi " +"si oglejte dnevnik napak, ki ga najdete na:" + +#. This is some filler text, needs to change before relase +#: ../../po/../src/extension/error-file.cpp:65 +msgid "Show dialog on startup" +msgstr "Pri zagonu pokaži pogovorno okno" + +#: ../../po/../src/extension/implementation/script.cpp:845 +msgid "" +"Inkscape has received an error from the script that it called. The text " +"returned with the error is included below. Inkscape will continue working, " +"but the action you requested has been cancelled." +msgstr "" +"Skripta ki jo je Inkscape poklical je vrnila napako. Sporočilo sledi spodaj. " +"Inkscape bo deloval dalje, željena operacija pa je prekinjena." + +#: ../../po/../src/extension/implementation/script.cpp:858 +msgid "" +"Inkscape has received additional data from the script executed. The script " +"did not return an error, but this may indicate the results will not be as " +"expected." +msgstr "" +"Skripta je vrnila sporočilo, ne pa napake. To lahko pomeni, da rezultati " +"niso povsem v skladu s pričakovanji." + +#: ../../po/../src/extension/init.cpp:173 +msgid "Null external module directory name. Modules will not be loaded." +msgstr "Ime zunanjega imenika ni podano. Dodatki se ne bodo naložili." + +#: ../../po/../src/extension/init.cpp:187 +#, c-format +msgid "" +"Modules directory (%s) is unavailable. External modules in that directory " +"will not be loaded." +msgstr "" +"Mapa z dodatki (%s) ni dostopna. Zunanji dodatki iz te mape se ne bodo " +"naložili." + +#: ../../po/../src/extension/internal/gnome.cpp:80 +msgid "Select printer" +msgstr "Izberi tiskalnik" + +#: ../../po/../src/extension/internal/gnome.cpp:131 +msgid "Inkscape: Print Preview" +msgstr "Inkscape: Predogled tiskanja" + +#: ../../po/../src/extension/internal/grid.cpp:213 +msgid "Line Width" +msgstr "Å irina črte" + +#: ../../po/../src/extension/internal/grid.cpp:214 +msgid "Horizontal Spacing" +msgstr "Vodoravni razmiki" + +#: ../../po/../src/extension/internal/grid.cpp:215 +msgid "Vertical Spacing" +msgstr "Navpični razmiki" + +#: ../../po/../src/extension/internal/grid.cpp:216 +msgid "Horizontal Offset" +msgstr "Vodoravn zamiki" + +#: ../../po/../src/extension/internal/grid.cpp:217 +msgid "Vertical Offset" +msgstr "Navpični zamiki" + +#: ../../po/../src/extension/internal/ps.cpp:123 +msgid "Print Destination" +msgstr "Cilj tiskanja" + +#. Print properties frame +#: ../../po/../src/extension/internal/ps.cpp:138 +msgid "Print properties" +msgstr "Lastnosti tiskanja" + +#: ../../po/../src/extension/internal/ps.cpp:145 +msgid "Print using PostScript operators" +msgstr "Tiskaj s Postscript ukazi" + +#: ../../po/../src/extension/internal/ps.cpp:147 +msgid "" +"Use PostScript vector operators. The resulting image is usually smaller in " +"file size and can be arbitrarily scaled, but alpha transparency and patterns " +"will be lost." +msgstr "" +"Uporabi Postscript opise vektorjev. Tako bo datoteka manjÅ¡a, dalo se jo bo " +"poljubno preoblikovati, izgubljni pa bodo prelivi, prosojnosti in vzorci." + +#: ../../po/../src/extension/internal/ps.cpp:152 +msgid "Print as bitmap" +msgstr "Tiskaj kot sliko" + +#: ../../po/../src/extension/internal/ps.cpp:154 +msgid "" +"Print everything as bitmap. The resulting image is usually larger in file " +"size and cannot be arbitrarily scaled without quality loss, but all objects " +"will be rendered exactly as displayed." +msgstr "" +"Tiskaj kot sliko. Datoteka bo večja, ob preoblikovanjih bo priÅ¡lo do izgube " +"kvalitete, bo pa vse izrisano natanko tako, kot je sedaj na zaslonu." + +#: ../../po/../src/extension/internal/ps.cpp:168 +msgid "Preferred resolution (dots per inch) of bitmap" +msgstr "Željena ločljivost slike (DPI)" + +#: ../../po/../src/extension/internal/ps.cpp:182 +msgid "Resolution:" +msgstr "Ločljivost:" + +#. Print destination frame +#: ../../po/../src/extension/internal/ps.cpp:186 +msgid "Print destination" +msgstr "Cilj tiskanja" + +#: ../../po/../src/extension/internal/ps.cpp:192 +msgid "" +"Use '> filename' to print to file.\n" +"Use '| prog arg...' to pipe to a program." +msgstr "" +"Uporabite '> ime' za tisk v datoteko.\n" +"Uporabite '| prog arg ...' za preusmeritev v program." + +#: ../../po/../src/extension/internal/ps.cpp:1227 +msgid "write error occurred" +msgstr "napaka pri pisanju" + +#: ../../po/../src/extension/prefdialog.cpp:21 +msgid " Preferences" +msgstr " Nastavitve" + +#. We can't call sp_ui_error_dialog because we may be +#. running from the console, in which case calling sp_ui +#. routines will cause a segfault. See bug 1000350 - bryce +#. sp_ui_error_dialog(_("Format autodetect failed. The file is being opened as SVG.")); +#: ../../po/../src/extension/system.cpp:105 +msgid "Format autodetect failed. The file is being opened as SVG." +msgstr "Ne morem zaznati formata datoteke. Odpiram kot SVG." + +#. TRANSLATORS: default.svg is localizable - this is the name of the default document +#. template. This way you can localize the default pagesize, translate the name of +#. the default layer, etc. If you wish to localize this file, please create a +#. localized share/templates/default.xx.svg file, where xx is your language code. +#: ../../po/../src/file.cpp:133 +msgid "default.svg" +msgstr "default.svg" + +#: ../../po/../src/file.cpp:215 ../../po/../src/file.cpp:900 +#, c-format +msgid "Failed to load the requested file %s" +msgstr "Ne morem naložiti željene datoteke %s" + +#: ../../po/../src/file.cpp:240 +msgid "Document not saved yet. Cannot revert." +msgstr "Dokument Å¡e ni shranjen. Ne morem se vrniti." + +#: ../../po/../src/file.cpp:246 +#, c-format +msgid "Changes will be lost! Are you sure you want to reload document %s?" +msgstr "" +"Spremembe bodo izgubljene. Ali zares želite ponovno naložiti dokument %s?" + +#: ../../po/../src/file.cpp:266 +msgid "Document reverted." +msgstr "Dokument povrnjen." + +#: ../../po/../src/file.cpp:268 +msgid "Document not reverted." +msgstr "Dokument ni povrnjen." + +#: ../../po/../src/file.cpp:382 +msgid "Select file to open" +msgstr "Izberi datoteko za odprtje" + +#: ../../po/../src/file.cpp:518 +#, c-format +msgid "Removed %i unused definition in <defs>." +msgid_plural "Removed %i unused definitions in <defs>." +msgstr[0] "" +"Odstranil %i neuporabljenih elementov v <definicijah>." +msgstr[1] "Odstranil %i neuporabljen element v <definicijah>." +msgstr[2] "Odstranil %i neuporabljena elementa v <definicijah>." +msgstr[3] "Odstranil %i neuporabljene elemente v <definicijah>." + +#: ../../po/../src/file.cpp:523 +msgid "No unused definitions in <defs>." +msgstr "Ni neuporabljenih elementov v <definicijah>." + +#: ../../po/../src/file.cpp:548 +#, c-format +msgid "" +"No Inkscape extension found to save document (%s). This may have been " +"caused by an unknown filename extension." +msgstr "" +"Ne najdem razÅ¡iritve Inkscape za shranjevanje dokumenta (%s). To se lahko " +"zgodi zaradi neznane končnice datoteke." + +#: ../../po/../src/file.cpp:549 ../../po/../src/file.cpp:557 +msgid "Document not saved." +msgstr "Dokument ni shranjen." + +#: ../../po/../src/file.cpp:556 +#, c-format +msgid "File %s could not be saved." +msgstr "Na morem shraniti datoteke %s." + +#: ../../po/../src/file.cpp:566 +msgid "Document saved." +msgstr "Dokument shranjen." + +#: ../../po/../src/file.cpp:614 +#, c-format +msgid "drawing%s" +msgstr "risba%s" + +#: ../../po/../src/file.cpp:620 +#, c-format +msgid "drawing-%d%s" +msgstr "risba-%d%s" + +#: ../../po/../src/file.cpp:655 +msgid "Select file to save to" +msgstr "Izberi datoteko za shranjevanje" + +#: ../../po/../src/file.cpp:739 +msgid "No changes need to be saved." +msgstr "Ni sprememb za shranjevanje." + +#: ../../po/../src/file.cpp:926 +msgid "Select file to import" +msgstr "Izberi datoteko za uvoz" + +#: ../../po/../src/gradient-context.cpp:263 +msgid "Ctrl: snap gradient angle" +msgstr "Ctrl: preskakuj po kotih" + +#: ../../po/../src/gradient-context.cpp:264 +msgid "Shift: draw gradient around the starting point" +msgstr "Shift: riÅ¡i okrog začetne točke" + +#. We did an undoable action, but sp_document_done will be called by the knot when released +#. status text; we do not track coords because this branch is run once, not all the time +#. during drag +#: ../../po/../src/gradient-context.cpp:462 +#, c-format +msgid "Gradient for %d objects; with Ctrl to snap angle" +msgstr "Preliv za %d predmetov; s Ctrl preskakuj po kotih" + +#: ../../po/../src/gradient-context.cpp:464 +msgid "Select objects on which to create gradient." +msgstr "Izberite predmete, na katerih naj se naredi preliv." + +#: ../../po/../src/gradient-drag.cpp:65 +msgid "Linear gradient start" +msgstr "Zvezen preliv - začetek" + +#. POINT_LG_P1 +#: ../../po/../src/gradient-drag.cpp:66 +msgid "Linear gradient end" +msgstr "Zvezen preliv - konec" + +#: ../../po/../src/gradient-drag.cpp:67 +msgid "Radial gradient center" +msgstr "Krožen preliv - središče" + +#: ../../po/../src/gradient-drag.cpp:68 ../../po/../src/gradient-drag.cpp:69 +msgid "Radial gradient radius" +msgstr "Krožen preliv - radij" + +#: ../../po/../src/gradient-drag.cpp:70 +msgid "Radial gradient focus" +msgstr "Krožen preliv - žarišče" + +#: ../../po/../src/gradient-drag.cpp:659 +#, c-format +msgid "" +"%s for: %s%s; drag with Ctrl to snap angle, with Ctrl+Alt to " +"preserve angle, with Ctrl+Shift to scale around center" +msgstr "" +"%s za: %s%s; s Ctrl preskakujete po kotih, s Ctrl+Alt ohranite " +"kot, s Ctrl+Shift umerite okrog središča" + +#: ../../po/../src/gradient-drag.cpp:662 +msgid " (stroke)" +msgstr " (poteza)" + +#: ../../po/../src/gradient-drag.cpp:665 +msgid "" +"Radial gradient center and focus; drag with Shift to " +"separate focus" +msgstr "" +"Središče in žarišče krožnega preliva; povlecite z Shift " +"za ločitev žarišča" + +#: ../../po/../src/gradient-drag.cpp:667 +#, c-format +msgid "" +"Gradient point shared by %d gradients; drag with Shift to " +"separate" +msgstr "" +"Točko preliva si deli %d prelivov; povlecite z Shift za " +"ločitev." + +#: ../../po/../src/helper/units.cpp:40 +msgid "Unit" +msgstr "Enota" + +#: ../../po/../src/helper/units.cpp:40 +msgid "Units" +msgstr "Enote" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Point" +msgstr "Pika" + +#: ../../po/../src/helper/units.cpp:41 +msgid "pt" +msgstr "pik" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Points" +msgstr "Pik" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Pt" +msgstr "Tč" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Pixel" +msgstr "piksel" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Pixels" +msgstr "pikslov" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Px" +msgstr "Piks" + +#. You can add new elements from this point forward +#: ../../po/../src/helper/units.cpp:44 ../share/extensions/straightseg.inx.h:2 +msgid "Percent" +msgstr "Odstotek" + +#: ../../po/../src/helper/units.cpp:44 +msgid "Percents" +msgstr "Odstotkov" + +#: ../../po/../src/helper/units.cpp:45 +msgid "Millimeter" +msgstr "Milimeter" + +#: ../../po/../src/helper/units.cpp:45 +msgid "mm" +msgstr "mm" + +#: ../../po/../src/helper/units.cpp:45 +msgid "Millimeters" +msgstr "Milimetrov" + +#: ../../po/../src/helper/units.cpp:46 +msgid "Centimeter" +msgstr "Centimeter" + +#: ../../po/../src/helper/units.cpp:46 +msgid "cm" +msgstr "cm" + +#: ../../po/../src/helper/units.cpp:46 +msgid "Centimeters" +msgstr "Centimetrov" + +#: ../../po/../src/helper/units.cpp:47 +msgid "Meter" +msgstr "Meter" + +#: ../../po/../src/helper/units.cpp:47 +msgid "m" +msgstr "m" + +#: ../../po/../src/helper/units.cpp:47 +msgid "Meters" +msgstr "Metrov" + +#. no svg_unit +#: ../../po/../src/helper/units.cpp:48 +msgid "Inch" +msgstr "Palec" + +#: ../../po/../src/helper/units.cpp:48 +msgid "in" +msgstr "palec" + +#: ../../po/../src/helper/units.cpp:48 +msgid "Inches" +msgstr "Palcev" + +#. Volatiles do not have default, so there are none here +#. TRANSLATORS: for info, see http://www.w3.org/TR/REC-CSS2/syndata.html#length-units +#: ../../po/../src/helper/units.cpp:51 +msgid "Em square" +msgstr "Kvadrat em" + +#: ../../po/../src/helper/units.cpp:51 +msgid "em" +msgstr "em" + +#: ../../po/../src/helper/units.cpp:51 +msgid "Em squares" +msgstr "Kvadratov em" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/REC-CSS2/syndata.html#length-units +#: ../../po/../src/helper/units.cpp:53 +msgid "Ex square" +msgstr "Kvadrat ex" + +#: ../../po/../src/helper/units.cpp:53 +msgid "ex" +msgstr "ex" + +#: ../../po/../src/helper/units.cpp:53 +msgid "Ex squares" +msgstr "Kvadratov ex" + +#: ../../po/../src/inkscape.cpp:468 +msgid "Untitled document" +msgstr "Neimenovan dokument" + +#. Show nice dialog box +#: ../../po/../src/inkscape.cpp:497 +msgid "Inkscape encountered an internal error and will close now.\n" +msgstr "Inkscape je naletel na notranjo napako in se bo zato zaprl.\n" + +#: ../../po/../src/inkscape.cpp:498 +msgid "" +"Automatic backups of unsaved documents were done to the following " +"locations:\n" +msgstr "" +"Samodejno shranjevanje neshranjenih dokumentov je bilo opravljeno, na " +"sledeče lokacije:\n" + +#: ../../po/../src/inkscape.cpp:499 +msgid "Automatic backup of the following documents failed:\n" +msgstr "Samodejno shranjevanje sledečih dokumentov ni uspelo:\n" + +#: ../../po/../src/inkscape.cpp:634 +#, c-format +msgid "" +"Cannot create directory %s.\n" +"%s" +msgstr "" +"Ne morem ustvariti mape %s.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:635 +#, c-format +msgid "" +"%s is not a valid directory.\n" +"%s" +msgstr "" +"Mapa %s ni veljavna.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:636 +#, c-format +msgid "" +"Cannot create file %s.\n" +"%s" +msgstr "" +"Ne morem ustvariti datoteke %s.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:637 +#, c-format +msgid "" +"Cannot write file %s.\n" +"%s" +msgstr "" +"Ne morem zapisati datoteke %s.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:638 +msgid "" +"Although Inkscape will run, it will use default settings,\n" +"and any changes made in preferences will not be saved." +msgstr "" +"Inkscape bo sicer deloval, a z privzetimi nastavitvami.\n" +"Spremembe nastavitev se ne bodo shranile." + +#: ../../po/../src/inkscape.cpp:708 +#, c-format +msgid "" +"%s is not a regular file.\n" +"%s" +msgstr "" +"%s ni običajna datoteka.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:709 +#, c-format +msgid "" +"%s not a valid XML file, or\n" +"you don't have read permissions on it.\n" +"%s" +msgstr "" +"%s ni veljavna XML datoteka, ali\n" +"pa zanjo nimate pravice branja.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:711 +#, fuzzy, c-format +msgid "" +"%s is not a valid menus file.\n" +"%s" +msgstr "" +"Datoteka %s ne vsebuje nastavitev.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:712 +#, fuzzy +msgid "" +"Inkscape will run with default menus.\n" +"New menus will not be saved." +msgstr "" +"Inkscape se bo zagnal s privzetimi nastavitvami.\n" +"Nove nastavitve ne bodo shranjene." + +#. sp_ui_menu_append_check_item_from_verb(m, view, _("_Menu"), _("Show or hide the menu bar"), "menu", +#. checkitem_toggled, checkitem_update, 0); +#: ../../po/../src/interface.cpp:753 +msgid "Commands Bar" +msgstr "Vrstica ukazov" + +#: ../../po/../src/interface.cpp:753 +msgid "Show or hide the Commands bar (under the menu)" +msgstr "Kaži ali skrij vrstico ukazov (pod meniji)" + +#: ../../po/../src/interface.cpp:755 +msgid "Tool Controls" +msgstr "Nadzor orodij" + +#: ../../po/../src/interface.cpp:755 +msgid "Show or hide the Tool Controls panel" +msgstr "Kaži ali skrij orodno vrstico (na levi)" + +#: ../../po/../src/interface.cpp:757 +msgid "_Toolbox" +msgstr "_Orodjarna" + +#: ../../po/../src/interface.cpp:757 +msgid "Show or hide the main toolbox (on the left)" +msgstr "Kaži ali skrij glavno orodno vrstico (na levi)" + +#: ../../po/../src/interface.cpp:763 +msgid "_Statusbar" +msgstr "Vrstica _stanja" + +#: ../../po/../src/interface.cpp:763 +msgid "Show or hide the statusbar (at the bottom of the window)" +msgstr "Kaži ali skrij vrstico stanja (na dnu okna)" + +#: ../../po/../src/interface.cpp:820 +#, c-format +msgid "Verb \"%s\" Unknown" +msgstr "" + +#. TRANSLATORS: #%s is the id of the group e.g. , not a number. +#: ../../po/../src/interface.cpp:930 +#, c-format +msgid "Enter group #%s" +msgstr "Vnesi skupino #%s" + +#: ../../po/../src/interface.cpp:941 +msgid "Go to parent" +msgstr "Pojdi do starÅ¡a" + +#: ../../po/../src/interface.cpp:972 +msgid "Could not parse SVG data" +msgstr "Ne morem uvoziti podatkov SVG" + +#: ../../po/../src/interface.cpp:1135 +#, c-format +msgid "Overwrite %s" +msgstr "PrepiÅ¡i %s" + +#: ../../po/../src/interface.cpp:1153 +#, c-format +msgid "" +"The file %s already exists. Do you want to overwrite that file with the " +"current document?" +msgstr "" +"Datoteka %s že obstaja. Ali jo želite prepisati s trenutnim dokumentom?" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:59 +msgid "Jabber connection lost." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:72 +#, c-format +msgid "Sending message; %u message remaining in send queue." +msgid_plural "Sending message; %u messages remaining in send queue." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:78 +msgid "Receive queue empty." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:154 +#, c-format +msgid "Receiving change; %u change left to process." +msgid_plural "Receiving change; %u changes left to process." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:157 +#, c-format +msgid "%s has left the chatroom." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:221 +msgid "Nickname %1 is already in use. Please choose a different nickname." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:225 +msgid "An error was encountered while attempting to connect to the server." +msgstr "" + +#. Check to see if the user made any modifications to this document. If so, +#. we want to give them the option of (1) letting us clear their document or (2) +#. opening a new, blank document for the whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:131 +msgid "%1 has invited you to a whiteboard session." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:132 +msgid "Incoming whiteboard invitation from %1" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:135 +msgid "Do you wish to accept %1's whiteboard session invitation?" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:137 +msgid "" +"Would you like to accept %1's invitation in a new document window?\n" +"Accepting the invitation in your current window will discard unsaved changes." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:143 +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:198 +#, fuzzy +msgid "Accept invitation" +msgstr "PospeÅ¡ek" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:144 +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:199 +msgid "Decline invitation" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:145 +#, fuzzy +msgid "Accept invitation in new document window" +msgstr "Ustvari nov dokument" + +#. We could not create a new desktop; ask the user if she or he wants to +#. replace the current document and accept the invitation, or reject the invitation. +#. TRANSLATORS: %1 is a userid here +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:196 +msgid "" +"A new document window could not be opened for a whiteboard session with %" +"1" +msgstr "" + +#. TRANSLATORS: %1 is the peer whom refused our invitation. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:238 +msgid "" +"The user %1 has refused your " +"whiteboard invitation.\n" +"\n" +msgstr "" + +#. TRANSLATORS: %1 is the peer whom refused our invitation, %2 is our Jabber identity. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:241 +msgid "" +"You are still connected to a Jabber server as %2, and may send an " +"invitation to %1 again, or you may send an invitation to a different " +"user." +msgstr "" + +#. TRANSLATORS: %1 is the peer whom we tried to contact, but is already in a whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:252 +msgid "" +"The user %1 is already in a " +"whiteboard session.\n" +"\n" +msgstr "" + +#. TRANSLATORS: %1 is the peer whom we tried to contact, but is already in a whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:255 +msgid "" +"You are still connected to a Jabber server as %1, and may send an " +"invitation to a different user." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/invitation-confirm-dialog.cpp:26 +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:24 +msgid "_Write session file:" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/message-processors.cpp:145 +#, c-format +msgid "%s has joined the chatroom." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/message-queue.cpp:87 +#, fuzzy, c-format +msgid "%u change in receive queue." +msgid_plural "%u changes in receive queue." +msgstr[0] "Ni sprememb za shranjevanje." +msgstr[1] "Ni sprememb za shranjevanje." +msgstr[2] "Ni sprememb za shranjevanje." +msgstr[3] "Ni sprememb za shranjevanje." + +#: ../../po/../src/jabber_whiteboard/message-queue.cpp:117 +#, fuzzy, c-format +msgid "%u change in send queue." +msgid_plural "%u changes in send queue." +msgstr[0] "Ni sprememb za shranjevanje." +msgstr[1] "Ni sprememb za shranjevanje." +msgstr[2] "Ni sprememb za shranjevanje." +msgstr[3] "Ni sprememb za shranjevanje." + +#. if ID is NULL, then we have a real problem -- we were not able to find a key +#. nor generate one. The only thing we can really do here is abort, since we have +#. no way to let the other client(s) uniquely identify this object. +#. FIXME: If this indicates a programming bug, then don't request translation with +#. * _(...): it is most useful in untranslated form so that developers may search for +#. * it when someone reports it in a bug report (as we want users to do for all bugs, +#. * as indicated by it being a g_warning string). +#. * +#. * Otherwise, if it is not a programming bug but a network error or a bug in the +#. * remote peer (perhaps running different software) or whatever, then present it in +#. * an alert box, and avoid use of technical jargon `NULL'. +#. +#: ../../po/../src/jabber_whiteboard/message-utilities.cpp:171 +msgid "" +"ID for new object is NULL even after generation and lookup attempts: the new " +"object will NOT be sent, nor will any of its child objects!" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:60 +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:995 +msgid "Select a location and filename" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:62 +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:997 +#, fuzzy +msgid "Set filename" +msgstr "_Ime datoteke" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:301 +msgid "No SSL certificate was found." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:304 +msgid "The SSL certificate provided by the Jabber server is untrusted." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:307 +msgid "The SSL certificate provided by the Jabber server is expired." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:310 +msgid "" +"The SSL certificate provided by the Jabber server has not been activated." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:313 +msgid "" +"The SSL certificate provided by the Jabber server contains a hostname that " +"does not match the Jabber server's hostname." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:316 +msgid "" +"The SSL certificate provided by the Jabber server contains an invalid " +"fingerprint." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:319 +msgid "An unknown error occurred while setting up the SSL connection." +msgstr "" + +#. TRANSLATORS: %1 is the message that describes the specific error that occurred when +#. establishing the SSL connection. +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:325 +msgid "" +"%1\n" +"\n" +"Do you wish to continue connecting to the Jabber server?" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:328 +msgid "Continue connecting and ignore further errors" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:329 +msgid "Continue connecting, but warn me of further errors" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:330 +#, fuzzy +msgid "Cancel connection" +msgstr "Izbira" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:777 +#, c-format +msgid "Established whiteboard session with %s." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:785 +#, c-format +msgid "%s has left the whiteboard session." +msgstr "" + +#. Inform the user +#. TRANSLATORS: %1 is the name of the user that disconnected, %2 is the name of the user whom the disconnected user disconnected from. +#. This message is not used in a chatroom context. +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:790 +msgid "" +"The user %1 has left the " +"whiteboard session.\n" +"\n" +msgstr "" + +#. TRANSLATORS: %1 and %2 are userids +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:792 +msgid "" +"You are still connected to a Jabber server as %2, and may establish a " +"new session to %1 or a different user." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:988 +msgid "" +"Could not open file %1 for session recording.\n" +"The error encountered was: %2.\n" +"\n" +"You may select a different location to record the session, or you may opt to " +"not record this session." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:990 +msgid "Choose a different location" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:991 +msgid "Skip session recording" +msgstr "" + +#: ../../po/../src/knot.cpp:673 +msgid "Node or handle drag canceled." +msgstr "Preklican premik vozlišča ali ročice." + +#: ../../po/../src/libnrtype/FontFactory.cpp:358 +msgid "Ignoring font without family that will crash Pango" +msgstr "Spregledovanje pisave brez družine, ki bi sesula Pango" + +#: ../../po/../src/main.cpp:395 +msgid "Print the Inkscape version number" +msgstr "IzpiÅ¡i različico Inkscape-a" + +#: ../../po/../src/main.cpp:400 +msgid "Do not use X server (only process files from console)" +msgstr "Ne uporabi strežnika X (datoteke obdeluj iz konzole)" + +#: ../../po/../src/main.cpp:405 +msgid "Try to use X server (even if $DISPLAY is not set)" +msgstr "" +"Poskusi uporabiti strežnik X (četudi spremenljivka $DISPLAY ni nastavljena)" + +#: ../../po/../src/main.cpp:410 +msgid "Open specified document(s) (option string may be excluded)" +msgstr "Odpri izbrano datoteko (niz možnosti je lahko izključen)" + +#: ../../po/../src/main.cpp:411 ../../po/../src/main.cpp:416 +#: ../../po/../src/main.cpp:421 ../../po/../src/main.cpp:483 +#: ../../po/../src/main.cpp:488 ../../po/../src/main.cpp:493 +msgid "FILENAME" +msgstr "IME DATOTEKE" + +#: ../../po/../src/main.cpp:415 +msgid "Print document(s) to specified output file (use '| program' for pipe)" +msgstr "" +"Natisni datoteke v izbrano izhodno datoteko (uporabite '| program' za " +"preusmeritev)" + +#: ../../po/../src/main.cpp:420 +msgid "Export document to a PNG file" +msgstr "Izvozi dokument v PNG sliko" + +#: ../../po/../src/main.cpp:425 +msgid "The resolution used for exporting SVG into bitmap (default 90)" +msgstr "Ločljivost pri pretvarjanju iz SVG v rastersko sliko (privzeto 90)" + +#: ../../po/../src/main.cpp:426 +msgid "DPI" +msgstr "DPI" + +#: ../../po/../src/main.cpp:430 +#, fuzzy +msgid "" +"Exported area in SVG user units (default is the canvas; 0,0 is lower-left " +"corner)" +msgstr "" +"Območje za izvoz v SVG točkah (privzet je cel dokument, 0,0 pomeni spodnji " +"levi kot)" + +#: ../../po/../src/main.cpp:431 +msgid "x0:y0:x1:y1" +msgstr "x0:y0:x1:y1" + +#: ../../po/../src/main.cpp:435 +msgid "Exported area is the entire drawing (not canvas)" +msgstr "Izvoženo območje je celotna risba (ne platno)" + +#: ../../po/../src/main.cpp:440 +msgid "" +"Snap the bitmap export area outwards to the nearest integer values (in SVG " +"user units)" +msgstr "" + +#: ../../po/../src/main.cpp:445 +msgid "The width of exported bitmap in pixels (overrides export-dpi)" +msgstr "Å irina ustvarjene slike v pikah (spremeni dpi) " + +#: ../../po/../src/main.cpp:446 +msgid "WIDTH" +msgstr "Å IRINA" + +#: ../../po/../src/main.cpp:450 +msgid "The height of exported bitmap in pixels (overrides export-dpi)" +msgstr "ViÅ¡ina ustvarjene slike v pikah (spremeni dpi)" + +#: ../../po/../src/main.cpp:451 +msgid "HEIGHT" +msgstr "VIÅ INA" + +#: ../../po/../src/main.cpp:455 +msgid "The ID of the object to export (overrides export-area)" +msgstr "ID predmeta, ki ga želite izvoziti (spremeni območje za izvoz)" + +#: ../../po/../src/main.cpp:456 ../../po/../src/main.cpp:532 +msgid "ID" +msgstr "ID" + +#. TRANSLATORS: this means: "Only export the object whose id is given in --export-id". +#. See "man inkscape" for details. +#: ../../po/../src/main.cpp:462 +msgid "" +"Export just the object with export-id, hide all others (only with export-id)" +msgstr "" +"Izvozi samo predmet s to oznako in skrije vse druge (samo z ID za izvoz)" + +#: ../../po/../src/main.cpp:467 +msgid "Use stored filename and DPI hints when exporting (only with export-id)" +msgstr "" +"Ob izvozu uporabi shranjeno ime datoteke in namige ločljivosti (samo za id " +"za izvoz)" + +#: ../../po/../src/main.cpp:472 +msgid "Background color of exported bitmap (any SVG-supported color string)" +msgstr "Barva ozadja izvoženih slik (kakrÅ¡nakoli oblika podprta v SVGju) " + +#: ../../po/../src/main.cpp:473 +msgid "COLOR" +msgstr "BARVA" + +#: ../../po/../src/main.cpp:477 +msgid "Background opacity of exported bitmap (either 0.0 to 1.0, or 1 to 255)" +msgstr "Prosojnost ozadja izvoženih slik (0.0 do 1.0 ali 1 do 255)" + +#: ../../po/../src/main.cpp:478 +msgid "VALUE" +msgstr "VREDNOST" + +#: ../../po/../src/main.cpp:482 +msgid "Export document to plain SVG file (no sodipodi or inkscape namespaces)" +msgstr "Izvozi dokument v čisti SVG (brez dodatnih Sodiopi in Inkscape polj)" + +#: ../../po/../src/main.cpp:487 +msgid "Export document to a PS file" +msgstr "Izvozi dokument v PS datoteko" + +#: ../../po/../src/main.cpp:492 +msgid "Export document to an EPS file" +msgstr "Izvozi dokument v EPS datoteko" + +#: ../../po/../src/main.cpp:497 +msgid "Convert text object to paths on export (EPS)" +msgstr "Ob izvozu (EPS) pretvori besedila v krivulje" + +#: ../../po/../src/main.cpp:502 +msgid "Export files with the bounding box set to the page size (EPS)" +msgstr "Izvozi datoteke z okvirjem v velikosti strani (EPS)" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:508 +msgid "" +"Query the X coordinate of the drawing or, if specified, of the object with --" +"query-id" +msgstr "" +"Preveri X koordinate risbe ali, če je določen, predmet z nastavljeno oznako " +"za preverjanje" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:514 +msgid "" +"Query the Y coordinate of the drawing or, if specified, of the object with --" +"query-id" +msgstr "" +"Preveri Y koordinate risbe ali, če je določen, predmet z nastavljeno oznako " +"za preverjanje" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:520 +msgid "" +"Query the width of the drawing or, if specified, of the object with --query-" +"id" +msgstr "" +"Preveri Å¡irino risbe ali, če je določen, predmet z nastavljeno oznako za " +"preverjanje" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:526 +msgid "" +"Query the height of the drawing or, if specified, of the object with --query-" +"id" +msgstr "" +"Preveri viÅ¡ino risbe ali, če je določen, predmet z nastavljeno oznako za " +"preverjanje" + +#: ../../po/../src/main.cpp:531 +msgid "The ID of the object whose dimensions are queried" +msgstr "ID predmeta, katerega velikost je zahtevana" + +#. TRANSLATORS: this option makes Inkscape print the name (path) of the extension directory +#: ../../po/../src/main.cpp:537 +msgid "Print out the extension directory and exit" +msgstr "IzpiÅ¡i imenik razÅ¡iritev in končaj" + +#: ../../po/../src/main.cpp:542 +msgid "Show given files one-by-one, switch to next on any key/mouse event" +msgstr "" +"Kaži podane datoteke vsako posebaj, preklopi na naslednjo ob kateremkoli " +"miÅ¡kinem ali tipkovničnem dogodku." + +#: ../../po/../src/main.cpp:547 +msgid "Use the new Gtkmm GUI interface" +msgstr "Uporabi novi Gtkmm grafični vmesnik" + +#: ../../po/../src/main.cpp:552 +msgid "Remove unused definitions from the defs section(s) of the document" +msgstr "Odstrani nepotrebne definicije iz dokumenta" + +#: ../../po/../src/main.cpp:741 +msgid "" +"[OPTIONS...] [FILE...]\n" +"\n" +"Available options:" +msgstr "" +"[Možnosti ...] [Datoteka ...]\n" +"\n" +"Mogoče izbire:" + +#: ../../po/../src/menus-skeleton.h:17 +msgid "_New" +msgstr "_Nova" + +#: ../../po/../src/menus-skeleton.h:22 +msgid "Open _Recent" +msgstr "Odpri _nedavno" + +#: ../../po/../src/menus-skeleton.h:53 +msgid "_Edit" +msgstr "_Uredi" + +#: ../../po/../src/menus-skeleton.h:84 +msgid "_View" +msgstr "_Pogled" + +#: ../../po/../src/menus-skeleton.h:85 +#, fuzzy +msgid "_Zoom" +msgstr "Povečava" + +#: ../../po/../src/menus-skeleton.h:102 +#, fuzzy +msgid "Show/Hide" +msgstr "_Pokaži/skrij" + +#: ../../po/../src/menus-skeleton.h:107 +msgid "_Display mode" +msgstr "" + +#: ../../po/../src/menus-skeleton.h:126 +msgid "_Layer" +msgstr "_Sloj" + +#: ../../po/../src/menus-skeleton.h:143 +msgid "_Object" +msgstr "_Predmet" + +#: ../../po/../src/menus-skeleton.h:165 +msgid "_Path" +msgstr "_Pot" + +#: ../../po/../src/menus-skeleton.h:188 +msgid "_Text" +msgstr "_Besedilo" + +#: ../../po/../src/menus-skeleton.h:200 +msgid "Effects" +msgstr "Učinki" + +#: ../../po/../src/menus-skeleton.h:207 +msgid "Whiteboa_rd" +msgstr "" + +#: ../../po/../src/menus-skeleton.h:220 +msgid "_Help" +msgstr "_Pomoč" + +#: ../../po/../src/menus-skeleton.h:222 +#, fuzzy +msgid "Tutorials" +msgstr "_Vodiči" + +#: ../../po/../src/node-context.cpp:382 +msgid "" +"Ctrl: toggle node type, snap handle angle, move hor/vert; Ctrl" +"+Alt: move along handles" +msgstr "" +"Ctrl: preklopi vrsto vozlišča, preskakuj kot ročice, premikaj navipno/" +"vodoravno; Ctrl+Alt: premikaj po ročicah" + +#: ../../po/../src/node-context.cpp:383 +msgid "" +"Shift: toggle node selection, disable snapping, rotate both handles" +msgstr "" +"Shift: preklopi izbiro vozlišč, izključi preskakovanje, zavrti obe " +"ročici" + +#: ../../po/../src/node-context.cpp:384 +msgid "Alt: lock handle length; Ctrl+Alt: move along handles" +msgstr "" +"Alt: zakleni dolžino ročice; Ctrl+Alt: premikaj po ročicah" + +#: ../../po/../src/nodepath.cpp:1399 ../../po/../src/nodepath.cpp:1411 +#: ../../po/../src/nodepath.cpp:1492 ../../po/../src/nodepath.cpp:1504 +msgid "To join, you must have two endnodes selected." +msgstr "Za združitev morate izbrati vsaj dve vozlišči." + +#: ../../po/../src/nodepath.cpp:1633 ../../po/../src/nodepath.cpp:1647 +msgid "" +"Select two non-endpoint nodes on a path between which to delete " +"segments." +msgstr "" +"Da bi izbrisali del poti, morate na njej izbrati dve vmesni vozlišči." + +#: ../../po/../src/nodepath.cpp:1743 +msgid "Cannot find path between nodes." +msgstr "Ne najdem poti med vozlišči." + +#: ../../po/../src/nodepath.cpp:2822 +#, fuzzy, c-format +msgid "" +"Node handle: angle %0.2f°, length %s; with Ctrl to snap " +"angle; with Alt to lock length; with Shift to rotate both " +"handles" +msgstr "" +"Ročica vozlišča: pri %0.2f° dolžine %s; Ctrl za " +"preskakovanje kota; z Alt zaklenete dolžino; s Shift pa hkrati " +"premikate tudi nasprotno ročico" + +#: ../../po/../src/nodepath.cpp:3351 +msgid "" +"Node: drag to edit the path; with Ctrl to snap to horizontal/" +"vertical; with Ctrl+Alt to snap to handles' directions" +msgstr "" +"Vozlišče: povlecite za urejanje poti; s Ctrl za preskakovanje " +"vodoravno ali navpično; s Ctrl+Alt za preskakovanje po smereh ročic" + +#: ../../po/../src/nodepath.cpp:3375 +msgid "" +"Node handle: drag to shape the curve; with Ctrl to snap angle; " +"with Alt to lock length; with Shift to rotate both handles" +msgstr "" +"Ročica vozlišča povlecite da oblikujete krivuljo; s Ctrl za " +"preskakovanje kota; z Alt zaklenete dolžino; s Shift pa hkrati " +"premikate tudi nasprotno ročico" + +#: ../../po/../src/nodepath.cpp:3399 +msgid "" +"Node handle: drag to shape the curve; with Ctrl to snap angle; " +"with Alt to lock length; with Shift to rotate the opposite " +"handle in sync" +msgstr "" +"Ročica vozlišča povlecite da oblikujete krivuljo; s Ctrl za " +"preskakovanje kota; z Alt zaklenete dolžino; s Shift pa hkrati " +"premikate tudi nasprotno ročico" + +#. TRANSLATORS: "end" is an adjective here (NOT a verb) +#: ../../po/../src/nodepath.cpp:3591 +msgid "end node" +msgstr "končno vozlišče" + +#. TRANSLATORS: "cusp" means "sharp" (cusp node); see also the Advanced Tutorial +#: ../../po/../src/nodepath.cpp:3596 +msgid "cusp" +msgstr "ostro" + +#. TRANSLATORS: "smooth" is an adjective here +#: ../../po/../src/nodepath.cpp:3599 +msgid "smooth" +msgstr "gladka" + +#: ../../po/../src/nodepath.cpp:3601 +msgid "symmetric" +msgstr "simetrična" + +#. TRANSLATORS: "end" is an adjective here (NOT a verb) +#: ../../po/../src/nodepath.cpp:3607 +msgid "end node, handle retracted (drag with Shift to extend)" +msgstr "končno vozlišče, skrčena ročica (povlecite s Shift za razteg)" + +#: ../../po/../src/nodepath.cpp:3609 +msgid "one handle retracted (drag with Shift to extend)" +msgstr "ena skrčena ročica (povlecite s Shift za razteg)" + +#: ../../po/../src/nodepath.cpp:3612 +msgid "both handles retracted (drag with Shift to extend)" +msgstr "obe ročici skrčeni (povlecite s Shift za razteg)" + +#: ../../po/../src/nodepath.cpp:3624 +msgid "Drag nodes or node handles; arrow keys to move nodes" +msgstr "" +"Za urejanje poti povlecite vozlišča ali kontrolne točke; smerne " +"tipke premikajo vozlišča" + +#: ../../po/../src/nodepath.cpp:3625 +msgid "Drag the node or its handles; arrow keys to move the node" +msgstr "" +"Za urejanje poti povlecite vozlišča ali kontrolne točke; smerne " +"tipke premikajo vozlišča" + +#: ../../po/../src/nodepath.cpp:3651 ../../po/../src/nodepath.cpp:3663 +msgid "Select a single object to edit its nodes or handles." +msgstr "Izberi en predmet in uredi vozlišča ali ročice" + +#: ../../po/../src/nodepath.cpp:3655 +#, c-format +msgid "" +"0 out of %i node selected. Click, Shift+click, " +"or drag around nodes to select." +msgid_plural "" +"0 out of %i nodes selected. Click, Shift+click, " +"or drag around nodes to select." +msgstr[0] "" +"Izbranih 0 od %i vozlišč. Izberite jih s klikom, Shift+klikom " +"ali s potegom okrog njih." +msgstr[1] "" +"Izbranih 0 od %i vozlišča. Izberite jih s klikom, Shift+klikom " +"ali s potegom okrog njih." +msgstr[2] "" +"Izbranih 0 od %i vozlišč. Izberite jih s klikom, Shift+klikom " +"ali s potegom okrog njih." +msgstr[3] "" +"Izbranih 0 od %i vozlišč. Izberite jih s klikom, Shift+klikom " +"ali s potegom okrog njih." + +#: ../../po/../src/nodepath.cpp:3661 +msgid "Drag the handles of the object to modify it." +msgstr "Za preoblikovanje povlecite ročice predmeta." + +#: ../../po/../src/nodepath.cpp:3669 +#, c-format +msgid "%i of %i node selected; %s. %s." +msgid_plural "%i of %i nodes selected; %s. %s." +msgstr[0] "Izbranih %i od %i vozlišč; %s. %s. " +msgstr[1] "Izbrano %i od %i vozlišč; %s. %s. " +msgstr[2] "Izbrani %i od %i vozlišč; %s. %s. " +msgstr[3] "Izbrana %i od %i vozlišč; %s. %s. " + +#: ../../po/../src/nodepath.cpp:3675 +#, c-format +msgid "%i of %i node selected. %s." +msgid_plural "%i of %i nodes selected. %s." +msgstr[0] "Izbranih %i od %i vozlišč. %s. " +msgstr[1] "Izbrano %i od %i vozlišč. %s. " +msgstr[2] "Izbrani %i od %i vozlišč. %s. " +msgstr[3] "Izbrana %i od %i vozlišč. %s. " + +#: ../../po/../src/object-edit.cpp:493 +msgid "" +"Adjust the horizontal rounding radius; with Ctrl to make the " +"vertical radius the same" +msgstr "" +"Prilagodite polmer vodoravne obrobe; s Ctrl pa poenotite " +"navpični polmer" + +#: ../../po/../src/object-edit.cpp:499 +msgid "" +"Adjust the vertical rounding radius; with Ctrl to make the " +"horizontal radius the same" +msgstr "" +"Prilagodite polmer navpične obrobe; s Ctrl pa poenotite " +"vodoravni polmer" + +#: ../../po/../src/object-edit.cpp:506 ../../po/../src/object-edit.cpp:513 +msgid "" +"Adjust the width and height of the rectangle; with Ctrl to " +"lock ratio or stretch in one dimension only" +msgstr "" +"Prilagodite viÅ¡ino in Å¡irino pravokotnika; s Ctrl zaklenete " +"razmerje ali raztegujete le eno razseznost" + +#: ../../po/../src/object-edit.cpp:686 +msgid "Adjust ellipse width, with Ctrl to make circle" +msgstr "Prilagodite Å¡irino elipse; s Ctrl nariÅ¡ete krog" + +#: ../../po/../src/object-edit.cpp:689 +msgid "Adjust ellipse height, with Ctrl to make circle" +msgstr "Prilagodite viÅ¡ino elipse; s Ctrl nariÅ¡ete krog" + +#: ../../po/../src/object-edit.cpp:692 +msgid "" +"Position the start point of the arc or segment; with Ctrl to " +"snap angle; drag inside the ellipse for arc, outside for " +"segment" +msgstr "" +"Nastavitev začetne točke loka ali odseka; s Ctrl preskakujete " +"po kotih; za lok povlecite znotraj elipse in za odsek zunaj" + +#: ../../po/../src/object-edit.cpp:695 +msgid "" +"Position the end point of the arc or segment; with Ctrl to " +"snap angle; drag inside the ellipse for arc, outside for " +"segment" +msgstr "" +"Nastavitev končne točke loka ali odseka; s Ctrl preskakujete " +"po kotih; za lok povlecite znotraj elipse in za odsek zunaj" + +#: ../../po/../src/object-edit.cpp:800 +msgid "" +"Adjust the tip radius of the star or polygon; with Shift to " +"round; with Alt to randomize" +msgstr "" +"Prilagodite polmer vrhov zvezde ali mnogokotnika; s Ctrl ju " +"zaobljite; z Alt napravite naključno" + +#: ../../po/../src/object-edit.cpp:803 +msgid "" +"Adjust the base radius of the star; with Ctrl to keep star " +"rays radial (no skew); with Shift to round; with Alt to " +"randomize" +msgstr "" +"Prilagodite polmer osnove zvezde ali mnogokotnika; s Ctrl " +"ostanejo kraki pravilni (ne zamaknjeni); s Shift jo zaobljite; z " +"Alt napravite naključno" + +#: ../../po/../src/object-edit.cpp:967 +msgid "" +"Roll/unroll the spiral from inside; with Ctrl to snap angle; " +"with Alt to converge/diverge" +msgstr "" +"Zavijte/razvijte spiralo od znotraj; s Ctrl preskakujete po " +"kotih; z Alt prilagodite konvergenčnost" + +#: ../../po/../src/object-edit.cpp:969 +msgid "" +"Roll/unroll the spiral from outside; with Ctrl to snap angle; " +"with Shift to scale/rotate" +msgstr "" +"Zavijte/razvijte spiralo od zunaj; s Ctrl preskakujete po " +"kotih; s Shift jo razvlečete/vrtite" + +#: ../../po/../src/object-edit.cpp:1006 +msgid "Adjust the offset distance" +msgstr "Prilagodite razdaljo zamika" + +#. TRANSLATORS: This refers to the pattern that's inside the object +#: ../../po/../src/object-edit.cpp:1036 +msgid "Move the pattern fill inside the object" +msgstr "Premakni vzorec v predmetu" + +#: ../../po/../src/object-edit.cpp:1038 +msgid "Scale the pattern fill uniformly" +msgstr "Enakomerno spremeni velikost vzorca" + +#: ../../po/../src/object-edit.cpp:1040 +msgid "Rotate the pattern fill; with Ctrl to snap angle" +msgstr "Vrtitevzorec; s Ctrl preskakujete po kotih" + +#: ../../po/../src/object-edit.cpp:1065 +msgid "Drag to resize the flowed text frame" +msgstr "Povlecite za umeritev tekočega besedilnega okvirja" + +#. Item dialog +#: ../../po/../src/object-ui.cpp:106 +msgid "Object _Properties" +msgstr "Lastnosti _predmeta" + +#. Select item +#: ../../po/../src/object-ui.cpp:116 +msgid "_Select This" +msgstr "_Izberi to" + +#. Create link +#: ../../po/../src/object-ui.cpp:126 +msgid "_Create Link" +msgstr "_Ustvari povezavo" + +#. "Ungroup" +#: ../../po/../src/object-ui.cpp:199 ../../po/../src/verbs.cpp:1931 +msgid "_Ungroup" +msgstr "_Razdruži" + +#. Link dialog +#: ../../po/../src/object-ui.cpp:239 +msgid "Link _Properties" +msgstr "_Lastnosti povezave" + +#. Select item +#: ../../po/../src/object-ui.cpp:249 +msgid "_Follow Link" +msgstr "_Sledi povezavi" + +#. Reset transformations +#: ../../po/../src/object-ui.cpp:254 +msgid "_Remove Link" +msgstr "_Odstrani povezavo" + +#. Link dialog +#: ../../po/../src/object-ui.cpp:303 +msgid "Image _Properties" +msgstr "_Lastnosti slike" + +#. Item dialog +#: ../../po/../src/object-ui.cpp:344 +msgid "_Fill and Stroke" +msgstr "_Polnjenje in obroba" + +#: ../../po/../src/path-chemistry.cpp:58 +msgid "Select at least two objects to combine." +msgstr "Za sestavljanje izberite vsaj dva predmeta." + +#: ../../po/../src/path-chemistry.cpp:65 +msgid "At least one of the objects is not a path, cannot combine." +msgstr "Ne morem sestaviti, ker eden od predmetov ni pot." + +#: ../../po/../src/path-chemistry.cpp:73 +msgid "" +"You cannot combine objects from different groups or layers." +msgstr "Ne morete sestavljati predmetov iz različnih skupin ali slojev." + +#: ../../po/../src/path-chemistry.cpp:155 +msgid "Select path(s) to break apart." +msgstr "Izberite nekaj poti za razlom." + +#: ../../po/../src/path-chemistry.cpp:231 +msgid "No path(s) to break apart in the selection." +msgstr "V izbiri ni poti, ki bi jih lahko razstavil." + +#: ../../po/../src/path-chemistry.cpp:252 +msgid "Select object(s) to convert to path." +msgstr "Izberite nekaj predmetov za pretvorbo v poti." + +#: ../../po/../src/path-chemistry.cpp:297 +msgid "No objects to convert to path in the selection." +msgstr "Med izbiro ni predmetov, ki bi jih lahko pretvoril v črte." + +#: ../../po/../src/path-chemistry.cpp:345 +msgid "Select path(s) to reverse." +msgstr "Izberite eno ali več poti za spremembo smeri." + +#: ../../po/../src/path-chemistry.cpp:370 +msgid "No paths to reverse in the selection." +msgstr "V izbiri ni poti, ki bi jih lahko obrnil." + +#: ../../po/../src/pen-context.cpp:379 ../../po/../src/pencil-context.cpp:233 +msgid "Continuing selected path" +msgstr "Nadaljuj izbrano pot" + +#: ../../po/../src/pen-context.cpp:390 ../../po/../src/pencil-context.cpp:242 +msgid "Creating new path" +msgstr "Ustari novo pot" + +#: ../../po/../src/pen-context.cpp:394 ../../po/../src/pencil-context.cpp:246 +msgid "Appending to selected path" +msgstr "Dodaj k izbrani poti" + +#: ../../po/../src/pen-context.cpp:538 +#, fuzzy +msgid "Click or click and drag to close and finish the path." +msgstr "" +"Kliknite da uredite besedilo, povlecite da izberete del " +"besedila" + +#: ../../po/../src/pen-context.cpp:548 +#, fuzzy +msgid "" +"Click or click and drag to continue the path from this point." +msgstr "" +"Kliknite da uredite besedilo, povlecite da izberete del " +"besedila" + +#: ../../po/../src/pen-context.cpp:857 +#, fuzzy, c-format +msgid "" +"%s: angle %3.2f°, distance %s; with Ctrl to snap angle, " +"Enter to finish the path" +msgstr "" +"Ročica vozlišča: pri %0.2f° dolžine %s; Ctrl za " +"preskakovanje kota; z Alt zaklenete dolžino; s Shift pa hkrati " +"premikate tudi nasprotno ročico" + +#: ../../po/../src/pen-context.cpp:882 +#, fuzzy, c-format +msgid "" +"Curve handle: angle %3.2f°, length %s; with Ctrl to snap " +"angle" +msgstr "Zavrti: %0.2f stopinj;s Ctrl preskakuj po kotih " + +#: ../../po/../src/pen-context.cpp:912 +#, fuzzy, c-format +msgid "" +"%s: angle %3.2f°, length %s; with Ctrl to snap angle, " +"with Shift to move this handle only" +msgstr "" +"Ročica vozlišča: pri %0.2f° dolžine %s; Ctrl za " +"preskakovanje kota; z Alt zaklenete dolžino; s Shift pa hkrati " +"premikate tudi nasprotno ročico" + +#: ../../po/../src/pen-context.cpp:946 +msgid "Finishing pen" +msgstr "Dokončaj s peresom" + +#: ../../po/../src/pencil-context.cpp:320 +msgid "Release here to close and finish the path." +msgstr "" + +#: ../../po/../src/pencil-context.cpp:326 +#, fuzzy +msgid "Drawing a freehand path" +msgstr "RiÅ¡i prostoročno " + +#: ../../po/../src/pencil-context.cpp:331 +msgid "Drag to continue the path from this point." +msgstr "" + +#. Write curves to object +#: ../../po/../src/pencil-context.cpp:390 +msgid "Finishing freehand" +msgstr "Dokončaj prostoročno" + +#: ../../po/../src/rect-context.cpp:387 +msgid "" +"Ctrl: make square or integer-ratio rect, lock a rounded corner " +"circular" +msgstr "" +"Ctrl: nariÅ¡ite kvadrat ali pravokotnik z razmerji celih Å¡tevil, " +"zaklenite krožen zaobljen kot" + +#: ../../po/../src/rect-context.cpp:549 +#, c-format +msgid "" +"Rectangle: %s × %s; with Ctrl to make square or integer-" +"ratio rectangle; with Shift to draw around the starting point" +msgstr "" +"Pravokotnik: %s × %s Ctrl da nariÅ¡ete kvadrat ali " +"pravokotnik z razmerji celih Å¡tevil; s Shift riÅ¡ete okrog začetne " +"točke" + +#: ../../po/../src/select-context.cpp:243 +msgid "Move canceled." +msgstr "Premik preklican." + +#: ../../po/../src/select-context.cpp:252 +msgid "Selection canceled." +msgstr "Izbiranje preklicano." + +#: ../../po/../src/select-context.cpp:642 +msgid "Ctrl: select in groups, move hor/vert" +msgstr "Ctrl: izberi v skupini, premikaj navpično / vodoravno" + +#: ../../po/../src/select-context.cpp:643 +msgid "Shift: toggle select, force rubberband, disable snapping" +msgstr "Shift: preklopi izbiro, vsili elastiko, izključi preskakovanje" + +#: ../../po/../src/select-context.cpp:644 +msgid "Alt: select under, move selected" +msgstr "Alt: izberi pod, premakni izbrano" + +#: ../../po/../src/select-context.cpp:798 +#, fuzzy +msgid "Selected object is not a group. Cannot enter." +msgstr "Ne morem razÅ¡iriti ali zožati, ker izbran predmet ni pot." + +#: ../../po/../src/select-context.cpp:876 +#, c-format +msgid "" +"Move by %s, %s; with Ctrl to restrict to horizontal/vertical; " +"with Shift to disable snapping" +msgstr "" +"Premakni za %s, %s; s Ctrl da omejite na vodoravno / navpično; " +"s Shift izključite preskakovanje" + +#: ../../po/../src/selection-chemistry.cpp:228 +msgid "Nothing was deleted." +msgstr "Nič nisem izbrisal." + +#: ../../po/../src/selection-chemistry.cpp:259 +msgid "Select object(s) to duplicate." +msgstr "Izberite nekaj predmetov za podvojevanje." + +#: ../../po/../src/selection-chemistry.cpp:420 +msgid "Select two or more objects to group." +msgstr "Za skupinjenje izberite vsaj dva predmeta." + +#: ../../po/../src/selection-chemistry.cpp:428 +msgid "Select at least two objects to group." +msgstr "Za skupinjenje izberite vsaj dva predmeta." + +#: ../../po/../src/selection-chemistry.cpp:513 +msgid "Select a group to ungroup." +msgstr "Izberite skupino za razdruženje" + +#: ../../po/../src/selection-chemistry.cpp:554 +msgid "No groups to ungroup in the selection." +msgstr "Med izbranimi predmeti ni skupin, ki bi jih lahko razdružili." + +#: ../../po/../src/selection-chemistry.cpp:623 +msgid "Select objects to raise." +msgstr "Za dvig izberite kak predmet." + +#: ../../po/../src/selection-chemistry.cpp:629 +#: ../../po/../src/selection-chemistry.cpp:681 +#: ../../po/../src/selection-chemistry.cpp:715 +#: ../../po/../src/selection-chemistry.cpp:773 +msgid "" +"You cannot raise/lower objects from different groups or layers." +msgstr "" +"Ne morete dvigati ali spuščati predmetov iz različnih skupin ali slojev." + +#: ../../po/../src/selection-chemistry.cpp:673 +msgid "Select object(s) to raise to top." +msgstr "Za dvig na vrh izberite kak predmet." + +#: ../../po/../src/selection-chemistry.cpp:709 +msgid "Select object(s) to lower." +msgstr "Za spust izberite kak predmet." + +#: ../../po/../src/selection-chemistry.cpp:765 +msgid "Select object(s) to lower to bottom." +msgstr "Za spust na dno izberite kak predmet." + +#: ../../po/../src/selection-chemistry.cpp:806 +msgid "Nothing to undo." +msgstr "Nič za popraviti" + +#: ../../po/../src/selection-chemistry.cpp:813 +msgid "Nothing to redo." +msgstr "Nič za ponoviti" + +#: ../../po/../src/selection-chemistry.cpp:969 +msgid "Nothing was copied." +msgstr "Nič nisem presnel" + +#: ../../po/../src/selection-chemistry.cpp:1051 +msgid "Current layer is hidden. Unhide it to be able to paste to it." +msgstr "Trenutni sloj je skrit. Če želite lepiti vanj ga odkrijte." + +#: ../../po/../src/selection-chemistry.cpp:1055 +msgid "Current layer is locked. Unlock it to be able to paste to it." +msgstr "Trenutni sloj je zaklenjen. Če želite lepiti vanj ga odkrijte." + +#: ../../po/../src/selection-chemistry.cpp:1068 +#: ../../po/../src/selection-chemistry.cpp:1103 +msgid "Nothing on the clipboard." +msgstr "Ničesar ni na odložišču." + +#: ../../po/../src/selection-chemistry.cpp:1109 +msgid "Select object(s) to paste style to." +msgstr "Izberite predmet za prenos sloga." + +#: ../../po/../src/selection-chemistry.cpp:1128 +msgid "Select object(s) to move to the layer above." +msgstr "Izberite nekaj predmetov za premik v sloj zgoraj." + +#: ../../po/../src/selection-chemistry.cpp:1146 +msgid "No more layers above." +msgstr "Zgoraj ni več slojev." + +#: ../../po/../src/selection-chemistry.cpp:1160 +msgid "Select object(s) to move to the layer below." +msgstr "Izberite nekaj predmetov za pomik na spodnji sloj." + +#: ../../po/../src/selection-chemistry.cpp:1178 +msgid "No more layers below." +msgstr "Spodaj ni več slojev." + +#: ../../po/../src/selection-chemistry.cpp:1811 +msgid "Select a clone to unlink." +msgstr "Izberite klona za razvez." + +#: ../../po/../src/selection-chemistry.cpp:1842 +msgid "No clones to unlink in the selection." +msgstr "Med izbranimi predmeti ni klonov, ki bi jih lahko odvezali." + +#: ../../po/../src/selection-chemistry.cpp:1859 +msgid "" +"Select a clone to go to its original. Select a linked offset " +"to go to its source. Select a text on path to go to the path. Select " +"a flowed text to go to its frame." +msgstr "" +"Izberite klona, ki naj se vrne k izvirniku. Izberite povezan " +"odmik, ki naj se vrne k izvirniku. Izberite besedilo na poti, ki " +"naj gre po poti. Izberite tekoče besedilo, ki naj gre k svojemu " +"okviru." + +#: ../../po/../src/selection-chemistry.cpp:1882 +msgid "" +"Cannot find the object to select (orphaned clone, offset, textpath, " +"flowed text?)" +msgstr "" +"Ne najdem predmeta, ki ga izbirate (zapuščen klon, zamik ali besedilo " +"na poti, tekoče besedilo?)" + +#: ../../po/../src/selection-chemistry.cpp:1888 +msgid "" +"The object you're trying to select is not visible (it is in <" +"defs>)" +msgstr "Predmet ki ga izbirate ni viden (je med <defs>)" + +#: ../../po/../src/selection-chemistry.cpp:1915 +msgid "Select object(s) to convert to pattern." +msgstr "Izberite predmet(e) za pretvorbo v vzorec." + +#: ../../po/../src/selection-chemistry.cpp:2006 +msgid "Select an object with pattern fill to extract objects from." +msgstr "" +"Izberite predmet s tlakovanim polnilom iz katerega želite izvleči " +"predmete." + +#: ../../po/../src/selection-chemistry.cpp:2059 +msgid "No pattern fills in the selection." +msgstr "Med izbiro ni polnjenj z vzorci." + +#: ../../po/../src/selection-chemistry.cpp:2079 +msgid "Select object(s) to make a bitmap copy." +msgstr "Izberite predmet(e) za rastersko kopiranje." + +#: ../../po/../src/selection-describer.cpp:37 +msgid "Click selection to toggle scale/rotation handles" +msgstr "" +"Z miÅ¡ko pritisnite na izbiro, da zamenjate ročke za povečevanje ali vrtenje" + +#. no items +#: ../../po/../src/selection-describer.cpp:39 +msgid "" +"No objects selected. Click, Shift+click, or drag around objects to select." +msgstr "" +"Ni izbranih predmetov. Izberite jih s klikom, Shift+klikom ali potegom okrog " +"njih." + +#: ../../po/../src/selection-describer.cpp:51 +#, c-format +msgid " in layer %s" +msgstr "v sloju %s." + +#: ../../po/../src/selection-describer.cpp:54 +#, c-format +msgid " in layer %s" +msgstr "v sloju %s." + +#: ../../po/../src/selection-describer.cpp:66 +msgid "Use Shift+D to look up original" +msgstr "Uporabite·Shift+D·da poiščene izvirnika" + +#: ../../po/../src/selection-describer.cpp:70 +msgid "Use Shift+D to look up path" +msgstr "Uporabite·Shift+D·da poiščete pot" + +#: ../../po/../src/selection-describer.cpp:74 +msgid "Use Shift+D to look up frame" +msgstr "Uporabite·Shift+D·da poiščene okvir" + +#: ../../po/../src/selection-describer.cpp:84 +#, c-format +msgid "%i object selected" +msgid_plural "%i objects selected" +msgstr[0] "%i izbranih predmetov" +msgstr[1] "%i izbran predmet" +msgstr[2] "%i izbrana predmeta" +msgstr[3] "%i izbrani predmeti" + +#: ../../po/../src/selection-describer.cpp:90 +#, c-format +msgid "%s%s. %s." +msgstr "%s%s. %s." + +#: ../../po/../src/selection-describer.cpp:94 +#, c-format +msgid "%s in %i layer. %s." +msgid_plural "%s in %i layers. %s." +msgstr[0] "%s v %i slojih. %s." +msgstr[1] "%s v %i sloju. %s." +msgstr[2] "%s v %i slojih. %s." +msgstr[3] "%s v %i slojih. %s." + +#: ../../po/../src/seltrans.cpp:498 +msgid "" +"Center of rotation and skewing: drag to reposition; scaling with " +"Shift also uses this center" +msgstr "" +"Središče vrtenja ali vlečenja: povlecite za premik središča; tudi " +"raztegovanje s držanjem Shifta uporablja to središče" + +#: ../../po/../src/seltrans.cpp:514 +msgid "" +"Squeeze or stretch selection; with Ctrl to scale uniformly; " +"with Shift to scale around rotation center" +msgstr "" +"Stisni ali raztegni izbrano; s Ctrl razteguj enakomerno; s " +"Shift razteguj okrog središča vrtenja" + +#: ../../po/../src/seltrans.cpp:515 +msgid "" +"Scale selection; with Ctrl to scale uniformly; with Shift to scale around rotation center" +msgstr "" +"Razteguj izbrano; s Ctrl razteguj enakomerno; s Shift " +"razteguj okrog središča vrtenja" + +#: ../../po/../src/seltrans.cpp:519 +msgid "" +"Skew selection; with Ctrl to snap angle; with Shift to " +"skew around the opposite side" +msgstr "" +"Nagni izbrano; s Ctrl preskakuj po kotih; s Shift " +"nagiba okrog nasprotne strani" + +#: ../../po/../src/seltrans.cpp:520 +msgid "" +"Rotate selection; with Ctrl to snap angle; with Shift " +"to rotate around the opposite corner" +msgstr "" +"Zavrti izbrano; s Ctrl preskakuj po kotih; s Shift vrti " +"okrog nasprotnega kota" + +#: ../../po/../src/seltrans.cpp:829 ../../po/../src/seltrans.cpp:909 +#, c-format +msgid "Scale: %0.2f%% x %0.2f%%; with Ctrl to lock ratio" +msgstr "Razteguj: %0.2f%% x %0.2f%%; s Ctrl zakleni razmerje" + +#. TRANSLATORS: don't modify the first ";" (it will NOT be displayed as ";" - only the second one will be) +#: ../../po/../src/seltrans.cpp:984 +#, c-format +msgid "Skew: %0.2f°; with Ctrl to snap angle" +msgstr "Nagni: %0.2f°; s Ctrl preskakuj po kotih " + +#. TRANSLATORS: don't modify the first ";" (it will NOT be displayed as ";" - only the second one will be) +#: ../../po/../src/seltrans.cpp:1035 +#, c-format +msgid "Rotate: %0.2f°; with Ctrl to snap angle" +msgstr "Zavrti: %0.2f stopinj;s Ctrl preskakuj po kotih " + +#: ../../po/../src/seltrans.cpp:1090 +#, c-format +msgid "Move center to %s, %s" +msgstr "Premakni središče na %s, %s" + +#: ../../po/../src/slideshow.cpp:90 +msgid "Inkscape slideshow" +msgstr "Inkscape projekcija" + +#: ../../po/../src/sp-anchor.cpp:181 +#, c-format +msgid "Link to %s" +msgstr "Povezava do %s" + +#: ../../po/../src/sp-anchor.cpp:185 +msgid "Link without URI" +msgstr "Povezava brez URI (naslova)" + +#: ../../po/../src/sp-ellipse.cpp:438 ../../po/../src/sp-ellipse.cpp:870 +msgid "Ellipse" +msgstr "Elipsa" + +#: ../../po/../src/sp-ellipse.cpp:583 +msgid "Circle" +msgstr "Krog" + +#: ../../po/../src/sp-ellipse.cpp:865 +msgid "Segment" +msgstr "Odsek" + +#: ../../po/../src/sp-ellipse.cpp:867 +msgid "Arc" +msgstr "Lok" + +#. TRANSLATORS: "Flow region" is an area where text is allowed to flow +#: ../../po/../src/sp-flowregion.cpp:276 +msgid "Flow region" +msgstr "Tekoče območje" + +#. TRANSLATORS: A region "cut out of" a flow region; text is not allowed to flow inside the +#. * flow excluded region. flowRegionExclude in SVG 1.2: see +#. * http://www.w3.org/TR/2004/WD-SVG12-20041027/flow.html#flowRegion-elem and +#. * http://www.w3.org/TR/2004/WD-SVG12-20041027/flow.html#flowRegionExclude-elem. +#: ../../po/../src/sp-flowregion.cpp:493 +msgid "Flow excluded region" +msgstr "Izključi tekoči odsek" + +#: ../../po/../src/sp-flowtext.cpp:355 +#, c-format +msgid "Flowed text (%d characters)" +msgstr "Tekoče besedilo (%d znakov)" + +#: ../../po/../src/sp-flowtext.cpp:357 +#, c-format +msgid "Linked flowed text (%d characters)" +msgstr "Povezano tekoče besedilo (%d znakov)" + +#: ../../po/../src/sp-guide.cpp:290 +msgid "vertical guideline" +msgstr "navpično vodilo" + +#: ../../po/../src/sp-guide.cpp:292 +msgid "horizontal guideline" +msgstr "vodoravno vodilo" + +#: ../../po/../src/sp-image.cpp:835 +msgid "embedded" +msgstr "vključeno" + +#: ../../po/../src/sp-image.cpp:839 +msgid "(null_pointer)" +msgstr "(null_pointer)" + +#: ../../po/../src/sp-image.cpp:843 +#, c-format +msgid "Image with bad reference: %s" +msgstr "Slika s slabo povezavo: %s" + +#: ../../po/../src/sp-image.cpp:844 +#, c-format +msgid "Image %d × %d: %s" +msgstr "Slika %d × %d: %s" + +#: ../../po/../src/sp-item-group.cpp:390 +#, c-format +msgid "Group of %d object" +msgid_plural "Group of %d objects" +msgstr[0] "Skupina %d predmetov" +msgstr[1] "Skupina %d predmeta" +msgstr[2] "Skupina %d predmetov" +msgstr[3] "Skupina %d predmetov" + +#: ../../po/../src/sp-item.cpp:720 +msgid "Object" +msgstr "Predmet" + +#: ../../po/../src/sp-line.cpp:202 +msgid "Line" +msgstr "Črta" + +#. TRANSLATORS COMMENT: %s is either "outset" or "inset" depending on sign +#: ../../po/../src/sp-offset.cpp:433 +#, c-format +msgid "Linked offset, %s by %f pt" +msgstr "Dinamičen odmik, %s za %f točk " + +#: ../../po/../src/sp-offset.cpp:434 ../../po/../src/sp-offset.cpp:438 +msgid "outset" +msgstr "razÅ¡iri" + +#: ../../po/../src/sp-offset.cpp:434 ../../po/../src/sp-offset.cpp:438 +msgid "inset" +msgstr "zožaj" + +#. TRANSLATORS COMMENT: %s is either "outset" or "inset" depending on sign +#: ../../po/../src/sp-offset.cpp:437 +#, c-format +msgid "Dynamic offset, %s by %f pt" +msgstr "Dinamičen odmik, %s za %f točk" + +#: ../../po/../src/sp-path.cpp:127 +#, c-format +msgid "Path (%i node)" +msgid_plural "Path (%i nodes)" +msgstr[0] "Pot (%i vozlišč)" +msgstr[1] "Pot (%i vozlišče)" +msgstr[2] "Pot (%i vozlišči)" +msgstr[3] "Pot (%i vozlišča)" + +#: ../../po/../src/sp-polygon.cpp:216 +msgid "Polygon" +msgstr "Mnogokotnik" + +#: ../../po/../src/sp-polyline.cpp:179 +msgid "Polyline" +msgstr "Lomljena črta" + +#: ../../po/../src/sp-rect.cpp:250 +msgid "Rectangle" +msgstr "Pravokotnik" + +#. TRANSLATORS: since turn count isn't an integer, please adjust the +#. string as needed to deal with an localized plural forms. +#: ../../po/../src/sp-spiral.cpp:305 +#, c-format +msgid "Spiral with %3f turns" +msgstr "Spiralas %3f zavoji" + +#: ../../po/../src/sp-star.cpp:288 +#, c-format +msgid "Star with %d vertex" +msgid_plural "Star with %d vertices" +msgstr[0] "Zvezda s %d kraki" +msgstr[1] "Zvezda s %d krakom" +msgstr[2] "Zvezda s %d krakoma" +msgstr[3] "Zvezda s %d kraki" + +#: ../../po/../src/sp-star.cpp:292 +#, c-format +msgid "Polygon with %d vertex" +msgid_plural "Polygon with %d vertices" +msgstr[0] "Mnogokotnik s/z %d oglišči" +msgstr[1] "Mnogokotnik s/z %d ogliščem" +msgstr[2] "Mnogokotnik s/z %d ogliščema" +msgstr[3] "Mnogokotnik s/z %d oglišči" + +#. TRANSLATORS: For description of font with no name. +#: ../../po/../src/sp-text.cpp:420 +msgid "<no name found>" +msgstr "<ne najdem imena>" + +#: ../../po/../src/sp-text.cpp:426 +#, c-format +msgid "Text on path (%s, %s)" +msgstr "Besedilo po poti (%s, %s)" + +#: ../../po/../src/sp-text.cpp:427 +#, c-format +msgid "Text (%s, %s)" +msgstr "Besedilo (%s, %s)" + +#. TRANSLATORS: Used for statusbar description for long chains: +#. * "Clone of: Clone of: ... in Layer 1". +#: ../../po/../src/sp-use.cpp:317 +msgid "..." +msgstr "..." + +#: ../../po/../src/sp-use.cpp:325 +#, c-format +msgid "Clone of: %s" +msgstr "Klon predmeta %s" + +#: ../../po/../src/sp-use.cpp:329 +msgid "Orphaned clone" +msgstr "Klon-sirota" + +#: ../../po/../src/spiral-context.cpp:355 +msgid "Ctrl: snap angle" +msgstr "Ctrl: preskakuj po kotih" + +#: ../../po/../src/spiral-context.cpp:357 +msgid "Alt: lock spiral radius" +msgstr "Alt: zakleni polmer spirale" + +#: ../../po/../src/spiral-context.cpp:469 +#, c-format +msgid "" +"Spiral: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" +"Spirala: polmer %s, kot %5g°; s Ctrl preskakujete po kotih" + +#: ../../po/../src/splivarot.cpp:106 +msgid "Select at least 2 paths to perform a boolean operation." +msgstr "Za logične operacije izberite vsaj dve poti." + +#: ../../po/../src/splivarot.cpp:112 +msgid "" +"Select exactly 2 paths to perform difference, XOR, division, or path " +"cut." +msgstr "" +"Za dejanje razlike, ALI, radelitve ali razreza izberite natanko dve poti." + +#: ../../po/../src/splivarot.cpp:129 ../../po/../src/splivarot.cpp:144 +msgid "" +"Unable to determine the z-order of the objects selected for " +"difference, XOR, division, or path cut." +msgstr "" +"Ne morem prepoznati prekrivanja predmetov izbranih za razliko, ALI, " +"delitev ali razrez poti." + +#: ../../po/../src/splivarot.cpp:174 +msgid "" +"One of the objects is not a path, cannot perform boolean operation." +msgstr "Ne morem napraviti logične operacije, ker en predmet ni pot." + +#. TRANSLATORS: "to outline" means "to convert stroke to path" +#: ../../po/../src/splivarot.cpp:554 +msgid "Select path(s) to outline." +msgstr "Izberite pot(i) za obris." + +#. TRANSLATORS: "to outline" means "to convert stroke to path" +#: ../../po/../src/splivarot.cpp:748 +msgid "No stroked paths to outline in the selection." +msgstr "Med izbiro ni poteznih poti, ki bi jih lahko obrisal." + +#: ../../po/../src/splivarot.cpp:832 +msgid "Selected object is not a path, cannot inset/outset." +msgstr "Ne morem razÅ¡iriti ali zožati, ker izbran predmet ni pot." + +#: ../../po/../src/splivarot.cpp:1040 +msgid "Select path(s) to inset/outset." +msgstr "Izberite pot(i) za razÅ¡irjanje/zožanje." + +#: ../../po/../src/splivarot.cpp:1257 +msgid "No paths to inset/outset in the selection." +msgstr "Med izbiro ni poti, ki bi jih lahko razÅ¡iril ali zožal." + +#: ../../po/../src/splivarot.cpp:1390 +msgid "Select path(s) to simplify." +msgstr "Izberite pot(i) za poenostavljanje." + +#: ../../po/../src/splivarot.cpp:1417 +msgid "No paths to simplify in the selection." +msgstr "Med izbiro ni poti, ki bi jih lahko poenostavil." + +#: ../../po/../src/star-context.cpp:362 +msgid "Ctrl: snap angle; keep rays radial" +msgstr "Ctrl: preskakuj po kotih; obdrži radialne žarke" + +#: ../../po/../src/star-context.cpp:470 +#, c-format +msgid "" +"Polygon: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" +"Mnogokotnik: polmer %s, kot %5g°; s Ctrl preskakujete po " +"kotih" + +#: ../../po/../src/star-context.cpp:471 +#, c-format +msgid "Star: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" +"Zvezda: polmer %s, kot %5g°; s Ctrl preskakujete po kotih" + +#: ../../po/../src/text-chemistry.cpp:90 +msgid "Select a text and a path to put text on path." +msgstr "Da položite besedilo na pot izberite besedilo in pot." + +#: ../../po/../src/text-chemistry.cpp:95 +msgid "" +"This text object is already put to a path. Remove it from the path " +"first. Use Shift+D to look up its path." +msgstr "" +"To besedilo je že položeno na pot. Najprej ga odstranite. Uporabite " +"Shift+D, da poiščete njegovo pot." + +#. rect is the only SPShape which is not yet, and thus SVG forbids us from putting text on it +#: ../../po/../src/text-chemistry.cpp:101 +msgid "" +"You cannot put text on a rectangle in this version. Convert rectangle to " +"path first." +msgstr "" +"V tej različici ne morete spustiti besedila v pravokotnik. Najprej ga " +"pretvorite v pot." + +#: ../../po/../src/text-chemistry.cpp:159 +msgid "Select a text on path to remove it from path." +msgstr "Da snamete besedilo s poti izberite besedilo na poti." + +#: ../../po/../src/text-chemistry.cpp:181 +msgid "No texts-on-paths in the selection." +msgstr "V izbiri ni besedil na poti, ki bi jih lahko obrnil." + +#: ../../po/../src/text-chemistry.cpp:209 +#: ../../po/../src/text-chemistry.cpp:229 +msgid "Select text(s) to remove kerns from." +msgstr "Izberite besedila za odstranitev zgoščevanj." + +#: ../../po/../src/text-chemistry.cpp:250 +msgid "" +"Select a text and one or more paths or shapes to flow text " +"into frame." +msgstr "" +"Da položite besedilo na pot izberite besedilo in eno ali več poti " +"ali oblik." + +#: ../../po/../src/text-chemistry.cpp:322 +msgid "Select a flowed text to unflow it." +msgstr "Izberite tekoče besedilo, ki naj se prekliče." + +#: ../../po/../src/text-context.cpp:463 +msgid "Click to edit the text, drag to select part of the text." +msgstr "" +"Kliknite da uredite besedilo, povlecite da izberete del " +"besedila" + +#: ../../po/../src/text-context.cpp:465 +msgid "" +"Click to edit the flowed text, drag to select part of the text." +msgstr "" +"Kliknite za urejanje tekočega besedila, povlecite da izberete " +"del besedila." + +#: ../../po/../src/text-context.cpp:540 +msgid "Non-printable character" +msgstr "Neizpisljiva črka" + +#: ../../po/../src/text-context.cpp:589 +#, c-format +msgid "Unicode: %s: %s" +msgstr "Unicode: %s: %s" + +#: ../../po/../src/text-context.cpp:591 ../../po/../src/text-context.cpp:855 +msgid "Unicode: " +msgstr "Unicode: " + +#: ../../po/../src/text-context.cpp:615 +msgid "Current layer is hidden. Unhide it to be able to add text." +msgstr "" +"Trenutni sloj je skrit. Če želite dodajati besedilo ga odkrijte." + +#: ../../po/../src/text-context.cpp:619 +msgid "Current layer is locked. Unlock it to be able to add text." +msgstr "" +"Trenutni sloj je zaklenjen. Če želite dodajati besedilo ga odkrijte." + +#: ../../po/../src/text-context.cpp:673 +#, c-format +msgid "Flowed text frame: %s × %s" +msgstr "Okvir tekočega besedila: %s × %s" + +#: ../../po/../src/text-context.cpp:708 ../../po/../src/text-context.cpp:1464 +msgid "Type text; Enter to start new line." +msgstr "Vnesite besedilo; Enter začne novo vrstico." + +#: ../../po/../src/text-context.cpp:719 +msgid "Flowed text is created." +msgstr "Tekoče besedilo je ustvarjeno." + +#: ../../po/../src/text-context.cpp:722 +msgid "" +"The frame is too small for the current font size. Flowed text not " +"created." +msgstr "" +"Ta okvir je premajhen za trenutno velikost pisave. Tekoče besedilo ni " +"bilo ustvarjeno." + +#: ../../po/../src/text-context.cpp:841 +msgid "No-break space" +msgstr "Presledek brez preloma" + +#: ../../po/../src/text-context.cpp:1462 +msgid "Type flowed text; Enter to start new paragraph." +msgstr "Vnesite tekoče besedilo; Enter začne nov odstavek." + +#: ../../po/../src/text-context.cpp:1472 ../../po/../src/tools-switch.cpp:189 +msgid "" +"Click to select or create text, drag to create flowed text; " +"then type." +msgstr "" +"Pritisnite z miÅ¡ko, da izberete ali ustvarite tekoče besedilo, nato " +"lahko piÅ¡ete." + +#: ../../po/../src/tools-switch.cpp:141 +msgid "" +"To edit a path, click, Shift+click, or drag around " +"nodes to select them, then drag nodes and handles. Click on an " +"object to select." +msgstr "" +"Za urejanje poti: pritisk miÅ¡ke, Shift+miÅ¡ka ali poteg " +"okrog vozlišč za izbiro, nato, za urejanje oblike, povlecite " +"ročice. Pritisk miÅ¡ke na predmet za izbiro." + +#: ../../po/../src/tools-switch.cpp:147 +msgid "" +"Drag to create a rectangle. Drag controls to round corners and " +"resize. Click to select." +msgstr "" +"Povlecite in ustvarite pravokotnik. Povlecite vozlišča, da " +"zaobljte kote ali spremenite velikost. Pritisk miÅ¡ke za izbiro." + +#: ../../po/../src/tools-switch.cpp:153 +msgid "" +"Drag to create an ellipse. Drag controls to make an arc or " +"segment. Click to select." +msgstr "" +"Povlecite in nariÅ¡ite elipso. Povlecite vozlišča, da naredite " +"lok ali odsek. Pritisk miÅ¡ke za izbiro." + +#: ../../po/../src/tools-switch.cpp:159 +msgid "" +"Drag to create a star. Drag controls to edit the star shape. " +"Click to select." +msgstr "" +"Povlecite da nariÅ¡ete zvezdo. Povlecite vozlišča, da ji " +"spremenite obliko. Pritisk miÅ¡ke za izbiro." + +#: ../../po/../src/tools-switch.cpp:165 +msgid "" +"Drag to create a spiral. Drag controls to edit the spiral " +"shape. Click to select." +msgstr "" +"Povlecite da nariÅ¡ete spiralo. Povlecite vozlišča, da ji " +"spremenite obliko. Pritisk miÅ¡ke za izbiro." + +#: ../../po/../src/tools-switch.cpp:171 +msgid "" +"Drag to create a freehand line. Start drawing with Shift to " +"append to selected path." +msgstr "" +"Povlecite in nariÅ¡ite prostoročno črto. Začnite s Shift za " +"dodajanje k izbrani poti." + +#: ../../po/../src/tools-switch.cpp:177 +#, fuzzy +msgid "" +"Click or click and drag to start a path; with Shift to " +"append to selected path." +msgstr "" +"Pritisnite z miÅ¡ko, da ustvarite vozlišče, pritisnite in vlecite da ustvarite zmehčano vozlišče. Začnite s Shift, za dodajanje k " +"izbrani poti." + +#: ../../po/../src/tools-switch.cpp:183 +msgid "" +"Drag to paint a calligraphic stroke. Left/right arrow " +"keys adjust width, up/down adjust angle." +msgstr "" +"Povlecite da ustvarite kaligrafsko potezo. Tipki levo " +"desno spreminjajo Å¡irino, gor dol pa kot nagiba peresa." + +#: ../../po/../src/tools-switch.cpp:195 +msgid "" +"Drag or double click to create a gradient on selected objects, " +"drag handles to adjust gradients." +msgstr "" +"Povlecite z miÅ¡ko ali dvojno kliknite, da na izbranih " +"predmetih ustvarite preliv, povlecite ročice za prilagoditev preliva." + +#: ../../po/../src/tools-switch.cpp:201 +msgid "" +"Click or drag around an area to zoom in, Shift+click to " +"zoom out." +msgstr "" +"Pritisnite z miÅ¡ko za povečavo, Shift+pritisk za pomanjÅ¡anje, " +"povlecite okrog območja za povečavo." + +#: ../../po/../src/tools-switch.cpp:213 +msgid "Click and drag between shapes to create a connector." +msgstr "" + +#: ../../po/../src/trace/potrace/inkscape-potrace.cpp:553 +#: ../../po/../src/trace/potrace/inkscape-potrace.cpp:654 +#, c-format +msgid "Trace: %d. %ld nodes" +msgstr "PreriÅ¡i: %d. %ld vozlišč" + +#: ../../po/../src/trace/trace.cpp:53 ../../po/../src/trace/trace.cpp:62 +#: ../../po/../src/trace/trace.cpp:70 +msgid "Select an image to trace" +msgstr "Izberite sliko za prerisanje" + +#: ../../po/../src/trace/trace.cpp:133 +msgid "Trace: No active document" +msgstr "Prerisanje: Ni aktivnega dokumenta" + +#: ../../po/../src/trace/trace.cpp:154 +msgid "Trace: Image has no bitmap data" +msgstr "Prerisanje: V sliki ni rasterskih podatkov" + +#: ../../po/../src/trace/trace.cpp:267 +#, c-format +msgid "Trace: Done. %ld nodes created" +msgstr "PrerirÅ¡i: opravljeno. ustvarjenih %ld vozlišč" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:59 ../../po/../src/verbs.cpp:2212 +msgid "About Inkscape" +msgstr "O programu Inkscape" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:66 +msgid "_Splash" +msgstr "" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:68 +msgid "_Authors" +msgstr "" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:69 +#, fuzzy +msgid "_Translators" +msgstr "Preoblikovanja" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:70 +#, fuzzy +msgid "_License" +msgstr "Licenca" + +#. TRANSLATORS: This is the filename of the `About Inkscape' picture in +#. the `screens' directory. Thus the translation of "about.svg" should be +#. the filename of its translated version, e.g. about.zh.svg for Chinese. +#. +#. N.B. about.svg changes once per release. (We should probably rename +#. the original to about-0.40.svg etc. as soon as we have a translation. +#. If we do so, then add an item to release-checklist saying that the +#. string here should be changed.) +#. FIXME? INKSCAPE_SCREENSDIR and "about.svg" are in UTF-8, not the +#. native filename encoding... and the filename passed to sp_document_new +#. should be in UTF-*8.. +#: ../../po/../src/ui/dialog/aboutbox.cpp:114 +msgid "about.svg" +msgstr "about.svg" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:464 +msgid "Minimum horizontal gap (in px units) between bounding boxes" +msgstr "" + +#. TRANSLATORS: Horizontal gap +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:466 +#: ../../po/../src/widgets/toolbox.cpp:1556 +msgid "H:" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:474 +msgid "Minimum vertical gap (in px units) between bounding boxes" +msgstr "" + +#. TRANSLATORS: Vertical gap +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:476 +msgid "V:" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:734 +msgid "Align" +msgstr "Poravnava" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:735 +msgid "Distribute" +msgstr "Porazdeli" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:736 +msgid "Remove overlaps" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:737 +msgid "Nodes" +msgstr "Vozlišča" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:742 +msgid "Relative to: " +msgstr "Relativno na: " + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:747 +msgid "Align right sides of objects to left side of anchor" +msgstr "Desni rob predmetov poravnaj na levi rob sidra" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:750 +msgid "Align left sides" +msgstr "Poravnaj leve strani" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:753 +msgid "Center on vertical axis" +msgstr "Poravnaj na sredino navpične osi" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:756 +msgid "Align right sides" +msgstr "Poravnaj desne strani" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:759 +msgid "Align left sides of objects to right side of anchor" +msgstr "Levi rob predmetov poravnaj na desni rob sidra" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:762 +msgid "Align bottoms of objects to top of anchor" +msgstr "Dno predmetov poravnaj na vrh sidra" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:765 +msgid "Align tops" +msgstr "Poravnaj vrhove" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:768 +msgid "Center on horizontal axis" +msgstr "Poravnaj na sredino vodoravne osi" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:771 +msgid "Align bottoms" +msgstr "Poravnaj dna" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:774 +msgid "Align tops of objects to bottom of anchor" +msgstr "Vrh predmetov poravnaj na dno sidra" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:779 +msgid "Align baseline anchors of texts vertically" +msgstr "Navpično poravnaj osnovna sidra besedila" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:782 +msgid "Align baseline anchors of texts horizontally" +msgstr "Vodoravno poravnaj osnovna sidra besedila" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:787 +msgid "Make horizontal gaps between objects equal" +msgstr "Enakomerno raporedi vodoravne razdalje med predmeti" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:791 +msgid "Distribute left sides equidistantly" +msgstr "Enakomerno razporedi leve robove predmetov" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:794 +msgid "Distribute centers equidistantly horizontally" +msgstr "Enakomerno vodoravno razporedi središča predmetov" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:797 +msgid "Distribute right sides equidistantly" +msgstr "Enakomerno razporedi desne robove predmetov" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:801 +msgid "Make vertical gaps between objects equal" +msgstr "Enakomerno razporedi navpične razmake med predmeti" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:805 +msgid "Distribute tops equidistantly" +msgstr "Enakomerno razporedi zgornje robove predmetov" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:808 +msgid "Distribute centers equidistantly vertically" +msgstr "Enakomerno navpično razporedi središča predmetov" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:811 +msgid "Distribute bottoms equidistantly" +msgstr "Enakomerno razporedi spodnje robove predmetov" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:816 +msgid "Distribute baseline anchors of texts horizontally" +msgstr "Vodoravno razporedi osnovna sidra besedila" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:819 +msgid "Distribute baseline anchors of texts vertically" +msgstr "Navpično razporedi osnovna sidra besedila" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:824 +msgid "Randomize centers in both dimensions" +msgstr "Razporedi središča naključno v obeh smereh" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:827 +msgid "Unclump objects: try to equalize edge-to-edge distances" +msgstr "Ravnaj predmete: poskuÅ¡aj poenotiti razdalje med robovi" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:832 +msgid "" +"Move objects as little as possible so that their bounding boxes do not " +"overlap" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:837 +msgid "Align selected nodes horizontally" +msgstr "Vodoravno poravnaj izbrana vozlišča" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:840 +msgid "Align selected nodes vertically" +msgstr "Navpično poravnaj izbrana vozlišča" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:843 +msgid "Distribute selected nodes horizontally" +msgstr "Vodoravno razporedi izbrana vozlišča" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:846 +msgid "Distribute selected nodes vertically" +msgstr "Navpično razporedi izbrana vozlišča" + +#. Rest of the widgetry +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:851 +msgid "Last selected" +msgstr "Zadnja izbira" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:852 +msgid "First selected" +msgstr "Prva izbira" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:853 +msgid "Biggest item" +msgstr "Največji predmet" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:854 +msgid "Smallest item" +msgstr "NajmanjÅ¡i predmet" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:856 +#: ../../po/../src/widgets/desktop-widget.cpp:1065 +msgid "Drawing" +msgstr "Risanje" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:91 +#, fuzzy +msgid "Metadata 1" +msgstr "Meta podatki" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:92 +#, fuzzy +msgid "Metadata 2" +msgstr "Meta podatki" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:187 +#, fuzzy +msgid "X coordinate of grid origin" +msgstr "Navpična koordinata izbire" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:189 +#, fuzzy +msgid "Y coordinate of grid origin" +msgstr "Navpična koordinata izbire" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:191 +#, fuzzy +msgid "Distance of vertical grid lines" +msgstr "navpično vodilo" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:193 +#, fuzzy +msgid "Distance of horizontal grid lines" +msgstr "vodoravno vodilo" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:197 +msgid "Max. snapping distance from grid" +msgstr "" + +#: ../../po/../src/ui/dialog/export.cpp:34 +msgid "Export" +msgstr "Izvozi" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:36 +msgid "Fill" +msgstr "Zapolni" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:37 +msgid "Stroke Paint" +msgstr "Barva črte" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:38 +msgid "Stroke Style" +msgstr "Slog črte" + +#: ../../po/../src/ui/dialog/find.cpp:34 +msgid "Find" +msgstr "Najdi" + +#: ../../po/../src/ui/dialog/memory.cpp:96 +msgid "Heap" +msgstr "Kup" + +#: ../../po/../src/ui/dialog/memory.cpp:97 +msgid "In Use" +msgstr "Uporabljen" + +#. TRANSLATORS: "Slack" refers to memory which is in the heap but currently unused. +#. More typical usage is to call this memory "free" rather than "slack". +#: ../../po/../src/ui/dialog/memory.cpp:100 +msgid "Slack" +msgstr "Slack" + +#: ../../po/../src/ui/dialog/memory.cpp:101 +msgid "Total" +msgstr "Skupaj" + +#: ../../po/../src/ui/dialog/memory.cpp:141 +#: ../../po/../src/ui/dialog/memory.cpp:147 +#: ../../po/../src/ui/dialog/memory.cpp:154 +#: ../../po/../src/ui/dialog/memory.cpp:186 +msgid "Unknown" +msgstr "Neznana" + +#: ../../po/../src/ui/dialog/memory.cpp:167 +msgid "Combined" +msgstr "Združen" + +#: ../../po/../src/ui/dialog/memory.cpp:209 +msgid "Recalculate" +msgstr "Ponovno izračunaj" + +#: ../../po/../src/ui/dialog/messages.cpp:74 +msgid "Ready." +msgstr "Pripravljen." + +#: ../../po/../src/ui/dialog/messages.cpp:75 +msgid "" +"Enable log display by setting dialogs.debug 'redirect' attribute to 1 in " +"preferences.xml" +msgstr "" +"Vključite prikaz beleženja tako, da v preferences.xml nastavite vrednost " +"lastnosti 'preusmeri' na 1" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:184 +msgid "_Execute Python" +msgstr "_Zaženi Python" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:186 +msgid "_Execute Perl" +msgstr "_Zaženi Perl" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:195 +msgid "Script" +msgstr "Skripta" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:205 +msgid "Output" +msgstr "Izvoz" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:215 +msgid "Errors" +msgstr "Napake" + +#. Dialog organization +#: ../../po/../src/ui/dialog/session-player.cpp:73 +msgid "Session file" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:74 +#, fuzzy +msgid "Playback controls" +msgstr "Nadzor orodij" + +#: ../../po/../src/ui/dialog/session-player.cpp:75 +#, fuzzy +msgid "Message information" +msgstr "Odstrani _preoblikovanja" + +#. Active session file display +#. fixme: Does this mean the active file for the session, or the file for the active session? +#. Please indicate which with a TRANSLATORS comment. +#: ../../po/../src/ui/dialog/session-player.cpp:85 +msgid "Active session file:" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:86 +msgid "Delay (milliseconds):" +msgstr "" + +#. Unload/load buttons +#: ../../po/../src/ui/dialog/session-player.cpp:94 +#, fuzzy +msgid "Close file" +msgstr "Zapri" + +#: ../../po/../src/ui/dialog/session-player.cpp:95 +msgid "Open new file" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:96 +#, fuzzy +msgid "Set delay" +msgstr "Naj bo privzeto" + +#: ../../po/../src/ui/dialog/session-player.cpp:138 +#, fuzzy +msgid "Rewind" +msgstr "Rdeča" + +#: ../../po/../src/ui/dialog/session-player.cpp:139 +msgid "Go back one change" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:140 +#, fuzzy +msgid "Pause" +msgstr "Prilepi" + +#: ../../po/../src/ui/dialog/session-player.cpp:141 +msgid "Go forward one change" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:142 +msgid "Play" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:177 +#: ../../po/../src/verbs.cpp:1573 +msgid "Open session file" +msgstr "" + +#. ##Set up the Potrace panel +#. #### brightness #### +#. #### Multiple scanning#### +#. ----Hbox1 +#: ../../po/../src/ui/dialog/tracedialog.cpp:345 +#: ../../po/../src/ui/dialog/tracedialog.cpp:428 +msgid "Brightness" +msgstr "Svetlost" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:348 +msgid "Trace by a given brightness level" +msgstr "PreriÅ¡i glede na stopnjo svetlost" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:355 +msgid "Brightness cutoff for black/white" +msgstr "Obrez svetlosti glede na belo/črno" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:362 +msgid "Image Brightness" +msgstr "Svetlost slike" + +#. #### canny edge detection #### +#. TRANSLATORS: "Canny" is the name of the inventor of this edge detection method +#: ../../po/../src/ui/dialog/tracedialog.cpp:369 +msgid "Optimal Edge Detection (Canny)" +msgstr "Optimalno zaznavanje robu (Canny)" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:372 +msgid "Trace with edge detection by J. Canny's algorithm" +msgstr "Prerisuj z iskanjem robov po metodi J. Canny" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:388 +msgid "Brightness cutoff for adjacent pixels (determines edge thickness)" +msgstr "Obrez svetlosti sosednjih točk (debelina robov)" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:395 +msgid "Edge Detection" +msgstr "Zaznavanje robu" + +#. #### quantization #### +#. TRANSLATORS: Color Quantization: the process of reducing the number of colors +#. in an image by selecting an optimized set of representative colors and then +#. re-applying this reduced set to the original image. +#: ../../po/../src/ui/dialog/tracedialog.cpp:404 +msgid "Color Quantization" +msgstr "Kvantizacija barve" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:407 +msgid "Trace along the boundaries of reduced colors" +msgstr "Prerisuj po robovih omejenih barv" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:414 +msgid "The number of reduced colors" +msgstr "Å tevilo omejenih barv" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:416 +msgid "Colors:" +msgstr "Barve:" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:421 +msgid "Quantization / Reduction" +msgstr "Kvantizacija / redukcija" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:431 +msgid "Trace the given number of brightness levels" +msgstr "PreriÅ¡i dano Å¡tevilo svetlostnih stopenj" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:438 +msgid "Scans:" +msgstr "Pregledi:" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:440 +msgid "The desired number of scans" +msgstr "Željeno Å¡tevilo pregledov" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:448 +msgid "Trace the given number of reduced colors" +msgstr "PreriÅ¡i dano Å¡tevilo omejenih barv" + +#. ---Hbox3 +#: ../../po/../src/ui/dialog/tracedialog.cpp:454 +msgid "Monochrome" +msgstr "Črno belo" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:457 +msgid "Same as Color, but convert result to grayscale" +msgstr "Enako kot 'Barvno', le izhod se pretvori v sivine" + +#. TRANSLATORS: "Stack" is a verb here +#: ../../po/../src/ui/dialog/tracedialog.cpp:460 +msgid "Stack" +msgstr "Sklad" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:463 +msgid "" +"Stack scans vertically (no gaps) or tile horizontally (usually with gaps)" +msgstr "" +"Preglede zlagaj navpično (brez presledkov) ali tlakuj vodoravno (običajno s " +"presledki)" + +#. TRANSLATORS: "Smooth" is a verb here +#: ../../po/../src/ui/dialog/tracedialog.cpp:466 +msgid "Smooth" +msgstr "Gladka" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:469 +msgid "Apply Gaussian blur to the bitmap before tracing" +msgstr "Opravi Gaussian mehčanje pred prerisovanjem" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:473 +msgid "Multiple Scanning" +msgstr "Večkratno pregledovanje" + +#. #### Preview #### +#: ../../po/../src/ui/dialog/tracedialog.cpp:479 +#: ../../po/../src/ui/dialog/tracedialog.cpp:489 +msgid "Preview" +msgstr "Predogled" + +#. do not expand +#: ../../po/../src/ui/dialog/tracedialog.cpp:483 +msgid "Preview the result without actual tracing" +msgstr "Predogled rezultata" + +#. #### swap black and white #### +#: ../../po/../src/ui/dialog/tracedialog.cpp:495 +msgid "Invert" +msgstr "Zaobrni" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:499 +msgid "Invert black and white regions for single traces" +msgstr "Zaobrni črne in bele dele za enojne preglede" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:503 +msgid "Thanks to Peter Selinger, http://potrace.sourceforge.net" +msgstr "Zahvala: Peter Selinger, http://potrace.sourceforge.net" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:506 +msgid "Credits" +msgstr "Zahvale" + +#. done +#. TRANSLATORS: Potrace is an application for transforming bitmaps into +#. vector graphics (http://potrace.sourceforge.net/) +#: ../../po/../src/ui/dialog/tracedialog.cpp:514 +msgid "Potrace" +msgstr "Potrace" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:527 +msgid "Abort a trace in progress" +msgstr "Prekliči trenutno prerisovanje" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:531 +msgid "Execute the trace" +msgstr "PreriÅ¡i!" + +#: ../../po/../src/ui/dialog/transformation.cpp:80 +#: ../../po/../src/ui/dialog/transformation.cpp:90 +#, fuzzy +msgid "_Horizontal" +msgstr "Vodoravno" + +#: ../../po/../src/ui/dialog/transformation.cpp:80 +msgid "Horizontal displacement (relative) or position (absolute)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:82 +#: ../../po/../src/ui/dialog/transformation.cpp:92 +#, fuzzy +msgid "_Vertical" +msgstr "Navpično" + +#: ../../po/../src/ui/dialog/transformation.cpp:82 +msgid "Vertical displacement (relative) or position (absolute)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:84 +#, fuzzy +msgid "_Width" +msgstr "_Å irina:" + +#: ../../po/../src/ui/dialog/transformation.cpp:84 +msgid "Horizontal size increment (absolute or percentage)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:86 +#, fuzzy +msgid "_Height" +msgstr "ViÅ¡ina" + +#: ../../po/../src/ui/dialog/transformation.cpp:86 +msgid "Vertical size increment (absolute or percentage)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:88 +#, fuzzy +msgid "A_ngle" +msgstr "Kot:" + +#: ../../po/../src/ui/dialog/transformation.cpp:88 +#, fuzzy +msgid "Rotation angle (positive = counterclockwise)" +msgstr "Zavrti izbrano za 90 stopinj nasprotno SUK" + +#: ../../po/../src/ui/dialog/transformation.cpp:90 +msgid "" +"Horizontal skew angle (positive = counterclockwise), or absolute " +"displacement, or percentage displacement" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:92 +msgid "" +"Vertical skew angle (positive = counterclockwise), or absolute displacement, " +"or percentage displacement" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:95 +#, fuzzy +msgid "Transformation matrix element A" +msgstr "Nastavitve preoblikovanja" + +#: ../../po/../src/ui/dialog/transformation.cpp:96 +#, fuzzy +msgid "Transformation matrix element B" +msgstr "Nastavitve preoblikovanja" + +#: ../../po/../src/ui/dialog/transformation.cpp:97 +#, fuzzy +msgid "Transformation matrix element C" +msgstr "Nastavitve preoblikovanja" + +#: ../../po/../src/ui/dialog/transformation.cpp:98 +#, fuzzy +msgid "Transformation matrix element D" +msgstr "Nastavitve preoblikovanja" + +#: ../../po/../src/ui/dialog/transformation.cpp:99 +#, fuzzy +msgid "Transformation matrix element E" +msgstr "Nastavitve preoblikovanja" + +#: ../../po/../src/ui/dialog/transformation.cpp:100 +#, fuzzy +msgid "Transformation matrix element F" +msgstr "Nastavitve preoblikovanja" + +#: ../../po/../src/ui/dialog/transformation.cpp:102 +#, fuzzy +msgid "Rela_tive move" +msgstr "Relativni premik" + +#: ../../po/../src/ui/dialog/transformation.cpp:102 +msgid "" +"Add the specified relative displacement to the current position; otherwise, " +"edit the current absolute position directly" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:103 +msgid "Scale proportionally" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:103 +msgid "Preserve the width/height ratio of the scaled objects" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:104 +msgid "Apply to each _object separately" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:104 +msgid "" +"Apply the scale/rotate/skew to each selected object separately; otherwise, " +"transform the selection as a whole" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:105 +#, fuzzy +msgid "Edit c_urrent matrix" +msgstr "Dvigni trenutni sloj" + +#: ../../po/../src/ui/dialog/transformation.cpp:105 +msgid "" +"Edit the current transform= matrix; otherwise, post-multiply transform= by " +"this matrix" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:115 +#, fuzzy +msgid "_Move" +msgstr "Premakni" + +#: ../../po/../src/ui/dialog/transformation.cpp:118 +#, fuzzy +msgid "_Scale" +msgstr "Spremeni velikost" + +#: ../../po/../src/ui/dialog/transformation.cpp:121 +#, fuzzy +msgid "_Rotate" +msgstr "Zasukaj" + +#: ../../po/../src/ui/dialog/transformation.cpp:124 +#, fuzzy +msgid "Ske_w" +msgstr "Nagib" + +#: ../../po/../src/ui/dialog/transformation.cpp:127 +msgid "Matri_x" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:141 +msgid "Reset the values on the current tab to defaults" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:148 +#, fuzzy +msgid "Apply transformation to selection" +msgstr "Uveljavi preoblikovanje" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:43 +msgid "_Use SSL" +msgstr "" + +#. Construct dialog interface +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:68 +#, fuzzy +msgid "_Server:" +msgstr "_Obratno" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:69 +#, fuzzy +msgid "_Username:" +msgstr "P_reimenuj" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:70 +msgid "_Password:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:71 +msgid "P_ort:" +msgstr "" + +#. Buttons +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:99 +#, fuzzy +msgid "Connect" +msgstr "Kloni" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:126 +msgid "Establishing connection to Jabber server %1 as user %2" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:131 +msgid "Failed to establish connection to Jabber server %1" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:136 +msgid "Authentication failed on Jabber server %1 as %2" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:141 +msgid "SSL initialization failed when connecting to Jabber server %1" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:147 +msgid "Connected to Jabber server %1 as %2" +msgstr "" + +#. Construct labels +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:75 +#, fuzzy +msgid "Chatroom _name:" +msgstr "Ime sloja:" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:76 +msgid "Chatroom _server:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:77 +msgid "Chatroom _password:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:78 +msgid "Chatroom _handle:" +msgstr "" + +#. Button setup and callback registration +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:97 +msgid "Connect to chatroom" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:132 +msgid "Synchronizing with chatroom %1@%2 using the handle %3" +msgstr "" + +#. Construct dialog interface +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:78 +msgid "_User's Jabber ID:" +msgstr "" + +#. Buttons +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:82 +msgid "_Invite user" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:83 +#, fuzzy +msgid "_Cancel" +msgstr "Prekliči" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:94 +msgid "Buddy List" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:170 +msgid "Sending whiteboard invitation to %1" +msgstr "" + +#. FIXME: strings are replaced by placeholders, NOT to be translated until the code is enabled +#. See http://sourceforge.net/mailarchive/message.php?msg_id=11746016 for details +#. File menu +#. Edit menu +#. View menu +#. Layer menu +#. Object menu +#. Path menu +#. add(Gtk::StockItem(CLEANUP, _("PLACEHOLDER, do not translate"))); (using Gtk::Stock::CLEAR) +#. Text menu +#. About menu +#. Tools toolbox +#. Select Tool controls +#. Node Tool controls +#. Calligraphy Tool controls +#. Session playback controls +#: ../../po/../src/ui/stock-items.cpp:34 ../../po/../src/ui/stock-items.cpp:35 +#: ../../po/../src/ui/stock-items.cpp:36 ../../po/../src/ui/stock-items.cpp:37 +#: ../../po/../src/ui/stock-items.cpp:38 ../../po/../src/ui/stock-items.cpp:39 +#: ../../po/../src/ui/stock-items.cpp:40 ../../po/../src/ui/stock-items.cpp:41 +#: ../../po/../src/ui/stock-items.cpp:42 ../../po/../src/ui/stock-items.cpp:43 +#: ../../po/../src/ui/stock-items.cpp:46 ../../po/../src/ui/stock-items.cpp:47 +#: ../../po/../src/ui/stock-items.cpp:48 ../../po/../src/ui/stock-items.cpp:49 +#: ../../po/../src/ui/stock-items.cpp:50 ../../po/../src/ui/stock-items.cpp:51 +#: ../../po/../src/ui/stock-items.cpp:52 ../../po/../src/ui/stock-items.cpp:53 +#: ../../po/../src/ui/stock-items.cpp:54 ../../po/../src/ui/stock-items.cpp:55 +#: ../../po/../src/ui/stock-items.cpp:56 ../../po/../src/ui/stock-items.cpp:57 +#: ../../po/../src/ui/stock-items.cpp:58 ../../po/../src/ui/stock-items.cpp:59 +#: ../../po/../src/ui/stock-items.cpp:62 ../../po/../src/ui/stock-items.cpp:63 +#: ../../po/../src/ui/stock-items.cpp:64 ../../po/../src/ui/stock-items.cpp:65 +#: ../../po/../src/ui/stock-items.cpp:66 ../../po/../src/ui/stock-items.cpp:67 +#: ../../po/../src/ui/stock-items.cpp:68 ../../po/../src/ui/stock-items.cpp:69 +#: ../../po/../src/ui/stock-items.cpp:70 ../../po/../src/ui/stock-items.cpp:71 +#: ../../po/../src/ui/stock-items.cpp:72 ../../po/../src/ui/stock-items.cpp:73 +#: ../../po/../src/ui/stock-items.cpp:74 ../../po/../src/ui/stock-items.cpp:75 +#: ../../po/../src/ui/stock-items.cpp:76 ../../po/../src/ui/stock-items.cpp:77 +#: ../../po/../src/ui/stock-items.cpp:78 ../../po/../src/ui/stock-items.cpp:79 +#: ../../po/../src/ui/stock-items.cpp:80 ../../po/../src/ui/stock-items.cpp:81 +#: ../../po/../src/ui/stock-items.cpp:82 ../../po/../src/ui/stock-items.cpp:83 +#: ../../po/../src/ui/stock-items.cpp:84 ../../po/../src/ui/stock-items.cpp:85 +#: ../../po/../src/ui/stock-items.cpp:86 ../../po/../src/ui/stock-items.cpp:87 +#: ../../po/../src/ui/stock-items.cpp:88 ../../po/../src/ui/stock-items.cpp:89 +#: ../../po/../src/ui/stock-items.cpp:92 ../../po/../src/ui/stock-items.cpp:93 +#: ../../po/../src/ui/stock-items.cpp:94 ../../po/../src/ui/stock-items.cpp:95 +#: ../../po/../src/ui/stock-items.cpp:96 ../../po/../src/ui/stock-items.cpp:97 +#: ../../po/../src/ui/stock-items.cpp:98 ../../po/../src/ui/stock-items.cpp:99 +#: ../../po/../src/ui/stock-items.cpp:100 +#: ../../po/../src/ui/stock-items.cpp:101 +#: ../../po/../src/ui/stock-items.cpp:102 +#: ../../po/../src/ui/stock-items.cpp:103 +#: ../../po/../src/ui/stock-items.cpp:104 +#: ../../po/../src/ui/stock-items.cpp:105 +#: ../../po/../src/ui/stock-items.cpp:108 +#: ../../po/../src/ui/stock-items.cpp:109 +#: ../../po/../src/ui/stock-items.cpp:110 +#: ../../po/../src/ui/stock-items.cpp:111 +#: ../../po/../src/ui/stock-items.cpp:112 +#: ../../po/../src/ui/stock-items.cpp:113 +#: ../../po/../src/ui/stock-items.cpp:114 +#: ../../po/../src/ui/stock-items.cpp:115 +#: ../../po/../src/ui/stock-items.cpp:116 +#: ../../po/../src/ui/stock-items.cpp:117 +#: ../../po/../src/ui/stock-items.cpp:118 +#: ../../po/../src/ui/stock-items.cpp:119 +#: ../../po/../src/ui/stock-items.cpp:120 +#: ../../po/../src/ui/stock-items.cpp:121 +#: ../../po/../src/ui/stock-items.cpp:122 +#: ../../po/../src/ui/stock-items.cpp:123 +#: ../../po/../src/ui/stock-items.cpp:124 +#: ../../po/../src/ui/stock-items.cpp:125 +#: ../../po/../src/ui/stock-items.cpp:126 +#: ../../po/../src/ui/stock-items.cpp:127 +#: ../../po/../src/ui/stock-items.cpp:130 +#: ../../po/../src/ui/stock-items.cpp:131 +#: ../../po/../src/ui/stock-items.cpp:132 +#: ../../po/../src/ui/stock-items.cpp:133 +#: ../../po/../src/ui/stock-items.cpp:134 +#: ../../po/../src/ui/stock-items.cpp:135 +#: ../../po/../src/ui/stock-items.cpp:136 +#: ../../po/../src/ui/stock-items.cpp:137 +#: ../../po/../src/ui/stock-items.cpp:138 +#: ../../po/../src/ui/stock-items.cpp:139 +#: ../../po/../src/ui/stock-items.cpp:140 +#: ../../po/../src/ui/stock-items.cpp:141 +#: ../../po/../src/ui/stock-items.cpp:142 +#: ../../po/../src/ui/stock-items.cpp:143 +#: ../../po/../src/ui/stock-items.cpp:144 +#: ../../po/../src/ui/stock-items.cpp:145 +#: ../../po/../src/ui/stock-items.cpp:146 +#: ../../po/../src/ui/stock-items.cpp:150 +#: ../../po/../src/ui/stock-items.cpp:151 +#: ../../po/../src/ui/stock-items.cpp:152 +#: ../../po/../src/ui/stock-items.cpp:153 +#: ../../po/../src/ui/stock-items.cpp:156 +#: ../../po/../src/ui/stock-items.cpp:157 +#: ../../po/../src/ui/stock-items.cpp:158 +#: ../../po/../src/ui/stock-items.cpp:161 +#: ../../po/../src/ui/stock-items.cpp:162 +#: ../../po/../src/ui/stock-items.cpp:163 +#: ../../po/../src/ui/stock-items.cpp:164 +#: ../../po/../src/ui/stock-items.cpp:165 +#: ../../po/../src/ui/stock-items.cpp:166 +#: ../../po/../src/ui/stock-items.cpp:167 +#: ../../po/../src/ui/stock-items.cpp:168 +#: ../../po/../src/ui/stock-items.cpp:169 +#: ../../po/../src/ui/stock-items.cpp:170 +#: ../../po/../src/ui/stock-items.cpp:171 +#: ../../po/../src/ui/stock-items.cpp:172 +#: ../../po/../src/ui/stock-items.cpp:175 +#: ../../po/../src/ui/stock-items.cpp:176 +#: ../../po/../src/ui/stock-items.cpp:177 +#: ../../po/../src/ui/stock-items.cpp:178 +#: ../../po/../src/ui/stock-items.cpp:181 +#: ../../po/../src/ui/stock-items.cpp:182 +#: ../../po/../src/ui/stock-items.cpp:183 +#: ../../po/../src/ui/stock-items.cpp:184 +#: ../../po/../src/ui/stock-items.cpp:185 +#: ../../po/../src/ui/stock-items.cpp:186 +#: ../../po/../src/ui/stock-items.cpp:187 +#: ../../po/../src/ui/stock-items.cpp:188 +#: ../../po/../src/ui/stock-items.cpp:189 +#: ../../po/../src/ui/stock-items.cpp:190 +#: ../../po/../src/ui/stock-items.cpp:191 +#: ../../po/../src/ui/stock-items.cpp:194 +#: ../../po/../src/ui/stock-items.cpp:195 +#: ../../po/../src/ui/stock-items.cpp:198 +#: ../../po/../src/ui/stock-items.cpp:199 +#: ../../po/../src/ui/stock-items.cpp:200 +#: ../../po/../src/ui/stock-items.cpp:201 +#: ../../po/../src/ui/stock-items.cpp:202 +msgid "PLACEHOLDER, do not translate" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:88 +msgid "small" +msgstr "majhen" + +#: ../../po/../src/ui/widget/panel.cpp:89 +msgid "medium" +msgstr "srednji" + +#: ../../po/../src/ui/widget/panel.cpp:90 +msgid "large" +msgstr "velik" + +#: ../../po/../src/ui/widget/panel.cpp:91 +msgid "huge" +msgstr "ogromen" + +#: ../../po/../src/ui/widget/panel.cpp:106 +msgid "List" +msgstr "Spisek" + +#: ../../po/../src/ui/widget/selected-style.cpp:67 +msgid "F:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:68 +msgid "S:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:69 +msgid "O:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:95 +msgid "N/A" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:98 +#: ../../po/../src/ui/widget/selected-style.cpp:712 +#, fuzzy +msgid "Nothing selected" +msgstr "Izbran ni noben preliv" + +#: ../../po/../src/ui/widget/selected-style.cpp:103 +msgid "No fill" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:103 +#, fuzzy +msgid "No stroke" +msgstr " (poteza)" + +#: ../../po/../src/ui/widget/selected-style.cpp:105 +#: ../../po/../src/widgets/paint-selector.cpp:190 +msgid "Pattern" +msgstr "Vzorec" + +#: ../../po/../src/ui/widget/selected-style.cpp:108 +#: ../../po/../src/widgets/paint-selector.cpp:885 +msgid "Pattern fill" +msgstr "Polnjenje z vzorcem" + +#: ../../po/../src/ui/widget/selected-style.cpp:108 +#, fuzzy +msgid "Pattern stroke" +msgstr "Zamik vzorca" + +#: ../../po/../src/ui/widget/selected-style.cpp:110 +#, fuzzy +msgid "L Gradient" +msgstr "Preliv" + +#: ../../po/../src/ui/widget/selected-style.cpp:113 +#, fuzzy +msgid "Linear gradient fill" +msgstr "Raven preliv" + +#: ../../po/../src/ui/widget/selected-style.cpp:113 +#, fuzzy +msgid "Linear gradient stroke" +msgstr "Raven preliv" + +#: ../../po/../src/ui/widget/selected-style.cpp:115 +#, fuzzy +msgid "R Gradient" +msgstr "Preliv" + +#: ../../po/../src/ui/widget/selected-style.cpp:118 +#, fuzzy +msgid "Radial gradient fill" +msgstr "Krožen preliv" + +#: ../../po/../src/ui/widget/selected-style.cpp:118 +#, fuzzy +msgid "Radial gradient stroke" +msgstr "Krožen preliv" + +#: ../../po/../src/ui/widget/selected-style.cpp:120 +#, fuzzy +msgid "Different" +msgstr "_Razlika" + +#: ../../po/../src/ui/widget/selected-style.cpp:123 +#, fuzzy +msgid "Different fills" +msgstr "_Razlika" + +#: ../../po/../src/ui/widget/selected-style.cpp:123 +#, fuzzy +msgid "Different strokes" +msgstr "_Razlika" + +#: ../../po/../src/ui/widget/selected-style.cpp:125 +#, fuzzy +msgid "Unset" +msgstr "zožaj" + +#. TRANSLATORS COMMENT: unset is a verb here +#: ../../po/../src/ui/widget/selected-style.cpp:128 +#: ../../po/../src/ui/widget/selected-style.cpp:182 +msgid "Unset fill" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:128 +#: ../../po/../src/ui/widget/selected-style.cpp:182 +#, fuzzy +msgid "Unset stroke" +msgstr " (poteza)" + +#: ../../po/../src/ui/widget/selected-style.cpp:131 +#, fuzzy +msgid "Flat color fill" +msgstr "Čista barva" + +#: ../../po/../src/ui/widget/selected-style.cpp:131 +#, fuzzy +msgid "Flat color stroke" +msgstr "Čista barva" + +#. TRANSLATOR COMMENT: A means "Averaged" +#: ../../po/../src/ui/widget/selected-style.cpp:134 +#, fuzzy +msgid "A" +msgstr "_A" + +#: ../../po/../src/ui/widget/selected-style.cpp:137 +#, fuzzy +msgid "Fill is averaged over selected objects" +msgstr "Natančen ALI izbranih predmetov" + +#: ../../po/../src/ui/widget/selected-style.cpp:137 +#, fuzzy +msgid "Stroke is averaged over selected objects" +msgstr "Presek izbranih predmetov" + +#. TRANSLATOR COMMENT: M means "Multiple" +#: ../../po/../src/ui/widget/selected-style.cpp:140 +#, fuzzy +msgid "M" +msgstr "_M" + +#: ../../po/../src/ui/widget/selected-style.cpp:143 +#, fuzzy +msgid "Multiple selected objects have the same fill" +msgstr "Navpično poravnaj izbrana vozlišča" + +#: ../../po/../src/ui/widget/selected-style.cpp:143 +#, fuzzy +msgid "Multiple selected objects have the same stroke" +msgstr "Navpično poravnaj izbrana vozlišča" + +#: ../../po/../src/ui/widget/selected-style.cpp:145 +#, fuzzy +msgid "Edit fill..." +msgstr "Uredi..." + +#: ../../po/../src/ui/widget/selected-style.cpp:145 +#, fuzzy +msgid "Edit stroke..." +msgstr "Uredi..." + +#: ../../po/../src/ui/widget/selected-style.cpp:149 +#, fuzzy +msgid "Last set color" +msgstr "Čista barva" + +#: ../../po/../src/ui/widget/selected-style.cpp:153 +#, fuzzy +msgid "Last selected color" +msgstr "Zadnja izbira" + +#: ../../po/../src/ui/widget/selected-style.cpp:157 +msgid "White" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:161 +#: ../../po/../src/widgets/sp-color-scales.cpp:461 +#: ../../po/../src/widgets/sp-color-scales.cpp:462 +msgid "Black" +msgstr "Črna" + +#: ../../po/../src/ui/widget/selected-style.cpp:165 +#, fuzzy +msgid "Copy color" +msgstr "Barva za konec" + +#: ../../po/../src/ui/widget/selected-style.cpp:169 +#, fuzzy +msgid "Paste color" +msgstr "Čista barva" + +#: ../../po/../src/ui/widget/selected-style.cpp:173 +#, fuzzy +msgid "Swap fill and stroke" +msgstr "_Polnjenje in obroba" + +#: ../../po/../src/ui/widget/selected-style.cpp:177 +msgid "Make fill opaque" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:177 +msgid "Make stroke opaque" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:186 +#, fuzzy +msgid "Remove fill" +msgstr " Od_strani " + +#: ../../po/../src/ui/widget/selected-style.cpp:186 +#, fuzzy +msgid "Remove stroke" +msgstr "_Odstrani povezavo" + +#: ../../po/../src/ui/widget/selected-style.cpp:718 +#, fuzzy +msgid "Master opacity" +msgstr "Glavna _prosojnost" + +#: ../../po/../src/ui/widget/selected-style.cpp:744 +msgid "0 (transparent)" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:768 +msgid "1.0 (opaque)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1046 +msgid "Moved to next layer." +msgstr "Premaknjeno na naslednji sloj." + +#: ../../po/../src/verbs.cpp:1048 +#, fuzzy +msgid "Cannot move past last layer." +msgstr "Ne morem premikati preko zadnjega sloja." + +#: ../../po/../src/verbs.cpp:1057 +msgid "Moved to previous layer." +msgstr "Premaknil v prejÅ¡nji sloj." + +#: ../../po/../src/verbs.cpp:1059 +#, fuzzy +msgid "Cannot move past first layer." +msgstr "Ne morem premikati pred prvi sloj." + +#: ../../po/../src/verbs.cpp:1076 ../../po/../src/verbs.cpp:1150 +msgid "No current layer." +msgstr "Ni trenutnega sloja." + +#: ../../po/../src/verbs.cpp:1105 +#, c-format +msgid "Raised layer %s." +msgstr "Dvignjen sloj %s." + +#: ../../po/../src/verbs.cpp:1109 +#, c-format +msgid "Lowered layer %s." +msgstr "Spuščen sloj.%s." + +#: ../../po/../src/verbs.cpp:1118 +#, fuzzy +msgid "Cannot move layer any further." +msgstr "Sloja ne morem več premakniti." + +#. TRANSLATORS: this means "The layer has been deleted." +#: ../../po/../src/verbs.cpp:1148 +msgid "Deleted layer." +msgstr "Sloj izbrisan." + +#: ../../po/../src/verbs.cpp:1544 +msgid "" +"You need to connect to a Jabber server before sharing a document with " +"another user." +msgstr "" + +#: ../../po/../src/verbs.cpp:1559 +msgid "" +"You need to connect to a Jabber server before sharing a document with a " +"chatroom." +msgstr "" + +#: ../../po/../src/verbs.cpp:1569 +msgid "XML node tracker has not been initialized; nothing to dump" +msgstr "" + +#. TRANSLATORS: If you have translated the keys.svg file to your language, then +#. translate this string as "keys.LANG.svg" (where LANG is your language code); +#. otherwise leave as "keys.svg". +#: ../../po/../src/verbs.cpp:1631 +msgid "keys.svg" +msgstr "keys.sl.svg" + +#. TRANSLATORS: If you have translated the tutorial-basic.svg file to your language, +#. then translate this string as "tutorial-basic.LANG.svg" (where LANG is your language +#. code); otherwise leave as "tutorial-basic.svg". +#: ../../po/../src/verbs.cpp:1667 +msgid "tutorial-basic.svg" +msgstr "tutorial-basic.sl.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1671 +msgid "tutorial-shapes.svg" +msgstr "tutorial-shapes.sl.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1675 +msgid "tutorial-advanced.svg" +msgstr "tutorial-advanced.sl.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1679 +msgid "tutorial-tracing.svg" +msgstr "tutorial-tracing.sl.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1683 +msgid "tutorial-calligraphy.svg" +msgstr "tutorial-calligraphy.sl.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1687 +msgid "tutorial-elements.svg" +msgstr "tutorial-elements.sl.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1691 +msgid "tutorial-tips.svg" +msgstr "tutorial-tips.sl.svg" + +#: ../../po/../src/verbs.cpp:1842 +msgid "Does nothing" +msgstr "Ne naredi ničesar" + +#. File +#: ../../po/../src/verbs.cpp:1845 +msgid "Default" +msgstr "Privzeto " + +#: ../../po/../src/verbs.cpp:1845 +msgid "Create new document from default template" +msgstr "Ustvari nov dokument iz privzete predloge" + +#: ../../po/../src/verbs.cpp:1847 +msgid "_Open..." +msgstr "_Odpri ..." + +#: ../../po/../src/verbs.cpp:1848 +msgid "Open existing document" +msgstr "Odpri obstoječ dokument" + +#: ../../po/../src/verbs.cpp:1849 +msgid "Re_vert" +msgstr "Po_vrni" + +#: ../../po/../src/verbs.cpp:1850 +msgid "Revert to the last saved version of document (changes will be lost)" +msgstr "Povrni zadnjo shranjeno inačico dokumenta (spremembe bodo izgubljene)" + +#: ../../po/../src/verbs.cpp:1851 +msgid "_Save" +msgstr "_Shrani" + +#: ../../po/../src/verbs.cpp:1851 +msgid "Save document" +msgstr "Shrani dokument" + +#: ../../po/../src/verbs.cpp:1853 +msgid "Save _As..." +msgstr "Shrani _kot ..." + +#: ../../po/../src/verbs.cpp:1854 +msgid "Save document under new name" +msgstr "Shrani dokument v novo datoteko" + +#: ../../po/../src/verbs.cpp:1855 +msgid "_Print..." +msgstr "_Natisni ..." + +#: ../../po/../src/verbs.cpp:1855 +msgid "Print document" +msgstr "Natisni dokument" + +#. TRANSLATORS: "Vacuum Defs" means "Clean up defs" (so as to remove unused definitions) +#: ../../po/../src/verbs.cpp:1858 +msgid "Vac_uum Defs" +msgstr "Po_čisti definicije" + +#: ../../po/../src/verbs.cpp:1858 +#, fuzzy +msgid "Remove unused predefined items from the <defs> of the document" +msgstr "Odstrani nepotrebne reči iz <definicij> dokumenta" + +#: ../../po/../src/verbs.cpp:1860 +msgid "Print _Direct" +msgstr "Tiskaj _neposredno" + +#: ../../po/../src/verbs.cpp:1861 +#, fuzzy +msgid "Print directly without prompting to a file or pipe" +msgstr "Tiskaj neposredno v datoteko ali program" + +#: ../../po/../src/verbs.cpp:1862 +msgid "Print Previe_w" +msgstr "Predo_gled tiskanja" + +#: ../../po/../src/verbs.cpp:1863 +msgid "Preview document printout" +msgstr "Predogled tiskanja risbe" + +#: ../../po/../src/verbs.cpp:1864 +msgid "_Import..." +msgstr "_Uvozi ..." + +#: ../../po/../src/verbs.cpp:1865 +msgid "Import bitmap or SVG image into document" +msgstr "V dokument uvozi sliko ali SVG" + +#: ../../po/../src/verbs.cpp:1866 +msgid "_Export Bitmap..." +msgstr "_Izvozi kot sliko ..." + +#: ../../po/../src/verbs.cpp:1867 +#, fuzzy +msgid "Export document or selection as a bitmap image" +msgstr "Izvozi dokument ali izbiro kot sliko v PNG" + +#: ../../po/../src/verbs.cpp:1868 +msgid "N_ext Window" +msgstr "Na_slednje okno" + +#: ../../po/../src/verbs.cpp:1869 +msgid "Switch to the next document window" +msgstr "Preskoči v okno z naslednjim dokumentom" + +#: ../../po/../src/verbs.cpp:1870 +msgid "P_revious Window" +msgstr "P_rejÅ¡nje okno" + +#: ../../po/../src/verbs.cpp:1871 +msgid "Switch to the previous document window" +msgstr "Preskoči v okno s prejÅ¡njim dokumentom" + +#: ../../po/../src/verbs.cpp:1872 +msgid "_Close" +msgstr "_Zapri" + +#: ../../po/../src/verbs.cpp:1873 +msgid "Close window" +msgstr "Zapri okno" + +#: ../../po/../src/verbs.cpp:1874 +msgid "_Quit" +msgstr "_Izhod" + +#: ../../po/../src/verbs.cpp:1874 +msgid "Quit Inkscape" +msgstr "Zapri Inkscape" + +#. Edit +#: ../../po/../src/verbs.cpp:1877 +msgid "_Undo" +msgstr "_Razveljavi" + +#: ../../po/../src/verbs.cpp:1877 +msgid "Undo last action" +msgstr "Prekliči zadnje dejanje" + +#: ../../po/../src/verbs.cpp:1879 +msgid "_Redo" +msgstr "_Ponovi" + +#: ../../po/../src/verbs.cpp:1880 +msgid "Do again last undone action" +msgstr "Spet naredi razveljavljeno" + +#: ../../po/../src/verbs.cpp:1881 +msgid "Cu_t" +msgstr "Izreži" + +#: ../../po/../src/verbs.cpp:1882 +msgid "Cut selection to clipboard" +msgstr "Izreži izbrano v odložišče" + +#: ../../po/../src/verbs.cpp:1883 +msgid "_Copy" +msgstr "Kopiraj" + +#: ../../po/../src/verbs.cpp:1884 +msgid "Copy selection to clipboard" +msgstr "Kopiraj izbrano na odložišče" + +#: ../../po/../src/verbs.cpp:1885 +msgid "_Paste" +msgstr "Prilepi" + +#: ../../po/../src/verbs.cpp:1886 +#, fuzzy +msgid "Paste objects from clipboard to mouse point" +msgstr "Prilepi iz odložišča pod kazalec" + +#: ../../po/../src/verbs.cpp:1887 +msgid "Paste _Style" +msgstr "Slog _lepljenja" + +#: ../../po/../src/verbs.cpp:1888 +msgid "Apply style of the copied object to selection" +msgstr "Dodaj slog kopiranega predmeta na izbiro" + +#: ../../po/../src/verbs.cpp:1889 +msgid "Paste _In Place" +msgstr "Prilepi _naravnost" + +#: ../../po/../src/verbs.cpp:1890 +#, fuzzy +msgid "Paste objects from clipboard to the original location" +msgstr "Prilepi predmet(e) z odložišča na izvirno mesto" + +#: ../../po/../src/verbs.cpp:1891 +msgid "_Delete" +msgstr "ZbriÅ¡i" + +#: ../../po/../src/verbs.cpp:1892 +msgid "Delete selection" +msgstr "IzbriÅ¡i izbiro" + +#: ../../po/../src/verbs.cpp:1893 +msgid "Duplic_ate" +msgstr "Podvo_ji" + +#: ../../po/../src/verbs.cpp:1894 +#, fuzzy +msgid "Duplicate selected objects" +msgstr "Podvoji izbran(e) predmet(e)" + +#: ../../po/../src/verbs.cpp:1895 +msgid "Clo_ne" +msgstr "Kloniraj" + +#: ../../po/../src/verbs.cpp:1896 +msgid "Create a clone of selected object (a copy linked to the original)" +msgstr "Ustvari klon izbranega predmeta (dvojnik povezan z izvirnikom)" + +#: ../../po/../src/verbs.cpp:1897 +msgid "Unlin_k Clone" +msgstr "Odve_ži klona" + +#: ../../po/../src/verbs.cpp:1898 +msgid "Cut the clone's link to its original" +msgstr "Prereži povezavo klona in izvirnika" + +#: ../../po/../src/verbs.cpp:1899 +msgid "Select _Original" +msgstr "Izberi _izvirnik" + +#: ../../po/../src/verbs.cpp:1900 +msgid "Select the object to which the clone is linked" +msgstr "Izberi predmet, k kateremu je povezan dvojnik" + +#. TRANSLATORS: Convert selection to a rectangle with tiled pattern fill +#: ../../po/../src/verbs.cpp:1902 +#, fuzzy +msgid "O_bjects to Pattern" +msgstr "Pre_dmet(i) v vzorce" + +#: ../../po/../src/verbs.cpp:1903 +msgid "Convert selection to a rectangle with tiled pattern fill" +msgstr "S tlakovanjem pretvori izbrano v pravokotnik" + +#. TRANSLATORS: Extract objects from a tiled pattern fill +#: ../../po/../src/verbs.cpp:1905 +#, fuzzy +msgid "Pattern to Ob_jects" +msgstr "Vzorec v pred_met(e)" + +#: ../../po/../src/verbs.cpp:1906 +msgid "Extract objects from a tiled pattern fill" +msgstr "Izvleci predmete iz tlakovanega polnila" + +#: ../../po/../src/verbs.cpp:1907 +msgid "Clea_r All" +msgstr "_Počisti vse" + +#: ../../po/../src/verbs.cpp:1908 +msgid "Delete all objects from document" +msgstr "IzbriÅ¡i vse predmete iz dokumenta" + +#: ../../po/../src/verbs.cpp:1909 +msgid "Select Al_l" +msgstr "Izberi v_se" + +#: ../../po/../src/verbs.cpp:1910 +msgid "Select all objects or all nodes" +msgstr "Izberi vse predmete ali vozlišča" + +#: ../../po/../src/verbs.cpp:1911 +msgid "Select All in All La_yers" +msgstr "Izberi vse v vseh _slojih" + +#: ../../po/../src/verbs.cpp:1912 +msgid "Select all objects in all visible and unlocked layers" +msgstr "Izberi vse predmete v vseh vidnih in nezaklenjenih slojih" + +#: ../../po/../src/verbs.cpp:1913 +msgid "In_vert Selection" +msgstr "Za_obrni izbiro" + +#: ../../po/../src/verbs.cpp:1914 +msgid "Invert selection (unselect what is selected and select everything else)" +msgstr "Zaobrni izbiro (izberi vse kar trenutno ni izbrano)" + +#: ../../po/../src/verbs.cpp:1915 +msgid "Invert in All Layers" +msgstr "Zaobrni po vseh slojih" + +#: ../../po/../src/verbs.cpp:1916 +msgid "Invert selection in all visible and unlocked layers" +msgstr "Zaobrni izbiro v vseh vidnih in nezaklenjenih slojih" + +#: ../../po/../src/verbs.cpp:1917 +msgid "D_eselect" +msgstr "Pre_kliči izbiro" + +#: ../../po/../src/verbs.cpp:1918 +msgid "Deselect any selected objects or nodes" +msgstr "Prekliči izbiro vseh predmetov ali vozlišč" + +#. Selection +#: ../../po/../src/verbs.cpp:1921 +msgid "Raise to _Top" +msgstr "Dvigni na _vrh" + +#: ../../po/../src/verbs.cpp:1922 +msgid "Raise selection to top" +msgstr "Dvigni izbrane predmete na vrh" + +#: ../../po/../src/verbs.cpp:1923 +msgid "Lower to _Bottom" +msgstr "Spusti na _dno" + +#: ../../po/../src/verbs.cpp:1924 +msgid "Lower selection to bottom" +msgstr "Spusti izbrano na dno" + +#: ../../po/../src/verbs.cpp:1925 +msgid "_Raise" +msgstr "_Dvigni" + +#: ../../po/../src/verbs.cpp:1926 +msgid "Raise selection one step" +msgstr "Dvigni izbrano za en sloj" + +#: ../../po/../src/verbs.cpp:1927 +msgid "_Lower" +msgstr "_Spusti" + +#: ../../po/../src/verbs.cpp:1928 +msgid "Lower selection one step" +msgstr "Spusti izbrano za en sloj" + +#: ../../po/../src/verbs.cpp:1929 +msgid "_Group" +msgstr "_Združi" + +#: ../../po/../src/verbs.cpp:1930 +msgid "Group selected objects" +msgstr "Združi izbrane predmete v skupino" + +#: ../../po/../src/verbs.cpp:1932 +#, fuzzy +msgid "Ungroup selected groups" +msgstr "Razdruži predmete iz izbrane skupine" + +#: ../../po/../src/verbs.cpp:1934 +msgid "_Put on Path" +msgstr "_Pripni na pot" + +#: ../../po/../src/verbs.cpp:1935 +msgid "Put text on path" +msgstr "Pripni besedilo na pot" + +#: ../../po/../src/verbs.cpp:1936 +msgid "_Remove from Path" +msgstr "_Odstrani s poti" + +#: ../../po/../src/verbs.cpp:1937 +msgid "Remove text from path" +msgstr "Odstrani besedilo s poti" + +#: ../../po/../src/verbs.cpp:1938 +msgid "Remove Manual _Kerns" +msgstr "Odstrani ročno _zgoščevanje" + +#. TRANSLATORS: "glyph": An image used in the visual representation of characters; +#. roughly speaking, how a character looks. A font is a set of glyphs. +#: ../../po/../src/verbs.cpp:1941 +msgid "Remove all manual kerns and glyph rotations from a text object" +msgstr "Odstrani vsa ročna vrtenja črk v besedilu" + +#: ../../po/../src/verbs.cpp:1943 +msgid "_Union" +msgstr "_Združi" + +#: ../../po/../src/verbs.cpp:1944 +msgid "Union of selected objects" +msgstr "Unija izbranih predmetov" + +#: ../../po/../src/verbs.cpp:1945 +msgid "_Intersection" +msgstr "_Presek" + +#: ../../po/../src/verbs.cpp:1946 +msgid "Intersection of selected objects" +msgstr "Presek izbranih predmetov" + +#: ../../po/../src/verbs.cpp:1947 +msgid "_Difference" +msgstr "_Razlika" + +#: ../../po/../src/verbs.cpp:1948 +msgid "Difference of selected objects (bottom minus top)" +msgstr "Razlika izbranih predmetov (dno minus vrh)" + +#: ../../po/../src/verbs.cpp:1949 +msgid "E_xclusion" +msgstr "_Odvzem" + +#: ../../po/../src/verbs.cpp:1950 +msgid "Exclusive OR of selected objects" +msgstr "Natančen ALI izbranih predmetov" + +#: ../../po/../src/verbs.cpp:1951 +msgid "Di_vision" +msgstr "_Deljenje" + +#: ../../po/../src/verbs.cpp:1952 +msgid "Cut the bottom object into pieces" +msgstr "Razreži spodnji predmet na koščke" + +#. TRANSLATORS: "to cut a path" is not the same as "to break a path apart" - see the +#. Advanced tutorial for more info +#: ../../po/../src/verbs.cpp:1955 +msgid "Cut _Path" +msgstr "Izreži _pot" + +#: ../../po/../src/verbs.cpp:1956 +msgid "Cut the bottom object's stroke into pieces, removing fill" +msgstr "Razreži črto spodnjega predmeta na koščke in odstrani polnila" + +#. TRANSLATORS: "outset": expand a shape by offsetting the object's path, +#. i.e. by displacing it perpendicular to the path in each point. +#. See also the Advanced Tutorial for explanation. +#: ../../po/../src/verbs.cpp:1960 +msgid "Outs_et" +msgstr "Raz_Å¡iri" + +#: ../../po/../src/verbs.cpp:1961 +#, fuzzy +msgid "Outset selected paths" +msgstr "RazÅ¡iri izbrane poti" + +#: ../../po/../src/verbs.cpp:1963 +msgid "O_utset Path by 1 px" +msgstr "RazÅ¡iri po_t za 1 točko" + +#: ../../po/../src/verbs.cpp:1964 +#, fuzzy +msgid "Outset selected paths by 1 px" +msgstr "RazÅ¡iri izbrane poti za 1 točko" + +#: ../../po/../src/verbs.cpp:1966 +msgid "O_utset Path by 10 px" +msgstr "RazÅ¡iri pot za 10 točk" + +#: ../../po/../src/verbs.cpp:1967 +#, fuzzy +msgid "Outset selected paths by 10 px" +msgstr "RazÅ¡iri izbrane poti za 10 točk" + +#. TRANSLATORS: "inset": contract a shape by offsetting the object's path, +#. i.e. by displacing it perpendicular to the path in each point. +#. See also the Advanced Tutorial for explanation. +#: ../../po/../src/verbs.cpp:1971 +msgid "I_nset" +msgstr "_Zožaj" + +#: ../../po/../src/verbs.cpp:1972 +#, fuzzy +msgid "Inset selected paths" +msgstr "Zoži izbrane poti" + +#: ../../po/../src/verbs.cpp:1974 +msgid "I_nset Path by 1 px" +msgstr "_Zoži pot za 1 točko" + +#: ../../po/../src/verbs.cpp:1975 +#, fuzzy +msgid "Inset selected paths by 1 px" +msgstr "Zoži izbrane poti za 1 točko" + +#: ../../po/../src/verbs.cpp:1977 +msgid "I_nset Path by 10 px" +msgstr "_Zoži pot za 10 točk" + +#: ../../po/../src/verbs.cpp:1978 +#, fuzzy +msgid "Inset selected paths by 10 px" +msgstr "Zoži izbrane poti za 10 točk" + +#: ../../po/../src/verbs.cpp:1980 +msgid "D_ynamic Offset" +msgstr "D_inamičen odmik" + +#: ../../po/../src/verbs.cpp:1980 +msgid "Create a dynamic offset object" +msgstr "Ustvari razÅ¡iritev kot predmet" + +#: ../../po/../src/verbs.cpp:1982 +msgid "_Linked Offset" +msgstr "Po_vezan zamik" + +#: ../../po/../src/verbs.cpp:1983 +msgid "Create a dynamic offset object linked to the original path" +msgstr "Ustvari razÅ¡iritev kot predmet, povezan z izvirno potjo" + +#: ../../po/../src/verbs.cpp:1985 +msgid "_Stroke to Path" +msgstr "_Poteza v pot" + +#: ../../po/../src/verbs.cpp:1986 +#, fuzzy +msgid "Convert selected strokes to paths" +msgstr "Pretvori izbrane poteze v pot(i)" + +#: ../../po/../src/verbs.cpp:1987 +msgid "Si_mplify" +msgstr "Po_enostavi" + +#: ../../po/../src/verbs.cpp:1988 +#, fuzzy +msgid "Simplify selected paths by removing extra nodes" +msgstr "Poenostavi izbrane poti z odstranjevanjem vozlišč" + +#: ../../po/../src/verbs.cpp:1989 +msgid "_Reverse" +msgstr "_Obratno" + +#: ../../po/../src/verbs.cpp:1990 +#, fuzzy +msgid "Reverses the direction of selected paths; useful for flipping markers" +msgstr "Zamenjaj smer izbranih poti; uporabno za obračanje puščic" + +#. TRANSLATORS: "to trace" means "to convert a bitmap to vector graphics" (to vectorize) +#: ../../po/../src/verbs.cpp:1992 +msgid "_Trace Bitmap" +msgstr "Preri_Å¡i rastersko sliko" + +#: ../../po/../src/verbs.cpp:1993 +msgid "Convert bitmap object to paths" +msgstr "Pretvori rasterski predmet v poti" + +#: ../../po/../src/verbs.cpp:1994 +msgid "_Make a Bitmap Copy" +msgstr "_Naredi rastersko kopijo" + +#: ../../po/../src/verbs.cpp:1995 +msgid "Export selection to a bitmap and insert it into document" +msgstr "Izbrano izvozi v rastersko datoteko in jo dodaj v dokument" + +#: ../../po/../src/verbs.cpp:1996 +msgid "_Combine" +msgstr "_Sestavi" + +#: ../../po/../src/verbs.cpp:1997 +msgid "Combine several paths into one" +msgstr "Sestavi več poti v eno" + +#. TRANSLATORS: "to cut a path" is not the same as "to break a path apart" - see the +#. Advanced tutorial for more info +#: ../../po/../src/verbs.cpp:2000 +msgid "Break _Apart" +msgstr "Razs_tavi" + +#: ../../po/../src/verbs.cpp:2001 +#, fuzzy +msgid "Break selected paths into subpaths" +msgstr "Razstavi izbrane poti na manjÅ¡e enote" + +#: ../../po/../src/verbs.cpp:2002 +msgid "Gri_d Arrange..." +msgstr "Razporedi _mrežo ..." + +#: ../../po/../src/verbs.cpp:2003 +msgid "Arrange selection in grid pattern" +msgstr "Razporedi izbiro v vzorcu mreže" + +#. Layer +#: ../../po/../src/verbs.cpp:2005 +msgid "_Add Layer..." +msgstr "_Dodaj sloj ..." + +#: ../../po/../src/verbs.cpp:2006 +msgid "Create a new layer" +msgstr "Ustvari nov sloj" + +#: ../../po/../src/verbs.cpp:2007 +msgid "Re_name Layer..." +msgstr "P_reimenuj sloj..." + +#: ../../po/../src/verbs.cpp:2008 +msgid "Rename the current layer" +msgstr "Preimenuj trenutni sloj" + +#: ../../po/../src/verbs.cpp:2009 +msgid "Switch to Layer Abov_e" +msgstr "Preklopi na _zgornji sloj" + +#: ../../po/../src/verbs.cpp:2010 +msgid "Switch to the layer above the current" +msgstr "Preklopi na sloj nad trenutnim" + +#: ../../po/../src/verbs.cpp:2011 +msgid "Switch to Layer Belo_w" +msgstr "Preklopi na _spodnji sloj" + +#: ../../po/../src/verbs.cpp:2012 +msgid "Switch to the layer below the current" +msgstr "Preklopi na sloj pod trenutnim" + +#: ../../po/../src/verbs.cpp:2013 +msgid "Move Selection to Layer Abo_ve" +msgstr "Premakni izbiro na sloj _nad njim" + +#: ../../po/../src/verbs.cpp:2014 +msgid "Move selection to the layer above the current" +msgstr "Premakni izbiro na sloj nad trenutnim" + +#: ../../po/../src/verbs.cpp:2015 +msgid "Move Selection to Layer Bel_ow" +msgstr "Premakni izbiro na sloj _pod njim" + +#: ../../po/../src/verbs.cpp:2016 +msgid "Move selection to the layer below the current" +msgstr "Premakni izbiro na sloj pod trenutnim" + +#: ../../po/../src/verbs.cpp:2017 +msgid "Layer to _Top" +msgstr "Sloj na _vrh" + +#: ../../po/../src/verbs.cpp:2018 +msgid "Raise the current layer to the top" +msgstr "Trenutni sloj dvigni na vrh" + +#: ../../po/../src/verbs.cpp:2019 +msgid "Layer to _Bottom" +msgstr "Sloj na _dno" + +#: ../../po/../src/verbs.cpp:2020 +msgid "Lower the current layer to the bottom" +msgstr "Spusti trnutni sloj na dno" + +#: ../../po/../src/verbs.cpp:2021 +msgid "_Raise Layer" +msgstr "_Dvigni sloj" + +#: ../../po/../src/verbs.cpp:2022 +msgid "Raise the current layer" +msgstr "Dvigni trenutni sloj" + +#: ../../po/../src/verbs.cpp:2023 +msgid "_Lower Layer" +msgstr "_Spusti sloj" + +#: ../../po/../src/verbs.cpp:2024 +msgid "Lower the current layer" +msgstr "Spusti trenutni sloj" + +#: ../../po/../src/verbs.cpp:2025 +msgid "_Delete Current Layer" +msgstr "_ZbriÅ¡i trenutni sloj" + +#: ../../po/../src/verbs.cpp:2026 +msgid "Delete the current layer" +msgstr "IzbriÅ¡i trenutni sloj" + +#. Object +#: ../../po/../src/verbs.cpp:2029 +#, fuzzy +msgid "Rotate _90° CW" +msgstr "Zavrti za 90 stopinj v SUK" + +#: ../../po/../src/verbs.cpp:2030 +#, fuzzy +msgid "Rotate selection 90° clockwise" +msgstr "Zavrti izbrano za 90 stopinj nasprotno SUK" + +#: ../../po/../src/verbs.cpp:2031 +#, fuzzy +msgid "Rotate 9_0° CCW" +msgstr "Zavrti za 90 stopinj v SUK" + +#: ../../po/../src/verbs.cpp:2032 +#, fuzzy +msgid "Rotate selection 90° counter-clockwise" +msgstr "Zavrti izbrano za 90 stopinj nasprotno SUK" + +#: ../../po/../src/verbs.cpp:2033 +msgid "Remove _Transformations" +msgstr "Odstrani _preoblikovanja" + +#: ../../po/../src/verbs.cpp:2034 +msgid "Remove transformations from object" +msgstr "Odstrani preoblikovanja predmeta" + +#: ../../po/../src/verbs.cpp:2035 +msgid "_Object to Path" +msgstr "_Predmet v pot" + +#: ../../po/../src/verbs.cpp:2036 +#, fuzzy +msgid "Convert selected objects to paths" +msgstr "Pretvori izbrane predmete v pot(i)" + +#: ../../po/../src/verbs.cpp:2037 +msgid "_Flow into Frame" +msgstr "_Spustite besedilo po obliki" + +#: ../../po/../src/verbs.cpp:2038 +#, fuzzy +msgid "Put text into frames" +msgstr "Pripni besedilo na pot" + +#: ../../po/../src/verbs.cpp:2039 +msgid "_Unflow" +msgstr "_Netekoče besedilo" + +#: ../../po/../src/verbs.cpp:2040 +msgid "Remove text from frame (creates a single-line text object)" +msgstr "Odstrani besedilo iz okvirja (ustvari predmet z eno vrstico besedila)" + +#: ../../po/../src/verbs.cpp:2041 +msgid "_Convert to Text" +msgstr "_Pretvori v besedilo" + +#: ../../po/../src/verbs.cpp:2042 +#, fuzzy +msgid "Convert flowed text to regular text objects (preserves appearance)" +msgstr "Pretvori izbrano tekoče besedilo v običajno besedilo (ohrani izgled)" + +#: ../../po/../src/verbs.cpp:2044 +#, fuzzy +msgid "Flip _Horizontal" +msgstr "Prevrni _vodoravno" + +#: ../../po/../src/verbs.cpp:2044 +#, fuzzy +msgid "Flips selected objects horizontally" +msgstr "Vodoravno poravnaj izbrana vozlišča" + +#: ../../po/../src/verbs.cpp:2047 +#, fuzzy +msgid "Flip _Vertical" +msgstr "Prevrni _navpično" + +#: ../../po/../src/verbs.cpp:2047 +#, fuzzy +msgid "Flips selected objects vertically" +msgstr "Navpično poravnaj izbrana vozlišča" + +#. Tools +#: ../../po/../src/verbs.cpp:2051 +msgid "Select" +msgstr "Izberi" + +#: ../../po/../src/verbs.cpp:2052 +msgid "Select and transform objects" +msgstr "Izberi in preoblikuj predmete" + +#: ../../po/../src/verbs.cpp:2053 +msgid "Node Edit" +msgstr "Urejanje vozlišč" + +#: ../../po/../src/verbs.cpp:2054 +msgid "Edit path nodes or control handles" +msgstr "Uredite vozlišča ali kotrolne ročice" + +#: ../../po/../src/verbs.cpp:2056 +msgid "Create rectangles and squares" +msgstr "RiÅ¡i kvadrate in pravokotnike" + +#: ../../po/../src/verbs.cpp:2058 +msgid "Create circles, ellipses, and arcs" +msgstr "RiÅ¡i kroge, elipse, loke" + +#: ../../po/../src/verbs.cpp:2060 +msgid "Create stars and polygons" +msgstr "RiÅ¡i zvezde in poligone " + +#: ../../po/../src/verbs.cpp:2062 +msgid "Create spirals" +msgstr "RiÅ¡i spirale " + +#: ../../po/../src/verbs.cpp:2064 +msgid "Draw freehand lines" +msgstr "RiÅ¡i prostoročno " + +#: ../../po/../src/verbs.cpp:2066 +msgid "Draw Bezier curves and straight lines" +msgstr "RiÅ¡i krivulje in ravne črte " + +#: ../../po/../src/verbs.cpp:2068 +msgid "Draw calligraphic lines" +msgstr "RiÅ¡i kaligrafske poteze " + +#: ../../po/../src/verbs.cpp:2070 +msgid "Create and edit text objects" +msgstr "Ustvari in urejaj besedilo " + +#: ../../po/../src/verbs.cpp:2072 +msgid "Create and edit gradients" +msgstr "Ustvari in urejaj prelive" + +#: ../../po/../src/verbs.cpp:2074 +msgid "Zoom in or out" +msgstr "Približaj ali oddalji " + +#: ../../po/../src/verbs.cpp:2076 +msgid "Pick averaged colors from image" +msgstr "Iz slike izberi povprečne barve " + +#: ../../po/../src/verbs.cpp:2078 +#, fuzzy +msgid "Create connectors" +msgstr "Ustvari nov dokument" + +#. Tool prefs +#: ../../po/../src/verbs.cpp:2081 +msgid "Selector Preferences" +msgstr "Nastavitve izbirnika" + +#: ../../po/../src/verbs.cpp:2082 +#, fuzzy +msgid "Open Preferences for the Selector tool" +msgstr "Odpri nastavitve za orodje za izbiranje" + +#: ../../po/../src/verbs.cpp:2083 +msgid "Node Tool Preferences" +msgstr "Nastavitve orodja za vozlišča" + +#: ../../po/../src/verbs.cpp:2084 +#, fuzzy +msgid "Open Preferences for the Node tool" +msgstr "Odpri nastavitve za orodje za vozlišča" + +#: ../../po/../src/verbs.cpp:2085 +msgid "Rectangle Preferences" +msgstr "Nastavitve pravokotnika" + +#: ../../po/../src/verbs.cpp:2086 +#, fuzzy +msgid "Open Preferences for the Rectangle tool" +msgstr "Odpri nastavitve za orodje za pravokotnike" + +#: ../../po/../src/verbs.cpp:2087 +msgid "Ellipse Preferences" +msgstr "Nastavitve elips" + +#: ../../po/../src/verbs.cpp:2088 +#, fuzzy +msgid "Open Preferences for the Ellipse tool" +msgstr "Odpri nastavitve za orodje za elipse" + +#: ../../po/../src/verbs.cpp:2089 +msgid "Star Preferences" +msgstr "Nastavitve zvezd" + +#: ../../po/../src/verbs.cpp:2090 +#, fuzzy +msgid "Open Preferences for the Star tool" +msgstr "Odpri nastavitve za orodje za risanje zvezd" + +#: ../../po/../src/verbs.cpp:2091 +msgid "Spiral Preferences" +msgstr "Nastavitve spiral" + +#: ../../po/../src/verbs.cpp:2092 +#, fuzzy +msgid "Open Preferences for the Spiral tool" +msgstr "Odpri nastavitve za orodje za risanje spiral" + +#: ../../po/../src/verbs.cpp:2093 +msgid "Pencil Preferences" +msgstr "Nastavitve svinčnika" + +#: ../../po/../src/verbs.cpp:2094 +#, fuzzy +msgid "Open Preferences for the Pencil tool" +msgstr "Odpri nastavitve za svinčnik" + +#: ../../po/../src/verbs.cpp:2095 +msgid "Pen Preferences" +msgstr "Nastavitve peresa" + +#: ../../po/../src/verbs.cpp:2096 +#, fuzzy +msgid "Open Preferences for the Pen tool" +msgstr "Odpri nastavitve za pero" + +#: ../../po/../src/verbs.cpp:2097 +msgid "Calligraphic Preferences" +msgstr "Nastavitve kaligrafije" + +#: ../../po/../src/verbs.cpp:2098 +#, fuzzy +msgid "Open Preferences for the Calligraphy tool" +msgstr "Odpri nastavitve za orodje za kaligrafijo" + +#: ../../po/../src/verbs.cpp:2099 +msgid "Text Preferences" +msgstr "Nastavitve besedila" + +#: ../../po/../src/verbs.cpp:2100 +#, fuzzy +msgid "Open Preferences for the Text tool" +msgstr "Odpri nastavitve orodja za besedila" + +#: ../../po/../src/verbs.cpp:2101 +msgid "Gradient Preferences" +msgstr "Nastavitve preliva" + +#: ../../po/../src/verbs.cpp:2102 +#, fuzzy +msgid "Open Preferences for the Gradient tool" +msgstr "Odpri nastavitve za prelive" + +#: ../../po/../src/verbs.cpp:2103 +msgid "Zoom Preferences" +msgstr "Nastavitve povečevala" + +#: ../../po/../src/verbs.cpp:2104 +#, fuzzy +msgid "Open Preferences for the Zoom tool" +msgstr "Odpri nastavitve orodja za povečavo" + +#: ../../po/../src/verbs.cpp:2105 +msgid "Dropper Preferences" +msgstr "Nastavitve kapalke" + +#: ../../po/../src/verbs.cpp:2106 +#, fuzzy +msgid "Open Preferences for the Dropper tool" +msgstr "Odpri nastavitve za orodje za izbiro barve" + +#: ../../po/../src/verbs.cpp:2107 +#, fuzzy +msgid "Connector Preferences" +msgstr "Nastavitve izbirnika" + +#: ../../po/../src/verbs.cpp:2108 +#, fuzzy +msgid "Open Preferences for the Connector tool" +msgstr "Odpri nastavitve za orodje za izbiranje" + +#. Zoom/View +#: ../../po/../src/verbs.cpp:2111 +msgid "Zoom In" +msgstr "Približaj" + +#: ../../po/../src/verbs.cpp:2111 +msgid "Zoom in" +msgstr "Približaj" + +#: ../../po/../src/verbs.cpp:2112 +msgid "Zoom Out" +msgstr "Oddalji" + +#: ../../po/../src/verbs.cpp:2112 +msgid "Zoom out" +msgstr "Oddalji" + +#: ../../po/../src/verbs.cpp:2113 +msgid "_Rulers" +msgstr "_Ravnila" + +#: ../../po/../src/verbs.cpp:2113 +msgid "Show or hide the canvas rulers" +msgstr "Kaži ali skrij ravnila platna" + +#: ../../po/../src/verbs.cpp:2114 +msgid "Scroll_bars" +msgstr "_Drsniki" + +#: ../../po/../src/verbs.cpp:2114 +msgid "Show or hide the canvas scrollbars" +msgstr "Kaži ali skrij gibala platna" + +#: ../../po/../src/verbs.cpp:2115 +msgid "_Grid" +msgstr "_Mreža" + +#: ../../po/../src/verbs.cpp:2116 +msgid "G_uides" +msgstr "_Vodila" + +#: ../../po/../src/verbs.cpp:2117 +msgid "Nex_t Zoom" +msgstr "Na_slednja povečava" + +#: ../../po/../src/verbs.cpp:2117 +msgid "Next zoom (from the history of zooms)" +msgstr "Naslednja povečava (iz zgodovine povečav)" + +#: ../../po/../src/verbs.cpp:2119 +msgid "Pre_vious Zoom" +msgstr "P_rejÅ¡nja povečava" + +#: ../../po/../src/verbs.cpp:2119 +msgid "Previous zoom (from the history of zooms)" +msgstr "PrejÅ¡nja povečava (iz zgodovine povečav)" + +#: ../../po/../src/verbs.cpp:2121 +msgid "Zoom 1:_1" +msgstr "Približaj na 1:_1" + +#: ../../po/../src/verbs.cpp:2121 +msgid "Zoom to 1:1" +msgstr "Približaj na 1:1" + +#: ../../po/../src/verbs.cpp:2123 +msgid "Zoom 1:_2" +msgstr "Približaj na 1:_2" + +#: ../../po/../src/verbs.cpp:2123 +msgid "Zoom to 1:2" +msgstr "Približaj na 1:2" + +#: ../../po/../src/verbs.cpp:2125 +msgid "_Zoom 2:1" +msgstr "_Približaj na 2:1" + +#: ../../po/../src/verbs.cpp:2125 +msgid "Zoom to 2:1" +msgstr "Približaj na 2:1" + +#: ../../po/../src/verbs.cpp:2128 +msgid "_Fullscreen" +msgstr "_Celozaslonsko" + +#: ../../po/../src/verbs.cpp:2128 +msgid "Stretch this document window to full screen" +msgstr "Razpni to okno čez ves zaslon" + +#: ../../po/../src/verbs.cpp:2131 +msgid "Duplic_ate Window" +msgstr "Po_dvoji okno" + +#: ../../po/../src/verbs.cpp:2131 +msgid "Open a new window with the same document" +msgstr "Odpri novo okno z istim dokumentom" + +#: ../../po/../src/verbs.cpp:2133 +msgid "_New View Preview" +msgstr "_Nov predogled" + +#: ../../po/../src/verbs.cpp:2134 +msgid "New View Preview" +msgstr "Nov predogled" + +#. "view_new_preview" +#: ../../po/../src/verbs.cpp:2136 +#, fuzzy +msgid "_Normal" +msgstr "Običajno" + +#: ../../po/../src/verbs.cpp:2137 +msgid "Switch to normal display mode" +msgstr "" + +#: ../../po/../src/verbs.cpp:2138 +#, fuzzy +msgid "_Outline" +msgstr "Zgolj obroba" + +#: ../../po/../src/verbs.cpp:2139 +msgid "Switch to outline (wireframe) display mode" +msgstr "" + +#: ../../po/../src/verbs.cpp:2141 +msgid "Ico_n Preview" +msgstr "Predogled _ikon" + +#: ../../po/../src/verbs.cpp:2142 +msgid "Open a window to preview items at different icon resolutions" +msgstr "Odpre okno s predogledom predmetov pri različnih ločljivostih" + +#: ../../po/../src/verbs.cpp:2144 +msgid "Zoom to fit page in window" +msgstr "Približaj na celo stran" + +#: ../../po/../src/verbs.cpp:2145 +msgid "Page _Width" +msgstr "_Å irina strani" + +#: ../../po/../src/verbs.cpp:2146 +msgid "Zoom to fit page width in window" +msgstr "Približaj na Å¡irino strani" + +#: ../../po/../src/verbs.cpp:2148 +msgid "Zoom to fit drawing in window" +msgstr "Približaj na velikost risbe" + +#: ../../po/../src/verbs.cpp:2150 +msgid "Zoom to fit selection in window" +msgstr "Približaj na velikost izbire" + +#. Dialogs +#: ../../po/../src/verbs.cpp:2153 +msgid "In_kscape Preferences..." +msgstr "Nastavitve In_kscape-a ..." + +#: ../../po/../src/verbs.cpp:2154 +msgid "Global Inkscape preferences" +msgstr "SploÅ¡ne nastavitve Inkscape-a" + +#: ../../po/../src/verbs.cpp:2155 +msgid "_Document Preferences..." +msgstr "Nastavitve _dokumenta ..." + +#: ../../po/../src/verbs.cpp:2156 +msgid "Preferences saved with the document" +msgstr "Nastavitve so shranjene v dokumentu" + +#: ../../po/../src/verbs.cpp:2157 +msgid "_Fill and Stroke..." +msgstr "_Polnenje in obroba ..." + +#: ../../po/../src/verbs.cpp:2158 +msgid "Fill and Stroke dialog" +msgstr "Okno polnenje in obroba" + +#. TRANSLATORS: "Swatches" means: color samples +#: ../../po/../src/verbs.cpp:2160 +msgid "S_watches..." +msgstr "I_zvlečki..." + +#: ../../po/../src/verbs.cpp:2161 +msgid "View color swatches" +msgstr "Pokaži barve izvlečke" + +#: ../../po/../src/verbs.cpp:2162 +msgid "Transfor_m..." +msgstr "Pre_oblikuj ..." + +#: ../../po/../src/verbs.cpp:2163 +msgid "Transform dialog" +msgstr "Okno preoblikovanja" + +#: ../../po/../src/verbs.cpp:2164 +msgid "_Align and Distribute..." +msgstr "Pora_vnaj in razporedi ..." + +#: ../../po/../src/verbs.cpp:2165 +msgid "Align and Distribute dialog" +msgstr "Okno poravnave in raporejanja" + +#: ../../po/../src/verbs.cpp:2166 +msgid "_Text and Font..." +msgstr "_Besedilo in pisava ..." + +#: ../../po/../src/verbs.cpp:2167 +msgid "Text and Font dialog" +msgstr "Okno besedila in pisave" + +#: ../../po/../src/verbs.cpp:2168 +msgid "_XML Editor..." +msgstr "Urejevalnik _XML ..." + +#: ../../po/../src/verbs.cpp:2169 +msgid "XML Editor" +msgstr "Urejevalnik XML" + +#: ../../po/../src/verbs.cpp:2170 +msgid "_Find..." +msgstr "_Najdi ..." + +#: ../../po/../src/verbs.cpp:2171 +msgid "Find objects in document" +msgstr "Poišči predmet v dokumentu" + +#: ../../po/../src/verbs.cpp:2172 +msgid "_Messages..." +msgstr "_Sporočila ..." + +#: ../../po/../src/verbs.cpp:2173 +msgid "View debug messages" +msgstr "Pokaži sporočila o napakah" + +#: ../../po/../src/verbs.cpp:2174 +msgid "S_cripts..." +msgstr "_Skripte ..." + +#: ../../po/../src/verbs.cpp:2175 +msgid "Run scripts" +msgstr "Poženi skripte" + +#: ../../po/../src/verbs.cpp:2176 +msgid "Show/Hide D_ialogs" +msgstr "Pokaži/_skrij pogovorna okna" + +#: ../../po/../src/verbs.cpp:2177 +msgid "Show or hide all active dialogs" +msgstr "Pokaži ali skrij uporabljena pogovorna okna" + +#. TRANSLATORS: "Tile clones" means: "Create tiled clones" +#: ../../po/../src/verbs.cpp:2179 +msgid "Tile clones..." +msgstr "Tlakuj klone ..." + +#: ../../po/../src/verbs.cpp:2180 +msgid "Create and arrange multiple clones of selection" +msgstr "Ustvari in urejaj večkratne klone izbire" + +#: ../../po/../src/verbs.cpp:2181 +msgid "_Object Properties..." +msgstr "Lastnosti _predmeta ..." + +#: ../../po/../src/verbs.cpp:2182 +msgid "Object Properties dialog" +msgstr "Okno lastnosti predmeta" + +#: ../../po/../src/verbs.cpp:2185 +msgid "_Connect to Jabber server..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2185 +msgid "Connect to a Jabber server" +msgstr "" + +#: ../../po/../src/verbs.cpp:2187 +#, fuzzy +msgid "Share with _user..." +msgstr "Shrani _kot ..." + +#: ../../po/../src/verbs.cpp:2187 +msgid "Establish a whiteboard session with another Jabber user" +msgstr "" + +#: ../../po/../src/verbs.cpp:2189 +msgid "Share with _chatroom..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2189 +msgid "" +"Join a chatroom to start a new whiteboard session or join one in progress" +msgstr "" + +#: ../../po/../src/verbs.cpp:2191 +msgid "_Dump XML node tracker" +msgstr "" + +#: ../../po/../src/verbs.cpp:2191 +msgid "Dump the contents of the XML tracker to the console" +msgstr "" + +#: ../../po/../src/verbs.cpp:2193 +msgid "_Open session file..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2193 +msgid "Open and browse through records of past whiteboard sessions" +msgstr "" + +#: ../../po/../src/verbs.cpp:2195 +msgid "Session file playback" +msgstr "" + +#: ../../po/../src/verbs.cpp:2197 +msgid "_Disconnect from session" +msgstr "" + +#: ../../po/../src/verbs.cpp:2199 +msgid "Disconnect from _server" +msgstr "" + +#: ../../po/../src/verbs.cpp:2201 +msgid "_Input Devices..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2202 +msgid "Configure extended input devices" +msgstr "" + +#. Help +#: ../../po/../src/verbs.cpp:2205 +msgid "_Keys and Mouse" +msgstr "MiÅ¡ka in _tipkovnica" + +#: ../../po/../src/verbs.cpp:2206 +msgid "Key and mouse shortcuts reference" +msgstr "Spisek bližnjic tipkovnice in miÅ¡ke" + +#: ../../po/../src/verbs.cpp:2207 +msgid "About E_xtensions" +msgstr "O _razÅ¡iritvah" + +#: ../../po/../src/verbs.cpp:2208 +msgid "About Extensions..." +msgstr "O razÅ¡iritvah..." + +#: ../../po/../src/verbs.cpp:2209 +msgid "About _Memory" +msgstr "O _pomnilniku" + +#: ../../po/../src/verbs.cpp:2210 +msgid "About Memory..." +msgstr "O pomnilniku..." + +#: ../../po/../src/verbs.cpp:2211 +msgid "_About Inkscape" +msgstr "_O Inkscape-u" + +#. "help_about" +#. new HelpVerb(SP_VERB_SHOW_LICENSE, "ShowLicense", N_("Modifying or Redistributing Inkscape"), +#. N_("Show license to modify and/or redistribute Inkscape: GNU GPL"), NULL), +#. Tutorials +#: ../../po/../src/verbs.cpp:2217 +msgid "Inkscape: _Basic" +msgstr "Inkscape: _Osnove" + +#: ../../po/../src/verbs.cpp:2218 +msgid "Getting started with Inkscape" +msgstr "Začetki z Inkscapeom" + +#. "tutorial_basic" +#: ../../po/../src/verbs.cpp:2219 +msgid "Inkscape: _Shapes" +msgstr "Inkscape: _Oblike" + +#: ../../po/../src/verbs.cpp:2220 +msgid "Using shape tools to create and edit shapes" +msgstr "Uporabite orodja za risanje likov in spreminjanje njihovih oblik" + +#: ../../po/../src/verbs.cpp:2221 +msgid "Inkscape: _Advanced" +msgstr "Inkscape: _Napredno" + +#: ../../po/../src/verbs.cpp:2222 +msgid "Advanced Inkscape topics" +msgstr "Napredna navodila za uporabo" + +#. "tutorial_advanced" +#. TRANSLATORS: "to trace" means "to convert a bitmap to vector graphics" (to vectorize) +#: ../../po/../src/verbs.cpp:2224 +msgid "Inkscape: T_racing" +msgstr "Inkscape: _Sledenje" + +#: ../../po/../src/verbs.cpp:2225 +msgid "Using bitmap tracing" +msgstr "Uporaba sledenja bitnih slik" + +#. "tutorial_tracing" +#: ../../po/../src/verbs.cpp:2226 +msgid "Inkscape: _Calligraphy" +msgstr "Inkscape: _Kaligrafija" + +#: ../../po/../src/verbs.cpp:2227 +msgid "Using the Calligraphy pen tool" +msgstr "Uporabljate kaligrafsko pero" + +#: ../../po/../src/verbs.cpp:2228 +msgid "_Elements of Design" +msgstr "_Gradniki oblikovanja" + +#: ../../po/../src/verbs.cpp:2229 +msgid "Principles of design in the tutorial form" +msgstr "Vodič s primeri skozi temeljna načela oblikovanja" + +#. "tutorial_design" +#: ../../po/../src/verbs.cpp:2230 +msgid "_Tips and Tricks" +msgstr "_Triki in nasveti" + +#: ../../po/../src/verbs.cpp:2231 +msgid "Miscellaneous tips and tricks" +msgstr "Razni namigi in triki" + +#. "tutorial_tips" +#. Effect +#: ../../po/../src/verbs.cpp:2234 +msgid "Previous Effect" +msgstr "PrejÅ¡nji učinek" + +#: ../../po/../src/verbs.cpp:2235 +msgid "Repeat the last effect with the same settings" +msgstr "Ponovi zadnji učinek z istimi nastavitvami" + +#. "tutorial_tips" +#: ../../po/../src/verbs.cpp:2236 +msgid "Previous Effect Settings..." +msgstr "Nastavitve prejÅ¡njega učinka ..." + +#: ../../po/../src/verbs.cpp:2237 +msgid "Repeat the last effect with new settings" +msgstr "Ponovi prejÅ¡nji učinek z novimi nastavitvami" + +#: ../../po/../src/widgets/dash-selector.cpp:106 +msgid "Dash pattern" +msgstr "Črtkan vzorec" + +#: ../../po/../src/widgets/dash-selector.cpp:121 +msgid "Pattern offset" +msgstr "Zamik vzorca" + +#: ../../po/../src/widgets/desktop-widget.cpp:240 +msgid "Zoom drawing if window size changes" +msgstr "Približaj risbo, če se spremeni velikost okna" + +#: ../../po/../src/widgets/desktop-widget.cpp:298 +msgid "Cursor coordinates" +msgstr "Koordinate kazalca" + +#. display the initial welcome message in the statusbar +#: ../../po/../src/widgets/desktop-widget.cpp:324 +msgid "" +"Welcome to Inkscape! Use shape or freehand tools to create objects; " +"use selector (arrow) to move or transform them." +msgstr "" +"Pozdravljeni v Inkscape. Uporabite orodja za risanje oblik ali " +"prostoročno risanje; uporabite izbirnik (puščico), da jih premikate in " +"spreminjate." + +#: ../../po/../src/widgets/desktop-widget.cpp:372 +#, c-format +msgid "%s: %d - Inkscape" +msgstr "%s: %d - Inkscape" + +#: ../../po/../src/widgets/desktop-widget.cpp:374 +#, c-format +msgid "%s - Inkscape" +msgstr "%s - Inkscape" + +#: ../../po/../src/widgets/desktop-widget.cpp:532 +#, c-format +msgid "" +"Save changes to document \"%s\" before " +"closing?\n" +"\n" +"If you close without saving, your changes will be discarded." +msgstr "" +"Shranim spremembe v dokumentu \"%s\" " +"preden zaprem?\n" +"\n" +"Če zaprete brez shranjevanja, bodo spremembe izgubljene." + +#: ../../po/../src/widgets/desktop-widget.cpp:548 +#: ../../po/../src/widgets/desktop-widget.cpp:612 +msgid "Close _without saving" +msgstr "Zapri _brez shranjevanja" + +#: ../../po/../src/widgets/desktop-widget.cpp:595 +#, c-format +msgid "" +"The file \"%s\" was saved with a " +"format (%s) that may cause data loss!\n" +"\n" +"Do you want to save this file in another format?" +msgstr "" +"Datoteka \"%s\" je bila shranjena v " +"obliki (%s), ki lahko povzroči izgubo poadtkov!\n" +"\n" +"Ali želite shraniti dokument v kaki drugi obliki?" + +#. Family frame +#: ../../po/../src/widgets/font-selector.cpp:156 +msgid "Font family" +msgstr "Družina pisav" + +#. Style frame +#: ../../po/../src/widgets/font-selector.cpp:184 +msgid "Style" +msgstr "Slog" + +#: ../../po/../src/widgets/font-selector.cpp:219 +msgid "Font size:" +msgstr "Velikost pisave:" + +#. TRANSLATORS: Test string used in text and font dialog (when no +#. * text has been entered) to get a preview of the font. Choose +#. * some representative characters that users of your locale will be +#. * interested in. +#: ../../po/../src/widgets/font-selector.cpp:554 +msgid "AaBbCcIiPpQq12368.;/()" +msgstr "AaBbCcIiPpQqŠšČčĆćĐđŽž12368.;/()" + +#: ../../po/../src/widgets/gradient-selector.cpp:137 +#: ../../po/../src/widgets/gradient-toolbar.cpp:524 +msgid "Duplicate" +msgstr "Podvoji" + +#: ../../po/../src/widgets/gradient-selector.cpp:142 +#: ../../po/../src/widgets/gradient-toolbar.cpp:535 +msgid "Edit..." +msgstr "Uredi..." + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/pservers.html#LinearGradientSpreadMethodAttribute +#: ../../po/../src/widgets/gradient-selector.cpp:159 +msgid "" +"Whether to fill with flat color beyond the ends of the gradient vector " +"(spreadMethod=\"pad\"), or repeat the gradient in the same direction " +"(spreadMethod=\"repeat\"), or repeat the gradient in alternating opposite " +"directions (spreadMethod=\"reflect\")" +msgstr "" +"Ali na koncu preliva dokončujemo s čisto barvo (spreadMethod=\"pad\"), ali " +"ponovimo preliv v isti smeri (spreadMethod=\"repeat\"), ali pa ga ponovimo v " +"nasprotni smeri (spreadMethod=\"reflect\")" + +#: ../../po/../src/widgets/gradient-selector.cpp:165 +msgid "none" +msgstr "brez" + +#: ../../po/../src/widgets/gradient-selector.cpp:169 +msgid "reflected" +msgstr "odsevanje" + +#: ../../po/../src/widgets/gradient-selector.cpp:173 +msgid "direct" +msgstr "neposredno" + +#: ../../po/../src/widgets/gradient-selector.cpp:181 +msgid "Repeat:" +msgstr "Ponovi:" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:217 +msgid "No gradients" +msgstr "Ni prelivov" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:226 +msgid "Nothing selected" +msgstr "Ni izbire" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:237 +msgid "No gradients in selection" +msgstr "Izbran ni noben preliv" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:247 +msgid "Multiple gradients" +msgstr "Več prelivov" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:525 +msgid "" +"If the gradient is used by more than one object, create a copy of it for the " +"selected object(s)" +msgstr "" +"Če je preliv uporabljen za več kot en predmet, ustvari kopijo za izbrane " +"predmete" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:536 +msgid "Edit the stops of the gradient" +msgstr "Uredi postanke preliva" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:593 +#: ../../po/../src/widgets/toolbox.cpp:1103 +#: ../../po/../src/widgets/toolbox.cpp:1192 +#: ../../po/../src/widgets/toolbox.cpp:1485 +#: ../../po/../src/widgets/toolbox.cpp:1534 +#: ../../po/../src/widgets/toolbox.cpp:1766 +#: ../../po/../src/widgets/toolbox.cpp:1801 +#: ../../po/../src/widgets/toolbox.cpp:2331 +#: ../../po/../src/widgets/toolbox.cpp:2370 +msgid "New:" +msgstr "Nova:" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:606 +msgid "Create linear gradient" +msgstr "Ustvari raven preliv" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:620 +msgid "Create radial (elliptic or circular) gradient" +msgstr "Ustvari krožni (ali eliptičen) preliv" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:635 +msgid "on" +msgstr "na" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:648 +msgid "Create gradient in the fill" +msgstr "Ustvari preliv na polnilu" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:662 +msgid "Create gradient in the stroke" +msgstr "Ustvari preliv na obrobi" + +#. FIXME: implement averaging of all parameters for multiple selected stars +#. gtk_label_set_markup(GTK_LABEL(l), _("Average:")); +#. FIXME: implement averaging of all parameters for multiple selected +#. gtk_label_set_markup(GTK_LABEL(l), _("Average:")); +#: ../../po/../src/widgets/gradient-toolbar.cpp:676 +#: ../../po/../src/widgets/toolbox.cpp:1105 +#: ../../po/../src/widgets/toolbox.cpp:1124 +#: ../../po/../src/widgets/toolbox.cpp:1493 +#: ../../po/../src/widgets/toolbox.cpp:1518 +#: ../../po/../src/widgets/toolbox.cpp:1768 +#: ../../po/../src/widgets/toolbox.cpp:1787 +#: ../../po/../src/widgets/toolbox.cpp:2334 +#: ../../po/../src/widgets/toolbox.cpp:2354 +msgid "Change:" +msgstr "Spremeni:" + +#: ../../po/../src/widgets/gradient-vector.cpp:269 +msgid "No gradients in document" +msgstr "V dokumentu ni prelivov" + +#: ../../po/../src/widgets/gradient-vector.cpp:275 +msgid "No gradient selected" +msgstr "Izbran ni noben preliv" + +#: ../../po/../src/widgets/gradient-vector.cpp:532 +msgid "No stops in gradient" +msgstr "Preliv brez postankov" + +#. TRANSLATORS: "Stop" means: a "phase" of a gradient +#: ../../po/../src/widgets/gradient-vector.cpp:794 +msgid "Add stop" +msgstr "Dodaj postanek" + +#: ../../po/../src/widgets/gradient-vector.cpp:797 +msgid "Add another control stop to gradient" +msgstr "Dodaj nov postanek za preliv" + +#: ../../po/../src/widgets/gradient-vector.cpp:799 +msgid "Delete stop" +msgstr "IzbriÅ¡i postanek" + +#: ../../po/../src/widgets/gradient-vector.cpp:802 +msgid "Delete current control stop from gradient" +msgstr "IzbriÅ¡i trenuten konec iz preliva" + +#. Label +#: ../../po/../src/widgets/gradient-vector.cpp:813 +msgid "Offset:" +msgstr "Zamik:" + +#. TRANSLATORS: "Stop" means: a "phase" of a gradient +#: ../../po/../src/widgets/gradient-vector.cpp:858 +msgid "Stop Color" +msgstr "Barva za konec" + +#: ../../po/../src/widgets/gradient-vector.cpp:887 +msgid "Gradient editor" +msgstr "Urejevalnik preliva" + +#: ../../po/../src/widgets/layer-selector.cpp:119 +msgid "Toggle current layer visibility" +msgstr "Preklopi vidnost trenutnega sloja" + +#: ../../po/../src/widgets/layer-selector.cpp:139 +msgid "Lock or unlock current layer" +msgstr "Zakleni ali odkleni trenutni sloj" + +#: ../../po/../src/widgets/layer-selector.cpp:142 +msgid "Current layer" +msgstr "Trenutni sloj" + +#: ../../po/../src/widgets/layer-selector.cpp:553 +msgid "(root)" +msgstr "(osnova)" + +#: ../../po/../src/widgets/paint-selector.cpp:182 +#: ../../po/../src/widgets/paint-selector.cpp:561 +msgid "No paint" +msgstr "Ni barve" + +#: ../../po/../src/widgets/paint-selector.cpp:184 +#: ../../po/../src/widgets/paint-selector.cpp:629 +msgid "Flat color" +msgstr "Čista barva" + +#: ../../po/../src/widgets/paint-selector.cpp:186 +#: ../../po/../src/widgets/paint-selector.cpp:696 +msgid "Linear gradient" +msgstr "Raven preliv" + +#: ../../po/../src/widgets/paint-selector.cpp:188 +#: ../../po/../src/widgets/paint-selector.cpp:699 +msgid "Radial gradient" +msgstr "Krožen preliv" + +#: ../../po/../src/widgets/paint-selector.cpp:192 +msgid "Unset paint (make it undefined so it can be inherited)" +msgstr "Prekliči barvo (označi kot nedoločeno, da se jo bo dalo naslediti)" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/painting.html#FillRuleProperty +#: ../../po/../src/widgets/paint-selector.cpp:204 +msgid "" +"Any path self-intersections or subpaths create holes in the fill (fill-rule: " +"evenodd)" +msgstr "" +"Vsako presečišče poti s samo seboj ustvari luknje v polnilu (pravilo: liho-" +"sodo)" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/painting.html#FillRuleProperty +#: ../../po/../src/widgets/paint-selector.cpp:215 +msgid "" +"Fill is solid unless a subpath is counterdirectional (fill-rule: nonzero)" +msgstr "" +"Polnilo je polno, razen če je podpot obratno usmerjena (pravilo: nenič)" + +#: ../../po/../src/widgets/paint-selector.cpp:528 +msgid "No objects" +msgstr "Ni predmetov" + +#: ../../po/../src/widgets/paint-selector.cpp:539 +msgid "Multiple styles" +msgstr "Več slogov" + +#: ../../po/../src/widgets/paint-selector.cpp:550 +msgid "Paint is undefined" +msgstr "Barvanje ni določeno" + +#: ../../po/../src/widgets/paint-selector.cpp:757 +msgid "No patterns in document" +msgstr "V dokumentu ni vzorcev" + +#: ../../po/../src/widgets/paint-selector.cpp:872 +msgid "" +"Use Edit > Object(s) to Pattern to create a new pattern from " +"selection." +msgstr "" +"Uporabite Uredi > Tlakuj, da iz izbranega ustvarite nov vzorec." + +#: ../../po/../src/widgets/select-toolbar.cpp:426 +msgid "Now stroke width is scaled when objects are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:428 +msgid "Now stroke width is not scaled when objects are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:436 +msgid "" +"Now rounded rectangle corners are scaled when rectangles are " +"scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:438 +msgid "" +"Now rounded rectangle corners are not scaled when rectangles " +"are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:446 +msgid "" +"Now gradients are transformed along with their objects when " +"those are transformed (moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:448 +msgid "" +"Now gradients remain fixed when objects are transformed " +"(moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:456 +msgid "" +"Now patterns are transformed along with their objects when " +"those are transformed (moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:458 +msgid "" +"Now patterns remain fixed when objects are transformed (moved, " +"scaled, rotated, or skewed)." +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:506 +msgid "select_toolbar|X" +msgstr "izbiranje|X" + +#: ../../po/../src/widgets/select-toolbar.cpp:506 +msgid "Horizontal coordinate of selection" +msgstr "Vodoravna koordinata izbire" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:511 +msgid "select_toolbar|Y" +msgstr "izbiranje|Y" + +#: ../../po/../src/widgets/select-toolbar.cpp:511 +msgid "Vertical coordinate of selection" +msgstr "Navpična koordinata izbire" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:517 +msgid "select_toolbar|W" +msgstr "izbiranje|W" + +#: ../../po/../src/widgets/select-toolbar.cpp:517 +msgid "Width of selection" +msgstr "Å irina izbire" + +#: ../../po/../src/widgets/select-toolbar.cpp:525 +msgid "Change both width and height by the same proportion" +msgstr "V enakem razmerju spremeni viÅ¡ino in Å¡irino" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:534 +msgid "select_toolbar|H" +msgstr "izbiranje|H" + +#: ../../po/../src/widgets/select-toolbar.cpp:534 +msgid "Height of selection" +msgstr "ViÅ¡ina izbire" + +#: ../../po/../src/widgets/sp-color-gtkselector.cpp:62 +msgid "System" +msgstr "Sistem" + +#: ../../po/../src/widgets/sp-color-notebook.cpp:322 +msgid "RGBA_:" +msgstr "RGBA_:" + +#: ../../po/../src/widgets/sp-color-notebook.cpp:330 +msgid "Hexadecimal RGBA value of the color" +msgstr "Heksadecimalna RGBA vrednost barve" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "RGB" +msgstr "RGB" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "HSL" +msgstr "HSL" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "CMYK" +msgstr "CMYK" + +#: ../../po/../src/widgets/sp-color-scales.cpp:397 +msgid "_R" +msgstr "_R" + +#: ../../po/../src/widgets/sp-color-scales.cpp:398 +#: ../../po/../src/widgets/sp-color-scales.cpp:399 +msgid "Red" +msgstr "Rdeča" + +#: ../../po/../src/widgets/sp-color-scales.cpp:400 +msgid "_G" +msgstr "_G" + +#: ../../po/../src/widgets/sp-color-scales.cpp:401 +#: ../../po/../src/widgets/sp-color-scales.cpp:402 +msgid "Green" +msgstr "Zelena" + +#: ../../po/../src/widgets/sp-color-scales.cpp:403 +msgid "_B" +msgstr "_B" + +#: ../../po/../src/widgets/sp-color-scales.cpp:404 +#: ../../po/../src/widgets/sp-color-scales.cpp:405 +msgid "Blue" +msgstr "Modra" + +#. Label +#: ../../po/../src/widgets/sp-color-scales.cpp:406 +#: ../../po/../src/widgets/sp-color-scales.cpp:432 +#: ../../po/../src/widgets/sp-color-scales.cpp:463 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:141 +msgid "_A" +msgstr "_A" + +#: ../../po/../src/widgets/sp-color-scales.cpp:407 +#: ../../po/../src/widgets/sp-color-scales.cpp:408 +#: ../../po/../src/widgets/sp-color-scales.cpp:433 +#: ../../po/../src/widgets/sp-color-scales.cpp:434 +#: ../../po/../src/widgets/sp-color-scales.cpp:464 +#: ../../po/../src/widgets/sp-color-scales.cpp:465 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:151 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:163 +msgid "Alpha (opacity)" +msgstr "Prosojnost" + +#: ../../po/../src/widgets/sp-color-scales.cpp:423 +msgid "_H" +msgstr "_H" + +#: ../../po/../src/widgets/sp-color-scales.cpp:424 +#: ../../po/../src/widgets/sp-color-scales.cpp:425 +msgid "Hue" +msgstr "Barvnost" + +#: ../../po/../src/widgets/sp-color-scales.cpp:426 +msgid "_S" +msgstr "_S" + +#: ../../po/../src/widgets/sp-color-scales.cpp:427 +#: ../../po/../src/widgets/sp-color-scales.cpp:428 +msgid "Saturation" +msgstr "Nasičenost" + +#: ../../po/../src/widgets/sp-color-scales.cpp:429 +msgid "_L" +msgstr "_L" + +#: ../../po/../src/widgets/sp-color-scales.cpp:430 +#: ../../po/../src/widgets/sp-color-scales.cpp:431 +msgid "Lightness" +msgstr "Svetlost" + +#: ../../po/../src/widgets/sp-color-scales.cpp:451 +msgid "_C" +msgstr "_C" + +#: ../../po/../src/widgets/sp-color-scales.cpp:452 +#: ../../po/../src/widgets/sp-color-scales.cpp:453 +msgid "Cyan" +msgstr "Cijan" + +#: ../../po/../src/widgets/sp-color-scales.cpp:454 +msgid "_M" +msgstr "_M" + +#: ../../po/../src/widgets/sp-color-scales.cpp:455 +#: ../../po/../src/widgets/sp-color-scales.cpp:456 +msgid "Magenta" +msgstr "Magenta" + +#: ../../po/../src/widgets/sp-color-scales.cpp:457 +msgid "_Y" +msgstr "_Y" + +#: ../../po/../src/widgets/sp-color-scales.cpp:458 +#: ../../po/../src/widgets/sp-color-scales.cpp:459 +msgid "Yellow" +msgstr "Rumena" + +#: ../../po/../src/widgets/sp-color-scales.cpp:460 +msgid "_K" +msgstr "_K" + +#: ../../po/../src/widgets/sp-color-selector.cpp:71 +msgid "Unnamed" +msgstr "Brezimen" + +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:68 +msgid "Wheel" +msgstr "Kolešček" + +#: ../../po/../src/widgets/sp-xmlview-attr-list.cpp:53 +msgid "Attribute" +msgstr "Lastnost" + +#: ../../po/../src/widgets/sp-xmlview-attr-list.cpp:54 +msgid "Value" +msgstr "Vrednost" + +#: ../../po/../src/widgets/toolbox.cpp:424 +msgid "Insert new nodes into selected segments" +msgstr "Vstavi vozlišča v izbrane segmente" + +#: ../../po/../src/widgets/toolbox.cpp:426 +msgid "Delete selected nodes" +msgstr "ZbriÅ¡i izbrane točke" + +#: ../../po/../src/widgets/toolbox.cpp:431 +msgid "Join paths at selected nodes" +msgstr "Združi poti ob izbranih vozliščih" + +#: ../../po/../src/widgets/toolbox.cpp:433 +msgid "Join paths at selected nodes with new segment" +msgstr "Združi poti ob izbranih vozliščih z novim odsekom" + +#: ../../po/../src/widgets/toolbox.cpp:436 +msgid "Split path between two non-endpoint nodes" +msgstr "Razcepi pot med dvema srednjima vozliščema" + +#: ../../po/../src/widgets/toolbox.cpp:439 +msgid "Break path at selected nodes" +msgstr "Prelomi pot po izbranih vozliščih" + +#: ../../po/../src/widgets/toolbox.cpp:444 +msgid "Make selected nodes corner" +msgstr "Naj bodo izbrana vozlišča koti" + +#: ../../po/../src/widgets/toolbox.cpp:447 +msgid "Make selected nodes smooth" +msgstr "Naj bodo izbrana vozlišča mehkejÅ¡a" + +#: ../../po/../src/widgets/toolbox.cpp:450 +msgid "Make selected nodes symmetric" +msgstr "Naj bodo izbrana vozlišča simetrična" + +#: ../../po/../src/widgets/toolbox.cpp:455 +msgid "Make selected segments lines" +msgstr "Pretvori izbrane odseke v črte" + +#: ../../po/../src/widgets/toolbox.cpp:458 +msgid "Make selected segments curves" +msgstr "Pretvori izbrane odseke v krivulje" + +#: ../../po/../src/widgets/toolbox.cpp:1199 +msgid "Polygon" +msgstr "Poligon" + +#: ../../po/../src/widgets/toolbox.cpp:1206 +msgid "Regular polygon (with one handle) instead of a star" +msgstr "Običajen poligon (z eno ročico) namesto zvezde" + +#: ../../po/../src/widgets/toolbox.cpp:1218 +msgid "Corners:" +msgstr "Oglišča:" + +#: ../../po/../src/widgets/toolbox.cpp:1218 +msgid "Number of corners of a polygon or star" +msgstr "Å tevilo kotov poligona ali zvezde" + +#: ../../po/../src/widgets/toolbox.cpp:1228 +msgid "Spoke ratio:" +msgstr "Razmerje govora:" + +#. TRANSLATORS: Tip radius of a star is the distance from the center to the farthest handle. +#. Base radius is the same for the closest handle. +#: ../../po/../src/widgets/toolbox.cpp:1231 +msgid "Base radius to tip radius ratio" +msgstr "Razmerje med bližnjo in oddaljeno točko" + +#: ../../po/../src/widgets/toolbox.cpp:1246 +msgid "Rounded:" +msgstr "Zaobljen:" + +#: ../../po/../src/widgets/toolbox.cpp:1246 +msgid "How much rounded are the corners (0 for sharp)" +msgstr "Koliko so koti zaobljeni (0 za ostre)" + +#: ../../po/../src/widgets/toolbox.cpp:1256 +msgid "Randomized:" +msgstr "Naključno:" + +#: ../../po/../src/widgets/toolbox.cpp:1256 +msgid "Scatter randomly the corners and angles" +msgstr "Kote in vogale naključno razporedi" + +#: ../../po/../src/widgets/toolbox.cpp:1269 +#: ../../po/../src/widgets/toolbox.cpp:1838 +#: ../../po/../src/widgets/toolbox.cpp:2061 +msgid "Defaults" +msgstr "Privzeto" + +#: ../../po/../src/widgets/toolbox.cpp:1270 +#: ../../po/../src/widgets/toolbox.cpp:1839 +#: ../../po/../src/widgets/toolbox.cpp:2062 +msgid "" +"Reset shape parameters to defaults (use Inkscape Preferences > Tools to " +"change defaults)" +msgstr "" +"Povrni lastnosti oblike na privzete (uporabite Nastavitve Inkscapea >Orodja " +"za nastavitev privzetih vrednosti)" + +#: ../../po/../src/widgets/toolbox.cpp:1544 +msgid "W:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1544 +#, fuzzy +msgid "Width of rectangle" +msgstr "Å irina izbire" + +#: ../../po/../src/widgets/toolbox.cpp:1556 +#, fuzzy +msgid "Height of rectangle" +msgstr "ViÅ¡ina izbire" + +#: ../../po/../src/widgets/toolbox.cpp:1568 +msgid "Rx:" +msgstr "Rx:" + +#: ../../po/../src/widgets/toolbox.cpp:1568 +msgid "Horizontal radius of rounded corners" +msgstr "Vodoravni polmer zaobljenega kota " + +#: ../../po/../src/widgets/toolbox.cpp:1578 +msgid "Ry:" +msgstr "Ry:" + +#: ../../po/../src/widgets/toolbox.cpp:1578 +msgid "Vertical radius of rounded corners" +msgstr "Navpični polmer zaobljenega kota " + +#: ../../po/../src/widgets/toolbox.cpp:1594 +msgid "Not rounded" +msgstr "Nezaobljeno" + +#: ../../po/../src/widgets/toolbox.cpp:1596 +msgid "Make corners sharp" +msgstr "Naj bodo koti ostri" + +#: ../../po/../src/widgets/toolbox.cpp:1805 +msgid "Turns:" +msgstr "Obrati:" + +#: ../../po/../src/widgets/toolbox.cpp:1805 +msgid "Number of revolutions" +msgstr "Å tevilo obhodov" + +#: ../../po/../src/widgets/toolbox.cpp:1815 +msgid "Divergence:" +msgstr "Divergenca:" + +#: ../../po/../src/widgets/toolbox.cpp:1815 +msgid "How much denser/sparser are outer revolutions; 1 = uniform" +msgstr "Zgoščevanje ali zredčevanje obhodov navzven; 1 = enakomerno" + +#: ../../po/../src/widgets/toolbox.cpp:1825 +msgid "Inner radius:" +msgstr "Notranji polmer:" + +#: ../../po/../src/widgets/toolbox.cpp:1825 +msgid "Radius of the innermost revolution (relative to the spiral size)" +msgstr "Polmer najmanjÅ¡ega obhoda (v razmerju do velikosti spirale)" + +#: ../../po/../src/widgets/toolbox.cpp:1957 +msgid "The width of the calligraphic pen (relative to the visible canvas area)" +msgstr "Debelina kaligrafskega peresa (glede na vidno območje platna)" + +#: ../../po/../src/widgets/toolbox.cpp:1967 +msgid "Thinning:" +msgstr "TanjÅ¡anje:" + +#: ../../po/../src/widgets/toolbox.cpp:1967 +msgid "" +"How much velocity thins the stroke (> 0 makes fast strokes thinner, < 0 " +"makes them broader, 0 makes width independent of velocity)" +msgstr "" +"Koliko hitrost stanjÅ¡a potezo (> 0 pomeni tanjÅ¡e, < 0 pomeni Å¡irÅ¡e, 0 pomeni " +"neodvisno od hitrosti)" + +#: ../../po/../src/widgets/toolbox.cpp:1980 +msgid "Angle:" +msgstr "Kot:" + +#: ../../po/../src/widgets/toolbox.cpp:1980 +msgid "" +"The angle of the pen's nib (in degrees; 0 = horizontal; has no effect if " +"fixation = 0)" +msgstr "" +"Kot vrha peresa (v stopinjah; 0 = vodoravno; nima vpliva, če je nagibanje = " +"0)" + +#: ../../po/../src/widgets/toolbox.cpp:1990 +msgid "Fixation:" +msgstr "Nagibanje:" + +#: ../../po/../src/widgets/toolbox.cpp:1990 +msgid "" +"How fixed is the pen angle (0 = always perpendicular to stroke direction, 1 " +"= fixed)" +msgstr "" +"Koliko je kot peresa nespremenljiv (0 = vedno pravokoten na smer poteze, 1 = " +"stalen)" + +#: ../../po/../src/widgets/toolbox.cpp:2003 +msgid "Mass:" +msgstr "Masa:" + +#: ../../po/../src/widgets/toolbox.cpp:2003 +msgid "How much inertia affects the movement of the pen" +msgstr "Koliko vztrajnost vpliva na gibanje peresa" + +#. TRANSLATORS: "drag" means "resistance" here +#: ../../po/../src/widgets/toolbox.cpp:2014 +msgid "Drag:" +msgstr "Upor:" + +#: ../../po/../src/widgets/toolbox.cpp:2014 +msgid "How much resistance affects the movement of the pen" +msgstr "Koliko upor vpliva na gibanje peresa" + +#: ../../po/../src/widgets/toolbox.cpp:2034 +msgid "Use the pressure of the input device to alter the width of the pen" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2047 +msgid "Use the tilt of the input device to alter the angle of the pen's nib" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2374 +msgid "Start:" +msgstr "Začetek:" + +#: ../../po/../src/widgets/toolbox.cpp:2374 +msgid "The angle (in degrees) from the horizontal to the arc's start point" +msgstr "Kot med vodoravnico in začetno točko loka." + +#: ../../po/../src/widgets/toolbox.cpp:2384 +msgid "End:" +msgstr "Konec:" + +#: ../../po/../src/widgets/toolbox.cpp:2384 +msgid "The angle (in degrees) from the horizontal to the arc's end point" +msgstr "Kot med vodoravnico in končno točko loka." + +#: ../../po/../src/widgets/toolbox.cpp:2395 +msgid "Open arc" +msgstr "Odpri krog" + +#: ../../po/../src/widgets/toolbox.cpp:2396 +msgid "" +"Switch between arc (unclosed shape) and segment (closed shape with two radii)" +msgstr "" +"Izberi med lokom (nezaključena oblika) in odsekom (zaprta oblika z dvema " +"polmeroma)" + +#: ../../po/../src/widgets/toolbox.cpp:2415 +msgid "Make whole" +msgstr "Celota" + +#: ../../po/../src/widgets/toolbox.cpp:2417 +msgid "Make the shape a whole ellipse, not arc or segment" +msgstr "Naj bo predmet cela elipsa in ne le odsek ali lok" + +#: ../../po/../src/widgets/toolbox.cpp:2644 +msgid "" +"When pressed, picks visible color without alpha and when not pressed, picks " +"color including its alpha" +msgstr "" +"Če vključen, izbira neprosojne vidne barve, če izključen, izbira barve " +"skupaj s prosojnostjo" + +#: ../../po/../src/widgets/toolbox.cpp:3039 +#, fuzzy +msgid "Make connectors avoid selected objects" +msgstr "Presek izbranih predmetov" + +#: ../../po/../src/widgets/toolbox.cpp:3043 +#, fuzzy +msgid "Make connectors ignore selected objects" +msgstr "Presek izbranih predmetov" + +#. +#. 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 : +#: ../share/extensions/addnodes.inx.h:1 +#, fuzzy +msgid "Add Nodes" +msgstr "Vozlišča" + +#: ../share/extensions/addnodes.inx.h:2 +msgid "Maximum Segment Length" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:1 +msgid "AI Input" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:2 ../share/extensions/ai_output.inx.h:2 +msgid "Adobe Illustrator (*.ai)" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:3 +msgid "Open files saved with Adobe Illustrator" +msgstr "" + +#: ../share/extensions/ai_output.inx.h:1 +#, fuzzy +msgid "AI Output" +msgstr "Izvoz" + +#: ../share/extensions/ai_output.inx.h:3 +msgid "Write Adobe Illustrator" +msgstr "" + +#: ../share/extensions/dia.inx.h:1 +msgid "A diagram created with the program Dia" +msgstr "" + +#: ../share/extensions/dia.inx.h:2 +msgid "Dia Diagram (*.dia)" +msgstr "" + +#: ../share/extensions/dia.inx.h:3 +msgid "Dia Input" +msgstr "" + +#: ../share/extensions/dia.inx.h:4 +msgid "" +"In order to import Dia files, Dia itself must be installed. You can get Dia " +"at http://www.gnome.org/projects/dia/" +msgstr "" + +#: ../share/extensions/dia.inx.h:5 +msgid "" +"The dia2svg.sh script should be installed with your Inkscape distribution. " +"If you do not have it, there is likely to be something wrong with your " +"Inkscape installation." +msgstr "" + +#: ../share/extensions/dots.inx.h:1 +#, fuzzy +msgid "Connect the Dots" +msgstr "Avtor" + +#: ../share/extensions/dots.inx.h:2 +#, fuzzy +msgid "Dot Size" +msgstr "Velikost" + +#: ../share/extensions/dots.inx.h:3 +#, fuzzy +msgid "Font Size" +msgstr "Velikost pisave:" + +#: ../share/extensions/dropshadow.inx.h:1 +msgid "Color of shadow" +msgstr "" + +#: ../share/extensions/dropshadow.inx.h:2 +#, fuzzy +msgid "Dropshadow" +msgstr "Kaži senco strani" + +#: ../share/extensions/dxf_input.inx.h:1 +#: ../share/extensions/dxf_output.inx.h:1 +msgid "AutoCAD DXF (*.dxf)" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:2 +msgid "DXF Input" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:3 +msgid "Import AutoCAD's Document Exchange Format" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:4 +msgid "" +"dxf2svg may come with Inkscape, but is also at http://dxf-svg-convert." +"sourceforge.net/" +msgstr "" + +#: ../share/extensions/dxf_output.inx.h:2 +#, fuzzy +msgid "DXF Output" +msgstr "Izvoz" + +#: ../share/extensions/dxf_output.inx.h:3 +msgid "DXF file written by pstoedit" +msgstr "" + +#: ../share/extensions/dxf_output.inx.h:4 +msgid "pstoedit must be installed to run see http://www.pstoedit.net/pstoedit" +msgstr "" + +#: ../share/extensions/embedimage.inx.h:1 +#, fuzzy +msgid "Embed Images" +msgstr "Slike" + +#: ../share/extensions/eps_input.inx.h:1 +msgid "EPS Input" +msgstr "" + +#: ../share/extensions/eps_input.inx.h:2 +msgid "Encapsulated Postscript" +msgstr "" + +#: ../share/extensions/eps_input.inx.h:3 +msgid "Encapsulated Postscript (*.eps)" +msgstr "" + +#: ../share/extensions/epsi_output.inx.h:1 +#, fuzzy +msgid "EPSI Output" +msgstr "Izvoz" + +#: ../share/extensions/epsi_output.inx.h:2 +msgid "Encapsulated Postscript Interchange (*.epsi)" +msgstr "" + +#: ../share/extensions/epsi_output.inx.h:3 +msgid "Encapsulated Postscript with a thumbnail" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:1 ../share/extensions/ffms.inx.h:1 +#: ../share/extensions/ffset.inx.h:1 ../share/extensions/ffss.inx.h:1 +#, fuzzy +msgid "Bridge Width" +msgstr "Å irina črte" + +#: ../share/extensions/ffmet.inx.h:2 ../share/extensions/ffms.inx.h:2 +msgid "First String Length" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:3 +msgid "FretFind Multi Length ET" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:4 ../share/extensions/ffms.inx.h:4 +#: ../share/extensions/ffset.inx.h:3 ../share/extensions/ffss.inx.h:3 +msgid "Fretboard Edges" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:5 ../share/extensions/ffms.inx.h:5 +msgid "Last String Length" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:6 ../share/extensions/ffms.inx.h:6 +#: ../share/extensions/ffset.inx.h:4 ../share/extensions/ffss.inx.h:4 +#, fuzzy +msgid "Number of Frets" +msgstr "Å tevilo vrstic" + +#: ../share/extensions/ffmet.inx.h:7 ../share/extensions/ffms.inx.h:7 +#: ../share/extensions/ffset.inx.h:5 ../share/extensions/ffss.inx.h:5 +#, fuzzy +msgid "Number of Strings" +msgstr "Å tevilo vrstic" + +#: ../share/extensions/ffmet.inx.h:8 ../share/extensions/ffms.inx.h:8 +#: ../share/extensions/ffset.inx.h:6 ../share/extensions/ffss.inx.h:6 +#, fuzzy +msgid "Nut Width" +msgstr "Å irina" + +#: ../share/extensions/ffmet.inx.h:9 ../share/extensions/ffms.inx.h:10 +msgid "Perpendicular Distance" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:10 ../share/extensions/ffset.inx.h:7 +msgid "Scale Base (2 for Octave)" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:11 ../share/extensions/ffset.inx.h:9 +msgid "Tones in Scale" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:12 ../share/extensions/ffms.inx.h:12 +#: ../share/extensions/ffset.inx.h:10 ../share/extensions/ffss.inx.h:10 +msgid "px per Unit" +msgstr "" + +#: ../share/extensions/ffms.inx.h:3 +msgid "FretFind Multi Length Scala" +msgstr "" + +#: ../share/extensions/ffms.inx.h:9 ../share/extensions/ffss.inx.h:7 +msgid "Path to Scala *.scl File" +msgstr "" + +#: ../share/extensions/ffms.inx.h:11 +msgid "Tuning (scale step for each string seperated by semicolons)" +msgstr "" + +#: ../share/extensions/ffset.inx.h:2 +msgid "FretFind Single Length ET" +msgstr "" + +#: ../share/extensions/ffset.inx.h:8 ../share/extensions/ffss.inx.h:8 +msgid "Scale Length" +msgstr "" + +#: ../share/extensions/ffss.inx.h:2 +msgid "FretFind Single Length Scala" +msgstr "" + +#: ../share/extensions/ffss.inx.h:9 +msgid "Tuning (Scale step for each string seperated by semicolons)" +msgstr "" + +#: ../share/extensions/handles.inx.h:1 +#, fuzzy +msgid "Draw Handles" +msgstr "RiÅ¡i prostoročno " + +#: ../share/extensions/interp.inx.h:1 +#, fuzzy +msgid "Duplicate Endpaths" +msgstr "Podvoji vozlišče" + +#: ../share/extensions/interp.inx.h:2 +#, fuzzy +msgid "Exponent" +msgstr "Izvozi" + +#: ../share/extensions/interp.inx.h:3 +msgid "Interpolate" +msgstr "" + +#: ../share/extensions/interp.inx.h:4 +msgid "Interpolate Style (Experimental)" +msgstr "" + +#: ../share/extensions/interp.inx.h:5 +msgid "Interpolation Method" +msgstr "" + +#: ../share/extensions/interp.inx.h:6 +msgid "Interpolation Steps" +msgstr "" + +#: ../share/extensions/kochify.inx.h:1 +msgid "Kochify" +msgstr "" + +#: ../share/extensions/kochify_load.inx.h:1 +msgid "Kochify (Load)" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:1 +#, fuzzy +msgid "Angle" +msgstr "Kot:" + +#: ../share/extensions/lindenmayer.inx.h:2 +msgid "Axiom" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:3 +#, fuzzy +msgid "Lindenmayer" +msgstr "Preimenuj sloj" + +#: ../share/extensions/lindenmayer.inx.h:4 +msgid "Order" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:5 +#, fuzzy +msgid "Rules" +msgstr "_Ravnila" + +#: ../share/extensions/lindenmayer.inx.h:6 +#, fuzzy +msgid "Step" +msgstr "Korakov" + +#: ../share/extensions/motion.inx.h:1 +#, fuzzy +msgid "Direction" +msgstr "Opis" + +#: ../share/extensions/motion.inx.h:2 +#, fuzzy +msgid "Magnitude" +msgstr "Magenta" + +#: ../share/extensions/motion.inx.h:3 +#, fuzzy +msgid "Motion" +msgstr "V_rtenje" + +#: ../share/extensions/pdf_output.inx.h:1 +msgid "Adobe PDF (*.pdf)" +msgstr "" + +#: ../share/extensions/pdf_output.inx.h:2 +msgid "Adobe Portable Document Format" +msgstr "" + +#: ../share/extensions/pdf_output.inx.h:3 +#, fuzzy +msgid "PDF Output" +msgstr "Izvoz" + +#: ../share/extensions/ps_input.inx.h:1 +#, fuzzy +msgid "Postscript" +msgstr "Pokončno" + +#: ../share/extensions/ps_input.inx.h:2 +msgid "Postscript (*.ps)" +msgstr "" + +#: ../share/extensions/ps_input.inx.h:3 +msgid "Postscript Input" +msgstr "" + +#: ../share/extensions/radiusrand.inx.h:1 +#, fuzzy +msgid "Radius" +msgstr "_Dvigni" + +#: ../share/extensions/radiusrand.inx.h:2 +#, fuzzy +msgid "Radius Randomize" +msgstr "Naključno:" + +#: ../share/extensions/radiusrand.inx.h:3 +msgid "Randomize Control Points" +msgstr "" + +#: ../share/extensions/radiusrand.inx.h:4 +#, fuzzy +msgid "Randomize Nodes" +msgstr "Naključno:" + +#: ../share/extensions/rtree.inx.h:1 +#, fuzzy +msgid "Initial Size" +msgstr "Velikost slike" + +#: ../share/extensions/rtree.inx.h:2 +msgid "Minimum Size" +msgstr "" + +#: ../share/extensions/rtree.inx.h:3 +#, fuzzy +msgid "Random Tree" +msgstr "Naključno:" + +#: ../share/extensions/sk_input.inx.h:1 +msgid "A diagram created with the program Sketch" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:2 +msgid "Sketch Diagram (*.sk)" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:3 +msgid "Sketch Input" +msgstr "" + +#: ../share/extensions/straightseg.inx.h:1 +msgid "Behavior" +msgstr "" + +#: ../share/extensions/straightseg.inx.h:3 +msgid "Segment Straightener" +msgstr "" + +#: ../share/extensions/summersnight.inx.h:1 +msgid "Summer's Night" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:1 +#: ../share/extensions/svgz_output.inx.h:1 +msgid "Compressed Inkscape SVG (*.svgz)" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:2 +#: ../share/extensions/svgz_output.inx.h:2 +msgid "Inkscape's native file format compressed with GZip" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:3 +msgid "SVGZ Input" +msgstr "" + +#: ../share/extensions/svgz_output.inx.h:3 +#, fuzzy +msgid "SVGZ Output" +msgstr "Izvoz" + +#: ../share/extensions/txt2svg.inx.h:1 +msgid "ASCII Text" +msgstr "" + +#: ../share/extensions/txt2svg.inx.h:2 +msgid "Text File (*.txt)" +msgstr "" + +#: ../share/extensions/txt2svg.inx.h:3 +msgid "Text Input" +msgstr "" + +#: ../share/extensions/wavy.inx.h:1 +msgid "Calculate first derivative numerically" +msgstr "" + +#: ../share/extensions/wavy.inx.h:2 +msgid "First derivative" +msgstr "" + +#: ../share/extensions/wavy.inx.h:3 +msgid "Function" +msgstr "" + +#: ../share/extensions/wavy.inx.h:4 +msgid "Function Plotter" +msgstr "" + +#: ../share/extensions/wavy.inx.h:5 +msgid "Nodes per period" +msgstr "" + +#: ../share/extensions/wavy.inx.h:6 +msgid "Periods (2*Pi each)" +msgstr "" + +#: ../share/extensions/whirl.inx.h:1 +msgid "Amount of Whirl" +msgstr "" + +#: ../share/extensions/whirl.inx.h:2 +#, fuzzy +msgid "Center X" +msgstr "Črte poravnaj sredinsko" + +#: ../share/extensions/whirl.inx.h:3 +#, fuzzy +msgid "Center Y" +msgstr "Črte poravnaj sredinsko" + +#: ../share/extensions/whirl.inx.h:4 +#, fuzzy +msgid "Direction of Rotation" +msgstr "Spusti izbrano na dno" + +#: ../share/extensions/whirl.inx.h:5 +msgid "Whirl" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:1 +msgid "A popular graphics file format for clipart" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:2 +msgid "Windows Metafile (*.wmf)" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:3 +msgid "Windows Metafile Input" +msgstr "" + +#~ msgid "Custom canvas" +#~ msgstr "Platno po meri" + +#~ msgid "Current style" +#~ msgstr "Trenuten slog" + +#~ msgid "" +#~ "Current style is updated every time you change the style of any object " +#~ "(its fill, stroke, transparency, etc.)" +#~ msgstr "" +#~ "Trenuten slog orodja je posodobljen ob vsaki spremembi kateregakoli " +#~ "predmeta (polnilo, prosojnost ...)" + +#~ msgid "Arrange Objects" +#~ msgstr "Razporedi predmete" + +#~ msgid "deg" +#~ msgstr "stopinj" + +#~ msgid "" +#~ "%s is not a valid preferences file.\n" +#~ "%s" +#~ msgstr "" +#~ "Datoteka %s ne vsebuje nastavitev.\n" +#~ "%s" + +#~ msgid "" +#~ "Inkscape will run with default settings.\n" +#~ "New settings will not be saved." +#~ msgstr "" +#~ "Inkscape se bo zagnal s privzetimi nastavitvami.\n" +#~ "Nove nastavitve ne bodo shranjene." + +#, fuzzy +#~ msgid "_Credits" +#~ msgstr "Zahvale" + +#~ msgid "Grab sensitivity" +#~ msgstr "Občutljivost oprijema" + +#~ msgid "Click/drag threshold" +#~ msgstr "Prag natančnosti miÅ¡ke" + +#~ msgid "Mouse wheel scrolls by" +#~ msgstr "Kolešček premika po" + +#~ msgid "Scroll by" +#~ msgstr "Preskakuj po" + +#~ msgid "Acceleration" +#~ msgstr "PospeÅ¡ek" + +#~ msgid "Speed" +#~ msgstr "Hitrost" + +#~ msgid "Threshold" +#~ msgstr "Prag" + +#~ msgid "Arrow keys move by" +#~ msgstr "Smerne tipke premikajo za" + +#~ msgid "> and < scale by" +#~ msgstr "> in < raztegujeta po" + +#~ msgid "Inset/Outset by" +#~ msgstr "RazÅ¡iri/zoži za" + +#~ msgid "Rotation snaps every" +#~ msgstr "Vrtenje se ustavi vsakih" + +#~ msgid "Zoom in/out by" +#~ msgstr "Povečaj/pomanjÅ¡aj za" + +#~ msgid "Transform" +#~ msgstr "Preoblikuj" + +#~ msgid "Flip selection horizontally" +#~ msgstr "Prevrni izbrano vodoravno" + +#~ msgid "Flip selection vertically" +#~ msgstr "Prevrni izbrano navpično" + +#, fuzzy +#~ msgid "Could not read next message due to I/O error (error: %s)!" +#~ msgstr "Datoteke z zapisi o napakah razÅ¡irirtve '%s' ni mogoče ustvariti." + +#~ msgid "Open one of the recently visited documents" +#~ msgstr "Odpri nedavno uporabljan dokument" + +#~ msgid "" +#~ "Show or hide parts of the document window (differently for normal and " +#~ "fullscreen modes)" +#~ msgstr "" +#~ "Kaži ali skrij nekatere dele okna z dokumentom (v običajnem ali " +#~ "celozaslonskem načinu)." + +#~ msgid "Interactive Inkscape tutorials" +#~ msgstr "Vodiči po Inkscape-u" + +#~ msgid "gpl-2.svg" +#~ msgstr "gpl-2.svg" + +#~ msgid "Modifying or Redistributing Inkscape" +#~ msgstr "O spreminjanju in razÅ¡irjanju Inkscape-a" + +#~ msgid "Show license to modify and/or redistribute Inkscape: GNU GPL" +#~ msgstr "" +#~ "Pokaži licenco, ki določa pravice spreminjanja in razÅ¡irjanja Inkscape-a: " +#~ "GNU GPL" + +#~ msgid "Edit" +#~ msgstr "Uredi" + +#~ msgid "Add" +#~ msgstr "Dodaj" diff --git a/po/sr.po b/po/sr.po new file mode 100644 index 000000000..5a9d812aa --- /dev/null +++ b/po/sr.po @@ -0,0 +1,9526 @@ +# Serbian translation of inkscape +# Courtesy of Prevod.org team (http://prevod.org/) -- 2004, 2005 +# +# This file is distributed under the same license as the inkscape package. +# +# Maintainer: Александар Урошевић +# +msgid "" +msgstr "" +"Project-Id-Version: Inkscape 0.42\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2005-12-04 11:51-0800\n" +"PO-Revision-Date: 2005-07-08 01:23+0200\n" +"Last-Translator: Александар Урошевић \n" +"Language-Team: Serbian (sr) \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: ../inkscape.desktop.in.h:1 +msgid "Create and edit Scalable Vector Graphics images" +msgstr "Прављење и уређивање SVG векторских слика" + +#: ../inkscape.desktop.in.h:2 +msgid "Inkscape SVG Vector Illustrator" +msgstr "Inkscape — програм за векторско цртање" + +#: ../../po/../src/arc-context.cpp:350 +msgid "" +"Ctrl: make circle or integer-ratio ellipse, snap arc/segment angle" +msgstr "" +"Ctrl: прави кружницу или пропорционалну елипсу, пријања на утао/лук" + +#: ../../po/../src/arc-context.cpp:351 ../../po/../src/rect-context.cpp:388 +msgid "Shift: draw around the starting point" +msgstr "Shift: исцртава објекат са центром у почетној тачки" + +#: ../../po/../src/arc-context.cpp:413 +#: ../../po/../src/connector-context.cpp:493 +#: ../../po/../src/dyna-draw-context.cpp:506 +#: ../../po/../src/pen-context.cpp:329 ../../po/../src/pencil-context.cpp:208 +#: ../../po/../src/rect-context.cpp:452 ../../po/../src/spiral-context.cpp:421 +#: ../../po/../src/star-context.cpp:427 +msgid "Current layer is hidden. Unhide it to be able to draw on it." +msgstr "" +"Активни слој је сакривен. Укините сакривање како би могли да цртате " +"на њему." + +#: ../../po/../src/arc-context.cpp:417 +#: ../../po/../src/connector-context.cpp:497 +#: ../../po/../src/dyna-draw-context.cpp:510 +#: ../../po/../src/pen-context.cpp:336 ../../po/../src/pencil-context.cpp:212 +#: ../../po/../src/rect-context.cpp:456 ../../po/../src/spiral-context.cpp:426 +#: ../../po/../src/star-context.cpp:431 +msgid "Current layer is locked. Unlock it to be able to draw on it." +msgstr "" +"Активни слој је закључан. Откључајте га како би могли да цртте на " +"њему." + +#: ../../po/../src/arc-context.cpp:496 +#, fuzzy, c-format +msgid "" +"Ellipse: %s × %s; with Ctrl to make circle or integer-" +"ratio ellipse; with Shift to draw around the starting point" +msgstr "" +"Елипса: %s x %s; притисните Ctrl за исцртавање кружнице или " +"пропорционалне елипсе; притисните Shift за исцртавање око почетне " +"тачке" + +#: ../../po/../src/connector-context.cpp:518 +#, fuzzy +msgid "Creating new connector" +msgstr "Прављење нове криве" + +#: ../../po/../src/connector-context.cpp:939 +#, fuzzy +msgid "Finishing connector" +msgstr "Завршавање оловке" + +#: ../../po/../src/connector-context.cpp:1108 +msgid "Connection point: click or drag to create a new connector" +msgstr "" + +#: ../../po/../src/connector-context.cpp:1185 +msgid "Connector endpoint: drag to reroute or connect to new shapes" +msgstr "" + +#: ../../po/../src/connector-context.cpp:1278 +#, fuzzy +msgid "Select at least one non-connector object." +msgstr "Изаберите најмање два објекта за груписање." + +#: ../../po/../src/desktop-events.cpp:238 +#, c-format +msgid "%s at %s" +msgstr "%s на %s" + +#. TRANSLATORS: This string appears when double-clicking on a guide. +#. This is the distance by which the guide is to be moved. +#: ../../po/../src/desktop-events.cpp:277 +msgid " relative by " +msgstr " у односу на " + +#. TRANSLATORS: This string appears when double-clicking on a guide. +#. This is the target location where the guide is to be moved. +#: ../../po/../src/desktop-events.cpp:282 +#: ../../po/../src/desktop-events.cpp:395 +msgid " absolute to " +msgstr " апсолутно на " + +#. create dialog +#: ../../po/../src/desktop-events.cpp:348 +msgid "Guideline" +msgstr "Вођице" + +#: ../../po/../src/desktop-events.cpp:432 +#, c-format +msgid "Move %s" +msgstr "Помери %s" + +#: ../../po/../src/desktop.cpp:678 +msgid "No previous zoom." +msgstr "Нема више умањења." + +#: ../../po/../src/desktop.cpp:703 +msgid "No next zoom." +msgstr "Нема више увећања." + +#: ../../po/../src/dialogs/clonetiler.cpp:182 +msgid "Nothing selected." +msgstr "Ништа није изабрано." + +#: ../../po/../src/dialogs/clonetiler.cpp:188 +msgid "More than one object selected." +msgstr "Изабрано је више од једног објекта." + +#: ../../po/../src/dialogs/clonetiler.cpp:195 +#, c-format +msgid "Object has %d tiled clones." +msgstr "Објекат има %d поплочаних клонова." + +#: ../../po/../src/dialogs/clonetiler.cpp:200 +msgid "Object has no tiled clones." +msgstr "Објекат нема поплочане клонове" + +#: ../../po/../src/dialogs/clonetiler.cpp:865 +msgid "Select one object whose tiled clones to unclump." +msgstr "Изаберите објекат са наслаганим клоновима за раздвајање." + +#: ../../po/../src/dialogs/clonetiler.cpp:916 +msgid "Select one object whose tiled clones to remove." +msgstr "Изаберите објекат са наслаганим клоновима за уклањање." + +#: ../../po/../src/dialogs/clonetiler.cpp:984 +#: ../../po/../src/selection-chemistry.cpp:1774 +msgid "Select an object to clone." +msgstr "Изаберите објекат за клонирање." + +#: ../../po/../src/dialogs/clonetiler.cpp:990 +#: ../../po/../src/selection-chemistry.cpp:1780 +msgid "" +"If you want to clone several objects, group them and clone the " +"group." +msgstr "" +"Ако желите да клонирате више објеката, групишите их па клонирајте " +"групу." + +#: ../../po/../src/dialogs/clonetiler.cpp:1484 +msgid "Per row:" +msgstr "По реду:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1497 +msgid "Per column:" +msgstr "По колони:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1505 +msgid "Randomize:" +msgstr "Насумично:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1656 +msgid "_Symmetry" +msgstr "_Симетрија" + +#. TRANSLATORS: For the following 17 symmetry groups, see +#. * http://www.bib.ulb.ac.be/coursmath/doc/17.htm (visual examples); +#. * http://www.clarku.edu/~djoyce/wallpaper/seventeen.html (English vocabulary); or +#. * http://membres.lycos.fr/villemingerard/Geometri/Sym1D.htm (French vocabulary). +#. +#: ../../po/../src/dialogs/clonetiler.cpp:1664 +msgid "Select one of the 17 symmetry groups for the tiling" +msgstr "Изаберите једну од 17 симетричних група за поплочавање" + +#. TRANSLATORS: "translation" means "shift" / "displacement" here. +#: ../../po/../src/dialogs/clonetiler.cpp:1675 +msgid "P1: simple translation" +msgstr "P1: једноставно премештање" + +#: ../../po/../src/dialogs/clonetiler.cpp:1676 +msgid "P2: 180° rotation" +msgstr "P2: 180° ротација" + +#: ../../po/../src/dialogs/clonetiler.cpp:1677 +msgid "PM: reflection" +msgstr "PM: рефлексија" + +#. TRANSLATORS: "glide reflection" is a reflection and a translation combined. +#. For more info, see http://mathforum.org/sum95/suzanne/symsusan.html +#: ../../po/../src/dialogs/clonetiler.cpp:1680 +msgid "PG: glide reflection" +msgstr "PG: рефлексија са померајем" + +#: ../../po/../src/dialogs/clonetiler.cpp:1681 +msgid "CM: reflection + glide reflection" +msgstr "CM: рефлексија + рефлексија са померајем" + +#: ../../po/../src/dialogs/clonetiler.cpp:1682 +msgid "PMM: reflection + reflection" +msgstr "PMM: рефлексија + рефлексија" + +#: ../../po/../src/dialogs/clonetiler.cpp:1683 +msgid "PMG: reflection + 180° rotation" +msgstr "PMG: рефлексија + 180° ротација" + +#: ../../po/../src/dialogs/clonetiler.cpp:1684 +msgid "PGG: glide reflection + 180° rotation" +msgstr "PGG: рефлексија са померајем + 180° ротација" + +#: ../../po/../src/dialogs/clonetiler.cpp:1685 +msgid "CMM: reflection + reflection + 180° rotation" +msgstr "CMM: рефлексија + рефлексија + 180° ротација" + +#: ../../po/../src/dialogs/clonetiler.cpp:1686 +msgid "P4: 90° rotation" +msgstr "P4: 90° ротација" + +#: ../../po/../src/dialogs/clonetiler.cpp:1687 +msgid "P4M: 90° rotation + 45° reflection" +msgstr "P4M: 90° ротација + 45° рефлексија" + +#: ../../po/../src/dialogs/clonetiler.cpp:1688 +msgid "P4G: 90° rotation + 90° reflection" +msgstr "P4G: 90° ротација + 90° рефлексија" + +#: ../../po/../src/dialogs/clonetiler.cpp:1689 +msgid "P3: 120° rotation" +msgstr "P3: 120° ротација" + +#: ../../po/../src/dialogs/clonetiler.cpp:1690 +msgid "P31M: reflection + 120° rotation, dense" +msgstr "P31M: рефлексија + 120° ротација, згуснуто" + +#: ../../po/../src/dialogs/clonetiler.cpp:1691 +msgid "P3M1: reflection + 120° rotation, sparse" +msgstr "P3M1: рефлексија + 120° ротација, растегнуто" + +#: ../../po/../src/dialogs/clonetiler.cpp:1692 +msgid "P6: 60° rotation" +msgstr "P6: 60° ротација" + +#: ../../po/../src/dialogs/clonetiler.cpp:1693 +msgid "P6M: reflection + 60° rotation" +msgstr "P6M: рефлексија + 60° ротација" + +#: ../../po/../src/dialogs/clonetiler.cpp:1721 +msgid "S_hift" +msgstr "_Померај" + +#. TRANSLATORS: "shift" means: the tiles will be shifted (offset) horizontally by this amount +#: ../../po/../src/dialogs/clonetiler.cpp:1731 +#, no-c-format +msgid "Shift X:" +msgstr "Померај X:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1739 +#, no-c-format +msgid "Horizontal shift per row (in % of tile width)" +msgstr "Водоравни померај реда (у % ширине објекта)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1747 +#, no-c-format +msgid "Horizontal shift per column (in % of tile width)" +msgstr "Водоравни померај колоне (у % ширине објекта)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1754 +msgid "Randomize the horizontal shift by this percentage" +msgstr "Насумични водоравни померај за овај проценат" + +#. TRANSLATORS: "shift" means: the tiles will be shifted (offset) vertically by this amount +#: ../../po/../src/dialogs/clonetiler.cpp:1764 +#, no-c-format +msgid "Shift Y:" +msgstr "Померај Y:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1772 +#, no-c-format +msgid "Vertical shift per row (in % of tile height)" +msgstr "Усправни померај реда (у % висине објекта)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1780 +#, no-c-format +msgid "Vertical shift per column (in % of tile height)" +msgstr "Усправни померај колоне (у % висине објекта)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1787 +msgid "Randomize the vertical shift by this percentage" +msgstr "Насумични усправни померај за овај проценат" + +#: ../../po/../src/dialogs/clonetiler.cpp:1795 +msgid "Exponent:" +msgstr "Експонент:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1802 +msgid "Whether rows are spaced evenly (1), converge (<1) or diverge (>1)" +msgstr "" +"Да ли су редови раздвојени подједнако (1), спојено (<1) или раздвојено (>1)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1809 +msgid "Whether columns are spaced evenly (1), converge (<1) or diverge (>1)" +msgstr "" +"Да ли су колоне раздвојене подједнако (1), спојено (<1) или раздвојено (>1)" + +#. TRANSLATORS: "Alternate" is a verb here +#: ../../po/../src/dialogs/clonetiler.cpp:1817 +#: ../../po/../src/dialogs/clonetiler.cpp:1907 +#: ../../po/../src/dialogs/clonetiler.cpp:1966 +#: ../../po/../src/dialogs/clonetiler.cpp:2022 +#: ../../po/../src/dialogs/clonetiler.cpp:2153 +msgid "Alternate:" +msgstr "Извртање:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1823 +msgid "Alternate the sign of shifts for each row" +msgstr "Наизменични померај (плус/минус) за сваки ред" + +#: ../../po/../src/dialogs/clonetiler.cpp:1828 +msgid "Alternate the sign of shifts for each column" +msgstr "Наизменични померај (плус/минус) за сваку колону" + +#: ../../po/../src/dialogs/clonetiler.cpp:1837 +msgid "Sc_ale" +msgstr "Ра_змера" + +#: ../../po/../src/dialogs/clonetiler.cpp:1845 +msgid "Scale X:" +msgstr "Размера X" + +#: ../../po/../src/dialogs/clonetiler.cpp:1853 +#, no-c-format +msgid "Horizontal scale per row (in % of tile width)" +msgstr "Водоравна размера по реду (у % ширине објекта)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1861 +#, no-c-format +msgid "Horizontal scale per column (in % of tile width)" +msgstr "Водоравна размера по колони (у % ширине објекта)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1868 +msgid "Randomize the horizontal scale by this percentage" +msgstr "Насумична водоравна размера за овај проценат" + +#: ../../po/../src/dialogs/clonetiler.cpp:1876 +msgid "Scale Y:" +msgstr "Размера Y:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1884 +#, no-c-format +msgid "Vertical scale per row (in % of tile height)" +msgstr "Усправна размера по реду (у % висине објекта)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1892 +#, no-c-format +msgid "Vertical scale per column (in % of tile height)" +msgstr "Усправна размера по колони (у % висине објекта)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1899 +msgid "Randomize the vertical scale by this percentage" +msgstr "Насумична усправна размера за овај проценат" + +#: ../../po/../src/dialogs/clonetiler.cpp:1913 +msgid "Alternate the sign of scales for each row" +msgstr "Наизменична размера сваког реда" + +#: ../../po/../src/dialogs/clonetiler.cpp:1918 +msgid "Alternate the sign of scales for each column" +msgstr "Наизменични размера сваке колоне" + +#: ../../po/../src/dialogs/clonetiler.cpp:1927 +msgid "_Rotation" +msgstr "_Ротација" + +#: ../../po/../src/dialogs/clonetiler.cpp:1935 +msgid "Angle:" +msgstr "Угао:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1943 +#, no-c-format +msgid "Rotate tiles by this angle for each row" +msgstr "Ротација објекта за овај угао у сваком реду" + +#: ../../po/../src/dialogs/clonetiler.cpp:1951 +#, no-c-format +msgid "Rotate tiles by this angle for each column" +msgstr "Ротација објекта за овај угао у свакој колони" + +#: ../../po/../src/dialogs/clonetiler.cpp:1958 +msgid "Randomize the rotation angle by this percentage" +msgstr "Насумичан угао ротације за овај проценат" + +#: ../../po/../src/dialogs/clonetiler.cpp:1972 +msgid "Alternate the rotation direction for each row" +msgstr "Наизменичан смер ротације у сваком реду" + +#: ../../po/../src/dialogs/clonetiler.cpp:1977 +msgid "Alternate the rotation direction for each column" +msgstr "Наизменичан смер ротације у свакој колони" + +#: ../../po/../src/dialogs/clonetiler.cpp:1985 +msgid "_Opacity" +msgstr "Про_видност" + +#: ../../po/../src/dialogs/clonetiler.cpp:1993 +msgid "Fade out:" +msgstr "Исчезавање:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2000 +msgid "Decrease tile opacity by this percentage for each row" +msgstr "Повећавање провидности објекта за овај проценат у сваком реду" + +#: ../../po/../src/dialogs/clonetiler.cpp:2007 +msgid "Decrease tile opacity by this percentage for each column" +msgstr "Повећавање провидности објекта за овај проценат у свакој колони" + +#: ../../po/../src/dialogs/clonetiler.cpp:2014 +msgid "Randomize the tile opacity by this percentage" +msgstr "Произвољна провидност објекта за овај проценат" + +#: ../../po/../src/dialogs/clonetiler.cpp:2028 +msgid "Alternate the sign of opacity change for each row" +msgstr "Наизменична провидност у сваком реду" + +#: ../../po/../src/dialogs/clonetiler.cpp:2033 +msgid "Alternate the sign of opacity change for each column" +msgstr "Наизменична провидност у свакој колони" + +#: ../../po/../src/dialogs/clonetiler.cpp:2041 +msgid "Co_lor" +msgstr "Бо_ја" + +#: ../../po/../src/dialogs/clonetiler.cpp:2046 +msgid "Initial color: " +msgstr "Почетна боја:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2050 +msgid "Initial color of tiled clones" +msgstr "Почетна боја појединачног клона" + +#: ../../po/../src/dialogs/clonetiler.cpp:2050 +msgid "" +"Initial color for clones (works only if the original has unset fill or " +"stroke)" +msgstr "" +"Почетна боја за клонове (има ефекта само ако оригинал нема постављену попуну " +"и боју ивичне линије)" + +#: ../../po/../src/dialogs/clonetiler.cpp:2065 +msgid "H:" +msgstr "Н:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2072 +msgid "Change the tile hue by this percentage for each row" +msgstr "Промена нијансе објекта за овај проценат у сваком реду" + +#: ../../po/../src/dialogs/clonetiler.cpp:2079 +msgid "Change the tile hue by this percentage for each column" +msgstr "Промена нијансе објекта за овај проценат у свакој колони" + +#: ../../po/../src/dialogs/clonetiler.cpp:2086 +msgid "Randomize the tile hue by this percentage" +msgstr "Насумична нијанса објекта за овај проценат" + +#: ../../po/../src/dialogs/clonetiler.cpp:2095 +msgid "S:" +msgstr "З" + +#: ../../po/../src/dialogs/clonetiler.cpp:2102 +msgid "Change the color saturation by this percentage for each row" +msgstr "Промена засићености боје за овај проценат у сваком реду" + +#: ../../po/../src/dialogs/clonetiler.cpp:2109 +msgid "Change the color saturation by this percentage for each column" +msgstr "Промена засићености боје за овај проценат у свакој колони" + +#: ../../po/../src/dialogs/clonetiler.cpp:2116 +msgid "Randomize the color saturation by this percentage" +msgstr "Насумична засићеност боје за овај проценат" + +#: ../../po/../src/dialogs/clonetiler.cpp:2124 +msgid "L:" +msgstr "О:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2131 +msgid "Change the color lightness by this percentage for each row" +msgstr "Промена осветљености боје за овај проценат у сваком реду" + +#: ../../po/../src/dialogs/clonetiler.cpp:2138 +msgid "Change the color lightness by this percentage for each column" +msgstr "Промена осветљености боје за овај проценат у свакој колони" + +#: ../../po/../src/dialogs/clonetiler.cpp:2145 +msgid "Randomize the color lightness by this percentage" +msgstr "Насумична осветљеност боје за овај проценат" + +#: ../../po/../src/dialogs/clonetiler.cpp:2159 +msgid "Alternate the sign of color changes for each row" +msgstr "Наизменична боја у сваком реду" + +#: ../../po/../src/dialogs/clonetiler.cpp:2164 +msgid "Alternate the sign of color changes for each column" +msgstr "Наизменична обја у свакој колони" + +#: ../../po/../src/dialogs/clonetiler.cpp:2172 +msgid "_Trace" +msgstr "_Прецртавање" + +#: ../../po/../src/dialogs/clonetiler.cpp:2179 +msgid "Trace the drawing under the tiles" +msgstr "Прецртавање цртежа испод поплочаних објеката" + +#: ../../po/../src/dialogs/clonetiler.cpp:2183 +msgid "" +"For each clone, pick a value from the drawing in that clone's location and " +"apply it to the clone" +msgstr "" +"За сваки клон, узима се вредност са цртежа са површине клона и примењује се " +"на клон" + +#: ../../po/../src/dialogs/clonetiler.cpp:2197 +msgid "1. Pick from the drawing:" +msgstr "1. Узми са цртежа:" + +#. ----Hbox2 +#: ../../po/../src/dialogs/clonetiler.cpp:2208 +#: ../../po/../src/dialogs/clonetiler.cpp:2355 +#: ../../po/../src/ui/dialog/tracedialog.cpp:445 +msgid "Color" +msgstr "Боју" + +#: ../../po/../src/dialogs/clonetiler.cpp:2209 +msgid "Pick the visible color and opacity" +msgstr "Узима видљиву боју и провидност" + +#: ../../po/../src/dialogs/clonetiler.cpp:2216 +#: ../../po/../src/dialogs/clonetiler.cpp:2365 +#: ../share/extensions/dropshadow.inx.h:3 +msgid "Opacity" +msgstr "Провидност" + +#: ../../po/../src/dialogs/clonetiler.cpp:2217 +msgid "Pick the total accumulated opacity" +msgstr "Узима укупну нагомилану провидност" + +#: ../../po/../src/dialogs/clonetiler.cpp:2224 +msgid "R" +msgstr "Ц" + +#: ../../po/../src/dialogs/clonetiler.cpp:2225 +msgid "Pick the Red component of the color" +msgstr "Узмиа црвену компоненту боје" + +#: ../../po/../src/dialogs/clonetiler.cpp:2232 +msgid "G" +msgstr "З" + +#: ../../po/../src/dialogs/clonetiler.cpp:2233 +msgid "Pick the Green component of the color" +msgstr "Узима зелену компоненту боје" + +#: ../../po/../src/dialogs/clonetiler.cpp:2240 +msgid "B" +msgstr "П" + +#: ../../po/../src/dialogs/clonetiler.cpp:2241 +msgid "Pick the Blue component of the color" +msgstr "Узима плаву компоненту боје" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2250 +msgid "clonetiler|H" +msgstr "Клонирана плочица|Н" + +#: ../../po/../src/dialogs/clonetiler.cpp:2251 +msgid "Pick the hue of the color" +msgstr "Узима нијансу боје" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2260 +msgid "clonetiler|S" +msgstr "Клонирана плочица|З" + +#: ../../po/../src/dialogs/clonetiler.cpp:2261 +msgid "Pick the saturation of the color" +msgstr "Узима засићеност боје" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2270 +msgid "clonetiler|L" +msgstr "Клонирана плочица|О" + +#: ../../po/../src/dialogs/clonetiler.cpp:2271 +msgid "Pick the lightness of the color" +msgstr "Узима осветљеност боје" + +#: ../../po/../src/dialogs/clonetiler.cpp:2281 +msgid "2. Tweak the picked value:" +msgstr "2. Подешавање узете вредности" + +#: ../../po/../src/dialogs/clonetiler.cpp:2291 +msgid "Gamma-correct:" +msgstr "Корекција гаме:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2296 +msgid "Shift the mid-range of the picked value upwards (>0) or downwards (<0)" +msgstr "Помера средњи ниво узете вредности навише (>0) или надоле (<0)" + +#: ../../po/../src/dialogs/clonetiler.cpp:2303 +msgid "Randomize:" +msgstr "Насумично:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2308 +msgid "Randomize the picked value by this percentage" +msgstr "Насумично узимање вредности за овај проценат" + +#: ../../po/../src/dialogs/clonetiler.cpp:2315 +msgid "Invert:" +msgstr "Преокретање:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2319 +msgid "Invert the picked value" +msgstr "Преокретање узете вредности" + +#: ../../po/../src/dialogs/clonetiler.cpp:2325 +msgid "3. Apply the value to the clones':" +msgstr "3. Примена вредности на клонове:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2335 +msgid "Presence" +msgstr "Понашање" + +#: ../../po/../src/dialogs/clonetiler.cpp:2338 +msgid "" +"Each clone is created with the probability determined by the picked value in " +"that point" +msgstr "" +"Сваки клон је направљен са особинама прорачунатим из узете вредности у тој " +"тачки" + +#: ../../po/../src/dialogs/clonetiler.cpp:2345 +msgid "Size" +msgstr "Величина" + +#: ../../po/../src/dialogs/clonetiler.cpp:2348 +msgid "Each clone's size is determined by the picked value in that point" +msgstr "" +"Сваки клон има величину прорачунату на основу узете вредности у тој тачки" + +#: ../../po/../src/dialogs/clonetiler.cpp:2358 +msgid "" +"Each clone is painted by the picked color (the original must have unset fill " +"or stroke)" +msgstr "" +"Сваки клон се боји узетом бојом (оригинал не сме да има постављену попуну " +"или боју ивичне линије)" + +#: ../../po/../src/dialogs/clonetiler.cpp:2368 +msgid "Each clone's opacity is determined by the picked value in that point" +msgstr "" +"Провидност сваког клона се рачуна на основу узете вредности у тој тачки" + +#: ../../po/../src/dialogs/clonetiler.cpp:2395 +msgid "How many rows in the tiling" +msgstr "Колико ће редова имати поплочана површина" + +#: ../../po/../src/dialogs/clonetiler.cpp:2415 +msgid "How many columns in the tiling" +msgstr "Колико ће колона имати поплочана површина" + +#: ../../po/../src/dialogs/clonetiler.cpp:2445 +msgid "Width of the rectangle to be filled" +msgstr "Ширина површине која ће се попунити" + +#: ../../po/../src/dialogs/clonetiler.cpp:2470 +msgid "Height of the rectangle to be filled" +msgstr "Висина површине која ће се попунити" + +#: ../../po/../src/dialogs/clonetiler.cpp:2485 +msgid "Rows, columns: " +msgstr "Редова, колона: " + +#: ../../po/../src/dialogs/clonetiler.cpp:2486 +msgid "Create the specified number of rows and columns" +msgstr "Направи одређени број редова и колона" + +#: ../../po/../src/dialogs/clonetiler.cpp:2495 +msgid "Width, height: " +msgstr "Ширина, висина: " + +#: ../../po/../src/dialogs/clonetiler.cpp:2496 +msgid "Fill the specified width and height with the tiling" +msgstr "Попуни одређену ширину и висину поплочавањем" + +#: ../../po/../src/dialogs/clonetiler.cpp:2512 +msgid "Use saved size and position of the tile" +msgstr "Користи сачувану величину и положај објекта" + +#: ../../po/../src/dialogs/clonetiler.cpp:2515 +msgid "" +"Pretend that the size and position of the tile are the same as the last time " +"you tiled it (if any), instead of using the current size" +msgstr "" +"Узми да су величина и позиција објекта исте као и предходног пута када је " +"поплочан (ако јесте), уместо коришћења тренутне величине" + +#: ../../po/../src/dialogs/clonetiler.cpp:2539 +msgid " _Create " +msgstr " _Направи " + +#: ../../po/../src/dialogs/clonetiler.cpp:2541 +msgid "Create and tile the clones of the selection" +msgstr "Направи и поплочај клонове изабраног објекта" + +#. TRANSLATORS: if a group of objects are "clumped" together, then they +#. are unevenly spread in the given amount of space - as shown in the +#. diagrams on the left in the following screenshot: +#. http://www.inkscape.org/screenshots/gallery/inkscape-0.42-CVS-tiles-unclump.png +#. So unclumping is the process of spreading a number of objects out more evenly. +#: ../../po/../src/dialogs/clonetiler.cpp:2556 +msgid " _Unclump " +msgstr " _Растави " + +#: ../../po/../src/dialogs/clonetiler.cpp:2557 +msgid "Spread out clones to reduce clumping; can be applied repeatedly" +msgstr "Растављање клонова да би се разредили; може се узастопно примењивати" + +#: ../../po/../src/dialogs/clonetiler.cpp:2563 +msgid " Re_move " +msgstr " _Уклони " + +#: ../../po/../src/dialogs/clonetiler.cpp:2564 +msgid "Remove existing tiled clones of the selected object (siblings only)" +msgstr "" +"Уклања постојеће поплочане клонове изабраног објекта (само истог нивоа)" + +#: ../../po/../src/dialogs/clonetiler.cpp:2580 +msgid " R_eset " +msgstr " _Васпостави " + +#. TRANSLATORS: "change" is a noun here +#: ../../po/../src/dialogs/clonetiler.cpp:2582 +msgid "" +"Reset all shifts, scales, rotates, opacity and color changes in the dialog " +"to zero" +msgstr "" +"Враћа све параметре помераја, размере, ротације, провидности и боје у " +"дијалогу на нулу." + +#: ../../po/../src/dialogs/color-picker.cpp:280 +msgid "Close" +msgstr "Затвори" + +#: ../../po/../src/dialogs/debugdialog.cpp:138 +msgid "Messages" +msgstr "Поруке" + +#. ## Add a menu for clear() +#: ../../po/../src/dialogs/debugdialog.cpp:144 +#: ../../po/../src/menus-skeleton.h:16 +#: ../../po/../src/ui/dialog/messages.cpp:56 +#: ../../po/../src/ui/dialog/scriptdialog.cpp:181 +msgid "_File" +msgstr "_Датотека" + +#. TRANSLATORS: "Clear" is a verb here +#: ../../po/../src/dialogs/debugdialog.cpp:145 +#: ../../po/../src/dialogs/find.cpp:753 +#: ../../po/../src/ui/dialog/messages.cpp:57 +#: ../../po/../src/ui/dialog/scriptdialog.cpp:182 +msgid "_Clear" +msgstr "_Очисти" + +#: ../../po/../src/dialogs/debugdialog.cpp:147 +#: ../../po/../src/ui/dialog/messages.cpp:59 +msgid "Capture log messages" +msgstr "Бележи поруке дневника рада" + +#: ../../po/../src/dialogs/debugdialog.cpp:149 +#: ../../po/../src/ui/dialog/messages.cpp:61 +msgid "Release log messages" +msgstr "Заустави бележење порука дневника рада" + +#. Notebook tab +#: ../../po/../src/dialogs/desktop-properties.cpp:909 +#: ../../po/../src/ui/dialog/document-preferences.cpp:89 +#: ../../po/../src/ui/widget/panel.cpp:107 +msgid "Grid" +msgstr "Мрежа" + +#. Checkbuttons +#. / \todo FIXME: gray out snapping when grid is off +#. / \todo FIXME: gray out snapping when grid is off. +#. / Dissenting view: you want snapping without grid. +#: ../../po/../src/dialogs/desktop-properties.cpp:917 +#: ../../po/../src/ui/dialog/document-preferences.cpp:179 +msgid "Show grid" +msgstr "Прикажи мрежу" + +#: ../../po/../src/dialogs/desktop-properties.cpp:917 +#: ../../po/../src/ui/dialog/document-preferences.cpp:179 +#: ../../po/../src/verbs.cpp:2115 +msgid "Show or hide grid" +msgstr "Прикажи или сакриј мрежу" + +#: ../../po/../src/dialogs/desktop-properties.cpp:918 +#: ../../po/../src/ui/dialog/document-preferences.cpp:180 +msgid "Snap bounding boxes to grid" +msgstr "Пријањање контејнера уз мрежу" + +#: ../../po/../src/dialogs/desktop-properties.cpp:918 +#: ../../po/../src/dialogs/desktop-properties.cpp:1001 +#: ../../po/../src/ui/dialog/document-preferences.cpp:181 +#: ../../po/../src/ui/dialog/document-preferences.cpp:236 +msgid "Snap the edges of the object bounding boxes" +msgstr "Пријањање ивица контејнера објекта" + +#: ../../po/../src/dialogs/desktop-properties.cpp:919 +#: ../../po/../src/ui/dialog/document-preferences.cpp:183 +#, fuzzy +msgid "Snap nodes to grid" +msgstr "Пријањање тачака уз мрежу" + +#: ../../po/../src/dialogs/desktop-properties.cpp:919 +#: ../../po/../src/dialogs/desktop-properties.cpp:1002 +#: ../../po/../src/ui/dialog/document-preferences.cpp:184 +#: ../../po/../src/ui/dialog/document-preferences.cpp:239 +msgid "Snap path nodes, text baselines, ellipse centers, etc." +msgstr "Пријањање чворова криве, основе текста, центра елипсе, и сл." + +#: ../../po/../src/dialogs/desktop-properties.cpp:937 +#: ../../po/../src/ui/dialog/document-preferences.cpp:186 +msgid "Grid units:" +msgstr "Јединица мере мреже:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:939 +#: ../../po/../src/ui/dialog/document-preferences.cpp:187 +msgid "Origin X:" +msgstr "Почетак X:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:942 +#: ../../po/../src/ui/dialog/document-preferences.cpp:189 +msgid "Origin Y:" +msgstr "Почетак Y:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:945 +#: ../../po/../src/ui/dialog/document-preferences.cpp:191 +msgid "Spacing X:" +msgstr "Водоравни корак:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:948 +#: ../../po/../src/ui/dialog/document-preferences.cpp:193 +msgid "Spacing Y:" +msgstr "Усправни корак:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:952 +#: ../../po/../src/dialogs/desktop-properties.cpp:1013 +#: ../../po/../src/ui/dialog/document-preferences.cpp:195 +#: ../../po/../src/ui/dialog/document-preferences.cpp:241 +msgid "Snap units:" +msgstr "Јединица мере пријањања:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:955 +#: ../../po/../src/dialogs/desktop-properties.cpp:1016 +#: ../../po/../src/ui/dialog/document-preferences.cpp:196 +#: ../../po/../src/ui/dialog/document-preferences.cpp:242 +msgid "Snap distance:" +msgstr "Удаљеност за пријањање:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:958 +#: ../../po/../src/ui/dialog/document-preferences.cpp:199 +msgid "Grid line color:" +msgstr "Боја линија мреже:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:959 +#: ../../po/../src/ui/dialog/document-preferences.cpp:199 +msgid "Grid line color" +msgstr "Боја линија мреже" + +#: ../../po/../src/dialogs/desktop-properties.cpp:959 +#: ../../po/../src/ui/dialog/document-preferences.cpp:200 +msgid "Color of grid lines" +msgstr "Боја линија мреже" + +#: ../../po/../src/dialogs/desktop-properties.cpp:961 +#: ../../po/../src/ui/dialog/document-preferences.cpp:201 +msgid "Major grid line color:" +msgstr "Боја главних линија мреже:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:962 +#: ../../po/../src/ui/dialog/document-preferences.cpp:201 +msgid "Major grid line color" +msgstr "Боја главних линија мреже" + +#: ../../po/../src/dialogs/desktop-properties.cpp:962 +#: ../../po/../src/ui/dialog/document-preferences.cpp:202 +msgid "Color of the major (highlighted) grid lines" +msgstr "Боја главних (истакнутих) линија мреже" + +#: ../../po/../src/dialogs/desktop-properties.cpp:965 +#: ../../po/../src/ui/dialog/document-preferences.cpp:204 +msgid "Major grid line every:" +msgstr "Главне линије мреже на:" + +#. TRANSLATORS: This belongs to the "Major grid line every:" string, +#. see grid settings in the "Document Preferences" dialog +#: ../../po/../src/dialogs/desktop-properties.cpp:977 +#: ../../po/../src/ui/dialog/document-preferences.cpp:204 +msgid "lines" +msgstr "линија" + +#. Guidelines page +#: ../../po/../src/dialogs/desktop-properties.cpp:991 +#: ../../po/../src/ui/dialog/document-preferences.cpp:90 +msgid "Guides" +msgstr "Вођице" + +#. / \todo FIXME: gray out snapping when guides are off +#. / Dissenting view: you want snapping without guides. +#: ../../po/../src/dialogs/desktop-properties.cpp:1000 +#: ../../po/../src/ui/dialog/document-preferences.cpp:234 +msgid "Show guides" +msgstr "Прикажи вођице" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1000 +#: ../../po/../src/ui/dialog/document-preferences.cpp:234 +#: ../../po/../src/verbs.cpp:2116 +msgid "Show or hide guides" +msgstr "Прикажи или сакриј вођице" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1001 +#: ../../po/../src/ui/dialog/document-preferences.cpp:235 +msgid "Snap bounding boxes to guides" +msgstr "Пријањање контејнера уз вођице" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1002 +#: ../../po/../src/ui/dialog/document-preferences.cpp:238 +msgid "Snap points to guides" +msgstr "Пријањање тачака уз вођице" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1020 +#: ../../po/../src/ui/dialog/document-preferences.cpp:243 +msgid "Guide color:" +msgstr "Боја вођица:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1021 +#: ../../po/../src/ui/dialog/document-preferences.cpp:243 +msgid "Guideline color" +msgstr "Боја вођица" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1021 +#: ../../po/../src/ui/dialog/document-preferences.cpp:244 +msgid "Color of guidelines" +msgstr "Боја водећих линија" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1023 +#: ../../po/../src/ui/dialog/document-preferences.cpp:245 +msgid "Highlight color:" +msgstr "Боја истакнутих вођица:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1024 +#: ../../po/../src/ui/dialog/document-preferences.cpp:245 +msgid "Highlighted guideline color" +msgstr "Боја истакнутих вођица" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1024 +#: ../../po/../src/ui/dialog/document-preferences.cpp:246 +msgid "Color of a guideline when it is under mouse" +msgstr "Боја водеће линије када је испод курсора" + +#. Page page +#: ../../po/../src/dialogs/desktop-properties.cpp:1029 +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:855 +#: ../../po/../src/ui/dialog/document-preferences.cpp:88 +#: ../../po/../src/widgets/desktop-widget.cpp:1061 +msgid "Page" +msgstr "Страна" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1039 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +msgid "Background:" +msgstr "Позадина:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1040 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +msgid "Background color" +msgstr "Боја позадине" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1041 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +msgid "" +"Color and transparency of the page background (also used for bitmap export)" +msgstr "" +"Боја и провидност позадине стране (такође се корсти за извоз у битмапирану " +"слику)" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1045 +#: ../../po/../src/ui/dialog/document-preferences.cpp:147 +#, fuzzy +msgid "Show page border" +msgstr "Прикажи оквир платна" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1049 +#: ../../po/../src/ui/dialog/document-preferences.cpp:148 +msgid "Border on top of drawing" +msgstr "Оквир изнад цртежа" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1052 +#: ../../po/../src/ui/dialog/document-preferences.cpp:149 +msgid "Border color:" +msgstr "Боја оквира:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1053 +#: ../../po/../src/ui/dialog/document-preferences.cpp:149 +#, fuzzy +msgid "Page border color" +msgstr "Боја линије оквира платна" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1054 +#: ../../po/../src/ui/dialog/document-preferences.cpp:150 +#, fuzzy +msgid "Color of the page border" +msgstr "Боја оквира платна" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1059 +#: ../../po/../src/ui/dialog/document-preferences.cpp:152 +msgid "Show page shadow" +msgstr "Прикажи сенку стране" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1063 +#: ../../po/../src/ui/dialog/document-preferences.cpp:153 +msgid "Default units:" +msgstr "Подразумеване јединице мере:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1069 +msgid "Units for the tool controls, ruler, and the statusbar" +msgstr "Јединица мере за алате, лењире и статусну линију" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1086 +#: ../../po/../src/ui/widget/page-sizer.cpp:209 +#, fuzzy +msgid "Page size:" +msgstr "Величина платна:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1110 +#: ../../po/../src/ui/widget/page-sizer.cpp:219 +msgid "Custom" +msgstr "Прилагођено" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1121 +#: ../../po/../src/ui/widget/page-sizer.cpp:225 +#, fuzzy +msgid "Page orientation:" +msgstr "Оријентација платна:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1133 +#: ../../po/../src/ui/widget/page-sizer.cpp:232 +msgid "Landscape" +msgstr "Водоравно" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1139 +#: ../../po/../src/ui/widget/page-sizer.cpp:234 +msgid "Portrait" +msgstr "Усправно" + +#. Custom paper frame +#: ../../po/../src/dialogs/desktop-properties.cpp:1148 +#: ../../po/../src/ui/widget/page-sizer.cpp:249 +#, fuzzy +msgid "Custom size" +msgstr "Прилагођено" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1160 +#: ../../po/../src/dialogs/export.cpp:269 +#: ../../po/../src/ui/widget/page-sizer.cpp:261 +msgid "Units:" +msgstr "Јединица мере:" + +#. Stroke width +#: ../../po/../src/dialogs/desktop-properties.cpp:1162 +#: ../../po/../src/dialogs/export.cpp:310 +#: ../../po/../src/dialogs/object-attributes.cpp:55 +#: ../../po/../src/dialogs/stroke-style.cpp:985 +#: ../../po/../src/ui/widget/page-sizer.cpp:262 +#: ../../po/../src/widgets/toolbox.cpp:1957 +msgid "Width:" +msgstr "Ширина:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1183 +#: ../../po/../src/dialogs/export.cpp:326 +#: ../../po/../src/dialogs/export.cpp:431 +#: ../../po/../src/dialogs/object-attributes.cpp:56 +#: ../../po/../src/ui/widget/page-sizer.cpp:263 +msgid "Height:" +msgstr "Висина:" + +#. +#. * Ownership metadata tab +#. +#: ../../po/../src/dialogs/desktop-properties.cpp:1206 +msgid "Metadata" +msgstr "Допунске информације" + +#. add license selector pull-down +#: ../../po/../src/dialogs/desktop-properties.cpp:1225 +msgid "License" +msgstr "Лиценца" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1255 +msgid "Proprietary" +msgstr "Власништво" + +#: ../../po/../src/dialogs/display-settings.cpp:212 +msgid "When transforming, show:" +msgstr "Прикажи при померању и трансформацији" + +#: ../../po/../src/dialogs/display-settings.cpp:223 +msgid "Objects" +msgstr "Објекат" + +#: ../../po/../src/dialogs/display-settings.cpp:224 +msgid "Show the actual objects when moving or transforming" +msgstr "Прикажи прави објекат при померању или трансформацији" + +#: ../../po/../src/dialogs/display-settings.cpp:231 +msgid "Box outline" +msgstr "Оквир контејнера" + +#: ../../po/../src/dialogs/display-settings.cpp:232 +msgid "Show only a box outline of the objects when moving or transforming" +msgstr "Прикажи само оквир контејнера објекта при померању или трансформацији" + +#: ../../po/../src/dialogs/display-settings.cpp:238 +msgid "Per-object selection cue:" +msgstr "Обележавање изабраног објекта" + +#. sorationsnapsperpi == 0 means no snapping +#: ../../po/../src/dialogs/display-settings.cpp:249 +#: ../../po/../src/dialogs/display-settings.cpp:386 +#: ../../po/../src/dialogs/display-settings.cpp:441 +#: ../../po/../src/dialogs/display-settings.cpp:1482 +#: ../../po/../src/dialogs/stroke-style.cpp:791 +#: ../../po/../src/interface.cpp:741 +#: ../../po/../src/ui/widget/selected-style.cpp:100 +#: ../../po/../src/verbs.cpp:1842 +msgid "None" +msgstr "Без ознака" + +#: ../../po/../src/dialogs/display-settings.cpp:250 +msgid "No per-object selection indication" +msgstr "Изабрани објекат нема видљиве ознаке" + +#: ../../po/../src/dialogs/display-settings.cpp:256 +msgid "Mark" +msgstr "Са ознаком" + +#: ../../po/../src/dialogs/display-settings.cpp:257 +msgid "Each selected object has a diamond mark in the top left corner" +msgstr "Сваки изабрани објекат има ознаку у облику ромба у горњем левом углу" + +#: ../../po/../src/dialogs/display-settings.cpp:264 +msgid "Box" +msgstr "Оквир" + +#: ../../po/../src/dialogs/display-settings.cpp:265 +msgid "Each selected object displays its bounding box" +msgstr "Сваки одабрани објекат се означава оквиром контејнера" + +#: ../../po/../src/dialogs/display-settings.cpp:270 +msgid "Default scale origin:" +msgstr "Подразумевана основа за промену величине:" + +#: ../../po/../src/dialogs/display-settings.cpp:281 +msgid "Opposite bounding box edge" +msgstr "Супротне ивице контејнера" + +#: ../../po/../src/dialogs/display-settings.cpp:282 +msgid "Default scale origin will be on the bounding box of the item" +msgstr "" +"Подразумевана основа за промену величине ће бити оквир контејнера објекта" + +#: ../../po/../src/dialogs/display-settings.cpp:288 +msgid "Farthest opposite node" +msgstr "Највише удаљени чворови" + +#: ../../po/../src/dialogs/display-settings.cpp:289 +msgid "Default scale origin will be on the bounding box of the item's points" +msgstr "" +"Подразумевана основа за промену величине ће бити простор између " +"најудаљенијих чворова објекта" + +#: ../../po/../src/dialogs/display-settings.cpp:341 +msgid "degrees" +msgstr "степени" + +#: ../../po/../src/dialogs/display-settings.cpp:350 +msgid "" +"Rotating with Ctrl pressed snaps every that much degrees; also, pressing " +"[ or ] rotates by this amount" +msgstr "" +"Ротација са притиснутим Ctrl пријања за оволико степени; такође, притискање " +"[ или ] ротира објекат за ову вредност" + +#: ../../po/../src/dialogs/display-settings.cpp:407 +msgid "Rotation snaps every:" +msgstr "Ротација пријања на сваких:" + +#: ../../po/../src/dialogs/display-settings.cpp:430 +msgid "" +"None: dialogs are treated as regular windows; Normal: dialogs stay on top of " +"document windows; Aggressive: same as Normal but may work better with some " +"window managers." +msgstr "" +"Ништа: дијалози се третирају као обични прозори; Нормално: дијалози остају " +"на врху прозора документа; Агресивно: исто као Нормално али ће боље радити " +"са неким менаџерима прозора." + +#: ../../po/../src/dialogs/display-settings.cpp:451 +msgid "Normal" +msgstr "Нормално" + +#: ../../po/../src/dialogs/display-settings.cpp:461 +msgid "Aggressive" +msgstr "Агресивно" + +#: ../../po/../src/dialogs/display-settings.cpp:475 +msgid "Dialogs on top:" +msgstr "Прозорчићи на врху:" + +#: ../../po/../src/dialogs/display-settings.cpp:645 +msgid "Show selection cue" +msgstr "Прикажи обележивач" + +#: ../../po/../src/dialogs/display-settings.cpp:646 +msgid "" +"Whether selected objects display a selection cue (the same as in selector)" +msgstr "Увек када се за изабрани објекат приказује ознака (као код изборника)" + +#: ../../po/../src/dialogs/display-settings.cpp:657 +msgid "Enable gradient editing" +msgstr "Омогући уређивач прелива" + +#: ../../po/../src/dialogs/display-settings.cpp:658 +msgid "Whether selected objects display gradient editing controls" +msgstr "Приказује контролне тачке за уређивање прелива кад се изабере објекат" + +#: ../../po/../src/dialogs/display-settings.cpp:719 +msgid "No objects selected to take the style from." +msgstr "Нема изабраног објекта од кога ће се преузети стил." + +#: ../../po/../src/dialogs/display-settings.cpp:728 +msgid "" +"More than one object selected. Cannot take style from multiple " +"objects." +msgstr "" +"Изабрано је више од једног објекта. Није могуће узети стил од више " +"објеката." + +#: ../../po/../src/dialogs/display-settings.cpp:767 +msgid "Create new objects with:" +msgstr "Прављење новог објекта са:" + +#: ../../po/../src/dialogs/display-settings.cpp:777 +msgid "Take from selection" +msgstr "Узми из избора" + +#: ../../po/../src/dialogs/display-settings.cpp:778 +msgid "Remember the style of the (first) selected object as this tool's style" +msgstr "Упамти стил (првог) изабраног објекта као стил овог алата" + +#: ../../po/../src/dialogs/display-settings.cpp:782 +#, fuzzy +msgid "Last used style" +msgstr "Убаци _стил" + +#: ../../po/../src/dialogs/display-settings.cpp:782 +msgid "Apply the style you last set on an object" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:790 +msgid "This tool's own style:" +msgstr "Лични стил овог алата:" + +#: ../../po/../src/dialogs/display-settings.cpp:790 +msgid "" +"Each tool may store its own style to apply to the newly created objects. Use " +"the button below to set it." +msgstr "" +"Сваки алат може да има лични стил који ће се применити на новонаправљене " +"објекте. Употребите дугме испод да видите стил." + +#. Mouse +#: ../../po/../src/dialogs/display-settings.cpp:877 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:55 +msgid "Mouse" +msgstr "Миш" + +#. TRANSLATORS: "Grab" is a noun here. "Grab sensitivity" is intended to mean how +#. * close on the screen you need to be to an object to be able to grab it with mouse (in +#. * pixels). +#: ../../po/../src/dialogs/display-settings.cpp:883 +msgid "Grab sensitivity:" +msgstr "Осетљивост хватања:" + +#: ../../po/../src/dialogs/display-settings.cpp:884 +msgid "" +"How close on the screen you need to be to an object to be able to grab it " +"with mouse (in screen pixels)" +msgstr "" +"Колико је потребно да курсор буде близу објекта на екрану како би се он " +"могао изабрати кликом миша (у екранским пикселима)" + +#: ../../po/../src/dialogs/display-settings.cpp:885 +#: ../../po/../src/dialogs/display-settings.cpp:897 +#: ../../po/../src/dialogs/display-settings.cpp:912 +#: ../../po/../src/dialogs/display-settings.cpp:930 +#: ../../po/../src/dialogs/display-settings.cpp:970 +msgid "pixels" +msgstr "тачака" + +#: ../../po/../src/dialogs/display-settings.cpp:895 +msgid "Click/drag threshold:" +msgstr "Праг клика/помераја:" + +#: ../../po/../src/dialogs/display-settings.cpp:896 +msgid "" +"Maximum mouse drag (in screen pixels) which is considered a click, not a drag" +msgstr "" +"Максималан померај (у пикселима екрана) који се третира као клик, а не као " +"померај" + +#. Scrolling +#: ../../po/../src/dialogs/display-settings.cpp:907 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:56 +msgid "Scrolling" +msgstr "Померање" + +#: ../../po/../src/dialogs/display-settings.cpp:910 +msgid "Mouse wheel scrolls by:" +msgstr "Точкић миша помера за:" + +#: ../../po/../src/dialogs/display-settings.cpp:911 +msgid "" +"One mouse wheel notch scrolls by this distance in screen pixels " +"(horizontally with Shift)" +msgstr "" +"Један корак точкића миша помера екран за овај корак у пикселима екрана (за " +"водоравно померање користите Shift)" + +#: ../../po/../src/dialogs/display-settings.cpp:920 +msgid "Ctrl+arrows" +msgstr "Ctrl+стрлице" + +#: ../../po/../src/dialogs/display-settings.cpp:928 +msgid "Scroll by:" +msgstr "Померај за:" + +#: ../../po/../src/dialogs/display-settings.cpp:929 +msgid "Pressing Ctrl+arrow key scrolls by this distance (in screen pixels)" +msgstr "" +"Притискањем Ctrl+стрелица помера за оволику раздаљину (у екранским пикселима)" + +#: ../../po/../src/dialogs/display-settings.cpp:939 +msgid "Acceleration:" +msgstr "Убрзање:" + +#: ../../po/../src/dialogs/display-settings.cpp:940 +msgid "" +"Pressing and holding Ctrl+arrow will gradually speed up scrolling (0 for no " +"acceleration)" +msgstr "" +"Притискањем и држањем Ctrl+стрелица померање се постепено убрзава (0 за " +"искључено убрзање)" + +#: ../../po/../src/dialogs/display-settings.cpp:949 +msgid "Autoscrolling" +msgstr "Аутоматско померање" + +#: ../../po/../src/dialogs/display-settings.cpp:957 +msgid "Speed:" +msgstr "Брзина:" + +#: ../../po/../src/dialogs/display-settings.cpp:958 +msgid "" +"How fast the canvas autoscrolls when you drag beyond canvas edge (0 to turn " +"autoscroll off)" +msgstr "" +"Колико брзо се платно помера када ухватите спољашњост платна (0 за искључено " +"аутоматско померање)" + +#: ../../po/../src/dialogs/display-settings.cpp:968 +#: ../../po/../src/ui/dialog/tracedialog.cpp:357 +#: ../../po/../src/ui/dialog/tracedialog.cpp:390 +msgid "Threshold:" +msgstr "Праг толеранције:" + +#: ../../po/../src/dialogs/display-settings.cpp:969 +msgid "" +"How far (in screen pixels) you need to be from the canvas edge to trigger " +"autoscroll; positive is outside the canvas, negative is within the canvas" +msgstr "" +"Колико близу (у екранским пикселима) је потребно да курсор буде уз ивицу " +"платна за активирање аутоматског померања; позитивна вредност је ван платна, " +"негативна је за унутрашњост платна" + +#. Steps +#: ../../po/../src/dialogs/display-settings.cpp:979 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:57 +msgid "Steps" +msgstr "Кораци" + +#: ../../po/../src/dialogs/display-settings.cpp:982 +msgid "Arrow keys move by:" +msgstr "Стрелице померају за:" + +#: ../../po/../src/dialogs/display-settings.cpp:983 +msgid "" +"Pressing an arrow key moves selected object(s) or node(s) by this distance " +"(in px units)" +msgstr "" +"Притискање стрелица помера изабрани објекат или чвор за ову раздаљину (у " +"пикселима)" + +#: ../../po/../src/dialogs/display-settings.cpp:984 +#: ../../po/../src/dialogs/display-settings.cpp:995 +#: ../../po/../src/dialogs/display-settings.cpp:1006 +#: ../../po/../src/helper/units.cpp:42 +msgid "px" +msgstr "px" + +#: ../../po/../src/dialogs/display-settings.cpp:993 +msgid "> and < scale by:" +msgstr "„>“ и „<“ мењају величину за:" + +#: ../../po/../src/dialogs/display-settings.cpp:994 +msgid "" +"Pressing > or < scales selection up or down by this increment (in px units)" +msgstr "" +"Притискањем „>“ или „<“ мења се величина избора за овај корак (у пикселима)" + +#: ../../po/../src/dialogs/display-settings.cpp:1004 +msgid "Inset/Outset by:" +msgstr "Скупљање/ширење за:" + +#: ../../po/../src/dialogs/display-settings.cpp:1005 +msgid "" +"Inset and Outset commands displace the path by this distance (in px units)" +msgstr "Скупљање и Ширење помера криву за ову раздаљину (у пикселима)" + +#: ../../po/../src/dialogs/display-settings.cpp:1017 +msgid "Compass-like display of angles" +msgstr "" + +#. TRANSLATORS: "positive clockwise" means "increasing in clockwise direction" +#: ../../po/../src/dialogs/display-settings.cpp:1019 +msgid "" +"When on, angles are displayed with 0 at north, 0 to 360 range, positive " +"clockwise; otherwise with 0 at east, -180 to 180 range, positive " +"counterclockwise" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1026 +msgid "Zoom in/out by:" +msgstr "Увећавање/умањење за:" + +#: ../../po/../src/dialogs/display-settings.cpp:1027 +msgid "" +"Zoom tool click, +/- keys, and middle click zoom in and out by this " +"multiplier" +msgstr "" +"Алат за промену величине (зумирање), +/- тастери и средњи клик мишем " +"увеличава и умањује за овај умножак" + +#: ../../po/../src/dialogs/display-settings.cpp:1028 +#: ../../po/../src/helper/units.cpp:44 +msgid "%" +msgstr "%" + +#. Tools +#: ../../po/../src/dialogs/display-settings.cpp:1037 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:58 +msgid "Tools" +msgstr "Алатке" + +#: ../../po/../src/dialogs/display-settings.cpp:1045 +msgid "Selector" +msgstr "Изборник" + +#: ../../po/../src/dialogs/display-settings.cpp:1056 +msgid "Node" +msgstr "Чвор" + +#: ../../po/../src/dialogs/display-settings.cpp:1064 +#: ../../po/../src/verbs.cpp:2073 +#: ../../po/../src/widgets/desktop-widget.cpp:277 +msgid "Zoom" +msgstr "Увећај" + +#. The 4 shape tools +#: ../../po/../src/dialogs/display-settings.cpp:1071 +msgid "Shapes" +msgstr "Четвороугаоник" + +#: ../../po/../src/dialogs/display-settings.cpp:1079 +#: ../../po/../src/verbs.cpp:2055 +msgid "Rectangle" +msgstr "Правоугаоник" + +#: ../../po/../src/dialogs/display-settings.cpp:1085 +#: ../../po/../src/verbs.cpp:2057 +msgid "Ellipse" +msgstr "Елипса" + +#: ../../po/../src/dialogs/display-settings.cpp:1091 +#: ../../po/../src/verbs.cpp:2059 +msgid "Star" +msgstr "Звезда" + +#: ../../po/../src/dialogs/display-settings.cpp:1097 +#: ../../po/../src/verbs.cpp:2061 +msgid "Spiral" +msgstr "Спирала" + +#: ../../po/../src/dialogs/display-settings.cpp:1111 +#: ../../po/../src/verbs.cpp:2063 +msgid "Pencil" +msgstr "Груба оловка" + +#: ../../po/../src/dialogs/display-settings.cpp:1114 +msgid "Tolerance:" +msgstr "Толеранција:" + +#: ../../po/../src/dialogs/display-settings.cpp:1115 +msgid "" +"This value affects the amount of smoothing applied to freehand lines; lower " +"values produce more uneven paths with more nodes" +msgstr "" +"Ова вредност се односи на јачину умекшавања примењених на исцртавање криве " +"слободном руком; мање вредности производе назубљеније линије са више чворова" + +#: ../../po/../src/dialogs/display-settings.cpp:1131 +#: ../../po/../src/verbs.cpp:2065 +msgid "Pen" +msgstr "Оловка" + +#: ../../po/../src/dialogs/display-settings.cpp:1140 +#: ../../po/../src/verbs.cpp:2067 +msgid "Calligraphy" +msgstr "Калиграфија" + +#: ../../po/../src/dialogs/display-settings.cpp:1147 +#: ../../po/../src/dialogs/text-edit.cpp:353 +#: ../../po/../src/ui/dialog/text-properties.cpp:37 +#: ../../po/../src/verbs.cpp:2069 +msgid "Text" +msgstr "Текст" + +#: ../../po/../src/dialogs/display-settings.cpp:1157 +#: ../../po/../src/verbs.cpp:2071 +msgid "Gradient" +msgstr "Уређивач прелива" + +#: ../../po/../src/dialogs/display-settings.cpp:1164 +#: ../../po/../src/verbs.cpp:2077 +#, fuzzy +msgid "Connector" +msgstr "Аутор" + +#: ../../po/../src/dialogs/display-settings.cpp:1171 +#: ../../po/../src/verbs.cpp:2075 +msgid "Dropper" +msgstr "Изборник боја" + +#. Windows +#: ../../po/../src/dialogs/display-settings.cpp:1183 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:59 +msgid "Windows" +msgstr "Прозори" + +#: ../../po/../src/dialogs/display-settings.cpp:1188 +msgid "Save window geometry" +msgstr "Сачувај димензије прозора" + +#: ../../po/../src/dialogs/display-settings.cpp:1189 +msgid "" +"Save the window size and position with each document (only for Inkscape SVG " +"format)" +msgstr "" +"Сачувај димензије прозора и позицију са сваким документом (само за Инкскејп " +"СВГ формат)" + +#: ../../po/../src/dialogs/display-settings.cpp:1196 +msgid "Dialogs are hidden in taskbar" +msgstr "Сакриј прозорчиће у линију послова" + +#: ../../po/../src/dialogs/display-settings.cpp:1197 +msgid "Whether dialog windows are to be hidden in the window manager taskbar" +msgstr "" +"Увек када су прозорчићи скривени, смести их у линију послова менаџера прозора" + +#: ../../po/../src/dialogs/display-settings.cpp:1204 +msgid "Zoom when window is resized" +msgstr "Промени увећање при промени величине прозора" + +#: ../../po/../src/dialogs/display-settings.cpp:1205 +msgid "" +"Zoom drawing when document window is resized, to keep the same area visible " +"(this is the default which can be changed in any window using the button " +"above the right scrollbar)" +msgstr "" +"Зумирање цртежа када се прмени величина прозора, да би се иста површина " +"одржала видљивом (ово је подразумевана особина која се може променити за " +"сваки прозор помоћу дугмета у десном углу изнад траке за померање)" + +#. Clones +#: ../../po/../src/dialogs/display-settings.cpp:1213 +#: ../../po/../src/dialogs/find.cpp:624 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:60 +msgid "Clones" +msgstr "Клонови" + +#: ../../po/../src/dialogs/display-settings.cpp:1217 +msgid "When the original moves, its clones and linked offsets:" +msgstr "Када се помери оригинал, померај клона и повезаног објекта је:" + +#: ../../po/../src/dialogs/display-settings.cpp:1229 +msgid "Move in parallel" +msgstr "Помера паралелно са оригиналом" + +#: ../../po/../src/dialogs/display-settings.cpp:1230 +msgid "Clones are translated by the same vector as their original." +msgstr "Клон се помера по истој путањи као и оригинал." + +#: ../../po/../src/dialogs/display-settings.cpp:1237 +msgid "Stay unmoved" +msgstr "Остаје на месту" + +#: ../../po/../src/dialogs/display-settings.cpp:1238 +msgid "Clones preserve their positions when their original is moved." +msgstr "Клон задржава позицију када се оригинал помери." + +#: ../../po/../src/dialogs/display-settings.cpp:1245 +msgid "Move according to transform" +msgstr "Померање сходно трансформацији" + +#: ../../po/../src/dialogs/display-settings.cpp:1246 +msgid "" +"Each clone moves according to the value of its transform= attribute. For " +"example, a rotated clone will move in a different direction than its " +"original." +msgstr "" +"Сваки клон се помера у складу са вредношћу његовог transform= атрибута. Нпр, " +"ротирани клон ће се померити у супротном правцу од оригинала." + +#: ../../po/../src/dialogs/display-settings.cpp:1255 +msgid "When the original is deleted, its clones:" +msgstr "Када се оригинал обрише, клон се" + +#: ../../po/../src/dialogs/display-settings.cpp:1267 +msgid "Are unlinked" +msgstr "Одвезује" + +#: ../../po/../src/dialogs/display-settings.cpp:1267 +msgid "Orphaned clones are converted to regular objects." +msgstr "Клонови сирочићи се претварају у нормалне објекте." + +#: ../../po/../src/dialogs/display-settings.cpp:1273 +msgid "Are deleted" +msgstr "Брише" + +#: ../../po/../src/dialogs/display-settings.cpp:1273 +msgid "Orphaned clones are deleted along with their original." +msgstr "Клонови сирочићи се бришу заједно са оригиналом." + +#. Transforms +#. TRANSLATORS: Noun, i.e. transformations. +#: ../../po/../src/dialogs/display-settings.cpp:1289 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:61 +msgid "Transforms" +msgstr "Трансформација" + +#: ../../po/../src/dialogs/display-settings.cpp:1292 +msgid "Scale stroke width" +msgstr "Скалирај ширину линије" + +#: ../../po/../src/dialogs/display-settings.cpp:1293 +#: ../../po/../src/widgets/select-toolbar.cpp:568 +msgid "When scaling objects, scale the stroke width by the same proportion" +msgstr "Када се мења величина објекта, пропорцијално се мења и ширина линије" + +#: ../../po/../src/dialogs/display-settings.cpp:1300 +msgid "Scale rounded corners in rectangles" +msgstr "Промена величине заобљених углова правоугаоника" + +#: ../../po/../src/dialogs/display-settings.cpp:1301 +#: ../../po/../src/widgets/select-toolbar.cpp:580 +msgid "When scaling rectangles, scale the radii of rounded corners" +msgstr "" +"Када се мења величина правоугаоника, мења се и полупречник заобљених углова" + +#: ../../po/../src/dialogs/display-settings.cpp:1308 +msgid "Transform gradients" +msgstr "Трансформација прелива" + +#: ../../po/../src/dialogs/display-settings.cpp:1309 +#: ../../po/../src/widgets/select-toolbar.cpp:592 +msgid "Transform gradients (in fill or stroke) along with the objects" +msgstr "" +"Трансформација прелива (у попуни или боји ивичне линије) заједно са објектом" + +#: ../../po/../src/dialogs/display-settings.cpp:1316 +msgid "Transform patterns" +msgstr "Трансформација мустре" + +#: ../../po/../src/dialogs/display-settings.cpp:1317 +#: ../../po/../src/widgets/select-toolbar.cpp:604 +msgid "Transform patterns (in fill or stroke) along with the objects" +msgstr "" +"Трансформација мустре (у попуни или боји ивичне линије) заједно са објектом" + +#. TRANSLATORS: How to specify the affine transformation in the SVG file. +#: ../../po/../src/dialogs/display-settings.cpp:1327 +msgid "Store transformation:" +msgstr "Памћење трансформација:" + +#: ../../po/../src/dialogs/display-settings.cpp:1338 +msgid "Optimized" +msgstr "Оптимизовано" + +#: ../../po/../src/dialogs/display-settings.cpp:1339 +msgid "" +"If possible, apply transformation to objects without adding a transform= " +"attribute" +msgstr "" +"Ако је могуће, примени трансформацију објекта без додавања атрибута " +"transform=" + +#: ../../po/../src/dialogs/display-settings.cpp:1346 +msgid "Preserved" +msgstr "Сачувано" + +#: ../../po/../src/dialogs/display-settings.cpp:1347 +msgid "Always store transformation as a transform= attribute on objects" +msgstr "Увек сачувај трансформацију као transform= атрибут објекта" + +#. Selecting +#: ../../po/../src/dialogs/display-settings.cpp:1355 +msgid "Selecting" +msgstr "Избор" + +#: ../../po/../src/dialogs/display-settings.cpp:1357 +msgid "Ctrl+A, Tab, Shift+Tab:" +msgstr "Ctrl+A, Tab, Shift+Tab:" + +#: ../../po/../src/dialogs/display-settings.cpp:1366 +msgid "Select only within current layer" +msgstr "Изабери само у тренутном слоју" + +#: ../../po/../src/dialogs/display-settings.cpp:1367 +msgid "" +"Uncheck this to make keyboard selection commands work on objects in all " +"layers" +msgstr "" +"Искључите ову опцију да би омогућили избор објеката тастатуром на свим " +"слојевима" + +#: ../../po/../src/dialogs/display-settings.cpp:1374 +msgid "Ignore hidden objects" +msgstr "Игнориши скривене објекте" + +#: ../../po/../src/dialogs/display-settings.cpp:1375 +msgid "" +"Uncheck this to be able to select objects that are hidden (either by " +"themselves or by being in a hidden group or layer)" +msgstr "" +"Искључите ову опцију да би могли да изаберете скривени објекат (било њега " +"лично или преласком у скривену групу или слој)" + +#: ../../po/../src/dialogs/display-settings.cpp:1382 +msgid "Ignore locked objects" +msgstr "Занемари закључане слојеве" + +#: ../../po/../src/dialogs/display-settings.cpp:1383 +msgid "" +"Uncheck this to be able to select objects that are locked (either by " +"themselves or by being in a locked group or layer)" +msgstr "" +"Искључите ову опцију да би могли да изаберете закључани објекат (било њега " +"лично или преласком у закључану групу или слој)" + +#. To be broken into: Display, Save, Export, SVG, Commands +#: ../../po/../src/dialogs/display-settings.cpp:1391 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:62 +msgid "Misc" +msgstr "Разно" + +#: ../../po/../src/dialogs/display-settings.cpp:1394 +msgid "Default export resolution:" +msgstr "Подразумевана резолуција за извоз:" + +#: ../../po/../src/dialogs/display-settings.cpp:1395 +msgid "Default bitmap resolution (in dots per inch) in the Export dialog" +msgstr "" +"Подразумевана резолуција битмапе (тачака по инчу) у Извозном прозорчету" + +#. FIXME: add "Used for new exports; once exported, documents remember this value on per-object basis" when implemented +#: ../../po/../src/dialogs/display-settings.cpp:1396 +#: ../../po/../src/dialogs/export.cpp:442 +msgid "dpi" +msgstr "тпи" + +#. TRANSLATORS: When on, an imported bitmap creates an element; otherwise it is a +#. * rectangle with bitmap fill. +#: ../../po/../src/dialogs/display-settings.cpp:1407 +msgid "Import bitmap as " +msgstr "Увези битмапу као слику „“" + +#: ../../po/../src/dialogs/display-settings.cpp:1408 +msgid "" +"When on, an imported bitmap creates an element; otherwise it is a " +"rectangle with bitmap fill" +msgstr "" +"Када је активно, увежена битмапа је елемент; у супротном је " +"правоугаоник са битмапираном попуном" + +#. TRANSLATORS: When on, the print out (currently Postscript) will have +#. * a comment with the each object's label visible, marking the section +#. * of the printing commands that represent the given object. +#: ../../po/../src/dialogs/display-settings.cpp:1418 +msgid "Add label comments to printing output" +msgstr "Додавање коментара у штампани излаз" + +#: ../../po/../src/dialogs/display-settings.cpp:1419 +msgid "" +"When on, a comment will be added to the raw print output, marking the " +"rendered output for an object with its label" +msgstr "" +"Када је активно, коментар ће бити додат на сирови излаз при штампи, " +"обележавајући рендеровани излаз објекта његовом ознаком" + +#. TRANSLATORS: When on, enable the effects menu, default is off +#: ../../po/../src/dialogs/display-settings.cpp:1427 +msgid "Enable script effects (requires restart) - EXPERIMENTAL" +msgstr "Омогући ефекте скриптама (захтева рестартовање) - ЕКСПЕРИМЕНТАЛНО" + +#: ../../po/../src/dialogs/display-settings.cpp:1428 +msgid "" +"When on, the effects menu is enabled, allowing external effect scripts to be " +"called, requires restart before effective - EXPERIMENTAL" +msgstr "" +"Када је активно, мени са ефектима је омогућен, дозвољава да буду позване " +"спољне скрипте за ефекте, захтева рестартовање пре употребе - ЕКСПЕРИМЕНТАЛНО" + +#. TRANSLATORS: The maximum length of the Open Recent list in the File menu. +#: ../../po/../src/dialogs/display-settings.cpp:1436 +msgid "Max recent documents:" +msgstr "Највише последње коришћених докумената:" + +#: ../../po/../src/dialogs/display-settings.cpp:1437 +msgid "The maximum length of the Open Recent list in the File menu" +msgstr "" +"Максималан број докумената у листи „Отвори последње коришћене“ у менију " +"„Датотека“" + +#: ../../po/../src/dialogs/display-settings.cpp:1447 +msgid "Simplification threshold:" +msgstr "Праг поједностављивања:" + +#: ../../po/../src/dialogs/display-settings.cpp:1448 +msgid "" +"How strong is the Simplify command by default. If you invoke this command " +"several times in quick succession, it will act more and more aggressively; " +"invoking it again after a pause restores the default threshold." +msgstr "" +"Колико је подразумевано велика наредба Поједностављивање. Ако позивате ову " +"наредбу више пута узастопно, примењиваће се све агресивније; поновно " +"позивање након кратке паузе враћа праг на подразумевану вредност." + +#: ../../po/../src/dialogs/display-settings.cpp:1469 +msgid "Oversample bitmaps:" +msgstr "Преувеличавање битмапа:" + +#: ../../po/../src/dialogs/display-settings.cpp:1488 +msgid "2x2" +msgstr "2x2" + +#: ../../po/../src/dialogs/display-settings.cpp:1494 +msgid "4x4" +msgstr "4x4" + +#: ../../po/../src/dialogs/display-settings.cpp:1500 +msgid "8x8" +msgstr "8x8" + +#: ../../po/../src/dialogs/display-settings.cpp:1506 +msgid "16x16" +msgstr "16x16" + +#. "view_icon_preview" +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2143 +msgid "_Page" +msgstr "_Страна" + +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2147 +msgid "_Drawing" +msgstr "_Цртеж" + +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2149 +msgid "_Selection" +msgstr "_Избор" + +#: ../../po/../src/dialogs/export.cpp:133 +msgid "_Custom" +msgstr "_Прилагођено" + +#: ../../po/../src/dialogs/export.cpp:254 +msgid "Export area" +msgstr "Извоз површине" + +#: ../../po/../src/dialogs/export.cpp:300 +msgid "_x0:" +msgstr "_x0:" + +#: ../../po/../src/dialogs/export.cpp:305 +msgid "x_1:" +msgstr "x_1:" + +#: ../../po/../src/dialogs/export.cpp:316 +msgid "_y0:" +msgstr "_y0:" + +#: ../../po/../src/dialogs/export.cpp:321 +msgid "y_1:" +msgstr "y_1:" + +#: ../../po/../src/dialogs/export.cpp:406 +msgid "Bitmap size" +msgstr "Величина битмапе" + +#: ../../po/../src/dialogs/export.cpp:416 +msgid "_Width:" +msgstr "_Ширина:" + +#: ../../po/../src/dialogs/export.cpp:416 +#: ../../po/../src/dialogs/export.cpp:431 +msgid "pixels at" +msgstr "пиксела на" + +#: ../../po/../src/dialogs/export.cpp:426 +msgid "dp_i" +msgstr "тп_и" + +#: ../../po/../src/dialogs/export.cpp:448 +msgid "_Filename" +msgstr "Назив _датотеке" + +#: ../../po/../src/dialogs/export.cpp:512 +msgid "_Browse..." +msgstr "_Тражи..." + +#: ../../po/../src/dialogs/export.cpp:539 +msgid " _Export " +msgstr "_Извоз" + +#: ../../po/../src/dialogs/export.cpp:541 +msgid "Export the bitmap file with these settings" +msgstr "Извози битмапу са овим подешавањима" + +#: ../../po/../src/dialogs/export.cpp:968 +msgid "You have to enter a filename" +msgstr "Морате унети назив датотеке" + +#: ../../po/../src/dialogs/export.cpp:973 +msgid "The chosen area to be exported is invalid" +msgstr "Одабрана површина за извоз је нерегуларна" + +#: ../../po/../src/dialogs/export.cpp:982 +#, c-format +msgid "Directory %s does not exist or is not a directory.\n" +msgstr "Директоријум %s не постоји или није директоријум.\n" + +#: ../../po/../src/dialogs/export.cpp:998 +msgid "Export in progress" +msgstr "Извоз је у току" + +#: ../../po/../src/dialogs/export.cpp:1004 +#, c-format +msgid "Exporting %s (%d x %d)" +msgstr "Извоз %s (%d x %d)" + +#: ../../po/../src/dialogs/export.cpp:1031 +#, c-format +msgid "Could not export to filename %s.\n" +msgstr "Не могу да извезем у датотеку %s.\n" + +#: ../../po/../src/dialogs/export.cpp:1137 +msgid "Select a filename for exporting" +msgstr "Одаберите назив датотеке за извоз" + +#: ../../po/../src/dialogs/filedialog.cpp:367 +msgid "No preview" +msgstr "Нема приказа" + +#: ../../po/../src/dialogs/filedialog.cpp:468 +msgid "too large for preview" +msgstr "превише велико да би се приказало" + +#: ../../po/../src/dialogs/filedialog.cpp:762 +#: ../../po/../src/dialogs/filedialog.cpp:763 +msgid "All Images" +msgstr "Све слике" + +#: ../../po/../src/dialogs/filedialog.cpp:767 +#: ../../po/../src/dialogs/filedialog.cpp:768 +msgid "All Files" +msgstr "Све датотеке" + +#: ../../po/../src/dialogs/filedialog.cpp:774 +#: ../../po/../src/dialogs/filedialog.cpp:775 +msgid "All Inkscape Files" +msgstr "Све Инкскејп датотеке" + +#: ../../po/../src/dialogs/filedialog.cpp:1176 +msgid "Guess from extension" +msgstr "Препознај по наставку" + +#. ###### Add the file types menu +#. createFilterMenu(); +#. ###### Do we want the .xxx extension automatically added? +#: ../../po/../src/dialogs/filedialog.cpp:1261 +msgid "Append filename extension automatically" +msgstr "Аутоматски додај екстензију датотеке" + +#. TRANSLATORS: "%s" is replaced with "exact" or "partial" when this string is displayed +#: ../../po/../src/dialogs/find.cpp:378 +#, c-format +msgid "%d object found (out of %d), %s match." +msgid_plural "%d objects found (out of %d), %s match." +msgstr[0] "" +"%d објекат пронађен (од укупно %d), %s одговара услову" +msgstr[1] "" +"%d објеката пронађено (од укупно %d), %s одговара услову" + +#: ../../po/../src/dialogs/find.cpp:381 +msgid "exact" +msgstr "апсолутно" + +#: ../../po/../src/dialogs/find.cpp:381 +msgid "partial" +msgstr "делимично" + +#: ../../po/../src/dialogs/find.cpp:388 +msgid "No objects found" +msgstr "Нема пронађених објеката" + +#: ../../po/../src/dialogs/find.cpp:546 +msgid "T_ype: " +msgstr "_Врста: " + +#: ../../po/../src/dialogs/find.cpp:553 +msgid "Search in all object types" +msgstr "Тражи у свим врстама објеката" + +#: ../../po/../src/dialogs/find.cpp:553 +msgid "All types" +msgstr "Све врсте" + +#: ../../po/../src/dialogs/find.cpp:564 +msgid "Search all shapes" +msgstr "Тражи међу облицима" + +#: ../../po/../src/dialogs/find.cpp:564 +msgid "All shapes" +msgstr "Сви облици" + +#: ../../po/../src/dialogs/find.cpp:581 +msgid "Search rectangles" +msgstr "Тражи међу правоугаоницима" + +#: ../../po/../src/dialogs/find.cpp:581 +msgid "Rectangles" +msgstr "Правоугаоници" + +#: ../../po/../src/dialogs/find.cpp:586 +msgid "Search ellipses, arcs, circles" +msgstr "Тражи међу елипсама, угловима и кружницама" + +#: ../../po/../src/dialogs/find.cpp:586 +msgid "Ellipses" +msgstr "Елипсе" + +#: ../../po/../src/dialogs/find.cpp:591 +msgid "Search stars and polygons" +msgstr "Тражи међу звездама и полигонима" + +#: ../../po/../src/dialogs/find.cpp:591 +msgid "Stars" +msgstr "Звезде" + +#: ../../po/../src/dialogs/find.cpp:596 +msgid "Search spirals" +msgstr "Тражи међу спиралама" + +#: ../../po/../src/dialogs/find.cpp:596 +msgid "Spirals" +msgstr "Спирале" + +#. TRANSLATORS: polyline is a set of connected straight line segments +#. http://www.w3.org/TR/SVG11/shapes.html#PolylineElement +#: ../../po/../src/dialogs/find.cpp:609 +msgid "Search paths, lines, polylines" +msgstr "Тражи међу кривама, линијама и саставним линијама" + +#: ../../po/../src/dialogs/find.cpp:609 +msgid "Paths" +msgstr "Криве" + +#: ../../po/../src/dialogs/find.cpp:614 +msgid "Search text objects" +msgstr "Тражи међу текстуалним објектима" + +#: ../../po/../src/dialogs/find.cpp:614 +msgid "Texts" +msgstr "Текст" + +#: ../../po/../src/dialogs/find.cpp:619 +msgid "Search groups" +msgstr "Тражи међу групама" + +#: ../../po/../src/dialogs/find.cpp:619 +msgid "Groups" +msgstr "Групе" + +#: ../../po/../src/dialogs/find.cpp:624 +msgid "Search clones" +msgstr "Тражи међу клоновима" + +#: ../../po/../src/dialogs/find.cpp:629 +msgid "Search images" +msgstr "Тражи међу сликама" + +#: ../../po/../src/dialogs/find.cpp:629 +msgid "Images" +msgstr "Слике" + +#: ../../po/../src/dialogs/find.cpp:634 +msgid "Search offset objects" +msgstr "Тражи међу размакнутим објектима" + +#: ../../po/../src/dialogs/find.cpp:634 +msgid "Offsets" +msgstr "Размакнути" + +#: ../../po/../src/dialogs/find.cpp:694 +msgid "_Text: " +msgstr "_Текст: " + +#: ../../po/../src/dialogs/find.cpp:694 +msgid "Find objects by their text content (exact or partial match)" +msgstr "Тражи објекте по садржају текста (апсолутно или делимично поклапање)" + +#: ../../po/../src/dialogs/find.cpp:695 +msgid "_ID: " +msgstr "_ИД: " + +#: ../../po/../src/dialogs/find.cpp:695 +msgid "Find objects by the value of the id attribute (exact or partial match)" +msgstr "" +"Тражи објекте по садржају особине „ИД“ (апсолутно или делимично поклапање)" + +#: ../../po/../src/dialogs/find.cpp:696 +msgid "_Style: " +msgstr "_Стил: " + +#: ../../po/../src/dialogs/find.cpp:696 +msgid "" +"Find objects by the value of the style attribute (exact or partial match)" +msgstr "" +"Тражи објекте по садржају особине „стил“ (апсолутно или делимично поклапање)" + +#: ../../po/../src/dialogs/find.cpp:697 +msgid "_Attribute: " +msgstr "_Особина: " + +#: ../../po/../src/dialogs/find.cpp:697 +msgid "Find objects by the name of an attribute (exact or partial match)" +msgstr "Тражи објекте по називу особине (апсолутно или делимично поклапање)" + +#: ../../po/../src/dialogs/find.cpp:711 +msgid "Search in s_election" +msgstr "Тражи у _избору" + +#: ../../po/../src/dialogs/find.cpp:715 +msgid "Limit search to the current selection" +msgstr "Ограничи претрагу на тренутни избор" + +#: ../../po/../src/dialogs/find.cpp:720 +msgid "Search in current _layer" +msgstr "Претрага у активном _слоју" + +#: ../../po/../src/dialogs/find.cpp:724 +msgid "Limit search to the current layer" +msgstr "Ограничавање претраге на тренутно одабрани слој" + +#: ../../po/../src/dialogs/find.cpp:729 +msgid "Include _hidden" +msgstr "Укључи _скривене" + +#: ../../po/../src/dialogs/find.cpp:733 +msgid "Include hidden objects in search" +msgstr "Укључи скривене објекте у претргу" + +#: ../../po/../src/dialogs/find.cpp:738 +msgid "Include l_ocked" +msgstr "Укључи _закључане" + +#: ../../po/../src/dialogs/find.cpp:742 +msgid "Include locked objects in search" +msgstr "Укључи закључане објекте у претрагу" + +#: ../../po/../src/dialogs/find.cpp:753 +msgid "Clear values" +msgstr "Очисти вредности" + +#: ../../po/../src/dialogs/find.cpp:754 +msgid "_Find" +msgstr "_Тражи" + +#: ../../po/../src/dialogs/find.cpp:754 +msgid "Select objects matching all of the fields you filled in" +msgstr "Изабери објекте који испуњавају све задате услове" + +#: ../../po/../src/dialogs/iconpreview.cpp:145 +#, c-format +msgid "%d x %d" +msgstr "" + +#: ../../po/../src/dialogs/iconpreview.cpp:193 +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:857 +#: ../../po/../src/widgets/desktop-widget.cpp:1069 +msgid "Selection" +msgstr "Избор" + +#: ../../po/../src/dialogs/iconpreview.cpp:195 +#, fuzzy +msgid "Selection only or whole document" +msgstr "Изабери само у тренутном слоју" + +#: ../../po/../src/dialogs/iconpreview.cpp:203 +msgid "Refresh the icons" +msgstr "Освежи иконице" + +#. Create the label for the object id +#: ../../po/../src/dialogs/item-properties.cpp:126 +#: ../../po/../src/dialogs/item-properties.cpp:327 +#: ../../po/../src/dialogs/item-properties.cpp:396 +#: ../../po/../src/dialogs/item-properties.cpp:403 +msgid "_Id" +msgstr "_ИД" + +#: ../../po/../src/dialogs/item-properties.cpp:135 +msgid "" +"The id= attribute (only letters, digits, and the characters .-_: allowed)" +msgstr "Атрибут id= (само слива, бројеви и знаци .-_: дозвољено" + +#. Button for setting the object's id, label, title and description. +#: ../../po/../src/dialogs/item-properties.cpp:149 +msgid "_Set" +msgstr "_Постави" + +#. Create the label for the object label +#: ../../po/../src/dialogs/item-properties.cpp:158 +msgid "_Label" +msgstr "_Ознака" + +#: ../../po/../src/dialogs/item-properties.cpp:167 +msgid "A freeform label for the object" +msgstr "Слободна ознака за објекат" + +#. Create the label for the object title +#: ../../po/../src/dialogs/item-properties.cpp:179 +#: ../../po/../src/dialogs/rdf.cpp:243 +msgid "Title" +msgstr "Наслов" + +#. Create the frame for the object description +#: ../../po/../src/dialogs/item-properties.cpp:196 +#: ../../po/../src/dialogs/rdf.cpp:287 +msgid "Description" +msgstr "Опис" + +#. Hide +#: ../../po/../src/dialogs/item-properties.cpp:223 +msgid "_Hide" +msgstr "_Сакриј" + +#: ../../po/../src/dialogs/item-properties.cpp:224 +msgid "Check to make the object invisible" +msgstr "Активирајте да учините објекат невидљивим" + +#. Lock +#. TRANSLATORS: "Lock" is a verb here +#: ../../po/../src/dialogs/item-properties.cpp:233 +msgid "L_ock" +msgstr "_Закључај" + +#: ../../po/../src/dialogs/item-properties.cpp:234 +msgid "Check to make the object insensitive (not selectable by mouse)" +msgstr "" +"Активирајте да учините објекат неосетљивим (није га могуће изабрати мишем)" + +#: ../../po/../src/dialogs/item-properties.cpp:310 +#: ../../po/../src/dialogs/item-properties.cpp:317 +msgid "Ref" +msgstr "Референца" + +#: ../../po/../src/dialogs/item-properties.cpp:398 +msgid "Id invalid! " +msgstr "ИД је неисправан! " + +#: ../../po/../src/dialogs/item-properties.cpp:400 +msgid "Id exists! " +msgstr "ИД постоји! " + +#: ../../po/../src/dialogs/layer-properties.cpp:50 +msgid "Layer name:" +msgstr "Назив слоја:" + +#: ../../po/../src/dialogs/layer-properties.cpp:133 +msgid "Rename Layer" +msgstr "Преименуј слој" + +#: ../../po/../src/dialogs/layer-properties.cpp:136 +msgid "_Rename" +msgstr "_Преименуј" + +#. TRANSLATORS: This means "The layer has been renamed" +#: ../../po/../src/dialogs/layer-properties.cpp:147 +msgid "Renamed layer" +msgstr "Слој је преименован" + +#: ../../po/../src/dialogs/layer-properties.cpp:151 +msgid "Add Layer" +msgstr "Додавање слоја" + +#: ../../po/../src/dialogs/layer-properties.cpp:153 +msgid "_Add" +msgstr "_Додај" + +#: ../../po/../src/dialogs/layer-properties.cpp:167 +msgid "New layer created." +msgstr "Направљен је нови слој." + +#: ../../po/../src/dialogs/object-attributes.cpp:34 +msgid "Href:" +msgstr "Адреса:" + +#: ../../po/../src/dialogs/object-attributes.cpp:35 +msgid "Target:" +msgstr "Одредиште:" + +#: ../../po/../src/dialogs/object-attributes.cpp:36 +msgid "Type:" +msgstr "Врста:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkRoleAttribute +#. Identifies the type of the related resource with an absolute URI +#: ../../po/../src/dialogs/object-attributes.cpp:39 +msgid "Role:" +msgstr "Улога:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkArcRoleAttribute +#. For situations where the nature/role alone isn't enough, this offers an additional URI defining the purpose of the link. +#: ../../po/../src/dialogs/object-attributes.cpp:42 +msgid "Arcrole:" +msgstr "Лучна улога:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkTitleAttribute +#: ../../po/../src/dialogs/object-attributes.cpp:44 +msgid "Title:" +msgstr "Наслов:" + +#: ../../po/../src/dialogs/object-attributes.cpp:45 +msgid "Show:" +msgstr "Прикажи:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkActuateAttribute +#: ../../po/../src/dialogs/object-attributes.cpp:47 +msgid "Actuate:" +msgstr "Покрени:" + +#: ../../po/../src/dialogs/object-attributes.cpp:52 +msgid "URL:" +msgstr "Адреса:" + +#: ../../po/../src/dialogs/object-attributes.cpp:53 +msgid "X:" +msgstr "X:" + +#: ../../po/../src/dialogs/object-attributes.cpp:54 +msgid "Y:" +msgstr "Y:" + +#: ../../po/../src/dialogs/object-attributes.cpp:98 +#, c-format +msgid "%s attributes" +msgstr "Особине за %s" + +#: ../../po/../src/dialogs/object-properties.cpp:158 +msgid "_Fill" +msgstr "_Попуна" + +#: ../../po/../src/dialogs/object-properties.cpp:165 +msgid "Stroke _paint" +msgstr "_Линија" + +#: ../../po/../src/dialogs/object-properties.cpp:172 +msgid "Stroke st_yle" +msgstr "С_тил линије" + +#: ../../po/../src/dialogs/object-properties.cpp:183 +msgid "Master _opacity" +msgstr "Основна _провидност" + +#: ../../po/../src/dialogs/rdf.cpp:244 +msgid "Name by which this document is formally known." +msgstr "Назив под којим ће овај документ бити формално познат." + +#: ../../po/../src/dialogs/rdf.cpp:246 +msgid "Date" +msgstr "Датум" + +#: ../../po/../src/dialogs/rdf.cpp:247 +msgid "Date associated with the creation of this document (YYYY-MM-DD)." +msgstr "Датум који представља датум прављења овог документа (YYYY-MM-DD)." + +#: ../../po/../src/dialogs/rdf.cpp:249 +msgid "Format" +msgstr "Формат" + +#: ../../po/../src/dialogs/rdf.cpp:250 +msgid "The physical or digital manifestation of this document (MIME type)." +msgstr "Физичко или дигитално представљање овог документа (МИМЕ врста)." + +#: ../../po/../src/dialogs/rdf.cpp:252 +msgid "Type" +msgstr "Врста" + +#: ../../po/../src/dialogs/rdf.cpp:253 +msgid "Type of document (DCMI Type)." +msgstr "Врста документа (ДЦМИ врста)." + +#: ../../po/../src/dialogs/rdf.cpp:256 +msgid "Creator" +msgstr "Аутор" + +#: ../../po/../src/dialogs/rdf.cpp:257 +msgid "" +"Name of entity primarily responsible for making the content of this document." +msgstr "" +"Назим примарног ствараоца који је одговоран за прављење садржаја документа." + +#: ../../po/../src/dialogs/rdf.cpp:259 +msgid "Rights" +msgstr "Права" + +#: ../../po/../src/dialogs/rdf.cpp:260 +msgid "" +"Name of entity with rights to the Intellectual Property of this document." +msgstr "Назив ентитета који има права на интелектуалну својину овог документа." + +#: ../../po/../src/dialogs/rdf.cpp:262 +msgid "Publisher" +msgstr "Издавач" + +#: ../../po/../src/dialogs/rdf.cpp:263 +msgid "Name of entity responsible for making this document available." +msgstr "Назив ентитета који је одговоран за објављивање овог документа." + +#: ../../po/../src/dialogs/rdf.cpp:266 +msgid "Identifier" +msgstr "Идентификатор" + +#: ../../po/../src/dialogs/rdf.cpp:267 +msgid "Unique URI to reference this document." +msgstr "Јединствени УРЛ коме је референца овај документ." + +#: ../../po/../src/dialogs/rdf.cpp:269 +msgid "Source" +msgstr "Извор" + +#: ../../po/../src/dialogs/rdf.cpp:270 +msgid "Unique URI to reference the source of this document." +msgstr "Јединствени УРЛ коме је референца изворни кôд овог документа." + +#: ../../po/../src/dialogs/rdf.cpp:272 +msgid "Relation" +msgstr "Однос" + +#: ../../po/../src/dialogs/rdf.cpp:273 +msgid "Unique URI to a related document." +msgstr "Јединствени УРЛ за релациони документ." + +#: ../../po/../src/dialogs/rdf.cpp:275 +msgid "Language" +msgstr "Језик" + +#: ../../po/../src/dialogs/rdf.cpp:276 +msgid "" +"Two-letter language tag with optional subtags for the language of this " +"document. (e.g. 'en-GB')" +msgstr "" +"Двословни језички таг са опционалним подтаговима за језике документа (нпр. " +"„sr_CS“)" + +#: ../../po/../src/dialogs/rdf.cpp:278 +msgid "Keywords" +msgstr "Кључне речи" + +#: ../../po/../src/dialogs/rdf.cpp:279 +msgid "" +"The topic of this document as comma-separated key words, phrases, or " +"classifications." +msgstr "" +"Садржина документа као зарезом раздвојене речи, фразе или класификације." + +#. TRANSLATORS: "Coverage": the spatial or temporal characteristics of the content. +#. For info, see Appendix D of http://www.w3.org/TR/1998/WD-rdf-schema-19980409/ +#: ../../po/../src/dialogs/rdf.cpp:283 +msgid "Coverage" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:284 +msgid "Extent or scope of this document." +msgstr "Подручје докрумента." + +#: ../../po/../src/dialogs/rdf.cpp:288 +msgid "A short account of the content of this document." +msgstr "" + +#. FIXME: need to handle 1 agent per line of input +#: ../../po/../src/dialogs/rdf.cpp:292 +msgid "Contributors" +msgstr "Прилагачи" + +#: ../../po/../src/dialogs/rdf.cpp:293 +msgid "" +"Names of entities responsible for making contributions to the content of " +"this document." +msgstr "Називи ентитета који су учствовали на стварању садржаја документа." + +#. TRANSLATORS: URL to a page that defines the license for the document +#: ../../po/../src/dialogs/rdf.cpp:297 +msgid "URI" +msgstr "УРЛ" + +#. TRANSLATORS: this is where you put a URL to a page that defines the license +#: ../../po/../src/dialogs/rdf.cpp:299 +msgid "URI to this document's license's namespace definition." +msgstr "УРЛ до дефиниције лиценце овог документа." + +#. TRANSLATORS: fragment of XML representing the license of the document +#: ../../po/../src/dialogs/rdf.cpp:303 +msgid "Fragment" +msgstr "Делови" + +#: ../../po/../src/dialogs/rdf.cpp:304 +msgid "XML fragment for the RDF 'License' section." +msgstr "XML делови за RDF део лиценце." + +#: ../../po/../src/dialogs/stroke-style.cpp:774 +#: ../../po/../src/widgets/gradient-vector.cpp:263 +#: ../../po/../src/widgets/paint-selector.cpp:751 +msgid "No document selected" +msgstr "Нисте изабрали документ" + +#: ../../po/../src/dialogs/stroke-style.cpp:992 +msgid "Stroke width" +msgstr "Ширина потеза" + +#. Join type +#. TRANSLATORS: The line join style specifies the shape to be used at the +#. corners of paths. It can be "miter", "round" or "bevel". +#: ../../po/../src/dialogs/stroke-style.cpp:1015 +msgid "Join:" +msgstr "Прикључи:" + +#. TRANSLATORS: Miter join: joining lines with a sharp (pointed) corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1027 +msgid "Miter join" +msgstr "Оштри спојевиви" + +#. TRANSLATORS: Round join: joining lines with a rounded corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1035 +msgid "Round join" +msgstr "Заобљени спојеви" + +#. TRANSLATORS: Bevel join: joining lines with a blunted (flattened) corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1043 +msgid "Bevel join" +msgstr "Равни спојеви" + +#. Miterlimit +#. TRANSLATORS: Miter limit: only for "miter join", this limits the length +#. of the sharp "spike" when the lines connect at too sharp an angle. +#. When two line segments meet at a sharp angle, a miter join results in a +#. spike that extends well beyond the connection point. The purpose of the +#. miter limit is to cut off such spikes (i.e. convert them into bevels) +#. when they become too long. +#: ../../po/../src/dialogs/stroke-style.cpp:1054 +msgid "Miter limit:" +msgstr "Дужина споја:" + +#: ../../po/../src/dialogs/stroke-style.cpp:1062 +msgid "Maximum length of the miter (in units of stroke width)" +msgstr "Максимална дужина оштрих спојева (у јединицама ширине линије)" + +#. Cap type +#. TRANSLATORS: cap type specifies the shape for the ends of lines +#: ../../po/../src/dialogs/stroke-style.cpp:1075 +msgid "Cap:" +msgstr "Завршетак:" + +#. TRANSLATORS: Butt cap: the line shape does not extend beyond the end point +#. of the line; the ends of the line are square +#: ../../po/../src/dialogs/stroke-style.cpp:1086 +msgid "Butt cap" +msgstr "Раван завршетак" + +#. TRANSLATORS: Round cap: the line shape extends beyond the end point of the +#. line; the ends of the line are rounded +#: ../../po/../src/dialogs/stroke-style.cpp:1093 +msgid "Round cap" +msgstr "Заобљени завршетак" + +#. TRANSLATORS: Square cap: the line shape extends beyond the end point of the +#. line; the ends of the line are square +#: ../../po/../src/dialogs/stroke-style.cpp:1100 +msgid "Square cap" +msgstr "Квадратни завршетак" + +#. Dash +#: ../../po/../src/dialogs/stroke-style.cpp:1106 +msgid "Dashes:" +msgstr "Линија:" + +#. TRANSLATORS: Path markers are an SVG feature that allows you to attach arbitrary shapes +#. (arrowheads, bullets, faces, whatever) to the start, end, or middle nodes of a path. +#: ../../po/../src/dialogs/stroke-style.cpp:1127 +msgid "Start Markers:" +msgstr "Почетак:" + +#: ../../po/../src/dialogs/stroke-style.cpp:1137 +msgid "Mid Markers:" +msgstr "Средина:" + +#: ../../po/../src/dialogs/stroke-style.cpp:1148 +msgid "End Markers:" +msgstr "Завршетак:" + +#: ../../po/../src/dialogs/swatches.cpp:424 +#, c-format +msgid "Palettes directory (%s) is unavailable." +msgstr "Директоријум палета (%s) није доступан." + +#. TODO: Insert widgets +#: ../../po/../src/dialogs/text-edit.cpp:199 +#: ../../po/../src/ui/dialog/text-properties.cpp:36 +msgid "Font" +msgstr "Фонт" + +#: ../../po/../src/dialogs/text-edit.cpp:216 +msgid "Layout" +msgstr "Распоред" + +#: ../../po/../src/dialogs/text-edit.cpp:229 +msgid "Align lines left" +msgstr "Лево поравнање" + +#. TRANSLATORS: `Center' here is a verb. +#: ../../po/../src/dialogs/text-edit.cpp:243 +msgid "Center lines" +msgstr "Централно поравнање" + +#: ../../po/../src/dialogs/text-edit.cpp:256 +msgid "Align lines right" +msgstr "Десно поравнање" + +#: ../../po/../src/dialogs/text-edit.cpp:278 +msgid "Horizontal text" +msgstr "Водоравни текст" + +#: ../../po/../src/dialogs/text-edit.cpp:292 +msgid "Vertical text" +msgstr "Усправни текст" + +#: ../../po/../src/dialogs/text-edit.cpp:307 +msgid "Line spacing:" +msgstr "Размак линија:" + +#: ../../po/../src/dialogs/text-edit.cpp:400 +msgid "Set as default" +msgstr "Постави као подразумевано" + +#: ../../po/../src/dialogs/tiledialog.cpp:603 +msgid "Rows:" +msgstr "Редова:" + +#: ../../po/../src/dialogs/tiledialog.cpp:613 +msgid "Number of rows" +msgstr "Број редова" + +#: ../../po/../src/dialogs/tiledialog.cpp:617 +msgid "Equal height" +msgstr "Иста висина" + +#: ../../po/../src/dialogs/tiledialog.cpp:627 +msgid "If not set, each row has the height of the tallest object in it" +msgstr "Ако није постављено, сваки ред има висину највишег објекта у њему" + +#. #### Radio buttons to control vertical alignment #### +#. #### Radio buttons to control horizontal alignment #### +#: ../../po/../src/dialogs/tiledialog.cpp:637 +#: ../../po/../src/dialogs/tiledialog.cpp:708 +msgid "Align:" +msgstr "Поравнање:" + +#: ../../po/../src/dialogs/tiledialog.cpp:672 +msgid " X " +msgstr " X " + +#. #### Number of columns #### +#: ../../po/../src/dialogs/tiledialog.cpp:678 +msgid "Columns:" +msgstr "Колона:" + +#: ../../po/../src/dialogs/tiledialog.cpp:688 +msgid "Number of columns" +msgstr "Број колона" + +#: ../../po/../src/dialogs/tiledialog.cpp:692 +msgid "Equal width" +msgstr "Иста ширина" + +#: ../../po/../src/dialogs/tiledialog.cpp:701 +msgid "If not set, each column has the width of the widest object in it" +msgstr "Ако није псотављено, свака колона има ширину најширег објекта у њему" + +#. #### Radio buttons to control spacing manually or to fit selection bbox #### +#: ../../po/../src/dialogs/tiledialog.cpp:746 +msgid "Fit into selection box" +msgstr "Прилагоди изабору" + +#: ../../po/../src/dialogs/tiledialog.cpp:753 +msgid "Set spacing:" +msgstr "Постави растојање:" + +#. #### Y Padding #### +#: ../../po/../src/dialogs/tiledialog.cpp:777 +msgid "Row spacing: " +msgstr "Размак редова:" + +#: ../../po/../src/dialogs/tiledialog.cpp:786 +msgid "Vertical spacing between rows" +msgstr "Усправни размак између редова" + +#. #### X padding #### +#: ../../po/../src/dialogs/tiledialog.cpp:795 +msgid "Column spacing:" +msgstr "Размак колона:" + +#: ../../po/../src/dialogs/tiledialog.cpp:804 +msgid "Horizontal spacing between columns" +msgstr "Водоравни размак између колона" + +#: ../../po/../src/dialogs/tiledialog.cpp:818 +#, fuzzy +msgid "Arrange selected objects" +msgstr "Групиши изабране објекте" + +#: ../../po/../src/dialogs/xml-tree.cpp:178 +msgid "Click to select nodes, drag to rearrange." +msgstr "Клик за избор чвора, превлачење за преуређивање." + +#: ../../po/../src/dialogs/xml-tree.cpp:189 +msgid "Click attribute to edit." +msgstr "Клик на атрибут за уређивање" + +#: ../../po/../src/dialogs/xml-tree.cpp:193 +#, c-format +msgid "" +"Attribute %s selected. Press Ctrl+Enter when done editing to " +"commit changes." +msgstr "" +"Изабран је атрибут %s. Притисните Ctrl+Enter када завршите " +"уређивање да би измене биле прихваћене." + +#: ../../po/../src/dialogs/xml-tree.cpp:284 +msgid "Drag to reorder nodes" +msgstr "Превуците за прерасподеђивање чворова" + +#: ../../po/../src/dialogs/xml-tree.cpp:304 +msgid "New element node" +msgstr "Нови чвор у елементу" + +#: ../../po/../src/dialogs/xml-tree.cpp:326 +msgid "New text node" +msgstr "Нови чвор за текст" + +#: ../../po/../src/dialogs/xml-tree.cpp:347 +msgid "Duplicate node" +msgstr "Удвостручи чвор" + +#: ../../po/../src/dialogs/xml-tree.cpp:368 +msgid "Delete node" +msgstr "Уклони чвор" + +#: ../../po/../src/dialogs/xml-tree.cpp:384 +msgid "Unindent node" +msgstr "Извуци чвор" + +#: ../../po/../src/dialogs/xml-tree.cpp:399 +msgid "Indent node" +msgstr "Увуци чвор" + +#: ../../po/../src/dialogs/xml-tree.cpp:411 +msgid "Raise node" +msgstr "Издигни чвор" + +#: ../../po/../src/dialogs/xml-tree.cpp:423 +msgid "Lower node" +msgstr "Заклони чвор" + +#: ../../po/../src/dialogs/xml-tree.cpp:468 +msgid "Delete attribute" +msgstr "Обриши особину" + +#. TRANSLATORS: "Attribute" is a noun here +#: ../../po/../src/dialogs/xml-tree.cpp:513 +msgid "Attribute name" +msgstr "Назив особине" + +#. TRANSLATORS: "Set" is a verb here +#: ../../po/../src/dialogs/xml-tree.cpp:533 +msgid "Set attribute" +msgstr "Постави особину" + +#. TRANSLATORS: "Set" is a verb here +#: ../../po/../src/dialogs/xml-tree.cpp:535 +msgid "Set" +msgstr "Постави" + +#. TRANSLATORS: "Attribute" is a noun here +#: ../../po/../src/dialogs/xml-tree.cpp:558 +msgid "Attribute value" +msgstr "Вредност особине" + +#: ../../po/../src/dialogs/xml-tree.cpp:1318 +msgid "New element node..." +msgstr "Нови чвор елемента..." + +#: ../../po/../src/dialogs/xml-tree.cpp:1339 +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:100 +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:98 +msgid "Cancel" +msgstr "Откажи" + +#: ../../po/../src/dialogs/xml-tree.cpp:1345 +msgid "Create" +msgstr "Направи" + +#: ../../po/../src/dialogs/xml-tree.cpp:1458 +#, c-format +msgid "" +"Cannot set %s: Another element with value %s already exists!" +msgstr "" +"Не могу да поставим %s: Већ постоји атрибут са вредношћу %s" + +#: ../../po/../src/document.cpp:369 +#, c-format +msgid "New document %d" +msgstr "Нови документ %d" + +#: ../../po/../src/document.cpp:401 +#, c-format +msgid "Memory document %d" +msgstr "Меморијски документ %d" + +#: ../../po/../src/document.cpp:524 +#, c-format +msgid "Unnamed document %d" +msgstr "Неименовани документ %d" + +#. We hit green anchor, closing Green-Blue-Red +#: ../../po/../src/draw-context.cpp:441 +msgid "Path is closed." +msgstr "Крива је затворена." + +#. We hit bot start and end of single curve, closing paths +#: ../../po/../src/draw-context.cpp:456 +msgid "Closing path." +msgstr "Затварање криве." + +#. alpha of color under cursor, to show in the statusbar +#. locale-sensitive printf is OK, since this goes to the UI, not into SVG +#: ../../po/../src/dropper-context.cpp:354 +#, c-format +msgid " alpha %.3g" +msgstr " провидност %.3g" + +#. where the color is picked, to show in the statusbar +#: ../../po/../src/dropper-context.cpp:356 +#, c-format +msgid ", averaged with radius %d" +msgstr ", пресек полупречника %d" + +#: ../../po/../src/dropper-context.cpp:356 +msgid " under cursor" +msgstr " под курсором" + +#. message, to show in the statusbar +#: ../../po/../src/dropper-context.cpp:358 +msgid "Release mouse to set color." +msgstr "Отпустите тастер миша за постављање боје." + +#: ../../po/../src/dropper-context.cpp:358 +#: ../../po/../src/tools-switch.cpp:207 +msgid "" +"Click to set fill, Shift+click to set stroke; drag to " +"average color in area; with Alt to pick inverse color; Ctrl+C " +"to copy the color under mouse to clipboard" +msgstr "" +"Клик поставља попуну, Shift+клик линију. Превлачењем се " +"узима просечна боја површине. Alt за изокренуту боју. Ctrl+Ц " +"за копирање боје испод курсора у клипборд" + +#: ../../po/../src/extension/dependency.cpp:244 +msgid "Dependency::" +msgstr "зависност::" + +#: ../../po/../src/extension/dependency.cpp:245 +msgid " type: " +msgstr " врста: " + +#: ../../po/../src/extension/dependency.cpp:246 +msgid " location: " +msgstr " локација: " + +#: ../../po/../src/extension/dependency.cpp:247 +msgid " string: " +msgstr " текст: " + +#: ../../po/../src/extension/dependency.cpp:250 +msgid " description: " +msgstr " опис: " + +#. static int i = 0; +#. std::cout << "Checking module[" << i++ << "]: " << name << std::endl; +#: ../../po/../src/extension/extension.cpp:244 +msgid "" +" This is caused by an improper .inx file for this extension. An improper ." +"inx file could have been caused by a faulty installation of Inkscape." +msgstr "" +" Ово је проузроковано неприкладном .inx датотеком за ову екстензију. " +"Неприкладна.inx датотека може да буде резултат грешке при инсталацији " +"Инкскејпа." + +#: ../../po/../src/extension/extension.cpp:247 +msgid "an ID was not defined for it." +msgstr "ИД није одређен за њу." + +#: ../../po/../src/extension/extension.cpp:251 +msgid "there was no name defined for it." +msgstr "назив није одређен за њу." + +#: ../../po/../src/extension/extension.cpp:255 +msgid "the XML description of it got lost." +msgstr "изгубљен је XML опис за њу." + +#: ../../po/../src/extension/extension.cpp:259 +msgid "no implementation was defined for the extension." +msgstr "извршавање није постављено за екстензију." + +#. std::cout << "Failed: " << *(_deps[i]) << std::endl; +#: ../../po/../src/extension/extension.cpp:266 +msgid "a dependency was not met." +msgstr "зависност није пронађена." + +#: ../../po/../src/extension/extension.cpp:286 +msgid "Extension \"" +msgstr "Проширење „" + +#: ../../po/../src/extension/extension.cpp:286 +msgid "\" failed to load because " +msgstr "“ не може да се учита зато што " + +#: ../../po/../src/extension/extension.cpp:565 +#, c-format +msgid "Could not create extension error log file '%s'" +msgstr "Не могу да направим дневник грешака проширења „%s“" + +#. This is some filler text, needs to change before relase +#: ../../po/../src/extension/error-file.cpp:56 +msgid "" +"One or more extensions failed to load\n" +"\n" +"The failed extensions have been skipped. Inkscape will continue to run " +"normally but those extensions will be unavailable. For details to " +"troubleshoot this problem, please refer to the error log located at: " +msgstr "" +"Једна или више екстензија неуспешно " +"учитана\n" +"\n" +"Проблематичне екстензије су прескочене. Инкскејп ће наставити извршавање, " +"али ове екстензије неће бити доступне. За детаље о отклањању ових грешака, " +"погледајте дневник гершака сачуван у: " + +#. This is some filler text, needs to change before relase +#: ../../po/../src/extension/error-file.cpp:65 +msgid "Show dialog on startup" +msgstr "Прикажи ову поруку при сваком покретању програма" + +#: ../../po/../src/extension/implementation/script.cpp:845 +#, fuzzy +msgid "" +"Inkscape has received an error from the script that it called. The text " +"returned with the error is included below. Inkscape will continue working, " +"but the action you requested has been cancelled." +msgstr "" +"Inkscape је добио грешку од позване скрипте. Добијени текст грешке је ниже " +"приказан. Inkscape ће наставити са радом, али је захтевана акција " +"обустављена." + +#: ../../po/../src/extension/implementation/script.cpp:858 +#, fuzzy +msgid "" +"Inkscape has received additional data from the script executed. The script " +"did not return an error, but this may indicate the results will not be as " +"expected." +msgstr "" +"Inkscape је добио додатне податке од скрипте која је извршена. Скрипта није " +"вратила грешку, али ово може да значи да резултат неће изгледати како се " +"очекује." + +#: ../../po/../src/extension/init.cpp:173 +msgid "Null external module directory name. Modules will not be loaded." +msgstr "" +"Нема назива директоријума за екстерне модуле. Никакви модули неће бити " +"учитани." + +#: ../../po/../src/extension/init.cpp:187 +#, c-format +msgid "" +"Modules directory (%s) is unavailable. External modules in that directory " +"will not be loaded." +msgstr "" +"Директоријум са модулима (%s) је недоступан. Спољашњи модули у том " +"директоријуму неће бити учитани." + +#: ../../po/../src/extension/internal/gnome.cpp:80 +msgid "Select printer" +msgstr "Избор штампача" + +#: ../../po/../src/extension/internal/gnome.cpp:131 +msgid "Inkscape: Print Preview" +msgstr "Инкскејп: Преглед пред штампу" + +#: ../../po/../src/extension/internal/grid.cpp:213 +msgid "Line Width" +msgstr "Ширина линије" + +#: ../../po/../src/extension/internal/grid.cpp:214 +msgid "Horizontal Spacing" +msgstr "Водоравни размак" + +#: ../../po/../src/extension/internal/grid.cpp:215 +msgid "Vertical Spacing" +msgstr "Усправни размак" + +#: ../../po/../src/extension/internal/grid.cpp:216 +msgid "Horizontal Offset" +msgstr "Водоравни померај" + +#: ../../po/../src/extension/internal/grid.cpp:217 +msgid "Vertical Offset" +msgstr "Усправни померај" + +#: ../../po/../src/extension/internal/ps.cpp:123 +msgid "Print Destination" +msgstr "Одредиште штампе" + +#. Print properties frame +#: ../../po/../src/extension/internal/ps.cpp:138 +msgid "Print properties" +msgstr "Особине штампе" + +#: ../../po/../src/extension/internal/ps.cpp:145 +msgid "Print using PostScript operators" +msgstr "Штампај помоћу ПостСкрипт оператора" + +#: ../../po/../src/extension/internal/ps.cpp:147 +msgid "" +"Use PostScript vector operators. The resulting image is usually smaller in " +"file size and can be arbitrarily scaled, but alpha transparency and patterns " +"will be lost." +msgstr "" +"Користе се векторски оператори из PostScript-а. Добијена слика ће вероватно " +"бити умањена и датотека ће бити мање величине, али провидност и обрасци ће " +"бити изгубљени" + +#: ../../po/../src/extension/internal/ps.cpp:152 +msgid "Print as bitmap" +msgstr "Штампај као битмапу" + +#: ../../po/../src/extension/internal/ps.cpp:154 +msgid "" +"Print everything as bitmap. The resulting image is usually larger in file " +"size and cannot be arbitrarily scaled without quality loss, but all objects " +"will be rendered exactly as displayed." +msgstr "" +"Штампаће се као битмапа. Добијена слика ће вероватно бити већа и неће моћи " +"да се увећава без губитка на квалитету, што зависи од размере увећања, али " +"сва графика ће се исцртати исто као што је и приказана" + +#: ../../po/../src/extension/internal/ps.cpp:168 +msgid "Preferred resolution (dots per inch) of bitmap" +msgstr "Жељена резолуција (тачака по инчу) битмапе" + +#: ../../po/../src/extension/internal/ps.cpp:182 +msgid "Resolution:" +msgstr "Резолуција:" + +#. Print destination frame +#: ../../po/../src/extension/internal/ps.cpp:186 +msgid "Print destination" +msgstr "Одредиште штампе" + +#: ../../po/../src/extension/internal/ps.cpp:192 +msgid "" +"Use '> filename' to print to file.\n" +"Use '| prog arg...' to pipe to a program." +msgstr "" +"Користите „> датотека“ за штампање у датотеку.\n" +"Користите „| програм аргумент...“ за прослеђивање програму." + +#: ../../po/../src/extension/internal/ps.cpp:1227 +msgid "write error occurred" +msgstr "грешка при писању" + +#: ../../po/../src/extension/prefdialog.cpp:21 +msgid " Preferences" +msgstr " Поставке" + +#. We can't call sp_ui_error_dialog because we may be +#. running from the console, in which case calling sp_ui +#. routines will cause a segfault. See bug 1000350 - bryce +#. sp_ui_error_dialog(_("Format autodetect failed. The file is being opened as SVG.")); +#: ../../po/../src/extension/system.cpp:105 +msgid "Format autodetect failed. The file is being opened as SVG." +msgstr "" +"Аутоматско препознавање формата није успело. Датотека је отворена као СВГ." + +#. TRANSLATORS: default.svg is localizable - this is the name of the default document +#. template. This way you can localize the default pagesize, translate the name of +#. the default layer, etc. If you wish to localize this file, please create a +#. localized share/templates/default.xx.svg file, where xx is your language code. +#: ../../po/../src/file.cpp:133 +msgid "default.svg" +msgstr "default.svg" + +#: ../../po/../src/file.cpp:215 ../../po/../src/file.cpp:900 +#, c-format +msgid "Failed to load the requested file %s" +msgstr "Не моћу да учитам захтевану датотеку %s" + +#: ../../po/../src/file.cpp:240 +msgid "Document not saved yet. Cannot revert." +msgstr "Документ још увек није сачуван. Не могу да повратим пређашње стање." + +#: ../../po/../src/file.cpp:246 +#, c-format +msgid "Changes will be lost! Are you sure you want to reload document %s?" +msgstr "" +"Измене ће бити изгубљене! Да ли сте сигурни да желите поново да учитате " +"документ %s?" + +#: ../../po/../src/file.cpp:266 +msgid "Document reverted." +msgstr "Документ повраћен на пређашње стање." + +#: ../../po/../src/file.cpp:268 +msgid "Document not reverted." +msgstr "Документ није повраћен на пређашње стање." + +#: ../../po/../src/file.cpp:382 +msgid "Select file to open" +msgstr "Изаберите коју датотеку желите да отворите" + +#: ../../po/../src/file.cpp:518 +#, c-format +msgid "Removed %i unused definition in <defs>." +msgid_plural "Removed %i unused definitions in <defs>." +msgstr[0] "Уклоњена %i неискоришћена ставка у <defs>." +msgstr[1] "Уклоњено %i неискоришћених ставки у <defs>." + +#: ../../po/../src/file.cpp:523 +msgid "No unused definitions in <defs>." +msgstr "Нема неискоришћених ставки у <defs>." + +#: ../../po/../src/file.cpp:548 +#, c-format +msgid "" +"No Inkscape extension found to save document (%s). This may have been " +"caused by an unknown filename extension." +msgstr "" +"Инкскејп екстензија за чување документа није пронађена (%s). Могући разлог " +"овоме је непозната екстензија датотеке." + +#: ../../po/../src/file.cpp:549 ../../po/../src/file.cpp:557 +msgid "Document not saved." +msgstr "Документ није сачуван." + +#: ../../po/../src/file.cpp:556 +#, c-format +msgid "File %s could not be saved." +msgstr "Датотека %s не може бити сачувана." + +#: ../../po/../src/file.cpp:566 +msgid "Document saved." +msgstr "Документ је сачуван." + +#: ../../po/../src/file.cpp:614 +#, c-format +msgid "drawing%s" +msgstr "цртеж%s" + +#: ../../po/../src/file.cpp:620 +#, c-format +msgid "drawing-%d%s" +msgstr "цртеж-%d%s" + +#: ../../po/../src/file.cpp:655 +msgid "Select file to save to" +msgstr "Изаберите датотеку у коју желите да сачувате документ" + +#: ../../po/../src/file.cpp:739 +msgid "No changes need to be saved." +msgstr "Нема измена потребних за снимање." + +#: ../../po/../src/file.cpp:926 +msgid "Select file to import" +msgstr "Одаберите датотеку за увоз" + +#: ../../po/../src/gradient-context.cpp:263 +msgid "Ctrl: snap gradient angle" +msgstr "Ctrl: пријањање угла прелива" + +#: ../../po/../src/gradient-context.cpp:264 +msgid "Shift: draw gradient around the starting point" +msgstr "Shift: исцртава прелив са центром у почетној тачки" + +#. We did an undoable action, but sp_document_done will be called by the knot when released +#. status text; we do not track coords because this branch is run once, not all the time +#. during drag +#: ../../po/../src/gradient-context.cpp:462 +#, c-format +msgid "Gradient for %d objects; with Ctrl to snap angle" +msgstr "Прелив за %d објеката; Ctrl за пријањање угла" + +#: ../../po/../src/gradient-context.cpp:464 +msgid "Select objects on which to create gradient." +msgstr "Изаберите објекат за који ће се направити прелив." + +#: ../../po/../src/gradient-drag.cpp:65 +msgid "Linear gradient start" +msgstr "почетак линијског прелива" + +#. POINT_LG_P1 +#: ../../po/../src/gradient-drag.cpp:66 +msgid "Linear gradient end" +msgstr "Звршетак лнијског прелива" + +#: ../../po/../src/gradient-drag.cpp:67 +msgid "Radial gradient center" +msgstr "Средина кружног прелива" + +#: ../../po/../src/gradient-drag.cpp:68 ../../po/../src/gradient-drag.cpp:69 +msgid "Radial gradient radius" +msgstr "Полупречник кружног прелива" + +#: ../../po/../src/gradient-drag.cpp:70 +msgid "Radial gradient focus" +msgstr "Жижа кружног прелива" + +#: ../../po/../src/gradient-drag.cpp:659 +#, c-format +msgid "" +"%s for: %s%s; drag with Ctrl to snap angle, with Ctrl+Alt to " +"preserve angle, with Ctrl+Shift to scale around center" +msgstr "" +"%s за: %s%s; повлачење са Ctrl за пријањање угла, са Ctrl+Altза закључавање угла, са Ctrl+Shift за промену величине око средине" + +#: ../../po/../src/gradient-drag.cpp:662 +msgid " (stroke)" +msgstr " (линија)" + +#: ../../po/../src/gradient-drag.cpp:665 +msgid "" +"Radial gradient center and focus; drag with Shift to " +"separate focus" +msgstr "" +"Средина и жижа кружног прелива; превлачење са Shift за " +"раздвајање жиже" + +#: ../../po/../src/gradient-drag.cpp:667 +#, c-format +msgid "" +"Gradient point shared by %d gradients; drag with Shift to " +"separate" +msgstr "" +"Тачка прелива садржана у %d прелива; превлачење са Shift за " +"раздвајање" + +#: ../../po/../src/helper/units.cpp:40 +msgid "Unit" +msgstr "Јединица мере" + +#: ../../po/../src/helper/units.cpp:40 +msgid "Units" +msgstr "Јединице мере" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Point" +msgstr "штампарска тачка" + +#: ../../po/../src/helper/units.cpp:41 +msgid "pt" +msgstr "pt" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Points" +msgstr "штампарских тачака" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Pt" +msgstr "Pt" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Pixel" +msgstr "тачка" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Pixels" +msgstr "тачке" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Px" +msgstr "Px" + +#. You can add new elements from this point forward +#: ../../po/../src/helper/units.cpp:44 ../share/extensions/straightseg.inx.h:2 +msgid "Percent" +msgstr "проценат" + +#: ../../po/../src/helper/units.cpp:44 +msgid "Percents" +msgstr "процената" + +#: ../../po/../src/helper/units.cpp:45 +msgid "Millimeter" +msgstr "милиметар" + +#: ../../po/../src/helper/units.cpp:45 +msgid "mm" +msgstr "mm" + +#: ../../po/../src/helper/units.cpp:45 +msgid "Millimeters" +msgstr "милиметара" + +#: ../../po/../src/helper/units.cpp:46 +msgid "Centimeter" +msgstr "центиметар" + +#: ../../po/../src/helper/units.cpp:46 +msgid "cm" +msgstr "cm" + +#: ../../po/../src/helper/units.cpp:46 +msgid "Centimeters" +msgstr "центиметара" + +#: ../../po/../src/helper/units.cpp:47 +msgid "Meter" +msgstr "метар" + +#: ../../po/../src/helper/units.cpp:47 +msgid "m" +msgstr "m" + +#: ../../po/../src/helper/units.cpp:47 +msgid "Meters" +msgstr "метара" + +#. no svg_unit +#: ../../po/../src/helper/units.cpp:48 +msgid "Inch" +msgstr "палац" + +#: ../../po/../src/helper/units.cpp:48 +msgid "in" +msgstr "in" + +#: ../../po/../src/helper/units.cpp:48 +msgid "Inches" +msgstr "палаца" + +#. Volatiles do not have default, so there are none here +#. TRANSLATORS: for info, see http://www.w3.org/TR/REC-CSS2/syndata.html#length-units +#: ../../po/../src/helper/units.cpp:51 +msgid "Em square" +msgstr "ем квадрат" + +#: ../../po/../src/helper/units.cpp:51 +msgid "em" +msgstr "em" + +#: ../../po/../src/helper/units.cpp:51 +msgid "Em squares" +msgstr "ем квадрати" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/REC-CSS2/syndata.html#length-units +#: ../../po/../src/helper/units.cpp:53 +msgid "Ex square" +msgstr "екс квадрат" + +#: ../../po/../src/helper/units.cpp:53 +msgid "ex" +msgstr "ex" + +#: ../../po/../src/helper/units.cpp:53 +msgid "Ex squares" +msgstr "екс квадрати" + +#: ../../po/../src/inkscape.cpp:468 +msgid "Untitled document" +msgstr "Неименовани документ" + +#. Show nice dialog box +#: ../../po/../src/inkscape.cpp:497 +msgid "Inkscape encountered an internal error and will close now.\n" +msgstr "ИнкСкејп је наишао на унутрашњу грешку и сада ће се затворити.\n" + +#: ../../po/../src/inkscape.cpp:498 +msgid "" +"Automatic backups of unsaved documents were done to the following " +"locations:\n" +msgstr "Аутоматски резервни примерци несачуваних докумената се чувају у:\n" + +#: ../../po/../src/inkscape.cpp:499 +msgid "Automatic backup of the following documents failed:\n" +msgstr "Није успело аутоматско снимање резервног примерака документа:\n" + +#: ../../po/../src/inkscape.cpp:634 +#, c-format +msgid "" +"Cannot create directory %s.\n" +"%s" +msgstr "" +"Не могу да направим директоријум %s.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:635 +#, c-format +msgid "" +"%s is not a valid directory.\n" +"%s" +msgstr "" +"%s није исправан директоријум.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:636 +#, c-format +msgid "" +"Cannot create file %s.\n" +"%s" +msgstr "" +"Не могу да направим датотеку %s.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:637 +#, c-format +msgid "" +"Cannot write file %s.\n" +"%s" +msgstr "" +"Не могу да запишем датотеку %s.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:638 +msgid "" +"Although Inkscape will run, it will use default settings,\n" +"and any changes made in preferences will not be saved." +msgstr "" +"Иако ће ИнкСкејп бити покренут, користиће се подразумевана подешавања,\n" +"и било какве измене у подешавањима неће бити сачуване." + +#: ../../po/../src/inkscape.cpp:708 +#, c-format +msgid "" +"%s is not a regular file.\n" +"%s" +msgstr "" +"%s није права датотека.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:709 +#, c-format +msgid "" +"%s not a valid XML file, or\n" +"you don't have read permissions on it.\n" +"%s" +msgstr "" +"%s није исправна XML датотека, или\n" +"немате права читања за њу.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:711 +#, fuzzy, c-format +msgid "" +"%s is not a valid menus file.\n" +"%s" +msgstr "" +"%s није исправна датотека подешавања.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:712 +#, fuzzy +msgid "" +"Inkscape will run with default menus.\n" +"New menus will not be saved." +msgstr "" +"ИнкСкејп ће бити покренут са подразумеваним подешавањима.\n" +"Нова подешавања неће бити сачувана." + +#. sp_ui_menu_append_check_item_from_verb(m, view, _("_Menu"), _("Show or hide the menu bar"), "menu", +#. checkitem_toggled, checkitem_update, 0); +#: ../../po/../src/interface.cpp:753 +msgid "Commands Bar" +msgstr "Линија наредби" + +#: ../../po/../src/interface.cpp:753 +msgid "Show or hide the Commands bar (under the menu)" +msgstr "Прикажи или сакриј траку наредби (испод менија)" + +#: ../../po/../src/interface.cpp:755 +msgid "Tool Controls" +msgstr "Контрола алата" + +#: ../../po/../src/interface.cpp:755 +msgid "Show or hide the Tool Controls panel" +msgstr "Прикажи или сакриј траку за контролна подешавања алата" + +#: ../../po/../src/interface.cpp:757 +msgid "_Toolbox" +msgstr "_Алатке" + +#: ../../po/../src/interface.cpp:757 +msgid "Show or hide the main toolbox (on the left)" +msgstr "Прикажи или сакриј главну траку алата (уз леву ивицу)" + +#: ../../po/../src/interface.cpp:763 +msgid "_Statusbar" +msgstr "_Статусна линија" + +#: ../../po/../src/interface.cpp:763 +msgid "Show or hide the statusbar (at the bottom of the window)" +msgstr "Прикажи или сакриј статустну линију (на дну прозора)" + +#: ../../po/../src/interface.cpp:820 +#, c-format +msgid "Verb \"%s\" Unknown" +msgstr "" + +#. TRANSLATORS: #%s is the id of the group e.g. , not a number. +#: ../../po/../src/interface.cpp:930 +#, c-format +msgid "Enter group #%s" +msgstr "Уђи у групу #%s" + +#: ../../po/../src/interface.cpp:941 +msgid "Go to parent" +msgstr "Прелазак на родитељски слој" + +#: ../../po/../src/interface.cpp:972 +msgid "Could not parse SVG data" +msgstr "Не могу да обрадим СВГ податке" + +#: ../../po/../src/interface.cpp:1135 +#, c-format +msgid "Overwrite %s" +msgstr "Препиши %s" + +#: ../../po/../src/interface.cpp:1153 +#, c-format +msgid "" +"The file %s already exists. Do you want to overwrite that file with the " +"current document?" +msgstr "" +"Датотека %s већ постоји. Да ли желите да је препишете са тренутним " +"документом?" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:59 +msgid "Jabber connection lost." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:72 +#, c-format +msgid "Sending message; %u message remaining in send queue." +msgid_plural "Sending message; %u messages remaining in send queue." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:78 +msgid "Receive queue empty." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:154 +#, c-format +msgid "Receiving change; %u change left to process." +msgid_plural "Receiving change; %u changes left to process." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:157 +#, c-format +msgid "%s has left the chatroom." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:221 +msgid "Nickname %1 is already in use. Please choose a different nickname." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:225 +msgid "An error was encountered while attempting to connect to the server." +msgstr "" + +#. Check to see if the user made any modifications to this document. If so, +#. we want to give them the option of (1) letting us clear their document or (2) +#. opening a new, blank document for the whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:131 +msgid "%1 has invited you to a whiteboard session." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:132 +msgid "Incoming whiteboard invitation from %1" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:135 +msgid "Do you wish to accept %1's whiteboard session invitation?" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:137 +msgid "" +"Would you like to accept %1's invitation in a new document window?\n" +"Accepting the invitation in your current window will discard unsaved changes." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:143 +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:198 +#, fuzzy +msgid "Accept invitation" +msgstr "Убрзање" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:144 +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:199 +msgid "Decline invitation" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:145 +#, fuzzy +msgid "Accept invitation in new document window" +msgstr "Направи нови СВГ документ" + +#. We could not create a new desktop; ask the user if she or he wants to +#. replace the current document and accept the invitation, or reject the invitation. +#. TRANSLATORS: %1 is a userid here +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:196 +msgid "" +"A new document window could not be opened for a whiteboard session with %" +"1" +msgstr "" + +#. TRANSLATORS: %1 is the peer whom refused our invitation. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:238 +msgid "" +"The user %1 has refused your " +"whiteboard invitation.\n" +"\n" +msgstr "" + +#. TRANSLATORS: %1 is the peer whom refused our invitation, %2 is our Jabber identity. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:241 +msgid "" +"You are still connected to a Jabber server as %2, and may send an " +"invitation to %1 again, or you may send an invitation to a different " +"user." +msgstr "" + +#. TRANSLATORS: %1 is the peer whom we tried to contact, but is already in a whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:252 +msgid "" +"The user %1 is already in a " +"whiteboard session.\n" +"\n" +msgstr "" + +#. TRANSLATORS: %1 is the peer whom we tried to contact, but is already in a whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:255 +msgid "" +"You are still connected to a Jabber server as %1, and may send an " +"invitation to a different user." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/invitation-confirm-dialog.cpp:26 +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:24 +msgid "_Write session file:" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/message-processors.cpp:145 +#, c-format +msgid "%s has joined the chatroom." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/message-queue.cpp:87 +#, fuzzy, c-format +msgid "%u change in receive queue." +msgid_plural "%u changes in receive queue." +msgstr[0] "Нема измена потребних за снимање." +msgstr[1] "Нема измена потребних за снимање." + +#: ../../po/../src/jabber_whiteboard/message-queue.cpp:117 +#, fuzzy, c-format +msgid "%u change in send queue." +msgid_plural "%u changes in send queue." +msgstr[0] "Нема измена потребних за снимање." +msgstr[1] "Нема измена потребних за снимање." + +#. if ID is NULL, then we have a real problem -- we were not able to find a key +#. nor generate one. The only thing we can really do here is abort, since we have +#. no way to let the other client(s) uniquely identify this object. +#. FIXME: If this indicates a programming bug, then don't request translation with +#. * _(...): it is most useful in untranslated form so that developers may search for +#. * it when someone reports it in a bug report (as we want users to do for all bugs, +#. * as indicated by it being a g_warning string). +#. * +#. * Otherwise, if it is not a programming bug but a network error or a bug in the +#. * remote peer (perhaps running different software) or whatever, then present it in +#. * an alert box, and avoid use of technical jargon `NULL'. +#. +#: ../../po/../src/jabber_whiteboard/message-utilities.cpp:171 +msgid "" +"ID for new object is NULL even after generation and lookup attempts: the new " +"object will NOT be sent, nor will any of its child objects!" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:60 +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:995 +msgid "Select a location and filename" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:62 +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:997 +#, fuzzy +msgid "Set filename" +msgstr "Назив _датотеке" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:301 +msgid "No SSL certificate was found." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:304 +msgid "The SSL certificate provided by the Jabber server is untrusted." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:307 +msgid "The SSL certificate provided by the Jabber server is expired." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:310 +msgid "" +"The SSL certificate provided by the Jabber server has not been activated." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:313 +msgid "" +"The SSL certificate provided by the Jabber server contains a hostname that " +"does not match the Jabber server's hostname." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:316 +msgid "" +"The SSL certificate provided by the Jabber server contains an invalid " +"fingerprint." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:319 +msgid "An unknown error occurred while setting up the SSL connection." +msgstr "" + +#. TRANSLATORS: %1 is the message that describes the specific error that occurred when +#. establishing the SSL connection. +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:325 +msgid "" +"%1\n" +"\n" +"Do you wish to continue connecting to the Jabber server?" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:328 +msgid "Continue connecting and ignore further errors" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:329 +msgid "Continue connecting, but warn me of further errors" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:330 +#, fuzzy +msgid "Cancel connection" +msgstr "Избор" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:777 +#, c-format +msgid "Established whiteboard session with %s." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:785 +#, c-format +msgid "%s has left the whiteboard session." +msgstr "" + +#. Inform the user +#. TRANSLATORS: %1 is the name of the user that disconnected, %2 is the name of the user whom the disconnected user disconnected from. +#. This message is not used in a chatroom context. +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:790 +msgid "" +"The user %1 has left the " +"whiteboard session.\n" +"\n" +msgstr "" + +#. TRANSLATORS: %1 and %2 are userids +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:792 +msgid "" +"You are still connected to a Jabber server as %2, and may establish a " +"new session to %1 or a different user." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:988 +msgid "" +"Could not open file %1 for session recording.\n" +"The error encountered was: %2.\n" +"\n" +"You may select a different location to record the session, or you may opt to " +"not record this session." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:990 +msgid "Choose a different location" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:991 +msgid "Skip session recording" +msgstr "" + +#: ../../po/../src/knot.cpp:673 +msgid "Node or handle drag canceled." +msgstr "Превлачење чвора или ручке је отказано." + +#: ../../po/../src/libnrtype/FontFactory.cpp:358 +msgid "Ignoring font without family that will crash Pango" +msgstr "Игнорисање фонта без фамилије који би оборили Панго" + +#: ../../po/../src/main.cpp:395 +msgid "Print the Inkscape version number" +msgstr "Штампај ознаку верзије Инкскејпа" + +#: ../../po/../src/main.cpp:400 +msgid "Do not use X server (only process files from console)" +msgstr "Не користи X сервер (само обрађуј датотеке преко конзоле)" + +#: ../../po/../src/main.cpp:405 +msgid "Try to use X server (even if $DISPLAY is not set)" +msgstr "" +"Покушај да користиш X сервер (чак иако променљива $DISPLAY није постављена)" + +#: ../../po/../src/main.cpp:410 +msgid "Open specified document(s) (option string may be excluded)" +msgstr "Отвори наведене документе (ниска опција се може прескочити)" + +#: ../../po/../src/main.cpp:411 ../../po/../src/main.cpp:416 +#: ../../po/../src/main.cpp:421 ../../po/../src/main.cpp:483 +#: ../../po/../src/main.cpp:488 ../../po/../src/main.cpp:493 +msgid "FILENAME" +msgstr "НАЗИВ ДАТОТЕКЕ" + +#: ../../po/../src/main.cpp:415 +msgid "Print document(s) to specified output file (use '| program' for pipe)" +msgstr "" +"Штампај документе у наведену излазну датотеку (користите „| програм“ за " +"цевку)" + +#: ../../po/../src/main.cpp:420 +msgid "Export document to a PNG file" +msgstr "Извоз документа у PNG датотеку" + +#: ../../po/../src/main.cpp:425 +msgid "The resolution used for exporting SVG into bitmap (default 90)" +msgstr "" +"Резолуција која се користи за претварање СВГ-а у битмапу (подразумевано 90)" + +#: ../../po/../src/main.cpp:426 +msgid "DPI" +msgstr "ТПИ" + +#: ../../po/../src/main.cpp:430 +#, fuzzy +msgid "" +"Exported area in SVG user units (default is the canvas; 0,0 is lower-left " +"corner)" +msgstr "" +"Површина за извоз у SVG пикселима (подразумевано је платно, 0,0 је доњи-леви " +"угао)" + +#: ../../po/../src/main.cpp:431 +msgid "x0:y0:x1:y1" +msgstr "x0:y0:x1:y1" + +#: ../../po/../src/main.cpp:435 +msgid "Exported area is the entire drawing (not canvas)" +msgstr "Површина за извоз је тренутни цртеж (а не платно)" + +#: ../../po/../src/main.cpp:440 +msgid "" +"Snap the bitmap export area outwards to the nearest integer values (in SVG " +"user units)" +msgstr "" + +#: ../../po/../src/main.cpp:445 +msgid "The width of exported bitmap in pixels (overrides export-dpi)" +msgstr "Ширина образоване битмапе у тачкама (преписује извозни ТПИ)" + +#: ../../po/../src/main.cpp:446 +msgid "WIDTH" +msgstr "ШИРИНА" + +#: ../../po/../src/main.cpp:450 +msgid "The height of exported bitmap in pixels (overrides export-dpi)" +msgstr "Висина образоване битмапе у тачкама (занемарује атрибут „export-dpi“)" + +#: ../../po/../src/main.cpp:451 +msgid "HEIGHT" +msgstr "ВИСИНА" + +#: ../../po/../src/main.cpp:455 +msgid "The ID of the object to export (overrides export-area)" +msgstr "ИД објекта за извоз (занемарује атрибут „export-area“)" + +#: ../../po/../src/main.cpp:456 ../../po/../src/main.cpp:532 +msgid "ID" +msgstr "ИД" + +#. TRANSLATORS: this means: "Only export the object whose id is given in --export-id". +#. See "man inkscape" for details. +#: ../../po/../src/main.cpp:462 +msgid "" +"Export just the object with export-id, hide all others (only with export-id)" +msgstr "" +"Извози само објекат са атрибутом „export-id“, сакрива све друге (само са " +"атрибутом „export-id“)" + +#: ../../po/../src/main.cpp:467 +msgid "Use stored filename and DPI hints when exporting (only with export-id)" +msgstr "" +"Користи сачувани назив датотеке и ТПИ резолуцију при извозу (само са " +"атрибутом „export-id“)" + +#: ../../po/../src/main.cpp:472 +msgid "Background color of exported bitmap (any SVG-supported color string)" +msgstr "" +"Боја позадине битмапе за образовање (било која ознака боје коју подржава СВГ)" + +#: ../../po/../src/main.cpp:473 +msgid "COLOR" +msgstr "БОЈА" + +#: ../../po/../src/main.cpp:477 +msgid "Background opacity of exported bitmap (either 0.0 to 1.0, or 1 to 255)" +msgstr "Боја позадине битмапе за образовање (било од 0.0 до 1.0, или 1 до 255)" + +#: ../../po/../src/main.cpp:478 +msgid "VALUE" +msgstr "ВРЕДНОСТ" + +#: ../../po/../src/main.cpp:482 +msgid "Export document to plain SVG file (no sodipodi or inkscape namespaces)" +msgstr "" +"Извези документ у обичну СВГ датотеку (без атрибута „sodipodi“ или " +"„inkscape“)" + +#: ../../po/../src/main.cpp:487 +msgid "Export document to a PS file" +msgstr "Извоз документа у PS датотеку" + +#: ../../po/../src/main.cpp:492 +msgid "Export document to an EPS file" +msgstr "Извоз документа у EPS датотеку" + +#: ../../po/../src/main.cpp:497 +msgid "Convert text object to paths on export (EPS)" +msgstr "Претвори текстуалне објекте у криве при извозу (EPS)" + +#: ../../po/../src/main.cpp:502 +msgid "Export files with the bounding box set to the page size (EPS)" +msgstr "" +"Извоз датотека са оквиром контејнера постављеним на величину стране (EPS)" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:508 +msgid "" +"Query the X coordinate of the drawing or, if specified, of the object with --" +"query-id" +msgstr "" +"Питај за X координату цртежа или, ако је постављено, објекта са --query-id" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:514 +msgid "" +"Query the Y coordinate of the drawing or, if specified, of the object with --" +"query-id" +msgstr "" +"Питај за Y координату цртежа или, ако је постављено, објекта са --query-id" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:520 +msgid "" +"Query the width of the drawing or, if specified, of the object with --query-" +"id" +msgstr "Питај за ширину цртежа или, ако је постављено, објекта са --query-id" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:526 +msgid "" +"Query the height of the drawing or, if specified, of the object with --query-" +"id" +msgstr "Питај за висину цртежа или, ако је постављено, објекта са --query-id" + +#: ../../po/../src/main.cpp:531 +msgid "The ID of the object whose dimensions are queried" +msgstr "ИД објекта за чије се димензије поставља упит" + +#. TRANSLATORS: this option makes Inkscape print the name (path) of the extension directory +#: ../../po/../src/main.cpp:537 +msgid "Print out the extension directory and exit" +msgstr "Штампа директоријум са екстензијама и напушта програм" + +#: ../../po/../src/main.cpp:542 +msgid "Show given files one-by-one, switch to next on any key/mouse event" +msgstr "" +"Приказује датотеке једну по једну, прелази на следећу након било каквог " +"догађаја са тастерима или мишем" + +#: ../../po/../src/main.cpp:547 +msgid "Use the new Gtkmm GUI interface" +msgstr "Користи нови Gtkmm графички интерфејс" + +#: ../../po/../src/main.cpp:552 +msgid "Remove unused definitions from the defs section(s) of the document" +msgstr "Уклања неупотребљене ставке из defs избора документа" + +#: ../../po/../src/main.cpp:741 +msgid "" +"[OPTIONS...] [FILE...]\n" +"\n" +"Available options:" +msgstr "" +"[ОПЦИЈЕ...] [ДАТОТЕКА...]\n" +"\n" +"Доступне опције:" + +#: ../../po/../src/menus-skeleton.h:17 +msgid "_New" +msgstr "_Ново" + +#: ../../po/../src/menus-skeleton.h:22 +msgid "Open _Recent" +msgstr "Отвори _последње коришћене" + +#: ../../po/../src/menus-skeleton.h:53 +msgid "_Edit" +msgstr "_Уређивање" + +#: ../../po/../src/menus-skeleton.h:84 +msgid "_View" +msgstr "_Преглед" + +#: ../../po/../src/menus-skeleton.h:85 +#, fuzzy +msgid "_Zoom" +msgstr "Увећај" + +#: ../../po/../src/menus-skeleton.h:102 +#, fuzzy +msgid "Show/Hide" +msgstr "_Прикажи/сакриј" + +#: ../../po/../src/menus-skeleton.h:107 +msgid "_Display mode" +msgstr "" + +#: ../../po/../src/menus-skeleton.h:126 +msgid "_Layer" +msgstr "_Слој" + +#: ../../po/../src/menus-skeleton.h:143 +msgid "_Object" +msgstr "_Објекат" + +#: ../../po/../src/menus-skeleton.h:165 +msgid "_Path" +msgstr "_Крива" + +#: ../../po/../src/menus-skeleton.h:188 +msgid "_Text" +msgstr "_Текст" + +#: ../../po/../src/menus-skeleton.h:200 +msgid "Effects" +msgstr "Ефекти" + +#: ../../po/../src/menus-skeleton.h:207 +msgid "Whiteboa_rd" +msgstr "" + +#: ../../po/../src/menus-skeleton.h:220 +msgid "_Help" +msgstr "_Помоћ" + +#: ../../po/../src/menus-skeleton.h:222 +#, fuzzy +msgid "Tutorials" +msgstr "_Вежбе" + +#: ../../po/../src/node-context.cpp:382 +msgid "" +"Ctrl: toggle node type, snap handle angle, move hor/vert; Ctrl" +"+Alt: move along handles" +msgstr "" +"Ctrl: промена типа човра, пријањање угла ручке, померање водоравно и " +"усправно; Ctrl+Alt: померање дуж ручки" + +#: ../../po/../src/node-context.cpp:383 +msgid "" +"Shift: toggle node selection, disable snapping, rotate both handles" +msgstr "" +"Shift: промена избора чвора, искључивање пријањања, ротирање обе ручке" + +#: ../../po/../src/node-context.cpp:384 +msgid "Alt: lock handle length; Ctrl+Alt: move along handles" +msgstr "Alt: фиксна дужина ручки; Ctrl+Alt: помера дуж ручки" + +#: ../../po/../src/nodepath.cpp:1399 ../../po/../src/nodepath.cpp:1411 +#: ../../po/../src/nodepath.cpp:1492 ../../po/../src/nodepath.cpp:1504 +msgid "To join, you must have two endnodes selected." +msgstr "За спајање, морате да изаберете два крајња чвора." + +#: ../../po/../src/nodepath.cpp:1633 ../../po/../src/nodepath.cpp:1647 +msgid "" +"Select two non-endpoint nodes on a path between which to delete " +"segments." +msgstr "" +"Морате да изаберете два незавршавајућа чвора на криви, између којих " +"ће сегмент бити обрисан." + +#: ../../po/../src/nodepath.cpp:1743 +msgid "Cannot find path between nodes." +msgstr "Не могу да пронађем криву између чворова." + +#: ../../po/../src/nodepath.cpp:2822 +#, fuzzy, c-format +msgid "" +"Node handle: angle %0.2f°, length %s; with Ctrl to snap " +"angle; with Alt to lock length; with Shift to rotate both " +"handles" +msgstr "" +"Ручка чвора: на %0.2f°, дужина %s; са Ctrl за пријањање " +"угла; са Alt за фиксну дужину; са Shift за ротацију обе ручке" + +#: ../../po/../src/nodepath.cpp:3351 +msgid "" +"Node: drag to edit the path; with Ctrl to snap to horizontal/" +"vertical; with Ctrl+Alt to snap to handles' directions" +msgstr "" +"Чвор: повлачењем се уређује крива; са Ctrl за пријањање " +"водоравно/усправно; са Ctrl+Alt за пријањање на правац ручке" + +#: ../../po/../src/nodepath.cpp:3375 +msgid "" +"Node handle: drag to shape the curve; with Ctrl to snap angle; " +"with Alt to lock length; with Shift to rotate both handles" +msgstr "" +"Ручка чвора: повлачење уређује криву; са Ctrl за пријањање " +"угла; са Alt за фиксну дужину; са Shift за ротацију обе ручке" + +#: ../../po/../src/nodepath.cpp:3399 +msgid "" +"Node handle: drag to shape the curve; with Ctrl to snap angle; " +"with Alt to lock length; with Shift to rotate the opposite " +"handle in sync" +msgstr "" +"Ручка чвора: повлачење уређује криву; са Ctrl за пријањање " +"угла; са Alt за фиксну дужину; са Shift за синхрону ротацију " +"супротне ручке" + +#. TRANSLATORS: "end" is an adjective here (NOT a verb) +#: ../../po/../src/nodepath.cpp:3591 +msgid "end node" +msgstr "завршни чвор" + +#. TRANSLATORS: "cusp" means "sharp" (cusp node); see also the Advanced Tutorial +#: ../../po/../src/nodepath.cpp:3596 +msgid "cusp" +msgstr "угласта крива" + +#. TRANSLATORS: "smooth" is an adjective here +#: ../../po/../src/nodepath.cpp:3599 +msgid "smooth" +msgstr "глатка крива" + +#: ../../po/../src/nodepath.cpp:3601 +msgid "symmetric" +msgstr "симетрична крива" + +#. TRANSLATORS: "end" is an adjective here (NOT a verb) +#: ../../po/../src/nodepath.cpp:3607 +msgid "end node, handle retracted (drag with Shift to extend)" +msgstr "завршни чвор, ручка одбијена (користите Shift за наставак)" + +#: ../../po/../src/nodepath.cpp:3609 +msgid "one handle retracted (drag with Shift to extend)" +msgstr "једна ручка је одбијена (користите Shift за наставак)" + +#: ../../po/../src/nodepath.cpp:3612 +msgid "both handles retracted (drag with Shift to extend)" +msgstr "обе ручке су одбијене (користите Shift за наставак)" + +#: ../../po/../src/nodepath.cpp:3624 +msgid "Drag nodes or node handles; arrow keys to move nodes" +msgstr "" +"Превлачите чворове или контролне тачке; стралице за померање " +"чворова" + +#: ../../po/../src/nodepath.cpp:3625 +msgid "Drag the node or its handles; arrow keys to move the node" +msgstr "" +"Повлачите чворове или ручке; стрелице за померање чворова" + +#: ../../po/../src/nodepath.cpp:3651 ../../po/../src/nodepath.cpp:3663 +msgid "Select a single object to edit its nodes or handles." +msgstr "Изаберите један објекат за уређивање његових чворова или ручки." + +#: ../../po/../src/nodepath.cpp:3655 +#, c-format +msgid "" +"0 out of %i node selected. Click, Shift+click, " +"or drag around nodes to select." +msgid_plural "" +"0 out of %i nodes selected. Click, Shift+click, " +"or drag around nodes to select." +msgstr[0] "" +"0 од %i чвора одабрано. Клик, Shift+клик или " +"превлачење око чвора за избор." +msgstr[1] "" +"0 од %i чворова одабрано. Клик, Shift+клик или " +"превлачење око чворова за избор." + +#: ../../po/../src/nodepath.cpp:3661 +msgid "Drag the handles of the object to modify it." +msgstr "Вуците ручке објекта за његову измену." + +#: ../../po/../src/nodepath.cpp:3669 +#, c-format +msgid "%i of %i node selected; %s. %s." +msgid_plural "%i of %i nodes selected; %s. %s." +msgstr[0] "%i од %i чвора одабрано; %s. %s." +msgstr[1] "%i од %i чворова одабрано; %s. %s." + +#: ../../po/../src/nodepath.cpp:3675 +#, c-format +msgid "%i of %i node selected. %s." +msgid_plural "%i of %i nodes selected. %s." +msgstr[0] "%i од %i чвора одабрано. %s." +msgstr[1] "%i од %i чворова одабрано. %s." + +#: ../../po/../src/object-edit.cpp:493 +msgid "" +"Adjust the horizontal rounding radius; with Ctrl to make the " +"vertical radius the same" +msgstr "" +"Прилагођавање полупречника водоравног заобљења; Ctrl за исту " +"вредност усправног полупречника" + +#: ../../po/../src/object-edit.cpp:499 +msgid "" +"Adjust the vertical rounding radius; with Ctrl to make the " +"horizontal radius the same" +msgstr "" +"Прилагођавање полупречника усправног заобљења; Ctrl за исту " +"вредност водоравног полупречника" + +#: ../../po/../src/object-edit.cpp:506 ../../po/../src/object-edit.cpp:513 +msgid "" +"Adjust the width and height of the rectangle; with Ctrl to " +"lock ratio or stretch in one dimension only" +msgstr "" +"Подеси ширину и висину правоугаоника; Ctrl закључава однос или " +"издуживање једне димензије" + +#: ../../po/../src/object-edit.cpp:686 +msgid "Adjust ellipse width, with Ctrl to make circle" +msgstr "Подешавање ширине елипсе, са Ctrl за прављење кружнице" + +#: ../../po/../src/object-edit.cpp:689 +msgid "Adjust ellipse height, with Ctrl to make circle" +msgstr "Подешавање висине елипсе, са Ctrl за прављење кружнице" + +#: ../../po/../src/object-edit.cpp:692 +msgid "" +"Position the start point of the arc or segment; with Ctrl to " +"snap angle; drag inside the ellipse for arc, outside for " +"segment" +msgstr "" + +#: ../../po/../src/object-edit.cpp:695 +msgid "" +"Position the end point of the arc or segment; with Ctrl to " +"snap angle; drag inside the ellipse for arc, outside for " +"segment" +msgstr "" + +#: ../../po/../src/object-edit.cpp:800 +msgid "" +"Adjust the tip radius of the star or polygon; with Shift to " +"round; with Alt to randomize" +msgstr "" + +#: ../../po/../src/object-edit.cpp:803 +msgid "" +"Adjust the base radius of the star; with Ctrl to keep star " +"rays radial (no skew); with Shift to round; with Alt to " +"randomize" +msgstr "" + +#: ../../po/../src/object-edit.cpp:967 +msgid "" +"Roll/unroll the spiral from inside; with Ctrl to snap angle; " +"with Alt to converge/diverge" +msgstr "" + +#: ../../po/../src/object-edit.cpp:969 +msgid "" +"Roll/unroll the spiral from outside; with Ctrl to snap angle; " +"with Shift to scale/rotate" +msgstr "" + +#: ../../po/../src/object-edit.cpp:1006 +msgid "Adjust the offset distance" +msgstr "Подеси удаљеност помераја" + +#. TRANSLATORS: This refers to the pattern that's inside the object +#: ../../po/../src/object-edit.cpp:1036 +msgid "Move the pattern fill inside the object" +msgstr "Померање попуне мустром унутар објекта" + +#: ../../po/../src/object-edit.cpp:1038 +msgid "Scale the pattern fill uniformly" +msgstr "Јединствена промена величине попуне мустром" + +#: ../../po/../src/object-edit.cpp:1040 +msgid "Rotate the pattern fill; with Ctrl to snap angle" +msgstr "" +"Ротирање попуне мустром; притисните Ctrl за пријањање на углао" + +#: ../../po/../src/object-edit.cpp:1065 +msgid "Drag to resize the flowed text frame" +msgstr "Повлачење за прмену величине плутајућег оквира текста" + +# bug: rect -> rectangle +#. Item dialog +#: ../../po/../src/object-ui.cpp:106 +msgid "Object _Properties" +msgstr "_Особине објекта" + +#. Select item +#: ../../po/../src/object-ui.cpp:116 +msgid "_Select This" +msgstr "_Изабери ово" + +#. Create link +#: ../../po/../src/object-ui.cpp:126 +msgid "_Create Link" +msgstr "_Направи везу" + +#. "Ungroup" +#: ../../po/../src/object-ui.cpp:199 ../../po/../src/verbs.cpp:1931 +msgid "_Ungroup" +msgstr "_Разгрупиши" + +#. Link dialog +#: ../../po/../src/object-ui.cpp:239 +msgid "Link _Properties" +msgstr "_Особине везе" + +#. Select item +#: ../../po/../src/object-ui.cpp:249 +msgid "_Follow Link" +msgstr "_Прати везу" + +#. Reset transformations +#: ../../po/../src/object-ui.cpp:254 +msgid "_Remove Link" +msgstr "_Уклони везу" + +#. Link dialog +#: ../../po/../src/object-ui.cpp:303 +msgid "Image _Properties" +msgstr "_Особине слике" + +#. Item dialog +#: ../../po/../src/object-ui.cpp:344 +msgid "_Fill and Stroke" +msgstr "_Попуне и линије" + +#: ../../po/../src/path-chemistry.cpp:58 +msgid "Select at least two objects to combine." +msgstr "Изаберите најмање два објекта за сједињавање." + +#: ../../po/../src/path-chemistry.cpp:65 +msgid "At least one of the objects is not a path, cannot combine." +msgstr "Један од објеката није затворена крива и не може се сјединити." + +#: ../../po/../src/path-chemistry.cpp:73 +msgid "" +"You cannot combine objects from different groups or layers." +msgstr "" +"Не можете да сједините објекте у различитим групама или слојевима." + +#: ../../po/../src/path-chemistry.cpp:155 +msgid "Select path(s) to break apart." +msgstr "Одаберите криву(е) за раскидање јединства." + +#: ../../po/../src/path-chemistry.cpp:231 +msgid "No path(s) to break apart in the selection." +msgstr "Нема криве за раскидање јединства међу изабраним објектима." + +#: ../../po/../src/path-chemistry.cpp:252 +msgid "Select object(s) to convert to path." +msgstr "Одаберите објекат за претварање у криве." + +#: ../../po/../src/path-chemistry.cpp:297 +msgid "No objects to convert to path in the selection." +msgstr "Нема објекта за претварање у криве међу изабраним објектима." + +#: ../../po/../src/path-chemistry.cpp:345 +msgid "Select path(s) to reverse." +msgstr "Изаберите криву(е) за променусмеравање." + +#: ../../po/../src/path-chemistry.cpp:370 +msgid "No paths to reverse in the selection." +msgstr "Нема криве за преусмеравање међу изабраним објектима." + +#: ../../po/../src/pen-context.cpp:379 ../../po/../src/pencil-context.cpp:233 +msgid "Continuing selected path" +msgstr "Настављање изабране криве" + +#: ../../po/../src/pen-context.cpp:390 ../../po/../src/pencil-context.cpp:242 +msgid "Creating new path" +msgstr "Прављење нове криве" + +#: ../../po/../src/pen-context.cpp:394 ../../po/../src/pencil-context.cpp:246 +msgid "Appending to selected path" +msgstr "Додавање изабраној криви" + +#: ../../po/../src/pen-context.cpp:538 +#, fuzzy +msgid "Click or click and drag to close and finish the path." +msgstr "" +"Клик за уређивање текста, превлачење за избор дела текста." + +#: ../../po/../src/pen-context.cpp:548 +#, fuzzy +msgid "" +"Click or click and drag to continue the path from this point." +msgstr "" +"Клик за уређивање текста, превлачење за избор дела текста." + +#: ../../po/../src/pen-context.cpp:857 +#, fuzzy, c-format +msgid "" +"%s: angle %3.2f°, distance %s; with Ctrl to snap angle, " +"Enter to finish the path" +msgstr "" +"Ручка чвора: на %0.2f°, дужина %s; са Ctrl за пријањање " +"угла; са Alt за фиксну дужину; са Shift за ротацију обе ручке" + +#: ../../po/../src/pen-context.cpp:882 +#, fuzzy, c-format +msgid "" +"Curve handle: angle %3.2f°, length %s; with Ctrl to snap " +"angle" +msgstr "Ротација: %0.2f°; са Ctrl за пријањање угла" + +#: ../../po/../src/pen-context.cpp:912 +#, fuzzy, c-format +msgid "" +"%s: angle %3.2f°, length %s; with Ctrl to snap angle, " +"with Shift to move this handle only" +msgstr "" +"Ручка чвора: на %0.2f°, дужина %s; са Ctrl за пријањање " +"угла; са Alt за фиксну дужину; са Shift за ротацију обе ручке" + +#: ../../po/../src/pen-context.cpp:946 +msgid "Finishing pen" +msgstr "Завршавање оловке" + +#: ../../po/../src/pencil-context.cpp:320 +msgid "Release here to close and finish the path." +msgstr "" + +#: ../../po/../src/pencil-context.cpp:326 +#, fuzzy +msgid "Drawing a freehand path" +msgstr "Исцртавање линије слободном руком" + +#: ../../po/../src/pencil-context.cpp:331 +msgid "Drag to continue the path from this point." +msgstr "" + +#. Write curves to object +#: ../../po/../src/pencil-context.cpp:390 +msgid "Finishing freehand" +msgstr "Завршавање слободне руке" + +#: ../../po/../src/rect-context.cpp:387 +msgid "" +"Ctrl: make square or integer-ratio rect, lock a rounded corner " +"circular" +msgstr "" +"Ctrl: прави квадрат или пропорционални правоугаоник, закључава " +"заобљене углове у кружницу" + +#: ../../po/../src/rect-context.cpp:549 +#, c-format +msgid "" +"Rectangle: %s × %s; with Ctrl to make square or integer-" +"ratio rectangle; with Shift to draw around the starting point" +msgstr "" +"Правоугаоник: %s × %s; са Ctrl прави квадрат или " +"пропорционални правоугаоник; са Shift црта око центра ротације" + +#: ../../po/../src/select-context.cpp:243 +msgid "Move canceled." +msgstr "Померање је отказано." + +#: ../../po/../src/select-context.cpp:252 +msgid "Selection canceled." +msgstr "Избор је отказан." + +#: ../../po/../src/select-context.cpp:642 +msgid "Ctrl: select in groups, move hor/vert" +msgstr "Ctrl: избор у групи, померање водоравно/усправно" + +#: ../../po/../src/select-context.cpp:643 +msgid "Shift: toggle select, force rubberband, disable snapping" +msgstr "" +"Shift:\tпоставља и укида избор, форсира гумицу, искључује пријањање" + +#: ../../po/../src/select-context.cpp:644 +msgid "Alt: select under, move selected" +msgstr "Alt: избор доњег објекта, померање избора" + +#: ../../po/../src/select-context.cpp:798 +#, fuzzy +msgid "Selected object is not a group. Cannot enter." +msgstr "Изабрани објекат није крива, не може да се скупља или шири." + +#: ../../po/../src/select-context.cpp:876 +#, c-format +msgid "" +"Move by %s, %s; with Ctrl to restrict to horizontal/vertical; " +"with Shift to disable snapping" +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:228 +msgid "Nothing was deleted." +msgstr "Ништа није обрисано." + +#: ../../po/../src/selection-chemistry.cpp:259 +msgid "Select object(s) to duplicate." +msgstr "Изаберите објекат за дуплирање." + +#: ../../po/../src/selection-chemistry.cpp:420 +msgid "Select two or more objects to group." +msgstr "Изаберите два или више објеката за гурписање." + +#: ../../po/../src/selection-chemistry.cpp:428 +msgid "Select at least two objects to group." +msgstr "Изаберите најмање два објекта за груписање." + +#: ../../po/../src/selection-chemistry.cpp:513 +msgid "Select a group to ungroup." +msgstr "Изаберите групу за разгруписавање." + +#: ../../po/../src/selection-chemistry.cpp:554 +msgid "No groups to ungroup in the selection." +msgstr "Нема групе за разгруписавање међу изабраним групама." + +#: ../../po/../src/selection-chemistry.cpp:623 +msgid "Select objects to raise." +msgstr "Изаберите објекат за издизање." + +#: ../../po/../src/selection-chemistry.cpp:629 +#: ../../po/../src/selection-chemistry.cpp:681 +#: ../../po/../src/selection-chemistry.cpp:715 +#: ../../po/../src/selection-chemistry.cpp:773 +msgid "" +"You cannot raise/lower objects from different groups or layers." +msgstr "" +"Не могу се издићи/заклонити објекти из различитих група или " +"слојева." + +#: ../../po/../src/selection-chemistry.cpp:673 +msgid "Select object(s) to raise to top." +msgstr "Изаберите објекте за издизање на врх." + +#: ../../po/../src/selection-chemistry.cpp:709 +msgid "Select object(s) to lower." +msgstr "Изаберите објекте за заклањање." + +#: ../../po/../src/selection-chemistry.cpp:765 +msgid "Select object(s) to lower to bottom." +msgstr "Изаберите објекте за заклањање на дно." + +#: ../../po/../src/selection-chemistry.cpp:806 +msgid "Nothing to undo." +msgstr "Нема опозива акције." + +#: ../../po/../src/selection-chemistry.cpp:813 +msgid "Nothing to redo." +msgstr "Нема понављања акције." + +#: ../../po/../src/selection-chemistry.cpp:969 +msgid "Nothing was copied." +msgstr "Ништа није умножено." + +#: ../../po/../src/selection-chemistry.cpp:1051 +msgid "Current layer is hidden. Unhide it to be able to paste to it." +msgstr "" +"Тренутни слој је скривен. Прикажите га да би могли да прилепите на " +"њега." + +#: ../../po/../src/selection-chemistry.cpp:1055 +msgid "Current layer is locked. Unlock it to be able to paste to it." +msgstr "" +"Тренутни слој је закључан. Откључајте га да би могли да прилепите на " +"њега." + +#: ../../po/../src/selection-chemistry.cpp:1068 +#: ../../po/../src/selection-chemistry.cpp:1103 +msgid "Nothing on the clipboard." +msgstr "Нема ничега у клипборду." + +#: ../../po/../src/selection-chemistry.cpp:1109 +msgid "Select object(s) to paste style to." +msgstr "Изаберите објекте на које ће се пренети стил." + +#: ../../po/../src/selection-chemistry.cpp:1128 +msgid "Select object(s) to move to the layer above." +msgstr "Изаберите објекат за премештање на горњи слој." + +#: ../../po/../src/selection-chemistry.cpp:1146 +msgid "No more layers above." +msgstr "Нема слојева изнад тренутног." + +#: ../../po/../src/selection-chemistry.cpp:1160 +msgid "Select object(s) to move to the layer below." +msgstr "Изаберите објекат за премештање на доњи слој." + +#: ../../po/../src/selection-chemistry.cpp:1178 +msgid "No more layers below." +msgstr "Нема слојева испод тренутног." + +#: ../../po/../src/selection-chemistry.cpp:1811 +msgid "Select a clone to unlink." +msgstr "Изаберите клон за одвезивање." + +#: ../../po/../src/selection-chemistry.cpp:1842 +msgid "No clones to unlink in the selection." +msgstr "Нема клона за одвезивање међу изабраним клоновима." + +#: ../../po/../src/selection-chemistry.cpp:1859 +msgid "" +"Select a clone to go to its original. Select a linked offset " +"to go to its source. Select a text on path to go to the path. Select " +"a flowed text to go to its frame." +msgstr "" +"Изаберите клон за прелазак на оригинал. Изаберите повезани " +"померај за прелазак на извор. Изаберите текст на криви за " +"прелазак на криву. Изаберите плутајући текст за прелазак на његов " +"оквир." + +#: ../../po/../src/selection-chemistry.cpp:1882 +msgid "" +"Cannot find the object to select (orphaned clone, offset, textpath, " +"flowed text?)" +msgstr "" +"Не могу да пронађем објекат за избор (клон сироче, померај, путања " +"текста, плутајући текст?)" + +#: ../../po/../src/selection-chemistry.cpp:1888 +msgid "" +"The object you're trying to select is not visible (it is in <" +"defs>)" +msgstr "" +"Оригинал овог клона није видљиви објекат (налази се у <defs> " +"атрибуту)" + +#: ../../po/../src/selection-chemistry.cpp:1915 +msgid "Select object(s) to convert to pattern." +msgstr "Одаберите објекте који ће бити спојени у мустру." + +#: ../../po/../src/selection-chemistry.cpp:2006 +msgid "Select an object with pattern fill to extract objects from." +msgstr "" +"Изаберите објекат попуњен мустром за издвајање објеката из мустре." + +#: ../../po/../src/selection-chemistry.cpp:2059 +msgid "No pattern fills in the selection." +msgstr "У избору нема попуне мустром." + +#: ../../po/../src/selection-chemistry.cpp:2079 +msgid "Select object(s) to make a bitmap copy." +msgstr "Изаберите објекте за издизање на врх." + +#: ../../po/../src/selection-describer.cpp:37 +msgid "Click selection to toggle scale/rotation handles" +msgstr "Кликните на изабрани објекат за промену режима скалирање/ротација" + +#. no items +#: ../../po/../src/selection-describer.cpp:39 +msgid "" +"No objects selected. Click, Shift+click, or drag around objects to select." +msgstr "" +"Нема изабраних објеката. Клик, Shift+клик или превлачење око објекта за " +"избор." + +#: ../../po/../src/selection-describer.cpp:51 +#, c-format +msgid " in layer %s" +msgstr " у слоју %s" + +#: ../../po/../src/selection-describer.cpp:54 +#, c-format +msgid " in layer %s" +msgstr " у слоју %s" + +#: ../../po/../src/selection-describer.cpp:66 +msgid "Use Shift+D to look up original" +msgstr "Употрбите Shift+Д за проналажење оригинала" + +#: ../../po/../src/selection-describer.cpp:70 +msgid "Use Shift+D to look up path" +msgstr "Употрбите Shift+Д за проналажење криве" + +#: ../../po/../src/selection-describer.cpp:74 +msgid "Use Shift+D to look up frame" +msgstr "Употрбите Shift+Д за проналажење оквира" + +#: ../../po/../src/selection-describer.cpp:84 +#, c-format +msgid "%i object selected" +msgid_plural "%i objects selected" +msgstr[0] "%i објекат изабран" +msgstr[1] "%i објеката изабрано" + +#: ../../po/../src/selection-describer.cpp:90 +#, c-format +msgid "%s%s. %s." +msgstr "%s%s. %s." + +#: ../../po/../src/selection-describer.cpp:94 +#, c-format +msgid "%s in %i layer. %s." +msgid_plural "%s in %i layers. %s." +msgstr[0] "%s у %i слоју. %s." +msgstr[1] "%s у %i слојева. %s." + +#: ../../po/../src/seltrans.cpp:498 +msgid "" +"Center of rotation and skewing: drag to reposition; scaling with " +"Shift also uses this center" +msgstr "" +"Центар ротације и укошавања: повуците за премештање; промена величине " +"са " + +#: ../../po/../src/seltrans.cpp:514 +msgid "" +"Squeeze or stretch selection; with Ctrl to scale uniformly; " +"with Shift to scale around rotation center" +msgstr "" +"Стискање и развлачење избора; са Ctrl за пропорционално; са " +"Shift за промену око центра ротације" + +#: ../../po/../src/seltrans.cpp:515 +msgid "" +"Scale selection; with Ctrl to scale uniformly; with Shift to scale around rotation center" +msgstr "" +"Промена величине избора; са Ctrl за пропорционално; са " +"Shift за промену око центра ротације" + +#: ../../po/../src/seltrans.cpp:519 +msgid "" +"Skew selection; with Ctrl to snap angle; with Shift to " +"skew around the opposite side" +msgstr "" +"Искошавање избора; са Ctrl за пријањање угла; са Shift " +"за ротирање око супротне стране" + +#: ../../po/../src/seltrans.cpp:520 +msgid "" +"Rotate selection; with Ctrl to snap angle; with Shift " +"to rotate around the opposite corner" +msgstr "" +"Ротација избора; са Ctrl за фиксни угао; са Shift за " +"ротирање око супротног ћошка" + +#: ../../po/../src/seltrans.cpp:829 ../../po/../src/seltrans.cpp:909 +#, c-format +msgid "Scale: %0.2f%% x %0.2f%%; with Ctrl to lock ratio" +msgstr "Скалирање: %0.2f%% x %0.2f%%; са Ctrl за пропорционално" + +#. TRANSLATORS: don't modify the first ";" (it will NOT be displayed as ";" - only the second one will be) +#: ../../po/../src/seltrans.cpp:984 +#, c-format +msgid "Skew: %0.2f°; with Ctrl to snap angle" +msgstr "Искошавање: %0.2f°; са Ctrl за пријањање угла" + +#. TRANSLATORS: don't modify the first ";" (it will NOT be displayed as ";" - only the second one will be) +#: ../../po/../src/seltrans.cpp:1035 +#, c-format +msgid "Rotate: %0.2f°; with Ctrl to snap angle" +msgstr "Ротација: %0.2f°; са Ctrl за пријањање угла" + +#: ../../po/../src/seltrans.cpp:1090 +#, c-format +msgid "Move center to %s, %s" +msgstr "Центар премештен на %s, %s" + +#: ../../po/../src/slideshow.cpp:90 +msgid "Inkscape slideshow" +msgstr "Слајд шоу презентација" + +#: ../../po/../src/sp-anchor.cpp:181 +#, c-format +msgid "Link to %s" +msgstr "Веза на %s" + +#: ../../po/../src/sp-anchor.cpp:185 +msgid "Link without URI" +msgstr "Веза без УРИ адресе" + +#: ../../po/../src/sp-ellipse.cpp:438 ../../po/../src/sp-ellipse.cpp:870 +msgid "Ellipse" +msgstr "Елипса" + +#: ../../po/../src/sp-ellipse.cpp:583 +msgid "Circle" +msgstr "Кружница" + +#: ../../po/../src/sp-ellipse.cpp:865 +msgid "Segment" +msgstr "Сегмент" + +#: ../../po/../src/sp-ellipse.cpp:867 +msgid "Arc" +msgstr "Угао" + +#. TRANSLATORS: "Flow region" is an area where text is allowed to flow +#: ../../po/../src/sp-flowregion.cpp:276 +msgid "Flow region" +msgstr "Слободна површина" + +#. TRANSLATORS: A region "cut out of" a flow region; text is not allowed to flow inside the +#. * flow excluded region. flowRegionExclude in SVG 1.2: see +#. * http://www.w3.org/TR/2004/WD-SVG12-20041027/flow.html#flowRegion-elem and +#. * http://www.w3.org/TR/2004/WD-SVG12-20041027/flow.html#flowRegionExclude-elem. +#: ../../po/../src/sp-flowregion.cpp:493 +msgid "Flow excluded region" +msgstr "" + +#: ../../po/../src/sp-flowtext.cpp:355 +#, c-format +msgid "Flowed text (%d characters)" +msgstr "Плутајући текст (%d знакова)" + +#: ../../po/../src/sp-flowtext.cpp:357 +#, c-format +msgid "Linked flowed text (%d characters)" +msgstr "Повезани плутајући текст (%d знакова)" + +#: ../../po/../src/sp-guide.cpp:290 +msgid "vertical guideline" +msgstr "усправна вођица" + +#: ../../po/../src/sp-guide.cpp:292 +msgid "horizontal guideline" +msgstr "водоравна вођица" + +#: ../../po/../src/sp-image.cpp:835 +msgid "embedded" +msgstr "уграђен" + +#: ../../po/../src/sp-image.cpp:839 +msgid "(null_pointer)" +msgstr "(null_pointer)" + +#: ../../po/../src/sp-image.cpp:843 +#, c-format +msgid "Image with bad reference: %s" +msgstr "Слика са лошом референцом: %s" + +#: ../../po/../src/sp-image.cpp:844 +#, c-format +msgid "Image %d × %d: %s" +msgstr "Слика %d × %d: %s" + +# bug: plural-forms +#: ../../po/../src/sp-item-group.cpp:390 +#, c-format +msgid "Group of %d object" +msgid_plural "Group of %d objects" +msgstr[0] "Група од %d објекта" +msgstr[1] "Група од %d објеката" + +#: ../../po/../src/sp-item.cpp:720 +msgid "Object" +msgstr "Објекат" + +#: ../../po/../src/sp-line.cpp:202 +msgid "Line" +msgstr "Линија" + +#. TRANSLATORS COMMENT: %s is either "outset" or "inset" depending on sign +#: ../../po/../src/sp-offset.cpp:433 +#, c-format +msgid "Linked offset, %s by %f pt" +msgstr "Повезани померај, %s за %f тачака" + +#: ../../po/../src/sp-offset.cpp:434 ../../po/../src/sp-offset.cpp:438 +msgid "outset" +msgstr "проширено" + +#: ../../po/../src/sp-offset.cpp:434 ../../po/../src/sp-offset.cpp:438 +msgid "inset" +msgstr "сузжено" + +#. TRANSLATORS COMMENT: %s is either "outset" or "inset" depending on sign +#: ../../po/../src/sp-offset.cpp:437 +#, c-format +msgid "Dynamic offset, %s by %f pt" +msgstr "Динамичка удаљеност, %s за %f тачака" + +#: ../../po/../src/sp-path.cpp:127 +#, c-format +msgid "Path (%i node)" +msgid_plural "Path (%i nodes)" +msgstr[0] "Путања (%i чвор)" +msgstr[1] "Путања (%i чворова)" + +#: ../../po/../src/sp-polygon.cpp:216 +msgid "Polygon" +msgstr "полигон" + +#: ../../po/../src/sp-polyline.cpp:179 +msgid "Polyline" +msgstr "Вишеструка линија" + +#: ../../po/../src/sp-rect.cpp:250 +msgid "Rectangle" +msgstr "Правоугаоник" + +#. TRANSLATORS: since turn count isn't an integer, please adjust the +#. string as needed to deal with an localized plural forms. +#: ../../po/../src/sp-spiral.cpp:305 +#, c-format +msgid "Spiral with %3f turns" +msgstr "Спирала са %3f завоја" + +#: ../../po/../src/sp-star.cpp:288 +#, c-format +msgid "Star with %d vertex" +msgid_plural "Star with %d vertices" +msgstr[0] "Звезда са %d краком" +msgstr[1] "Звезда са %d кракова" + +#: ../../po/../src/sp-star.cpp:292 +#, c-format +msgid "Polygon with %d vertex" +msgid_plural "Polygon with %d vertices" +msgstr[0] "Полигон са %d страном" +msgstr[1] "Полигон са %d страна" + +#. TRANSLATORS: For description of font with no name. +#: ../../po/../src/sp-text.cpp:420 +msgid "<no name found>" +msgstr "<назив није пронађен>" + +#: ../../po/../src/sp-text.cpp:426 +#, c-format +msgid "Text on path (%s, %s)" +msgstr "Крива са текстом (%s, %s)" + +#: ../../po/../src/sp-text.cpp:427 +#, c-format +msgid "Text (%s, %s)" +msgstr "Текст (%s, %s)" + +#. TRANSLATORS: Used for statusbar description for long chains: +#. * "Clone of: Clone of: ... in Layer 1". +#: ../../po/../src/sp-use.cpp:317 +msgid "..." +msgstr "..." + +#: ../../po/../src/sp-use.cpp:325 +#, c-format +msgid "Clone of: %s" +msgstr "Клон за: %s" + +#: ../../po/../src/sp-use.cpp:329 +msgid "Orphaned clone" +msgstr "Клон сироче" + +#: ../../po/../src/spiral-context.cpp:355 +msgid "Ctrl: snap angle" +msgstr "Ctrl: пријањање угла" + +#: ../../po/../src/spiral-context.cpp:357 +msgid "Alt: lock spiral radius" +msgstr "Alt: закључава пречник спирале" + +#: ../../po/../src/spiral-context.cpp:469 +#, c-format +msgid "" +"Spiral: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" +"Спирала: пречник %s, угао %5g°; са Ctrl за пријањање угла" + +#: ../../po/../src/splivarot.cpp:106 +msgid "Select at least 2 paths to perform a boolean operation." +msgstr "Изаберите најмање две криве за примењивање Булове операције." + +#: ../../po/../src/splivarot.cpp:112 +msgid "" +"Select exactly 2 paths to perform difference, XOR, division, or path " +"cut." +msgstr "" +"Изаберите тачно две криве за примењивање операције различитости, XOR, " +"поделе или исецања криве." + +#: ../../po/../src/splivarot.cpp:129 ../../po/../src/splivarot.cpp:144 +msgid "" +"Unable to determine the z-order of the objects selected for " +"difference, XOR, division, or path cut." +msgstr "" +"Не могу да распознам поредак слоја објеката изабраних за различитост, " +"XOR, поделу или исецање криве." + +#: ../../po/../src/splivarot.cpp:174 +msgid "" +"One of the objects is not a path, cannot perform boolean operation." +msgstr "" +"Један од објеката није крива, није могуће применити Булову операцију." + +#. TRANSLATORS: "to outline" means "to convert stroke to path" +#: ../../po/../src/splivarot.cpp:554 +msgid "Select path(s) to outline." +msgstr "Изаберите објекте за претварање у криве." + +#. TRANSLATORS: "to outline" means "to convert stroke to path" +#: ../../po/../src/splivarot.cpp:748 +msgid "No stroked paths to outline in the selection." +msgstr "У избору нема исцртаних потеза за претварање у криве." + +#: ../../po/../src/splivarot.cpp:832 +msgid "Selected object is not a path, cannot inset/outset." +msgstr "Изабрани објекат није крива, не може да се скупља или шири." + +#: ../../po/../src/splivarot.cpp:1040 +msgid "Select path(s) to inset/outset." +msgstr "Изаберите неку криву за скупљање или ширење." + +#: ../../po/../src/splivarot.cpp:1257 +msgid "No paths to inset/outset in the selection." +msgstr "У избору нема крива за скупљање или ширење." + +#: ../../po/../src/splivarot.cpp:1390 +msgid "Select path(s) to simplify." +msgstr "Изаберите криве за поједностављивање." + +#: ../../po/../src/splivarot.cpp:1417 +msgid "No paths to simplify in the selection." +msgstr "У избору нема крива за поједностављивање." + +#: ../../po/../src/star-context.cpp:362 +msgid "Ctrl: snap angle; keep rays radial" +msgstr "Ctrl: пријања на угао; задржи радијалне краке" + +#: ../../po/../src/star-context.cpp:470 +#, c-format +msgid "" +"Polygon: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" +"Полигон: полупречник %s, угао %5g°; Ctrl пријања на угао" + +#: ../../po/../src/star-context.cpp:471 +#, c-format +msgid "Star: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" +"Звезда: полупречник %s, угао %5g°; Ctrl пријања на угао" + +#: ../../po/../src/text-chemistry.cpp:90 +msgid "Select a text and a path to put text on path." +msgstr "Изаберите текст и криву за постављање текста на криву." + +#: ../../po/../src/text-chemistry.cpp:95 +msgid "" +"This text object is already put to a path. Remove it from the path " +"first. Use Shift+D to look up its path." +msgstr "" +"Овај текст објекат је већ постављен на криву. Прво га уклоните са " +"криве. Користите Shift+Д за наглашавање припадајуће криве." + +#. rect is the only SPShape which is not yet, and thus SVG forbids us from putting text on it +#: ../../po/../src/text-chemistry.cpp:101 +msgid "" +"You cannot put text on a rectangle in this version. Convert rectangle to " +"path first." +msgstr "" +"У овој верзији не можете да поставите текст на правоугаоник. Прво претворите " +"правоугаоник у криву." + +#: ../../po/../src/text-chemistry.cpp:159 +msgid "Select a text on path to remove it from path." +msgstr "Изаберите текст на облику за склањање са криве." + +#: ../../po/../src/text-chemistry.cpp:181 +msgid "No texts-on-paths in the selection." +msgstr "Нема текста на облику у избору." + +#: ../../po/../src/text-chemistry.cpp:209 +#: ../../po/../src/text-chemistry.cpp:229 +msgid "Select text(s) to remove kerns from." +msgstr "Изаберите текст за који ће бити уклоњено уклапање слова." + +#: ../../po/../src/text-chemistry.cpp:250 +msgid "" +"Select a text and one or more paths or shapes to flow text " +"into frame." +msgstr "" +"Изаберите текст и једну или више криву или облик за постављање " +"текста у оквир." + +#: ../../po/../src/text-chemistry.cpp:322 +msgid "Select a flowed text to unflow it." +msgstr "Изаберите плутајући текст за ослобађање из објекта." + +#: ../../po/../src/text-context.cpp:463 +msgid "Click to edit the text, drag to select part of the text." +msgstr "" +"Клик за уређивање текста, превлачење за избор дела текста." + +#: ../../po/../src/text-context.cpp:465 +msgid "" +"Click to edit the flowed text, drag to select part of the text." +msgstr "" +"Клик за уређивање плутајућег текста, превлачење за избор дела " +"текста." + +#: ../../po/../src/text-context.cpp:540 +msgid "Non-printable character" +msgstr "Знакови који се не штампају" + +#: ../../po/../src/text-context.cpp:589 +#, c-format +msgid "Unicode: %s: %s" +msgstr "Уникод: %s: %s" + +#: ../../po/../src/text-context.cpp:591 ../../po/../src/text-context.cpp:855 +msgid "Unicode: " +msgstr "Уникод: " + +#: ../../po/../src/text-context.cpp:615 +msgid "Current layer is hidden. Unhide it to be able to add text." +msgstr "" +"Активни слој је скривен. Укините сакривање да би могли да додате " +"текст." + +#: ../../po/../src/text-context.cpp:619 +msgid "Current layer is locked. Unlock it to be able to add text." +msgstr "" +"Активни слој је закључан. Откључајте га да би могли да додате текст." + +#: ../../po/../src/text-context.cpp:673 +#, c-format +msgid "Flowed text frame: %s × %s" +msgstr "Оквир плутајућег текста: %s × %s" + +#: ../../po/../src/text-context.cpp:708 ../../po/../src/text-context.cpp:1464 +msgid "Type text; Enter to start new line." +msgstr "Унесите текст; Ентер за почетак нове линије." + +#: ../../po/../src/text-context.cpp:719 +msgid "Flowed text is created." +msgstr "Плутајући текст је направљен." + +#: ../../po/../src/text-context.cpp:722 +msgid "" +"The frame is too small for the current font size. Flowed text not " +"created." +msgstr "" +"Оквир је премали за тернутну величину фонта. Плутајући текст није " +"направљен." + +#: ../../po/../src/text-context.cpp:841 +msgid "No-break space" +msgstr "Непрекидајући размак" + +#: ../../po/../src/text-context.cpp:1462 +msgid "Type flowed text; Enter to start new paragraph." +msgstr "Унесите плитајући текст; Ентер за почетак новог пасуса." + +#: ../../po/../src/text-context.cpp:1472 ../../po/../src/tools-switch.cpp:189 +msgid "" +"Click to select or create text, drag to create flowed text; " +"then type." +msgstr "" +"Клик за избор или прављење текста, превлачење за прављење " +"плутајућег текста; потом куцајте текст." + +#: ../../po/../src/tools-switch.cpp:141 +msgid "" +"To edit a path, click, Shift+click, or drag around " +"nodes to select them, then drag nodes and handles. Click on an " +"object to select." +msgstr "" +"За уређивање криве клик, Shift+клик или повлачење преко " +"чворова за избор, затим повлачење чворова и ручки. Клик на " +"објекат за избор." + +#: ../../po/../src/tools-switch.cpp:147 +msgid "" +"Drag to create a rectangle. Drag controls to round corners and " +"resize. Click to select." +msgstr "" +"Цртање правоугаоника повлачењем. Повлачење квачица за заобљене " +"углове и промену величине. Клик за избор." + +#: ../../po/../src/tools-switch.cpp:153 +msgid "" +"Drag to create an ellipse. Drag controls to make an arc or " +"segment. Click to select." +msgstr "" +"Цртање елипсе повлачењем. Повлачење квачица за лук или " +"сегмент. Клик за избор." + +#: ../../po/../src/tools-switch.cpp:159 +msgid "" +"Drag to create a star. Drag controls to edit the star shape. " +"Click to select." +msgstr "" +"Цртање звезде повлачењем. Уређивање повлачењем квачица. " +"Клик за избор." + +#: ../../po/../src/tools-switch.cpp:165 +msgid "" +"Drag to create a spiral. Drag controls to edit the spiral " +"shape. Click to select." +msgstr "" +"Цртање спирале повлачењем. Уређивање спирале повлачењем квачица. Клик за избор." + +#: ../../po/../src/tools-switch.cpp:171 +msgid "" +"Drag to create a freehand line. Start drawing with Shift to " +"append to selected path." +msgstr "" +"Цртање криве линије повлачењем. Започните цртање са Shiftа за " +"додавање на изабрану криву." + +#: ../../po/../src/tools-switch.cpp:177 +#, fuzzy +msgid "" +"Click or click and drag to start a path; with Shift to " +"append to selected path." +msgstr "" +"Клик за прављење чвора, клик и повлачење за прављење глатког " +"чвора. Започните са Shift за додавање на изабрану криву." + +#: ../../po/../src/tools-switch.cpp:183 +msgid "" +"Drag to paint a calligraphic stroke. Left/right arrow " +"keys adjust width, up/down adjust angle." +msgstr "" +"Цртање калиграфске линије повлачењем. Стрелица лево/десно подешава ширину, горе/доле подешава угао." + +#: ../../po/../src/tools-switch.cpp:195 +msgid "" +"Drag or double click to create a gradient on selected objects, " +"drag handles to adjust gradients." +msgstr "" +"Прављење или двоклик за прављење прелива за изабрани објекат, " +"повлачење ручки за уређивање прелива." + +#: ../../po/../src/tools-switch.cpp:201 +msgid "" +"Click or drag around an area to zoom in, Shift+click to " +"zoom out." +msgstr "" +"Клик или превлачење преко површине за увећање, Shift+клик за умањење." + +#: ../../po/../src/tools-switch.cpp:213 +msgid "Click and drag between shapes to create a connector." +msgstr "" + +#: ../../po/../src/trace/potrace/inkscape-potrace.cpp:553 +#: ../../po/../src/trace/potrace/inkscape-potrace.cpp:654 +#, c-format +msgid "Trace: %d. %ld nodes" +msgstr "Векторизација: %d. %ld чворова" + +#: ../../po/../src/trace/trace.cpp:53 ../../po/../src/trace/trace.cpp:62 +#: ../../po/../src/trace/trace.cpp:70 +msgid "Select an image to trace" +msgstr "Изаберите слику за векторизацију" + +#: ../../po/../src/trace/trace.cpp:133 +msgid "Trace: No active document" +msgstr "Векторизација: Нема активног документа" + +#: ../../po/../src/trace/trace.cpp:154 +msgid "Trace: Image has no bitmap data" +msgstr "Векторизација: Слика нема битмапираних података" + +#: ../../po/../src/trace/trace.cpp:267 +#, c-format +msgid "Trace: Done. %ld nodes created" +msgstr "Векторизација: Готово. %ld чворова направљено" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:59 ../../po/../src/verbs.cpp:2212 +msgid "About Inkscape" +msgstr "О програму" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:66 +msgid "_Splash" +msgstr "" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:68 +msgid "_Authors" +msgstr "" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:69 +#, fuzzy +msgid "_Translators" +msgstr "Трансформација" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:70 +#, fuzzy +msgid "_License" +msgstr "Лиценца" + +#. TRANSLATORS: This is the filename of the `About Inkscape' picture in +#. the `screens' directory. Thus the translation of "about.svg" should be +#. the filename of its translated version, e.g. about.zh.svg for Chinese. +#. +#. N.B. about.svg changes once per release. (We should probably rename +#. the original to about-0.40.svg etc. as soon as we have a translation. +#. If we do so, then add an item to release-checklist saying that the +#. string here should be changed.) +#. FIXME? INKSCAPE_SCREENSDIR and "about.svg" are in UTF-8, not the +#. native filename encoding... and the filename passed to sp_document_new +#. should be in UTF-*8.. +#: ../../po/../src/ui/dialog/aboutbox.cpp:114 +msgid "about.svg" +msgstr "about.svg" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:464 +msgid "Minimum horizontal gap (in px units) between bounding boxes" +msgstr "" + +#. TRANSLATORS: Horizontal gap +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:466 +#: ../../po/../src/widgets/toolbox.cpp:1556 +msgid "H:" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:474 +msgid "Minimum vertical gap (in px units) between bounding boxes" +msgstr "" + +#. TRANSLATORS: Vertical gap +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:476 +msgid "V:" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:734 +msgid "Align" +msgstr "Поравнавање" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:735 +msgid "Distribute" +msgstr "Распоређивање" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:736 +msgid "Remove overlaps" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:737 +msgid "Nodes" +msgstr "Чворови" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:742 +msgid "Relative to: " +msgstr "Релативно на: " + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:747 +msgid "Align right sides of objects to left side of anchor" +msgstr "Поравнава десну страну избора уз леву страну основног објекта" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:750 +msgid "Align left sides" +msgstr "Лево поравнање" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:753 +msgid "Center on vertical axis" +msgstr "Центрирај на усправној оси" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:756 +msgid "Align right sides" +msgstr "Десно поравнање" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:759 +msgid "Align left sides of objects to right side of anchor" +msgstr "Лева страна избора уз десну страну основног објекта" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:762 +msgid "Align bottoms of objects to top of anchor" +msgstr "Дно избора уз врх основног објекта" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:765 +msgid "Align tops" +msgstr "Поравнавање врхова" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:768 +msgid "Center on horizontal axis" +msgstr "Центрирај на водоравној оси" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:771 +msgid "Align bottoms" +msgstr "Поравнање дна" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:774 +msgid "Align tops of objects to bottom of anchor" +msgstr "Врх избора уз дно основног објекта" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:779 +msgid "Align baseline anchors of texts vertically" +msgstr "Усправно поравнање основа текста" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:782 +msgid "Align baseline anchors of texts horizontally" +msgstr "Водоравно поравнање основа текста" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:787 +msgid "Make horizontal gaps between objects equal" +msgstr "Подједнаки водоравни размаци између објеката" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:791 +msgid "Distribute left sides equidistantly" +msgstr "Леве стране објеката на подједнаким растојањима" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:794 +msgid "Distribute centers equidistantly horizontally" +msgstr "Средине објеката на подједнаким водоравним растојањима" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:797 +msgid "Distribute right sides equidistantly" +msgstr "Десне стране објеката на подједнаким растојањима" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:801 +msgid "Make vertical gaps between objects equal" +msgstr "Подједнаки усправни размаци између објеката" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:805 +msgid "Distribute tops equidistantly" +msgstr "Врхови објеката на подједнаким растојањима" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:808 +msgid "Distribute centers equidistantly vertically" +msgstr "Средине објеката на подједнаким усправним растојањима" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:811 +msgid "Distribute bottoms equidistantly" +msgstr "Доње стране објеката на подједнаким растојањима" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:816 +msgid "Distribute baseline anchors of texts horizontally" +msgstr "Основе текста на подједнаким водоравним растојањима" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:819 +msgid "Distribute baseline anchors of texts vertically" +msgstr "Основе текста на подједнаким усправним растојањима" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:824 +msgid "Randomize centers in both dimensions" +msgstr "Насумично центрирање у обе димензије" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:827 +msgid "Unclump objects: try to equalize edge-to-edge distances" +msgstr "Растурање објеката: покушај изједначавања удаљености ивице од ивице" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:832 +msgid "" +"Move objects as little as possible so that their bounding boxes do not " +"overlap" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:837 +msgid "Align selected nodes horizontally" +msgstr "Поравнава изабране чворове водоравно" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:840 +msgid "Align selected nodes vertically" +msgstr "Поравнава изабране чворове усправно" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:843 +msgid "Distribute selected nodes horizontally" +msgstr "Подједнаки водоравни размаци изабраних чворова" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:846 +msgid "Distribute selected nodes vertically" +msgstr "Подједнаки усправни размаци изабраних чворова" + +#. Rest of the widgetry +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:851 +msgid "Last selected" +msgstr "Последњи" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:852 +msgid "First selected" +msgstr "Први" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:853 +msgid "Biggest item" +msgstr "Највеће" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:854 +msgid "Smallest item" +msgstr "Најмање" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:856 +#: ../../po/../src/widgets/desktop-widget.cpp:1065 +msgid "Drawing" +msgstr "Цртеж" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:91 +#, fuzzy +msgid "Metadata 1" +msgstr "Допунске информације" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:92 +#, fuzzy +msgid "Metadata 2" +msgstr "Допунске информације" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:187 +#, fuzzy +msgid "X coordinate of grid origin" +msgstr "Усправна координата избора" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:189 +#, fuzzy +msgid "Y coordinate of grid origin" +msgstr "Усправна координата избора" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:191 +#, fuzzy +msgid "Distance of vertical grid lines" +msgstr "усправна вођица" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:193 +#, fuzzy +msgid "Distance of horizontal grid lines" +msgstr "водоравна вођица" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:197 +msgid "Max. snapping distance from grid" +msgstr "" + +#: ../../po/../src/ui/dialog/export.cpp:34 +msgid "Export" +msgstr "Извези" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:36 +msgid "Fill" +msgstr "Попуна" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:37 +msgid "Stroke Paint" +msgstr "Боја линије" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:38 +msgid "Stroke Style" +msgstr "Стил линије" + +#: ../../po/../src/ui/dialog/find.cpp:34 +msgid "Find" +msgstr "Тражи" + +#: ../../po/../src/ui/dialog/memory.cpp:96 +msgid "Heap" +msgstr "Нагомилано" + +#: ../../po/../src/ui/dialog/memory.cpp:97 +msgid "In Use" +msgstr "Заузето" + +#. TRANSLATORS: "Slack" refers to memory which is in the heap but currently unused. +#. More typical usage is to call this memory "free" rather than "slack". +#: ../../po/../src/ui/dialog/memory.cpp:100 +msgid "Slack" +msgstr "Слободно" + +#: ../../po/../src/ui/dialog/memory.cpp:101 +msgid "Total" +msgstr "Укупно" + +#: ../../po/../src/ui/dialog/memory.cpp:141 +#: ../../po/../src/ui/dialog/memory.cpp:147 +#: ../../po/../src/ui/dialog/memory.cpp:154 +#: ../../po/../src/ui/dialog/memory.cpp:186 +msgid "Unknown" +msgstr "Непознато" + +#: ../../po/../src/ui/dialog/memory.cpp:167 +msgid "Combined" +msgstr "Комбиновано" + +#: ../../po/../src/ui/dialog/memory.cpp:209 +msgid "Recalculate" +msgstr "Прерачунај" + +#: ../../po/../src/ui/dialog/messages.cpp:74 +#, fuzzy +msgid "Ready." +msgstr "Црвена" + +#: ../../po/../src/ui/dialog/messages.cpp:75 +msgid "" +"Enable log display by setting dialogs.debug 'redirect' attribute to 1 in " +"preferences.xml" +msgstr "" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:184 +msgid "_Execute Python" +msgstr "_Изврши Питон" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:186 +msgid "_Execute Perl" +msgstr "_Изврши Перл" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:195 +msgid "Script" +msgstr "Скрипт" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:205 +msgid "Output" +msgstr "Излаз" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:215 +msgid "Errors" +msgstr "Грешке" + +#. Dialog organization +#: ../../po/../src/ui/dialog/session-player.cpp:73 +msgid "Session file" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:74 +#, fuzzy +msgid "Playback controls" +msgstr "Контрола алата" + +#: ../../po/../src/ui/dialog/session-player.cpp:75 +#, fuzzy +msgid "Message information" +msgstr "Поништи _трансформацију" + +#. Active session file display +#. fixme: Does this mean the active file for the session, or the file for the active session? +#. Please indicate which with a TRANSLATORS comment. +#: ../../po/../src/ui/dialog/session-player.cpp:85 +msgid "Active session file:" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:86 +msgid "Delay (milliseconds):" +msgstr "" + +#. Unload/load buttons +#: ../../po/../src/ui/dialog/session-player.cpp:94 +#, fuzzy +msgid "Close file" +msgstr "Затвори" + +#: ../../po/../src/ui/dialog/session-player.cpp:95 +msgid "Open new file" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:96 +#, fuzzy +msgid "Set delay" +msgstr "Постави као подразумевано" + +#: ../../po/../src/ui/dialog/session-player.cpp:138 +#, fuzzy +msgid "Rewind" +msgstr "Црвена" + +#: ../../po/../src/ui/dialog/session-player.cpp:139 +msgid "Go back one change" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:140 +#, fuzzy +msgid "Pause" +msgstr "У_баци" + +#: ../../po/../src/ui/dialog/session-player.cpp:141 +msgid "Go forward one change" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:142 +msgid "Play" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:177 +#: ../../po/../src/verbs.cpp:1573 +msgid "Open session file" +msgstr "" + +#. ##Set up the Potrace panel +#. #### brightness #### +#. #### Multiple scanning#### +#. ----Hbox1 +#: ../../po/../src/ui/dialog/tracedialog.cpp:345 +#: ../../po/../src/ui/dialog/tracedialog.cpp:428 +msgid "Brightness" +msgstr "Осветљеност" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:348 +msgid "Trace by a given brightness level" +msgstr "Препознавање контура за дати ниво осветљености" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:355 +msgid "Brightness cutoff for black/white" +msgstr "Занемаривање осветљености за црно/бело" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:362 +msgid "Image Brightness" +msgstr "Осветљеност слике" + +#. #### canny edge detection #### +#. TRANSLATORS: "Canny" is the name of the inventor of this edge detection method +#: ../../po/../src/ui/dialog/tracedialog.cpp:369 +msgid "Optimal Edge Detection (Canny)" +msgstr "Оптимално препознавање контура (Кени)" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:372 +msgid "Trace with edge detection by J. Canny's algorithm" +msgstr "Препознавање контура са Кенијевим алгоритмом " + +#: ../../po/../src/ui/dialog/tracedialog.cpp:388 +msgid "Brightness cutoff for adjacent pixels (determines edge thickness)" +msgstr "Занемаривање осветљености за суседне тачке (одређује ширину контуре)" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:395 +msgid "Edge Detection" +msgstr "Препознавање контура" + +#. #### quantization #### +#. TRANSLATORS: Color Quantization: the process of reducing the number of colors +#. in an image by selecting an optimized set of representative colors and then +#. re-applying this reduced set to the original image. +#: ../../po/../src/ui/dialog/tracedialog.cpp:404 +msgid "Color Quantization" +msgstr "Засићеност боја" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:407 +msgid "Trace along the boundaries of reduced colors" +msgstr "Препознавање контура по ивицама ограничених боја" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:414 +msgid "The number of reduced colors" +msgstr "Број ограничених боја" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:416 +msgid "Colors:" +msgstr "Боје:" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:421 +msgid "Quantization / Reduction" +msgstr "Засићеност / Пригушење" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:431 +msgid "Trace the given number of brightness levels" +msgstr "Препознавање задатог броја нивоа осветљености" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:438 +msgid "Scans:" +msgstr "Испивање:" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:440 +msgid "The desired number of scans" +msgstr "Жељени број испитивања" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:448 +msgid "Trace the given number of reduced colors" +msgstr "Препознавање задатог броја ограничених боја" + +#. ---Hbox3 +#: ../../po/../src/ui/dialog/tracedialog.cpp:454 +msgid "Monochrome" +msgstr "Монохроматски" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:457 +msgid "Same as Color, but convert result to grayscale" +msgstr "Исто као у боји, али се резултат претвара у сиве тонове" + +#. TRANSLATORS: "Stack" is a verb here +#: ../../po/../src/ui/dialog/tracedialog.cpp:460 +msgid "Stack" +msgstr "Гомилање" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:463 +msgid "" +"Stack scans vertically (no gaps) or tile horizontally (usually with gaps)" +msgstr "" +"Додаје испитивања усправно (без празнина) или поплочава водоравно (обично са " +"празнинама)" + +#. TRANSLATORS: "Smooth" is a verb here +#: ../../po/../src/ui/dialog/tracedialog.cpp:466 +msgid "Smooth" +msgstr "Глатко" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:469 +msgid "Apply Gaussian blur to the bitmap before tracing" +msgstr "Примењује Гаусово замагљивање на битмапу пре препознавања контура" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:473 +msgid "Multiple Scanning" +msgstr "Испитивање у више пролаза" + +#. #### Preview #### +#: ../../po/../src/ui/dialog/tracedialog.cpp:479 +#: ../../po/../src/ui/dialog/tracedialog.cpp:489 +msgid "Preview" +msgstr "Приказ" + +#. do not expand +#: ../../po/../src/ui/dialog/tracedialog.cpp:483 +msgid "Preview the result without actual tracing" +msgstr "Приказује резултат без стварног препознавања контура" + +#. #### swap black and white #### +#: ../../po/../src/ui/dialog/tracedialog.cpp:495 +msgid "Invert" +msgstr "Преокрени" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:499 +msgid "Invert black and white regions for single traces" +msgstr "Замењује црне и беле површине за сваки пролаз" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:503 +msgid "Thanks to Peter Selinger, http://potrace.sourceforge.net" +msgstr "Захваљујемо се Питеру Силингеру, http://potrace.sourceforge.net" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:506 +msgid "Credits" +msgstr "Захвале" + +#. done +#. TRANSLATORS: Potrace is an application for transforming bitmaps into +#. vector graphics (http://potrace.sourceforge.net/) +#: ../../po/../src/ui/dialog/tracedialog.cpp:514 +msgid "Potrace" +msgstr "Потрејс (Potrace)" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:527 +msgid "Abort a trace in progress" +msgstr "Заустави препознавање које је у току" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:531 +msgid "Execute the trace" +msgstr "Извршти препознавање" + +#: ../../po/../src/ui/dialog/transformation.cpp:80 +#: ../../po/../src/ui/dialog/transformation.cpp:90 +#, fuzzy +msgid "_Horizontal" +msgstr "Водоравни текст" + +#: ../../po/../src/ui/dialog/transformation.cpp:80 +msgid "Horizontal displacement (relative) or position (absolute)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:82 +#: ../../po/../src/ui/dialog/transformation.cpp:92 +#, fuzzy +msgid "_Vertical" +msgstr "Усправни текст" + +#: ../../po/../src/ui/dialog/transformation.cpp:82 +msgid "Vertical displacement (relative) or position (absolute)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:84 +#, fuzzy +msgid "_Width" +msgstr "_Ширина:" + +#: ../../po/../src/ui/dialog/transformation.cpp:84 +msgid "Horizontal size increment (absolute or percentage)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:86 +#, fuzzy +msgid "_Height" +msgstr "Висина:" + +#: ../../po/../src/ui/dialog/transformation.cpp:86 +msgid "Vertical size increment (absolute or percentage)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:88 +#, fuzzy +msgid "A_ngle" +msgstr "Угао:" + +#: ../../po/../src/ui/dialog/transformation.cpp:88 +#, fuzzy +msgid "Rotation angle (positive = counterclockwise)" +msgstr "Ротира за 90° у обрнутом смеру од смера казаљке на сату" + +#: ../../po/../src/ui/dialog/transformation.cpp:90 +msgid "" +"Horizontal skew angle (positive = counterclockwise), or absolute " +"displacement, or percentage displacement" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:92 +msgid "" +"Vertical skew angle (positive = counterclockwise), or absolute displacement, " +"or percentage displacement" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:95 +#, fuzzy +msgid "Transformation matrix element A" +msgstr "Трансформациона матрица" + +#: ../../po/../src/ui/dialog/transformation.cpp:96 +#, fuzzy +msgid "Transformation matrix element B" +msgstr "Трансформациона матрица" + +#: ../../po/../src/ui/dialog/transformation.cpp:97 +#, fuzzy +msgid "Transformation matrix element C" +msgstr "Трансформациона матрица" + +#: ../../po/../src/ui/dialog/transformation.cpp:98 +#, fuzzy +msgid "Transformation matrix element D" +msgstr "Трансформациона матрица" + +#: ../../po/../src/ui/dialog/transformation.cpp:99 +#, fuzzy +msgid "Transformation matrix element E" +msgstr "Трансформациона матрица" + +#: ../../po/../src/ui/dialog/transformation.cpp:100 +#, fuzzy +msgid "Transformation matrix element F" +msgstr "Трансформациона матрица" + +#: ../../po/../src/ui/dialog/transformation.cpp:102 +#, fuzzy +msgid "Rela_tive move" +msgstr "Релативно померање" + +#: ../../po/../src/ui/dialog/transformation.cpp:102 +msgid "" +"Add the specified relative displacement to the current position; otherwise, " +"edit the current absolute position directly" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:103 +msgid "Scale proportionally" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:103 +msgid "Preserve the width/height ratio of the scaled objects" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:104 +msgid "Apply to each _object separately" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:104 +msgid "" +"Apply the scale/rotate/skew to each selected object separately; otherwise, " +"transform the selection as a whole" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:105 +#, fuzzy +msgid "Edit c_urrent matrix" +msgstr "Издизање тренутног слоја" + +#: ../../po/../src/ui/dialog/transformation.cpp:105 +msgid "" +"Edit the current transform= matrix; otherwise, post-multiply transform= by " +"this matrix" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:115 +#, fuzzy +msgid "_Move" +msgstr "Помери" + +#: ../../po/../src/ui/dialog/transformation.cpp:118 +#, fuzzy +msgid "_Scale" +msgstr "Размера" + +#: ../../po/../src/ui/dialog/transformation.cpp:121 +#, fuzzy +msgid "_Rotate" +msgstr "Ротирај" + +#: ../../po/../src/ui/dialog/transformation.cpp:124 +#, fuzzy +msgid "Ske_w" +msgstr "Искривљавање" + +#: ../../po/../src/ui/dialog/transformation.cpp:127 +msgid "Matri_x" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:141 +msgid "Reset the values on the current tab to defaults" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:148 +#, fuzzy +msgid "Apply transformation to selection" +msgstr "Примени трансформацију на објекат" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:43 +msgid "_Use SSL" +msgstr "" + +#. Construct dialog interface +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:68 +#, fuzzy +msgid "_Server:" +msgstr "П_реусмеравање" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:69 +#, fuzzy +msgid "_Username:" +msgstr "_Преименуј" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:70 +msgid "_Password:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:71 +msgid "P_ort:" +msgstr "" + +#. Buttons +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:99 +#, fuzzy +msgid "Connect" +msgstr "Клонови" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:126 +msgid "Establishing connection to Jabber server %1 as user %2" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:131 +msgid "Failed to establish connection to Jabber server %1" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:136 +msgid "Authentication failed on Jabber server %1 as %2" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:141 +msgid "SSL initialization failed when connecting to Jabber server %1" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:147 +msgid "Connected to Jabber server %1 as %2" +msgstr "" + +#. Construct labels +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:75 +#, fuzzy +msgid "Chatroom _name:" +msgstr "Назив слоја:" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:76 +msgid "Chatroom _server:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:77 +msgid "Chatroom _password:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:78 +msgid "Chatroom _handle:" +msgstr "" + +#. Button setup and callback registration +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:97 +msgid "Connect to chatroom" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:132 +msgid "Synchronizing with chatroom %1@%2 using the handle %3" +msgstr "" + +#. Construct dialog interface +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:78 +msgid "_User's Jabber ID:" +msgstr "" + +#. Buttons +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:82 +msgid "_Invite user" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:83 +#, fuzzy +msgid "_Cancel" +msgstr "Откажи" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:94 +msgid "Buddy List" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:170 +msgid "Sending whiteboard invitation to %1" +msgstr "" + +#. FIXME: strings are replaced by placeholders, NOT to be translated until the code is enabled +#. See http://sourceforge.net/mailarchive/message.php?msg_id=11746016 for details +#. File menu +#. Edit menu +#. View menu +#. Layer menu +#. Object menu +#. Path menu +#. add(Gtk::StockItem(CLEANUP, _("PLACEHOLDER, do not translate"))); (using Gtk::Stock::CLEAR) +#. Text menu +#. About menu +#. Tools toolbox +#. Select Tool controls +#. Node Tool controls +#. Calligraphy Tool controls +#. Session playback controls +#: ../../po/../src/ui/stock-items.cpp:34 ../../po/../src/ui/stock-items.cpp:35 +#: ../../po/../src/ui/stock-items.cpp:36 ../../po/../src/ui/stock-items.cpp:37 +#: ../../po/../src/ui/stock-items.cpp:38 ../../po/../src/ui/stock-items.cpp:39 +#: ../../po/../src/ui/stock-items.cpp:40 ../../po/../src/ui/stock-items.cpp:41 +#: ../../po/../src/ui/stock-items.cpp:42 ../../po/../src/ui/stock-items.cpp:43 +#: ../../po/../src/ui/stock-items.cpp:46 ../../po/../src/ui/stock-items.cpp:47 +#: ../../po/../src/ui/stock-items.cpp:48 ../../po/../src/ui/stock-items.cpp:49 +#: ../../po/../src/ui/stock-items.cpp:50 ../../po/../src/ui/stock-items.cpp:51 +#: ../../po/../src/ui/stock-items.cpp:52 ../../po/../src/ui/stock-items.cpp:53 +#: ../../po/../src/ui/stock-items.cpp:54 ../../po/../src/ui/stock-items.cpp:55 +#: ../../po/../src/ui/stock-items.cpp:56 ../../po/../src/ui/stock-items.cpp:57 +#: ../../po/../src/ui/stock-items.cpp:58 ../../po/../src/ui/stock-items.cpp:59 +#: ../../po/../src/ui/stock-items.cpp:62 ../../po/../src/ui/stock-items.cpp:63 +#: ../../po/../src/ui/stock-items.cpp:64 ../../po/../src/ui/stock-items.cpp:65 +#: ../../po/../src/ui/stock-items.cpp:66 ../../po/../src/ui/stock-items.cpp:67 +#: ../../po/../src/ui/stock-items.cpp:68 ../../po/../src/ui/stock-items.cpp:69 +#: ../../po/../src/ui/stock-items.cpp:70 ../../po/../src/ui/stock-items.cpp:71 +#: ../../po/../src/ui/stock-items.cpp:72 ../../po/../src/ui/stock-items.cpp:73 +#: ../../po/../src/ui/stock-items.cpp:74 ../../po/../src/ui/stock-items.cpp:75 +#: ../../po/../src/ui/stock-items.cpp:76 ../../po/../src/ui/stock-items.cpp:77 +#: ../../po/../src/ui/stock-items.cpp:78 ../../po/../src/ui/stock-items.cpp:79 +#: ../../po/../src/ui/stock-items.cpp:80 ../../po/../src/ui/stock-items.cpp:81 +#: ../../po/../src/ui/stock-items.cpp:82 ../../po/../src/ui/stock-items.cpp:83 +#: ../../po/../src/ui/stock-items.cpp:84 ../../po/../src/ui/stock-items.cpp:85 +#: ../../po/../src/ui/stock-items.cpp:86 ../../po/../src/ui/stock-items.cpp:87 +#: ../../po/../src/ui/stock-items.cpp:88 ../../po/../src/ui/stock-items.cpp:89 +#: ../../po/../src/ui/stock-items.cpp:92 ../../po/../src/ui/stock-items.cpp:93 +#: ../../po/../src/ui/stock-items.cpp:94 ../../po/../src/ui/stock-items.cpp:95 +#: ../../po/../src/ui/stock-items.cpp:96 ../../po/../src/ui/stock-items.cpp:97 +#: ../../po/../src/ui/stock-items.cpp:98 ../../po/../src/ui/stock-items.cpp:99 +#: ../../po/../src/ui/stock-items.cpp:100 +#: ../../po/../src/ui/stock-items.cpp:101 +#: ../../po/../src/ui/stock-items.cpp:102 +#: ../../po/../src/ui/stock-items.cpp:103 +#: ../../po/../src/ui/stock-items.cpp:104 +#: ../../po/../src/ui/stock-items.cpp:105 +#: ../../po/../src/ui/stock-items.cpp:108 +#: ../../po/../src/ui/stock-items.cpp:109 +#: ../../po/../src/ui/stock-items.cpp:110 +#: ../../po/../src/ui/stock-items.cpp:111 +#: ../../po/../src/ui/stock-items.cpp:112 +#: ../../po/../src/ui/stock-items.cpp:113 +#: ../../po/../src/ui/stock-items.cpp:114 +#: ../../po/../src/ui/stock-items.cpp:115 +#: ../../po/../src/ui/stock-items.cpp:116 +#: ../../po/../src/ui/stock-items.cpp:117 +#: ../../po/../src/ui/stock-items.cpp:118 +#: ../../po/../src/ui/stock-items.cpp:119 +#: ../../po/../src/ui/stock-items.cpp:120 +#: ../../po/../src/ui/stock-items.cpp:121 +#: ../../po/../src/ui/stock-items.cpp:122 +#: ../../po/../src/ui/stock-items.cpp:123 +#: ../../po/../src/ui/stock-items.cpp:124 +#: ../../po/../src/ui/stock-items.cpp:125 +#: ../../po/../src/ui/stock-items.cpp:126 +#: ../../po/../src/ui/stock-items.cpp:127 +#: ../../po/../src/ui/stock-items.cpp:130 +#: ../../po/../src/ui/stock-items.cpp:131 +#: ../../po/../src/ui/stock-items.cpp:132 +#: ../../po/../src/ui/stock-items.cpp:133 +#: ../../po/../src/ui/stock-items.cpp:134 +#: ../../po/../src/ui/stock-items.cpp:135 +#: ../../po/../src/ui/stock-items.cpp:136 +#: ../../po/../src/ui/stock-items.cpp:137 +#: ../../po/../src/ui/stock-items.cpp:138 +#: ../../po/../src/ui/stock-items.cpp:139 +#: ../../po/../src/ui/stock-items.cpp:140 +#: ../../po/../src/ui/stock-items.cpp:141 +#: ../../po/../src/ui/stock-items.cpp:142 +#: ../../po/../src/ui/stock-items.cpp:143 +#: ../../po/../src/ui/stock-items.cpp:144 +#: ../../po/../src/ui/stock-items.cpp:145 +#: ../../po/../src/ui/stock-items.cpp:146 +#: ../../po/../src/ui/stock-items.cpp:150 +#: ../../po/../src/ui/stock-items.cpp:151 +#: ../../po/../src/ui/stock-items.cpp:152 +#: ../../po/../src/ui/stock-items.cpp:153 +#: ../../po/../src/ui/stock-items.cpp:156 +#: ../../po/../src/ui/stock-items.cpp:157 +#: ../../po/../src/ui/stock-items.cpp:158 +#: ../../po/../src/ui/stock-items.cpp:161 +#: ../../po/../src/ui/stock-items.cpp:162 +#: ../../po/../src/ui/stock-items.cpp:163 +#: ../../po/../src/ui/stock-items.cpp:164 +#: ../../po/../src/ui/stock-items.cpp:165 +#: ../../po/../src/ui/stock-items.cpp:166 +#: ../../po/../src/ui/stock-items.cpp:167 +#: ../../po/../src/ui/stock-items.cpp:168 +#: ../../po/../src/ui/stock-items.cpp:169 +#: ../../po/../src/ui/stock-items.cpp:170 +#: ../../po/../src/ui/stock-items.cpp:171 +#: ../../po/../src/ui/stock-items.cpp:172 +#: ../../po/../src/ui/stock-items.cpp:175 +#: ../../po/../src/ui/stock-items.cpp:176 +#: ../../po/../src/ui/stock-items.cpp:177 +#: ../../po/../src/ui/stock-items.cpp:178 +#: ../../po/../src/ui/stock-items.cpp:181 +#: ../../po/../src/ui/stock-items.cpp:182 +#: ../../po/../src/ui/stock-items.cpp:183 +#: ../../po/../src/ui/stock-items.cpp:184 +#: ../../po/../src/ui/stock-items.cpp:185 +#: ../../po/../src/ui/stock-items.cpp:186 +#: ../../po/../src/ui/stock-items.cpp:187 +#: ../../po/../src/ui/stock-items.cpp:188 +#: ../../po/../src/ui/stock-items.cpp:189 +#: ../../po/../src/ui/stock-items.cpp:190 +#: ../../po/../src/ui/stock-items.cpp:191 +#: ../../po/../src/ui/stock-items.cpp:194 +#: ../../po/../src/ui/stock-items.cpp:195 +#: ../../po/../src/ui/stock-items.cpp:198 +#: ../../po/../src/ui/stock-items.cpp:199 +#: ../../po/../src/ui/stock-items.cpp:200 +#: ../../po/../src/ui/stock-items.cpp:201 +#: ../../po/../src/ui/stock-items.cpp:202 +msgid "PLACEHOLDER, do not translate" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:88 +msgid "small" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:89 +msgid "medium" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:90 +#, fuzzy +msgid "large" +msgstr "Одредиште:" + +#: ../../po/../src/ui/widget/panel.cpp:91 +msgid "huge" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:106 +#, fuzzy +msgid "List" +msgstr "сузжено" + +#: ../../po/../src/ui/widget/selected-style.cpp:67 +msgid "F:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:68 +msgid "S:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:69 +msgid "O:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:95 +msgid "N/A" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:98 +#: ../../po/../src/ui/widget/selected-style.cpp:712 +#, fuzzy +msgid "Nothing selected" +msgstr "Прелив није изабран" + +#: ../../po/../src/ui/widget/selected-style.cpp:103 +msgid "No fill" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:103 +#, fuzzy +msgid "No stroke" +msgstr " (линија)" + +#: ../../po/../src/ui/widget/selected-style.cpp:105 +#: ../../po/../src/widgets/paint-selector.cpp:190 +msgid "Pattern" +msgstr "Мустра" + +#: ../../po/../src/ui/widget/selected-style.cpp:108 +#: ../../po/../src/widgets/paint-selector.cpp:885 +msgid "Pattern fill" +msgstr "Мустра" + +#: ../../po/../src/ui/widget/selected-style.cpp:108 +#, fuzzy +msgid "Pattern stroke" +msgstr "Размак шаблона" + +#: ../../po/../src/ui/widget/selected-style.cpp:110 +#, fuzzy +msgid "L Gradient" +msgstr "Уређивач прелива" + +#: ../../po/../src/ui/widget/selected-style.cpp:113 +#, fuzzy +msgid "Linear gradient fill" +msgstr "Линијски прелив" + +#: ../../po/../src/ui/widget/selected-style.cpp:113 +#, fuzzy +msgid "Linear gradient stroke" +msgstr "Линијски прелив" + +#: ../../po/../src/ui/widget/selected-style.cpp:115 +#, fuzzy +msgid "R Gradient" +msgstr "Уређивач прелива" + +#: ../../po/../src/ui/widget/selected-style.cpp:118 +#, fuzzy +msgid "Radial gradient fill" +msgstr "Кружни прелив" + +#: ../../po/../src/ui/widget/selected-style.cpp:118 +#, fuzzy +msgid "Radial gradient stroke" +msgstr "Кружни прелив" + +#: ../../po/../src/ui/widget/selected-style.cpp:120 +#, fuzzy +msgid "Different" +msgstr "_Разликуј" + +#: ../../po/../src/ui/widget/selected-style.cpp:123 +#, fuzzy +msgid "Different fills" +msgstr "_Разликуј" + +#: ../../po/../src/ui/widget/selected-style.cpp:123 +#, fuzzy +msgid "Different strokes" +msgstr "_Разликуј" + +#: ../../po/../src/ui/widget/selected-style.cpp:125 +#, fuzzy +msgid "Unset" +msgstr "сузжено" + +#. TRANSLATORS COMMENT: unset is a verb here +#: ../../po/../src/ui/widget/selected-style.cpp:128 +#: ../../po/../src/ui/widget/selected-style.cpp:182 +msgid "Unset fill" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:128 +#: ../../po/../src/ui/widget/selected-style.cpp:182 +#, fuzzy +msgid "Unset stroke" +msgstr " (линија)" + +#: ../../po/../src/ui/widget/selected-style.cpp:131 +#, fuzzy +msgid "Flat color fill" +msgstr "Једнобојно" + +#: ../../po/../src/ui/widget/selected-style.cpp:131 +#, fuzzy +msgid "Flat color stroke" +msgstr "Једнобојно" + +#. TRANSLATOR COMMENT: A means "Averaged" +#: ../../po/../src/ui/widget/selected-style.cpp:134 +#, fuzzy +msgid "A" +msgstr "_П" + +#: ../../po/../src/ui/widget/selected-style.cpp:137 +#, fuzzy +msgid "Fill is averaged over selected objects" +msgstr "" +"Изузимање ИЛИ изабраних објеката (непарне преклопљене површине се бришу)" + +#: ../../po/../src/ui/widget/selected-style.cpp:137 +#, fuzzy +msgid "Stroke is averaged over selected objects" +msgstr "Пресецање изабраних објеката" + +#. TRANSLATOR COMMENT: M means "Multiple" +#: ../../po/../src/ui/widget/selected-style.cpp:140 +#, fuzzy +msgid "M" +msgstr "_М" + +#: ../../po/../src/ui/widget/selected-style.cpp:143 +#, fuzzy +msgid "Multiple selected objects have the same fill" +msgstr "Поравнава изабране чворове усправно" + +#: ../../po/../src/ui/widget/selected-style.cpp:143 +#, fuzzy +msgid "Multiple selected objects have the same stroke" +msgstr "Поравнава изабране чворове усправно" + +#: ../../po/../src/ui/widget/selected-style.cpp:145 +#, fuzzy +msgid "Edit fill..." +msgstr "Уреди..." + +#: ../../po/../src/ui/widget/selected-style.cpp:145 +#, fuzzy +msgid "Edit stroke..." +msgstr "Уреди..." + +#: ../../po/../src/ui/widget/selected-style.cpp:149 +#, fuzzy +msgid "Last set color" +msgstr "Једнобојно" + +#: ../../po/../src/ui/widget/selected-style.cpp:153 +#, fuzzy +msgid "Last selected color" +msgstr "Последњи" + +#: ../../po/../src/ui/widget/selected-style.cpp:157 +msgid "White" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:161 +#: ../../po/../src/widgets/sp-color-scales.cpp:461 +#: ../../po/../src/widgets/sp-color-scales.cpp:462 +msgid "Black" +msgstr "Црна" + +#: ../../po/../src/ui/widget/selected-style.cpp:165 +#, fuzzy +msgid "Copy color" +msgstr "Станица боје" + +#: ../../po/../src/ui/widget/selected-style.cpp:169 +#, fuzzy +msgid "Paste color" +msgstr "Једнобојно" + +#: ../../po/../src/ui/widget/selected-style.cpp:173 +#, fuzzy +msgid "Swap fill and stroke" +msgstr "_Попуне и линије" + +#: ../../po/../src/ui/widget/selected-style.cpp:177 +msgid "Make fill opaque" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:177 +msgid "Make stroke opaque" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:186 +#, fuzzy +msgid "Remove fill" +msgstr " _Уклони " + +#: ../../po/../src/ui/widget/selected-style.cpp:186 +#, fuzzy +msgid "Remove stroke" +msgstr "_Уклони везу" + +#: ../../po/../src/ui/widget/selected-style.cpp:718 +#, fuzzy +msgid "Master opacity" +msgstr "Основна _провидност" + +#: ../../po/../src/ui/widget/selected-style.cpp:744 +msgid "0 (transparent)" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:768 +msgid "1.0 (opaque)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1046 +msgid "Moved to next layer." +msgstr "Премештено на следећи слој." + +#: ../../po/../src/verbs.cpp:1048 +#, fuzzy +msgid "Cannot move past last layer." +msgstr "Није могуће премештање иза последњег слоја." + +#: ../../po/../src/verbs.cpp:1057 +msgid "Moved to previous layer." +msgstr "Премештено на претходни слој." + +#: ../../po/../src/verbs.cpp:1059 +#, fuzzy +msgid "Cannot move past first layer." +msgstr "Није могуће премештање испред првог слоја." + +#: ../../po/../src/verbs.cpp:1076 ../../po/../src/verbs.cpp:1150 +msgid "No current layer." +msgstr "Нема тренутног слоја." + +#: ../../po/../src/verbs.cpp:1105 +#, c-format +msgid "Raised layer %s." +msgstr "Слој %s је издигнут." + +#: ../../po/../src/verbs.cpp:1109 +#, c-format +msgid "Lowered layer %s." +msgstr "Слој %s је спуштен." + +#: ../../po/../src/verbs.cpp:1118 +#, fuzzy +msgid "Cannot move layer any further." +msgstr "Више није могуће премештати слој." + +#. TRANSLATORS: this means "The layer has been deleted." +#: ../../po/../src/verbs.cpp:1148 +msgid "Deleted layer." +msgstr "Слој је обрисан." + +#: ../../po/../src/verbs.cpp:1544 +msgid "" +"You need to connect to a Jabber server before sharing a document with " +"another user." +msgstr "" + +#: ../../po/../src/verbs.cpp:1559 +msgid "" +"You need to connect to a Jabber server before sharing a document with a " +"chatroom." +msgstr "" + +#: ../../po/../src/verbs.cpp:1569 +msgid "XML node tracker has not been initialized; nothing to dump" +msgstr "" + +#. TRANSLATORS: If you have translated the keys.svg file to your language, then +#. translate this string as "keys.LANG.svg" (where LANG is your language code); +#. otherwise leave as "keys.svg". +#: ../../po/../src/verbs.cpp:1631 +msgid "keys.svg" +msgstr "keys.svg" + +#. TRANSLATORS: If you have translated the tutorial-basic.svg file to your language, +#. then translate this string as "tutorial-basic.LANG.svg" (where LANG is your language +#. code); otherwise leave as "tutorial-basic.svg". +#: ../../po/../src/verbs.cpp:1667 +msgid "tutorial-basic.svg" +msgstr "tutorial-basic.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1671 +msgid "tutorial-shapes.svg" +msgstr "tutorial-shapes.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1675 +msgid "tutorial-advanced.svg" +msgstr "tutorial-advanced.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1679 +msgid "tutorial-tracing.svg" +msgstr "tutorial-tracing.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1683 +msgid "tutorial-calligraphy.svg" +msgstr "tutorial-calligraphy.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1687 +msgid "tutorial-elements.svg" +msgstr "tutorial-elements.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1691 +msgid "tutorial-tips.svg" +msgstr "tutorial-tips.svg" + +#: ../../po/../src/verbs.cpp:1842 +msgid "Does nothing" +msgstr "Не чини ништа" + +#. File +#: ../../po/../src/verbs.cpp:1845 +msgid "Default" +msgstr "Подразумевано" + +#: ../../po/../src/verbs.cpp:1845 +msgid "Create new document from default template" +msgstr "Направи нови документ по подразумеваном шаблону" + +#: ../../po/../src/verbs.cpp:1847 +msgid "_Open..." +msgstr "_Отвори..." + +#: ../../po/../src/verbs.cpp:1848 +msgid "Open existing document" +msgstr "Отвори постојећи СВГ документ" + +#: ../../po/../src/verbs.cpp:1849 +msgid "Re_vert" +msgstr "_Опоравак" + +#: ../../po/../src/verbs.cpp:1850 +msgid "Revert to the last saved version of document (changes will be lost)" +msgstr "" +"Повраћај последње сачуване верзије документа (измене ће бити занемарене)" + +#: ../../po/../src/verbs.cpp:1851 +msgid "_Save" +msgstr "_Сачувај" + +#: ../../po/../src/verbs.cpp:1851 +msgid "Save document" +msgstr "Сачувај документ" + +#: ../../po/../src/verbs.cpp:1853 +msgid "Save _As..." +msgstr "Сачувај _као..." + +#: ../../po/../src/verbs.cpp:1854 +msgid "Save document under new name" +msgstr "Сачувај документ под новим именом" + +#: ../../po/../src/verbs.cpp:1855 +msgid "_Print..." +msgstr "_Штампај..." + +#: ../../po/../src/verbs.cpp:1855 +msgid "Print document" +msgstr "Штампај документ" + +#. TRANSLATORS: "Vacuum Defs" means "Clean up defs" (so as to remove unused definitions) +#: ../../po/../src/verbs.cpp:1858 +msgid "Vac_uum Defs" +msgstr "Пр_ечисти дефиниције" + +#: ../../po/../src/verbs.cpp:1858 +#, fuzzy +msgid "Remove unused predefined items from the <defs> of the document" +msgstr "Уклања неупотребљиве ставке из <defs> документа" + +#: ../../po/../src/verbs.cpp:1860 +msgid "Print _Direct" +msgstr "_Непосредна штампа" + +#: ../../po/../src/verbs.cpp:1861 +#, fuzzy +msgid "Print directly without prompting to a file or pipe" +msgstr "Штампај непосредно у датотеку или цев" + +#: ../../po/../src/verbs.cpp:1862 +msgid "Print Previe_w" +msgstr "Преглед пре_д штампу" + +#: ../../po/../src/verbs.cpp:1863 +msgid "Preview document printout" +msgstr "Преглед излаза документа за штампање" + +#: ../../po/../src/verbs.cpp:1864 +msgid "_Import..." +msgstr "_Увези..." + +#: ../../po/../src/verbs.cpp:1865 +msgid "Import bitmap or SVG image into document" +msgstr "Увези битмапу или СВГ слику у документ" + +#: ../../po/../src/verbs.cpp:1866 +msgid "_Export Bitmap..." +msgstr "_Извези битмапу..." + +#: ../../po/../src/verbs.cpp:1867 +#, fuzzy +msgid "Export document or selection as a bitmap image" +msgstr "Извези документ или избор као PNG слику" + +#: ../../po/../src/verbs.cpp:1868 +msgid "N_ext Window" +msgstr "Сл_едећи прозор" + +#: ../../po/../src/verbs.cpp:1869 +msgid "Switch to the next document window" +msgstr "Прелазак на следећи прозор документа" + +#: ../../po/../src/verbs.cpp:1870 +msgid "P_revious Window" +msgstr "П_ретходни прозор" + +#: ../../po/../src/verbs.cpp:1871 +msgid "Switch to the previous document window" +msgstr "Прелазак на претходни прозор документа" + +#: ../../po/../src/verbs.cpp:1872 +msgid "_Close" +msgstr "_Затвори" + +#: ../../po/../src/verbs.cpp:1873 +msgid "Close window" +msgstr "Затварање овог прозора" + +#: ../../po/../src/verbs.cpp:1874 +msgid "_Quit" +msgstr "_Излаз" + +#: ../../po/../src/verbs.cpp:1874 +msgid "Quit Inkscape" +msgstr "Напуштање ИнкСкејпа" + +#. Edit +#: ../../po/../src/verbs.cpp:1877 +msgid "_Undo" +msgstr "_Опозови" + +#: ../../po/../src/verbs.cpp:1877 +msgid "Undo last action" +msgstr "Поништи последњу акцију" + +#: ../../po/../src/verbs.cpp:1879 +msgid "_Redo" +msgstr "_Понови" + +#: ../../po/../src/verbs.cpp:1880 +msgid "Do again last undone action" +msgstr "Понови опозвану акцију" + +#: ../../po/../src/verbs.cpp:1881 +msgid "Cu_t" +msgstr "И_сеци" + +#: ../../po/../src/verbs.cpp:1882 +msgid "Cut selection to clipboard" +msgstr "Исеци изабране објекте и смести их у клипборд" + +#: ../../po/../src/verbs.cpp:1883 +msgid "_Copy" +msgstr "_Умножи" + +#: ../../po/../src/verbs.cpp:1884 +msgid "Copy selection to clipboard" +msgstr "Умножи изабране објекте у клипборд" + +#: ../../po/../src/verbs.cpp:1885 +msgid "_Paste" +msgstr "У_баци" + +#: ../../po/../src/verbs.cpp:1886 +#, fuzzy +msgid "Paste objects from clipboard to mouse point" +msgstr "Убаци објекте из клипборда" + +#: ../../po/../src/verbs.cpp:1887 +msgid "Paste _Style" +msgstr "Убаци _стил" + +#: ../../po/../src/verbs.cpp:1888 +msgid "Apply style of the copied object to selection" +msgstr "Примени стил умноженог објекта на избор" + +#: ../../po/../src/verbs.cpp:1889 +msgid "Paste _In Place" +msgstr "Убаци у _простор" + +#: ../../po/../src/verbs.cpp:1890 +#, fuzzy +msgid "Paste objects from clipboard to the original location" +msgstr "Убаци објекте из клипборда на оригиналну позицију" + +#: ../../po/../src/verbs.cpp:1891 +msgid "_Delete" +msgstr "_Обриши" + +#: ../../po/../src/verbs.cpp:1892 +msgid "Delete selection" +msgstr "Обриши избор" + +#: ../../po/../src/verbs.cpp:1893 +msgid "Duplic_ate" +msgstr "Уд_востручи" + +#: ../../po/../src/verbs.cpp:1894 +#, fuzzy +msgid "Duplicate selected objects" +msgstr "Удвостручи изабране објекте" + +#: ../../po/../src/verbs.cpp:1895 +msgid "Clo_ne" +msgstr "_Клонирај" + +#: ../../po/../src/verbs.cpp:1896 +msgid "Create a clone of selected object (a copy linked to the original)" +msgstr "Направи клон изабраног објекта (умножак повезан са оригиналом)" + +#: ../../po/../src/verbs.cpp:1897 +msgid "Unlin_k Clone" +msgstr "Одве_жи клон" + +#: ../../po/../src/verbs.cpp:1898 +msgid "Cut the clone's link to its original" +msgstr "Уклони везу клона са оригиналом" + +#: ../../po/../src/verbs.cpp:1899 +msgid "Select _Original" +msgstr "Изабери _оригинал" + +#: ../../po/../src/verbs.cpp:1900 +msgid "Select the object to which the clone is linked" +msgstr "Изабери објекат са којим је клон повезан" + +#. TRANSLATORS: Convert selection to a rectangle with tiled pattern fill +#: ../../po/../src/verbs.cpp:1902 +#, fuzzy +msgid "O_bjects to Pattern" +msgstr "Из_бор у мустру" + +#: ../../po/../src/verbs.cpp:1903 +msgid "Convert selection to a rectangle with tiled pattern fill" +msgstr "Претварање избора у правоугаоник са попуном од поплочане мустре" + +#. TRANSLATORS: Extract objects from a tiled pattern fill +#: ../../po/../src/verbs.cpp:1905 +#, fuzzy +msgid "Pattern to Ob_jects" +msgstr "Мустра у об_јекте" + +#: ../../po/../src/verbs.cpp:1906 +msgid "Extract objects from a tiled pattern fill" +msgstr "Издваја објекте из попуне са поплочаном мустром" + +#: ../../po/../src/verbs.cpp:1907 +msgid "Clea_r All" +msgstr "О_чисти све" + +#: ../../po/../src/verbs.cpp:1908 +msgid "Delete all objects from document" +msgstr "Обриши све објекте из документа" + +#: ../../po/../src/verbs.cpp:1909 +msgid "Select Al_l" +msgstr "Иза_бери све" + +#: ../../po/../src/verbs.cpp:1910 +msgid "Select all objects or all nodes" +msgstr "Изабери све објекте или све чворове" + +#: ../../po/../src/verbs.cpp:1911 +msgid "Select All in All La_yers" +msgstr "Изабери све на свим с_лојевима" + +#: ../../po/../src/verbs.cpp:1912 +msgid "Select all objects in all visible and unlocked layers" +msgstr "Изабери све објекте на свим видљивим и незакључаним слојевима" + +#: ../../po/../src/verbs.cpp:1913 +msgid "In_vert Selection" +msgstr "Из_врни избор" + +#: ../../po/../src/verbs.cpp:1914 +msgid "Invert selection (unselect what is selected and select everything else)" +msgstr "" +"Извртање избора (уклања се избор онога што је изабрано и врши се избор свега " +"што није било изабрано)" + +#: ../../po/../src/verbs.cpp:1915 +msgid "Invert in All Layers" +msgstr "Изврни на свим слојевима" + +#: ../../po/../src/verbs.cpp:1916 +msgid "Invert selection in all visible and unlocked layers" +msgstr "Изврни избор у свим видљивим и откључаним слојевима" + +#: ../../po/../src/verbs.cpp:1917 +msgid "D_eselect" +msgstr "У_кини избор" + +#: ../../po/../src/verbs.cpp:1918 +msgid "Deselect any selected objects or nodes" +msgstr "Укини избор објеката или чворова" + +#. Selection +#: ../../po/../src/verbs.cpp:1921 +msgid "Raise to _Top" +msgstr "Издигни на _врх" + +#: ../../po/../src/verbs.cpp:1922 +msgid "Raise selection to top" +msgstr "Издигни изабране објекте испред осталих" + +#: ../../po/../src/verbs.cpp:1923 +msgid "Lower to _Bottom" +msgstr "Заклони на _дно" + +#: ../../po/../src/verbs.cpp:1924 +msgid "Lower selection to bottom" +msgstr "Постави изабране објекте иза осталих" + +#: ../../po/../src/verbs.cpp:1925 +msgid "_Raise" +msgstr "_Издигни" + +#: ../../po/../src/verbs.cpp:1926 +msgid "Raise selection one step" +msgstr "Издигни изабране објекте испред осталих" + +#: ../../po/../src/verbs.cpp:1927 +msgid "_Lower" +msgstr "_Спусти" + +#: ../../po/../src/verbs.cpp:1928 +msgid "Lower selection one step" +msgstr "Спусти изабране објекте за један ниво" + +#: ../../po/../src/verbs.cpp:1929 +msgid "_Group" +msgstr "_Групиши" + +#: ../../po/../src/verbs.cpp:1930 +msgid "Group selected objects" +msgstr "Групиши изабране објекте" + +#: ../../po/../src/verbs.cpp:1932 +#, fuzzy +msgid "Ungroup selected groups" +msgstr "Разгрупиши изабране објекте" + +#: ../../po/../src/verbs.cpp:1934 +msgid "_Put on Path" +msgstr "_Текст на криву" + +#: ../../po/../src/verbs.cpp:1935 +msgid "Put text on path" +msgstr "Поставља текст на криву" + +#: ../../po/../src/verbs.cpp:1936 +msgid "_Remove from Path" +msgstr "_Уклони са криве" + +#: ../../po/../src/verbs.cpp:1937 +msgid "Remove text from path" +msgstr "уклони текст са криве" + +#: ../../po/../src/verbs.cpp:1938 +msgid "Remove Manual _Kerns" +msgstr "Уклони ручне _кернинге" + +#. TRANSLATORS: "glyph": An image used in the visual representation of characters; +#. roughly speaking, how a character looks. A font is a set of glyphs. +#: ../../po/../src/verbs.cpp:1941 +msgid "Remove all manual kerns and glyph rotations from a text object" +msgstr "Уклони све ручне кернинге и ротације графема из текстуалног објекта" + +#: ../../po/../src/verbs.cpp:1943 +msgid "_Union" +msgstr "_Сједини" + +#: ../../po/../src/verbs.cpp:1944 +msgid "Union of selected objects" +msgstr "Сједини изабране објекте" + +#: ../../po/../src/verbs.cpp:1945 +msgid "_Intersection" +msgstr "_Пресеци" + +#: ../../po/../src/verbs.cpp:1946 +msgid "Intersection of selected objects" +msgstr "Пресецање изабраних објеката" + +#: ../../po/../src/verbs.cpp:1947 +msgid "_Difference" +msgstr "_Разликуј" + +#: ../../po/../src/verbs.cpp:1948 +msgid "Difference of selected objects (bottom minus top)" +msgstr "Разлика изабраних објеката (доњи минус горњи)" + +#: ../../po/../src/verbs.cpp:1949 +msgid "E_xclusion" +msgstr "И_зузми" + +#: ../../po/../src/verbs.cpp:1950 +msgid "Exclusive OR of selected objects" +msgstr "" +"Изузимање ИЛИ изабраних објеката (непарне преклопљене површине се бришу)" + +#: ../../po/../src/verbs.cpp:1951 +msgid "Di_vision" +msgstr "П_одели" + +#: ../../po/../src/verbs.cpp:1952 +msgid "Cut the bottom object into pieces" +msgstr "Исеци доњи објекат у преклопљене делове са горњим" + +#. TRANSLATORS: "to cut a path" is not the same as "to break a path apart" - see the +#. Advanced tutorial for more info +#: ../../po/../src/verbs.cpp:1955 +msgid "Cut _Path" +msgstr "Исеци _линију" + +#: ../../po/../src/verbs.cpp:1956 +msgid "Cut the bottom object's stroke into pieces, removing fill" +msgstr "" +"Исеци линију доњег објекта у преклопљене делове са горњим, уклањање попуне" + +#. TRANSLATORS: "outset": expand a shape by offsetting the object's path, +#. i.e. by displacing it perpendicular to the path in each point. +#. See also the Advanced Tutorial for explanation. +#: ../../po/../src/verbs.cpp:1960 +msgid "Outs_et" +msgstr "Про_шири" + +#: ../../po/../src/verbs.cpp:1961 +#, fuzzy +msgid "Outset selected paths" +msgstr "Проширивање изабране криве повећавањем ка спољашњости" + +#: ../../po/../src/verbs.cpp:1963 +msgid "O_utset Path by 1 px" +msgstr "Пр_ошири криву за 1 px" + +#: ../../po/../src/verbs.cpp:1964 +#, fuzzy +msgid "Outset selected paths by 1 px" +msgstr "Проширивање изабране криве повећавањем ка спољашњости за 1 px" + +#: ../../po/../src/verbs.cpp:1966 +msgid "O_utset Path by 10 px" +msgstr "Пр_ошири криву за 10 px" + +#: ../../po/../src/verbs.cpp:1967 +#, fuzzy +msgid "Outset selected paths by 10 px" +msgstr "Проширивање изабране криве повећавањем ка спољашњости за 10 px" + +#. TRANSLATORS: "inset": contract a shape by offsetting the object's path, +#. i.e. by displacing it perpendicular to the path in each point. +#. See also the Advanced Tutorial for explanation. +#: ../../po/../src/verbs.cpp:1971 +msgid "I_nset" +msgstr "_Сузи" + +#: ../../po/../src/verbs.cpp:1972 +#, fuzzy +msgid "Inset selected paths" +msgstr "Сужавање изабране кривее ка унутрашњости" + +#: ../../po/../src/verbs.cpp:1974 +msgid "I_nset Path by 1 px" +msgstr "С_узи криву за 1 px" + +#: ../../po/../src/verbs.cpp:1975 +#, fuzzy +msgid "Inset selected paths by 1 px" +msgstr "Сужавање изабране криве ка унутрашњости за 1 px" + +#: ../../po/../src/verbs.cpp:1977 +msgid "I_nset Path by 10 px" +msgstr "С_узи криву за 10 px" + +#: ../../po/../src/verbs.cpp:1978 +#, fuzzy +msgid "Inset selected paths by 10 px" +msgstr "Сужавање изабране криве ка унутрашњости за 10 px" + +#: ../../po/../src/verbs.cpp:1980 +msgid "D_ynamic Offset" +msgstr "Д_инамичко померање" + +#: ../../po/../src/verbs.cpp:1980 +msgid "Create a dynamic offset object" +msgstr "Прављење објекта који се може динамички померати" + +#: ../../po/../src/verbs.cpp:1982 +msgid "_Linked Offset" +msgstr "Уређивање _клона" + +#: ../../po/../src/verbs.cpp:1983 +msgid "Create a dynamic offset object linked to the original path" +msgstr "Клонира објекат за трансформацију и повезује га са оригиналом" + +#: ../../po/../src/verbs.cpp:1985 +msgid "_Stroke to Path" +msgstr "_Потез у криву" + +#: ../../po/../src/verbs.cpp:1986 +#, fuzzy +msgid "Convert selected strokes to paths" +msgstr "Претвори изабране потезе у криве" + +#: ../../po/../src/verbs.cpp:1987 +msgid "Si_mplify" +msgstr "По_једностави" + +#: ../../po/../src/verbs.cpp:1988 +#, fuzzy +msgid "Simplify selected paths by removing extra nodes" +msgstr "Поједностави изабране криве уклањањем сувишних чворова" + +#: ../../po/../src/verbs.cpp:1989 +msgid "_Reverse" +msgstr "П_реусмеравање" + +#: ../../po/../src/verbs.cpp:1990 +#, fuzzy +msgid "Reverses the direction of selected paths; useful for flipping markers" +msgstr "Обртање смера изабране криве; корисно за обртање маркера" + +#. TRANSLATORS: "to trace" means "to convert a bitmap to vector graphics" (to vectorize) +#: ../../po/../src/verbs.cpp:1992 +msgid "_Trace Bitmap" +msgstr "_Прецртавање" + +#: ../../po/../src/verbs.cpp:1993 +msgid "Convert bitmap object to paths" +msgstr "Прецртавање битмапиране слике у векторске криве" + +#: ../../po/../src/verbs.cpp:1994 +msgid "_Make a Bitmap Copy" +msgstr "_Направи дупликат битмапе" + +#: ../../po/../src/verbs.cpp:1995 +msgid "Export selection to a bitmap and insert it into document" +msgstr "Извоз избора у битмапу и убацивање те битмапе у документ" + +#: ../../po/../src/verbs.cpp:1996 +msgid "_Combine" +msgstr "_Спој у облик" + +#: ../../po/../src/verbs.cpp:1997 +msgid "Combine several paths into one" +msgstr "Спој више крива у једну" + +#. TRANSLATORS: "to cut a path" is not the same as "to break a path apart" - see the +#. Advanced tutorial for more info +#: ../../po/../src/verbs.cpp:2000 +msgid "Break _Apart" +msgstr "_Раздвој облик" + +#: ../../po/../src/verbs.cpp:2001 +#, fuzzy +msgid "Break selected paths into subpaths" +msgstr "Раздвој изабрану криву на подкриве" + +#: ../../po/../src/verbs.cpp:2002 +msgid "Gri_d Arrange..." +msgstr "Уклапање у _мрежу..." + +#: ../../po/../src/verbs.cpp:2003 +msgid "Arrange selection in grid pattern" +msgstr "Уклапање изабраних објеката у мрежу" + +#. Layer +#: ../../po/../src/verbs.cpp:2005 +msgid "_Add Layer..." +msgstr "_Нови слој..." + +#: ../../po/../src/verbs.cpp:2006 +msgid "Create a new layer" +msgstr "Прављење новог слоја" + +#: ../../po/../src/verbs.cpp:2007 +msgid "Re_name Layer..." +msgstr "_Преименуј слој..." + +#: ../../po/../src/verbs.cpp:2008 +msgid "Rename the current layer" +msgstr "Промена назива тренутног слоја" + +#: ../../po/../src/verbs.cpp:2009 +msgid "Switch to Layer Abov_e" +msgstr "Пређи на _горњи слој" + +#: ../../po/../src/verbs.cpp:2010 +msgid "Switch to the layer above the current" +msgstr "Прелазак на први слој изнад тренутног" + +#: ../../po/../src/verbs.cpp:2011 +msgid "Switch to Layer Belo_w" +msgstr "Пређи на _доњи слој" + +#: ../../po/../src/verbs.cpp:2012 +msgid "Switch to the layer below the current" +msgstr "Прелазак на први слој испод тренутног" + +#: ../../po/../src/verbs.cpp:2013 +msgid "Move Selection to Layer Abo_ve" +msgstr "Премести избор на го_рњи слој" + +#: ../../po/../src/verbs.cpp:2014 +msgid "Move selection to the layer above the current" +msgstr "Премешта избор на први слој изнад тренутног" + +#: ../../po/../src/verbs.cpp:2015 +msgid "Move Selection to Layer Bel_ow" +msgstr "Премести избор на д_оњи слој" + +#: ../../po/../src/verbs.cpp:2016 +msgid "Move selection to the layer below the current" +msgstr "Премешта избор на први слој испод тренутног" + +#: ../../po/../src/verbs.cpp:2017 +msgid "Layer to _Top" +msgstr "Слој на _врх" + +#: ../../po/../src/verbs.cpp:2018 +msgid "Raise the current layer to the top" +msgstr "Издизање тренутног слоја испред осталих" + +#: ../../po/../src/verbs.cpp:2019 +msgid "Layer to _Bottom" +msgstr "Слој на _дно" + +#: ../../po/../src/verbs.cpp:2020 +msgid "Lower the current layer to the bottom" +msgstr "Постави тренутни слој иза осталих" + +#: ../../po/../src/verbs.cpp:2021 +msgid "_Raise Layer" +msgstr "_Издигни слој" + +#: ../../po/../src/verbs.cpp:2022 +msgid "Raise the current layer" +msgstr "Издизање тренутног слоја" + +#: ../../po/../src/verbs.cpp:2023 +msgid "_Lower Layer" +msgstr "_Заклони слој" + +#: ../../po/../src/verbs.cpp:2024 +msgid "Lower the current layer" +msgstr "Спушта тренутног слоја" + +#: ../../po/../src/verbs.cpp:2025 +msgid "_Delete Current Layer" +msgstr "_Уклони тренутни слој" + +#: ../../po/../src/verbs.cpp:2026 +msgid "Delete the current layer" +msgstr "Уклања тренутни слој" + +#. Object +#: ../../po/../src/verbs.cpp:2029 +#, fuzzy +msgid "Rotate _90° CW" +msgstr "Ротирај за _90° у десно" + +#: ../../po/../src/verbs.cpp:2030 +#, fuzzy +msgid "Rotate selection 90° clockwise" +msgstr "Ротира за 90° у смеру казаљке на сату" + +#: ../../po/../src/verbs.cpp:2031 +#, fuzzy +msgid "Rotate 9_0° CCW" +msgstr "Ротирај за 9_0° у лево" + +#: ../../po/../src/verbs.cpp:2032 +#, fuzzy +msgid "Rotate selection 90° counter-clockwise" +msgstr "Ротира за 90° у обрнутом смеру од смера казаљке на сату" + +#: ../../po/../src/verbs.cpp:2033 +msgid "Remove _Transformations" +msgstr "Поништи _трансформацију" + +#: ../../po/../src/verbs.cpp:2034 +msgid "Remove transformations from object" +msgstr "Уклања трансформације објекта" + +#: ../../po/../src/verbs.cpp:2035 +msgid "_Object to Path" +msgstr "_Објекат у линију" + +#: ../../po/../src/verbs.cpp:2036 +#, fuzzy +msgid "Convert selected objects to paths" +msgstr "Претвaрa изабрани објекат у криву" + +#: ../../po/../src/verbs.cpp:2037 +msgid "_Flow into Frame" +msgstr "_Постави у оквир" + +#: ../../po/../src/verbs.cpp:2038 +#, fuzzy +msgid "Put text into frames" +msgstr "Поставља текст у оквир" + +#: ../../po/../src/verbs.cpp:2039 +msgid "_Unflow" +msgstr "_Неплутајући текст" + +#: ../../po/../src/verbs.cpp:2040 +msgid "Remove text from frame (creates a single-line text object)" +msgstr "Склања текст из оквира (прави једнолинијски текст)" + +#: ../../po/../src/verbs.cpp:2041 +msgid "_Convert to Text" +msgstr "_Претвори у текст" + +#: ../../po/../src/verbs.cpp:2042 +#, fuzzy +msgid "Convert flowed text to regular text objects (preserves appearance)" +msgstr "Претвара изабрани плутајући текст у регуларан текст објекат" + +#: ../../po/../src/verbs.cpp:2044 +#, fuzzy +msgid "Flip _Horizontal" +msgstr "Изврни _водоравно" + +#: ../../po/../src/verbs.cpp:2044 +#, fuzzy +msgid "Flips selected objects horizontally" +msgstr "Поравнава изабране чворове водоравно" + +#: ../../po/../src/verbs.cpp:2047 +#, fuzzy +msgid "Flip _Vertical" +msgstr "Изврни _усправно" + +#: ../../po/../src/verbs.cpp:2047 +#, fuzzy +msgid "Flips selected objects vertically" +msgstr "Поравнава изабране чворове усправно" + +#. Tools +#: ../../po/../src/verbs.cpp:2051 +msgid "Select" +msgstr "Изборник" + +#: ../../po/../src/verbs.cpp:2052 +msgid "Select and transform objects" +msgstr "Избор и трансформација објеката" + +#: ../../po/../src/verbs.cpp:2053 +msgid "Node Edit" +msgstr "Уређивач чворова" + +#: ../../po/../src/verbs.cpp:2054 +msgid "Edit path nodes or control handles" +msgstr "Уређивање чворова криве и контрола ручки" + +#: ../../po/../src/verbs.cpp:2056 +msgid "Create rectangles and squares" +msgstr "Исцртавање правоугаоника и квадрата" + +#: ../../po/../src/verbs.cpp:2058 +msgid "Create circles, ellipses, and arcs" +msgstr "Исцртавање кружница, елипса и лукова" + +#: ../../po/../src/verbs.cpp:2060 +msgid "Create stars and polygons" +msgstr "Исцртавање звезди и полигона" + +#: ../../po/../src/verbs.cpp:2062 +msgid "Create spirals" +msgstr "Исцртавање спирала" + +#: ../../po/../src/verbs.cpp:2064 +msgid "Draw freehand lines" +msgstr "Исцртавање линије слободном руком" + +#: ../../po/../src/verbs.cpp:2066 +msgid "Draw Bezier curves and straight lines" +msgstr "Исцртавање безиерових крива и правих линија" + +#: ../../po/../src/verbs.cpp:2068 +msgid "Draw calligraphic lines" +msgstr "Исцртавање калиграфске линије" + +#: ../../po/../src/verbs.cpp:2070 +msgid "Create and edit text objects" +msgstr "Прављење и уређивање текста" + +#: ../../po/../src/verbs.cpp:2072 +msgid "Create and edit gradients" +msgstr "Прављење и уређивање прелива" + +#: ../../po/../src/verbs.cpp:2074 +msgid "Zoom in or out" +msgstr "Увеличавање и умањење" + +#: ../../po/../src/verbs.cpp:2076 +msgid "Pick averaged colors from image" +msgstr "Бојење изабраног објекта просечном бојом површине" + +#: ../../po/../src/verbs.cpp:2078 +#, fuzzy +msgid "Create connectors" +msgstr "Направи нови СВГ документ" + +#. Tool prefs +#: ../../po/../src/verbs.cpp:2081 +msgid "Selector Preferences" +msgstr "Поставке изборника" + +#: ../../po/../src/verbs.cpp:2082 +#, fuzzy +msgid "Open Preferences for the Selector tool" +msgstr "Отвара картицу алата за избор у поставкама програма" + +#: ../../po/../src/verbs.cpp:2083 +msgid "Node Tool Preferences" +msgstr "Поставке чворова" + +#: ../../po/../src/verbs.cpp:2084 +#, fuzzy +msgid "Open Preferences for the Node tool" +msgstr "Отвара картицу алата за чворове у поставкама програма" + +# bug: rect -> rectangle +#: ../../po/../src/verbs.cpp:2085 +msgid "Rectangle Preferences" +msgstr "Поставке правоугаоника" + +#: ../../po/../src/verbs.cpp:2086 +#, fuzzy +msgid "Open Preferences for the Rectangle tool" +msgstr "Отвара картицу алата за правоугаонике у поставкама програма" + +#: ../../po/../src/verbs.cpp:2087 +msgid "Ellipse Preferences" +msgstr "Поставке елипсе" + +#: ../../po/../src/verbs.cpp:2088 +#, fuzzy +msgid "Open Preferences for the Ellipse tool" +msgstr "Отвара картицу алата за елипсе у поставкама програма" + +#: ../../po/../src/verbs.cpp:2089 +msgid "Star Preferences" +msgstr "Поставке звезде" + +#: ../../po/../src/verbs.cpp:2090 +#, fuzzy +msgid "Open Preferences for the Star tool" +msgstr "Отвара картицу алата за звезде у поставкама програма" + +#: ../../po/../src/verbs.cpp:2091 +msgid "Spiral Preferences" +msgstr "Поставке спирале" + +#: ../../po/../src/verbs.cpp:2092 +#, fuzzy +msgid "Open Preferences for the Spiral tool" +msgstr "Отвара картицу алата за спирале у поставкама програма" + +#: ../../po/../src/verbs.cpp:2093 +msgid "Pencil Preferences" +msgstr "Поставке грубе оловке" + +#: ../../po/../src/verbs.cpp:2094 +#, fuzzy +msgid "Open Preferences for the Pencil tool" +msgstr "Отвара картицу алата грубе оловке у поставкама програма" + +#: ../../po/../src/verbs.cpp:2095 +msgid "Pen Preferences" +msgstr "Поставке оловке" + +#: ../../po/../src/verbs.cpp:2096 +#, fuzzy +msgid "Open Preferences for the Pen tool" +msgstr "Отвара картицу алата оловке у поставкама програма" + +#: ../../po/../src/verbs.cpp:2097 +msgid "Calligraphic Preferences" +msgstr "Поставке калиграфског пера" + +#: ../../po/../src/verbs.cpp:2098 +#, fuzzy +msgid "Open Preferences for the Calligraphy tool" +msgstr "Отвара картицу алата за калиграфију у поставкама програма" + +#: ../../po/../src/verbs.cpp:2099 +msgid "Text Preferences" +msgstr "Поставке текста" + +#: ../../po/../src/verbs.cpp:2100 +#, fuzzy +msgid "Open Preferences for the Text tool" +msgstr "Отвара картицу алата за текст у поставкама програма" + +#: ../../po/../src/verbs.cpp:2101 +msgid "Gradient Preferences" +msgstr "Поставке прелива" + +#: ../../po/../src/verbs.cpp:2102 +#, fuzzy +msgid "Open Preferences for the Gradient tool" +msgstr "Отвара картицу прелива у поставкама програма" + +#: ../../po/../src/verbs.cpp:2103 +msgid "Zoom Preferences" +msgstr "Поставке зума" + +#: ../../po/../src/verbs.cpp:2104 +#, fuzzy +msgid "Open Preferences for the Zoom tool" +msgstr "Отвара картицу алата за зумирање у поставкама програма" + +#: ../../po/../src/verbs.cpp:2105 +msgid "Dropper Preferences" +msgstr "Поставке изборника боја" + +#: ../../po/../src/verbs.cpp:2106 +#, fuzzy +msgid "Open Preferences for the Dropper tool" +msgstr "Отвара картицу алата за избор боје у поставкама програма" + +#: ../../po/../src/verbs.cpp:2107 +#, fuzzy +msgid "Connector Preferences" +msgstr "Поставке изборника" + +#: ../../po/../src/verbs.cpp:2108 +#, fuzzy +msgid "Open Preferences for the Connector tool" +msgstr "Отвара картицу алата за избор у поставкама програма" + +#. Zoom/View +#: ../../po/../src/verbs.cpp:2111 +msgid "Zoom In" +msgstr "Увећај" + +#: ../../po/../src/verbs.cpp:2111 +msgid "Zoom in" +msgstr "Увећавање" + +#: ../../po/../src/verbs.cpp:2112 +msgid "Zoom Out" +msgstr "Умањи" + +#: ../../po/../src/verbs.cpp:2112 +msgid "Zoom out" +msgstr "Умањивање" + +#: ../../po/../src/verbs.cpp:2113 +msgid "_Rulers" +msgstr "_Лењири" + +#: ../../po/../src/verbs.cpp:2113 +msgid "Show or hide the canvas rulers" +msgstr "Прикажи или сакриј лењире платна" + +#: ../../po/../src/verbs.cpp:2114 +msgid "Scroll_bars" +msgstr "_Траке за померање" + +#: ../../po/../src/verbs.cpp:2114 +msgid "Show or hide the canvas scrollbars" +msgstr "Прикажи или сакриј траке за померање платна" + +#: ../../po/../src/verbs.cpp:2115 +msgid "_Grid" +msgstr "_Мрежа" + +#: ../../po/../src/verbs.cpp:2116 +msgid "G_uides" +msgstr "_Вођице" + +#: ../../po/../src/verbs.cpp:2117 +msgid "Nex_t Zoom" +msgstr "Сле_дећи зум" + +#: ../../po/../src/verbs.cpp:2117 +msgid "Next zoom (from the history of zooms)" +msgstr "Следећи зум (из историје промене увећања)" + +#: ../../po/../src/verbs.cpp:2119 +msgid "Pre_vious Zoom" +msgstr "Пре_тходни зум" + +#: ../../po/../src/verbs.cpp:2119 +msgid "Previous zoom (from the history of zooms)" +msgstr "Претходни зум (из историје промене увећања)" + +#: ../../po/../src/verbs.cpp:2121 +msgid "Zoom 1:_1" +msgstr "Постави размеру на 1:_1" + +#: ../../po/../src/verbs.cpp:2121 +msgid "Zoom to 1:1" +msgstr "Постављање размере на 1:1" + +#: ../../po/../src/verbs.cpp:2123 +msgid "Zoom 1:_2" +msgstr "Постави размеру на 1:_2" + +#: ../../po/../src/verbs.cpp:2123 +msgid "Zoom to 1:2" +msgstr "Постављање размере на 1:2" + +#: ../../po/../src/verbs.cpp:2125 +msgid "_Zoom 2:1" +msgstr "Постави _размеру на 2:1" + +#: ../../po/../src/verbs.cpp:2125 +msgid "Zoom to 2:1" +msgstr "Постављање размере на 2:1" + +#: ../../po/../src/verbs.cpp:2128 +msgid "_Fullscreen" +msgstr "_Цео екран" + +#: ../../po/../src/verbs.cpp:2128 +msgid "Stretch this document window to full screen" +msgstr "Развлачење прозора овог документа преко целог екрана" + +#: ../../po/../src/verbs.cpp:2131 +msgid "Duplic_ate Window" +msgstr "_Удвостручи прозор" + +#: ../../po/../src/verbs.cpp:2131 +msgid "Open a new window with the same document" +msgstr "Отварање новог прозора са истим документом" + +#: ../../po/../src/verbs.cpp:2133 +msgid "_New View Preview" +msgstr "_Нови преглед" + +#: ../../po/../src/verbs.cpp:2134 +msgid "New View Preview" +msgstr "Нови преглед документа" + +#. "view_new_preview" +#: ../../po/../src/verbs.cpp:2136 +#, fuzzy +msgid "_Normal" +msgstr "Нормално" + +#: ../../po/../src/verbs.cpp:2137 +msgid "Switch to normal display mode" +msgstr "" + +#: ../../po/../src/verbs.cpp:2138 +#, fuzzy +msgid "_Outline" +msgstr "Оквир контејнера" + +#: ../../po/../src/verbs.cpp:2139 +msgid "Switch to outline (wireframe) display mode" +msgstr "" + +#: ../../po/../src/verbs.cpp:2141 +msgid "Ico_n Preview" +msgstr "Приказ и_кона" + +#: ../../po/../src/verbs.cpp:2142 +msgid "Open a window to preview items at different icon resolutions" +msgstr "Отвара прозор за приказ објекта у различитим резолуцијама иконе" + +#: ../../po/../src/verbs.cpp:2144 +msgid "Zoom to fit page in window" +msgstr "Уклопи целу страну у прозор" + +#: ../../po/../src/verbs.cpp:2145 +msgid "Page _Width" +msgstr "_Ширина стране" + +#: ../../po/../src/verbs.cpp:2146 +msgid "Zoom to fit page width in window" +msgstr "Уклопи ширину стране у прозор" + +#: ../../po/../src/verbs.cpp:2148 +msgid "Zoom to fit drawing in window" +msgstr "Уклопи цео цртеж у прозор" + +#: ../../po/../src/verbs.cpp:2150 +msgid "Zoom to fit selection in window" +msgstr "Уклопи цео избор у прозор" + +#. Dialogs +#: ../../po/../src/verbs.cpp:2153 +msgid "In_kscape Preferences..." +msgstr "Поставке _програма..." + +#: ../../po/../src/verbs.cpp:2154 +msgid "Global Inkscape preferences" +msgstr "Општа подешавања ИнкСкејпа" + +#: ../../po/../src/verbs.cpp:2155 +msgid "_Document Preferences..." +msgstr "Поставке _документа..." + +#: ../../po/../src/verbs.cpp:2156 +msgid "Preferences saved with the document" +msgstr "Поставке се чувају у датотеци документа" + +#: ../../po/../src/verbs.cpp:2157 +msgid "_Fill and Stroke..." +msgstr "_Попуне и линије..." + +#: ../../po/../src/verbs.cpp:2158 +msgid "Fill and Stroke dialog" +msgstr "Прозорче за поставке карактеристика попуна и линија" + +#. TRANSLATORS: "Swatches" means: color samples +#: ../../po/../src/verbs.cpp:2160 +#, fuzzy +msgid "S_watches..." +msgstr "Сачувај _као..." + +#: ../../po/../src/verbs.cpp:2161 +msgid "View color swatches" +msgstr "" + +#: ../../po/../src/verbs.cpp:2162 +msgid "Transfor_m..." +msgstr "_Трансформација..." + +#: ../../po/../src/verbs.cpp:2163 +msgid "Transform dialog" +msgstr "Прозорче за трансформације" + +#: ../../po/../src/verbs.cpp:2164 +msgid "_Align and Distribute..." +msgstr "Пор_авнавање и распоређивање" + +#: ../../po/../src/verbs.cpp:2165 +msgid "Align and Distribute dialog" +msgstr "Прозорче за подешавање поравнавања и распоређивања" + +#: ../../po/../src/verbs.cpp:2166 +msgid "_Text and Font..." +msgstr "_Текст и фонт..." + +#: ../../po/../src/verbs.cpp:2167 +msgid "Text and Font dialog" +msgstr "Прозорче за поставке текста и фонта" + +#: ../../po/../src/verbs.cpp:2168 +msgid "_XML Editor..." +msgstr "XML _уређивач" + +#: ../../po/../src/verbs.cpp:2169 +msgid "XML Editor" +msgstr "XML уређивач" + +#: ../../po/../src/verbs.cpp:2170 +msgid "_Find..." +msgstr "_Тражи..." + +#: ../../po/../src/verbs.cpp:2171 +msgid "Find objects in document" +msgstr "Тражење објекта у документу" + +#: ../../po/../src/verbs.cpp:2172 +msgid "_Messages..." +msgstr "_Поруке..." + +#: ../../po/../src/verbs.cpp:2173 +msgid "View debug messages" +msgstr "Преглед порука дневника рада" + +#: ../../po/../src/verbs.cpp:2174 +msgid "S_cripts..." +msgstr "_Скрипте..." + +#: ../../po/../src/verbs.cpp:2175 +msgid "Run scripts" +msgstr "Покрени скрипту" + +#: ../../po/../src/verbs.cpp:2176 +msgid "Show/Hide D_ialogs" +msgstr "Прикажи/_сакриј прозорчиће" + +#: ../../po/../src/verbs.cpp:2177 +msgid "Show or hide all active dialogs" +msgstr "Прикажи или сакриј све активне прозорчиће" + +#. TRANSLATORS: "Tile clones" means: "Create tiled clones" +#: ../../po/../src/verbs.cpp:2179 +msgid "Tile clones..." +msgstr "Слагање клонова..." + +#: ../../po/../src/verbs.cpp:2180 +msgid "Create and arrange multiple clones of selection" +msgstr "Прављење и слагање вишеструких клонова избора" + +# bug: rect -> rectangle +#: ../../po/../src/verbs.cpp:2181 +msgid "_Object Properties..." +msgstr "_Особине објекта..." + +# bug: rect -> rectangle +#: ../../po/../src/verbs.cpp:2182 +msgid "Object Properties dialog" +msgstr "Прозорче са особинама објекта" + +#: ../../po/../src/verbs.cpp:2185 +msgid "_Connect to Jabber server..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2185 +msgid "Connect to a Jabber server" +msgstr "" + +#: ../../po/../src/verbs.cpp:2187 +#, fuzzy +msgid "Share with _user..." +msgstr "Сачувај _као..." + +#: ../../po/../src/verbs.cpp:2187 +msgid "Establish a whiteboard session with another Jabber user" +msgstr "" + +#: ../../po/../src/verbs.cpp:2189 +msgid "Share with _chatroom..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2189 +msgid "" +"Join a chatroom to start a new whiteboard session or join one in progress" +msgstr "" + +#: ../../po/../src/verbs.cpp:2191 +msgid "_Dump XML node tracker" +msgstr "" + +#: ../../po/../src/verbs.cpp:2191 +msgid "Dump the contents of the XML tracker to the console" +msgstr "" + +#: ../../po/../src/verbs.cpp:2193 +msgid "_Open session file..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2193 +msgid "Open and browse through records of past whiteboard sessions" +msgstr "" + +#: ../../po/../src/verbs.cpp:2195 +msgid "Session file playback" +msgstr "" + +#: ../../po/../src/verbs.cpp:2197 +msgid "_Disconnect from session" +msgstr "" + +#: ../../po/../src/verbs.cpp:2199 +msgid "Disconnect from _server" +msgstr "" + +#: ../../po/../src/verbs.cpp:2201 +msgid "_Input Devices..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2202 +msgid "Configure extended input devices" +msgstr "" + +#. Help +#: ../../po/../src/verbs.cpp:2205 +msgid "_Keys and Mouse" +msgstr "_Пречице и миш" + +#: ../../po/../src/verbs.cpp:2206 +msgid "Key and mouse shortcuts reference" +msgstr "Попис печица тастатуре и миша" + +#: ../../po/../src/verbs.cpp:2207 +msgid "About E_xtensions" +msgstr "О _екстензијама" + +#: ../../po/../src/verbs.cpp:2208 +msgid "About Extensions..." +msgstr "Детаљи о екстензијама" + +#: ../../po/../src/verbs.cpp:2209 +msgid "About _Memory" +msgstr "О _меморији" + +#: ../../po/../src/verbs.cpp:2210 +msgid "About Memory..." +msgstr "Детаљи о меморији" + +#: ../../po/../src/verbs.cpp:2211 +msgid "_About Inkscape" +msgstr "О _програму" + +#. "help_about" +#. new HelpVerb(SP_VERB_SHOW_LICENSE, "ShowLicense", N_("Modifying or Redistributing Inkscape"), +#. N_("Show license to modify and/or redistribute Inkscape: GNU GPL"), NULL), +#. Tutorials +#: ../../po/../src/verbs.cpp:2217 +msgid "Inkscape: _Basic" +msgstr "ИнкСкејп: _Основе" + +#: ../../po/../src/verbs.cpp:2218 +msgid "Getting started with Inkscape" +msgstr "Основе програма" + +#. "tutorial_basic" +#: ../../po/../src/verbs.cpp:2219 +msgid "Inkscape: _Shapes" +msgstr "Inkscape: _Облици" + +#: ../../po/../src/verbs.cpp:2220 +msgid "Using shape tools to create and edit shapes" +msgstr "Употреба алата за прављење и уређивање облика" + +#: ../../po/../src/verbs.cpp:2221 +msgid "Inkscape: _Advanced" +msgstr "Inkscape: _Напредно" + +#: ../../po/../src/verbs.cpp:2222 +msgid "Advanced Inkscape topics" +msgstr "Напредне вежбе" + +#. "tutorial_advanced" +#. TRANSLATORS: "to trace" means "to convert a bitmap to vector graphics" (to vectorize) +#: ../../po/../src/verbs.cpp:2224 +msgid "Inkscape: T_racing" +msgstr "Inkscape: _Трасирање" + +#: ../../po/../src/verbs.cpp:2225 +msgid "Using bitmap tracing" +msgstr "Употреба алата за претварање битмапа у векторе" + +#. "tutorial_tracing" +#: ../../po/../src/verbs.cpp:2226 +msgid "Inkscape: _Calligraphy" +msgstr "Inkscape: _Калиграфија" + +#: ../../po/../src/verbs.cpp:2227 +msgid "Using the Calligraphy pen tool" +msgstr "Употреба калиграфске оловке" + +#: ../../po/../src/verbs.cpp:2228 +msgid "_Elements of Design" +msgstr "_Делови за дизајн" + +#: ../../po/../src/verbs.cpp:2229 +msgid "Principles of design in the tutorial form" +msgstr "Принципи дизајнирања у облику упутства" + +#. "tutorial_design" +#: ../../po/../src/verbs.cpp:2230 +msgid "_Tips and Tricks" +msgstr "_Савети и трикови" + +#: ../../po/../src/verbs.cpp:2231 +msgid "Miscellaneous tips and tricks" +msgstr "Разни савети и трикови за употребу програма" + +#. "tutorial_tips" +#. Effect +#: ../../po/../src/verbs.cpp:2234 +msgid "Previous Effect" +msgstr "Претходни ефекат" + +#: ../../po/../src/verbs.cpp:2235 +msgid "Repeat the last effect with the same settings" +msgstr "Понови последњи ефекат са истим подешавањима" + +#. "tutorial_tips" +#: ../../po/../src/verbs.cpp:2236 +#, fuzzy +msgid "Previous Effect Settings..." +msgstr "Претходни ефекат..." + +#: ../../po/../src/verbs.cpp:2237 +msgid "Repeat the last effect with new settings" +msgstr "Понављање последњег ефекта са новим подешавањима" + +#: ../../po/../src/widgets/dash-selector.cpp:106 +msgid "Dash pattern" +msgstr "Шаблон линије" + +#: ../../po/../src/widgets/dash-selector.cpp:121 +msgid "Pattern offset" +msgstr "Размак шаблона" + +#: ../../po/../src/widgets/desktop-widget.cpp:240 +msgid "Zoom drawing if window size changes" +msgstr "Зумирај цртеж када се промени величина прозора" + +#: ../../po/../src/widgets/desktop-widget.cpp:298 +msgid "Cursor coordinates" +msgstr "Координате показивача миша" + +#. display the initial welcome message in the statusbar +#: ../../po/../src/widgets/desktop-widget.cpp:324 +msgid "" +"Welcome to Inkscape! Use shape or freehand tools to create objects; " +"use selector (arrow) to move or transform them." +msgstr "" +"Добро дошли у Инкскејп! Користите облике или алат за цртање слободном " +"руком да би исцртали објекте; користите изборник (стрелицу) за њихово " +"померање и промену облика." + +#: ../../po/../src/widgets/desktop-widget.cpp:372 +#, c-format +msgid "%s: %d - Inkscape" +msgstr "%s: %d - Inkscape" + +#: ../../po/../src/widgets/desktop-widget.cpp:374 +#, c-format +msgid "%s - Inkscape" +msgstr "%s - Inkscape" + +#: ../../po/../src/widgets/desktop-widget.cpp:532 +#, c-format +msgid "" +"Save changes to document \"%s\" before " +"closing?\n" +"\n" +"If you close without saving, your changes will be discarded." +msgstr "" +"Памћење измена у документу „%s“ пре " +"затварања?\n" +"\n" +"Ако напустите програм без памћења измена, измене које сте начинили ће бити " +"занемарене." + +#: ../../po/../src/widgets/desktop-widget.cpp:548 +#: ../../po/../src/widgets/desktop-widget.cpp:612 +msgid "Close _without saving" +msgstr "Затвори _без снимања" + +#: ../../po/../src/widgets/desktop-widget.cpp:595 +#, c-format +msgid "" +"The file \"%s\" was saved with a " +"format (%s) that may cause data loss!\n" +"\n" +"Do you want to save this file in another format?" +msgstr "" +"Датотека „%s“ је сачувана у формату (%" +"s) који може проузроковати губитак података!\n" +"\n" +"Желите ли да сачувате ову датотеку у неком другом формату?" + +#. Family frame +#: ../../po/../src/widgets/font-selector.cpp:156 +msgid "Font family" +msgstr "Породица фонта" + +#. Style frame +#: ../../po/../src/widgets/font-selector.cpp:184 +msgid "Style" +msgstr "Стил" + +#: ../../po/../src/widgets/font-selector.cpp:219 +msgid "Font size:" +msgstr "Величина фонта:" + +#. TRANSLATORS: Test string used in text and font dialog (when no +#. * text has been entered) to get a preview of the font. Choose +#. * some representative characters that users of your locale will be +#. * interested in. +#: ../../po/../src/widgets/font-selector.cpp:554 +msgid "AaBbCcIiPpQq12368.;/()" +msgstr "АаБбВвДдЂђЉљЧч12368.;/()„“" + +#: ../../po/../src/widgets/gradient-selector.cpp:137 +#: ../../po/../src/widgets/gradient-toolbar.cpp:524 +msgid "Duplicate" +msgstr "Удвостручи" + +#: ../../po/../src/widgets/gradient-selector.cpp:142 +#: ../../po/../src/widgets/gradient-toolbar.cpp:535 +msgid "Edit..." +msgstr "Уреди..." + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/pservers.html#LinearGradientSpreadMethodAttribute +#: ../../po/../src/widgets/gradient-selector.cpp:159 +msgid "" +"Whether to fill with flat color beyond the ends of the gradient vector " +"(spreadMethod=\"pad\"), or repeat the gradient in the same direction " +"(spreadMethod=\"repeat\"), or repeat the gradient in alternating opposite " +"directions (spreadMethod=\"reflect\")" +msgstr "" +"Да ли ће се за попуну изван ивица вектора прелива узима једнобојна попуна " +"(spreadMethod=\"pad\"), или понављање прелива у истом смеру (spreadMethod=" +"\"repeat\"), или понављање прелива у алтернативном супротном смеру " +"(spreadMethod=\"reflect\")" + +#: ../../po/../src/widgets/gradient-selector.cpp:165 +msgid "none" +msgstr "ништа" + +#: ../../po/../src/widgets/gradient-selector.cpp:169 +msgid "reflected" +msgstr "одраз" + +# bug: cannot be easily translated; please use "rectangle" +#: ../../po/../src/widgets/gradient-selector.cpp:173 +msgid "direct" +msgstr "понављање" + +#: ../../po/../src/widgets/gradient-selector.cpp:181 +msgid "Repeat:" +msgstr "Понављање:" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:217 +msgid "No gradients" +msgstr "Нема прелива" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:226 +msgid "Nothing selected" +msgstr "Ништа није изабрано" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:237 +msgid "No gradients in selection" +msgstr "Нема прелива у избору" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:247 +msgid "Multiple gradients" +msgstr "Вишеструки преливи" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:525 +msgid "" +"If the gradient is used by more than one object, create a copy of it for the " +"selected object(s)" +msgstr "" +"Ако прелив користи више од једног објекта, направи његову копију за " +"изабреане објекте" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:536 +msgid "Edit the stops of the gradient" +msgstr "Уређивање станица прелива" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:593 +#: ../../po/../src/widgets/toolbox.cpp:1103 +#: ../../po/../src/widgets/toolbox.cpp:1192 +#: ../../po/../src/widgets/toolbox.cpp:1485 +#: ../../po/../src/widgets/toolbox.cpp:1534 +#: ../../po/../src/widgets/toolbox.cpp:1766 +#: ../../po/../src/widgets/toolbox.cpp:1801 +#: ../../po/../src/widgets/toolbox.cpp:2331 +#: ../../po/../src/widgets/toolbox.cpp:2370 +msgid "New:" +msgstr "Ново:" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:606 +msgid "Create linear gradient" +msgstr "Направи линеарни прелив" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:620 +msgid "Create radial (elliptic or circular) gradient" +msgstr "Направи радијални (елипсасти или округли) прелив" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:635 +msgid "on" +msgstr "на" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:648 +msgid "Create gradient in the fill" +msgstr "Направи прелив у попуни" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:662 +msgid "Create gradient in the stroke" +msgstr "Направи прелив у линији" + +#. FIXME: implement averaging of all parameters for multiple selected stars +#. gtk_label_set_markup(GTK_LABEL(l), _("Average:")); +#. FIXME: implement averaging of all parameters for multiple selected +#. gtk_label_set_markup(GTK_LABEL(l), _("Average:")); +#: ../../po/../src/widgets/gradient-toolbar.cpp:676 +#: ../../po/../src/widgets/toolbox.cpp:1105 +#: ../../po/../src/widgets/toolbox.cpp:1124 +#: ../../po/../src/widgets/toolbox.cpp:1493 +#: ../../po/../src/widgets/toolbox.cpp:1518 +#: ../../po/../src/widgets/toolbox.cpp:1768 +#: ../../po/../src/widgets/toolbox.cpp:1787 +#: ../../po/../src/widgets/toolbox.cpp:2334 +#: ../../po/../src/widgets/toolbox.cpp:2354 +msgid "Change:" +msgstr "Измена:" + +#: ../../po/../src/widgets/gradient-vector.cpp:269 +msgid "No gradients in document" +msgstr "Нема прелива у документу" + +#: ../../po/../src/widgets/gradient-vector.cpp:275 +msgid "No gradient selected" +msgstr "Прелив није изабран" + +#: ../../po/../src/widgets/gradient-vector.cpp:532 +msgid "No stops in gradient" +msgstr "Без станице боје у преливу" + +#. TRANSLATORS: "Stop" means: a "phase" of a gradient +#: ../../po/../src/widgets/gradient-vector.cpp:794 +msgid "Add stop" +msgstr "Додај станицу боје" + +#: ../../po/../src/widgets/gradient-vector.cpp:797 +msgid "Add another control stop to gradient" +msgstr "Додавање још једне контролне станице боје у прелив" + +#: ../../po/../src/widgets/gradient-vector.cpp:799 +msgid "Delete stop" +msgstr "Уклони станицу боје" + +#: ../../po/../src/widgets/gradient-vector.cpp:802 +msgid "Delete current control stop from gradient" +msgstr "Уклањање тренутне контролне станице боје из прелива" + +#. Label +#: ../../po/../src/widgets/gradient-vector.cpp:813 +msgid "Offset:" +msgstr "Размак:" + +#. TRANSLATORS: "Stop" means: a "phase" of a gradient +#: ../../po/../src/widgets/gradient-vector.cpp:858 +msgid "Stop Color" +msgstr "Станица боје" + +#: ../../po/../src/widgets/gradient-vector.cpp:887 +msgid "Gradient editor" +msgstr "Уређивач прелива" + +#: ../../po/../src/widgets/layer-selector.cpp:119 +msgid "Toggle current layer visibility" +msgstr "Промена видљивости тренутног слоја" + +#: ../../po/../src/widgets/layer-selector.cpp:139 +msgid "Lock or unlock current layer" +msgstr "Закључавање или откључавање тренутног слоја" + +#: ../../po/../src/widgets/layer-selector.cpp:142 +msgid "Current layer" +msgstr "Тренутни слој" + +#: ../../po/../src/widgets/layer-selector.cpp:553 +msgid "(root)" +msgstr "(основа)" + +#: ../../po/../src/widgets/paint-selector.cpp:182 +#: ../../po/../src/widgets/paint-selector.cpp:561 +msgid "No paint" +msgstr "Без боје" + +#: ../../po/../src/widgets/paint-selector.cpp:184 +#: ../../po/../src/widgets/paint-selector.cpp:629 +msgid "Flat color" +msgstr "Једнобојно" + +#: ../../po/../src/widgets/paint-selector.cpp:186 +#: ../../po/../src/widgets/paint-selector.cpp:696 +msgid "Linear gradient" +msgstr "Линијски прелив" + +#: ../../po/../src/widgets/paint-selector.cpp:188 +#: ../../po/../src/widgets/paint-selector.cpp:699 +msgid "Radial gradient" +msgstr "Кружни прелив" + +#: ../../po/../src/widgets/paint-selector.cpp:192 +msgid "Unset paint (make it undefined so it can be inherited)" +msgstr "Уклони боју (учини је неодређеном да може бити наслеђена)" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/painting.html#FillRuleProperty +#: ../../po/../src/widgets/paint-selector.cpp:204 +msgid "" +"Any path self-intersections or subpaths create holes in the fill (fill-rule: " +"evenodd)" +msgstr "" +"Било које преклапање криве објекта прави рупе у попуни (fill-rule: evenodd)" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/painting.html#FillRuleProperty +#: ../../po/../src/widgets/paint-selector.cpp:215 +msgid "" +"Fill is solid unless a subpath is counterdirectional (fill-rule: nonzero)" +msgstr "" +"Попуна је једнобојна док подкрива не буде изокренута (fill-rule: nonzero)" + +#: ../../po/../src/widgets/paint-selector.cpp:528 +msgid "No objects" +msgstr "Нема објеката" + +#: ../../po/../src/widgets/paint-selector.cpp:539 +msgid "Multiple styles" +msgstr "Више стилова" + +#: ../../po/../src/widgets/paint-selector.cpp:550 +msgid "Paint is undefined" +msgstr "Боја је неодређена" + +#: ../../po/../src/widgets/paint-selector.cpp:757 +msgid "No patterns in document" +msgstr "Нема мустри у документу" + +#: ../../po/../src/widgets/paint-selector.cpp:872 +msgid "" +"Use Edit > Object(s) to Pattern to create a new pattern from " +"selection." +msgstr "" +"Употребите Уређивање > Избор у Мустру за прављење нове мустре од " +"избора." + +#: ../../po/../src/widgets/select-toolbar.cpp:426 +msgid "Now stroke width is scaled when objects are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:428 +msgid "Now stroke width is not scaled when objects are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:436 +msgid "" +"Now rounded rectangle corners are scaled when rectangles are " +"scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:438 +msgid "" +"Now rounded rectangle corners are not scaled when rectangles " +"are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:446 +msgid "" +"Now gradients are transformed along with their objects when " +"those are transformed (moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:448 +msgid "" +"Now gradients remain fixed when objects are transformed " +"(moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:456 +msgid "" +"Now patterns are transformed along with their objects when " +"those are transformed (moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:458 +msgid "" +"Now patterns remain fixed when objects are transformed (moved, " +"scaled, rotated, or skewed)." +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:506 +msgid "select_toolbar|X" +msgstr "Изборник|X" + +#: ../../po/../src/widgets/select-toolbar.cpp:506 +msgid "Horizontal coordinate of selection" +msgstr "Водоравна координата избора" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:511 +msgid "select_toolbar|Y" +msgstr "Изборник|Y" + +#: ../../po/../src/widgets/select-toolbar.cpp:511 +msgid "Vertical coordinate of selection" +msgstr "Усправна координата избора" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:517 +msgid "select_toolbar|W" +msgstr "Изборник|Ш" + +#: ../../po/../src/widgets/select-toolbar.cpp:517 +msgid "Width of selection" +msgstr "Ширина избора" + +#: ../../po/../src/widgets/select-toolbar.cpp:525 +msgid "Change both width and height by the same proportion" +msgstr "Пропорцијална промена ширине и висине" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:534 +msgid "select_toolbar|H" +msgstr "Изборник|В" + +#: ../../po/../src/widgets/select-toolbar.cpp:534 +msgid "Height of selection" +msgstr "Висина избора" + +#: ../../po/../src/widgets/sp-color-gtkselector.cpp:62 +msgid "System" +msgstr "Систем" + +#: ../../po/../src/widgets/sp-color-notebook.cpp:322 +msgid "RGBA_:" +msgstr "RGBA_:" + +#: ../../po/../src/widgets/sp-color-notebook.cpp:330 +msgid "Hexadecimal RGBA value of the color" +msgstr "Хексадецимална RGBA вредност боје" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "RGB" +msgstr "RGB" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "HSL" +msgstr "HSL" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "CMYK" +msgstr "CMYK" + +#: ../../po/../src/widgets/sp-color-scales.cpp:397 +msgid "_R" +msgstr "_Ц" + +#: ../../po/../src/widgets/sp-color-scales.cpp:398 +#: ../../po/../src/widgets/sp-color-scales.cpp:399 +msgid "Red" +msgstr "Црвена" + +#: ../../po/../src/widgets/sp-color-scales.cpp:400 +msgid "_G" +msgstr "_З" + +#: ../../po/../src/widgets/sp-color-scales.cpp:401 +#: ../../po/../src/widgets/sp-color-scales.cpp:402 +msgid "Green" +msgstr "Зелена" + +#: ../../po/../src/widgets/sp-color-scales.cpp:403 +msgid "_B" +msgstr "_П" + +#: ../../po/../src/widgets/sp-color-scales.cpp:404 +#: ../../po/../src/widgets/sp-color-scales.cpp:405 +msgid "Blue" +msgstr "Плава" + +#. Label +#: ../../po/../src/widgets/sp-color-scales.cpp:406 +#: ../../po/../src/widgets/sp-color-scales.cpp:432 +#: ../../po/../src/widgets/sp-color-scales.cpp:463 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:141 +msgid "_A" +msgstr "_П" + +#: ../../po/../src/widgets/sp-color-scales.cpp:407 +#: ../../po/../src/widgets/sp-color-scales.cpp:408 +#: ../../po/../src/widgets/sp-color-scales.cpp:433 +#: ../../po/../src/widgets/sp-color-scales.cpp:434 +#: ../../po/../src/widgets/sp-color-scales.cpp:464 +#: ../../po/../src/widgets/sp-color-scales.cpp:465 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:151 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:163 +msgid "Alpha (opacity)" +msgstr "Провидност" + +#: ../../po/../src/widgets/sp-color-scales.cpp:423 +msgid "_H" +msgstr "_Н" + +#: ../../po/../src/widgets/sp-color-scales.cpp:424 +#: ../../po/../src/widgets/sp-color-scales.cpp:425 +msgid "Hue" +msgstr "Нијанса" + +#: ../../po/../src/widgets/sp-color-scales.cpp:426 +msgid "_S" +msgstr "_З" + +#: ../../po/../src/widgets/sp-color-scales.cpp:427 +#: ../../po/../src/widgets/sp-color-scales.cpp:428 +msgid "Saturation" +msgstr "Засићеност" + +#: ../../po/../src/widgets/sp-color-scales.cpp:429 +msgid "_L" +msgstr "_О" + +#: ../../po/../src/widgets/sp-color-scales.cpp:430 +#: ../../po/../src/widgets/sp-color-scales.cpp:431 +msgid "Lightness" +msgstr "Осветљеност" + +#: ../../po/../src/widgets/sp-color-scales.cpp:451 +msgid "_C" +msgstr "_Ц" + +#: ../../po/../src/widgets/sp-color-scales.cpp:452 +#: ../../po/../src/widgets/sp-color-scales.cpp:453 +msgid "Cyan" +msgstr "Цијан" + +#: ../../po/../src/widgets/sp-color-scales.cpp:454 +msgid "_M" +msgstr "_М" + +#: ../../po/../src/widgets/sp-color-scales.cpp:455 +#: ../../po/../src/widgets/sp-color-scales.cpp:456 +msgid "Magenta" +msgstr "Магента" + +#: ../../po/../src/widgets/sp-color-scales.cpp:457 +msgid "_Y" +msgstr "_Ж" + +#: ../../po/../src/widgets/sp-color-scales.cpp:458 +#: ../../po/../src/widgets/sp-color-scales.cpp:459 +msgid "Yellow" +msgstr "Жута" + +#: ../../po/../src/widgets/sp-color-scales.cpp:460 +msgid "_K" +msgstr "_К" + +#: ../../po/../src/widgets/sp-color-selector.cpp:71 +msgid "Unnamed" +msgstr "Неименовано" + +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:68 +msgid "Wheel" +msgstr "Круг" + +#: ../../po/../src/widgets/sp-xmlview-attr-list.cpp:53 +msgid "Attribute" +msgstr "Особина" + +#: ../../po/../src/widgets/sp-xmlview-attr-list.cpp:54 +msgid "Value" +msgstr "Вредност" + +#: ../../po/../src/widgets/toolbox.cpp:424 +msgid "Insert new nodes into selected segments" +msgstr "Убацивање нових чворова у изабране делове" + +#: ../../po/../src/widgets/toolbox.cpp:426 +msgid "Delete selected nodes" +msgstr "Уклањање изабраних чворова" + +#: ../../po/../src/widgets/toolbox.cpp:431 +msgid "Join paths at selected nodes" +msgstr "Спајање криве на изабраним чворовима" + +#: ../../po/../src/widgets/toolbox.cpp:433 +msgid "Join paths at selected nodes with new segment" +msgstr "Спајање криве новим делом између изабраних чворова" + +#: ../../po/../src/widgets/toolbox.cpp:436 +msgid "Split path between two non-endpoint nodes" +msgstr "Подели криву између два незавршавајућа чвора" + +#: ../../po/../src/widgets/toolbox.cpp:439 +msgid "Break path at selected nodes" +msgstr "Раздвајање криве на изабраним чворовима" + +#: ../../po/../src/widgets/toolbox.cpp:444 +msgid "Make selected nodes corner" +msgstr "Прављење ћошкасте криве на изабраним чворовима" + +# глатка крива се прецизно математички дефинише, и управо делује као „глатка“ +#: ../../po/../src/widgets/toolbox.cpp:447 +msgid "Make selected nodes smooth" +msgstr "Прављење глатке криве на изабраним чворовима" + +#: ../../po/../src/widgets/toolbox.cpp:450 +msgid "Make selected nodes symmetric" +msgstr "Прављење симетричне глатке криве на изабраним чворовима" + +#: ../../po/../src/widgets/toolbox.cpp:455 +msgid "Make selected segments lines" +msgstr "Прављење праве линије од изабраних делова" + +#: ../../po/../src/widgets/toolbox.cpp:458 +msgid "Make selected segments curves" +msgstr "Прављење криве линије од изабраних делова" + +#: ../../po/../src/widgets/toolbox.cpp:1199 +msgid "Polygon" +msgstr "Полигон" + +#: ../../po/../src/widgets/toolbox.cpp:1206 +msgid "Regular polygon (with one handle) instead of a star" +msgstr "Нормалан полигон (са једном ручком) уместо звезде" + +#: ../../po/../src/widgets/toolbox.cpp:1218 +msgid "Corners:" +msgstr "Углови:" + +#: ../../po/../src/widgets/toolbox.cpp:1218 +msgid "Number of corners of a polygon or star" +msgstr "Број углова полигона или звезде" + +#: ../../po/../src/widgets/toolbox.cpp:1228 +msgid "Spoke ratio:" +msgstr "Ширина крака:" + +#. TRANSLATORS: Tip radius of a star is the distance from the center to the farthest handle. +#. Base radius is the same for the closest handle. +#: ../../po/../src/widgets/toolbox.cpp:1231 +msgid "Base radius to tip radius ratio" +msgstr "Однос основног полупречника до ручке" + +#: ../../po/../src/widgets/toolbox.cpp:1246 +msgid "Rounded:" +msgstr "Заобљеност:" + +#: ../../po/../src/widgets/toolbox.cpp:1246 +msgid "How much rounded are the corners (0 for sharp)" +msgstr "Колико ће бити заобљени углови (0 за оштар угао)" + +#: ../../po/../src/widgets/toolbox.cpp:1256 +msgid "Randomized:" +msgstr "Насумично:" + +#: ../../po/../src/widgets/toolbox.cpp:1256 +msgid "Scatter randomly the corners and angles" +msgstr "Насумично размести ћошкове и углове" + +#: ../../po/../src/widgets/toolbox.cpp:1269 +#: ../../po/../src/widgets/toolbox.cpp:1838 +#: ../../po/../src/widgets/toolbox.cpp:2061 +msgid "Defaults" +msgstr "Подразумевано" + +#: ../../po/../src/widgets/toolbox.cpp:1270 +#: ../../po/../src/widgets/toolbox.cpp:1839 +#: ../../po/../src/widgets/toolbox.cpp:2062 +msgid "" +"Reset shape parameters to defaults (use Inkscape Preferences > Tools to " +"change defaults)" +msgstr "" +"Враћање параметара облика на подразумеване вредности (користите ИнкСкејп " +"Подешавања > Алати за промене подразумевано)" + +#: ../../po/../src/widgets/toolbox.cpp:1544 +msgid "W:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1544 +#, fuzzy +msgid "Width of rectangle" +msgstr "Ширина избора" + +#: ../../po/../src/widgets/toolbox.cpp:1556 +#, fuzzy +msgid "Height of rectangle" +msgstr "Висина избора" + +#: ../../po/../src/widgets/toolbox.cpp:1568 +msgid "Rx:" +msgstr "Rx:" + +#: ../../po/../src/widgets/toolbox.cpp:1568 +msgid "Horizontal radius of rounded corners" +msgstr "Водоравни полупречник заобљених углова" + +#: ../../po/../src/widgets/toolbox.cpp:1578 +msgid "Ry:" +msgstr "Ry:" + +#: ../../po/../src/widgets/toolbox.cpp:1578 +msgid "Vertical radius of rounded corners" +msgstr "Усправни полупречник заобљених углова" + +#: ../../po/../src/widgets/toolbox.cpp:1594 +msgid "Not rounded" +msgstr "Није заобљено" + +#: ../../po/../src/widgets/toolbox.cpp:1596 +msgid "Make corners sharp" +msgstr "Направи угласту линију" + +#: ../../po/../src/widgets/toolbox.cpp:1805 +msgid "Turns:" +msgstr "Трансформација:" + +#: ../../po/../src/widgets/toolbox.cpp:1805 +msgid "Number of revolutions" +msgstr "Број револуција" + +#: ../../po/../src/widgets/toolbox.cpp:1815 +msgid "Divergence:" +msgstr "Одступање:" + +#: ../../po/../src/widgets/toolbox.cpp:1815 +msgid "How much denser/sparser are outer revolutions; 1 = uniform" +msgstr "Колики је скупљач/растављач изван револуције; 1 = непроменљив" + +#: ../../po/../src/widgets/toolbox.cpp:1825 +msgid "Inner radius:" +msgstr "Унутрашњи полупречник:" + +#: ../../po/../src/widgets/toolbox.cpp:1825 +msgid "Radius of the innermost revolution (relative to the spiral size)" +msgstr "" +"Полупречник најмање унутрашње револуције (односи се на величину спирале)" + +#: ../../po/../src/widgets/toolbox.cpp:1957 +msgid "The width of the calligraphic pen (relative to the visible canvas area)" +msgstr "Ширина калиграфске оловке (у односу на видљиву површину платна)" + +#: ../../po/../src/widgets/toolbox.cpp:1967 +msgid "Thinning:" +msgstr "Истањивање:" + +#: ../../po/../src/widgets/toolbox.cpp:1967 +msgid "" +"How much velocity thins the stroke (> 0 makes fast strokes thinner, < 0 " +"makes them broader, 0 makes width independent of velocity)" +msgstr "" +"Колико брзина тањи потез (веће од 0 чини брзе потезе тањим, мање од 0 чини " +"их дебљим. 0 чини дебљину независну од брзине потеза)" + +#: ../../po/../src/widgets/toolbox.cpp:1980 +msgid "Angle:" +msgstr "Угао:" + +#: ../../po/../src/widgets/toolbox.cpp:1980 +msgid "" +"The angle of the pen's nib (in degrees; 0 = horizontal; has no effect if " +"fixation = 0)" +msgstr "Угао врха оловке (у степенима; 0 је водоравно, нема ефекта ако је )" + +#: ../../po/../src/widgets/toolbox.cpp:1990 +msgid "Fixation:" +msgstr "Положај:" + +#: ../../po/../src/widgets/toolbox.cpp:1990 +msgid "" +"How fixed is the pen angle (0 = always perpendicular to stroke direction, 1 " +"= fixed)" +msgstr "" +"Положај угла оловке (0 = увек усправан у односу на правац потеза, 1 = фиксан)" + +#: ../../po/../src/widgets/toolbox.cpp:2003 +msgid "Mass:" +msgstr "Маса:" + +#: ../../po/../src/widgets/toolbox.cpp:2003 +msgid "How much inertia affects the movement of the pen" +msgstr "Колико се инерција одражава на потез оловке" + +#. TRANSLATORS: "drag" means "resistance" here +#: ../../po/../src/widgets/toolbox.cpp:2014 +msgid "Drag:" +msgstr "Отпор:" + +#: ../../po/../src/widgets/toolbox.cpp:2014 +msgid "How much resistance affects the movement of the pen" +msgstr "Колико се отпор одражава на потез оловке" + +#: ../../po/../src/widgets/toolbox.cpp:2034 +msgid "Use the pressure of the input device to alter the width of the pen" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2047 +msgid "Use the tilt of the input device to alter the angle of the pen's nib" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2374 +msgid "Start:" +msgstr "Почетак:" + +#: ../../po/../src/widgets/toolbox.cpp:2374 +msgid "The angle (in degrees) from the horizontal to the arc's start point" +msgstr "Угао (у степенима) од водоравне до лучне почетне тачке" + +#: ../../po/../src/widgets/toolbox.cpp:2384 +msgid "End:" +msgstr "Завршетак:" + +#: ../../po/../src/widgets/toolbox.cpp:2384 +msgid "The angle (in degrees) from the horizontal to the arc's end point" +msgstr "Угао (у степенима) од водоравне до лучне крајње тачке" + +#: ../../po/../src/widgets/toolbox.cpp:2395 +msgid "Open arc" +msgstr "Отворени лук" + +#: ../../po/../src/widgets/toolbox.cpp:2396 +msgid "" +"Switch between arc (unclosed shape) and segment (closed shape with two radii)" +msgstr "" +"Промена између лука (отворене линије) и дела (затворена линија са два угла)" + +#: ../../po/../src/widgets/toolbox.cpp:2415 +msgid "Make whole" +msgstr "Употпуни" + +#: ../../po/../src/widgets/toolbox.cpp:2417 +msgid "Make the shape a whole ellipse, not arc or segment" +msgstr "Затвори линију у елипсу, не као лук или део" + +#: ../../po/../src/widgets/toolbox.cpp:2644 +msgid "" +"When pressed, picks visible color without alpha and when not pressed, picks " +"color including its alpha" +msgstr "" +"Када је притиснуто, узима видљиву боју без провидности а када није " +"притиснут, узима боју укључујући и провидност" + +#: ../../po/../src/widgets/toolbox.cpp:3039 +#, fuzzy +msgid "Make connectors avoid selected objects" +msgstr "Пресецање изабраних објеката" + +#: ../../po/../src/widgets/toolbox.cpp:3043 +#, fuzzy +msgid "Make connectors ignore selected objects" +msgstr "Пресецање изабраних објеката" + +#. +#. 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 : +#: ../share/extensions/addnodes.inx.h:1 +#, fuzzy +msgid "Add Nodes" +msgstr "Чворови" + +#: ../share/extensions/addnodes.inx.h:2 +msgid "Maximum Segment Length" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:1 +msgid "AI Input" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:2 ../share/extensions/ai_output.inx.h:2 +msgid "Adobe Illustrator (*.ai)" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:3 +msgid "Open files saved with Adobe Illustrator" +msgstr "" + +#: ../share/extensions/ai_output.inx.h:1 +#, fuzzy +msgid "AI Output" +msgstr "Излаз" + +#: ../share/extensions/ai_output.inx.h:3 +msgid "Write Adobe Illustrator" +msgstr "" + +#: ../share/extensions/dia.inx.h:1 +msgid "A diagram created with the program Dia" +msgstr "" + +#: ../share/extensions/dia.inx.h:2 +msgid "Dia Diagram (*.dia)" +msgstr "" + +#: ../share/extensions/dia.inx.h:3 +msgid "Dia Input" +msgstr "" + +#: ../share/extensions/dia.inx.h:4 +msgid "" +"In order to import Dia files, Dia itself must be installed. You can get Dia " +"at http://www.gnome.org/projects/dia/" +msgstr "" + +#: ../share/extensions/dia.inx.h:5 +msgid "" +"The dia2svg.sh script should be installed with your Inkscape distribution. " +"If you do not have it, there is likely to be something wrong with your " +"Inkscape installation." +msgstr "" + +#: ../share/extensions/dots.inx.h:1 +#, fuzzy +msgid "Connect the Dots" +msgstr "Аутор" + +#: ../share/extensions/dots.inx.h:2 +#, fuzzy +msgid "Dot Size" +msgstr "Величина" + +#: ../share/extensions/dots.inx.h:3 +#, fuzzy +msgid "Font Size" +msgstr "Величина фонта:" + +#: ../share/extensions/dropshadow.inx.h:1 +msgid "Color of shadow" +msgstr "" + +#: ../share/extensions/dropshadow.inx.h:2 +#, fuzzy +msgid "Dropshadow" +msgstr "Прикажи сенку стране" + +#: ../share/extensions/dxf_input.inx.h:1 +#: ../share/extensions/dxf_output.inx.h:1 +msgid "AutoCAD DXF (*.dxf)" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:2 +msgid "DXF Input" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:3 +msgid "Import AutoCAD's Document Exchange Format" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:4 +msgid "" +"dxf2svg may come with Inkscape, but is also at http://dxf-svg-convert." +"sourceforge.net/" +msgstr "" + +#: ../share/extensions/dxf_output.inx.h:2 +#, fuzzy +msgid "DXF Output" +msgstr "Излаз" + +#: ../share/extensions/dxf_output.inx.h:3 +msgid "DXF file written by pstoedit" +msgstr "" + +#: ../share/extensions/dxf_output.inx.h:4 +msgid "pstoedit must be installed to run see http://www.pstoedit.net/pstoedit" +msgstr "" + +#: ../share/extensions/embedimage.inx.h:1 +#, fuzzy +msgid "Embed Images" +msgstr "Слике" + +#: ../share/extensions/eps_input.inx.h:1 +msgid "EPS Input" +msgstr "" + +#: ../share/extensions/eps_input.inx.h:2 +msgid "Encapsulated Postscript" +msgstr "" + +#: ../share/extensions/eps_input.inx.h:3 +msgid "Encapsulated Postscript (*.eps)" +msgstr "" + +#: ../share/extensions/epsi_output.inx.h:1 +#, fuzzy +msgid "EPSI Output" +msgstr "Излаз" + +#: ../share/extensions/epsi_output.inx.h:2 +msgid "Encapsulated Postscript Interchange (*.epsi)" +msgstr "" + +#: ../share/extensions/epsi_output.inx.h:3 +msgid "Encapsulated Postscript with a thumbnail" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:1 ../share/extensions/ffms.inx.h:1 +#: ../share/extensions/ffset.inx.h:1 ../share/extensions/ffss.inx.h:1 +#, fuzzy +msgid "Bridge Width" +msgstr "Ширина линије" + +#: ../share/extensions/ffmet.inx.h:2 ../share/extensions/ffms.inx.h:2 +msgid "First String Length" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:3 +msgid "FretFind Multi Length ET" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:4 ../share/extensions/ffms.inx.h:4 +#: ../share/extensions/ffset.inx.h:3 ../share/extensions/ffss.inx.h:3 +msgid "Fretboard Edges" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:5 ../share/extensions/ffms.inx.h:5 +msgid "Last String Length" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:6 ../share/extensions/ffms.inx.h:6 +#: ../share/extensions/ffset.inx.h:4 ../share/extensions/ffss.inx.h:4 +#, fuzzy +msgid "Number of Frets" +msgstr "Број редова" + +#: ../share/extensions/ffmet.inx.h:7 ../share/extensions/ffms.inx.h:7 +#: ../share/extensions/ffset.inx.h:5 ../share/extensions/ffss.inx.h:5 +#, fuzzy +msgid "Number of Strings" +msgstr "Број редова" + +#: ../share/extensions/ffmet.inx.h:8 ../share/extensions/ffms.inx.h:8 +#: ../share/extensions/ffset.inx.h:6 ../share/extensions/ffss.inx.h:6 +#, fuzzy +msgid "Nut Width" +msgstr "Ширина:" + +#: ../share/extensions/ffmet.inx.h:9 ../share/extensions/ffms.inx.h:10 +msgid "Perpendicular Distance" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:10 ../share/extensions/ffset.inx.h:7 +msgid "Scale Base (2 for Octave)" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:11 ../share/extensions/ffset.inx.h:9 +msgid "Tones in Scale" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:12 ../share/extensions/ffms.inx.h:12 +#: ../share/extensions/ffset.inx.h:10 ../share/extensions/ffss.inx.h:10 +msgid "px per Unit" +msgstr "" + +#: ../share/extensions/ffms.inx.h:3 +msgid "FretFind Multi Length Scala" +msgstr "" + +#: ../share/extensions/ffms.inx.h:9 ../share/extensions/ffss.inx.h:7 +msgid "Path to Scala *.scl File" +msgstr "" + +#: ../share/extensions/ffms.inx.h:11 +msgid "Tuning (scale step for each string seperated by semicolons)" +msgstr "" + +#: ../share/extensions/ffset.inx.h:2 +msgid "FretFind Single Length ET" +msgstr "" + +#: ../share/extensions/ffset.inx.h:8 ../share/extensions/ffss.inx.h:8 +msgid "Scale Length" +msgstr "" + +#: ../share/extensions/ffss.inx.h:2 +msgid "FretFind Single Length Scala" +msgstr "" + +#: ../share/extensions/ffss.inx.h:9 +msgid "Tuning (Scale step for each string seperated by semicolons)" +msgstr "" + +#: ../share/extensions/handles.inx.h:1 +#, fuzzy +msgid "Draw Handles" +msgstr "Исцртавање линије слободном руком" + +#: ../share/extensions/interp.inx.h:1 +#, fuzzy +msgid "Duplicate Endpaths" +msgstr "Удвостручи чвор" + +#: ../share/extensions/interp.inx.h:2 +#, fuzzy +msgid "Exponent" +msgstr "Извези" + +#: ../share/extensions/interp.inx.h:3 +msgid "Interpolate" +msgstr "" + +#: ../share/extensions/interp.inx.h:4 +msgid "Interpolate Style (Experimental)" +msgstr "" + +#: ../share/extensions/interp.inx.h:5 +msgid "Interpolation Method" +msgstr "" + +#: ../share/extensions/interp.inx.h:6 +msgid "Interpolation Steps" +msgstr "" + +#: ../share/extensions/kochify.inx.h:1 +msgid "Kochify" +msgstr "" + +#: ../share/extensions/kochify_load.inx.h:1 +msgid "Kochify (Load)" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:1 +#, fuzzy +msgid "Angle" +msgstr "Угао:" + +#: ../share/extensions/lindenmayer.inx.h:2 +msgid "Axiom" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:3 +#, fuzzy +msgid "Lindenmayer" +msgstr "Преименуј слој" + +#: ../share/extensions/lindenmayer.inx.h:4 +msgid "Order" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:5 +#, fuzzy +msgid "Rules" +msgstr "_Лењири" + +#: ../share/extensions/lindenmayer.inx.h:6 +#, fuzzy +msgid "Step" +msgstr "Кораци" + +#: ../share/extensions/motion.inx.h:1 +#, fuzzy +msgid "Direction" +msgstr "Опис" + +#: ../share/extensions/motion.inx.h:2 +#, fuzzy +msgid "Magnitude" +msgstr "Магента" + +#: ../share/extensions/motion.inx.h:3 +#, fuzzy +msgid "Motion" +msgstr "_Ротација" + +#: ../share/extensions/pdf_output.inx.h:1 +msgid "Adobe PDF (*.pdf)" +msgstr "" + +#: ../share/extensions/pdf_output.inx.h:2 +msgid "Adobe Portable Document Format" +msgstr "" + +#: ../share/extensions/pdf_output.inx.h:3 +#, fuzzy +msgid "PDF Output" +msgstr "Излаз" + +#: ../share/extensions/ps_input.inx.h:1 +#, fuzzy +msgid "Postscript" +msgstr "Усправно" + +#: ../share/extensions/ps_input.inx.h:2 +msgid "Postscript (*.ps)" +msgstr "" + +#: ../share/extensions/ps_input.inx.h:3 +msgid "Postscript Input" +msgstr "" + +#: ../share/extensions/radiusrand.inx.h:1 +#, fuzzy +msgid "Radius" +msgstr "_Издигни" + +#: ../share/extensions/radiusrand.inx.h:2 +#, fuzzy +msgid "Radius Randomize" +msgstr "Насумично:" + +#: ../share/extensions/radiusrand.inx.h:3 +msgid "Randomize Control Points" +msgstr "" + +#: ../share/extensions/radiusrand.inx.h:4 +#, fuzzy +msgid "Randomize Nodes" +msgstr "Насумично:" + +#: ../share/extensions/rtree.inx.h:1 +#, fuzzy +msgid "Initial Size" +msgstr "Величина битмапе" + +#: ../share/extensions/rtree.inx.h:2 +msgid "Minimum Size" +msgstr "" + +#: ../share/extensions/rtree.inx.h:3 +#, fuzzy +msgid "Random Tree" +msgstr "Насумично:" + +#: ../share/extensions/sk_input.inx.h:1 +msgid "A diagram created with the program Sketch" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:2 +msgid "Sketch Diagram (*.sk)" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:3 +msgid "Sketch Input" +msgstr "" + +#: ../share/extensions/straightseg.inx.h:1 +msgid "Behavior" +msgstr "" + +#: ../share/extensions/straightseg.inx.h:3 +msgid "Segment Straightener" +msgstr "" + +#: ../share/extensions/summersnight.inx.h:1 +msgid "Summer's Night" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:1 +#: ../share/extensions/svgz_output.inx.h:1 +msgid "Compressed Inkscape SVG (*.svgz)" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:2 +#: ../share/extensions/svgz_output.inx.h:2 +msgid "Inkscape's native file format compressed with GZip" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:3 +msgid "SVGZ Input" +msgstr "" + +#: ../share/extensions/svgz_output.inx.h:3 +#, fuzzy +msgid "SVGZ Output" +msgstr "Излаз" + +#: ../share/extensions/txt2svg.inx.h:1 +msgid "ASCII Text" +msgstr "" + +#: ../share/extensions/txt2svg.inx.h:2 +msgid "Text File (*.txt)" +msgstr "" + +#: ../share/extensions/txt2svg.inx.h:3 +msgid "Text Input" +msgstr "" + +#: ../share/extensions/wavy.inx.h:1 +msgid "Calculate first derivative numerically" +msgstr "" + +#: ../share/extensions/wavy.inx.h:2 +msgid "First derivative" +msgstr "" + +#: ../share/extensions/wavy.inx.h:3 +msgid "Function" +msgstr "" + +#: ../share/extensions/wavy.inx.h:4 +msgid "Function Plotter" +msgstr "" + +#: ../share/extensions/wavy.inx.h:5 +msgid "Nodes per period" +msgstr "" + +#: ../share/extensions/wavy.inx.h:6 +msgid "Periods (2*Pi each)" +msgstr "" + +#: ../share/extensions/whirl.inx.h:1 +msgid "Amount of Whirl" +msgstr "" + +#: ../share/extensions/whirl.inx.h:2 +#, fuzzy +msgid "Center X" +msgstr "Централно поравнање" + +#: ../share/extensions/whirl.inx.h:3 +#, fuzzy +msgid "Center Y" +msgstr "Централно поравнање" + +#: ../share/extensions/whirl.inx.h:4 +#, fuzzy +msgid "Direction of Rotation" +msgstr "Постави изабране објекте иза осталих" + +#: ../share/extensions/whirl.inx.h:5 +msgid "Whirl" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:1 +msgid "A popular graphics file format for clipart" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:2 +msgid "Windows Metafile (*.wmf)" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:3 +msgid "Windows Metafile Input" +msgstr "" + +#~ msgid "Custom canvas" +#~ msgstr "Прилагођено платно" + +#~ msgid "Current style" +#~ msgstr "Тренутни стил" + +#~ msgid "" +#~ "Current style is updated every time you change the style of any object " +#~ "(its fill, stroke, transparency, etc.)" +#~ msgstr "" +#~ "Тренутни стил се освежава сваки пут када промените стил неког објекта " +#~ "(његова попуна, боја ивичне линије, провидност и др.)" + +#~ msgid "Arrange Objects" +#~ msgstr "Разврстај објекте" + +#~ msgid "deg" +#~ msgstr "степени" + +#~ msgid "" +#~ "%s is not a valid preferences file.\n" +#~ "%s" +#~ msgstr "" +#~ "%s није исправна датотека подешавања.\n" +#~ "%s" + +#~ msgid "" +#~ "Inkscape will run with default settings.\n" +#~ "New settings will not be saved." +#~ msgstr "" +#~ "ИнкСкејп ће бити покренут са подразумеваним подешавањима.\n" +#~ "Нова подешавања неће бити сачувана." + +#, fuzzy +#~ msgid "_Credits" +#~ msgstr "Захвале" + +#~ msgid "Grab sensitivity" +#~ msgstr "Осетљивост хватања" + +#~ msgid "Click/drag threshold" +#~ msgstr "Праг клика/помераја" + +#~ msgid "Mouse wheel scrolls by" +#~ msgstr "Точкић миша помера за" + +#~ msgid "Scroll by" +#~ msgstr "Померај за" + +#~ msgid "Acceleration" +#~ msgstr "Убрзање" + +#~ msgid "Speed" +#~ msgstr "Брзина" + +#~ msgid "Threshold" +#~ msgstr "Праг толеранције" + +#~ msgid "Arrow keys move by" +#~ msgstr "Стралице померају за" + +#~ msgid "> and < scale by" +#~ msgstr "„>“ и „<“ мењају величину за" + +#~ msgid "Inset/Outset by" +#~ msgstr "Скупљање/ширење за" + +#~ msgid "Rotation snaps every" +#~ msgstr "Ротација пријања на сваких" + +#~ msgid "Zoom in/out by" +#~ msgstr "Увећавање/умањење за" + +#~ msgid "Transform" +#~ msgstr "Трансформација" + +#~ msgid "Flip selection horizontally" +#~ msgstr "Изврће избор као у огледалу водоравно" + +#~ msgid "Flip selection vertically" +#~ msgstr "Изврће избор као у огледалу усправно" + +#, fuzzy +#~ msgid "Could not read next message due to I/O error (error: %s)!" +#~ msgstr "Не могу да направим дневник грешака проширења „%s“" + +#~ msgid "Open one of the recently visited documents" +#~ msgstr "Отварање једног од последње отвараних докумената" + +#~ msgid "" +#~ "Show or hide parts of the document window (differently for normal and " +#~ "fullscreen modes)" +#~ msgstr "" +#~ "Приказивање или скривање делова прозора документа (разликују се нормалан " +#~ "и режим преко целог екрана)" + +#~ msgid "Interactive Inkscape tutorials" +#~ msgstr "Интерактивне ИнкСкејп вежбе" + +#~ msgid "Edit" +#~ msgstr "Уреди" + +#~ msgid "Add" +#~ msgstr "Додај" diff --git a/po/sr@Latn.po b/po/sr@Latn.po new file mode 100644 index 000000000..ea6008f10 --- /dev/null +++ b/po/sr@Latn.po @@ -0,0 +1,9541 @@ +# Serbian translation of inkscape +# Courtesy of Prevod.org team (http://prevod.org/) -- 2004, 2005 +# +# This file is distributed under the same license as the inkscape package. +# +# Maintainer: Aleksandar UroÅ¡ević +# +msgid "" +msgstr "" +"Project-Id-Version: Inkscape 0.42\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2005-12-04 11:51-0800\n" +"PO-Revision-Date: 2005-07-08 01:23+0200\n" +"Last-Translator: Aleksandar UroÅ¡ević \n" +"Language-Team: Serbian (sr) \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: ../inkscape.desktop.in.h:1 +msgid "Create and edit Scalable Vector Graphics images" +msgstr "Pravljenje i uređivanje SVG vektorskih slika" + +#: ../inkscape.desktop.in.h:2 +msgid "Inkscape SVG Vector Illustrator" +msgstr "Inkscape — program za vektorsko crtanje" + +#: ../../po/../src/arc-context.cpp:350 +msgid "" +"Ctrl: make circle or integer-ratio ellipse, snap arc/segment angle" +msgstr "" +"Ctrl: pravi kružnicu ili proporcionalnu elipsu, prijanja na utao/luk" + +#: ../../po/../src/arc-context.cpp:351 ../../po/../src/rect-context.cpp:388 +msgid "Shift: draw around the starting point" +msgstr "Shift: iscrtava objekat sa centrom u početnoj tački" + +#: ../../po/../src/arc-context.cpp:413 +#: ../../po/../src/connector-context.cpp:493 +#: ../../po/../src/dyna-draw-context.cpp:506 +#: ../../po/../src/pen-context.cpp:329 ../../po/../src/pencil-context.cpp:208 +#: ../../po/../src/rect-context.cpp:452 ../../po/../src/spiral-context.cpp:421 +#: ../../po/../src/star-context.cpp:427 +msgid "Current layer is hidden. Unhide it to be able to draw on it." +msgstr "" +"Aktivni sloj je sakriven. Ukinite sakrivanje kako bi mogli da crtate " +"na njemu." + +#: ../../po/../src/arc-context.cpp:417 +#: ../../po/../src/connector-context.cpp:497 +#: ../../po/../src/dyna-draw-context.cpp:510 +#: ../../po/../src/pen-context.cpp:336 ../../po/../src/pencil-context.cpp:212 +#: ../../po/../src/rect-context.cpp:456 ../../po/../src/spiral-context.cpp:426 +#: ../../po/../src/star-context.cpp:431 +msgid "Current layer is locked. Unlock it to be able to draw on it." +msgstr "" +"Aktivni sloj je zaključan. Otključajte ga kako bi mogli da crtte na " +"njemu." + +#: ../../po/../src/arc-context.cpp:496 +#, fuzzy, c-format +msgid "" +"Ellipse: %s × %s; with Ctrl to make circle or integer-" +"ratio ellipse; with Shift to draw around the starting point" +msgstr "" +"Elipsa: %s x %s; pritisnite Ctrl za iscrtavanje kružnice ili " +"proporcionalne elipse; pritisnite Shift za iscrtavanje oko početne " +"tačke" + +#: ../../po/../src/connector-context.cpp:518 +#, fuzzy +msgid "Creating new connector" +msgstr "Pravljenje nove krive" + +#: ../../po/../src/connector-context.cpp:939 +#, fuzzy +msgid "Finishing connector" +msgstr "ZavrÅ¡avanje olovke" + +#: ../../po/../src/connector-context.cpp:1108 +msgid "Connection point: click or drag to create a new connector" +msgstr "" + +#: ../../po/../src/connector-context.cpp:1185 +msgid "Connector endpoint: drag to reroute or connect to new shapes" +msgstr "" + +#: ../../po/../src/connector-context.cpp:1278 +#, fuzzy +msgid "Select at least one non-connector object." +msgstr "Izaberite najmanje dva objekta za grupisanje." + +#: ../../po/../src/desktop-events.cpp:238 +#, c-format +msgid "%s at %s" +msgstr "%s na %s" + +#. TRANSLATORS: This string appears when double-clicking on a guide. +#. This is the distance by which the guide is to be moved. +#: ../../po/../src/desktop-events.cpp:277 +msgid " relative by " +msgstr " u odnosu na " + +#. TRANSLATORS: This string appears when double-clicking on a guide. +#. This is the target location where the guide is to be moved. +#: ../../po/../src/desktop-events.cpp:282 +#: ../../po/../src/desktop-events.cpp:395 +msgid " absolute to " +msgstr " apsolutno na " + +#. create dialog +#: ../../po/../src/desktop-events.cpp:348 +msgid "Guideline" +msgstr "Vođice" + +#: ../../po/../src/desktop-events.cpp:432 +#, c-format +msgid "Move %s" +msgstr "Pomeri %s" + +#: ../../po/../src/desktop.cpp:678 +msgid "No previous zoom." +msgstr "Nema viÅ¡e umanjenja." + +#: ../../po/../src/desktop.cpp:703 +msgid "No next zoom." +msgstr "Nema viÅ¡e uvećanja." + +#: ../../po/../src/dialogs/clonetiler.cpp:182 +msgid "Nothing selected." +msgstr "NiÅ¡ta nije izabrano." + +#: ../../po/../src/dialogs/clonetiler.cpp:188 +msgid "More than one object selected." +msgstr "Izabrano je viÅ¡e od jednog objekta." + +#: ../../po/../src/dialogs/clonetiler.cpp:195 +#, c-format +msgid "Object has %d tiled clones." +msgstr "Objekat ima %d popločanih klonova." + +#: ../../po/../src/dialogs/clonetiler.cpp:200 +msgid "Object has no tiled clones." +msgstr "Objekat nema popločane klonove" + +#: ../../po/../src/dialogs/clonetiler.cpp:865 +msgid "Select one object whose tiled clones to unclump." +msgstr "Izaberite objekat sa naslaganim klonovima za razdvajanje." + +#: ../../po/../src/dialogs/clonetiler.cpp:916 +msgid "Select one object whose tiled clones to remove." +msgstr "Izaberite objekat sa naslaganim klonovima za uklanjanje." + +#: ../../po/../src/dialogs/clonetiler.cpp:984 +#: ../../po/../src/selection-chemistry.cpp:1774 +msgid "Select an object to clone." +msgstr "Izaberite objekat za kloniranje." + +#: ../../po/../src/dialogs/clonetiler.cpp:990 +#: ../../po/../src/selection-chemistry.cpp:1780 +msgid "" +"If you want to clone several objects, group them and clone the " +"group." +msgstr "" +"Ako želite da klonirate viÅ¡e objekata, grupiÅ¡ite ih pa klonirajte " +"grupu." + +#: ../../po/../src/dialogs/clonetiler.cpp:1484 +msgid "Per row:" +msgstr "Po redu:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1497 +msgid "Per column:" +msgstr "Po koloni:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1505 +msgid "Randomize:" +msgstr "Nasumično:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1656 +msgid "_Symmetry" +msgstr "_Simetrija" + +#. TRANSLATORS: For the following 17 symmetry groups, see +#. * http://www.bib.ulb.ac.be/coursmath/doc/17.htm (visual examples); +#. * http://www.clarku.edu/~djoyce/wallpaper/seventeen.html (English vocabulary); or +#. * http://membres.lycos.fr/villemingerard/Geometri/Sym1D.htm (French vocabulary). +#. +#: ../../po/../src/dialogs/clonetiler.cpp:1664 +msgid "Select one of the 17 symmetry groups for the tiling" +msgstr "Izaberite jednu od 17 simetričnih grupa za popločavanje" + +#. TRANSLATORS: "translation" means "shift" / "displacement" here. +#: ../../po/../src/dialogs/clonetiler.cpp:1675 +msgid "P1: simple translation" +msgstr "P1: jednostavno premeÅ¡tanje" + +#: ../../po/../src/dialogs/clonetiler.cpp:1676 +msgid "P2: 180° rotation" +msgstr "P2: 180° rotacija" + +#: ../../po/../src/dialogs/clonetiler.cpp:1677 +msgid "PM: reflection" +msgstr "PM: refleksija" + +#. TRANSLATORS: "glide reflection" is a reflection and a translation combined. +#. For more info, see http://mathforum.org/sum95/suzanne/symsusan.html +#: ../../po/../src/dialogs/clonetiler.cpp:1680 +msgid "PG: glide reflection" +msgstr "PG: refleksija sa pomerajem" + +#: ../../po/../src/dialogs/clonetiler.cpp:1681 +msgid "CM: reflection + glide reflection" +msgstr "CM: refleksija + refleksija sa pomerajem" + +#: ../../po/../src/dialogs/clonetiler.cpp:1682 +msgid "PMM: reflection + reflection" +msgstr "PMM: refleksija + refleksija" + +#: ../../po/../src/dialogs/clonetiler.cpp:1683 +msgid "PMG: reflection + 180° rotation" +msgstr "PMG: refleksija + 180° rotacija" + +#: ../../po/../src/dialogs/clonetiler.cpp:1684 +msgid "PGG: glide reflection + 180° rotation" +msgstr "PGG: refleksija sa pomerajem + 180° rotacija" + +#: ../../po/../src/dialogs/clonetiler.cpp:1685 +msgid "CMM: reflection + reflection + 180° rotation" +msgstr "CMM: refleksija + refleksija + 180° rotacija" + +#: ../../po/../src/dialogs/clonetiler.cpp:1686 +msgid "P4: 90° rotation" +msgstr "P4: 90° rotacija" + +#: ../../po/../src/dialogs/clonetiler.cpp:1687 +msgid "P4M: 90° rotation + 45° reflection" +msgstr "P4M: 90° rotacija + 45° refleksija" + +#: ../../po/../src/dialogs/clonetiler.cpp:1688 +msgid "P4G: 90° rotation + 90° reflection" +msgstr "P4G: 90° rotacija + 90° refleksija" + +#: ../../po/../src/dialogs/clonetiler.cpp:1689 +msgid "P3: 120° rotation" +msgstr "P3: 120° rotacija" + +#: ../../po/../src/dialogs/clonetiler.cpp:1690 +msgid "P31M: reflection + 120° rotation, dense" +msgstr "P31M: refleksija + 120° rotacija, zgusnuto" + +#: ../../po/../src/dialogs/clonetiler.cpp:1691 +msgid "P3M1: reflection + 120° rotation, sparse" +msgstr "P3M1: refleksija + 120° rotacija, rastegnuto" + +#: ../../po/../src/dialogs/clonetiler.cpp:1692 +msgid "P6: 60° rotation" +msgstr "P6: 60° rotacija" + +#: ../../po/../src/dialogs/clonetiler.cpp:1693 +msgid "P6M: reflection + 60° rotation" +msgstr "P6M: refleksija + 60° rotacija" + +#: ../../po/../src/dialogs/clonetiler.cpp:1721 +msgid "S_hift" +msgstr "_Pomeraj" + +#. TRANSLATORS: "shift" means: the tiles will be shifted (offset) horizontally by this amount +#: ../../po/../src/dialogs/clonetiler.cpp:1731 +#, no-c-format +msgid "Shift X:" +msgstr "Pomeraj X:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1739 +#, no-c-format +msgid "Horizontal shift per row (in % of tile width)" +msgstr "Vodoravni pomeraj reda (u % Å¡irine objekta)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1747 +#, no-c-format +msgid "Horizontal shift per column (in % of tile width)" +msgstr "Vodoravni pomeraj kolone (u % Å¡irine objekta)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1754 +msgid "Randomize the horizontal shift by this percentage" +msgstr "Nasumični vodoravni pomeraj za ovaj procenat" + +#. TRANSLATORS: "shift" means: the tiles will be shifted (offset) vertically by this amount +#: ../../po/../src/dialogs/clonetiler.cpp:1764 +#, no-c-format +msgid "Shift Y:" +msgstr "Pomeraj Y:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1772 +#, no-c-format +msgid "Vertical shift per row (in % of tile height)" +msgstr "Uspravni pomeraj reda (u % visine objekta)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1780 +#, no-c-format +msgid "Vertical shift per column (in % of tile height)" +msgstr "Uspravni pomeraj kolone (u % visine objekta)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1787 +msgid "Randomize the vertical shift by this percentage" +msgstr "Nasumični uspravni pomeraj za ovaj procenat" + +#: ../../po/../src/dialogs/clonetiler.cpp:1795 +msgid "Exponent:" +msgstr "Eksponent:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1802 +msgid "Whether rows are spaced evenly (1), converge (<1) or diverge (>1)" +msgstr "" +"Da li su redovi razdvojeni podjednako (1), spojeno (<1) ili razdvojeno (>1)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1809 +msgid "Whether columns are spaced evenly (1), converge (<1) or diverge (>1)" +msgstr "" +"Da li su kolone razdvojene podjednako (1), spojeno (<1) ili razdvojeno (>1)" + +#. TRANSLATORS: "Alternate" is a verb here +#: ../../po/../src/dialogs/clonetiler.cpp:1817 +#: ../../po/../src/dialogs/clonetiler.cpp:1907 +#: ../../po/../src/dialogs/clonetiler.cpp:1966 +#: ../../po/../src/dialogs/clonetiler.cpp:2022 +#: ../../po/../src/dialogs/clonetiler.cpp:2153 +msgid "Alternate:" +msgstr "Izvrtanje:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1823 +msgid "Alternate the sign of shifts for each row" +msgstr "Naizmenični pomeraj (plus/minus) za svaki red" + +#: ../../po/../src/dialogs/clonetiler.cpp:1828 +msgid "Alternate the sign of shifts for each column" +msgstr "Naizmenični pomeraj (plus/minus) za svaku kolonu" + +#: ../../po/../src/dialogs/clonetiler.cpp:1837 +msgid "Sc_ale" +msgstr "Ra_zmera" + +#: ../../po/../src/dialogs/clonetiler.cpp:1845 +msgid "Scale X:" +msgstr "Razmera X" + +#: ../../po/../src/dialogs/clonetiler.cpp:1853 +#, no-c-format +msgid "Horizontal scale per row (in % of tile width)" +msgstr "Vodoravna razmera po redu (u % Å¡irine objekta)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1861 +#, no-c-format +msgid "Horizontal scale per column (in % of tile width)" +msgstr "Vodoravna razmera po koloni (u % Å¡irine objekta)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1868 +msgid "Randomize the horizontal scale by this percentage" +msgstr "Nasumična vodoravna razmera za ovaj procenat" + +#: ../../po/../src/dialogs/clonetiler.cpp:1876 +msgid "Scale Y:" +msgstr "Razmera Y:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1884 +#, no-c-format +msgid "Vertical scale per row (in % of tile height)" +msgstr "Uspravna razmera po redu (u % visine objekta)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1892 +#, no-c-format +msgid "Vertical scale per column (in % of tile height)" +msgstr "Uspravna razmera po koloni (u % visine objekta)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1899 +msgid "Randomize the vertical scale by this percentage" +msgstr "Nasumična uspravna razmera za ovaj procenat" + +#: ../../po/../src/dialogs/clonetiler.cpp:1913 +msgid "Alternate the sign of scales for each row" +msgstr "Naizmenična razmera svakog reda" + +#: ../../po/../src/dialogs/clonetiler.cpp:1918 +msgid "Alternate the sign of scales for each column" +msgstr "Naizmenični razmera svake kolone" + +#: ../../po/../src/dialogs/clonetiler.cpp:1927 +msgid "_Rotation" +msgstr "_Rotacija" + +#: ../../po/../src/dialogs/clonetiler.cpp:1935 +msgid "Angle:" +msgstr "Ugao:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1943 +#, no-c-format +msgid "Rotate tiles by this angle for each row" +msgstr "Rotacija objekta za ovaj ugao u svakom redu" + +#: ../../po/../src/dialogs/clonetiler.cpp:1951 +#, no-c-format +msgid "Rotate tiles by this angle for each column" +msgstr "Rotacija objekta za ovaj ugao u svakoj koloni" + +#: ../../po/../src/dialogs/clonetiler.cpp:1958 +msgid "Randomize the rotation angle by this percentage" +msgstr "Nasumičan ugao rotacije za ovaj procenat" + +#: ../../po/../src/dialogs/clonetiler.cpp:1972 +msgid "Alternate the rotation direction for each row" +msgstr "Naizmeničan smer rotacije u svakom redu" + +#: ../../po/../src/dialogs/clonetiler.cpp:1977 +msgid "Alternate the rotation direction for each column" +msgstr "Naizmeničan smer rotacije u svakoj koloni" + +#: ../../po/../src/dialogs/clonetiler.cpp:1985 +msgid "_Opacity" +msgstr "Pro_vidnost" + +#: ../../po/../src/dialogs/clonetiler.cpp:1993 +msgid "Fade out:" +msgstr "Isčezavanje:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2000 +msgid "Decrease tile opacity by this percentage for each row" +msgstr "Povećavanje providnosti objekta za ovaj procenat u svakom redu" + +#: ../../po/../src/dialogs/clonetiler.cpp:2007 +msgid "Decrease tile opacity by this percentage for each column" +msgstr "Povećavanje providnosti objekta za ovaj procenat u svakoj koloni" + +#: ../../po/../src/dialogs/clonetiler.cpp:2014 +msgid "Randomize the tile opacity by this percentage" +msgstr "Proizvoljna providnost objekta za ovaj procenat" + +#: ../../po/../src/dialogs/clonetiler.cpp:2028 +msgid "Alternate the sign of opacity change for each row" +msgstr "Naizmenična providnost u svakom redu" + +#: ../../po/../src/dialogs/clonetiler.cpp:2033 +msgid "Alternate the sign of opacity change for each column" +msgstr "Naizmenična providnost u svakoj koloni" + +#: ../../po/../src/dialogs/clonetiler.cpp:2041 +msgid "Co_lor" +msgstr "Bo_ja" + +#: ../../po/../src/dialogs/clonetiler.cpp:2046 +msgid "Initial color: " +msgstr "Početna boja:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2050 +msgid "Initial color of tiled clones" +msgstr "Početna boja pojedinačnog klona" + +#: ../../po/../src/dialogs/clonetiler.cpp:2050 +msgid "" +"Initial color for clones (works only if the original has unset fill or " +"stroke)" +msgstr "" +"Početna boja za klonove (ima efekta samo ako original nema postavljenu " +"popunu i boju ivične linije)" + +#: ../../po/../src/dialogs/clonetiler.cpp:2065 +msgid "H:" +msgstr "N:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2072 +msgid "Change the tile hue by this percentage for each row" +msgstr "Promena nijanse objekta za ovaj procenat u svakom redu" + +#: ../../po/../src/dialogs/clonetiler.cpp:2079 +msgid "Change the tile hue by this percentage for each column" +msgstr "Promena nijanse objekta za ovaj procenat u svakoj koloni" + +#: ../../po/../src/dialogs/clonetiler.cpp:2086 +msgid "Randomize the tile hue by this percentage" +msgstr "Nasumična nijansa objekta za ovaj procenat" + +#: ../../po/../src/dialogs/clonetiler.cpp:2095 +msgid "S:" +msgstr "Z" + +#: ../../po/../src/dialogs/clonetiler.cpp:2102 +msgid "Change the color saturation by this percentage for each row" +msgstr "Promena zasićenosti boje za ovaj procenat u svakom redu" + +#: ../../po/../src/dialogs/clonetiler.cpp:2109 +msgid "Change the color saturation by this percentage for each column" +msgstr "Promena zasićenosti boje za ovaj procenat u svakoj koloni" + +#: ../../po/../src/dialogs/clonetiler.cpp:2116 +msgid "Randomize the color saturation by this percentage" +msgstr "Nasumična zasićenost boje za ovaj procenat" + +#: ../../po/../src/dialogs/clonetiler.cpp:2124 +msgid "L:" +msgstr "O:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2131 +msgid "Change the color lightness by this percentage for each row" +msgstr "Promena osvetljenosti boje za ovaj procenat u svakom redu" + +#: ../../po/../src/dialogs/clonetiler.cpp:2138 +msgid "Change the color lightness by this percentage for each column" +msgstr "Promena osvetljenosti boje za ovaj procenat u svakoj koloni" + +#: ../../po/../src/dialogs/clonetiler.cpp:2145 +msgid "Randomize the color lightness by this percentage" +msgstr "Nasumična osvetljenost boje za ovaj procenat" + +#: ../../po/../src/dialogs/clonetiler.cpp:2159 +msgid "Alternate the sign of color changes for each row" +msgstr "Naizmenična boja u svakom redu" + +#: ../../po/../src/dialogs/clonetiler.cpp:2164 +msgid "Alternate the sign of color changes for each column" +msgstr "Naizmenična obja u svakoj koloni" + +#: ../../po/../src/dialogs/clonetiler.cpp:2172 +msgid "_Trace" +msgstr "_Precrtavanje" + +#: ../../po/../src/dialogs/clonetiler.cpp:2179 +msgid "Trace the drawing under the tiles" +msgstr "Precrtavanje crteža ispod popločanih objekata" + +#: ../../po/../src/dialogs/clonetiler.cpp:2183 +msgid "" +"For each clone, pick a value from the drawing in that clone's location and " +"apply it to the clone" +msgstr "" +"Za svaki klon, uzima se vrednost sa crteža sa povrÅ¡ine klona i primenjuje se " +"na klon" + +#: ../../po/../src/dialogs/clonetiler.cpp:2197 +msgid "1. Pick from the drawing:" +msgstr "1. Uzmi sa crteža:" + +#. ----Hbox2 +#: ../../po/../src/dialogs/clonetiler.cpp:2208 +#: ../../po/../src/dialogs/clonetiler.cpp:2355 +#: ../../po/../src/ui/dialog/tracedialog.cpp:445 +msgid "Color" +msgstr "Boju" + +#: ../../po/../src/dialogs/clonetiler.cpp:2209 +msgid "Pick the visible color and opacity" +msgstr "Uzima vidljivu boju i providnost" + +#: ../../po/../src/dialogs/clonetiler.cpp:2216 +#: ../../po/../src/dialogs/clonetiler.cpp:2365 +#: ../share/extensions/dropshadow.inx.h:3 +msgid "Opacity" +msgstr "Providnost" + +#: ../../po/../src/dialogs/clonetiler.cpp:2217 +msgid "Pick the total accumulated opacity" +msgstr "Uzima ukupnu nagomilanu providnost" + +#: ../../po/../src/dialogs/clonetiler.cpp:2224 +msgid "R" +msgstr "C" + +#: ../../po/../src/dialogs/clonetiler.cpp:2225 +msgid "Pick the Red component of the color" +msgstr "Uzmia crvenu komponentu boje" + +#: ../../po/../src/dialogs/clonetiler.cpp:2232 +msgid "G" +msgstr "Z" + +#: ../../po/../src/dialogs/clonetiler.cpp:2233 +msgid "Pick the Green component of the color" +msgstr "Uzima zelenu komponentu boje" + +#: ../../po/../src/dialogs/clonetiler.cpp:2240 +msgid "B" +msgstr "P" + +#: ../../po/../src/dialogs/clonetiler.cpp:2241 +msgid "Pick the Blue component of the color" +msgstr "Uzima plavu komponentu boje" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2250 +msgid "clonetiler|H" +msgstr "Klonirana pločica|N" + +#: ../../po/../src/dialogs/clonetiler.cpp:2251 +msgid "Pick the hue of the color" +msgstr "Uzima nijansu boje" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2260 +msgid "clonetiler|S" +msgstr "Klonirana pločica|Z" + +#: ../../po/../src/dialogs/clonetiler.cpp:2261 +msgid "Pick the saturation of the color" +msgstr "Uzima zasićenost boje" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2270 +msgid "clonetiler|L" +msgstr "Klonirana pločica|O" + +#: ../../po/../src/dialogs/clonetiler.cpp:2271 +msgid "Pick the lightness of the color" +msgstr "Uzima osvetljenost boje" + +#: ../../po/../src/dialogs/clonetiler.cpp:2281 +msgid "2. Tweak the picked value:" +msgstr "2. PodeÅ¡avanje uzete vrednosti" + +#: ../../po/../src/dialogs/clonetiler.cpp:2291 +msgid "Gamma-correct:" +msgstr "Korekcija game:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2296 +msgid "Shift the mid-range of the picked value upwards (>0) or downwards (<0)" +msgstr "Pomera srednji nivo uzete vrednosti naviÅ¡e (>0) ili nadole (<0)" + +#: ../../po/../src/dialogs/clonetiler.cpp:2303 +msgid "Randomize:" +msgstr "Nasumično:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2308 +msgid "Randomize the picked value by this percentage" +msgstr "Nasumično uzimanje vrednosti za ovaj procenat" + +#: ../../po/../src/dialogs/clonetiler.cpp:2315 +msgid "Invert:" +msgstr "Preokretanje:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2319 +msgid "Invert the picked value" +msgstr "Preokretanje uzete vrednosti" + +#: ../../po/../src/dialogs/clonetiler.cpp:2325 +msgid "3. Apply the value to the clones':" +msgstr "3. Primena vrednosti na klonove:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2335 +msgid "Presence" +msgstr "PonaÅ¡anje" + +#: ../../po/../src/dialogs/clonetiler.cpp:2338 +msgid "" +"Each clone is created with the probability determined by the picked value in " +"that point" +msgstr "" +"Svaki klon je napravljen sa osobinama proračunatim iz uzete vrednosti u toj " +"tački" + +#: ../../po/../src/dialogs/clonetiler.cpp:2345 +msgid "Size" +msgstr "Veličina" + +#: ../../po/../src/dialogs/clonetiler.cpp:2348 +msgid "Each clone's size is determined by the picked value in that point" +msgstr "" +"Svaki klon ima veličinu proračunatu na osnovu uzete vrednosti u toj tački" + +#: ../../po/../src/dialogs/clonetiler.cpp:2358 +msgid "" +"Each clone is painted by the picked color (the original must have unset fill " +"or stroke)" +msgstr "" +"Svaki klon se boji uzetom bojom (original ne sme da ima postavljenu popunu " +"ili boju ivične linije)" + +#: ../../po/../src/dialogs/clonetiler.cpp:2368 +msgid "Each clone's opacity is determined by the picked value in that point" +msgstr "" +"Providnost svakog klona se računa na osnovu uzete vrednosti u toj tački" + +#: ../../po/../src/dialogs/clonetiler.cpp:2395 +msgid "How many rows in the tiling" +msgstr "Koliko će redova imati popločana povrÅ¡ina" + +#: ../../po/../src/dialogs/clonetiler.cpp:2415 +msgid "How many columns in the tiling" +msgstr "Koliko će kolona imati popločana povrÅ¡ina" + +#: ../../po/../src/dialogs/clonetiler.cpp:2445 +msgid "Width of the rectangle to be filled" +msgstr "Å irina povrÅ¡ine koja će se popuniti" + +#: ../../po/../src/dialogs/clonetiler.cpp:2470 +msgid "Height of the rectangle to be filled" +msgstr "Visina povrÅ¡ine koja će se popuniti" + +#: ../../po/../src/dialogs/clonetiler.cpp:2485 +msgid "Rows, columns: " +msgstr "Redova, kolona: " + +#: ../../po/../src/dialogs/clonetiler.cpp:2486 +msgid "Create the specified number of rows and columns" +msgstr "Napravi određeni broj redova i kolona" + +#: ../../po/../src/dialogs/clonetiler.cpp:2495 +msgid "Width, height: " +msgstr "Å irina, visina: " + +#: ../../po/../src/dialogs/clonetiler.cpp:2496 +msgid "Fill the specified width and height with the tiling" +msgstr "Popuni određenu Å¡irinu i visinu popločavanjem" + +#: ../../po/../src/dialogs/clonetiler.cpp:2512 +msgid "Use saved size and position of the tile" +msgstr "Koristi sačuvanu veličinu i položaj objekta" + +#: ../../po/../src/dialogs/clonetiler.cpp:2515 +msgid "" +"Pretend that the size and position of the tile are the same as the last time " +"you tiled it (if any), instead of using the current size" +msgstr "" +"Uzmi da su veličina i pozicija objekta iste kao i predhodnog puta kada je " +"popločan (ako jeste), umesto korišćenja trenutne veličine" + +#: ../../po/../src/dialogs/clonetiler.cpp:2539 +msgid " _Create " +msgstr " _Napravi " + +#: ../../po/../src/dialogs/clonetiler.cpp:2541 +msgid "Create and tile the clones of the selection" +msgstr "Napravi i popločaj klonove izabranog objekta" + +#. TRANSLATORS: if a group of objects are "clumped" together, then they +#. are unevenly spread in the given amount of space - as shown in the +#. diagrams on the left in the following screenshot: +#. http://www.inkscape.org/screenshots/gallery/inkscape-0.42-CVS-tiles-unclump.png +#. So unclumping is the process of spreading a number of objects out more evenly. +#: ../../po/../src/dialogs/clonetiler.cpp:2556 +msgid " _Unclump " +msgstr " _Rastavi " + +#: ../../po/../src/dialogs/clonetiler.cpp:2557 +msgid "Spread out clones to reduce clumping; can be applied repeatedly" +msgstr "" +"Rastavljanje klonova da bi se razredili; može se uzastopno primenjivati" + +#: ../../po/../src/dialogs/clonetiler.cpp:2563 +msgid " Re_move " +msgstr " _Ukloni " + +#: ../../po/../src/dialogs/clonetiler.cpp:2564 +msgid "Remove existing tiled clones of the selected object (siblings only)" +msgstr "" +"Uklanja postojeće popločane klonove izabranog objekta (samo istog nivoa)" + +#: ../../po/../src/dialogs/clonetiler.cpp:2580 +msgid " R_eset " +msgstr " _Vaspostavi " + +#. TRANSLATORS: "change" is a noun here +#: ../../po/../src/dialogs/clonetiler.cpp:2582 +msgid "" +"Reset all shifts, scales, rotates, opacity and color changes in the dialog " +"to zero" +msgstr "" +"Vraća sve parametre pomeraja, razmere, rotacije, providnosti i boje u " +"dijalogu na nulu." + +#: ../../po/../src/dialogs/color-picker.cpp:280 +msgid "Close" +msgstr "Zatvori" + +#: ../../po/../src/dialogs/debugdialog.cpp:138 +msgid "Messages" +msgstr "Poruke" + +#. ## Add a menu for clear() +#: ../../po/../src/dialogs/debugdialog.cpp:144 +#: ../../po/../src/menus-skeleton.h:16 +#: ../../po/../src/ui/dialog/messages.cpp:56 +#: ../../po/../src/ui/dialog/scriptdialog.cpp:181 +msgid "_File" +msgstr "_Datoteka" + +#. TRANSLATORS: "Clear" is a verb here +#: ../../po/../src/dialogs/debugdialog.cpp:145 +#: ../../po/../src/dialogs/find.cpp:753 +#: ../../po/../src/ui/dialog/messages.cpp:57 +#: ../../po/../src/ui/dialog/scriptdialog.cpp:182 +msgid "_Clear" +msgstr "_Očisti" + +#: ../../po/../src/dialogs/debugdialog.cpp:147 +#: ../../po/../src/ui/dialog/messages.cpp:59 +msgid "Capture log messages" +msgstr "Beleži poruke dnevnika rada" + +#: ../../po/../src/dialogs/debugdialog.cpp:149 +#: ../../po/../src/ui/dialog/messages.cpp:61 +msgid "Release log messages" +msgstr "Zaustavi beleženje poruka dnevnika rada" + +#. Notebook tab +#: ../../po/../src/dialogs/desktop-properties.cpp:909 +#: ../../po/../src/ui/dialog/document-preferences.cpp:89 +#: ../../po/../src/ui/widget/panel.cpp:107 +msgid "Grid" +msgstr "Mreža" + +#. Checkbuttons +#. / \todo FIXME: gray out snapping when grid is off +#. / \todo FIXME: gray out snapping when grid is off. +#. / Dissenting view: you want snapping without grid. +#: ../../po/../src/dialogs/desktop-properties.cpp:917 +#: ../../po/../src/ui/dialog/document-preferences.cpp:179 +msgid "Show grid" +msgstr "Prikaži mrežu" + +#: ../../po/../src/dialogs/desktop-properties.cpp:917 +#: ../../po/../src/ui/dialog/document-preferences.cpp:179 +#: ../../po/../src/verbs.cpp:2115 +msgid "Show or hide grid" +msgstr "Prikaži ili sakrij mrežu" + +#: ../../po/../src/dialogs/desktop-properties.cpp:918 +#: ../../po/../src/ui/dialog/document-preferences.cpp:180 +msgid "Snap bounding boxes to grid" +msgstr "Prijanjanje kontejnera uz mrežu" + +#: ../../po/../src/dialogs/desktop-properties.cpp:918 +#: ../../po/../src/dialogs/desktop-properties.cpp:1001 +#: ../../po/../src/ui/dialog/document-preferences.cpp:181 +#: ../../po/../src/ui/dialog/document-preferences.cpp:236 +msgid "Snap the edges of the object bounding boxes" +msgstr "Prijanjanje ivica kontejnera objekta" + +#: ../../po/../src/dialogs/desktop-properties.cpp:919 +#: ../../po/../src/ui/dialog/document-preferences.cpp:183 +#, fuzzy +msgid "Snap nodes to grid" +msgstr "Prijanjanje tačaka uz mrežu" + +#: ../../po/../src/dialogs/desktop-properties.cpp:919 +#: ../../po/../src/dialogs/desktop-properties.cpp:1002 +#: ../../po/../src/ui/dialog/document-preferences.cpp:184 +#: ../../po/../src/ui/dialog/document-preferences.cpp:239 +msgid "Snap path nodes, text baselines, ellipse centers, etc." +msgstr "Prijanjanje čvorova krive, osnove teksta, centra elipse, i sl." + +#: ../../po/../src/dialogs/desktop-properties.cpp:937 +#: ../../po/../src/ui/dialog/document-preferences.cpp:186 +msgid "Grid units:" +msgstr "Jedinica mere mreže:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:939 +#: ../../po/../src/ui/dialog/document-preferences.cpp:187 +msgid "Origin X:" +msgstr "Početak X:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:942 +#: ../../po/../src/ui/dialog/document-preferences.cpp:189 +msgid "Origin Y:" +msgstr "Početak Y:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:945 +#: ../../po/../src/ui/dialog/document-preferences.cpp:191 +msgid "Spacing X:" +msgstr "Vodoravni korak:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:948 +#: ../../po/../src/ui/dialog/document-preferences.cpp:193 +msgid "Spacing Y:" +msgstr "Uspravni korak:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:952 +#: ../../po/../src/dialogs/desktop-properties.cpp:1013 +#: ../../po/../src/ui/dialog/document-preferences.cpp:195 +#: ../../po/../src/ui/dialog/document-preferences.cpp:241 +msgid "Snap units:" +msgstr "Jedinica mere prijanjanja:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:955 +#: ../../po/../src/dialogs/desktop-properties.cpp:1016 +#: ../../po/../src/ui/dialog/document-preferences.cpp:196 +#: ../../po/../src/ui/dialog/document-preferences.cpp:242 +msgid "Snap distance:" +msgstr "Udaljenost za prijanjanje:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:958 +#: ../../po/../src/ui/dialog/document-preferences.cpp:199 +msgid "Grid line color:" +msgstr "Boja linija mreže:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:959 +#: ../../po/../src/ui/dialog/document-preferences.cpp:199 +msgid "Grid line color" +msgstr "Boja linija mreže" + +#: ../../po/../src/dialogs/desktop-properties.cpp:959 +#: ../../po/../src/ui/dialog/document-preferences.cpp:200 +msgid "Color of grid lines" +msgstr "Boja linija mreže" + +#: ../../po/../src/dialogs/desktop-properties.cpp:961 +#: ../../po/../src/ui/dialog/document-preferences.cpp:201 +msgid "Major grid line color:" +msgstr "Boja glavnih linija mreže:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:962 +#: ../../po/../src/ui/dialog/document-preferences.cpp:201 +msgid "Major grid line color" +msgstr "Boja glavnih linija mreže" + +#: ../../po/../src/dialogs/desktop-properties.cpp:962 +#: ../../po/../src/ui/dialog/document-preferences.cpp:202 +msgid "Color of the major (highlighted) grid lines" +msgstr "Boja glavnih (istaknutih) linija mreže" + +#: ../../po/../src/dialogs/desktop-properties.cpp:965 +#: ../../po/../src/ui/dialog/document-preferences.cpp:204 +msgid "Major grid line every:" +msgstr "Glavne linije mreže na:" + +#. TRANSLATORS: This belongs to the "Major grid line every:" string, +#. see grid settings in the "Document Preferences" dialog +#: ../../po/../src/dialogs/desktop-properties.cpp:977 +#: ../../po/../src/ui/dialog/document-preferences.cpp:204 +msgid "lines" +msgstr "linija" + +#. Guidelines page +#: ../../po/../src/dialogs/desktop-properties.cpp:991 +#: ../../po/../src/ui/dialog/document-preferences.cpp:90 +msgid "Guides" +msgstr "Vođice" + +#. / \todo FIXME: gray out snapping when guides are off +#. / Dissenting view: you want snapping without guides. +#: ../../po/../src/dialogs/desktop-properties.cpp:1000 +#: ../../po/../src/ui/dialog/document-preferences.cpp:234 +msgid "Show guides" +msgstr "Prikaži vođice" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1000 +#: ../../po/../src/ui/dialog/document-preferences.cpp:234 +#: ../../po/../src/verbs.cpp:2116 +msgid "Show or hide guides" +msgstr "Prikaži ili sakrij vođice" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1001 +#: ../../po/../src/ui/dialog/document-preferences.cpp:235 +msgid "Snap bounding boxes to guides" +msgstr "Prijanjanje kontejnera uz vođice" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1002 +#: ../../po/../src/ui/dialog/document-preferences.cpp:238 +msgid "Snap points to guides" +msgstr "Prijanjanje tačaka uz vođice" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1020 +#: ../../po/../src/ui/dialog/document-preferences.cpp:243 +msgid "Guide color:" +msgstr "Boja vođica:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1021 +#: ../../po/../src/ui/dialog/document-preferences.cpp:243 +msgid "Guideline color" +msgstr "Boja vođica" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1021 +#: ../../po/../src/ui/dialog/document-preferences.cpp:244 +msgid "Color of guidelines" +msgstr "Boja vodećih linija" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1023 +#: ../../po/../src/ui/dialog/document-preferences.cpp:245 +msgid "Highlight color:" +msgstr "Boja istaknutih vođica:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1024 +#: ../../po/../src/ui/dialog/document-preferences.cpp:245 +msgid "Highlighted guideline color" +msgstr "Boja istaknutih vođica" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1024 +#: ../../po/../src/ui/dialog/document-preferences.cpp:246 +msgid "Color of a guideline when it is under mouse" +msgstr "Boja vodeće linije kada je ispod kursora" + +#. Page page +#: ../../po/../src/dialogs/desktop-properties.cpp:1029 +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:855 +#: ../../po/../src/ui/dialog/document-preferences.cpp:88 +#: ../../po/../src/widgets/desktop-widget.cpp:1061 +msgid "Page" +msgstr "Strana" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1039 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +msgid "Background:" +msgstr "Pozadina:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1040 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +msgid "Background color" +msgstr "Boja pozadine" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1041 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +msgid "" +"Color and transparency of the page background (also used for bitmap export)" +msgstr "" +"Boja i providnost pozadine strane (takođe se korsti za izvoz u bitmapiranu " +"sliku)" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1045 +#: ../../po/../src/ui/dialog/document-preferences.cpp:147 +#, fuzzy +msgid "Show page border" +msgstr "Prikaži okvir platna" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1049 +#: ../../po/../src/ui/dialog/document-preferences.cpp:148 +msgid "Border on top of drawing" +msgstr "Okvir iznad crteža" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1052 +#: ../../po/../src/ui/dialog/document-preferences.cpp:149 +msgid "Border color:" +msgstr "Boja okvira:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1053 +#: ../../po/../src/ui/dialog/document-preferences.cpp:149 +#, fuzzy +msgid "Page border color" +msgstr "Boja linije okvira platna" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1054 +#: ../../po/../src/ui/dialog/document-preferences.cpp:150 +#, fuzzy +msgid "Color of the page border" +msgstr "Boja okvira platna" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1059 +#: ../../po/../src/ui/dialog/document-preferences.cpp:152 +msgid "Show page shadow" +msgstr "Prikaži senku strane" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1063 +#: ../../po/../src/ui/dialog/document-preferences.cpp:153 +msgid "Default units:" +msgstr "Podrazumevane jedinice mere:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1069 +msgid "Units for the tool controls, ruler, and the statusbar" +msgstr "Jedinica mere za alate, lenjire i statusnu liniju" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1086 +#: ../../po/../src/ui/widget/page-sizer.cpp:209 +#, fuzzy +msgid "Page size:" +msgstr "Veličina platna:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1110 +#: ../../po/../src/ui/widget/page-sizer.cpp:219 +msgid "Custom" +msgstr "Prilagođeno" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1121 +#: ../../po/../src/ui/widget/page-sizer.cpp:225 +#, fuzzy +msgid "Page orientation:" +msgstr "Orijentacija platna:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1133 +#: ../../po/../src/ui/widget/page-sizer.cpp:232 +msgid "Landscape" +msgstr "Vodoravno" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1139 +#: ../../po/../src/ui/widget/page-sizer.cpp:234 +msgid "Portrait" +msgstr "Uspravno" + +#. Custom paper frame +#: ../../po/../src/dialogs/desktop-properties.cpp:1148 +#: ../../po/../src/ui/widget/page-sizer.cpp:249 +#, fuzzy +msgid "Custom size" +msgstr "Prilagođeno" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1160 +#: ../../po/../src/dialogs/export.cpp:269 +#: ../../po/../src/ui/widget/page-sizer.cpp:261 +msgid "Units:" +msgstr "Jedinica mere:" + +#. Stroke width +#: ../../po/../src/dialogs/desktop-properties.cpp:1162 +#: ../../po/../src/dialogs/export.cpp:310 +#: ../../po/../src/dialogs/object-attributes.cpp:55 +#: ../../po/../src/dialogs/stroke-style.cpp:985 +#: ../../po/../src/ui/widget/page-sizer.cpp:262 +#: ../../po/../src/widgets/toolbox.cpp:1957 +msgid "Width:" +msgstr "Å irina:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1183 +#: ../../po/../src/dialogs/export.cpp:326 +#: ../../po/../src/dialogs/export.cpp:431 +#: ../../po/../src/dialogs/object-attributes.cpp:56 +#: ../../po/../src/ui/widget/page-sizer.cpp:263 +msgid "Height:" +msgstr "Visina:" + +#. +#. * Ownership metadata tab +#. +#: ../../po/../src/dialogs/desktop-properties.cpp:1206 +msgid "Metadata" +msgstr "Dopunske informacije" + +#. add license selector pull-down +#: ../../po/../src/dialogs/desktop-properties.cpp:1225 +msgid "License" +msgstr "Licenca" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1255 +msgid "Proprietary" +msgstr "VlasniÅ¡tvo" + +#: ../../po/../src/dialogs/display-settings.cpp:212 +msgid "When transforming, show:" +msgstr "Prikaži pri pomeranju i transformaciji" + +#: ../../po/../src/dialogs/display-settings.cpp:223 +msgid "Objects" +msgstr "Objekat" + +#: ../../po/../src/dialogs/display-settings.cpp:224 +msgid "Show the actual objects when moving or transforming" +msgstr "Prikaži pravi objekat pri pomeranju ili transformaciji" + +#: ../../po/../src/dialogs/display-settings.cpp:231 +msgid "Box outline" +msgstr "Okvir kontejnera" + +#: ../../po/../src/dialogs/display-settings.cpp:232 +msgid "Show only a box outline of the objects when moving or transforming" +msgstr "Prikaži samo okvir kontejnera objekta pri pomeranju ili transformaciji" + +#: ../../po/../src/dialogs/display-settings.cpp:238 +msgid "Per-object selection cue:" +msgstr "Obeležavanje izabranog objekta" + +#. sorationsnapsperpi == 0 means no snapping +#: ../../po/../src/dialogs/display-settings.cpp:249 +#: ../../po/../src/dialogs/display-settings.cpp:386 +#: ../../po/../src/dialogs/display-settings.cpp:441 +#: ../../po/../src/dialogs/display-settings.cpp:1482 +#: ../../po/../src/dialogs/stroke-style.cpp:791 +#: ../../po/../src/interface.cpp:741 +#: ../../po/../src/ui/widget/selected-style.cpp:100 +#: ../../po/../src/verbs.cpp:1842 +msgid "None" +msgstr "Bez oznaka" + +#: ../../po/../src/dialogs/display-settings.cpp:250 +msgid "No per-object selection indication" +msgstr "Izabrani objekat nema vidljive oznake" + +#: ../../po/../src/dialogs/display-settings.cpp:256 +msgid "Mark" +msgstr "Sa oznakom" + +#: ../../po/../src/dialogs/display-settings.cpp:257 +msgid "Each selected object has a diamond mark in the top left corner" +msgstr "Svaki izabrani objekat ima oznaku u obliku romba u gornjem levom uglu" + +#: ../../po/../src/dialogs/display-settings.cpp:264 +msgid "Box" +msgstr "Okvir" + +#: ../../po/../src/dialogs/display-settings.cpp:265 +msgid "Each selected object displays its bounding box" +msgstr "Svaki odabrani objekat se označava okvirom kontejnera" + +#: ../../po/../src/dialogs/display-settings.cpp:270 +msgid "Default scale origin:" +msgstr "Podrazumevana osnova za promenu veličine:" + +#: ../../po/../src/dialogs/display-settings.cpp:281 +msgid "Opposite bounding box edge" +msgstr "Suprotne ivice kontejnera" + +#: ../../po/../src/dialogs/display-settings.cpp:282 +msgid "Default scale origin will be on the bounding box of the item" +msgstr "" +"Podrazumevana osnova za promenu veličine će biti okvir kontejnera objekta" + +#: ../../po/../src/dialogs/display-settings.cpp:288 +msgid "Farthest opposite node" +msgstr "NajviÅ¡e udaljeni čvorovi" + +#: ../../po/../src/dialogs/display-settings.cpp:289 +msgid "Default scale origin will be on the bounding box of the item's points" +msgstr "" +"Podrazumevana osnova za promenu veličine će biti prostor između " +"najudaljenijih čvorova objekta" + +#: ../../po/../src/dialogs/display-settings.cpp:341 +msgid "degrees" +msgstr "stepeni" + +#: ../../po/../src/dialogs/display-settings.cpp:350 +msgid "" +"Rotating with Ctrl pressed snaps every that much degrees; also, pressing " +"[ or ] rotates by this amount" +msgstr "" +"Rotacija sa pritisnutim Ctrl prijanja za ovoliko stepeni; takođe, " +"pritiskanje [ ili ] rotira objekat za ovu vrednost" + +#: ../../po/../src/dialogs/display-settings.cpp:407 +msgid "Rotation snaps every:" +msgstr "Rotacija prijanja na svakih:" + +#: ../../po/../src/dialogs/display-settings.cpp:430 +msgid "" +"None: dialogs are treated as regular windows; Normal: dialogs stay on top of " +"document windows; Aggressive: same as Normal but may work better with some " +"window managers." +msgstr "" +"NiÅ¡ta: dijalozi se tretiraju kao obični prozori; Normalno: dijalozi ostaju " +"na vrhu prozora dokumenta; Agresivno: isto kao Normalno ali će bolje raditi " +"sa nekim menadžerima prozora." + +#: ../../po/../src/dialogs/display-settings.cpp:451 +msgid "Normal" +msgstr "Normalno" + +#: ../../po/../src/dialogs/display-settings.cpp:461 +msgid "Aggressive" +msgstr "Agresivno" + +#: ../../po/../src/dialogs/display-settings.cpp:475 +msgid "Dialogs on top:" +msgstr "Prozorčići na vrhu:" + +#: ../../po/../src/dialogs/display-settings.cpp:645 +msgid "Show selection cue" +msgstr "Prikaži obeleživač" + +#: ../../po/../src/dialogs/display-settings.cpp:646 +msgid "" +"Whether selected objects display a selection cue (the same as in selector)" +msgstr "Uvek kada se za izabrani objekat prikazuje oznaka (kao kod izbornika)" + +#: ../../po/../src/dialogs/display-settings.cpp:657 +msgid "Enable gradient editing" +msgstr "Omogući uređivač preliva" + +#: ../../po/../src/dialogs/display-settings.cpp:658 +msgid "Whether selected objects display gradient editing controls" +msgstr "Prikazuje kontrolne tačke za uređivanje preliva kad se izabere objekat" + +#: ../../po/../src/dialogs/display-settings.cpp:719 +msgid "No objects selected to take the style from." +msgstr "Nema izabranog objekta od koga će se preuzeti stil." + +#: ../../po/../src/dialogs/display-settings.cpp:728 +msgid "" +"More than one object selected. Cannot take style from multiple " +"objects." +msgstr "" +"Izabrano je viÅ¡e od jednog objekta. Nije moguće uzeti stil od viÅ¡e " +"objekata." + +#: ../../po/../src/dialogs/display-settings.cpp:767 +msgid "Create new objects with:" +msgstr "Pravljenje novog objekta sa:" + +#: ../../po/../src/dialogs/display-settings.cpp:777 +msgid "Take from selection" +msgstr "Uzmi iz izbora" + +#: ../../po/../src/dialogs/display-settings.cpp:778 +msgid "Remember the style of the (first) selected object as this tool's style" +msgstr "Upamti stil (prvog) izabranog objekta kao stil ovog alata" + +#: ../../po/../src/dialogs/display-settings.cpp:782 +#, fuzzy +msgid "Last used style" +msgstr "Ubaci _stil" + +#: ../../po/../src/dialogs/display-settings.cpp:782 +msgid "Apply the style you last set on an object" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:790 +msgid "This tool's own style:" +msgstr "Lični stil ovog alata:" + +#: ../../po/../src/dialogs/display-settings.cpp:790 +msgid "" +"Each tool may store its own style to apply to the newly created objects. Use " +"the button below to set it." +msgstr "" +"Svaki alat može da ima lični stil koji će se primeniti na novonapravljene " +"objekte. Upotrebite dugme ispod da vidite stil." + +#. Mouse +#: ../../po/../src/dialogs/display-settings.cpp:877 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:55 +msgid "Mouse" +msgstr "MiÅ¡" + +#. TRANSLATORS: "Grab" is a noun here. "Grab sensitivity" is intended to mean how +#. * close on the screen you need to be to an object to be able to grab it with mouse (in +#. * pixels). +#: ../../po/../src/dialogs/display-settings.cpp:883 +msgid "Grab sensitivity:" +msgstr "Osetljivost hvatanja:" + +#: ../../po/../src/dialogs/display-settings.cpp:884 +msgid "" +"How close on the screen you need to be to an object to be able to grab it " +"with mouse (in screen pixels)" +msgstr "" +"Koliko je potrebno da kursor bude blizu objekta na ekranu kako bi se on " +"mogao izabrati klikom miÅ¡a (u ekranskim pikselima)" + +#: ../../po/../src/dialogs/display-settings.cpp:885 +#: ../../po/../src/dialogs/display-settings.cpp:897 +#: ../../po/../src/dialogs/display-settings.cpp:912 +#: ../../po/../src/dialogs/display-settings.cpp:930 +#: ../../po/../src/dialogs/display-settings.cpp:970 +msgid "pixels" +msgstr "tačaka" + +#: ../../po/../src/dialogs/display-settings.cpp:895 +msgid "Click/drag threshold:" +msgstr "Prag klika/pomeraja:" + +#: ../../po/../src/dialogs/display-settings.cpp:896 +msgid "" +"Maximum mouse drag (in screen pixels) which is considered a click, not a drag" +msgstr "" +"Maksimalan pomeraj (u pikselima ekrana) koji se tretira kao klik, a ne kao " +"pomeraj" + +#. Scrolling +#: ../../po/../src/dialogs/display-settings.cpp:907 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:56 +msgid "Scrolling" +msgstr "Pomeranje" + +#: ../../po/../src/dialogs/display-settings.cpp:910 +msgid "Mouse wheel scrolls by:" +msgstr "Točkić miÅ¡a pomera za:" + +#: ../../po/../src/dialogs/display-settings.cpp:911 +msgid "" +"One mouse wheel notch scrolls by this distance in screen pixels " +"(horizontally with Shift)" +msgstr "" +"Jedan korak točkića miÅ¡a pomera ekran za ovaj korak u pikselima ekrana (za " +"vodoravno pomeranje koristite Shift)" + +#: ../../po/../src/dialogs/display-settings.cpp:920 +msgid "Ctrl+arrows" +msgstr "Ctrl+strlice" + +#: ../../po/../src/dialogs/display-settings.cpp:928 +msgid "Scroll by:" +msgstr "Pomeraj za:" + +#: ../../po/../src/dialogs/display-settings.cpp:929 +msgid "Pressing Ctrl+arrow key scrolls by this distance (in screen pixels)" +msgstr "" +"Pritiskanjem Ctrl+strelica pomera za ovoliku razdaljinu (u ekranskim " +"pikselima)" + +#: ../../po/../src/dialogs/display-settings.cpp:939 +msgid "Acceleration:" +msgstr "Ubrzanje:" + +#: ../../po/../src/dialogs/display-settings.cpp:940 +msgid "" +"Pressing and holding Ctrl+arrow will gradually speed up scrolling (0 for no " +"acceleration)" +msgstr "" +"Pritiskanjem i držanjem Ctrl+strelica pomeranje se postepeno ubrzava (0 za " +"isključeno ubrzanje)" + +#: ../../po/../src/dialogs/display-settings.cpp:949 +msgid "Autoscrolling" +msgstr "Automatsko pomeranje" + +#: ../../po/../src/dialogs/display-settings.cpp:957 +msgid "Speed:" +msgstr "Brzina:" + +#: ../../po/../src/dialogs/display-settings.cpp:958 +msgid "" +"How fast the canvas autoscrolls when you drag beyond canvas edge (0 to turn " +"autoscroll off)" +msgstr "" +"Koliko brzo se platno pomera kada uhvatite spoljaÅ¡njost platna (0 za " +"isključeno automatsko pomeranje)" + +#: ../../po/../src/dialogs/display-settings.cpp:968 +#: ../../po/../src/ui/dialog/tracedialog.cpp:357 +#: ../../po/../src/ui/dialog/tracedialog.cpp:390 +msgid "Threshold:" +msgstr "Prag tolerancije:" + +#: ../../po/../src/dialogs/display-settings.cpp:969 +msgid "" +"How far (in screen pixels) you need to be from the canvas edge to trigger " +"autoscroll; positive is outside the canvas, negative is within the canvas" +msgstr "" +"Koliko blizu (u ekranskim pikselima) je potrebno da kursor bude uz ivicu " +"platna za aktiviranje automatskog pomeranja; pozitivna vrednost je van " +"platna, negativna je za unutraÅ¡njost platna" + +#. Steps +#: ../../po/../src/dialogs/display-settings.cpp:979 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:57 +msgid "Steps" +msgstr "Koraci" + +#: ../../po/../src/dialogs/display-settings.cpp:982 +msgid "Arrow keys move by:" +msgstr "Strelice pomeraju za:" + +#: ../../po/../src/dialogs/display-settings.cpp:983 +msgid "" +"Pressing an arrow key moves selected object(s) or node(s) by this distance " +"(in px units)" +msgstr "" +"Pritiskanje strelica pomera izabrani objekat ili čvor za ovu razdaljinu (u " +"pikselima)" + +#: ../../po/../src/dialogs/display-settings.cpp:984 +#: ../../po/../src/dialogs/display-settings.cpp:995 +#: ../../po/../src/dialogs/display-settings.cpp:1006 +#: ../../po/../src/helper/units.cpp:42 +msgid "px" +msgstr "px" + +#: ../../po/../src/dialogs/display-settings.cpp:993 +msgid "> and < scale by:" +msgstr "„>“ i „<“ menjaju veličinu za:" + +#: ../../po/../src/dialogs/display-settings.cpp:994 +msgid "" +"Pressing > or < scales selection up or down by this increment (in px units)" +msgstr "" +"Pritiskanjem „>“ ili „<“ menja se veličina izbora za ovaj korak (u pikselima)" + +#: ../../po/../src/dialogs/display-settings.cpp:1004 +msgid "Inset/Outset by:" +msgstr "Skupljanje/Å¡irenje za:" + +#: ../../po/../src/dialogs/display-settings.cpp:1005 +msgid "" +"Inset and Outset commands displace the path by this distance (in px units)" +msgstr "Skupljanje i Å irenje pomera krivu za ovu razdaljinu (u pikselima)" + +#: ../../po/../src/dialogs/display-settings.cpp:1017 +msgid "Compass-like display of angles" +msgstr "" + +#. TRANSLATORS: "positive clockwise" means "increasing in clockwise direction" +#: ../../po/../src/dialogs/display-settings.cpp:1019 +msgid "" +"When on, angles are displayed with 0 at north, 0 to 360 range, positive " +"clockwise; otherwise with 0 at east, -180 to 180 range, positive " +"counterclockwise" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1026 +msgid "Zoom in/out by:" +msgstr "Uvećavanje/umanjenje za:" + +#: ../../po/../src/dialogs/display-settings.cpp:1027 +msgid "" +"Zoom tool click, +/- keys, and middle click zoom in and out by this " +"multiplier" +msgstr "" +"Alat za promenu veličine (zumiranje), +/- tasteri i srednji klik miÅ¡em " +"uveličava i umanjuje za ovaj umnožak" + +#: ../../po/../src/dialogs/display-settings.cpp:1028 +#: ../../po/../src/helper/units.cpp:44 +msgid "%" +msgstr "%" + +#. Tools +#: ../../po/../src/dialogs/display-settings.cpp:1037 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:58 +msgid "Tools" +msgstr "Alatke" + +#: ../../po/../src/dialogs/display-settings.cpp:1045 +msgid "Selector" +msgstr "Izbornik" + +#: ../../po/../src/dialogs/display-settings.cpp:1056 +msgid "Node" +msgstr "Čvor" + +#: ../../po/../src/dialogs/display-settings.cpp:1064 +#: ../../po/../src/verbs.cpp:2073 +#: ../../po/../src/widgets/desktop-widget.cpp:277 +msgid "Zoom" +msgstr "Uvećaj" + +#. The 4 shape tools +#: ../../po/../src/dialogs/display-settings.cpp:1071 +msgid "Shapes" +msgstr "Četvorougaonik" + +#: ../../po/../src/dialogs/display-settings.cpp:1079 +#: ../../po/../src/verbs.cpp:2055 +msgid "Rectangle" +msgstr "Pravougaonik" + +#: ../../po/../src/dialogs/display-settings.cpp:1085 +#: ../../po/../src/verbs.cpp:2057 +msgid "Ellipse" +msgstr "Elipsa" + +#: ../../po/../src/dialogs/display-settings.cpp:1091 +#: ../../po/../src/verbs.cpp:2059 +msgid "Star" +msgstr "Zvezda" + +#: ../../po/../src/dialogs/display-settings.cpp:1097 +#: ../../po/../src/verbs.cpp:2061 +msgid "Spiral" +msgstr "Spirala" + +#: ../../po/../src/dialogs/display-settings.cpp:1111 +#: ../../po/../src/verbs.cpp:2063 +msgid "Pencil" +msgstr "Gruba olovka" + +#: ../../po/../src/dialogs/display-settings.cpp:1114 +msgid "Tolerance:" +msgstr "Tolerancija:" + +#: ../../po/../src/dialogs/display-settings.cpp:1115 +msgid "" +"This value affects the amount of smoothing applied to freehand lines; lower " +"values produce more uneven paths with more nodes" +msgstr "" +"Ova vrednost se odnosi na jačinu umekÅ¡avanja primenjenih na iscrtavanje " +"krive slobodnom rukom; manje vrednosti proizvode nazubljenije linije sa viÅ¡e " +"čvorova" + +#: ../../po/../src/dialogs/display-settings.cpp:1131 +#: ../../po/../src/verbs.cpp:2065 +msgid "Pen" +msgstr "Olovka" + +#: ../../po/../src/dialogs/display-settings.cpp:1140 +#: ../../po/../src/verbs.cpp:2067 +msgid "Calligraphy" +msgstr "Kaligrafija" + +#: ../../po/../src/dialogs/display-settings.cpp:1147 +#: ../../po/../src/dialogs/text-edit.cpp:353 +#: ../../po/../src/ui/dialog/text-properties.cpp:37 +#: ../../po/../src/verbs.cpp:2069 +msgid "Text" +msgstr "Tekst" + +#: ../../po/../src/dialogs/display-settings.cpp:1157 +#: ../../po/../src/verbs.cpp:2071 +msgid "Gradient" +msgstr "Uređivač preliva" + +#: ../../po/../src/dialogs/display-settings.cpp:1164 +#: ../../po/../src/verbs.cpp:2077 +#, fuzzy +msgid "Connector" +msgstr "Autor" + +#: ../../po/../src/dialogs/display-settings.cpp:1171 +#: ../../po/../src/verbs.cpp:2075 +msgid "Dropper" +msgstr "Izbornik boja" + +#. Windows +#: ../../po/../src/dialogs/display-settings.cpp:1183 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:59 +msgid "Windows" +msgstr "Prozori" + +#: ../../po/../src/dialogs/display-settings.cpp:1188 +msgid "Save window geometry" +msgstr "Sačuvaj dimenzije prozora" + +#: ../../po/../src/dialogs/display-settings.cpp:1189 +msgid "" +"Save the window size and position with each document (only for Inkscape SVG " +"format)" +msgstr "" +"Sačuvaj dimenzije prozora i poziciju sa svakim dokumentom (samo za Inkskejp " +"SVG format)" + +#: ../../po/../src/dialogs/display-settings.cpp:1196 +msgid "Dialogs are hidden in taskbar" +msgstr "Sakrij prozorčiće u liniju poslova" + +#: ../../po/../src/dialogs/display-settings.cpp:1197 +msgid "Whether dialog windows are to be hidden in the window manager taskbar" +msgstr "" +"Uvek kada su prozorčići skriveni, smesti ih u liniju poslova menadžera " +"prozora" + +#: ../../po/../src/dialogs/display-settings.cpp:1204 +msgid "Zoom when window is resized" +msgstr "Promeni uvećanje pri promeni veličine prozora" + +#: ../../po/../src/dialogs/display-settings.cpp:1205 +msgid "" +"Zoom drawing when document window is resized, to keep the same area visible " +"(this is the default which can be changed in any window using the button " +"above the right scrollbar)" +msgstr "" +"Zumiranje crteža kada se prmeni veličina prozora, da bi se ista povrÅ¡ina " +"održala vidljivom (ovo je podrazumevana osobina koja se može promeniti za " +"svaki prozor pomoću dugmeta u desnom uglu iznad trake za pomeranje)" + +#. Clones +#: ../../po/../src/dialogs/display-settings.cpp:1213 +#: ../../po/../src/dialogs/find.cpp:624 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:60 +msgid "Clones" +msgstr "Klonovi" + +#: ../../po/../src/dialogs/display-settings.cpp:1217 +msgid "When the original moves, its clones and linked offsets:" +msgstr "Kada se pomeri original, pomeraj klona i povezanog objekta je:" + +#: ../../po/../src/dialogs/display-settings.cpp:1229 +msgid "Move in parallel" +msgstr "Pomera paralelno sa originalom" + +#: ../../po/../src/dialogs/display-settings.cpp:1230 +msgid "Clones are translated by the same vector as their original." +msgstr "Klon se pomera po istoj putanji kao i original." + +#: ../../po/../src/dialogs/display-settings.cpp:1237 +msgid "Stay unmoved" +msgstr "Ostaje na mestu" + +#: ../../po/../src/dialogs/display-settings.cpp:1238 +msgid "Clones preserve their positions when their original is moved." +msgstr "Klon zadržava poziciju kada se original pomeri." + +#: ../../po/../src/dialogs/display-settings.cpp:1245 +msgid "Move according to transform" +msgstr "Pomeranje shodno transformaciji" + +#: ../../po/../src/dialogs/display-settings.cpp:1246 +msgid "" +"Each clone moves according to the value of its transform= attribute. For " +"example, a rotated clone will move in a different direction than its " +"original." +msgstr "" +"Svaki klon se pomera u skladu sa vrednošću njegovog transform= atributa. " +"Npr, rotirani klon će se pomeriti u suprotnom pravcu od originala." + +#: ../../po/../src/dialogs/display-settings.cpp:1255 +msgid "When the original is deleted, its clones:" +msgstr "Kada se original obriÅ¡e, klon se" + +#: ../../po/../src/dialogs/display-settings.cpp:1267 +msgid "Are unlinked" +msgstr "Odvezuje" + +#: ../../po/../src/dialogs/display-settings.cpp:1267 +msgid "Orphaned clones are converted to regular objects." +msgstr "Klonovi siročići se pretvaraju u normalne objekte." + +#: ../../po/../src/dialogs/display-settings.cpp:1273 +msgid "Are deleted" +msgstr "BriÅ¡e" + +#: ../../po/../src/dialogs/display-settings.cpp:1273 +msgid "Orphaned clones are deleted along with their original." +msgstr "Klonovi siročići se briÅ¡u zajedno sa originalom." + +#. Transforms +#. TRANSLATORS: Noun, i.e. transformations. +#: ../../po/../src/dialogs/display-settings.cpp:1289 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:61 +msgid "Transforms" +msgstr "Transformacija" + +#: ../../po/../src/dialogs/display-settings.cpp:1292 +msgid "Scale stroke width" +msgstr "Skaliraj Å¡irinu linije" + +#: ../../po/../src/dialogs/display-settings.cpp:1293 +#: ../../po/../src/widgets/select-toolbar.cpp:568 +msgid "When scaling objects, scale the stroke width by the same proportion" +msgstr "Kada se menja veličina objekta, proporcijalno se menja i Å¡irina linije" + +#: ../../po/../src/dialogs/display-settings.cpp:1300 +msgid "Scale rounded corners in rectangles" +msgstr "Promena veličine zaobljenih uglova pravougaonika" + +#: ../../po/../src/dialogs/display-settings.cpp:1301 +#: ../../po/../src/widgets/select-toolbar.cpp:580 +msgid "When scaling rectangles, scale the radii of rounded corners" +msgstr "" +"Kada se menja veličina pravougaonika, menja se i poluprečnik zaobljenih " +"uglova" + +#: ../../po/../src/dialogs/display-settings.cpp:1308 +msgid "Transform gradients" +msgstr "Transformacija preliva" + +#: ../../po/../src/dialogs/display-settings.cpp:1309 +#: ../../po/../src/widgets/select-toolbar.cpp:592 +msgid "Transform gradients (in fill or stroke) along with the objects" +msgstr "" +"Transformacija preliva (u popuni ili boji ivične linije) zajedno sa objektom" + +#: ../../po/../src/dialogs/display-settings.cpp:1316 +msgid "Transform patterns" +msgstr "Transformacija mustre" + +#: ../../po/../src/dialogs/display-settings.cpp:1317 +#: ../../po/../src/widgets/select-toolbar.cpp:604 +msgid "Transform patterns (in fill or stroke) along with the objects" +msgstr "" +"Transformacija mustre (u popuni ili boji ivične linije) zajedno sa objektom" + +#. TRANSLATORS: How to specify the affine transformation in the SVG file. +#: ../../po/../src/dialogs/display-settings.cpp:1327 +msgid "Store transformation:" +msgstr "Pamćenje transformacija:" + +#: ../../po/../src/dialogs/display-settings.cpp:1338 +msgid "Optimized" +msgstr "Optimizovano" + +#: ../../po/../src/dialogs/display-settings.cpp:1339 +msgid "" +"If possible, apply transformation to objects without adding a transform= " +"attribute" +msgstr "" +"Ako je moguće, primeni transformaciju objekta bez dodavanja atributa " +"transform=" + +#: ../../po/../src/dialogs/display-settings.cpp:1346 +msgid "Preserved" +msgstr "Sačuvano" + +#: ../../po/../src/dialogs/display-settings.cpp:1347 +msgid "Always store transformation as a transform= attribute on objects" +msgstr "Uvek sačuvaj transformaciju kao transform= atribut objekta" + +#. Selecting +#: ../../po/../src/dialogs/display-settings.cpp:1355 +msgid "Selecting" +msgstr "Izbor" + +#: ../../po/../src/dialogs/display-settings.cpp:1357 +msgid "Ctrl+A, Tab, Shift+Tab:" +msgstr "Ctrl+A, Tab, Shift+Tab:" + +#: ../../po/../src/dialogs/display-settings.cpp:1366 +msgid "Select only within current layer" +msgstr "Izaberi samo u trenutnom sloju" + +#: ../../po/../src/dialogs/display-settings.cpp:1367 +msgid "" +"Uncheck this to make keyboard selection commands work on objects in all " +"layers" +msgstr "" +"Isključite ovu opciju da bi omogućili izbor objekata tastaturom na svim " +"slojevima" + +#: ../../po/../src/dialogs/display-settings.cpp:1374 +msgid "Ignore hidden objects" +msgstr "IgnoriÅ¡i skrivene objekte" + +#: ../../po/../src/dialogs/display-settings.cpp:1375 +msgid "" +"Uncheck this to be able to select objects that are hidden (either by " +"themselves or by being in a hidden group or layer)" +msgstr "" +"Isključite ovu opciju da bi mogli da izaberete skriveni objekat (bilo njega " +"lično ili prelaskom u skrivenu grupu ili sloj)" + +#: ../../po/../src/dialogs/display-settings.cpp:1382 +msgid "Ignore locked objects" +msgstr "Zanemari zaključane slojeve" + +#: ../../po/../src/dialogs/display-settings.cpp:1383 +msgid "" +"Uncheck this to be able to select objects that are locked (either by " +"themselves or by being in a locked group or layer)" +msgstr "" +"Isključite ovu opciju da bi mogli da izaberete zaključani objekat (bilo " +"njega lično ili prelaskom u zaključanu grupu ili sloj)" + +#. To be broken into: Display, Save, Export, SVG, Commands +#: ../../po/../src/dialogs/display-settings.cpp:1391 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:62 +msgid "Misc" +msgstr "Razno" + +#: ../../po/../src/dialogs/display-settings.cpp:1394 +msgid "Default export resolution:" +msgstr "Podrazumevana rezolucija za izvoz:" + +#: ../../po/../src/dialogs/display-settings.cpp:1395 +msgid "Default bitmap resolution (in dots per inch) in the Export dialog" +msgstr "" +"Podrazumevana rezolucija bitmape (tačaka po inču) u Izvoznom prozorčetu" + +#. FIXME: add "Used for new exports; once exported, documents remember this value on per-object basis" when implemented +#: ../../po/../src/dialogs/display-settings.cpp:1396 +#: ../../po/../src/dialogs/export.cpp:442 +msgid "dpi" +msgstr "tpi" + +#. TRANSLATORS: When on, an imported bitmap creates an element; otherwise it is a +#. * rectangle with bitmap fill. +#: ../../po/../src/dialogs/display-settings.cpp:1407 +msgid "Import bitmap as " +msgstr "Uvezi bitmapu kao sliku „“" + +#: ../../po/../src/dialogs/display-settings.cpp:1408 +msgid "" +"When on, an imported bitmap creates an element; otherwise it is a " +"rectangle with bitmap fill" +msgstr "" +"Kada je aktivno, uvežena bitmapa je element; u suprotnom je " +"pravougaonik sa bitmapiranom popunom" + +#. TRANSLATORS: When on, the print out (currently Postscript) will have +#. * a comment with the each object's label visible, marking the section +#. * of the printing commands that represent the given object. +#: ../../po/../src/dialogs/display-settings.cpp:1418 +msgid "Add label comments to printing output" +msgstr "Dodavanje komentara u Å¡tampani izlaz" + +#: ../../po/../src/dialogs/display-settings.cpp:1419 +msgid "" +"When on, a comment will be added to the raw print output, marking the " +"rendered output for an object with its label" +msgstr "" +"Kada je aktivno, komentar će biti dodat na sirovi izlaz pri Å¡tampi, " +"obeležavajući renderovani izlaz objekta njegovom oznakom" + +#. TRANSLATORS: When on, enable the effects menu, default is off +#: ../../po/../src/dialogs/display-settings.cpp:1427 +msgid "Enable script effects (requires restart) - EXPERIMENTAL" +msgstr "Omogući efekte skriptama (zahteva restartovanje) - EKSPERIMENTALNO" + +#: ../../po/../src/dialogs/display-settings.cpp:1428 +msgid "" +"When on, the effects menu is enabled, allowing external effect scripts to be " +"called, requires restart before effective - EXPERIMENTAL" +msgstr "" +"Kada je aktivno, meni sa efektima je omogućen, dozvoljava da budu pozvane " +"spoljne skripte za efekte, zahteva restartovanje pre upotrebe - " +"EKSPERIMENTALNO" + +#. TRANSLATORS: The maximum length of the Open Recent list in the File menu. +#: ../../po/../src/dialogs/display-settings.cpp:1436 +msgid "Max recent documents:" +msgstr "NajviÅ¡e poslednje korišćenih dokumenata:" + +#: ../../po/../src/dialogs/display-settings.cpp:1437 +msgid "The maximum length of the Open Recent list in the File menu" +msgstr "" +"Maksimalan broj dokumenata u listi „Otvori poslednje korišćene“ u meniju " +"„Datoteka“" + +#: ../../po/../src/dialogs/display-settings.cpp:1447 +msgid "Simplification threshold:" +msgstr "Prag pojednostavljivanja:" + +#: ../../po/../src/dialogs/display-settings.cpp:1448 +msgid "" +"How strong is the Simplify command by default. If you invoke this command " +"several times in quick succession, it will act more and more aggressively; " +"invoking it again after a pause restores the default threshold." +msgstr "" +"Koliko je podrazumevano velika naredba Pojednostavljivanje. Ako pozivate ovu " +"naredbu viÅ¡e puta uzastopno, primenjivaće se sve agresivnije; ponovno " +"pozivanje nakon kratke pauze vraća prag na podrazumevanu vrednost." + +#: ../../po/../src/dialogs/display-settings.cpp:1469 +msgid "Oversample bitmaps:" +msgstr "Preuveličavanje bitmapa:" + +#: ../../po/../src/dialogs/display-settings.cpp:1488 +msgid "2x2" +msgstr "2x2" + +#: ../../po/../src/dialogs/display-settings.cpp:1494 +msgid "4x4" +msgstr "4x4" + +#: ../../po/../src/dialogs/display-settings.cpp:1500 +msgid "8x8" +msgstr "8x8" + +#: ../../po/../src/dialogs/display-settings.cpp:1506 +msgid "16x16" +msgstr "16x16" + +#. "view_icon_preview" +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2143 +msgid "_Page" +msgstr "_Strana" + +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2147 +msgid "_Drawing" +msgstr "_Crtež" + +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2149 +msgid "_Selection" +msgstr "_Izbor" + +#: ../../po/../src/dialogs/export.cpp:133 +msgid "_Custom" +msgstr "_Prilagođeno" + +#: ../../po/../src/dialogs/export.cpp:254 +msgid "Export area" +msgstr "Izvoz povrÅ¡ine" + +#: ../../po/../src/dialogs/export.cpp:300 +msgid "_x0:" +msgstr "_x0:" + +#: ../../po/../src/dialogs/export.cpp:305 +msgid "x_1:" +msgstr "x_1:" + +#: ../../po/../src/dialogs/export.cpp:316 +msgid "_y0:" +msgstr "_y0:" + +#: ../../po/../src/dialogs/export.cpp:321 +msgid "y_1:" +msgstr "y_1:" + +#: ../../po/../src/dialogs/export.cpp:406 +msgid "Bitmap size" +msgstr "Veličina bitmape" + +#: ../../po/../src/dialogs/export.cpp:416 +msgid "_Width:" +msgstr "_Å irina:" + +#: ../../po/../src/dialogs/export.cpp:416 +#: ../../po/../src/dialogs/export.cpp:431 +msgid "pixels at" +msgstr "piksela na" + +#: ../../po/../src/dialogs/export.cpp:426 +msgid "dp_i" +msgstr "tp_i" + +#: ../../po/../src/dialogs/export.cpp:448 +msgid "_Filename" +msgstr "Naziv _datoteke" + +#: ../../po/../src/dialogs/export.cpp:512 +msgid "_Browse..." +msgstr "_Traži..." + +#: ../../po/../src/dialogs/export.cpp:539 +msgid " _Export " +msgstr "_Izvoz" + +#: ../../po/../src/dialogs/export.cpp:541 +msgid "Export the bitmap file with these settings" +msgstr "Izvozi bitmapu sa ovim podeÅ¡avanjima" + +#: ../../po/../src/dialogs/export.cpp:968 +msgid "You have to enter a filename" +msgstr "Morate uneti naziv datoteke" + +#: ../../po/../src/dialogs/export.cpp:973 +msgid "The chosen area to be exported is invalid" +msgstr "Odabrana povrÅ¡ina za izvoz je neregularna" + +#: ../../po/../src/dialogs/export.cpp:982 +#, c-format +msgid "Directory %s does not exist or is not a directory.\n" +msgstr "Direktorijum %s ne postoji ili nije direktorijum.\n" + +#: ../../po/../src/dialogs/export.cpp:998 +msgid "Export in progress" +msgstr "Izvoz je u toku" + +#: ../../po/../src/dialogs/export.cpp:1004 +#, c-format +msgid "Exporting %s (%d x %d)" +msgstr "Izvoz %s (%d x %d)" + +#: ../../po/../src/dialogs/export.cpp:1031 +#, c-format +msgid "Could not export to filename %s.\n" +msgstr "Ne mogu da izvezem u datoteku %s.\n" + +#: ../../po/../src/dialogs/export.cpp:1137 +msgid "Select a filename for exporting" +msgstr "Odaberite naziv datoteke za izvoz" + +#: ../../po/../src/dialogs/filedialog.cpp:367 +msgid "No preview" +msgstr "Nema prikaza" + +#: ../../po/../src/dialogs/filedialog.cpp:468 +msgid "too large for preview" +msgstr "previÅ¡e veliko da bi se prikazalo" + +#: ../../po/../src/dialogs/filedialog.cpp:762 +#: ../../po/../src/dialogs/filedialog.cpp:763 +msgid "All Images" +msgstr "Sve slike" + +#: ../../po/../src/dialogs/filedialog.cpp:767 +#: ../../po/../src/dialogs/filedialog.cpp:768 +msgid "All Files" +msgstr "Sve datoteke" + +#: ../../po/../src/dialogs/filedialog.cpp:774 +#: ../../po/../src/dialogs/filedialog.cpp:775 +msgid "All Inkscape Files" +msgstr "Sve Inkskejp datoteke" + +#: ../../po/../src/dialogs/filedialog.cpp:1176 +msgid "Guess from extension" +msgstr "Prepoznaj po nastavku" + +#. ###### Add the file types menu +#. createFilterMenu(); +#. ###### Do we want the .xxx extension automatically added? +#: ../../po/../src/dialogs/filedialog.cpp:1261 +msgid "Append filename extension automatically" +msgstr "Automatski dodaj ekstenziju datoteke" + +#. TRANSLATORS: "%s" is replaced with "exact" or "partial" when this string is displayed +#: ../../po/../src/dialogs/find.cpp:378 +#, c-format +msgid "%d object found (out of %d), %s match." +msgid_plural "%d objects found (out of %d), %s match." +msgstr[0] "" +"%d objekat pronađen (od ukupno %d), %s odgovara uslovu" +msgstr[1] "" +"%d objekata pronađeno (od ukupno %d), %s odgovara uslovu" + +#: ../../po/../src/dialogs/find.cpp:381 +msgid "exact" +msgstr "apsolutno" + +#: ../../po/../src/dialogs/find.cpp:381 +msgid "partial" +msgstr "delimično" + +#: ../../po/../src/dialogs/find.cpp:388 +msgid "No objects found" +msgstr "Nema pronađenih objekata" + +#: ../../po/../src/dialogs/find.cpp:546 +msgid "T_ype: " +msgstr "_Vrsta: " + +#: ../../po/../src/dialogs/find.cpp:553 +msgid "Search in all object types" +msgstr "Traži u svim vrstama objekata" + +#: ../../po/../src/dialogs/find.cpp:553 +msgid "All types" +msgstr "Sve vrste" + +#: ../../po/../src/dialogs/find.cpp:564 +msgid "Search all shapes" +msgstr "Traži među oblicima" + +#: ../../po/../src/dialogs/find.cpp:564 +msgid "All shapes" +msgstr "Svi oblici" + +#: ../../po/../src/dialogs/find.cpp:581 +msgid "Search rectangles" +msgstr "Traži među pravougaonicima" + +#: ../../po/../src/dialogs/find.cpp:581 +msgid "Rectangles" +msgstr "Pravougaonici" + +#: ../../po/../src/dialogs/find.cpp:586 +msgid "Search ellipses, arcs, circles" +msgstr "Traži među elipsama, uglovima i kružnicama" + +#: ../../po/../src/dialogs/find.cpp:586 +msgid "Ellipses" +msgstr "Elipse" + +#: ../../po/../src/dialogs/find.cpp:591 +msgid "Search stars and polygons" +msgstr "Traži među zvezdama i poligonima" + +#: ../../po/../src/dialogs/find.cpp:591 +msgid "Stars" +msgstr "Zvezde" + +#: ../../po/../src/dialogs/find.cpp:596 +msgid "Search spirals" +msgstr "Traži među spiralama" + +#: ../../po/../src/dialogs/find.cpp:596 +msgid "Spirals" +msgstr "Spirale" + +#. TRANSLATORS: polyline is a set of connected straight line segments +#. http://www.w3.org/TR/SVG11/shapes.html#PolylineElement +#: ../../po/../src/dialogs/find.cpp:609 +msgid "Search paths, lines, polylines" +msgstr "Traži među krivama, linijama i sastavnim linijama" + +#: ../../po/../src/dialogs/find.cpp:609 +msgid "Paths" +msgstr "Krive" + +#: ../../po/../src/dialogs/find.cpp:614 +msgid "Search text objects" +msgstr "Traži među tekstualnim objektima" + +#: ../../po/../src/dialogs/find.cpp:614 +msgid "Texts" +msgstr "Tekst" + +#: ../../po/../src/dialogs/find.cpp:619 +msgid "Search groups" +msgstr "Traži među grupama" + +#: ../../po/../src/dialogs/find.cpp:619 +msgid "Groups" +msgstr "Grupe" + +#: ../../po/../src/dialogs/find.cpp:624 +msgid "Search clones" +msgstr "Traži među klonovima" + +#: ../../po/../src/dialogs/find.cpp:629 +msgid "Search images" +msgstr "Traži među slikama" + +#: ../../po/../src/dialogs/find.cpp:629 +msgid "Images" +msgstr "Slike" + +#: ../../po/../src/dialogs/find.cpp:634 +msgid "Search offset objects" +msgstr "Traži među razmaknutim objektima" + +#: ../../po/../src/dialogs/find.cpp:634 +msgid "Offsets" +msgstr "Razmaknuti" + +#: ../../po/../src/dialogs/find.cpp:694 +msgid "_Text: " +msgstr "_Tekst: " + +#: ../../po/../src/dialogs/find.cpp:694 +msgid "Find objects by their text content (exact or partial match)" +msgstr "Traži objekte po sadržaju teksta (apsolutno ili delimično poklapanje)" + +#: ../../po/../src/dialogs/find.cpp:695 +msgid "_ID: " +msgstr "_ID: " + +#: ../../po/../src/dialogs/find.cpp:695 +msgid "Find objects by the value of the id attribute (exact or partial match)" +msgstr "" +"Traži objekte po sadržaju osobine „ID“ (apsolutno ili delimično poklapanje)" + +#: ../../po/../src/dialogs/find.cpp:696 +msgid "_Style: " +msgstr "_Stil: " + +#: ../../po/../src/dialogs/find.cpp:696 +msgid "" +"Find objects by the value of the style attribute (exact or partial match)" +msgstr "" +"Traži objekte po sadržaju osobine „stil“ (apsolutno ili delimično poklapanje)" + +#: ../../po/../src/dialogs/find.cpp:697 +msgid "_Attribute: " +msgstr "_Osobina: " + +#: ../../po/../src/dialogs/find.cpp:697 +msgid "Find objects by the name of an attribute (exact or partial match)" +msgstr "Traži objekte po nazivu osobine (apsolutno ili delimično poklapanje)" + +#: ../../po/../src/dialogs/find.cpp:711 +msgid "Search in s_election" +msgstr "Traži u _izboru" + +#: ../../po/../src/dialogs/find.cpp:715 +msgid "Limit search to the current selection" +msgstr "Ograniči pretragu na trenutni izbor" + +#: ../../po/../src/dialogs/find.cpp:720 +msgid "Search in current _layer" +msgstr "Pretraga u aktivnom _sloju" + +#: ../../po/../src/dialogs/find.cpp:724 +msgid "Limit search to the current layer" +msgstr "Ograničavanje pretrage na trenutno odabrani sloj" + +#: ../../po/../src/dialogs/find.cpp:729 +msgid "Include _hidden" +msgstr "Uključi _skrivene" + +#: ../../po/../src/dialogs/find.cpp:733 +msgid "Include hidden objects in search" +msgstr "Uključi skrivene objekte u pretrgu" + +#: ../../po/../src/dialogs/find.cpp:738 +msgid "Include l_ocked" +msgstr "Uključi _zaključane" + +#: ../../po/../src/dialogs/find.cpp:742 +msgid "Include locked objects in search" +msgstr "Uključi zaključane objekte u pretragu" + +#: ../../po/../src/dialogs/find.cpp:753 +msgid "Clear values" +msgstr "Očisti vrednosti" + +#: ../../po/../src/dialogs/find.cpp:754 +msgid "_Find" +msgstr "_Traži" + +#: ../../po/../src/dialogs/find.cpp:754 +msgid "Select objects matching all of the fields you filled in" +msgstr "Izaberi objekte koji ispunjavaju sve zadate uslove" + +#: ../../po/../src/dialogs/iconpreview.cpp:145 +#, c-format +msgid "%d x %d" +msgstr "" + +#: ../../po/../src/dialogs/iconpreview.cpp:193 +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:857 +#: ../../po/../src/widgets/desktop-widget.cpp:1069 +msgid "Selection" +msgstr "Izbor" + +#: ../../po/../src/dialogs/iconpreview.cpp:195 +#, fuzzy +msgid "Selection only or whole document" +msgstr "Izaberi samo u trenutnom sloju" + +#: ../../po/../src/dialogs/iconpreview.cpp:203 +msgid "Refresh the icons" +msgstr "Osveži ikonice" + +#. Create the label for the object id +#: ../../po/../src/dialogs/item-properties.cpp:126 +#: ../../po/../src/dialogs/item-properties.cpp:327 +#: ../../po/../src/dialogs/item-properties.cpp:396 +#: ../../po/../src/dialogs/item-properties.cpp:403 +msgid "_Id" +msgstr "_ID" + +#: ../../po/../src/dialogs/item-properties.cpp:135 +msgid "" +"The id= attribute (only letters, digits, and the characters .-_: allowed)" +msgstr "Atribut id= (samo sliva, brojevi i znaci .-_: dozvoljeno" + +#. Button for setting the object's id, label, title and description. +#: ../../po/../src/dialogs/item-properties.cpp:149 +msgid "_Set" +msgstr "_Postavi" + +#. Create the label for the object label +#: ../../po/../src/dialogs/item-properties.cpp:158 +msgid "_Label" +msgstr "_Oznaka" + +#: ../../po/../src/dialogs/item-properties.cpp:167 +msgid "A freeform label for the object" +msgstr "Slobodna oznaka za objekat" + +#. Create the label for the object title +#: ../../po/../src/dialogs/item-properties.cpp:179 +#: ../../po/../src/dialogs/rdf.cpp:243 +msgid "Title" +msgstr "Naslov" + +#. Create the frame for the object description +#: ../../po/../src/dialogs/item-properties.cpp:196 +#: ../../po/../src/dialogs/rdf.cpp:287 +msgid "Description" +msgstr "Opis" + +#. Hide +#: ../../po/../src/dialogs/item-properties.cpp:223 +msgid "_Hide" +msgstr "_Sakrij" + +#: ../../po/../src/dialogs/item-properties.cpp:224 +msgid "Check to make the object invisible" +msgstr "Aktivirajte da učinite objekat nevidljivim" + +#. Lock +#. TRANSLATORS: "Lock" is a verb here +#: ../../po/../src/dialogs/item-properties.cpp:233 +msgid "L_ock" +msgstr "_Zaključaj" + +#: ../../po/../src/dialogs/item-properties.cpp:234 +msgid "Check to make the object insensitive (not selectable by mouse)" +msgstr "" +"Aktivirajte da učinite objekat neosetljivim (nije ga moguće izabrati miÅ¡em)" + +#: ../../po/../src/dialogs/item-properties.cpp:310 +#: ../../po/../src/dialogs/item-properties.cpp:317 +msgid "Ref" +msgstr "Referenca" + +#: ../../po/../src/dialogs/item-properties.cpp:398 +msgid "Id invalid! " +msgstr "ID je neispravan! " + +#: ../../po/../src/dialogs/item-properties.cpp:400 +msgid "Id exists! " +msgstr "ID postoji! " + +#: ../../po/../src/dialogs/layer-properties.cpp:50 +msgid "Layer name:" +msgstr "Naziv sloja:" + +#: ../../po/../src/dialogs/layer-properties.cpp:133 +msgid "Rename Layer" +msgstr "Preimenuj sloj" + +#: ../../po/../src/dialogs/layer-properties.cpp:136 +msgid "_Rename" +msgstr "_Preimenuj" + +#. TRANSLATORS: This means "The layer has been renamed" +#: ../../po/../src/dialogs/layer-properties.cpp:147 +msgid "Renamed layer" +msgstr "Sloj je preimenovan" + +#: ../../po/../src/dialogs/layer-properties.cpp:151 +msgid "Add Layer" +msgstr "Dodavanje sloja" + +#: ../../po/../src/dialogs/layer-properties.cpp:153 +msgid "_Add" +msgstr "_Dodaj" + +#: ../../po/../src/dialogs/layer-properties.cpp:167 +msgid "New layer created." +msgstr "Napravljen je novi sloj." + +#: ../../po/../src/dialogs/object-attributes.cpp:34 +msgid "Href:" +msgstr "Adresa:" + +#: ../../po/../src/dialogs/object-attributes.cpp:35 +msgid "Target:" +msgstr "OdrediÅ¡te:" + +#: ../../po/../src/dialogs/object-attributes.cpp:36 +msgid "Type:" +msgstr "Vrsta:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkRoleAttribute +#. Identifies the type of the related resource with an absolute URI +#: ../../po/../src/dialogs/object-attributes.cpp:39 +msgid "Role:" +msgstr "Uloga:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkArcRoleAttribute +#. For situations where the nature/role alone isn't enough, this offers an additional URI defining the purpose of the link. +#: ../../po/../src/dialogs/object-attributes.cpp:42 +msgid "Arcrole:" +msgstr "Lučna uloga:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkTitleAttribute +#: ../../po/../src/dialogs/object-attributes.cpp:44 +msgid "Title:" +msgstr "Naslov:" + +#: ../../po/../src/dialogs/object-attributes.cpp:45 +msgid "Show:" +msgstr "Prikaži:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkActuateAttribute +#: ../../po/../src/dialogs/object-attributes.cpp:47 +msgid "Actuate:" +msgstr "Pokreni:" + +#: ../../po/../src/dialogs/object-attributes.cpp:52 +msgid "URL:" +msgstr "Adresa:" + +#: ../../po/../src/dialogs/object-attributes.cpp:53 +msgid "X:" +msgstr "X:" + +#: ../../po/../src/dialogs/object-attributes.cpp:54 +msgid "Y:" +msgstr "Y:" + +#: ../../po/../src/dialogs/object-attributes.cpp:98 +#, c-format +msgid "%s attributes" +msgstr "Osobine za %s" + +#: ../../po/../src/dialogs/object-properties.cpp:158 +msgid "_Fill" +msgstr "_Popuna" + +#: ../../po/../src/dialogs/object-properties.cpp:165 +msgid "Stroke _paint" +msgstr "_Linija" + +#: ../../po/../src/dialogs/object-properties.cpp:172 +msgid "Stroke st_yle" +msgstr "S_til linije" + +#: ../../po/../src/dialogs/object-properties.cpp:183 +msgid "Master _opacity" +msgstr "Osnovna _providnost" + +#: ../../po/../src/dialogs/rdf.cpp:244 +msgid "Name by which this document is formally known." +msgstr "Naziv pod kojim će ovaj dokument biti formalno poznat." + +#: ../../po/../src/dialogs/rdf.cpp:246 +msgid "Date" +msgstr "Datum" + +#: ../../po/../src/dialogs/rdf.cpp:247 +msgid "Date associated with the creation of this document (YYYY-MM-DD)." +msgstr "Datum koji predstavlja datum pravljenja ovog dokumenta (YYYY-MM-DD)." + +#: ../../po/../src/dialogs/rdf.cpp:249 +msgid "Format" +msgstr "Format" + +#: ../../po/../src/dialogs/rdf.cpp:250 +msgid "The physical or digital manifestation of this document (MIME type)." +msgstr "Fizičko ili digitalno predstavljanje ovog dokumenta (MIME vrsta)." + +#: ../../po/../src/dialogs/rdf.cpp:252 +msgid "Type" +msgstr "Vrsta" + +#: ../../po/../src/dialogs/rdf.cpp:253 +msgid "Type of document (DCMI Type)." +msgstr "Vrsta dokumenta (DCMI vrsta)." + +#: ../../po/../src/dialogs/rdf.cpp:256 +msgid "Creator" +msgstr "Autor" + +#: ../../po/../src/dialogs/rdf.cpp:257 +msgid "" +"Name of entity primarily responsible for making the content of this document." +msgstr "" +"Nazim primarnog stvaraoca koji je odgovoran za pravljenje sadržaja dokumenta." + +#: ../../po/../src/dialogs/rdf.cpp:259 +msgid "Rights" +msgstr "Prava" + +#: ../../po/../src/dialogs/rdf.cpp:260 +msgid "" +"Name of entity with rights to the Intellectual Property of this document." +msgstr "Naziv entiteta koji ima prava na intelektualnu svojinu ovog dokumenta." + +#: ../../po/../src/dialogs/rdf.cpp:262 +msgid "Publisher" +msgstr "Izdavač" + +#: ../../po/../src/dialogs/rdf.cpp:263 +msgid "Name of entity responsible for making this document available." +msgstr "Naziv entiteta koji je odgovoran za objavljivanje ovog dokumenta." + +#: ../../po/../src/dialogs/rdf.cpp:266 +msgid "Identifier" +msgstr "Identifikator" + +#: ../../po/../src/dialogs/rdf.cpp:267 +msgid "Unique URI to reference this document." +msgstr "Jedinstveni URL kome je referenca ovaj dokument." + +#: ../../po/../src/dialogs/rdf.cpp:269 +msgid "Source" +msgstr "Izvor" + +#: ../../po/../src/dialogs/rdf.cpp:270 +msgid "Unique URI to reference the source of this document." +msgstr "Jedinstveni URL kome je referenca izvorni kôd ovog dokumenta." + +#: ../../po/../src/dialogs/rdf.cpp:272 +msgid "Relation" +msgstr "Odnos" + +#: ../../po/../src/dialogs/rdf.cpp:273 +msgid "Unique URI to a related document." +msgstr "Jedinstveni URL za relacioni dokument." + +#: ../../po/../src/dialogs/rdf.cpp:275 +msgid "Language" +msgstr "Jezik" + +#: ../../po/../src/dialogs/rdf.cpp:276 +msgid "" +"Two-letter language tag with optional subtags for the language of this " +"document. (e.g. 'en-GB')" +msgstr "" +"Dvoslovni jezički tag sa opcionalnim podtagovima za jezike dokumenta (npr. " +"„sr_CS“)" + +#: ../../po/../src/dialogs/rdf.cpp:278 +msgid "Keywords" +msgstr "Ključne reči" + +#: ../../po/../src/dialogs/rdf.cpp:279 +msgid "" +"The topic of this document as comma-separated key words, phrases, or " +"classifications." +msgstr "" +"Sadržina dokumenta kao zarezom razdvojene reči, fraze ili klasifikacije." + +#. TRANSLATORS: "Coverage": the spatial or temporal characteristics of the content. +#. For info, see Appendix D of http://www.w3.org/TR/1998/WD-rdf-schema-19980409/ +#: ../../po/../src/dialogs/rdf.cpp:283 +msgid "Coverage" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:284 +msgid "Extent or scope of this document." +msgstr "Područje dokrumenta." + +#: ../../po/../src/dialogs/rdf.cpp:288 +msgid "A short account of the content of this document." +msgstr "" + +#. FIXME: need to handle 1 agent per line of input +#: ../../po/../src/dialogs/rdf.cpp:292 +msgid "Contributors" +msgstr "Prilagači" + +#: ../../po/../src/dialogs/rdf.cpp:293 +msgid "" +"Names of entities responsible for making contributions to the content of " +"this document." +msgstr "Nazivi entiteta koji su učstvovali na stvaranju sadržaja dokumenta." + +#. TRANSLATORS: URL to a page that defines the license for the document +#: ../../po/../src/dialogs/rdf.cpp:297 +msgid "URI" +msgstr "URL" + +#. TRANSLATORS: this is where you put a URL to a page that defines the license +#: ../../po/../src/dialogs/rdf.cpp:299 +msgid "URI to this document's license's namespace definition." +msgstr "URL do definicije licence ovog dokumenta." + +#. TRANSLATORS: fragment of XML representing the license of the document +#: ../../po/../src/dialogs/rdf.cpp:303 +msgid "Fragment" +msgstr "Delovi" + +#: ../../po/../src/dialogs/rdf.cpp:304 +msgid "XML fragment for the RDF 'License' section." +msgstr "XML delovi za RDF deo licence." + +#: ../../po/../src/dialogs/stroke-style.cpp:774 +#: ../../po/../src/widgets/gradient-vector.cpp:263 +#: ../../po/../src/widgets/paint-selector.cpp:751 +msgid "No document selected" +msgstr "Niste izabrali dokument" + +#: ../../po/../src/dialogs/stroke-style.cpp:992 +msgid "Stroke width" +msgstr "Å irina poteza" + +#. Join type +#. TRANSLATORS: The line join style specifies the shape to be used at the +#. corners of paths. It can be "miter", "round" or "bevel". +#: ../../po/../src/dialogs/stroke-style.cpp:1015 +msgid "Join:" +msgstr "Priključi:" + +#. TRANSLATORS: Miter join: joining lines with a sharp (pointed) corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1027 +msgid "Miter join" +msgstr "OÅ¡tri spojevivi" + +#. TRANSLATORS: Round join: joining lines with a rounded corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1035 +msgid "Round join" +msgstr "Zaobljeni spojevi" + +#. TRANSLATORS: Bevel join: joining lines with a blunted (flattened) corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1043 +msgid "Bevel join" +msgstr "Ravni spojevi" + +#. Miterlimit +#. TRANSLATORS: Miter limit: only for "miter join", this limits the length +#. of the sharp "spike" when the lines connect at too sharp an angle. +#. When two line segments meet at a sharp angle, a miter join results in a +#. spike that extends well beyond the connection point. The purpose of the +#. miter limit is to cut off such spikes (i.e. convert them into bevels) +#. when they become too long. +#: ../../po/../src/dialogs/stroke-style.cpp:1054 +msgid "Miter limit:" +msgstr "Dužina spoja:" + +#: ../../po/../src/dialogs/stroke-style.cpp:1062 +msgid "Maximum length of the miter (in units of stroke width)" +msgstr "Maksimalna dužina oÅ¡trih spojeva (u jedinicama Å¡irine linije)" + +#. Cap type +#. TRANSLATORS: cap type specifies the shape for the ends of lines +#: ../../po/../src/dialogs/stroke-style.cpp:1075 +msgid "Cap:" +msgstr "ZavrÅ¡etak:" + +#. TRANSLATORS: Butt cap: the line shape does not extend beyond the end point +#. of the line; the ends of the line are square +#: ../../po/../src/dialogs/stroke-style.cpp:1086 +msgid "Butt cap" +msgstr "Ravan zavrÅ¡etak" + +#. TRANSLATORS: Round cap: the line shape extends beyond the end point of the +#. line; the ends of the line are rounded +#: ../../po/../src/dialogs/stroke-style.cpp:1093 +msgid "Round cap" +msgstr "Zaobljeni zavrÅ¡etak" + +#. TRANSLATORS: Square cap: the line shape extends beyond the end point of the +#. line; the ends of the line are square +#: ../../po/../src/dialogs/stroke-style.cpp:1100 +msgid "Square cap" +msgstr "Kvadratni zavrÅ¡etak" + +#. Dash +#: ../../po/../src/dialogs/stroke-style.cpp:1106 +msgid "Dashes:" +msgstr "Linija:" + +#. TRANSLATORS: Path markers are an SVG feature that allows you to attach arbitrary shapes +#. (arrowheads, bullets, faces, whatever) to the start, end, or middle nodes of a path. +#: ../../po/../src/dialogs/stroke-style.cpp:1127 +msgid "Start Markers:" +msgstr "Početak:" + +#: ../../po/../src/dialogs/stroke-style.cpp:1137 +msgid "Mid Markers:" +msgstr "Sredina:" + +#: ../../po/../src/dialogs/stroke-style.cpp:1148 +msgid "End Markers:" +msgstr "ZavrÅ¡etak:" + +#: ../../po/../src/dialogs/swatches.cpp:424 +#, c-format +msgid "Palettes directory (%s) is unavailable." +msgstr "Direktorijum paleta (%s) nije dostupan." + +#. TODO: Insert widgets +#: ../../po/../src/dialogs/text-edit.cpp:199 +#: ../../po/../src/ui/dialog/text-properties.cpp:36 +msgid "Font" +msgstr "Font" + +#: ../../po/../src/dialogs/text-edit.cpp:216 +msgid "Layout" +msgstr "Raspored" + +#: ../../po/../src/dialogs/text-edit.cpp:229 +msgid "Align lines left" +msgstr "Levo poravnanje" + +#. TRANSLATORS: `Center' here is a verb. +#: ../../po/../src/dialogs/text-edit.cpp:243 +msgid "Center lines" +msgstr "Centralno poravnanje" + +#: ../../po/../src/dialogs/text-edit.cpp:256 +msgid "Align lines right" +msgstr "Desno poravnanje" + +#: ../../po/../src/dialogs/text-edit.cpp:278 +msgid "Horizontal text" +msgstr "Vodoravni tekst" + +#: ../../po/../src/dialogs/text-edit.cpp:292 +msgid "Vertical text" +msgstr "Uspravni tekst" + +#: ../../po/../src/dialogs/text-edit.cpp:307 +msgid "Line spacing:" +msgstr "Razmak linija:" + +#: ../../po/../src/dialogs/text-edit.cpp:400 +msgid "Set as default" +msgstr "Postavi kao podrazumevano" + +#: ../../po/../src/dialogs/tiledialog.cpp:603 +msgid "Rows:" +msgstr "Redova:" + +#: ../../po/../src/dialogs/tiledialog.cpp:613 +msgid "Number of rows" +msgstr "Broj redova" + +#: ../../po/../src/dialogs/tiledialog.cpp:617 +msgid "Equal height" +msgstr "Ista visina" + +#: ../../po/../src/dialogs/tiledialog.cpp:627 +msgid "If not set, each row has the height of the tallest object in it" +msgstr "Ako nije postavljeno, svaki red ima visinu najviÅ¡eg objekta u njemu" + +#. #### Radio buttons to control vertical alignment #### +#. #### Radio buttons to control horizontal alignment #### +#: ../../po/../src/dialogs/tiledialog.cpp:637 +#: ../../po/../src/dialogs/tiledialog.cpp:708 +msgid "Align:" +msgstr "Poravnanje:" + +#: ../../po/../src/dialogs/tiledialog.cpp:672 +msgid " X " +msgstr " X " + +#. #### Number of columns #### +#: ../../po/../src/dialogs/tiledialog.cpp:678 +msgid "Columns:" +msgstr "Kolona:" + +#: ../../po/../src/dialogs/tiledialog.cpp:688 +msgid "Number of columns" +msgstr "Broj kolona" + +#: ../../po/../src/dialogs/tiledialog.cpp:692 +msgid "Equal width" +msgstr "Ista Å¡irina" + +#: ../../po/../src/dialogs/tiledialog.cpp:701 +msgid "If not set, each column has the width of the widest object in it" +msgstr "Ako nije psotavljeno, svaka kolona ima Å¡irinu najÅ¡ireg objekta u njemu" + +#. #### Radio buttons to control spacing manually or to fit selection bbox #### +#: ../../po/../src/dialogs/tiledialog.cpp:746 +msgid "Fit into selection box" +msgstr "Prilagodi izaboru" + +#: ../../po/../src/dialogs/tiledialog.cpp:753 +msgid "Set spacing:" +msgstr "Postavi rastojanje:" + +#. #### Y Padding #### +#: ../../po/../src/dialogs/tiledialog.cpp:777 +msgid "Row spacing: " +msgstr "Razmak redova:" + +#: ../../po/../src/dialogs/tiledialog.cpp:786 +msgid "Vertical spacing between rows" +msgstr "Uspravni razmak između redova" + +#. #### X padding #### +#: ../../po/../src/dialogs/tiledialog.cpp:795 +msgid "Column spacing:" +msgstr "Razmak kolona:" + +#: ../../po/../src/dialogs/tiledialog.cpp:804 +msgid "Horizontal spacing between columns" +msgstr "Vodoravni razmak između kolona" + +#: ../../po/../src/dialogs/tiledialog.cpp:818 +#, fuzzy +msgid "Arrange selected objects" +msgstr "GrupiÅ¡i izabrane objekte" + +#: ../../po/../src/dialogs/xml-tree.cpp:178 +msgid "Click to select nodes, drag to rearrange." +msgstr "Klik za izbor čvora, prevlačenje za preuređivanje." + +#: ../../po/../src/dialogs/xml-tree.cpp:189 +msgid "Click attribute to edit." +msgstr "Klik na atribut za uređivanje" + +#: ../../po/../src/dialogs/xml-tree.cpp:193 +#, c-format +msgid "" +"Attribute %s selected. Press Ctrl+Enter when done editing to " +"commit changes." +msgstr "" +"Izabran je atribut %s. Pritisnite Ctrl+Enter kada zavrÅ¡ite " +"uređivanje da bi izmene bile prihvaćene." + +#: ../../po/../src/dialogs/xml-tree.cpp:284 +msgid "Drag to reorder nodes" +msgstr "Prevucite za preraspodeđivanje čvorova" + +#: ../../po/../src/dialogs/xml-tree.cpp:304 +msgid "New element node" +msgstr "Novi čvor u elementu" + +#: ../../po/../src/dialogs/xml-tree.cpp:326 +msgid "New text node" +msgstr "Novi čvor za tekst" + +#: ../../po/../src/dialogs/xml-tree.cpp:347 +msgid "Duplicate node" +msgstr "Udvostruči čvor" + +#: ../../po/../src/dialogs/xml-tree.cpp:368 +msgid "Delete node" +msgstr "Ukloni čvor" + +#: ../../po/../src/dialogs/xml-tree.cpp:384 +msgid "Unindent node" +msgstr "Izvuci čvor" + +#: ../../po/../src/dialogs/xml-tree.cpp:399 +msgid "Indent node" +msgstr "Uvuci čvor" + +#: ../../po/../src/dialogs/xml-tree.cpp:411 +msgid "Raise node" +msgstr "Izdigni čvor" + +#: ../../po/../src/dialogs/xml-tree.cpp:423 +msgid "Lower node" +msgstr "Zakloni čvor" + +#: ../../po/../src/dialogs/xml-tree.cpp:468 +msgid "Delete attribute" +msgstr "ObriÅ¡i osobinu" + +#. TRANSLATORS: "Attribute" is a noun here +#: ../../po/../src/dialogs/xml-tree.cpp:513 +msgid "Attribute name" +msgstr "Naziv osobine" + +#. TRANSLATORS: "Set" is a verb here +#: ../../po/../src/dialogs/xml-tree.cpp:533 +msgid "Set attribute" +msgstr "Postavi osobinu" + +#. TRANSLATORS: "Set" is a verb here +#: ../../po/../src/dialogs/xml-tree.cpp:535 +msgid "Set" +msgstr "Postavi" + +#. TRANSLATORS: "Attribute" is a noun here +#: ../../po/../src/dialogs/xml-tree.cpp:558 +msgid "Attribute value" +msgstr "Vrednost osobine" + +#: ../../po/../src/dialogs/xml-tree.cpp:1318 +msgid "New element node..." +msgstr "Novi čvor elementa..." + +#: ../../po/../src/dialogs/xml-tree.cpp:1339 +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:100 +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:98 +msgid "Cancel" +msgstr "Otkaži" + +#: ../../po/../src/dialogs/xml-tree.cpp:1345 +msgid "Create" +msgstr "Napravi" + +#: ../../po/../src/dialogs/xml-tree.cpp:1458 +#, c-format +msgid "" +"Cannot set %s: Another element with value %s already exists!" +msgstr "" +"Ne mogu da postavim %s: Već postoji atribut sa vrednošću %s" + +#: ../../po/../src/document.cpp:369 +#, c-format +msgid "New document %d" +msgstr "Novi dokument %d" + +#: ../../po/../src/document.cpp:401 +#, c-format +msgid "Memory document %d" +msgstr "Memorijski dokument %d" + +#: ../../po/../src/document.cpp:524 +#, c-format +msgid "Unnamed document %d" +msgstr "Neimenovani dokument %d" + +#. We hit green anchor, closing Green-Blue-Red +#: ../../po/../src/draw-context.cpp:441 +msgid "Path is closed." +msgstr "Kriva je zatvorena." + +#. We hit bot start and end of single curve, closing paths +#: ../../po/../src/draw-context.cpp:456 +msgid "Closing path." +msgstr "Zatvaranje krive." + +#. alpha of color under cursor, to show in the statusbar +#. locale-sensitive printf is OK, since this goes to the UI, not into SVG +#: ../../po/../src/dropper-context.cpp:354 +#, c-format +msgid " alpha %.3g" +msgstr " providnost %.3g" + +#. where the color is picked, to show in the statusbar +#: ../../po/../src/dropper-context.cpp:356 +#, c-format +msgid ", averaged with radius %d" +msgstr ", presek poluprečnika %d" + +#: ../../po/../src/dropper-context.cpp:356 +msgid " under cursor" +msgstr " pod kursorom" + +#. message, to show in the statusbar +#: ../../po/../src/dropper-context.cpp:358 +msgid "Release mouse to set color." +msgstr "Otpustite taster miÅ¡a za postavljanje boje." + +#: ../../po/../src/dropper-context.cpp:358 +#: ../../po/../src/tools-switch.cpp:207 +msgid "" +"Click to set fill, Shift+click to set stroke; drag to " +"average color in area; with Alt to pick inverse color; Ctrl+C " +"to copy the color under mouse to clipboard" +msgstr "" +"Klik postavlja popunu, Shift+klik liniju. Prevlačenjem " +"se uzima prosečna boja povrÅ¡ine. Alt za izokrenutu boju. Ctrl+C za kopiranje boje ispod kursora u klipbord" + +#: ../../po/../src/extension/dependency.cpp:244 +msgid "Dependency::" +msgstr "zavisnost::" + +#: ../../po/../src/extension/dependency.cpp:245 +msgid " type: " +msgstr " vrsta: " + +#: ../../po/../src/extension/dependency.cpp:246 +msgid " location: " +msgstr " lokacija: " + +#: ../../po/../src/extension/dependency.cpp:247 +msgid " string: " +msgstr " tekst: " + +#: ../../po/../src/extension/dependency.cpp:250 +msgid " description: " +msgstr " opis: " + +#. static int i = 0; +#. std::cout << "Checking module[" << i++ << "]: " << name << std::endl; +#: ../../po/../src/extension/extension.cpp:244 +msgid "" +" This is caused by an improper .inx file for this extension. An improper ." +"inx file could have been caused by a faulty installation of Inkscape." +msgstr "" +" Ovo je prouzrokovano neprikladnom .inx datotekom za ovu ekstenziju. " +"Neprikladna.inx datoteka može da bude rezultat greÅ¡ke pri instalaciji " +"Inkskejpa." + +#: ../../po/../src/extension/extension.cpp:247 +msgid "an ID was not defined for it." +msgstr "ID nije određen za nju." + +#: ../../po/../src/extension/extension.cpp:251 +msgid "there was no name defined for it." +msgstr "naziv nije određen za nju." + +#: ../../po/../src/extension/extension.cpp:255 +msgid "the XML description of it got lost." +msgstr "izgubljen je XML opis za nju." + +#: ../../po/../src/extension/extension.cpp:259 +msgid "no implementation was defined for the extension." +msgstr "izvrÅ¡avanje nije postavljeno za ekstenziju." + +#. std::cout << "Failed: " << *(_deps[i]) << std::endl; +#: ../../po/../src/extension/extension.cpp:266 +msgid "a dependency was not met." +msgstr "zavisnost nije pronađena." + +#: ../../po/../src/extension/extension.cpp:286 +msgid "Extension \"" +msgstr "ProÅ¡irenje „" + +#: ../../po/../src/extension/extension.cpp:286 +msgid "\" failed to load because " +msgstr "“ ne može da se učita zato Å¡to " + +#: ../../po/../src/extension/extension.cpp:565 +#, c-format +msgid "Could not create extension error log file '%s'" +msgstr "Ne mogu da napravim dnevnik greÅ¡aka proÅ¡irenja „%s“" + +#. This is some filler text, needs to change before relase +#: ../../po/../src/extension/error-file.cpp:56 +msgid "" +"One or more extensions failed to load\n" +"\n" +"The failed extensions have been skipped. Inkscape will continue to run " +"normally but those extensions will be unavailable. For details to " +"troubleshoot this problem, please refer to the error log located at: " +msgstr "" +"Jedna ili viÅ¡e ekstenzija neuspeÅ¡no " +"učitana\n" +"\n" +"Problematične ekstenzije su preskočene. Inkskejp će nastaviti izvrÅ¡avanje, " +"ali ove ekstenzije neće biti dostupne. Za detalje o otklanjanju ovih " +"greÅ¡aka, pogledajte dnevnik gerÅ¡aka sačuvan u: " + +#. This is some filler text, needs to change before relase +#: ../../po/../src/extension/error-file.cpp:65 +msgid "Show dialog on startup" +msgstr "Prikaži ovu poruku pri svakom pokretanju programa" + +#: ../../po/../src/extension/implementation/script.cpp:845 +#, fuzzy +msgid "" +"Inkscape has received an error from the script that it called. The text " +"returned with the error is included below. Inkscape will continue working, " +"but the action you requested has been cancelled." +msgstr "" +"Inkscape je dobio greÅ¡ku od pozvane skripte. Dobijeni tekst greÅ¡ke je niže " +"prikazan. Inkscape će nastaviti sa radom, ali je zahtevana akcija " +"obustavljena." + +#: ../../po/../src/extension/implementation/script.cpp:858 +#, fuzzy +msgid "" +"Inkscape has received additional data from the script executed. The script " +"did not return an error, but this may indicate the results will not be as " +"expected." +msgstr "" +"Inkscape je dobio dodatne podatke od skripte koja je izvrÅ¡ena. Skripta nije " +"vratila greÅ¡ku, ali ovo može da znači da rezultat neće izgledati kako se " +"očekuje." + +#: ../../po/../src/extension/init.cpp:173 +msgid "Null external module directory name. Modules will not be loaded." +msgstr "" +"Nema naziva direktorijuma za eksterne module. Nikakvi moduli neće biti " +"učitani." + +#: ../../po/../src/extension/init.cpp:187 +#, c-format +msgid "" +"Modules directory (%s) is unavailable. External modules in that directory " +"will not be loaded." +msgstr "" +"Direktorijum sa modulima (%s) je nedostupan. SpoljaÅ¡nji moduli u tom " +"direktorijumu neće biti učitani." + +#: ../../po/../src/extension/internal/gnome.cpp:80 +msgid "Select printer" +msgstr "Izbor Å¡tampača" + +#: ../../po/../src/extension/internal/gnome.cpp:131 +msgid "Inkscape: Print Preview" +msgstr "Inkskejp: Pregled pred Å¡tampu" + +#: ../../po/../src/extension/internal/grid.cpp:213 +msgid "Line Width" +msgstr "Å irina linije" + +#: ../../po/../src/extension/internal/grid.cpp:214 +msgid "Horizontal Spacing" +msgstr "Vodoravni razmak" + +#: ../../po/../src/extension/internal/grid.cpp:215 +msgid "Vertical Spacing" +msgstr "Uspravni razmak" + +#: ../../po/../src/extension/internal/grid.cpp:216 +msgid "Horizontal Offset" +msgstr "Vodoravni pomeraj" + +#: ../../po/../src/extension/internal/grid.cpp:217 +msgid "Vertical Offset" +msgstr "Uspravni pomeraj" + +#: ../../po/../src/extension/internal/ps.cpp:123 +msgid "Print Destination" +msgstr "OdrediÅ¡te Å¡tampe" + +#. Print properties frame +#: ../../po/../src/extension/internal/ps.cpp:138 +msgid "Print properties" +msgstr "Osobine Å¡tampe" + +#: ../../po/../src/extension/internal/ps.cpp:145 +msgid "Print using PostScript operators" +msgstr "Å tampaj pomoću PostSkript operatora" + +#: ../../po/../src/extension/internal/ps.cpp:147 +msgid "" +"Use PostScript vector operators. The resulting image is usually smaller in " +"file size and can be arbitrarily scaled, but alpha transparency and patterns " +"will be lost." +msgstr "" +"Koriste se vektorski operatori iz PostScript-a. Dobijena slika će verovatno " +"biti umanjena i datoteka će biti manje veličine, ali providnost i obrasci će " +"biti izgubljeni" + +#: ../../po/../src/extension/internal/ps.cpp:152 +msgid "Print as bitmap" +msgstr "Å tampaj kao bitmapu" + +#: ../../po/../src/extension/internal/ps.cpp:154 +msgid "" +"Print everything as bitmap. The resulting image is usually larger in file " +"size and cannot be arbitrarily scaled without quality loss, but all objects " +"will be rendered exactly as displayed." +msgstr "" +"Å tampaće se kao bitmapa. Dobijena slika će verovatno biti veća i neće moći " +"da se uvećava bez gubitka na kvalitetu, Å¡to zavisi od razmere uvećanja, ali " +"sva grafika će se iscrtati isto kao Å¡to je i prikazana" + +#: ../../po/../src/extension/internal/ps.cpp:168 +msgid "Preferred resolution (dots per inch) of bitmap" +msgstr "Željena rezolucija (tačaka po inču) bitmape" + +#: ../../po/../src/extension/internal/ps.cpp:182 +msgid "Resolution:" +msgstr "Rezolucija:" + +#. Print destination frame +#: ../../po/../src/extension/internal/ps.cpp:186 +msgid "Print destination" +msgstr "OdrediÅ¡te Å¡tampe" + +#: ../../po/../src/extension/internal/ps.cpp:192 +msgid "" +"Use '> filename' to print to file.\n" +"Use '| prog arg...' to pipe to a program." +msgstr "" +"Koristite „> datoteka“ za Å¡tampanje u datoteku.\n" +"Koristite „| program argument...“ za prosleđivanje programu." + +#: ../../po/../src/extension/internal/ps.cpp:1227 +msgid "write error occurred" +msgstr "greÅ¡ka pri pisanju" + +#: ../../po/../src/extension/prefdialog.cpp:21 +msgid " Preferences" +msgstr " Postavke" + +#. We can't call sp_ui_error_dialog because we may be +#. running from the console, in which case calling sp_ui +#. routines will cause a segfault. See bug 1000350 - bryce +#. sp_ui_error_dialog(_("Format autodetect failed. The file is being opened as SVG.")); +#: ../../po/../src/extension/system.cpp:105 +msgid "Format autodetect failed. The file is being opened as SVG." +msgstr "" +"Automatsko prepoznavanje formata nije uspelo. Datoteka je otvorena kao SVG." + +#. TRANSLATORS: default.svg is localizable - this is the name of the default document +#. template. This way you can localize the default pagesize, translate the name of +#. the default layer, etc. If you wish to localize this file, please create a +#. localized share/templates/default.xx.svg file, where xx is your language code. +#: ../../po/../src/file.cpp:133 +msgid "default.svg" +msgstr "default.svg" + +#: ../../po/../src/file.cpp:215 ../../po/../src/file.cpp:900 +#, c-format +msgid "Failed to load the requested file %s" +msgstr "Ne moću da učitam zahtevanu datoteku %s" + +#: ../../po/../src/file.cpp:240 +msgid "Document not saved yet. Cannot revert." +msgstr "Dokument joÅ¡ uvek nije sačuvan. Ne mogu da povratim pređaÅ¡nje stanje." + +#: ../../po/../src/file.cpp:246 +#, c-format +msgid "Changes will be lost! Are you sure you want to reload document %s?" +msgstr "" +"Izmene će biti izgubljene! Da li ste sigurni da želite ponovo da učitate " +"dokument %s?" + +#: ../../po/../src/file.cpp:266 +msgid "Document reverted." +msgstr "Dokument povraćen na pređaÅ¡nje stanje." + +#: ../../po/../src/file.cpp:268 +msgid "Document not reverted." +msgstr "Dokument nije povraćen na pređaÅ¡nje stanje." + +#: ../../po/../src/file.cpp:382 +msgid "Select file to open" +msgstr "Izaberite koju datoteku želite da otvorite" + +#: ../../po/../src/file.cpp:518 +#, c-format +msgid "Removed %i unused definition in <defs>." +msgid_plural "Removed %i unused definitions in <defs>." +msgstr[0] "Uklonjena %i neiskorišćena stavka u <defs>." +msgstr[1] "Uklonjeno %i neiskorišćenih stavki u <defs>." + +#: ../../po/../src/file.cpp:523 +msgid "No unused definitions in <defs>." +msgstr "Nema neiskorišćenih stavki u <defs>." + +#: ../../po/../src/file.cpp:548 +#, c-format +msgid "" +"No Inkscape extension found to save document (%s). This may have been " +"caused by an unknown filename extension." +msgstr "" +"Inkskejp ekstenzija za čuvanje dokumenta nije pronađena (%s). Mogući razlog " +"ovome je nepoznata ekstenzija datoteke." + +#: ../../po/../src/file.cpp:549 ../../po/../src/file.cpp:557 +msgid "Document not saved." +msgstr "Dokument nije sačuvan." + +#: ../../po/../src/file.cpp:556 +#, c-format +msgid "File %s could not be saved." +msgstr "Datoteka %s ne može biti sačuvana." + +#: ../../po/../src/file.cpp:566 +msgid "Document saved." +msgstr "Dokument je sačuvan." + +#: ../../po/../src/file.cpp:614 +#, c-format +msgid "drawing%s" +msgstr "crtež%s" + +#: ../../po/../src/file.cpp:620 +#, c-format +msgid "drawing-%d%s" +msgstr "crtež-%d%s" + +#: ../../po/../src/file.cpp:655 +msgid "Select file to save to" +msgstr "Izaberite datoteku u koju želite da sačuvate dokument" + +#: ../../po/../src/file.cpp:739 +msgid "No changes need to be saved." +msgstr "Nema izmena potrebnih za snimanje." + +#: ../../po/../src/file.cpp:926 +msgid "Select file to import" +msgstr "Odaberite datoteku za uvoz" + +#: ../../po/../src/gradient-context.cpp:263 +msgid "Ctrl: snap gradient angle" +msgstr "Ctrl: prijanjanje ugla preliva" + +#: ../../po/../src/gradient-context.cpp:264 +msgid "Shift: draw gradient around the starting point" +msgstr "Shift: iscrtava preliv sa centrom u početnoj tački" + +#. We did an undoable action, but sp_document_done will be called by the knot when released +#. status text; we do not track coords because this branch is run once, not all the time +#. during drag +#: ../../po/../src/gradient-context.cpp:462 +#, c-format +msgid "Gradient for %d objects; with Ctrl to snap angle" +msgstr "Preliv za %d objekata; Ctrl za prijanjanje ugla" + +#: ../../po/../src/gradient-context.cpp:464 +msgid "Select objects on which to create gradient." +msgstr "Izaberite objekat za koji će se napraviti preliv." + +#: ../../po/../src/gradient-drag.cpp:65 +msgid "Linear gradient start" +msgstr "početak linijskog preliva" + +#. POINT_LG_P1 +#: ../../po/../src/gradient-drag.cpp:66 +msgid "Linear gradient end" +msgstr "ZvrÅ¡etak lnijskog preliva" + +#: ../../po/../src/gradient-drag.cpp:67 +msgid "Radial gradient center" +msgstr "Sredina kružnog preliva" + +#: ../../po/../src/gradient-drag.cpp:68 ../../po/../src/gradient-drag.cpp:69 +msgid "Radial gradient radius" +msgstr "Poluprečnik kružnog preliva" + +#: ../../po/../src/gradient-drag.cpp:70 +msgid "Radial gradient focus" +msgstr "Žiža kružnog preliva" + +#: ../../po/../src/gradient-drag.cpp:659 +#, c-format +msgid "" +"%s for: %s%s; drag with Ctrl to snap angle, with Ctrl+Alt to " +"preserve angle, with Ctrl+Shift to scale around center" +msgstr "" +"%s za: %s%s; povlačenje sa Ctrl za prijanjanje ugla, sa Ctrl+Altza zaključavanje ugla, sa Ctrl+Shift za promenu veličine oko sredine" + +#: ../../po/../src/gradient-drag.cpp:662 +msgid " (stroke)" +msgstr " (linija)" + +#: ../../po/../src/gradient-drag.cpp:665 +msgid "" +"Radial gradient center and focus; drag with Shift to " +"separate focus" +msgstr "" +"Sredina i žiža kružnog preliva; prevlačenje sa Shift za " +"razdvajanje žiže" + +#: ../../po/../src/gradient-drag.cpp:667 +#, c-format +msgid "" +"Gradient point shared by %d gradients; drag with Shift to " +"separate" +msgstr "" +"Tačka preliva sadržana u %d preliva; prevlačenje sa Shift za " +"razdvajanje" + +#: ../../po/../src/helper/units.cpp:40 +msgid "Unit" +msgstr "Jedinica mere" + +#: ../../po/../src/helper/units.cpp:40 +msgid "Units" +msgstr "Jedinice mere" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Point" +msgstr "Å¡tamparska tačka" + +#: ../../po/../src/helper/units.cpp:41 +msgid "pt" +msgstr "pt" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Points" +msgstr "Å¡tamparskih tačaka" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Pt" +msgstr "Pt" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Pixel" +msgstr "tačka" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Pixels" +msgstr "tačke" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Px" +msgstr "Px" + +#. You can add new elements from this point forward +#: ../../po/../src/helper/units.cpp:44 ../share/extensions/straightseg.inx.h:2 +msgid "Percent" +msgstr "procenat" + +#: ../../po/../src/helper/units.cpp:44 +msgid "Percents" +msgstr "procenata" + +#: ../../po/../src/helper/units.cpp:45 +msgid "Millimeter" +msgstr "milimetar" + +#: ../../po/../src/helper/units.cpp:45 +msgid "mm" +msgstr "mm" + +#: ../../po/../src/helper/units.cpp:45 +msgid "Millimeters" +msgstr "milimetara" + +#: ../../po/../src/helper/units.cpp:46 +msgid "Centimeter" +msgstr "centimetar" + +#: ../../po/../src/helper/units.cpp:46 +msgid "cm" +msgstr "cm" + +#: ../../po/../src/helper/units.cpp:46 +msgid "Centimeters" +msgstr "centimetara" + +#: ../../po/../src/helper/units.cpp:47 +msgid "Meter" +msgstr "metar" + +#: ../../po/../src/helper/units.cpp:47 +msgid "m" +msgstr "m" + +#: ../../po/../src/helper/units.cpp:47 +msgid "Meters" +msgstr "metara" + +#. no svg_unit +#: ../../po/../src/helper/units.cpp:48 +msgid "Inch" +msgstr "palac" + +#: ../../po/../src/helper/units.cpp:48 +msgid "in" +msgstr "in" + +#: ../../po/../src/helper/units.cpp:48 +msgid "Inches" +msgstr "palaca" + +#. Volatiles do not have default, so there are none here +#. TRANSLATORS: for info, see http://www.w3.org/TR/REC-CSS2/syndata.html#length-units +#: ../../po/../src/helper/units.cpp:51 +msgid "Em square" +msgstr "em kvadrat" + +#: ../../po/../src/helper/units.cpp:51 +msgid "em" +msgstr "em" + +#: ../../po/../src/helper/units.cpp:51 +msgid "Em squares" +msgstr "em kvadrati" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/REC-CSS2/syndata.html#length-units +#: ../../po/../src/helper/units.cpp:53 +msgid "Ex square" +msgstr "eks kvadrat" + +#: ../../po/../src/helper/units.cpp:53 +msgid "ex" +msgstr "ex" + +#: ../../po/../src/helper/units.cpp:53 +msgid "Ex squares" +msgstr "eks kvadrati" + +#: ../../po/../src/inkscape.cpp:468 +msgid "Untitled document" +msgstr "Neimenovani dokument" + +#. Show nice dialog box +#: ../../po/../src/inkscape.cpp:497 +msgid "Inkscape encountered an internal error and will close now.\n" +msgstr "InkSkejp je naiÅ¡ao na unutraÅ¡nju greÅ¡ku i sada će se zatvoriti.\n" + +#: ../../po/../src/inkscape.cpp:498 +msgid "" +"Automatic backups of unsaved documents were done to the following " +"locations:\n" +msgstr "Automatski rezervni primerci nesačuvanih dokumenata se čuvaju u:\n" + +#: ../../po/../src/inkscape.cpp:499 +msgid "Automatic backup of the following documents failed:\n" +msgstr "Nije uspelo automatsko snimanje rezervnog primeraka dokumenta:\n" + +#: ../../po/../src/inkscape.cpp:634 +#, c-format +msgid "" +"Cannot create directory %s.\n" +"%s" +msgstr "" +"Ne mogu da napravim direktorijum %s.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:635 +#, c-format +msgid "" +"%s is not a valid directory.\n" +"%s" +msgstr "" +"%s nije ispravan direktorijum.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:636 +#, c-format +msgid "" +"Cannot create file %s.\n" +"%s" +msgstr "" +"Ne mogu da napravim datoteku %s.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:637 +#, c-format +msgid "" +"Cannot write file %s.\n" +"%s" +msgstr "" +"Ne mogu da zapiÅ¡em datoteku %s.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:638 +msgid "" +"Although Inkscape will run, it will use default settings,\n" +"and any changes made in preferences will not be saved." +msgstr "" +"Iako će InkSkejp biti pokrenut, koristiće se podrazumevana podeÅ¡avanja,\n" +"i bilo kakve izmene u podeÅ¡avanjima neće biti sačuvane." + +#: ../../po/../src/inkscape.cpp:708 +#, c-format +msgid "" +"%s is not a regular file.\n" +"%s" +msgstr "" +"%s nije prava datoteka.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:709 +#, c-format +msgid "" +"%s not a valid XML file, or\n" +"you don't have read permissions on it.\n" +"%s" +msgstr "" +"%s nije ispravna XML datoteka, ili\n" +"nemate prava čitanja za nju.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:711 +#, fuzzy, c-format +msgid "" +"%s is not a valid menus file.\n" +"%s" +msgstr "" +"%s nije ispravna datoteka podeÅ¡avanja.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:712 +#, fuzzy +msgid "" +"Inkscape will run with default menus.\n" +"New menus will not be saved." +msgstr "" +"InkSkejp će biti pokrenut sa podrazumevanim podeÅ¡avanjima.\n" +"Nova podeÅ¡avanja neće biti sačuvana." + +#. sp_ui_menu_append_check_item_from_verb(m, view, _("_Menu"), _("Show or hide the menu bar"), "menu", +#. checkitem_toggled, checkitem_update, 0); +#: ../../po/../src/interface.cpp:753 +msgid "Commands Bar" +msgstr "Linija naredbi" + +#: ../../po/../src/interface.cpp:753 +msgid "Show or hide the Commands bar (under the menu)" +msgstr "Prikaži ili sakrij traku naredbi (ispod menija)" + +#: ../../po/../src/interface.cpp:755 +msgid "Tool Controls" +msgstr "Kontrola alata" + +#: ../../po/../src/interface.cpp:755 +msgid "Show or hide the Tool Controls panel" +msgstr "Prikaži ili sakrij traku za kontrolna podeÅ¡avanja alata" + +#: ../../po/../src/interface.cpp:757 +msgid "_Toolbox" +msgstr "_Alatke" + +#: ../../po/../src/interface.cpp:757 +msgid "Show or hide the main toolbox (on the left)" +msgstr "Prikaži ili sakrij glavnu traku alata (uz levu ivicu)" + +#: ../../po/../src/interface.cpp:763 +msgid "_Statusbar" +msgstr "_Statusna linija" + +#: ../../po/../src/interface.cpp:763 +msgid "Show or hide the statusbar (at the bottom of the window)" +msgstr "Prikaži ili sakrij statustnu liniju (na dnu prozora)" + +#: ../../po/../src/interface.cpp:820 +#, c-format +msgid "Verb \"%s\" Unknown" +msgstr "" + +#. TRANSLATORS: #%s is the id of the group e.g. , not a number. +#: ../../po/../src/interface.cpp:930 +#, c-format +msgid "Enter group #%s" +msgstr "Uđi u grupu #%s" + +#: ../../po/../src/interface.cpp:941 +msgid "Go to parent" +msgstr "Prelazak na roditeljski sloj" + +#: ../../po/../src/interface.cpp:972 +msgid "Could not parse SVG data" +msgstr "Ne mogu da obradim SVG podatke" + +#: ../../po/../src/interface.cpp:1135 +#, c-format +msgid "Overwrite %s" +msgstr "PrepiÅ¡i %s" + +#: ../../po/../src/interface.cpp:1153 +#, c-format +msgid "" +"The file %s already exists. Do you want to overwrite that file with the " +"current document?" +msgstr "" +"Datoteka %s već postoji. Da li želite da je prepiÅ¡ete sa trenutnim " +"dokumentom?" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:59 +msgid "Jabber connection lost." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:72 +#, c-format +msgid "Sending message; %u message remaining in send queue." +msgid_plural "Sending message; %u messages remaining in send queue." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:78 +msgid "Receive queue empty." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:154 +#, c-format +msgid "Receiving change; %u change left to process." +msgid_plural "Receiving change; %u changes left to process." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:157 +#, c-format +msgid "%s has left the chatroom." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:221 +msgid "Nickname %1 is already in use. Please choose a different nickname." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:225 +msgid "An error was encountered while attempting to connect to the server." +msgstr "" + +#. Check to see if the user made any modifications to this document. If so, +#. we want to give them the option of (1) letting us clear their document or (2) +#. opening a new, blank document for the whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:131 +msgid "%1 has invited you to a whiteboard session." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:132 +msgid "Incoming whiteboard invitation from %1" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:135 +msgid "Do you wish to accept %1's whiteboard session invitation?" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:137 +msgid "" +"Would you like to accept %1's invitation in a new document window?\n" +"Accepting the invitation in your current window will discard unsaved changes." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:143 +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:198 +#, fuzzy +msgid "Accept invitation" +msgstr "Ubrzanje" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:144 +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:199 +msgid "Decline invitation" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:145 +#, fuzzy +msgid "Accept invitation in new document window" +msgstr "Napravi novi SVG dokument" + +#. We could not create a new desktop; ask the user if she or he wants to +#. replace the current document and accept the invitation, or reject the invitation. +#. TRANSLATORS: %1 is a userid here +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:196 +msgid "" +"A new document window could not be opened for a whiteboard session with %" +"1" +msgstr "" + +#. TRANSLATORS: %1 is the peer whom refused our invitation. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:238 +msgid "" +"The user %1 has refused your " +"whiteboard invitation.\n" +"\n" +msgstr "" + +#. TRANSLATORS: %1 is the peer whom refused our invitation, %2 is our Jabber identity. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:241 +msgid "" +"You are still connected to a Jabber server as %2, and may send an " +"invitation to %1 again, or you may send an invitation to a different " +"user." +msgstr "" + +#. TRANSLATORS: %1 is the peer whom we tried to contact, but is already in a whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:252 +msgid "" +"The user %1 is already in a " +"whiteboard session.\n" +"\n" +msgstr "" + +#. TRANSLATORS: %1 is the peer whom we tried to contact, but is already in a whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:255 +msgid "" +"You are still connected to a Jabber server as %1, and may send an " +"invitation to a different user." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/invitation-confirm-dialog.cpp:26 +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:24 +msgid "_Write session file:" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/message-processors.cpp:145 +#, c-format +msgid "%s has joined the chatroom." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/message-queue.cpp:87 +#, fuzzy, c-format +msgid "%u change in receive queue." +msgid_plural "%u changes in receive queue." +msgstr[0] "Nema izmena potrebnih za snimanje." +msgstr[1] "Nema izmena potrebnih za snimanje." + +#: ../../po/../src/jabber_whiteboard/message-queue.cpp:117 +#, fuzzy, c-format +msgid "%u change in send queue." +msgid_plural "%u changes in send queue." +msgstr[0] "Nema izmena potrebnih za snimanje." +msgstr[1] "Nema izmena potrebnih za snimanje." + +#. if ID is NULL, then we have a real problem -- we were not able to find a key +#. nor generate one. The only thing we can really do here is abort, since we have +#. no way to let the other client(s) uniquely identify this object. +#. FIXME: If this indicates a programming bug, then don't request translation with +#. * _(...): it is most useful in untranslated form so that developers may search for +#. * it when someone reports it in a bug report (as we want users to do for all bugs, +#. * as indicated by it being a g_warning string). +#. * +#. * Otherwise, if it is not a programming bug but a network error or a bug in the +#. * remote peer (perhaps running different software) or whatever, then present it in +#. * an alert box, and avoid use of technical jargon `NULL'. +#. +#: ../../po/../src/jabber_whiteboard/message-utilities.cpp:171 +msgid "" +"ID for new object is NULL even after generation and lookup attempts: the new " +"object will NOT be sent, nor will any of its child objects!" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:60 +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:995 +msgid "Select a location and filename" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:62 +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:997 +#, fuzzy +msgid "Set filename" +msgstr "Naziv _datoteke" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:301 +msgid "No SSL certificate was found." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:304 +msgid "The SSL certificate provided by the Jabber server is untrusted." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:307 +msgid "The SSL certificate provided by the Jabber server is expired." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:310 +msgid "" +"The SSL certificate provided by the Jabber server has not been activated." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:313 +msgid "" +"The SSL certificate provided by the Jabber server contains a hostname that " +"does not match the Jabber server's hostname." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:316 +msgid "" +"The SSL certificate provided by the Jabber server contains an invalid " +"fingerprint." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:319 +msgid "An unknown error occurred while setting up the SSL connection." +msgstr "" + +#. TRANSLATORS: %1 is the message that describes the specific error that occurred when +#. establishing the SSL connection. +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:325 +msgid "" +"%1\n" +"\n" +"Do you wish to continue connecting to the Jabber server?" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:328 +msgid "Continue connecting and ignore further errors" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:329 +msgid "Continue connecting, but warn me of further errors" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:330 +#, fuzzy +msgid "Cancel connection" +msgstr "Izbor" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:777 +#, c-format +msgid "Established whiteboard session with %s." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:785 +#, c-format +msgid "%s has left the whiteboard session." +msgstr "" + +#. Inform the user +#. TRANSLATORS: %1 is the name of the user that disconnected, %2 is the name of the user whom the disconnected user disconnected from. +#. This message is not used in a chatroom context. +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:790 +msgid "" +"The user %1 has left the " +"whiteboard session.\n" +"\n" +msgstr "" + +#. TRANSLATORS: %1 and %2 are userids +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:792 +msgid "" +"You are still connected to a Jabber server as %2, and may establish a " +"new session to %1 or a different user." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:988 +msgid "" +"Could not open file %1 for session recording.\n" +"The error encountered was: %2.\n" +"\n" +"You may select a different location to record the session, or you may opt to " +"not record this session." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:990 +msgid "Choose a different location" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:991 +msgid "Skip session recording" +msgstr "" + +#: ../../po/../src/knot.cpp:673 +msgid "Node or handle drag canceled." +msgstr "Prevlačenje čvora ili ručke je otkazano." + +#: ../../po/../src/libnrtype/FontFactory.cpp:358 +msgid "Ignoring font without family that will crash Pango" +msgstr "Ignorisanje fonta bez familije koji bi oborili Pango" + +#: ../../po/../src/main.cpp:395 +msgid "Print the Inkscape version number" +msgstr "Å tampaj oznaku verzije Inkskejpa" + +#: ../../po/../src/main.cpp:400 +msgid "Do not use X server (only process files from console)" +msgstr "Ne koristi X server (samo obrađuj datoteke preko konzole)" + +#: ../../po/../src/main.cpp:405 +msgid "Try to use X server (even if $DISPLAY is not set)" +msgstr "" +"PokuÅ¡aj da koristiÅ¡ X server (čak iako promenljiva $DISPLAY nije postavljena)" + +#: ../../po/../src/main.cpp:410 +msgid "Open specified document(s) (option string may be excluded)" +msgstr "Otvori navedene dokumente (niska opcija se može preskočiti)" + +#: ../../po/../src/main.cpp:411 ../../po/../src/main.cpp:416 +#: ../../po/../src/main.cpp:421 ../../po/../src/main.cpp:483 +#: ../../po/../src/main.cpp:488 ../../po/../src/main.cpp:493 +msgid "FILENAME" +msgstr "NAZIV DATOTEKE" + +#: ../../po/../src/main.cpp:415 +msgid "Print document(s) to specified output file (use '| program' for pipe)" +msgstr "" +"Å tampaj dokumente u navedenu izlaznu datoteku (koristite „| program“ za " +"cevku)" + +#: ../../po/../src/main.cpp:420 +msgid "Export document to a PNG file" +msgstr "Izvoz dokumenta u PNG datoteku" + +#: ../../po/../src/main.cpp:425 +msgid "The resolution used for exporting SVG into bitmap (default 90)" +msgstr "" +"Rezolucija koja se koristi za pretvaranje SVG-a u bitmapu (podrazumevano 90)" + +#: ../../po/../src/main.cpp:426 +msgid "DPI" +msgstr "TPI" + +#: ../../po/../src/main.cpp:430 +#, fuzzy +msgid "" +"Exported area in SVG user units (default is the canvas; 0,0 is lower-left " +"corner)" +msgstr "" +"PovrÅ¡ina za izvoz u SVG pikselima (podrazumevano je platno, 0,0 je donji-" +"levi ugao)" + +#: ../../po/../src/main.cpp:431 +msgid "x0:y0:x1:y1" +msgstr "x0:y0:x1:y1" + +#: ../../po/../src/main.cpp:435 +msgid "Exported area is the entire drawing (not canvas)" +msgstr "PovrÅ¡ina za izvoz je trenutni crtež (a ne platno)" + +#: ../../po/../src/main.cpp:440 +msgid "" +"Snap the bitmap export area outwards to the nearest integer values (in SVG " +"user units)" +msgstr "" + +#: ../../po/../src/main.cpp:445 +msgid "The width of exported bitmap in pixels (overrides export-dpi)" +msgstr "Å irina obrazovane bitmape u tačkama (prepisuje izvozni TPI)" + +#: ../../po/../src/main.cpp:446 +msgid "WIDTH" +msgstr "Å IRINA" + +#: ../../po/../src/main.cpp:450 +msgid "The height of exported bitmap in pixels (overrides export-dpi)" +msgstr "Visina obrazovane bitmape u tačkama (zanemaruje atribut „export-dpi“)" + +#: ../../po/../src/main.cpp:451 +msgid "HEIGHT" +msgstr "VISINA" + +#: ../../po/../src/main.cpp:455 +msgid "The ID of the object to export (overrides export-area)" +msgstr "ID objekta za izvoz (zanemaruje atribut „export-area“)" + +#: ../../po/../src/main.cpp:456 ../../po/../src/main.cpp:532 +msgid "ID" +msgstr "ID" + +#. TRANSLATORS: this means: "Only export the object whose id is given in --export-id". +#. See "man inkscape" for details. +#: ../../po/../src/main.cpp:462 +msgid "" +"Export just the object with export-id, hide all others (only with export-id)" +msgstr "" +"Izvozi samo objekat sa atributom „export-id“, sakriva sve druge (samo sa " +"atributom „export-id“)" + +#: ../../po/../src/main.cpp:467 +msgid "Use stored filename and DPI hints when exporting (only with export-id)" +msgstr "" +"Koristi sačuvani naziv datoteke i TPI rezoluciju pri izvozu (samo sa " +"atributom „export-id“)" + +#: ../../po/../src/main.cpp:472 +msgid "Background color of exported bitmap (any SVG-supported color string)" +msgstr "" +"Boja pozadine bitmape za obrazovanje (bilo koja oznaka boje koju podržava " +"SVG)" + +#: ../../po/../src/main.cpp:473 +msgid "COLOR" +msgstr "BOJA" + +#: ../../po/../src/main.cpp:477 +msgid "Background opacity of exported bitmap (either 0.0 to 1.0, or 1 to 255)" +msgstr "" +"Boja pozadine bitmape za obrazovanje (bilo od 0.0 do 1.0, ili 1 do 255)" + +#: ../../po/../src/main.cpp:478 +msgid "VALUE" +msgstr "VREDNOST" + +#: ../../po/../src/main.cpp:482 +msgid "Export document to plain SVG file (no sodipodi or inkscape namespaces)" +msgstr "" +"Izvezi dokument u običnu SVG datoteku (bez atributa „sodipodi“ ili " +"„inkscape“)" + +#: ../../po/../src/main.cpp:487 +msgid "Export document to a PS file" +msgstr "Izvoz dokumenta u PS datoteku" + +#: ../../po/../src/main.cpp:492 +msgid "Export document to an EPS file" +msgstr "Izvoz dokumenta u EPS datoteku" + +#: ../../po/../src/main.cpp:497 +msgid "Convert text object to paths on export (EPS)" +msgstr "Pretvori tekstualne objekte u krive pri izvozu (EPS)" + +#: ../../po/../src/main.cpp:502 +msgid "Export files with the bounding box set to the page size (EPS)" +msgstr "" +"Izvoz datoteka sa okvirom kontejnera postavljenim na veličinu strane (EPS)" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:508 +msgid "" +"Query the X coordinate of the drawing or, if specified, of the object with --" +"query-id" +msgstr "" +"Pitaj za X koordinatu crteža ili, ako je postavljeno, objekta sa --query-id" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:514 +msgid "" +"Query the Y coordinate of the drawing or, if specified, of the object with --" +"query-id" +msgstr "" +"Pitaj za Y koordinatu crteža ili, ako je postavljeno, objekta sa --query-id" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:520 +msgid "" +"Query the width of the drawing or, if specified, of the object with --query-" +"id" +msgstr "Pitaj za Å¡irinu crteža ili, ako je postavljeno, objekta sa --query-id" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:526 +msgid "" +"Query the height of the drawing or, if specified, of the object with --query-" +"id" +msgstr "Pitaj za visinu crteža ili, ako je postavljeno, objekta sa --query-id" + +#: ../../po/../src/main.cpp:531 +msgid "The ID of the object whose dimensions are queried" +msgstr "ID objekta za čije se dimenzije postavlja upit" + +#. TRANSLATORS: this option makes Inkscape print the name (path) of the extension directory +#: ../../po/../src/main.cpp:537 +msgid "Print out the extension directory and exit" +msgstr "Å tampa direktorijum sa ekstenzijama i napuÅ¡ta program" + +#: ../../po/../src/main.cpp:542 +msgid "Show given files one-by-one, switch to next on any key/mouse event" +msgstr "" +"Prikazuje datoteke jednu po jednu, prelazi na sledeću nakon bilo kakvog " +"događaja sa tasterima ili miÅ¡em" + +#: ../../po/../src/main.cpp:547 +msgid "Use the new Gtkmm GUI interface" +msgstr "Koristi novi Gtkmm grafički interfejs" + +#: ../../po/../src/main.cpp:552 +msgid "Remove unused definitions from the defs section(s) of the document" +msgstr "Uklanja neupotrebljene stavke iz defs izbora dokumenta" + +#: ../../po/../src/main.cpp:741 +msgid "" +"[OPTIONS...] [FILE...]\n" +"\n" +"Available options:" +msgstr "" +"[OPCIJE...] [DATOTEKA...]\n" +"\n" +"Dostupne opcije:" + +#: ../../po/../src/menus-skeleton.h:17 +msgid "_New" +msgstr "_Novo" + +#: ../../po/../src/menus-skeleton.h:22 +msgid "Open _Recent" +msgstr "Otvori _poslednje korišćene" + +#: ../../po/../src/menus-skeleton.h:53 +msgid "_Edit" +msgstr "_Uređivanje" + +#: ../../po/../src/menus-skeleton.h:84 +msgid "_View" +msgstr "_Pregled" + +#: ../../po/../src/menus-skeleton.h:85 +#, fuzzy +msgid "_Zoom" +msgstr "Uvećaj" + +#: ../../po/../src/menus-skeleton.h:102 +#, fuzzy +msgid "Show/Hide" +msgstr "_Prikaži/sakrij" + +#: ../../po/../src/menus-skeleton.h:107 +msgid "_Display mode" +msgstr "" + +#: ../../po/../src/menus-skeleton.h:126 +msgid "_Layer" +msgstr "_Sloj" + +#: ../../po/../src/menus-skeleton.h:143 +msgid "_Object" +msgstr "_Objekat" + +#: ../../po/../src/menus-skeleton.h:165 +msgid "_Path" +msgstr "_Kriva" + +#: ../../po/../src/menus-skeleton.h:188 +msgid "_Text" +msgstr "_Tekst" + +#: ../../po/../src/menus-skeleton.h:200 +msgid "Effects" +msgstr "Efekti" + +#: ../../po/../src/menus-skeleton.h:207 +msgid "Whiteboa_rd" +msgstr "" + +#: ../../po/../src/menus-skeleton.h:220 +msgid "_Help" +msgstr "_Pomoć" + +#: ../../po/../src/menus-skeleton.h:222 +#, fuzzy +msgid "Tutorials" +msgstr "_Vežbe" + +#: ../../po/../src/node-context.cpp:382 +msgid "" +"Ctrl: toggle node type, snap handle angle, move hor/vert; Ctrl" +"+Alt: move along handles" +msgstr "" +"Ctrl: promena tipa čovra, prijanjanje ugla ručke, pomeranje vodoravno " +"i uspravno; Ctrl+Alt: pomeranje duž ručki" + +#: ../../po/../src/node-context.cpp:383 +msgid "" +"Shift: toggle node selection, disable snapping, rotate both handles" +msgstr "" +"Shift: promena izbora čvora, isključivanje prijanjanja, rotiranje obe " +"ručke" + +#: ../../po/../src/node-context.cpp:384 +msgid "Alt: lock handle length; Ctrl+Alt: move along handles" +msgstr "Alt: fiksna dužina ručki; Ctrl+Alt: pomera duž ručki" + +#: ../../po/../src/nodepath.cpp:1399 ../../po/../src/nodepath.cpp:1411 +#: ../../po/../src/nodepath.cpp:1492 ../../po/../src/nodepath.cpp:1504 +msgid "To join, you must have two endnodes selected." +msgstr "Za spajanje, morate da izaberete dva krajnja čvora." + +#: ../../po/../src/nodepath.cpp:1633 ../../po/../src/nodepath.cpp:1647 +msgid "" +"Select two non-endpoint nodes on a path between which to delete " +"segments." +msgstr "" +"Morate da izaberete dva nezavrÅ¡avajuća čvora na krivi, između kojih " +"će segment biti obrisan." + +#: ../../po/../src/nodepath.cpp:1743 +msgid "Cannot find path between nodes." +msgstr "Ne mogu da pronađem krivu između čvorova." + +#: ../../po/../src/nodepath.cpp:2822 +#, fuzzy, c-format +msgid "" +"Node handle: angle %0.2f°, length %s; with Ctrl to snap " +"angle; with Alt to lock length; with Shift to rotate both " +"handles" +msgstr "" +"Ručka čvora: na %0.2f°, dužina %s; sa Ctrl za prijanjanje " +"ugla; sa Alt za fiksnu dužinu; sa Shift za rotaciju obe ručke" + +#: ../../po/../src/nodepath.cpp:3351 +msgid "" +"Node: drag to edit the path; with Ctrl to snap to horizontal/" +"vertical; with Ctrl+Alt to snap to handles' directions" +msgstr "" +"Čvor: povlačenjem se uređuje kriva; sa Ctrl za prijanjanje " +"vodoravno/uspravno; sa Ctrl+Alt za prijanjanje na pravac ručke" + +#: ../../po/../src/nodepath.cpp:3375 +msgid "" +"Node handle: drag to shape the curve; with Ctrl to snap angle; " +"with Alt to lock length; with Shift to rotate both handles" +msgstr "" +"Ručka čvora: povlačenje uređuje krivu; sa Ctrl za prijanjanje " +"ugla; sa Alt za fiksnu dužinu; sa Shift za rotaciju obe ručke" + +#: ../../po/../src/nodepath.cpp:3399 +msgid "" +"Node handle: drag to shape the curve; with Ctrl to snap angle; " +"with Alt to lock length; with Shift to rotate the opposite " +"handle in sync" +msgstr "" +"Ručka čvora: povlačenje uređuje krivu; sa Ctrl za prijanjanje " +"ugla; sa Alt za fiksnu dužinu; sa Shift za sinhronu rotaciju " +"suprotne ručke" + +#. TRANSLATORS: "end" is an adjective here (NOT a verb) +#: ../../po/../src/nodepath.cpp:3591 +msgid "end node" +msgstr "zavrÅ¡ni čvor" + +#. TRANSLATORS: "cusp" means "sharp" (cusp node); see also the Advanced Tutorial +#: ../../po/../src/nodepath.cpp:3596 +msgid "cusp" +msgstr "uglasta kriva" + +#. TRANSLATORS: "smooth" is an adjective here +#: ../../po/../src/nodepath.cpp:3599 +msgid "smooth" +msgstr "glatka kriva" + +#: ../../po/../src/nodepath.cpp:3601 +msgid "symmetric" +msgstr "simetrična kriva" + +#. TRANSLATORS: "end" is an adjective here (NOT a verb) +#: ../../po/../src/nodepath.cpp:3607 +msgid "end node, handle retracted (drag with Shift to extend)" +msgstr "zavrÅ¡ni čvor, ručka odbijena (koristite Shift za nastavak)" + +#: ../../po/../src/nodepath.cpp:3609 +msgid "one handle retracted (drag with Shift to extend)" +msgstr "jedna ručka je odbijena (koristite Shift za nastavak)" + +#: ../../po/../src/nodepath.cpp:3612 +msgid "both handles retracted (drag with Shift to extend)" +msgstr "obe ručke su odbijene (koristite Shift za nastavak)" + +#: ../../po/../src/nodepath.cpp:3624 +msgid "Drag nodes or node handles; arrow keys to move nodes" +msgstr "" +"Prevlačite čvorove ili kontrolne tačke; stralice za pomeranje " +"čvorova" + +#: ../../po/../src/nodepath.cpp:3625 +msgid "Drag the node or its handles; arrow keys to move the node" +msgstr "" +"Povlačite čvorove ili ručke; strelice za pomeranje čvorova" + +#: ../../po/../src/nodepath.cpp:3651 ../../po/../src/nodepath.cpp:3663 +msgid "Select a single object to edit its nodes or handles." +msgstr "Izaberite jedan objekat za uređivanje njegovih čvorova ili ručki." + +#: ../../po/../src/nodepath.cpp:3655 +#, c-format +msgid "" +"0 out of %i node selected. Click, Shift+click, " +"or drag around nodes to select." +msgid_plural "" +"0 out of %i nodes selected. Click, Shift+click, " +"or drag around nodes to select." +msgstr[0] "" +"0 od %i čvora odabrano. Klik, Shift+klik ili " +"prevlačenje oko čvora za izbor." +msgstr[1] "" +"0 od %i čvorova odabrano. Klik, Shift+klik ili " +"prevlačenje oko čvorova za izbor." + +#: ../../po/../src/nodepath.cpp:3661 +msgid "Drag the handles of the object to modify it." +msgstr "Vucite ručke objekta za njegovu izmenu." + +#: ../../po/../src/nodepath.cpp:3669 +#, c-format +msgid "%i of %i node selected; %s. %s." +msgid_plural "%i of %i nodes selected; %s. %s." +msgstr[0] "%i od %i čvora odabrano; %s. %s." +msgstr[1] "%i od %i čvorova odabrano; %s. %s." + +#: ../../po/../src/nodepath.cpp:3675 +#, c-format +msgid "%i of %i node selected. %s." +msgid_plural "%i of %i nodes selected. %s." +msgstr[0] "%i od %i čvora odabrano. %s." +msgstr[1] "%i od %i čvorova odabrano. %s." + +#: ../../po/../src/object-edit.cpp:493 +msgid "" +"Adjust the horizontal rounding radius; with Ctrl to make the " +"vertical radius the same" +msgstr "" +"Prilagođavanje poluprečnika vodoravnog zaobljenja; Ctrl za " +"istu vrednost uspravnog poluprečnika" + +#: ../../po/../src/object-edit.cpp:499 +msgid "" +"Adjust the vertical rounding radius; with Ctrl to make the " +"horizontal radius the same" +msgstr "" +"Prilagođavanje poluprečnika uspravnog zaobljenja; Ctrl za istu " +"vrednost vodoravnog poluprečnika" + +#: ../../po/../src/object-edit.cpp:506 ../../po/../src/object-edit.cpp:513 +msgid "" +"Adjust the width and height of the rectangle; with Ctrl to " +"lock ratio or stretch in one dimension only" +msgstr "" +"Podesi Å¡irinu i visinu pravougaonika; Ctrl zaključava odnos " +"ili izduživanje jedne dimenzije" + +#: ../../po/../src/object-edit.cpp:686 +msgid "Adjust ellipse width, with Ctrl to make circle" +msgstr "" +"PodeÅ¡avanje Å¡irine elipse, sa Ctrl za pravljenje kružnice" + +#: ../../po/../src/object-edit.cpp:689 +msgid "Adjust ellipse height, with Ctrl to make circle" +msgstr "" +"PodeÅ¡avanje visine elipse, sa Ctrl za pravljenje kružnice" + +#: ../../po/../src/object-edit.cpp:692 +msgid "" +"Position the start point of the arc or segment; with Ctrl to " +"snap angle; drag inside the ellipse for arc, outside for " +"segment" +msgstr "" + +#: ../../po/../src/object-edit.cpp:695 +msgid "" +"Position the end point of the arc or segment; with Ctrl to " +"snap angle; drag inside the ellipse for arc, outside for " +"segment" +msgstr "" + +#: ../../po/../src/object-edit.cpp:800 +msgid "" +"Adjust the tip radius of the star or polygon; with Shift to " +"round; with Alt to randomize" +msgstr "" + +#: ../../po/../src/object-edit.cpp:803 +msgid "" +"Adjust the base radius of the star; with Ctrl to keep star " +"rays radial (no skew); with Shift to round; with Alt to " +"randomize" +msgstr "" + +#: ../../po/../src/object-edit.cpp:967 +msgid "" +"Roll/unroll the spiral from inside; with Ctrl to snap angle; " +"with Alt to converge/diverge" +msgstr "" + +#: ../../po/../src/object-edit.cpp:969 +msgid "" +"Roll/unroll the spiral from outside; with Ctrl to snap angle; " +"with Shift to scale/rotate" +msgstr "" + +#: ../../po/../src/object-edit.cpp:1006 +msgid "Adjust the offset distance" +msgstr "Podesi udaljenost pomeraja" + +#. TRANSLATORS: This refers to the pattern that's inside the object +#: ../../po/../src/object-edit.cpp:1036 +msgid "Move the pattern fill inside the object" +msgstr "Pomeranje popune mustrom unutar objekta" + +#: ../../po/../src/object-edit.cpp:1038 +msgid "Scale the pattern fill uniformly" +msgstr "Jedinstvena promena veličine popune mustrom" + +#: ../../po/../src/object-edit.cpp:1040 +msgid "Rotate the pattern fill; with Ctrl to snap angle" +msgstr "" +"Rotiranje popune mustrom; pritisnite Ctrl za prijanjanje na " +"uglao" + +#: ../../po/../src/object-edit.cpp:1065 +msgid "Drag to resize the flowed text frame" +msgstr "Povlačenje za prmenu veličine plutajućeg okvira teksta" + +# bug: rect -> rectangle +#. Item dialog +#: ../../po/../src/object-ui.cpp:106 +msgid "Object _Properties" +msgstr "_Osobine objekta" + +#. Select item +#: ../../po/../src/object-ui.cpp:116 +msgid "_Select This" +msgstr "_Izaberi ovo" + +#. Create link +#: ../../po/../src/object-ui.cpp:126 +msgid "_Create Link" +msgstr "_Napravi vezu" + +#. "Ungroup" +#: ../../po/../src/object-ui.cpp:199 ../../po/../src/verbs.cpp:1931 +msgid "_Ungroup" +msgstr "_RazgrupiÅ¡i" + +#. Link dialog +#: ../../po/../src/object-ui.cpp:239 +msgid "Link _Properties" +msgstr "_Osobine veze" + +#. Select item +#: ../../po/../src/object-ui.cpp:249 +msgid "_Follow Link" +msgstr "_Prati vezu" + +#. Reset transformations +#: ../../po/../src/object-ui.cpp:254 +msgid "_Remove Link" +msgstr "_Ukloni vezu" + +#. Link dialog +#: ../../po/../src/object-ui.cpp:303 +msgid "Image _Properties" +msgstr "_Osobine slike" + +#. Item dialog +#: ../../po/../src/object-ui.cpp:344 +msgid "_Fill and Stroke" +msgstr "_Popune i linije" + +#: ../../po/../src/path-chemistry.cpp:58 +msgid "Select at least two objects to combine." +msgstr "Izaberite najmanje dva objekta za sjedinjavanje." + +#: ../../po/../src/path-chemistry.cpp:65 +msgid "At least one of the objects is not a path, cannot combine." +msgstr "Jedan od objekata nije zatvorena kriva i ne može se sjediniti." + +#: ../../po/../src/path-chemistry.cpp:73 +msgid "" +"You cannot combine objects from different groups or layers." +msgstr "" +"Ne možete da sjedinite objekte u različitim grupama ili slojevima." + +#: ../../po/../src/path-chemistry.cpp:155 +msgid "Select path(s) to break apart." +msgstr "Odaberite krivu(e) za raskidanje jedinstva." + +#: ../../po/../src/path-chemistry.cpp:231 +msgid "No path(s) to break apart in the selection." +msgstr "Nema krive za raskidanje jedinstva među izabranim objektima." + +#: ../../po/../src/path-chemistry.cpp:252 +msgid "Select object(s) to convert to path." +msgstr "Odaberite objekat za pretvaranje u krive." + +#: ../../po/../src/path-chemistry.cpp:297 +msgid "No objects to convert to path in the selection." +msgstr "Nema objekta za pretvaranje u krive među izabranim objektima." + +#: ../../po/../src/path-chemistry.cpp:345 +msgid "Select path(s) to reverse." +msgstr "Izaberite krivu(e) za promenusmeravanje." + +#: ../../po/../src/path-chemistry.cpp:370 +msgid "No paths to reverse in the selection." +msgstr "Nema krive za preusmeravanje među izabranim objektima." + +#: ../../po/../src/pen-context.cpp:379 ../../po/../src/pencil-context.cpp:233 +msgid "Continuing selected path" +msgstr "Nastavljanje izabrane krive" + +#: ../../po/../src/pen-context.cpp:390 ../../po/../src/pencil-context.cpp:242 +msgid "Creating new path" +msgstr "Pravljenje nove krive" + +#: ../../po/../src/pen-context.cpp:394 ../../po/../src/pencil-context.cpp:246 +msgid "Appending to selected path" +msgstr "Dodavanje izabranoj krivi" + +#: ../../po/../src/pen-context.cpp:538 +#, fuzzy +msgid "Click or click and drag to close and finish the path." +msgstr "" +"Klik za uređivanje teksta, prevlačenje za izbor dela teksta." + +#: ../../po/../src/pen-context.cpp:548 +#, fuzzy +msgid "" +"Click or click and drag to continue the path from this point." +msgstr "" +"Klik za uređivanje teksta, prevlačenje za izbor dela teksta." + +#: ../../po/../src/pen-context.cpp:857 +#, fuzzy, c-format +msgid "" +"%s: angle %3.2f°, distance %s; with Ctrl to snap angle, " +"Enter to finish the path" +msgstr "" +"Ručka čvora: na %0.2f°, dužina %s; sa Ctrl za prijanjanje " +"ugla; sa Alt za fiksnu dužinu; sa Shift za rotaciju obe ručke" + +#: ../../po/../src/pen-context.cpp:882 +#, fuzzy, c-format +msgid "" +"Curve handle: angle %3.2f°, length %s; with Ctrl to snap " +"angle" +msgstr "Rotacija: %0.2f°; sa Ctrl za prijanjanje ugla" + +#: ../../po/../src/pen-context.cpp:912 +#, fuzzy, c-format +msgid "" +"%s: angle %3.2f°, length %s; with Ctrl to snap angle, " +"with Shift to move this handle only" +msgstr "" +"Ručka čvora: na %0.2f°, dužina %s; sa Ctrl za prijanjanje " +"ugla; sa Alt za fiksnu dužinu; sa Shift za rotaciju obe ručke" + +#: ../../po/../src/pen-context.cpp:946 +msgid "Finishing pen" +msgstr "ZavrÅ¡avanje olovke" + +#: ../../po/../src/pencil-context.cpp:320 +msgid "Release here to close and finish the path." +msgstr "" + +#: ../../po/../src/pencil-context.cpp:326 +#, fuzzy +msgid "Drawing a freehand path" +msgstr "Iscrtavanje linije slobodnom rukom" + +#: ../../po/../src/pencil-context.cpp:331 +msgid "Drag to continue the path from this point." +msgstr "" + +#. Write curves to object +#: ../../po/../src/pencil-context.cpp:390 +msgid "Finishing freehand" +msgstr "ZavrÅ¡avanje slobodne ruke" + +#: ../../po/../src/rect-context.cpp:387 +msgid "" +"Ctrl: make square or integer-ratio rect, lock a rounded corner " +"circular" +msgstr "" +"Ctrl: pravi kvadrat ili proporcionalni pravougaonik, zaključava " +"zaobljene uglove u kružnicu" + +#: ../../po/../src/rect-context.cpp:549 +#, c-format +msgid "" +"Rectangle: %s × %s; with Ctrl to make square or integer-" +"ratio rectangle; with Shift to draw around the starting point" +msgstr "" +"Pravougaonik: %s × %s; sa Ctrl pravi kvadrat ili " +"proporcionalni pravougaonik; sa Shift crta oko centra rotacije" + +#: ../../po/../src/select-context.cpp:243 +msgid "Move canceled." +msgstr "Pomeranje je otkazano." + +#: ../../po/../src/select-context.cpp:252 +msgid "Selection canceled." +msgstr "Izbor je otkazan." + +#: ../../po/../src/select-context.cpp:642 +msgid "Ctrl: select in groups, move hor/vert" +msgstr "Ctrl: izbor u grupi, pomeranje vodoravno/uspravno" + +#: ../../po/../src/select-context.cpp:643 +msgid "Shift: toggle select, force rubberband, disable snapping" +msgstr "" +"Shift:\tpostavlja i ukida izbor, forsira gumicu, isključuje " +"prijanjanje" + +#: ../../po/../src/select-context.cpp:644 +msgid "Alt: select under, move selected" +msgstr "Alt: izbor donjeg objekta, pomeranje izbora" + +#: ../../po/../src/select-context.cpp:798 +#, fuzzy +msgid "Selected object is not a group. Cannot enter." +msgstr "Izabrani objekat nije kriva, ne može da se skuplja ili Å¡iri." + +#: ../../po/../src/select-context.cpp:876 +#, c-format +msgid "" +"Move by %s, %s; with Ctrl to restrict to horizontal/vertical; " +"with Shift to disable snapping" +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:228 +msgid "Nothing was deleted." +msgstr "NiÅ¡ta nije obrisano." + +#: ../../po/../src/selection-chemistry.cpp:259 +msgid "Select object(s) to duplicate." +msgstr "Izaberite objekat za dupliranje." + +#: ../../po/../src/selection-chemistry.cpp:420 +msgid "Select two or more objects to group." +msgstr "Izaberite dva ili viÅ¡e objekata za gurpisanje." + +#: ../../po/../src/selection-chemistry.cpp:428 +msgid "Select at least two objects to group." +msgstr "Izaberite najmanje dva objekta za grupisanje." + +#: ../../po/../src/selection-chemistry.cpp:513 +msgid "Select a group to ungroup." +msgstr "Izaberite grupu za razgrupisavanje." + +#: ../../po/../src/selection-chemistry.cpp:554 +msgid "No groups to ungroup in the selection." +msgstr "Nema grupe za razgrupisavanje među izabranim grupama." + +#: ../../po/../src/selection-chemistry.cpp:623 +msgid "Select objects to raise." +msgstr "Izaberite objekat za izdizanje." + +#: ../../po/../src/selection-chemistry.cpp:629 +#: ../../po/../src/selection-chemistry.cpp:681 +#: ../../po/../src/selection-chemistry.cpp:715 +#: ../../po/../src/selection-chemistry.cpp:773 +msgid "" +"You cannot raise/lower objects from different groups or layers." +msgstr "" +"Ne mogu se izdići/zakloniti objekti iz različitih grupa ili " +"slojeva." + +#: ../../po/../src/selection-chemistry.cpp:673 +msgid "Select object(s) to raise to top." +msgstr "Izaberite objekte za izdizanje na vrh." + +#: ../../po/../src/selection-chemistry.cpp:709 +msgid "Select object(s) to lower." +msgstr "Izaberite objekte za zaklanjanje." + +#: ../../po/../src/selection-chemistry.cpp:765 +msgid "Select object(s) to lower to bottom." +msgstr "Izaberite objekte za zaklanjanje na dno." + +#: ../../po/../src/selection-chemistry.cpp:806 +msgid "Nothing to undo." +msgstr "Nema opoziva akcije." + +#: ../../po/../src/selection-chemistry.cpp:813 +msgid "Nothing to redo." +msgstr "Nema ponavljanja akcije." + +#: ../../po/../src/selection-chemistry.cpp:969 +msgid "Nothing was copied." +msgstr "NiÅ¡ta nije umnoženo." + +#: ../../po/../src/selection-chemistry.cpp:1051 +msgid "Current layer is hidden. Unhide it to be able to paste to it." +msgstr "" +"Trenutni sloj je skriven. Prikažite ga da bi mogli da prilepite na " +"njega." + +#: ../../po/../src/selection-chemistry.cpp:1055 +msgid "Current layer is locked. Unlock it to be able to paste to it." +msgstr "" +"Trenutni sloj je zaključan. Otključajte ga da bi mogli da prilepite " +"na njega." + +#: ../../po/../src/selection-chemistry.cpp:1068 +#: ../../po/../src/selection-chemistry.cpp:1103 +msgid "Nothing on the clipboard." +msgstr "Nema ničega u klipbordu." + +#: ../../po/../src/selection-chemistry.cpp:1109 +msgid "Select object(s) to paste style to." +msgstr "Izaberite objekte na koje će se preneti stil." + +#: ../../po/../src/selection-chemistry.cpp:1128 +msgid "Select object(s) to move to the layer above." +msgstr "Izaberite objekat za premeÅ¡tanje na gornji sloj." + +#: ../../po/../src/selection-chemistry.cpp:1146 +msgid "No more layers above." +msgstr "Nema slojeva iznad trenutnog." + +#: ../../po/../src/selection-chemistry.cpp:1160 +msgid "Select object(s) to move to the layer below." +msgstr "Izaberite objekat za premeÅ¡tanje na donji sloj." + +#: ../../po/../src/selection-chemistry.cpp:1178 +msgid "No more layers below." +msgstr "Nema slojeva ispod trenutnog." + +#: ../../po/../src/selection-chemistry.cpp:1811 +msgid "Select a clone to unlink." +msgstr "Izaberite klon za odvezivanje." + +#: ../../po/../src/selection-chemistry.cpp:1842 +msgid "No clones to unlink in the selection." +msgstr "Nema klona za odvezivanje među izabranim klonovima." + +#: ../../po/../src/selection-chemistry.cpp:1859 +msgid "" +"Select a clone to go to its original. Select a linked offset " +"to go to its source. Select a text on path to go to the path. Select " +"a flowed text to go to its frame." +msgstr "" +"Izaberite klon za prelazak na original. Izaberite povezani " +"pomeraj za prelazak na izvor. Izaberite tekst na krivi za " +"prelazak na krivu. Izaberite plutajući tekst za prelazak na njegov " +"okvir." + +#: ../../po/../src/selection-chemistry.cpp:1882 +msgid "" +"Cannot find the object to select (orphaned clone, offset, textpath, " +"flowed text?)" +msgstr "" +"Ne mogu da pronađem objekat za izbor (klon siroče, pomeraj, putanja " +"teksta, plutajući tekst?)" + +#: ../../po/../src/selection-chemistry.cpp:1888 +msgid "" +"The object you're trying to select is not visible (it is in <" +"defs>)" +msgstr "" +"Original ovog klona nije vidljivi objekat (nalazi se u <defs> " +"atributu)" + +#: ../../po/../src/selection-chemistry.cpp:1915 +msgid "Select object(s) to convert to pattern." +msgstr "Odaberite objekte koji će biti spojeni u mustru." + +#: ../../po/../src/selection-chemistry.cpp:2006 +msgid "Select an object with pattern fill to extract objects from." +msgstr "" +"Izaberite objekat popunjen mustrom za izdvajanje objekata iz mustre." + +#: ../../po/../src/selection-chemistry.cpp:2059 +msgid "No pattern fills in the selection." +msgstr "U izboru nema popune mustrom." + +#: ../../po/../src/selection-chemistry.cpp:2079 +msgid "Select object(s) to make a bitmap copy." +msgstr "Izaberite objekte za izdizanje na vrh." + +#: ../../po/../src/selection-describer.cpp:37 +msgid "Click selection to toggle scale/rotation handles" +msgstr "Kliknite na izabrani objekat za promenu režima skaliranje/rotacija" + +#. no items +#: ../../po/../src/selection-describer.cpp:39 +msgid "" +"No objects selected. Click, Shift+click, or drag around objects to select." +msgstr "" +"Nema izabranih objekata. Klik, Shift+klik ili prevlačenje oko objekta za " +"izbor." + +#: ../../po/../src/selection-describer.cpp:51 +#, c-format +msgid " in layer %s" +msgstr " u sloju %s" + +#: ../../po/../src/selection-describer.cpp:54 +#, c-format +msgid " in layer %s" +msgstr " u sloju %s" + +#: ../../po/../src/selection-describer.cpp:66 +msgid "Use Shift+D to look up original" +msgstr "Upotrbite Shift+D za pronalaženje originala" + +#: ../../po/../src/selection-describer.cpp:70 +msgid "Use Shift+D to look up path" +msgstr "Upotrbite Shift+D za pronalaženje krive" + +#: ../../po/../src/selection-describer.cpp:74 +msgid "Use Shift+D to look up frame" +msgstr "Upotrbite Shift+D za pronalaženje okvira" + +#: ../../po/../src/selection-describer.cpp:84 +#, c-format +msgid "%i object selected" +msgid_plural "%i objects selected" +msgstr[0] "%i objekat izabran" +msgstr[1] "%i objekata izabrano" + +#: ../../po/../src/selection-describer.cpp:90 +#, c-format +msgid "%s%s. %s." +msgstr "%s%s. %s." + +#: ../../po/../src/selection-describer.cpp:94 +#, c-format +msgid "%s in %i layer. %s." +msgid_plural "%s in %i layers. %s." +msgstr[0] "%s u %i sloju. %s." +msgstr[1] "%s u %i slojeva. %s." + +#: ../../po/../src/seltrans.cpp:498 +msgid "" +"Center of rotation and skewing: drag to reposition; scaling with " +"Shift also uses this center" +msgstr "" +"Centar rotacije i ukoÅ¡avanja: povucite za premeÅ¡tanje; promena " +"veličine sa " + +#: ../../po/../src/seltrans.cpp:514 +msgid "" +"Squeeze or stretch selection; with Ctrl to scale uniformly; " +"with Shift to scale around rotation center" +msgstr "" +"Stiskanje i razvlačenje izbora; sa Ctrl za proporcionalno; sa " +"Shift za promenu oko centra rotacije" + +#: ../../po/../src/seltrans.cpp:515 +msgid "" +"Scale selection; with Ctrl to scale uniformly; with Shift to scale around rotation center" +msgstr "" +"Promena veličine izbora; sa Ctrl za proporcionalno; sa " +"Shift za promenu oko centra rotacije" + +#: ../../po/../src/seltrans.cpp:519 +msgid "" +"Skew selection; with Ctrl to snap angle; with Shift to " +"skew around the opposite side" +msgstr "" +"IskoÅ¡avanje izbora; sa Ctrl za prijanjanje ugla; sa Shift za rotiranje oko suprotne strane" + +#: ../../po/../src/seltrans.cpp:520 +msgid "" +"Rotate selection; with Ctrl to snap angle; with Shift " +"to rotate around the opposite corner" +msgstr "" +"Rotacija izbora; sa Ctrl za fiksni ugao; sa Shift za " +"rotiranje oko suprotnog ćoÅ¡ka" + +#: ../../po/../src/seltrans.cpp:829 ../../po/../src/seltrans.cpp:909 +#, c-format +msgid "Scale: %0.2f%% x %0.2f%%; with Ctrl to lock ratio" +msgstr "Skaliranje: %0.2f%% x %0.2f%%; sa Ctrl za proporcionalno" + +#. TRANSLATORS: don't modify the first ";" (it will NOT be displayed as ";" - only the second one will be) +#: ../../po/../src/seltrans.cpp:984 +#, c-format +msgid "Skew: %0.2f°; with Ctrl to snap angle" +msgstr "IskoÅ¡avanje: %0.2f°; sa Ctrl za prijanjanje ugla" + +#. TRANSLATORS: don't modify the first ";" (it will NOT be displayed as ";" - only the second one will be) +#: ../../po/../src/seltrans.cpp:1035 +#, c-format +msgid "Rotate: %0.2f°; with Ctrl to snap angle" +msgstr "Rotacija: %0.2f°; sa Ctrl za prijanjanje ugla" + +#: ../../po/../src/seltrans.cpp:1090 +#, c-format +msgid "Move center to %s, %s" +msgstr "Centar premeÅ¡ten na %s, %s" + +#: ../../po/../src/slideshow.cpp:90 +msgid "Inkscape slideshow" +msgstr "Slajd Å¡ou prezentacija" + +#: ../../po/../src/sp-anchor.cpp:181 +#, c-format +msgid "Link to %s" +msgstr "Veza na %s" + +#: ../../po/../src/sp-anchor.cpp:185 +msgid "Link without URI" +msgstr "Veza bez URI adrese" + +#: ../../po/../src/sp-ellipse.cpp:438 ../../po/../src/sp-ellipse.cpp:870 +msgid "Ellipse" +msgstr "Elipsa" + +#: ../../po/../src/sp-ellipse.cpp:583 +msgid "Circle" +msgstr "Kružnica" + +#: ../../po/../src/sp-ellipse.cpp:865 +msgid "Segment" +msgstr "Segment" + +#: ../../po/../src/sp-ellipse.cpp:867 +msgid "Arc" +msgstr "Ugao" + +#. TRANSLATORS: "Flow region" is an area where text is allowed to flow +#: ../../po/../src/sp-flowregion.cpp:276 +msgid "Flow region" +msgstr "Slobodna povrÅ¡ina" + +#. TRANSLATORS: A region "cut out of" a flow region; text is not allowed to flow inside the +#. * flow excluded region. flowRegionExclude in SVG 1.2: see +#. * http://www.w3.org/TR/2004/WD-SVG12-20041027/flow.html#flowRegion-elem and +#. * http://www.w3.org/TR/2004/WD-SVG12-20041027/flow.html#flowRegionExclude-elem. +#: ../../po/../src/sp-flowregion.cpp:493 +msgid "Flow excluded region" +msgstr "" + +#: ../../po/../src/sp-flowtext.cpp:355 +#, c-format +msgid "Flowed text (%d characters)" +msgstr "Plutajući tekst (%d znakova)" + +#: ../../po/../src/sp-flowtext.cpp:357 +#, c-format +msgid "Linked flowed text (%d characters)" +msgstr "Povezani plutajući tekst (%d znakova)" + +#: ../../po/../src/sp-guide.cpp:290 +msgid "vertical guideline" +msgstr "uspravna vođica" + +#: ../../po/../src/sp-guide.cpp:292 +msgid "horizontal guideline" +msgstr "vodoravna vođica" + +#: ../../po/../src/sp-image.cpp:835 +msgid "embedded" +msgstr "ugrađen" + +#: ../../po/../src/sp-image.cpp:839 +msgid "(null_pointer)" +msgstr "(null_pointer)" + +#: ../../po/../src/sp-image.cpp:843 +#, c-format +msgid "Image with bad reference: %s" +msgstr "Slika sa loÅ¡om referencom: %s" + +#: ../../po/../src/sp-image.cpp:844 +#, c-format +msgid "Image %d × %d: %s" +msgstr "Slika %d × %d: %s" + +# bug: plural-forms +#: ../../po/../src/sp-item-group.cpp:390 +#, c-format +msgid "Group of %d object" +msgid_plural "Group of %d objects" +msgstr[0] "Grupa od %d objekta" +msgstr[1] "Grupa od %d objekata" + +#: ../../po/../src/sp-item.cpp:720 +msgid "Object" +msgstr "Objekat" + +#: ../../po/../src/sp-line.cpp:202 +msgid "Line" +msgstr "Linija" + +#. TRANSLATORS COMMENT: %s is either "outset" or "inset" depending on sign +#: ../../po/../src/sp-offset.cpp:433 +#, c-format +msgid "Linked offset, %s by %f pt" +msgstr "Povezani pomeraj, %s za %f tačaka" + +#: ../../po/../src/sp-offset.cpp:434 ../../po/../src/sp-offset.cpp:438 +msgid "outset" +msgstr "proÅ¡ireno" + +#: ../../po/../src/sp-offset.cpp:434 ../../po/../src/sp-offset.cpp:438 +msgid "inset" +msgstr "suzženo" + +#. TRANSLATORS COMMENT: %s is either "outset" or "inset" depending on sign +#: ../../po/../src/sp-offset.cpp:437 +#, c-format +msgid "Dynamic offset, %s by %f pt" +msgstr "Dinamička udaljenost, %s za %f tačaka" + +#: ../../po/../src/sp-path.cpp:127 +#, c-format +msgid "Path (%i node)" +msgid_plural "Path (%i nodes)" +msgstr[0] "Putanja (%i čvor)" +msgstr[1] "Putanja (%i čvorova)" + +#: ../../po/../src/sp-polygon.cpp:216 +msgid "Polygon" +msgstr "poligon" + +#: ../../po/../src/sp-polyline.cpp:179 +msgid "Polyline" +msgstr "ViÅ¡estruka linija" + +#: ../../po/../src/sp-rect.cpp:250 +msgid "Rectangle" +msgstr "Pravougaonik" + +#. TRANSLATORS: since turn count isn't an integer, please adjust the +#. string as needed to deal with an localized plural forms. +#: ../../po/../src/sp-spiral.cpp:305 +#, c-format +msgid "Spiral with %3f turns" +msgstr "Spirala sa %3f zavoja" + +#: ../../po/../src/sp-star.cpp:288 +#, c-format +msgid "Star with %d vertex" +msgid_plural "Star with %d vertices" +msgstr[0] "Zvezda sa %d krakom" +msgstr[1] "Zvezda sa %d krakova" + +#: ../../po/../src/sp-star.cpp:292 +#, c-format +msgid "Polygon with %d vertex" +msgid_plural "Polygon with %d vertices" +msgstr[0] "Poligon sa %d stranom" +msgstr[1] "Poligon sa %d strana" + +#. TRANSLATORS: For description of font with no name. +#: ../../po/../src/sp-text.cpp:420 +msgid "<no name found>" +msgstr "<naziv nije pronađen>" + +#: ../../po/../src/sp-text.cpp:426 +#, c-format +msgid "Text on path (%s, %s)" +msgstr "Kriva sa tekstom (%s, %s)" + +#: ../../po/../src/sp-text.cpp:427 +#, c-format +msgid "Text (%s, %s)" +msgstr "Tekst (%s, %s)" + +#. TRANSLATORS: Used for statusbar description for long chains: +#. * "Clone of: Clone of: ... in Layer 1". +#: ../../po/../src/sp-use.cpp:317 +msgid "..." +msgstr "..." + +#: ../../po/../src/sp-use.cpp:325 +#, c-format +msgid "Clone of: %s" +msgstr "Klon za: %s" + +#: ../../po/../src/sp-use.cpp:329 +msgid "Orphaned clone" +msgstr "Klon siroče" + +#: ../../po/../src/spiral-context.cpp:355 +msgid "Ctrl: snap angle" +msgstr "Ctrl: prijanjanje ugla" + +#: ../../po/../src/spiral-context.cpp:357 +msgid "Alt: lock spiral radius" +msgstr "Alt: zaključava prečnik spirale" + +#: ../../po/../src/spiral-context.cpp:469 +#, c-format +msgid "" +"Spiral: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" +"Spirala: prečnik %s, ugao %5g°; sa Ctrl za prijanjanje " +"ugla" + +#: ../../po/../src/splivarot.cpp:106 +msgid "Select at least 2 paths to perform a boolean operation." +msgstr "Izaberite najmanje dve krive za primenjivanje Bulove operacije." + +#: ../../po/../src/splivarot.cpp:112 +msgid "" +"Select exactly 2 paths to perform difference, XOR, division, or path " +"cut." +msgstr "" +"Izaberite tačno dve krive za primenjivanje operacije različitosti, " +"XOR, podele ili isecanja krive." + +#: ../../po/../src/splivarot.cpp:129 ../../po/../src/splivarot.cpp:144 +msgid "" +"Unable to determine the z-order of the objects selected for " +"difference, XOR, division, or path cut." +msgstr "" +"Ne mogu da raspoznam poredak sloja objekata izabranih za različitost, " +"XOR, podelu ili isecanje krive." + +#: ../../po/../src/splivarot.cpp:174 +msgid "" +"One of the objects is not a path, cannot perform boolean operation." +msgstr "" +"Jedan od objekata nije kriva, nije moguće primeniti Bulovu operaciju." + +#. TRANSLATORS: "to outline" means "to convert stroke to path" +#: ../../po/../src/splivarot.cpp:554 +msgid "Select path(s) to outline." +msgstr "Izaberite objekte za pretvaranje u krive." + +#. TRANSLATORS: "to outline" means "to convert stroke to path" +#: ../../po/../src/splivarot.cpp:748 +msgid "No stroked paths to outline in the selection." +msgstr "U izboru nema iscrtanih poteza za pretvaranje u krive." + +#: ../../po/../src/splivarot.cpp:832 +msgid "Selected object is not a path, cannot inset/outset." +msgstr "Izabrani objekat nije kriva, ne može da se skuplja ili Å¡iri." + +#: ../../po/../src/splivarot.cpp:1040 +msgid "Select path(s) to inset/outset." +msgstr "Izaberite neku krivu za skupljanje ili Å¡irenje." + +#: ../../po/../src/splivarot.cpp:1257 +msgid "No paths to inset/outset in the selection." +msgstr "U izboru nema kriva za skupljanje ili Å¡irenje." + +#: ../../po/../src/splivarot.cpp:1390 +msgid "Select path(s) to simplify." +msgstr "Izaberite krive za pojednostavljivanje." + +#: ../../po/../src/splivarot.cpp:1417 +msgid "No paths to simplify in the selection." +msgstr "U izboru nema kriva za pojednostavljivanje." + +#: ../../po/../src/star-context.cpp:362 +msgid "Ctrl: snap angle; keep rays radial" +msgstr "Ctrl: prijanja na ugao; zadrži radijalne krake" + +#: ../../po/../src/star-context.cpp:470 +#, c-format +msgid "" +"Polygon: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" +"Poligon: poluprečnik %s, ugao %5g°; Ctrl prijanja na ugao" + +#: ../../po/../src/star-context.cpp:471 +#, c-format +msgid "Star: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" +"Zvezda: poluprečnik %s, ugao %5g°; Ctrl prijanja na ugao" + +#: ../../po/../src/text-chemistry.cpp:90 +msgid "Select a text and a path to put text on path." +msgstr "Izaberite tekst i krivu za postavljanje teksta na krivu." + +#: ../../po/../src/text-chemistry.cpp:95 +msgid "" +"This text object is already put to a path. Remove it from the path " +"first. Use Shift+D to look up its path." +msgstr "" +"Ovaj tekst objekat je već postavljen na krivu. Prvo ga uklonite sa " +"krive. Koristite Shift+D za naglaÅ¡avanje pripadajuće krive." + +#. rect is the only SPShape which is not yet, and thus SVG forbids us from putting text on it +#: ../../po/../src/text-chemistry.cpp:101 +msgid "" +"You cannot put text on a rectangle in this version. Convert rectangle to " +"path first." +msgstr "" +"U ovoj verziji ne možete da postavite tekst na pravougaonik. Prvo pretvorite " +"pravougaonik u krivu." + +#: ../../po/../src/text-chemistry.cpp:159 +msgid "Select a text on path to remove it from path." +msgstr "Izaberite tekst na obliku za sklanjanje sa krive." + +#: ../../po/../src/text-chemistry.cpp:181 +msgid "No texts-on-paths in the selection." +msgstr "Nema teksta na obliku u izboru." + +#: ../../po/../src/text-chemistry.cpp:209 +#: ../../po/../src/text-chemistry.cpp:229 +msgid "Select text(s) to remove kerns from." +msgstr "Izaberite tekst za koji će biti uklonjeno uklapanje slova." + +#: ../../po/../src/text-chemistry.cpp:250 +msgid "" +"Select a text and one or more paths or shapes to flow text " +"into frame." +msgstr "" +"Izaberite tekst i jednu ili viÅ¡e krivu ili oblik za " +"postavljanje teksta u okvir." + +#: ../../po/../src/text-chemistry.cpp:322 +msgid "Select a flowed text to unflow it." +msgstr "Izaberite plutajući tekst za oslobađanje iz objekta." + +#: ../../po/../src/text-context.cpp:463 +msgid "Click to edit the text, drag to select part of the text." +msgstr "" +"Klik za uređivanje teksta, prevlačenje za izbor dela teksta." + +#: ../../po/../src/text-context.cpp:465 +msgid "" +"Click to edit the flowed text, drag to select part of the text." +msgstr "" +"Klik za uređivanje plutajućeg teksta, prevlačenje za izbor " +"dela teksta." + +#: ../../po/../src/text-context.cpp:540 +msgid "Non-printable character" +msgstr "Znakovi koji se ne Å¡tampaju" + +#: ../../po/../src/text-context.cpp:589 +#, c-format +msgid "Unicode: %s: %s" +msgstr "Unikod: %s: %s" + +#: ../../po/../src/text-context.cpp:591 ../../po/../src/text-context.cpp:855 +msgid "Unicode: " +msgstr "Unikod: " + +#: ../../po/../src/text-context.cpp:615 +msgid "Current layer is hidden. Unhide it to be able to add text." +msgstr "" +"Aktivni sloj je skriven. Ukinite sakrivanje da bi mogli da dodate " +"tekst." + +#: ../../po/../src/text-context.cpp:619 +msgid "Current layer is locked. Unlock it to be able to add text." +msgstr "" +"Aktivni sloj je zaključan. Otključajte ga da bi mogli da dodate tekst." + +#: ../../po/../src/text-context.cpp:673 +#, c-format +msgid "Flowed text frame: %s × %s" +msgstr "Okvir plutajućeg teksta: %s × %s" + +#: ../../po/../src/text-context.cpp:708 ../../po/../src/text-context.cpp:1464 +msgid "Type text; Enter to start new line." +msgstr "Unesite tekst; Enter za početak nove linije." + +#: ../../po/../src/text-context.cpp:719 +msgid "Flowed text is created." +msgstr "Plutajući tekst je napravljen." + +#: ../../po/../src/text-context.cpp:722 +msgid "" +"The frame is too small for the current font size. Flowed text not " +"created." +msgstr "" +"Okvir je premali za ternutnu veličinu fonta. Plutajući tekst nije " +"napravljen." + +#: ../../po/../src/text-context.cpp:841 +msgid "No-break space" +msgstr "Neprekidajući razmak" + +#: ../../po/../src/text-context.cpp:1462 +msgid "Type flowed text; Enter to start new paragraph." +msgstr "Unesite plitajući tekst; Enter za početak novog pasusa." + +#: ../../po/../src/text-context.cpp:1472 ../../po/../src/tools-switch.cpp:189 +msgid "" +"Click to select or create text, drag to create flowed text; " +"then type." +msgstr "" +"Klik za izbor ili pravljenje teksta, prevlačenje za pravljenje " +"plutajućeg teksta; potom kucajte tekst." + +#: ../../po/../src/tools-switch.cpp:141 +msgid "" +"To edit a path, click, Shift+click, or drag around " +"nodes to select them, then drag nodes and handles. Click on an " +"object to select." +msgstr "" +"Za uređivanje krive klik, Shift+klik ili povlačenje preko čvorova za izbor, zatim povlačenje čvorova i ručki. Klik na " +"objekat za izbor." + +#: ../../po/../src/tools-switch.cpp:147 +msgid "" +"Drag to create a rectangle. Drag controls to round corners and " +"resize. Click to select." +msgstr "" +"Crtanje pravougaonika povlačenjem. Povlačenje kvačica za " +"zaobljene uglove i promenu veličine. Klik za izbor." + +#: ../../po/../src/tools-switch.cpp:153 +msgid "" +"Drag to create an ellipse. Drag controls to make an arc or " +"segment. Click to select." +msgstr "" +"Crtanje elipse povlačenjem. Povlačenje kvačica za luk ili " +"segment. Klik za izbor." + +#: ../../po/../src/tools-switch.cpp:159 +msgid "" +"Drag to create a star. Drag controls to edit the star shape. " +"Click to select." +msgstr "" +"Crtanje zvezde povlačenjem. Uređivanje povlačenjem kvačica. " +"Klik za izbor." + +#: ../../po/../src/tools-switch.cpp:165 +msgid "" +"Drag to create a spiral. Drag controls to edit the spiral " +"shape. Click to select." +msgstr "" +"Crtanje spirale povlačenjem. Uređivanje spirale povlačenjem " +"kvačica. Klik za izbor." + +#: ../../po/../src/tools-switch.cpp:171 +msgid "" +"Drag to create a freehand line. Start drawing with Shift to " +"append to selected path." +msgstr "" +"Crtanje krive linije povlačenjem. Započnite crtanje sa Shifta " +"za dodavanje na izabranu krivu." + +#: ../../po/../src/tools-switch.cpp:177 +#, fuzzy +msgid "" +"Click or click and drag to start a path; with Shift to " +"append to selected path." +msgstr "" +"Klik za pravljenje čvora, klik i povlačenje za pravljenje " +"glatkog čvora. Započnite sa Shift za dodavanje na izabranu krivu." + +#: ../../po/../src/tools-switch.cpp:183 +msgid "" +"Drag to paint a calligraphic stroke. Left/right arrow " +"keys adjust width, up/down adjust angle." +msgstr "" +"Crtanje kaligrafske linije povlačenjem. Strelica levo/" +"desno podeÅ¡ava Å¡irinu, gore/dole podeÅ¡ava ugao." + +#: ../../po/../src/tools-switch.cpp:195 +msgid "" +"Drag or double click to create a gradient on selected objects, " +"drag handles to adjust gradients." +msgstr "" +"Pravljenje ili dvoklik za pravljenje preliva za izabrani " +"objekat, povlačenje ručki za uređivanje preliva." + +#: ../../po/../src/tools-switch.cpp:201 +msgid "" +"Click or drag around an area to zoom in, Shift+click to " +"zoom out." +msgstr "" +"Klik ili prevlačenje preko povrÅ¡ine za uvećanje, Shift" +"+klik za umanjenje." + +#: ../../po/../src/tools-switch.cpp:213 +msgid "Click and drag between shapes to create a connector." +msgstr "" + +#: ../../po/../src/trace/potrace/inkscape-potrace.cpp:553 +#: ../../po/../src/trace/potrace/inkscape-potrace.cpp:654 +#, c-format +msgid "Trace: %d. %ld nodes" +msgstr "Vektorizacija: %d. %ld čvorova" + +#: ../../po/../src/trace/trace.cpp:53 ../../po/../src/trace/trace.cpp:62 +#: ../../po/../src/trace/trace.cpp:70 +msgid "Select an image to trace" +msgstr "Izaberite sliku za vektorizaciju" + +#: ../../po/../src/trace/trace.cpp:133 +msgid "Trace: No active document" +msgstr "Vektorizacija: Nema aktivnog dokumenta" + +#: ../../po/../src/trace/trace.cpp:154 +msgid "Trace: Image has no bitmap data" +msgstr "Vektorizacija: Slika nema bitmapiranih podataka" + +#: ../../po/../src/trace/trace.cpp:267 +#, c-format +msgid "Trace: Done. %ld nodes created" +msgstr "Vektorizacija: Gotovo. %ld čvorova napravljeno" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:59 ../../po/../src/verbs.cpp:2212 +msgid "About Inkscape" +msgstr "O programu" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:66 +msgid "_Splash" +msgstr "" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:68 +msgid "_Authors" +msgstr "" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:69 +#, fuzzy +msgid "_Translators" +msgstr "Transformacija" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:70 +#, fuzzy +msgid "_License" +msgstr "Licenca" + +#. TRANSLATORS: This is the filename of the `About Inkscape' picture in +#. the `screens' directory. Thus the translation of "about.svg" should be +#. the filename of its translated version, e.g. about.zh.svg for Chinese. +#. +#. N.B. about.svg changes once per release. (We should probably rename +#. the original to about-0.40.svg etc. as soon as we have a translation. +#. If we do so, then add an item to release-checklist saying that the +#. string here should be changed.) +#. FIXME? INKSCAPE_SCREENSDIR and "about.svg" are in UTF-8, not the +#. native filename encoding... and the filename passed to sp_document_new +#. should be in UTF-*8.. +#: ../../po/../src/ui/dialog/aboutbox.cpp:114 +msgid "about.svg" +msgstr "about.svg" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:464 +msgid "Minimum horizontal gap (in px units) between bounding boxes" +msgstr "" + +#. TRANSLATORS: Horizontal gap +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:466 +#: ../../po/../src/widgets/toolbox.cpp:1556 +msgid "H:" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:474 +msgid "Minimum vertical gap (in px units) between bounding boxes" +msgstr "" + +#. TRANSLATORS: Vertical gap +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:476 +msgid "V:" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:734 +msgid "Align" +msgstr "Poravnavanje" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:735 +msgid "Distribute" +msgstr "Raspoređivanje" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:736 +msgid "Remove overlaps" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:737 +msgid "Nodes" +msgstr "Čvorovi" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:742 +msgid "Relative to: " +msgstr "Relativno na: " + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:747 +msgid "Align right sides of objects to left side of anchor" +msgstr "Poravnava desnu stranu izbora uz levu stranu osnovnog objekta" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:750 +msgid "Align left sides" +msgstr "Levo poravnanje" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:753 +msgid "Center on vertical axis" +msgstr "Centriraj na uspravnoj osi" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:756 +msgid "Align right sides" +msgstr "Desno poravnanje" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:759 +msgid "Align left sides of objects to right side of anchor" +msgstr "Leva strana izbora uz desnu stranu osnovnog objekta" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:762 +msgid "Align bottoms of objects to top of anchor" +msgstr "Dno izbora uz vrh osnovnog objekta" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:765 +msgid "Align tops" +msgstr "Poravnavanje vrhova" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:768 +msgid "Center on horizontal axis" +msgstr "Centriraj na vodoravnoj osi" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:771 +msgid "Align bottoms" +msgstr "Poravnanje dna" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:774 +msgid "Align tops of objects to bottom of anchor" +msgstr "Vrh izbora uz dno osnovnog objekta" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:779 +msgid "Align baseline anchors of texts vertically" +msgstr "Uspravno poravnanje osnova teksta" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:782 +msgid "Align baseline anchors of texts horizontally" +msgstr "Vodoravno poravnanje osnova teksta" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:787 +msgid "Make horizontal gaps between objects equal" +msgstr "Podjednaki vodoravni razmaci između objekata" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:791 +msgid "Distribute left sides equidistantly" +msgstr "Leve strane objekata na podjednakim rastojanjima" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:794 +msgid "Distribute centers equidistantly horizontally" +msgstr "Sredine objekata na podjednakim vodoravnim rastojanjima" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:797 +msgid "Distribute right sides equidistantly" +msgstr "Desne strane objekata na podjednakim rastojanjima" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:801 +msgid "Make vertical gaps between objects equal" +msgstr "Podjednaki uspravni razmaci između objekata" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:805 +msgid "Distribute tops equidistantly" +msgstr "Vrhovi objekata na podjednakim rastojanjima" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:808 +msgid "Distribute centers equidistantly vertically" +msgstr "Sredine objekata na podjednakim uspravnim rastojanjima" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:811 +msgid "Distribute bottoms equidistantly" +msgstr "Donje strane objekata na podjednakim rastojanjima" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:816 +msgid "Distribute baseline anchors of texts horizontally" +msgstr "Osnove teksta na podjednakim vodoravnim rastojanjima" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:819 +msgid "Distribute baseline anchors of texts vertically" +msgstr "Osnove teksta na podjednakim uspravnim rastojanjima" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:824 +msgid "Randomize centers in both dimensions" +msgstr "Nasumično centriranje u obe dimenzije" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:827 +msgid "Unclump objects: try to equalize edge-to-edge distances" +msgstr "Rasturanje objekata: pokuÅ¡aj izjednačavanja udaljenosti ivice od ivice" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:832 +msgid "" +"Move objects as little as possible so that their bounding boxes do not " +"overlap" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:837 +msgid "Align selected nodes horizontally" +msgstr "Poravnava izabrane čvorove vodoravno" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:840 +msgid "Align selected nodes vertically" +msgstr "Poravnava izabrane čvorove uspravno" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:843 +msgid "Distribute selected nodes horizontally" +msgstr "Podjednaki vodoravni razmaci izabranih čvorova" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:846 +msgid "Distribute selected nodes vertically" +msgstr "Podjednaki uspravni razmaci izabranih čvorova" + +#. Rest of the widgetry +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:851 +msgid "Last selected" +msgstr "Poslednji" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:852 +msgid "First selected" +msgstr "Prvi" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:853 +msgid "Biggest item" +msgstr "Najveće" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:854 +msgid "Smallest item" +msgstr "Najmanje" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:856 +#: ../../po/../src/widgets/desktop-widget.cpp:1065 +msgid "Drawing" +msgstr "Crtež" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:91 +#, fuzzy +msgid "Metadata 1" +msgstr "Dopunske informacije" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:92 +#, fuzzy +msgid "Metadata 2" +msgstr "Dopunske informacije" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:187 +#, fuzzy +msgid "X coordinate of grid origin" +msgstr "Uspravna koordinata izbora" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:189 +#, fuzzy +msgid "Y coordinate of grid origin" +msgstr "Uspravna koordinata izbora" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:191 +#, fuzzy +msgid "Distance of vertical grid lines" +msgstr "uspravna vođica" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:193 +#, fuzzy +msgid "Distance of horizontal grid lines" +msgstr "vodoravna vođica" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:197 +msgid "Max. snapping distance from grid" +msgstr "" + +#: ../../po/../src/ui/dialog/export.cpp:34 +msgid "Export" +msgstr "Izvezi" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:36 +msgid "Fill" +msgstr "Popuna" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:37 +msgid "Stroke Paint" +msgstr "Boja linije" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:38 +msgid "Stroke Style" +msgstr "Stil linije" + +#: ../../po/../src/ui/dialog/find.cpp:34 +msgid "Find" +msgstr "Traži" + +#: ../../po/../src/ui/dialog/memory.cpp:96 +msgid "Heap" +msgstr "Nagomilano" + +#: ../../po/../src/ui/dialog/memory.cpp:97 +msgid "In Use" +msgstr "Zauzeto" + +#. TRANSLATORS: "Slack" refers to memory which is in the heap but currently unused. +#. More typical usage is to call this memory "free" rather than "slack". +#: ../../po/../src/ui/dialog/memory.cpp:100 +msgid "Slack" +msgstr "Slobodno" + +#: ../../po/../src/ui/dialog/memory.cpp:101 +msgid "Total" +msgstr "Ukupno" + +#: ../../po/../src/ui/dialog/memory.cpp:141 +#: ../../po/../src/ui/dialog/memory.cpp:147 +#: ../../po/../src/ui/dialog/memory.cpp:154 +#: ../../po/../src/ui/dialog/memory.cpp:186 +msgid "Unknown" +msgstr "Nepoznato" + +#: ../../po/../src/ui/dialog/memory.cpp:167 +msgid "Combined" +msgstr "Kombinovano" + +#: ../../po/../src/ui/dialog/memory.cpp:209 +msgid "Recalculate" +msgstr "Preračunaj" + +#: ../../po/../src/ui/dialog/messages.cpp:74 +#, fuzzy +msgid "Ready." +msgstr "Crvena" + +#: ../../po/../src/ui/dialog/messages.cpp:75 +msgid "" +"Enable log display by setting dialogs.debug 'redirect' attribute to 1 in " +"preferences.xml" +msgstr "" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:184 +msgid "_Execute Python" +msgstr "_IzvrÅ¡i Piton" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:186 +msgid "_Execute Perl" +msgstr "_IzvrÅ¡i Perl" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:195 +msgid "Script" +msgstr "Skript" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:205 +msgid "Output" +msgstr "Izlaz" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:215 +msgid "Errors" +msgstr "GreÅ¡ke" + +#. Dialog organization +#: ../../po/../src/ui/dialog/session-player.cpp:73 +msgid "Session file" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:74 +#, fuzzy +msgid "Playback controls" +msgstr "Kontrola alata" + +#: ../../po/../src/ui/dialog/session-player.cpp:75 +#, fuzzy +msgid "Message information" +msgstr "PoniÅ¡ti _transformaciju" + +#. Active session file display +#. fixme: Does this mean the active file for the session, or the file for the active session? +#. Please indicate which with a TRANSLATORS comment. +#: ../../po/../src/ui/dialog/session-player.cpp:85 +msgid "Active session file:" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:86 +msgid "Delay (milliseconds):" +msgstr "" + +#. Unload/load buttons +#: ../../po/../src/ui/dialog/session-player.cpp:94 +#, fuzzy +msgid "Close file" +msgstr "Zatvori" + +#: ../../po/../src/ui/dialog/session-player.cpp:95 +msgid "Open new file" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:96 +#, fuzzy +msgid "Set delay" +msgstr "Postavi kao podrazumevano" + +#: ../../po/../src/ui/dialog/session-player.cpp:138 +#, fuzzy +msgid "Rewind" +msgstr "Crvena" + +#: ../../po/../src/ui/dialog/session-player.cpp:139 +msgid "Go back one change" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:140 +#, fuzzy +msgid "Pause" +msgstr "U_baci" + +#: ../../po/../src/ui/dialog/session-player.cpp:141 +msgid "Go forward one change" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:142 +msgid "Play" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:177 +#: ../../po/../src/verbs.cpp:1573 +msgid "Open session file" +msgstr "" + +#. ##Set up the Potrace panel +#. #### brightness #### +#. #### Multiple scanning#### +#. ----Hbox1 +#: ../../po/../src/ui/dialog/tracedialog.cpp:345 +#: ../../po/../src/ui/dialog/tracedialog.cpp:428 +msgid "Brightness" +msgstr "Osvetljenost" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:348 +msgid "Trace by a given brightness level" +msgstr "Prepoznavanje kontura za dati nivo osvetljenosti" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:355 +msgid "Brightness cutoff for black/white" +msgstr "Zanemarivanje osvetljenosti za crno/belo" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:362 +msgid "Image Brightness" +msgstr "Osvetljenost slike" + +#. #### canny edge detection #### +#. TRANSLATORS: "Canny" is the name of the inventor of this edge detection method +#: ../../po/../src/ui/dialog/tracedialog.cpp:369 +msgid "Optimal Edge Detection (Canny)" +msgstr "Optimalno prepoznavanje kontura (Keni)" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:372 +msgid "Trace with edge detection by J. Canny's algorithm" +msgstr "Prepoznavanje kontura sa Kenijevim algoritmom " + +#: ../../po/../src/ui/dialog/tracedialog.cpp:388 +msgid "Brightness cutoff for adjacent pixels (determines edge thickness)" +msgstr "Zanemarivanje osvetljenosti za susedne tačke (određuje Å¡irinu konture)" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:395 +msgid "Edge Detection" +msgstr "Prepoznavanje kontura" + +#. #### quantization #### +#. TRANSLATORS: Color Quantization: the process of reducing the number of colors +#. in an image by selecting an optimized set of representative colors and then +#. re-applying this reduced set to the original image. +#: ../../po/../src/ui/dialog/tracedialog.cpp:404 +msgid "Color Quantization" +msgstr "Zasićenost boja" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:407 +msgid "Trace along the boundaries of reduced colors" +msgstr "Prepoznavanje kontura po ivicama ograničenih boja" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:414 +msgid "The number of reduced colors" +msgstr "Broj ograničenih boja" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:416 +msgid "Colors:" +msgstr "Boje:" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:421 +msgid "Quantization / Reduction" +msgstr "Zasićenost / PriguÅ¡enje" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:431 +msgid "Trace the given number of brightness levels" +msgstr "Prepoznavanje zadatog broja nivoa osvetljenosti" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:438 +msgid "Scans:" +msgstr "Ispivanje:" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:440 +msgid "The desired number of scans" +msgstr "Željeni broj ispitivanja" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:448 +msgid "Trace the given number of reduced colors" +msgstr "Prepoznavanje zadatog broja ograničenih boja" + +#. ---Hbox3 +#: ../../po/../src/ui/dialog/tracedialog.cpp:454 +msgid "Monochrome" +msgstr "Monohromatski" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:457 +msgid "Same as Color, but convert result to grayscale" +msgstr "Isto kao u boji, ali se rezultat pretvara u sive tonove" + +#. TRANSLATORS: "Stack" is a verb here +#: ../../po/../src/ui/dialog/tracedialog.cpp:460 +msgid "Stack" +msgstr "Gomilanje" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:463 +msgid "" +"Stack scans vertically (no gaps) or tile horizontally (usually with gaps)" +msgstr "" +"Dodaje ispitivanja uspravno (bez praznina) ili popločava vodoravno (obično " +"sa prazninama)" + +#. TRANSLATORS: "Smooth" is a verb here +#: ../../po/../src/ui/dialog/tracedialog.cpp:466 +msgid "Smooth" +msgstr "Glatko" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:469 +msgid "Apply Gaussian blur to the bitmap before tracing" +msgstr "Primenjuje Gausovo zamagljivanje na bitmapu pre prepoznavanja kontura" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:473 +msgid "Multiple Scanning" +msgstr "Ispitivanje u viÅ¡e prolaza" + +#. #### Preview #### +#: ../../po/../src/ui/dialog/tracedialog.cpp:479 +#: ../../po/../src/ui/dialog/tracedialog.cpp:489 +msgid "Preview" +msgstr "Prikaz" + +#. do not expand +#: ../../po/../src/ui/dialog/tracedialog.cpp:483 +msgid "Preview the result without actual tracing" +msgstr "Prikazuje rezultat bez stvarnog prepoznavanja kontura" + +#. #### swap black and white #### +#: ../../po/../src/ui/dialog/tracedialog.cpp:495 +msgid "Invert" +msgstr "Preokreni" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:499 +msgid "Invert black and white regions for single traces" +msgstr "Zamenjuje crne i bele povrÅ¡ine za svaki prolaz" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:503 +msgid "Thanks to Peter Selinger, http://potrace.sourceforge.net" +msgstr "Zahvaljujemo se Piteru Silingeru, http://potrace.sourceforge.net" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:506 +msgid "Credits" +msgstr "Zahvale" + +#. done +#. TRANSLATORS: Potrace is an application for transforming bitmaps into +#. vector graphics (http://potrace.sourceforge.net/) +#: ../../po/../src/ui/dialog/tracedialog.cpp:514 +msgid "Potrace" +msgstr "Potrejs (Potrace)" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:527 +msgid "Abort a trace in progress" +msgstr "Zaustavi prepoznavanje koje je u toku" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:531 +msgid "Execute the trace" +msgstr "IzvrÅ¡ti prepoznavanje" + +#: ../../po/../src/ui/dialog/transformation.cpp:80 +#: ../../po/../src/ui/dialog/transformation.cpp:90 +#, fuzzy +msgid "_Horizontal" +msgstr "Vodoravni tekst" + +#: ../../po/../src/ui/dialog/transformation.cpp:80 +msgid "Horizontal displacement (relative) or position (absolute)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:82 +#: ../../po/../src/ui/dialog/transformation.cpp:92 +#, fuzzy +msgid "_Vertical" +msgstr "Uspravni tekst" + +#: ../../po/../src/ui/dialog/transformation.cpp:82 +msgid "Vertical displacement (relative) or position (absolute)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:84 +#, fuzzy +msgid "_Width" +msgstr "_Å irina:" + +#: ../../po/../src/ui/dialog/transformation.cpp:84 +msgid "Horizontal size increment (absolute or percentage)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:86 +#, fuzzy +msgid "_Height" +msgstr "Visina:" + +#: ../../po/../src/ui/dialog/transformation.cpp:86 +msgid "Vertical size increment (absolute or percentage)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:88 +#, fuzzy +msgid "A_ngle" +msgstr "Ugao:" + +#: ../../po/../src/ui/dialog/transformation.cpp:88 +#, fuzzy +msgid "Rotation angle (positive = counterclockwise)" +msgstr "Rotira za 90° u obrnutom smeru od smera kazaljke na satu" + +#: ../../po/../src/ui/dialog/transformation.cpp:90 +msgid "" +"Horizontal skew angle (positive = counterclockwise), or absolute " +"displacement, or percentage displacement" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:92 +msgid "" +"Vertical skew angle (positive = counterclockwise), or absolute displacement, " +"or percentage displacement" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:95 +#, fuzzy +msgid "Transformation matrix element A" +msgstr "Transformaciona matrica" + +#: ../../po/../src/ui/dialog/transformation.cpp:96 +#, fuzzy +msgid "Transformation matrix element B" +msgstr "Transformaciona matrica" + +#: ../../po/../src/ui/dialog/transformation.cpp:97 +#, fuzzy +msgid "Transformation matrix element C" +msgstr "Transformaciona matrica" + +#: ../../po/../src/ui/dialog/transformation.cpp:98 +#, fuzzy +msgid "Transformation matrix element D" +msgstr "Transformaciona matrica" + +#: ../../po/../src/ui/dialog/transformation.cpp:99 +#, fuzzy +msgid "Transformation matrix element E" +msgstr "Transformaciona matrica" + +#: ../../po/../src/ui/dialog/transformation.cpp:100 +#, fuzzy +msgid "Transformation matrix element F" +msgstr "Transformaciona matrica" + +#: ../../po/../src/ui/dialog/transformation.cpp:102 +#, fuzzy +msgid "Rela_tive move" +msgstr "Relativno pomeranje" + +#: ../../po/../src/ui/dialog/transformation.cpp:102 +msgid "" +"Add the specified relative displacement to the current position; otherwise, " +"edit the current absolute position directly" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:103 +msgid "Scale proportionally" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:103 +msgid "Preserve the width/height ratio of the scaled objects" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:104 +msgid "Apply to each _object separately" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:104 +msgid "" +"Apply the scale/rotate/skew to each selected object separately; otherwise, " +"transform the selection as a whole" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:105 +#, fuzzy +msgid "Edit c_urrent matrix" +msgstr "Izdizanje trenutnog sloja" + +#: ../../po/../src/ui/dialog/transformation.cpp:105 +msgid "" +"Edit the current transform= matrix; otherwise, post-multiply transform= by " +"this matrix" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:115 +#, fuzzy +msgid "_Move" +msgstr "Pomeri" + +#: ../../po/../src/ui/dialog/transformation.cpp:118 +#, fuzzy +msgid "_Scale" +msgstr "Razmera" + +#: ../../po/../src/ui/dialog/transformation.cpp:121 +#, fuzzy +msgid "_Rotate" +msgstr "Rotiraj" + +#: ../../po/../src/ui/dialog/transformation.cpp:124 +#, fuzzy +msgid "Ske_w" +msgstr "Iskrivljavanje" + +#: ../../po/../src/ui/dialog/transformation.cpp:127 +msgid "Matri_x" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:141 +msgid "Reset the values on the current tab to defaults" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:148 +#, fuzzy +msgid "Apply transformation to selection" +msgstr "Primeni transformaciju na objekat" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:43 +msgid "_Use SSL" +msgstr "" + +#. Construct dialog interface +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:68 +#, fuzzy +msgid "_Server:" +msgstr "P_reusmeravanje" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:69 +#, fuzzy +msgid "_Username:" +msgstr "_Preimenuj" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:70 +msgid "_Password:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:71 +msgid "P_ort:" +msgstr "" + +#. Buttons +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:99 +#, fuzzy +msgid "Connect" +msgstr "Klonovi" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:126 +msgid "Establishing connection to Jabber server %1 as user %2" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:131 +msgid "Failed to establish connection to Jabber server %1" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:136 +msgid "Authentication failed on Jabber server %1 as %2" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:141 +msgid "SSL initialization failed when connecting to Jabber server %1" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:147 +msgid "Connected to Jabber server %1 as %2" +msgstr "" + +#. Construct labels +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:75 +#, fuzzy +msgid "Chatroom _name:" +msgstr "Naziv sloja:" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:76 +msgid "Chatroom _server:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:77 +msgid "Chatroom _password:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:78 +msgid "Chatroom _handle:" +msgstr "" + +#. Button setup and callback registration +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:97 +msgid "Connect to chatroom" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:132 +msgid "Synchronizing with chatroom %1@%2 using the handle %3" +msgstr "" + +#. Construct dialog interface +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:78 +msgid "_User's Jabber ID:" +msgstr "" + +#. Buttons +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:82 +msgid "_Invite user" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:83 +#, fuzzy +msgid "_Cancel" +msgstr "Otkaži" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:94 +msgid "Buddy List" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:170 +msgid "Sending whiteboard invitation to %1" +msgstr "" + +#. FIXME: strings are replaced by placeholders, NOT to be translated until the code is enabled +#. See http://sourceforge.net/mailarchive/message.php?msg_id=11746016 for details +#. File menu +#. Edit menu +#. View menu +#. Layer menu +#. Object menu +#. Path menu +#. add(Gtk::StockItem(CLEANUP, _("PLACEHOLDER, do not translate"))); (using Gtk::Stock::CLEAR) +#. Text menu +#. About menu +#. Tools toolbox +#. Select Tool controls +#. Node Tool controls +#. Calligraphy Tool controls +#. Session playback controls +#: ../../po/../src/ui/stock-items.cpp:34 ../../po/../src/ui/stock-items.cpp:35 +#: ../../po/../src/ui/stock-items.cpp:36 ../../po/../src/ui/stock-items.cpp:37 +#: ../../po/../src/ui/stock-items.cpp:38 ../../po/../src/ui/stock-items.cpp:39 +#: ../../po/../src/ui/stock-items.cpp:40 ../../po/../src/ui/stock-items.cpp:41 +#: ../../po/../src/ui/stock-items.cpp:42 ../../po/../src/ui/stock-items.cpp:43 +#: ../../po/../src/ui/stock-items.cpp:46 ../../po/../src/ui/stock-items.cpp:47 +#: ../../po/../src/ui/stock-items.cpp:48 ../../po/../src/ui/stock-items.cpp:49 +#: ../../po/../src/ui/stock-items.cpp:50 ../../po/../src/ui/stock-items.cpp:51 +#: ../../po/../src/ui/stock-items.cpp:52 ../../po/../src/ui/stock-items.cpp:53 +#: ../../po/../src/ui/stock-items.cpp:54 ../../po/../src/ui/stock-items.cpp:55 +#: ../../po/../src/ui/stock-items.cpp:56 ../../po/../src/ui/stock-items.cpp:57 +#: ../../po/../src/ui/stock-items.cpp:58 ../../po/../src/ui/stock-items.cpp:59 +#: ../../po/../src/ui/stock-items.cpp:62 ../../po/../src/ui/stock-items.cpp:63 +#: ../../po/../src/ui/stock-items.cpp:64 ../../po/../src/ui/stock-items.cpp:65 +#: ../../po/../src/ui/stock-items.cpp:66 ../../po/../src/ui/stock-items.cpp:67 +#: ../../po/../src/ui/stock-items.cpp:68 ../../po/../src/ui/stock-items.cpp:69 +#: ../../po/../src/ui/stock-items.cpp:70 ../../po/../src/ui/stock-items.cpp:71 +#: ../../po/../src/ui/stock-items.cpp:72 ../../po/../src/ui/stock-items.cpp:73 +#: ../../po/../src/ui/stock-items.cpp:74 ../../po/../src/ui/stock-items.cpp:75 +#: ../../po/../src/ui/stock-items.cpp:76 ../../po/../src/ui/stock-items.cpp:77 +#: ../../po/../src/ui/stock-items.cpp:78 ../../po/../src/ui/stock-items.cpp:79 +#: ../../po/../src/ui/stock-items.cpp:80 ../../po/../src/ui/stock-items.cpp:81 +#: ../../po/../src/ui/stock-items.cpp:82 ../../po/../src/ui/stock-items.cpp:83 +#: ../../po/../src/ui/stock-items.cpp:84 ../../po/../src/ui/stock-items.cpp:85 +#: ../../po/../src/ui/stock-items.cpp:86 ../../po/../src/ui/stock-items.cpp:87 +#: ../../po/../src/ui/stock-items.cpp:88 ../../po/../src/ui/stock-items.cpp:89 +#: ../../po/../src/ui/stock-items.cpp:92 ../../po/../src/ui/stock-items.cpp:93 +#: ../../po/../src/ui/stock-items.cpp:94 ../../po/../src/ui/stock-items.cpp:95 +#: ../../po/../src/ui/stock-items.cpp:96 ../../po/../src/ui/stock-items.cpp:97 +#: ../../po/../src/ui/stock-items.cpp:98 ../../po/../src/ui/stock-items.cpp:99 +#: ../../po/../src/ui/stock-items.cpp:100 +#: ../../po/../src/ui/stock-items.cpp:101 +#: ../../po/../src/ui/stock-items.cpp:102 +#: ../../po/../src/ui/stock-items.cpp:103 +#: ../../po/../src/ui/stock-items.cpp:104 +#: ../../po/../src/ui/stock-items.cpp:105 +#: ../../po/../src/ui/stock-items.cpp:108 +#: ../../po/../src/ui/stock-items.cpp:109 +#: ../../po/../src/ui/stock-items.cpp:110 +#: ../../po/../src/ui/stock-items.cpp:111 +#: ../../po/../src/ui/stock-items.cpp:112 +#: ../../po/../src/ui/stock-items.cpp:113 +#: ../../po/../src/ui/stock-items.cpp:114 +#: ../../po/../src/ui/stock-items.cpp:115 +#: ../../po/../src/ui/stock-items.cpp:116 +#: ../../po/../src/ui/stock-items.cpp:117 +#: ../../po/../src/ui/stock-items.cpp:118 +#: ../../po/../src/ui/stock-items.cpp:119 +#: ../../po/../src/ui/stock-items.cpp:120 +#: ../../po/../src/ui/stock-items.cpp:121 +#: ../../po/../src/ui/stock-items.cpp:122 +#: ../../po/../src/ui/stock-items.cpp:123 +#: ../../po/../src/ui/stock-items.cpp:124 +#: ../../po/../src/ui/stock-items.cpp:125 +#: ../../po/../src/ui/stock-items.cpp:126 +#: ../../po/../src/ui/stock-items.cpp:127 +#: ../../po/../src/ui/stock-items.cpp:130 +#: ../../po/../src/ui/stock-items.cpp:131 +#: ../../po/../src/ui/stock-items.cpp:132 +#: ../../po/../src/ui/stock-items.cpp:133 +#: ../../po/../src/ui/stock-items.cpp:134 +#: ../../po/../src/ui/stock-items.cpp:135 +#: ../../po/../src/ui/stock-items.cpp:136 +#: ../../po/../src/ui/stock-items.cpp:137 +#: ../../po/../src/ui/stock-items.cpp:138 +#: ../../po/../src/ui/stock-items.cpp:139 +#: ../../po/../src/ui/stock-items.cpp:140 +#: ../../po/../src/ui/stock-items.cpp:141 +#: ../../po/../src/ui/stock-items.cpp:142 +#: ../../po/../src/ui/stock-items.cpp:143 +#: ../../po/../src/ui/stock-items.cpp:144 +#: ../../po/../src/ui/stock-items.cpp:145 +#: ../../po/../src/ui/stock-items.cpp:146 +#: ../../po/../src/ui/stock-items.cpp:150 +#: ../../po/../src/ui/stock-items.cpp:151 +#: ../../po/../src/ui/stock-items.cpp:152 +#: ../../po/../src/ui/stock-items.cpp:153 +#: ../../po/../src/ui/stock-items.cpp:156 +#: ../../po/../src/ui/stock-items.cpp:157 +#: ../../po/../src/ui/stock-items.cpp:158 +#: ../../po/../src/ui/stock-items.cpp:161 +#: ../../po/../src/ui/stock-items.cpp:162 +#: ../../po/../src/ui/stock-items.cpp:163 +#: ../../po/../src/ui/stock-items.cpp:164 +#: ../../po/../src/ui/stock-items.cpp:165 +#: ../../po/../src/ui/stock-items.cpp:166 +#: ../../po/../src/ui/stock-items.cpp:167 +#: ../../po/../src/ui/stock-items.cpp:168 +#: ../../po/../src/ui/stock-items.cpp:169 +#: ../../po/../src/ui/stock-items.cpp:170 +#: ../../po/../src/ui/stock-items.cpp:171 +#: ../../po/../src/ui/stock-items.cpp:172 +#: ../../po/../src/ui/stock-items.cpp:175 +#: ../../po/../src/ui/stock-items.cpp:176 +#: ../../po/../src/ui/stock-items.cpp:177 +#: ../../po/../src/ui/stock-items.cpp:178 +#: ../../po/../src/ui/stock-items.cpp:181 +#: ../../po/../src/ui/stock-items.cpp:182 +#: ../../po/../src/ui/stock-items.cpp:183 +#: ../../po/../src/ui/stock-items.cpp:184 +#: ../../po/../src/ui/stock-items.cpp:185 +#: ../../po/../src/ui/stock-items.cpp:186 +#: ../../po/../src/ui/stock-items.cpp:187 +#: ../../po/../src/ui/stock-items.cpp:188 +#: ../../po/../src/ui/stock-items.cpp:189 +#: ../../po/../src/ui/stock-items.cpp:190 +#: ../../po/../src/ui/stock-items.cpp:191 +#: ../../po/../src/ui/stock-items.cpp:194 +#: ../../po/../src/ui/stock-items.cpp:195 +#: ../../po/../src/ui/stock-items.cpp:198 +#: ../../po/../src/ui/stock-items.cpp:199 +#: ../../po/../src/ui/stock-items.cpp:200 +#: ../../po/../src/ui/stock-items.cpp:201 +#: ../../po/../src/ui/stock-items.cpp:202 +msgid "PLACEHOLDER, do not translate" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:88 +msgid "small" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:89 +msgid "medium" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:90 +#, fuzzy +msgid "large" +msgstr "OdrediÅ¡te:" + +#: ../../po/../src/ui/widget/panel.cpp:91 +msgid "huge" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:106 +#, fuzzy +msgid "List" +msgstr "suzženo" + +#: ../../po/../src/ui/widget/selected-style.cpp:67 +msgid "F:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:68 +msgid "S:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:69 +msgid "O:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:95 +msgid "N/A" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:98 +#: ../../po/../src/ui/widget/selected-style.cpp:712 +#, fuzzy +msgid "Nothing selected" +msgstr "Preliv nije izabran" + +#: ../../po/../src/ui/widget/selected-style.cpp:103 +msgid "No fill" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:103 +#, fuzzy +msgid "No stroke" +msgstr " (linija)" + +#: ../../po/../src/ui/widget/selected-style.cpp:105 +#: ../../po/../src/widgets/paint-selector.cpp:190 +msgid "Pattern" +msgstr "Mustra" + +#: ../../po/../src/ui/widget/selected-style.cpp:108 +#: ../../po/../src/widgets/paint-selector.cpp:885 +msgid "Pattern fill" +msgstr "Mustra" + +#: ../../po/../src/ui/widget/selected-style.cpp:108 +#, fuzzy +msgid "Pattern stroke" +msgstr "Razmak Å¡ablona" + +#: ../../po/../src/ui/widget/selected-style.cpp:110 +#, fuzzy +msgid "L Gradient" +msgstr "Uređivač preliva" + +#: ../../po/../src/ui/widget/selected-style.cpp:113 +#, fuzzy +msgid "Linear gradient fill" +msgstr "Linijski preliv" + +#: ../../po/../src/ui/widget/selected-style.cpp:113 +#, fuzzy +msgid "Linear gradient stroke" +msgstr "Linijski preliv" + +#: ../../po/../src/ui/widget/selected-style.cpp:115 +#, fuzzy +msgid "R Gradient" +msgstr "Uređivač preliva" + +#: ../../po/../src/ui/widget/selected-style.cpp:118 +#, fuzzy +msgid "Radial gradient fill" +msgstr "Kružni preliv" + +#: ../../po/../src/ui/widget/selected-style.cpp:118 +#, fuzzy +msgid "Radial gradient stroke" +msgstr "Kružni preliv" + +#: ../../po/../src/ui/widget/selected-style.cpp:120 +#, fuzzy +msgid "Different" +msgstr "_Razlikuj" + +#: ../../po/../src/ui/widget/selected-style.cpp:123 +#, fuzzy +msgid "Different fills" +msgstr "_Razlikuj" + +#: ../../po/../src/ui/widget/selected-style.cpp:123 +#, fuzzy +msgid "Different strokes" +msgstr "_Razlikuj" + +#: ../../po/../src/ui/widget/selected-style.cpp:125 +#, fuzzy +msgid "Unset" +msgstr "suzženo" + +#. TRANSLATORS COMMENT: unset is a verb here +#: ../../po/../src/ui/widget/selected-style.cpp:128 +#: ../../po/../src/ui/widget/selected-style.cpp:182 +msgid "Unset fill" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:128 +#: ../../po/../src/ui/widget/selected-style.cpp:182 +#, fuzzy +msgid "Unset stroke" +msgstr " (linija)" + +#: ../../po/../src/ui/widget/selected-style.cpp:131 +#, fuzzy +msgid "Flat color fill" +msgstr "Jednobojno" + +#: ../../po/../src/ui/widget/selected-style.cpp:131 +#, fuzzy +msgid "Flat color stroke" +msgstr "Jednobojno" + +#. TRANSLATOR COMMENT: A means "Averaged" +#: ../../po/../src/ui/widget/selected-style.cpp:134 +#, fuzzy +msgid "A" +msgstr "_P" + +#: ../../po/../src/ui/widget/selected-style.cpp:137 +#, fuzzy +msgid "Fill is averaged over selected objects" +msgstr "" +"Izuzimanje ILI izabranih objekata (neparne preklopljene povrÅ¡ine se briÅ¡u)" + +#: ../../po/../src/ui/widget/selected-style.cpp:137 +#, fuzzy +msgid "Stroke is averaged over selected objects" +msgstr "Presecanje izabranih objekata" + +#. TRANSLATOR COMMENT: M means "Multiple" +#: ../../po/../src/ui/widget/selected-style.cpp:140 +#, fuzzy +msgid "M" +msgstr "_M" + +#: ../../po/../src/ui/widget/selected-style.cpp:143 +#, fuzzy +msgid "Multiple selected objects have the same fill" +msgstr "Poravnava izabrane čvorove uspravno" + +#: ../../po/../src/ui/widget/selected-style.cpp:143 +#, fuzzy +msgid "Multiple selected objects have the same stroke" +msgstr "Poravnava izabrane čvorove uspravno" + +#: ../../po/../src/ui/widget/selected-style.cpp:145 +#, fuzzy +msgid "Edit fill..." +msgstr "Uredi..." + +#: ../../po/../src/ui/widget/selected-style.cpp:145 +#, fuzzy +msgid "Edit stroke..." +msgstr "Uredi..." + +#: ../../po/../src/ui/widget/selected-style.cpp:149 +#, fuzzy +msgid "Last set color" +msgstr "Jednobojno" + +#: ../../po/../src/ui/widget/selected-style.cpp:153 +#, fuzzy +msgid "Last selected color" +msgstr "Poslednji" + +#: ../../po/../src/ui/widget/selected-style.cpp:157 +msgid "White" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:161 +#: ../../po/../src/widgets/sp-color-scales.cpp:461 +#: ../../po/../src/widgets/sp-color-scales.cpp:462 +msgid "Black" +msgstr "Crna" + +#: ../../po/../src/ui/widget/selected-style.cpp:165 +#, fuzzy +msgid "Copy color" +msgstr "Stanica boje" + +#: ../../po/../src/ui/widget/selected-style.cpp:169 +#, fuzzy +msgid "Paste color" +msgstr "Jednobojno" + +#: ../../po/../src/ui/widget/selected-style.cpp:173 +#, fuzzy +msgid "Swap fill and stroke" +msgstr "_Popune i linije" + +#: ../../po/../src/ui/widget/selected-style.cpp:177 +msgid "Make fill opaque" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:177 +msgid "Make stroke opaque" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:186 +#, fuzzy +msgid "Remove fill" +msgstr " _Ukloni " + +#: ../../po/../src/ui/widget/selected-style.cpp:186 +#, fuzzy +msgid "Remove stroke" +msgstr "_Ukloni vezu" + +#: ../../po/../src/ui/widget/selected-style.cpp:718 +#, fuzzy +msgid "Master opacity" +msgstr "Osnovna _providnost" + +#: ../../po/../src/ui/widget/selected-style.cpp:744 +msgid "0 (transparent)" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:768 +msgid "1.0 (opaque)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1046 +msgid "Moved to next layer." +msgstr "PremeÅ¡teno na sledeći sloj." + +#: ../../po/../src/verbs.cpp:1048 +#, fuzzy +msgid "Cannot move past last layer." +msgstr "Nije moguće premeÅ¡tanje iza poslednjeg sloja." + +#: ../../po/../src/verbs.cpp:1057 +msgid "Moved to previous layer." +msgstr "PremeÅ¡teno na prethodni sloj." + +#: ../../po/../src/verbs.cpp:1059 +#, fuzzy +msgid "Cannot move past first layer." +msgstr "Nije moguće premeÅ¡tanje ispred prvog sloja." + +#: ../../po/../src/verbs.cpp:1076 ../../po/../src/verbs.cpp:1150 +msgid "No current layer." +msgstr "Nema trenutnog sloja." + +#: ../../po/../src/verbs.cpp:1105 +#, c-format +msgid "Raised layer %s." +msgstr "Sloj %s je izdignut." + +#: ../../po/../src/verbs.cpp:1109 +#, c-format +msgid "Lowered layer %s." +msgstr "Sloj %s je spuÅ¡ten." + +#: ../../po/../src/verbs.cpp:1118 +#, fuzzy +msgid "Cannot move layer any further." +msgstr "ViÅ¡e nije moguće premeÅ¡tati sloj." + +#. TRANSLATORS: this means "The layer has been deleted." +#: ../../po/../src/verbs.cpp:1148 +msgid "Deleted layer." +msgstr "Sloj je obrisan." + +#: ../../po/../src/verbs.cpp:1544 +msgid "" +"You need to connect to a Jabber server before sharing a document with " +"another user." +msgstr "" + +#: ../../po/../src/verbs.cpp:1559 +msgid "" +"You need to connect to a Jabber server before sharing a document with a " +"chatroom." +msgstr "" + +#: ../../po/../src/verbs.cpp:1569 +msgid "XML node tracker has not been initialized; nothing to dump" +msgstr "" + +#. TRANSLATORS: If you have translated the keys.svg file to your language, then +#. translate this string as "keys.LANG.svg" (where LANG is your language code); +#. otherwise leave as "keys.svg". +#: ../../po/../src/verbs.cpp:1631 +msgid "keys.svg" +msgstr "keys.svg" + +#. TRANSLATORS: If you have translated the tutorial-basic.svg file to your language, +#. then translate this string as "tutorial-basic.LANG.svg" (where LANG is your language +#. code); otherwise leave as "tutorial-basic.svg". +#: ../../po/../src/verbs.cpp:1667 +msgid "tutorial-basic.svg" +msgstr "tutorial-basic.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1671 +msgid "tutorial-shapes.svg" +msgstr "tutorial-shapes.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1675 +msgid "tutorial-advanced.svg" +msgstr "tutorial-advanced.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1679 +msgid "tutorial-tracing.svg" +msgstr "tutorial-tracing.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1683 +msgid "tutorial-calligraphy.svg" +msgstr "tutorial-calligraphy.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1687 +msgid "tutorial-elements.svg" +msgstr "tutorial-elements.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1691 +msgid "tutorial-tips.svg" +msgstr "tutorial-tips.svg" + +#: ../../po/../src/verbs.cpp:1842 +msgid "Does nothing" +msgstr "Ne čini niÅ¡ta" + +#. File +#: ../../po/../src/verbs.cpp:1845 +msgid "Default" +msgstr "Podrazumevano" + +#: ../../po/../src/verbs.cpp:1845 +msgid "Create new document from default template" +msgstr "Napravi novi dokument po podrazumevanom Å¡ablonu" + +#: ../../po/../src/verbs.cpp:1847 +msgid "_Open..." +msgstr "_Otvori..." + +#: ../../po/../src/verbs.cpp:1848 +msgid "Open existing document" +msgstr "Otvori postojeći SVG dokument" + +#: ../../po/../src/verbs.cpp:1849 +msgid "Re_vert" +msgstr "_Oporavak" + +#: ../../po/../src/verbs.cpp:1850 +msgid "Revert to the last saved version of document (changes will be lost)" +msgstr "" +"Povraćaj poslednje sačuvane verzije dokumenta (izmene će biti zanemarene)" + +#: ../../po/../src/verbs.cpp:1851 +msgid "_Save" +msgstr "_Sačuvaj" + +#: ../../po/../src/verbs.cpp:1851 +msgid "Save document" +msgstr "Sačuvaj dokument" + +#: ../../po/../src/verbs.cpp:1853 +msgid "Save _As..." +msgstr "Sačuvaj _kao..." + +#: ../../po/../src/verbs.cpp:1854 +msgid "Save document under new name" +msgstr "Sačuvaj dokument pod novim imenom" + +#: ../../po/../src/verbs.cpp:1855 +msgid "_Print..." +msgstr "_Å tampaj..." + +#: ../../po/../src/verbs.cpp:1855 +msgid "Print document" +msgstr "Å tampaj dokument" + +#. TRANSLATORS: "Vacuum Defs" means "Clean up defs" (so as to remove unused definitions) +#: ../../po/../src/verbs.cpp:1858 +msgid "Vac_uum Defs" +msgstr "Pr_ečisti definicije" + +#: ../../po/../src/verbs.cpp:1858 +#, fuzzy +msgid "Remove unused predefined items from the <defs> of the document" +msgstr "Uklanja neupotrebljive stavke iz <defs> dokumenta" + +#: ../../po/../src/verbs.cpp:1860 +msgid "Print _Direct" +msgstr "_Neposredna Å¡tampa" + +#: ../../po/../src/verbs.cpp:1861 +#, fuzzy +msgid "Print directly without prompting to a file or pipe" +msgstr "Å tampaj neposredno u datoteku ili cev" + +#: ../../po/../src/verbs.cpp:1862 +msgid "Print Previe_w" +msgstr "Pregled pre_d Å¡tampu" + +#: ../../po/../src/verbs.cpp:1863 +msgid "Preview document printout" +msgstr "Pregled izlaza dokumenta za Å¡tampanje" + +#: ../../po/../src/verbs.cpp:1864 +msgid "_Import..." +msgstr "_Uvezi..." + +#: ../../po/../src/verbs.cpp:1865 +msgid "Import bitmap or SVG image into document" +msgstr "Uvezi bitmapu ili SVG sliku u dokument" + +#: ../../po/../src/verbs.cpp:1866 +msgid "_Export Bitmap..." +msgstr "_Izvezi bitmapu..." + +#: ../../po/../src/verbs.cpp:1867 +#, fuzzy +msgid "Export document or selection as a bitmap image" +msgstr "Izvezi dokument ili izbor kao PNG sliku" + +#: ../../po/../src/verbs.cpp:1868 +msgid "N_ext Window" +msgstr "Sl_edeći prozor" + +#: ../../po/../src/verbs.cpp:1869 +msgid "Switch to the next document window" +msgstr "Prelazak na sledeći prozor dokumenta" + +#: ../../po/../src/verbs.cpp:1870 +msgid "P_revious Window" +msgstr "P_rethodni prozor" + +#: ../../po/../src/verbs.cpp:1871 +msgid "Switch to the previous document window" +msgstr "Prelazak na prethodni prozor dokumenta" + +#: ../../po/../src/verbs.cpp:1872 +msgid "_Close" +msgstr "_Zatvori" + +#: ../../po/../src/verbs.cpp:1873 +msgid "Close window" +msgstr "Zatvaranje ovog prozora" + +#: ../../po/../src/verbs.cpp:1874 +msgid "_Quit" +msgstr "_Izlaz" + +#: ../../po/../src/verbs.cpp:1874 +msgid "Quit Inkscape" +msgstr "NapuÅ¡tanje InkSkejpa" + +#. Edit +#: ../../po/../src/verbs.cpp:1877 +msgid "_Undo" +msgstr "_Opozovi" + +#: ../../po/../src/verbs.cpp:1877 +msgid "Undo last action" +msgstr "PoniÅ¡ti poslednju akciju" + +#: ../../po/../src/verbs.cpp:1879 +msgid "_Redo" +msgstr "_Ponovi" + +#: ../../po/../src/verbs.cpp:1880 +msgid "Do again last undone action" +msgstr "Ponovi opozvanu akciju" + +#: ../../po/../src/verbs.cpp:1881 +msgid "Cu_t" +msgstr "I_seci" + +#: ../../po/../src/verbs.cpp:1882 +msgid "Cut selection to clipboard" +msgstr "Iseci izabrane objekte i smesti ih u klipbord" + +#: ../../po/../src/verbs.cpp:1883 +msgid "_Copy" +msgstr "_Umnoži" + +#: ../../po/../src/verbs.cpp:1884 +msgid "Copy selection to clipboard" +msgstr "Umnoži izabrane objekte u klipbord" + +#: ../../po/../src/verbs.cpp:1885 +msgid "_Paste" +msgstr "U_baci" + +#: ../../po/../src/verbs.cpp:1886 +#, fuzzy +msgid "Paste objects from clipboard to mouse point" +msgstr "Ubaci objekte iz klipborda" + +#: ../../po/../src/verbs.cpp:1887 +msgid "Paste _Style" +msgstr "Ubaci _stil" + +#: ../../po/../src/verbs.cpp:1888 +msgid "Apply style of the copied object to selection" +msgstr "Primeni stil umnoženog objekta na izbor" + +#: ../../po/../src/verbs.cpp:1889 +msgid "Paste _In Place" +msgstr "Ubaci u _prostor" + +#: ../../po/../src/verbs.cpp:1890 +#, fuzzy +msgid "Paste objects from clipboard to the original location" +msgstr "Ubaci objekte iz klipborda na originalnu poziciju" + +#: ../../po/../src/verbs.cpp:1891 +msgid "_Delete" +msgstr "_ObriÅ¡i" + +#: ../../po/../src/verbs.cpp:1892 +msgid "Delete selection" +msgstr "ObriÅ¡i izbor" + +#: ../../po/../src/verbs.cpp:1893 +msgid "Duplic_ate" +msgstr "Ud_vostruči" + +#: ../../po/../src/verbs.cpp:1894 +#, fuzzy +msgid "Duplicate selected objects" +msgstr "Udvostruči izabrane objekte" + +#: ../../po/../src/verbs.cpp:1895 +msgid "Clo_ne" +msgstr "_Kloniraj" + +#: ../../po/../src/verbs.cpp:1896 +msgid "Create a clone of selected object (a copy linked to the original)" +msgstr "Napravi klon izabranog objekta (umnožak povezan sa originalom)" + +#: ../../po/../src/verbs.cpp:1897 +msgid "Unlin_k Clone" +msgstr "Odve_ži klon" + +#: ../../po/../src/verbs.cpp:1898 +msgid "Cut the clone's link to its original" +msgstr "Ukloni vezu klona sa originalom" + +#: ../../po/../src/verbs.cpp:1899 +msgid "Select _Original" +msgstr "Izaberi _original" + +#: ../../po/../src/verbs.cpp:1900 +msgid "Select the object to which the clone is linked" +msgstr "Izaberi objekat sa kojim je klon povezan" + +#. TRANSLATORS: Convert selection to a rectangle with tiled pattern fill +#: ../../po/../src/verbs.cpp:1902 +#, fuzzy +msgid "O_bjects to Pattern" +msgstr "Iz_bor u mustru" + +#: ../../po/../src/verbs.cpp:1903 +msgid "Convert selection to a rectangle with tiled pattern fill" +msgstr "Pretvaranje izbora u pravougaonik sa popunom od popločane mustre" + +#. TRANSLATORS: Extract objects from a tiled pattern fill +#: ../../po/../src/verbs.cpp:1905 +#, fuzzy +msgid "Pattern to Ob_jects" +msgstr "Mustra u ob_jekte" + +#: ../../po/../src/verbs.cpp:1906 +msgid "Extract objects from a tiled pattern fill" +msgstr "Izdvaja objekte iz popune sa popločanom mustrom" + +#: ../../po/../src/verbs.cpp:1907 +msgid "Clea_r All" +msgstr "O_čisti sve" + +#: ../../po/../src/verbs.cpp:1908 +msgid "Delete all objects from document" +msgstr "ObriÅ¡i sve objekte iz dokumenta" + +#: ../../po/../src/verbs.cpp:1909 +msgid "Select Al_l" +msgstr "Iza_beri sve" + +#: ../../po/../src/verbs.cpp:1910 +msgid "Select all objects or all nodes" +msgstr "Izaberi sve objekte ili sve čvorove" + +#: ../../po/../src/verbs.cpp:1911 +msgid "Select All in All La_yers" +msgstr "Izaberi sve na svim s_lojevima" + +#: ../../po/../src/verbs.cpp:1912 +msgid "Select all objects in all visible and unlocked layers" +msgstr "Izaberi sve objekte na svim vidljivim i nezaključanim slojevima" + +#: ../../po/../src/verbs.cpp:1913 +msgid "In_vert Selection" +msgstr "Iz_vrni izbor" + +#: ../../po/../src/verbs.cpp:1914 +msgid "Invert selection (unselect what is selected and select everything else)" +msgstr "" +"Izvrtanje izbora (uklanja se izbor onoga Å¡to je izabrano i vrÅ¡i se izbor " +"svega Å¡to nije bilo izabrano)" + +#: ../../po/../src/verbs.cpp:1915 +msgid "Invert in All Layers" +msgstr "Izvrni na svim slojevima" + +#: ../../po/../src/verbs.cpp:1916 +msgid "Invert selection in all visible and unlocked layers" +msgstr "Izvrni izbor u svim vidljivim i otključanim slojevima" + +#: ../../po/../src/verbs.cpp:1917 +msgid "D_eselect" +msgstr "U_kini izbor" + +#: ../../po/../src/verbs.cpp:1918 +msgid "Deselect any selected objects or nodes" +msgstr "Ukini izbor objekata ili čvorova" + +#. Selection +#: ../../po/../src/verbs.cpp:1921 +msgid "Raise to _Top" +msgstr "Izdigni na _vrh" + +#: ../../po/../src/verbs.cpp:1922 +msgid "Raise selection to top" +msgstr "Izdigni izabrane objekte ispred ostalih" + +#: ../../po/../src/verbs.cpp:1923 +msgid "Lower to _Bottom" +msgstr "Zakloni na _dno" + +#: ../../po/../src/verbs.cpp:1924 +msgid "Lower selection to bottom" +msgstr "Postavi izabrane objekte iza ostalih" + +#: ../../po/../src/verbs.cpp:1925 +msgid "_Raise" +msgstr "_Izdigni" + +#: ../../po/../src/verbs.cpp:1926 +msgid "Raise selection one step" +msgstr "Izdigni izabrane objekte ispred ostalih" + +#: ../../po/../src/verbs.cpp:1927 +msgid "_Lower" +msgstr "_Spusti" + +#: ../../po/../src/verbs.cpp:1928 +msgid "Lower selection one step" +msgstr "Spusti izabrane objekte za jedan nivo" + +#: ../../po/../src/verbs.cpp:1929 +msgid "_Group" +msgstr "_GrupiÅ¡i" + +#: ../../po/../src/verbs.cpp:1930 +msgid "Group selected objects" +msgstr "GrupiÅ¡i izabrane objekte" + +#: ../../po/../src/verbs.cpp:1932 +#, fuzzy +msgid "Ungroup selected groups" +msgstr "RazgrupiÅ¡i izabrane objekte" + +#: ../../po/../src/verbs.cpp:1934 +msgid "_Put on Path" +msgstr "_Tekst na krivu" + +#: ../../po/../src/verbs.cpp:1935 +msgid "Put text on path" +msgstr "Postavlja tekst na krivu" + +#: ../../po/../src/verbs.cpp:1936 +msgid "_Remove from Path" +msgstr "_Ukloni sa krive" + +#: ../../po/../src/verbs.cpp:1937 +msgid "Remove text from path" +msgstr "ukloni tekst sa krive" + +#: ../../po/../src/verbs.cpp:1938 +msgid "Remove Manual _Kerns" +msgstr "Ukloni ručne _kerninge" + +#. TRANSLATORS: "glyph": An image used in the visual representation of characters; +#. roughly speaking, how a character looks. A font is a set of glyphs. +#: ../../po/../src/verbs.cpp:1941 +msgid "Remove all manual kerns and glyph rotations from a text object" +msgstr "Ukloni sve ručne kerninge i rotacije grafema iz tekstualnog objekta" + +#: ../../po/../src/verbs.cpp:1943 +msgid "_Union" +msgstr "_Sjedini" + +#: ../../po/../src/verbs.cpp:1944 +msgid "Union of selected objects" +msgstr "Sjedini izabrane objekte" + +#: ../../po/../src/verbs.cpp:1945 +msgid "_Intersection" +msgstr "_Preseci" + +#: ../../po/../src/verbs.cpp:1946 +msgid "Intersection of selected objects" +msgstr "Presecanje izabranih objekata" + +#: ../../po/../src/verbs.cpp:1947 +msgid "_Difference" +msgstr "_Razlikuj" + +#: ../../po/../src/verbs.cpp:1948 +msgid "Difference of selected objects (bottom minus top)" +msgstr "Razlika izabranih objekata (donji minus gornji)" + +#: ../../po/../src/verbs.cpp:1949 +msgid "E_xclusion" +msgstr "I_zuzmi" + +#: ../../po/../src/verbs.cpp:1950 +msgid "Exclusive OR of selected objects" +msgstr "" +"Izuzimanje ILI izabranih objekata (neparne preklopljene povrÅ¡ine se briÅ¡u)" + +#: ../../po/../src/verbs.cpp:1951 +msgid "Di_vision" +msgstr "P_odeli" + +#: ../../po/../src/verbs.cpp:1952 +msgid "Cut the bottom object into pieces" +msgstr "Iseci donji objekat u preklopljene delove sa gornjim" + +#. TRANSLATORS: "to cut a path" is not the same as "to break a path apart" - see the +#. Advanced tutorial for more info +#: ../../po/../src/verbs.cpp:1955 +msgid "Cut _Path" +msgstr "Iseci _liniju" + +#: ../../po/../src/verbs.cpp:1956 +msgid "Cut the bottom object's stroke into pieces, removing fill" +msgstr "" +"Iseci liniju donjeg objekta u preklopljene delove sa gornjim, uklanjanje " +"popune" + +#. TRANSLATORS: "outset": expand a shape by offsetting the object's path, +#. i.e. by displacing it perpendicular to the path in each point. +#. See also the Advanced Tutorial for explanation. +#: ../../po/../src/verbs.cpp:1960 +msgid "Outs_et" +msgstr "Pro_Å¡iri" + +#: ../../po/../src/verbs.cpp:1961 +#, fuzzy +msgid "Outset selected paths" +msgstr "ProÅ¡irivanje izabrane krive povećavanjem ka spoljaÅ¡njosti" + +#: ../../po/../src/verbs.cpp:1963 +msgid "O_utset Path by 1 px" +msgstr "Pr_oÅ¡iri krivu za 1 px" + +#: ../../po/../src/verbs.cpp:1964 +#, fuzzy +msgid "Outset selected paths by 1 px" +msgstr "ProÅ¡irivanje izabrane krive povećavanjem ka spoljaÅ¡njosti za 1 px" + +#: ../../po/../src/verbs.cpp:1966 +msgid "O_utset Path by 10 px" +msgstr "Pr_oÅ¡iri krivu za 10 px" + +#: ../../po/../src/verbs.cpp:1967 +#, fuzzy +msgid "Outset selected paths by 10 px" +msgstr "ProÅ¡irivanje izabrane krive povećavanjem ka spoljaÅ¡njosti za 10 px" + +#. TRANSLATORS: "inset": contract a shape by offsetting the object's path, +#. i.e. by displacing it perpendicular to the path in each point. +#. See also the Advanced Tutorial for explanation. +#: ../../po/../src/verbs.cpp:1971 +msgid "I_nset" +msgstr "_Suzi" + +#: ../../po/../src/verbs.cpp:1972 +#, fuzzy +msgid "Inset selected paths" +msgstr "Sužavanje izabrane krivee ka unutraÅ¡njosti" + +#: ../../po/../src/verbs.cpp:1974 +msgid "I_nset Path by 1 px" +msgstr "S_uzi krivu za 1 px" + +#: ../../po/../src/verbs.cpp:1975 +#, fuzzy +msgid "Inset selected paths by 1 px" +msgstr "Sužavanje izabrane krive ka unutraÅ¡njosti za 1 px" + +#: ../../po/../src/verbs.cpp:1977 +msgid "I_nset Path by 10 px" +msgstr "S_uzi krivu za 10 px" + +#: ../../po/../src/verbs.cpp:1978 +#, fuzzy +msgid "Inset selected paths by 10 px" +msgstr "Sužavanje izabrane krive ka unutraÅ¡njosti za 10 px" + +#: ../../po/../src/verbs.cpp:1980 +msgid "D_ynamic Offset" +msgstr "D_inamičko pomeranje" + +#: ../../po/../src/verbs.cpp:1980 +msgid "Create a dynamic offset object" +msgstr "Pravljenje objekta koji se može dinamički pomerati" + +#: ../../po/../src/verbs.cpp:1982 +msgid "_Linked Offset" +msgstr "Uređivanje _klona" + +#: ../../po/../src/verbs.cpp:1983 +msgid "Create a dynamic offset object linked to the original path" +msgstr "Klonira objekat za transformaciju i povezuje ga sa originalom" + +#: ../../po/../src/verbs.cpp:1985 +msgid "_Stroke to Path" +msgstr "_Potez u krivu" + +#: ../../po/../src/verbs.cpp:1986 +#, fuzzy +msgid "Convert selected strokes to paths" +msgstr "Pretvori izabrane poteze u krive" + +#: ../../po/../src/verbs.cpp:1987 +msgid "Si_mplify" +msgstr "Po_jednostavi" + +#: ../../po/../src/verbs.cpp:1988 +#, fuzzy +msgid "Simplify selected paths by removing extra nodes" +msgstr "Pojednostavi izabrane krive uklanjanjem suviÅ¡nih čvorova" + +#: ../../po/../src/verbs.cpp:1989 +msgid "_Reverse" +msgstr "P_reusmeravanje" + +#: ../../po/../src/verbs.cpp:1990 +#, fuzzy +msgid "Reverses the direction of selected paths; useful for flipping markers" +msgstr "Obrtanje smera izabrane krive; korisno za obrtanje markera" + +#. TRANSLATORS: "to trace" means "to convert a bitmap to vector graphics" (to vectorize) +#: ../../po/../src/verbs.cpp:1992 +msgid "_Trace Bitmap" +msgstr "_Precrtavanje" + +#: ../../po/../src/verbs.cpp:1993 +msgid "Convert bitmap object to paths" +msgstr "Precrtavanje bitmapirane slike u vektorske krive" + +#: ../../po/../src/verbs.cpp:1994 +msgid "_Make a Bitmap Copy" +msgstr "_Napravi duplikat bitmape" + +#: ../../po/../src/verbs.cpp:1995 +msgid "Export selection to a bitmap and insert it into document" +msgstr "Izvoz izbora u bitmapu i ubacivanje te bitmape u dokument" + +#: ../../po/../src/verbs.cpp:1996 +msgid "_Combine" +msgstr "_Spoj u oblik" + +#: ../../po/../src/verbs.cpp:1997 +msgid "Combine several paths into one" +msgstr "Spoj viÅ¡e kriva u jednu" + +#. TRANSLATORS: "to cut a path" is not the same as "to break a path apart" - see the +#. Advanced tutorial for more info +#: ../../po/../src/verbs.cpp:2000 +msgid "Break _Apart" +msgstr "_Razdvoj oblik" + +#: ../../po/../src/verbs.cpp:2001 +#, fuzzy +msgid "Break selected paths into subpaths" +msgstr "Razdvoj izabranu krivu na podkrive" + +#: ../../po/../src/verbs.cpp:2002 +msgid "Gri_d Arrange..." +msgstr "Uklapanje u _mrežu..." + +#: ../../po/../src/verbs.cpp:2003 +msgid "Arrange selection in grid pattern" +msgstr "Uklapanje izabranih objekata u mrežu" + +#. Layer +#: ../../po/../src/verbs.cpp:2005 +msgid "_Add Layer..." +msgstr "_Novi sloj..." + +#: ../../po/../src/verbs.cpp:2006 +msgid "Create a new layer" +msgstr "Pravljenje novog sloja" + +#: ../../po/../src/verbs.cpp:2007 +msgid "Re_name Layer..." +msgstr "_Preimenuj sloj..." + +#: ../../po/../src/verbs.cpp:2008 +msgid "Rename the current layer" +msgstr "Promena naziva trenutnog sloja" + +#: ../../po/../src/verbs.cpp:2009 +msgid "Switch to Layer Abov_e" +msgstr "Pređi na _gornji sloj" + +#: ../../po/../src/verbs.cpp:2010 +msgid "Switch to the layer above the current" +msgstr "Prelazak na prvi sloj iznad trenutnog" + +#: ../../po/../src/verbs.cpp:2011 +msgid "Switch to Layer Belo_w" +msgstr "Pređi na _donji sloj" + +#: ../../po/../src/verbs.cpp:2012 +msgid "Switch to the layer below the current" +msgstr "Prelazak na prvi sloj ispod trenutnog" + +#: ../../po/../src/verbs.cpp:2013 +msgid "Move Selection to Layer Abo_ve" +msgstr "Premesti izbor na go_rnji sloj" + +#: ../../po/../src/verbs.cpp:2014 +msgid "Move selection to the layer above the current" +msgstr "PremeÅ¡ta izbor na prvi sloj iznad trenutnog" + +#: ../../po/../src/verbs.cpp:2015 +msgid "Move Selection to Layer Bel_ow" +msgstr "Premesti izbor na d_onji sloj" + +#: ../../po/../src/verbs.cpp:2016 +msgid "Move selection to the layer below the current" +msgstr "PremeÅ¡ta izbor na prvi sloj ispod trenutnog" + +#: ../../po/../src/verbs.cpp:2017 +msgid "Layer to _Top" +msgstr "Sloj na _vrh" + +#: ../../po/../src/verbs.cpp:2018 +msgid "Raise the current layer to the top" +msgstr "Izdizanje trenutnog sloja ispred ostalih" + +#: ../../po/../src/verbs.cpp:2019 +msgid "Layer to _Bottom" +msgstr "Sloj na _dno" + +#: ../../po/../src/verbs.cpp:2020 +msgid "Lower the current layer to the bottom" +msgstr "Postavi trenutni sloj iza ostalih" + +#: ../../po/../src/verbs.cpp:2021 +msgid "_Raise Layer" +msgstr "_Izdigni sloj" + +#: ../../po/../src/verbs.cpp:2022 +msgid "Raise the current layer" +msgstr "Izdizanje trenutnog sloja" + +#: ../../po/../src/verbs.cpp:2023 +msgid "_Lower Layer" +msgstr "_Zakloni sloj" + +#: ../../po/../src/verbs.cpp:2024 +msgid "Lower the current layer" +msgstr "SpuÅ¡ta trenutnog sloja" + +#: ../../po/../src/verbs.cpp:2025 +msgid "_Delete Current Layer" +msgstr "_Ukloni trenutni sloj" + +#: ../../po/../src/verbs.cpp:2026 +msgid "Delete the current layer" +msgstr "Uklanja trenutni sloj" + +#. Object +#: ../../po/../src/verbs.cpp:2029 +#, fuzzy +msgid "Rotate _90° CW" +msgstr "Rotiraj za _90° u desno" + +#: ../../po/../src/verbs.cpp:2030 +#, fuzzy +msgid "Rotate selection 90° clockwise" +msgstr "Rotira za 90° u smeru kazaljke na satu" + +#: ../../po/../src/verbs.cpp:2031 +#, fuzzy +msgid "Rotate 9_0° CCW" +msgstr "Rotiraj za 9_0° u levo" + +#: ../../po/../src/verbs.cpp:2032 +#, fuzzy +msgid "Rotate selection 90° counter-clockwise" +msgstr "Rotira za 90° u obrnutom smeru od smera kazaljke na satu" + +#: ../../po/../src/verbs.cpp:2033 +msgid "Remove _Transformations" +msgstr "PoniÅ¡ti _transformaciju" + +#: ../../po/../src/verbs.cpp:2034 +msgid "Remove transformations from object" +msgstr "Uklanja transformacije objekta" + +#: ../../po/../src/verbs.cpp:2035 +msgid "_Object to Path" +msgstr "_Objekat u liniju" + +#: ../../po/../src/verbs.cpp:2036 +#, fuzzy +msgid "Convert selected objects to paths" +msgstr "Pretvara izabrani objekat u krivu" + +#: ../../po/../src/verbs.cpp:2037 +msgid "_Flow into Frame" +msgstr "_Postavi u okvir" + +#: ../../po/../src/verbs.cpp:2038 +#, fuzzy +msgid "Put text into frames" +msgstr "Postavlja tekst u okvir" + +#: ../../po/../src/verbs.cpp:2039 +msgid "_Unflow" +msgstr "_Neplutajući tekst" + +#: ../../po/../src/verbs.cpp:2040 +msgid "Remove text from frame (creates a single-line text object)" +msgstr "Sklanja tekst iz okvira (pravi jednolinijski tekst)" + +#: ../../po/../src/verbs.cpp:2041 +msgid "_Convert to Text" +msgstr "_Pretvori u tekst" + +#: ../../po/../src/verbs.cpp:2042 +#, fuzzy +msgid "Convert flowed text to regular text objects (preserves appearance)" +msgstr "Pretvara izabrani plutajući tekst u regularan tekst objekat" + +#: ../../po/../src/verbs.cpp:2044 +#, fuzzy +msgid "Flip _Horizontal" +msgstr "Izvrni _vodoravno" + +#: ../../po/../src/verbs.cpp:2044 +#, fuzzy +msgid "Flips selected objects horizontally" +msgstr "Poravnava izabrane čvorove vodoravno" + +#: ../../po/../src/verbs.cpp:2047 +#, fuzzy +msgid "Flip _Vertical" +msgstr "Izvrni _uspravno" + +#: ../../po/../src/verbs.cpp:2047 +#, fuzzy +msgid "Flips selected objects vertically" +msgstr "Poravnava izabrane čvorove uspravno" + +#. Tools +#: ../../po/../src/verbs.cpp:2051 +msgid "Select" +msgstr "Izbornik" + +#: ../../po/../src/verbs.cpp:2052 +msgid "Select and transform objects" +msgstr "Izbor i transformacija objekata" + +#: ../../po/../src/verbs.cpp:2053 +msgid "Node Edit" +msgstr "Uređivač čvorova" + +#: ../../po/../src/verbs.cpp:2054 +msgid "Edit path nodes or control handles" +msgstr "Uređivanje čvorova krive i kontrola ručki" + +#: ../../po/../src/verbs.cpp:2056 +msgid "Create rectangles and squares" +msgstr "Iscrtavanje pravougaonika i kvadrata" + +#: ../../po/../src/verbs.cpp:2058 +msgid "Create circles, ellipses, and arcs" +msgstr "Iscrtavanje kružnica, elipsa i lukova" + +#: ../../po/../src/verbs.cpp:2060 +msgid "Create stars and polygons" +msgstr "Iscrtavanje zvezdi i poligona" + +#: ../../po/../src/verbs.cpp:2062 +msgid "Create spirals" +msgstr "Iscrtavanje spirala" + +#: ../../po/../src/verbs.cpp:2064 +msgid "Draw freehand lines" +msgstr "Iscrtavanje linije slobodnom rukom" + +#: ../../po/../src/verbs.cpp:2066 +msgid "Draw Bezier curves and straight lines" +msgstr "Iscrtavanje bezierovih kriva i pravih linija" + +#: ../../po/../src/verbs.cpp:2068 +msgid "Draw calligraphic lines" +msgstr "Iscrtavanje kaligrafske linije" + +#: ../../po/../src/verbs.cpp:2070 +msgid "Create and edit text objects" +msgstr "Pravljenje i uređivanje teksta" + +#: ../../po/../src/verbs.cpp:2072 +msgid "Create and edit gradients" +msgstr "Pravljenje i uređivanje preliva" + +#: ../../po/../src/verbs.cpp:2074 +msgid "Zoom in or out" +msgstr "Uveličavanje i umanjenje" + +#: ../../po/../src/verbs.cpp:2076 +msgid "Pick averaged colors from image" +msgstr "Bojenje izabranog objekta prosečnom bojom povrÅ¡ine" + +#: ../../po/../src/verbs.cpp:2078 +#, fuzzy +msgid "Create connectors" +msgstr "Napravi novi SVG dokument" + +#. Tool prefs +#: ../../po/../src/verbs.cpp:2081 +msgid "Selector Preferences" +msgstr "Postavke izbornika" + +#: ../../po/../src/verbs.cpp:2082 +#, fuzzy +msgid "Open Preferences for the Selector tool" +msgstr "Otvara karticu alata za izbor u postavkama programa" + +#: ../../po/../src/verbs.cpp:2083 +msgid "Node Tool Preferences" +msgstr "Postavke čvorova" + +#: ../../po/../src/verbs.cpp:2084 +#, fuzzy +msgid "Open Preferences for the Node tool" +msgstr "Otvara karticu alata za čvorove u postavkama programa" + +# bug: rect -> rectangle +#: ../../po/../src/verbs.cpp:2085 +msgid "Rectangle Preferences" +msgstr "Postavke pravougaonika" + +#: ../../po/../src/verbs.cpp:2086 +#, fuzzy +msgid "Open Preferences for the Rectangle tool" +msgstr "Otvara karticu alata za pravougaonike u postavkama programa" + +#: ../../po/../src/verbs.cpp:2087 +msgid "Ellipse Preferences" +msgstr "Postavke elipse" + +#: ../../po/../src/verbs.cpp:2088 +#, fuzzy +msgid "Open Preferences for the Ellipse tool" +msgstr "Otvara karticu alata za elipse u postavkama programa" + +#: ../../po/../src/verbs.cpp:2089 +msgid "Star Preferences" +msgstr "Postavke zvezde" + +#: ../../po/../src/verbs.cpp:2090 +#, fuzzy +msgid "Open Preferences for the Star tool" +msgstr "Otvara karticu alata za zvezde u postavkama programa" + +#: ../../po/../src/verbs.cpp:2091 +msgid "Spiral Preferences" +msgstr "Postavke spirale" + +#: ../../po/../src/verbs.cpp:2092 +#, fuzzy +msgid "Open Preferences for the Spiral tool" +msgstr "Otvara karticu alata za spirale u postavkama programa" + +#: ../../po/../src/verbs.cpp:2093 +msgid "Pencil Preferences" +msgstr "Postavke grube olovke" + +#: ../../po/../src/verbs.cpp:2094 +#, fuzzy +msgid "Open Preferences for the Pencil tool" +msgstr "Otvara karticu alata grube olovke u postavkama programa" + +#: ../../po/../src/verbs.cpp:2095 +msgid "Pen Preferences" +msgstr "Postavke olovke" + +#: ../../po/../src/verbs.cpp:2096 +#, fuzzy +msgid "Open Preferences for the Pen tool" +msgstr "Otvara karticu alata olovke u postavkama programa" + +#: ../../po/../src/verbs.cpp:2097 +msgid "Calligraphic Preferences" +msgstr "Postavke kaligrafskog pera" + +#: ../../po/../src/verbs.cpp:2098 +#, fuzzy +msgid "Open Preferences for the Calligraphy tool" +msgstr "Otvara karticu alata za kaligrafiju u postavkama programa" + +#: ../../po/../src/verbs.cpp:2099 +msgid "Text Preferences" +msgstr "Postavke teksta" + +#: ../../po/../src/verbs.cpp:2100 +#, fuzzy +msgid "Open Preferences for the Text tool" +msgstr "Otvara karticu alata za tekst u postavkama programa" + +#: ../../po/../src/verbs.cpp:2101 +msgid "Gradient Preferences" +msgstr "Postavke preliva" + +#: ../../po/../src/verbs.cpp:2102 +#, fuzzy +msgid "Open Preferences for the Gradient tool" +msgstr "Otvara karticu preliva u postavkama programa" + +#: ../../po/../src/verbs.cpp:2103 +msgid "Zoom Preferences" +msgstr "Postavke zuma" + +#: ../../po/../src/verbs.cpp:2104 +#, fuzzy +msgid "Open Preferences for the Zoom tool" +msgstr "Otvara karticu alata za zumiranje u postavkama programa" + +#: ../../po/../src/verbs.cpp:2105 +msgid "Dropper Preferences" +msgstr "Postavke izbornika boja" + +#: ../../po/../src/verbs.cpp:2106 +#, fuzzy +msgid "Open Preferences for the Dropper tool" +msgstr "Otvara karticu alata za izbor boje u postavkama programa" + +#: ../../po/../src/verbs.cpp:2107 +#, fuzzy +msgid "Connector Preferences" +msgstr "Postavke izbornika" + +#: ../../po/../src/verbs.cpp:2108 +#, fuzzy +msgid "Open Preferences for the Connector tool" +msgstr "Otvara karticu alata za izbor u postavkama programa" + +#. Zoom/View +#: ../../po/../src/verbs.cpp:2111 +msgid "Zoom In" +msgstr "Uvećaj" + +#: ../../po/../src/verbs.cpp:2111 +msgid "Zoom in" +msgstr "Uvećavanje" + +#: ../../po/../src/verbs.cpp:2112 +msgid "Zoom Out" +msgstr "Umanji" + +#: ../../po/../src/verbs.cpp:2112 +msgid "Zoom out" +msgstr "Umanjivanje" + +#: ../../po/../src/verbs.cpp:2113 +msgid "_Rulers" +msgstr "_Lenjiri" + +#: ../../po/../src/verbs.cpp:2113 +msgid "Show or hide the canvas rulers" +msgstr "Prikaži ili sakrij lenjire platna" + +#: ../../po/../src/verbs.cpp:2114 +msgid "Scroll_bars" +msgstr "_Trake za pomeranje" + +#: ../../po/../src/verbs.cpp:2114 +msgid "Show or hide the canvas scrollbars" +msgstr "Prikaži ili sakrij trake za pomeranje platna" + +#: ../../po/../src/verbs.cpp:2115 +msgid "_Grid" +msgstr "_Mreža" + +#: ../../po/../src/verbs.cpp:2116 +msgid "G_uides" +msgstr "_Vođice" + +#: ../../po/../src/verbs.cpp:2117 +msgid "Nex_t Zoom" +msgstr "Sle_deći zum" + +#: ../../po/../src/verbs.cpp:2117 +msgid "Next zoom (from the history of zooms)" +msgstr "Sledeći zum (iz istorije promene uvećanja)" + +#: ../../po/../src/verbs.cpp:2119 +msgid "Pre_vious Zoom" +msgstr "Pre_thodni zum" + +#: ../../po/../src/verbs.cpp:2119 +msgid "Previous zoom (from the history of zooms)" +msgstr "Prethodni zum (iz istorije promene uvećanja)" + +#: ../../po/../src/verbs.cpp:2121 +msgid "Zoom 1:_1" +msgstr "Postavi razmeru na 1:_1" + +#: ../../po/../src/verbs.cpp:2121 +msgid "Zoom to 1:1" +msgstr "Postavljanje razmere na 1:1" + +#: ../../po/../src/verbs.cpp:2123 +msgid "Zoom 1:_2" +msgstr "Postavi razmeru na 1:_2" + +#: ../../po/../src/verbs.cpp:2123 +msgid "Zoom to 1:2" +msgstr "Postavljanje razmere na 1:2" + +#: ../../po/../src/verbs.cpp:2125 +msgid "_Zoom 2:1" +msgstr "Postavi _razmeru na 2:1" + +#: ../../po/../src/verbs.cpp:2125 +msgid "Zoom to 2:1" +msgstr "Postavljanje razmere na 2:1" + +#: ../../po/../src/verbs.cpp:2128 +msgid "_Fullscreen" +msgstr "_Ceo ekran" + +#: ../../po/../src/verbs.cpp:2128 +msgid "Stretch this document window to full screen" +msgstr "Razvlačenje prozora ovog dokumenta preko celog ekrana" + +#: ../../po/../src/verbs.cpp:2131 +msgid "Duplic_ate Window" +msgstr "_Udvostruči prozor" + +#: ../../po/../src/verbs.cpp:2131 +msgid "Open a new window with the same document" +msgstr "Otvaranje novog prozora sa istim dokumentom" + +#: ../../po/../src/verbs.cpp:2133 +msgid "_New View Preview" +msgstr "_Novi pregled" + +#: ../../po/../src/verbs.cpp:2134 +msgid "New View Preview" +msgstr "Novi pregled dokumenta" + +#. "view_new_preview" +#: ../../po/../src/verbs.cpp:2136 +#, fuzzy +msgid "_Normal" +msgstr "Normalno" + +#: ../../po/../src/verbs.cpp:2137 +msgid "Switch to normal display mode" +msgstr "" + +#: ../../po/../src/verbs.cpp:2138 +#, fuzzy +msgid "_Outline" +msgstr "Okvir kontejnera" + +#: ../../po/../src/verbs.cpp:2139 +msgid "Switch to outline (wireframe) display mode" +msgstr "" + +#: ../../po/../src/verbs.cpp:2141 +msgid "Ico_n Preview" +msgstr "Prikaz i_kona" + +#: ../../po/../src/verbs.cpp:2142 +msgid "Open a window to preview items at different icon resolutions" +msgstr "Otvara prozor za prikaz objekta u različitim rezolucijama ikone" + +#: ../../po/../src/verbs.cpp:2144 +msgid "Zoom to fit page in window" +msgstr "Uklopi celu stranu u prozor" + +#: ../../po/../src/verbs.cpp:2145 +msgid "Page _Width" +msgstr "_Å irina strane" + +#: ../../po/../src/verbs.cpp:2146 +msgid "Zoom to fit page width in window" +msgstr "Uklopi Å¡irinu strane u prozor" + +#: ../../po/../src/verbs.cpp:2148 +msgid "Zoom to fit drawing in window" +msgstr "Uklopi ceo crtež u prozor" + +#: ../../po/../src/verbs.cpp:2150 +msgid "Zoom to fit selection in window" +msgstr "Uklopi ceo izbor u prozor" + +#. Dialogs +#: ../../po/../src/verbs.cpp:2153 +msgid "In_kscape Preferences..." +msgstr "Postavke _programa..." + +#: ../../po/../src/verbs.cpp:2154 +msgid "Global Inkscape preferences" +msgstr "OpÅ¡ta podeÅ¡avanja InkSkejpa" + +#: ../../po/../src/verbs.cpp:2155 +msgid "_Document Preferences..." +msgstr "Postavke _dokumenta..." + +#: ../../po/../src/verbs.cpp:2156 +msgid "Preferences saved with the document" +msgstr "Postavke se čuvaju u datoteci dokumenta" + +#: ../../po/../src/verbs.cpp:2157 +msgid "_Fill and Stroke..." +msgstr "_Popune i linije..." + +#: ../../po/../src/verbs.cpp:2158 +msgid "Fill and Stroke dialog" +msgstr "Prozorče za postavke karakteristika popuna i linija" + +#. TRANSLATORS: "Swatches" means: color samples +#: ../../po/../src/verbs.cpp:2160 +#, fuzzy +msgid "S_watches..." +msgstr "Sačuvaj _kao..." + +#: ../../po/../src/verbs.cpp:2161 +msgid "View color swatches" +msgstr "" + +#: ../../po/../src/verbs.cpp:2162 +msgid "Transfor_m..." +msgstr "_Transformacija..." + +#: ../../po/../src/verbs.cpp:2163 +msgid "Transform dialog" +msgstr "Prozorče za transformacije" + +#: ../../po/../src/verbs.cpp:2164 +msgid "_Align and Distribute..." +msgstr "Por_avnavanje i raspoređivanje" + +#: ../../po/../src/verbs.cpp:2165 +msgid "Align and Distribute dialog" +msgstr "Prozorče za podeÅ¡avanje poravnavanja i raspoređivanja" + +#: ../../po/../src/verbs.cpp:2166 +msgid "_Text and Font..." +msgstr "_Tekst i font..." + +#: ../../po/../src/verbs.cpp:2167 +msgid "Text and Font dialog" +msgstr "Prozorče za postavke teksta i fonta" + +#: ../../po/../src/verbs.cpp:2168 +msgid "_XML Editor..." +msgstr "XML _uređivač" + +#: ../../po/../src/verbs.cpp:2169 +msgid "XML Editor" +msgstr "XML uređivač" + +#: ../../po/../src/verbs.cpp:2170 +msgid "_Find..." +msgstr "_Traži..." + +#: ../../po/../src/verbs.cpp:2171 +msgid "Find objects in document" +msgstr "Traženje objekta u dokumentu" + +#: ../../po/../src/verbs.cpp:2172 +msgid "_Messages..." +msgstr "_Poruke..." + +#: ../../po/../src/verbs.cpp:2173 +msgid "View debug messages" +msgstr "Pregled poruka dnevnika rada" + +#: ../../po/../src/verbs.cpp:2174 +msgid "S_cripts..." +msgstr "_Skripte..." + +#: ../../po/../src/verbs.cpp:2175 +msgid "Run scripts" +msgstr "Pokreni skriptu" + +#: ../../po/../src/verbs.cpp:2176 +msgid "Show/Hide D_ialogs" +msgstr "Prikaži/_sakrij prozorčiće" + +#: ../../po/../src/verbs.cpp:2177 +msgid "Show or hide all active dialogs" +msgstr "Prikaži ili sakrij sve aktivne prozorčiće" + +#. TRANSLATORS: "Tile clones" means: "Create tiled clones" +#: ../../po/../src/verbs.cpp:2179 +msgid "Tile clones..." +msgstr "Slaganje klonova..." + +#: ../../po/../src/verbs.cpp:2180 +msgid "Create and arrange multiple clones of selection" +msgstr "Pravljenje i slaganje viÅ¡estrukih klonova izbora" + +# bug: rect -> rectangle +#: ../../po/../src/verbs.cpp:2181 +msgid "_Object Properties..." +msgstr "_Osobine objekta..." + +# bug: rect -> rectangle +#: ../../po/../src/verbs.cpp:2182 +msgid "Object Properties dialog" +msgstr "Prozorče sa osobinama objekta" + +#: ../../po/../src/verbs.cpp:2185 +msgid "_Connect to Jabber server..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2185 +msgid "Connect to a Jabber server" +msgstr "" + +#: ../../po/../src/verbs.cpp:2187 +#, fuzzy +msgid "Share with _user..." +msgstr "Sačuvaj _kao..." + +#: ../../po/../src/verbs.cpp:2187 +msgid "Establish a whiteboard session with another Jabber user" +msgstr "" + +#: ../../po/../src/verbs.cpp:2189 +msgid "Share with _chatroom..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2189 +msgid "" +"Join a chatroom to start a new whiteboard session or join one in progress" +msgstr "" + +#: ../../po/../src/verbs.cpp:2191 +msgid "_Dump XML node tracker" +msgstr "" + +#: ../../po/../src/verbs.cpp:2191 +msgid "Dump the contents of the XML tracker to the console" +msgstr "" + +#: ../../po/../src/verbs.cpp:2193 +msgid "_Open session file..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2193 +msgid "Open and browse through records of past whiteboard sessions" +msgstr "" + +#: ../../po/../src/verbs.cpp:2195 +msgid "Session file playback" +msgstr "" + +#: ../../po/../src/verbs.cpp:2197 +msgid "_Disconnect from session" +msgstr "" + +#: ../../po/../src/verbs.cpp:2199 +msgid "Disconnect from _server" +msgstr "" + +#: ../../po/../src/verbs.cpp:2201 +msgid "_Input Devices..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2202 +msgid "Configure extended input devices" +msgstr "" + +#. Help +#: ../../po/../src/verbs.cpp:2205 +msgid "_Keys and Mouse" +msgstr "_Prečice i miÅ¡" + +#: ../../po/../src/verbs.cpp:2206 +msgid "Key and mouse shortcuts reference" +msgstr "Popis pečica tastature i miÅ¡a" + +#: ../../po/../src/verbs.cpp:2207 +msgid "About E_xtensions" +msgstr "O _ekstenzijama" + +#: ../../po/../src/verbs.cpp:2208 +msgid "About Extensions..." +msgstr "Detalji o ekstenzijama" + +#: ../../po/../src/verbs.cpp:2209 +msgid "About _Memory" +msgstr "O _memoriji" + +#: ../../po/../src/verbs.cpp:2210 +msgid "About Memory..." +msgstr "Detalji o memoriji" + +#: ../../po/../src/verbs.cpp:2211 +msgid "_About Inkscape" +msgstr "O _programu" + +#. "help_about" +#. new HelpVerb(SP_VERB_SHOW_LICENSE, "ShowLicense", N_("Modifying or Redistributing Inkscape"), +#. N_("Show license to modify and/or redistribute Inkscape: GNU GPL"), NULL), +#. Tutorials +#: ../../po/../src/verbs.cpp:2217 +msgid "Inkscape: _Basic" +msgstr "InkSkejp: _Osnove" + +#: ../../po/../src/verbs.cpp:2218 +msgid "Getting started with Inkscape" +msgstr "Osnove programa" + +#. "tutorial_basic" +#: ../../po/../src/verbs.cpp:2219 +msgid "Inkscape: _Shapes" +msgstr "Inkscape: _Oblici" + +#: ../../po/../src/verbs.cpp:2220 +msgid "Using shape tools to create and edit shapes" +msgstr "Upotreba alata za pravljenje i uređivanje oblika" + +#: ../../po/../src/verbs.cpp:2221 +msgid "Inkscape: _Advanced" +msgstr "Inkscape: _Napredno" + +#: ../../po/../src/verbs.cpp:2222 +msgid "Advanced Inkscape topics" +msgstr "Napredne vežbe" + +#. "tutorial_advanced" +#. TRANSLATORS: "to trace" means "to convert a bitmap to vector graphics" (to vectorize) +#: ../../po/../src/verbs.cpp:2224 +msgid "Inkscape: T_racing" +msgstr "Inkscape: _Trasiranje" + +#: ../../po/../src/verbs.cpp:2225 +msgid "Using bitmap tracing" +msgstr "Upotreba alata za pretvaranje bitmapa u vektore" + +#. "tutorial_tracing" +#: ../../po/../src/verbs.cpp:2226 +msgid "Inkscape: _Calligraphy" +msgstr "Inkscape: _Kaligrafija" + +#: ../../po/../src/verbs.cpp:2227 +msgid "Using the Calligraphy pen tool" +msgstr "Upotreba kaligrafske olovke" + +#: ../../po/../src/verbs.cpp:2228 +msgid "_Elements of Design" +msgstr "_Delovi za dizajn" + +#: ../../po/../src/verbs.cpp:2229 +msgid "Principles of design in the tutorial form" +msgstr "Principi dizajniranja u obliku uputstva" + +#. "tutorial_design" +#: ../../po/../src/verbs.cpp:2230 +msgid "_Tips and Tricks" +msgstr "_Saveti i trikovi" + +#: ../../po/../src/verbs.cpp:2231 +msgid "Miscellaneous tips and tricks" +msgstr "Razni saveti i trikovi za upotrebu programa" + +#. "tutorial_tips" +#. Effect +#: ../../po/../src/verbs.cpp:2234 +msgid "Previous Effect" +msgstr "Prethodni efekat" + +#: ../../po/../src/verbs.cpp:2235 +msgid "Repeat the last effect with the same settings" +msgstr "Ponovi poslednji efekat sa istim podeÅ¡avanjima" + +#. "tutorial_tips" +#: ../../po/../src/verbs.cpp:2236 +#, fuzzy +msgid "Previous Effect Settings..." +msgstr "Prethodni efekat..." + +#: ../../po/../src/verbs.cpp:2237 +msgid "Repeat the last effect with new settings" +msgstr "Ponavljanje poslednjeg efekta sa novim podeÅ¡avanjima" + +#: ../../po/../src/widgets/dash-selector.cpp:106 +msgid "Dash pattern" +msgstr "Å ablon linije" + +#: ../../po/../src/widgets/dash-selector.cpp:121 +msgid "Pattern offset" +msgstr "Razmak Å¡ablona" + +#: ../../po/../src/widgets/desktop-widget.cpp:240 +msgid "Zoom drawing if window size changes" +msgstr "Zumiraj crtež kada se promeni veličina prozora" + +#: ../../po/../src/widgets/desktop-widget.cpp:298 +msgid "Cursor coordinates" +msgstr "Koordinate pokazivača miÅ¡a" + +#. display the initial welcome message in the statusbar +#: ../../po/../src/widgets/desktop-widget.cpp:324 +msgid "" +"Welcome to Inkscape! Use shape or freehand tools to create objects; " +"use selector (arrow) to move or transform them." +msgstr "" +"Dobro doÅ¡li u Inkskejp! Koristite oblike ili alat za crtanje " +"slobodnom rukom da bi iscrtali objekte; koristite izbornik (strelicu) za " +"njihovo pomeranje i promenu oblika." + +#: ../../po/../src/widgets/desktop-widget.cpp:372 +#, c-format +msgid "%s: %d - Inkscape" +msgstr "%s: %d - Inkscape" + +#: ../../po/../src/widgets/desktop-widget.cpp:374 +#, c-format +msgid "%s - Inkscape" +msgstr "%s - Inkscape" + +#: ../../po/../src/widgets/desktop-widget.cpp:532 +#, c-format +msgid "" +"Save changes to document \"%s\" before " +"closing?\n" +"\n" +"If you close without saving, your changes will be discarded." +msgstr "" +"Pamćenje izmena u dokumentu „%s“ pre " +"zatvaranja?\n" +"\n" +"Ako napustite program bez pamćenja izmena, izmene koje ste načinili će biti " +"zanemarene." + +#: ../../po/../src/widgets/desktop-widget.cpp:548 +#: ../../po/../src/widgets/desktop-widget.cpp:612 +msgid "Close _without saving" +msgstr "Zatvori _bez snimanja" + +#: ../../po/../src/widgets/desktop-widget.cpp:595 +#, c-format +msgid "" +"The file \"%s\" was saved with a " +"format (%s) that may cause data loss!\n" +"\n" +"Do you want to save this file in another format?" +msgstr "" +"Datoteka „%s“ je sačuvana u formatu (%" +"s) koji može prouzrokovati gubitak podataka!\n" +"\n" +"Želite li da sačuvate ovu datoteku u nekom drugom formatu?" + +#. Family frame +#: ../../po/../src/widgets/font-selector.cpp:156 +msgid "Font family" +msgstr "Porodica fonta" + +#. Style frame +#: ../../po/../src/widgets/font-selector.cpp:184 +msgid "Style" +msgstr "Stil" + +#: ../../po/../src/widgets/font-selector.cpp:219 +msgid "Font size:" +msgstr "Veličina fonta:" + +#. TRANSLATORS: Test string used in text and font dialog (when no +#. * text has been entered) to get a preview of the font. Choose +#. * some representative characters that users of your locale will be +#. * interested in. +#: ../../po/../src/widgets/font-selector.cpp:554 +msgid "AaBbCcIiPpQq12368.;/()" +msgstr "AaBbVvDdĐđLJljČč12368.;/()„“" + +#: ../../po/../src/widgets/gradient-selector.cpp:137 +#: ../../po/../src/widgets/gradient-toolbar.cpp:524 +msgid "Duplicate" +msgstr "Udvostruči" + +#: ../../po/../src/widgets/gradient-selector.cpp:142 +#: ../../po/../src/widgets/gradient-toolbar.cpp:535 +msgid "Edit..." +msgstr "Uredi..." + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/pservers.html#LinearGradientSpreadMethodAttribute +#: ../../po/../src/widgets/gradient-selector.cpp:159 +msgid "" +"Whether to fill with flat color beyond the ends of the gradient vector " +"(spreadMethod=\"pad\"), or repeat the gradient in the same direction " +"(spreadMethod=\"repeat\"), or repeat the gradient in alternating opposite " +"directions (spreadMethod=\"reflect\")" +msgstr "" +"Da li će se za popunu izvan ivica vektora preliva uzima jednobojna popuna " +"(spreadMethod=\"pad\"), ili ponavljanje preliva u istom smeru (spreadMethod=" +"\"repeat\"), ili ponavljanje preliva u alternativnom suprotnom smeru " +"(spreadMethod=\"reflect\")" + +#: ../../po/../src/widgets/gradient-selector.cpp:165 +msgid "none" +msgstr "niÅ¡ta" + +#: ../../po/../src/widgets/gradient-selector.cpp:169 +msgid "reflected" +msgstr "odraz" + +# bug: cannot be easily translated; please use "rectangle" +#: ../../po/../src/widgets/gradient-selector.cpp:173 +msgid "direct" +msgstr "ponavljanje" + +#: ../../po/../src/widgets/gradient-selector.cpp:181 +msgid "Repeat:" +msgstr "Ponavljanje:" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:217 +msgid "No gradients" +msgstr "Nema preliva" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:226 +msgid "Nothing selected" +msgstr "NiÅ¡ta nije izabrano" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:237 +msgid "No gradients in selection" +msgstr "Nema preliva u izboru" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:247 +msgid "Multiple gradients" +msgstr "ViÅ¡estruki prelivi" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:525 +msgid "" +"If the gradient is used by more than one object, create a copy of it for the " +"selected object(s)" +msgstr "" +"Ako preliv koristi viÅ¡e od jednog objekta, napravi njegovu kopiju za " +"izabreane objekte" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:536 +msgid "Edit the stops of the gradient" +msgstr "Uređivanje stanica preliva" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:593 +#: ../../po/../src/widgets/toolbox.cpp:1103 +#: ../../po/../src/widgets/toolbox.cpp:1192 +#: ../../po/../src/widgets/toolbox.cpp:1485 +#: ../../po/../src/widgets/toolbox.cpp:1534 +#: ../../po/../src/widgets/toolbox.cpp:1766 +#: ../../po/../src/widgets/toolbox.cpp:1801 +#: ../../po/../src/widgets/toolbox.cpp:2331 +#: ../../po/../src/widgets/toolbox.cpp:2370 +msgid "New:" +msgstr "Novo:" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:606 +msgid "Create linear gradient" +msgstr "Napravi linearni preliv" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:620 +msgid "Create radial (elliptic or circular) gradient" +msgstr "Napravi radijalni (elipsasti ili okrugli) preliv" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:635 +msgid "on" +msgstr "na" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:648 +msgid "Create gradient in the fill" +msgstr "Napravi preliv u popuni" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:662 +msgid "Create gradient in the stroke" +msgstr "Napravi preliv u liniji" + +#. FIXME: implement averaging of all parameters for multiple selected stars +#. gtk_label_set_markup(GTK_LABEL(l), _("Average:")); +#. FIXME: implement averaging of all parameters for multiple selected +#. gtk_label_set_markup(GTK_LABEL(l), _("Average:")); +#: ../../po/../src/widgets/gradient-toolbar.cpp:676 +#: ../../po/../src/widgets/toolbox.cpp:1105 +#: ../../po/../src/widgets/toolbox.cpp:1124 +#: ../../po/../src/widgets/toolbox.cpp:1493 +#: ../../po/../src/widgets/toolbox.cpp:1518 +#: ../../po/../src/widgets/toolbox.cpp:1768 +#: ../../po/../src/widgets/toolbox.cpp:1787 +#: ../../po/../src/widgets/toolbox.cpp:2334 +#: ../../po/../src/widgets/toolbox.cpp:2354 +msgid "Change:" +msgstr "Izmena:" + +#: ../../po/../src/widgets/gradient-vector.cpp:269 +msgid "No gradients in document" +msgstr "Nema preliva u dokumentu" + +#: ../../po/../src/widgets/gradient-vector.cpp:275 +msgid "No gradient selected" +msgstr "Preliv nije izabran" + +#: ../../po/../src/widgets/gradient-vector.cpp:532 +msgid "No stops in gradient" +msgstr "Bez stanice boje u prelivu" + +#. TRANSLATORS: "Stop" means: a "phase" of a gradient +#: ../../po/../src/widgets/gradient-vector.cpp:794 +msgid "Add stop" +msgstr "Dodaj stanicu boje" + +#: ../../po/../src/widgets/gradient-vector.cpp:797 +msgid "Add another control stop to gradient" +msgstr "Dodavanje joÅ¡ jedne kontrolne stanice boje u preliv" + +#: ../../po/../src/widgets/gradient-vector.cpp:799 +msgid "Delete stop" +msgstr "Ukloni stanicu boje" + +#: ../../po/../src/widgets/gradient-vector.cpp:802 +msgid "Delete current control stop from gradient" +msgstr "Uklanjanje trenutne kontrolne stanice boje iz preliva" + +#. Label +#: ../../po/../src/widgets/gradient-vector.cpp:813 +msgid "Offset:" +msgstr "Razmak:" + +#. TRANSLATORS: "Stop" means: a "phase" of a gradient +#: ../../po/../src/widgets/gradient-vector.cpp:858 +msgid "Stop Color" +msgstr "Stanica boje" + +#: ../../po/../src/widgets/gradient-vector.cpp:887 +msgid "Gradient editor" +msgstr "Uređivač preliva" + +#: ../../po/../src/widgets/layer-selector.cpp:119 +msgid "Toggle current layer visibility" +msgstr "Promena vidljivosti trenutnog sloja" + +#: ../../po/../src/widgets/layer-selector.cpp:139 +msgid "Lock or unlock current layer" +msgstr "Zaključavanje ili otključavanje trenutnog sloja" + +#: ../../po/../src/widgets/layer-selector.cpp:142 +msgid "Current layer" +msgstr "Trenutni sloj" + +#: ../../po/../src/widgets/layer-selector.cpp:553 +msgid "(root)" +msgstr "(osnova)" + +#: ../../po/../src/widgets/paint-selector.cpp:182 +#: ../../po/../src/widgets/paint-selector.cpp:561 +msgid "No paint" +msgstr "Bez boje" + +#: ../../po/../src/widgets/paint-selector.cpp:184 +#: ../../po/../src/widgets/paint-selector.cpp:629 +msgid "Flat color" +msgstr "Jednobojno" + +#: ../../po/../src/widgets/paint-selector.cpp:186 +#: ../../po/../src/widgets/paint-selector.cpp:696 +msgid "Linear gradient" +msgstr "Linijski preliv" + +#: ../../po/../src/widgets/paint-selector.cpp:188 +#: ../../po/../src/widgets/paint-selector.cpp:699 +msgid "Radial gradient" +msgstr "Kružni preliv" + +#: ../../po/../src/widgets/paint-selector.cpp:192 +msgid "Unset paint (make it undefined so it can be inherited)" +msgstr "Ukloni boju (učini je neodređenom da može biti nasleđena)" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/painting.html#FillRuleProperty +#: ../../po/../src/widgets/paint-selector.cpp:204 +msgid "" +"Any path self-intersections or subpaths create holes in the fill (fill-rule: " +"evenodd)" +msgstr "" +"Bilo koje preklapanje krive objekta pravi rupe u popuni (fill-rule: evenodd)" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/painting.html#FillRuleProperty +#: ../../po/../src/widgets/paint-selector.cpp:215 +msgid "" +"Fill is solid unless a subpath is counterdirectional (fill-rule: nonzero)" +msgstr "" +"Popuna je jednobojna dok podkriva ne bude izokrenuta (fill-rule: nonzero)" + +#: ../../po/../src/widgets/paint-selector.cpp:528 +msgid "No objects" +msgstr "Nema objekata" + +#: ../../po/../src/widgets/paint-selector.cpp:539 +msgid "Multiple styles" +msgstr "ViÅ¡e stilova" + +#: ../../po/../src/widgets/paint-selector.cpp:550 +msgid "Paint is undefined" +msgstr "Boja je neodređena" + +#: ../../po/../src/widgets/paint-selector.cpp:757 +msgid "No patterns in document" +msgstr "Nema mustri u dokumentu" + +#: ../../po/../src/widgets/paint-selector.cpp:872 +msgid "" +"Use Edit > Object(s) to Pattern to create a new pattern from " +"selection." +msgstr "" +"Upotrebite Uređivanje > Izbor u Mustru za pravljenje nove mustre " +"od izbora." + +#: ../../po/../src/widgets/select-toolbar.cpp:426 +msgid "Now stroke width is scaled when objects are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:428 +msgid "Now stroke width is not scaled when objects are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:436 +msgid "" +"Now rounded rectangle corners are scaled when rectangles are " +"scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:438 +msgid "" +"Now rounded rectangle corners are not scaled when rectangles " +"are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:446 +msgid "" +"Now gradients are transformed along with their objects when " +"those are transformed (moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:448 +msgid "" +"Now gradients remain fixed when objects are transformed " +"(moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:456 +msgid "" +"Now patterns are transformed along with their objects when " +"those are transformed (moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:458 +msgid "" +"Now patterns remain fixed when objects are transformed (moved, " +"scaled, rotated, or skewed)." +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:506 +msgid "select_toolbar|X" +msgstr "Izbornik|X" + +#: ../../po/../src/widgets/select-toolbar.cpp:506 +msgid "Horizontal coordinate of selection" +msgstr "Vodoravna koordinata izbora" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:511 +msgid "select_toolbar|Y" +msgstr "Izbornik|Y" + +#: ../../po/../src/widgets/select-toolbar.cpp:511 +msgid "Vertical coordinate of selection" +msgstr "Uspravna koordinata izbora" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:517 +msgid "select_toolbar|W" +msgstr "Izbornik|Å " + +#: ../../po/../src/widgets/select-toolbar.cpp:517 +msgid "Width of selection" +msgstr "Å irina izbora" + +#: ../../po/../src/widgets/select-toolbar.cpp:525 +msgid "Change both width and height by the same proportion" +msgstr "Proporcijalna promena Å¡irine i visine" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:534 +msgid "select_toolbar|H" +msgstr "Izbornik|V" + +#: ../../po/../src/widgets/select-toolbar.cpp:534 +msgid "Height of selection" +msgstr "Visina izbora" + +#: ../../po/../src/widgets/sp-color-gtkselector.cpp:62 +msgid "System" +msgstr "Sistem" + +#: ../../po/../src/widgets/sp-color-notebook.cpp:322 +msgid "RGBA_:" +msgstr "RGBA_:" + +#: ../../po/../src/widgets/sp-color-notebook.cpp:330 +msgid "Hexadecimal RGBA value of the color" +msgstr "Heksadecimalna RGBA vrednost boje" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "RGB" +msgstr "RGB" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "HSL" +msgstr "HSL" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "CMYK" +msgstr "CMYK" + +#: ../../po/../src/widgets/sp-color-scales.cpp:397 +msgid "_R" +msgstr "_C" + +#: ../../po/../src/widgets/sp-color-scales.cpp:398 +#: ../../po/../src/widgets/sp-color-scales.cpp:399 +msgid "Red" +msgstr "Crvena" + +#: ../../po/../src/widgets/sp-color-scales.cpp:400 +msgid "_G" +msgstr "_Z" + +#: ../../po/../src/widgets/sp-color-scales.cpp:401 +#: ../../po/../src/widgets/sp-color-scales.cpp:402 +msgid "Green" +msgstr "Zelena" + +#: ../../po/../src/widgets/sp-color-scales.cpp:403 +msgid "_B" +msgstr "_P" + +#: ../../po/../src/widgets/sp-color-scales.cpp:404 +#: ../../po/../src/widgets/sp-color-scales.cpp:405 +msgid "Blue" +msgstr "Plava" + +#. Label +#: ../../po/../src/widgets/sp-color-scales.cpp:406 +#: ../../po/../src/widgets/sp-color-scales.cpp:432 +#: ../../po/../src/widgets/sp-color-scales.cpp:463 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:141 +msgid "_A" +msgstr "_P" + +#: ../../po/../src/widgets/sp-color-scales.cpp:407 +#: ../../po/../src/widgets/sp-color-scales.cpp:408 +#: ../../po/../src/widgets/sp-color-scales.cpp:433 +#: ../../po/../src/widgets/sp-color-scales.cpp:434 +#: ../../po/../src/widgets/sp-color-scales.cpp:464 +#: ../../po/../src/widgets/sp-color-scales.cpp:465 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:151 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:163 +msgid "Alpha (opacity)" +msgstr "Providnost" + +#: ../../po/../src/widgets/sp-color-scales.cpp:423 +msgid "_H" +msgstr "_N" + +#: ../../po/../src/widgets/sp-color-scales.cpp:424 +#: ../../po/../src/widgets/sp-color-scales.cpp:425 +msgid "Hue" +msgstr "Nijansa" + +#: ../../po/../src/widgets/sp-color-scales.cpp:426 +msgid "_S" +msgstr "_Z" + +#: ../../po/../src/widgets/sp-color-scales.cpp:427 +#: ../../po/../src/widgets/sp-color-scales.cpp:428 +msgid "Saturation" +msgstr "Zasićenost" + +#: ../../po/../src/widgets/sp-color-scales.cpp:429 +msgid "_L" +msgstr "_O" + +#: ../../po/../src/widgets/sp-color-scales.cpp:430 +#: ../../po/../src/widgets/sp-color-scales.cpp:431 +msgid "Lightness" +msgstr "Osvetljenost" + +#: ../../po/../src/widgets/sp-color-scales.cpp:451 +msgid "_C" +msgstr "_C" + +#: ../../po/../src/widgets/sp-color-scales.cpp:452 +#: ../../po/../src/widgets/sp-color-scales.cpp:453 +msgid "Cyan" +msgstr "Cijan" + +#: ../../po/../src/widgets/sp-color-scales.cpp:454 +msgid "_M" +msgstr "_M" + +#: ../../po/../src/widgets/sp-color-scales.cpp:455 +#: ../../po/../src/widgets/sp-color-scales.cpp:456 +msgid "Magenta" +msgstr "Magenta" + +#: ../../po/../src/widgets/sp-color-scales.cpp:457 +msgid "_Y" +msgstr "_Ž" + +#: ../../po/../src/widgets/sp-color-scales.cpp:458 +#: ../../po/../src/widgets/sp-color-scales.cpp:459 +msgid "Yellow" +msgstr "Žuta" + +#: ../../po/../src/widgets/sp-color-scales.cpp:460 +msgid "_K" +msgstr "_K" + +#: ../../po/../src/widgets/sp-color-selector.cpp:71 +msgid "Unnamed" +msgstr "Neimenovano" + +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:68 +msgid "Wheel" +msgstr "Krug" + +#: ../../po/../src/widgets/sp-xmlview-attr-list.cpp:53 +msgid "Attribute" +msgstr "Osobina" + +#: ../../po/../src/widgets/sp-xmlview-attr-list.cpp:54 +msgid "Value" +msgstr "Vrednost" + +#: ../../po/../src/widgets/toolbox.cpp:424 +msgid "Insert new nodes into selected segments" +msgstr "Ubacivanje novih čvorova u izabrane delove" + +#: ../../po/../src/widgets/toolbox.cpp:426 +msgid "Delete selected nodes" +msgstr "Uklanjanje izabranih čvorova" + +#: ../../po/../src/widgets/toolbox.cpp:431 +msgid "Join paths at selected nodes" +msgstr "Spajanje krive na izabranim čvorovima" + +#: ../../po/../src/widgets/toolbox.cpp:433 +msgid "Join paths at selected nodes with new segment" +msgstr "Spajanje krive novim delom između izabranih čvorova" + +#: ../../po/../src/widgets/toolbox.cpp:436 +msgid "Split path between two non-endpoint nodes" +msgstr "Podeli krivu između dva nezavrÅ¡avajuća čvora" + +#: ../../po/../src/widgets/toolbox.cpp:439 +msgid "Break path at selected nodes" +msgstr "Razdvajanje krive na izabranim čvorovima" + +#: ../../po/../src/widgets/toolbox.cpp:444 +msgid "Make selected nodes corner" +msgstr "Pravljenje ćoÅ¡kaste krive na izabranim čvorovima" + +# glatka kriva se precizno matematički definiÅ¡e, i upravo deluje kao „glatka“ +#: ../../po/../src/widgets/toolbox.cpp:447 +msgid "Make selected nodes smooth" +msgstr "Pravljenje glatke krive na izabranim čvorovima" + +#: ../../po/../src/widgets/toolbox.cpp:450 +msgid "Make selected nodes symmetric" +msgstr "Pravljenje simetrične glatke krive na izabranim čvorovima" + +#: ../../po/../src/widgets/toolbox.cpp:455 +msgid "Make selected segments lines" +msgstr "Pravljenje prave linije od izabranih delova" + +#: ../../po/../src/widgets/toolbox.cpp:458 +msgid "Make selected segments curves" +msgstr "Pravljenje krive linije od izabranih delova" + +#: ../../po/../src/widgets/toolbox.cpp:1199 +msgid "Polygon" +msgstr "Poligon" + +#: ../../po/../src/widgets/toolbox.cpp:1206 +msgid "Regular polygon (with one handle) instead of a star" +msgstr "Normalan poligon (sa jednom ručkom) umesto zvezde" + +#: ../../po/../src/widgets/toolbox.cpp:1218 +msgid "Corners:" +msgstr "Uglovi:" + +#: ../../po/../src/widgets/toolbox.cpp:1218 +msgid "Number of corners of a polygon or star" +msgstr "Broj uglova poligona ili zvezde" + +#: ../../po/../src/widgets/toolbox.cpp:1228 +msgid "Spoke ratio:" +msgstr "Å irina kraka:" + +#. TRANSLATORS: Tip radius of a star is the distance from the center to the farthest handle. +#. Base radius is the same for the closest handle. +#: ../../po/../src/widgets/toolbox.cpp:1231 +msgid "Base radius to tip radius ratio" +msgstr "Odnos osnovnog poluprečnika do ručke" + +#: ../../po/../src/widgets/toolbox.cpp:1246 +msgid "Rounded:" +msgstr "Zaobljenost:" + +#: ../../po/../src/widgets/toolbox.cpp:1246 +msgid "How much rounded are the corners (0 for sharp)" +msgstr "Koliko će biti zaobljeni uglovi (0 za oÅ¡tar ugao)" + +#: ../../po/../src/widgets/toolbox.cpp:1256 +msgid "Randomized:" +msgstr "Nasumično:" + +#: ../../po/../src/widgets/toolbox.cpp:1256 +msgid "Scatter randomly the corners and angles" +msgstr "Nasumično razmesti ćoÅ¡kove i uglove" + +#: ../../po/../src/widgets/toolbox.cpp:1269 +#: ../../po/../src/widgets/toolbox.cpp:1838 +#: ../../po/../src/widgets/toolbox.cpp:2061 +msgid "Defaults" +msgstr "Podrazumevano" + +#: ../../po/../src/widgets/toolbox.cpp:1270 +#: ../../po/../src/widgets/toolbox.cpp:1839 +#: ../../po/../src/widgets/toolbox.cpp:2062 +msgid "" +"Reset shape parameters to defaults (use Inkscape Preferences > Tools to " +"change defaults)" +msgstr "" +"Vraćanje parametara oblika na podrazumevane vrednosti (koristite InkSkejp " +"PodeÅ¡avanja > Alati za promene podrazumevano)" + +#: ../../po/../src/widgets/toolbox.cpp:1544 +msgid "W:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1544 +#, fuzzy +msgid "Width of rectangle" +msgstr "Å irina izbora" + +#: ../../po/../src/widgets/toolbox.cpp:1556 +#, fuzzy +msgid "Height of rectangle" +msgstr "Visina izbora" + +#: ../../po/../src/widgets/toolbox.cpp:1568 +msgid "Rx:" +msgstr "Rx:" + +#: ../../po/../src/widgets/toolbox.cpp:1568 +msgid "Horizontal radius of rounded corners" +msgstr "Vodoravni poluprečnik zaobljenih uglova" + +#: ../../po/../src/widgets/toolbox.cpp:1578 +msgid "Ry:" +msgstr "Ry:" + +#: ../../po/../src/widgets/toolbox.cpp:1578 +msgid "Vertical radius of rounded corners" +msgstr "Uspravni poluprečnik zaobljenih uglova" + +#: ../../po/../src/widgets/toolbox.cpp:1594 +msgid "Not rounded" +msgstr "Nije zaobljeno" + +#: ../../po/../src/widgets/toolbox.cpp:1596 +msgid "Make corners sharp" +msgstr "Napravi uglastu liniju" + +#: ../../po/../src/widgets/toolbox.cpp:1805 +msgid "Turns:" +msgstr "Transformacija:" + +#: ../../po/../src/widgets/toolbox.cpp:1805 +msgid "Number of revolutions" +msgstr "Broj revolucija" + +#: ../../po/../src/widgets/toolbox.cpp:1815 +msgid "Divergence:" +msgstr "Odstupanje:" + +#: ../../po/../src/widgets/toolbox.cpp:1815 +msgid "How much denser/sparser are outer revolutions; 1 = uniform" +msgstr "Koliki je skupljač/rastavljač izvan revolucije; 1 = nepromenljiv" + +#: ../../po/../src/widgets/toolbox.cpp:1825 +msgid "Inner radius:" +msgstr "UnutraÅ¡nji poluprečnik:" + +#: ../../po/../src/widgets/toolbox.cpp:1825 +msgid "Radius of the innermost revolution (relative to the spiral size)" +msgstr "" +"Poluprečnik najmanje unutraÅ¡nje revolucije (odnosi se na veličinu spirale)" + +#: ../../po/../src/widgets/toolbox.cpp:1957 +msgid "The width of the calligraphic pen (relative to the visible canvas area)" +msgstr "Å irina kaligrafske olovke (u odnosu na vidljivu povrÅ¡inu platna)" + +#: ../../po/../src/widgets/toolbox.cpp:1967 +msgid "Thinning:" +msgstr "Istanjivanje:" + +#: ../../po/../src/widgets/toolbox.cpp:1967 +msgid "" +"How much velocity thins the stroke (> 0 makes fast strokes thinner, < 0 " +"makes them broader, 0 makes width independent of velocity)" +msgstr "" +"Koliko brzina tanji potez (veće od 0 čini brze poteze tanjim, manje od 0 " +"čini ih debljim. 0 čini debljinu nezavisnu od brzine poteza)" + +#: ../../po/../src/widgets/toolbox.cpp:1980 +msgid "Angle:" +msgstr "Ugao:" + +#: ../../po/../src/widgets/toolbox.cpp:1980 +msgid "" +"The angle of the pen's nib (in degrees; 0 = horizontal; has no effect if " +"fixation = 0)" +msgstr "Ugao vrha olovke (u stepenima; 0 je vodoravno, nema efekta ako je )" + +#: ../../po/../src/widgets/toolbox.cpp:1990 +msgid "Fixation:" +msgstr "Položaj:" + +#: ../../po/../src/widgets/toolbox.cpp:1990 +msgid "" +"How fixed is the pen angle (0 = always perpendicular to stroke direction, 1 " +"= fixed)" +msgstr "" +"Položaj ugla olovke (0 = uvek uspravan u odnosu na pravac poteza, 1 = fiksan)" + +#: ../../po/../src/widgets/toolbox.cpp:2003 +msgid "Mass:" +msgstr "Masa:" + +#: ../../po/../src/widgets/toolbox.cpp:2003 +msgid "How much inertia affects the movement of the pen" +msgstr "Koliko se inercija odražava na potez olovke" + +#. TRANSLATORS: "drag" means "resistance" here +#: ../../po/../src/widgets/toolbox.cpp:2014 +msgid "Drag:" +msgstr "Otpor:" + +#: ../../po/../src/widgets/toolbox.cpp:2014 +msgid "How much resistance affects the movement of the pen" +msgstr "Koliko se otpor odražava na potez olovke" + +#: ../../po/../src/widgets/toolbox.cpp:2034 +msgid "Use the pressure of the input device to alter the width of the pen" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2047 +msgid "Use the tilt of the input device to alter the angle of the pen's nib" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2374 +msgid "Start:" +msgstr "Početak:" + +#: ../../po/../src/widgets/toolbox.cpp:2374 +msgid "The angle (in degrees) from the horizontal to the arc's start point" +msgstr "Ugao (u stepenima) od vodoravne do lučne početne tačke" + +#: ../../po/../src/widgets/toolbox.cpp:2384 +msgid "End:" +msgstr "ZavrÅ¡etak:" + +#: ../../po/../src/widgets/toolbox.cpp:2384 +msgid "The angle (in degrees) from the horizontal to the arc's end point" +msgstr "Ugao (u stepenima) od vodoravne do lučne krajnje tačke" + +#: ../../po/../src/widgets/toolbox.cpp:2395 +msgid "Open arc" +msgstr "Otvoreni luk" + +#: ../../po/../src/widgets/toolbox.cpp:2396 +msgid "" +"Switch between arc (unclosed shape) and segment (closed shape with two radii)" +msgstr "" +"Promena između luka (otvorene linije) i dela (zatvorena linija sa dva ugla)" + +#: ../../po/../src/widgets/toolbox.cpp:2415 +msgid "Make whole" +msgstr "Upotpuni" + +#: ../../po/../src/widgets/toolbox.cpp:2417 +msgid "Make the shape a whole ellipse, not arc or segment" +msgstr "Zatvori liniju u elipsu, ne kao luk ili deo" + +#: ../../po/../src/widgets/toolbox.cpp:2644 +msgid "" +"When pressed, picks visible color without alpha and when not pressed, picks " +"color including its alpha" +msgstr "" +"Kada je pritisnuto, uzima vidljivu boju bez providnosti a kada nije " +"pritisnut, uzima boju uključujući i providnost" + +#: ../../po/../src/widgets/toolbox.cpp:3039 +#, fuzzy +msgid "Make connectors avoid selected objects" +msgstr "Presecanje izabranih objekata" + +#: ../../po/../src/widgets/toolbox.cpp:3043 +#, fuzzy +msgid "Make connectors ignore selected objects" +msgstr "Presecanje izabranih objekata" + +#. +#. 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 : +#: ../share/extensions/addnodes.inx.h:1 +#, fuzzy +msgid "Add Nodes" +msgstr "Čvorovi" + +#: ../share/extensions/addnodes.inx.h:2 +msgid "Maximum Segment Length" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:1 +msgid "AI Input" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:2 ../share/extensions/ai_output.inx.h:2 +msgid "Adobe Illustrator (*.ai)" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:3 +msgid "Open files saved with Adobe Illustrator" +msgstr "" + +#: ../share/extensions/ai_output.inx.h:1 +#, fuzzy +msgid "AI Output" +msgstr "Izlaz" + +#: ../share/extensions/ai_output.inx.h:3 +msgid "Write Adobe Illustrator" +msgstr "" + +#: ../share/extensions/dia.inx.h:1 +msgid "A diagram created with the program Dia" +msgstr "" + +#: ../share/extensions/dia.inx.h:2 +msgid "Dia Diagram (*.dia)" +msgstr "" + +#: ../share/extensions/dia.inx.h:3 +msgid "Dia Input" +msgstr "" + +#: ../share/extensions/dia.inx.h:4 +msgid "" +"In order to import Dia files, Dia itself must be installed. You can get Dia " +"at http://www.gnome.org/projects/dia/" +msgstr "" + +#: ../share/extensions/dia.inx.h:5 +msgid "" +"The dia2svg.sh script should be installed with your Inkscape distribution. " +"If you do not have it, there is likely to be something wrong with your " +"Inkscape installation." +msgstr "" + +#: ../share/extensions/dots.inx.h:1 +#, fuzzy +msgid "Connect the Dots" +msgstr "Autor" + +#: ../share/extensions/dots.inx.h:2 +#, fuzzy +msgid "Dot Size" +msgstr "Veličina" + +#: ../share/extensions/dots.inx.h:3 +#, fuzzy +msgid "Font Size" +msgstr "Veličina fonta:" + +#: ../share/extensions/dropshadow.inx.h:1 +msgid "Color of shadow" +msgstr "" + +#: ../share/extensions/dropshadow.inx.h:2 +#, fuzzy +msgid "Dropshadow" +msgstr "Prikaži senku strane" + +#: ../share/extensions/dxf_input.inx.h:1 +#: ../share/extensions/dxf_output.inx.h:1 +msgid "AutoCAD DXF (*.dxf)" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:2 +msgid "DXF Input" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:3 +msgid "Import AutoCAD's Document Exchange Format" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:4 +msgid "" +"dxf2svg may come with Inkscape, but is also at http://dxf-svg-convert." +"sourceforge.net/" +msgstr "" + +#: ../share/extensions/dxf_output.inx.h:2 +#, fuzzy +msgid "DXF Output" +msgstr "Izlaz" + +#: ../share/extensions/dxf_output.inx.h:3 +msgid "DXF file written by pstoedit" +msgstr "" + +#: ../share/extensions/dxf_output.inx.h:4 +msgid "pstoedit must be installed to run see http://www.pstoedit.net/pstoedit" +msgstr "" + +#: ../share/extensions/embedimage.inx.h:1 +#, fuzzy +msgid "Embed Images" +msgstr "Slike" + +#: ../share/extensions/eps_input.inx.h:1 +msgid "EPS Input" +msgstr "" + +#: ../share/extensions/eps_input.inx.h:2 +msgid "Encapsulated Postscript" +msgstr "" + +#: ../share/extensions/eps_input.inx.h:3 +msgid "Encapsulated Postscript (*.eps)" +msgstr "" + +#: ../share/extensions/epsi_output.inx.h:1 +#, fuzzy +msgid "EPSI Output" +msgstr "Izlaz" + +#: ../share/extensions/epsi_output.inx.h:2 +msgid "Encapsulated Postscript Interchange (*.epsi)" +msgstr "" + +#: ../share/extensions/epsi_output.inx.h:3 +msgid "Encapsulated Postscript with a thumbnail" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:1 ../share/extensions/ffms.inx.h:1 +#: ../share/extensions/ffset.inx.h:1 ../share/extensions/ffss.inx.h:1 +#, fuzzy +msgid "Bridge Width" +msgstr "Å irina linije" + +#: ../share/extensions/ffmet.inx.h:2 ../share/extensions/ffms.inx.h:2 +msgid "First String Length" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:3 +msgid "FretFind Multi Length ET" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:4 ../share/extensions/ffms.inx.h:4 +#: ../share/extensions/ffset.inx.h:3 ../share/extensions/ffss.inx.h:3 +msgid "Fretboard Edges" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:5 ../share/extensions/ffms.inx.h:5 +msgid "Last String Length" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:6 ../share/extensions/ffms.inx.h:6 +#: ../share/extensions/ffset.inx.h:4 ../share/extensions/ffss.inx.h:4 +#, fuzzy +msgid "Number of Frets" +msgstr "Broj redova" + +#: ../share/extensions/ffmet.inx.h:7 ../share/extensions/ffms.inx.h:7 +#: ../share/extensions/ffset.inx.h:5 ../share/extensions/ffss.inx.h:5 +#, fuzzy +msgid "Number of Strings" +msgstr "Broj redova" + +#: ../share/extensions/ffmet.inx.h:8 ../share/extensions/ffms.inx.h:8 +#: ../share/extensions/ffset.inx.h:6 ../share/extensions/ffss.inx.h:6 +#, fuzzy +msgid "Nut Width" +msgstr "Å irina:" + +#: ../share/extensions/ffmet.inx.h:9 ../share/extensions/ffms.inx.h:10 +msgid "Perpendicular Distance" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:10 ../share/extensions/ffset.inx.h:7 +msgid "Scale Base (2 for Octave)" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:11 ../share/extensions/ffset.inx.h:9 +msgid "Tones in Scale" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:12 ../share/extensions/ffms.inx.h:12 +#: ../share/extensions/ffset.inx.h:10 ../share/extensions/ffss.inx.h:10 +msgid "px per Unit" +msgstr "" + +#: ../share/extensions/ffms.inx.h:3 +msgid "FretFind Multi Length Scala" +msgstr "" + +#: ../share/extensions/ffms.inx.h:9 ../share/extensions/ffss.inx.h:7 +msgid "Path to Scala *.scl File" +msgstr "" + +#: ../share/extensions/ffms.inx.h:11 +msgid "Tuning (scale step for each string seperated by semicolons)" +msgstr "" + +#: ../share/extensions/ffset.inx.h:2 +msgid "FretFind Single Length ET" +msgstr "" + +#: ../share/extensions/ffset.inx.h:8 ../share/extensions/ffss.inx.h:8 +msgid "Scale Length" +msgstr "" + +#: ../share/extensions/ffss.inx.h:2 +msgid "FretFind Single Length Scala" +msgstr "" + +#: ../share/extensions/ffss.inx.h:9 +msgid "Tuning (Scale step for each string seperated by semicolons)" +msgstr "" + +#: ../share/extensions/handles.inx.h:1 +#, fuzzy +msgid "Draw Handles" +msgstr "Iscrtavanje linije slobodnom rukom" + +#: ../share/extensions/interp.inx.h:1 +#, fuzzy +msgid "Duplicate Endpaths" +msgstr "Udvostruči čvor" + +#: ../share/extensions/interp.inx.h:2 +#, fuzzy +msgid "Exponent" +msgstr "Izvezi" + +#: ../share/extensions/interp.inx.h:3 +msgid "Interpolate" +msgstr "" + +#: ../share/extensions/interp.inx.h:4 +msgid "Interpolate Style (Experimental)" +msgstr "" + +#: ../share/extensions/interp.inx.h:5 +msgid "Interpolation Method" +msgstr "" + +#: ../share/extensions/interp.inx.h:6 +msgid "Interpolation Steps" +msgstr "" + +#: ../share/extensions/kochify.inx.h:1 +msgid "Kochify" +msgstr "" + +#: ../share/extensions/kochify_load.inx.h:1 +msgid "Kochify (Load)" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:1 +#, fuzzy +msgid "Angle" +msgstr "Ugao:" + +#: ../share/extensions/lindenmayer.inx.h:2 +msgid "Axiom" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:3 +#, fuzzy +msgid "Lindenmayer" +msgstr "Preimenuj sloj" + +#: ../share/extensions/lindenmayer.inx.h:4 +msgid "Order" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:5 +#, fuzzy +msgid "Rules" +msgstr "_Lenjiri" + +#: ../share/extensions/lindenmayer.inx.h:6 +#, fuzzy +msgid "Step" +msgstr "Koraci" + +#: ../share/extensions/motion.inx.h:1 +#, fuzzy +msgid "Direction" +msgstr "Opis" + +#: ../share/extensions/motion.inx.h:2 +#, fuzzy +msgid "Magnitude" +msgstr "Magenta" + +#: ../share/extensions/motion.inx.h:3 +#, fuzzy +msgid "Motion" +msgstr "_Rotacija" + +#: ../share/extensions/pdf_output.inx.h:1 +msgid "Adobe PDF (*.pdf)" +msgstr "" + +#: ../share/extensions/pdf_output.inx.h:2 +msgid "Adobe Portable Document Format" +msgstr "" + +#: ../share/extensions/pdf_output.inx.h:3 +#, fuzzy +msgid "PDF Output" +msgstr "Izlaz" + +#: ../share/extensions/ps_input.inx.h:1 +#, fuzzy +msgid "Postscript" +msgstr "Uspravno" + +#: ../share/extensions/ps_input.inx.h:2 +msgid "Postscript (*.ps)" +msgstr "" + +#: ../share/extensions/ps_input.inx.h:3 +msgid "Postscript Input" +msgstr "" + +#: ../share/extensions/radiusrand.inx.h:1 +#, fuzzy +msgid "Radius" +msgstr "_Izdigni" + +#: ../share/extensions/radiusrand.inx.h:2 +#, fuzzy +msgid "Radius Randomize" +msgstr "Nasumično:" + +#: ../share/extensions/radiusrand.inx.h:3 +msgid "Randomize Control Points" +msgstr "" + +#: ../share/extensions/radiusrand.inx.h:4 +#, fuzzy +msgid "Randomize Nodes" +msgstr "Nasumično:" + +#: ../share/extensions/rtree.inx.h:1 +#, fuzzy +msgid "Initial Size" +msgstr "Veličina bitmape" + +#: ../share/extensions/rtree.inx.h:2 +msgid "Minimum Size" +msgstr "" + +#: ../share/extensions/rtree.inx.h:3 +#, fuzzy +msgid "Random Tree" +msgstr "Nasumično:" + +#: ../share/extensions/sk_input.inx.h:1 +msgid "A diagram created with the program Sketch" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:2 +msgid "Sketch Diagram (*.sk)" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:3 +msgid "Sketch Input" +msgstr "" + +#: ../share/extensions/straightseg.inx.h:1 +msgid "Behavior" +msgstr "" + +#: ../share/extensions/straightseg.inx.h:3 +msgid "Segment Straightener" +msgstr "" + +#: ../share/extensions/summersnight.inx.h:1 +msgid "Summer's Night" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:1 +#: ../share/extensions/svgz_output.inx.h:1 +msgid "Compressed Inkscape SVG (*.svgz)" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:2 +#: ../share/extensions/svgz_output.inx.h:2 +msgid "Inkscape's native file format compressed with GZip" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:3 +msgid "SVGZ Input" +msgstr "" + +#: ../share/extensions/svgz_output.inx.h:3 +#, fuzzy +msgid "SVGZ Output" +msgstr "Izlaz" + +#: ../share/extensions/txt2svg.inx.h:1 +msgid "ASCII Text" +msgstr "" + +#: ../share/extensions/txt2svg.inx.h:2 +msgid "Text File (*.txt)" +msgstr "" + +#: ../share/extensions/txt2svg.inx.h:3 +msgid "Text Input" +msgstr "" + +#: ../share/extensions/wavy.inx.h:1 +msgid "Calculate first derivative numerically" +msgstr "" + +#: ../share/extensions/wavy.inx.h:2 +msgid "First derivative" +msgstr "" + +#: ../share/extensions/wavy.inx.h:3 +msgid "Function" +msgstr "" + +#: ../share/extensions/wavy.inx.h:4 +msgid "Function Plotter" +msgstr "" + +#: ../share/extensions/wavy.inx.h:5 +msgid "Nodes per period" +msgstr "" + +#: ../share/extensions/wavy.inx.h:6 +msgid "Periods (2*Pi each)" +msgstr "" + +#: ../share/extensions/whirl.inx.h:1 +msgid "Amount of Whirl" +msgstr "" + +#: ../share/extensions/whirl.inx.h:2 +#, fuzzy +msgid "Center X" +msgstr "Centralno poravnanje" + +#: ../share/extensions/whirl.inx.h:3 +#, fuzzy +msgid "Center Y" +msgstr "Centralno poravnanje" + +#: ../share/extensions/whirl.inx.h:4 +#, fuzzy +msgid "Direction of Rotation" +msgstr "Postavi izabrane objekte iza ostalih" + +#: ../share/extensions/whirl.inx.h:5 +msgid "Whirl" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:1 +msgid "A popular graphics file format for clipart" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:2 +msgid "Windows Metafile (*.wmf)" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:3 +msgid "Windows Metafile Input" +msgstr "" + +#~ msgid "Custom canvas" +#~ msgstr "Prilagođeno platno" + +#~ msgid "Current style" +#~ msgstr "Trenutni stil" + +#~ msgid "" +#~ "Current style is updated every time you change the style of any object " +#~ "(its fill, stroke, transparency, etc.)" +#~ msgstr "" +#~ "Trenutni stil se osvežava svaki put kada promenite stil nekog objekta " +#~ "(njegova popuna, boja ivične linije, providnost i dr.)" + +#~ msgid "Arrange Objects" +#~ msgstr "Razvrstaj objekte" + +#~ msgid "deg" +#~ msgstr "stepeni" + +#~ msgid "" +#~ "%s is not a valid preferences file.\n" +#~ "%s" +#~ msgstr "" +#~ "%s nije ispravna datoteka podeÅ¡avanja.\n" +#~ "%s" + +#~ msgid "" +#~ "Inkscape will run with default settings.\n" +#~ "New settings will not be saved." +#~ msgstr "" +#~ "InkSkejp će biti pokrenut sa podrazumevanim podeÅ¡avanjima.\n" +#~ "Nova podeÅ¡avanja neće biti sačuvana." + +#, fuzzy +#~ msgid "_Credits" +#~ msgstr "Zahvale" + +#~ msgid "Grab sensitivity" +#~ msgstr "Osetljivost hvatanja" + +#~ msgid "Click/drag threshold" +#~ msgstr "Prag klika/pomeraja" + +#~ msgid "Mouse wheel scrolls by" +#~ msgstr "Točkić miÅ¡a pomera za" + +#~ msgid "Scroll by" +#~ msgstr "Pomeraj za" + +#~ msgid "Acceleration" +#~ msgstr "Ubrzanje" + +#~ msgid "Speed" +#~ msgstr "Brzina" + +#~ msgid "Threshold" +#~ msgstr "Prag tolerancije" + +#~ msgid "Arrow keys move by" +#~ msgstr "Stralice pomeraju za" + +#~ msgid "> and < scale by" +#~ msgstr "„>“ i „<“ menjaju veličinu za" + +#~ msgid "Inset/Outset by" +#~ msgstr "Skupljanje/Å¡irenje za" + +#~ msgid "Rotation snaps every" +#~ msgstr "Rotacija prijanja na svakih" + +#~ msgid "Zoom in/out by" +#~ msgstr "Uvećavanje/umanjenje za" + +#~ msgid "Transform" +#~ msgstr "Transformacija" + +#~ msgid "Flip selection horizontally" +#~ msgstr "Izvrće izbor kao u ogledalu vodoravno" + +#~ msgid "Flip selection vertically" +#~ msgstr "Izvrće izbor kao u ogledalu uspravno" + +#, fuzzy +#~ msgid "Could not read next message due to I/O error (error: %s)!" +#~ msgstr "Ne mogu da napravim dnevnik greÅ¡aka proÅ¡irenja „%s“" + +#~ msgid "Open one of the recently visited documents" +#~ msgstr "Otvaranje jednog od poslednje otvaranih dokumenata" + +#~ msgid "" +#~ "Show or hide parts of the document window (differently for normal and " +#~ "fullscreen modes)" +#~ msgstr "" +#~ "Prikazivanje ili skrivanje delova prozora dokumenta (razlikuju se " +#~ "normalan i režim preko celog ekrana)" + +#~ msgid "Interactive Inkscape tutorials" +#~ msgstr "Interaktivne InkSkejp vežbe" + +#~ msgid "Edit" +#~ msgstr "Uredi" + +#~ msgid "Add" +#~ msgstr "Dodaj" diff --git a/po/sv.po b/po/sv.po new file mode 100644 index 000000000..142e8589f --- /dev/null +++ b/po/sv.po @@ -0,0 +1,11496 @@ +# Swedish messages for Inkscape. +# Copyright (C) 2000, 2001, 2002, 2003, 2005 Free Software Foundation, Inc. +# +# $Id$ +# Andreas Hyden , 2000. +# Christian Rose , 2000, 2001, 2002, 2003. +# Mattias Hultgren , 2005. +# +msgid "" +msgstr "" +"Project-Id-Version: sv\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2005-12-04 11:51-0800\n" +"PO-Revision-Date: 2005-10-08 21:49+0200\n" +"Last-Translator: Mattias Hultgren \n" +"Language-Team: Svenska \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 1.10.2\n" + +#: ../inkscape.desktop.in.h:1 +#, fuzzy +msgid "Create and edit Scalable Vector Graphics images" +msgstr "Format för skalbar vektorgrafik" + +#: ../inkscape.desktop.in.h:2 +msgid "Inkscape SVG Vector Illustrator" +msgstr "Inkscape - SVG-vektorillustrationsprogram" + +#: ../../po/../src/arc-context.cpp:350 +msgid "" +"Ctrl: make circle or integer-ratio ellipse, snap arc/segment angle" +msgstr "" + +#: ../../po/../src/arc-context.cpp:351 ../../po/../src/rect-context.cpp:388 +msgid "Shift: draw around the starting point" +msgstr "" + +#: ../../po/../src/arc-context.cpp:413 +#: ../../po/../src/connector-context.cpp:493 +#: ../../po/../src/dyna-draw-context.cpp:506 +#: ../../po/../src/pen-context.cpp:329 ../../po/../src/pencil-context.cpp:208 +#: ../../po/../src/rect-context.cpp:452 ../../po/../src/spiral-context.cpp:421 +#: ../../po/../src/star-context.cpp:427 +msgid "Current layer is hidden. Unhide it to be able to draw on it." +msgstr "" + +#: ../../po/../src/arc-context.cpp:417 +#: ../../po/../src/connector-context.cpp:497 +#: ../../po/../src/dyna-draw-context.cpp:510 +#: ../../po/../src/pen-context.cpp:336 ../../po/../src/pencil-context.cpp:212 +#: ../../po/../src/rect-context.cpp:456 ../../po/../src/spiral-context.cpp:426 +#: ../../po/../src/star-context.cpp:431 +msgid "Current layer is locked. Unlock it to be able to draw on it." +msgstr "Aktuellt lager är lÃ¥st. LÃ¥s upp för att kunna rita till det." + +#: ../../po/../src/arc-context.cpp:496 +#, c-format +msgid "" +"Ellipse: %s × %s; with Ctrl to make circle or integer-" +"ratio ellipse; with Shift to draw around the starting point" +msgstr "" + +#: ../../po/../src/connector-context.cpp:518 +#, fuzzy +msgid "Creating new connector" +msgstr "Skapa nytt SVG-dokument" + +#: ../../po/../src/connector-context.cpp:939 +#, fuzzy +msgid "Finishing connector" +msgstr "Frihand" + +#: ../../po/../src/connector-context.cpp:1108 +msgid "Connection point: click or drag to create a new connector" +msgstr "" + +#: ../../po/../src/connector-context.cpp:1185 +msgid "Connector endpoint: drag to reroute or connect to new shapes" +msgstr "" + +#: ../../po/../src/connector-context.cpp:1278 +#, fuzzy +msgid "Select at least one non-connector object." +msgstr "Markera minst tvÃ¥ objekt att gruppera." + +#: ../../po/../src/desktop-events.cpp:238 +#, c-format +msgid "%s at %s" +msgstr "" + +#. TRANSLATORS: This string appears when double-clicking on a guide. +#. This is the distance by which the guide is to be moved. +#: ../../po/../src/desktop-events.cpp:277 +#, fuzzy +msgid " relative by " +msgstr "flytta relativt" + +#. TRANSLATORS: This string appears when double-clicking on a guide. +#. This is the target location where the guide is to be moved. +#: ../../po/../src/desktop-events.cpp:282 +#: ../../po/../src/desktop-events.cpp:395 +#, fuzzy +msgid " absolute to " +msgstr "absolut" + +#. create dialog +#: ../../po/../src/desktop-events.cpp:348 +msgid "Guideline" +msgstr "Hjälplinje" + +#: ../../po/../src/desktop-events.cpp:432 +#, c-format +msgid "Move %s" +msgstr "Flytta %s" + +#: ../../po/../src/desktop.cpp:678 +msgid "No previous zoom." +msgstr "Ingen föregÃ¥ende zoom." + +#: ../../po/../src/desktop.cpp:703 +msgid "No next zoom." +msgstr "Ingen nästa zoom." + +#: ../../po/../src/dialogs/clonetiler.cpp:182 +msgid "Nothing selected." +msgstr "Inget markerat." + +#: ../../po/../src/dialogs/clonetiler.cpp:188 +msgid "More than one object selected." +msgstr "Mer än ett objekt markerat." + +#: ../../po/../src/dialogs/clonetiler.cpp:195 +#, c-format +msgid "Object has %d tiled clones." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:200 +msgid "Object has no tiled clones." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:865 +#, fuzzy +msgid "Select one object whose tiled clones to unclump." +msgstr "Klipp ut markerade objekt till urklipp" + +#: ../../po/../src/dialogs/clonetiler.cpp:916 +#, fuzzy +msgid "Select one object whose tiled clones to remove." +msgstr "Klipp ut markerade objekt till urklipp" + +#: ../../po/../src/dialogs/clonetiler.cpp:984 +#: ../../po/../src/selection-chemistry.cpp:1774 +msgid "Select an object to clone." +msgstr "Markera ett objekt at klona." + +#: ../../po/../src/dialogs/clonetiler.cpp:990 +#: ../../po/../src/selection-chemistry.cpp:1780 +msgid "" +"If you want to clone several objects, group them and clone the " +"group." +msgstr "" +"Om du vill klona flera objekt, gruppera dem och klona gruppen." + +#: ../../po/../src/dialogs/clonetiler.cpp:1484 +msgid "Per row:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1497 +#, fuzzy +msgid "Per column:" +msgstr "Ingen toning markerad" + +#: ../../po/../src/dialogs/clonetiler.cpp:1505 +msgid "Randomize:" +msgstr "Slumpa:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1656 +#, fuzzy +msgid "_Symmetry" +msgstr "Symmetrisk " + +#. TRANSLATORS: For the following 17 symmetry groups, see +#. * http://www.bib.ulb.ac.be/coursmath/doc/17.htm (visual examples); +#. * http://www.clarku.edu/~djoyce/wallpaper/seventeen.html (English vocabulary); or +#. * http://membres.lycos.fr/villemingerard/Geometri/Sym1D.htm (French vocabulary). +#. +#: ../../po/../src/dialogs/clonetiler.cpp:1664 +msgid "Select one of the 17 symmetry groups for the tiling" +msgstr "" + +#. TRANSLATORS: "translation" means "shift" / "displacement" here. +#: ../../po/../src/dialogs/clonetiler.cpp:1675 +msgid "P1: simple translation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1676 +msgid "P2: 180° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1677 +msgid "PM: reflection" +msgstr "" + +#. TRANSLATORS: "glide reflection" is a reflection and a translation combined. +#. For more info, see http://mathforum.org/sum95/suzanne/symsusan.html +#: ../../po/../src/dialogs/clonetiler.cpp:1680 +msgid "PG: glide reflection" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1681 +msgid "CM: reflection + glide reflection" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1682 +msgid "PMM: reflection + reflection" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1683 +msgid "PMG: reflection + 180° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1684 +msgid "PGG: glide reflection + 180° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1685 +msgid "CMM: reflection + reflection + 180° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1686 +msgid "P4: 90° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1687 +msgid "P4M: 90° rotation + 45° reflection" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1688 +msgid "P4G: 90° rotation + 90° reflection" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1689 +msgid "P3: 120° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1690 +msgid "P31M: reflection + 120° rotation, dense" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1691 +msgid "P3M1: reflection + 120° rotation, sparse" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1692 +msgid "P6: 60° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1693 +msgid "P6M: reflection + 60° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1721 +msgid "S_hift" +msgstr "" + +#. TRANSLATORS: "shift" means: the tiles will be shifted (offset) horizontally by this amount +#: ../../po/../src/dialogs/clonetiler.cpp:1731 +#, fuzzy, no-c-format +msgid "Shift X:" +msgstr "Ändra" + +#: ../../po/../src/dialogs/clonetiler.cpp:1739 +#, no-c-format +msgid "Horizontal shift per row (in % of tile width)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1747 +#, no-c-format +msgid "Horizontal shift per column (in % of tile width)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1754 +msgid "Randomize the horizontal shift by this percentage" +msgstr "" + +#. TRANSLATORS: "shift" means: the tiles will be shifted (offset) vertically by this amount +#: ../../po/../src/dialogs/clonetiler.cpp:1764 +#, fuzzy, no-c-format +msgid "Shift Y:" +msgstr "Ändra" + +#: ../../po/../src/dialogs/clonetiler.cpp:1772 +#, no-c-format +msgid "Vertical shift per row (in % of tile height)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1780 +#, no-c-format +msgid "Vertical shift per column (in % of tile height)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1787 +msgid "Randomize the vertical shift by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1795 +#, fuzzy +msgid "Exponent:" +msgstr "Ändra" + +#: ../../po/../src/dialogs/clonetiler.cpp:1802 +msgid "Whether rows are spaced evenly (1), converge (<1) or diverge (>1)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1809 +msgid "Whether columns are spaced evenly (1), converge (<1) or diverge (>1)" +msgstr "" + +#. TRANSLATORS: "Alternate" is a verb here +#: ../../po/../src/dialogs/clonetiler.cpp:1817 +#: ../../po/../src/dialogs/clonetiler.cpp:1907 +#: ../../po/../src/dialogs/clonetiler.cpp:1966 +#: ../../po/../src/dialogs/clonetiler.cpp:2022 +#: ../../po/../src/dialogs/clonetiler.cpp:2153 +msgid "Alternate:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1823 +msgid "Alternate the sign of shifts for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1828 +msgid "Alternate the sign of shifts for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1837 +#, fuzzy +msgid "Sc_ale" +msgstr "Skala" + +#: ../../po/../src/dialogs/clonetiler.cpp:1845 +#, fuzzy +msgid "Scale X:" +msgstr "Ändra" + +#: ../../po/../src/dialogs/clonetiler.cpp:1853 +#, fuzzy, no-c-format +msgid "Horizontal scale per row (in % of tile width)" +msgstr "horisontellt skalningsvärde" + +#: ../../po/../src/dialogs/clonetiler.cpp:1861 +#, fuzzy, no-c-format +msgid "Horizontal scale per column (in % of tile width)" +msgstr "horisontellt skalningsvärde" + +#: ../../po/../src/dialogs/clonetiler.cpp:1868 +msgid "Randomize the horizontal scale by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1876 +#, fuzzy +msgid "Scale Y:" +msgstr "Ändra" + +#: ../../po/../src/dialogs/clonetiler.cpp:1884 +#, fuzzy, no-c-format +msgid "Vertical scale per row (in % of tile height)" +msgstr "vertikalt skalningsvärde" + +#: ../../po/../src/dialogs/clonetiler.cpp:1892 +#, fuzzy, no-c-format +msgid "Vertical scale per column (in % of tile height)" +msgstr "vertikalt skalningsvärde" + +#: ../../po/../src/dialogs/clonetiler.cpp:1899 +msgid "Randomize the vertical scale by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1913 +#, fuzzy +msgid "Alternate the sign of scales for each row" +msgstr "vertikalt skalningsvärde" + +#: ../../po/../src/dialogs/clonetiler.cpp:1918 +#, fuzzy +msgid "Alternate the sign of scales for each column" +msgstr "vertikalt skalningsvärde" + +#: ../../po/../src/dialogs/clonetiler.cpp:1927 +#, fuzzy +msgid "_Rotation" +msgstr "Upplösning:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1935 +#, fuzzy +msgid "Angle:" +msgstr "Ändra" + +#: ../../po/../src/dialogs/clonetiler.cpp:1943 +#, no-c-format +msgid "Rotate tiles by this angle for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1951 +#, no-c-format +msgid "Rotate tiles by this angle for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1958 +msgid "Randomize the rotation angle by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1972 +msgid "Alternate the rotation direction for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1977 +msgid "Alternate the rotation direction for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1985 +#, fuzzy +msgid "_Opacity" +msgstr "Opacitet:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1993 +#, fuzzy +msgid "Fade out:" +msgstr "Ändra" + +#: ../../po/../src/dialogs/clonetiler.cpp:2000 +msgid "Decrease tile opacity by this percentage for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2007 +msgid "Decrease tile opacity by this percentage for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2014 +msgid "Randomize the tile opacity by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2028 +msgid "Alternate the sign of opacity change for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2033 +msgid "Alternate the sign of opacity change for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2041 +msgid "Co_lor" +msgstr "Färg" + +#: ../../po/../src/dialogs/clonetiler.cpp:2046 +#, fuzzy +msgid "Initial color: " +msgstr "Fyllningsfärg: " + +#: ../../po/../src/dialogs/clonetiler.cpp:2050 +msgid "Initial color of tiled clones" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2050 +msgid "" +"Initial color for clones (works only if the original has unset fill or " +"stroke)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2065 +#, fuzzy +msgid "H:" +msgstr "Ändra" + +#: ../../po/../src/dialogs/clonetiler.cpp:2072 +msgid "Change the tile hue by this percentage for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2079 +msgid "Change the tile hue by this percentage for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2086 +msgid "Randomize the tile hue by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2095 +#, fuzzy +msgid "S:" +msgstr "Ändra" + +#: ../../po/../src/dialogs/clonetiler.cpp:2102 +msgid "Change the color saturation by this percentage for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2109 +msgid "Change the color saturation by this percentage for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2116 +msgid "Randomize the color saturation by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2124 +#, fuzzy +msgid "L:" +msgstr "Ändra" + +#: ../../po/../src/dialogs/clonetiler.cpp:2131 +msgid "Change the color lightness by this percentage for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2138 +msgid "Change the color lightness by this percentage for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2145 +msgid "Randomize the color lightness by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2159 +msgid "Alternate the sign of color changes for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2164 +msgid "Alternate the sign of color changes for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2172 +#, fuzzy +msgid "_Trace" +msgstr "SpÃ¥r" + +#: ../../po/../src/dialogs/clonetiler.cpp:2179 +msgid "Trace the drawing under the tiles" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2183 +msgid "" +"For each clone, pick a value from the drawing in that clone's location and " +"apply it to the clone" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2197 +msgid "1. Pick from the drawing:" +msgstr "" + +#. ----Hbox2 +#: ../../po/../src/dialogs/clonetiler.cpp:2208 +#: ../../po/../src/dialogs/clonetiler.cpp:2355 +#: ../../po/../src/ui/dialog/tracedialog.cpp:445 +msgid "Color" +msgstr "Färg" + +#: ../../po/../src/dialogs/clonetiler.cpp:2209 +msgid "Pick the visible color and opacity" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2216 +#: ../../po/../src/dialogs/clonetiler.cpp:2365 +#: ../share/extensions/dropshadow.inx.h:3 +#, fuzzy +msgid "Opacity" +msgstr "Opacitet:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2217 +msgid "Pick the total accumulated opacity" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2224 +msgid "R" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2225 +msgid "Pick the Red component of the color" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2232 +msgid "G" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2233 +msgid "Pick the Green component of the color" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2240 +msgid "B" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2241 +msgid "Pick the Blue component of the color" +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2250 +msgid "clonetiler|H" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2251 +#, fuzzy +msgid "Pick the hue of the color" +msgstr "Välj en genomstrykningsfärg" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2260 +msgid "clonetiler|S" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2261 +#, fuzzy +msgid "Pick the saturation of the color" +msgstr "Välj en genomstrykningsfärg" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2270 +msgid "clonetiler|L" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2271 +msgid "Pick the lightness of the color" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2281 +msgid "2. Tweak the picked value:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2291 +msgid "Gamma-correct:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2296 +msgid "Shift the mid-range of the picked value upwards (>0) or downwards (<0)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2303 +msgid "Randomize:" +msgstr "Slumpa:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2308 +msgid "Randomize the picked value by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2315 +msgid "Invert:" +msgstr "Invertera" + +#: ../../po/../src/dialogs/clonetiler.cpp:2319 +msgid "Invert the picked value" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2325 +msgid "3. Apply the value to the clones':" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2335 +#, fuzzy +msgid "Presence" +msgstr "Bevara" + +#: ../../po/../src/dialogs/clonetiler.cpp:2338 +msgid "" +"Each clone is created with the probability determined by the picked value in " +"that point" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2345 +msgid "Size" +msgstr "Storlek" + +#: ../../po/../src/dialogs/clonetiler.cpp:2348 +msgid "Each clone's size is determined by the picked value in that point" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2358 +msgid "" +"Each clone is painted by the picked color (the original must have unset fill " +"or stroke)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2368 +msgid "Each clone's opacity is determined by the picked value in that point" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2395 +msgid "How many rows in the tiling" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2415 +msgid "How many columns in the tiling" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2445 +msgid "Width of the rectangle to be filled" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2470 +msgid "Height of the rectangle to be filled" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2485 +#, fuzzy +msgid "Rows, columns: " +msgstr "Ändra" + +#: ../../po/../src/dialogs/clonetiler.cpp:2486 +msgid "Create the specified number of rows and columns" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2495 +msgid "Width, height: " +msgstr "Bredd, höjd: " + +#: ../../po/../src/dialogs/clonetiler.cpp:2496 +msgid "Fill the specified width and height with the tiling" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2512 +#, fuzzy +msgid "Use saved size and position of the tile" +msgstr "Objektstorlek och -position" + +#: ../../po/../src/dialogs/clonetiler.cpp:2515 +msgid "" +"Pretend that the size and position of the tile are the same as the last time " +"you tiled it (if any), instead of using the current size" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2539 +msgid " _Create " +msgstr " Skapa " + +#: ../../po/../src/dialogs/clonetiler.cpp:2541 +msgid "Create and tile the clones of the selection" +msgstr "" + +#. TRANSLATORS: if a group of objects are "clumped" together, then they +#. are unevenly spread in the given amount of space - as shown in the +#. diagrams on the left in the following screenshot: +#. http://www.inkscape.org/screenshots/gallery/inkscape-0.42-CVS-tiles-unclump.png +#. So unclumping is the process of spreading a number of objects out more evenly. +#: ../../po/../src/dialogs/clonetiler.cpp:2556 +msgid " _Unclump " +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2557 +msgid "Spread out clones to reduce clumping; can be applied repeatedly" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2563 +msgid " Re_move " +msgstr " Ta bort " + +#: ../../po/../src/dialogs/clonetiler.cpp:2564 +msgid "Remove existing tiled clones of the selected object (siblings only)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2580 +msgid " R_eset " +msgstr "" + +#. TRANSLATORS: "change" is a noun here +#: ../../po/../src/dialogs/clonetiler.cpp:2582 +msgid "" +"Reset all shifts, scales, rotates, opacity and color changes in the dialog " +"to zero" +msgstr "" + +#: ../../po/../src/dialogs/color-picker.cpp:280 +msgid "Close" +msgstr "Stäng" + +#: ../../po/../src/dialogs/debugdialog.cpp:138 +msgid "Messages" +msgstr "" + +#. ## Add a menu for clear() +#: ../../po/../src/dialogs/debugdialog.cpp:144 +#: ../../po/../src/menus-skeleton.h:16 +#: ../../po/../src/ui/dialog/messages.cpp:56 +#: ../../po/../src/ui/dialog/scriptdialog.cpp:181 +msgid "_File" +msgstr "_Arkiv" + +#. TRANSLATORS: "Clear" is a verb here +#: ../../po/../src/dialogs/debugdialog.cpp:145 +#: ../../po/../src/dialogs/find.cpp:753 +#: ../../po/../src/ui/dialog/messages.cpp:57 +#: ../../po/../src/ui/dialog/scriptdialog.cpp:182 +msgid "_Clear" +msgstr "Rensa" + +#: ../../po/../src/dialogs/debugdialog.cpp:147 +#: ../../po/../src/ui/dialog/messages.cpp:59 +msgid "Capture log messages" +msgstr "" + +#: ../../po/../src/dialogs/debugdialog.cpp:149 +#: ../../po/../src/ui/dialog/messages.cpp:61 +msgid "Release log messages" +msgstr "" + +#. Notebook tab +#: ../../po/../src/dialogs/desktop-properties.cpp:909 +#: ../../po/../src/ui/dialog/document-preferences.cpp:89 +#: ../../po/../src/ui/widget/panel.cpp:107 +msgid "Grid" +msgstr "Rutnät" + +#. Checkbuttons +#. / \todo FIXME: gray out snapping when grid is off +#. / \todo FIXME: gray out snapping when grid is off. +#. / Dissenting view: you want snapping without grid. +#: ../../po/../src/dialogs/desktop-properties.cpp:917 +#: ../../po/../src/ui/dialog/document-preferences.cpp:179 +msgid "Show grid" +msgstr "Visa rutnät" + +#: ../../po/../src/dialogs/desktop-properties.cpp:917 +#: ../../po/../src/ui/dialog/document-preferences.cpp:179 +#: ../../po/../src/verbs.cpp:2115 +msgid "Show or hide grid" +msgstr "Visa eller göm rutnät" + +#: ../../po/../src/dialogs/desktop-properties.cpp:918 +#: ../../po/../src/ui/dialog/document-preferences.cpp:180 +#, fuzzy +msgid "Snap bounding boxes to grid" +msgstr "Fäst vid rutnät" + +#: ../../po/../src/dialogs/desktop-properties.cpp:918 +#: ../../po/../src/dialogs/desktop-properties.cpp:1001 +#: ../../po/../src/ui/dialog/document-preferences.cpp:181 +#: ../../po/../src/ui/dialog/document-preferences.cpp:236 +msgid "Snap the edges of the object bounding boxes" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:919 +#: ../../po/../src/ui/dialog/document-preferences.cpp:183 +#, fuzzy +msgid "Snap nodes to grid" +msgstr "Fäst vid rutnät" + +#: ../../po/../src/dialogs/desktop-properties.cpp:919 +#: ../../po/../src/dialogs/desktop-properties.cpp:1002 +#: ../../po/../src/ui/dialog/document-preferences.cpp:184 +#: ../../po/../src/ui/dialog/document-preferences.cpp:239 +msgid "Snap path nodes, text baselines, ellipse centers, etc." +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:937 +#: ../../po/../src/ui/dialog/document-preferences.cpp:186 +msgid "Grid units:" +msgstr "Enheter för rutnät:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:939 +#: ../../po/../src/ui/dialog/document-preferences.cpp:187 +msgid "Origin X:" +msgstr "X-origo:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:942 +#: ../../po/../src/ui/dialog/document-preferences.cpp:189 +msgid "Origin Y:" +msgstr "Y-origo:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:945 +#: ../../po/../src/ui/dialog/document-preferences.cpp:191 +msgid "Spacing X:" +msgstr "X-avstÃ¥nd:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:948 +#: ../../po/../src/ui/dialog/document-preferences.cpp:193 +msgid "Spacing Y:" +msgstr "Y-avstÃ¥nd:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:952 +#: ../../po/../src/dialogs/desktop-properties.cpp:1013 +#: ../../po/../src/ui/dialog/document-preferences.cpp:195 +#: ../../po/../src/ui/dialog/document-preferences.cpp:241 +msgid "Snap units:" +msgstr "Enheter för fästande:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:955 +#: ../../po/../src/dialogs/desktop-properties.cpp:1016 +#: ../../po/../src/ui/dialog/document-preferences.cpp:196 +#: ../../po/../src/ui/dialog/document-preferences.cpp:242 +msgid "Snap distance:" +msgstr "FästavstÃ¥nd:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:958 +#: ../../po/../src/ui/dialog/document-preferences.cpp:199 +msgid "Grid line color:" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:959 +#: ../../po/../src/ui/dialog/document-preferences.cpp:199 +#, fuzzy +msgid "Grid line color" +msgstr "Färg pÃ¥ hjälplinjer" + +#: ../../po/../src/dialogs/desktop-properties.cpp:959 +#: ../../po/../src/ui/dialog/document-preferences.cpp:200 +msgid "Color of grid lines" +msgstr "Färgen pÃ¥ rutnätet" + +#: ../../po/../src/dialogs/desktop-properties.cpp:961 +#: ../../po/../src/ui/dialog/document-preferences.cpp:201 +#, fuzzy +msgid "Major grid line color:" +msgstr "Färg pÃ¥ hjälplinjer" + +#: ../../po/../src/dialogs/desktop-properties.cpp:962 +#: ../../po/../src/ui/dialog/document-preferences.cpp:201 +#, fuzzy +msgid "Major grid line color" +msgstr "Färg pÃ¥ hjälplinjer" + +#: ../../po/../src/dialogs/desktop-properties.cpp:962 +#: ../../po/../src/ui/dialog/document-preferences.cpp:202 +#, fuzzy +msgid "Color of the major (highlighted) grid lines" +msgstr "Välj färgen pÃ¥ markerade hjälplinjer" + +#: ../../po/../src/dialogs/desktop-properties.cpp:965 +#: ../../po/../src/ui/dialog/document-preferences.cpp:204 +#, fuzzy +msgid "Major grid line every:" +msgstr "Färg pÃ¥ hjälplinjer" + +#. TRANSLATORS: This belongs to the "Major grid line every:" string, +#. see grid settings in the "Document Preferences" dialog +#: ../../po/../src/dialogs/desktop-properties.cpp:977 +#: ../../po/../src/ui/dialog/document-preferences.cpp:204 +#, fuzzy +msgid "lines" +msgstr "Stäng" + +#. Guidelines page +#: ../../po/../src/dialogs/desktop-properties.cpp:991 +#: ../../po/../src/ui/dialog/document-preferences.cpp:90 +msgid "Guides" +msgstr "Hjälplinjer" + +#. / \todo FIXME: gray out snapping when guides are off +#. / Dissenting view: you want snapping without guides. +#: ../../po/../src/dialogs/desktop-properties.cpp:1000 +#: ../../po/../src/ui/dialog/document-preferences.cpp:234 +msgid "Show guides" +msgstr "Visa hjälplinjer" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1000 +#: ../../po/../src/ui/dialog/document-preferences.cpp:234 +#: ../../po/../src/verbs.cpp:2116 +msgid "Show or hide guides" +msgstr "Visa eller göm hjälplinjer" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1001 +#: ../../po/../src/ui/dialog/document-preferences.cpp:235 +#, fuzzy +msgid "Snap bounding boxes to guides" +msgstr "Fäst vid hjälplinjer" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1002 +#: ../../po/../src/ui/dialog/document-preferences.cpp:238 +#, fuzzy +msgid "Snap points to guides" +msgstr "Fäst vid rutnät" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1020 +#: ../../po/../src/ui/dialog/document-preferences.cpp:243 +#, fuzzy +msgid "Guide color:" +msgstr "Färg pÃ¥ hjälplinjer:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1021 +#: ../../po/../src/ui/dialog/document-preferences.cpp:243 +msgid "Guideline color" +msgstr "Färg pÃ¥ hjälplinjer" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1021 +#: ../../po/../src/ui/dialog/document-preferences.cpp:244 +#, fuzzy +msgid "Color of guidelines" +msgstr "Välj färgen pÃ¥ hjälplinjerna" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1023 +#: ../../po/../src/ui/dialog/document-preferences.cpp:245 +msgid "Highlight color:" +msgstr "Markeringsfärg:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1024 +#: ../../po/../src/ui/dialog/document-preferences.cpp:245 +msgid "Highlighted guideline color" +msgstr "Färg pÃ¥ markerade hjälplinjer" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1024 +#: ../../po/../src/ui/dialog/document-preferences.cpp:246 +msgid "Color of a guideline when it is under mouse" +msgstr "" + +#. Page page +#: ../../po/../src/dialogs/desktop-properties.cpp:1029 +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:855 +#: ../../po/../src/ui/dialog/document-preferences.cpp:88 +#: ../../po/../src/widgets/desktop-widget.cpp:1061 +msgid "Page" +msgstr "Sida" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1039 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +msgid "Background:" +msgstr "Bakgrund:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1040 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +msgid "Background color" +msgstr "Bakgrundsfärg" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1041 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +msgid "" +"Color and transparency of the page background (also used for bitmap export)" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1045 +#: ../../po/../src/ui/dialog/document-preferences.cpp:147 +#, fuzzy +msgid "Show page border" +msgstr "Visa ram" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1049 +#: ../../po/../src/ui/dialog/document-preferences.cpp:148 +msgid "Border on top of drawing" +msgstr "Ram överst pÃ¥ teckning" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1052 +#: ../../po/../src/ui/dialog/document-preferences.cpp:149 +#, fuzzy +msgid "Border color:" +msgstr "Färg pÃ¥ rutnät:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1053 +#: ../../po/../src/ui/dialog/document-preferences.cpp:149 +#, fuzzy +msgid "Page border color" +msgstr "Färg pÃ¥ rutnät:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1054 +#: ../../po/../src/ui/dialog/document-preferences.cpp:150 +#, fuzzy +msgid "Color of the page border" +msgstr "Visa ram" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1059 +#: ../../po/../src/ui/dialog/document-preferences.cpp:152 +msgid "Show page shadow" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1063 +#: ../../po/../src/ui/dialog/document-preferences.cpp:153 +#, fuzzy +msgid "Default units:" +msgstr "Standardalternativ" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1069 +msgid "Units for the tool controls, ruler, and the statusbar" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1086 +#: ../../po/../src/ui/widget/page-sizer.cpp:209 +#, fuzzy +msgid "Page size:" +msgstr "Pappersstorlek:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1110 +#: ../../po/../src/ui/widget/page-sizer.cpp:219 +msgid "Custom" +msgstr "Egen" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1121 +#: ../../po/../src/ui/widget/page-sizer.cpp:225 +#, fuzzy +msgid "Page orientation:" +msgstr "Orientering:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1133 +#: ../../po/../src/ui/widget/page-sizer.cpp:232 +msgid "Landscape" +msgstr "Landskap" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1139 +#: ../../po/../src/ui/widget/page-sizer.cpp:234 +msgid "Portrait" +msgstr "Porträtt" + +#. Custom paper frame +#: ../../po/../src/dialogs/desktop-properties.cpp:1148 +#: ../../po/../src/ui/widget/page-sizer.cpp:249 +#, fuzzy +msgid "Custom size" +msgstr "Egen" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1160 +#: ../../po/../src/dialogs/export.cpp:269 +#: ../../po/../src/ui/widget/page-sizer.cpp:261 +msgid "Units:" +msgstr "Enheter:" + +#. Stroke width +#: ../../po/../src/dialogs/desktop-properties.cpp:1162 +#: ../../po/../src/dialogs/export.cpp:310 +#: ../../po/../src/dialogs/object-attributes.cpp:55 +#: ../../po/../src/dialogs/stroke-style.cpp:985 +#: ../../po/../src/ui/widget/page-sizer.cpp:262 +#: ../../po/../src/widgets/toolbox.cpp:1957 +msgid "Width:" +msgstr "Bredd:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1183 +#: ../../po/../src/dialogs/export.cpp:326 +#: ../../po/../src/dialogs/export.cpp:431 +#: ../../po/../src/dialogs/object-attributes.cpp:56 +#: ../../po/../src/ui/widget/page-sizer.cpp:263 +msgid "Height:" +msgstr "Höjd:" + +#. +#. * Ownership metadata tab +#. +#: ../../po/../src/dialogs/desktop-properties.cpp:1206 +msgid "Metadata" +msgstr "" + +#. add license selector pull-down +#: ../../po/../src/dialogs/desktop-properties.cpp:1225 +msgid "License" +msgstr "Licens" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1255 +msgid "Proprietary" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:212 +#, fuzzy +msgid "When transforming, show:" +msgstr "Objekttransformeringar" + +#: ../../po/../src/dialogs/display-settings.cpp:223 +#, fuzzy +msgid "Objects" +msgstr "Objekt" + +#: ../../po/../src/dialogs/display-settings.cpp:224 +msgid "Show the actual objects when moving or transforming" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:231 +#, fuzzy +msgid "Box outline" +msgstr "Visa kontur" + +#: ../../po/../src/dialogs/display-settings.cpp:232 +msgid "Show only a box outline of the objects when moving or transforming" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:238 +#, fuzzy +msgid "Per-object selection cue:" +msgstr "Konvertera objekt till kurva" + +#. sorationsnapsperpi == 0 means no snapping +#: ../../po/../src/dialogs/display-settings.cpp:249 +#: ../../po/../src/dialogs/display-settings.cpp:386 +#: ../../po/../src/dialogs/display-settings.cpp:441 +#: ../../po/../src/dialogs/display-settings.cpp:1482 +#: ../../po/../src/dialogs/stroke-style.cpp:791 +#: ../../po/../src/interface.cpp:741 +#: ../../po/../src/ui/widget/selected-style.cpp:100 +#: ../../po/../src/verbs.cpp:1842 +msgid "None" +msgstr "Ingen" + +#: ../../po/../src/dialogs/display-settings.cpp:250 +msgid "No per-object selection indication" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:256 +msgid "Mark" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:257 +msgid "Each selected object has a diamond mark in the top left corner" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:264 +msgid "Box" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:265 +msgid "Each selected object displays its bounding box" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:270 +#, fuzzy +msgid "Default scale origin:" +msgstr "Standardmarkörtolerans:" + +#: ../../po/../src/dialogs/display-settings.cpp:281 +#, fuzzy +msgid "Opposite bounding box edge" +msgstr "Fäst vid rutnät" + +#: ../../po/../src/dialogs/display-settings.cpp:282 +msgid "Default scale origin will be on the bounding box of the item" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:288 +msgid "Farthest opposite node" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:289 +msgid "Default scale origin will be on the bounding box of the item's points" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:341 +msgid "degrees" +msgstr "grader" + +#: ../../po/../src/dialogs/display-settings.cpp:350 +msgid "" +"Rotating with Ctrl pressed snaps every that much degrees; also, pressing " +"[ or ] rotates by this amount" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:407 +msgid "Rotation snaps every:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:430 +msgid "" +"None: dialogs are treated as regular windows; Normal: dialogs stay on top of " +"document windows; Aggressive: same as Normal but may work better with some " +"window managers." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:451 +msgid "Normal" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:461 +msgid "Aggressive" +msgstr "" + +# Denna meny heter ocksÃ¥ Fönster i GIMP +#: ../../po/../src/dialogs/display-settings.cpp:475 +#, fuzzy +msgid "Dialogs on top:" +msgstr "Fönster" + +#: ../../po/../src/dialogs/display-settings.cpp:645 +#, fuzzy +msgid "Show selection cue" +msgstr "Konvertera objekt till kurva" + +#: ../../po/../src/dialogs/display-settings.cpp:646 +msgid "" +"Whether selected objects display a selection cue (the same as in selector)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:657 +#, fuzzy +msgid "Enable gradient editing" +msgstr "Toningsvektor" + +#: ../../po/../src/dialogs/display-settings.cpp:658 +msgid "Whether selected objects display gradient editing controls" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:719 +#, fuzzy +msgid "No objects selected to take the style from." +msgstr "Konvertera markerat objekt till slinga" + +#: ../../po/../src/dialogs/display-settings.cpp:728 +msgid "" +"More than one object selected. Cannot take style from multiple " +"objects." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:767 +#, fuzzy +msgid "Create new objects with:" +msgstr "Skapa och redigera textobjekt" + +#: ../../po/../src/dialogs/display-settings.cpp:777 +#, fuzzy +msgid "Take from selection" +msgstr "Transformera markering" + +#: ../../po/../src/dialogs/display-settings.cpp:778 +msgid "Remember the style of the (first) selected object as this tool's style" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:782 +#, fuzzy +msgid "Last used style" +msgstr "Genomstrykningsstil" + +#: ../../po/../src/dialogs/display-settings.cpp:782 +msgid "Apply the style you last set on an object" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:790 +msgid "This tool's own style:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:790 +msgid "" +"Each tool may store its own style to apply to the newly created objects. Use " +"the button below to set it." +msgstr "" + +#. Mouse +#: ../../po/../src/dialogs/display-settings.cpp:877 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:55 +#, fuzzy +msgid "Mouse" +msgstr "Flytta" + +#. TRANSLATORS: "Grab" is a noun here. "Grab sensitivity" is intended to mean how +#. * close on the screen you need to be to an object to be able to grab it with mouse (in +#. * pixels). +#: ../../po/../src/dialogs/display-settings.cpp:883 +#, fuzzy +msgid "Grab sensitivity:" +msgstr "Gör känslig" + +#: ../../po/../src/dialogs/display-settings.cpp:884 +msgid "" +"How close on the screen you need to be to an object to be able to grab it " +"with mouse (in screen pixels)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:885 +#: ../../po/../src/dialogs/display-settings.cpp:897 +#: ../../po/../src/dialogs/display-settings.cpp:912 +#: ../../po/../src/dialogs/display-settings.cpp:930 +#: ../../po/../src/dialogs/display-settings.cpp:970 +msgid "pixels" +msgstr "bildpunkter" + +#: ../../po/../src/dialogs/display-settings.cpp:895 +msgid "Click/drag threshold:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:896 +msgid "" +"Maximum mouse drag (in screen pixels) which is considered a click, not a drag" +msgstr "" + +#. Scrolling +#: ../../po/../src/dialogs/display-settings.cpp:907 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:56 +msgid "Scrolling" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:910 +msgid "Mouse wheel scrolls by:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:911 +msgid "" +"One mouse wheel notch scrolls by this distance in screen pixels " +"(horizontally with Shift)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:920 +msgid "Ctrl+arrows" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:928 +msgid "Scroll by:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:929 +msgid "Pressing Ctrl+arrow key scrolls by this distance (in screen pixels)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:939 +msgid "Acceleration:" +msgstr "Acceleration:" + +#: ../../po/../src/dialogs/display-settings.cpp:940 +msgid "" +"Pressing and holding Ctrl+arrow will gradually speed up scrolling (0 for no " +"acceleration)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:949 +msgid "Autoscrolling" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:957 +msgid "Speed:" +msgstr "Hastighet:" + +#: ../../po/../src/dialogs/display-settings.cpp:958 +msgid "" +"How fast the canvas autoscrolls when you drag beyond canvas edge (0 to turn " +"autoscroll off)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:968 +#: ../../po/../src/ui/dialog/tracedialog.cpp:357 +#: ../../po/../src/ui/dialog/tracedialog.cpp:390 +msgid "Threshold:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:969 +msgid "" +"How far (in screen pixels) you need to be from the canvas edge to trigger " +"autoscroll; positive is outside the canvas, negative is within the canvas" +msgstr "" + +#. Steps +#: ../../po/../src/dialogs/display-settings.cpp:979 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:57 +msgid "Steps" +msgstr "Steg" + +#: ../../po/../src/dialogs/display-settings.cpp:982 +msgid "Arrow keys move by:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:983 +msgid "" +"Pressing an arrow key moves selected object(s) or node(s) by this distance " +"(in px units)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:984 +#: ../../po/../src/dialogs/display-settings.cpp:995 +#: ../../po/../src/dialogs/display-settings.cpp:1006 +#: ../../po/../src/helper/units.cpp:42 +msgid "px" +msgstr "px" + +#: ../../po/../src/dialogs/display-settings.cpp:993 +msgid "> and < scale by:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:994 +msgid "" +"Pressing > or < scales selection up or down by this increment (in px units)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1004 +msgid "Inset/Outset by:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1005 +msgid "" +"Inset and Outset commands displace the path by this distance (in px units)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1017 +msgid "Compass-like display of angles" +msgstr "" + +#. TRANSLATORS: "positive clockwise" means "increasing in clockwise direction" +#: ../../po/../src/dialogs/display-settings.cpp:1019 +msgid "" +"When on, angles are displayed with 0 at north, 0 to 360 range, positive " +"clockwise; otherwise with 0 at east, -180 to 180 range, positive " +"counterclockwise" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1026 +msgid "Zoom in/out by:" +msgstr "Zooma in/ut med:" + +#: ../../po/../src/dialogs/display-settings.cpp:1027 +#, fuzzy +msgid "" +"Zoom tool click, +/- keys, and middle click zoom in and out by this " +"multiplier" +msgstr "" +"Zoomverktygsklick, +/- tangent och mitten musklick zoomar in och ut med " +"denna multipeln" + +#: ../../po/../src/dialogs/display-settings.cpp:1028 +#: ../../po/../src/helper/units.cpp:44 +msgid "%" +msgstr "%" + +#. Tools +#: ../../po/../src/dialogs/display-settings.cpp:1037 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:58 +msgid "Tools" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1045 +#, fuzzy +msgid "Selector" +msgstr "Markera" + +#: ../../po/../src/dialogs/display-settings.cpp:1056 +msgid "Node" +msgstr "Nod" + +#: ../../po/../src/dialogs/display-settings.cpp:1064 +#: ../../po/../src/verbs.cpp:2073 +#: ../../po/../src/widgets/desktop-widget.cpp:277 +msgid "Zoom" +msgstr "Zooma" + +#. The 4 shape tools +#: ../../po/../src/dialogs/display-settings.cpp:1071 +#, fuzzy +msgid "Shapes" +msgstr "Form" + +#: ../../po/../src/dialogs/display-settings.cpp:1079 +#: ../../po/../src/verbs.cpp:2055 +msgid "Rectangle" +msgstr "Rektangel" + +#: ../../po/../src/dialogs/display-settings.cpp:1085 +#: ../../po/../src/verbs.cpp:2057 +msgid "Ellipse" +msgstr "Ellips" + +#: ../../po/../src/dialogs/display-settings.cpp:1091 +#: ../../po/../src/verbs.cpp:2059 +msgid "Star" +msgstr "Stjärna" + +#: ../../po/../src/dialogs/display-settings.cpp:1097 +#: ../../po/../src/verbs.cpp:2061 +msgid "Spiral" +msgstr "Spiral" + +#: ../../po/../src/dialogs/display-settings.cpp:1111 +#: ../../po/../src/verbs.cpp:2063 +msgid "Pencil" +msgstr "Blyertspenna" + +#: ../../po/../src/dialogs/display-settings.cpp:1114 +msgid "Tolerance:" +msgstr "Tolerans:" + +#: ../../po/../src/dialogs/display-settings.cpp:1115 +msgid "" +"This value affects the amount of smoothing applied to freehand lines; lower " +"values produce more uneven paths with more nodes" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1131 +#: ../../po/../src/verbs.cpp:2065 +msgid "Pen" +msgstr "Bläckpenna" + +#: ../../po/../src/dialogs/display-settings.cpp:1140 +#: ../../po/../src/verbs.cpp:2067 +msgid "Calligraphy" +msgstr "Kalligrafi" + +#: ../../po/../src/dialogs/display-settings.cpp:1147 +#: ../../po/../src/dialogs/text-edit.cpp:353 +#: ../../po/../src/ui/dialog/text-properties.cpp:37 +#: ../../po/../src/verbs.cpp:2069 +msgid "Text" +msgstr "Text" + +#: ../../po/../src/dialogs/display-settings.cpp:1157 +#: ../../po/../src/verbs.cpp:2071 +#, fuzzy +msgid "Gradient" +msgstr "Toningsfyllning" + +#: ../../po/../src/dialogs/display-settings.cpp:1164 +#: ../../po/../src/verbs.cpp:2077 +#, fuzzy +msgid "Connector" +msgstr "Hörn:" + +#: ../../po/../src/dialogs/display-settings.cpp:1171 +#: ../../po/../src/verbs.cpp:2075 +msgid "Dropper" +msgstr "Pipett" + +#. Windows +#: ../../po/../src/dialogs/display-settings.cpp:1183 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:59 +#, fuzzy +msgid "Windows" +msgstr "window1" + +#: ../../po/../src/dialogs/display-settings.cpp:1188 +msgid "Save window geometry" +msgstr "Spara fönsterstorlek" + +#: ../../po/../src/dialogs/display-settings.cpp:1189 +msgid "" +"Save the window size and position with each document (only for Inkscape SVG " +"format)" +msgstr "" +"Spara fönstrets storlek och position i varje dokument (gäller endast " +"Inkscape SVG-formatet)" + +#: ../../po/../src/dialogs/display-settings.cpp:1196 +msgid "Dialogs are hidden in taskbar" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1197 +msgid "Whether dialog windows are to be hidden in the window manager taskbar" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1204 +msgid "Zoom when window is resized" +msgstr "Zooma om teckning när fönsterstorleken ändras" + +#: ../../po/../src/dialogs/display-settings.cpp:1205 +msgid "" +"Zoom drawing when document window is resized, to keep the same area visible " +"(this is the default which can be changed in any window using the button " +"above the right scrollbar)" +msgstr "" + +#. Clones +#: ../../po/../src/dialogs/display-settings.cpp:1213 +#: ../../po/../src/dialogs/find.cpp:624 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:60 +msgid "Clones" +msgstr "Kloner" + +#: ../../po/../src/dialogs/display-settings.cpp:1217 +msgid "When the original moves, its clones and linked offsets:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1229 +msgid "Move in parallel" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1230 +msgid "Clones are translated by the same vector as their original." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1237 +msgid "Stay unmoved" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1238 +msgid "Clones preserve their positions when their original is moved." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1245 +msgid "Move according to transform" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1246 +msgid "" +"Each clone moves according to the value of its transform= attribute. For " +"example, a rotated clone will move in a different direction than its " +"original." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1255 +msgid "When the original is deleted, its clones:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1267 +msgid "Are unlinked" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1267 +msgid "Orphaned clones are converted to regular objects." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1273 +#, fuzzy +msgid "Are deleted" +msgstr "Först markerad" + +#: ../../po/../src/dialogs/display-settings.cpp:1273 +msgid "Orphaned clones are deleted along with their original." +msgstr "" + +#. Transforms +#. TRANSLATORS: Noun, i.e. transformations. +#: ../../po/../src/dialogs/display-settings.cpp:1289 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:61 +msgid "Transforms" +msgstr "Transformeringar" + +#: ../../po/../src/dialogs/display-settings.cpp:1292 +#, fuzzy +msgid "Scale stroke width" +msgstr "Genomstrykningsbredd" + +#: ../../po/../src/dialogs/display-settings.cpp:1293 +#: ../../po/../src/widgets/select-toolbar.cpp:568 +msgid "When scaling objects, scale the stroke width by the same proportion" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1300 +msgid "Scale rounded corners in rectangles" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1301 +#: ../../po/../src/widgets/select-toolbar.cpp:580 +msgid "When scaling rectangles, scale the radii of rounded corners" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1308 +#, fuzzy +msgid "Transform gradients" +msgstr "Transformeringar" + +#: ../../po/../src/dialogs/display-settings.cpp:1309 +#: ../../po/../src/widgets/select-toolbar.cpp:592 +msgid "Transform gradients (in fill or stroke) along with the objects" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1316 +#, fuzzy +msgid "Transform patterns" +msgstr "Transformering" + +#: ../../po/../src/dialogs/display-settings.cpp:1317 +#: ../../po/../src/widgets/select-toolbar.cpp:604 +msgid "Transform patterns (in fill or stroke) along with the objects" +msgstr "" + +#. TRANSLATORS: How to specify the affine transformation in the SVG file. +#: ../../po/../src/dialogs/display-settings.cpp:1327 +#, fuzzy +msgid "Store transformation:" +msgstr "Objekttransformering" + +#: ../../po/../src/dialogs/display-settings.cpp:1338 +msgid "Optimized" +msgstr "Optimerad" + +#: ../../po/../src/dialogs/display-settings.cpp:1339 +msgid "" +"If possible, apply transformation to objects without adding a transform= " +"attribute" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1346 +#, fuzzy +msgid "Preserved" +msgstr "Bevara" + +#: ../../po/../src/dialogs/display-settings.cpp:1347 +msgid "Always store transformation as a transform= attribute on objects" +msgstr "" + +#. Selecting +#: ../../po/../src/dialogs/display-settings.cpp:1355 +msgid "Selecting" +msgstr "Markerar" + +#: ../../po/../src/dialogs/display-settings.cpp:1357 +msgid "Ctrl+A, Tab, Shift+Tab:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1366 +msgid "Select only within current layer" +msgstr "Markera endast inom akivt lager" + +#: ../../po/../src/dialogs/display-settings.cpp:1367 +#, fuzzy +msgid "" +"Uncheck this to make keyboard selection commands work on objects in all " +"layers" +msgstr "" +"Avmarkera detta för att tangentbordsmarkeringskommandon ska arbeta med " +"objekt i alla lager" + +#: ../../po/../src/dialogs/display-settings.cpp:1374 +msgid "Ignore hidden objects" +msgstr "Ignorera gömda objekt" + +#: ../../po/../src/dialogs/display-settings.cpp:1375 +msgid "" +"Uncheck this to be able to select objects that are hidden (either by " +"themselves or by being in a hidden group or layer)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1382 +msgid "Ignore locked objects" +msgstr "Ignorera lÃ¥sta objekt" + +#: ../../po/../src/dialogs/display-settings.cpp:1383 +msgid "" +"Uncheck this to be able to select objects that are locked (either by " +"themselves or by being in a locked group or layer)" +msgstr "" + +#. To be broken into: Display, Save, Export, SVG, Commands +#: ../../po/../src/dialogs/display-settings.cpp:1391 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:62 +msgid "Misc" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1394 +msgid "Default export resolution:" +msgstr "Standardexportupplösning:" + +#: ../../po/../src/dialogs/display-settings.cpp:1395 +#, fuzzy +msgid "Default bitmap resolution (in dots per inch) in the Export dialog" +msgstr "Föredragen upplösning (punkter per tum) av bitmappsbild" + +#. FIXME: add "Used for new exports; once exported, documents remember this value on per-object basis" when implemented +#: ../../po/../src/dialogs/display-settings.cpp:1396 +#: ../../po/../src/dialogs/export.cpp:442 +msgid "dpi" +msgstr "punkter/tum" + +#. TRANSLATORS: When on, an imported bitmap creates an element; otherwise it is a +#. * rectangle with bitmap fill. +#: ../../po/../src/dialogs/display-settings.cpp:1407 +#, fuzzy +msgid "Import bitmap as " +msgstr "Importera bitmappsbild eller SVG-bild till dokument" + +#: ../../po/../src/dialogs/display-settings.cpp:1408 +msgid "" +"When on, an imported bitmap creates an element; otherwise it is a " +"rectangle with bitmap fill" +msgstr "" + +#. TRANSLATORS: When on, the print out (currently Postscript) will have +#. * a comment with the each object's label visible, marking the section +#. * of the printing commands that represent the given object. +#: ../../po/../src/dialogs/display-settings.cpp:1418 +msgid "Add label comments to printing output" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1419 +msgid "" +"When on, a comment will be added to the raw print output, marking the " +"rendered output for an object with its label" +msgstr "" + +#. TRANSLATORS: When on, enable the effects menu, default is off +#: ../../po/../src/dialogs/display-settings.cpp:1427 +msgid "Enable script effects (requires restart) - EXPERIMENTAL" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1428 +msgid "" +"When on, the effects menu is enabled, allowing external effect scripts to be " +"called, requires restart before effective - EXPERIMENTAL" +msgstr "" + +#. TRANSLATORS: The maximum length of the Open Recent list in the File menu. +#: ../../po/../src/dialogs/display-settings.cpp:1436 +#, fuzzy +msgid "Max recent documents:" +msgstr "Skriv ut dokument" + +#: ../../po/../src/dialogs/display-settings.cpp:1437 +msgid "The maximum length of the Open Recent list in the File menu" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1447 +msgid "Simplification threshold:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1448 +msgid "" +"How strong is the Simplify command by default. If you invoke this command " +"several times in quick succession, it will act more and more aggressively; " +"invoking it again after a pause restores the default threshold." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1469 +msgid "Oversample bitmaps:" +msgstr "Översampla bitmappsbilder:" + +#: ../../po/../src/dialogs/display-settings.cpp:1488 +msgid "2x2" +msgstr "2×2" + +#: ../../po/../src/dialogs/display-settings.cpp:1494 +msgid "4x4" +msgstr "4×4" + +#: ../../po/../src/dialogs/display-settings.cpp:1500 +msgid "8x8" +msgstr "8×8" + +#: ../../po/../src/dialogs/display-settings.cpp:1506 +msgid "16x16" +msgstr "16×16" + +#. "view_icon_preview" +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2143 +msgid "_Page" +msgstr "_Sida" + +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2147 +msgid "_Drawing" +msgstr "_Teckning" + +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2149 +msgid "_Selection" +msgstr "_Markering" + +#: ../../po/../src/dialogs/export.cpp:133 +msgid "_Custom" +msgstr "Egen" + +#: ../../po/../src/dialogs/export.cpp:254 +msgid "Export area" +msgstr "Exportera omrÃ¥de" + +#: ../../po/../src/dialogs/export.cpp:300 +msgid "_x0:" +msgstr "_x0:" + +#: ../../po/../src/dialogs/export.cpp:305 +msgid "x_1:" +msgstr "x_1:" + +#: ../../po/../src/dialogs/export.cpp:316 +msgid "_y0:" +msgstr "_y0:" + +#: ../../po/../src/dialogs/export.cpp:321 +msgid "y_1:" +msgstr "y_1:" + +#: ../../po/../src/dialogs/export.cpp:406 +msgid "Bitmap size" +msgstr "Bitmappsstorlek" + +#: ../../po/../src/dialogs/export.cpp:416 +msgid "_Width:" +msgstr "Bredd:" + +#: ../../po/../src/dialogs/export.cpp:416 +#: ../../po/../src/dialogs/export.cpp:431 +#, fuzzy +msgid "pixels at" +msgstr "bildpunkter" + +#: ../../po/../src/dialogs/export.cpp:426 +#, fuzzy +msgid "dp_i" +msgstr "punkter/tum" + +#: ../../po/../src/dialogs/export.cpp:448 +msgid "_Filename" +msgstr "_Filnamn:" + +#: ../../po/../src/dialogs/export.cpp:512 +msgid "_Browse..." +msgstr "_Bläddra..." + +#: ../../po/../src/dialogs/export.cpp:539 +msgid " _Export " +msgstr " Exportera" + +#: ../../po/../src/dialogs/export.cpp:541 +msgid "Export the bitmap file with these settings" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:968 +msgid "You have to enter a filename" +msgstr "Du mÃ¥ste ange ett filnamn" + +#: ../../po/../src/dialogs/export.cpp:973 +msgid "The chosen area to be exported is invalid" +msgstr "Den valda arean att exportera är ogiltig" + +#: ../../po/../src/dialogs/export.cpp:982 +#, c-format +msgid "Directory %s does not exist or is not a directory.\n" +msgstr "Katalogen %s existerar inte eller är det inte en katalog.\n" + +#: ../../po/../src/dialogs/export.cpp:998 +msgid "Export in progress" +msgstr "Exporterar" + +#: ../../po/../src/dialogs/export.cpp:1004 +#, c-format +msgid "Exporting %s (%d x %d)" +msgstr "Exporterar %s (%d × %d)" + +#: ../../po/../src/dialogs/export.cpp:1031 +#, c-format +msgid "Could not export to filename %s.\n" +msgstr "Kunde inte exportera till filen %s.\n" + +#: ../../po/../src/dialogs/export.cpp:1137 +msgid "Select a filename for exporting" +msgstr "Välj ett filnamn för exportering" + +#: ../../po/../src/dialogs/filedialog.cpp:367 +msgid "No preview" +msgstr "Ingen förhandsgranskning" + +#: ../../po/../src/dialogs/filedialog.cpp:468 +msgid "too large for preview" +msgstr "för stor för förhandsgranskning58" + +#: ../../po/../src/dialogs/filedialog.cpp:762 +#: ../../po/../src/dialogs/filedialog.cpp:763 +msgid "All Images" +msgstr "Alla bilder" + +#: ../../po/../src/dialogs/filedialog.cpp:767 +#: ../../po/../src/dialogs/filedialog.cpp:768 +msgid "All Files" +msgstr "Alla filer" + +#: ../../po/../src/dialogs/filedialog.cpp:774 +#: ../../po/../src/dialogs/filedialog.cpp:775 +msgid "All Inkscape Files" +msgstr "Alla Inkscape-filer" + +#: ../../po/../src/dialogs/filedialog.cpp:1176 +msgid "Guess from extension" +msgstr "Gissa frÃ¥n ändelse" + +#. ###### Add the file types menu +#. createFilterMenu(); +#. ###### Do we want the .xxx extension automatically added? +#: ../../po/../src/dialogs/filedialog.cpp:1261 +msgid "Append filename extension automatically" +msgstr "Lägg till filnamnsändelse automatiskt" + +#. TRANSLATORS: "%s" is replaced with "exact" or "partial" when this string is displayed +#: ../../po/../src/dialogs/find.cpp:378 +#, fuzzy, c-format +msgid "%d object found (out of %d), %s match." +msgid_plural "%d objects found (out of %d), %s match." +msgstr[0] "Anslut linjer vid markerade noder" +msgstr[1] "Anslut linjer vid markerade noder" + +#: ../../po/../src/dialogs/find.cpp:381 +#, fuzzy +msgid "exact" +msgstr "Text" + +#: ../../po/../src/dialogs/find.cpp:381 +#, fuzzy +msgid "partial" +msgstr "Spiral" + +#: ../../po/../src/dialogs/find.cpp:388 +#, fuzzy +msgid "No objects found" +msgstr "Inga objekt" + +#: ../../po/../src/dialogs/find.cpp:546 +#, fuzzy +msgid "T_ype: " +msgstr "Typ:" + +#: ../../po/../src/dialogs/find.cpp:553 +msgid "Search in all object types" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:553 +#, fuzzy +msgid "All types" +msgstr "Fyllningsstil" + +#: ../../po/../src/dialogs/find.cpp:564 +msgid "Search all shapes" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:564 +#, fuzzy +msgid "All shapes" +msgstr "Alla figurverktyg" + +#: ../../po/../src/dialogs/find.cpp:581 +#, fuzzy +msgid "Search rectangles" +msgstr "Rita rektangel" + +#: ../../po/../src/dialogs/find.cpp:581 +#, fuzzy +msgid "Rectangles" +msgstr "Rektangel" + +#: ../../po/../src/dialogs/find.cpp:586 +msgid "Search ellipses, arcs, circles" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:586 +#, fuzzy +msgid "Ellipses" +msgstr "Ellips" + +#: ../../po/../src/dialogs/find.cpp:591 +#, fuzzy +msgid "Search stars and polygons" +msgstr "Skapa stjärnor och polygoner" + +#: ../../po/../src/dialogs/find.cpp:591 +#, fuzzy +msgid "Stars" +msgstr "Stjärna" + +#: ../../po/../src/dialogs/find.cpp:596 +#, fuzzy +msgid "Search spirals" +msgstr "Skapa spiraler" + +#: ../../po/../src/dialogs/find.cpp:596 +#, fuzzy +msgid "Spirals" +msgstr "Spiral" + +#. TRANSLATORS: polyline is a set of connected straight line segments +#. http://www.w3.org/TR/SVG11/shapes.html#PolylineElement +#: ../../po/../src/dialogs/find.cpp:609 +msgid "Search paths, lines, polylines" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:609 +msgid "Paths" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:614 +#, fuzzy +msgid "Search text objects" +msgstr "Markerade objekt" + +#: ../../po/../src/dialogs/find.cpp:614 +#, fuzzy +msgid "Texts" +msgstr "Text" + +#: ../../po/../src/dialogs/find.cpp:619 +msgid "Search groups" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:619 +#, fuzzy +msgid "Groups" +msgstr "Gruppera" + +#: ../../po/../src/dialogs/find.cpp:624 +msgid "Search clones" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:629 +#, fuzzy +msgid "Search images" +msgstr "Skala med bild" + +#: ../../po/../src/dialogs/find.cpp:629 +msgid "Images" +msgstr "Bilder" + +#: ../../po/../src/dialogs/find.cpp:634 +#, fuzzy +msgid "Search offset objects" +msgstr "Skapa och redigera textobjekt" + +#: ../../po/../src/dialogs/find.cpp:634 +msgid "Offsets" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:694 +msgid "_Text: " +msgstr "_Text: " + +#: ../../po/../src/dialogs/find.cpp:694 +msgid "Find objects by their text content (exact or partial match)" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:695 +msgid "_ID: " +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:695 +msgid "Find objects by the value of the id attribute (exact or partial match)" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:696 +msgid "_Style: " +msgstr " _Stil: " + +#: ../../po/../src/dialogs/find.cpp:696 +msgid "" +"Find objects by the value of the style attribute (exact or partial match)" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:697 +msgid "_Attribute: " +msgstr "_Attribut: " + +#: ../../po/../src/dialogs/find.cpp:697 +msgid "Find objects by the name of an attribute (exact or partial match)" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:711 +msgid "Search in s_election" +msgstr "Sök i markering" + +#: ../../po/../src/dialogs/find.cpp:715 +msgid "Limit search to the current selection" +msgstr "Begränsa sökningen till aktuell markering" + +#: ../../po/../src/dialogs/find.cpp:720 +msgid "Search in current _layer" +msgstr "Sök i aktuellt _lager" + +#: ../../po/../src/dialogs/find.cpp:724 +msgid "Limit search to the current layer" +msgstr "Begränsa sökningen till aktuellt lager" + +#: ../../po/../src/dialogs/find.cpp:729 +msgid "Include _hidden" +msgstr "Inkludera gömda" + +#: ../../po/../src/dialogs/find.cpp:733 +msgid "Include hidden objects in search" +msgstr "Inkludera gömda objekt i sökningen" + +#: ../../po/../src/dialogs/find.cpp:738 +msgid "Include l_ocked" +msgstr "Inkludera lÃ¥sta" + +#: ../../po/../src/dialogs/find.cpp:742 +msgid "Include locked objects in search" +msgstr "Inkludera lÃ¥sta objekt i sökningen" + +#: ../../po/../src/dialogs/find.cpp:753 +msgid "Clear values" +msgstr "Rensa värden" + +#: ../../po/../src/dialogs/find.cpp:754 +msgid "_Find" +msgstr "Sök" + +#: ../../po/../src/dialogs/find.cpp:754 +msgid "Select objects matching all of the fields you filled in" +msgstr "Markera objekten som matchar alla fält du fyllt i" + +#: ../../po/../src/dialogs/iconpreview.cpp:145 +#, c-format +msgid "%d x %d" +msgstr "" + +#: ../../po/../src/dialogs/iconpreview.cpp:193 +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:857 +#: ../../po/../src/widgets/desktop-widget.cpp:1069 +msgid "Selection" +msgstr "Markering" + +#: ../../po/../src/dialogs/iconpreview.cpp:195 +#, fuzzy +msgid "Selection only or whole document" +msgstr "Markera endast inom akivt lager" + +#: ../../po/../src/dialogs/iconpreview.cpp:203 +msgid "Refresh the icons" +msgstr "" + +#. Create the label for the object id +#: ../../po/../src/dialogs/item-properties.cpp:126 +#: ../../po/../src/dialogs/item-properties.cpp:327 +#: ../../po/../src/dialogs/item-properties.cpp:396 +#: ../../po/../src/dialogs/item-properties.cpp:403 +msgid "_Id" +msgstr "" + +#: ../../po/../src/dialogs/item-properties.cpp:135 +msgid "" +"The id= attribute (only letters, digits, and the characters .-_: allowed)" +msgstr "" + +#. Button for setting the object's id, label, title and description. +#: ../../po/../src/dialogs/item-properties.cpp:149 +#, fuzzy +msgid "_Set" +msgstr "Markera" + +#. Create the label for the object label +#: ../../po/../src/dialogs/item-properties.cpp:158 +#, fuzzy +msgid "_Label" +msgstr "avfasad" + +#: ../../po/../src/dialogs/item-properties.cpp:167 +msgid "A freeform label for the object" +msgstr "" + +#. Create the label for the object title +#: ../../po/../src/dialogs/item-properties.cpp:179 +#: ../../po/../src/dialogs/rdf.cpp:243 +msgid "Title" +msgstr "Titel" + +#. Create the frame for the object description +#: ../../po/../src/dialogs/item-properties.cpp:196 +#: ../../po/../src/dialogs/rdf.cpp:287 +msgid "Description" +msgstr "Beskrivning" + +#. Hide +#: ../../po/../src/dialogs/item-properties.cpp:223 +msgid "_Hide" +msgstr "Göm" + +#: ../../po/../src/dialogs/item-properties.cpp:224 +msgid "Check to make the object invisible" +msgstr "Markera för att göra objektet osynligt" + +#. Lock +#. TRANSLATORS: "Lock" is a verb here +#: ../../po/../src/dialogs/item-properties.cpp:233 +msgid "L_ock" +msgstr "LÃ¥s" + +#: ../../po/../src/dialogs/item-properties.cpp:234 +msgid "Check to make the object insensitive (not selectable by mouse)" +msgstr "Markera för att göra objektet okänsligt (icke markerbart för musen)" + +#: ../../po/../src/dialogs/item-properties.cpp:310 +#: ../../po/../src/dialogs/item-properties.cpp:317 +msgid "Ref" +msgstr "" + +#: ../../po/../src/dialogs/item-properties.cpp:398 +msgid "Id invalid! " +msgstr "Ogiltigt ID!" + +#: ../../po/../src/dialogs/item-properties.cpp:400 +msgid "Id exists! " +msgstr "" + +#: ../../po/../src/dialogs/layer-properties.cpp:50 +msgid "Layer name:" +msgstr "Lagrets namn:" + +#: ../../po/../src/dialogs/layer-properties.cpp:133 +msgid "Rename Layer" +msgstr "Byt namn pÃ¥ lager" + +#: ../../po/../src/dialogs/layer-properties.cpp:136 +msgid "_Rename" +msgstr "Byt namn" + +#. TRANSLATORS: This means "The layer has been renamed" +#: ../../po/../src/dialogs/layer-properties.cpp:147 +msgid "Renamed layer" +msgstr "Bytt namn pÃ¥ lager" + +#: ../../po/../src/dialogs/layer-properties.cpp:151 +msgid "Add Layer" +msgstr "Lägg till lager" + +#: ../../po/../src/dialogs/layer-properties.cpp:153 +msgid "_Add" +msgstr "Lägg till" + +#: ../../po/../src/dialogs/layer-properties.cpp:167 +msgid "New layer created." +msgstr "Skapat nytt lager." + +#: ../../po/../src/dialogs/object-attributes.cpp:34 +msgid "Href:" +msgstr "Href:" + +#: ../../po/../src/dialogs/object-attributes.cpp:35 +msgid "Target:" +msgstr "MÃ¥l:" + +#: ../../po/../src/dialogs/object-attributes.cpp:36 +msgid "Type:" +msgstr "Typ:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkRoleAttribute +#. Identifies the type of the related resource with an absolute URI +#: ../../po/../src/dialogs/object-attributes.cpp:39 +msgid "Role:" +msgstr "Roll:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkArcRoleAttribute +#. For situations where the nature/role alone isn't enough, this offers an additional URI defining the purpose of the link. +#: ../../po/../src/dialogs/object-attributes.cpp:42 +msgid "Arcrole:" +msgstr "BÃ¥groll:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkTitleAttribute +#: ../../po/../src/dialogs/object-attributes.cpp:44 +msgid "Title:" +msgstr "Titel:" + +#: ../../po/../src/dialogs/object-attributes.cpp:45 +msgid "Show:" +msgstr "Visa:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkActuateAttribute +#: ../../po/../src/dialogs/object-attributes.cpp:47 +msgid "Actuate:" +msgstr "Sätt i rörelse:" + +#: ../../po/../src/dialogs/object-attributes.cpp:52 +msgid "URL:" +msgstr "URL:" + +#: ../../po/../src/dialogs/object-attributes.cpp:53 +msgid "X:" +msgstr "X:" + +#: ../../po/../src/dialogs/object-attributes.cpp:54 +msgid "Y:" +msgstr "Y:" + +#: ../../po/../src/dialogs/object-attributes.cpp:98 +#, c-format +msgid "%s attributes" +msgstr "Attribut för %s" + +#: ../../po/../src/dialogs/object-properties.cpp:158 +#, fuzzy +msgid "_Fill" +msgstr "Fyll" + +#: ../../po/../src/dialogs/object-properties.cpp:165 +#, fuzzy +msgid "Stroke _paint" +msgstr "Genomstrykningsbredd" + +#: ../../po/../src/dialogs/object-properties.cpp:172 +#, fuzzy +msgid "Stroke st_yle" +msgstr "Genomstrykningsinställningar" + +#: ../../po/../src/dialogs/object-properties.cpp:183 +#, fuzzy +msgid "Master _opacity" +msgstr "Opacitet:" + +#: ../../po/../src/dialogs/rdf.cpp:244 +msgid "Name by which this document is formally known." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:246 +#, fuzzy +msgid "Date" +msgstr "Rita text" + +#: ../../po/../src/dialogs/rdf.cpp:247 +msgid "Date associated with the creation of this document (YYYY-MM-DD)." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:249 +#, fuzzy +msgid "Format" +msgstr "Fraktal" + +#: ../../po/../src/dialogs/rdf.cpp:250 +msgid "The physical or digital manifestation of this document (MIME type)." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:252 +#, fuzzy +msgid "Type" +msgstr "Typ:" + +#: ../../po/../src/dialogs/rdf.cpp:253 +msgid "Type of document (DCMI Type)." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:256 +#, fuzzy +msgid "Creator" +msgstr "Skapa" + +#: ../../po/../src/dialogs/rdf.cpp:257 +msgid "" +"Name of entity primarily responsible for making the content of this document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:259 +#, fuzzy +msgid "Rights" +msgstr "höger" + +#: ../../po/../src/dialogs/rdf.cpp:260 +msgid "" +"Name of entity with rights to the Intellectual Property of this document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:262 +msgid "Publisher" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:263 +msgid "Name of entity responsible for making this document available." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:266 +#, fuzzy +msgid "Identifier" +msgstr "Mittpunkt" + +#: ../../po/../src/dialogs/rdf.cpp:267 +msgid "Unique URI to reference this document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:269 +msgid "Source" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:270 +msgid "Unique URI to reference the source of this document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:272 +#, fuzzy +msgid "Relation" +msgstr "Upplösning:" + +#: ../../po/../src/dialogs/rdf.cpp:273 +#, fuzzy +msgid "Unique URI to a related document." +msgstr "Namnlöst dokument" + +#: ../../po/../src/dialogs/rdf.cpp:275 +#, fuzzy +msgid "Language" +msgstr "vinkel" + +#: ../../po/../src/dialogs/rdf.cpp:276 +msgid "" +"Two-letter language tag with optional subtags for the language of this " +"document. (e.g. 'en-GB')" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:278 +msgid "Keywords" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:279 +msgid "" +"The topic of this document as comma-separated key words, phrases, or " +"classifications." +msgstr "" + +#. TRANSLATORS: "Coverage": the spatial or temporal characteristics of the content. +#. For info, see Appendix D of http://www.w3.org/TR/1998/WD-rdf-schema-19980409/ +#: ../../po/../src/dialogs/rdf.cpp:283 +msgid "Coverage" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:284 +msgid "Extent or scope of this document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:288 +msgid "A short account of the content of this document." +msgstr "" + +#. FIXME: need to handle 1 agent per line of input +#: ../../po/../src/dialogs/rdf.cpp:292 +#, fuzzy +msgid "Contributors" +msgstr "Attribut" + +#: ../../po/../src/dialogs/rdf.cpp:293 +msgid "" +"Names of entities responsible for making contributions to the content of " +"this document." +msgstr "" + +#. TRANSLATORS: URL to a page that defines the license for the document +#: ../../po/../src/dialogs/rdf.cpp:297 +msgid "URI" +msgstr "" + +#. TRANSLATORS: this is where you put a URL to a page that defines the license +#: ../../po/../src/dialogs/rdf.cpp:299 +msgid "URI to this document's license's namespace definition." +msgstr "" + +#. TRANSLATORS: fragment of XML representing the license of the document +#: ../../po/../src/dialogs/rdf.cpp:303 +#, fuzzy +msgid "Fragment" +msgstr "Argument:" + +#: ../../po/../src/dialogs/rdf.cpp:304 +msgid "XML fragment for the RDF 'License' section." +msgstr "" + +#: ../../po/../src/dialogs/stroke-style.cpp:774 +#: ../../po/../src/widgets/gradient-vector.cpp:263 +#: ../../po/../src/widgets/paint-selector.cpp:751 +msgid "No document selected" +msgstr "Inget dokument markerat" + +#: ../../po/../src/dialogs/stroke-style.cpp:992 +#, fuzzy +msgid "Stroke width" +msgstr "Genomstrykningsbredd" + +#. Join type +#. TRANSLATORS: The line join style specifies the shape to be used at the +#. corners of paths. It can be "miter", "round" or "bevel". +#: ../../po/../src/dialogs/stroke-style.cpp:1015 +msgid "Join:" +msgstr "Anslutning:" + +#. TRANSLATORS: Miter join: joining lines with a sharp (pointed) corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1027 +msgid "Miter join" +msgstr "Miteranslutning" + +#. TRANSLATORS: Round join: joining lines with a rounded corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1035 +msgid "Round join" +msgstr "Rund anslutning" + +#. TRANSLATORS: Bevel join: joining lines with a blunted (flattened) corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1043 +msgid "Bevel join" +msgstr "Avfasad anslutning" + +#. Miterlimit +#. TRANSLATORS: Miter limit: only for "miter join", this limits the length +#. of the sharp "spike" when the lines connect at too sharp an angle. +#. When two line segments meet at a sharp angle, a miter join results in a +#. spike that extends well beyond the connection point. The purpose of the +#. miter limit is to cut off such spikes (i.e. convert them into bevels) +#. when they become too long. +#: ../../po/../src/dialogs/stroke-style.cpp:1054 +msgid "Miter limit:" +msgstr "Mitergräns:" + +#: ../../po/../src/dialogs/stroke-style.cpp:1062 +msgid "Maximum length of the miter (in units of stroke width)" +msgstr "" + +#. Cap type +#. TRANSLATORS: cap type specifies the shape for the ends of lines +#: ../../po/../src/dialogs/stroke-style.cpp:1075 +msgid "Cap:" +msgstr "Lock:" + +#. TRANSLATORS: Butt cap: the line shape does not extend beyond the end point +#. of the line; the ends of the line are square +#: ../../po/../src/dialogs/stroke-style.cpp:1086 +msgid "Butt cap" +msgstr "" + +#. TRANSLATORS: Round cap: the line shape extends beyond the end point of the +#. line; the ends of the line are rounded +#: ../../po/../src/dialogs/stroke-style.cpp:1093 +#, fuzzy +msgid "Round cap" +msgstr "Rund anslutning" + +#. TRANSLATORS: Square cap: the line shape extends beyond the end point of the +#. line; the ends of the line are square +#: ../../po/../src/dialogs/stroke-style.cpp:1100 +#, fuzzy +msgid "Square cap" +msgstr "Fyrkantiga ändpunkter" + +#. Dash +#: ../../po/../src/dialogs/stroke-style.cpp:1106 +#, fuzzy +msgid "Dashes:" +msgstr "Massa:" + +#. TRANSLATORS: Path markers are an SVG feature that allows you to attach arbitrary shapes +#. (arrowheads, bullets, faces, whatever) to the start, end, or middle nodes of a path. +#: ../../po/../src/dialogs/stroke-style.cpp:1127 +#, fuzzy +msgid "Start Markers:" +msgstr "Stjärnegenskaper" + +#: ../../po/../src/dialogs/stroke-style.cpp:1137 +msgid "Mid Markers:" +msgstr "" + +#: ../../po/../src/dialogs/stroke-style.cpp:1148 +msgid "End Markers:" +msgstr "" + +#: ../../po/../src/dialogs/swatches.cpp:424 +#, c-format +msgid "Palettes directory (%s) is unavailable." +msgstr "" + +#. TODO: Insert widgets +#: ../../po/../src/dialogs/text-edit.cpp:199 +#: ../../po/../src/ui/dialog/text-properties.cpp:36 +#, fuzzy +msgid "Font" +msgstr "Främst" + +#: ../../po/../src/dialogs/text-edit.cpp:216 +msgid "Layout" +msgstr "Utseende" + +#: ../../po/../src/dialogs/text-edit.cpp:229 +#, fuzzy +msgid "Align lines left" +msgstr "Vänsterjustera överst" + +#. TRANSLATORS: `Center' here is a verb. +#: ../../po/../src/dialogs/text-edit.cpp:243 +#, fuzzy +msgid "Center lines" +msgstr "Mittpunkt i Y-led:" + +#: ../../po/../src/dialogs/text-edit.cpp:256 +#, fuzzy +msgid "Align lines right" +msgstr "Högerjustera överst" + +#: ../../po/../src/dialogs/text-edit.cpp:278 +#, fuzzy +msgid "Horizontal text" +msgstr "horisontell flytt" + +#: ../../po/../src/dialogs/text-edit.cpp:292 +#, fuzzy +msgid "Vertical text" +msgstr "Vertikalt mittpunktsvärde" + +#: ../../po/../src/dialogs/text-edit.cpp:307 +msgid "Line spacing:" +msgstr "RadavstÃ¥nd:" + +#: ../../po/../src/dialogs/text-edit.cpp:400 +msgid "Set as default" +msgstr "Ställ in som standard" + +#: ../../po/../src/dialogs/tiledialog.cpp:603 +#, fuzzy +msgid "Rows:" +msgstr "Visa:" + +#: ../../po/../src/dialogs/tiledialog.cpp:613 +msgid "Number of rows" +msgstr "" + +#: ../../po/../src/dialogs/tiledialog.cpp:617 +#, fuzzy +msgid "Equal height" +msgstr "Höjd: " + +#: ../../po/../src/dialogs/tiledialog.cpp:627 +msgid "If not set, each row has the height of the tallest object in it" +msgstr "" + +#. #### Radio buttons to control vertical alignment #### +#. #### Radio buttons to control horizontal alignment #### +#: ../../po/../src/dialogs/tiledialog.cpp:637 +#: ../../po/../src/dialogs/tiledialog.cpp:708 +#, fuzzy +msgid "Align:" +msgstr "Justera" + +#: ../../po/../src/dialogs/tiledialog.cpp:672 +#, fuzzy +msgid " X " +msgstr "% " + +#. #### Number of columns #### +#: ../../po/../src/dialogs/tiledialog.cpp:678 +#, fuzzy +msgid "Columns:" +msgstr "Ändra" + +#: ../../po/../src/dialogs/tiledialog.cpp:688 +msgid "Number of columns" +msgstr "" + +#: ../../po/../src/dialogs/tiledialog.cpp:692 +#, fuzzy +msgid "Equal width" +msgstr "Bredd " + +#: ../../po/../src/dialogs/tiledialog.cpp:701 +msgid "If not set, each column has the width of the widest object in it" +msgstr "" + +#. #### Radio buttons to control spacing manually or to fit selection bbox #### +#: ../../po/../src/dialogs/tiledialog.cpp:746 +#, fuzzy +msgid "Fit into selection box" +msgstr "Klipp ut markering" + +#: ../../po/../src/dialogs/tiledialog.cpp:753 +#, fuzzy +msgid "Set spacing:" +msgstr "Y-avstÃ¥nd:" + +#. #### Y Padding #### +#: ../../po/../src/dialogs/tiledialog.cpp:777 +#, fuzzy +msgid "Row spacing: " +msgstr "RadavstÃ¥nd:" + +#: ../../po/../src/dialogs/tiledialog.cpp:786 +#, fuzzy +msgid "Vertical spacing between rows" +msgstr "Vertikalt mittpunktsvärde" + +#. #### X padding #### +#: ../../po/../src/dialogs/tiledialog.cpp:795 +#, fuzzy +msgid "Column spacing:" +msgstr "RadavstÃ¥nd:" + +#: ../../po/../src/dialogs/tiledialog.cpp:804 +#, fuzzy +msgid "Horizontal spacing between columns" +msgstr "horisontellt skalningsvärde" + +#: ../../po/../src/dialogs/tiledialog.cpp:818 +#, fuzzy +msgid "Arrange selected objects" +msgstr "Gruppera markerade objekt" + +#: ../../po/../src/dialogs/xml-tree.cpp:178 +msgid "Click to select nodes, drag to rearrange." +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:189 +msgid "Click attribute to edit." +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:193 +#, c-format +msgid "" +"Attribute %s selected. Press Ctrl+Enter when done editing to " +"commit changes." +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:284 +msgid "Drag to reorder nodes" +msgstr "Dra för att sortera om noder" + +#: ../../po/../src/dialogs/xml-tree.cpp:304 +msgid "New element node" +msgstr "Ny elementnod" + +#: ../../po/../src/dialogs/xml-tree.cpp:326 +msgid "New text node" +msgstr "Ny textnod" + +#: ../../po/../src/dialogs/xml-tree.cpp:347 +msgid "Duplicate node" +msgstr "MÃ¥ngfaldiga nod" + +#: ../../po/../src/dialogs/xml-tree.cpp:368 +msgid "Delete node" +msgstr "Ta bort nod" + +#: ../../po/../src/dialogs/xml-tree.cpp:384 +msgid "Unindent node" +msgstr "Dra ut nod" + +#: ../../po/../src/dialogs/xml-tree.cpp:399 +msgid "Indent node" +msgstr "Dra in nod" + +#: ../../po/../src/dialogs/xml-tree.cpp:411 +msgid "Raise node" +msgstr "Höj nod" + +#: ../../po/../src/dialogs/xml-tree.cpp:423 +msgid "Lower node" +msgstr "Sänk nod" + +#: ../../po/../src/dialogs/xml-tree.cpp:468 +msgid "Delete attribute" +msgstr "Ta bort attribut" + +#. TRANSLATORS: "Attribute" is a noun here +#: ../../po/../src/dialogs/xml-tree.cpp:513 +msgid "Attribute name" +msgstr "Attributnamn" + +#. TRANSLATORS: "Set" is a verb here +#: ../../po/../src/dialogs/xml-tree.cpp:533 +msgid "Set attribute" +msgstr "Ställ in attribut" + +#. TRANSLATORS: "Set" is a verb here +#: ../../po/../src/dialogs/xml-tree.cpp:535 +#, fuzzy +msgid "Set" +msgstr "Markera" + +#. TRANSLATORS: "Attribute" is a noun here +#: ../../po/../src/dialogs/xml-tree.cpp:558 +msgid "Attribute value" +msgstr "Attributvärde" + +#: ../../po/../src/dialogs/xml-tree.cpp:1318 +msgid "New element node..." +msgstr "Ny elementnod..." + +#: ../../po/../src/dialogs/xml-tree.cpp:1339 +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:100 +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:98 +msgid "Cancel" +msgstr "Avbryt" + +#: ../../po/../src/dialogs/xml-tree.cpp:1345 +msgid "Create" +msgstr "Skapa" + +#: ../../po/../src/dialogs/xml-tree.cpp:1458 +#, c-format +msgid "" +"Cannot set %s: Another element with value %s already exists!" +msgstr "" + +#: ../../po/../src/document.cpp:369 +#, c-format +msgid "New document %d" +msgstr "Nytt dokument %d" + +#: ../../po/../src/document.cpp:401 +#, c-format +msgid "Memory document %d" +msgstr "Minnesdokument %d" + +#: ../../po/../src/document.cpp:524 +#, c-format +msgid "Unnamed document %d" +msgstr "Namnlöst dokument %d" + +#. We hit green anchor, closing Green-Blue-Red +#: ../../po/../src/draw-context.cpp:441 +msgid "Path is closed." +msgstr "" + +#. We hit bot start and end of single curve, closing paths +#: ../../po/../src/draw-context.cpp:456 +msgid "Closing path." +msgstr "" + +#. alpha of color under cursor, to show in the statusbar +#. locale-sensitive printf is OK, since this goes to the UI, not into SVG +#: ../../po/../src/dropper-context.cpp:354 +#, c-format +msgid " alpha %.3g" +msgstr "" + +#. where the color is picked, to show in the statusbar +#: ../../po/../src/dropper-context.cpp:356 +#, c-format +msgid ", averaged with radius %d" +msgstr "" + +#: ../../po/../src/dropper-context.cpp:356 +msgid " under cursor" +msgstr "" + +#. message, to show in the statusbar +#: ../../po/../src/dropper-context.cpp:358 +msgid "Release mouse to set color." +msgstr "" + +#: ../../po/../src/dropper-context.cpp:358 +#: ../../po/../src/tools-switch.cpp:207 +msgid "" +"Click to set fill, Shift+click to set stroke; drag to " +"average color in area; with Alt to pick inverse color; Ctrl+C " +"to copy the color under mouse to clipboard" +msgstr "" + +#: ../../po/../src/extension/dependency.cpp:244 +msgid "Dependency::" +msgstr "" + +#: ../../po/../src/extension/dependency.cpp:245 +#, fuzzy +msgid " type: " +msgstr "Filtyp:" + +#: ../../po/../src/extension/dependency.cpp:246 +#, fuzzy +msgid " location: " +msgstr "Upplösning:" + +#: ../../po/../src/extension/dependency.cpp:247 +msgid " string: " +msgstr "" + +#: ../../po/../src/extension/dependency.cpp:250 +#, fuzzy +msgid " description: " +msgstr "Position" + +#. static int i = 0; +#. std::cout << "Checking module[" << i++ << "]: " << name << std::endl; +#: ../../po/../src/extension/extension.cpp:244 +msgid "" +" This is caused by an improper .inx file for this extension. An improper ." +"inx file could have been caused by a faulty installation of Inkscape." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:247 +msgid "an ID was not defined for it." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:251 +msgid "there was no name defined for it." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:255 +msgid "the XML description of it got lost." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:259 +msgid "no implementation was defined for the extension." +msgstr "" + +#. std::cout << "Failed: " << *(_deps[i]) << std::endl; +#: ../../po/../src/extension/extension.cpp:266 +msgid "a dependency was not met." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:286 +#, fuzzy +msgid "Extension \"" +msgstr "Tillägg" + +#: ../../po/../src/extension/extension.cpp:286 +msgid "\" failed to load because " +msgstr "" + +#: ../../po/../src/extension/extension.cpp:565 +#, c-format +msgid "Could not create extension error log file '%s'" +msgstr "" + +#. This is some filler text, needs to change before relase +#: ../../po/../src/extension/error-file.cpp:56 +msgid "" +"One or more extensions failed to load\n" +"\n" +"The failed extensions have been skipped. Inkscape will continue to run " +"normally but those extensions will be unavailable. For details to " +"troubleshoot this problem, please refer to the error log located at: " +msgstr "" + +#. This is some filler text, needs to change before relase +#: ../../po/../src/extension/error-file.cpp:65 +msgid "Show dialog on startup" +msgstr "" + +#: ../../po/../src/extension/implementation/script.cpp:845 +msgid "" +"Inkscape has received an error from the script that it called. The text " +"returned with the error is included below. Inkscape will continue working, " +"but the action you requested has been cancelled." +msgstr "" + +#: ../../po/../src/extension/implementation/script.cpp:858 +msgid "" +"Inkscape has received additional data from the script executed. The script " +"did not return an error, but this may indicate the results will not be as " +"expected." +msgstr "" + +#: ../../po/../src/extension/init.cpp:173 +msgid "Null external module directory name. Modules will not be loaded." +msgstr "" + +#: ../../po/../src/extension/init.cpp:187 +#, c-format +msgid "" +"Modules directory (%s) is unavailable. External modules in that directory " +"will not be loaded." +msgstr "" + +#: ../../po/../src/extension/internal/gnome.cpp:80 +msgid "Select printer" +msgstr "Välj skrivare" + +#: ../../po/../src/extension/internal/gnome.cpp:131 +#, fuzzy +msgid "Inkscape: Print Preview" +msgstr "Sodipodi (dokumentnamn %s...): Förhandsgranska" + +#: ../../po/../src/extension/internal/grid.cpp:213 +#, fuzzy +msgid "Line Width" +msgstr " Bredd " + +#: ../../po/../src/extension/internal/grid.cpp:214 +#, fuzzy +msgid "Horizontal Spacing" +msgstr "horisontell flytt" + +#: ../../po/../src/extension/internal/grid.cpp:215 +#, fuzzy +msgid "Vertical Spacing" +msgstr "Vertikalt mittpunktsvärde" + +#: ../../po/../src/extension/internal/grid.cpp:216 +#, fuzzy +msgid "Horizontal Offset" +msgstr "horisontell flytt" + +#: ../../po/../src/extension/internal/grid.cpp:217 +#, fuzzy +msgid "Vertical Offset" +msgstr "Vertikalt mittpunktsvärde" + +#: ../../po/../src/extension/internal/ps.cpp:123 +msgid "Print Destination" +msgstr "Utskriftsdestination" + +#. Print properties frame +#: ../../po/../src/extension/internal/ps.cpp:138 +msgid "Print properties" +msgstr "Utskriftsegenskaper" + +#: ../../po/../src/extension/internal/ps.cpp:145 +msgid "Print using PostScript operators" +msgstr "Skriv ut genom användning av PostScript-operatorer" + +#: ../../po/../src/extension/internal/ps.cpp:147 +msgid "" +"Use PostScript vector operators. The resulting image is usually smaller in " +"file size and can be arbitrarily scaled, but alpha transparency and patterns " +"will be lost." +msgstr "" +"Använd PostScript-vektoroperatorer. Resulterande bilden blir (vanligtvis) " +"mindre och kan skalas godtyckligt, men alfatransparens, och mönster kommer " +"att gÃ¥ förlorade" + +#: ../../po/../src/extension/internal/ps.cpp:152 +msgid "Print as bitmap" +msgstr "Skriv ut som bitmappsbild" + +#: ../../po/../src/extension/internal/ps.cpp:154 +#, fuzzy +msgid "" +"Print everything as bitmap. The resulting image is usually larger in file " +"size and cannot be arbitrarily scaled without quality loss, but all objects " +"will be rendered exactly as displayed." +msgstr "" +"Skriv ut allt som bitmappsbilder. Resulterande bilden kommer (vanligtvis) " +"att bli större och dess kvalitet beror pÃ¥ zoomfaktorn, men all grafik kommer " +"att renderas identiskt till displayen" + +#: ../../po/../src/extension/internal/ps.cpp:168 +msgid "Preferred resolution (dots per inch) of bitmap" +msgstr "Föredragen upplösning (punkter per tum) av bitmappsbild" + +#: ../../po/../src/extension/internal/ps.cpp:182 +msgid "Resolution:" +msgstr "Upplösning:" + +#. Print destination frame +#: ../../po/../src/extension/internal/ps.cpp:186 +msgid "Print destination" +msgstr "Utskriftsdestination" + +#: ../../po/../src/extension/internal/ps.cpp:192 +msgid "" +"Use '> filename' to print to file.\n" +"Use '| prog arg...' to pipe to a program." +msgstr "" +"Använd \"> filnamn\" för att skriva till fil.\n" +"Använd \"| prog arg...\" för att skicka via rör till program" + +#: ../../po/../src/extension/internal/ps.cpp:1227 +msgid "write error occurred" +msgstr "skrivfel inträffade" + +#: ../../po/../src/extension/prefdialog.cpp:21 +#, fuzzy +msgid " Preferences" +msgstr "Objekt är referens" + +#. We can't call sp_ui_error_dialog because we may be +#. running from the console, in which case calling sp_ui +#. routines will cause a segfault. See bug 1000350 - bryce +#. sp_ui_error_dialog(_("Format autodetect failed. The file is being opened as SVG.")); +#: ../../po/../src/extension/system.cpp:105 +msgid "Format autodetect failed. The file is being opened as SVG." +msgstr "" + +#. TRANSLATORS: default.svg is localizable - this is the name of the default document +#. template. This way you can localize the default pagesize, translate the name of +#. the default layer, etc. If you wish to localize this file, please create a +#. localized share/templates/default.xx.svg file, where xx is your language code. +#: ../../po/../src/file.cpp:133 +#, fuzzy +msgid "default.svg" +msgstr "Standardalternativ" + +#: ../../po/../src/file.cpp:215 ../../po/../src/file.cpp:900 +#, c-format +msgid "Failed to load the requested file %s" +msgstr "" + +#: ../../po/../src/file.cpp:240 +#, fuzzy +msgid "Document not saved yet. Cannot revert." +msgstr "Dokumentnamn:" + +#: ../../po/../src/file.cpp:246 +#, c-format +msgid "Changes will be lost! Are you sure you want to reload document %s?" +msgstr "" + +#: ../../po/../src/file.cpp:266 +#, fuzzy +msgid "Document reverted." +msgstr "Dokumentnamn:" + +#: ../../po/../src/file.cpp:268 +#, fuzzy +msgid "Document not reverted." +msgstr "Dokumentnamn:" + +#: ../../po/../src/file.cpp:382 +msgid "Select file to open" +msgstr "Välj fil att öppna" + +#: ../../po/../src/file.cpp:518 +#, c-format +msgid "Removed %i unused definition in <defs>." +msgid_plural "Removed %i unused definitions in <defs>." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/file.cpp:523 +msgid "No unused definitions in <defs>." +msgstr "" + +#: ../../po/../src/file.cpp:548 +#, c-format +msgid "" +"No Inkscape extension found to save document (%s). This may have been " +"caused by an unknown filename extension." +msgstr "" + +#: ../../po/../src/file.cpp:549 ../../po/../src/file.cpp:557 +#, fuzzy +msgid "Document not saved." +msgstr "Dokumentnamn:" + +#: ../../po/../src/file.cpp:556 +#, c-format +msgid "File %s could not be saved." +msgstr "" + +#: ../../po/../src/file.cpp:566 +#, fuzzy +msgid "Document saved." +msgstr "Dokumentnamn:" + +#: ../../po/../src/file.cpp:614 +#, fuzzy, c-format +msgid "drawing%s" +msgstr "Teckning" + +#: ../../po/../src/file.cpp:620 +#, fuzzy, c-format +msgid "drawing-%d%s" +msgstr "Teckning" + +#: ../../po/../src/file.cpp:655 +#, fuzzy +msgid "Select file to save to" +msgstr "Välj fil att öppna" + +#: ../../po/../src/file.cpp:739 +msgid "No changes need to be saved." +msgstr "" + +#: ../../po/../src/file.cpp:926 +msgid "Select file to import" +msgstr "Välj fil att importera" + +#: ../../po/../src/gradient-context.cpp:263 +msgid "Ctrl: snap gradient angle" +msgstr "" + +#: ../../po/../src/gradient-context.cpp:264 +msgid "Shift: draw gradient around the starting point" +msgstr "" + +#. We did an undoable action, but sp_document_done will be called by the knot when released +#. status text; we do not track coords because this branch is run once, not all the time +#. during drag +#: ../../po/../src/gradient-context.cpp:462 +#, c-format +msgid "Gradient for %d objects; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/gradient-context.cpp:464 +#, fuzzy +msgid "Select objects on which to create gradient." +msgstr "Klipp ut markerade objekt till urklipp" + +#: ../../po/../src/gradient-drag.cpp:65 +#, fuzzy +msgid "Linear gradient start" +msgstr "Linjär toning" + +#. POINT_LG_P1 +#: ../../po/../src/gradient-drag.cpp:66 +#, fuzzy +msgid "Linear gradient end" +msgstr "Linjär toning" + +#: ../../po/../src/gradient-drag.cpp:67 +#, fuzzy +msgid "Radial gradient center" +msgstr "Radiell toning" + +#: ../../po/../src/gradient-drag.cpp:68 ../../po/../src/gradient-drag.cpp:69 +#, fuzzy +msgid "Radial gradient radius" +msgstr "Radiell toning" + +#: ../../po/../src/gradient-drag.cpp:70 +#, fuzzy +msgid "Radial gradient focus" +msgstr "Radiell toning" + +#: ../../po/../src/gradient-drag.cpp:659 +#, c-format +msgid "" +"%s for: %s%s; drag with Ctrl to snap angle, with Ctrl+Alt to " +"preserve angle, with Ctrl+Shift to scale around center" +msgstr "" + +#: ../../po/../src/gradient-drag.cpp:662 +#, fuzzy +msgid " (stroke)" +msgstr "Är genomstruket" + +#: ../../po/../src/gradient-drag.cpp:665 +msgid "" +"Radial gradient center and focus; drag with Shift to " +"separate focus" +msgstr "" + +#: ../../po/../src/gradient-drag.cpp:667 +#, c-format +msgid "" +"Gradient point shared by %d gradients; drag with Shift to " +"separate" +msgstr "" + +#: ../../po/../src/helper/units.cpp:40 +msgid "Unit" +msgstr "Enhet" + +#: ../../po/../src/helper/units.cpp:40 +msgid "Units" +msgstr "Enheter" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Point" +msgstr "Punkter" + +#: ../../po/../src/helper/units.cpp:41 +msgid "pt" +msgstr "pt" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Points" +msgstr "Punkter" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Pt" +msgstr "pt" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Pixel" +msgstr "Bildpunkt" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Pixels" +msgstr "Bildpunkter" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Px" +msgstr "bp" + +#. You can add new elements from this point forward +#: ../../po/../src/helper/units.cpp:44 ../share/extensions/straightseg.inx.h:2 +msgid "Percent" +msgstr "Procent" + +#: ../../po/../src/helper/units.cpp:44 +msgid "Percents" +msgstr "procent" + +#: ../../po/../src/helper/units.cpp:45 +msgid "Millimeter" +msgstr "Millimeter" + +#: ../../po/../src/helper/units.cpp:45 +msgid "mm" +msgstr "mm" + +#: ../../po/../src/helper/units.cpp:45 +msgid "Millimeters" +msgstr "Millimeter" + +#: ../../po/../src/helper/units.cpp:46 +msgid "Centimeter" +msgstr "Centimeter" + +#: ../../po/../src/helper/units.cpp:46 +msgid "cm" +msgstr "cm" + +#: ../../po/../src/helper/units.cpp:46 +msgid "Centimeters" +msgstr "Centimeter" + +#: ../../po/../src/helper/units.cpp:47 +msgid "Meter" +msgstr "meter" + +#: ../../po/../src/helper/units.cpp:47 +msgid "m" +msgstr "m" + +#: ../../po/../src/helper/units.cpp:47 +#, fuzzy +msgid "Meters" +msgstr "meter" + +#. no svg_unit +#: ../../po/../src/helper/units.cpp:48 +msgid "Inch" +msgstr "Tum" + +#: ../../po/../src/helper/units.cpp:48 +msgid "in" +msgstr "tum" + +#: ../../po/../src/helper/units.cpp:48 +msgid "Inches" +msgstr "Tum" + +#. Volatiles do not have default, so there are none here +#. TRANSLATORS: for info, see http://www.w3.org/TR/REC-CSS2/syndata.html#length-units +#: ../../po/../src/helper/units.cpp:51 +msgid "Em square" +msgstr "Emmfyrkant" + +#: ../../po/../src/helper/units.cpp:51 +msgid "em" +msgstr "emm" + +#: ../../po/../src/helper/units.cpp:51 +msgid "Em squares" +msgstr "Emmfyrkanter" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/REC-CSS2/syndata.html#length-units +#: ../../po/../src/helper/units.cpp:53 +msgid "Ex square" +msgstr "exfyrkant" + +#: ../../po/../src/helper/units.cpp:53 +msgid "ex" +msgstr "ex" + +#: ../../po/../src/helper/units.cpp:53 +msgid "Ex squares" +msgstr "exfyrkanter" + +#: ../../po/../src/inkscape.cpp:468 +msgid "Untitled document" +msgstr "Namnlöst dokument" + +#. Show nice dialog box +#: ../../po/../src/inkscape.cpp:497 +#, fuzzy +msgid "Inkscape encountered an internal error and will close now.\n" +msgstr "Sodipodi pÃ¥träffade ett internt fel och kommer nu att stängas.\n" + +#: ../../po/../src/inkscape.cpp:498 +#, fuzzy +msgid "" +"Automatic backups of unsaved documents were done to the following " +"locations:\n" +msgstr "" +"Automatiska säkerhetskopior pÃ¥ osparade dokument gjordes pÃ¥ följande " +"platser:\n" + +#: ../../po/../src/inkscape.cpp:499 +#, fuzzy +msgid "Automatic backup of the following documents failed:\n" +msgstr "Automatisk säkerhetskopiering av följande dokument misslyckades:\n" + +#: ../../po/../src/inkscape.cpp:634 +#, c-format +msgid "" +"Cannot create directory %s.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:635 +#, c-format +msgid "" +"%s is not a valid directory.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:636 +#, c-format +msgid "" +"Cannot create file %s.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:637 +#, c-format +msgid "" +"Cannot write file %s.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:638 +msgid "" +"Although Inkscape will run, it will use default settings,\n" +"and any changes made in preferences will not be saved." +msgstr "" + +#: ../../po/../src/inkscape.cpp:708 +#, c-format +msgid "" +"%s is not a regular file.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:709 +#, c-format +msgid "" +"%s not a valid XML file, or\n" +"you don't have read permissions on it.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:711 +#, c-format +msgid "" +"%s is not a valid menus file.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:712 +msgid "" +"Inkscape will run with default menus.\n" +"New menus will not be saved." +msgstr "" + +#. sp_ui_menu_append_check_item_from_verb(m, view, _("_Menu"), _("Show or hide the menu bar"), "menu", +#. checkitem_toggled, checkitem_update, 0); +#: ../../po/../src/interface.cpp:753 +msgid "Commands Bar" +msgstr "" + +#: ../../po/../src/interface.cpp:753 +#, fuzzy +msgid "Show or hide the Commands bar (under the menu)" +msgstr "Visa hjälplinjer" + +#: ../../po/../src/interface.cpp:755 +#, fuzzy +msgid "Tool Controls" +msgstr "Verktygsalternativ" + +#: ../../po/../src/interface.cpp:755 +#, fuzzy +msgid "Show or hide the Tool Controls panel" +msgstr "Visa hjälplinjer" + +#: ../../po/../src/interface.cpp:757 +msgid "_Toolbox" +msgstr "" + +#: ../../po/../src/interface.cpp:757 +msgid "Show or hide the main toolbox (on the left)" +msgstr "" + +#: ../../po/../src/interface.cpp:763 +msgid "_Statusbar" +msgstr "" + +#: ../../po/../src/interface.cpp:763 +msgid "Show or hide the statusbar (at the bottom of the window)" +msgstr "" + +#: ../../po/../src/interface.cpp:820 +#, c-format +msgid "Verb \"%s\" Unknown" +msgstr "" + +#. TRANSLATORS: #%s is the id of the group e.g. , not a number. +#: ../../po/../src/interface.cpp:930 +#, fuzzy, c-format +msgid "Enter group #%s" +msgstr "Redigera noder" + +#: ../../po/../src/interface.cpp:941 +#, fuzzy +msgid "Go to parent" +msgstr "Zooma till sida" + +#: ../../po/../src/interface.cpp:972 +msgid "Could not parse SVG data" +msgstr "" + +#: ../../po/../src/interface.cpp:1135 +#, c-format +msgid "Overwrite %s" +msgstr "Skrivöver %s" + +#: ../../po/../src/interface.cpp:1153 +#, c-format +msgid "" +"The file %s already exists. Do you want to overwrite that file with the " +"current document?" +msgstr "" +"Filen %s finns redan. Vill du skriva över den med det aktuella dokumentet?" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:59 +msgid "Jabber connection lost." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:72 +#, c-format +msgid "Sending message; %u message remaining in send queue." +msgid_plural "Sending message; %u messages remaining in send queue." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:78 +msgid "Receive queue empty." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:154 +#, c-format +msgid "Receiving change; %u change left to process." +msgid_plural "Receiving change; %u changes left to process." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:157 +#, c-format +msgid "%s has left the chatroom." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:221 +msgid "Nickname %1 is already in use. Please choose a different nickname." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:225 +msgid "An error was encountered while attempting to connect to the server." +msgstr "" + +#. Check to see if the user made any modifications to this document. If so, +#. we want to give them the option of (1) letting us clear their document or (2) +#. opening a new, blank document for the whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:131 +msgid "%1 has invited you to a whiteboard session." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:132 +msgid "Incoming whiteboard invitation from %1" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:135 +msgid "Do you wish to accept %1's whiteboard session invitation?" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:137 +msgid "" +"Would you like to accept %1's invitation in a new document window?\n" +"Accepting the invitation in your current window will discard unsaved changes." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:143 +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:198 +#, fuzzy +msgid "Accept invitation" +msgstr "Markering" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:144 +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:199 +msgid "Decline invitation" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:145 +#, fuzzy +msgid "Accept invitation in new document window" +msgstr "Skapa nytt dokument" + +#. We could not create a new desktop; ask the user if she or he wants to +#. replace the current document and accept the invitation, or reject the invitation. +#. TRANSLATORS: %1 is a userid here +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:196 +msgid "" +"A new document window could not be opened for a whiteboard session with %" +"1" +msgstr "" + +#. TRANSLATORS: %1 is the peer whom refused our invitation. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:238 +msgid "" +"The user %1 has refused your " +"whiteboard invitation.\n" +"\n" +msgstr "" + +#. TRANSLATORS: %1 is the peer whom refused our invitation, %2 is our Jabber identity. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:241 +msgid "" +"You are still connected to a Jabber server as %2, and may send an " +"invitation to %1 again, or you may send an invitation to a different " +"user." +msgstr "" + +#. TRANSLATORS: %1 is the peer whom we tried to contact, but is already in a whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:252 +msgid "" +"The user %1 is already in a " +"whiteboard session.\n" +"\n" +msgstr "" + +#. TRANSLATORS: %1 is the peer whom we tried to contact, but is already in a whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:255 +msgid "" +"You are still connected to a Jabber server as %1, and may send an " +"invitation to a different user." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/invitation-confirm-dialog.cpp:26 +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:24 +msgid "_Write session file:" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/message-processors.cpp:145 +#, c-format +msgid "%s has joined the chatroom." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/message-queue.cpp:87 +#, c-format +msgid "%u change in receive queue." +msgid_plural "%u changes in receive queue." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/jabber_whiteboard/message-queue.cpp:117 +#, c-format +msgid "%u change in send queue." +msgid_plural "%u changes in send queue." +msgstr[0] "" +msgstr[1] "" + +#. if ID is NULL, then we have a real problem -- we were not able to find a key +#. nor generate one. The only thing we can really do here is abort, since we have +#. no way to let the other client(s) uniquely identify this object. +#. FIXME: If this indicates a programming bug, then don't request translation with +#. * _(...): it is most useful in untranslated form so that developers may search for +#. * it when someone reports it in a bug report (as we want users to do for all bugs, +#. * as indicated by it being a g_warning string). +#. * +#. * Otherwise, if it is not a programming bug but a network error or a bug in the +#. * remote peer (perhaps running different software) or whatever, then present it in +#. * an alert box, and avoid use of technical jargon `NULL'. +#. +#: ../../po/../src/jabber_whiteboard/message-utilities.cpp:171 +msgid "" +"ID for new object is NULL even after generation and lookup attempts: the new " +"object will NOT be sent, nor will any of its child objects!" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:60 +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:995 +msgid "Select a location and filename" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:62 +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:997 +#, fuzzy +msgid "Set filename" +msgstr "Namn pÃ¥ png-fil" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:301 +msgid "No SSL certificate was found." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:304 +msgid "The SSL certificate provided by the Jabber server is untrusted." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:307 +msgid "The SSL certificate provided by the Jabber server is expired." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:310 +msgid "" +"The SSL certificate provided by the Jabber server has not been activated." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:313 +msgid "" +"The SSL certificate provided by the Jabber server contains a hostname that " +"does not match the Jabber server's hostname." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:316 +msgid "" +"The SSL certificate provided by the Jabber server contains an invalid " +"fingerprint." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:319 +msgid "An unknown error occurred while setting up the SSL connection." +msgstr "" + +#. TRANSLATORS: %1 is the message that describes the specific error that occurred when +#. establishing the SSL connection. +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:325 +msgid "" +"%1\n" +"\n" +"Do you wish to continue connecting to the Jabber server?" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:328 +msgid "Continue connecting and ignore further errors" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:329 +msgid "Continue connecting, but warn me of further errors" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:330 +#, fuzzy +msgid "Cancel connection" +msgstr "Markering" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:777 +#, c-format +msgid "Established whiteboard session with %s." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:785 +#, c-format +msgid "%s has left the whiteboard session." +msgstr "" + +#. Inform the user +#. TRANSLATORS: %1 is the name of the user that disconnected, %2 is the name of the user whom the disconnected user disconnected from. +#. This message is not used in a chatroom context. +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:790 +msgid "" +"The user %1 has left the " +"whiteboard session.\n" +"\n" +msgstr "" + +#. TRANSLATORS: %1 and %2 are userids +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:792 +msgid "" +"You are still connected to a Jabber server as %2, and may establish a " +"new session to %1 or a different user." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:988 +msgid "" +"Could not open file %1 for session recording.\n" +"The error encountered was: %2.\n" +"\n" +"You may select a different location to record the session, or you may opt to " +"not record this session." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:990 +msgid "Choose a different location" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:991 +msgid "Skip session recording" +msgstr "" + +#: ../../po/../src/knot.cpp:673 +msgid "Node or handle drag canceled." +msgstr "" + +#: ../../po/../src/libnrtype/FontFactory.cpp:358 +msgid "Ignoring font without family that will crash Pango" +msgstr "" + +#: ../../po/../src/main.cpp:395 +msgid "Print the Inkscape version number" +msgstr "" + +#: ../../po/../src/main.cpp:400 +msgid "Do not use X server (only process files from console)" +msgstr "Använd inte X-server (behandla endast filer frÃ¥n konsollen)" + +#: ../../po/../src/main.cpp:405 +#, fuzzy +msgid "Try to use X server (even if $DISPLAY is not set)" +msgstr "Försök att använda X-server även om $DISPLAY inte är inställd)" + +#: ../../po/../src/main.cpp:410 +msgid "Open specified document(s) (option string may be excluded)" +msgstr "Öppna angivna dokument (flaggsträng kan utelämnas)" + +#: ../../po/../src/main.cpp:411 ../../po/../src/main.cpp:416 +#: ../../po/../src/main.cpp:421 ../../po/../src/main.cpp:483 +#: ../../po/../src/main.cpp:488 ../../po/../src/main.cpp:493 +msgid "FILENAME" +msgstr "FILNAMN" + +#: ../../po/../src/main.cpp:415 +msgid "Print document(s) to specified output file (use '| program' for pipe)" +msgstr "" +"Skriv ut dokument till angiven utdatafil (använd \"| program\" för rör)" + +#: ../../po/../src/main.cpp:420 +msgid "Export document to a PNG file" +msgstr "Exportera dokument till en PNG-fil" + +#: ../../po/../src/main.cpp:425 +#, fuzzy +msgid "The resolution used for exporting SVG into bitmap (default 90)" +msgstr "" +"Upplösningen som används för konvertering av SVG till bitmappsbild " +"(standardvärde 72,0)" + +#: ../../po/../src/main.cpp:426 +msgid "DPI" +msgstr "DPI" + +#: ../../po/../src/main.cpp:430 +#, fuzzy +msgid "" +"Exported area in SVG user units (default is the canvas; 0,0 is lower-left " +"corner)" +msgstr "" +"Exporterad area i millimeter (standard är hela dokumentet, 0,0 är nedre " +"vänstra hörnet)" + +#: ../../po/../src/main.cpp:431 +msgid "x0:y0:x1:y1" +msgstr "x0:y0:x1:y1" + +#: ../../po/../src/main.cpp:435 +msgid "Exported area is the entire drawing (not canvas)" +msgstr "" + +#: ../../po/../src/main.cpp:440 +msgid "" +"Snap the bitmap export area outwards to the nearest integer values (in SVG " +"user units)" +msgstr "" + +#: ../../po/../src/main.cpp:445 +#, fuzzy +msgid "The width of exported bitmap in pixels (overrides export-dpi)" +msgstr "" +"Bredden pÃ¥ den genererade bimappsbilden i bildpunkter (Ã¥sidosätter dpi)" + +#: ../../po/../src/main.cpp:446 +msgid "WIDTH" +msgstr "BREDD" + +#: ../../po/../src/main.cpp:450 +#, fuzzy +msgid "The height of exported bitmap in pixels (overrides export-dpi)" +msgstr "Höjden pÃ¥ den genererade bimappsbilden i bildpunkter (Ã¥sidosätter dpi)" + +#: ../../po/../src/main.cpp:451 +msgid "HEIGHT" +msgstr "HÖJD" + +#: ../../po/../src/main.cpp:455 +#, fuzzy +msgid "The ID of the object to export (overrides export-area)" +msgstr "" +"Bredden pÃ¥ den genererade bimappsbilden i bildpunkter (Ã¥sidosätter dpi)" + +#: ../../po/../src/main.cpp:456 ../../po/../src/main.cpp:532 +#, fuzzy +msgid "ID" +msgstr "ID:" + +#. TRANSLATORS: this means: "Only export the object whose id is given in --export-id". +#. See "man inkscape" for details. +#: ../../po/../src/main.cpp:462 +msgid "" +"Export just the object with export-id, hide all others (only with export-id)" +msgstr "" + +#: ../../po/../src/main.cpp:467 +msgid "Use stored filename and DPI hints when exporting (only with export-id)" +msgstr "" + +#: ../../po/../src/main.cpp:472 +#, fuzzy +msgid "Background color of exported bitmap (any SVG-supported color string)" +msgstr "" +"Bakgrundsfärg för den exporterade bitmappsbilden (godtycklig färgsträng som " +"stöds av SVG)" + +#: ../../po/../src/main.cpp:473 +msgid "COLOR" +msgstr "FÄRG" + +#: ../../po/../src/main.cpp:477 +#, fuzzy +msgid "Background opacity of exported bitmap (either 0.0 to 1.0, or 1 to 255)" +msgstr "" +"Bakgrundsfärg för den exporterade bitmappsbilden (godtycklig färgsträng som " +"stöds av SVG)" + +#: ../../po/../src/main.cpp:478 +msgid "VALUE" +msgstr "" + +#: ../../po/../src/main.cpp:482 +#, fuzzy +msgid "Export document to plain SVG file (no sodipodi or inkscape namespaces)" +msgstr "" +"Exportera dokument till vanlig SVG-fil (inget \"xmlns:sodipodi\"-namnutrymme)" + +#: ../../po/../src/main.cpp:487 +#, fuzzy +msgid "Export document to a PS file" +msgstr "Exportera dokument till png-fil" + +#: ../../po/../src/main.cpp:492 +#, fuzzy +msgid "Export document to an EPS file" +msgstr "Exportera dokument till png-fil" + +#: ../../po/../src/main.cpp:497 +#, fuzzy +msgid "Convert text object to paths on export (EPS)" +msgstr "Konvertera markerat objekt till slinga" + +#: ../../po/../src/main.cpp:502 +msgid "Export files with the bounding box set to the page size (EPS)" +msgstr "" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:508 +msgid "" +"Query the X coordinate of the drawing or, if specified, of the object with --" +"query-id" +msgstr "" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:514 +msgid "" +"Query the Y coordinate of the drawing or, if specified, of the object with --" +"query-id" +msgstr "" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:520 +msgid "" +"Query the width of the drawing or, if specified, of the object with --query-" +"id" +msgstr "" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:526 +msgid "" +"Query the height of the drawing or, if specified, of the object with --query-" +"id" +msgstr "" + +#: ../../po/../src/main.cpp:531 +#, fuzzy +msgid "The ID of the object whose dimensions are queried" +msgstr "" +"Bredden pÃ¥ den genererade bimappsbilden i bildpunkter (Ã¥sidosätter dpi)" + +#. TRANSLATORS: this option makes Inkscape print the name (path) of the extension directory +#: ../../po/../src/main.cpp:537 +msgid "Print out the extension directory and exit" +msgstr "" + +#: ../../po/../src/main.cpp:542 +msgid "Show given files one-by-one, switch to next on any key/mouse event" +msgstr "" +"Visa angivna filer en och en, byt till nästa vid nÃ¥gon tangent- eller " +"mushändelse" + +#: ../../po/../src/main.cpp:547 +msgid "Use the new Gtkmm GUI interface" +msgstr "" + +#: ../../po/../src/main.cpp:552 +msgid "Remove unused definitions from the defs section(s) of the document" +msgstr "" + +#: ../../po/../src/main.cpp:741 +msgid "" +"[OPTIONS...] [FILE...]\n" +"\n" +"Available options:" +msgstr "" + +#: ../../po/../src/menus-skeleton.h:17 +msgid "_New" +msgstr "_Ny" + +#: ../../po/../src/menus-skeleton.h:22 +#, fuzzy +msgid "Open _Recent" +msgstr "Öppna" + +#: ../../po/../src/menus-skeleton.h:53 +msgid "_Edit" +msgstr "_Redigera" + +#: ../../po/../src/menus-skeleton.h:84 +msgid "_View" +msgstr "_Visa" + +#: ../../po/../src/menus-skeleton.h:85 +#, fuzzy +msgid "_Zoom" +msgstr "Zooma" + +#: ../../po/../src/menus-skeleton.h:102 +#, fuzzy +msgid "Show/Hide" +msgstr "Visa hjälplinjer" + +#: ../../po/../src/menus-skeleton.h:107 +#, fuzzy +msgid "_Display mode" +msgstr "Visning" + +#: ../../po/../src/menus-skeleton.h:126 +msgid "_Layer" +msgstr "_Lager" + +#: ../../po/../src/menus-skeleton.h:143 +msgid "_Object" +msgstr "_Objekt" + +#: ../../po/../src/menus-skeleton.h:165 +#, fuzzy +msgid "_Path" +msgstr "Klistra _in" + +#: ../../po/../src/menus-skeleton.h:188 +msgid "_Text" +msgstr "_Text" + +#: ../../po/../src/menus-skeleton.h:200 +#, fuzzy +msgid "Effects" +msgstr "Objekt" + +#: ../../po/../src/menus-skeleton.h:207 +msgid "Whiteboa_rd" +msgstr "" + +#: ../../po/../src/menus-skeleton.h:220 +msgid "_Help" +msgstr "_Hjälp" + +#: ../../po/../src/menus-skeleton.h:222 +msgid "Tutorials" +msgstr "" + +#: ../../po/../src/node-context.cpp:382 +msgid "" +"Ctrl: toggle node type, snap handle angle, move hor/vert; Ctrl" +"+Alt: move along handles" +msgstr "" + +#: ../../po/../src/node-context.cpp:383 +msgid "" +"Shift: toggle node selection, disable snapping, rotate both handles" +msgstr "" + +#: ../../po/../src/node-context.cpp:384 +msgid "Alt: lock handle length; Ctrl+Alt: move along handles" +msgstr "" + +#: ../../po/../src/nodepath.cpp:1399 ../../po/../src/nodepath.cpp:1411 +#: ../../po/../src/nodepath.cpp:1492 ../../po/../src/nodepath.cpp:1504 +msgid "To join, you must have two endnodes selected." +msgstr "" + +#: ../../po/../src/nodepath.cpp:1633 ../../po/../src/nodepath.cpp:1647 +msgid "" +"Select two non-endpoint nodes on a path between which to delete " +"segments." +msgstr "" + +#: ../../po/../src/nodepath.cpp:1743 +#, fuzzy +msgid "Cannot find path between nodes." +msgstr "Anslut linjer vid markerade noder" + +#: ../../po/../src/nodepath.cpp:2822 +#, c-format +msgid "" +"Node handle: angle %0.2f°, length %s; with Ctrl to snap " +"angle; with Alt to lock length; with Shift to rotate both " +"handles" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3351 +msgid "" +"Node: drag to edit the path; with Ctrl to snap to horizontal/" +"vertical; with Ctrl+Alt to snap to handles' directions" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3375 +msgid "" +"Node handle: drag to shape the curve; with Ctrl to snap angle; " +"with Alt to lock length; with Shift to rotate both handles" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3399 +msgid "" +"Node handle: drag to shape the curve; with Ctrl to snap angle; " +"with Alt to lock length; with Shift to rotate the opposite " +"handle in sync" +msgstr "" + +#. TRANSLATORS: "end" is an adjective here (NOT a verb) +#: ../../po/../src/nodepath.cpp:3591 +#, fuzzy +msgid "end node" +msgstr "Dra in nod" + +#. TRANSLATORS: "cusp" means "sharp" (cusp node); see also the Advanced Tutorial +#: ../../po/../src/nodepath.cpp:3596 +#, fuzzy +msgid "cusp" +msgstr "anvkoord" + +#. TRANSLATORS: "smooth" is an adjective here +#: ../../po/../src/nodepath.cpp:3599 +msgid "smooth" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3601 +#, fuzzy +msgid "symmetric" +msgstr "Osymmetrisk" + +#. TRANSLATORS: "end" is an adjective here (NOT a verb) +#: ../../po/../src/nodepath.cpp:3607 +msgid "end node, handle retracted (drag with Shift to extend)" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3609 +msgid "one handle retracted (drag with Shift to extend)" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3612 +msgid "both handles retracted (drag with Shift to extend)" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3624 +#, fuzzy +msgid "Drag nodes or node handles; arrow keys to move nodes" +msgstr "Skapar ny kurva. Tryck \"a\" för att växla Lägg till/Ny." + +#: ../../po/../src/nodepath.cpp:3625 +#, fuzzy +msgid "Drag the node or its handles; arrow keys to move the node" +msgstr "Skapar ny kurva. Tryck \"a\" för att växla Lägg till/Ny." + +#: ../../po/../src/nodepath.cpp:3651 ../../po/../src/nodepath.cpp:3663 +#, fuzzy +msgid "Select a single object to edit its nodes or handles." +msgstr "Markera alla objekt i dokumentet" + +#: ../../po/../src/nodepath.cpp:3655 +#, c-format +msgid "" +"0 out of %i node selected. Click, Shift+click, " +"or drag around nodes to select." +msgid_plural "" +"0 out of %i nodes selected. Click, Shift+click, " +"or drag around nodes to select." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/nodepath.cpp:3661 +msgid "Drag the handles of the object to modify it." +msgstr "" + +#: ../../po/../src/nodepath.cpp:3669 +#, fuzzy, c-format +msgid "%i of %i node selected; %s. %s." +msgid_plural "%i of %i nodes selected; %s. %s." +msgstr[0] "Anslut linjer vid markerade noder" +msgstr[1] "Anslut linjer vid markerade noder" + +#: ../../po/../src/nodepath.cpp:3675 +#, fuzzy, c-format +msgid "%i of %i node selected. %s." +msgid_plural "%i of %i nodes selected. %s." +msgstr[0] "Anslut linjer vid markerade noder" +msgstr[1] "Anslut linjer vid markerade noder" + +#: ../../po/../src/object-edit.cpp:493 +msgid "" +"Adjust the horizontal rounding radius; with Ctrl to make the " +"vertical radius the same" +msgstr "" + +#: ../../po/../src/object-edit.cpp:499 +msgid "" +"Adjust the vertical rounding radius; with Ctrl to make the " +"horizontal radius the same" +msgstr "" + +#: ../../po/../src/object-edit.cpp:506 ../../po/../src/object-edit.cpp:513 +msgid "" +"Adjust the width and height of the rectangle; with Ctrl to " +"lock ratio or stretch in one dimension only" +msgstr "" + +#: ../../po/../src/object-edit.cpp:686 +msgid "Adjust ellipse width, with Ctrl to make circle" +msgstr "" + +#: ../../po/../src/object-edit.cpp:689 +msgid "Adjust ellipse height, with Ctrl to make circle" +msgstr "" + +#: ../../po/../src/object-edit.cpp:692 +msgid "" +"Position the start point of the arc or segment; with Ctrl to " +"snap angle; drag inside the ellipse for arc, outside for " +"segment" +msgstr "" + +#: ../../po/../src/object-edit.cpp:695 +msgid "" +"Position the end point of the arc or segment; with Ctrl to " +"snap angle; drag inside the ellipse for arc, outside for " +"segment" +msgstr "" + +#: ../../po/../src/object-edit.cpp:800 +msgid "" +"Adjust the tip radius of the star or polygon; with Shift to " +"round; with Alt to randomize" +msgstr "" + +#: ../../po/../src/object-edit.cpp:803 +msgid "" +"Adjust the base radius of the star; with Ctrl to keep star " +"rays radial (no skew); with Shift to round; with Alt to " +"randomize" +msgstr "" + +#: ../../po/../src/object-edit.cpp:967 +msgid "" +"Roll/unroll the spiral from inside; with Ctrl to snap angle; " +"with Alt to converge/diverge" +msgstr "" + +#: ../../po/../src/object-edit.cpp:969 +msgid "" +"Roll/unroll the spiral from outside; with Ctrl to snap angle; " +"with Shift to scale/rotate" +msgstr "" + +#: ../../po/../src/object-edit.cpp:1006 +msgid "Adjust the offset distance" +msgstr "" + +#. TRANSLATORS: This refers to the pattern that's inside the object +#: ../../po/../src/object-edit.cpp:1036 +msgid "Move the pattern fill inside the object" +msgstr "" + +#: ../../po/../src/object-edit.cpp:1038 +#, fuzzy +msgid "Scale the pattern fill uniformly" +msgstr "Klipp ut markerade objekt till urklipp" + +#: ../../po/../src/object-edit.cpp:1040 +msgid "Rotate the pattern fill; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/object-edit.cpp:1065 +msgid "Drag to resize the flowed text frame" +msgstr "" + +#. Item dialog +#: ../../po/../src/object-ui.cpp:106 +msgid "Object _Properties" +msgstr "Objektegenskaper" + +#. Select item +#: ../../po/../src/object-ui.cpp:116 +msgid "_Select This" +msgstr "Markera detta" + +#. Create link +#: ../../po/../src/object-ui.cpp:126 +msgid "_Create Link" +msgstr "Skapa länk" + +#. "Ungroup" +#: ../../po/../src/object-ui.cpp:199 ../../po/../src/verbs.cpp:1931 +msgid "_Ungroup" +msgstr "_Avgruppera" + +#. Link dialog +#: ../../po/../src/object-ui.cpp:239 +msgid "Link _Properties" +msgstr "Länkegenskaper" + +#. Select item +#: ../../po/../src/object-ui.cpp:249 +msgid "_Follow Link" +msgstr "Följ länk" + +#. Reset transformations +#: ../../po/../src/object-ui.cpp:254 +msgid "_Remove Link" +msgstr "Ta bort länk" + +#. Link dialog +#: ../../po/../src/object-ui.cpp:303 +msgid "Image _Properties" +msgstr "Bildegenskaper" + +#. Item dialog +#: ../../po/../src/object-ui.cpp:344 +#, fuzzy +msgid "_Fill and Stroke" +msgstr "Fyllning och genomstrykning" + +#: ../../po/../src/path-chemistry.cpp:58 +msgid "Select at least two objects to combine." +msgstr "" + +#: ../../po/../src/path-chemistry.cpp:65 +#, fuzzy +msgid "At least one of the objects is not a path, cannot combine." +msgstr "Konvertera markerat objekt till slinga" + +#: ../../po/../src/path-chemistry.cpp:73 +msgid "" +"You cannot combine objects from different groups or layers." +msgstr "" + +#: ../../po/../src/path-chemistry.cpp:155 +#, fuzzy +msgid "Select path(s) to break apart." +msgstr "Klipp ut markerade objekt till urklipp" + +#: ../../po/../src/path-chemistry.cpp:231 +msgid "No path(s) to break apart in the selection." +msgstr "" + +#: ../../po/../src/path-chemistry.cpp:252 +#, fuzzy +msgid "Select object(s) to convert to path." +msgstr "Klipp ut markerade objekt till urklipp" + +#: ../../po/../src/path-chemistry.cpp:297 +#, fuzzy +msgid "No objects to convert to path in the selection." +msgstr "Klipp ut markerade objekt till urklipp" + +#: ../../po/../src/path-chemistry.cpp:345 +#, fuzzy +msgid "Select path(s) to reverse." +msgstr "Höj markerade objekt överst" + +#: ../../po/../src/path-chemistry.cpp:370 +msgid "No paths to reverse in the selection." +msgstr "" + +#: ../../po/../src/pen-context.cpp:379 ../../po/../src/pencil-context.cpp:233 +#, fuzzy +msgid "Continuing selected path" +msgstr "SlÃ¥ samman markerade slingor" + +#: ../../po/../src/pen-context.cpp:390 ../../po/../src/pencil-context.cpp:242 +#, fuzzy +msgid "Creating new path" +msgstr "Skapa nytt SVG-dokument" + +#: ../../po/../src/pen-context.cpp:394 ../../po/../src/pencil-context.cpp:246 +#, fuzzy +msgid "Appending to selected path" +msgstr "Zooma till markering" + +#: ../../po/../src/pen-context.cpp:538 +msgid "Click or click and drag to close and finish the path." +msgstr "" + +#: ../../po/../src/pen-context.cpp:548 +msgid "" +"Click or click and drag to continue the path from this point." +msgstr "" + +#: ../../po/../src/pen-context.cpp:857 +#, c-format +msgid "" +"%s: angle %3.2f°, distance %s; with Ctrl to snap angle, " +"Enter to finish the path" +msgstr "" + +#: ../../po/../src/pen-context.cpp:882 +#, c-format +msgid "" +"Curve handle: angle %3.2f°, length %s; with Ctrl to snap " +"angle" +msgstr "" + +#: ../../po/../src/pen-context.cpp:912 +#, c-format +msgid "" +"%s: angle %3.2f°, length %s; with Ctrl to snap angle, " +"with Shift to move this handle only" +msgstr "" + +#: ../../po/../src/pen-context.cpp:946 +#, fuzzy +msgid "Finishing pen" +msgstr "Frihand" + +#: ../../po/../src/pencil-context.cpp:320 +msgid "Release here to close and finish the path." +msgstr "" + +#: ../../po/../src/pencil-context.cpp:326 +#, fuzzy +msgid "Drawing a freehand path" +msgstr "Rita frihand-linje" + +#: ../../po/../src/pencil-context.cpp:331 +msgid "Drag to continue the path from this point." +msgstr "" + +#. Write curves to object +#: ../../po/../src/pencil-context.cpp:390 +#, fuzzy +msgid "Finishing freehand" +msgstr "Frihand" + +#: ../../po/../src/rect-context.cpp:387 +msgid "" +"Ctrl: make square or integer-ratio rect, lock a rounded corner " +"circular" +msgstr "" + +#: ../../po/../src/rect-context.cpp:549 +#, c-format +msgid "" +"Rectangle: %s × %s; with Ctrl to make square or integer-" +"ratio rectangle; with Shift to draw around the starting point" +msgstr "" + +#: ../../po/../src/select-context.cpp:243 +#, fuzzy +msgid "Move canceled." +msgstr "Avbröt flytt" + +#: ../../po/../src/select-context.cpp:252 +msgid "Selection canceled." +msgstr "Markering avbruten." + +#: ../../po/../src/select-context.cpp:642 +msgid "Ctrl: select in groups, move hor/vert" +msgstr "" + +#: ../../po/../src/select-context.cpp:643 +msgid "Shift: toggle select, force rubberband, disable snapping" +msgstr "" + +#: ../../po/../src/select-context.cpp:644 +msgid "Alt: select under, move selected" +msgstr "" + +#: ../../po/../src/select-context.cpp:798 +#, fuzzy +msgid "Selected object is not a group. Cannot enter." +msgstr "Konvertera markerat objekt till slinga" + +#: ../../po/../src/select-context.cpp:876 +#, c-format +msgid "" +"Move by %s, %s; with Ctrl to restrict to horizontal/vertical; " +"with Shift to disable snapping" +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:228 +msgid "Nothing was deleted." +msgstr "Inget blev bort taget." + +#: ../../po/../src/selection-chemistry.cpp:259 +msgid "Select object(s) to duplicate." +msgstr "Markera objekt att dubblera." + +#: ../../po/../src/selection-chemistry.cpp:420 +msgid "Select two or more objects to group." +msgstr "Markera tvÃ¥ eller mer objekt att gruppera" + +#: ../../po/../src/selection-chemistry.cpp:428 +msgid "Select at least two objects to group." +msgstr "Markera minst tvÃ¥ objekt att gruppera." + +#: ../../po/../src/selection-chemistry.cpp:513 +msgid "Select a group to ungroup." +msgstr "Markera en grupp att avgruppera" + +#: ../../po/../src/selection-chemistry.cpp:554 +msgid "No groups to ungroup in the selection." +msgstr "Inga grupper att avgruppera i markeringen." + +#: ../../po/../src/selection-chemistry.cpp:623 +msgid "Select objects to raise." +msgstr "Markera objekt att höja." + +#: ../../po/../src/selection-chemistry.cpp:629 +#: ../../po/../src/selection-chemistry.cpp:681 +#: ../../po/../src/selection-chemistry.cpp:715 +#: ../../po/../src/selection-chemistry.cpp:773 +msgid "" +"You cannot raise/lower objects from different groups or layers." +msgstr "" +"Du kan inte höja/sänka objekt frÃ¥n olika grupper eller lager." + +#: ../../po/../src/selection-chemistry.cpp:673 +msgid "Select object(s) to raise to top." +msgstr "Markera objekt att höja till toppen." + +#: ../../po/../src/selection-chemistry.cpp:709 +msgid "Select object(s) to lower." +msgstr "Markera objekt att sänka." + +#: ../../po/../src/selection-chemistry.cpp:765 +msgid "Select object(s) to lower to bottom." +msgstr "Markera objekt att sänka till botten." + +#: ../../po/../src/selection-chemistry.cpp:806 +msgid "Nothing to undo." +msgstr "Inget att Ã¥ngra." + +#: ../../po/../src/selection-chemistry.cpp:813 +msgid "Nothing to redo." +msgstr "Inget att göra om." + +#: ../../po/../src/selection-chemistry.cpp:969 +msgid "Nothing was copied." +msgstr "Inget blev kopierat." + +#: ../../po/../src/selection-chemistry.cpp:1051 +msgid "Current layer is hidden. Unhide it to be able to paste to it." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1055 +msgid "Current layer is locked. Unlock it to be able to paste to it." +msgstr "" +"Aktuellt lager är lÃ¥st. LÃ¥s upp det för att kunna klistra in till det." + +#: ../../po/../src/selection-chemistry.cpp:1068 +#: ../../po/../src/selection-chemistry.cpp:1103 +msgid "Nothing on the clipboard." +msgstr "Inget i urklipp." + +#: ../../po/../src/selection-chemistry.cpp:1109 +#, fuzzy +msgid "Select object(s) to paste style to." +msgstr "Konvertera markerat objekt till slinga" + +#: ../../po/../src/selection-chemistry.cpp:1128 +msgid "Select object(s) to move to the layer above." +msgstr "Markera objekt att flytta till lagret över." + +#: ../../po/../src/selection-chemistry.cpp:1146 +msgid "No more layers above." +msgstr "Inga mer lager över." + +#: ../../po/../src/selection-chemistry.cpp:1160 +msgid "Select object(s) to move to the layer below." +msgstr "Markera objekt att flytta till lagret under." + +#: ../../po/../src/selection-chemistry.cpp:1178 +msgid "No more layers below." +msgstr "Inga mer lager under." + +#: ../../po/../src/selection-chemistry.cpp:1811 +msgid "Select a clone to unlink." +msgstr "Markera en klon att avlänka." + +#: ../../po/../src/selection-chemistry.cpp:1842 +msgid "No clones to unlink in the selection." +msgstr "Inga kloner att avlänka i markeringen." + +#: ../../po/../src/selection-chemistry.cpp:1859 +msgid "" +"Select a clone to go to its original. Select a linked offset " +"to go to its source. Select a text on path to go to the path. Select " +"a flowed text to go to its frame." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1882 +msgid "" +"Cannot find the object to select (orphaned clone, offset, textpath, " +"flowed text?)" +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1888 +msgid "" +"The object you're trying to select is not visible (it is in <" +"defs>)" +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1915 +#, fuzzy +msgid "Select object(s) to convert to pattern." +msgstr "Klipp ut markerade objekt till urklipp" + +#: ../../po/../src/selection-chemistry.cpp:2006 +#, fuzzy +msgid "Select an object with pattern fill to extract objects from." +msgstr "Klipp ut markerade objekt till urklipp" + +#: ../../po/../src/selection-chemistry.cpp:2059 +#, fuzzy +msgid "No pattern fills in the selection." +msgstr "Klipp ut markerade objekt till urklipp" + +#: ../../po/../src/selection-chemistry.cpp:2079 +#, fuzzy +msgid "Select object(s) to make a bitmap copy." +msgstr "Konvertera markerat objekt till slinga" + +#: ../../po/../src/selection-describer.cpp:37 +msgid "Click selection to toggle scale/rotation handles" +msgstr "" + +#. no items +#: ../../po/../src/selection-describer.cpp:39 +msgid "" +"No objects selected. Click, Shift+click, or drag around objects to select." +msgstr "" + +#: ../../po/../src/selection-describer.cpp:51 +#, fuzzy, c-format +msgid " in layer %s" +msgstr "Höj nod" + +#: ../../po/../src/selection-describer.cpp:54 +#, fuzzy, c-format +msgid " in layer %s" +msgstr "Höj nod" + +#: ../../po/../src/selection-describer.cpp:66 +msgid "Use Shift+D to look up original" +msgstr "" + +#: ../../po/../src/selection-describer.cpp:70 +msgid "Use Shift+D to look up path" +msgstr "" + +#: ../../po/../src/selection-describer.cpp:74 +msgid "Use Shift+D to look up frame" +msgstr "" + +#: ../../po/../src/selection-describer.cpp:84 +#, fuzzy, c-format +msgid "%i object selected" +msgid_plural "%i objects selected" +msgstr[0] "%i markerade objekt" +msgstr[1] "%i markerade objekt" + +#: ../../po/../src/selection-describer.cpp:90 +#, c-format +msgid "%s%s. %s." +msgstr "" + +#: ../../po/../src/selection-describer.cpp:94 +#, fuzzy, c-format +msgid "%s in %i layer. %s." +msgid_plural "%s in %i layers. %s." +msgstr[0] "Anslut linjer vid markerade noder" +msgstr[1] "Anslut linjer vid markerade noder" + +#: ../../po/../src/seltrans.cpp:498 +msgid "" +"Center of rotation and skewing: drag to reposition; scaling with " +"Shift also uses this center" +msgstr "" + +#: ../../po/../src/seltrans.cpp:514 +msgid "" +"Squeeze or stretch selection; with Ctrl to scale uniformly; " +"with Shift to scale around rotation center" +msgstr "" + +#: ../../po/../src/seltrans.cpp:515 +msgid "" +"Scale selection; with Ctrl to scale uniformly; with Shift to scale around rotation center" +msgstr "" + +#: ../../po/../src/seltrans.cpp:519 +msgid "" +"Skew selection; with Ctrl to snap angle; with Shift to " +"skew around the opposite side" +msgstr "" + +#: ../../po/../src/seltrans.cpp:520 +msgid "" +"Rotate selection; with Ctrl to snap angle; with Shift " +"to rotate around the opposite corner" +msgstr "" + +#: ../../po/../src/seltrans.cpp:829 ../../po/../src/seltrans.cpp:909 +#, c-format +msgid "Scale: %0.2f%% x %0.2f%%; with Ctrl to lock ratio" +msgstr "" + +#. TRANSLATORS: don't modify the first ";" (it will NOT be displayed as ";" - only the second one will be) +#: ../../po/../src/seltrans.cpp:984 +#, c-format +msgid "Skew: %0.2f°; with Ctrl to snap angle" +msgstr "" + +#. TRANSLATORS: don't modify the first ";" (it will NOT be displayed as ";" - only the second one will be) +#: ../../po/../src/seltrans.cpp:1035 +#, c-format +msgid "Rotate: %0.2f°; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/seltrans.cpp:1090 +#, fuzzy, c-format +msgid "Move center to %s, %s" +msgstr "Länk till %s" + +#: ../../po/../src/slideshow.cpp:90 +#, fuzzy +msgid "Inkscape slideshow" +msgstr "Sodipodi-bildspel" + +#: ../../po/../src/sp-anchor.cpp:181 +#, c-format +msgid "Link to %s" +msgstr "Länk till %s" + +#: ../../po/../src/sp-anchor.cpp:185 +msgid "Link without URI" +msgstr "Länk utan URI" + +#: ../../po/../src/sp-ellipse.cpp:438 ../../po/../src/sp-ellipse.cpp:870 +#, fuzzy +msgid "Ellipse" +msgstr "Ellips" + +#: ../../po/../src/sp-ellipse.cpp:583 +#, fuzzy +msgid "Circle" +msgstr "Ändra" + +#: ../../po/../src/sp-ellipse.cpp:865 +#, fuzzy +msgid "Segment" +msgstr "Ändra" + +#: ../../po/../src/sp-ellipse.cpp:867 +msgid "Arc" +msgstr "" + +#. TRANSLATORS: "Flow region" is an area where text is allowed to flow +#: ../../po/../src/sp-flowregion.cpp:276 +#, fuzzy +msgid "Flow region" +msgstr "Följ länk" + +#. TRANSLATORS: A region "cut out of" a flow region; text is not allowed to flow inside the +#. * flow excluded region. flowRegionExclude in SVG 1.2: see +#. * http://www.w3.org/TR/2004/WD-SVG12-20041027/flow.html#flowRegion-elem and +#. * http://www.w3.org/TR/2004/WD-SVG12-20041027/flow.html#flowRegionExclude-elem. +#: ../../po/../src/sp-flowregion.cpp:493 +msgid "Flow excluded region" +msgstr "" + +#: ../../po/../src/sp-flowtext.cpp:355 +#, c-format +msgid "Flowed text (%d characters)" +msgstr "" + +#: ../../po/../src/sp-flowtext.cpp:357 +#, c-format +msgid "Linked flowed text (%d characters)" +msgstr "" + +#: ../../po/../src/sp-guide.cpp:290 +#, fuzzy +msgid "vertical guideline" +msgstr "Vertikalt mittpunktsvärde" + +#: ../../po/../src/sp-guide.cpp:292 +#, fuzzy +msgid "horizontal guideline" +msgstr "horisontell flytt" + +#: ../../po/../src/sp-image.cpp:835 +msgid "embedded" +msgstr "" + +#: ../../po/../src/sp-image.cpp:839 +msgid "(null_pointer)" +msgstr "" + +#: ../../po/../src/sp-image.cpp:843 +#, c-format +msgid "Image with bad reference: %s" +msgstr "Bild med felaktig referens: %s" + +#: ../../po/../src/sp-image.cpp:844 +#, fuzzy, c-format +msgid "Image %d × %d: %s" +msgstr "Färgbild %d × %d: %s" + +#: ../../po/../src/sp-item-group.cpp:390 +#, fuzzy, c-format +msgid "Group of %d object" +msgid_plural "Group of %d objects" +msgstr[0] "Grupp med %d objekt" +msgstr[1] "Grupp med %d objekt" + +#: ../../po/../src/sp-item.cpp:720 +msgid "Object" +msgstr "Objekt" + +#: ../../po/../src/sp-line.cpp:202 +#, fuzzy +msgid "Line" +msgstr "Ändra" + +#. TRANSLATORS COMMENT: %s is either "outset" or "inset" depending on sign +#: ../../po/../src/sp-offset.cpp:433 +#, c-format +msgid "Linked offset, %s by %f pt" +msgstr "" + +#: ../../po/../src/sp-offset.cpp:434 ../../po/../src/sp-offset.cpp:438 +#, fuzzy +msgid "outset" +msgstr "SlÃ¥ samman markerade slingor" + +#: ../../po/../src/sp-offset.cpp:434 ../../po/../src/sp-offset.cpp:438 +#, fuzzy +msgid "inset" +msgstr "tum" + +#. TRANSLATORS COMMENT: %s is either "outset" or "inset" depending on sign +#: ../../po/../src/sp-offset.cpp:437 +#, c-format +msgid "Dynamic offset, %s by %f pt" +msgstr "" + +#: ../../po/../src/sp-path.cpp:127 +#, fuzzy, c-format +msgid "Path (%i node)" +msgid_plural "Path (%i nodes)" +msgstr[0] "Länk till %s" +msgstr[1] "Länk till %s" + +#: ../../po/../src/sp-polygon.cpp:216 +#, fuzzy +msgid "Polygon" +msgstr "Ändra" + +#: ../../po/../src/sp-polyline.cpp:179 +#, fuzzy +msgid "Polyline" +msgstr "Ellips" + +#: ../../po/../src/sp-rect.cpp:250 +#, fuzzy +msgid "Rectangle" +msgstr "Ändra" + +#. TRANSLATORS: since turn count isn't an integer, please adjust the +#. string as needed to deal with an localized plural forms. +#: ../../po/../src/sp-spiral.cpp:305 +#, c-format +msgid "Spiral with %3f turns" +msgstr "" + +#: ../../po/../src/sp-star.cpp:288 +#, c-format +msgid "Star with %d vertex" +msgid_plural "Star with %d vertices" +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/sp-star.cpp:292 +#, c-format +msgid "Polygon with %d vertex" +msgid_plural "Polygon with %d vertices" +msgstr[0] "" +msgstr[1] "" + +#. TRANSLATORS: For description of font with no name. +#: ../../po/../src/sp-text.cpp:420 +msgid "<no name found>" +msgstr "" + +#: ../../po/../src/sp-text.cpp:426 +#, fuzzy, c-format +msgid "Text on path (%s, %s)" +msgstr "Länk till %s" + +#: ../../po/../src/sp-text.cpp:427 +#, fuzzy, c-format +msgid "Text (%s, %s)" +msgstr "Länk till %s" + +#. TRANSLATORS: Used for statusbar description for long chains: +#. * "Clone of: Clone of: ... in Layer 1". +#: ../../po/../src/sp-use.cpp:317 +#, fuzzy +msgid "..." +msgstr "Öppna..." + +#: ../../po/../src/sp-use.cpp:325 +#, fuzzy, c-format +msgid "Clone of: %s" +msgstr "Länk till %s" + +#: ../../po/../src/sp-use.cpp:329 +#, fuzzy +msgid "Orphaned clone" +msgstr "Ändra" + +#: ../../po/../src/spiral-context.cpp:355 +msgid "Ctrl: snap angle" +msgstr "" + +#: ../../po/../src/spiral-context.cpp:357 +msgid "Alt: lock spiral radius" +msgstr "" + +#: ../../po/../src/spiral-context.cpp:469 +#, c-format +msgid "" +"Spiral: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/splivarot.cpp:106 +#, fuzzy +msgid "Select at least 2 paths to perform a boolean operation." +msgstr "Markera alla objekt i dokumentet" + +#: ../../po/../src/splivarot.cpp:112 +msgid "" +"Select exactly 2 paths to perform difference, XOR, division, or path " +"cut." +msgstr "" + +#: ../../po/../src/splivarot.cpp:129 ../../po/../src/splivarot.cpp:144 +msgid "" +"Unable to determine the z-order of the objects selected for " +"difference, XOR, division, or path cut." +msgstr "" + +#: ../../po/../src/splivarot.cpp:174 +#, fuzzy +msgid "" +"One of the objects is not a path, cannot perform boolean operation." +msgstr "Konvertera markerat objekt till slinga" + +#. TRANSLATORS: "to outline" means "to convert stroke to path" +#: ../../po/../src/splivarot.cpp:554 +#, fuzzy +msgid "Select path(s) to outline." +msgstr "Klipp ut markerade objekt till urklipp" + +#. TRANSLATORS: "to outline" means "to convert stroke to path" +#: ../../po/../src/splivarot.cpp:748 +msgid "No stroked paths to outline in the selection." +msgstr "" + +#: ../../po/../src/splivarot.cpp:832 +#, fuzzy +msgid "Selected object is not a path, cannot inset/outset." +msgstr "Konvertera markerat objekt till slinga" + +#: ../../po/../src/splivarot.cpp:1040 +#, fuzzy +msgid "Select path(s) to inset/outset." +msgstr "Klipp ut markerade objekt till urklipp" + +#: ../../po/../src/splivarot.cpp:1257 +msgid "No paths to inset/outset in the selection." +msgstr "" + +#: ../../po/../src/splivarot.cpp:1390 +#, fuzzy +msgid "Select path(s) to simplify." +msgstr "Klipp ut markerade objekt till urklipp" + +#: ../../po/../src/splivarot.cpp:1417 +msgid "No paths to simplify in the selection." +msgstr "" + +#: ../../po/../src/star-context.cpp:362 +msgid "Ctrl: snap angle; keep rays radial" +msgstr "" + +#: ../../po/../src/star-context.cpp:470 +#, c-format +msgid "" +"Polygon: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/star-context.cpp:471 +#, c-format +msgid "Star: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/text-chemistry.cpp:90 +#, fuzzy +msgid "Select a text and a path to put text on path." +msgstr "Markera alla objekt i dokumentet" + +#: ../../po/../src/text-chemistry.cpp:95 +msgid "" +"This text object is already put to a path. Remove it from the path " +"first. Use Shift+D to look up its path." +msgstr "" + +#. rect is the only SPShape which is not yet, and thus SVG forbids us from putting text on it +#: ../../po/../src/text-chemistry.cpp:101 +msgid "" +"You cannot put text on a rectangle in this version. Convert rectangle to " +"path first." +msgstr "" + +#: ../../po/../src/text-chemistry.cpp:159 +#, fuzzy +msgid "Select a text on path to remove it from path." +msgstr "Markera alla objekt i dokumentet" + +#: ../../po/../src/text-chemistry.cpp:181 +#, fuzzy +msgid "No texts-on-paths in the selection." +msgstr "Klipp ut markerade objekt till urklipp" + +#: ../../po/../src/text-chemistry.cpp:209 +#: ../../po/../src/text-chemistry.cpp:229 +#, fuzzy +msgid "Select text(s) to remove kerns from." +msgstr "Höj markerade objekt överst" + +#: ../../po/../src/text-chemistry.cpp:250 +#, fuzzy +msgid "" +"Select a text and one or more paths or shapes to flow text " +"into frame." +msgstr "Markera alla objekt i dokumentet" + +#: ../../po/../src/text-chemistry.cpp:322 +#, fuzzy +msgid "Select a flowed text to unflow it." +msgstr "Klipp ut markerade objekt till urklipp" + +#: ../../po/../src/text-context.cpp:463 +msgid "Click to edit the text, drag to select part of the text." +msgstr "" + +#: ../../po/../src/text-context.cpp:465 +msgid "" +"Click to edit the flowed text, drag to select part of the text." +msgstr "" + +#: ../../po/../src/text-context.cpp:540 +msgid "Non-printable character" +msgstr "" + +#: ../../po/../src/text-context.cpp:589 +#, fuzzy, c-format +msgid "Unicode: %s: %s" +msgstr "Sodipodi: %s: %s: %d" + +#: ../../po/../src/text-context.cpp:591 ../../po/../src/text-context.cpp:855 +msgid "Unicode: " +msgstr "" + +#: ../../po/../src/text-context.cpp:615 +msgid "Current layer is hidden. Unhide it to be able to add text." +msgstr "" + +#: ../../po/../src/text-context.cpp:619 +msgid "Current layer is locked. Unlock it to be able to add text." +msgstr "" +"Aktuellt lager är lÃ¥st. LÃ¥s upp det för att kunna lägga till text." + +#: ../../po/../src/text-context.cpp:673 +#, c-format +msgid "Flowed text frame: %s × %s" +msgstr "" + +#: ../../po/../src/text-context.cpp:708 ../../po/../src/text-context.cpp:1464 +msgid "Type text; Enter to start new line." +msgstr "" + +#: ../../po/../src/text-context.cpp:719 +msgid "Flowed text is created." +msgstr "" + +#: ../../po/../src/text-context.cpp:722 +msgid "" +"The frame is too small for the current font size. Flowed text not " +"created." +msgstr "" + +#: ../../po/../src/text-context.cpp:841 +msgid "No-break space" +msgstr "" + +#: ../../po/../src/text-context.cpp:1462 +msgid "Type flowed text; Enter to start new paragraph." +msgstr "" + +#: ../../po/../src/text-context.cpp:1472 ../../po/../src/tools-switch.cpp:189 +msgid "" +"Click to select or create text, drag to create flowed text; " +"then type." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:141 +msgid "" +"To edit a path, click, Shift+click, or drag around " +"nodes to select them, then drag nodes and handles. Click on an " +"object to select." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:147 +#, fuzzy +msgid "" +"Drag to create a rectangle. Drag controls to round corners and " +"resize. Click to select." +msgstr "Skapa rektanglar och fyrkanter med valfria rundade hörn" + +#: ../../po/../src/tools-switch.cpp:153 +msgid "" +"Drag to create an ellipse. Drag controls to make an arc or " +"segment. Click to select." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:159 +msgid "" +"Drag to create a star. Drag controls to edit the star shape. " +"Click to select." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:165 +msgid "" +"Drag to create a spiral. Drag controls to edit the spiral " +"shape. Click to select." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:171 +#, fuzzy +msgid "" +"Drag to create a freehand line. Start drawing with Shift to " +"append to selected path." +msgstr "Skapar ny kurva. Tryck \"a\" för att växla Lägg till/Ny." + +#: ../../po/../src/tools-switch.cpp:177 +#, fuzzy +msgid "" +"Click or click and drag to start a path; with Shift to " +"append to selected path." +msgstr "Skapar ny kurva. Tryck \"a\" för att växla Lägg till/Ny." + +#: ../../po/../src/tools-switch.cpp:183 +msgid "" +"Drag to paint a calligraphic stroke. Left/right arrow " +"keys adjust width, up/down adjust angle." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:195 +#, fuzzy +msgid "" +"Drag or double click to create a gradient on selected objects, " +"drag handles to adjust gradients." +msgstr "Skapar ny kurva. Tryck \"a\" för att växla Lägg till/Ny." + +#: ../../po/../src/tools-switch.cpp:201 +msgid "" +"Click or drag around an area to zoom in, Shift+click to " +"zoom out." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:213 +msgid "Click and drag between shapes to create a connector." +msgstr "" + +#: ../../po/../src/trace/potrace/inkscape-potrace.cpp:553 +#: ../../po/../src/trace/potrace/inkscape-potrace.cpp:654 +#, c-format +msgid "Trace: %d. %ld nodes" +msgstr "" + +#: ../../po/../src/trace/trace.cpp:53 ../../po/../src/trace/trace.cpp:62 +#: ../../po/../src/trace/trace.cpp:70 +#, fuzzy +msgid "Select an image to trace" +msgstr "Klipp ut markerade objekt till urklipp" + +#: ../../po/../src/trace/trace.cpp:133 +#, fuzzy +msgid "Trace: No active document" +msgstr "Skapa nytt SVG-dokument" + +#: ../../po/../src/trace/trace.cpp:154 +msgid "Trace: Image has no bitmap data" +msgstr "" + +#: ../../po/../src/trace/trace.cpp:267 +#, fuzzy, c-format +msgid "Trace: Done. %ld nodes created" +msgstr "Senast markerad" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:59 ../../po/../src/verbs.cpp:2212 +msgid "About Inkscape" +msgstr "Om Inkscape" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:66 +msgid "_Splash" +msgstr "" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:68 +msgid "_Authors" +msgstr "" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:69 +#, fuzzy +msgid "_Translators" +msgstr "Översättare" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:70 +msgid "_License" +msgstr "Licens" + +#. TRANSLATORS: This is the filename of the `About Inkscape' picture in +#. the `screens' directory. Thus the translation of "about.svg" should be +#. the filename of its translated version, e.g. about.zh.svg for Chinese. +#. +#. N.B. about.svg changes once per release. (We should probably rename +#. the original to about-0.40.svg etc. as soon as we have a translation. +#. If we do so, then add an item to release-checklist saying that the +#. string here should be changed.) +#. FIXME? INKSCAPE_SCREENSDIR and "about.svg" are in UTF-8, not the +#. native filename encoding... and the filename passed to sp_document_new +#. should be in UTF-*8.. +#: ../../po/../src/ui/dialog/aboutbox.cpp:114 +msgid "about.svg" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:464 +msgid "Minimum horizontal gap (in px units) between bounding boxes" +msgstr "" + +#. TRANSLATORS: Horizontal gap +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:466 +#: ../../po/../src/widgets/toolbox.cpp:1556 +msgid "H:" +msgstr "H:" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:474 +msgid "Minimum vertical gap (in px units) between bounding boxes" +msgstr "" + +#. TRANSLATORS: Vertical gap +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:476 +msgid "V:" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:734 +msgid "Align" +msgstr "Justera" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:735 +msgid "Distribute" +msgstr "Distribuera" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:736 +msgid "Remove overlaps" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:737 +msgid "Nodes" +msgstr "Noder" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:742 +msgid "Relative to: " +msgstr "Relativ till:" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:747 +#, fuzzy +msgid "Align right sides of objects to left side of anchor" +msgstr "Högersida pÃ¥ justerade objekt mot vänsterkanten pÃ¥ ankare" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:750 +#, fuzzy +msgid "Align left sides" +msgstr "Vänsterjustera i mitten" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:753 +#, fuzzy +msgid "Center on vertical axis" +msgstr "Centrera vertikalt" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:756 +#, fuzzy +msgid "Align right sides" +msgstr "Högerjustera i mitten" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:759 +#, fuzzy +msgid "Align left sides of objects to right side of anchor" +msgstr "Vänstersida pÃ¥ justerade objekt mot högerkanten pÃ¥ ankare" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:762 +#, fuzzy +msgid "Align bottoms of objects to top of anchor" +msgstr "Nederkanten pÃ¥ justerade objekt mot överkanten pÃ¥ ankare" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:765 +#, fuzzy +msgid "Align tops" +msgstr "Justera objekt" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:768 +#, fuzzy +msgid "Center on horizontal axis" +msgstr "Centrera horisontellt" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:771 +#, fuzzy +msgid "Align bottoms" +msgstr "Vänsterjustera nederst" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:774 +#, fuzzy +msgid "Align tops of objects to bottom of anchor" +msgstr "Överkanten pÃ¥ justerade objekt mot överkanten pÃ¥ ankare" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:779 +#, fuzzy +msgid "Align baseline anchors of texts vertically" +msgstr "Vänd markerade objekt vertikalt" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:782 +#, fuzzy +msgid "Align baseline anchors of texts horizontally" +msgstr "Vänd markerade objekt horisontellt" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:787 +#, fuzzy +msgid "Make horizontal gaps between objects equal" +msgstr "Distribuera horisontellt avstÃ¥nd mellan objekt med jämna mellanrum" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:791 +#, fuzzy +msgid "Distribute left sides equidistantly" +msgstr "Distribuera vänstersidor pÃ¥ objekt med jämna mellanrum" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:794 +#, fuzzy +msgid "Distribute centers equidistantly horizontally" +msgstr "Distribuera objektcentrum med jämna mellanrum horisontellt" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:797 +#, fuzzy +msgid "Distribute right sides equidistantly" +msgstr "Distribuera högersidor pÃ¥ objekt med jämna mellanrum" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:801 +#, fuzzy +msgid "Make vertical gaps between objects equal" +msgstr "Distribuera vertikalt avstÃ¥nd mellan objekt med jämna mellanrum" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:805 +#, fuzzy +msgid "Distribute tops equidistantly" +msgstr "Distribuera objektcentrum med jämna mellanrum vertikalt" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:808 +#, fuzzy +msgid "Distribute centers equidistantly vertically" +msgstr "Distribuera objektcentrum med jämna mellanrum vertikalt" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:811 +#, fuzzy +msgid "Distribute bottoms equidistantly" +msgstr "Distribuera nederkanter pÃ¥ objekt med jämna mellanrum" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:816 +#, fuzzy +msgid "Distribute baseline anchors of texts horizontally" +msgstr "Vänd markerade objekt horisontellt" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:819 +#, fuzzy +msgid "Distribute baseline anchors of texts vertically" +msgstr "Distribuera objektcentrum med jämna mellanrum vertikalt" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:824 +msgid "Randomize centers in both dimensions" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:827 +msgid "Unclump objects: try to equalize edge-to-edge distances" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:832 +msgid "" +"Move objects as little as possible so that their bounding boxes do not " +"overlap" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:837 +#, fuzzy +msgid "Align selected nodes horizontally" +msgstr "Vänd markerade objekt horisontellt" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:840 +#, fuzzy +msgid "Align selected nodes vertically" +msgstr "Vänd markerade objekt vertikalt" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:843 +#, fuzzy +msgid "Distribute selected nodes horizontally" +msgstr "Vänd markerade objekt horisontellt" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:846 +#, fuzzy +msgid "Distribute selected nodes vertically" +msgstr "Distribuera objektcentrum med jämna mellanrum vertikalt" + +#. Rest of the widgetry +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:851 +#, fuzzy +msgid "Last selected" +msgstr "Senast markerad" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:852 +#, fuzzy +msgid "First selected" +msgstr "Först markerad" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:853 +msgid "Biggest item" +msgstr "Största objekt" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:854 +msgid "Smallest item" +msgstr "Minsta objekt" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:856 +#: ../../po/../src/widgets/desktop-widget.cpp:1065 +msgid "Drawing" +msgstr "Teckning" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:91 +msgid "Metadata 1" +msgstr "" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:92 +msgid "Metadata 2" +msgstr "" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:187 +#, fuzzy +msgid "X coordinate of grid origin" +msgstr "Färgen pÃ¥ rutnätet" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:189 +#, fuzzy +msgid "Y coordinate of grid origin" +msgstr "Färgen pÃ¥ rutnätet" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:191 +#, fuzzy +msgid "Distance of vertical grid lines" +msgstr "Ställ in avstÃ¥ndet mellan vertikala rutnätslinjer" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:193 +#, fuzzy +msgid "Distance of horizontal grid lines" +msgstr "Ställ in avstÃ¥ndet mellan horisontella rutnätslinjer" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:197 +msgid "Max. snapping distance from grid" +msgstr "" + +#: ../../po/../src/ui/dialog/export.cpp:34 +msgid "Export" +msgstr "Exportera" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:36 +msgid "Fill" +msgstr "Fyll" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:37 +#, fuzzy +msgid "Stroke Paint" +msgstr "Genomstrykningsbredd" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:38 +#, fuzzy +msgid "Stroke Style" +msgstr "Genomstrykningsinställningar" + +#: ../../po/../src/ui/dialog/find.cpp:34 +#, fuzzy +msgid "Find" +msgstr "Rutnät" + +#: ../../po/../src/ui/dialog/memory.cpp:96 +#, fuzzy +msgid "Heap" +msgstr "_Hjälp" + +#: ../../po/../src/ui/dialog/memory.cpp:97 +#, fuzzy +msgid "In Use" +msgstr "Återställ" + +#. TRANSLATORS: "Slack" refers to memory which is in the heap but currently unused. +#. More typical usage is to call this memory "free" rather than "slack". +#: ../../po/../src/ui/dialog/memory.cpp:100 +msgid "Slack" +msgstr "Ledigt" + +#: ../../po/../src/ui/dialog/memory.cpp:101 +msgid "Total" +msgstr "Totalt" + +#: ../../po/../src/ui/dialog/memory.cpp:141 +#: ../../po/../src/ui/dialog/memory.cpp:147 +#: ../../po/../src/ui/dialog/memory.cpp:154 +#: ../../po/../src/ui/dialog/memory.cpp:186 +msgid "Unknown" +msgstr "Okänt" + +#: ../../po/../src/ui/dialog/memory.cpp:167 +msgid "Combined" +msgstr "Kombinerat" + +#: ../../po/../src/ui/dialog/memory.cpp:209 +msgid "Recalculate" +msgstr "Beräkna om" + +#: ../../po/../src/ui/dialog/messages.cpp:74 +#, fuzzy +msgid "Ready." +msgstr "Läs om" + +#: ../../po/../src/ui/dialog/messages.cpp:75 +msgid "" +"Enable log display by setting dialogs.debug 'redirect' attribute to 1 in " +"preferences.xml" +msgstr "" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:184 +msgid "_Execute Python" +msgstr "" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:186 +msgid "_Execute Perl" +msgstr "" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:195 +msgid "Script" +msgstr "" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:205 +#, fuzzy +msgid "Output" +msgstr "Ut" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:215 +msgid "Errors" +msgstr "" + +#. Dialog organization +#: ../../po/../src/ui/dialog/session-player.cpp:73 +#, fuzzy +msgid "Session file" +msgstr "Spara fil" + +#: ../../po/../src/ui/dialog/session-player.cpp:74 +#, fuzzy +msgid "Playback controls" +msgstr "Verktygsalternativ" + +#: ../../po/../src/ui/dialog/session-player.cpp:75 +#, fuzzy +msgid "Message information" +msgstr "Återställ transformering" + +#. Active session file display +#. fixme: Does this mean the active file for the session, or the file for the active session? +#. Please indicate which with a TRANSLATORS comment. +#: ../../po/../src/ui/dialog/session-player.cpp:85 +msgid "Active session file:" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:86 +msgid "Delay (milliseconds):" +msgstr "" + +#. Unload/load buttons +#: ../../po/../src/ui/dialog/session-player.cpp:94 +#, fuzzy +msgid "Close file" +msgstr "Färgfyllning" + +#: ../../po/../src/ui/dialog/session-player.cpp:95 +#, fuzzy +msgid "Open new file" +msgstr "Öppna SVG-fil" + +#: ../../po/../src/ui/dialog/session-player.cpp:96 +#, fuzzy +msgid "Set delay" +msgstr "Ställ in attribut" + +#: ../../po/../src/ui/dialog/session-player.cpp:138 +#, fuzzy +msgid "Rewind" +msgstr "Röd:" + +#: ../../po/../src/ui/dialog/session-player.cpp:139 +msgid "Go back one change" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:140 +#, fuzzy +msgid "Pause" +msgstr "Klistra in" + +#: ../../po/../src/ui/dialog/session-player.cpp:141 +msgid "Go forward one change" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:142 +msgid "Play" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:177 +#: ../../po/../src/verbs.cpp:1573 +#, fuzzy +msgid "Open session file" +msgstr "Öppna SVG-fil" + +#. ##Set up the Potrace panel +#. #### brightness #### +#. #### Multiple scanning#### +#. ----Hbox1 +#: ../../po/../src/ui/dialog/tracedialog.cpp:345 +#: ../../po/../src/ui/dialog/tracedialog.cpp:428 +#, fuzzy +msgid "Brightness" +msgstr "höger" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:348 +msgid "Trace by a given brightness level" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:355 +msgid "Brightness cutoff for black/white" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:362 +#, fuzzy +msgid "Image Brightness" +msgstr "Bildstorlek" + +#. #### canny edge detection #### +#. TRANSLATORS: "Canny" is the name of the inventor of this edge detection method +#: ../../po/../src/ui/dialog/tracedialog.cpp:369 +msgid "Optimal Edge Detection (Canny)" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:372 +msgid "Trace with edge detection by J. Canny's algorithm" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:388 +msgid "Brightness cutoff for adjacent pixels (determines edge thickness)" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:395 +#, fuzzy +msgid "Edge Detection" +msgstr "Markering" + +#. #### quantization #### +#. TRANSLATORS: Color Quantization: the process of reducing the number of colors +#. in an image by selecting an optimized set of representative colors and then +#. re-applying this reduced set to the original image. +#: ../../po/../src/ui/dialog/tracedialog.cpp:404 +#, fuzzy +msgid "Color Quantization" +msgstr "FärgmÃ¥lning" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:407 +msgid "Trace along the boundaries of reduced colors" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:414 +msgid "The number of reduced colors" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:416 +#, fuzzy +msgid "Colors:" +msgstr "Färg" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:421 +msgid "Quantization / Reduction" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:431 +msgid "Trace the given number of brightness levels" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:438 +#, fuzzy +msgid "Scans:" +msgstr "Form" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:440 +msgid "The desired number of scans" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:448 +msgid "Trace the given number of reduced colors" +msgstr "" + +#. ---Hbox3 +#: ../../po/../src/ui/dialog/tracedialog.cpp:454 +msgid "Monochrome" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:457 +msgid "Same as Color, but convert result to grayscale" +msgstr "" + +#. TRANSLATORS: "Stack" is a verb here +#: ../../po/../src/ui/dialog/tracedialog.cpp:460 +#, fuzzy +msgid "Stack" +msgstr "Stjärna" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:463 +msgid "" +"Stack scans vertically (no gaps) or tile horizontally (usually with gaps)" +msgstr "" + +#. TRANSLATORS: "Smooth" is a verb here +#: ../../po/../src/ui/dialog/tracedialog.cpp:466 +msgid "Smooth" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:469 +msgid "Apply Gaussian blur to the bitmap before tracing" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:473 +msgid "Multiple Scanning" +msgstr "" + +#. #### Preview #### +#: ../../po/../src/ui/dialog/tracedialog.cpp:479 +#: ../../po/../src/ui/dialog/tracedialog.cpp:489 +#, fuzzy +msgid "Preview" +msgstr "Ny förhandsgranskning" + +#. do not expand +#: ../../po/../src/ui/dialog/tracedialog.cpp:483 +msgid "Preview the result without actual tracing" +msgstr "" + +#. #### swap black and white #### +#: ../../po/../src/ui/dialog/tracedialog.cpp:495 +#, fuzzy +msgid "Invert" +msgstr "Återställ" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:499 +msgid "Invert black and white regions for single traces" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:503 +msgid "Thanks to Peter Selinger, http://potrace.sourceforge.net" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:506 +#, fuzzy +msgid "Credits" +msgstr "Hörn:" + +#. done +#. TRANSLATORS: Potrace is an application for transforming bitmaps into +#. vector graphics (http://potrace.sourceforge.net/) +#: ../../po/../src/ui/dialog/tracedialog.cpp:514 +#, fuzzy +msgid "Potrace" +msgstr "SpÃ¥r" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:527 +#, fuzzy +msgid "Abort a trace in progress" +msgstr "Exportera bild" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:531 +msgid "Execute the trace" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:80 +#: ../../po/../src/ui/dialog/transformation.cpp:90 +#, fuzzy +msgid "_Horizontal" +msgstr "horisontell flytt" + +#: ../../po/../src/ui/dialog/transformation.cpp:80 +msgid "Horizontal displacement (relative) or position (absolute)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:82 +#: ../../po/../src/ui/dialog/transformation.cpp:92 +#, fuzzy +msgid "_Vertical" +msgstr "Vertikalt mittpunktsvärde" + +#: ../../po/../src/ui/dialog/transformation.cpp:82 +msgid "Vertical displacement (relative) or position (absolute)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:84 +#, fuzzy +msgid "_Width" +msgstr "Bredd:" + +#: ../../po/../src/ui/dialog/transformation.cpp:84 +msgid "Horizontal size increment (absolute or percentage)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:86 +#, fuzzy +msgid "_Height" +msgstr "Höjd" + +#: ../../po/../src/ui/dialog/transformation.cpp:86 +msgid "Vertical size increment (absolute or percentage)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:88 +#, fuzzy +msgid "A_ngle" +msgstr "Vinkel" + +#: ../../po/../src/ui/dialog/transformation.cpp:88 +#, fuzzy +msgid "Rotation angle (positive = counterclockwise)" +msgstr "Rotera objekt 90 grader medurs" + +#: ../../po/../src/ui/dialog/transformation.cpp:90 +msgid "" +"Horizontal skew angle (positive = counterclockwise), or absolute " +"displacement, or percentage displacement" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:92 +msgid "" +"Vertical skew angle (positive = counterclockwise), or absolute displacement, " +"or percentage displacement" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:95 +#, fuzzy +msgid "Transformation matrix element A" +msgstr "Transformationsmatris" + +#: ../../po/../src/ui/dialog/transformation.cpp:96 +#, fuzzy +msgid "Transformation matrix element B" +msgstr "Transformationsmatris" + +#: ../../po/../src/ui/dialog/transformation.cpp:97 +#, fuzzy +msgid "Transformation matrix element C" +msgstr "Transformationsmatris" + +#: ../../po/../src/ui/dialog/transformation.cpp:98 +#, fuzzy +msgid "Transformation matrix element D" +msgstr "Transformationsmatris" + +#: ../../po/../src/ui/dialog/transformation.cpp:99 +#, fuzzy +msgid "Transformation matrix element E" +msgstr "Transformationsmatris" + +#: ../../po/../src/ui/dialog/transformation.cpp:100 +#, fuzzy +msgid "Transformation matrix element F" +msgstr "Transformationsmatris" + +#: ../../po/../src/ui/dialog/transformation.cpp:102 +#, fuzzy +msgid "Rela_tive move" +msgstr "Relativ flytt" + +#: ../../po/../src/ui/dialog/transformation.cpp:102 +msgid "" +"Add the specified relative displacement to the current position; otherwise, " +"edit the current absolute position directly" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:103 +msgid "Scale proportionally" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:103 +msgid "Preserve the width/height ratio of the scaled objects" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:104 +msgid "Apply to each _object separately" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:104 +msgid "" +"Apply the scale/rotate/skew to each selected object separately; otherwise, " +"transform the selection as a whole" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:105 +msgid "Edit c_urrent matrix" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:105 +msgid "" +"Edit the current transform= matrix; otherwise, post-multiply transform= by " +"this matrix" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:115 +#, fuzzy +msgid "_Move" +msgstr "Flytta" + +#: ../../po/../src/ui/dialog/transformation.cpp:118 +#, fuzzy +msgid "_Scale" +msgstr "Skala" + +#: ../../po/../src/ui/dialog/transformation.cpp:121 +#, fuzzy +msgid "_Rotate" +msgstr "Rotera" + +#: ../../po/../src/ui/dialog/transformation.cpp:124 +#, fuzzy +msgid "Ske_w" +msgstr "Snedställ" + +#: ../../po/../src/ui/dialog/transformation.cpp:127 +msgid "Matri_x" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:141 +#, fuzzy +msgid "Reset the values on the current tab to defaults" +msgstr "Återställ dialogfönstret till standardvärden - Ctrl+r" + +#: ../../po/../src/ui/dialog/transformation.cpp:148 +#, fuzzy +msgid "Apply transformation to selection" +msgstr "Verkställ transformeringen för att kopiera Ctrl+m" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:43 +msgid "_Use SSL" +msgstr "" + +#. Construct dialog interface +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:68 +#, fuzzy +msgid "_Server:" +msgstr "Filter" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:69 +#, fuzzy +msgid "_Username:" +msgstr "Filnamn:" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:70 +msgid "_Password:" +msgstr "Lösenord:" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:71 +msgid "P_ort:" +msgstr "Port:" + +#. Buttons +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:99 +#, fuzzy +msgid "Connect" +msgstr "InnehÃ¥ll" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:126 +msgid "Establishing connection to Jabber server %1 as user %2" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:131 +msgid "Failed to establish connection to Jabber server %1" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:136 +msgid "Authentication failed on Jabber server %1 as %2" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:141 +msgid "SSL initialization failed when connecting to Jabber server %1" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:147 +msgid "Connected to Jabber server %1 as %2" +msgstr "" + +#. Construct labels +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:75 +msgid "Chatroom _name:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:76 +msgid "Chatroom _server:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:77 +msgid "Chatroom _password:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:78 +msgid "Chatroom _handle:" +msgstr "" + +#. Button setup and callback registration +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:97 +msgid "Connect to chatroom" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:132 +msgid "Synchronizing with chatroom %1@%2 using the handle %3" +msgstr "" + +#. Construct dialog interface +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:78 +msgid "_User's Jabber ID:" +msgstr "" + +#. Buttons +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:82 +msgid "_Invite user" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:83 +#, fuzzy +msgid "_Cancel" +msgstr "Avbryt" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:94 +msgid "Buddy List" +msgstr "Kompislista" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:170 +msgid "Sending whiteboard invitation to %1" +msgstr "" + +#. FIXME: strings are replaced by placeholders, NOT to be translated until the code is enabled +#. See http://sourceforge.net/mailarchive/message.php?msg_id=11746016 for details +#. File menu +#. Edit menu +#. View menu +#. Layer menu +#. Object menu +#. Path menu +#. add(Gtk::StockItem(CLEANUP, _("PLACEHOLDER, do not translate"))); (using Gtk::Stock::CLEAR) +#. Text menu +#. About menu +#. Tools toolbox +#. Select Tool controls +#. Node Tool controls +#. Calligraphy Tool controls +#. Session playback controls +#: ../../po/../src/ui/stock-items.cpp:34 ../../po/../src/ui/stock-items.cpp:35 +#: ../../po/../src/ui/stock-items.cpp:36 ../../po/../src/ui/stock-items.cpp:37 +#: ../../po/../src/ui/stock-items.cpp:38 ../../po/../src/ui/stock-items.cpp:39 +#: ../../po/../src/ui/stock-items.cpp:40 ../../po/../src/ui/stock-items.cpp:41 +#: ../../po/../src/ui/stock-items.cpp:42 ../../po/../src/ui/stock-items.cpp:43 +#: ../../po/../src/ui/stock-items.cpp:46 ../../po/../src/ui/stock-items.cpp:47 +#: ../../po/../src/ui/stock-items.cpp:48 ../../po/../src/ui/stock-items.cpp:49 +#: ../../po/../src/ui/stock-items.cpp:50 ../../po/../src/ui/stock-items.cpp:51 +#: ../../po/../src/ui/stock-items.cpp:52 ../../po/../src/ui/stock-items.cpp:53 +#: ../../po/../src/ui/stock-items.cpp:54 ../../po/../src/ui/stock-items.cpp:55 +#: ../../po/../src/ui/stock-items.cpp:56 ../../po/../src/ui/stock-items.cpp:57 +#: ../../po/../src/ui/stock-items.cpp:58 ../../po/../src/ui/stock-items.cpp:59 +#: ../../po/../src/ui/stock-items.cpp:62 ../../po/../src/ui/stock-items.cpp:63 +#: ../../po/../src/ui/stock-items.cpp:64 ../../po/../src/ui/stock-items.cpp:65 +#: ../../po/../src/ui/stock-items.cpp:66 ../../po/../src/ui/stock-items.cpp:67 +#: ../../po/../src/ui/stock-items.cpp:68 ../../po/../src/ui/stock-items.cpp:69 +#: ../../po/../src/ui/stock-items.cpp:70 ../../po/../src/ui/stock-items.cpp:71 +#: ../../po/../src/ui/stock-items.cpp:72 ../../po/../src/ui/stock-items.cpp:73 +#: ../../po/../src/ui/stock-items.cpp:74 ../../po/../src/ui/stock-items.cpp:75 +#: ../../po/../src/ui/stock-items.cpp:76 ../../po/../src/ui/stock-items.cpp:77 +#: ../../po/../src/ui/stock-items.cpp:78 ../../po/../src/ui/stock-items.cpp:79 +#: ../../po/../src/ui/stock-items.cpp:80 ../../po/../src/ui/stock-items.cpp:81 +#: ../../po/../src/ui/stock-items.cpp:82 ../../po/../src/ui/stock-items.cpp:83 +#: ../../po/../src/ui/stock-items.cpp:84 ../../po/../src/ui/stock-items.cpp:85 +#: ../../po/../src/ui/stock-items.cpp:86 ../../po/../src/ui/stock-items.cpp:87 +#: ../../po/../src/ui/stock-items.cpp:88 ../../po/../src/ui/stock-items.cpp:89 +#: ../../po/../src/ui/stock-items.cpp:92 ../../po/../src/ui/stock-items.cpp:93 +#: ../../po/../src/ui/stock-items.cpp:94 ../../po/../src/ui/stock-items.cpp:95 +#: ../../po/../src/ui/stock-items.cpp:96 ../../po/../src/ui/stock-items.cpp:97 +#: ../../po/../src/ui/stock-items.cpp:98 ../../po/../src/ui/stock-items.cpp:99 +#: ../../po/../src/ui/stock-items.cpp:100 +#: ../../po/../src/ui/stock-items.cpp:101 +#: ../../po/../src/ui/stock-items.cpp:102 +#: ../../po/../src/ui/stock-items.cpp:103 +#: ../../po/../src/ui/stock-items.cpp:104 +#: ../../po/../src/ui/stock-items.cpp:105 +#: ../../po/../src/ui/stock-items.cpp:108 +#: ../../po/../src/ui/stock-items.cpp:109 +#: ../../po/../src/ui/stock-items.cpp:110 +#: ../../po/../src/ui/stock-items.cpp:111 +#: ../../po/../src/ui/stock-items.cpp:112 +#: ../../po/../src/ui/stock-items.cpp:113 +#: ../../po/../src/ui/stock-items.cpp:114 +#: ../../po/../src/ui/stock-items.cpp:115 +#: ../../po/../src/ui/stock-items.cpp:116 +#: ../../po/../src/ui/stock-items.cpp:117 +#: ../../po/../src/ui/stock-items.cpp:118 +#: ../../po/../src/ui/stock-items.cpp:119 +#: ../../po/../src/ui/stock-items.cpp:120 +#: ../../po/../src/ui/stock-items.cpp:121 +#: ../../po/../src/ui/stock-items.cpp:122 +#: ../../po/../src/ui/stock-items.cpp:123 +#: ../../po/../src/ui/stock-items.cpp:124 +#: ../../po/../src/ui/stock-items.cpp:125 +#: ../../po/../src/ui/stock-items.cpp:126 +#: ../../po/../src/ui/stock-items.cpp:127 +#: ../../po/../src/ui/stock-items.cpp:130 +#: ../../po/../src/ui/stock-items.cpp:131 +#: ../../po/../src/ui/stock-items.cpp:132 +#: ../../po/../src/ui/stock-items.cpp:133 +#: ../../po/../src/ui/stock-items.cpp:134 +#: ../../po/../src/ui/stock-items.cpp:135 +#: ../../po/../src/ui/stock-items.cpp:136 +#: ../../po/../src/ui/stock-items.cpp:137 +#: ../../po/../src/ui/stock-items.cpp:138 +#: ../../po/../src/ui/stock-items.cpp:139 +#: ../../po/../src/ui/stock-items.cpp:140 +#: ../../po/../src/ui/stock-items.cpp:141 +#: ../../po/../src/ui/stock-items.cpp:142 +#: ../../po/../src/ui/stock-items.cpp:143 +#: ../../po/../src/ui/stock-items.cpp:144 +#: ../../po/../src/ui/stock-items.cpp:145 +#: ../../po/../src/ui/stock-items.cpp:146 +#: ../../po/../src/ui/stock-items.cpp:150 +#: ../../po/../src/ui/stock-items.cpp:151 +#: ../../po/../src/ui/stock-items.cpp:152 +#: ../../po/../src/ui/stock-items.cpp:153 +#: ../../po/../src/ui/stock-items.cpp:156 +#: ../../po/../src/ui/stock-items.cpp:157 +#: ../../po/../src/ui/stock-items.cpp:158 +#: ../../po/../src/ui/stock-items.cpp:161 +#: ../../po/../src/ui/stock-items.cpp:162 +#: ../../po/../src/ui/stock-items.cpp:163 +#: ../../po/../src/ui/stock-items.cpp:164 +#: ../../po/../src/ui/stock-items.cpp:165 +#: ../../po/../src/ui/stock-items.cpp:166 +#: ../../po/../src/ui/stock-items.cpp:167 +#: ../../po/../src/ui/stock-items.cpp:168 +#: ../../po/../src/ui/stock-items.cpp:169 +#: ../../po/../src/ui/stock-items.cpp:170 +#: ../../po/../src/ui/stock-items.cpp:171 +#: ../../po/../src/ui/stock-items.cpp:172 +#: ../../po/../src/ui/stock-items.cpp:175 +#: ../../po/../src/ui/stock-items.cpp:176 +#: ../../po/../src/ui/stock-items.cpp:177 +#: ../../po/../src/ui/stock-items.cpp:178 +#: ../../po/../src/ui/stock-items.cpp:181 +#: ../../po/../src/ui/stock-items.cpp:182 +#: ../../po/../src/ui/stock-items.cpp:183 +#: ../../po/../src/ui/stock-items.cpp:184 +#: ../../po/../src/ui/stock-items.cpp:185 +#: ../../po/../src/ui/stock-items.cpp:186 +#: ../../po/../src/ui/stock-items.cpp:187 +#: ../../po/../src/ui/stock-items.cpp:188 +#: ../../po/../src/ui/stock-items.cpp:189 +#: ../../po/../src/ui/stock-items.cpp:190 +#: ../../po/../src/ui/stock-items.cpp:191 +#: ../../po/../src/ui/stock-items.cpp:194 +#: ../../po/../src/ui/stock-items.cpp:195 +#: ../../po/../src/ui/stock-items.cpp:198 +#: ../../po/../src/ui/stock-items.cpp:199 +#: ../../po/../src/ui/stock-items.cpp:200 +#: ../../po/../src/ui/stock-items.cpp:201 +#: ../../po/../src/ui/stock-items.cpp:202 +msgid "PLACEHOLDER, do not translate" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:88 +msgid "small" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:89 +msgid "medium" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:90 +#, fuzzy +msgid "large" +msgstr "MÃ¥l:" + +#: ../../po/../src/ui/widget/panel.cpp:91 +msgid "huge" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:106 +#, fuzzy +msgid "List" +msgstr "tum" + +#: ../../po/../src/ui/widget/selected-style.cpp:67 +msgid "F:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:68 +msgid "S:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:69 +msgid "O:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:95 +msgid "N/A" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:98 +#: ../../po/../src/ui/widget/selected-style.cpp:712 +#, fuzzy +msgid "Nothing selected" +msgstr "Ta bort markerade objekt" + +#: ../../po/../src/ui/widget/selected-style.cpp:103 +msgid "No fill" +msgstr "Ingen fyllning" + +#: ../../po/../src/ui/widget/selected-style.cpp:103 +#, fuzzy +msgid "No stroke" +msgstr "Är genomstruket" + +#: ../../po/../src/ui/widget/selected-style.cpp:105 +#: ../../po/../src/widgets/paint-selector.cpp:190 +#, fuzzy +msgid "Pattern" +msgstr "Mönster:" + +#: ../../po/../src/ui/widget/selected-style.cpp:108 +#: ../../po/../src/widgets/paint-selector.cpp:885 +#, fuzzy +msgid "Pattern fill" +msgstr "Mönster:" + +#: ../../po/../src/ui/widget/selected-style.cpp:108 +#, fuzzy +msgid "Pattern stroke" +msgstr "Mönsterfyllning" + +#: ../../po/../src/ui/widget/selected-style.cpp:110 +#, fuzzy +msgid "L Gradient" +msgstr "Toningsfyllning" + +#: ../../po/../src/ui/widget/selected-style.cpp:113 +#, fuzzy +msgid "Linear gradient fill" +msgstr "Linjär toning" + +#: ../../po/../src/ui/widget/selected-style.cpp:113 +#, fuzzy +msgid "Linear gradient stroke" +msgstr "Linjär toning" + +#: ../../po/../src/ui/widget/selected-style.cpp:115 +#, fuzzy +msgid "R Gradient" +msgstr "Toningsfyllning" + +#: ../../po/../src/ui/widget/selected-style.cpp:118 +#, fuzzy +msgid "Radial gradient fill" +msgstr "Radiell toning" + +#: ../../po/../src/ui/widget/selected-style.cpp:118 +#, fuzzy +msgid "Radial gradient stroke" +msgstr "Radiell toning" + +#: ../../po/../src/ui/widget/selected-style.cpp:120 +#, fuzzy +msgid "Different" +msgstr "Grad" + +#: ../../po/../src/ui/widget/selected-style.cpp:123 +#, fuzzy +msgid "Different fills" +msgstr "Grad" + +#: ../../po/../src/ui/widget/selected-style.cpp:123 +#, fuzzy +msgid "Different strokes" +msgstr "Grad" + +#: ../../po/../src/ui/widget/selected-style.cpp:125 +#, fuzzy +msgid "Unset" +msgstr "tum" + +#. TRANSLATORS COMMENT: unset is a verb here +#: ../../po/../src/ui/widget/selected-style.cpp:128 +#: ../../po/../src/ui/widget/selected-style.cpp:182 +#, fuzzy +msgid "Unset fill" +msgstr "Namnlös" + +#: ../../po/../src/ui/widget/selected-style.cpp:128 +#: ../../po/../src/ui/widget/selected-style.cpp:182 +#, fuzzy +msgid "Unset stroke" +msgstr "Är genomstruket" + +#: ../../po/../src/ui/widget/selected-style.cpp:131 +#, fuzzy +msgid "Flat color fill" +msgstr "Enfärgad" + +#: ../../po/../src/ui/widget/selected-style.cpp:131 +#, fuzzy +msgid "Flat color stroke" +msgstr "Enfärgad" + +#. TRANSLATOR COMMENT: A means "Averaged" +#: ../../po/../src/ui/widget/selected-style.cpp:134 +#, fuzzy +msgid "A" +msgstr "A4" + +#: ../../po/../src/ui/widget/selected-style.cpp:137 +#, fuzzy +msgid "Fill is averaged over selected objects" +msgstr "Redigera layout pÃ¥ markerade objekt" + +#: ../../po/../src/ui/widget/selected-style.cpp:137 +#, fuzzy +msgid "Stroke is averaged over selected objects" +msgstr "Redigera genomstrykningstyp hos markerade objekt" + +#. TRANSLATOR COMMENT: M means "Multiple" +#: ../../po/../src/ui/widget/selected-style.cpp:140 +msgid "M" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:143 +#, fuzzy +msgid "Multiple selected objects have the same fill" +msgstr "Vänd markerade objekt vertikalt" + +#: ../../po/../src/ui/widget/selected-style.cpp:143 +#, fuzzy +msgid "Multiple selected objects have the same stroke" +msgstr "Vänd markerade objekt vertikalt" + +#: ../../po/../src/ui/widget/selected-style.cpp:145 +#, fuzzy +msgid "Edit fill..." +msgstr "Redigera..." + +#: ../../po/../src/ui/widget/selected-style.cpp:145 +#, fuzzy +msgid "Edit stroke..." +msgstr "Redigera..." + +#: ../../po/../src/ui/widget/selected-style.cpp:149 +#, fuzzy +msgid "Last set color" +msgstr "Enfärgad" + +#: ../../po/../src/ui/widget/selected-style.cpp:153 +#, fuzzy +msgid "Last selected color" +msgstr "Senast markerad" + +#: ../../po/../src/ui/widget/selected-style.cpp:157 +msgid "White" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:161 +#: ../../po/../src/widgets/sp-color-scales.cpp:461 +#: ../../po/../src/widgets/sp-color-scales.cpp:462 +msgid "Black" +msgstr "Svart" + +#: ../../po/../src/ui/widget/selected-style.cpp:165 +#, fuzzy +msgid "Copy color" +msgstr "Startfärg" + +#: ../../po/../src/ui/widget/selected-style.cpp:169 +#, fuzzy +msgid "Paste color" +msgstr "Enfärgad" + +#: ../../po/../src/ui/widget/selected-style.cpp:173 +#, fuzzy +msgid "Swap fill and stroke" +msgstr "Fyllning och genomstrykning" + +#: ../../po/../src/ui/widget/selected-style.cpp:177 +msgid "Make fill opaque" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:177 +msgid "Make stroke opaque" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:186 +#, fuzzy +msgid "Remove fill" +msgstr " Ta bort " + +#: ../../po/../src/ui/widget/selected-style.cpp:186 +#, fuzzy +msgid "Remove stroke" +msgstr "Ta bort länk" + +#: ../../po/../src/ui/widget/selected-style.cpp:718 +#, fuzzy +msgid "Master opacity" +msgstr "Opacitet:" + +#: ../../po/../src/ui/widget/selected-style.cpp:744 +msgid "0 (transparent)" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:768 +msgid "1.0 (opaque)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1046 +msgid "Moved to next layer." +msgstr "" + +#: ../../po/../src/verbs.cpp:1048 +msgid "Cannot move past last layer." +msgstr "" + +#: ../../po/../src/verbs.cpp:1057 +msgid "Moved to previous layer." +msgstr "" + +#: ../../po/../src/verbs.cpp:1059 +msgid "Cannot move past first layer." +msgstr "" + +#: ../../po/../src/verbs.cpp:1076 ../../po/../src/verbs.cpp:1150 +#, fuzzy +msgid "No current layer." +msgstr "Dokumentnamn:" + +#: ../../po/../src/verbs.cpp:1105 +#, c-format +msgid "Raised layer %s." +msgstr "Höjde lager %s" + +#: ../../po/../src/verbs.cpp:1109 +#, c-format +msgid "Lowered layer %s." +msgstr "Sänkte lager %s" + +#: ../../po/../src/verbs.cpp:1118 +msgid "Cannot move layer any further." +msgstr "" + +#. TRANSLATORS: this means "The layer has been deleted." +#: ../../po/../src/verbs.cpp:1148 +msgid "Deleted layer." +msgstr "Raderade lagret." + +#: ../../po/../src/verbs.cpp:1544 +msgid "" +"You need to connect to a Jabber server before sharing a document with " +"another user." +msgstr "" + +#: ../../po/../src/verbs.cpp:1559 +msgid "" +"You need to connect to a Jabber server before sharing a document with a " +"chatroom." +msgstr "" + +#: ../../po/../src/verbs.cpp:1569 +msgid "XML node tracker has not been initialized; nothing to dump" +msgstr "" + +#. TRANSLATORS: If you have translated the keys.svg file to your language, then +#. translate this string as "keys.LANG.svg" (where LANG is your language code); +#. otherwise leave as "keys.svg". +#: ../../po/../src/verbs.cpp:1631 +msgid "keys.svg" +msgstr "" + +#. TRANSLATORS: If you have translated the tutorial-basic.svg file to your language, +#. then translate this string as "tutorial-basic.LANG.svg" (where LANG is your language +#. code); otherwise leave as "tutorial-basic.svg". +#: ../../po/../src/verbs.cpp:1667 +msgid "tutorial-basic.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1671 +msgid "tutorial-shapes.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1675 +msgid "tutorial-advanced.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1679 +msgid "tutorial-tracing.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1683 +msgid "tutorial-calligraphy.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1687 +msgid "tutorial-elements.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1691 +msgid "tutorial-tips.svg" +msgstr "" + +#: ../../po/../src/verbs.cpp:1842 +msgid "Does nothing" +msgstr "Gör inget" + +#. File +#: ../../po/../src/verbs.cpp:1845 +#, fuzzy +msgid "Default" +msgstr "Standardalternativ" + +#: ../../po/../src/verbs.cpp:1845 +msgid "Create new document from default template" +msgstr "Skapa nytt dokument frÃ¥n standard mallen" + +#: ../../po/../src/verbs.cpp:1847 +msgid "_Open..." +msgstr "_Öppna..." + +#: ../../po/../src/verbs.cpp:1848 +msgid "Open existing document" +msgstr "Öppna befintligt dokument" + +#: ../../po/../src/verbs.cpp:1849 +msgid "Re_vert" +msgstr "Återställ" + +#: ../../po/../src/verbs.cpp:1850 +msgid "Revert to the last saved version of document (changes will be lost)" +msgstr "" +"Återställ till den senast sparade versionen av dokumentet (alla ändringar " +"kommer att gÃ¥ förlorade)" + +#: ../../po/../src/verbs.cpp:1851 +msgid "_Save" +msgstr "_Spara" + +#: ../../po/../src/verbs.cpp:1851 +msgid "Save document" +msgstr "Spara dokument" + +#: ../../po/../src/verbs.cpp:1853 +msgid "Save _As..." +msgstr "Spara so_m..." + +#: ../../po/../src/verbs.cpp:1854 +msgid "Save document under new name" +msgstr "Spara dokument med nytt namn" + +#: ../../po/../src/verbs.cpp:1855 +msgid "_Print..." +msgstr "Skriv _ut..." + +#: ../../po/../src/verbs.cpp:1855 +msgid "Print document" +msgstr "Skriv ut dokument" + +#. TRANSLATORS: "Vacuum Defs" means "Clean up defs" (so as to remove unused definitions) +#: ../../po/../src/verbs.cpp:1858 +msgid "Vac_uum Defs" +msgstr "" + +#: ../../po/../src/verbs.cpp:1858 +msgid "Remove unused predefined items from the <defs> of the document" +msgstr "" + +#: ../../po/../src/verbs.cpp:1860 +#, fuzzy +msgid "Print _Direct" +msgstr "Skriv ut direkt..." + +#: ../../po/../src/verbs.cpp:1861 +#, fuzzy +msgid "Print directly without prompting to a file or pipe" +msgstr "Skriv ut direkt till fil eller rör" + +#: ../../po/../src/verbs.cpp:1862 +#, fuzzy +msgid "Print Previe_w" +msgstr "Förhandsgranska" + +#: ../../po/../src/verbs.cpp:1863 +msgid "Preview document printout" +msgstr "Förhandsgranska dokumentutskrift" + +#: ../../po/../src/verbs.cpp:1864 +msgid "_Import..." +msgstr "_Importera..." + +#: ../../po/../src/verbs.cpp:1865 +msgid "Import bitmap or SVG image into document" +msgstr "Importera bitmappsbild eller SVG-bild till dokument" + +#: ../../po/../src/verbs.cpp:1866 +msgid "_Export Bitmap..." +msgstr "_Exportera bitmappbild..." + +#: ../../po/../src/verbs.cpp:1867 +#, fuzzy +msgid "Export document or selection as a bitmap image" +msgstr "Exportera dokument eller markering som PNG-bitmappsbild" + +#: ../../po/../src/verbs.cpp:1868 +msgid "N_ext Window" +msgstr "Nästa fönster" + +#: ../../po/../src/verbs.cpp:1869 +msgid "Switch to the next document window" +msgstr "Växla till nästa dokumentfönster" + +#: ../../po/../src/verbs.cpp:1870 +msgid "P_revious Window" +msgstr "FöregÃ¥ende fönster" + +#: ../../po/../src/verbs.cpp:1871 +msgid "Switch to the previous document window" +msgstr "Växla till föregÃ¥ende dokumentfönster" + +#: ../../po/../src/verbs.cpp:1872 +msgid "_Close" +msgstr "Stän_g" + +#: ../../po/../src/verbs.cpp:1873 +msgid "Close window" +msgstr "Stäng fönster" + +#: ../../po/../src/verbs.cpp:1874 +msgid "_Quit" +msgstr "_Avsluta" + +#: ../../po/../src/verbs.cpp:1874 +msgid "Quit Inkscape" +msgstr "Avsluta Inkscape" + +#. Edit +#: ../../po/../src/verbs.cpp:1877 +msgid "_Undo" +msgstr "_Ångra" + +#: ../../po/../src/verbs.cpp:1877 +msgid "Undo last action" +msgstr "Ångra senaste Ã¥tgärd" + +#: ../../po/../src/verbs.cpp:1879 +msgid "_Redo" +msgstr "Gör o_m" + +#: ../../po/../src/verbs.cpp:1880 +msgid "Do again last undone action" +msgstr "Gör om senast Ã¥ngrade Ã¥tgärden" + +#: ../../po/../src/verbs.cpp:1881 +msgid "Cu_t" +msgstr "Klipp _ut" + +#: ../../po/../src/verbs.cpp:1882 +msgid "Cut selection to clipboard" +msgstr "Klipp ut markerade objekt till urklipp" + +#: ../../po/../src/verbs.cpp:1883 +msgid "_Copy" +msgstr "_Kopiera" + +#: ../../po/../src/verbs.cpp:1884 +msgid "Copy selection to clipboard" +msgstr "Kopiera markerade objekt till urklipp" + +#: ../../po/../src/verbs.cpp:1885 +msgid "_Paste" +msgstr "Klistra _in" + +#: ../../po/../src/verbs.cpp:1886 +#, fuzzy +msgid "Paste objects from clipboard to mouse point" +msgstr "Klistra in objekt frÃ¥n urklipp till muspekare" + +#: ../../po/../src/verbs.cpp:1887 +#, fuzzy +msgid "Paste _Style" +msgstr "Genomstrykningsstil" + +#: ../../po/../src/verbs.cpp:1888 +#, fuzzy +msgid "Apply style of the copied object to selection" +msgstr "Kopiera markerade objekt till urklipp" + +#: ../../po/../src/verbs.cpp:1889 +#, fuzzy +msgid "Paste _In Place" +msgstr "Genomstrykningsstil" + +#: ../../po/../src/verbs.cpp:1890 +#, fuzzy +msgid "Paste objects from clipboard to the original location" +msgstr "Justera objekt mot horisontella mitten" + +#: ../../po/../src/verbs.cpp:1891 +msgid "_Delete" +msgstr "_Ta bort" + +#: ../../po/../src/verbs.cpp:1892 +msgid "Delete selection" +msgstr "Ta bort markering" + +#: ../../po/../src/verbs.cpp:1893 +#, fuzzy +msgid "Duplic_ate" +msgstr "MÃ¥ngfaldiga" + +#: ../../po/../src/verbs.cpp:1894 +#, fuzzy +msgid "Duplicate selected objects" +msgstr "MÃ¥ngfaldiga markerade objekt" + +#: ../../po/../src/verbs.cpp:1895 +msgid "Clo_ne" +msgstr "Klona" + +#: ../../po/../src/verbs.cpp:1896 +msgid "Create a clone of selected object (a copy linked to the original)" +msgstr "Klonar markerat objekt (en kopia länkad till originalet)" + +#: ../../po/../src/verbs.cpp:1897 +#, fuzzy +msgid "Unlin_k Clone" +msgstr "Avlänka klon" + +#: ../../po/../src/verbs.cpp:1898 +msgid "Cut the clone's link to its original" +msgstr "Bryt klonens länk till originalet" + +#: ../../po/../src/verbs.cpp:1899 +msgid "Select _Original" +msgstr "Markera originalet" + +#: ../../po/../src/verbs.cpp:1900 +msgid "Select the object to which the clone is linked" +msgstr "Markera objektet som klonen är länkad till" + +#. TRANSLATORS: Convert selection to a rectangle with tiled pattern fill +#: ../../po/../src/verbs.cpp:1902 +#, fuzzy +msgid "O_bjects to Pattern" +msgstr "Objekttransformering" + +#: ../../po/../src/verbs.cpp:1903 +msgid "Convert selection to a rectangle with tiled pattern fill" +msgstr "" + +#. TRANSLATORS: Extract objects from a tiled pattern fill +#: ../../po/../src/verbs.cpp:1905 +#, fuzzy +msgid "Pattern to Ob_jects" +msgstr "Platta till objekt" + +#: ../../po/../src/verbs.cpp:1906 +msgid "Extract objects from a tiled pattern fill" +msgstr "" + +#: ../../po/../src/verbs.cpp:1907 +#, fuzzy +msgid "Clea_r All" +msgstr "Töm allt" + +#: ../../po/../src/verbs.cpp:1908 +msgid "Delete all objects from document" +msgstr "Ta bort alla objekt frÃ¥n dokumentet" + +#: ../../po/../src/verbs.cpp:1909 +#, fuzzy +msgid "Select Al_l" +msgstr "Markera allt" + +#: ../../po/../src/verbs.cpp:1910 +#, fuzzy +msgid "Select all objects or all nodes" +msgstr "Markera alla objekt i dokumentet" + +#: ../../po/../src/verbs.cpp:1911 +#, fuzzy +msgid "Select All in All La_yers" +msgstr "Markera" + +#: ../../po/../src/verbs.cpp:1912 +#, fuzzy +msgid "Select all objects in all visible and unlocked layers" +msgstr "Markera alla objekt i dokumentet" + +#: ../../po/../src/verbs.cpp:1913 +#, fuzzy +msgid "In_vert Selection" +msgstr "Markering" + +#: ../../po/../src/verbs.cpp:1914 +msgid "Invert selection (unselect what is selected and select everything else)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1915 +msgid "Invert in All Layers" +msgstr "" + +#: ../../po/../src/verbs.cpp:1916 +msgid "Invert selection in all visible and unlocked layers" +msgstr "" + +#: ../../po/../src/verbs.cpp:1917 +msgid "D_eselect" +msgstr "Avmarkera" + +#: ../../po/../src/verbs.cpp:1918 +msgid "Deselect any selected objects or nodes" +msgstr "Avmarkerar alla markerade objekt eller punkter" + +#. Selection +#: ../../po/../src/verbs.cpp:1921 +#, fuzzy +msgid "Raise to _Top" +msgstr "Placera markeringen överst" + +#: ../../po/../src/verbs.cpp:1922 +msgid "Raise selection to top" +msgstr "Placera markeringen överst" + +#: ../../po/../src/verbs.cpp:1923 +#, fuzzy +msgid "Lower to _Bottom" +msgstr "placera markeringen nederst" + +#: ../../po/../src/verbs.cpp:1924 +#, fuzzy +msgid "Lower selection to bottom" +msgstr "placera markeringen nederst" + +#: ../../po/../src/verbs.cpp:1925 +#, fuzzy +msgid "_Raise" +msgstr "Höj" + +#: ../../po/../src/verbs.cpp:1926 +#, fuzzy +msgid "Raise selection one step" +msgstr "Placera markeringen överst" + +#: ../../po/../src/verbs.cpp:1927 +#, fuzzy +msgid "_Lower" +msgstr "Sänk" + +#: ../../po/../src/verbs.cpp:1928 +#, fuzzy +msgid "Lower selection one step" +msgstr "Sänk markeringen ett lager" + +#: ../../po/../src/verbs.cpp:1929 +msgid "_Group" +msgstr "_Gruppera" + +#: ../../po/../src/verbs.cpp:1930 +msgid "Group selected objects" +msgstr "Gruppera markerade objekt" + +#: ../../po/../src/verbs.cpp:1932 +#, fuzzy +msgid "Ungroup selected groups" +msgstr "Avgruppera markerad(e) grupp(er)" + +#: ../../po/../src/verbs.cpp:1934 +#, fuzzy +msgid "_Put on Path" +msgstr "Konvertera markerat objekt till slinga" + +#: ../../po/../src/verbs.cpp:1935 +#, fuzzy +msgid "Put text on path" +msgstr "Konvertera markerat objekt till slinga" + +#: ../../po/../src/verbs.cpp:1936 +#, fuzzy +msgid "_Remove from Path" +msgstr "Ta bort transformering" + +#: ../../po/../src/verbs.cpp:1937 +#, fuzzy +msgid "Remove text from path" +msgstr "Konvertera markerat objekt till slinga" + +#: ../../po/../src/verbs.cpp:1938 +msgid "Remove Manual _Kerns" +msgstr "" + +#. TRANSLATORS: "glyph": An image used in the visual representation of characters; +#. roughly speaking, how a character looks. A font is a set of glyphs. +#: ../../po/../src/verbs.cpp:1941 +#, fuzzy +msgid "Remove all manual kerns and glyph rotations from a text object" +msgstr "Ta bort transformeringar frÃ¥n objekt" + +#: ../../po/../src/verbs.cpp:1943 +#, fuzzy +msgid "_Union" +msgstr "ingen" + +#: ../../po/../src/verbs.cpp:1944 +#, fuzzy +msgid "Union of selected objects" +msgstr "Avgruppera markerade objekt" + +#: ../../po/../src/verbs.cpp:1945 +#, fuzzy +msgid "_Intersection" +msgstr "_Interaktiv" + +#: ../../po/../src/verbs.cpp:1946 +#, fuzzy +msgid "Intersection of selected objects" +msgstr "Ta bort markerade objekt" + +#: ../../po/../src/verbs.cpp:1947 +#, fuzzy +msgid "_Difference" +msgstr "Grad" + +#: ../../po/../src/verbs.cpp:1948 +#, fuzzy +msgid "Difference of selected objects (bottom minus top)" +msgstr "Ta bort markerade objekt" + +#: ../../po/../src/verbs.cpp:1949 +#, fuzzy +msgid "E_xclusion" +msgstr "Expansion" + +#: ../../po/../src/verbs.cpp:1950 +#, fuzzy +msgid "Exclusive OR of selected objects" +msgstr "Redigera layout pÃ¥ markerade objekt" + +#: ../../po/../src/verbs.cpp:1951 +#, fuzzy +msgid "Di_vision" +msgstr "MÃ¥tt" + +#: ../../po/../src/verbs.cpp:1952 +msgid "Cut the bottom object into pieces" +msgstr "" + +#. TRANSLATORS: "to cut a path" is not the same as "to break a path apart" - see the +#. Advanced tutorial for more info +#: ../../po/../src/verbs.cpp:1955 +#, fuzzy +msgid "Cut _Path" +msgstr "SlÃ¥ samman markerade slingor" + +#: ../../po/../src/verbs.cpp:1956 +msgid "Cut the bottom object's stroke into pieces, removing fill" +msgstr "" + +#. TRANSLATORS: "outset": expand a shape by offsetting the object's path, +#. i.e. by displacing it perpendicular to the path in each point. +#. See also the Advanced Tutorial for explanation. +#: ../../po/../src/verbs.cpp:1960 +#, fuzzy +msgid "Outs_et" +msgstr "SlÃ¥ samman markerade slingor" + +#: ../../po/../src/verbs.cpp:1961 +#, fuzzy +msgid "Outset selected paths" +msgstr "SlÃ¥ samman markerade slingor" + +#: ../../po/../src/verbs.cpp:1963 +#, fuzzy +msgid "O_utset Path by 1 px" +msgstr "SlÃ¥ samman markerade slingor" + +#: ../../po/../src/verbs.cpp:1964 +#, fuzzy +msgid "Outset selected paths by 1 px" +msgstr "SlÃ¥ samman markerade slingor" + +#: ../../po/../src/verbs.cpp:1966 +#, fuzzy +msgid "O_utset Path by 10 px" +msgstr "SlÃ¥ samman markerade slingor" + +#: ../../po/../src/verbs.cpp:1967 +#, fuzzy +msgid "Outset selected paths by 10 px" +msgstr "SlÃ¥ samman markerade slingor" + +#. TRANSLATORS: "inset": contract a shape by offsetting the object's path, +#. i.e. by displacing it perpendicular to the path in each point. +#. See also the Advanced Tutorial for explanation. +#: ../../po/../src/verbs.cpp:1971 +msgid "I_nset" +msgstr "" + +#: ../../po/../src/verbs.cpp:1972 +#, fuzzy +msgid "Inset selected paths" +msgstr "SlÃ¥ samman markerade slingor" + +#: ../../po/../src/verbs.cpp:1974 +#, fuzzy +msgid "I_nset Path by 1 px" +msgstr "SlÃ¥ samman markerade slingor" + +#: ../../po/../src/verbs.cpp:1975 +#, fuzzy +msgid "Inset selected paths by 1 px" +msgstr "SlÃ¥ samman markerade slingor" + +#: ../../po/../src/verbs.cpp:1977 +#, fuzzy +msgid "I_nset Path by 10 px" +msgstr "SlÃ¥ samman markerade slingor" + +#: ../../po/../src/verbs.cpp:1978 +#, fuzzy +msgid "Inset selected paths by 10 px" +msgstr "SlÃ¥ samman markerade slingor" + +#: ../../po/../src/verbs.cpp:1980 +#, fuzzy +msgid "D_ynamic Offset" +msgstr "Dynamisk ifyllning" + +#: ../../po/../src/verbs.cpp:1980 +#, fuzzy +msgid "Create a dynamic offset object" +msgstr "Skapa och redigera textobjekt" + +#: ../../po/../src/verbs.cpp:1982 +msgid "_Linked Offset" +msgstr "" + +#: ../../po/../src/verbs.cpp:1983 +msgid "Create a dynamic offset object linked to the original path" +msgstr "" + +#: ../../po/../src/verbs.cpp:1985 +#, fuzzy +msgid "_Stroke to Path" +msgstr "GenomstrykningsmÃ¥lning" + +#: ../../po/../src/verbs.cpp:1986 +#, fuzzy +msgid "Convert selected strokes to paths" +msgstr "Konvertera markerat objekt till slinga" + +#: ../../po/../src/verbs.cpp:1987 +#, fuzzy +msgid "Si_mplify" +msgstr "SlÃ¥ samman markerade slingor" + +#: ../../po/../src/verbs.cpp:1988 +#, fuzzy +msgid "Simplify selected paths by removing extra nodes" +msgstr "SlÃ¥ samman markerade slingor" + +#: ../../po/../src/verbs.cpp:1989 +#, fuzzy +msgid "_Reverse" +msgstr "Filter" + +#: ../../po/../src/verbs.cpp:1990 +#, fuzzy +msgid "Reverses the direction of selected paths; useful for flipping markers" +msgstr "Ta bort markerade objekt" + +#. TRANSLATORS: "to trace" means "to convert a bitmap to vector graphics" (to vectorize) +#: ../../po/../src/verbs.cpp:1992 +#, fuzzy +msgid "_Trace Bitmap" +msgstr "Trasig bitmappsbild" + +#: ../../po/../src/verbs.cpp:1993 +#, fuzzy +msgid "Convert bitmap object to paths" +msgstr "Konvertera markerat objekt till slinga" + +#: ../../po/../src/verbs.cpp:1994 +#, fuzzy +msgid "_Make a Bitmap Copy" +msgstr "Trasig bitmappsbild" + +#: ../../po/../src/verbs.cpp:1995 +#, fuzzy +msgid "Export selection to a bitmap and insert it into document" +msgstr "Importera bitmappsbild eller SVG-bild till dokument" + +#: ../../po/../src/verbs.cpp:1996 +msgid "_Combine" +msgstr "_SlÃ¥ samman" + +#: ../../po/../src/verbs.cpp:1997 +msgid "Combine several paths into one" +msgstr "" + +#. TRANSLATORS: "to cut a path" is not the same as "to break a path apart" - see the +#. Advanced tutorial for more info +#: ../../po/../src/verbs.cpp:2000 +#, fuzzy +msgid "Break _Apart" +msgstr "Dela upp" + +#: ../../po/../src/verbs.cpp:2001 +#, fuzzy +msgid "Break selected paths into subpaths" +msgstr "Dela upp markerad slinga till underslingor" + +#: ../../po/../src/verbs.cpp:2002 +#, fuzzy +msgid "Gri_d Arrange..." +msgstr "_Arrangera" + +#: ../../po/../src/verbs.cpp:2003 +msgid "Arrange selection in grid pattern" +msgstr "" + +#. Layer +#: ../../po/../src/verbs.cpp:2005 +msgid "_Add Layer..." +msgstr "Lägg till lager" + +#: ../../po/../src/verbs.cpp:2006 +msgid "Create a new layer" +msgstr "Skapar ett nytt lager" + +#: ../../po/../src/verbs.cpp:2007 +#, fuzzy +msgid "Re_name Layer..." +msgstr "Höj nod" + +#: ../../po/../src/verbs.cpp:2008 +#, fuzzy +msgid "Rename the current layer" +msgstr "Markera" + +#: ../../po/../src/verbs.cpp:2009 +msgid "Switch to Layer Abov_e" +msgstr "Växla till lagret över" + +#: ../../po/../src/verbs.cpp:2010 +msgid "Switch to the layer above the current" +msgstr "Växla till lagret över det aktuella" + +#: ../../po/../src/verbs.cpp:2011 +msgid "Switch to Layer Belo_w" +msgstr "Växla till lagret under" + +#: ../../po/../src/verbs.cpp:2012 +msgid "Switch to the layer below the current" +msgstr "Växla till lagret under det aktuella" + +#: ../../po/../src/verbs.cpp:2013 +msgid "Move Selection to Layer Abo_ve" +msgstr "Flytta markering till lagret över" + +#: ../../po/../src/verbs.cpp:2014 +msgid "Move selection to the layer above the current" +msgstr "Flytta markering till lagret över det aktuella" + +#: ../../po/../src/verbs.cpp:2015 +msgid "Move Selection to Layer Bel_ow" +msgstr "Flytta markering till lagret under" + +#: ../../po/../src/verbs.cpp:2016 +msgid "Move selection to the layer below the current" +msgstr "Flytta markering till lagret under det aktuella" + +#: ../../po/../src/verbs.cpp:2017 +#, fuzzy +msgid "Layer to _Top" +msgstr "Placera markeringen överst" + +#: ../../po/../src/verbs.cpp:2018 +#, fuzzy +msgid "Raise the current layer to the top" +msgstr "Placera markeringen överst" + +#: ../../po/../src/verbs.cpp:2019 +#, fuzzy +msgid "Layer to _Bottom" +msgstr "placera markeringen nederst" + +#: ../../po/../src/verbs.cpp:2020 +#, fuzzy +msgid "Lower the current layer to the bottom" +msgstr "placera markeringen nederst" + +#: ../../po/../src/verbs.cpp:2021 +#, fuzzy +msgid "_Raise Layer" +msgstr "Höj nod" + +#: ../../po/../src/verbs.cpp:2022 +msgid "Raise the current layer" +msgstr "" + +#: ../../po/../src/verbs.cpp:2023 +#, fuzzy +msgid "_Lower Layer" +msgstr "Sänk nod" + +#: ../../po/../src/verbs.cpp:2024 +msgid "Lower the current layer" +msgstr "" + +#: ../../po/../src/verbs.cpp:2025 +#, fuzzy +msgid "_Delete Current Layer" +msgstr "Markera" + +#: ../../po/../src/verbs.cpp:2026 +#, fuzzy +msgid "Delete the current layer" +msgstr "Markera" + +#. Object +#: ../../po/../src/verbs.cpp:2029 +#, fuzzy +msgid "Rotate _90° CW" +msgstr "Rotera 90°" + +#: ../../po/../src/verbs.cpp:2030 +#, fuzzy +msgid "Rotate selection 90° clockwise" +msgstr "Rotera objekt 90 grader medurs" + +#: ../../po/../src/verbs.cpp:2031 +#, fuzzy +msgid "Rotate 9_0° CCW" +msgstr "Rotera 90°" + +#: ../../po/../src/verbs.cpp:2032 +#, fuzzy +msgid "Rotate selection 90° counter-clockwise" +msgstr "Rotera objekt 90 grader medurs" + +#: ../../po/../src/verbs.cpp:2033 +#, fuzzy +msgid "Remove _Transformations" +msgstr "Ta bort transformering" + +#: ../../po/../src/verbs.cpp:2034 +msgid "Remove transformations from object" +msgstr "Ta bort transformeringar frÃ¥n objekt" + +#: ../../po/../src/verbs.cpp:2035 +#, fuzzy +msgid "_Object to Path" +msgstr "Objekttransformering" + +#: ../../po/../src/verbs.cpp:2036 +#, fuzzy +msgid "Convert selected objects to paths" +msgstr "Konvertera markerat objekt till slinga" + +#: ../../po/../src/verbs.cpp:2037 +msgid "_Flow into Frame" +msgstr "" + +#: ../../po/../src/verbs.cpp:2038 +#, fuzzy +msgid "Put text into frames" +msgstr "Konvertera markerat objekt till slinga" + +#: ../../po/../src/verbs.cpp:2039 +#, fuzzy +msgid "_Unflow" +msgstr "_Ångra" + +#: ../../po/../src/verbs.cpp:2040 +msgid "Remove text from frame (creates a single-line text object)" +msgstr "" + +#: ../../po/../src/verbs.cpp:2041 +#, fuzzy +msgid "_Convert to Text" +msgstr "Konvertera markerat objekt till slinga" + +#: ../../po/../src/verbs.cpp:2042 +#, fuzzy +msgid "Convert flowed text to regular text objects (preserves appearance)" +msgstr "Konvertera markerade segment till linjer" + +#: ../../po/../src/verbs.cpp:2044 +#, fuzzy +msgid "Flip _Horizontal" +msgstr "Vänd horisontellt" + +#: ../../po/../src/verbs.cpp:2044 +#, fuzzy +msgid "Flips selected objects horizontally" +msgstr "Vänd markerade objekt horisontellt" + +#: ../../po/../src/verbs.cpp:2047 +#, fuzzy +msgid "Flip _Vertical" +msgstr "Vänd vertikalt" + +#: ../../po/../src/verbs.cpp:2047 +#, fuzzy +msgid "Flips selected objects vertically" +msgstr "Vänd markerade objekt vertikalt" + +#. Tools +#: ../../po/../src/verbs.cpp:2051 +msgid "Select" +msgstr "Markera" + +#: ../../po/../src/verbs.cpp:2052 +msgid "Select and transform objects" +msgstr "Markera och transformera objekt" + +#: ../../po/../src/verbs.cpp:2053 +#, fuzzy +msgid "Node Edit" +msgstr "Nodredigering" + +#: ../../po/../src/verbs.cpp:2054 +#, fuzzy +msgid "Edit path nodes or control handles" +msgstr "Redigera layout pÃ¥ markerade objekt" + +#: ../../po/../src/verbs.cpp:2056 +msgid "Create rectangles and squares" +msgstr "Skapa rektanglar och kvadrater" + +#: ../../po/../src/verbs.cpp:2058 +msgid "Create circles, ellipses, and arcs" +msgstr "Skapa cirklar, ellipser och bÃ¥gar" + +#: ../../po/../src/verbs.cpp:2060 +msgid "Create stars and polygons" +msgstr "Skapa stjärnor och polygoner" + +#: ../../po/../src/verbs.cpp:2062 +msgid "Create spirals" +msgstr "Skapa spiraler" + +#: ../../po/../src/verbs.cpp:2064 +msgid "Draw freehand lines" +msgstr "Rita frihand-linje" + +#: ../../po/../src/verbs.cpp:2066 +msgid "Draw Bezier curves and straight lines" +msgstr "Rita Bezier kurvor och raka linjer" + +#: ../../po/../src/verbs.cpp:2068 +msgid "Draw calligraphic lines" +msgstr "Rita kalligrafiska linjer" + +#: ../../po/../src/verbs.cpp:2070 +msgid "Create and edit text objects" +msgstr "Skapa och redigera textobjekt" + +#: ../../po/../src/verbs.cpp:2072 +#, fuzzy +msgid "Create and edit gradients" +msgstr "Skapa och redigera textobjekt" + +#: ../../po/../src/verbs.cpp:2074 +msgid "Zoom in or out" +msgstr "Zooma in eller ut" + +#: ../../po/../src/verbs.cpp:2076 +msgid "Pick averaged colors from image" +msgstr "Hämta medelfärger frÃ¥n bild" + +#: ../../po/../src/verbs.cpp:2078 +#, fuzzy +msgid "Create connectors" +msgstr "Skapa nytt SVG-dokument" + +#. Tool prefs +#: ../../po/../src/verbs.cpp:2081 +msgid "Selector Preferences" +msgstr "" + +#: ../../po/../src/verbs.cpp:2082 +#, fuzzy +msgid "Open Preferences for the Selector tool" +msgstr "Sodipodi-bildspel" + +#: ../../po/../src/verbs.cpp:2083 +#, fuzzy +msgid "Node Tool Preferences" +msgstr "Verktygsinställningar saknas" + +#: ../../po/../src/verbs.cpp:2084 +#, fuzzy +msgid "Open Preferences for the Node tool" +msgstr "Sodipodi-bildspel" + +#: ../../po/../src/verbs.cpp:2085 +#, fuzzy +msgid "Rectangle Preferences" +msgstr "Rektangelegenskaper" + +#: ../../po/../src/verbs.cpp:2086 +#, fuzzy +msgid "Open Preferences for the Rectangle tool" +msgstr "Sodipodi-bildspel" + +#: ../../po/../src/verbs.cpp:2087 +#, fuzzy +msgid "Ellipse Preferences" +msgstr "Objekt är referens" + +#: ../../po/../src/verbs.cpp:2088 +#, fuzzy +msgid "Open Preferences for the Ellipse tool" +msgstr "Sodipodi-bildspel" + +#: ../../po/../src/verbs.cpp:2089 +#, fuzzy +msgid "Star Preferences" +msgstr "Stjärnegenskaper" + +#: ../../po/../src/verbs.cpp:2090 +#, fuzzy +msgid "Open Preferences for the Star tool" +msgstr "Sodipodi-bildspel" + +#: ../../po/../src/verbs.cpp:2091 +#, fuzzy +msgid "Spiral Preferences" +msgstr "Spiralegenskaper" + +#: ../../po/../src/verbs.cpp:2092 +#, fuzzy +msgid "Open Preferences for the Spiral tool" +msgstr "Sodipodi-bildspel" + +#: ../../po/../src/verbs.cpp:2093 +#, fuzzy +msgid "Pencil Preferences" +msgstr "Objekt är referens" + +#: ../../po/../src/verbs.cpp:2094 +#, fuzzy +msgid "Open Preferences for the Pencil tool" +msgstr "Sodipodi-bildspel" + +#: ../../po/../src/verbs.cpp:2095 +#, fuzzy +msgid "Pen Preferences" +msgstr "Objekt är referens" + +#: ../../po/../src/verbs.cpp:2096 +#, fuzzy +msgid "Open Preferences for the Pen tool" +msgstr "Sodipodi-bildspel" + +#: ../../po/../src/verbs.cpp:2097 +#, fuzzy +msgid "Calligraphic Preferences" +msgstr "Kalligrafisk linje" + +#: ../../po/../src/verbs.cpp:2098 +#, fuzzy +msgid "Open Preferences for the Calligraphy tool" +msgstr "Sodipodi-bildspel" + +#: ../../po/../src/verbs.cpp:2099 +#, fuzzy +msgid "Text Preferences" +msgstr "Objekt är referens" + +#: ../../po/../src/verbs.cpp:2100 +#, fuzzy +msgid "Open Preferences for the Text tool" +msgstr "Sodipodi-bildspel" + +#: ../../po/../src/verbs.cpp:2101 +#, fuzzy +msgid "Gradient Preferences" +msgstr "Objekt är referens" + +#: ../../po/../src/verbs.cpp:2102 +#, fuzzy +msgid "Open Preferences for the Gradient tool" +msgstr "Sodipodi-bildspel" + +#: ../../po/../src/verbs.cpp:2103 +#, fuzzy +msgid "Zoom Preferences" +msgstr "Objekt är referens" + +#: ../../po/../src/verbs.cpp:2104 +#, fuzzy +msgid "Open Preferences for the Zoom tool" +msgstr "Sodipodi-bildspel" + +#: ../../po/../src/verbs.cpp:2105 +#, fuzzy +msgid "Dropper Preferences" +msgstr "Sodipodi-bildspel" + +#: ../../po/../src/verbs.cpp:2106 +#, fuzzy +msgid "Open Preferences for the Dropper tool" +msgstr "Sodipodi-bildspel" + +#: ../../po/../src/verbs.cpp:2107 +#, fuzzy +msgid "Connector Preferences" +msgstr "Stjärnegenskaper" + +#: ../../po/../src/verbs.cpp:2108 +#, fuzzy +msgid "Open Preferences for the Connector tool" +msgstr "Sodipodi-bildspel" + +#. Zoom/View +#: ../../po/../src/verbs.cpp:2111 +#, fuzzy +msgid "Zoom In" +msgstr "Zooma in" + +#: ../../po/../src/verbs.cpp:2111 +msgid "Zoom in" +msgstr "Zooma in" + +#: ../../po/../src/verbs.cpp:2112 +#, fuzzy +msgid "Zoom Out" +msgstr "Zooma ut" + +#: ../../po/../src/verbs.cpp:2112 +msgid "Zoom out" +msgstr "Zooma ut" + +#: ../../po/../src/verbs.cpp:2113 +#, fuzzy +msgid "_Rulers" +msgstr "Filter" + +#: ../../po/../src/verbs.cpp:2113 +#, fuzzy +msgid "Show or hide the canvas rulers" +msgstr "Visa hjälplinjer" + +#: ../../po/../src/verbs.cpp:2114 +msgid "Scroll_bars" +msgstr "" + +#: ../../po/../src/verbs.cpp:2114 +#, fuzzy +msgid "Show or hide the canvas scrollbars" +msgstr "Visa hjälplinjer" + +#: ../../po/../src/verbs.cpp:2115 +#, fuzzy +msgid "_Grid" +msgstr "Rutnät" + +#: ../../po/../src/verbs.cpp:2116 +#, fuzzy +msgid "G_uides" +msgstr "Hjälplinjer" + +#: ../../po/../src/verbs.cpp:2117 +msgid "Nex_t Zoom" +msgstr "" + +#: ../../po/../src/verbs.cpp:2117 +msgid "Next zoom (from the history of zooms)" +msgstr "" + +#: ../../po/../src/verbs.cpp:2119 +msgid "Pre_vious Zoom" +msgstr "" + +#: ../../po/../src/verbs.cpp:2119 +msgid "Previous zoom (from the history of zooms)" +msgstr "" + +#: ../../po/../src/verbs.cpp:2121 +#, fuzzy +msgid "Zoom 1:_1" +msgstr "Zooma till 1:1" + +#: ../../po/../src/verbs.cpp:2121 +msgid "Zoom to 1:1" +msgstr "Zooma till 1:1" + +#: ../../po/../src/verbs.cpp:2123 +#, fuzzy +msgid "Zoom 1:_2" +msgstr "Zooma till 1:2" + +#: ../../po/../src/verbs.cpp:2123 +msgid "Zoom to 1:2" +msgstr "Zooma till 1:2" + +#: ../../po/../src/verbs.cpp:2125 +#, fuzzy +msgid "_Zoom 2:1" +msgstr "Zooma till 2:1" + +#: ../../po/../src/verbs.cpp:2125 +msgid "Zoom to 2:1" +msgstr "Zooma till 2:1" + +#: ../../po/../src/verbs.cpp:2128 +msgid "_Fullscreen" +msgstr "" + +#: ../../po/../src/verbs.cpp:2128 +msgid "Stretch this document window to full screen" +msgstr "" + +#: ../../po/../src/verbs.cpp:2131 +#, fuzzy +msgid "Duplic_ate Window" +msgstr "MÃ¥ngfaldiga nod" + +#: ../../po/../src/verbs.cpp:2131 +#, fuzzy +msgid "Open a new window with the same document" +msgstr "Öppna befintligt SVG-dokument" + +#: ../../po/../src/verbs.cpp:2133 +#, fuzzy +msgid "_New View Preview" +msgstr "Ny förhandsgranskning" + +#: ../../po/../src/verbs.cpp:2134 +#, fuzzy +msgid "New View Preview" +msgstr "Ny förhandsgranskning" + +#. "view_new_preview" +#: ../../po/../src/verbs.cpp:2136 +#, fuzzy +msgid "_Normal" +msgstr "Fraktal" + +#: ../../po/../src/verbs.cpp:2137 +msgid "Switch to normal display mode" +msgstr "" + +#: ../../po/../src/verbs.cpp:2138 +#, fuzzy +msgid "_Outline" +msgstr "Visa kontur" + +#: ../../po/../src/verbs.cpp:2139 +msgid "Switch to outline (wireframe) display mode" +msgstr "" + +#: ../../po/../src/verbs.cpp:2141 +#, fuzzy +msgid "Ico_n Preview" +msgstr "Ny förhandsgranskning" + +#: ../../po/../src/verbs.cpp:2142 +msgid "Open a window to preview items at different icon resolutions" +msgstr "" + +#: ../../po/../src/verbs.cpp:2144 +#, fuzzy +msgid "Zoom to fit page in window" +msgstr "Passa in sidan i fönstret" + +#: ../../po/../src/verbs.cpp:2145 +#, fuzzy +msgid "Page _Width" +msgstr "Ställ in pappersbredden" + +#: ../../po/../src/verbs.cpp:2146 +#, fuzzy +msgid "Zoom to fit page width in window" +msgstr "Passa in sidan i fönstret" + +#: ../../po/../src/verbs.cpp:2148 +#, fuzzy +msgid "Zoom to fit drawing in window" +msgstr "Passa in hela teckningen i fönstret" + +#: ../../po/../src/verbs.cpp:2150 +#, fuzzy +msgid "Zoom to fit selection in window" +msgstr "Passa in hela markeringen i fönstret" + +#. Dialogs +#: ../../po/../src/verbs.cpp:2153 +#, fuzzy +msgid "In_kscape Preferences..." +msgstr "Sodipodi-bildspel" + +#: ../../po/../src/verbs.cpp:2154 +#, fuzzy +msgid "Global Inkscape preferences" +msgstr "Globala visningsinställningar" + +#: ../../po/../src/verbs.cpp:2155 +msgid "_Document Preferences..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2156 +#, fuzzy +msgid "Preferences saved with the document" +msgstr "Öppna befintligt SVG-dokument" + +#: ../../po/../src/verbs.cpp:2157 +#, fuzzy +msgid "_Fill and Stroke..." +msgstr "Fyllning och genomstrykning" + +#: ../../po/../src/verbs.cpp:2158 +#, fuzzy +msgid "Fill and Stroke dialog" +msgstr "Fyllning och genomstrykning" + +#. TRANSLATORS: "Swatches" means: color samples +#: ../../po/../src/verbs.cpp:2160 +#, fuzzy +msgid "S_watches..." +msgstr "Spara som..." + +#: ../../po/../src/verbs.cpp:2161 +msgid "View color swatches" +msgstr "" + +#: ../../po/../src/verbs.cpp:2162 +#, fuzzy +msgid "Transfor_m..." +msgstr "Transform:" + +#: ../../po/../src/verbs.cpp:2163 +#, fuzzy +msgid "Transform dialog" +msgstr "Transformationsfönster" + +#: ../../po/../src/verbs.cpp:2164 +#, fuzzy +msgid "_Align and Distribute..." +msgstr "Justera och distribuera" + +#: ../../po/../src/verbs.cpp:2165 +#, fuzzy +msgid "Align and Distribute dialog" +msgstr "Justera och distribuera" + +#: ../../po/../src/verbs.cpp:2166 +#, fuzzy +msgid "_Text and Font..." +msgstr "Text och typsnitt" + +#: ../../po/../src/verbs.cpp:2167 +#, fuzzy +msgid "Text and Font dialog" +msgstr "Text och typsnitt" + +#: ../../po/../src/verbs.cpp:2168 +#, fuzzy +msgid "_XML Editor..." +msgstr "XML-redigerare" + +#: ../../po/../src/verbs.cpp:2169 +msgid "XML Editor" +msgstr "XML-redigerare" + +#: ../../po/../src/verbs.cpp:2170 +#, fuzzy +msgid "_Find..." +msgstr "Skriv ut..." + +#: ../../po/../src/verbs.cpp:2171 +#, fuzzy +msgid "Find objects in document" +msgstr "Inga toningar i dokument" + +#: ../../po/../src/verbs.cpp:2172 +msgid "_Messages..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2173 +msgid "View debug messages" +msgstr "" + +#: ../../po/../src/verbs.cpp:2174 +#, fuzzy +msgid "S_cripts..." +msgstr "Skriv ut..." + +#: ../../po/../src/verbs.cpp:2175 +#, fuzzy +msgid "Run scripts" +msgstr "Rund anslutning" + +#: ../../po/../src/verbs.cpp:2176 +#, fuzzy +msgid "Show/Hide D_ialogs" +msgstr "Stäng dialogfönster" + +#: ../../po/../src/verbs.cpp:2177 +msgid "Show or hide all active dialogs" +msgstr "" + +#. TRANSLATORS: "Tile clones" means: "Create tiled clones" +#: ../../po/../src/verbs.cpp:2179 +msgid "Tile clones..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2180 +msgid "Create and arrange multiple clones of selection" +msgstr "" + +#: ../../po/../src/verbs.cpp:2181 +#, fuzzy +msgid "_Object Properties..." +msgstr "objektegenskaper" + +#: ../../po/../src/verbs.cpp:2182 +#, fuzzy +msgid "Object Properties dialog" +msgstr "objektegenskaper" + +#: ../../po/../src/verbs.cpp:2185 +msgid "_Connect to Jabber server..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2185 +msgid "Connect to a Jabber server" +msgstr "" + +#: ../../po/../src/verbs.cpp:2187 +#, fuzzy +msgid "Share with _user..." +msgstr "Spara so_m..." + +#: ../../po/../src/verbs.cpp:2187 +msgid "Establish a whiteboard session with another Jabber user" +msgstr "" + +#: ../../po/../src/verbs.cpp:2189 +msgid "Share with _chatroom..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2189 +msgid "" +"Join a chatroom to start a new whiteboard session or join one in progress" +msgstr "" + +#: ../../po/../src/verbs.cpp:2191 +msgid "_Dump XML node tracker" +msgstr "" + +#: ../../po/../src/verbs.cpp:2191 +msgid "Dump the contents of the XML tracker to the console" +msgstr "" + +#: ../../po/../src/verbs.cpp:2193 +msgid "_Open session file..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2193 +msgid "Open and browse through records of past whiteboard sessions" +msgstr "" + +#: ../../po/../src/verbs.cpp:2195 +msgid "Session file playback" +msgstr "" + +#: ../../po/../src/verbs.cpp:2197 +msgid "_Disconnect from session" +msgstr "" + +#: ../../po/../src/verbs.cpp:2199 +msgid "Disconnect from _server" +msgstr "" + +#: ../../po/../src/verbs.cpp:2201 +msgid "_Input Devices..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2202 +msgid "Configure extended input devices" +msgstr "" + +#. Help +#: ../../po/../src/verbs.cpp:2205 +msgid "_Keys and Mouse" +msgstr "" + +#: ../../po/../src/verbs.cpp:2206 +msgid "Key and mouse shortcuts reference" +msgstr "" + +#: ../../po/../src/verbs.cpp:2207 +#, fuzzy +msgid "About E_xtensions" +msgstr "Tillägg" + +#: ../../po/../src/verbs.cpp:2208 +#, fuzzy +msgid "About Extensions..." +msgstr "Tillägg" + +#: ../../po/../src/verbs.cpp:2209 +#, fuzzy +msgid "About _Memory" +msgstr "Om moduler" + +#: ../../po/../src/verbs.cpp:2210 +#, fuzzy +msgid "About Memory..." +msgstr "_Om..." + +#: ../../po/../src/verbs.cpp:2211 +msgid "_About Inkscape" +msgstr "" + +#. "help_about" +#. new HelpVerb(SP_VERB_SHOW_LICENSE, "ShowLicense", N_("Modifying or Redistributing Inkscape"), +#. N_("Show license to modify and/or redistribute Inkscape: GNU GPL"), NULL), +#. Tutorials +#: ../../po/../src/verbs.cpp:2217 +#, fuzzy +msgid "Inkscape: _Basic" +msgstr "Sodipodi-bildspel" + +#: ../../po/../src/verbs.cpp:2218 +msgid "Getting started with Inkscape" +msgstr "" + +#. "tutorial_basic" +#: ../../po/../src/verbs.cpp:2219 +#, fuzzy +msgid "Inkscape: _Shapes" +msgstr "Sodipodi-bildspel" + +#: ../../po/../src/verbs.cpp:2220 +msgid "Using shape tools to create and edit shapes" +msgstr "" + +#: ../../po/../src/verbs.cpp:2221 +#, fuzzy +msgid "Inkscape: _Advanced" +msgstr "Sodipodi-bildspel" + +#: ../../po/../src/verbs.cpp:2222 +#, fuzzy +msgid "Advanced Inkscape topics" +msgstr "Sodipodi-bildspel" + +#. "tutorial_advanced" +#. TRANSLATORS: "to trace" means "to convert a bitmap to vector graphics" (to vectorize) +#: ../../po/../src/verbs.cpp:2224 +#, fuzzy +msgid "Inkscape: T_racing" +msgstr "Sodipodi-bildspel" + +#: ../../po/../src/verbs.cpp:2225 +#, fuzzy +msgid "Using bitmap tracing" +msgstr "Bitmappsstorlek" + +#. "tutorial_tracing" +#: ../../po/../src/verbs.cpp:2226 +#, fuzzy +msgid "Inkscape: _Calligraphy" +msgstr "Sodipodi-bildspel" + +#: ../../po/../src/verbs.cpp:2227 +msgid "Using the Calligraphy pen tool" +msgstr "" + +#: ../../po/../src/verbs.cpp:2228 +msgid "_Elements of Design" +msgstr "" + +#: ../../po/../src/verbs.cpp:2229 +msgid "Principles of design in the tutorial form" +msgstr "" + +#. "tutorial_design" +#: ../../po/../src/verbs.cpp:2230 +msgid "_Tips and Tricks" +msgstr "" + +#: ../../po/../src/verbs.cpp:2231 +msgid "Miscellaneous tips and tricks" +msgstr "" + +#. "tutorial_tips" +#. Effect +#: ../../po/../src/verbs.cpp:2234 +msgid "Previous Effect" +msgstr "" + +#: ../../po/../src/verbs.cpp:2235 +msgid "Repeat the last effect with the same settings" +msgstr "" + +#. "tutorial_tips" +#: ../../po/../src/verbs.cpp:2236 +msgid "Previous Effect Settings..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2237 +msgid "Repeat the last effect with new settings" +msgstr "" + +#: ../../po/../src/widgets/dash-selector.cpp:106 +#, fuzzy +msgid "Dash pattern" +msgstr "Mönster" + +#: ../../po/../src/widgets/dash-selector.cpp:121 +#, fuzzy +msgid "Pattern offset" +msgstr "Mönsterfyllning" + +#: ../../po/../src/widgets/desktop-widget.cpp:240 +#, fuzzy +msgid "Zoom drawing if window size changes" +msgstr "Passa in hela teckningen i fönstret" + +#: ../../po/../src/widgets/desktop-widget.cpp:298 +msgid "Cursor coordinates" +msgstr "" + +#. display the initial welcome message in the statusbar +#: ../../po/../src/widgets/desktop-widget.cpp:324 +msgid "" +"Welcome to Inkscape! Use shape or freehand tools to create objects; " +"use selector (arrow) to move or transform them." +msgstr "" + +#: ../../po/../src/widgets/desktop-widget.cpp:372 +#, c-format +msgid "%s: %d - Inkscape" +msgstr "%s: %d - Inkscape" + +#: ../../po/../src/widgets/desktop-widget.cpp:374 +#, c-format +msgid "%s - Inkscape" +msgstr "%s - Inkscape" + +#: ../../po/../src/widgets/desktop-widget.cpp:532 +#, c-format +msgid "" +"Save changes to document \"%s\" before " +"closing?\n" +"\n" +"If you close without saving, your changes will be discarded." +msgstr "" + +#: ../../po/../src/widgets/desktop-widget.cpp:548 +#: ../../po/../src/widgets/desktop-widget.cpp:612 +msgid "Close _without saving" +msgstr "Stäng _utan att spara" + +#: ../../po/../src/widgets/desktop-widget.cpp:595 +#, c-format +msgid "" +"The file \"%s\" was saved with a " +"format (%s) that may cause data loss!\n" +"\n" +"Do you want to save this file in another format?" +msgstr "" +"Filen \"%s\" sparades med ett format (%" +"s) som kan ha orsakat informationsförlust!\n" +"\n" +"Vill du spara filen i ett annat format?" + +#. Family frame +#: ../../po/../src/widgets/font-selector.cpp:156 +msgid "Font family" +msgstr "Typsnittsfamilj" + +#. Style frame +#: ../../po/../src/widgets/font-selector.cpp:184 +msgid "Style" +msgstr "Stil" + +#: ../../po/../src/widgets/font-selector.cpp:219 +msgid "Font size:" +msgstr "Typsnittsstorlek:" + +#. TRANSLATORS: Test string used in text and font dialog (when no +#. * text has been entered) to get a preview of the font. Choose +#. * some representative characters that users of your locale will be +#. * interested in. +#: ../../po/../src/widgets/font-selector.cpp:554 +msgid "AaBbCcIiPpQq12368.;/()" +msgstr "AaBbCcIiPpQqÅåÄäÖö12368.;/()" + +#: ../../po/../src/widgets/gradient-selector.cpp:137 +#: ../../po/../src/widgets/gradient-toolbar.cpp:524 +#, fuzzy +msgid "Duplicate" +msgstr "MÃ¥ngfaldiga" + +#: ../../po/../src/widgets/gradient-selector.cpp:142 +#: ../../po/../src/widgets/gradient-toolbar.cpp:535 +msgid "Edit..." +msgstr "Redigera..." + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/pservers.html#LinearGradientSpreadMethodAttribute +#: ../../po/../src/widgets/gradient-selector.cpp:159 +msgid "" +"Whether to fill with flat color beyond the ends of the gradient vector " +"(spreadMethod=\"pad\"), or repeat the gradient in the same direction " +"(spreadMethod=\"repeat\"), or repeat the gradient in alternating opposite " +"directions (spreadMethod=\"reflect\")" +msgstr "" + +#: ../../po/../src/widgets/gradient-selector.cpp:165 +#, fuzzy +msgid "none" +msgstr "Ingen" + +#: ../../po/../src/widgets/gradient-selector.cpp:169 +#, fuzzy +msgid "reflected" +msgstr "Först markerad" + +#: ../../po/../src/widgets/gradient-selector.cpp:173 +#, fuzzy +msgid "direct" +msgstr "Rektangel" + +#: ../../po/../src/widgets/gradient-selector.cpp:181 +#, fuzzy +msgid "Repeat:" +msgstr "Återställ" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:217 +msgid "No gradients" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:226 +#, fuzzy +msgid "Nothing selected" +msgstr "Senast markerad" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:237 +#, fuzzy +msgid "No gradients in selection" +msgstr "Ingen toning markerad" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:247 +msgid "Multiple gradients" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:525 +msgid "" +"If the gradient is used by more than one object, create a copy of it for the " +"selected object(s)" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:536 +#, fuzzy +msgid "Edit the stops of the gradient" +msgstr "Linjär toning" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:593 +#: ../../po/../src/widgets/toolbox.cpp:1103 +#: ../../po/../src/widgets/toolbox.cpp:1192 +#: ../../po/../src/widgets/toolbox.cpp:1485 +#: ../../po/../src/widgets/toolbox.cpp:1534 +#: ../../po/../src/widgets/toolbox.cpp:1766 +#: ../../po/../src/widgets/toolbox.cpp:1801 +#: ../../po/../src/widgets/toolbox.cpp:2331 +#: ../../po/../src/widgets/toolbox.cpp:2370 +msgid "New:" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:606 +#, fuzzy +msgid "Create linear gradient" +msgstr "Linjär toning" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:620 +msgid "Create radial (elliptic or circular) gradient" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:635 +#, fuzzy +msgid "on" +msgstr "Ner" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:648 +#, fuzzy +msgid "Create gradient in the fill" +msgstr "Toningsvektor" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:662 +msgid "Create gradient in the stroke" +msgstr "" + +#. FIXME: implement averaging of all parameters for multiple selected stars +#. gtk_label_set_markup(GTK_LABEL(l), _("Average:")); +#. FIXME: implement averaging of all parameters for multiple selected +#. gtk_label_set_markup(GTK_LABEL(l), _("Average:")); +#: ../../po/../src/widgets/gradient-toolbar.cpp:676 +#: ../../po/../src/widgets/toolbox.cpp:1105 +#: ../../po/../src/widgets/toolbox.cpp:1124 +#: ../../po/../src/widgets/toolbox.cpp:1493 +#: ../../po/../src/widgets/toolbox.cpp:1518 +#: ../../po/../src/widgets/toolbox.cpp:1768 +#: ../../po/../src/widgets/toolbox.cpp:1787 +#: ../../po/../src/widgets/toolbox.cpp:2334 +#: ../../po/../src/widgets/toolbox.cpp:2354 +#, fuzzy +msgid "Change:" +msgstr "Ändra" + +#: ../../po/../src/widgets/gradient-vector.cpp:269 +msgid "No gradients in document" +msgstr "Inga toningar i dokument" + +#: ../../po/../src/widgets/gradient-vector.cpp:275 +msgid "No gradient selected" +msgstr "Ingen toning markerad" + +#: ../../po/../src/widgets/gradient-vector.cpp:532 +#, fuzzy +msgid "No stops in gradient" +msgstr "Linjär toning" + +#. TRANSLATORS: "Stop" means: a "phase" of a gradient +#: ../../po/../src/widgets/gradient-vector.cpp:794 +#, fuzzy +msgid "Add stop" +msgstr "skrivbord" + +#: ../../po/../src/widgets/gradient-vector.cpp:797 +msgid "Add another control stop to gradient" +msgstr "" + +#: ../../po/../src/widgets/gradient-vector.cpp:799 +#, fuzzy +msgid "Delete stop" +msgstr "Ta bort markering" + +#: ../../po/../src/widgets/gradient-vector.cpp:802 +msgid "Delete current control stop from gradient" +msgstr "" + +#. Label +#: ../../po/../src/widgets/gradient-vector.cpp:813 +msgid "Offset:" +msgstr "" + +#. TRANSLATORS: "Stop" means: a "phase" of a gradient +#: ../../po/../src/widgets/gradient-vector.cpp:858 +#, fuzzy +msgid "Stop Color" +msgstr "Startfärg" + +#: ../../po/../src/widgets/gradient-vector.cpp:887 +msgid "Gradient editor" +msgstr "Toningseditor" + +#: ../../po/../src/widgets/layer-selector.cpp:119 +#, fuzzy +msgid "Toggle current layer visibility" +msgstr "Dokumentnamn:" + +#: ../../po/../src/widgets/layer-selector.cpp:139 +#, fuzzy +msgid "Lock or unlock current layer" +msgstr "Dokumentnamn:" + +#: ../../po/../src/widgets/layer-selector.cpp:142 +#, fuzzy +msgid "Current layer" +msgstr "Dokumentnamn:" + +#: ../../po/../src/widgets/layer-selector.cpp:553 +msgid "(root)" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:182 +#: ../../po/../src/widgets/paint-selector.cpp:561 +msgid "No paint" +msgstr "Ingen mÃ¥lning" + +#: ../../po/../src/widgets/paint-selector.cpp:184 +#: ../../po/../src/widgets/paint-selector.cpp:629 +#, fuzzy +msgid "Flat color" +msgstr "Enfärgad" + +#: ../../po/../src/widgets/paint-selector.cpp:186 +#: ../../po/../src/widgets/paint-selector.cpp:696 +msgid "Linear gradient" +msgstr "Linjär toning" + +#: ../../po/../src/widgets/paint-selector.cpp:188 +#: ../../po/../src/widgets/paint-selector.cpp:699 +msgid "Radial gradient" +msgstr "Radiell toning" + +#: ../../po/../src/widgets/paint-selector.cpp:192 +msgid "Unset paint (make it undefined so it can be inherited)" +msgstr "" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/painting.html#FillRuleProperty +#: ../../po/../src/widgets/paint-selector.cpp:204 +msgid "" +"Any path self-intersections or subpaths create holes in the fill (fill-rule: " +"evenodd)" +msgstr "" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/painting.html#FillRuleProperty +#: ../../po/../src/widgets/paint-selector.cpp:215 +msgid "" +"Fill is solid unless a subpath is counterdirectional (fill-rule: nonzero)" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:528 +msgid "No objects" +msgstr "Inga objekt" + +#: ../../po/../src/widgets/paint-selector.cpp:539 +msgid "Multiple styles" +msgstr "Flera stilar" + +#: ../../po/../src/widgets/paint-selector.cpp:550 +msgid "Paint is undefined" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:757 +msgid "No patterns in document" +msgstr "Inga mönster i dokument" + +#: ../../po/../src/widgets/paint-selector.cpp:872 +msgid "" +"Use Edit > Object(s) to Pattern to create a new pattern from " +"selection." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:426 +msgid "Now stroke width is scaled when objects are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:428 +msgid "Now stroke width is not scaled when objects are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:436 +msgid "" +"Now rounded rectangle corners are scaled when rectangles are " +"scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:438 +msgid "" +"Now rounded rectangle corners are not scaled when rectangles " +"are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:446 +msgid "" +"Now gradients are transformed along with their objects when " +"those are transformed (moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:448 +msgid "" +"Now gradients remain fixed when objects are transformed " +"(moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:456 +msgid "" +"Now patterns are transformed along with their objects when " +"those are transformed (moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:458 +msgid "" +"Now patterns remain fixed when objects are transformed (moved, " +"scaled, rotated, or skewed)." +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:506 +#, fuzzy +msgid "select_toolbar|X" +msgstr "Markera" + +#: ../../po/../src/widgets/select-toolbar.cpp:506 +#, fuzzy +msgid "Horizontal coordinate of selection" +msgstr "Horisontellt mittpunktsvärde" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:511 +#, fuzzy +msgid "select_toolbar|Y" +msgstr "Markera" + +#: ../../po/../src/widgets/select-toolbar.cpp:511 +msgid "Vertical coordinate of selection" +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:517 +#, fuzzy +msgid "select_toolbar|W" +msgstr "Markera" + +#: ../../po/../src/widgets/select-toolbar.cpp:517 +msgid "Width of selection" +msgstr "Markeringens bredd" + +#: ../../po/../src/widgets/select-toolbar.cpp:525 +msgid "Change both width and height by the same proportion" +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:534 +#, fuzzy +msgid "select_toolbar|H" +msgstr "Markera" + +#: ../../po/../src/widgets/select-toolbar.cpp:534 +msgid "Height of selection" +msgstr "Markeringens höjd" + +#: ../../po/../src/widgets/sp-color-gtkselector.cpp:62 +msgid "System" +msgstr "" + +#: ../../po/../src/widgets/sp-color-notebook.cpp:322 +msgid "RGBA_:" +msgstr "RGBA:" + +#: ../../po/../src/widgets/sp-color-notebook.cpp:330 +msgid "Hexadecimal RGBA value of the color" +msgstr "Hexadecimalt RGBA-värde för färgen" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "RGB" +msgstr "RGB" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +#, fuzzy +msgid "HSL" +msgstr "HSV" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "CMYK" +msgstr "CMYK" + +#: ../../po/../src/widgets/sp-color-scales.cpp:397 +msgid "_R" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:398 +#: ../../po/../src/widgets/sp-color-scales.cpp:399 +msgid "Red" +msgstr "Röd" + +#: ../../po/../src/widgets/sp-color-scales.cpp:400 +msgid "_G" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:401 +#: ../../po/../src/widgets/sp-color-scales.cpp:402 +msgid "Green" +msgstr "Grön" + +#: ../../po/../src/widgets/sp-color-scales.cpp:403 +msgid "_B" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:404 +#: ../../po/../src/widgets/sp-color-scales.cpp:405 +msgid "Blue" +msgstr "BlÃ¥" + +#. Label +#: ../../po/../src/widgets/sp-color-scales.cpp:406 +#: ../../po/../src/widgets/sp-color-scales.cpp:432 +#: ../../po/../src/widgets/sp-color-scales.cpp:463 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:141 +msgid "_A" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:407 +#: ../../po/../src/widgets/sp-color-scales.cpp:408 +#: ../../po/../src/widgets/sp-color-scales.cpp:433 +#: ../../po/../src/widgets/sp-color-scales.cpp:434 +#: ../../po/../src/widgets/sp-color-scales.cpp:464 +#: ../../po/../src/widgets/sp-color-scales.cpp:465 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:151 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:163 +msgid "Alpha (opacity)" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:423 +msgid "_H" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:424 +#: ../../po/../src/widgets/sp-color-scales.cpp:425 +#, fuzzy +msgid "Hue" +msgstr "Nyans:" + +#: ../../po/../src/widgets/sp-color-scales.cpp:426 +msgid "_S" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:427 +#: ../../po/../src/widgets/sp-color-scales.cpp:428 +msgid "Saturation" +msgstr "Mättnad" + +#: ../../po/../src/widgets/sp-color-scales.cpp:429 +msgid "_L" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:430 +#: ../../po/../src/widgets/sp-color-scales.cpp:431 +#, fuzzy +msgid "Lightness" +msgstr "höger" + +#: ../../po/../src/widgets/sp-color-scales.cpp:451 +msgid "_C" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:452 +#: ../../po/../src/widgets/sp-color-scales.cpp:453 +#, fuzzy +msgid "Cyan" +msgstr "Cyan" + +#: ../../po/../src/widgets/sp-color-scales.cpp:454 +msgid "_M" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:455 +#: ../../po/../src/widgets/sp-color-scales.cpp:456 +msgid "Magenta" +msgstr "Magenta" + +#: ../../po/../src/widgets/sp-color-scales.cpp:457 +msgid "_Y" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:458 +#: ../../po/../src/widgets/sp-color-scales.cpp:459 +msgid "Yellow" +msgstr "Gul" + +#: ../../po/../src/widgets/sp-color-scales.cpp:460 +msgid "_K" +msgstr "" + +#: ../../po/../src/widgets/sp-color-selector.cpp:71 +msgid "Unnamed" +msgstr "Namnlös" + +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:68 +msgid "Wheel" +msgstr "" + +#: ../../po/../src/widgets/sp-xmlview-attr-list.cpp:53 +msgid "Attribute" +msgstr "Attribut" + +#: ../../po/../src/widgets/sp-xmlview-attr-list.cpp:54 +msgid "Value" +msgstr "Värde" + +#: ../../po/../src/widgets/toolbox.cpp:424 +msgid "Insert new nodes into selected segments" +msgstr "Infoga nya noder i markerade segment" + +#: ../../po/../src/widgets/toolbox.cpp:426 +msgid "Delete selected nodes" +msgstr "Ta bort markerade noder" + +#: ../../po/../src/widgets/toolbox.cpp:431 +#, fuzzy +msgid "Join paths at selected nodes" +msgstr "Anslut linjer vid markerade noder" + +#: ../../po/../src/widgets/toolbox.cpp:433 +#, fuzzy +msgid "Join paths at selected nodes with new segment" +msgstr "Anslut linjer vid markerade noder med nya segment" + +#: ../../po/../src/widgets/toolbox.cpp:436 +msgid "Split path between two non-endpoint nodes" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:439 +#, fuzzy +msgid "Break path at selected nodes" +msgstr "Dela upp markerad nod" + +#: ../../po/../src/widgets/toolbox.cpp:444 +msgid "Make selected nodes corner" +msgstr "Gör markerade noder till hörn" + +#: ../../po/../src/widgets/toolbox.cpp:447 +msgid "Make selected nodes smooth" +msgstr "Gör markerade noder mjuka" + +#: ../../po/../src/widgets/toolbox.cpp:450 +#, fuzzy +msgid "Make selected nodes symmetric" +msgstr "Gör markerade noder mjuka" + +#: ../../po/../src/widgets/toolbox.cpp:455 +msgid "Make selected segments lines" +msgstr "Gör markerade segment till linjer" + +#: ../../po/../src/widgets/toolbox.cpp:458 +msgid "Make selected segments curves" +msgstr "Gör markerade segment till kurvor" + +#: ../../po/../src/widgets/toolbox.cpp:1199 +msgid "Polygon" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1206 +msgid "Regular polygon (with one handle) instead of a star" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1218 +msgid "Corners:" +msgstr "Hörn:" + +#: ../../po/../src/widgets/toolbox.cpp:1218 +msgid "Number of corners of a polygon or star" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1228 +#, fuzzy +msgid "Spoke ratio:" +msgstr "LÃ¥s skala" + +#. TRANSLATORS: Tip radius of a star is the distance from the center to the farthest handle. +#. Base radius is the same for the closest handle. +#: ../../po/../src/widgets/toolbox.cpp:1231 +msgid "Base radius to tip radius ratio" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1246 +#, fuzzy +msgid "Rounded:" +msgstr "Runda ändpunkter" + +#: ../../po/../src/widgets/toolbox.cpp:1246 +msgid "How much rounded are the corners (0 for sharp)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1256 +msgid "Randomized:" +msgstr "Slumpad:" + +#: ../../po/../src/widgets/toolbox.cpp:1256 +msgid "Scatter randomly the corners and angles" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1269 +#: ../../po/../src/widgets/toolbox.cpp:1838 +#: ../../po/../src/widgets/toolbox.cpp:2061 +msgid "Defaults" +msgstr "Standardalternativ" + +#: ../../po/../src/widgets/toolbox.cpp:1270 +#: ../../po/../src/widgets/toolbox.cpp:1839 +#: ../../po/../src/widgets/toolbox.cpp:2062 +msgid "" +"Reset shape parameters to defaults (use Inkscape Preferences > Tools to " +"change defaults)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1544 +msgid "W:" +msgstr "B:" + +#: ../../po/../src/widgets/toolbox.cpp:1544 +msgid "Width of rectangle" +msgstr "Rektangelns bredd" + +#: ../../po/../src/widgets/toolbox.cpp:1556 +msgid "Height of rectangle" +msgstr "Rektangelns höjd" + +#: ../../po/../src/widgets/toolbox.cpp:1568 +msgid "Rx:" +msgstr "Rx:" + +#: ../../po/../src/widgets/toolbox.cpp:1568 +msgid "Horizontal radius of rounded corners" +msgstr "Horisontellt radie pÃ¥ rundade hörn" + +#: ../../po/../src/widgets/toolbox.cpp:1578 +msgid "Ry:" +msgstr "Ry:" + +#: ../../po/../src/widgets/toolbox.cpp:1578 +msgid "Vertical radius of rounded corners" +msgstr "Vertikal radie pÃ¥ rundade hörn" + +#: ../../po/../src/widgets/toolbox.cpp:1594 +msgid "Not rounded" +msgstr "Icke rundad" + +#: ../../po/../src/widgets/toolbox.cpp:1596 +msgid "Make corners sharp" +msgstr "Gör hörnen skarpa" + +#: ../../po/../src/widgets/toolbox.cpp:1805 +#, fuzzy +msgid "Turns:" +msgstr "Transform:" + +#: ../../po/../src/widgets/toolbox.cpp:1805 +msgid "Number of revolutions" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1815 +#, fuzzy +msgid "Divergence:" +msgstr "Grad" + +#: ../../po/../src/widgets/toolbox.cpp:1815 +msgid "How much denser/sparser are outer revolutions; 1 = uniform" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1825 +msgid "Inner radius:" +msgstr "Innerradie:" + +#: ../../po/../src/widgets/toolbox.cpp:1825 +msgid "Radius of the innermost revolution (relative to the spiral size)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1957 +msgid "The width of the calligraphic pen (relative to the visible canvas area)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1967 +#, fuzzy +msgid "Thinning:" +msgstr "Rendering" + +#: ../../po/../src/widgets/toolbox.cpp:1967 +msgid "" +"How much velocity thins the stroke (> 0 makes fast strokes thinner, < 0 " +"makes them broader, 0 makes width independent of velocity)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1980 +msgid "Angle:" +msgstr "Vinkel:" + +#: ../../po/../src/widgets/toolbox.cpp:1980 +msgid "" +"The angle of the pen's nib (in degrees; 0 = horizontal; has no effect if " +"fixation = 0)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1990 +#, fuzzy +msgid "Fixation:" +msgstr "Orientering:" + +#: ../../po/../src/widgets/toolbox.cpp:1990 +msgid "" +"How fixed is the pen angle (0 = always perpendicular to stroke direction, 1 " +"= fixed)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2003 +msgid "Mass:" +msgstr "Massa:" + +#: ../../po/../src/widgets/toolbox.cpp:2003 +msgid "How much inertia affects the movement of the pen" +msgstr "" + +#. TRANSLATORS: "drag" means "resistance" here +#: ../../po/../src/widgets/toolbox.cpp:2014 +msgid "Drag:" +msgstr "Drag:" + +#: ../../po/../src/widgets/toolbox.cpp:2014 +msgid "How much resistance affects the movement of the pen" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2034 +msgid "Use the pressure of the input device to alter the width of the pen" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2047 +msgid "Use the tilt of the input device to alter the angle of the pen's nib" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2374 +#, fuzzy +msgid "Start:" +msgstr "Stjärna" + +#: ../../po/../src/widgets/toolbox.cpp:2374 +msgid "The angle (in degrees) from the horizontal to the arc's start point" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2384 +msgid "End:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2384 +msgid "The angle (in degrees) from the horizontal to the arc's end point" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2395 +#, fuzzy +msgid "Open arc" +msgstr "Öppna" + +#: ../../po/../src/widgets/toolbox.cpp:2396 +msgid "" +"Switch between arc (unclosed shape) and segment (closed shape with two radii)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2415 +msgid "Make whole" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2417 +msgid "Make the shape a whole ellipse, not arc or segment" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2644 +msgid "" +"When pressed, picks visible color without alpha and when not pressed, picks " +"color including its alpha" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:3039 +#, fuzzy +msgid "Make connectors avoid selected objects" +msgstr "Ta bort markerade objekt" + +#: ../../po/../src/widgets/toolbox.cpp:3043 +#, fuzzy +msgid "Make connectors ignore selected objects" +msgstr "Ta bort markerade objekt" + +#. +#. 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 : +#: ../share/extensions/addnodes.inx.h:1 +#, fuzzy +msgid "Add Nodes" +msgstr "Noder" + +#: ../share/extensions/addnodes.inx.h:2 +msgid "Maximum Segment Length" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:1 +#, fuzzy +msgid "AI Input" +msgstr "Indata" + +#: ../share/extensions/ai_input.inx.h:2 ../share/extensions/ai_output.inx.h:2 +#, fuzzy +msgid "Adobe Illustrator (*.ai)" +msgstr "Vektorillustrationsprogram" + +#: ../share/extensions/ai_input.inx.h:3 +msgid "Open files saved with Adobe Illustrator" +msgstr "" + +#: ../share/extensions/ai_output.inx.h:1 +#, fuzzy +msgid "AI Output" +msgstr "Ut" + +#: ../share/extensions/ai_output.inx.h:3 +#, fuzzy +msgid "Write Adobe Illustrator" +msgstr "Vektorillustrationsprogram" + +#: ../share/extensions/dia.inx.h:1 +msgid "A diagram created with the program Dia" +msgstr "" + +#: ../share/extensions/dia.inx.h:2 +msgid "Dia Diagram (*.dia)" +msgstr "" + +#: ../share/extensions/dia.inx.h:3 +#, fuzzy +msgid "Dia Input" +msgstr "Indata" + +#: ../share/extensions/dia.inx.h:4 +msgid "" +"In order to import Dia files, Dia itself must be installed. You can get Dia " +"at http://www.gnome.org/projects/dia/" +msgstr "" + +#: ../share/extensions/dia.inx.h:5 +msgid "" +"The dia2svg.sh script should be installed with your Inkscape distribution. " +"If you do not have it, there is likely to be something wrong with your " +"Inkscape installation." +msgstr "" + +#: ../share/extensions/dots.inx.h:1 +#, fuzzy +msgid "Connect the Dots" +msgstr "Hörn:" + +#: ../share/extensions/dots.inx.h:2 +#, fuzzy +msgid "Dot Size" +msgstr "Typsnittsstorlek" + +#: ../share/extensions/dots.inx.h:3 +#, fuzzy +msgid "Font Size" +msgstr "Typsnittsstorlek" + +#: ../share/extensions/dropshadow.inx.h:1 +msgid "Color of shadow" +msgstr "" + +#: ../share/extensions/dropshadow.inx.h:2 +msgid "Dropshadow" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:1 +#: ../share/extensions/dxf_output.inx.h:1 +msgid "AutoCAD DXF (*.dxf)" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:2 +#, fuzzy +msgid "DXF Input" +msgstr "Indata" + +#: ../share/extensions/dxf_input.inx.h:3 +msgid "Import AutoCAD's Document Exchange Format" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:4 +msgid "" +"dxf2svg may come with Inkscape, but is also at http://dxf-svg-convert." +"sourceforge.net/" +msgstr "" + +#: ../share/extensions/dxf_output.inx.h:2 +#, fuzzy +msgid "DXF Output" +msgstr "Ut" + +#: ../share/extensions/dxf_output.inx.h:3 +msgid "DXF file written by pstoedit" +msgstr "" + +#: ../share/extensions/dxf_output.inx.h:4 +msgid "pstoedit must be installed to run see http://www.pstoedit.net/pstoedit" +msgstr "" + +#: ../share/extensions/embedimage.inx.h:1 +#, fuzzy +msgid "Embed Images" +msgstr "Bilder" + +#: ../share/extensions/eps_input.inx.h:1 +#, fuzzy +msgid "EPS Input" +msgstr "Indata" + +#: ../share/extensions/eps_input.inx.h:2 +msgid "Encapsulated Postscript" +msgstr "" + +#: ../share/extensions/eps_input.inx.h:3 +msgid "Encapsulated Postscript (*.eps)" +msgstr "" + +#: ../share/extensions/epsi_output.inx.h:1 +#, fuzzy +msgid "EPSI Output" +msgstr "Ut" + +#: ../share/extensions/epsi_output.inx.h:2 +msgid "Encapsulated Postscript Interchange (*.epsi)" +msgstr "" + +#: ../share/extensions/epsi_output.inx.h:3 +msgid "Encapsulated Postscript with a thumbnail" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:1 ../share/extensions/ffms.inx.h:1 +#: ../share/extensions/ffset.inx.h:1 ../share/extensions/ffss.inx.h:1 +#, fuzzy +msgid "Bridge Width" +msgstr " Bredd " + +#: ../share/extensions/ffmet.inx.h:2 ../share/extensions/ffms.inx.h:2 +msgid "First String Length" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:3 +msgid "FretFind Multi Length ET" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:4 ../share/extensions/ffms.inx.h:4 +#: ../share/extensions/ffset.inx.h:3 ../share/extensions/ffss.inx.h:3 +msgid "Fretboard Edges" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:5 ../share/extensions/ffms.inx.h:5 +msgid "Last String Length" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:6 ../share/extensions/ffms.inx.h:6 +#: ../share/extensions/ffset.inx.h:4 ../share/extensions/ffss.inx.h:4 +msgid "Number of Frets" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:7 ../share/extensions/ffms.inx.h:7 +#: ../share/extensions/ffset.inx.h:5 ../share/extensions/ffss.inx.h:5 +msgid "Number of Strings" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:8 ../share/extensions/ffms.inx.h:8 +#: ../share/extensions/ffset.inx.h:6 ../share/extensions/ffss.inx.h:6 +#, fuzzy +msgid "Nut Width" +msgstr "Bredd" + +#: ../share/extensions/ffmet.inx.h:9 ../share/extensions/ffms.inx.h:10 +msgid "Perpendicular Distance" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:10 ../share/extensions/ffset.inx.h:7 +msgid "Scale Base (2 for Octave)" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:11 ../share/extensions/ffset.inx.h:9 +msgid "Tones in Scale" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:12 ../share/extensions/ffms.inx.h:12 +#: ../share/extensions/ffset.inx.h:10 ../share/extensions/ffss.inx.h:10 +msgid "px per Unit" +msgstr "" + +#: ../share/extensions/ffms.inx.h:3 +msgid "FretFind Multi Length Scala" +msgstr "" + +#: ../share/extensions/ffms.inx.h:9 ../share/extensions/ffss.inx.h:7 +msgid "Path to Scala *.scl File" +msgstr "" + +#: ../share/extensions/ffms.inx.h:11 +msgid "Tuning (scale step for each string seperated by semicolons)" +msgstr "" + +#: ../share/extensions/ffset.inx.h:2 +msgid "FretFind Single Length ET" +msgstr "" + +#: ../share/extensions/ffset.inx.h:8 ../share/extensions/ffss.inx.h:8 +msgid "Scale Length" +msgstr "" + +#: ../share/extensions/ffss.inx.h:2 +msgid "FretFind Single Length Scala" +msgstr "" + +#: ../share/extensions/ffss.inx.h:9 +msgid "Tuning (Scale step for each string seperated by semicolons)" +msgstr "" + +#: ../share/extensions/handles.inx.h:1 +#, fuzzy +msgid "Draw Handles" +msgstr "Rita frihand-linje" + +#: ../share/extensions/interp.inx.h:1 +#, fuzzy +msgid "Duplicate Endpaths" +msgstr "MÃ¥ngfaldiga nod" + +#: ../share/extensions/interp.inx.h:2 +#, fuzzy +msgid "Exponent" +msgstr "Exportera" + +#: ../share/extensions/interp.inx.h:3 +msgid "Interpolate" +msgstr "" + +#: ../share/extensions/interp.inx.h:4 +msgid "Interpolate Style (Experimental)" +msgstr "" + +#: ../share/extensions/interp.inx.h:5 +msgid "Interpolation Method" +msgstr "" + +#: ../share/extensions/interp.inx.h:6 +msgid "Interpolation Steps" +msgstr "" + +#: ../share/extensions/kochify.inx.h:1 +msgid "Kochify" +msgstr "" + +#: ../share/extensions/kochify_load.inx.h:1 +msgid "Kochify (Load)" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:1 +msgid "Angle" +msgstr "Vinkel" + +#: ../share/extensions/lindenmayer.inx.h:2 +msgid "Axiom" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:3 +#, fuzzy +msgid "Lindenmayer" +msgstr "Byt namn pÃ¥ lager" + +#: ../share/extensions/lindenmayer.inx.h:4 +#, fuzzy +msgid "Order" +msgstr "_Sortera" + +#: ../share/extensions/lindenmayer.inx.h:5 +#, fuzzy +msgid "Rules" +msgstr "Filter" + +#: ../share/extensions/lindenmayer.inx.h:6 +#, fuzzy +msgid "Step" +msgstr "Steg" + +#: ../share/extensions/motion.inx.h:1 +#, fuzzy +msgid "Direction" +msgstr "Beskrivning" + +#: ../share/extensions/motion.inx.h:2 +#, fuzzy +msgid "Magnitude" +msgstr "Magenta" + +#: ../share/extensions/motion.inx.h:3 +#, fuzzy +msgid "Motion" +msgstr "Upplösning:" + +#: ../share/extensions/pdf_output.inx.h:1 +msgid "Adobe PDF (*.pdf)" +msgstr "" + +#: ../share/extensions/pdf_output.inx.h:2 +msgid "Adobe Portable Document Format" +msgstr "" + +#: ../share/extensions/pdf_output.inx.h:3 +#, fuzzy +msgid "PDF Output" +msgstr "Ut" + +#: ../share/extensions/ps_input.inx.h:1 +#, fuzzy +msgid "Postscript" +msgstr "Porträtt" + +#: ../share/extensions/ps_input.inx.h:2 +msgid "Postscript (*.ps)" +msgstr "" + +#: ../share/extensions/ps_input.inx.h:3 +msgid "Postscript Input" +msgstr "" + +#: ../share/extensions/radiusrand.inx.h:1 +#, fuzzy +msgid "Radius" +msgstr "Radie:" + +#: ../share/extensions/radiusrand.inx.h:2 +#, fuzzy +msgid "Radius Randomize" +msgstr "Slumpa:" + +#: ../share/extensions/radiusrand.inx.h:3 +msgid "Randomize Control Points" +msgstr "" + +#: ../share/extensions/radiusrand.inx.h:4 +#, fuzzy +msgid "Randomize Nodes" +msgstr "Slumpad:" + +#: ../share/extensions/rtree.inx.h:1 +#, fuzzy +msgid "Initial Size" +msgstr "Bitmappsstorlek" + +#: ../share/extensions/rtree.inx.h:2 +msgid "Minimum Size" +msgstr "" + +#: ../share/extensions/rtree.inx.h:3 +#, fuzzy +msgid "Random Tree" +msgstr "Slumpa:" + +#: ../share/extensions/sk_input.inx.h:1 +msgid "A diagram created with the program Sketch" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:2 +msgid "Sketch Diagram (*.sk)" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:3 +msgid "Sketch Input" +msgstr "" + +#: ../share/extensions/straightseg.inx.h:1 +msgid "Behavior" +msgstr "" + +#: ../share/extensions/straightseg.inx.h:3 +msgid "Segment Straightener" +msgstr "" + +#: ../share/extensions/summersnight.inx.h:1 +msgid "Summer's Night" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:1 +#: ../share/extensions/svgz_output.inx.h:1 +#, fuzzy +msgid "Compressed Inkscape SVG (*.svgz)" +msgstr "Okomprimerad filstorlek:" + +# Osäker +#: ../share/extensions/svgz_input.inx.h:2 +#: ../share/extensions/svgz_output.inx.h:2 +#, fuzzy +msgid "Inkscape's native file format compressed with GZip" +msgstr "Inbyggt filformat för Sodipodi och W3C-standard" + +#: ../share/extensions/svgz_input.inx.h:3 +#, fuzzy +msgid "SVGZ Input" +msgstr "Indata" + +#: ../share/extensions/svgz_output.inx.h:3 +#, fuzzy +msgid "SVGZ Output" +msgstr "Ut" + +#: ../share/extensions/txt2svg.inx.h:1 +msgid "ASCII Text" +msgstr "" + +#: ../share/extensions/txt2svg.inx.h:2 +msgid "Text File (*.txt)" +msgstr "" + +#: ../share/extensions/txt2svg.inx.h:3 +#, fuzzy +msgid "Text Input" +msgstr "Indata" + +#: ../share/extensions/wavy.inx.h:1 +msgid "Calculate first derivative numerically" +msgstr "" + +#: ../share/extensions/wavy.inx.h:2 +msgid "First derivative" +msgstr "" + +#: ../share/extensions/wavy.inx.h:3 +msgid "Function" +msgstr "" + +#: ../share/extensions/wavy.inx.h:4 +msgid "Function Plotter" +msgstr "" + +#: ../share/extensions/wavy.inx.h:5 +msgid "Nodes per period" +msgstr "" + +#: ../share/extensions/wavy.inx.h:6 +msgid "Periods (2*Pi each)" +msgstr "" + +#: ../share/extensions/whirl.inx.h:1 +msgid "Amount of Whirl" +msgstr "" + +#: ../share/extensions/whirl.inx.h:2 +#, fuzzy +msgid "Center X" +msgstr "Mittpunkt i X-led:" + +#: ../share/extensions/whirl.inx.h:3 +#, fuzzy +msgid "Center Y" +msgstr "Mittpunkt i Y-led:" + +#: ../share/extensions/whirl.inx.h:4 +#, fuzzy +msgid "Direction of Rotation" +msgstr "placera markeringen nederst" + +#: ../share/extensions/whirl.inx.h:5 +msgid "Whirl" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:1 +msgid "A popular graphics file format for clipart" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:2 +msgid "Windows Metafile (*.wmf)" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:3 +msgid "Windows Metafile Input" +msgstr "" + +#, fuzzy +#~ msgid "Canvas size:" +#~ msgstr "Typsnittsstorlek:" + +#, fuzzy +#~ msgid "Custom canvas" +#~ msgstr "Egen pappersstorlek" + +#, fuzzy +#~ msgid "Current style" +#~ msgstr "Genomstrykningsinställningar" + +#, fuzzy +#~ msgid "Arrange Objects" +#~ msgstr "Justera objekt" + +#~ msgid "deg" +#~ msgstr "grader" + +#, fuzzy +#~ msgid "_Credits" +#~ msgstr "Hörn:" + +#, fuzzy +#~ msgid "Grab sensitivity" +#~ msgstr "Gör känslig" + +#, fuzzy +#~ msgid "Acceleration" +#~ msgstr "Markering" + +#, fuzzy +#~ msgid "Speed" +#~ msgstr "Röd:" + +#~ msgid "Threshold" +#~ msgstr "Tröskelvärde" + +#, fuzzy +#~ msgid "Zoom in/out by" +#~ msgstr "Zooma in/ut med" + +#, fuzzy +#~ msgid "Transform" +#~ msgstr "Transformeringar" + +#, fuzzy +#~ msgid "Rotate _90 deg CW" +#~ msgstr "Rotera 90°" + +#, fuzzy +#~ msgid "Rotate 9_0 deg CCW" +#~ msgstr "Rotera 90°" + +#, fuzzy +#~ msgid "Flip selection horizontally" +#~ msgstr "Vänd markerade objekt horisontellt" + +#, fuzzy +#~ msgid "Flip selection vertically" +#~ msgstr "Vänd markerade objekt vertikalt" + +#~ msgid "Edit" +#~ msgstr "Redigera" + +#~ msgid "Add" +#~ msgstr "Lägg till" + +#~ msgid "SVG Vector Illustrator" +#~ msgstr "SVG-vektorillustrationsprogram" + +#, fuzzy +#~ msgid "C_reate" +#~ msgstr "Skapa" + +#, fuzzy +#~ msgid "Automatically scale Rows to fit selected objects." +#~ msgstr "Redigera fyllningstyp hos markerade objekt" + +#, fuzzy +#~ msgid "Automatically scale Columns to fit selected objects." +#~ msgstr "Redigera fyllningstyp hos markerade objekt" + +#, fuzzy +#~ msgid "Go to root" +#~ msgstr "Redigera noder" + +#~ msgid "X" +#~ msgstr "X" + +#~ msgid "Y" +#~ msgstr "Y" + +#, fuzzy +#~ msgid " " +#~ msgstr "% " + +#~ msgid "Sides:" +#~ msgstr "Sidor:" + +#~ msgid "R1:" +#~ msgstr "R1:" + +#~ msgid "R2:" +#~ msgstr "R2:" + +#~ msgid "ARG1:" +#~ msgstr "ARG1:" + +#~ msgid "ARG2:" +#~ msgstr "ARG2:" + +#, fuzzy +#~ msgid "Flatsides:" +#~ msgstr "Sidor:" + +#, fuzzy +#~ msgid "Radius X:" +#~ msgstr "Radie:" + +#, fuzzy +#~ msgid "Radius Y:" +#~ msgstr "Radie:" + +#, fuzzy +#~ msgid "Start Angle:" +#~ msgstr "Stjärna" + +#, fuzzy +#~ msgid "End Angle:" +#~ msgstr "Vinkel:" + +#, fuzzy +#~ msgid "Open:" +#~ msgstr "_Öppna" + +#~ msgid "Expansion:" +#~ msgstr "Expansion:" + +#, fuzzy +#~ msgid "Revolutions:" +#~ msgstr "Revolution:" + +#~ msgid "Argument:" +#~ msgstr "Argument:" + +#~ msgid "T0:" +#~ msgstr "T0:" + +#~ msgid "RX:" +#~ msgstr "RX:" + +#~ msgid "RY:" +#~ msgstr "RY:" + +#, fuzzy +#~ msgid "Rectangle _Properties" +#~ msgstr "Rektangelegenskaper" + +#, fuzzy +#~ msgid "Star _Properties" +#~ msgstr "Stjärnegenskaper" + +#, fuzzy +#~ msgid "Ellipse _Properties" +#~ msgstr "Länkegenskaper" + +#, fuzzy +#~ msgid "Spiral _Properties" +#~ msgstr "Spiralegenskaper" + +#, fuzzy +#~ msgid "Document Preferences" +#~ msgstr "Objekt är referens" + +#, fuzzy +#~ msgid "Extensions Editor" +#~ msgstr "Tillägg" + +#, fuzzy +#~ msgid "Preferences" +#~ msgstr "Objekt är referens" + +#, fuzzy +#~ msgid "Layer Editor" +#~ msgstr "XML-redigerare" + +#, fuzzy +#~ msgid "Text Properties" +#~ msgstr "Textegenskaper" + +#, fuzzy +#~ msgid "Transformation" +#~ msgstr "Transformationsmatris" + +#, fuzzy +#~ msgid "_Export..." +#~ msgstr "_Exportera" + +#, fuzzy +#~ msgid "_Document Properties" +#~ msgstr "Dokumentinställningar" + +#, fuzzy +#~ msgid "In_kscape Preferences" +#~ msgstr "Sodipodi-bildspel" + +#, fuzzy +#~ msgid "Select _Original Clone" +#~ msgstr "Markera allt" + +#, fuzzy +#~ msgid "Tile" +#~ msgstr "_Arkiv" + +#, fuzzy +#~ msgid "Select A_ll" +#~ msgstr "Markera allt" + +#, fuzzy +#~ msgid "Select Non_e" +#~ msgstr "Markering" + +#, fuzzy +#~ msgid "Zoom _In" +#~ msgstr "Zooma in" + +#, fuzzy +#~ msgid "Zoom _Out" +#~ msgstr "Zooma ut" + +#, fuzzy +#~ msgid "Pre_vious" +#~ msgstr "Stäng fönster" + +#, fuzzy +#~ msgid "Nex_t" +#~ msgstr "Text" + +#, fuzzy +#~ msgid "Tool Co_ntrols bar" +#~ msgstr "Verktygsalternativ" + +#, fuzzy +#~ msgid "R_ename Layer..." +#~ msgstr "Höj nod" + +#, fuzzy +#~ msgid "D_uplicate Layer" +#~ msgstr "MÃ¥ng_faldiga" + +#, fuzzy +#~ msgid "_Anchor Layer" +#~ msgstr "Sänk nod" + +#, fuzzy +#~ msgid "_Delete Layer" +#~ msgstr "Markera" + +#, fuzzy +#~ msgid "Select Ne_xt Layer" +#~ msgstr "Markera" + +#, fuzzy +#~ msgid "Select Pre_vious Layer" +#~ msgstr "Välj skrivare" + +#, fuzzy +#~ msgid "Select To_p Layer" +#~ msgstr "Välj skrivare" + +#, fuzzy +#~ msgid "Move to Ne_w Layer" +#~ msgstr "Skapa nytt SVG-dokument" + +#, fuzzy +#~ msgid "Move to B_ottom Layer" +#~ msgstr "placera markeringen nederst" + +#, fuzzy +#~ msgid "_Trace Bitmap..." +#~ msgstr "Trasig bitmappsbild" + +#, fuzzy +#~ msgid "_Put Text on Path" +#~ msgstr "Konvertera markerat objekt till slinga" + +#, fuzzy +#~ msgid "_Remove Text from Path" +#~ msgstr "Konvertera markerat objekt till slinga" + +#~ msgid "Arc" +#~ msgstr "BÃ¥ge" + +#, fuzzy +#~ msgid "Freehand" +#~ msgstr "Frihand och penna" + +#, fuzzy +#~ msgid "DynaDraw" +#~ msgstr "Rita" + +#~ msgid "Stroke" +#~ msgstr "Genomstrykning" + +#, fuzzy +#~ msgid "Corners" +#~ msgstr "Hörn:" + +#~ msgid "Delete" +#~ msgstr "Ta bort" + +#, fuzzy +#~ msgid "Join" +#~ msgstr "Anslutning:" + +#, fuzzy +#~ msgid "Delete Segment" +#~ msgstr "MÃ¥ngfaldiga markering" + +#, fuzzy +#~ msgid "Break" +#~ msgstr "Dela upp" + +#, fuzzy +#~ msgid "Symmetric" +#~ msgstr "Osymmetrisk" + +#, fuzzy +#~ msgid "Line" +#~ msgstr "Linjär" + +#~ msgid "New" +#~ msgstr "Ny" + +#, fuzzy +#~ msgid "Revert to Saved" +#~ msgstr "Omvandla till kurvor" + +#, fuzzy +#~ msgid "Save" +#~ msgstr "Spara" + +#, fuzzy +#~ msgid "Save As..." +#~ msgstr "Spara som..." + +#, fuzzy +#~ msgid "Import..." +#~ msgstr "_Importera" + +#, fuzzy +#~ msgid "Export..." +#~ msgstr "Exportera" + +#, fuzzy +#~ msgid "Print..." +#~ msgstr "Skriv ut..." + +#, fuzzy +#~ msgid "Global Inkscape preferences (Shift+Ctrl+P)" +#~ msgstr "Globala visningsinställningar" + +#, fuzzy +#~ msgid "Undo" +#~ msgstr "Ångra " + +#, fuzzy +#~ msgid "Redo" +#~ msgstr "Gör om" + +#, fuzzy +#~ msgid "Cut" +#~ msgstr "Klipp ut" + +#, fuzzy +#~ msgid "Copy" +#~ msgstr "Kopiera" + +#, fuzzy +#~ msgid "Duplicate selected object(s) (Ctrl+D)" +#~ msgstr "MÃ¥ngfaldiga markerade objekt" + +#, fuzzy +#~ msgid "Clone selected object (Alt+D)" +#~ msgstr "MÃ¥ngfaldiga markerade objekt" + +#, fuzzy +#~ msgid "Zoom in (+)" +#~ msgstr "Zooma in" + +#, fuzzy +#~ msgid "Zoom out (-)" +#~ msgstr "Zooma ut" + +#, fuzzy +#~ msgid "Zoom to 1:1 (100%) (1)" +#~ msgstr "Zooma till 1:1" + +#, fuzzy +#~ msgid "Zoom to 1:2 (50%) (2)" +#~ msgstr "Zooma till 1:2" + +#, fuzzy +#~ msgid "Zoom to 2:1 (200%) (0)" +#~ msgstr "Zooma till 2:1" + +#, fuzzy +#~ msgid "Zoom to fit selection in window (3)" +#~ msgstr "Passa in hela markeringen i fönstret" + +#, fuzzy +#~ msgid "Zoom to fit drawing in window (4)" +#~ msgstr "Passa in hela teckningen i fönstret" + +#, fuzzy +#~ msgid "Zoom to fit page in window (5)" +#~ msgstr "Passa in sidan i fönstret" + +#, fuzzy +#~ msgid "Zoom to fit page width in window (6)" +#~ msgstr "Passa in sidan i fönstret" + +#, fuzzy +#~ msgid "Fill and Stroke dialog (Shift+Ctrl+F)" +#~ msgstr "Fyllning och genomstrykning" + +#, fuzzy +#~ msgid "Group selected objects (Ctrl+G)" +#~ msgstr "Gruppera markerade objekt" + +#, fuzzy +#~ msgid "Ungroup selected group(s) (Ctrl+U)" +#~ msgstr "Avgruppera markerad grupp" + +#, fuzzy +#~ msgid "Raise selection up one step (PgUp)" +#~ msgstr "Placera markeringen överst" + +#, fuzzy +#~ msgid "Lower selection down one step (PgDn)" +#~ msgstr "Sänk markeringen ett lager" + +#, fuzzy +#~ msgid "Raise selection to top (Home)" +#~ msgstr "Placera markeringen överst" + +#, fuzzy +#~ msgid "Lower selection to bottom (End)" +#~ msgstr "placera markeringen nederst" + +#, fuzzy +#~ msgid "Move selection to new layer" +#~ msgstr "Höj markeringen ett lager" + +#, fuzzy +#~ msgid "Move selection to next layer" +#~ msgstr "Höj markeringen ett lager" + +#, fuzzy +#~ msgid "Move selection to previous layer" +#~ msgstr "Höj markeringen ett lager" + +#, fuzzy +#~ msgid "Move selection to top layer" +#~ msgstr "Höj markeringen ett lager" + +#, fuzzy +#~ msgid "Move selection to bottom layer" +#~ msgstr "placera markeringen nederst" + +#, fuzzy +#~ msgid "Rotate selection 90° clockwise (Shift+Ctrl+Right)" +#~ msgstr "Rotera objekt 90 grader medurs" + +#, fuzzy +#~ msgid "Rotate selection 90° counter-clockwise (Shift+Ctrl+Left)" +#~ msgstr "Rotera objekt 90 grader medurs" + +#, fuzzy +#~ msgid "Flip selection horizontally (H)" +#~ msgstr "Vänd markerade objekt horisontellt" + +#, fuzzy +#~ msgid "Flip selection vertically (V)" +#~ msgstr "Vänd markerade objekt vertikalt" + +#, fuzzy +#~ msgid "Align and Distribute dialog (Shift+Ctrl+A)" +#~ msgstr "Justera och distribuera" + +#, fuzzy +#~ msgid "Convert selected object(s) to path(s) (Shift+Ctrl+C)" +#~ msgstr "Konvertera markerat objekt till slinga" + +#, fuzzy +#~ msgid "Convert selected stroke(s) to path(s) (Ctrl+Alt+C)" +#~ msgstr "Konvertera markerat objekt till slinga" + +#, fuzzy +#~ msgid "Cl_eanup" +#~ msgstr "Städa" + +#, fuzzy +#~ msgid "Text and Font dialog (Shift+Ctrl+T)" +#~ msgstr "Text och typsnitt" + +#, fuzzy +#~ msgid "Node tool" +#~ msgstr "Inget aktivt verktyg" + +#, fuzzy +#~ msgid "Zoom tool" +#~ msgstr "Zooma ut" + +#~ msgid "Rectangle tool" +#~ msgstr "Rektangelverktyg" + +#~ msgid "Arc tool" +#~ msgstr "BÃ¥gverktyg" + +#~ msgid "Star tool" +#~ msgstr "Stjärnverktyg" + +#~ msgid "Spiral tool" +#~ msgstr "Spiralverktyg" + +#, fuzzy +#~ msgid "Freehand tool" +#~ msgstr "Frihand och penna" + +#, fuzzy +#~ msgid "Pen tool" +#~ msgstr "Rektangelverktyg" + +#, fuzzy +#~ msgid "Calligraphy tool" +#~ msgstr "Kalligrafi" + +#, fuzzy +#~ msgid "Text tool" +#~ msgstr "Stjärnverktyg" + +#, fuzzy +#~ msgid "Dropper tool" +#~ msgstr "Pipett" + +#, fuzzy +#~ msgid "When scaling rectangles, scale radii of rounded corners" +#~ msgstr "Horisontellt mittpunktsvärde" + +#, fuzzy +#~ msgid "Delete segment between two nodes" +#~ msgstr "Ta bort markerade noder" + +#, fuzzy +#~ msgid "URI:" +#~ msgstr "URL:" + +#, fuzzy +#~ msgid "Select All in All Layers" +#~ msgstr "Markera" + +#, fuzzy +#~ msgid "Invert Selection" +#~ msgstr "Markering" + +#, fuzzy +#~ msgid "Clean up selected path(s)" +#~ msgstr "SlÃ¥ samman markerade slingor" + +#, fuzzy +#~ msgid "_Scripts..." +#~ msgstr "Skriv ut..." + +#, fuzzy +#~ msgid "Align and Distribute" +#~ msgstr "Justera och distribuera" + +#, fuzzy +#~ msgid "Align and Distribute Dialog" +#~ msgstr "Justera och distribuera" + +#, fuzzy +#~ msgid "Export Dialog" +#~ msgstr "Exportera som" + +#, fuzzy +#~ msgid "Fill and Stroke Dialog" +#~ msgstr "Fyllning och genomstrykning" + +#, fuzzy +#~ msgid "Find Dialog" +#~ msgstr "Justera dialogfönster" + +#, fuzzy +#~ msgid "Inkscape Preferences" +#~ msgstr "Sodipodi-bildspel" + +#, fuzzy +#~ msgid "Inkscape Preferences Dialog" +#~ msgstr "Sodipodi-bildspel" + +#, fuzzy +#~ msgid "Layer Editor Dialog" +#~ msgstr "Placera markeringen överst" + +#, fuzzy +#~ msgid "Text Properties Dialog" +#~ msgstr "objektegenskaper" + +#, fuzzy +#~ msgid "Transformation Dialog" +#~ msgstr "Transformationsfönster" + +#, fuzzy +#~ msgid "Tree Editor" +#~ msgstr "XML-redigerare" + +#, fuzzy +#~ msgid "XML Editor Dialog" +#~ msgstr "XML-redigerare" + +#, fuzzy +#~ msgid "Row height:" +#~ msgstr "Höjd:" + +#, fuzzy +#~ msgid "Column width:" +#~ msgstr "Ändra" + +#, fuzzy +#~ msgid "Creating anchor at (%g,%g)" +#~ msgstr "Rita stjärna" + +#, fuzzy +#~ msgid "EPS Output Settings" +#~ msgstr "Dokumentinställningar" + +#, fuzzy +#~ msgid "Inkscape" +#~ msgstr "Sodipodi-bildspel" + +#~ msgid "Left side of aligned objects to left side of anchor" +#~ msgstr "Vänstersida pÃ¥ justerade objekt mot vänsterkanten pÃ¥ ankare" + +#~ msgid "Right side of aligned objects to right side of anchor" +#~ msgstr "Högersida pÃ¥ justerade objekt mot högerkanten pÃ¥ ankare" + +#~ msgid "Top of aligned objects to top of anchor" +#~ msgstr "Överkanten pÃ¥ justerade objekt mot överkanten pÃ¥ ankare" + +#~ msgid "Bottom of aligned objects to bottom of anchor" +#~ msgstr "Nederkanten pÃ¥ justerade objekt mot nederkanten pÃ¥ ankare" + +#~ msgid "Distribute top sides of objects at even distances" +#~ msgstr "Distribuera överkanter pÃ¥ objekt med jämna mellanrum" + +#, fuzzy +#~ msgid "Alternate sign" +#~ msgstr "Mättnad:" + +#, fuzzy +#~ msgid "Rows:" +#~ msgstr "Ellips" + +#, fuzzy +#~ msgid "Minor grid line color:" +#~ msgstr "Färg pÃ¥ hjälplinjer" + +#~ msgid "Grid color" +#~ msgstr "Färg pÃ¥ rutnät" + +#, fuzzy +#~ msgid "Grid emphasis color" +#~ msgstr "Färg pÃ¥ rutnät" + +#, fuzzy +#~ msgid "Major grid line spacing:" +#~ msgstr "RadavstÃ¥nd:" + +#, fuzzy +#~ msgid "Background (also for export):" +#~ msgstr "Slutfärg" + +#, fuzzy +#~ msgid "Picking colors:" +#~ msgstr "Välj en färg" + +#~ msgid "Fill style" +#~ msgstr "Fyllningsstil" + +#, fuzzy +#~ msgid "Fill:" +#~ msgstr "Fyll" + +#, fuzzy +#~ msgid "winding" +#~ msgstr "Rendering" + +#, fuzzy +#~ msgid "alternating" +#~ msgstr "Mättnad:" + +#, fuzzy +#~ msgid "Update Properties" +#~ msgstr "Objektegenskaper" + +#, fuzzy +#~ msgid "Label invalid" +#~ msgstr "ID:t är giltigt" + +#, fuzzy +#~ msgid "executable" +#~ msgstr "Rektangel" + +#, fuzzy +#~ msgid "file" +#~ msgstr "Arkiv" + +#, fuzzy +#~ msgid "extension" +#~ msgstr "Tillägg" + +#, fuzzy +#~ msgid "path" +#~ msgstr "pt" + +#, fuzzy +#~ msgid "absolute" +#~ msgstr "absolut" + +#~ msgid "Could not create sodipodi-svg-doc factory" +#~ msgstr "Kunde inte skapa sodipodi-svg-doc-fabrik" + +#, fuzzy +#~ msgid "SVG Files" +#~ msgstr "Spara fil" + +#~ msgid "Plain SVG" +#~ msgstr "Vanlig SVG" + +#, fuzzy +#~ msgid "Make s_ensitive" +#~ msgstr "Gör känslig" + +#, fuzzy +#~ msgid "Make i_nsensitive" +#~ msgstr "Gör okänslig" + +#, fuzzy +#~ msgid "Layer Properties" +#~ msgstr "Stjärnegenskaper" + +#, fuzzy +#~ msgid "Select object(s) to tile." +#~ msgstr "Klipp ut markerade objekt till urklipp" + +#, fuzzy +#~ msgid "Apply" +#~ msgstr "Tillämpa pÃ¥:" + +#~ msgid "Sensitive" +#~ msgstr "Känslig" + +#~ msgid "Active" +#~ msgstr "Aktiv" + +#~ msgid "Printable" +#~ msgstr "Utskrivbar" + +#, fuzzy +#~ msgid "Prefer bitmap (XPM) icons to SVG ones" +#~ msgstr "Föredra bitmappsikoner (xpm) över SVG-ikoner" + +#~ msgid "Trace" +#~ msgstr "SpÃ¥r" + +#, fuzzy +#~ msgid "Error writing %s: %s" +#~ msgstr "Fel vid skrivning av %s: %s" + +#~ msgid "Untitled" +#~ msgstr "Namnlös" + +#~ msgid "Document Name:" +#~ msgstr "Dokumentnamn:" + +#~ msgid "Image URI:" +#~ msgstr "Bild-URI:" + +#~ msgid "Visible" +#~ msgstr "Synlig" + +#, fuzzy +#~ msgid "Drag to paint a calligraphic stroke." +#~ msgstr "Rita kalligrafiska linjer" + +#, fuzzy +#~ msgid "Flatness:" +#~ msgstr "Sidor:" + +#, fuzzy +#~ msgid "Other" +#~ msgstr "Sortera" + +#, fuzzy +#~ msgid "Trace: Selected object is not an image" +#~ msgstr "Höj markerade objekt en nivÃ¥" + +#, fuzzy +#~ msgid "object" +#~ msgstr "Objekt" + +#, fuzzy +#~ msgid "user space" +#~ msgstr "Användarkoordinater" + +#, fuzzy +#~ msgid "Coordinates:" +#~ msgstr "Hörn:" + +#, fuzzy +#~ msgid "" +#~ "Distribute centers of objects of objects at even distances horizontally" +#~ msgstr "Distribuera objektcentrum med jämna mellanrum horisontellt" + +#~ msgid "Alignment:" +#~ msgstr "Justering:" + +#~ msgid "Text and font" +#~ msgstr "Text och typsnitt" + +#, fuzzy +#~ msgid "Draw arc: %s x %s" +#~ msgstr "Rita bÃ¥ge" + +#~ msgid "All shape tools" +#~ msgstr "Alla figurverktyg" + +#, fuzzy +#~ msgid "Draw rectangle: %s x %s" +#~ msgstr "Rita rektanglar" + +#, fuzzy +#~ msgid "Move by %s, %s" +#~ msgstr " Flytta " + +#, fuzzy +#~ msgid "Active group" +#~ msgstr "Aktiv" + +#~ msgid "Grid color:" +#~ msgstr "Färg pÃ¥ rutnät:" + +#, fuzzy +#~ msgid "typeset object" +#~ msgstr "Textobjekt" + +#, fuzzy +#~ msgid "Pattern Fill" +#~ msgstr "Mönster:" + +#~ msgid "Snap to grid" +#~ msgstr "Fäst vid rutnät" + +#~ msgid "Snap to guides" +#~ msgstr "Fäst vid hjälplinjer" + +#, fuzzy +#~ msgid "_Menu" +#~ msgstr "Städa" + +#, fuzzy +#~ msgid "Snap points to the grid" +#~ msgstr "Fäst vid rutnät" + +#, fuzzy +#~ msgid "Rect" +#~ msgstr "Rektangel" + +#~ msgid "meters" +#~ msgstr "meter" + +#~ msgid "Userspace unit" +#~ msgstr "Användarenhet" + +#~ msgid "User" +#~ msgstr "Användare" + +#~ msgid "Userspace units" +#~ msgstr "Användarenheter" + +#, fuzzy +#~ msgid "Ru_lers" +#~ msgstr "Filter" + +#, fuzzy +#~ msgid "Show or hide rulers" +#~ msgstr "Visa hjälplinjer" + +#, fuzzy +#~ msgid "_New Window" +#~ msgstr "Ny vy" + +#~ msgid "Mode:" +#~ msgstr "Läge:" + +#~ msgid "RGB Colorspace" +#~ msgstr "RGB-färgutrymme" + +#~ msgid "CMYK Colorspace" +#~ msgstr "CMYK-färgutrymme" + +#~ msgid "Get from dropper" +#~ msgstr "Hämta frÃ¥n pipett" + +#~ msgid "Alpha:" +#~ msgstr "Alfa:" + +#~ msgid "Value:" +#~ msgstr "Värde:" + +#~ msgid "Stroke settings" +#~ msgstr "Genomstrykningsinställningar" + +#, fuzzy +#~ msgid "Stroke pattern" +#~ msgstr "Genomstrykningsbredd" + +#~ msgid "Item properties" +#~ msgstr "Objektegenskaper" + +#, fuzzy +#~ msgid "Quit" +#~ msgstr "_Avsluta" + +#~ msgid "Combine multiple paths" +#~ msgstr "SlÃ¥ samman flera slingor" + +#, fuzzy +#~ msgid "New View" +#~ msgstr "Ny vy" + +#~ msgid "Fill and stroke settings" +#~ msgstr "Inställningar för fyllning och genomstrykning" + +#~ msgid "Object transformations" +#~ msgstr "Objekttransformeringar" + +#, fuzzy +#~ msgid "Align and distribute objects" +#~ msgstr "Justera och distribuera" + +#~ msgid "Text editing and font settings" +#~ msgstr "Inställningar för textredigering och typsnitt" + +#~ msgid "Fill Rule" +#~ msgstr "Fyllningsregel" + +#~ msgid "Tool has no options" +#~ msgstr "Verktyget har inga alternativ" + +#~ msgid "Roundness ratio for x:" +#~ msgstr "Rundhetsgrad för x:" + +#~ msgid "Roundness ratio for y:" +#~ msgstr "Rundhetsgrad för y:" + +#~ msgid "Visual transformation" +#~ msgstr "Visuell transformering" + +#~ msgid "Show content" +#~ msgstr "Visa innehÃ¥ll" + +#, fuzzy +#~ msgid "Selected object has no curve, cannot outline." +#~ msgstr "Klipp ut markerade objekt till urklipp" + +#~ msgid "Proportion:" +#~ msgstr "Proportion:" + +#, fuzzy +#~ msgid "Inkscape _Options" +#~ msgstr "Sodipodi-bildspel" + +#, fuzzy +#~ msgid "Tool Optio_ns" +#~ msgstr "Verktygsalternativ" + +#~ msgid "gradientUnits" +#~ msgstr "toningsenheter" + +#~ msgid "gradientSpread" +#~ msgstr "toningsspridning" + +#~ msgid "nonzero" +#~ msgstr "ickenoll" + +#~ msgid "evenodd" +#~ msgstr "jämnudda" + +#, fuzzy +#~ msgid "" +#~ "%s is not regular file.\n" +#~ "Although inkscape will run, you can\n" +#~ "neither load nor save preferences\n" +#~ msgstr "" +#~ "%s är ingen vanlig fil.\n" +#~ "Även om sodipodi kommer att köra kan du\n" +#~ "varken läsa in eller spara inställningar\n" + +#, fuzzy +#~ msgid "" +#~ "%s either is not valid xml file or\n" +#~ "you do not have read premissions on it.\n" +#~ "Although inkscape will run, you\n" +#~ "are neither able to load nor save\n" +#~ "preferences." +#~ msgstr "" +#~ "%s är varken en giltig xml-fil eller\n" +#~ "sÃ¥ har du inte läsrättigheter till den.\n" +#~ "Även om sodipodi kommer att köra kommer\n" +#~ "du varken att kunna läsa in eller spara\n" +#~ "inställningar." + +#, fuzzy +#~ msgid "" +#~ "%s is not valid inkscape preferences file.\n" +#~ "Although inkscape will run, you\n" +#~ "are neither able to load nor save\n" +#~ "preferences." +#~ msgstr "" +#~ "%s är inte en giltig sodipodi-inställningsfil.\n" +#~ "Även om sodipodi kommer att köra kan du\n" +#~ "varken läsa in eller spara inställningar." + +#, fuzzy +#~ msgid "" +#~ "Cannot create directory %s.\n" +#~ "Although inkscape will run, you\n" +#~ "are neither able to load nor save\n" +#~ "%s." +#~ msgstr "" +#~ "Kan inte skapa katalogen %s.\n" +#~ "Även om sodipodi kommer att köra\n" +#~ "kan du varken läsa in eller spara\n" +#~ "%s." + +#, fuzzy +#~ msgid "" +#~ "%s is not a valid directory.\n" +#~ "Although inkscape will run, you\n" +#~ "are neither able to load nor save\n" +#~ "preferences." +#~ msgstr "" +#~ "%s är inte en giltig katalog.\n" +#~ "Även om sodipodi kommer att köra\n" +#~ "kan du varken läsa in eller spara\n" +#~ "inställningar." + +#, fuzzy +#~ msgid "" +#~ "Cannot create file %s.\n" +#~ "Although inkscape will run, you\n" +#~ "are neither able to load nor save\n" +#~ "preferences." +#~ msgstr "" +#~ "Kan inte skapa filen %s.\n" +#~ "Även om sodipodi kommer att köra\n" +#~ "kan du varken läsa in eller spara\n" +#~ "inställningar." + +#, fuzzy +#~ msgid "" +#~ "Cannot write file %s.\n" +#~ "Although inkscape will run, you\n" +#~ "are neither able to load nor save\n" +#~ "preferences." +#~ msgstr "" +#~ "Kan inte skriva filen %s.\n" +#~ "Även om sodipodi kommer att köra\n" +#~ "kan du varken läsa in eller spara\n" +#~ "inställningar." + +#~ msgid "End color" +#~ msgstr "Slutfärg" + +#~ msgid "Make sides flat" +#~ msgstr "Gör sidor platta" + +#~ msgid "Bring to _Front" +#~ msgstr "Flytta _främst" + +#~ msgid "Send to _Back" +#~ msgstr "Skicka _bakÃ¥t" + +#~ msgid "Toggle separate window and main toolbox placement" +#~ msgstr "Växla placering för separata fönster och huvudverktygslÃ¥da" + +#~ msgid "Document %s has unsaved changes, save them?" +#~ msgstr "Dokumentet %s har osparade ändringar, spara dem?" + +#, fuzzy +#~ msgid "Object Size and Position" +#~ msgstr "Objektstorlek och -position" + +#~ msgid "Size and Position" +#~ msgstr "Storlek och position" + +#~ msgid "Tool attributes" +#~ msgstr "Verktygsattribut" + +#~ msgid "Inner radius" +#~ msgstr "Innerradie" + +#~ msgid "Proportion" +#~ msgstr "Proportion" + +#~ msgid "Tool has no attributes" +#~ msgstr "Verktyget har inga attribut" + +#~ msgid "Item" +#~ msgstr "Objekt" + +#~ msgid "Group Properties" +#~ msgstr "Gruppegenskaper" + +#~ msgid "Ungroup" +#~ msgstr "Avgruppera" + +#~ msgid "Link" +#~ msgstr "Länk" + +#~ msgid "Fill settings" +#~ msgstr "Fyllningsinställningar" + +#~ msgid "Break line at selected nodes" +#~ msgstr "Dela linjen vid markerade noder" + +#~ msgid "Import" +#~ msgstr "Importera" + +#~ msgid "Bring to Front" +#~ msgstr "Flytta främst" + +#~ msgid "Send to Back" +#~ msgstr "Skicka bakÃ¥t" + +#~ msgid "Lower selected objects to bottom" +#~ msgstr "Sänk markerade objekt underst" + +#~ msgid "Raise selected objects one position" +#~ msgstr "Höj markerade objekt en position" + +#~ msgid "Lower selected objects one position" +#~ msgstr "Sänk markerade objekt en position" + +#~ msgid "Draw freehand curves and straight lines" +#~ msgstr "Rita kurvor pÃ¥ fri hand och raka linjer" + +#~ msgid "Zoom into precisely selected area" +#~ msgstr "Zooma in i exakt markerade omrÃ¥den" + +#~ msgid "In" +#~ msgstr "In" + +#, fuzzy +#~ msgid "Toggle grid" +#~ msgstr "Växla kanter" + +#, fuzzy +#~ msgid "Toggle guides" +#~ msgstr "Växla kanter" + +#~ msgid "1:1" +#~ msgstr "1:1" + +#~ msgid "1:2" +#~ msgstr "1:2" + +#~ msgid "2:1" +#~ msgstr "2:1" + +#~ msgid "Editing Window" +#~ msgstr "Redigeringsfönster" + +#~ msgid "Editing window properties" +#~ msgstr "Egenskaper för redigeringsfönster" + +#~ msgid "Tool Attributes" +#~ msgstr "Verktygsattribut" + +#~ msgid "Sodipodi" +#~ msgstr "Sodipodi" + +#~ msgid "Desktop settings" +#~ msgstr "Skrivbordsinställningar" + +#, fuzzy +#~ msgid "Iso grid" +#~ msgstr "Visa rutnät" + +#~ msgid "Display settings" +#~ msgstr "Visningsinställningar" + +#~ msgid "Export png file" +#~ msgstr "Exportera png-fil" + +#~ msgid "Object style" +#~ msgstr "Objektstil" + +#, fuzzy +#~ msgid "Inkscape: %s : XML View" +#~ msgstr "Sodipodi: %s: XML-vy" + +#~ msgid "Appending to selection. Press 'a' to toggle Append/New." +#~ msgstr "Lägger till i markering. Tryck \"a\" för att växla Lägg till/Ny." + +#~ msgid "Scalable Vector Graphic (SVG)" +#~ msgstr "Skalbar vektorgrafik (SVG)" + +#~ msgid "Exit Program" +#~ msgstr "Avsluta programmet" + +#~ msgid "New Toplevel Toolbox" +#~ msgstr "Ny övre verktygslÃ¥da" + +#~ msgid "New Docked Toolbox" +#~ msgstr "Ny dockad verktygslÃ¥da" + +#~ msgid "Remove Docked Toolbox" +#~ msgstr "Ta bort dockad verktygslÃ¥da" + +#~ msgid "Drawing Mode" +#~ msgstr "Teckningsläge" + +#~ msgid "SVG with \"xmlns:sodipodi\" namespace" +#~ msgstr "SVG med \"xmlns:sodipodi\"-namnutrymme" + +#, fuzzy +#~ msgid "Scalable Vector Graphics format with inkscape extensions" +#~ msgstr "Format för skalbar vektorgrafik med sodipodi-tillägg" + +#, fuzzy +#~ msgid "" +#~ "%s is not regular file.\n" +#~ "Although inkscape will run, you are\n" +#~ "not able to use extensions (plugins)\n" +#~ msgstr "" +#~ "%s är ingen vanlig fil.\n" +#~ "Även om sodipodi kommer att köra kan du\n" +#~ "inte använda tillägg (insticksmoduler)\n" + +#, fuzzy +#~ msgid "" +#~ "%s either is not valid xml file or\n" +#~ "you do not have read premissions on it.\n" +#~ "Although inkscape will run, you are\n" +#~ "not able to use extensions (plugins)\n" +#~ msgstr "" +#~ "%s är varken en giltig xml-fil eller\n" +#~ "sÃ¥ har du inte läsrättigheter till den.\n" +#~ "Även om sodipodi kommer att köra kan\n" +#~ "du inte använda tillägg (insticksmoduler)\n" + +#, fuzzy +#~ msgid "" +#~ "%s is not valid inkscape extensions file.\n" +#~ "Although inkscape will run, you are\n" +#~ "not able to use extensions (plugins)\n" +#~ msgstr "" +#~ "%s är inte en giltig sodipodi-tilläggsfil.\n" +#~ "Även om sodipodi kommer att köra kan du\n" +#~ "inte använda tillägg (insticksmoduler)\n" + +#, fuzzy +#~ msgid "" +#~ "Cannot create directory %s.\n" +#~ "Although inkscape will run, you are\n" +#~ "not able to use extensions (plugins)\n" +#~ msgstr "" +#~ "Kan inte skapa katalogen %s.\n" +#~ "Även om sodipodi kommer att köra\n" +#~ "kan du inte använda tillägg\n" +#~ "(insticksmoduler)\n" + +#, fuzzy +#~ msgid "" +#~ "%s is not a valid directory.\n" +#~ "Although inkscape will run, you are\n" +#~ "not able to use extensions (plugins)\n" +#~ msgstr "" +#~ "%s är inte en giltig katalog.\n" +#~ "Även om sodipodi kommer att köra\n" +#~ "kan du inte använda tillägg\n" +#~ "(insticksmoduler)\n" + +#, fuzzy +#~ msgid "" +#~ "Cannot create file %s.\n" +#~ "Although inkscape will run, you are\n" +#~ "not able to use extensions (plugins)\n" +#~ msgstr "" +#~ "Kan inte skapa filen %s.\n" +#~ "Även om sodipodi kommer att köra\n" +#~ "kan du inte använda tillägg\n" +#~ "(insticksmoduler)\n" + +#, fuzzy +#~ msgid "" +#~ "Cannot write file %s.\n" +#~ "Although inkscape will run, you are\n" +#~ "not able to use extensions (plugins)\n" +#~ msgstr "" +#~ "Kan inte skriva filen %s.\n" +#~ "Även om sodipodi kommer att köra\n" +#~ "kan du inte använda tillägg\n" +#~ "(insticksmoduler)\n" + +#~ msgid "Unknown item :-(" +#~ msgstr "Okänt objekt :-(" + +#~ msgid "Text and font settings" +#~ msgstr "Text- och typsnittsinställningar" + +#~ msgid "Rotates object 90 degrees clockwise" +#~ msgstr "Roterar objekt 90 grader medurs" + +#~ msgid "Modify existing objects by control nodes" +#~ msgstr "Ändra befintliga objekt genom att använda kontrollnoder" + +#~ msgid "Draw precisely positioned curved and straight lines" +#~ msgstr "Rita exakt positionerade kurvor och raka linjer" + +#~ msgid "Zoom in drawing" +#~ msgstr "Zooma in teckning" + +#~ msgid "Zoom out drawing" +#~ msgstr "Zooma ut teckning" + +#~ msgid "Set zoom factor to 1:1" +#~ msgstr "Ställ in zoomfaktorn till 1:1" + +#~ msgid "Set zoom factor to 1:2" +#~ msgstr "Ställ in zoomfaktorn till 1:2" + +#~ msgid "Set zoom factor to 2:1" +#~ msgstr "Ställ in zoomfaktorn till 2:1" + +#~ msgid "Document" +#~ msgstr "Dokument" + +#~ msgid "Page layout" +#~ msgstr "Sidlayout" + +#~ msgid "Document variant:" +#~ msgstr "Dokumentvariant:" + +#~ msgid "" +#~ "*.svg *.svgz|SVG files\n" +#~ "*.xml|XML files\n" +#~ "*|All files" +#~ msgstr "" +#~ "*.svg *.svgz|SVG-filer\n" +#~ "*.xml|XML-filer\n" +#~ "*|Alla filer" + +#~ msgid "Save document as" +#~ msgstr "Spara dokument som" + +#~ msgid "About sodipodi" +#~ msgstr "Om sodipodi" + +#~ msgid "About Sodipodi" +#~ msgstr "Om Sodipodi" + +#~ msgid "The SVG ID of item" +#~ msgstr "Objektets SVG-ID" + +#~ msgid "The ID is not valid" +#~ msgstr "ID:t är inte giltigt" + +#~ msgid "The ID is already defined" +#~ msgstr "ID:t är redan definierat" + +#~ msgid "Object position and size" +#~ msgstr "Objektposition och -storlek" + +#~ msgid "Position and size" +#~ msgstr "Position och storlek" + +#~ msgid "About" +#~ msgstr "Om" + +#~ msgid "Print" +#~ msgstr "Skriv ut" + +#~ msgid "Draw precisely positioned curves and straight lines" +#~ msgstr "Rita exakt positionerade kurvor och raka linjer" + +#~ msgid "Gradient Units" +#~ msgstr "Toningsenheter" + +#~ msgid "Gradient Spread" +#~ msgstr "Toningsspridning" + +#~ msgid "Align object" +#~ msgstr "Justera objekt" + +#~ msgid "Filter" +#~ msgstr "Filter" + +#~ msgid "Dynahand" +#~ msgstr "Dynahand" + +#~ msgid "Text Editing" +#~ msgstr "Textredigering" + +#~ msgid "Display Properties" +#~ msgstr "Visningsegenskaper" + +#~ msgid "Lower selected objects one level" +#~ msgstr "Sänk markerade objekt en nivÃ¥" + +#~ msgid "Select tool - select and transform objects" +#~ msgstr "Markeringsverktyg - markera och transformera objekt" + +#~ msgid "Save as:" +#~ msgstr "Spara som:" + +#~ msgid "A path - whatever it means" +#~ msgstr "En slinga - vad det nu än betyder" + +#~ msgid "Welcome !" +#~ msgstr "Välkommen!" + +#~ msgid "Sodipodi SVG Document" +#~ msgstr "Sodipodi SVG-dokument" + +#~ msgid "Sodipodi SVG Document factory" +#~ msgstr "Sodipodi SVG-dokumentfabrik" + +#~ msgid "Align objects to vertical mid" +#~ msgstr "Justera objekt mot vertikala mitten" + +#~ msgid "Align outside object to bottom border" +#~ msgstr "Justera utanför objektet mot nederkanten" + +#~ msgid "Align outside object to left border" +#~ msgstr "Justera utanför objektet mot vänsterkanten" + +#~ msgid "Align outside object to right border" +#~ msgstr "Justera utanför objektet mot högerkanten" + +#~ msgid "Align outside object to top border" +#~ msgstr "Justera utanför objektet mot överkanten" + +#~ msgid "Alignment base" +#~ msgstr "Justeringsbas" + +#~ msgid "Choose align type" +#~ msgstr "Välj typ av justering" + +#~ msgid "Parent X =" +#~ msgstr "Förälder X =" + +#~ msgid "Parent Y =" +#~ msgstr "Förälder Y =" + +#~ msgid "X +" +#~ msgstr "X +" + +#~ msgid "Y +" +#~ msgstr "Y +" + +#~ msgid " Color fill " +#~ msgstr " Färgfyllning " + +#~ msgid " General " +#~ msgstr " Allmänt " + +#~ msgid "Add new gradient" +#~ msgstr "Lägg till ny toning" + +#~ msgid "Behind fill" +#~ msgstr "Bakom fyllning" + +#~ msgid "Butt endpoints" +#~ msgstr "Skottavleändpunkter" + +#~ msgid "Choose fill color" +#~ msgstr "Välj fyllningsfärg" + +#~ msgid "Choose stroke color" +#~ msgstr "Välj genomstrykningsfärg " + +#~ msgid "Endpoints:" +#~ msgstr "Ändpunkter:" + +#~ msgid "Fill Color:" +#~ msgstr "Fyllningsfärg:" + +#~ msgid "Fractal fill" +#~ msgstr "Fraktalfyllning" + +#~ msgid "Pick fill color" +#~ msgstr "Välj en fyllningsfärg" + +#~ msgid "Scale with object" +#~ msgstr "Skala med objekt" + +#~ msgid "centimeter" +#~ msgstr "centimeter" + +#~ msgid "color" +#~ msgstr "färg" + +#~ msgid "millimeters" +#~ msgstr "millimeter" + +#~ msgid "points" +#~ msgstr "punkter" + +#~ msgid "1.0MB" +#~ msgstr "1,0 MB" + +#~ msgid "Back One" +#~ msgstr "Flytta bakÃ¥t ett steg" + +#~ msgid "Convert selected segments to curves" +#~ msgstr "Konvertera markerade segment till kurvor" + +#~ msgid "Cusp line at selected nodes" +#~ msgstr "Spetsa linjen vid markerade noder" + +#~ msgid "Desktop" +#~ msgstr "Skrivbord" + +#~ msgid "Drawing Context" +#~ msgstr "Teckningssammanhang" + +#~ msgid "Export picture to png" +#~ msgstr "Exportera bild till png" + +#~ msgid "Forward One" +#~ msgstr "Flytta framÃ¥t ett steg" + +#~ msgid "Include one node into selected segments" +#~ msgstr "Inkludera en nod i markerade segment" + +#~ msgid "Join 2 selected endpoints" +#~ msgstr "Anslut tvÃ¥ markerade ändpunkter" + +#~ msgid "Set dimensions" +#~ msgstr "Ställ in mÃ¥tt" + +#~ msgid "Smooth line at selected nodes" +#~ msgstr "Gör linjen mjukare vid markerade noder" + +#~ msgid "Where to export" +#~ msgstr "Vart det ska exporteras" + +#~ msgid "X0" +#~ msgstr "X0" + +#~ msgid "XML Tree" +#~ msgstr "XML-träd" + +#~ msgid "Y0" +#~ msgstr "Y0" + +#~ msgid "_Align" +#~ msgstr "_Justera" + +#~ msgid "Break apart selected paths" +#~ msgstr "Dela upp markerade slingor" + +#~ msgid "Drawing context" +#~ msgstr "Teckningssammanhang" + +#~ msgid "Edit font style of selected objects" +#~ msgstr "Redigera typsnittsstilen hos markerade objekt" + +#~ msgid "Import " +#~ msgstr "Importera " + +#~ msgid "New drawing" +#~ msgstr "Ny teckning" + +#~ msgid "No I'd rather do some more cool vector drawing with sodipodi." +#~ msgstr "Nej, jag vill hellre rita mer häftig vektorgrafik i sodipodi." + +#~ msgid "Nope !" +#~ msgstr "Nix!" + +#~ msgid "Open new drawing" +#~ msgstr "Öppna ny teckning" + +#~ msgid "Paste from clipboard" +#~ msgstr "Klistra in frÃ¥n urklipp" + +#~ msgid "Preview print drawing" +#~ msgstr "Förhandsgranska teckning" + +#~ msgid "Quit or not quit ?" +#~ msgstr "Avsluta eller inte avsluta?" + +#~ msgid "Really wanna quit sodipodi ?" +#~ msgstr "Vill du verkligen avsluta sodipodi?" + +#~ msgid "Rotate selected objects 90deg clockwise" +#~ msgstr "Rotera markerade objekt 90 grader medurs" + +#~ msgid "Save drawing " +#~ msgstr "Spara teckning " + +#~ msgid "Yep !" +#~ msgstr "Jäpp!" + +#~ msgid "Yes quick! I want to leave sodipodi and come back later." +#~ msgstr "Ja, snabbt! Jag vill lämna sodipodi och komma tillbaka senare." + +#~ msgid "Align to bottom middle" +#~ msgstr "Centrera nederst" + +#~ msgid "Align to bottom right" +#~ msgstr "Högerjustera nederst" + +#~ msgid "Align to center" +#~ msgstr "Centrera" + +#~ msgid "Align to top middle" +#~ msgstr "Centrera överst" + +#~ msgid "Choose metric for center" +#~ msgstr "Välj metrik för mittpunkt" + +#~ msgid "Close dialog - Ctl+c" +#~ msgstr "Stäng dialogfönster - Ctrl+c" + +#~ msgid "Expand dialog - Ctl+e" +#~ msgstr "Utöka dialogfönster - Ctrl+e" + +#~ msgid "Keep height of selection during transformation" +#~ msgstr "BehÃ¥ll höjden pÃ¥ markeringen under transformeringen" + +#~ msgid "Keep width of selection during transformation" +#~ msgstr "BehÃ¥ll bredden pÃ¥ markeringen under transformeringen" + +#~ msgid "Orig. Width: " +#~ msgstr "Originalbredd: " + +#~ msgid "Orig. X: " +#~ msgstr "Orig. X: " + +#~ msgid "Set angle to 0 degrees" +#~ msgstr "Ställ in vinkeln till 0°" + +#~ msgid "Set angle to 180 degrees" +#~ msgstr "Ställ in vinkeln till 180°" + +#~ msgid "Set angle to 270 degrees" +#~ msgstr "Ställ in vinkeln till 270°" + +#~ msgid "Start transformation - Ctl+a" +#~ msgstr "Starta transformering - Ctrl+a" + +#~ msgid "Toggle center given in selection/desktop coordiantes" +#~ msgstr "Växla mittpunkt angiven i markerings-/skrivbordskoordinater" + +#~ msgid "Use alignment during transformation" +#~ msgstr "Använd justering under transformering" + +#~ msgid "Use center as transformation fixpoint" +#~ msgstr "Använd mittpunkt som transformeringsfixpunkt" + +#~ msgid "Y: " +#~ msgstr "Y: " + +#~ msgid "keep aspect" +#~ msgstr "behÃ¥ll proportioner" + +#~ msgid "lock/unlock horizontal and vertical scale" +#~ msgstr "lÃ¥s/lÃ¥s upp horisontell och vertikal skalning" + +#~ msgid "select direction" +#~ msgstr "välj riktning" + +#~ msgid "select direction (horizontal/vertical skew)" +#~ msgstr "välj riktning (horisontell/vertikal snedställning)" + +#~ msgid "select metric for scale" +#~ msgstr "välj metrik för skalning" + +#~ msgid "select metric for values" +#~ msgstr "välj metric för värden" + +#~ msgid "skew" +#~ msgstr "snedställ" + +#~ msgid "toggle absolute/relative move" +#~ msgstr "växla absolut/relativ flytt" + +#~ msgid "toggle absolute/relative scale" +#~ msgstr "växla absolut/relativ skalning" + +#~ msgid "Change Attribute" +#~ msgstr "Ändra attribut" + +#~ msgid "Change Content" +#~ msgstr "Ändra innehÃ¥ll" + +#~ msgid "Do you want to delete attribute?" +#~ msgstr "Vill du ta bort attribut?" + +#~ msgid "Element:" +#~ msgstr "Element:" + +#~ msgid "Enter element name:" +#~ msgstr "Ange elementnamn:" + +#~ msgid "Hierarchy" +#~ msgstr "Hierarki" + +#~ msgid "Key" +#~ msgstr "Nyckel" + +#~ msgid "New Element" +#~ msgstr "Nytt element" + +#~ msgid "Don't save" +#~ msgstr "Spara inte" + +#~ msgid "Ok" +#~ msgstr "OK" + +#~ msgid "You can't delete 'id' attribute!" +#~ msgstr "Du kan inte ta bort \"id\"-attributet!" + +#~ msgid "Do you want to delete attribute %s?" +#~ msgstr "Vill du ta bort attribut %s?" + +#~ msgid "Yes" +#~ msgstr "Ja" + +#~ msgid "No" +#~ msgstr "Nej" + +#~ msgid "You can't delete element %s!" +#~ msgstr "Du kan inte ta bort element %s!" + +#~ msgid "Do you want to delete element %s?" +#~ msgstr "Vill du ta bort element %s?" + +#~ msgid "You can't cut element %s!" +#~ msgstr "Du kan inte klippa ut element %s!" + +#~ msgid "\"" +#~ msgstr "\"" + +#~ msgid "Exported bitmap resolution in pixels per inch (default 72.0)" +#~ msgstr "Exporterad bitmappsupplösning i bildpunkter per tum (standard 72,0)" + +#~ msgid "Style to change:" +#~ msgstr "Stil att ändra:" + +#~ msgid "Oaf options" +#~ msgstr "Oaf-alternativ" + +#~ msgid "Could not initialize Bonobo" +#~ msgstr "Kunde inte initiera Bonobo" + +#~ msgid "Radial" +#~ msgstr "Radiell" + +#~ msgid "Rotate selected objects 90 degrees clockwise" +#~ msgstr "Rotera markerade objekt 90 grader medurs" + +#~ msgid "Choose base unit system for grid" +#~ msgstr "Välj enhetssystemet för rutnätet" + +#~ msgid "Choose color for grid" +#~ msgstr "Välj färgen pÃ¥ rutnätet" + +#~ msgid "Choose unit system for grid snapping" +#~ msgstr "Välj enhetssystem för fästande vid rutnät" + +#~ msgid "Choose unit system for guideline snapping" +#~ msgstr "Välj enhetssystem för fästande vid hjälplinjer" + +#~ msgid "Set maximum distance for grid snapping" +#~ msgstr "Ställ in det maximala avstÃ¥ndet för fästande vid rutnätet" + +#~ msgid "Set maximum distance for guideline snapping" +#~ msgstr "Ställ in maximala avstÃ¥ndet för fästande vid hjälplinjer" + +#~ msgid "Set origin of page coordinate system" +#~ msgstr "Ställ in origo för koordinatsystemet pÃ¥ sidan" + +#~ msgid "Choose paper size" +#~ msgstr "Välj pappersstorlek" + +#~ msgid "Choose unit system" +#~ msgstr "Välj enhetssystem" + +#~ msgid "Set page height" +#~ msgstr "Ställ in pappershöjden" + +#~ msgid "Draw ellipse" +#~ msgstr "Rita ellips" + +#~ msgid "Del" +#~ msgstr "Ta bort" + +#~ msgid "Dup" +#~ msgstr "MÃ¥ngfaldiga" + +#~ msgid "Empty" +#~ msgstr "Tom" + +#~ msgid "Do not use GUI. NB! if exist, should be FIRST argument!" +#~ msgstr "Använd inte grafiskt användargränssnitt. Bör vara FÖRSTA argument!" + +#~ msgid "Millimeters\n" +#~ msgstr "Millimeter\n" + +#~ msgid "Pixels\n" +#~ msgstr "Bildpunkter\n" + +#~ msgid "window2" +#~ msgstr "window2" + +#~ msgid "Copyright Lauris Kaplinski 1999-2000." +#~ msgstr "Copyright Lauris Kaplinski 1999-2000." + +#~ msgid "" +#~ "A Vector Drawing Program.\n" +#~ "Released under GPL" +#~ msgstr "" +#~ "Ett vektorbaserat ritprogram.\n" +#~ "Släppt under GPL" + +#~ msgid "Pixelss" +#~ msgstr "Bildpunkter" + +#~ msgid "dashed" +#~ msgstr "streckad" + +#~ msgid "double" +#~ msgstr "dubbel" + +#~ msgid " Join " +#~ msgstr " Anslut " + +#~ msgid "butt" +#~ msgstr "skottavla" + +#~ msgid "y" +#~ msgstr "y" + +#~ msgid "Height " +#~ msgstr "Höjd " + +#~ msgid "_New File" +#~ msgstr "_Ny fil" + +#~ msgid "Toggles desktop borders (rulers and scrollbars on and off)" +#~ msgstr "Växlar skrivbordskanter (slÃ¥ pÃ¥/av linjaler och rullningslister)" + +#~ msgid "Toggle borders" +#~ msgstr "Växla kanter" + +#~ msgid "Groups selected items" +#~ msgstr "Grupperar markerade objekt" + +#~ msgid "Duplic\t" +#~ msgstr "MÃ¥ngf\t" + +#~ msgid "Up" +#~ msgstr "Upp" + +#~ msgid "Lower one position" +#~ msgstr "Sänk en position" + +#~ msgid "Draw ellipses" +#~ msgstr "Rita ellipser" + +#~ msgid "Write text" +#~ msgstr "Skriv text" + +#~ msgid "Left button zooms in, right out" +#~ msgstr "Vänsterknappen zommar in, högerknappen zommar ut" + +#~ msgid "100%" +#~ msgstr "100%" + +#~ msgid " Rotate " +#~ msgstr " Rotera " + +#~ msgid "any" +#~ msgstr "vilken" + +#~ msgid "left" +#~ msgstr "vänster" + +#~ msgid " flip " +#~ msgstr " vänd " + +#~ msgid " Skew " +#~ msgstr " Snedställ " + +#~ msgid "make copy" +#~ msgstr "skapa kopia" + +#~ msgid "Guidelines setup" +#~ msgstr "Inställningar för hjälplinjer" + +#~ msgid "close dialog" +#~ msgstr "stäng dialogfönster" diff --git a/po/tr.po b/po/tr.po new file mode 100644 index 000000000..b4e19c526 --- /dev/null +++ b/po/tr.po @@ -0,0 +1,11567 @@ +# Turkish translation of sodipodi. +# Copyright (C) 2000-2003 Free Software Foundation, Inc. +# Fatih Demir , 2000. +# Mufit Eribol , 2000. +# Arman Aksoy , 2003. +# +msgid "" +msgstr "" +"Project-Id-Version: sodipodi\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2005-12-04 11:51-0800\n" +"PO-Revision-Date: 2003-02-03 02:18+0200\n" +"Last-Translator: Arman Aksoy (Armish) \n" +"Language-Team: Turkish \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../inkscape.desktop.in.h:1 +msgid "Create and edit Scalable Vector Graphics images" +msgstr "" + +#: ../inkscape.desktop.in.h:2 +#, fuzzy +msgid "Inkscape SVG Vector Illustrator" +msgstr "Vektöt Çizimcisi" + +#: ../../po/../src/arc-context.cpp:350 +msgid "" +"Ctrl: make circle or integer-ratio ellipse, snap arc/segment angle" +msgstr "" + +#: ../../po/../src/arc-context.cpp:351 ../../po/../src/rect-context.cpp:388 +msgid "Shift: draw around the starting point" +msgstr "" + +#: ../../po/../src/arc-context.cpp:413 +#: ../../po/../src/connector-context.cpp:493 +#: ../../po/../src/dyna-draw-context.cpp:506 +#: ../../po/../src/pen-context.cpp:329 ../../po/../src/pencil-context.cpp:208 +#: ../../po/../src/rect-context.cpp:452 ../../po/../src/spiral-context.cpp:421 +#: ../../po/../src/star-context.cpp:427 +msgid "Current layer is hidden. Unhide it to be able to draw on it." +msgstr "" + +#: ../../po/../src/arc-context.cpp:417 +#: ../../po/../src/connector-context.cpp:497 +#: ../../po/../src/dyna-draw-context.cpp:510 +#: ../../po/../src/pen-context.cpp:336 ../../po/../src/pencil-context.cpp:212 +#: ../../po/../src/rect-context.cpp:456 ../../po/../src/spiral-context.cpp:426 +#: ../../po/../src/star-context.cpp:431 +msgid "Current layer is locked. Unlock it to be able to draw on it." +msgstr "" + +#: ../../po/../src/arc-context.cpp:496 +#, c-format +msgid "" +"Ellipse: %s × %s; with Ctrl to make circle or integer-" +"ratio ellipse; with Shift to draw around the starting point" +msgstr "" + +#: ../../po/../src/connector-context.cpp:518 +#, fuzzy +msgid "Creating new connector" +msgstr "Yeni bir SVG dökümanı oluştur" + +#: ../../po/../src/connector-context.cpp:939 +#, fuzzy +msgid "Finishing connector" +msgstr "Serbest" + +#: ../../po/../src/connector-context.cpp:1108 +msgid "Connection point: click or drag to create a new connector" +msgstr "" + +#: ../../po/../src/connector-context.cpp:1185 +msgid "Connector endpoint: drag to reroute or connect to new shapes" +msgstr "" + +#: ../../po/../src/connector-context.cpp:1278 +#, fuzzy +msgid "Select at least one non-connector object." +msgstr "Dökümanda geçiş yok" + +#: ../../po/../src/desktop-events.cpp:238 +#, c-format +msgid "%s at %s" +msgstr "" + +#. TRANSLATORS: This string appears when double-clicking on a guide. +#. This is the distance by which the guide is to be moved. +#: ../../po/../src/desktop-events.cpp:277 +#, fuzzy +msgid " relative by " +msgstr "göreceli içeri taşı" + +#. TRANSLATORS: This string appears when double-clicking on a guide. +#. This is the target location where the guide is to be moved. +#: ../../po/../src/desktop-events.cpp:282 +#: ../../po/../src/desktop-events.cpp:395 +#, fuzzy +msgid " absolute to " +msgstr "Yapış" + +#. create dialog +#: ../../po/../src/desktop-events.cpp:348 +#, fuzzy +msgid "Guideline" +msgstr "Rehber satırı rengi" + +#: ../../po/../src/desktop-events.cpp:432 +#, fuzzy, c-format +msgid "Move %s" +msgstr " Taşı " + +#: ../../po/../src/desktop.cpp:678 +msgid "No previous zoom." +msgstr "" + +#: ../../po/../src/desktop.cpp:703 +msgid "No next zoom." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:182 +#, fuzzy +msgid "Nothing selected." +msgstr "Son seçilen" + +#: ../../po/../src/dialogs/clonetiler.cpp:188 +msgid "More than one object selected." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:195 +#, c-format +msgid "Object has %d tiled clones." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:200 +msgid "Object has no tiled clones." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:865 +#, fuzzy +msgid "Select one object whose tiled clones to unclump." +msgstr "Seçili nesneleri panoya kes" + +#: ../../po/../src/dialogs/clonetiler.cpp:916 +#, fuzzy +msgid "Select one object whose tiled clones to remove." +msgstr "Seçili nesneleri panoya kes" + +#: ../../po/../src/dialogs/clonetiler.cpp:984 +#: ../../po/../src/selection-chemistry.cpp:1774 +#, fuzzy +msgid "Select an object to clone." +msgstr "Seçili nesneleri panoya kes" + +#: ../../po/../src/dialogs/clonetiler.cpp:990 +#: ../../po/../src/selection-chemistry.cpp:1780 +msgid "" +"If you want to clone several objects, group them and clone the " +"group." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1484 +msgid "Per row:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1497 +#, fuzzy +msgid "Per column:" +msgstr "Geçiş seçilmedi" + +#: ../../po/../src/dialogs/clonetiler.cpp:1505 +#, fuzzy +msgid "Randomize:" +msgstr "Son seçilen" + +#: ../../po/../src/dialogs/clonetiler.cpp:1656 +#, fuzzy +msgid "_Symmetry" +msgstr "Simetrik" + +#. TRANSLATORS: For the following 17 symmetry groups, see +#. * http://www.bib.ulb.ac.be/coursmath/doc/17.htm (visual examples); +#. * http://www.clarku.edu/~djoyce/wallpaper/seventeen.html (English vocabulary); or +#. * http://membres.lycos.fr/villemingerard/Geometri/Sym1D.htm (French vocabulary). +#. +#: ../../po/../src/dialogs/clonetiler.cpp:1664 +msgid "Select one of the 17 symmetry groups for the tiling" +msgstr "" + +#. TRANSLATORS: "translation" means "shift" / "displacement" here. +#: ../../po/../src/dialogs/clonetiler.cpp:1675 +msgid "P1: simple translation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1676 +msgid "P2: 180° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1677 +msgid "PM: reflection" +msgstr "" + +#. TRANSLATORS: "glide reflection" is a reflection and a translation combined. +#. For more info, see http://mathforum.org/sum95/suzanne/symsusan.html +#: ../../po/../src/dialogs/clonetiler.cpp:1680 +msgid "PG: glide reflection" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1681 +msgid "CM: reflection + glide reflection" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1682 +msgid "PMM: reflection + reflection" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1683 +msgid "PMG: reflection + 180° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1684 +msgid "PGG: glide reflection + 180° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1685 +msgid "CMM: reflection + reflection + 180° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1686 +msgid "P4: 90° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1687 +msgid "P4M: 90° rotation + 45° reflection" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1688 +msgid "P4G: 90° rotation + 90° reflection" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1689 +msgid "P3: 120° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1690 +msgid "P31M: reflection + 120° rotation, dense" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1691 +msgid "P3M1: reflection + 120° rotation, sparse" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1692 +msgid "P6: 60° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1693 +msgid "P6M: reflection + 60° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1721 +msgid "S_hift" +msgstr "" + +#. TRANSLATORS: "shift" means: the tiles will be shifted (offset) horizontally by this amount +#: ../../po/../src/dialogs/clonetiler.cpp:1731 +#, fuzzy, no-c-format +msgid "Shift X:" +msgstr "Değiştir" + +#: ../../po/../src/dialogs/clonetiler.cpp:1739 +#, no-c-format +msgid "Horizontal shift per row (in % of tile width)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1747 +#, no-c-format +msgid "Horizontal shift per column (in % of tile width)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1754 +msgid "Randomize the horizontal shift by this percentage" +msgstr "" + +#. TRANSLATORS: "shift" means: the tiles will be shifted (offset) vertically by this amount +#: ../../po/../src/dialogs/clonetiler.cpp:1764 +#, fuzzy, no-c-format +msgid "Shift Y:" +msgstr "Değiştir" + +#: ../../po/../src/dialogs/clonetiler.cpp:1772 +#, no-c-format +msgid "Vertical shift per row (in % of tile height)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1780 +#, no-c-format +msgid "Vertical shift per column (in % of tile height)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1787 +msgid "Randomize the vertical shift by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1795 +#, fuzzy +msgid "Exponent:" +msgstr "Değiştir" + +#: ../../po/../src/dialogs/clonetiler.cpp:1802 +msgid "Whether rows are spaced evenly (1), converge (<1) or diverge (>1)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1809 +msgid "Whether columns are spaced evenly (1), converge (<1) or diverge (>1)" +msgstr "" + +#. TRANSLATORS: "Alternate" is a verb here +#: ../../po/../src/dialogs/clonetiler.cpp:1817 +#: ../../po/../src/dialogs/clonetiler.cpp:1907 +#: ../../po/../src/dialogs/clonetiler.cpp:1966 +#: ../../po/../src/dialogs/clonetiler.cpp:2022 +#: ../../po/../src/dialogs/clonetiler.cpp:2153 +msgid "Alternate:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1823 +msgid "Alternate the sign of shifts for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1828 +msgid "Alternate the sign of shifts for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1837 +#, fuzzy +msgid "Sc_ale" +msgstr "Cetvel" + +#: ../../po/../src/dialogs/clonetiler.cpp:1845 +#, fuzzy +msgid "Scale X:" +msgstr "Değiştir" + +#: ../../po/../src/dialogs/clonetiler.cpp:1853 +#, fuzzy, no-c-format +msgid "Horizontal scale per row (in % of tile width)" +msgstr "yatay" + +#: ../../po/../src/dialogs/clonetiler.cpp:1861 +#, fuzzy, no-c-format +msgid "Horizontal scale per column (in % of tile width)" +msgstr "yatay" + +#: ../../po/../src/dialogs/clonetiler.cpp:1868 +msgid "Randomize the horizontal scale by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1876 +#, fuzzy +msgid "Scale Y:" +msgstr "Değiştir" + +#: ../../po/../src/dialogs/clonetiler.cpp:1884 +#, no-c-format +msgid "Vertical scale per row (in % of tile height)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1892 +#, no-c-format +msgid "Vertical scale per column (in % of tile height)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1899 +msgid "Randomize the vertical scale by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1913 +msgid "Alternate the sign of scales for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1918 +#, fuzzy +msgid "Alternate the sign of scales for each column" +msgstr "yatay" + +#: ../../po/../src/dialogs/clonetiler.cpp:1927 +#, fuzzy +msgid "_Rotation" +msgstr "Devir:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1935 +#, fuzzy +msgid "Angle:" +msgstr "Değiştir" + +#: ../../po/../src/dialogs/clonetiler.cpp:1943 +#, no-c-format +msgid "Rotate tiles by this angle for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1951 +#, no-c-format +msgid "Rotate tiles by this angle for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1958 +msgid "Randomize the rotation angle by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1972 +msgid "Alternate the rotation direction for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1977 +msgid "Alternate the rotation direction for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1985 +#, fuzzy +msgid "_Opacity" +msgstr "Donukluk:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1993 +#, fuzzy +msgid "Fade out:" +msgstr "Değiştir" + +#: ../../po/../src/dialogs/clonetiler.cpp:2000 +msgid "Decrease tile opacity by this percentage for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2007 +msgid "Decrease tile opacity by this percentage for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2014 +msgid "Randomize the tile opacity by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2028 +msgid "Alternate the sign of opacity change for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2033 +msgid "Alternate the sign of opacity change for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2041 +#, fuzzy +msgid "Co_lor" +msgstr "Renk" + +#: ../../po/../src/dialogs/clonetiler.cpp:2046 +#, fuzzy +msgid "Initial color: " +msgstr "Dolgu rengi : " + +#: ../../po/../src/dialogs/clonetiler.cpp:2050 +msgid "Initial color of tiled clones" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2050 +msgid "" +"Initial color for clones (works only if the original has unset fill or " +"stroke)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2065 +#, fuzzy +msgid "H:" +msgstr "Değiştir" + +#: ../../po/../src/dialogs/clonetiler.cpp:2072 +msgid "Change the tile hue by this percentage for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2079 +msgid "Change the tile hue by this percentage for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2086 +msgid "Randomize the tile hue by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2095 +#, fuzzy +msgid "S:" +msgstr "Değiştir" + +#: ../../po/../src/dialogs/clonetiler.cpp:2102 +msgid "Change the color saturation by this percentage for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2109 +msgid "Change the color saturation by this percentage for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2116 +msgid "Randomize the color saturation by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2124 +#, fuzzy +msgid "L:" +msgstr "Değiştir" + +#: ../../po/../src/dialogs/clonetiler.cpp:2131 +msgid "Change the color lightness by this percentage for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2138 +msgid "Change the color lightness by this percentage for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2145 +msgid "Randomize the color lightness by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2159 +msgid "Alternate the sign of color changes for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2164 +msgid "Alternate the sign of color changes for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2172 +#, fuzzy +msgid "_Trace" +msgstr "Ä°pucu" + +#: ../../po/../src/dialogs/clonetiler.cpp:2179 +msgid "Trace the drawing under the tiles" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2183 +msgid "" +"For each clone, pick a value from the drawing in that clone's location and " +"apply it to the clone" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2197 +msgid "1. Pick from the drawing:" +msgstr "" + +#. ----Hbox2 +#: ../../po/../src/dialogs/clonetiler.cpp:2208 +#: ../../po/../src/dialogs/clonetiler.cpp:2355 +#: ../../po/../src/ui/dialog/tracedialog.cpp:445 +#, fuzzy +msgid "Color" +msgstr "Renk" + +#: ../../po/../src/dialogs/clonetiler.cpp:2209 +msgid "Pick the visible color and opacity" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2216 +#: ../../po/../src/dialogs/clonetiler.cpp:2365 +#: ../share/extensions/dropshadow.inx.h:3 +#, fuzzy +msgid "Opacity" +msgstr "Donukluk:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2217 +msgid "Pick the total accumulated opacity" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2224 +msgid "R" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2225 +msgid "Pick the Red component of the color" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2232 +msgid "G" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2233 +msgid "Pick the Green component of the color" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2240 +msgid "B" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2241 +msgid "Pick the Blue component of the color" +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2250 +msgid "clonetiler|H" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2251 +#, fuzzy +msgid "Pick the hue of the color" +msgstr "Renk seçiniz" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2260 +msgid "clonetiler|S" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2261 +#, fuzzy +msgid "Pick the saturation of the color" +msgstr "Renk seçiniz" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2270 +msgid "clonetiler|L" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2271 +msgid "Pick the lightness of the color" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2281 +msgid "2. Tweak the picked value:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2291 +msgid "Gamma-correct:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2296 +msgid "Shift the mid-range of the picked value upwards (>0) or downwards (<0)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2303 +msgid "Randomize:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2308 +msgid "Randomize the picked value by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2315 +#, fuzzy +msgid "Invert:" +msgstr "Nokta" + +#: ../../po/../src/dialogs/clonetiler.cpp:2319 +msgid "Invert the picked value" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2325 +msgid "3. Apply the value to the clones':" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2335 +#, fuzzy +msgid "Presence" +msgstr "Koru" + +#: ../../po/../src/dialogs/clonetiler.cpp:2338 +msgid "" +"Each clone is created with the probability determined by the picked value in " +"that point" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2345 +#, fuzzy +msgid "Size" +msgstr "Bölümler:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2348 +msgid "Each clone's size is determined by the picked value in that point" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2358 +msgid "" +"Each clone is painted by the picked color (the original must have unset fill " +"or stroke)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2368 +msgid "Each clone's opacity is determined by the picked value in that point" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2395 +msgid "How many rows in the tiling" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2415 +msgid "How many columns in the tiling" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2445 +msgid "Width of the rectangle to be filled" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2470 +msgid "Height of the rectangle to be filled" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2485 +#, fuzzy +msgid "Rows, columns: " +msgstr "Değiştir" + +#: ../../po/../src/dialogs/clonetiler.cpp:2486 +msgid "Create the specified number of rows and columns" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2495 +#, fuzzy +msgid "Width, height: " +msgstr "Yükseklik:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2496 +msgid "Fill the specified width and height with the tiling" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2512 +#, fuzzy +msgid "Use saved size and position of the tile" +msgstr "Nesne boyutu ve konumu" + +#: ../../po/../src/dialogs/clonetiler.cpp:2515 +msgid "" +"Pretend that the size and position of the tile are the same as the last time " +"you tiled it (if any), instead of using the current size" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2539 +#, fuzzy +msgid " _Create " +msgstr "Değiştir" + +#: ../../po/../src/dialogs/clonetiler.cpp:2541 +msgid "Create and tile the clones of the selection" +msgstr "" + +#. TRANSLATORS: if a group of objects are "clumped" together, then they +#. are unevenly spread in the given amount of space - as shown in the +#. diagrams on the left in the following screenshot: +#. http://www.inkscape.org/screenshots/gallery/inkscape-0.42-CVS-tiles-unclump.png +#. So unclumping is the process of spreading a number of objects out more evenly. +#: ../../po/../src/dialogs/clonetiler.cpp:2556 +msgid " _Unclump " +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2557 +msgid "Spread out clones to reduce clumping; can be applied repeatedly" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2563 +#, fuzzy +msgid " Re_move " +msgstr "Bağlantıyı kaldır" + +#: ../../po/../src/dialogs/clonetiler.cpp:2564 +msgid "Remove existing tiled clones of the selected object (siblings only)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2580 +#, fuzzy +msgid " R_eset " +msgstr "Bağlantıyı kaldır" + +#. TRANSLATORS: "change" is a noun here +#: ../../po/../src/dialogs/clonetiler.cpp:2582 +msgid "" +"Reset all shifts, scales, rotates, opacity and color changes in the dialog " +"to zero" +msgstr "" + +#: ../../po/../src/dialogs/color-picker.cpp:280 +msgid "Close" +msgstr "Kapat" + +#: ../../po/../src/dialogs/debugdialog.cpp:138 +msgid "Messages" +msgstr "" + +#. ## Add a menu for clear() +#: ../../po/../src/dialogs/debugdialog.cpp:144 +#: ../../po/../src/menus-skeleton.h:16 +#: ../../po/../src/ui/dialog/messages.cpp:56 +#: ../../po/../src/ui/dialog/scriptdialog.cpp:181 +msgid "_File" +msgstr "_Dosya" + +#. TRANSLATORS: "Clear" is a verb here +#: ../../po/../src/dialogs/debugdialog.cpp:145 +#: ../../po/../src/dialogs/find.cpp:753 +#: ../../po/../src/ui/dialog/messages.cpp:57 +#: ../../po/../src/ui/dialog/scriptdialog.cpp:182 +#, fuzzy +msgid "_Clear" +msgstr "Kapat" + +#: ../../po/../src/dialogs/debugdialog.cpp:147 +#: ../../po/../src/ui/dialog/messages.cpp:59 +msgid "Capture log messages" +msgstr "" + +#: ../../po/../src/dialogs/debugdialog.cpp:149 +#: ../../po/../src/ui/dialog/messages.cpp:61 +msgid "Release log messages" +msgstr "" + +#. Notebook tab +#: ../../po/../src/dialogs/desktop-properties.cpp:909 +#: ../../po/../src/ui/dialog/document-preferences.cpp:89 +#: ../../po/../src/ui/widget/panel.cpp:107 +msgid "Grid" +msgstr "Izgara" + +#. Checkbuttons +#. / \todo FIXME: gray out snapping when grid is off +#. / \todo FIXME: gray out snapping when grid is off. +#. / Dissenting view: you want snapping without grid. +#: ../../po/../src/dialogs/desktop-properties.cpp:917 +#: ../../po/../src/ui/dialog/document-preferences.cpp:179 +msgid "Show grid" +msgstr "Izgarayı göster" + +#: ../../po/../src/dialogs/desktop-properties.cpp:917 +#: ../../po/../src/ui/dialog/document-preferences.cpp:179 +#: ../../po/../src/verbs.cpp:2115 +#, fuzzy +msgid "Show or hide grid" +msgstr "Izgarayı göster" + +#: ../../po/../src/dialogs/desktop-properties.cpp:918 +#: ../../po/../src/ui/dialog/document-preferences.cpp:180 +#, fuzzy +msgid "Snap bounding boxes to grid" +msgstr "Izgaraya yakala" + +#: ../../po/../src/dialogs/desktop-properties.cpp:918 +#: ../../po/../src/dialogs/desktop-properties.cpp:1001 +#: ../../po/../src/ui/dialog/document-preferences.cpp:181 +#: ../../po/../src/ui/dialog/document-preferences.cpp:236 +msgid "Snap the edges of the object bounding boxes" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:919 +#: ../../po/../src/ui/dialog/document-preferences.cpp:183 +#, fuzzy +msgid "Snap nodes to grid" +msgstr "Izgaraya yakala" + +#: ../../po/../src/dialogs/desktop-properties.cpp:919 +#: ../../po/../src/dialogs/desktop-properties.cpp:1002 +#: ../../po/../src/ui/dialog/document-preferences.cpp:184 +#: ../../po/../src/ui/dialog/document-preferences.cpp:239 +msgid "Snap path nodes, text baselines, ellipse centers, etc." +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:937 +#: ../../po/../src/ui/dialog/document-preferences.cpp:186 +msgid "Grid units:" +msgstr "Izgara birimleri:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:939 +#: ../../po/../src/ui/dialog/document-preferences.cpp:187 +msgid "Origin X:" +msgstr "Orijin X:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:942 +#: ../../po/../src/ui/dialog/document-preferences.cpp:189 +msgid "Origin Y:" +msgstr "Orijin Y:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:945 +#: ../../po/../src/ui/dialog/document-preferences.cpp:191 +msgid "Spacing X:" +msgstr "X aralığı:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:948 +#: ../../po/../src/ui/dialog/document-preferences.cpp:193 +msgid "Spacing Y:" +msgstr "Y aralığı:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:952 +#: ../../po/../src/dialogs/desktop-properties.cpp:1013 +#: ../../po/../src/ui/dialog/document-preferences.cpp:195 +#: ../../po/../src/ui/dialog/document-preferences.cpp:241 +msgid "Snap units:" +msgstr "Yakalama birimleri:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:955 +#: ../../po/../src/dialogs/desktop-properties.cpp:1016 +#: ../../po/../src/ui/dialog/document-preferences.cpp:196 +#: ../../po/../src/ui/dialog/document-preferences.cpp:242 +msgid "Snap distance:" +msgstr "Yakalama uzaklığı:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:958 +#: ../../po/../src/ui/dialog/document-preferences.cpp:199 +#, fuzzy +msgid "Grid line color:" +msgstr "Rehber satırı rengi" + +#: ../../po/../src/dialogs/desktop-properties.cpp:959 +#: ../../po/../src/ui/dialog/document-preferences.cpp:199 +#, fuzzy +msgid "Grid line color" +msgstr "Rehber satırı rengi" + +#: ../../po/../src/dialogs/desktop-properties.cpp:959 +#: ../../po/../src/ui/dialog/document-preferences.cpp:200 +#, fuzzy +msgid "Color of grid lines" +msgstr "Rehber çizgileri rengini seçiniz" + +#: ../../po/../src/dialogs/desktop-properties.cpp:961 +#: ../../po/../src/ui/dialog/document-preferences.cpp:201 +#, fuzzy +msgid "Major grid line color:" +msgstr "Rehber satırı rengi" + +#: ../../po/../src/dialogs/desktop-properties.cpp:962 +#: ../../po/../src/ui/dialog/document-preferences.cpp:201 +#, fuzzy +msgid "Major grid line color" +msgstr "Rehber satırı rengi" + +#: ../../po/../src/dialogs/desktop-properties.cpp:962 +#: ../../po/../src/ui/dialog/document-preferences.cpp:202 +#, fuzzy +msgid "Color of the major (highlighted) grid lines" +msgstr "İşaretli rehber çizgileri için renk seçiniz" + +#: ../../po/../src/dialogs/desktop-properties.cpp:965 +#: ../../po/../src/ui/dialog/document-preferences.cpp:204 +#, fuzzy +msgid "Major grid line every:" +msgstr "Rehber satırı rengi" + +#. TRANSLATORS: This belongs to the "Major grid line every:" string, +#. see grid settings in the "Document Preferences" dialog +#: ../../po/../src/dialogs/desktop-properties.cpp:977 +#: ../../po/../src/ui/dialog/document-preferences.cpp:204 +#, fuzzy +msgid "lines" +msgstr "Kapat" + +#. Guidelines page +#: ../../po/../src/dialogs/desktop-properties.cpp:991 +#: ../../po/../src/ui/dialog/document-preferences.cpp:90 +msgid "Guides" +msgstr "Rehberler" + +#. / \todo FIXME: gray out snapping when guides are off +#. / Dissenting view: you want snapping without guides. +#: ../../po/../src/dialogs/desktop-properties.cpp:1000 +#: ../../po/../src/ui/dialog/document-preferences.cpp:234 +msgid "Show guides" +msgstr "Rehberleri göster" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1000 +#: ../../po/../src/ui/dialog/document-preferences.cpp:234 +#: ../../po/../src/verbs.cpp:2116 +#, fuzzy +msgid "Show or hide guides" +msgstr "Rehberleri göster" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1001 +#: ../../po/../src/ui/dialog/document-preferences.cpp:235 +#, fuzzy +msgid "Snap bounding boxes to guides" +msgstr "Rehberlere yakala" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1002 +#: ../../po/../src/ui/dialog/document-preferences.cpp:238 +#, fuzzy +msgid "Snap points to guides" +msgstr "Izgaraya yakala" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1020 +#: ../../po/../src/ui/dialog/document-preferences.cpp:243 +#, fuzzy +msgid "Guide color:" +msgstr "Rehber rengi:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1021 +#: ../../po/../src/ui/dialog/document-preferences.cpp:243 +msgid "Guideline color" +msgstr "Rehber satırı rengi" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1021 +#: ../../po/../src/ui/dialog/document-preferences.cpp:244 +#, fuzzy +msgid "Color of guidelines" +msgstr "Rehber çizgileri rengini seçiniz" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1023 +#: ../../po/../src/ui/dialog/document-preferences.cpp:245 +msgid "Highlight color:" +msgstr "İşaret rengi:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1024 +#: ../../po/../src/ui/dialog/document-preferences.cpp:245 +msgid "Highlighted guideline color" +msgstr "İşaretli rehber satırlarının rengi" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1024 +#: ../../po/../src/ui/dialog/document-preferences.cpp:246 +msgid "Color of a guideline when it is under mouse" +msgstr "" + +#. Page page +#: ../../po/../src/dialogs/desktop-properties.cpp:1029 +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:855 +#: ../../po/../src/ui/dialog/document-preferences.cpp:88 +#: ../../po/../src/widgets/desktop-widget.cpp:1061 +msgid "Page" +msgstr "Sayfa" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1039 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +#, fuzzy +msgid "Background:" +msgstr "Bitiş rengi" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1040 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +#, fuzzy +msgid "Background color" +msgstr "Bitiş rengi" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1041 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +msgid "" +"Color and transparency of the page background (also used for bitmap export)" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1045 +#: ../../po/../src/ui/dialog/document-preferences.cpp:147 +#, fuzzy +msgid "Show page border" +msgstr "Ayrıracı göster" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1049 +#: ../../po/../src/ui/dialog/document-preferences.cpp:148 +#, fuzzy +msgid "Border on top of drawing" +msgstr "Çizimi göster" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1052 +#: ../../po/../src/ui/dialog/document-preferences.cpp:149 +#, fuzzy +msgid "Border color:" +msgstr "Izgara rengi" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1053 +#: ../../po/../src/ui/dialog/document-preferences.cpp:149 +#, fuzzy +msgid "Page border color" +msgstr "Izgara rengi" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1054 +#: ../../po/../src/ui/dialog/document-preferences.cpp:150 +#, fuzzy +msgid "Color of the page border" +msgstr "Ayrıracı göster" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1059 +#: ../../po/../src/ui/dialog/document-preferences.cpp:152 +msgid "Show page shadow" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1063 +#: ../../po/../src/ui/dialog/document-preferences.cpp:153 +#, fuzzy +msgid "Default units:" +msgstr "Öntanımlı" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1069 +msgid "Units for the tool controls, ruler, and the statusbar" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1086 +#: ../../po/../src/ui/widget/page-sizer.cpp:209 +#, fuzzy +msgid "Page size:" +msgstr "Kağıt boyutu:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1110 +#: ../../po/../src/ui/widget/page-sizer.cpp:219 +msgid "Custom" +msgstr "Özel" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1121 +#: ../../po/../src/ui/widget/page-sizer.cpp:225 +#, fuzzy +msgid "Page orientation:" +msgstr "Oran:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1133 +#: ../../po/../src/ui/widget/page-sizer.cpp:232 +#, fuzzy +msgid "Landscape" +msgstr "Sodipodi: %s : XML Görünümü" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1139 +#: ../../po/../src/ui/widget/page-sizer.cpp:234 +#, fuzzy +msgid "Portrait" +msgstr "Nokta" + +#. Custom paper frame +#: ../../po/../src/dialogs/desktop-properties.cpp:1148 +#: ../../po/../src/ui/widget/page-sizer.cpp:249 +#, fuzzy +msgid "Custom size" +msgstr "Özel" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1160 +#: ../../po/../src/dialogs/export.cpp:269 +#: ../../po/../src/ui/widget/page-sizer.cpp:261 +msgid "Units:" +msgstr "Birimler:" + +#. Stroke width +#: ../../po/../src/dialogs/desktop-properties.cpp:1162 +#: ../../po/../src/dialogs/export.cpp:310 +#: ../../po/../src/dialogs/object-attributes.cpp:55 +#: ../../po/../src/dialogs/stroke-style.cpp:985 +#: ../../po/../src/ui/widget/page-sizer.cpp:262 +#: ../../po/../src/widgets/toolbox.cpp:1957 +msgid "Width:" +msgstr "Genişlik:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1183 +#: ../../po/../src/dialogs/export.cpp:326 +#: ../../po/../src/dialogs/export.cpp:431 +#: ../../po/../src/dialogs/object-attributes.cpp:56 +#: ../../po/../src/ui/widget/page-sizer.cpp:263 +msgid "Height:" +msgstr "Yükseklik:" + +#. +#. * Ownership metadata tab +#. +#: ../../po/../src/dialogs/desktop-properties.cpp:1206 +msgid "Metadata" +msgstr "" + +#. add license selector pull-down +#: ../../po/../src/dialogs/desktop-properties.cpp:1225 +msgid "License" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1255 +msgid "Proprietary" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:212 +#, fuzzy +msgid "When transforming, show:" +msgstr "Nesne dönüşümleri" + +#: ../../po/../src/dialogs/display-settings.cpp:223 +#, fuzzy +msgid "Objects" +msgstr "Nesne" + +#: ../../po/../src/dialogs/display-settings.cpp:224 +msgid "Show the actual objects when moving or transforming" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:231 +#, fuzzy +msgid "Box outline" +msgstr "Taslağı göster" + +#: ../../po/../src/dialogs/display-settings.cpp:232 +msgid "Show only a box outline of the objects when moving or transforming" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:238 +#, fuzzy +msgid "Per-object selection cue:" +msgstr "Seçili nesneleri eğrilere çevir" + +#. sorationsnapsperpi == 0 means no snapping +#: ../../po/../src/dialogs/display-settings.cpp:249 +#: ../../po/../src/dialogs/display-settings.cpp:386 +#: ../../po/../src/dialogs/display-settings.cpp:441 +#: ../../po/../src/dialogs/display-settings.cpp:1482 +#: ../../po/../src/dialogs/stroke-style.cpp:791 +#: ../../po/../src/interface.cpp:741 +#: ../../po/../src/ui/widget/selected-style.cpp:100 +#: ../../po/../src/verbs.cpp:1842 +msgid "None" +msgstr "Yok" + +#: ../../po/../src/dialogs/display-settings.cpp:250 +msgid "No per-object selection indication" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:256 +msgid "Mark" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:257 +msgid "Each selected object has a diamond mark in the top left corner" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:264 +msgid "Box" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:265 +msgid "Each selected object displays its bounding box" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:270 +#, fuzzy +msgid "Default scale origin:" +msgstr "Öntanımlı kursor töleransı" + +#: ../../po/../src/dialogs/display-settings.cpp:281 +#, fuzzy +msgid "Opposite bounding box edge" +msgstr "Izgaraya yakala" + +#: ../../po/../src/dialogs/display-settings.cpp:282 +msgid "Default scale origin will be on the bounding box of the item" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:288 +msgid "Farthest opposite node" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:289 +msgid "Default scale origin will be on the bounding box of the item's points" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:341 +#, fuzzy +msgid "degrees" +msgstr "derece" + +#: ../../po/../src/dialogs/display-settings.cpp:350 +msgid "" +"Rotating with Ctrl pressed snaps every that much degrees; also, pressing " +"[ or ] rotates by this amount" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:407 +msgid "Rotation snaps every:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:430 +msgid "" +"None: dialogs are treated as regular windows; Normal: dialogs stay on top of " +"document windows; Aggressive: same as Normal but may work better with some " +"window managers." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:451 +msgid "Normal" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:461 +msgid "Aggressive" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:475 +#, fuzzy +msgid "Dialogs on top:" +msgstr "Pencereler" + +#: ../../po/../src/dialogs/display-settings.cpp:645 +#, fuzzy +msgid "Show selection cue" +msgstr "Seçili nesneleri eğrilere çevir" + +#: ../../po/../src/dialogs/display-settings.cpp:646 +msgid "" +"Whether selected objects display a selection cue (the same as in selector)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:657 +#, fuzzy +msgid "Enable gradient editing" +msgstr "Geçiş vektörü" + +#: ../../po/../src/dialogs/display-settings.cpp:658 +msgid "Whether selected objects display gradient editing controls" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:719 +#, fuzzy +msgid "No objects selected to take the style from." +msgstr "Seçili nesneleri eğrilere dönder" + +#: ../../po/../src/dialogs/display-settings.cpp:728 +msgid "" +"More than one object selected. Cannot take style from multiple " +"objects." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:767 +#, fuzzy +msgid "Create new objects with:" +msgstr "MEtin aracı - düzenlenebilir metin nesneleri yaratır" + +#: ../../po/../src/dialogs/display-settings.cpp:777 +#, fuzzy +msgid "Take from selection" +msgstr "Seçileni dönüştür" + +#: ../../po/../src/dialogs/display-settings.cpp:778 +msgid "Remember the style of the (first) selected object as this tool's style" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:782 +#, fuzzy +msgid "Last used style" +msgstr "Vuruş stili" + +#: ../../po/../src/dialogs/display-settings.cpp:782 +msgid "Apply the style you last set on an object" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:790 +msgid "This tool's own style:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:790 +msgid "" +"Each tool may store its own style to apply to the newly created objects. Use " +"the button below to set it." +msgstr "" + +#. Mouse +#: ../../po/../src/dialogs/display-settings.cpp:877 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:55 +#, fuzzy +msgid "Mouse" +msgstr "Taşı" + +#. TRANSLATORS: "Grab" is a noun here. "Grab sensitivity" is intended to mean how +#. * close on the screen you need to be to an object to be able to grab it with mouse (in +#. * pixels). +#: ../../po/../src/dialogs/display-settings.cpp:883 +#, fuzzy +msgid "Grab sensitivity:" +msgstr "Duyarlı hale getir" + +#: ../../po/../src/dialogs/display-settings.cpp:884 +msgid "" +"How close on the screen you need to be to an object to be able to grab it " +"with mouse (in screen pixels)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:885 +#: ../../po/../src/dialogs/display-settings.cpp:897 +#: ../../po/../src/dialogs/display-settings.cpp:912 +#: ../../po/../src/dialogs/display-settings.cpp:930 +#: ../../po/../src/dialogs/display-settings.cpp:970 +msgid "pixels" +msgstr "piksel" + +#: ../../po/../src/dialogs/display-settings.cpp:895 +msgid "Click/drag threshold:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:896 +msgid "" +"Maximum mouse drag (in screen pixels) which is considered a click, not a drag" +msgstr "" + +#. Scrolling +#: ../../po/../src/dialogs/display-settings.cpp:907 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:56 +msgid "Scrolling" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:910 +msgid "Mouse wheel scrolls by:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:911 +msgid "" +"One mouse wheel notch scrolls by this distance in screen pixels " +"(horizontally with Shift)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:920 +msgid "Ctrl+arrows" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:928 +msgid "Scroll by:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:929 +msgid "Pressing Ctrl+arrow key scrolls by this distance (in screen pixels)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:939 +#, fuzzy +msgid "Acceleration:" +msgstr "Seçim" + +#: ../../po/../src/dialogs/display-settings.cpp:940 +msgid "" +"Pressing and holding Ctrl+arrow will gradually speed up scrolling (0 for no " +"acceleration)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:949 +msgid "Autoscrolling" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:957 +#, fuzzy +msgid "Speed:" +msgstr "Kırmızı:" + +#: ../../po/../src/dialogs/display-settings.cpp:958 +msgid "" +"How fast the canvas autoscrolls when you drag beyond canvas edge (0 to turn " +"autoscroll off)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:968 +#: ../../po/../src/ui/dialog/tracedialog.cpp:357 +#: ../../po/../src/ui/dialog/tracedialog.cpp:390 +msgid "Threshold:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:969 +msgid "" +"How far (in screen pixels) you need to be from the canvas edge to trigger " +"autoscroll; positive is outside the canvas, negative is within the canvas" +msgstr "" + +#. Steps +#: ../../po/../src/dialogs/display-settings.cpp:979 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:57 +#, fuzzy +msgid "Steps" +msgstr "Stil" + +#: ../../po/../src/dialogs/display-settings.cpp:982 +msgid "Arrow keys move by:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:983 +msgid "" +"Pressing an arrow key moves selected object(s) or node(s) by this distance " +"(in px units)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:984 +#: ../../po/../src/dialogs/display-settings.cpp:995 +#: ../../po/../src/dialogs/display-settings.cpp:1006 +#: ../../po/../src/helper/units.cpp:42 +msgid "px" +msgstr "px" + +#: ../../po/../src/dialogs/display-settings.cpp:993 +msgid "> and < scale by:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:994 +msgid "" +"Pressing > or < scales selection up or down by this increment (in px units)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1004 +msgid "Inset/Outset by:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1005 +msgid "" +"Inset and Outset commands displace the path by this distance (in px units)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1017 +msgid "Compass-like display of angles" +msgstr "" + +#. TRANSLATORS: "positive clockwise" means "increasing in clockwise direction" +#: ../../po/../src/dialogs/display-settings.cpp:1019 +msgid "" +"When on, angles are displayed with 0 at north, 0 to 360 range, positive " +"clockwise; otherwise with 0 at east, -180 to 180 range, positive " +"counterclockwise" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1026 +#, fuzzy +msgid "Zoom in/out by:" +msgstr "Küçült" + +#: ../../po/../src/dialogs/display-settings.cpp:1027 +msgid "" +"Zoom tool click, +/- keys, and middle click zoom in and out by this " +"multiplier" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1028 +#: ../../po/../src/helper/units.cpp:44 +msgid "%" +msgstr "%" + +#. Tools +#: ../../po/../src/dialogs/display-settings.cpp:1037 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:58 +msgid "Tools" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1045 +#, fuzzy +msgid "Selector" +msgstr "Seç" + +#: ../../po/../src/dialogs/display-settings.cpp:1056 +msgid "Node" +msgstr "Düğüm" + +#: ../../po/../src/dialogs/display-settings.cpp:1064 +#: ../../po/../src/verbs.cpp:2073 +#: ../../po/../src/widgets/desktop-widget.cpp:277 +msgid "Zoom" +msgstr "Büyüt" + +#. The 4 shape tools +#: ../../po/../src/dialogs/display-settings.cpp:1071 +#, fuzzy +msgid "Shapes" +msgstr "Şekillendir" + +#: ../../po/../src/dialogs/display-settings.cpp:1079 +#: ../../po/../src/verbs.cpp:2055 +msgid "Rectangle" +msgstr "Dörtgen" + +#: ../../po/../src/dialogs/display-settings.cpp:1085 +#: ../../po/../src/verbs.cpp:2057 +msgid "Ellipse" +msgstr "Elips" + +#: ../../po/../src/dialogs/display-settings.cpp:1091 +#: ../../po/../src/verbs.cpp:2059 +msgid "Star" +msgstr "Yıldız" + +#: ../../po/../src/dialogs/display-settings.cpp:1097 +#: ../../po/../src/verbs.cpp:2061 +msgid "Spiral" +msgstr "Spiral" + +#: ../../po/../src/dialogs/display-settings.cpp:1111 +#: ../../po/../src/verbs.cpp:2063 +msgid "Pencil" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1114 +#, fuzzy +msgid "Tolerance:" +msgstr "Ä°pucu" + +#: ../../po/../src/dialogs/display-settings.cpp:1115 +msgid "" +"This value affects the amount of smoothing applied to freehand lines; lower " +"values produce more uneven paths with more nodes" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1131 +#: ../../po/../src/verbs.cpp:2065 +#, fuzzy +msgid "Pen" +msgstr "Yüzde" + +#: ../../po/../src/dialogs/display-settings.cpp:1140 +#: ../../po/../src/verbs.cpp:2067 +#, fuzzy +msgid "Calligraphy" +msgstr "Karalama çizgisi" + +#: ../../po/../src/dialogs/display-settings.cpp:1147 +#: ../../po/../src/dialogs/text-edit.cpp:353 +#: ../../po/../src/ui/dialog/text-properties.cpp:37 +#: ../../po/../src/verbs.cpp:2069 +msgid "Text" +msgstr "Metin" + +#: ../../po/../src/dialogs/display-settings.cpp:1157 +#: ../../po/../src/verbs.cpp:2071 +#, fuzzy +msgid "Gradient" +msgstr "Geçişim" + +#: ../../po/../src/dialogs/display-settings.cpp:1164 +#: ../../po/../src/verbs.cpp:2077 +#, fuzzy +msgid "Connector" +msgstr "Köşeler:" + +#: ../../po/../src/dialogs/display-settings.cpp:1171 +#: ../../po/../src/verbs.cpp:2075 +msgid "Dropper" +msgstr "" + +#. Windows +#: ../../po/../src/dialogs/display-settings.cpp:1183 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:59 +msgid "Windows" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1188 +#, fuzzy +msgid "Save window geometry" +msgstr "Dökümanı kaydet" + +#: ../../po/../src/dialogs/display-settings.cpp:1189 +msgid "" +"Save the window size and position with each document (only for Inkscape SVG " +"format)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1196 +msgid "Dialogs are hidden in taskbar" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1197 +msgid "Whether dialog windows are to be hidden in the window manager taskbar" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1204 +msgid "Zoom when window is resized" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1205 +msgid "" +"Zoom drawing when document window is resized, to keep the same area visible " +"(this is the default which can be changed in any window using the button " +"above the right scrollbar)" +msgstr "" + +#. Clones +#: ../../po/../src/dialogs/display-settings.cpp:1213 +#: ../../po/../src/dialogs/find.cpp:624 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:60 +#, fuzzy +msgid "Clones" +msgstr "Kapat" + +#: ../../po/../src/dialogs/display-settings.cpp:1217 +msgid "When the original moves, its clones and linked offsets:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1229 +msgid "Move in parallel" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1230 +msgid "Clones are translated by the same vector as their original." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1237 +msgid "Stay unmoved" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1238 +msgid "Clones preserve their positions when their original is moved." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1245 +msgid "Move according to transform" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1246 +msgid "" +"Each clone moves according to the value of its transform= attribute. For " +"example, a rotated clone will move in a different direction than its " +"original." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1255 +msgid "When the original is deleted, its clones:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1267 +msgid "Are unlinked" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1267 +msgid "Orphaned clones are converted to regular objects." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1273 +#, fuzzy +msgid "Are deleted" +msgstr "Ä°lk seçilen" + +#: ../../po/../src/dialogs/display-settings.cpp:1273 +msgid "Orphaned clones are deleted along with their original." +msgstr "" + +#. Transforms +#. TRANSLATORS: Noun, i.e. transformations. +#: ../../po/../src/dialogs/display-settings.cpp:1289 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:61 +#, fuzzy +msgid "Transforms" +msgstr "Dönüşümler" + +#: ../../po/../src/dialogs/display-settings.cpp:1292 +#, fuzzy +msgid "Scale stroke width" +msgstr "Sayfa genişliğini ayarla" + +#: ../../po/../src/dialogs/display-settings.cpp:1293 +#: ../../po/../src/widgets/select-toolbar.cpp:568 +msgid "When scaling objects, scale the stroke width by the same proportion" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1300 +msgid "Scale rounded corners in rectangles" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1301 +#: ../../po/../src/widgets/select-toolbar.cpp:580 +msgid "When scaling rectangles, scale the radii of rounded corners" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1308 +#, fuzzy +msgid "Transform gradients" +msgstr "Dönüşümler" + +#: ../../po/../src/dialogs/display-settings.cpp:1309 +#: ../../po/../src/widgets/select-toolbar.cpp:592 +msgid "Transform gradients (in fill or stroke) along with the objects" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1316 +#, fuzzy +msgid "Transform patterns" +msgstr "Dönüştürme diyalogu" + +#: ../../po/../src/dialogs/display-settings.cpp:1317 +#: ../../po/../src/widgets/select-toolbar.cpp:604 +msgid "Transform patterns (in fill or stroke) along with the objects" +msgstr "" + +#. TRANSLATORS: How to specify the affine transformation in the SVG file. +#: ../../po/../src/dialogs/display-settings.cpp:1327 +#, fuzzy +msgid "Store transformation:" +msgstr "Nesne dönüşümü" + +#: ../../po/../src/dialogs/display-settings.cpp:1338 +#, fuzzy +msgid "Optimized" +msgstr "Optimize" + +#: ../../po/../src/dialogs/display-settings.cpp:1339 +msgid "" +"If possible, apply transformation to objects without adding a transform= " +"attribute" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1346 +#, fuzzy +msgid "Preserved" +msgstr "Koru" + +#: ../../po/../src/dialogs/display-settings.cpp:1347 +msgid "Always store transformation as a transform= attribute on objects" +msgstr "" + +#. Selecting +#: ../../po/../src/dialogs/display-settings.cpp:1355 +#, fuzzy +msgid "Selecting" +msgstr "Seçim" + +#: ../../po/../src/dialogs/display-settings.cpp:1357 +msgid "Ctrl+A, Tab, Shift+Tab:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1366 +#, fuzzy +msgid "Select only within current layer" +msgstr "Seç" + +#: ../../po/../src/dialogs/display-settings.cpp:1367 +msgid "" +"Uncheck this to make keyboard selection commands work on objects in all " +"layers" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1374 +msgid "Ignore hidden objects" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1375 +msgid "" +"Uncheck this to be able to select objects that are hidden (either by " +"themselves or by being in a hidden group or layer)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1382 +#, fuzzy +msgid "Ignore locked objects" +msgstr "Seçilen nesneler" + +#: ../../po/../src/dialogs/display-settings.cpp:1383 +msgid "" +"Uncheck this to be able to select objects that are locked (either by " +"themselves or by being in a locked group or layer)" +msgstr "" + +#. To be broken into: Display, Save, Export, SVG, Commands +#: ../../po/../src/dialogs/display-settings.cpp:1391 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:62 +msgid "Misc" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1394 +msgid "Default export resolution:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1395 +msgid "Default bitmap resolution (in dots per inch) in the Export dialog" +msgstr "" + +#. FIXME: add "Used for new exports; once exported, documents remember this value on per-object basis" when implemented +#: ../../po/../src/dialogs/display-settings.cpp:1396 +#: ../../po/../src/dialogs/export.cpp:442 +msgid "dpi" +msgstr "dpi" + +#. TRANSLATORS: When on, an imported bitmap creates an element; otherwise it is a +#. * rectangle with bitmap fill. +#: ../../po/../src/dialogs/display-settings.cpp:1407 +#, fuzzy +msgid "Import bitmap as " +msgstr "Bitmap veya SVG dosyasını döküman içine aktar" + +#: ../../po/../src/dialogs/display-settings.cpp:1408 +msgid "" +"When on, an imported bitmap creates an element; otherwise it is a " +"rectangle with bitmap fill" +msgstr "" + +#. TRANSLATORS: When on, the print out (currently Postscript) will have +#. * a comment with the each object's label visible, marking the section +#. * of the printing commands that represent the given object. +#: ../../po/../src/dialogs/display-settings.cpp:1418 +msgid "Add label comments to printing output" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1419 +msgid "" +"When on, a comment will be added to the raw print output, marking the " +"rendered output for an object with its label" +msgstr "" + +#. TRANSLATORS: When on, enable the effects menu, default is off +#: ../../po/../src/dialogs/display-settings.cpp:1427 +msgid "Enable script effects (requires restart) - EXPERIMENTAL" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1428 +msgid "" +"When on, the effects menu is enabled, allowing external effect scripts to be " +"called, requires restart before effective - EXPERIMENTAL" +msgstr "" + +#. TRANSLATORS: The maximum length of the Open Recent list in the File menu. +#: ../../po/../src/dialogs/display-settings.cpp:1436 +#, fuzzy +msgid "Max recent documents:" +msgstr "Dökümanı yazdır" + +#: ../../po/../src/dialogs/display-settings.cpp:1437 +msgid "The maximum length of the Open Recent list in the File menu" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1447 +msgid "Simplification threshold:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1448 +msgid "" +"How strong is the Simplify command by default. If you invoke this command " +"several times in quick succession, it will act more and more aggressively; " +"invoking it again after a pause restores the default threshold." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1469 +msgid "Oversample bitmaps:" +msgstr "Örnek bitmapler:" + +#: ../../po/../src/dialogs/display-settings.cpp:1488 +msgid "2x2" +msgstr "2x2" + +#: ../../po/../src/dialogs/display-settings.cpp:1494 +msgid "4x4" +msgstr "4x4" + +#: ../../po/../src/dialogs/display-settings.cpp:1500 +msgid "8x8" +msgstr "8x8" + +#: ../../po/../src/dialogs/display-settings.cpp:1506 +msgid "16x16" +msgstr "16x16" + +#. "view_icon_preview" +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2143 +msgid "_Page" +msgstr "S_ayfa" + +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2147 +msgid "_Drawing" +msgstr "_Çizim" + +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2149 +msgid "_Selection" +msgstr "_Seçim" + +#: ../../po/../src/dialogs/export.cpp:133 +#, fuzzy +msgid "_Custom" +msgstr "Özel" + +#: ../../po/../src/dialogs/export.cpp:254 +msgid "Export area" +msgstr "Bölümü dışarı aktar" + +#: ../../po/../src/dialogs/export.cpp:300 +#, fuzzy +msgid "_x0:" +msgstr "x0:" + +#: ../../po/../src/dialogs/export.cpp:305 +#, fuzzy +msgid "x_1:" +msgstr "x1:" + +#: ../../po/../src/dialogs/export.cpp:316 +#, fuzzy +msgid "_y0:" +msgstr "y0:" + +#: ../../po/../src/dialogs/export.cpp:321 +#, fuzzy +msgid "y_1:" +msgstr "y1:" + +#: ../../po/../src/dialogs/export.cpp:406 +msgid "Bitmap size" +msgstr "Bitmap boyutu" + +#: ../../po/../src/dialogs/export.cpp:416 +#, fuzzy +msgid "_Width:" +msgstr "Genişlik:" + +#: ../../po/../src/dialogs/export.cpp:416 +#: ../../po/../src/dialogs/export.cpp:431 +#, fuzzy +msgid "pixels at" +msgstr "piksel" + +#: ../../po/../src/dialogs/export.cpp:426 +#, fuzzy +msgid "dp_i" +msgstr "dpi" + +#: ../../po/../src/dialogs/export.cpp:448 +#, fuzzy +msgid "_Filename" +msgstr "Dosya adı:" + +#: ../../po/../src/dialogs/export.cpp:512 +msgid "_Browse..." +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:539 +#, fuzzy +msgid " _Export " +msgstr "Değiştir" + +#: ../../po/../src/dialogs/export.cpp:541 +msgid "Export the bitmap file with these settings" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:968 +#, fuzzy +msgid "You have to enter a filename" +msgstr "Çizimi yeni dosya adıyla kaydet" + +#: ../../po/../src/dialogs/export.cpp:973 +msgid "The chosen area to be exported is invalid" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:982 +#, c-format +msgid "Directory %s does not exist or is not a directory.\n" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:998 +#, fuzzy +msgid "Export in progress" +msgstr "Bölümü dışarı aktar" + +#: ../../po/../src/dialogs/export.cpp:1004 +#, fuzzy, c-format +msgid "Exporting %s (%d x %d)" +msgstr "Resmi renklendir %d x %d: %s" + +#: ../../po/../src/dialogs/export.cpp:1031 +#, c-format +msgid "Could not export to filename %s.\n" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:1137 +#, fuzzy +msgid "Select a filename for exporting" +msgstr "İçeri aktarılacak dosyayı seçin" + +#: ../../po/../src/dialogs/filedialog.cpp:367 +#, fuzzy +msgid "No preview" +msgstr "Yeni Önizleme" + +#: ../../po/../src/dialogs/filedialog.cpp:468 +msgid "too large for preview" +msgstr "" + +#: ../../po/../src/dialogs/filedialog.cpp:762 +#: ../../po/../src/dialogs/filedialog.cpp:763 +#, fuzzy +msgid "All Images" +msgstr "Resim" + +#: ../../po/../src/dialogs/filedialog.cpp:767 +#: ../../po/../src/dialogs/filedialog.cpp:768 +#, fuzzy +msgid "All Files" +msgstr "Doldurma stili" + +#: ../../po/../src/dialogs/filedialog.cpp:774 +#: ../../po/../src/dialogs/filedialog.cpp:775 +#, fuzzy +msgid "All Inkscape Files" +msgstr "Sodipodi: %s : XML Görünümü" + +#: ../../po/../src/dialogs/filedialog.cpp:1176 +#, fuzzy +msgid "Guess from extension" +msgstr "Seçileni dönüştür" + +#. ###### Add the file types menu +#. createFilterMenu(); +#. ###### Do we want the .xxx extension automatically added? +#: ../../po/../src/dialogs/filedialog.cpp:1261 +msgid "Append filename extension automatically" +msgstr "" + +#. TRANSLATORS: "%s" is replaced with "exact" or "partial" when this string is displayed +#: ../../po/../src/dialogs/find.cpp:378 +#, fuzzy, c-format +msgid "%d object found (out of %d), %s match." +msgid_plural "%d objects found (out of %d), %s match." +msgstr[0] "Seçilen düğümleri çizgilere ekle" +msgstr[1] "Seçilen düğümleri çizgilere ekle" + +#: ../../po/../src/dialogs/find.cpp:381 +#, fuzzy +msgid "exact" +msgstr "Metin" + +#: ../../po/../src/dialogs/find.cpp:381 +#, fuzzy +msgid "partial" +msgstr "Spiral" + +#: ../../po/../src/dialogs/find.cpp:388 +#, fuzzy +msgid "No objects found" +msgstr "Nesne yok" + +#: ../../po/../src/dialogs/find.cpp:546 +#, fuzzy +msgid "T_ype: " +msgstr "Tip:" + +#: ../../po/../src/dialogs/find.cpp:553 +msgid "Search in all object types" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:553 +#, fuzzy +msgid "All types" +msgstr "Doldurma stili" + +#: ../../po/../src/dialogs/find.cpp:564 +msgid "Search all shapes" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:564 +#, fuzzy +msgid "All shapes" +msgstr "Tüm şekillendirme araçları" + +#: ../../po/../src/dialogs/find.cpp:581 +#, fuzzy +msgid "Search rectangles" +msgstr "Dörtgen çiz" + +#: ../../po/../src/dialogs/find.cpp:581 +#, fuzzy +msgid "Rectangles" +msgstr "Dörtgen" + +#: ../../po/../src/dialogs/find.cpp:586 +msgid "Search ellipses, arcs, circles" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:586 +#, fuzzy +msgid "Ellipses" +msgstr "Elips" + +#: ../../po/../src/dialogs/find.cpp:591 +#, fuzzy +msgid "Search stars and polygons" +msgstr "Yıldız aracı - yıldızlar ve poligonlar yaratır" + +#: ../../po/../src/dialogs/find.cpp:591 +#, fuzzy +msgid "Stars" +msgstr "Yıldız" + +#: ../../po/../src/dialogs/find.cpp:596 +#, fuzzy +msgid "Search spirals" +msgstr "Dörtgen çiz" + +#: ../../po/../src/dialogs/find.cpp:596 +#, fuzzy +msgid "Spirals" +msgstr "Spiral" + +#. TRANSLATORS: polyline is a set of connected straight line segments +#. http://www.w3.org/TR/SVG11/shapes.html#PolylineElement +#: ../../po/../src/dialogs/find.cpp:609 +msgid "Search paths, lines, polylines" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:609 +msgid "Paths" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:614 +#, fuzzy +msgid "Search text objects" +msgstr "Seçilen nesneler" + +#: ../../po/../src/dialogs/find.cpp:614 +#, fuzzy +msgid "Texts" +msgstr "Metin" + +#: ../../po/../src/dialogs/find.cpp:619 +msgid "Search groups" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:619 +#, fuzzy +msgid "Groups" +msgstr "Grupla" + +#: ../../po/../src/dialogs/find.cpp:624 +msgid "Search clones" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:629 +#, fuzzy +msgid "Search images" +msgstr "Resimle boyutla" + +#: ../../po/../src/dialogs/find.cpp:629 +#, fuzzy +msgid "Images" +msgstr "Resim" + +#: ../../po/../src/dialogs/find.cpp:634 +#, fuzzy +msgid "Search offset objects" +msgstr "MEtin aracı - düzenlenebilir metin nesneleri yaratır" + +#: ../../po/../src/dialogs/find.cpp:634 +msgid "Offsets" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:694 +#, fuzzy +msgid "_Text: " +msgstr "Metin" + +#: ../../po/../src/dialogs/find.cpp:694 +msgid "Find objects by their text content (exact or partial match)" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:695 +msgid "_ID: " +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:695 +msgid "Find objects by the value of the id attribute (exact or partial match)" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:696 +#, fuzzy +msgid "_Style: " +msgstr " Boyutla " + +#: ../../po/../src/dialogs/find.cpp:696 +msgid "" +"Find objects by the value of the style attribute (exact or partial match)" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:697 +#, fuzzy +msgid "_Attribute: " +msgstr "Özellik:" + +#: ../../po/../src/dialogs/find.cpp:697 +msgid "Find objects by the name of an attribute (exact or partial match)" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:711 +#, fuzzy +msgid "Search in s_election" +msgstr "Seçileni göster" + +#: ../../po/../src/dialogs/find.cpp:715 +msgid "Limit search to the current selection" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:720 +#, fuzzy +msgid "Search in current _layer" +msgstr "Seç" + +#: ../../po/../src/dialogs/find.cpp:724 +#, fuzzy +msgid "Limit search to the current layer" +msgstr "Seç" + +#: ../../po/../src/dialogs/find.cpp:729 +msgid "Include _hidden" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:733 +msgid "Include hidden objects in search" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:738 +msgid "Include l_ocked" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:742 +#, fuzzy +msgid "Include locked objects in search" +msgstr "Seçilen nesneler" + +#: ../../po/../src/dialogs/find.cpp:753 +#, fuzzy +msgid "Clear values" +msgstr "Hepsini temizle" + +#: ../../po/../src/dialogs/find.cpp:754 +#, fuzzy +msgid "_Find" +msgstr "Izgara" + +#: ../../po/../src/dialogs/find.cpp:754 +msgid "Select objects matching all of the fields you filled in" +msgstr "" + +#: ../../po/../src/dialogs/iconpreview.cpp:145 +#, c-format +msgid "%d x %d" +msgstr "" + +#: ../../po/../src/dialogs/iconpreview.cpp:193 +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:857 +#: ../../po/../src/widgets/desktop-widget.cpp:1069 +msgid "Selection" +msgstr "Seçim" + +#: ../../po/../src/dialogs/iconpreview.cpp:195 +#, fuzzy +msgid "Selection only or whole document" +msgstr "Seç" + +#: ../../po/../src/dialogs/iconpreview.cpp:203 +msgid "Refresh the icons" +msgstr "" + +#. Create the label for the object id +#: ../../po/../src/dialogs/item-properties.cpp:126 +#: ../../po/../src/dialogs/item-properties.cpp:327 +#: ../../po/../src/dialogs/item-properties.cpp:396 +#: ../../po/../src/dialogs/item-properties.cpp:403 +msgid "_Id" +msgstr "" + +#: ../../po/../src/dialogs/item-properties.cpp:135 +msgid "" +"The id= attribute (only letters, digits, and the characters .-_: allowed)" +msgstr "" + +#. Button for setting the object's id, label, title and description. +#: ../../po/../src/dialogs/item-properties.cpp:149 +#, fuzzy +msgid "_Set" +msgstr "Seç" + +#. Create the label for the object label +#: ../../po/../src/dialogs/item-properties.cpp:158 +#, fuzzy +msgid "_Label" +msgstr "kenar" + +#: ../../po/../src/dialogs/item-properties.cpp:167 +msgid "A freeform label for the object" +msgstr "" + +#. Create the label for the object title +#: ../../po/../src/dialogs/item-properties.cpp:179 +#: ../../po/../src/dialogs/rdf.cpp:243 +#, fuzzy +msgid "Title" +msgstr "Başlık:" + +#. Create the frame for the object description +#: ../../po/../src/dialogs/item-properties.cpp:196 +#: ../../po/../src/dialogs/rdf.cpp:287 +#, fuzzy +msgid "Description" +msgstr "Konum" + +#. Hide +#: ../../po/../src/dialogs/item-properties.cpp:223 +#, fuzzy +msgid "_Hide" +msgstr "Bölümler:" + +#: ../../po/../src/dialogs/item-properties.cpp:224 +msgid "Check to make the object invisible" +msgstr "" + +#. Lock +#. TRANSLATORS: "Lock" is a verb here +#: ../../po/../src/dialogs/item-properties.cpp:233 +msgid "L_ock" +msgstr "" + +#: ../../po/../src/dialogs/item-properties.cpp:234 +msgid "Check to make the object insensitive (not selectable by mouse)" +msgstr "" + +#: ../../po/../src/dialogs/item-properties.cpp:310 +#: ../../po/../src/dialogs/item-properties.cpp:317 +msgid "Ref" +msgstr "" + +#: ../../po/../src/dialogs/item-properties.cpp:398 +#, fuzzy +msgid "Id invalid! " +msgstr "Numara geçerli" + +#: ../../po/../src/dialogs/item-properties.cpp:400 +msgid "Id exists! " +msgstr "" + +#: ../../po/../src/dialogs/layer-properties.cpp:50 +msgid "Layer name:" +msgstr "" + +#: ../../po/../src/dialogs/layer-properties.cpp:133 +#, fuzzy +msgid "Rename Layer" +msgstr "Düğümü büyüt" + +#: ../../po/../src/dialogs/layer-properties.cpp:136 +#, fuzzy +msgid "_Rename" +msgstr "Dosya adı:" + +#. TRANSLATORS: This means "The layer has been renamed" +#: ../../po/../src/dialogs/layer-properties.cpp:147 +#, fuzzy +msgid "Renamed layer" +msgstr "Düğümü büyüt" + +#: ../../po/../src/dialogs/layer-properties.cpp:151 +#, fuzzy +msgid "Add Layer" +msgstr "Küçült" + +#: ../../po/../src/dialogs/layer-properties.cpp:153 +#, fuzzy +msgid "_Add" +msgstr "Ekle" + +#: ../../po/../src/dialogs/layer-properties.cpp:167 +msgid "New layer created." +msgstr "" + +#: ../../po/../src/dialogs/object-attributes.cpp:34 +msgid "Href:" +msgstr "Değer:" + +#: ../../po/../src/dialogs/object-attributes.cpp:35 +msgid "Target:" +msgstr "Hedef:" + +#: ../../po/../src/dialogs/object-attributes.cpp:36 +msgid "Type:" +msgstr "Tip:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkRoleAttribute +#. Identifies the type of the related resource with an absolute URI +#: ../../po/../src/dialogs/object-attributes.cpp:39 +msgid "Role:" +msgstr "İşlev:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkArcRoleAttribute +#. For situations where the nature/role alone isn't enough, this offers an additional URI defining the purpose of the link. +#: ../../po/../src/dialogs/object-attributes.cpp:42 +msgid "Arcrole:" +msgstr "Arcrole:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkTitleAttribute +#: ../../po/../src/dialogs/object-attributes.cpp:44 +msgid "Title:" +msgstr "Başlık:" + +#: ../../po/../src/dialogs/object-attributes.cpp:45 +msgid "Show:" +msgstr "Göster:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkActuateAttribute +#: ../../po/../src/dialogs/object-attributes.cpp:47 +msgid "Actuate:" +msgstr "Çalıştır:" + +#: ../../po/../src/dialogs/object-attributes.cpp:52 +msgid "URL:" +msgstr "Adres:" + +#: ../../po/../src/dialogs/object-attributes.cpp:53 +msgid "X:" +msgstr "X:" + +#: ../../po/../src/dialogs/object-attributes.cpp:54 +msgid "Y:" +msgstr "Y:" + +#: ../../po/../src/dialogs/object-attributes.cpp:98 +#, c-format +msgid "%s attributes" +msgstr "%s özellikleri" + +#: ../../po/../src/dialogs/object-properties.cpp:158 +#, fuzzy +msgid "_Fill" +msgstr "Doldur" + +#: ../../po/../src/dialogs/object-properties.cpp:165 +#, fuzzy +msgid "Stroke _paint" +msgstr "Sayfa genişliğini ayarla" + +#: ../../po/../src/dialogs/object-properties.cpp:172 +#, fuzzy +msgid "Stroke st_yle" +msgstr "Vuruş ayarları" + +#: ../../po/../src/dialogs/object-properties.cpp:183 +#, fuzzy +msgid "Master _opacity" +msgstr "Donukluk:" + +#: ../../po/../src/dialogs/rdf.cpp:244 +msgid "Name by which this document is formally known." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:246 +#, fuzzy +msgid "Date" +msgstr "Metin çiz" + +#: ../../po/../src/dialogs/rdf.cpp:247 +msgid "Date associated with the creation of this document (YYYY-MM-DD)." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:249 +#, fuzzy +msgid "Format" +msgstr "Fraktal" + +#: ../../po/../src/dialogs/rdf.cpp:250 +msgid "The physical or digital manifestation of this document (MIME type)." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:252 +#, fuzzy +msgid "Type" +msgstr "Tip:" + +#: ../../po/../src/dialogs/rdf.cpp:253 +msgid "Type of document (DCMI Type)." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:256 +#, fuzzy +msgid "Creator" +msgstr "Yarat" + +#: ../../po/../src/dialogs/rdf.cpp:257 +msgid "" +"Name of entity primarily responsible for making the content of this document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:259 +#, fuzzy +msgid "Rights" +msgstr "sağ" + +#: ../../po/../src/dialogs/rdf.cpp:260 +msgid "" +"Name of entity with rights to the Intellectual Property of this document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:262 +msgid "Publisher" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:263 +msgid "Name of entity responsible for making this document available." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:266 +#, fuzzy +msgid "Identifier" +msgstr "İçerik" + +#: ../../po/../src/dialogs/rdf.cpp:267 +msgid "Unique URI to reference this document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:269 +msgid "Source" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:270 +msgid "Unique URI to reference the source of this document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:272 +#, fuzzy +msgid "Relation" +msgstr "Devir:" + +#: ../../po/../src/dialogs/rdf.cpp:273 +#, fuzzy +msgid "Unique URI to a related document." +msgstr "Başlıksız döküman" + +#: ../../po/../src/dialogs/rdf.cpp:275 +#, fuzzy +msgid "Language" +msgstr "Değiştir" + +#: ../../po/../src/dialogs/rdf.cpp:276 +msgid "" +"Two-letter language tag with optional subtags for the language of this " +"document. (e.g. 'en-GB')" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:278 +msgid "Keywords" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:279 +msgid "" +"The topic of this document as comma-separated key words, phrases, or " +"classifications." +msgstr "" + +#. TRANSLATORS: "Coverage": the spatial or temporal characteristics of the content. +#. For info, see Appendix D of http://www.w3.org/TR/1998/WD-rdf-schema-19980409/ +#: ../../po/../src/dialogs/rdf.cpp:283 +msgid "Coverage" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:284 +msgid "Extent or scope of this document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:288 +msgid "A short account of the content of this document." +msgstr "" + +#. FIXME: need to handle 1 agent per line of input +#: ../../po/../src/dialogs/rdf.cpp:292 +#, fuzzy +msgid "Contributors" +msgstr "Santrimetre" + +#: ../../po/../src/dialogs/rdf.cpp:293 +msgid "" +"Names of entities responsible for making contributions to the content of " +"this document." +msgstr "" + +#. TRANSLATORS: URL to a page that defines the license for the document +#: ../../po/../src/dialogs/rdf.cpp:297 +msgid "URI" +msgstr "" + +#. TRANSLATORS: this is where you put a URL to a page that defines the license +#: ../../po/../src/dialogs/rdf.cpp:299 +msgid "URI to this document's license's namespace definition." +msgstr "" + +#. TRANSLATORS: fragment of XML representing the license of the document +#: ../../po/../src/dialogs/rdf.cpp:303 +#, fuzzy +msgid "Fragment" +msgstr "Argüman:" + +#: ../../po/../src/dialogs/rdf.cpp:304 +msgid "XML fragment for the RDF 'License' section." +msgstr "" + +#: ../../po/../src/dialogs/stroke-style.cpp:774 +#: ../../po/../src/widgets/gradient-vector.cpp:263 +#: ../../po/../src/widgets/paint-selector.cpp:751 +msgid "No document selected" +msgstr "Döküman seçilmedi" + +#: ../../po/../src/dialogs/stroke-style.cpp:992 +#, fuzzy +msgid "Stroke width" +msgstr "Sayfa genişliğini ayarla" + +#. Join type +#. TRANSLATORS: The line join style specifies the shape to be used at the +#. corners of paths. It can be "miter", "round" or "bevel". +#: ../../po/../src/dialogs/stroke-style.cpp:1015 +msgid "Join:" +msgstr "Ekle:" + +#. TRANSLATORS: Miter join: joining lines with a sharp (pointed) corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1027 +msgid "Miter join" +msgstr "" + +#. TRANSLATORS: Round join: joining lines with a rounded corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1035 +#, fuzzy +msgid "Round join" +msgstr "2 seçili bitiş noktasını birleştir" + +#. TRANSLATORS: Bevel join: joining lines with a blunted (flattened) corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1043 +msgid "Bevel join" +msgstr "" + +#. Miterlimit +#. TRANSLATORS: Miter limit: only for "miter join", this limits the length +#. of the sharp "spike" when the lines connect at too sharp an angle. +#. When two line segments meet at a sharp angle, a miter join results in a +#. spike that extends well beyond the connection point. The purpose of the +#. miter limit is to cut off such spikes (i.e. convert them into bevels) +#. when they become too long. +#: ../../po/../src/dialogs/stroke-style.cpp:1054 +msgid "Miter limit:" +msgstr "" + +#: ../../po/../src/dialogs/stroke-style.cpp:1062 +msgid "Maximum length of the miter (in units of stroke width)" +msgstr "" + +#. Cap type +#. TRANSLATORS: cap type specifies the shape for the ends of lines +#: ../../po/../src/dialogs/stroke-style.cpp:1075 +msgid "Cap:" +msgstr "Kapak:" + +#. TRANSLATORS: Butt cap: the line shape does not extend beyond the end point +#. of the line; the ends of the line are square +#: ../../po/../src/dialogs/stroke-style.cpp:1086 +msgid "Butt cap" +msgstr "" + +#. TRANSLATORS: Round cap: the line shape extends beyond the end point of the +#. line; the ends of the line are rounded +#: ../../po/../src/dialogs/stroke-style.cpp:1093 +#, fuzzy +msgid "Round cap" +msgstr "2 seçili bitiş noktasını birleştir" + +#. TRANSLATORS: Square cap: the line shape extends beyond the end point of the +#. line; the ends of the line are square +#: ../../po/../src/dialogs/stroke-style.cpp:1100 +#, fuzzy +msgid "Square cap" +msgstr "2 seçili bitiş noktasını birleştir" + +#. Dash +#: ../../po/../src/dialogs/stroke-style.cpp:1106 +#, fuzzy +msgid "Dashes:" +msgstr "Büyük:" + +#. TRANSLATORS: Path markers are an SVG feature that allows you to attach arbitrary shapes +#. (arrowheads, bullets, faces, whatever) to the start, end, or middle nodes of a path. +#: ../../po/../src/dialogs/stroke-style.cpp:1127 +#, fuzzy +msgid "Start Markers:" +msgstr "Yıldız Ayarları" + +#: ../../po/../src/dialogs/stroke-style.cpp:1137 +msgid "Mid Markers:" +msgstr "" + +#: ../../po/../src/dialogs/stroke-style.cpp:1148 +msgid "End Markers:" +msgstr "" + +#: ../../po/../src/dialogs/swatches.cpp:424 +#, c-format +msgid "Palettes directory (%s) is unavailable." +msgstr "" + +#. TODO: Insert widgets +#: ../../po/../src/dialogs/text-edit.cpp:199 +#: ../../po/../src/ui/dialog/text-properties.cpp:36 +#, fuzzy +msgid "Font" +msgstr "Öne getir" + +#: ../../po/../src/dialogs/text-edit.cpp:216 +msgid "Layout" +msgstr "Konumlama" + +#: ../../po/../src/dialogs/text-edit.cpp:229 +#, fuzzy +msgid "Align lines left" +msgstr "Nesne dışını sol kenara hizala" + +#. TRANSLATORS: `Center' here is a verb. +#: ../../po/../src/dialogs/text-edit.cpp:243 +#, fuzzy +msgid "Center lines" +msgstr "Merkezi Y:" + +#: ../../po/../src/dialogs/text-edit.cpp:256 +#, fuzzy +msgid "Align lines right" +msgstr "Nesne dışını sağ kenara hizala" + +#: ../../po/../src/dialogs/text-edit.cpp:278 +#, fuzzy +msgid "Horizontal text" +msgstr "yatay" + +#: ../../po/../src/dialogs/text-edit.cpp:292 +#, fuzzy +msgid "Vertical text" +msgstr "dikey" + +#: ../../po/../src/dialogs/text-edit.cpp:307 +#, fuzzy +msgid "Line spacing:" +msgstr "X aralığı:" + +#: ../../po/../src/dialogs/text-edit.cpp:400 +msgid "Set as default" +msgstr "Öntanımlı olarak ata" + +#: ../../po/../src/dialogs/tiledialog.cpp:603 +#, fuzzy +msgid "Rows:" +msgstr "Göster:" + +#: ../../po/../src/dialogs/tiledialog.cpp:613 +msgid "Number of rows" +msgstr "" + +#: ../../po/../src/dialogs/tiledialog.cpp:617 +#, fuzzy +msgid "Equal height" +msgstr "Yükseklik:" + +#: ../../po/../src/dialogs/tiledialog.cpp:627 +msgid "If not set, each row has the height of the tallest object in it" +msgstr "" + +#. #### Radio buttons to control vertical alignment #### +#. #### Radio buttons to control horizontal alignment #### +#: ../../po/../src/dialogs/tiledialog.cpp:637 +#: ../../po/../src/dialogs/tiledialog.cpp:708 +#, fuzzy +msgid "Align:" +msgstr "Hizala" + +#: ../../po/../src/dialogs/tiledialog.cpp:672 +#, fuzzy +msgid " X " +msgstr "% " + +#. #### Number of columns #### +#: ../../po/../src/dialogs/tiledialog.cpp:678 +#, fuzzy +msgid "Columns:" +msgstr "Değiştir" + +#: ../../po/../src/dialogs/tiledialog.cpp:688 +msgid "Number of columns" +msgstr "" + +#: ../../po/../src/dialogs/tiledialog.cpp:692 +#, fuzzy +msgid "Equal width" +msgstr "Genişlik " + +#: ../../po/../src/dialogs/tiledialog.cpp:701 +msgid "If not set, each column has the width of the widest object in it" +msgstr "" + +#. #### Radio buttons to control spacing manually or to fit selection bbox #### +#: ../../po/../src/dialogs/tiledialog.cpp:746 +#, fuzzy +msgid "Fit into selection box" +msgstr "Seçileni kes" + +#: ../../po/../src/dialogs/tiledialog.cpp:753 +#, fuzzy +msgid "Set spacing:" +msgstr "Y aralığı:" + +#. #### Y Padding #### +#: ../../po/../src/dialogs/tiledialog.cpp:777 +#, fuzzy +msgid "Row spacing: " +msgstr "X aralığı:" + +#: ../../po/../src/dialogs/tiledialog.cpp:786 +#, fuzzy +msgid "Vertical spacing between rows" +msgstr "dikey" + +#. #### X padding #### +#: ../../po/../src/dialogs/tiledialog.cpp:795 +#, fuzzy +msgid "Column spacing:" +msgstr "X aralığı:" + +#: ../../po/../src/dialogs/tiledialog.cpp:804 +#, fuzzy +msgid "Horizontal spacing between columns" +msgstr "yatay" + +#: ../../po/../src/dialogs/tiledialog.cpp:818 +#, fuzzy +msgid "Arrange selected objects" +msgstr "Seçili nesneleri grupla" + +#: ../../po/../src/dialogs/xml-tree.cpp:178 +msgid "Click to select nodes, drag to rearrange." +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:189 +msgid "Click attribute to edit." +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:193 +#, c-format +msgid "" +"Attribute %s selected. Press Ctrl+Enter when done editing to " +"commit changes." +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:284 +msgid "Drag to reorder nodes" +msgstr "Yeni düzenlenen düğümlere taşı" + +#: ../../po/../src/dialogs/xml-tree.cpp:304 +msgid "New element node" +msgstr "Yeni öğe düğümü" + +#: ../../po/../src/dialogs/xml-tree.cpp:326 +msgid "New text node" +msgstr "Yeni metin düğümü" + +#: ../../po/../src/dialogs/xml-tree.cpp:347 +msgid "Duplicate node" +msgstr "Düğümü çiftle" + +#: ../../po/../src/dialogs/xml-tree.cpp:368 +msgid "Delete node" +msgstr "Düğümü sil" + +#: ../../po/../src/dialogs/xml-tree.cpp:384 +msgid "Unindent node" +msgstr "Düğümü düzelt" + +#: ../../po/../src/dialogs/xml-tree.cpp:399 +msgid "Indent node" +msgstr "Düğüme girinti ekle" + +#: ../../po/../src/dialogs/xml-tree.cpp:411 +msgid "Raise node" +msgstr "Düğümü büyüt" + +#: ../../po/../src/dialogs/xml-tree.cpp:423 +msgid "Lower node" +msgstr "Düğümü küçült" + +#: ../../po/../src/dialogs/xml-tree.cpp:468 +msgid "Delete attribute" +msgstr "Özelliği sil" + +#. TRANSLATORS: "Attribute" is a noun here +#: ../../po/../src/dialogs/xml-tree.cpp:513 +msgid "Attribute name" +msgstr "Özellik adı" + +#. TRANSLATORS: "Set" is a verb here +#: ../../po/../src/dialogs/xml-tree.cpp:533 +msgid "Set attribute" +msgstr "Özellik ata" + +#. TRANSLATORS: "Set" is a verb here +#: ../../po/../src/dialogs/xml-tree.cpp:535 +#, fuzzy +msgid "Set" +msgstr "Seç" + +#. TRANSLATORS: "Attribute" is a noun here +#: ../../po/../src/dialogs/xml-tree.cpp:558 +msgid "Attribute value" +msgstr "Özellik değeri" + +#: ../../po/../src/dialogs/xml-tree.cpp:1318 +msgid "New element node..." +msgstr "Yeni öğe düğümü..." + +#: ../../po/../src/dialogs/xml-tree.cpp:1339 +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:100 +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:98 +msgid "Cancel" +msgstr "Ä°ptal" + +#: ../../po/../src/dialogs/xml-tree.cpp:1345 +msgid "Create" +msgstr "Yarat" + +#: ../../po/../src/dialogs/xml-tree.cpp:1458 +#, c-format +msgid "" +"Cannot set %s: Another element with value %s already exists!" +msgstr "" + +#: ../../po/../src/document.cpp:369 +#, c-format +msgid "New document %d" +msgstr "Yeni döküman %d" + +#: ../../po/../src/document.cpp:401 +#, c-format +msgid "Memory document %d" +msgstr "Hafıza dökümanı %d" + +#: ../../po/../src/document.cpp:524 +#, c-format +msgid "Unnamed document %d" +msgstr "Adlandırılmamış döküman %d" + +#. We hit green anchor, closing Green-Blue-Red +#: ../../po/../src/draw-context.cpp:441 +msgid "Path is closed." +msgstr "" + +#. We hit bot start and end of single curve, closing paths +#: ../../po/../src/draw-context.cpp:456 +msgid "Closing path." +msgstr "" + +#. alpha of color under cursor, to show in the statusbar +#. locale-sensitive printf is OK, since this goes to the UI, not into SVG +#: ../../po/../src/dropper-context.cpp:354 +#, c-format +msgid " alpha %.3g" +msgstr "" + +#. where the color is picked, to show in the statusbar +#: ../../po/../src/dropper-context.cpp:356 +#, c-format +msgid ", averaged with radius %d" +msgstr "" + +#: ../../po/../src/dropper-context.cpp:356 +msgid " under cursor" +msgstr "" + +#. message, to show in the statusbar +#: ../../po/../src/dropper-context.cpp:358 +msgid "Release mouse to set color." +msgstr "" + +#: ../../po/../src/dropper-context.cpp:358 +#: ../../po/../src/tools-switch.cpp:207 +msgid "" +"Click to set fill, Shift+click to set stroke; drag to " +"average color in area; with Alt to pick inverse color; Ctrl+C " +"to copy the color under mouse to clipboard" +msgstr "" + +#: ../../po/../src/extension/dependency.cpp:244 +msgid "Dependency::" +msgstr "" + +#: ../../po/../src/extension/dependency.cpp:245 +#, fuzzy +msgid " type: " +msgstr "Doldurma stili" + +#: ../../po/../src/extension/dependency.cpp:246 +#, fuzzy +msgid " location: " +msgstr "Devir:" + +#: ../../po/../src/extension/dependency.cpp:247 +msgid " string: " +msgstr "" + +#: ../../po/../src/extension/dependency.cpp:250 +#, fuzzy +msgid " description: " +msgstr "Konum" + +#. static int i = 0; +#. std::cout << "Checking module[" << i++ << "]: " << name << std::endl; +#: ../../po/../src/extension/extension.cpp:244 +msgid "" +" This is caused by an improper .inx file for this extension. An improper ." +"inx file could have been caused by a faulty installation of Inkscape." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:247 +msgid "an ID was not defined for it." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:251 +msgid "there was no name defined for it." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:255 +msgid "the XML description of it got lost." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:259 +msgid "no implementation was defined for the extension." +msgstr "" + +#. std::cout << "Failed: " << *(_deps[i]) << std::endl; +#: ../../po/../src/extension/extension.cpp:266 +msgid "a dependency was not met." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:286 +#, fuzzy +msgid "Extension \"" +msgstr "Genişletme" + +#: ../../po/../src/extension/extension.cpp:286 +msgid "\" failed to load because " +msgstr "" + +#: ../../po/../src/extension/extension.cpp:565 +#, c-format +msgid "Could not create extension error log file '%s'" +msgstr "" + +#. This is some filler text, needs to change before relase +#: ../../po/../src/extension/error-file.cpp:56 +msgid "" +"One or more extensions failed to load\n" +"\n" +"The failed extensions have been skipped. Inkscape will continue to run " +"normally but those extensions will be unavailable. For details to " +"troubleshoot this problem, please refer to the error log located at: " +msgstr "" + +#. This is some filler text, needs to change before relase +#: ../../po/../src/extension/error-file.cpp:65 +msgid "Show dialog on startup" +msgstr "" + +#: ../../po/../src/extension/implementation/script.cpp:845 +msgid "" +"Inkscape has received an error from the script that it called. The text " +"returned with the error is included below. Inkscape will continue working, " +"but the action you requested has been cancelled." +msgstr "" + +#: ../../po/../src/extension/implementation/script.cpp:858 +msgid "" +"Inkscape has received additional data from the script executed. The script " +"did not return an error, but this may indicate the results will not be as " +"expected." +msgstr "" + +#: ../../po/../src/extension/init.cpp:173 +msgid "Null external module directory name. Modules will not be loaded." +msgstr "" + +#: ../../po/../src/extension/init.cpp:187 +#, c-format +msgid "" +"Modules directory (%s) is unavailable. External modules in that directory " +"will not be loaded." +msgstr "" + +#: ../../po/../src/extension/internal/gnome.cpp:80 +msgid "Select printer" +msgstr "Yazıcıyı seçin" + +#: ../../po/../src/extension/internal/gnome.cpp:131 +#, fuzzy +msgid "Inkscape: Print Preview" +msgstr "Sodipodi (döküman %s..): Yazdırma Önizlemesi" + +#: ../../po/../src/extension/internal/grid.cpp:213 +#, fuzzy +msgid "Line Width" +msgstr " Genişlik " + +#: ../../po/../src/extension/internal/grid.cpp:214 +#, fuzzy +msgid "Horizontal Spacing" +msgstr "yatay" + +#: ../../po/../src/extension/internal/grid.cpp:215 +#, fuzzy +msgid "Vertical Spacing" +msgstr "dikey" + +#: ../../po/../src/extension/internal/grid.cpp:216 +#, fuzzy +msgid "Horizontal Offset" +msgstr "yatay" + +#: ../../po/../src/extension/internal/grid.cpp:217 +#, fuzzy +msgid "Vertical Offset" +msgstr "dikey" + +#: ../../po/../src/extension/internal/ps.cpp:123 +#, fuzzy +msgid "Print Destination" +msgstr "Hedefi yazdır" + +#. Print properties frame +#: ../../po/../src/extension/internal/ps.cpp:138 +#, fuzzy +msgid "Print properties" +msgstr "Bağlantı Özellikleri" + +#: ../../po/../src/extension/internal/ps.cpp:145 +msgid "Print using PostScript operators" +msgstr "" + +#: ../../po/../src/extension/internal/ps.cpp:147 +msgid "" +"Use PostScript vector operators. The resulting image is usually smaller in " +"file size and can be arbitrarily scaled, but alpha transparency and patterns " +"will be lost." +msgstr "" + +#: ../../po/../src/extension/internal/ps.cpp:152 +#, fuzzy +msgid "Print as bitmap" +msgstr "Bitmap'i dışarı aktar" + +#: ../../po/../src/extension/internal/ps.cpp:154 +msgid "" +"Print everything as bitmap. The resulting image is usually larger in file " +"size and cannot be arbitrarily scaled without quality loss, but all objects " +"will be rendered exactly as displayed." +msgstr "" + +#: ../../po/../src/extension/internal/ps.cpp:168 +msgid "Preferred resolution (dots per inch) of bitmap" +msgstr "" + +#: ../../po/../src/extension/internal/ps.cpp:182 +#, fuzzy +msgid "Resolution:" +msgstr "Devir:" + +#. Print destination frame +#: ../../po/../src/extension/internal/ps.cpp:186 +msgid "Print destination" +msgstr "Hedefi yazdır" + +#: ../../po/../src/extension/internal/ps.cpp:192 +#, fuzzy +msgid "" +"Use '> filename' to print to file.\n" +"Use '| prog arg...' to pipe to a program." +msgstr "" +"Hedef lpr kuyruğunu girin.\n" +"Dosyaya yazmak için '>dosyaadi' \n" +"Programa yönlendirmek için '|' kullanın" + +#: ../../po/../src/extension/internal/ps.cpp:1227 +msgid "write error occurred" +msgstr "" + +#: ../../po/../src/extension/prefdialog.cpp:21 +#, fuzzy +msgid " Preferences" +msgstr "Nesne referans" + +#. We can't call sp_ui_error_dialog because we may be +#. running from the console, in which case calling sp_ui +#. routines will cause a segfault. See bug 1000350 - bryce +#. sp_ui_error_dialog(_("Format autodetect failed. The file is being opened as SVG.")); +#: ../../po/../src/extension/system.cpp:105 +msgid "Format autodetect failed. The file is being opened as SVG." +msgstr "" + +#. TRANSLATORS: default.svg is localizable - this is the name of the default document +#. template. This way you can localize the default pagesize, translate the name of +#. the default layer, etc. If you wish to localize this file, please create a +#. localized share/templates/default.xx.svg file, where xx is your language code. +#: ../../po/../src/file.cpp:133 +#, fuzzy +msgid "default.svg" +msgstr "Öntanımlı" + +#: ../../po/../src/file.cpp:215 ../../po/../src/file.cpp:900 +#, c-format +msgid "Failed to load the requested file %s" +msgstr "" + +#: ../../po/../src/file.cpp:240 +#, fuzzy +msgid "Document not saved yet. Cannot revert." +msgstr "Döküman Adı:" + +#: ../../po/../src/file.cpp:246 +#, c-format +msgid "Changes will be lost! Are you sure you want to reload document %s?" +msgstr "" + +#: ../../po/../src/file.cpp:266 +#, fuzzy +msgid "Document reverted." +msgstr "Döküman Adı:" + +#: ../../po/../src/file.cpp:268 +#, fuzzy +msgid "Document not reverted." +msgstr "Döküman Adı:" + +#: ../../po/../src/file.cpp:382 +msgid "Select file to open" +msgstr "Açılacak dosyayı seçin" + +#: ../../po/../src/file.cpp:518 +#, c-format +msgid "Removed %i unused definition in <defs>." +msgid_plural "Removed %i unused definitions in <defs>." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/file.cpp:523 +msgid "No unused definitions in <defs>." +msgstr "" + +#: ../../po/../src/file.cpp:548 +#, c-format +msgid "" +"No Inkscape extension found to save document (%s). This may have been " +"caused by an unknown filename extension." +msgstr "" + +#: ../../po/../src/file.cpp:549 ../../po/../src/file.cpp:557 +#, fuzzy +msgid "Document not saved." +msgstr "Döküman Adı:" + +#: ../../po/../src/file.cpp:556 +#, c-format +msgid "File %s could not be saved." +msgstr "" + +#: ../../po/../src/file.cpp:566 +#, fuzzy +msgid "Document saved." +msgstr "Döküman Adı:" + +#: ../../po/../src/file.cpp:614 +#, fuzzy, c-format +msgid "drawing%s" +msgstr "Çizim" + +#: ../../po/../src/file.cpp:620 +#, fuzzy, c-format +msgid "drawing-%d%s" +msgstr "Çizim" + +#: ../../po/../src/file.cpp:655 +#, fuzzy +msgid "Select file to save to" +msgstr "Açılacak dosyayı seçin" + +#: ../../po/../src/file.cpp:739 +msgid "No changes need to be saved." +msgstr "" + +#: ../../po/../src/file.cpp:926 +msgid "Select file to import" +msgstr "İçeri aktarılacak dosyayı seçin" + +#: ../../po/../src/gradient-context.cpp:263 +msgid "Ctrl: snap gradient angle" +msgstr "" + +#: ../../po/../src/gradient-context.cpp:264 +msgid "Shift: draw gradient around the starting point" +msgstr "" + +#. We did an undoable action, but sp_document_done will be called by the knot when released +#. status text; we do not track coords because this branch is run once, not all the time +#. during drag +#: ../../po/../src/gradient-context.cpp:462 +#, c-format +msgid "Gradient for %d objects; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/gradient-context.cpp:464 +#, fuzzy +msgid "Select objects on which to create gradient." +msgstr "Seçili nesneleri panoya kes" + +#: ../../po/../src/gradient-drag.cpp:65 +#, fuzzy +msgid "Linear gradient start" +msgstr "Çizgisel geçiş" + +#. POINT_LG_P1 +#: ../../po/../src/gradient-drag.cpp:66 +#, fuzzy +msgid "Linear gradient end" +msgstr "Çizgisel geçiş" + +#: ../../po/../src/gradient-drag.cpp:67 +#, fuzzy +msgid "Radial gradient center" +msgstr "Radyal geçiş" + +#: ../../po/../src/gradient-drag.cpp:68 ../../po/../src/gradient-drag.cpp:69 +#, fuzzy +msgid "Radial gradient radius" +msgstr "Radyal geçiş" + +#: ../../po/../src/gradient-drag.cpp:70 +#, fuzzy +msgid "Radial gradient focus" +msgstr "Radyal geçiş" + +#: ../../po/../src/gradient-drag.cpp:659 +#, c-format +msgid "" +"%s for: %s%s; drag with Ctrl to snap angle, with Ctrl+Alt to " +"preserve angle, with Ctrl+Shift to scale around center" +msgstr "" + +#: ../../po/../src/gradient-drag.cpp:662 +#, fuzzy +msgid " (stroke)" +msgstr "Baskılı" + +#: ../../po/../src/gradient-drag.cpp:665 +msgid "" +"Radial gradient center and focus; drag with Shift to " +"separate focus" +msgstr "" + +#: ../../po/../src/gradient-drag.cpp:667 +#, c-format +msgid "" +"Gradient point shared by %d gradients; drag with Shift to " +"separate" +msgstr "" + +#: ../../po/../src/helper/units.cpp:40 +msgid "Unit" +msgstr "Birim" + +#: ../../po/../src/helper/units.cpp:40 +msgid "Units" +msgstr "Birimler" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Point" +msgstr "Nokta" + +#: ../../po/../src/helper/units.cpp:41 +msgid "pt" +msgstr "pt" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Points" +msgstr "Noktalar" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Pt" +msgstr "Pt" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Pixel" +msgstr "Piksel" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Pixels" +msgstr "Piksel" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Px" +msgstr "Px" + +#. You can add new elements from this point forward +#: ../../po/../src/helper/units.cpp:44 ../share/extensions/straightseg.inx.h:2 +msgid "Percent" +msgstr "Yüzde" + +#: ../../po/../src/helper/units.cpp:44 +msgid "Percents" +msgstr "Yüzde" + +#: ../../po/../src/helper/units.cpp:45 +msgid "Millimeter" +msgstr "Milimetr" + +#: ../../po/../src/helper/units.cpp:45 +msgid "mm" +msgstr "mm" + +#: ../../po/../src/helper/units.cpp:45 +msgid "Millimeters" +msgstr "Milimetre" + +#: ../../po/../src/helper/units.cpp:46 +msgid "Centimeter" +msgstr "Santimetre" + +#: ../../po/../src/helper/units.cpp:46 +msgid "cm" +msgstr "cm" + +#: ../../po/../src/helper/units.cpp:46 +msgid "Centimeters" +msgstr "Santrimetre" + +#: ../../po/../src/helper/units.cpp:47 +msgid "Meter" +msgstr "Metre" + +#: ../../po/../src/helper/units.cpp:47 +msgid "m" +msgstr "m" + +#: ../../po/../src/helper/units.cpp:47 +#, fuzzy +msgid "Meters" +msgstr "Metre" + +#. no svg_unit +#: ../../po/../src/helper/units.cpp:48 +msgid "Inch" +msgstr "Ä°nç" + +#: ../../po/../src/helper/units.cpp:48 +msgid "in" +msgstr "in" + +#: ../../po/../src/helper/units.cpp:48 +msgid "Inches" +msgstr "Ä°nç" + +#. Volatiles do not have default, so there are none here +#. TRANSLATORS: for info, see http://www.w3.org/TR/REC-CSS2/syndata.html#length-units +#: ../../po/../src/helper/units.cpp:51 +msgid "Em square" +msgstr "Metrekare" + +#: ../../po/../src/helper/units.cpp:51 +msgid "em" +msgstr "em" + +#: ../../po/../src/helper/units.cpp:51 +msgid "Em squares" +msgstr "Metrekare" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/REC-CSS2/syndata.html#length-units +#: ../../po/../src/helper/units.cpp:53 +msgid "Ex square" +msgstr "Ex square" + +#: ../../po/../src/helper/units.cpp:53 +msgid "ex" +msgstr "ex" + +#: ../../po/../src/helper/units.cpp:53 +msgid "Ex squares" +msgstr "Ex squares" + +#: ../../po/../src/inkscape.cpp:468 +msgid "Untitled document" +msgstr "Başlıksız döküman" + +#. Show nice dialog box +#: ../../po/../src/inkscape.cpp:497 +#, fuzzy +msgid "Inkscape encountered an internal error and will close now.\n" +msgstr "Sodipodi, dahili bir hata karşılaştı ve şimdi kapatılacak.\n" + +#: ../../po/../src/inkscape.cpp:498 +#, fuzzy +msgid "" +"Automatic backups of unsaved documents were done to the following " +"locations:\n" +msgstr "" +"Kaydedilmeyen dökümanların otomatik yedekleri aşağıdaki konuma alınacak.\n" + +#: ../../po/../src/inkscape.cpp:499 +#, fuzzy +msgid "Automatic backup of the following documents failed:\n" +msgstr "Aşağıdaki dökümanların otomatik yedekleri alınırken hata oluştu.\n" + +#: ../../po/../src/inkscape.cpp:634 +#, c-format +msgid "" +"Cannot create directory %s.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:635 +#, c-format +msgid "" +"%s is not a valid directory.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:636 +#, c-format +msgid "" +"Cannot create file %s.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:637 +#, c-format +msgid "" +"Cannot write file %s.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:638 +msgid "" +"Although Inkscape will run, it will use default settings,\n" +"and any changes made in preferences will not be saved." +msgstr "" + +#: ../../po/../src/inkscape.cpp:708 +#, c-format +msgid "" +"%s is not a regular file.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:709 +#, c-format +msgid "" +"%s not a valid XML file, or\n" +"you don't have read permissions on it.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:711 +#, c-format +msgid "" +"%s is not a valid menus file.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:712 +msgid "" +"Inkscape will run with default menus.\n" +"New menus will not be saved." +msgstr "" + +#. sp_ui_menu_append_check_item_from_verb(m, view, _("_Menu"), _("Show or hide the menu bar"), "menu", +#. checkitem_toggled, checkitem_update, 0); +#: ../../po/../src/interface.cpp:753 +msgid "Commands Bar" +msgstr "" + +#: ../../po/../src/interface.cpp:753 +#, fuzzy +msgid "Show or hide the Commands bar (under the menu)" +msgstr "Rehberleri göster" + +#: ../../po/../src/interface.cpp:755 +#, fuzzy +msgid "Tool Controls" +msgstr "Araç ayarları" + +#: ../../po/../src/interface.cpp:755 +#, fuzzy +msgid "Show or hide the Tool Controls panel" +msgstr "Rehberleri göster" + +#: ../../po/../src/interface.cpp:757 +msgid "_Toolbox" +msgstr "" + +#: ../../po/../src/interface.cpp:757 +msgid "Show or hide the main toolbox (on the left)" +msgstr "" + +#: ../../po/../src/interface.cpp:763 +msgid "_Statusbar" +msgstr "" + +#: ../../po/../src/interface.cpp:763 +msgid "Show or hide the statusbar (at the bottom of the window)" +msgstr "" + +#: ../../po/../src/interface.cpp:820 +#, c-format +msgid "Verb \"%s\" Unknown" +msgstr "" + +#. TRANSLATORS: #%s is the id of the group e.g. , not a number. +#: ../../po/../src/interface.cpp:930 +#, fuzzy, c-format +msgid "Enter group #%s" +msgstr "Noktaları değiştir" + +#: ../../po/../src/interface.cpp:941 +#, fuzzy +msgid "Go to parent" +msgstr "Sayfayı göster" + +#: ../../po/../src/interface.cpp:972 +msgid "Could not parse SVG data" +msgstr "" + +#: ../../po/../src/interface.cpp:1135 +#, c-format +msgid "Overwrite %s" +msgstr "" + +#: ../../po/../src/interface.cpp:1153 +#, c-format +msgid "" +"The file %s already exists. Do you want to overwrite that file with the " +"current document?" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:59 +msgid "Jabber connection lost." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:72 +#, c-format +msgid "Sending message; %u message remaining in send queue." +msgid_plural "Sending message; %u messages remaining in send queue." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:78 +msgid "Receive queue empty." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:154 +#, c-format +msgid "Receiving change; %u change left to process." +msgid_plural "Receiving change; %u changes left to process." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:157 +#, c-format +msgid "%s has left the chatroom." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:221 +msgid "Nickname %1 is already in use. Please choose a different nickname." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:225 +msgid "An error was encountered while attempting to connect to the server." +msgstr "" + +#. Check to see if the user made any modifications to this document. If so, +#. we want to give them the option of (1) letting us clear their document or (2) +#. opening a new, blank document for the whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:131 +msgid "%1 has invited you to a whiteboard session." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:132 +msgid "Incoming whiteboard invitation from %1" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:135 +msgid "Do you wish to accept %1's whiteboard session invitation?" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:137 +msgid "" +"Would you like to accept %1's invitation in a new document window?\n" +"Accepting the invitation in your current window will discard unsaved changes." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:143 +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:198 +#, fuzzy +msgid "Accept invitation" +msgstr "Seçim" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:144 +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:199 +msgid "Decline invitation" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:145 +#, fuzzy +msgid "Accept invitation in new document window" +msgstr "Yeni bir SVG dökümanı oluştur" + +#. We could not create a new desktop; ask the user if she or he wants to +#. replace the current document and accept the invitation, or reject the invitation. +#. TRANSLATORS: %1 is a userid here +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:196 +msgid "" +"A new document window could not be opened for a whiteboard session with %" +"1" +msgstr "" + +#. TRANSLATORS: %1 is the peer whom refused our invitation. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:238 +msgid "" +"The user %1 has refused your " +"whiteboard invitation.\n" +"\n" +msgstr "" + +#. TRANSLATORS: %1 is the peer whom refused our invitation, %2 is our Jabber identity. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:241 +msgid "" +"You are still connected to a Jabber server as %2, and may send an " +"invitation to %1 again, or you may send an invitation to a different " +"user." +msgstr "" + +#. TRANSLATORS: %1 is the peer whom we tried to contact, but is already in a whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:252 +msgid "" +"The user %1 is already in a " +"whiteboard session.\n" +"\n" +msgstr "" + +#. TRANSLATORS: %1 is the peer whom we tried to contact, but is already in a whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:255 +msgid "" +"You are still connected to a Jabber server as %1, and may send an " +"invitation to a different user." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/invitation-confirm-dialog.cpp:26 +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:24 +msgid "_Write session file:" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/message-processors.cpp:145 +#, c-format +msgid "%s has joined the chatroom." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/message-queue.cpp:87 +#, c-format +msgid "%u change in receive queue." +msgid_plural "%u changes in receive queue." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/jabber_whiteboard/message-queue.cpp:117 +#, c-format +msgid "%u change in send queue." +msgid_plural "%u changes in send queue." +msgstr[0] "" +msgstr[1] "" + +#. if ID is NULL, then we have a real problem -- we were not able to find a key +#. nor generate one. The only thing we can really do here is abort, since we have +#. no way to let the other client(s) uniquely identify this object. +#. FIXME: If this indicates a programming bug, then don't request translation with +#. * _(...): it is most useful in untranslated form so that developers may search for +#. * it when someone reports it in a bug report (as we want users to do for all bugs, +#. * as indicated by it being a g_warning string). +#. * +#. * Otherwise, if it is not a programming bug but a network error or a bug in the +#. * remote peer (perhaps running different software) or whatever, then present it in +#. * an alert box, and avoid use of technical jargon `NULL'. +#. +#: ../../po/../src/jabber_whiteboard/message-utilities.cpp:171 +msgid "" +"ID for new object is NULL even after generation and lookup attempts: the new " +"object will NOT be sent, nor will any of its child objects!" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:60 +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:995 +msgid "Select a location and filename" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:62 +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:997 +#, fuzzy +msgid "Set filename" +msgstr "Png dosya adı" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:301 +msgid "No SSL certificate was found." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:304 +msgid "The SSL certificate provided by the Jabber server is untrusted." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:307 +msgid "The SSL certificate provided by the Jabber server is expired." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:310 +msgid "" +"The SSL certificate provided by the Jabber server has not been activated." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:313 +msgid "" +"The SSL certificate provided by the Jabber server contains a hostname that " +"does not match the Jabber server's hostname." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:316 +msgid "" +"The SSL certificate provided by the Jabber server contains an invalid " +"fingerprint." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:319 +msgid "An unknown error occurred while setting up the SSL connection." +msgstr "" + +#. TRANSLATORS: %1 is the message that describes the specific error that occurred when +#. establishing the SSL connection. +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:325 +msgid "" +"%1\n" +"\n" +"Do you wish to continue connecting to the Jabber server?" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:328 +msgid "Continue connecting and ignore further errors" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:329 +msgid "Continue connecting, but warn me of further errors" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:330 +#, fuzzy +msgid "Cancel connection" +msgstr "Seçim" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:777 +#, c-format +msgid "Established whiteboard session with %s." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:785 +#, c-format +msgid "%s has left the whiteboard session." +msgstr "" + +#. Inform the user +#. TRANSLATORS: %1 is the name of the user that disconnected, %2 is the name of the user whom the disconnected user disconnected from. +#. This message is not used in a chatroom context. +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:790 +msgid "" +"The user %1 has left the " +"whiteboard session.\n" +"\n" +msgstr "" + +#. TRANSLATORS: %1 and %2 are userids +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:792 +msgid "" +"You are still connected to a Jabber server as %2, and may establish a " +"new session to %1 or a different user." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:988 +msgid "" +"Could not open file %1 for session recording.\n" +"The error encountered was: %2.\n" +"\n" +"You may select a different location to record the session, or you may opt to " +"not record this session." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:990 +msgid "Choose a different location" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:991 +msgid "Skip session recording" +msgstr "" + +#: ../../po/../src/knot.cpp:673 +msgid "Node or handle drag canceled." +msgstr "" + +#: ../../po/../src/libnrtype/FontFactory.cpp:358 +msgid "Ignoring font without family that will crash Pango" +msgstr "" + +#: ../../po/../src/main.cpp:395 +msgid "Print the Inkscape version number" +msgstr "" + +#: ../../po/../src/main.cpp:400 +msgid "Do not use X server (only process files from console)" +msgstr "X sunucusunu kullanma (dosyaları sadece konsoldan sürdür)" + +#: ../../po/../src/main.cpp:405 +#, fuzzy +msgid "Try to use X server (even if $DISPLAY is not set)" +msgstr "$DISPLAY atanmamışsa bile X sunucusunu kullanmaya çalış)" + +#: ../../po/../src/main.cpp:410 +msgid "Open specified document(s) (option string may be excluded)" +msgstr "Belirtilen döküman(lar)ı aç (seçenekler dahil olmayacaktır)" + +#: ../../po/../src/main.cpp:411 ../../po/../src/main.cpp:416 +#: ../../po/../src/main.cpp:421 ../../po/../src/main.cpp:483 +#: ../../po/../src/main.cpp:488 ../../po/../src/main.cpp:493 +msgid "FILENAME" +msgstr "DOSYA ADI" + +#: ../../po/../src/main.cpp:415 +msgid "Print document(s) to specified output file (use '| program' for pipe)" +msgstr "" +"Dökümanları belirtilen dosyaya yazdur (başka programa yönlendirmek için '|' " +"kullanın)" + +#: ../../po/../src/main.cpp:420 +#, fuzzy +msgid "Export document to a PNG file" +msgstr "Resmi png olarak aktar" + +#: ../../po/../src/main.cpp:425 +#, fuzzy +msgid "The resolution used for exporting SVG into bitmap (default 90)" +msgstr "SVG'den bitmap'e çevirim için kullanılacak çözünürlük (öntanımlı 72.0)" + +#: ../../po/../src/main.cpp:426 +msgid "DPI" +msgstr "DPI" + +#: ../../po/../src/main.cpp:430 +#, fuzzy +msgid "" +"Exported area in SVG user units (default is the canvas; 0,0 is lower-left " +"corner)" +msgstr "" +"Milimetre değerinde aktarılan bölüm (öntanımlı olarak tüm döküman, 0,0 " +"resmin en alt sol köşesi)" + +#: ../../po/../src/main.cpp:431 +msgid "x0:y0:x1:y1" +msgstr "x0:y0:x1:y1" + +#: ../../po/../src/main.cpp:435 +msgid "Exported area is the entire drawing (not canvas)" +msgstr "" + +#: ../../po/../src/main.cpp:440 +msgid "" +"Snap the bitmap export area outwards to the nearest integer values (in SVG " +"user units)" +msgstr "" + +#: ../../po/../src/main.cpp:445 +#, fuzzy +msgid "The width of exported bitmap in pixels (overrides export-dpi)" +msgstr "Yaratılan bitmap'in piksel değerinde genişliği (dpi üzerine yazar)" + +#: ../../po/../src/main.cpp:446 +msgid "WIDTH" +msgstr "GENİŞLÄ°K" + +#: ../../po/../src/main.cpp:450 +#, fuzzy +msgid "The height of exported bitmap in pixels (overrides export-dpi)" +msgstr "Yaratılan bitmap'in piksel değerinde yüksekliği (dpi üzerine yazar)" + +#: ../../po/../src/main.cpp:451 +msgid "HEIGHT" +msgstr "YÜKSEKLÄ°K" + +#: ../../po/../src/main.cpp:455 +#, fuzzy +msgid "The ID of the object to export (overrides export-area)" +msgstr "Yaratılan bitmap'in piksel değerinde genişliği (dpi üzerine yazar)" + +#: ../../po/../src/main.cpp:456 ../../po/../src/main.cpp:532 +msgid "ID" +msgstr "" + +#. TRANSLATORS: this means: "Only export the object whose id is given in --export-id". +#. See "man inkscape" for details. +#: ../../po/../src/main.cpp:462 +msgid "" +"Export just the object with export-id, hide all others (only with export-id)" +msgstr "" + +#: ../../po/../src/main.cpp:467 +msgid "Use stored filename and DPI hints when exporting (only with export-id)" +msgstr "" + +#: ../../po/../src/main.cpp:472 +#, fuzzy +msgid "Background color of exported bitmap (any SVG-supported color string)" +msgstr "Dışarı aktarılan birmap'in arkaplanı (SVG destekli herhangi bir renk)" + +#: ../../po/../src/main.cpp:473 +msgid "COLOR" +msgstr "RENK" + +#: ../../po/../src/main.cpp:477 +#, fuzzy +msgid "Background opacity of exported bitmap (either 0.0 to 1.0, or 1 to 255)" +msgstr "Dışarı aktarılan birmap'in arkaplanı (SVG destekli herhangi bir renk)" + +#: ../../po/../src/main.cpp:478 +msgid "VALUE" +msgstr "" + +#: ../../po/../src/main.cpp:482 +#, fuzzy +msgid "Export document to plain SVG file (no sodipodi or inkscape namespaces)" +msgstr "Dökümanı düz SVG dosyasına aktar (\"xmlns:sodipodi\" alan boşluğu yok)" + +#: ../../po/../src/main.cpp:487 +#, fuzzy +msgid "Export document to a PS file" +msgstr "Resmi png olarak aktar" + +#: ../../po/../src/main.cpp:492 +#, fuzzy +msgid "Export document to an EPS file" +msgstr "Resmi png olarak aktar" + +#: ../../po/../src/main.cpp:497 +#, fuzzy +msgid "Convert text object to paths on export (EPS)" +msgstr "Seçili nesneleri eğrilere dönder" + +#: ../../po/../src/main.cpp:502 +msgid "Export files with the bounding box set to the page size (EPS)" +msgstr "" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:508 +msgid "" +"Query the X coordinate of the drawing or, if specified, of the object with --" +"query-id" +msgstr "" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:514 +msgid "" +"Query the Y coordinate of the drawing or, if specified, of the object with --" +"query-id" +msgstr "" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:520 +msgid "" +"Query the width of the drawing or, if specified, of the object with --query-" +"id" +msgstr "" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:526 +msgid "" +"Query the height of the drawing or, if specified, of the object with --query-" +"id" +msgstr "" + +#: ../../po/../src/main.cpp:531 +#, fuzzy +msgid "The ID of the object whose dimensions are queried" +msgstr "Yaratılan bitmap'in piksel değerinde genişliği (dpi üzerine yazar)" + +#. TRANSLATORS: this option makes Inkscape print the name (path) of the extension directory +#: ../../po/../src/main.cpp:537 +msgid "Print out the extension directory and exit" +msgstr "" + +#: ../../po/../src/main.cpp:542 +msgid "Show given files one-by-one, switch to next on any key/mouse event" +msgstr "" +"Verilen dosyaları teker teker göster, herhangi bir tuşa basıldığında " +"sonrakine geç" + +#: ../../po/../src/main.cpp:547 +msgid "Use the new Gtkmm GUI interface" +msgstr "" + +#: ../../po/../src/main.cpp:552 +msgid "Remove unused definitions from the defs section(s) of the document" +msgstr "" + +#: ../../po/../src/main.cpp:741 +msgid "" +"[OPTIONS...] [FILE...]\n" +"\n" +"Available options:" +msgstr "" + +#: ../../po/../src/menus-skeleton.h:17 +msgid "_New" +msgstr "_Yeni" + +#: ../../po/../src/menus-skeleton.h:22 +#, fuzzy +msgid "Open _Recent" +msgstr "Aç" + +#: ../../po/../src/menus-skeleton.h:53 +#, fuzzy +msgid "_Edit" +msgstr "Düzenle" + +#: ../../po/../src/menus-skeleton.h:84 +#, fuzzy +msgid "_View" +msgstr "Görünüm" + +#: ../../po/../src/menus-skeleton.h:85 +#, fuzzy +msgid "_Zoom" +msgstr "Büyüt" + +#: ../../po/../src/menus-skeleton.h:102 +#, fuzzy +msgid "Show/Hide" +msgstr "Rehberleri göster" + +#: ../../po/../src/menus-skeleton.h:107 +#, fuzzy +msgid "_Display mode" +msgstr "Dolgu ayarları" + +#: ../../po/../src/menus-skeleton.h:126 +#, fuzzy +msgid "_Layer" +msgstr "Küçült" + +#: ../../po/../src/menus-skeleton.h:143 +#, fuzzy +msgid "_Object" +msgstr "Nesne" + +#: ../../po/../src/menus-skeleton.h:165 +#, fuzzy +msgid "_Path" +msgstr "Yapıştır" + +#: ../../po/../src/menus-skeleton.h:188 +#, fuzzy +msgid "_Text" +msgstr "Metin" + +#: ../../po/../src/menus-skeleton.h:200 +#, fuzzy +msgid "Effects" +msgstr "Nesne" + +#: ../../po/../src/menus-skeleton.h:207 +msgid "Whiteboa_rd" +msgstr "" + +#: ../../po/../src/menus-skeleton.h:220 +#, fuzzy +msgid "_Help" +msgstr "_Yardım" + +#: ../../po/../src/menus-skeleton.h:222 +msgid "Tutorials" +msgstr "" + +#: ../../po/../src/node-context.cpp:382 +msgid "" +"Ctrl: toggle node type, snap handle angle, move hor/vert; Ctrl" +"+Alt: move along handles" +msgstr "" + +#: ../../po/../src/node-context.cpp:383 +msgid "" +"Shift: toggle node selection, disable snapping, rotate both handles" +msgstr "" + +#: ../../po/../src/node-context.cpp:384 +msgid "Alt: lock handle length; Ctrl+Alt: move along handles" +msgstr "" + +#: ../../po/../src/nodepath.cpp:1399 ../../po/../src/nodepath.cpp:1411 +#: ../../po/../src/nodepath.cpp:1492 ../../po/../src/nodepath.cpp:1504 +msgid "To join, you must have two endnodes selected." +msgstr "" + +#: ../../po/../src/nodepath.cpp:1633 ../../po/../src/nodepath.cpp:1647 +msgid "" +"Select two non-endpoint nodes on a path between which to delete " +"segments." +msgstr "" + +#: ../../po/../src/nodepath.cpp:1743 +#, fuzzy +msgid "Cannot find path between nodes." +msgstr "Seçilen düğümleri çizgilere ekle" + +#: ../../po/../src/nodepath.cpp:2822 +#, c-format +msgid "" +"Node handle: angle %0.2f°, length %s; with Ctrl to snap " +"angle; with Alt to lock length; with Shift to rotate both " +"handles" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3351 +msgid "" +"Node: drag to edit the path; with Ctrl to snap to horizontal/" +"vertical; with Ctrl+Alt to snap to handles' directions" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3375 +msgid "" +"Node handle: drag to shape the curve; with Ctrl to snap angle; " +"with Alt to lock length; with Shift to rotate both handles" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3399 +msgid "" +"Node handle: drag to shape the curve; with Ctrl to snap angle; " +"with Alt to lock length; with Shift to rotate the opposite " +"handle in sync" +msgstr "" + +#. TRANSLATORS: "end" is an adjective here (NOT a verb) +#: ../../po/../src/nodepath.cpp:3591 +#, fuzzy +msgid "end node" +msgstr "Düğüme girinti ekle" + +#. TRANSLATORS: "cusp" means "sharp" (cusp node); see also the Advanced Tutorial +#: ../../po/../src/nodepath.cpp:3596 +#, fuzzy +msgid "cusp" +msgstr "_Biz" + +#. TRANSLATORS: "smooth" is an adjective here +#: ../../po/../src/nodepath.cpp:3599 +msgid "smooth" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3601 +#, fuzzy +msgid "symmetric" +msgstr "Asimetrik" + +#. TRANSLATORS: "end" is an adjective here (NOT a verb) +#: ../../po/../src/nodepath.cpp:3607 +msgid "end node, handle retracted (drag with Shift to extend)" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3609 +msgid "one handle retracted (drag with Shift to extend)" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3612 +msgid "both handles retracted (drag with Shift to extend)" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3624 +#, fuzzy +msgid "Drag nodes or node handles; arrow keys to move nodes" +msgstr "Yeni bir eğri yaratılıyor. '+'a basarak Yeni/Ekleye ulaşabilirsiniz" + +#: ../../po/../src/nodepath.cpp:3625 +#, fuzzy +msgid "Drag the node or its handles; arrow keys to move the node" +msgstr "Yeni bir eğri yaratılıyor. '+'a basarak Yeni/Ekleye ulaşabilirsiniz" + +#: ../../po/../src/nodepath.cpp:3651 ../../po/../src/nodepath.cpp:3663 +#, fuzzy +msgid "Select a single object to edit its nodes or handles." +msgstr "Dökümanda geçiş yok" + +#: ../../po/../src/nodepath.cpp:3655 +#, c-format +msgid "" +"0 out of %i node selected. Click, Shift+click, " +"or drag around nodes to select." +msgid_plural "" +"0 out of %i nodes selected. Click, Shift+click, " +"or drag around nodes to select." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/nodepath.cpp:3661 +msgid "Drag the handles of the object to modify it." +msgstr "" + +#: ../../po/../src/nodepath.cpp:3669 +#, fuzzy, c-format +msgid "%i of %i node selected; %s. %s." +msgid_plural "%i of %i nodes selected; %s. %s." +msgstr[0] "Seçilen düğümleri çizgilere ekle" +msgstr[1] "Seçilen düğümleri çizgilere ekle" + +#: ../../po/../src/nodepath.cpp:3675 +#, fuzzy, c-format +msgid "%i of %i node selected. %s." +msgid_plural "%i of %i nodes selected. %s." +msgstr[0] "Seçilen düğümleri çizgilere ekle" +msgstr[1] "Seçilen düğümleri çizgilere ekle" + +#: ../../po/../src/object-edit.cpp:493 +msgid "" +"Adjust the horizontal rounding radius; with Ctrl to make the " +"vertical radius the same" +msgstr "" + +#: ../../po/../src/object-edit.cpp:499 +msgid "" +"Adjust the vertical rounding radius; with Ctrl to make the " +"horizontal radius the same" +msgstr "" + +#: ../../po/../src/object-edit.cpp:506 ../../po/../src/object-edit.cpp:513 +msgid "" +"Adjust the width and height of the rectangle; with Ctrl to " +"lock ratio or stretch in one dimension only" +msgstr "" + +#: ../../po/../src/object-edit.cpp:686 +msgid "Adjust ellipse width, with Ctrl to make circle" +msgstr "" + +#: ../../po/../src/object-edit.cpp:689 +msgid "Adjust ellipse height, with Ctrl to make circle" +msgstr "" + +#: ../../po/../src/object-edit.cpp:692 +msgid "" +"Position the start point of the arc or segment; with Ctrl to " +"snap angle; drag inside the ellipse for arc, outside for " +"segment" +msgstr "" + +#: ../../po/../src/object-edit.cpp:695 +msgid "" +"Position the end point of the arc or segment; with Ctrl to " +"snap angle; drag inside the ellipse for arc, outside for " +"segment" +msgstr "" + +#: ../../po/../src/object-edit.cpp:800 +msgid "" +"Adjust the tip radius of the star or polygon; with Shift to " +"round; with Alt to randomize" +msgstr "" + +#: ../../po/../src/object-edit.cpp:803 +msgid "" +"Adjust the base radius of the star; with Ctrl to keep star " +"rays radial (no skew); with Shift to round; with Alt to " +"randomize" +msgstr "" + +#: ../../po/../src/object-edit.cpp:967 +msgid "" +"Roll/unroll the spiral from inside; with Ctrl to snap angle; " +"with Alt to converge/diverge" +msgstr "" + +#: ../../po/../src/object-edit.cpp:969 +msgid "" +"Roll/unroll the spiral from outside; with Ctrl to snap angle; " +"with Shift to scale/rotate" +msgstr "" + +#: ../../po/../src/object-edit.cpp:1006 +msgid "Adjust the offset distance" +msgstr "" + +#. TRANSLATORS: This refers to the pattern that's inside the object +#: ../../po/../src/object-edit.cpp:1036 +msgid "Move the pattern fill inside the object" +msgstr "" + +#: ../../po/../src/object-edit.cpp:1038 +#, fuzzy +msgid "Scale the pattern fill uniformly" +msgstr "Seçili nesneleri panoya kes" + +#: ../../po/../src/object-edit.cpp:1040 +msgid "Rotate the pattern fill; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/object-edit.cpp:1065 +msgid "Drag to resize the flowed text frame" +msgstr "" + +#. Item dialog +#: ../../po/../src/object-ui.cpp:106 +#, fuzzy +msgid "Object _Properties" +msgstr "nesne özellikleri" + +#. Select item +#: ../../po/../src/object-ui.cpp:116 +#, fuzzy +msgid "_Select This" +msgstr "Bunu Seç" + +#. Create link +#: ../../po/../src/object-ui.cpp:126 +#, fuzzy +msgid "_Create Link" +msgstr "Bağlantı yarat" + +#. "Ungroup" +#: ../../po/../src/object-ui.cpp:199 ../../po/../src/verbs.cpp:1931 +#, fuzzy +msgid "_Ungroup" +msgstr "Gr_ubu çöz" + +#. Link dialog +#: ../../po/../src/object-ui.cpp:239 +#, fuzzy +msgid "Link _Properties" +msgstr "Bağlantı Özellikleri" + +#. Select item +#: ../../po/../src/object-ui.cpp:249 +#, fuzzy +msgid "_Follow Link" +msgstr "Bağlantıyı takip et" + +#. Reset transformations +#: ../../po/../src/object-ui.cpp:254 +#, fuzzy +msgid "_Remove Link" +msgstr "Bağlantıyı kaldır" + +#. Link dialog +#: ../../po/../src/object-ui.cpp:303 +#, fuzzy +msgid "Image _Properties" +msgstr "Resim Özellikleri" + +#. Item dialog +#: ../../po/../src/object-ui.cpp:344 +#, fuzzy +msgid "_Fill and Stroke" +msgstr "Doldur ve Vur" + +#: ../../po/../src/path-chemistry.cpp:58 +#, fuzzy +msgid "Select at least two objects to combine." +msgstr "Dökümanda geçiş yok" + +#: ../../po/../src/path-chemistry.cpp:65 +#, fuzzy +msgid "At least one of the objects is not a path, cannot combine." +msgstr "Seçili nesneleri eğrilere dönder" + +#: ../../po/../src/path-chemistry.cpp:73 +msgid "" +"You cannot combine objects from different groups or layers." +msgstr "" + +#: ../../po/../src/path-chemistry.cpp:155 +#, fuzzy +msgid "Select path(s) to break apart." +msgstr "Seçili nesneleri panoya kes" + +#: ../../po/../src/path-chemistry.cpp:231 +msgid "No path(s) to break apart in the selection." +msgstr "" + +#: ../../po/../src/path-chemistry.cpp:252 +#, fuzzy +msgid "Select object(s) to convert to path." +msgstr "Seçili nesneleri panoya kes" + +#: ../../po/../src/path-chemistry.cpp:297 +#, fuzzy +msgid "No objects to convert to path in the selection." +msgstr "Seçili nesneleri panoya kes" + +#: ../../po/../src/path-chemistry.cpp:345 +#, fuzzy +msgid "Select path(s) to reverse." +msgstr "Seçili nesneleri üste taşı" + +#: ../../po/../src/path-chemistry.cpp:370 +msgid "No paths to reverse in the selection." +msgstr "" + +#: ../../po/../src/pen-context.cpp:379 ../../po/../src/pencil-context.cpp:233 +#, fuzzy +msgid "Continuing selected path" +msgstr "Seçili yolları birleştir" + +#: ../../po/../src/pen-context.cpp:390 ../../po/../src/pencil-context.cpp:242 +#, fuzzy +msgid "Creating new path" +msgstr "Yeni bir SVG dökümanı oluştur" + +#: ../../po/../src/pen-context.cpp:394 ../../po/../src/pencil-context.cpp:246 +#, fuzzy +msgid "Appending to selected path" +msgstr "Seçileni göster" + +#: ../../po/../src/pen-context.cpp:538 +msgid "Click or click and drag to close and finish the path." +msgstr "" + +#: ../../po/../src/pen-context.cpp:548 +msgid "" +"Click or click and drag to continue the path from this point." +msgstr "" + +#: ../../po/../src/pen-context.cpp:857 +#, c-format +msgid "" +"%s: angle %3.2f°, distance %s; with Ctrl to snap angle, " +"Enter to finish the path" +msgstr "" + +#: ../../po/../src/pen-context.cpp:882 +#, c-format +msgid "" +"Curve handle: angle %3.2f°, length %s; with Ctrl to snap " +"angle" +msgstr "" + +#: ../../po/../src/pen-context.cpp:912 +#, c-format +msgid "" +"%s: angle %3.2f°, length %s; with Ctrl to snap angle, " +"with Shift to move this handle only" +msgstr "" + +#: ../../po/../src/pen-context.cpp:946 +#, fuzzy +msgid "Finishing pen" +msgstr "Serbest" + +#: ../../po/../src/pencil-context.cpp:320 +msgid "Release here to close and finish the path." +msgstr "" + +#: ../../po/../src/pencil-context.cpp:326 +#, fuzzy +msgid "Drawing a freehand path" +msgstr "Serbest şekiller çiz" + +#: ../../po/../src/pencil-context.cpp:331 +msgid "Drag to continue the path from this point." +msgstr "" + +#. Write curves to object +#: ../../po/../src/pencil-context.cpp:390 +#, fuzzy +msgid "Finishing freehand" +msgstr "Serbest" + +#: ../../po/../src/rect-context.cpp:387 +msgid "" +"Ctrl: make square or integer-ratio rect, lock a rounded corner " +"circular" +msgstr "" + +#: ../../po/../src/rect-context.cpp:549 +#, c-format +msgid "" +"Rectangle: %s × %s; with Ctrl to make square or integer-" +"ratio rectangle; with Shift to draw around the starting point" +msgstr "" + +#: ../../po/../src/select-context.cpp:243 +#, fuzzy +msgid "Move canceled." +msgstr "Seçim" + +#: ../../po/../src/select-context.cpp:252 +#, fuzzy +msgid "Selection canceled." +msgstr "Seçim" + +#: ../../po/../src/select-context.cpp:642 +msgid "Ctrl: select in groups, move hor/vert" +msgstr "" + +#: ../../po/../src/select-context.cpp:643 +msgid "Shift: toggle select, force rubberband, disable snapping" +msgstr "" + +#: ../../po/../src/select-context.cpp:644 +msgid "Alt: select under, move selected" +msgstr "" + +#: ../../po/../src/select-context.cpp:798 +#, fuzzy +msgid "Selected object is not a group. Cannot enter." +msgstr "Seçili nesneleri eğrilere dönder" + +#: ../../po/../src/select-context.cpp:876 +#, c-format +msgid "" +"Move by %s, %s; with Ctrl to restrict to horizontal/vertical; " +"with Shift to disable snapping" +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:228 +msgid "Nothing was deleted." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:259 +#, fuzzy +msgid "Select object(s) to duplicate." +msgstr "Seçili nesneleri panoya kes" + +#: ../../po/../src/selection-chemistry.cpp:420 +#, fuzzy +msgid "Select two or more objects to group." +msgstr "Seçili nesneleri üste taşı" + +#: ../../po/../src/selection-chemistry.cpp:428 +#, fuzzy +msgid "Select at least two objects to group." +msgstr "Dökümanda geçiş yok" + +#: ../../po/../src/selection-chemistry.cpp:513 +#, fuzzy +msgid "Select a group to ungroup." +msgstr "Seçili nesneleri üste taşı" + +#: ../../po/../src/selection-chemistry.cpp:554 +msgid "No groups to ungroup in the selection." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:623 +#, fuzzy +msgid "Select objects to raise." +msgstr "Seçili nesneleri panoya kes" + +#: ../../po/../src/selection-chemistry.cpp:629 +#: ../../po/../src/selection-chemistry.cpp:681 +#: ../../po/../src/selection-chemistry.cpp:715 +#: ../../po/../src/selection-chemistry.cpp:773 +msgid "" +"You cannot raise/lower objects from different groups or layers." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:673 +#, fuzzy +msgid "Select object(s) to raise to top." +msgstr "Seçili nesneleri eğrilere dönder" + +#: ../../po/../src/selection-chemistry.cpp:709 +#, fuzzy +msgid "Select object(s) to lower." +msgstr "Seçili nesneleri panoya kes" + +#: ../../po/../src/selection-chemistry.cpp:765 +#, fuzzy +msgid "Select object(s) to lower to bottom." +msgstr "Seçili nesneleri panoya kes" + +#: ../../po/../src/selection-chemistry.cpp:806 +msgid "Nothing to undo." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:813 +msgid "Nothing to redo." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:969 +msgid "Nothing was copied." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1051 +msgid "Current layer is hidden. Unhide it to be able to paste to it." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1055 +msgid "Current layer is locked. Unlock it to be able to paste to it." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1068 +#: ../../po/../src/selection-chemistry.cpp:1103 +#, fuzzy +msgid "Nothing on the clipboard." +msgstr "Seçileni panoya kopyala" + +#: ../../po/../src/selection-chemistry.cpp:1109 +#, fuzzy +msgid "Select object(s) to paste style to." +msgstr "Seçili nesneleri eğrilere dönder" + +#: ../../po/../src/selection-chemistry.cpp:1128 +#, fuzzy +msgid "Select object(s) to move to the layer above." +msgstr "Seçili nesneleri panoya kes" + +#: ../../po/../src/selection-chemistry.cpp:1146 +#, fuzzy +msgid "No more layers above." +msgstr "Döküman Adı:" + +#: ../../po/../src/selection-chemistry.cpp:1160 +#, fuzzy +msgid "Select object(s) to move to the layer below." +msgstr "Seçili nesneleri panoya kes" + +#: ../../po/../src/selection-chemistry.cpp:1178 +#, fuzzy +msgid "No more layers below." +msgstr "Döküman Adı:" + +#: ../../po/../src/selection-chemistry.cpp:1811 +#, fuzzy +msgid "Select a clone to unlink." +msgstr "Açılacak dosyayı seçin" + +#: ../../po/../src/selection-chemistry.cpp:1842 +msgid "No clones to unlink in the selection." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1859 +msgid "" +"Select a clone to go to its original. Select a linked offset " +"to go to its source. Select a text on path to go to the path. Select " +"a flowed text to go to its frame." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1882 +msgid "" +"Cannot find the object to select (orphaned clone, offset, textpath, " +"flowed text?)" +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1888 +msgid "" +"The object you're trying to select is not visible (it is in <" +"defs>)" +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1915 +#, fuzzy +msgid "Select object(s) to convert to pattern." +msgstr "Seçili nesneleri panoya kes" + +#: ../../po/../src/selection-chemistry.cpp:2006 +#, fuzzy +msgid "Select an object with pattern fill to extract objects from." +msgstr "Seçili nesneleri panoya kes" + +#: ../../po/../src/selection-chemistry.cpp:2059 +#, fuzzy +msgid "No pattern fills in the selection." +msgstr "Seçili nesneleri panoya kes" + +#: ../../po/../src/selection-chemistry.cpp:2079 +#, fuzzy +msgid "Select object(s) to make a bitmap copy." +msgstr "Seçili nesneleri eğrilere dönder" + +#: ../../po/../src/selection-describer.cpp:37 +msgid "Click selection to toggle scale/rotation handles" +msgstr "" + +#. no items +#: ../../po/../src/selection-describer.cpp:39 +msgid "" +"No objects selected. Click, Shift+click, or drag around objects to select." +msgstr "" + +#: ../../po/../src/selection-describer.cpp:51 +#, fuzzy, c-format +msgid " in layer %s" +msgstr "Düğümü büyüt" + +#: ../../po/../src/selection-describer.cpp:54 +#, fuzzy, c-format +msgid " in layer %s" +msgstr "Düğümü büyüt" + +#: ../../po/../src/selection-describer.cpp:66 +msgid "Use Shift+D to look up original" +msgstr "" + +#: ../../po/../src/selection-describer.cpp:70 +msgid "Use Shift+D to look up path" +msgstr "" + +#: ../../po/../src/selection-describer.cpp:74 +msgid "Use Shift+D to look up frame" +msgstr "" + +#: ../../po/../src/selection-describer.cpp:84 +#, fuzzy, c-format +msgid "%i object selected" +msgid_plural "%i objects selected" +msgstr[0] "Seçilen düğümleri çizgilere ekle" +msgstr[1] "Seçilen düğümleri çizgilere ekle" + +#: ../../po/../src/selection-describer.cpp:90 +#, c-format +msgid "%s%s. %s." +msgstr "" + +#: ../../po/../src/selection-describer.cpp:94 +#, fuzzy, c-format +msgid "%s in %i layer. %s." +msgid_plural "%s in %i layers. %s." +msgstr[0] "Seçilen düğümleri çizgilere ekle" +msgstr[1] "Seçilen düğümleri çizgilere ekle" + +#: ../../po/../src/seltrans.cpp:498 +msgid "" +"Center of rotation and skewing: drag to reposition; scaling with " +"Shift also uses this center" +msgstr "" + +#: ../../po/../src/seltrans.cpp:514 +msgid "" +"Squeeze or stretch selection; with Ctrl to scale uniformly; " +"with Shift to scale around rotation center" +msgstr "" + +#: ../../po/../src/seltrans.cpp:515 +msgid "" +"Scale selection; with Ctrl to scale uniformly; with Shift to scale around rotation center" +msgstr "" + +#: ../../po/../src/seltrans.cpp:519 +msgid "" +"Skew selection; with Ctrl to snap angle; with Shift to " +"skew around the opposite side" +msgstr "" + +#: ../../po/../src/seltrans.cpp:520 +msgid "" +"Rotate selection; with Ctrl to snap angle; with Shift " +"to rotate around the opposite corner" +msgstr "" + +#: ../../po/../src/seltrans.cpp:829 ../../po/../src/seltrans.cpp:909 +#, c-format +msgid "Scale: %0.2f%% x %0.2f%%; with Ctrl to lock ratio" +msgstr "" + +#. TRANSLATORS: don't modify the first ";" (it will NOT be displayed as ";" - only the second one will be) +#: ../../po/../src/seltrans.cpp:984 +#, c-format +msgid "Skew: %0.2f°; with Ctrl to snap angle" +msgstr "" + +#. TRANSLATORS: don't modify the first ";" (it will NOT be displayed as ";" - only the second one will be) +#: ../../po/../src/seltrans.cpp:1035 +#, c-format +msgid "Rotate: %0.2f°; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/seltrans.cpp:1090 +#, fuzzy, c-format +msgid "Move center to %s, %s" +msgstr "%s'e bağlantı" + +#: ../../po/../src/slideshow.cpp:90 +#, fuzzy +msgid "Inkscape slideshow" +msgstr "Sodipodi: %s : XML Görünümü" + +#: ../../po/../src/sp-anchor.cpp:181 +#, fuzzy, c-format +msgid "Link to %s" +msgstr "%s'e bağlantı" + +#: ../../po/../src/sp-anchor.cpp:185 +#, fuzzy +msgid "Link without URI" +msgstr "%s'e bağlantı" + +#: ../../po/../src/sp-ellipse.cpp:438 ../../po/../src/sp-ellipse.cpp:870 +#, fuzzy +msgid "Ellipse" +msgstr "Elips" + +#: ../../po/../src/sp-ellipse.cpp:583 +#, fuzzy +msgid "Circle" +msgstr "Değiştir" + +#: ../../po/../src/sp-ellipse.cpp:865 +#, fuzzy +msgid "Segment" +msgstr "Değiştir" + +#: ../../po/../src/sp-ellipse.cpp:867 +msgid "Arc" +msgstr "" + +#. TRANSLATORS: "Flow region" is an area where text is allowed to flow +#: ../../po/../src/sp-flowregion.cpp:276 +#, fuzzy +msgid "Flow region" +msgstr "Bağlantıyı takip et" + +#. TRANSLATORS: A region "cut out of" a flow region; text is not allowed to flow inside the +#. * flow excluded region. flowRegionExclude in SVG 1.2: see +#. * http://www.w3.org/TR/2004/WD-SVG12-20041027/flow.html#flowRegion-elem and +#. * http://www.w3.org/TR/2004/WD-SVG12-20041027/flow.html#flowRegionExclude-elem. +#: ../../po/../src/sp-flowregion.cpp:493 +msgid "Flow excluded region" +msgstr "" + +#: ../../po/../src/sp-flowtext.cpp:355 +#, c-format +msgid "Flowed text (%d characters)" +msgstr "" + +#: ../../po/../src/sp-flowtext.cpp:357 +#, c-format +msgid "Linked flowed text (%d characters)" +msgstr "" + +#: ../../po/../src/sp-guide.cpp:290 +#, fuzzy +msgid "vertical guideline" +msgstr "dikey" + +#: ../../po/../src/sp-guide.cpp:292 +#, fuzzy +msgid "horizontal guideline" +msgstr "yatay" + +#: ../../po/../src/sp-image.cpp:835 +msgid "embedded" +msgstr "" + +#: ../../po/../src/sp-image.cpp:839 +msgid "(null_pointer)" +msgstr "" + +#: ../../po/../src/sp-image.cpp:843 +#, fuzzy, c-format +msgid "Image with bad reference: %s" +msgstr "Kötü referanslı resim: %s" + +#: ../../po/../src/sp-image.cpp:844 +#, fuzzy, c-format +msgid "Image %d × %d: %s" +msgstr "Resmi renklendir %d x %d: %s" + +#: ../../po/../src/sp-item-group.cpp:390 +#, fuzzy, c-format +msgid "Group of %d object" +msgid_plural "Group of %d objects" +msgstr[0] "%d birimden oluşan grup" +msgstr[1] "%d birimden oluşan grup" + +#: ../../po/../src/sp-item.cpp:720 +msgid "Object" +msgstr "Nesne" + +#: ../../po/../src/sp-line.cpp:202 +#, fuzzy +msgid "Line" +msgstr "Değiştir" + +#. TRANSLATORS COMMENT: %s is either "outset" or "inset" depending on sign +#: ../../po/../src/sp-offset.cpp:433 +#, c-format +msgid "Linked offset, %s by %f pt" +msgstr "" + +#: ../../po/../src/sp-offset.cpp:434 ../../po/../src/sp-offset.cpp:438 +#, fuzzy +msgid "outset" +msgstr "Seçili yolları birleştir" + +#: ../../po/../src/sp-offset.cpp:434 ../../po/../src/sp-offset.cpp:438 +#, fuzzy +msgid "inset" +msgstr "Nokta" + +#. TRANSLATORS COMMENT: %s is either "outset" or "inset" depending on sign +#: ../../po/../src/sp-offset.cpp:437 +#, c-format +msgid "Dynamic offset, %s by %f pt" +msgstr "" + +#: ../../po/../src/sp-path.cpp:127 +#, fuzzy, c-format +msgid "Path (%i node)" +msgid_plural "Path (%i nodes)" +msgstr[0] "%s'e bağlantı" +msgstr[1] "%s'e bağlantı" + +#: ../../po/../src/sp-polygon.cpp:216 +#, fuzzy +msgid "Polygon" +msgstr "Değiştir" + +#: ../../po/../src/sp-polyline.cpp:179 +#, fuzzy +msgid "Polyline" +msgstr "Elips" + +#: ../../po/../src/sp-rect.cpp:250 +#, fuzzy +msgid "Rectangle" +msgstr "Değiştir" + +#. TRANSLATORS: since turn count isn't an integer, please adjust the +#. string as needed to deal with an localized plural forms. +#: ../../po/../src/sp-spiral.cpp:305 +#, c-format +msgid "Spiral with %3f turns" +msgstr "" + +#: ../../po/../src/sp-star.cpp:288 +#, c-format +msgid "Star with %d vertex" +msgid_plural "Star with %d vertices" +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/sp-star.cpp:292 +#, c-format +msgid "Polygon with %d vertex" +msgid_plural "Polygon with %d vertices" +msgstr[0] "" +msgstr[1] "" + +#. TRANSLATORS: For description of font with no name. +#: ../../po/../src/sp-text.cpp:420 +msgid "<no name found>" +msgstr "" + +#: ../../po/../src/sp-text.cpp:426 +#, fuzzy, c-format +msgid "Text on path (%s, %s)" +msgstr "%s'e bağlantı" + +#: ../../po/../src/sp-text.cpp:427 +#, fuzzy, c-format +msgid "Text (%s, %s)" +msgstr "%s'e bağlantı" + +#. TRANSLATORS: Used for statusbar description for long chains: +#. * "Clone of: Clone of: ... in Layer 1". +#: ../../po/../src/sp-use.cpp:317 +#, fuzzy +msgid "..." +msgstr "Aç" + +#: ../../po/../src/sp-use.cpp:325 +#, fuzzy, c-format +msgid "Clone of: %s" +msgstr "%s'e bağlantı" + +#: ../../po/../src/sp-use.cpp:329 +#, fuzzy +msgid "Orphaned clone" +msgstr "Değiştir" + +#: ../../po/../src/spiral-context.cpp:355 +msgid "Ctrl: snap angle" +msgstr "" + +#: ../../po/../src/spiral-context.cpp:357 +msgid "Alt: lock spiral radius" +msgstr "" + +#: ../../po/../src/spiral-context.cpp:469 +#, c-format +msgid "" +"Spiral: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/splivarot.cpp:106 +#, fuzzy +msgid "Select at least 2 paths to perform a boolean operation." +msgstr "Dökümanda geçiş yok" + +#: ../../po/../src/splivarot.cpp:112 +msgid "" +"Select exactly 2 paths to perform difference, XOR, division, or path " +"cut." +msgstr "" + +#: ../../po/../src/splivarot.cpp:129 ../../po/../src/splivarot.cpp:144 +msgid "" +"Unable to determine the z-order of the objects selected for " +"difference, XOR, division, or path cut." +msgstr "" + +#: ../../po/../src/splivarot.cpp:174 +#, fuzzy +msgid "" +"One of the objects is not a path, cannot perform boolean operation." +msgstr "Seçili nesneleri eğrilere dönder" + +#. TRANSLATORS: "to outline" means "to convert stroke to path" +#: ../../po/../src/splivarot.cpp:554 +#, fuzzy +msgid "Select path(s) to outline." +msgstr "Seçili nesneleri panoya kes" + +#. TRANSLATORS: "to outline" means "to convert stroke to path" +#: ../../po/../src/splivarot.cpp:748 +msgid "No stroked paths to outline in the selection." +msgstr "" + +#: ../../po/../src/splivarot.cpp:832 +#, fuzzy +msgid "Selected object is not a path, cannot inset/outset." +msgstr "Seçili nesneleri eğrilere dönder" + +#: ../../po/../src/splivarot.cpp:1040 +#, fuzzy +msgid "Select path(s) to inset/outset." +msgstr "Seçili nesneleri panoya kes" + +#: ../../po/../src/splivarot.cpp:1257 +msgid "No paths to inset/outset in the selection." +msgstr "" + +#: ../../po/../src/splivarot.cpp:1390 +#, fuzzy +msgid "Select path(s) to simplify." +msgstr "Seçili nesneleri panoya kes" + +#: ../../po/../src/splivarot.cpp:1417 +msgid "No paths to simplify in the selection." +msgstr "" + +#: ../../po/../src/star-context.cpp:362 +msgid "Ctrl: snap angle; keep rays radial" +msgstr "" + +#: ../../po/../src/star-context.cpp:470 +#, c-format +msgid "" +"Polygon: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/star-context.cpp:471 +#, c-format +msgid "Star: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/text-chemistry.cpp:90 +#, fuzzy +msgid "Select a text and a path to put text on path." +msgstr "Dökümanda geçiş yok" + +#: ../../po/../src/text-chemistry.cpp:95 +msgid "" +"This text object is already put to a path. Remove it from the path " +"first. Use Shift+D to look up its path." +msgstr "" + +#. rect is the only SPShape which is not yet, and thus SVG forbids us from putting text on it +#: ../../po/../src/text-chemistry.cpp:101 +msgid "" +"You cannot put text on a rectangle in this version. Convert rectangle to " +"path first." +msgstr "" + +#: ../../po/../src/text-chemistry.cpp:159 +#, fuzzy +msgid "Select a text on path to remove it from path." +msgstr "Dökümanda geçiş yok" + +#: ../../po/../src/text-chemistry.cpp:181 +#, fuzzy +msgid "No texts-on-paths in the selection." +msgstr "Seçili nesneleri panoya kes" + +#: ../../po/../src/text-chemistry.cpp:209 +#: ../../po/../src/text-chemistry.cpp:229 +#, fuzzy +msgid "Select text(s) to remove kerns from." +msgstr "Seçili nesneleri üste taşı" + +#: ../../po/../src/text-chemistry.cpp:250 +#, fuzzy +msgid "" +"Select a text and one or more paths or shapes to flow text " +"into frame." +msgstr "Dökümanda geçiş yok" + +#: ../../po/../src/text-chemistry.cpp:322 +#, fuzzy +msgid "Select a flowed text to unflow it." +msgstr "Seçili nesneleri panoya kes" + +#: ../../po/../src/text-context.cpp:463 +msgid "Click to edit the text, drag to select part of the text." +msgstr "" + +#: ../../po/../src/text-context.cpp:465 +msgid "" +"Click to edit the flowed text, drag to select part of the text." +msgstr "" + +#: ../../po/../src/text-context.cpp:540 +msgid "Non-printable character" +msgstr "" + +#: ../../po/../src/text-context.cpp:589 +#, fuzzy, c-format +msgid "Unicode: %s: %s" +msgstr "Sodipodi: %s: %s: %d" + +#: ../../po/../src/text-context.cpp:591 ../../po/../src/text-context.cpp:855 +msgid "Unicode: " +msgstr "" + +#: ../../po/../src/text-context.cpp:615 +msgid "Current layer is hidden. Unhide it to be able to add text." +msgstr "" + +#: ../../po/../src/text-context.cpp:619 +msgid "Current layer is locked. Unlock it to be able to add text." +msgstr "" + +#: ../../po/../src/text-context.cpp:673 +#, c-format +msgid "Flowed text frame: %s × %s" +msgstr "" + +#: ../../po/../src/text-context.cpp:708 ../../po/../src/text-context.cpp:1464 +msgid "Type text; Enter to start new line." +msgstr "" + +#: ../../po/../src/text-context.cpp:719 +msgid "Flowed text is created." +msgstr "" + +#: ../../po/../src/text-context.cpp:722 +msgid "" +"The frame is too small for the current font size. Flowed text not " +"created." +msgstr "" + +#: ../../po/../src/text-context.cpp:841 +msgid "No-break space" +msgstr "" + +#: ../../po/../src/text-context.cpp:1462 +msgid "Type flowed text; Enter to start new paragraph." +msgstr "" + +#: ../../po/../src/text-context.cpp:1472 ../../po/../src/tools-switch.cpp:189 +msgid "" +"Click to select or create text, drag to create flowed text; " +"then type." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:141 +msgid "" +"To edit a path, click, Shift+click, or drag around " +"nodes to select them, then drag nodes and handles. Click on an " +"object to select." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:147 +#, fuzzy +msgid "" +"Drag to create a rectangle. Drag controls to round corners and " +"resize. Click to select." +msgstr "" +"Dörtgen aracı - Köşeleri belirtilen yuvarlıkta dörtgenler ve kareler yaratır" + +#: ../../po/../src/tools-switch.cpp:153 +msgid "" +"Drag to create an ellipse. Drag controls to make an arc or " +"segment. Click to select." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:159 +msgid "" +"Drag to create a star. Drag controls to edit the star shape. " +"Click to select." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:165 +msgid "" +"Drag to create a spiral. Drag controls to edit the spiral " +"shape. Click to select." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:171 +#, fuzzy +msgid "" +"Drag to create a freehand line. Start drawing with Shift to " +"append to selected path." +msgstr "Yeni bir eğri yaratılıyor. '+'a basarak Yeni/Ekleye ulaşabilirsiniz" + +#: ../../po/../src/tools-switch.cpp:177 +#, fuzzy +msgid "" +"Click or click and drag to start a path; with Shift to " +"append to selected path." +msgstr "Yeni bir eğri yaratılıyor. '+'a basarak Yeni/Ekleye ulaşabilirsiniz" + +#: ../../po/../src/tools-switch.cpp:183 +msgid "" +"Drag to paint a calligraphic stroke. Left/right arrow " +"keys adjust width, up/down adjust angle." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:195 +#, fuzzy +msgid "" +"Drag or double click to create a gradient on selected objects, " +"drag handles to adjust gradients." +msgstr "Yeni bir eğri yaratılıyor. '+'a basarak Yeni/Ekleye ulaşabilirsiniz" + +#: ../../po/../src/tools-switch.cpp:201 +msgid "" +"Click or drag around an area to zoom in, Shift+click to " +"zoom out." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:213 +msgid "Click and drag between shapes to create a connector." +msgstr "" + +#: ../../po/../src/trace/potrace/inkscape-potrace.cpp:553 +#: ../../po/../src/trace/potrace/inkscape-potrace.cpp:654 +#, c-format +msgid "Trace: %d. %ld nodes" +msgstr "" + +#: ../../po/../src/trace/trace.cpp:53 ../../po/../src/trace/trace.cpp:62 +#: ../../po/../src/trace/trace.cpp:70 +#, fuzzy +msgid "Select an image to trace" +msgstr "Seçili nesneleri panoya kes" + +#: ../../po/../src/trace/trace.cpp:133 +#, fuzzy +msgid "Trace: No active document" +msgstr "Yeni bir SVG dökümanı oluştur" + +#: ../../po/../src/trace/trace.cpp:154 +msgid "Trace: Image has no bitmap data" +msgstr "" + +#: ../../po/../src/trace/trace.cpp:267 +#, fuzzy, c-format +msgid "Trace: Done. %ld nodes created" +msgstr "Son seçilen" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:59 ../../po/../src/verbs.cpp:2212 +msgid "About Inkscape" +msgstr "" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:66 +msgid "_Splash" +msgstr "" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:68 +msgid "_Authors" +msgstr "" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:69 +#, fuzzy +msgid "_Translators" +msgstr "Dönüşümler" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:70 +#, fuzzy +msgid "_License" +msgstr "Bağlantı" + +#. TRANSLATORS: This is the filename of the `About Inkscape' picture in +#. the `screens' directory. Thus the translation of "about.svg" should be +#. the filename of its translated version, e.g. about.zh.svg for Chinese. +#. +#. N.B. about.svg changes once per release. (We should probably rename +#. the original to about-0.40.svg etc. as soon as we have a translation. +#. If we do so, then add an item to release-checklist saying that the +#. string here should be changed.) +#. FIXME? INKSCAPE_SCREENSDIR and "about.svg" are in UTF-8, not the +#. native filename encoding... and the filename passed to sp_document_new +#. should be in UTF-*8.. +#: ../../po/../src/ui/dialog/aboutbox.cpp:114 +msgid "about.svg" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:464 +msgid "Minimum horizontal gap (in px units) between bounding boxes" +msgstr "" + +#. TRANSLATORS: Horizontal gap +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:466 +#: ../../po/../src/widgets/toolbox.cpp:1556 +msgid "H:" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:474 +msgid "Minimum vertical gap (in px units) between bounding boxes" +msgstr "" + +#. TRANSLATORS: Vertical gap +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:476 +msgid "V:" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:734 +msgid "Align" +msgstr "Hizala" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:735 +#, fuzzy +msgid "Distribute" +msgstr "Özellik" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:736 +msgid "Remove overlaps" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:737 +msgid "Nodes" +msgstr "Düğümler" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:742 +#, fuzzy +msgid "Relative to: " +msgstr "Bağlantılı taşı" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:747 +#, fuzzy +msgid "Align right sides of objects to left side of anchor" +msgstr "Çapanın soluna hizalanmış nesnelerin sağ tarafı" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:750 +#, fuzzy +msgid "Align left sides" +msgstr "Nesneleri dikey ortasına hizala" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:753 +#, fuzzy +msgid "Center on vertical axis" +msgstr "Dikey hizala" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:756 +#, fuzzy +msgid "Align right sides" +msgstr "Nesneleri yatay ortasına hizala" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:759 +#, fuzzy +msgid "Align left sides of objects to right side of anchor" +msgstr "Çapanın sağına hizalanmış nesnelerin sol tarafı" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:762 +#, fuzzy +msgid "Align bottoms of objects to top of anchor" +msgstr "Çapanın üstüne hizalanmış nesnelerin altı" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:765 +#, fuzzy +msgid "Align tops" +msgstr "Nesneleri hizala" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:768 +#, fuzzy +msgid "Center on horizontal axis" +msgstr "Yatay hizala" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:771 +#, fuzzy +msgid "Align bottoms" +msgstr "Nesne dışını sol kenara hizala" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:774 +#, fuzzy +msgid "Align tops of objects to bottom of anchor" +msgstr "Çapanın üstüne hizalanmış nesnelerin üstü" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:779 +#, fuzzy +msgid "Align baseline anchors of texts vertically" +msgstr "Seçili nesneleri dikey çevir" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:782 +#, fuzzy +msgid "Align baseline anchors of texts horizontally" +msgstr "Seçili nesneleri yatay çevir" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:787 +msgid "Make horizontal gaps between objects equal" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:791 +#, fuzzy +msgid "Distribute left sides equidistantly" +msgstr "Seçili nesneleri dikey çevir" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:794 +#, fuzzy +msgid "Distribute centers equidistantly horizontally" +msgstr "Seçili nesneleri yatay çevir" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:797 +#, fuzzy +msgid "Distribute right sides equidistantly" +msgstr "Seçili nesneleri dikey çevir" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:801 +msgid "Make vertical gaps between objects equal" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:805 +#, fuzzy +msgid "Distribute tops equidistantly" +msgstr "Seçili nesneleri dikey çevir" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:808 +#, fuzzy +msgid "Distribute centers equidistantly vertically" +msgstr "Seçili nesneleri dikey çevir" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:811 +msgid "Distribute bottoms equidistantly" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:816 +#, fuzzy +msgid "Distribute baseline anchors of texts horizontally" +msgstr "Seçili nesneleri yatay çevir" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:819 +#, fuzzy +msgid "Distribute baseline anchors of texts vertically" +msgstr "Seçili nesneleri dikey çevir" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:824 +msgid "Randomize centers in both dimensions" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:827 +msgid "Unclump objects: try to equalize edge-to-edge distances" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:832 +msgid "" +"Move objects as little as possible so that their bounding boxes do not " +"overlap" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:837 +#, fuzzy +msgid "Align selected nodes horizontally" +msgstr "Seçili nesneleri yatay çevir" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:840 +#, fuzzy +msgid "Align selected nodes vertically" +msgstr "Seçili nesneleri dikey çevir" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:843 +#, fuzzy +msgid "Distribute selected nodes horizontally" +msgstr "Seçili nesneleri yatay çevir" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:846 +#, fuzzy +msgid "Distribute selected nodes vertically" +msgstr "Seçili nesneleri dikey çevir" + +#. Rest of the widgetry +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:851 +msgid "Last selected" +msgstr "Son seçilen" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:852 +msgid "First selected" +msgstr "Ä°lk seçilen" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:853 +msgid "Biggest item" +msgstr "En büyük birim" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:854 +msgid "Smallest item" +msgstr "En küçük birim" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:856 +#: ../../po/../src/widgets/desktop-widget.cpp:1065 +msgid "Drawing" +msgstr "Çizim" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:91 +msgid "Metadata 1" +msgstr "" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:92 +msgid "Metadata 2" +msgstr "" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:187 +#, fuzzy +msgid "X coordinate of grid origin" +msgstr "Rehber çizgileri rengini seçiniz" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:189 +#, fuzzy +msgid "Y coordinate of grid origin" +msgstr "Rehber çizgileri rengini seçiniz" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:191 +#, fuzzy +msgid "Distance of vertical grid lines" +msgstr "Dikey ızgara aralığını belirle" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:193 +#, fuzzy +msgid "Distance of horizontal grid lines" +msgstr "Yatay ızgara aralığını belirle" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:197 +msgid "Max. snapping distance from grid" +msgstr "" + +#: ../../po/../src/ui/dialog/export.cpp:34 +msgid "Export" +msgstr "Dışarı aktar" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:36 +msgid "Fill" +msgstr "Doldur" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:37 +#, fuzzy +msgid "Stroke Paint" +msgstr "Sayfa genişliğini ayarla" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:38 +#, fuzzy +msgid "Stroke Style" +msgstr "Vuruş ayarları" + +#: ../../po/../src/ui/dialog/find.cpp:34 +#, fuzzy +msgid "Find" +msgstr "Izgara" + +#: ../../po/../src/ui/dialog/memory.cpp:96 +#, fuzzy +msgid "Heap" +msgstr "_Yardım" + +#: ../../po/../src/ui/dialog/memory.cpp:97 +#, fuzzy +msgid "In Use" +msgstr "Nokta" + +#. TRANSLATORS: "Slack" refers to memory which is in the heap but currently unused. +#. More typical usage is to call this memory "free" rather than "slack". +#: ../../po/../src/ui/dialog/memory.cpp:100 +#, fuzzy +msgid "Slack" +msgstr "Yıldız" + +#: ../../po/../src/ui/dialog/memory.cpp:101 +#, fuzzy +msgid "Total" +msgstr "Başlık:" + +#: ../../po/../src/ui/dialog/memory.cpp:141 +#: ../../po/../src/ui/dialog/memory.cpp:147 +#: ../../po/../src/ui/dialog/memory.cpp:154 +#: ../../po/../src/ui/dialog/memory.cpp:186 +msgid "Unknown" +msgstr "Bilinmeyen" + +#: ../../po/../src/ui/dialog/memory.cpp:167 +#, fuzzy +msgid "Combined" +msgstr "Birleştir" + +#: ../../po/../src/ui/dialog/memory.cpp:209 +#, fuzzy +msgid "Recalculate" +msgstr "Dörtgen" + +#: ../../po/../src/ui/dialog/messages.cpp:74 +#, fuzzy +msgid "Ready." +msgstr "Kırmızı:" + +#: ../../po/../src/ui/dialog/messages.cpp:75 +msgid "" +"Enable log display by setting dialogs.debug 'redirect' attribute to 1 in " +"preferences.xml" +msgstr "" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:184 +msgid "_Execute Python" +msgstr "" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:186 +msgid "_Execute Perl" +msgstr "" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:195 +msgid "Script" +msgstr "" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:205 +#, fuzzy +msgid "Output" +msgstr "Kes" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:215 +msgid "Errors" +msgstr "" + +#. Dialog organization +#: ../../po/../src/ui/dialog/session-player.cpp:73 +#, fuzzy +msgid "Session file" +msgstr "Dosyayı kaydet" + +#: ../../po/../src/ui/dialog/session-player.cpp:74 +#, fuzzy +msgid "Playback controls" +msgstr "Araç ayarları" + +#: ../../po/../src/ui/dialog/session-player.cpp:75 +#, fuzzy +msgid "Message information" +msgstr "Dönüşümü sıfırla" + +#. Active session file display +#. fixme: Does this mean the active file for the session, or the file for the active session? +#. Please indicate which with a TRANSLATORS comment. +#: ../../po/../src/ui/dialog/session-player.cpp:85 +msgid "Active session file:" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:86 +msgid "Delay (milliseconds):" +msgstr "" + +#. Unload/load buttons +#: ../../po/../src/ui/dialog/session-player.cpp:94 +#, fuzzy +msgid "Close file" +msgstr " Renkli dolgu " + +#: ../../po/../src/ui/dialog/session-player.cpp:95 +#, fuzzy +msgid "Open new file" +msgstr "Dosya aç" + +#: ../../po/../src/ui/dialog/session-player.cpp:96 +#, fuzzy +msgid "Set delay" +msgstr "Özellik ata" + +#: ../../po/../src/ui/dialog/session-player.cpp:138 +#, fuzzy +msgid "Rewind" +msgstr "Kırmızı:" + +#: ../../po/../src/ui/dialog/session-player.cpp:139 +msgid "Go back one change" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:140 +#, fuzzy +msgid "Pause" +msgstr "Yapıştır" + +#: ../../po/../src/ui/dialog/session-player.cpp:141 +msgid "Go forward one change" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:142 +msgid "Play" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:177 +#: ../../po/../src/verbs.cpp:1573 +#, fuzzy +msgid "Open session file" +msgstr "Dosya aç" + +#. ##Set up the Potrace panel +#. #### brightness #### +#. #### Multiple scanning#### +#. ----Hbox1 +#: ../../po/../src/ui/dialog/tracedialog.cpp:345 +#: ../../po/../src/ui/dialog/tracedialog.cpp:428 +#, fuzzy +msgid "Brightness" +msgstr "sağ" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:348 +msgid "Trace by a given brightness level" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:355 +msgid "Brightness cutoff for black/white" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:362 +#, fuzzy +msgid "Image Brightness" +msgstr "Resim boyutu" + +#. #### canny edge detection #### +#. TRANSLATORS: "Canny" is the name of the inventor of this edge detection method +#: ../../po/../src/ui/dialog/tracedialog.cpp:369 +msgid "Optimal Edge Detection (Canny)" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:372 +msgid "Trace with edge detection by J. Canny's algorithm" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:388 +msgid "Brightness cutoff for adjacent pixels (determines edge thickness)" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:395 +#, fuzzy +msgid "Edge Detection" +msgstr "Seçim" + +#. #### quantization #### +#. TRANSLATORS: Color Quantization: the process of reducing the number of colors +#. in an image by selecting an optimized set of representative colors and then +#. re-applying this reduced set to the original image. +#: ../../po/../src/ui/dialog/tracedialog.cpp:404 +#, fuzzy +msgid "Color Quantization" +msgstr "Renkli resim" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:407 +msgid "Trace along the boundaries of reduced colors" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:414 +msgid "The number of reduced colors" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:416 +#, fuzzy +msgid "Colors:" +msgstr "Renk" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:421 +msgid "Quantization / Reduction" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:431 +msgid "Trace the given number of brightness levels" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:438 +#, fuzzy +msgid "Scans:" +msgstr "Şekillendir" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:440 +msgid "The desired number of scans" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:448 +msgid "Trace the given number of reduced colors" +msgstr "" + +#. ---Hbox3 +#: ../../po/../src/ui/dialog/tracedialog.cpp:454 +msgid "Monochrome" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:457 +msgid "Same as Color, but convert result to grayscale" +msgstr "" + +#. TRANSLATORS: "Stack" is a verb here +#: ../../po/../src/ui/dialog/tracedialog.cpp:460 +#, fuzzy +msgid "Stack" +msgstr "Yıldız" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:463 +msgid "" +"Stack scans vertically (no gaps) or tile horizontally (usually with gaps)" +msgstr "" + +#. TRANSLATORS: "Smooth" is a verb here +#: ../../po/../src/ui/dialog/tracedialog.cpp:466 +msgid "Smooth" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:469 +msgid "Apply Gaussian blur to the bitmap before tracing" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:473 +msgid "Multiple Scanning" +msgstr "" + +#. #### Preview #### +#: ../../po/../src/ui/dialog/tracedialog.cpp:479 +#: ../../po/../src/ui/dialog/tracedialog.cpp:489 +#, fuzzy +msgid "Preview" +msgstr "Yeni Önizleme" + +#. do not expand +#: ../../po/../src/ui/dialog/tracedialog.cpp:483 +msgid "Preview the result without actual tracing" +msgstr "" + +#. #### swap black and white #### +#: ../../po/../src/ui/dialog/tracedialog.cpp:495 +msgid "Invert" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:499 +msgid "Invert black and white regions for single traces" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:503 +msgid "Thanks to Peter Selinger, http://potrace.sourceforge.net" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:506 +#, fuzzy +msgid "Credits" +msgstr "Köşeler:" + +#. done +#. TRANSLATORS: Potrace is an application for transforming bitmaps into +#. vector graphics (http://potrace.sourceforge.net/) +#: ../../po/../src/ui/dialog/tracedialog.cpp:514 +#, fuzzy +msgid "Potrace" +msgstr "Ä°pucu" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:527 +#, fuzzy +msgid "Abort a trace in progress" +msgstr "Bölümü dışarı aktar" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:531 +msgid "Execute the trace" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:80 +#: ../../po/../src/ui/dialog/transformation.cpp:90 +#, fuzzy +msgid "_Horizontal" +msgstr "yatay" + +#: ../../po/../src/ui/dialog/transformation.cpp:80 +msgid "Horizontal displacement (relative) or position (absolute)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:82 +#: ../../po/../src/ui/dialog/transformation.cpp:92 +#, fuzzy +msgid "_Vertical" +msgstr "dikey" + +#: ../../po/../src/ui/dialog/transformation.cpp:82 +msgid "Vertical displacement (relative) or position (absolute)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:84 +#, fuzzy +msgid "_Width" +msgstr "Genişlik:" + +#: ../../po/../src/ui/dialog/transformation.cpp:84 +msgid "Horizontal size increment (absolute or percentage)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:86 +#, fuzzy +msgid "_Height" +msgstr "Yükseklik" + +#: ../../po/../src/ui/dialog/transformation.cpp:86 +msgid "Vertical size increment (absolute or percentage)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:88 +#, fuzzy +msgid "A_ngle" +msgstr "Açı" + +#: ../../po/../src/ui/dialog/transformation.cpp:88 +#, fuzzy +msgid "Rotation angle (positive = counterclockwise)" +msgstr "Seçili nesneleri saat yönünde 90 derece dönder" + +#: ../../po/../src/ui/dialog/transformation.cpp:90 +msgid "" +"Horizontal skew angle (positive = counterclockwise), or absolute " +"displacement, or percentage displacement" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:92 +msgid "" +"Vertical skew angle (positive = counterclockwise), or absolute displacement, " +"or percentage displacement" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:95 +#, fuzzy +msgid "Transformation matrix element A" +msgstr "Döünüşüm kalıbı" + +#: ../../po/../src/ui/dialog/transformation.cpp:96 +#, fuzzy +msgid "Transformation matrix element B" +msgstr "Döünüşüm kalıbı" + +#: ../../po/../src/ui/dialog/transformation.cpp:97 +#, fuzzy +msgid "Transformation matrix element C" +msgstr "Döünüşüm kalıbı" + +#: ../../po/../src/ui/dialog/transformation.cpp:98 +#, fuzzy +msgid "Transformation matrix element D" +msgstr "Döünüşüm kalıbı" + +#: ../../po/../src/ui/dialog/transformation.cpp:99 +#, fuzzy +msgid "Transformation matrix element E" +msgstr "Döünüşüm kalıbı" + +#: ../../po/../src/ui/dialog/transformation.cpp:100 +#, fuzzy +msgid "Transformation matrix element F" +msgstr "Döünüşüm kalıbı" + +#: ../../po/../src/ui/dialog/transformation.cpp:102 +#, fuzzy +msgid "Rela_tive move" +msgstr "Bağlantılı taşı" + +#: ../../po/../src/ui/dialog/transformation.cpp:102 +msgid "" +"Add the specified relative displacement to the current position; otherwise, " +"edit the current absolute position directly" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:103 +msgid "Scale proportionally" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:103 +msgid "Preserve the width/height ratio of the scaled objects" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:104 +msgid "Apply to each _object separately" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:104 +msgid "" +"Apply the scale/rotate/skew to each selected object separately; otherwise, " +"transform the selection as a whole" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:105 +msgid "Edit c_urrent matrix" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:105 +msgid "" +"Edit the current transform= matrix; otherwise, post-multiply transform= by " +"this matrix" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:115 +#, fuzzy +msgid "_Move" +msgstr "Taşı" + +#: ../../po/../src/ui/dialog/transformation.cpp:118 +#, fuzzy +msgid "_Scale" +msgstr "Cetvel" + +#: ../../po/../src/ui/dialog/transformation.cpp:121 +#, fuzzy +msgid "_Rotate" +msgstr "Dönder" + +#: ../../po/../src/ui/dialog/transformation.cpp:124 +#, fuzzy +msgid "Ske_w" +msgstr "Eğilt" + +#: ../../po/../src/ui/dialog/transformation.cpp:127 +msgid "Matri_x" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:141 +msgid "Reset the values on the current tab to defaults" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:148 +#, fuzzy +msgid "Apply transformation to selection" +msgstr "Nesne ve grupları seç ve değiştir" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:43 +msgid "_Use SSL" +msgstr "" + +#. Construct dialog interface +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:68 +#, fuzzy +msgid "_Server:" +msgstr "Dosya" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:69 +#, fuzzy +msgid "_Username:" +msgstr "Dosya adı:" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:70 +msgid "_Password:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:71 +msgid "P_ort:" +msgstr "" + +#. Buttons +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:99 +#, fuzzy +msgid "Connect" +msgstr "İçerik" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:126 +msgid "Establishing connection to Jabber server %1 as user %2" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:131 +msgid "Failed to establish connection to Jabber server %1" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:136 +msgid "Authentication failed on Jabber server %1 as %2" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:141 +msgid "SSL initialization failed when connecting to Jabber server %1" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:147 +msgid "Connected to Jabber server %1 as %2" +msgstr "" + +#. Construct labels +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:75 +msgid "Chatroom _name:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:76 +msgid "Chatroom _server:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:77 +msgid "Chatroom _password:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:78 +msgid "Chatroom _handle:" +msgstr "" + +#. Button setup and callback registration +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:97 +msgid "Connect to chatroom" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:132 +msgid "Synchronizing with chatroom %1@%2 using the handle %3" +msgstr "" + +#. Construct dialog interface +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:78 +msgid "_User's Jabber ID:" +msgstr "" + +#. Buttons +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:82 +msgid "_Invite user" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:83 +#, fuzzy +msgid "_Cancel" +msgstr "Ä°ptal" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:94 +msgid "Buddy List" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:170 +msgid "Sending whiteboard invitation to %1" +msgstr "" + +#. FIXME: strings are replaced by placeholders, NOT to be translated until the code is enabled +#. See http://sourceforge.net/mailarchive/message.php?msg_id=11746016 for details +#. File menu +#. Edit menu +#. View menu +#. Layer menu +#. Object menu +#. Path menu +#. add(Gtk::StockItem(CLEANUP, _("PLACEHOLDER, do not translate"))); (using Gtk::Stock::CLEAR) +#. Text menu +#. About menu +#. Tools toolbox +#. Select Tool controls +#. Node Tool controls +#. Calligraphy Tool controls +#. Session playback controls +#: ../../po/../src/ui/stock-items.cpp:34 ../../po/../src/ui/stock-items.cpp:35 +#: ../../po/../src/ui/stock-items.cpp:36 ../../po/../src/ui/stock-items.cpp:37 +#: ../../po/../src/ui/stock-items.cpp:38 ../../po/../src/ui/stock-items.cpp:39 +#: ../../po/../src/ui/stock-items.cpp:40 ../../po/../src/ui/stock-items.cpp:41 +#: ../../po/../src/ui/stock-items.cpp:42 ../../po/../src/ui/stock-items.cpp:43 +#: ../../po/../src/ui/stock-items.cpp:46 ../../po/../src/ui/stock-items.cpp:47 +#: ../../po/../src/ui/stock-items.cpp:48 ../../po/../src/ui/stock-items.cpp:49 +#: ../../po/../src/ui/stock-items.cpp:50 ../../po/../src/ui/stock-items.cpp:51 +#: ../../po/../src/ui/stock-items.cpp:52 ../../po/../src/ui/stock-items.cpp:53 +#: ../../po/../src/ui/stock-items.cpp:54 ../../po/../src/ui/stock-items.cpp:55 +#: ../../po/../src/ui/stock-items.cpp:56 ../../po/../src/ui/stock-items.cpp:57 +#: ../../po/../src/ui/stock-items.cpp:58 ../../po/../src/ui/stock-items.cpp:59 +#: ../../po/../src/ui/stock-items.cpp:62 ../../po/../src/ui/stock-items.cpp:63 +#: ../../po/../src/ui/stock-items.cpp:64 ../../po/../src/ui/stock-items.cpp:65 +#: ../../po/../src/ui/stock-items.cpp:66 ../../po/../src/ui/stock-items.cpp:67 +#: ../../po/../src/ui/stock-items.cpp:68 ../../po/../src/ui/stock-items.cpp:69 +#: ../../po/../src/ui/stock-items.cpp:70 ../../po/../src/ui/stock-items.cpp:71 +#: ../../po/../src/ui/stock-items.cpp:72 ../../po/../src/ui/stock-items.cpp:73 +#: ../../po/../src/ui/stock-items.cpp:74 ../../po/../src/ui/stock-items.cpp:75 +#: ../../po/../src/ui/stock-items.cpp:76 ../../po/../src/ui/stock-items.cpp:77 +#: ../../po/../src/ui/stock-items.cpp:78 ../../po/../src/ui/stock-items.cpp:79 +#: ../../po/../src/ui/stock-items.cpp:80 ../../po/../src/ui/stock-items.cpp:81 +#: ../../po/../src/ui/stock-items.cpp:82 ../../po/../src/ui/stock-items.cpp:83 +#: ../../po/../src/ui/stock-items.cpp:84 ../../po/../src/ui/stock-items.cpp:85 +#: ../../po/../src/ui/stock-items.cpp:86 ../../po/../src/ui/stock-items.cpp:87 +#: ../../po/../src/ui/stock-items.cpp:88 ../../po/../src/ui/stock-items.cpp:89 +#: ../../po/../src/ui/stock-items.cpp:92 ../../po/../src/ui/stock-items.cpp:93 +#: ../../po/../src/ui/stock-items.cpp:94 ../../po/../src/ui/stock-items.cpp:95 +#: ../../po/../src/ui/stock-items.cpp:96 ../../po/../src/ui/stock-items.cpp:97 +#: ../../po/../src/ui/stock-items.cpp:98 ../../po/../src/ui/stock-items.cpp:99 +#: ../../po/../src/ui/stock-items.cpp:100 +#: ../../po/../src/ui/stock-items.cpp:101 +#: ../../po/../src/ui/stock-items.cpp:102 +#: ../../po/../src/ui/stock-items.cpp:103 +#: ../../po/../src/ui/stock-items.cpp:104 +#: ../../po/../src/ui/stock-items.cpp:105 +#: ../../po/../src/ui/stock-items.cpp:108 +#: ../../po/../src/ui/stock-items.cpp:109 +#: ../../po/../src/ui/stock-items.cpp:110 +#: ../../po/../src/ui/stock-items.cpp:111 +#: ../../po/../src/ui/stock-items.cpp:112 +#: ../../po/../src/ui/stock-items.cpp:113 +#: ../../po/../src/ui/stock-items.cpp:114 +#: ../../po/../src/ui/stock-items.cpp:115 +#: ../../po/../src/ui/stock-items.cpp:116 +#: ../../po/../src/ui/stock-items.cpp:117 +#: ../../po/../src/ui/stock-items.cpp:118 +#: ../../po/../src/ui/stock-items.cpp:119 +#: ../../po/../src/ui/stock-items.cpp:120 +#: ../../po/../src/ui/stock-items.cpp:121 +#: ../../po/../src/ui/stock-items.cpp:122 +#: ../../po/../src/ui/stock-items.cpp:123 +#: ../../po/../src/ui/stock-items.cpp:124 +#: ../../po/../src/ui/stock-items.cpp:125 +#: ../../po/../src/ui/stock-items.cpp:126 +#: ../../po/../src/ui/stock-items.cpp:127 +#: ../../po/../src/ui/stock-items.cpp:130 +#: ../../po/../src/ui/stock-items.cpp:131 +#: ../../po/../src/ui/stock-items.cpp:132 +#: ../../po/../src/ui/stock-items.cpp:133 +#: ../../po/../src/ui/stock-items.cpp:134 +#: ../../po/../src/ui/stock-items.cpp:135 +#: ../../po/../src/ui/stock-items.cpp:136 +#: ../../po/../src/ui/stock-items.cpp:137 +#: ../../po/../src/ui/stock-items.cpp:138 +#: ../../po/../src/ui/stock-items.cpp:139 +#: ../../po/../src/ui/stock-items.cpp:140 +#: ../../po/../src/ui/stock-items.cpp:141 +#: ../../po/../src/ui/stock-items.cpp:142 +#: ../../po/../src/ui/stock-items.cpp:143 +#: ../../po/../src/ui/stock-items.cpp:144 +#: ../../po/../src/ui/stock-items.cpp:145 +#: ../../po/../src/ui/stock-items.cpp:146 +#: ../../po/../src/ui/stock-items.cpp:150 +#: ../../po/../src/ui/stock-items.cpp:151 +#: ../../po/../src/ui/stock-items.cpp:152 +#: ../../po/../src/ui/stock-items.cpp:153 +#: ../../po/../src/ui/stock-items.cpp:156 +#: ../../po/../src/ui/stock-items.cpp:157 +#: ../../po/../src/ui/stock-items.cpp:158 +#: ../../po/../src/ui/stock-items.cpp:161 +#: ../../po/../src/ui/stock-items.cpp:162 +#: ../../po/../src/ui/stock-items.cpp:163 +#: ../../po/../src/ui/stock-items.cpp:164 +#: ../../po/../src/ui/stock-items.cpp:165 +#: ../../po/../src/ui/stock-items.cpp:166 +#: ../../po/../src/ui/stock-items.cpp:167 +#: ../../po/../src/ui/stock-items.cpp:168 +#: ../../po/../src/ui/stock-items.cpp:169 +#: ../../po/../src/ui/stock-items.cpp:170 +#: ../../po/../src/ui/stock-items.cpp:171 +#: ../../po/../src/ui/stock-items.cpp:172 +#: ../../po/../src/ui/stock-items.cpp:175 +#: ../../po/../src/ui/stock-items.cpp:176 +#: ../../po/../src/ui/stock-items.cpp:177 +#: ../../po/../src/ui/stock-items.cpp:178 +#: ../../po/../src/ui/stock-items.cpp:181 +#: ../../po/../src/ui/stock-items.cpp:182 +#: ../../po/../src/ui/stock-items.cpp:183 +#: ../../po/../src/ui/stock-items.cpp:184 +#: ../../po/../src/ui/stock-items.cpp:185 +#: ../../po/../src/ui/stock-items.cpp:186 +#: ../../po/../src/ui/stock-items.cpp:187 +#: ../../po/../src/ui/stock-items.cpp:188 +#: ../../po/../src/ui/stock-items.cpp:189 +#: ../../po/../src/ui/stock-items.cpp:190 +#: ../../po/../src/ui/stock-items.cpp:191 +#: ../../po/../src/ui/stock-items.cpp:194 +#: ../../po/../src/ui/stock-items.cpp:195 +#: ../../po/../src/ui/stock-items.cpp:198 +#: ../../po/../src/ui/stock-items.cpp:199 +#: ../../po/../src/ui/stock-items.cpp:200 +#: ../../po/../src/ui/stock-items.cpp:201 +#: ../../po/../src/ui/stock-items.cpp:202 +msgid "PLACEHOLDER, do not translate" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:88 +msgid "small" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:89 +msgid "medium" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:90 +#, fuzzy +msgid "large" +msgstr "Hedef:" + +#: ../../po/../src/ui/widget/panel.cpp:91 +msgid "huge" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:106 +#, fuzzy +msgid "List" +msgstr "Nokta" + +#: ../../po/../src/ui/widget/selected-style.cpp:67 +msgid "F:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:68 +msgid "S:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:69 +msgid "O:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:95 +msgid "N/A" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:98 +#: ../../po/../src/ui/widget/selected-style.cpp:712 +#, fuzzy +msgid "Nothing selected" +msgstr "Seçili nesneleri sil" + +#: ../../po/../src/ui/widget/selected-style.cpp:103 +#, fuzzy +msgid "No fill" +msgstr " Renkli dolgu " + +#: ../../po/../src/ui/widget/selected-style.cpp:103 +#, fuzzy +msgid "No stroke" +msgstr "Baskılı" + +#: ../../po/../src/ui/widget/selected-style.cpp:105 +#: ../../po/../src/widgets/paint-selector.cpp:190 +#, fuzzy +msgid "Pattern" +msgstr "Motif:" + +#: ../../po/../src/ui/widget/selected-style.cpp:108 +#: ../../po/../src/widgets/paint-selector.cpp:885 +#, fuzzy +msgid "Pattern fill" +msgstr "Motif:" + +#: ../../po/../src/ui/widget/selected-style.cpp:108 +#, fuzzy +msgid "Pattern stroke" +msgstr "Motif" + +#: ../../po/../src/ui/widget/selected-style.cpp:110 +#, fuzzy +msgid "L Gradient" +msgstr "Geçişim" + +#: ../../po/../src/ui/widget/selected-style.cpp:113 +#, fuzzy +msgid "Linear gradient fill" +msgstr "Çizgisel geçiş" + +#: ../../po/../src/ui/widget/selected-style.cpp:113 +#, fuzzy +msgid "Linear gradient stroke" +msgstr "Çizgisel geçiş" + +#: ../../po/../src/ui/widget/selected-style.cpp:115 +#, fuzzy +msgid "R Gradient" +msgstr "Geçişim" + +#: ../../po/../src/ui/widget/selected-style.cpp:118 +#, fuzzy +msgid "Radial gradient fill" +msgstr "Radyal geçiş" + +#: ../../po/../src/ui/widget/selected-style.cpp:118 +#, fuzzy +msgid "Radial gradient stroke" +msgstr "Radyal geçiş" + +#: ../../po/../src/ui/widget/selected-style.cpp:120 +#, fuzzy +msgid "Different" +msgstr "derece" + +#: ../../po/../src/ui/widget/selected-style.cpp:123 +#, fuzzy +msgid "Different fills" +msgstr "derece" + +#: ../../po/../src/ui/widget/selected-style.cpp:123 +#, fuzzy +msgid "Different strokes" +msgstr "derece" + +#: ../../po/../src/ui/widget/selected-style.cpp:125 +#, fuzzy +msgid "Unset" +msgstr "Nokta" + +#. TRANSLATORS COMMENT: unset is a verb here +#: ../../po/../src/ui/widget/selected-style.cpp:128 +#: ../../po/../src/ui/widget/selected-style.cpp:182 +#, fuzzy +msgid "Unset fill" +msgstr "Başlıksız" + +#: ../../po/../src/ui/widget/selected-style.cpp:128 +#: ../../po/../src/ui/widget/selected-style.cpp:182 +#, fuzzy +msgid "Unset stroke" +msgstr "Baskılı" + +#: ../../po/../src/ui/widget/selected-style.cpp:131 +#, fuzzy +msgid "Flat color fill" +msgstr "renk" + +#: ../../po/../src/ui/widget/selected-style.cpp:131 +#, fuzzy +msgid "Flat color stroke" +msgstr "renk" + +#. TRANSLATOR COMMENT: A means "Averaged" +#: ../../po/../src/ui/widget/selected-style.cpp:134 +msgid "A" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:137 +#, fuzzy +msgid "Fill is averaged over selected objects" +msgstr "Seçili nesnelerin yerleşimini değiştir" + +#: ../../po/../src/ui/widget/selected-style.cpp:137 +#, fuzzy +msgid "Stroke is averaged over selected objects" +msgstr "Seçili nesnelerin baskı tipini değiştir" + +#. TRANSLATOR COMMENT: M means "Multiple" +#: ../../po/../src/ui/widget/selected-style.cpp:140 +msgid "M" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:143 +#, fuzzy +msgid "Multiple selected objects have the same fill" +msgstr "Seçili nesneleri dikey çevir" + +#: ../../po/../src/ui/widget/selected-style.cpp:143 +#, fuzzy +msgid "Multiple selected objects have the same stroke" +msgstr "Seçili nesneleri dikey çevir" + +#: ../../po/../src/ui/widget/selected-style.cpp:145 +#, fuzzy +msgid "Edit fill..." +msgstr "Değiştir" + +#: ../../po/../src/ui/widget/selected-style.cpp:145 +#, fuzzy +msgid "Edit stroke..." +msgstr "Değiştir" + +#: ../../po/../src/ui/widget/selected-style.cpp:149 +#, fuzzy +msgid "Last set color" +msgstr "renk" + +#: ../../po/../src/ui/widget/selected-style.cpp:153 +#, fuzzy +msgid "Last selected color" +msgstr "Son seçilen" + +#: ../../po/../src/ui/widget/selected-style.cpp:157 +msgid "White" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:161 +#: ../../po/../src/widgets/sp-color-scales.cpp:461 +#: ../../po/../src/widgets/sp-color-scales.cpp:462 +#, fuzzy +msgid "Black" +msgstr "Siyah:" + +#: ../../po/../src/ui/widget/selected-style.cpp:165 +#, fuzzy +msgid "Copy color" +msgstr "Başlangıç rengi" + +#: ../../po/../src/ui/widget/selected-style.cpp:169 +#, fuzzy +msgid "Paste color" +msgstr "renk" + +#: ../../po/../src/ui/widget/selected-style.cpp:173 +#, fuzzy +msgid "Swap fill and stroke" +msgstr "Doldur ve Vur" + +#: ../../po/../src/ui/widget/selected-style.cpp:177 +msgid "Make fill opaque" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:177 +msgid "Make stroke opaque" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:186 +#, fuzzy +msgid "Remove fill" +msgstr "Bağlantıyı kaldır" + +#: ../../po/../src/ui/widget/selected-style.cpp:186 +#, fuzzy +msgid "Remove stroke" +msgstr "Bağlantıyı kaldır" + +#: ../../po/../src/ui/widget/selected-style.cpp:718 +#, fuzzy +msgid "Master opacity" +msgstr "Donukluk:" + +#: ../../po/../src/ui/widget/selected-style.cpp:744 +msgid "0 (transparent)" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:768 +msgid "1.0 (opaque)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1046 +msgid "Moved to next layer." +msgstr "" + +#: ../../po/../src/verbs.cpp:1048 +msgid "Cannot move past last layer." +msgstr "" + +#: ../../po/../src/verbs.cpp:1057 +msgid "Moved to previous layer." +msgstr "" + +#: ../../po/../src/verbs.cpp:1059 +msgid "Cannot move past first layer." +msgstr "" + +#: ../../po/../src/verbs.cpp:1076 ../../po/../src/verbs.cpp:1150 +#, fuzzy +msgid "No current layer." +msgstr "Döküman Adı:" + +#: ../../po/../src/verbs.cpp:1105 +#, fuzzy, c-format +msgid "Raised layer %s." +msgstr "Düğümü büyüt" + +#: ../../po/../src/verbs.cpp:1109 +#, fuzzy, c-format +msgid "Lowered layer %s." +msgstr "Seç" + +#: ../../po/../src/verbs.cpp:1118 +msgid "Cannot move layer any further." +msgstr "" + +#. TRANSLATORS: this means "The layer has been deleted." +#: ../../po/../src/verbs.cpp:1148 +#, fuzzy +msgid "Deleted layer." +msgstr "Seç" + +#: ../../po/../src/verbs.cpp:1544 +msgid "" +"You need to connect to a Jabber server before sharing a document with " +"another user." +msgstr "" + +#: ../../po/../src/verbs.cpp:1559 +msgid "" +"You need to connect to a Jabber server before sharing a document with a " +"chatroom." +msgstr "" + +#: ../../po/../src/verbs.cpp:1569 +msgid "XML node tracker has not been initialized; nothing to dump" +msgstr "" + +#. TRANSLATORS: If you have translated the keys.svg file to your language, then +#. translate this string as "keys.LANG.svg" (where LANG is your language code); +#. otherwise leave as "keys.svg". +#: ../../po/../src/verbs.cpp:1631 +msgid "keys.svg" +msgstr "" + +#. TRANSLATORS: If you have translated the tutorial-basic.svg file to your language, +#. then translate this string as "tutorial-basic.LANG.svg" (where LANG is your language +#. code); otherwise leave as "tutorial-basic.svg". +#: ../../po/../src/verbs.cpp:1667 +msgid "tutorial-basic.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1671 +msgid "tutorial-shapes.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1675 +msgid "tutorial-advanced.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1679 +msgid "tutorial-tracing.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1683 +msgid "tutorial-calligraphy.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1687 +msgid "tutorial-elements.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1691 +msgid "tutorial-tips.svg" +msgstr "" + +#: ../../po/../src/verbs.cpp:1842 +msgid "Does nothing" +msgstr "" + +#. File +#: ../../po/../src/verbs.cpp:1845 +#, fuzzy +msgid "Default" +msgstr "Öntanımlı" + +#: ../../po/../src/verbs.cpp:1845 +#, fuzzy +msgid "Create new document from default template" +msgstr "Yeni bir SVG dökümanı oluştur" + +#: ../../po/../src/verbs.cpp:1847 +#, fuzzy +msgid "_Open..." +msgstr "Aç" + +#: ../../po/../src/verbs.cpp:1848 +#, fuzzy +msgid "Open existing document" +msgstr "SVG dökümanı aç" + +#: ../../po/../src/verbs.cpp:1849 +msgid "Re_vert" +msgstr "" + +#: ../../po/../src/verbs.cpp:1850 +msgid "Revert to the last saved version of document (changes will be lost)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1851 +#, fuzzy +msgid "_Save" +msgstr "Kayde" + +#: ../../po/../src/verbs.cpp:1851 +msgid "Save document" +msgstr "Dökümanı kaydet" + +#: ../../po/../src/verbs.cpp:1853 +#, fuzzy +msgid "Save _As..." +msgstr "Farklı kaydet" + +#: ../../po/../src/verbs.cpp:1854 +msgid "Save document under new name" +msgstr "Dökümanı yeni bir adla kaydet" + +#: ../../po/../src/verbs.cpp:1855 +#, fuzzy +msgid "_Print..." +msgstr "Yazdır" + +#: ../../po/../src/verbs.cpp:1855 +msgid "Print document" +msgstr "Dökümanı yazdır" + +#. TRANSLATORS: "Vacuum Defs" means "Clean up defs" (so as to remove unused definitions) +#: ../../po/../src/verbs.cpp:1858 +msgid "Vac_uum Defs" +msgstr "" + +#: ../../po/../src/verbs.cpp:1858 +msgid "Remove unused predefined items from the <defs> of the document" +msgstr "" + +#: ../../po/../src/verbs.cpp:1860 +#, fuzzy +msgid "Print _Direct" +msgstr "Bağlantı Özellikleri" + +#: ../../po/../src/verbs.cpp:1861 +msgid "Print directly without prompting to a file or pipe" +msgstr "" + +#: ../../po/../src/verbs.cpp:1862 +#, fuzzy +msgid "Print Previe_w" +msgstr "Önizleme" + +#: ../../po/../src/verbs.cpp:1863 +msgid "Preview document printout" +msgstr "Döküman Öngörünümü" + +#: ../../po/../src/verbs.cpp:1864 +#, fuzzy +msgid "_Import..." +msgstr "_Ä°thal et" + +#: ../../po/../src/verbs.cpp:1865 +msgid "Import bitmap or SVG image into document" +msgstr "Bitmap veya SVG dosyasını döküman içine aktar" + +#: ../../po/../src/verbs.cpp:1866 +#, fuzzy +msgid "_Export Bitmap..." +msgstr "Bitmap'i dışarı aktar" + +#: ../../po/../src/verbs.cpp:1867 +#, fuzzy +msgid "Export document or selection as a bitmap image" +msgstr "Dökümanı png olarak aktar" + +#: ../../po/../src/verbs.cpp:1868 +#, fuzzy +msgid "N_ext Window" +msgstr "Diyalogu kapat" + +#: ../../po/../src/verbs.cpp:1869 +msgid "Switch to the next document window" +msgstr "" + +#: ../../po/../src/verbs.cpp:1870 +#, fuzzy +msgid "P_revious Window" +msgstr "Diyalogu kapat" + +#: ../../po/../src/verbs.cpp:1871 +msgid "Switch to the previous document window" +msgstr "" + +#: ../../po/../src/verbs.cpp:1872 +#, fuzzy +msgid "_Close" +msgstr "Kapat" + +#: ../../po/../src/verbs.cpp:1873 +#, fuzzy +msgid "Close window" +msgstr "Görünümü Kapat" + +#: ../../po/../src/verbs.cpp:1874 +#, fuzzy +msgid "_Quit" +msgstr "Çı_k" + +#: ../../po/../src/verbs.cpp:1874 +#, fuzzy +msgid "Quit Inkscape" +msgstr "Sodipodi: %s : XML Görünümü" + +#. Edit +#: ../../po/../src/verbs.cpp:1877 +#, fuzzy +msgid "_Undo" +msgstr "Geri Al" + +#: ../../po/../src/verbs.cpp:1877 +#, fuzzy +msgid "Undo last action" +msgstr "Son eyleme dön" + +#: ../../po/../src/verbs.cpp:1879 +#, fuzzy +msgid "_Redo" +msgstr "Yeniden yap" + +#: ../../po/../src/verbs.cpp:1880 +#, fuzzy +msgid "Do again last undone action" +msgstr "Geri alınan eylemi yeniden yap" + +#: ../../po/../src/verbs.cpp:1881 +#, fuzzy +msgid "Cu_t" +msgstr "Kes" + +#: ../../po/../src/verbs.cpp:1882 +#, fuzzy +msgid "Cut selection to clipboard" +msgstr "Seçili nesneleri panoya kes" + +#: ../../po/../src/verbs.cpp:1883 +#, fuzzy +msgid "_Copy" +msgstr "Kopya" + +#: ../../po/../src/verbs.cpp:1884 +#, fuzzy +msgid "Copy selection to clipboard" +msgstr "Seçili nesneleri panoya kopyala" + +#: ../../po/../src/verbs.cpp:1885 +#, fuzzy +msgid "_Paste" +msgstr "Yapıştır" + +#: ../../po/../src/verbs.cpp:1886 +#, fuzzy +msgid "Paste objects from clipboard to mouse point" +msgstr "Panodan nesne yapıştır" + +#: ../../po/../src/verbs.cpp:1887 +#, fuzzy +msgid "Paste _Style" +msgstr "Vuruş stili" + +#: ../../po/../src/verbs.cpp:1888 +#, fuzzy +msgid "Apply style of the copied object to selection" +msgstr "Seçili nesneleri panoya kopyala" + +#: ../../po/../src/verbs.cpp:1889 +#, fuzzy +msgid "Paste _In Place" +msgstr "Vuruş stili" + +#: ../../po/../src/verbs.cpp:1890 +#, fuzzy +msgid "Paste objects from clipboard to the original location" +msgstr "Nesneleri yatay ortasına hizala" + +#: ../../po/../src/verbs.cpp:1891 +msgid "_Delete" +msgstr "S_il" + +#: ../../po/../src/verbs.cpp:1892 +#, fuzzy +msgid "Delete selection" +msgstr "Seçileni klonla" + +#: ../../po/../src/verbs.cpp:1893 +#, fuzzy +msgid "Duplic_ate" +msgstr "Çiftle" + +#: ../../po/../src/verbs.cpp:1894 +#, fuzzy +msgid "Duplicate selected objects" +msgstr "Seçili nesneleri çiftle" + +#: ../../po/../src/verbs.cpp:1895 +#, fuzzy +msgid "Clo_ne" +msgstr "Kapat" + +#: ../../po/../src/verbs.cpp:1896 +msgid "Create a clone of selected object (a copy linked to the original)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1897 +msgid "Unlin_k Clone" +msgstr "" + +#: ../../po/../src/verbs.cpp:1898 +msgid "Cut the clone's link to its original" +msgstr "" + +#: ../../po/../src/verbs.cpp:1899 +#, fuzzy +msgid "Select _Original" +msgstr "Seç" + +#: ../../po/../src/verbs.cpp:1900 +#, fuzzy +msgid "Select the object to which the clone is linked" +msgstr "Seçili nesneleri panoya kes" + +#. TRANSLATORS: Convert selection to a rectangle with tiled pattern fill +#: ../../po/../src/verbs.cpp:1902 +#, fuzzy +msgid "O_bjects to Pattern" +msgstr "Nesne dönüşümü" + +#: ../../po/../src/verbs.cpp:1903 +msgid "Convert selection to a rectangle with tiled pattern fill" +msgstr "" + +#. TRANSLATORS: Extract objects from a tiled pattern fill +#: ../../po/../src/verbs.cpp:1905 +#, fuzzy +msgid "Pattern to Ob_jects" +msgstr "Seçilen nesneler" + +#: ../../po/../src/verbs.cpp:1906 +msgid "Extract objects from a tiled pattern fill" +msgstr "" + +#: ../../po/../src/verbs.cpp:1907 +#, fuzzy +msgid "Clea_r All" +msgstr "Hepsini temizle" + +#: ../../po/../src/verbs.cpp:1908 +msgid "Delete all objects from document" +msgstr "" + +#: ../../po/../src/verbs.cpp:1909 +#, fuzzy +msgid "Select Al_l" +msgstr "Seç" + +#: ../../po/../src/verbs.cpp:1910 +#, fuzzy +msgid "Select all objects or all nodes" +msgstr "Dökümanda geçiş yok" + +#: ../../po/../src/verbs.cpp:1911 +#, fuzzy +msgid "Select All in All La_yers" +msgstr "Seç" + +#: ../../po/../src/verbs.cpp:1912 +#, fuzzy +msgid "Select all objects in all visible and unlocked layers" +msgstr "Dökümanda geçiş yok" + +#: ../../po/../src/verbs.cpp:1913 +#, fuzzy +msgid "In_vert Selection" +msgstr "Seçim" + +#: ../../po/../src/verbs.cpp:1914 +msgid "Invert selection (unselect what is selected and select everything else)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1915 +msgid "Invert in All Layers" +msgstr "" + +#: ../../po/../src/verbs.cpp:1916 +msgid "Invert selection in all visible and unlocked layers" +msgstr "" + +#: ../../po/../src/verbs.cpp:1917 +#, fuzzy +msgid "D_eselect" +msgstr "Seç" + +#: ../../po/../src/verbs.cpp:1918 +#, fuzzy +msgid "Deselect any selected objects or nodes" +msgstr "Seçili nesneleri sil" + +#. Selection +#: ../../po/../src/verbs.cpp:1921 +#, fuzzy +msgid "Raise to _Top" +msgstr "Seçileni öne getir" + +#: ../../po/../src/verbs.cpp:1922 +msgid "Raise selection to top" +msgstr "Seçileni öne getir" + +#: ../../po/../src/verbs.cpp:1923 +#, fuzzy +msgid "Lower to _Bottom" +msgstr "seçili nesneleri arkaya it" + +#: ../../po/../src/verbs.cpp:1924 +#, fuzzy +msgid "Lower selection to bottom" +msgstr "seçili nesneleri arkaya it" + +#: ../../po/../src/verbs.cpp:1925 +#, fuzzy +msgid "_Raise" +msgstr "Büyüt" + +#: ../../po/../src/verbs.cpp:1926 +#, fuzzy +msgid "Raise selection one step" +msgstr "Seçileni öne getir" + +#: ../../po/../src/verbs.cpp:1927 +#, fuzzy +msgid "_Lower" +msgstr "Küçült" + +#: ../../po/../src/verbs.cpp:1928 +#, fuzzy +msgid "Lower selection one step" +msgstr "Seçileni bir katman alçalt" + +#: ../../po/../src/verbs.cpp:1929 +#, fuzzy +msgid "_Group" +msgstr "_Grup" + +#: ../../po/../src/verbs.cpp:1930 +msgid "Group selected objects" +msgstr "Seçili nesneleri grupla" + +#: ../../po/../src/verbs.cpp:1932 +#, fuzzy +msgid "Ungroup selected groups" +msgstr "Seçili grupların gruplandırmasını kaldır" + +#: ../../po/../src/verbs.cpp:1934 +#, fuzzy +msgid "_Put on Path" +msgstr "Seçili nesneleri eğrilere dönder" + +#: ../../po/../src/verbs.cpp:1935 +#, fuzzy +msgid "Put text on path" +msgstr "Seçili nesneleri eğrilere dönder" + +#: ../../po/../src/verbs.cpp:1936 +#, fuzzy +msgid "_Remove from Path" +msgstr "Dönüştürmeyi kaldır" + +#: ../../po/../src/verbs.cpp:1937 +#, fuzzy +msgid "Remove text from path" +msgstr "Seçili nesneleri eğrilere dönder" + +#: ../../po/../src/verbs.cpp:1938 +msgid "Remove Manual _Kerns" +msgstr "" + +#. TRANSLATORS: "glyph": An image used in the visual representation of characters; +#. roughly speaking, how a character looks. A font is a set of glyphs. +#: ../../po/../src/verbs.cpp:1941 +#, fuzzy +msgid "Remove all manual kerns and glyph rotations from a text object" +msgstr "Dönüşümleri kaldır" + +#: ../../po/../src/verbs.cpp:1943 +#, fuzzy +msgid "_Union" +msgstr "yok" + +#: ../../po/../src/verbs.cpp:1944 +#, fuzzy +msgid "Union of selected objects" +msgstr "Seçili nesneleri çöz" + +#: ../../po/../src/verbs.cpp:1945 +#, fuzzy +msgid "_Intersection" +msgstr "_Interaktif" + +#: ../../po/../src/verbs.cpp:1946 +#, fuzzy +msgid "Intersection of selected objects" +msgstr "Seçili nesneleri sil" + +#: ../../po/../src/verbs.cpp:1947 +#, fuzzy +msgid "_Difference" +msgstr "derece" + +#: ../../po/../src/verbs.cpp:1948 +#, fuzzy +msgid "Difference of selected objects (bottom minus top)" +msgstr "Seçili nesneleri sil" + +#: ../../po/../src/verbs.cpp:1949 +#, fuzzy +msgid "E_xclusion" +msgstr "Genişletme" + +#: ../../po/../src/verbs.cpp:1950 +#, fuzzy +msgid "Exclusive OR of selected objects" +msgstr "Seçili nesnelerin yerleşimini değiştir" + +#: ../../po/../src/verbs.cpp:1951 +#, fuzzy +msgid "Di_vision" +msgstr "Boyut" + +#: ../../po/../src/verbs.cpp:1952 +msgid "Cut the bottom object into pieces" +msgstr "" + +#. TRANSLATORS: "to cut a path" is not the same as "to break a path apart" - see the +#. Advanced tutorial for more info +#: ../../po/../src/verbs.cpp:1955 +#, fuzzy +msgid "Cut _Path" +msgstr "Seçili yolları birleştir" + +#: ../../po/../src/verbs.cpp:1956 +msgid "Cut the bottom object's stroke into pieces, removing fill" +msgstr "" + +#. TRANSLATORS: "outset": expand a shape by offsetting the object's path, +#. i.e. by displacing it perpendicular to the path in each point. +#. See also the Advanced Tutorial for explanation. +#: ../../po/../src/verbs.cpp:1960 +#, fuzzy +msgid "Outs_et" +msgstr "Seçili yolları birleştir" + +#: ../../po/../src/verbs.cpp:1961 +#, fuzzy +msgid "Outset selected paths" +msgstr "Seçili yolları birleştir" + +#: ../../po/../src/verbs.cpp:1963 +#, fuzzy +msgid "O_utset Path by 1 px" +msgstr "Seçili yolları birleştir" + +#: ../../po/../src/verbs.cpp:1964 +#, fuzzy +msgid "Outset selected paths by 1 px" +msgstr "Seçili yolları birleştir" + +#: ../../po/../src/verbs.cpp:1966 +#, fuzzy +msgid "O_utset Path by 10 px" +msgstr "Seçili yolları birleştir" + +#: ../../po/../src/verbs.cpp:1967 +#, fuzzy +msgid "Outset selected paths by 10 px" +msgstr "Seçili yolları birleştir" + +#. TRANSLATORS: "inset": contract a shape by offsetting the object's path, +#. i.e. by displacing it perpendicular to the path in each point. +#. See also the Advanced Tutorial for explanation. +#: ../../po/../src/verbs.cpp:1971 +msgid "I_nset" +msgstr "" + +#: ../../po/../src/verbs.cpp:1972 +#, fuzzy +msgid "Inset selected paths" +msgstr "Seçili yolları birleştir" + +#: ../../po/../src/verbs.cpp:1974 +#, fuzzy +msgid "I_nset Path by 1 px" +msgstr "Seçili yolları birleştir" + +#: ../../po/../src/verbs.cpp:1975 +#, fuzzy +msgid "Inset selected paths by 1 px" +msgstr "Seçili yolları birleştir" + +#: ../../po/../src/verbs.cpp:1977 +#, fuzzy +msgid "I_nset Path by 10 px" +msgstr "Seçili yolları birleştir" + +#: ../../po/../src/verbs.cpp:1978 +#, fuzzy +msgid "Inset selected paths by 10 px" +msgstr "Seçili yolları birleştir" + +#: ../../po/../src/verbs.cpp:1980 +msgid "D_ynamic Offset" +msgstr "" + +#: ../../po/../src/verbs.cpp:1980 +#, fuzzy +msgid "Create a dynamic offset object" +msgstr "MEtin aracı - düzenlenebilir metin nesneleri yaratır" + +#: ../../po/../src/verbs.cpp:1982 +msgid "_Linked Offset" +msgstr "" + +#: ../../po/../src/verbs.cpp:1983 +msgid "Create a dynamic offset object linked to the original path" +msgstr "" + +#: ../../po/../src/verbs.cpp:1985 +#, fuzzy +msgid "_Stroke to Path" +msgstr "Resme vuruş" + +#: ../../po/../src/verbs.cpp:1986 +#, fuzzy +msgid "Convert selected strokes to paths" +msgstr "Seçili nesneleri eğrilere dönder" + +#: ../../po/../src/verbs.cpp:1987 +#, fuzzy +msgid "Si_mplify" +msgstr "Seçili yolları birleştir" + +#: ../../po/../src/verbs.cpp:1988 +#, fuzzy +msgid "Simplify selected paths by removing extra nodes" +msgstr "Seçili yolları birleştir" + +#: ../../po/../src/verbs.cpp:1989 +#, fuzzy +msgid "_Reverse" +msgstr "Dosya" + +#: ../../po/../src/verbs.cpp:1990 +#, fuzzy +msgid "Reverses the direction of selected paths; useful for flipping markers" +msgstr "Seçili nesneleri sil" + +#. TRANSLATORS: "to trace" means "to convert a bitmap to vector graphics" (to vectorize) +#: ../../po/../src/verbs.cpp:1992 +#, fuzzy +msgid "_Trace Bitmap" +msgstr "Bozuk resim" + +#: ../../po/../src/verbs.cpp:1993 +#, fuzzy +msgid "Convert bitmap object to paths" +msgstr "Seçili nesneleri eğrilere dönder" + +#: ../../po/../src/verbs.cpp:1994 +#, fuzzy +msgid "_Make a Bitmap Copy" +msgstr "Bozuk resim" + +#: ../../po/../src/verbs.cpp:1995 +#, fuzzy +msgid "Export selection to a bitmap and insert it into document" +msgstr "Bitmap veya SVG dosyasını döküman içine aktar" + +#: ../../po/../src/verbs.cpp:1996 +msgid "_Combine" +msgstr "_Birleştir" + +#: ../../po/../src/verbs.cpp:1997 +msgid "Combine several paths into one" +msgstr "" + +#. TRANSLATORS: "to cut a path" is not the same as "to break a path apart" - see the +#. Advanced tutorial for more info +#: ../../po/../src/verbs.cpp:2000 +#, fuzzy +msgid "Break _Apart" +msgstr "_Kopar" + +#: ../../po/../src/verbs.cpp:2001 +#, fuzzy +msgid "Break selected paths into subpaths" +msgstr "Seçilen konumu alt konumlara böl" + +#: ../../po/../src/verbs.cpp:2002 +#, fuzzy +msgid "Gri_d Arrange..." +msgstr "_Ayarla" + +#: ../../po/../src/verbs.cpp:2003 +msgid "Arrange selection in grid pattern" +msgstr "" + +#. Layer +#: ../../po/../src/verbs.cpp:2005 +#, fuzzy +msgid "_Add Layer..." +msgstr "Küçült" + +#: ../../po/../src/verbs.cpp:2006 +#, fuzzy +msgid "Create a new layer" +msgstr "Yeni bir SVG dökümanı oluştur" + +#: ../../po/../src/verbs.cpp:2007 +#, fuzzy +msgid "Re_name Layer..." +msgstr "Düğümü büyüt" + +#: ../../po/../src/verbs.cpp:2008 +#, fuzzy +msgid "Rename the current layer" +msgstr "Seç" + +#: ../../po/../src/verbs.cpp:2009 +#, fuzzy +msgid "Switch to Layer Abov_e" +msgstr "Seçileni bir katman yükselt" + +#: ../../po/../src/verbs.cpp:2010 +msgid "Switch to the layer above the current" +msgstr "" + +#: ../../po/../src/verbs.cpp:2011 +#, fuzzy +msgid "Switch to Layer Belo_w" +msgstr "Seçileni bir katman yükselt" + +#: ../../po/../src/verbs.cpp:2012 +msgid "Switch to the layer below the current" +msgstr "" + +#: ../../po/../src/verbs.cpp:2013 +#, fuzzy +msgid "Move Selection to Layer Abo_ve" +msgstr "Seçileni bir katman yükselt" + +#: ../../po/../src/verbs.cpp:2014 +msgid "Move selection to the layer above the current" +msgstr "" + +#: ../../po/../src/verbs.cpp:2015 +#, fuzzy +msgid "Move Selection to Layer Bel_ow" +msgstr "Seçileni bir katman yükselt" + +#: ../../po/../src/verbs.cpp:2016 +msgid "Move selection to the layer below the current" +msgstr "" + +#: ../../po/../src/verbs.cpp:2017 +#, fuzzy +msgid "Layer to _Top" +msgstr "Seçileni öne getir" + +#: ../../po/../src/verbs.cpp:2018 +#, fuzzy +msgid "Raise the current layer to the top" +msgstr "Seçileni öne getir" + +#: ../../po/../src/verbs.cpp:2019 +#, fuzzy +msgid "Layer to _Bottom" +msgstr "seçili nesneleri arkaya it" + +#: ../../po/../src/verbs.cpp:2020 +#, fuzzy +msgid "Lower the current layer to the bottom" +msgstr "seçili nesneleri arkaya it" + +#: ../../po/../src/verbs.cpp:2021 +#, fuzzy +msgid "_Raise Layer" +msgstr "Düğümü büyüt" + +#: ../../po/../src/verbs.cpp:2022 +msgid "Raise the current layer" +msgstr "" + +#: ../../po/../src/verbs.cpp:2023 +#, fuzzy +msgid "_Lower Layer" +msgstr "Düğümü küçült" + +#: ../../po/../src/verbs.cpp:2024 +msgid "Lower the current layer" +msgstr "" + +#: ../../po/../src/verbs.cpp:2025 +#, fuzzy +msgid "_Delete Current Layer" +msgstr "Seç" + +#: ../../po/../src/verbs.cpp:2026 +#, fuzzy +msgid "Delete the current layer" +msgstr "Seç" + +#. Object +#: ../../po/../src/verbs.cpp:2029 +#, fuzzy +msgid "Rotate _90° CW" +msgstr "Sayfa genişliğini ayarla" + +#: ../../po/../src/verbs.cpp:2030 +#, fuzzy +msgid "Rotate selection 90° clockwise" +msgstr "Seçili nesneleri saat yönünde 90 derece dönder" + +#: ../../po/../src/verbs.cpp:2031 +#, fuzzy +msgid "Rotate 9_0° CCW" +msgstr "Sayfa genişliğini ayarla" + +#: ../../po/../src/verbs.cpp:2032 +#, fuzzy +msgid "Rotate selection 90° counter-clockwise" +msgstr "Seçili nesneleri saat yönünde 90 derece dönder" + +#: ../../po/../src/verbs.cpp:2033 +#, fuzzy +msgid "Remove _Transformations" +msgstr "Dönüştürmeyi kaldır" + +#: ../../po/../src/verbs.cpp:2034 +#, fuzzy +msgid "Remove transformations from object" +msgstr "Dönüşümleri kaldır" + +#: ../../po/../src/verbs.cpp:2035 +#, fuzzy +msgid "_Object to Path" +msgstr "Nesne dönüşümü" + +#: ../../po/../src/verbs.cpp:2036 +#, fuzzy +msgid "Convert selected objects to paths" +msgstr "Seçili nesneleri eğrilere dönder" + +#: ../../po/../src/verbs.cpp:2037 +msgid "_Flow into Frame" +msgstr "" + +#: ../../po/../src/verbs.cpp:2038 +#, fuzzy +msgid "Put text into frames" +msgstr "Seçili nesneleri eğrilere dönder" + +#: ../../po/../src/verbs.cpp:2039 +#, fuzzy +msgid "_Unflow" +msgstr "Geri Al" + +#: ../../po/../src/verbs.cpp:2040 +msgid "Remove text from frame (creates a single-line text object)" +msgstr "" + +#: ../../po/../src/verbs.cpp:2041 +#, fuzzy +msgid "_Convert to Text" +msgstr "Seçili nesneleri eğrilere dönder" + +#: ../../po/../src/verbs.cpp:2042 +#, fuzzy +msgid "Convert flowed text to regular text objects (preserves appearance)" +msgstr "Seçili bölümleri çizgilere dönüştür" + +#: ../../po/../src/verbs.cpp:2044 +#, fuzzy +msgid "Flip _Horizontal" +msgstr "yatay" + +#: ../../po/../src/verbs.cpp:2044 +#, fuzzy +msgid "Flips selected objects horizontally" +msgstr "Seçili nesneleri yatay çevir" + +#: ../../po/../src/verbs.cpp:2047 +#, fuzzy +msgid "Flip _Vertical" +msgstr "dikey" + +#: ../../po/../src/verbs.cpp:2047 +#, fuzzy +msgid "Flips selected objects vertically" +msgstr "Seçili nesneleri dikey çevir" + +#. Tools +#: ../../po/../src/verbs.cpp:2051 +msgid "Select" +msgstr "Seç" + +#: ../../po/../src/verbs.cpp:2052 +#, fuzzy +msgid "Select and transform objects" +msgstr "Nesne ve grupları seç ve değiştir" + +#: ../../po/../src/verbs.cpp:2053 +#, fuzzy +msgid "Node Edit" +msgstr "Noktayı Değiştir" + +#: ../../po/../src/verbs.cpp:2054 +#, fuzzy +msgid "Edit path nodes or control handles" +msgstr "Seçili nesnelerin yerleşimini değiştir" + +#: ../../po/../src/verbs.cpp:2056 +#, fuzzy +msgid "Create rectangles and squares" +msgstr "" +"Dörtgen aracı - Köşeleri belirtilen yuvarlıkta dörtgenler ve kareler yaratır" + +#: ../../po/../src/verbs.cpp:2058 +#, fuzzy +msgid "Create circles, ellipses, and arcs" +msgstr "Eğri aracı - daireler, elipsler ve eğriler yaratır" + +#: ../../po/../src/verbs.cpp:2060 +#, fuzzy +msgid "Create stars and polygons" +msgstr "Yıldız aracı - yıldızlar ve poligonlar yaratır" + +#: ../../po/../src/verbs.cpp:2062 +#, fuzzy +msgid "Create spirals" +msgstr "Dörtgen çiz" + +#: ../../po/../src/verbs.cpp:2064 +#, fuzzy +msgid "Draw freehand lines" +msgstr "Serbest şekiller çiz" + +#: ../../po/../src/verbs.cpp:2066 +#, fuzzy +msgid "Draw Bezier curves and straight lines" +msgstr "Kalem aracı - düz ve serbest çizgiler çizer" + +#: ../../po/../src/verbs.cpp:2068 +#, fuzzy +msgid "Draw calligraphic lines" +msgstr "Karalama çizgisi" + +#: ../../po/../src/verbs.cpp:2070 +#, fuzzy +msgid "Create and edit text objects" +msgstr "MEtin aracı - düzenlenebilir metin nesneleri yaratır" + +#: ../../po/../src/verbs.cpp:2072 +#, fuzzy +msgid "Create and edit gradients" +msgstr "MEtin aracı - düzenlenebilir metin nesneleri yaratır" + +#: ../../po/../src/verbs.cpp:2074 +#, fuzzy +msgid "Zoom in or out" +msgstr "Küçült" + +#: ../../po/../src/verbs.cpp:2076 +msgid "Pick averaged colors from image" +msgstr "" + +#: ../../po/../src/verbs.cpp:2078 +#, fuzzy +msgid "Create connectors" +msgstr "Yeni bir SVG dökümanı oluştur" + +#. Tool prefs +#: ../../po/../src/verbs.cpp:2081 +msgid "Selector Preferences" +msgstr "" + +#: ../../po/../src/verbs.cpp:2082 +#, fuzzy +msgid "Open Preferences for the Selector tool" +msgstr "Sodipodi: %s : XML Görünümü" + +#: ../../po/../src/verbs.cpp:2083 +#, fuzzy +msgid "Node Tool Preferences" +msgstr "Eksik araç ayarları" + +#: ../../po/../src/verbs.cpp:2084 +#, fuzzy +msgid "Open Preferences for the Node tool" +msgstr "Sodipodi: %s : XML Görünümü" + +#: ../../po/../src/verbs.cpp:2085 +#, fuzzy +msgid "Rectangle Preferences" +msgstr "Dörtgen Özellikleri" + +#: ../../po/../src/verbs.cpp:2086 +#, fuzzy +msgid "Open Preferences for the Rectangle tool" +msgstr "Sodipodi: %s : XML Görünümü" + +#: ../../po/../src/verbs.cpp:2087 +#, fuzzy +msgid "Ellipse Preferences" +msgstr "Nesne referans" + +#: ../../po/../src/verbs.cpp:2088 +#, fuzzy +msgid "Open Preferences for the Ellipse tool" +msgstr "Sodipodi: %s : XML Görünümü" + +#: ../../po/../src/verbs.cpp:2089 +#, fuzzy +msgid "Star Preferences" +msgstr "Yıldız Ayarları" + +#: ../../po/../src/verbs.cpp:2090 +#, fuzzy +msgid "Open Preferences for the Star tool" +msgstr "Sodipodi: %s : XML Görünümü" + +#: ../../po/../src/verbs.cpp:2091 +#, fuzzy +msgid "Spiral Preferences" +msgstr "Spiral Özellikleri" + +#: ../../po/../src/verbs.cpp:2092 +#, fuzzy +msgid "Open Preferences for the Spiral tool" +msgstr "Sodipodi: %s : XML Görünümü" + +#: ../../po/../src/verbs.cpp:2093 +#, fuzzy +msgid "Pencil Preferences" +msgstr "Nesne referans" + +#: ../../po/../src/verbs.cpp:2094 +#, fuzzy +msgid "Open Preferences for the Pencil tool" +msgstr "Sodipodi: %s : XML Görünümü" + +#: ../../po/../src/verbs.cpp:2095 +#, fuzzy +msgid "Pen Preferences" +msgstr "Nesne referans" + +#: ../../po/../src/verbs.cpp:2096 +#, fuzzy +msgid "Open Preferences for the Pen tool" +msgstr "Sodipodi: %s : XML Görünümü" + +#: ../../po/../src/verbs.cpp:2097 +#, fuzzy +msgid "Calligraphic Preferences" +msgstr "Karalama çizgisi" + +#: ../../po/../src/verbs.cpp:2098 +#, fuzzy +msgid "Open Preferences for the Calligraphy tool" +msgstr "Sodipodi: %s : XML Görünümü" + +#: ../../po/../src/verbs.cpp:2099 +#, fuzzy +msgid "Text Preferences" +msgstr "Nesne referans" + +#: ../../po/../src/verbs.cpp:2100 +#, fuzzy +msgid "Open Preferences for the Text tool" +msgstr "Sodipodi: %s : XML Görünümü" + +#: ../../po/../src/verbs.cpp:2101 +#, fuzzy +msgid "Gradient Preferences" +msgstr "Nesne referans" + +#: ../../po/../src/verbs.cpp:2102 +#, fuzzy +msgid "Open Preferences for the Gradient tool" +msgstr "Sodipodi: %s : XML Görünümü" + +#: ../../po/../src/verbs.cpp:2103 +#, fuzzy +msgid "Zoom Preferences" +msgstr "Nesne referans" + +#: ../../po/../src/verbs.cpp:2104 +#, fuzzy +msgid "Open Preferences for the Zoom tool" +msgstr "Sodipodi: %s : XML Görünümü" + +#: ../../po/../src/verbs.cpp:2105 +#, fuzzy +msgid "Dropper Preferences" +msgstr "Sodipodi: %s : XML Görünümü" + +#: ../../po/../src/verbs.cpp:2106 +#, fuzzy +msgid "Open Preferences for the Dropper tool" +msgstr "Sodipodi: %s : XML Görünümü" + +#: ../../po/../src/verbs.cpp:2107 +#, fuzzy +msgid "Connector Preferences" +msgstr "Yıldız Ayarları" + +#: ../../po/../src/verbs.cpp:2108 +#, fuzzy +msgid "Open Preferences for the Connector tool" +msgstr "Sodipodi: %s : XML Görünümü" + +#. Zoom/View +#: ../../po/../src/verbs.cpp:2111 +#, fuzzy +msgid "Zoom In" +msgstr "Büyült" + +#: ../../po/../src/verbs.cpp:2111 +msgid "Zoom in" +msgstr "Büyült" + +#: ../../po/../src/verbs.cpp:2112 +#, fuzzy +msgid "Zoom Out" +msgstr "Küçült" + +#: ../../po/../src/verbs.cpp:2112 +msgid "Zoom out" +msgstr "Küçült" + +#: ../../po/../src/verbs.cpp:2113 +#, fuzzy +msgid "_Rulers" +msgstr "Dosya" + +#: ../../po/../src/verbs.cpp:2113 +#, fuzzy +msgid "Show or hide the canvas rulers" +msgstr "Rehberleri göster" + +#: ../../po/../src/verbs.cpp:2114 +msgid "Scroll_bars" +msgstr "" + +#: ../../po/../src/verbs.cpp:2114 +#, fuzzy +msgid "Show or hide the canvas scrollbars" +msgstr "Rehberleri göster" + +#: ../../po/../src/verbs.cpp:2115 +#, fuzzy +msgid "_Grid" +msgstr "Izgara" + +#: ../../po/../src/verbs.cpp:2116 +#, fuzzy +msgid "G_uides" +msgstr "Rehberler" + +#: ../../po/../src/verbs.cpp:2117 +msgid "Nex_t Zoom" +msgstr "" + +#: ../../po/../src/verbs.cpp:2117 +msgid "Next zoom (from the history of zooms)" +msgstr "" + +#: ../../po/../src/verbs.cpp:2119 +msgid "Pre_vious Zoom" +msgstr "" + +#: ../../po/../src/verbs.cpp:2119 +msgid "Previous zoom (from the history of zooms)" +msgstr "" + +#: ../../po/../src/verbs.cpp:2121 +#, fuzzy +msgid "Zoom 1:_1" +msgstr "1:1 göster" + +#: ../../po/../src/verbs.cpp:2121 +msgid "Zoom to 1:1" +msgstr "1:1 göster" + +#: ../../po/../src/verbs.cpp:2123 +#, fuzzy +msgid "Zoom 1:_2" +msgstr "1:1 göster" + +#: ../../po/../src/verbs.cpp:2123 +#, fuzzy +msgid "Zoom to 1:2" +msgstr "1:1 göster" + +#: ../../po/../src/verbs.cpp:2125 +#, fuzzy +msgid "_Zoom 2:1" +msgstr "1:1 göster" + +#: ../../po/../src/verbs.cpp:2125 +#, fuzzy +msgid "Zoom to 2:1" +msgstr "1:1 göster" + +#: ../../po/../src/verbs.cpp:2128 +msgid "_Fullscreen" +msgstr "" + +#: ../../po/../src/verbs.cpp:2128 +msgid "Stretch this document window to full screen" +msgstr "" + +#: ../../po/../src/verbs.cpp:2131 +#, fuzzy +msgid "Duplic_ate Window" +msgstr "Düğümü çiftle" + +#: ../../po/../src/verbs.cpp:2131 +#, fuzzy +msgid "Open a new window with the same document" +msgstr "SVG dökümanı aç" + +#: ../../po/../src/verbs.cpp:2133 +#, fuzzy +msgid "_New View Preview" +msgstr "Yeni Önizleme" + +#: ../../po/../src/verbs.cpp:2134 +#, fuzzy +msgid "New View Preview" +msgstr "Yeni Önizleme" + +#. "view_new_preview" +#: ../../po/../src/verbs.cpp:2136 +#, fuzzy +msgid "_Normal" +msgstr "Fraktal" + +#: ../../po/../src/verbs.cpp:2137 +msgid "Switch to normal display mode" +msgstr "" + +#: ../../po/../src/verbs.cpp:2138 +#, fuzzy +msgid "_Outline" +msgstr "Taslağı göster" + +#: ../../po/../src/verbs.cpp:2139 +msgid "Switch to outline (wireframe) display mode" +msgstr "" + +#: ../../po/../src/verbs.cpp:2141 +#, fuzzy +msgid "Ico_n Preview" +msgstr "Yeni Önizleme" + +#: ../../po/../src/verbs.cpp:2142 +msgid "Open a window to preview items at different icon resolutions" +msgstr "" + +#: ../../po/../src/verbs.cpp:2144 +#, fuzzy +msgid "Zoom to fit page in window" +msgstr "Tüm sayfayı pencereye uydur" + +#: ../../po/../src/verbs.cpp:2145 +#, fuzzy +msgid "Page _Width" +msgstr "Sayfa genişliğini ayarla" + +#: ../../po/../src/verbs.cpp:2146 +#, fuzzy +msgid "Zoom to fit page width in window" +msgstr "Tüm sayfayı pencereye uydur" + +#: ../../po/../src/verbs.cpp:2148 +#, fuzzy +msgid "Zoom to fit drawing in window" +msgstr "Çizimi pencereye uydur" + +#: ../../po/../src/verbs.cpp:2150 +#, fuzzy +msgid "Zoom to fit selection in window" +msgstr "Seçimi pencereye uydur" + +#. Dialogs +#: ../../po/../src/verbs.cpp:2153 +#, fuzzy +msgid "In_kscape Preferences..." +msgstr "Sodipodi: %s : XML Görünümü" + +#: ../../po/../src/verbs.cpp:2154 +#, fuzzy +msgid "Global Inkscape preferences" +msgstr "Görüntü ayarları" + +#: ../../po/../src/verbs.cpp:2155 +msgid "_Document Preferences..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2156 +#, fuzzy +msgid "Preferences saved with the document" +msgstr "SVG dökümanı aç" + +#: ../../po/../src/verbs.cpp:2157 +#, fuzzy +msgid "_Fill and Stroke..." +msgstr "Doldur ve Vur" + +#: ../../po/../src/verbs.cpp:2158 +#, fuzzy +msgid "Fill and Stroke dialog" +msgstr "Doldur ve Vur" + +#. TRANSLATORS: "Swatches" means: color samples +#: ../../po/../src/verbs.cpp:2160 +#, fuzzy +msgid "S_watches..." +msgstr "Farklı kaydet" + +#: ../../po/../src/verbs.cpp:2161 +msgid "View color swatches" +msgstr "" + +#: ../../po/../src/verbs.cpp:2162 +#, fuzzy +msgid "Transfor_m..." +msgstr "Dönüşüm:" + +#: ../../po/../src/verbs.cpp:2163 +#, fuzzy +msgid "Transform dialog" +msgstr "Dönüştürme diyalogu" + +#: ../../po/../src/verbs.cpp:2164 +#, fuzzy +msgid "_Align and Distribute..." +msgstr "Özellik" + +#: ../../po/../src/verbs.cpp:2165 +#, fuzzy +msgid "Align and Distribute dialog" +msgstr "Özellik" + +#: ../../po/../src/verbs.cpp:2166 +#, fuzzy +msgid "_Text and Font..." +msgstr "Metin ve yazı tipi" + +#: ../../po/../src/verbs.cpp:2167 +#, fuzzy +msgid "Text and Font dialog" +msgstr "Metin ve yazı tipi" + +#: ../../po/../src/verbs.cpp:2168 +#, fuzzy +msgid "_XML Editor..." +msgstr "XML Düzenleyicisi" + +#: ../../po/../src/verbs.cpp:2169 +msgid "XML Editor" +msgstr "XML Düzenleyicisi" + +#: ../../po/../src/verbs.cpp:2170 +#, fuzzy +msgid "_Find..." +msgstr "Yazdır" + +#: ../../po/../src/verbs.cpp:2171 +#, fuzzy +msgid "Find objects in document" +msgstr "Dökümanda geçiş yok" + +#: ../../po/../src/verbs.cpp:2172 +msgid "_Messages..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2173 +msgid "View debug messages" +msgstr "" + +#: ../../po/../src/verbs.cpp:2174 +#, fuzzy +msgid "S_cripts..." +msgstr "Yazdır" + +#: ../../po/../src/verbs.cpp:2175 +#, fuzzy +msgid "Run scripts" +msgstr "2 seçili bitiş noktasını birleştir" + +#: ../../po/../src/verbs.cpp:2176 +#, fuzzy +msgid "Show/Hide D_ialogs" +msgstr "Diyalogu kapat" + +#: ../../po/../src/verbs.cpp:2177 +msgid "Show or hide all active dialogs" +msgstr "" + +#. TRANSLATORS: "Tile clones" means: "Create tiled clones" +#: ../../po/../src/verbs.cpp:2179 +msgid "Tile clones..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2180 +msgid "Create and arrange multiple clones of selection" +msgstr "" + +#: ../../po/../src/verbs.cpp:2181 +#, fuzzy +msgid "_Object Properties..." +msgstr "nesne özellikleri" + +#: ../../po/../src/verbs.cpp:2182 +#, fuzzy +msgid "Object Properties dialog" +msgstr "nesne özellikleri" + +#: ../../po/../src/verbs.cpp:2185 +msgid "_Connect to Jabber server..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2185 +msgid "Connect to a Jabber server" +msgstr "" + +#: ../../po/../src/verbs.cpp:2187 +#, fuzzy +msgid "Share with _user..." +msgstr "Farklı kaydet" + +#: ../../po/../src/verbs.cpp:2187 +msgid "Establish a whiteboard session with another Jabber user" +msgstr "" + +#: ../../po/../src/verbs.cpp:2189 +msgid "Share with _chatroom..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2189 +msgid "" +"Join a chatroom to start a new whiteboard session or join one in progress" +msgstr "" + +#: ../../po/../src/verbs.cpp:2191 +msgid "_Dump XML node tracker" +msgstr "" + +#: ../../po/../src/verbs.cpp:2191 +msgid "Dump the contents of the XML tracker to the console" +msgstr "" + +#: ../../po/../src/verbs.cpp:2193 +msgid "_Open session file..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2193 +msgid "Open and browse through records of past whiteboard sessions" +msgstr "" + +#: ../../po/../src/verbs.cpp:2195 +msgid "Session file playback" +msgstr "" + +#: ../../po/../src/verbs.cpp:2197 +msgid "_Disconnect from session" +msgstr "" + +#: ../../po/../src/verbs.cpp:2199 +msgid "Disconnect from _server" +msgstr "" + +#: ../../po/../src/verbs.cpp:2201 +msgid "_Input Devices..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2202 +msgid "Configure extended input devices" +msgstr "" + +#. Help +#: ../../po/../src/verbs.cpp:2205 +msgid "_Keys and Mouse" +msgstr "" + +#: ../../po/../src/verbs.cpp:2206 +msgid "Key and mouse shortcuts reference" +msgstr "" + +#: ../../po/../src/verbs.cpp:2207 +#, fuzzy +msgid "About E_xtensions" +msgstr "Genişletme" + +#: ../../po/../src/verbs.cpp:2208 +#, fuzzy +msgid "About Extensions..." +msgstr "Genişletme" + +#: ../../po/../src/verbs.cpp:2209 +#, fuzzy +msgid "About _Memory" +msgstr "Genişletme" + +#: ../../po/../src/verbs.cpp:2210 +#, fuzzy +msgid "About Memory..." +msgstr "Hakkında ..." + +#: ../../po/../src/verbs.cpp:2211 +msgid "_About Inkscape" +msgstr "" + +#. "help_about" +#. new HelpVerb(SP_VERB_SHOW_LICENSE, "ShowLicense", N_("Modifying or Redistributing Inkscape"), +#. N_("Show license to modify and/or redistribute Inkscape: GNU GPL"), NULL), +#. Tutorials +#: ../../po/../src/verbs.cpp:2217 +#, fuzzy +msgid "Inkscape: _Basic" +msgstr "Sodipodi: %s : XML Görünümü" + +#: ../../po/../src/verbs.cpp:2218 +msgid "Getting started with Inkscape" +msgstr "" + +#. "tutorial_basic" +#: ../../po/../src/verbs.cpp:2219 +#, fuzzy +msgid "Inkscape: _Shapes" +msgstr "Sodipodi: %s : XML Görünümü" + +#: ../../po/../src/verbs.cpp:2220 +msgid "Using shape tools to create and edit shapes" +msgstr "" + +#: ../../po/../src/verbs.cpp:2221 +#, fuzzy +msgid "Inkscape: _Advanced" +msgstr "Sodipodi: %s : XML Görünümü" + +#: ../../po/../src/verbs.cpp:2222 +#, fuzzy +msgid "Advanced Inkscape topics" +msgstr "Sodipodi: %s : XML Görünümü" + +#. "tutorial_advanced" +#. TRANSLATORS: "to trace" means "to convert a bitmap to vector graphics" (to vectorize) +#: ../../po/../src/verbs.cpp:2224 +#, fuzzy +msgid "Inkscape: T_racing" +msgstr "Sodipodi: %s : XML Görünümü" + +#: ../../po/../src/verbs.cpp:2225 +#, fuzzy +msgid "Using bitmap tracing" +msgstr "Bitmap boyutu" + +#. "tutorial_tracing" +#: ../../po/../src/verbs.cpp:2226 +#, fuzzy +msgid "Inkscape: _Calligraphy" +msgstr "Sodipodi: %s : XML Görünümü" + +#: ../../po/../src/verbs.cpp:2227 +msgid "Using the Calligraphy pen tool" +msgstr "" + +#: ../../po/../src/verbs.cpp:2228 +msgid "_Elements of Design" +msgstr "" + +#: ../../po/../src/verbs.cpp:2229 +msgid "Principles of design in the tutorial form" +msgstr "" + +#. "tutorial_design" +#: ../../po/../src/verbs.cpp:2230 +msgid "_Tips and Tricks" +msgstr "" + +#: ../../po/../src/verbs.cpp:2231 +msgid "Miscellaneous tips and tricks" +msgstr "" + +#. "tutorial_tips" +#. Effect +#: ../../po/../src/verbs.cpp:2234 +msgid "Previous Effect" +msgstr "" + +#: ../../po/../src/verbs.cpp:2235 +msgid "Repeat the last effect with the same settings" +msgstr "" + +#. "tutorial_tips" +#: ../../po/../src/verbs.cpp:2236 +msgid "Previous Effect Settings..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2237 +msgid "Repeat the last effect with new settings" +msgstr "" + +#: ../../po/../src/widgets/dash-selector.cpp:106 +#, fuzzy +msgid "Dash pattern" +msgstr "Sayfa genişliğini ayarla" + +#: ../../po/../src/widgets/dash-selector.cpp:121 +#, fuzzy +msgid "Pattern offset" +msgstr "Motif" + +#: ../../po/../src/widgets/desktop-widget.cpp:240 +#, fuzzy +msgid "Zoom drawing if window size changes" +msgstr "Çizimi pencereye uydur" + +#: ../../po/../src/widgets/desktop-widget.cpp:298 +msgid "Cursor coordinates" +msgstr "" + +#. display the initial welcome message in the statusbar +#: ../../po/../src/widgets/desktop-widget.cpp:324 +msgid "" +"Welcome to Inkscape! Use shape or freehand tools to create objects; " +"use selector (arrow) to move or transform them." +msgstr "" + +#: ../../po/../src/widgets/desktop-widget.cpp:372 +#, c-format +msgid "%s: %d - Inkscape" +msgstr "" + +#: ../../po/../src/widgets/desktop-widget.cpp:374 +#, c-format +msgid "%s - Inkscape" +msgstr "" + +#: ../../po/../src/widgets/desktop-widget.cpp:532 +#, c-format +msgid "" +"Save changes to document \"%s\" before " +"closing?\n" +"\n" +"If you close without saving, your changes will be discarded." +msgstr "" + +#: ../../po/../src/widgets/desktop-widget.cpp:548 +#: ../../po/../src/widgets/desktop-widget.cpp:612 +msgid "Close _without saving" +msgstr "" + +#: ../../po/../src/widgets/desktop-widget.cpp:595 +#, c-format +msgid "" +"The file \"%s\" was saved with a " +"format (%s) that may cause data loss!\n" +"\n" +"Do you want to save this file in another format?" +msgstr "" + +#. Family frame +#: ../../po/../src/widgets/font-selector.cpp:156 +msgid "Font family" +msgstr "Yazı tipi ailesi" + +#. Style frame +#: ../../po/../src/widgets/font-selector.cpp:184 +msgid "Style" +msgstr "Stil" + +#: ../../po/../src/widgets/font-selector.cpp:219 +msgid "Font size:" +msgstr "Yazı tipi boyutu:" + +#. TRANSLATORS: Test string used in text and font dialog (when no +#. * text has been entered) to get a preview of the font. Choose +#. * some representative characters that users of your locale will be +#. * interested in. +#: ../../po/../src/widgets/font-selector.cpp:554 +msgid "AaBbCcIiPpQq12368.;/()" +msgstr "AaBbCcIiPpQq12368.;/()" + +#: ../../po/../src/widgets/gradient-selector.cpp:137 +#: ../../po/../src/widgets/gradient-toolbar.cpp:524 +#, fuzzy +msgid "Duplicate" +msgstr "Çiftle" + +#: ../../po/../src/widgets/gradient-selector.cpp:142 +#: ../../po/../src/widgets/gradient-toolbar.cpp:535 +#, fuzzy +msgid "Edit..." +msgstr "Değiştir" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/pservers.html#LinearGradientSpreadMethodAttribute +#: ../../po/../src/widgets/gradient-selector.cpp:159 +msgid "" +"Whether to fill with flat color beyond the ends of the gradient vector " +"(spreadMethod=\"pad\"), or repeat the gradient in the same direction " +"(spreadMethod=\"repeat\"), or repeat the gradient in alternating opposite " +"directions (spreadMethod=\"reflect\")" +msgstr "" + +#: ../../po/../src/widgets/gradient-selector.cpp:165 +#, fuzzy +msgid "none" +msgstr "Yok" + +#: ../../po/../src/widgets/gradient-selector.cpp:169 +#, fuzzy +msgid "reflected" +msgstr "Ä°lk seçilen" + +#: ../../po/../src/widgets/gradient-selector.cpp:173 +#, fuzzy +msgid "direct" +msgstr "Dörtgen" + +#: ../../po/../src/widgets/gradient-selector.cpp:181 +#, fuzzy +msgid "Repeat:" +msgstr "Yeniden oku" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:217 +msgid "No gradients" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:226 +#, fuzzy +msgid "Nothing selected" +msgstr "Son seçilen" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:237 +#, fuzzy +msgid "No gradients in selection" +msgstr "Geçiş seçilmedi" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:247 +msgid "Multiple gradients" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:525 +msgid "" +"If the gradient is used by more than one object, create a copy of it for the " +"selected object(s)" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:536 +#, fuzzy +msgid "Edit the stops of the gradient" +msgstr "Çizgisel geçiş" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:593 +#: ../../po/../src/widgets/toolbox.cpp:1103 +#: ../../po/../src/widgets/toolbox.cpp:1192 +#: ../../po/../src/widgets/toolbox.cpp:1485 +#: ../../po/../src/widgets/toolbox.cpp:1534 +#: ../../po/../src/widgets/toolbox.cpp:1766 +#: ../../po/../src/widgets/toolbox.cpp:1801 +#: ../../po/../src/widgets/toolbox.cpp:2331 +#: ../../po/../src/widgets/toolbox.cpp:2370 +msgid "New:" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:606 +#, fuzzy +msgid "Create linear gradient" +msgstr "Çizgisel geçiş" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:620 +msgid "Create radial (elliptic or circular) gradient" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:635 +#, fuzzy +msgid "on" +msgstr "Aşağı" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:648 +#, fuzzy +msgid "Create gradient in the fill" +msgstr "Geçiş vektörü" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:662 +msgid "Create gradient in the stroke" +msgstr "" + +#. FIXME: implement averaging of all parameters for multiple selected stars +#. gtk_label_set_markup(GTK_LABEL(l), _("Average:")); +#. FIXME: implement averaging of all parameters for multiple selected +#. gtk_label_set_markup(GTK_LABEL(l), _("Average:")); +#: ../../po/../src/widgets/gradient-toolbar.cpp:676 +#: ../../po/../src/widgets/toolbox.cpp:1105 +#: ../../po/../src/widgets/toolbox.cpp:1124 +#: ../../po/../src/widgets/toolbox.cpp:1493 +#: ../../po/../src/widgets/toolbox.cpp:1518 +#: ../../po/../src/widgets/toolbox.cpp:1768 +#: ../../po/../src/widgets/toolbox.cpp:1787 +#: ../../po/../src/widgets/toolbox.cpp:2334 +#: ../../po/../src/widgets/toolbox.cpp:2354 +#, fuzzy +msgid "Change:" +msgstr "Değiştir" + +#: ../../po/../src/widgets/gradient-vector.cpp:269 +msgid "No gradients in document" +msgstr "Dökümanda geçiş yok" + +#: ../../po/../src/widgets/gradient-vector.cpp:275 +msgid "No gradient selected" +msgstr "Geçiş seçilmedi" + +#: ../../po/../src/widgets/gradient-vector.cpp:532 +#, fuzzy +msgid "No stops in gradient" +msgstr "Çizgisel geçiş" + +#. TRANSLATORS: "Stop" means: a "phase" of a gradient +#: ../../po/../src/widgets/gradient-vector.cpp:794 +#, fuzzy +msgid "Add stop" +msgstr "Masaüstü" + +#: ../../po/../src/widgets/gradient-vector.cpp:797 +msgid "Add another control stop to gradient" +msgstr "" + +#: ../../po/../src/widgets/gradient-vector.cpp:799 +#, fuzzy +msgid "Delete stop" +msgstr "Seçileni sil" + +#: ../../po/../src/widgets/gradient-vector.cpp:802 +msgid "Delete current control stop from gradient" +msgstr "" + +#. Label +#: ../../po/../src/widgets/gradient-vector.cpp:813 +msgid "Offset:" +msgstr "" + +#. TRANSLATORS: "Stop" means: a "phase" of a gradient +#: ../../po/../src/widgets/gradient-vector.cpp:858 +#, fuzzy +msgid "Stop Color" +msgstr "Başlangıç rengi" + +#: ../../po/../src/widgets/gradient-vector.cpp:887 +#, fuzzy +msgid "Gradient editor" +msgstr "Geçiş vektörü" + +#: ../../po/../src/widgets/layer-selector.cpp:119 +#, fuzzy +msgid "Toggle current layer visibility" +msgstr "Döküman Adı:" + +#: ../../po/../src/widgets/layer-selector.cpp:139 +#, fuzzy +msgid "Lock or unlock current layer" +msgstr "Döküman Adı:" + +#: ../../po/../src/widgets/layer-selector.cpp:142 +#, fuzzy +msgid "Current layer" +msgstr "Döküman Adı:" + +#: ../../po/../src/widgets/layer-selector.cpp:553 +msgid "(root)" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:182 +#: ../../po/../src/widgets/paint-selector.cpp:561 +msgid "No paint" +msgstr "Çizim yok" + +#: ../../po/../src/widgets/paint-selector.cpp:184 +#: ../../po/../src/widgets/paint-selector.cpp:629 +#, fuzzy +msgid "Flat color" +msgstr "renk" + +#: ../../po/../src/widgets/paint-selector.cpp:186 +#: ../../po/../src/widgets/paint-selector.cpp:696 +msgid "Linear gradient" +msgstr "Çizgisel geçiş" + +#: ../../po/../src/widgets/paint-selector.cpp:188 +#: ../../po/../src/widgets/paint-selector.cpp:699 +msgid "Radial gradient" +msgstr "Radyal geçiş" + +#: ../../po/../src/widgets/paint-selector.cpp:192 +msgid "Unset paint (make it undefined so it can be inherited)" +msgstr "" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/painting.html#FillRuleProperty +#: ../../po/../src/widgets/paint-selector.cpp:204 +msgid "" +"Any path self-intersections or subpaths create holes in the fill (fill-rule: " +"evenodd)" +msgstr "" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/painting.html#FillRuleProperty +#: ../../po/../src/widgets/paint-selector.cpp:215 +msgid "" +"Fill is solid unless a subpath is counterdirectional (fill-rule: nonzero)" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:528 +msgid "No objects" +msgstr "Nesne yok" + +#: ../../po/../src/widgets/paint-selector.cpp:539 +msgid "Multiple styles" +msgstr "Çoklu stiller" + +#: ../../po/../src/widgets/paint-selector.cpp:550 +msgid "Paint is undefined" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:757 +#, fuzzy +msgid "No patterns in document" +msgstr "Dökümanda geçiş yok" + +#: ../../po/../src/widgets/paint-selector.cpp:872 +msgid "" +"Use Edit > Object(s) to Pattern to create a new pattern from " +"selection." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:426 +msgid "Now stroke width is scaled when objects are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:428 +msgid "Now stroke width is not scaled when objects are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:436 +msgid "" +"Now rounded rectangle corners are scaled when rectangles are " +"scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:438 +msgid "" +"Now rounded rectangle corners are not scaled when rectangles " +"are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:446 +msgid "" +"Now gradients are transformed along with their objects when " +"those are transformed (moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:448 +msgid "" +"Now gradients remain fixed when objects are transformed " +"(moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:456 +msgid "" +"Now patterns are transformed along with their objects when " +"those are transformed (moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:458 +msgid "" +"Now patterns remain fixed when objects are transformed (moved, " +"scaled, rotated, or skewed)." +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:506 +#, fuzzy +msgid "select_toolbar|X" +msgstr "Seç" + +#: ../../po/../src/widgets/select-toolbar.cpp:506 +msgid "Horizontal coordinate of selection" +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:511 +#, fuzzy +msgid "select_toolbar|Y" +msgstr "Seç" + +#: ../../po/../src/widgets/select-toolbar.cpp:511 +msgid "Vertical coordinate of selection" +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:517 +#, fuzzy +msgid "select_toolbar|W" +msgstr "Seç" + +#: ../../po/../src/widgets/select-toolbar.cpp:517 +#, fuzzy +msgid "Width of selection" +msgstr "Seçileni kes" + +#: ../../po/../src/widgets/select-toolbar.cpp:525 +msgid "Change both width and height by the same proportion" +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:534 +#, fuzzy +msgid "select_toolbar|H" +msgstr "Seç" + +#: ../../po/../src/widgets/select-toolbar.cpp:534 +#, fuzzy +msgid "Height of selection" +msgstr "Seçileni göster" + +#: ../../po/../src/widgets/sp-color-gtkselector.cpp:62 +msgid "System" +msgstr "" + +#: ../../po/../src/widgets/sp-color-notebook.cpp:322 +#, fuzzy +msgid "RGBA_:" +msgstr "RGB" + +#: ../../po/../src/widgets/sp-color-notebook.cpp:330 +msgid "Hexadecimal RGBA value of the color" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "RGB" +msgstr "RGB" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +#, fuzzy +msgid "HSL" +msgstr "HSV" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "CMYK" +msgstr "CMYK" + +#: ../../po/../src/widgets/sp-color-scales.cpp:397 +msgid "_R" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:398 +#: ../../po/../src/widgets/sp-color-scales.cpp:399 +#, fuzzy +msgid "Red" +msgstr "Kırmızı:" + +#: ../../po/../src/widgets/sp-color-scales.cpp:400 +msgid "_G" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:401 +#: ../../po/../src/widgets/sp-color-scales.cpp:402 +#, fuzzy +msgid "Green" +msgstr "Yeşil:" + +#: ../../po/../src/widgets/sp-color-scales.cpp:403 +msgid "_B" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:404 +#: ../../po/../src/widgets/sp-color-scales.cpp:405 +#, fuzzy +msgid "Blue" +msgstr "Mavi:" + +#. Label +#: ../../po/../src/widgets/sp-color-scales.cpp:406 +#: ../../po/../src/widgets/sp-color-scales.cpp:432 +#: ../../po/../src/widgets/sp-color-scales.cpp:463 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:141 +msgid "_A" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:407 +#: ../../po/../src/widgets/sp-color-scales.cpp:408 +#: ../../po/../src/widgets/sp-color-scales.cpp:433 +#: ../../po/../src/widgets/sp-color-scales.cpp:434 +#: ../../po/../src/widgets/sp-color-scales.cpp:464 +#: ../../po/../src/widgets/sp-color-scales.cpp:465 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:151 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:163 +msgid "Alpha (opacity)" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:423 +msgid "_H" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:424 +#: ../../po/../src/widgets/sp-color-scales.cpp:425 +#, fuzzy +msgid "Hue" +msgstr "Renk:" + +#: ../../po/../src/widgets/sp-color-scales.cpp:426 +msgid "_S" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:427 +#: ../../po/../src/widgets/sp-color-scales.cpp:428 +#, fuzzy +msgid "Saturation" +msgstr "Canlılık" + +#: ../../po/../src/widgets/sp-color-scales.cpp:429 +msgid "_L" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:430 +#: ../../po/../src/widgets/sp-color-scales.cpp:431 +#, fuzzy +msgid "Lightness" +msgstr "sağ" + +#: ../../po/../src/widgets/sp-color-scales.cpp:451 +msgid "_C" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:452 +#: ../../po/../src/widgets/sp-color-scales.cpp:453 +#, fuzzy +msgid "Cyan" +msgstr "Cyan:" + +#: ../../po/../src/widgets/sp-color-scales.cpp:454 +msgid "_M" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:455 +#: ../../po/../src/widgets/sp-color-scales.cpp:456 +#, fuzzy +msgid "Magenta" +msgstr "Macenta" + +#: ../../po/../src/widgets/sp-color-scales.cpp:457 +msgid "_Y" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:458 +#: ../../po/../src/widgets/sp-color-scales.cpp:459 +#, fuzzy +msgid "Yellow" +msgstr "Sarı:" + +#: ../../po/../src/widgets/sp-color-scales.cpp:460 +msgid "_K" +msgstr "" + +#: ../../po/../src/widgets/sp-color-selector.cpp:71 +#, fuzzy +msgid "Unnamed" +msgstr "isim" + +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:68 +msgid "Wheel" +msgstr "" + +#: ../../po/../src/widgets/sp-xmlview-attr-list.cpp:53 +msgid "Attribute" +msgstr "Özellik" + +#: ../../po/../src/widgets/sp-xmlview-attr-list.cpp:54 +msgid "Value" +msgstr "Değer" + +#: ../../po/../src/widgets/toolbox.cpp:424 +msgid "Insert new nodes into selected segments" +msgstr "Seçili bölümlere düğüm ekle" + +#: ../../po/../src/widgets/toolbox.cpp:426 +msgid "Delete selected nodes" +msgstr "Seçili düğümleri sil" + +#: ../../po/../src/widgets/toolbox.cpp:431 +#, fuzzy +msgid "Join paths at selected nodes" +msgstr "Seçilen düğümleri çizgilere ekle" + +#: ../../po/../src/widgets/toolbox.cpp:433 +#, fuzzy +msgid "Join paths at selected nodes with new segment" +msgstr "Seçilen düğümleri çizgilere ekle" + +#: ../../po/../src/widgets/toolbox.cpp:436 +msgid "Split path between two non-endpoint nodes" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:439 +#, fuzzy +msgid "Break path at selected nodes" +msgstr "Seçili noktadan kopart" + +#: ../../po/../src/widgets/toolbox.cpp:444 +msgid "Make selected nodes corner" +msgstr "Seçilen düğümleri köşeye çevir" + +#: ../../po/../src/widgets/toolbox.cpp:447 +msgid "Make selected nodes smooth" +msgstr "Seçilen düğümleri güzelleştir" + +#: ../../po/../src/widgets/toolbox.cpp:450 +#, fuzzy +msgid "Make selected nodes symmetric" +msgstr "Seçilen düğümleri güzelleştir" + +#: ../../po/../src/widgets/toolbox.cpp:455 +msgid "Make selected segments lines" +msgstr "Seçilen bölümleri çizgiye çevir" + +#: ../../po/../src/widgets/toolbox.cpp:458 +msgid "Make selected segments curves" +msgstr "Seçilen bölümleri eğrilere dönüştür" + +#: ../../po/../src/widgets/toolbox.cpp:1199 +msgid "Polygon" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1206 +msgid "Regular polygon (with one handle) instead of a star" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1218 +msgid "Corners:" +msgstr "Köşeler:" + +#: ../../po/../src/widgets/toolbox.cpp:1218 +msgid "Number of corners of a polygon or star" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1228 +#, fuzzy +msgid "Spoke ratio:" +msgstr "Resim oranlarını kitle" + +#. TRANSLATORS: Tip radius of a star is the distance from the center to the farthest handle. +#. Base radius is the same for the closest handle. +#: ../../po/../src/widgets/toolbox.cpp:1231 +msgid "Base radius to tip radius ratio" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1246 +#, fuzzy +msgid "Rounded:" +msgstr "2 seçili bitiş noktasını birleştir" + +#: ../../po/../src/widgets/toolbox.cpp:1246 +msgid "How much rounded are the corners (0 for sharp)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1256 +msgid "Randomized:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1256 +msgid "Scatter randomly the corners and angles" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1269 +#: ../../po/../src/widgets/toolbox.cpp:1838 +#: ../../po/../src/widgets/toolbox.cpp:2061 +msgid "Defaults" +msgstr "Öntanımlı" + +#: ../../po/../src/widgets/toolbox.cpp:1270 +#: ../../po/../src/widgets/toolbox.cpp:1839 +#: ../../po/../src/widgets/toolbox.cpp:2062 +msgid "" +"Reset shape parameters to defaults (use Inkscape Preferences > Tools to " +"change defaults)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1544 +msgid "W:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1544 +#, fuzzy +msgid "Width of rectangle" +msgstr "Seçileni kes" + +#: ../../po/../src/widgets/toolbox.cpp:1556 +#, fuzzy +msgid "Height of rectangle" +msgstr "Seçileni göster" + +#: ../../po/../src/widgets/toolbox.cpp:1568 +#, fuzzy +msgid "Rx:" +msgstr "x0:" + +#: ../../po/../src/widgets/toolbox.cpp:1568 +msgid "Horizontal radius of rounded corners" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1578 +#, fuzzy +msgid "Ry:" +msgstr "y0:" + +#: ../../po/../src/widgets/toolbox.cpp:1578 +msgid "Vertical radius of rounded corners" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1594 +#, fuzzy +msgid "Not rounded" +msgstr "daire" + +#: ../../po/../src/widgets/toolbox.cpp:1596 +msgid "Make corners sharp" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1805 +#, fuzzy +msgid "Turns:" +msgstr "Dönüşüm:" + +#: ../../po/../src/widgets/toolbox.cpp:1805 +msgid "Number of revolutions" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1815 +#, fuzzy +msgid "Divergence:" +msgstr "derece" + +#: ../../po/../src/widgets/toolbox.cpp:1815 +msgid "How much denser/sparser are outer revolutions; 1 = uniform" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1825 +msgid "Inner radius:" +msgstr "İç çevre:" + +#: ../../po/../src/widgets/toolbox.cpp:1825 +msgid "Radius of the innermost revolution (relative to the spiral size)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1957 +msgid "The width of the calligraphic pen (relative to the visible canvas area)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1967 +#, fuzzy +msgid "Thinning:" +msgstr "Sunum" + +#: ../../po/../src/widgets/toolbox.cpp:1967 +msgid "" +"How much velocity thins the stroke (> 0 makes fast strokes thinner, < 0 " +"makes them broader, 0 makes width independent of velocity)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1980 +msgid "Angle:" +msgstr "açı:" + +#: ../../po/../src/widgets/toolbox.cpp:1980 +msgid "" +"The angle of the pen's nib (in degrees; 0 = horizontal; has no effect if " +"fixation = 0)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1990 +#, fuzzy +msgid "Fixation:" +msgstr "Oran:" + +#: ../../po/../src/widgets/toolbox.cpp:1990 +msgid "" +"How fixed is the pen angle (0 = always perpendicular to stroke direction, 1 " +"= fixed)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2003 +msgid "Mass:" +msgstr "Büyük:" + +#: ../../po/../src/widgets/toolbox.cpp:2003 +msgid "How much inertia affects the movement of the pen" +msgstr "" + +#. TRANSLATORS: "drag" means "resistance" here +#: ../../po/../src/widgets/toolbox.cpp:2014 +msgid "Drag:" +msgstr "Sürükle:" + +#: ../../po/../src/widgets/toolbox.cpp:2014 +msgid "How much resistance affects the movement of the pen" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2034 +msgid "Use the pressure of the input device to alter the width of the pen" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2047 +msgid "Use the tilt of the input device to alter the angle of the pen's nib" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2374 +#, fuzzy +msgid "Start:" +msgstr "Yıldız" + +#: ../../po/../src/widgets/toolbox.cpp:2374 +msgid "The angle (in degrees) from the horizontal to the arc's start point" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2384 +msgid "End:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2384 +msgid "The angle (in degrees) from the horizontal to the arc's end point" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2395 +#, fuzzy +msgid "Open arc" +msgstr "Aç" + +#: ../../po/../src/widgets/toolbox.cpp:2396 +msgid "" +"Switch between arc (unclosed shape) and segment (closed shape with two radii)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2415 +msgid "Make whole" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2417 +msgid "Make the shape a whole ellipse, not arc or segment" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2644 +msgid "" +"When pressed, picks visible color without alpha and when not pressed, picks " +"color including its alpha" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:3039 +#, fuzzy +msgid "Make connectors avoid selected objects" +msgstr "Seçili nesneleri sil" + +#: ../../po/../src/widgets/toolbox.cpp:3043 +#, fuzzy +msgid "Make connectors ignore selected objects" +msgstr "Seçili nesneleri sil" + +#. +#. 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 : +#: ../share/extensions/addnodes.inx.h:1 +#, fuzzy +msgid "Add Nodes" +msgstr "Düğümler" + +#: ../share/extensions/addnodes.inx.h:2 +msgid "Maximum Segment Length" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:1 +#, fuzzy +msgid "AI Input" +msgstr "Girdi" + +#: ../share/extensions/ai_input.inx.h:2 ../share/extensions/ai_output.inx.h:2 +msgid "Adobe Illustrator (*.ai)" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:3 +msgid "Open files saved with Adobe Illustrator" +msgstr "" + +#: ../share/extensions/ai_output.inx.h:1 +#, fuzzy +msgid "AI Output" +msgstr "Kes" + +#: ../share/extensions/ai_output.inx.h:3 +#, fuzzy +msgid "Write Adobe Illustrator" +msgstr "Vektöt Çizimcisi" + +#: ../share/extensions/dia.inx.h:1 +msgid "A diagram created with the program Dia" +msgstr "" + +#: ../share/extensions/dia.inx.h:2 +msgid "Dia Diagram (*.dia)" +msgstr "" + +#: ../share/extensions/dia.inx.h:3 +#, fuzzy +msgid "Dia Input" +msgstr "Girdi" + +#: ../share/extensions/dia.inx.h:4 +msgid "" +"In order to import Dia files, Dia itself must be installed. You can get Dia " +"at http://www.gnome.org/projects/dia/" +msgstr "" + +#: ../share/extensions/dia.inx.h:5 +msgid "" +"The dia2svg.sh script should be installed with your Inkscape distribution. " +"If you do not have it, there is likely to be something wrong with your " +"Inkscape installation." +msgstr "" + +#: ../share/extensions/dots.inx.h:1 +#, fuzzy +msgid "Connect the Dots" +msgstr "Köşeler:" + +#: ../share/extensions/dots.inx.h:2 +#, fuzzy +msgid "Dot Size" +msgstr "Bölümler:" + +#: ../share/extensions/dots.inx.h:3 +#, fuzzy +msgid "Font Size" +msgstr "Yazı tipi boyutu:" + +#: ../share/extensions/dropshadow.inx.h:1 +msgid "Color of shadow" +msgstr "" + +#: ../share/extensions/dropshadow.inx.h:2 +msgid "Dropshadow" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:1 +#: ../share/extensions/dxf_output.inx.h:1 +msgid "AutoCAD DXF (*.dxf)" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:2 +#, fuzzy +msgid "DXF Input" +msgstr "Girdi" + +#: ../share/extensions/dxf_input.inx.h:3 +msgid "Import AutoCAD's Document Exchange Format" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:4 +msgid "" +"dxf2svg may come with Inkscape, but is also at http://dxf-svg-convert." +"sourceforge.net/" +msgstr "" + +#: ../share/extensions/dxf_output.inx.h:2 +#, fuzzy +msgid "DXF Output" +msgstr "Kes" + +#: ../share/extensions/dxf_output.inx.h:3 +msgid "DXF file written by pstoedit" +msgstr "" + +#: ../share/extensions/dxf_output.inx.h:4 +msgid "pstoedit must be installed to run see http://www.pstoedit.net/pstoedit" +msgstr "" + +#: ../share/extensions/embedimage.inx.h:1 +#, fuzzy +msgid "Embed Images" +msgstr "Resim" + +#: ../share/extensions/eps_input.inx.h:1 +#, fuzzy +msgid "EPS Input" +msgstr "Girdi" + +#: ../share/extensions/eps_input.inx.h:2 +msgid "Encapsulated Postscript" +msgstr "" + +#: ../share/extensions/eps_input.inx.h:3 +msgid "Encapsulated Postscript (*.eps)" +msgstr "" + +#: ../share/extensions/epsi_output.inx.h:1 +#, fuzzy +msgid "EPSI Output" +msgstr "Kes" + +#: ../share/extensions/epsi_output.inx.h:2 +msgid "Encapsulated Postscript Interchange (*.epsi)" +msgstr "" + +#: ../share/extensions/epsi_output.inx.h:3 +msgid "Encapsulated Postscript with a thumbnail" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:1 ../share/extensions/ffms.inx.h:1 +#: ../share/extensions/ffset.inx.h:1 ../share/extensions/ffss.inx.h:1 +#, fuzzy +msgid "Bridge Width" +msgstr " Genişlik " + +#: ../share/extensions/ffmet.inx.h:2 ../share/extensions/ffms.inx.h:2 +msgid "First String Length" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:3 +msgid "FretFind Multi Length ET" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:4 ../share/extensions/ffms.inx.h:4 +#: ../share/extensions/ffset.inx.h:3 ../share/extensions/ffss.inx.h:3 +msgid "Fretboard Edges" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:5 ../share/extensions/ffms.inx.h:5 +msgid "Last String Length" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:6 ../share/extensions/ffms.inx.h:6 +#: ../share/extensions/ffset.inx.h:4 ../share/extensions/ffss.inx.h:4 +msgid "Number of Frets" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:7 ../share/extensions/ffms.inx.h:7 +#: ../share/extensions/ffset.inx.h:5 ../share/extensions/ffss.inx.h:5 +msgid "Number of Strings" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:8 ../share/extensions/ffms.inx.h:8 +#: ../share/extensions/ffset.inx.h:6 ../share/extensions/ffss.inx.h:6 +#, fuzzy +msgid "Nut Width" +msgstr "Genişlik" + +#: ../share/extensions/ffmet.inx.h:9 ../share/extensions/ffms.inx.h:10 +msgid "Perpendicular Distance" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:10 ../share/extensions/ffset.inx.h:7 +msgid "Scale Base (2 for Octave)" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:11 ../share/extensions/ffset.inx.h:9 +msgid "Tones in Scale" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:12 ../share/extensions/ffms.inx.h:12 +#: ../share/extensions/ffset.inx.h:10 ../share/extensions/ffss.inx.h:10 +msgid "px per Unit" +msgstr "" + +#: ../share/extensions/ffms.inx.h:3 +msgid "FretFind Multi Length Scala" +msgstr "" + +#: ../share/extensions/ffms.inx.h:9 ../share/extensions/ffss.inx.h:7 +msgid "Path to Scala *.scl File" +msgstr "" + +#: ../share/extensions/ffms.inx.h:11 +msgid "Tuning (scale step for each string seperated by semicolons)" +msgstr "" + +#: ../share/extensions/ffset.inx.h:2 +msgid "FretFind Single Length ET" +msgstr "" + +#: ../share/extensions/ffset.inx.h:8 ../share/extensions/ffss.inx.h:8 +msgid "Scale Length" +msgstr "" + +#: ../share/extensions/ffss.inx.h:2 +msgid "FretFind Single Length Scala" +msgstr "" + +#: ../share/extensions/ffss.inx.h:9 +msgid "Tuning (Scale step for each string seperated by semicolons)" +msgstr "" + +#: ../share/extensions/handles.inx.h:1 +#, fuzzy +msgid "Draw Handles" +msgstr "Serbest şekiller çiz" + +#: ../share/extensions/interp.inx.h:1 +#, fuzzy +msgid "Duplicate Endpaths" +msgstr "Düğümü çiftle" + +#: ../share/extensions/interp.inx.h:2 +#, fuzzy +msgid "Exponent" +msgstr "Dışarı aktar" + +#: ../share/extensions/interp.inx.h:3 +msgid "Interpolate" +msgstr "" + +#: ../share/extensions/interp.inx.h:4 +msgid "Interpolate Style (Experimental)" +msgstr "" + +#: ../share/extensions/interp.inx.h:5 +msgid "Interpolation Method" +msgstr "" + +#: ../share/extensions/interp.inx.h:6 +msgid "Interpolation Steps" +msgstr "" + +#: ../share/extensions/kochify.inx.h:1 +msgid "Kochify" +msgstr "" + +#: ../share/extensions/kochify_load.inx.h:1 +msgid "Kochify (Load)" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:1 +msgid "Angle" +msgstr "Açı" + +#: ../share/extensions/lindenmayer.inx.h:2 +msgid "Axiom" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:3 +#, fuzzy +msgid "Lindenmayer" +msgstr "Düğümü büyüt" + +#: ../share/extensions/lindenmayer.inx.h:4 +#, fuzzy +msgid "Order" +msgstr "_Sırala" + +#: ../share/extensions/lindenmayer.inx.h:5 +#, fuzzy +msgid "Rules" +msgstr "Dosya" + +#: ../share/extensions/lindenmayer.inx.h:6 +#, fuzzy +msgid "Step" +msgstr "Stil" + +#: ../share/extensions/motion.inx.h:1 +#, fuzzy +msgid "Direction" +msgstr "Konum" + +#: ../share/extensions/motion.inx.h:2 +#, fuzzy +msgid "Magnitude" +msgstr "Macenta" + +#: ../share/extensions/motion.inx.h:3 +#, fuzzy +msgid "Motion" +msgstr "Devir:" + +#: ../share/extensions/pdf_output.inx.h:1 +msgid "Adobe PDF (*.pdf)" +msgstr "" + +#: ../share/extensions/pdf_output.inx.h:2 +msgid "Adobe Portable Document Format" +msgstr "" + +#: ../share/extensions/pdf_output.inx.h:3 +#, fuzzy +msgid "PDF Output" +msgstr "Kes" + +#: ../share/extensions/ps_input.inx.h:1 +#, fuzzy +msgid "Postscript" +msgstr "Nokta" + +#: ../share/extensions/ps_input.inx.h:2 +msgid "Postscript (*.ps)" +msgstr "" + +#: ../share/extensions/ps_input.inx.h:3 +msgid "Postscript Input" +msgstr "" + +#: ../share/extensions/radiusrand.inx.h:1 +#, fuzzy +msgid "Radius" +msgstr "Çevre:" + +#: ../share/extensions/radiusrand.inx.h:2 +#, fuzzy +msgid "Radius Randomize" +msgstr "Düğümü büyüt" + +#: ../share/extensions/radiusrand.inx.h:3 +msgid "Randomize Control Points" +msgstr "" + +#: ../share/extensions/radiusrand.inx.h:4 +#, fuzzy +msgid "Randomize Nodes" +msgstr "Düğümü büyüt" + +#: ../share/extensions/rtree.inx.h:1 +#, fuzzy +msgid "Initial Size" +msgstr "Bitmap boyutu" + +#: ../share/extensions/rtree.inx.h:2 +msgid "Minimum Size" +msgstr "" + +#: ../share/extensions/rtree.inx.h:3 +msgid "Random Tree" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:1 +msgid "A diagram created with the program Sketch" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:2 +msgid "Sketch Diagram (*.sk)" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:3 +msgid "Sketch Input" +msgstr "" + +#: ../share/extensions/straightseg.inx.h:1 +msgid "Behavior" +msgstr "" + +#: ../share/extensions/straightseg.inx.h:3 +msgid "Segment Straightener" +msgstr "" + +#: ../share/extensions/summersnight.inx.h:1 +msgid "Summer's Night" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:1 +#: ../share/extensions/svgz_output.inx.h:1 +#, fuzzy +msgid "Compressed Inkscape SVG (*.svgz)" +msgstr "Sıkıştırılmamış dosya boyutu:" + +#: ../share/extensions/svgz_input.inx.h:2 +#: ../share/extensions/svgz_output.inx.h:2 +msgid "Inkscape's native file format compressed with GZip" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:3 +#, fuzzy +msgid "SVGZ Input" +msgstr "Girdi" + +#: ../share/extensions/svgz_output.inx.h:3 +#, fuzzy +msgid "SVGZ Output" +msgstr "Kes" + +#: ../share/extensions/txt2svg.inx.h:1 +msgid "ASCII Text" +msgstr "" + +#: ../share/extensions/txt2svg.inx.h:2 +msgid "Text File (*.txt)" +msgstr "" + +#: ../share/extensions/txt2svg.inx.h:3 +#, fuzzy +msgid "Text Input" +msgstr "Girdi" + +#: ../share/extensions/wavy.inx.h:1 +msgid "Calculate first derivative numerically" +msgstr "" + +#: ../share/extensions/wavy.inx.h:2 +msgid "First derivative" +msgstr "" + +#: ../share/extensions/wavy.inx.h:3 +msgid "Function" +msgstr "" + +#: ../share/extensions/wavy.inx.h:4 +msgid "Function Plotter" +msgstr "" + +#: ../share/extensions/wavy.inx.h:5 +msgid "Nodes per period" +msgstr "" + +#: ../share/extensions/wavy.inx.h:6 +msgid "Periods (2*Pi each)" +msgstr "" + +#: ../share/extensions/whirl.inx.h:1 +msgid "Amount of Whirl" +msgstr "" + +#: ../share/extensions/whirl.inx.h:2 +#, fuzzy +msgid "Center X" +msgstr "Merkezi X:" + +#: ../share/extensions/whirl.inx.h:3 +#, fuzzy +msgid "Center Y" +msgstr "Merkezi Y:" + +#: ../share/extensions/whirl.inx.h:4 +#, fuzzy +msgid "Direction of Rotation" +msgstr "seçili nesneleri arkaya it" + +#: ../share/extensions/whirl.inx.h:5 +msgid "Whirl" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:1 +msgid "A popular graphics file format for clipart" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:2 +msgid "Windows Metafile (*.wmf)" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:3 +msgid "Windows Metafile Input" +msgstr "" + +#, fuzzy +#~ msgid "Canvas size:" +#~ msgstr "Yazı tipi boyutu:" + +#, fuzzy +#~ msgid "Custom canvas" +#~ msgstr "Özel kağıt" + +#, fuzzy +#~ msgid "Current style" +#~ msgstr "Vuruş ayarları" + +#, fuzzy +#~ msgid "Arrange Objects" +#~ msgstr "Nesneleri Hizala" + +#~ msgid "deg" +#~ msgstr "derece" + +#, fuzzy +#~ msgid "_Credits" +#~ msgstr "Köşeler:" + +#, fuzzy +#~ msgid "Grab sensitivity" +#~ msgstr "Duyarlı hale getir" + +#, fuzzy +#~ msgid "Acceleration" +#~ msgstr "Seçim" + +#, fuzzy +#~ msgid "Speed" +#~ msgstr "Kırmızı:" + +#, fuzzy +#~ msgid "Zoom in/out by" +#~ msgstr "Küçült" + +#, fuzzy +#~ msgid "Transform" +#~ msgstr "Dönüşümler" + +#, fuzzy +#~ msgid "Rotate _90 deg CW" +#~ msgstr "Sayfa genişliğini ayarla" + +#, fuzzy +#~ msgid "Rotate 9_0 deg CCW" +#~ msgstr "Sayfa genişliğini ayarla" + +#, fuzzy +#~ msgid "Flip selection horizontally" +#~ msgstr "Seçili nesneleri yatay çevir" + +#, fuzzy +#~ msgid "Flip selection vertically" +#~ msgstr "Seçili nesneleri dikey çevir" + +#~ msgid "Edit" +#~ msgstr "Düzenle" + +#~ msgid "Add" +#~ msgstr "Ekle" + +#, fuzzy +#~ msgid "C_reate" +#~ msgstr "Yarat" + +#, fuzzy +#~ msgid "Automatically scale Rows to fit selected objects." +#~ msgstr "Seçili nesnelerin dolgu tipini değiştir" + +#, fuzzy +#~ msgid "Automatically scale Columns to fit selected objects." +#~ msgstr "Seçili nesnelerin dolgu tipini değiştir" + +#, fuzzy +#~ msgid "Go to root" +#~ msgstr "Noktaları değiştir" + +#, fuzzy +#~ msgid "X" +#~ msgstr "X1" + +#, fuzzy +#~ msgid "Y" +#~ msgstr "Y1" + +#, fuzzy +#~ msgid " " +#~ msgstr "% " + +#~ msgid "Sides:" +#~ msgstr "Bölümler:" + +#~ msgid "R1:" +#~ msgstr "R1:" + +#~ msgid "R2:" +#~ msgstr "R2:" + +#~ msgid "ARG1:" +#~ msgstr "ARG1:" + +#~ msgid "ARG2:" +#~ msgstr "ARG2:" + +#, fuzzy +#~ msgid "Flatsides:" +#~ msgstr "Bölümler:" + +#, fuzzy +#~ msgid "Radius X:" +#~ msgstr "Çevre:" + +#, fuzzy +#~ msgid "Radius Y:" +#~ msgstr "Çevre:" + +#, fuzzy +#~ msgid "Start Angle:" +#~ msgstr "Yıldız" + +#, fuzzy +#~ msgid "End Angle:" +#~ msgstr "açı:" + +#, fuzzy +#~ msgid "Open:" +#~ msgstr "_Aç" + +#~ msgid "Expansion:" +#~ msgstr "Genişletme:" + +#, fuzzy +#~ msgid "Revolutions:" +#~ msgstr "Devir:" + +#~ msgid "Argument:" +#~ msgstr "Argüman:" + +#~ msgid "T0:" +#~ msgstr "T0:" + +#~ msgid "RX:" +#~ msgstr "RX:" + +#~ msgid "RY:" +#~ msgstr "RY:" + +#, fuzzy +#~ msgid "Rectangle _Properties" +#~ msgstr "Dörtgen Özellikleri" + +#, fuzzy +#~ msgid "Star _Properties" +#~ msgstr "Yıldız Ayarları" + +#, fuzzy +#~ msgid "Ellipse _Properties" +#~ msgstr "Bağlantı Özellikleri" + +#, fuzzy +#~ msgid "Spiral _Properties" +#~ msgstr "Spiral Özellikleri" + +#, fuzzy +#~ msgid "Document Preferences" +#~ msgstr "Nesne referans" + +#, fuzzy +#~ msgid "Extensions Editor" +#~ msgstr "Genişletme" + +#, fuzzy +#~ msgid "Preferences" +#~ msgstr "Nesne referans" + +#, fuzzy +#~ msgid "Layer Editor" +#~ msgstr "XML Düzenleyicisi" + +#, fuzzy +#~ msgid "Text Properties" +#~ msgstr "Metin özellikleri" + +#, fuzzy +#~ msgid "Transformation" +#~ msgstr "Döünüşüm kalıbı" + +#, fuzzy +#~ msgid "_Export..." +#~ msgstr "_Ä°hraç et" + +#, fuzzy +#~ msgid "_Document Properties" +#~ msgstr "Döküman ayarları" + +#, fuzzy +#~ msgid "In_kscape Preferences" +#~ msgstr "Sodipodi: %s : XML Görünümü" + +#, fuzzy +#~ msgid "Select _Original Clone" +#~ msgstr "Seç" + +#, fuzzy +#~ msgid "Tile" +#~ msgstr "_Dosya" + +#, fuzzy +#~ msgid "Select A_ll" +#~ msgstr "Seç" + +#, fuzzy +#~ msgid "Select Non_e" +#~ msgstr "Seçim" + +#, fuzzy +#~ msgid "Zoom _In" +#~ msgstr "Büyült" + +#, fuzzy +#~ msgid "Zoom _Out" +#~ msgstr "Küçült" + +#, fuzzy +#~ msgid "Pre_vious" +#~ msgstr "Diyalogu kapat" + +#, fuzzy +#~ msgid "Nex_t" +#~ msgstr "Metin" + +#, fuzzy +#~ msgid "Tool Co_ntrols bar" +#~ msgstr "Araç ayarları" + +#, fuzzy +#~ msgid "R_ename Layer..." +#~ msgstr "Düğümü büyüt" + +#, fuzzy +#~ msgid "D_uplicate Layer" +#~ msgstr "Kl_onla" + +#, fuzzy +#~ msgid "_Anchor Layer" +#~ msgstr "Düğümü küçült" + +#, fuzzy +#~ msgid "_Delete Layer" +#~ msgstr "Seç" + +#, fuzzy +#~ msgid "Select Ne_xt Layer" +#~ msgstr "Seç" + +#, fuzzy +#~ msgid "Select Pre_vious Layer" +#~ msgstr "Yazıcıyı seçin" + +#, fuzzy +#~ msgid "Select To_p Layer" +#~ msgstr "Yazıcıyı seçin" + +#, fuzzy +#~ msgid "Move to Ne_w Layer" +#~ msgstr "Yeni bir SVG dökümanı oluştur" + +#, fuzzy +#~ msgid "Move to B_ottom Layer" +#~ msgstr "seçili nesneleri arkaya it" + +#, fuzzy +#~ msgid "_Trace Bitmap..." +#~ msgstr "Bozuk resim" + +#, fuzzy +#~ msgid "_Put Text on Path" +#~ msgstr "Seçili nesneleri eğrilere dönder" + +#, fuzzy +#~ msgid "_Remove Text from Path" +#~ msgstr "Seçili nesneleri eğrilere dönder" + +#~ msgid "Arc" +#~ msgstr "Eğri" + +#, fuzzy +#~ msgid "Freehand" +#~ msgstr "Serbest ve kalem çizimi" + +#, fuzzy +#~ msgid "DynaDraw" +#~ msgstr "Çiz" + +#~ msgid "Stroke" +#~ msgstr "Baskı" + +#, fuzzy +#~ msgid "Corners" +#~ msgstr "Köşeler:" + +#~ msgid "Delete" +#~ msgstr "Sil" + +#, fuzzy +#~ msgid "Join" +#~ msgstr "Ekle:" + +#, fuzzy +#~ msgid "Delete Segment" +#~ msgstr "Seçileni klonla" + +#, fuzzy +#~ msgid "Break" +#~ msgstr "Kopar" + +#, fuzzy +#~ msgid "Symmetric" +#~ msgstr "Asimetrik" + +#~ msgid "New" +#~ msgstr "Yeni" + +#, fuzzy +#~ msgid "Revert to Saved" +#~ msgstr "_Eğrilere Dönüştür" + +#, fuzzy +#~ msgid "Save" +#~ msgstr "Kayde" + +#, fuzzy +#~ msgid "Save As..." +#~ msgstr "Farklı kaydet" + +#, fuzzy +#~ msgid "Import..." +#~ msgstr "_Ä°thal et" + +#, fuzzy +#~ msgid "Export..." +#~ msgstr "Dışarı aktar" + +#, fuzzy +#~ msgid "Print..." +#~ msgstr "Yazdır" + +#, fuzzy +#~ msgid "Global Inkscape preferences (Shift+Ctrl+P)" +#~ msgstr "Görüntü ayarları" + +#, fuzzy +#~ msgid "Undo" +#~ msgstr "Geri al" + +#, fuzzy +#~ msgid "Redo" +#~ msgstr "Yeniden yap" + +#, fuzzy +#~ msgid "Cut" +#~ msgstr "Kes" + +#, fuzzy +#~ msgid "Copy" +#~ msgstr "Kopya" + +#, fuzzy +#~ msgid "Duplicate selected object(s) (Ctrl+D)" +#~ msgstr "Seçili nesneleri çiftle" + +#, fuzzy +#~ msgid "Clone selected object (Alt+D)" +#~ msgstr "Seçili nesneleri çiftle" + +#, fuzzy +#~ msgid "Zoom in (+)" +#~ msgstr "Büyült" + +#, fuzzy +#~ msgid "Zoom out (-)" +#~ msgstr "Küçült" + +#, fuzzy +#~ msgid "Zoom to 1:1 (100%) (1)" +#~ msgstr "1:1 göster" + +#, fuzzy +#~ msgid "Zoom to 1:2 (50%) (2)" +#~ msgstr "1:1 göster" + +#, fuzzy +#~ msgid "Zoom to 2:1 (200%) (0)" +#~ msgstr "1:1 göster" + +#, fuzzy +#~ msgid "Zoom to fit selection in window (3)" +#~ msgstr "Seçimi pencereye uydur" + +#, fuzzy +#~ msgid "Zoom to fit drawing in window (4)" +#~ msgstr "Çizimi pencereye uydur" + +#, fuzzy +#~ msgid "Zoom to fit page in window (5)" +#~ msgstr "Tüm sayfayı pencereye uydur" + +#, fuzzy +#~ msgid "Zoom to fit page width in window (6)" +#~ msgstr "Tüm sayfayı pencereye uydur" + +#, fuzzy +#~ msgid "Fill and Stroke dialog (Shift+Ctrl+F)" +#~ msgstr "Doldur ve Vur" + +#, fuzzy +#~ msgid "Group selected objects (Ctrl+G)" +#~ msgstr "Seçili nesneleri grupla" + +#, fuzzy +#~ msgid "Ungroup selected group(s) (Ctrl+U)" +#~ msgstr "Seçili grupların gruplandırmasını kaldır" + +#, fuzzy +#~ msgid "Raise selection up one step (PgUp)" +#~ msgstr "Seçileni öne getir" + +#, fuzzy +#~ msgid "Lower selection down one step (PgDn)" +#~ msgstr "Seçileni bir katman alçalt" + +#, fuzzy +#~ msgid "Raise selection to top (Home)" +#~ msgstr "Seçileni öne getir" + +#, fuzzy +#~ msgid "Lower selection to bottom (End)" +#~ msgstr "seçili nesneleri arkaya it" + +#, fuzzy +#~ msgid "Move selection to new layer" +#~ msgstr "Seçileni bir katman yükselt" + +#, fuzzy +#~ msgid "Move selection to next layer" +#~ msgstr "Seçileni bir katman yükselt" + +#, fuzzy +#~ msgid "Move selection to previous layer" +#~ msgstr "Seçileni bir katman yükselt" + +#, fuzzy +#~ msgid "Move selection to top layer" +#~ msgstr "Seçileni bir katman yükselt" + +#, fuzzy +#~ msgid "Move selection to bottom layer" +#~ msgstr "seçili nesneleri arkaya it" + +#, fuzzy +#~ msgid "Rotate selection 90° clockwise (Shift+Ctrl+Right)" +#~ msgstr "Seçili nesneleri saat yönünde 90 derece dönder" + +#, fuzzy +#~ msgid "Rotate selection 90° counter-clockwise (Shift+Ctrl+Left)" +#~ msgstr "Seçili nesneleri saat yönünde 90 derece dönder" + +#, fuzzy +#~ msgid "Flip selection horizontally (H)" +#~ msgstr "Seçili nesneleri yatay çevir" + +#, fuzzy +#~ msgid "Flip selection vertically (V)" +#~ msgstr "Seçili nesneleri dikey çevir" + +#, fuzzy +#~ msgid "Align and Distribute dialog (Shift+Ctrl+A)" +#~ msgstr "Özellik" + +#, fuzzy +#~ msgid "Convert selected object(s) to path(s) (Shift+Ctrl+C)" +#~ msgstr "Seçili nesneleri eğrilere dönder" + +#, fuzzy +#~ msgid "Convert selected stroke(s) to path(s) (Ctrl+Alt+C)" +#~ msgstr "Seçili nesneleri eğrilere dönder" + +#, fuzzy +#~ msgid "Cl_eanup" +#~ msgstr "Temizle" + +#, fuzzy +#~ msgid "Text and Font dialog (Shift+Ctrl+T)" +#~ msgstr "Metin ve yazı tipi" + +#, fuzzy +#~ msgid "Node tool" +#~ msgstr "Aktif araç yok" + +#, fuzzy +#~ msgid "Zoom tool" +#~ msgstr "Küçült" + +#~ msgid "Rectangle tool" +#~ msgstr "Dörtgen aracı" + +#~ msgid "Arc tool" +#~ msgstr "Eğik çizim aracı" + +#~ msgid "Star tool" +#~ msgstr "Yıldız aracı" + +#~ msgid "Spiral tool" +#~ msgstr "Spiral aracı" + +#, fuzzy +#~ msgid "Freehand tool" +#~ msgstr "Serbest ve kalem çizimi" + +#, fuzzy +#~ msgid "Pen tool" +#~ msgstr "Dörtgen aracı" + +#, fuzzy +#~ msgid "Calligraphy tool" +#~ msgstr "Karalama çizgisi" + +#, fuzzy +#~ msgid "Text tool" +#~ msgstr "Yıldız aracı" + +#, fuzzy +#~ msgid "Dropper tool" +#~ msgstr "Spiral aracı" + +#, fuzzy +#~ msgid "Delete segment between two nodes" +#~ msgstr "Seçili düğümleri sil" + +#, fuzzy +#~ msgid "URI:" +#~ msgstr "Adres:" + +#, fuzzy +#~ msgid "Select All in All Layers" +#~ msgstr "Seç" + +#, fuzzy +#~ msgid "Invert Selection" +#~ msgstr "Seçim" + +#, fuzzy +#~ msgid "Clean up selected path(s)" +#~ msgstr "Seçili yolları birleştir" + +#, fuzzy +#~ msgid "_Scripts..." +#~ msgstr "Yazdır" + +#, fuzzy +#~ msgid "Align and Distribute" +#~ msgstr "Özellik" + +#, fuzzy +#~ msgid "Align and Distribute Dialog" +#~ msgstr "Özellik" + +#, fuzzy +#~ msgid "Export Dialog" +#~ msgstr "Ä°hraç ediliş şekli" + +#, fuzzy +#~ msgid "Fill and Stroke Dialog" +#~ msgstr "Doldur ve Vur" + +#, fuzzy +#~ msgid "Find Dialog" +#~ msgstr "Diyalogu hizala" + +#, fuzzy +#~ msgid "Inkscape Preferences" +#~ msgstr "Sodipodi: %s : XML Görünümü" + +#, fuzzy +#~ msgid "Inkscape Preferences Dialog" +#~ msgstr "Sodipodi: %s : XML Görünümü" + +#, fuzzy +#~ msgid "Layer Editor Dialog" +#~ msgstr "Seçileni öne getir" + +#, fuzzy +#~ msgid "Text Properties Dialog" +#~ msgstr "nesne özellikleri" + +#, fuzzy +#~ msgid "Transformation Dialog" +#~ msgstr "Dönüştürme diyalogu" + +#, fuzzy +#~ msgid "Tree Editor" +#~ msgstr "XML Düzenleyicisi" + +#, fuzzy +#~ msgid "XML Editor Dialog" +#~ msgstr "XML Düzenleyicisi" + +#, fuzzy +#~ msgid "Row height:" +#~ msgstr "Yükseklik:" + +#, fuzzy +#~ msgid "Column width:" +#~ msgstr "Değiştir" + +#, fuzzy +#~ msgid "Creating anchor at (%g,%g)" +#~ msgstr "Metin çiz" + +#, fuzzy +#~ msgid "EPS Output Settings" +#~ msgstr "Döküman ayarları" + +#, fuzzy +#~ msgid "Inkscape" +#~ msgstr "Sodipodi: %s : XML Görünümü" + +#~ msgid "Left side of aligned objects to left side of anchor" +#~ msgstr "Çapanın soluna hizalanmış nesnelerin sol tarafı" + +#~ msgid "Right side of aligned objects to right side of anchor" +#~ msgstr "Çapanın sağına hizalanmış nesnelerin sağ tarafı" + +#~ msgid "Top of aligned objects to top of anchor" +#~ msgstr "Çapanın üstüne hizalanmış nesnelerin üstü" + +#~ msgid "Bottom of aligned objects to bottom of anchor" +#~ msgstr "Çapanın altına hizalanmış nesnelerin altı" + +#, fuzzy +#~ msgid "Alternate sign" +#~ msgstr "Canlılık" + +#, fuzzy +#~ msgid "Rows:" +#~ msgstr "Elips" + +#, fuzzy +#~ msgid "Minor grid line color:" +#~ msgstr "Rehber satırı rengi" + +#~ msgid "Grid color" +#~ msgstr "Izgara rengi" + +#, fuzzy +#~ msgid "Grid emphasis color" +#~ msgstr "Izgara rengi" + +#, fuzzy +#~ msgid "Major grid line spacing:" +#~ msgstr "X aralığı:" + +#, fuzzy +#~ msgid "Background (also for export):" +#~ msgstr "Bitiş rengi" + +#, fuzzy +#~ msgid "Picking colors:" +#~ msgstr "Renk seçiniz" + +#~ msgid "Fill style" +#~ msgstr "Doldurma stili" + +#, fuzzy +#~ msgid "Fill:" +#~ msgstr "Doldur" + +#, fuzzy +#~ msgid "winding" +#~ msgstr "Sunum" + +#, fuzzy +#~ msgid "alternating" +#~ msgstr "Canlılık" + +#, fuzzy +#~ msgid "Update Properties" +#~ msgstr "Birim Özellikleri" + +#, fuzzy +#~ msgid "Label invalid" +#~ msgstr "Numara geçerli" + +#, fuzzy +#~ msgid "executable" +#~ msgstr "Dörtgen" + +#, fuzzy +#~ msgid "file" +#~ msgstr "Dosya" + +#, fuzzy +#~ msgid "extension" +#~ msgstr "Genişletme" + +#, fuzzy +#~ msgid "path" +#~ msgstr "pt" + +#, fuzzy +#~ msgid "absolute" +#~ msgstr "Yapış" + +#~ msgid "Could not create sodipodi-svg-doc factory" +#~ msgstr "sodipodi-svg-doc üreticisi yaratılamadı" + +#, fuzzy +#~ msgid "SVG Files" +#~ msgstr "Dosyayı kaydet" + +#~ msgid "Plain SVG" +#~ msgstr "Düz SVG" + +#, fuzzy +#~ msgid "Make s_ensitive" +#~ msgstr "Duyarlı hale getir" + +#, fuzzy +#~ msgid "Make i_nsensitive" +#~ msgstr "Duyarsız hale getir" + +#, fuzzy +#~ msgid "Layer Properties" +#~ msgstr "Yıldız Ayarları" + +#, fuzzy +#~ msgid "Select object(s) to tile." +#~ msgstr "Seçili nesneleri panoya kes" + +#, fuzzy +#~ msgid "Apply" +#~ msgstr "Uygula:" + +#~ msgid "Sensitive" +#~ msgstr "Duyarlı" + +#~ msgid "Active" +#~ msgstr "Aktif" + +#~ msgid "Printable" +#~ msgstr "Yazılabilir" + +#~ msgid "Trace" +#~ msgstr "Ä°pucu" + +#, fuzzy +#~ msgid "Error writing %s: %s" +#~ msgstr "%s dosyasına yazılırken hata oluştu: %s" + +#~ msgid "Untitled" +#~ msgstr "Başlıksız" + +#~ msgid "Document Name:" +#~ msgstr "Döküman Adı:" + +#~ msgid "Image URI:" +#~ msgstr "Resim Adresi:" + +#~ msgid "Visible" +#~ msgstr "Görünür" + +#, fuzzy +#~ msgid "Drag to paint a calligraphic stroke." +#~ msgstr "Karalama çizgisi" + +#, fuzzy +#~ msgid "Flatness:" +#~ msgstr "Bölümler:" + +#, fuzzy +#~ msgid "Other" +#~ msgstr "Sırala" + +#, fuzzy +#~ msgid "Trace: Selected object is not an image" +#~ msgstr "Seçili nesneleri bir seviye üste taşı" + +#, fuzzy +#~ msgid "object" +#~ msgstr "Nesne" + +#, fuzzy +#~ msgid "user space" +#~ msgstr "Kullanıcı boşluk birimi" + +#, fuzzy +#~ msgid "Coordinates:" +#~ msgstr "Köşeler:" + +#~ msgid "Alignment:" +#~ msgstr "Hiza:" + +#~ msgid "Text and font" +#~ msgstr "Metin ve yazı tipi" + +#, fuzzy +#~ msgid "Draw arc: %s x %s" +#~ msgstr "Çiz\t" + +#~ msgid "All shape tools" +#~ msgstr "Tüm şekillendirme araçları" + +#, fuzzy +#~ msgid "Draw rectangle: %s x %s" +#~ msgstr "Dörtgen çiz" + +#, fuzzy +#~ msgid "Move by %s, %s" +#~ msgstr " Taşı " + +#, fuzzy +#~ msgid "Active group" +#~ msgstr "Aktif" + +#~ msgid "Grid color:" +#~ msgstr "Izgara rengi" + +#, fuzzy +#~ msgid "typeset object" +#~ msgstr "Metin nesnesi" + +#, fuzzy +#~ msgid "Pattern Fill" +#~ msgstr "Motif:" + +#~ msgid "Snap to grid" +#~ msgstr "Izgaraya yakala" + +#~ msgid "Snap to guides" +#~ msgstr "Rehberlere yakala" + +#, fuzzy +#~ msgid "_Menu" +#~ msgstr "Temizle" + +#, fuzzy +#~ msgid "Snap points to the grid" +#~ msgstr "Izgaraya yakala" + +#, fuzzy +#~ msgid "Rect" +#~ msgstr "Dörtgen" + +#~ msgid "meters" +#~ msgstr "metre" + +#~ msgid "Userspace unit" +#~ msgstr "Kullanıcı boşluk birimi" + +#~ msgid "User" +#~ msgstr "Kullanıcı" + +#~ msgid "Userspace units" +#~ msgstr "Kullanıcı boşluk birimleri" + +#, fuzzy +#~ msgid "Ru_lers" +#~ msgstr "Dosya" + +#, fuzzy +#~ msgid "Show or hide rulers" +#~ msgstr "Rehberleri göster" + +#, fuzzy +#~ msgid "_New Window" +#~ msgstr "Yeni Görünüm" + +#~ msgid "Mode:" +#~ msgstr "Mod:" + +#~ msgid "Alpha:" +#~ msgstr "Alfa:" + +#~ msgid "Value:" +#~ msgstr "Değer:" + +#~ msgid "Stroke settings" +#~ msgstr "Vuruş ayarları" + +#~ msgid "Item properties" +#~ msgstr "Nesne özellikleri" + +#, fuzzy +#~ msgid "Quit" +#~ msgstr "Çı_k" + +#~ msgid "Combine multiple paths" +#~ msgstr "Çoklu konumları birleştir" + +#, fuzzy +#~ msgid "New View" +#~ msgstr "Yeni Görünüm" + +#, fuzzy +#~ msgid "Fill and stroke settings" +#~ msgstr "Vuruş ayarları" + +#~ msgid "Object transformations" +#~ msgstr "Nesne dönüşümleri" + +#, fuzzy +#~ msgid "Align and distribute objects" +#~ msgstr "Özellik ekle" + +#, fuzzy +#~ msgid "Text editing and font settings" +#~ msgstr "Metin ve yazı tipi ayarları" + +#~ msgid "Fill Rule" +#~ msgstr "Doldurma Kuralları" + +#~ msgid "Tool has no options" +#~ msgstr "Aracın özelliği yok" + +#~ msgid "Roundness ratio for x:" +#~ msgstr "X için yuvarlaklık değeri:" + +#~ msgid "Roundness ratio for y:" +#~ msgstr "Y için yuvarlaklık değeri:" + +#~ msgid "Visual transformation" +#~ msgstr "Görüntülü dönüşüm" + +#~ msgid "Show content" +#~ msgstr "İçeriği göster" + +#, fuzzy +#~ msgid "Selected object has no curve, cannot outline." +#~ msgstr "Seçili nesneleri panoya kes" + +#~ msgid "Proportion:" +#~ msgstr "Orantı:" + +#, fuzzy +#~ msgid "Inkscape _Options" +#~ msgstr "Sodipodi: %s : XML Görünümü" + +#, fuzzy +#~ msgid "Tool Optio_ns" +#~ msgstr "Araç Özellikleri" + +#~ msgid "gradientUnits" +#~ msgstr "gradientUnits" + +#~ msgid "gradientSpread" +#~ msgstr "gradientSpread" + +#~ msgid "nonzero" +#~ msgstr "boş değil" + +#~ msgid "evenodd" +#~ msgstr "rastgele" + +#, fuzzy +#~ msgid "" +#~ "%s is not regular file.\n" +#~ "Although inkscape will run, you can\n" +#~ "neither load nor save preferences\n" +#~ msgstr "" +#~ "%s uygun bir dosya değil.\n" +#~ "Sodipodi çalışacak fakat ayarları kaydemeyecek\n" +#~ "veya yükleyemeyeceksiniz.\n" + +#, fuzzy +#~ msgid "" +#~ "%s either is not valid xml file or\n" +#~ "you do not have read premissions on it.\n" +#~ "Although inkscape will run, you\n" +#~ "are neither able to load nor save\n" +#~ "preferences." +#~ msgstr "" +#~ "%s uygun bir xml dosyası değil veya \n" +#~ "bu dosya üzerinde gerekli haklarınız yok.\n" +#~ "Sodipodi çalışacak fakat ayarları kaydemeyecek\n" +#~ "veya yükleyemeyeceksiniz." + +#, fuzzy +#~ msgid "" +#~ "%s is not valid inkscape preferences file.\n" +#~ "Although inkscape will run, you\n" +#~ "are neither able to load nor save\n" +#~ "preferences." +#~ msgstr "" +#~ "%s uygun bir sodipodi ayar dosyası değil.\n" +#~ "Sodipodi çalışacak fakat ayarları kaydemeyecek\n" +#~ "veya yükleyemeyeceksiniz." + +#, fuzzy +#~ msgid "" +#~ "Cannot create directory %s.\n" +#~ "Although inkscape will run, you\n" +#~ "are neither able to load nor save\n" +#~ "%s." +#~ msgstr "" +#~ "%s dizini yaratılamıyor.\n" +#~ "Sodipodi çalışacak fakat ayarları kaydemeyecek\n" +#~ "veya yükleyemeyeceksiniz." + +#, fuzzy +#~ msgid "" +#~ "%s is not a valid directory.\n" +#~ "Although inkscape will run, you\n" +#~ "are neither able to load nor save\n" +#~ "preferences." +#~ msgstr "" +#~ "%s uygun bir dizin değil.\n" +#~ "Sodipodi çalışacak fakat ayarları kaydemeyecek\n" +#~ "veya yükleyemeyeceksiniz." + +#, fuzzy +#~ msgid "" +#~ "Cannot create file %s.\n" +#~ "Although inkscape will run, you\n" +#~ "are neither able to load nor save\n" +#~ "preferences." +#~ msgstr "" +#~ "%s dosyası yaratılamıyor.\n" +#~ "Sodipodi çalışacak fakat ayarları kaydemeyecek\n" +#~ "veya yükleyemeyeceksiniz." + +#, fuzzy +#~ msgid "" +#~ "Cannot write file %s.\n" +#~ "Although inkscape will run, you\n" +#~ "are neither able to load nor save\n" +#~ "preferences." +#~ msgstr "" +#~ "%s dosyasına yazılamıyor.\n" +#~ "Sodipodi çalışacak fakat ayarları kaydemeyecek\n" +#~ "veya yükleyemeyeceksiniz." + +#~ msgid "End color" +#~ msgstr "Bitiş rengi" + +#~ msgid "Make sides flat" +#~ msgstr "Kenarları düzleştir" + +#~ msgid "Bring to _Front" +#~ msgstr "Ö_ne Getir" + +#~ msgid "Send to _Back" +#~ msgstr "Arka_ya it" + +#~ msgid "Document %s has unsaved changes, save them?" +#~ msgstr "%s dökümanı kaydedilmemiş değişiklikler içeriyor, kaydedilsin mi?" + +#, fuzzy +#~ msgid "Object Size and Position" +#~ msgstr "Nesne boyutu ve konumu" + +#~ msgid "Size and Position" +#~ msgstr "Boyut ve Konum" + +#~ msgid "Tool attributes" +#~ msgstr "Araç özellikleri" + +#~ msgid "Inner radius" +#~ msgstr "İç çevre" + +#~ msgid "Proportion" +#~ msgstr "Orantı" + +#~ msgid "Tool has no attributes" +#~ msgstr "Aracın özellikleri yok" + +#~ msgid "Item" +#~ msgstr "Birim" + +#~ msgid "Group Properties" +#~ msgstr "Grup Özellikleri" + +#~ msgid "Ungroup" +#~ msgstr "Grupları Kaldır" + +#~ msgid "Fill settings" +#~ msgstr "Doldurma ayarları" + +#~ msgid "Break line at selected nodes" +#~ msgstr "Çizgileri seçilen düğümlerden kes" + +#~ msgid "Import" +#~ msgstr "İçeri Aktar" + +#~ msgid "Bring to Front" +#~ msgstr "Öne Getir" + +#~ msgid "Send to Back" +#~ msgstr "Arkaya it" + +#~ msgid "Lower selected objects to bottom" +#~ msgstr "Seçili nesneleri arkaya it" + +#, fuzzy +#~ msgid "Raise selected objects one position" +#~ msgstr "Seçili nesneleri üste taşı" + +#, fuzzy +#~ msgid "Lower selected objects one position" +#~ msgstr "Seçili nesneleri arkaya it" + +#, fuzzy +#~ msgid "Draw freehand curves and straight lines" +#~ msgstr "Kalem aracı - düz ve serbest çizgiler çizer" + +#, fuzzy +#~ msgid "In" +#~ msgstr "Ä°nç" + +#, fuzzy +#~ msgid "Toggle grid" +#~ msgstr "Kenarları aç/kapat" + +#, fuzzy +#~ msgid "Toggle guides" +#~ msgstr "Kenarları aç/kapat" + +#~ msgid "1:1" +#~ msgstr "1:1" + +#~ msgid "1:2" +#~ msgstr "1:2" + +#~ msgid "2:1" +#~ msgstr "2:1" + +#~ msgid "Editing Window" +#~ msgstr "Düzenleme Penceresi" + +#, fuzzy +#~ msgid "Editing window properties" +#~ msgstr "Düzenleme Penceresi" + +#~ msgid "Tool Attributes" +#~ msgstr "Araç Özellikleri" + +#~ msgid "Sodipodi" +#~ msgstr "Sodipodi" + +#~ msgid "Desktop settings" +#~ msgstr "Masaüstü ayarları" + +#, fuzzy +#~ msgid "Iso grid" +#~ msgstr "Izgarayı göster" + +#~ msgid "Display settings" +#~ msgstr "Görüntü ayarları" + +#~ msgid "Export png file" +#~ msgstr "Png dosyasını dışarı aktar" + +#~ msgid "Object style" +#~ msgstr "Nesne stili" + +#, fuzzy +#~ msgid "Inkscape: %s : XML View" +#~ msgstr "Sodipodi: %s : XML Görünümü" + +#, fuzzy +#~ msgid "Appending to selection. Press 'a' to toggle Append/New." +#~ msgstr "Seçime ekleme yapılıyor. '+'a basarak Yeni/Ekleye ulaşabilirsiniz" + +#~ msgid "Exit Program" +#~ msgstr "Programdan Çık" + +#~ msgid "New Toplevel Toolbox" +#~ msgstr "Yeni Yüksek Seviye Araç Kutusu" + +#~ msgid "New Docked Toolbox" +#~ msgstr "Yeni Küçük Araç Kutusu" + +#~ msgid "Remove Docked Toolbox" +#~ msgstr "Küçük Araç Kutusunu Kaldır" + +#~ msgid "Drawing Mode" +#~ msgstr "Çizim Modu" + +#~ msgid "SVG with \"xmlns:sodipodi\" namespace" +#~ msgstr "\"xmlns:sodipodi\" ad boşluğu ile SVG" + +#, fuzzy +#~ msgid "" +#~ "%s is not regular file.\n" +#~ "Although inkscape will run, you are\n" +#~ "not able to use extensions (plugins)\n" +#~ msgstr "" +#~ "%s uygun bir dosya değil.\n" +#~ "Sodipodi çalışacak fakat ayarları kaydemeyecek\n" +#~ "veya yükleyemeyeceksiniz.\n" + +#, fuzzy +#~ msgid "" +#~ "%s either is not valid xml file or\n" +#~ "you do not have read premissions on it.\n" +#~ "Although inkscape will run, you are\n" +#~ "not able to use extensions (plugins)\n" +#~ msgstr "" +#~ "%s uygun bir xml dosyası değil veya \n" +#~ "bu dosya üzerinde gerekli haklarınız yok.\n" +#~ "Sodipodi çalışacak fakat ayarları kaydemeyecek\n" +#~ "veya yükleyemeyeceksiniz." + +#, fuzzy +#~ msgid "" +#~ "%s is not valid inkscape extensions file.\n" +#~ "Although inkscape will run, you are\n" +#~ "not able to use extensions (plugins)\n" +#~ msgstr "" +#~ "%s uygun bir sodipodi ayar dosyası değil.\n" +#~ "Sodipodi çalışacak fakat ayarları kaydemeyecek\n" +#~ "veya yükleyemeyeceksiniz." + +#, fuzzy +#~ msgid "" +#~ "Cannot create directory %s.\n" +#~ "Although inkscape will run, you are\n" +#~ "not able to use extensions (plugins)\n" +#~ msgstr "" +#~ "%s dizini yaratılamıyor.\n" +#~ "Sodipodi çalışacak fakat ayarları kaydemeyecek\n" +#~ "veya yükleyemeyeceksiniz." + +#, fuzzy +#~ msgid "" +#~ "%s is not a valid directory.\n" +#~ "Although inkscape will run, you are\n" +#~ "not able to use extensions (plugins)\n" +#~ msgstr "" +#~ "%s uygun bir dizin değil.\n" +#~ "Sodipodi çalışacak fakat ayarları kaydemeyecek\n" +#~ "veya yükleyemeyeceksiniz." + +#, fuzzy +#~ msgid "" +#~ "Cannot create file %s.\n" +#~ "Although inkscape will run, you are\n" +#~ "not able to use extensions (plugins)\n" +#~ msgstr "" +#~ "%s dosyası yaratılamıyor.\n" +#~ "Sodipodi çalışacak fakat ayarları kaydemeyecek\n" +#~ "veya yükleyemeyeceksiniz." + +#, fuzzy +#~ msgid "" +#~ "Cannot write file %s.\n" +#~ "Although inkscape will run, you are\n" +#~ "not able to use extensions (plugins)\n" +#~ msgstr "" +#~ "%s dosyasına yazılamıyor.\n" +#~ "Sodipodi çalışacak fakat ayarları kaydemeyecek\n" +#~ "veya yükleyemeyeceksiniz." + +#~ msgid "Unknown item :-(" +#~ msgstr "Bilinmeyen birim:-(" + +#~ msgid "Text and font settings" +#~ msgstr "Metin ve yazı tipi ayarları" + +#, fuzzy +#~ msgid "Modify existing objects by control nodes" +#~ msgstr "Nesneleri kontrol noktalarıyla değiştir" + +#, fuzzy +#~ msgid "Draw precisely positioned curved and straight lines" +#~ msgstr "Eğri kalem aracı - belirli noktalarla eğriler çizer" + +#~ msgid "Zoom in drawing" +#~ msgstr "Çizimi yakınlaştır" + +#~ msgid "Zoom out drawing" +#~ msgstr "Çizimi uzaklaştır" + +#~ msgid "Set zoom factor to 1:1" +#~ msgstr "Yakınlaştırma faktörünü 1.1 ata" + +#~ msgid "Set zoom factor to 1:2" +#~ msgstr "Yakınlaştırma faktörünü 1.2 ata" + +#~ msgid "Set zoom factor to 2:1" +#~ msgstr "Yakınlaştırma faktörünü 2.1 ata" + +#~ msgid "Document" +#~ msgstr "Belge" + +#, fuzzy +#~ msgid "Document variant:" +#~ msgstr "Döküman Adı:" + +#, fuzzy +#~ msgid "Save document as" +#~ msgstr "Dökümanı kaydet" + +#~ msgid "About sodipodi" +#~ msgstr "Sodipodi hakkında" + +#~ msgid "About Sodipodi" +#~ msgstr "Sodipodi Hakkında" + +#~ msgid "The SVG ID of item" +#~ msgstr "Nesnenin SVG numarası" + +#~ msgid "The ID is not valid" +#~ msgstr "Numara geçerli değil" + +#~ msgid "The ID is already defined" +#~ msgstr "Numara önceden belirlenmiş" + +#~ msgid "Object position and size" +#~ msgstr "Nesne konumu ve boyutu" + +#~ msgid "Position and size" +#~ msgstr "Konum ve boyut" + +#~ msgid "Dynahand" +#~ msgstr "Düz" + +#~ msgid "Text Editing" +#~ msgstr "Metin Düzenlemesi" + +#~ msgid "Display Properties" +#~ msgstr "Görünüm Ayarları" + +#~ msgid "Lower selected objects one level" +#~ msgstr "Seçili nesneleri bir seviye arkaya it" + +#~ msgid "Select tool - select and transform objects" +#~ msgstr "Seçim Aracı - Nesneleri seçer ve şekillendirir" + +#~ msgid "Node tool - modify different aspects of existing objects" +#~ msgstr "Düğüm aracı - Varolan nesnelerin özelliklerini değiştirir" + +#~ msgid "Spiral tool - create spirals" +#~ msgstr "Spiral aracı - spiraller yaratır" + +#~ msgid "Calligraphic tool - draw calligraphic lines" +#~ msgstr "Karalama aracı - karalama çizgileri çizer" + +#~ msgid "Zoom tool - zoom into choosen area" +#~ msgstr "Yakınlaştırma aracı - seçilen alanı yakından gösterir" + +#~ msgid "Save as:" +#~ msgstr "Farklı kaydet:" + +#~ msgid "Whether zoom follows window size" +#~ msgstr "Yakınlaştırma/Uzaklaştırma pencere boyutuna bağlı olsun" + +#~ msgid "A path - whatever it means" +#~ msgstr "Bir konum - ne anlama geliyorsa" + +#~ msgid "Align objects to vertical mid" +#~ msgstr "Nesneleri dikey ortasına hizala" + +#~ msgid "Align outside object to bottom border" +#~ msgstr "Nesne dışını alt kenara hizala" + +#~ msgid "Align outside object to left border" +#~ msgstr "Nesne dışını sol kenara hizala" + +#~ msgid "Align outside object to right border" +#~ msgstr "Nesne dışını sağ kenara hizala" + +#~ msgid "Align outside object to top border" +#~ msgstr "Nesne dışını üst kenara hizala" + +#, fuzzy +#~ msgid "Choose align type" +#~ msgstr "Birim sistemini seçiniz" + +#~ msgid " Color fill " +#~ msgstr " Renkli dolgu " + +#~ msgid " General " +#~ msgstr " Genel " + +#~ msgid "Behind fill" +#~ msgstr "Dolgu arkası" + +#, fuzzy +#~ msgid "Butt endpoints" +#~ msgstr "2 seçili bitiş noktasını birleştir" + +#, fuzzy +#~ msgid "Choose fill color" +#~ msgstr "Izgara rengini seçiniz" + +#, fuzzy +#~ msgid "Choose stroke color" +#~ msgstr "Baskı rengi : " + +#, fuzzy +#~ msgid "Endpoints:" +#~ msgstr "Birimler:" + +#, fuzzy +#~ msgid "Fill Color:" +#~ msgstr "Dolgu rengi : " + +#, fuzzy +#~ msgid "Fractal fill" +#~ msgstr "Fraktal" + +#, fuzzy +#~ msgid "Pick fill color" +#~ msgstr "Renk seçiniz" + +#, fuzzy +#~ msgid "Scale with object" +#~ msgstr "Resimle boyutla" + +#, fuzzy +#~ msgid "centimeter" +#~ msgstr "İçerik" + +#, fuzzy +#~ msgid "millimeters" +#~ msgstr "Milimetre\n" + +#, fuzzy +#~ msgid "points" +#~ msgstr "Yazdır" + +#~ msgid "1.0MB" +#~ msgstr "1.0 MB" + +#~ msgid "Back One" +#~ msgstr "Bir geri" + +#~ msgid "Convert selected segments to curves" +#~ msgstr "Seçili bölümleri eğrilere dönüştür" + +#~ msgid "Cusp line at selected nodes" +#~ msgstr "Seçili noktalardaki çizgiyi tepele" + +#~ msgid "Desktop" +#~ msgstr "Masaüstü" + +#~ msgid "Drawing Context" +#~ msgstr "Çizim Kapsamı" + +#~ msgid "Export picture to png" +#~ msgstr "Resmi png olarak ithal et" + +#~ msgid "Forward One" +#~ msgstr "Bir ileri" + +#~ msgid "Include one node into selected segments" +#~ msgstr "Seçili bölümlere bir nokta koy" + +#~ msgid "Join 2 selected endpoints" +#~ msgstr "2 seçili bitiş noktasını birleştir" + +#~ msgid "Set dimensions" +#~ msgstr "Boyutları belirle" + +#~ msgid "Smooth line at selected nodes" +#~ msgstr "Seçili noktalardaki çizgiyi düzelt" + +#~ msgid "Where to export" +#~ msgstr "Ä°thal edilecek yer" + +#~ msgid "X0" +#~ msgstr "X0" + +#~ msgid "XML Tree" +#~ msgstr "XML Ağacı" + +#~ msgid "Y0" +#~ msgstr "Y0" + +#~ msgid "_Align" +#~ msgstr "_Hizala" + +#~ msgid "Break apart selected paths" +#~ msgstr "Seçilen yolları kopar" + +#, fuzzy +#~ msgid "Draw dynahand line" +#~ msgstr "Serbest şekiller çiz" + +#~ msgid "Drawing context" +#~ msgstr "Çizim kapsamı" + +#~ msgid "Edit font style of selected objects" +#~ msgstr "Seçili nesnelerin yazı tipini değiştir" + +#~ msgid "Import " +#~ msgstr "Ä°thal et" + +#~ msgid "New drawing" +#~ msgstr "Yeni çizim" + +#~ msgid "No I'd rather do some more cool vector drawing with sodipodi." +#~ msgstr "Hayır! Sodipodi ile çizime devam edeceğim." + +#~ msgid "Nope !" +#~ msgstr "Hayır !" + +#~ msgid "Open new drawing" +#~ msgstr "Yeni çizim aç" + +#~ msgid "Paste from clipboard" +#~ msgstr "Panodan yapıştır" + +#~ msgid "Preview print drawing" +#~ msgstr "Çizim yazdırma öngörünümü" + +#~ msgid "Quit or not quit ?" +#~ msgstr "Çıkıyormusun ?" + +#~ msgid "Really wanna quit sodipodi ?" +#~ msgstr "Gerçekten Sodipodi'den çıkacakmısınız ?" + +#, fuzzy +#~ msgid "Rotate selected objects 90deg clockwise" +#~ msgstr "Seçili nesneleri saat yönünde 90° dönder" + +#~ msgid "Save drawing " +#~ msgstr "Çizimi kaydet" + +#~ msgid "Yep !" +#~ msgstr "Evet !" + +#~ msgid "Yes quick! I want to leave sodipodi and come back later." +#~ msgstr "Evet! Sodipodi'ye daha sonra dönmek üzere." + +#, fuzzy +#~ msgid "Align to bottom middle" +#~ msgstr "Nesne içini alt kenara hizala" + +#, fuzzy +#~ msgid "Align to bottom right" +#~ msgstr "Nesne dışını sağ kenara hizala" + +#, fuzzy +#~ msgid "Choose metric for center" +#~ msgstr "Rehber çizgileri rengini seçiniz" + +#, fuzzy +#~ msgid "Close dialog - Ctl+c" +#~ msgstr "Diyalogu kapat" + +#, fuzzy +#~ msgid "Orig. Width: " +#~ msgstr " Genişlik " + +#, fuzzy +#~ msgid "Orig. X: " +#~ msgstr "Orijin X:" + +#, fuzzy +#~ msgid "Set angle to 0 degrees" +#~ msgstr "Sayfa genişliğini ayarla" + +#, fuzzy +#~ msgid "Set angle to 180 degrees" +#~ msgstr "Sayfa genişliğini ayarla" + +#, fuzzy +#~ msgid "Set angle to 270 degrees" +#~ msgstr "Sayfa genişliğini ayarla" + +#, fuzzy +#~ msgid "Start transformation - Ctl+a" +#~ msgstr "Dönüştürmeye başla" + +#, fuzzy +#~ msgid "Use alignment during transformation" +#~ msgstr "Dönüştürmeyi kaldır" + +#, fuzzy +#~ msgid "select direction" +#~ msgstr "Seçileni sil" + +#, fuzzy +#~ msgid "skew" +#~ msgstr "Eğilt" + +#~ msgid "Change Attribute" +#~ msgstr "Özelliği değiştir" + +#, fuzzy +#~ msgid "Change Content" +#~ msgstr "Çizim Kapsamı" + +#~ msgid "Do you want to delete attribute?" +#~ msgstr "Bu özelliği silmek istiyormusun?" + +#~ msgid "Hierarchy" +#~ msgstr "Hiyerarşi" + +#~ msgid "Key" +#~ msgstr "Anahtar" + +#, fuzzy +#~ msgid "New Element" +#~ msgstr "Yeni dosya" + +#, fuzzy +#~ msgid "You can't delete 'id' attribute!" +#~ msgstr "Bu özelliği silmek istiyormusun?" + +#, fuzzy +#~ msgid "Do you want to delete attribute %s?" +#~ msgstr "Bu özelliği silmek istiyormusun?" + +#, fuzzy +#~ msgid "No" +#~ msgstr "Nokta" + +#, fuzzy +#~ msgid "Do you want to delete element %s?" +#~ msgstr "Bu özelliği silmek istiyormusun?" + +#~ msgid "Choose base unit system for grid" +#~ msgstr "Izgara için temel birim sistemini seçiniz" + +#~ msgid "Millimeters\n" +#~ msgstr "Milimetre\n" + +#~ msgid "Choose color for grid" +#~ msgstr "Izgara rengini seçiniz" + +#~ msgid "Set maximum distance for grid snapping" +#~ msgstr "Izgara yakalamasının maksimum uzaklığını ayarla" + +#~ msgid "Choose unit system for grid snapping" +#~ msgstr "Izgara yakalama birim sistemini seçiniz" + +#~ msgid "Pixels\n" +#~ msgstr "Piksel\n" + +#~ msgid "Set origin of page coordinate system" +#~ msgstr "Sayfa koordinat sisteminin orijinini ayarla" + +#~ msgid "Choose unit system for guideline snapping" +#~ msgstr "Rehber çizgileri yakalama birim sistemini seç" + +#~ msgid "Set maximum distance for guideline snapping" +#~ msgstr "Rehber çizgileri yakalama maksimum aralığını seç" + +#~ msgid "Choose paper size" +#~ msgstr "Sayfa boyutunu seçin" + +#~ msgid "A4\n" +#~ msgstr "A4\n" + +#~ msgid "Set page height" +#~ msgstr "Sayfa yüksekliğini ayarla" + +#~ msgid "Copyright Lauris Kaplinski 1999-2000." +#~ msgstr "Telif hakkı Lauris Kaplinski 1999-2000" + +#~ msgid "" +#~ "A Vector Drawing Program.\n" +#~ "Released under GPL" +#~ msgstr "" +#~ "Bir Vektör Çizim Programı.\n" +#~ "GPL'e göre yayınlanmıştır" + +#~ msgid "Draw ellipse" +#~ msgstr "Elips çiz" + +#~ msgid "Dup" +#~ msgstr "Klon" + +#~ msgid "Del" +#~ msgstr "Sil" + +#~ msgid "Do not use GUI. NB! if exist, should be FIRST argument!" +#~ msgstr "Grafik arabirimini kullanma. NB! varsa, Ä°LK argüman olmalı!" + +#~ msgid "Could not initialize Bonobo" +#~ msgstr "Bonobo'yu başlatamadım" + +#~ msgid "Valige värv" +#~ msgstr "Valige (?)" + +#~ msgid "" +#~ "pixels\n" +#~ "millimeters\n" +#~ "centimeter\n" +#~ "points\n" +#~ "inches\n" +#~ msgstr "" +#~ "piksel\n" +#~ "milimetre\n" +#~ "santimetre\n" +#~ "nokta\n" +#~ "inç\n" + +#~ msgid "dashed" +#~ msgstr "kesik" + +#~ msgid "double" +#~ msgstr "çift" + +#~ msgid " Join " +#~ msgstr " Ekle " + +#~ msgid "butt" +#~ msgstr "alt" + +#~ msgid "y" +#~ msgstr "y" + +#~ msgid "Height " +#~ msgstr "Yükseklik " + +#~ msgid "" +#~ "px\n" +#~ "mm\n" +#~ "cm\n" +#~ "pt\n" +#~ "in\n" +#~ msgstr "" +#~ "px\n" +#~ "mm\n" +#~ "cm\n" +#~ "pt\n" +#~ "in\n" + +#, fuzzy +#~ msgid "" +#~ "px\n" +#~ "mm\n" +#~ "cm\n" +#~ "in\n" +#~ msgstr "" +#~ "px\n" +#~ "mm\n" +#~ "cm\n" +#~ "pt\n" +#~ "in\n" + +#, fuzzy +#~ msgid "" +#~ "pt\n" +#~ "mm\n" +#~ "cm\n" +#~ "in\n" +#~ msgstr "" +#~ "px\n" +#~ "mm\n" +#~ "cm\n" +#~ "pt\n" +#~ "in\n" + +#~ msgid "_New File" +#~ msgstr "_Yeni Dosya" + +#~ msgid "Toggles desktop borders (rulers and scrollbars on and off)" +#~ msgstr "Masaüstü kenarları aç/kapat (cetvel ve çubukları aç/kapat )" + +#~ msgid "Toggle borders" +#~ msgstr "Kenarları aç/kapat" + +#~ msgid "Groups selected items" +#~ msgstr "Seçili birimlrı gruplar" + +#~ msgid "Duplic\t" +#~ msgstr "Klonla\t" + +#~ msgid "Up" +#~ msgstr "Yukarı" + +#~ msgid "Lower one position" +#~ msgstr "Bir pozisyon alçalt" + +#~ msgid "Draw ellipses" +#~ msgstr "Elips çiz" + +#~ msgid "Write text" +#~ msgstr "Metin yaz" + +#~ msgid "Left button zooms in, right out" +#~ msgstr "Farenin sol tuşu büyültür, sağ tuşu küçültür" + +#~ msgid "" +#~ "10%\n" +#~ "25%\n" +#~ "50%\n" +#~ "75%\n" +#~ "100%\n" +#~ "150%\n" +#~ "200%\n" +#~ "300%\n" +#~ "500%\n" +#~ msgstr "" +#~ "%10\n" +#~ "%25\n" +#~ "%50\n" +#~ "%75\n" +#~ "%100\n" +#~ "%150\n" +#~ "%200\n" +#~ "%300\n" +#~ "%500\n" + +#~ msgid "100%" +#~ msgstr "%100" + +#~ msgid "" +#~ "pixel\n" +#~ "points\n" +#~ "millimeter\n" +#~ "centimeter\n" +#~ "inch\n" +#~ msgstr "" +#~ "piksel\n" +#~ "milimetre\n" +#~ "santimetre\n" +#~ "nokta\n" +#~ "inç\n" + +#~ msgid " Rotate " +#~ msgstr " Dönder " + +#~ msgid "90°" +#~ msgstr "90°" + +#~ msgid "180°" +#~ msgstr "180°" + +#~ msgid "270°" +#~ msgstr "270°" + +#~ msgid "any" +#~ msgstr "herhangi" + +#~ msgid "left" +#~ msgstr "sol" + +#~ msgid " flip " +#~ msgstr " tersine çevir " + +#~ msgid " Skew " +#~ msgstr " Eğilt " + +#~ msgid "make copy" +#~ msgstr "kopyala" + +#~ msgid "Guidelines setup" +#~ msgstr "Rehber ayarlaması" + +#~ msgid "close dialog" +#~ msgstr "diyalogu kapat" diff --git a/po/uk.po b/po/uk.po new file mode 100644 index 000000000..d87e10323 --- /dev/null +++ b/po/uk.po @@ -0,0 +1,9561 @@ +# Ukrainian translation of inkscape. +# Copyright (C) 2001 Free Software Foundation, Inc. +# Yuri Syrota , 2000. +# Maxim Dziumanenko , 2004-2005 +# Alex , 2005 +# +msgid "" +msgstr "" +"Project-Id-Version: inkscape\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2005-12-04 11:51-0800\n" +"PO-Revision-Date: 2005-10-21 13:33+0300\n" +"Last-Translator: Maxim V. Dziumanenko \n" +"Language-Team: Ukrainian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%" +"10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" + +#: ../inkscape.desktop.in.h:1 +msgid "Create and edit Scalable Vector Graphics images" +msgstr "Створення та редагування векторних графічних зображень" + +#: ../inkscape.desktop.in.h:2 +msgid "Inkscape SVG Vector Illustrator" +msgstr "Редактор векторної SVG-графіки Inkscape" + +#: ../../po/../src/arc-context.cpp:350 +msgid "" +"Ctrl: make circle or integer-ratio ellipse, snap arc/segment angle" +msgstr "" +"Ctrl: робить коло або еліпс з цілим відношенням сторін, обмежує кут " +"дуги/сектора" + +#: ../../po/../src/arc-context.cpp:351 ../../po/../src/rect-context.cpp:388 +msgid "Shift: draw around the starting point" +msgstr "Shift: малювати навколо початкової точки" + +#: ../../po/../src/arc-context.cpp:413 +#: ../../po/../src/connector-context.cpp:493 +#: ../../po/../src/dyna-draw-context.cpp:506 +#: ../../po/../src/pen-context.cpp:329 ../../po/../src/pencil-context.cpp:208 +#: ../../po/../src/rect-context.cpp:452 ../../po/../src/spiral-context.cpp:421 +#: ../../po/../src/star-context.cpp:427 +msgid "Current layer is hidden. Unhide it to be able to draw on it." +msgstr "" +"Поточний рівень - прихований. Зробіть його неприхованим, щоб мати " +"можливість креслити у ньому." + +#: ../../po/../src/arc-context.cpp:417 +#: ../../po/../src/connector-context.cpp:497 +#: ../../po/../src/dyna-draw-context.cpp:510 +#: ../../po/../src/pen-context.cpp:336 ../../po/../src/pencil-context.cpp:212 +#: ../../po/../src/rect-context.cpp:456 ../../po/../src/spiral-context.cpp:426 +#: ../../po/../src/star-context.cpp:431 +msgid "Current layer is locked. Unlock it to be able to draw on it." +msgstr "" +"Поточний рівень - замкнений. Розблокуйте його, щоб мати можливість " +"креслити у ньому." + +#: ../../po/../src/arc-context.cpp:496 +#, c-format +msgid "" +"Ellipse: %s × %s; with Ctrl to make circle or integer-" +"ratio ellipse; with Shift to draw around the starting point" +msgstr "" +"Еліпс: %s × %s; з натиснутим Ctrl робить коло або еліпс з " +"цілим відношенням сторін; з Shift малює навколо початкової точки" + +#: ../../po/../src/connector-context.cpp:518 +msgid "Creating new connector" +msgstr "Створення нової з'єднувальної лінії" + +#: ../../po/../src/connector-context.cpp:939 +msgid "Finishing connector" +msgstr "Завершення лінії з'єднання" + +#: ../../po/../src/connector-context.cpp:1108 +#, fuzzy +msgid "Connection point: click or drag to create a new connector" +msgstr "" +"Точка з'єднання: клацніть мишею або перетягніть для створення нової " +"лінії" + +#: ../../po/../src/connector-context.cpp:1185 +#, fuzzy +msgid "Connector endpoint: drag to reroute or connect to new shapes" +msgstr "" +"Кінцева з'єднувальна точка: перетягніть для повторного з'єднання або " +"з'єднання з новими фігурами" + +#: ../../po/../src/connector-context.cpp:1278 +msgid "Select at least one non-connector object." +msgstr "Виділіть принаймні два об'єкти для з'єднання." + +#: ../../po/../src/desktop-events.cpp:238 +#, c-format +msgid "%s at %s" +msgstr "%s у %s" + +#. TRANSLATORS: This string appears when double-clicking on a guide. +#. This is the distance by which the guide is to be moved. +#: ../../po/../src/desktop-events.cpp:277 +msgid " relative by " +msgstr " відносно до " + +#. TRANSLATORS: This string appears when double-clicking on a guide. +#. This is the target location where the guide is to be moved. +#: ../../po/../src/desktop-events.cpp:282 +#: ../../po/../src/desktop-events.cpp:395 +msgid " absolute to " +msgstr " абсолютно до " + +#. create dialog +#: ../../po/../src/desktop-events.cpp:348 +msgid "Guideline" +msgstr "Напрямна" + +#: ../../po/../src/desktop-events.cpp:432 +#, c-format +msgid "Move %s" +msgstr "Перемістити %s" + +#: ../../po/../src/desktop.cpp:678 +msgid "No previous zoom." +msgstr "Немає попереднього масштабу." + +#: ../../po/../src/desktop.cpp:703 +msgid "No next zoom." +msgstr "Немає наступного масштабу." + +#: ../../po/../src/dialogs/clonetiler.cpp:182 +msgid "Nothing selected." +msgstr "Нічого не виділено." + +#: ../../po/../src/dialogs/clonetiler.cpp:188 +msgid "More than one object selected." +msgstr "Виділено більше ніж один об'єкт." + +#: ../../po/../src/dialogs/clonetiler.cpp:195 +#, c-format +msgid "Object has %d tiled clones." +msgstr "Об'єкт має%d мозаїчних клонів." + +#: ../../po/../src/dialogs/clonetiler.cpp:200 +msgid "Object has no tiled clones." +msgstr "Об'єкт не має мозаїчних клонів." + +#: ../../po/../src/dialogs/clonetiler.cpp:865 +msgid "Select one object whose tiled clones to unclump." +msgstr "Виділіть один об'єкт, клони якого слід розгрупувати." + +#: ../../po/../src/dialogs/clonetiler.cpp:916 +msgid "Select one object whose tiled clones to remove." +msgstr "Виділіть один об'єкт, клони якого слід видалити." + +#: ../../po/../src/dialogs/clonetiler.cpp:984 +#: ../../po/../src/selection-chemistry.cpp:1774 +msgid "Select an object to clone." +msgstr "Виділіть об'єкт для клонування." + +#: ../../po/../src/dialogs/clonetiler.cpp:990 +#: ../../po/../src/selection-chemistry.cpp:1780 +msgid "" +"If you want to clone several objects, group them and clone the " +"group." +msgstr "" +"Для клонування кількох об'єктів, згрупуйте їх та клонуйте групу." + +#: ../../po/../src/dialogs/clonetiler.cpp:1484 +msgid "Per row:" +msgstr "У рядку:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1497 +msgid "Per column:" +msgstr "У стовпчику:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1505 +msgid "Randomize:" +msgstr "Випадковість:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1656 +msgid "_Symmetry" +msgstr "_Симетрія" + +#. TRANSLATORS: For the following 17 symmetry groups, see +#. * http://www.bib.ulb.ac.be/coursmath/doc/17.htm (visual examples); +#. * http://www.clarku.edu/~djoyce/wallpaper/seventeen.html (English vocabulary); or +#. * http://membres.lycos.fr/villemingerard/Geometri/Sym1D.htm (French vocabulary). +#. +#: ../../po/../src/dialogs/clonetiler.cpp:1664 +msgid "Select one of the 17 symmetry groups for the tiling" +msgstr "Виберіть одну з 17 груп симетрії для мозаїки" + +#. TRANSLATORS: "translation" means "shift" / "displacement" here. +#: ../../po/../src/dialogs/clonetiler.cpp:1675 +msgid "P1: simple translation" +msgstr "P1: простий зсув" + +#: ../../po/../src/dialogs/clonetiler.cpp:1676 +msgid "P2: 180° rotation" +msgstr "P2: обертання на 180°" + +#: ../../po/../src/dialogs/clonetiler.cpp:1677 +msgid "PM: reflection" +msgstr "PM: віддзеркалення" + +#. TRANSLATORS: "glide reflection" is a reflection and a translation combined. +#. For more info, see http://mathforum.org/sum95/suzanne/symsusan.html +#: ../../po/../src/dialogs/clonetiler.cpp:1680 +msgid "PG: glide reflection" +msgstr "PG: ковзне віддзеркалення" + +#: ../../po/../src/dialogs/clonetiler.cpp:1681 +msgid "CM: reflection + glide reflection" +msgstr "CM: віддзеркалення + ковзне віддзеркалення" + +#: ../../po/../src/dialogs/clonetiler.cpp:1682 +msgid "PMM: reflection + reflection" +msgstr "PMM: віддзеркалення + віддзеркалення" + +#: ../../po/../src/dialogs/clonetiler.cpp:1683 +msgid "PMG: reflection + 180° rotation" +msgstr "PMG: віддзеркалення + обертання на 180°" + +#: ../../po/../src/dialogs/clonetiler.cpp:1684 +msgid "PGG: glide reflection + 180° rotation" +msgstr "PGG: ковзне віддзеркалення + обертання на 180°" + +#: ../../po/../src/dialogs/clonetiler.cpp:1685 +msgid "CMM: reflection + reflection + 180° rotation" +msgstr "CMM: віддзеркалення + віддзеркалення + обертання на 180°" + +#: ../../po/../src/dialogs/clonetiler.cpp:1686 +msgid "P4: 90° rotation" +msgstr "P4: обертання на 90°" + +#: ../../po/../src/dialogs/clonetiler.cpp:1687 +msgid "P4M: 90° rotation + 45° reflection" +msgstr "P4M: обертання на 90° + обертання на 45°" + +#: ../../po/../src/dialogs/clonetiler.cpp:1688 +msgid "P4G: 90° rotation + 90° reflection" +msgstr "P4G: обертання на 90° + обертання на 90°" + +#: ../../po/../src/dialogs/clonetiler.cpp:1689 +msgid "P3: 120° rotation" +msgstr "P3: обертання на 120°" + +#: ../../po/../src/dialogs/clonetiler.cpp:1690 +msgid "P31M: reflection + 120° rotation, dense" +msgstr "P31M: віддзеркалення + обертання на 120°, щільне" + +#: ../../po/../src/dialogs/clonetiler.cpp:1691 +msgid "P3M1: reflection + 120° rotation, sparse" +msgstr "P3M1: віддзеркалення + обертання на 120°, розсіяне" + +#: ../../po/../src/dialogs/clonetiler.cpp:1692 +msgid "P6: 60° rotation" +msgstr "P6: обертання на 60°" + +#: ../../po/../src/dialogs/clonetiler.cpp:1693 +msgid "P6M: reflection + 60° rotation" +msgstr "P6M: віддзеркалення + обертання на 60°" + +#: ../../po/../src/dialogs/clonetiler.cpp:1721 +msgid "S_hift" +msgstr "Зс_ув" + +#. TRANSLATORS: "shift" means: the tiles will be shifted (offset) horizontally by this amount +#: ../../po/../src/dialogs/clonetiler.cpp:1731 +#, no-c-format +msgid "Shift X:" +msgstr "Зсув за віссю X:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1739 +#, no-c-format +msgid "Horizontal shift per row (in % of tile width)" +msgstr "Горизонтальний зсув на кожен рядок (у % від ширини плитки)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1747 +#, no-c-format +msgid "Horizontal shift per column (in % of tile width)" +msgstr "Горизонтальний зсув на кожен стовпчик (у % від ширини плитки)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1754 +msgid "Randomize the horizontal shift by this percentage" +msgstr "Випадковий горизонтальний зсув не більше ніж на на даний відсоток" + +#. TRANSLATORS: "shift" means: the tiles will be shifted (offset) vertically by this amount +#: ../../po/../src/dialogs/clonetiler.cpp:1764 +#, no-c-format +msgid "Shift Y:" +msgstr "Зсув за віссю Y:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1772 +#, no-c-format +msgid "Vertical shift per row (in % of tile height)" +msgstr "Вертикальний зсув на кожен рядок (у % від висоти плитки)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1780 +#, no-c-format +msgid "Vertical shift per column (in % of tile height)" +msgstr "Вертикальний зсув на кожен стовпчик (у % від висоти плитки)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1787 +msgid "Randomize the vertical shift by this percentage" +msgstr "Випадковий вертикальний зсув не більше ніж на даний відсоток" + +#: ../../po/../src/dialogs/clonetiler.cpp:1795 +msgid "Exponent:" +msgstr "Експоненціально:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1802 +msgid "Whether rows are spaced evenly (1), converge (<1) or diverge (>1)" +msgstr "" +"Спосіб розстановки проміжку між рядками: рівномірно (1), зближення (<1) чи " +"розходження (>1)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1809 +msgid "Whether columns are spaced evenly (1), converge (<1) or diverge (>1)" +msgstr "" +"Спосіб розстановки проміжку між стовпчиками: рівномірно (1), зближення (<1) " +"чи розходження (>1)" + +#. TRANSLATORS: "Alternate" is a verb here +#: ../../po/../src/dialogs/clonetiler.cpp:1817 +#: ../../po/../src/dialogs/clonetiler.cpp:1907 +#: ../../po/../src/dialogs/clonetiler.cpp:1966 +#: ../../po/../src/dialogs/clonetiler.cpp:2022 +#: ../../po/../src/dialogs/clonetiler.cpp:2153 +msgid "Alternate:" +msgstr "Чергування:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1823 +msgid "Alternate the sign of shifts for each row" +msgstr "Чергувати знак зсувів кожного рядка та стовпчика" + +#: ../../po/../src/dialogs/clonetiler.cpp:1828 +msgid "Alternate the sign of shifts for each column" +msgstr "Чергувати знак зсувів кожного рядка та стовпчика" + +#: ../../po/../src/dialogs/clonetiler.cpp:1837 +msgid "Sc_ale" +msgstr "Мас_штабувати" + +#: ../../po/../src/dialogs/clonetiler.cpp:1845 +msgid "Scale X:" +msgstr "Масштабувати X:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1853 +#, no-c-format +msgid "Horizontal scale per row (in % of tile width)" +msgstr "Горизонтальний масштаб на кожен рядок (у % від ширини плитки)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1861 +#, no-c-format +msgid "Horizontal scale per column (in % of tile width)" +msgstr "Горизонтальний масштаб на кожен стовпчик (у % від ширини плитки)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1868 +msgid "Randomize the horizontal scale by this percentage" +msgstr "" +"Випадково змінити горизонтальний масштаб не більше ніж на даний відсоток" + +#: ../../po/../src/dialogs/clonetiler.cpp:1876 +msgid "Scale Y:" +msgstr "Масштабувати Y:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1884 +#, no-c-format +msgid "Vertical scale per row (in % of tile height)" +msgstr "Вертикальний масштаб на кожен рядок (у % від висоти плитки)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1892 +#, no-c-format +msgid "Vertical scale per column (in % of tile height)" +msgstr "Вертикальний масштаб на кожен стовпчик (у % від висоти плитки)" + +#: ../../po/../src/dialogs/clonetiler.cpp:1899 +msgid "Randomize the vertical scale by this percentage" +msgstr "Випадково змінити вертикальний масштаб не більше ніж на даний відсоток" + +#: ../../po/../src/dialogs/clonetiler.cpp:1913 +msgid "Alternate the sign of scales for each row" +msgstr "Чергувати знак зміни масштабу для кожного рядка" + +#: ../../po/../src/dialogs/clonetiler.cpp:1918 +msgid "Alternate the sign of scales for each column" +msgstr "Чергувати знак зміни масштабу для кожного стовпчика" + +#: ../../po/../src/dialogs/clonetiler.cpp:1927 +msgid "_Rotation" +msgstr "_Обертання" + +#: ../../po/../src/dialogs/clonetiler.cpp:1935 +msgid "Angle:" +msgstr "Кут:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1943 +#, no-c-format +msgid "Rotate tiles by this angle for each row" +msgstr "Обертати плитки на цей кут на кожен рядок" + +#: ../../po/../src/dialogs/clonetiler.cpp:1951 +#, no-c-format +msgid "Rotate tiles by this angle for each column" +msgstr "Обертати плитки на цей кут на кожен стовпчик" + +#: ../../po/../src/dialogs/clonetiler.cpp:1958 +msgid "Randomize the rotation angle by this percentage" +msgstr "Випадковий кут обертання не більше ніж на даний відсоток" + +#: ../../po/../src/dialogs/clonetiler.cpp:1972 +msgid "Alternate the rotation direction for each row" +msgstr "Чергувати напрямок обертання на кожен рядок" + +#: ../../po/../src/dialogs/clonetiler.cpp:1977 +msgid "Alternate the rotation direction for each column" +msgstr "Чергувати напрямок обертання на кожен стовпчик" + +#: ../../po/../src/dialogs/clonetiler.cpp:1985 +msgid "_Opacity" +msgstr "_Непрозорість" + +#: ../../po/../src/dialogs/clonetiler.cpp:1993 +msgid "Fade out:" +msgstr "Згасання:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2000 +msgid "Decrease tile opacity by this percentage for each row" +msgstr "Зменшувати непрозорість плитки на цей відсоток на кожен рядок" + +#: ../../po/../src/dialogs/clonetiler.cpp:2007 +msgid "Decrease tile opacity by this percentage for each column" +msgstr "Зменшувати непрозорість плитки на цей відсоток на кожен стовпчик" + +#: ../../po/../src/dialogs/clonetiler.cpp:2014 +msgid "Randomize the tile opacity by this percentage" +msgstr "Випадкова непрозорість плитки не більше ніж на даний відсоток" + +#: ../../po/../src/dialogs/clonetiler.cpp:2028 +msgid "Alternate the sign of opacity change for each row" +msgstr "Чергувати знак зміни непрозорості на кожен рядок" + +#: ../../po/../src/dialogs/clonetiler.cpp:2033 +msgid "Alternate the sign of opacity change for each column" +msgstr "Чергувати знак зміни непрозорості на кожен стовпчик" + +#: ../../po/../src/dialogs/clonetiler.cpp:2041 +msgid "Co_lor" +msgstr "_Колір" + +#: ../../po/../src/dialogs/clonetiler.cpp:2046 +msgid "Initial color: " +msgstr "Початковий колір:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2050 +msgid "Initial color of tiled clones" +msgstr "Початковий колір для клонів" + +#: ../../po/../src/dialogs/clonetiler.cpp:2050 +msgid "" +"Initial color for clones (works only if the original has unset fill or " +"stroke)" +msgstr "" +"Початковий колір для клонів (працює лише якщо для оригіналу не встановлено " +"заповнення чи штрих)" + +#: ../../po/../src/dialogs/clonetiler.cpp:2065 +msgid "H:" +msgstr "H:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2072 +msgid "Change the tile hue by this percentage for each row" +msgstr "Змінювати відтінок плитки на цей відсоток на кожен рядок" + +#: ../../po/../src/dialogs/clonetiler.cpp:2079 +msgid "Change the tile hue by this percentage for each column" +msgstr "Зменшувати відтінок плитки на цей відсоток на кожен стовпчик" + +#: ../../po/../src/dialogs/clonetiler.cpp:2086 +msgid "Randomize the tile hue by this percentage" +msgstr "Випадкова зміна відтінку плитки не більше ніж на даний відсоток" + +#: ../../po/../src/dialogs/clonetiler.cpp:2095 +msgid "S:" +msgstr "S:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2102 +msgid "Change the color saturation by this percentage for each row" +msgstr "Змінювати насиченіть на цей відсоток на кожен рядок" + +#: ../../po/../src/dialogs/clonetiler.cpp:2109 +msgid "Change the color saturation by this percentage for each column" +msgstr "Змінювати насиченість на цей відсоток на кожен стовпчик" + +#: ../../po/../src/dialogs/clonetiler.cpp:2116 +msgid "Randomize the color saturation by this percentage" +msgstr "Випадкова зміна насиченості кольору не більше ніж на даний відсоток" + +#: ../../po/../src/dialogs/clonetiler.cpp:2124 +msgid "L:" +msgstr "L:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2131 +msgid "Change the color lightness by this percentage for each row" +msgstr "Змінювати яскравість плитки на цей відсоток на кожен рядок" + +#: ../../po/../src/dialogs/clonetiler.cpp:2138 +msgid "Change the color lightness by this percentage for each column" +msgstr "Змінювати яскравість плитки на цей відсоток на кожен стовпчик" + +#: ../../po/../src/dialogs/clonetiler.cpp:2145 +msgid "Randomize the color lightness by this percentage" +msgstr "Випадкова зміна яскравості плитки не більше ніж на даний відсоток" + +#: ../../po/../src/dialogs/clonetiler.cpp:2159 +msgid "Alternate the sign of color changes for each row" +msgstr "Чергувати знак зміни кольору на кожен рядок" + +#: ../../po/../src/dialogs/clonetiler.cpp:2164 +msgid "Alternate the sign of color changes for each column" +msgstr "Чергувати знак зміни кольору на кожен стовпчик" + +#: ../../po/../src/dialogs/clonetiler.cpp:2172 +msgid "_Trace" +msgstr "_Векторизувати растр" + +#: ../../po/../src/dialogs/clonetiler.cpp:2179 +msgid "Trace the drawing under the tiles" +msgstr "Векторизувати область за плитками" + +#: ../../po/../src/dialogs/clonetiler.cpp:2183 +msgid "" +"For each clone, pick a value from the drawing in that clone's location and " +"apply it to the clone" +msgstr "" +"Для кожного клону, вибрати значення під клоном та застосувати його до клону" + +#: ../../po/../src/dialogs/clonetiler.cpp:2197 +msgid "1. Pick from the drawing:" +msgstr "1. Взяти значення:" + +#. ----Hbox2 +#: ../../po/../src/dialogs/clonetiler.cpp:2208 +#: ../../po/../src/dialogs/clonetiler.cpp:2355 +#: ../../po/../src/ui/dialog/tracedialog.cpp:445 +msgid "Color" +msgstr "Колір" + +#: ../../po/../src/dialogs/clonetiler.cpp:2209 +msgid "Pick the visible color and opacity" +msgstr "Взяти видимий колір і прозорість" + +#: ../../po/../src/dialogs/clonetiler.cpp:2216 +#: ../../po/../src/dialogs/clonetiler.cpp:2365 +#: ../share/extensions/dropshadow.inx.h:3 +msgid "Opacity" +msgstr "Непрозорість" + +#: ../../po/../src/dialogs/clonetiler.cpp:2217 +msgid "Pick the total accumulated opacity" +msgstr "Взяти сумарну непрозорість у кожній точці" + +#: ../../po/../src/dialogs/clonetiler.cpp:2224 +msgid "R" +msgstr "R" + +#: ../../po/../src/dialogs/clonetiler.cpp:2225 +msgid "Pick the Red component of the color" +msgstr "Взяти червону компоненту кольору" + +#: ../../po/../src/dialogs/clonetiler.cpp:2232 +msgid "G" +msgstr "G" + +#: ../../po/../src/dialogs/clonetiler.cpp:2233 +msgid "Pick the Green component of the color" +msgstr "Взяти зелену компоненту кольору" + +#: ../../po/../src/dialogs/clonetiler.cpp:2240 +msgid "B" +msgstr "B" + +#: ../../po/../src/dialogs/clonetiler.cpp:2241 +msgid "Pick the Blue component of the color" +msgstr "Взяти блакитну компоненту кольору" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2250 +msgid "clonetiler|H" +msgstr "clonetiler|H" + +#: ../../po/../src/dialogs/clonetiler.cpp:2251 +msgid "Pick the hue of the color" +msgstr "Взяти відтінок кольору" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2260 +msgid "clonetiler|S" +msgstr "clonetiler|S" + +#: ../../po/../src/dialogs/clonetiler.cpp:2261 +msgid "Pick the saturation of the color" +msgstr "Взяти насиченість кольору" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2270 +msgid "clonetiler|L" +msgstr "clonetiler|L" + +#: ../../po/../src/dialogs/clonetiler.cpp:2271 +msgid "Pick the lightness of the color" +msgstr "Взяти яскравість кольору" + +#: ../../po/../src/dialogs/clonetiler.cpp:2281 +msgid "2. Tweak the picked value:" +msgstr "2. Змінити взяте значення:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2291 +msgid "Gamma-correct:" +msgstr "Гамма-корекція:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2296 +msgid "Shift the mid-range of the picked value upwards (>0) or downwards (<0)" +msgstr "Зсунути середину діапазону взятих значень вгору (>0) чи вниз (<0)" + +#: ../../po/../src/dialogs/clonetiler.cpp:2303 +msgid "Randomize:" +msgstr "Випадково:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2308 +msgid "Randomize the picked value by this percentage" +msgstr "Випадково міняти взяте значення, максимум на даний відсоток" + +#: ../../po/../src/dialogs/clonetiler.cpp:2315 +msgid "Invert:" +msgstr "Інвертувати:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2319 +msgid "Invert the picked value" +msgstr "Інвертувати взяте значення" + +#: ../../po/../src/dialogs/clonetiler.cpp:2325 +msgid "3. Apply the value to the clones':" +msgstr "3. Застосувати це значення до клонів:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2335 +msgid "Presence" +msgstr "Наявність" + +#: ../../po/../src/dialogs/clonetiler.cpp:2338 +msgid "" +"Each clone is created with the probability determined by the picked value in " +"that point" +msgstr "" +"Ймовірність появи кожного клону визначається значенням, взятим у даній точці" + +#: ../../po/../src/dialogs/clonetiler.cpp:2345 +msgid "Size" +msgstr "Розмір" + +#: ../../po/../src/dialogs/clonetiler.cpp:2348 +msgid "Each clone's size is determined by the picked value in that point" +msgstr "Розмір кожного клону визначається значенням, взятим у даній точці" + +#: ../../po/../src/dialogs/clonetiler.cpp:2358 +msgid "" +"Each clone is painted by the picked color (the original must have unset fill " +"or stroke)" +msgstr "" +"Кожен клон фарбується взятим у даній точці кольором (оригінал не повинен " +"мати власний колір чи штрих)" + +#: ../../po/../src/dialogs/clonetiler.cpp:2368 +msgid "Each clone's opacity is determined by the picked value in that point" +msgstr "" +"Прозорість кожного кольору визначається значенням, взятим у даній точці" + +#: ../../po/../src/dialogs/clonetiler.cpp:2395 +msgid "How many rows in the tiling" +msgstr "Кількість рядків у мозаїці" + +#: ../../po/../src/dialogs/clonetiler.cpp:2415 +msgid "How many columns in the tiling" +msgstr "Кількість стовпчиків у мозаїці" + +#: ../../po/../src/dialogs/clonetiler.cpp:2445 +msgid "Width of the rectangle to be filled" +msgstr "Ширина області, що заповнюється" + +#: ../../po/../src/dialogs/clonetiler.cpp:2470 +msgid "Height of the rectangle to be filled" +msgstr "Висота області, що заповнюється" + +#: ../../po/../src/dialogs/clonetiler.cpp:2485 +msgid "Rows, columns: " +msgstr "Рядків, стовпчиків: " + +#: ../../po/../src/dialogs/clonetiler.cpp:2486 +msgid "Create the specified number of rows and columns" +msgstr "Створити вказану кількість рядків та стовпчиків" + +#: ../../po/../src/dialogs/clonetiler.cpp:2495 +msgid "Width, height: " +msgstr "Ширина, висота: " + +#: ../../po/../src/dialogs/clonetiler.cpp:2496 +msgid "Fill the specified width and height with the tiling" +msgstr "Заповнити мозаїкою вказану область" + +#: ../../po/../src/dialogs/clonetiler.cpp:2512 +msgid "Use saved size and position of the tile" +msgstr "Використовувати збережені розмір та позицію плитки" + +#: ../../po/../src/dialogs/clonetiler.cpp:2515 +msgid "" +"Pretend that the size and position of the tile are the same as the last time " +"you tiled it (if any), instead of using the current size" +msgstr "" +"Сприяти, щоб розмір та позиція плиток були такі самі, як і останнього разу, " +"коли ви їх розбивали на мозаїку, замість використання поточного розміру" + +#: ../../po/../src/dialogs/clonetiler.cpp:2539 +msgid " _Create " +msgstr "_Створити " + +#: ../../po/../src/dialogs/clonetiler.cpp:2541 +msgid "Create and tile the clones of the selection" +msgstr "Створити мозаїку з клонів виділеної ділянки" + +#. TRANSLATORS: if a group of objects are "clumped" together, then they +#. are unevenly spread in the given amount of space - as shown in the +#. diagrams on the left in the following screenshot: +#. http://www.inkscape.org/screenshots/gallery/inkscape-0.42-CVS-tiles-unclump.png +#. So unclumping is the process of spreading a number of objects out more evenly. +#: ../../po/../src/dialogs/clonetiler.cpp:2556 +msgid " _Unclump " +msgstr "_Розгрупувати" + +#: ../../po/../src/dialogs/clonetiler.cpp:2557 +msgid "Spread out clones to reduce clumping; can be applied repeatedly" +msgstr "" +"Розповсюдити клони для послаблення групування; може бути застосовано повторно" + +#: ../../po/../src/dialogs/clonetiler.cpp:2563 +msgid " Re_move " +msgstr "В_идалити " + +#: ../../po/../src/dialogs/clonetiler.cpp:2564 +msgid "Remove existing tiled clones of the selected object (siblings only)" +msgstr "" +"Видалити існуючі мозаїчні клони виділеного об'єкту (лише нащадків одного " +"об'єкту)" + +#: ../../po/../src/dialogs/clonetiler.cpp:2580 +msgid " R_eset " +msgstr "С_кинути " + +#. TRANSLATORS: "change" is a noun here +#: ../../po/../src/dialogs/clonetiler.cpp:2582 +msgid "" +"Reset all shifts, scales, rotates, opacity and color changes in the dialog " +"to zero" +msgstr "" +"Скинути усі зсуви, масштабування, обертання та зміни прозорості й кольору на " +"нуль" + +#: ../../po/../src/dialogs/color-picker.cpp:280 +msgid "Close" +msgstr "Закрити" + +#: ../../po/../src/dialogs/debugdialog.cpp:138 +msgid "Messages" +msgstr "Повідомлення" + +#. ## Add a menu for clear() +#: ../../po/../src/dialogs/debugdialog.cpp:144 +#: ../../po/../src/menus-skeleton.h:16 +#: ../../po/../src/ui/dialog/messages.cpp:56 +#: ../../po/../src/ui/dialog/scriptdialog.cpp:181 +msgid "_File" +msgstr "_Файл" + +#. TRANSLATORS: "Clear" is a verb here +#: ../../po/../src/dialogs/debugdialog.cpp:145 +#: ../../po/../src/dialogs/find.cpp:753 +#: ../../po/../src/ui/dialog/messages.cpp:57 +#: ../../po/../src/ui/dialog/scriptdialog.cpp:182 +msgid "_Clear" +msgstr "О_чистити" + +#: ../../po/../src/dialogs/debugdialog.cpp:147 +#: ../../po/../src/ui/dialog/messages.cpp:59 +msgid "Capture log messages" +msgstr "Зберігати налагоджувальні повідомлення" + +#: ../../po/../src/dialogs/debugdialog.cpp:149 +#: ../../po/../src/ui/dialog/messages.cpp:61 +msgid "Release log messages" +msgstr "Відключити збереження налагоджувальних повідомлень" + +#. Notebook tab +#: ../../po/../src/dialogs/desktop-properties.cpp:909 +#: ../../po/../src/ui/dialog/document-preferences.cpp:89 +#: ../../po/../src/ui/widget/panel.cpp:107 +msgid "Grid" +msgstr "Сітка" + +#. Checkbuttons +#. / \todo FIXME: gray out snapping when grid is off +#. / \todo FIXME: gray out snapping when grid is off. +#. / Dissenting view: you want snapping without grid. +#: ../../po/../src/dialogs/desktop-properties.cpp:917 +#: ../../po/../src/ui/dialog/document-preferences.cpp:179 +msgid "Show grid" +msgstr "Показувати сітку" + +#: ../../po/../src/dialogs/desktop-properties.cpp:917 +#: ../../po/../src/ui/dialog/document-preferences.cpp:179 +#: ../../po/../src/verbs.cpp:2115 +msgid "Show or hide grid" +msgstr "Показати або сховати сітку" + +#: ../../po/../src/dialogs/desktop-properties.cpp:918 +#: ../../po/../src/ui/dialog/document-preferences.cpp:180 +msgid "Snap bounding boxes to grid" +msgstr "Рамки об'єктів прилипають до сітки" + +#: ../../po/../src/dialogs/desktop-properties.cpp:918 +#: ../../po/../src/dialogs/desktop-properties.cpp:1001 +#: ../../po/../src/ui/dialog/document-preferences.cpp:181 +#: ../../po/../src/ui/dialog/document-preferences.cpp:236 +msgid "Snap the edges of the object bounding boxes" +msgstr "Прив'язувати межі прямокутника, що обмежує об'єкт" + +#: ../../po/../src/dialogs/desktop-properties.cpp:919 +#: ../../po/../src/ui/dialog/document-preferences.cpp:183 +msgid "Snap nodes to grid" +msgstr "Точки контурів прилипають до сітки" + +#: ../../po/../src/dialogs/desktop-properties.cpp:919 +#: ../../po/../src/dialogs/desktop-properties.cpp:1002 +#: ../../po/../src/ui/dialog/document-preferences.cpp:184 +#: ../../po/../src/ui/dialog/document-preferences.cpp:239 +msgid "Snap path nodes, text baselines, ellipse centers, etc." +msgstr "Прив'язувати вузли контуру, базові лінії тексту, центри еліпсів, тощо." + +#: ../../po/../src/dialogs/desktop-properties.cpp:937 +#: ../../po/../src/ui/dialog/document-preferences.cpp:186 +msgid "Grid units:" +msgstr "Одиниці сітки:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:939 +#: ../../po/../src/ui/dialog/document-preferences.cpp:187 +msgid "Origin X:" +msgstr "Початок по X:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:942 +#: ../../po/../src/ui/dialog/document-preferences.cpp:189 +msgid "Origin Y:" +msgstr "Початок по Y:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:945 +#: ../../po/../src/ui/dialog/document-preferences.cpp:191 +msgid "Spacing X:" +msgstr "Інтервал по X:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:948 +#: ../../po/../src/ui/dialog/document-preferences.cpp:193 +msgid "Spacing Y:" +msgstr "Інтервал по Y:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:952 +#: ../../po/../src/dialogs/desktop-properties.cpp:1013 +#: ../../po/../src/ui/dialog/document-preferences.cpp:195 +#: ../../po/../src/ui/dialog/document-preferences.cpp:241 +msgid "Snap units:" +msgstr "Одиниці прилипання:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:955 +#: ../../po/../src/dialogs/desktop-properties.cpp:1016 +#: ../../po/../src/ui/dialog/document-preferences.cpp:196 +#: ../../po/../src/ui/dialog/document-preferences.cpp:242 +msgid "Snap distance:" +msgstr "Зона прилипання:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:958 +#: ../../po/../src/ui/dialog/document-preferences.cpp:199 +msgid "Grid line color:" +msgstr "Колір ліній сітки:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:959 +#: ../../po/../src/ui/dialog/document-preferences.cpp:199 +msgid "Grid line color" +msgstr "Колір ліній сітки" + +#: ../../po/../src/dialogs/desktop-properties.cpp:959 +#: ../../po/../src/ui/dialog/document-preferences.cpp:200 +msgid "Color of grid lines" +msgstr "Колір ліній сітки" + +#: ../../po/../src/dialogs/desktop-properties.cpp:961 +#: ../../po/../src/ui/dialog/document-preferences.cpp:201 +msgid "Major grid line color:" +msgstr "Колір основної лінії:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:962 +#: ../../po/../src/ui/dialog/document-preferences.cpp:201 +msgid "Major grid line color" +msgstr "Колір основної лінії сітки" + +#: ../../po/../src/dialogs/desktop-properties.cpp:962 +#: ../../po/../src/ui/dialog/document-preferences.cpp:202 +msgid "Color of the major (highlighted) grid lines" +msgstr "Колір основних (підсвічених) ліній сітки" + +#: ../../po/../src/dialogs/desktop-properties.cpp:965 +#: ../../po/../src/ui/dialog/document-preferences.cpp:204 +msgid "Major grid line every:" +msgstr "Основна лінія через кожні:" + +#. TRANSLATORS: This belongs to the "Major grid line every:" string, +#. see grid settings in the "Document Preferences" dialog +#: ../../po/../src/dialogs/desktop-properties.cpp:977 +#: ../../po/../src/ui/dialog/document-preferences.cpp:204 +msgid "lines" +msgstr "ліній" + +#. Guidelines page +#: ../../po/../src/dialogs/desktop-properties.cpp:991 +#: ../../po/../src/ui/dialog/document-preferences.cpp:90 +msgid "Guides" +msgstr "Напрямні" + +#. / \todo FIXME: gray out snapping when guides are off +#. / Dissenting view: you want snapping without guides. +#: ../../po/../src/dialogs/desktop-properties.cpp:1000 +#: ../../po/../src/ui/dialog/document-preferences.cpp:234 +msgid "Show guides" +msgstr "Показувати напрямні" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1000 +#: ../../po/../src/ui/dialog/document-preferences.cpp:234 +#: ../../po/../src/verbs.cpp:2116 +msgid "Show or hide guides" +msgstr "Показати/сховати напрямні" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1001 +#: ../../po/../src/ui/dialog/document-preferences.cpp:235 +msgid "Snap bounding boxes to guides" +msgstr "Рамки об'єктів прилипають до напрямних" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1002 +#: ../../po/../src/ui/dialog/document-preferences.cpp:238 +msgid "Snap points to guides" +msgstr "Точки контуру прилипають до напрямних" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1020 +#: ../../po/../src/ui/dialog/document-preferences.cpp:243 +msgid "Guide color:" +msgstr "Колір напрямних:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1021 +#: ../../po/../src/ui/dialog/document-preferences.cpp:243 +msgid "Guideline color" +msgstr "Колір напрямних" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1021 +#: ../../po/../src/ui/dialog/document-preferences.cpp:244 +msgid "Color of guidelines" +msgstr "Колір напрямних" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1023 +#: ../../po/../src/ui/dialog/document-preferences.cpp:245 +msgid "Highlight color:" +msgstr "Колір підсвічення:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1024 +#: ../../po/../src/ui/dialog/document-preferences.cpp:245 +msgid "Highlighted guideline color" +msgstr "Колір підсвіченої напрямної" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1024 +#: ../../po/../src/ui/dialog/document-preferences.cpp:246 +msgid "Color of a guideline when it is under mouse" +msgstr "Колір напрямної при наведенні на неї миші" + +#. Page page +#: ../../po/../src/dialogs/desktop-properties.cpp:1029 +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:855 +#: ../../po/../src/ui/dialog/document-preferences.cpp:88 +#: ../../po/../src/widgets/desktop-widget.cpp:1061 +msgid "Page" +msgstr "Сторінка" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1039 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +msgid "Background:" +msgstr "Колір тла:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1040 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +msgid "Background color" +msgstr "Колір тла" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1041 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +msgid "" +"Color and transparency of the page background (also used for bitmap export)" +msgstr "" +"Колір та прозорість тла сторінки (враховується при експортуванні у растр)" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1045 +#: ../../po/../src/ui/dialog/document-preferences.cpp:147 +#, fuzzy +msgid "Show page border" +msgstr "Показувати рамку полотна" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1049 +#: ../../po/../src/ui/dialog/document-preferences.cpp:148 +msgid "Border on top of drawing" +msgstr "Рамка полотна завжди над малюнком" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1052 +#: ../../po/../src/ui/dialog/document-preferences.cpp:149 +msgid "Border color:" +msgstr "Колір рамки:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1053 +#: ../../po/../src/ui/dialog/document-preferences.cpp:149 +#, fuzzy +msgid "Page border color" +msgstr "Колір рамки полотна" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1054 +#: ../../po/../src/ui/dialog/document-preferences.cpp:150 +#, fuzzy +msgid "Color of the page border" +msgstr "Колір рамки полотна" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1059 +#: ../../po/../src/ui/dialog/document-preferences.cpp:152 +msgid "Show page shadow" +msgstr "Показувати тінь від сторінки" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1063 +#: ../../po/../src/ui/dialog/document-preferences.cpp:153 +msgid "Default units:" +msgstr "Типові одиниці:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1069 +msgid "Units for the tool controls, ruler, and the statusbar" +msgstr "Одиниці вимірювання для інструментів, лінійок, рядка стану" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1086 +#: ../../po/../src/ui/widget/page-sizer.cpp:209 +#, fuzzy +msgid "Page size:" +msgstr "Розмір полотна:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1110 +#: ../../po/../src/ui/widget/page-sizer.cpp:219 +msgid "Custom" +msgstr "Власний" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1121 +#: ../../po/../src/ui/widget/page-sizer.cpp:225 +#, fuzzy +msgid "Page orientation:" +msgstr "Орієнтація полотна:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1133 +#: ../../po/../src/ui/widget/page-sizer.cpp:232 +msgid "Landscape" +msgstr "Альбомна" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1139 +#: ../../po/../src/ui/widget/page-sizer.cpp:234 +msgid "Portrait" +msgstr "Книжкова" + +#. Custom paper frame +#: ../../po/../src/dialogs/desktop-properties.cpp:1148 +#: ../../po/../src/ui/widget/page-sizer.cpp:249 +#, fuzzy +msgid "Custom size" +msgstr "Власний" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1160 +#: ../../po/../src/dialogs/export.cpp:269 +#: ../../po/../src/ui/widget/page-sizer.cpp:261 +msgid "Units:" +msgstr "Одиниці:" + +#. Stroke width +#: ../../po/../src/dialogs/desktop-properties.cpp:1162 +#: ../../po/../src/dialogs/export.cpp:310 +#: ../../po/../src/dialogs/object-attributes.cpp:55 +#: ../../po/../src/dialogs/stroke-style.cpp:985 +#: ../../po/../src/ui/widget/page-sizer.cpp:262 +#: ../../po/../src/widgets/toolbox.cpp:1957 +msgid "Width:" +msgstr "Ширина:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1183 +#: ../../po/../src/dialogs/export.cpp:326 +#: ../../po/../src/dialogs/export.cpp:431 +#: ../../po/../src/dialogs/object-attributes.cpp:56 +#: ../../po/../src/ui/widget/page-sizer.cpp:263 +msgid "Height:" +msgstr "Висота:" + +#. +#. * Ownership metadata tab +#. +#: ../../po/../src/dialogs/desktop-properties.cpp:1206 +msgid "Metadata" +msgstr "Метадані" + +#. add license selector pull-down +#: ../../po/../src/dialogs/desktop-properties.cpp:1225 +msgid "License" +msgstr "Ліцензія" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1255 +msgid "Proprietary" +msgstr "Комерційна" + +#: ../../po/../src/dialogs/display-settings.cpp:212 +msgid "When transforming, show:" +msgstr "При трансформації показувати:" + +#: ../../po/../src/dialogs/display-settings.cpp:223 +msgid "Objects" +msgstr "Об'єкти" + +#: ../../po/../src/dialogs/display-settings.cpp:224 +msgid "Show the actual objects when moving or transforming" +msgstr "Показувати об'єкти повністю при переміщенні чи трансформації" + +#: ../../po/../src/dialogs/display-settings.cpp:231 +msgid "Box outline" +msgstr "Рамку" + +#: ../../po/../src/dialogs/display-settings.cpp:232 +msgid "Show only a box outline of the objects when moving or transforming" +msgstr "" +"Показувати лише прямокутну рамку об'єктів при переміщенні чи трансформації" + +#: ../../po/../src/dialogs/display-settings.cpp:238 +msgid "Per-object selection cue:" +msgstr "Позначення виділених об'єктів:" + +#. sorationsnapsperpi == 0 means no snapping +#: ../../po/../src/dialogs/display-settings.cpp:249 +#: ../../po/../src/dialogs/display-settings.cpp:386 +#: ../../po/../src/dialogs/display-settings.cpp:441 +#: ../../po/../src/dialogs/display-settings.cpp:1482 +#: ../../po/../src/dialogs/stroke-style.cpp:791 +#: ../../po/../src/interface.cpp:741 +#: ../../po/../src/ui/widget/selected-style.cpp:100 +#: ../../po/../src/verbs.cpp:1842 +msgid "None" +msgstr "немає" + +#: ../../po/../src/dialogs/display-settings.cpp:250 +msgid "No per-object selection indication" +msgstr "Виділені об'єкти ніяк не позначені" + +#: ../../po/../src/dialogs/display-settings.cpp:256 +msgid "Mark" +msgstr "Позначка" + +#: ../../po/../src/dialogs/display-settings.cpp:257 +msgid "Each selected object has a diamond mark in the top left corner" +msgstr "" +"Кожен виділений об'єкт має позначку у вигляді ромба у лівому верхньому куті" + +#: ../../po/../src/dialogs/display-settings.cpp:264 +msgid "Box" +msgstr "Рамка" + +#: ../../po/../src/dialogs/display-settings.cpp:265 +msgid "Each selected object displays its bounding box" +msgstr "Кожен виділений об'єкт позначений пунктирною рамкою" + +#: ../../po/../src/dialogs/display-settings.cpp:270 +msgid "Default scale origin:" +msgstr "Нерухома точка при зміні розміру:" + +#: ../../po/../src/dialogs/display-settings.cpp:281 +msgid "Opposite bounding box edge" +msgstr "Протилежний край" + +#: ../../po/../src/dialogs/display-settings.cpp:282 +msgid "Default scale origin will be on the bounding box of the item" +msgstr "Типово, селектор змінює розмір об'єкту відносно протилежного краю" + +#: ../../po/../src/dialogs/display-settings.cpp:288 +msgid "Farthest opposite node" +msgstr "Протилежний вузол контуру" + +#: ../../po/../src/dialogs/display-settings.cpp:289 +msgid "Default scale origin will be on the bounding box of the item's points" +msgstr "" +"Типово, селектор змінює розмір об'єкту відносно протилежного вузла контуру" + +#: ../../po/../src/dialogs/display-settings.cpp:341 +msgid "degrees" +msgstr "градусів" + +#: ../../po/../src/dialogs/display-settings.cpp:350 +msgid "" +"Rotating with Ctrl pressed snaps every that much degrees; also, pressing " +"[ or ] rotates by this amount" +msgstr "" +"Обертання з натиснутою Ctrl обмежує кут значеннями, кратними вибраному; " +"натиснення [ чи ] повертає на вибраний кут" + +#: ../../po/../src/dialogs/display-settings.cpp:407 +msgid "Rotation snaps every:" +msgstr "Обмеження обертання:" + +#: ../../po/../src/dialogs/display-settings.cpp:430 +msgid "" +"None: dialogs are treated as regular windows; Normal: dialogs stay on top of " +"document windows; Aggressive: same as Normal but may work better with some " +"window managers." +msgstr "" +"Немає: діалоги ведуть себе як звичайні вікна; звичайно: діалоги залишаються " +"згори вікон документа; наполегливо: як і звичайно, але може краще працювати " +"з деякими менеджерами вікон." + +#: ../../po/../src/dialogs/display-settings.cpp:451 +msgid "Normal" +msgstr "звичайно" + +#: ../../po/../src/dialogs/display-settings.cpp:461 +msgid "Aggressive" +msgstr "наполегливо" + +#: ../../po/../src/dialogs/display-settings.cpp:475 +msgid "Dialogs on top:" +msgstr "Діалоги згори вікна:" + +#: ../../po/../src/dialogs/display-settings.cpp:645 +msgid "Show selection cue" +msgstr "Показувати позначку виділення" + +#: ../../po/../src/dialogs/display-settings.cpp:646 +msgid "" +"Whether selected objects display a selection cue (the same as in selector)" +msgstr "Чи відображатиметься позначка виділення (як і у селекторі)" + +#: ../../po/../src/dialogs/display-settings.cpp:657 +msgid "Enable gradient editing" +msgstr "Увімкнути редагування градієнтів" + +#: ../../po/../src/dialogs/display-settings.cpp:658 +msgid "Whether selected objects display gradient editing controls" +msgstr "Чи будуть відображатись засоби редагування градієнтів" + +#: ../../po/../src/dialogs/display-settings.cpp:719 +msgid "No objects selected to take the style from." +msgstr "Немає вибраних об'єктів, звідки б можна було б узяти стиль." + +#: ../../po/../src/dialogs/display-settings.cpp:728 +msgid "" +"More than one object selected. Cannot take style from multiple " +"objects." +msgstr "" +"Виділено більше ніж один об'єкт. Не вдається взяти стиль від кількох " +"об'єктів." + +#: ../../po/../src/dialogs/display-settings.cpp:767 +msgid "Create new objects with:" +msgstr "Створювати нові об'єкти з:" + +#: ../../po/../src/dialogs/display-settings.cpp:777 +msgid "Take from selection" +msgstr "Взяти з виділеного" + +#: ../../po/../src/dialogs/display-settings.cpp:778 +msgid "Remember the style of the (first) selected object as this tool's style" +msgstr "" +"Запам'ятати стиль (першого) виділеного об'єкту як стиль даного інструменту" + +#: ../../po/../src/dialogs/display-settings.cpp:782 +#, fuzzy +msgid "Last used style" +msgstr "Вставити _стиль" + +#: ../../po/../src/dialogs/display-settings.cpp:782 +msgid "Apply the style you last set on an object" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:790 +msgid "This tool's own style:" +msgstr "Власний стиль інструменту:" + +#: ../../po/../src/dialogs/display-settings.cpp:790 +msgid "" +"Each tool may store its own style to apply to the newly created objects. Use " +"the button below to set it." +msgstr "" +"Кожен інструмент може використовувати свій власний стиль для створюваних " +"об'єктів. Кнопка внизу встановлює цей стиль." + +#. Mouse +#: ../../po/../src/dialogs/display-settings.cpp:877 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:55 +msgid "Mouse" +msgstr "Миші" + +#. TRANSLATORS: "Grab" is a noun here. "Grab sensitivity" is intended to mean how +#. * close on the screen you need to be to an object to be able to grab it with mouse (in +#. * pixels). +#: ../../po/../src/dialogs/display-settings.cpp:883 +msgid "Grab sensitivity:" +msgstr "Радіус захоплення:" + +#: ../../po/../src/dialogs/display-settings.cpp:884 +msgid "" +"How close on the screen you need to be to an object to be able to grab it " +"with mouse (in screen pixels)" +msgstr "" +"Як близько (у точках) потрібно підвести курсор миші до об'єкту, щоб захопити " +"його" + +#: ../../po/../src/dialogs/display-settings.cpp:885 +#: ../../po/../src/dialogs/display-settings.cpp:897 +#: ../../po/../src/dialogs/display-settings.cpp:912 +#: ../../po/../src/dialogs/display-settings.cpp:930 +#: ../../po/../src/dialogs/display-settings.cpp:970 +msgid "pixels" +msgstr "точок" + +#: ../../po/../src/dialogs/display-settings.cpp:895 +msgid "Click/drag threshold:" +msgstr "Вважати клацанням перетягування на:" + +#: ../../po/../src/dialogs/display-settings.cpp:896 +msgid "" +"Maximum mouse drag (in screen pixels) which is considered a click, not a drag" +msgstr "" +"Максимальна кількість точок, перетягування на яку сприймається як клацання, " +"а не перетягування" + +#. Scrolling +#: ../../po/../src/dialogs/display-settings.cpp:907 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:56 +msgid "Scrolling" +msgstr "Прокрутка" + +#: ../../po/../src/dialogs/display-settings.cpp:910 +msgid "Mouse wheel scrolls by:" +msgstr "Колесо миші прокручує на:" + +#: ../../po/../src/dialogs/display-settings.cpp:911 +msgid "" +"One mouse wheel notch scrolls by this distance in screen pixels " +"(horizontally with Shift)" +msgstr "" +"На цю відстань у точках зсувається зображення одним клацанням колеса миші (з " +"натиснутою клавішею Shift - по горизонталі)" + +#: ../../po/../src/dialogs/display-settings.cpp:920 +msgid "Ctrl+arrows" +msgstr "Ctrl+стрілки" + +#: ../../po/../src/dialogs/display-settings.cpp:928 +msgid "Scroll by:" +msgstr "Крок прокрутки:" + +#: ../../po/../src/dialogs/display-settings.cpp:929 +msgid "Pressing Ctrl+arrow key scrolls by this distance (in screen pixels)" +msgstr "" +"На цю відстань у точках зсувається зображення при натисканні Ctrl+стрілки" + +#: ../../po/../src/dialogs/display-settings.cpp:939 +msgid "Acceleration:" +msgstr "Прискорення:" + +#: ../../po/../src/dialogs/display-settings.cpp:940 +msgid "" +"Pressing and holding Ctrl+arrow will gradually speed up scrolling (0 for no " +"acceleration)" +msgstr "" +"Якщо утримувати натиснутими Ctrl+стрілку, швидкість прокрутки буде зростати " +"(0 скасовує прискорення)" + +#: ../../po/../src/dialogs/display-settings.cpp:949 +msgid "Autoscrolling" +msgstr "Автопрокрутка" + +#: ../../po/../src/dialogs/display-settings.cpp:957 +msgid "Speed:" +msgstr "Швидкість:" + +#: ../../po/../src/dialogs/display-settings.cpp:958 +msgid "" +"How fast the canvas autoscrolls when you drag beyond canvas edge (0 to turn " +"autoscroll off)" +msgstr "" +"Як швидко буде відбуватись прокрутка при перетягуванні об'єкта за межі вікна " +"(0 скасовує автопрокрутку)" + +#: ../../po/../src/dialogs/display-settings.cpp:968 +#: ../../po/../src/ui/dialog/tracedialog.cpp:357 +#: ../../po/../src/ui/dialog/tracedialog.cpp:390 +msgid "Threshold:" +msgstr "Поріг:" + +#: ../../po/../src/dialogs/display-settings.cpp:969 +msgid "" +"How far (in screen pixels) you need to be from the canvas edge to trigger " +"autoscroll; positive is outside the canvas, negative is within the canvas" +msgstr "" +"Як далеко (у точках) від краю вікна потрібно бути, щоб увімкнулась " +"автопрокрутка; додатні значення - за межами вікна, від'ємні - всередині вікна" + +#. Steps +#: ../../po/../src/dialogs/display-settings.cpp:979 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:57 +msgid "Steps" +msgstr "Кроки" + +#: ../../po/../src/dialogs/display-settings.cpp:982 +msgid "Arrow keys move by:" +msgstr "Стрілки переміщують на:" + +#: ../../po/../src/dialogs/display-settings.cpp:983 +msgid "" +"Pressing an arrow key moves selected object(s) or node(s) by this distance " +"(in px units)" +msgstr "" +"На цю відстань (у точках) переміщується виділений об'єкт чи вузол при " +"натисканні клавіші зі стрілкою" + +#: ../../po/../src/dialogs/display-settings.cpp:984 +#: ../../po/../src/dialogs/display-settings.cpp:995 +#: ../../po/../src/dialogs/display-settings.cpp:1006 +#: ../../po/../src/helper/units.cpp:42 +msgid "px" +msgstr "точок" + +#: ../../po/../src/dialogs/display-settings.cpp:993 +msgid "> and < scale by:" +msgstr "Крок масштабування при > та <:" + +#: ../../po/../src/dialogs/display-settings.cpp:994 +msgid "" +"Pressing > or < scales selection up or down by this increment (in px units)" +msgstr "" +"На цю величину (у точках) змінюється розмір виділеного при натисканні " +"клавіш > чи <" + +#: ../../po/../src/dialogs/display-settings.cpp:1004 +msgid "Inset/Outset by:" +msgstr "Вставка/розтяжка на:" + +#: ../../po/../src/dialogs/display-settings.cpp:1005 +msgid "" +"Inset and Outset commands displace the path by this distance (in px units)" +msgstr "" +"На цю відстань (у точках) переміщують контур команди вставки та розтяжки" + +#: ../../po/../src/dialogs/display-settings.cpp:1017 +msgid "Compass-like display of angles" +msgstr "Подібне до компасу відображення кутів" + +#. TRANSLATORS: "positive clockwise" means "increasing in clockwise direction" +#: ../../po/../src/dialogs/display-settings.cpp:1019 +msgid "" +"When on, angles are displayed with 0 at north, 0 to 360 range, positive " +"clockwise; otherwise with 0 at east, -180 to 180 range, positive " +"counterclockwise" +msgstr "" +"Якщо увімкнено, кут зі значенням 0 вказує на північ з діапазоном від 0 до " +"360, причому значення збільшується за годинниковою стрілкою. У іншому " +"випадку 0 вказує на схід, діапазон значень знаходиться між -180 та 180, " +"приріст кута відбувається проти годинникової стрілки." + +#: ../../po/../src/dialogs/display-settings.cpp:1026 +msgid "Zoom in/out by:" +msgstr "Крок масштабу:" + +#: ../../po/../src/dialogs/display-settings.cpp:1027 +msgid "" +"Zoom tool click, +/- keys, and middle click zoom in and out by this " +"multiplier" +msgstr "" +"Крок при клацанні інструментом масштабу, натисканні клавіш +/- та клацанні " +"середньою кнопкою миші" + +#: ../../po/../src/dialogs/display-settings.cpp:1028 +#: ../../po/../src/helper/units.cpp:44 +msgid "%" +msgstr "%" + +#. Tools +#: ../../po/../src/dialogs/display-settings.cpp:1037 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:58 +msgid "Tools" +msgstr "Інструменти" + +#: ../../po/../src/dialogs/display-settings.cpp:1045 +msgid "Selector" +msgstr "Селектор" + +#: ../../po/../src/dialogs/display-settings.cpp:1056 +msgid "Node" +msgstr "Вузол" + +#: ../../po/../src/dialogs/display-settings.cpp:1064 +#: ../../po/../src/verbs.cpp:2073 +#: ../../po/../src/widgets/desktop-widget.cpp:277 +msgid "Zoom" +msgstr "Масштаб" + +#. The 4 shape tools +#: ../../po/../src/dialogs/display-settings.cpp:1071 +msgid "Shapes" +msgstr "Фігури" + +#: ../../po/../src/dialogs/display-settings.cpp:1079 +#: ../../po/../src/verbs.cpp:2055 +msgid "Rectangle" +msgstr "Прямокутник" + +#: ../../po/../src/dialogs/display-settings.cpp:1085 +#: ../../po/../src/verbs.cpp:2057 +msgid "Ellipse" +msgstr "Еліпс" + +#: ../../po/../src/dialogs/display-settings.cpp:1091 +#: ../../po/../src/verbs.cpp:2059 +msgid "Star" +msgstr "Зірка" + +#: ../../po/../src/dialogs/display-settings.cpp:1097 +#: ../../po/../src/verbs.cpp:2061 +msgid "Spiral" +msgstr "Спіраль" + +#: ../../po/../src/dialogs/display-settings.cpp:1111 +#: ../../po/../src/verbs.cpp:2063 +msgid "Pencil" +msgstr "Олівець" + +#: ../../po/../src/dialogs/display-settings.cpp:1114 +msgid "Tolerance:" +msgstr "Згладжування:" + +#: ../../po/../src/dialogs/display-settings.cpp:1115 +msgid "" +"This value affects the amount of smoothing applied to freehand lines; lower " +"values produce more uneven paths with more nodes" +msgstr "" +"Це значення визначає ступінь згладжування намальованих від руки ліній; чим " +"менше значення, тим більше вузлів у контурі " + +#: ../../po/../src/dialogs/display-settings.cpp:1131 +#: ../../po/../src/verbs.cpp:2065 +msgid "Pen" +msgstr "Перо" + +#: ../../po/../src/dialogs/display-settings.cpp:1140 +#: ../../po/../src/verbs.cpp:2067 +msgid "Calligraphy" +msgstr "Каліграфія" + +#: ../../po/../src/dialogs/display-settings.cpp:1147 +#: ../../po/../src/dialogs/text-edit.cpp:353 +#: ../../po/../src/ui/dialog/text-properties.cpp:37 +#: ../../po/../src/verbs.cpp:2069 +msgid "Text" +msgstr "Текст" + +#: ../../po/../src/dialogs/display-settings.cpp:1157 +#: ../../po/../src/verbs.cpp:2071 +msgid "Gradient" +msgstr "Градієнт" + +#: ../../po/../src/dialogs/display-settings.cpp:1164 +#: ../../po/../src/verbs.cpp:2077 +msgid "Connector" +msgstr "Лінія з'єднання" + +#: ../../po/../src/dialogs/display-settings.cpp:1171 +#: ../../po/../src/verbs.cpp:2075 +msgid "Dropper" +msgstr "Піпетка" + +#. Windows +#: ../../po/../src/dialogs/display-settings.cpp:1183 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:59 +msgid "Windows" +msgstr "Вікна" + +#: ../../po/../src/dialogs/display-settings.cpp:1188 +msgid "Save window geometry" +msgstr "Зберігати геометрію вікон" + +#: ../../po/../src/dialogs/display-settings.cpp:1189 +msgid "" +"Save the window size and position with each document (only for Inkscape SVG " +"format)" +msgstr "" +"Зберігати з документом розмір та розташування вікна (лише для формату " +"Inkscape SVG)" + +#: ../../po/../src/dialogs/display-settings.cpp:1196 +msgid "Dialogs are hidden in taskbar" +msgstr "Не відображати діалоги на панелі задач" + +#: ../../po/../src/dialogs/display-settings.cpp:1197 +msgid "Whether dialog windows are to be hidden in the window manager taskbar" +msgstr "Чи прибирати діалогові вікна з панелі завдань віконного менеджера" + +#: ../../po/../src/dialogs/display-settings.cpp:1204 +msgid "Zoom when window is resized" +msgstr "Масштабувати при зміні розмірів вікна" + +#: ../../po/../src/dialogs/display-settings.cpp:1205 +msgid "" +"Zoom drawing when document window is resized, to keep the same area visible " +"(this is the default which can be changed in any window using the button " +"above the right scrollbar)" +msgstr "" +"Масштабувати малюнок при зміні розмірів вікна, щоб зберегти видиму область " +"(можна змінювати кнопкою над правою смугою прокрутки)" + +#. Clones +#: ../../po/../src/dialogs/display-settings.cpp:1213 +#: ../../po/../src/dialogs/find.cpp:624 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:60 +msgid "Clones" +msgstr "Клони" + +#: ../../po/../src/dialogs/display-settings.cpp:1217 +msgid "When the original moves, its clones and linked offsets:" +msgstr "При переміщенні оригіналу, його клони та прив'язані розтяжки:" + +#: ../../po/../src/dialogs/display-settings.cpp:1229 +msgid "Move in parallel" +msgstr "Переміщуються паралельно" + +#: ../../po/../src/dialogs/display-settings.cpp:1230 +msgid "Clones are translated by the same vector as their original." +msgstr "Кожен клон зсувається на той самий вектор, що й оригінал." + +#: ../../po/../src/dialogs/display-settings.cpp:1237 +msgid "Stay unmoved" +msgstr "Залишаються нерухомими" + +#: ../../po/../src/dialogs/display-settings.cpp:1238 +msgid "Clones preserve their positions when their original is moved." +msgstr "Клони залишаються на місці, коли рухаються їх оригінали." + +#: ../../po/../src/dialogs/display-settings.cpp:1245 +msgid "Move according to transform" +msgstr "Рухаються у відповідності до transform=" + +#: ../../po/../src/dialogs/display-settings.cpp:1246 +msgid "" +"Each clone moves according to the value of its transform= attribute. For " +"example, a rotated clone will move in a different direction than its " +"original." +msgstr "" +"Кожен клон рухається у відповідності до значення його атрибуту transform=. " +"Наприклад, повернутий клон буде переміщуватись у іншому напрямку, ніж його " +"оригінал." + +#: ../../po/../src/dialogs/display-settings.cpp:1255 +msgid "When the original is deleted, its clones:" +msgstr "Коли оригінал видаляється, його клони:" + +#: ../../po/../src/dialogs/display-settings.cpp:1267 +msgid "Are unlinked" +msgstr "Від'єднуються" + +#: ../../po/../src/dialogs/display-settings.cpp:1267 +msgid "Orphaned clones are converted to regular objects." +msgstr "Осиротілі клони перетворюються у звичайні об'єкти." + +#: ../../po/../src/dialogs/display-settings.cpp:1273 +msgid "Are deleted" +msgstr "Видаляються" + +#: ../../po/../src/dialogs/display-settings.cpp:1273 +msgid "Orphaned clones are deleted along with their original." +msgstr "Осиротілі клони видаляються разом з оригіналом." + +#. Transforms +#. TRANSLATORS: Noun, i.e. transformations. +#: ../../po/../src/dialogs/display-settings.cpp:1289 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:61 +msgid "Transforms" +msgstr "Трансформації" + +#: ../../po/../src/dialogs/display-settings.cpp:1292 +msgid "Scale stroke width" +msgstr "Змінювати ширину штриха" + +#: ../../po/../src/dialogs/display-settings.cpp:1293 +#: ../../po/../src/widgets/select-toolbar.cpp:568 +msgid "When scaling objects, scale the stroke width by the same proportion" +msgstr "" +"При зміні розміру об'єктів змінювати ширину штриха у відповідній пропорції" + +#: ../../po/../src/dialogs/display-settings.cpp:1300 +msgid "Scale rounded corners in rectangles" +msgstr "Змінювати радіус округлених кутів" + +#: ../../po/../src/dialogs/display-settings.cpp:1301 +#: ../../po/../src/widgets/select-toolbar.cpp:580 +msgid "When scaling rectangles, scale the radii of rounded corners" +msgstr "" +"При зміні розміру прямокутників міняти радіус округлених кутів у тій самій " +"пропорції" + +#: ../../po/../src/dialogs/display-settings.cpp:1308 +msgid "Transform gradients" +msgstr "Трансформувати градієнти" + +#: ../../po/../src/dialogs/display-settings.cpp:1309 +#: ../../po/../src/widgets/select-toolbar.cpp:592 +msgid "Transform gradients (in fill or stroke) along with the objects" +msgstr "Трансформувати градієнти (у заповненні чи штрихах) разом з об'єктом" + +#: ../../po/../src/dialogs/display-settings.cpp:1316 +msgid "Transform patterns" +msgstr "Трансформувати візерунки" + +#: ../../po/../src/dialogs/display-settings.cpp:1317 +#: ../../po/../src/widgets/select-toolbar.cpp:604 +msgid "Transform patterns (in fill or stroke) along with the objects" +msgstr "Трансформувати візерунки (у заповненнях чи штрихах) разом з об'єктом" + +#. TRANSLATORS: How to specify the affine transformation in the SVG file. +#: ../../po/../src/dialogs/display-settings.cpp:1327 +msgid "Store transformation:" +msgstr "Збереження трансформації:" + +#: ../../po/../src/dialogs/display-settings.cpp:1338 +msgid "Optimized" +msgstr "З оптимізацією" + +#: ../../po/../src/dialogs/display-settings.cpp:1339 +msgid "" +"If possible, apply transformation to objects without adding a transform= " +"attribute" +msgstr "" +"При можливості застосовувати до об'єктів трансформацію без додавання " +"атрибуту transform=" + +#: ../../po/../src/dialogs/display-settings.cpp:1346 +msgid "Preserved" +msgstr "Без оптимізації" + +#: ../../po/../src/dialogs/display-settings.cpp:1347 +msgid "Always store transformation as a transform= attribute on objects" +msgstr "Завжди зберігати трансформацію у вигляді атрибута transform=" + +#. Selecting +#: ../../po/../src/dialogs/display-settings.cpp:1355 +msgid "Selecting" +msgstr "Виділення" + +#: ../../po/../src/dialogs/display-settings.cpp:1357 +msgid "Ctrl+A, Tab, Shift+Tab:" +msgstr "Ctrl+A, Tab, Shift+Tab:" + +#: ../../po/../src/dialogs/display-settings.cpp:1366 +msgid "Select only within current layer" +msgstr "Працюють лише у поточному шарі" + +#: ../../po/../src/dialogs/display-settings.cpp:1367 +msgid "" +"Uncheck this to make keyboard selection commands work on objects in all " +"layers" +msgstr "" +"Вимкніть цей параметр, якщо бажаєте виділяти з клавіатури об'єкти в усіх " +"шарах одночасно" + +#: ../../po/../src/dialogs/display-settings.cpp:1374 +msgid "Ignore hidden objects" +msgstr "Ігнорувати приховані об'єкти" + +#: ../../po/../src/dialogs/display-settings.cpp:1375 +msgid "" +"Uncheck this to be able to select objects that are hidden (either by " +"themselves or by being in a hidden group or layer)" +msgstr "" +"Вимкніть цей параметр, якщо бажаєте виділяти приховані (невидимі) об'єкти" + +#: ../../po/../src/dialogs/display-settings.cpp:1382 +msgid "Ignore locked objects" +msgstr "Ігнорувати замкнені об'єкти" + +#: ../../po/../src/dialogs/display-settings.cpp:1383 +msgid "" +"Uncheck this to be able to select objects that are locked (either by " +"themselves or by being in a locked group or layer)" +msgstr "Вимкніть це параметр, якщо бажаєте виділяти замкнені об'єкти" + +#. To be broken into: Display, Save, Export, SVG, Commands +#: ../../po/../src/dialogs/display-settings.cpp:1391 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:62 +msgid "Misc" +msgstr "Інше" + +#: ../../po/../src/dialogs/display-settings.cpp:1394 +msgid "Default export resolution:" +msgstr "Типова роздільна здатність для експорту:" + +#: ../../po/../src/dialogs/display-settings.cpp:1395 +msgid "Default bitmap resolution (in dots per inch) in the Export dialog" +msgstr "Типова роздільна здатність (у точках на дюйм) у вікні експорту" + +#. FIXME: add "Used for new exports; once exported, documents remember this value on per-object basis" when implemented +#: ../../po/../src/dialogs/display-settings.cpp:1396 +#: ../../po/../src/dialogs/export.cpp:442 +msgid "dpi" +msgstr "dpi" + +#. TRANSLATORS: When on, an imported bitmap creates an element; otherwise it is a +#. * rectangle with bitmap fill. +#: ../../po/../src/dialogs/display-settings.cpp:1407 +msgid "Import bitmap as " +msgstr "Імпортувати растрові зображення як " + +#: ../../po/../src/dialogs/display-settings.cpp:1408 +msgid "" +"When on, an imported bitmap creates an element; otherwise it is a " +"rectangle with bitmap fill" +msgstr "" +"З цим параметром імпортоване растрове зображення створює елемент ; " +"інакше створюється прямокутник з растровим заповненням" + +#. TRANSLATORS: When on, the print out (currently Postscript) will have +#. * a comment with the each object's label visible, marking the section +#. * of the printing commands that represent the given object. +#: ../../po/../src/dialogs/display-settings.cpp:1418 +msgid "Add label comments to printing output" +msgstr "Додати коментар до виводу друку" + +#: ../../po/../src/dialogs/display-settings.cpp:1419 +msgid "" +"When on, a comment will be added to the raw print output, marking the " +"rendered output for an object with its label" +msgstr "" +"Якщо увімкнено, до необробленого виводу друку буде додано коментар, що " +"позначає вивід об'єкта його позначкою" + +#. TRANSLATORS: When on, enable the effects menu, default is off +#: ../../po/../src/dialogs/display-settings.cpp:1427 +msgid "Enable script effects (requires restart) - EXPERIMENTAL" +msgstr "" +"Увімкнути сценарії з ефектами (вимагається перезапуск) - ЕКСПЕРИМЕНТАЛЬНА " +"ФУНКЦІЯ" + +#: ../../po/../src/dialogs/display-settings.cpp:1428 +msgid "" +"When on, the effects menu is enabled, allowing external effect scripts to be " +"called, requires restart before effective - EXPERIMENTAL" +msgstr "" +"Якщо відмічено, відображається меню з ефектами, що дозволяє виконувати " +"зовнішні сценарії з ефектами, перед активацією вимагається перезапуск - " +"ЕКСПЕРИМЕНТАЛЬНА ФУНКЦІЯ" + +#. TRANSLATORS: The maximum length of the Open Recent list in the File menu. +#: ../../po/../src/dialogs/display-settings.cpp:1436 +msgid "Max recent documents:" +msgstr "Недавніх документів у меню:" + +#: ../../po/../src/dialogs/display-settings.cpp:1437 +msgid "The maximum length of the Open Recent list in the File menu" +msgstr "Максимальна довжина підменю недавніх документів у меню \"Файл\"" + +#: ../../po/../src/dialogs/display-settings.cpp:1447 +msgid "Simplification threshold:" +msgstr "Поріг спрощення:" + +#: ../../po/../src/dialogs/display-settings.cpp:1448 +msgid "" +"How strong is the Simplify command by default. If you invoke this command " +"several times in quick succession, it will act more and more aggressively; " +"invoking it again after a pause restores the default threshold." +msgstr "" +"Ступінь спрощення за командою \"Спростити\". Якщо викликати цю команду " +"кілька разів поспіль, вона діятиме з кожним разом все більш агресивно; щоб " +"повернутися до типового значення, зробіть паузу перед черговим викликом " +"команди." + +#: ../../po/../src/dialogs/display-settings.cpp:1469 +msgid "Oversample bitmaps:" +msgstr "Усереднювати растр по точках:" + +#: ../../po/../src/dialogs/display-settings.cpp:1488 +msgid "2x2" +msgstr "2x2" + +#: ../../po/../src/dialogs/display-settings.cpp:1494 +msgid "4x4" +msgstr "4x4" + +#: ../../po/../src/dialogs/display-settings.cpp:1500 +msgid "8x8" +msgstr "8x8" + +#: ../../po/../src/dialogs/display-settings.cpp:1506 +msgid "16x16" +msgstr "16x16" + +#. "view_icon_preview" +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2143 +msgid "_Page" +msgstr "_Сторінка" + +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2147 +msgid "_Drawing" +msgstr "_Малюнок" + +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2149 +msgid "_Selection" +msgstr "Виді_лене" + +#: ../../po/../src/dialogs/export.cpp:133 +msgid "_Custom" +msgstr "В_ласна" + +#: ../../po/../src/dialogs/export.cpp:254 +msgid "Export area" +msgstr "Область експорту" + +#: ../../po/../src/dialogs/export.cpp:300 +msgid "_x0:" +msgstr "_x0:" + +#: ../../po/../src/dialogs/export.cpp:305 +msgid "x_1:" +msgstr "x_1:" + +#: ../../po/../src/dialogs/export.cpp:316 +msgid "_y0:" +msgstr "_y0:" + +#: ../../po/../src/dialogs/export.cpp:321 +msgid "y_1:" +msgstr "y_1:" + +#: ../../po/../src/dialogs/export.cpp:406 +msgid "Bitmap size" +msgstr "Розмір зображення" + +#: ../../po/../src/dialogs/export.cpp:416 +msgid "_Width:" +msgstr "_Ширина:" + +#: ../../po/../src/dialogs/export.cpp:416 +#: ../../po/../src/dialogs/export.cpp:431 +msgid "pixels at" +msgstr "точок" + +#: ../../po/../src/dialogs/export.cpp:426 +msgid "dp_i" +msgstr "dp_i" + +#: ../../po/../src/dialogs/export.cpp:448 +msgid "_Filename" +msgstr "Назва _файлу" + +#: ../../po/../src/dialogs/export.cpp:512 +msgid "_Browse..." +msgstr "О_гляд..." + +#: ../../po/../src/dialogs/export.cpp:539 +msgid " _Export " +msgstr "_Експорт " + +#: ../../po/../src/dialogs/export.cpp:541 +msgid "Export the bitmap file with these settings" +msgstr "Експортувати файл з цими параметрами" + +#: ../../po/../src/dialogs/export.cpp:968 +msgid "You have to enter a filename" +msgstr "Необхідно ввести назву файлу" + +#: ../../po/../src/dialogs/export.cpp:973 +msgid "The chosen area to be exported is invalid" +msgstr "Недопустима область для експорту" + +#: ../../po/../src/dialogs/export.cpp:982 +#, c-format +msgid "Directory %s does not exist or is not a directory.\n" +msgstr "Каталог %s не існує, або ж це не каталог.\n" + +#: ../../po/../src/dialogs/export.cpp:998 +msgid "Export in progress" +msgstr "Триває експорт" + +#: ../../po/../src/dialogs/export.cpp:1004 +#, c-format +msgid "Exporting %s (%d x %d)" +msgstr "Експорт %s (%d x %d)" + +#: ../../po/../src/dialogs/export.cpp:1031 +#, c-format +msgid "Could not export to filename %s.\n" +msgstr "Не вдається експортувати у файл %s.\n" + +#: ../../po/../src/dialogs/export.cpp:1137 +msgid "Select a filename for exporting" +msgstr "Виберіть ім'я файлу для експорту" + +#: ../../po/../src/dialogs/filedialog.cpp:367 +msgid "No preview" +msgstr "Немає перегляду" + +#: ../../po/../src/dialogs/filedialog.cpp:468 +msgid "too large for preview" +msgstr "занадто великий для перегляду" + +#: ../../po/../src/dialogs/filedialog.cpp:762 +#: ../../po/../src/dialogs/filedialog.cpp:763 +msgid "All Images" +msgstr "Усі зображення" + +#: ../../po/../src/dialogs/filedialog.cpp:767 +#: ../../po/../src/dialogs/filedialog.cpp:768 +msgid "All Files" +msgstr "Усі файли" + +#: ../../po/../src/dialogs/filedialog.cpp:774 +#: ../../po/../src/dialogs/filedialog.cpp:775 +msgid "All Inkscape Files" +msgstr "Усі файли Inkscape" + +#: ../../po/../src/dialogs/filedialog.cpp:1176 +msgid "Guess from extension" +msgstr "Визначити з розширення" + +#. ###### Add the file types menu +#. createFilterMenu(); +#. ###### Do we want the .xxx extension automatically added? +#: ../../po/../src/dialogs/filedialog.cpp:1261 +msgid "Append filename extension automatically" +msgstr "Додавати розширення автоматично" + +#. TRANSLATORS: "%s" is replaced with "exact" or "partial" when this string is displayed +#: ../../po/../src/dialogs/find.cpp:378 +#, c-format +msgid "%d object found (out of %d), %s match." +msgid_plural "%d objects found (out of %d), %s match." +msgstr[0] "Знайдено %d об'єкт (з %d), %s відповідність." +msgstr[1] "Знайдено %d об'єкти (з %d), %s відповідність." +msgstr[2] "Знайдено %d об'єктів (з %d), %s відповідність." + +#: ../../po/../src/dialogs/find.cpp:381 +msgid "exact" +msgstr "точна" + +#: ../../po/../src/dialogs/find.cpp:381 +msgid "partial" +msgstr "часткова" + +#: ../../po/../src/dialogs/find.cpp:388 +msgid "No objects found" +msgstr "Нічого не знайдено" + +#: ../../po/../src/dialogs/find.cpp:546 +msgid "T_ype: " +msgstr "Т_ип: " + +#: ../../po/../src/dialogs/find.cpp:553 +msgid "Search in all object types" +msgstr "Шукати серед об'єктів усіх типів" + +#: ../../po/../src/dialogs/find.cpp:553 +msgid "All types" +msgstr "Усі типи" + +#: ../../po/../src/dialogs/find.cpp:564 +msgid "Search all shapes" +msgstr "Шукати серед усіх фігур" + +#: ../../po/../src/dialogs/find.cpp:564 +msgid "All shapes" +msgstr "Усі фігури" + +#: ../../po/../src/dialogs/find.cpp:581 +msgid "Search rectangles" +msgstr "Шукати прямокутники" + +#: ../../po/../src/dialogs/find.cpp:581 +msgid "Rectangles" +msgstr "Прямокутники" + +#: ../../po/../src/dialogs/find.cpp:586 +msgid "Search ellipses, arcs, circles" +msgstr "Шукати серед еліпсів, секторів, кругів" + +#: ../../po/../src/dialogs/find.cpp:586 +msgid "Ellipses" +msgstr "Еліпси" + +#: ../../po/../src/dialogs/find.cpp:591 +msgid "Search stars and polygons" +msgstr "Шукати серед зірок та багатокутників" + +#: ../../po/../src/dialogs/find.cpp:591 +msgid "Stars" +msgstr "Зірки" + +#: ../../po/../src/dialogs/find.cpp:596 +msgid "Search spirals" +msgstr "Шукати спіралі" + +#: ../../po/../src/dialogs/find.cpp:596 +msgid "Spirals" +msgstr "Спіралі" + +#. TRANSLATORS: polyline is a set of connected straight line segments +#. http://www.w3.org/TR/SVG11/shapes.html#PolylineElement +#: ../../po/../src/dialogs/find.cpp:609 +msgid "Search paths, lines, polylines" +msgstr "Шукати серед контурів, ліній, поліліній" + +#: ../../po/../src/dialogs/find.cpp:609 +msgid "Paths" +msgstr "Контури" + +#: ../../po/../src/dialogs/find.cpp:614 +msgid "Search text objects" +msgstr "Шукати текстові об'єкти" + +#: ../../po/../src/dialogs/find.cpp:614 +msgid "Texts" +msgstr "Тексти" + +#: ../../po/../src/dialogs/find.cpp:619 +msgid "Search groups" +msgstr "Шукати групи" + +#: ../../po/../src/dialogs/find.cpp:619 +msgid "Groups" +msgstr "Групи" + +#: ../../po/../src/dialogs/find.cpp:624 +msgid "Search clones" +msgstr "Шукати серед клонах" + +#: ../../po/../src/dialogs/find.cpp:629 +msgid "Search images" +msgstr "Шукати зображення" + +#: ../../po/../src/dialogs/find.cpp:629 +msgid "Images" +msgstr "Зображення" + +#: ../../po/../src/dialogs/find.cpp:634 +msgid "Search offset objects" +msgstr "Шукати серед розтяжок" + +#: ../../po/../src/dialogs/find.cpp:634 +msgid "Offsets" +msgstr "Розтяжки" + +#: ../../po/../src/dialogs/find.cpp:694 +msgid "_Text: " +msgstr "_Текст:" + +#: ../../po/../src/dialogs/find.cpp:694 +msgid "Find objects by their text content (exact or partial match)" +msgstr "" +"Шукати об'єкти за їх текстовим вмістом (повна або часткова відповідність)" + +#: ../../po/../src/dialogs/find.cpp:695 +msgid "_ID: " +msgstr "_ID: " + +#: ../../po/../src/dialogs/find.cpp:695 +msgid "Find objects by the value of the id attribute (exact or partial match)" +msgstr "" +"Шукати об'єкти за значенням атрибуту id (повна або часткова відповідність)" + +#: ../../po/../src/dialogs/find.cpp:696 +msgid "_Style: " +msgstr "_Стиль: " + +#: ../../po/../src/dialogs/find.cpp:696 +msgid "" +"Find objects by the value of the style attribute (exact or partial match)" +msgstr "" +"Шукати об'єкти за значенням атрибуту style (повна або часткова відповідність)" + +#: ../../po/../src/dialogs/find.cpp:697 +msgid "_Attribute: " +msgstr "_Атрибут: " + +#: ../../po/../src/dialogs/find.cpp:697 +msgid "Find objects by the name of an attribute (exact or partial match)" +msgstr "Шукати об'єкти за назвою атрибуту (повна або часткова відповідність)" + +#: ../../po/../src/dialogs/find.cpp:711 +msgid "Search in s_election" +msgstr "Шукати у виді_леному" + +#: ../../po/../src/dialogs/find.cpp:715 +msgid "Limit search to the current selection" +msgstr "Обмежити пошук поточним виділенням" + +#: ../../po/../src/dialogs/find.cpp:720 +msgid "Search in current _layer" +msgstr "Шукати у поточному _шарі" + +#: ../../po/../src/dialogs/find.cpp:724 +msgid "Limit search to the current layer" +msgstr "Обмежити пошук поточним шаром" + +#: ../../po/../src/dialogs/find.cpp:729 +msgid "Include _hidden" +msgstr "Включаючи _приховані" + +#: ../../po/../src/dialogs/find.cpp:733 +msgid "Include hidden objects in search" +msgstr "Включити в пошук приховані об'єкти" + +#: ../../po/../src/dialogs/find.cpp:738 +msgid "Include l_ocked" +msgstr "Включно з _замкненими" + +#: ../../po/../src/dialogs/find.cpp:742 +msgid "Include locked objects in search" +msgstr "Включити в пошук замкнені об'єкти" + +#: ../../po/../src/dialogs/find.cpp:753 +msgid "Clear values" +msgstr "Очистити значення" + +#: ../../po/../src/dialogs/find.cpp:754 +msgid "_Find" +msgstr "З_найти" + +#: ../../po/../src/dialogs/find.cpp:754 +msgid "Select objects matching all of the fields you filled in" +msgstr "Виділити об'єкти, що відповідають усім критеріям пошуку" + +#: ../../po/../src/dialogs/iconpreview.cpp:145 +#, c-format +msgid "%d x %d" +msgstr "%d x %d" + +#: ../../po/../src/dialogs/iconpreview.cpp:193 +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:857 +#: ../../po/../src/widgets/desktop-widget.cpp:1069 +msgid "Selection" +msgstr "Виділене" + +#: ../../po/../src/dialogs/iconpreview.cpp:195 +msgid "Selection only or whole document" +msgstr "Або лише виділене, або весь документ" + +#: ../../po/../src/dialogs/iconpreview.cpp:203 +msgid "Refresh the icons" +msgstr "Оновити значки" + +#. Create the label for the object id +#: ../../po/../src/dialogs/item-properties.cpp:126 +#: ../../po/../src/dialogs/item-properties.cpp:327 +#: ../../po/../src/dialogs/item-properties.cpp:396 +#: ../../po/../src/dialogs/item-properties.cpp:403 +msgid "_Id" +msgstr "_Id" + +#: ../../po/../src/dialogs/item-properties.cpp:135 +msgid "" +"The id= attribute (only letters, digits, and the characters .-_: allowed)" +msgstr "" +"Атрибут id= (дозволяються лише латинські літери, цифри та символи .-_:)" + +#. Button for setting the object's id, label, title and description. +#: ../../po/../src/dialogs/item-properties.cpp:149 +msgid "_Set" +msgstr "_Встановити" + +#. Create the label for the object label +#: ../../po/../src/dialogs/item-properties.cpp:158 +msgid "_Label" +msgstr "_Позначка" + +#: ../../po/../src/dialogs/item-properties.cpp:167 +msgid "A freeform label for the object" +msgstr "Довільна позначка об'єкту" + +#. Create the label for the object title +#: ../../po/../src/dialogs/item-properties.cpp:179 +#: ../../po/../src/dialogs/rdf.cpp:243 +msgid "Title" +msgstr "Назва" + +#. Create the frame for the object description +#: ../../po/../src/dialogs/item-properties.cpp:196 +#: ../../po/../src/dialogs/rdf.cpp:287 +msgid "Description" +msgstr "Опис" + +#. Hide +#: ../../po/../src/dialogs/item-properties.cpp:223 +msgid "_Hide" +msgstr "С_ховати" + +#: ../../po/../src/dialogs/item-properties.cpp:224 +msgid "Check to make the object invisible" +msgstr "Зробити об'єкт невидимим" + +#. Lock +#. TRANSLATORS: "Lock" is a verb here +#: ../../po/../src/dialogs/item-properties.cpp:233 +msgid "L_ock" +msgstr "За_мкнути" + +#: ../../po/../src/dialogs/item-properties.cpp:234 +msgid "Check to make the object insensitive (not selectable by mouse)" +msgstr "Зробити цей об'єкт нечутливим до виділення" + +#: ../../po/../src/dialogs/item-properties.cpp:310 +#: ../../po/../src/dialogs/item-properties.cpp:317 +msgid "Ref" +msgstr "Ref" + +#: ../../po/../src/dialogs/item-properties.cpp:398 +msgid "Id invalid! " +msgstr "ID неправильний!" + +#: ../../po/../src/dialogs/item-properties.cpp:400 +msgid "Id exists! " +msgstr "Такий ID вже є!" + +#: ../../po/../src/dialogs/layer-properties.cpp:50 +msgid "Layer name:" +msgstr "Назва шару:" + +#: ../../po/../src/dialogs/layer-properties.cpp:133 +msgid "Rename Layer" +msgstr "Перейменування шару" + +#: ../../po/../src/dialogs/layer-properties.cpp:136 +msgid "_Rename" +msgstr "Пере_йменувати" + +#. TRANSLATORS: This means "The layer has been renamed" +#: ../../po/../src/dialogs/layer-properties.cpp:147 +msgid "Renamed layer" +msgstr "Шар перейменовано" + +#: ../../po/../src/dialogs/layer-properties.cpp:151 +msgid "Add Layer" +msgstr "Додавання шару" + +#: ../../po/../src/dialogs/layer-properties.cpp:153 +msgid "_Add" +msgstr "_Додати" + +#: ../../po/../src/dialogs/layer-properties.cpp:167 +msgid "New layer created." +msgstr "Новий шар створено." + +#: ../../po/../src/dialogs/object-attributes.cpp:34 +msgid "Href:" +msgstr "Href:" + +#: ../../po/../src/dialogs/object-attributes.cpp:35 +msgid "Target:" +msgstr "Target:" + +#: ../../po/../src/dialogs/object-attributes.cpp:36 +msgid "Type:" +msgstr "Тип:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkRoleAttribute +#. Identifies the type of the related resource with an absolute URI +#: ../../po/../src/dialogs/object-attributes.cpp:39 +msgid "Role:" +msgstr "Role:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkArcRoleAttribute +#. For situations where the nature/role alone isn't enough, this offers an additional URI defining the purpose of the link. +#: ../../po/../src/dialogs/object-attributes.cpp:42 +msgid "Arcrole:" +msgstr "Arcrole:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkTitleAttribute +#: ../../po/../src/dialogs/object-attributes.cpp:44 +msgid "Title:" +msgstr "Заголовок:" + +#: ../../po/../src/dialogs/object-attributes.cpp:45 +msgid "Show:" +msgstr "Показ:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkActuateAttribute +#: ../../po/../src/dialogs/object-attributes.cpp:47 +msgid "Actuate:" +msgstr "Actuate:" + +#: ../../po/../src/dialogs/object-attributes.cpp:52 +msgid "URL:" +msgstr "URL:" + +#: ../../po/../src/dialogs/object-attributes.cpp:53 +msgid "X:" +msgstr "X:" + +#: ../../po/../src/dialogs/object-attributes.cpp:54 +msgid "Y:" +msgstr "Y:" + +#: ../../po/../src/dialogs/object-attributes.cpp:98 +#, c-format +msgid "%s attributes" +msgstr "Атрибути %s" + +#: ../../po/../src/dialogs/object-properties.cpp:158 +msgid "_Fill" +msgstr "_Заповнення" + +#: ../../po/../src/dialogs/object-properties.cpp:165 +msgid "Stroke _paint" +msgstr "_Колір штриха" + +#: ../../po/../src/dialogs/object-properties.cpp:172 +msgid "Stroke st_yle" +msgstr "С_тиль штриха" + +#: ../../po/../src/dialogs/object-properties.cpp:183 +msgid "Master _opacity" +msgstr "Загальна _прозорість" + +#: ../../po/../src/dialogs/rdf.cpp:244 +msgid "Name by which this document is formally known." +msgstr "Назва, під якою цей документ офіційно відомий." + +#: ../../po/../src/dialogs/rdf.cpp:246 +msgid "Date" +msgstr "Дата" + +#: ../../po/../src/dialogs/rdf.cpp:247 +msgid "Date associated with the creation of this document (YYYY-MM-DD)." +msgstr "Дата, до якої відноситься створення цього документу (РРРР-ММ-ДД)." + +#: ../../po/../src/dialogs/rdf.cpp:249 +msgid "Format" +msgstr "Формат" + +#: ../../po/../src/dialogs/rdf.cpp:250 +msgid "The physical or digital manifestation of this document (MIME type)." +msgstr "Фізичний або цифровий вияв цього документу (MIME-тип)." + +#: ../../po/../src/dialogs/rdf.cpp:252 +msgid "Type" +msgstr "Тип" + +#: ../../po/../src/dialogs/rdf.cpp:253 +msgid "Type of document (DCMI Type)." +msgstr "Тип документу (тип DCMI)" + +#: ../../po/../src/dialogs/rdf.cpp:256 +msgid "Creator" +msgstr "Автор" + +#: ../../po/../src/dialogs/rdf.cpp:257 +msgid "" +"Name of entity primarily responsible for making the content of this document." +msgstr "" +"Назва суб'єкта, головним чином відповідального за створення цього документу." + +#: ../../po/../src/dialogs/rdf.cpp:259 +msgid "Rights" +msgstr "Права" + +#: ../../po/../src/dialogs/rdf.cpp:260 +msgid "" +"Name of entity with rights to the Intellectual Property of this document." +msgstr "Назва суб'єкта, чиєю інтелектуальною власністю є цей документ." + +#: ../../po/../src/dialogs/rdf.cpp:262 +msgid "Publisher" +msgstr "Видавець" + +#: ../../po/../src/dialogs/rdf.cpp:263 +msgid "Name of entity responsible for making this document available." +msgstr "Назва суб'єкта, відповідального за публікацію цього документу." + +#: ../../po/../src/dialogs/rdf.cpp:266 +msgid "Identifier" +msgstr "Ідентифікатор" + +#: ../../po/../src/dialogs/rdf.cpp:267 +msgid "Unique URI to reference this document." +msgstr "Унікальний URI для посилання на цей документ." + +#: ../../po/../src/dialogs/rdf.cpp:269 +msgid "Source" +msgstr "Джерело" + +#: ../../po/../src/dialogs/rdf.cpp:270 +msgid "Unique URI to reference the source of this document." +msgstr "Унікальний URI для посилання на джерело цього документу." + +#: ../../po/../src/dialogs/rdf.cpp:272 +msgid "Relation" +msgstr "Суміжний" + +#: ../../po/../src/dialogs/rdf.cpp:273 +msgid "Unique URI to a related document." +msgstr "Унікальний URI пов'язаного документу." + +#: ../../po/../src/dialogs/rdf.cpp:275 +msgid "Language" +msgstr "Мова" + +#: ../../po/../src/dialogs/rdf.cpp:276 +msgid "" +"Two-letter language tag with optional subtags for the language of this " +"document. (e.g. 'en-GB')" +msgstr "Дволітерний код мови, можливо з підтегами (наприклад, uk-UA)" + +#: ../../po/../src/dialogs/rdf.cpp:278 +msgid "Keywords" +msgstr "Ключові слова" + +#: ../../po/../src/dialogs/rdf.cpp:279 +msgid "" +"The topic of this document as comma-separated key words, phrases, or " +"classifications." +msgstr "Опис теми цього документу списком ключових слів, фраз чи класифікацій." + +#. TRANSLATORS: "Coverage": the spatial or temporal characteristics of the content. +#. For info, see Appendix D of http://www.w3.org/TR/1998/WD-rdf-schema-19980409/ +#: ../../po/../src/dialogs/rdf.cpp:283 +msgid "Coverage" +msgstr "Висвітлення" + +#: ../../po/../src/dialogs/rdf.cpp:284 +msgid "Extent or scope of this document." +msgstr "Висвітлення або тематичні рамки цього документу." + +#: ../../po/../src/dialogs/rdf.cpp:288 +msgid "A short account of the content of this document." +msgstr "Короткий опис вмісту документа." + +#. FIXME: need to handle 1 agent per line of input +#: ../../po/../src/dialogs/rdf.cpp:292 +msgid "Contributors" +msgstr "Співавтори" + +#: ../../po/../src/dialogs/rdf.cpp:293 +msgid "" +"Names of entities responsible for making contributions to the content of " +"this document." +msgstr "Назви суб'єктів, що зробили внесок у створення цього документу. " + +#. TRANSLATORS: URL to a page that defines the license for the document +#: ../../po/../src/dialogs/rdf.cpp:297 +msgid "URI" +msgstr "URI" + +#. TRANSLATORS: this is where you put a URL to a page that defines the license +#: ../../po/../src/dialogs/rdf.cpp:299 +msgid "URI to this document's license's namespace definition." +msgstr "URI тексту ліцензії, що застосовується до цього документу." + +#. TRANSLATORS: fragment of XML representing the license of the document +#: ../../po/../src/dialogs/rdf.cpp:303 +msgid "Fragment" +msgstr "Фрагмент" + +#: ../../po/../src/dialogs/rdf.cpp:304 +msgid "XML fragment for the RDF 'License' section." +msgstr "XML-фрагмент RDF-розділу \"Ліцензія\"" + +#: ../../po/../src/dialogs/stroke-style.cpp:774 +#: ../../po/../src/widgets/gradient-vector.cpp:263 +#: ../../po/../src/widgets/paint-selector.cpp:751 +msgid "No document selected" +msgstr "Документ не вибрано" + +#: ../../po/../src/dialogs/stroke-style.cpp:992 +msgid "Stroke width" +msgstr "Товщина штриха" + +#. Join type +#. TRANSLATORS: The line join style specifies the shape to be used at the +#. corners of paths. It can be "miter", "round" or "bevel". +#: ../../po/../src/dialogs/stroke-style.cpp:1015 +msgid "Join:" +msgstr "З'єднання:" + +#. TRANSLATORS: Miter join: joining lines with a sharp (pointed) corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1027 +msgid "Miter join" +msgstr "Гостре" + +#. TRANSLATORS: Round join: joining lines with a rounded corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1035 +msgid "Round join" +msgstr "Округлене" + +#. TRANSLATORS: Bevel join: joining lines with a blunted (flattened) corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1043 +msgid "Bevel join" +msgstr "Фасочне" + +#. Miterlimit +#. TRANSLATORS: Miter limit: only for "miter join", this limits the length +#. of the sharp "spike" when the lines connect at too sharp an angle. +#. When two line segments meet at a sharp angle, a miter join results in a +#. spike that extends well beyond the connection point. The purpose of the +#. miter limit is to cut off such spikes (i.e. convert them into bevels) +#. when they become too long. +#: ../../po/../src/dialogs/stroke-style.cpp:1054 +msgid "Miter limit:" +msgstr "Межа вістря:" + +#: ../../po/../src/dialogs/stroke-style.cpp:1062 +msgid "Maximum length of the miter (in units of stroke width)" +msgstr "Найбільша довжина вістря (у одиницях товщини штриха)" + +#. Cap type +#. TRANSLATORS: cap type specifies the shape for the ends of lines +#: ../../po/../src/dialogs/stroke-style.cpp:1075 +msgid "Cap:" +msgstr "Закінчення:" + +#. TRANSLATORS: Butt cap: the line shape does not extend beyond the end point +#. of the line; the ends of the line are square +#: ../../po/../src/dialogs/stroke-style.cpp:1086 +msgid "Butt cap" +msgstr "Плоскі" + +#. TRANSLATORS: Round cap: the line shape extends beyond the end point of the +#. line; the ends of the line are rounded +#: ../../po/../src/dialogs/stroke-style.cpp:1093 +msgid "Round cap" +msgstr "Округлені" + +#. TRANSLATORS: Square cap: the line shape extends beyond the end point of the +#. line; the ends of the line are square +#: ../../po/../src/dialogs/stroke-style.cpp:1100 +msgid "Square cap" +msgstr "Квадратні" + +#. Dash +#: ../../po/../src/dialogs/stroke-style.cpp:1106 +msgid "Dashes:" +msgstr "Пунктир:" + +#. TRANSLATORS: Path markers are an SVG feature that allows you to attach arbitrary shapes +#. (arrowheads, bullets, faces, whatever) to the start, end, or middle nodes of a path. +#: ../../po/../src/dialogs/stroke-style.cpp:1127 +msgid "Start Markers:" +msgstr "Початкові маркери:" + +#: ../../po/../src/dialogs/stroke-style.cpp:1137 +msgid "Mid Markers:" +msgstr "Серединні маркери:" + +#: ../../po/../src/dialogs/stroke-style.cpp:1148 +msgid "End Markers:" +msgstr "Кінцеві маркери:" + +#: ../../po/../src/dialogs/swatches.cpp:424 +#, c-format +msgid "Palettes directory (%s) is unavailable." +msgstr "Каталог з палітрами (%s) недоступний." + +#. TODO: Insert widgets +#: ../../po/../src/dialogs/text-edit.cpp:199 +#: ../../po/../src/ui/dialog/text-properties.cpp:36 +msgid "Font" +msgstr "Шрифт" + +#: ../../po/../src/dialogs/text-edit.cpp:216 +msgid "Layout" +msgstr "Розташування" + +#: ../../po/../src/dialogs/text-edit.cpp:229 +msgid "Align lines left" +msgstr "Вирівняти рядки за лівою межею" + +#. TRANSLATORS: `Center' here is a verb. +#: ../../po/../src/dialogs/text-edit.cpp:243 +msgid "Center lines" +msgstr "Центрувати рядки" + +#: ../../po/../src/dialogs/text-edit.cpp:256 +msgid "Align lines right" +msgstr "Вирівняти рядки за правою межею" + +#: ../../po/../src/dialogs/text-edit.cpp:278 +msgid "Horizontal text" +msgstr "Горизонтальний текст" + +#: ../../po/../src/dialogs/text-edit.cpp:292 +msgid "Vertical text" +msgstr "Вертикальний текст" + +#: ../../po/../src/dialogs/text-edit.cpp:307 +msgid "Line spacing:" +msgstr "Міжрядковий інтервал:" + +#: ../../po/../src/dialogs/text-edit.cpp:400 +msgid "Set as default" +msgstr "Зберегти типовим" + +#: ../../po/../src/dialogs/tiledialog.cpp:603 +msgid "Rows:" +msgstr "Рядків:" + +#: ../../po/../src/dialogs/tiledialog.cpp:613 +msgid "Number of rows" +msgstr "Кількість рядків" + +#: ../../po/../src/dialogs/tiledialog.cpp:617 +msgid "Equal height" +msgstr "Однакова висота" + +#: ../../po/../src/dialogs/tiledialog.cpp:627 +msgid "If not set, each row has the height of the tallest object in it" +msgstr "" +"Якщо не відмічено, висота кожного рядка дорівнює висоті найвищого об'єкта в " +"ньому" + +#. #### Radio buttons to control vertical alignment #### +#. #### Radio buttons to control horizontal alignment #### +#: ../../po/../src/dialogs/tiledialog.cpp:637 +#: ../../po/../src/dialogs/tiledialog.cpp:708 +msgid "Align:" +msgstr "Вирівнювання:" + +#: ../../po/../src/dialogs/tiledialog.cpp:672 +msgid " X " +msgstr " X " + +#. #### Number of columns #### +#: ../../po/../src/dialogs/tiledialog.cpp:678 +msgid "Columns:" +msgstr "Стовпчиків:" + +#: ../../po/../src/dialogs/tiledialog.cpp:688 +msgid "Number of columns" +msgstr "Кількість стовпчиків" + +#: ../../po/../src/dialogs/tiledialog.cpp:692 +msgid "Equal width" +msgstr "Однакова ширина" + +#: ../../po/../src/dialogs/tiledialog.cpp:701 +msgid "If not set, each column has the width of the widest object in it" +msgstr "" +"Якщо не відмічено, ширина кожного стовпчика дорівнює ширині найширшого " +"об'єкту в ньому" + +#. #### Radio buttons to control spacing manually or to fit selection bbox #### +#: ../../po/../src/dialogs/tiledialog.cpp:746 +msgid "Fit into selection box" +msgstr "Зберегти ширину та висоту виділення" + +#: ../../po/../src/dialogs/tiledialog.cpp:753 +msgid "Set spacing:" +msgstr "Встановити інтервал:" + +#. #### Y Padding #### +#: ../../po/../src/dialogs/tiledialog.cpp:777 +msgid "Row spacing: " +msgstr "Міжрядковий інтервал: " + +#: ../../po/../src/dialogs/tiledialog.cpp:786 +msgid "Vertical spacing between rows" +msgstr "Вертикальний інтервал між рядками" + +#. #### X padding #### +#: ../../po/../src/dialogs/tiledialog.cpp:795 +msgid "Column spacing:" +msgstr "Інтервал між стовпчиками:" + +#: ../../po/../src/dialogs/tiledialog.cpp:804 +msgid "Horizontal spacing between columns" +msgstr "Горизонтальний інтервал між стовпчиками" + +#: ../../po/../src/dialogs/tiledialog.cpp:818 +#, fuzzy +msgid "Arrange selected objects" +msgstr "Згрупувати виділені об'єкти" + +#: ../../po/../src/dialogs/xml-tree.cpp:178 +msgid "Click to select nodes, drag to rearrange." +msgstr "" +"Клацніть, щоб виділити вузли, перетягуванням можна змінити " +"порядок." + +#: ../../po/../src/dialogs/xml-tree.cpp:189 +msgid "Click attribute to edit." +msgstr "Клацніть мишею на атрибуті для редагування." + +#: ../../po/../src/dialogs/xml-tree.cpp:193 +#, c-format +msgid "" +"Attribute %s selected. Press Ctrl+Enter when done editing to " +"commit changes." +msgstr "" +"Виділено атрибут %s. Натисніть Ctrl+Enter, коли закінчите " +"редагування." + +#: ../../po/../src/dialogs/xml-tree.cpp:284 +msgid "Drag to reorder nodes" +msgstr "Використовуйте мишу для перетягування вузлів" + +#: ../../po/../src/dialogs/xml-tree.cpp:304 +msgid "New element node" +msgstr "Створити вузол елемента" + +#: ../../po/../src/dialogs/xml-tree.cpp:326 +msgid "New text node" +msgstr "Створити вузол з текстом" + +#: ../../po/../src/dialogs/xml-tree.cpp:347 +msgid "Duplicate node" +msgstr "Дублювати вузол" + +#: ../../po/../src/dialogs/xml-tree.cpp:368 +msgid "Delete node" +msgstr "Видалити вузол" + +#: ../../po/../src/dialogs/xml-tree.cpp:384 +msgid "Unindent node" +msgstr "Перемістити до кореня" + +#: ../../po/../src/dialogs/xml-tree.cpp:399 +msgid "Indent node" +msgstr "Перемістити від кореня" + +#: ../../po/../src/dialogs/xml-tree.cpp:411 +msgid "Raise node" +msgstr "Підняти вузол" + +#: ../../po/../src/dialogs/xml-tree.cpp:423 +msgid "Lower node" +msgstr "Опустити вузол" + +#: ../../po/../src/dialogs/xml-tree.cpp:468 +msgid "Delete attribute" +msgstr "Видалити атрибут" + +#. TRANSLATORS: "Attribute" is a noun here +#: ../../po/../src/dialogs/xml-tree.cpp:513 +msgid "Attribute name" +msgstr "Назва атрибута" + +#. TRANSLATORS: "Set" is a verb here +#: ../../po/../src/dialogs/xml-tree.cpp:533 +msgid "Set attribute" +msgstr "Встановити атрибут" + +#. TRANSLATORS: "Set" is a verb here +#: ../../po/../src/dialogs/xml-tree.cpp:535 +msgid "Set" +msgstr "Встановити" + +#. TRANSLATORS: "Attribute" is a noun here +#: ../../po/../src/dialogs/xml-tree.cpp:558 +msgid "Attribute value" +msgstr "Значення атрибута" + +#: ../../po/../src/dialogs/xml-tree.cpp:1318 +msgid "New element node..." +msgstr "Створити новий вузол..." + +#: ../../po/../src/dialogs/xml-tree.cpp:1339 +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:100 +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:98 +msgid "Cancel" +msgstr "Скасувати" + +#: ../../po/../src/dialogs/xml-tree.cpp:1345 +msgid "Create" +msgstr "Створити" + +#: ../../po/../src/dialogs/xml-tree.cpp:1458 +#, c-format +msgid "" +"Cannot set %s: Another element with value %s already exists!" +msgstr "" +"Не вдається встановити %s: вже існує інший елемент зі значенням %" +"s!" + +#: ../../po/../src/document.cpp:369 +#, c-format +msgid "New document %d" +msgstr "Новий документ %d" + +#: ../../po/../src/document.cpp:401 +#, c-format +msgid "Memory document %d" +msgstr "Документ у пам'яті %d" + +#: ../../po/../src/document.cpp:524 +#, c-format +msgid "Unnamed document %d" +msgstr "Документ без назви %d" + +#. We hit green anchor, closing Green-Blue-Red +#: ../../po/../src/draw-context.cpp:441 +msgid "Path is closed." +msgstr "Контур закритий." + +#. We hit bot start and end of single curve, closing paths +#: ../../po/../src/draw-context.cpp:456 +msgid "Closing path." +msgstr "Закривається контур." + +#. alpha of color under cursor, to show in the statusbar +#. locale-sensitive printf is OK, since this goes to the UI, not into SVG +#: ../../po/../src/dropper-context.cpp:354 +#, c-format +msgid " alpha %.3g" +msgstr " альфа %.3g" + +#. where the color is picked, to show in the statusbar +#: ../../po/../src/dropper-context.cpp:356 +#, c-format +msgid ", averaged with radius %d" +msgstr ", усереднений з радіусом %d" + +#: ../../po/../src/dropper-context.cpp:356 +msgid " under cursor" +msgstr " під курсором" + +#. message, to show in the statusbar +#: ../../po/../src/dropper-context.cpp:358 +msgid "Release mouse to set color." +msgstr "Відпустіть кнопку для встановлення кольору." + +#: ../../po/../src/dropper-context.cpp:358 +#: ../../po/../src/tools-switch.cpp:207 +msgid "" +"Click to set fill, Shift+click to set stroke; drag to " +"average color in area; with Alt to pick inverse color; Ctrl+C " +"to copy the color under mouse to clipboard" +msgstr "" +"Клацання встановлює колір заповнення, Shift+клацання змінює " +"колір штриха. Клацання+перетягування обчислює середній колір області; " +"разом з Alt береться інверсний колір; Ctrl+C копіює у буфер " +"колір під курсором." + +#: ../../po/../src/extension/dependency.cpp:244 +msgid "Dependency::" +msgstr "Залежність::" + +#: ../../po/../src/extension/dependency.cpp:245 +msgid " type: " +msgstr " тип: " + +#: ../../po/../src/extension/dependency.cpp:246 +msgid " location: " +msgstr " розташування: " + +#: ../../po/../src/extension/dependency.cpp:247 +msgid " string: " +msgstr " рядок: " + +#: ../../po/../src/extension/dependency.cpp:250 +msgid " description: " +msgstr " опис: " + +#. static int i = 0; +#. std::cout << "Checking module[" << i++ << "]: " << name << std::endl; +#: ../../po/../src/extension/extension.cpp:244 +msgid "" +" This is caused by an improper .inx file for this extension. An improper ." +"inx file could have been caused by a faulty installation of Inkscape." +msgstr "" +" Це викликано неправильним файлом .inx для цього розширення. Причиною появи " +"неправильного файлу .inx може бути некоректне встановлення Inkscape." + +#: ../../po/../src/extension/extension.cpp:247 +msgid "an ID was not defined for it." +msgstr "для нього не вказано ідентифікатор ID." + +#: ../../po/../src/extension/extension.cpp:251 +msgid "there was no name defined for it." +msgstr "для нього не вказано назви." + +#: ../../po/../src/extension/extension.cpp:255 +msgid "the XML description of it got lost." +msgstr "втрачено його XML опис." + +#: ../../po/../src/extension/extension.cpp:259 +msgid "no implementation was defined for the extension." +msgstr "для розширення не вказано реалізацію." + +#. std::cout << "Failed: " << *(_deps[i]) << std::endl; +#: ../../po/../src/extension/extension.cpp:266 +msgid "a dependency was not met." +msgstr "залежність не була задоволена." + +#: ../../po/../src/extension/extension.cpp:286 +msgid "Extension \"" +msgstr "Помилка у розширенні \"" + +#: ../../po/../src/extension/extension.cpp:286 +msgid "\" failed to load because " +msgstr "\". Причина: " + +#: ../../po/../src/extension/extension.cpp:565 +#, c-format +msgid "Could not create extension error log file '%s'" +msgstr "Не вдається створити файл журналу помилок розширення '%s'" + +#. This is some filler text, needs to change before relase +#: ../../po/../src/extension/error-file.cpp:56 +msgid "" +"One or more extensions failed to load\n" +"\n" +"The failed extensions have been skipped. Inkscape will continue to run " +"normally but those extensions will be unavailable. For details to " +"troubleshoot this problem, please refer to the error log located at: " +msgstr "" +"Не вдається завантажити одне або " +"більше розширень.\n" +"\n" +"Розширення, яке викликали помилки були пропущені. Inkscape продовжить " +"звичайний запуск, але ці розширення будуть недоступні. Подробиці щодо цієї " +"проблеми дивіться у файлі журналу помилок:" + +#. This is some filler text, needs to change before relase +#: ../../po/../src/extension/error-file.cpp:65 +msgid "Show dialog on startup" +msgstr "Показувати діалогове вікно при запуску" + +#: ../../po/../src/extension/implementation/script.cpp:845 +msgid "" +"Inkscape has received an error from the script that it called. The text " +"returned with the error is included below. Inkscape will continue working, " +"but the action you requested has been cancelled." +msgstr "" +"Запущений з Inkscape сценарій завершився з помилкою. Отриманий з помилкою " +"текст показано нижче. Inkscape продовжить роботу, але дія, що виконувалась " +"буде скасована." + +#: ../../po/../src/extension/implementation/script.cpp:858 +msgid "" +"Inkscape has received additional data from the script executed. The script " +"did not return an error, but this may indicate the results will not be as " +"expected." +msgstr "" +"Inkscape отримав додаткові дані від виконаного сценарію. Сценарій не " +"повернув код помилки, проте це може означати, що результат не такий як " +"очікувався." + +#: ../../po/../src/extension/init.cpp:173 +msgid "Null external module directory name. Modules will not be loaded." +msgstr "" +"Порожнє поле назви каталогу зовнішнього модуля. Модулі не будуть " +"завантажуватись." + +#: ../../po/../src/extension/init.cpp:187 +#, c-format +msgid "" +"Modules directory (%s) is unavailable. External modules in that directory " +"will not be loaded." +msgstr "" +"Каталог модулів (%s) недоступний. Зовнішнього модулі з цього каталогу не " +"будуть завантажені." + +#: ../../po/../src/extension/internal/gnome.cpp:80 +msgid "Select printer" +msgstr "Виберіть принтер" + +#: ../../po/../src/extension/internal/gnome.cpp:131 +msgid "Inkscape: Print Preview" +msgstr "Inkscape: Попередній перегляд" + +#: ../../po/../src/extension/internal/grid.cpp:213 +msgid "Line Width" +msgstr "Ширина лінії" + +#: ../../po/../src/extension/internal/grid.cpp:214 +msgid "Horizontal Spacing" +msgstr "Інтервал по горизонталі" + +#: ../../po/../src/extension/internal/grid.cpp:215 +msgid "Vertical Spacing" +msgstr "Інтервал по вертикалі" + +#: ../../po/../src/extension/internal/grid.cpp:216 +msgid "Horizontal Offset" +msgstr "Горизонтальний зсув" + +#: ../../po/../src/extension/internal/grid.cpp:217 +msgid "Vertical Offset" +msgstr "Вертикальний зсув" + +#: ../../po/../src/extension/internal/ps.cpp:123 +msgid "Print Destination" +msgstr "Цільовий принтер" + +#. Print properties frame +#: ../../po/../src/extension/internal/ps.cpp:138 +msgid "Print properties" +msgstr "Властивості друку" + +#: ../../po/../src/extension/internal/ps.cpp:145 +msgid "Print using PostScript operators" +msgstr "Друкувати з використанням PostScript" + +#: ../../po/../src/extension/internal/ps.cpp:147 +msgid "" +"Use PostScript vector operators. The resulting image is usually smaller in " +"file size and can be arbitrarily scaled, but alpha transparency and patterns " +"will be lost." +msgstr "" +"Використовувати PostScript. В результаті зображення зазвичай має менший " +"розмір файлу та може масштабуватись довільним чином, але альфа-канал, " +"градієнти та візерунки будуть втрачені." + +#: ../../po/../src/extension/internal/ps.cpp:152 +msgid "Print as bitmap" +msgstr "Друкувати як растрове зображення" + +#: ../../po/../src/extension/internal/ps.cpp:154 +msgid "" +"Print everything as bitmap. The resulting image is usually larger in file " +"size and cannot be arbitrarily scaled without quality loss, but all objects " +"will be rendered exactly as displayed." +msgstr "" +"Друкувати як растрове зображення. В результаті розмір файлу зображення буде " +"більшим, та не зможе масштабуватись без втрати якості. Проте усі об'єкти " +"будуть друкуватись так, як виглядають на екрані." + +#: ../../po/../src/extension/internal/ps.cpp:168 +msgid "Preferred resolution (dots per inch) of bitmap" +msgstr "Основна роздільна здатність (у точках на дюйм)" + +#: ../../po/../src/extension/internal/ps.cpp:182 +msgid "Resolution:" +msgstr "Роздільна здатність:" + +#. Print destination frame +#: ../../po/../src/extension/internal/ps.cpp:186 +msgid "Print destination" +msgstr "Цільовий принтер" + +#: ../../po/../src/extension/internal/ps.cpp:192 +msgid "" +"Use '> filename' to print to file.\n" +"Use '| prog arg...' to pipe to a program." +msgstr "" +"Використовуйте '> filename' для друкування у файл.\n" +"Використовуйте '| prog arg...' для передавання виводу іншій програмі." + +#: ../../po/../src/extension/internal/ps.cpp:1227 +msgid "write error occurred" +msgstr "помилка запису" + +#: ../../po/../src/extension/prefdialog.cpp:21 +msgid " Preferences" +msgstr "Параметри" + +#. We can't call sp_ui_error_dialog because we may be +#. running from the console, in which case calling sp_ui +#. routines will cause a segfault. See bug 1000350 - bryce +#. sp_ui_error_dialog(_("Format autodetect failed. The file is being opened as SVG.")); +#: ../../po/../src/extension/system.cpp:105 +msgid "Format autodetect failed. The file is being opened as SVG." +msgstr "Не вдається визначити формат файлу. Файл відкривається як SVG." + +#. TRANSLATORS: default.svg is localizable - this is the name of the default document +#. template. This way you can localize the default pagesize, translate the name of +#. the default layer, etc. If you wish to localize this file, please create a +#. localized share/templates/default.xx.svg file, where xx is your language code. +#: ../../po/../src/file.cpp:133 +msgid "default.svg" +msgstr "типовий.svg" + +#: ../../po/../src/file.cpp:215 ../../po/../src/file.cpp:900 +#, c-format +msgid "Failed to load the requested file %s" +msgstr "Не вдається завантажити запитаний файл %s" + +#: ../../po/../src/file.cpp:240 +msgid "Document not saved yet. Cannot revert." +msgstr "" +"Документ ще не був збережений. Неможливо повернутись до попереднього стану." + +#: ../../po/../src/file.cpp:246 +#, c-format +msgid "Changes will be lost! Are you sure you want to reload document %s?" +msgstr "" +"Зміни будуть втрачені! Ви впевнені, що бажаєте завантажити документ %s знову?" + +#: ../../po/../src/file.cpp:266 +msgid "Document reverted." +msgstr "Документ повернутий до попереднього стану." + +#: ../../po/../src/file.cpp:268 +msgid "Document not reverted." +msgstr "Документ не повернутий до попереднього стану." + +#: ../../po/../src/file.cpp:382 +msgid "Select file to open" +msgstr "Виберіть файл" + +#: ../../po/../src/file.cpp:518 +#, c-format +msgid "Removed %i unused definition in <defs>." +msgid_plural "Removed %i unused definitions in <defs>." +msgstr[0] "Видалено %i непотрібний елемент у <defs>." +msgstr[1] "Видалено %i непотрібних елементи у <defs>." +msgstr[2] "Видалено %i непотрібних елементів у <defs>." + +#: ../../po/../src/file.cpp:523 +msgid "No unused definitions in <defs>." +msgstr "Немає непотрібних елементів у <defs>." + +#: ../../po/../src/file.cpp:548 +#, c-format +msgid "" +"No Inkscape extension found to save document (%s). This may have been " +"caused by an unknown filename extension." +msgstr "" +"Не знайдено модуль збереження документу (%s). Можливо, невідоме розширення " +"файлу." + +#: ../../po/../src/file.cpp:549 ../../po/../src/file.cpp:557 +msgid "Document not saved." +msgstr "Документ не збережено." + +#: ../../po/../src/file.cpp:556 +#, c-format +msgid "File %s could not be saved." +msgstr "Файл %s неможливо зберегти." + +#: ../../po/../src/file.cpp:566 +msgid "Document saved." +msgstr "Документ збережено." + +#: ../../po/../src/file.cpp:614 +#, c-format +msgid "drawing%s" +msgstr "рисунок%s" + +#: ../../po/../src/file.cpp:620 +#, c-format +msgid "drawing-%d%s" +msgstr "рисунок-%d%s" + +#: ../../po/../src/file.cpp:655 +msgid "Select file to save to" +msgstr "Виберіть файл для збереження" + +#: ../../po/../src/file.cpp:739 +msgid "No changes need to be saved." +msgstr "Файл не було змінено. Збереження непотрібне." + +#: ../../po/../src/file.cpp:926 +msgid "Select file to import" +msgstr "Виберіть файл для імпорту" + +#: ../../po/../src/gradient-context.cpp:263 +msgid "Ctrl: snap gradient angle" +msgstr "Ctrl: обмежити кут градієнта" + +#: ../../po/../src/gradient-context.cpp:264 +msgid "Shift: draw gradient around the starting point" +msgstr "Shift: малювати навколо початкової точки" + +#. We did an undoable action, but sp_document_done will be called by the knot when released +#. status text; we do not track coords because this branch is run once, not all the time +#. during drag +#: ../../po/../src/gradient-context.cpp:462 +#, c-format +msgid "Gradient for %d objects; with Ctrl to snap angle" +msgstr "Градієнт для %d об'єктів; з Ctrl - кут обмежується" + +#: ../../po/../src/gradient-context.cpp:464 +msgid "Select objects on which to create gradient." +msgstr "Виділіть об'єкти до яких буде застосовано градієнт." + +#: ../../po/../src/gradient-drag.cpp:65 +msgid "Linear gradient start" +msgstr "Початок лінійного градієнту" + +#. POINT_LG_P1 +#: ../../po/../src/gradient-drag.cpp:66 +msgid "Linear gradient end" +msgstr "Кінець лінійного градієнту" + +#: ../../po/../src/gradient-drag.cpp:67 +msgid "Radial gradient center" +msgstr "Центр радіального градієнту" + +#: ../../po/../src/gradient-drag.cpp:68 ../../po/../src/gradient-drag.cpp:69 +msgid "Radial gradient radius" +msgstr "Радіус радіального градієнту" + +#: ../../po/../src/gradient-drag.cpp:70 +msgid "Radial gradient focus" +msgstr "Фокус радіального градієнту" + +#: ../../po/../src/gradient-drag.cpp:659 +#, c-format +msgid "" +"%s for: %s%s; drag with Ctrl to snap angle, with Ctrl+Alt to " +"preserve angle, with Ctrl+Shift to scale around center" +msgstr "" +"%s для: %s%s; Ctrl - обмежує кут, Ctrl+Alt фіксує кут, Ctrl" +"+Shift масштабування відносно центру" + +#: ../../po/../src/gradient-drag.cpp:662 +msgid " (stroke)" +msgstr " (штрих)" + +#: ../../po/../src/gradient-drag.cpp:665 +msgid "" +"Radial gradient center and focus; drag with Shift to " +"separate focus" +msgstr "" +"Центр та фокус радіального градієнту; для відокремлення фокусу " +"перетягуйте з Shift" + +#: ../../po/../src/gradient-drag.cpp:667 +#, c-format +msgid "" +"Gradient point shared by %d gradients; drag with Shift to " +"separate" +msgstr "" +"Точка градієнту спільна для %d градієнтів; для відокремлення " +"перетягуйте з Shift" + +#: ../../po/../src/helper/units.cpp:40 +msgid "Unit" +msgstr "Одиниця" + +#: ../../po/../src/helper/units.cpp:40 +msgid "Units" +msgstr "Одиниці" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Point" +msgstr "Пункт" + +#: ../../po/../src/helper/units.cpp:41 +msgid "pt" +msgstr "пт" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Points" +msgstr "Пункти" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Pt" +msgstr "пт" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Pixel" +msgstr "Точка" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Pixels" +msgstr "Точки" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Px" +msgstr "точок" + +#. You can add new elements from this point forward +#: ../../po/../src/helper/units.cpp:44 ../share/extensions/straightseg.inx.h:2 +msgid "Percent" +msgstr "Відсоток" + +#: ../../po/../src/helper/units.cpp:44 +msgid "Percents" +msgstr "Відсотки" + +#: ../../po/../src/helper/units.cpp:45 +msgid "Millimeter" +msgstr "Міліметр" + +#: ../../po/../src/helper/units.cpp:45 +msgid "mm" +msgstr "мм" + +#: ../../po/../src/helper/units.cpp:45 +msgid "Millimeters" +msgstr "Міліметри" + +#: ../../po/../src/helper/units.cpp:46 +msgid "Centimeter" +msgstr "Сантиметр" + +#: ../../po/../src/helper/units.cpp:46 +msgid "cm" +msgstr "см" + +#: ../../po/../src/helper/units.cpp:46 +msgid "Centimeters" +msgstr "Сантиметри" + +#: ../../po/../src/helper/units.cpp:47 +msgid "Meter" +msgstr "Метр" + +#: ../../po/../src/helper/units.cpp:47 +msgid "m" +msgstr "м" + +#: ../../po/../src/helper/units.cpp:47 +msgid "Meters" +msgstr "Метри" + +#. no svg_unit +#: ../../po/../src/helper/units.cpp:48 +msgid "Inch" +msgstr "Дюйм" + +#: ../../po/../src/helper/units.cpp:48 +msgid "in" +msgstr "\"" + +#: ../../po/../src/helper/units.cpp:48 +msgid "Inches" +msgstr "Дюйми" + +#. Volatiles do not have default, so there are none here +#. TRANSLATORS: for info, see http://www.w3.org/TR/REC-CSS2/syndata.html#length-units +#: ../../po/../src/helper/units.cpp:51 +msgid "Em square" +msgstr "Em квадрат" + +#: ../../po/../src/helper/units.cpp:51 +msgid "em" +msgstr "em" + +#: ../../po/../src/helper/units.cpp:51 +msgid "Em squares" +msgstr "Em квадрати" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/REC-CSS2/syndata.html#length-units +#: ../../po/../src/helper/units.cpp:53 +msgid "Ex square" +msgstr "Ex квадрат" + +#: ../../po/../src/helper/units.cpp:53 +msgid "ex" +msgstr "ex" + +#: ../../po/../src/helper/units.cpp:53 +msgid "Ex squares" +msgstr "Ex квадрати" + +#: ../../po/../src/inkscape.cpp:468 +msgid "Untitled document" +msgstr "Без назви" + +#. Show nice dialog box +#: ../../po/../src/inkscape.cpp:497 +msgid "Inkscape encountered an internal error and will close now.\n" +msgstr "Внутрішня помилка. Inkscape зараз буде закритий.\n" + +#: ../../po/../src/inkscape.cpp:498 +msgid "" +"Automatic backups of unsaved documents were done to the following " +"locations:\n" +msgstr "" +"Виконано автоматичне збереження резервних копій не збережених документів:\n" + +#: ../../po/../src/inkscape.cpp:499 +msgid "Automatic backup of the following documents failed:\n" +msgstr "Не вдається створити резервну копію такого документу:\n" + +#: ../../po/../src/inkscape.cpp:634 +#, c-format +msgid "" +"Cannot create directory %s.\n" +"%s" +msgstr "" +"Не вдається створити каталог %s.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:635 +#, c-format +msgid "" +"%s is not a valid directory.\n" +"%s" +msgstr "" +"%s не є правильним каталогом.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:636 +#, c-format +msgid "" +"Cannot create file %s.\n" +"%s" +msgstr "" +"Не вдається створити файл %s.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:637 +#, c-format +msgid "" +"Cannot write file %s.\n" +"%s" +msgstr "" +"Не вдається записати файл %s.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:638 +msgid "" +"Although Inkscape will run, it will use default settings,\n" +"and any changes made in preferences will not be saved." +msgstr "" +"Inkscape буде використовувати типові параметри. Змінені\n" +"параметри не будуть збережені." + +#: ../../po/../src/inkscape.cpp:708 +#, c-format +msgid "" +"%s is not a regular file.\n" +"%s" +msgstr "" +"%s не є звичайним файлом.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:709 +#, c-format +msgid "" +"%s not a valid XML file, or\n" +"you don't have read permissions on it.\n" +"%s" +msgstr "" +"%s не є звичайним XML-файлом, чи\n" +"у вас немає прав на його відкривання.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:711 +#, c-format +msgid "" +"%s is not a valid menus file.\n" +"%s" +msgstr "" +"%s не є файлом меню.\n" +"%s" + +#: ../../po/../src/inkscape.cpp:712 +msgid "" +"Inkscape will run with default menus.\n" +"New menus will not be saved." +msgstr "" +"Inkscape буде використовувати типове меню.\n" +"Змінені меню не будуть збережені." + +#. sp_ui_menu_append_check_item_from_verb(m, view, _("_Menu"), _("Show or hide the menu bar"), "menu", +#. checkitem_toggled, checkitem_update, 0); +#: ../../po/../src/interface.cpp:753 +msgid "Commands Bar" +msgstr "Панель команд" + +#: ../../po/../src/interface.cpp:753 +msgid "Show or hide the Commands bar (under the menu)" +msgstr "Показати/сховати панель команд (під меню)" + +#: ../../po/../src/interface.cpp:755 +msgid "Tool Controls" +msgstr "Параметри інструментів" + +#: ../../po/../src/interface.cpp:755 +msgid "Show or hide the Tool Controls panel" +msgstr "Показати або сховати панель з параметрами інструментів" + +#: ../../po/../src/interface.cpp:757 +msgid "_Toolbox" +msgstr "_Панель інструментів" + +#: ../../po/../src/interface.cpp:757 +msgid "Show or hide the main toolbox (on the left)" +msgstr "Показати або сховати головну панель інструментів (зліва)" + +#: ../../po/../src/interface.cpp:763 +msgid "_Statusbar" +msgstr "_Рядок стану" + +#: ../../po/../src/interface.cpp:763 +msgid "Show or hide the statusbar (at the bottom of the window)" +msgstr "Показати або сховати рядок стану (внизу вікна)" + +#: ../../po/../src/interface.cpp:820 +#, c-format +msgid "Verb \"%s\" Unknown" +msgstr "Невідоме дієслово \"%s\"" + +#. TRANSLATORS: #%s is the id of the group e.g. , not a number. +#: ../../po/../src/interface.cpp:930 +#, c-format +msgid "Enter group #%s" +msgstr "Увійти у групу №%s" + +#: ../../po/../src/interface.cpp:941 +msgid "Go to parent" +msgstr "На рівень вище" + +#: ../../po/../src/interface.cpp:972 +msgid "Could not parse SVG data" +msgstr "Не вдається прочитати SVG-дані" + +#: ../../po/../src/interface.cpp:1135 +#, c-format +msgid "Overwrite %s" +msgstr "Перезапис %s" + +#: ../../po/../src/interface.cpp:1153 +#, c-format +msgid "" +"The file %s already exists. Do you want to overwrite that file with the " +"current document?" +msgstr "Файл %s вже існує. Записати документ у цей файл?" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:59 +msgid "Jabber connection lost." +msgstr "З'єднання з Jabber втрачено." + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:72 +#, c-format +msgid "Sending message; %u message remaining in send queue." +msgid_plural "Sending message; %u messages remaining in send queue." +msgstr[0] "Надсилається повідомлення; у черзі залишилось %u повідомлення." +msgstr[1] "Надсилається повідомлення; у черзі залишилось %u повідомлення." +msgstr[2] "Надсилається повідомлення; у черзі залишилось %u повідомлень." + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:78 +msgid "Receive queue empty." +msgstr "Черга прийому порожня." + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:154 +#, c-format +msgid "Receiving change; %u change left to process." +msgid_plural "Receiving change; %u changes left to process." +msgstr[0] "Отримуються зміни; залишилось обробити %u зміна." +msgstr[1] "Отримуються зміни; залишилось обробити %u зміни." +msgstr[2] "Отримуються зміни; залишилось обробити %u змін." + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:157 +#, c-format +msgid "%s has left the chatroom." +msgstr "%s вже залишив кімнату розмов." + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:221 +msgid "Nickname %1 is already in use. Please choose a different nickname." +msgstr "Псевдонім %1 вже зайнятий іншою людиною. Виберіть собі інший." + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:225 +msgid "An error was encountered while attempting to connect to the server." +msgstr "Помилка при спробі з'єднатись з сервером." + +#. Check to see if the user made any modifications to this document. If so, +#. we want to give them the option of (1) letting us clear their document or (2) +#. opening a new, blank document for the whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:131 +msgid "%1 has invited you to a whiteboard session." +msgstr "%1 запропонував вас помалювати разом." + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:132 +msgid "Incoming whiteboard invitation from %1" +msgstr "Надійшло повідомлення помалювати разом від %1" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:135 +msgid "Do you wish to accept %1's whiteboard session invitation?" +msgstr "Бажаєте прийняти запрошення %1 помалювати разом?" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:137 +msgid "" +"Would you like to accept %1's invitation in a new document window?\n" +"Accepting the invitation in your current window will discard unsaved changes." +msgstr "" +"Бажаєте помалювати разом з %1 у новому вікні?\n" +"Малювання у поточному документі призведе до очищення історії історії змін." + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:143 +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:198 +msgid "Accept invitation" +msgstr "Прийняти запрошення" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:144 +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:199 +msgid "Decline invitation" +msgstr "Відхилити запрошення" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:145 +msgid "Accept invitation in new document window" +msgstr "Прийняти запрошення у новому вікні документа" + +#. We could not create a new desktop; ask the user if she or he wants to +#. replace the current document and accept the invitation, or reject the invitation. +#. TRANSLATORS: %1 is a userid here +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:196 +msgid "" +"A new document window could not be opened for a whiteboard session with %" +"1" +msgstr "" +"Не вдається відкрити нове вікно документа для спільного з %1 сеансу" + +#. TRANSLATORS: %1 is the peer whom refused our invitation. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:238 +msgid "" +"The user %1 has refused your " +"whiteboard invitation.\n" +"\n" +msgstr "" +"Користувач %1 відхилив ваше " +"запрошення помалювати разом.\n" +"\n" + +#. TRANSLATORS: %1 is the peer whom refused our invitation, %2 is our Jabber identity. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:241 +msgid "" +"You are still connected to a Jabber server as %2, and may send an " +"invitation to %1 again, or you may send an invitation to a different " +"user." +msgstr "" +"Ви досі з'єднані з сервером Jabber як користувач %2, та можете " +"надіслати запрошення %1 ще раз, або надіслати запрошення іншому " +"користувачу." + +#. TRANSLATORS: %1 is the peer whom we tried to contact, but is already in a whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:252 +msgid "" +"The user %1 is already in a " +"whiteboard session.\n" +"\n" +msgstr "" +"Користувач %1 вже малює з вами." +"\n" +"\n" + +#. TRANSLATORS: %1 is the peer whom we tried to contact, but is already in a whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:255 +msgid "" +"You are still connected to a Jabber server as %1, and may send an " +"invitation to a different user." +msgstr "" +"Ви досі з'єднані з сервером Jabber як користувач %1, та можете " +"надіслати запрошення іншому користувачу." + +#: ../../po/../src/jabber_whiteboard/invitation-confirm-dialog.cpp:26 +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:24 +msgid "_Write session file:" +msgstr "_Записати файл сеансу:" + +#: ../../po/../src/jabber_whiteboard/message-processors.cpp:145 +#, c-format +msgid "%s has joined the chatroom." +msgstr "%s зайшов у кімнату для розмов." + +#: ../../po/../src/jabber_whiteboard/message-queue.cpp:87 +#, c-format +msgid "%u change in receive queue." +msgid_plural "%u changes in receive queue." +msgstr[0] "%u зміна у черзі на отримання." +msgstr[1] "%u зміни у черзі на отримання." +msgstr[2] "%u змін у черзі на отримання." + +#: ../../po/../src/jabber_whiteboard/message-queue.cpp:117 +#, c-format +msgid "%u change in send queue." +msgid_plural "%u changes in send queue." +msgstr[0] "%u зміна у черзі на відправку." +msgstr[1] "%u зміни у черзі на відправку." +msgstr[2] "%u змін у черзі на відправку." + +#. if ID is NULL, then we have a real problem -- we were not able to find a key +#. nor generate one. The only thing we can really do here is abort, since we have +#. no way to let the other client(s) uniquely identify this object. +#. FIXME: If this indicates a programming bug, then don't request translation with +#. * _(...): it is most useful in untranslated form so that developers may search for +#. * it when someone reports it in a bug report (as we want users to do for all bugs, +#. * as indicated by it being a g_warning string). +#. * +#. * Otherwise, if it is not a programming bug but a network error or a bug in the +#. * remote peer (perhaps running different software) or whatever, then present it in +#. * an alert box, and avoid use of technical jargon `NULL'. +#. +#: ../../po/../src/jabber_whiteboard/message-utilities.cpp:171 +msgid "" +"ID for new object is NULL even after generation and lookup attempts: the new " +"object will NOT be sent, nor will any of its child objects!" +msgstr "" +"ID нового об'єкту дорівнює NULL, навіть після спроб генерації та пошуку: НЕ " +"буде надіслано ані новий об'єкт, ані будь-які його дочірні об'єкти!" + +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:60 +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:995 +msgid "Select a location and filename" +msgstr "Виберіть розташування та назву файла" + +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:62 +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:997 +msgid "Set filename" +msgstr "Вкажіть назву файлу" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:301 +msgid "No SSL certificate was found." +msgstr "Сертифікат SSL не знайдено." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:304 +msgid "The SSL certificate provided by the Jabber server is untrusted." +msgstr "Неможна довіряти сертифікату SSL, що наданий службою Jabber." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:307 +msgid "The SSL certificate provided by the Jabber server is expired." +msgstr "Вийшов термін дії сертифікату SSL, що наданий сервером Jabber." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:310 +msgid "" +"The SSL certificate provided by the Jabber server has not been activated." +msgstr "Сертифікат SSL, що наданий сервером Jabber, не активований." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:313 +msgid "" +"The SSL certificate provided by the Jabber server contains a hostname that " +"does not match the Jabber server's hostname." +msgstr "" +"Назва вузла у сертифікаті SSL, що наданий сервером Jabber, не співпадає з " +"назвою вузла сервера." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:316 +msgid "" +"The SSL certificate provided by the Jabber server contains an invalid " +"fingerprint." +msgstr "" +"Сертифікат SSL, що наданий сервером Jabber, містить некоректні відбитки." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:319 +msgid "An unknown error occurred while setting up the SSL connection." +msgstr "Невідома помилка при встановленні з'єднання SSL." + +#. TRANSLATORS: %1 is the message that describes the specific error that occurred when +#. establishing the SSL connection. +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:325 +msgid "" +"%1\n" +"\n" +"Do you wish to continue connecting to the Jabber server?" +msgstr "" +"%1\n" +"\n" +"Бажаєте продовжити з'єднання з сервером Jabber?" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:328 +msgid "Continue connecting and ignore further errors" +msgstr "Продовжити з'єднання та ігнорувати подальші помилки" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:329 +msgid "Continue connecting, but warn me of further errors" +msgstr "Продовжити з'єднання та сповіщати про подальші помилки" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:330 +msgid "Cancel connection" +msgstr "Завершити з'єднання" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:777 +#, c-format +msgid "Established whiteboard session with %s." +msgstr "Встановлено сеанс сумісного малювання з %s." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:785 +#, c-format +msgid "%s has left the whiteboard session." +msgstr "%s припинив сеанс сумісного малювання." + +#. Inform the user +#. TRANSLATORS: %1 is the name of the user that disconnected, %2 is the name of the user whom the disconnected user disconnected from. +#. This message is not used in a chatroom context. +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:790 +msgid "" +"The user %1 has left the " +"whiteboard session.\n" +"\n" +msgstr "" +"Користувач %1 припинив сеанс " +"сумісного малювання.\n" +"\n" + +#. TRANSLATORS: %1 and %2 are userids +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:792 +msgid "" +"You are still connected to a Jabber server as %2, and may establish a " +"new session to %1 or a different user." +msgstr "" +"Ви досі з'єднані з сервером Jabber як %2, та можете встановити новий " +"сеанс малювання з %1 або іншим користувачем." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:988 +msgid "" +"Could not open file %1 for session recording.\n" +"The error encountered was: %2.\n" +"\n" +"You may select a different location to record the session, or you may opt to " +"not record this session." +msgstr "" +"Не вдається відкрити файл %1 для запису сеансу.\n" +"Помилка: %2.\n" +"\n" +"Можете вибрати іншу адресу для запису сеансу, або не записувати сеанс " +"взагалі." + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:990 +msgid "Choose a different location" +msgstr "Виберіть інший каталог" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:991 +msgid "Skip session recording" +msgstr "Пропустити запис сеансу" + +#: ../../po/../src/knot.cpp:673 +msgid "Node or handle drag canceled." +msgstr "Переміщення вузла скасовано." + +#: ../../po/../src/libnrtype/FontFactory.cpp:358 +msgid "Ignoring font without family that will crash Pango" +msgstr "Шрифт без сімейства, який може привести до збою Pango, ігнорується" + +#: ../../po/../src/main.cpp:395 +msgid "Print the Inkscape version number" +msgstr "Вивести версію Inkscape" + +#: ../../po/../src/main.cpp:400 +msgid "Do not use X server (only process files from console)" +msgstr "Не використовувати X сервер (лише консольні операції)" + +#: ../../po/../src/main.cpp:405 +msgid "Try to use X server (even if $DISPLAY is not set)" +msgstr "" +"Намагатися використовувати X сервер, навіть якщо змінну $DISPLAY не " +"встановлено" + +#: ../../po/../src/main.cpp:410 +msgid "Open specified document(s) (option string may be excluded)" +msgstr "Відкрити вказані документи (аргумент може бути виключений)" + +#: ../../po/../src/main.cpp:411 ../../po/../src/main.cpp:416 +#: ../../po/../src/main.cpp:421 ../../po/../src/main.cpp:483 +#: ../../po/../src/main.cpp:488 ../../po/../src/main.cpp:493 +msgid "FILENAME" +msgstr "НАЗВА_ФАЙЛА" + +#: ../../po/../src/main.cpp:415 +msgid "Print document(s) to specified output file (use '| program' for pipe)" +msgstr "" +"Друкувати документ(и) у вказаний файл (для передавання програмі " +"використовуйте '| program')" + +#: ../../po/../src/main.cpp:420 +msgid "Export document to a PNG file" +msgstr "Експортувати документ у файл формату PNG" + +#: ../../po/../src/main.cpp:425 +msgid "The resolution used for exporting SVG into bitmap (default 90)" +msgstr "Роздільна здатність для експортування SVG у растр (типово 90)" + +#: ../../po/../src/main.cpp:426 +msgid "DPI" +msgstr "DPI" + +#: ../../po/../src/main.cpp:430 +msgid "" +"Exported area in SVG user units (default is the canvas; 0,0 is lower-left " +"corner)" +msgstr "" +"Область експорту у одиницях SVG (типово - все полотно; 0,0 - лівий нижній " +"кут)" + +#: ../../po/../src/main.cpp:431 +msgid "x0:y0:x1:y1" +msgstr "x0:y0:x1:y1" + +#: ../../po/../src/main.cpp:435 +msgid "Exported area is the entire drawing (not canvas)" +msgstr "Область експорту є суцільним малюнком (не полотном)" + +#: ../../po/../src/main.cpp:440 +msgid "" +"Snap the bitmap export area outwards to the nearest integer values (in SVG " +"user units)" +msgstr "" +"Округлити область експорту растру назовні до найближчого цілого значення (у " +"одиницях SVG)" + +#: ../../po/../src/main.cpp:445 +msgid "The width of exported bitmap in pixels (overrides export-dpi)" +msgstr "Ширина зображення для експорту у точках (перевизначає export-dpi)" + +#: ../../po/../src/main.cpp:446 +msgid "WIDTH" +msgstr "ШИРИНА" + +#: ../../po/../src/main.cpp:450 +msgid "The height of exported bitmap in pixels (overrides export-dpi)" +msgstr "Висота зображення для експорту у точках (перевизначає export-dpi)" + +#: ../../po/../src/main.cpp:451 +msgid "HEIGHT" +msgstr "ВИСОТА" + +#: ../../po/../src/main.cpp:455 +msgid "The ID of the object to export (overrides export-area)" +msgstr "Ідентифікатор об'єкту, що експортується (перевизначає export-area)" + +#: ../../po/../src/main.cpp:456 ../../po/../src/main.cpp:532 +msgid "ID" +msgstr "ID" + +#. TRANSLATORS: this means: "Only export the object whose id is given in --export-id". +#. See "man inkscape" for details. +#: ../../po/../src/main.cpp:462 +msgid "" +"Export just the object with export-id, hide all others (only with export-id)" +msgstr "" +"Експортувати лише об'єкт з заданим ідентифікатором, усі інші приховати (лише " +"з export-id)" + +#: ../../po/../src/main.cpp:467 +msgid "Use stored filename and DPI hints when exporting (only with export-id)" +msgstr "" +"При експорті використовувати збережену назву файлу та розширення (лише з " +"export-id)" + +#: ../../po/../src/main.cpp:472 +msgid "Background color of exported bitmap (any SVG-supported color string)" +msgstr "" +"Колір тла для експорту растрового зображення (будь-яка підтримувана SVG-" +"кольорова гама)" + +#: ../../po/../src/main.cpp:473 +msgid "COLOR" +msgstr "КОЛІР" + +#: ../../po/../src/main.cpp:477 +msgid "Background opacity of exported bitmap (either 0.0 to 1.0, or 1 to 255)" +msgstr "Прозорість тла для експорту растру (від 0.0 до 1.0, або від 1 до 255)" + +#: ../../po/../src/main.cpp:478 +msgid "VALUE" +msgstr "ЗНАЧЕННЯ" + +#: ../../po/../src/main.cpp:482 +msgid "Export document to plain SVG file (no sodipodi or inkscape namespaces)" +msgstr "" +"Експортувати документ у формат \"звичайний SVG\" (без елементів sodipodi: " +"або inkscape:)" + +#: ../../po/../src/main.cpp:487 +msgid "Export document to a PS file" +msgstr "Експортувати документ у файл формату PS" + +#: ../../po/../src/main.cpp:492 +msgid "Export document to an EPS file" +msgstr "Експортувати документ у файл формату EPS" + +#: ../../po/../src/main.cpp:497 +msgid "Convert text object to paths on export (EPS)" +msgstr "Перетворити тестовий об'єкт у контури при експорті (EPS)" + +#: ../../po/../src/main.cpp:502 +msgid "Export files with the bounding box set to the page size (EPS)" +msgstr "" +"Експортувати файли з областю обмеження, що дорівнює розміру сторінки (EPS)" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:508 +msgid "" +"Query the X coordinate of the drawing or, if specified, of the object with --" +"query-id" +msgstr "Запитати X-координату рисунка чи, якщо вказано, об'єкту з --query-id" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:514 +msgid "" +"Query the Y coordinate of the drawing or, if specified, of the object with --" +"query-id" +msgstr "Запитати Y-координату рисунка чи, якщо вказано, об'єкту з --query-id" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:520 +msgid "" +"Query the width of the drawing or, if specified, of the object with --query-" +"id" +msgstr "Запитати ширину рисунка чи, якщо вказано, об'єкту з --query-id" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:526 +msgid "" +"Query the height of the drawing or, if specified, of the object with --query-" +"id" +msgstr "Запитати висоту рисунка чи, якщо вказано, об'єкту з --query-id" + +#: ../../po/../src/main.cpp:531 +msgid "The ID of the object whose dimensions are queried" +msgstr "Ідентифікатор об'єкту, розміри якого опитуються" + +#. TRANSLATORS: this option makes Inkscape print the name (path) of the extension directory +#: ../../po/../src/main.cpp:537 +msgid "Print out the extension directory and exit" +msgstr "Вивести на екран каталог розширення та вийти" + +#: ../../po/../src/main.cpp:542 +msgid "Show given files one-by-one, switch to next on any key/mouse event" +msgstr "" +"Показати дані файли по черзі, перемикання на наступний - будь-яка клавіша" + +#: ../../po/../src/main.cpp:547 +msgid "Use the new Gtkmm GUI interface" +msgstr "Використовувати новий графічний інтерфейс Gtkmm" + +#: ../../po/../src/main.cpp:552 +msgid "Remove unused definitions from the defs section(s) of the document" +msgstr "Видалити з розділу defs документа визначення, що не використовуються" + +#: ../../po/../src/main.cpp:741 +msgid "" +"[OPTIONS...] [FILE...]\n" +"\n" +"Available options:" +msgstr "" +"[ПАРАМЕТРИ...] [ФАЙЛ...]\n" +"\n" +"Доступні параметри:" + +#: ../../po/../src/menus-skeleton.h:17 +msgid "_New" +msgstr "_Створити" + +#: ../../po/../src/menus-skeleton.h:22 +msgid "Open _Recent" +msgstr "Відкрити не_давній" + +#: ../../po/../src/menus-skeleton.h:53 +msgid "_Edit" +msgstr "_Правка" + +#: ../../po/../src/menus-skeleton.h:84 +msgid "_View" +msgstr "_Вигляд" + +#: ../../po/../src/menus-skeleton.h:85 +#, fuzzy +msgid "_Zoom" +msgstr "Масштаб" + +#: ../../po/../src/menus-skeleton.h:102 +msgid "Show/Hide" +msgstr "Показати/сховати" + +#: ../../po/../src/menus-skeleton.h:107 +msgid "_Display mode" +msgstr "" + +#: ../../po/../src/menus-skeleton.h:126 +msgid "_Layer" +msgstr "_Шар" + +#: ../../po/../src/menus-skeleton.h:143 +msgid "_Object" +msgstr "_Об'єкт" + +#: ../../po/../src/menus-skeleton.h:165 +msgid "_Path" +msgstr "_Контур" + +#: ../../po/../src/menus-skeleton.h:188 +msgid "_Text" +msgstr "_Текст" + +#: ../../po/../src/menus-skeleton.h:200 +msgid "Effects" +msgstr "Ефекти" + +#: ../../po/../src/menus-skeleton.h:207 +msgid "Whiteboa_rd" +msgstr "Спільне _малювання" + +#: ../../po/../src/menus-skeleton.h:220 +msgid "_Help" +msgstr "_Довідка" + +#: ../../po/../src/menus-skeleton.h:222 +msgid "Tutorials" +msgstr "Підручники" + +#: ../../po/../src/node-context.cpp:382 +msgid "" +"Ctrl: toggle node type, snap handle angle, move hor/vert; Ctrl" +"+Alt: move along handles" +msgstr "" +"Ctrl: змінити тип вузла, обмежити кут вуса, переміщувати гориз/верт; " +"Ctrl+Alt: переміщувати вздовж вуса чи прямого фрагменту" + +#: ../../po/../src/node-context.cpp:383 +msgid "" +"Shift: toggle node selection, disable snapping, rotate both handles" +msgstr "" +"Shift: виділити/зняти виділення вузла, вимкнути прилипання, обертати " +"обидва вуса" + +#: ../../po/../src/node-context.cpp:384 +msgid "Alt: lock handle length; Ctrl+Alt: move along handles" +msgstr "" +"Alt: зафіксувати довжину вуса; Ctrl+Alt: переміщувати вздовж " +"вусів" + +#: ../../po/../src/nodepath.cpp:1399 ../../po/../src/nodepath.cpp:1411 +#: ../../po/../src/nodepath.cpp:1492 ../../po/../src/nodepath.cpp:1504 +msgid "To join, you must have two endnodes selected." +msgstr "Щоб з'єднати виберіть два кінцевих вузли." + +#: ../../po/../src/nodepath.cpp:1633 ../../po/../src/nodepath.cpp:1647 +msgid "" +"Select two non-endpoint nodes on a path between which to delete " +"segments." +msgstr "" +"Виберіть два не кінцевих вузли у контурі, щоб видалити сектори між " +"ними." + +#: ../../po/../src/nodepath.cpp:1743 +msgid "Cannot find path between nodes." +msgstr "Не вдається знайти контур між вузлами." + +#: ../../po/../src/nodepath.cpp:2822 +#, c-format +msgid "" +"Node handle: angle %0.2f°, length %s; with Ctrl to snap " +"angle; with Alt to lock length; with Shift to rotate both " +"handles" +msgstr "" +"Вус вузла: під кутом %0.2f°, довжина %s; перетягування з " +"Ctrl - обмежує кут; Alt - фіксує довжину; Shift - " +"синхронно обертає протилежний вус" + +#: ../../po/../src/nodepath.cpp:3351 +msgid "" +"Node: drag to edit the path; with Ctrl to snap to horizontal/" +"vertical; with Ctrl+Alt to snap to handles' directions" +msgstr "" +"Вузол: перетягніть для редагування контуру; при натиснутій Ctrl - прилипання до горизонталі/вертикалі; з Ctrl+Alt - вздовж вусів" + +#: ../../po/../src/nodepath.cpp:3375 +msgid "" +"Node handle: drag to shape the curve; with Ctrl to snap angle; " +"with Alt to lock length; with Shift to rotate both handles" +msgstr "" +"Вус вузла: перетягніть для окреслення кривої; Ctrl - обмежує " +"кут; Alt - фіксує довжину; Shift - синхронно повертає обидва " +"вуса" + +#: ../../po/../src/nodepath.cpp:3399 +msgid "" +"Node handle: drag to shape the curve; with Ctrl to snap angle; " +"with Alt to lock length; with Shift to rotate the opposite " +"handle in sync" +msgstr "" +"Вус вузла: перетягніть для окреслення кривоЇ; Ctrl - обмежує " +"кут; Alt - фіксує довжину; Shift - синхронно повертає " +"протилежний вус" + +#. TRANSLATORS: "end" is an adjective here (NOT a verb) +#: ../../po/../src/nodepath.cpp:3591 +msgid "end node" +msgstr "кінцевий вузол" + +#. TRANSLATORS: "cusp" means "sharp" (cusp node); see also the Advanced Tutorial +#: ../../po/../src/nodepath.cpp:3596 +msgid "cusp" +msgstr "гострі" + +#. TRANSLATORS: "smooth" is an adjective here +#: ../../po/../src/nodepath.cpp:3599 +msgid "smooth" +msgstr "гладкі" + +#: ../../po/../src/nodepath.cpp:3601 +msgid "symmetric" +msgstr "симетричні" + +#. TRANSLATORS: "end" is an adjective here (NOT a verb) +#: ../../po/../src/nodepath.cpp:3607 +msgid "end node, handle retracted (drag with Shift to extend)" +msgstr "кінцевий вузол, вус втягнутий (витягується з Shift)" + +#: ../../po/../src/nodepath.cpp:3609 +msgid "one handle retracted (drag with Shift to extend)" +msgstr "один вус втягнутий (витягується з Shift)" + +#: ../../po/../src/nodepath.cpp:3612 +msgid "both handles retracted (drag with Shift to extend)" +msgstr "обидва вуса втягнуто (витягується з Shift)" + +#: ../../po/../src/nodepath.cpp:3624 +msgid "Drag nodes or node handles; arrow keys to move nodes" +msgstr "" +"Перетягуйте вузли та вуса; клавіші-стрілки переміщують " +"виділені вузли" + +#: ../../po/../src/nodepath.cpp:3625 +msgid "Drag the node or its handles; arrow keys to move the node" +msgstr "" +"Перетягуйте вузол або його вуса; клавіші-стрілки переміщують " +"вузол" + +#: ../../po/../src/nodepath.cpp:3651 ../../po/../src/nodepath.cpp:3663 +msgid "Select a single object to edit its nodes or handles." +msgstr "Виділіть об'єкт для редагування його вузлів чи вус." + +#: ../../po/../src/nodepath.cpp:3655 +#, c-format +msgid "" +"0 out of %i node selected. Click, Shift+click, " +"or drag around nodes to select." +msgid_plural "" +"0 out of %i nodes selected. Click, Shift+click, " +"or drag around nodes to select." +msgstr[0] "" +"Виділено 0 з %i вузла. Щоб виділити використовуйте " +"клацання, Shift+клацання, чи перетягування рамки навколо " +"вузлів." +msgstr[1] "" +"Виділено 0 з %i вузлів. Щоб виділити використовуйте " +"клацання, Shift+клацання, чи перетягування рамки навколо " +"вузлів." +msgstr[2] "" +"Виділено 0 з %i вузлів. Щоб виділити використовуйте " +"клацання, Shift+клацання, чи перетягування рамки навколо " +"вузлів." + +#: ../../po/../src/nodepath.cpp:3661 +msgid "Drag the handles of the object to modify it." +msgstr "Перетягніть вуса об'єкту, щоб змінити його." + +#: ../../po/../src/nodepath.cpp:3669 +#, c-format +msgid "%i of %i node selected; %s. %s." +msgid_plural "%i of %i nodes selected; %s. %s." +msgstr[0] "Виділено %i з %i вузла; %s. %s." +msgstr[1] "Виділено %i з %i вузлів; %s. %s." +msgstr[2] "Виділено %i з %i вузлів; %s. %s." + +#: ../../po/../src/nodepath.cpp:3675 +#, c-format +msgid "%i of %i node selected. %s." +msgid_plural "%i of %i nodes selected. %s." +msgstr[0] "Виділено %i з %i вузла. %s." +msgstr[1] "Виділено %i з %i вузлів. %s." +msgstr[2] "Виділено %i з %i вузлів. %s." + +#: ../../po/../src/object-edit.cpp:493 +msgid "" +"Adjust the horizontal rounding radius; with Ctrl to make the " +"vertical radius the same" +msgstr "" +"Скорегувати радіус горизонтального округлення. З Ctrl " +"вертикальний радіус буде таким самим" + +#: ../../po/../src/object-edit.cpp:499 +msgid "" +"Adjust the vertical rounding radius; with Ctrl to make the " +"horizontal radius the same" +msgstr "" +"Скорегувати радіус вертикального округлення. З Ctrl " +"горизонтальний радіус буде таким самим" + +#: ../../po/../src/object-edit.cpp:506 ../../po/../src/object-edit.cpp:513 +msgid "" +"Adjust the width and height of the rectangle; with Ctrl to " +"lock ratio or stretch in one dimension only" +msgstr "" +"Скорегувати ширину та висоту прямокутника. Ctrl фіксує " +"співвідношення чи розтягує/стискає лише один вимір" + +#: ../../po/../src/object-edit.cpp:686 +msgid "Adjust ellipse width, with Ctrl to make circle" +msgstr "Змінити велику вісь еліпса. Ctrl робить коло" + +#: ../../po/../src/object-edit.cpp:689 +msgid "Adjust ellipse height, with Ctrl to make circle" +msgstr "Змінити малу вісь еліпса. Ctrl робить коло" + +#: ../../po/../src/object-edit.cpp:692 +msgid "" +"Position the start point of the arc or segment; with Ctrl to " +"snap angle; drag inside the ellipse for arc, outside for " +"segment" +msgstr "" +"Початкова точка сектора чи дуги. Ctrl обмежує кут. " +"Перетягування всередині еліпса дає дугу, зовні - сектор" + +#: ../../po/../src/object-edit.cpp:695 +msgid "" +"Position the end point of the arc or segment; with Ctrl to " +"snap angle; drag inside the ellipse for arc, outside for " +"segment" +msgstr "" +"Кінцева точка сектора чи дуги. Ctrl обмежує кут. Перетягування " +"всередині еліпса дає дугу, зовні - сектор" + +#: ../../po/../src/object-edit.cpp:800 +msgid "" +"Adjust the tip radius of the star or polygon; with Shift to " +"round; with Alt to randomize" +msgstr "" +"Змінити великий радіус зірки чи багатокутника. Shift - " +"округляє; Alt - змішує" + +#: ../../po/../src/object-edit.cpp:803 +msgid "" +"Adjust the base radius of the star; with Ctrl to keep star " +"rays radial (no skew); with Shift to round; with Alt to " +"randomize" +msgstr "" +"Змінити малий радіус зірки. Ctrl зберігає промені зірки " +"радіальними (без нахилу), Shift - округляє; Alt - змішує" + +#: ../../po/../src/object-edit.cpp:967 +msgid "" +"Roll/unroll the spiral from inside; with Ctrl to snap angle; " +"with Alt to converge/diverge" +msgstr "" +"Згорнути/розгорнути спіраль всередині. Ctrl - обмежує кут, " +"Alt змінює нелінійність" + +#: ../../po/../src/object-edit.cpp:969 +msgid "" +"Roll/unroll the spiral from outside; with Ctrl to snap angle; " +"with Shift to scale/rotate" +msgstr "" +"Згорнути/розгорнути спіраль зовні. Ctrl - обмежує кут, " +"Shift - розтягує/обертає як ціле" + +#: ../../po/../src/object-edit.cpp:1006 +msgid "Adjust the offset distance" +msgstr "Міняти відстань втягування" + +#. TRANSLATORS: This refers to the pattern that's inside the object +#: ../../po/../src/object-edit.cpp:1036 +msgid "Move the pattern fill inside the object" +msgstr "Переміщувати заповнення візерунком всередині об'єкту" + +#: ../../po/../src/object-edit.cpp:1038 +msgid "Scale the pattern fill uniformly" +msgstr "Пропорційно масштабувати заповнення візерунком" + +#: ../../po/../src/object-edit.cpp:1040 +msgid "Rotate the pattern fill; with Ctrl to snap angle" +msgstr "Обертати заповнення візерунком, Ctrl обмежує кут" + +#: ../../po/../src/object-edit.cpp:1065 +msgid "Drag to resize the flowed text frame" +msgstr "Перетягніть для зміни розміру тексту у рамці" + +#. Item dialog +#: ../../po/../src/object-ui.cpp:106 +msgid "Object _Properties" +msgstr "В_ластивості об'єкта" + +#. Select item +#: ../../po/../src/object-ui.cpp:116 +msgid "_Select This" +msgstr "_Виділити це" + +#. Create link +#: ../../po/../src/object-ui.cpp:126 +msgid "_Create Link" +msgstr "С_творити посилання" + +#. "Ungroup" +#: ../../po/../src/object-ui.cpp:199 ../../po/../src/verbs.cpp:1931 +msgid "_Ungroup" +msgstr "Розгр_упувати" + +#. Link dialog +#: ../../po/../src/object-ui.cpp:239 +msgid "Link _Properties" +msgstr "В_ластивості посилання" + +#. Select item +#: ../../po/../src/object-ui.cpp:249 +msgid "_Follow Link" +msgstr "_Перейти за посиланням" + +#. Reset transformations +#: ../../po/../src/object-ui.cpp:254 +msgid "_Remove Link" +msgstr "П_омістити в рамку" + +#. Link dialog +#: ../../po/../src/object-ui.cpp:303 +msgid "Image _Properties" +msgstr "В_ластивості зображення" + +#. Item dialog +#: ../../po/../src/object-ui.cpp:344 +msgid "_Fill and Stroke" +msgstr "_Заповнення та штрих" + +#: ../../po/../src/path-chemistry.cpp:58 +msgid "Select at least two objects to combine." +msgstr "Виберіть принаймні два об'єкти для об'єднання." + +#: ../../po/../src/path-chemistry.cpp:65 +msgid "At least one of the objects is not a path, cannot combine." +msgstr "" +"Як мінімум один з об'єктів не є контуром, тому об'єднання неможливе." + +#: ../../po/../src/path-chemistry.cpp:73 +msgid "" +"You cannot combine objects from different groups or layers." +msgstr "" +"Не можна об'єднувати об'єкти з різних груп чи різних шарів." + +#: ../../po/../src/path-chemistry.cpp:155 +msgid "Select path(s) to break apart." +msgstr "Виберіть контур(и) для розділення." + +#: ../../po/../src/path-chemistry.cpp:231 +msgid "No path(s) to break apart in the selection." +msgstr "У виділеному немає контурів, що можуть розділитись." + +#: ../../po/../src/path-chemistry.cpp:252 +msgid "Select object(s) to convert to path." +msgstr "Виділіть об'єкти для перетворення у контур." + +#: ../../po/../src/path-chemistry.cpp:297 +msgid "No objects to convert to path in the selection." +msgstr "У виділеному немає об'єктів, що перетворюються у контур." + +#: ../../po/../src/path-chemistry.cpp:345 +msgid "Select path(s) to reverse." +msgstr "Виберіть контур(и) для зміни напряму." + +#: ../../po/../src/path-chemistry.cpp:370 +msgid "No paths to reverse in the selection." +msgstr "У виділеному немає контурів для зміни напряму." + +#: ../../po/../src/pen-context.cpp:379 ../../po/../src/pencil-context.cpp:233 +msgid "Continuing selected path" +msgstr "Продовжується виділений контур" + +#: ../../po/../src/pen-context.cpp:390 ../../po/../src/pencil-context.cpp:242 +msgid "Creating new path" +msgstr "Створення нового контуру" + +#: ../../po/../src/pen-context.cpp:394 ../../po/../src/pencil-context.cpp:246 +msgid "Appending to selected path" +msgstr "Додається до виділеного контуру" + +#: ../../po/../src/pen-context.cpp:538 +msgid "Click or click and drag to close and finish the path." +msgstr "Клацання або перетягування закривають цей контур." + +#: ../../po/../src/pen-context.cpp:548 +msgid "" +"Click or click and drag to continue the path from this point." +msgstr "" +"Клацання або перетягування продовжує контур з цієї точки." + +#: ../../po/../src/pen-context.cpp:857 +#, c-format +msgid "" +"%s: angle %3.2f°, distance %s; with Ctrl to snap angle, " +"Enter to finish the path" +msgstr "" +"%s: під кутом %3.2f°, довжина %s; разом з Ctrl - обмежує " +"кут; Enter завершує контур" + +#: ../../po/../src/pen-context.cpp:882 +#, c-format +msgid "" +"Curve handle: angle %3.2f°, length %s; with Ctrl to snap " +"angle" +msgstr "" +"Вус вузла кривої: кут %3.2f°, довжина %s; Ctrl обмежує кут" + +#: ../../po/../src/pen-context.cpp:912 +#, c-format +msgid "" +"%s: angle %3.2f°, length %s; with Ctrl to snap angle, " +"with Shift to move this handle only" +msgstr "" +"%s: кут %3.2f°, довжина %s; перетягування з Ctrl обмежує кут; " +"с Shift синхронно обертає протилежний кут" + +#: ../../po/../src/pen-context.cpp:946 +msgid "Finishing pen" +msgstr "Контур створено" + +#: ../../po/../src/pencil-context.cpp:320 +msgid "Release here to close and finish the path." +msgstr "Відпустіть тут для закривання та завершення контуру." + +#: ../../po/../src/pencil-context.cpp:326 +msgid "Drawing a freehand path" +msgstr "Малювання довільного контуру" + +#: ../../po/../src/pencil-context.cpp:331 +msgid "Drag to continue the path from this point." +msgstr "Перетягніть для продовження контуру з цієї точки." + +#. Write curves to object +#: ../../po/../src/pencil-context.cpp:390 +msgid "Finishing freehand" +msgstr "Контур створено" + +#: ../../po/../src/rect-context.cpp:387 +msgid "" +"Ctrl: make square or integer-ratio rect, lock a rounded corner " +"circular" +msgstr "" +"Ctrl: квадрати чи прямокутник з цілим відношенням сторін, кругле " +"округлення" + +#: ../../po/../src/rect-context.cpp:549 +#, c-format +msgid "" +"Rectangle: %s × %s; with Ctrl to make square or integer-" +"ratio rectangle; with Shift to draw around the starting point" +msgstr "" +"Прямокутник: %s × %s; Ctrl - квадрат чи прямокутник з " +"цілим відношенням сторін, Shift - малювати навколо початкової точки" + +#: ../../po/../src/select-context.cpp:243 +msgid "Move canceled." +msgstr "Переміщення скасовано." + +#: ../../po/../src/select-context.cpp:252 +msgid "Selection canceled." +msgstr "Виділення скасовано." + +#: ../../po/../src/select-context.cpp:642 +msgid "Ctrl: select in groups, move hor/vert" +msgstr "Ctrl: виділяти у групі, переміщувати по горизонталі/вертикалі" + +#: ../../po/../src/select-context.cpp:643 +msgid "Shift: toggle select, force rubberband, disable snapping" +msgstr "" +"Shift: виділити/зняти видалення, форсувати рамку, вимкнути прилипання" + +#: ../../po/../src/select-context.cpp:644 +msgid "Alt: select under, move selected" +msgstr "Alt: виділяти під виділеним, переміщувати виділене" + +#: ../../po/../src/select-context.cpp:798 +#, fuzzy +msgid "Selected object is not a group. Cannot enter." +msgstr "" +"Виділений об'єкт не є контуром, втягування/розтягування неможливі." + +#: ../../po/../src/select-context.cpp:876 +#, c-format +msgid "" +"Move by %s, %s; with Ctrl to restrict to horizontal/vertical; " +"with Shift to disable snapping" +msgstr "" +"Перемістити на %s, %s. Ctrl - лише по горизонталі/вертикалі, " +"Shift - без прилипання" + +#: ../../po/../src/selection-chemistry.cpp:228 +msgid "Nothing was deleted." +msgstr "Нічого не було видалено." + +#: ../../po/../src/selection-chemistry.cpp:259 +msgid "Select object(s) to duplicate." +msgstr "Виділіть об'єкт(и) для дублювання." + +#: ../../po/../src/selection-chemistry.cpp:420 +msgid "Select two or more objects to group." +msgstr "Виділіть два або більше об'єктів для групування." + +#: ../../po/../src/selection-chemistry.cpp:428 +msgid "Select at least two objects to group." +msgstr "Виділіть принаймні два об'єкти для групування." + +#: ../../po/../src/selection-chemistry.cpp:513 +msgid "Select a group to ungroup." +msgstr "Виділіть групу для розгрупування." + +#: ../../po/../src/selection-chemistry.cpp:554 +msgid "No groups to ungroup in the selection." +msgstr "У виділеному немає груп." + +#: ../../po/../src/selection-chemistry.cpp:623 +msgid "Select objects to raise." +msgstr "Виділіть об'єкти для піднімання." + +#: ../../po/../src/selection-chemistry.cpp:629 +#: ../../po/../src/selection-chemistry.cpp:681 +#: ../../po/../src/selection-chemistry.cpp:715 +#: ../../po/../src/selection-chemistry.cpp:773 +msgid "" +"You cannot raise/lower objects from different groups or layers." +msgstr "" +"Не можна піднімати/опускати об'єкти з різних груп чи шарів." + +#: ../../po/../src/selection-chemistry.cpp:673 +msgid "Select object(s) to raise to top." +msgstr "Виділіть об'єкт(и) для піднімання нагору." + +#: ../../po/../src/selection-chemistry.cpp:709 +msgid "Select object(s) to lower." +msgstr "Виділіть об'єкт(и) для опускання." + +#: ../../po/../src/selection-chemistry.cpp:765 +msgid "Select object(s) to lower to bottom." +msgstr "Виділіть об'єкт(и) для опускання на низ." + +#: ../../po/../src/selection-chemistry.cpp:806 +msgid "Nothing to undo." +msgstr "Немає операцій, що можна скасувати." + +#: ../../po/../src/selection-chemistry.cpp:813 +msgid "Nothing to redo." +msgstr "Немає операцій, що можна вернути." + +#: ../../po/../src/selection-chemistry.cpp:969 +msgid "Nothing was copied." +msgstr "Нічого не було скопійовано." + +#: ../../po/../src/selection-chemistry.cpp:1051 +msgid "Current layer is hidden. Unhide it to be able to paste to it." +msgstr "" +"Поточний рівень - прихований. Зробіть його не прихованим, щоб мати " +"можливість вставляти." + +#: ../../po/../src/selection-chemistry.cpp:1055 +msgid "Current layer is locked. Unlock it to be able to paste to it." +msgstr "" +"Поточний рівень - замкнений. Розімкніть його, щоб мати можливість " +"вставляти." + +#: ../../po/../src/selection-chemistry.cpp:1068 +#: ../../po/../src/selection-chemistry.cpp:1103 +msgid "Nothing on the clipboard." +msgstr "У буфері обміну нічого немає." + +#: ../../po/../src/selection-chemistry.cpp:1109 +msgid "Select object(s) to paste style to." +msgstr "Виділіть об'єкти(и) для застосування стилю." + +#: ../../po/../src/selection-chemistry.cpp:1128 +msgid "Select object(s) to move to the layer above." +msgstr "Виділіть об'єкти для переміщення на шар вище." + +#: ../../po/../src/selection-chemistry.cpp:1146 +msgid "No more layers above." +msgstr "Більше немає вищих шарів." + +#: ../../po/../src/selection-chemistry.cpp:1160 +msgid "Select object(s) to move to the layer below." +msgstr "Виділіть об'єкти для переміщення на шар нижче." + +#: ../../po/../src/selection-chemistry.cpp:1178 +msgid "No more layers below." +msgstr "Немає нижчого шару." + +#: ../../po/../src/selection-chemistry.cpp:1811 +msgid "Select a clone to unlink." +msgstr "Виділіть клон для від'єднання." + +#: ../../po/../src/selection-chemistry.cpp:1842 +msgid "No clones to unlink in the selection." +msgstr "У виділеному немає клонів." + +#: ../../po/../src/selection-chemistry.cpp:1859 +msgid "" +"Select a clone to go to its original. Select a linked offset " +"to go to its source. Select a text on path to go to the path. Select " +"a flowed text to go to its frame." +msgstr "" +"Виділіть клон, щоб перейти до оригіналу; пов'язану втяжку, щоб " +"перейти до її контуру; текст по контуру, щоб перейти до його контуру. " +"Виділіть текст у рамці, щоб перейти до рамки." + +#: ../../po/../src/selection-chemistry.cpp:1882 +msgid "" +"Cannot find the object to select (orphaned clone, offset, textpath, " +"flowed text?)" +msgstr "" +"Не вдається знайти об'єкт, що виділяється (осиротілий клон, втяжка, " +"текст по контуру чи текст у рамці?)" + +#: ../../po/../src/selection-chemistry.cpp:1888 +msgid "" +"The object you're trying to select is not visible (it is in <" +"defs>)" +msgstr "" +"Об'єкт, який ви намагаєтесь виділити, є невидимим (знаходиться у <" +"defs>)" + +#: ../../po/../src/selection-chemistry.cpp:1915 +msgid "Select object(s) to convert to pattern." +msgstr "Виділіть об'єкт(и) для перетворення у візерунок." + +#: ../../po/../src/selection-chemistry.cpp:2006 +msgid "Select an object with pattern fill to extract objects from." +msgstr "" +"Виділіть об'єкт із заповненням візерунком для витягування об'єктів з " +"нього." + +#: ../../po/../src/selection-chemistry.cpp:2059 +msgid "No pattern fills in the selection." +msgstr "У виділеному немає заповнення візерунком." + +#: ../../po/../src/selection-chemistry.cpp:2079 +msgid "Select object(s) to make a bitmap copy." +msgstr "Виділіть об'єкти для створення їх растрової копії." + +#: ../../po/../src/selection-describer.cpp:37 +msgid "Click selection to toggle scale/rotation handles" +msgstr "Клацання на об'єкті перемикає стрілки масштабування/обертання" + +#. no items +#: ../../po/../src/selection-describer.cpp:39 +msgid "" +"No objects selected. Click, Shift+click, or drag around objects to select." +msgstr "" +"Немає виділених об'єктів. Використовуйте клацання, Shift+клацання, або " +"обведіть навколо об'єктів, які треба виділити." + +#: ../../po/../src/selection-describer.cpp:51 +#, c-format +msgid " in layer %s" +msgstr " у шарі %s" + +#: ../../po/../src/selection-describer.cpp:54 +#, c-format +msgid " in layer %s" +msgstr " у шарі %s" + +#: ../../po/../src/selection-describer.cpp:66 +msgid "Use Shift+D to look up original" +msgstr "Натисніть Shift+D, щоб виділити оригінал" + +#: ../../po/../src/selection-describer.cpp:70 +msgid "Use Shift+D to look up path" +msgstr "Натисніть Shift+D, щоб виділити контур" + +#: ../../po/../src/selection-describer.cpp:74 +msgid "Use Shift+D to look up frame" +msgstr "Натисніть Shift+D, щоб виділити рамку" + +#: ../../po/../src/selection-describer.cpp:84 +#, c-format +msgid "%i object selected" +msgid_plural "%i objects selected" +msgstr[0] "%i об'єкт виділено" +msgstr[1] "%i об'єкти виділено" +msgstr[2] "%i об'єктів виділено" + +#: ../../po/../src/selection-describer.cpp:90 +#, c-format +msgid "%s%s. %s." +msgstr "%s%s. %s." + +#: ../../po/../src/selection-describer.cpp:94 +#, c-format +msgid "%s in %i layer. %s." +msgid_plural "%s in %i layers. %s." +msgstr[0] "%s у %i шарі. %s." +msgstr[1] "%s у %i шарах. %s." +msgstr[2] "%s у %i шарах. %s." + +#: ../../po/../src/seltrans.cpp:498 +msgid "" +"Center of rotation and skewing: drag to reposition; scaling with " +"Shift also uses this center" +msgstr "" +"Центр обертання та нахилу: його можна перетягнути; зміна розміру з " +"Shift також відбувається навколо нього" + +#: ../../po/../src/seltrans.cpp:514 +msgid "" +"Squeeze or stretch selection; with Ctrl to scale uniformly; " +"with Shift to scale around rotation center" +msgstr "" +"Стиснути чи розтягнути виділене; з Ctrl - зберігати пропорцію; " +"з Shift - навколо центру обертання" + +#: ../../po/../src/seltrans.cpp:515 +msgid "" +"Scale selection; with Ctrl to scale uniformly; with Shift to scale around rotation center" +msgstr "" +"Змінювати розмір виділеного; з Ctrl - зберігати пропорцію; з " +"Shift - навколо центру обертання" + +#: ../../po/../src/seltrans.cpp:519 +msgid "" +"Skew selection; with Ctrl to snap angle; with Shift to " +"skew around the opposite side" +msgstr "" +"Нахил виділене; з Ctrl - обмежувати кут; з Shift - " +"навколо протилежного кута" + +#: ../../po/../src/seltrans.cpp:520 +msgid "" +"Rotate selection; with Ctrl to snap angle; with Shift " +"to rotate around the opposite corner" +msgstr "" +"Обертати виділене; з Ctrl - обмежувати кут; з Shift - " +"навколо протилежного кута" + +#: ../../po/../src/seltrans.cpp:829 ../../po/../src/seltrans.cpp:909 +#, c-format +msgid "Scale: %0.2f%% x %0.2f%%; with Ctrl to lock ratio" +msgstr "" +"Зміна розміру: %0.2f%% x %0.2f%%; з Ctrl - зберігаючи пропорцію" + +#. TRANSLATORS: don't modify the first ";" (it will NOT be displayed as ";" - only the second one will be) +#: ../../po/../src/seltrans.cpp:984 +#, c-format +msgid "Skew: %0.2f°; with Ctrl to snap angle" +msgstr "Нахил: %0.2f°; з Ctrl - обмежити кут" + +#. TRANSLATORS: don't modify the first ";" (it will NOT be displayed as ";" - only the second one will be) +#: ../../po/../src/seltrans.cpp:1035 +#, c-format +msgid "Rotate: %0.2f°; with Ctrl to snap angle" +msgstr "Обертання: %0.2f°; з Ctrl - обмежити кут" + +#: ../../po/../src/seltrans.cpp:1090 +#, c-format +msgid "Move center to %s, %s" +msgstr "Перемістити центр до %s, %s" + +#: ../../po/../src/slideshow.cpp:90 +msgid "Inkscape slideshow" +msgstr "Показ слайдів" + +#: ../../po/../src/sp-anchor.cpp:181 +#, c-format +msgid "Link to %s" +msgstr "Посилання на: %s" + +#: ../../po/../src/sp-anchor.cpp:185 +msgid "Link without URI" +msgstr "Посилання без URI" + +#: ../../po/../src/sp-ellipse.cpp:438 ../../po/../src/sp-ellipse.cpp:870 +msgid "Ellipse" +msgstr "Еліпс" + +#: ../../po/../src/sp-ellipse.cpp:583 +msgid "Circle" +msgstr "Коло" + +#: ../../po/../src/sp-ellipse.cpp:865 +msgid "Segment" +msgstr "Сектор" + +#: ../../po/../src/sp-ellipse.cpp:867 +msgid "Arc" +msgstr "Дуга" + +#. TRANSLATORS: "Flow region" is an area where text is allowed to flow +#: ../../po/../src/sp-flowregion.cpp:276 +msgid "Flow region" +msgstr "Область верстки" + +#. TRANSLATORS: A region "cut out of" a flow region; text is not allowed to flow inside the +#. * flow excluded region. flowRegionExclude in SVG 1.2: see +#. * http://www.w3.org/TR/2004/WD-SVG12-20041027/flow.html#flowRegion-elem and +#. * http://www.w3.org/TR/2004/WD-SVG12-20041027/flow.html#flowRegionExclude-elem. +#: ../../po/../src/sp-flowregion.cpp:493 +msgid "Flow excluded region" +msgstr "Виключена область верстки" + +#: ../../po/../src/sp-flowtext.cpp:355 +#, c-format +msgid "Flowed text (%d characters)" +msgstr "Текст у рамці (%d символів)" + +#: ../../po/../src/sp-flowtext.cpp:357 +#, c-format +msgid "Linked flowed text (%d characters)" +msgstr "Зв'язаний текст у рамці (%d символів)" + +#: ../../po/../src/sp-guide.cpp:290 +msgid "vertical guideline" +msgstr "вертикальна напрямна" + +#: ../../po/../src/sp-guide.cpp:292 +msgid "horizontal guideline" +msgstr "горизонтальна напрямна" + +#: ../../po/../src/sp-image.cpp:835 +msgid "embedded" +msgstr "включене" + +#: ../../po/../src/sp-image.cpp:839 +msgid "(null_pointer)" +msgstr "(null_вказівник)" + +#: ../../po/../src/sp-image.cpp:843 +#, c-format +msgid "Image with bad reference: %s" +msgstr "Зображення з неправильним посиланням: %s" + +#: ../../po/../src/sp-image.cpp:844 +#, c-format +msgid "Image %d × %d: %s" +msgstr "Зображення %d × %d: %s" + +#: ../../po/../src/sp-item-group.cpp:390 +#, c-format +msgid "Group of %d object" +msgid_plural "Group of %d objects" +msgstr[0] "Група з %d об'єкту" +msgstr[1] "Група з %d об'єктів" +msgstr[2] "Група з %d об'єктів" + +#: ../../po/../src/sp-item.cpp:720 +msgid "Object" +msgstr "Об'єкт" + +#: ../../po/../src/sp-line.cpp:202 +msgid "Line" +msgstr "Рядок" + +#. TRANSLATORS COMMENT: %s is either "outset" or "inset" depending on sign +#: ../../po/../src/sp-offset.cpp:433 +#, c-format +msgid "Linked offset, %s by %f pt" +msgstr "Зв'язана втяжка, %s на %f пт" + +#: ../../po/../src/sp-offset.cpp:434 ../../po/../src/sp-offset.cpp:438 +msgid "outset" +msgstr "розтягнута" + +#: ../../po/../src/sp-offset.cpp:434 ../../po/../src/sp-offset.cpp:438 +msgid "inset" +msgstr "утягнена" + +#. TRANSLATORS COMMENT: %s is either "outset" or "inset" depending on sign +#: ../../po/../src/sp-offset.cpp:437 +#, c-format +msgid "Dynamic offset, %s by %f pt" +msgstr "Динамічна втяжка, %s на %f пт" + +#: ../../po/../src/sp-path.cpp:127 +#, c-format +msgid "Path (%i node)" +msgid_plural "Path (%i nodes)" +msgstr[0] "Контур (%i вузол)" +msgstr[1] "Контур (%i вузли)" +msgstr[2] "Контур (%i вузлів)" + +#: ../../po/../src/sp-polygon.cpp:216 +msgid "Polygon" +msgstr "Багатокутник" + +#: ../../po/../src/sp-polyline.cpp:179 +msgid "Polyline" +msgstr "Полілінія" + +#: ../../po/../src/sp-rect.cpp:250 +msgid "Rectangle" +msgstr "Прямокутник" + +#. TRANSLATORS: since turn count isn't an integer, please adjust the +#. string as needed to deal with an localized plural forms. +#: ../../po/../src/sp-spiral.cpp:305 +#, c-format +msgid "Spiral with %3f turns" +msgstr "Спіраль з %3f обертами" + +#: ../../po/../src/sp-star.cpp:288 +#, c-format +msgid "Star with %d vertex" +msgid_plural "Star with %d vertices" +msgstr[0] "Зірка з %d вершиною" +msgstr[1] "Зірка з %d вершинами" +msgstr[2] "Зірка з %d вершинами" + +#: ../../po/../src/sp-star.cpp:292 +#, c-format +msgid "Polygon with %d vertex" +msgid_plural "Polygon with %d vertices" +msgstr[0] "Багатокутник з %d вершиною" +msgstr[1] "Багатокутник з %d вершинами" +msgstr[2] "Багатокутник з %d вершинами" + +#. TRANSLATORS: For description of font with no name. +#: ../../po/../src/sp-text.cpp:420 +msgid "<no name found>" +msgstr "<назву не знайдено>" + +#: ../../po/../src/sp-text.cpp:426 +#, c-format +msgid "Text on path (%s, %s)" +msgstr "Текст по контуру (%s, %s)" + +#: ../../po/../src/sp-text.cpp:427 +#, c-format +msgid "Text (%s, %s)" +msgstr "Текст (%s, %s)" + +#. TRANSLATORS: Used for statusbar description for long chains: +#. * "Clone of: Clone of: ... in Layer 1". +#: ../../po/../src/sp-use.cpp:317 +msgid "..." +msgstr "..." + +#: ../../po/../src/sp-use.cpp:325 +#, c-format +msgid "Clone of: %s" +msgstr "Клон від: %s" + +#: ../../po/../src/sp-use.cpp:329 +msgid "Orphaned clone" +msgstr "Осиротілий клон" + +#: ../../po/../src/spiral-context.cpp:355 +msgid "Ctrl: snap angle" +msgstr "Ctrl: обмежити кут" + +#: ../../po/../src/spiral-context.cpp:357 +msgid "Alt: lock spiral radius" +msgstr "Alt: зафіксувати радіус спіралі" + +#: ../../po/../src/spiral-context.cpp:469 +#, c-format +msgid "" +"Spiral: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "Спіраль: радіус %s, кут %5g°; з Ctrl - обмежує кут" + +#: ../../po/../src/splivarot.cpp:106 +msgid "Select at least 2 paths to perform a boolean operation." +msgstr "Для логічної операції треба виділити не менше двох контурів." + +#: ../../po/../src/splivarot.cpp:112 +msgid "" +"Select exactly 2 paths to perform difference, XOR, division, or path " +"cut." +msgstr "" +"Для операції виключного АБО, ділення та розрізання контуру виберіть точно " +"2 контури." + +#: ../../po/../src/splivarot.cpp:129 ../../po/../src/splivarot.cpp:144 +msgid "" +"Unable to determine the z-order of the objects selected for " +"difference, XOR, division, or path cut." +msgstr "" +"Не вдається визначити порядок розташування дуг одна над одною " +"об'єктів, виділених для операції різниці, виключного АБО, ділення розрізання " +"контуру." + +#: ../../po/../src/splivarot.cpp:174 +msgid "" +"One of the objects is not a path, cannot perform boolean operation." +msgstr "Один з об'єктів не є контуром, логічна операція неможлива." + +#. TRANSLATORS: "to outline" means "to convert stroke to path" +#: ../../po/../src/splivarot.cpp:554 +msgid "Select path(s) to outline." +msgstr "Виділіть контур(и) для створення контуру штриха." + +#. TRANSLATORS: "to outline" means "to convert stroke to path" +#: ../../po/../src/splivarot.cpp:748 +msgid "No stroked paths to outline in the selection." +msgstr "У виділеному немає контурів зі штрихом для створення контуру." + +#: ../../po/../src/splivarot.cpp:832 +msgid "Selected object is not a path, cannot inset/outset." +msgstr "" +"Виділений об'єкт не є контуром, втягування/розтягування неможливі." + +#: ../../po/../src/splivarot.cpp:1040 +msgid "Select path(s) to inset/outset." +msgstr "Виділіть контур(и) для втягування/розтягування." + +#: ../../po/../src/splivarot.cpp:1257 +msgid "No paths to inset/outset in the selection." +msgstr "У виділеному немає контурів для втягування/розтягування." + +#: ../../po/../src/splivarot.cpp:1390 +msgid "Select path(s) to simplify." +msgstr "Виділіть контур(и) для спрощення." + +#: ../../po/../src/splivarot.cpp:1417 +msgid "No paths to simplify in the selection." +msgstr "У виділеному немає контурів для спрощення." + +#: ../../po/../src/star-context.cpp:362 +msgid "Ctrl: snap angle; keep rays radial" +msgstr "Ctrl: обмежити кут; промені за радіусом без перекосу" + +#: ../../po/../src/star-context.cpp:470 +#, c-format +msgid "" +"Polygon: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" +"Багатокутник: радіус %s, кут %5g°; з Ctrl - обмежує кут" + +#: ../../po/../src/star-context.cpp:471 +#, c-format +msgid "Star: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "Зірка: радіус %s, кут %5g°; з Ctrl - обмежує кут" + +#: ../../po/../src/text-chemistry.cpp:90 +msgid "Select a text and a path to put text on path." +msgstr "Виділіть текст та шлях для розміщення тексту за контуром." + +#: ../../po/../src/text-chemistry.cpp:95 +msgid "" +"This text object is already put to a path. Remove it from the path " +"first. Use Shift+D to look up its path." +msgstr "" +"Текстовий об'єкт вже розміщений за контуром. Спочатку зніміть його з " +"контуру. Натисніть Shift+D для переходу до його контуру." + +#. rect is the only SPShape which is not yet, and thus SVG forbids us from putting text on it +#: ../../po/../src/text-chemistry.cpp:101 +msgid "" +"You cannot put text on a rectangle in this version. Convert rectangle to " +"path first." +msgstr "" +"У цій версії програми не можна розміщувати текст по контуру прямокутника. " +"Перетворіть прямокутник у контур та спробуйте знову." + +#: ../../po/../src/text-chemistry.cpp:159 +msgid "Select a text on path to remove it from path." +msgstr "Виділіть текст по контуру, щоб видалити його з контуру." + +#: ../../po/../src/text-chemistry.cpp:181 +msgid "No texts-on-paths in the selection." +msgstr "У виділеному немає тексту на контурі." + +#: ../../po/../src/text-chemistry.cpp:209 +#: ../../po/../src/text-chemistry.cpp:229 +msgid "Select text(s) to remove kerns from." +msgstr "Виділіть текст для видалення ручного кернінгу." + +#: ../../po/../src/text-chemistry.cpp:250 +msgid "" +"Select a text and one or more paths or shapes to flow text " +"into frame." +msgstr "" +"Виділіть текст та контур чи фігуру для розміщення тексту у " +"рамку." + +#: ../../po/../src/text-chemistry.cpp:322 +msgid "Select a flowed text to unflow it." +msgstr "Виділіть текст у рамці, щоб вийняти його з рамки." + +#: ../../po/../src/text-context.cpp:463 +msgid "Click to edit the text, drag to select part of the text." +msgstr "" +"Клацніть, щоб редагувати текст, перетягуванням можна виділити " +"частину тексту." + +#: ../../po/../src/text-context.cpp:465 +msgid "" +"Click to edit the flowed text, drag to select part of the text." +msgstr "" +"Клацніть, щоб редагувати текст у рамці, перетягуванням можна " +"виділити частину тексту." + +#: ../../po/../src/text-context.cpp:540 +msgid "Non-printable character" +msgstr "Недрукований символ" + +#: ../../po/../src/text-context.cpp:589 +#, c-format +msgid "Unicode: %s: %s" +msgstr "Юнікод: %s: %s" + +#: ../../po/../src/text-context.cpp:591 ../../po/../src/text-context.cpp:855 +msgid "Unicode: " +msgstr "Юнікод: " + +#: ../../po/../src/text-context.cpp:615 +msgid "Current layer is hidden. Unhide it to be able to add text." +msgstr "" +"Поточний рівень є прихованим. Зробіть його неприхованим, щоб додати " +"текст." + +#: ../../po/../src/text-context.cpp:619 +msgid "Current layer is locked. Unlock it to be able to add text." +msgstr "" +"Поточний рівень замкнений. Зробіть його не замкненим, щоб додати " +"текст." + +#: ../../po/../src/text-context.cpp:673 +#, c-format +msgid "Flowed text frame: %s × %s" +msgstr "Текст у рамці: %s × %s" + +#: ../../po/../src/text-context.cpp:708 ../../po/../src/text-context.cpp:1464 +msgid "Type text; Enter to start new line." +msgstr "Введіть текст; Enter - початок нового рядка." + +#: ../../po/../src/text-context.cpp:719 +msgid "Flowed text is created." +msgstr "Текстову область створено." + +#: ../../po/../src/text-context.cpp:722 +msgid "" +"The frame is too small for the current font size. Flowed text not " +"created." +msgstr "" +"Рамка надто мала для поточного розміру шрифту. Текстову область не " +"створено." + +#: ../../po/../src/text-context.cpp:841 +msgid "No-break space" +msgstr "Нерозривний пробіл" + +#: ../../po/../src/text-context.cpp:1462 +msgid "Type flowed text; Enter to start new paragraph." +msgstr "Введіть текст у рамці; Enter - початок нового абзацу." + +#: ../../po/../src/text-context.cpp:1472 ../../po/../src/tools-switch.cpp:189 +msgid "" +"Click to select or create text, drag to create flowed text; " +"then type." +msgstr "" +"Клацання виділяє чи створює текстовий об'єкт; перетягніть щоб " +"створити плаваючу тестову область; після чого можна набирати текст." + +#: ../../po/../src/tools-switch.cpp:141 +msgid "" +"To edit a path, click, Shift+click, or drag around " +"nodes to select them, then drag nodes and handles. Click on an " +"object to select." +msgstr "" +"Для редагування контуру: клацання, Shift+клацання, чи " +"обведення для виділення вузлів, потім перетягування. " +"Клацніть на об'єкті, щоб виділити." + +#: ../../po/../src/tools-switch.cpp:147 +msgid "" +"Drag to create a rectangle. Drag controls to round corners and " +"resize. Click to select." +msgstr "" +"Перетягування малює прямокутник. Перетягування ручок змінює " +"розмір та округляє кути. Клацання виділяє об'єкт." + +#: ../../po/../src/tools-switch.cpp:153 +msgid "" +"Drag to create an ellipse. Drag controls to make an arc or " +"segment. Click to select." +msgstr "" +"Перетягування малює еліпс. Перетягування ручок робить дугу або " +"сектор. Клацання виділяє об'єкт." + +#: ../../po/../src/tools-switch.cpp:159 +msgid "" +"Drag to create a star. Drag controls to edit the star shape. " +"Click to select." +msgstr "" +"Перетягування малює зірку. Перетягування ручок змінює її " +"форму. Клацання виділяє об'єкт." + +#: ../../po/../src/tools-switch.cpp:165 +msgid "" +"Drag to create a spiral. Drag controls to edit the spiral " +"shape. Click to select." +msgstr "" +"Перетягування малює спіраль. Перетягування ручок змінює її " +"форму. Клацання виділяє об'єкт." + +#: ../../po/../src/tools-switch.cpp:171 +msgid "" +"Drag to create a freehand line. Start drawing with Shift to " +"append to selected path." +msgstr "" +"Перетягування малює довільну лінію. Щоб додати до виділеної лінії " +"натисніть спочатку Shift." + +#: ../../po/../src/tools-switch.cpp:177 +msgid "" +"Click or click and drag to start a path; with Shift to " +"append to selected path." +msgstr "" +"Клацання створює вузол та клацання з перетягуванням - починає " +"контур. Щоб додати до виділеної лінії натисніть спочатку Shift." + +#: ../../po/../src/tools-switch.cpp:183 +msgid "" +"Drag to paint a calligraphic stroke. Left/right arrow " +"keys adjust width, up/down adjust angle." +msgstr "" +"Перетягування малює каліграфічний штрих. Клавіші-стрілки Вліво/" +"Вправо змінюють ширину, вгору/вниз кут пера." + +#: ../../po/../src/tools-switch.cpp:195 +msgid "" +"Drag or double click to create a gradient on selected objects, " +"drag handles to adjust gradients." +msgstr "" +"Перетягніть або двічі клацніть, щоб створити градієнт на " +"виділеному об'єкті, перетягніть вуса для корегування градієнту." + +#: ../../po/../src/tools-switch.cpp:201 +msgid "" +"Click or drag around an area to zoom in, Shift+click to " +"zoom out." +msgstr "" +"Клацання чи обведення рамкою наближають, Shift+клацання " +"віддаляють полотно." + +#: ../../po/../src/tools-switch.cpp:213 +msgid "Click and drag between shapes to create a connector." +msgstr "" +"Клацання + перетягування між фігурами створюють лінію з'єднання." + +#: ../../po/../src/trace/potrace/inkscape-potrace.cpp:553 +#: ../../po/../src/trace/potrace/inkscape-potrace.cpp:654 +#, c-format +msgid "Trace: %d. %ld nodes" +msgstr "Векторизація: %d. %ld вузлів" + +#: ../../po/../src/trace/trace.cpp:53 ../../po/../src/trace/trace.cpp:62 +#: ../../po/../src/trace/trace.cpp:70 +msgid "Select an image to trace" +msgstr "Виберіть растрове зображення для векторизації" + +#: ../../po/../src/trace/trace.cpp:133 +msgid "Trace: No active document" +msgstr "Векторизація: немає активного документу" + +#: ../../po/../src/trace/trace.cpp:154 +msgid "Trace: Image has no bitmap data" +msgstr "Векторизація: у зображенні немає растрових даних" + +#: ../../po/../src/trace/trace.cpp:267 +#, c-format +msgid "Trace: Done. %ld nodes created" +msgstr "Векторизація: Завершено. Створено %ld вузлів." + +#: ../../po/../src/ui/dialog/aboutbox.cpp:59 ../../po/../src/verbs.cpp:2212 +msgid "About Inkscape" +msgstr "Про програму" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:66 +msgid "_Splash" +msgstr "" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:68 +#, fuzzy +msgid "_Authors" +msgstr "Автори" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:69 +#, fuzzy +msgid "_Translators" +msgstr "Перекладачі" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:70 +msgid "_License" +msgstr "_Ліцензія" + +#. TRANSLATORS: This is the filename of the `About Inkscape' picture in +#. the `screens' directory. Thus the translation of "about.svg" should be +#. the filename of its translated version, e.g. about.zh.svg for Chinese. +#. +#. N.B. about.svg changes once per release. (We should probably rename +#. the original to about-0.40.svg etc. as soon as we have a translation. +#. If we do so, then add an item to release-checklist saying that the +#. string here should be changed.) +#. FIXME? INKSCAPE_SCREENSDIR and "about.svg" are in UTF-8, not the +#. native filename encoding... and the filename passed to sp_document_new +#. should be in UTF-*8.. +#: ../../po/../src/ui/dialog/aboutbox.cpp:114 +msgid "about.svg" +msgstr "about.svg" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:464 +msgid "Minimum horizontal gap (in px units) between bounding boxes" +msgstr "" + +#. TRANSLATORS: Horizontal gap +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:466 +#: ../../po/../src/widgets/toolbox.cpp:1556 +msgid "H:" +msgstr "В:" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:474 +msgid "Minimum vertical gap (in px units) between bounding boxes" +msgstr "" + +#. TRANSLATORS: Vertical gap +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:476 +msgid "V:" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:734 +msgid "Align" +msgstr "Вирівнювання" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:735 +msgid "Distribute" +msgstr "Розставити" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:736 +msgid "Remove overlaps" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:737 +msgid "Nodes" +msgstr "Вузли" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:742 +msgid "Relative to: " +msgstr "Відносно:" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:747 +msgid "Align right sides of objects to left side of anchor" +msgstr "Права сторона об'єктів до лівої сторони якоря" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:750 +msgid "Align left sides" +msgstr "Вирівняти ліві сторони" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:753 +msgid "Center on vertical axis" +msgstr "Центрувати на вертикальній осі" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:756 +msgid "Align right sides" +msgstr "Вирівняти праві сторони" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:759 +msgid "Align left sides of objects to right side of anchor" +msgstr "Ліва сторона об'єктів до правої сторони якоря" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:762 +msgid "Align bottoms of objects to top of anchor" +msgstr "Нижня сторона об'єктів до верхньої сторони якоря" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:765 +msgid "Align tops" +msgstr "Вирівняти верхні сторони" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:768 +msgid "Center on horizontal axis" +msgstr "Центрувати на горизонтальній осі" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:771 +msgid "Align bottoms" +msgstr "Вирівняти нижні сторони" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:774 +msgid "Align tops of objects to bottom of anchor" +msgstr "Верхня сторона об'єктів до нижньої сторони якоря" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:779 +msgid "Align baseline anchors of texts vertically" +msgstr "Розташувати базову лінію тексту вертикально" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:782 +msgid "Align baseline anchors of texts horizontally" +msgstr "Розташувати базову лінію тексту горизонтально" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:787 +msgid "Make horizontal gaps between objects equal" +msgstr "Зробити однаковими інтервали між об'єктами по горизонталі" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:791 +msgid "Distribute left sides equidistantly" +msgstr "Розставити ліві сторони об'єктів на однаковій відстані" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:794 +msgid "Distribute centers equidistantly horizontally" +msgstr "Розставити центри об'єктів на однаковій відстані по горизонталі" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:797 +msgid "Distribute right sides equidistantly" +msgstr "Розставити праві сторони об'єктів на однаковій відстані" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:801 +msgid "Make vertical gaps between objects equal" +msgstr "Вирівняти інтервали між об'єктами по вертикалі" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:805 +msgid "Distribute tops equidistantly" +msgstr "Розподілити верхні сторони об'єктів на однаковій відстані" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:808 +msgid "Distribute centers equidistantly vertically" +msgstr "Розставити центри об'єктів на однаковій відстані по вертикалі" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:811 +msgid "Distribute bottoms equidistantly" +msgstr "Розставити нижні сторони об'єктів на однаковій відстані" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:816 +msgid "Distribute baseline anchors of texts horizontally" +msgstr "Розподілити базові якорі символів рівномірно по горизонталі" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:819 +msgid "Distribute baseline anchors of texts vertically" +msgstr "Розподілити базові якорі символів рівномірно по вертикалі" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:824 +msgid "Randomize centers in both dimensions" +msgstr "Випадково розташувати центри у обох напрямках" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:827 +msgid "Unclump objects: try to equalize edge-to-edge distances" +msgstr "" +"Розгрупувати об'єкт: спробувати встановити рівну відстань між межами об'єктів" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:832 +msgid "" +"Move objects as little as possible so that their bounding boxes do not " +"overlap" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:837 +msgid "Align selected nodes horizontally" +msgstr "Вирівняти вибрані вузли по горизонталі" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:840 +msgid "Align selected nodes vertically" +msgstr "Вирівняти вибрані вузли по вертикалі" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:843 +msgid "Distribute selected nodes horizontally" +msgstr "Розподілити вибрані вузли по горизонталі" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:846 +msgid "Distribute selected nodes vertically" +msgstr "Розподілити вибрані вузли по вертикалі" + +#. Rest of the widgetry +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:851 +msgid "Last selected" +msgstr "Останній виділений" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:852 +msgid "First selected" +msgstr "Перший виділений" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:853 +msgid "Biggest item" +msgstr "Найбільший об'єкт" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:854 +msgid "Smallest item" +msgstr "Найменший об'єкт" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:856 +#: ../../po/../src/widgets/desktop-widget.cpp:1065 +msgid "Drawing" +msgstr "Малюнок" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:91 +#, fuzzy +msgid "Metadata 1" +msgstr "Метадані" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:92 +#, fuzzy +msgid "Metadata 2" +msgstr "Метадані" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:187 +#, fuzzy +msgid "X coordinate of grid origin" +msgstr "Вертикальна координата виділення" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:189 +#, fuzzy +msgid "Y coordinate of grid origin" +msgstr "Вертикальна координата виділення" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:191 +#, fuzzy +msgid "Distance of vertical grid lines" +msgstr "вертикальна напрямна" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:193 +#, fuzzy +msgid "Distance of horizontal grid lines" +msgstr "горизонтальна напрямна" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:197 +msgid "Max. snapping distance from grid" +msgstr "" + +#: ../../po/../src/ui/dialog/export.cpp:34 +msgid "Export" +msgstr "Експорт" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:36 +msgid "Fill" +msgstr "Заповнення" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:37 +msgid "Stroke Paint" +msgstr "Колір штриха" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:38 +msgid "Stroke Style" +msgstr "Стиль штриха" + +#: ../../po/../src/ui/dialog/find.cpp:34 +msgid "Find" +msgstr "З_найти" + +#: ../../po/../src/ui/dialog/memory.cpp:96 +msgid "Heap" +msgstr "Пул" + +#: ../../po/../src/ui/dialog/memory.cpp:97 +msgid "In Use" +msgstr "Використовується" + +#. TRANSLATORS: "Slack" refers to memory which is in the heap but currently unused. +#. More typical usage is to call this memory "free" rather than "slack". +#: ../../po/../src/ui/dialog/memory.cpp:100 +msgid "Slack" +msgstr "Залишок" + +#: ../../po/../src/ui/dialog/memory.cpp:101 +msgid "Total" +msgstr "Загалом" + +#: ../../po/../src/ui/dialog/memory.cpp:141 +#: ../../po/../src/ui/dialog/memory.cpp:147 +#: ../../po/../src/ui/dialog/memory.cpp:154 +#: ../../po/../src/ui/dialog/memory.cpp:186 +msgid "Unknown" +msgstr "Невідомо" + +#: ../../po/../src/ui/dialog/memory.cpp:167 +msgid "Combined" +msgstr "Разом" + +#: ../../po/../src/ui/dialog/memory.cpp:209 +msgid "Recalculate" +msgstr "Переобчислити" + +#: ../../po/../src/ui/dialog/messages.cpp:74 +msgid "Ready." +msgstr "Завершено." + +#: ../../po/../src/ui/dialog/messages.cpp:75 +msgid "" +"Enable log display by setting dialogs.debug 'redirect' attribute to 1 in " +"preferences.xml" +msgstr "" +"Увімкнути відображення журналу встановленням значення атрибуту dialogs.debug " +"'redirect' як 1 у preferences.xml" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:184 +msgid "_Execute Python" +msgstr "_Виконати Python" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:186 +msgid "_Execute Perl" +msgstr "_Виконати Perl" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:195 +msgid "Script" +msgstr "Сценарій" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:205 +msgid "Output" +msgstr "Вивід" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:215 +msgid "Errors" +msgstr "Помилки" + +#. Dialog organization +#: ../../po/../src/ui/dialog/session-player.cpp:73 +msgid "Session file" +msgstr "Файл сеансу" + +#: ../../po/../src/ui/dialog/session-player.cpp:74 +msgid "Playback controls" +msgstr "Кнопки керування сеансом" + +#: ../../po/../src/ui/dialog/session-player.cpp:75 +msgid "Message information" +msgstr "Інформація про повідомлення" + +#. Active session file display +#. fixme: Does this mean the active file for the session, or the file for the active session? +#. Please indicate which with a TRANSLATORS comment. +#: ../../po/../src/ui/dialog/session-player.cpp:85 +msgid "Active session file:" +msgstr "Активний файл сеансу:" + +#: ../../po/../src/ui/dialog/session-player.cpp:86 +msgid "Delay (milliseconds):" +msgstr "Затримка (у мілісекундах):" + +#. Unload/load buttons +#: ../../po/../src/ui/dialog/session-player.cpp:94 +msgid "Close file" +msgstr "Закрити файл" + +#: ../../po/../src/ui/dialog/session-player.cpp:95 +msgid "Open new file" +msgstr "Відкрити новий файл" + +#: ../../po/../src/ui/dialog/session-player.cpp:96 +msgid "Set delay" +msgstr "Встановити затримку" + +#: ../../po/../src/ui/dialog/session-player.cpp:138 +msgid "Rewind" +msgstr "Перемотати назад" + +#: ../../po/../src/ui/dialog/session-player.cpp:139 +msgid "Go back one change" +msgstr "На одну зміну назад" + +#: ../../po/../src/ui/dialog/session-player.cpp:140 +msgid "Pause" +msgstr "Призупинити" + +#: ../../po/../src/ui/dialog/session-player.cpp:141 +msgid "Go forward one change" +msgstr "На одну зміну вперед" + +#: ../../po/../src/ui/dialog/session-player.cpp:142 +msgid "Play" +msgstr "Відтворити" + +#: ../../po/../src/ui/dialog/session-player.cpp:177 +#: ../../po/../src/verbs.cpp:1573 +msgid "Open session file" +msgstr "Відкрити файл сеансу" + +#. ##Set up the Potrace panel +#. #### brightness #### +#. #### Multiple scanning#### +#. ----Hbox1 +#: ../../po/../src/ui/dialog/tracedialog.cpp:345 +#: ../../po/../src/ui/dialog/tracedialog.cpp:428 +msgid "Brightness" +msgstr "Яскравість" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:348 +msgid "Trace by a given brightness level" +msgstr "Векторизація за вказаним рівнем яскравості" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:355 +msgid "Brightness cutoff for black/white" +msgstr "Поділ яскравості на чорне/біле" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:362 +msgid "Image Brightness" +msgstr "Яскравість зображення" + +#. #### canny edge detection #### +#. TRANSLATORS: "Canny" is the name of the inventor of this edge detection method +#: ../../po/../src/ui/dialog/tracedialog.cpp:369 +msgid "Optimal Edge Detection (Canny)" +msgstr "Оптимальне визначення меж (Canny)" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:372 +msgid "Trace with edge detection by J. Canny's algorithm" +msgstr "Векторизація за межею, що визначається алгоритмом J. Canny" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:388 +msgid "Brightness cutoff for adjacent pixels (determines edge thickness)" +msgstr "Поділ яскравості для суміжних точок (визначає товщину межі)" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:395 +msgid "Edge Detection" +msgstr "Визначення меж" + +#. #### quantization #### +#. TRANSLATORS: Color Quantization: the process of reducing the number of colors +#. in an image by selecting an optimized set of representative colors and then +#. re-applying this reduced set to the original image. +#: ../../po/../src/ui/dialog/tracedialog.cpp:404 +msgid "Color Quantization" +msgstr "Квантування кольорів" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:407 +msgid "Trace along the boundaries of reduced colors" +msgstr "Векторизація вздовж меж зниження кількості кольорів" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:414 +msgid "The number of reduced colors" +msgstr "Кількість кольорів, що скорочуються" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:416 +msgid "Colors:" +msgstr "Кольори:" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:421 +msgid "Quantization / Reduction" +msgstr "Квантування / скорочення" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:431 +msgid "Trace the given number of brightness levels" +msgstr "Векторизувати вказану кількість рівнів яскравості" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:438 +msgid "Scans:" +msgstr "Проходів:" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:440 +msgid "The desired number of scans" +msgstr "Бажана кількість проходів" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:448 +msgid "Trace the given number of reduced colors" +msgstr "Векторизувати вказану кількість кольорів, що скорочуються" + +#. ---Hbox3 +#: ../../po/../src/ui/dialog/tracedialog.cpp:454 +msgid "Monochrome" +msgstr "Монохромно" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:457 +msgid "Same as Color, but convert result to grayscale" +msgstr "Так само як і \"Колір\", але результат буде чорно-білий" + +#. TRANSLATORS: "Stack" is a verb here +#: ../../po/../src/ui/dialog/tracedialog.cpp:460 +msgid "Stack" +msgstr "Складати у стос" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:463 +msgid "" +"Stack scans vertically (no gaps) or tile horizontally (usually with gaps)" +msgstr "" +"Складати у стос проходи вертикально (без проміжків) або мозаїкою " +"горизонтально (зазвичай з проміжками) " + +#. TRANSLATORS: "Smooth" is a verb here +#: ../../po/../src/ui/dialog/tracedialog.cpp:466 +msgid "Smooth" +msgstr "Згладити" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:469 +msgid "Apply Gaussian blur to the bitmap before tracing" +msgstr "Перед векторизацією застосувати Гаусове розмивання зображення" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:473 +msgid "Multiple Scanning" +msgstr "Багаторазове сканування" + +#. #### Preview #### +#: ../../po/../src/ui/dialog/tracedialog.cpp:479 +#: ../../po/../src/ui/dialog/tracedialog.cpp:489 +msgid "Preview" +msgstr "Перегляд" + +#. do not expand +#: ../../po/../src/ui/dialog/tracedialog.cpp:483 +msgid "Preview the result without actual tracing" +msgstr "Попередній перегляд без фактичної векторизації" + +#. #### swap black and white #### +#: ../../po/../src/ui/dialog/tracedialog.cpp:495 +msgid "Invert" +msgstr "Інвертувати" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:499 +msgid "Invert black and white regions for single traces" +msgstr "Інвертувати чорні та білі області для однієї векторизації" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:503 +msgid "Thanks to Peter Selinger, http://potrace.sourceforge.net" +msgstr "Подяка Peter Selinger, http://potrace.sourceforge.net" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:506 +msgid "Credits" +msgstr "Подяки" + +#. done +#. TRANSLATORS: Potrace is an application for transforming bitmaps into +#. vector graphics (http://potrace.sourceforge.net/) +#: ../../po/../src/ui/dialog/tracedialog.cpp:514 +msgid "Potrace" +msgstr "Potrace" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:527 +msgid "Abort a trace in progress" +msgstr "Перервати векторизацію" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:531 +msgid "Execute the trace" +msgstr "Провести векторизацію" + +#: ../../po/../src/ui/dialog/transformation.cpp:80 +#: ../../po/../src/ui/dialog/transformation.cpp:90 +#, fuzzy +msgid "_Horizontal" +msgstr "По-горизонталі" + +#: ../../po/../src/ui/dialog/transformation.cpp:80 +msgid "Horizontal displacement (relative) or position (absolute)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:82 +#: ../../po/../src/ui/dialog/transformation.cpp:92 +#, fuzzy +msgid "_Vertical" +msgstr "По-вертикалі" + +#: ../../po/../src/ui/dialog/transformation.cpp:82 +msgid "Vertical displacement (relative) or position (absolute)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:84 +#, fuzzy +msgid "_Width" +msgstr "_Ширина:" + +#: ../../po/../src/ui/dialog/transformation.cpp:84 +msgid "Horizontal size increment (absolute or percentage)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:86 +#, fuzzy +msgid "_Height" +msgstr "Висота" + +#: ../../po/../src/ui/dialog/transformation.cpp:86 +msgid "Vertical size increment (absolute or percentage)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:88 +#, fuzzy +msgid "A_ngle" +msgstr "Кут:" + +#: ../../po/../src/ui/dialog/transformation.cpp:88 +#, fuzzy +msgid "Rotation angle (positive = counterclockwise)" +msgstr "Обернути виділене на 90° проти годинникової стрілки" + +#: ../../po/../src/ui/dialog/transformation.cpp:90 +msgid "" +"Horizontal skew angle (positive = counterclockwise), or absolute " +"displacement, or percentage displacement" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:92 +msgid "" +"Vertical skew angle (positive = counterclockwise), or absolute displacement, " +"or percentage displacement" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:95 +#, fuzzy +msgid "Transformation matrix element A" +msgstr "Матриця трансформації" + +#: ../../po/../src/ui/dialog/transformation.cpp:96 +#, fuzzy +msgid "Transformation matrix element B" +msgstr "Матриця трансформації" + +#: ../../po/../src/ui/dialog/transformation.cpp:97 +#, fuzzy +msgid "Transformation matrix element C" +msgstr "Матриця трансформації" + +#: ../../po/../src/ui/dialog/transformation.cpp:98 +#, fuzzy +msgid "Transformation matrix element D" +msgstr "Матриця трансформації" + +#: ../../po/../src/ui/dialog/transformation.cpp:99 +#, fuzzy +msgid "Transformation matrix element E" +msgstr "Матриця трансформації" + +#: ../../po/../src/ui/dialog/transformation.cpp:100 +#, fuzzy +msgid "Transformation matrix element F" +msgstr "Матриця трансформації" + +#: ../../po/../src/ui/dialog/transformation.cpp:102 +#, fuzzy +msgid "Rela_tive move" +msgstr "Відносні координати" + +#: ../../po/../src/ui/dialog/transformation.cpp:102 +msgid "" +"Add the specified relative displacement to the current position; otherwise, " +"edit the current absolute position directly" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:103 +msgid "Scale proportionally" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:103 +msgid "Preserve the width/height ratio of the scaled objects" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:104 +msgid "Apply to each _object separately" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:104 +msgid "" +"Apply the scale/rotate/skew to each selected object separately; otherwise, " +"transform the selection as a whole" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:105 +#, fuzzy +msgid "Edit c_urrent matrix" +msgstr "Підняти поточний шар" + +#: ../../po/../src/ui/dialog/transformation.cpp:105 +msgid "" +"Edit the current transform= matrix; otherwise, post-multiply transform= by " +"this matrix" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:115 +#, fuzzy +msgid "_Move" +msgstr "Перемістити" + +#: ../../po/../src/ui/dialog/transformation.cpp:118 +#, fuzzy +msgid "_Scale" +msgstr "Масштаб" + +#: ../../po/../src/ui/dialog/transformation.cpp:121 +#, fuzzy +msgid "_Rotate" +msgstr "Обернути" + +#: ../../po/../src/ui/dialog/transformation.cpp:124 +#, fuzzy +msgid "Ske_w" +msgstr "Нахилити" + +#: ../../po/../src/ui/dialog/transformation.cpp:127 +msgid "Matri_x" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:141 +msgid "Reset the values on the current tab to defaults" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:148 +#, fuzzy +msgid "Apply transformation to selection" +msgstr "Застосувати перетворення до об'єкту" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:43 +msgid "_Use SSL" +msgstr "_Використовувати SSL" + +#. Construct dialog interface +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:68 +msgid "_Server:" +msgstr "_Сервер:" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:69 +msgid "_Username:" +msgstr "_Користувач:" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:70 +msgid "_Password:" +msgstr "_Пароль:" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:71 +msgid "P_ort:" +msgstr "П_орт:" + +#. Buttons +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:99 +msgid "Connect" +msgstr "З'єднатись" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:126 +msgid "Establishing connection to Jabber server %1 as user %2" +msgstr "" +"Встановлюється з'єднання з сервером Jabber %1 з іменем %2" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:131 +msgid "Failed to establish connection to Jabber server %1" +msgstr "Не вдається встановити з'єднання з сервером Jabber %1" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:136 +msgid "Authentication failed on Jabber server %1 as %2" +msgstr "" +"Помилка автентифікації на сервері Jabber %1 під іменем %2" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:141 +msgid "SSL initialization failed when connecting to Jabber server %1" +msgstr "Помилка ініціалізації SSL при з'єднанні з сервером Jabber %1" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:147 +msgid "Connected to Jabber server %1 as %2" +msgstr "Встановлено з'єднання з сервером Jabber %1 як %2" + +#. Construct labels +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:75 +msgid "Chatroom _name:" +msgstr "Назва _кімнати:" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:76 +msgid "Chatroom _server:" +msgstr "_Сервер кімнати:" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:77 +msgid "Chatroom _password:" +msgstr "_Пароль кімнати:" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:78 +msgid "Chatroom _handle:" +msgstr "_Дескриптор кімнати:" + +#. Button setup and callback registration +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:97 +msgid "Connect to chatroom" +msgstr "Зайти у кімнату" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:132 +msgid "Synchronizing with chatroom %1@%2 using the handle %3" +msgstr "" +"Синхронізація з кімнатою %1@%2 з використанням дескриптора %3" + +#. Construct dialog interface +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:78 +msgid "_User's Jabber ID:" +msgstr "Jabber ID _користувача:" + +#. Buttons +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:82 +msgid "_Invite user" +msgstr "_Запросити користувача" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:83 +msgid "_Cancel" +msgstr "_Скасувати" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:94 +msgid "Buddy List" +msgstr "Список контактів" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:170 +msgid "Sending whiteboard invitation to %1" +msgstr "Надсилається запрошення помалювати разом користувачу %1" + +#. FIXME: strings are replaced by placeholders, NOT to be translated until the code is enabled +#. See http://sourceforge.net/mailarchive/message.php?msg_id=11746016 for details +#. File menu +#. Edit menu +#. View menu +#. Layer menu +#. Object menu +#. Path menu +#. add(Gtk::StockItem(CLEANUP, _("PLACEHOLDER, do not translate"))); (using Gtk::Stock::CLEAR) +#. Text menu +#. About menu +#. Tools toolbox +#. Select Tool controls +#. Node Tool controls +#. Calligraphy Tool controls +#. Session playback controls +#: ../../po/../src/ui/stock-items.cpp:34 ../../po/../src/ui/stock-items.cpp:35 +#: ../../po/../src/ui/stock-items.cpp:36 ../../po/../src/ui/stock-items.cpp:37 +#: ../../po/../src/ui/stock-items.cpp:38 ../../po/../src/ui/stock-items.cpp:39 +#: ../../po/../src/ui/stock-items.cpp:40 ../../po/../src/ui/stock-items.cpp:41 +#: ../../po/../src/ui/stock-items.cpp:42 ../../po/../src/ui/stock-items.cpp:43 +#: ../../po/../src/ui/stock-items.cpp:46 ../../po/../src/ui/stock-items.cpp:47 +#: ../../po/../src/ui/stock-items.cpp:48 ../../po/../src/ui/stock-items.cpp:49 +#: ../../po/../src/ui/stock-items.cpp:50 ../../po/../src/ui/stock-items.cpp:51 +#: ../../po/../src/ui/stock-items.cpp:52 ../../po/../src/ui/stock-items.cpp:53 +#: ../../po/../src/ui/stock-items.cpp:54 ../../po/../src/ui/stock-items.cpp:55 +#: ../../po/../src/ui/stock-items.cpp:56 ../../po/../src/ui/stock-items.cpp:57 +#: ../../po/../src/ui/stock-items.cpp:58 ../../po/../src/ui/stock-items.cpp:59 +#: ../../po/../src/ui/stock-items.cpp:62 ../../po/../src/ui/stock-items.cpp:63 +#: ../../po/../src/ui/stock-items.cpp:64 ../../po/../src/ui/stock-items.cpp:65 +#: ../../po/../src/ui/stock-items.cpp:66 ../../po/../src/ui/stock-items.cpp:67 +#: ../../po/../src/ui/stock-items.cpp:68 ../../po/../src/ui/stock-items.cpp:69 +#: ../../po/../src/ui/stock-items.cpp:70 ../../po/../src/ui/stock-items.cpp:71 +#: ../../po/../src/ui/stock-items.cpp:72 ../../po/../src/ui/stock-items.cpp:73 +#: ../../po/../src/ui/stock-items.cpp:74 ../../po/../src/ui/stock-items.cpp:75 +#: ../../po/../src/ui/stock-items.cpp:76 ../../po/../src/ui/stock-items.cpp:77 +#: ../../po/../src/ui/stock-items.cpp:78 ../../po/../src/ui/stock-items.cpp:79 +#: ../../po/../src/ui/stock-items.cpp:80 ../../po/../src/ui/stock-items.cpp:81 +#: ../../po/../src/ui/stock-items.cpp:82 ../../po/../src/ui/stock-items.cpp:83 +#: ../../po/../src/ui/stock-items.cpp:84 ../../po/../src/ui/stock-items.cpp:85 +#: ../../po/../src/ui/stock-items.cpp:86 ../../po/../src/ui/stock-items.cpp:87 +#: ../../po/../src/ui/stock-items.cpp:88 ../../po/../src/ui/stock-items.cpp:89 +#: ../../po/../src/ui/stock-items.cpp:92 ../../po/../src/ui/stock-items.cpp:93 +#: ../../po/../src/ui/stock-items.cpp:94 ../../po/../src/ui/stock-items.cpp:95 +#: ../../po/../src/ui/stock-items.cpp:96 ../../po/../src/ui/stock-items.cpp:97 +#: ../../po/../src/ui/stock-items.cpp:98 ../../po/../src/ui/stock-items.cpp:99 +#: ../../po/../src/ui/stock-items.cpp:100 +#: ../../po/../src/ui/stock-items.cpp:101 +#: ../../po/../src/ui/stock-items.cpp:102 +#: ../../po/../src/ui/stock-items.cpp:103 +#: ../../po/../src/ui/stock-items.cpp:104 +#: ../../po/../src/ui/stock-items.cpp:105 +#: ../../po/../src/ui/stock-items.cpp:108 +#: ../../po/../src/ui/stock-items.cpp:109 +#: ../../po/../src/ui/stock-items.cpp:110 +#: ../../po/../src/ui/stock-items.cpp:111 +#: ../../po/../src/ui/stock-items.cpp:112 +#: ../../po/../src/ui/stock-items.cpp:113 +#: ../../po/../src/ui/stock-items.cpp:114 +#: ../../po/../src/ui/stock-items.cpp:115 +#: ../../po/../src/ui/stock-items.cpp:116 +#: ../../po/../src/ui/stock-items.cpp:117 +#: ../../po/../src/ui/stock-items.cpp:118 +#: ../../po/../src/ui/stock-items.cpp:119 +#: ../../po/../src/ui/stock-items.cpp:120 +#: ../../po/../src/ui/stock-items.cpp:121 +#: ../../po/../src/ui/stock-items.cpp:122 +#: ../../po/../src/ui/stock-items.cpp:123 +#: ../../po/../src/ui/stock-items.cpp:124 +#: ../../po/../src/ui/stock-items.cpp:125 +#: ../../po/../src/ui/stock-items.cpp:126 +#: ../../po/../src/ui/stock-items.cpp:127 +#: ../../po/../src/ui/stock-items.cpp:130 +#: ../../po/../src/ui/stock-items.cpp:131 +#: ../../po/../src/ui/stock-items.cpp:132 +#: ../../po/../src/ui/stock-items.cpp:133 +#: ../../po/../src/ui/stock-items.cpp:134 +#: ../../po/../src/ui/stock-items.cpp:135 +#: ../../po/../src/ui/stock-items.cpp:136 +#: ../../po/../src/ui/stock-items.cpp:137 +#: ../../po/../src/ui/stock-items.cpp:138 +#: ../../po/../src/ui/stock-items.cpp:139 +#: ../../po/../src/ui/stock-items.cpp:140 +#: ../../po/../src/ui/stock-items.cpp:141 +#: ../../po/../src/ui/stock-items.cpp:142 +#: ../../po/../src/ui/stock-items.cpp:143 +#: ../../po/../src/ui/stock-items.cpp:144 +#: ../../po/../src/ui/stock-items.cpp:145 +#: ../../po/../src/ui/stock-items.cpp:146 +#: ../../po/../src/ui/stock-items.cpp:150 +#: ../../po/../src/ui/stock-items.cpp:151 +#: ../../po/../src/ui/stock-items.cpp:152 +#: ../../po/../src/ui/stock-items.cpp:153 +#: ../../po/../src/ui/stock-items.cpp:156 +#: ../../po/../src/ui/stock-items.cpp:157 +#: ../../po/../src/ui/stock-items.cpp:158 +#: ../../po/../src/ui/stock-items.cpp:161 +#: ../../po/../src/ui/stock-items.cpp:162 +#: ../../po/../src/ui/stock-items.cpp:163 +#: ../../po/../src/ui/stock-items.cpp:164 +#: ../../po/../src/ui/stock-items.cpp:165 +#: ../../po/../src/ui/stock-items.cpp:166 +#: ../../po/../src/ui/stock-items.cpp:167 +#: ../../po/../src/ui/stock-items.cpp:168 +#: ../../po/../src/ui/stock-items.cpp:169 +#: ../../po/../src/ui/stock-items.cpp:170 +#: ../../po/../src/ui/stock-items.cpp:171 +#: ../../po/../src/ui/stock-items.cpp:172 +#: ../../po/../src/ui/stock-items.cpp:175 +#: ../../po/../src/ui/stock-items.cpp:176 +#: ../../po/../src/ui/stock-items.cpp:177 +#: ../../po/../src/ui/stock-items.cpp:178 +#: ../../po/../src/ui/stock-items.cpp:181 +#: ../../po/../src/ui/stock-items.cpp:182 +#: ../../po/../src/ui/stock-items.cpp:183 +#: ../../po/../src/ui/stock-items.cpp:184 +#: ../../po/../src/ui/stock-items.cpp:185 +#: ../../po/../src/ui/stock-items.cpp:186 +#: ../../po/../src/ui/stock-items.cpp:187 +#: ../../po/../src/ui/stock-items.cpp:188 +#: ../../po/../src/ui/stock-items.cpp:189 +#: ../../po/../src/ui/stock-items.cpp:190 +#: ../../po/../src/ui/stock-items.cpp:191 +#: ../../po/../src/ui/stock-items.cpp:194 +#: ../../po/../src/ui/stock-items.cpp:195 +#: ../../po/../src/ui/stock-items.cpp:198 +#: ../../po/../src/ui/stock-items.cpp:199 +#: ../../po/../src/ui/stock-items.cpp:200 +#: ../../po/../src/ui/stock-items.cpp:201 +#: ../../po/../src/ui/stock-items.cpp:202 +msgid "PLACEHOLDER, do not translate" +msgstr "PLACEHOLDER, do not translate" + +#: ../../po/../src/ui/widget/panel.cpp:88 +msgid "small" +msgstr "маленькі" + +#: ../../po/../src/ui/widget/panel.cpp:89 +msgid "medium" +msgstr "середні" + +#: ../../po/../src/ui/widget/panel.cpp:90 +msgid "large" +msgstr "великі" + +#: ../../po/../src/ui/widget/panel.cpp:91 +msgid "huge" +msgstr "величезні" + +#: ../../po/../src/ui/widget/panel.cpp:106 +msgid "List" +msgstr "Список" + +#: ../../po/../src/ui/widget/selected-style.cpp:67 +msgid "F:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:68 +msgid "S:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:69 +msgid "O:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:95 +msgid "N/A" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:98 +#: ../../po/../src/ui/widget/selected-style.cpp:712 +#, fuzzy +msgid "Nothing selected" +msgstr "Не вибрано жодного градієнта" + +#: ../../po/../src/ui/widget/selected-style.cpp:103 +msgid "No fill" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:103 +#, fuzzy +msgid "No stroke" +msgstr " (штрих)" + +#: ../../po/../src/ui/widget/selected-style.cpp:105 +#: ../../po/../src/widgets/paint-selector.cpp:190 +msgid "Pattern" +msgstr "Заповнення візерунком" + +#: ../../po/../src/ui/widget/selected-style.cpp:108 +#: ../../po/../src/widgets/paint-selector.cpp:885 +msgid "Pattern fill" +msgstr "Заповнення візерунком" + +#: ../../po/../src/ui/widget/selected-style.cpp:108 +#, fuzzy +msgid "Pattern stroke" +msgstr "Зміщення пунктиру" + +#: ../../po/../src/ui/widget/selected-style.cpp:110 +#, fuzzy +msgid "L Gradient" +msgstr "Градієнт" + +#: ../../po/../src/ui/widget/selected-style.cpp:113 +#, fuzzy +msgid "Linear gradient fill" +msgstr "Лінійний градієнт" + +#: ../../po/../src/ui/widget/selected-style.cpp:113 +#, fuzzy +msgid "Linear gradient stroke" +msgstr "Лінійний градієнт" + +#: ../../po/../src/ui/widget/selected-style.cpp:115 +#, fuzzy +msgid "R Gradient" +msgstr "Градієнт" + +#: ../../po/../src/ui/widget/selected-style.cpp:118 +#, fuzzy +msgid "Radial gradient fill" +msgstr "Радіальний градієнт" + +#: ../../po/../src/ui/widget/selected-style.cpp:118 +#, fuzzy +msgid "Radial gradient stroke" +msgstr "Радіальний градієнт" + +#: ../../po/../src/ui/widget/selected-style.cpp:120 +#, fuzzy +msgid "Different" +msgstr "Р_ізниця" + +#: ../../po/../src/ui/widget/selected-style.cpp:123 +#, fuzzy +msgid "Different fills" +msgstr "Р_ізниця" + +#: ../../po/../src/ui/widget/selected-style.cpp:123 +#, fuzzy +msgid "Different strokes" +msgstr "Р_ізниця" + +#: ../../po/../src/ui/widget/selected-style.cpp:125 +#, fuzzy +msgid "Unset" +msgstr "утягнена" + +#. TRANSLATORS COMMENT: unset is a verb here +#: ../../po/../src/ui/widget/selected-style.cpp:128 +#: ../../po/../src/ui/widget/selected-style.cpp:182 +msgid "Unset fill" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:128 +#: ../../po/../src/ui/widget/selected-style.cpp:182 +#, fuzzy +msgid "Unset stroke" +msgstr " (штрих)" + +#: ../../po/../src/ui/widget/selected-style.cpp:131 +#, fuzzy +msgid "Flat color fill" +msgstr "Суцільний колір" + +#: ../../po/../src/ui/widget/selected-style.cpp:131 +#, fuzzy +msgid "Flat color stroke" +msgstr "Суцільний колір" + +#. TRANSLATOR COMMENT: A means "Averaged" +#: ../../po/../src/ui/widget/selected-style.cpp:134 +#, fuzzy +msgid "A" +msgstr "_A" + +#: ../../po/../src/ui/widget/selected-style.cpp:137 +#, fuzzy +msgid "Fill is averaged over selected objects" +msgstr "Виключне АБО виділених об'єктів" + +#: ../../po/../src/ui/widget/selected-style.cpp:137 +#, fuzzy +msgid "Stroke is averaged over selected objects" +msgstr "Змусити лінії обгинати виділені об'єкти" + +#. TRANSLATOR COMMENT: M means "Multiple" +#: ../../po/../src/ui/widget/selected-style.cpp:140 +#, fuzzy +msgid "M" +msgstr "_M" + +#: ../../po/../src/ui/widget/selected-style.cpp:143 +#, fuzzy +msgid "Multiple selected objects have the same fill" +msgstr "Вирівняти вибрані вузли по вертикалі" + +#: ../../po/../src/ui/widget/selected-style.cpp:143 +#, fuzzy +msgid "Multiple selected objects have the same stroke" +msgstr "Вирівняти вибрані вузли по вертикалі" + +#: ../../po/../src/ui/widget/selected-style.cpp:145 +#, fuzzy +msgid "Edit fill..." +msgstr "Редагування..." + +#: ../../po/../src/ui/widget/selected-style.cpp:145 +#, fuzzy +msgid "Edit stroke..." +msgstr "Редагування..." + +#: ../../po/../src/ui/widget/selected-style.cpp:149 +#, fuzzy +msgid "Last set color" +msgstr "Суцільний колір" + +#: ../../po/../src/ui/widget/selected-style.cpp:153 +#, fuzzy +msgid "Last selected color" +msgstr "Останній виділений" + +#: ../../po/../src/ui/widget/selected-style.cpp:157 +#, fuzzy +msgid "White" +msgstr "Спільне _малювання" + +#: ../../po/../src/ui/widget/selected-style.cpp:161 +#: ../../po/../src/widgets/sp-color-scales.cpp:461 +#: ../../po/../src/widgets/sp-color-scales.cpp:462 +msgid "Black" +msgstr "Чорний" + +#: ../../po/../src/ui/widget/selected-style.cpp:165 +#, fuzzy +msgid "Copy color" +msgstr "Колір опорної точки" + +#: ../../po/../src/ui/widget/selected-style.cpp:169 +#, fuzzy +msgid "Paste color" +msgstr "Суцільний колір" + +#: ../../po/../src/ui/widget/selected-style.cpp:173 +#, fuzzy +msgid "Swap fill and stroke" +msgstr "_Заповнення та штрих" + +#: ../../po/../src/ui/widget/selected-style.cpp:177 +msgid "Make fill opaque" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:177 +msgid "Make stroke opaque" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:186 +#, fuzzy +msgid "Remove fill" +msgstr "В_идалити " + +#: ../../po/../src/ui/widget/selected-style.cpp:186 +#, fuzzy +msgid "Remove stroke" +msgstr "П_омістити в рамку" + +#: ../../po/../src/ui/widget/selected-style.cpp:718 +#, fuzzy +msgid "Master opacity" +msgstr "Загальна _прозорість" + +#: ../../po/../src/ui/widget/selected-style.cpp:744 +msgid "0 (transparent)" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:768 +msgid "1.0 (opaque)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1046 +msgid "Moved to next layer." +msgstr "Переміщений на наступний шар." + +#: ../../po/../src/verbs.cpp:1048 +#, fuzzy +msgid "Cannot move past last layer." +msgstr "Не вдається перемістити за останній шар." + +#: ../../po/../src/verbs.cpp:1057 +msgid "Moved to previous layer." +msgstr "Переміщений на попередній шар." + +#: ../../po/../src/verbs.cpp:1059 +#, fuzzy +msgid "Cannot move past first layer." +msgstr "Не вдається перемістити за перший шар." + +#: ../../po/../src/verbs.cpp:1076 ../../po/../src/verbs.cpp:1150 +msgid "No current layer." +msgstr "Немає поточного шару." + +#: ../../po/../src/verbs.cpp:1105 +#, c-format +msgid "Raised layer %s." +msgstr "Шар %s піднято." + +#: ../../po/../src/verbs.cpp:1109 +#, c-format +msgid "Lowered layer %s." +msgstr "Шар %s опущено." + +#: ../../po/../src/verbs.cpp:1118 +#, fuzzy +msgid "Cannot move layer any further." +msgstr "Не вдається перемістити шар далі." + +#. TRANSLATORS: this means "The layer has been deleted." +#: ../../po/../src/verbs.cpp:1148 +msgid "Deleted layer." +msgstr "Шар видалено." + +#: ../../po/../src/verbs.cpp:1544 +msgid "" +"You need to connect to a Jabber server before sharing a document with " +"another user." +msgstr "" +"Щоб працювати над одним документом з іншим користувачем, спочатку треба " +"з'єднатись з сервером Jabber." + +#: ../../po/../src/verbs.cpp:1559 +msgid "" +"You need to connect to a Jabber server before sharing a document with a " +"chatroom." +msgstr "" +"Щоб працювати над одним документом усією командою, спочатку треба з'єднатись " +"з сервером Jabber." + +#: ../../po/../src/verbs.cpp:1569 +msgid "XML node tracker has not been initialized; nothing to dump" +msgstr "Аналізатор вузлів XML не було ініціалізовано; нема що виводити" + +#. TRANSLATORS: If you have translated the keys.svg file to your language, then +#. translate this string as "keys.LANG.svg" (where LANG is your language code); +#. otherwise leave as "keys.svg". +#: ../../po/../src/verbs.cpp:1631 +msgid "keys.svg" +msgstr "keys.svg" + +#. TRANSLATORS: If you have translated the tutorial-basic.svg file to your language, +#. then translate this string as "tutorial-basic.LANG.svg" (where LANG is your language +#. code); otherwise leave as "tutorial-basic.svg". +#: ../../po/../src/verbs.cpp:1667 +msgid "tutorial-basic.svg" +msgstr "tutorial-basic.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1671 +msgid "tutorial-shapes.svg" +msgstr "tutorial-shapes.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1675 +msgid "tutorial-advanced.svg" +msgstr "tutorial-advanced.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1679 +msgid "tutorial-tracing.svg" +msgstr "tutorial-tracing.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1683 +msgid "tutorial-calligraphy.svg" +msgstr "tutorial-calligraphy.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1687 +msgid "tutorial-elements.svg" +msgstr "tutorial-elements.svg" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1691 +msgid "tutorial-tips.svg" +msgstr "tutorial-tips.svg" + +#: ../../po/../src/verbs.cpp:1842 +msgid "Does nothing" +msgstr "Немає дій" + +#. File +#: ../../po/../src/verbs.cpp:1845 +msgid "Default" +msgstr "Типовий" + +#: ../../po/../src/verbs.cpp:1845 +msgid "Create new document from default template" +msgstr "Створити новий документ зі стандартного шаблону" + +#: ../../po/../src/verbs.cpp:1847 +msgid "_Open..." +msgstr "_Відкрити..." + +#: ../../po/../src/verbs.cpp:1848 +msgid "Open existing document" +msgstr "Відкрити існуючий документ" + +#: ../../po/../src/verbs.cpp:1849 +msgid "Re_vert" +msgstr "Від_новити" + +#: ../../po/../src/verbs.cpp:1850 +msgid "Revert to the last saved version of document (changes will be lost)" +msgstr "Відновити останню збережену версію документа (зміни будуть втрачені)" + +#: ../../po/../src/verbs.cpp:1851 +msgid "_Save" +msgstr "З_берегти" + +#: ../../po/../src/verbs.cpp:1851 +msgid "Save document" +msgstr "Зберегти документ" + +#: ../../po/../src/verbs.cpp:1853 +msgid "Save _As..." +msgstr "Зберегти _як..." + +#: ../../po/../src/verbs.cpp:1854 +msgid "Save document under new name" +msgstr "Зберегти документ під іншою назвою" + +#: ../../po/../src/verbs.cpp:1855 +msgid "_Print..." +msgstr "Д_рук..." + +#: ../../po/../src/verbs.cpp:1855 +msgid "Print document" +msgstr "Надрукувати документ" + +#. TRANSLATORS: "Vacuum Defs" means "Clean up defs" (so as to remove unused definitions) +#: ../../po/../src/verbs.cpp:1858 +msgid "Vac_uum Defs" +msgstr "О_чистити Defs" + +#: ../../po/../src/verbs.cpp:1858 +#, fuzzy +msgid "Remove unused predefined items from the <defs> of the document" +msgstr "Прибрати непотрібне з <defs> документу" + +#: ../../po/../src/verbs.cpp:1860 +msgid "Print _Direct" +msgstr "_Прямий друк" + +#: ../../po/../src/verbs.cpp:1861 +#, fuzzy +msgid "Print directly without prompting to a file or pipe" +msgstr "Надрукувати документ у файл або передати програмі" + +#: ../../po/../src/verbs.cpp:1862 +msgid "Print Previe_w" +msgstr "_Попередній перегляд" + +#: ../../po/../src/verbs.cpp:1863 +msgid "Preview document printout" +msgstr "Попередній перегляд друку" + +#: ../../po/../src/verbs.cpp:1864 +msgid "_Import..." +msgstr "_Імпорт..." + +#: ../../po/../src/verbs.cpp:1865 +msgid "Import bitmap or SVG image into document" +msgstr "Імпортувати зображення (растрове чи SVG) у документ" + +#: ../../po/../src/verbs.cpp:1866 +msgid "_Export Bitmap..." +msgstr "_Експорт..." + +#: ../../po/../src/verbs.cpp:1867 +#, fuzzy +msgid "Export document or selection as a bitmap image" +msgstr "Експортувати документ чи виділену частину у растровий формат PNG" + +#: ../../po/../src/verbs.cpp:1868 +msgid "N_ext Window" +msgstr "_Наступне вікно" + +#: ../../po/../src/verbs.cpp:1869 +msgid "Switch to the next document window" +msgstr "Перейти до наступного вікна документу" + +#: ../../po/../src/verbs.cpp:1870 +msgid "P_revious Window" +msgstr "_Попереднє вікно" + +#: ../../po/../src/verbs.cpp:1871 +msgid "Switch to the previous document window" +msgstr "Перейти до попереднього вікна документу" + +#: ../../po/../src/verbs.cpp:1872 +msgid "_Close" +msgstr "_Закрити" + +#: ../../po/../src/verbs.cpp:1873 +msgid "Close window" +msgstr "Закрити вікно" + +#: ../../po/../src/verbs.cpp:1874 +msgid "_Quit" +msgstr "Ви_йти" + +#: ../../po/../src/verbs.cpp:1874 +msgid "Quit Inkscape" +msgstr "Вийти з Inkscape" + +#. Edit +#: ../../po/../src/verbs.cpp:1877 +msgid "_Undo" +msgstr "В_ернути" + +#: ../../po/../src/verbs.cpp:1877 +msgid "Undo last action" +msgstr "Скасувати останню операцію" + +#: ../../po/../src/verbs.cpp:1879 +msgid "_Redo" +msgstr "Повт_орити" + +#: ../../po/../src/verbs.cpp:1880 +msgid "Do again last undone action" +msgstr "Повторити останню скасовану дію" + +#: ../../po/../src/verbs.cpp:1881 +msgid "Cu_t" +msgstr "_Вирізати" + +#: ../../po/../src/verbs.cpp:1882 +msgid "Cut selection to clipboard" +msgstr "Вирізати виділене у буфер обміну" + +#: ../../po/../src/verbs.cpp:1883 +msgid "_Copy" +msgstr "_Копіювати" + +#: ../../po/../src/verbs.cpp:1884 +msgid "Copy selection to clipboard" +msgstr "Скопіювати виділене у буфер обміну" + +#: ../../po/../src/verbs.cpp:1885 +msgid "_Paste" +msgstr "Вст_авити" + +#: ../../po/../src/verbs.cpp:1886 +#, fuzzy +msgid "Paste objects from clipboard to mouse point" +msgstr "Вставити об'єкт(и) з буферу обміну у позицію курсора миші" + +#: ../../po/../src/verbs.cpp:1887 +msgid "Paste _Style" +msgstr "Вставити _стиль" + +#: ../../po/../src/verbs.cpp:1888 +msgid "Apply style of the copied object to selection" +msgstr "Застосувати стиль скопійованого об'єкта до виділеного" + +#: ../../po/../src/verbs.cpp:1889 +msgid "Paste _In Place" +msgstr "Вставити на _місце" + +#: ../../po/../src/verbs.cpp:1890 +#, fuzzy +msgid "Paste objects from clipboard to the original location" +msgstr "Вставити об'єкти з буфера у місце, де вони були раніше" + +#: ../../po/../src/verbs.cpp:1891 +msgid "_Delete" +msgstr "В_идалити" + +#: ../../po/../src/verbs.cpp:1892 +msgid "Delete selection" +msgstr "Видалити виділене" + +#: ../../po/../src/verbs.cpp:1893 +msgid "Duplic_ate" +msgstr "_Дублювати" + +#: ../../po/../src/verbs.cpp:1894 +#, fuzzy +msgid "Duplicate selected objects" +msgstr "Створити копію виділених об'єктів" + +#: ../../po/../src/verbs.cpp:1895 +msgid "Clo_ne" +msgstr "Клон_увати" + +#: ../../po/../src/verbs.cpp:1896 +msgid "Create a clone of selected object (a copy linked to the original)" +msgstr "Створити клон виділеного об'єкту (копію, пов'язану з оригіналом)" + +#: ../../po/../src/verbs.cpp:1897 +msgid "Unlin_k Clone" +msgstr "В_ід'єднати клон" + +#: ../../po/../src/verbs.cpp:1898 +msgid "Cut the clone's link to its original" +msgstr "Прибрати у клону посилання на оригінал" + +#: ../../po/../src/verbs.cpp:1899 +msgid "Select _Original" +msgstr "Виділити о_ригінал" + +#: ../../po/../src/verbs.cpp:1900 +msgid "Select the object to which the clone is linked" +msgstr "Виділити об'єкт з яким пов'язаний клон" + +#. TRANSLATORS: Convert selection to a rectangle with tiled pattern fill +#: ../../po/../src/verbs.cpp:1902 +#, fuzzy +msgid "O_bjects to Pattern" +msgstr "О_б'єкти у візерунок" + +#: ../../po/../src/verbs.cpp:1903 +msgid "Convert selection to a rectangle with tiled pattern fill" +msgstr "Перетворити виділене у прямокутник, заповнений візерунком" + +#. TRANSLATORS: Extract objects from a tiled pattern fill +#: ../../po/../src/verbs.cpp:1905 +#, fuzzy +msgid "Pattern to Ob_jects" +msgstr "_Візерунок у об'єкти" + +#: ../../po/../src/verbs.cpp:1906 +msgid "Extract objects from a tiled pattern fill" +msgstr "Витягнути об'єкти з текстурного заповнення" + +#: ../../po/../src/verbs.cpp:1907 +msgid "Clea_r All" +msgstr "О_чистити все" + +#: ../../po/../src/verbs.cpp:1908 +msgid "Delete all objects from document" +msgstr "Видалити усі об'єкти з документу" + +#: ../../po/../src/verbs.cpp:1909 +msgid "Select Al_l" +msgstr "Виді_лити все" + +#: ../../po/../src/verbs.cpp:1910 +msgid "Select all objects or all nodes" +msgstr "Виділити всі об'єкти чи всі вузли" + +#: ../../po/../src/verbs.cpp:1911 +msgid "Select All in All La_yers" +msgstr "Виділити все в усіх _шарах" + +#: ../../po/../src/verbs.cpp:1912 +msgid "Select all objects in all visible and unlocked layers" +msgstr "Виділити усі об'єкти в усіх видимих та незамкнутих шарах" + +#: ../../po/../src/verbs.cpp:1913 +msgid "In_vert Selection" +msgstr "_Інвертувати виділення" + +#: ../../po/../src/verbs.cpp:1914 +msgid "Invert selection (unselect what is selected and select everything else)" +msgstr "Інвертувати виділення (зняти виділення з виділеного та виділити решту)" + +#: ../../po/../src/verbs.cpp:1915 +msgid "Invert in All Layers" +msgstr "Інвертувати в усіх шарах" + +#: ../../po/../src/verbs.cpp:1916 +msgid "Invert selection in all visible and unlocked layers" +msgstr "Інвертувати виділення в усіх видимих та незамкнених шарах" + +#: ../../po/../src/verbs.cpp:1917 +msgid "D_eselect" +msgstr "Зн_яти виділення" + +#: ../../po/../src/verbs.cpp:1918 +msgid "Deselect any selected objects or nodes" +msgstr "Зняти виділення з усіх об'єктів чи вузлів" + +#. Selection +#: ../../po/../src/verbs.cpp:1921 +msgid "Raise to _Top" +msgstr "Підняти на п_ередній план" + +#: ../../po/../src/verbs.cpp:1922 +msgid "Raise selection to top" +msgstr "Підняти виділене на передній план" + +#: ../../po/../src/verbs.cpp:1923 +msgid "Lower to _Bottom" +msgstr "Опустити на з_адній план" + +#: ../../po/../src/verbs.cpp:1924 +msgid "Lower selection to bottom" +msgstr "Опустити виділене на задній план" + +#: ../../po/../src/verbs.cpp:1925 +msgid "_Raise" +msgstr "_Підняти" + +#: ../../po/../src/verbs.cpp:1926 +msgid "Raise selection one step" +msgstr "Підняти виділене на один рівень" + +#: ../../po/../src/verbs.cpp:1927 +msgid "_Lower" +msgstr "_Опустити" + +#: ../../po/../src/verbs.cpp:1928 +msgid "Lower selection one step" +msgstr "Опустити виділене на один рівень" + +#: ../../po/../src/verbs.cpp:1929 +msgid "_Group" +msgstr "З_групувати" + +#: ../../po/../src/verbs.cpp:1930 +msgid "Group selected objects" +msgstr "Згрупувати виділені об'єкти" + +#: ../../po/../src/verbs.cpp:1932 +#, fuzzy +msgid "Ungroup selected groups" +msgstr "Розгрупувати виділені групи" + +#: ../../po/../src/verbs.cpp:1934 +msgid "_Put on Path" +msgstr "_Розмістити по контуру" + +#: ../../po/../src/verbs.cpp:1935 +msgid "Put text on path" +msgstr "Розмістити текст по контуру" + +#: ../../po/../src/verbs.cpp:1936 +msgid "_Remove from Path" +msgstr "Відокрем_ити від контуру" + +#: ../../po/../src/verbs.cpp:1937 +msgid "Remove text from path" +msgstr "Зняти текст з контуру" + +#: ../../po/../src/verbs.cpp:1938 +msgid "Remove Manual _Kerns" +msgstr "Видалити ручний _кернінг" + +#. TRANSLATORS: "glyph": An image used in the visual representation of characters; +#. roughly speaking, how a character looks. A font is a set of glyphs. +#: ../../po/../src/verbs.cpp:1941 +msgid "Remove all manual kerns and glyph rotations from a text object" +msgstr "" +"Видалити з текстового об'єкта усі додані вручну повороти кернів та гліфів" + +#: ../../po/../src/verbs.cpp:1943 +msgid "_Union" +msgstr "С_ума" + +#: ../../po/../src/verbs.cpp:1944 +msgid "Union of selected objects" +msgstr "Сума виділених об'єктів" + +#: ../../po/../src/verbs.cpp:1945 +msgid "_Intersection" +msgstr "_Перетин" + +#: ../../po/../src/verbs.cpp:1946 +msgid "Intersection of selected objects" +msgstr "Перетин виділених об'єктів" + +#: ../../po/../src/verbs.cpp:1947 +msgid "_Difference" +msgstr "Р_ізниця" + +#: ../../po/../src/verbs.cpp:1948 +msgid "Difference of selected objects (bottom minus top)" +msgstr "Різниця виділених об'єктів (низ мінус верх)" + +#: ../../po/../src/verbs.cpp:1949 +msgid "E_xclusion" +msgstr "Виключне _АБО" + +#: ../../po/../src/verbs.cpp:1950 +msgid "Exclusive OR of selected objects" +msgstr "Виключне АБО виділених об'єктів" + +#: ../../po/../src/verbs.cpp:1951 +msgid "Di_vision" +msgstr "_Ділення" + +#: ../../po/../src/verbs.cpp:1952 +msgid "Cut the bottom object into pieces" +msgstr "Розрізати нижній об'єкт верхнім на частини" + +#. TRANSLATORS: "to cut a path" is not the same as "to break a path apart" - see the +#. Advanced tutorial for more info +#: ../../po/../src/verbs.cpp:1955 +msgid "Cut _Path" +msgstr "Розрізати _контур" + +#: ../../po/../src/verbs.cpp:1956 +msgid "Cut the bottom object's stroke into pieces, removing fill" +msgstr "" +"Розрізати контур нижнього об'єкта верхнім на частини, з видаленням заповнення" + +#. TRANSLATORS: "outset": expand a shape by offsetting the object's path, +#. i.e. by displacing it perpendicular to the path in each point. +#. See also the Advanced Tutorial for explanation. +#: ../../po/../src/verbs.cpp:1960 +msgid "Outs_et" +msgstr "Ро_зтягнути" + +#: ../../po/../src/verbs.cpp:1961 +#, fuzzy +msgid "Outset selected paths" +msgstr "Розтягнути виділений контур" + +#: ../../po/../src/verbs.cpp:1963 +msgid "O_utset Path by 1 px" +msgstr "Р_озтягнути на 1 точку" + +#: ../../po/../src/verbs.cpp:1964 +#, fuzzy +msgid "Outset selected paths by 1 px" +msgstr "Розтягнути виділений контур(и) на 1 точку" + +#: ../../po/../src/verbs.cpp:1966 +msgid "O_utset Path by 10 px" +msgstr "Р_озтягнути на 10 точок" + +#: ../../po/../src/verbs.cpp:1967 +#, fuzzy +msgid "Outset selected paths by 10 px" +msgstr "Розтягнути виділений контур(и) на 10 точок" + +#. TRANSLATORS: "inset": contract a shape by offsetting the object's path, +#. i.e. by displacing it perpendicular to the path in each point. +#. See also the Advanced Tutorial for explanation. +#: ../../po/../src/verbs.cpp:1971 +msgid "I_nset" +msgstr "В_тягнути" + +#: ../../po/../src/verbs.cpp:1972 +#, fuzzy +msgid "Inset selected paths" +msgstr "Втягнути виділений контур(и)" + +#: ../../po/../src/verbs.cpp:1974 +msgid "I_nset Path by 1 px" +msgstr "Вт_ягнути контур на 1 точку" + +#: ../../po/../src/verbs.cpp:1975 +#, fuzzy +msgid "Inset selected paths by 1 px" +msgstr "Втягнути виділений контур(и) на 1 точку" + +#: ../../po/../src/verbs.cpp:1977 +msgid "I_nset Path by 10 px" +msgstr "Вт_ягнути контур на 10 точок" + +#: ../../po/../src/verbs.cpp:1978 +#, fuzzy +msgid "Inset selected paths by 10 px" +msgstr "Втягнути виділений контур(и) на 10 точок" + +#: ../../po/../src/verbs.cpp:1980 +msgid "D_ynamic Offset" +msgstr "Д_инамічне втягування" + +#: ../../po/../src/verbs.cpp:1980 +msgid "Create a dynamic offset object" +msgstr "" +"Створити об'єкт, втягування/розтягування якого можна змінювати динамічно" + +#: ../../po/../src/verbs.cpp:1982 +msgid "_Linked Offset" +msgstr "Зв'_язане втягування" + +#: ../../po/../src/verbs.cpp:1983 +msgid "Create a dynamic offset object linked to the original path" +msgstr "" +"Створити втягування/розтягування, динамічно пов'язане з початковим контуром" + +#: ../../po/../src/verbs.cpp:1985 +msgid "_Stroke to Path" +msgstr "_Штрих у контур" + +#: ../../po/../src/verbs.cpp:1986 +#, fuzzy +msgid "Convert selected strokes to paths" +msgstr "Перетворити виділені штрихи у контури" + +#: ../../po/../src/verbs.cpp:1987 +msgid "Si_mplify" +msgstr "_Спростити" + +#: ../../po/../src/verbs.cpp:1988 +#, fuzzy +msgid "Simplify selected paths by removing extra nodes" +msgstr "Спростити виділені контури видаленням зайвих вузлів" + +#: ../../po/../src/verbs.cpp:1989 +msgid "_Reverse" +msgstr "Роз_вернути" + +#: ../../po/../src/verbs.cpp:1990 +#, fuzzy +msgid "Reverses the direction of selected paths; useful for flipping markers" +msgstr "" +"Змінити напрямок виділених контурів на протилежний; корисно для " +"віддзеркалення маркерів" + +#. TRANSLATORS: "to trace" means "to convert a bitmap to vector graphics" (to vectorize) +#: ../../po/../src/verbs.cpp:1992 +msgid "_Trace Bitmap" +msgstr "_Векторизувати растр" + +#: ../../po/../src/verbs.cpp:1993 +msgid "Convert bitmap object to paths" +msgstr "Перетворити растровий об'єкт у контури" + +#: ../../po/../src/verbs.cpp:1994 +msgid "_Make a Bitmap Copy" +msgstr "_Зробити растрову копію" + +#: ../../po/../src/verbs.cpp:1995 +msgid "Export selection to a bitmap and insert it into document" +msgstr "Експортувати виділене у растр та вставити його у документ" + +#: ../../po/../src/verbs.cpp:1996 +msgid "_Combine" +msgstr "Об'_єднати" + +#: ../../po/../src/verbs.cpp:1997 +msgid "Combine several paths into one" +msgstr "Об'єднати декілька контурів у один" + +#. TRANSLATORS: "to cut a path" is not the same as "to break a path apart" - see the +#. Advanced tutorial for more info +#: ../../po/../src/verbs.cpp:2000 +msgid "Break _Apart" +msgstr "_Розділити" + +#: ../../po/../src/verbs.cpp:2001 +#, fuzzy +msgid "Break selected paths into subpaths" +msgstr "Розділити виділені контури на частини" + +#: ../../po/../src/verbs.cpp:2002 +msgid "Gri_d Arrange..." +msgstr "_Розподілити вздовж сітки" + +#: ../../po/../src/verbs.cpp:2003 +msgid "Arrange selection in grid pattern" +msgstr "Вирівняти виділене за шаблоном сітки" + +#. Layer +#: ../../po/../src/verbs.cpp:2005 +msgid "_Add Layer..." +msgstr "_Додати шар..." + +#: ../../po/../src/verbs.cpp:2006 +msgid "Create a new layer" +msgstr "Створити новий шар" + +#: ../../po/../src/verbs.cpp:2007 +msgid "Re_name Layer..." +msgstr "Пере_йменувати шар..." + +#: ../../po/../src/verbs.cpp:2008 +msgid "Rename the current layer" +msgstr "Перейменувати поточний шар" + +#: ../../po/../src/verbs.cpp:2009 +msgid "Switch to Layer Abov_e" +msgstr "Перейти на шар _вище" + +#: ../../po/../src/verbs.cpp:2010 +msgid "Switch to the layer above the current" +msgstr "Перейти на шар, що знаходиться вище від поточного" + +#: ../../po/../src/verbs.cpp:2011 +msgid "Switch to Layer Belo_w" +msgstr "Перейти на шар _нижче" + +#: ../../po/../src/verbs.cpp:2012 +msgid "Switch to the layer below the current" +msgstr "Перейти на шар, що знаходиться нижче від поточного" + +#: ../../po/../src/verbs.cpp:2013 +msgid "Move Selection to Layer Abo_ve" +msgstr "Перемістити виділене на шар ви_ще" + +#: ../../po/../src/verbs.cpp:2014 +msgid "Move selection to the layer above the current" +msgstr "Перемістити на шар, що знаходиться над поточним" + +#: ../../po/../src/verbs.cpp:2015 +msgid "Move Selection to Layer Bel_ow" +msgstr "Перемістити на шар ни_жче" + +#: ../../po/../src/verbs.cpp:2016 +msgid "Move selection to the layer below the current" +msgstr "Перемістити на шар, що знаходиться під поточним" + +#: ../../po/../src/verbs.cpp:2017 +msgid "Layer to _Top" +msgstr "Підняти шар до_гори" + +#: ../../po/../src/verbs.cpp:2018 +msgid "Raise the current layer to the top" +msgstr "Підняти поточний шар догори" + +#: ../../po/../src/verbs.cpp:2019 +msgid "Layer to _Bottom" +msgstr "Опустити шар до_долу" + +#: ../../po/../src/verbs.cpp:2020 +msgid "Lower the current layer to the bottom" +msgstr "Опустити поточний шар додолу" + +#: ../../po/../src/verbs.cpp:2021 +msgid "_Raise Layer" +msgstr "_Підняти шар" + +#: ../../po/../src/verbs.cpp:2022 +msgid "Raise the current layer" +msgstr "Підняти поточний шар" + +#: ../../po/../src/verbs.cpp:2023 +msgid "_Lower Layer" +msgstr "_Опустити шар" + +#: ../../po/../src/verbs.cpp:2024 +msgid "Lower the current layer" +msgstr "Опустити поточний шар" + +#: ../../po/../src/verbs.cpp:2025 +msgid "_Delete Current Layer" +msgstr "В_идалити поточний шар" + +#: ../../po/../src/verbs.cpp:2026 +msgid "Delete the current layer" +msgstr "Видалити поточний шар" + +#. Object +#: ../../po/../src/verbs.cpp:2029 +#, fuzzy +msgid "Rotate _90° CW" +msgstr "Обернути на _90° за годинниковою стрілкою" + +#: ../../po/../src/verbs.cpp:2030 +#, fuzzy +msgid "Rotate selection 90° clockwise" +msgstr "Обернути виділене на 90° за годинниковою стрілкою" + +#: ../../po/../src/verbs.cpp:2031 +#, fuzzy +msgid "Rotate 9_0° CCW" +msgstr "Обернути на 9_0° проти годинникової стрілки" + +#: ../../po/../src/verbs.cpp:2032 +#, fuzzy +msgid "Rotate selection 90° counter-clockwise" +msgstr "Обернути виділене на 90° проти годинникової стрілки" + +#: ../../po/../src/verbs.cpp:2033 +msgid "Remove _Transformations" +msgstr "Прибрати _трансформацію" + +#: ../../po/../src/verbs.cpp:2034 +msgid "Remove transformations from object" +msgstr "Прибрати трансформації з об'єкту" + +#: ../../po/../src/verbs.cpp:2035 +msgid "_Object to Path" +msgstr "_Об'єкт у контур" + +#: ../../po/../src/verbs.cpp:2036 +#, fuzzy +msgid "Convert selected objects to paths" +msgstr "Перетворити виділені об'єкти на контури" + +#: ../../po/../src/verbs.cpp:2037 +msgid "_Flow into Frame" +msgstr "_Огорнути в рамку" + +#: ../../po/../src/verbs.cpp:2038 +#, fuzzy +msgid "Put text into frames" +msgstr "Помістити текст в рамку(и)" + +#: ../../po/../src/verbs.cpp:2039 +msgid "_Unflow" +msgstr "_Вийняти з рамки" + +#: ../../po/../src/verbs.cpp:2040 +msgid "Remove text from frame (creates a single-line text object)" +msgstr "Вийняти тест з рамки, створивши звичайний тестовий об'єкт в один рядок" + +#: ../../po/../src/verbs.cpp:2041 +msgid "_Convert to Text" +msgstr "_Перетворити у текст" + +#: ../../po/../src/verbs.cpp:2042 +#, fuzzy +msgid "Convert flowed text to regular text objects (preserves appearance)" +msgstr "" +"Перетворити текст, що огорнений рамкою, у звичайний текст (із збереженням " +"вигляду)" + +#: ../../po/../src/verbs.cpp:2044 +#, fuzzy +msgid "Flip _Horizontal" +msgstr "Віддзеркалити гор_изонтально" + +#: ../../po/../src/verbs.cpp:2044 +#, fuzzy +msgid "Flips selected objects horizontally" +msgstr "Вирівняти вибрані вузли по горизонталі" + +#: ../../po/../src/verbs.cpp:2047 +#, fuzzy +msgid "Flip _Vertical" +msgstr "Віддзеркалити _вертикально" + +#: ../../po/../src/verbs.cpp:2047 +#, fuzzy +msgid "Flips selected objects vertically" +msgstr "Вирівняти вибрані вузли по вертикалі" + +#. Tools +#: ../../po/../src/verbs.cpp:2051 +msgid "Select" +msgstr "Селектор" + +#: ../../po/../src/verbs.cpp:2052 +msgid "Select and transform objects" +msgstr "Виділення та трансформація об'єктів" + +#: ../../po/../src/verbs.cpp:2053 +msgid "Node Edit" +msgstr "Редактор вузлів" + +#: ../../po/../src/verbs.cpp:2054 +msgid "Edit path nodes or control handles" +msgstr "Редагування вузлів контурів та вусів вузлів" + +#: ../../po/../src/verbs.cpp:2056 +msgid "Create rectangles and squares" +msgstr "Створення прямокутників та квадратів" + +#: ../../po/../src/verbs.cpp:2058 +msgid "Create circles, ellipses, and arcs" +msgstr "Створення кіл, еліпсів та дуг" + +#: ../../po/../src/verbs.cpp:2060 +msgid "Create stars and polygons" +msgstr "Створення зірок та багатокутників" + +#: ../../po/../src/verbs.cpp:2062 +msgid "Create spirals" +msgstr "Створення спіралей" + +#: ../../po/../src/verbs.cpp:2064 +msgid "Draw freehand lines" +msgstr "Малювання довільних контурів" + +#: ../../po/../src/verbs.cpp:2066 +msgid "Draw Bezier curves and straight lines" +msgstr "Малювання кривих Безьє чи прямих ліній" + +#: ../../po/../src/verbs.cpp:2068 +msgid "Draw calligraphic lines" +msgstr "Малювання каліграфічних ліній" + +#: ../../po/../src/verbs.cpp:2070 +msgid "Create and edit text objects" +msgstr "Створення та зміна текстових об'єктів" + +#: ../../po/../src/verbs.cpp:2072 +msgid "Create and edit gradients" +msgstr "Створення та зміна градієнтів" + +#: ../../po/../src/verbs.cpp:2074 +msgid "Zoom in or out" +msgstr "Змінити масштаб" + +#: ../../po/../src/verbs.cpp:2076 +msgid "Pick averaged colors from image" +msgstr "Брати усереднені кольори з зображення" + +#: ../../po/../src/verbs.cpp:2078 +msgid "Create connectors" +msgstr "Створити лінії з'єднання" + +#. Tool prefs +#: ../../po/../src/verbs.cpp:2081 +msgid "Selector Preferences" +msgstr "Параметри селектора" + +#: ../../po/../src/verbs.cpp:2082 +#, fuzzy +msgid "Open Preferences for the Selector tool" +msgstr "Відкрити вікно параметрів Inkscape селектора" + +#: ../../po/../src/verbs.cpp:2083 +msgid "Node Tool Preferences" +msgstr "Параметри редактора вузлів" + +#: ../../po/../src/verbs.cpp:2084 +#, fuzzy +msgid "Open Preferences for the Node tool" +msgstr "Відкрити вікно параметрів Inkscape для інструмента \"Редактор вузлів\"" + +#: ../../po/../src/verbs.cpp:2085 +msgid "Rectangle Preferences" +msgstr "Параметри прямокутника" + +#: ../../po/../src/verbs.cpp:2086 +#, fuzzy +msgid "Open Preferences for the Rectangle tool" +msgstr "Відкрити вікно параметрів Inkscape для інструмента \"Прямокутник\"" + +#: ../../po/../src/verbs.cpp:2087 +msgid "Ellipse Preferences" +msgstr "Параметри еліпса" + +#: ../../po/../src/verbs.cpp:2088 +#, fuzzy +msgid "Open Preferences for the Ellipse tool" +msgstr "Відкрити вікно параметрів Inkscape для інструмента \"Еліпс\"" + +#: ../../po/../src/verbs.cpp:2089 +msgid "Star Preferences" +msgstr "Властивості зірки" + +#: ../../po/../src/verbs.cpp:2090 +#, fuzzy +msgid "Open Preferences for the Star tool" +msgstr "Відкрити вікно параметрів Inkscape для інструмента \"Зірка\"" + +#: ../../po/../src/verbs.cpp:2091 +msgid "Spiral Preferences" +msgstr "Властивості спіралі" + +#: ../../po/../src/verbs.cpp:2092 +#, fuzzy +msgid "Open Preferences for the Spiral tool" +msgstr "Відкрити вікно параметрів Inkscape для інструмента \"Спіраль\"" + +#: ../../po/../src/verbs.cpp:2093 +msgid "Pencil Preferences" +msgstr "Параметри олівця" + +#: ../../po/../src/verbs.cpp:2094 +#, fuzzy +msgid "Open Preferences for the Pencil tool" +msgstr "Відкрити вікно параметрів Inkscape для інструмента \"Олівець\"" + +#: ../../po/../src/verbs.cpp:2095 +msgid "Pen Preferences" +msgstr "Параметри пера" + +#: ../../po/../src/verbs.cpp:2096 +#, fuzzy +msgid "Open Preferences for the Pen tool" +msgstr "Відкрити вікно параметрів Inkscape для інструмента \"Перо\"" + +#: ../../po/../src/verbs.cpp:2097 +msgid "Calligraphic Preferences" +msgstr "Параметри каліграфічного пера" + +#: ../../po/../src/verbs.cpp:2098 +#, fuzzy +msgid "Open Preferences for the Calligraphy tool" +msgstr "" +"Відкрити вікно параметрів Inkscape для інструмента \"Каліграфічне перо\"" + +#: ../../po/../src/verbs.cpp:2099 +msgid "Text Preferences" +msgstr "Параметри тексту" + +#: ../../po/../src/verbs.cpp:2100 +#, fuzzy +msgid "Open Preferences for the Text tool" +msgstr "Відкрити вікно параметрів Inkscape для інструмента \"Текст\"" + +#: ../../po/../src/verbs.cpp:2101 +msgid "Gradient Preferences" +msgstr "Параметри градієнту" + +#: ../../po/../src/verbs.cpp:2102 +#, fuzzy +msgid "Open Preferences for the Gradient tool" +msgstr "Відкрити вікно параметрів Inkscape для інструмента \"Градієнт\"" + +#: ../../po/../src/verbs.cpp:2103 +msgid "Zoom Preferences" +msgstr "Параметри масштабу" + +#: ../../po/../src/verbs.cpp:2104 +#, fuzzy +msgid "Open Preferences for the Zoom tool" +msgstr "Відкрити вікно параметрів Inkscape для інструмента \"Масштаб\"" + +#: ../../po/../src/verbs.cpp:2105 +msgid "Dropper Preferences" +msgstr "Параметри піпетки" + +#: ../../po/../src/verbs.cpp:2106 +#, fuzzy +msgid "Open Preferences for the Dropper tool" +msgstr "Відкрити вікно параметрів Inkscape для інструмента \"Піпетка\"" + +#: ../../po/../src/verbs.cpp:2107 +msgid "Connector Preferences" +msgstr "Параметри лінії з'єднання" + +#: ../../po/../src/verbs.cpp:2108 +#, fuzzy +msgid "Open Preferences for the Connector tool" +msgstr "Відкрити вікно параметрів лінії з'єднання" + +#. Zoom/View +#: ../../po/../src/verbs.cpp:2111 +msgid "Zoom In" +msgstr "Збільшити" + +#: ../../po/../src/verbs.cpp:2111 +msgid "Zoom in" +msgstr "Збільшити" + +#: ../../po/../src/verbs.cpp:2112 +msgid "Zoom Out" +msgstr "Зменшити" + +#: ../../po/../src/verbs.cpp:2112 +msgid "Zoom out" +msgstr "Зменшити" + +#: ../../po/../src/verbs.cpp:2113 +msgid "_Rulers" +msgstr "_Лінійки" + +#: ../../po/../src/verbs.cpp:2113 +msgid "Show or hide the canvas rulers" +msgstr "Показати або сховати лінійки полотна" + +#: ../../po/../src/verbs.cpp:2114 +msgid "Scroll_bars" +msgstr "_Смуги прокрутки" + +#: ../../po/../src/verbs.cpp:2114 +msgid "Show or hide the canvas scrollbars" +msgstr "Показати/сховати смуги прокрутки полотна" + +#: ../../po/../src/verbs.cpp:2115 +msgid "_Grid" +msgstr "С_ітка" + +#: ../../po/../src/verbs.cpp:2116 +msgid "G_uides" +msgstr "Нап_рямні" + +#: ../../po/../src/verbs.cpp:2117 +msgid "Nex_t Zoom" +msgstr "Н_аступний масштаб" + +#: ../../po/../src/verbs.cpp:2117 +msgid "Next zoom (from the history of zooms)" +msgstr "Наступний масштаб (з історії масштабування)" + +#: ../../po/../src/verbs.cpp:2119 +msgid "Pre_vious Zoom" +msgstr "П_опередній масштаб" + +#: ../../po/../src/verbs.cpp:2119 +msgid "Previous zoom (from the history of zooms)" +msgstr "Попередній масштаб (з історії масштабування)" + +#: ../../po/../src/verbs.cpp:2121 +msgid "Zoom 1:_1" +msgstr "Масштаб 1:_1" + +#: ../../po/../src/verbs.cpp:2121 +msgid "Zoom to 1:1" +msgstr "Масштаб 1:1" + +#: ../../po/../src/verbs.cpp:2123 +msgid "Zoom 1:_2" +msgstr "Масштаб 1:_2" + +#: ../../po/../src/verbs.cpp:2123 +msgid "Zoom to 1:2" +msgstr "Масштаб 1:2" + +#: ../../po/../src/verbs.cpp:2125 +msgid "_Zoom 2:1" +msgstr "Мас_штаб 2:1" + +#: ../../po/../src/verbs.cpp:2125 +msgid "Zoom to 2:1" +msgstr "Масштаб 2:1" + +#: ../../po/../src/verbs.cpp:2128 +msgid "_Fullscreen" +msgstr "На весь _екран" + +#: ../../po/../src/verbs.cpp:2128 +msgid "Stretch this document window to full screen" +msgstr "Розтягнути вікно документа на весь екран" + +#: ../../po/../src/verbs.cpp:2131 +msgid "Duplic_ate Window" +msgstr "_Дублювати вікно" + +#: ../../po/../src/verbs.cpp:2131 +msgid "Open a new window with the same document" +msgstr "Відкрити нове вікно з цим самим документом" + +#: ../../po/../src/verbs.cpp:2133 +msgid "_New View Preview" +msgstr "_Створити попередній перегляд" + +#: ../../po/../src/verbs.cpp:2134 +msgid "New View Preview" +msgstr "Створити нове вікно попереднього перегляду" + +#. "view_new_preview" +#: ../../po/../src/verbs.cpp:2136 +#, fuzzy +msgid "_Normal" +msgstr "звичайно" + +#: ../../po/../src/verbs.cpp:2137 +msgid "Switch to normal display mode" +msgstr "" + +#: ../../po/../src/verbs.cpp:2138 +#, fuzzy +msgid "_Outline" +msgstr "Рамку" + +#: ../../po/../src/verbs.cpp:2139 +msgid "Switch to outline (wireframe) display mode" +msgstr "" + +#: ../../po/../src/verbs.cpp:2141 +msgid "Ico_n Preview" +msgstr "Переглянути як _значок" + +#: ../../po/../src/verbs.cpp:2142 +msgid "Open a window to preview items at different icon resolutions" +msgstr "Переглянути виділений елемент як значок різних розмірів" + +#: ../../po/../src/verbs.cpp:2144 +msgid "Zoom to fit page in window" +msgstr "Змінити масштаб, щоб умістити сторінку цілком" + +#: ../../po/../src/verbs.cpp:2145 +msgid "Page _Width" +msgstr "Ш_ирина сторінки" + +#: ../../po/../src/verbs.cpp:2146 +msgid "Zoom to fit page width in window" +msgstr "Змінити масштаб, щоб умістити сторінку по ширині" + +#: ../../po/../src/verbs.cpp:2148 +msgid "Zoom to fit drawing in window" +msgstr "Змінити масштаб, щоб умістити малюнок цілком" + +#: ../../po/../src/verbs.cpp:2150 +msgid "Zoom to fit selection in window" +msgstr "Змінити масштаб, щоб умістити виділену область" + +#. Dialogs +#: ../../po/../src/verbs.cpp:2153 +msgid "In_kscape Preferences..." +msgstr "П_араметри Inkscape..." + +#: ../../po/../src/verbs.cpp:2154 +msgid "Global Inkscape preferences" +msgstr "Загальні параметри Inkscape" + +#: ../../po/../src/verbs.cpp:2155 +msgid "_Document Preferences..." +msgstr "Параметри д_окумента..." + +#: ../../po/../src/verbs.cpp:2156 +msgid "Preferences saved with the document" +msgstr "Параметри, що зберігаються разом з документом" + +#: ../../po/../src/verbs.cpp:2157 +msgid "_Fill and Stroke..." +msgstr "_Заповнення та штрих" + +#: ../../po/../src/verbs.cpp:2158 +msgid "Fill and Stroke dialog" +msgstr "Вікно заповнення та штриха" + +#. TRANSLATORS: "Swatches" means: color samples +#: ../../po/../src/verbs.cpp:2160 +msgid "S_watches..." +msgstr "Зразки _кольорів..." + +#: ../../po/../src/verbs.cpp:2161 +msgid "View color swatches" +msgstr "Переглянути зразки кольорів" + +#: ../../po/../src/verbs.cpp:2162 +msgid "Transfor_m..." +msgstr "_Трансформувати..." + +#: ../../po/../src/verbs.cpp:2163 +msgid "Transform dialog" +msgstr "Вікно трансформації" + +#: ../../po/../src/verbs.cpp:2164 +msgid "_Align and Distribute..." +msgstr "Ви_рівняти та розподілити..." + +#: ../../po/../src/verbs.cpp:2165 +msgid "Align and Distribute dialog" +msgstr "Вікно вирівнювання" + +#: ../../po/../src/verbs.cpp:2166 +msgid "_Text and Font..." +msgstr "_Текст і шрифт..." + +#: ../../po/../src/verbs.cpp:2167 +msgid "Text and Font dialog" +msgstr "Вікно тексту та вибору шрифту" + +#: ../../po/../src/verbs.cpp:2168 +msgid "_XML Editor..." +msgstr "Редактор _XML..." + +#: ../../po/../src/verbs.cpp:2169 +msgid "XML Editor" +msgstr "Редактор XML" + +#: ../../po/../src/verbs.cpp:2170 +msgid "_Find..." +msgstr "З_найти..." + +#: ../../po/../src/verbs.cpp:2171 +msgid "Find objects in document" +msgstr "Знайти об'єкти у документі" + +#: ../../po/../src/verbs.cpp:2172 +msgid "_Messages..." +msgstr "По_відомлення..." + +#: ../../po/../src/verbs.cpp:2173 +msgid "View debug messages" +msgstr "Переглянути налагоджувальні повідомлення" + +#: ../../po/../src/verbs.cpp:2174 +msgid "S_cripts..." +msgstr "С_ценарії..." + +#: ../../po/../src/verbs.cpp:2175 +msgid "Run scripts" +msgstr "Запустити сценарії" + +#: ../../po/../src/verbs.cpp:2176 +msgid "Show/Hide D_ialogs" +msgstr "Показати/сховати діало_ги" + +#: ../../po/../src/verbs.cpp:2177 +msgid "Show or hide all active dialogs" +msgstr "Показати чи сховати активні діалогові вікна" + +#. TRANSLATORS: "Tile clones" means: "Create tiled clones" +#: ../../po/../src/verbs.cpp:2179 +msgid "Tile clones..." +msgstr "Створити мозаїку з клонів" + +#: ../../po/../src/verbs.cpp:2180 +msgid "Create and arrange multiple clones of selection" +msgstr "Створити та впорядкувати кілька клонів з виділеного" + +#: ../../po/../src/verbs.cpp:2181 +msgid "_Object Properties..." +msgstr "В_ластивості об'єкта..." + +#: ../../po/../src/verbs.cpp:2182 +msgid "Object Properties dialog" +msgstr "Вікно властивостей об'єкта" + +#: ../../po/../src/verbs.cpp:2185 +msgid "_Connect to Jabber server..." +msgstr "_З'єднатись с сервером Jabber..." + +#: ../../po/../src/verbs.cpp:2185 +msgid "Connect to a Jabber server" +msgstr "З'єднання з сервером Jabber" + +#: ../../po/../src/verbs.cpp:2187 +msgid "Share with _user..." +msgstr "Спільно з _користувачем..." + +#: ../../po/../src/verbs.cpp:2187 +msgid "Establish a whiteboard session with another Jabber user" +msgstr "Розпочати сеанс спільного малювання з іншим користувачем Jabber" + +#: ../../po/../src/verbs.cpp:2189 +msgid "Share with _chatroom..." +msgstr "Спільно з усією к_імнатою..." + +#: ../../po/../src/verbs.cpp:2189 +msgid "" +"Join a chatroom to start a new whiteboard session or join one in progress" +msgstr "" +"Зайти у кімнату для початку нового сеансу спільного малювання або приєднання " +"до поточного сеансу" + +#: ../../po/../src/verbs.cpp:2191 +msgid "_Dump XML node tracker" +msgstr "_Дамп вузлів XML" + +#: ../../po/../src/verbs.cpp:2191 +msgid "Dump the contents of the XML tracker to the console" +msgstr "Дамп вмісту аналізатора XML на консоль" + +#: ../../po/../src/verbs.cpp:2193 +msgid "_Open session file..." +msgstr "_Відкрити файл сеансу..." + +#: ../../po/../src/verbs.cpp:2193 +msgid "Open and browse through records of past whiteboard sessions" +msgstr "Відкрити та переглянути записи попередніх сеансів малювання" + +#: ../../po/../src/verbs.cpp:2195 +msgid "Session file playback" +msgstr "Відтворення файлу сеансу" + +#: ../../po/../src/verbs.cpp:2197 +msgid "_Disconnect from session" +msgstr "_Від'єднатись від сеансу" + +#: ../../po/../src/verbs.cpp:2199 +msgid "Disconnect from _server" +msgstr "Від'єднатись від _сервера" + +#: ../../po/../src/verbs.cpp:2201 +msgid "_Input Devices..." +msgstr "_пристрої вводу..." + +#: ../../po/../src/verbs.cpp:2202 +msgid "Configure extended input devices" +msgstr "Налаштовування розширених пристроїв вводу" + +#. Help +#: ../../po/../src/verbs.cpp:2205 +msgid "_Keys and Mouse" +msgstr "_Клавіатура та миша" + +#: ../../po/../src/verbs.cpp:2206 +msgid "Key and mouse shortcuts reference" +msgstr "Довідка з використання клавіатури та миші" + +#: ../../po/../src/verbs.cpp:2207 +msgid "About E_xtensions" +msgstr "Про _розширення" + +#: ../../po/../src/verbs.cpp:2208 +msgid "About Extensions..." +msgstr "Про розширення..." + +#: ../../po/../src/verbs.cpp:2209 +msgid "About _Memory" +msgstr "Про п_ам'ять" + +#: ../../po/../src/verbs.cpp:2210 +msgid "About Memory..." +msgstr "Про пам'ять" + +#: ../../po/../src/verbs.cpp:2211 +msgid "_About Inkscape" +msgstr "_Про програму Inkscape" + +#. "help_about" +#. new HelpVerb(SP_VERB_SHOW_LICENSE, "ShowLicense", N_("Modifying or Redistributing Inkscape"), +#. N_("Show license to modify and/or redistribute Inkscape: GNU GPL"), NULL), +#. Tutorials +#: ../../po/../src/verbs.cpp:2217 +msgid "Inkscape: _Basic" +msgstr "Inkscape: _Початковий рівень" + +#: ../../po/../src/verbs.cpp:2218 +msgid "Getting started with Inkscape" +msgstr "Починаємо роботу з Inkscape" + +#. "tutorial_basic" +#: ../../po/../src/verbs.cpp:2219 +msgid "Inkscape: _Shapes" +msgstr "Inkscape: _Фігури" + +#: ../../po/../src/verbs.cpp:2220 +msgid "Using shape tools to create and edit shapes" +msgstr "Використання інструментів малювання та редагування фігур" + +#: ../../po/../src/verbs.cpp:2221 +msgid "Inkscape: _Advanced" +msgstr "Inkscape: _Другий рівень" + +#: ../../po/../src/verbs.cpp:2222 +msgid "Advanced Inkscape topics" +msgstr "Додаткові теми з Inkscape" + +#. "tutorial_advanced" +#. TRANSLATORS: "to trace" means "to convert a bitmap to vector graphics" (to vectorize) +#: ../../po/../src/verbs.cpp:2224 +msgid "Inkscape: T_racing" +msgstr "Inkscape: _Векторизація" + +#: ../../po/../src/verbs.cpp:2225 +msgid "Using bitmap tracing" +msgstr "Використання векторизації растру" + +#. "tutorial_tracing" +#: ../../po/../src/verbs.cpp:2226 +msgid "Inkscape: _Calligraphy" +msgstr "Inkscape: _Каліграфія" + +#: ../../po/../src/verbs.cpp:2227 +msgid "Using the Calligraphy pen tool" +msgstr "Використання каліграфічного пера" + +#: ../../po/../src/verbs.cpp:2228 +msgid "_Elements of Design" +msgstr "_Елементи дизайну" + +#: ../../po/../src/verbs.cpp:2229 +msgid "Principles of design in the tutorial form" +msgstr "Підручник з принципів дизайну" + +#. "tutorial_design" +#: ../../po/../src/verbs.cpp:2230 +msgid "_Tips and Tricks" +msgstr "_Поради та прийоми" + +#: ../../po/../src/verbs.cpp:2231 +msgid "Miscellaneous tips and tricks" +msgstr "Різноманітні поради та прийоми" + +#. "tutorial_tips" +#. Effect +#: ../../po/../src/verbs.cpp:2234 +msgid "Previous Effect" +msgstr "Попередній ефект" + +#: ../../po/../src/verbs.cpp:2235 +msgid "Repeat the last effect with the same settings" +msgstr "Повторити останній ефект з тими самими параметрами" + +#. "tutorial_tips" +#: ../../po/../src/verbs.cpp:2236 +msgid "Previous Effect Settings..." +msgstr "Повторити з налаштовуванням..." + +#: ../../po/../src/verbs.cpp:2237 +msgid "Repeat the last effect with new settings" +msgstr "Повторити останній ефект з новими параметрами" + +#: ../../po/../src/widgets/dash-selector.cpp:106 +msgid "Dash pattern" +msgstr "Пунктир" + +#: ../../po/../src/widgets/dash-selector.cpp:121 +msgid "Pattern offset" +msgstr "Зміщення пунктиру" + +#: ../../po/../src/widgets/desktop-widget.cpp:240 +msgid "Zoom drawing if window size changes" +msgstr "Змінювати масштаб при зміні розмірів вікна" + +#: ../../po/../src/widgets/desktop-widget.cpp:298 +msgid "Cursor coordinates" +msgstr "Координати курсору" + +#. display the initial welcome message in the statusbar +#: ../../po/../src/widgets/desktop-widget.cpp:324 +msgid "" +"Welcome to Inkscape! Use shape or freehand tools to create objects; " +"use selector (arrow) to move or transform them." +msgstr "" +"Ласкаво просимо до Inkscape! Використовуйте інструменти фігур чи " +"малювання для створення об'єктів; для їх переміщенням чи трансформації " +"використовуйте селектор (стрілку)." + +#: ../../po/../src/widgets/desktop-widget.cpp:372 +#, c-format +msgid "%s: %d - Inkscape" +msgstr "%s: %d - Inkscape" + +#: ../../po/../src/widgets/desktop-widget.cpp:374 +#, c-format +msgid "%s - Inkscape" +msgstr "%s - Inkscape" + +#: ../../po/../src/widgets/desktop-widget.cpp:532 +#, c-format +msgid "" +"Save changes to document \"%s\" before " +"closing?\n" +"\n" +"If you close without saving, your changes will be discarded." +msgstr "" +"Зберегти перед закриванням зміни у " +"документі \"%s\"?\n" +"\n" +"Якщо ви закриєте документ без збереження, усі зміни будуть втрачені." + +#: ../../po/../src/widgets/desktop-widget.cpp:548 +#: ../../po/../src/widgets/desktop-widget.cpp:612 +msgid "Close _without saving" +msgstr "_Не зберігати" + +#: ../../po/../src/widgets/desktop-widget.cpp:595 +#, c-format +msgid "" +"The file \"%s\" was saved with a " +"format (%s) that may cause data loss!\n" +"\n" +"Do you want to save this file in another format?" +msgstr "" +"Файл \"%s\" збережено у форматі (%s), " +"який може призвести до часткової втрати даних!\n" +"\n" +"Зберегти документ у іншому форматі?" + +#. Family frame +#: ../../po/../src/widgets/font-selector.cpp:156 +msgid "Font family" +msgstr "Шрифт" + +#. Style frame +#: ../../po/../src/widgets/font-selector.cpp:184 +msgid "Style" +msgstr "Стиль" + +#: ../../po/../src/widgets/font-selector.cpp:219 +msgid "Font size:" +msgstr "Розмір :" + +#. TRANSLATORS: Test string used in text and font dialog (when no +#. * text has been entered) to get a preview of the font. Choose +#. * some representative characters that users of your locale will be +#. * interested in. +#: ../../po/../src/widgets/font-selector.cpp:554 +msgid "AaBbCcIiPpQq12368.;/()" +msgstr "АаБбВвЇїЄєҐґIiPpQq12368.;/()" + +#: ../../po/../src/widgets/gradient-selector.cpp:137 +#: ../../po/../src/widgets/gradient-toolbar.cpp:524 +msgid "Duplicate" +msgstr "Дублювати" + +#: ../../po/../src/widgets/gradient-selector.cpp:142 +#: ../../po/../src/widgets/gradient-toolbar.cpp:535 +msgid "Edit..." +msgstr "Редагування..." + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/pservers.html#LinearGradientSpreadMethodAttribute +#: ../../po/../src/widgets/gradient-selector.cpp:159 +msgid "" +"Whether to fill with flat color beyond the ends of the gradient vector " +"(spreadMethod=\"pad\"), or repeat the gradient in the same direction " +"(spreadMethod=\"repeat\"), or repeat the gradient in alternating opposite " +"directions (spreadMethod=\"reflect\")" +msgstr "" +"За межами вектору градієнту: заповнювати суцільним кольором (spreadMethod=" +"\"pad\"), чи повторювати початковий градієнт (spreadMethod=\"repeat\"), " +"повторювати відбитий градієнт (spreadMethod=\"reflect\")" + +#: ../../po/../src/widgets/gradient-selector.cpp:165 +msgid "none" +msgstr "немає" + +#: ../../po/../src/widgets/gradient-selector.cpp:169 +msgid "reflected" +msgstr "відбитий" + +#: ../../po/../src/widgets/gradient-selector.cpp:173 +msgid "direct" +msgstr "повтор" + +#: ../../po/../src/widgets/gradient-selector.cpp:181 +msgid "Repeat:" +msgstr "Повтор:" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:217 +msgid "No gradients" +msgstr "Без градієнтів" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:226 +msgid "Nothing selected" +msgstr "Нічого не виділено" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:237 +msgid "No gradients in selection" +msgstr "Не вибрано жодного градієнта" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:247 +msgid "Multiple gradients" +msgstr "Декілька градієнтів" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:525 +msgid "" +"If the gradient is used by more than one object, create a copy of it for the " +"selected object(s)" +msgstr "" +"Якщо градієнт використовується більше ніж для одного об'єкту, створити його " +"копію для виділеного об'єкту(ів)" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:536 +msgid "Edit the stops of the gradient" +msgstr "Змінити опорні точки градієнту" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:593 +#: ../../po/../src/widgets/toolbox.cpp:1103 +#: ../../po/../src/widgets/toolbox.cpp:1192 +#: ../../po/../src/widgets/toolbox.cpp:1485 +#: ../../po/../src/widgets/toolbox.cpp:1534 +#: ../../po/../src/widgets/toolbox.cpp:1766 +#: ../../po/../src/widgets/toolbox.cpp:1801 +#: ../../po/../src/widgets/toolbox.cpp:2331 +#: ../../po/../src/widgets/toolbox.cpp:2370 +msgid "New:" +msgstr "Новий:" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:606 +msgid "Create linear gradient" +msgstr "Створити лінійний градієнт" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:620 +msgid "Create radial (elliptic or circular) gradient" +msgstr "Створити радіальний (еліптичний чи круговий) градієнт" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:635 +msgid "on" +msgstr "на" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:648 +msgid "Create gradient in the fill" +msgstr "Створити градієнт у заповненні" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:662 +msgid "Create gradient in the stroke" +msgstr "Створити градієнт у штриху" + +#. FIXME: implement averaging of all parameters for multiple selected stars +#. gtk_label_set_markup(GTK_LABEL(l), _("Average:")); +#. FIXME: implement averaging of all parameters for multiple selected +#. gtk_label_set_markup(GTK_LABEL(l), _("Average:")); +#: ../../po/../src/widgets/gradient-toolbar.cpp:676 +#: ../../po/../src/widgets/toolbox.cpp:1105 +#: ../../po/../src/widgets/toolbox.cpp:1124 +#: ../../po/../src/widgets/toolbox.cpp:1493 +#: ../../po/../src/widgets/toolbox.cpp:1518 +#: ../../po/../src/widgets/toolbox.cpp:1768 +#: ../../po/../src/widgets/toolbox.cpp:1787 +#: ../../po/../src/widgets/toolbox.cpp:2334 +#: ../../po/../src/widgets/toolbox.cpp:2354 +msgid "Change:" +msgstr "Змінити:" + +#: ../../po/../src/widgets/gradient-vector.cpp:269 +msgid "No gradients in document" +msgstr "Документ не містить градієнтів" + +#: ../../po/../src/widgets/gradient-vector.cpp:275 +msgid "No gradient selected" +msgstr "Не вибрано жодного градієнта" + +#: ../../po/../src/widgets/gradient-vector.cpp:532 +msgid "No stops in gradient" +msgstr "У градієнті немає опорних точок" + +#. TRANSLATORS: "Stop" means: a "phase" of a gradient +#: ../../po/../src/widgets/gradient-vector.cpp:794 +msgid "Add stop" +msgstr "Додати опорну точку" + +#: ../../po/../src/widgets/gradient-vector.cpp:797 +msgid "Add another control stop to gradient" +msgstr "Додати ще одну опорну точку у градієнт" + +#: ../../po/../src/widgets/gradient-vector.cpp:799 +msgid "Delete stop" +msgstr "Видалити опорну точку" + +#: ../../po/../src/widgets/gradient-vector.cpp:802 +msgid "Delete current control stop from gradient" +msgstr "Видалити опорну точку градієнта" + +#. Label +#: ../../po/../src/widgets/gradient-vector.cpp:813 +msgid "Offset:" +msgstr "Зсув:" + +#. TRANSLATORS: "Stop" means: a "phase" of a gradient +#: ../../po/../src/widgets/gradient-vector.cpp:858 +msgid "Stop Color" +msgstr "Колір опорної точки" + +#: ../../po/../src/widgets/gradient-vector.cpp:887 +msgid "Gradient editor" +msgstr "Редактор градієнтів" + +#: ../../po/../src/widgets/layer-selector.cpp:119 +msgid "Toggle current layer visibility" +msgstr "Сховати чи відкрити поточний шар" + +#: ../../po/../src/widgets/layer-selector.cpp:139 +msgid "Lock or unlock current layer" +msgstr "Замкнути чи розімкнути поточний шар" + +#: ../../po/../src/widgets/layer-selector.cpp:142 +msgid "Current layer" +msgstr "Поточний шар" + +#: ../../po/../src/widgets/layer-selector.cpp:553 +msgid "(root)" +msgstr "(корінь)" + +#: ../../po/../src/widgets/paint-selector.cpp:182 +#: ../../po/../src/widgets/paint-selector.cpp:561 +msgid "No paint" +msgstr "Немає заповнення" + +#: ../../po/../src/widgets/paint-selector.cpp:184 +#: ../../po/../src/widgets/paint-selector.cpp:629 +msgid "Flat color" +msgstr "Суцільний колір" + +#: ../../po/../src/widgets/paint-selector.cpp:186 +#: ../../po/../src/widgets/paint-selector.cpp:696 +msgid "Linear gradient" +msgstr "Лінійний градієнт" + +#: ../../po/../src/widgets/paint-selector.cpp:188 +#: ../../po/../src/widgets/paint-selector.cpp:699 +msgid "Radial gradient" +msgstr "Радіальний градієнт" + +#: ../../po/../src/widgets/paint-selector.cpp:192 +msgid "Unset paint (make it undefined so it can be inherited)" +msgstr "" +"Прибрати заповнення (зробити його невизначеним, щоб воно могло " +"успадковуватись)" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/painting.html#FillRuleProperty +#: ../../po/../src/widgets/paint-selector.cpp:204 +msgid "" +"Any path self-intersections or subpaths create holes in the fill (fill-rule: " +"evenodd)" +msgstr "" +"Будь-які самоперетини або внутрішні субконтури утворюють дірки у заповненні " +"(fill-rule: evenodd)" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/painting.html#FillRuleProperty +#: ../../po/../src/widgets/paint-selector.cpp:215 +msgid "" +"Fill is solid unless a subpath is counterdirectional (fill-rule: nonzero)" +msgstr "" +"Заповнення має дірку, лише якщо внутрішній субконтур направлений у " +"протилежному напрямку відносно зовнішнього (fill-rule: nonzero)" + +#: ../../po/../src/widgets/paint-selector.cpp:528 +msgid "No objects" +msgstr "Немає об'єктів" + +#: ../../po/../src/widgets/paint-selector.cpp:539 +msgid "Multiple styles" +msgstr "Множинні стилі" + +#: ../../po/../src/widgets/paint-selector.cpp:550 +msgid "Paint is undefined" +msgstr "Заповнення не визначено" + +#: ../../po/../src/widgets/paint-selector.cpp:757 +msgid "No patterns in document" +msgstr "У документі немає візерунків" + +#: ../../po/../src/widgets/paint-selector.cpp:872 +msgid "" +"Use Edit > Object(s) to Pattern to create a new pattern from " +"selection." +msgstr "" +"Використовуйте Правка > Об'єкти у візерунок, щоб створити новий " +"візерунок з виділення." + +#: ../../po/../src/widgets/select-toolbar.cpp:426 +msgid "Now stroke width is scaled when objects are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:428 +msgid "Now stroke width is not scaled when objects are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:436 +msgid "" +"Now rounded rectangle corners are scaled when rectangles are " +"scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:438 +msgid "" +"Now rounded rectangle corners are not scaled when rectangles " +"are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:446 +msgid "" +"Now gradients are transformed along with their objects when " +"those are transformed (moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:448 +msgid "" +"Now gradients remain fixed when objects are transformed " +"(moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:456 +msgid "" +"Now patterns are transformed along with their objects when " +"those are transformed (moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:458 +msgid "" +"Now patterns remain fixed when objects are transformed (moved, " +"scaled, rotated, or skewed)." +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:506 +msgid "select_toolbar|X" +msgstr "select_toolbar|X" + +#: ../../po/../src/widgets/select-toolbar.cpp:506 +msgid "Horizontal coordinate of selection" +msgstr "Горизонтальна координата виділення" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:511 +msgid "select_toolbar|Y" +msgstr "select_toolbar|Y" + +#: ../../po/../src/widgets/select-toolbar.cpp:511 +msgid "Vertical coordinate of selection" +msgstr "Вертикальна координата виділення" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:517 +msgid "select_toolbar|W" +msgstr "select_toolbar|W" + +#: ../../po/../src/widgets/select-toolbar.cpp:517 +msgid "Width of selection" +msgstr "Ширина виділення" + +#: ../../po/../src/widgets/select-toolbar.cpp:525 +msgid "Change both width and height by the same proportion" +msgstr "Пропорційно змінювати ширину та висоту" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:534 +msgid "select_toolbar|H" +msgstr "select_toolbar|H" + +#: ../../po/../src/widgets/select-toolbar.cpp:534 +msgid "Height of selection" +msgstr "Висота виділення" + +#: ../../po/../src/widgets/sp-color-gtkselector.cpp:62 +msgid "System" +msgstr "Системний" + +#: ../../po/../src/widgets/sp-color-notebook.cpp:322 +msgid "RGBA_:" +msgstr "RGBA_:" + +#: ../../po/../src/widgets/sp-color-notebook.cpp:330 +msgid "Hexadecimal RGBA value of the color" +msgstr "Шістнадцяткове значення кольору RGBA" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "RGB" +msgstr "RGB" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "HSL" +msgstr "HSL" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "CMYK" +msgstr "CMYK" + +#: ../../po/../src/widgets/sp-color-scales.cpp:397 +msgid "_R" +msgstr "_R" + +#: ../../po/../src/widgets/sp-color-scales.cpp:398 +#: ../../po/../src/widgets/sp-color-scales.cpp:399 +msgid "Red" +msgstr "Червоний" + +#: ../../po/../src/widgets/sp-color-scales.cpp:400 +msgid "_G" +msgstr "_G" + +#: ../../po/../src/widgets/sp-color-scales.cpp:401 +#: ../../po/../src/widgets/sp-color-scales.cpp:402 +msgid "Green" +msgstr "Зелений" + +#: ../../po/../src/widgets/sp-color-scales.cpp:403 +msgid "_B" +msgstr "_B" + +#: ../../po/../src/widgets/sp-color-scales.cpp:404 +#: ../../po/../src/widgets/sp-color-scales.cpp:405 +msgid "Blue" +msgstr "Синій" + +#. Label +#: ../../po/../src/widgets/sp-color-scales.cpp:406 +#: ../../po/../src/widgets/sp-color-scales.cpp:432 +#: ../../po/../src/widgets/sp-color-scales.cpp:463 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:141 +msgid "_A" +msgstr "_A" + +#: ../../po/../src/widgets/sp-color-scales.cpp:407 +#: ../../po/../src/widgets/sp-color-scales.cpp:408 +#: ../../po/../src/widgets/sp-color-scales.cpp:433 +#: ../../po/../src/widgets/sp-color-scales.cpp:434 +#: ../../po/../src/widgets/sp-color-scales.cpp:464 +#: ../../po/../src/widgets/sp-color-scales.cpp:465 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:151 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:163 +msgid "Alpha (opacity)" +msgstr "Альфа-канал (прозорість)" + +#: ../../po/../src/widgets/sp-color-scales.cpp:423 +msgid "_H" +msgstr "_H" + +#: ../../po/../src/widgets/sp-color-scales.cpp:424 +#: ../../po/../src/widgets/sp-color-scales.cpp:425 +msgid "Hue" +msgstr "Відтінок" + +#: ../../po/../src/widgets/sp-color-scales.cpp:426 +msgid "_S" +msgstr "_S" + +#: ../../po/../src/widgets/sp-color-scales.cpp:427 +#: ../../po/../src/widgets/sp-color-scales.cpp:428 +msgid "Saturation" +msgstr "Насиченість" + +#: ../../po/../src/widgets/sp-color-scales.cpp:429 +msgid "_L" +msgstr "_L" + +#: ../../po/../src/widgets/sp-color-scales.cpp:430 +#: ../../po/../src/widgets/sp-color-scales.cpp:431 +msgid "Lightness" +msgstr "Яскравість" + +#: ../../po/../src/widgets/sp-color-scales.cpp:451 +msgid "_C" +msgstr "_C" + +#: ../../po/../src/widgets/sp-color-scales.cpp:452 +#: ../../po/../src/widgets/sp-color-scales.cpp:453 +msgid "Cyan" +msgstr "Бірюзовий" + +#: ../../po/../src/widgets/sp-color-scales.cpp:454 +msgid "_M" +msgstr "_M" + +#: ../../po/../src/widgets/sp-color-scales.cpp:455 +#: ../../po/../src/widgets/sp-color-scales.cpp:456 +msgid "Magenta" +msgstr "Бузковий" + +#: ../../po/../src/widgets/sp-color-scales.cpp:457 +msgid "_Y" +msgstr "_Y" + +#: ../../po/../src/widgets/sp-color-scales.cpp:458 +#: ../../po/../src/widgets/sp-color-scales.cpp:459 +msgid "Yellow" +msgstr "Жовтий" + +#: ../../po/../src/widgets/sp-color-scales.cpp:460 +msgid "_K" +msgstr "_K" + +#: ../../po/../src/widgets/sp-color-selector.cpp:71 +msgid "Unnamed" +msgstr "Без назви" + +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:68 +msgid "Wheel" +msgstr "Колесо" + +#: ../../po/../src/widgets/sp-xmlview-attr-list.cpp:53 +msgid "Attribute" +msgstr "Атрибут" + +#: ../../po/../src/widgets/sp-xmlview-attr-list.cpp:54 +msgid "Value" +msgstr "Значення" + +#: ../../po/../src/widgets/toolbox.cpp:424 +msgid "Insert new nodes into selected segments" +msgstr "Вставити нові вузли у виділені сектори" + +#: ../../po/../src/widgets/toolbox.cpp:426 +msgid "Delete selected nodes" +msgstr "Видалити виділені вузли" + +#: ../../po/../src/widgets/toolbox.cpp:431 +msgid "Join paths at selected nodes" +msgstr "З'єднати контури у виділених вузлах" + +#: ../../po/../src/widgets/toolbox.cpp:433 +msgid "Join paths at selected nodes with new segment" +msgstr "З'єднати контури у виділених вузлах новим сектором" + +#: ../../po/../src/widgets/toolbox.cpp:436 +msgid "Split path between two non-endpoint nodes" +msgstr "Розірвати контур між двома не кінцевими вузлами" + +#: ../../po/../src/widgets/toolbox.cpp:439 +msgid "Break path at selected nodes" +msgstr "Розірвати контур у виділеному вузлі" + +#: ../../po/../src/widgets/toolbox.cpp:444 +msgid "Make selected nodes corner" +msgstr "Зробити виділені вузли гострими" + +#: ../../po/../src/widgets/toolbox.cpp:447 +msgid "Make selected nodes smooth" +msgstr "Зробити виділені вузли гладкими" + +#: ../../po/../src/widgets/toolbox.cpp:450 +msgid "Make selected nodes symmetric" +msgstr "Зробити виділені вузли симетричними" + +#: ../../po/../src/widgets/toolbox.cpp:455 +msgid "Make selected segments lines" +msgstr "Зробити виділені сектори прямими" + +#: ../../po/../src/widgets/toolbox.cpp:458 +msgid "Make selected segments curves" +msgstr "Зробити виділені сектори кривими" + +#: ../../po/../src/widgets/toolbox.cpp:1199 +msgid "Polygon" +msgstr "Багатокутник" + +#: ../../po/../src/widgets/toolbox.cpp:1206 +msgid "Regular polygon (with one handle) instead of a star" +msgstr "Правильний багатокутник, а не зірка" + +#: ../../po/../src/widgets/toolbox.cpp:1218 +msgid "Corners:" +msgstr "Кути:" + +#: ../../po/../src/widgets/toolbox.cpp:1218 +msgid "Number of corners of a polygon or star" +msgstr "Кількість кутів багатокутника чи зірки" + +#: ../../po/../src/widgets/toolbox.cpp:1228 +msgid "Spoke ratio:" +msgstr "Відношення радіусів:" + +#. TRANSLATORS: Tip radius of a star is the distance from the center to the farthest handle. +#. Base radius is the same for the closest handle. +#: ../../po/../src/widgets/toolbox.cpp:1231 +msgid "Base radius to tip radius ratio" +msgstr "Відношення радіусів основи та вершини променя" + +#: ../../po/../src/widgets/toolbox.cpp:1246 +msgid "Rounded:" +msgstr "Округлений:" + +#: ../../po/../src/widgets/toolbox.cpp:1246 +msgid "How much rounded are the corners (0 for sharp)" +msgstr "Наскільки згладжені кути (0 - гострі)" + +#: ../../po/../src/widgets/toolbox.cpp:1256 +msgid "Randomized:" +msgstr "Викривлено:" + +#: ../../po/../src/widgets/toolbox.cpp:1256 +msgid "Scatter randomly the corners and angles" +msgstr "Випадковим чином перемістити кути та повернути радіуси" + +#: ../../po/../src/widgets/toolbox.cpp:1269 +#: ../../po/../src/widgets/toolbox.cpp:1838 +#: ../../po/../src/widgets/toolbox.cpp:2061 +msgid "Defaults" +msgstr "Типово" + +#: ../../po/../src/widgets/toolbox.cpp:1270 +#: ../../po/../src/widgets/toolbox.cpp:1839 +#: ../../po/../src/widgets/toolbox.cpp:2062 +msgid "" +"Reset shape parameters to defaults (use Inkscape Preferences > Tools to " +"change defaults)" +msgstr "" +"Скинути параметри фігури на типові (типові параметри змінюються у вікні " +"Параметри Inkscape->Інструменти)" + +#: ../../po/../src/widgets/toolbox.cpp:1544 +msgid "W:" +msgstr "Ш:" + +#: ../../po/../src/widgets/toolbox.cpp:1544 +msgid "Width of rectangle" +msgstr "Ширина прямокутника" + +#: ../../po/../src/widgets/toolbox.cpp:1556 +msgid "Height of rectangle" +msgstr "Висота прямокутника" + +#: ../../po/../src/widgets/toolbox.cpp:1568 +msgid "Rx:" +msgstr "Гор. радіус:" + +#: ../../po/../src/widgets/toolbox.cpp:1568 +msgid "Horizontal radius of rounded corners" +msgstr "Горизонтальний радіус округлених кутів" + +#: ../../po/../src/widgets/toolbox.cpp:1578 +msgid "Ry:" +msgstr "Верт. радіус:" + +#: ../../po/../src/widgets/toolbox.cpp:1578 +msgid "Vertical radius of rounded corners" +msgstr "Вертикальний радіус округлених кутів" + +#: ../../po/../src/widgets/toolbox.cpp:1594 +msgid "Not rounded" +msgstr "Не округлений" + +#: ../../po/../src/widgets/toolbox.cpp:1596 +msgid "Make corners sharp" +msgstr "Прибрати округлення кутів" + +#: ../../po/../src/widgets/toolbox.cpp:1805 +msgid "Turns:" +msgstr "Витків:" + +#: ../../po/../src/widgets/toolbox.cpp:1805 +msgid "Number of revolutions" +msgstr "Кількість витків" + +#: ../../po/../src/widgets/toolbox.cpp:1815 +msgid "Divergence:" +msgstr "Розходження:" + +#: ../../po/../src/widgets/toolbox.cpp:1815 +msgid "How much denser/sparser are outer revolutions; 1 = uniform" +msgstr "Ступінь збільшення/зменшення відстані між витками; 1 = рівномірно" + +#: ../../po/../src/widgets/toolbox.cpp:1825 +msgid "Inner radius:" +msgstr "Внутрішній радіус:" + +#: ../../po/../src/widgets/toolbox.cpp:1825 +msgid "Radius of the innermost revolution (relative to the spiral size)" +msgstr "Радіус першого внутрішнього витка (відносно розміру спіралі)" + +#: ../../po/../src/widgets/toolbox.cpp:1957 +msgid "The width of the calligraphic pen (relative to the visible canvas area)" +msgstr "Ширина каліграфічного пера (відносно видимої області полотна)" + +#: ../../po/../src/widgets/toolbox.cpp:1967 +msgid "Thinning:" +msgstr "Звуження:" + +#: ../../po/../src/widgets/toolbox.cpp:1967 +msgid "" +"How much velocity thins the stroke (> 0 makes fast strokes thinner, < 0 " +"makes them broader, 0 makes width independent of velocity)" +msgstr "" +"Наскільки сильно швидкість звужує штрих (> 0 швидкі штрихи вужче, < 0 швидкі " +"штрихи ширше, 0 - ширина штриха не залежить від швидкості)" + +#: ../../po/../src/widgets/toolbox.cpp:1980 +msgid "Angle:" +msgstr "Кут:" + +#: ../../po/../src/widgets/toolbox.cpp:1980 +msgid "" +"The angle of the pen's nib (in degrees; 0 = horizontal; has no effect if " +"fixation = 0)" +msgstr "" +"Кут пера (у градусах ; 0 = горизонтально; при нульовій фіксації не матиме " +"ефекту)" + +#: ../../po/../src/widgets/toolbox.cpp:1990 +msgid "Fixation:" +msgstr "Фіксація:" + +#: ../../po/../src/widgets/toolbox.cpp:1990 +msgid "" +"How fixed is the pen angle (0 = always perpendicular to stroke direction, 1 " +"= fixed)" +msgstr "" +"Ступінь фіксації кута (0 = завжди перпендикулярно штриху, 1 = кут не " +"змінюється)" + +#: ../../po/../src/widgets/toolbox.cpp:2003 +msgid "Mass:" +msgstr "Маса:" + +#: ../../po/../src/widgets/toolbox.cpp:2003 +msgid "How much inertia affects the movement of the pen" +msgstr "Як сильно інерція впливає на рух пера" + +#. TRANSLATORS: "drag" means "resistance" here +#: ../../po/../src/widgets/toolbox.cpp:2014 +msgid "Drag:" +msgstr "Гальмування:" + +#: ../../po/../src/widgets/toolbox.cpp:2014 +msgid "How much resistance affects the movement of the pen" +msgstr "Наскільки сильно опір паперу впливає на рух пера" + +#: ../../po/../src/widgets/toolbox.cpp:2034 +msgid "Use the pressure of the input device to alter the width of the pen" +msgstr "Використовувати силу натиску пристроєм вводу для зміни ширини лінії" + +#: ../../po/../src/widgets/toolbox.cpp:2047 +msgid "Use the tilt of the input device to alter the angle of the pen's nib" +msgstr "Використовувати нахил пристрою вводу для зміни кута" + +#: ../../po/../src/widgets/toolbox.cpp:2374 +msgid "Start:" +msgstr "Початок:" + +#: ../../po/../src/widgets/toolbox.cpp:2374 +msgid "The angle (in degrees) from the horizontal to the arc's start point" +msgstr "Кут (у градусах) від горизонталі до початкової точки дуги" + +#: ../../po/../src/widgets/toolbox.cpp:2384 +msgid "End:" +msgstr "Кінець:" + +#: ../../po/../src/widgets/toolbox.cpp:2384 +msgid "The angle (in degrees) from the horizontal to the arc's end point" +msgstr "Кут (у градусах) від горизонталі до кінцевої точки дуги" + +#: ../../po/../src/widgets/toolbox.cpp:2395 +msgid "Open arc" +msgstr "Відкрити дугу" + +#: ../../po/../src/widgets/toolbox.cpp:2396 +msgid "" +"Switch between arc (unclosed shape) and segment (closed shape with two radii)" +msgstr "" +"Перемикання між дугою (незамкнутою фігурою) та сектором (замкнутою фігурою з " +"двома радіусами)" + +#: ../../po/../src/widgets/toolbox.cpp:2415 +msgid "Make whole" +msgstr "Зробити цілим" + +#: ../../po/../src/widgets/toolbox.cpp:2417 +msgid "Make the shape a whole ellipse, not arc or segment" +msgstr "Робить фігуру цілим еліпсом, а не дугою чи сектором" + +#: ../../po/../src/widgets/toolbox.cpp:2644 +msgid "" +"When pressed, picks visible color without alpha and when not pressed, picks " +"color including its alpha" +msgstr "" +"При натисканні береться видимий колір без альфа-каналу, а без натискання " +"береться колір разом з його альфа-каналом" + +#: ../../po/../src/widgets/toolbox.cpp:3039 +msgid "Make connectors avoid selected objects" +msgstr "Змусити лінії обгинати виділені об'єкти" + +#: ../../po/../src/widgets/toolbox.cpp:3043 +msgid "Make connectors ignore selected objects" +msgstr "Змусити лінії ігнорувати виділені об'єкти" + +#. +#. 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 : +#: ../share/extensions/addnodes.inx.h:1 +#, fuzzy +msgid "Add Nodes" +msgstr "Вузли" + +#: ../share/extensions/addnodes.inx.h:2 +msgid "Maximum Segment Length" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:1 +msgid "AI Input" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:2 ../share/extensions/ai_output.inx.h:2 +msgid "Adobe Illustrator (*.ai)" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:3 +msgid "Open files saved with Adobe Illustrator" +msgstr "" + +#: ../share/extensions/ai_output.inx.h:1 +#, fuzzy +msgid "AI Output" +msgstr "Вивід" + +#: ../share/extensions/ai_output.inx.h:3 +msgid "Write Adobe Illustrator" +msgstr "" + +#: ../share/extensions/dia.inx.h:1 +msgid "A diagram created with the program Dia" +msgstr "" + +#: ../share/extensions/dia.inx.h:2 +msgid "Dia Diagram (*.dia)" +msgstr "" + +#: ../share/extensions/dia.inx.h:3 +msgid "Dia Input" +msgstr "" + +#: ../share/extensions/dia.inx.h:4 +msgid "" +"In order to import Dia files, Dia itself must be installed. You can get Dia " +"at http://www.gnome.org/projects/dia/" +msgstr "" + +#: ../share/extensions/dia.inx.h:5 +msgid "" +"The dia2svg.sh script should be installed with your Inkscape distribution. " +"If you do not have it, there is likely to be something wrong with your " +"Inkscape installation." +msgstr "" + +#: ../share/extensions/dots.inx.h:1 +#, fuzzy +msgid "Connect the Dots" +msgstr "Лінія з'єднання" + +#: ../share/extensions/dots.inx.h:2 +#, fuzzy +msgid "Dot Size" +msgstr "Розмір" + +#: ../share/extensions/dots.inx.h:3 +#, fuzzy +msgid "Font Size" +msgstr "Розмір :" + +#: ../share/extensions/dropshadow.inx.h:1 +msgid "Color of shadow" +msgstr "" + +#: ../share/extensions/dropshadow.inx.h:2 +#, fuzzy +msgid "Dropshadow" +msgstr "Показувати тінь від сторінки" + +#: ../share/extensions/dxf_input.inx.h:1 +#: ../share/extensions/dxf_output.inx.h:1 +msgid "AutoCAD DXF (*.dxf)" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:2 +msgid "DXF Input" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:3 +msgid "Import AutoCAD's Document Exchange Format" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:4 +msgid "" +"dxf2svg may come with Inkscape, but is also at http://dxf-svg-convert." +"sourceforge.net/" +msgstr "" + +#: ../share/extensions/dxf_output.inx.h:2 +#, fuzzy +msgid "DXF Output" +msgstr "Вивід" + +#: ../share/extensions/dxf_output.inx.h:3 +msgid "DXF file written by pstoedit" +msgstr "" + +#: ../share/extensions/dxf_output.inx.h:4 +msgid "pstoedit must be installed to run see http://www.pstoedit.net/pstoedit" +msgstr "" + +#: ../share/extensions/embedimage.inx.h:1 +#, fuzzy +msgid "Embed Images" +msgstr "Зображення" + +#: ../share/extensions/eps_input.inx.h:1 +msgid "EPS Input" +msgstr "" + +#: ../share/extensions/eps_input.inx.h:2 +msgid "Encapsulated Postscript" +msgstr "" + +#: ../share/extensions/eps_input.inx.h:3 +msgid "Encapsulated Postscript (*.eps)" +msgstr "" + +#: ../share/extensions/epsi_output.inx.h:1 +#, fuzzy +msgid "EPSI Output" +msgstr "Вивід" + +#: ../share/extensions/epsi_output.inx.h:2 +msgid "Encapsulated Postscript Interchange (*.epsi)" +msgstr "" + +#: ../share/extensions/epsi_output.inx.h:3 +msgid "Encapsulated Postscript with a thumbnail" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:1 ../share/extensions/ffms.inx.h:1 +#: ../share/extensions/ffset.inx.h:1 ../share/extensions/ffss.inx.h:1 +#, fuzzy +msgid "Bridge Width" +msgstr "Ширина лінії" + +#: ../share/extensions/ffmet.inx.h:2 ../share/extensions/ffms.inx.h:2 +msgid "First String Length" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:3 +msgid "FretFind Multi Length ET" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:4 ../share/extensions/ffms.inx.h:4 +#: ../share/extensions/ffset.inx.h:3 ../share/extensions/ffss.inx.h:3 +msgid "Fretboard Edges" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:5 ../share/extensions/ffms.inx.h:5 +msgid "Last String Length" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:6 ../share/extensions/ffms.inx.h:6 +#: ../share/extensions/ffset.inx.h:4 ../share/extensions/ffss.inx.h:4 +#, fuzzy +msgid "Number of Frets" +msgstr "Кількість рядків" + +#: ../share/extensions/ffmet.inx.h:7 ../share/extensions/ffms.inx.h:7 +#: ../share/extensions/ffset.inx.h:5 ../share/extensions/ffss.inx.h:5 +#, fuzzy +msgid "Number of Strings" +msgstr "Кількість рядків" + +#: ../share/extensions/ffmet.inx.h:8 ../share/extensions/ffms.inx.h:8 +#: ../share/extensions/ffset.inx.h:6 ../share/extensions/ffss.inx.h:6 +#, fuzzy +msgid "Nut Width" +msgstr "Ширина" + +#: ../share/extensions/ffmet.inx.h:9 ../share/extensions/ffms.inx.h:10 +msgid "Perpendicular Distance" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:10 ../share/extensions/ffset.inx.h:7 +msgid "Scale Base (2 for Octave)" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:11 ../share/extensions/ffset.inx.h:9 +msgid "Tones in Scale" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:12 ../share/extensions/ffms.inx.h:12 +#: ../share/extensions/ffset.inx.h:10 ../share/extensions/ffss.inx.h:10 +msgid "px per Unit" +msgstr "" + +#: ../share/extensions/ffms.inx.h:3 +msgid "FretFind Multi Length Scala" +msgstr "" + +#: ../share/extensions/ffms.inx.h:9 ../share/extensions/ffss.inx.h:7 +msgid "Path to Scala *.scl File" +msgstr "" + +#: ../share/extensions/ffms.inx.h:11 +msgid "Tuning (scale step for each string seperated by semicolons)" +msgstr "" + +#: ../share/extensions/ffset.inx.h:2 +msgid "FretFind Single Length ET" +msgstr "" + +#: ../share/extensions/ffset.inx.h:8 ../share/extensions/ffss.inx.h:8 +msgid "Scale Length" +msgstr "" + +#: ../share/extensions/ffss.inx.h:2 +msgid "FretFind Single Length Scala" +msgstr "" + +#: ../share/extensions/ffss.inx.h:9 +msgid "Tuning (Scale step for each string seperated by semicolons)" +msgstr "" + +#: ../share/extensions/handles.inx.h:1 +#, fuzzy +msgid "Draw Handles" +msgstr "Малювання довільних контурів" + +#: ../share/extensions/interp.inx.h:1 +#, fuzzy +msgid "Duplicate Endpaths" +msgstr "Дублювати вузол" + +#: ../share/extensions/interp.inx.h:2 +#, fuzzy +msgid "Exponent" +msgstr "Експорт" + +#: ../share/extensions/interp.inx.h:3 +msgid "Interpolate" +msgstr "" + +#: ../share/extensions/interp.inx.h:4 +msgid "Interpolate Style (Experimental)" +msgstr "" + +#: ../share/extensions/interp.inx.h:5 +msgid "Interpolation Method" +msgstr "" + +#: ../share/extensions/interp.inx.h:6 +msgid "Interpolation Steps" +msgstr "" + +#: ../share/extensions/kochify.inx.h:1 +msgid "Kochify" +msgstr "" + +#: ../share/extensions/kochify_load.inx.h:1 +msgid "Kochify (Load)" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:1 +#, fuzzy +msgid "Angle" +msgstr "Кут:" + +#: ../share/extensions/lindenmayer.inx.h:2 +msgid "Axiom" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:3 +#, fuzzy +msgid "Lindenmayer" +msgstr "Перейменування шару" + +#: ../share/extensions/lindenmayer.inx.h:4 +msgid "Order" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:5 +#, fuzzy +msgid "Rules" +msgstr "_Лінійки" + +#: ../share/extensions/lindenmayer.inx.h:6 +#, fuzzy +msgid "Step" +msgstr "Кроки" + +#: ../share/extensions/motion.inx.h:1 +#, fuzzy +msgid "Direction" +msgstr "Опис" + +#: ../share/extensions/motion.inx.h:2 +#, fuzzy +msgid "Magnitude" +msgstr "Бузковий" + +#: ../share/extensions/motion.inx.h:3 +#, fuzzy +msgid "Motion" +msgstr "_Обертання" + +#: ../share/extensions/pdf_output.inx.h:1 +msgid "Adobe PDF (*.pdf)" +msgstr "" + +#: ../share/extensions/pdf_output.inx.h:2 +msgid "Adobe Portable Document Format" +msgstr "" + +#: ../share/extensions/pdf_output.inx.h:3 +#, fuzzy +msgid "PDF Output" +msgstr "Вивід" + +#: ../share/extensions/ps_input.inx.h:1 +#, fuzzy +msgid "Postscript" +msgstr "Книжкова" + +#: ../share/extensions/ps_input.inx.h:2 +msgid "Postscript (*.ps)" +msgstr "" + +#: ../share/extensions/ps_input.inx.h:3 +msgid "Postscript Input" +msgstr "" + +#: ../share/extensions/radiusrand.inx.h:1 +#, fuzzy +msgid "Radius" +msgstr "_Підняти" + +#: ../share/extensions/radiusrand.inx.h:2 +#, fuzzy +msgid "Radius Randomize" +msgstr "Випадково:" + +#: ../share/extensions/radiusrand.inx.h:3 +msgid "Randomize Control Points" +msgstr "" + +#: ../share/extensions/radiusrand.inx.h:4 +#, fuzzy +msgid "Randomize Nodes" +msgstr "Викривлено:" + +#: ../share/extensions/rtree.inx.h:1 +#, fuzzy +msgid "Initial Size" +msgstr "Розмір зображення" + +#: ../share/extensions/rtree.inx.h:2 +msgid "Minimum Size" +msgstr "" + +#: ../share/extensions/rtree.inx.h:3 +#, fuzzy +msgid "Random Tree" +msgstr "Випадково:" + +#: ../share/extensions/sk_input.inx.h:1 +msgid "A diagram created with the program Sketch" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:2 +msgid "Sketch Diagram (*.sk)" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:3 +msgid "Sketch Input" +msgstr "" + +#: ../share/extensions/straightseg.inx.h:1 +msgid "Behavior" +msgstr "" + +#: ../share/extensions/straightseg.inx.h:3 +msgid "Segment Straightener" +msgstr "" + +#: ../share/extensions/summersnight.inx.h:1 +msgid "Summer's Night" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:1 +#: ../share/extensions/svgz_output.inx.h:1 +msgid "Compressed Inkscape SVG (*.svgz)" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:2 +#: ../share/extensions/svgz_output.inx.h:2 +msgid "Inkscape's native file format compressed with GZip" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:3 +msgid "SVGZ Input" +msgstr "" + +#: ../share/extensions/svgz_output.inx.h:3 +#, fuzzy +msgid "SVGZ Output" +msgstr "Вивід" + +#: ../share/extensions/txt2svg.inx.h:1 +msgid "ASCII Text" +msgstr "" + +#: ../share/extensions/txt2svg.inx.h:2 +msgid "Text File (*.txt)" +msgstr "" + +#: ../share/extensions/txt2svg.inx.h:3 +msgid "Text Input" +msgstr "" + +#: ../share/extensions/wavy.inx.h:1 +msgid "Calculate first derivative numerically" +msgstr "" + +#: ../share/extensions/wavy.inx.h:2 +msgid "First derivative" +msgstr "" + +#: ../share/extensions/wavy.inx.h:3 +msgid "Function" +msgstr "" + +#: ../share/extensions/wavy.inx.h:4 +msgid "Function Plotter" +msgstr "" + +#: ../share/extensions/wavy.inx.h:5 +msgid "Nodes per period" +msgstr "" + +#: ../share/extensions/wavy.inx.h:6 +msgid "Periods (2*Pi each)" +msgstr "" + +#: ../share/extensions/whirl.inx.h:1 +msgid "Amount of Whirl" +msgstr "" + +#: ../share/extensions/whirl.inx.h:2 +#, fuzzy +msgid "Center X" +msgstr "Центрувати рядки" + +#: ../share/extensions/whirl.inx.h:3 +#, fuzzy +msgid "Center Y" +msgstr "Центрувати рядки" + +#: ../share/extensions/whirl.inx.h:4 +#, fuzzy +msgid "Direction of Rotation" +msgstr "Відхилити запрошення" + +#: ../share/extensions/whirl.inx.h:5 +msgid "Whirl" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:1 +msgid "A popular graphics file format for clipart" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:2 +msgid "Windows Metafile (*.wmf)" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:3 +msgid "Windows Metafile Input" +msgstr "" + +#~ msgid "Custom canvas" +#~ msgstr "Вказаний розмір полотна" + +#~ msgid "Current style" +#~ msgstr "Поточним стилем" + +#~ msgid "" +#~ "Current style is updated every time you change the style of any object " +#~ "(its fill, stroke, transparency, etc.)" +#~ msgstr "" +#~ "Поточний стиль зберігає останній призначений вами (будь-якому об'єкту) " +#~ "стиль - його заповнення, штрих, прозорість та т.п." + +#~ msgid "Arrange Objects" +#~ msgstr "Впорядкувати об'єкти" + +#~ msgid "deg" +#~ msgstr "град" + +#~ msgid "" +#~ "%s is not a valid preferences file.\n" +#~ "%s" +#~ msgstr "" +#~ "%s не є файлом з параметрами.\n" +#~ "%s" + +#~ msgid "" +#~ "Inkscape will run with default settings.\n" +#~ "New settings will not be saved." +#~ msgstr "" +#~ "Inkscape буде використовувати типові параметри.\n" +#~ "Змінені параметри не будуть збережені." + +#~ msgid "_Credits" +#~ msgstr "_Подяки" + +#~ msgid "Grab sensitivity" +#~ msgstr "Радіус захоплення" + +#~ msgid "Click/drag threshold" +#~ msgstr "Вважати клацанням перетягування на" + +#~ msgid "Mouse wheel scrolls by" +#~ msgstr "Колесо миші прокручує на" + +#~ msgid "Scroll by" +#~ msgstr "Крок прокрутки" + +#~ msgid "Acceleration" +#~ msgstr "Прискорення" + +#~ msgid "Speed" +#~ msgstr "Швидкість" + +#~ msgid "Threshold" +#~ msgstr "Поріг" + +#~ msgid "Arrow keys move by" +#~ msgstr "Стрілки переміщують на" + +#~ msgid "> and < scale by" +#~ msgstr "Крок масштабування > та <" + +#~ msgid "Inset/Outset by" +#~ msgstr "Втяжка/розтяжка на" + +#~ msgid "Rotation snaps every" +#~ msgstr "Обмеження обертання" + +#~ msgid "Zoom in/out by" +#~ msgstr "Крок масштабу" + +#~ msgid "Transform" +#~ msgstr "Трансформувати" + +#~ msgid "PLACEHOLDER, DO NOT TRANSLATE" +#~ msgstr "PLACEHOLDER, DO NOT TRANSLATE" + +#~ msgid "Flip selection horizontally" +#~ msgstr "Віддзеркалити виділені об'єкти горизонтально" + +#~ msgid "Flip selection vertically" +#~ msgstr "Віддзеркалити виділені об'єкти вертикально" diff --git a/po/zh_CN.po b/po/zh_CN.po new file mode 100644 index 000000000..4a26add64 --- /dev/null +++ b/po/zh_CN.po @@ -0,0 +1,11366 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR Free Software Foundation, Inc. +# Wang Li , 2002 +# +msgid "" +msgstr "" +"Project-Id-Version: sodipodi 0.24\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2005-12-04 11:51-0800\n" +"PO-Revision-Date: 2002-03-17 15:51+0800\n" +"Last-Translator: wang li \n" +"Language-Team: zh_CN \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../inkscape.desktop.in.h:1 +msgid "Create and edit Scalable Vector Graphics images" +msgstr "" + +#: ../inkscape.desktop.in.h:2 +#, fuzzy +msgid "Inkscape SVG Vector Illustrator" +msgstr "向量图解器" + +#: ../../po/../src/arc-context.cpp:350 +msgid "" +"Ctrl: make circle or integer-ratio ellipse, snap arc/segment angle" +msgstr "" + +#: ../../po/../src/arc-context.cpp:351 ../../po/../src/rect-context.cpp:388 +msgid "Shift: draw around the starting point" +msgstr "" + +#: ../../po/../src/arc-context.cpp:413 +#: ../../po/../src/connector-context.cpp:493 +#: ../../po/../src/dyna-draw-context.cpp:506 +#: ../../po/../src/pen-context.cpp:329 ../../po/../src/pencil-context.cpp:208 +#: ../../po/../src/rect-context.cpp:452 ../../po/../src/spiral-context.cpp:421 +#: ../../po/../src/star-context.cpp:427 +msgid "Current layer is hidden. Unhide it to be able to draw on it." +msgstr "" + +#: ../../po/../src/arc-context.cpp:417 +#: ../../po/../src/connector-context.cpp:497 +#: ../../po/../src/dyna-draw-context.cpp:510 +#: ../../po/../src/pen-context.cpp:336 ../../po/../src/pencil-context.cpp:212 +#: ../../po/../src/rect-context.cpp:456 ../../po/../src/spiral-context.cpp:426 +#: ../../po/../src/star-context.cpp:431 +msgid "Current layer is locked. Unlock it to be able to draw on it." +msgstr "" + +#: ../../po/../src/arc-context.cpp:496 +#, c-format +msgid "" +"Ellipse: %s × %s; with Ctrl to make circle or integer-" +"ratio ellipse; with Shift to draw around the starting point" +msgstr "" + +#: ../../po/../src/connector-context.cpp:518 +#, fuzzy +msgid "Creating new connector" +msgstr "内存文档 %d" + +#: ../../po/../src/connector-context.cpp:939 +#, fuzzy +msgid "Finishing connector" +msgstr "手绘" + +#: ../../po/../src/connector-context.cpp:1108 +msgid "Connection point: click or drag to create a new connector" +msgstr "" + +#: ../../po/../src/connector-context.cpp:1185 +msgid "Connector endpoint: drag to reroute or connect to new shapes" +msgstr "" + +#: ../../po/../src/connector-context.cpp:1278 +#, fuzzy +msgid "Select at least one non-connector object." +msgstr "文档中无渐变" + +#: ../../po/../src/desktop-events.cpp:238 +#, c-format +msgid "%s at %s" +msgstr "" + +#. TRANSLATORS: This string appears when double-clicking on a guide. +#. This is the distance by which the guide is to be moved. +#: ../../po/../src/desktop-events.cpp:277 +#, fuzzy +msgid " relative by " +msgstr "垂直移动" + +#. TRANSLATORS: This string appears when double-clicking on a guide. +#. This is the target location where the guide is to be moved. +#: ../../po/../src/desktop-events.cpp:282 +#: ../../po/../src/desktop-events.cpp:395 +#, fuzzy +msgid " absolute to " +msgstr "绝对" + +#. create dialog +#: ../../po/../src/desktop-events.cpp:348 +#, fuzzy +msgid "Guideline" +msgstr "指示线颜色" + +#: ../../po/../src/desktop-events.cpp:432 +#, fuzzy, c-format +msgid "Move %s" +msgstr "移动" + +#: ../../po/../src/desktop.cpp:678 +msgid "No previous zoom." +msgstr "" + +#: ../../po/../src/desktop.cpp:703 +msgid "No next zoom." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:182 +#, fuzzy +msgid "Nothing selected." +msgstr "最后的选择" + +#: ../../po/../src/dialogs/clonetiler.cpp:188 +msgid "More than one object selected." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:195 +#, c-format +msgid "Object has %d tiled clones." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:200 +msgid "Object has no tiled clones." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:865 +#, fuzzy +msgid "Select one object whose tiled clones to unclump." +msgstr "将选定对象转换为曲线" + +#: ../../po/../src/dialogs/clonetiler.cpp:916 +#, fuzzy +msgid "Select one object whose tiled clones to remove." +msgstr "将选定对象转换为曲线" + +#: ../../po/../src/dialogs/clonetiler.cpp:984 +#: ../../po/../src/selection-chemistry.cpp:1774 +#, fuzzy +msgid "Select an object to clone." +msgstr "将选定对象转换为曲线" + +#: ../../po/../src/dialogs/clonetiler.cpp:990 +#: ../../po/../src/selection-chemistry.cpp:1780 +msgid "" +"If you want to clone several objects, group them and clone the " +"group." +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1484 +msgid "Per row:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1497 +#, fuzzy +msgid "Per column:" +msgstr "未选择渐变" + +#: ../../po/../src/dialogs/clonetiler.cpp:1505 +#, fuzzy +msgid "Randomize:" +msgstr "最后的选择" + +#: ../../po/../src/dialogs/clonetiler.cpp:1656 +#, fuzzy +msgid "_Symmetry" +msgstr "对称 " + +#. TRANSLATORS: For the following 17 symmetry groups, see +#. * http://www.bib.ulb.ac.be/coursmath/doc/17.htm (visual examples); +#. * http://www.clarku.edu/~djoyce/wallpaper/seventeen.html (English vocabulary); or +#. * http://membres.lycos.fr/villemingerard/Geometri/Sym1D.htm (French vocabulary). +#. +#: ../../po/../src/dialogs/clonetiler.cpp:1664 +msgid "Select one of the 17 symmetry groups for the tiling" +msgstr "" + +#. TRANSLATORS: "translation" means "shift" / "displacement" here. +#: ../../po/../src/dialogs/clonetiler.cpp:1675 +msgid "P1: simple translation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1676 +msgid "P2: 180° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1677 +msgid "PM: reflection" +msgstr "" + +#. TRANSLATORS: "glide reflection" is a reflection and a translation combined. +#. For more info, see http://mathforum.org/sum95/suzanne/symsusan.html +#: ../../po/../src/dialogs/clonetiler.cpp:1680 +msgid "PG: glide reflection" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1681 +msgid "CM: reflection + glide reflection" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1682 +msgid "PMM: reflection + reflection" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1683 +msgid "PMG: reflection + 180° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1684 +msgid "PGG: glide reflection + 180° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1685 +msgid "CMM: reflection + reflection + 180° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1686 +msgid "P4: 90° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1687 +msgid "P4M: 90° rotation + 45° reflection" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1688 +msgid "P4G: 90° rotation + 90° reflection" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1689 +msgid "P3: 120° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1690 +msgid "P31M: reflection + 120° rotation, dense" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1691 +msgid "P3M1: reflection + 120° rotation, sparse" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1692 +msgid "P6: 60° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1693 +msgid "P6M: reflection + 60° rotation" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1721 +msgid "S_hift" +msgstr "" + +#. TRANSLATORS: "shift" means: the tiles will be shifted (offset) horizontally by this amount +#: ../../po/../src/dialogs/clonetiler.cpp:1731 +#, fuzzy, no-c-format +msgid "Shift X:" +msgstr "改变" + +#: ../../po/../src/dialogs/clonetiler.cpp:1739 +#, no-c-format +msgid "Horizontal shift per row (in % of tile width)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1747 +#, no-c-format +msgid "Horizontal shift per column (in % of tile width)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1754 +msgid "Randomize the horizontal shift by this percentage" +msgstr "" + +#. TRANSLATORS: "shift" means: the tiles will be shifted (offset) vertically by this amount +#: ../../po/../src/dialogs/clonetiler.cpp:1764 +#, fuzzy, no-c-format +msgid "Shift Y:" +msgstr "改变" + +#: ../../po/../src/dialogs/clonetiler.cpp:1772 +#, no-c-format +msgid "Vertical shift per row (in % of tile height)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1780 +#, no-c-format +msgid "Vertical shift per column (in % of tile height)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1787 +msgid "Randomize the vertical shift by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1795 +#, fuzzy +msgid "Exponent:" +msgstr "改变" + +#: ../../po/../src/dialogs/clonetiler.cpp:1802 +msgid "Whether rows are spaced evenly (1), converge (<1) or diverge (>1)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1809 +msgid "Whether columns are spaced evenly (1), converge (<1) or diverge (>1)" +msgstr "" + +#. TRANSLATORS: "Alternate" is a verb here +#: ../../po/../src/dialogs/clonetiler.cpp:1817 +#: ../../po/../src/dialogs/clonetiler.cpp:1907 +#: ../../po/../src/dialogs/clonetiler.cpp:1966 +#: ../../po/../src/dialogs/clonetiler.cpp:2022 +#: ../../po/../src/dialogs/clonetiler.cpp:2153 +msgid "Alternate:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1823 +msgid "Alternate the sign of shifts for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1828 +msgid "Alternate the sign of shifts for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1837 +#, fuzzy +msgid "Sc_ale" +msgstr "缩放" + +#: ../../po/../src/dialogs/clonetiler.cpp:1845 +#, fuzzy +msgid "Scale X:" +msgstr "改变" + +#: ../../po/../src/dialogs/clonetiler.cpp:1853 +#, fuzzy, no-c-format +msgid "Horizontal scale per row (in % of tile width)" +msgstr "水平缩放值" + +#: ../../po/../src/dialogs/clonetiler.cpp:1861 +#, fuzzy, no-c-format +msgid "Horizontal scale per column (in % of tile width)" +msgstr "水平缩放值" + +#: ../../po/../src/dialogs/clonetiler.cpp:1868 +msgid "Randomize the horizontal scale by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1876 +#, fuzzy +msgid "Scale Y:" +msgstr "改变" + +#: ../../po/../src/dialogs/clonetiler.cpp:1884 +#, fuzzy, no-c-format +msgid "Vertical scale per row (in % of tile height)" +msgstr "垂直缩放值" + +#: ../../po/../src/dialogs/clonetiler.cpp:1892 +#, fuzzy, no-c-format +msgid "Vertical scale per column (in % of tile height)" +msgstr "垂直缩放值" + +#: ../../po/../src/dialogs/clonetiler.cpp:1899 +msgid "Randomize the vertical scale by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1913 +#, fuzzy +msgid "Alternate the sign of scales for each row" +msgstr "垂直缩放值" + +#: ../../po/../src/dialogs/clonetiler.cpp:1918 +#, fuzzy +msgid "Alternate the sign of scales for each column" +msgstr "垂直缩放值" + +#: ../../po/../src/dialogs/clonetiler.cpp:1927 +#, fuzzy +msgid "_Rotation" +msgstr "旋转:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1935 +#, fuzzy +msgid "Angle:" +msgstr "改变" + +#: ../../po/../src/dialogs/clonetiler.cpp:1943 +#, no-c-format +msgid "Rotate tiles by this angle for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1951 +#, no-c-format +msgid "Rotate tiles by this angle for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1958 +msgid "Randomize the rotation angle by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1972 +msgid "Alternate the rotation direction for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1977 +msgid "Alternate the rotation direction for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:1985 +#, fuzzy +msgid "_Opacity" +msgstr "不透明度:" + +#: ../../po/../src/dialogs/clonetiler.cpp:1993 +#, fuzzy +msgid "Fade out:" +msgstr "改变" + +#: ../../po/../src/dialogs/clonetiler.cpp:2000 +msgid "Decrease tile opacity by this percentage for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2007 +msgid "Decrease tile opacity by this percentage for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2014 +msgid "Randomize the tile opacity by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2028 +msgid "Alternate the sign of opacity change for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2033 +msgid "Alternate the sign of opacity change for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2041 +#, fuzzy +msgid "Co_lor" +msgstr "颜色" + +#: ../../po/../src/dialogs/clonetiler.cpp:2046 +#, fuzzy +msgid "Initial color: " +msgstr "栅格颜色:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2050 +msgid "Initial color of tiled clones" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2050 +msgid "" +"Initial color for clones (works only if the original has unset fill or " +"stroke)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2065 +#, fuzzy +msgid "H:" +msgstr "改变" + +#: ../../po/../src/dialogs/clonetiler.cpp:2072 +msgid "Change the tile hue by this percentage for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2079 +msgid "Change the tile hue by this percentage for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2086 +msgid "Randomize the tile hue by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2095 +#, fuzzy +msgid "S:" +msgstr "改变" + +#: ../../po/../src/dialogs/clonetiler.cpp:2102 +msgid "Change the color saturation by this percentage for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2109 +msgid "Change the color saturation by this percentage for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2116 +msgid "Randomize the color saturation by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2124 +#, fuzzy +msgid "L:" +msgstr "改变" + +#: ../../po/../src/dialogs/clonetiler.cpp:2131 +msgid "Change the color lightness by this percentage for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2138 +msgid "Change the color lightness by this percentage for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2145 +msgid "Randomize the color lightness by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2159 +msgid "Alternate the sign of color changes for each row" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2164 +msgid "Alternate the sign of color changes for each column" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2172 +#, fuzzy +msgid "_Trace" +msgstr "不完整的位图" + +#: ../../po/../src/dialogs/clonetiler.cpp:2179 +msgid "Trace the drawing under the tiles" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2183 +msgid "" +"For each clone, pick a value from the drawing in that clone's location and " +"apply it to the clone" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2197 +msgid "1. Pick from the drawing:" +msgstr "" + +#. ----Hbox2 +#: ../../po/../src/dialogs/clonetiler.cpp:2208 +#: ../../po/../src/dialogs/clonetiler.cpp:2355 +#: ../../po/../src/ui/dialog/tracedialog.cpp:445 +#, fuzzy +msgid "Color" +msgstr "颜色" + +#: ../../po/../src/dialogs/clonetiler.cpp:2209 +msgid "Pick the visible color and opacity" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2216 +#: ../../po/../src/dialogs/clonetiler.cpp:2365 +#: ../share/extensions/dropshadow.inx.h:3 +#, fuzzy +msgid "Opacity" +msgstr "不透明度:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2217 +msgid "Pick the total accumulated opacity" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2224 +msgid "R" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2225 +msgid "Pick the Red component of the color" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2232 +msgid "G" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2233 +msgid "Pick the Green component of the color" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2240 +msgid "B" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2241 +msgid "Pick the Blue component of the color" +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2250 +msgid "clonetiler|H" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2251 +#, fuzzy +msgid "Pick the hue of the color" +msgstr "选取勾描颜色" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2260 +msgid "clonetiler|S" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2261 +#, fuzzy +msgid "Pick the saturation of the color" +msgstr "选取勾描颜色" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/dialogs/clonetiler.cpp:2270 +msgid "clonetiler|L" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2271 +msgid "Pick the lightness of the color" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2281 +msgid "2. Tweak the picked value:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2291 +msgid "Gamma-correct:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2296 +msgid "Shift the mid-range of the picked value upwards (>0) or downwards (<0)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2303 +msgid "Randomize:" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2308 +msgid "Randomize the picked value by this percentage" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2315 +#, fuzzy +msgid "Invert:" +msgstr "重置" + +#: ../../po/../src/dialogs/clonetiler.cpp:2319 +msgid "Invert the picked value" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2325 +msgid "3. Apply the value to the clones':" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2335 +#, fuzzy +msgid "Presence" +msgstr "项目是引用" + +#: ../../po/../src/dialogs/clonetiler.cpp:2338 +msgid "" +"Each clone is created with the probability determined by the picked value in " +"that point" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2345 +#, fuzzy +msgid "Size" +msgstr "边:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2348 +msgid "Each clone's size is determined by the picked value in that point" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2358 +msgid "" +"Each clone is painted by the picked color (the original must have unset fill " +"or stroke)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2368 +msgid "Each clone's opacity is determined by the picked value in that point" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2395 +msgid "How many rows in the tiling" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2415 +msgid "How many columns in the tiling" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2445 +msgid "Width of the rectangle to be filled" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2470 +msgid "Height of the rectangle to be filled" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2485 +#, fuzzy +msgid "Rows, columns: " +msgstr "改变" + +#: ../../po/../src/dialogs/clonetiler.cpp:2486 +msgid "Create the specified number of rows and columns" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2495 +#, fuzzy +msgid "Width, height: " +msgstr "高度:" + +#: ../../po/../src/dialogs/clonetiler.cpp:2496 +msgid "Fill the specified width and height with the tiling" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2512 +#, fuzzy +msgid "Use saved size and position of the tile" +msgstr "大小和位置" + +#: ../../po/../src/dialogs/clonetiler.cpp:2515 +msgid "" +"Pretend that the size and position of the tile are the same as the last time " +"you tiled it (if any), instead of using the current size" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2539 +#, fuzzy +msgid " _Create " +msgstr "改变" + +#: ../../po/../src/dialogs/clonetiler.cpp:2541 +msgid "Create and tile the clones of the selection" +msgstr "" + +#. TRANSLATORS: if a group of objects are "clumped" together, then they +#. are unevenly spread in the given amount of space - as shown in the +#. diagrams on the left in the following screenshot: +#. http://www.inkscape.org/screenshots/gallery/inkscape-0.42-CVS-tiles-unclump.png +#. So unclumping is the process of spreading a number of objects out more evenly. +#: ../../po/../src/dialogs/clonetiler.cpp:2556 +msgid " _Unclump " +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2557 +msgid "Spread out clones to reduce clumping; can be applied repeatedly" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2563 +#, fuzzy +msgid " Re_move " +msgstr "删除连接" + +#: ../../po/../src/dialogs/clonetiler.cpp:2564 +msgid "Remove existing tiled clones of the selected object (siblings only)" +msgstr "" + +#: ../../po/../src/dialogs/clonetiler.cpp:2580 +#, fuzzy +msgid " R_eset " +msgstr "删除连接" + +#. TRANSLATORS: "change" is a noun here +#: ../../po/../src/dialogs/clonetiler.cpp:2582 +msgid "" +"Reset all shifts, scales, rotates, opacity and color changes in the dialog " +"to zero" +msgstr "" + +#: ../../po/../src/dialogs/color-picker.cpp:280 +#, fuzzy +msgid "Close" +msgstr "关闭视图" + +#: ../../po/../src/dialogs/debugdialog.cpp:138 +msgid "Messages" +msgstr "" + +#. ## Add a menu for clear() +#: ../../po/../src/dialogs/debugdialog.cpp:144 +#: ../../po/../src/menus-skeleton.h:16 +#: ../../po/../src/ui/dialog/messages.cpp:56 +#: ../../po/../src/ui/dialog/scriptdialog.cpp:181 +msgid "_File" +msgstr "文件(_F)" + +#. TRANSLATORS: "Clear" is a verb here +#: ../../po/../src/dialogs/debugdialog.cpp:145 +#: ../../po/../src/dialogs/find.cpp:753 +#: ../../po/../src/ui/dialog/messages.cpp:57 +#: ../../po/../src/ui/dialog/scriptdialog.cpp:182 +#, fuzzy +msgid "_Clear" +msgstr "关闭视图" + +#: ../../po/../src/dialogs/debugdialog.cpp:147 +#: ../../po/../src/ui/dialog/messages.cpp:59 +msgid "Capture log messages" +msgstr "" + +#: ../../po/../src/dialogs/debugdialog.cpp:149 +#: ../../po/../src/ui/dialog/messages.cpp:61 +msgid "Release log messages" +msgstr "" + +#. Notebook tab +#: ../../po/../src/dialogs/desktop-properties.cpp:909 +#: ../../po/../src/ui/dialog/document-preferences.cpp:89 +#: ../../po/../src/ui/widget/panel.cpp:107 +msgid "Grid" +msgstr "栅格" + +#. Checkbuttons +#. / \todo FIXME: gray out snapping when grid is off +#. / \todo FIXME: gray out snapping when grid is off. +#. / Dissenting view: you want snapping without grid. +#: ../../po/../src/dialogs/desktop-properties.cpp:917 +#: ../../po/../src/ui/dialog/document-preferences.cpp:179 +msgid "Show grid" +msgstr "显示栅格" + +#: ../../po/../src/dialogs/desktop-properties.cpp:917 +#: ../../po/../src/ui/dialog/document-preferences.cpp:179 +#: ../../po/../src/verbs.cpp:2115 +#, fuzzy +msgid "Show or hide grid" +msgstr "显示栅格" + +#: ../../po/../src/dialogs/desktop-properties.cpp:918 +#: ../../po/../src/ui/dialog/document-preferences.cpp:180 +#, fuzzy +msgid "Snap bounding boxes to grid" +msgstr "定位到栅格" + +#: ../../po/../src/dialogs/desktop-properties.cpp:918 +#: ../../po/../src/dialogs/desktop-properties.cpp:1001 +#: ../../po/../src/ui/dialog/document-preferences.cpp:181 +#: ../../po/../src/ui/dialog/document-preferences.cpp:236 +msgid "Snap the edges of the object bounding boxes" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:919 +#: ../../po/../src/ui/dialog/document-preferences.cpp:183 +#, fuzzy +msgid "Snap nodes to grid" +msgstr "定位到栅格" + +#: ../../po/../src/dialogs/desktop-properties.cpp:919 +#: ../../po/../src/dialogs/desktop-properties.cpp:1002 +#: ../../po/../src/ui/dialog/document-preferences.cpp:184 +#: ../../po/../src/ui/dialog/document-preferences.cpp:239 +msgid "Snap path nodes, text baselines, ellipse centers, etc." +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:937 +#: ../../po/../src/ui/dialog/document-preferences.cpp:186 +msgid "Grid units:" +msgstr "栅格单元:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:939 +#: ../../po/../src/ui/dialog/document-preferences.cpp:187 +msgid "Origin X:" +msgstr "X 原点:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:942 +#: ../../po/../src/ui/dialog/document-preferences.cpp:189 +msgid "Origin Y:" +msgstr "Y 原点:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:945 +#: ../../po/../src/ui/dialog/document-preferences.cpp:191 +msgid "Spacing X:" +msgstr "X 间据:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:948 +#: ../../po/../src/ui/dialog/document-preferences.cpp:193 +msgid "Spacing Y:" +msgstr "Y 间据:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:952 +#: ../../po/../src/dialogs/desktop-properties.cpp:1013 +#: ../../po/../src/ui/dialog/document-preferences.cpp:195 +#: ../../po/../src/ui/dialog/document-preferences.cpp:241 +msgid "Snap units:" +msgstr "定位单位:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:955 +#: ../../po/../src/dialogs/desktop-properties.cpp:1016 +#: ../../po/../src/ui/dialog/document-preferences.cpp:196 +#: ../../po/../src/ui/dialog/document-preferences.cpp:242 +msgid "Snap distance:" +msgstr "定位距离:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:958 +#: ../../po/../src/ui/dialog/document-preferences.cpp:199 +#, fuzzy +msgid "Grid line color:" +msgstr "指示线颜色" + +#: ../../po/../src/dialogs/desktop-properties.cpp:959 +#: ../../po/../src/ui/dialog/document-preferences.cpp:199 +#, fuzzy +msgid "Grid line color" +msgstr "指示线颜色" + +#: ../../po/../src/dialogs/desktop-properties.cpp:959 +#: ../../po/../src/ui/dialog/document-preferences.cpp:200 +#, fuzzy +msgid "Color of grid lines" +msgstr "选择指示线颜色" + +#: ../../po/../src/dialogs/desktop-properties.cpp:961 +#: ../../po/../src/ui/dialog/document-preferences.cpp:201 +#, fuzzy +msgid "Major grid line color:" +msgstr "指示线颜色" + +#: ../../po/../src/dialogs/desktop-properties.cpp:962 +#: ../../po/../src/ui/dialog/document-preferences.cpp:201 +#, fuzzy +msgid "Major grid line color" +msgstr "指示线颜色" + +#: ../../po/../src/dialogs/desktop-properties.cpp:962 +#: ../../po/../src/ui/dialog/document-preferences.cpp:202 +#, fuzzy +msgid "Color of the major (highlighted) grid lines" +msgstr "选择高亮指示线颜色" + +#: ../../po/../src/dialogs/desktop-properties.cpp:965 +#: ../../po/../src/ui/dialog/document-preferences.cpp:204 +#, fuzzy +msgid "Major grid line every:" +msgstr "指示线颜色" + +#. TRANSLATORS: This belongs to the "Major grid line every:" string, +#. see grid settings in the "Document Preferences" dialog +#: ../../po/../src/dialogs/desktop-properties.cpp:977 +#: ../../po/../src/ui/dialog/document-preferences.cpp:204 +#, fuzzy +msgid "lines" +msgstr "关闭视图" + +#. Guidelines page +#: ../../po/../src/dialogs/desktop-properties.cpp:991 +#: ../../po/../src/ui/dialog/document-preferences.cpp:90 +msgid "Guides" +msgstr "指示" + +#. / \todo FIXME: gray out snapping when guides are off +#. / Dissenting view: you want snapping without guides. +#: ../../po/../src/dialogs/desktop-properties.cpp:1000 +#: ../../po/../src/ui/dialog/document-preferences.cpp:234 +msgid "Show guides" +msgstr "显示指示线" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1000 +#: ../../po/../src/ui/dialog/document-preferences.cpp:234 +#: ../../po/../src/verbs.cpp:2116 +#, fuzzy +msgid "Show or hide guides" +msgstr "显示指示线" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1001 +#: ../../po/../src/ui/dialog/document-preferences.cpp:235 +#, fuzzy +msgid "Snap bounding boxes to guides" +msgstr "定位到指示线" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1002 +#: ../../po/../src/ui/dialog/document-preferences.cpp:238 +#, fuzzy +msgid "Snap points to guides" +msgstr "定位到栅格" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1020 +#: ../../po/../src/ui/dialog/document-preferences.cpp:243 +#, fuzzy +msgid "Guide color:" +msgstr "指示颜色:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1021 +#: ../../po/../src/ui/dialog/document-preferences.cpp:243 +msgid "Guideline color" +msgstr "指示线颜色" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1021 +#: ../../po/../src/ui/dialog/document-preferences.cpp:244 +#, fuzzy +msgid "Color of guidelines" +msgstr "选择指示线颜色" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1023 +#: ../../po/../src/ui/dialog/document-preferences.cpp:245 +msgid "Highlight color:" +msgstr "高亮颜色:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1024 +#: ../../po/../src/ui/dialog/document-preferences.cpp:245 +#, fuzzy +msgid "Highlighted guideline color" +msgstr "高亮指示线颜色" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1024 +#: ../../po/../src/ui/dialog/document-preferences.cpp:246 +msgid "Color of a guideline when it is under mouse" +msgstr "" + +#. Page page +#: ../../po/../src/dialogs/desktop-properties.cpp:1029 +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:855 +#: ../../po/../src/ui/dialog/document-preferences.cpp:88 +#: ../../po/../src/widgets/desktop-widget.cpp:1061 +msgid "Page" +msgstr "页" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1039 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +#, fuzzy +msgid "Background:" +msgstr "终点颜色" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1040 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +#, fuzzy +msgid "Background color" +msgstr "终点颜色" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1041 +#: ../../po/../src/ui/dialog/document-preferences.cpp:145 +msgid "" +"Color and transparency of the page background (also used for bitmap export)" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1045 +#: ../../po/../src/ui/dialog/document-preferences.cpp:147 +#, fuzzy +msgid "Show page border" +msgstr "显示栅格" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1049 +#: ../../po/../src/ui/dialog/document-preferences.cpp:148 +#, fuzzy +msgid "Border on top of drawing" +msgstr "缩放到图画" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1052 +#: ../../po/../src/ui/dialog/document-preferences.cpp:149 +#, fuzzy +msgid "Border color:" +msgstr "栅格颜色:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1053 +#: ../../po/../src/ui/dialog/document-preferences.cpp:149 +#, fuzzy +msgid "Page border color" +msgstr "栅格颜色:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1054 +#: ../../po/../src/ui/dialog/document-preferences.cpp:150 +#, fuzzy +msgid "Color of the page border" +msgstr "显示栅格" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1059 +#: ../../po/../src/ui/dialog/document-preferences.cpp:152 +msgid "Show page shadow" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1063 +#: ../../po/../src/ui/dialog/document-preferences.cpp:153 +#, fuzzy +msgid "Default units:" +msgstr "删除" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1069 +msgid "Units for the tool controls, ruler, and the statusbar" +msgstr "" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1086 +#: ../../po/../src/ui/widget/page-sizer.cpp:209 +#, fuzzy +msgid "Page size:" +msgstr "页面大小:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1110 +#: ../../po/../src/ui/widget/page-sizer.cpp:219 +msgid "Custom" +msgstr "定制" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1121 +#: ../../po/../src/ui/widget/page-sizer.cpp:225 +#, fuzzy +msgid "Page orientation:" +msgstr "渐变颜料" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1133 +#: ../../po/../src/ui/widget/page-sizer.cpp:232 +#, fuzzy +msgid "Landscape" +msgstr "Sodipodi:%s:%s:%d" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1139 +#: ../../po/../src/ui/widget/page-sizer.cpp:234 +#, fuzzy +msgid "Portrait" +msgstr "点" + +#. Custom paper frame +#: ../../po/../src/dialogs/desktop-properties.cpp:1148 +#: ../../po/../src/ui/widget/page-sizer.cpp:249 +#, fuzzy +msgid "Custom size" +msgstr "定制" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1160 +#: ../../po/../src/dialogs/export.cpp:269 +#: ../../po/../src/ui/widget/page-sizer.cpp:261 +msgid "Units:" +msgstr "单位:" + +#. Stroke width +#: ../../po/../src/dialogs/desktop-properties.cpp:1162 +#: ../../po/../src/dialogs/export.cpp:310 +#: ../../po/../src/dialogs/object-attributes.cpp:55 +#: ../../po/../src/dialogs/stroke-style.cpp:985 +#: ../../po/../src/ui/widget/page-sizer.cpp:262 +#: ../../po/../src/widgets/toolbox.cpp:1957 +msgid "Width:" +msgstr "宽度:" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1183 +#: ../../po/../src/dialogs/export.cpp:326 +#: ../../po/../src/dialogs/export.cpp:431 +#: ../../po/../src/dialogs/object-attributes.cpp:56 +#: ../../po/../src/ui/widget/page-sizer.cpp:263 +msgid "Height:" +msgstr "高度:" + +#. +#. * Ownership metadata tab +#. +#: ../../po/../src/dialogs/desktop-properties.cpp:1206 +msgid "Metadata" +msgstr "" + +#. add license selector pull-down +#: ../../po/../src/dialogs/desktop-properties.cpp:1225 +#, fuzzy +msgid "License" +msgstr "英寸" + +#: ../../po/../src/dialogs/desktop-properties.cpp:1255 +msgid "Proprietary" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:212 +#, fuzzy +msgid "When transforming, show:" +msgstr "重置变换" + +#: ../../po/../src/dialogs/display-settings.cpp:223 +#, fuzzy +msgid "Objects" +msgstr "对象" + +#: ../../po/../src/dialogs/display-settings.cpp:224 +msgid "Show the actual objects when moving or transforming" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:231 +#, fuzzy +msgid "Box outline" +msgstr "显示指示线" + +#: ../../po/../src/dialogs/display-settings.cpp:232 +msgid "Show only a box outline of the objects when moving or transforming" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:238 +#, fuzzy +msgid "Per-object selection cue:" +msgstr "将选定对象转换为曲线" + +#. sorationsnapsperpi == 0 means no snapping +#: ../../po/../src/dialogs/display-settings.cpp:249 +#: ../../po/../src/dialogs/display-settings.cpp:386 +#: ../../po/../src/dialogs/display-settings.cpp:441 +#: ../../po/../src/dialogs/display-settings.cpp:1482 +#: ../../po/../src/dialogs/stroke-style.cpp:791 +#: ../../po/../src/interface.cpp:741 +#: ../../po/../src/ui/widget/selected-style.cpp:100 +#: ../../po/../src/verbs.cpp:1842 +msgid "None" +msgstr "无" + +#: ../../po/../src/dialogs/display-settings.cpp:250 +msgid "No per-object selection indication" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:256 +msgid "Mark" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:257 +msgid "Each selected object has a diamond mark in the top left corner" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:264 +msgid "Box" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:265 +msgid "Each selected object displays its bounding box" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:270 +#, fuzzy +msgid "Default scale origin:" +msgstr "默认光标公差:" + +#: ../../po/../src/dialogs/display-settings.cpp:281 +#, fuzzy +msgid "Opposite bounding box edge" +msgstr "定位到栅格" + +#: ../../po/../src/dialogs/display-settings.cpp:282 +msgid "Default scale origin will be on the bounding box of the item" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:288 +msgid "Farthest opposite node" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:289 +msgid "Default scale origin will be on the bounding box of the item's points" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:341 +#, fuzzy +msgid "degrees" +msgstr "度" + +#: ../../po/../src/dialogs/display-settings.cpp:350 +msgid "" +"Rotating with Ctrl pressed snaps every that much degrees; also, pressing " +"[ or ] rotates by this amount" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:407 +msgid "Rotation snaps every:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:430 +msgid "" +"None: dialogs are treated as regular windows; Normal: dialogs stay on top of " +"document windows; Aggressive: same as Normal but may work better with some " +"window managers." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:451 +msgid "Normal" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:461 +msgid "Aggressive" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:475 +#, fuzzy +msgid "Dialogs on top:" +msgstr "对话框" + +#: ../../po/../src/dialogs/display-settings.cpp:645 +#, fuzzy +msgid "Show selection cue" +msgstr "将选定对象转换为曲线" + +#: ../../po/../src/dialogs/display-settings.cpp:646 +msgid "" +"Whether selected objects display a selection cue (the same as in selector)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:657 +#, fuzzy +msgid "Enable gradient editing" +msgstr "渐变向量" + +#: ../../po/../src/dialogs/display-settings.cpp:658 +msgid "Whether selected objects display gradient editing controls" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:719 +#, fuzzy +msgid "No objects selected to take the style from." +msgstr "将选定对象转换为曲线" + +#: ../../po/../src/dialogs/display-settings.cpp:728 +msgid "" +"More than one object selected. Cannot take style from multiple " +"objects." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:767 +#, fuzzy +msgid "Create new objects with:" +msgstr "添加属性" + +#: ../../po/../src/dialogs/display-settings.cpp:777 +#, fuzzy +msgid "Take from selection" +msgstr "变换选择" + +#: ../../po/../src/dialogs/display-settings.cpp:778 +msgid "Remember the style of the (first) selected object as this tool's style" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:782 +#, fuzzy +msgid "Last used style" +msgstr "勾描风格" + +#: ../../po/../src/dialogs/display-settings.cpp:782 +msgid "Apply the style you last set on an object" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:790 +msgid "This tool's own style:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:790 +msgid "" +"Each tool may store its own style to apply to the newly created objects. Use " +"the button below to set it." +msgstr "" + +#. Mouse +#: ../../po/../src/dialogs/display-settings.cpp:877 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:55 +#, fuzzy +msgid "Mouse" +msgstr "移动" + +#. TRANSLATORS: "Grab" is a noun here. "Grab sensitivity" is intended to mean how +#. * close on the screen you need to be to an object to be able to grab it with mouse (in +#. * pixels). +#: ../../po/../src/dialogs/display-settings.cpp:883 +#, fuzzy +msgid "Grab sensitivity:" +msgstr "使其敏感" + +#: ../../po/../src/dialogs/display-settings.cpp:884 +msgid "" +"How close on the screen you need to be to an object to be able to grab it " +"with mouse (in screen pixels)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:885 +#: ../../po/../src/dialogs/display-settings.cpp:897 +#: ../../po/../src/dialogs/display-settings.cpp:912 +#: ../../po/../src/dialogs/display-settings.cpp:930 +#: ../../po/../src/dialogs/display-settings.cpp:970 +msgid "pixels" +msgstr "像素" + +#: ../../po/../src/dialogs/display-settings.cpp:895 +msgid "Click/drag threshold:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:896 +msgid "" +"Maximum mouse drag (in screen pixels) which is considered a click, not a drag" +msgstr "" + +#. Scrolling +#: ../../po/../src/dialogs/display-settings.cpp:907 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:56 +msgid "Scrolling" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:910 +msgid "Mouse wheel scrolls by:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:911 +msgid "" +"One mouse wheel notch scrolls by this distance in screen pixels " +"(horizontally with Shift)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:920 +msgid "Ctrl+arrows" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:928 +msgid "Scroll by:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:929 +msgid "Pressing Ctrl+arrow key scrolls by this distance (in screen pixels)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:939 +#, fuzzy +msgid "Acceleration:" +msgstr "选择" + +#: ../../po/../src/dialogs/display-settings.cpp:940 +msgid "" +"Pressing and holding Ctrl+arrow will gradually speed up scrolling (0 for no " +"acceleration)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:949 +msgid "Autoscrolling" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:957 +#, fuzzy +msgid "Speed:" +msgstr "红色:" + +#: ../../po/../src/dialogs/display-settings.cpp:958 +msgid "" +"How fast the canvas autoscrolls when you drag beyond canvas edge (0 to turn " +"autoscroll off)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:968 +#: ../../po/../src/ui/dialog/tracedialog.cpp:357 +#: ../../po/../src/ui/dialog/tracedialog.cpp:390 +msgid "Threshold:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:969 +msgid "" +"How far (in screen pixels) you need to be from the canvas edge to trigger " +"autoscroll; positive is outside the canvas, negative is within the canvas" +msgstr "" + +#. Steps +#: ../../po/../src/dialogs/display-settings.cpp:979 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:57 +#, fuzzy +msgid "Steps" +msgstr " 风格 " + +#: ../../po/../src/dialogs/display-settings.cpp:982 +msgid "Arrow keys move by:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:983 +msgid "" +"Pressing an arrow key moves selected object(s) or node(s) by this distance " +"(in px units)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:984 +#: ../../po/../src/dialogs/display-settings.cpp:995 +#: ../../po/../src/dialogs/display-settings.cpp:1006 +#: ../../po/../src/helper/units.cpp:42 +msgid "px" +msgstr "px" + +#: ../../po/../src/dialogs/display-settings.cpp:993 +msgid "> and < scale by:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:994 +msgid "" +"Pressing > or < scales selection up or down by this increment (in px units)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1004 +msgid "Inset/Outset by:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1005 +msgid "" +"Inset and Outset commands displace the path by this distance (in px units)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1017 +msgid "Compass-like display of angles" +msgstr "" + +#. TRANSLATORS: "positive clockwise" means "increasing in clockwise direction" +#: ../../po/../src/dialogs/display-settings.cpp:1019 +msgid "" +"When on, angles are displayed with 0 at north, 0 to 360 range, positive " +"clockwise; otherwise with 0 at east, -180 to 180 range, positive " +"counterclockwise" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1026 +#, fuzzy +msgid "Zoom in/out by:" +msgstr "缩小" + +#: ../../po/../src/dialogs/display-settings.cpp:1027 +msgid "" +"Zoom tool click, +/- keys, and middle click zoom in and out by this " +"multiplier" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1028 +#: ../../po/../src/helper/units.cpp:44 +msgid "%" +msgstr "%" + +#. Tools +#: ../../po/../src/dialogs/display-settings.cpp:1037 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:58 +msgid "Tools" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1045 +#, fuzzy +msgid "Selector" +msgstr "选择" + +#: ../../po/../src/dialogs/display-settings.cpp:1056 +msgid "Node" +msgstr "节点" + +#: ../../po/../src/dialogs/display-settings.cpp:1064 +#: ../../po/../src/verbs.cpp:2073 +#: ../../po/../src/widgets/desktop-widget.cpp:277 +msgid "Zoom" +msgstr "缩放" + +#. The 4 shape tools +#: ../../po/../src/dialogs/display-settings.cpp:1071 +#, fuzzy +msgid "Shapes" +msgstr "形状" + +#: ../../po/../src/dialogs/display-settings.cpp:1079 +#: ../../po/../src/verbs.cpp:2055 +msgid "Rectangle" +msgstr "长方形" + +#: ../../po/../src/dialogs/display-settings.cpp:1085 +#: ../../po/../src/verbs.cpp:2057 +msgid "Ellipse" +msgstr "椭圆" + +#: ../../po/../src/dialogs/display-settings.cpp:1091 +#: ../../po/../src/verbs.cpp:2059 +msgid "Star" +msgstr "星形" + +#: ../../po/../src/dialogs/display-settings.cpp:1097 +#: ../../po/../src/verbs.cpp:2061 +msgid "Spiral" +msgstr "螺旋形" + +#: ../../po/../src/dialogs/display-settings.cpp:1111 +#: ../../po/../src/verbs.cpp:2063 +msgid "Pencil" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1114 +msgid "Tolerance:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1115 +msgid "" +"This value affects the amount of smoothing applied to freehand lines; lower " +"values produce more uneven paths with more nodes" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1131 +#: ../../po/../src/verbs.cpp:2065 +#, fuzzy +msgid "Pen" +msgstr "百分比" + +#: ../../po/../src/dialogs/display-settings.cpp:1140 +#: ../../po/../src/verbs.cpp:2067 +msgid "Calligraphy" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1147 +#: ../../po/../src/dialogs/text-edit.cpp:353 +#: ../../po/../src/ui/dialog/text-properties.cpp:37 +#: ../../po/../src/verbs.cpp:2069 +msgid "Text" +msgstr "文本" + +#: ../../po/../src/dialogs/display-settings.cpp:1157 +#: ../../po/../src/verbs.cpp:2071 +#, fuzzy +msgid "Gradient" +msgstr "渐变填充" + +#: ../../po/../src/dialogs/display-settings.cpp:1164 +#: ../../po/../src/verbs.cpp:2077 +#, fuzzy +msgid "Connector" +msgstr "关闭视图" + +#: ../../po/../src/dialogs/display-settings.cpp:1171 +#: ../../po/../src/verbs.cpp:2075 +msgid "Dropper" +msgstr "" + +#. Windows +#: ../../po/../src/dialogs/display-settings.cpp:1183 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:59 +msgid "Windows" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1188 +#, fuzzy +msgid "Save window geometry" +msgstr "内存文档 %d" + +#: ../../po/../src/dialogs/display-settings.cpp:1189 +msgid "" +"Save the window size and position with each document (only for Inkscape SVG " +"format)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1196 +msgid "Dialogs are hidden in taskbar" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1197 +msgid "Whether dialog windows are to be hidden in the window manager taskbar" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1204 +msgid "Zoom when window is resized" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1205 +msgid "" +"Zoom drawing when document window is resized, to keep the same area visible " +"(this is the default which can be changed in any window using the button " +"above the right scrollbar)" +msgstr "" + +#. Clones +#: ../../po/../src/dialogs/display-settings.cpp:1213 +#: ../../po/../src/dialogs/find.cpp:624 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:60 +#, fuzzy +msgid "Clones" +msgstr "关闭视图" + +#: ../../po/../src/dialogs/display-settings.cpp:1217 +msgid "When the original moves, its clones and linked offsets:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1229 +msgid "Move in parallel" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1230 +msgid "Clones are translated by the same vector as their original." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1237 +msgid "Stay unmoved" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1238 +msgid "Clones preserve their positions when their original is moved." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1245 +msgid "Move according to transform" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1246 +msgid "" +"Each clone moves according to the value of its transform= attribute. For " +"example, a rotated clone will move in a different direction than its " +"original." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1255 +msgid "When the original is deleted, its clones:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1267 +msgid "Are unlinked" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1267 +msgid "Orphaned clones are converted to regular objects." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1273 +#, fuzzy +msgid "Are deleted" +msgstr "第一个选择" + +#: ../../po/../src/dialogs/display-settings.cpp:1273 +msgid "Orphaned clones are deleted along with their original." +msgstr "" + +#. Transforms +#. TRANSLATORS: Noun, i.e. transformations. +#: ../../po/../src/dialogs/display-settings.cpp:1289 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:61 +#, fuzzy +msgid "Transforms" +msgstr "变换" + +#: ../../po/../src/dialogs/display-settings.cpp:1292 +#, fuzzy +msgid "Scale stroke width" +msgstr "勾描宽度" + +#: ../../po/../src/dialogs/display-settings.cpp:1293 +#: ../../po/../src/widgets/select-toolbar.cpp:568 +msgid "When scaling objects, scale the stroke width by the same proportion" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1300 +msgid "Scale rounded corners in rectangles" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1301 +#: ../../po/../src/widgets/select-toolbar.cpp:580 +msgid "When scaling rectangles, scale the radii of rounded corners" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1308 +#, fuzzy +msgid "Transform gradients" +msgstr "变换" + +#: ../../po/../src/dialogs/display-settings.cpp:1309 +#: ../../po/../src/widgets/select-toolbar.cpp:592 +msgid "Transform gradients (in fill or stroke) along with the objects" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1316 +#, fuzzy +msgid "Transform patterns" +msgstr "转化" + +#: ../../po/../src/dialogs/display-settings.cpp:1317 +#: ../../po/../src/widgets/select-toolbar.cpp:604 +msgid "Transform patterns (in fill or stroke) along with the objects" +msgstr "" + +#. TRANSLATORS: How to specify the affine transformation in the SVG file. +#: ../../po/../src/dialogs/display-settings.cpp:1327 +#, fuzzy +msgid "Store transformation:" +msgstr "重置变换" + +#: ../../po/../src/dialogs/display-settings.cpp:1338 +msgid "Optimized" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1339 +msgid "" +"If possible, apply transformation to objects without adding a transform= " +"attribute" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1346 +msgid "Preserved" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1347 +msgid "Always store transformation as a transform= attribute on objects" +msgstr "" + +#. Selecting +#: ../../po/../src/dialogs/display-settings.cpp:1355 +#, fuzzy +msgid "Selecting" +msgstr "选择" + +#: ../../po/../src/dialogs/display-settings.cpp:1357 +msgid "Ctrl+A, Tab, Shift+Tab:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1366 +#, fuzzy +msgid "Select only within current layer" +msgstr "选择" + +#: ../../po/../src/dialogs/display-settings.cpp:1367 +msgid "" +"Uncheck this to make keyboard selection commands work on objects in all " +"layers" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1374 +msgid "Ignore hidden objects" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1375 +msgid "" +"Uncheck this to be able to select objects that are hidden (either by " +"themselves or by being in a hidden group or layer)" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1382 +#, fuzzy +msgid "Ignore locked objects" +msgstr "翻转选中对象" + +#: ../../po/../src/dialogs/display-settings.cpp:1383 +msgid "" +"Uncheck this to be able to select objects that are locked (either by " +"themselves or by being in a locked group or layer)" +msgstr "" + +#. To be broken into: Display, Save, Export, SVG, Commands +#: ../../po/../src/dialogs/display-settings.cpp:1391 +#: ../../po/../src/ui/dialog/inkscape-preferences.cpp:62 +msgid "Misc" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1394 +msgid "Default export resolution:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1395 +msgid "Default bitmap resolution (in dots per inch) in the Export dialog" +msgstr "" + +#. FIXME: add "Used for new exports; once exported, documents remember this value on per-object basis" when implemented +#: ../../po/../src/dialogs/display-settings.cpp:1396 +#: ../../po/../src/dialogs/export.cpp:442 +msgid "dpi" +msgstr "dpi" + +#. TRANSLATORS: When on, an imported bitmap creates an element; otherwise it is a +#. * rectangle with bitmap fill. +#: ../../po/../src/dialogs/display-settings.cpp:1407 +msgid "Import bitmap as " +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1408 +msgid "" +"When on, an imported bitmap creates an element; otherwise it is a " +"rectangle with bitmap fill" +msgstr "" + +#. TRANSLATORS: When on, the print out (currently Postscript) will have +#. * a comment with the each object's label visible, marking the section +#. * of the printing commands that represent the given object. +#: ../../po/../src/dialogs/display-settings.cpp:1418 +msgid "Add label comments to printing output" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1419 +msgid "" +"When on, a comment will be added to the raw print output, marking the " +"rendered output for an object with its label" +msgstr "" + +#. TRANSLATORS: When on, enable the effects menu, default is off +#: ../../po/../src/dialogs/display-settings.cpp:1427 +msgid "Enable script effects (requires restart) - EXPERIMENTAL" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1428 +msgid "" +"When on, the effects menu is enabled, allowing external effect scripts to be " +"called, requires restart before effective - EXPERIMENTAL" +msgstr "" + +#. TRANSLATORS: The maximum length of the Open Recent list in the File menu. +#: ../../po/../src/dialogs/display-settings.cpp:1436 +#, fuzzy +msgid "Max recent documents:" +msgstr "未命名文档 %d" + +#: ../../po/../src/dialogs/display-settings.cpp:1437 +msgid "The maximum length of the Open Recent list in the File menu" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1447 +msgid "Simplification threshold:" +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1448 +msgid "" +"How strong is the Simplify command by default. If you invoke this command " +"several times in quick succession, it will act more and more aggressively; " +"invoking it again after a pause restores the default threshold." +msgstr "" + +#: ../../po/../src/dialogs/display-settings.cpp:1469 +msgid "Oversample bitmaps:" +msgstr "超取样位图:" + +#: ../../po/../src/dialogs/display-settings.cpp:1488 +msgid "2x2" +msgstr "2x2" + +#: ../../po/../src/dialogs/display-settings.cpp:1494 +msgid "4x4" +msgstr "4x4" + +#: ../../po/../src/dialogs/display-settings.cpp:1500 +msgid "8x8" +msgstr "8x8" + +#: ../../po/../src/dialogs/display-settings.cpp:1506 +msgid "16x16" +msgstr "16x16" + +#. "view_icon_preview" +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2143 +msgid "_Page" +msgstr "页(_P)" + +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2147 +msgid "_Drawing" +msgstr "绘图(_D)" + +#: ../../po/../src/dialogs/export.cpp:133 ../../po/../src/verbs.cpp:2149 +msgid "_Selection" +msgstr "选择(_S)" + +#: ../../po/../src/dialogs/export.cpp:133 +#, fuzzy +msgid "_Custom" +msgstr "定制" + +#: ../../po/../src/dialogs/export.cpp:254 +#, fuzzy +msgid "Export area" +msgstr "导出为" + +#: ../../po/../src/dialogs/export.cpp:300 +#, fuzzy +msgid "_x0:" +msgstr "T0:" + +#: ../../po/../src/dialogs/export.cpp:305 +#, fuzzy +msgid "x_1:" +msgstr "R1:" + +#: ../../po/../src/dialogs/export.cpp:316 +#, fuzzy +msgid "_y0:" +msgstr "T0:" + +#: ../../po/../src/dialogs/export.cpp:321 +#, fuzzy +msgid "y_1:" +msgstr "R1:" + +#: ../../po/../src/dialogs/export.cpp:406 +#, fuzzy +msgid "Bitmap size" +msgstr "图像大小" + +#: ../../po/../src/dialogs/export.cpp:416 +#, fuzzy +msgid "_Width:" +msgstr "宽度:" + +#: ../../po/../src/dialogs/export.cpp:416 +#: ../../po/../src/dialogs/export.cpp:431 +#, fuzzy +msgid "pixels at" +msgstr "像素" + +#: ../../po/../src/dialogs/export.cpp:426 +#, fuzzy +msgid "dp_i" +msgstr "dpi" + +#: ../../po/../src/dialogs/export.cpp:448 +#, fuzzy +msgid "_Filename" +msgstr "文件名:" + +#: ../../po/../src/dialogs/export.cpp:512 +msgid "_Browse..." +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:539 +#, fuzzy +msgid " _Export " +msgstr "改变" + +#: ../../po/../src/dialogs/export.cpp:541 +msgid "Export the bitmap file with these settings" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:968 +#, fuzzy +msgid "You have to enter a filename" +msgstr "以新文件名保存图画" + +#: ../../po/../src/dialogs/export.cpp:973 +msgid "The chosen area to be exported is invalid" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:982 +#, c-format +msgid "Directory %s does not exist or is not a directory.\n" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:998 +#, fuzzy +msgid "Export in progress" +msgstr "导出为" + +#: ../../po/../src/dialogs/export.cpp:1004 +#, c-format +msgid "Exporting %s (%d x %d)" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:1031 +#, c-format +msgid "Could not export to filename %s.\n" +msgstr "" + +#: ../../po/../src/dialogs/export.cpp:1137 +#, fuzzy +msgid "Select a filename for exporting" +msgstr "选择需导入的文件" + +#: ../../po/../src/dialogs/filedialog.cpp:367 +#, fuzzy +msgid "No preview" +msgstr "新建预览" + +#: ../../po/../src/dialogs/filedialog.cpp:468 +msgid "too large for preview" +msgstr "" + +#: ../../po/../src/dialogs/filedialog.cpp:762 +#: ../../po/../src/dialogs/filedialog.cpp:763 +#, fuzzy +msgid "All Images" +msgstr "图像" + +#: ../../po/../src/dialogs/filedialog.cpp:767 +#: ../../po/../src/dialogs/filedialog.cpp:768 +#, fuzzy +msgid "All Files" +msgstr "填充模式" + +#: ../../po/../src/dialogs/filedialog.cpp:774 +#: ../../po/../src/dialogs/filedialog.cpp:775 +#, fuzzy +msgid "All Inkscape Files" +msgstr "Sodipodi:%s:%s:%d" + +#: ../../po/../src/dialogs/filedialog.cpp:1176 +#, fuzzy +msgid "Guess from extension" +msgstr "变换选择" + +#. ###### Add the file types menu +#. createFilterMenu(); +#. ###### Do we want the .xxx extension automatically added? +#: ../../po/../src/dialogs/filedialog.cpp:1261 +msgid "Append filename extension automatically" +msgstr "" + +#. TRANSLATORS: "%s" is replaced with "exact" or "partial" when this string is displayed +#: ../../po/../src/dialogs/find.cpp:378 +#, fuzzy, c-format +msgid "%d object found (out of %d), %s match." +msgid_plural "%d objects found (out of %d), %s match." +msgstr[0] "使选定节点处成为光滑线段" +msgstr[1] "使选定节点处成为光滑线段" + +#: ../../po/../src/dialogs/find.cpp:381 +#, fuzzy +msgid "exact" +msgstr "文本" + +#: ../../po/../src/dialogs/find.cpp:381 +#, fuzzy +msgid "partial" +msgstr "螺旋形" + +#: ../../po/../src/dialogs/find.cpp:388 +#, fuzzy +msgid "No objects found" +msgstr "无对象" + +#: ../../po/../src/dialogs/find.cpp:546 +#, fuzzy +msgid "T_ype: " +msgstr "类型:" + +#: ../../po/../src/dialogs/find.cpp:553 +msgid "Search in all object types" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:553 +#, fuzzy +msgid "All types" +msgstr "填充模式" + +#: ../../po/../src/dialogs/find.cpp:564 +msgid "Search all shapes" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:564 +msgid "All shapes" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:581 +#, fuzzy +msgid "Search rectangles" +msgstr "长方形" + +#: ../../po/../src/dialogs/find.cpp:581 +#, fuzzy +msgid "Rectangles" +msgstr "长方形" + +#: ../../po/../src/dialogs/find.cpp:586 +msgid "Search ellipses, arcs, circles" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:586 +#, fuzzy +msgid "Ellipses" +msgstr "椭圆" + +#: ../../po/../src/dialogs/find.cpp:591 +msgid "Search stars and polygons" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:591 +#, fuzzy +msgid "Stars" +msgstr "星形" + +#: ../../po/../src/dialogs/find.cpp:596 +#, fuzzy +msgid "Search spirals" +msgstr "绘制螺旋" + +#: ../../po/../src/dialogs/find.cpp:596 +#, fuzzy +msgid "Spirals" +msgstr "螺旋形" + +#. TRANSLATORS: polyline is a set of connected straight line segments +#. http://www.w3.org/TR/SVG11/shapes.html#PolylineElement +#: ../../po/../src/dialogs/find.cpp:609 +msgid "Search paths, lines, polylines" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:609 +msgid "Paths" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:614 +#, fuzzy +msgid "Search text objects" +msgstr "翻转选中对象" + +#: ../../po/../src/dialogs/find.cpp:614 +#, fuzzy +msgid "Texts" +msgstr "文本" + +#: ../../po/../src/dialogs/find.cpp:619 +msgid "Search groups" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:619 +#, fuzzy +msgid "Groups" +msgstr "组" + +#: ../../po/../src/dialogs/find.cpp:624 +msgid "Search clones" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:629 +msgid "Search images" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:629 +#, fuzzy +msgid "Images" +msgstr "图像" + +#: ../../po/../src/dialogs/find.cpp:634 +#, fuzzy +msgid "Search offset objects" +msgstr "翻转选中对象" + +#: ../../po/../src/dialogs/find.cpp:634 +msgid "Offsets" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:694 +#, fuzzy +msgid "_Text: " +msgstr "文本" + +#: ../../po/../src/dialogs/find.cpp:694 +msgid "Find objects by their text content (exact or partial match)" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:695 +msgid "_ID: " +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:695 +msgid "Find objects by the value of the id attribute (exact or partial match)" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:696 +#, fuzzy +msgid "_Style: " +msgstr " 风格 " + +#: ../../po/../src/dialogs/find.cpp:696 +msgid "" +"Find objects by the value of the style attribute (exact or partial match)" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:697 +#, fuzzy +msgid "_Attribute: " +msgstr "属性:" + +#: ../../po/../src/dialogs/find.cpp:697 +msgid "Find objects by the name of an attribute (exact or partial match)" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:711 +#, fuzzy +msgid "Search in s_election" +msgstr "缩放到选中内容" + +#: ../../po/../src/dialogs/find.cpp:715 +msgid "Limit search to the current selection" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:720 +#, fuzzy +msgid "Search in current _layer" +msgstr "选择" + +#: ../../po/../src/dialogs/find.cpp:724 +#, fuzzy +msgid "Limit search to the current layer" +msgstr "选择" + +#: ../../po/../src/dialogs/find.cpp:729 +msgid "Include _hidden" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:733 +msgid "Include hidden objects in search" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:738 +msgid "Include l_ocked" +msgstr "" + +#: ../../po/../src/dialogs/find.cpp:742 +#, fuzzy +msgid "Include locked objects in search" +msgstr "翻转选中对象" + +#: ../../po/../src/dialogs/find.cpp:753 +#, fuzzy +msgid "Clear values" +msgstr "色彩填充" + +#: ../../po/../src/dialogs/find.cpp:754 +#, fuzzy +msgid "_Find" +msgstr "栅格" + +#: ../../po/../src/dialogs/find.cpp:754 +msgid "Select objects matching all of the fields you filled in" +msgstr "" + +#: ../../po/../src/dialogs/iconpreview.cpp:145 +#, c-format +msgid "%d x %d" +msgstr "" + +#: ../../po/../src/dialogs/iconpreview.cpp:193 +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:857 +#: ../../po/../src/widgets/desktop-widget.cpp:1069 +msgid "Selection" +msgstr "选择" + +#: ../../po/../src/dialogs/iconpreview.cpp:195 +#, fuzzy +msgid "Selection only or whole document" +msgstr "选择" + +#: ../../po/../src/dialogs/iconpreview.cpp:203 +msgid "Refresh the icons" +msgstr "" + +#. Create the label for the object id +#: ../../po/../src/dialogs/item-properties.cpp:126 +#: ../../po/../src/dialogs/item-properties.cpp:327 +#: ../../po/../src/dialogs/item-properties.cpp:396 +#: ../../po/../src/dialogs/item-properties.cpp:403 +msgid "_Id" +msgstr "" + +#: ../../po/../src/dialogs/item-properties.cpp:135 +msgid "" +"The id= attribute (only letters, digits, and the characters .-_: allowed)" +msgstr "" + +#. Button for setting the object's id, label, title and description. +#: ../../po/../src/dialogs/item-properties.cpp:149 +#, fuzzy +msgid "_Set" +msgstr "选择" + +#. Create the label for the object label +#: ../../po/../src/dialogs/item-properties.cpp:158 +#, fuzzy +msgid "_Label" +msgstr "删除属性" + +#: ../../po/../src/dialogs/item-properties.cpp:167 +msgid "A freeform label for the object" +msgstr "" + +#. Create the label for the object title +#: ../../po/../src/dialogs/item-properties.cpp:179 +#: ../../po/../src/dialogs/rdf.cpp:243 +#, fuzzy +msgid "Title" +msgstr "标题:" + +#. Create the frame for the object description +#: ../../po/../src/dialogs/item-properties.cpp:196 +#: ../../po/../src/dialogs/rdf.cpp:287 +#, fuzzy +msgid "Description" +msgstr "位置" + +#. Hide +#: ../../po/../src/dialogs/item-properties.cpp:223 +#, fuzzy +msgid "_Hide" +msgstr "边:" + +#: ../../po/../src/dialogs/item-properties.cpp:224 +msgid "Check to make the object invisible" +msgstr "" + +#. Lock +#. TRANSLATORS: "Lock" is a verb here +#: ../../po/../src/dialogs/item-properties.cpp:233 +msgid "L_ock" +msgstr "" + +#: ../../po/../src/dialogs/item-properties.cpp:234 +msgid "Check to make the object insensitive (not selectable by mouse)" +msgstr "" + +#: ../../po/../src/dialogs/item-properties.cpp:310 +#: ../../po/../src/dialogs/item-properties.cpp:317 +msgid "Ref" +msgstr "" + +#: ../../po/../src/dialogs/item-properties.cpp:398 +#, fuzzy +msgid "Id invalid! " +msgstr "标识合法" + +#: ../../po/../src/dialogs/item-properties.cpp:400 +msgid "Id exists! " +msgstr "" + +#: ../../po/../src/dialogs/layer-properties.cpp:50 +msgid "Layer name:" +msgstr "" + +#: ../../po/../src/dialogs/layer-properties.cpp:133 +#, fuzzy +msgid "Rename Layer" +msgstr "提升" + +#: ../../po/../src/dialogs/layer-properties.cpp:136 +#, fuzzy +msgid "_Rename" +msgstr "文件名:" + +#. TRANSLATORS: This means "The layer has been renamed" +#: ../../po/../src/dialogs/layer-properties.cpp:147 +#, fuzzy +msgid "Renamed layer" +msgstr "提升" + +#: ../../po/../src/dialogs/layer-properties.cpp:151 +#, fuzzy +msgid "Add Layer" +msgstr "降低" + +#: ../../po/../src/dialogs/layer-properties.cpp:153 +#, fuzzy +msgid "_Add" +msgstr "添加" + +#: ../../po/../src/dialogs/layer-properties.cpp:167 +msgid "New layer created." +msgstr "" + +#: ../../po/../src/dialogs/object-attributes.cpp:34 +msgid "Href:" +msgstr "Href:" + +#: ../../po/../src/dialogs/object-attributes.cpp:35 +msgid "Target:" +msgstr "目标:" + +#: ../../po/../src/dialogs/object-attributes.cpp:36 +msgid "Type:" +msgstr "类型:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkRoleAttribute +#. Identifies the type of the related resource with an absolute URI +#: ../../po/../src/dialogs/object-attributes.cpp:39 +msgid "Role:" +msgstr "作用:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkArcRoleAttribute +#. For situations where the nature/role alone isn't enough, this offers an additional URI defining the purpose of the link. +#: ../../po/../src/dialogs/object-attributes.cpp:42 +msgid "Arcrole:" +msgstr "弓形作用:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkTitleAttribute +#: ../../po/../src/dialogs/object-attributes.cpp:44 +msgid "Title:" +msgstr "标题:" + +#: ../../po/../src/dialogs/object-attributes.cpp:45 +msgid "Show:" +msgstr "显示:" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkActuateAttribute +#: ../../po/../src/dialogs/object-attributes.cpp:47 +msgid "Actuate:" +msgstr "促使:" + +#: ../../po/../src/dialogs/object-attributes.cpp:52 +msgid "URL:" +msgstr "URL:" + +#: ../../po/../src/dialogs/object-attributes.cpp:53 +msgid "X:" +msgstr "X:" + +#: ../../po/../src/dialogs/object-attributes.cpp:54 +msgid "Y:" +msgstr "Y:" + +#: ../../po/../src/dialogs/object-attributes.cpp:98 +#, c-format +msgid "%s attributes" +msgstr "%s 属性" + +#: ../../po/../src/dialogs/object-properties.cpp:158 +#, fuzzy +msgid "_Fill" +msgstr "填充" + +#: ../../po/../src/dialogs/object-properties.cpp:165 +#, fuzzy +msgid "Stroke _paint" +msgstr "勾描宽度" + +#: ../../po/../src/dialogs/object-properties.cpp:172 +#, fuzzy +msgid "Stroke st_yle" +msgstr "勾描设置" + +#: ../../po/../src/dialogs/object-properties.cpp:183 +#, fuzzy +msgid "Master _opacity" +msgstr "不透明度:" + +#: ../../po/../src/dialogs/rdf.cpp:244 +msgid "Name by which this document is formally known." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:246 +#, fuzzy +msgid "Date" +msgstr "绘制文本" + +#: ../../po/../src/dialogs/rdf.cpp:247 +msgid "Date associated with the creation of this document (YYYY-MM-DD)." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:249 +msgid "Format" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:250 +msgid "The physical or digital manifestation of this document (MIME type)." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:252 +#, fuzzy +msgid "Type" +msgstr "类型:" + +#: ../../po/../src/dialogs/rdf.cpp:253 +msgid "Type of document (DCMI Type)." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:256 +#, fuzzy +msgid "Creator" +msgstr "创建连接" + +#: ../../po/../src/dialogs/rdf.cpp:257 +msgid "" +"Name of entity primarily responsible for making the content of this document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:259 +#, fuzzy +msgid "Rights" +msgstr "高度" + +#: ../../po/../src/dialogs/rdf.cpp:260 +msgid "" +"Name of entity with rights to the Intellectual Property of this document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:262 +msgid "Publisher" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:263 +msgid "Name of entity responsible for making this document available." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:266 +#, fuzzy +msgid "Identifier" +msgstr "中央" + +#: ../../po/../src/dialogs/rdf.cpp:267 +msgid "Unique URI to reference this document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:269 +msgid "Source" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:270 +msgid "Unique URI to reference the source of this document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:272 +#, fuzzy +msgid "Relation" +msgstr "旋转:" + +#: ../../po/../src/dialogs/rdf.cpp:273 +#, fuzzy +msgid "Unique URI to a related document." +msgstr "未命名文档 %d" + +#: ../../po/../src/dialogs/rdf.cpp:275 +#, fuzzy +msgid "Language" +msgstr "角度" + +#: ../../po/../src/dialogs/rdf.cpp:276 +msgid "" +"Two-letter language tag with optional subtags for the language of this " +"document. (e.g. 'en-GB')" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:278 +msgid "Keywords" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:279 +msgid "" +"The topic of this document as comma-separated key words, phrases, or " +"classifications." +msgstr "" + +#. TRANSLATORS: "Coverage": the spatial or temporal characteristics of the content. +#. For info, see Appendix D of http://www.w3.org/TR/1998/WD-rdf-schema-19980409/ +#: ../../po/../src/dialogs/rdf.cpp:283 +msgid "Coverage" +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:284 +msgid "Extent or scope of this document." +msgstr "" + +#: ../../po/../src/dialogs/rdf.cpp:288 +msgid "A short account of the content of this document." +msgstr "" + +#. FIXME: need to handle 1 agent per line of input +#: ../../po/../src/dialogs/rdf.cpp:292 +#, fuzzy +msgid "Contributors" +msgstr "厘米" + +#: ../../po/../src/dialogs/rdf.cpp:293 +msgid "" +"Names of entities responsible for making contributions to the content of " +"this document." +msgstr "" + +#. TRANSLATORS: URL to a page that defines the license for the document +#: ../../po/../src/dialogs/rdf.cpp:297 +msgid "URI" +msgstr "" + +#. TRANSLATORS: this is where you put a URL to a page that defines the license +#: ../../po/../src/dialogs/rdf.cpp:299 +msgid "URI to this document's license's namespace definition." +msgstr "" + +#. TRANSLATORS: fragment of XML representing the license of the document +#: ../../po/../src/dialogs/rdf.cpp:303 +#, fuzzy +msgid "Fragment" +msgstr "参数:" + +#: ../../po/../src/dialogs/rdf.cpp:304 +msgid "XML fragment for the RDF 'License' section." +msgstr "" + +#: ../../po/../src/dialogs/stroke-style.cpp:774 +#: ../../po/../src/widgets/gradient-vector.cpp:263 +#: ../../po/../src/widgets/paint-selector.cpp:751 +msgid "No document selected" +msgstr "未选择文档" + +#: ../../po/../src/dialogs/stroke-style.cpp:992 +#, fuzzy +msgid "Stroke width" +msgstr "勾描宽度" + +#. Join type +#. TRANSLATORS: The line join style specifies the shape to be used at the +#. corners of paths. It can be "miter", "round" or "bevel". +#: ../../po/../src/dialogs/stroke-style.cpp:1015 +msgid "Join:" +msgstr "连接:" + +#. TRANSLATORS: Miter join: joining lines with a sharp (pointed) corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1027 +msgid "Miter join" +msgstr "斜角连接" + +#. TRANSLATORS: Round join: joining lines with a rounded corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1035 +msgid "Round join" +msgstr "圆形连接" + +#. TRANSLATORS: Bevel join: joining lines with a blunted (flattened) corner. +#. For an example, draw a triangle with a large stroke width and modify the +#. "Join" option (in the Fill and Stroke dialog). +#: ../../po/../src/dialogs/stroke-style.cpp:1043 +msgid "Bevel join" +msgstr "斜削连接" + +#. Miterlimit +#. TRANSLATORS: Miter limit: only for "miter join", this limits the length +#. of the sharp "spike" when the lines connect at too sharp an angle. +#. When two line segments meet at a sharp angle, a miter join results in a +#. spike that extends well beyond the connection point. The purpose of the +#. miter limit is to cut off such spikes (i.e. convert them into bevels) +#. when they become too long. +#: ../../po/../src/dialogs/stroke-style.cpp:1054 +#, fuzzy +msgid "Miter limit:" +msgstr "斜角连接" + +#: ../../po/../src/dialogs/stroke-style.cpp:1062 +msgid "Maximum length of the miter (in units of stroke width)" +msgstr "" + +#. Cap type +#. TRANSLATORS: cap type specifies the shape for the ends of lines +#: ../../po/../src/dialogs/stroke-style.cpp:1075 +#, fuzzy +msgid "Cap:" +msgstr "青蓝:" + +#. TRANSLATORS: Butt cap: the line shape does not extend beyond the end point +#. of the line; the ends of the line are square +#: ../../po/../src/dialogs/stroke-style.cpp:1086 +msgid "Butt cap" +msgstr "" + +#. TRANSLATORS: Round cap: the line shape extends beyond the end point of the +#. line; the ends of the line are rounded +#: ../../po/../src/dialogs/stroke-style.cpp:1093 +#, fuzzy +msgid "Round cap" +msgstr "圆形连接" + +#. TRANSLATORS: Square cap: the line shape extends beyond the end point of the +#. line; the ends of the line are square +#: ../../po/../src/dialogs/stroke-style.cpp:1100 +#, fuzzy +msgid "Square cap" +msgstr "正方形端点" + +#. Dash +#: ../../po/../src/dialogs/stroke-style.cpp:1106 +msgid "Dashes:" +msgstr "" + +#. TRANSLATORS: Path markers are an SVG feature that allows you to attach arbitrary shapes +#. (arrowheads, bullets, faces, whatever) to the start, end, or middle nodes of a path. +#: ../../po/../src/dialogs/stroke-style.cpp:1127 +#, fuzzy +msgid "Start Markers:" +msgstr "星形属性" + +#: ../../po/../src/dialogs/stroke-style.cpp:1137 +msgid "Mid Markers:" +msgstr "" + +#: ../../po/../src/dialogs/stroke-style.cpp:1148 +msgid "End Markers:" +msgstr "" + +#: ../../po/../src/dialogs/swatches.cpp:424 +#, c-format +msgid "Palettes directory (%s) is unavailable." +msgstr "" + +#. TODO: Insert widgets +#: ../../po/../src/dialogs/text-edit.cpp:199 +#: ../../po/../src/ui/dialog/text-properties.cpp:36 +#, fuzzy +msgid "Font" +msgstr "点" + +#: ../../po/../src/dialogs/text-edit.cpp:216 +msgid "Layout" +msgstr "布局" + +#: ../../po/../src/dialogs/text-edit.cpp:229 +#, fuzzy +msgid "Align lines left" +msgstr "对齐到顶部左侧" + +#. TRANSLATORS: `Center' here is a verb. +#: ../../po/../src/dialogs/text-edit.cpp:243 +#, fuzzy +msgid "Center lines" +msgstr "Y 中心:" + +#: ../../po/../src/dialogs/text-edit.cpp:256 +#, fuzzy +msgid "Align lines right" +msgstr "对齐到顶部右侧" + +#: ../../po/../src/dialogs/text-edit.cpp:278 +#, fuzzy +msgid "Horizontal text" +msgstr "水平移动" + +#: ../../po/../src/dialogs/text-edit.cpp:292 +#, fuzzy +msgid "Vertical text" +msgstr "垂直中心值" + +#: ../../po/../src/dialogs/text-edit.cpp:307 +#, fuzzy +msgid "Line spacing:" +msgstr "X 间据:" + +#: ../../po/../src/dialogs/text-edit.cpp:400 +msgid "Set as default" +msgstr "" + +#: ../../po/../src/dialogs/tiledialog.cpp:603 +#, fuzzy +msgid "Rows:" +msgstr "显示:" + +#: ../../po/../src/dialogs/tiledialog.cpp:613 +msgid "Number of rows" +msgstr "" + +#: ../../po/../src/dialogs/tiledialog.cpp:617 +#, fuzzy +msgid "Equal height" +msgstr "高度:" + +#: ../../po/../src/dialogs/tiledialog.cpp:627 +msgid "If not set, each row has the height of the tallest object in it" +msgstr "" + +#. #### Radio buttons to control vertical alignment #### +#. #### Radio buttons to control horizontal alignment #### +#: ../../po/../src/dialogs/tiledialog.cpp:637 +#: ../../po/../src/dialogs/tiledialog.cpp:708 +#, fuzzy +msgid "Align:" +msgstr "对齐" + +#: ../../po/../src/dialogs/tiledialog.cpp:672 +#, fuzzy +msgid " X " +msgstr "X +" + +#. #### Number of columns #### +#: ../../po/../src/dialogs/tiledialog.cpp:678 +#, fuzzy +msgid "Columns:" +msgstr "改变" + +#: ../../po/../src/dialogs/tiledialog.cpp:688 +msgid "Number of columns" +msgstr "" + +#: ../../po/../src/dialogs/tiledialog.cpp:692 +#, fuzzy +msgid "Equal width" +msgstr "宽度:" + +#: ../../po/../src/dialogs/tiledialog.cpp:701 +msgid "If not set, each column has the width of the widest object in it" +msgstr "" + +#. #### Radio buttons to control spacing manually or to fit selection bbox #### +#: ../../po/../src/dialogs/tiledialog.cpp:746 +#, fuzzy +msgid "Fit into selection box" +msgstr "剪切选中内容" + +#: ../../po/../src/dialogs/tiledialog.cpp:753 +#, fuzzy +msgid "Set spacing:" +msgstr "Y 间据:" + +#. #### Y Padding #### +#: ../../po/../src/dialogs/tiledialog.cpp:777 +#, fuzzy +msgid "Row spacing: " +msgstr "X 间据:" + +#: ../../po/../src/dialogs/tiledialog.cpp:786 +#, fuzzy +msgid "Vertical spacing between rows" +msgstr "垂直中心值" + +#. #### X padding #### +#: ../../po/../src/dialogs/tiledialog.cpp:795 +#, fuzzy +msgid "Column spacing:" +msgstr "X 间据:" + +#: ../../po/../src/dialogs/tiledialog.cpp:804 +#, fuzzy +msgid "Horizontal spacing between columns" +msgstr "水平缩放值" + +#: ../../po/../src/dialogs/tiledialog.cpp:818 +#, fuzzy +msgid "Arrange selected objects" +msgstr "编组选中对象" + +#: ../../po/../src/dialogs/xml-tree.cpp:178 +msgid "Click to select nodes, drag to rearrange." +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:189 +msgid "Click attribute to edit." +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:193 +#, c-format +msgid "" +"Attribute %s selected. Press Ctrl+Enter when done editing to " +"commit changes." +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:284 +msgid "Drag to reorder nodes" +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:304 +#, fuzzy +msgid "New element node" +msgstr "内存文档 %d" + +#: ../../po/../src/dialogs/xml-tree.cpp:326 +msgid "New text node" +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:347 +#, fuzzy +msgid "Duplicate node" +msgstr "复制" + +#: ../../po/../src/dialogs/xml-tree.cpp:368 +#, fuzzy +msgid "Delete node" +msgstr "删除" + +#: ../../po/../src/dialogs/xml-tree.cpp:384 +#, fuzzy +msgid "Unindent node" +msgstr "编辑节点" + +#: ../../po/../src/dialogs/xml-tree.cpp:399 +#, fuzzy +msgid "Indent node" +msgstr "编辑节点" + +#: ../../po/../src/dialogs/xml-tree.cpp:411 +#, fuzzy +msgid "Raise node" +msgstr "提升" + +#: ../../po/../src/dialogs/xml-tree.cpp:423 +#, fuzzy +msgid "Lower node" +msgstr "降低" + +#: ../../po/../src/dialogs/xml-tree.cpp:468 +msgid "Delete attribute" +msgstr "删除属性" + +#. TRANSLATORS: "Attribute" is a noun here +#: ../../po/../src/dialogs/xml-tree.cpp:513 +#, fuzzy +msgid "Attribute name" +msgstr "属性:" + +#. TRANSLATORS: "Set" is a verb here +#: ../../po/../src/dialogs/xml-tree.cpp:533 +#, fuzzy +msgid "Set attribute" +msgstr "删除属性" + +#. TRANSLATORS: "Set" is a verb here +#: ../../po/../src/dialogs/xml-tree.cpp:535 +#, fuzzy +msgid "Set" +msgstr "选择" + +#. TRANSLATORS: "Attribute" is a noun here +#: ../../po/../src/dialogs/xml-tree.cpp:558 +#, fuzzy +msgid "Attribute value" +msgstr "属性" + +#: ../../po/../src/dialogs/xml-tree.cpp:1318 +msgid "New element node..." +msgstr "" + +#: ../../po/../src/dialogs/xml-tree.cpp:1339 +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:100 +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:98 +#, fuzzy +msgid "Cancel" +msgstr "改变" + +#: ../../po/../src/dialogs/xml-tree.cpp:1345 +#, fuzzy +msgid "Create" +msgstr "创建连接" + +#: ../../po/../src/dialogs/xml-tree.cpp:1458 +#, c-format +msgid "" +"Cannot set %s: Another element with value %s already exists!" +msgstr "" + +#: ../../po/../src/document.cpp:369 +#, fuzzy, c-format +msgid "New document %d" +msgstr "内存文档 %d" + +#: ../../po/../src/document.cpp:401 +#, c-format +msgid "Memory document %d" +msgstr "内存文档 %d" + +#: ../../po/../src/document.cpp:524 +#, c-format +msgid "Unnamed document %d" +msgstr "未命名文档 %d" + +#. We hit green anchor, closing Green-Blue-Red +#: ../../po/../src/draw-context.cpp:441 +msgid "Path is closed." +msgstr "" + +#. We hit bot start and end of single curve, closing paths +#: ../../po/../src/draw-context.cpp:456 +msgid "Closing path." +msgstr "" + +#. alpha of color under cursor, to show in the statusbar +#. locale-sensitive printf is OK, since this goes to the UI, not into SVG +#: ../../po/../src/dropper-context.cpp:354 +#, c-format +msgid " alpha %.3g" +msgstr "" + +#. where the color is picked, to show in the statusbar +#: ../../po/../src/dropper-context.cpp:356 +#, c-format +msgid ", averaged with radius %d" +msgstr "" + +#: ../../po/../src/dropper-context.cpp:356 +msgid " under cursor" +msgstr "" + +#. message, to show in the statusbar +#: ../../po/../src/dropper-context.cpp:358 +msgid "Release mouse to set color." +msgstr "" + +#: ../../po/../src/dropper-context.cpp:358 +#: ../../po/../src/tools-switch.cpp:207 +msgid "" +"Click to set fill, Shift+click to set stroke; drag to " +"average color in area; with Alt to pick inverse color; Ctrl+C " +"to copy the color under mouse to clipboard" +msgstr "" + +#: ../../po/../src/extension/dependency.cpp:244 +msgid "Dependency::" +msgstr "" + +#: ../../po/../src/extension/dependency.cpp:245 +#, fuzzy +msgid " type: " +msgstr "填充模式" + +#: ../../po/../src/extension/dependency.cpp:246 +#, fuzzy +msgid " location: " +msgstr "旋转:" + +#: ../../po/../src/extension/dependency.cpp:247 +msgid " string: " +msgstr "" + +#: ../../po/../src/extension/dependency.cpp:250 +#, fuzzy +msgid " description: " +msgstr "位置" + +#. static int i = 0; +#. std::cout << "Checking module[" << i++ << "]: " << name << std::endl; +#: ../../po/../src/extension/extension.cpp:244 +msgid "" +" This is caused by an improper .inx file for this extension. An improper ." +"inx file could have been caused by a faulty installation of Inkscape." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:247 +msgid "an ID was not defined for it." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:251 +msgid "there was no name defined for it." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:255 +msgid "the XML description of it got lost." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:259 +msgid "no implementation was defined for the extension." +msgstr "" + +#. std::cout << "Failed: " << *(_deps[i]) << std::endl; +#: ../../po/../src/extension/extension.cpp:266 +msgid "a dependency was not met." +msgstr "" + +#: ../../po/../src/extension/extension.cpp:286 +#, fuzzy +msgid "Extension \"" +msgstr "扩充:" + +#: ../../po/../src/extension/extension.cpp:286 +msgid "\" failed to load because " +msgstr "" + +#: ../../po/../src/extension/extension.cpp:565 +#, c-format +msgid "Could not create extension error log file '%s'" +msgstr "" + +#. This is some filler text, needs to change before relase +#: ../../po/../src/extension/error-file.cpp:56 +msgid "" +"One or more extensions failed to load\n" +"\n" +"The failed extensions have been skipped. Inkscape will continue to run " +"normally but those extensions will be unavailable. For details to " +"troubleshoot this problem, please refer to the error log located at: " +msgstr "" + +#. This is some filler text, needs to change before relase +#: ../../po/../src/extension/error-file.cpp:65 +msgid "Show dialog on startup" +msgstr "" + +#: ../../po/../src/extension/implementation/script.cpp:845 +msgid "" +"Inkscape has received an error from the script that it called. The text " +"returned with the error is included below. Inkscape will continue working, " +"but the action you requested has been cancelled." +msgstr "" + +#: ../../po/../src/extension/implementation/script.cpp:858 +msgid "" +"Inkscape has received additional data from the script executed. The script " +"did not return an error, but this may indicate the results will not be as " +"expected." +msgstr "" + +#: ../../po/../src/extension/init.cpp:173 +msgid "Null external module directory name. Modules will not be loaded." +msgstr "" + +#: ../../po/../src/extension/init.cpp:187 +#, c-format +msgid "" +"Modules directory (%s) is unavailable. External modules in that directory " +"will not be loaded." +msgstr "" + +#: ../../po/../src/extension/internal/gnome.cpp:80 +#, fuzzy +msgid "Select printer" +msgstr "选择" + +#: ../../po/../src/extension/internal/gnome.cpp:131 +#, fuzzy +msgid "Inkscape: Print Preview" +msgstr "Sodipodi (文档名 %s..):打印预览" + +#: ../../po/../src/extension/internal/grid.cpp:213 +#, fuzzy +msgid "Line Width" +msgstr "宽度" + +#: ../../po/../src/extension/internal/grid.cpp:214 +#, fuzzy +msgid "Horizontal Spacing" +msgstr "水平移动" + +#: ../../po/../src/extension/internal/grid.cpp:215 +#, fuzzy +msgid "Vertical Spacing" +msgstr "垂直中心值" + +#: ../../po/../src/extension/internal/grid.cpp:216 +#, fuzzy +msgid "Horizontal Offset" +msgstr "水平移动" + +#: ../../po/../src/extension/internal/grid.cpp:217 +#, fuzzy +msgid "Vertical Offset" +msgstr "垂直中心值" + +#: ../../po/../src/extension/internal/ps.cpp:123 +#, fuzzy +msgid "Print Destination" +msgstr "打印图画" + +#. Print properties frame +#: ../../po/../src/extension/internal/ps.cpp:138 +#, fuzzy +msgid "Print properties" +msgstr "连接属性" + +#: ../../po/../src/extension/internal/ps.cpp:145 +msgid "Print using PostScript operators" +msgstr "" + +#: ../../po/../src/extension/internal/ps.cpp:147 +msgid "" +"Use PostScript vector operators. The resulting image is usually smaller in " +"file size and can be arbitrarily scaled, but alpha transparency and patterns " +"will be lost." +msgstr "" + +#: ../../po/../src/extension/internal/ps.cpp:152 +#, fuzzy +msgid "Print as bitmap" +msgstr "彩色位图" + +#: ../../po/../src/extension/internal/ps.cpp:154 +msgid "" +"Print everything as bitmap. The resulting image is usually larger in file " +"size and cannot be arbitrarily scaled without quality loss, but all objects " +"will be rendered exactly as displayed." +msgstr "" + +#: ../../po/../src/extension/internal/ps.cpp:168 +msgid "Preferred resolution (dots per inch) of bitmap" +msgstr "" + +#: ../../po/../src/extension/internal/ps.cpp:182 +#, fuzzy +msgid "Resolution:" +msgstr "旋转:" + +#. Print destination frame +#: ../../po/../src/extension/internal/ps.cpp:186 +#, fuzzy +msgid "Print destination" +msgstr "打印图画" + +#: ../../po/../src/extension/internal/ps.cpp:192 +msgid "" +"Use '> filename' to print to file.\n" +"Use '| prog arg...' to pipe to a program." +msgstr "" + +#: ../../po/../src/extension/internal/ps.cpp:1227 +msgid "write error occurred" +msgstr "" + +#: ../../po/../src/extension/prefdialog.cpp:21 +#, fuzzy +msgid " Preferences" +msgstr "项目是引用" + +#. We can't call sp_ui_error_dialog because we may be +#. running from the console, in which case calling sp_ui +#. routines will cause a segfault. See bug 1000350 - bryce +#. sp_ui_error_dialog(_("Format autodetect failed. The file is being opened as SVG.")); +#: ../../po/../src/extension/system.cpp:105 +msgid "Format autodetect failed. The file is being opened as SVG." +msgstr "" + +#. TRANSLATORS: default.svg is localizable - this is the name of the default document +#. template. This way you can localize the default pagesize, translate the name of +#. the default layer, etc. If you wish to localize this file, please create a +#. localized share/templates/default.xx.svg file, where xx is your language code. +#: ../../po/../src/file.cpp:133 +#, fuzzy +msgid "default.svg" +msgstr "删除" + +#: ../../po/../src/file.cpp:215 ../../po/../src/file.cpp:900 +#, c-format +msgid "Failed to load the requested file %s" +msgstr "" + +#: ../../po/../src/file.cpp:240 +#, fuzzy +msgid "Document not saved yet. Cannot revert." +msgstr "文档" + +#: ../../po/../src/file.cpp:246 +#, c-format +msgid "Changes will be lost! Are you sure you want to reload document %s?" +msgstr "" + +#: ../../po/../src/file.cpp:266 +#, fuzzy +msgid "Document reverted." +msgstr "文档" + +#: ../../po/../src/file.cpp:268 +#, fuzzy +msgid "Document not reverted." +msgstr "文档" + +#: ../../po/../src/file.cpp:382 +msgid "Select file to open" +msgstr "选择打开的文件" + +#: ../../po/../src/file.cpp:518 +#, c-format +msgid "Removed %i unused definition in <defs>." +msgid_plural "Removed %i unused definitions in <defs>." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/file.cpp:523 +msgid "No unused definitions in <defs>." +msgstr "" + +#: ../../po/../src/file.cpp:548 +#, c-format +msgid "" +"No Inkscape extension found to save document (%s). This may have been " +"caused by an unknown filename extension." +msgstr "" + +#: ../../po/../src/file.cpp:549 ../../po/../src/file.cpp:557 +#, fuzzy +msgid "Document not saved." +msgstr "文档" + +#: ../../po/../src/file.cpp:556 +#, c-format +msgid "File %s could not be saved." +msgstr "" + +#: ../../po/../src/file.cpp:566 +#, fuzzy +msgid "Document saved." +msgstr "文档" + +#: ../../po/../src/file.cpp:614 +#, fuzzy, c-format +msgid "drawing%s" +msgstr "图画" + +#: ../../po/../src/file.cpp:620 +#, fuzzy, c-format +msgid "drawing-%d%s" +msgstr "图画" + +#: ../../po/../src/file.cpp:655 +#, fuzzy +msgid "Select file to save to" +msgstr "选择打开的文件" + +#: ../../po/../src/file.cpp:739 +msgid "No changes need to be saved." +msgstr "" + +#: ../../po/../src/file.cpp:926 +msgid "Select file to import" +msgstr "选择需导入的文件" + +#: ../../po/../src/gradient-context.cpp:263 +msgid "Ctrl: snap gradient angle" +msgstr "" + +#: ../../po/../src/gradient-context.cpp:264 +msgid "Shift: draw gradient around the starting point" +msgstr "" + +#. We did an undoable action, but sp_document_done will be called by the knot when released +#. status text; we do not track coords because this branch is run once, not all the time +#. during drag +#: ../../po/../src/gradient-context.cpp:462 +#, c-format +msgid "Gradient for %d objects; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/gradient-context.cpp:464 +#, fuzzy +msgid "Select objects on which to create gradient." +msgstr "将选定对象转换为曲线" + +#: ../../po/../src/gradient-drag.cpp:65 +#, fuzzy +msgid "Linear gradient start" +msgstr "添加新渐变" + +#. POINT_LG_P1 +#: ../../po/../src/gradient-drag.cpp:66 +#, fuzzy +msgid "Linear gradient end" +msgstr "添加新渐变" + +#: ../../po/../src/gradient-drag.cpp:67 +#, fuzzy +msgid "Radial gradient center" +msgstr "添加新渐变" + +#: ../../po/../src/gradient-drag.cpp:68 ../../po/../src/gradient-drag.cpp:69 +#, fuzzy +msgid "Radial gradient radius" +msgstr "添加新渐变" + +#: ../../po/../src/gradient-drag.cpp:70 +#, fuzzy +msgid "Radial gradient focus" +msgstr "添加新渐变" + +#: ../../po/../src/gradient-drag.cpp:659 +#, c-format +msgid "" +"%s for: %s%s; drag with Ctrl to snap angle, with Ctrl+Alt to " +"preserve angle, with Ctrl+Shift to scale around center" +msgstr "" + +#: ../../po/../src/gradient-drag.cpp:662 +#, fuzzy +msgid " (stroke)" +msgstr "已被勾描" + +#: ../../po/../src/gradient-drag.cpp:665 +msgid "" +"Radial gradient center and focus; drag with Shift to " +"separate focus" +msgstr "" + +#: ../../po/../src/gradient-drag.cpp:667 +#, c-format +msgid "" +"Gradient point shared by %d gradients; drag with Shift to " +"separate" +msgstr "" + +#: ../../po/../src/helper/units.cpp:40 +msgid "Unit" +msgstr "单位" + +#: ../../po/../src/helper/units.cpp:40 +msgid "Units" +msgstr "单位" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Point" +msgstr "点" + +#: ../../po/../src/helper/units.cpp:41 +msgid "pt" +msgstr "pt" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Points" +msgstr "点" + +#: ../../po/../src/helper/units.cpp:41 +msgid "Pt" +msgstr "点" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Pixel" +msgstr "像素" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Pixels" +msgstr "像素" + +#: ../../po/../src/helper/units.cpp:42 +msgid "Px" +msgstr "像素" + +#. You can add new elements from this point forward +#: ../../po/../src/helper/units.cpp:44 ../share/extensions/straightseg.inx.h:2 +msgid "Percent" +msgstr "百分比" + +#: ../../po/../src/helper/units.cpp:44 +msgid "Percents" +msgstr "百分比" + +#: ../../po/../src/helper/units.cpp:45 +msgid "Millimeter" +msgstr "毫米" + +#: ../../po/../src/helper/units.cpp:45 +msgid "mm" +msgstr "mm" + +#: ../../po/../src/helper/units.cpp:45 +msgid "Millimeters" +msgstr "毫米" + +#: ../../po/../src/helper/units.cpp:46 +msgid "Centimeter" +msgstr "厘米" + +#: ../../po/../src/helper/units.cpp:46 +msgid "cm" +msgstr "cm" + +#: ../../po/../src/helper/units.cpp:46 +msgid "Centimeters" +msgstr "厘米" + +#: ../../po/../src/helper/units.cpp:47 +msgid "Meter" +msgstr "ç±³" + +#: ../../po/../src/helper/units.cpp:47 +msgid "m" +msgstr "m" + +#: ../../po/../src/helper/units.cpp:47 +#, fuzzy +msgid "Meters" +msgstr "ç±³" + +#. no svg_unit +#: ../../po/../src/helper/units.cpp:48 +msgid "Inch" +msgstr "英寸" + +#: ../../po/../src/helper/units.cpp:48 +msgid "in" +msgstr "in" + +#: ../../po/../src/helper/units.cpp:48 +msgid "Inches" +msgstr "英寸" + +#. Volatiles do not have default, so there are none here +#. TRANSLATORS: for info, see http://www.w3.org/TR/REC-CSS2/syndata.html#length-units +#: ../../po/../src/helper/units.cpp:51 +msgid "Em square" +msgstr "" + +#: ../../po/../src/helper/units.cpp:51 +msgid "em" +msgstr "" + +#: ../../po/../src/helper/units.cpp:51 +msgid "Em squares" +msgstr "" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/REC-CSS2/syndata.html#length-units +#: ../../po/../src/helper/units.cpp:53 +msgid "Ex square" +msgstr "" + +#: ../../po/../src/helper/units.cpp:53 +msgid "ex" +msgstr "" + +#: ../../po/../src/helper/units.cpp:53 +msgid "Ex squares" +msgstr "" + +#: ../../po/../src/inkscape.cpp:468 +#, fuzzy +msgid "Untitled document" +msgstr "未命名文档 %d" + +#. Show nice dialog box +#: ../../po/../src/inkscape.cpp:497 +msgid "Inkscape encountered an internal error and will close now.\n" +msgstr "" + +#: ../../po/../src/inkscape.cpp:498 +msgid "" +"Automatic backups of unsaved documents were done to the following " +"locations:\n" +msgstr "" + +#: ../../po/../src/inkscape.cpp:499 +msgid "Automatic backup of the following documents failed:\n" +msgstr "" + +#: ../../po/../src/inkscape.cpp:634 +#, c-format +msgid "" +"Cannot create directory %s.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:635 +#, c-format +msgid "" +"%s is not a valid directory.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:636 +#, c-format +msgid "" +"Cannot create file %s.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:637 +#, c-format +msgid "" +"Cannot write file %s.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:638 +msgid "" +"Although Inkscape will run, it will use default settings,\n" +"and any changes made in preferences will not be saved." +msgstr "" + +#: ../../po/../src/inkscape.cpp:708 +#, c-format +msgid "" +"%s is not a regular file.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:709 +#, c-format +msgid "" +"%s not a valid XML file, or\n" +"you don't have read permissions on it.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:711 +#, c-format +msgid "" +"%s is not a valid menus file.\n" +"%s" +msgstr "" + +#: ../../po/../src/inkscape.cpp:712 +msgid "" +"Inkscape will run with default menus.\n" +"New menus will not be saved." +msgstr "" + +#. sp_ui_menu_append_check_item_from_verb(m, view, _("_Menu"), _("Show or hide the menu bar"), "menu", +#. checkitem_toggled, checkitem_update, 0); +#: ../../po/../src/interface.cpp:753 +msgid "Commands Bar" +msgstr "" + +#: ../../po/../src/interface.cpp:753 +#, fuzzy +msgid "Show or hide the Commands bar (under the menu)" +msgstr "显示指示线" + +#: ../../po/../src/interface.cpp:755 +#, fuzzy +msgid "Tool Controls" +msgstr "Oaf 选项" + +#: ../../po/../src/interface.cpp:755 +#, fuzzy +msgid "Show or hide the Tool Controls panel" +msgstr "显示指示线" + +#: ../../po/../src/interface.cpp:757 +msgid "_Toolbox" +msgstr "" + +#: ../../po/../src/interface.cpp:757 +msgid "Show or hide the main toolbox (on the left)" +msgstr "" + +#: ../../po/../src/interface.cpp:763 +msgid "_Statusbar" +msgstr "" + +#: ../../po/../src/interface.cpp:763 +msgid "Show or hide the statusbar (at the bottom of the window)" +msgstr "" + +#: ../../po/../src/interface.cpp:820 +#, c-format +msgid "Verb \"%s\" Unknown" +msgstr "" + +#. TRANSLATORS: #%s is the id of the group e.g. , not a number. +#: ../../po/../src/interface.cpp:930 +#, fuzzy, c-format +msgid "Enter group #%s" +msgstr "编辑节点" + +#: ../../po/../src/interface.cpp:941 +#, fuzzy +msgid "Go to parent" +msgstr "缩放到页" + +#: ../../po/../src/interface.cpp:972 +msgid "Could not parse SVG data" +msgstr "" + +#: ../../po/../src/interface.cpp:1135 +#, c-format +msgid "Overwrite %s" +msgstr "" + +#: ../../po/../src/interface.cpp:1153 +#, c-format +msgid "" +"The file %s already exists. Do you want to overwrite that file with the " +"current document?" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:59 +msgid "Jabber connection lost." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:72 +#, c-format +msgid "Sending message; %u message remaining in send queue." +msgid_plural "Sending message; %u messages remaining in send queue." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:78 +msgid "Receive queue empty." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/callbacks.cpp:154 +#, c-format +msgid "Receiving change; %u change left to process." +msgid_plural "Receiving change; %u changes left to process." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:157 +#, c-format +msgid "%s has left the chatroom." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:221 +msgid "Nickname %1 is already in use. Please choose a different nickname." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/chat-handler.cpp:225 +msgid "An error was encountered while attempting to connect to the server." +msgstr "" + +#. Check to see if the user made any modifications to this document. If so, +#. we want to give them the option of (1) letting us clear their document or (2) +#. opening a new, blank document for the whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:131 +msgid "%1 has invited you to a whiteboard session." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:132 +msgid "Incoming whiteboard invitation from %1" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:135 +msgid "Do you wish to accept %1's whiteboard session invitation?" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:137 +msgid "" +"Would you like to accept %1's invitation in a new document window?\n" +"Accepting the invitation in your current window will discard unsaved changes." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:143 +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:198 +#, fuzzy +msgid "Accept invitation" +msgstr "选择" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:144 +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:199 +msgid "Decline invitation" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:145 +#, fuzzy +msgid "Accept invitation in new document window" +msgstr "内存文档 %d" + +#. We could not create a new desktop; ask the user if she or he wants to +#. replace the current document and accept the invitation, or reject the invitation. +#. TRANSLATORS: %1 is a userid here +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:196 +msgid "" +"A new document window could not be opened for a whiteboard session with %" +"1" +msgstr "" + +#. TRANSLATORS: %1 is the peer whom refused our invitation. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:238 +msgid "" +"The user %1 has refused your " +"whiteboard invitation.\n" +"\n" +msgstr "" + +#. TRANSLATORS: %1 is the peer whom refused our invitation, %2 is our Jabber identity. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:241 +msgid "" +"You are still connected to a Jabber server as %2, and may send an " +"invitation to %1 again, or you may send an invitation to a different " +"user." +msgstr "" + +#. TRANSLATORS: %1 is the peer whom we tried to contact, but is already in a whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:252 +msgid "" +"The user %1 is already in a " +"whiteboard session.\n" +"\n" +msgstr "" + +#. TRANSLATORS: %1 is the peer whom we tried to contact, but is already in a whiteboard session. +#: ../../po/../src/jabber_whiteboard/connection-establishment.cpp:255 +msgid "" +"You are still connected to a Jabber server as %1, and may send an " +"invitation to a different user." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/invitation-confirm-dialog.cpp:26 +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:24 +msgid "_Write session file:" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/message-processors.cpp:145 +#, c-format +msgid "%s has joined the chatroom." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/message-queue.cpp:87 +#, c-format +msgid "%u change in receive queue." +msgid_plural "%u changes in receive queue." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/jabber_whiteboard/message-queue.cpp:117 +#, c-format +msgid "%u change in send queue." +msgid_plural "%u changes in send queue." +msgstr[0] "" +msgstr[1] "" + +#. if ID is NULL, then we have a real problem -- we were not able to find a key +#. nor generate one. The only thing we can really do here is abort, since we have +#. no way to let the other client(s) uniquely identify this object. +#. FIXME: If this indicates a programming bug, then don't request translation with +#. * _(...): it is most useful in untranslated form so that developers may search for +#. * it when someone reports it in a bug report (as we want users to do for all bugs, +#. * as indicated by it being a g_warning string). +#. * +#. * Otherwise, if it is not a programming bug but a network error or a bug in the +#. * remote peer (perhaps running different software) or whatever, then present it in +#. * an alert box, and avoid use of technical jargon `NULL'. +#. +#: ../../po/../src/jabber_whiteboard/message-utilities.cpp:171 +msgid "" +"ID for new object is NULL even after generation and lookup attempts: the new " +"object will NOT be sent, nor will any of its child objects!" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:60 +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:995 +msgid "Select a location and filename" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-file-selector.cpp:62 +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:997 +#, fuzzy +msgid "Set filename" +msgstr "Png 文件名" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:301 +msgid "No SSL certificate was found." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:304 +msgid "The SSL certificate provided by the Jabber server is untrusted." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:307 +msgid "The SSL certificate provided by the Jabber server is expired." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:310 +msgid "" +"The SSL certificate provided by the Jabber server has not been activated." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:313 +msgid "" +"The SSL certificate provided by the Jabber server contains a hostname that " +"does not match the Jabber server's hostname." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:316 +msgid "" +"The SSL certificate provided by the Jabber server contains an invalid " +"fingerprint." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:319 +msgid "An unknown error occurred while setting up the SSL connection." +msgstr "" + +#. TRANSLATORS: %1 is the message that describes the specific error that occurred when +#. establishing the SSL connection. +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:325 +msgid "" +"%1\n" +"\n" +"Do you wish to continue connecting to the Jabber server?" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:328 +msgid "Continue connecting and ignore further errors" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:329 +msgid "Continue connecting, but warn me of further errors" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:330 +#, fuzzy +msgid "Cancel connection" +msgstr "选择" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:777 +#, c-format +msgid "Established whiteboard session with %s." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:785 +#, c-format +msgid "%s has left the whiteboard session." +msgstr "" + +#. Inform the user +#. TRANSLATORS: %1 is the name of the user that disconnected, %2 is the name of the user whom the disconnected user disconnected from. +#. This message is not used in a chatroom context. +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:790 +msgid "" +"The user %1 has left the " +"whiteboard session.\n" +"\n" +msgstr "" + +#. TRANSLATORS: %1 and %2 are userids +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:792 +msgid "" +"You are still connected to a Jabber server as %2, and may establish a " +"new session to %1 or a different user." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:988 +msgid "" +"Could not open file %1 for session recording.\n" +"The error encountered was: %2.\n" +"\n" +"You may select a different location to record the session, or you may opt to " +"not record this session." +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:990 +msgid "Choose a different location" +msgstr "" + +#: ../../po/../src/jabber_whiteboard/session-manager.cpp:991 +msgid "Skip session recording" +msgstr "" + +#: ../../po/../src/knot.cpp:673 +msgid "Node or handle drag canceled." +msgstr "" + +#: ../../po/../src/libnrtype/FontFactory.cpp:358 +msgid "Ignoring font without family that will crash Pango" +msgstr "" + +#: ../../po/../src/main.cpp:395 +msgid "Print the Inkscape version number" +msgstr "" + +#: ../../po/../src/main.cpp:400 +msgid "Do not use X server (only process files from console)" +msgstr "" + +#: ../../po/../src/main.cpp:405 +msgid "Try to use X server (even if $DISPLAY is not set)" +msgstr "" + +#: ../../po/../src/main.cpp:410 +#, fuzzy +msgid "Open specified document(s) (option string may be excluded)" +msgstr "打开指定文件 (可能不包括选项字符串)" + +#: ../../po/../src/main.cpp:411 ../../po/../src/main.cpp:416 +#: ../../po/../src/main.cpp:421 ../../po/../src/main.cpp:483 +#: ../../po/../src/main.cpp:488 ../../po/../src/main.cpp:493 +msgid "FILENAME" +msgstr "文件名" + +#: ../../po/../src/main.cpp:415 +#, fuzzy +msgid "Print document(s) to specified output file (use '| program' for pipe)" +msgstr "将文件打印到指定输出文件 (‘| 程序’将成为管道)" + +#: ../../po/../src/main.cpp:420 +#, fuzzy +msgid "Export document to a PNG file" +msgstr "将图形导出为 png" + +#: ../../po/../src/main.cpp:425 +msgid "The resolution used for exporting SVG into bitmap (default 90)" +msgstr "" + +#: ../../po/../src/main.cpp:426 +msgid "DPI" +msgstr "" + +#: ../../po/../src/main.cpp:430 +msgid "" +"Exported area in SVG user units (default is the canvas; 0,0 is lower-left " +"corner)" +msgstr "" + +#: ../../po/../src/main.cpp:431 +msgid "x0:y0:x1:y1" +msgstr "" + +#: ../../po/../src/main.cpp:435 +msgid "Exported area is the entire drawing (not canvas)" +msgstr "" + +#: ../../po/../src/main.cpp:440 +msgid "" +"Snap the bitmap export area outwards to the nearest integer values (in SVG " +"user units)" +msgstr "" + +#: ../../po/../src/main.cpp:445 +msgid "The width of exported bitmap in pixels (overrides export-dpi)" +msgstr "" + +#: ../../po/../src/main.cpp:446 +msgid "WIDTH" +msgstr "" + +#: ../../po/../src/main.cpp:450 +msgid "The height of exported bitmap in pixels (overrides export-dpi)" +msgstr "" + +#: ../../po/../src/main.cpp:451 +msgid "HEIGHT" +msgstr "" + +#: ../../po/../src/main.cpp:455 +msgid "The ID of the object to export (overrides export-area)" +msgstr "" + +#: ../../po/../src/main.cpp:456 ../../po/../src/main.cpp:532 +#, fuzzy +msgid "ID" +msgstr "标识:" + +#. TRANSLATORS: this means: "Only export the object whose id is given in --export-id". +#. See "man inkscape" for details. +#: ../../po/../src/main.cpp:462 +msgid "" +"Export just the object with export-id, hide all others (only with export-id)" +msgstr "" + +#: ../../po/../src/main.cpp:467 +msgid "Use stored filename and DPI hints when exporting (only with export-id)" +msgstr "" + +#: ../../po/../src/main.cpp:472 +msgid "Background color of exported bitmap (any SVG-supported color string)" +msgstr "" + +#: ../../po/../src/main.cpp:473 +msgid "COLOR" +msgstr "" + +#: ../../po/../src/main.cpp:477 +msgid "Background opacity of exported bitmap (either 0.0 to 1.0, or 1 to 255)" +msgstr "" + +#: ../../po/../src/main.cpp:478 +msgid "VALUE" +msgstr "" + +#: ../../po/../src/main.cpp:482 +msgid "Export document to plain SVG file (no sodipodi or inkscape namespaces)" +msgstr "" + +#: ../../po/../src/main.cpp:487 +#, fuzzy +msgid "Export document to a PS file" +msgstr "将图形导出为 png" + +#: ../../po/../src/main.cpp:492 +#, fuzzy +msgid "Export document to an EPS file" +msgstr "将图形导出为 png" + +#: ../../po/../src/main.cpp:497 +#, fuzzy +msgid "Convert text object to paths on export (EPS)" +msgstr "将选定对象转换为曲线" + +#: ../../po/../src/main.cpp:502 +msgid "Export files with the bounding box set to the page size (EPS)" +msgstr "" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:508 +msgid "" +"Query the X coordinate of the drawing or, if specified, of the object with --" +"query-id" +msgstr "" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:514 +msgid "" +"Query the Y coordinate of the drawing or, if specified, of the object with --" +"query-id" +msgstr "" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:520 +msgid "" +"Query the width of the drawing or, if specified, of the object with --query-" +"id" +msgstr "" + +#. TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" +#: ../../po/../src/main.cpp:526 +msgid "" +"Query the height of the drawing or, if specified, of the object with --query-" +"id" +msgstr "" + +#: ../../po/../src/main.cpp:531 +msgid "The ID of the object whose dimensions are queried" +msgstr "" + +#. TRANSLATORS: this option makes Inkscape print the name (path) of the extension directory +#: ../../po/../src/main.cpp:537 +msgid "Print out the extension directory and exit" +msgstr "" + +#: ../../po/../src/main.cpp:542 +msgid "Show given files one-by-one, switch to next on any key/mouse event" +msgstr "逐个显示给定文件,在出现任何键盘/鼠标事件时切换" + +#: ../../po/../src/main.cpp:547 +msgid "Use the new Gtkmm GUI interface" +msgstr "" + +#: ../../po/../src/main.cpp:552 +msgid "Remove unused definitions from the defs section(s) of the document" +msgstr "" + +#: ../../po/../src/main.cpp:741 +msgid "" +"[OPTIONS...] [FILE...]\n" +"\n" +"Available options:" +msgstr "" + +#: ../../po/../src/menus-skeleton.h:17 +msgid "_New" +msgstr "新建(_N)" + +#: ../../po/../src/menus-skeleton.h:22 +#, fuzzy +msgid "Open _Recent" +msgstr "打开" + +#: ../../po/../src/menus-skeleton.h:53 +#, fuzzy +msgid "_Edit" +msgstr " 编辑" + +#: ../../po/../src/menus-skeleton.h:84 +#, fuzzy +msgid "_View" +msgstr "视图" + +#: ../../po/../src/menus-skeleton.h:85 +#, fuzzy +msgid "_Zoom" +msgstr "缩放" + +#: ../../po/../src/menus-skeleton.h:102 +#, fuzzy +msgid "Show/Hide" +msgstr "显示指示线" + +#: ../../po/../src/menus-skeleton.h:107 +#, fuzzy +msgid "_Display mode" +msgstr "显示" + +#: ../../po/../src/menus-skeleton.h:126 +#, fuzzy +msgid "_Layer" +msgstr "降低" + +#: ../../po/../src/menus-skeleton.h:143 +#, fuzzy +msgid "_Object" +msgstr "对象" + +#: ../../po/../src/menus-skeleton.h:165 +#, fuzzy +msgid "_Path" +msgstr "粘贴" + +#: ../../po/../src/menus-skeleton.h:188 +#, fuzzy +msgid "_Text" +msgstr "文本" + +#: ../../po/../src/menus-skeleton.h:200 +#, fuzzy +msgid "Effects" +msgstr "对象" + +#: ../../po/../src/menus-skeleton.h:207 +msgid "Whiteboa_rd" +msgstr "" + +#: ../../po/../src/menus-skeleton.h:220 +#, fuzzy +msgid "_Help" +msgstr "求助(_H)" + +#: ../../po/../src/menus-skeleton.h:222 +msgid "Tutorials" +msgstr "" + +#: ../../po/../src/node-context.cpp:382 +msgid "" +"Ctrl: toggle node type, snap handle angle, move hor/vert; Ctrl" +"+Alt: move along handles" +msgstr "" + +#: ../../po/../src/node-context.cpp:383 +msgid "" +"Shift: toggle node selection, disable snapping, rotate both handles" +msgstr "" + +#: ../../po/../src/node-context.cpp:384 +msgid "Alt: lock handle length; Ctrl+Alt: move along handles" +msgstr "" + +#: ../../po/../src/nodepath.cpp:1399 ../../po/../src/nodepath.cpp:1411 +#: ../../po/../src/nodepath.cpp:1492 ../../po/../src/nodepath.cpp:1504 +msgid "To join, you must have two endnodes selected." +msgstr "" + +#: ../../po/../src/nodepath.cpp:1633 ../../po/../src/nodepath.cpp:1647 +msgid "" +"Select two non-endpoint nodes on a path between which to delete " +"segments." +msgstr "" + +#: ../../po/../src/nodepath.cpp:1743 +#, fuzzy +msgid "Cannot find path between nodes." +msgstr "使选定节点处成为光滑线段" + +#: ../../po/../src/nodepath.cpp:2822 +#, c-format +msgid "" +"Node handle: angle %0.2f°, length %s; with Ctrl to snap " +"angle; with Alt to lock length; with Shift to rotate both " +"handles" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3351 +msgid "" +"Node: drag to edit the path; with Ctrl to snap to horizontal/" +"vertical; with Ctrl+Alt to snap to handles' directions" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3375 +msgid "" +"Node handle: drag to shape the curve; with Ctrl to snap angle; " +"with Alt to lock length; with Shift to rotate both handles" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3399 +msgid "" +"Node handle: drag to shape the curve; with Ctrl to snap angle; " +"with Alt to lock length; with Shift to rotate the opposite " +"handle in sync" +msgstr "" + +#. TRANSLATORS: "end" is an adjective here (NOT a verb) +#: ../../po/../src/nodepath.cpp:3591 +#, fuzzy +msgid "end node" +msgstr "编辑节点" + +#. TRANSLATORS: "cusp" means "sharp" (cusp node); see also the Advanced Tutorial +#: ../../po/../src/nodepath.cpp:3596 +msgid "cusp" +msgstr "" + +#. TRANSLATORS: "smooth" is an adjective here +#: ../../po/../src/nodepath.cpp:3599 +msgid "smooth" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3601 +#, fuzzy +msgid "symmetric" +msgstr "不对称" + +#. TRANSLATORS: "end" is an adjective here (NOT a verb) +#: ../../po/../src/nodepath.cpp:3607 +msgid "end node, handle retracted (drag with Shift to extend)" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3609 +msgid "one handle retracted (drag with Shift to extend)" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3612 +msgid "both handles retracted (drag with Shift to extend)" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3624 +msgid "Drag nodes or node handles; arrow keys to move nodes" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3625 +msgid "Drag the node or its handles; arrow keys to move the node" +msgstr "" + +#: ../../po/../src/nodepath.cpp:3651 ../../po/../src/nodepath.cpp:3663 +#, fuzzy +msgid "Select a single object to edit its nodes or handles." +msgstr "文档中无渐变" + +#: ../../po/../src/nodepath.cpp:3655 +#, c-format +msgid "" +"0 out of %i node selected. Click, Shift+click, " +"or drag around nodes to select." +msgid_plural "" +"0 out of %i nodes selected. Click, Shift+click, " +"or drag around nodes to select." +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/nodepath.cpp:3661 +msgid "Drag the handles of the object to modify it." +msgstr "" + +#: ../../po/../src/nodepath.cpp:3669 +#, fuzzy, c-format +msgid "%i of %i node selected; %s. %s." +msgid_plural "%i of %i nodes selected; %s. %s." +msgstr[0] "使选定节点处成为光滑线段" +msgstr[1] "使选定节点处成为光滑线段" + +#: ../../po/../src/nodepath.cpp:3675 +#, fuzzy, c-format +msgid "%i of %i node selected. %s." +msgid_plural "%i of %i nodes selected. %s." +msgstr[0] "使选定节点处成为光滑线段" +msgstr[1] "使选定节点处成为光滑线段" + +#: ../../po/../src/object-edit.cpp:493 +msgid "" +"Adjust the horizontal rounding radius; with Ctrl to make the " +"vertical radius the same" +msgstr "" + +#: ../../po/../src/object-edit.cpp:499 +msgid "" +"Adjust the vertical rounding radius; with Ctrl to make the " +"horizontal radius the same" +msgstr "" + +#: ../../po/../src/object-edit.cpp:506 ../../po/../src/object-edit.cpp:513 +msgid "" +"Adjust the width and height of the rectangle; with Ctrl to " +"lock ratio or stretch in one dimension only" +msgstr "" + +#: ../../po/../src/object-edit.cpp:686 +msgid "Adjust ellipse width, with Ctrl to make circle" +msgstr "" + +#: ../../po/../src/object-edit.cpp:689 +msgid "Adjust ellipse height, with Ctrl to make circle" +msgstr "" + +#: ../../po/../src/object-edit.cpp:692 +msgid "" +"Position the start point of the arc or segment; with Ctrl to " +"snap angle; drag inside the ellipse for arc, outside for " +"segment" +msgstr "" + +#: ../../po/../src/object-edit.cpp:695 +msgid "" +"Position the end point of the arc or segment; with Ctrl to " +"snap angle; drag inside the ellipse for arc, outside for " +"segment" +msgstr "" + +#: ../../po/../src/object-edit.cpp:800 +msgid "" +"Adjust the tip radius of the star or polygon; with Shift to " +"round; with Alt to randomize" +msgstr "" + +#: ../../po/../src/object-edit.cpp:803 +msgid "" +"Adjust the base radius of the star; with Ctrl to keep star " +"rays radial (no skew); with Shift to round; with Alt to " +"randomize" +msgstr "" + +#: ../../po/../src/object-edit.cpp:967 +msgid "" +"Roll/unroll the spiral from inside; with Ctrl to snap angle; " +"with Alt to converge/diverge" +msgstr "" + +#: ../../po/../src/object-edit.cpp:969 +msgid "" +"Roll/unroll the spiral from outside; with Ctrl to snap angle; " +"with Shift to scale/rotate" +msgstr "" + +#: ../../po/../src/object-edit.cpp:1006 +msgid "Adjust the offset distance" +msgstr "" + +#. TRANSLATORS: This refers to the pattern that's inside the object +#: ../../po/../src/object-edit.cpp:1036 +msgid "Move the pattern fill inside the object" +msgstr "" + +#: ../../po/../src/object-edit.cpp:1038 +#, fuzzy +msgid "Scale the pattern fill uniformly" +msgstr "将选定对象转换为曲线" + +#: ../../po/../src/object-edit.cpp:1040 +msgid "Rotate the pattern fill; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/object-edit.cpp:1065 +msgid "Drag to resize the flowed text frame" +msgstr "" + +#. Item dialog +#: ../../po/../src/object-ui.cpp:106 +#, fuzzy +msgid "Object _Properties" +msgstr "对象属性" + +#. Select item +#: ../../po/../src/object-ui.cpp:116 +#, fuzzy +msgid "_Select This" +msgstr "选择它" + +#. Create link +#: ../../po/../src/object-ui.cpp:126 +#, fuzzy +msgid "_Create Link" +msgstr "创建连接" + +#. "Ungroup" +#: ../../po/../src/object-ui.cpp:199 ../../po/../src/verbs.cpp:1931 +msgid "_Ungroup" +msgstr "分解组(_U)" + +#. Link dialog +#: ../../po/../src/object-ui.cpp:239 +#, fuzzy +msgid "Link _Properties" +msgstr "连接属性" + +#. Select item +#: ../../po/../src/object-ui.cpp:249 +#, fuzzy +msgid "_Follow Link" +msgstr "跟随连接" + +#. Reset transformations +#: ../../po/../src/object-ui.cpp:254 +#, fuzzy +msgid "_Remove Link" +msgstr "删除连接" + +#. Link dialog +#: ../../po/../src/object-ui.cpp:303 +#, fuzzy +msgid "Image _Properties" +msgstr "图像属性" + +#. Item dialog +#: ../../po/../src/object-ui.cpp:344 +#, fuzzy +msgid "_Fill and Stroke" +msgstr "填充并勾描" + +#: ../../po/../src/path-chemistry.cpp:58 +#, fuzzy +msgid "Select at least two objects to combine." +msgstr "文档中无渐变" + +#: ../../po/../src/path-chemistry.cpp:65 +#, fuzzy +msgid "At least one of the objects is not a path, cannot combine." +msgstr "将选定对象转换为曲线" + +#: ../../po/../src/path-chemistry.cpp:73 +msgid "" +"You cannot combine objects from different groups or layers." +msgstr "" + +#: ../../po/../src/path-chemistry.cpp:155 +#, fuzzy +msgid "Select path(s) to break apart." +msgstr "将选定对象转换为曲线" + +#: ../../po/../src/path-chemistry.cpp:231 +msgid "No path(s) to break apart in the selection." +msgstr "" + +#: ../../po/../src/path-chemistry.cpp:252 +#, fuzzy +msgid "Select object(s) to convert to path." +msgstr "将选定对象转换为曲线" + +#: ../../po/../src/path-chemistry.cpp:297 +#, fuzzy +msgid "No objects to convert to path in the selection." +msgstr "将选定对象转换为曲线" + +#: ../../po/../src/path-chemistry.cpp:345 +#, fuzzy +msgid "Select path(s) to reverse." +msgstr "将选中内容提升到顶层" + +#: ../../po/../src/path-chemistry.cpp:370 +msgid "No paths to reverse in the selection." +msgstr "" + +#: ../../po/../src/pen-context.cpp:379 ../../po/../src/pencil-context.cpp:233 +#, fuzzy +msgid "Continuing selected path" +msgstr "组合选定路径" + +#: ../../po/../src/pen-context.cpp:390 ../../po/../src/pencil-context.cpp:242 +#, fuzzy +msgid "Creating new path" +msgstr "内存文档 %d" + +#: ../../po/../src/pen-context.cpp:394 ../../po/../src/pencil-context.cpp:246 +#, fuzzy +msgid "Appending to selected path" +msgstr "缩放到选中内容" + +#: ../../po/../src/pen-context.cpp:538 +msgid "Click or click and drag to close and finish the path." +msgstr "" + +#: ../../po/../src/pen-context.cpp:548 +msgid "" +"Click or click and drag to continue the path from this point." +msgstr "" + +#: ../../po/../src/pen-context.cpp:857 +#, c-format +msgid "" +"%s: angle %3.2f°, distance %s; with Ctrl to snap angle, " +"Enter to finish the path" +msgstr "" + +#: ../../po/../src/pen-context.cpp:882 +#, c-format +msgid "" +"Curve handle: angle %3.2f°, length %s; with Ctrl to snap " +"angle" +msgstr "" + +#: ../../po/../src/pen-context.cpp:912 +#, c-format +msgid "" +"%s: angle %3.2f°, length %s; with Ctrl to snap angle, " +"with Shift to move this handle only" +msgstr "" + +#: ../../po/../src/pen-context.cpp:946 +#, fuzzy +msgid "Finishing pen" +msgstr "手绘" + +#: ../../po/../src/pencil-context.cpp:320 +msgid "Release here to close and finish the path." +msgstr "" + +#: ../../po/../src/pencil-context.cpp:326 +#, fuzzy +msgid "Drawing a freehand path" +msgstr "绘制弹力手绘线" + +#: ../../po/../src/pencil-context.cpp:331 +msgid "Drag to continue the path from this point." +msgstr "" + +#. Write curves to object +#: ../../po/../src/pencil-context.cpp:390 +#, fuzzy +msgid "Finishing freehand" +msgstr "手绘" + +#: ../../po/../src/rect-context.cpp:387 +msgid "" +"Ctrl: make square or integer-ratio rect, lock a rounded corner " +"circular" +msgstr "" + +#: ../../po/../src/rect-context.cpp:549 +#, c-format +msgid "" +"Rectangle: %s × %s; with Ctrl to make square or integer-" +"ratio rectangle; with Shift to draw around the starting point" +msgstr "" + +#: ../../po/../src/select-context.cpp:243 +#, fuzzy +msgid "Move canceled." +msgstr "选择" + +#: ../../po/../src/select-context.cpp:252 +#, fuzzy +msgid "Selection canceled." +msgstr "选择" + +#: ../../po/../src/select-context.cpp:642 +msgid "Ctrl: select in groups, move hor/vert" +msgstr "" + +#: ../../po/../src/select-context.cpp:643 +msgid "Shift: toggle select, force rubberband, disable snapping" +msgstr "" + +#: ../../po/../src/select-context.cpp:644 +msgid "Alt: select under, move selected" +msgstr "" + +#: ../../po/../src/select-context.cpp:798 +#, fuzzy +msgid "Selected object is not a group. Cannot enter." +msgstr "将选定对象转换为曲线" + +#: ../../po/../src/select-context.cpp:876 +#, c-format +msgid "" +"Move by %s, %s; with Ctrl to restrict to horizontal/vertical; " +"with Shift to disable snapping" +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:228 +msgid "Nothing was deleted." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:259 +#, fuzzy +msgid "Select object(s) to duplicate." +msgstr "将选定对象转换为曲线" + +#: ../../po/../src/selection-chemistry.cpp:420 +#, fuzzy +msgid "Select two or more objects to group." +msgstr "将选中内容提升到顶层" + +#: ../../po/../src/selection-chemistry.cpp:428 +#, fuzzy +msgid "Select at least two objects to group." +msgstr "文档中无渐变" + +#: ../../po/../src/selection-chemistry.cpp:513 +#, fuzzy +msgid "Select a group to ungroup." +msgstr "将选中内容提升到顶层" + +#: ../../po/../src/selection-chemistry.cpp:554 +msgid "No groups to ungroup in the selection." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:623 +#, fuzzy +msgid "Select objects to raise." +msgstr "将选定对象转换为曲线" + +#: ../../po/../src/selection-chemistry.cpp:629 +#: ../../po/../src/selection-chemistry.cpp:681 +#: ../../po/../src/selection-chemistry.cpp:715 +#: ../../po/../src/selection-chemistry.cpp:773 +msgid "" +"You cannot raise/lower objects from different groups or layers." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:673 +#, fuzzy +msgid "Select object(s) to raise to top." +msgstr "将选定对象转换为曲线" + +#: ../../po/../src/selection-chemistry.cpp:709 +#, fuzzy +msgid "Select object(s) to lower." +msgstr "将选定对象转换为曲线" + +#: ../../po/../src/selection-chemistry.cpp:765 +#, fuzzy +msgid "Select object(s) to lower to bottom." +msgstr "将选定对象转换为曲线" + +#: ../../po/../src/selection-chemistry.cpp:806 +msgid "Nothing to undo." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:813 +msgid "Nothing to redo." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:969 +msgid "Nothing was copied." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1051 +msgid "Current layer is hidden. Unhide it to be able to paste to it." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1055 +msgid "Current layer is locked. Unlock it to be able to paste to it." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1068 +#: ../../po/../src/selection-chemistry.cpp:1103 +#, fuzzy +msgid "Nothing on the clipboard." +msgstr "将选中内容复制到剪贴板" + +#: ../../po/../src/selection-chemistry.cpp:1109 +#, fuzzy +msgid "Select object(s) to paste style to." +msgstr "将选定对象转换为曲线" + +#: ../../po/../src/selection-chemistry.cpp:1128 +#, fuzzy +msgid "Select object(s) to move to the layer above." +msgstr "将选定对象转换为曲线" + +#: ../../po/../src/selection-chemistry.cpp:1146 +#, fuzzy +msgid "No more layers above." +msgstr "文档" + +#: ../../po/../src/selection-chemistry.cpp:1160 +#, fuzzy +msgid "Select object(s) to move to the layer below." +msgstr "将选定对象转换为曲线" + +#: ../../po/../src/selection-chemistry.cpp:1178 +#, fuzzy +msgid "No more layers below." +msgstr "文档" + +#: ../../po/../src/selection-chemistry.cpp:1811 +#, fuzzy +msgid "Select a clone to unlink." +msgstr "选择打开的文件" + +#: ../../po/../src/selection-chemistry.cpp:1842 +msgid "No clones to unlink in the selection." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1859 +msgid "" +"Select a clone to go to its original. Select a linked offset " +"to go to its source. Select a text on path to go to the path. Select " +"a flowed text to go to its frame." +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1882 +msgid "" +"Cannot find the object to select (orphaned clone, offset, textpath, " +"flowed text?)" +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1888 +msgid "" +"The object you're trying to select is not visible (it is in <" +"defs>)" +msgstr "" + +#: ../../po/../src/selection-chemistry.cpp:1915 +#, fuzzy +msgid "Select object(s) to convert to pattern." +msgstr "将选定对象转换为曲线" + +#: ../../po/../src/selection-chemistry.cpp:2006 +#, fuzzy +msgid "Select an object with pattern fill to extract objects from." +msgstr "将选定对象转换为曲线" + +#: ../../po/../src/selection-chemistry.cpp:2059 +#, fuzzy +msgid "No pattern fills in the selection." +msgstr "将选定对象转换为曲线" + +#: ../../po/../src/selection-chemistry.cpp:2079 +#, fuzzy +msgid "Select object(s) to make a bitmap copy." +msgstr "将选定对象转换为曲线" + +#: ../../po/../src/selection-describer.cpp:37 +msgid "Click selection to toggle scale/rotation handles" +msgstr "" + +#. no items +#: ../../po/../src/selection-describer.cpp:39 +msgid "" +"No objects selected. Click, Shift+click, or drag around objects to select." +msgstr "" + +#: ../../po/../src/selection-describer.cpp:51 +#, fuzzy, c-format +msgid " in layer %s" +msgstr "提升" + +#: ../../po/../src/selection-describer.cpp:54 +#, fuzzy, c-format +msgid " in layer %s" +msgstr "提升" + +#: ../../po/../src/selection-describer.cpp:66 +msgid "Use Shift+D to look up original" +msgstr "" + +#: ../../po/../src/selection-describer.cpp:70 +msgid "Use Shift+D to look up path" +msgstr "" + +#: ../../po/../src/selection-describer.cpp:74 +msgid "Use Shift+D to look up frame" +msgstr "" + +#: ../../po/../src/selection-describer.cpp:84 +#, fuzzy, c-format +msgid "%i object selected" +msgid_plural "%i objects selected" +msgstr[0] "使选定节点处成为光滑线段" +msgstr[1] "使选定节点处成为光滑线段" + +#: ../../po/../src/selection-describer.cpp:90 +#, c-format +msgid "%s%s. %s." +msgstr "" + +#: ../../po/../src/selection-describer.cpp:94 +#, fuzzy, c-format +msgid "%s in %i layer. %s." +msgid_plural "%s in %i layers. %s." +msgstr[0] "使选定节点处成为光滑线段" +msgstr[1] "使选定节点处成为光滑线段" + +#: ../../po/../src/seltrans.cpp:498 +msgid "" +"Center of rotation and skewing: drag to reposition; scaling with " +"Shift also uses this center" +msgstr "" + +#: ../../po/../src/seltrans.cpp:514 +msgid "" +"Squeeze or stretch selection; with Ctrl to scale uniformly; " +"with Shift to scale around rotation center" +msgstr "" + +#: ../../po/../src/seltrans.cpp:515 +msgid "" +"Scale selection; with Ctrl to scale uniformly; with Shift to scale around rotation center" +msgstr "" + +#: ../../po/../src/seltrans.cpp:519 +msgid "" +"Skew selection; with Ctrl to snap angle; with Shift to " +"skew around the opposite side" +msgstr "" + +#: ../../po/../src/seltrans.cpp:520 +msgid "" +"Rotate selection; with Ctrl to snap angle; with Shift " +"to rotate around the opposite corner" +msgstr "" + +#: ../../po/../src/seltrans.cpp:829 ../../po/../src/seltrans.cpp:909 +#, c-format +msgid "Scale: %0.2f%% x %0.2f%%; with Ctrl to lock ratio" +msgstr "" + +#. TRANSLATORS: don't modify the first ";" (it will NOT be displayed as ";" - only the second one will be) +#: ../../po/../src/seltrans.cpp:984 +#, c-format +msgid "Skew: %0.2f°; with Ctrl to snap angle" +msgstr "" + +#. TRANSLATORS: don't modify the first ";" (it will NOT be displayed as ";" - only the second one will be) +#: ../../po/../src/seltrans.cpp:1035 +#, c-format +msgid "Rotate: %0.2f°; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/seltrans.cpp:1090 +#, fuzzy, c-format +msgid "Move center to %s, %s" +msgstr "连接到 %s" + +#: ../../po/../src/slideshow.cpp:90 +#, fuzzy +msgid "Inkscape slideshow" +msgstr "Sodipodi:%s:%s:%d" + +#: ../../po/../src/sp-anchor.cpp:181 +#, fuzzy, c-format +msgid "Link to %s" +msgstr "连接到 %s" + +#: ../../po/../src/sp-anchor.cpp:185 +#, fuzzy +msgid "Link without URI" +msgstr "连接到 %s" + +#: ../../po/../src/sp-ellipse.cpp:438 ../../po/../src/sp-ellipse.cpp:870 +#, fuzzy +msgid "Ellipse" +msgstr "椭圆" + +#: ../../po/../src/sp-ellipse.cpp:583 +#, fuzzy +msgid "Circle" +msgstr "改变" + +#: ../../po/../src/sp-ellipse.cpp:865 +#, fuzzy +msgid "Segment" +msgstr "改变" + +#: ../../po/../src/sp-ellipse.cpp:867 +msgid "Arc" +msgstr "" + +#. TRANSLATORS: "Flow region" is an area where text is allowed to flow +#: ../../po/../src/sp-flowregion.cpp:276 +#, fuzzy +msgid "Flow region" +msgstr "跟随连接" + +#. TRANSLATORS: A region "cut out of" a flow region; text is not allowed to flow inside the +#. * flow excluded region. flowRegionExclude in SVG 1.2: see +#. * http://www.w3.org/TR/2004/WD-SVG12-20041027/flow.html#flowRegion-elem and +#. * http://www.w3.org/TR/2004/WD-SVG12-20041027/flow.html#flowRegionExclude-elem. +#: ../../po/../src/sp-flowregion.cpp:493 +msgid "Flow excluded region" +msgstr "" + +#: ../../po/../src/sp-flowtext.cpp:355 +#, c-format +msgid "Flowed text (%d characters)" +msgstr "" + +#: ../../po/../src/sp-flowtext.cpp:357 +#, c-format +msgid "Linked flowed text (%d characters)" +msgstr "" + +#: ../../po/../src/sp-guide.cpp:290 +#, fuzzy +msgid "vertical guideline" +msgstr "垂直中心值" + +#: ../../po/../src/sp-guide.cpp:292 +#, fuzzy +msgid "horizontal guideline" +msgstr "水平移动" + +#: ../../po/../src/sp-image.cpp:835 +msgid "embedded" +msgstr "" + +#: ../../po/../src/sp-image.cpp:839 +msgid "(null_pointer)" +msgstr "" + +#: ../../po/../src/sp-image.cpp:843 +#, fuzzy, c-format +msgid "Image with bad reference: %s" +msgstr "项目是引用" + +#: ../../po/../src/sp-image.cpp:844 +#, c-format +msgid "Image %d × %d: %s" +msgstr "" + +#: ../../po/../src/sp-item-group.cpp:390 +#, fuzzy, c-format +msgid "Group of %d object" +msgid_plural "Group of %d objects" +msgstr[0] "含有 %d 个对象的组" +msgstr[1] "含有 %d 个对象的组" + +#: ../../po/../src/sp-item.cpp:720 +msgid "Object" +msgstr "对象" + +#: ../../po/../src/sp-line.cpp:202 +#, fuzzy +msgid "Line" +msgstr "改变" + +#. TRANSLATORS COMMENT: %s is either "outset" or "inset" depending on sign +#: ../../po/../src/sp-offset.cpp:433 +#, c-format +msgid "Linked offset, %s by %f pt" +msgstr "" + +#: ../../po/../src/sp-offset.cpp:434 ../../po/../src/sp-offset.cpp:438 +#, fuzzy +msgid "outset" +msgstr "组合选定路径" + +#: ../../po/../src/sp-offset.cpp:434 ../../po/../src/sp-offset.cpp:438 +#, fuzzy +msgid "inset" +msgstr "英寸" + +#. TRANSLATORS COMMENT: %s is either "outset" or "inset" depending on sign +#: ../../po/../src/sp-offset.cpp:437 +#, c-format +msgid "Dynamic offset, %s by %f pt" +msgstr "" + +#: ../../po/../src/sp-path.cpp:127 +#, fuzzy, c-format +msgid "Path (%i node)" +msgid_plural "Path (%i nodes)" +msgstr[0] "连接到 %s" +msgstr[1] "连接到 %s" + +#: ../../po/../src/sp-polygon.cpp:216 +#, fuzzy +msgid "Polygon" +msgstr "改变" + +#: ../../po/../src/sp-polyline.cpp:179 +#, fuzzy +msgid "Polyline" +msgstr "椭圆" + +#: ../../po/../src/sp-rect.cpp:250 +#, fuzzy +msgid "Rectangle" +msgstr "改变" + +#. TRANSLATORS: since turn count isn't an integer, please adjust the +#. string as needed to deal with an localized plural forms. +#: ../../po/../src/sp-spiral.cpp:305 +#, c-format +msgid "Spiral with %3f turns" +msgstr "" + +#: ../../po/../src/sp-star.cpp:288 +#, c-format +msgid "Star with %d vertex" +msgid_plural "Star with %d vertices" +msgstr[0] "" +msgstr[1] "" + +#: ../../po/../src/sp-star.cpp:292 +#, c-format +msgid "Polygon with %d vertex" +msgid_plural "Polygon with %d vertices" +msgstr[0] "" +msgstr[1] "" + +#. TRANSLATORS: For description of font with no name. +#: ../../po/../src/sp-text.cpp:420 +msgid "<no name found>" +msgstr "" + +#: ../../po/../src/sp-text.cpp:426 +#, fuzzy, c-format +msgid "Text on path (%s, %s)" +msgstr "连接到 %s" + +#: ../../po/../src/sp-text.cpp:427 +#, fuzzy, c-format +msgid "Text (%s, %s)" +msgstr "连接到 %s" + +#. TRANSLATORS: Used for statusbar description for long chains: +#. * "Clone of: Clone of: ... in Layer 1". +#: ../../po/../src/sp-use.cpp:317 +#, fuzzy +msgid "..." +msgstr "打开" + +#: ../../po/../src/sp-use.cpp:325 +#, fuzzy, c-format +msgid "Clone of: %s" +msgstr "连接到 %s" + +#: ../../po/../src/sp-use.cpp:329 +#, fuzzy +msgid "Orphaned clone" +msgstr "改变" + +#: ../../po/../src/spiral-context.cpp:355 +msgid "Ctrl: snap angle" +msgstr "" + +#: ../../po/../src/spiral-context.cpp:357 +msgid "Alt: lock spiral radius" +msgstr "" + +#: ../../po/../src/spiral-context.cpp:469 +#, c-format +msgid "" +"Spiral: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/splivarot.cpp:106 +#, fuzzy +msgid "Select at least 2 paths to perform a boolean operation." +msgstr "文档中无渐变" + +#: ../../po/../src/splivarot.cpp:112 +msgid "" +"Select exactly 2 paths to perform difference, XOR, division, or path " +"cut." +msgstr "" + +#: ../../po/../src/splivarot.cpp:129 ../../po/../src/splivarot.cpp:144 +msgid "" +"Unable to determine the z-order of the objects selected for " +"difference, XOR, division, or path cut." +msgstr "" + +#: ../../po/../src/splivarot.cpp:174 +#, fuzzy +msgid "" +"One of the objects is not a path, cannot perform boolean operation." +msgstr "将选定对象转换为曲线" + +#. TRANSLATORS: "to outline" means "to convert stroke to path" +#: ../../po/../src/splivarot.cpp:554 +#, fuzzy +msgid "Select path(s) to outline." +msgstr "将选定对象转换为曲线" + +#. TRANSLATORS: "to outline" means "to convert stroke to path" +#: ../../po/../src/splivarot.cpp:748 +msgid "No stroked paths to outline in the selection." +msgstr "" + +#: ../../po/../src/splivarot.cpp:832 +#, fuzzy +msgid "Selected object is not a path, cannot inset/outset." +msgstr "将选定对象转换为曲线" + +#: ../../po/../src/splivarot.cpp:1040 +#, fuzzy +msgid "Select path(s) to inset/outset." +msgstr "将选定对象转换为曲线" + +#: ../../po/../src/splivarot.cpp:1257 +msgid "No paths to inset/outset in the selection." +msgstr "" + +#: ../../po/../src/splivarot.cpp:1390 +#, fuzzy +msgid "Select path(s) to simplify." +msgstr "将选定对象转换为曲线" + +#: ../../po/../src/splivarot.cpp:1417 +msgid "No paths to simplify in the selection." +msgstr "" + +#: ../../po/../src/star-context.cpp:362 +msgid "Ctrl: snap angle; keep rays radial" +msgstr "" + +#: ../../po/../src/star-context.cpp:470 +#, c-format +msgid "" +"Polygon: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/star-context.cpp:471 +#, c-format +msgid "Star: radius %s, angle %5g°; with Ctrl to snap angle" +msgstr "" + +#: ../../po/../src/text-chemistry.cpp:90 +#, fuzzy +msgid "Select a text and a path to put text on path." +msgstr "文档中无渐变" + +#: ../../po/../src/text-chemistry.cpp:95 +msgid "" +"This text object is already put to a path. Remove it from the path " +"first. Use Shift+D to look up its path." +msgstr "" + +#. rect is the only SPShape which is not yet, and thus SVG forbids us from putting text on it +#: ../../po/../src/text-chemistry.cpp:101 +msgid "" +"You cannot put text on a rectangle in this version. Convert rectangle to " +"path first." +msgstr "" + +#: ../../po/../src/text-chemistry.cpp:159 +#, fuzzy +msgid "Select a text on path to remove it from path." +msgstr "文档中无渐变" + +#: ../../po/../src/text-chemistry.cpp:181 +#, fuzzy +msgid "No texts-on-paths in the selection." +msgstr "将选定对象转换为曲线" + +#: ../../po/../src/text-chemistry.cpp:209 +#: ../../po/../src/text-chemistry.cpp:229 +#, fuzzy +msgid "Select text(s) to remove kerns from." +msgstr "将选中内容提升到顶层" + +#: ../../po/../src/text-chemistry.cpp:250 +#, fuzzy +msgid "" +"Select a text and one or more paths or shapes to flow text " +"into frame." +msgstr "文档中无渐变" + +#: ../../po/../src/text-chemistry.cpp:322 +#, fuzzy +msgid "Select a flowed text to unflow it." +msgstr "将选定对象转换为曲线" + +#: ../../po/../src/text-context.cpp:463 +msgid "Click to edit the text, drag to select part of the text." +msgstr "" + +#: ../../po/../src/text-context.cpp:465 +msgid "" +"Click to edit the flowed text, drag to select part of the text." +msgstr "" + +#: ../../po/../src/text-context.cpp:540 +msgid "Non-printable character" +msgstr "" + +#: ../../po/../src/text-context.cpp:589 +#, fuzzy, c-format +msgid "Unicode: %s: %s" +msgstr "Sodipodi:%s:%s:%d" + +#: ../../po/../src/text-context.cpp:591 ../../po/../src/text-context.cpp:855 +msgid "Unicode: " +msgstr "" + +#: ../../po/../src/text-context.cpp:615 +msgid "Current layer is hidden. Unhide it to be able to add text." +msgstr "" + +#: ../../po/../src/text-context.cpp:619 +msgid "Current layer is locked. Unlock it to be able to add text." +msgstr "" + +#: ../../po/../src/text-context.cpp:673 +#, c-format +msgid "Flowed text frame: %s × %s" +msgstr "" + +#: ../../po/../src/text-context.cpp:708 ../../po/../src/text-context.cpp:1464 +msgid "Type text; Enter to start new line." +msgstr "" + +#: ../../po/../src/text-context.cpp:719 +msgid "Flowed text is created." +msgstr "" + +#: ../../po/../src/text-context.cpp:722 +msgid "" +"The frame is too small for the current font size. Flowed text not " +"created." +msgstr "" + +#: ../../po/../src/text-context.cpp:841 +msgid "No-break space" +msgstr "" + +#: ../../po/../src/text-context.cpp:1462 +msgid "Type flowed text; Enter to start new paragraph." +msgstr "" + +#: ../../po/../src/text-context.cpp:1472 ../../po/../src/tools-switch.cpp:189 +msgid "" +"Click to select or create text, drag to create flowed text; " +"then type." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:141 +msgid "" +"To edit a path, click, Shift+click, or drag around " +"nodes to select them, then drag nodes and handles. Click on an " +"object to select." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:147 +msgid "" +"Drag to create a rectangle. Drag controls to round corners and " +"resize. Click to select." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:153 +msgid "" +"Drag to create an ellipse. Drag controls to make an arc or " +"segment. Click to select." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:159 +msgid "" +"Drag to create a star. Drag controls to edit the star shape. " +"Click to select." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:165 +msgid "" +"Drag to create a spiral. Drag controls to edit the spiral " +"shape. Click to select." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:171 +msgid "" +"Drag to create a freehand line. Start drawing with Shift to " +"append to selected path." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:177 +msgid "" +"Click or click and drag to start a path; with Shift to " +"append to selected path." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:183 +msgid "" +"Drag to paint a calligraphic stroke. Left/right arrow " +"keys adjust width, up/down adjust angle." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:195 +msgid "" +"Drag or double click to create a gradient on selected objects, " +"drag handles to adjust gradients." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:201 +msgid "" +"Click or drag around an area to zoom in, Shift+click to " +"zoom out." +msgstr "" + +#: ../../po/../src/tools-switch.cpp:213 +msgid "Click and drag between shapes to create a connector." +msgstr "" + +#: ../../po/../src/trace/potrace/inkscape-potrace.cpp:553 +#: ../../po/../src/trace/potrace/inkscape-potrace.cpp:654 +#, c-format +msgid "Trace: %d. %ld nodes" +msgstr "" + +#: ../../po/../src/trace/trace.cpp:53 ../../po/../src/trace/trace.cpp:62 +#: ../../po/../src/trace/trace.cpp:70 +#, fuzzy +msgid "Select an image to trace" +msgstr "将选定对象转换为曲线" + +#: ../../po/../src/trace/trace.cpp:133 +#, fuzzy +msgid "Trace: No active document" +msgstr "内存文档 %d" + +#: ../../po/../src/trace/trace.cpp:154 +msgid "Trace: Image has no bitmap data" +msgstr "" + +#: ../../po/../src/trace/trace.cpp:267 +#, fuzzy, c-format +msgid "Trace: Done. %ld nodes created" +msgstr "最后的选择" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:59 ../../po/../src/verbs.cpp:2212 +msgid "About Inkscape" +msgstr "" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:66 +msgid "_Splash" +msgstr "" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:68 +msgid "_Authors" +msgstr "" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:69 +#, fuzzy +msgid "_Translators" +msgstr "变换" + +#: ../../po/../src/ui/dialog/aboutbox.cpp:70 +#, fuzzy +msgid "_License" +msgstr "英寸" + +#. TRANSLATORS: This is the filename of the `About Inkscape' picture in +#. the `screens' directory. Thus the translation of "about.svg" should be +#. the filename of its translated version, e.g. about.zh.svg for Chinese. +#. +#. N.B. about.svg changes once per release. (We should probably rename +#. the original to about-0.40.svg etc. as soon as we have a translation. +#. If we do so, then add an item to release-checklist saying that the +#. string here should be changed.) +#. FIXME? INKSCAPE_SCREENSDIR and "about.svg" are in UTF-8, not the +#. native filename encoding... and the filename passed to sp_document_new +#. should be in UTF-*8.. +#: ../../po/../src/ui/dialog/aboutbox.cpp:114 +msgid "about.svg" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:464 +msgid "Minimum horizontal gap (in px units) between bounding boxes" +msgstr "" + +#. TRANSLATORS: Horizontal gap +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:466 +#: ../../po/../src/widgets/toolbox.cpp:1556 +msgid "H:" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:474 +msgid "Minimum vertical gap (in px units) between bounding boxes" +msgstr "" + +#. TRANSLATORS: Vertical gap +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:476 +msgid "V:" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:734 +msgid "Align" +msgstr "对齐" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:735 +#, fuzzy +msgid "Distribute" +msgstr "属性" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:736 +msgid "Remove overlaps" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:737 +msgid "Nodes" +msgstr "节点" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:742 +#, fuzzy +msgid "Relative to: " +msgstr "垂直移动" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:747 +#, fuzzy +msgid "Align right sides of objects to left side of anchor" +msgstr "将内部对象对齐到左边" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:750 +#, fuzzy +msgid "Align left sides" +msgstr "对齐到左侧中央" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:753 +#, fuzzy +msgid "Center on vertical axis" +msgstr "垂直翻转" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:756 +#, fuzzy +msgid "Align right sides" +msgstr "对齐到右侧中央" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:759 +#, fuzzy +msgid "Align left sides of objects to right side of anchor" +msgstr "将内部对象对齐到右边" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:762 +#, fuzzy +msgid "Align bottoms of objects to top of anchor" +msgstr "将内部对象对齐到底边" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:765 +#, fuzzy +msgid "Align tops" +msgstr "对齐对象" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:768 +#, fuzzy +msgid "Center on horizontal axis" +msgstr "水平翻转" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:771 +#, fuzzy +msgid "Align bottoms" +msgstr "对齐到底部左侧" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:774 +#, fuzzy +msgid "Align tops of objects to bottom of anchor" +msgstr "将内部对象对齐到顶边" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:779 +#, fuzzy +msgid "Align baseline anchors of texts vertically" +msgstr "翻转选中对象" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:782 +#, fuzzy +msgid "Align baseline anchors of texts horizontally" +msgstr "翻转选中对象" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:787 +msgid "Make horizontal gaps between objects equal" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:791 +#, fuzzy +msgid "Distribute left sides equidistantly" +msgstr "翻转选中对象" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:794 +#, fuzzy +msgid "Distribute centers equidistantly horizontally" +msgstr "翻转选中对象" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:797 +#, fuzzy +msgid "Distribute right sides equidistantly" +msgstr "翻转选中对象" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:801 +msgid "Make vertical gaps between objects equal" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:805 +#, fuzzy +msgid "Distribute tops equidistantly" +msgstr "翻转选中对象" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:808 +#, fuzzy +msgid "Distribute centers equidistantly vertically" +msgstr "翻转选中对象" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:811 +msgid "Distribute bottoms equidistantly" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:816 +#, fuzzy +msgid "Distribute baseline anchors of texts horizontally" +msgstr "翻转选中对象" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:819 +#, fuzzy +msgid "Distribute baseline anchors of texts vertically" +msgstr "翻转选中对象" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:824 +msgid "Randomize centers in both dimensions" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:827 +msgid "Unclump objects: try to equalize edge-to-edge distances" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:832 +msgid "" +"Move objects as little as possible so that their bounding boxes do not " +"overlap" +msgstr "" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:837 +#, fuzzy +msgid "Align selected nodes horizontally" +msgstr "翻转选中对象" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:840 +#, fuzzy +msgid "Align selected nodes vertically" +msgstr "翻转选中对象" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:843 +#, fuzzy +msgid "Distribute selected nodes horizontally" +msgstr "翻转选中对象" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:846 +#, fuzzy +msgid "Distribute selected nodes vertically" +msgstr "翻转选中对象" + +#. Rest of the widgetry +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:851 +msgid "Last selected" +msgstr "最后的选择" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:852 +msgid "First selected" +msgstr "第一个选择" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:853 +msgid "Biggest item" +msgstr "最大项目" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:854 +msgid "Smallest item" +msgstr "最小项目" + +#: ../../po/../src/ui/dialog/align-and-distribute.cpp:856 +#: ../../po/../src/widgets/desktop-widget.cpp:1065 +msgid "Drawing" +msgstr "图画" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:91 +msgid "Metadata 1" +msgstr "" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:92 +msgid "Metadata 2" +msgstr "" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:187 +#, fuzzy +msgid "X coordinate of grid origin" +msgstr "选择指示线颜色" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:189 +#, fuzzy +msgid "Y coordinate of grid origin" +msgstr "选择指示线颜色" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:191 +#, fuzzy +msgid "Distance of vertical grid lines" +msgstr "设置垂直栅格线之间的距离" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:193 +#, fuzzy +msgid "Distance of horizontal grid lines" +msgstr "设置水平栅格线之间的距离" + +#: ../../po/../src/ui/dialog/document-preferences.cpp:197 +msgid "Max. snapping distance from grid" +msgstr "" + +#: ../../po/../src/ui/dialog/export.cpp:34 +msgid "Export" +msgstr "导出" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:36 +msgid "Fill" +msgstr "填充" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:37 +#, fuzzy +msgid "Stroke Paint" +msgstr "勾描宽度" + +#: ../../po/../src/ui/dialog/fill-and-stroke.cpp:38 +#, fuzzy +msgid "Stroke Style" +msgstr "勾描设置" + +#: ../../po/../src/ui/dialog/find.cpp:34 +#, fuzzy +msgid "Find" +msgstr "栅格" + +#: ../../po/../src/ui/dialog/memory.cpp:96 +#, fuzzy +msgid "Heap" +msgstr "求助(_H)" + +#: ../../po/../src/ui/dialog/memory.cpp:97 +#, fuzzy +msgid "In Use" +msgstr "重置" + +#. TRANSLATORS: "Slack" refers to memory which is in the heap but currently unused. +#. More typical usage is to call this memory "free" rather than "slack". +#: ../../po/../src/ui/dialog/memory.cpp:100 +#, fuzzy +msgid "Slack" +msgstr "星形" + +#: ../../po/../src/ui/dialog/memory.cpp:101 +#, fuzzy +msgid "Total" +msgstr "标题:" + +#: ../../po/../src/ui/dialog/memory.cpp:141 +#: ../../po/../src/ui/dialog/memory.cpp:147 +#: ../../po/../src/ui/dialog/memory.cpp:154 +#: ../../po/../src/ui/dialog/memory.cpp:186 +#, fuzzy +msgid "Unknown" +msgstr "未知项目 :-(" + +#: ../../po/../src/ui/dialog/memory.cpp:167 +#, fuzzy +msgid "Combined" +msgstr "组合" + +#: ../../po/../src/ui/dialog/memory.cpp:209 +#, fuzzy +msgid "Recalculate" +msgstr "长方形" + +#: ../../po/../src/ui/dialog/messages.cpp:74 +#, fuzzy +msgid "Ready." +msgstr "重读" + +#: ../../po/../src/ui/dialog/messages.cpp:75 +msgid "" +"Enable log display by setting dialogs.debug 'redirect' attribute to 1 in " +"preferences.xml" +msgstr "" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:184 +msgid "_Execute Python" +msgstr "" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:186 +msgid "_Execute Perl" +msgstr "" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:195 +msgid "Script" +msgstr "" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:205 +#, fuzzy +msgid "Output" +msgstr "剪切" + +#: ../../po/../src/ui/dialog/scriptdialog.cpp:215 +msgid "Errors" +msgstr "" + +#. Dialog organization +#: ../../po/../src/ui/dialog/session-player.cpp:73 +#, fuzzy +msgid "Session file" +msgstr "保存文件" + +#: ../../po/../src/ui/dialog/session-player.cpp:74 +#, fuzzy +msgid "Playback controls" +msgstr "Oaf 选项" + +#: ../../po/../src/ui/dialog/session-player.cpp:75 +#, fuzzy +msgid "Message information" +msgstr "重置变换" + +#. Active session file display +#. fixme: Does this mean the active file for the session, or the file for the active session? +#. Please indicate which with a TRANSLATORS comment. +#: ../../po/../src/ui/dialog/session-player.cpp:85 +msgid "Active session file:" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:86 +msgid "Delay (milliseconds):" +msgstr "" + +#. Unload/load buttons +#: ../../po/../src/ui/dialog/session-player.cpp:94 +#, fuzzy +msgid "Close file" +msgstr "色彩填充" + +#: ../../po/../src/ui/dialog/session-player.cpp:95 +#, fuzzy +msgid "Open new file" +msgstr "打开新图画" + +#: ../../po/../src/ui/dialog/session-player.cpp:96 +msgid "Set delay" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:138 +#, fuzzy +msgid "Rewind" +msgstr "红色:" + +#: ../../po/../src/ui/dialog/session-player.cpp:139 +msgid "Go back one change" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:140 +#, fuzzy +msgid "Pause" +msgstr "粘贴" + +#: ../../po/../src/ui/dialog/session-player.cpp:141 +msgid "Go forward one change" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:142 +msgid "Play" +msgstr "" + +#: ../../po/../src/ui/dialog/session-player.cpp:177 +#: ../../po/../src/verbs.cpp:1573 +msgid "Open session file" +msgstr "" + +#. ##Set up the Potrace panel +#. #### brightness #### +#. #### Multiple scanning#### +#. ----Hbox1 +#: ../../po/../src/ui/dialog/tracedialog.cpp:345 +#: ../../po/../src/ui/dialog/tracedialog.cpp:428 +#, fuzzy +msgid "Brightness" +msgstr "高度" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:348 +msgid "Trace by a given brightness level" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:355 +msgid "Brightness cutoff for black/white" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:362 +#, fuzzy +msgid "Image Brightness" +msgstr "图像大小" + +#. #### canny edge detection #### +#. TRANSLATORS: "Canny" is the name of the inventor of this edge detection method +#: ../../po/../src/ui/dialog/tracedialog.cpp:369 +msgid "Optimal Edge Detection (Canny)" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:372 +msgid "Trace with edge detection by J. Canny's algorithm" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:388 +msgid "Brightness cutoff for adjacent pixels (determines edge thickness)" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:395 +#, fuzzy +msgid "Edge Detection" +msgstr "选择" + +#. #### quantization #### +#. TRANSLATORS: Color Quantization: the process of reducing the number of colors +#. in an image by selecting an optimized set of representative colors and then +#. re-applying this reduced set to the original image. +#: ../../po/../src/ui/dialog/tracedialog.cpp:404 +#, fuzzy +msgid "Color Quantization" +msgstr "彩色颜料" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:407 +msgid "Trace along the boundaries of reduced colors" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:414 +msgid "The number of reduced colors" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:416 +#, fuzzy +msgid "Colors:" +msgstr "颜色" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:421 +msgid "Quantization / Reduction" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:431 +msgid "Trace the given number of brightness levels" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:438 +#, fuzzy +msgid "Scans:" +msgstr "形状" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:440 +msgid "The desired number of scans" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:448 +msgid "Trace the given number of reduced colors" +msgstr "" + +#. ---Hbox3 +#: ../../po/../src/ui/dialog/tracedialog.cpp:454 +msgid "Monochrome" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:457 +msgid "Same as Color, but convert result to grayscale" +msgstr "" + +#. TRANSLATORS: "Stack" is a verb here +#: ../../po/../src/ui/dialog/tracedialog.cpp:460 +#, fuzzy +msgid "Stack" +msgstr "星形" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:463 +msgid "" +"Stack scans vertically (no gaps) or tile horizontally (usually with gaps)" +msgstr "" + +#. TRANSLATORS: "Smooth" is a verb here +#: ../../po/../src/ui/dialog/tracedialog.cpp:466 +msgid "Smooth" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:469 +msgid "Apply Gaussian blur to the bitmap before tracing" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:473 +msgid "Multiple Scanning" +msgstr "" + +#. #### Preview #### +#: ../../po/../src/ui/dialog/tracedialog.cpp:479 +#: ../../po/../src/ui/dialog/tracedialog.cpp:489 +#, fuzzy +msgid "Preview" +msgstr "新建预览" + +#. do not expand +#: ../../po/../src/ui/dialog/tracedialog.cpp:483 +msgid "Preview the result without actual tracing" +msgstr "" + +#. #### swap black and white #### +#: ../../po/../src/ui/dialog/tracedialog.cpp:495 +#, fuzzy +msgid "Invert" +msgstr "重置" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:499 +msgid "Invert black and white regions for single traces" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:503 +msgid "Thanks to Peter Selinger, http://potrace.sourceforge.net" +msgstr "" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:506 +#, fuzzy +msgid "Credits" +msgstr "彩色颜料" + +#. done +#. TRANSLATORS: Potrace is an application for transforming bitmaps into +#. vector graphics (http://potrace.sourceforge.net/) +#: ../../po/../src/ui/dialog/tracedialog.cpp:514 +#, fuzzy +msgid "Potrace" +msgstr "点" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:527 +#, fuzzy +msgid "Abort a trace in progress" +msgstr "导出为" + +#: ../../po/../src/ui/dialog/tracedialog.cpp:531 +msgid "Execute the trace" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:80 +#: ../../po/../src/ui/dialog/transformation.cpp:90 +#, fuzzy +msgid "_Horizontal" +msgstr "水平移动" + +#: ../../po/../src/ui/dialog/transformation.cpp:80 +msgid "Horizontal displacement (relative) or position (absolute)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:82 +#: ../../po/../src/ui/dialog/transformation.cpp:92 +#, fuzzy +msgid "_Vertical" +msgstr "垂直中心值" + +#: ../../po/../src/ui/dialog/transformation.cpp:82 +msgid "Vertical displacement (relative) or position (absolute)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:84 +#, fuzzy +msgid "_Width" +msgstr "宽度:" + +#: ../../po/../src/ui/dialog/transformation.cpp:84 +msgid "Horizontal size increment (absolute or percentage)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:86 +#, fuzzy +msgid "_Height" +msgstr "高度:" + +#: ../../po/../src/ui/dialog/transformation.cpp:86 +msgid "Vertical size increment (absolute or percentage)" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:88 +#, fuzzy +msgid "A_ngle" +msgstr "角度" + +#: ../../po/../src/ui/dialog/transformation.cpp:88 +#, fuzzy +msgid "Rotation angle (positive = counterclockwise)" +msgstr "将选定对象顺时针旋转 90 度" + +#: ../../po/../src/ui/dialog/transformation.cpp:90 +msgid "" +"Horizontal skew angle (positive = counterclockwise), or absolute " +"displacement, or percentage displacement" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:92 +msgid "" +"Vertical skew angle (positive = counterclockwise), or absolute displacement, " +"or percentage displacement" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:95 +#, fuzzy +msgid "Transformation matrix element A" +msgstr "转化" + +#: ../../po/../src/ui/dialog/transformation.cpp:96 +#, fuzzy +msgid "Transformation matrix element B" +msgstr "转化" + +#: ../../po/../src/ui/dialog/transformation.cpp:97 +#, fuzzy +msgid "Transformation matrix element C" +msgstr "转化" + +#: ../../po/../src/ui/dialog/transformation.cpp:98 +#, fuzzy +msgid "Transformation matrix element D" +msgstr "转化" + +#: ../../po/../src/ui/dialog/transformation.cpp:99 +#, fuzzy +msgid "Transformation matrix element E" +msgstr "转化" + +#: ../../po/../src/ui/dialog/transformation.cpp:100 +#, fuzzy +msgid "Transformation matrix element F" +msgstr "转化" + +#: ../../po/../src/ui/dialog/transformation.cpp:102 +#, fuzzy +msgid "Rela_tive move" +msgstr "垂直移动" + +#: ../../po/../src/ui/dialog/transformation.cpp:102 +msgid "" +"Add the specified relative displacement to the current position; otherwise, " +"edit the current absolute position directly" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:103 +msgid "Scale proportionally" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:103 +msgid "Preserve the width/height ratio of the scaled objects" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:104 +msgid "Apply to each _object separately" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:104 +msgid "" +"Apply the scale/rotate/skew to each selected object separately; otherwise, " +"transform the selection as a whole" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:105 +msgid "Edit c_urrent matrix" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:105 +msgid "" +"Edit the current transform= matrix; otherwise, post-multiply transform= by " +"this matrix" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:115 +#, fuzzy +msgid "_Move" +msgstr "移动" + +#: ../../po/../src/ui/dialog/transformation.cpp:118 +#, fuzzy +msgid "_Scale" +msgstr "缩放" + +#: ../../po/../src/ui/dialog/transformation.cpp:121 +#, fuzzy +msgid "_Rotate" +msgstr "旋转" + +#: ../../po/../src/ui/dialog/transformation.cpp:124 +#, fuzzy +msgid "Ske_w" +msgstr "扭曲" + +#: ../../po/../src/ui/dialog/transformation.cpp:127 +msgid "Matri_x" +msgstr "" + +#: ../../po/../src/ui/dialog/transformation.cpp:141 +#, fuzzy +msgid "Reset the values on the current tab to defaults" +msgstr "将对话框内容重置为默认值 - Ctl+r" + +#: ../../po/../src/ui/dialog/transformation.cpp:148 +#, fuzzy +msgid "Apply transformation to selection" +msgstr "对副本应用变换 Ctl+m" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:43 +msgid "_Use SSL" +msgstr "" + +#. Construct dialog interface +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:68 +#, fuzzy +msgid "_Server:" +msgstr "文件" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:69 +#, fuzzy +msgid "_Username:" +msgstr "文件名:" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:70 +msgid "_Password:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:71 +msgid "P_ort:" +msgstr "" + +#. Buttons +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:99 +#, fuzzy +msgid "Connect" +msgstr "内容" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:126 +msgid "Establishing connection to Jabber server %1 as user %2" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:131 +msgid "Failed to establish connection to Jabber server %1" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:136 +msgid "Authentication failed on Jabber server %1 as %2" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:141 +msgid "SSL initialization failed when connecting to Jabber server %1" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-connect.cpp:147 +msgid "Connected to Jabber server %1 as %2" +msgstr "" + +#. Construct labels +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:75 +msgid "Chatroom _name:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:76 +msgid "Chatroom _server:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:77 +msgid "Chatroom _password:" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:78 +msgid "Chatroom _handle:" +msgstr "" + +#. Button setup and callback registration +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:97 +msgid "Connect to chatroom" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithchat.cpp:132 +msgid "Synchronizing with chatroom %1@%2 using the handle %3" +msgstr "" + +#. Construct dialog interface +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:78 +msgid "_User's Jabber ID:" +msgstr "" + +#. Buttons +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:82 +msgid "_Invite user" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:83 +#, fuzzy +msgid "_Cancel" +msgstr "改变" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:94 +msgid "Buddy List" +msgstr "" + +#: ../../po/../src/ui/dialog/whiteboard-sharewithuser.cpp:170 +msgid "Sending whiteboard invitation to %1" +msgstr "" + +#. FIXME: strings are replaced by placeholders, NOT to be translated until the code is enabled +#. See http://sourceforge.net/mailarchive/message.php?msg_id=11746016 for details +#. File menu +#. Edit menu +#. View menu +#. Layer menu +#. Object menu +#. Path menu +#. add(Gtk::StockItem(CLEANUP, _("PLACEHOLDER, do not translate"))); (using Gtk::Stock::CLEAR) +#. Text menu +#. About menu +#. Tools toolbox +#. Select Tool controls +#. Node Tool controls +#. Calligraphy Tool controls +#. Session playback controls +#: ../../po/../src/ui/stock-items.cpp:34 ../../po/../src/ui/stock-items.cpp:35 +#: ../../po/../src/ui/stock-items.cpp:36 ../../po/../src/ui/stock-items.cpp:37 +#: ../../po/../src/ui/stock-items.cpp:38 ../../po/../src/ui/stock-items.cpp:39 +#: ../../po/../src/ui/stock-items.cpp:40 ../../po/../src/ui/stock-items.cpp:41 +#: ../../po/../src/ui/stock-items.cpp:42 ../../po/../src/ui/stock-items.cpp:43 +#: ../../po/../src/ui/stock-items.cpp:46 ../../po/../src/ui/stock-items.cpp:47 +#: ../../po/../src/ui/stock-items.cpp:48 ../../po/../src/ui/stock-items.cpp:49 +#: ../../po/../src/ui/stock-items.cpp:50 ../../po/../src/ui/stock-items.cpp:51 +#: ../../po/../src/ui/stock-items.cpp:52 ../../po/../src/ui/stock-items.cpp:53 +#: ../../po/../src/ui/stock-items.cpp:54 ../../po/../src/ui/stock-items.cpp:55 +#: ../../po/../src/ui/stock-items.cpp:56 ../../po/../src/ui/stock-items.cpp:57 +#: ../../po/../src/ui/stock-items.cpp:58 ../../po/../src/ui/stock-items.cpp:59 +#: ../../po/../src/ui/stock-items.cpp:62 ../../po/../src/ui/stock-items.cpp:63 +#: ../../po/../src/ui/stock-items.cpp:64 ../../po/../src/ui/stock-items.cpp:65 +#: ../../po/../src/ui/stock-items.cpp:66 ../../po/../src/ui/stock-items.cpp:67 +#: ../../po/../src/ui/stock-items.cpp:68 ../../po/../src/ui/stock-items.cpp:69 +#: ../../po/../src/ui/stock-items.cpp:70 ../../po/../src/ui/stock-items.cpp:71 +#: ../../po/../src/ui/stock-items.cpp:72 ../../po/../src/ui/stock-items.cpp:73 +#: ../../po/../src/ui/stock-items.cpp:74 ../../po/../src/ui/stock-items.cpp:75 +#: ../../po/../src/ui/stock-items.cpp:76 ../../po/../src/ui/stock-items.cpp:77 +#: ../../po/../src/ui/stock-items.cpp:78 ../../po/../src/ui/stock-items.cpp:79 +#: ../../po/../src/ui/stock-items.cpp:80 ../../po/../src/ui/stock-items.cpp:81 +#: ../../po/../src/ui/stock-items.cpp:82 ../../po/../src/ui/stock-items.cpp:83 +#: ../../po/../src/ui/stock-items.cpp:84 ../../po/../src/ui/stock-items.cpp:85 +#: ../../po/../src/ui/stock-items.cpp:86 ../../po/../src/ui/stock-items.cpp:87 +#: ../../po/../src/ui/stock-items.cpp:88 ../../po/../src/ui/stock-items.cpp:89 +#: ../../po/../src/ui/stock-items.cpp:92 ../../po/../src/ui/stock-items.cpp:93 +#: ../../po/../src/ui/stock-items.cpp:94 ../../po/../src/ui/stock-items.cpp:95 +#: ../../po/../src/ui/stock-items.cpp:96 ../../po/../src/ui/stock-items.cpp:97 +#: ../../po/../src/ui/stock-items.cpp:98 ../../po/../src/ui/stock-items.cpp:99 +#: ../../po/../src/ui/stock-items.cpp:100 +#: ../../po/../src/ui/stock-items.cpp:101 +#: ../../po/../src/ui/stock-items.cpp:102 +#: ../../po/../src/ui/stock-items.cpp:103 +#: ../../po/../src/ui/stock-items.cpp:104 +#: ../../po/../src/ui/stock-items.cpp:105 +#: ../../po/../src/ui/stock-items.cpp:108 +#: ../../po/../src/ui/stock-items.cpp:109 +#: ../../po/../src/ui/stock-items.cpp:110 +#: ../../po/../src/ui/stock-items.cpp:111 +#: ../../po/../src/ui/stock-items.cpp:112 +#: ../../po/../src/ui/stock-items.cpp:113 +#: ../../po/../src/ui/stock-items.cpp:114 +#: ../../po/../src/ui/stock-items.cpp:115 +#: ../../po/../src/ui/stock-items.cpp:116 +#: ../../po/../src/ui/stock-items.cpp:117 +#: ../../po/../src/ui/stock-items.cpp:118 +#: ../../po/../src/ui/stock-items.cpp:119 +#: ../../po/../src/ui/stock-items.cpp:120 +#: ../../po/../src/ui/stock-items.cpp:121 +#: ../../po/../src/ui/stock-items.cpp:122 +#: ../../po/../src/ui/stock-items.cpp:123 +#: ../../po/../src/ui/stock-items.cpp:124 +#: ../../po/../src/ui/stock-items.cpp:125 +#: ../../po/../src/ui/stock-items.cpp:126 +#: ../../po/../src/ui/stock-items.cpp:127 +#: ../../po/../src/ui/stock-items.cpp:130 +#: ../../po/../src/ui/stock-items.cpp:131 +#: ../../po/../src/ui/stock-items.cpp:132 +#: ../../po/../src/ui/stock-items.cpp:133 +#: ../../po/../src/ui/stock-items.cpp:134 +#: ../../po/../src/ui/stock-items.cpp:135 +#: ../../po/../src/ui/stock-items.cpp:136 +#: ../../po/../src/ui/stock-items.cpp:137 +#: ../../po/../src/ui/stock-items.cpp:138 +#: ../../po/../src/ui/stock-items.cpp:139 +#: ../../po/../src/ui/stock-items.cpp:140 +#: ../../po/../src/ui/stock-items.cpp:141 +#: ../../po/../src/ui/stock-items.cpp:142 +#: ../../po/../src/ui/stock-items.cpp:143 +#: ../../po/../src/ui/stock-items.cpp:144 +#: ../../po/../src/ui/stock-items.cpp:145 +#: ../../po/../src/ui/stock-items.cpp:146 +#: ../../po/../src/ui/stock-items.cpp:150 +#: ../../po/../src/ui/stock-items.cpp:151 +#: ../../po/../src/ui/stock-items.cpp:152 +#: ../../po/../src/ui/stock-items.cpp:153 +#: ../../po/../src/ui/stock-items.cpp:156 +#: ../../po/../src/ui/stock-items.cpp:157 +#: ../../po/../src/ui/stock-items.cpp:158 +#: ../../po/../src/ui/stock-items.cpp:161 +#: ../../po/../src/ui/stock-items.cpp:162 +#: ../../po/../src/ui/stock-items.cpp:163 +#: ../../po/../src/ui/stock-items.cpp:164 +#: ../../po/../src/ui/stock-items.cpp:165 +#: ../../po/../src/ui/stock-items.cpp:166 +#: ../../po/../src/ui/stock-items.cpp:167 +#: ../../po/../src/ui/stock-items.cpp:168 +#: ../../po/../src/ui/stock-items.cpp:169 +#: ../../po/../src/ui/stock-items.cpp:170 +#: ../../po/../src/ui/stock-items.cpp:171 +#: ../../po/../src/ui/stock-items.cpp:172 +#: ../../po/../src/ui/stock-items.cpp:175 +#: ../../po/../src/ui/stock-items.cpp:176 +#: ../../po/../src/ui/stock-items.cpp:177 +#: ../../po/../src/ui/stock-items.cpp:178 +#: ../../po/../src/ui/stock-items.cpp:181 +#: ../../po/../src/ui/stock-items.cpp:182 +#: ../../po/../src/ui/stock-items.cpp:183 +#: ../../po/../src/ui/stock-items.cpp:184 +#: ../../po/../src/ui/stock-items.cpp:185 +#: ../../po/../src/ui/stock-items.cpp:186 +#: ../../po/../src/ui/stock-items.cpp:187 +#: ../../po/../src/ui/stock-items.cpp:188 +#: ../../po/../src/ui/stock-items.cpp:189 +#: ../../po/../src/ui/stock-items.cpp:190 +#: ../../po/../src/ui/stock-items.cpp:191 +#: ../../po/../src/ui/stock-items.cpp:194 +#: ../../po/../src/ui/stock-items.cpp:195 +#: ../../po/../src/ui/stock-items.cpp:198 +#: ../../po/../src/ui/stock-items.cpp:199 +#: ../../po/../src/ui/stock-items.cpp:200 +#: ../../po/../src/ui/stock-items.cpp:201 +#: ../../po/../src/ui/stock-items.cpp:202 +msgid "PLACEHOLDER, do not translate" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:88 +msgid "small" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:89 +msgid "medium" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:90 +#, fuzzy +msgid "large" +msgstr "目标:" + +#: ../../po/../src/ui/widget/panel.cpp:91 +msgid "huge" +msgstr "" + +#: ../../po/../src/ui/widget/panel.cpp:106 +#, fuzzy +msgid "List" +msgstr "英寸" + +#: ../../po/../src/ui/widget/selected-style.cpp:67 +msgid "F:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:68 +msgid "S:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:69 +msgid "O:" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:95 +msgid "N/A" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:98 +#: ../../po/../src/ui/widget/selected-style.cpp:712 +#, fuzzy +msgid "Nothing selected" +msgstr "删除选定节点" + +#: ../../po/../src/ui/widget/selected-style.cpp:103 +msgid "No fill" +msgstr "不填充" + +#: ../../po/../src/ui/widget/selected-style.cpp:103 +#, fuzzy +msgid "No stroke" +msgstr "已被勾描" + +#: ../../po/../src/ui/widget/selected-style.cpp:105 +#: ../../po/../src/widgets/paint-selector.cpp:190 +#, fuzzy +msgid "Pattern" +msgstr "模式填充" + +#: ../../po/../src/ui/widget/selected-style.cpp:108 +#: ../../po/../src/widgets/paint-selector.cpp:885 +#, fuzzy +msgid "Pattern fill" +msgstr "模式填充" + +#: ../../po/../src/ui/widget/selected-style.cpp:108 +#, fuzzy +msgid "Pattern stroke" +msgstr "模式填充" + +#: ../../po/../src/ui/widget/selected-style.cpp:110 +#, fuzzy +msgid "L Gradient" +msgstr "渐变填充" + +#: ../../po/../src/ui/widget/selected-style.cpp:113 +#, fuzzy +msgid "Linear gradient fill" +msgstr "添加新渐变" + +#: ../../po/../src/ui/widget/selected-style.cpp:113 +#, fuzzy +msgid "Linear gradient stroke" +msgstr "添加新渐变" + +#: ../../po/../src/ui/widget/selected-style.cpp:115 +#, fuzzy +msgid "R Gradient" +msgstr "渐变填充" + +#: ../../po/../src/ui/widget/selected-style.cpp:118 +#, fuzzy +msgid "Radial gradient fill" +msgstr "添加新渐变" + +#: ../../po/../src/ui/widget/selected-style.cpp:118 +#, fuzzy +msgid "Radial gradient stroke" +msgstr "添加新渐变" + +#: ../../po/../src/ui/widget/selected-style.cpp:120 +#, fuzzy +msgid "Different" +msgstr "度" + +#: ../../po/../src/ui/widget/selected-style.cpp:123 +#, fuzzy +msgid "Different fills" +msgstr "度" + +#: ../../po/../src/ui/widget/selected-style.cpp:123 +#, fuzzy +msgid "Different strokes" +msgstr "度" + +#: ../../po/../src/ui/widget/selected-style.cpp:125 +#, fuzzy +msgid "Unset" +msgstr "英寸" + +#. TRANSLATORS COMMENT: unset is a verb here +#: ../../po/../src/ui/widget/selected-style.cpp:128 +#: ../../po/../src/ui/widget/selected-style.cpp:182 +#, fuzzy +msgid "Unset fill" +msgstr "单位" + +#: ../../po/../src/ui/widget/selected-style.cpp:128 +#: ../../po/../src/ui/widget/selected-style.cpp:182 +#, fuzzy +msgid "Unset stroke" +msgstr "已被勾描" + +#: ../../po/../src/ui/widget/selected-style.cpp:131 +#, fuzzy +msgid "Flat color fill" +msgstr "纯色" + +#: ../../po/../src/ui/widget/selected-style.cpp:131 +#, fuzzy +msgid "Flat color stroke" +msgstr "纯色" + +#. TRANSLATOR COMMENT: A means "Averaged" +#: ../../po/../src/ui/widget/selected-style.cpp:134 +#, fuzzy +msgid "A" +msgstr "A4" + +#: ../../po/../src/ui/widget/selected-style.cpp:137 +#, fuzzy +msgid "Fill is averaged over selected objects" +msgstr "编辑选中对象的布局" + +#: ../../po/../src/ui/widget/selected-style.cpp:137 +#, fuzzy +msgid "Stroke is averaged over selected objects" +msgstr "编辑选中对象的勾描风格" + +#. TRANSLATOR COMMENT: M means "Multiple" +#: ../../po/../src/ui/widget/selected-style.cpp:140 +msgid "M" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:143 +#, fuzzy +msgid "Multiple selected objects have the same fill" +msgstr "翻转选中对象" + +#: ../../po/../src/ui/widget/selected-style.cpp:143 +#, fuzzy +msgid "Multiple selected objects have the same stroke" +msgstr "翻转选中对象" + +#: ../../po/../src/ui/widget/selected-style.cpp:145 +#, fuzzy +msgid "Edit fill..." +msgstr "编辑..." + +#: ../../po/../src/ui/widget/selected-style.cpp:145 +#, fuzzy +msgid "Edit stroke..." +msgstr "编辑..." + +#: ../../po/../src/ui/widget/selected-style.cpp:149 +#, fuzzy +msgid "Last set color" +msgstr "纯色" + +#: ../../po/../src/ui/widget/selected-style.cpp:153 +#, fuzzy +msgid "Last selected color" +msgstr "最后的选择" + +#: ../../po/../src/ui/widget/selected-style.cpp:157 +msgid "White" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:161 +#: ../../po/../src/widgets/sp-color-scales.cpp:461 +#: ../../po/../src/widgets/sp-color-scales.cpp:462 +#, fuzzy +msgid "Black" +msgstr "黑:" + +#: ../../po/../src/ui/widget/selected-style.cpp:165 +#, fuzzy +msgid "Copy color" +msgstr "起点颜色" + +#: ../../po/../src/ui/widget/selected-style.cpp:169 +#, fuzzy +msgid "Paste color" +msgstr "纯色" + +#: ../../po/../src/ui/widget/selected-style.cpp:173 +#, fuzzy +msgid "Swap fill and stroke" +msgstr "填充并勾描" + +#: ../../po/../src/ui/widget/selected-style.cpp:177 +msgid "Make fill opaque" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:177 +msgid "Make stroke opaque" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:186 +#, fuzzy +msgid "Remove fill" +msgstr "删除连接" + +#: ../../po/../src/ui/widget/selected-style.cpp:186 +#, fuzzy +msgid "Remove stroke" +msgstr "删除连接" + +#: ../../po/../src/ui/widget/selected-style.cpp:718 +#, fuzzy +msgid "Master opacity" +msgstr "不透明度:" + +#: ../../po/../src/ui/widget/selected-style.cpp:744 +msgid "0 (transparent)" +msgstr "" + +#: ../../po/../src/ui/widget/selected-style.cpp:768 +msgid "1.0 (opaque)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1046 +msgid "Moved to next layer." +msgstr "" + +#: ../../po/../src/verbs.cpp:1048 +msgid "Cannot move past last layer." +msgstr "" + +#: ../../po/../src/verbs.cpp:1057 +msgid "Moved to previous layer." +msgstr "" + +#: ../../po/../src/verbs.cpp:1059 +msgid "Cannot move past first layer." +msgstr "" + +#: ../../po/../src/verbs.cpp:1076 ../../po/../src/verbs.cpp:1150 +#, fuzzy +msgid "No current layer." +msgstr "文档" + +#: ../../po/../src/verbs.cpp:1105 +#, fuzzy, c-format +msgid "Raised layer %s." +msgstr "提升" + +#: ../../po/../src/verbs.cpp:1109 +#, fuzzy, c-format +msgid "Lowered layer %s." +msgstr "选择" + +#: ../../po/../src/verbs.cpp:1118 +msgid "Cannot move layer any further." +msgstr "" + +#. TRANSLATORS: this means "The layer has been deleted." +#: ../../po/../src/verbs.cpp:1148 +#, fuzzy +msgid "Deleted layer." +msgstr "选择" + +#: ../../po/../src/verbs.cpp:1544 +msgid "" +"You need to connect to a Jabber server before sharing a document with " +"another user." +msgstr "" + +#: ../../po/../src/verbs.cpp:1559 +msgid "" +"You need to connect to a Jabber server before sharing a document with a " +"chatroom." +msgstr "" + +#: ../../po/../src/verbs.cpp:1569 +msgid "XML node tracker has not been initialized; nothing to dump" +msgstr "" + +#. TRANSLATORS: If you have translated the keys.svg file to your language, then +#. translate this string as "keys.LANG.svg" (where LANG is your language code); +#. otherwise leave as "keys.svg". +#: ../../po/../src/verbs.cpp:1631 +msgid "keys.svg" +msgstr "" + +#. TRANSLATORS: If you have translated the tutorial-basic.svg file to your language, +#. then translate this string as "tutorial-basic.LANG.svg" (where LANG is your language +#. code); otherwise leave as "tutorial-basic.svg". +#: ../../po/../src/verbs.cpp:1667 +msgid "tutorial-basic.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1671 +msgid "tutorial-shapes.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1675 +msgid "tutorial-advanced.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1679 +msgid "tutorial-tracing.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1683 +msgid "tutorial-calligraphy.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1687 +msgid "tutorial-elements.svg" +msgstr "" + +#. TRANSLATORS: See "tutorial-basic.svg" comment. +#: ../../po/../src/verbs.cpp:1691 +msgid "tutorial-tips.svg" +msgstr "" + +#: ../../po/../src/verbs.cpp:1842 +msgid "Does nothing" +msgstr "" + +#. File +#: ../../po/../src/verbs.cpp:1845 +#, fuzzy +msgid "Default" +msgstr "删除" + +#: ../../po/../src/verbs.cpp:1845 +#, fuzzy +msgid "Create new document from default template" +msgstr "内存文档 %d" + +#: ../../po/../src/verbs.cpp:1847 +#, fuzzy +msgid "_Open..." +msgstr "打开" + +#: ../../po/../src/verbs.cpp:1848 +#, fuzzy +msgid "Open existing document" +msgstr "未命名文档 %d" + +#: ../../po/../src/verbs.cpp:1849 +#, fuzzy +msgid "Re_vert" +msgstr "重置" + +#: ../../po/../src/verbs.cpp:1850 +msgid "Revert to the last saved version of document (changes will be lost)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1851 +#, fuzzy +msgid "_Save" +msgstr "保存" + +#: ../../po/../src/verbs.cpp:1851 +#, fuzzy +msgid "Save document" +msgstr "内存文档 %d" + +#: ../../po/../src/verbs.cpp:1853 +#, fuzzy +msgid "Save _As..." +msgstr "保存为" + +#: ../../po/../src/verbs.cpp:1854 +#, fuzzy +msgid "Save document under new name" +msgstr "以新文件名保存图画" + +#: ../../po/../src/verbs.cpp:1855 +#, fuzzy +msgid "_Print..." +msgstr "打印" + +#: ../../po/../src/verbs.cpp:1855 +#, fuzzy +msgid "Print document" +msgstr "未命名文档 %d" + +#. TRANSLATORS: "Vacuum Defs" means "Clean up defs" (so as to remove unused definitions) +#: ../../po/../src/verbs.cpp:1858 +msgid "Vac_uum Defs" +msgstr "" + +#: ../../po/../src/verbs.cpp:1858 +msgid "Remove unused predefined items from the <defs> of the document" +msgstr "" + +#: ../../po/../src/verbs.cpp:1860 +#, fuzzy +msgid "Print _Direct" +msgstr "连接属性" + +#: ../../po/../src/verbs.cpp:1861 +msgid "Print directly without prompting to a file or pipe" +msgstr "" + +#: ../../po/../src/verbs.cpp:1862 +#, fuzzy +msgid "Print Previe_w" +msgstr "打印预览" + +#: ../../po/../src/verbs.cpp:1863 +#, fuzzy +msgid "Preview document printout" +msgstr "预览打印图画" + +#: ../../po/../src/verbs.cpp:1864 +#, fuzzy +msgid "_Import..." +msgstr "导入" + +#: ../../po/../src/verbs.cpp:1865 +msgid "Import bitmap or SVG image into document" +msgstr "" + +#: ../../po/../src/verbs.cpp:1866 +#, fuzzy +msgid "_Export Bitmap..." +msgstr "彩色位图" + +#: ../../po/../src/verbs.cpp:1867 +#, fuzzy +msgid "Export document or selection as a bitmap image" +msgstr "将图形导出为 png" + +#: ../../po/../src/verbs.cpp:1868 +#, fuzzy +msgid "N_ext Window" +msgstr "关闭窗口" + +#: ../../po/../src/verbs.cpp:1869 +msgid "Switch to the next document window" +msgstr "" + +#: ../../po/../src/verbs.cpp:1870 +#, fuzzy +msgid "P_revious Window" +msgstr "关闭窗口" + +#: ../../po/../src/verbs.cpp:1871 +msgid "Switch to the previous document window" +msgstr "" + +#: ../../po/../src/verbs.cpp:1872 +#, fuzzy +msgid "_Close" +msgstr "关闭视图" + +#: ../../po/../src/verbs.cpp:1873 +#, fuzzy +msgid "Close window" +msgstr "关闭视图" + +#: ../../po/../src/verbs.cpp:1874 +#, fuzzy +msgid "_Quit" +msgstr "退出(_Q)" + +#: ../../po/../src/verbs.cpp:1874 +#, fuzzy +msgid "Quit Inkscape" +msgstr "Sodipodi:%s:%s:%d" + +#. Edit +#: ../../po/../src/verbs.cpp:1877 +#, fuzzy +msgid "_Undo" +msgstr "撤消" + +#: ../../po/../src/verbs.cpp:1877 +#, fuzzy +msgid "Undo last action" +msgstr "重置变换" + +#: ../../po/../src/verbs.cpp:1879 +#, fuzzy +msgid "_Redo" +msgstr "恢复" + +#: ../../po/../src/verbs.cpp:1880 +msgid "Do again last undone action" +msgstr "" + +#: ../../po/../src/verbs.cpp:1881 +#, fuzzy +msgid "Cu_t" +msgstr "剪切" + +#: ../../po/../src/verbs.cpp:1882 +#, fuzzy +msgid "Cut selection to clipboard" +msgstr "将选定对象转换为曲线" + +#: ../../po/../src/verbs.cpp:1883 +#, fuzzy +msgid "_Copy" +msgstr "复制" + +#: ../../po/../src/verbs.cpp:1884 +#, fuzzy +msgid "Copy selection to clipboard" +msgstr "将选中内容复制到剪贴板" + +#: ../../po/../src/verbs.cpp:1885 +#, fuzzy +msgid "_Paste" +msgstr "粘贴" + +#: ../../po/../src/verbs.cpp:1886 +#, fuzzy +msgid "Paste objects from clipboard to mouse point" +msgstr "从剪贴板中粘贴" + +#: ../../po/../src/verbs.cpp:1887 +#, fuzzy +msgid "Paste _Style" +msgstr "勾描风格" + +#: ../../po/../src/verbs.cpp:1888 +#, fuzzy +msgid "Apply style of the copied object to selection" +msgstr "将选中内容复制到剪贴板" + +#: ../../po/../src/verbs.cpp:1889 +#, fuzzy +msgid "Paste _In Place" +msgstr "勾描风格" + +#: ../../po/../src/verbs.cpp:1890 +#, fuzzy +msgid "Paste objects from clipboard to the original location" +msgstr "将对象对齐到水平中央" + +#: ../../po/../src/verbs.cpp:1891 +#, fuzzy +msgid "_Delete" +msgstr "删除" + +#: ../../po/../src/verbs.cpp:1892 +#, fuzzy +msgid "Delete selection" +msgstr "复制选中内容" + +#: ../../po/../src/verbs.cpp:1893 +#, fuzzy +msgid "Duplic_ate" +msgstr "复制" + +#: ../../po/../src/verbs.cpp:1894 +#, fuzzy +msgid "Duplicate selected objects" +msgstr "翻转选中对象" + +#: ../../po/../src/verbs.cpp:1895 +#, fuzzy +msgid "Clo_ne" +msgstr "关闭视图" + +#: ../../po/../src/verbs.cpp:1896 +msgid "Create a clone of selected object (a copy linked to the original)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1897 +msgid "Unlin_k Clone" +msgstr "" + +#: ../../po/../src/verbs.cpp:1898 +msgid "Cut the clone's link to its original" +msgstr "" + +#: ../../po/../src/verbs.cpp:1899 +#, fuzzy +msgid "Select _Original" +msgstr "选择" + +#: ../../po/../src/verbs.cpp:1900 +#, fuzzy +msgid "Select the object to which the clone is linked" +msgstr "将选定对象转换为曲线" + +#. TRANSLATORS: Convert selection to a rectangle with tiled pattern fill +#: ../../po/../src/verbs.cpp:1902 +#, fuzzy +msgid "O_bjects to Pattern" +msgstr "重置变换" + +#: ../../po/../src/verbs.cpp:1903 +msgid "Convert selection to a rectangle with tiled pattern fill" +msgstr "" + +#. TRANSLATORS: Extract objects from a tiled pattern fill +#: ../../po/../src/verbs.cpp:1905 +#, fuzzy +msgid "Pattern to Ob_jects" +msgstr "翻转选中对象" + +#: ../../po/../src/verbs.cpp:1906 +msgid "Extract objects from a tiled pattern fill" +msgstr "" + +#: ../../po/../src/verbs.cpp:1907 +#, fuzzy +msgid "Clea_r All" +msgstr "色彩填充" + +#: ../../po/../src/verbs.cpp:1908 +msgid "Delete all objects from document" +msgstr "" + +#: ../../po/../src/verbs.cpp:1909 +#, fuzzy +msgid "Select Al_l" +msgstr "选择" + +#: ../../po/../src/verbs.cpp:1910 +#, fuzzy +msgid "Select all objects or all nodes" +msgstr "文档中无渐变" + +#: ../../po/../src/verbs.cpp:1911 +#, fuzzy +msgid "Select All in All La_yers" +msgstr "选择" + +#: ../../po/../src/verbs.cpp:1912 +#, fuzzy +msgid "Select all objects in all visible and unlocked layers" +msgstr "文档中无渐变" + +#: ../../po/../src/verbs.cpp:1913 +#, fuzzy +msgid "In_vert Selection" +msgstr "选择" + +#: ../../po/../src/verbs.cpp:1914 +msgid "Invert selection (unselect what is selected and select everything else)" +msgstr "" + +#: ../../po/../src/verbs.cpp:1915 +msgid "Invert in All Layers" +msgstr "" + +#: ../../po/../src/verbs.cpp:1916 +msgid "Invert selection in all visible and unlocked layers" +msgstr "" + +#: ../../po/../src/verbs.cpp:1917 +#, fuzzy +msgid "D_eselect" +msgstr "选择" + +#: ../../po/../src/verbs.cpp:1918 +#, fuzzy +msgid "Deselect any selected objects or nodes" +msgstr "删除选定节点" + +#. Selection +#: ../../po/../src/verbs.cpp:1921 +#, fuzzy +msgid "Raise to _Top" +msgstr "将选中内容提升到顶层" + +#: ../../po/../src/verbs.cpp:1922 +#, fuzzy +msgid "Raise selection to top" +msgstr "将选中内容提升到顶层" + +#: ../../po/../src/verbs.cpp:1923 +#, fuzzy +msgid "Lower to _Bottom" +msgstr "将选中内容降低到底层" + +#: ../../po/../src/verbs.cpp:1924 +#, fuzzy +msgid "Lower selection to bottom" +msgstr "将选中内容降低到底层" + +#: ../../po/../src/verbs.cpp:1925 +#, fuzzy +msgid "_Raise" +msgstr "提升" + +#: ../../po/../src/verbs.cpp:1926 +#, fuzzy +msgid "Raise selection one step" +msgstr "将选中内容提升一个图层" + +#: ../../po/../src/verbs.cpp:1927 +#, fuzzy +msgid "_Lower" +msgstr "降低" + +#: ../../po/../src/verbs.cpp:1928 +#, fuzzy +msgid "Lower selection one step" +msgstr "将选中内容降低一个图层" + +#: ../../po/../src/verbs.cpp:1929 +msgid "_Group" +msgstr "编组(_G)" + +#: ../../po/../src/verbs.cpp:1930 +msgid "Group selected objects" +msgstr "编组选中对象" + +#: ../../po/../src/verbs.cpp:1932 +#, fuzzy +msgid "Ungroup selected groups" +msgstr "分解选中对象构成的组" + +#: ../../po/../src/verbs.cpp:1934 +#, fuzzy +msgid "_Put on Path" +msgstr "将选定对象转换为曲线" + +#: ../../po/../src/verbs.cpp:1935 +#, fuzzy +msgid "Put text on path" +msgstr "将选定对象转换为曲线" + +#: ../../po/../src/verbs.cpp:1936 +#, fuzzy +msgid "_Remove from Path" +msgstr "删除变换" + +#: ../../po/../src/verbs.cpp:1937 +#, fuzzy +msgid "Remove text from path" +msgstr "将选定对象转换为曲线" + +#: ../../po/../src/verbs.cpp:1938 +msgid "Remove Manual _Kerns" +msgstr "" + +#. TRANSLATORS: "glyph": An image used in the visual representation of characters; +#. roughly speaking, how a character looks. A font is a set of glyphs. +#: ../../po/../src/verbs.cpp:1941 +#, fuzzy +msgid "Remove all manual kerns and glyph rotations from a text object" +msgstr "删除变换" + +#: ../../po/../src/verbs.cpp:1943 +#, fuzzy +msgid "_Union" +msgstr "无" + +#: ../../po/../src/verbs.cpp:1944 +#, fuzzy +msgid "Union of selected objects" +msgstr "分解选中对象构成的组" + +#: ../../po/../src/verbs.cpp:1945 +#, fuzzy +msgid "_Intersection" +msgstr "交互(_I)" + +#: ../../po/../src/verbs.cpp:1946 +#, fuzzy +msgid "Intersection of selected objects" +msgstr "删除选定节点" + +#: ../../po/../src/verbs.cpp:1947 +#, fuzzy +msgid "_Difference" +msgstr "度" + +#: ../../po/../src/verbs.cpp:1948 +#, fuzzy +msgid "Difference of selected objects (bottom minus top)" +msgstr "删除选定节点" + +#: ../../po/../src/verbs.cpp:1949 +#, fuzzy +msgid "E_xclusion" +msgstr "扩充:" + +#: ../../po/../src/verbs.cpp:1950 +#, fuzzy +msgid "Exclusive OR of selected objects" +msgstr "编辑选中对象的布局" + +#: ../../po/../src/verbs.cpp:1951 +#, fuzzy +msgid "Di_vision" +msgstr "尺寸" + +#: ../../po/../src/verbs.cpp:1952 +msgid "Cut the bottom object into pieces" +msgstr "" + +#. TRANSLATORS: "to cut a path" is not the same as "to break a path apart" - see the +#. Advanced tutorial for more info +#: ../../po/../src/verbs.cpp:1955 +#, fuzzy +msgid "Cut _Path" +msgstr "组合选定路径" + +#: ../../po/../src/verbs.cpp:1956 +msgid "Cut the bottom object's stroke into pieces, removing fill" +msgstr "" + +#. TRANSLATORS: "outset": expand a shape by offsetting the object's path, +#. i.e. by displacing it perpendicular to the path in each point. +#. See also the Advanced Tutorial for explanation. +#: ../../po/../src/verbs.cpp:1960 +#, fuzzy +msgid "Outs_et" +msgstr "组合选定路径" + +#: ../../po/../src/verbs.cpp:1961 +#, fuzzy +msgid "Outset selected paths" +msgstr "组合选定路径" + +#: ../../po/../src/verbs.cpp:1963 +#, fuzzy +msgid "O_utset Path by 1 px" +msgstr "组合选定路径" + +#: ../../po/../src/verbs.cpp:1964 +#, fuzzy +msgid "Outset selected paths by 1 px" +msgstr "组合选定路径" + +#: ../../po/../src/verbs.cpp:1966 +#, fuzzy +msgid "O_utset Path by 10 px" +msgstr "组合选定路径" + +#: ../../po/../src/verbs.cpp:1967 +#, fuzzy +msgid "Outset selected paths by 10 px" +msgstr "组合选定路径" + +#. TRANSLATORS: "inset": contract a shape by offsetting the object's path, +#. i.e. by displacing it perpendicular to the path in each point. +#. See also the Advanced Tutorial for explanation. +#: ../../po/../src/verbs.cpp:1971 +msgid "I_nset" +msgstr "" + +#: ../../po/../src/verbs.cpp:1972 +#, fuzzy +msgid "Inset selected paths" +msgstr "组合选定路径" + +#: ../../po/../src/verbs.cpp:1974 +#, fuzzy +msgid "I_nset Path by 1 px" +msgstr "组合选定路径" + +#: ../../po/../src/verbs.cpp:1975 +#, fuzzy +msgid "Inset selected paths by 1 px" +msgstr "组合选定路径" + +#: ../../po/../src/verbs.cpp:1977 +#, fuzzy +msgid "I_nset Path by 10 px" +msgstr "组合选定路径" + +#: ../../po/../src/verbs.cpp:1978 +#, fuzzy +msgid "Inset selected paths by 10 px" +msgstr "组合选定路径" + +#: ../../po/../src/verbs.cpp:1980 +#, fuzzy +msgid "D_ynamic Offset" +msgstr "动态填充" + +#: ../../po/../src/verbs.cpp:1980 +msgid "Create a dynamic offset object" +msgstr "" + +#: ../../po/../src/verbs.cpp:1982 +msgid "_Linked Offset" +msgstr "" + +#: ../../po/../src/verbs.cpp:1983 +msgid "Create a dynamic offset object linked to the original path" +msgstr "" + +#: ../../po/../src/verbs.cpp:1985 +#, fuzzy +msgid "_Stroke to Path" +msgstr "勾描宽度" + +#: ../../po/../src/verbs.cpp:1986 +#, fuzzy +msgid "Convert selected strokes to paths" +msgstr "将选定对象转换为曲线" + +#: ../../po/../src/verbs.cpp:1987 +#, fuzzy +msgid "Si_mplify" +msgstr "组合选定路径" + +#: ../../po/../src/verbs.cpp:1988 +#, fuzzy +msgid "Simplify selected paths by removing extra nodes" +msgstr "组合选定路径" + +#: ../../po/../src/verbs.cpp:1989 +#, fuzzy +msgid "_Reverse" +msgstr "文件" + +#: ../../po/../src/verbs.cpp:1990 +#, fuzzy +msgid "Reverses the direction of selected paths; useful for flipping markers" +msgstr "删除选定节点" + +#. TRANSLATORS: "to trace" means "to convert a bitmap to vector graphics" (to vectorize) +#: ../../po/../src/verbs.cpp:1992 +#, fuzzy +msgid "_Trace Bitmap" +msgstr "不完整的位图" + +#: ../../po/../src/verbs.cpp:1993 +#, fuzzy +msgid "Convert bitmap object to paths" +msgstr "将选定对象转换为曲线" + +#: ../../po/../src/verbs.cpp:1994 +#, fuzzy +msgid "_Make a Bitmap Copy" +msgstr "不完整的位图" + +#: ../../po/../src/verbs.cpp:1995 +msgid "Export selection to a bitmap and insert it into document" +msgstr "" + +#: ../../po/../src/verbs.cpp:1996 +msgid "_Combine" +msgstr "组合(_C)" + +#: ../../po/../src/verbs.cpp:1997 +msgid "Combine several paths into one" +msgstr "" + +#. TRANSLATORS: "to cut a path" is not the same as "to break a path apart" - see the +#. Advanced tutorial for more info +#: ../../po/../src/verbs.cpp:2000 +#, fuzzy +msgid "Break _Apart" +msgstr "拆分(_B)" + +#: ../../po/../src/verbs.cpp:2001 +#, fuzzy +msgid "Break selected paths into subpaths" +msgstr "拆分选定路径" + +#: ../../po/../src/verbs.cpp:2002 +msgid "Gri_d Arrange..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2003 +msgid "Arrange selection in grid pattern" +msgstr "" + +#. Layer +#: ../../po/../src/verbs.cpp:2005 +#, fuzzy +msgid "_Add Layer..." +msgstr "降低" + +#: ../../po/../src/verbs.cpp:2006 +#, fuzzy +msgid "Create a new layer" +msgstr "内存文档 %d" + +#: ../../po/../src/verbs.cpp:2007 +#, fuzzy +msgid "Re_name Layer..." +msgstr "提升" + +#: ../../po/../src/verbs.cpp:2008 +#, fuzzy +msgid "Rename the current layer" +msgstr "选择" + +#: ../../po/../src/verbs.cpp:2009 +#, fuzzy +msgid "Switch to Layer Abov_e" +msgstr "将选中内容降低到底层" + +#: ../../po/../src/verbs.cpp:2010 +msgid "Switch to the layer above the current" +msgstr "" + +#: ../../po/../src/verbs.cpp:2011 +#, fuzzy +msgid "Switch to Layer Belo_w" +msgstr "将选中内容降低一个图层" + +#: ../../po/../src/verbs.cpp:2012 +msgid "Switch to the layer below the current" +msgstr "" + +#: ../../po/../src/verbs.cpp:2013 +#, fuzzy +msgid "Move Selection to Layer Abo_ve" +msgstr "将选中内容降低到底层" + +#: ../../po/../src/verbs.cpp:2014 +msgid "Move selection to the layer above the current" +msgstr "" + +#: ../../po/../src/verbs.cpp:2015 +#, fuzzy +msgid "Move Selection to Layer Bel_ow" +msgstr "将选中内容降低一个图层" + +#: ../../po/../src/verbs.cpp:2016 +msgid "Move selection to the layer below the current" +msgstr "" + +#: ../../po/../src/verbs.cpp:2017 +#, fuzzy +msgid "Layer to _Top" +msgstr "将选中内容提升到顶层" + +#: ../../po/../src/verbs.cpp:2018 +#, fuzzy +msgid "Raise the current layer to the top" +msgstr "将选中内容提升到顶层" + +#: ../../po/../src/verbs.cpp:2019 +#, fuzzy +msgid "Layer to _Bottom" +msgstr "将选中内容降低到底层" + +#: ../../po/../src/verbs.cpp:2020 +#, fuzzy +msgid "Lower the current layer to the bottom" +msgstr "将选中内容降低到底层" + +#: ../../po/../src/verbs.cpp:2021 +#, fuzzy +msgid "_Raise Layer" +msgstr "提升" + +#: ../../po/../src/verbs.cpp:2022 +msgid "Raise the current layer" +msgstr "" + +#: ../../po/../src/verbs.cpp:2023 +#, fuzzy +msgid "_Lower Layer" +msgstr "降低" + +#: ../../po/../src/verbs.cpp:2024 +msgid "Lower the current layer" +msgstr "" + +#: ../../po/../src/verbs.cpp:2025 +#, fuzzy +msgid "_Delete Current Layer" +msgstr "选择" + +#: ../../po/../src/verbs.cpp:2026 +#, fuzzy +msgid "Delete the current layer" +msgstr "选择" + +#. Object +#: ../../po/../src/verbs.cpp:2029 +#, fuzzy +msgid "Rotate _90° CW" +msgstr "将角度设置为 90 度" + +#: ../../po/../src/verbs.cpp:2030 +#, fuzzy +msgid "Rotate selection 90° clockwise" +msgstr "将选定对象顺时针旋转 90 度" + +#: ../../po/../src/verbs.cpp:2031 +#, fuzzy +msgid "Rotate 9_0° CCW" +msgstr "将角度设置为 90 度" + +#: ../../po/../src/verbs.cpp:2032 +#, fuzzy +msgid "Rotate selection 90° counter-clockwise" +msgstr "将选定对象顺时针旋转 90 度" + +#: ../../po/../src/verbs.cpp:2033 +#, fuzzy +msgid "Remove _Transformations" +msgstr "删除变换" + +#: ../../po/../src/verbs.cpp:2034 +#, fuzzy +msgid "Remove transformations from object" +msgstr "删除变换" + +#: ../../po/../src/verbs.cpp:2035 +#, fuzzy +msgid "_Object to Path" +msgstr "重置变换" + +#: ../../po/../src/verbs.cpp:2036 +#, fuzzy +msgid "Convert selected objects to paths" +msgstr "将选定对象转换为曲线" + +#: ../../po/../src/verbs.cpp:2037 +msgid "_Flow into Frame" +msgstr "" + +#: ../../po/../src/verbs.cpp:2038 +#, fuzzy +msgid "Put text into frames" +msgstr "将选定对象转换为曲线" + +#: ../../po/../src/verbs.cpp:2039 +#, fuzzy +msgid "_Unflow" +msgstr "撤消" + +#: ../../po/../src/verbs.cpp:2040 +msgid "Remove text from frame (creates a single-line text object)" +msgstr "" + +#: ../../po/../src/verbs.cpp:2041 +#, fuzzy +msgid "_Convert to Text" +msgstr "将选定对象转换为曲线" + +#: ../../po/../src/verbs.cpp:2042 +#, fuzzy +msgid "Convert flowed text to regular text objects (preserves appearance)" +msgstr "将选定段转换为连线" + +#: ../../po/../src/verbs.cpp:2044 +#, fuzzy +msgid "Flip _Horizontal" +msgstr "水平翻转" + +#: ../../po/../src/verbs.cpp:2044 +#, fuzzy +msgid "Flips selected objects horizontally" +msgstr "翻转选中对象" + +#: ../../po/../src/verbs.cpp:2047 +#, fuzzy +msgid "Flip _Vertical" +msgstr "垂直翻转" + +#: ../../po/../src/verbs.cpp:2047 +#, fuzzy +msgid "Flips selected objects vertically" +msgstr "翻转选中对象" + +#. Tools +#: ../../po/../src/verbs.cpp:2051 +msgid "Select" +msgstr "选择" + +#: ../../po/../src/verbs.cpp:2052 +#, fuzzy +msgid "Select and transform objects" +msgstr "选择并变换" + +#: ../../po/../src/verbs.cpp:2053 +#, fuzzy +msgid "Node Edit" +msgstr "节点编辑" + +#: ../../po/../src/verbs.cpp:2054 +#, fuzzy +msgid "Edit path nodes or control handles" +msgstr "编辑选中对象的布局" + +#: ../../po/../src/verbs.cpp:2056 +#, fuzzy +msgid "Create rectangles and squares" +msgstr "绘制长方形" + +#: ../../po/../src/verbs.cpp:2058 +msgid "Create circles, ellipses, and arcs" +msgstr "" + +#: ../../po/../src/verbs.cpp:2060 +msgid "Create stars and polygons" +msgstr "" + +#: ../../po/../src/verbs.cpp:2062 +#, fuzzy +msgid "Create spirals" +msgstr "绘制螺旋" + +#: ../../po/../src/verbs.cpp:2064 +#, fuzzy +msgid "Draw freehand lines" +msgstr "绘制弹力手绘线" + +#: ../../po/../src/verbs.cpp:2066 +#, fuzzy +msgid "Draw Bezier curves and straight lines" +msgstr "绘制手绘线" + +#: ../../po/../src/verbs.cpp:2068 +msgid "Draw calligraphic lines" +msgstr "" + +#: ../../po/../src/verbs.cpp:2070 +#, fuzzy +msgid "Create and edit text objects" +msgstr "添加属性" + +#: ../../po/../src/verbs.cpp:2072 +#, fuzzy +msgid "Create and edit gradients" +msgstr "添加属性" + +#: ../../po/../src/verbs.cpp:2074 +#, fuzzy +msgid "Zoom in or out" +msgstr "缩小" + +#: ../../po/../src/verbs.cpp:2076 +msgid "Pick averaged colors from image" +msgstr "" + +#: ../../po/../src/verbs.cpp:2078 +#, fuzzy +msgid "Create connectors" +msgstr "内存文档 %d" + +#. Tool prefs +#: ../../po/../src/verbs.cpp:2081 +msgid "Selector Preferences" +msgstr "" + +#: ../../po/../src/verbs.cpp:2082 +#, fuzzy +msgid "Open Preferences for the Selector tool" +msgstr "Sodipodi:%s:%s:%d" + +#: ../../po/../src/verbs.cpp:2083 +#, fuzzy +msgid "Node Tool Preferences" +msgstr "项目是引用" + +#: ../../po/../src/verbs.cpp:2084 +#, fuzzy +msgid "Open Preferences for the Node tool" +msgstr "Sodipodi:%s:%s:%d" + +#: ../../po/../src/verbs.cpp:2085 +#, fuzzy +msgid "Rectangle Preferences" +msgstr "长方形属性" + +#: ../../po/../src/verbs.cpp:2086 +#, fuzzy +msgid "Open Preferences for the Rectangle tool" +msgstr "Sodipodi:%s:%s:%d" + +#: ../../po/../src/verbs.cpp:2087 +#, fuzzy +msgid "Ellipse Preferences" +msgstr "项目是引用" + +#: ../../po/../src/verbs.cpp:2088 +#, fuzzy +msgid "Open Preferences for the Ellipse tool" +msgstr "Sodipodi:%s:%s:%d" + +#: ../../po/../src/verbs.cpp:2089 +#, fuzzy +msgid "Star Preferences" +msgstr "星形属性" + +#: ../../po/../src/verbs.cpp:2090 +#, fuzzy +msgid "Open Preferences for the Star tool" +msgstr "Sodipodi:%s:%s:%d" + +#: ../../po/../src/verbs.cpp:2091 +#, fuzzy +msgid "Spiral Preferences" +msgstr "螺旋属性" + +#: ../../po/../src/verbs.cpp:2092 +#, fuzzy +msgid "Open Preferences for the Spiral tool" +msgstr "Sodipodi:%s:%s:%d" + +#: ../../po/../src/verbs.cpp:2093 +#, fuzzy +msgid "Pencil Preferences" +msgstr "项目是引用" + +#: ../../po/../src/verbs.cpp:2094 +#, fuzzy +msgid "Open Preferences for the Pencil tool" +msgstr "Sodipodi:%s:%s:%d" + +#: ../../po/../src/verbs.cpp:2095 +#, fuzzy +msgid "Pen Preferences" +msgstr "项目是引用" + +#: ../../po/../src/verbs.cpp:2096 +#, fuzzy +msgid "Open Preferences for the Pen tool" +msgstr "Sodipodi:%s:%s:%d" + +#: ../../po/../src/verbs.cpp:2097 +msgid "Calligraphic Preferences" +msgstr "" + +#: ../../po/../src/verbs.cpp:2098 +#, fuzzy +msgid "Open Preferences for the Calligraphy tool" +msgstr "Sodipodi:%s:%s:%d" + +#: ../../po/../src/verbs.cpp:2099 +#, fuzzy +msgid "Text Preferences" +msgstr "项目是引用" + +#: ../../po/../src/verbs.cpp:2100 +#, fuzzy +msgid "Open Preferences for the Text tool" +msgstr "Sodipodi:%s:%s:%d" + +#: ../../po/../src/verbs.cpp:2101 +#, fuzzy +msgid "Gradient Preferences" +msgstr "项目是引用" + +#: ../../po/../src/verbs.cpp:2102 +#, fuzzy +msgid "Open Preferences for the Gradient tool" +msgstr "Sodipodi:%s:%s:%d" + +#: ../../po/../src/verbs.cpp:2103 +#, fuzzy +msgid "Zoom Preferences" +msgstr "项目是引用" + +#: ../../po/../src/verbs.cpp:2104 +#, fuzzy +msgid "Open Preferences for the Zoom tool" +msgstr "Sodipodi:%s:%s:%d" + +#: ../../po/../src/verbs.cpp:2105 +#, fuzzy +msgid "Dropper Preferences" +msgstr "Sodipodi:%s:%s:%d" + +#: ../../po/../src/verbs.cpp:2106 +#, fuzzy +msgid "Open Preferences for the Dropper tool" +msgstr "Sodipodi:%s:%s:%d" + +#: ../../po/../src/verbs.cpp:2107 +#, fuzzy +msgid "Connector Preferences" +msgstr "星形属性" + +#: ../../po/../src/verbs.cpp:2108 +#, fuzzy +msgid "Open Preferences for the Connector tool" +msgstr "Sodipodi:%s:%s:%d" + +#. Zoom/View +#: ../../po/../src/verbs.cpp:2111 +#, fuzzy +msgid "Zoom In" +msgstr "放大" + +#: ../../po/../src/verbs.cpp:2111 +msgid "Zoom in" +msgstr "放大" + +#: ../../po/../src/verbs.cpp:2112 +#, fuzzy +msgid "Zoom Out" +msgstr "缩小" + +#: ../../po/../src/verbs.cpp:2112 +msgid "Zoom out" +msgstr "缩小" + +#: ../../po/../src/verbs.cpp:2113 +#, fuzzy +msgid "_Rulers" +msgstr "文件" + +#: ../../po/../src/verbs.cpp:2113 +#, fuzzy +msgid "Show or hide the canvas rulers" +msgstr "显示指示线" + +#: ../../po/../src/verbs.cpp:2114 +msgid "Scroll_bars" +msgstr "" + +#: ../../po/../src/verbs.cpp:2114 +#, fuzzy +msgid "Show or hide the canvas scrollbars" +msgstr "显示指示线" + +#: ../../po/../src/verbs.cpp:2115 +#, fuzzy +msgid "_Grid" +msgstr "栅格" + +#: ../../po/../src/verbs.cpp:2116 +#, fuzzy +msgid "G_uides" +msgstr "指示" + +#: ../../po/../src/verbs.cpp:2117 +msgid "Nex_t Zoom" +msgstr "" + +#: ../../po/../src/verbs.cpp:2117 +msgid "Next zoom (from the history of zooms)" +msgstr "" + +#: ../../po/../src/verbs.cpp:2119 +msgid "Pre_vious Zoom" +msgstr "" + +#: ../../po/../src/verbs.cpp:2119 +msgid "Previous zoom (from the history of zooms)" +msgstr "" + +#: ../../po/../src/verbs.cpp:2121 +#, fuzzy +msgid "Zoom 1:_1" +msgstr "缩放到 1:1" + +#: ../../po/../src/verbs.cpp:2121 +msgid "Zoom to 1:1" +msgstr "缩放到 1:1" + +#: ../../po/../src/verbs.cpp:2123 +#, fuzzy +msgid "Zoom 1:_2" +msgstr "缩放到 1:2" + +#: ../../po/../src/verbs.cpp:2123 +msgid "Zoom to 1:2" +msgstr "缩放到 1:2" + +#: ../../po/../src/verbs.cpp:2125 +#, fuzzy +msgid "_Zoom 2:1" +msgstr "缩放到 2:1" + +#: ../../po/../src/verbs.cpp:2125 +msgid "Zoom to 2:1" +msgstr "缩放到 2:1" + +#: ../../po/../src/verbs.cpp:2128 +msgid "_Fullscreen" +msgstr "" + +#: ../../po/../src/verbs.cpp:2128 +msgid "Stretch this document window to full screen" +msgstr "" + +#: ../../po/../src/verbs.cpp:2131 +#, fuzzy +msgid "Duplic_ate Window" +msgstr "复制" + +#: ../../po/../src/verbs.cpp:2131 +#, fuzzy +msgid "Open a new window with the same document" +msgstr "未命名文档 %d" + +#: ../../po/../src/verbs.cpp:2133 +#, fuzzy +msgid "_New View Preview" +msgstr "新建预览" + +#: ../../po/../src/verbs.cpp:2134 +#, fuzzy +msgid "New View Preview" +msgstr "新建预览" + +#. "view_new_preview" +#: ../../po/../src/verbs.cpp:2136 +msgid "_Normal" +msgstr "" + +#: ../../po/../src/verbs.cpp:2137 +msgid "Switch to normal display mode" +msgstr "" + +#: ../../po/../src/verbs.cpp:2138 +#, fuzzy +msgid "_Outline" +msgstr "显示指示线" + +#: ../../po/../src/verbs.cpp:2139 +msgid "Switch to outline (wireframe) display mode" +msgstr "" + +#: ../../po/../src/verbs.cpp:2141 +#, fuzzy +msgid "Ico_n Preview" +msgstr "新建预览" + +#: ../../po/../src/verbs.cpp:2142 +msgid "Open a window to preview items at different icon resolutions" +msgstr "" + +#: ../../po/../src/verbs.cpp:2144 +#, fuzzy +msgid "Zoom to fit page in window" +msgstr "编辑窗口" + +#: ../../po/../src/verbs.cpp:2145 +#, fuzzy +msgid "Page _Width" +msgstr "设定页面宽度" + +#: ../../po/../src/verbs.cpp:2146 +#, fuzzy +msgid "Zoom to fit page width in window" +msgstr "设定页面宽度" + +#: ../../po/../src/verbs.cpp:2148 +#, fuzzy +msgid "Zoom to fit drawing in window" +msgstr "编辑窗口" + +#: ../../po/../src/verbs.cpp:2150 +#, fuzzy +msgid "Zoom to fit selection in window" +msgstr "将选中内容提升到顶层" + +#. Dialogs +#: ../../po/../src/verbs.cpp:2153 +#, fuzzy +msgid "In_kscape Preferences..." +msgstr "Sodipodi:%s:%s:%d" + +#: ../../po/../src/verbs.cpp:2154 +#, fuzzy +msgid "Global Inkscape preferences" +msgstr "显示设置" + +#: ../../po/../src/verbs.cpp:2155 +msgid "_Document Preferences..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2156 +#, fuzzy +msgid "Preferences saved with the document" +msgstr "未命名文档 %d" + +#: ../../po/../src/verbs.cpp:2157 +#, fuzzy +msgid "_Fill and Stroke..." +msgstr "填充并勾描" + +#: ../../po/../src/verbs.cpp:2158 +#, fuzzy +msgid "Fill and Stroke dialog" +msgstr "填充并勾描" + +#. TRANSLATORS: "Swatches" means: color samples +#: ../../po/../src/verbs.cpp:2160 +#, fuzzy +msgid "S_watches..." +msgstr "保存为" + +#: ../../po/../src/verbs.cpp:2161 +msgid "View color swatches" +msgstr "" + +#: ../../po/../src/verbs.cpp:2162 +#, fuzzy +msgid "Transfor_m..." +msgstr "转化" + +#: ../../po/../src/verbs.cpp:2163 +#, fuzzy +msgid "Transform dialog" +msgstr "变换对话框" + +#: ../../po/../src/verbs.cpp:2164 +#, fuzzy +msgid "_Align and Distribute..." +msgstr "属性" + +#: ../../po/../src/verbs.cpp:2165 +#, fuzzy +msgid "Align and Distribute dialog" +msgstr "属性" + +#: ../../po/../src/verbs.cpp:2166 +#, fuzzy +msgid "_Text and Font..." +msgstr "桌面设置" + +#: ../../po/../src/verbs.cpp:2167 +#, fuzzy +msgid "Text and Font dialog" +msgstr "桌面设置" + +#: ../../po/../src/verbs.cpp:2168 +#, fuzzy +msgid "_XML Editor..." +msgstr "XML 编辑器" + +#: ../../po/../src/verbs.cpp:2169 +msgid "XML Editor" +msgstr "XML 编辑器" + +#: ../../po/../src/verbs.cpp:2170 +#, fuzzy +msgid "_Find..." +msgstr "打印" + +#: ../../po/../src/verbs.cpp:2171 +#, fuzzy +msgid "Find objects in document" +msgstr "文档中无渐变" + +#: ../../po/../src/verbs.cpp:2172 +msgid "_Messages..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2173 +msgid "View debug messages" +msgstr "" + +#: ../../po/../src/verbs.cpp:2174 +#, fuzzy +msgid "S_cripts..." +msgstr "打印" + +#: ../../po/../src/verbs.cpp:2175 +#, fuzzy +msgid "Run scripts" +msgstr "圆形连接" + +#: ../../po/../src/verbs.cpp:2176 +#, fuzzy +msgid "Show/Hide D_ialogs" +msgstr "关闭对话框" + +#: ../../po/../src/verbs.cpp:2177 +msgid "Show or hide all active dialogs" +msgstr "" + +#. TRANSLATORS: "Tile clones" means: "Create tiled clones" +#: ../../po/../src/verbs.cpp:2179 +msgid "Tile clones..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2180 +msgid "Create and arrange multiple clones of selection" +msgstr "" + +#: ../../po/../src/verbs.cpp:2181 +#, fuzzy +msgid "_Object Properties..." +msgstr "对象属性" + +#: ../../po/../src/verbs.cpp:2182 +#, fuzzy +msgid "Object Properties dialog" +msgstr "对象属性" + +#: ../../po/../src/verbs.cpp:2185 +msgid "_Connect to Jabber server..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2185 +msgid "Connect to a Jabber server" +msgstr "" + +#: ../../po/../src/verbs.cpp:2187 +#, fuzzy +msgid "Share with _user..." +msgstr "保存为" + +#: ../../po/../src/verbs.cpp:2187 +msgid "Establish a whiteboard session with another Jabber user" +msgstr "" + +#: ../../po/../src/verbs.cpp:2189 +msgid "Share with _chatroom..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2189 +msgid "" +"Join a chatroom to start a new whiteboard session or join one in progress" +msgstr "" + +#: ../../po/../src/verbs.cpp:2191 +msgid "_Dump XML node tracker" +msgstr "" + +#: ../../po/../src/verbs.cpp:2191 +msgid "Dump the contents of the XML tracker to the console" +msgstr "" + +#: ../../po/../src/verbs.cpp:2193 +msgid "_Open session file..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2193 +msgid "Open and browse through records of past whiteboard sessions" +msgstr "" + +#: ../../po/../src/verbs.cpp:2195 +msgid "Session file playback" +msgstr "" + +#: ../../po/../src/verbs.cpp:2197 +msgid "_Disconnect from session" +msgstr "" + +#: ../../po/../src/verbs.cpp:2199 +msgid "Disconnect from _server" +msgstr "" + +#: ../../po/../src/verbs.cpp:2201 +msgid "_Input Devices..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2202 +msgid "Configure extended input devices" +msgstr "" + +#. Help +#: ../../po/../src/verbs.cpp:2205 +msgid "_Keys and Mouse" +msgstr "" + +#: ../../po/../src/verbs.cpp:2206 +msgid "Key and mouse shortcuts reference" +msgstr "" + +#: ../../po/../src/verbs.cpp:2207 +#, fuzzy +msgid "About E_xtensions" +msgstr "扩充:" + +#: ../../po/../src/verbs.cpp:2208 +#, fuzzy +msgid "About Extensions..." +msgstr "扩充:" + +#: ../../po/../src/verbs.cpp:2209 +#, fuzzy +msgid "About _Memory" +msgstr "扩充:" + +#: ../../po/../src/verbs.cpp:2210 +#, fuzzy +msgid "About Memory..." +msgstr "关于(_A)..." + +#: ../../po/../src/verbs.cpp:2211 +msgid "_About Inkscape" +msgstr "" + +#. "help_about" +#. new HelpVerb(SP_VERB_SHOW_LICENSE, "ShowLicense", N_("Modifying or Redistributing Inkscape"), +#. N_("Show license to modify and/or redistribute Inkscape: GNU GPL"), NULL), +#. Tutorials +#: ../../po/../src/verbs.cpp:2217 +#, fuzzy +msgid "Inkscape: _Basic" +msgstr "Sodipodi:%s:%s:%d" + +#: ../../po/../src/verbs.cpp:2218 +msgid "Getting started with Inkscape" +msgstr "" + +#. "tutorial_basic" +#: ../../po/../src/verbs.cpp:2219 +#, fuzzy +msgid "Inkscape: _Shapes" +msgstr "Sodipodi:%s:%s:%d" + +#: ../../po/../src/verbs.cpp:2220 +msgid "Using shape tools to create and edit shapes" +msgstr "" + +#: ../../po/../src/verbs.cpp:2221 +#, fuzzy +msgid "Inkscape: _Advanced" +msgstr "Sodipodi:%s:%s:%d" + +#: ../../po/../src/verbs.cpp:2222 +#, fuzzy +msgid "Advanced Inkscape topics" +msgstr "Sodipodi:%s:%s:%d" + +#. "tutorial_advanced" +#. TRANSLATORS: "to trace" means "to convert a bitmap to vector graphics" (to vectorize) +#: ../../po/../src/verbs.cpp:2224 +#, fuzzy +msgid "Inkscape: T_racing" +msgstr "Sodipodi:%s:%s:%d" + +#: ../../po/../src/verbs.cpp:2225 +#, fuzzy +msgid "Using bitmap tracing" +msgstr "图像大小" + +#. "tutorial_tracing" +#: ../../po/../src/verbs.cpp:2226 +#, fuzzy +msgid "Inkscape: _Calligraphy" +msgstr "Sodipodi:%s:%s:%d" + +#: ../../po/../src/verbs.cpp:2227 +msgid "Using the Calligraphy pen tool" +msgstr "" + +#: ../../po/../src/verbs.cpp:2228 +msgid "_Elements of Design" +msgstr "" + +#: ../../po/../src/verbs.cpp:2229 +msgid "Principles of design in the tutorial form" +msgstr "" + +#. "tutorial_design" +#: ../../po/../src/verbs.cpp:2230 +msgid "_Tips and Tricks" +msgstr "" + +#: ../../po/../src/verbs.cpp:2231 +msgid "Miscellaneous tips and tricks" +msgstr "" + +#. "tutorial_tips" +#. Effect +#: ../../po/../src/verbs.cpp:2234 +msgid "Previous Effect" +msgstr "" + +#: ../../po/../src/verbs.cpp:2235 +msgid "Repeat the last effect with the same settings" +msgstr "" + +#. "tutorial_tips" +#: ../../po/../src/verbs.cpp:2236 +msgid "Previous Effect Settings..." +msgstr "" + +#: ../../po/../src/verbs.cpp:2237 +msgid "Repeat the last effect with new settings" +msgstr "" + +#: ../../po/../src/widgets/dash-selector.cpp:106 +#, fuzzy +msgid "Dash pattern" +msgstr "勾描宽度" + +#: ../../po/../src/widgets/dash-selector.cpp:121 +#, fuzzy +msgid "Pattern offset" +msgstr "模式填充" + +#: ../../po/../src/widgets/desktop-widget.cpp:240 +#, fuzzy +msgid "Zoom drawing if window size changes" +msgstr "编辑窗口" + +#: ../../po/../src/widgets/desktop-widget.cpp:298 +msgid "Cursor coordinates" +msgstr "" + +#. display the initial welcome message in the statusbar +#: ../../po/../src/widgets/desktop-widget.cpp:324 +msgid "" +"Welcome to Inkscape! Use shape or freehand tools to create objects; " +"use selector (arrow) to move or transform them." +msgstr "" + +#: ../../po/../src/widgets/desktop-widget.cpp:372 +#, c-format +msgid "%s: %d - Inkscape" +msgstr "" + +#: ../../po/../src/widgets/desktop-widget.cpp:374 +#, c-format +msgid "%s - Inkscape" +msgstr "" + +#: ../../po/../src/widgets/desktop-widget.cpp:532 +#, c-format +msgid "" +"Save changes to document \"%s\" before " +"closing?\n" +"\n" +"If you close without saving, your changes will be discarded." +msgstr "" + +#: ../../po/../src/widgets/desktop-widget.cpp:548 +#: ../../po/../src/widgets/desktop-widget.cpp:612 +msgid "Close _without saving" +msgstr "" + +#: ../../po/../src/widgets/desktop-widget.cpp:595 +#, c-format +msgid "" +"The file \"%s\" was saved with a " +"format (%s) that may cause data loss!\n" +"\n" +"Do you want to save this file in another format?" +msgstr "" + +#. Family frame +#: ../../po/../src/widgets/font-selector.cpp:156 +msgid "Font family" +msgstr "" + +#. Style frame +#: ../../po/../src/widgets/font-selector.cpp:184 +#, fuzzy +msgid "Style" +msgstr " 风格 " + +#: ../../po/../src/widgets/font-selector.cpp:219 +#, fuzzy +msgid "Font size:" +msgstr "不保存" + +#. TRANSLATORS: Test string used in text and font dialog (when no +#. * text has been entered) to get a preview of the font. Choose +#. * some representative characters that users of your locale will be +#. * interested in. +#: ../../po/../src/widgets/font-selector.cpp:554 +msgid "AaBbCcIiPpQq12368.;/()" +msgstr "" + +#: ../../po/../src/widgets/gradient-selector.cpp:137 +#: ../../po/../src/widgets/gradient-toolbar.cpp:524 +#, fuzzy +msgid "Duplicate" +msgstr "复制" + +#: ../../po/../src/widgets/gradient-selector.cpp:142 +#: ../../po/../src/widgets/gradient-toolbar.cpp:535 +msgid "Edit..." +msgstr "编辑..." + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/pservers.html#LinearGradientSpreadMethodAttribute +#: ../../po/../src/widgets/gradient-selector.cpp:159 +msgid "" +"Whether to fill with flat color beyond the ends of the gradient vector " +"(spreadMethod=\"pad\"), or repeat the gradient in the same direction " +"(spreadMethod=\"repeat\"), or repeat the gradient in alternating opposite " +"directions (spreadMethod=\"reflect\")" +msgstr "" + +#: ../../po/../src/widgets/gradient-selector.cpp:165 +#, fuzzy +msgid "none" +msgstr "无" + +#: ../../po/../src/widgets/gradient-selector.cpp:169 +#, fuzzy +msgid "reflected" +msgstr "第一个选择" + +#: ../../po/../src/widgets/gradient-selector.cpp:173 +#, fuzzy +msgid "direct" +msgstr "长方形" + +#: ../../po/../src/widgets/gradient-selector.cpp:181 +#, fuzzy +msgid "Repeat:" +msgstr "重置" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:217 +msgid "No gradients" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:226 +#, fuzzy +msgid "Nothing selected" +msgstr "最后的选择" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:237 +#, fuzzy +msgid "No gradients in selection" +msgstr "未选择渐变" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:247 +msgid "Multiple gradients" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:525 +msgid "" +"If the gradient is used by more than one object, create a copy of it for the " +"selected object(s)" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:536 +#, fuzzy +msgid "Edit the stops of the gradient" +msgstr "添加新渐变" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:593 +#: ../../po/../src/widgets/toolbox.cpp:1103 +#: ../../po/../src/widgets/toolbox.cpp:1192 +#: ../../po/../src/widgets/toolbox.cpp:1485 +#: ../../po/../src/widgets/toolbox.cpp:1534 +#: ../../po/../src/widgets/toolbox.cpp:1766 +#: ../../po/../src/widgets/toolbox.cpp:1801 +#: ../../po/../src/widgets/toolbox.cpp:2331 +#: ../../po/../src/widgets/toolbox.cpp:2370 +msgid "New:" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:606 +#, fuzzy +msgid "Create linear gradient" +msgstr "添加新渐变" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:620 +msgid "Create radial (elliptic or circular) gradient" +msgstr "" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:635 +#, fuzzy +msgid "on" +msgstr "无" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:648 +#, fuzzy +msgid "Create gradient in the fill" +msgstr "渐变向量" + +#: ../../po/../src/widgets/gradient-toolbar.cpp:662 +msgid "Create gradient in the stroke" +msgstr "" + +#. FIXME: implement averaging of all parameters for multiple selected stars +#. gtk_label_set_markup(GTK_LABEL(l), _("Average:")); +#. FIXME: implement averaging of all parameters for multiple selected +#. gtk_label_set_markup(GTK_LABEL(l), _("Average:")); +#: ../../po/../src/widgets/gradient-toolbar.cpp:676 +#: ../../po/../src/widgets/toolbox.cpp:1105 +#: ../../po/../src/widgets/toolbox.cpp:1124 +#: ../../po/../src/widgets/toolbox.cpp:1493 +#: ../../po/../src/widgets/toolbox.cpp:1518 +#: ../../po/../src/widgets/toolbox.cpp:1768 +#: ../../po/../src/widgets/toolbox.cpp:1787 +#: ../../po/../src/widgets/toolbox.cpp:2334 +#: ../../po/../src/widgets/toolbox.cpp:2354 +#, fuzzy +msgid "Change:" +msgstr "改变" + +#: ../../po/../src/widgets/gradient-vector.cpp:269 +msgid "No gradients in document" +msgstr "文档中无渐变" + +#: ../../po/../src/widgets/gradient-vector.cpp:275 +msgid "No gradient selected" +msgstr "未选择渐变" + +#: ../../po/../src/widgets/gradient-vector.cpp:532 +#, fuzzy +msgid "No stops in gradient" +msgstr "添加新渐变" + +#. TRANSLATORS: "Stop" means: a "phase" of a gradient +#: ../../po/../src/widgets/gradient-vector.cpp:794 +#, fuzzy +msgid "Add stop" +msgstr "桌面" + +#: ../../po/../src/widgets/gradient-vector.cpp:797 +msgid "Add another control stop to gradient" +msgstr "" + +#: ../../po/../src/widgets/gradient-vector.cpp:799 +#, fuzzy +msgid "Delete stop" +msgstr "删除选中内容" + +#: ../../po/../src/widgets/gradient-vector.cpp:802 +msgid "Delete current control stop from gradient" +msgstr "" + +#. Label +#: ../../po/../src/widgets/gradient-vector.cpp:813 +msgid "Offset:" +msgstr "" + +#. TRANSLATORS: "Stop" means: a "phase" of a gradient +#: ../../po/../src/widgets/gradient-vector.cpp:858 +#, fuzzy +msgid "Stop Color" +msgstr "起点颜色" + +#: ../../po/../src/widgets/gradient-vector.cpp:887 +#, fuzzy +msgid "Gradient editor" +msgstr "渐变向量" + +#: ../../po/../src/widgets/layer-selector.cpp:119 +#, fuzzy +msgid "Toggle current layer visibility" +msgstr "文档" + +#: ../../po/../src/widgets/layer-selector.cpp:139 +#, fuzzy +msgid "Lock or unlock current layer" +msgstr "文档" + +#: ../../po/../src/widgets/layer-selector.cpp:142 +#, fuzzy +msgid "Current layer" +msgstr "文档" + +#: ../../po/../src/widgets/layer-selector.cpp:553 +msgid "(root)" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:182 +#: ../../po/../src/widgets/paint-selector.cpp:561 +msgid "No paint" +msgstr "无颜料" + +#: ../../po/../src/widgets/paint-selector.cpp:184 +#: ../../po/../src/widgets/paint-selector.cpp:629 +#, fuzzy +msgid "Flat color" +msgstr "纯色" + +#: ../../po/../src/widgets/paint-selector.cpp:186 +#: ../../po/../src/widgets/paint-selector.cpp:696 +#, fuzzy +msgid "Linear gradient" +msgstr "添加新渐变" + +#: ../../po/../src/widgets/paint-selector.cpp:188 +#: ../../po/../src/widgets/paint-selector.cpp:699 +#, fuzzy +msgid "Radial gradient" +msgstr "添加新渐变" + +#: ../../po/../src/widgets/paint-selector.cpp:192 +msgid "Unset paint (make it undefined so it can be inherited)" +msgstr "" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/painting.html#FillRuleProperty +#: ../../po/../src/widgets/paint-selector.cpp:204 +msgid "" +"Any path self-intersections or subpaths create holes in the fill (fill-rule: " +"evenodd)" +msgstr "" + +#. TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/painting.html#FillRuleProperty +#: ../../po/../src/widgets/paint-selector.cpp:215 +msgid "" +"Fill is solid unless a subpath is counterdirectional (fill-rule: nonzero)" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:528 +msgid "No objects" +msgstr "无对象" + +#: ../../po/../src/widgets/paint-selector.cpp:539 +msgid "Multiple styles" +msgstr "多种风格" + +#: ../../po/../src/widgets/paint-selector.cpp:550 +msgid "Paint is undefined" +msgstr "" + +#: ../../po/../src/widgets/paint-selector.cpp:757 +#, fuzzy +msgid "No patterns in document" +msgstr "文档中无渐变" + +#: ../../po/../src/widgets/paint-selector.cpp:872 +msgid "" +"Use Edit > Object(s) to Pattern to create a new pattern from " +"selection." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:426 +msgid "Now stroke width is scaled when objects are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:428 +msgid "Now stroke width is not scaled when objects are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:436 +msgid "" +"Now rounded rectangle corners are scaled when rectangles are " +"scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:438 +msgid "" +"Now rounded rectangle corners are not scaled when rectangles " +"are scaled." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:446 +msgid "" +"Now gradients are transformed along with their objects when " +"those are transformed (moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:448 +msgid "" +"Now gradients remain fixed when objects are transformed " +"(moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:456 +msgid "" +"Now patterns are transformed along with their objects when " +"those are transformed (moved, scaled, rotated, or skewed)." +msgstr "" + +#: ../../po/../src/widgets/select-toolbar.cpp:458 +msgid "" +"Now patterns remain fixed when objects are transformed (moved, " +"scaled, rotated, or skewed)." +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:506 +#, fuzzy +msgid "select_toolbar|X" +msgstr "选择" + +#: ../../po/../src/widgets/select-toolbar.cpp:506 +#, fuzzy +msgid "Horizontal coordinate of selection" +msgstr "水平中心值" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:511 +#, fuzzy +msgid "select_toolbar|Y" +msgstr "选择" + +#: ../../po/../src/widgets/select-toolbar.cpp:511 +msgid "Vertical coordinate of selection" +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:517 +#, fuzzy +msgid "select_toolbar|W" +msgstr "选择" + +#: ../../po/../src/widgets/select-toolbar.cpp:517 +#, fuzzy +msgid "Width of selection" +msgstr "剪切选中内容" + +#: ../../po/../src/widgets/select-toolbar.cpp:525 +msgid "Change both width and height by the same proportion" +msgstr "" + +#. TRANSLATORS: only translate "string" in "context|string". +#. For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS +#: ../../po/../src/widgets/select-toolbar.cpp:534 +#, fuzzy +msgid "select_toolbar|H" +msgstr "选择" + +#: ../../po/../src/widgets/select-toolbar.cpp:534 +#, fuzzy +msgid "Height of selection" +msgstr "缩放到选中内容" + +#: ../../po/../src/widgets/sp-color-gtkselector.cpp:62 +msgid "System" +msgstr "" + +#: ../../po/../src/widgets/sp-color-notebook.cpp:322 +#, fuzzy +msgid "RGBA_:" +msgstr "RGB" + +#: ../../po/../src/widgets/sp-color-notebook.cpp:330 +msgid "Hexadecimal RGBA value of the color" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "RGB" +msgstr "RGB" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +#, fuzzy +msgid "HSL" +msgstr "HSV" + +#: ../../po/../src/widgets/sp-color-scales.cpp:80 +msgid "CMYK" +msgstr "CMYK" + +#: ../../po/../src/widgets/sp-color-scales.cpp:397 +msgid "_R" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:398 +#: ../../po/../src/widgets/sp-color-scales.cpp:399 +#, fuzzy +msgid "Red" +msgstr "红色:" + +#: ../../po/../src/widgets/sp-color-scales.cpp:400 +msgid "_G" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:401 +#: ../../po/../src/widgets/sp-color-scales.cpp:402 +#, fuzzy +msgid "Green" +msgstr "绿色:" + +#: ../../po/../src/widgets/sp-color-scales.cpp:403 +msgid "_B" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:404 +#: ../../po/../src/widgets/sp-color-scales.cpp:405 +#, fuzzy +msgid "Blue" +msgstr "蓝色:" + +#. Label +#: ../../po/../src/widgets/sp-color-scales.cpp:406 +#: ../../po/../src/widgets/sp-color-scales.cpp:432 +#: ../../po/../src/widgets/sp-color-scales.cpp:463 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:141 +msgid "_A" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:407 +#: ../../po/../src/widgets/sp-color-scales.cpp:408 +#: ../../po/../src/widgets/sp-color-scales.cpp:433 +#: ../../po/../src/widgets/sp-color-scales.cpp:434 +#: ../../po/../src/widgets/sp-color-scales.cpp:464 +#: ../../po/../src/widgets/sp-color-scales.cpp:465 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:151 +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:163 +msgid "Alpha (opacity)" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:423 +msgid "_H" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:424 +#: ../../po/../src/widgets/sp-color-scales.cpp:425 +#, fuzzy +msgid "Hue" +msgstr "色调:" + +#: ../../po/../src/widgets/sp-color-scales.cpp:426 +msgid "_S" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:427 +#: ../../po/../src/widgets/sp-color-scales.cpp:428 +#, fuzzy +msgid "Saturation" +msgstr "饱和度:" + +#: ../../po/../src/widgets/sp-color-scales.cpp:429 +msgid "_L" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:430 +#: ../../po/../src/widgets/sp-color-scales.cpp:431 +#, fuzzy +msgid "Lightness" +msgstr "高度" + +#: ../../po/../src/widgets/sp-color-scales.cpp:451 +msgid "_C" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:452 +#: ../../po/../src/widgets/sp-color-scales.cpp:453 +#, fuzzy +msgid "Cyan" +msgstr "青蓝:" + +#: ../../po/../src/widgets/sp-color-scales.cpp:454 +msgid "_M" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:455 +#: ../../po/../src/widgets/sp-color-scales.cpp:456 +#, fuzzy +msgid "Magenta" +msgstr "洋红:" + +#: ../../po/../src/widgets/sp-color-scales.cpp:457 +msgid "_Y" +msgstr "" + +#: ../../po/../src/widgets/sp-color-scales.cpp:458 +#: ../../po/../src/widgets/sp-color-scales.cpp:459 +#, fuzzy +msgid "Yellow" +msgstr "黄:" + +#: ../../po/../src/widgets/sp-color-scales.cpp:460 +msgid "_K" +msgstr "" + +#: ../../po/../src/widgets/sp-color-selector.cpp:71 +#, fuzzy +msgid "Unnamed" +msgstr "名称" + +#: ../../po/../src/widgets/sp-color-wheel-selector.cpp:68 +msgid "Wheel" +msgstr "" + +#: ../../po/../src/widgets/sp-xmlview-attr-list.cpp:53 +#, fuzzy +msgid "Attribute" +msgstr "属性" + +#: ../../po/../src/widgets/sp-xmlview-attr-list.cpp:54 +msgid "Value" +msgstr "值" + +#: ../../po/../src/widgets/toolbox.cpp:424 +#, fuzzy +msgid "Insert new nodes into selected segments" +msgstr "将一个节点包含到选定段中去" + +#: ../../po/../src/widgets/toolbox.cpp:426 +msgid "Delete selected nodes" +msgstr "删除选定节点" + +#: ../../po/../src/widgets/toolbox.cpp:431 +#, fuzzy +msgid "Join paths at selected nodes" +msgstr "使选定节点处成为光滑线段" + +#: ../../po/../src/widgets/toolbox.cpp:433 +#, fuzzy +msgid "Join paths at selected nodes with new segment" +msgstr "使选定节点处成为光滑线段" + +#: ../../po/../src/widgets/toolbox.cpp:436 +msgid "Split path between two non-endpoint nodes" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:439 +#, fuzzy +msgid "Break path at selected nodes" +msgstr "拆分选定的节点" + +#: ../../po/../src/widgets/toolbox.cpp:444 +#, fuzzy +msgid "Make selected nodes corner" +msgstr "删除选定节点" + +#: ../../po/../src/widgets/toolbox.cpp:447 +#, fuzzy +msgid "Make selected nodes smooth" +msgstr "删除选定节点" + +#: ../../po/../src/widgets/toolbox.cpp:450 +#, fuzzy +msgid "Make selected nodes symmetric" +msgstr "删除选定节点" + +#: ../../po/../src/widgets/toolbox.cpp:455 +#, fuzzy +msgid "Make selected segments lines" +msgstr "将选定段转换为连线" + +#: ../../po/../src/widgets/toolbox.cpp:458 +#, fuzzy +msgid "Make selected segments curves" +msgstr "将选定段转换为曲线" + +#: ../../po/../src/widgets/toolbox.cpp:1199 +msgid "Polygon" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1206 +msgid "Regular polygon (with one handle) instead of a star" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1218 +msgid "Corners:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1218 +msgid "Number of corners of a polygon or star" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1228 +#, fuzzy +msgid "Spoke ratio:" +msgstr "锁定外观比率" + +#. TRANSLATORS: Tip radius of a star is the distance from the center to the farthest handle. +#. Base radius is the same for the closest handle. +#: ../../po/../src/widgets/toolbox.cpp:1231 +msgid "Base radius to tip radius ratio" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1246 +#, fuzzy +msgid "Rounded:" +msgstr "圆形端点" + +#: ../../po/../src/widgets/toolbox.cpp:1246 +msgid "How much rounded are the corners (0 for sharp)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1256 +msgid "Randomized:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1256 +msgid "Scatter randomly the corners and angles" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1269 +#: ../../po/../src/widgets/toolbox.cpp:1838 +#: ../../po/../src/widgets/toolbox.cpp:2061 +msgid "Defaults" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1270 +#: ../../po/../src/widgets/toolbox.cpp:1839 +#: ../../po/../src/widgets/toolbox.cpp:2062 +msgid "" +"Reset shape parameters to defaults (use Inkscape Preferences > Tools to " +"change defaults)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1544 +msgid "W:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1544 +#, fuzzy +msgid "Width of rectangle" +msgstr "剪切选中内容" + +#: ../../po/../src/widgets/toolbox.cpp:1556 +#, fuzzy +msgid "Height of rectangle" +msgstr "缩放到选中内容" + +#: ../../po/../src/widgets/toolbox.cpp:1568 +#, fuzzy +msgid "Rx:" +msgstr "T0:" + +#: ../../po/../src/widgets/toolbox.cpp:1568 +#, fuzzy +msgid "Horizontal radius of rounded corners" +msgstr "水平中心值" + +#: ../../po/../src/widgets/toolbox.cpp:1578 +#, fuzzy +msgid "Ry:" +msgstr "T0:" + +#: ../../po/../src/widgets/toolbox.cpp:1578 +#, fuzzy +msgid "Vertical radius of rounded corners" +msgstr "水平中心值" + +#: ../../po/../src/widgets/toolbox.cpp:1594 +msgid "Not rounded" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1596 +msgid "Make corners sharp" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1805 +#, fuzzy +msgid "Turns:" +msgstr "转化" + +#: ../../po/../src/widgets/toolbox.cpp:1805 +msgid "Number of revolutions" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1815 +#, fuzzy +msgid "Divergence:" +msgstr "度" + +#: ../../po/../src/widgets/toolbox.cpp:1815 +msgid "How much denser/sparser are outer revolutions; 1 = uniform" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1825 +#, fuzzy +msgid "Inner radius:" +msgstr "半径:" + +#: ../../po/../src/widgets/toolbox.cpp:1825 +msgid "Radius of the innermost revolution (relative to the spiral size)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1957 +msgid "The width of the calligraphic pen (relative to the visible canvas area)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1967 +#, fuzzy +msgid "Thinning:" +msgstr "正在渲染" + +#: ../../po/../src/widgets/toolbox.cpp:1967 +msgid "" +"How much velocity thins the stroke (> 0 makes fast strokes thinner, < 0 " +"makes them broader, 0 makes width independent of velocity)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1980 +#, fuzzy +msgid "Angle:" +msgstr "角度" + +#: ../../po/../src/widgets/toolbox.cpp:1980 +msgid "" +"The angle of the pen's nib (in degrees; 0 = horizontal; has no effect if " +"fixation = 0)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:1990 +#, fuzzy +msgid "Fixation:" +msgstr "渐变颜料" + +#: ../../po/../src/widgets/toolbox.cpp:1990 +msgid "" +"How fixed is the pen angle (0 = always perpendicular to stroke direction, 1 " +"= fixed)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2003 +msgid "Mass:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2003 +msgid "How much inertia affects the movement of the pen" +msgstr "" + +#. TRANSLATORS: "drag" means "resistance" here +#: ../../po/../src/widgets/toolbox.cpp:2014 +#, fuzzy +msgid "Drag:" +msgstr "绘制" + +#: ../../po/../src/widgets/toolbox.cpp:2014 +msgid "How much resistance affects the movement of the pen" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2034 +msgid "Use the pressure of the input device to alter the width of the pen" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2047 +msgid "Use the tilt of the input device to alter the angle of the pen's nib" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2374 +#, fuzzy +msgid "Start:" +msgstr "星形" + +#: ../../po/../src/widgets/toolbox.cpp:2374 +msgid "The angle (in degrees) from the horizontal to the arc's start point" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2384 +msgid "End:" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2384 +msgid "The angle (in degrees) from the horizontal to the arc's end point" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2395 +#, fuzzy +msgid "Open arc" +msgstr "打开" + +#: ../../po/../src/widgets/toolbox.cpp:2396 +msgid "" +"Switch between arc (unclosed shape) and segment (closed shape with two radii)" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2415 +msgid "Make whole" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2417 +msgid "Make the shape a whole ellipse, not arc or segment" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:2644 +msgid "" +"When pressed, picks visible color without alpha and when not pressed, picks " +"color including its alpha" +msgstr "" + +#: ../../po/../src/widgets/toolbox.cpp:3039 +#, fuzzy +msgid "Make connectors avoid selected objects" +msgstr "删除选定节点" + +#: ../../po/../src/widgets/toolbox.cpp:3043 +#, fuzzy +msgid "Make connectors ignore selected objects" +msgstr "删除选定节点" + +#. +#. 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 : +#: ../share/extensions/addnodes.inx.h:1 +#, fuzzy +msgid "Add Nodes" +msgstr "节点" + +#: ../share/extensions/addnodes.inx.h:2 +msgid "Maximum Segment Length" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:1 +#, fuzzy +msgid "AI Input" +msgstr "输入" + +#: ../share/extensions/ai_input.inx.h:2 ../share/extensions/ai_output.inx.h:2 +msgid "Adobe Illustrator (*.ai)" +msgstr "" + +#: ../share/extensions/ai_input.inx.h:3 +msgid "Open files saved with Adobe Illustrator" +msgstr "" + +#: ../share/extensions/ai_output.inx.h:1 +#, fuzzy +msgid "AI Output" +msgstr "剪切" + +#: ../share/extensions/ai_output.inx.h:3 +#, fuzzy +msgid "Write Adobe Illustrator" +msgstr "向量图解器" + +#: ../share/extensions/dia.inx.h:1 +msgid "A diagram created with the program Dia" +msgstr "" + +#: ../share/extensions/dia.inx.h:2 +msgid "Dia Diagram (*.dia)" +msgstr "" + +#: ../share/extensions/dia.inx.h:3 +#, fuzzy +msgid "Dia Input" +msgstr "输入" + +#: ../share/extensions/dia.inx.h:4 +msgid "" +"In order to import Dia files, Dia itself must be installed. You can get Dia " +"at http://www.gnome.org/projects/dia/" +msgstr "" + +#: ../share/extensions/dia.inx.h:5 +msgid "" +"The dia2svg.sh script should be installed with your Inkscape distribution. " +"If you do not have it, there is likely to be something wrong with your " +"Inkscape installation." +msgstr "" + +#: ../share/extensions/dots.inx.h:1 +#, fuzzy +msgid "Connect the Dots" +msgstr "关闭视图" + +#: ../share/extensions/dots.inx.h:2 +#, fuzzy +msgid "Dot Size" +msgstr "边:" + +#: ../share/extensions/dots.inx.h:3 +#, fuzzy +msgid "Font Size" +msgstr "不保存" + +#: ../share/extensions/dropshadow.inx.h:1 +msgid "Color of shadow" +msgstr "" + +#: ../share/extensions/dropshadow.inx.h:2 +msgid "Dropshadow" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:1 +#: ../share/extensions/dxf_output.inx.h:1 +msgid "AutoCAD DXF (*.dxf)" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:2 +#, fuzzy +msgid "DXF Input" +msgstr "输入" + +#: ../share/extensions/dxf_input.inx.h:3 +msgid "Import AutoCAD's Document Exchange Format" +msgstr "" + +#: ../share/extensions/dxf_input.inx.h:4 +msgid "" +"dxf2svg may come with Inkscape, but is also at http://dxf-svg-convert." +"sourceforge.net/" +msgstr "" + +#: ../share/extensions/dxf_output.inx.h:2 +#, fuzzy +msgid "DXF Output" +msgstr "剪切" + +#: ../share/extensions/dxf_output.inx.h:3 +msgid "DXF file written by pstoedit" +msgstr "" + +#: ../share/extensions/dxf_output.inx.h:4 +msgid "pstoedit must be installed to run see http://www.pstoedit.net/pstoedit" +msgstr "" + +#: ../share/extensions/embedimage.inx.h:1 +#, fuzzy +msgid "Embed Images" +msgstr "图像" + +#: ../share/extensions/eps_input.inx.h:1 +#, fuzzy +msgid "EPS Input" +msgstr "输入" + +#: ../share/extensions/eps_input.inx.h:2 +msgid "Encapsulated Postscript" +msgstr "" + +#: ../share/extensions/eps_input.inx.h:3 +msgid "Encapsulated Postscript (*.eps)" +msgstr "" + +#: ../share/extensions/epsi_output.inx.h:1 +#, fuzzy +msgid "EPSI Output" +msgstr "剪切" + +#: ../share/extensions/epsi_output.inx.h:2 +msgid "Encapsulated Postscript Interchange (*.epsi)" +msgstr "" + +#: ../share/extensions/epsi_output.inx.h:3 +msgid "Encapsulated Postscript with a thumbnail" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:1 ../share/extensions/ffms.inx.h:1 +#: ../share/extensions/ffset.inx.h:1 ../share/extensions/ffss.inx.h:1 +#, fuzzy +msgid "Bridge Width" +msgstr "宽度" + +#: ../share/extensions/ffmet.inx.h:2 ../share/extensions/ffms.inx.h:2 +msgid "First String Length" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:3 +msgid "FretFind Multi Length ET" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:4 ../share/extensions/ffms.inx.h:4 +#: ../share/extensions/ffset.inx.h:3 ../share/extensions/ffss.inx.h:3 +msgid "Fretboard Edges" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:5 ../share/extensions/ffms.inx.h:5 +msgid "Last String Length" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:6 ../share/extensions/ffms.inx.h:6 +#: ../share/extensions/ffset.inx.h:4 ../share/extensions/ffss.inx.h:4 +msgid "Number of Frets" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:7 ../share/extensions/ffms.inx.h:7 +#: ../share/extensions/ffset.inx.h:5 ../share/extensions/ffss.inx.h:5 +msgid "Number of Strings" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:8 ../share/extensions/ffms.inx.h:8 +#: ../share/extensions/ffset.inx.h:6 ../share/extensions/ffss.inx.h:6 +#, fuzzy +msgid "Nut Width" +msgstr "宽度:" + +#: ../share/extensions/ffmet.inx.h:9 ../share/extensions/ffms.inx.h:10 +msgid "Perpendicular Distance" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:10 ../share/extensions/ffset.inx.h:7 +msgid "Scale Base (2 for Octave)" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:11 ../share/extensions/ffset.inx.h:9 +msgid "Tones in Scale" +msgstr "" + +#: ../share/extensions/ffmet.inx.h:12 ../share/extensions/ffms.inx.h:12 +#: ../share/extensions/ffset.inx.h:10 ../share/extensions/ffss.inx.h:10 +msgid "px per Unit" +msgstr "" + +#: ../share/extensions/ffms.inx.h:3 +msgid "FretFind Multi Length Scala" +msgstr "" + +#: ../share/extensions/ffms.inx.h:9 ../share/extensions/ffss.inx.h:7 +msgid "Path to Scala *.scl File" +msgstr "" + +#: ../share/extensions/ffms.inx.h:11 +msgid "Tuning (scale step for each string seperated by semicolons)" +msgstr "" + +#: ../share/extensions/ffset.inx.h:2 +msgid "FretFind Single Length ET" +msgstr "" + +#: ../share/extensions/ffset.inx.h:8 ../share/extensions/ffss.inx.h:8 +msgid "Scale Length" +msgstr "" + +#: ../share/extensions/ffss.inx.h:2 +msgid "FretFind Single Length Scala" +msgstr "" + +#: ../share/extensions/ffss.inx.h:9 +msgid "Tuning (Scale step for each string seperated by semicolons)" +msgstr "" + +#: ../share/extensions/handles.inx.h:1 +#, fuzzy +msgid "Draw Handles" +msgstr "绘制弹力手绘线" + +#: ../share/extensions/interp.inx.h:1 +#, fuzzy +msgid "Duplicate Endpaths" +msgstr "复制" + +#: ../share/extensions/interp.inx.h:2 +#, fuzzy +msgid "Exponent" +msgstr "导出" + +#: ../share/extensions/interp.inx.h:3 +msgid "Interpolate" +msgstr "" + +#: ../share/extensions/interp.inx.h:4 +msgid "Interpolate Style (Experimental)" +msgstr "" + +#: ../share/extensions/interp.inx.h:5 +msgid "Interpolation Method" +msgstr "" + +#: ../share/extensions/interp.inx.h:6 +msgid "Interpolation Steps" +msgstr "" + +#: ../share/extensions/kochify.inx.h:1 +msgid "Kochify" +msgstr "" + +#: ../share/extensions/kochify_load.inx.h:1 +msgid "Kochify (Load)" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:1 +#, fuzzy +msgid "Angle" +msgstr "角度" + +#: ../share/extensions/lindenmayer.inx.h:2 +msgid "Axiom" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:3 +#, fuzzy +msgid "Lindenmayer" +msgstr "提升" + +#: ../share/extensions/lindenmayer.inx.h:4 +msgid "Order" +msgstr "" + +#: ../share/extensions/lindenmayer.inx.h:5 +#, fuzzy +msgid "Rules" +msgstr "文件" + +#: ../share/extensions/lindenmayer.inx.h:6 +#, fuzzy +msgid "Step" +msgstr " 风格 " + +#: ../share/extensions/motion.inx.h:1 +#, fuzzy +msgid "Direction" +msgstr "位置" + +#: ../share/extensions/motion.inx.h:2 +#, fuzzy +msgid "Magnitude" +msgstr "洋红:" + +#: ../share/extensions/motion.inx.h:3 +#, fuzzy +msgid "Motion" +msgstr "旋转:" + +#: ../share/extensions/pdf_output.inx.h:1 +msgid "Adobe PDF (*.pdf)" +msgstr "" + +#: ../share/extensions/pdf_output.inx.h:2 +msgid "Adobe Portable Document Format" +msgstr "" + +#: ../share/extensions/pdf_output.inx.h:3 +#, fuzzy +msgid "PDF Output" +msgstr "剪切" + +#: ../share/extensions/ps_input.inx.h:1 +#, fuzzy +msgid "Postscript" +msgstr "点" + +#: ../share/extensions/ps_input.inx.h:2 +msgid "Postscript (*.ps)" +msgstr "" + +#: ../share/extensions/ps_input.inx.h:3 +msgid "Postscript Input" +msgstr "" + +#: ../share/extensions/radiusrand.inx.h:1 +#, fuzzy +msgid "Radius" +msgstr "半径:" + +#: ../share/extensions/radiusrand.inx.h:2 +#, fuzzy +msgid "Radius Randomize" +msgstr "提升" + +#: ../share/extensions/radiusrand.inx.h:3 +msgid "Randomize Control Points" +msgstr "" + +#: ../share/extensions/radiusrand.inx.h:4 +#, fuzzy +msgid "Randomize Nodes" +msgstr "提升" + +#: ../share/extensions/rtree.inx.h:1 +#, fuzzy +msgid "Initial Size" +msgstr "图像大小" + +#: ../share/extensions/rtree.inx.h:2 +msgid "Minimum Size" +msgstr "" + +#: ../share/extensions/rtree.inx.h:3 +msgid "Random Tree" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:1 +msgid "A diagram created with the program Sketch" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:2 +msgid "Sketch Diagram (*.sk)" +msgstr "" + +#: ../share/extensions/sk_input.inx.h:3 +msgid "Sketch Input" +msgstr "" + +#: ../share/extensions/straightseg.inx.h:1 +msgid "Behavior" +msgstr "" + +#: ../share/extensions/straightseg.inx.h:3 +msgid "Segment Straightener" +msgstr "" + +#: ../share/extensions/summersnight.inx.h:1 +msgid "Summer's Night" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:1 +#: ../share/extensions/svgz_output.inx.h:1 +#, fuzzy +msgid "Compressed Inkscape SVG (*.svgz)" +msgstr "解压文件大小:" + +#: ../share/extensions/svgz_input.inx.h:2 +#: ../share/extensions/svgz_output.inx.h:2 +msgid "Inkscape's native file format compressed with GZip" +msgstr "" + +#: ../share/extensions/svgz_input.inx.h:3 +#, fuzzy +msgid "SVGZ Input" +msgstr "输入" + +#: ../share/extensions/svgz_output.inx.h:3 +#, fuzzy +msgid "SVGZ Output" +msgstr "剪切" + +#: ../share/extensions/txt2svg.inx.h:1 +msgid "ASCII Text" +msgstr "" + +#: ../share/extensions/txt2svg.inx.h:2 +msgid "Text File (*.txt)" +msgstr "" + +#: ../share/extensions/txt2svg.inx.h:3 +#, fuzzy +msgid "Text Input" +msgstr "输入" + +#: ../share/extensions/wavy.inx.h:1 +msgid "Calculate first derivative numerically" +msgstr "" + +#: ../share/extensions/wavy.inx.h:2 +msgid "First derivative" +msgstr "" + +#: ../share/extensions/wavy.inx.h:3 +msgid "Function" +msgstr "" + +#: ../share/extensions/wavy.inx.h:4 +msgid "Function Plotter" +msgstr "" + +#: ../share/extensions/wavy.inx.h:5 +msgid "Nodes per period" +msgstr "" + +#: ../share/extensions/wavy.inx.h:6 +msgid "Periods (2*Pi each)" +msgstr "" + +#: ../share/extensions/whirl.inx.h:1 +msgid "Amount of Whirl" +msgstr "" + +#: ../share/extensions/whirl.inx.h:2 +#, fuzzy +msgid "Center X" +msgstr "X 中心:" + +#: ../share/extensions/whirl.inx.h:3 +#, fuzzy +msgid "Center Y" +msgstr "Y 中心:" + +#: ../share/extensions/whirl.inx.h:4 +#, fuzzy +msgid "Direction of Rotation" +msgstr "将选中内容降低到底层" + +#: ../share/extensions/whirl.inx.h:5 +msgid "Whirl" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:1 +msgid "A popular graphics file format for clipart" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:2 +msgid "Windows Metafile (*.wmf)" +msgstr "" + +#: ../share/extensions/wmf_input.inx.h:3 +msgid "Windows Metafile Input" +msgstr "" + +#, fuzzy +#~ msgid "Canvas size:" +#~ msgstr "不保存" + +#, fuzzy +#~ msgid "Custom canvas" +#~ msgstr "定制页面" + +#, fuzzy +#~ msgid "Current style" +#~ msgstr "勾描设置" + +#, fuzzy +#~ msgid "Arrange Objects" +#~ msgstr "对齐对象" + +#~ msgid "deg" +#~ msgstr "度" + +#, fuzzy +#~ msgid "_Credits" +#~ msgstr "彩色颜料" + +#, fuzzy +#~ msgid "Grab sensitivity" +#~ msgstr "使其敏感" + +#, fuzzy +#~ msgid "Acceleration" +#~ msgstr "选择" + +#, fuzzy +#~ msgid "Speed" +#~ msgstr "红色:" + +#, fuzzy +#~ msgid "Zoom in/out by" +#~ msgstr "缩小" + +#, fuzzy +#~ msgid "Transform" +#~ msgstr "变换" + +#, fuzzy +#~ msgid "Rotate _90 deg CW" +#~ msgstr "将角度设置为 90 度" + +#, fuzzy +#~ msgid "Rotate 9_0 deg CCW" +#~ msgstr "将角度设置为 90 度" + +#, fuzzy +#~ msgid "Flip selection horizontally" +#~ msgstr "翻转选中对象" + +#, fuzzy +#~ msgid "Flip selection vertically" +#~ msgstr "翻转选中对象" + +#~ msgid "Edit" +#~ msgstr " 编辑" + +#~ msgid "Add" +#~ msgstr "添加" + +#, fuzzy +#~ msgid "C_reate" +#~ msgstr "创建连接" + +#, fuzzy +#~ msgid "Automatically scale Rows to fit selected objects." +#~ msgstr "编辑选中对象的填充风格" + +#, fuzzy +#~ msgid "Automatically scale Columns to fit selected objects." +#~ msgstr "编辑选中对象的填充风格" + +#, fuzzy +#~ msgid "Go to root" +#~ msgstr "编辑节点" + +#, fuzzy +#~ msgid "X" +#~ msgstr "X1" + +#, fuzzy +#~ msgid "Y" +#~ msgstr "Y1" + +#, fuzzy +#~ msgid " " +#~ msgstr "X +" + +#~ msgid "Sides:" +#~ msgstr "边:" + +#~ msgid "R1:" +#~ msgstr "R1:" + +#~ msgid "R2:" +#~ msgstr "R2:" + +#~ msgid "ARG1:" +#~ msgstr "参数1:" + +#~ msgid "ARG2:" +#~ msgstr "参数2:" + +#, fuzzy +#~ msgid "Flatsides:" +#~ msgstr "边:" + +#, fuzzy +#~ msgid "Radius X:" +#~ msgstr "半径:" + +#, fuzzy +#~ msgid "Radius Y:" +#~ msgstr "半径:" + +#, fuzzy +#~ msgid "Start Angle:" +#~ msgstr "星形" + +#, fuzzy +#~ msgid "End Angle:" +#~ msgstr "角度" + +#, fuzzy +#~ msgid "Open:" +#~ msgstr "打开" + +#~ msgid "Expansion:" +#~ msgstr "扩充:" + +#, fuzzy +#~ msgid "Revolutions:" +#~ msgstr "旋转:" + +#~ msgid "Argument:" +#~ msgstr "参数:" + +#~ msgid "T0:" +#~ msgstr "T0:" + +#~ msgid "RX:" +#~ msgstr "RX:" + +#~ msgid "RY:" +#~ msgstr "RY:" + +#, fuzzy +#~ msgid "Rectangle _Properties" +#~ msgstr "长方形属性" + +#, fuzzy +#~ msgid "Star _Properties" +#~ msgstr "星形属性" + +#, fuzzy +#~ msgid "Ellipse _Properties" +#~ msgstr "连接属性" + +#, fuzzy +#~ msgid "Spiral _Properties" +#~ msgstr "螺旋属性" + +#, fuzzy +#~ msgid "Document Preferences" +#~ msgstr "项目是引用" + +#, fuzzy +#~ msgid "Extensions Editor" +#~ msgstr "扩充:" + +#, fuzzy +#~ msgid "Preferences" +#~ msgstr "项目是引用" + +#, fuzzy +#~ msgid "Layer Editor" +#~ msgstr "XML 编辑器" + +#, fuzzy +#~ msgid "Text Properties" +#~ msgstr "文本属性" + +#, fuzzy +#~ msgid "Transformation" +#~ msgstr "转化" + +#, fuzzy +#~ msgid "_Export..." +#~ msgstr "导入" + +#, fuzzy +#~ msgid "_Document Properties" +#~ msgstr "文档设置" + +#, fuzzy +#~ msgid "In_kscape Preferences" +#~ msgstr "Sodipodi:%s:%s:%d" + +#, fuzzy +#~ msgid "Select _Original Clone" +#~ msgstr "选择" + +#, fuzzy +#~ msgid "Tile" +#~ msgstr "标题:" + +#, fuzzy +#~ msgid "Select A_ll" +#~ msgstr "选择" + +#, fuzzy +#~ msgid "Select Non_e" +#~ msgstr "选择" + +#, fuzzy +#~ msgid "Zoom _In" +#~ msgstr "放大" + +#, fuzzy +#~ msgid "Zoom _Out" +#~ msgstr "缩小" + +#, fuzzy +#~ msgid "Pre_vious" +#~ msgstr "关闭窗口" + +#, fuzzy +#~ msgid "Nex_t" +#~ msgstr "文本" + +#, fuzzy +#~ msgid "Tool Co_ntrols bar" +#~ msgstr "Oaf 选项" + +#, fuzzy +#~ msgid "R_ename Layer..." +#~ msgstr "提升" + +#, fuzzy +#~ msgid "D_uplicate Layer" +#~ msgstr "复制" + +#, fuzzy +#~ msgid "_Anchor Layer" +#~ msgstr "降低" + +#, fuzzy +#~ msgid "_Delete Layer" +#~ msgstr "选择" + +#, fuzzy +#~ msgid "Select Ne_xt Layer" +#~ msgstr "选择" + +#, fuzzy +#~ msgid "Select Pre_vious Layer" +#~ msgstr "选择" + +#, fuzzy +#~ msgid "Select To_p Layer" +#~ msgstr "选择" + +#, fuzzy +#~ msgid "Move to Ne_w Layer" +#~ msgstr "内存文档 %d" + +#, fuzzy +#~ msgid "Move to B_ottom Layer" +#~ msgstr "将选中内容降低到底层" + +#, fuzzy +#~ msgid "_Trace Bitmap..." +#~ msgstr "不完整的位图" + +#, fuzzy +#~ msgid "_Put Text on Path" +#~ msgstr "将选定对象转换为曲线" + +#, fuzzy +#~ msgid "_Remove Text from Path" +#~ msgstr "将选定对象转换为曲线" + +#~ msgid "Arc" +#~ msgstr "弧线" + +#, fuzzy +#~ msgid "Freehand" +#~ msgstr "手绘" + +#, fuzzy +#~ msgid "DynaDraw" +#~ msgstr "绘制" + +#~ msgid "Stroke" +#~ msgstr "勾描" + +#, fuzzy +#~ msgid "Corners" +#~ msgstr "关闭视图" + +#, fuzzy +#~ msgid "Delete" +#~ msgstr "删除" + +#, fuzzy +#~ msgid "Join" +#~ msgstr "连接:" + +#, fuzzy +#~ msgid "Delete Segment" +#~ msgstr "复制选中内容" + +#, fuzzy +#~ msgid "Break" +#~ msgstr "拆分" + +#, fuzzy +#~ msgid "Symmetric" +#~ msgstr "不对称" + +#, fuzzy +#~ msgid "Line" +#~ msgstr "线性" + +#~ msgid "New" +#~ msgstr "新建" + +#, fuzzy +#~ msgid "Revert to Saved" +#~ msgstr "转换为曲线(_R)" + +#, fuzzy +#~ msgid "Save" +#~ msgstr "保存" + +#, fuzzy +#~ msgid "Save As..." +#~ msgstr "保存为" + +#, fuzzy +#~ msgid "Import..." +#~ msgstr "导入" + +#, fuzzy +#~ msgid "Export..." +#~ msgstr "导出" + +#, fuzzy +#~ msgid "Print..." +#~ msgstr "打印" + +#, fuzzy +#~ msgid "Global Inkscape preferences (Shift+Ctrl+P)" +#~ msgstr "显示设置" + +#, fuzzy +#~ msgid "Undo" +#~ msgstr "撤销 " + +#, fuzzy +#~ msgid "Redo" +#~ msgstr "恢复" + +#, fuzzy +#~ msgid "Cut" +#~ msgstr "剪切" + +#, fuzzy +#~ msgid "Copy" +#~ msgstr "复制" + +#, fuzzy +#~ msgid "Duplicate selected object(s) (Ctrl+D)" +#~ msgstr "翻转选中对象" + +#, fuzzy +#~ msgid "Clone selected object (Alt+D)" +#~ msgstr "翻转选中对象" + +#, fuzzy +#~ msgid "Zoom in (+)" +#~ msgstr "放大" + +#, fuzzy +#~ msgid "Zoom out (-)" +#~ msgstr "缩小" + +#, fuzzy +#~ msgid "Zoom to 1:1 (100%) (1)" +#~ msgstr "缩放到 1:1" + +#, fuzzy +#~ msgid "Zoom to 1:2 (50%) (2)" +#~ msgstr "缩放到 1:2" + +#, fuzzy +#~ msgid "Zoom to 2:1 (200%) (0)" +#~ msgstr "缩放到 2:1" + +#, fuzzy +#~ msgid "Zoom to fit selection in window (3)" +#~ msgstr "将选中内容提升到顶层" + +#, fuzzy +#~ msgid "Zoom to fit drawing in window (4)" +#~ msgstr "编辑窗口" + +#, fuzzy +#~ msgid "Zoom to fit page in window (5)" +#~ msgstr "编辑窗口" + +#, fuzzy +#~ msgid "Zoom to fit page width in window (6)" +#~ msgstr "设定页面宽度" + +#, fuzzy +#~ msgid "Fill and Stroke dialog (Shift+Ctrl+F)" +#~ msgstr "填充并勾描" + +#, fuzzy +#~ msgid "Group selected objects (Ctrl+G)" +#~ msgstr "编组选中对象" + +#, fuzzy +#~ msgid "Ungroup selected group(s) (Ctrl+U)" +#~ msgstr "分解选中对象构成的组" + +#, fuzzy +#~ msgid "Raise selection up one step (PgUp)" +#~ msgstr "将选中内容提升一个图层" + +#, fuzzy +#~ msgid "Lower selection down one step (PgDn)" +#~ msgstr "将选中内容降低一个图层" + +#, fuzzy +#~ msgid "Raise selection to top (Home)" +#~ msgstr "将选中内容提升到顶层" + +#, fuzzy +#~ msgid "Lower selection to bottom (End)" +#~ msgstr "将选中内容降低到底层" + +#, fuzzy +#~ msgid "Move selection to new layer" +#~ msgstr "将选中内容降低一个图层" + +#, fuzzy +#~ msgid "Move selection to next layer" +#~ msgstr "将选中内容降低一个图层" + +#, fuzzy +#~ msgid "Move selection to previous layer" +#~ msgstr "将选中内容复制到剪贴板" + +#, fuzzy +#~ msgid "Move selection to top layer" +#~ msgstr "将选中内容提升到顶层" + +#, fuzzy +#~ msgid "Move selection to bottom layer" +#~ msgstr "将选中内容降低到底层" + +#, fuzzy +#~ msgid "Rotate selection 90° clockwise (Shift+Ctrl+Right)" +#~ msgstr "将选定对象顺时针旋转 90 度" + +#, fuzzy +#~ msgid "Rotate selection 90° counter-clockwise (Shift+Ctrl+Left)" +#~ msgstr "将选定对象顺时针旋转 90 度" + +#, fuzzy +#~ msgid "Flip selection horizontally (H)" +#~ msgstr "翻转选中对象" + +#, fuzzy +#~ msgid "Flip selection vertically (V)" +#~ msgstr "翻转选中对象" + +#, fuzzy +#~ msgid "Align and Distribute dialog (Shift+Ctrl+A)" +#~ msgstr "属性" + +#, fuzzy +#~ msgid "Convert selected object(s) to path(s) (Shift+Ctrl+C)" +#~ msgstr "将选定对象转换为曲线" + +#, fuzzy +#~ msgid "Convert selected stroke(s) to path(s) (Ctrl+Alt+C)" +#~ msgstr "将选定对象转换为曲线" + +#, fuzzy +#~ msgid "Text and Font dialog (Shift+Ctrl+T)" +#~ msgstr "桌面设置" + +#, fuzzy +#~ msgid "Node tool" +#~ msgstr "节点编辑" + +#, fuzzy +#~ msgid "Zoom tool" +#~ msgstr "缩小" + +#, fuzzy +#~ msgid "Rectangle tool" +#~ msgstr "长方形" + +#, fuzzy +#~ msgid "Arc tool" +#~ msgstr "弓形作用:" + +#, fuzzy +#~ msgid "Star tool" +#~ msgstr "起点颜色" + +#, fuzzy +#~ msgid "Spiral tool" +#~ msgstr "螺旋形" + +#, fuzzy +#~ msgid "Freehand tool" +#~ msgstr "手绘" + +#, fuzzy +#~ msgid "Pen tool" +#~ msgstr "长方形" + +#, fuzzy +#~ msgid "Text tool" +#~ msgstr "起点颜色" + +#, fuzzy +#~ msgid "Dropper tool" +#~ msgstr "螺旋形" + +#, fuzzy +#~ msgid "When scaling rectangles, scale radii of rounded corners" +#~ msgstr "水平中心值" + +#, fuzzy +#~ msgid "Delete segment between two nodes" +#~ msgstr "删除选定节点" + +#, fuzzy +#~ msgid "URI:" +#~ msgstr "URL:" + +#, fuzzy +#~ msgid "Select All in All Layers" +#~ msgstr "选择" + +#, fuzzy +#~ msgid "Invert Selection" +#~ msgstr "选择" + +#, fuzzy +#~ msgid "Clean up selected path(s)" +#~ msgstr "组合选定路径" + +#, fuzzy +#~ msgid "_Scripts..." +#~ msgstr "打印" + +#, fuzzy +#~ msgid "Align and Distribute" +#~ msgstr "属性" + +#, fuzzy +#~ msgid "Align and Distribute Dialog" +#~ msgstr "属性" + +#, fuzzy +#~ msgid "Export Dialog" +#~ msgstr "导出为" + +#, fuzzy +#~ msgid "Fill and Stroke Dialog" +#~ msgstr "填充并勾描" + +#, fuzzy +#~ msgid "Find Dialog" +#~ msgstr "对齐对话框" + +#, fuzzy +#~ msgid "Inkscape Preferences" +#~ msgstr "Sodipodi:%s:%s:%d" + +#, fuzzy +#~ msgid "Inkscape Preferences Dialog" +#~ msgstr "Sodipodi:%s:%s:%d" + +#, fuzzy +#~ msgid "Layer Editor Dialog" +#~ msgstr "将选中内容提升到顶层" + +#, fuzzy +#~ msgid "Text Properties Dialog" +#~ msgstr "对象属性" + +#, fuzzy +#~ msgid "Transformation Dialog" +#~ msgstr "变换对话框" + +#, fuzzy +#~ msgid "Tree Editor" +#~ msgstr "XML 编辑器" + +#, fuzzy +#~ msgid "XML Editor Dialog" +#~ msgstr "XML 编辑器" + +#, fuzzy +#~ msgid "Row height:" +#~ msgstr "高度:" + +#, fuzzy +#~ msgid "Column width:" +#~ msgstr "改变" + +#, fuzzy +#~ msgid "Creating anchor at (%g,%g)" +#~ msgstr "绘制星形" + +#, fuzzy +#~ msgid "EPS Output Settings" +#~ msgstr "文档设置" + +#, fuzzy +#~ msgid "Inkscape" +#~ msgstr "Sodipodi:%s:%s:%d" + +#, fuzzy +#~ msgid "Top of aligned objects to top of anchor" +#~ msgstr "将内部对象对齐到顶边" + +#, fuzzy +#~ msgid "Alternate sign" +#~ msgstr "饱和度:" + +#, fuzzy +#~ msgid "Rows:" +#~ msgstr "椭圆" + +#, fuzzy +#~ msgid "Minor grid line color:" +#~ msgstr "指示线颜色" + +#~ msgid "Grid color" +#~ msgstr "栅格颜色" + +#, fuzzy +#~ msgid "Grid emphasis color" +#~ msgstr "栅格颜色" + +#, fuzzy +#~ msgid "Major grid line spacing:" +#~ msgstr "X 间据:" + +#, fuzzy +#~ msgid "Background (also for export):" +#~ msgstr "终点颜色" + +#, fuzzy +#~ msgid "Picking colors:" +#~ msgstr "选取颜色" + +#~ msgid "Fill style" +#~ msgstr "填充模式" + +#, fuzzy +#~ msgid "Fill:" +#~ msgstr "填充" + +#, fuzzy +#~ msgid "winding" +#~ msgstr "正在渲染" + +#, fuzzy +#~ msgid "alternating" +#~ msgstr "饱和度:" + +#, fuzzy +#~ msgid "Update Properties" +#~ msgstr "项目属性" + +#, fuzzy +#~ msgid "Label invalid" +#~ msgstr "标识合法" + +#, fuzzy +#~ msgid "executable" +#~ msgstr "长方形" + +#, fuzzy +#~ msgid "file" +#~ msgstr "文件(_F)" + +#, fuzzy +#~ msgid "extension" +#~ msgstr "扩充:" + +#, fuzzy +#~ msgid "path" +#~ msgstr "pt" + +#, fuzzy +#~ msgid "absolute" +#~ msgstr "绝对" + +#~ msgid "Could not create sodipodi-svg-doc factory" +#~ msgstr "无法创建 sodipodi-svg-doc 车间" + +#, fuzzy +#~ msgid "SVG Files" +#~ msgstr "文件" + +#, fuzzy +#~ msgid "Make s_ensitive" +#~ msgstr "使其敏感" + +#, fuzzy +#~ msgid "Make i_nsensitive" +#~ msgstr "使其不敏感" + +#, fuzzy +#~ msgid "Layer Properties" +#~ msgstr "星形属性" + +#, fuzzy +#~ msgid "Select object(s) to tile." +#~ msgstr "将选定对象转换为曲线" + +#~ msgid "Sensitive" +#~ msgstr "敏感的" + +#~ msgid "Active" +#~ msgstr "活跃" + +#~ msgid "Printable" +#~ msgstr "可打印的" + +#, fuzzy +#~ msgid "Untitled" +#~ msgstr "单位" + +#, fuzzy +#~ msgid "Document Name:" +#~ msgstr "文档" + +#, fuzzy +#~ msgid "Image URI:" +#~ msgstr "图像" + +#~ msgid "Visible" +#~ msgstr "可见" + +#, fuzzy +#~ msgid "Flatness:" +#~ msgstr "边:" + +#, fuzzy +#~ msgid "Other" +#~ msgstr "顺序" + +#, fuzzy +#~ msgid "Trace: Selected object is not an image" +#~ msgstr "将选定对象顺时针旋转 90 度" + +#, fuzzy +#~ msgid "object" +#~ msgstr "对象" + +#, fuzzy +#~ msgid "user space" +#~ msgstr "用户空间" + +#, fuzzy +#~ msgid "Coordinates:" +#~ msgstr "彩色颜料" + +#, fuzzy +#~ msgid "Alignment:" +#~ msgstr "对齐基础" + +#, fuzzy +#~ msgid "Draw arc: %s x %s" +#~ msgstr "绘制弧线" + +#, fuzzy +#~ msgid "Draw rectangle: %s x %s" +#~ msgstr "绘制长方形" + +#, fuzzy +#~ msgid "Move by %s, %s" +#~ msgstr "移动" + +#, fuzzy +#~ msgid "Active group" +#~ msgstr "活跃" + +#, fuzzy +#~ msgid "typeset object" +#~ msgstr "文本对象" + +#, fuzzy +#~ msgid "Pattern Fill" +#~ msgstr "模式填充" + +#~ msgid "Snap to grid" +#~ msgstr "定位到栅格" + +#~ msgid "Snap to guides" +#~ msgstr "定位到指示线" + +#, fuzzy +#~ msgid "_Menu" +#~ msgstr "打开(_O)" + +#, fuzzy +#~ msgid "Snap points to the grid" +#~ msgstr "定位到栅格" + +#, fuzzy +#~ msgid "Rect" +#~ msgstr "长方形" + +#~ msgid "meters" +#~ msgstr "ç±³" + +#~ msgid "Userspace unit" +#~ msgstr "用户空间单位" + +#~ msgid "User" +#~ msgstr "用户" + +#~ msgid "Userspace units" +#~ msgstr "用户空间单位" + +#, fuzzy +#~ msgid "Ru_lers" +#~ msgstr "文件" + +#, fuzzy +#~ msgid "Show or hide rulers" +#~ msgstr "显示指示线" + +#, fuzzy +#~ msgid "_New Window" +#~ msgstr "新建视图" + +#~ msgid "Mode:" +#~ msgstr "模式:" + +#~ msgid "Alpha:" +#~ msgstr "Alpha:" + +#~ msgid "Value:" +#~ msgstr "值:" + +#~ msgid "Stroke settings" +#~ msgstr "勾描设置" + +#~ msgid "Item properties" +#~ msgstr "项目属性" + +#, fuzzy +#~ msgid "Quit" +#~ msgstr "退出(_Q)" + +#, fuzzy +#~ msgid "Combine multiple paths" +#~ msgstr "组合选定路径" + +#, fuzzy +#~ msgid "New View" +#~ msgstr "新建视图" + +#, fuzzy +#~ msgid "Fill and stroke settings" +#~ msgstr "勾描设置" + +#, fuzzy +#~ msgid "Object transformations" +#~ msgstr "重置变换" + +#, fuzzy +#~ msgid "Text editing and font settings" +#~ msgstr "桌面设置" + +#, fuzzy +#~ msgid "Fill Rule" +#~ msgstr "填充模式" + +#, fuzzy +#~ msgid "Tool has no options" +#~ msgstr "Oaf 选项" + +#, fuzzy +#~ msgid "Visual transformation" +#~ msgstr "重置变换" + +#, fuzzy +#~ msgid "Show content" +#~ msgstr "内容" + +#, fuzzy +#~ msgid "Selected object has no curve, cannot outline." +#~ msgstr "将选定对象转换为曲线" + +#, fuzzy +#~ msgid "Proportion:" +#~ msgstr "位置" + +#, fuzzy +#~ msgid "Inkscape _Options" +#~ msgstr "Sodipodi:%s:%s:%d" + +#, fuzzy +#~ msgid "Tool Optio_ns" +#~ msgstr "Oaf 选项" + +#, fuzzy +#~ msgid "gradientUnits" +#~ msgstr "渐变" + +#, fuzzy +#~ msgid "gradientSpread" +#~ msgstr "渐变" + +#, fuzzy +#~ msgid "nonzero" +#~ msgstr "无" + +#, fuzzy +#~ msgid "" +#~ "%s is not regular file.\n" +#~ "Although inkscape will run, you can\n" +#~ "neither load nor save preferences\n" +#~ msgstr "" +#~ "%s 不是普通文件。\n" +#~ "虽然 sodipodi 能够运行,您即\n" +#~ "不能读取也不能保存设置\n" + +#, fuzzy +#~ msgid "" +#~ "%s either is not valid xml file or\n" +#~ "you do not have read premissions on it.\n" +#~ "Although inkscape will run, you\n" +#~ "are neither able to load nor save\n" +#~ "preferences." +#~ msgstr "" +#~ "%s 不是合法的 xml 文件或\n" +#~ "您没有访问它的读权限。\n" +#~ "虽然 sodipodi 能够运行,\n" +#~ "但您即不能读取也不能保存\n" +#~ "设置。" + +#, fuzzy +#~ msgid "" +#~ "%s is not valid inkscape preferences file.\n" +#~ "Although inkscape will run, you\n" +#~ "are neither able to load nor save\n" +#~ "preferences." +#~ msgstr "" +#~ "%s 不是合法的 sodipodi 设置文件。\n" +#~ "虽然 sodipodi 能够运行,\n" +#~ "但您即不能读取也不能保存\n" +#~ "设置。" + +#, fuzzy +#~ msgid "" +#~ "Cannot create directory %s.\n" +#~ "Although inkscape will run, you\n" +#~ "are neither able to load nor save\n" +#~ "%s." +#~ msgstr "" +#~ "无法创建目录 %s。\n" +#~ "虽然 sodipodi 能够运行,\n" +#~ "但您即不能读取也不能保存\n" +#~ "设置。" + +#, fuzzy +#~ msgid "" +#~ "%s is not a valid directory.\n" +#~ "Although inkscape will run, you\n" +#~ "are neither able to load nor save\n" +#~ "preferences." +#~ msgstr "" +#~ "%s 不是合法的目录。\n" +#~ "虽然 sodipodi 能够运行,\n" +#~ "但您即不能读取也不能保存\n" +#~ "设置。" + +#, fuzzy +#~ msgid "" +#~ "Cannot create file %s.\n" +#~ "Although inkscape will run, you\n" +#~ "are neither able to load nor save\n" +#~ "preferences." +#~ msgstr "" +#~ "无法创建文件 %s。\n" +#~ "虽然 sodipodi 能够运行,\n" +#~ "但您即不能读取也不能保存\n" +#~ "设置。" + +#, fuzzy +#~ msgid "" +#~ "Cannot write file %s.\n" +#~ "Although inkscape will run, you\n" +#~ "are neither able to load nor save\n" +#~ "preferences." +#~ msgstr "" +#~ "无法写入文件 %s。\n" +#~ "虽然 sodipodi 能够运行,\n" +#~ "但您即不能读取也不能保存\n" +#~ "设置。" + +#~ msgid "End color" +#~ msgstr "终点颜色" + +#, fuzzy +#~ msgid "Make sides flat" +#~ msgstr "使其敏感" + +#~ msgid "Bring to _Front" +#~ msgstr "放置在前面(_F)" + +#~ msgid "Send to _Back" +#~ msgstr "放置在后面(_B)" + +#~ msgid "Document %s has unsaved changes, save them?" +#~ msgstr "文档 %s 含有未保存的修改,保存吗?" + +#, fuzzy +#~ msgid "Object Size and Position" +#~ msgstr "大小和位置" + +#~ msgid "Size and Position" +#~ msgstr "大小和位置" + +#, fuzzy +#~ msgid "Tool attributes" +#~ msgstr "%s 属性" + +#, fuzzy +#~ msgid "Proportion" +#~ msgstr "位置" + +#, fuzzy +#~ msgid "Tool has no attributes" +#~ msgstr "%s 属性" + +#~ msgid "Item" +#~ msgstr "项目" + +#~ msgid "Group Properties" +#~ msgstr "组属性" + +#~ msgid "Ungroup" +#~ msgstr "分解组" + +#~ msgid "Link" +#~ msgstr "连接" + +#~ msgid "Fill settings" +#~ msgstr "填充设置" + +#, fuzzy +#~ msgid "Break line at selected nodes" +#~ msgstr "选定节点处为尖点线" + +#~ msgid "Bring to Front" +#~ msgstr "放置在前面" + +#~ msgid "Send to Back" +#~ msgstr "放置在后面" + +#, fuzzy +#~ msgid "Lower selected objects to bottom" +#~ msgstr "将选中内容降低到底层" + +#, fuzzy +#~ msgid "Raise selected objects one position" +#~ msgstr "将选中内容提升到顶层" + +#, fuzzy +#~ msgid "Lower selected objects one position" +#~ msgstr "将选中内容降低到底层" + +#, fuzzy +#~ msgid "Draw freehand curves and straight lines" +#~ msgstr "绘制手绘线" + +#, fuzzy +#~ msgid "In" +#~ msgstr "英寸" + +#, fuzzy +#~ msgid "Toggle grid" +#~ msgstr "切换边框" + +#, fuzzy +#~ msgid "Toggle guides" +#~ msgstr "切换边框" + +#~ msgid "1:1" +#~ msgstr "1:1" + +#~ msgid "1:2" +#~ msgstr "1:2" + +#~ msgid "2:1" +#~ msgstr "2:1" + +#~ msgid "Editing Window" +#~ msgstr "编辑窗口" + +#, fuzzy +#~ msgid "Editing window properties" +#~ msgstr "编辑窗口" + +#, fuzzy +#~ msgid "Tool Attributes" +#~ msgstr "属性" + +#~ msgid "Sodipodi" +#~ msgstr "Sodipodi" + +#~ msgid "Desktop settings" +#~ msgstr "桌面设置" + +#, fuzzy +#~ msgid "Iso grid" +#~ msgstr "显示栅格" + +#~ msgid "Display settings" +#~ msgstr "显示设置" + +#, fuzzy +#~ msgid "Export png file" +#~ msgstr "导出文件" + +#~ msgid "Object style" +#~ msgstr "对象风格" + +#, fuzzy +#~ msgid "Inkscape: %s : XML View" +#~ msgstr "Sodipodi:%s:%s:%d" + +#, fuzzy +#~ msgid "New Docked Toolbox" +#~ msgstr "显示工具条" + +#~ msgid "Drawing Mode" +#~ msgstr "绘图模式" + +#, fuzzy +#~ msgid "" +#~ "%s is not regular file.\n" +#~ "Although inkscape will run, you are\n" +#~ "not able to use extensions (plugins)\n" +#~ msgstr "" +#~ "%s 不是普通文件。\n" +#~ "虽然 sodipodi 能够运行,您即\n" +#~ "不能读取也不能保存设置\n" + +#, fuzzy +#~ msgid "" +#~ "%s either is not valid xml file or\n" +#~ "you do not have read premissions on it.\n" +#~ "Although inkscape will run, you are\n" +#~ "not able to use extensions (plugins)\n" +#~ msgstr "" +#~ "%s 不是合法的 xml 文件或\n" +#~ "您没有访问它的读权限。\n" +#~ "虽然 sodipodi 能够运行,\n" +#~ "但您即不能读取也不能保存\n" +#~ "设置。" + +#, fuzzy +#~ msgid "" +#~ "%s is not valid inkscape extensions file.\n" +#~ "Although inkscape will run, you are\n" +#~ "not able to use extensions (plugins)\n" +#~ msgstr "" +#~ "%s 不是合法的 sodipodi 设置文件。\n" +#~ "虽然 sodipodi 能够运行,\n" +#~ "但您即不能读取也不能保存\n" +#~ "设置。" + +#, fuzzy +#~ msgid "" +#~ "Cannot create directory %s.\n" +#~ "Although inkscape will run, you are\n" +#~ "not able to use extensions (plugins)\n" +#~ msgstr "" +#~ "无法创建目录 %s。\n" +#~ "虽然 sodipodi 能够运行,\n" +#~ "但您即不能读取也不能保存\n" +#~ "设置。" + +#, fuzzy +#~ msgid "" +#~ "%s is not a valid directory.\n" +#~ "Although inkscape will run, you are\n" +#~ "not able to use extensions (plugins)\n" +#~ msgstr "" +#~ "%s 不是合法的目录。\n" +#~ "虽然 sodipodi 能够运行,\n" +#~ "但您即不能读取也不能保存\n" +#~ "设置。" + +#, fuzzy +#~ msgid "" +#~ "Cannot create file %s.\n" +#~ "Although inkscape will run, you are\n" +#~ "not able to use extensions (plugins)\n" +#~ msgstr "" +#~ "无法创建文件 %s。\n" +#~ "虽然 sodipodi 能够运行,\n" +#~ "但您即不能读取也不能保存\n" +#~ "设置。" + +#, fuzzy +#~ msgid "" +#~ "Cannot write file %s.\n" +#~ "Although inkscape will run, you are\n" +#~ "not able to use extensions (plugins)\n" +#~ msgstr "" +#~ "无法写入文件 %s。\n" +#~ "虽然 sodipodi 能够运行,\n" +#~ "但您即不能读取也不能保存\n" +#~ "设置。" + +#~ msgid "Unknown item :-(" +#~ msgstr "未知项目 :-(" + +#, fuzzy +#~ msgid "Zoom in drawing" +#~ msgstr "缩放到图画" + +#, fuzzy +#~ msgid "Zoom out drawing" +#~ msgstr "缩放到图画" + +#, fuzzy +#~ msgid "Set zoom factor to 1:1" +#~ msgstr "缩放到 1:1" + +#, fuzzy +#~ msgid "Set zoom factor to 1:2" +#~ msgstr "缩放到 1:2" + +#, fuzzy +#~ msgid "Set zoom factor to 2:1" +#~ msgstr "缩放到 2:1" + +#~ msgid "Document" +#~ msgstr "文档" + +#, fuzzy +#~ msgid "Document variant:" +#~ msgstr "文档" + +#, fuzzy +#~ msgid "Save document as" +#~ msgstr "内存文档 %d" + +#~ msgid "About sodipodi" +#~ msgstr "关于 sodipodi" + +#, fuzzy +#~ msgid "About Sodipodi" +#~ msgstr "关于 sodipodi" + +#~ msgid "The SVG ID of item" +#~ msgstr "项目的 SVG 标识" + +#~ msgid "The ID is not valid" +#~ msgstr "标识不合法" + +#~ msgid "The ID is already defined" +#~ msgstr "标识已定义" + +#~ msgid "Object position and size" +#~ msgstr "对象位置与尺寸" + +#~ msgid "Position and size" +#~ msgstr "位置与尺寸" + +#~ msgid "Dynahand" +#~ msgstr "弹力手绘" + +#~ msgid "Text Editing" +#~ msgstr "文本编辑" + +#~ msgid "Display Properties" +#~ msgstr "显示属性" + +#, fuzzy +#~ msgid "Lower selected objects one level" +#~ msgstr "将选定对象转换为曲线" + +#, fuzzy +#~ msgid "Select tool - select and transform objects" +#~ msgstr "选择并变换" + +#, fuzzy +#~ msgid "Save as:" +#~ msgstr "保存为" + +#~ msgid "A path - whatever it means" +#~ msgstr "一条路径 - 任何含义" + +#~ msgid "Welcome !" +#~ msgstr "欢迎 !" + +#~ msgid "Sodipodi SVG Document" +#~ msgstr "Sodipodi SVG 文档" + +#~ msgid "Sodipodi SVG Document factory" +#~ msgstr "Sodipodi SVG 文档车间" + +#~ msgid "Align objects to vertical mid" +#~ msgstr "将对象对齐到垂直中央" + +#~ msgid "Align outside object to bottom border" +#~ msgstr "将外部对象对齐到底边" + +#~ msgid "Align outside object to left border" +#~ msgstr "将外部对象对齐到左边" + +#~ msgid "Align outside object to right border" +#~ msgstr "将外部对象对齐到右边" + +#~ msgid "Align outside object to top border" +#~ msgstr "将外部对象对齐到顶边" + +#~ msgid "Alignment base" +#~ msgstr "对齐基础" + +#~ msgid "Choose align type" +#~ msgstr "选择对齐类型" + +#~ msgid "Parent X =" +#~ msgstr "父坐标 X =" + +#~ msgid "Parent Y =" +#~ msgstr "父坐标 Y =" + +#~ msgid "Y +" +#~ msgstr "Y +" + +#~ msgid " Color fill " +#~ msgstr " 色彩填充 " + +#~ msgid " General " +#~ msgstr " 通用 " + +#~ msgid "Add new gradient" +#~ msgstr "添加新渐变" + +#~ msgid "Choose fill color" +#~ msgstr "选择填充颜色" + +#~ msgid "Choose stroke color" +#~ msgstr "选择勾描颜色" + +#~ msgid "Endpoints:" +#~ msgstr "端点:" + +#~ msgid "Fill Color:" +#~ msgstr "填充颜色:" + +#~ msgid "Fractal fill" +#~ msgstr "分形填充" + +#~ msgid "Pick fill color" +#~ msgstr "选取填充颜色" + +#~ msgid "Scale with object" +#~ msgstr "按对象缩放" + +#~ msgid "centimeter" +#~ msgstr "厘米" + +#~ msgid "color" +#~ msgstr "颜色" + +#~ msgid "millimeters" +#~ msgstr "毫米" + +#~ msgid "points" +#~ msgstr "点" + +#~ msgid "1.0MB" +#~ msgstr "1.0MB" + +#~ msgid "Back One" +#~ msgstr "后移一个位置" + +#~ msgid "Convert selected segments to curves" +#~ msgstr "将选定段转换为曲线" + +#~ msgid "Cusp line at selected nodes" +#~ msgstr "选定节点处为尖点线" + +#~ msgid "Desktop" +#~ msgstr "桌面" + +#~ msgid "Drawing Context" +#~ msgstr "绘图上下文" + +#~ msgid "Export picture to png" +#~ msgstr "将图形导出为 png" + +#~ msgid "Forward One" +#~ msgstr "前移一个位置" + +#~ msgid "Include one node into selected segments" +#~ msgstr "将一个节点包含到选定段中去" + +#~ msgid "Join 2 selected endpoints" +#~ msgstr "连接两个选定端点" + +#~ msgid "Set dimensions" +#~ msgstr "设定尺寸" + +#~ msgid "Smooth line at selected nodes" +#~ msgstr "使选定节点处成为光滑线段" + +#~ msgid "Where to export" +#~ msgstr "导出到何处" + +#~ msgid "X0" +#~ msgstr "X0" + +#~ msgid "XML Tree" +#~ msgstr "XML 树" + +#~ msgid "Y0" +#~ msgstr "Y0" + +#~ msgid "_Align" +#~ msgstr "对齐(_A)" + +#~ msgid "Break apart selected paths" +#~ msgstr "拆分选定路径" + +#~ msgid "Drawing context" +#~ msgstr "绘图上下文" + +#~ msgid "Edit font style of selected objects" +#~ msgstr "编辑选中对象的字体风格" + +#~ msgid "Import " +#~ msgstr "导入 " + +#~ msgid "New drawing" +#~ msgstr "新建图画" + +#~ msgid "No I'd rather do some more cool vector drawing with sodipodi." +#~ msgstr "不,我宁愿用 sodipodi 做些更酷的向量图画。" + +#~ msgid "Nope !" +#~ msgstr "不 !" + +#~ msgid "Paste from clipboard" +#~ msgstr "从剪贴板中粘贴" + +#~ msgid "Preview print drawing" +#~ msgstr "预览打印图画" + +#~ msgid "Quit or not quit ?" +#~ msgstr "退出或不退出?" + +#~ msgid "Really wanna quit sodipodi ?" +#~ msgstr "真的要退出 sodipodi ?" + +#, fuzzy +#~ msgid "Rotate selected objects 90deg clockwise" +#~ msgstr "将选定对象顺时针旋转 90 度" + +#~ msgid "Save drawing " +#~ msgstr "保存图画 " + +#~ msgid "Yep !" +#~ msgstr "是 !" + +#~ msgid "Yes quick! I want to leave sodipodi and come back later." +#~ msgstr "是的 快点!我希望离开 sodipodi 一会儿再回来。" + +#~ msgid "Align to bottom middle" +#~ msgstr "对齐到底部中央" + +#~ msgid "Align to bottom right" +#~ msgstr "对齐到底部右侧" + +#~ msgid "Align to center" +#~ msgstr "对齐到中央" + +#~ msgid "Align to top middle" +#~ msgstr "对齐到顶部中央" + +#~ msgid "Choose metric for center" +#~ msgstr "为中央选择公制" + +#~ msgid "Close dialog - Ctl+c" +#~ msgstr "关闭对话框 - Ctl+c" + +#~ msgid "Expand dialog - Ctl+e" +#~ msgstr "扩展对话框 - Ctl+e" + +#~ msgid "Keep height of selection during transformation" +#~ msgstr "在变换中保持选中内容的高度不变" + +#~ msgid "Keep width of selection during transformation" +#~ msgstr "在变换中保持选中内容的宽度不变" + +#~ msgid "Orig. Width: " +#~ msgstr "原点宽度:" + +#~ msgid "Orig. X: " +#~ msgstr "X 原点:" + +#~ msgid "Set angle to 0 degrees" +#~ msgstr "将角度设置为 0 度" + +#~ msgid "Set angle to 180 degrees" +#~ msgstr "将角度设置为 180 度" + +#~ msgid "Set angle to 270 degrees" +#~ msgstr "将角度设置为 270 度" + +#~ msgid "Start transformation - Ctl+a" +#~ msgstr "开始变换 - Ctl+a" + +#~ msgid "Toggle center given in selection/desktop coordiantes" +#~ msgstr "在选中内容坐标给出的中心和桌面坐标给出的中心间切换" + +#~ msgid "Use alignment during transformation" +#~ msgstr "在变换中对齐" + +#~ msgid "Use center as transformation fixpoint" +#~ msgstr "将中心作为变换的固定点" + +#~ msgid "Y: " +#~ msgstr "Y: " + +#~ msgid "keep aspect" +#~ msgstr "保持比率" + +#~ msgid "lock/unlock horizontal and vertical scale" +#~ msgstr "锁定/解锁水平及垂直缩放" + +#~ msgid "select direction" +#~ msgstr "选择方向" + +#~ msgid "select direction (horizontal/vertical skew)" +#~ msgstr "选择方向 (æ°´å¹³/垂直 扭曲)" + +#~ msgid "select metric for scale" +#~ msgstr "按公制缩放" + +#~ msgid "select metric for values" +#~ msgstr "按公制计值" + +#~ msgid "skew" +#~ msgstr "扭曲" + +#~ msgid "toggle absolute/relative move" +#~ msgstr "切换绝对/相对移动" + +#~ msgid "toggle absolute/relative scale" +#~ msgstr "切换绝对/相对缩放" + +#~ msgid "Change Attribute" +#~ msgstr "改变属性" + +#, fuzzy +#~ msgid "Change Content" +#~ msgstr "绘图上下文" + +#~ msgid "Do you want to delete attribute?" +#~ msgstr "你是否需要删除属性?" + +#~ msgid "Hierarchy" +#~ msgstr "层次" + +#~ msgid "Key" +#~ msgstr "键" + +#~ msgid "Don't save" +#~ msgstr "不保存" + +#, fuzzy +#~ msgid "You can't delete 'id' attribute!" +#~ msgstr "你是否需要删除属性?" + +#, fuzzy +#~ msgid "Do you want to delete attribute %s?" +#~ msgstr "你是否需要删除属性?" + +#, fuzzy +#~ msgid "No" +#~ msgstr "无" + +#, fuzzy +#~ msgid "Do you want to delete element %s?" +#~ msgstr "你是否需要删除属性?" + +#~ msgid "\"" +#~ msgstr "\"" + +#~ msgid "Dup" +#~ msgstr "复制" + +#~ msgid "Empty" +#~ msgstr "空" + +#~ msgid "Exit" +#~ msgstr "退出" + +#~ msgid "Do not use GUI. NB! if exist, should be FIRST argument!" +#~ msgstr "不要使用 GUI。若 NB! 存在,应为第一个参数!" + +#~ msgid "Could not initialize Bonobo" +#~ msgstr "无法初始化 Bonobo" + +#~ msgid "Radial" +#~ msgstr "半径" + +#~ msgid "Choose base unit system for grid" +#~ msgstr "为栅格选择基本单位系统" + +#~ msgid "Choose color for grid" +#~ msgstr "选择栅格颜色" + +#~ msgid "Choose unit system for grid snapping" +#~ msgstr "选择栅格定位单位系统" + +#~ msgid "Choose unit system for guideline snapping" +#~ msgstr "选择指示线定位单位系统" + +#~ msgid "Set maximum distance for grid snapping" +#~ msgstr "设置栅格定位最大距离" + +#~ msgid "Set maximum distance for guideline snapping" +#~ msgstr "设置指示线定位最大距离" + +#~ msgid "Set origin of page coordinate system" +#~ msgstr "设定页坐标系统原点" + +#~ msgid "Choose paper size" +#~ msgstr "选择页面大小" + +#~ msgid "Choose unit system" +#~ msgstr "选择单位系统" + +#~ msgid "Set page height" +#~ msgstr "设定页面高度" + +#~ msgid "Draw ellipse" +#~ msgstr "绘制椭圆" diff --git a/share/.cvsignore b/share/.cvsignore new file mode 100644 index 000000000..3dda72986 --- /dev/null +++ b/share/.cvsignore @@ -0,0 +1,2 @@ +Makefile.in +Makefile diff --git a/share/Makefile.am b/share/Makefile.am new file mode 100644 index 000000000..c77be8161 --- /dev/null +++ b/share/Makefile.am @@ -0,0 +1,22 @@ +SUBDIRS = clipart \ + examples \ + extensions \ + fonts \ + gradients \ + icons \ + keyboards \ + markers \ + palettes \ + patterns \ + screens \ + templates \ + tutorials \ + ui + +## COPY THE REST OF THE FOLDERS TO THE PROPER LOCATION + +## dist-hook: +## mkdir $(distdir)/samples +## cp $(datadir)/samples/*svg $(distdir)/samples +## cp $(datadir)/samples/*png $(distdir)/samples + diff --git a/share/README b/share/README new file mode 100644 index 000000000..0dd74cf49 --- /dev/null +++ b/share/README @@ -0,0 +1,5 @@ +This new folder is part of the Inkscape 0.38 directory reorganization. Please place the appropriate files into this folder. + +Thank You! + +Inkscape Developers diff --git a/share/clipart/.cvsignore b/share/clipart/.cvsignore new file mode 100644 index 000000000..282522db0 --- /dev/null +++ b/share/clipart/.cvsignore @@ -0,0 +1,2 @@ +Makefile +Makefile.in diff --git a/share/clipart/Makefile.am b/share/clipart/Makefile.am new file mode 100644 index 000000000..853a1c84c --- /dev/null +++ b/share/clipart/Makefile.am @@ -0,0 +1,13 @@ + +clipartdir = $(datadir)/inkscape/clipart + +clipart_DATA = \ + README \ + README-ribbon.txt \ + inkscape.logo.svg \ + orav.svg \ + ribbon.svg \ + tux.png \ + tux.svg + +EXTRA_DIST = $(clipart_DATA) diff --git a/share/clipart/README b/share/clipart/README new file mode 100644 index 000000000..91c7f44e7 --- /dev/null +++ b/share/clipart/README @@ -0,0 +1,25 @@ +This directory is for collecting user-supplied clipart for use with +SVG editors such as Inkscape. + +Where possible please organize clipart collections into +topic-oriented sub-directories. For example, "street_signs", +"landscape_symbols", "flowchart_symbols", or "geometric_shapes". + +The the time of submission please send an email containing your email +address, a copyright statement with your real name and the current year, +and the license you permit reuse of the art under. + +We will only include clipart submissions under open source or public +domain licenses. We prefer Public Domain for simplicity, but will take +work under licenses such as Artistic, BSD or LGPL. If you have +questions about the meaning of various licenses, please see +www.open-source.org and www.creativecommons.org. + +If you choose to place your work In the Public Domain, you will need to +fill out a form at the CC site to make it legal: + + http://creativecommons.org/license/publicdomain-2 + +This will generate an RDF receipt that you should include with your +submission. If you submit a package of clipart, you need only include +one copy of the public domain receipt for the whole package. diff --git a/share/clipart/README-ribbon.txt b/share/clipart/README-ribbon.txt new file mode 100644 index 000000000..31c0d2445 --- /dev/null +++ b/share/clipart/README-ribbon.txt @@ -0,0 +1,13 @@ +Date: Sat, 14 Feb 2004 18:01:16 +0000 +From: Johann Myrkraverk Oskarsson +To: inkscape-user@lists.sourceforge.net +Subject: Clipart ribbon + +Hi, + +Here is a clipart ribbon, if anyone wants it. + +Copyright 2004 Johann "Myrkraverk" Oskarsson, no usage restrictions. + +-- +This line is left blank intentionally. diff --git a/share/clipart/inkscape.logo.svg b/share/clipart/inkscape.logo.svg new file mode 100644 index 000000000..755603b11 --- /dev/null +++ b/share/clipart/inkscape.logo.svg @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + diff --git a/share/clipart/orav.svg b/share/clipart/orav.svg new file mode 100644 index 000000000..139cc6ee5 --- /dev/null +++ b/share/clipart/orav.svg @@ -0,0 +1,121 @@ + + +]> + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/share/clipart/ribbon.svg b/share/clipart/ribbon.svg new file mode 100644 index 000000000..dcd536683 --- /dev/null +++ b/share/clipart/ribbon.svg @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + Inkscape Clipart + + + Johann "Myrkraverk" Oskarsson + + + + + + + + + + + diff --git a/share/clipart/tux.png b/share/clipart/tux.png new file mode 100644 index 0000000000000000000000000000000000000000..444033c4231a34c12644022c933aeca27fb4996c GIT binary patch literal 71610 zcmYg%1yEaE7i|dcTHK*X(c%;f?o!&XP>MUnDQ*ew?hY+din|k>V#SKP6)5h(-|heA z&AgdRlF4L}bI(0{@3q%jJ3>oC5f_UR3j_k;Dl5rpgFr~YTO=^J!ZHV`=|Rqf@eM-?O5Hj z%~#t?Gt|^M=lX``-w6)&38t{aGZE_9!^~H9CB=LZG;>PIxe^Q8eJa^~UI}Ji37i>v z>~9N|R5rmdQ23*R)sf?q$PH|lHrvM;DUg|dqYV7(=-Bb-@j$X9E1hB#hfxOQ0F$2| zR3F^*#-6f@=HBBF%CX3kh)FoD1kqO_5|W|9_t19Yx2{UVos(%ZdyaiPsM*l7ZmW@I zCKMxN_Q?rvq`44SG}q78VQp`)Zfju3X#DprN1OW;ZJLNFa*x2VVk7)G+XDN+Ez9Yu zu))|zvFoa|)K-htUsit`(e>S4>kRWotQdR+Um#t%wbj~tu+$*XC=6Q zJMy3&^t{_Iq5D4bxy35a?>e_(@1%JvmdwZ7JN39_H`l6e!OpL3>G=cC^VMRNJf=+_ zNPBt{XF9l0BB_1$t1W8@an;rEvH6yJbza8)a?2NVTEEN5IPoXM)``zX2-$IVdip#v z3`y%SBDwiL8(CS|cVYN+k{7=`Ixo=gZ%&|(m2Jn~PmN0sKI}iJ>C_FcUO_SOrWa7_-KIaKx{=$wIv1a!^sh6cKJ zzj}j+d)kZhw{miFVi__+Z)81e$83&SKU}B_13rJ+gWgR`Jx&|x>*}(3^t>ce5_-4- z)ye3Efj}pogJQXNw|URE@Y@ul+Z3KZ7q@>yLk_#f&@Dr?KU-iWkQyGG={9HXln60d5)U5V<@A6ApY?XGuC5Gj`&cE<&^0Blem{!s zz$K2>7SQZ^>pndk*gR+OTj4$aI(hi@{Im;w+I_Cr68R8Jx;48!=PXI9^OeR>Op5nK z-bd%?;KJl5bSXqP^zO1m>T&6R>(r>TLiH+nXzPKSTsvCgyLLPYP4zmUjg8%XG0?dm zwUWGml0@~(2Xj@3(y=WEtbFrM6R>^iw?flaIVpkOl{`y|GR?C;SJ*;FvS6cB zONq_2pJCSUo#TB6EEgGFTMSfa{cTw%jc zv5g*kr5<`Uw=ZrNKd_e_X*~&xS7fbzeW%Ob@Tz^rX4=yp^&Wm%#PdjGDk+q(ClFbd zeCllp%2F;1j<>Vs6Z(X7b8|B;emNmahZ_j1^jPhn7=E^#hu7gYqjuf+-L{PT9nV3x zg#EXkWxjle&;Iv7g)0ZMeroYQ!0Q=*IvjsG>cy9OFfM(s*Xl)i452)LeE*D=aamlnK93c#uYXPS0F}kKmj?3eB*;D#S6{`C7GMbG1g!D83BNtYYO+oTbKvMk@0qA+cE5fP-49`sXK@C_U&Q z3x1pRe8!)5I|^<8h*p8VI(qdS$^&-jS8Gn_8uh%I(TQ7zK0iv8zkk(lKY=j$3=>eh zyu74O8tSPnPk~#q!W6y*D13`8Dtg%*i@fHxQLKs8Xu(?jv3lk&bfh3Z$GggNS#SR! z0=b&qx3VNQYiQ|0{OFh1iSI^=j-eM7h$Rs;1^?AH(5${8D`)o+?PF?$cIjw_TBu49 z5nl$*?uD0&L0(1%bxCZ0|I5m`gZk#?u9O|D+gxlOV@rpf72l+I(5WoG#AOXSo$sk; zqc+8g(rVXO#j{=^Nkan zK)R_RzLJ_DGDx8&@mnI*_QZ05YSSnnBANWRRRxA+No1hW_MR*ytqU`zyMJLG#>B*w zbOL?8e;%2+6n4B_V_RLB`ga~7>Dk%TqV9+Dr7A^w^M9wGFmN!fLnCBr!u7esa&u{u zM>_TnIKGvXpp5W!k6H`Z{XTFT{q@Vl!GW|v4>x7lWm>R$qm?#s)$+1`V{dP-|HSXa z=VYbL0FkT`=1ZTd(o|ptCs6`q<7IaMnH%oTT&d= z6>8GO>$;7Fs!M^LX+4znhf1cmsn!~+4#eE&XUFGjN9f{>AB}YqQkfMJ#FjNd?IbxA@9fCj zt#8haMkd^RS8g<#9^?D13nn%L5=aJvPaQkdB#{8DJ+1rqO|Y&#w4UH@Vch>(idxG5 zVf6*_n%oZjzXRwGrbUgR`ugqP7ECrr=7m=-RFgGJ^)VA3W?QN}9hcWmmuXx>Iq#La zmECt&CaQ!hm|{)H-?9?C>WfzRCOtAT@_p_Ac)YKg(^(b37DFNqHR<8S;ZsM}9)3?D zN0hrufiH%R6PamdU=~W zY-W(AT^Dkn&E6k|GqGhq5fdWAifwQ}D(u&ObPakj2UnD-sj1C+6<x8C&qNr3|yBsIaAtu#sR*xY1M|^fXdAQIi2jdu#xIum&kOWww#3+McS>zV{2Y zr#~!z><{r5m>SDF=${O$bNX&%x zFVLkyMI?4hq1squA>Anh_De$ga|ZjMaFpPDmRRKRt2aXaAbKKe0m=+bp#H-jg`pS1 zQqZ7s-w~M+N=W8OLNEf{qle9Mw6}Pse&1n8yRz44xFXER0F=J@Zgk9^E5EiJ>9cukkqeN#k^mlR*Rj@ihO5Z7P{OH%Fs zRGbt1Wv-^1DxaDn&5~qdFt_1Fi!|DxS0Os)@$*6)xV5>vNxQcMD6@qyaKZ_?^U9mW zaq7)gk2Sx+Jm2#n4`ueCBi*N^uTQK7FzapxOl6a!&8^F!HJeM@p?2EVWwwlQ$@{~V zn^m8aI+Ip4p;}TQs&LJ%l-c-ce-EyASY5p8d#%4xEoA0mJXyZhw)b_KBK$oM({^u< z%-!v!E{1jF9hTJ4PbMp!{pN^-VQs^ZfPJ8hk=FZpfu8jIJO6-Z5 zx287dzS<5lX`6GkHn@ILy|(;0AO1Lo2kWg`>tWVMbs*Jkf9te(VrlZytIv6W zO=h=M{m9L?SJ0jR);&)M37NNAZ&%nQB9cfwD)@w=j`fai{EU2Vchc5q(cZ!DqN?Cp zoc1%0cxwqI%#Ysw{QUjq4gL0iNd#5EkWN$2T+K?dF|Zw0GgsWt#`?>cc})Naodzvc zJT$34{)@=FuJd!3n)k1`z+LXk&+yx>aJ&~Zl$4pYbaZP>MRw5Rc|1Fe#zEoIC4yKw zDSsmb2c=q4>^^b+k3JjE@t#AY&XTg7AG`QAc1-qjsKtMoF?rVaWbpAJ7>BVfrbv z+??r9p(M3`IQ=B=hYoR-?R^AF`U{DFEyj|@&KmbJ_p#;7bLx1&meLAaUZYlRYQYho zq=UXVcZ?Oau#GMePfTM{MV7^Le-xQw@Avy=s0>x4S3cMj*?{=50Ik|Ap!-!Hybf8Ra)6RKzmfH$>vh2kO5m z|IHe0ceqlrT(n$-K0VxiVr;B|*Ym#YQCcsW>~r1}p9o;#qJ|dtH%yQdsU_c$n)qHG zD;&2T>8M1o=6Y@#aAACEerQsCoSS-xZs^JJ9=ZyxN?}>RUc-=>HItf6|54I!11{XB zgb-09K60VpiScRBfIxrTP8n@!qg$el^WDx&)EA4B3>cJI~ z7MqPdg2{jP?7402@tC!@`RMJ_r;aB_YchKEf-F>F*|Y|8@7$6c5$Db8%hpcHLJ+5{ zEQ=Xq(rc4+mf+vUnQv-aIBRdgdJz4ISOa*cgJK}6qG+*qDi-cx3i`J2T)6chT1g!aJax)DOI?YWs`U!YJ6%& z&feDfl&3z={nF(x6j%{xpHbXC44E$X;7iv=Jtc^QGG6;D98S06!ef&;aB=ZPKteD^ zuR|jybnHh1*`B%FHcL6;Zze`>r(RMcY9Qn_=*I_J{i>x?as15Uv(r=FHZTtZ1&+ipyU((LusD z@iKRJzu2a=h6nUXSDD=;^GzTXHbYdlv%#23Mv zjCDFZlqB+ecd(6SFs3j?pTeEh@MGq4!$hieR5COe{^IYMo@?@9NTNi4Lmz8O8|ms% zuI-T8Nbp!AKgCI_!*8VeaQQF4zmfBWsWe9adaF$whZJu?A9GVkRU7Ke=M-S!suveg_D69uZH?Egn;D{AU&bXoZVWtDu6jOj zKOen+{uGOHusu?bT_qT!lJ%$W#eu*JRsPzXQ4L8gJq6dz$)QyTSLH~}r&!_9?+FLm z`MRTDYTkqSjhApax&E7P%=yFB&JEPzd0w38=;+haQ*M#i-s?kf&qD7otuOO8`LJU9 zp-^;2Qvq0@(zc6NEH~(Ae?K5u$BN%$#f?WJPqLq<{S>_Fxg|b# zfcx7nk4K*zo!{&RxExAK0IGfeaFCsxv6sGC3E?A7$^rYX%{9Keb-cQ(dg&9!Y$~?r zuJW6!s-BkfSJhIz?TlZYXKZ^xAGe)IK0K~HOXT|B*}N}v zLy?Bv-lCfGeQe~!270Kmkp#;N_;HM;6?d_L0fkZ^k|OCWTDTDt_J9C2}p7e@P5McTh4)j0jKSsgup$c&l_*jf3*Kd z+H-|PTuib0kW|BI&PNK$*XL%)8<(BK6~Emk{{H^6uAyGwyQ;S=d0{NQ2C=7xU4oB? z8tz(I7Li;ZpO#9WnjT5%Db{Q#C%GkJG%4-H9x&eQ&u~36!ySCTdp>v{N`3h=x*?E6 zK;`wNg_BOqodf_*JVy(4Ry*I1TuOuOxX~F<;-U{_jEv}jjy7ea!}CwZRPZ7f;uH&|KeGf9Hc}*k9jDx1SgPd(ND#vc_XJ7OWofEkvhK>C&NM=-s!1O?BzAi zWZ@jyjJ8PJMYr3djFgaIE<)j#ofBNG^AVOrbmPZsM*{So$PZQ3_a43?tBjoQ!W{H? zacE+<8fSQ3R&DNciA?IGerkDm7qjs73T}aGEa9(~$v0Z2NpCY~#g(zLUP$rc@mS%H zp1+}MDX}hAIIt_mx z2$BX8_>=cGd!7-A&js0wZ4}WkY&G+&OiiQ*AU@rtTAXn;MQ^Nk2Z{4e#Qlqw3oqd4 z{Iaau_{oC;L7AQ~$t2yC+pE$`?N7DnZnPJm#05qBc6I@A#5y)McHZ*EYQf-#R(_Wu zh#c}Dl;7x8i&nlaKpCSZM(0_U{OtbYxoj5H`u4j))y%I`ch8l(w?_!p{Uxs8!u=Wb z@g=;f*5MSEX${Lek z9Z#FqfIk%wEtPHobr8^WF$cp=yqu`fWk3=V^6igDj^8-=rYsbZW?~N+E^0WW}VPP@>%9M*J z-W}K!hT99PTnmVZz|_;%H5PH3Z(Qnm{?Wp<1mm~^Vq{?8`h2y+XJYBopMU@cN(u@E zC{)VZTP1tUQfXRXRv;%h-#RBiVw_2Rdf`GGD-aZF0?YVV3aj72I%w7K^LrF=MPQ7L z@zlPnc$*J{pejE$mr}jldUqa8wD0+NHFx89^}kf0`i?CkorGkg=^gXfx`QXP&0@%O zw8r_7K!@siJMA^oTW49yE&1Wr+W2_1;%ex4)a#RzZx2_* zhX2)@6z`w4oEQur=LF@>bu2(#v0J82)p-E*G=qk&JMD^)2Ku{~K!!bAUkCkdpyY69 zkV;i_)_ED5G+HOuyfgEc%iw9L2*?nW)dq3N!3|Ecn=OX4R7D?o#?`Cyh%^bhLbBz3 zt`7&gx(ke*i zp%ZFV30Jqbr;PHqj$rsQbtN z4+7_@#?~AqM20qV_U`TXUDWi<%$^8ho-bls1!)#Y+%@45QB8Mnb}h>j>9#}}jKNr%-UOzwmXeaN;P3}AC&|2TH=Q>f4`k14I&aGayL3ed#8OdFq@y7Q zG;ZqCI4f~3834%&9D5mpFf&Ph$hMbc-W#__TCZ(eL>Lr-o-GBVNZprp!!=AG2n7!0@PJ0q7tbmB1?86WWijr*V2qQXBIqB;!a zB|DKQ*0>nX1UBm3I+onQH^Iz#HlvH|lS6AtuO@%(ShI5AmQZ;e^&B0psNFNw_ciVIr-Y15I{I;1mVlbzRJftpO93W>C$v{+;wLh=V`yr{I ziuhbpOI%L$B9`EfpY%J$W9Tugot!}E_{WMYN&P7tI;T54(2Nppqhh0nJ)VDwrNAZ; zDU^UHC@2V!pu`Ye0e&K1{@_r?ytw7yerwCRkh#Kss}zxUc{!~q<#ae-lTy~(^uH_5 zYsH?xd_&>Xk^c!=POL86XkYu7tTrbQ5fFeB9UJ?#qy&958pvu7S4L8S@Vhejz-AA4 zc!vl;1@Ys%&ew+@eRnvXDP%C7y3kjFI28ShGO@O%*|h4-k?VaPQO2aS-m6n!7+O%L z9a*T`5}Or5U`~!EpdM6ggF$xRBXLKM!RuoY3%_otnw*0_v9Yk085vPz7E5E$XEjuNoX}E>IDvpznXDH3W0f{h>%I=u z3*2Go^t$&fG~uv6-D}23Try%h){@_5I@k70CG=Zv9r3Z{0$nM3eYs^_VXV;whMH8FR#U$*kesT zvf$CY`6+`n>lWi?5L9WKpq8pFqtg8w2OCV$YHl#sB8t4u!h;5yySfFGtPp^@qVse) z=PNs{Mq+`Hk&(R?6&)HK1!B4P@n&sYLPFx!Sth;I^tWUs%9B6;Ob#)r^+@RS>FtIb=XtOC;-$c{@yWIyc`Zct(PEIkTEs7B3;=NE=iQP`LBW@}&h zt$t|}pd=h`b4)BRgZ&Y`Tfnc5zXcGbrY1g(h!c!ukmujsb^HCfft=^78jGx1)3OXQ zGBUuQo8ERs_}YAI3hy7ZVM|cJ#>U>M(Eo=L*Q&Durf}431j>4rsPqo4Gg;_?l7BBC zDyqz?k)8j!p)pXm^!*+X^8ykQxC|IT4Ui!K&@rZds{r1NZ_U6BGI=QG2w#B>W%(b) zHxd%4hpQdfJ~y!@&rgpc-j{3&iZ_f|W3UWD6pmeV5GY;Nu&VtW%h2}>^?ljQe;*K? zaU*FZPQbpYsi_(J`_t~Y0LMIA((lz@Q&L3W|MLQLeL&b`hIV&L#)#p4mO?^ zfXKyb_dYy`8$ut&Gnu%NVO!1Vxw!*4XJTK2zR(s^)KpT?k{ zRsSOIp00oq2&-Mdp$e7GuuH9Lp%!4@@RCf{<~R@UiIURHdDFkOMa*U6{L_-_ec6jQ zZhuL_&_j~7{vP!%FN4bUsFtYH0_!5&zksH7Yin!1 z&4ULJUbu}qflQ@(`UuKo(XpFw%fSlyuf)TRaxu|CI#aCrRaKMe|8l(xn{`R<*DS+& zgGF!eCF{E+{k?Dw>hWdwfdMkH)&?{Fqqz5RTHn@2aptZ7`Zrd=lmUgRRgM4!qo>O9 z=NALR^gP)X{Xm;c{nGb9-QJ54{?*%PkJj@khsUt}XXOf{!$HxdON9`VRlkcVu+sMD z?uDG3e%0LmPMXoCY#5#i(5CL~v&&2iXsgt0iEOhr5+lW*ppTBeFB8;dSLj#;RfE=U z!o%mC^#LXv(TV=`)Qq7hJw3zh2^v+USuvMdRDs;Ll}IBq!f4zszPaPVKLQm4Xgss- zY44=^T(-{IdA!-b-LoA0Hcona!s5c2q?#uK{)N%TqcCl($&uFpWbpIr5Ri1}sma;v zr9k6wv7-Xy5;l@Z^Ceui7x|Oc)%I;#k*@^>L;k69By1t{TGoxky;k`F zPZzvL;6Z%5b2HfA z$g>Rz&m!Jg6z>>t9)0d11!x8B=XY@^pGLw3G6fZS-#^4?BsnN7q8%E&C`b;pUjk%; z(a~a?w>4U@-R5xIP7=0!y(VB;xQqdM6=;?U7rperK@-28hp%rBr4@9`LJ8R{BV0mZ zHm^hiVCP6Y1WtZ*NaCi~Z%t6YgLEqOyF;+afNu6JiZmp%n903bNtLwz{-~7}1ewD% zultC>AQJmEIZzublVwAsbfIlnN+lsl?Q>Qm>IfV#D%`Q+Dn%yp?V)DY3Hg zYSE6|LJ5c)KIfxm71xC8zcO)kCHW!B9}an){{V`L8gV*8)8~N@d_N7!$q(Gkr5WU3 zd&G*x8C_3pLM2~$`SvF`6QwpZ_D9Kjoy-TU-_#MUBj1HcxHXmAC3m_@4f^({t2VEf z92Hyi9gb-)1;!c6jV0)d`sU}!ab%6WdNtWY?U%mK*EcpH6om zvYWeGJ2T6tnJ2f-{6i<xyTow4o%|}O` ze@ja~a36%ry54F!BJI_{!;0SV7>gLm@59t(J5b7W=s7S0u;07F>_VssDRD562#`bR zt%)YStasLSReZx~a>q{RKgT6Zw0(I+5)D%I+C9c$sr#YB0BlOosqDz#oq| zj5tHFLxe0XD}xo&yjCM0ZC#GA7OU*4P=yN~gbm#F!>(j9@o45io59NMSFfsH6f059 zn3!ExsjwE2{MjXQ+UW6GcAGQ!x#I#<8gj`?e!793Qg*fR(ehSp)wHevlYqQ-o%I#P z&wGMYT6pV}C`A|_Ag9b-Z{p8Dq$nk&d2}G`sNj|sP%PIvnp`Gc^byM?9$UNpcdR8J z>XE7(nEeyEgP48~|M=zB)b@{$kVSu%qopQ%y2m|59St0`p6M{#2FiaKacBrrH+5!N zbnn4sJO)Pf=_!lJho3<`>_4)g`lYYB2l5g16%ov9?jkvj?-w`R66bKs8yf1Aubb>p z`S`hbc(!JAjCNFt0<}wnU0Q+Nk5TEywQ!p)X2PqcSGBJ;pBzv@BIc+yaqPE1|A?aGC7yAe20(f|7`x5G41rA zc-r}x|2J;-7A}sOodsHOSUM6}ZF0ncUqSuRZq}eYl>_{~QtKHRHbC{IoSx=)>Uq&+ zZRbDx$1Ho3@v32+>p^vs&Nz zoV%G1X^^}<0#sYADL&wWsnI^7%%cTR(`ONj@R1tZr8`+@^lFbOwvbdiV1-g>M}dA~ zpf|+^Dn94*jkkZ=T+&2;(9}c~aSkwPtN3=a(Tl!c2fzA+h{$_T-fN{@_|;ieU0)9r zFJQV&(j2lmfuTFn)?CHU6NslTIr5wJjWt9hF4`iZ10` z7Sndk{{jn^!m!QXRSAZ1HfJ+Tq4eO3hNn}rG-mdiseP@+_(%|+q!0T38y%$)mcg(` z5ud_9{u_Dx-QgJ@CMF5az?1mddUZZNJneLueO+vvBb(OB5JzE8@p&w6V~g(DV%hH| zXKX33Cz2%C3Ou#B$!O?*YmxoNt=9f!On=i7mj2Kb%FZwxfzj+X0_V32xdSx592CdK zvn=^(+_(m7hr-7I)6r3`&CC61&$+f$`CDJw%;H{N*YC#VOK3^`s-=EAy^!3UTZ8BlE6q${Bz*92|3Czebx=qH!@0Q8*P~(c_;b;8_9r| zN@gfX-$2E=9~Vpay`=6=Y7u(``|tU<@Q# zaz8VJ?LsGoe>#yqTwVi{R+A` zG7cF8fhE}j;v~ia|D*>a6QHO&`WLavd;aF-mwf}`Ow~nD zsv~ez8O(@$3XM})ZH)Kd{ko)Cr_xL#Hg?LEe4C*%(UeWTd*hFK6Y^6+4APSs<yg-?c%eHACB`wD~Z9cy}b2Ke`1TJ*VMP{s)3FzUs>;Eh8snw$=Pg70d<#mc;{{jF$3;Bssh zSt1mq+;O`-6ozzxxOE$lhAR}G z@9jOcB6SwxF40yoONN*aQ~&(=bJxlqm-XL2A}>lrda+Tqr1>Y*V7yUaw3K zq&{d~B!x78AphstkN{}?q=&}Ok7UY0n~?)sv)Td?bCqO&2Y6H{DK^~nNIt46=phvj z&2!$H=}t<4K@5-}iFK$C)rO)&%H9dXur*euxiw`zCIkyYjAH;p?V13|5@1UAfs)X= zK=T+BRA}qB1vq%*g~UjS4CfeWNN!+(;(T@Rt7JDhxnRq>RD|h@pso%UmZgu%I1rkLD`r3vykO%(uSfx(@p|6c|V##P13r$tc7lRk$$KFhvXSO2}XVd7-MgRcnu`1blp51{%epMj0J;q!lbj z250~+wZkRu!^rWg%)ob9TaeH6NydNlNut(Q{2<+oq`x!q$J#f|pZffpMid>c$$ZZ? z`zLR2Z&x)eoPoxt?KhP0ijz=oW7|la3%82ckFVlWyF20_C9fDtIX+e|h2>(`t%^0_ zgz0LBUyzKNk*LfRUl8On*Rqo4D=-& zi$S>*htQQVm3f9<>4*t~5bvuwGBrUBp$1W=M|ctz#w+?jdaS?+^3pI{ENTLDS_WeQ zO1Y#ok{rn)*Nt*n;zXEruRh?gaz%8T11Kaw5<{1W+uKSR^ie(Dj0DTd>p zpef_V_Yr_OQR!dm5(l~}7uvvzkpjC42?MQjSu%|frIz2~`*0xBn9LFMllph87&f)P zNrF_=YC%dY3_RdrvkxyAY0>*c(m&&Tpl9!umt>GF>RCqCMJn$KP~5(!ZjN5$bK1ux z9hTdr?*mHy4QsBJ$c;=g&8E@nW^TjV+cv?U`bKMuqFsGAl!LY z;Q8b@bG|nGKiXh9OnD^O9jl%=Q7Gs0E>pwS9JlOjV%m0I@!(ah6t|?xh?M~C{?*&Y zbV0NL3~jJBuPu=|W#8AU4-VSK*|MksOx(TrB&+qF1ZT~1G;U3nqN{88v^MPP9ZGp$?(OsXS%61d(Jo0L z%vl_MDvc~YO&jy!m!-}8j7A@SRoyursn3rv{+F^n$Q@ls_Lha zP!U(NwT4AH)Ed6b*MaoLX{DmLXxKpR(w#<9M-R?-+IAHB2*Sa{vqE3bZ{dJhwz6dT zL`(8xY@FvMYrPr|=HySujEqRl;6*ZSTzG-WLWJ{Sbh#Zl{=W;}o>R3GdJxZ8fF``> zp{EXsM-!dAov>Fa)$LU3K_b7bZpf0zzk+Z_rh((zhWR8n`|ZI9x_G> zkksAYH@Y)FBZr3bHSQ}TW~QZX$`>6KwR0*|akf@!!b0^U(GJ$aroCKE%PyUQ87;>s z&FxCf+Qj-ENO>6LNZQEQG@Q7hBpfIA@pMid=s#n&PUDkAGP6?uB z;8u+ZLDLve;#evc(px-xYC>m2_^k44bX?qt*FS5iI>)#A z^Omv@nWVhcYq@ z6{1Ie`Z6C3LW2ZCSfoFj7O7*fBMn0^z-1t959wk2L3IX*Gze8@9eFrT0aeB?mmXjluU`-new} zDR?qBml1H3gs-&SNP1USA}9^ z@0gluu}9lx>x(H%(Nrw)aq7=5)5#-x~p7T6d` zh)sW5XUxBA4t6TB!N{*1Urvt^2}(zKMNo_M{m-H_0p8@O8g;N3`YYoPSjKsi-vOr> z+T~x-kYPrqssJBsh!O2iJsg9y!UT{q9S27kj#G21;wWqyWT*HV6MqJ63n7X-p3C$@ zXfYQwxfyxw$YML;nnJO-(Zs6ZT_C=Dn|ZCdE2sGY>j|1=|QQKPY*9 zYMHi`)$tVNKAlj{6=JTpEc}s!>uJtjFB_=-Ht$PPerqhTt;{#Sz5h3T4c z&z<8Z_eeZkTuBG5$wTJWc6QOnKI=&SyJBk*5vaSiSkKB6wYd+*T|HV9aLe!|vmjmd$5iT#bNAli?G zV94AE#)G^yB?diOkZysf1bRAVXW6H829dgZ$R1rU4?M+4uS}x)j@&w+h7_Xi% zm52mSnxJ=Y9yr;);N)QwhX&gGt?hbxJ#cI&Q;Lx&kJJk;B!GbkNxOfLNoz4N{2}xl z8<7xgS5|6?RzMbzs;cItGj`6jZluhwRg14gSC&KelF`ha$U@&y4>bYHAQOr#vl47* z8(p&S+|uvx`3ggrP7Ahqvo~K`w=5}J`V{O3Rnt2?6HGp6BLiZi?uC#!H0AN_ssQE2 zOGZG##i$~-GOrVT2`T@Gs!q+>RC-DAda)G8d*V2j9Fd8KAg$V=@!wl^NPLy za9*x*q?|e?^;K6-`DO@K5^BFZlP{7pFO$eS^I9Cs5#Xt7qARfH8pYHUMjmOv^YB0p zx|LjSHpYWEREITm5+)*h)LE|J_r6N1>Pln|K&Jf(J8ru%)Nl7p$n!ZCJr{>tpb_ju z*o*ycXA8N%zh}=IudAezlhcaSofE7rH6MGkfC32YIJieWU0oJG-v6*}1&<(ga}ob03?~w1WnE4PiZzKsmbRdj2$AAX4jg(%e;Fgbd zNr;$!eSzrxRY3x*Bv8xv%Uc2#MK~s?4h&FpL)CHTFTN0fa`9{Z0uOj~dHB6!6I!0( zLDgtT880<4x4)3edl`S6Ray1w#Kv2ATcax{X=GgkH=tc`N8bIFBU_`}x4upwa;P=W z+j9^V*$BDsZs+!GQQnfI?58%1*%? zPt}U;7xv7d;7?~qc1qLV*y|*|8Hrul7WsgRxAPr`h~bhaH<^@+($4+Bd#j_L)h}AzFDP zAY5126);@Lp)dmSDluUaLAkAhIWO6{S2W=4WHGBT+50_;uCa|Ra@t(WI}Yqd_vomA zU0e5t1v`uQxW%9|@9WpyfcUFl_TNyvj?K5-VTv#i^cFY=MQ3McE5ddEE0Cf@qD zh6)F5{h&N4cu)_!ubOgxo}uAmkbZ41$Sxp3>K*N>d{^ZXxyOukk_E zWW1EQU-iZYfC?!-&NTi7DcJGHqI-~))$ZB(2#=Y!H%sQzJ4Q!QmnOh`{sfGJ>p-6^ zQ=z~nw4?yFvJGjg<3DkxC+PL6#Qap*539#@o3Ujc?5Sc}~Y)K2QOi`wnPc`%(5h?Tb^UR_<;#bHvNRD`Pb<=pQ&YuzvA^F3-JP%phXZvezQA3OEY6$U!7Z z7HRQ`$({tr*}HO~^CEIB(*e67c0v+qJ@z~n#J`j=w~}x)FuSRNCi4H#be2(7bzc|1 zgn)pAfLuDIq(kWr0Z9pIknZm8kQPB2=>|c%Lpr5PTDm*$yLtZO{o)vWkjuH}oW1v& zYtG*?q2UV~-*G~L5E+`C{o_GLV(Yd4fQDAU6G7R!*6wrL(@}E$1$GU?iY4!dka9tl zhoJ6+>$6{_ZupjOFr0ZwFuEZ2X^L&j>xRA2e~LcR{%o8#{TC-DLWKjTVN68^yYBT} z-P42JJ|ZAvEM5hg!3tzy6#~etBS*_!?_P}zUEgmB`BF`nD?52vmFQKLAzN%CPfwbUl;wx84IoLnKP^Im#jAtZPI8j;QOu+ zf|SG!pqs8N@GnSnKa;BJA`jsQx>8ePem_ z(w8@QW*+I@^{S=e?x@Xoc?sCuafB`3BykwolRfy5xo31a3yd8n2=LD!poFbMdpO7D zZ$4X{nA+d_3-u<`lKr+wq2l}c8S7=$cQzE1a?@!eLzLq*;u7zMiv_Zc_iykIL^H9U zF-JDxNt?1XHvK*$AOxLJ2gV~n2ZhpiyPWf%I>MX&<%138L*r2o+!YX}yi zAn+SBF3}V7xe!ao>t7u%%>rPw5a@ zC!X>X)hwQKgNOWk-9j`rLC>I4iIWW%YngJ_^|t!_u#dD@MfoKm3Z3g-i7?<24E>!t zU{s9K40VC98f)|vS*80&R-%eF!ewk>=gA5m+M6zL*`;c&_?*e7Js!foxK)bV3$2P| z_MbuHG85yN+&+7cvLBNp_4%Eme=x!d!O&iYBgDtDZH;bWdKVjByPKk*Zx>0!&y51F zpynzhj4LtQ?9P!*mraLCKrSAq0O1}buumgL;pdM2;nFm$k!Y~oI=HPd>hVhGex=R8 zo=pU)xC)NSId|D~gmHB!Ij=DUYFxswvtLV&kOgdV2bW3B8?Q4jyoDZpYG89AF?UEA zw~t4}f?jSxjD@W+p3`4^->z=Lf9vX9RqDl=$}8zC>?w;E+se7meAqYDJG}({H=VWD zA=kJsATRr&5!qPyI={YN>iF=0pe||-l4q-edj^i9JOqvgVl434uh}ew@C>R}l;~%4e%u7W^%zZI?cxrlzVF5~RqsT#nZRN>1k=1h%)LLDU)oA>#1+TEa zOgIW!`15UM_YA2X=;^&5;V=z&X;YGuDG2VdJ6Wkm9i@A!pv?Bfp+<)s$NV#`vey8> zLE^F2hm*h&Gu^-K$2_CKCC|mYJAs`r^+{867ab{ZC78u)b!j=~(zo#fMn>ojafbhL zu~x#j;ADyevjScqw2Jz*2w(T(4&+RFLvJSYLvE12#QOO0WBpEk>T%;t%d6D4!vV=W z(l1~3d+5o}%mp)rOCHYMbohTNf8K-Du zMbGNzjC>w7HMNriTVEpIOH)rhy-&b=zl=Bz9TiY$nFv$8F29G5%zMIr~ zo@aWr+y*03FuwC;IYgd6eFBp5Q6T z*RALc^vSH!uJ{u#HwqCBLFeFj9xRM*60!chgXe?8=OA&Db+((-zBBJccDf@uaScoe zw{c8Z7>Q@W_eg`~GigL0>^e=RQ}4{wVVacTus)j_X}oQEer6i@?9K`mpEcTOet)6H z2bbG+x3xflw7hfLcMl)padMsb9a$_`twB$Vc zyVW~MDF?g5p7^_RjoNN;?c-a*auPxGoX#U_ThE0fU|Moh0Th5{QSL{)5K5wV*sQ+NJ!pqFREJglCu#;6B zie$!_f)W5}J?c8+5Bh;g`TC0X>z>LOqSzKU2JgXJd14`dK-R#Ll^s-jtYn*qX%l0k zs_g=k!^Du4?r{MA{lSeDtRQEC{R2O$_9OG%H|embk+;s3J$V&f1zp?0-n_*4;KSx&|3oJ+I4PFRZy!oeQjUnDLUauT>aXo}3H6UWGI zrXDSRI|FUo^-L#&D5jX$5f>a^uM0h{!!CY=k~Us@)xaiNV5#=c%47&=;Yvc(O?w+< zh?9Jjf5&{$`}_AhV#U1M*VBdfpxSx&WL~-S6$Alvd?_XIba^x%TnbbH7s+>!K1YH5 zmW^b$xj|j|g*sbW!w}wspnKOoXC2N|xm~AuU^wnOLufxt=J@`HlVW^|Y8gGmJ~B(| zl<2G+ljD1&A-QM^5?896MUCd9)!T6p&@|&LoU?Msp_mlLx^{tL&RH+rirM!o)m`?T zUQjub?+_j}VgRRAOvc^fo_)u&1@KX2p{M%g8280`7wIKFoK~!qe*6ZhW>2@Lwyx#i zs_Mgs^2hos-yD>rxN=l%&QgZ=P}&Q|E~pg4)TRdh+Y#TF&C->-guB{A$C~wZHVJwh$!n$Y;eNL1V(hqeYp8IS0R*P5yJDYApt)yS(QA(-L02;gGt^Y3o zlO8c{t>T-S4bD$}{Ru^SYbD?6>S}JMZI8cgFbA8rsdgj?*<5vq1YGTJmZ3O3d6yfE z>NeugT!1eztn&h8XWNOVHH<9y(RLu15V?|fVKPq%CT(6^ZNZ~MvcqmeQx;eg$LV|s zuI*`097|ok{|7^YL`i~@K8T!ljdNHyS}XQZY2^%0eSZtT^*ERxxVe|F+8F~Fs@|;= z_fquQuW(~@vSzVHj#<5(t25nqZhqrI-XNJ^Qq&@ACRXO_9zDisgp#pGVZn*TMTpXc z1s?R&;aAy(B4uhg!zKtKD+_S_`|ivGB}F9SpF1PPnd;GPJ`=chi=(fKp@{!R9fsH^ zZt9!tFEu5Vw>@IjS}zQ=n$Du1{JNQSh;FPBQopCo?>~(z(`ddZvwaxVNaPVZeDICZ zJZ3nZI*y7L+lx~){`56gj|FCLP7`Oa*P#h|R?EJy)>PZpn~Ew%M>ujhj`KV3-K)Fp ztGfhh`n(34JD%BAL%x=636^|-qv>+i0Y2Xu=UEKKJ66cg#ZB%W)D2M!&J>3!wQO{0 z9TIpe?@-LS(7~>5dvpndAd`|{`GP=jJOh`iS@x=C!CG7iWz@t7~)HX5RgUGAB@oZQJ-hO2;%$Byo4U~DN@P-BOdO+7=A5dHA?ezC_^ zkiyWpdD2v8d>8N9=#i&~Mc4iAD}!QW9hvRl#lvjU@b6w_;D{n6U$SB`n-f4+a7(BW`TsUjMzujXQr7L?Y}+w#E@m z^~-VCyennH4}3}N`E(39Ik_KG76#nMRBjov8C$z*21@hn1WG*>|Gc|aqu1N7Hp|;b z(wjiVF{9tO5DdTw4ayXjDOvx#wNvKnU(3olJ%wyQ7^lwVf%^*P2nq>%XZMWMnU+Im z-`gi}2@7uKs#V%nRrU!RI*?kxrFSy}k`_9mZgcG;k ze|2J{ucK)RUcH0UJa`MfW|h7I+S_cppgrEIm(YiIHR(r1cIA711lI%VtpQZa0s)N6 zpXOTCX*Y3NqGG_lS+3r)t4j9RYIHBQJxz>A_|7qs>Pt_sLQ2%`8b6*L&2OI6`$?Fb zt;YnJ_XZW2JD$^X0)a!>aCAkP_yiPjj#Lx7hl|kTv@QNn_!8ld>xmi4K4Q2|rsNTX zlLzt!KpXqGL~p@K=rVQLccD$W`6!DOE?mB)lrxuo=#->cMgyLUT_;|!85ux@>9FU- zoWxPyDL=dX@duW2#lD+YHTkXVRvyv^4P|cHXV-Q=X81MFG{)0eG;JvNNlpjt#1jDG z9`;FG7f&L{W**xlDcyX2HiH>^DXS{Q9zD-3u{9>$i7 z1}l#_q61r!4s$>;@EaU`LJSp-u;KRl&HGSijI_pZ_l2P$+ZP@Q)NEIG-re>AjDx7H zX~K2__zp|&{I+hkop_J=@iVrlBH&Xq{nx(-SSU3Q$|-g_8;zMy75X;tM_jRQRoo7TBi11ExjMAp3V!q%Ks zjmu61b(a+ipNmzmtlsSex1GL_*RnAsUfK@2(1*^_HznuRcQ2ATh_MJT;4=xMP#zv3 z4?Zy-ErPcXtu}+;m~(do@(w@@=z+eBYN5Nf`J^P^7eEqMW#Mi9SY=FukjT`ULL6bG zgjBWQ#`~O(QR}tg;1PF_WqB(S_&Z+S!X6JO&OK@(ghHM(wacW>{I0O1lCUs($qk55 z`%f|n%)XbzwON!29aewtTRq;_Y#JvrA z+#a|wF{#7g7?I!deIi#fM>wj z+CQNU-VXAFEBKs#Wx0D|Zz9QS5{BLm0W9JwA+IZ6Tt(2dZ4uWS+C_p)J?7u?z!sy$gGewAX;tK$l5|2uIwzEhBV_a@fT%yCSApvxP8ou|_K$aC1{O`*WQV!l@*y zDmN=hSj$UL>R+^lAfLv~=DHsB&gb!@m#ocBCrb$ap)D3pMLL4l_XQDt0pVNvzcB^>?g4gnZ3symWC1P=LG*>B%pnXXb>B!`4WK^v7@50$6_CG9KyWPO)1oB^X%e-k0y4o}c3$ zE&K8))THk74TVVV*4DO;o)DnP&J(z8{|IIFdD7=yK>{N6PU#3n^)7qBM&M;WaY2d? z6}6I1N>uFD)Gs1$GUSrm$8y(}y#qkC^nGm0`ov|#HhI~r=}_(V@1M!Z8H+DZ0C`r2 zK4kQ4>jUB?yAUSr zv#K5O(~%)oq%gypZp%*tB}rdCA#8FRzvMVTQqe&VG9)KP(8#!lb{cM!&3O&#m--{BZ8Za?H*q8i z&v*%u*(=dr@}Yb0UH}xUG5TqWL^Or#+3SW6XjHBjp%?v?tF_VZ?N#|XS^6T%FN#YF z62G7h0%LC1Oi*uMR`lFG*%Y4V9}B%1krIS7n(i9A zkh!PejF9IbQ=J!Qv>{BY43^3+>YO0V)qJZvl1r?MZ>#Ngk&LSr^^O^4p}W3D3by1! zkjupvs;#dFRN(}dW5=D2de`-5+aH{NI&R5>D#pc*b)gzY9MYOc1HtvY>)KROcdBYc z3~^WF@g2UhsdJ zE1XYR2opV9L^{-M$#=MQ>ruS|H%-y1(QDt2`fYFGNEFcLnGcw!yyU<~_KByaKb^02 zCRKt`j)=6%LUW%DNuyXbBczGlgcGxxUOz!|IV#+TEg!c+1FGKl0l0E!Of6wa+AdAZrI6A9-ygwa3hjHr+<{ z7>BnvQB*(({YYD1`sjO>y4-y3>a*qQL)I8HC!k+?z`g#yzti{ZAJg}g-OuLk!N?D! zuU?I0&FtB?2?-PTf&vpM5Yav3V@9v62=&w8k!fJC#FYW}ML_`gZe^XOr*Ni*i z%=^|aokY7fufwhv0k8G5mU&m0Le68w2-BzPJ#6U&U?_7;B8Q9?{!uxHHF7zcv&%&14Hni`QKD5i$YNI}_~E1EFl$p+%9n_kFzh z7U94d=)YibPz|z=RN3@^SnBg@+(k>v8=N@kkrdZa7XJUtN2CT z#-x54!Rw)ZSwie`2e!0J1=zWQkWz%IPf z3q_7m3GIw6;S9``MvT)m4aV(=iMt!dCI@|_cxs7^Ezq+9FKrcLNn#A#oRq>u(7K!O zLn~&l{bV6BfnhsikCgEOlR8>^Usb7!6glM@<6zdRd&bw;J@kKR>S{(=P35xo{J)M0 z9%x1#WhQdJkDaE)<$t#RWcNXd0Re#=v;?;ZI$7a4)&URb{GG4kyEQkzDI-W0>p4&K zVrKWuOmI|A(~PG(1IG1Jw9yKY9e-}a@`kxqGJ1YQF)+cKCaXg}cFvvq=b$KH}JU)}7MRQ%X0Z^9^$ zPv4lDBK7O2m#(*|oGv?bX4D~h_S658w!K&iRsskYsX`As;BJE=@6RZ|&aE$Az83x` zA2NJF`r-QHi`JQS+qbs@{YOu&y3sTqj%Sg@;nQ?nN6tQGoF5^@-v93fpoA!{C$sj< zA_xmsF@9tx`GQp?Agv7OOHeVZNCX1}l#H#PdyVt@=qP06(^jR?f|uTykfP(ry9dFr zSxvmR`**EV08KOg!c*(RJ?JoH*(VkdM6u!7Geo(K z%Ru43&Q08F-|@1Ni;H;~9O(>32+-qhx7ZH42nDgy?l}x^d9Kj|Q?{{@8_W{~~-eTlVgt^KVkW(=~@+b;*pqMvt`b;$=ye za{)o(8im9;QQ2XW+~G%_Koe*^Qo;@1XpH_2rCODVWV1`_B*&G3*%2FRd?ha5gCxed z61RLtcgwIuw!tt&kEf>KtAt~%Vx$sAvPcZS4@B>X6-mhxkM*zE?XAJ)w8;Ps@LBe@ zXPzt#K>&pi4tS|)K`%c|Fhhi+4e268E$x2KD-2m4i6%@`^kRIl^3~vn0z}0GzP4S5 zYvx6%srTHgLfoy;64*@e)GlIaW8<8W^6Z?7=v)Ou;A~&yC%l9Y0U(gwb|-{^6j-^@ z7AFr;QA3+r04j0-xsl~kotxKk0Uau~B(_RL+g>9|7bJQ;cIyTO9x!JYI#`?WG5tuS zBshj39nLz_EWK>U{G&4WhTPExqi107z)NAQz0Q~FMJ+O_St{N&2BLA0jKz1N@z7V_ zK4W|*5Q*)$66m&vpK(r3W`l}5n=-)=Fk5qy{~~20(5RBd$uMY zbNZ8)&oZv=FD-S?QeXrUO18P|CtXvpy-pfs2;q)Z#?e%|wGYwonLjdV{RYru?hFME z`TqI%GRaK!UJ+Z=rgRT+a!ut8vMehAX8~l)sSa(%c|3U+kO;CD4mz*A=VqeCb8K_4 zDI$V`V^wGL-44?eh${EkV{m8ei3!m^%SW@6*-& z#iic2tpq3W+!CQ@{t6jeaX^N2C)Mx{+;IQf*Y*L|=7(7G3=B%kumXml&ve7;NzBRaUC}_6{;f4Yl<>a{`K{Y&Vl{AH?yqAASO_F@=K_JxB;C> zcNx9Ci_VM%9s4shr4O9$7$eCYuW_I}4d_!_D_Se*!t5J{h}xr_DG$gd!h& zi9c+SfTTwsYNZQT7FYNTTFJ-<=i`#cy^fMME0U*_lxh6#4igoRyA_YpZObvNxR2)9 z#VQT=87HL@W-p9U1Yo{02FyKNr;D($`K&5=`H1*WooucxS5_>jE(owyZEI zgWgY!rY3-N2mxXt>S;ZK>#8Y<+46v&uCYb|F zYx$l-(^5V;O5S~TOyudB-&8}LFVB!NoY%jhWM+;DxpzxWSD0F`icaQU4(AM_)i=e- z)59OuV@qT?=>KxpDM2%@yJ>xV3=9l3#ftS==V#k1f6f>kHi9M!rJp&luGDYDw|vhy zRIXdtR4a+v*)dPaILuzM$yu_QgIm))O&dH$A$K7T*qh%ZD=luZu<3k0cjzupPzHa+ zIgAq9B_SOzvV6urGo_uy+V@YRUEgHnYzTG4NY_p$)M!z?h);PoAwPMV2Ci~CO2Fc+ z@mgxiZtP?)=f)2BM2Uh45x{D?MHi@#mK7K8VS~WACyr+=_k!!ceGt6x@OI)QX};vD z=y;N5#3n;GN6*p{lM;6Tg_pVY;oxXxT#76Y0Ee=cY=D}CR_X3TI>EtVRzs*V_rP6p z$?`i#`6Yb&ktdjFa=h_X!G@mlA@&?*ky7Odq7(csAsVAcR-Ku}oO>PmCigwI_dULK z0|ExNw^MTP5Qv!H9-(EOk2swe1T>pg?ttru#-{m1a=*!nEZ@|Gbt#>Ot7XdS?P?=) zHl1)rH68}xMgws(wrB;+y^rC8jAhVL)0Uz0(8H#wmqm@vP$ zQ-$&leN=N#KR?ibqhxSMY?&UxjY$4U{Q+md<$3Ru z-}pj^5Uyrem?JSrXLZQ+bb!>pn!3~r)uACL>=26b)?153he4+L?d&gO7B#E_OQ1y= zvgIC@jRh$U(UJsBULAaw)RI|ALleudw&Lu1X(JO%WsI^1)cWTtI`+y6wMYaRTh{gR zVfsfavX92JTZl$$eO2fV)Sr;@KCn7$zps5Bie{2xGS(%jk(g9-m#Dv$7%Yw5%LdM| zx)m|h;bk3PTLmt-A#oqxieTwmSfDyOI)aY}@EW(Pqc$SgLyNDxZ!e7ke;8 zCu`|Y-`V+@g5V7`Pz?R2rUXaSVKa_!3$@mKr+~J#f6C9o!{V3uxz0ezZBF$jB8q=& z!J2a!OfAW&YiE}GTFap`^ZVQhAK#`8%Q3Z%Jff4!ZIFC~?cF=s8J#Pf*;a2pz~cQ_ zF!6&mvT(^}=P#eTMcwFWxH#qZN9mTOm{8q}pI%MgeHeexhunYOmURDhCb@2vg1nb@ z_LHt17k>TV2^#Su2jy^*r-68v{aN_0#ICl(!BCF(bx6;UM<*Pg@heMWa~6v|$5*1J zMo=#FH>n10iC|#JbK?D&X#CRhw*k~YEH?i+SVcNJ;lU0)ws*nCHPtcP=ElL?avmQ* zO?YLbA^-5`2WaK;V0Z)y6JwfW!9+(ezHV4@G67;Mf}@SjR~cCCeP<5|kHbd5RU7P~ z0%ouS+gsHi!5foAQ{7Y=nWLjAWi%2O`l+d~2e5zJi&_Pn)iPuC(!ZE96}>r)mA9%A#W5w&A_zv|F_!Ac1LG&A zEEKEfa@9&C%GACPM)ldy-Wo;zU>r1Kg^qQ0nuF$SLO#y{=mFa_Y~o4W%s6T!8XByk zlio~sop;Ak0TmtKQk6h=gX(f-TY6h`@kVG9 zemdAZ|Et2i#}+{B>W2j=v69=5?Az4I6#tR71fSYzfAvp)@y^YeK@1BW`A*gXIr zKk1X(3dN@x=j%>1mJQ4DhLAeYicXhDK5z*=$Rlzg4u!KLru{A8)%2}b25x&3+7$3A zp?$l>b()pt0Fshv^ton#d)$Ch3Eu|x1E=aYVOM0XZ(w9H!{XP%YdHE#2?qyOkc$Z>t8`$w6EQR?;mb8)7{vKxgR#ZKY8yG=mYFI zR4zP~gH>o_*qa;YeqpqRct2T`z6o4+;Te-jz%OIEoh32>hYh#OJ`|uIpla%#MtQrc z;ya+?b(%9y0;69z#J6X1$z%6g%HJS<+Z&kDS4v>ZjaAjBak*8@qCijxvN2Ejb~CI4ZtaIx1MRBpM1Zusk)w!_MJj zhL8e9BKVPi+kd7fW~xBtez7BN*fIayn(q6gBO-XP77l=s4@KrVR)28Lw{Lj5ATmr$ z`^$9H#$)r1o^&E=AR<%dHfA*@)hLH9Z2 z;qeIec!Z1XBmB^2L#*CgPz0YDWVGaBz}0L+Q`|#O#Y&&a5Gj45X23pZ%_ME=7cYt& zWrAY%7JeRRVd5(}QkmjALpSfeW+3=h3j^;KkG-B|c>xPhHr+3Ln-4rM_AK@qF*rCd zk;0MY@Y4D)NFhVT-crc#3*9)%im#)NUuw6YuJjj!w<27t)Hroj=Rm zy|(reELtNF!@)%N-4Al#Xg0B-s_Jz*+%L-`j9c$FS@h1Hd?mMJMldqu>U#n0SG_}& zL=S?g+k*(*x_Uufc{rdGwI}tTT8C67h2F$&2 z+We-jKap=@gq*L?2#c zSQaeJQ^pX868j~;QuPy9uv_QvnfmmdnEmNq!c z=9ZWK1u6Ua8pV*9PXfJ;<-ni9^Rr?pAsQa#MjI0?`2ERFlGfpBXOOa^vKC?%J>Yj&W(~Crg`wnnU{%^kWycpw^~?%)cd8< zWc&Uicmc7KmBRIFMoX_=#7BQpL?pXkLDstq+=UUzIm$Od6p&p<1+Erjjg$GpksWpL z%UqDnQ-HVQYobwwEB?V^IFXH;V6DxPW_*I|YmW@{?)XC?NTWmiHy^&=b&K^Ad%yB$ z+eWK?anq9HBq_3FY$YIixx?wnZ}x{CHBGlwB5B9Y>{fuzcj`+)n>fi$Y-OR&s&0EL z^<;yFV%W2jFRPcvJTM2I3opQ98{6wQ=62}j5zZMGuAckFhhXr7%M3t#fo9V=se;eq zaq{J-t*=4n&p)lv#9Ei$0F(~4Liqx)6}}>#=?Vu&>fK5D4+^e7-Oo(Km42CIr9}~y zPX<4>tN+&|NQ3hsTO?fYbM6e5h7T#Y<(cttb>1h^pT$F2M=`cBIa19EEzbH>`%st^^RE;Ho7UJaYmh2(xbn zCBjDHb~LW%dD8pMzh!t40159CZ>BqInDwLBsuqt<#@5>rEKEpRe)8)9=-wE!F`=cZ}tM{1zseDT<^>+paZQ z!4L+$Y8fwJUdr|A&C}D=w1Axn!Om3a5IJ&0Da5iQSH}Mhr}m%m^ZML#tEt~@a!b_q zaWsNxga_CmBEK-tV=S%D9B{~9`fvUs!S>((rcJ5r_F)J_^X;E6QF0k;NJ_{5VHJKI zDx(T7j;c2;Er8t4zxbt2-2sg?V@oMx3%3`X0PWEm$~lysA?HrSa38WmO2;rtZ{UUP zA0d#NR`p50Eq4h5COq-W1j-^sc4=jSn96(%t8`7K4$2MAo>*mg;H>5Z$S(t^GB^TI zOK+d={P*+Id(YWoUQ6DRhY_Yd^MgFLY(Y)-(DZ{`KUJxOFgP)h`rfns(tNRlX&|1* zthh`&Ey!h`w_JpJa%2hAa`L$i%cdSu`;vCi;w0DJOgnK&VyKNq$jNmNr_8f==Gvd%C60TCf+;af6ytM&GCCB=Esy%(uBIofgh0tpb$At;;KzmELm34j zqSEqjJ*ry!YTO_|M!tnusvj#p9@>ZE#43}m1Q&0^^m4}rX~FdqL!aU5!Qf=DA}%GX z^K^nQO2+<1krh$Nfb$0hg&Z&);OyVz6Uo_o<(?SNIx7Fdji+OUi2Uekf2T#`O6pZy@c*yxs?n>vhu_j{&Lm%=oPuwuD~f`k(zocc4Xq2*w1r^KNcF3j&4kq|ZaQ0zYz+wnKOs zm=!YrE-Y&cl6Ap?sYR&X6!1-kXzGZz2_a+a6ib3(<-HCX|MC^8Sn|W8@RTim(F@4p z-o+O?!8V%z=!pV9D)}mhs*0o^H$)^(5Z(LFx5X;% zv1)|YqjLJTJ>JsY9>yu9gtldc*nTz?RCuz_WQyH*ywaS66e+_fO1QCkqEE*hS?0Mf z4Gp4yC9^~1n4Ml+;2;7=Q7N;Sk%ro$Ik%%poI)CR$jyyA=&pR+e#x-pKKnkWe1Np{ z`P~Ms(2e8r=%XG<=+_<>3dG4dgO?h5ms&@jIjkd6t;WzR5V_fWn&m{Q@5YWch8I>( zP|q*ah9`n`9Ed46BrE%d%APah$g}=*;LY{ekFAsY`&Wr#{B)5{kV=MvdhUIj{yTVY zU@Eq&z}M@WH@%zONcBku7rzAUD1vwqKV~}wngv) zsUPLTzaOk4XWFkC{9=!z*Ky^3*msVx$OUxuJA8T-NPcWxzY+&t&9A}|H#Ik`{7E9W zB#0R`hU7b4W2TgyySrKKb-z;ZmPJ-3UMKMfViM1emhahB6Ljp-DRxl6t#s(Ot9i1; zQ~%>1g+lHy+{Vbpz&Z{(&l#DSTWWP^k@KdEtF1q5nOK&=%JVcOus``o3RV%wM(yG>tPuaw8mp}rblSKZJdE@fk=iX$>j~dQ)Q)`ZX*>QfLR$mH z_ptEm=Re2QxL6Hx%RHjt#m+kPGwk2lJZBl#%DN)m7!oOG&H5!uz+y7H@C~G^ueEtM zXAk5jK;VK7#mj*h;q}9BEa?Dh>B8ls37}X2|34t|$Hi0s;FdRw{g=RDXl@=34v{v_ z&>?cW8JzQ|>u+t=Nx0ZxI-DgsW}ZOJ1I()TGz?u|;ID6v4KbR1x%mjqhkjUuyDfdG z{l=?LE33d`WXh*MDDQ5&4{Sa*^{Yr=%w*@4fGop6w;;8pR9g<+SVSHjs$^%fM4?o! z1Ec{nOO$8S@x8m_utJ|Zrbc3%_Hy1IMrOOIdv0eOnEjk|lp&9@4#O^e7_ zgLp&;Z~Cjz(b4tmpX*+yvtKt;KK>!AI$GYeEO&o}K|EW5kO|j-Zs>f;MxNjFo#1yI zB&)Kkz--5-g{@m;1y1pC7J=Lo#(+FFwOEDlyKb*BjrzIvj7YrEn1HJvPlOlO*^A9# zYh85o6T;4!(^o3UzpT`xgr9pR`#Hffod3~>puc(3o$`$Q0=qYRvI~{Od5JmYw=(bV zzrMr;V^pJ49yR;X(*@I*Xj)WuU96qJ5%kk|kiR=i8u%UTD(WJFgD1Ssw{ZZzotq_1 zFnDv*`0(O3!8q9hgZXv<)EQtZamv;HTohP)T9}8pFy9_y8jBqP`g(XYm)p2gmbahUq@|TPr<51yk5pnX_QBN>1+ZZWM2mZgCANkXGkHo$Df zH>g7P1uhfew0r{4KQ!kld0w%(iKnS^U|?*FS8j_N!k-%+YqL=VFR=7_yej< ze2c6sr%$yM5+eraKed_Rv-@bRE#oBmcuWmga__~vQ{RoA0F~#vhK)8eONG9>d2&)x z5&(=+X7W^rZRWk!)zt1Bkck1F6N*u#nIlZl2E_CWb8~S?^sXBt(->4syweyK`V!eg z4%|Fo)=}$D(LRhQxCA!T+$!i7RezzMwpXoGa3XY3r0{^Q=zCqTWb+4b&@b)~cY+ z=QnlG>HW(R8^~5}nV?-q;z3YS@&KRdHS2ni?mgS_yu?%3`2|XwZKRlkeyH<8RhR_VKgl@;RG6o)fnMVl;gx!&n#dRltS2&syZCR})t^c;)f0}l1&r^mK zWzpsi&OU!ZP?L=36cHqEXWDT|Uo{&KnzXJB1kN@aqe1Kvjn%vp)9PG_b9()l=o!3I z2pGnyu5n#K6!p=_IDTqu7g0qp*?2RFjV*{J$k8FOBQ#iGm^>-wCByf~z!s z$M~FuLo#tw?Ep$OTH__Ni7ymO)sBd(6`*`)u&t#mz%)?N1kpV3Fcqo5+A*N@C!dcF zdWa>87d=V*5v=2|r4 zgp#Wo3usp+?~|J_m-(UlO>nAK#RRsSnpFN>3v5AHaVJGkS$wAd>Rx>5J1)y$cO}gi zc~AM54W29Ry7pU1$)F98P&U?k^?maE&?PRYQlb|?Z*SD@ z*dfNjVM@TkQ9X-|dl&Fx)b!i`djX6urP6C$jA;3)@+ZD0YtW++W&EssMp|I5*#W0! zBV0Rz(7F;}&Ht{hf%m;s<4_PX1j}>}xZqecFQu1oidrUUg6sAYJLbEINEpA03( zu|kX@MX*9{ifO-{tJYR%KxIheTjhe>swjP6XZDY6z5|DB9WD&c&`w5QNaWmNPGwnHxe_1??9 zrV)lIR(-l=Xp;F{8?mbZ)cGi4P@fegq!IR>C={+8%M5gCm2g+Vyhvg8$x~I%?5&3H zDHczI;+#NoJ!fJEtJ2;1BlB1|Kz|1+k{WAD2L^49@)C+FH_ z4@u!5V~xbG>(Bwm{sm2VN>AR3mGlXfM0Ei%{WA*xxNipYp_4}>l6+Lbu~kN?@h?Ju#pnW4>aZ~W zQA2u1dH0cRr+hOoxK`rMvT3q@mz=pbZ!^!h+ddMg^{4@UrO`=ot*ZV%VA`i-$<$$H z!$s|9))Fy@D$iE&D6CpC@5_k zfI1K4P&>hdlad#O?#d-o*#N_}8ZVonVRkzHO-8M@nL9=Zpc8jOdH*$Fsr46Ad#*yh zvT-_?E)yQk&pl3r)h)$2kyxEV%-ZmDglHD9}D>j$$ z;{&&q>jxt#(Yc?X)nTo*g?3>)Wurdx_=)cmkKE^xD&nO>&Q4Z3A}YA)PMuM_6Ee^J zp9f%S`B=u;9L$oV)c<2Tu^$_|AH(ObG=cU6X~Q3x$8z~g3?jDv1LfGZ_l+-$E;+iI z;DB7fX*dq8tn0)xVsg~C67Sm40Z9k~iduN`t#gTsSJitdYlST2xPfev#&E{k7b)eN z>aSjl2&!wdI3T3%N@c9B6>s5vmuS@&>XXk` zGljEnTKXqfU2V+weEs_L`8_XPzj*5kcgPC@(j`XXy#bt|lwRIj0D`*PN*{d`qF<^% z$v>)@@t>-QW-k;gCRCHxdTl%MwiLaIc^?dkzi+7UxhO%Fy?pHB5>7$W;1g>5=C#}l z>?v-^DsM;)iGM9vH(sxqt_-}XU{u2&9_b0(BLwnOR!9j6q;}rtlZvjiCR-Wpe%S5Y zx5!Ag4Q`B0ciq_OMrGa{i(=>49StPaY3Z&O=Me30aUbpJ?h6N4YCzZ`}2yf$#Wn3~AOy%>+0Nk}6(XqJQAlHxt^3ha){ z7M!0m22RsH&s!^{Z#(h?-F&pYK?#Y-M|J7*Mq?GcF6DTd0p4jj1nnC=7R<({GuWxu z1+4LWy>s`Jbqa;*b;%ItI!%PV0a5tJURdN{8%Evo!_u-hvf_RX2(!ofl}>VSaDa0& zm~M*iml9%PVo|3BSSvEX^5Q9SxWLN1(^c(pmN1!EM$0E1*-nZP{iE^=!B~fiu0*nk zMm~agDa=IdcRS<%(R7tjO+Q|Lqq|FKq`Q=q?nW40(%oI7Q@W+QQ@RnPrC}m1-QBTg zzvrC)3*K_ZcjNBfPp()nl~ytmk*l;bYFS*$7V4{AB?mljZKiaeh=zqtC0Q)}p^Pq4 z1<6`21|M$HTZZJ+LKcmlTFVrZYZ6JV6|FT~2fBVNI`At^|N0E*Adi|8o8#u@Ssp_Y zyznq0w`CwAi{pa%WDY#bCw>dN6sV%i3yMH)KDg94DlDMFO}9X`w-zi#zP>0gpnA7< zzdbtd3PV^H7(_0kGr+gi#-DX+{aQYeM*#nxeu}5~EI9jZVfBOz%gBfBr<#&4CX96) zvbKy@*Nhp6-7=)f#gR)hCVC^BWP5Y7Ios^eimekTJB1 zMBWjV=KM^y2`oAXhr#hPFvKWcOZ@Q(B%_8cy>HLw8+@Xo;2U8$5eB{@BLCza=MQh& z-kI0Ht|Rb&^3qQ-=ahiu>ipc?QkbSz(C13?ofJ$%^68 zRfS<2GHKGunj5`E4AnenALr8{t=x!gp&?)R2lXA(Yv^0r_3IQYKN7&v%EL`u6MF)K ze-epR3J+E-IE5EJ3dT#C#w#%;F4Rp)>PAfcux0zRCu@r=wpC^$Xi#R;{8Hrc=b%K7 zOmgX^EJ%HD);8FB0jQyJ`vsIR<{c-Xzn^TL!H;}P51FZ6p% zuGQz$nc2KV5Hf^0xm~D>L{!yg{gL)vy<`Eq<6>VO4lE_+&rRNa_kJ67XdgyNVqlA& z^5mq_HjD{Xz^ySX0v>sm+ra9X5Fa_<*q4702d92h5VDSr0tF!ggm!`&I zB?Qc&s&mLvQOl;J zBV4U16C*;qDLS$hJAxa&IyY;G*N+;3weySNGvtBT5mEs zI8-$Dz3aFGFX{fk(|$cRSTx>_KY{zUqA>Gq*gz+&nbwG3-WCyfIZ$W&mr^cG0~ldIKOPDTOjuBw|$LHYTDElK>mILxU*qaP!z5W+fX zvh&GS8(OiWqLOH%*@WDDPEb8Q{3ux;TBu|EgeYMvB~Fb|X9qUAp|jI= z!nn&qE)A@?StH#~^8~vHPd-E5j1BGiXlk^<;pHx?S0n9VumNoe%L>`vREDvI4gW2* zJvT4|DfIYbn=7ZiBneyyr&Mx@j-ehID$DEObvHD>lMgeUwPR|qm*aX}ALMj;c1ZZc z?A-}MzqDk?f-?dR0i!s8X^huF<^h{9{RD-}K1CA&EC;ZWo%zZ|lCCU0`ZYF$jY}>x z6`)pN9ux~WqY?v>;80oS=hfZ^zAjaDDpEjUbiCzawePDhK;bU#pzirBdF6MC&(itk zYKNQa*{XnyRyO_fQC$RzNmkRkIZ%LGqYedD<>z~bkOXQW^J$fHH%!Ela1RB2+URIT zk8QdQ&`%phtHAEV%SPI)AU6<*H>lFO`|||Q5#;W9M+_fDReEImo!#=P(Qs+Uy>X`? zr!;?=D`6GwZ)`V@QH?{x~oB87m!ZZhK)39sOwddDX0igoV40c%*@o-Yr>3n zYqsyf?bM%eT%p>-2N1G-Y5j_;070aVu0z+Y8$cMQrjZk)#!VdjcV=dLr2=3Z!3*WI zJYD=Yz#d;-U?Vuh?}J;&zc2j(+6DS(ODO#B04)e zd`lAj9gUpFq7tQu{FBR2kX)J>k6W!u+CV{a+TzDTp8iGY4d_gFmO!@`cdm*#7<^uF zAJ3eDKCXOj)Z=@5vJLx3oXMSnI`JwKj-OmhAI6s_P5cOsZh)ybZY*qp4u686!Io z5m(%a`B=y@fY(W4KGjZWbdm+TbNjes$wr7tL+Cay>tx8lf40?-S5@#Rz8=Tmd$wv( z9-MAgWdhH3TIAJ~F2$c|d3~{2W4Qo}rxkz9AcOn`2nbT^g4;N$%OX!!Jo?Utey{ao zY^)xw49kayB7pDp`6a!v@Y2$f4v5fk?Qic|G0%p3yjX@aa_1*^!+ql4x7%}Lxx!s1 z9ng&(q?+T-mrGb_W&W>8Dt3|1I!WDh9YaH)IYmD_)AG>c_5KCy?v|m;vTgcpS?hYV z1*V7F*)J=lPw_HH?jhWz--YA9nLgt2>oX+ARiZa@Hx!a2Q!W-jJpIllr=`t)oibL) zV6%Q|&~hmoew$)s)^B&@{B`|20Fv8!Od7y?3$HWubH&5N z#VWyfUj^Cf?KS^(IsX*~-hy9l#lE}%e_Rm(lo8pARCuQZTy_DO6qAIqy88OR97za zxj?o9IEl&s$B{MY7xj&$RIMyfF!h3;AEjI6K?A1R{$zVuk9-s{1bDbU_GJ+_|5SL`)|X z2@;w`5XH#3W3VF2G(?Qk$+NSw$r48JzDxEuM((Y0jT`Ch=Q2(Z8yag3yVzW+IrevN zO7CCm4ZZZdJg!6&UEh*}?ysjs!ROO2lhZFHhQD=fCdbXJ;ndOzrKOf2kgMTRY}pVH zXbYA@Gy7IM>*KJZj;fZX=%QU{dF(P{SruVy_8fiK93Kd+6hQcb)uZV#%*J^Z((HE1 z{4P4ASKC-WiUZJK^Ioa^Bc^XQf#fr=;PS>LL#f1kkmNYjdIsCiE^LXEm`MgVc#3*{ zbTHMKR(g255@7lzWS8RGE6Y1#X~BIwFY_p|W$!OiYv5eBbh}ws_+fF}J2K+mH?US= z{@kUgbb?B|aI?0j=6H!1nq97($G2sHy|eP`S?jP%?{A%$*VE$$?;icGci9Bz+CRgV zNbFzeBSk%rR>64>#IuJ*uKQ`>?BK6i9Rp~3p5Qm(`h$uHj(OXudVA4Je9=qn;(rOU zV{c+j9L06VFS;gXT@XJ8{>f(NjFwL?~0nQa^Fr7%~Jo zb7xKAbc~IfkC$Xe^#4_%hkB!r#i2EX41NvIjE;KzX?jYI!E7r-g}8u0Ef!6e_Dk;D zx9zm2>4RD`H$i%6SQJSxni$DUr4%K2C2m{7wyTXZ>+T03dmx-cg5K5hxkEHaK3x1b z&Hd9f5VT|~*L1hiFKhq3bRaJ`g=a(5qe)a1ty3JBBis>vdg_oKxVQYs=7GDlfBPH4 z^~1%m!*zGnWe>_tlP{XiMjJccVC8g-+FlV-oR{S^%EC5s2L2CdoS=Lhl?~)HQhpr^ z#Kt@^QTxhSVa`vcN1g+&V??W|uRlgtNc?1#N%wowC@GV7zSQvJzO?1##pE$Im%hrn z0jPiFj4U5{W~A3DWer89BfBix2V*h7N;ofu_97_^jo`;Fqg4SvLM#3qybAZ$o<7vf z?~iJF;7>;JD#%vR+dkSwH#Dg8w5rFbW~%gcdYC7jnk0dtxyj6L^2}*(XaSr}ihIZE z;WZ$fB|68`OJ-uWjWE1@`GP*eggoNC*J?o)nYqum4151A*oxXdqy@=leTerxBULZ^ z{5%hX#Gw6elY;#n8;F+Vru<|Is+j?ev=$y7AeDR(HVfV5_%s4Lq|{m7TwdkuhIJYj z)ac9+cALX_9%SVCjwzfn{23A5Hy?Qi#})Q}2P1r=S!4FoAW(RFg}T)B)!{WwvgxaX zS6mAnjdFI5cyjFS;XI-$yknWhaYkkiM~Nw!Z5Pw_C2xG1@+W0**}w28Iy#$`pu=YA z$zW?U7U`|hI?~u<;_aHfXUY+R!7ZxW-~3HDw62Cn{b{8lq4!1+gVY4z%Nc5ZVPnhq zxZjuy9&x9q`rM~jpP@11IRT$Wg86;lID9Q}%Ns^Dy~*@EVkt!G7#ox*8!EP9brQQ@ zq;J7@Kk@?}u%Q>&eeka;nG|DzRy&Qe)?&XOItTUJTKDqf!f~d2Wax6;4Wqo@h^DG) zob#vjXsVS$uhK=nB3TI6RUU}%So2a5yx^sbEf8U1Af>tI($669HhT*?;2Ju}fBA+Y zO^X@HL|nW5okX%tX9AlMPNwLaxZaKqa+Pa^7% zOjGYzb(4*8wnj7jp;;S`&-~!G5Q7d^#O+Jk{o#`ge$zL$4sb=_+~t2ZPKw#KZ`ZK-fTC77mRjsG9MJMIn5?XQSb z5NJSvm@xjm(?&KV&wU@>YucsT`BRI~U?RzITa3Jne#2kdB14_Aoy~&sbe*3erVf=UiqZ{CtSK8S8 z_{mJ%+~5bda7al>D~_2|@`ODObobq9cK-pRQ^P`=h3{}G);1OQHphDN?YA!32WysmX7@M%u*H3 z+DDYCq6}hsM@=KYbZ+7LIl*Ig_|v`6C=@diWDrJtt4@@z4Eu)XVLyxC%O*t>;A7#xAOoTLzmz|*0fU|ZZa($ z-FM^8{CJ2xnkTR5#O$ozs-e0_p#w^~F37mJNliCuC%(~;dF*fE2?8fd>9IafQNlqZ zuJC$K9XLBPel$Mhz8wzwjl5rdRz5OCb}%cZ$8wJBYh!jT+C2er(+1ecb&T?Nk(A=Z zMTvZ%E!fn(3~*`@gFq=(=vRvlAR=J$mR}3rPSV{i@35~$eLke?z_k|AlHUoJNkTh^ z49}FIL9cB!5#YSgt?Pce?spD*QHSQ=%M-dz{YHdGURsI|j#LgD-g=7jeotGu!pD#; zG4B!XOaoq-g}@tUzeQ8D9Y?s?_WmP$&!_U6@F$zT0I1TuNHpnStDV66xb}{YF__d8 zBl5#4jQZyxOg0CBgguVfE31HjsK+$fpX$`0G#i&TG*h8OdX%)$cy0Ii6So5!KVI~P zblCGFz_m5#(S65iK_tKO&f@OF>{ISjy}GL)b9yY!OvPv1!YJ_|`AI};ofkM- zgU=Jb3(-&b1dM15%JVXeu7Jb?4-)lzslrJ%tNgo0*@x!0k<}ms-Y-p6F^tU>aJ=z0 ztj5R3`?2iYB`)~B0+w3zpbe^$Ecj}JKLv{!VC+eXYd6L9 zRBal_?_i%QSFf)^O`#X6jr4Wov?;U%K+zJrHc4G}iJ zZcFiDeHd59hXfRL?%OEY4BYw+!UYB!6E>@+g(=|49!I<17Un;yG{C9Bg$ZbDXB9?VLM z4_ibe*$EW-QsC+;?8GmW0jB({A7qQN9Sz&auoT@UqleguOzmT(lrYQCbEV1jpe?WO zNoQIOr8u?Dejc5TsB6Sjv$T}p{A)c`1HH=FZTwbC%$O|Z%?onCVBn%qZRqMsXkz6g z9uokQNk6pF1-;7}K{F_*(7#wejmZ;mY{MatUH|;gyA*xIWdeixk5ZPvo-UQpQRhG$ zDPLn>8?jgS513DW5O%$odzj%rr;tXjtN*-9WPJ(z#9W`?&qD*ixjew2D+jkZXsinU zZIuR9;wRGGEg05`wh^xFnDs}uu$V>TGggobZhahYa3E!5PEtMPOc(Vfk8!0|>M|Gc zPm(hUXbdlb(nrif%mD8dzBF5x+)MK=QA^5)xKT{q9`w8?TTIZU(6#n_F0(PU7ZWYJ zi{Fz>jWV=$A^5S;aIClBkvo^OO#%bbQ1+*d`_ou5W?JL2^b>q{|G2p=U;Y;&sK|r( zCNRHHRGeug6olx%pA529NA!fM)ZK?Udnw|vI8Q}KyyR_F zYIuz;R`bmXmC&s7@9RL=A_mdQL^b$paV!in{>-*wa>dlC-V=Ilr1DBJFer&8dJe$K zd2M=m0}aKw-MJXiWR>C2eCx4i;f$anB5xizBA%_ zARPQ+;*9^$B5IRlHtZrtw!wR62-(`)6r=g>H1&6K`W>9$y4RWq9tbq{JDZOyOG$u_ z_*#@Gy406jh>!S?!m`fE(b19eBQ#@8pMIO8c-O~;rjKtB$f`eZCZ(DwEe??=Mlm0@}^E& zx|}o3WF5!;q0kV|&vdm^-Hf@={nxX(L4!@{~k*-DkB&8lF%i*aTDFiDVS1>zx)o|b$M(wFH zH2TLxNkI+1UY-oQYh zi0qX#%yNej37_-X4=ZIX%(hU#H-2r;sE$~N_V@?b{%jaePtX0_^L#QEe_~va7H&uA z)+H5F_TxbX7WrcI%Mv*szyyMLa&`s;)ERWd@K~KmsCzS0kbm%Rm0AU?fx6Gdg|{8? zT3$^#jgrVAV^v93Oel0`5iwm>`&XC8q0ADVt4*Y0^mb{?F zn1PD0dFde{+Lc_wQO&}(=02oxE+JWETvV}}ZeqXgwwk^t70R%|)%>6y5>wr%ueUKS zaCdAuKLl;efb$nDvc>4lXAj9YBw6tvj*BC(AReJ>YimC50=EpV*3BFoFsB4o+g(0` zReT!=fgyhpx&|-su8}ixwr5OMBu8k^w#mHov>LyK>kKFFj0k5Z=P#CjcT1VaRGEybI~IHo2_8MN z>M~tm;3o(#y8Am^vVn{foav*p)UXoT+-@Rhpm9Gdve@Jv{H)| zj6>}_qTw};_-_7sWZ#5v3Q1Z41zFL*rAYfyDh%oc;Aw7rq~KvSbRLFoPEM)>pI&DS zfB=}#3syQfX3g6Vvy^h>s^I5+-9j-=CySGjKS`_$k8=LfX8AsRmvM5R!jd7CwZd=q zV~>lHZ+2f_)ViZ~dXM%FLN;+av3cL);|ou0UOw1Kx15OW{eP8fy%*JD zbI2Ze9@%M0A#{GhO(jQyz_ zqE^KoWO~+vq@wV1D66{`0i(j8TtSmL#xSaY>ZEfjF?ze`9W8>mx;F*c$pmbcxIw@1 z_7=~=wm97BoDRi*Q!uTixs_Gq{2{?_cjho>3yUz=pEzK`Xb5R!M7vy9gtV+~h$fcV z@KdPH@OCasy-o>VuAEC;ZvPkFsGac}YT??u_QUSFZ(>|eOO?xbxd`pLj~MrwrWO3= z)mu0*-nLH}a5Jk4U7dbiO<1mTJt(!uWkkbP5L@x<0UnUMvK#qRtow;PY=*+*X$W0) zgJ);#JniLSb_}l+!t+Blg1~-8L8)*EMzj7^0BnzyL*u5wg{SWF1D zH36p)Q};s}o#ToMuT7cY6UjvFX>v_{vMIb2uV~@v(5T=B2X}6VBsxHbhgupzxj3N3 z)oLX5n*;u08Wp=UDlssKNf)0JeeZ>X=FFI*$!4uG;cx&aWVN#;u3EcZA%5?;r@Tlk zcN-SEBZ0EIygcl#SL~o4kA2tJCMsi1+AL0sL@u3ip*7w#^z`%|rkX2d9M4SdF76S{ zT^g6>{g_=QohXTr@1XfgpApA(LOM-3QAaMVc#S^Rv{5P;FoU@FetrgS+M{gFH;fTiWke0bX{g@J4A-g=m(F==IafZHPn+WEb zT3In1p-xI!?%GNI)?mw6e3tKI3@geAeNG5M(aJKZ-HZ2eRD+&%il}b9$i{cQev3C* z%HLqW-}iwkoh@Cz@qM7#Ls-mkxb+(IiClPAu-2<{V~SP%Li=~hKH!Jv?(NM;4a#TH zGBM-&8*%B%-qus+>ph}6qn>mHbpbFTgKAzsESBi)4d$9z?>{@E(6duLu!pAxd>ctg zHCcR`S7NA$I1+AcZH>6S#mo`b?VoFJbBGOn4S>xx_%6R^U1KXDdOR41(s^II@l=}+ z^*uNx6|aWo|Hf=@Y;3&ddmG+($>_U4@4NUARKOb5rHWJEhwZ&d<_s0s1X%^+ANNf~N=G21urbuUP?`g^}w)*Zb3Ec6R6g^Il=9X6QHkA0ksj)NJm6YNi$q&F|Vo1&?F zZWFOUYswP2>kJoh+4naR6T12|eb=U4rPtg0IB5Rbo$%Pc7obsBGCKU*6=5&n_;?C8 z7g$hN-tM}K=D6CPG;Rn3U-$Nqq!6?@jDNyjUdkAO17xe>FrOinF8H(+@g8e4XV6=C zcwhhs!#`m64y;K6wWi*wfEC@KFOVGOT_S@$`iRy_>N&rnzn8(-{+rvdodFUD{d2?j z0ge@>>F_vLnLgjig*De>2V9s@!XkJT-Hz*=0&54`gsJ@J1AzBNK{>)qWVLv9lA{$@ z1lYV9qj9GZ*rK%U`)(?4`Jzbm4kNkk_{$rV*UMJq!)-@q2~S>I1@rIgqWw}ij5Ls^dP)DQh_~_)giBH(Rv>+n5qo~u<#B=y!k&rVLbk<8&||3)VdHxYn!HtBBk5uvVjZSg zSrPJwb<8%jw9u{l)zx4$wzi_BU3&?R+X_do{|WnQ*{wEyWv(~s2nh{s40A-%R||ZI1V0cb%=P`wUs-*W zna_dFM2e(R=+RD4dN}nazpSfIPl{T>e%fFk+vl=pZI`1>zP|fhC%C@HmJq)wIIHQP zauxoXS~Vp2=_0D`4>`!lk^>zn{Q*|+5Ur@#jG){`Eks5|k@byTZ|;GkqxVyJpC@2o zOsWN8FzbAAy4~=}1Of&cnI}7-*wA>zG0XA92jrS1p<0AqEh#k!Um4FitCjDL>#$-f znEU1PI$7l4*YQ)UR*wo1YD~TOtO7mn+(8%F@}_Yl$Eq&dn_cAScZLyZr9vM03N=C_CnGNp}D2O-!6 zs__7WSz=&VV|@c7S`L3>bP;1iPtSjkH7+zWgU1mZc#wy}nnrfqDPyQwNPf{REN3WB`jxM!H3M3pLf3f=dl8}F~*!#Jm$}jx*VLV91`pNL+h5q7XXVoEvU0- z*41PhlM$r}Y>dvIQuf?;t)u9^3ugEf9p_?QLYNkdvdK7FeU8)%CO0sq zemi6ciq-aG+c5X1`p*&%7|Px5@m@PNid|ex8>O+EQ>AxSu@l8vR=-@w^N%S7!kgH% zCAz@C02(uLx#6eDmHZMAY?Q)4O!wOx4_ zCO(h>6<;lu-b%*8`jUn&8{{q33MDc#y&A6Q8nMR{E;jQ5(!Dwu2O9%~hnX4|r z_RSnU-w`jJ~_$gm`9Gw_F`V zY?4|W(AH+|1PWejb-(8)!L5L_&3a)B8~rQj6HNQ5tx0Iu_Ok&TL~P`36!_c*j#co7 z)%U=9A7JRzGM1B`ITMFG_m7-OC0@RTuVLB#gYCH$0=i@cO+IvbHjmFyx`~24r*p;CIF)3?HO; z8Lc@P*^bnBUozCgI1_q|a>NX%K2jFqpO2LtCNo&{HAD|dhpz3=|GX9LAE>q3%9Vt8 zk_Z(Y17_e+4g?F@pGeO1yP}R66kQw8aFZ?{sM;P_O|Px~yq^4hxxSXwLs8li&Q;m{ z+hVu6&JKgAJq?lTT`&=XkSV+`mMLFnDPLt@A?=^5d%wNK3&yjc5eO7g9z0a{j7bbl@;AT^M+k#JJ6FljN_`S!ae~N-vH7q2f=_rwE?I=@f?iMYCw0tb#$p zGoiB`6l%4UB!bz_nQYo;M3sq{OTcp7s)l_&FRv}h_Wt;agdQhhDWrH*Nmo55k|>Ac`^f~aJI`yvg(F@MF>C^#ob&PX^C#x!o>mxu*e~HJy`l9!=Upqm zp$kDDQo~{o?6TS$PI^9E0?u|GWYXXPg?1AhZ^wQ2TbBD-i?_I(?*WSd5-s)P6(==4 zuXQX!k2FSfQ?W(Tm$b-5%^MC8&{Z@s;e{)A*1xCQ>^~c#|E(mRUS2b;nCowMZDwX> z0WyOd_1}N&|FG;G^f|FtKPX;&x{P7!z+Th%c`DXP;0nc7+m*(Zk*&Ji ztS!>SSH_qMy3>DMGS<1h>NAFBnxU1fXHMgLv#jXXGJ{vr0kXSEX+o|13kkE@W?C z;}#GAzwTGz`Uu#*1bVi$QO`)bstF1|9el_aVXyW7U}LMBRnJfM0CT!N{@h=8d#r|D z3CV_==m0@LZ)7=)FD@!LfUh@U<{B}@{ZN@ai}|C^p@Np#fomh?;l2coK&P)K~`v}%7uib^Es_= zw%9=|c=cdQ!oGTXsg#{q*sa1<&CY4QO7=moqEfjA*BP}_Y&3xkNkG7Xzl9F^ z6{gkr`@%5RSq)@yr4JZAY)(JmW}UamhsfL|^mL3xqe zM8dj>cUL(eH{1%h01^R&fo(C_Z3-^~W_~Yo5L=J)qbJ))cSpZ`6QJC%{GdcP=hh}<2EYR0Qzp!d=fpAzG#=mTxvg0$rdY;u2bbtYc7dYW^mGwmB#Cy(*|#6qO^c;tB=wChvnlA zO34@pF-RpLl`DFgu!#{dQyI!{0i3%fTsiIYMhfIns)9_h90q^D7MwYtsYH#9kN`QV zoHys+lH*8iHZX4QPQPq)qJAvoSe6NJNX}WIuq^BoVrOSJBfyi?>Y%PlPo`R?LyFdW zD9+*3Np)3qO@3_qjfKNV@A(DedWZF>RzSAqfzHEjLP3Tz&Y#FE_a+D?AEW_Ri z$I5-p_T;CI*tT+*a8x0;sV(w|{r1+s$X(Sh4kQZi&%jX(Cf**EZc~<8=3#>a&@5?| z1-iOZ3Gu^);_-tiu11Yfx?MPb)dwQ|$*p+TXrp&x?^Ik{&Yh*y-qtpfo9od1Y5Nvodvt1N`jZ#5;t0X1>&XLffc@2B(9}F-D1yxMTVi!>=20)q6tbeziwhJsr$Ur zYJu=Kv9nHqLMUEFQfFN}t%uGPplo0-_XR%#kp6zM8)uP44Jgvw7ld2#X@wPEAvqmK zy5;imy$A(_EDlNSx_bF3gWo5bT5;yV{CLP}( zEV$Q_eojuQDFvzn!7Xo&(IxhV`8w(cEU}-6a=Y7{mmE)ifz+9gLMS*c+1vih((}!l zw<8- z3y=OKbZzRS&Aze0ZwaLG8Ha5K0OCb9dbbJsm`2ME{wgl2h(Yxoi#>pYD#A zNMuSMM2kW5N?x8g4qO+yMBGv|u>f84`wZL%#%^--{HA;H!WCaZTwW%<{@Zf=0AuDg zUamNx8xN!PFKDn#7bcP>4lzYjnA+r1s)=F(p>9IEvgC*rCu8X`ZPNvjVYy|i2z6z0 zEfEJYDFeUfPL%pO!ev@;p&A4N6tk(O1Gr&@Bc#7`;@5q%QI3fiX__r+S zw3f}$!C`D*KRwh zVhWS_>qn|_G**@dR;DTVa0Ybj)HL|d;?uf6^Ix5L;tD?Kl2oI{glZykGLKr-<3SvM zW8kc`O3w2(wRofubBK(<^dk25_7`8{cQ{b|A-u9kD@oj}_fj5ZGa}(dUSOc;>*1qF$ zeCJ!V@UBZxUzka*#k`Z3w}85d23F6zlb00Um9^?Ta-pfo!lEzFM6X$L&P3Sia0uvh zQl;L}<+qzlP|dZ9tszjHAg^{J3A^F?pF9#8tg~a1m=433LRI57Cx7qqo_a{YoVbu8 z(C}O1eR>}2UYmBkkKi zUfhW%i&g2s&j_RDUq(J12Al^dwOGpaF%gBl`sZdH%yF=ER>X~HoQd3W*?8rZ*2DRu z`WpZ25c^n|j8KYh0#Nh%dD%O<&UW!gOl9m#)ZI-e^#hl~{Vt2)BiPrDg(x z54t?RRoH37bdT661<*VVCGrML)MS3nisvhpkzlcWxT<&|4RR;LK*CWMeQ7aVO)DgVLJ-vDFQ{rI!1_p$`$Qp z7Y(Y*vbQ((J4zxY7QH`cDGz*}?O`$Ycd#DGHjkRjQf4noA)2p~{FM@PV&dxzpNO;$ ztF$H5njn$}5*R55N*DGiJeY5N_7~@OV?P$y3%oNYHb47|5y}w+uTB`U_;GX6XS1uf zau6K?7r2csm2guMxl7K7mM}u$rz9ypV%B{ga6Sl&fwhJGR+$gVGcXcYLq$Z)?KT_- z@5vd0`nUCW4bp^eH$^~u00kZ%cEEHHqm#laepw7joktg{0u=3sg^ikN#)S#O) zOX;iQ@9jo*+iMT<^(tdfQ3}@)wUexG5Kc%?eIOVK?lR%CDG-#AHmo&g{F*yUR&5eI+D!%VL zc{)8KukP{WuBX*$y^2ElJ2n-~5O@!MoQXAl`vZ1qxLrk!;OfR^ME_by|1MbLH3NYr zjG9*IS8PKl+(&}-Xg4ukcg9%MYB)ypq#}eWpbjR$*cz*^iB-+JfiZZI}cVfF(1r0!qtW!MKjJQWHix_udi74BVqAyYmk2=AvM+O3!C}Kh)3>Zhx~!2WCYCSh;k$qW zk2s~xtV(F(`a^mVb>$*8m-wvmM=1hB5VM|)sm00aMAySf;FtK1BEYSo@)1Yd``T{Q{wo6@% z+t|rm5z{{x+f1z-VnM)DPq)4L(QCgKRe+RKMr1d!2owYb(Ip1i1XY4RK4A>c0PGjP<#=0JwGN|}OWcwCEW5f2nuMBTBrRipyEo;Noh6nD&w?ecr!6?8JhxQrnlAU%83S z!wnC1u@N{!8jJA8n{k(vky}HGLJ25V4d~89`&1H(3|I`6S5wI-Uak?KSC=) z*Maw|h~4|-D!q>_o4#~nfbU5E07Qbe1(EJ*0nO(qo&?VLLHcqvZN($?_vexY1+wJN z`o!nZ6yrw@QGe&{O9&{uUq}uV5{kyiBEE(D(J&~G28V_fSDBuC#zS5gZhxV;o{>tL zniZ{}iey(+g6GE5`JK%A>fL&_ITp0%WDpM*XHY1TDmb2IF~<2CC8$a>!AyPibmoWy}2GrvvQ~0{wk~)1?kaY8CGbSA(HAw z&Sewzh%81sU4CFnl{O?*%!Gy)L~9q_s*hiuyaVIf?(Xgca#djCMji6;Q&-RoO|7`H zq9(kAUcn{KM(_Zzm#|rIG!^S2$bcUx;w6wJnj>hhUzpDX~!1<)P(O)Ct0O|kd+w0~DW zMAQ#=&NGreVyIv16Zs$a7XK}D;~{hI0T{W`d;Z*;0OK-AORA8Z<4vOlr7;$oqBbd& zynXikCFvVxv+79X%I;G;m$>bTTf%YyC3X7g7D+Tnxy72GF%rN2D(0ah_bJ74#*cVz zh{H2xubX=V#)nS$YYry*(EFQuXrf(SB z0!SCCyV0i5s5Bz-&ebK{nLU-0W*JJB(Po1(flS5N0A-UZ9Ym4Ba~(>vOh+vSOhd*c zE04&myPaFzch?@vZcCnnDl@42b3*U><*VwC;jpmoTu%RboSdKU3%mjVb}1Yo$i_gD z&F%u$pdzYHI245MDzJiT2?(4rywY&U7(xZSTH1G5_yWnF?5Fm7lul=z1JNmQ+jemf zz)tet$Niwb7tep6ofxKa@h~E!1PC62r~JMUE+f8^r76;m21t;Rp|m=B@Ox|sL9K5W zLRGs%=mQK#8i|5tRFJ_p)8GrUxsw{d@=(2BIBQJ^RcIs_Xb%$eVi|<|6~f~R!9u(t z3C>vGEI)Tj=%nowFjw$9OPmAF)B63zIjvrOvcV$(NI?ieD#TXE5{x+ID#JhoI5oU> zcX;o|;VpYkaV*umy5oj6H*^l;&dF>(Cs%&5uK@x7=}S>Bl4mIyB%Ew$L_7{l<*2Bb zNKhJ-#HbrLt6s8S{qBq@J4o;|;STV__okT(DeLNGA9f2nO)2+|j_~t_kKL#ADWpQ5 zmd47w!J1Q&+Ce=%@Qw~^MO#2Q$7`Oiv$OUp&Y&k7fLnpKK;R3lytg(fOD;IT-(CFUoq)q6=w_zBduWX{h=F;X#krm-$u+}+9W+vjW1KQ z#b0jOr~w!ewkMnp9(9E3ZRXQaj2UX_{RML(PH+!<&%wW`FFVQ+RSoFt&X3@@=CQry zX2Q8pOeU?ig4LyS3=rAv;jnwhx8l6;v2$>1YW!*v;FvkobLb3GLq7*6F-Va48D9Nc zEo0ZJ{$RpSFhf^y4=or;3IxzI82IgB_mZlQX?Pzx+$?jvy9xC!aPI7#S2Xv56V%X( z#Zo#<>%pd`_hq)<0+>9lKi*B|U3u~{MM9NuBnXO7g7_`KpQGl0Bq%@8oFVd?TYM6E z-bvl9@F&XgZ5A-2OzR3#KJ;b(Vos6cD~ySUWtJQNT3NqShWYq#r8J^hBJZ>Wa>f|e zb*xurZ##8FBy3j91(oiLM+`l&ZYl>b2;03n5EK767#b`fZ-`09NF)WUv~t-)HMJ8q ziyz+0W-jV!F9z&tmuo>D6NSS zgqbedj3^k$Rfu>1yRhy@qYF@ZRCygvf-&C734F@?Oi!_SIOU5VgfOvY@`hFkUAAxr z?dTs22>1DJ?dJr}rh|jTAxX$p+y$(u=yg?c*e+&FV-=iu+c{w>3~g8;1tfstk0!^z zL?2^EK*N;x9oyY0lR>f_w`azFC%1w&sfbt63BhWT9$Dt(()%ABvMUJX(>_jBzN?RN zi&XisgHynw^h!W}N9$n4^BUDR;oEl*ShsqZR!f0KQ%H)Y$d8KmM?g-1pe_gDtas#c zi|e&7GKz5bg~`*XpQvcWn~HL}a3Em13ve{`Zv|Qme*t=wdBL1^ zUr%&mNE+zs-!=GR3N|91BaZj;jV-f;e$Lt+zWSU(UtVeYzVcy#}j(3SZ8%TxV=7`}FlI5JRMmzO@0F8GGe zW5B8ei67{XlTL@gf_2O=(AJaZeUzM{$QKUrGVjgtVUqe+z*9yy2ovT$zADgBV}$Pu6Y9dPP6)x%v8ISHP+f&tsCCsX*S0vLdO2_{{Xx|L%;eYA{s{> zLG*W!loZw600K%jZJM}gp_XhyhOUKl>gEsv83dwv5dz~}&E|ssIH%mIcj^-`EQ!uR zx&Sn-uqc5Qfnc4u5Wud}QpB29sP^7fx)5qK1u0HYQiI5R0S-#A8mZq(SrJ8C5Q>7j zp?Rk?u1ymMz#%t{X)MO+HQ>f@S6=$lkN@y%-}!fbW?m06PsEGNeT$Cy=VI?>{ys7m zzzP_wo!tft2wMn^MTIJ33a~8HSD%ryiJwHAIgI$Y`bEzGQ--O1KPU6P3GvTErWxx; z-rVfyfuAokFUSetK?V<$Bgok^!f$&$@zv)YwhuaF$zt-?mT?|v8%-DW#V>w= zJ3Bkr-rknK_Wr-d2OfBU(X^N3ZNT8P5^T1#ZJ^~VXj@~wEoVUr)`{ONPrf0Tn@DE& z7ZI@QG+C*i`3Cx)ro|S0G=nj*-JLVSm#}Gi!q+;Lpv~kM#f_A99Z;m-T-)FGp&v(* z(sqID2Bg%WMo1$Bb*=S9|62S4>f~%L_nu zBmnP3V$dW40Y3mn9&i-+Qn4xrC0JIFY9J^I&FknL;EIS(BWg8(D3?U1VsPe%fZ+f* zd9uONzxzM@)VbHa`{V0pUia1Xp=`%oJWfl`=Z|In0Sl9Z&cAf(-f#VqNI>Y2*wv!Y z$>Y4{({ogZlIs_Uzh%dzib&W!KX4LLdk` zXR89?g1~!VumX_k6<^zF>&-bG7{UUzhEHbyry0Vv0ydW7h%8>{0?-OeEqxNU*v2xR&P3!nAgLzAM+VoG#v%ckq#qy(jelO~(2 z{l;%LcJBdoJ%@1sI?Ez{XvzMQtAbT6I=%zDR(G!u(WeR$WzpkMz$uuFS13C8LM&<( z!%A3Hkrv{{=;PierqhzxPOoq-AzCcZXj5E~3jj zk^PVJ{;|w}`?p?v^Yj1yU;Ity1F8b3Dz)RQ*^hAEC5Pi5qu;go*!YjZ}U6< zvHNxW{vWS6rys&(4)sz}aufnx5J(LS3A}UzxV+VCosWA2F+cnkySux%di4sLrop}U z-is3_P9SF9iSl&^+uebLwU^FSEa6 z=-eVAQHdaQ(Pdc+10l&A2MS83!8o1~HK|mkVObEv0WgTa=65g}O7dwbD?t(cV5(9u z7!ZR2Q4~7oy@srV-sZc`v;JE$%?k-Y5RYo0EW*~c=kMORe)ZMoUjN>Y;`Vy(ulqp`L0^UVGOJ^TG%lochJ-Lmh;*G~wTtC$(ve(qlN%^KD zh)>0GWtQ=^_hK1_8j-21X37Krah`M{(g_${*6BK(Xw?WDI0C?vcAB z)NeDkIg_GuGYAh3#(4Var}3#zeF~>fpT-aTz$(t4KQ9qzBg*=*smuqVFUNaT-2gHl zWtXvd`VOh(*|;BGXeA{wF&#seQarOJNVEz_1UE%0SKF!!kivl%&~#^k-WM@32@Sv$ zfS_&FARLKeR`CZUS-0(oLTaFcz=5F?QC)zllqAG{#Wt8|T9m33>4K=Oi38zR6oU#TpAO3-58po>aOx*!7K z$_R4eWXDT?_K_btdEYxfbN{#e@IUFl($Vq#3n$<)o=J#6^Rh(Fijgdz`P@JM+eF7v z*(;+l`}VUVKKM)#p^M*U3*dO(Q+(uZCv>$UFfh zWlI7OV-9raBg!x=&!0h{lSEzDQr9(`reWK*ru*w<9RPCk^Ozo7hVS<2d{jOwAtJ(> zi0YH{`H++%apR}j^G*IPBD`F-U_{wG6HQgYE#4a*g`Rs4RuyCX3ZpMfoc}&?xXJ30 zfB$S**GZzP+!#v`*tP1IQ5Iy^c6jm0KY8@btKa>p;riK2_WkTPr_G~?eE#~PXWdZ` z*m*hJyyAy89?$Hcf-*!Dq=bg)}X@R?#%gOnv%&Ld((*YjO{5)mym?%Whnzz+M~eZ9zt-^EBh#`jXU#l(roAtv4`I)+4L>kSMsb6}oPA+Dh(Do^7 z+jSyMqq2R32^W|2KoI8~ilU6pO*4Zj0N}i%bR9x7k**Cc|Lt(GI`t-l2&a@4H;{x~QP| zu#7e@JV%*IR9t9!}Ej&xIMT9}ho2^K5nv*|k(AXRpsZ z%fr_tYlAHUhyi7A09*(7pu59h1+uvbeCIcTZ+(y$l(fmZh|uS`0m*+w!0BWv7oUAb z{`ikSC(l3sJk57LrqIsJ;i|XRTzi^?#0Y*mt<}pk`exWp?7iaTn8{8v_IA=V3U}1D zn!^qdQJ_v;MEX!(L^i#RZpu1y&7^1ZD}sik^t{GsB61aadA+0cc7{uMM+Ukfh?T5vwIik&b9D;AWMR#Sj6S3TB}B89q<_r*&0Irv4YSW4>wO;ceH`(=#5pcO-~=q0bjV;Q z@C2&?Sgr#1oCCi9VTT7Uj4aCzXQ-lIc4mfk{(9SWynbVg7cXAq*4B3Ny;r%ri|N5> z|Ds&Y6i+Wgs?A>6cKZh?z-RV%G~YU^!Y@SvQtkXH*(ppPp!M}B!mNIgegP6u{6G;h z1ih}@iMO`G7M7@wpa|JCE!tKQlghGWRaMj!WwYbwyec)PGFE)X4(vKmx}J;E>|nZn z`}n?hWL1*J;zv<{&VxlMEULKk7kbTk)oJ-s;|MCX?b~i29pFgS7chwpHe{LLinzor zo`11l=Jz3@pF4WUA_N!rAmN}0JbyCa%*iQsFMi|$pZ}G={V_mXPM5t1cYFF>^sI8a z$2?pyjKLPr^*)}PEtQDcRRDQHTQjF+>qGkcsC#$%_t*O_puX(V28E6hffq(U0p$jY z3aD0rwH4qEuOZ&`wg&5?-kD{Q+;!9;0<>Mgty{OSy?rZw6hxNVCmFkGnk+I88B5;h z2Aoc(Ne@uhb&~y?rb+LaC_tK@KC^pRSeNM^)K_2G{oLzNlX&X0mbu z%13sNxxe%KNKKo)kF4zZcjuoysxBB`CKBSUfY1ui8P~@Dx4kzHx2&q}MSo+?wf5fU zoa!5zqABSW6+y+IfPevF^adn&BjVGmN%W~{eYtu0?t3@Mz3D!E<{ICZ``(L93~Gej zYivLi5W%7gAcRKRqA#EdsykJ6n!Wd0YtA{|A7jk9*4}5IQ>PFR4eR^P*?X^M&bj6o zbIj2XHVn=(pfv{0CV(Xq%x50QeC)yCJR4;1M|=)U>F{5_-^cXy6npQ}c(slo%PyR; z2Iw?qv@xduw_16+Cgwn4EwjwB_kkl@uFo+u*g3~ir>`DMmSrgzD9x3$nVwZHfgzbL zA_hZ@sp5iMmKCHAAJd$}Iftrp97V)D&$yFS+{$CUgd|R|a}{56?X^7p?9(VKAA|Hn z{BOeF0Kuym8UhoTjSw2PmN*wtfU}$u3vUeAh$}in<+2nS19&!o1*#)q031SnRdgbO8O*^DlO=}9I2#A{TLa#IZH3)W zeEpnTzIMTe{`9tkMy=828Xi73-!(I=NgTc@9=5ft%VN<)faL%ykO+*xpb%8HQCSBK ziG?sIt5af`5zI1lXH$FQ70=iE=n_Dw}s>A z_lvYdiHJ%XZ!?&39*tF?MTzl;gv3bWM?D_#DizO8+ z=SU1Zm<$s)_F_V^G*Gn5XBla-8j3|oCG^~qWTFy10faEfd}kTBofFj8fON6TCddQ} zz+_Q8N_wOkUu$49lu#(glZ*us=Nc$O#6%(FFeU&Dwr${mwcuCmUy$E<<;gex{V(0M z?UC!=8Q172mS5*`&beWIL7i=K1QBS;4V|U?Z?RbhFc7@5%R%M;z+zu!rWo|B=E7v6 ztJimwmmAj_*V77VCZKxCr->v znx&We62=B*sn6xU<|D3%A)ok-Jq*`cvAw^|vDA?o)lYC1g)r3@!# zkPstDa8eYNfFMG-fm^b)>-W#|48e@UvxpRVo|AVDWzol#S6)e*Ha&q*I+zA2WlnN* z(ld#>uF?9DGDDW6e1wrt%1B&;b4zHq2x5U zUqg|I*n{9XI{8HWlDVfL{MQ5No>~M;i(kfxJa=RoiUX4Y%T@ueIEZQO#KUXu{^kYW zzWcJ@|C%pnm&&}pH;KdW8Yd#*0EUldL-B8X#X*n2w8?uQ_&~vV_+*)Z>d&-l zBUC6;p9My3u1nh%H>4j<`nv(9Y3Lq+len&|hAO%Aw+dTnJc+Dw>W`Tl{WX-bYF>}j zB1&+g1z>R+Gfb3&&}k8kjRTz(;N?pgzj~_0s}CV=WYr$#0-A(ih$#fETD67_J#;-f zowjQ9Wf#ixEV|jog%nGGC2VO_ABNQHlk@F%ENjk9b}R*AHGVS@P?n;YlV=jHa=V=~ zr92%JkyeSTP$ne`Ohihg1Rla|#O%t+fkj0Xi7lYerQmv`<=NR-%U4`^760f*w_-)U z6RrvpQ7WxOy=-*biUUzR)Gb6w1c*QuOgS?QV2C)kM6JvyX9UjVPpkz-a#>_z4x}t2 zCW$EI%#w`5=qyNzADKl7gk!;&h@WYl&B6aT{^$##3;~!q!h@}qcoa!4LPV0KikB}3 z4n3Ip@PqbbvrqiPg*RPv?yb8v-~Hy{H9U%wALbTVre*M^=E5I5(ySsdv#%8~=~k6e zN#(VOD7C(=$$rP}8Y#(QO+wK?*5*ArZl$Ok&qv=RrgSZG6&aDkx9_7=c*r zf7D90qxC_~xp<)9M$oYAmv9$(e zS&?%gjUcw)@0SQ6lH{6YjWCTk27n~3cL~XRkg;=)HIuRy2z8`=B5SW;m=>z4L^=Ho zuKeC*xb)I*V`|41-ftq%c-tUD!j&5S1U5Djf=E@O44Nnfa{z*41QHo8$|?j_-vJ=A zU~2>(>iomTfZShdo=zlag8vG&QVP^HFEbFalw)C z<-nX}gtcqHM;+#P8E$#ykG}fLH{AT?ci*`Eu^Y~6uGr=p9+;=b`D6whW)()A2el}0 zMm~m9HZ1$3Qc`53qpv{CvI%WY@fne#G+5$hdkV>Vt8ZR!()oe)o@nx%wkT3!uAhqp zF}4XnoB%wCg6?%H*|EYK0h9rh<%ZfFP-h7!U&8eISAgE}3mN5gSaf=?5q}^eTC#LG z{n9VLgD$-ALabiBik$Q0oNq9gI_s@Gdj3(n-HMDP_4{SYD;WPmVDx&0&@MwHrNo5w zx7JcwIs!mdHK#8klH#M$^RFmMlH?#vTJ4AcP`6u9Y_&V0LDfzIV;7^gsXkTeSJfO%&`H6~Q7@o*aXM!Ysv>X;x|?#WlSi zzyc?U;3pVi#0^P=A{#kp#q>wk64{(Y6v&9O79npb>(467O8!>K0U$0DWHOM+5iO{- z#lL~Gy6ca|{{%((s5t?m0sIjc<@y|h*fDVcwQ{C|4-Rz1E2eDLz53+aE;;Y2>;CSH zd!BvZd+%lr18aM}b-idapwPb(94d%6Q2j>)kg?jBfPxySq2e+iBuTs0-qo!OZRE#1$VUhj?#niyLjB(RO4e5^E5D#*4~%C)q?Yh5`)uiol*=ETJ_9;5qnq&0-}q--cG;zPcJtHdml7|~v5azvcWMkV$&#!%$c7L=nqx?4 zBAG^*uK4^X^PkNKwk45!HX~$hNuOra1el`xG*w+4QmubRcb0}kHy^$&g#VFJ)~4Br zq)C|xV=1u%%_BF2wJRBiAMSDVQC%7fx4!1CZ++nFH-F{A4c*;Oy<)`V4;z~4^ci4JPe+wtDJ8*{EnAA?j(aW6KmUB3 ze){QHzy8p)C?nvdCZLS6EM2VVgQ6%^FEEH*V`Ci*AIy?;Q*;D#0T9QfbqD}Rtbw@a zHk27$->;HKQ%uv@cL*u~03ZNKL_t)YBGd*8bP zd-hDBEWIRPt-1h!Hj(<8NZTPgHVwUtCGkUH645jg@uo;LGy}p?>n}5eP10@?i{?H( zh>!J?!%vM`VWY28nmZzzyKYSElaW|$2w`Y@!s-=-i7|`J^zrQGt5138y3hQV*PZj3 z4~~2RJqAKrqWnMVVDE;KUP8r1k3$mF2{o5@Sf-zq)H?()3$$Un~|H zVhAj;=KqhobDhvLD&(T}4kDk%Sc8-{4E3ub&vQkAdhwQJl@fi_H2?|B&1yw)p~nIt zErcNP1+7+=`V{K}gBes5CEtJlefZqxzkn+)zYIHf?HJ zuCY-H?&_kf2~gss)B6t}bMU0GdC#}_7kGZJ=N5-Vww-fzC=xOaZ)BPMH=^R4Rz(}E9PBM?<2iyv$Zrx<8L^a@gTJg_8aZ1CXC zeU|FqJow^6b4QJd;?eiav$50g>o)rvZifeOW#A!dCUFA*3gS4zAXGs`14CrnfH?7*p7Fc1rZwm?LxRhPwBR|d+p3XtrTF$u>|sjd{}Yb}wq&0r=-32;&T6-AZU z|FW!9M?kSkQLHftK;FeUkW@G_n4X@&Ew|iCU;5IQ`0A^#!Ja*P24G?cSdq_SWk#qv5~6G2cBkRh{R)feoCWJO1mI1Y?poMZ?>l zmP_a8soQR6G~TJOZQHia6*yiPrWVYMVs^*DAvo4BK;7P% zRI?dPo(yQcJ4y2nGU6D*0a1IK<{%RA=0r4DsODQHxBPm(xHJUtceuc0HK}QEqU*F7QD=g9Vi|C7pXvO!7~0ZVhI7w7hYvaA zpg4`GzFr7Hs{_a69!OjOkh1jxqS%X85CXuGMoiwn-EPP4)NaROq+Jv(3WG2!mc=o3I;}Ks@;%lZjKqy8mInibAXJsZ)~(xc!womm zMHgMfH{SR!n4O&+Cd|mKlr`hb!k9qBl3iPnjyZTj$e04hoE}6Rm~4tNR4%!8&Y1`P z104GxzD3+0#Km}tP&c1&X{e3FAPq^UsgFhDzoKb`zic4&bHP)r`KXClJX;fph&cGF zosbXp`c8fTqd0)(x%gmr*OP~{FNq+oa$*LI##R|5j2eKsHiyQ1@xjTYM8|;!4x-g`~& zElD(V9-{@2ViHSX>p9J+_Z+h>CAJ~LUiu(b&$WbW-uonmMDhV}Oy0rD+LPSN(L@FB zh0riF>32keCGV-s8xwlHK0WZjgY>npU5w9u_OrPD`WrAiJKMzj<|5&C3usfI+%SS+ z+3AgpIs{ON0YNfpGHL-hMfWb!s%G=TU)Mn*2Z-$@zmtTMI>9l(Dss0nm!d6De=?yA z@%hwr^gpTF9l-x)U!(9}X^NZ=Ou@56<9bp?huC{Ukg#i%l~iROUem)4Ls^qDG#7mH zI}u^ev-cinh}kB?Wby7$h_CErV(l@!o1_p@8Lwq4niAP%AW^OM5 zR#m_{-^X1ye+3U5_d2}x_&2dJM3Sg8E;NzZWBRNZc?YB-9L&u63|NzLf{55ThgK^V z9d&Gs6bO|ho*7BDVQ7{iV((LhAcYxoqz~E`X);ib!93Cbp9mBSkZQjG0OuUl{rae! zRJ*oKguCDG;@*4j<4Z2Ngue5g%jv17o=%pB#+)Z~Fa)$k^UkGb3Qjp{OL2E$4MLOR zph=aZ3&ab&B-I>=gfJ5RgF9`)p|o|^yY$d*Ubof6J4$PQ2pJK_K+X3|V`>uX!Dk2X zpP8lfnG4Fz5OFZN5fPjRSI(j6JL+};kmd0e2R|{NKL9XP7hsea5Wmk(ZaO@RrW7Hz z4Ag1Cj35?=02rI}?qav}%1K+Wkws2%0y$2OZBR|EWTnpw^amNN=*NWy77uH z@VY~ep#An+%gl_RF04|iCqtGQc1{*+EU|42vD`-*pU(~J08zW$;`l1EIORQBtz2dJ zjH3gPwK-c0vNjW3(b@pf%TNQ4kmr^Gg7<+myN%4CihFfmQ1K&A)7oz56p2a*lKjJ3 zOMCY0p<8abl`p>dYjpMZuja|gNhy>uxCR<~uoT+pw20fSAmt&wK-LCj>QsLMB{0l@ zg%#SS$=nR;8Wp?%{D;sz@ykgxOemt@Iut%CN+0cmq7)lF1-%S9UJg$mj z)l@c3{vZQ1fFudHape;To}lXy95lofph_T4Sq9`|!lsTf;m89#?%sS2-E#evIP0D7 zM!VgPMKdVY-d0{VafoMjuXotG~;jDsyT6Rq<(;rZ&bUUfO{eMryZW+K7trj zl4g`62cUcXz=2WDoe6A+1kWEM(!1rvOkG2ok^7K=y-qGmez2~<^uO`Eph zhd;cIF2DS8+<4=SyldBPj5tPsyFLs_Ku(7kE~FwF9CyUjh-UMRn*r;~M5MuK3=oLsEqld(-StK8X9O?MlrrcB&I47+aE@boKHjs3F}a68 zmhh@G{@_#j*osLRbQ8A+-)O)QXg-tR_Q!5G9b780)tGG22T%-#u#zrGv$Trn6Z@v* z8aOb9IKhcgpnB4p6PQ>fG>B!y)yAYJwyE)4^Ll)aco1fdrfA?fr3y(~Mpl%S39`Zz zYLQx1PCz@UO>hZ zGX+O^ToiN3Nm`YBGMEq~qb&f=^NfTj1Wh1HY%Pdcv^APa3tE#903ig=BnLYeS^rx8 z*T_POPDIXm%JYmv@YuR_8{KiooqWX=SJD+%T#3z_H?wnY?gl!z`8GgXUuQ`8ZuB=| z*5WEra}N+{bYF7AR|Y_XLj+E?#`nF!KjIz_;>`dLIP_feI(X>b1)dvt|Ap{B_`n+H z0A|1kqN)N{6;o9O_>$Q>xz_D5Cij5)mBnk$`oyP?KJE8E-5BQ_?SB#hnm06WY@XZs z#J`*-`-IdxG?`?_u{k))r6hQr8d=x@nMq<&xswPY)YVLMlYlm7G%?vjhpd1!d9{;Z z!z9X){x{p@#&;S7fKu5sEd8Xp!16%yzf4oZOc3|yjDadnp}t&3#5tH+V5}Ge@7Lae zdv3g#R;)UN&wR(P(z0bsS(I(kg~;ZD2a!Fm%XER93#{ya96RNCo;=*de$Q!PCe0D3 zQK!!^K#&BZob&+JQrtir5sj?oKF^wwnA8%%fY_X$dFEOC_{TrSHP>8=4I4J#!3Q_; z>}Yxvxlrc79{{y;;&v{J9zf(SDL8QDfV>Sh8nSChEHzY*UC1&Zq|__|{`#AS z&SUW2=Hqd_bA5BoWHcHW`Th&xKUBdUG|6uCRt=uWdE&ARs48Y(G5Lz9DwvCcF*(EN z`*wB0um1Osu7BhE|DnNT4D9;D>pUC2Vfgp-_J@z(_Q((3Y9Q5CjjgM%*i06G7IUhT z&b`;y4geeVmZ(WxMA%`#Cp7{MpC5TN^)33p!Ra)=HQBZ~eGYtTOEdsPd5<{4$Z7yd z1FcVr0-BMs)@twu8r6~cj1P>ZksN2<_m7J(iU%WZ zVSv>_W1H7`=zebA--rR=W;{TnS&sepdOh58&pr6=cfW@lufGoW-v1y^O-+w@W^Z#o zcs?^)UYnB4&!Of35>Y@Ssx|HeF-3R64P9b;gFnqb#$jaS!MkZ>+k3&^0sL>QHT|uN zUI_p**g2r8fYJq2MSw2}-Wx6p!b~?{x))IKMDeBzzkK1kV}IpanCBR^&PSKGK+XO? zb@w+u%x*R%Oo)r$H0q#BWuVB6H6}=jKmY~=`Z@AWJVztWEpQCqGwPY9nx&Ui|KOGVH!PgV zV8GDEjSu0ftFFQifA~Y(amSsQ+Pw>Iu+Z;wKH52u8&!7c{wO;kqHZF+e~3JrvbGV) zh$K}PK#PL^NW78Oc<7lp4Rg&3===jfF!)kjlkX=}}cuCM|fNEDd^H zV7kYc=@VK@4te&iANcyaRvdJ~kLI7*!6P{W&36$1W_CRC`iHOo%*PBV0!!Tj7J0ue zokaEOW{y^u#w2L~jo1Slisyle8=SRzpK3VYV3>W3TYqC0)}CtaxBeL5)Oeo$x$Z~w zNz~{$g2_N+QJ>Hc85j;=h{=j8l0+1iB-M0gm<)i4al*Q#UEH?uNBp_Z6?pQ=r*QV! zXXBV-j@HOMF(-*xPFVG-@-bh(iU*beVhz-xnB6yWm$GX(NUCifc*AJV3L!9aZ3(Ek z2`E4b&N;HyviBa-)6;n5kw@sd>#paUZ@!ssz4bQUv111sa(2x^w$*XYFi27le-o2EKW%q0)#4^r&WAit^iG}=o9M;qY~ zpCVE41&Or~7eXK~kq;JC=}?r+u41)VOZR_v zScf+-`9q5SIgUWXp8&9N!+-lzxGA)B;l~Uru~r%b6oO&zK>)KHi(8!+Tr5TlxWHq3$4VC7R=5lE4|H~Nn5oYGihzQ}^$RYo=% z=;WmfM46c-UywMf1MHdL#Take;4EXbE%TUVtXcwEJKn?n58g?CzvUUe>#n=#%rnpA zQ%*Sr>(?Kua(zg);pnIXrEJk#FqQ|)vJA{jRaHmsMFpl5>?>zR6C-9)Qpsjuz_1qsI5P_^wl-3_ zASr1T1VQIb6gHA#nd-$4)E-k&r>A;Eps^?;*DD4nft1oxiguZ}W7mXGzf*%^H#`KR z$5-Okxc2psp&8XGOAR;ScMP+sxp3*p63DT%?}6Z%5H#ybCK-i07MSRO4_WE4d$z}q zZF_>gf5kJn^Uk~I>Z`BjQ%^mW-}I&vap{( zl;0=#3#m!YVKf4l1UDj?RGO3E&m7ry0t3b{U?ZuPwJ&(V(Yk>Uz?I9$RTVfem6d1j zn5#<4s(BA8x0#&?_Uaw}KJ4^2M+AsB zZ-4B@b6jsXmUJXKD>I_`&sw0YB}$@5MFWEch0Hqg5_wWGfG!do2qBXA6$We12=~4)?XrW=u%%A|#Z*T&*+|Deu5h$W4 zfnbRTO9oXSZyo?K>th z+wCEEhnV#pqgnh>yZn6j&i5R03$!!9GgFLvB0|jb4;aNa4{*jDOVLV^Mhn2p^3-i( zfbHE2{1cnsfb$Uk)Z`>OAnF;ZgeB)f5PS|EFv1jaQd~;tI5+^MGw`0Na-ORaa0Md- z3HmB}pl;uAQ3lM+fTw2xyY!IhH@^En{@oG3aN*zNon_Agg9{s&yVDOJqX%NKszk|!%!QMIayIP?)G>WMi2F_RH#KVIb-gCJp{af6OIqC~UKQl?5{3Il;8 zeSOoZv-z#DPuJify`NN+(tB#T0LjKWx^20EIp#2k4nF}DB0>;ACPgz!MR}FI*(syI zVg@xNap_fJAb^a(xgq2kku?Er3#=FePmJZj6d@D^&CYi5=%Y{I$tO4SEw|i?RjXF= zx^)N9{`>ET)vH(Ipo0$LwQJX6)v8rkyLJstOiZBD>0rr{C9JN(-0%0vRTZXZrpYrqkk5dvfP?mfI^%VuoZvW2&A-$uK3?ZVX53}&aNc+b=n&&+mFRTXgv2+`-h zxeV&hQA7ZXI6og(K1O{B6sPs8pSzv0K zdB+|`uMZwub;OpV&-%bWzV^(Iex^OXVq2Pu263B@i*K&y`R>g|HyCL0$(v6|GNQhy zXK`^g9xz^A@H3fSQqNFsOkq&=07y_4|G7-n|D;J@quQEXVkG2V-Mn)M~XbF)@L5yN!wQ zF)UrS99mxwMNy#N@1x)Eq1)}EEGr@+Eg3F}KB~&m?CdONW@b>9CA^pXdyrihBQ}oF z^Y#3kA2??W(6Yc-F8(H#V)zK62T#oxf*{#B2@EDn0h+2?TNVCc(ePggGobCo9iL+) ztnB6tG)msGvnl0aR(cXIRk3eNTh2*JNVK=EsWZV(s^C% z@iR_OZGLLdnn;xlqebeoPO>9d0wh*gaW;xY#3COWkrT&Tz_Jcwx(m2+a6BOd6h#T$ z#X+=7$0ArRdF3;mZ$gywnS*{tb`Yw?s;PenbLZ)&eYA3*owF=_i@N-J1aXj}G|UoP zrYv`2*s@wAORV6iRlN}Wn_V{N3_zMQPADgvS6ci`2y8%F#4tcy#F-6>qJsA&oMZI6 z0aZzGzKw3zVREXEscA;P4=h=GD{|BEw=H&N%$!6`o^!LKSY92oT<$zgsGOIb6 zL#$m$puo(|gYsMz8d*$RB+nZHC^`)h2(U~xz;gxzhnU5dbVgZYfQgLg1wdd2kWCH| zGBO1&H^q>e`$)*1-h|R^GVq}{9p(d5oKAXvU`m=F@lg&Hp~_O`Dp(6h1uX!?uq>v* z5ZTv8r|q1vY>coy1A65^+XIIt3>gLz0}E~rFVr#c{`+wMf`=iATWDEu$1toJxt#2^He?BOa; zRTbD(0j>i2J)qkKcF$JWH5D*D3#>i(*eBk2_V0cA=r><5Qn@#0Lg$h5_w|@#1_Xf4 z(*2*v+Dj|fEAl8tgir&V0rml~9_&5Hd*&s#lgx~=7 zvhhRHQbE%>#jtlD5Y27MoJJl2h@Zsi8X{~$oTS7AN_=~?CZNeT4BB?*!PKOE;DJZw zoXNpiCG`=jGHB9H!BX}@L<2K|2Nfl=b4U)yEeq;o%&iPV!y4*;?t$2=D{)G^ujM7)ulgmI;}007Xx=WIq+N zm%NNrWMOb{tN}Gd(MqfBa&3@h(%Kpg8lo&bMYDN2J7-hSCb{`+QfLC;z+7oGUkFUT ziYc1_S20|{fQyfr3I`Xx>y;k`#}H&27F+46+l|!(5YP=oML&p$edGA9!Xv(WdPdGvyk0{ORxi z`a3@GN1vEjx?=0d$sS?SYbx#IXH)Sv{QU5>1$6*T3USEs7kushtN--(QW&>7{t$uL zA?~v5JrHt1WXU>%#GD(F%)wb6{nB+;Hjsi1MA5aF0I=7@fzA;sRp?|{4ue2qR{&ep z=L%0iM20!AM8#>b$N^IiX|N3$0bIT0(JVI>MF&EyH=ILG^_Ir6Ck_<@Mr3avBsZR~ zWL_j;gX{*C69uYo#IzG+m&**OlM}acMsGAnKOc86e13R`oo`oO%=yJUx3}>u_84qe z7klvP?yI}JcN!$)0d{~Zi8O5k69rgfC}x&Y6D=_jYmT~s{^C|I>}OJbiZh1K4>+?Ww1t0W&)%=POU>^%y(%09$tf+xN6Fw)PF1KKRj3e&op4 zo^*A3Pld=SFmJfNxlks0t<4jylb z9UOCa_~GvuIzQi{U1+DBZzrFxo%zI$QO77E)Ew`qJ{gcW07Jr6dJlH$5AOpw5zioS z2}bTQ4ib{?0q?~eXcCo|9XzNjN_5?Tt{DmhWV)~!alMNipu8Tlh`*i*EJ<+TeMKAu z#?CQZsr@j(fyp^$?}4%e_RKJC-cHy&nW5`e@YxsspMUwb^FQ`qjkONIoP|BS7Kgt# zkNL!cW;+9b8PWDYU4Q`>!S<5fZ@AzqAG-A`@A<}_ts7T*S3@ewWpM{3-Q6=S!9=Ri zH>CapQKM^wwTk!VS%9@fRmlk*2n=IM@&X#DQiYWpU>GZr62dB0AhH0o;v)+So@EjI zp~0q;j7_aHLUC9~yDEwZEOF*qfd$bt$wU&$94Riq#1wS5j)5C2#YN!)QRzjiUz9+% z5M-#FD2NF{d5v^IN%1%cv-#NYQO82}E{5fQF6Z~P&&9RFfb$F&KrYl=lM)3o z5rI^@D};ez?SRa#&oF$U6*-KMV`BlAX`XuhZ7oU3sE~9CDuW}{w2Rcv5Q7bYGZG@e zgN_o>VjKekq{w-_NpYa00bt@-89Aw!N=K+FIqwUGFC}A3S!yV!etO+0O0KOe&f(=l zk0QvQ3rXgeIZM%TK<0rw#046&B4_z!uBT$Hgx@w{ig$P{vKj5AJTn;Q52gW);s|}2e5ysm7to#%e!Q@?xMo8NxPyf6Pe+3|nUw&$%4I7(pv0AownK0CH_?X&BSddmj6 z9?X`9ZhY(058iOv%;eLDKl#9hv%7nqJ;0S+kOO8QUU9h+fh?99y zN*r1u05K~Oq6h-9_(kp_7pElIzcph~Wd4_Yc+ZUCv`Ob?nuv^Jz=|E1zRFn?$CDm9AB==QD zU(C@|((P;C``QPps6=B)1lrI#viOihu7Kbj;2oh+gnn@HremP2Tc(?YnXe&Kty@YEhtcK<=d$MNz3( zpks*Y`@ALRtQDC(7^u7{_1ppnP#_qv=5}C|MK6gN-U;EBaBfoTPE_JX0wAv2MZwrL z1Kv49=v6J8dfp#@`m75+@h4f{Dqc)>|0n5-h93bU58d$In@J*`A9Zd{8yrmVuC?j@ z>(0IJrhodijkkXD99PZSjs-byU=R?i3>&J;J%Lgn2q)`8tn(JVy`Y=FZ~#ms`Q&US zX2&e*AaZb)iE=pRFpSm-BRLMqTGFJZ(eQ()WF%`c7;D)WhWAcWYJtSo&nOC@-)B@M z$m{OpJn{4lqgOEX3t+YsAAa~qB=)_DD<+Nw)QFfG(G1Ub{@~TX{>zD$ zb%2%QjFn^HBd+LE3&UozpJ5S&C z#9c=?A7F@CJoRMZ8d><186cPJL!`O@2Gn#Gqkbsn6i`PbS@;}Nm}QxUGiM-8V9Hk8 zw(=by66=wX%*TjrWCUYL^uwY&A`SuGgR2S%9@HF3YkC0IaqCc5uqr`RtUigkuW5NsEPs5nx(*@YYfKQ;1!)f%f^6}9q_6N(DDgjd>q_q z5jrhUmNB-P7xoXdFdP4q#WQccCtHuimXbNCx8I ziOPz(Qn8>c8I#lC9n*x_BBQaDuiSFM@Bi(uA9MUESM6;+hZpz0UfY*-x6rkL@1tA_ z_l6v!uJ7wJ!MkkdGmjp>?dgYKdH;{Td(O@+j~@Qy##@i`WjA9mc@|l|rMU+ix;r)` z3teOgO;tv^%ZqrySq5t55@Du9AQA@{B@jk(8-gHl{4L3~0VYOfi92lrW3(b}5O)9$ z0l_nhiX>ZW$yBIzzjBhnb+!j8E1=s47ZoT3V7d?VDsaC7dL^h=0W*E@t}d{33bb`f z`~`r(Z+OESZa@9>(>I)R&N-JIdg!4~9(w4ZPwp!m_V#-*&%6-u-?(w(G1Jr2OLy$p zvF85!Hy*on>*N6sKYZ^|fK&w9{@A~~wd(C!HJ$}5Z8O$PfLDwI%f>+yW5UsOTA+4L zXt#kpCpMO04O4D`R!(T;#Cb+!j5-XciU;++dY1yl@Ifh#BO zyw6S%cJ(q|bHE9kKK2*?^KGm4Klt(IGG{L&92VQ=91-C8Xmq|~A$9}+c5i?Bum^9y z@}2kHe$Bb}+ks%Ch*n=cHkBJFJx~_lUIE%Y3+yg39CFN=w|(Fb|G)RF+W(M|i~qU4|M30K zrOkbT|41|7OX28ur`JCD=#Nj_c-IZ5ZF=a=6CSwZ+LOzoJLX*l$%rSK+&mLvkg1X| z5&?Bfmg~8gnUYtctsRu2{W;4BSuX7Ya^6NIBmhGMvZR_|PRhNiQoFQMWuI4@zY>7L z0evS#p!D_MbYBR-mPue&zg>Rv)1UeM4}9SLUmhD9+iNK3&-3vopLowVuD|+Q=d}!D zNeft}I)JrHgaBj;&#{i|_U%?}GB$=3=0?v2h!1!JhQxJ^ff#QPNL`Lq&TqiBauTN9 zEr2~eU{BBDwZCxw4}Rl6f9c$;)&7}>)jkn`#mXs*VORD=b4f&)otj)dJvDjYBlrBv zX%F0a{pn9Ue9v*4AHVNt3IztBm~LkKA=uz(uL2-@u;YPej$s0rU&fq z5~hkatv~kETYu-zzxuA_D_1}JV&eY`1^<^U2e7w;na%cR9)H!2XP!Lru?PS4l-o9Z z`@-$dJbqwzdJ<(J0rz<({s-+${yMn?oMg&5C_zYEK-~37bPI@1N@9$z`_=%JWXAIv z^Y7F~+*dn)4FCMKRA_n)7GG$4t&FgzJ(;#BBR8;6>KsyJGwS*v8;RsSD zvBUvr9R!U?hy*}34o)VbXu3qN(%63w6uQ`}m<$ARex?NVJ%QQqc^CfHmw)SzKK+~4 z+6A3}7yJJEax5gvFSg$o3jWNDzx+=h|LXTI`-lG}Gah3(^H>HfX@Mq`7%UwFFBt>%8xtWp>KzP+_-+1@m{nJe+{Pbq# zrF|4dZ~S8yoO1hP58eApYZ#r3F_r=2xe@@?3$)w9&9(9vZ&Gt`ggRI)Iv$V`fSAZL zD*mGWh9yi}JT(hZ%3pW?Kq6WY5oPl0)Y(Cx-}Gdc3)`tPwv>d?z4aKd!N7ds&Boc zWkny*$%JT+wSbA1Z~&bg)XBkl?E;>Nc;pJ2PR&u{AC-WWa%!bo04fK}6hN;anl8ZO z`yc(p|MmH+esS#q2R;5`zWJ*I&Hq zZTqh~^ogGr{2%^J%sf(aIQ-eX7LWO!o72fc19%><4S!$gJ&JyJ`5m`zIQPm+zxttD zHe7ZZ`-(bNJr502CJR3mLyeCTM1E96;=pPd@L;cnM5+Lk9@KY0<%zS*(tAGmyMOc1 zKltPy5D~u=-v1}L_F}@nDvQ>q{`ezb`oVYq=|T>HtN}V1vn9}24s>#`T6v_1jc@>z zQ7UK00m7{X7N;z&yiH{Q_ezlS;9dplmW0Y@Tr$(y=lqASe*6zV`Fl&2t=RSRi2v!_ zeBr>&#+&Dc&yVVS)IEDUMzJ!B?Q=10Ep*&>_bsPf{`J5Ajhi=Ier|VWa)kj?E^f)( z$vNr)2uN}2DLE=2JBssCAczCV0dRpBWU+d`b-Um7o{#*$7kuawf1c&7;-&chqn;n` z^QR5}?|l7>ANj)n{ilDibH}zdtxVj(I~h15vFs>!5JSt!5;#}+pA}Y77ZdX`dKP)V z?+8@@$mBTTq_Z}>?>GPO&yIV;$s6Vy%g+=3|6D5p_w|_CGr4-hRp0pcci(pX=|8&Z zs<-!Mrj}VFCB8MmkR|{DnjtNL#oWhACbGPZlivEyo6daa1s9!k>f8UR)$YvxwBG6G z>DaMt%erq}^10vo?l->lo4a;yTMHJyfXoUPo2&VcRF9KEGrs8&f<#?IGfUoL{H8U!+_pmOpfu1rPHUL z`L0V}_r_DNJL#>z{O#o{R`1x?ar`{s|4&2!{;eF$jIt~`58iwGi9`ku-FL^y09yb! zc>Ph2tlsayEr%WPs#|TAmoF5sUp_`3%#7KYspXG8bkA|~-9s^Y5)5N34td2<4=!82 zYWvHudRYW``FQ#GH+>jjE_*PFGVYC9z7WqWrp@Ov_UEIG#aw^+{a=3npX8YruViDRKj9M#5r;}|uD`Nsb8`@j7D|7PC5DFQSbn6INz4K4Os zY-hfHo@<}OFSQu+)qL&0{QfV$|4%ZO#q{}7djA1Wz=a02FO&09e(t3`^83I1{`-3TEWQ8#4{MMX+kivnX8-^I M07*qoM6N<$g7^uRB>(^b literal 0 HcmV?d00001 diff --git a/share/clipart/tux.svg b/share/clipart/tux.svg new file mode 100644 index 000000000..e3155ebfd --- /dev/null +++ b/share/clipart/tux.svg @@ -0,0 +1,175 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/share/examples/.cvsignore b/share/examples/.cvsignore new file mode 100644 index 000000000..282522db0 --- /dev/null +++ b/share/examples/.cvsignore @@ -0,0 +1,2 @@ +Makefile +Makefile.in diff --git a/share/examples/Makefile.am b/share/examples/Makefile.am new file mode 100644 index 000000000..f8b9dd9e0 --- /dev/null +++ b/share/examples/Makefile.am @@ -0,0 +1,19 @@ + +exampledir = $(datadir)/inkscape/examples + +example_DATA = \ + README \ + istest.pov \ + gradient.svg \ + tiger.svgz \ + markers.svg \ + i18n.svg \ + stars.svgz \ + text-on-path.svg \ + flowsample.svg \ + data_uri.svg \ + tesselation-P3.svg \ + art-nouveau-P3.svg \ + eastern-motive-P4G.svg + +EXTRA_DIST = $(example_DATA) diff --git a/share/examples/README b/share/examples/README new file mode 100644 index 000000000..b2404c84f --- /dev/null +++ b/share/examples/README @@ -0,0 +1,5 @@ +This directory contains some example SVG files created +with Inkscape. If you have a file which is visually nice and +demonstrates some Inkscape features (not covered by the +existing examples) in an interesting way, please submit it +to the developers. \ No newline at end of file diff --git a/share/examples/art-nouveau-P3.svg b/share/examples/art-nouveau-P3.svg new file mode 100644 index 000000000..d32aa97de --- /dev/null +++ b/share/examples/art-nouveau-P3.svg @@ -0,0 +1,475 @@ + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/share/examples/data_uri.svg b/share/examples/data_uri.svg new file mode 100644 index 000000000..b5444128a --- /dev/null +++ b/share/examples/data_uri.svg @@ -0,0 +1,110 @@ + + + + + + + + + image/svg+xml + + data uri test + Nov 3, 2004 + + + Jon A. cruz + + + + A simple test file with image data embedded directly in an xlink:href using the "data:" URI scheme + + + + + + + + + + + + A simple test file with image data embedded directlyin an xlink:href using the "data:" URI scheme + diff --git a/share/examples/eastern-motive-P4G.svg b/share/examples/eastern-motive-P4G.svg new file mode 100644 index 000000000..12a83f182 --- /dev/null +++ b/share/examples/eastern-motive-P4G.svg @@ -0,0 +1,1435 @@ + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/share/examples/flow-go.svg b/share/examples/flow-go.svg new file mode 100644 index 000000000..b55bbc82f --- /dev/null +++ b/share/examples/flow-go.svg @@ -0,0 +1,59 @@ + + + Multilingual textflow + Text flow with Japanese text, and styled spans. + + + + + + + + + The paragraph contains spans of text styled + differently as well as + forced line breaks. The text flows from one child of the 're­gion' + element to another. This example has three regions, shaped like + the letters 'G', 'O' and '!" respectively. + + The text flow algorithm + wraps on spaces if it can + find them, otherwise it will break in the middle + of a word. This is needed for Japanese and + Chinese text where there are no spaces between + words like this: + + + + If you need to implement Japanese + kinsoku rules for + line breaking, you will have to insert Unicode zero-width-joiner (zwj) + characters to forbid certain line breaks when generating the text. + + Here is a third paragraph. The text is in blue to + show where the second paragraph ends and a third one begins. It will + not win any design awards. + + + + + + + + diff --git a/share/examples/flowsample.svg b/share/examples/flowsample.svg new file mode 100644 index 000000000..598da4e7d --- /dev/null +++ b/share/examples/flowsample.svg @@ -0,0 +1,80 @@ + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + In a move that will grab Apple's attention in a big way, RealNetworks is expected to announce on Monday that it has broken Apple's stranglehold on the iPod. The latest version of their Harmony software mimics Apple's FairPlay DRM, the format in which tracks from the iTunes Music Store are sold. According to RealNetworks, Harmony will allow music purchased from its RealRhapsody music service to be copied to and played on iPods. + قتل أربعة أشخاص وجرح مفخخة أمام مركز للشرطة العراقية في مدينة الموصل which includes SkypeOut في شمالي العراق. وفي الفلوجة ارتفع عدد قتلى الاشتباكات بين القوات الأميركية والمقاتلين آخرين + In a move that will grab Apple's attention in a big way, RealNetworks is expected to announce on Monday that it has broken Apple's stranglehold on the iPod. The latest version of their Harmony software mimics Apple's FairPlay DRM, the format in which tracks from the iTunes Music Store are sold. According to RealNetworks, Harmony will allow music purchased from its RealRhapsody music service to be copied to and played on iPods. + + diff --git a/share/examples/gradient.svg b/share/examples/gradient.svg new file mode 100644 index 000000000..38f6a16a7 --- /dev/null +++ b/share/examples/gradient.svg @@ -0,0 +1,1514 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/share/examples/i18n.svg b/share/examples/i18n.svg new file mode 100644 index 000000000..ada40b21b --- /dev/null +++ b/share/examples/i18n.svg @@ -0,0 +1,415 @@ + + + + + + + image/svg+xml + + + + + + + すべての人間は、生まれながらにして自由であり、かつ、尊厳と権利と について平等である。 + Все люди рождаются свободными и равными в своём достоинстве и правах. + + يولد جميع الناس أحرارًا متساوين في الكرامة والحقوق. + כל בני אדם נולדו בני חורין ושווים בערכם ובזכויותיהם. + সমস্ত মানুস স্বাধীনভাবে সমান মর্যাদা এবং অধিকার নিয়ে জন্মগ্রহন করে । + પ્રતિષ્ઠા અને અધિકારોની દષ્ટિએ સર્વ માનવો જન્મથી સ્વતંત્ર અને સમાન હોય છે. + सभी मनुष्यों को गौरव और अधिकारों के मामले में जन्मजात स्वतन्त्रता और समानता प्राप्त हे । + ಎಲ್ಲಾ ಮಾನವರೂ ಸ್ವತಂತ್ರರಾಗಿಯೇ ಜನಿಸಿದ್ದಾರೆ । + Arabic + Bengali + Gujarati + Hebrew + Hindi + Japanese + Kannada + Russian + সমস্ত মানুস স্বাধীনভাবে সমান মর্যাদা এবং অধিকার নিয়ে জন্মগ্রহন করে । + પ્રતિષ્ઠા અને અધિકારોની દષ્ટિએ સર્વ માનવો જન્મથી સ્વતંત્ર અને સમાન હોય છે. + כל בני אדם נולדו בני חורין ושווים בערכם ובזכויותיהם. + يولد جميع الناس أحرارًا متساوين في الكرامة والحقوق. + सभी मनुष्यों को गौरव और अधिकारों के मामले में जन्मजात स्वतन्त्रता और समानता प्राप्त हे । + すべての人間は、生まれながらにして自由であり、かつ、尊厳と権利と について平等である。 + ಎಲ್ಲಾ ಮಾನವರೂ ಸ್ವತಂತ್ರರಾಗಿಯೇ ಜನಿಸಿದ್ದಾರೆ । + มนุษย์ทั้งหลายเกิดมามีอิสระและเสมอภาคกันในเกียรติศักดิ์และสิทธิ + This is a demo of Inkscape's i18n capabilities. If you see squares instead of some of the scripts, this means your system does not have the corresponding fonts; visit http://eyegene.ophthy.med.umich.edu/unicode/fontguide/ for links to many free Unicode fonts. + Tous les êtres humains naissent libres et égaux en dignité et en droits. + Français + Tous les êtres humains naissent libres et égaux en dignité et en droits. + มนุษย์ทั้งหลายเกิดมามีอิสระและเสมอภาคกันในเกียรติศักดิ์และสิทธิ + Thai + Все люди рождаются свободными и равными в своём достоинстве и правах. + i18n text on path: + diff --git a/share/examples/istest.pov b/share/examples/istest.pov new file mode 100644 index 000000000..d4f2eae36 --- /dev/null +++ b/share/examples/istest.pov @@ -0,0 +1,163 @@ +/*######################################################################### +## +## File: itest.pov +## +## Authors: +## Bob Jamison +## +## Copyright (C) 2004 The Inkscape Organization +## +## Released under GNU GPL, read the file 'COPYING' for more information +## +########################################################################### +## +## This simple file is provided to demonstrate POV output from Inkscape. +## PovRay output is intended for people who have had moderate experience +## with authoring POV files. This is NOT for beginners. +## +## To use: +## 1) Install PovRay, version 3.5 or above, and put the povray executable +## in your PATH. PovRay is found at http://www.povray.org . For +## PovRay-specific questions, please look there. They are the experts. +## +## 2) Copy this file to a working area. +## +## 3) Make or load a document in Inkscape with some shapes in it. +## +## 4) Save as a .pov file using the SaveAs dialog. For this example, save +## it in the same directory as this file, with the name 'isshapes.pov' +## +## 5) Execute povray with this file. An example command would be: +## +## povray +X +V +A +W320 +H320 +Iistest.pov +FN +## +## 6) Adjust the values to suit your needs and desires. Have fun. +## +#########################################################################*/ + +/*######################################################################### +# Some standard PovRay scene additives +#########################################################################*/ + +#include "colors.inc" +#include "textures.inc" +#include "shapes.inc" +#include "metals.inc" +#include "skies.inc" + +/*######################################################################### +# Note the Z-order differentation of the prisms in the object is +# normally just sufficient to display all of the objects, and +# avoid 'black spots' where surfaces are coincident. This can +# be adjusted by changing the value below. +#########################################################################*/ + +/* +#declare AllShapes_Z_Increment = 0.008; +*/ + + +/*######################################################################### +# Note that the finish of the "all shapes" object exported +# at the end of the shapes file can be modified, by defining +# if before the #include. Uncomment the following declaration +# to adjust it. Have fun. +#########################################################################*/ + +/* +#declare AllShapes_Finish = finish { + phong 0.7 + reflection 0.5 + specular 0.8 + } +*/ + +/*######################################################################### +# Our Inkscape-exported shapes file +#########################################################################*/ + +#include "isshapes.pov" + +/*######################################################################### +# Move the camera back in the -Z direction, about 1.5 times the width +# or height of the image. This will provide about a 60-degree view. +# 'AllShapes' is an item in isshapes.pov, and refers to the union of +# all of the shapes exported. +#########################################################################*/ + +camera { + location <0, 0, -(AllShapes_WIDTH * 1.5)> + look_at <0, 0, 0> + right x*image_width/image_height +} + +/*######################################################################### +# Put one or two lights in front of the objects, and at an angle to +# the viewer. +#########################################################################*/ + +light_source { <-200, 1, -8000> color White} +light_source { < 200, 100, -600> color White} + + +/*######################################################################### +# Make a pretty background, for contrast +#########################################################################*/ + +sky_sphere { + pigment { + gradient y + color_map { + [ 0.5 color CornflowerBlue ] + [ 1.0 color MidnightBlue ] + } + scale 1000 + translate -1 + } + } + + +/*######################################################################### +# Now let us use our shapes. We can include them individually, or include +# them as a group. Notice that we have two AllShapes. One plain, and +# an AllShapesZ. The 'Z' version is different in that the shapes are +# shifted slightly higher in their order of creation, so that coincident +# shapes can be discerned. +#########################################################################*/ + + +object { + /* + //## Individually + union{ + object { droplet01 } + object { droplet02 } + object { droplet03 } + object { mountainDroplet } + } + */ + + //## As a group + object { AllShapes_Z } + + + translate<-AllShapes_CENTER_X, 0, -AllShapes_CENTER_Y> + scale < 1, 60, 1> + rotate <-90, 0, 0> //x first + rotate < 0, 0, 0> //z second + rotate < 20, 0, 0> //whatever else + rotate < 0, -27, 0> //whatever else + +}//object + + + +/*######################################################################### +# End of File +#########################################################################*/ + + + + + + diff --git a/share/examples/markers.svg b/share/examples/markers.svg new file mode 100644 index 000000000..c681a62f7 --- /dev/null +++ b/share/examples/markers.svg @@ -0,0 +1,854 @@ + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/share/examples/stars.svgz b/share/examples/stars.svgz new file mode 100644 index 0000000000000000000000000000000000000000..ee2e120ca90d5d4ea5a6c3499baed4462194cb74 GIT binary patch literal 34102 zcmV)GK)$~piwFP!000000PMY4lO0!tDY4`sz=&Z@&NP zyKn#HvwV|2ySn}M<#(^X`u2DK^4b6WKmXhH`t0iaw=ceZ_2TRAzPE z{^_6px9jVxFW=n0czgTm>d#-j{r%N{|MuU$fBE7Mw^#r1_ix|+;fv2d|MQ>!eDl?D z@aDTWzx(_@U0q-6%J2X5yMMa6y3(-Ue*eX*m;dtFasD6v_~vV$_v+>6w_o3WbNlVv z??2Bs`SZ^nPJj7u`k!xqd-LY@`|tkv=4IUe<;%xszIpZf;Z!}zpQ}&Gd+*Ov`Mi{C zopJsBU%!3(;xE_Ve*YgHU8)DXbZJQ`eXidg&it^mzWB@6nucc|#=kxuT~q%D{onls z_j4HU`dU}s-h6xe_Va)Jpa1&#-Pzaa=GEI*k8X2!)jQ+9^EtkK@y+e`e|Yio_WS!G zeEr=mzj*cC%iq5EUU&HX_uqYU`}r$QyFc~w?|=W|&F$y6e|hoEAHKf*{_INb{x6?t z;k^0&M$_@{KH>MbU;Xa)Z~x`9vgbG7_{g8XdiD1AI*`+G;O_ok+%L&=)AE0Q`KKpC zJo>qoxbl_8`_u38Xa7b2`sZ(M-@bVD;_VB5iQn#ytl=|sj#j`I|JT3%w>TwE(m&Ta ze%BcEb>;KLm zpFMpDe&6l0tIzLW_VeRykJy5(=XbN`f4#bW{r$tl@~?U~r&`UoFW&qgZ(h9m zN*nm`)V}*mS*_kb)BQ((`Q6uF-@ep5zWDmjFaG-d!-x3(?RS58_bYHjH))Sv?7P>m zzrTIUl1TBtN56gl_OD;x##PrE<-0du{D<2zep~BreCRuE1Wnl&`R>x+Jf4|nNADL# z&mT7WdfjUue{=MI{`}o}yIZ>Y*Nd;8PV?)(^78%Z_^>ode(JT} zjHySvs-_f=a<7wyze zxitM+H-pcmk36!bV`}WtGoHd^{d8UQ*G{FUtFiRNT5aVdOXQ~Jk$Cf^XKy7j zn`LSSOKn$6x34+RamqE{G~H-lob`Xddb;@DeD}w1U){c9eYJOF$Nd?vzkc!d`>%Y? z+c$r_Q&ji+{KcE!6_)KaY}?~z4!y_I zAK9(7mK$x>+0K5{ZtX=sjJI38^dHpCwHXNEp_{hb8W_h0?{?H9QmqW?E> zjNiZb7F*!!IP#|#Z@zl*?b~;b{n?`Ei~Mlao7=Z9fB(fFzt*Ocp3%gA`~B^!-y9m} zZUC7CQhxRI>-^IHxK}@DgGVP_zxksc;`UFs-+uS%l@!&R@BZ!f{x0#)kab_Qd%blW zM%3%$e(~EszJ2@n*#Gz4SKodi+vN7m-BJJJ>#y|x&hPT-#rMAtt@=fJ`rEn6{N}}* zf4hC73HtW-`1>03^X)rFzWM6aJO94@_V~9a@b!ytzWVyFU;OW1y=5w2d~@~x+`f5n z^*Gdrh&&`^}%kt;j!Ld1iCvGQx#`Pq zlUmJ9$NG(gcF{9RF|=CeI>wf$<9#IBB^aevP}{SO9M6+xmc-@Q>ND$(b?H89dTbrl zWayLCs;5{ZF?PM#Q;NdlOzEQ-TV{Y%fUjOaq)kAljrRaHhTD^F@_tyMN{rPCi zJ57B>tu;-g&XiS?n!btGfHYBEKBmXXe)6feSSj;FG9ydbHOA389)6qAdr2N8uifH# zdTupVi&mwyQSqwOit5{Ix{sMOljy$Hn`UimR#IYYsV;r@<@etD61ttfj&$GBV|K5< zJf*n&Hu@lY`N)u5ry)YhFsY-=uzo=Xa`utB!A{w0Md>qE9nNoT4w6r#*mt*7%JF<%EZ zini-B3UNMFh;uwqh}KQ7%WrRAw@;*-^i69n{qNIG=UV0i)z*tQZ(jU0G|R_{e|^Wj zB|lF^Yq-swFoz%ieSLq%b?&kv*m*-TSMqbeqXe{`*@C5=`d$)?&BkJpS*fL*s_a*+ zB<(^idHueUmVBQw7ImX_RkSLk7S=k+KasuElkHsDr&-1=Hf@nslAyZEO+HLcOIEuC zo3^mTSwV=&x-A;JOIhshZQXUx(PTmPEXC3r0!boJ5>Bs!&9CEQUKNRCDS?EAE>YRi z=IV@vE(OGsYd7e9vYsc);>}x6j?Lc&PhJoTMZ&o+sSy1yL}^D9tf8Z_wsldtlDnaI zoU_Vfkh+lI)06AoQWg?ij6G%FBNR%rc$TQJtu7(gucX9eEz6phZ-FC|3S&#frrGp{ znu{q*(gI1MO>#y8b~MfTD7#;2yGhJ!34F<5#H$2k(Px~sX(pNT(hf0RG?y|-_1^m4 z(#BH9S+go3Il7)lUu%v|774b9JzAV`~afym8+t9eHW zMhSctXdgMJt6Xh*WY(2Nlz!*ErQRj_`HGD-5UXWLP-}+TNm5p;NpqwXv^2j-s&xqT2J5f&SS?wT=9SuYPc22>QBP5d-Y09tx4fiIwHI`C+wr~SA7)mnd>&aw#a~RS zOdp0Pm#>rZOg5i1D}^W5O0+U&)^frjvsbyMO@>^V%TeV^>Umi1zGP zYSC(tUn+x)vAexS&6?(=Csg!I>{a=lQdJFyDC=$TSv6@ITdTWkD%iEm+FIGWM2b*` zShmNjJIbhH&oBLn&#E2KWmRdlV7TaeYR)@SWczBZ7VYfDYSB}+we{WvFr)$X9pp8p z+;Y}?V+d5F!`2$uG9-9%{KvE!D^(-PQ__=btraYrQ^#b`vdi9~T7H9FqI>JL{KfFD z>Si}e%19g)eH|S`9>rWtl=?-v_8!Hn2Q43=cdt>MT_Wfiy_=aE3D0xQirUo*PHD|_ z(GS&U-np(bg^k)}V)*UM)kN*e>Xk9A{qv04&FP8WEhW!ijwky1)k-gZ3EKWwU-WMp zBNCf3h-GTXH&e~b=+Aadr61pq7@`-bX-X>N;)FBDu*IVm*j>9&YiKxke)|pYd>m~hTGTY^w_vC zvYJm>dRG>JG?4`NCb(Wt*$ykugWpCZQ%^35I*EyKwbVk>lkbxp4WepoNd7Hpq9$#b zdEgc>ElSLY4EDaXeD1QEVrULI!XPZ=r_tuno6^+N$}t;Nk(1q z!ExgDN!lQ_mWq@P&T^6pIpJnW^*IKCx|Fks+UZ;)UtWs-MjBPO)Jw{=kOrw&=y{FW z^*oJHstqYUk+cDx9brl7DXDt&RF|nKwL$b#?p(RTmMM;iYWlkrj3*r{1LK0|De>Xm z{gh*N;thJjnk98Et+k~FGqD4` zjFezO-!&UEEPpK*E#M-lp?Az0N0x_7Xa}sNr1a_26%JLFrfer-wfb~636>U?Zr=6Y zQldp`W?iw%WWDRm&9{?Hr(+I$ZcXR?br*! zR&C?0@7QhLFE+D2nHE3hFfMd0aw7CSWhBb%)+=n8Ob*Jk*}Lo-Eq~pI=jBYv>WTTu zs+1&H?V@mbuP?4W^)WU9;d<>LJ@|9Z_{JAsdtR~%8h(Q&?fgewstu%-(EFLmfK{Lm zs?C>Yzho6?Axdt_WqZad*iVgu)qXif!Ry!hn&}f61$asFk$3;}CPDc55)hdYwBzpo z`qglF$8eC}(rd#!$WjQUy!+SPuf*Eq<|1h`-syNZf*}t_ZVes|e$k(%hrw*vvgXK?<)^nGF8G|+VBVv^EPW0 z*(P|JTLzN+Bl4F!IixC|PDYSS3HfF`8-5rzg*-0VPhA>DTDkG$j-E6;dCk5)i-Z4( zV7v@4`Q3$>N}pl7m4RnR(kv6&E)v9Tc8-xjO!Ax#Z(0txl)285!Lg;b^LExT$xmIF zF0utQ7qS5>{<)NyzDImAob;XaRb&W|*OeJIeRXc3 zQT2874s#KRPQ=i(as4*>B5hq_5_=daHsq8Bu9!R@g(dp=2IQE%gH^J2+~MwX_FDSsg+O?AzWFpcFwRmo>%FC!yOiCbcHX zlDcROYK}As820Vra(j=wyMBst`{5>YO-oL8J(Fm65--V-$GJO$ULf-1&q&S9^LQ8{ zk8mM?opaCzB5#t_o#~>@EOoE1JL{P|d`9GH!Ixi*&HPxTo?DjBOWFW(JvEu@Bx#a= zjiP;WV_0i!Y5O-Rg@U1&9{#w#|Lt0$5S>6oXn`4c7tukQLXxWG(@Lag$ftj4b8Dg# zPK$KNk^y5Nn`}&(YE!>1?R%hT60EDq_*>xVWJfvpCUGmVo9apCoV@DD#k3~pM=I((mYFtmd8#~Ld9b*fk#1NXTbnn=mROZ|W$acA50p+N71$ipHg+KRI+Bt}vmw>6vSv$f zLpV>9p|>IM0?GqdL2E#&K?>qV$|7f9Ep4T_()-BakujgaC=$w8Mc)CmPVO_(ubG5{ z-&-oa`MrBG;BfitNX(Od^_w-Gyy2i#lD8Mu`FlZztACUkJ~|=Dc9u!GQ%bpZ=KEaj z6eDQ$o;_dGNuYs@2)(3}m>IPBMU){QPn#<}r<0zd3~Q^u9GKzj%zsbK|5jxWY3sj7 zDZQ-x_cXcVFpiASU$xRF*GlEgReA7P%EMoi@VabKQZtfBPjH3=v!%Esr4pL#K#s}D zm-LnS4EA07m^3>8>JC^!+CiosD6v9_y8zCXBDj&g?5hhPW{GD&*ShCuPO~Q*lr9M= zEh))w>0xvhQe5_5cTnL=>kvs&$&Z2|mPpWh z6CWOhQLwv?s~2d=jK4%wOd_3G(@YYAk>O5qXo7o0gID0|1dOVFG|rHehUP_2Y4ArS z1H-J=UbFA0cO`JboK9a&%11Vcod&*+RABMfkv>|;1ow2w{_IEY)L;jS_9HVLd##>|!M9aq}olBiAo0Cr||hEs-Z zL*_}Y5OwM+JB8dxmS&Q`TX#xXqWNkJnbimx2?xqIW|>zyGzer)BkX|hAa1VFC9;&s z*%Cxvz~m^BAx4o-dxF=Nok~KzHh^CmeUd3~OiZIUut0z$n~mrk@f8BXmGmrIRHFM@ zhH6S}5}C>%ReSgKnClX&^1me8CDmm?ajtzAxnen6ke7DVG4Pwg_$2Sig^G&BZGpJ_r|-+ zxL?a3r)hL!+&a)JIR=`Jv3_eA+*}{Z&!?7_p^Y+L|ZI8!A-` z_kUd9|8`Ai9I(tOH|kZ^yJ=QxHL%w~&}3Kkl%ozJZ>Kd45S1q&E0gpmcK9HlP$k%P z3;@#_NwWMdx%Z{5)G8xXk{6gu-9Vu#5hZ#3lIFmg2Ef+l$_tXY)QNNn<)iMUfB@G~ z;tGJZtHf1yjmzi;`mBBN$=`2}_P;4+p07#Ndjcg|&sJdcy>`x*%~4mK$QZu}`jBx? z?xCE=s4+*I5#Hy+x&osCF>U8@@k7Yer$R>0aH$02#p~b7!8+UTWy@vD>j#4}CH^r_ z+K2ArfK@zPclGGczi+>PwEYF{Xd9~_AFqse|2lqkBCisLEJg!9*;f=!6hr)7yOaz9 zs3dSQc7|M1T}-BqN}~k;(Z^PGEnCIN*|NNVKFf1FiUC~0%b6LJrTjk~E0h=aWKTFt zIXC-*O?DX`bD}JudF%xAPgm+Fk>gGRjo79f;P9ifERz(TqpVBr*wL+lBb%FeUW&2h zTFn+E3$5p3e|sLDxlAEBh_YTC!;>|0SPt^n7g#y@t(ukqS%4eFGsms~!$wSdOAJg$ z1+*>lI^YXUPq~~;l=V}#J@XEP+8}+IB6#Ki_ftil4De{c?7wsbTa&SMrc9J9(Gh;V zEYPMqc7PYV7Z;w$9miV-V6aFq#@PDMdT*VMv?6|>-}hLfM~aZ*D*OMskLCg(h~8s6 z>grm{!jtn&I;+4CmeOT}A>W7vOh-d^qNa0D8nTaa9dePox5)MCmOX&~x<<3si4TBH z*H@J7-<(+8WCD6b1spxk06b(9>*iAuH<3rqr5{&!eOn+bNt>-YKS*FsBqk)YD2X9y2+N%6*jiD0^{mVbcQO> z*g5_yH=-d10~p%N*lq3=nQQ5(SzY$8f0066l;d`4RWI!C_iCS(KhntEUifGFH^woCx-_mnk4`ox|Ka<5r)W> z{TEd@65>5OfSN`_jY;sYiI{#~@MFJZ3w~Xpu?gN%FSb2H65(78#6s7w#Rk<^fm`cF zp6zZSKO}FmMYo=0L=Y2&mY)^;pj|Q{W)hAIcy}Q{I>{-F@Dli1URQBjj|4Ehi?SO=iujUXjIloX4oh|M; zFE7(kX<-ji(8h zhg!8YT=houTyIg zkcK{SD-N+9f8GBEd_k3Izt8pkwlO-M{lu345BmsW4E;q*zRh&vw0M>gfuqqsE;Gh9OXk+2*wYtu%vQwxgzPkt44WMmfd!0#n!9@Y9o7>0Rl5#P63sc3IjdC`%r!=L6}?w zyQPP#nMG#D?!7eU?}xF?kHPKgl|ftAXYm3ZEX6wK7INJO6SmUjYEW6ZdZF3QLy0C~ zpct*3*PwbQ-cA1ph5%~&1F8bc9m86Aj5db z>>(dM6Pacy>xh0d`D0SM#7h!16~))29#^CB4uJp66ATim4Y)CEz(_zF1z@8a?wV%| zW9`|oF@lMR$m-2Dl-N+)26&bgwQU&BzKDiyW49fr#4y&bB?^E+2KA5)V`?*-V<)J$ z`K)2wrJ9qA+cE4G*ekLI5}N&pejx9CwKi=vVtYWvbI=6HpkKq;ed+fchOrDTVx%%) zWcZfxKEqfuJ!}MzjyY!oyn*l<_JBvZqr)h~AM};Tg?VfYvIS~vP+++;^b?e6l$wH6 zqE|>9o->S>3s58GJ19jxq92+u(=~Je(4O72TqnrYWxD>9*p!@ijI>Oq40bBclv4wF zg}y_ZR1ZF97&n*Bv@ndd!m^EJX?OIy)`;vK7xffMXF5iC5AkZlxLE;Aqu=E+*$4)k zvU3>5IgyWh&M?*&n;-)9Ep?yPITM89!j&;bQXD$ZQ;qsIFpBD#AR!Fl8yHbdGbc5sYp)F_3jfngb8dBoV{NvYUk1r`D`j-ANv z+{K2mT$A*Z8^)R9|GCeRavx$B1D+|m{vtl)C$)>$FWW8-U3>{9cK;hfD<^|h{cC%I z5`zmYkD#>y9&ATXJ7dD&;^H&B-efA5HJa&EWbN)se40In;PEjn_9*Z$`ALJa2H4G1KwWR1hhx$-rqt20lB}1V>!VGwGg}ih z;_1F4BCVLXNA7Nov4_@ipm50rq_zE&vmqyuD^rg)TwVu(-Ml#GKk82G#G%Twa^V2LDO*0@hzrp2fZ5E9UA4R8~T6Oe`_Dywv+?6y@2nE{r8mBa*UGFgm^sbtJ# z0B}?qvQt&p%$FcltYa06X!eV9{^N#@id^rtpV^ocWtRfW=EbD7jGPH9^fGOrX0i4$ z&eb40bAcdh>*CHd@nRn5V?Mhxe>p@2KbkoB)n)zkE-U+83Y1k2d(D%-j$a{|>4_?z zNi?meC*T+W(Xa_tM9r!P#b|P@fuj^PEx^%KuTm>=YR;@|3r@LDx$UUB=9T zL{&l=rbjdE7^hU_$++z8d3v&hIO$TUqVtZna)MsT^W#U)p-$U-t5-OLB1>`3EW>GKz~+9KJ_Dh z6_URS$-gNiug!}r1Hlq8XF_fdf8GDsP5jCq8=lLYe-)Cy3dw&wA-U62^vSP6@>e1G z36me?CMx0^q__2hk{^Jpld&~Ug8<$H0hA1rBM4+hZ9}j1Cy4>GRfXHBYxD~&$GgyW zA;~!|6Iy#PJYY-+89$T!Aec0xl)bo+fn+Y})@FhiIsLQ}7%mUolAFuPm@@LXLj`qO z!}y6-b@5i4OP{iJiID2)yC@P(ihk#HLVll??d+)k{`F!|fy%X?o(C!|4l(gXS&) z$uuXAIk#YPjv`SbwMeJbV(5B(Hu*spokfx*nei0x<|Gwi7%Wr^+x+XGP1XdNQwe6w zpbyxfRZ`C`s~OY@dCqBvFr}MO2@P7yXObU)E_a9Px;Uv$iD`Fy4LlRGuXpeokOJ#R zGNvEt3j(nzwLm`Y<)j*AOK^mG?1Lx!a`K~-@NXnFNZ6U(nR3$Zk}nWI8IagjHB)J2 zRWMw`5<-sK~WCWdNkDJI1lgS;}aE&|5RJn_R}e*St$(Rsh>B zUzcTD;_5aH#iyUc0xI-u(tA#ld?dZ0vVs$Dnv-rFm70xo49V0wcBK7=gq&rNS$LD5 zk{$*l2O3m6yiX^+Wm8Blzxb)57LaQ`qFa(Y(ovxabnNP3rIeoKPsrtn32N?x;qtdX*@mmN05urZ)J zZp(5O%IpCY10b9%g5iRJZHBbxlHSWLcv2+2@gYqRA$`Z3leX558OAbaJ7T1_^=)<_ zQT0R}j!DB5a3GxYmIRu|)hodL&n3Mf$yo+8z_3%TvFIAr{cW{?!B1m30CxJXpzKUAo1P*BttYn(SvT*Ow6JW z?<#--88=X=%W@xNK-sqUkuBRYr~`H~*u;Hka#*gC>m~LgU;q=dz;Kvt6#`9?BZS;H zzrQ=^0G*XMe~;X!>CUkI2f{l_+~7Vt%7LbPqR`8v8Ho=*ya$(LF=u%&Mkz6 z>=6|wGT&1L(9F&rK%xvpAjXk;&$c}~s433{oz=P}SV=XF1IG^?__l^vySx9+K$FmG z$Ja2wm*qa*0_go|xi6j4Qk463%i{*mRG|qQ*#CLggUL+><9t3-VAxTeOGS zt|6$wfBcNxZ#T5(SuXa~tl7rc2f>?rJ!#j3X9~ks*x_1;!!|coM77rkG%1f3a(@k% z`_Tk2%O-h`+)sH!`vCeKgp}{td+34+++?@dcZo_H)_{C))1LA~0}31$G;5{0NR5ym ztpkAN>3jb@RRFnsq}*rN^F}itBKNatj`KND!A~ytpVDXkW6S+zdp~`U+{Z^PC7_}S zwoS|4mhAsxpUAl1VXH|vOk23HkAxi1{tjymX(iEKyn3<2CF5NNK+NG8xev@T6=ZKo z?yC_X*9H%;?>G!taMe&RDMo=yF{H>gZ+4C+q7v3XE$uimn;{)^2dCDE zP{9wQhl{bBfxI4tnxvQuT7(@E4Af$G(LcP3%Q7C`$rf5ecKCW$?r(QIL+%qzF~K0< zt_ggDaeA65NH1yZRibLBLM;&QO@F4)2Alq*Q72|U2R88uIm@$hAA+pmvR~+gDd**m zC4jv69}8+T`(oRj#u%l*tRCN6A|B$K?q;DqJOk|TWVtWF4AJ8=a-T?<y#86LH9eq-0II zT`G612J$k>fXNUl4Lf3%6Ou>$^Z5ht`0U=2^Ml-FqATf_J!xn*zcC zUlf{zu30{oySu4%_uD=IiOsfs_?8Q|FY3hX=M3P&RObJ1xu0tK*#bQU7BnKeKfB6t^G(k2on7nhL6{XtBjDJSYg|}3WobKHWHZ$5*O3;5jV{pZIIl(2QNL7#Hj(? zro?MuX#!4{3H&>p3ZtSpng%S)*L6!7}H7T<43e6M!COIyyYFAD*%T zYNjuuzCSSy3x%!n2lIy}`tE30j_bcOi zo%UKEw54gj?C>=J~0wSA3gcQu`eIJtdAq6AOevHb4&D4;2V^*IhmO z^B;k0jVxdOP_8vtV`cQZl6Q=X0ZW~#JjUcebaPv{N)@aAM;M#E6bO|=L;1@GkNH^1E<7)}>BBLj zri;)mU^fy52iF?4EYDN!Xa=|^#6N}o>+TxFRGoNm+bf4N;C+>pkmLY68Li?-MjE05 z)0j5;I4X-AH~GCmv$#uE$*F{n9K@ zM`y0J*@7rWW7DqfS;`&CWs56$wO2`IARY4{v6xsu-6;x!{|@w1ao$M61oJ#)tl3FT z+TpaI;gLWHwlrcY&x31<+X+Swt=yIa4dV!MaEy}j>f~qJsRoG;Y)JE1Yj9*Fk3Dj7 zU>#0Nt?J-fqf`8QD0e#f5mWBWwT&)K@wQGpjBTb4D$eBv2G^QgzzFmYwp+p(rK5=~ z+;LPEJ0u1Iw&?fwC0Qd;rSF~TwdX+0)beglxI_@sX@I*N^GBJX z=c46ox`gExM#Gtd-O>DEKI`hKqm)l>H@e6s2c3Zk8Lb@AQ>^q9ie&a<)@XDg>3N#0 z|AY}*vRgH~RmFfqsYmWpZg(r87L5=Mgx;+5Hr02>@&}O_jVy@N({`fMn-4S;3_;y! zS$fd>y-i$i%8gA&px&yp!?N>okTyw9(pPnZnM4guW2JK22LcybCR$!mnoUy+Q=Lx8 zi=4HUEF1RFa|)tV$Dx}A7%Hbp6}v5x1T(FlG}H98u72|2RY~@I6dMkRdM&_u#OEYD zQ#-9nw~Ks7s9em8299g%VSH`^1W#c z1uj5W!zG+&ke7gpgo|!fkjKU_LW)XTM$g(bXPrr=+*{XG#L_6`$jl^QIH!eaAepuO zJSz~QtiNf)0mRYL3U#|IAP416QA;^#)@n2lTfyBXnHx?AZ9M`hr2kL5EKot3$Uy%> z#-9kovP-(hrl5F7mVmVsIVBp%6tHG=f%NQt>F&Bs#`Zcbc<~$etjjIZ!8RBVhS_1d zF4+d!O+DZpesbMuEebi7`v+TDf>G8ME`i(Y<|s6Ayo>|ST9fATlS96>-6en+P{Yt9 z`a*eswFxKl5%S*@jlP;06}p6#4Kx3qbWhr=C97`;!j}BwAf};-{PvgCMuv}}x=XQX zZ0Yj=f2^Kpf{W@X>J9N1_%-BBmAy3sfgvFx$pnm@Mh?f-Yl;~TCtdF~HoI~M*@G!{+NNn5 zt7hH(M@hA9#2|Zg*a5EAIl##zY=XEBR!)JFnT{BD>t(bg-9|p{h ztUo%$MKdEU2J)#86t{8A8q_?cM+=^jopmE0NGjM2OS?I*I3aRbAV2Be49L!_MOs}R z#EdNKTx1TM|J`1_ME??)8M1tnY#}Y_q)K+ImW|{x3WCz63CUdHZM*jOD${Yz6!?5S z_;3Tcribz_q3MIfG;##WqMZZf2`!NJJWOcKJBuJ81(^^Njso^?7Q`3C4T!hp;w&dSf)&`POWgnR$DEUhm_s+c1K9P)* zz8IAvv{H+vkqs=>gqZmt7BRv=!nivw+{4NMn?s^mSG%`1(g8cFf&Qgt#7*q3f-102 zIF9Ua9iZ#9EJq;Pr)u}=kzM$WpWWZs2 zP2Dyeoz`3AjEx7y*(L7YXs2o7mI}yB>q=5_!($6(L94 zvhly5oThVSv=!jX%J(tx`sOTw-Aq3Ag&MM`J z|MG~}>9PBAbg%tX(K8vzgBD}+z2UQu4tdMaYV{eemiP^^Wt0PLGO`5JyYVdvdkJBn z8W~VpDgo??n8b9iSE&IQyqwgPv^v3#!ww5}wE}nYsROo1&F%tyN2hkvG%0V|jv5qm z-^r9|UZ~4m=z!=IN@XxUW%F3XaHMeNOoG_I(2`gFM+jYR&$912ixS{r< z3}8gusd#L;6{c3s5;sXNpQD*Jbw|NWZy2If6pDsu9n4ZRMUJ?WRJyz7BEsNuvGC3E zs+P?tEX87`d@7@&psYyCqW85>6Suil#CMktOtiF(Xm?H=6lmzvQqyzJ{JZR}O&53(jRMjdh28Mc zWcX-g(h@}@cL0gwj*>h4UKvl6IuIX}2N%W&dCuYDiL@vUU~Dp#@!rHe{oc`2FHhHF zgAWSwbL~8nR8N}$`riJE%WQfLuEWNh(?+bCe~zA4#MPJK`EuQfC&4wNi&pT5P5L}| zY*~lvFejt|Skow)wCqr^4{%?sY8?T@(FXXLJr_v=1w&{sY0^!sjA3;coh#d>nL9<2 z)iE!|mR$EbCmISj;FmTsk~WXVF0lI68KpK{b1)^+cEIXRW_gcYg8E>GQqKazcsI{c zlBKh4I#42*JT|R!f?pC!`0cSNr4FXV3P`UtkF6Eec7z?s205-L1uKIf8;0G8J=Sh; zms!qm^Wjy~tN~0j6D4alMHdb!x!qQb4U1Xqu_>Q5K(waXJ}UJ=&UQlqW$=?h!YDMu zQZd(NU(q71xEu({)ErAKC$j)dVx+7fs0gxSij-Xj9J*ujdeim^>1qW$zI7$ zpAHAmo@Y3aArlUloT$ERMy(e5WPq|_Y%_gs7>?P&__NwMfOPVV4j`4!bFgwYzc)Oe z)mP&R!eg1u@1%W2*nzA7jEk0^dP>%Lh3efLa@xsuX1!YI!vRzXcQ(;{S`q`NZ()!o z*bjC;Aof}!*<)vL_ebbSN99y^hsqY9Ow26kDINXZ@(QO7K$%Kr_@ex^_jU(&bfk@t zhL)^WONR8l60_|T#csMdF?QXSl-&^Tfn-AROL#P7s-c8>pG+xJ#dRVtDXl>`0I-Gg z6=sN%Qt1acwo!?Ea9``|T1r!lsXdRgv1^O9CbtdfySwDA5gE))2!Td-3t;$SO)vUd zyGtIzgVw3R;fk`**tq*8%x2>4`UtQv!1gD1NbAr2UE$3p*1y~t9rKa4f0ojVxWQHM zb5{cHmLrppk;W!}A~~bEh~kPUsg?Flu$U3Qo_3R9jgT(jOCVF_3+TxyR_z4r8X9)s zDjRMqfgTz{J15@TM``tCD3+FHx7*gpKxx*hOZI{{cZ60>=(}xs4j)>A@4}isXVx#h z&9!^VHXBAu>2Q81!P*`ht1(P=N+HIG5GzQTZijQXf|L$j4Aht1M!;Fm0}yk2ol7qg z>Y=wFO#rsb#48|W97$L+NHlMcee|l~z2zad10-68%cWOyMhwZschKDF+Y<6{2iry) z%FYgDUyb4Jjpkz8esaTbFyviMJ_t|1Mvl9>t-qyX%rF@pXzpCJgz;<*OaspDa`Lui zMS9O`&C!|z80=oimJwhe&v~&hn7^ajOxRPw*Axb;tLfEctlDL4b>~ zVQ9&giiQeef4Z+>c8Ckx%&e8*;X8S`qh}D-NODKwC?T{>kVZJ_`oCR#tW%O;eoH;> z(F2LRe#lg*q&AKaj7&4icd%GfF;rd7xs)05)BL-@w=USoKW6WEy#@a7c@gzpk_Zbz zOZ^#OE*uSy>LDI`S;V_EUHP2vou-piLdv$gNQmOyn)-QImxGnA^^38@#55}HK=RcUYB?NzP>->Iuq_EGeUY8+4HWy z2FIiev_Tn=yA6a=!?~7@wN#K$oen7D3DwgAThLt;04%UUFF;uxz&}e(_jw!E<@OG= zuhFr~C2Nzvis?h};iTr8L+(=A=DcmjMplwyw5lEO3T28(Qg!Dz5)p&2Y;yPAa`alK z?}{ZCa)uHyoP6p}q~GB$l6cuJTa*i(qByNLr#Wo*9r8Xmhs~zLt(ks5dUEp0$<_gW z%YckxIVi+=*&WA@PLxoeNG>|;h|QWTbLU95m$!@HlAG($&n)=VCAXrV{3fp~9DtmJ#Q?2GAibHV)tP?qCqdUiNLgQy&c!_M=w^Yn^)=^dp#%Cj$_ZC@`8+8} z89)J#)%$3DCV!ni&9p@-He;>u74q&Lzcv~EN1?x}P>C0i zx&?Z&hd-|Gf4eS7SJ|USPow-{kX;=8>PkR@kx}o33+*Z{+_{Pv$0emN`8EnadZq`5 zihggwKm}vrwgH;qWQu-q6)p#|?DFGLoOCCt)gefmi_?r+!;nBKS?J8yAoL^1g&SK8 zSfW*JtcH4GM84(YW0V^sSgzwk}UK|}vj3LD$p*_!m zJp^!k#G*Qz&vgJYZA=zMmt(_$h*}vR{9L&n4?F>d(K~{Uok6>nYYhOGtT&g$Hewt+ z58d462>-xkzvK*{7?Qb&txBOR80Y{KwdBIx%T)x#NZ^|X8(OJ0w%ph^F z<=v}k;5xS70fU?1s5z`?8VEaf>^rMh1$eYwH14S*_QhUXS$S= zKOsg5RaIyE`Ua9< zk^>5W0-2O)$yW}1HF;En31spF)f*W+Q)(iQQYSu**99A8dVGwG;Ubgw&eetf?QU25 zFb+gq(}?(o=Xs{8soxX>WQkWwB2yEU075{$zZ|WD`Vih;eYRv{NH?584VjKStIO=m zK46f=&373a6!^4^S_xPj9;kK_vM^bB&Wc}eOw|kQq+H?Ol#PaL35%}o6k!BzRAJ0&<;a&6bO#Z~u zY)!&L;~&Yu+UL^jBBuS5N;6=pvhsguiRJxeR}X*v9MUYGflMCICilOABu_)aViz~I zd6&q5%u}C(ZugWex4>*PQ?M+u{p2wc`Ff5?OhN}h$3_^TbPV}oNmMQQoWpO8s97y> zv`fzItL7S&>^njrx#iw81AX18j&4AGIYZbCG7ifqOQOlGaWt#T(P_S8nafuLcMmiK zVDA7*HzN&_2@@c7VegWAgA^K(JIq}juN91`^4^Ur&>~IdhBSD@?98P!Cv7-%m z0-1b84uxir$pAczS?7Ezq`U6s=U!yETdla~?F!OeJ#!g8wv+R`5XP+R+MEU*F5%(m zb~tfTeMiuCf!onjPLJ($gwIpi$+2);+tKaN z_e{A)rVP4@>F+SyKxLTt2MRBLu>!3ycid7vesWVLyF@;rgJ}ECnX(Lx?pV?+kXsU2 z-p+v<1)_(DwMK`}GJ@2&NtkNvZbCAoZF2k;)Q@{;(qk>?W=fCzA~S898A?k{>++h` zE0P`Gnp52@>6q3HoyVN5N>XZmax!2vfb(pSHXOd=?)D$Zt;;4JM<%iLXxvUlJ;nyY zSVsUU+XjZ&Ab3uBgmd1e=0?XFRGiRAyZSfar)`48h-Q&z4d?SAA@&@vC+O;FdrDtBQU~3MJm@ojuN2Wg|cdWTl z&Qhjhy7~@aeX47!D{edF+k7#aMI~0Mt}ZxpzFG?zD~FB?awYaf+4BBMuKF=iTM(`p z5~#~sj{uX_(Rl|sv!>}iwA9DNhRtZi1#i|xr3XG00M;d?$2x|<d9#{UdQ*;Tmu8a*rkjw2a?*F*H|LwY&7Ke#Yq^%UAEf*Yj1~!O2-ftB6Sq_wrJpd>R8jM+&a zi&~(K%Ury~C#ziqo@i&o(Oh}7id0N9M_mh+5V??2;RtFy#ld7*q?N2BaL#KU(bSeE zyxoF24J%BfROC(=hYd@;Evk%kGUf&?7oz`Ici(+*ND z(p^{+G^cc@#GxFg2C*PrFpOiCl?+M^FV$r-6gzF;vq8l|nYsOI*UhhC^p30sccb=3 z8THg{M-SqC?&00Zv{QxNM{px-$`!$*%RVAE4SI)CG#C+1w%#h(QqYu*GVGImj{%}A z#+FS1j*mQZq4*V2q?I>pDG1AMdRI#4Rwec+K~n1B+sotc+Lgno&#b+2z(hvxamvO?q0=2|Thb&%H6`P`^aqk)MS&k^tKIs}gm3IL2sGnYU*%6lo)>Mgo# zNvc9N52cm;9lRmp*4>Ek)S>S}DP_}Ged$IYsnO-UkqwYhFdPZeHwF<7>O+Qa^78GEt3ZW?s81p)h=o_ByqD0(2vGh&~zJ%^4 zrzj|ycojT;qI`-y*5Rx_c8R7S7k}@z>Izn%0z=oS8moz?W)$Dbd_@YFUE~!+oVk?} z-OgxmvYqi@%g5Kz^S}wg*wMp`4!P9#UPUQ6Y_;PQn2|);qq!RJCRsN$#;Gp5&Gaxh z(b+b!z&ti3j@$jL@iG0BeHkCmY5|Q|ORRxbD1Bwm`+Hh48SkfYP_oqL#7f-_1Z(;8heylbU~Kpl4)3gjMj6C2>5$KJGDJI2m5yosK@ zo&I!moujr8G&;;ssYg6-RZJY@C@{Y}^!GC36JH`nn;PhB8)f4t!VVtaW6M~P=(bn7 zgY(7Iim?J`AicZ2bz(`HA^grM_3Y=Nb19=Z`x8tW?xL5x3cy%V`+&q4%-;zUarWIp zw(uFc$JVNIt$<5;8;uQ`+l)Y}YXj7=S|T9B#wNY^WDcVtOkFo3QjqG=vkr`qOk%GV zDu8G##OkHsV_Bwl=d$btYUh-@Xlth+7U@tj1*o1Yy>0gz(06JnA{W%do-j`vVQpi} zK*-63wItY)o13PL-LdxJ(hFUp-RoZN?jjhS{-*1K*p17*#K&-?D$D&1X$2z!<}{Tq zm8vQ{@6wF10xewee_d&yaq@Iu?5^ow(Pgl@+qDsQ)*8c=O;M)+VoEn3#<0S}yByo$ z=E-`a5w133Oj3>6g_bbwFhEVs5IAw7Y{NvHV4wZuK#B-#doCa~Y~J5Y={|M|RlCcQ zf2HDeMeT^|ub>X7SOhIcR*>gGn-1p+S$80Erz?q)D<_avF!J=!jHM$f9ebD~AN{j) ztaJ3ro^;xta5#<{c|oVzTz{o~PTur_-SS@3xqeh*jq5@S7RdOYwVkJw_j!-|fb(iy zfOx-TJ5x`whPKBg+u1IMmiBq`L-#iX&b!Zp42SKUFQogPcCr82@Ld6F`b6eBb=>{a z+v~sLyUfJ%ypvHL+zkS;)O%)1HOhJdcm}lvDN?YLuYKRIu2WZe>Qu%z7f$UN3e%-R z6!Ldpy*iyCD9Mx|a0K36Qo~V7mP#YwOSxX+j>J#2oPaEM_a8h!4wR@wK@-jaaMcdX z8D7|6BF`>pB1$tCrUh_bS(TKDNI>>-1i#@Hfa{>sU4-18Mcf#aNChu}nL|iiEEn!k z?u6Fy*e*mQeC;BXWnLGGiZJRaZ-r6<;S5UveCGgVQ`#$n{s@eG6hX>H!DPiTkpK!V zok{pL%u88#)rB5urgq0;4pdu53#=0K0|aljpbfRdwTn9;0p!Tgi&5yYTAp3!E}Urv_ilJwu50*vXLApd4yq0PSEP0%DlmROO^DFIz zk%!Zx3EBsMg|f(Q;gWqE1?=?jJ?>8dysx3!<0&x^qcs z188R&vX|}jZo^PLdFSX+<9kC&#MqVIU!xw7BYGJ}oKVk35$;%{f@YYB0NY zQ|Bq&@sO`r0k~6s*)fIo;gaqsHCW-uOFxz{Oro@#LIf7NS8s-wM0dnRnPIBKFVQhq zNT5texjgph6#Mucy(4h$v5sc!+7@mhO_ODjxj8lZK{FOR$J`&?Mkl3!@I$0UH%m$Z zW$HPAQB1QpO|J?ba!{OTFa=2!icvchl>Rm{Yf25H=-^gqW^SpJE&~ITaGR0Tqs5!X z0U)prDm!Ah)nk`>@O*@+PS;G>Q^2)HuO8WR+pAX+43OBM_d`y+H-L{+V{D!2NGfG* znRR2cT=IuraAqJGHJl#pWaeT3)H-^;f~YI-_^^J-1FisI$XX6Vlo<#{Y1#gDS&Hm= z6wkpQMJb#MSTxZjQenudE;fe~N>iS_ANs~6^?9X70UIEQX*6rdBL_;FLHygsAk;q5 zs9TGHpb`DwW&rb=DGObl!|yUbtKBtra7e3-PZccQrpfHMKTvWXcwJd{JqquKqt~$; zVbvn#r+q_7`!>8~R+oDhIsEOAigMap6!=fa=S{KO%Rxc82jw^fSr$D`T$Z9$6>=?8 zJVPqfk|3IYZ^8gL@)+PUj9YN)Ll|6K_>gu#T(f0|Eu!`kTzoNlAxV7AV5z~=jIp6D za#;#%-(%wdxr3eqL=*lkJBSnTp#wycN8QGDL$FyQC*zp|*0-a))!kuN4vh!9LJo$p zzIQOE4?6Khk*Iv-dN>)%+SS~9m-Y6 zX^!9tjOmeQAym1{uLCzMo6I5b$ z0(LA!4eL*ywA|1cI*ZbN|^`G)oJE)$L^O?xO16j}MfHfRy9KI(7s(X9zhyEg@w=6i#%CuF`P zy{UN?jH~8C1VuAUQ-rx_{|pIU(Ib-}vQ#bo8|hLt;ULZK#C7zOl(w#v9X0~prt3#4 zZJ9;&v>0c)XRr&!7fhZ&$7Z?fbJhqNP6ydr6r@*@Kzl}kZKc(jb!tx8T$AMB2b3i% ziZ!eG>DJg`L*dD7`Xa;i*MRm$8Lz}!btx@*f^PC6*fe24Gnc8!i#(T|J|Qq?(w4WH z7DHA-=UBI$k}uBrk5|rqO=e)hcJv%P6g~oJ-iz?i9LTM6Y^jkl{J7gW#>Sjs1Nsv= z8yBnDmp{`v&GI27&x_g5+UoqT5&fcxm%O9==>=q9S1B9;o0+dnUxmB*cVbun7Zsx) z1ggERfcIR0UVx5`ck}SseF8dlp!;Lgr&Dd~rV95*C5UlJj{sZT zaRTd{6&|(6V>h#@5k?&m++%)NWJO9K3U`kxWtPy3<)-1wyk@P7;n zl*iKfSE+naDid3*aP2N{*Zri1)S$k40QuxlM>XWb(F&`GT>c2^OLR=1Ic7RI#qu@> zN(CV|as=6W^hj}S!A{v^^`IMmxZ|v=j>luuO1_k6nfvgRP~;~W z&5z!Oc9W3Kjz{nPaO}%RGxYA6$4oxl@nOy%kNwWqiKl$@74P5X()WIU)m3{(Zhm61 zeEnXzY$%q#*+skBbg3|#Uxs8JFL&9lKIZ=e#j?Kk#k%%&`}*~rB>ZRz`B5AmKLX4g z!dC=}me<_n;g9S4->&n@t{jqoN8xs9KUlJ)O_eq&QJP|eMd3CEu^Wg@f~Xc9|yA= zg;xiiH+`5bS?H2gNY7CZ4b5K=mlW)s4hY!!}KMi(NaA17|XKyz^BL{zMo*d(JauQKfFyQJORS((R;%u zIC?Zdf0&_6xH7NwXeNDc%>-Ra}(HV5}#k&wQdeLni$hMpH& z=E`D;UMq7=%&c(}zNHx01@7&Mp>VI6RcHXe_0qXN(OSQaz2~zDk z`l{p+yghwJ*S+Jf`yYop!^j4Z>4XQ=@{^`ZCE5aerD{(YSDiD7ybc3wA}ro1ohXjq ztf+*Zg_i1tn&?c3Z@2|K#QxDJgT`dhXHC{kscv`Dq}{W5Ghn%ko^zSb3CCVcK?G#} z*jxf9ZVcO1p{OHw+B-}_lFRJ}An1WnP0wt`kKpu#>IX>x)9k3EM2opW!5;!W$!@qq zA3D7jJju(!zyte85*xm}L8GR;Wv!88t!ptC!%VUztThA3T+ui*0RdWY^`6<_2CU^E zaua<3ogQiCz~*^CWe=yt*EFcZJjuWxGU-^_<5bvFEl22B-^{$M88<&PsO;^smO$x+ zRFqGf2MMid=tK>;1r^&Z7y)S|4oVtXz6J(G9RB=Omj%5uKPRwK$-}ed(^+R|K8Vlx5NGa55*GkGz~x} zrC&@G>Gezg`#bjhi!YZ0$*favMOS7&srbJs(vkTJMwko-| zU6}p0Y`W57VhccZQ^Oh zHmORBVkh}}M=&AL>NE)DX;`T*i;cNJ(XumSxwFS$Sk|J=f$)P`W0-B2aSIFtvGo8||+ zXEw5%(yU^Pz1try&o2RyO3@ka!iM6+XQp0hT7&W4=%vZnG}Q3-W{p%@<^(~rn@Dtc zL7`M2WC6;%YE^*%n54&`^=i>#W`Ld2Cf{zHATv2f!|guYUa1Bx`108L-aFPljc&r} z!`h+s2G~X2m&P4#zvOoWp;jm*%gOAeUO}MomYqI#VxWQSiLxhvdC^o{?iQF}H_Dzg za=@mVAyZvU=OB9yRORd^@Qjj1a%yr4jD0_v@T^^~0AEi@tL$=EI(qWGO+pJ-$_bP$ z-!4{5i6%VF1!jpBGjx}WJx|+&=+sBE3JP?~iNe@1AdUe5xT=HS^c5|XL_^BD>9S*2 z4kU@&As~n4&JK49gJ(f&no?XB@^(mjDDjW?cKdqRCB{Dbwi>erO$(@MdXLR3Ds_oQ zQLJ2OK|j`&;mBI{6gUp=49{9Lu;J?Lnt*wm5oLMop@u z9n8HNujDHrx^P4u1;hHD+GDi$TFBW-i-{6w(hSCQL!;?lx*NnS%~FyMEo04TDjw^+ zx8<@$nq+Mkl^WAN==kZ9Rax!p3g&q2xT8#Pg7S;Ra?>aAe$aYyYaMzS(pOkx^XWIG zuRMA*ef>5J}3%O={wUQJ+IiI(lI zFRPjU*q}+N^gB^yK&IRJTi*#Zem&9OG&}T3Qy{QjQMfJLFkaItz-Gmm6Y% zJBrcq2SGsr;g$SEMuhZiTV`$O&j<+XtI)K@rQ#CkX185A z>Xxc|InyewI=lcO^}c+%a<3t~u;VqR;Y zGh9>(x)??=SHa8$QCcw_?FCfph{bUQBRC89U4^y+{MojIUFq z4f%n@2v}&!n|FgWgN8XNY(;7}3eCG6`lJ`daHmr(2T4FGc~YW@p2-mw?GC_=4|g4o z7E-ij=bp4zgPk1PwO}DyztAB(d+bi-O9_c9{Ex5ba$;mE%_c0Z zzH}SBMK@-R?G(ufT2#p-3iU~SC+tGgITshp7n9r_t+U*O%Wbm2v@e>E6kFg}Bh54k zG(*zZ^2bbrfCb&nJEU)I4x;7=5yb=DWFxSvR@*ZA%d`U^N*hJvFe2>~RZnsoDZ5Dq zA4%I%6Nx2C7fiqRfa4;>2oo|G zm&P8W=0pO$nC4`=t|sa+WnVDov?y(GX*no9XzM{W1EdhK&IkEU+o@O^*1!|$1&AF9 z($kT~Q|@QdMU_i`iNcA0Srg2i6W zLt<2oBN+3X7pumtmGDQNi##}Q%yXj~q7c6=WQIM-GP~2#O-gC`r4daE*NeCSmkwTRQ zC7U^v6Xw)aFdox6xtQfwItrnL3DDeb0d^oM((Zt8k46!6y6xE=`2e8H;x_h%yAuQ< zJTs`F(jB+Eil&QC{{CEV{+mnueF5P?#oBtNmvpq%)I6Q1T#DO8OA+;RaNv>YT@c1x z?t0UVy*wW_0>Z;k{^wwY=eY3olojFG1^y7^{Go|n`Yw(KjP{2nS>iJ3{QJLtrk)Hi zl=RcJX~g9~c{9E9kNb159V?ZXj%#XpebCOL;%Oi3=7U~JE-EghAf0lSAZNEZ07bE{ zdo57?Y17gjPr-VStCYG5?knhhy0goh=HhO_(yQ?(#XL9dPVMQ;5)7)^L@pb2I~F6$ zaE}+pi#xtzl5k!IwRIRODexbJ>l^|wr@K748Qo}Q;;)~4UrP1X3yS3zyf4piWhGzC zlYa7jNs|2U*q0K_^XlQRpJ`tv`lp?)X(BEUDEbh-^N;&;aBwq(#Kn+@IX-A#y3B}n zOK|y62jUW6nWZo~8>v(=q%rxlOGfm^D>+!Fa7t1d(TQLcrzY5!(EeIyNga~dOt|Ko zg4%93u!hq%!7s3jngiJMHldU~fxK{M?&@ycg!;<_fdH6S+a_4XOdpUB@=)Smb|U3s zg0jsHfg&ehyedKBitCudS*1XDnL(LO!?`=vN)Z?4D5$wY$<0r`t7Z1fzxYSewoh?Y z+SL~cJU_j*-Qx#x^dFZI=ez&w=hC*ztJEEIQoX%?_wVcbGoT4akDUsnhWRP1;h8zhGh|T{YJY65Nk7FeTZj!S%<-LVMl{7(0syl6ppQdZ3z z`tTdJ8T&U8UGVOQeX|8e+fM1g*48l}`m|Jc1aLUmXCfU<`7@d+i0e--5pt0nI!99e zf+fN@mk2+R{Vnh5@3OyByL$NRXOaj6<-lChkfzsu^c#NkkNb1-LCz8^OX*4P;S6H2 zH)(Hr?1EXZN6j0ZW9Nw=n=EKj7<4<=Hqw~{;|8IYeBYUj?zP!nhQGWbj+nN-`^ibW zt;e{UfWT=ld@3Y^pyjwSwIbclH4215Jz!QY=O`neNV}y>2{(D@=H37qav(;$f>e0x za(VZF2tP9B_S(mkadjgvf=oIPVgL%X6)n$?Pe#UA-93W z3N{x#4XxaA5#9%*boHHq#HLj93jEE6P>ZLY0w><&D$`GtS=E{S}0t1kI@=(53SsX zlTJ``5aP^cnXQ)M`o1LfxaZ)_Xj_?0IMQTOIx$Xz>Wl0A{c?EyO*#BtYW1G-zR!iB42djpth~|raP}?PmdMG;Dj?{I0Yb#W_d^+1? zzfg=_Lr?_fzdZ9<-iLRsAKTVjxn&EOmG42d0O}#SI?48z-%l)mZxg=$>bvm<5xa7c! zH66@G*pWsI^8tJS#Xuxsq~dF!_PYG_Wo97C?20)uWs2gQ;l`~LBlnDN#g}Qu(Q_{K!Wk1)fq+ba1>yI4(!I&f_utFr>%OF1vc8KQ9QG8TB9&eQ_zke zHyO()&rIMEjCWm2s{b?-IQBd!J|w^2T#$(9t5E=Lv`vC9Pd4akn57`Q3jUpKeTiWT zvQcO$ny@91QmG#KRedO`5t7>|khdoxwK7gWoTxLAV_yW_qdN~M;1!JyD4|+rw1m5D zyYsm@|3DF%lTy+!Aps=tx{KQftreo(W*=_X#>(id0lbg}ad@XJJRPR$gl1#WKrRZ^okPY-;@h=_8dAN{z3v&y>!c zQYtc0@;onzFdGw9P$OTi8VA)2AN=Jq47b&2<-GWkwDM60_FNgpQ)81}5*Mw_PgxOh zC!_N(p}vxGA(=emRH8gE;kG~i`}+Qj>rH(z{L&MDQbOciu?j4@Lc>S{r4 z82W=F0<~ZBUA5pUF!UpSq#Rm6?`WsxV<{>$v6H*EJ>4+i9yMeJQQRqF%C4lRu2AAx zwzJuX01D2%EneC*{VK$qBN?Uy57^Ml2if#+{16e^l1VLt-g0JFgttAR9(JFeYNmwdkQ)B1Z|0E+qqv7%8)+Gmnx1>L|v=wf0^=dVQ2^18J8^-Om(w zUc=+dl06G9y21>G+&RuoY9nU4LGR~xzT+txbzJDz=mO6~%a8t{DUPgfd`YxvvFpE2 zftWFqEo8R82*HLmh%*dhB*m@f!?^$B_$fnk+~CDvHS5?Dkw%LtnR&$=!C-94k(!t8 zr^#$XB)a0!F|-LTo04kRI~hB!6po2@lshjm5U z8chaPY6H7l=tMwxSYogS@rC4AH!T?{ng~ze-b0ku%u5NAadC^^1Q#}_#ASk^P7PXe zbu66OBbf53-x|@%yg2^3{{QyQWVewlJHvZF1p#l`0NK9t02toX!p~8L+lGOL7wzHs z{eS-nDV1VSRu1aQZf607Qc)r!7!mi}GyH>b(8`$)OfE{~`}BT)9BrHiv_f1O4}o~- zz4dZl#$)!p%85j!GbWxv{y7aRY(A~tcl{!)gaX_nmEU{$vvt~^)0VaCS7c0QK)jIJ z{XiA6kDruG5&&yhWEE|teE!q%ThA%x%-7|n_nfb^7!7UiA#|-6a0uF>Hib{!u=mh{ zTC>ow!5M2Z@X&(qhNVyXewLV@qr2$6IZ075SFbehdiRv%vm;>v9W}X|- zsA@5rzeZWx^#0H(>t)b(L>@+mLIhU9!SsY|XSdGL7fM($ccqX~$pX0nI_cVne_}1-4tg9fuArSnw}q3mWQlviS6nBA;fE_T*;neb6Wi{7hsjnRGzLJMq@99Yg`1+}ruOK~|YEBdtrw1~{#Ek6eGKz{= zwS+MRux_hZf-NaHzO5QY8sl;^{X_X7s==O-aq2xpJ+cwVvxM6UOp(qmaaC|NPa=Fe zw5!2nSjiG5E0~c92wLYcY1_O(U87-2MRGo->!R>}bJM=txRUyQlX{&!a&N@L@r@NE zr>!f{(?cs*Z7=Q2+`2fEq9~~6ZB68mki|TWhxSw`_nDN(6~!dM``Ytin$^zItnVtV zOU9yYaD9}D1`^P!)1jk0|MXjg&3AFzpI=h(V=B+*zS(oS8@DaU1G2;8*$K-y5jjjn zMfwykkD|&nvO4I7&1Ue}Idn_Q5K%3k1M9S45eH;i3k}bJVHn3yc@+*GJ=xbeS9m+a z-WRRdkEG+`V!2s3!FAXxTA_Pmwnq+@NejY#x*F^S!wFwZ-c6ShOB}zd$dFU`S!)Mb z{zTR1v)VUeb{JW_rYITT8-@y{pP?aRY+DCXpVSt|9*U6R_)VYe_=Y8ibs+L>1Gb*C zs0DKjE)_AjhG?6Ts%g{1wfu?0yikjZA*`hT2f#vx$9T}r8hK5?YYawpBf>sX;cz1^ zyeu13j(7KA_Ym@8oMbPIT~s3NVj(x3W!CvHkD|}ybA-qj#)B~9EyV`MMEha0?+ykF z+2U>(zl`u}X~{BhOn(k1m4cNi8ycWp6}TzeT}4%JUVb;lK$u(t)yoFsv|}XBJkGhP zUZuFrSQHjavoR56a<>iU!39If7kM~b9rUCwVVRihr-N(C+KA`DG{^cX`!6$U_?PBZ z$l?Q`x^qK)MLnDc+Oa1T04_C!^jFDPu z?iW*i!;H6W=9u(xaRl2yFLCl2W=gx~y2AQ5OfIW+YBHlr`z!%KNk<1dBdzDBDznSG zr>*^MhbM@8=kBt@N`al;iXD28#6x{z(|K=Z{g^er*o8}vRRZfgBtc1PfO9tMKCGF| zPS-Qgx>pXHPAKe@9J5PSp6+)K>Cu9HXRMNjL2-90gcxRi^nf$j;mw1@@VmJNon{i1 zOhHuw#Qz@%nbBk z>)4BX(vJJBq=R^lpf=V*K1V(9=3zFNzRUhy*omSD=UoSEe+Z|cw#~8aC}CZZ3>Vx$ zeQM#FVc;`O>J=V4er%{;W&?cY`fjg9U&O3r?~j4 z*#W8J@x=b4jcNKj){S`Hh`NAhpR21lu^oGBSt;%qn1x0M#!gds5OU4+R1$?ydl-wD zs^?QHo*A0mHI~_{{yqwo)v)lYqD9X%#>{o`iOmMZIs2(%p$|I{!r^vAX4-}rjCUek zRbMqaXA_}&q(Du77GjwoB0u}-`L`Jf8pPyQHfHXX z9580br4RI1Y;0^Uv7@@OUNl`c*4gAF7z`*KK`Q{#1qvVd#p!+M@>o;ka9AVHt|%v< zwPJkR1*ID;UDOm>Xd4tmo0rnCP}Ha@-aM3{p@Fx%H4;|BA<#~3=*gJ7TS#u~&sOwd z!^fuC6<(iwQXbt*dc|vU67W(nJqMOK2NACtCE2hH-}VG`)IpP=bbyQ*pioUAa*nBD zwdwav4NWUzex4{SpkdUv2SRwqVW7ILU$wG5bZGD!%nDz>;$MAw%|8%J#Ad;1KbYFG zJE0qKZZt->O8574vVoYAHqd_Bf@~IB*$*6~b^Ul49xeQPs$~0c@`kek<@WPCV|qS7 zc=A!n{QN62<(}QoqIbX2tBP64-S$d0sUjR(Z%o`+ZS~OTr#!JGE||V6ZL`vBM#+Fw z&r`8rNuo|RG%&|B1R7|BvG4$MN)0YJFWA3!@5q{0#2os$d5B94ucT6s?|*xX+ox?SeU3W zShpb=8hon`ItBS6PfQiqoK|nu6o^n^j!5!k_}~OPT`hD{Ehu+$OOpxlwM52?zabMA zs?)2_V=VkE0T$T}n4_l@aYHAM{Lxaf&WxNv=~3=A%1@iv>LzA8(Gb;-?~eaqT)Jhl z=eTAjh5&-?g@}pQ;S^o1YoPC=8-$t|x?(G|I&Rf2Ye}h1j(#czl%-pYE7ZmHI(#>V z!I0OkKybEYIe2Vvn=}xfra-Udn2T*CR*3lWP);<{00kp{<#sA{aJ(H<=VH8cW9ei> z?JTmai-Y};tF{t{*LF5h2SoFxHjmM779C=wg%>!(HbwjBif%~jlM%lzNxCpwSM8{M zrQ-cX4(s+f^70I%ueX7SNK*EViWiDKsx~Hd-EN-$SzvJ&AHQ*He0;rUE9VChOEE(W z15_>QQ-%J#yT6pi)ZK`O=;mYJ3G$0g!_K5SE=X3uP-}pl)zh3dNPtNKRhi{mw`^e# zX9!e3gtwY!{eU+B^=iMKlVM+F~Is%hVKJ7Cz4@^X!{0U{)7M1g>QR`wMa+fgdh#mdj>fNikFG7J^2V_T6G( zA*?&Bl8szoCb7068lZn-i4K4bt2GU&q5buFPL9JXQO!XrLx*mvayI{Svvh72Gw~z@ zX|{=2p3YO(xgrf{*5?=oT3Py~YHeRF>o`^avm7BQF!LZcpzXFe`slf~=A(B=XYK?5 zJ|el|G1lU$iC{2jK<#O{q6|F$VofFTC=1Y(98xtNvZAJPEirP@(s3-oWqev;YUmI? zx@sI`_e77;0JV18E)~W+v zgW%VV5TOe@sq^7LSbrzGx=&ALIJpd0WXX7F1|*g!!=(OZM0;V0!7xTQeRv=IFQqLYnyxMUCd~c01dcYGbuF?L*l7G`ceY7BxIhCj|;lS^#v8rQFHg5$<;g#0w%zHut8fJ;c`~DV`D;8G zU|T8hvH`4nPP7s#739F5mC1Ny!n4~AG{RFw2@}GiBU?)(EXGGhGLcr3Lf8laDf9=~ z02Ym`4#Ezj^vUL|*O0cH(jDsrGJ#XYb^(`< zng+>%Cu5%MQ&!^;qEaCT?0iR=lmI0#_}P#GtU9ONq3~!_qo)IGivkB4kkhO$tTm|> zH!aEQ+-y}%QIiR$@@Mqv2D)a|Q?l6{p@1|jkJC%POjjIwIUWddqp(u9M~L92nvJ!|rL-&#Z!ZSrRg2m}g-TDoOu-4Ij_v~bOUSAR z)kCS$%6?5{1t3m-Tgbz}X(@YiWQH_T>GoN+5mNH7i{YGvJkETO(fKv@?T{DE^>7A5 zno>(U`^*uKO$LjS+wpCdN7&tDq0yQJ^J%576_SP?Y*Q#v`u8=$GMpA*ywdDMrrUE{uAie9G}6|jk(u2W=Nb=%K137?Rt@9snH*XCS* zC4|P~?#{3BIs8d!{J)vu+3bjOW_bJ#*?|sH#{K}xtlp77A`b5;=Gc{&$#8%^3Z$^U z>5w8^%^1gm@D?K8y?da)0Pl2kCDEQyCWsOQNXZU>oD{2rb$pONGN{3{q0+f4R2ZXL zCIJy;+7H!(G%`47EeQt&q&*bRtdtLBWEs=cJ*`z;JOkR9Ludzm%JLw8q^+g210uSI zh{{;18@|~V0k_T}0f}C?FsmZ9!)mXogcuP5J*$^+GC+a6x!K*jF+1RrHf^H^`6DXL zs&3JbcFtMTWf?yLB^3aJuBt9(w?L6L6#GDxl*8a0#=7x2=p>iQ4YE(vpkHgvUL}$J zQT{kx&>IW35%E->x|oW=0Js{t27Uc9=*v=2UfE6>wKCru{DU@vdS$>hLbA~9+<{Mo zZ8q>CIL{vqMIJbVOz>8nUMsYul<68wBYN-%0DA_VN=1mhE<&Mr(!a)-<%%_mzJuzG z!8M;IY7FS10Ga>X`D0g}G4Fx&@5&#M8PMi`kKg~Z=8t*`|8n!kLeoYW-AQnK{?*ND z<_u151BIG&N8_R242X_QXqOU9wMh}#$e9Qi9SLg7gJ+BA9Fu>4h%LVv-Bas2( zj>|B_HY-|iZVz%sO92M+6wL2_J&FFi_-!=ODe$C#wA%UJqm;EYg<|V%4 z1Q>OEqD@ik9E&_S$F`64A)vlC<^!B%DcFcCa~K&N**eJNr;}^`w$e@i#&tR{oqh;l zL1`PQ+f#-fAYSH|4?1fL*6Jzw7@bC-kLL_ME-E@5@6R8991pnfnm>j=K~nwyGkyF3 z2e>b)uo1P=59?=z{jxfYb zLz%q3G-805LUHOxBRkW>S5=^W?Zy>v`a}kxFMs~@Cy1lWl)?Zrt8DqXuUT@d zef*LmhptLh=a07J0NJT%ujd`)<9EO=(aOETK)urzMdcW+x^cC<*qo6^<4~v7l--O( zybD<|L`IfPilRMN%&^~fKyl`cNgu6DOC$k{LlR`_ZZ1oHjJ-kZ>}{El9LAlv&Dy$9 zw=xCP-^!giUy)21%0I)JuMG%p=#|ciIA{(BqmF*F{ZV$1o8Y>Uaa%)Kg$fWb=xEE1 za*0+o3ZSO;w2b^SP0zW^tYV^%b?mxMx;AiBKnqQ+{T2{c)KjMYf8lfnlOpe&LMbJ~ z7932?t$hl7O`on>VYYfjC!iIs5mv2ZqPlAHX07(=oBh`!_elh=G*pp$^cc?plWQMZ8=(86hR!b7F-Y93e^fILy z2~`6FJ8hY9_Nc#Ec&+{og_m_9*9nd3Nz)+Fn?H%4XuM$OiXY)=*_ANM&G(!vf@`tt z#F?%Xng+i3+CkshK;HGek_M{7QD+=q7+4WvLz27w*l;g81S%B>vxo}ja!{)H>G^ly z*LAnYlZ9LPJfo?`xub66wcEo~=J&m?x?!6Fkp(6WcASQd_1=b(q?Q@RWPp_xi8KHg zqf3xpT7MIO5cn^>12fNRDUucfm2hVZuuetCY0|KkSHf@<^PIDCQ3~>iu3MD>Bl1nGt!AK)0PyW(**MeVcj>bYUvtwdh!j(Em z`lB5RP?ThRNyNF}{q7PlCZk`qX0>bY@PXVhEdw70y%w@IL#c()HX5tBTfq)=@-kBO zJc4asE;F^$))@H)7x|e{;>CZS7S>g7$~ofcT$! zv4D2BQ}^n@e#E}Sbw;7FV1HEPFuEtCD9_awuLaGZGuwIjm!=_TIluhGY8#7QKRdQn zaB+FKq8O~=Vrc~p1~w=mleTquN;b}ET1>-8c`d)gdl~l&RD)OQ!Jpsl5C)C)fM~ zmo9NP&3(T}-ct_2a)By;I`YLGHLY~g3pGf4J3~8nuX(!s?_9XLw6CE^E{EWef5)EX zgw}@BOCCS^&J77Gok47#f5jXEPr7S2(V~6sy=p!d5Tub^PzZT(KDbiB`DriC{OPq2uzvcEpI$A% zq37^-j87~fVo7cH*|EVO;jfflo@Mcz9E#?rZ*y|Zf7FGK&1QwE_F&;-ZFX-y<%Q2| z2uYpu9s9Wa?_Bu%Q#tTk4@kaamOw&?`rHR7p8da{jl5utql*o_;`yiN-(|}QO?1~# zP#pPHRg>-TuAoJ8h~{dP29}Rga4hC6v_tk8Wy=)wM^zEiBV5($=Fqw0(4VNIY2+P* zR0UaVq_g``9`?e3%i!`dL*YjDG>noP(YRV@GWP?}qFP{>0ix1(6`fD@pr_mZI;Bm% zk#b-Lo!6k5l*o$QQfj;#((F>Pr=SG|$DZ@3qhVWq<;)f~0EPx-i#m4`Dpi?{bqRJN zz61=UJN7Mc=63rg6Pj!}$C)pcIPf-|T|q48EHYso206s=eR|E`3XW#oe?xRM>$RNt zHXZY0OnFp%rTfam;c;N-HSe9_-6qbs96WIKgKSQx=zM^@Ar&f#eJ{jjq_e!}D?`jdx0Ewqq}u2&@y!hmXse`2D!PGW+@61W{vDD53FeWO0abc`RUp}v11!j} zKvZ~PceEhZ2I~M7x|7y71|vvXLDOCp#=AvKmEU(S@JdJ1uv8U8poc8mq6I@YVsn|0 zXsMPa1+f-%Z)46tS*&hS6vx)T#=DVE6x(HVqzq{UTV!RxB|S_zf-nuF#5C%J3>H#3 zE@E0{>2(kfB`NbtfRh&#a0-`Uw%xEq_w<<$3kG_L8$-QAd;yi;1iO$5HwH$vppRX7MsOyq!!*LQ{Fi&XNVfDM(sp>p!v3Ct z=ou|Y|46s>wj%VS>!AWvIaXt_UP0__Qcizj&ilCE@SPp{8`MF%ZaxdzEK%O?WDyJ6 z{g9+>&(jbG<4WNv<9F-n9+)pW-v!P*qZn__pkY!bT`d>H!+k?P=lUlfas}}3tI61- z0!D9Cl+5Q$M${!oDCA^~y`2|-QwN(~mQHHEkr+34`|H%%1@mhhAI_me4J)^F56g7q zN8Led{IrM7Qwyf>k&WPd75P + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/share/examples/text-on-path.svg b/share/examples/text-on-path.svg new file mode 100644 index 000000000..851f7a005 --- /dev/null +++ b/share/examples/text-on-path.svg @@ -0,0 +1,374 @@ + + + + + + + + + image/svg+xml + + + + + + Several texts + can be attached to the same path. + An attached text can be freely moved and transformed + without losing the link to its path. + + Text on path is fully editable, including kerning and letterspacing. + Horizontal kerning is often necessary to fix intervals in sharp bends: + Without kerning: + too dense + too sparse + + inkscape 0.40 + + inkscape 0.40 + + Text can be attached not only to a path but also to a shape (rectangle, ellipse, star, or spiral) without converting it to path. + + (The path or shape is editable, too.) + + With kerning: + mollusca monoplacophora + + + + mollusca monoplacophora + Vertical kerning works, too. + + + Меня так просто не раздавишь, царицу санками не сдвинешь, и в доказательство мы ляжем с царицей прямо под трамвай. + If your text is attached to an invisible path, select the text and press Shift+D to select the path. + + + + + Text put on an offset linked to a star. Editing the star updates both the offset and the text-on-path. + + If a path has several subpaths, text attached to it flows from one subpath to the next. + + glyph rotation (Alt+[, Alt+]) works in text-on-path too + diff --git a/share/examples/tiger.svgz b/share/examples/tiger.svgz new file mode 100644 index 0000000000000000000000000000000000000000..27e7e23accf5a375ee3b286fca1da82f102401fc GIT binary patch literal 34776 zcmZU4WmKHK^LC3Cr??a=#oZlR+`YKFyX%9yyHniVZSlq3ZE=TXap%wP>-(OQPsu$w zlWQiEN#?pqqP~4QKm02E1=_{Z+|-HD+0FdRMYnA&ql6pL{U#vL5dAk4F|pgS_b373 zh%ptjLn2;mHtCZ%3JvNGzB1k%fz+ROZ>#EVH&^w%n+@*+@3XoW!+A< zi|%{<_cOr902uJt34VXPK@)m=%wl>dy%=Zed4aSF`MwOqfj$n$KOWUT=G8xY{oW6< zNC0n#51$`y+V{LdN|`?H0MEGoPoTG~kBfKpk7d9|tN!b&JIEgb{@D9?d<9?X`#dc! z>wn}y-tU$_4r|{haX(%@AVU7%TWmqksXgz{p!Zt+_b4X+hjAwV7hHY+w^E_ElM@BV zNvV+E$DRILSgq3G*~gVVSU-luhr^$F>*~(qrboc{WxQ2?*IVEBZs;uznG|TzwxFzuOBY03pgo%g2t) zHsEEaQ|K*D=$10du;1Z4$oFC30q}Cbr5~#IaTRv= z7xaF+P6BuuC<8JH`Fw1Wz$0xx)VO1Q{UmfLy8~gBpwH+{a+^S z0WVM1AK+4ux9K7HO^E;Pb>9Dd@3S`x5(&=rd%eUZWDd3jU9mXZA|1wf;|r6G2QpkK_Ln&r@0({z4skb%3jXv*QCxaL+LO zNFAx}XLC^wX1%8SZ3emm-4rUb!8~q*+NNkFaHw6bh z&U|{h-(QbDjc}phPeAVH`}m3FEqqsV+F24PR*FE_ACd=@P~NKjcv290>mfW?HLvZNFCEfn`{p>q$N9*8vF=Oq6gtxoDPpa*yJ>RgQwL<&7HvT+UoTX1+ zD{~W-YWKox@-QFgSuAU2ycPhu)R$_@%kV{{s&x*r6r3yJ9_vSQOyV*U3A};ivigC< zA41(aectaF@r9qd_g*zyto_gGr$pFeIMV_>-2vN5qh!0oUG%1}4-6P0gDHtKJnp-8 z+`nN^6H@rb>=mko_gC3To&zIhVAb8UNOE*TN5)~n`aK`{D*a)|_eU#rk4uH!apJ~^ zH=s}WQlb^gDR<>OfLJw4BXuFAYct>2t-@P= zgQ;MlNQvf<=6a z>q)H&Suw}a{aF;xQy3jvca{7|kSG+jrC>pP{_lU{lF?SGg#c>Z?edhf^F<|$c+cbL zmV{T_!7%+Xx&`h0k#RKISC!l_+Es;A;z+F!kJ|}ij1(n1?HM;U{;@ck+^`Nd7@esZ zgVZ(t<3u#&aY2AtcfFao9F~!_MTBqJFI;|F{LsTdLA(zEb*rTAm{n^6Iu32jAYYfU zsZ~8*GyA4R47eKA|LU5iEcog8o00`N2fILwAir*re)uxeJpIBg4JtkpoN1^Bq>|{$ z^vA-!^hb2h^mgdb`iFnqO-uKKF*YR9r-CJpTofFXDpub0Q+h014FbZ%1zA(q&i+*` z!Dur;L4bI7J!6XuM|oBWBof%?Ao~)qhKU;S9*y&#lG{0NsQ8|^!lu>f<2t3goR$>Q zkIi8Bzh(5Tvu~XskAJ2 z1K5oUtb-c03Y~v)*>qTAcKN=$XVt6N#v2`EFCRZv@SKB8+cg#wD~W=%g;I`uyiIpDR*}(mJxDcJJj0!yRHvQm9L~hR%jJv z++64BM@jJPS9%5!RaO+U099FFmT^57SEDA>Iwv1*V@$OjJ#X|c)RKVdur^x=j$5UE z1V3=&f4dW1BWZJsIFNH`GW8tx#TtcMMcbl z>w?5g77c!6vSoH^G9HAD)4Jv}J~KM0;uPnL(Yx~40-9w2`BwZjZ8M8;`Fmnw*x>Kn zf-{^9(rL6i^{>hhyuHDVTX^+d5Z!4#@Pa9!F65EJOmoXt9O@rsx#d#TBMxE@2M%B| z)8>QYukW~Heavnkur`bozj%>RH?%0RN|%nfxV{177nU?`miFlLsb8N@&*mKWoqKAF zo@BkBuWn&DC0>IaiiqEnCY0f0|HB;E>|QVnVj+ADa{>0yMR}ES;iR5g2mY9{ zA@1+ysm19sob6z`F0riU)g?5m!CBiC3MG%e!rOR7k;Q>AbAiky^}qT|9=F7HdZDsw z7Z-BmvzD0vedcxUUl22=pQutpe=b|rb*?-J5AHP()U;j(TC^wCePq^;&nEr4Q;$%6 z0R~I1lFJ76z*_RWwHy#EXfD3+tG#_oRFUr6j7{#RD9GZ3I`5(EVcmbav$_F^7#yYM zcg}SD@QbY(tc+`um%NL7GbJE6J(MlPWOZMwuEA@SdL%HkZ7pcqtZqX zW}=dGWpV@zB=&S04f+aAZAVD;NK$MHWz{jpvX92gZ|(~1`PUaduFt?EZ2@myk#Bcc zFK0CO%PQx!r7QXh^?+O>e}SR*|9{{EkYjX&e}67~rx2^Zh5=PDZ0CxipNYL{OJgW% zG&b0-MY2CDFRET-+)r9pn9Hk}-q>9S4eTc=w&m#r^us#0t!|1?Ao*~K=JC~kx>svN z7cbT{CtsJeWxwjVV>0ns1uSxRziV=W06I!~CiydD35~!yClo@jrBm!JS4g8R6(N<3{64zJ^9*ff^FTZ7_Usec zURk@Cp|KI_tF-x7>u^~}t?l8opCwD!ZmhtayE_;Xdn(fVM}L=dg#q=frysJgq(bs6 zp3fNKc55-W7g*fscD%F4Z^&^ryEG3QhdJ0=_+FNfC;K0B7M}vk+@R*xgU({Lhwjf~OU}$tU|mL8B#< z6ID6Hzfdl7(|uqS!T@uNwDc#Oaypaq7>Ss|@!BH%uIM6Mf5X*DAHr~6_4S;4&;D$a z@@?6{ZQ{s~bZIFWK#5`&g8a8%n@g)d|7l$rP#gbUe$Sh8NekC@UekBTXWp$chhwwq zqax?%Q|DZJhf$II1(bhSF7vE(gKvRP8!&`FSmcDN#E8uXS0Ns#gox;;)<-3oi?DQN z|Dgy|wHCths_I?Y+SlbSh{6l6f1$ery#!iZY#g(%o!d99=;B_iKAIh8D2NP+f6u)) zDL#?ix@aECG>uo-@v&Ol+qy_T`HpDjOWz=<=hj5$=W34<_pqeTHTwTF|E(+&pCoAN zz?muAT{(>ybgnj;0~$Rtaa^0tu||RF;m%!sEH}5lhqIf7CY3<1KsRRcf|-_vjDv>I z-bTK`aE)Iz9yUIl)mF*24C$^_{fNUcfuMlx0$qGtM<}F)0!N7$kBaIkVU9#L!WG*c zA}(Y4ENHN@%~?hM44&j&txi6II*-ptT&!#Ib=ei(0rzckle0aX3>=8B1*wIj0JV(* zU&W!x5IIe=t75dXQ+HQYXFWz@@vx~S6LyQd286eaez+LlaUThs>Oq_rb4_w#OeWw{cNaHVFI)0hY?;oo>u+0dL^6_}Ug>G2^)KHEf{2|K_!Zn*>tAB)z>143W0$k}o+R`_Q)=`V6)^#C(_Y^- z3h@in+t@tvjxTF{)WnVykr}$kW8bt2Cqu*QrmETMEcTous3Rhgh(#vHu+lG;_%o~4 z-%_uT%jE_q;b54;D1S#Eh*z~6Hn>Kc5wnONHE5G87x(#;OJ6!(eKVJdHer>HRL=u$y&j!kZes=|G&l&GV&lXH=)ZA_W zxAM~u>To<)T>pZzhPc)9e>P-?Ar?nXMBdxtU|49+F#o!S1;Jw_n%CIiRhO-Yb<~Et1_VEeN~1SeoC8X1$4o2?j(Op zJ9#_pA0uh5`_08XDDB%`ch0SN;m7{x_#y|rk^aw86IoTKm`I7Pi?9<+?=%!OJx40|zN5bIK>ANZKp&X}9+!FeO4w4O zB@5`du4tePexUl%GqliMtQCbvP~LeXbtZEYDqf7yIY37{9*g29$`CaLT-pL)XUZJ-nd$ppS50CgsdpwzowJH9@P00B`H;P<>4! zQx=-uzsA(K&~dRe3F>PrKGtF0BDw0ji@#oo03ap5DjF9H`r{cEI_7n^Dl$HVMT;9! zqsv168lT~p9q0xk;p@ng%z)?LCGN?sbW&o1`r87r?VFl}-ri*)c%AxG_dN7Rd9!0b zL_-6PjAia?FZ#U&IE(6`R#zN0S{5fQf@|x=|u2^9cvQ=@a`c4Ae z@0H6NZItfe_0{#S@gTfz_I>X|oh=@nwD$K?+Dek`wj;S7mdi5FSJUv{zInkhg=DKmKCNzdo|o;-oQYIt zR!yqba1j_WrREbx6L98b=_^>1yC~TrIefi_ z&f~J*NldR^+tqaRKXNpE!DkY0?@$Jswa7m}^YxcFa%+(=4m<1YFbDL=mOzbmGv)TN zQS^0!@wlhZ0GV|CS+}U)Bz-sR{;mPdahe7Q$;tUZY9`!t6Cgi3n(mMKS7WPyt?(K> zlrUy=R5VR=9oW=a+?rl$A+;^eF*Hv$QTrX1iZ4_r%X7ozIjN-Hfhp6<)J;qb@wvWx zC|Ku;Ohzu7V{Y?E#Ah=4X!mX!)@=UvrwI2P(NTFW4ve5D{`%&xm?<9S7xmi~I*=I4 zTj`+}M>pUNay5P3ov}>!Xmf{4X)Iw9=F3>R8h%%fvp|NlXCLs{s^smwDE!O@wc@C$ zprEAFsHQeFh~#yy-|z=6a1s%mR+>JaL62&ju;g$~n+1X~*pJ@BnvTORmaa;tix!U{ zrNUQ51dtf75oT94_%f}^jvGl=9t!#bYlbq?ZEcj7!AYk_r7OSAz6#?ej@m^NZ7L>R zVB=Me%lf+}+{I~`eD`79hWD{e$k@5B(@D;bFeK=klo|{mma~Hn<8C&4CMl3wMOEY* z#(vOweCs9RmKsm(|DuA0x{r+&?2#+CA_dae5m2i{G5W)8UGVw()vI?!w6*r?Ro4pd zHEKTP^(v_9Nq5p4B*y^pG`VmT+H_5+AOTN zJ^(@Bpxvsh-;7;S*4-k2TLd=te(LC^WiEnT-ABuUa=~c<{7=B(rk?_r8Ap`*cI|Fm zh4?|cb#*9eR5}YXd|i=Oq$+17XR#W&XN407e3t8tkLk<4RY-bkc1>-G(=u=S6Y%%+ zfLDeW2Ahu^;-YaL_^T!7j6NtHciov2)D%{6SN1TF`ygo?mhf_zTbI>D_k2| zXdF3OeQNDs(V8K}mzw=FX= zI=_evSJZcJTT8^JkEE#kgrzvaV^Z09kcI}L)R62lKKl8_zCo2D5)0RZZ0r zCEvf_*`j%_WypZQWwwSQu~{5V%(==%5StA zYF%}LH`rdpw~ExGpI2&^9TiW8H-6p@awUgxDHoU$; z&^?bY(K}6%Wu;kw=}n0Csymc~f_k14vQm-O0YV(jXBH(NNBbVzCnCE#JS~R0WLg2} z7~9%0z59xf$9c?VT--g<8^3?<+hS^xJ?L@RMxo(i2xEo5HiKV`YQBz)M-;Z}Ap84R zjZm3#t*>G_yuoVtg6}+l9>uCfK1!%MF6-ySRD8W=83LZ-{P*!g5wE`Jtwx2L&97|D ztItyZ!86s0k#Xt?8banklxtSMU4-3L0IEC$l3r}Q4JNaRoKF(vX5ZVhO)lw~DG50g zRv6a)te(9V&}1{%6|FsvN&Az4P5MtCg#Lk z+N5>_@DKlNdbg7dl!u%r#M#*-k0z6!G-M4Dhejke98hUGzk;(iJ;q9>U+~-j!AEU- zeK))2d)(D;RQzhmf8p7x3%ayFIErv5(A8i5mqY!#XtAKJAE_wz?n4!(+z93WV=;N&AzpJ~2 zH)6>W=-XfBYP%y89!HKpC7dR4Q8yEXdWE~u}A6E zo&9}5Suq0td4FcS&Lh9LpJyV0+x%RSH}@uK-m^Hzyj3%d8Es6DPY!{~$i(Iy?Qr(U zne1slc@f9q(Z^up;x6a1x2wY{r&)DVOM_Gwh`iM$ao#+?ciB#<#(Z7iwUoV?rhK4* zGd_D&T^B!%!ZOK)tY_DM*!0x^#?z(R5H{xQtXqfiN$ps)L{$5RFb-E)3;SH{-G?5+ z71jz&kvlm?)rVn04AOv15lYk$RlE_Ed~O3O7qrROltK0{cRBiGjUvri(xv8MWvoFL zW~qf1;=UT(fgx+1jL78+^k6sv_+pFWYj9v5)6K(T@eRu*L8+`iumItYuNjTeWoXhK zp@$&i-nX-e10()=KW*k80XsIK&^H+YMKJCuI?VF!3d7O;dTBReQr89X-qp-GhCvBU z`Awq}nzj=hxipUz%}VO8R?~h93~#A+&qr&3y6yBn&_Wd~>odt<6EprfGYxzF#^dm; z8>dWedVX5zNMxzSdt%W+Bw??ypnx7p0`l#G2IQ^zD1fB|CoPBno_%$#(?HL)p{osP z8@ZjN)%^2m?m9RfdUp+>Hg*`eao8g`js2>)@#Z&l`2DvY@t$%0F(MqaP*_pfnVGuk zA6cBxO6NJ%kLpQdQNMvsmKD$N>6143Y@)MqO&^k^K5@edTza?Eb4*?NHJ+!pvp||o z3{6k!I}^NgaOkS>!T>kSL^menB6M)Oknu{Kok!J!JhNfVMES_2n^qgypG!nX(unE! z`7+Yeih!dO!QjWmv95)32t0liWAE>T_(NWY&s#L7@5182UNaGvZd{p7?0Ka9+Fv)2 z#H~vjAubRuVN@;>Fu8hrd8eV^IK#2c}om-D^WGk1NtsYfN85BCvwNET_}xU44< zWuxK_{)R{BYxyq(_LLwLWZWRL_&LO1|NgZ8t@|B{K*Vp9R@<}om4xu3UiW#fI+UCQEY~xDNlHz zyrF6TFxBwfQJO-suDX3KbxQNZewxRwcUUvApmxG3c8~C(Ty=Z z(1tI4rz3qka5bCJgTK|?n(el#4!IHOz>}4aYrS#Z~@9b z;Y8M<)7mr#Fls-GJJFWg4^4SSCbaeA*Rq=I&CakA#k|@KTytliai5t@cC?U^@qcPp zs;x$yVDpb5Ocl*7QyM)M0VzW3elNZ|*?6@sBQIK*pWdw+0bN^kEm1_7zo|_dogYv1 ze1}}7kbbDs*$Sk%pRCiBz;-2Ik4i@&nWufVAG+skX?PgmpL(x#SE+HX+oO}3eZ>E{ z$8wX=EsPOKF-vzrC0s8>&|Y<^elP~qaMn{_d`sm{K9TqD*QhF5kA~mL!PO-TGJ!%X zJ#RWz%_WEzeIvK*&r(jw*_In_F}d$wapAHFt2PHy303Jai-essQwB1M?LR}H(}Vds zOR7=r^ZT0CBnwBieuj(-R=8X?z~YPL2LnVeVY8MOe>FM%9Hhxtw`mPZBDN-m7Nv#_ zlSk)#>Yj&&hYhdmsYx~qNh3q=t4`|b+W#fv0F8%uG!9?Smw)BYjj&z26fCNy24>JWOOrK;o!N` zC=a9D8p<-iL%R0yeb;jtW;4fgW?IJyYpQ8dvPh?6CsLm%A&#Z2SDoFybxA)KSfZ#D zR}l7f2vw*~%lPcT(t&zITVXkJs}?0q~3X?{OYMkie-Q|%%{vEIh6 zMw3}UbnX|z4GQj29^7h2%fX`jD<0oBpFi8XFa5qoR-}GyS}fBzAvh6!OZt&v1dQpr z(Q|V~orf9gcxwDIGNnoNeCDuuwU1`w4Ca>jQ(sEMlP9AI*N!ZRCkp&ylxsGaG29EO zmKbrH#xqEE5y8u)30c-l2#gUJ({%Ml9faf;jDE;p(PR_yaen45OP)f(wy)~2zco0+ zWpbt^dGOfSDSt)xCX!O!{4F-OFmJd$)lEtacw0~>|Bysx$Dznz5H`#*isUp8{D4}hSwtAiKT>5rSsT@@<-K%aKPKo+Ks zB>JAe%Pl`G`i%|_gzV{PIZncV&CVLF>oFb*zmXuNFYnzZVLqIu3Yq-@{B+9_6Wm7S z-^JPRmE2eCHsa;Q(n{E@Fb?2w`pzd}B}Zt_cB+Yd!HZ6X=;MzVLkTN*vFNd;;QMHR zhdbU+(>W4l>U`W;*H6z*a@K*!r1sYjRN=I@!2h-85e{U)K8Wz>s=7!q9r^vMSWa{2 zl+`fa`kEd%_`wADR%(K)Til?(Lmd{51A;n0a12Mz`JF^xM|XH`#g2M=Q!IOZM!dyI zsVPQStv}Y#;CJ8WQbxi{v_&Dd?p=I*G*6bt3^_kj*&{7)UGIj~W|vfqO%pVgX~CR* z3oKtE3lDDBzV-`u;!4fu%XEy9n15**M76v#`4`7j^B7B9zTWA*&t|*$KD>9n*7h(G zSx$4S64$ml=4~>>KTnQ@Er4Mnmk+z;4MUmb92Z@~eK+#_S%t+AG|2ueo%=#HA8hVb z(S@v%Bej&*B52$fQ#dLyFh4A<=WK(CLI~mXdc- zWe1gLyam3!+kTueCm*+Lqez6W-c!G9y#cWmGPZ0QwKJE$OXfjM5ptDJfhWJ}@ZE1$ z|B-g`sp#9BcX&O3Y91Gft--T;Hjl+{QgJ;7&P@44HF;pZ#!J3F(3b=x61T+f`$^U)o}(k>PE zQSJBhQe z1}_o$0pcL$`&J2F-4pyx9Zx*^?kVP4o2xI6OG$TFk3pERVfbc)@s{Y**OT{I$A?HA zWw7Gf)U%4dtlEnZdm|OiwlO2+woA}A`!J(`HX_MtjnRZPS@;SQqz}#&)rE8Z4NxJ! z5MfHJ*p=C~K3&WOzKLt~M)#=W2Oem{toC!P>Ycx5kk1brhRe{86KK?jbpM%|>Erpeqzf|>Hru>Wa%8N|z3 zU2o&uDx-X7g2LjcY1S$?dq0RZo`sGI;P1~kG7-X zA8~OS%H;}@TwphX(Z56&J6>a^7ebYsRcTa+uraVH%>{n0B<}lIDKl@v?Zt~p)qln( zmn=IY>j6_uO1f6h`7eUKS9c&U+^%LPA&UQ=jfafqf@sA5=DF0n zpamESPERhWfFAIDeb1>cEccw_qcxq_{7_k2b@<+tN_|Fb56oBVT6^kz^vU}o)aWrf z4)94el6kHIpSsxK;Q4!UzJeheRCRdkhdO-+2|J~Wt5oZ$wYu+R3WEE?*UmP}g!-CZ z`Lq9=7*>9YWtob?>uyIQT$9g5wmT*UCOqqAB$R}u;v^)8osnxt;xNY+s9+=y-QC3T z9zb6*2u+9jLQSF-1%9jYTFgCp;-oKJa#k$Jy$Qh0gfBSo*iBiZH=qAsZgZhvmOH9} zEN{o7fQ5AUm0EorS7iguh^2N_YhL2*4ss82e^3X|pM*Aj;TN@=9f?7IGwIOG?CA~@ zu+D}fe=)I682U2^lccsOulJ92K(}r+O5tELUEJL@af@kXH#P>Y?2@nA$IZ@Bdn52f zE2+YWeD7jzNkZTqfqh)vnd-SY*ol!QhxCV9R3eI68;nbtKJ-BDx3n)TdLC}_b)e*6 z{(^jVk~rIXt~g;mNY1PWHEKb@u!UlsBbo8ZaXNKkN-95n^~_Nb8G2van-hVBY@o7P z7klpEFdxM)1|pQzppZCnY}$!BLAyzE#Dplzu5X+HW}d_utP6}S3uJO9&Ok)li2XdC zhYT!b%ha0m2i{TEBUl{x`X&nVXbHs>ua~}fFjy%|$Ydm=9$89D-#JrhS8FqK#_+lt2n`w;qf1~Szw2s5j3zMmgYEAc}s`P zfL=bhHbY^uS*a-(IJ8aWi+hG#%K!LJ`{rR1f>4KGPF9^bN&k-IQUTQ0UE~BPMK@Wg zzRdmg2={VM4Z#MHB|(`g6a0jNj#br3|AOdlC0&@EEoI>2Usj5DRh^EvhDa&eQkl#1 zm0v0^=eJUi@!%h_NFAUgbE=*7vJkWuF~3eVlW;Cutoo>1zc1;KD$W*pMD13iF&at7Ae ztN4+lN0*zqFZg!5JCH6iLYU|bDG?!nxfMSq-YPsm;<2bu)qLI56$BTL{Gkt9{i(A*7%Lwl@ zoWZ=VU8$w;9#nDYQNJz98wuwJ@n7U-d0J@Xe5&KzkkaBXP3>ofuh`}G@g<|Lx{#@| z4y||3!FIZz2yDFFym^F;)HY#N<3E3DL5SK#Iu3>~_r7tptQSj=#GFwvGj&ZV6+5Q% z>*l;#3`LjP+qmu#3Xzl#j+#JHaE+FImd6w(FQrXWHtRZCayVO7vD4Sc~H z0_wPmUmsx;s&r0*f)0J-B(A$DQ^@G>!-PnDbK|FKr26jp(WFNN^McIrK@TABx20#H z(?Nyp94>jz;}P|j8HM43MmUPwDMl#^j9n360w!B`sqBQR<=>vm{LeymqPX-J%+Kf7 zSmKR~WM*%N*KBx*i8(4Hbg@Ju6nlQia~;E*KPQ>J@~sf{HF(*h_OgSKYtY+Cm@=mQ zNLkbh zZ&arx_ymS68NX;Nhf%{;U6jw!Nfr<*ih}!NS~)1NWTHd$aNVya@_d1?+ zd|!r5dIURB)Hhkwj-xTNRqpbqxks|G`Us#ZFuPn};BQQZREL)%mzAC&??OhGRMKFx z+EEl!YHx{F$NujU3E2gw&gkdD@&^O~I(97H-iLtN&)@a9o1|*vo5bN z_uuxr<=>VDtQ(c)DQQv&ySNcUlpAc2>Mo-raHa|*O>u2h$T-*B6MCU}sB!fh`;+~~M;s9hL zVZSEJQ8AS4Kh+1bTkZ=<_@+{g2R`ji`A`YAYfKGE45y{tl6~ywtU{cgolMCeDPt`b z_k%J}hhYAae9ub8^dx3n&epu5r0Ee6-qmRSqNK@@`fwgHx#yXC-^@6wiKld%Z^}>q zJ$+-N7)=r~5o~bi?SLt05Iibm-Fx)m7a1!NpxIkyB{}f{;?;{XFwCl?m0FfTc7A2~ zh(B{4u+8lcrY98Bza;Z~WlEoyEh%@IkmUPb6Q4z}h6LNZ!RWj*8~qB?LS*yLkXm@% zT7E!ET|$27%W~VWG`0%Mvt28W;VMHl9nJ*4CZ@T`#D^H6*`ejGnx}RXsY7CxLa^vMSvx;YlZn5T79kJ0T`)I?Yw0(OdaN6b1oIG9 zQs0Ck|Kje_e73mV89WKc$DXY%xZ$xtkn_y93&$p~JTp!N?D z_c&IT>xYzt$ausz5s!jedG6?azc9QD;%}{#Q{rT$v2;D;0z-%3?}Q=*M5JaQ~MNL4!)?%EEA77ab;OS*b@`eZqa7#G#ex<*UkD z{Vv4L`k%Blo{on;^ZYaHmbNjRcP=7sB(7{N>%F9XCW#wIMOGg+XeZC0*b#JoNx3** zT(xp(qPfOTXajd8sOg6?KU+apNPD?#ck8kTHu#V&U|qamAecGC)>*rL+He^vbeT1G z+|0)c{p;vXR}@7x&Kf?w34XnF4{$*>kWgh*Z$mp_&95uZmK<^l6jPXp60OacI*{%joY58HaU7YciXQW>yd<{{<4Q7Zneh%df=>kMcRLwd((lCr^E{i(*6f+mY-EghzAsJ@Yu76o zCd|N|NKI(Qs8vIzM9qKcNfE{=)O5pS&b{*-ppLrNR%oVGRAq7a)dahtpb-%tg>+>lR*6!{!C6M z6eZtFT$>F8vO4`(c<>b)rxwSG!fdw2h=JN7?|C?`>{fRCe<#IpO)|#pFJ`R~ zbWI!94x=?GSj~v0mIW*w28BhzABPr7T#>YyjFlKe1v%e8I>m>7xG<*En4h8>;AN1>Du@^xy$ABJYs;N`do=lvtdO1;gF}GnRX5Tg zYJmF4x%EF2H}lv7cHRFe~vVS_I+=KKVCaRB7} zqo}u=XY@bsav7aQY6Lou0;FvW@xmyTCXtcYgubgQL8M92f=ncsnn?R!`Ubk$I4ga6 zzoaaz{>wSfX;~(QZZbec|KUce1$`H z)O=HbwEn9$ZNj#!dRQ-}BSx8_GNJaI4F4d5#wuG=ErC5&wzYt0kimx`F3FG0qTvzH zuL~{4cd5L0X?mB~R``tyr`w9a==Uxo)Z!S%!P-F9tLwuWz-WgREdcE5&q8 z?b>;=arvdugbvGFH1In`rhOf<*(`KC&II!cLbA}$dc7(>3C}t zN$t8T^Vng@&VriNLN#Sfn%($ z+ekTgpa{s;nzyTZABc~{Uy*#QO(mF~neFP-C;hB~d6@|Zg%#YC?jbefpKMJ8GhG+?mt<3v8K-muWYrKiDzA3e2{`WVX<%YT@Cn{G3pxP zf@JAJ35rGf_lq~>GlgRB-XA&i-Ve4LPnH=)Tk4Z#3IW^N9cnbP%Q?@;gI9z}yz?Rs zSlKr1{q}6=*ySb$d<0z84v|?t1Y)gJAEo8w6|JWeq4)^WBu&*!{jAKX1ocx7$fY2b zMr|Z^wZ=6BwUs}AFnMG{!XBGU99mVA9g0_)KEp)=yJ|*D5MzOZN}}3GX~r6574kSP z$*ssUOu!^qmF?FRKlBqU$N{ExK`*2Eh^;lMD!rN=PEW?h`bfF+&txLm*!TBrS5O)Q zU2^uQ1u zbO#%Ev_BY3x5^+kJz%JP{i)qUa6^XKTd`l9*TsBMh&OPb1)2z>6Y{0ONM_N84jXr0 z^F_Fv7HNP0kDqozoUc^Y>>d(>+_vu!y-0b0A6ptj!4tB?BzPJY$A!pWS6sX=<$V5Z z6Cg5}*>E0xP)^HHH<^5-%COuOLdsuSvkx^{Bz5}px;E2-&J58z9iObc*9^W~{1E4$ z1KKQCuzvF(-?@k}jq$N(ckCzt&^nk^6Pz|FTZB|ZVb50_8R{cq<|R|yN_vU??S+xl zqjYg#)nTGydJyilVT*!<^zg(uGZ+@6|9Mm5)TdueKYNw5p3K!`nWnU{tRFnEYhYOP zk#J&_;iary1Uf~i7Y(ci( z#~2!di0bPw!kN@;?!yih}Jd8N$H3s^*`>T_$y}+sgq(tTRQB#>Qf$Ai2ciz0_ ziajq6efFM%`@d<=tl-!q=0{Gk@Ns=^LJSfXH1#kLOZ9iyv3vhcURMaea}{p4>(?D{ zZAMQFV03DT)}7WH$=`=31daqjM0Sik%qj%zjyWZwB5mud0cC_4V74&b@)mgFK0F{cODpBCYA+>_9%Lc69BkrR!K_DEC>uJ&nO(?$g7(`OO+kUut7TXyAPUt z%J#mL0v!g@e|z*TwROh4Soe_*FLNIK7KJ)e?SQ^E@8|Xu()|cP)f~zyn2`ecQNt|I z(Tkfu;Mv*TyYqeq8*Ov=kX61^wYY-@!!6%KezMVNMOp(gGngruW&^D-X>V0*UF> zkf}GO-AL;ew=fY0So0_{v-?@_J>?x1v>{MtuNiP}Hl+4`uyn^h`_(2bCxuu@EL&{y z`7IFWyedzK%v00LIj{J?9~)%$vtH7Lsy9Z}N0^*d=wjRu?ATI|K4VAg!X~sqVay-x zbVzq~JX;V)i7k9C{CT;Jc5;bQVY__?jmdf)jt78WPQVh=j*3r$?ozJa;8`zy5}!OV z^T*QpE@^w3aG|4^-?zyhEfqRD#mTj84NachGY^%Krp4o})fEtfqr!3cH*`*~_htk4 zGp9`JhJAaNlocD_>k1Fjb@M}p-be}kbgw!5s;JzPQa)&s>M2o7%iG@xXE3NhGo_2f z7rGjL9p{?4Go0~wvk!~!IJmOwG2K}R6`VOhKN4Qd9x=GIUgfabLPbk^v}}5&D%*t}CW5Q{b3vlc=u;Pe!=lTcFD(S71K8@#N4wN$e!CI00TFq zvlqbyQjv%z)(^pGU?P zJO>31W-&a=`zFCXa8>y-&Vs-@UvIH{+ho0R!C*teiCS&8_hEa*FGkr_j#wL~7xjQw@LdPMLXX}%> z=g#>8#hyM|8?OtONj z5Wxc(s|07t9onM=xzg)kAKZ7&^*zEfA6%}T7@0{^SXTxtirpN{#z}^c_idNIOr1dk zNBP}44`FpBNOv_1PbCi<=t>TRK!9s1e4PD zElmR`Hr>2@;F*Ut(7HW`L#Ln4=C~%Txn|>zHHbqm))XDUUn@Uqqj7J1|Co*jL2Q+h z>mFXbA~2P;!3xAZdXm>9#x1$p>9z0dVPf`HvzH(L{X z6>jZRer!#fm9Lv^>*FYDxTHgemPQ0T^k-Y){C?INOcX3BYa;9nmxj0t_O$Tr;O^}v zFLLCjYVttx1JW`X&Re0rzh#p@kgcxnOWC9B<#=|eVXM_Z; zS*wN-frg`XFiZy4=5DZFKG16xI?k3Yq9mHe6Zgqs-IX~2l*VB*T*to=p%I&T6qkNP zY{(0qaU_^4xQ_s}+failPZ2v~u%oO|ewqUwhgzzMC0coKuK~kT6qrjR9#o$d3op`P zJJLZv>gR>nobYG-2zZzA>x#zVHfA>rUTLT6?a}QXV2)Gy%}7T#m4~V|yWVSqXrXSu z->UIJ2h}cvIj*@fYSn=^RVr+JB|rJ-+i1nXoZM~e^8*-Y<&){ASU3off;8X}EFPyo zAE*wiaxpCO^V013j-FKD8U2h&em;KRY+(1z==!%3_?+C@I>j92hb+tH2TPvA6W&r^ z%I_jp-ioR8sq55=k;b${U(WhyTK23Eh)Ug%O8FU|He zXsIvDgA(1I7t&rrqvCd7_9MvGk4qrc!>oe3kXalXay0dUmI|p43UmPG2275iKu$<* z@L;jS%2qOQ4_S%ifwJdhob0ygz~3<(dBa@*!koO_xCm`CwS@zqIZ)oybv z$XebwR?Fla&wEn!lb$ctzn1SNhxgt!`cFjdHoHKOX zrZO1Ciz_rTG!1MAn4zQcY1eTFo3mm)T^B=Wxv8~`Rm4G7idt(k?tB*J?V@2MQDDXu z`lcslhl%w#no&g7zyx)`8@TxKoQIu2mhq#!bEo5KOoo1V3gfDX$Cn{2kw0URAP=Ni z{xqI?kF(B*M@2C}Seg}l-!&MEIF@P&7Tp*66dbL3mX#d`2EZ)2vh_p^I?;3SNlIEh zo-7&{>~7^tI?@juuLs`+LXt8!04&7-;xiD5#y*#ld!A#e?wtWMoimZlbBv$CuWceW zIb7P)Mz{3Q4$fP=8|Dt=+Q_;CDcVu-ZiW{O4V&3AkXM&5P7%|J)CV%$ME0x6fUym9 z!#ILo`u)-1zb)%&G~Um-j&c5tCKf@l4D)XH zrKpxYm>ZJCCV);DjPQH3*tmwV+I%T%3uBaKvn?xHvJ%^ZB9qFkm4DQMZx+Pqq{@Eo zx?oGJU{;?Qr%V%3W6KIpOpWIJjaNbz9l-k`V?#Ql8}jxR-ZC}!+sB-z@BIRq95^t> zCD7ZS%dhdnD;(d$w-Kp}gj^z~?Vj#y!K0p$Wl1n2hf%)_yyWpWI z6kSAYH>XaQA#a6TofcVlurlj%V}-W1)TdDnudPe%UNIN3^=mlN$8_h(=Cy{shaN__ zw21N?oo`$**|q~wm;vy8(-~yN;_J6impMsvJ-FgA0`$LXj0*{3pKeXz7c1uF&loN8 zf`lsmDqR_0FthnJ1>Xeu?d!sLg$$zD7+n=+c2C5TGEig1&LEbJW>;6US=l6=Kur4| zVxbxnT!(Bj<9O?WnTc@YX0Xjn!$6jpc)>QKxenT?zs!ca;>rk`jlG9x8r}Cc)po^} zHD(~r7*Rg^s<~j3QCwjg$C~bEUGi|n%-!=Fqcbp3z&y&rt8S~VdUkonzrpzCWv!;7sm|bLCFf)qVjv8i? zP-OFBB-4T`XVqp2>c-zjC7nckcR~ykY6M5j%p|8dQ-lef;E8D%+Wvyk0m z^8QUSF1DDIbIw3Zo*nh!q^6_0M&;BXA*ba4bLvjd-eM{3;e@(beqYO5HQRi=j+|57 z`i|LVHm>R9G;rEklGDIdQ4MCbDII;|lyNI&S$l6emF;UkI;WrY`EFe6l2+nKr^ibp zkwjoD4zrc%wh$s_-3v6lohhHWywj0EcAJ@Vm{xPDJx8k zz^C;BnUJ;7JM|>t6+3~@w~cN+>ofM?itjI;lT4^tG@3ula!Xh-6AU+gr!kQ5sZ#dv5nNKh;Bxho_)U1O)VnYU?{q<~`p zVdPqAR4by~mgljE&J0A{}+v#Oli-De;msQN(f>;_zybhJ?@*VU=Uf>jIds?W_#tHa>PDMlUp%Q zN{!Ch<%osm{m6s*eL(K*nRP3A4$=kRY{es-_0%cJb0#mC^0krqaGR2FM*FUqJLhJ- za1dx3NA82hyvJq58sp*Xt7_+g=aI?r7%P~dxH^8ul^d3) zz;ixfL}!n0K4{FF5xCCrOOmWi+Fdz<%$1}e6G`v|-_3il4D}X1*HPZI)%dYjNVD!3 zLi4tZihK8-UNL2vVi=~Ks){?~g6XA*sA(P+bYECSfpx)m*kVz8%Rr`YZd%VPra2VR z3#2Hp6GV|G@Ctc1M&Ex>8PiXLT4NCb+6wP!PbzJm>B-LjrMjc%8QwuIX^~?pEvF7d ziWzn1g6UVm$hLl_sw~|@JQvLC+A)63eDMADRB>ik%-dJ=C5bAPyLOgcu~J_mf{g|Z z=QrHNGO%Lj8r)B8fl5Si!Smh^<8q=?-DH(oF&%KW8FS(;D5xW;Nzafymu8LO`NMdT zUQX1crOOd8*n8&~2AeyI=ey$h?ot(~DKDo|6esF z(Jv`3(JxngPl_2Vai30MjDQs@(FN1th2=w5dDAP3yDP5vj^CG4tfo7}6e$`P%=$D% zlCpd>@n78Sbj7nih|aO{iUx6C+74YKV)?56 z_c&2gSg)Aj-{lltqeY)R9ASZzB9{De{U8m_QCiE2r#wO+Uu1dnNd{-aPV5{Ck};ct zQG9ea^_3?+8C-{l_7$p37Iogsu1}Uv0k?sbeV?w6Q`G0azsA zrpPgiPb$r$&TZ67bKVKb(q^(6akZ3Ha+SW|yN7!E?r*e(wgVe?$ATHD#@f>m0KI~UF=aWv1 z@H0B`#?UP3D_xF)PJm5QxyK_pefR~>XhRs|j?XrkDK2=dH*wiAr-px7sXnfFw9r-0>UNF5|8RktcXx~}f4syYyK;bxc zM$t(=`_;k)PtDyfCOpjK9KUnI&wl)IK4e4`HD1XiMikNhqAQ{czDFK+*tOAI^+-!So_a zyuxb7)umCYuaHhg=&hz?3^Xe?XFy*tlSkW_;-sOAUAxm;;Y=Uhs*&J(Or=gGD`p^( zMPxGC)Z??%rVAdkW5%13G+!TXPW!*$J4p4z5tQlgvc6a$&wv)r3A!;48klo>#Z2{Z za2NXd&?$^Bm}wJ|qE3$_3(fV`6+a^y!$M&_e!`*>TlO;(OUqg0g71E&YNU-z;!t7g zMW&$O?28oLXoQJ1R%>^mr{mR%?@0=Wv2e`Kng_)S8K+>39r@`vczIg83ud^A<%wV= zbxdfwyS`wGlTG!2@NvPecdwX{HbsIy%=kFp7A}}^JWYZ=Q0$p#4vMtnd~t<7YgjDu zPKP1b=s96ld`EB$4N&||bi*K?k_&Q3*cKYbpV#8dx2}@PLX)QtO>OdUh+A4fa`G=%$=87 zAI-u^ww@X_fGZ~doau<%r={!H;1SOYHeP;|wrM8@DRF9EF@p`MV}*Qvx5#HM_>Q>l zCf)W3T&!a6zhItn`0kyPsYyHC%|Lv?`3DI*kmcu{J7vrAb`^ZEgRw&01t}w_=4}LH!(-;;;j&mO7+oS zF#CKvorZj#7M)=)m{I(Ee>Pr^c@|C1__*LPN@B)>g^FioKkL~NzF?m9H(9#OHXx2M zFTY|2I~mW5**50;vb4t)-w|cc(_B`6Dk`@WKf5p3_$g>_)mb|4V)~M$NzqZ@ouOqc zhqXTyuY~bn|E!q0uZ>rft-{1>5z)d08*3)#!zNpT&gRW+8w z?lKE0vvR0)bH%QBT3WE)6YUrz+_m_@HE2eqMvU_n8R6MT| z%3rY&QLr?3Z5fiQTrDryA{{p)feX_ttjnz{X1!SxrptAWpei}^1>avjSAH;4CuLGT zmu5{!bCHxW1viL^$gXm=2$GBnMj_(giEgZ3@YHIm9l2%d*KOn#-(P#)jxAF9=280C zKuuZa0;AuJp9*Sl)(<68ioEjos}F7a7kpoFJ@SDCl7uL)mEWluVKPbB=Dk?(RCo&> zr!U^!1Uh+EyQZ~VO@1A%M0~WunAU;YqK$GR&9H)bN6zTR59&emTp&)-97lUKFV2X>sIT;3{V(jndg;Oa(t~{eipTfI z6zocE`Qd%|X3-r-URm!yguZ3#znnPcLl@#%7a@Z|a?fXoKZgFX<=gx@4tSivdi_j| z3?7X0bL5!{r{9Yz(qFH~^XvNgtld)kN4@v)Y1AftDeRX_3uW_CTE*>PBz;#Yis`5e+04kuN$V)Nxlalv$lYCJ4i zi*-2G;dRB9V!LFX#m2diiO%_0XSoZ$sXL4LB={PgrB}=~x)F6%1>=P~P+0fpNF|pL z3+70Y0D2q`+s*{wMhLCqq)NmEC|d53KWh zpF$$3y_WR6BrQ(+sCZYgB(~#+yZn|!pdWU2oIho*7q7ss44lPI=A3ke^B-k*9xXw& z@5mOS-7D_RhRggrUJm_&A5GAYXSM?i%EQchyYgfJEsNE7*ZD51_zzo&1Jir8;vJtbTTJK-8IF`T{O-vr&E`t`_6b7xNX$ad!weR zB)=JVd_ZO$B1N@!4PB^veRswx0@+v3wLc~WE{7gW%#UZkdz^l2u8l*NI3TMR(UK< z0W8~;UFdiO9LR^vtcd)Efp#U!3lKz4U8`rKTCmr^B2wHP#@)XeFI+9EXLAEYU^92>!d3NV7IXhv^*4!vyG*VxpB8!=Nrz`Zo{dLIWXk0TX5`}4wG)< zy~=o_rEmis#gy9~E#c1spE0;#v)|~zt)vqd%;(sk+uS?0!(#osPWeZh!zWumm`n-!HxirbG6_4`t$u}A2 z_p!R0K+~Jz3-k?|HoZfu37Gqe$2%Fi2Cw!})^D?TUl3|$!s_lx$n~_MU zBBQ|g+mBR|-o*Kk-od@&=}`KN!|yGIWLPU75=dNw2ID7ktB} zu4tCqWyBs#qWbYhvPVHF@-S<=q7;ya#x7EFHnOIa?V3J=*TzX$c4JF`9kuaFX9MdA z_KK9~b+K>8_(Jaod11iS3ML);j_f-rT6!>dJYcM%fcF_O80WXpnX(t;N-1Wd$EtV=kW1AUOXu#2E z!^XZ{LuG;(vd={MGbw37^bl&8Tbf1PfXE0wH)z5Pf{%)8fd!n^8S|;j3XY^GvOmuF z`dJ=!nw|CO#mFy^=Na`)DI8vIK^|tX|6{0d^4{!yHCyMzR*wkBa9HHQ1_n15@a);| z3;j2SfSd#yem}=(Nqip?g6$o1yxLS~?YIG$QvtUH2vvu-KG+3e`KakVhv=2TW*ikT#!IqJEPf3or-~sLyE`{inl9@ZG z1*2EkEyNtAwwXs#SAf768<@~w6X5e0smx%F_@#oJS0agT&6y?h5+aZb7R57ehl1ZQ ziV7ZqgS%PmcC0FRUKP869A$1ZPO*ziN)i0P1yc*=ke&9^Ewoed<0@dIJ$7^*$a4Y~ zUuEMHXSVme$GXNR#?6n~kdJK$!&cdqdpJ#;P4UXWn0Q+m%xBXOF_l#6&O?Z-X z3O8u67y(2$?(bSqxGA1vg~IR97JO>i1WG#z02imYou&W;i0?(ZSuVHWS73~5K3P!Q=+*`1Ou~XrFVLz6%2j-wW9jr(5QsMh{bQTCh zPjA;Wtb?##9oMf*IZ zA9-VoHJ&?}?l@6d%xj1aO4Cgfqm!0&)<^S(S0vh2jVcIB53_E_^HXWbYOMHZvy!qG zUyCN2tAwk$LrPXt*j8d&(l|Y2;d<15%J#8WX8V2HB+IEpj6JH~E{o*RB7Hl$t$vy4 zLl8RqMl*KSWJ(2C;bvju+d^PTwyp+0J=~b%W^RpThM&%W0oYZ#=`YxJfHMY$`b;<+ zmF?y5QwAS1AH%z5h};})#X|S+*f3A%mMBAQ*2G*bRRg9tTv2nMsU5^C!n7t*33f%k zC9X(#^j4tP!n{e0j24Myf4ugH_gPKsXZEcyNu8jph|O=dxY#D^9p&b7{xcjGl&-4x1ot zPnJlCTei4|oDGD}vA`H+*T@RXDGOINlGtifoRt|`A{I2U@dbkq6F5Q?&-Z)zjr_vE zV6n&VH$`dmcz(Zh0H_kp@&ckdIOP-~h#5dm1Tn85oS^Kx@d+hs?G9xXxoDxBisRND zb)&PaVdS9vLG##5wsrR;y0d*!=wzK>J})*n_*5Ykey|zUyK;nMB25cL3kd` z?=CcB*^WH$K_82xOK0Ec_z2j{;lJ}?*TZy#$av98wqbMsw)mikr{dbNFu|#(RdNwy0&_nfVm+RuML1R`h_$&#VD&eK8x7Q1HR%?L z5MWi4F>PV*#{EsId`$gYOyqO#2TuAq>H>GM-JVA_OA-~k za+HTSjx4`tqmAFHZ9*g_5RH_YI^Z~~5@+(XLtQh)1WIG|EylLTYS-m}*kXY9-F^)- z?~CHb?rR&KF%=|(H6D!gQ-cL3LZW^PzU#er|{&hl<7;k8QDII}x&4@F~0>C^Sk!xMqG-Sm0#+t#2x zAaJ@lZN$`&$yl6Be{NzZ?xug^usq-Idj_0~vA97euzzSBxgts$JEvY(4+2dl>!{~7%g&i`2mllJ&^T>|3W6DJZL^jL) zjaa&jCCktli?wUoP?-xMOG8c`YlluGL{-5ygOSD6BdLR5mIi%olR1oUFNWKtJZA!; z-Y}H3ciHm|$_--QaXRq*ER|!&fpP+We@Fma3WaW(6{NoJP_90}dzzXTT47O-8`KT_ zKG#W+Do#W=jTWOpq~!@0EW7=B+YTO^`S#RlF$2yt@{Iw-8JMY5j5d{9+AI$lY$S6= zt7_R0fN2?WdgP>2FnSpWP1ZIT%`}t^^ad$hB}J0+KyTdE(VHQekE_Mj#?>;HJlh^F zbTj8djAp^ucu*a^xmf-*k)iGev)s|=6o$oMvAd)KccZAL8m_A$1Cx@Fg)IFn`f9O6teA(|AsILo713}9f`k62r`K#te(Foc{} zR+{n$O!e(}dGN?wWb(4JPvoqG*vWSG3F(;g^X=6X@bSEJ%~s~JV6<91@-yn}#NyF5 z-HpY^=XQ$_g!$1`M7PX<4!qk|#XT6O5{w$+%==OKSsZf1SR*$i@W7I47QKM=r$KUc z6$?a48z)SqN2_VC`%&7)2&>QZ$Ids8joGZGy&hfe>LCUcOPLwVi_t$-%gjyYagm-+ zy*cx)0KwSJ8fhllA>P8NQ(T$Ekg#UmludZS6=Ti>G5hTDT{5_t%mr@^CA<#PyXmkL z>8(u#5&l}i^1Y{K8$d3mKcahlL-5k(08WSl7WC|Hx@YI+Ej?S&roa$(R5vSk8%|ve zSUZBGkC)dhMHZb-%!*@D9PgHZp?^dqX6}H|u*TUi1Q+xi5fV-%8(~Vt`l(fQ44;p& zg?Yxe4=<0+Y_oCc*x9i?;OYS5Qcv554eO)hSbDSL*rtILJMW4sIl?=3dbGQSgMnF^ z#)`pjPFCf(iP_ndUwJba_qj3RS|~d`;X~0DXDjkKh?qkc1S=HVAI+}hyf$rLyy#~* zzF$f6N=9sF7S(mt1=G7zi~gvOzP~_RtHTw6t_02sTbukqR!nZwVuHt5Ru7ACAQKq$ z$Ha~*^Y7zshYlE()S{L%w(_=@9$cW%=B==97A}|rvDp!9=8$!fcflM~>xzx^0Pi9JNkrZ(nO?DW8#?z0Hx~wq$P5j6V&f8 zR!j}Y?^(7O|xxAb7I9x!^@-GZFWO&ruO=z3&opvfj06hzQ1_hqt*zj zYf@d?^a>e)LVdy5%1;7!fl5Nmy_``ZRn~P{DOP+_$6C#ux7*aM=eW7$OdGrL+LFLA zZnE(?XXF_^5L<7S$9)b}lB?c|DHsybiT;?1)3f_+AJokY=3<=v(-dPb??{`kWNUo! z#T7pik(@GE0VNLX#pZ`b~;)V;d8>$!ud- zXJYb@)(aGW=KSNq_XF{{Pr~#ldhJA#@41}TmOSdok9Ssl7&D?P;VQ>!;^dg_tB9!y zL4Ju%b8u(4Sfj*+l!xOU;{Wg)XLo8A@4&2zkr3vl;CxP9b8yAa!H68E%v~UT?EgHE$@Sd8@B zwAUFOSuLvb+KrEf@y!@tgE{??ewM7~E54a`FWfo9^t!FZ-9s0AGwc&&}g?7a6jCb z#&=An-8}ze+lh-jTuPG*0JJFP7>wRyRk}j-dYsAF zkK&0l5$mUOPDTtf-e?S?L$vC8x0nw$(uIr& zH-VAw5t#X^qvd-9F37n&-!B@CX!#z`&zs8o@4dWD-JNE2gznT9ZR#eAUTK`0CL@cJ zP$haQ0K+&>q6myIE#3#+L&@S9LJmLTG4r#nG+5){kR2eyoa;D?Uj&@XB@z$0$LeOR zL`<~QX0q{;#nuF~Cssbpbu8a(ZH(_#OagDN*9YCvSzWjq02T;6SzIoo^=Qs~noN88 z=M}A@YNA&od$?dmmm)wLwI1VS768)XC?1mbkr~k^%B>j{y5jqb=kSp8 z>rOK=zK&rZbo}DqWjbP(?tW4W)=}8mr91(PqKV8v0OxfEpTYlx5t#AZ$5ml#jW4QR zmeE&Lk&IoNlhgv7mCF%n+>J!u$4;?mBB(O!mQ(eGJ$f0eDQzYhVBTb|Lrc!# zGu2&yY}JY)K2!Wmlv)vL zA<_ln?px{MTw%IkPKwB!Av>KZXE$pzCV37|fjgZmBeOmvi{_4fde^%UWJ*P7_Z6%Z zg;JzAy?}A*?x*Z0H7XZIGRHeyV;TP(9FMZIrTeslD~GALIDNHZJMr5$`gm(Ws0CO&w$YRypj>@cHuQ zM=gCj)2J?)X5CjT+xf90I7OvmiK~sdI40(AU9>Iu`SR{ZZGAiYVbPW?xxBzzAWb*` z=dWBp=T1rT+mdWY3Pqwp)SVanyuSKTLqFa?_ns@@nJa07Q}!8BH8oC`e%7g~ z-<)SDlk34vX|-4UyuSKTL*LAO-Y+w!{b9wFqUqq35=nO{p83`EP@R4Kw?+3zD}KJb z`%zop&^N`|TKr78;2YDL(n6Fhj>8X?;!dH~y>+w2)Pq0KlaXEU^X2`I+WTfY({XCh zA#}wSySiyK;}Pp>oGv^RB{nzH;_azj5AAuu&zILfYVMncNa?8|$8MK&qC6vsc zU7>695Qw`+wzpdhllVt{DO~XL<^7M^`)10M2kVw9s?QbEYSwfG#_6n>`FUEwofp~* zLlfF7cM_L!7yNvA|D*Q4UCK@Qs7xErip^6qc| zf}bz%f7IT$)1!7BOS(eOSA4_#Bi}DV@wj}QL0@sC-rQ`{d2iFcYu&Zr=gaF~Z*JJ$ zP?z!(rtY9uET=7?e%1_~XspxHGS7dmKf8z2f}bz%e$>`aK*jo)?Inm$KFbGV#pdw= z!lT1q!Wl?*qs^QQB+Tn@@JQL^yd|lp6-fzmuOC?Pqdxd}73*D$H+GdELh2RLiK3DB z`s4@^tX&H<-W6rNJvdmTciLObbL;wnGknwmZ*3G6VV!cRJRjJWr4N%wDqS#rstV%~ z)AX;J?7J%#GbcS8Z?;{zOeVeMkq6+4v7|3kaO6MSvkRDJYAv=bSOtQKOeZ z#2Y+^7$gWLwa|$zqDtJ%-C~B}l#18GgDhH{AAj!EQDB{w@5C^#@%70<3{oqT))d&f zdTg%M62^hzB`|E>yfX7XY0#X3CPWX&g7<+@MT1~vKu{1kZLr7Sg26WI7Qcl^Vi5Z# zMQgyRAw+jc)WH%lAI4t;(GLjPVTN1r^+(RA$?BZVNilWf(e7QLBQP+;gT8?@!$SZ? zix3{VEnk-rw~EH4bkxRuTUnb*oHXK|l3C{D_eQRUE#AvsxUsmNL5u^*yKWRI9T|6W=1UM!3u zuw$1f2g0DBiDLb1(HxC58nd`~aM;h;0)#`fj$|wuxB@uL&c3ZHL9E{pnBD>`A8?GU zdos7aJx)JNx%t_+My&rT`shk85@3|``rv)+_{z@1=OX(WzAMpOwXp~#JE~4 zbt*QlnF&J>++z02Qaf-&5S+P|&#kExdE*xULz;f~Y_!bhEAQEb14yX z*74wu@V-eD+MVVm5$MFenI7O_;oi}7*5BxFNcT&`B8AEDJIe*S*XkW;M-w@xI=3`$q?hNircQyCvVQxDAN9!jQ2du)e?R~H{wQv}^3|Vy`1Y6I{pQOt zz+b+2_WK`x{O-5k{O#zXpZ@cY-=3c1L*Iw3eff@F|4e)Cjs0rf>3Vj^30AI>Aoh&d z4#r?Km^=N7>33eaA#UQET{{pPTr@T_1P`tszrY6_vcKm*`gu0$6L_7ydz9sKK6~Vh zE8X>Du${h<8Ctui@BAxflmO{`$ePmTet0M%P{$Hk?Rw3(%lEJNQLnt`EczL@>=PU^ z-#OmVr?5}a1=AK_)G=^>$06D^H@mA`AX(1$ZhcaZ3=iin8Izw~5<|Pa_}Gdcb;)~9 zo}X*8K0!8#ca5~usMaPg&J~;En*vI~(&Bz_&1{BngNvQfs0fRIi%L$Sj}$|U>4b7h zSuq(2K*z#_Gl*thzy7FC-lHFVw(a_O)Bk(MTEyke$uJgdWErAqZwCwR(S>7G?3Vj! zt47K~+BDdb-~;KTF4Dp;*t~L)Z3{kHBmiDM|EN>mb3gF;HtdZxv+4NUbe*wcI$uX7 ze;S9Z94GaOv-ATewW4HmSq)K4XJG7_^kNExUNQY3HxcQ!eo7~3-+$06;RDpO&$MN4 ztfS3TiA}f93$EmB&CzfIGcKww_1f zf+;^6{Ry);i-Hna(+M_J-K^2Wxy17=T=6_k&VG`V8i?LoWUGKT0c#;CI~`Qbd#~uL z)%`bPKj`1we-kTKfk5)lPRtTv^$lz5m zdQ{faJT5|7KXOCYd{Z8$SR1{ZRO4kB9!-ijbn4MHy?4Tjx%BBL4u&&O`FY%v4+pM< zx6I+PzzF@`MaPPtFYkZU-naAWQKH;g{}o#($JU5R*y&zKQ40Z~>+lKz7X;WscZng* zumwI}-u|eyZ|Bo97mI4YVhVmlY$6nruC#f|vo3y>y_!TTbo!TzQ}m#>1wUV2|ERfd z=M&wvf^GG$klwT4Sw`(Z@)u-Nap_Gj4r?s0aObbZ2DIYm_3e+^`gZO-Qe%*>$lSFS zOnDU%SPmuwk_BoHocmfgU*cp}n69^Y;>-(vzP$fId*d4>qw%TCxr# zBz3dKXUJ^-xz3{td|toxsHtzqxG#P@4->y&p0+@QO1DwszJ!TGw+oC`C^Wmz-)ChV zU-9$h{g2xFb_C<@=9w;TrLO%TEl3Gmmt+w2BxRmorqkp^WjyYO7pbD*FZlWL`bW+E zc%}2*hfgC|ti=d3&xi-CI(A%;*)YR|AFxW+gfIen5ceRX2{@^D+UDS=Sjm}9uO#st zT`-xVk!k=$KebO%b^H3G{&stD>QN zu`pO9i!d$9w3rKKc8G%VQ3`g~R^`Hf#YcH1L3TR%DS}pPEa*HMF=0Uy^^d5v&#;m` zp6@OevhRfN9^wFOeW9>javLIoXFnf+-A9+1J&|W`yS?bu6+asFw>BDYp4;1l8qT;< z!?chEJIu)^S_y9v5@E;v&T&rGcREHTshK4@kI)%gY6?cY<}4@Pr7n+pZ7Ut+ri} z?)`T8_M;y85bN;g*Qz(ZymwCex%;lzIO|zwGmd&Br4nMLAo3ba+*C}qRr27bnO~kq zv=!bG*cwrmO78N_M?LWYclMuAYu@;(e#W@Y!2JbVOf1ic{Y(#}Gb7?_jnaTx%N7*$ z?}ls&zg??h#WbXBd{aEf;=U^|KBN!0r2ouX^v0T2s4})qx|;=)zxyGd@7c`n($S){c_J+3%d9VZk@xjdixrXhr@z zbp=9ftt{J5>Yu!+ecIE4yrfsm*=@bS->%<%&>Q(fyd*!b7QMB05CyEhLyJ#7>GSOVci6FMRlQ*;wnX zLMS3#PZrO5K9Yl-FhjN*+!Aq0-EWt#KkAbYagY2Q+x6D^S987tPqDFJ(-LvT1b&3D zza-%7$efnQV3Wlb$JFd_f2i%~l-(09Ets8xR5ull#3W^0zW=CKK131wJX`kG8rcg@ z%mtHA3Gp4|+e6rDm!2UuCY~v>ajI8(5>(sR5QGZ?1-}!BI*YEDH#zV$sLcGAuN<8Z zdZm1bX7+iu?5%@XoDQy9HjxF|@go_#$%bH5^-z??dKwI)JcymVX_wc=ig`a|{?vA5 zw|w?dXME5_Ar2A!&UQ{27u|lO?#sERWc`Xd3boRz@`J| zif``Z?*R_WcOUh}2i-n?RxNsStC$Ch$WLg+JQu)K6~1b_mb~f%Js`sTa9=_ryz|VJ0-AFQqb!*OO3Ta=FyJqk}>5|x?Mj0s7pRb_4@pp z_13mAccq{7i3_Id{YHOfqf^xEbr)V7F|2I2L>Ai-J|_3NprQ-3B=oQ;gVG(OPwRId z^~Q(T#6GVUy|pcDrZDik^#$`r)mrGcvE~OOBF1jLk)*{K3BP#<1XQbd%=Q_!=&d!cba*aVg#3c3dsyBS%Vv0lS6DCxuhQ-A7T(VARxTDx(aVvj zO&xNQaK9h(?Lk$%iOlpJTh; zF6oVuHBUdA6*CQ5y3GVWMJK^5KI6>ThNL_i`3Qq!9*q@0U*7$wt#23L>7HB)@LVA8 zt-`cf&18ul-f2E!F=r&ht2_Z8lD?7MI_7?Tuq z!h7?`RM953#2X77fyM;A&7YeLUg7il@&`lvc3E%s=HZAYiwtMSqqf}|JEY0R#>(wD z+uixjd~OyU(%4vkpGlz$e!hI~QG4GkymPO9&1A7L7p&1KjBc^PRj7pW$nA9qX-2G46-fI$87~fSnw~S|qYiI*)3qn4%VXsG%*@(HHSl{V1>sa)Cyr?3o~%zWZn4&)VT5LjRb-Zj zfiMn*6Hamn?H;{{Yt;lZKufnvZ$28+PoP-7b4;Thl2iA~$3(Mc>KoJ80uO;>Ar!hC zgv3sw&jWYHo(Myy2@4DaC>=_kd|au?agbM+_O--|Or*F?JwBD#C!Lee7f{)2LR1b& zW~6O`LZ9-fxEt?Ahvvu*u01lVPum*rKk3C7E!@NSK53{8&88pc69R;gj~-+YFwf1N z@c^QM`%Y{<6PZ{SZGq>^+L4cj^Aiw0zf)StzsLIo7?hNWsk=q7)7b}L#yW~yp8$7` zeq(|lq@_brWX$1CQyDE>d6UN3;Rl+yWHuHD)u}Ck2JbR?1NoAGR=0OsGRRO$%;_-H zff#O{$1XW*=fEal#u9Fo&*NsT+4nT{LKhj9I@*?0L^cE1*0T*Myw}|JlX{$~ruQvy zNL#n0=tw1yZ~<}#jrlHUM{4TSY{vs05(cn0(TeQ$cG4Hw=^|OD(if{!02sw2bNUsV z-fc^_%UC^{F`vNR`_36tY$waksE)L5F)%{TLNx+~a5G;Jg>Gcef>15dL&mLRvIvaE zc)7@Y1Rjx*om?NJRD2sVc@%pqqw$U`akDB2E9jNeC$ac=Nz{g+!9NVj_3YO!F3JX$c?fCs3BC&0|@_>Z(H3j0%=ZU0#oO68t(*2Jn!6&f7zdPZ%t&7x@eFRae+sM)m`??rfClL@lAX_;ah#>!wCN;8$sl>v{ilvzGw&R`|L7zP2X9J86b zx(?XzBpWF6suPt(4jSz0sqME*vwG|(3h$$x&-e{s8iTT`8?caTV3pqkpZ=tiP>zKo_i*aEblVI-=9=H zWD&{?!h*Xmnu7=ocLSd?X5fsCeYa)+?-c8Z0P54N`zVj#F2ZO*TM25yzNvPbX$=y1 z;NS>0a3z|nYHO8>IHE|7$u2Em;K+Rz7FniP9qphLFDz~*!7L6}ydF7-u&HF!rkWDK zU4Tl!zV0#&dZ0m2iGjtVnC)qk_M7pOX^Kng0&M+%Bf~;FA!7gC4XlAm4TUN~HC@rU)EPbKqz_4OF zfR5ir)nuvXqu%>?bIW_qXS-_Q49E-Sd2C4HqB;kc<6>Q1F`sYjk1qC3s?S-WJ}c${ zYxKM_{9eBNs6XDC4R_X&YRmnC*`_i6Rm`&DBTdaxh%b=A4%T<(acO3^pS(?;}xt#}!uzX^Q@JV{XrbtnZj`ICDefd#;y!nY+lfmfbR!FJ@2r!S2 zmm=@&Tk&}A?aQZV`Z-BgOvQa;Puu;Wrf`w*XT>**+s7od(&uVE>bkc+I~PgaDg)Gt zNf6LD`|F8_AT`Cste8zQgIzz73%D%3V43>S9r)O&Az z=+qKQb|rc@oE+N_Q%&b$NqIGXt(b;@#1kb;ukU`)!uO@*`sfxa&E+&WF1WBw+bz?D z8ZERPK6}Q{1y{e^2}X5@%N#obYBsHSJdaOiDC2BOeuzV@*A4 z75OQ1#p4{2hc-F-W7N})Kt@S=zu;TODq-t3{%waA8`}@MsU)Pn|p4#XNeC289de^MR1d^mh5;qkec}O*_v} zUNeDQ@GUoNCWZ7$Lmu$T+nGQv_?B^-#9xlqNhk3T^$Q-)`Cdrf+vS^&dg6_>?BZPL z8&~>s)>(AA6|H!bBgG9Y0{mY{huqmC&zE;SYSCFwes>nkcW1hcdwFlB%iR+zP| Currently, version 2.0 of SVG.pm does not internally support DOM +# > traversiong functionality such as getting the children,siblings,or +# > parent of an element, so the interaction capability between SVG::Parser +# > and SVG is limited to manipulations of a known image. The next version +# > of SVG will support all these and more key functions which will make +# > SVG::Parser extremely useful. +# +# I plan to replace the /XML::XQL(::DOM)?/ code as soon as this is +# fixed. + +#use SVG; +#use SVG::Parser; + +use XML::XQL; +use XML::XQL::DOM; + +use vars qw(@ISA @EXPORT $VERSION); + +$VERSION = 1.02; # fixme: use SpSVG 1.01 doesn't raise exception. +@ISA = qw(Exporter); + +# Symbols +@EXPORT = qw( + +); + +sub new { + my $self = { + status => make_status(), + name => '', # Name of script + usage => '', # Usage string + opt_help => [], # Used for --help + + ids => [], # Array of ids that will be iterated over + # in process() + svg => '', # SVG document object + + }; + bless $self; +} + +sub parse { + my $self = shift; + + my $infile = $self->{'opts'}->{'file'}; + + my $xml; + { + local $/=undef; + if ($infile) { + open (IN, $infile) or + $self->error('IO_ERR', "Can't open $infile: $!\n"); + $xml = ; + close IN or + $self->error('IO_ERR', "Can't close $infile: $!\n"); + } else { + $xml = <>; + } + } + + + $self->{'parser'} = new XML::DOM::Parser; + my $parser = $self->{'parser'}; + my $svg = $parser->parse($xml) || + $self->error('INPUT_ERR', "Couldn't parse input: $!."); + $self->{'svg'} = $svg; +} + +# Return SVG document as a string +sub get { + my $self = shift; + my $string = $self->{'svg'}->toString; + +} + +# Print to $outfile|STDOUT +sub dump { + my $self = shift; + my $outfile = $self->{'opts'}->{'output'}; + if ($outfile) { + open(OUT, ">$outfile") or + $self->error('IO_ERR', "Can't open $outfile for writing: $!\n"); + print OUT $self->get; + close OUT or $self->error('IO_ERR', "Can't close $outfile: $!\n"); + } else { + print $self->get; + } +} + +sub process_ids { + my $self = shift; + my $func = shift; + + my @ids = @{$self->{'ids'}}; + + # Apply a user supplied function to each id + foreach my $id (@ids) { + my $svg = $self->{'svg'}; + #warn "ID: $id\n"; + my @nodes = $svg->xql("//*[\@id = '$id']") or + $self->error('NOOP_ERR', "Couldn't find element $id."); + my $node = shift @nodes; # Ids are unique + # fixme: Add more checking. + + # Call the user function on the node identified by $id + my $new_node = $func->($node->toString); + + # Replace the comment with user generated SVG + my $parent = $node->getParentNode; + my $comment = $svg->createComment('SpSVG'); + $parent->replaceChild($comment, $node); + my $output = $self->{'svg'}->toString; + $output =~ s//$new_node/; + + # Here the whole (new) document is parsed. Probably VERY inefficient, + # but at least you get syntax checking for free.. + $self->{'svg'} = $self->{'parser'}->parse($output); + #print $self->{'svg'}->toString; + } + + +} + +# Exit status codes +sub make_status { + my $self = shift; + my %status = ( + 0 => ["SUCCESS", "Extension exited gracefully"], + 1 => ["GEN_FAIL", "General failure"], + 2 => ["MEM_ERR", "Memory error"], + 3 => ["IO_ERR", "File I/O error"], + 4 => ["MATH_ERR", "Math error"], + 5 => ["INPUT_ERR", "Input not understood (not valid SVG)"], + 6 => ["NOOP_ERR", "Could not operate on any objects in this " . + "data stream"], + 7 => ["ARG_ERR", "Incorrect script arguments"] + ); + + # Generate error subs dynamically + foreach my $exit_code (sort keys %status) { + eval "sub $status{$exit_code}[0] { $exit_code; }"; + die $@ if $@; + } + return \%status; + +} + +# Create an option array suitable for Getopt::Long +sub make_opt_vals { + my $self = shift; + my @opt_desc = @_; + my @opt_vals; + my @opt_help = @{$self->{'opt_help'}}; + foreach (@opt_desc) { + my %h = %$_; + foreach my $key (keys %h) { + #print "Key : $h{$key}\n"; + if ($key eq 'opt') { + push @opt_vals, $h{'opt'}; + } elsif ($key eq 'desc') { + my $option = $h{'opt'}; + $option =~ s/([^=]+)=.+/$1/; + $option =~ s/([^|]+)/(length "$1" > 1 ? '--' : '-') . "$1"/eg; + push @opt_help, [$option, $h{'desc'}]; + } + } + } + $self->{'opt_help'} = \@opt_help; + return @opt_vals; +} + +# Parse command line options +sub get_opts { + my $self = shift; + my @user_opt_desc = @_; + + my @opt_desc = ( + { + opt => 'help|h', + desc => 'Display this help and exit.', + }, + + { + opt => 'version|v', + desc => 'Print version and exit.', + }, + + { + opt => 'file|F=s', + desc => 'Input file (default: STDIN).', + }, + + { + opt => 'output|o=s', + desc => 'Output file (default: STDOUT).', + }, + + { + opt => 'id=s@', + desc => 'svg id to operate on (can be multiple).', + }, + + { + opt => 'ids=s', + desc => 'Comma-separated list of svg ids to operate on.', + }, + ); + + # Create option arrays for Getopt::Long + my @opt_vals = $self->make_opt_vals(@opt_desc); + my @user_opt_vals = $self->make_opt_vals(@user_opt_desc); + + # Append user options + foreach (@user_opt_vals) { + push @opt_vals, $_; + } + + # Where the parsed options are stored + my %opts; + + #exit 0; + + # Parse all options + GetOptions(\%opts, @opt_vals) or usage(); + + # Handle comma-separated 'ids=foo,bar' + my @ids = @{$opts{'id'}} if $opts{'id'}; + if (exists $opts{'ids'} && $opts{'ids'} =~ /[\w\d_]+(,[\w\d_]+)*/) { + push (@ids, split(/,/, $opts{'ids'})); + } + + # Display usage etc. (and exit) + exists $opts{'version'} && $self->version(); + exists $opts{'help'} && $self->usage(); + + # Save id values for later processing + $self->{'ids'} = \@ids; + + # Save options + $self->{'opts'} = \%opts; + + # Return the options to script + return %opts; +} + +# Exit with named exit status +sub error { + my $self = shift; + my $error_name = shift; + my $script_error_msg = shift || ''; + + my %status = %{$self->{'status'}}; + + foreach (keys %status) { + if ($status{$_}[0] eq $error_name) { + $! = $_; # Set exit status + + # Commented out; let sodipodi handle the error code instead + #my $msg = ($status{$_}->[1] . ": $script_error_msg"); + + my $msg = "$script_error_msg"; + die $msg; + } + } + + # Will not be reached unless an improper error_name is given + $! = 255; # Exit status + warn "Illegal error code '$error_name' called from script\n"; +} + +# Some accessor methods +sub set_usage { + my $self = shift; + my $usage = shift || die "No usage string supplied!\n"; + $self->{'usage'} = $usage; +} + +sub set_name { + my $self = shift; + my $name = shift || die "No script name supplied!\n"; + $self->{'name'} = $name; +} + +# Print usage and exit +sub usage { + my $self = shift; + print "Usage: $self->{'name'} OPTIONS FILE\n"; + print $self->{'usage'}; + + my @opt_help = @{$self->{'opt_help'}}; + foreach (@opt_help) { + print pad($_->[0]) . $_->[1] . "\n"; + } + + exit ARG_ERR(); +} + +sub pad { + my $string = shift; + my $width = '20'; + return $string . ' ' x ($width - length($string)); +} + +# Print version +sub version { + print "Uses SpSVG version $VERSION\n"; + exit ARG_ERR(); +} + +# End of module; return something true +1; + +__END__ + +DOCUMENTATION HERE diff --git a/share/extensions/addnodes.inx b/share/extensions/addnodes.inx new file mode 100644 index 000000000..0ce315857 --- /dev/null +++ b/share/extensions/addnodes.inx @@ -0,0 +1,13 @@ + + <_name>Add Nodes + org.ekips.filter.addnodes + addnodes.py + inkex.py + 10.0 + + path + + + diff --git a/share/extensions/addnodes.py b/share/extensions/addnodes.py new file mode 100644 index 000000000..d9814e066 --- /dev/null +++ b/share/extensions/addnodes.py @@ -0,0 +1,92 @@ +#!/usr/bin/env python +''' +Copyright (C) 2005 Aaron Spike, aaron@ekips.org + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +''' +import inkex, cubicsuperpath, simplestyle, copy, math, re, bezmisc + +def numsegs(csp): + return sum([len(p)-1 for p in csp]) +def tpoint((x1,y1), (x2,y2), t = 0.5): + return [x1+t*(x2-x1),y1+t*(y2-y1)] +def cspbezsplit(sp1, sp2, t = 0.5): + m1=tpoint(sp1[1],sp1[2],t) + m2=tpoint(sp1[2],sp2[0],t) + m3=tpoint(sp2[0],sp2[1],t) + m4=tpoint(m1,m2,t) + m5=tpoint(m2,m3,t) + m=tpoint(m4,m5,t) + return [[sp1[0][:],sp1[1][:],m1], [m4,m,m5], [m3,sp2[1][:],sp2[2][:]]] +def cspbezsplitatlength(sp1, sp2, l = 0.5, tolerance = 0.001): + bez = (sp1[1][:],sp1[2][:],sp2[0][:],sp2[1][:]) + t = bezmisc.beziertatlength(bez, l, tolerance) + return cspbezsplit(sp1, sp2, t) +def cspseglength(sp1,sp2, tolerance = 0.001): + bez = (sp1[1][:],sp1[2][:],sp2[0][:],sp2[1][:]) + return bezmisc.bezierlength(bez, tolerance) +def csplength(csp): + total = 0 + lengths = [] + for sp in csp: + lengths.append([]) + for i in xrange(1,len(sp)): + l = cspseglength(sp[i-1],sp[i]) + lengths[-1].append(l) + total += l + return lengths, total +def numlengths(csplen): + retval = 0 + for sp in csplen: + for l in sp: + if l > 0: + retval += 1 + return retval + +class SplitIt(inkex.Effect): + def __init__(self): + inkex.Effect.__init__(self) + self.OptionParser.add_option("-m", "--max", + action="store", type="float", + dest="max", default=0.0, + help="maximum segment length") + def effect(self): + for id, node in self.selected.iteritems(): + if node.tagName == 'path': + d = node.attributes.getNamedItem('d') + p = cubicsuperpath.parsePath(d.value) + + #lens, total = csplength(p) + #avg = total/numlengths(lens) + #inkex.debug("average segment length: %s" % avg) + + new = [] + for sub in p: + new.append([sub[0][:]]) + i = 1 + while i <= len(sub)-1: + length = cspseglength(new[-1][-1], sub[i]) + if length > self.options.max: + splits = math.ceil(length/self.options.max) + for s in xrange(int(splits),1,-1): + new[-1][-1], next, sub[i] = cspbezsplitatlength(new[-1][-1], sub[i], 1.0/s) + new[-1].append(next[:]) + new[-1].append(sub[i]) + i+=1 + + d.value = cubicsuperpath.formatPath(new) + +e = SplitIt() +e.affect() diff --git a/share/extensions/ai_input.inx b/share/extensions/ai_input.inx new file mode 100644 index 000000000..a6a5794d5 --- /dev/null +++ b/share/extensions/ai_input.inx @@ -0,0 +1,16 @@ + + <_name>AI Input + org.inkscape.input.ai + perl + ill2svg.pl + + .ai + image/x-adobe-illustrator + <_filetypename>Adobe Illustrator (*.ai) + <_filetypetooltip>Open files saved with Adobe Illustrator + org.inkscape.output.ai + + + diff --git a/share/extensions/ai_output.inx b/share/extensions/ai_output.inx new file mode 100644 index 000000000..ebed2a194 --- /dev/null +++ b/share/extensions/ai_output.inx @@ -0,0 +1,16 @@ + + <_name>AI Output + org.inkscape.output.ai + gs + org.inkscape.output.ps + + .ai + image/x-adobe-illustrator + <_filetypename>Adobe Illustrator (*.ai) + <_filetypetooltip>Write Adobe Illustrator + + + diff --git a/share/extensions/bezmisc.py b/share/extensions/bezmisc.py new file mode 100755 index 000000000..7efafa3ea --- /dev/null +++ b/share/extensions/bezmisc.py @@ -0,0 +1,250 @@ +#!/usr/bin/env python +''' +Copyright (C) 2005 Aaron Spike, aaron@ekips.org + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +''' + +import math, cmath + +def rootWrapper(a,b,c,d): + if a: + #TODO: find a new cubic solver and put it here + #return solveCubicMonic(b/a,c/a,d/a) + return () + elif b: + det=c**2.0-4.0*b*d + if det: + return (-c+cmath.sqrt(det))/(2.0*b),(-c-cmath.sqrt(det))/(2.0*b) + else: + return -c/(2.0*b), + elif c: + return 1.0*(-d/c), + return () + +def bezierparameterize(((bx0,by0),(bx1,by1),(bx2,by2),(bx3,by3))): + #parametric bezier + x0=bx0 + y0=by0 + cx=3*(bx1-x0) + bx=3*(bx2-bx1)-cx + ax=bx3-x0-cx-bx + cy=3*(by1-y0) + by=3*(by2-by1)-cy + ay=by3-y0-cy-by + + return ax,ay,bx,by,cx,cy,x0,y0 + #ax,ay,bx,by,cx,cy,x0,y0=bezierparameterize(((bx0,by0),(bx1,by1),(bx2,by2),(bx3,by3))) + +def linebezierintersect(((lx1,ly1),(lx2,ly2)),((bx0,by0),(bx1,by1),(bx2,by2),(bx3,by3))): + #parametric line + dd=lx1 + cc=lx2-lx1 + bb=ly1 + aa=ly2-ly1 + + if aa: + coef1=cc/aa + coef2=1 + else: + coef1=1 + coef2=aa/cc + + ax,ay,bx,by,cx,cy,x0,y0=bezierparameterize(((bx0,by0),(bx1,by1),(bx2,by2),(bx3,by3))) + #cubic intersection coefficients + a=coef1*ay-coef2*ax + b=coef1*by-coef2*bx + c=coef1*cy-coef2*cx + d=coef1*(y0-bb)-coef2*(x0-dd) + + roots = rootWrapper(a,b,c,d) + retval = [] + for i in roots: + if type(i) is complex and i.imag==0: + i = i.real + if type(i) is not complex and 0<=i<=1: + retval.append(i) + return retval + +def bezierpointatt(((bx0,by0),(bx1,by1),(bx2,by2),(bx3,by3)),t): + ax,ay,bx,by,cx,cy,x0,y0=bezierparameterize(((bx0,by0),(bx1,by1),(bx2,by2),(bx3,by3))) + x=ax*(t**3)+bx*(t**2)+cx*t+x0 + y=ay*(t**3)+by*(t**2)+cy*t+y0 + return x,y + +def bezierslopeatt(((bx0,by0),(bx1,by1),(bx2,by2),(bx3,by3)),t): + ax,ay,bx,by,cx,cy,x0,y0=bezierparameterize(((bx0,by0),(bx1,by1),(bx2,by2),(bx3,by3))) + dx=3*ax*(t**2)+2*bx*t+cx + dy=3*ay*(t**2)+2*by*t+cy + return dx,dy + +def beziertatslope(((bx0,by0),(bx1,by1),(bx2,by2),(bx3,by3)),(dy,dx)): + ax,ay,bx,by,cx,cy,x0,y0=bezierparameterize(((bx0,by0),(bx1,by1),(bx2,by2),(bx3,by3))) + #quadratic coefficents of slope formula + if dx: + slope = 1.0*(dy/dx) + a=3*ay-3*ax*slope + b=2*by-2*bx*slope + c=cy-cx*slope + elif dy: + slope = 1.0*(dx/dy) + a=3*ax-3*ay*slope + b=2*bx-2*by*slope + c=cx-cy*slope + else: + return [] + + roots = rootWrapper(0,a,b,c) + retval = [] + for i in roots: + if type(i) is complex and i.imag==0: + i = i.real + if type(i) is not complex and 0<=i<=1: + retval.append(i) + return retval + +def tpoint((x1,y1),(x2,y2),t): + return x1+t*(x2-x1),y1+t*(y2-y1) +def beziersplitatt(((bx0,by0),(bx1,by1),(bx2,by2),(bx3,by3)),t): + m1=tpoint((bx0,by0),(bx1,by1),t) + m2=tpoint((bx1,by1),(bx2,by2),t) + m3=tpoint((bx2,by2),(bx3,by3),t) + m4=tpoint(m1,m2,t) + m5=tpoint(m2,m3,t) + m=tpoint(m4,m5,t) + + return ((bx0,by0),m1,m4,m),(m,m5,m3,(bx3,by3)) + +''' +Approximating the arc length of a bezier curve +according to + +if: + L1 = |P0 P1| +|P1 P2| +|P2 P3| + L0 = |P0 P3| +then: + L = 1/2*L0 + 1/2*L1 + ERR = L1-L0 +ERR approaches 0 as the number of subdivisions (m) increases + 2^-4m + +Reference: +Jens Gravesen +"Adaptive subdivision and the length of Bezier curves" +mat-report no. 1992-10, Mathematical Institute, The Technical +University of Denmark. +''' +def pointdistance((x1,y1),(x2,y2)): + return math.sqrt(((x2 - x1) ** 2) + ((y2 - y1) ** 2)) +def Gravesen_addifclose(b, len, error = 0.001): + box = 0 + for i in range(1,4): + box += pointdistance(b[i-1], b[i]) + chord = pointdistance(b[0], b[3]) + if (box - chord) > error: + first, second = beziersplitatt(b, 0.5) + Gravesen_addifclose(first, len, error) + Gravesen_addifclose(second, len, error) + else: + len[0] += (box / 2.0) + (chord / 2.0) +def bezierlengthGravesen(b, error = 0.001): + len = [0] + Gravesen_addifclose(b, len, error) + return len[0] + +# balf = Bezier Arc Length Function +balfax,balfbx,balfcx,balfay,balfby,balfcy = 0,0,0,0,0,0 +def balf(t): + retval = (balfax*(t**2) + balfbx*t + balfcx)**2 + (balfay*(t**2) + balfby*t + balfcy)**2 + return math.sqrt(retval) + +def Simpson(f, a, b, n_limit, tolerance): + n = 2 + multiplier = (b - a)/6.0 + endsum = f(a) + f(b) + interval = (b - a)/2.0 + asum = 0.0 + bsum = f(a + interval) + est1 = multiplier * (endsum + (2.0 * asum) + (4.0 * bsum)) + est0 = 2.0 * est1 + #print multiplier, endsum, interval, asum, bsum, est1, est0 + while n < n_limit and abs(est1 - est0) > tolerance: + n *= 2 + multiplier /= 2.0 + interval /= 2.0 + asum += bsum + bsum = 0.0 + est0 = est1 + for i in xrange(1, n, 2): + bsum += f(a + (i * interval)) + est1 = multiplier * (endsum + (2.0 * asum) + (4.0 * bsum)) + #print multiplier, endsum, interval, asum, bsum, est1, est0 + return est1 + +def bezierlengthSimpson(((bx0,by0),(bx1,by1),(bx2,by2),(bx3,by3)), tolerance = 0.001): + global balfax,balfbx,balfcx,balfay,balfby,balfcy + ax,ay,bx,by,cx,cy,x0,y0=bezierparameterize(((bx0,by0),(bx1,by1),(bx2,by2),(bx3,by3))) + balfax,balfbx,balfcx,balfay,balfby,balfcy = 3*ax,2*bx,cx,3*ay,2*by,cy + return Simpson(balf, 0.0, 1.0, 4096, tolerance) + +def beziertatlength(((bx0,by0),(bx1,by1),(bx2,by2),(bx3,by3)), l = 0.5, tolerance = 0.001): + global balfax,balfbx,balfcx,balfay,balfby,balfcy + ax,ay,bx,by,cx,cy,x0,y0=bezierparameterize(((bx0,by0),(bx1,by1),(bx2,by2),(bx3,by3))) + balfax,balfbx,balfcx,balfay,balfby,balfcy = 3*ax,2*bx,cx,3*ay,2*by,cy + t = 1.0 + tdiv = t + curlen = Simpson(balf, 0.0, t, 4096, tolerance) + targetlen = l * curlen + diff = curlen - targetlen + while abs(diff) > tolerance: + tdiv /= 2.0 + if diff < 0: + t += tdiv + else: + t -= tdiv + curlen = Simpson(balf, 0.0, t, 4096, tolerance) + diff = curlen - targetlen + return t + +#default bezier length method +bezierlength = bezierlengthSimpson + +if __name__ == '__main__': + import timing + #print linebezierintersect(((,),(,)),((,),(,),(,),(,))) + #print linebezierintersect(((0,1),(0,-1)),((-1,0),(-.5,0),(.5,0),(1,0))) + tol = 0.00000001 + curves = [((0,0),(1,5),(4,5),(5,5)), + ((0,0),(0,0),(5,0),(10,0)), + ((0,0),(0,0),(5,1),(10,0)), + ((-10,0),(0,0),(10,0),(10,10)), + ((15,10),(0,0),(10,0),(-5,10))] + ''' + for curve in curves: + timing.start() + g = bezierlengthGravesen(curve,tol) + timing.finish() + gt = timing.micro() + + timing.start() + s = bezierlengthSimpson(curve,tol) + timing.finish() + st = timing.micro() + + print g, gt + print s, st + ''' + for curve in curves: + print beziertatlength(curve,0.5) diff --git a/share/extensions/bluredge.inx b/share/extensions/bluredge.inx new file mode 100644 index 000000000..567efbc79 --- /dev/null +++ b/share/extensions/bluredge.inx @@ -0,0 +1,13 @@ + + <_name>Blur Edge + org.inkscape.effect.bluredge + bluredge + 1.0 + 11 + + all + + + bluredge + + diff --git a/share/extensions/cubicsuperpath.py b/share/extensions/cubicsuperpath.py new file mode 100755 index 000000000..fdd1afc59 --- /dev/null +++ b/share/extensions/cubicsuperpath.py @@ -0,0 +1,83 @@ +#!/usr/bin/env python +""" +cubicsuperpath.py + +Copyright (C) 2005 Aaron Spike, aaron@ekips.org + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +""" +import simplepath + +def CubicSuperPath(simplepath): + csp = [] + subpath = -1 + subpathstart = [] + last = [] + lastctrl = [] + for s in simplepath: + cmd, params = s + if cmd == 'M': + if last: + csp[subpath].append([lastctrl[:],last[:],last[:]]) + subpath += 1 + csp.append([]) + subpathstart = params[:] + last = params[:] + lastctrl = params[:] + elif cmd == 'L': + csp[subpath].append([lastctrl[:],last[:],last[:]]) + last = params[:] + lastctrl = params[:] + elif cmd == 'C': + csp[subpath].append([lastctrl[:],last[:],params[:2]]) + last = params[-2:] + lastctrl = params[2:4] + elif cmd == 'Q': + #TODO: convert to cubic + csp[subpath].append([lastctrl[:],last[:],last[:]]) + last = params[-2:] + lastctrl = params[-2:] + elif cmd == 'A': + #TODO: convert to cubics + csp[subpath].append([lastctrl[:],last[:],last[:]]) + last = params[-2:] + lastctrl = params[-2:] + elif cmd == 'Z': + csp[subpath].append([lastctrl[:],last[:],last[:]]) + last = subpathstart[:] + lastctrl = subpathstart[:] + #append final superpoint + csp[subpath].append([lastctrl[:],last[:],last[:]]) + return csp + +def unCubicSuperPath(csp): + a = [] + for subpath in csp: + if subpath: + a.append(['M',subpath[0][1][:]]) + for i in range(1,len(subpath)): + a.append(['C',subpath[i-1][2][:] + subpath[i][0][:] + subpath[i][1][:]]) + return a + +def parsePath(d): + return CubicSuperPath(simplepath.parsePath(d)) + +def formatPath(p): + return simplepath.formatPath(unCubicSuperPath(p)) + + + + diff --git a/share/extensions/dia.inx b/share/extensions/dia.inx new file mode 100644 index 000000000..3e9fa244c --- /dev/null +++ b/share/extensions/dia.inx @@ -0,0 +1,15 @@ + + <_name>Dia Input + org.inkscape.input.dia + dia2svg.sh + dia + + .dia + application/x-dia + <_filetypename>Dia Diagram (*.dia) + <_filetypetooltip>A diagram created with the program Dia + + + diff --git a/share/extensions/dia2svg.sh b/share/extensions/dia2svg.sh new file mode 100755 index 000000000..48403d0b5 --- /dev/null +++ b/share/extensions/dia2svg.sh @@ -0,0 +1,13 @@ +#! /bin/sh + +rc=0 + +# dia version 0.93 (the only version I've tested) allows `--export=-', but then +# ruins it by writing other cruft to stdout. So we'll have to use a temp file. +TMPDIR="${TMPDIR-/tmp}" +TEMPFILENAME=`mktemp 2>/dev/null || echo "$TMPDIR/tmpdia$$.svg"` +dia -n --export="${TEMPFILENAME}" --export-to-format=svg "$1" > /dev/null 2>&1 || rc=1 + +cat < "${TEMPFILENAME}" || rc=1 +rm -f "${TEMPFILENAME}" +exit $rc diff --git a/share/extensions/dots.inx b/share/extensions/dots.inx new file mode 100644 index 000000000..50e37ff4c --- /dev/null +++ b/share/extensions/dots.inx @@ -0,0 +1,14 @@ + + <_name>Connect the Dots + org.ekips.filter.dots + dots.py + inkex.py + 20 + 10px + + path + + + diff --git a/share/extensions/dots.py b/share/extensions/dots.py new file mode 100755 index 000000000..2e24ef2b1 --- /dev/null +++ b/share/extensions/dots.py @@ -0,0 +1,75 @@ +#!/usr/bin/env python +''' +Copyright (C) 2005 Aaron Spike, aaron@ekips.org + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +''' +import inkex, simplestyle, simplepath + +class Dots(inkex.Effect): + def __init__(self): + inkex.Effect.__init__(self) + self.OptionParser.add_option("-d", "--dotsize", + action="store", type="string", + dest="dotsize", default="10px", + help="Size of the dots placed at path nodes") + self.OptionParser.add_option("-f", "--fontsize", + action="store", type="string", + dest="fontsize", default="20", + help="Size of node label numbers") + def effect(self): + for id, node in self.selected.iteritems(): + if node.tagName == 'path': + self.group = self.document.createElement('svg:g') + node.parentNode.appendChild(self.group) + new = self.document.createElement('svg:path') + + try: + t = node.attributes.getNamedItem('transform').value + self.group.setAttribute('transform', t) + except AttributeError: + pass + + s = simplestyle.parseStyle(node.attributes.getNamedItem('style').value) + s['stroke-linecap']='round' + s['stroke-width']=self.options.dotsize + new.setAttribute('style', simplestyle.formatStyle(s)) + + a =[] + p = simplepath.parsePath(node.attributes.getNamedItem('d').value) + num = 1 + for cmd,params in p: + if cmd != 'Z': + a.append(['M',params[-2:]]) + a.append(['L',params[-2:]]) + self.addText(self.group,params[-2],params[-1],num) + num += 1 + new.setAttribute('d', simplepath.formatPath(a)) + self.group.appendChild(new) + node.parentNode.removeChild(node) + + + def addText(self,node,x,y,text): + new = self.document.createElement('svg:text') + s = {'font-size': self.options.fontsize, 'fill-opacity': '1.0', 'stroke': 'none', + 'font-weight': 'normal', 'font-style': 'normal', 'fill': '#000000'} + new.setAttribute('style', simplestyle.formatStyle(s)) + new.setAttribute('x', str(x)) + new.setAttribute('y', str(y)) + new.appendChild(self.document.createTextNode(str(text))) + node.appendChild(new) + +e = Dots() +e.affect() diff --git a/share/extensions/dropshadow.inx b/share/extensions/dropshadow.inx new file mode 100644 index 000000000..42aa077dd --- /dev/null +++ b/share/extensions/dropshadow.inx @@ -0,0 +1,13 @@ + + <_name>Dropshadow + org.inkscape.filter.dropshadow + svg_dropshadow + 0.9 + black + + all + + + diff --git a/share/extensions/dxf_input.inx b/share/extensions/dxf_input.inx new file mode 100644 index 000000000..769c29fdd --- /dev/null +++ b/share/extensions/dxf_input.inx @@ -0,0 +1,16 @@ + + <_name>DXF Input + org.inkscape.input.dxf + dxf2svg + org.inkscape.input.svg + + .dxf + image/x-svgz + <_filetypename>AutoCAD DXF (*.dxf) + <_filetypetooltip>Import AutoCAD's Document Exchange Format + org.inkscape.output.svg + + + diff --git a/share/extensions/dxf_output.inx b/share/extensions/dxf_output.inx new file mode 100644 index 000000000..51dc08bbe --- /dev/null +++ b/share/extensions/dxf_output.inx @@ -0,0 +1,17 @@ + + <_name>DXF Output + org.inkscape.output.dxf + org.inkscape.output.ps + ps2dxf.sh + pstoedit + + .dxf + image/dxf + <_filetypename>AutoCAD DXF (*.dxf) + <_filetypetooltip>DXF file written by pstoedit + + + diff --git a/share/extensions/embed_raster_in_svg.pl b/share/extensions/embed_raster_in_svg.pl new file mode 100755 index 000000000..ee3bf295e --- /dev/null +++ b/share/extensions/embed_raster_in_svg.pl @@ -0,0 +1,122 @@ +#!/usr/bin/perl + +#---------------------------------------------------------------------------------------------- +# embed_raster_in_svg +# B. Crowell, crowellXX at lightandmatter.com (replace XX with last two digits of current year) +# (c) 2004 B. Crowell +# This program is available under version 2 of the GPL License, http://www.gnu.org/copyleft/gpl.html, +# or, at your option, under the same license as Perl. +# For information about this program, scroll down in the source code, or invoke the program +# without any command-line arguments. +#---------------------------------------------------------------------------------------------- + +use strict; + +use MIME::Base64; +use Cwd; +use File::Basename; + +my $info = <<'INFO'; + usage: + embed_raster_in_svg foo.svg + Looks through the svg file for raster images that are given as links, rather than + being embedded, and embeds them in the file. The links must be local URIs, and if + they're relative, they must be relative to the directory where the svg file is located. + Starting with Inkscape 0.41, Inkscape can + handle embedded raster images as well as ones that are linked to (?). + Typical input looks like this: + + The output should look like this: + ; +close FILE; + +chdir dirname(Cwd::realpath($svg)); # so from now on, we can open raster files if they're relative to this directory + + +# The file is now in memory. +# First we go once through it and (1) find out if there are indeed any links to raster images, +# (2) rearrange things a little so that the (lengthy) base64 data will be the last attribute of the +# image tag. + +my $n = 0; +my @raster_files = (); +$data =~ + s@\@@g; +while ($data=~m@@g) { + my $raster = $1; + die "error, raster filename $raster contains a double quote" if $raster=~m/\"/; + if (!($raster=~m/data\:\;/)) { + ++$n; + push @raster_files,$raster; + } +} + +if ($n==0) { + print "no embedded jpgs found in file $svg\n"; + exit; +} + + +# Eliminate sodipodi:absref attributes. If these are present, Inkscape looks for the linked +# file, and ignores the embedded data. Also, get rid of those nasty hobbitses. +$data=~s@(; + close RASTER; + my $type = ''; + $type='image/png' if $raster_data=~m/^\x{89}PNG/; + $type='image/jpg' if $raster_data=~m/^\x{ff}\x{d8}/; + die "file $raster does not appear to be of type PNG or JPG" unless $type; + my $raster_data_base64 = encode_base64($raster_data); + ($data =~ s@ITHURTSUS\"$raster\"MYPRECIOUSS@\n xlink:href=\"data\:$type\;base64,$raster_data_base64\"@) or die "error embedding data for $raster"; + print "embedded raster file $raster, $type\n"; +} +my $bak = "$svg.bak"; +rename $svg,$bak or die "error renaming file $svg to $bak, $!"; +open(FILE,">$svg") or die "error creating new version of file $svg for output, $!"; +print FILE $data; +close FILE; + + + + + diff --git a/share/extensions/embedimage.inx b/share/extensions/embedimage.inx new file mode 100644 index 000000000..221a3f0f6 --- /dev/null +++ b/share/extensions/embedimage.inx @@ -0,0 +1,12 @@ + + <_name>Embed Images + org.ekips.filter.embedimage + embedimage.py + inkex.py + + all + + + diff --git a/share/extensions/embedimage.py b/share/extensions/embedimage.py new file mode 100644 index 000000000..12a0b78b2 --- /dev/null +++ b/share/extensions/embedimage.py @@ -0,0 +1,60 @@ +#!/usr/bin/env python +''' +Copyright (C) 2005 Aaron Spike, aaron@ekips.org + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +''' + +import inkex, os, base64 + +class MyEffect(inkex.Effect): + def __init__(self): + inkex.Effect.__init__(self) + + def effect(self): + ctx = inkex.xml.xpath.Context.Context(self.document,processorNss=inkex.NSS) + + # if there is a selection only embed selected images + # otherwise embed all images + if (self.options.ids): + for id, node in self.selected.iteritems(): + if node.tagName == 'image': + self.embedImage(node) + else: + path = '//image' + for node in inkex.xml.xpath.Evaluate(path,self.document, context=ctx): + self.embedImage(node) + def embedImage(self, node): + xlink = node.attributes.getNamedItemNS(inkex.NSS[u'xlink'],'href') + if (xlink.value[:4]!='data'): + absref=node.attributes.getNamedItemNS(inkex.NSS[u'sodipodi'],'absref') + if (os.path.isfile(absref.value)): + file = open(absref.value,"rb").read() + embed=True + if (file[:4]=='\x89PNG'): + type='image/png' + elif (file[:2]=='\xff\xd8'): + type='image/jpg' + else: + embed=False + if (embed): + xlink.value = 'data:%s;base64,%s' % (type, base64.encodestring(file)) + node.removeAttributeNS(inkex.NSS[u'sodipodi'],'absref') + else: + inkex.debug("%s is not of type image/png or image/jpg" % absref.value) + else: + inkex.debug("Sorry we could not locate %s" % absref.value) +e = MyEffect() +e.affect() diff --git a/share/extensions/eps_input.inx b/share/extensions/eps_input.inx new file mode 100644 index 000000000..d732dea8c --- /dev/null +++ b/share/extensions/eps_input.inx @@ -0,0 +1,17 @@ + + <_name>EPS Input + org.inkscape.input.eps + org.inkscape.input.ps + gs + + .eps + image/x-encapsulated-postscript + <_filetypename>Encapsulated Postscript (*.eps) + <_filetypetooltip>Encapsulated Postscript + org.inkscape.output.eps + + + diff --git a/share/extensions/epsi_output.inx b/share/extensions/epsi_output.inx new file mode 100644 index 000000000..06197dc0a --- /dev/null +++ b/share/extensions/epsi_output.inx @@ -0,0 +1,17 @@ + + <_name>EPSI Output + org.inkscape.output.epsi + org.inkscape.output.ps + ps2epsi.sh + ps2epsi + + .epsi + image/x-encapsulated-postscript + <_filetypename>Encapsulated Postscript Interchange (*.epsi) + <_filetypetooltip>Encapsulated Postscript with a thumbnail + + + diff --git a/share/extensions/extractimage.inx b/share/extensions/extractimage.inx new file mode 100644 index 000000000..a167ed15d --- /dev/null +++ b/share/extensions/extractimage.inx @@ -0,0 +1,13 @@ + + <_name>Extract One Image + org.ekips.filter.extractimage + extractimage.py + inkex.py + none + + all + + + diff --git a/share/extensions/extractimage.py b/share/extensions/extractimage.py new file mode 100644 index 000000000..27936bf80 --- /dev/null +++ b/share/extensions/extractimage.py @@ -0,0 +1,50 @@ +#!/usr/bin/env python +''' +Copyright (C) 2005 Aaron Spike, aaron@ekips.org + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +''' + +import inkex, base64 + +class MyEffect(inkex.Effect): + def __init__(self): + inkex.Effect.__init__(self) + self.OptionParser.add_option("--filepath", + action="store", type="string", + dest="filepath", default=None, + help="") + def effect(self): + ctx = inkex.xml.xpath.Context.Context(self.document,processorNss=inkex.NSS) + + # exbed the first embedded image + path = self.options.filepath + if (path != ''): + if (self.options.ids): + for id, node in self.selected.iteritems(): + if node.tagName == 'image': + xlink = node.attributes.getNamedItemNS(inkex.NSS[u'xlink'],'href') + if (xlink.value[:4]=='data'): + comma = xlink.value.find(',') + if comma>0: + data = base64.decodestring(xlink.value[comma:]) + open(path,'wb').write(data) + xlink.value = path + else: + inkex.debug('Difficulty finding the image data.') + break + +e = MyEffect() +e.affect() diff --git a/share/extensions/ffgeom.py b/share/extensions/ffgeom.py new file mode 100755 index 000000000..1e363c762 --- /dev/null +++ b/share/extensions/ffgeom.py @@ -0,0 +1,127 @@ +#!/usr/bin/env python +""" + ffgeom.py + Copyright (C) 2005 Aaron Cyril Spike, aaron@ekips.org + + This file is part of FretFind 2-D. + + FretFind 2-D is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + FretFind 2-D is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with FretFind 2-D; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +""" +import math +try: + NaN = float('NaN') +except ValueError: + PosInf = 1e300000 + NaN = PosInf/PosInf + +class Point: + precision = 5 + def __init__(self, x, y): + self.__coordinates = {'x' : float(x), 'y' : float(y)} + def __getitem__(self, key): + return self.__coordinates[key] + def __setitem__(self, key, value): + self.__coordinates[key] = float(value) + def __repr__(self): + return '(%s, %s)' % (round(self['x'],self.precision),round(self['y'],self.precision)) + def copy(self): + return Point(self['x'],self['y']) + def translate(self, x, y): + self['x'] += x + self['y'] += y + def move(self, x, y): + self['x'] = float(x) + self['y'] = float(y) + +class Segment: + def __init__(self, e0, e1): + self.__endpoints = [e0, e1] + def __getitem__(self, key): + return self.__endpoints[key] + def __setitem__(self, key, value): + self.__endpoints[key] = value + def __repr__(self): + return repr(self.__endpoints) + def copy(self): + return Segment(self[0],self[1]) + def translate(self, x, y): + self[0].translate(x,y) + self[1].translate(x,y) + def move(self,e0,e1): + self[0] = e0 + self[1] = e1 + def delta_x(self): + return self[1]['x'] - self[0]['x'] + def delta_y(self): + return self[1]['y'] - self[0]['y'] + #alias functions + run = delta_x + rise = delta_y + def slope(self): + if self.delta_x() != 0: + return self.delta_x() / self.delta_y() + return NaN + def intercept(self): + if self.delta_x() != 0: + return self[1]['y'] - (self[0]['x'] * self.slope()) + return NaN + def distanceToPoint(self, p): + len = self.length() + if len == 0: return NaN + return math.fabs(((self[1]['x'] - self[0]['x']) * (self[0]['y'] - p['y'])) - \ + ((self[0]['x'] - p['x']) * (self[1]['y'] - self[0]['y']))) / len + def angle(self): + return math.pi * (math.atan2(self.delta_y(), self.delta_x())) / 180 + def length(self): + return math.sqrt((self.delta_x() ** 2) + (self.delta_y() ** 2)) + def pointAtLength(self, len): + if self.length() == 0: return Point(NaN, NaN) + ratio = len / self.length() + x = self[0]['x'] + (ratio * self.delta_x()) + y = self[0]['y'] + (ratio * self.delta_y()) + return Point(x, y) + def pointAtRatio(self, ratio): + if self.length() == 0: return Point(NaN, NaN) + x = self[0]['x'] + (ratio * self.delta_x()) + y = self[0]['y'] + (ratio * self.delta_y()) + return Point(x, y) + def createParallel(self, p): + return Segment(Point(p['x'] + self.delta_x(), p['y'] + self.delta_y()), p) + def intersect(self, s): + return intersectSegments(self, s) + +def intersectSegments(s1, s2): + x1 = s1[0]['x'] + x2 = s1[1]['x'] + x3 = s2[0]['x'] + x4 = s2[1]['x'] + + y1 = s1[0]['y'] + y2 = s1[1]['y'] + y3 = s2[0]['y'] + y4 = s2[1]['y'] + + denom = ((y4 - y3) * (x2 - x1)) - ((x4 - x3) * (y2 - y1)) + num1 = ((x4 - x3) * (y1 - y3)) - ((y4 - y3) * (x1 - x3)) + num2 = ((x2 - x1) * (y1 - y3)) - ((y2 - y1) * (x1 - x3)) + + num = num1 + + if denom != 0: + x = x1 + ((num / denom) * (x2 - x1)) + y = y1 + ((num / denom) * (y2 - y1)) + return Point(x, y) + return Point(NaN, NaN) + diff --git a/share/extensions/ffmet.inx b/share/extensions/ffmet.inx new file mode 100644 index 000000000..9cebe2d6a --- /dev/null +++ b/share/extensions/ffmet.inx @@ -0,0 +1,23 @@ + + <_name>FretFind Multi Length ET + org.ekips.filter.fretfind.multi.et + fretfind.py + inkex.py + 25 + 26 + 0.5 + 2 + 2.5 + 2 + 12 + 24 + 6 + 0.0975 + 90 + + all + + + diff --git a/share/extensions/ffms.inx b/share/extensions/ffms.inx new file mode 100644 index 000000000..31ac61ecd --- /dev/null +++ b/share/extensions/ffms.inx @@ -0,0 +1,23 @@ + + <_name>FretFind Multi Length Scala + org.ekips.filter.fretfind.multi.scala + fretfind.py + inkex.py + 25 + 26 + 0.5 + 2 + 2.5 + none + 0;0;0;0;0;0 + 24 + 6 + 0.0975 + 90 + + all + + + diff --git a/share/extensions/ffproc.py b/share/extensions/ffproc.py new file mode 100755 index 000000000..7eb6f2dd1 --- /dev/null +++ b/share/extensions/ffproc.py @@ -0,0 +1,194 @@ +#!/usr/bin/env python +''' + Copyright (C) 2004 Aaron Cyril Spike + + This file is part of FretFind 2-D. + + FretFind 2-D is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + FretFind 2-D is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with FretFind 2-D; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +''' +import sys +from ffgeom import * +threshold=0.0000000001 + +def FindFrets(strings, meta, scale, tuning, numfrets): + scale = scale['steps'] + + #if the string ends don't fall on the nut and bridge + #don't look for partial frets. + numStrings = len(strings) + doPartials = True + parallelFrets = True + + nut = Segment(strings[0][0],strings[-1][0]) + bridge = Segment(strings[0][1],strings[-1][1]) + midline = Segment( + Point((nut[1]['x']+nut[0]['x'])/2.0,(nut[1]['y']+nut[0]['y'])/2.0), + Point((bridge[1]['x']+bridge[0]['x'])/2.0,(bridge[1]['y']+bridge[0]['y'])/2.0)) + for s in strings: + if nut.distanceToPoint(s[0])>=threshold or bridge.distanceToPoint(s[1])>=threshold: + doPartials = False + break + + denom = ((bridge[1]['y']-bridge[0]['y'])*(nut[1]['x']-nut[0]['x']))-((bridge[1]['x']-bridge[0]['x'])*(nut[1]['y']-nut[0]['y'])) + if denom != 0: + parallelFrets = False + + fretboard = [] + tones = len(scale)-1 + for i in range(len(strings)): + base = tuning[i] + frets = [] + if doPartials: + frets.append(Segment(meta[i][0],meta[i+1][0])) + else: + frets.append(Segment(strings[i][0],strings[i][0])) + last = strings[i][0] + + for j in range(numfrets): + step=((base+j-1)%(tones))+1 + ratio=1.0-((scale[step][1]*scale[step-1][0])/(scale[step][0]*scale[step-1][1])) + x = last['x']+(ratio*(strings[i][1]['x']-last['x'])) + y = last['y']+(ratio*(strings[i][1]['y']-last['y'])) + current = Point(x,y) + temp = Segment(strings[i][0],current) + totalRatio = temp.length()/strings[i].length() + + if doPartials: + #partials depending on outer strings (questionable) + if parallelFrets: + temp = nut.createParallel(current) + else: + temp = Segment(strings[0].pointAtLength(strings[0].length()*totalRatio), + strings[-1].pointAtLength(strings[-1].length()*totalRatio)) + frets.append(Segment(intersectSegments(temp,meta[i]),intersectSegments(temp,meta[i+1]))) + else: + frets.append(Segment(current,current)) + last = current + fretboard.append(frets) + return fretboard + +def FindStringsSingleScale(numStrings,scaleLength,nutWidth,bridgeWidth,oNF,oBF,oNL,oBL): + strings = [] + meta = [] + nutHalf = nutWidth/2 + bridgeHalf = bridgeWidth/2 + nutCandidateCenter = (nutHalf) + oNL + bridgeCandidateCenter = (bridgeHalf) + oBL + if bridgeCandidateCenter >= nutCandidateCenter: + center = bridgeCandidateCenter + else: + center = nutCandidateCenter + nutStringSpacing = nutWidth/(numStrings-1) + bridgeStringSpacing = bridgeWidth/(numStrings-1) + + for i in range(numStrings): + strings.append(Segment(Point(center+nutHalf-(i*nutStringSpacing),0), + Point(center+bridgeHalf-(i*bridgeStringSpacing),scaleLength))) + + meta.append(Segment(Point(center+nutHalf+oNF,0),Point(center+bridgeHalf+oBF,scaleLength))) + for i in range(1,numStrings): + meta.append(Segment( + Point((strings[i-1][0]['x']+strings[i][0]['x'])/2.0, + (strings[i-1][0]['y']+strings[i][0]['y'])/2.0), + Point((strings[i-1][1]['x']+strings[i][1]['x'])/2.0, + (strings[i-1][1]['y']+strings[i][1]['y'])/2.0))) + meta.append(Segment(Point(center-(nutHalf+oNL),0),Point(center-(bridgeHalf+oBL),scaleLength))) + + return strings, meta + +def FindStringsMultiScale(numStrings,scaleLengthF,scaleLengthL,nutWidth,bridgeWidth,perp,oNF,oBF,oNL,oBL): + strings = [] + meta = [] + nutHalf = nutWidth/2 + bridgeHalf = bridgeWidth/2 + nutCandidateCenter = (nutHalf)+oNL + bridgeCandidateCenter = (bridgeHalf)+oBL + if bridgeCandidateCenter >= nutCandidateCenter: + xcenter = bridgeCandidateCenter + else: + nutCandidateCenter + + fbnxf = xcenter+nutHalf+oNF + fbbxf = xcenter+bridgeHalf+oBF + fbnxl = xcenter-(nutHalf+oNL) + fbbxl = xcenter-(bridgeHalf+oBL) + + snxf = xcenter+nutHalf + sbxf = xcenter+bridgeHalf + snxl = xcenter-nutHalf + sbxl = xcenter-bridgeHalf + + fdeltax = sbxf-snxf + ldeltax = sbxl-snxl + fdeltay = math.sqrt((scaleLengthF*scaleLengthF)-(fdeltax*fdeltax)) + ldeltay = math.sqrt((scaleLengthL*scaleLengthL)-(ldeltax*ldeltax)) + + fperp = perp*fdeltay + lperp = perp*ldeltay + + #temporarily place first and last strings + first = Segment(Point(snxf,0),Point(sbxf,fdeltay)) + last = Segment(Point(snxl,0),Point(sbxl,ldeltay)) + + if fdeltay<=ldeltay: + first.translate(0,(lperp-fperp)) + else: + last.translate(0,(fperp-lperp)) + + nut = Segment(first[0].copy(),last[0].copy()) + bridge = Segment(first[1].copy(),last[1].copy()) + #overhang measurements are now converted from delta x to along line lengths + oNF = (oNF*nut.length())/nutWidth + oNL = (oNL*nut.length())/nutWidth + oBF = (oBF*bridge.length())/bridgeWidth + oBL = (oBL*bridge.length())/bridgeWidth + #place fretboard edges + fbf = Segment(nut.pointAtLength(-oNF),bridge.pointAtLength(-oBF)) + fbl = Segment(nut.pointAtLength(nut.length()+oNL),bridge.pointAtLength(bridge.length()+oBL)) + #normalize values into the first quadrant via translate + if fbf[0]['y']<0 or fbl[0]['y']<0: + if fbf[0]['y']<=fbl[0]['y']: + move = -fbf[0]['y'] + else: + move = -fbl[0]['y'] + + first.translate(0,move) + last.translate(0,move) + nut.translate(0,move) + bridge.translate(0,move) + fbf.translate(0,move) + fbl.translate(0,move) + + #output values + nutStringSpacing = nut.length()/(numStrings-1) + bridgeStringSpacing = bridge.length()/(numStrings-1) + strings.append(first) + for i in range(1,numStrings-1): + n = nut.pointAtLength(i*nutStringSpacing) + b = bridge.pointAtLength(i*bridgeStringSpacing) + strings.append(Segment(Point(n['x'],n['y']),Point(b['x'],b['y']))) + strings.append(last) + + meta.append(fbf) + for i in range(1,numStrings): + meta.append(Segment( + Point((strings[i-1][0]['x']+strings[i][0]['x'])/2.0, + (strings[i-1][0]['y']+strings[i][0]['y'])/2.0), + Point((strings[i-1][1]['x']+strings[i][1]['x'])/2.0, + (strings[i-1][1]['y']+strings[i][1]['y'])/2.0))) + + meta.append(fbl) + + return strings, meta diff --git a/share/extensions/ffscale.py b/share/extensions/ffscale.py new file mode 100755 index 000000000..f9afa0b02 --- /dev/null +++ b/share/extensions/ffscale.py @@ -0,0 +1,73 @@ +#!/usr/bin/env python +''' + Copyright (C) 2004 Aaron Cyril Spike + + This file is part of FretFind 2-D. + + FretFind 2-D is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + FretFind 2-D is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with FretFind 2-D; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +''' +import math + +def ETScale(tones, octave=2.0): + octave, tones = float(octave), float(tones) + scale = {'steps':[[1.0,1.0]], 'title':'', 'errors':0, 'errorstring':''} + if not tones: + scale['errors'] += 1 + scale['errorstring'] = 'Error: Number of tones must be non zero!' + else: + ratio = octave**(1/tones) + scale['title'] = '%s root of %s Equal Temperament' % (tones, octave) + scale['steps'].append([ratio,1]) + return scale + +def ScalaScale(scala): + #initial step 0 or 1/1 is implicit + scale = {'steps':[[1.0,1.0]], 'title':'', 'errors':0, 'errorstring':''} + + #split scale discarding commments + lines = [l.strip() for l in scala.strip().splitlines() if not l.strip().startswith('!')] + + #first line may be blank and contains the title + scale['title'] = lines.pop(0) + + #second line indicates the number of note lines that should follow + expected = int(lines.pop(0)) + + #discard blank lines and anything following whitespace + lines = [l.split()[0] for l in lines if l != ''] + + if len(lines) != expected: + scale['errors'] += 1 + scale['errorstring'] = 'Error: expected %s more tones but found %s!' % (expected,len(lines)) + else: + for l in lines: + #interpret anyline containing a dot as cents + if l.find('.') >= 0: + num = 2**(float(l)/1200) + denom = 1 + #everything else is a ratio + elif l.find('/') >=0: + l = l.split('/') + num = float(int(l[0])) + denom = float(int(l[1])) + else: + num = float(int(l)) + denom = 1.0 + scale['steps'].append([num,denom]) + + if (num < 0) ^ (denom <= 0): + scale['errors'] += 1 + scale['errorstring'] += 'Error at "'+l+'": Negative and undefined ratios are not allowed!\n' + return scale diff --git a/share/extensions/ffset.inx b/share/extensions/ffset.inx new file mode 100644 index 000000000..bba7ce558 --- /dev/null +++ b/share/extensions/ffset.inx @@ -0,0 +1,21 @@ + + <_name>FretFind Single Length ET + org.ekips.filter.fretfind.single.et + fretfind.py + inkex.py + 25 + 2 + 2.5 + 2 + 12 + 24 + 6 + 0.0975 + 90 + + all + + + diff --git a/share/extensions/ffss.inx b/share/extensions/ffss.inx new file mode 100644 index 000000000..102b50285 --- /dev/null +++ b/share/extensions/ffss.inx @@ -0,0 +1,21 @@ + + <_name>FretFind Single Length Scala + org.ekips.filter.fretfind.single.scala + fretfind.py + inkex.py + 25 + 2 + 2.5 + none + 0;0;0;0;0;0 + 24 + 6 + 0.0975 + 90 + + all + + + diff --git a/share/extensions/fretfind.py b/share/extensions/fretfind.py new file mode 100755 index 000000000..310a09a5d --- /dev/null +++ b/share/extensions/fretfind.py @@ -0,0 +1,186 @@ +#!/usr/bin/env python +''' +Copyright (C) 2005 Aaron Spike, aaron@ekips.org + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +''' +import sys +import inkex, simplestyle, simplepath +import ffscale, ffproc + +def seg2path(seg): + return "M%s,%sL%s,%s" % (seg[0]['x'],seg[0]['y'],seg[1]['x'],seg[1]['y']) + +class FretFind(inkex.Effect): + def __init__(self): + inkex.Effect.__init__(self) + self.doScala = False + self.doMultiScale = False + self.OptionParser.add_option("--scalafile", + action="store", type="string", + dest="scalafile", default=None, + help="") + self.OptionParser.add_option("--scalascale", + action="store", type="string", + dest="scalascale", default=None, + help="") + self.OptionParser.add_option("--etbase", + action="store", type="float", + dest="etbase", default=2.0, + help="") + self.OptionParser.add_option("--etroot", + action="store", type="float", + dest="etroot", default=12.0, + help="") + self.OptionParser.add_option("--tuning", + action="store", type="string", + dest="tuning", default="0;0;0;0;0;0", + help="") + self.OptionParser.add_option("--perpdist", + action="store", type="float", + dest="perpdist", default=0.5, + help="") + self.OptionParser.add_option("--offset", + action="store", type="float", + dest="offset", default=0.0, + help="") + self.OptionParser.add_option("--scalelength", + action="store", type="float", + dest="scalelength", default=25.0, + help="") + self.OptionParser.add_option("--firstscalelength", + action="store", type="float", + dest="firstscalelength", default=None, + help="") + self.OptionParser.add_option("--lastscalelength", + action="store", type="float", + dest="lastscalelength", default=None, + help="") + self.OptionParser.add_option("--nutwidth", + action="store", type="float", + dest="nutwidth", default=1.5, + help="") + self.OptionParser.add_option("--bridgewidth", + action="store", type="float", + dest="bridgewidth", default=2.5, + help="") + self.OptionParser.add_option("--frets", + action="store", type="int", + dest="frets", default=24, + help="") + self.OptionParser.add_option("--strings", + action="store", type="int", + dest="strings", default=6, + help="") + self.OptionParser.add_option("--fbedges", + action="store", type="float", + dest="fbedges", default=0.0975, + help="") + self.OptionParser.add_option("--pxperunit", + action="store", type="float", + dest="pxperunit", default=90, + help="") + def checkopts(self): + #scale type + if self.options.scalascale is not None: + self.doScala = True + if self.options.scalafile is not None: + if self.doScala: + sys.stderr.write('Mutually exclusive options: if found scalafile will override scalascale.') + else: + self.options.scalascale = "" + self.doScala = True + try: + f = open(self.options.scalafile,'r') + self.options.scalascale = f.read() + except: + sys.exit('Scala scale description file expected.') + #scale + if self.doScala: + self.scale = ffscale.ScalaScale(self.options.scalascale) + else: + self.scale = ffscale.ETScale(self.options.etroot,self.options.etbase) + + #string length + first = self.options.firstscalelength is not None + last = self.options.lastscalelength is not None + if first and last: + self.doMultiScale = True + elif first: + sys.stderr.write('Missing lastscalelength: overriding scalelength with firstscalelength.') + self.options.scalelength = self.options.firstscalelength + elif last: + sys.stderr.write('Missing firstscalelength: overriding scalelength with lastscalelength.') + self.options.scalelength = self.options.lastscalelength + + #tuning + self.tuning = [int(t.strip()) for t in self.options.tuning.split(";")] + self.tuning.extend([0 for i in range(self.options.strings - len(self.tuning))]) + + def effect(self): + self.checkopts() + + o = self.options.fbedges + oNF,oBF,oNL,oBL = o,o,o,o + + if self.doMultiScale: + strings, meta = ffproc.FindStringsMultiScale(self.options.strings,self.options.firstscalelength, + self.options.lastscalelength,self.options.nutwidth,self.options.bridgewidth, + self.options.perpdist,oNF,oBF,oNL,oBL) + else: + strings, meta = ffproc.FindStringsSingleScale(self.options.strings,self.options.scalelength, + self.options.nutwidth,self.options.bridgewidth, + oNF,oBF,oNL,oBL) + + frets = ffproc.FindFrets(strings, meta, self.scale, self.tuning, self.options.frets) + + edgepath = seg2path(meta[0]) + seg2path(meta[-1]) + stringpath = "".join([seg2path(s) for s in strings]) + fretpath = "".join(["".join([seg2path(f) for f in s]) for s in frets]) + + group = self.document.createElement('svg:g') + group.setAttribute('transform',"scale(%s,%s)" % (self.options.pxperunit,self.options.pxperunit)) + self.document.documentElement.appendChild(group) + + edge = self.document.createElement('svg:path') + s = {'stroke-linejoin': 'miter', 'stroke-width': '0.01px', + 'stroke-opacity': '1.0', 'fill-opacity': '1.0', + 'stroke': '#0000FF', 'stroke-linecap': 'butt', + 'fill': 'none'} + edge.setAttribute('style', simplestyle.formatStyle(s)) + edge.setAttribute('d', edgepath) + + string = self.document.createElement('svg:path') + s = {'stroke-linejoin': 'miter', 'stroke-width': '0.01px', + 'stroke-opacity': '1.0', 'fill-opacity': '1.0', + 'stroke': '#FF0000', 'stroke-linecap': 'butt', + 'fill': 'none'} + string.setAttribute('style', simplestyle.formatStyle(s)) + string.setAttribute('d', stringpath) + + fret = self.document.createElement('svg:path') + s = {'stroke-linejoin': 'miter', 'stroke-width': '0.01px', + 'stroke-opacity': '1.0', 'fill-opacity': '1.0', + 'stroke': '#000000', 'stroke-linecap': 'butt', + 'fill': 'none'} + fret.setAttribute('style', simplestyle.formatStyle(s)) + fret.setAttribute('d', fretpath) + + group.appendChild(edge) + group.appendChild(string) + group.appendChild(fret) + +e = FretFind() +e.affect() diff --git a/share/extensions/gimpgrad.inx b/share/extensions/gimpgrad.inx new file mode 100644 index 000000000..7441694dc --- /dev/null +++ b/share/extensions/gimpgrad.inx @@ -0,0 +1,14 @@ + + <_name>GIMP Gradients + org.inkscape.input.gimpgrad + gimpgrad + + .ggr + application/x-gimp-gradient + <_filetypename>GIMP Gradient (*.ggr) + <_filetypetooltip>Gradients used in GIMP + + + gimpgrad + + diff --git a/share/extensions/grid.inx b/share/extensions/grid.inx new file mode 100644 index 000000000..aaaef71af --- /dev/null +++ b/share/extensions/grid.inx @@ -0,0 +1,16 @@ + + <_name>Grid + org.inkscape.effect.grid + grid + 1.0 + 10.0 + 10.0 + 5.0 + 5.0 + + all + + + grid + + diff --git a/share/extensions/handles.inx b/share/extensions/handles.inx new file mode 100644 index 000000000..d0c42aafc --- /dev/null +++ b/share/extensions/handles.inx @@ -0,0 +1,12 @@ + + <_name>Draw Handles + org.ekips.filter.handles + handles.py + inkex.py + + path + + + diff --git a/share/extensions/handles.py b/share/extensions/handles.py new file mode 100755 index 000000000..a77b84ccc --- /dev/null +++ b/share/extensions/handles.py @@ -0,0 +1,56 @@ +#!/usr/bin/env python +''' +Copyright (C) 2005 Aaron Spike, aaron@ekips.org + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +''' +import inkex, simplepath, simplestyle + +class Handles(inkex.Effect): + def effect(self): + for id, node in self.selected.iteritems(): + if node.tagName == 'path': + p = simplepath.parsePath(node.attributes.getNamedItem('d').value) + a =[] + pen = None + subPathStart = None + for cmd,params in p: + if cmd == 'C': + a.extend([['M', params[:2]], ['L', pen], + ['M', params[2:4]], ['L', params[-2:]]]) + if cmd == 'Q': + a.extend([['M', params[:2]], ['L', pen], + ['M', params[:2]], ['L', params[-2:]]]) + + if cmd == 'M': + subPathStart = params + + if cmd == 'Z': + pen = subPathStart + else: + pen = params[-2:] + + if len(a) > 0: + new = self.document.createElement('svg:path') + s = {'stroke-linejoin': 'miter', 'stroke-width': '1.0px', + 'stroke-opacity': '1.0', 'fill-opacity': '1.0', + 'stroke': '#000000', 'stroke-linecap': 'butt', + 'fill': 'none'} + new.setAttribute('style', simplestyle.formatStyle(s)) + new.setAttribute('d', simplepath.formatPath(a)) + node.parentNode.appendChild(new) + +e = Handles() +e.affect() diff --git a/share/extensions/ill2svg.pl b/share/extensions/ill2svg.pl new file mode 100644 index 000000000..876888690 --- /dev/null +++ b/share/extensions/ill2svg.pl @@ -0,0 +1,374 @@ +#!/usr/bin/perl +# convert an illustrator file (on stdin) to svg (on stdout) +use strict; +use warnings; +use Getopt::Std; + +my $skip_images; + +BEGIN { + $skip_images = 0; + eval "use Image::Magick;"; + if ($@) { + warn "Couldn't load Perl module Image::Magick. Images will be skipped.\n"; + warn "$@\n"; + $skip_images = 1; + } +} + + +my %args; + +# Newline characters +my $NL_DOS = "\015\012"; +my $NL_MAC = "\015"; +my $NL_UNX = "\012"; + +getopts('h:', \%args); + +my @ImageData; +my $pagesize=1052.36218; +my $imagewidth = 128; +my $imageheight = 88; +my $imagex = 0; +my $imagey = 0; +my $imagenum = 0; +my $strokeparams; +my $strokecolor; +my $strokewidth; +my $fillcolor; +my $firstChar = 0; +my $image; +my $path; +my $color = 0; +my $weareinimage=0; +my $weareintext=0; +my($red,$green,$blue); +my($cpx,$cpy); + +if ($args{h}) { usage() && exit } + +$color = "#000"; + +sub addImageLine { + my ($data) = @_; + chomp($data); + #push (@ImageData, $data); + + my $len = length( $data ); + my $count = 0; + + #printf("%s %d\r\n",$data,$len); + #for( $loop=1; $loop < ($len - 2); $loop += 2){ + for( my $loop=1; $loop < $len; $loop += 2){ + my $value = substr( $data, $loop, 2); + + #printf("[%d:%s]",$loop,$value); + + if( $color == 0 ){ + #$red = hex($value); + $red = $value; + $color ++; + #printf("Color: RED: %s,",$red); + } elsif ( $color == 1 ) { + #$green = hex($value); + $green = $value; + $color ++; + #printf("Color: GREEN %s,",$green); + + } else { + $blue = $value; + my $pixel="pixel[${imagex},${imagey}]"; + my $rgb=sprintf("#%s%s%s",$red,$green,$blue); + #$image->Set($pixel=>$rgb); + $image->Set("pixel[${imagex},${imagey}]"=>"#${red}${green}${blue}") + unless ($skip_images); + #printf("PIXX: %d ",$image->Get($pixel)); + $color = 0; + $imagex++; + + #printf("Color:BLUE: %s, X: %d Y: %d %dx%d %s [%s]\r\n",$blue,$imagex,$imagey,$imagewidth,$imageheight,$rgb,$pixel); + + if( $imagex == $imagewidth ){ + $imagex = 0; + $imagey ++; + } # if + + + } #else + + } + + #printf("len: %d %dx%d\r\n",$len,$imagewidth,$imageheight); + +} + +sub cmyk_to_css { + my ($c, $m, $y, $k) = @_; + my ($r, $g, $b); + + $r = 1 - ($k + $c); + if ($r < 0) { $r = 0; } + $g = 1 - ($k + $m); + if ($g < 0) { $g = 0; } + $b = 1 - ($k + $y); + if ($b < 0) { $b = 0; } + return sprintf ("#%02x%02x%02x", 255 * $r, 255 * $g, 255 * $b); +} + +sub nice_float { + my ($x) = @_; + + my $result = sprintf ("%.3f", $x); + $result =~ s/0*$//; + $result =~ s/\.$//; + return $result; +} + +sub xform_xy { + my ($x, $y) = @_; + my @result = (); + + for my $i (0..$#_) { + if ($i & 1) { + #push @result, 1000 - $_[$i]; + push @result, $pagesize - $_[$i]; + } else { + #push @result, $_[$i] - 100; + push @result, $_[$i]; + } + } + return join ' ', map { nice_float ($_) } @result; +} + +sub strokeparams { + $strokecolor ||= 'black'; + my $result = "stroke:$strokecolor"; + if ($strokewidth && $strokewidth != 1) { + $result .= "; stroke-width:$strokewidth"; + } + return $result; +} + +sub usage { + warn qq|Usage: ill2svg [-l "string" -h] infile > outfile +options: + -h print this message and exit +|; +} + +sub process_line { + chomp; + return if /^%_/; + + if (/^([\d\.]+) ([\d\.]+) ([\d\.]+) ([\d\.]+) k$/) { + $fillcolor = cmyk_to_css ($1, $2, $3, $4); + } elsif (/^([\d\.]+) ([\d\.]+) ([\d\.]+) ([\d\.]+) K$/) { + $strokecolor = cmyk_to_css ($1, $2, $3, $4); + } elsif (/^([\d\.]+) g$/) { + $fillcolor = cmyk_to_css (0, 0, 0, 1 - $1); + } elsif (/^([\d\.]+) G$/) { + $strokecolor = cmyk_to_css (0, 0, 0, 1 - $1); + } elsif (/^([\d\.]+) ([\d\.]+) m$/) { + $path .= 'M'.xform_xy($1, $2); + $cpx = $1; + $cpy = $2; + } elsif (/^([\d\.]+) ([\d\.]+) l$/i) { + $path .= 'L'.xform_xy($1, $2); + $cpx = $1; + $cpy = $2; + } elsif (/^([\d\.]+) ([\d\.]+) ([\d\.]+) ([\d\.]+) v$/i) { + $path .= 'C'.xform_xy($cpx, $cpy, $1, $2, $3, $4); + $cpx = $3; + $cpy = $4; + } elsif (/^([\d\.]+) ([\d\.]+) ([\d\.]+) ([\d\.]+) y$/i) { + $path .= 'C'.xform_xy($1, $2, $3, $4, $3, $4); + $cpx = $3; + $cpy = $4; + } elsif (/^([\d\.]+) ([\d\.]+) ([\d\.]+) ([\d\.]+) ([\d\.]+) ([\d\.]+) c$/i) { + $path .= 'C'.xform_xy($1, $2, $3, $4, $5, $6); + $cpx = $5; + $cpy = $6; + } elsif (/^b$/) { + $path .= 'z'; + $strokeparams = strokeparams (); + print " \n"; + print " \n"; + print " \n"; + $path = ''; + } elsif (/^B$/) { + $strokeparams = strokeparams (); + print " \n"; + print " \n"; + print " \n"; + $path = ''; + } elsif (/^f$/i) { + $path .= 'z'; + if (! $fillcolor) { + warn "Error: Fill color not defined in source file!\n"; + print " \n"; + } else { + print " \n"; + print " \n"; + print " \n"; + } + $path = ''; + } elsif (/^s$/) { + $path .= 'z'; + $strokeparams = strokeparams (); + #print " \n"; + print " \n"; + print " \n"; + print " \n"; + $path = ''; + } elsif (/^S$/) { + $strokeparams = strokeparams (); + #print " \n"; + print " \n"; + print " \n"; + print " \n"; + $path = ''; + } elsif (/^1 XR$/) { + + if( $firstChar != 0){ + print (" \n\n"); + } + + $weareintext=0; + + $firstChar = 0; + } elsif (/^TP$/) { + #Something do with the text;) +# $weareintext=1; + } elsif (/^([\d\.]+) ([\d\.]+) ([\d\.]+) ([\d\.]+) ([\d\.]+) ([\d\.]+) ([\d\.]+) Tp$/i) { + + # Text position etc; + $cpx=$5; + $cpy=$pagesize - $6; + ## print ("x:$5 y:$6\r\n"); + + } elsif (/^TO$/) { + #one text ends + } elsif (/^LB$/) { + #Everything ends?? + ## Sometimes ain't working + warn "Error: Unexpected 'LB'! Everything has ended??\n"; + if( $weareintext != 0){ + print (" \n\n"); + } + + } elsif (/^\/_([\S\s]+) ([\d\.]+) Tf$/) { + my $FontName = $1; + my $FontSize = $2; + + ## When we know font name we can render this. + if( $firstChar != 1){ + print ("\n"); + $firstChar = 1; + $weareintext=1; + } else { + print ("\n"); + $weareintext=1; + } + + } elsif (/^\(([\S\s]+)\) Tx$/) { + # Normal text + my $text = $1; + $text =~ s/ä/ä/; + $text =~ s/ö/ö/; + $text =~ s/å/Ã¥/; + + print ("$text"); + + } elsif (/([\d\.]+) w$/) { + $strokewidth = $1; + } elsif (/^%%BeginData: ([\d\.]+)/) { + #How much we got image data + } elsif(/^%%EndData/) { + #and the data ends + } elsif (/^XI/) { + #actual image starts + $weareinimage=1; + } elsif (/^XH/) { + #it ends like they allways do. + #we just save it after this.. + $weareinimage=0; + my $imagename="${imagenum}.png"; + $image->Write($imagename) unless ($skip_images); + $imagenum++; + } elsif (/\[(.*)\](.*)Xh/) { + my @imagepos = split(/ /, $1); + my @imageinfo = split(/ /, $2); + $imagewidth = $imageinfo[1]; + $imageheight = $imageinfo[2]; + + if (! $imagewidth && ! $imageheight ) { + die "ERROR: This fileformat is not supported by " + ."ill2svg.pl.\n(Is it possible you are trying to " + ."use ill2svg.pl on a PDF file?) \n"; + } + + my $imageposx = $imagepos[4]; + my $imageposy = $pagesize - $imagepos[5]; + + #printf("%s %d %d Position x: %f 9y: %f\r\n",$1,@imagepos[4],@imagepos[5],$imageposx,$imageposy); + printf("\r\n"); + + my $size = "${imagewidth}x${imageheight}"; + + if (!$skip_images) { + $image = Image::Magick->new(size=>$size); + $image->Set('density'=>'72'); + $image->Read("xc:white"); + } + $imagex=0; + $imagey=0; + + } else { + if( $weareinimage == 1 ){ + addImageLine( $_ ); + } + + chomp; + + #print "$_\r\n"; + } +} + if( $firstChar != 0){ + print (" \n\n"); + } + +print "\r\n"; + +while (<>) { + if (m/$NL_DOS$/) { + $/ = $NL_DOS; + foreach (split /$NL_DOS/) { + process_line($_); + } + } elsif (m/$NL_MAC$/) { + $/ = $NL_MAC; + foreach (split /$NL_MAC/) { + process_line($_); + } + } else { + chomp; + process_line($_); + } +} +print "\n"; + diff --git a/share/extensions/inkex.py b/share/extensions/inkex.py new file mode 100755 index 000000000..041f7bff7 --- /dev/null +++ b/share/extensions/inkex.py @@ -0,0 +1,103 @@ +#!/usr/bin/env python +""" +inkex.py +A helper module for creating Inkscape extensions + +Copyright (C) 2005 Aaron Spike, aaron@ekips.org + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +""" +import sys, copy, optparse + +#a dictionary of all of the xmlns prefixes in a standard inkscape doc +NSS = { +u'sodipodi' :u'http://inkscape.sourceforge.net/DTD/sodipodi-0.dtd', +u'cc' :u'http://web.resource.org/cc/', +u'svg' :u'http://www.w3.org/2000/svg', +u'dc' :u'http://purl.org/dc/elements/1.1/', +u'rdf' :u'http://www.w3.org/1999/02/22-rdf-syntax-ns#', +u'inkscape' :u'http://www.inkscape.org/namespaces/inkscape', +u'xlink' :u'http://www.w3.org/1999/xlink' +} + +try: + import xml.dom.ext + import xml.dom.ext.reader.Sax2 + import xml.xpath +except: + sys.exit('The inkex.py module requires PyXML. Please download the latest version from .') + +def debug(what): + sys.stderr.write(str(what) + "\n") + return what + +def check_inkbool(option, opt, value): + if str(value).capitalize() == 'True': + return True + elif str(value).capitalize() == 'False': + return False + else: + raise OptionValueError("option %s: invalid inkbool value: %s" % (opt, value)) + +class InkOption(optparse.Option): + TYPES = optparse.Option.TYPES + ("inkbool",) + TYPE_CHECKER = copy.copy(optparse.Option.TYPE_CHECKER) + TYPE_CHECKER["inkbool"] = check_inkbool + + +class Effect: + """A class for creating Inkscape SVG Effects""" + def __init__(self): + self.document=None + self.selected={} + self.options=None + self.args=None + self.OptionParser = optparse.OptionParser(usage="usage: %prog [options] SVGfile",option_class=InkOption) + self.OptionParser.add_option("--id", + action="append", type="string", dest="ids", default=[], + help="id attribute of object to manipulate") + def effect(self): + pass + def getoptions(self,args=sys.argv[1:]): + """Collect command line arguments""" + self.options, self.args = self.OptionParser.parse_args(args) + def parse(self,file=None): + """Parse document in specified file or on stdin""" + reader = xml.dom.ext.reader.Sax2.Reader() + try: + try: + stream = open(file,'r') + except: + stream = open(self.args[-1],'r') + except: + stream = sys.stdin + self.document = reader.fromStream(stream) + stream.close() + def getselected(self): + """Collect selected nodes""" + for id in self.options.ids: + path = '//*[@id="%s"]' % id + for node in xml.xpath.Evaluate(path,self.document): + self.selected[id] = node + def output(self): + """Serialize document into XML on stdout""" + xml.dom.ext.Print(self.document) + def affect(self): + """Affect an SVG document with a callback effect""" + self.getoptions() + self.parse() + self.getselected() + self.effect() + self.output() diff --git a/share/extensions/inkscape-shadow-white.sh b/share/extensions/inkscape-shadow-white.sh new file mode 100755 index 000000000..c1cb0268c --- /dev/null +++ b/share/extensions/inkscape-shadow-white.sh @@ -0,0 +1,2 @@ +#!/bin/sh +convert -mattecolor "#ffff" -frame $((${2} * 3))x$((${2} * 3)) -fx '1' -channel A -blur $((${2} * 3))x${2} $1 $1 diff --git a/share/extensions/inkscape-shadow.sh b/share/extensions/inkscape-shadow.sh new file mode 100755 index 000000000..7a3e45fa9 --- /dev/null +++ b/share/extensions/inkscape-shadow.sh @@ -0,0 +1,2 @@ +#!/bin/sh +convert -mattecolor "#000f" -frame $((${2} * 3))x$((${2} * 3)) -fx '0' -channel A -blur $((${2} * 3))x${2} $1 $1 diff --git a/share/extensions/interp.inx b/share/extensions/interp.inx new file mode 100644 index 000000000..edc1ff4da --- /dev/null +++ b/share/extensions/interp.inx @@ -0,0 +1,17 @@ + + <_name>Interpolate + org.ekips.filter.interp + interp.py + inkex.py + 0.00 + 5 + 2 + true + false + + path + + + diff --git a/share/extensions/interp.py b/share/extensions/interp.py new file mode 100755 index 000000000..5edbf026d --- /dev/null +++ b/share/extensions/interp.py @@ -0,0 +1,332 @@ +#!/usr/bin/env python +''' +Copyright (C) 2005 Aaron Spike, aaron@ekips.org + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +''' +import inkex, cubicsuperpath, simplestyle, copy, math, re, bezmisc + +uuconv = {'in':90.0, 'pt':1.25, 'px':1, 'mm':3.5433070866, 'cm':35.433070866, 'pc':15.0} +def numsegs(csp): + return sum([len(p)-1 for p in csp]) +def interpcoord(v1,v2,p): + return v1+((v2-v1)*p) +def interppoints(p1,p2,p): + return [interpcoord(p1[0],p2[0],p),interpcoord(p1[1],p2[1],p)] +def pointdistance((x1,y1),(x2,y2)): + return math.sqrt(((x2 - x1) ** 2) + ((y2 - y1) ** 2)) +def bezlenapprx(sp1, sp2): + return pointdistance(sp1[1], sp1[2]) + pointdistance(sp1[2], sp2[0]) + pointdistance(sp2[0], sp2[1]) +def tpoint((x1,y1), (x2,y2), t = 0.5): + return [x1+t*(x2-x1),y1+t*(y2-y1)] +def cspbezsplit(sp1, sp2, t = 0.5): + m1=tpoint(sp1[1],sp1[2],t) + m2=tpoint(sp1[2],sp2[0],t) + m3=tpoint(sp2[0],sp2[1],t) + m4=tpoint(m1,m2,t) + m5=tpoint(m2,m3,t) + m=tpoint(m4,m5,t) + return [[sp1[0][:],sp1[1][:],m1], [m4,m,m5], [m3,sp2[1][:],sp2[2][:]]] +def cspbezsplitatlength(sp1, sp2, l = 0.5, tolerance = 0.001): + bez = (sp1[1][:],sp1[2][:],sp2[0][:],sp2[1][:]) + t = bezmisc.beziertatlength(bez, l, tolerance) + return cspbezsplit(sp1, sp2, t) +def cspseglength(sp1,sp2, tolerance = 0.001): + bez = (sp1[1][:],sp1[2][:],sp2[0][:],sp2[1][:]) + return bezmisc.bezierlength(bez, tolerance) +def csplength(csp): + total = 0 + lengths = [] + for sp in csp: + lengths.append([]) + for i in xrange(1,len(sp)): + l = cspseglength(sp[i-1],sp[i]) + lengths[-1].append(l) + total += l + return lengths, total +def styleunittouu(string): + unit = re.compile('(%s)$' % '|'.join(uuconv.keys())) + param = re.compile(r'(([-+]?[0-9]+(\.[0-9]*)?|[-+]?\.[0-9]+)([eE][-+]?[0-9]+)?)') + + p = param.match(string) + u = unit.search(string) + if p: + retval = float(p.string[p.start():p.end()]) + else: + retval = 0.0 + if u: + try: + return retval * uuconv[u.string[u.start():u.end()]] + except KeyError: + pass + return retval + +def tweenstylefloat(property, start, end, time): + sp = float(start[property]) + ep = float(end[property]) + return str(sp + (time * (ep - sp))) +def tweenstyleunit(property, start, end, time): + sp = styleunittouu(start[property]) + ep = styleunittouu(end[property]) + return str(sp + (time * (ep - sp))) +def tweenstylecolor(property, start, end, time): + sr,sg,sb = parsecolor(start[property]) + er,eg,eb = parsecolor(end[property]) + return '#%s%s%s' % (tweenhex(time,sr,er),tweenhex(time,sg,eg),tweenhex(time,sb,eb)) +def tweenhex(time,s,e): + s = float(int(s,16)) + e = float(int(e,16)) + retval = hex(int(math.floor(s + (time * (e - s)))))[2:] + if len(retval)==1: + retval = '0%s' % retval + return retval +def parsecolor(c): + r,g,b = '0','0','0' + if c[:1]=='#': + if len(c)==4: + r,g,b = c[1:2],c[2:3],c[3:4] + elif len(c)==7: + r,g,b = c[1:3],c[3:5],c[5:7] + return r,g,b + +class Interp(inkex.Effect): + def __init__(self): + inkex.Effect.__init__(self) + self.OptionParser.add_option("-e", "--exponent", + action="store", type="float", + dest="exponent", default=0.0, + help="values other than zero give non linear interpolation") + self.OptionParser.add_option("-s", "--steps", + action="store", type="int", + dest="steps", default=5, + help="number of interpolation steps") + self.OptionParser.add_option("-m", "--method", + action="store", type="int", + dest="method", default=2, + help="method of interpolation") + self.OptionParser.add_option("-d", "--dup", + action="store", type="inkbool", + dest="dup", default=True, + help="duplicate endpaths") + self.OptionParser.add_option("--style", + action="store", type="inkbool", + dest="style", default=True, + help="try interpolation of some style properties") + def effect(self): + exponent = self.options.exponent + if exponent>= 0: + exponent = 1.0 + exponent + else: + exponent = 1.0/(1.0 - exponent) + steps = [1.0/(self.options.steps + 1.0)] + for i in range(self.options.steps - 1): + steps.append(steps[0] + steps[-1]) + steps = [step**exponent for step in steps] + + paths = {} + styles = {} + for id in self.options.ids: + node = self.selected[id] + if node.tagName =='path': + paths[id] = cubicsuperpath.parsePath(node.attributes.getNamedItem('d').value) + styles[id] = simplestyle.parseStyle(node.attributes.getNamedItem('style').value) + else: + self.options.ids.remove(id) + + for i in range(1,len(self.options.ids)): + start = copy.deepcopy(paths[self.options.ids[i-1]]) + end = copy.deepcopy(paths[self.options.ids[i]]) + sst = copy.deepcopy(styles[self.options.ids[i-1]]) + est = copy.deepcopy(styles[self.options.ids[i]]) + basestyle = copy.deepcopy(sst) + + #prepare for experimental style tweening + if self.options.style: + dostroke = True + dofill = True + styledefaults = {'opacity':'1.0', 'stroke-opacity':'1.0', 'fill-opacity':'1.0', + 'stroke-width':'1.0', 'stroke':'none', 'fill':'none'} + for key in styledefaults.keys(): + sst.setdefault(key,styledefaults[key]) + est.setdefault(key,styledefaults[key]) + isnotplain = lambda x: not (x=='none' or x[:1]=='#') + if isnotplain(sst['stroke']) or isnotplain(est['stroke']) or (sst['stroke']=='none' and est['stroke']=='none'): + dostroke = False + if isnotplain(sst['fill']) or isnotplain(est['fill']) or (sst['fill']=='none' and est['fill']=='none'): + dofill = False + if dostroke: + if sst['stroke']=='none': + sst['stroke-width'] = '0.0' + sst['stroke-opacity'] = '0.0' + sst['stroke'] = est['stroke'] + elif est['stroke']=='none': + est['stroke-width'] = '0.0' + est['stroke-opacity'] = '0.0' + est['stroke'] = sst['stroke'] + if dofill: + if sst['fill']=='none': + sst['fill-opacity'] = '0.0' + sst['fill'] = est['fill'] + elif est['fill']=='none': + est['fill-opacity'] = '0.0' + est['fill'] = sst['fill'] + + + + if self.options.method == 2: + #subdivide both paths into segments of relatively equal lengths + slengths, stotal = csplength(start) + elengths, etotal = csplength(end) + lengths = {} + t = 0 + for sp in slengths: + for l in sp: + t += l / stotal + lengths.setdefault(t,0) + lengths[t] += 1 + t = 0 + for sp in elengths: + for l in sp: + t += l / etotal + lengths.setdefault(t,0) + lengths[t] += -1 + sadd = [k for (k,v) in lengths.iteritems() if v < 0] + sadd.sort() + eadd = [k for (k,v) in lengths.iteritems() if v > 0] + eadd.sort() + + t = 0 + s = [[]] + for sp in slengths: + if not start[0]: + s.append(start.pop(0)) + s[-1].append(start[0].pop(0)) + for l in sp: + pt = t + t += l / stotal + if sadd and t > sadd[0]: + while sadd and sadd[0] < t: + nt = (sadd[0] - pt) / (t - pt) + bezes = cspbezsplitatlength(s[-1][-1][:],start[0][0][:], nt) + s[-1][-1:] = bezes[:2] + start[0][0] = bezes[2] + pt = sadd.pop(0) + s[-1].append(start[0].pop(0)) + t = 0 + e = [[]] + for sp in elengths: + if not end[0]: + e.append(end.pop(0)) + e[-1].append(end[0].pop(0)) + for l in sp: + pt = t + t += l / etotal + if eadd and t > eadd[0]: + while eadd and eadd[0] < t: + nt = (eadd[0] - pt) / (t - pt) + bezes = cspbezsplitatlength(e[-1][-1][:],end[0][0][:], nt) + e[-1][-1:] = bezes[:2] + end[0][0] = bezes[2] + pt = eadd.pop(0) + e[-1].append(end[0].pop(0)) + start = s[:] + end = e[:] + else: + #which path has fewer segments? + lengthdiff = numsegs(start) - numsegs(end) + #swap shortest first + if lengthdiff > 0: + start, end = end, start + #subdivide the shorter path + for x in range(abs(lengthdiff)): + maxlen = 0 + subpath = 0 + segment = 0 + for y in range(len(start)): + for z in range(1, len(start[y])): + leng = bezlenapprx(start[y][z-1], start[y][z]) + if leng > maxlen: + maxlen = leng + subpath = y + segment = z + sp1, sp2 = start[subpath][segment - 1:segment + 1] + start[subpath][segment - 1:segment + 1] = cspbezsplit(sp1, sp2) + #if swapped, swap them back + if lengthdiff > 0: + start, end = end, start + + #break paths so that corresponding subpaths have an equal number of segments + s = [[]] + e = [[]] + while start and end: + if start[0] and end[0]: + s[-1].append(start[0].pop(0)) + e[-1].append(end[0].pop(0)) + elif end[0]: + s.append(start.pop(0)) + e[-1].append(end[0][0]) + e.append([end[0].pop(0)]) + elif start[0]: + e.append(end.pop(0)) + s[-1].append(start[0][0]) + s.append([start[0].pop(0)]) + else: + s.append(start.pop(0)) + e.append(end.pop(0)) + + if self.options.dup: + steps = [0] + steps + [1] + #create an interpolated path for each interval + group = self.document.createElement('svg:g') + self.document.documentElement.appendChild(group) + for time in steps: + interp = [] + #process subpaths + for ssp,esp in zip(s, e): + if not (ssp or esp): + break + interp.append([]) + #process superpoints + for sp,ep in zip(ssp, esp): + if not (sp or ep): + break + interp[-1].append([]) + #process points + for p1,p2 in zip(sp, ep): + if not (sp or ep): + break + interp[-1][-1].append(interppoints(p1, p2, time)) + + #remove final subpath if empty. + if not interp[-1]: + del interp[-1] + new = self.document.createElement('svg:path') + + #basic style tweening + if self.options.style: + basestyle['opacity'] = tweenstylefloat('opacity',sst,est,time) + if dostroke: + basestyle['stroke-opacity'] = tweenstylefloat('stroke-opacity',sst,est,time) + basestyle['stroke-width'] = tweenstyleunit('stroke-width',sst,est,time) + basestyle['stroke'] = tweenstylecolor('stroke',sst,est,time) + if dofill: + basestyle['fill-opacity'] = tweenstylefloat('fill-opacity',sst,est,time) + basestyle['fill'] = tweenstylecolor('fill',sst,est,time) + new.setAttribute('style', simplestyle.formatStyle(basestyle)) + new.setAttribute('d', cubicsuperpath.formatPath(interp)) + group.appendChild(new) + +e = Interp() +e.affect() diff --git a/share/extensions/kochify.inx b/share/extensions/kochify.inx new file mode 100644 index 000000000..2e7923f9a --- /dev/null +++ b/share/extensions/kochify.inx @@ -0,0 +1,12 @@ + + <_name>Kochify + org.ekips.filter.kochify + kochify.py + inkex.py + + path + + + diff --git a/share/extensions/kochify.py b/share/extensions/kochify.py new file mode 100755 index 000000000..e6914278c --- /dev/null +++ b/share/extensions/kochify.py @@ -0,0 +1,86 @@ +#!/usr/bin/env python +''' +Copyright (C) 2005 Aaron Spike, aaron@ekips.org + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +''' +import math, tempfile, copy, cPickle, inkex, simplepath + +def findend(d): + end = [] + subPathStart = [] + for cmd,params in d: + if cmd == 'M': + subPathStart = params[-2:] + if cmd == 'Z': + end = subPathStart[:] + else: + end = params[-2:] + return end + +class Kochify(inkex.Effect): + def effect(self): + try: + f = open(tempfile.gettempdir() + '/kochify.bin', 'r') + proto = cPickle.load(f) + f.close() + except: + return False + for id, node in self.selected.iteritems(): + if node.tagName == 'path': + d = node.attributes.getNamedItem('d') + p = simplepath.parsePath(d.value) + last = p[0][1][-2:] + subPathStart = [] + cur = [] + new = [] + for i in range(len(p)): + rep = copy.deepcopy(proto['path']) + cmd, params = p[i] + if cmd == 'M': + subPathStart = params[-2:] + new.append(copy.deepcopy(p[i])) + continue + if cmd == 'Z': + cur = subPathStart[:] + else: + cur = params[-2:] + + if last == cur: + continue + + dx = cur[0]-last[0] + dy = cur[1]-last[1] + length = math.sqrt((dx**2) + (dy**2)) + angle = math.atan2(dy,dx) + + scale = length / proto['length'] + rotate = angle - proto['angle'] + simplepath.scalePath(rep,scale,scale) + simplepath.rotatePath(rep, rotate) + repend = findend(rep) + transx = cur[0] - repend[0] + transy = cur[1] - repend[1] + simplepath.translatePath(rep, transx, transy) + + if proto['endsinz']: + new.extend(rep[:]) + else: + new.extend(rep[1:]) + last = cur[:] + + d.value = simplepath.formatPath(new) +e = Kochify() +e.affect() diff --git a/share/extensions/kochify_load.inx b/share/extensions/kochify_load.inx new file mode 100644 index 000000000..b42a32992 --- /dev/null +++ b/share/extensions/kochify_load.inx @@ -0,0 +1,12 @@ + + <_name>Kochify (Load) + org.ekips.filter.kochify.load + kochify_load.py + inkex.py + + path + + + diff --git a/share/extensions/kochify_load.py b/share/extensions/kochify_load.py new file mode 100755 index 000000000..d50c498c0 --- /dev/null +++ b/share/extensions/kochify_load.py @@ -0,0 +1,60 @@ +#!/usr/bin/env python +''' +Copyright (C) 2005 Aaron Spike, aaron@ekips.org + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +''' +import math, tempfile, cPickle, inkex, simplepath + +def findend(d): + end = [] + subPathStart = [] + for cmd,params in d: + if cmd == 'M': + subPathStart = params[-2:] + if cmd == 'Z': + end = subPathStart[:] + else: + end = params[-2:] + return end + +class LoadKochify(inkex.Effect): + def effect(self): + for id, node in self.selected.iteritems(): + if node.tagName == 'path': + d = simplepath.parsePath(node.attributes.getNamedItem('d').value) + start = d[0][1][-2:] + end = findend(d) + while start == end and len(d): + d = d[:-1] + end = findend(d) + if not end: + break + dx = end[0]-start[0] + dy = end[1]-start[1] + length = math.sqrt((dx**2) + (dy**2)) + angle = math.atan2(dy,dx) + endsinz = False + if d[-1][0]=='Z': + endsinz = True + path = {'start': start, 'end': end, 'endsinz': endsinz, + 'length': length, 'angle': angle, 'path': d} + f = open(tempfile.gettempdir() + '/kochify.bin', 'w') + cPickle.dump(path, f) + f.close() + break + +e = LoadKochify() +e.affect() diff --git a/share/extensions/lindenmayer.inx b/share/extensions/lindenmayer.inx new file mode 100644 index 000000000..655c95e33 --- /dev/null +++ b/share/extensions/lindenmayer.inx @@ -0,0 +1,17 @@ + + <_name>Lindenmayer + org.ekips.filter.turtle.lindenmayer + lindenmayer.py + inkex.py + 3 + 25.0 + 16.0 + ++F + F=FF-[-F+F+F]+[+F-F-F] + + all + + + diff --git a/share/extensions/lindenmayer.py b/share/extensions/lindenmayer.py new file mode 100755 index 000000000..a6848320d --- /dev/null +++ b/share/extensions/lindenmayer.py @@ -0,0 +1,88 @@ +#!/usr/bin/env python +''' +Copyright (C) 2005 Aaron Spike, aaron@ekips.org + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +''' +import inkex, simplestyle, pturtle + +class LSystem(inkex.Effect): + def __init__(self): + inkex.Effect.__init__(self) + self.OptionParser.add_option("-o", "--order", + action="store", type="int", + dest="order", default=3, + help="number of iteration") + self.OptionParser.add_option("-a", "--angle", + action="store", type="float", + dest="angle", default=16.0, + help="angle for turn commands") + self.OptionParser.add_option("-s", "--step", + action="store", type="float", + dest="step", default=25.0, + help="step size") + self.OptionParser.add_option("-x", "--axiom", + action="store", type="string", + dest="axiom", default="++F", + help="initial state of system") + self.OptionParser.add_option("-r", "--rules", + action="store", type="string", + dest="rules", default="F=FF-[-F+F+F]+[+F-F-F]", + help="replacement rules") + self.stack = [] + self.turtle = pturtle.pTurtle() + def iterate(self): + self.rules = dict([i.split("=") for i in self.options.rules.upper().split(";") if i.count("=")==1]) + self.__recurse(self.options.axiom.upper(),0) + return self.turtle.getPath() + def __recurse(self,rule,level): + for c in rule: + if level < self.options.order: + try: + self.__recurse(self.rules[c],level+1) + except KeyError: + pass + + if c == 'F': + self.turtle.pd() + self.turtle.fd(self.options.step) + elif c == 'G': + self.turtle.pu() + self.turtle.fd(self.options.step) + elif c == '+': + self.turtle.lt(self.options.angle) + elif c == '-': + self.turtle.rt(self.options.angle) + elif c == '|': + self.turtle.lt(180) + elif c == '[': + self.stack.append([self.turtle.getpos(), self.turtle.getheading()]) + elif c == ']': + self.turtle.pu() + pos,heading = self.stack.pop() + self.turtle.setpos(pos) + self.turtle.setheading(heading) + def effect(self): + new = self.document.createElement('svg:path') + s = {'stroke-linejoin': 'miter', 'stroke-width': '1.0px', + 'stroke-opacity': '1.0', 'fill-opacity': '1.0', + 'stroke': '#000000', 'stroke-linecap': 'butt', + 'fill': 'none'} + new.setAttribute('style', simplestyle.formatStyle(s)) + new.setAttribute('d', self.iterate()) + self.document.documentElement.appendChild(new) + +e = LSystem() +e.affect() diff --git a/share/extensions/motion.inx b/share/extensions/motion.inx new file mode 100644 index 000000000..46f7e7082 --- /dev/null +++ b/share/extensions/motion.inx @@ -0,0 +1,14 @@ + + <_name>Motion + org.ekips.filter.motion + motion.py + inkex.py + 100 + 45 + + path + + + diff --git a/share/extensions/motion.py b/share/extensions/motion.py new file mode 100755 index 000000000..95100e629 --- /dev/null +++ b/share/extensions/motion.py @@ -0,0 +1,119 @@ +#!/usr/bin/env python +''' +Copyright (C) 2005 Aaron Spike, aaron@ekips.org + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +''' +import math, inkex, simplestyle, simplepath, bezmisc + +class Motion(inkex.Effect): + def __init__(self): + inkex.Effect.__init__(self) + self.OptionParser.add_option("-a", "--angle", + action="store", type="float", + dest="angle", default=45.0, + help="direction of the motion vector") + self.OptionParser.add_option("-m", "--magnitude", + action="store", type="float", + dest="magnitude", default=100.0, + help="magnitude of the motion vector") + + def makeface(self,last,(cmd, params)): + a = [] + a.append(['M',last[:]]) + a.append([cmd, params[:]]) + + #translate path segment along vector + np = params[:] + defs = simplepath.pathdefs[cmd] + for i in range(defs[1]): + if defs[3][i] == 'x': + np[i] += self.vx + elif defs[3][i] == 'y': + np[i] += self.vy + + a.append(['L',[np[-2],np[-1]]]) + + #reverse direction of path segment + np[-2:] = last[0]+self.vx,last[1]+self.vy + if cmd == 'C': + c1 = np[:2], np[2:4] = np[2:4], np[:2] + a.append([cmd,np[:]]) + + a.append(['Z',[]]) + face = self.document.createElement('svg:path') + self.facegroup.appendChild(face) + face.setAttribute('d', simplepath.formatPath(a)) + + + def effect(self): + self.vx = math.cos(math.radians(self.options.angle))*self.options.magnitude + self.vy = math.sin(math.radians(self.options.angle))*self.options.magnitude + for id, node in self.selected.iteritems(): + if node.tagName == 'path': + group = self.document.createElement('svg:g') + self.facegroup = self.document.createElement('svg:g') + node.parentNode.appendChild(group) + group.appendChild(self.facegroup) + group.appendChild(node) + + try: + t = node.attributes.getNamedItem('transform').value + group.setAttribute('transform', t) + node.attributes.getNamedItem('transform').value="" + except AttributeError: + pass + + s = node.attributes.getNamedItem('style').value + self.facegroup.setAttribute('style', s) + + p = simplepath.parsePath(node.attributes.getNamedItem('d').value) + for cmd,params in p: + tees = [] + if cmd == 'C': + bez = (last,params[:2],params[2:4],params[-2:]) + tees = [t for t in bezmisc.beziertatslope(bez,(self.vy,self.vx)) if 0 + <_name>PDF Output + org.inkscape.output.pdf + org.inkscape.output.ps + ps2pdf.sh + ps2pdf + + .pdf + image/x-portable-document-format + <_filetypename>Adobe PDF (*.pdf) + <_filetypetooltip>Adobe Portable Document Format + + + diff --git a/share/extensions/pdf_output_via_gs_on_win32.inx b/share/extensions/pdf_output_via_gs_on_win32.inx new file mode 100644 index 000000000..50e63ced8 --- /dev/null +++ b/share/extensions/pdf_output_via_gs_on_win32.inx @@ -0,0 +1,24 @@ + + + <_name>PDF Output + org.inkscape.output.pdf.via_gs_on_win32 + org.inkscape.output.ps + ps2pdf.cmd + cmd.exe + + .pdf + image/x-portable-document-format + <_filetypename>Adobe PDF (*.pdf) + <_filetypetooltip>Adobe Portable Document Format + + + diff --git a/share/extensions/ps2dxf.sh b/share/extensions/ps2dxf.sh new file mode 100644 index 000000000..3479800e1 --- /dev/null +++ b/share/extensions/ps2dxf.sh @@ -0,0 +1,10 @@ +#!/bin/sh + +TMPDIR="${TMPDIR-/tmp}" +TEMPFILENAME=`mktemp 2>/dev/null || echo "$TMPDIR/tmp-ps-$$.dxf"` +pstoedit -f dxf "$1" "${TEMPFILENAME}" > /dev/null 2>&1 +rc=0 +cat < "${TEMPFILENAME}" || rc=1 +rm -f "${TEMPFILENAME}" +exit $rc +d \ No newline at end of file diff --git a/share/extensions/ps2epsi.sh b/share/extensions/ps2epsi.sh new file mode 100755 index 000000000..3584bcde8 --- /dev/null +++ b/share/extensions/ps2epsi.sh @@ -0,0 +1,9 @@ +#! /bin/sh + +TMPDIR="${TMPDIR-/tmp}" +TEMPFILENAME=`mktemp 2>/dev/null || echo "$TMPDIR/tmp-ps-$$.epsi"` +ps2epsi "$1" "${TEMPFILENAME}" > /dev/null 2>&1 +rc=0 +cat < "${TEMPFILENAME}" || rc=1 +rm -f "${TEMPFILENAME}" +exit $rc diff --git a/share/extensions/ps2pdf.cmd b/share/extensions/ps2pdf.cmd new file mode 100644 index 000000000..81e8ba813 --- /dev/null +++ b/share/extensions/ps2pdf.cmd @@ -0,0 +1,10 @@ +REM BEGIN +@echo off +REM edit %GSDIR% to match the ghostscript installation directory +set GSDIR=%PROGRAMFILES%\gs\gs8.51 +set GSBINDIR=%GSDIR%\bin +set GSLIBDIR=%GSDIR%\lib +set PATH=%GSBINDIR%;%GSLIBDIR%;%PATH% +echo %PATH% +ps2pdf.bat %1 - +REM END \ No newline at end of file diff --git a/share/extensions/ps2pdf.sh b/share/extensions/ps2pdf.sh new file mode 100755 index 000000000..86daa96bc --- /dev/null +++ b/share/extensions/ps2pdf.sh @@ -0,0 +1,2 @@ +#! /bin/sh +exec ps2pdf "$1" - 2> /dev/null diff --git a/share/extensions/ps_input.inx b/share/extensions/ps_input.inx new file mode 100644 index 000000000..84d6907ac --- /dev/null +++ b/share/extensions/ps_input.inx @@ -0,0 +1,17 @@ + + <_name>Postscript Input + org.inkscape.input.ps + org.inkscape.input.sk + pstoedit + + .ps + image/x-postscript + <_filetypename>Postscript (*.ps) + <_filetypetooltip>Postscript + org.inkscape.output.ps + + + diff --git a/share/extensions/pturtle.py b/share/extensions/pturtle.py new file mode 100755 index 000000000..f1806a68b --- /dev/null +++ b/share/extensions/pturtle.py @@ -0,0 +1,80 @@ +#!/usr/bin/env python +''' +Copyright (C) 2005 Aaron Spike, aaron@ekips.org + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +''' +import math +class pTurtle: + '''A Python path turtle''' + def __init__(self, home=(0,0)): + self.__home = [home[0], home[1]] + self.__pos = self.__home[:] + self.__heading = -90 + self.__path = "" + self.__draw = True + self.__new = True + def forward(self,mag): + self.setpos((self.__pos[0] + math.cos(math.radians(self.__heading))*mag, + self.__pos[1] + math.sin(math.radians(self.__heading))*mag)) + def backward(self,mag): + self.setpos((self.__pos[0] - math.cos(math.radians(self.__heading))*mag, + self.__pos[1] - math.sin(math.radians(self.__heading))*mag)) + def right(self,deg): + self.__heading -= deg + def left(self,deg): + self.__heading += deg + def penup(self): + self.__draw = False + self.__new = False + def pendown(self): + if not self.__draw: + self.__new = True + self.__draw = True + def pentoggle(self): + if self.__draw: + self.penup() + else: + self.pendown() + def home(self): + self.setpos(self.__home) + def clean(self): + self.__path = '' + def clear(self): + self.clean() + self.home() + def setpos(self,(x,y)): + if self.__new: + self.__path += "M"+",".join([str(i) for i in self.__pos]) + self.__new = False + self.__pos = [x, y] + if self.__draw: + self.__path += "L"+",".join([str(i) for i in self.__pos]) + def getpos(self): + return self.__pos[:] + def setheading(self,deg): + self.__heading = deg + def getheading(self): + return self.__heading + def sethome(self,(x,y)): + self.__home = [x, y] + def getPath(self): + return self.__path + fd = forward + bk = backward + rt = right + lt = left + pu = penup + pd = pendown diff --git a/share/extensions/radiusrand.inx b/share/extensions/radiusrand.inx new file mode 100644 index 000000000..555785477 --- /dev/null +++ b/share/extensions/radiusrand.inx @@ -0,0 +1,15 @@ + + <_name>Radius Randomize + org.ekips.filter.radiusrand + radiusrand.py + inkex.py + 100.0 + true + false + + path + + + diff --git a/share/extensions/radiusrand.py b/share/extensions/radiusrand.py new file mode 100755 index 000000000..97e9aed41 --- /dev/null +++ b/share/extensions/radiusrand.py @@ -0,0 +1,65 @@ +#!/usr/bin/env python +''' +Copyright (C) 2005 Aaron Spike, aaron@ekips.org + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +''' +import random, math, inkex, cubicsuperpath + +def randomize((x, y), r): + r = random.uniform(0.0,r) + a = random.uniform(0.0,2*math.pi) + x += math.cos(a)*r + y += math.sin(a)*r + return [x, y] + +class RadiusRandomize(inkex.Effect): + def __init__(self): + inkex.Effect.__init__(self) + self.OptionParser.add_option("-r", "--radius", + action="store", type="float", + dest="radius", default=10.0, + help="Randomly move control and end points in this radius") + self.OptionParser.add_option("-c", "--ctrl", + action="store", type="inkbool", + dest="ctrl", default=True, + help="Randomize control points") + self.OptionParser.add_option("-e", "--end", + action="store", type="inkbool", + dest="end", default=True, + help="Randomize nodes") + def effect(self): + for id, node in self.selected.iteritems(): + if node.tagName == 'path': + d = node.attributes.getNamedItem('d') + p = cubicsuperpath.parsePath(d.value) + for subpath in p: + for csp in subpath: + if self.options.end: + delta=randomize([0,0], self.options.radius) + csp[0][0]+=delta[0] + csp[0][1]+=delta[1] + csp[1][0]+=delta[0] + csp[1][1]+=delta[1] + csp[2][0]+=delta[0] + csp[2][1]+=delta[1] + if self.options.ctrl: + csp[0]=randomize(csp[0], self.options.radius) + csp[2]=randomize(csp[2], self.options.radius) + d.value = cubicsuperpath.formatPath(p) + +e = RadiusRandomize() +e.affect() + diff --git a/share/extensions/randompnt.inx b/share/extensions/randompnt.inx new file mode 100644 index 000000000..36086e762 --- /dev/null +++ b/share/extensions/randompnt.inx @@ -0,0 +1,11 @@ + + <_name>Random Point + org.inkscape.effect.randompnt + randompnt + + all + + + randompnt + + diff --git a/share/extensions/randompos.inx b/share/extensions/randompos.inx new file mode 100644 index 000000000..3c677382a --- /dev/null +++ b/share/extensions/randompos.inx @@ -0,0 +1,11 @@ + + <_name>Random Position + org.inkscape.effect.randompos + randompos + + all + + + randompos + + diff --git a/share/extensions/rtree.inx b/share/extensions/rtree.inx new file mode 100644 index 000000000..9832725d9 --- /dev/null +++ b/share/extensions/rtree.inx @@ -0,0 +1,14 @@ + + <_name>Random Tree + org.ekips.filter.turtle.rtree + rtree.py + inkex.py + 100.0 + 40.0 + + all + + + diff --git a/share/extensions/rtree.py b/share/extensions/rtree.py new file mode 100755 index 000000000..8728ed7a3 --- /dev/null +++ b/share/extensions/rtree.py @@ -0,0 +1,59 @@ +#!/usr/bin/env python +''' +Copyright (C) 2005 Aaron Spike, aaron@ekips.org + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +''' +import inkex, simplestyle, pturtle, random + +def rtree(turtle, size, min): + if size < min: + return + turtle.fd(size) + turn = random.uniform(20, 40) + turtle.lt(turn) + rtree(turtle, size*random.uniform(0.5,0.9), min) + turtle.rt(turn) + turn = random.uniform(20, 40) + turtle.rt(turn) + rtree(turtle, size*random.uniform(0.5,0.9), min) + turtle.lt(turn) + turtle.bk(size) + +class RTreeTurtle(inkex.Effect): + def __init__(self): + inkex.Effect.__init__(self) + self.OptionParser.add_option("-s", "--size", + action="store", type="float", + dest="size", default=100.0, + help="initial branch size") + self.OptionParser.add_option("-m", "--minimum", + action="store", type="float", + dest="minimum", default=4.0, + help="minimum branch size") + def effect(self): + new = self.document.createElement('svg:path') + s = {'stroke-linejoin': 'miter', 'stroke-width': '1.0px', + 'stroke-opacity': '1.0', 'fill-opacity': '1.0', + 'stroke': '#000000', 'stroke-linecap': 'butt', + 'fill': 'none'} + new.setAttribute('style', simplestyle.formatStyle(s)) + t = pturtle.pTurtle() + rtree(t, self.options.size, self.options.minimum) + new.setAttribute('d', t.getPath()) + self.document.documentElement.appendChild(new) + +e = RTreeTurtle() +e.affect() diff --git a/share/extensions/simplepath.py b/share/extensions/simplepath.py new file mode 100755 index 000000000..06ed73672 --- /dev/null +++ b/share/extensions/simplepath.py @@ -0,0 +1,201 @@ +#!/usr/bin/env python +""" +simplepath.py +functions for digesting paths into a simple list structure + +Copyright (C) 2005 Aaron Spike, aaron@ekips.org + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +""" +import re, math + +def lexPath(d): + """ + returns and iterator that breaks path data + identifies command and parameter tokens + """ + offset = 0 + length = len(d) + delim = re.compile(r'[ \t\r\n,]+') + command = re.compile(r'[MLHVCSQTAZmlhvcsqtaz]') + parameter = re.compile(r'(([-+]?[0-9]+(\.[0-9]*)?|[-+]?\.[0-9]+)([eE][-+]?[0-9]+)?)') + while 1: + m = delim.match(d, offset) + if m: + offset = m.end() + if offset >= length: + break + m = command.match(d, offset) + if m: + yield [d[offset:m.end()], True] + offset = m.end() + continue + m = parameter.match(d, offset) + if m: + yield [d[offset:m.end()], False] + offset = m.end() + continue + #TODO: create new exception + raise Exception, 'Invalid path data!' +''' +pathdefs = {commandfamily: + [ + implicitnext, + #params, + [casts,cast,cast], + [coord type,x,y,0] + ]} +''' +pathdefs = { + 'M':['L', 2, [float, float], ['x','y']], + 'L':['L', 2, [float, float], ['x','y']], + 'H':['H', 1, [float], ['x']], + 'V':['V', 1, [float], ['y']], + 'C':['C', 6, [float, float, float, float, float, float], ['x','y','x','y','x','y']], + 'S':['S', 4, [float, float, float, float], ['x','y','x','y']], + 'Q':['Q', 4, [float, float, float, float], ['x','y','x','y']], + 'T':['T', 2, [float, float], ['x','y']], + 'A':['A', 7, [float, float, float, int, int, float, float], [0,0,0,0,0,'x','y']], + 'Z':['L', 0, [], []] + } +def parsePath(d): + """ + Parse SVG path and return an array of segments. + Removes all shorthand notation. + Converts coordinates to absolute. + """ + retval = [] + lexer = lexPath(d) + + pen = (0.0,0.0) + subPathStart = pen + lastControl = pen + lastCommand = '' + + while 1: + try: + token, isCommand = lexer.next() + except StopIteration: + break + params = [] + needParam = True + if isCommand: + if not lastCommand and token.upper() != 'M': + raise Exception, 'Invalid path, must begin with moveto.' + else: + command = token + else: + #command was omited + #use last command's implicit next command + needParam = False + if lastCommand: + if token.isupper(): + command = pathdefs[lastCommand.upper()][0] + else: + command = pathdefs[lastCommand.upper()][0].lower() + else: + raise Exception, 'Invalid path, no initial command.' + numParams = pathdefs[command.upper()][1] + while numParams > 0: + if needParam: + try: + token, isCommand = lexer.next() + if isCommand: + raise Exception, 'Invalid number of parameters' + except StopIteration: + raise Exception, 'Unexpected end of path' + cast = pathdefs[command.upper()][2][-numParams] + param = cast(token) + if command.islower(): + if pathdefs[command.upper()][3][-numParams]=='x': + param += pen[0] + elif pathdefs[command.upper()][3][-numParams]=='y': + param += pen[1] + params.append(param) + needParam = True + numParams -= 1 + #segment is now absolute so + outputCommand = command.upper() + + #Flesh out shortcut notation + if outputCommand in ('H','V'): + if outputCommand == 'H': + params.append(pen[1]) + if outputCommand == 'V': + params.insert(0,pen[0]) + outputCommand = 'L' + if outputCommand in ('S','T'): + params.insert(0,pen[1]+(pen[1]-lastControl[1])) + params.insert(0,pen[0]+(pen[0]-lastControl[0])) + if outputCommand == 'S': + outputCommand = 'C' + if outputCommand == 'T': + outputCommand = 'Q' + + #current values become "last" values + if outputCommand == 'M': + subPathStart = tuple(params[0:2]) + if outputCommand == 'Z': + pen = subPathStart + else: + pen = tuple(params[-2:]) + + if outputCommand in ('Q','C'): + lastControl = tuple(params[-4:-2]) + else: + lastControl = pen + lastCommand = command + + retval.append([outputCommand,params]) + return retval + +def formatPath(a): + """Format SVG path data from an array""" + return "".join([cmd + " ".join([str(p) for p in params]) for cmd, params in a]) + +def translatePath(p, x, y): + for cmd,params in p: + defs = pathdefs[cmd] + for i in range(defs[1]): + if defs[3][i] == 'x': + params[i] += x + elif defs[3][i] == 'y': + params[i] += y + +def scalePath(p, x, y): + for cmd,params in p: + defs = pathdefs[cmd] + for i in range(defs[1]): + if defs[3][i] == 'x': + params[i] *= x + elif defs[3][i] == 'y': + params[i] *= y + +def rotatePath(p, a, cx = 0, cy = 0): + if a == 0: + return p + for cmd,params in p: + defs = pathdefs[cmd] + for i in range(defs[1]): + if defs[3][i] == 'x': + x = params[i] - cx + y = params[i + 1] - cy + r = math.sqrt((x**2) + (y**2)) + if r != 0: + theta = math.atan2(y, x) + a + params[i] = (r * math.cos(theta)) + cx + params[i + 1] = (r * math.sin(theta)) + cy + diff --git a/share/extensions/simplestyle.py b/share/extensions/simplestyle.py new file mode 100755 index 000000000..32fd987b7 --- /dev/null +++ b/share/extensions/simplestyle.py @@ -0,0 +1,27 @@ +#!/usr/bin/env python +""" +simplestyle.py +Two simple functions for working with inline css + +Copyright (C) 2005 Aaron Spike, aaron@ekips.org + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +""" +def parseStyle(s): + """Create a dictionary from the value of an inline style attribute""" + return dict([i.split(":") for i in s.split(";")]) +def formatStyle(a): + """Format an inline style attribute from a dictionary""" + return ";".join([":".join(i) for i in a.iteritems()]) diff --git a/share/extensions/sk2svg.sh b/share/extensions/sk2svg.sh new file mode 100755 index 000000000..dbfb3d1f7 --- /dev/null +++ b/share/extensions/sk2svg.sh @@ -0,0 +1,12 @@ +#! /bin/sh + +rc=0 + +TMPDIR="${TMPDIR-/tmp}" +UNIQTMPDIR=`mktemp -d 2>/dev/null || (mkdir "$TMPDIR/sk2svg.$$" && echo "$TMPDIR/sk2svg.$$") || echo "$TMPDIR"` +TMPSVG="$UNIQTMPDIR/sk2svg$$.svg" +skconvert "$1" "$TMPSVG" > /dev/null 2>&1 || rc=1 +cat < "$TMPSVG" || RC=1 +rm -f "$TMPSVG" +[ "$UNIQTMPDIR" = "$TMPDIR" ] || rmdir "$UNIQTMPDIR" +exit $rc diff --git a/share/extensions/sk_input.inx b/share/extensions/sk_input.inx new file mode 100644 index 000000000..e64e8ef0c --- /dev/null +++ b/share/extensions/sk_input.inx @@ -0,0 +1,15 @@ + + <_name>Sketch Input + org.inkscape.input.sk + sk2svg.sh + skconvert + + .sk + application/x-sketch + <_filetypename>Sketch Diagram (*.sk) + <_filetypetooltip>A diagram created with the program Sketch + + + diff --git a/share/extensions/straightseg.inx b/share/extensions/straightseg.inx new file mode 100644 index 000000000..490efd187 --- /dev/null +++ b/share/extensions/straightseg.inx @@ -0,0 +1,14 @@ + + <_name>Segment Straightener + org.ekips.filter.straightseg + straightseg.py + inkex.py + 50.0 + 1 + + path + + + diff --git a/share/extensions/straightseg.py b/share/extensions/straightseg.py new file mode 100755 index 000000000..692160e4d --- /dev/null +++ b/share/extensions/straightseg.py @@ -0,0 +1,69 @@ +#!/usr/bin/env python +''' +Copyright (C) 2005 Aaron Spike, aaron@ekips.org + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +''' +import math, inkex, simplepath, sys + +def pointAtPercent((x1, y1), (x2, y2), percent): + percent /= 100.0 + x = x1 + (percent * (x2 - x1)) + y = y1 + (percent * (y2 - y1)) + return [x,y] + +class SegmentStraightener(inkex.Effect): + def __init__(self): + inkex.Effect.__init__(self) + self.OptionParser.add_option("-p", "--percent", + action="store", type="float", + dest="percent", default=10.0, + help="move curve handles PERCENT percent closer to a straight line") + self.OptionParser.add_option("-b", "--behavior", + action="store", type="int", + dest="behave", default=1, + help="straightening behavior for cubic segments") + def effect(self): + for id, node in self.selected.iteritems(): + if node.tagName == 'path': + d = node.attributes.getNamedItem('d') + p = simplepath.parsePath(d.value) + last = [] + subPathStart = [] + for cmd,params in p: + if cmd == 'C': + if self.options.behave <= 1: + #shorten handles towards end points + params[:2] = pointAtPercent(params[:2],last[:],self.options.percent) + params[2:4] = pointAtPercent(params[2:4],params[-2:],self.options.percent) + else: + #shorten handles towards thirds of the segment + dest1 = pointAtPercent(last[:],params[-2:],33.3) + dest2 = pointAtPercent(params[-2:],last[:],33.3) + params[:2] = pointAtPercent(params[:2],dest1[:],self.options.percent) + params[2:4] = pointAtPercent(params[2:4],dest2[:],self.options.percent) + elif cmd == 'Q': + dest = pointAtPercent(last[:],params[-2:],50) + params[:2] = pointAtPercent(params[:2],dest,self.options.percent) + if cmd == 'M': + subPathStart = params[-2:] + if cmd == 'Z': + last = subPathStart[:] + else: + last = params[-2:] + d.value = simplepath.formatPath(p) + +e = SegmentStraightener() +e.affect() diff --git a/share/extensions/summersnight.inx b/share/extensions/summersnight.inx new file mode 100644 index 000000000..82b140b26 --- /dev/null +++ b/share/extensions/summersnight.inx @@ -0,0 +1,12 @@ + + <_name>Summer's Night + org.ekips.filter.summersnight + summersnight.py + inkex.py + + path + + + diff --git a/share/extensions/summersnight.py b/share/extensions/summersnight.py new file mode 100755 index 000000000..7ddfdf275 --- /dev/null +++ b/share/extensions/summersnight.py @@ -0,0 +1,99 @@ +#!/usr/bin/env python +""" +Copyright (C) 2005 Aaron Spike, aaron@ekips.org + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +""" +import inkex, os, re, simplepath, cubicsuperpath +from ffgeom import * + +uuconv = {'in':90.0, 'pt':1.25, 'px':1, 'mm':3.5433070866, 'cm':35.433070866, 'pc':15.0} +def unittouu(string): + unit = re.compile('(%s)$' % '|'.join(uuconv.keys())) + param = re.compile(r'(([-+]?[0-9]+(\.[0-9]*)?|[-+]?\.[0-9]+)([eE][-+]?[0-9]+)?)') + + p = param.match(string) + u = unit.search(string) + if p: + retval = float(p.string[p.start():p.end()]) + else: + retval = 0.0 + if u: + try: + return retval * uuconv[u.string[u.start():u.end()]] + except KeyError: + pass + return retval + +class Project(inkex.Effect): + def __init__(self): + inkex.Effect.__init__(self) + def effect(self): + if len(self.options.ids) < 2: + inkex.debug("Requires two selected paths. The second must be exctly four nodes long.") + exit() + + #obj is selected second + obj = self.selected[self.options.ids[0]] + trafo = self.selected[self.options.ids[1]] + if obj.tagName == 'path' and trafo.tagName == 'path': + #distil trafo into four node points + trafo = cubicsuperpath.parsePath(trafo.attributes.getNamedItem('d').value) + trafo = [[Point(csp[1][0],csp[1][1]) for csp in subs] for subs in trafo][0][:4] + + #vectors pointing away from the trafo origin + self.t1 = Segment(trafo[0],trafo[1]) + self.t2 = Segment(trafo[1],trafo[2]) + self.t3 = Segment(trafo[3],trafo[2]) + self.t4 = Segment(trafo[0],trafo[3]) + + #query inkscape about the bounding box of obj + self.q = {'x':0,'y':0,'width':0,'height':0} + file = self.args[-1] + id = self.options.ids[0] + for query in self.q.keys(): + f = os.popen("inkscape --query-%s --query-id=%s %s" % (query,id,file)) + self.q[query] = float(f.read()) + f.close() + #glean document height from the SVG + docheight = unittouu(inkex.xml.xpath.Evaluate('/svg/@height',self.document)[0].value) + #Flip inkscapes transposed renderer coords + self.q['y'] = docheight - self.q['y'] - self.q['height'] + + #process path + d = obj.attributes.getNamedItem('d') + p = cubicsuperpath.parsePath(d.value) + for subs in p: + for csp in subs: + csp[0] = self.trafopoint(csp[0]) + csp[1] = self.trafopoint(csp[1]) + csp[2] = self.trafopoint(csp[2]) + d.value = cubicsuperpath.formatPath(p) + + def trafopoint(self,(x,y)): + #Transform algorithm thanks to Jose Hevia (freon) + vector = Segment(Point(self.q['x'],self.q['y']),Point(x,y)) + xratio = abs(vector.delta_x())/self.q['width'] + yratio = abs(vector.delta_y())/self.q['height'] + + horz = Segment(self.t1.pointAtRatio(xratio),self.t3.pointAtRatio(xratio)) + vert = Segment(self.t4.pointAtRatio(yratio),self.t2.pointAtRatio(yratio)) + + p = intersectSegments(vert,horz) + return [p['x'],p['y']] + +e = Project() +e.affect() diff --git a/share/extensions/svg_and_media_zip_output.inx b/share/extensions/svg_and_media_zip_output.inx new file mode 100644 index 000000000..95863aec3 --- /dev/null +++ b/share/extensions/svg_and_media_zip_output.inx @@ -0,0 +1,18 @@ + + <_name>ZIP Output + org.inkscape.output.ZIP + org.inkscape.output.svg.inkscape + svg_and_media_zip_output.py + inkex.py + + .zip + application/x-zip + <_filetypename>Compressed Inkscape SVG with media (*.zip) + <_filetypetooltip>Inkscape's native file format compressed with Zip and including all media files + FALSE + + + diff --git a/share/extensions/svg_and_media_zip_output.py b/share/extensions/svg_and_media_zip_output.py new file mode 100644 index 000000000..09ecb5f99 --- /dev/null +++ b/share/extensions/svg_and_media_zip_output.py @@ -0,0 +1,123 @@ +#!/usr/bin/env python +""" +svg_and_media_zip_output.py +An extention which collects all images to the documents directory and +creates a zip archive containing all images and the document + +Copyright (C) 2005 Pim Snel, pim@lingewoud.com +this is the first Python script ever created +its based on embedimage.py + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +Version 0.3 + +TODO +- fix bug: not saving existing .zip after a Collect for Output is run + this bug occurs because after running an effect extention the inkscape:output_extension is reset to svg.inkscape + the file name is still xxx.zip. after saving again the file xxx.zip is written with a plain .svg which + looks like a corrupt zip +- maybe add better extention +""" + +import inkex, os.path +import os +import string +import zipfile +import shutil +import sys +import tempfile + +class MyEffect(inkex.Effect): + def __init__(self): + inkex.Effect.__init__(self) + + self.documentDst=None + + def parseTmp(self,file=None): + """Parse document in specified file or on stdin""" + reader = inkex.xml.dom.ext.reader.Sax2.Reader() + try: + try: + stream = open(file,'r') + except: + stream = open(self.args[-1],'r') + except: + stream = sys.stdin + self.documentDst = reader.fromStream(stream) + stream.close() + + def output(self): + pass + + def effect(self): + + #get needed info from orig document + ctx_orig = inkex.xml.xpath.Context.Context(self.document,processorNss=inkex.NSS) + + ttmp_orig = inkex.xml.xpath.Evaluate('/svg',self.document, context=ctx_orig) + + docbase = ttmp_orig[0].attributes.getNamedItemNS(inkex.NSS[u'sodipodi'],'docbase') + docname = ttmp_orig[0].attributes.getNamedItemNS(inkex.NSS[u'sodipodi'],'docname') + + orig_tmpfile = sys.argv[1] + + # create destination zip in same directory as the document + z = zipfile.ZipFile(docbase.value + '/'+ docname.value + '.zip', 'w') + + #create os temp dir + tmp_dir = tempfile.mkdtemp() + + #fixme replace whatever extention + docstripped = docname.value.replace('.zip', '') + + #read tmpdoc and copy all images to temp dir + for node in inkex.xml.xpath.Evaluate('//image',self.document, context=ctx_orig): + self.collectAndZipImages(node, tmp_dir, docname, z) + + ##copy tmpdoc to tempdir + dst_file = os.path.join(tmp_dir, docstripped) + stream = open(dst_file,'w') + + inkex.xml.dom.ext.Print(self.document,stream) + + stream.close() + + z.write(dst_file.encode("latin-1"),docstripped.encode("latin-1")+'.svg') + z.close() + + shutil.move(docbase.value + '/'+ docname.value + '.zip',docbase.value + '/'+ docname.value) + + shutil.rmtree(tmp_dir) + + def collectAndZipImages(self, node, tmp_dir, docname, z): + xlink = node.attributes.getNamedItemNS(inkex.NSS[u'xlink'],'href') + if (xlink.value[:4]!='data'): + absref=node.attributes.getNamedItemNS(inkex.NSS[u'sodipodi'],'absref') + + if (os.path.isfile(absref.value)): + shutil.copy(absref.value,tmp_dir) + z.write(absref.value.encode("latin-1"),os.path.basename(absref.value).encode("latin-1")) + + elif (os.path.isfile(tmp_dir + '/' + absref.value)): + shutil.copy(tmp_dir + '/' + absref.value,tmp_dir) + z.write(tmp_dir + '/' + absref.value.encode("latin-1"),os.path.basename(absref.value).encode("latin-1")) + + xlink.value = os.path.basename(absref.value) + absref.value = os.path.basename(absref.value) + + +e = MyEffect() +e.affect() diff --git a/share/extensions/svg_dropshadow b/share/extensions/svg_dropshadow new file mode 100644 index 000000000..0412d4827 --- /dev/null +++ b/share/extensions/svg_dropshadow @@ -0,0 +1,88 @@ +#!/usr/bin/perl -w +# +# svg_dropshadow +# +# Creates drop shadows for all svg elements specified by --id, or +# whole file if no ids are given. +# +# Authors: Daniel Goude (goude@dtek.chalmers.se) +# + +use strict; +use warnings; + +use File::Basename(); +use lib File::Basename::dirname($0); + +use SpSVG; + +my $sp = new SpSVG; + +# Set the script name, used when displaying --help +$sp->set_name($0); + +# Set usage string (options are handled separately). +my $usage = <set_usage($usage); + +# Set script specific options and description (used for --help) +# SpSVG will hasdle in/out files, and help +my @opt_vals = ( + { + "opt" => "color=s", + "desc" => "Shadow color (default black)", + }, + + + { + "opt" => "opacity=s", + "desc" => "Shadow offset (0-1, default 0.5)", + }, + + { + "opt" => "offset=s", + "desc" => "Shadow offset, default 10", + }, +); + +my %opts = $sp->get_opts(@opt_vals); + +my $color = $opts{'color'} || 'black'; +my $opacity = $opts{'opacity'} || '0.5'; +my $offset= $opts{'offset'} || '10'; + +# Read input file (from --file or STDIN) +$sp->parse; + +# Apply make_shadow to selected ids, or whole file +$sp->process_ids(\&make_shadow); + +# Dump the file (to --output or STDOUT) +$sp->dump; + +# That's it! + +# make_shadow takes an svg fragment and returns named fragment +# with a shadow added +sub make_shadow { + my $element = shift; + + # Duplicate element + my $shadow = $element; + + # Set shadow color + $shadow =~ s/(stroke|fill):[^;]+;/$1:$color;/ig; + + my $svg = < + $shadow + + $element +EOF + return $svg; +} + + diff --git a/share/extensions/svgz_input.inx b/share/extensions/svgz_input.inx new file mode 100644 index 000000000..ad142d0c9 --- /dev/null +++ b/share/extensions/svgz_input.inx @@ -0,0 +1,17 @@ + + <_name>SVGZ Input + org.inkscape.input.svgz + gzip + org.inkscape.input.svg + + .svgz + image/x-svgz + <_filetypename>Compressed Inkscape SVG (*.svgz) + <_filetypetooltip>Inkscape's native file format compressed with GZip + org.inkscape.output.svgz + + + diff --git a/share/extensions/svgz_output.inx b/share/extensions/svgz_output.inx new file mode 100644 index 000000000..0db0e188b --- /dev/null +++ b/share/extensions/svgz_output.inx @@ -0,0 +1,17 @@ + + <_name>SVGZ Output + org.inkscape.output.SVGZ + org.inkscape.output.svg.inkscape + gzip + + .svgz + image/x-svgz + <_filetypename>Compressed Inkscape SVG (*.svgz) + <_filetypetooltip>Inkscape's native file format compressed with GZip + FALSE + + + diff --git a/share/extensions/txt2svg.inx b/share/extensions/txt2svg.inx new file mode 100644 index 000000000..4e70d5ce9 --- /dev/null +++ b/share/extensions/txt2svg.inx @@ -0,0 +1,16 @@ + + <_name>Text Input + org.inkscape.input.txt + txt2svg.pl + perl + + .txt + text/html + <_filetypename>Text File (*.txt) + <_filetypetooltip>ASCII Text + + + diff --git a/share/extensions/txt2svg.pl b/share/extensions/txt2svg.pl new file mode 100755 index 000000000..ea5769797 --- /dev/null +++ b/share/extensions/txt2svg.pl @@ -0,0 +1,33 @@ +#!/usr/bin/perl + +# This is a script to render a plain text file into SVG, line by line. + +use strict; +use SVG; +use vars qw($VERSION); +$VERSION = '1.00'; + +my $svg = new SVG; + +$svg->comment('Generated by txt2svg'); + +my $i=0; +while (<>) { + chomp($_); + s/\t/ /g; # Convert tabs into spaces, otherwise we get errors about invalid char + + my $text = $svg->text(id => "text_line_$i", + x => 10, + y => 12*(1+$i), + 'xml:space' => 'preserve', + style => { 'font' => 'Courier', + 'font-family' => 'Courier 10 pitch', + 'font-size' => 10, + } + ) + ->cdata($_); + $i++; +} + +print $svg->xmlify(); + diff --git a/share/extensions/wavy.inx b/share/extensions/wavy.inx new file mode 100644 index 000000000..64a96d293 --- /dev/null +++ b/share/extensions/wavy.inx @@ -0,0 +1,17 @@ + + <_name>Function Plotter + org.ekips.filter.wavy + wavy.py + inkex.py + 4.0 + 8 + sin(x) + true + cos(x) + + rect + + + diff --git a/share/extensions/wavy.py b/share/extensions/wavy.py new file mode 100755 index 000000000..aa438e121 --- /dev/null +++ b/share/extensions/wavy.py @@ -0,0 +1,133 @@ +#!/usr/bin/env python +''' +Copyright (C) 2005 Aaron Spike, aaron@ekips.org + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + + +drawwave() was translated into python from the postscript version +described at http://www.ghostscript.com/person/toby/ and located +at http://www.telegraphics.com.au/sw/sine.ps . +http://www.tinaja.com/glib/bezsine.pdf shows another method for +approximating sine with beziers. + +The orginal postscript version displayed the following copyright +notice and was released under the terms of the GPL: +Copyright (C) 2001-3 Toby Thain, toby@telegraphics.com.au +''' +import inkex, simplepath, simplestyle +from math import * +from random import * + +def drawwave(samples, periods, width, height, left, top, + fx = "sin(x)", fpx = "cos(x)", fponum = True): + + # step is the distance between nodes on x + step = 2*pi / samples + third = step / 3.0 + + # coords and scales based on the source rect + xoff = left + yoff = top + (height / 2) + scalex = width / (2*pi * periods) + scaley = height / 2 + procx = lambda x: x * scalex + xoff + procy = lambda y: y * scaley + yoff + + # functions specified by the user + if fx != "": + f = eval('lambda x: ' + fx) + if fpx != "": + fp = eval('lambda x: ' + fpx) + + # initialize function and derivative for 0; + # they are carried over from one iteration to the next, to avoid extra function calculations + y0 = f(0) + if fponum == True: # numerical derivative, using 0.001*step as the small differential + d0 = (f(0 + 0.001*step) - y0)/(0.001*step) + else: # derivative given by the user + d0 = fp(0) + + a = [] # path array + a.append(['M',[procx(0.0), procy(y0)]]) # initial moveto + + for i in range(int(samples * periods)): + x = i * step + y1 = f(x + step) + if fponum == True: # numerical derivative + d1 = (y1 - f(x + step - 0.001*step))/(0.001*step) + else: # derivative given by the user + d1 = fp(x + step) + # create curve + a.append(['C',[procx(x + third), procy(y0 + (d0 * third)), + procx(x + (step - third)), procy(y1 - (d1 * third)), + procx(x + step), procy(y1)]]) + y0 = y1 # next segment's y0 is this segment's y1 + d0 = d1 # we assume the function is smooth everywhere, so carry over the derivative too + + return a + +class Wavy(inkex.Effect): + def __init__(self): + inkex.Effect.__init__(self) + self.OptionParser.add_option("-p", "--periods", + action="store", type="float", + dest="periods", default=4.0, + help="Periods (2*Pi each)") + self.OptionParser.add_option("-s", "--samples", + action="store", type="int", + dest="samples", default=8, + help="Samples per period") + self.OptionParser.add_option("--fofx", + action="store", type="string", + dest="fofx", default="sin(x)", + help="f(x) for plotting") + self.OptionParser.add_option("--fponum", + action="store", type="inkbool", + dest="fponum", default=True, + help="Calculate the first derivative numerically") + self.OptionParser.add_option("--fpofx", + action="store", type="string", + dest="fpofx", default="cos(x)", + help="f'(x) for plotting") + def effect(self): + for id, node in self.selected.iteritems(): + if node.tagName == 'rect': + new = self.document.createElement('svg:path') + x = float(node.attributes.getNamedItem('x').value) + y = float(node.attributes.getNamedItem('y').value) + w = float(node.attributes.getNamedItem('width').value) + h = float(node.attributes.getNamedItem('height').value) + + s = node.attributes.getNamedItem('style').value + new.setAttribute('style', s) + try: + t = node.attributes.getNamedItem('transform').value + new.setAttribute('transform', t) + except AttributeError: + pass + new.setAttribute('d', simplepath.formatPath( + drawwave(self.options.samples, + self.options.periods, + w,h,x,y, + self.options.fofx, + self.options.fpofx, + self.options.fponum))) + node.parentNode.appendChild(new) + node.parentNode.removeChild(node) + +e = Wavy() +e.affect() diff --git a/share/extensions/whirl.inx b/share/extensions/whirl.inx new file mode 100644 index 000000000..5b7069d33 --- /dev/null +++ b/share/extensions/whirl.inx @@ -0,0 +1,16 @@ + + <_name>Whirl + org.ekips.filter.whirl + whirl.py + inkex.py + 100.0 + 100.0 + 100.0 + true + + path + + + diff --git a/share/extensions/whirl.py b/share/extensions/whirl.py new file mode 100644 index 000000000..35dbc0840 --- /dev/null +++ b/share/extensions/whirl.py @@ -0,0 +1,65 @@ +#!/usr/bin/env python +''' +Copyright (C) 2005 Aaron Spike, aaron@ekips.org + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +''' +import math, inkex, cubicsuperpath + +class Whirl(inkex.Effect): + def __init__(self): + inkex.Effect.__init__(self) + self.OptionParser.add_option("-x", "--centerx", + action="store", type="float", + dest="centerx", default=10.0, + help="") + self.OptionParser.add_option("-y", "--centery", + action="store", type="float", + dest="centery", default=0.0, + help="") + self.OptionParser.add_option("-t", "--whirl", + action="store", type="float", + dest="whirl", default=1.0, + help="amount of whirl") + self.OptionParser.add_option("-r", "--rotation", + action="store", type="inkbool", + dest="rotation", default=True, + help="direction of rotation") + def effect(self): + for id, node in self.selected.iteritems(): + rotation = 1 + if self.options.rotation == True: + rotation = -1 + whirl = self.options.whirl / 1000 + if node.tagName == 'path': + d = node.attributes.getNamedItem('d') + p = cubicsuperpath.parsePath(d.value) + for sub in p: + for csp in sub: + for point in csp: + point[0] -= self.options.centerx + point[1] -= self.options.centery + dist = math.sqrt((point[0] ** 2) + (point[1] ** 2)) + if dist != 0: + a = rotation * dist * whirl + theta = math.atan2(point[1], point[0]) + a + point[0] = (dist * math.cos(theta)) + point[1] = (dist * math.sin(theta)) + point[0] += self.options.centerx + point[1] += self.options.centery + d.value = cubicsuperpath.formatPath(p) + +e = Whirl() +e.affect() diff --git a/share/extensions/wmf_input.inx b/share/extensions/wmf_input.inx new file mode 100644 index 000000000..99b234896 --- /dev/null +++ b/share/extensions/wmf_input.inx @@ -0,0 +1,14 @@ + + <_name>Windows Metafile Input + org.inkscape.input.wmf + wmf2svg + + .wmf + application/x-wmf + <_filetypename>Windows Metafile (*.wmf) + <_filetypetooltip>A popular graphics file format for clipart + + + diff --git a/share/fonts/.cvsignore b/share/fonts/.cvsignore new file mode 100644 index 000000000..282522db0 --- /dev/null +++ b/share/fonts/.cvsignore @@ -0,0 +1,2 @@ +Makefile +Makefile.in diff --git a/share/fonts/Makefile.am b/share/fonts/Makefile.am new file mode 100644 index 000000000..30a2f6997 --- /dev/null +++ b/share/fonts/Makefile.am @@ -0,0 +1,7 @@ + +fontsdir = $(datadir)/inkscape/fonts + +fonts_DATA = \ + README + +EXTRA_DIST = $(fonts_DATA) diff --git a/share/fonts/README b/share/fonts/README new file mode 100644 index 000000000..0dd74cf49 --- /dev/null +++ b/share/fonts/README @@ -0,0 +1,5 @@ +This new folder is part of the Inkscape 0.38 directory reorganization. Please place the appropriate files into this folder. + +Thank You! + +Inkscape Developers diff --git a/share/gradients/.cvsignore b/share/gradients/.cvsignore new file mode 100644 index 000000000..282522db0 --- /dev/null +++ b/share/gradients/.cvsignore @@ -0,0 +1,2 @@ +Makefile +Makefile.in diff --git a/share/gradients/Makefile.am b/share/gradients/Makefile.am new file mode 100644 index 000000000..9eadc5e57 --- /dev/null +++ b/share/gradients/Makefile.am @@ -0,0 +1,7 @@ + +gradientsdir = $(datadir)/inkscape/gradients + +gradients_DATA = \ + README + +EXTRA_DIST = $(gradients_DATA) diff --git a/share/gradients/README b/share/gradients/README new file mode 100644 index 000000000..0dd74cf49 --- /dev/null +++ b/share/gradients/README @@ -0,0 +1,5 @@ +This new folder is part of the Inkscape 0.38 directory reorganization. Please place the appropriate files into this folder. + +Thank You! + +Inkscape Developers diff --git a/share/icons/.cvsignore b/share/icons/.cvsignore new file mode 100644 index 000000000..fdbb9c778 --- /dev/null +++ b/share/icons/.cvsignore @@ -0,0 +1,3 @@ +Makefile +Makefile.in +.xvpics diff --git a/share/icons/David_icons.svg b/share/icons/David_icons.svg new file mode 100644 index 000000000..071e107e3 --- /dev/null +++ b/share/icons/David_icons.svg @@ -0,0 +1,13562 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Created with Inkscape +http://www.inkscape.org/ + image/svg+xml + + + + + Inkscape Developers + + + + + Inkscape Developers + + + Icon Sheet + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/share/icons/Makefile.am b/share/icons/Makefile.am new file mode 100644 index 000000000..52af7767c --- /dev/null +++ b/share/icons/Makefile.am @@ -0,0 +1,19 @@ + +iconsdir = $(datadir)/inkscape/icons + +pixmaps = + +icons_DATA = \ + $(pixmaps) \ + inkscape.svg \ + \ + icons.svg \ + crispy_icons.svg \ + David_icons.svg \ + \ + README.icon_themes \ + README.crispy_icons \ + README.David_icons + +EXTRA_DIST = $(icons_DATA) + diff --git a/share/icons/README b/share/icons/README new file mode 100644 index 000000000..0786db2ab --- /dev/null +++ b/share/icons/README @@ -0,0 +1,7 @@ +Wed Jan 19, 2005 + +All XPM and PNG icons have been replaced by SVG icons in icons.svg + +The only graphics that will be kept as XPMs will be the cursor +icons. (REJON: I"m actually in favor of trying to convert these to SVGs +as well.) These files are located in src/pixmaps. diff --git a/share/icons/README.David_icons b/share/icons/README.David_icons new file mode 100644 index 000000000..7071db5a6 --- /dev/null +++ b/share/icons/README.David_icons @@ -0,0 +1,3 @@ +This icon theme is the work of David Christian Berg. To use it, copy the file +"David_icons.svg" into Inkscape's icons folder which resides in your personal +folder and rename it to "icons.svg". \ No newline at end of file diff --git a/share/icons/README.crispy_icons b/share/icons/README.crispy_icons new file mode 100644 index 000000000..41e7f5e77 --- /dev/null +++ b/share/icons/README.crispy_icons @@ -0,0 +1,3 @@ +This icon theme is the work of Plácido Sousa. To use it, copy the file +"crispy_icons.svg" into Inkscape's icons folder which resides in your personal +folder and rename it to "icons.svg". \ No newline at end of file diff --git a/share/icons/README.icon_themes b/share/icons/README.icon_themes new file mode 100644 index 000000000..c18d4ba6b --- /dev/null +++ b/share/icons/README.icon_themes @@ -0,0 +1,29 @@ +CHANGING ICON THEMES +-------------------- +The Inkscape icons are read from the file 'icons.svg' that resides in the same +directory as this README. + +If you want to try a new theme, create a folder named 'icons' in your personal +Inkscape folder (under Linux/Unix: $HOME/.inkscape), copy the file containing +the alternative theme in that folder and rename it to icons.svg. The next time +Inkscape is run the alternative icons will be loaded. + + +CREATING A NEW ICON THEME +------------------------- +To create a new theme or simply modify some icons you need to make sure each +icon is assigned the correct ID (its name). Opening 'icons.svg' in Inkscape and +selecting an icon will display its ID in the XML editor (Shift+Ctrl+X). + +The simplest way to proceed is to work on a copy of the icons.svg file and +modify each icon one after the other, using the XML editor to adapt its ID. + +For example, if you've drawn a new pen icon, select it on the canvas, then open +the XML editor. The node corresponding to the pen icon will be highlighted. +Click on its ID in the upper right panel of the XML editor. The bottom right +panel will display something like 'g2570'. Change that value to 'draw_pen' and +click the 'Set' button. + + +For any questions relating to icon themes, please contact: +Jean-François Lemaire (jflemaire@skynet.be). \ No newline at end of file diff --git a/share/icons/crispy_icons.svg b/share/icons/crispy_icons.svg new file mode 100644 index 000000000..a13631324 --- /dev/null +++ b/share/icons/crispy_icons.svg @@ -0,0 +1,11734 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Created with Inkscape +http://www.inkscape.org/ + image/svg+xml + + + + + Inkscape Developers + + + + + Inkscape Developers + + + Icon Sheet + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + a + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/share/icons/icons.svg b/share/icons/icons.svg new file mode 100644 index 000000000..77eac9326 --- /dev/null +++ b/share/icons/icons.svg @@ -0,0 +1,8262 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Created with Inkscape +http://www.inkscape.org/ + image/svg+xml + + + + + Inkscape Developers + + + + + Inkscape Developers + + + Icon Sheet + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/share/icons/inkscape.svg b/share/icons/inkscape.svg new file mode 100644 index 000000000..d86867818 --- /dev/null +++ b/share/icons/inkscape.svg @@ -0,0 +1,204 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/share/keyboards/.cvsignore b/share/keyboards/.cvsignore new file mode 100644 index 000000000..282522db0 --- /dev/null +++ b/share/keyboards/.cvsignore @@ -0,0 +1,2 @@ +Makefile +Makefile.in diff --git a/share/keyboards/Makefile.am b/share/keyboards/Makefile.am new file mode 100644 index 000000000..bd4a760d1 --- /dev/null +++ b/share/keyboards/Makefile.am @@ -0,0 +1,7 @@ + +keyboardsdir = $(datadir)/inkscape/keyboards + +keyboards_DATA = \ + README + +EXTRA_DIST = $(keyboards_DATA) diff --git a/share/keyboards/README b/share/keyboards/README new file mode 100644 index 000000000..0dd74cf49 --- /dev/null +++ b/share/keyboards/README @@ -0,0 +1,5 @@ +This new folder is part of the Inkscape 0.38 directory reorganization. Please place the appropriate files into this folder. + +Thank You! + +Inkscape Developers diff --git a/share/markers/.cvsignore b/share/markers/.cvsignore new file mode 100644 index 000000000..fdbb9c778 --- /dev/null +++ b/share/markers/.cvsignore @@ -0,0 +1,3 @@ +Makefile +Makefile.in +.xvpics diff --git a/share/markers/Makefile.am b/share/markers/Makefile.am new file mode 100644 index 000000000..5db048146 --- /dev/null +++ b/share/markers/Makefile.am @@ -0,0 +1,9 @@ + +markersdir = $(datadir)/inkscape/markers + +markers_DATA = \ + markers.svg + + +EXTRA_DIST = $(markers_DATA) + diff --git a/share/markers/markers.svg b/share/markers/markers.svg new file mode 100644 index 000000000..96b9a89bf --- /dev/null +++ b/share/markers/markers.svg @@ -0,0 +1,615 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/share/palettes/.cvsignore b/share/palettes/.cvsignore new file mode 100644 index 000000000..282522db0 --- /dev/null +++ b/share/palettes/.cvsignore @@ -0,0 +1,2 @@ +Makefile +Makefile.in diff --git a/share/palettes/Makefile.am b/share/palettes/Makefile.am new file mode 100644 index 000000000..1b41be56e --- /dev/null +++ b/share/palettes/Makefile.am @@ -0,0 +1,11 @@ + +palettesdir = $(datadir)/inkscape/palettes + +palettes_DATA = \ + README \ + Tango-Palette.gpl \ + svg.gpl \ + webhex.gpl \ + websafe22.gpl + +EXTRA_DIST = $(palettes_DATA) diff --git a/share/palettes/README b/share/palettes/README new file mode 100644 index 000000000..8b04470b7 --- /dev/null +++ b/share/palettes/README @@ -0,0 +1,4 @@ +This is the directory with the Inkscape color palettes. +They are in Gimp format (.gpl). Within Inkscape, they +can be accessed by a drop-down menu in the Swatches +dialog (Ctrl+Shift+W). \ No newline at end of file diff --git a/share/palettes/Tango-Palette.gpl b/share/palettes/Tango-Palette.gpl new file mode 100644 index 000000000..e0345be71 --- /dev/null +++ b/share/palettes/Tango-Palette.gpl @@ -0,0 +1,31 @@ +GIMP Palette +Name: Tango Icon Theme Palette +Columns: 3 +# +252 233 79 Butter 1 +237 212 0 Butter 2 +196 160 0 Butter 3 +138 226 52 Chameleon 1 +115 210 22 Chameleon 2 + 78 154 6 Chameleon 3 +252 175 62 Orange 1 +245 121 0 Orange 2 +206 92 0 Orange 3 +114 159 207 Sky Blue 1 + 52 101 164 Sky Blue 2 + 32 74 135 Sky Blue 3 +173 127 168 Plum 1 +117 80 123 Plum 2 + 92 53 102 Plum 3 +233 185 110 Chocolate 1 +193 125 17 Chocolate 2 +143 89 2 Chocolate 3 +239 41 41 Scarlet Red 1 +204 0 0 Scarlet Red 2 +164 0 0 Scarlet Red 3 +238 238 236 Aluminium 1 +211 215 207 Aluminium 2 +186 189 182 Aluminium 3 +136 138 133 Aluminium 4 + 85 87 83 Aluminium 5 + 46 52 54 Aluminium 6 diff --git a/share/palettes/svg.gpl b/share/palettes/svg.gpl new file mode 100644 index 000000000..b0893cd82 --- /dev/null +++ b/share/palettes/svg.gpl @@ -0,0 +1,141 @@ +GIMP Palette +Name: SVG +# + 0 0 0 black (#000000) +105 105 105 dimgray (#696969) +128 128 128 gray (#808080) +169 169 169 darkgray (#A9A9A9) +192 192 192 silver (#C0C0C0) +211 211 211 lightgray (#D3D3D3) +220 220 220 gainsboro (#DCDCDC) +245 245 245 whitesmoke (#F5F5F5) +255 255 255 white (#FFFFFF) +188 143 143 rosybrown (#BC8F8F) +205 92 92 indianred (#CD5C5C) +165 42 42 brown (#A52A2A) +178 34 34 firebrick (#B22222) +240 128 128 lightcoral (#F08080) +128 0 0 maroon (#800000) +139 0 0 darkred (#8B0000) +255 0 0 red (#FF0000) +255 250 250 snow (#FFFAFA) +255 228 225 mistyrose (#FFE4E1) +250 128 114 salmon (#FA8072) +255 99 71 tomato (#FF6347) +233 150 122 darksalmon (#E9967A) +255 127 80 coral (#FF7F50) +255 69 0 orangered (#FF4500) +255 160 122 lightsalmon (#FFA07A) +160 82 45 sienna (#A0522D) +255 245 238 seashell (#FFF5EE) +210 105 30 chocolate (#D2691E) +139 69 19 saddlebrown (#8B4513) +244 164 96 sandybrown (#F4A460) +255 218 185 peachpuff (#FFDAB9) +205 133 63 peru (#CD853F) +250 240 230 linen (#FAF0E6) +255 228 196 bisque (#FFE4C4) +255 140 0 darkorange (#FF8C00) +222 184 135 burlywood (#DEB887) +210 180 140 tan (#D2B48C) +250 235 215 antiquewhite (#FAEBD7) +255 222 173 navajowhite (#FFDEAD) +255 235 205 blanchedalmond (#FFEBCD) +255 239 213 papayawhip (#FFEFD5) +255 228 181 moccasin (#FFE4B5) +255 165 0 orange (#FFA500) +245 222 179 wheat (#F5DEB3) +253 245 230 oldlace (#FDF5E6) +255 250 240 floralwhite (#FFFAF0) +184 134 11 darkgoldenrod (#B8860B) +218 165 32 goldenrod (#DAA520) +255 248 220 cornsilk (#FFF8DC) +255 215 0 gold (#FFD700) +240 230 140 khaki (#F0E68C) +255 250 205 lemonchiffon (#FFFACD) +238 232 170 palegoldenrod (#EEE8AA) +189 183 107 darkkhaki (#BDB76B) +245 245 220 beige (#F5F5DC) +250 250 210 lightgoldenrodyellow (#FAFAD2) +128 128 0 olive (#808000) +255 255 0 yellow (#FFFF00) +255 255 224 lightyellow (#FFFFE0) +255 255 240 ivory (#FFFFF0) +107 142 35 olivedrab (#6B8E23) +154 205 50 yellowgreen (#9ACD32) + 85 107 47 darkolivegreen (#556B2F) +173 255 47 greenyellow (#ADFF2F) +127 255 0 chartreuse (#7FFF00) +124 252 0 lawngreen (#7CFC00) +143 188 143 darkseagreen (#8FBC8F) + 34 139 34 forestgreen (#228B22) + 50 205 50 limegreen (#32CD32) +144 238 144 lightgreen (#90EE90) +152 251 152 palegreen (#98FB98) + 0 100 0 darkgreen (#006400) + 0 128 0 green (#008000) + 0 255 0 lime (#00FF00) +240 255 240 honeydew (#F0FFF0) + 46 139 87 seagreen (#2E8B57) + 60 179 113 mediumseagreen (#3CB371) + 0 255 127 springgreen (#00FF7F) +245 255 250 mintcream (#F5FFFA) + 0 250 154 mediumspringgreen (#00FA9A) +102 205 170 mediumaquamarine (#66CDAA) +127 255 212 aquamarine (#7FFFD4) + 64 224 208 turquoise (#40E0D0) + 32 178 170 lightseagreen (#20B2AA) + 72 209 204 mediumturquoise (#48D1CC) + 47 79 79 darkslategray (#2F4F4F) +175 238 238 paleturquoise (#AFEEEE) + 0 128 128 teal (#008080) + 0 139 139 darkcyan (#008B8B) + 0 255 255 cyan (#00FFFF) +224 255 255 lightcyan (#E0FFFF) +240 255 255 azure (#F0FFFF) + 0 206 209 darkturquoise (#00CED1) + 95 158 160 cadetblue (#5F9EA0) +176 224 230 powderblue (#B0E0E6) +173 216 230 lightblue (#ADD8E6) + 0 191 255 deepskyblue (#00BFFF) +135 206 235 skyblue (#87CEEB) +135 206 250 lightskyblue (#87CEFA) + 70 130 180 steelblue (#4682B4) +240 248 255 aliceblue (#F0F8FF) + 30 144 255 dodgerblue (#1E90FF) +112 128 144 slategray (#708090) +119 136 153 lightslategray (#778899) +176 196 222 lightsteelblue (#B0C4DE) +100 149 237 cornflowerblue (#6495ED) + 65 105 225 royalblue (#4169E1) + 25 25 112 midnightblue (#191970) +230 230 250 lavender (#E6E6FA) + 0 0 128 navy (#000080) + 0 0 139 darkblue (#00008B) + 0 0 205 mediumblue (#0000CD) + 0 0 255 blue (#0000FF) +248 248 255 ghostwhite (#F8F8FF) +106 90 205 slateblue (#6A5ACD) + 72 61 139 darkslateblue (#483D8B) +123 104 238 mediumslateblue (#7B68EE) +147 112 219 mediumpurple (#9370DB) +138 43 226 blueviolet (#8A2BE2) + 75 0 130 indigo (#4B0082) +153 50 204 darkorchid (#9932CC) +148 0 211 darkviolet (#9400D3) +186 85 211 mediumorchid (#BA55D3) +216 191 216 thistle (#D8BFD8) +221 160 221 plum (#DDA0DD) +238 130 238 violet (#EE82EE) +128 0 128 purple (#800080) +139 0 139 darkmagenta (#8B008B) +255 0 255 magenta (#FF00FF) +218 112 214 orchid (#DA70D6) +199 21 133 mediumvioletred (#C71585) +255 20 147 deeppink (#FF1493) +255 105 180 hotpink (#FF69B4) +255 240 245 lavenderblush (#FFF0F5) +219 112 147 palevioletred (#DB7093) +220 20 60 crimson (#DC143C) +255 192 203 pink (#FFC0CB) +255 182 193 lightpink (#FFB6C1) diff --git a/share/palettes/webhex.gpl b/share/palettes/webhex.gpl new file mode 100644 index 000000000..1fc6e32ef --- /dev/null +++ b/share/palettes/webhex.gpl @@ -0,0 +1,219 @@ +GIMP Palette +Name: WebHex +# +255 255 255 FFFFFF +255 255 204 FFFFCC +255 255 153 FFFF99 +255 255 102 FFFF66 +255 255 51 FFFF33 +255 255 0 FFFF00 +255 204 255 FFCCFF +255 204 204 FFCCCC +255 204 153 FFCC99 +255 204 102 FFCC66 +255 204 51 FFCC33 +255 204 0 FFCC00 +255 153 255 FF99FF +255 153 204 FF99CC +255 153 153 FF9999 +255 153 102 FF9966 +255 153 51 FF9933 +255 153 0 FF9900 +255 102 255 FF66FF +255 102 204 FF66CC +255 102 153 FF6699 +255 102 102 FF6666 +255 102 51 FF6633 +255 102 0 FF6600 +255 51 255 FF33FF +255 51 204 FF33CC +255 51 153 FF3399 +255 51 102 FF3366 +255 51 51 FF3333 +255 51 0 FF3300 +255 0 255 FF00FF +255 0 204 FF00CC +255 0 153 FF0099 +255 0 102 FF0066 +255 0 51 FF0033 +255 0 0 FF0000 +204 255 255 CCFFFF +204 255 204 CCFFCC +204 255 153 CCFF99 +204 255 102 CCFF66 +204 255 51 CCFF33 +204 255 0 CCFF00 +204 204 255 CCCCFF +204 204 204 CCCCCC +204 204 153 CCCC99 +204 204 102 CCCC66 +204 204 51 CCCC33 +204 204 0 CCCC00 +204 153 255 CC99FF +204 153 204 CC99CC +204 153 153 CC9999 +204 153 102 CC9966 +204 153 51 CC9933 +204 153 0 CC9900 +204 102 255 CC66FF +204 102 204 CC66CC +204 102 153 CC6699 +204 102 102 CC6666 +204 102 51 CC6633 +204 102 0 CC6600 +204 51 255 CC33FF +204 51 204 CC33CC +204 51 153 CC3399 +204 51 102 CC3366 +204 51 51 CC3333 +204 51 0 CC3300 +204 0 255 CC00FF +204 0 204 CC00CC +204 0 153 CC0099 +204 0 102 CC0066 +204 0 51 CC0033 +204 0 0 CC0000 +153 255 255 99FFFF +153 255 204 99FFCC +153 255 153 99FF99 +153 255 102 99FF66 +153 255 51 99FF33 +153 255 0 99FF00 +153 204 255 99CCFF +153 204 204 99CCCC +153 204 153 99CC99 +153 204 102 99CC66 +153 204 51 99CC33 +153 204 0 99CC00 +153 153 255 9999FF +153 153 204 9999CC +153 153 153 999999 +153 153 102 999966 +153 153 51 999933 +153 153 0 999900 +153 102 255 9966FF +153 102 204 9966CC +153 102 153 996699 +153 102 102 996666 +153 102 51 996633 +153 102 0 996600 +153 51 255 9933FF +153 51 204 9933CC +153 51 153 993399 +153 51 102 993366 +153 51 51 993333 +153 51 0 993300 +153 0 255 9900FF +153 0 204 9900CC +153 0 153 990099 +153 0 102 990066 +153 0 51 990033 +153 0 0 990000 +102 255 255 66FFFF +102 255 204 66FFCC +102 255 153 66FF99 +102 255 102 66FF66 +102 255 51 66FF33 +102 255 0 66FF00 +102 204 255 66CCFF +102 204 204 66CCCC +102 204 153 66CC99 +102 204 102 66CC66 +102 204 51 66CC33 +102 204 0 66CC00 +102 153 255 6699FF +102 153 204 6699CC +102 153 153 669999 +102 153 102 669966 +102 153 51 669933 +102 153 0 669900 +102 102 255 6666FF +102 102 204 6666CC +102 102 153 666699 +102 102 102 666666 +102 102 51 666633 +102 102 0 666600 +102 51 255 6633FF +102 51 204 6633CC +102 51 153 663399 +102 51 102 663366 +102 51 51 663333 +102 51 0 663300 +102 0 255 6600FF +102 0 204 6600CC +102 0 153 660099 +102 0 102 660066 +102 0 51 660033 +102 0 0 660000 + 51 255 255 33FFFF + 51 255 204 33FFCC + 51 255 153 33FF99 + 51 255 102 33FF66 + 51 255 51 33FF33 + 51 255 0 33FF00 + 51 204 255 33CCFF + 51 204 204 33CCCC + 51 204 153 33CC99 + 51 204 102 33CC66 + 51 204 51 33CC33 + 51 204 0 33CC00 + 51 153 255 3399FF + 51 153 204 3399CC + 51 153 153 339999 + 51 153 102 339966 + 51 153 51 339933 + 51 153 0 339900 + 51 102 255 3366FF + 51 102 204 3366CC + 51 102 153 336699 + 51 102 102 336666 + 51 102 51 336633 + 51 102 0 336600 + 51 51 255 3333FF + 51 51 204 3333CC + 51 51 153 333399 + 51 51 102 333366 + 51 51 51 333333 + 51 51 0 333300 + 51 0 255 3300FF + 51 0 204 3300CC + 51 0 153 330099 + 51 0 102 330066 + 51 0 51 330033 + 51 0 0 330000 + 0 255 255 00FFFF + 0 255 204 00FFCC + 0 255 153 00FF99 + 0 255 102 00FF66 + 0 255 51 00FF33 + 0 255 0 00FF00 + 0 204 255 00CCFF + 0 204 204 00CCCC + 0 204 153 00CC99 + 0 204 102 00CC66 + 0 204 51 00CC33 + 0 204 0 00CC00 + 0 153 255 0099FF + 0 153 204 0099CC + 0 153 153 009999 + 0 153 102 009966 + 0 153 51 009933 + 0 153 0 009900 + 0 102 255 0066FF + 0 102 204 0066CC + 0 102 153 006699 + 0 102 102 006666 + 0 102 51 006633 + 0 102 0 006600 + 0 51 255 0033FF + 0 51 204 0033CC + 0 51 153 003399 + 0 51 102 003366 + 0 51 51 003333 + 0 51 0 003300 + 0 0 255 0000FF + 0 0 204 0000CC + 0 0 153 000099 + 0 0 102 000066 + 0 0 51 000033 + 0 0 0 000000 diff --git a/share/palettes/websafe22.gpl b/share/palettes/websafe22.gpl new file mode 100644 index 000000000..12d5d4c55 --- /dev/null +++ b/share/palettes/websafe22.gpl @@ -0,0 +1,25 @@ +GIMP Palette +Name: WebSafe22 +# +255 255 255 FFFFFF +255 255 102 FFFF66 +255 255 51 FFFF33 +255 255 0 FFFF00 +204 255 102 CCFF66 +102 255 255 66FFFF +102 255 51 66FF33 +102 255 0 66FF00 + 51 255 255 33FFFF + 51 255 204 33FFCC + 51 255 102 33FF66 + 51 255 51 33FF33 + 0 255 255 00FFFF + 0 255 204 00FFCC + 0 255 102 00FF66 + 0 255 0 00FF00 +255 0 255 FF00FF +255 0 51 FF0033 +255 0 0 FF0000 + 0 0 255 0000FF + 0 0 51 000033 + 0 0 0 000000 diff --git a/share/patterns/.cvsignore b/share/patterns/.cvsignore new file mode 100644 index 000000000..282522db0 --- /dev/null +++ b/share/patterns/.cvsignore @@ -0,0 +1,2 @@ +Makefile +Makefile.in diff --git a/share/patterns/Makefile.am b/share/patterns/Makefile.am new file mode 100644 index 000000000..88007a394 --- /dev/null +++ b/share/patterns/Makefile.am @@ -0,0 +1,7 @@ + +patternsdir = $(datadir)/inkscape/patterns + +patterns_DATA = \ + README + +EXTRA_DIST = $(patterns_DATA) diff --git a/share/patterns/README b/share/patterns/README new file mode 100644 index 000000000..0dd74cf49 --- /dev/null +++ b/share/patterns/README @@ -0,0 +1,5 @@ +This new folder is part of the Inkscape 0.38 directory reorganization. Please place the appropriate files into this folder. + +Thank You! + +Inkscape Developers diff --git a/share/screens/.cvsignore b/share/screens/.cvsignore new file mode 100644 index 000000000..3dda72986 --- /dev/null +++ b/share/screens/.cvsignore @@ -0,0 +1,2 @@ +Makefile.in +Makefile diff --git a/share/screens/Makefile.am b/share/screens/Makefile.am new file mode 100644 index 000000000..b017bbc10 --- /dev/null +++ b/share/screens/Makefile.am @@ -0,0 +1,12 @@ + +screensdir = $(datadir)/inkscape/screens + +screens_DATA = \ + about.svg \ + keys.svg \ + keys.sl.svg \ + keys.fr.svg + + +EXTRA_DIST = $(screens_DATA) + diff --git a/share/screens/README b/share/screens/README new file mode 100644 index 000000000..ad5b9a874 --- /dev/null +++ b/share/screens/README @@ -0,0 +1,4 @@ +This directory contains miscellaneous SVG files that are part of +Inkscape UI: the About screen (new for each version) as well as the +Keys and Mouse reference sheet (generated from docs/keys.xml) +and its translations. \ No newline at end of file diff --git a/share/screens/about.svg b/share/screens/about.svg new file mode 100644 index 000000000..7eaecec33 --- /dev/null +++ b/share/screens/about.svg @@ -0,0 +1,409 @@ + + + + + + + + + image/svg+xml + + Inkscape.42 About Screen 1 + Primavera do 2005 + + + Denís Fernández Cabrera (Gatonegro, Anarres) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + THIS excellent + Vector Graphics Application is recommended for the generation of Scalable Vector Graphics for use on the World-Wide Web, for Print, Games, Desktop Icons, and all other sundry purposes to which Scalable Vector Graphics are best suited. Based upon the inimitable Extensible Markup Language, for graphical purposes demanding Programmatic Modification and Dynamic Content Generation ; and where Scripting and Interactivity via the celebrated Document Object Model are required, nothing can be better adapted. + + PERSONS + EMPLOYING + BITMAPPED + GRAPHICS +, which are subject to Aliasing, Blurring, Large File Size, and Difficulty of Correction or Subsequent Modification, arising from a lack of structure, should all promptly investigate the considerable benefits of Vector Graphics today. + + Available in most fine Linux Distributions, or obtained direct through our Web Site for Windows or Mac OS X at 8 b. per byte: http://www.inkscape.org + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/share/screens/keys.fr.svg b/share/screens/keys.fr.svg new file mode 100644 index 000000000..db608140f --- /dev/null +++ b/share/screens/keys.fr.svg @@ -0,0 +1,844 @@ + + +clickdragclickdragclickdragwheelShiftCtrlAltLeftRightarrowsupdownleftrightOutils + + +F1,ssélecteur +Espacesélecteur (temporaire) +Espace bascule temporairement vers le sélecteur. Espace de nouveau rebascule vers l'outil précédent. +F2,nnœud +F3,zzoom +F4,rrectangle +F5,eellipse/arc +F6,pcrayon (main levée) +F6,bstylo (Bézier) +F6plume calligraphique +F7,dpipette +F8,ttexte +F9,ispirale +F9,*étoile +Un double clic sur le bouton d'un outil ouvre la boîte de dialogue des préférences à l'onglet de l'outil correspondant. + + +Fichier + + +Ncréer un nouveau document +Oouvrir un document SVG +Eexporter en PNG +Iimporter un bitmap ou SVG +Pimprimer le document +Ssauver le document +Ssauver sous un autre nom +Qquitter Inkscape + + +Fenêtre + + +R(dés)afficher les règles +B(dés)afficher les barres de défilement +F11(dés)afficher en plein écran + + + +F10menu principal +Les menus peuvent aussi être activés en appuyant simultanément sur Alt et la lettre soulignée dans le nom du menu. +F10,menu contextuel + + + +F4,Wfermer la fenêtre (document) +Quitte Inkscape si la fenêtre courante est le seul document ouvert. +Tabfenêtre (document) suivante +Tabfenêtre (document) précédente +Permet de circuler entre les fenêtres (documents) en avant ou en arrière. + + +Dialogues + +FRemplissage et contour +TTexte et police +MTransformer +AAligner et distribuer +OPropriétés de l'objet +XEditeur XML +DPréférences du document +PPréférences d'Inkscape +EExporter en PNG +FRechercher +BVectoriser un bitmap +Ces raccourcis ouvrent si nécessaire une nouvelle boîte de dialogue, sinon réactivent la boîte correspondante. + + + +(dés)Afficher +F12(dés)afficher les boîtes de dialogue +Masque temporairement les boîtes de dialogue ouvertes. Un appui de plus sur F12 les rend de nouveau visibles. + + + +Dans une boîte de dialogue +Escretourner au canevas +F4,Wfermer le dialogue +Tabpasser au champ suivant +Tabpasser au champ précédent +Entréevalider la nouvelle valeur +Valide la nouvelle valeur entrée dans un champ et retourne au canevas. +Entréedéfinir la valeur d'un attribut (éditeur XML) +Valide la nouvelle valeur d'un attribut dans l'éditeur XML (comme cliquer sur le bouton "Définir l'attribut". +Espace,Entréeactiver le bouton ou la valeur d'une liste. +Préc.,Suiv.naviguer parmi les onglets d'un dialogue + +Contrôle + + +La barre de contrôle en haut de la fenêtre document affiche des champs et des contrôles pour chacun des outils. +Xaller au premier champ +Entréevalider la nouvelle valeur +Valide la nouvelle valeur entrée dans un champ et retourne au canevas. +Escannuler les modifications, retourner au canevas +Annule la modification d'un champ et retourne au canevas. +Zannuler les modifications +Annule la modification d'un champ mais reste dans ce champ. +Tabpasser au champ suivant +Tabpasser au champ précédent +Permet de naviguer entre les différents champs de la barre de contrôle (les modifications du champs quitté sont validées). + + + +Modification des valeurs +,modifier la valeur de 0.1 +Préc.,Suiv.modifier la valeur de 5.0 + + +Canevas + + +Zoom +=,+zoommer +-dézoommer +Les touches +/- du pavé numérique permettent de zoommer même pendant l'édition d'un objet texte. +,zoommer +,dézoommer +(dé)zoommer +Zactiver le champ de zoom +Le champ zoom dans le coin inférieur gauche de la fenêtre vous permet de spécifier précisément la valeur de zoom. + + + +Zooms prédéfinis +1zoommer à 1:1 +2zoommer à 1:2 +3zoommer sur la sélection +4zoommmer sur le dessin +5zoommer sur la page +E,6zoommer sur la largeur de page + + + +Historique du zoom +`(guillement inversé) zoom précédent +`zoom suivant +Ces raccourcis permettent de naviguer parmi les différents niveaux de zoom utilisés pendant la session. + + + +Défilement +faire défiler le canevas +Ces raccourcis peuvent être accélérés, par une répétition rapide ou un appui continu +faire défiler le canevas +,faire défiler le canevas +faire défiler le canevas verticalement +faire défiler le canevas horizontalement + + + +Guides et grille +créer un guide en le tirant depuis une règle +Cliquer-déplacer d'une règle vers le canevas pour créer un nouveau guide. Déplacer un guide vers la règle pour le supprimer. +|,\(dés)activer affichage et collage des guides +Pour des valeurs différentes d'affichage/collage des guides, les régler dans les Préférences du document. +Lors de sa création par cliquer-déplacer depuis une règle, l'affichage et le collage des guides sont activés. +#,3(dés)activer affichage et collage de la grille +Pour des valeurs différentes d'affichage/collage de la grille, les régler dans les Préférences du document. +Notez que seule la touche 3 du clavier principal a une action, pas celle du pavé numérique. + +Calques + +Préc.déplacer au calque supérieur +Suiv.déplacer au calque inférieur +Ces commandes déplacent les objets sélectionnés d'un calque à un autre. + +Préc.monter le calque +Suiv.descendre le calque +Débutmonter le calque au premier plan +Findescendre le calque à l'arrière plan +Ces commandes déplacent le calque courant parmi sa hiérarchie (normalement d'autres calques) + +Objet + + +Annuler/refaire +Y,Zannuler +Z,Yrefaire + + + +Presse-papiers +Ccopier la sélection +Copie la sélection dans le presse-papiers Inkscape (et aussi dans le presse-papiers système pour les textes). +Xcouper la sélection +Fonctionne comme un "copier la sélection" suivi de la suppression de la sélection. +Vcoller le presse-papiers +Ceci place les objets du presse-papier sous la souris, ou au centre de la fenêtre si la souris est hors du canevas. +Lors de l'édition d'un texte avec l'outil texte, colle le texte du presse-papiers système dans l'objet texte courant. +Vcoller sur place +Ceci place les objets du presse-papiers au même emplacement que lors de leur copie. +Vcoller le style +Ceci applique le style du premier des objet copiés à la sélection courante. + + + +Dupliquer +Ddupliquer la sélection +Les nouveaux objet(s) sont placés exactement au même endroit, au dessus des originaux et sont sélectionnés. + + + +Cloner +Dcloner l'objet +Un clone peut être déplacé/redimensionné/tourné/incliné indépendament, mais reçoit ses tracé/remplissage/contour de l'original. +Le clone est placé exactement au même endroit, au dessus de l'original et est sélectionné. +Vous ne pouvez cloner qu'un objet à la fois; si vous voulez cloner plusieurs objets ensemble, groupez-les puis clonez le groupe. +Ddélier le clone +Délier un clone supprime le lien vers son original, le clone devenant alors une simple copie. +Dsélectionner l'original +Après sélection d'un clone, cette commande sélectionne l'objet original dont le clone est issu. + + + +Bitmaps +Bcréer une copie bitmap +Exporte en PNG les objet(s) sélectionnés (les autres objets étant masqués) dans le répertoire du document et réimporte ce PNG. +Le bitmap (PNG) importé est placé exactement au même endroit, au dessus de la sélection originale, et est sélectionné. +Bvectoriser le bitmap +Ceci ouvre la boîte de dialogue vectoriser un bitmap, vous permettant de convertir une image bitmap en chemin. + + + +Motif +Iobjet en motif +Ceci convertit la sélection en un rectangle rempli avec la sélection comme motif de remplissage. +Imotif en objet +Sépare tout objet sélectionné rempli avec un motif en deux objets : ce même objet sans remplissage et le motif seul. + + + +Grouper +U,Ggrouper les objets sélectionnés +Ctrl+cliquer permet de sélectionner des objets au sein d'un groupe. +G,Udégrouper les groupe(s) sélectionnés +Retire un niveau de regroupement; répéter plusieurs fois Ctrl+U permet de dégrouper des groupes imbriqués. + + + +Ordre-Z (superposition) +Débutmonter la sélection au premier plan +Findescendre la sélection à l'arrière plan +Préc.monter la sélection d'un cran +Suiv.descendre la sélection d'un cran + + +Chemin + + +Convertir en chemin +Cconvertir les objet(s) sélectionnés en chemin +Cconvertir les contour(s) sélectionnés en chemin + + + +Booléens ++union +L'union combine plusieurs objets en un seul chemin, fusionnant les recouvrements. +-différence +La différence s'applique à deux objets, extrayant celui du dessus de celui du dessous. +*intersection +L'intersection crée un chemin représentant l'intersection des objets sélectionnés. +^exclusion (ou exclusif) +L'exclusion est similaire à l'union, mais ne s'applique qu'à deux objets et supprime les recouvrements. +/division (coupe) +La division découpe l'objet du dessous en morceaux selon l'objet du dessus, et préserve ses remplissage et contour. +/découpe des chemins +Découper en chemin découpe le contour de l'objet du dessous aux points d'intersection avec celui du dessus. + Le résultat est sans remplissage. +Le résultat d'une union/différence/intersection/exclusion hérite de l'attribut id (et donc des clones) de l'objet du dessous. +Les division et découpe en chemin peuvent produire plusieurs objets. L'un d'eux, au hasard, hérite de l'id de l'objet du dessous. + + + +Offsets +(éroder le chemin +)dilater le chemin +La distance d'offset par défaut est de 2 px (en pixels SVG, pas en pixels à l'écran). +(éroder le chemin d'1 pixel +)dilater le chemin d'1 pixel +(éroder le chemin de 10 pixels +)dilater le chemin de 10 pixels +Le déplacement réel des pixels dépend du niveau de zoom. Zommer pour ajuster plus finement. +Toutes les commandes (, ) convertissent l'objet en chemin si nécessaire, et produisent un chemin normal. +Jcréer un offset dynamique +Jcréer un offset lié +Ces commandes produisent un objet offset (autonome ou lié à l'original) que l'on peut éditer avec l'outil nœud. + +Dsélectionner l'objet source +Après sélection d'un offset lié, cette commande sélectionne l'objet original dont il est issu. + + + +Combiner +Kcombiner les chemins +Cette commande est différente de grouper : des chemins combinés créent un objet, pas un groupe. +Différente aussi d'une union : les recouvrements ne sont pas affectés.. +Le remplissage des recouvrements est géré par le champ remplissage (complet/alternatif) du dialogue Remplissage et contour. +Kséparer les chemins +Sépare les sous-chemins d'un chemin composé; ceci échouera si l'objet est constitué d'un seul chemin. + + + +Simplifier +Lsimplifier +Simplifie les chemin(s) sélectionnés en supprimant quelques nœuds. Si nécessaire, les objets sont convertis en chemins. +En invoquant cette commande plusieurs fois de suite rapidement, elle agira de plus en plus agressivement. +Le seuil par défaut (réglable dans les préférences d'Inkscape) est restauré après une pause. + + +Sélecteur + + +Sélection au clavier +Tabsélectionner l'objet suivant +Tabsélectionner l'objet précédent +Sélectionne les objets selon leur ordre-z (Tab circule de l'arrière au premier plan, Maj+Tab fait l'inverse). +A moins d'avoir fait des réarrangements manuels, le dernier objet créé est au tout premier plan +Aussi, si rien n'est sélectionné, Maj+Tab est une façon pratique de sélectionner le dernier objet créé. +Cette commande s'applique aux objets du calque courant (sauf modification des préférences). +Atout sélectionner (calque courant) +Cette commande s'applique aux objets du calque courant (sauf modification des préférences). +Atout sélectionner (tous les calques) +Cette commande s'applique aux objets de tout calque visible et déverrouillé. +!inverser la sélection (calque courant) +Inverse la sélection (désélectionne ce qui était sélectionné, et sélectionne tout le reste) du calque courant. +!inverser la sélection (tous les calques) +Inverse la sélection dans tout calque visible et déverrouillé. +Escdésélectionner +Backspace,Suppr.supprimer la sélection + + + +Déplacement au clavier +déplacer la sélection par incrément(s) +déplacer la sélection de 10x l'incrément +L'incrément de déplacement par défaut est 1mm. +déplacer la sélection d'1 pixel +déplacer la sélection de 10 pixels +Le déplacement réel à l'échelle du pixel dépend du niveau de zoom. Zommer pour déplacer plus finement. + + + +Rotation au clavier +[,]tourner la sélection par incrément(s) +L'incrément de rotation par défaut est 15°. ] tourne en sens horaire, [ en sens anti-horaire. +[,]tourner la sélection de 90 degrés +[,]tourner la sélection d'1 pixel +La rotation réelle à l'échelle du pixel dépend du niveau de zoom. Zommer pour tourner plus finement. + + + +Redimensionnement au clavier +.,>agrandir la sélection par incrément(s) +,,<rétrécir la sélection par incrément(s) +L'incrément de redimensionnement par défaut est de 2 px (en pixels SVG, pas en pixels à l'écran). +.,>agrandir la sélection à 200% +,,<rétrécir la sélection à 50% +.,>agrandir la sélection d'1 pixel +,,<rétrécir la sélection d'1 pixel +Le redimensionnement réel à l'échelle du pixel dépend du niveau de zoom. Zommer pour dimensionner plus finement. +Le redimensionnement est uniforme autour du centre : il est donc appliqué à la plus grande des deux dimensions. + + + +Retournement au clavier +hretourner la sélection horizontalement +vretourner la sélection verticalement + + + +Sélection à la souris +sélectionner un objet +En cliquant (bouton gauche) sur un objet, la sélection précédente est desélectionnée. +alterner la sélection +Maj+cliquer ajoute un objet à la sélection courante s'il n'était pas sélectionné, le retire sinon. + + + +Sélection dans un groupe, en-dessous +sélectionner dans un groupe +Sélectionne l'objet sous le curseur, quel que soit le groupe auquel cet objet peut appartenir. +alterner la sélection (dans un groupe) +sélectionner en-dessous +Sélectionne l'objet (sous le curseur) juste en dessous (dans l'ordre-z) l'objet sélectionné le plus bas. +Si l'objet le plus en bas atteint, un Alt+Cliquer de plus sélectionne l'objet au premier plan, circulant ainsi dans l'ordre-z. +Sous Linux, Alt+cliquer et Alt+cliquer-déplacer peuvent être préemptés par le gestionnaire de fenêtre. +Reconfigurez celui-ci afin de pouvoir utiliser ces raccourcis dans Inkscape. +alterner en-dessous +sélectionner en-dessous, dans des groupes +alterner en-dessous, dans des groupes + + + +Bande étirable +sélectionner plusieurs objets +Cliquer-déplacer autour d'objets les sélectionne par bande étirable; la sélection précédente est désélectionnée. +ajouter des objets à la sélection +Normalement, vous devez commencer une bande étirable sur une zone vide. +Mais, en appuyant sur Maj avant, Inkscape effectuera une zone étirable, même si elle commence sur un objet. + + + +Déplacement à la souris +sélectionner + déplacer +Cliquer-déplacer sur un objet le sélectionne s'il n'était pas sélectionné, puis déplace la sélection. +déplacer la sélection +Déplace la sélection courante (sans sélectionner ce qui est sous le curseur), quel que soit le point de départ. +Sous Linux, Alt+cliquer et Alt+cliquer-déplacer peuvent être utilisés par le gestionnaire de fenêtre. +Reconfigurez celui-ci afin de pouvoir utiliser ces raccourcis dans Inkscape. + +restreindre à un mouvement vertical/horizontal +désactiver temporairement le collage +Désactive temporairement le collage à la grille ou aux guides lors de déplacements (grille/guides étant actifs). +Espacetamponner une copie +Lors de déplacements/transformations à la souris, un appui sur la barre d'espace dépose une copie de l'objet sélectionné. +Vous pouvez maintenir la barre d'espace appuyée lors d'un déplacement pour obtenir une belle "trainée". + + + +Transformation à la souris +alterner poignées arrondi/redimensionnement +redimensionner +S'applique aux poignées de redimensionnement. +tourner ou incliner +S'applique aux poignées de rotation/inclinaison. + + + +Poignées de redimensionnement +redimensionner en préservant le ratio + +transformation symétrique +Appuyer sur Maj pendant une transformation rend cette transformation symétrique autour du centre de la sélection. + +mouvement lent +Force un ralentissement des mouvements de la souris, permettant ainsi des modifications plus fines. + + + +Poignées de rotation +incliner et étirer +Appuyer sur Ctrl tout en déplaçant une poignée d'inclinaison (pas un coin) permet d'étirer tout en inclinant. +tourner la sélection par incrément(s) +L'incrément de rotation par défaut est 15 degrés. + + + +Annuler +Escannuler bande étirable/déplacer/transformer +Un appui sur Esc (le bouton de la souris étant encore pressé) annule la bande étirable, le déplacement ou la transformation. + + +Main levée + +dessiner une ligne à main levée +désactiver temporairement le collage +Désactive temporairement le collage à la grille ou aux guides lors de déplacements (grille/guides étant actifs). +aalterner créer/prolonger +Alterne entre créer une nouvelle ligne et prolonger la ligne sélectionnée (des ancres sont affichées en mode prolonger). + +Bézier + + +Créer des nœuds +créer un nœud anguleux +créer un nœud de Bézier avec 2 poignées +ne déplacer qu'une poignée + +Ceci ne déplace qu'une poignée (au lieu des deux), pour créer un nœud dur. +tourner la poignée par incrément(s) +L'incrément de rotation par défaut est 15 degrés. + + + +Créer des segments +tourner le segment par incrément(s) + +Ceci force la rotation d'un nœud (nouvel angle relativement au nœud précédent) par incrément(s) (15 degrés par défaut) . + + + +Terminer +Entréeterminer le tracé courant +terminer le tracé courant +terminer le tracé courant +Entrée, clic-droit ou double-clic terminent la ligne courante, annulant le dernier segment non fini (en rouge). + + + +Clavier +Escannuler le tracé courant +Backspaceeffacer le dernier segment du tracé courant +aalterner créer/prolonger +Alterne entre créer une nouvelle ligne et prolonger la ligne sélectionnée (des ancres sont affichées en mode prolonger). + +Calligraphie + +traver une ligne calligraphique +,ajuster la largeur de la plume +,aduster l'angle de la plume +La largeur et l'angle de la plume peuvent être ajustés tout en dessinant. + +Nœud + + +Sélection au clavier +Tabsélectionner le nœud suivant +Tabsélectionner le nœud précédent +Ces raccourcis vous permettent de sélectionner n'importe quel nœud du chemin sélectionné. +Asélectionner tous les nœuds du chemin +Escdésélectionner tous les nœuds + + + +Déplacement au clavier +déplacer les nœuds sélect. par incrément(s) +déplacer les nœuds sélect. de 10x l'incrément +L'incrément de déplacement par défaut est 1mm. +déplacer les nœuds sélectionnés d'1 pixel +déplacer les nœuds sélectionnés de 10 pixels +Le déplacement réel à l'échelle du pixel dépend du niveau de zoom. Zommer pour déplacer plus finement. + + + +Rotation des poignées au clavier +[,]tourner les deux poignées par incrément(s) +L'incrément de rotation par défaut est 15 degrés. ] tourne en sens horaire, [ en sens anti-horaire. Applicable à plusieurs nœuds. +[,]tourner la poignée gauche par incrément(s) +[,]tourner la poignée droite par incrément(s) +[,]tourner la poignée gauche d'1 pixel +[,]tourner la poignée droite d'1 pixel + + + +Redim. des poignées au clavier +<,>redim. les deux poignées par incrément(s) +L'incrément de redimensionnement par défaut est de 2 px (en pixels SVG, pas en pixels à l'écran). Applicable à plusieurs nœuds. +<,>redim. la poignée gauche par incrément(s) +<,>redim. la poignée droite par incrément(s) +<,>redimensionner la poignée gauche d'1 pixel +<,>redimensionner la poignée droite d'1 pixel +Le redimensionnement réel à l'échelle du pixel dépend du niveau de zoom. Zommer pour dimensionner plus finement. +A la place des touches < et >, vous pouvez utiliser respectivement , (virgule) et . (point). + + + +Modifier le type de segment +Lrendre rectiligne +Krendre courbe +Ces commandes exigent que plus de deux nœuds adjacents soient sélectionnés. + + + +Modifier le type de nœud +Crendre dur +Srendre doux +Yrendre symétrique +alterner doux/dur/symétrique + + + +Joindre/briser +Jjoindre les nœuds sélectionnés +Egige que deux (et seulement deux) nœuds terminaux du chemin soient sélectionnés. +Bbriser les nœud(s) sélectionnés +Après brisure, un seul des deux nœuds est sélectionné. Applicable à plus d'un nœud à la fois. + + + +Supprimer, créer, dupliquer +Backspace,Suppr.supprimer les nœud(s) sélectionnés +supprimer le nœud +Ins.insérer des nouveaux nœuds +Ajoute de nouveaux nœud(s) au milieu des segment(s) sélectionnés, et exige la sélection de plus de deux nœuds adjacents. +Ddupliquer les nœud(s) sélectionnés +Les nouveaux nœuds sont créés sur le même chemin; ils sont placés au-dessus des précédents et sont sélectionnés. + + + +Nœud actif +Le nœud actif est celui sous la souris ou en train d'être déplacé. +Lorsque qu'un nœud est actif, certains raccourcis peuvent ne pas fonctionner; +déplacez votre souris de façon à ce qu'il n'y aie pas de nœud actif si vous voulez les utiliser. +crendre le nœud actif dur +srendre le nœud actif doux +yrendre le nœud actif symétrique +bbriser le nœud actif +Backspacesupprimer le nœud actif + + + +Sélection à la souris +sélectionner un objet +Cliquer sur un objet pour le sélectionner. +Les nœuds/poignées de l'objet sélectionné deviennent éditables (vous évitant d'avoir à basculer vers l'outil sélecteur). +sélectionner un nœud +Cliquer sur un nœud pour le sélectionner. +alterner la sélection d'un nœud +désélectionner +Cliquer sur une zone vide désélectionne tous les nœuds sélectionnés. + + + +Bande étirable +sélectionner plusieurs nœuds +Cliquer-déplacer autour de nœuds les sélectionne par bande étirable; la sélection précédente est désélectionnée. +ajouter des nœuds à la sélection + + + +Déplacement à la souris +déplacer les nœuds sélectionnés +restreindre à des mouvements horiz./vert. +déplacer le long des poignées +Restreint les déplacements selon les directions des poignées et leurs perpendiculaires (soit 8 directions). +Si le nœud a des droites d'un côté ou des deux, le déplacement sera restreint à ces droites et leurs perpendiculaires. +désactiver temporairement le collage +Le collage des nœuds est activable dans les préférences du document. +Par défaut, seules les boîtes de contour des objets collent à la grille ou aux guides. +Espacetamponner une copie + Lors du déplacement nœuds de à la souris, un appui sur la barre d'espace dépose une copie de l'objet sélectionné. +Vous pouvez maintenir la barre d'espace appuyée lors d'un déplacement pour obtenir une belle "trainée". + + + +Déplacement des poignées à la souris +déplacer une poignée de nœud +tourner la poignée par incrément(s) + +L'incrément de rotation par défaut est 15 degrés. + Permet aussi de forcer le déplacement selon la direction de la poignée et sa perpendiculaire. +tourner les deux poignées +préserver la longueur de la poignée +Ctrl, Maj, Alt peuvent être combinés lors du cliquer-déplacer de contrôles. + + + +Inverser +rinverser la direction du chemin + + + +Editer des formes + +L'outil nœud agit aussi sur les poignées des formes (rectangles, ellipses, étoiles, spirales). +Cliquer sur une forme pour la sélectionner. +Voir les les raccourcis des outils de formes correspondants, qui fonctionnent aussi dans l'outil nœud. + + + + +Annuler +Escannuler bande étirable/déplacer +Un appui sur Esc (le bouton de la souris étant encore pressé) annule la bande étirable, le déplacement de nœud/poignée. + + +Zoom + +zoommer +dézoommer +zoommer sur la zone + +Pipette + +capturer la couleur de remplissage +capturer la couleur de contour +couleur moyenne de remplissage +couleur moyenne de contour +Cliquer applique la couleur sous le curseur à la sélection courante. Cliquer-déplacer un disque en calcule la couleur moyenne. +Ccopier la couleur +Copie la couleur sous le curseur vers le presse-papiers, en tant que texte au format RRVVBBAA (8 chiffres hexadécimaux). + +Rectangle + +Création +dessiner un rectangle +dessiner un rectangle de ratio entier +Ceci force le rectangle à garder un rapport hauteur/largeur entier (permet aussi de dessiner un carré). +dessiner autour du point de départ +Ceci crée un rectangle symétriquement autour du point de départ. + + +Edition +cliquer sur un rectangle à sélectionner +redimensionner ou arrondir +Les deux poignées d'arrondi sont en haut à droite; celles de redimensionnement, en haut à gauche et en bas à droite. +préserver largeur, hauteur ou ratio +S'applique aux poignées de redimensionnement. +Celles-ci redimensionnent le rectangle dans son propre système de coordonnées, avant d'appliquer toute transformation. +préserver l'arrondi +S'applique aux poignées d'arrondi. +Lors de l'arrondi des coins, ne déplacer qu'une poignée (l'autre restant dans le coin) préserve la circularité du coin. +Déplacez les deux poignées pour un arrondi elliptique, ou une seule en appuyant sur Ctrl pour synchroniser la deuxième. + +Escdésélectionner + +Ellipse + +Création +dessiner une ellipse +dessiner une ellipse de ratio entier +Ceci force l'ellipse à garder un rapport hauteur/largeur entier (permet aussi de dessiner un cercle). +dessiner autour du point de départ +Ceci crée une ellipse symétriquement autour du point de départ. + + +Edition +cliquer sur une ellipse à sélectionner +redimensionner ou "ouvrir" +Les deux poignées d'arc/camembert sont tout à droite; celles de redimensionnement, tout en haut et tout à gauche. +forcer la circularité +S'applique aux poignées de redimensionnement. +Celles-ci redimensionnent l'ellipse dans son propre système de coordonnées, avant d'appliquer toute transformation. +modifier l'angle par incréments +S'applique aux poignées d'arc/camembert. +L'incrément d'angle par défaut est de 15 degrés. +Escdésélectionner + +Etoile + +Création +dessiner une étoile +tourner l'étoile par incréments +L'incrément d'angle par défaut est de 15 degrés. + + +Edition +cliquer sur une étoile à sélectionner +déplacer une poignée pour modifier l'étoile +garder l'étoile strictement radiale +arrondir l'étoile +supprimer l'arrondi +rendre l'étoile aléatoire +supprimer le hasard +Escdésélectionner + +Spirale + +Création +dessiner une spirale +tourner la spirale par incréments +L'incrément d'angle par défaut est de 15 degrés. + + +Edition +cliquer sur une spirale à sélectionner + +enrouler/dérouler (poignée intérieure) +Déplacer la poignée intérieure pour modifier le paramètre "rayon intérieur". + +converger/diverger (poignée intérieure) +forcer divergence=1 (poignée intérieure) +Alt+déplacer verticalement sur la poignée intérieure pour modifier la divergence, Alt+cliquer la remet à 1. +forcer rayon intérieur=0 (poignée intérieure) +Maj+cliquer sur la poignée intérieure la déplace (et donc le départ de la spirale) au centre. + +enrouler/dérouler (poignée extérieure) +Déplacer la poignée extérieure modifie le nombre de tours. Maj+Alt+cliquer-déplacer pour en/dé-rouler en préservant le rayon. +redimensionner/tourner (poignée extérieure) +Utiliser Maj+Alt pour forcer une rotation seulement (verrouille le rayon de la spirale). + +tourner une poignée par incréments +L'incrément d'angle par défaut est de 15 degrés. Ceci s'applique aux deux poignées. + +Escdésélectionner + +Texte + + +créer/activer un objet texte + +Cliquer sur un espace libre ou sur un objet autre qu'un texte affiche un curseur texte; vous pouvez alors taper votre texte. +Cliquer sur un objet texte pour l'activer; le curseur est placé à la fin du texte. +Pour taper des caractères + ou -, utilisez le clavier principal, les touches + et - du pavé numérique étant réservées pour le zoom. +se déplacer dans un objet texte +Début,Finaller au début/à la fin de la ligne +Entréecommencer une nouvelle ligne +Escdésélectionner l'objet texte + + + +Caractères spéciaux +U(dés)activer le mode Unicode +Dans ce mode, entrez des chiffres hexadécimaux et validez (Entrée ou Espace) pour obtenir le caractère Unicode correspondant. +Exemple : Ctrl+U 2 0 1 4 Entrée insère un tiret long et sort du mode Unicode. +Utilisez Espace au lieu d'Entrée pour rester en mode Unicode après avoir inséré un caractère. +Un appui sur Esc annule le mode Unicode (sans insérer de caractère). + +Espaceinsérer un espace insécable +Un espace insécable est visible même dans un objet texte sans attribut xml:space="preserve". + + + +Inter-lettrage +>allonger la ligne d'1 pixel +>allonger la ligne de 10 pixels +<rétrécir la ligne d'1 pixel +<rétrécir la ligne de 10 pixels +Ces raccourcis agissent lorsque vous éditez un objet texte. Ils ajustent l'inter-lignage de la ligne courante seulement. +La précision réelle de ces ajustements (à l'échelle du pixel) dépend du niveau de zoom. Zommer pour un ajustement plus fin. + + + +Inter-lignage +>rendre l'objet texte plus haut d'1 pixel +>rendre l'objet texte plus haut de 10 pixels +<rendre l'objet texte plus bas d'1 pixel +<rendre l'objet texte plus bas de 10 pixels +Ces raccourcis agissent lorsque vous éditez un objet texte. Ils ajustent l'inter-lignage de l'objet texte courant seulement. +La précision réelle de ces ajustements (à l'échelle du pixel) dépend du niveau de zoom. Zommer pour un ajustement plus fin. + + + +Crénage et déplacement +déplacer les caractères suivants d'1 pixel +déplacer les caractères suivants de 10 pixels +Ces raccourcis agissent lorsque vous éditez un objet texte. +Elles déplacent (horizontalement ou verticalement) le caractère suivant le curseur et tous les autres jusqu'à la fin de la ligne. +Exemeple : déplacer vers le bas un seul caractère. +Placez le curseur devant le caractère, appuyez sur Alt+Bas, puis derrière et appuyez sur Alt+Haut. + + + +La précision réelle des déplacements (à l'échelle du pixel) dépend du niveau de zoom. Zommer pour un ajustement plus fin. + + + +Texte suivant un chemin +Dsélectionner le chemin +Sélectionner un texte suivant un chemin puis utiliser ce raccourci permet de sélectionner le chemin source du texte. + + diff --git a/share/screens/keys.sl.svg b/share/screens/keys.sl.svg new file mode 100644 index 000000000..1f4ac63a9 --- /dev/null +++ b/share/screens/keys.sl.svg @@ -0,0 +1,737 @@ +clickdragclickdragclickdragwheelShiftCtrlAltLeftRightarrowsupdownOrodja + + +F1,sizbirnik +Presledekizbirnik (začasno) +Preslednica začasno vključi Izbirnika. Ponovljen pritisk preklopi nazaj na prejÅ¡nje orodje. +F2,norodje za vozlišča +F3,zpogled +F4,rpravokotniki +F5,eelipse/loki +F6,pprostoročno risanje (svinčnik) +F6,bbezier krivulje (pero) +F6kaligrafske poteze +F7,dpipeta +F8,tbesedila +F9,ispirale +F9,*zvezde + +Datoteka + + +Nustvari nov dokument +Oodpri SVG dokument +Eizvozi v PNG +Iuvozi sliko ali SVG +Pnatisni dokument +Sshrani dokument +Sshrani pod drugim imenom +Qzapri Inkscape + + +Okno + + +Rpreklopi ravnila +Bpreklopi drsnike +F11preklopi celozaslonski način + + + +F10glavni meni +Do menijev lahko dostopate tudi s tipko Alt in črko, ki je v imenu menija podčrtana. +F10,padajoči meni + + + +F4,Wzapri okno dokumenta +Če je bil to edini odprt dokument, se zapre tudi Inkscape. +Tabnaslednje okno dokumenta +TabprejÅ¡nje okno dokumenta +Tako krožite med odprtimi okni z dokumenti. + + +Pogovorna okna + +FPolnilo in obroba +TBesedilo and pisava +MPreoblikovanje +APoravnava in razpored +OLastnosti predmeta +XUrejevalnik XML +DNastavitve dokumenta +PNastavitve Inkscape-a +EIzvozi v PNG +FIšči +Če ustrezno pogovorno okno Å¡e ni odprto, ga tako odprete, sicer pa mu podelite pozornost. + + + +preklopi vidnost +F12preklopi pogovorna okna +Tako začasno skrijete vsa pogovorna okna. Ponovni pritisk na F12 jih spet pokaže. + + + +znotraj pogovornega okna +Escvrnitev na platno +F4,Wzapri okno +Tabskoči na naslednji gradnik +Tabskoči na predhodni gradnik +Enterpotrdi novo vrednost +This accepts the new value you typed in a besedilo field and returns focus to canvas. +Presledek,Entervključi trenutni gumb ali spisek +PgUp,PgDnzamenjaj zavihek + +Zgornja vrstica + + +To je vrstica na vrhu okna dokumenta. Vsebuje napredne nastavitve za vsako ordje. +Xpreskoči na prvo možno polje +Enterpotrdi novo vrednost +Tako potrdite novo vpisano vrednost in se vrnete na platno. +Escprekliči spremembe, vrni se na platno +Tako prekličete spremembe v polju in se vrnete na platno. +Zprekliči spremembe +Tako prekličete spremembe v polju, a ostanete v njem. +Tabskoči na naslednje polje +Tabskoči na prejÅ¡nje polje +Tako krmarite med polji zgornje vrstice (če ste spremenili vrednost bo ob izhodu potrjena). + + + +spreminjanje vrednosti +,spremeni vrednost za 0.1 +PgUp,PgDnspremeni vrednost za 5.0 + + +Platno + + +Pogled +=,+približaj +-oddalji +Tipke +/- na Å¡tevilčni tipkovnici delujejo tudi med urejanjem besedila. +,približaj +,oddalji +približaj ali oddalji +Zvključi polje za nastavitev pogleda +Polje za nastavitev pogleda je v spodnjem levem kotu in vam omogoča natančno nastavitev razmerja. + + + +Pripravljeni pogledi +1enakomerno 1:1 +2pomanjÅ¡ano 1:2 +3celotna izbira +4celotna risba +5celotna stran +E,6Å¡irina strani + + + +Zgodovina pogledov +`(apostrof) prejÅ¡nji pogled +`naslednji pogled +Tako potujete naprej in nazaj po zgodovini pogledov te seje. + + + +Gibanje +premakni platno +Te tipke so pospeÅ¡ene, to pomeni, da bo premikanje hitrejÅ¡e, če večkrat zaporedoma pritisnete, ali če držite pritisnjeno. +premakni platno +,premakni platno +premakni platno navpično +premakni platno vodoravno + + + +Vodila in mreža +vodilo izvleci iz ravnila +Če pritisnete na ravnilo in povlečete iz njega, boste ustvarili vodilo. ZbriÅ¡ete ga tako, da ga odvlečete nazaj. + +|,\preklopi vodila in preskakovanje do njih +Če želite drugačne nastavitve vidljivosti in preskakovanja vodil, jih nastavite med Nastavitvami dokumenta. +Če ustvarite vodilo iz ravnila, se bosta vključila vidnost vodil in preskakovanje do njih. +#,3preklopi mrežo in preskakovanje do nje +Če želite drugačne nastavitve vidljivosti in preskakovanja mreže, jih nastavite med Nastavitvami dokumenta. +Deluje samo tipka 3 na glavni tipkovnici, ne pa na Å¡tevilčni. + +Predmet + + +Razveljavi/ponovi +Y,Zrazveljavi +Z,Yponovi + + + +Odložišče +Ckopiraj izbrano +Tako skopirate izbrano na odložišče (Inkscape-ovo, ne sistemsko). +Xizreži izbrano +Tako skopirate izbrano na Inkscape-ovo odložišče in zbriÅ¡ete izvirnik. +Vprilepi z odložišča +Tako dodate predmet(e) z odložišča pod miÅ¡kin kazalec ali na sredo okna, če je kazalec izven platna. + +Vprilepi na mesto +Tako prilepite predmete z odložišča na mesto, s katerega so bili kopirani. +Vprilepi slog +Tako uporabite slog prvega predmeta z odložišča na celotni izbiri. + + + +Podvoji +Dpodvoji izbiro +Novi predmeti se postavijo natanko nad izvirne in so izbrani. + + + +Kloniranje +Dkloniraj predmet + +Klona lahko neodvisno premikate, vrtite, nagibate, mu spreminjate velikost, pot, polnilo in obrobo pa dobiva iz izvirnika. + +Klon se pojavi natanko nad izvirnikom in je izbran. +Klonirate lahko le posamezne predmete. Če jih želite klonirati več hkrati, jih prej združite in klonirajte skupino +Dodveži klona +To odstrani povezavo z izvirnikom, klon postane običajna kopija. +Dizberi izvirnika +Da ugotovite, kdo je izvirnik danega klona, uporabite ta ukaz. + + + +Tlakuj +TTlakuj izbrano +Tako pretvorite izbiro v pravokotnik s tlakovanim polnilom. + + + +Združevanje +U,GZdruži izbrane predmete +Uporabite Ctrl+klik, da izberete predmet, ki je združen v skupino. +G,URazdruži izbrane skupine +To razdruži le zadnjo raven združevanja. Pritisnite večkrat, da razdružite ujete skupine. + + + +Prekrivanje +Homeizbrano dvigni na vrh +Endizbrano spusti na dno +PgUpizbrano dvigni za eno raven +PgDnizbrano spusti za eno raven + + +Pot + + +Pretvori v pot +Cpretvori dane predmete v pot(i) +Cpretvori potezo (obrobo) v pot + + + +Logične operacije ++unija +Unija združi poljubno Å¡tevilo predmetov v eno pot in odstrani prekrivanja. +-razlika +Razlika odÅ¡teje zgornjega od dveh predmetov od spodnjega. +*presek +Presek ustvari pot, ki ustreza delu, na katerem so se prekrivali vsi izbrani predmeti. +^izključujoči ALI (XOR) +XOR deluje podobno kot unija, a le na dveh predmetih in odstrani področje prekrivanja. +/delitev (rez) +Delitev razreže spodnji predmet po potezah zgornjega. Spodnji ohrani nastavitve polnila in obrobe. +/razreži pot + +Razreži pot razreže obrobo spodnjega predmeta, kjer se križa z zgornjim in odstrani vso polnilo. +Rezultati unije, razlike, preseka in XOR podedujejo lastnost id= in s tem tudi vse klone spodnjega predmeta. +Delitev in razrez poti običajno ustvarita več predmetov; eden od njih (naključno) podeduje id= spodnjega izvirnega predmeta. + + + +Odmiki +(zožaj pot (proti središču) +)razÅ¡iri pot (iz središča) +Privzeta dolžina odmika je 2 točki. +(zožaj pot za 1 piko +)razÅ¡iri pot za 1 piko +(zožaj pot za 10 pik +)razÅ¡iri pot za 10 pik +Dejanska dolžina odmika je odvisna od stopnje pogleda. Za natančnejÅ¡i odmik približajte pogled. +Vsi ukazi z (, ) po potrebi pretvori predmet v pot. +Justvari dinamičen odmik +Justvari povezan odmik + +Ti ukazi ustvarijo odmaknjen predmet, samostojen ali povezan z izvirnikom, ki ga lahko urejate z orodjem za vozlišča. + + + +Sestavljanje +Ksestavi poti +V nasprotju z združevanjem, tu iz večih poti dobimo eno samo. +V nasprotju z unijo, se tu prekrivajoča področja ne spreminjajo. + +Prekrivajoča področja se zapolnijo s polnilom, odvisno od nastavitve vijugasto/spremenljivo v pogovornem oknu Polnilo in obroba. +Krazstavi poti +To razstavi predmet po njegovih poteh. Ne uspe, če je predmet ena sama pot. + + + +Poenostavitev +Lpoenostavi +Ta ukaz poskuÅ¡a zmanjÅ¡ati Å¡tevilo odvečnih vozlišč na poti. Zato predmete najprej pretvori v poti. +Če ga sprožite večkrat zaporedoma, bo bolj agresiven. + +Če ga sprožite po krajÅ¡em premoru, se bo spet nastavil na privzeto agresivnost (ki jo lahko nastavite v Nastavitvah Inkscape-a). + + +Izbirnik + + +Izbiranje s tipkovnico +Tabizberi naslednji predmet +Tabizberi prejÅ¡nji predmet +To izbira predmete po njihovih navpični urejenosti (tabulator kroži od spodaj navzgor, Shift ga obrne navzdol). +Če niste ročno preurejali, bo zadnji ustvarjeni predmet postavljen najviÅ¡je. +Zato, če ni nič drugega izbranega in pritisnete Shift+Tab enkrat, bo izbran zadnji ustvarjeni predmet. +Aizberi vse predmete +DelizbriÅ¡i izbrano +Escprekliči izbiro + + + +Premikanje s tipkovnico +premakni izbrano za 1 zamah +premakni izbrano za 10 zamahov +Privzeta dolžina zamaha je 1mm. +premakni izbrano za 1 piko +premakni izbrano za 10 pik +Dejanska dolžina premika v pikah je odvisna od stopnje pogleda. Prbiližajte pogled za natančnejÅ¡e premike. + + + +Vrtenje s tipkovnico +[,]zavrti izbrano za en korak +Privzet korak vrtenja je 15 stopinj. ] vrti v smeri ure, [ vrti proti smeri ure. +[,]zavrti izbrano za 90 stopinj +[,]zavrti izbrano za 1 piko +Dejanska dolžina zasuka v pikah je odvisna od stopnje pogleda. Prbiližajte pogled za natančnejÅ¡e zasuke. + + + +Raztegovanje s tipkovnico +.,>raztegni izbrano za en korak +,,<skrči izbrano za en korak +Privzet korak raztega je 2 točki. +.,>raztegni izbrano na 200% +,,<skrči izbrano na 50% +.,>raztegni izbrano za 1 piko +,,<skrči izbrano za 1 piko +Dejanska dolžina raztega v pikah je odvisna od stopnje pogleda. Prbiližajte pogled za natančnejÅ¡i razteg + +Raztegovanje je enakomerno okrog središča, tako da se velikost raztega nanaÅ¡a na večjo stranico. + + + +Prevračanje s tipkovnico +hprevrni izbrano vodoravno +vprevrni izbrano navpično + + + +Izbiranje z miÅ¡ko +izberi predmet +Če pritisnete z levim gumbom, bo prejÅ¡nja izbira preklicana. +preklopi izbiro + +Če držite Shift in kliknete na predmet, ga s tem dodate ali izključite iz izbire. + + + +Izbiranje znotraj skupine +izberi v skupini +preklopi izbiro v skupini + + + +Elastika +izberi več predmetov +Če povlečete z miÅ¡ko okrog predmetov, jih izberete z elastiko. PrejÅ¡nja izbira je razveljavljena. +dodaj predmet v izbiro +Elastiko morate običajno začeti na praznem področju, razen če obenem držite Shift. +Inkscape bo delal elastiko tudi če začnete v predmetu. + + + +Premikanje z miÅ¡ko +premakni izbrane predmete +Vlečenje predmeta ga tudi izbere. +omeji premikanje na vodoravn oali navpično +Presledekspusti kopijo +Med vlečenjem ali preoblikovanjem predmeta bo vsak pritisk na preslednico ustvaril kopijo predmeta. +Med vlečenjem lahko presledek tudi držite in tako ustvarite sled. + + + +Preoblikovanje z miÅ¡ko +preklopi ročice za velikost/vrtenje +spremeni velikost (z ročico) +zavrti ali nagni (z ročico) + + + +Ročice za velikost +spremeni velikost in ohrani razmerja + +simetrično preoblikovanje +Če med preoblikovanjem držite Shift, bo preoblikovanje simetrično glede na središče izbire. +počasno spreminjanje +Če med preoblikovanjem držite Alt, bo zaostajalo za premikanjem miÅ¡ke. Tako boste dosegli večjo natančnost. + + + +Ročice za vrtenje +nagni ali razetgni +Če držite Ctrl med vlečenjem ročice za nagibanje (ne-kotne), lahko poleg nagibanja tudi spreminjate velikost. +preskakuj po korakih +Privzet korak je 15 stopinj. + + + +Prekliči +Escprekčili elastiko, premik ali problikovanje +Če, dokler je miÅ¡kin gumb pritisnjen, pritisnete Esc, prekličete trenutno elastiko, premik ali preoblikovanje. + + +Prostoročno + +nariÅ¡i črto prostoročno +apreklopi nova/nadaljevana +To preklopi med dodajanjem nove črte, ali nadaljevanjem obstoječe (sidra za dodajanje so prikazana). + +Bezier krivulje + + +Ustvari vozlišče +ustvari ostro vozlišče +ustvari bezier vozlišče z dvema ročicama +spreminjaj le eno ročico +Tako premikate le eno ročico (namesto obeh) in ustvarite ostro vozlišče. +preskakuj s premiki ročice po korakih +Privzet korak je 15 stopinj. + + + +Ustvari odseke +preskakuj z odsekom po korakih +To preskakuje z novo smerjo vozlišča, glede na prejÅ¡njo, po korakih (privzeto 15 stopinj). + + + +Dokončanje +Enterdokončaj trenutno črto +dokončaj trenutno črto +dokončaj trenutno črto +Enter, desni klik, ali dvojni levi klik dokončajo trenutno črto in zanemarijo nedokončan (rdeč) odsek. + + + +Tipkovnica +Escprekliči trenutno črto +BackspacepobriÅ¡i zadnji odsek trenutne črte +apreklopi med nova/dodajanje +To preklopi med dodajanjem nove črte, ali nadaljevanjem obstoječe (sidra za dodajanje so prikazana). + +Vozlišča + + +Izbiranje s tipkovnico +Tabizberi naslednje vozlišče +Tabizberi prejÅ¡nje vozlišče +tako lahko izberete katerokoli vozlišče na trenutni poti. +Aizberi vsa vozlišča poti +Escprekliči izbiro vozlišč + + + +Premikanje s tipkovnico +premakni izbrano vozlišče za en sunek +premakni izbrano vozlišče za 10x sunek +Privzeta dolžina sunka je 1mm. +premakni izbrano vozlišče za 1 piko +premakni izbrano vozlišče za 10 pik +Dejanska dolžina premika v pikah je odvisna od stopnje pogleda. Približajte pogled za natančnejÅ¡e premike. + + + +Vrtenje ročic s tipkovnico +[,]zavrti obe ročici za en korak +Privzet korak je 15 stopinj. ] vrti v smeri ure, [ vrti proti smeri ure. To deluje za več vozlišč. +[,]zavrti levo vozlišče za en korak +[,]zavrti desno vozlišče za en korak +[,]zavrti levo vozlišče za 1 piko +[,]zavrti desno vozlišče za 1 piko + + + +Spreminjanje velikosti ročic s tipkovnico +<,>stisni/razÅ¡iri obe ročici za en korak +Privzet korak je 2 točki. To deluje za več vozlišč. +<,>raztegni levo ročico za en korak +<,>raztegni desno ročico za en korak +<,>raztegni levo ročico za 1 piko +<,>raztegni desno ročico za 1 piko +Dejanski razteg v pikah je odvisen od stopnje pogleda. Približajte pogled za natančnejÅ¡e raztege. +Namesto < in > lahko uporabite , (vejico) in . (piko). + + + +spremeni odsek poti +Lnaredi črto +Knaredi krivuljo +Za ta ukaz morate izbrati več kot dve nesosednji vozlišči. + + + +Spremeni vrsto vozlišča +CNaj bo ostro +SNaj bo mehko +YNaj bo simetrično +preklopi med mehko/ostro/simetrično + + + +Združi/zlomi +Jzdruži izbrana vozlišča +Za to morate izbrati natanko dve krajišči poti. +Bzlomi izbrana vozlišča +Potem je izbrano le eno vozlišče. To deluje za več vozlišč. + + + +Brisanje, ustvarjanje, podvojevanje +DelzbriÅ¡i izbrana vozlišča +zbriÅ¡i vozlišče +Insvstavi nova vozlišča +To doda nova vozlišča na sredino izbranega odseka, zato potrebuje vsaj dve nasosednji vozlišči. +Dpodvoji izbrana vozlišča) +Nova vozlišča se ustvarijo na isti poti; postavljena so natanko nad starimi in so izbrana. + + + +Vključi vozlišče +Vključeno vozlišče je tisto, ki ga premikamo ali pa pod miÅ¡kinim kazalcem. +Ko imate vključeno vozlišče, nekatere eno-znakovne bližnjice ne delajo; +da jih lahko uporabite, premaknite miÅ¡kin kazalec z vozlišča. +cnaj bo vozlišče ostro +snaj bo vozlišče mehko +ynaj bo vozlišče simetrično +bzlomi vključeno vozlišče +BackspacezbriÅ¡i vključeno vozlišče + + + +Izbiranje z miÅ¡ko +izberi predmet +Predmet izberete s klikom nanj. +Vozlišča in ročice izbranega predmeta so takoj dostopne (tako vam ni treba preklopiti na Izbirnik). +izberi vozlišče +Vozlišče izberete s klikom nanj. +preklopi izbranost vozlišče +prekliči izbiro +Vse izbire prekličete s klikom na prazno področje. + + + +Elastika +izberi več vozlišč +Če povlečete okrog vozlišč ustvarite elastiko (jih izberete); prejÅ¡nja izbira je zanemarjena. +dodaj vozlišče med izbrane + + + +Premikanje z miÅ¡ko +premakni izbrana vozlišča +restrict movement to horizontal or vertical +premakni v smeri ročic +To omeji gibanje na smer ročic vozlišča, njihova nadaljevanja in večkratnike (skupaj 8 skokov).. + +Presledekspusti kopijo +Ko vlečete vozlišče vsak pritisk na presledek spusti kopijo predmeta. +Če medtem držite presledek ustvarite sled. + + + +Premikanje ročic z miÅ¡ko +premakni ročico vozlišča +preskakuj po korakih +Privzet korak kota je 15 stopinj. To preskakuje tudi po izvirnem kotu ročice in njegovih večkratnikih. +zavrti obe ročici +zakleni dolžino ročice +Pri vlečenju ročic lahko uporabljate tudi Ctrl, Shift, Alt. + + + +Obrat +rzamenjaj smer poti + + + +Urejanje oblik +Orodje za vozlišča prav tako ureja vozlišča oblik (pravokotnikov, elips, zvezd, spiral). Kliknite na obliko, da jo izberete. +Veljajo vse bližnjice, kot pri posebnih orodjih za te oblike. + + + + +Preklic +EscPrekliči elastiko ali premik +Če, dokler je miÅ¡kin gumb pritisnjen, pritisnete Esc, prekličete trenutno elastiko ali premik vozlišč. + + + +Pogled + +približaj +oddalji +približaj območje + +Pipeta + +izberi barvo polnila +izberi barvo obrisa +povprečna barva polnila +povprečna barva obrisa +Pipeta nanese barvo na trenutno izbiro. Če jo povlečete, izračuna povprečno barvo na krožnem območju s tem polmerom. + +Pravokotniki + +Risanje +nariÅ¡i pravokotnik +nariÅ¡i pravokotnik z razmerji naravnih Å¡tevil +Tako omejite razmerja stranic pravokotnika na cela Å¡tevila. +riÅ¡i okrog začetne točke +Tako nariÅ¡ete pravokotnik simetrično okrog prve točke. + + +Urejanje +kliknite pravokotnik, da ga izberete +povlecite ročico, da zaobljite kote +zakleni kote, da bodo krožni +Ko mehčate kote pravokotnika, bo premik le ene ročice (z drugo v kotu) povzročil krožno zaobljene kote. +Če premaknete obe, bodo koti eliptični, če povlečete eno in držite Ctrl bo druga sledila. +Escprekliči izbiro + +Elipse + +Risanje +nariÅ¡i elipso +nariÅ¡ite elipso z razmerji naravnih Å¡tevil +Tako omejite razmerja osnovnic elipse na cela Å¡tevila. +riÅ¡i okrog začetne točke +Tako nariÅ¡ete elipso simetrično okrog prve točke. + + +Urejanje +kliknite elipso, da jo izberete +povlecite ročico, da ustvarite odsek ali lok +omejite lok ali segmet na korake +Privzeta dolžina koraka je 15 stopinj. +Escprekliči izbiro + +Zvezde + +Risanje +nariÅ¡i zvezdo +snap zvezda to angle steps +Privzeta dolžina koraka je 15 stopinj. + + +Urejanje +click a zvezda to select +povlecite ročico, da spremenite obliko zvezde +obdrži žarke ravne (brez zamikanja) +Escprekliči izbiro + +Spirale + +Risanje +nariÅ¡i spiralo +preskakuj po korakih +Privzeta dolžina koraka je 15 stopinj. + + +Urejanje +kliknite spiralo, da jo izberete +povlecite ročico, da spremenite obliko spirale +Če povlečete notranjo ročico, spiralo zvijete. zunanja ročica spremeni velikost spirale. +preskakuj z ročicami po korakih +Privzeta dolžina koraka je 15 stopinj. +zakleni polmer spirale +To ima smisel, če vlečete zunanjo ročico spirale. +Escprekliči izbiro + +Besedilo + + +vključi/izključi predmet besedilo + +Če kliknete na prazno območje ali kak drug predmet, se pojavi kazalec za besedilo; sedaj lahko piÅ¡ete. +Če kliknete na predmet z besedilom ga vključite; kazalec se postavi na konec besedila. +Če želite napisati + in - uporabite glavno tipkovnico. Tista na Å¡tevilččni tipkovnici sta za prilagajanje pogleda. +krmari po besedilu +Home,Endna začetek/konec vrstice +Enternova vrsta +Escprekliči izbiro predmeta besedilo + + + +Posebni znaki +Upreklopi znake Unicode + +V tem načinu se vsake Å¡tiri Å¡estnajstiÅ¡ke vrednosti prevedejo v ustrezen Unicode znak. +Ponovljen Ctrl+U ali pa Esc konča Unicode način. +Primer: Ctrl+U 2 0 1 4 Esc doda podčrtaj. + +Presledekvstavi presledek brez premora +Presledek brez premora je viden tudi v besedilnem predmetu brez xml:space="preserve". + + + +Razmikanje črk +>razÅ¡iri vrstico za 1 piko +>razÅ¡iri vrstico za 10 pik +<skrči vrstico za 1 piko +<skrči vrstico za 10 pik +To deluje le kadar urejate besedilo. Tako nastavite razdalje med črkami v trenutni vrstici. +Dejanska dolžina premika v pikah je odvisna od stopnje pogleda. Prbiližajte pogled za natančnejÅ¡e premike. + + + +Razmikanje vrstic +>make the besedilo object taller by 1 pixel +>make the besedilo object taller by 10 pixels +<make the besedilo object shorter by 1 pixel +<make the besedilo object shorter by 10 pixels +To deluje le kadar urejate besedilo. Tako nastavite razdalje med vrsticami v trenutnem predmetu. +Dejanska dolžina premika v pikah je odvisna od stopnje pogleda. Prbiližajte pogled za natančnejÅ¡e premike. + + + +Bližanje in zamikanje +zamakni naslednje znake za 1 piko +zamakni naslednje znake za 10 pik +To deluje le kadar urejate besedilo. +Tako premaknete (vodoravno ali navpično) vse znake za kazalcem do konca vrstice. + +Na primer: da navzdol premaknete eno črko postavite kazalec pred njo in pritiskajte Alt+Dol, nato pa kazalec za njo in Alt+Gor. +Dejanska dolžina premika v pikah je odvisna od stopnje pogleda. Prbiližajte pogled za natančnejÅ¡e premike. + + \ No newline at end of file diff --git a/share/screens/keys.svg b/share/screens/keys.svg new file mode 100644 index 000000000..bab7b350a --- /dev/null +++ b/share/screens/keys.svg @@ -0,0 +1,967 @@ + + +clickdragclickdragclickdragwheelShiftCtrlAltLeftRightarrowsupdownleftrightTools + + +F1,sselector +Spaceselector (temporary) +Space switches to the select tool temporarily; another Space switches back. +F2,nnode tool +F3,zzoom tool +F4,rrectangle tool +F5,eellipse/arc tool +F6,pfreehand (pencil) tool +F6,bbezier (pen) tool +F6,ccalligraphic tool +F1,ggradient tool +F7,ddropper tool +F8,ttext tool +F9,ispiral tool +F9,*star tool +F2,oconnector tool +Double click on the tool buttons opens the Preferences dialog showing the page of the corresponding tool. + +Dialogs + +FFill and Stroke +WSwatches +TText and Font +MTransform +AAlign and Distribute +OObject Properties +XXML Editor +DDocument Preferences +PInkscape Preferences +EExport to PNG +FFind +BTrace bitmap +These open a new dialog window if it wasn't open yet, otherwise the corresponding dialog gets focus. + + + +Toggle visibility +F12toggle dialogs +This temporarily hides all open dialogs; another F12 shows them again. + + + +Within a dialog +Escreturn to the canvas +F4,Wclose the dialog +Tabjump to next widget +Tabjump to previous widget +Enterset the new value +This accepts the new value you typed in a text field and returns focus to canvas. +Enterin XML Editor, set the attr value +When editing an attribute value in XML Editor, this sets the new value (same as clicking the "Set attribute" button). +Space,Enteractivate current button or list +PgUp,PgDnin a multi-tab dialog, switch tabs + +Controls bar + + +The Controls bar at the top of the document window provides different buttons and controls for each tool. +Xjump to the first editable field +Enteraccept the new value +This accepts the new value you typed in a text field and returns focus to canvas. +Esccancel changes, return to canvas +This cancels any changes you made in a text field and returns focus to canvas. +Zcancel changes +This cancels any changes you made in a text field but you stay in the field. +Tabjump to next field +Tabjump to previous field +Use these to navigate between fields in the Controls bar (the value in the field you leave, if changed, is accepted). + + + +Changing values +,change value by 0.1 +PgUp,PgDnchange value by 5.0 + + +Canvas + + +Zoom +=,+zoom in +-zoom out +The keypad +/- keys do zooming even when you are editing a text object, unless NumLock is on. +,zoom in +,zoom out +zoom in or out +Zactivate zoom field +The zoom field in the lower left corner of the window allows you to specify zoom level precisely. + + + +Preset zooms +1zoom 1:1 +2zoom 1:2 +3zoom to selection +4zoom to drawing +5zoom to page +E,6zoom to page width + + + +Zoom history +`(back quote) previous zoom +`next zoom +With these keys, you can travel back and forth through the history of zooms in this session + + + +Scrolling (panning) +scroll canvas +Scrolling by keys is accelerated, i.e. it speeds up when you press Ctrl+arrows in quick succession, or press and hold. +scroll canvas +,scroll canvas +scroll canvas vertically +scroll canvas horizontally + + + +Guides and grid +drag off a ruler to create guide +Drag off the horizontal or vertical ruler to create a new guideline. Drag a guideline onto the ruler to delete it. +|,\toggle guides and snapping to guides +If you want to have different values for guides visibility and snapping, set them via the Document Options dialog. +When you create a new guide by dragging off the ruler, guide visibility and snapping are turned on. +#,3toggle grid and snapping to grid +If you want to have different values for grid visibility and snapping, set them via the Document Options dialog. +Note that only the 3 key on the main keyboard works, not on the keypad. + +File + + +Ncreate new document +Oopen an SVG document +Eexport to PNG +Iimport bitmap or SVG +Pprint document +Ssave document +Ssave under a new name +Qexit Inkscape + + +Window + + +Rtoggle rulers +Btoggle scrollbars +F11toggle fullscreen + + + +F10main menu +Menus can also be activated by Alt with the letter underscored in the menu name. +F10,drop-down (context) menu + + + +F4,Wclose document window +This shuts down Inkscape if it was the only document window open. +Tabnext document window +Tabprevious document window +These cycle through the active document windows forward and backward. + + +Layers + +PgUpmove to layer above +PgDnmove to layer below +These commands move the selected objects from one layer to another. + +PgUpraise layer +PgDnlower layer +Homeraise layer to top +Endlower layer to bottom +These commands move the current layer among its siblings (normally other layers). + +Object + + +Undo/redo +Y,Zundo +Z,Yredo + + + +Clipboard +Ccopy selection +This places a copy of the selection to the Inkscape clipboard. Text from text objects is also placed onto the system clipboard. +Xcut selection +This works the same as "copy selection" followed by deleting the selection. +Vpaste clipboard +This places the clipboard objects at the mouse cursor, or at the center of the window if mouse is outside the canvas. +When editing text with the text tool, this pastes the text from the system clipboard into the current text object. +Vpaste in place +This places the clipboard objects to the original location from which they were copied. +Vpaste style +This applies the style of the (first of the) coped object(s) to the current selection. +If a gradient handle (in Gradient tool) or a text span (in Text tool) are selected, they get the style instead of the entire object. + + + +Duplicate +Dduplicate selection +New object(s) are placed exactly over the original(s) and selected. + + + +Clone +Dclone object +A clone can be moved/scaled/rotated/skewed independently, but it updates the path, fill, and stroke from its original. +The clone is placed exactly over the original object and is selected. +You can only clone one object at a time; if you want to clone several objects together, group them and clone the group. +Dunlink clone +Unlinking a clone cuts the link to the original, turning the clone into a plain copy. +Dselect original +To find out which object this is a clone of, select the clone and give this command. The original will be selected. + + + +Bitmaps +Bcreate a bitmap copy +This exports the selected object(s) (all other objects hidden) as PNG in the document's directory and imports it back. +The imported bitmap is placed over the original selection and is selected. +Btrace bitmap +This opens the Trace Bitmap dialog allowing you to convert a bitmap object to path(s). + + + +Patterns +Iobject(s) to pattern +This converts the selection to a rectangle with tiled pattern fill. +Ipattern to object(s) +Each selected object with pattern fill is broken into the same object without fill and a single pattern object. + + + +Group +U,Ggroup selected objects +Use Ctrl+click to select objects within group. +G,Uungroup selected group(s) +This removes only one level of grouping; press Ctrl+U repeatedly to ungroup nested groups. + + + +Z-order +Homeraise selection to top +Endlower selection to bottom +PgUpraise selection one step +PgDnlower selection one step + + +Path + + +Convert to path +Cconvert selected object(s) to path +Cconvert stroke to path + + + +Booleans ++union +Union combines any number of objects into a single path, removing overlaps. +-difference +Difference works on 2 objects, extracting the top from the bottom. +*intersection +Intersection creates a path representing the common (overlapping) area of all selected objects. +^exclusive OR (XOR) +XOR is similar to Union, except that it works on 2 objects and removes areas where the objects overlap. +/division (cut) +Division cuts the bottom object into pieces by the top object, preserving the fill and stroke of the bottom. +/cut path +Cut Path cuts the bottom object's stroke only where it is intersected by the top path, removing any fill from the result. +The result of Union, Difference, Intersection, and XOR inherits the id= attribute and therefore the clones of the bottom object. +Division and Cut path normally produce several objects; of them, a random one inherits the id= of the bottom source object. + + + +Offsets +(inset path (towards center) +)outset path (away from center) +The default offset distance is 2 px (SVG pixel units, not screen pixels). +(inset path by 1 pixel +)outset path by 1 pixel +(inset path by 10 pixels +)outset path by 10 pixels +The actual distance for pixel offsets depends on zoom level. Zoom in for finer adjustment. +All the (, ) commands convert the object to path, if necessary, and produce regular path. +Jcreate dynamic offset +Jcreate linked offset +These commands produce an offset object, editable by the node tool, standalone or linked to the original. +Dselect source +Selecting a linked offset and giving this command will select the source path of the linked offset. + + + +Combine +Kcombine paths +This is different from grouping in that combined paths create one object. +This is different from Union in that overlapping areas are not affected. +Whether overlapping areas are filled is controlled by the Fill: winding/alternating switch on the Fill & Stroke dialog. +Kbreak paths apart +This attempts to break an object into constituent paths; it will fail if the object is one solid path. + + + +Simplify +Lsimplify +This command attempts to simplify selected path(s) by removing extra nodes. It converts all objects to paths first. +If you invoke this command several times in quick succession, it will act more and more aggressively. +Invoking Simplify again after a pause restores the default threshold (settable in the Inkscape Preferences dialog). + + +Selector + + +Keyboard select +Tabselect next object +Tabselect previous object +These keys pick objects in their z-order (Tab cycles from bottom to top, Shift+Tab cycles from top to bottom). +Unless you did manual rearrangements, the last object you created is always on top. +As a result, if nothing is selected, pressing Shift+Tab once conveniently selects the object you created last. +This works on objects within the current layer (unless you change that in preferences). +Aselect all (current layer) +This works on objects within the current layer (unless you change that in preferences). +Aselect all (all layers) +This works on objects in all visible and unlocked layers. +!invert selection (current layer) +This inverts selection (deselects what was selected and selects everything else) in the current layer. +!invert selection (all layers) +This inverts selection (deselects what was selected and selects everything else) in visible and unlocked layers. +Escdeselect +Backspace,Deldelete selection + + + +Keyboard move +move selection by the nudge distance +move selection by 10x nudge distance +The default nudge distance is 2 px (SVG pixel units, not screen pixels). +move selection by 1 pixel +move selection by 10 pixels +The actual distance for pixel movements depends on zoom level. Zoom in for finer movement. + + + +Keyboard scale +.,>scale selection up by the scale step +,,<scale selection down by the scale step +The default scale step is 2 px (SVG pixel units, not screen pixels). +.,>scale selection to 200% +,,<scale selection to 50% +.,>scale selection up by 1 pixel +,,<scale selection down by 1 pixel +The actual size increment for pixel scaling depends on zoom level. Zoom in for finer scaling. +Scaling is uniform around the center, so that the size increment applies to the larger of the two dimensions. + + + +Keyboard rotate +[,]rotate selection by the angle step +The default angle step is 15 degrees. ] rotates clockwise, [ rotates counterclockwise. +[,]rotate selection by 90 degrees +[,]rotate selection by 1 pixel +The actual angle for pixel rotation depends on zoom level. Zoom in for finer movement. + + + +Keyboard flip +hflip selection horizontally +vflip selection vertically + + + +Mouse select +select an object +When you left-click on an object, previous selection is deselected. +toggle selection +Shift+click adds an object to the current selection if it was not selected, or deselects it otherwise. +edit the object +For paths, double clicking switches to Node tool; for shapes, to corresponding shape tool; for text, to Text tool. +For groups, double clicking performs the "Enter group" command (the group becomes temporary layer). + + + +Select within group, select under +select within group +Ctrl+click selects the object at click point disregarding any levels of grouping that this object might belong to. +toggle selection within group +select under +Alt+click selects the object at click point which is beneath (in z-order) the lowest selected object at click point. +If the bottom object is reached, Alt+click again selects the top object. So, several Alt+clicks cycle through z-order stack at point. +On Linux, Alt+click and Alt+drag may be reserved by the window manager. Reconfigure it so you can use them in Inkscape. +toggle under +select under, in groups +toggle under, in groups + + + +Rubberband +select multiple objects +Dragging around objects does "rubberband" selection; previous selection is deselected. +add objects to selection +Normally, you need to start from an empty space to initiate a rubberband. +However, if you press Shift before dragging, Inkscape will do rubberband selection even if you start from an object. + + + +Mouse move +select + move +Dragging an object selects it if it was not selected, then moves selection. +move selected +Alt+drag moves the current selection (without selecting what is under cursor), no matter where you start the drag. +On Linux, Alt+click and Alt+drag may be reserved by the window manager. Reconfigure it so you can use them in Inkscape. +restrict movement to horizontal or vertical +temporarily disable snapping +This temporaily disables snapping to grid or guides when you are dragging with grid or guides on. +Spacedrop a copy +When dragging or transforming with mouse, each Space leaves a copy of the selected object. +You can press and hold Space while dragging for a nice "trail." + + + +Mouse transform +toggle scale/rotation handles +scale (scale handles) +rotate or skew (rotation handles) + + + +Scale handles +scale preserving aspect ratio + +symmetric transformation +Holding Shift while transforming makes transformation symmetric around the center of the selection. + +slow movement +Holding Alt while transforming makes transformation lag behind mouse movement, allowing finer changes. + + + +Rotation handles +snap skew angle +Holding Ctrl when dragging a skew (non-corner) handle snaps the skew angle to angle steps (default 15 degrees). +snap rotation angle +Holding Ctrl when dragging a rotation (corner) handle snaps the rotation angle to angle steps (default 15 degrees). + + + +Cancel +Esccancel rubberband, move, transformation +Press Esc while mouse button is still down to cancel rubberband selection, move, or transformation of any kind. + + +Node tool + + +Keyboard select +Tabselect next node +Tabselect previous node +These keys let you select any node within the selected path +Aselect all nodes in path or subpath(s) +If the path has multiple subpaths and some nodes selected, this command selects all only in subpaths with selected nodes. +Aselect all nodes in path +Escdeselect all nodes + + + +Keyboard move +move selected node(s) by the nudge distance +move selected node(s) by 10x nudge distance +The default nudge distance is 2 px (SVG pixel units, not screen pixels). +move selected node(s) by 1 pixel +move selected node(s) by 10 pixels +The actual distance for pixel movements depends on zoom level. Zoom in for finer movement. + + + +Keyboard handle scale (1 node selected) +<,>contract/expand both handles by scale step +The default scale step is 2 px (SVG pixel units, not screen pixels). May apply to more than one node. +<,>scale left handle by the scale step +<,>scale right handle by the scale step +<,>scale left handle by 1 pixel +<,>scale right handle by 1 pixel +The actual size increment for pixel scaling depends on zoom level. Zoom in for finer scaling. +Instead of the < and > keys, you can use the , (comma) and . (period) keys respectively. + + + +Keyboard handle rotate (1 node selected) +[,]rotate both handles by the angle step +The default angle step is 15 degrees. ] rotates clockwise, [ rotates counterclockwise. May apply to more than one node. +[,]rotate left handle by the angle step +[,]rotate right handle by the angle step +[,]rotate left handle by 1 pixel +[,]rotate right handle by 1 pixel + + + + +Keyboard scale (>1 nodes selected) +These commands scale the selected nodes as if they were an "object", around the center of that object. +.,>scale nodes up by the scale step +,,<scale nodes down by the scale step +The default scale step is 2 px (SVG pixel units, not screen pixels). +.,>scale nodes up by 1 pixel +,,<scale nodes down by 1 pixel +The actual size increment for pixel scaling depends on zoom level. Zoom in for finer scaling. +Scaling is uniform around the center, so that the size increment applies to the larger of the two dimensions. + + + +Keyboard rotate (>1 nodes selected) +These commands rotate the selected nodes as if they were an "object", around the center of that object. +[,]rotate nodes by the angle step +The default angle step is 15 degrees. ] rotates clockwise, [ rotates counterclockwise. +[,]rotate nodes by 1 pixel +The actual angle for pixel rotation depends on zoom level. Zoom in for finer movement. + + + +Keyboard flip (>1 nodes selected) +These commands flip the selected nodes as if they were an "object", around the center of that object. +hflip nodes horizontally +vflip nodes vertically + + + + +Change path segment +Lmake line +Kmake curve +These commands require that more than two adjacent nodes be selected. + + + +Change node type +Cmake cusp +Smake smooth +Ymake symmetric +toggle smooth/cusp/symmetric + + + +Join/break +Jjoin selected nodes +This requires that exactly two end nodes within the path be selected. +Bbreak selected node(s) +After break, only one of each two new nodes is selected. May apply to more than one node. + + + +Delete, create, duplicate +Backspace,Deldelete selected node(s) +create/delete node +Ctrl+Alt+click on a node deletes it; Ctrl+Alt+click on the path between nodes creates a new node in the click point. +create node +Double clicking on the path between nodes creates a node in the click point. +Insinsert new node(s) +This adds new node(s) in the middle(s) of selected segment(s), so it requires that more than two adjacent nodes be selected. +Dduplicate selected node(s) +New nodes are created on the same path; they are placed exactly over the old ones and are selected. + + + + + +Mouse select: objects +click a non-selected object to select +select under +toggle selection +These work the same as in Selector. The nodes or handles of the single selected object become editable. + + + +Mouse select: nodes +select a node +Clicking on a node selects it. +select two adjacent nodes +Clicking on a selected path between the nodes selects the two nodes closest to the click point. +toggle selection +This adds/removes a node (if clicked on node) or two nodes (if clicked on path) to/from the node selection. +deselect +Clicking in an empty space deselects all selected nodes. Next click will deselect the object. + + + +Rubberband +select multiple nodes +Dragging around nodes does "rubberband" selection; previous node selection is deselected. +add nodes to selection + + + +Node move (mouse) +move selected nodes +restrict movement to horizontal or vertical +move along handles +This restricts movement to the directions of the node's handles, their continuations and perpendiculars (total 8 snaps). +If the node has straight lines on one or both sides, this will snap it to these lines' directions and perpendiculars instead. +temporarily disable snapping +Snapping nodes is enabled in Document Preferences. By default, only bounding box of objects snaps to grid/guides. +drag out handle +If a node has a retracted handle, dragging with Shift lets you drag it out of the node. +Spacedrop a copy +When dragging nodes with mouse, each Space leaves a copy of the selected object. +You can press and hold Space while dragging for a nice "trail." + + + +Node handles +move a node handle +snap the handle to angle steps +The default angle step is 15 degrees. This also snaps to the handle's original angle, its continuation and perpendiculars. +rotate both handles +lock the handle length +Ctrl, Shift, Alt can be combined when dragging handles. +retract the handle +Retracted handle is zero length; use Shift+drag to drag it back out. + + + +Reversing +rreverse path direction + + + +Editing shapes +Node tool can also drag the handles of shapes (rectangles, ellipses, stars, spirals). Click on a shape to select it. +See the corresponding shape tools for their editing shortcuts, all of which also work in node tool. + + + + +Cancel +Esccancel rubberband or move +Press Esc while mouse button is still down to cancel rubberband selection, node move, handle move, or handle move. + + +Rectangle tool + +Drawing +draw a rectangle +make a square or integer-ratio rectangle +This restricts rectangle so its height/width ratio is a whole number. +draw around the starting point +This creates a rectangle symmetric around the starting point of the mouse drag. + + +Editing +click an object to select +select under +toggle selection +drag a handle to resize or round corners +Initially, the two rounding handles are in the top right corner; two resize handles are in top left and bottom right corners. +lock width, height, or ratio (resize handles) +lock the corner circular (rounding handles) +Resize handles change the width and height of the rectangle in its own coordinate system, before any transforms are applied. +When rounding corners, dragging only one rounding handle (with the other at the corner) keeps the corner circular. +You can drag both handles for an elliptic rounded corner, or drag one with Ctrl to make sure the other one is synchronized. +Escdeselect + +Ellipse tool + +Drawing +draw an ellipse +make circle or integer-ratio ellipse +This restricts ellipse so its height/width ratio is a whole number. +draw around the starting point +This creates an ellipse symmetric around the starting point of the mouse drag. + + +Editing +click an object to select +select under +toggle selection +drag a handle to resize, make arc or segment +Initially, the two arc/segment handles are in the rightmost point; two resize handles are at the topmost and leftmost points. +lock circle (resize handles) +snap to angle steps (arc/segment handles) +Resize handles change the width and height of the ellipse in its own coordinate system, before any transforms are applied. +The default angle step is 15 degrees. +Escdeselect + +Star tool + +Drawing +draw a star +snap star to angle steps +The default angle step is 15 degrees. + + +Editing +click an object to select +select under +toggle selection +drag a handle to vary the star shape +keep star rays radial (no skew) +round the star +remove rounding +randomize the star +remove randomization +Escdeselect + +Spiral tool + +Drawing +draw a spiral +snap spiral to angle steps +The default angle step is 15 degrees. + + +Editing +click an object to select +select under +toggle selection +roll/unroll from inside (inner handle) +Dragging the inner handle adjusts the "inner radius" parameter. +converge/diverge (inner handle) +reset divergence (inner handle) +Vertical Alt+drag of the inner handle adjusts the "divergence" parameter, Alt+click resets it to 1. +zero inner radius (inner handle) +Shift+click on inner handle makes the spiral start from the center. + +roll/unroll from outside (outer handle) +Dragging the outer handle adjusts the "turns" parameter. Use Shift+Alt+drag to roll/unroll without changing radius. +scale/rotate (outer handle) +Use Shift+Alt to rotate only (locks the radius of the spiral). + +snap handles to angle steps +The default angle step is 15 degrees. This works for both handles. + +Escdeselect + +Zoom tool + +zoom in +zoom out +zoom into the area + +Freehand tool + +draw a freehand line +add to selected path +If a path is selected, Shift+dragging anywhere creates a new subpath instead of a new independent path. +temporarily disable snapping +Shift also temporaily disables snapping to grid or guides when you are drawing with grid or guides on. + +Bezier tool + + +Create nodes +create a sharp node +If no path is being created, this starts a new path. +add to selected path +If a path is selected, Shift+clicking anywhere starts a new subpath instead of a new independent path. +create a bezier node with two handles +move only one handle + +This moves only one handle (instead of both) to create a cusp node. +snap the handle to angle steps +The default angle step is 15 degrees. + + + +Create segments +snap the segment to angle steps +This snaps the new node's angle, relative to the previous node, to angle steps (default 15 degrees). + + + +Finish +Enterfinish current line +finish current line +finish current line +Enter, right click, or double left click finish the current line, discarding the last unfinished (red) segment. + + + +Keyboard +Esccancel current line +Backspaceerase last segment of current line + +Calligraphy + +draw a calligraphic line +,adjust pen width +,adjust pen angle +Width and angle can be adjusted while drawing. + +Gradient tool + +Creating gradients +create gradient +This creates gradient on selected objects. The Controls bar lets you select linear/radial and fill/stroke for the new gradient. +create default gradient +This creates default (horizontal edge-to-edge for linear, centered edge-to-edge-to-edge for radial) gradient on clicked object. + + + +Handles +Tabselect next handle +Tabselect previous handle +move selected handle by the nudge distance +move selected handle by 10x nudge distance +The default nudge distance is 2 px (SVG pixel units, not screen pixels). +move selected handle by 1 pixel +move selected handle by 10 pixels +The actual distance for pixel movements depends on zoom level. Zoom in for finer movement. +Escdeselect handle +open gradient editor +Double clicking a gradient handle opens the Gradient Editor with that gradient and the clicked handle chosen in the stops list. + + + +Mouse select +click an object to select +select under +toggle selection + + +Dropper tool + +pick fill color +pick stroke color +average fill color +average stroke color +Click applies the color under cursor to the current selection. Dragging a radius calculates the average color of a circular area. +If a gradient handle (in Gradient tool) is selected, it gets the color instead of the entire object. +,pick inverse color +If Alt is pressed, picking color (with or without Shift, by click or by drag) picks the inverse of the color. +Ccopy color +This copies the color under cursor to the system clipboard, as text in RRGGBBAA format (8 hex digits). + +Text tool + + +Selecting/creating +create/select a text object + +Clicking in an empty space or on a non-text creates a text object; now you can type your text. +Clicking on a text object selects it; cursor is placed near the click point. +Escdeselect the text object + + + +Text navigation +move cursor by one character +,move cursor by one word +,move cursor by one paragraph +Home,Endgo to beginning/end of line +Home,Endgo to beginning/end of text +All these commands cancel current text selection, if any. + + + +Flowed text (internal frame) +create flowed text +Clicking and dragging in an empty space or on a non-text creates a flowed text object with internal frame. +adjust frame size +Dragging the handle in the lower right corner of the selected flowed text changes width/height of the frame. +lock width, height, or ratio of frame +Dragging the corner handle with Ctrl resizes the frame preserving either width, or height, or ratio. + + + +Flowed text (external frame) +Wflow text into frame +With a text object and a shape/path selected, this flows text into the shape/path. +Both remain separate objects, but are linked; editing the shape/path causes the text to reflow. +Wunflow text from frame +This cuts the flowed text's link to the shape/path, producing a single-line regular text object. +Dselect external frame +To find out which object is the frame of this flowed text, select it and press Shift+D. The frame will be selected. + + + +Text on path +Dselect path +To find out which path this text is put on, select it and press Shift+D. The path will be selected. + + + +Editing text +To type + and - characters, use the main keyboard; keypad + and - are reserved for zoom (unless NumLock is on). +Enterstart a new line or paragraph +Enter in regular text creates new line; in flowed text it creates a new paragraph +Utoggle Unicode entry +To insert an arbitrary Unicode character, type Ctrl+U, then the hexadecimal code point, then Enter. +For example, Ctrl+U 2 0 1 4 Enter inserts an em-dash. +To stay in Unicode mode after inserting the character, press Space instead of Enter. +Press Esc or another Ctrl+U to cancel Unicode mode without inserting the character. +Spaceinsert no-break space +A no-break space is visible even in a text object without xml:space="preserve". + + + +Selecting text +select text +Left-dragging over a text object selects a text span. +select text by character +select text by word +Home,Endselect to beginning/end of line +Home,Endselect to beginning/end of text +select word +select line +Aselect all text +This selects the entire text of the current text object. + + + +Styling selection +Bmake selection bold +Imake selection italic +Also, you can use the Text&Font or Fill&Stroke dialogs to assign any style to text selection. + + + +Letter spacing +>expand line/paragraph by 1 pixel +>expand line/paragraph by 10 pixels +<contract line/paragraph by 1 pixel +<contract line/paragraph by 10 pixels +These commands (only when editing text) adjust letter spacing in the current line (regular text) or paragraph (flowed text). +The actual adjustment for pixel movements depends on zoom level. Zoom in for finer adjustment. + + + +Line spacing +>make the text object taller by 1 pixel +>make the text object taller by 10 pixels +<make the text object shorter by 1 pixel +<make the text object shorter by 10 pixels +These commands (only when editing text) adjust line spacing in the entire text object (regular or flowed). +The actual adjustment for pixel movements depends on zoom level. Zoom in for finer adjustment. + + + +Kerning and shifting +shift characters by 1 pixel +shift characters by 10 pixels +These commands work when editing a regular text object. Kerning does not work in flowed text. +With no selection, they shift (horizontally or vertically) the characters after the cursor until the end of line. +With selection, they shift the selection relative to the rest of text (by inserting opposite kerns at both ends of selection). +The actual adjustment for pixel movements depends on zoom level. Zoom in for finer adjustment. + + + +Rotating +[,]rotate character(s) by 90 degrees +[,]rotate character(s) by 1 pixel +These commands rotate the next character (without selection) or all characters in the selection (with selection). +Rotation only works in regular text (not flowed text). +The actual angle for pixel rotation depends on zoom level. Zoom in for finer movement. + + + diff --git a/share/templates/.cvsignore b/share/templates/.cvsignore new file mode 100644 index 000000000..282522db0 --- /dev/null +++ b/share/templates/.cvsignore @@ -0,0 +1,2 @@ +Makefile +Makefile.in diff --git a/share/templates/A4.svg b/share/templates/A4.svg new file mode 100644 index 000000000..63991a8f9 --- /dev/null +++ b/share/templates/A4.svg @@ -0,0 +1,39 @@ + + + + + + + + + image/svg+xml + + + + + + diff --git a/share/templates/A4_landscape.svg b/share/templates/A4_landscape.svg new file mode 100644 index 000000000..934c99f6d --- /dev/null +++ b/share/templates/A4_landscape.svg @@ -0,0 +1,36 @@ + + + + + + + + + image/svg+xml + + + + + + diff --git a/share/templates/CD_cover_300dpi.svg b/share/templates/CD_cover_300dpi.svg new file mode 100644 index 000000000..330ccf2dc --- /dev/null +++ b/share/templates/CD_cover_300dpi.svg @@ -0,0 +1,36 @@ + + + + + + + + + image/svg+xml + + + + + + diff --git a/share/templates/Letter.svg b/share/templates/Letter.svg new file mode 100644 index 000000000..9f14fdcd5 --- /dev/null +++ b/share/templates/Letter.svg @@ -0,0 +1,36 @@ + + + + + + + + + image/svg+xml + + + + + + diff --git a/share/templates/Letter_landscape.svg b/share/templates/Letter_landscape.svg new file mode 100644 index 000000000..564f4bcf6 --- /dev/null +++ b/share/templates/Letter_landscape.svg @@ -0,0 +1,36 @@ + + + + + + + + + image/svg+xml + + + + + + diff --git a/share/templates/Makefile.am b/share/templates/Makefile.am new file mode 100644 index 000000000..fbd5023fc --- /dev/null +++ b/share/templates/Makefile.am @@ -0,0 +1,38 @@ + +templatesdir = $(datadir)/inkscape/templates + +templates_DATA = \ + README \ + default.svg \ + A4_landscape.svg \ + A4.svg \ + black_opaque.svg \ + business_card_90x50mm.svg \ + CD_cover_300dpi.svg \ + default.svg \ + default.cs.svg \ + default.de.svg \ + default.es.svg \ + default.fr.svg \ + default.hu.svg \ + default.it.svg \ + default.pl.svg \ + default_mm.svg \ + default_pt.svg \ + desktop_1024x768.svg \ + desktop_1600x1200.svg \ + desktop_640x480.svg \ + desktop_800x600.svg \ + icon_16x16.svg \ + icon_32x32.svg \ + icon_48x48.svg \ + icon_64x64.svg \ + Letter_landscape.svg \ + Letter.svg \ + no_borders.svg \ + no_layers.svg \ + web_banner_468x60.svg \ + web_banner_728x90.svg \ + white_opaque.svg + +EXTRA_DIST = $(templates_DATA) \ No newline at end of file diff --git a/share/templates/README b/share/templates/README new file mode 100644 index 000000000..c611da431 --- /dev/null +++ b/share/templates/README @@ -0,0 +1,12 @@ +This folder contains the templates for new documents created in Inkscape. You will +normally see them listed in the File > New submenu. A template may store any +document-specific settings (such as initial zoom and view, paper size, background and +borders, metadata, window geometry, grid and guide settings, export hints) as well as +any objects. To add a new template, simply save or copy it in this folder; nothing else +is required. + +Files of the mask default.*.svg are the translations of default.svg template into +different languages. The default.svg itself is in English. These translations contain +a translated name of the default layer and possibly different canvas size. Each +language version of Inkscape will only use one of these templates and ignore the rest. + diff --git a/share/templates/black_opaque.svg b/share/templates/black_opaque.svg new file mode 100644 index 000000000..065494f90 --- /dev/null +++ b/share/templates/black_opaque.svg @@ -0,0 +1,36 @@ + + + + + + + + + image/svg+xml + + + + + + diff --git a/share/templates/business_card_85x54mm.svg b/share/templates/business_card_85x54mm.svg new file mode 100644 index 000000000..9c1b947ff --- /dev/null +++ b/share/templates/business_card_85x54mm.svg @@ -0,0 +1,37 @@ + + + + + + + + + image/svg+xml + + + + + + diff --git a/share/templates/business_card_90x50mm.svg b/share/templates/business_card_90x50mm.svg new file mode 100644 index 000000000..14e3d20d0 --- /dev/null +++ b/share/templates/business_card_90x50mm.svg @@ -0,0 +1,38 @@ + + + + + + + + + image/svg+xml + + + + + + diff --git a/share/templates/default.cs.svg b/share/templates/default.cs.svg new file mode 100644 index 000000000..f0032ceb2 --- /dev/null +++ b/share/templates/default.cs.svg @@ -0,0 +1,42 @@ + + + + + + + + + image/svg+xml + + + + + + diff --git a/share/templates/default.de.svg b/share/templates/default.de.svg new file mode 100644 index 000000000..6f0c400a2 --- /dev/null +++ b/share/templates/default.de.svg @@ -0,0 +1,37 @@ + + + + + + + + + image/svg+xml + + + + + + diff --git a/share/templates/default.es.svg b/share/templates/default.es.svg new file mode 100644 index 000000000..5b2741a9d --- /dev/null +++ b/share/templates/default.es.svg @@ -0,0 +1,37 @@ + + + + + + + + + image/svg+xml + + + + + + diff --git a/share/templates/default.fr.svg b/share/templates/default.fr.svg new file mode 100644 index 000000000..2f211f9f7 --- /dev/null +++ b/share/templates/default.fr.svg @@ -0,0 +1,37 @@ + + + + + + + + + image/svg+xml + + + + + + diff --git a/share/templates/default.hu.svg b/share/templates/default.hu.svg new file mode 100644 index 000000000..41e4cb73c --- /dev/null +++ b/share/templates/default.hu.svg @@ -0,0 +1,37 @@ + + + + + + + + + image/svg+xml + + + + + + diff --git a/share/templates/default.it.svg b/share/templates/default.it.svg new file mode 100644 index 000000000..df4f3ed95 --- /dev/null +++ b/share/templates/default.it.svg @@ -0,0 +1,37 @@ + + + + + + + + + image/svg+xml + + + + + + diff --git a/share/templates/default.pl.svg b/share/templates/default.pl.svg new file mode 100644 index 000000000..6c2ee688d --- /dev/null +++ b/share/templates/default.pl.svg @@ -0,0 +1,37 @@ + + + + + + + + + image/svg+xml + + + + + + diff --git a/share/templates/default.svg b/share/templates/default.svg new file mode 100644 index 000000000..a6a610fdb --- /dev/null +++ b/share/templates/default.svg @@ -0,0 +1,37 @@ + + + + + + + + + image/svg+xml + + + + + + diff --git a/share/templates/default_mm.svg b/share/templates/default_mm.svg new file mode 100644 index 000000000..e2fda7710 --- /dev/null +++ b/share/templates/default_mm.svg @@ -0,0 +1,37 @@ + + + + + + + + + image/svg+xml + + + + + + diff --git a/share/templates/default_pt.svg b/share/templates/default_pt.svg new file mode 100644 index 000000000..8c918fadb --- /dev/null +++ b/share/templates/default_pt.svg @@ -0,0 +1,37 @@ + + + + + + + + + image/svg+xml + + + + + + diff --git a/share/templates/desktop_1024x768.svg b/share/templates/desktop_1024x768.svg new file mode 100644 index 000000000..bda4f7ae7 --- /dev/null +++ b/share/templates/desktop_1024x768.svg @@ -0,0 +1,37 @@ + + + + + + + + + image/svg+xml + + + + + + diff --git a/share/templates/desktop_1600x1200.svg b/share/templates/desktop_1600x1200.svg new file mode 100644 index 000000000..6e98ce580 --- /dev/null +++ b/share/templates/desktop_1600x1200.svg @@ -0,0 +1,37 @@ + + + + + + + + + image/svg+xml + + + + + + diff --git a/share/templates/desktop_640x480.svg b/share/templates/desktop_640x480.svg new file mode 100644 index 000000000..f6f338015 --- /dev/null +++ b/share/templates/desktop_640x480.svg @@ -0,0 +1,37 @@ + + + + + + + + + image/svg+xml + + + + + + diff --git a/share/templates/desktop_800x600.svg b/share/templates/desktop_800x600.svg new file mode 100644 index 000000000..b06632cf5 --- /dev/null +++ b/share/templates/desktop_800x600.svg @@ -0,0 +1,38 @@ + + + + + + + + + image/svg+xml + + + + + + diff --git a/share/templates/icon_16x16.svg b/share/templates/icon_16x16.svg new file mode 100644 index 000000000..f90bc0a5b --- /dev/null +++ b/share/templates/icon_16x16.svg @@ -0,0 +1,42 @@ + + + + + + + + + image/svg+xml + + + + + + diff --git a/share/templates/icon_32x32.svg b/share/templates/icon_32x32.svg new file mode 100644 index 000000000..d332dbe5d --- /dev/null +++ b/share/templates/icon_32x32.svg @@ -0,0 +1,42 @@ + + + + + + + + + image/svg+xml + + + + + + diff --git a/share/templates/icon_48x48.svg b/share/templates/icon_48x48.svg new file mode 100644 index 000000000..d3946ff2d --- /dev/null +++ b/share/templates/icon_48x48.svg @@ -0,0 +1,42 @@ + + + + + + + + + image/svg+xml + + + + + + diff --git a/share/templates/icon_64x64.svg b/share/templates/icon_64x64.svg new file mode 100644 index 000000000..e777e9dde --- /dev/null +++ b/share/templates/icon_64x64.svg @@ -0,0 +1,43 @@ + + + + + + + + + image/svg+xml + + + + + + diff --git a/share/templates/no_borders.svg b/share/templates/no_borders.svg new file mode 100644 index 000000000..874b21c11 --- /dev/null +++ b/share/templates/no_borders.svg @@ -0,0 +1,37 @@ + + + + + + + + + image/svg+xml + + + + + + diff --git a/share/templates/no_layers.svg b/share/templates/no_layers.svg new file mode 100644 index 000000000..adb50f8e8 --- /dev/null +++ b/share/templates/no_layers.svg @@ -0,0 +1,35 @@ + + + + + + + + + image/svg+xml + + + + + diff --git a/share/templates/web_banner_468x60.svg b/share/templates/web_banner_468x60.svg new file mode 100644 index 000000000..90fceb7de --- /dev/null +++ b/share/templates/web_banner_468x60.svg @@ -0,0 +1,37 @@ + + + + + + + + + image/svg+xml + + + + + + diff --git a/share/templates/web_banner_728x90.svg b/share/templates/web_banner_728x90.svg new file mode 100644 index 000000000..dc35b21bf --- /dev/null +++ b/share/templates/web_banner_728x90.svg @@ -0,0 +1,37 @@ + + + + + + + + + image/svg+xml + + + + + + diff --git a/share/templates/white_opaque.svg b/share/templates/white_opaque.svg new file mode 100644 index 000000000..8f2022b0b --- /dev/null +++ b/share/templates/white_opaque.svg @@ -0,0 +1,37 @@ + + + + + + + + + image/svg+xml + + + + + + diff --git a/share/tutorials/.cvsignore b/share/tutorials/.cvsignore new file mode 100644 index 000000000..3dda72986 --- /dev/null +++ b/share/tutorials/.cvsignore @@ -0,0 +1,2 @@ +Makefile.in +Makefile diff --git a/share/tutorials/Makefile.am b/share/tutorials/Makefile.am new file mode 100644 index 000000000..538c1e5c4 --- /dev/null +++ b/share/tutorials/Makefile.am @@ -0,0 +1,49 @@ + +tutorialdir = $(datadir)/inkscape/tutorials + +tutorial_DATA = \ + README \ + gpl-2.svg \ + tutorial-elements.svg \ + tutorial-elements.fr.svg \ + tutorial-elements.es.svg \ + tutorial-elements.sl.svg \ + tutorial-tips.svg \ + tutorial-tips.es.svg \ + tutorial-tips.fr.svg \ + tutorial-tips.sl.svg \ + making_markers.svg \ + tutorial-advanced.svg \ + tutorial-advanced.es.svg \ + tutorial-advanced.fr.svg \ + tutorial-advanced.ja.svg \ + tutorial-advanced.sl.svg \ + tutorial-basic.svg \ + tutorial-basic.ca.svg \ + tutorial-basic.de.svg \ + tutorial-basic.es.svg \ + tutorial-basic.fr.svg \ + tutorial-basic.ja.svg \ + tutorial-basic.nn.svg \ + tutorial-basic.ru.svg \ + tutorial-basic.sl.svg \ + tutorial-calligraphy.svg \ + tutorial-calligraphy.es.svg \ + tutorial-calligraphy.fr.svg \ + tutorial-calligraphy.sl.svg \ + tutorial-shapes.svg \ + tutorial-shapes.ca.svg \ + tutorial-shapes.es.svg \ + tutorial-shapes.fr.svg \ + tutorial-shapes.ja.svg \ + tutorial-shapes.sl.svg \ + tutorial-tracing.svg potrace.png oldguitar.jpg tux.png \ + tutorial-tracing.de.svg potrace-de.png \ + tutorial-tracing.es.svg \ + tutorial-tracing.fr.svg potrace-fr.png \ + tutorial-tracing.sl.svg + + + +EXTRA_DIST = $(tutorial_DATA) + diff --git a/share/tutorials/README b/share/tutorials/README new file mode 100644 index 000000000..8d43c71bc --- /dev/null +++ b/share/tutorials/README @@ -0,0 +1,11 @@ +This folder contains the Inkscape tutorials in SVG format. You can access them +from within Inkscape via the Help > Tutorials submenu. + +DO NOT EDIT THESE FILES DIRECTLY. They are generated from DocBook sources that +are stored in the doc-docbook module in Inkscape CVS. If you want to edit, +translate, or create a new tutorial, obtain that module and follow the +instructions in its README to edit a tutorial and regenerate the SVG format for +the tutorial you changed. Then place the new SVG file here. + +This folder contains all tutorials in all languages for which translations were +provided. Later we may separate tutorials into language-packs. \ No newline at end of file diff --git a/share/tutorials/gpl-2.svg b/share/tutorials/gpl-2.svg new file mode 100644 index 000000000..35c517276 --- /dev/null +++ b/share/tutorials/gpl-2.svg @@ -0,0 +1,2051 @@ + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Copying this software + + + + + + + The licenses for most software are designed to take away your + freedom to share and change it. By contrast, the GNU General Public License is + intended to guarantee your freedom to share and change + free software — to make sure the software is free for all its users. + This General Public License applies to most of the Free Software + Foundation’s software and to any other program whose authors commit + to using it. (Some other Free Software Foundation software is covered + by the GNU Library General Public License instead.) You can apply it + to your programs, too. + + + + + + + + When we speak of free software, we are referring to freedom, not price. + Our General Public Licenses are designed to make sure that you have the + freedom to distribute copies of free software (and charge for this + service if you wish), that you receive source code or can get it if you + want it, that you can change the software or use pieces of it in new free + programs; and that you know you can do these things. + + + + + + + + To protect your rights, we need to make restrictions that forbid anyone + to deny you these rights or to ask you to surrender the rights. These + restrictions translate to certain responsibilities for you if you distribute + copies of the software, or if you modify it. + + + + + + + + For example, if you distribute copies of such a program, whether gratis or + for a fee, you must give the recipients all the rights that you have. You + must make sure that they, too, receive or can get the source code. And you + must show them these terms so they know their rights. + + + + + + + + We protect your rights with two steps: + + + + + + + + + copyright the software, and + + + + + + + + + offer you this license which gives you legal permission to copy, + distribute and/or modify the software. + + + + + + + + + + Also, for each author’s protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors’ reputations. + + + + + + + Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone’s free use or not licensed at all. + + + + + + + The precise terms and conditions for copying, distribution and modification follow. + + + TERMS AND CONDITIONS FOR + + + COPYING, DISTRIBUTION AND MODIFICATION + + + Section 0 + + + + + + + This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The “Program”, below, refers to any such program or work, and a “work based on the Program” means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term “modification”.) Each licensee is addressed as “you”. + + + + + + + Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. + + + Section 1 + + + + + + + You may copy and distribute verbatim copies of the Program’s source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. + + + + + + + You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. + + + Section 2 + + + + + + + You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: + + + + + + You must cause the modified files to carry prominent notices stating that + you changed the files and the date of any change. + + + + + + + + + You must cause any work that you distribute or publish, that in whole or + in part contains or is derived from the Program or any part thereof, to be + licensed as a whole at no charge to all third parties under the terms of + this License. + + + + + + + + + If the modified program normally reads commands interactively when run, you + must cause it, when started running for such interactive use in the most + ordinary way, to print or display an announcement including an appropriate + copyright notice and a notice that there is no warranty (or else, saying + that you provide a warranty) and that users may redistribute the program + under these conditions, and telling the user how to view a copy of this + License. + + Exception: + + If the Program itself is interactive but does not normally print such an + announcement, your work based on the Program is not required to print an + announcement.) + + + + + + + + + + + + These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. + + + + + + + Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. + + + + + + + In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. + + + Section 3 + + + + + + + You may copy and distribute the Program (or a work based on it, under Section 2 in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: + + + + + + Accompany it with the complete corresponding machine‐readable source code, which + must be distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + + + + + + + + Accompany it with a written offer, valid for at least three years, to give any + third party, for a charge no more than your cost of physically performing source + distribution, a complete machine‐readable copy of the corresponding source code, + to be distributed under the terms of Sections 1 and 2 above on a medium customarily + used for software interchange; or, + + + + + + + + + Accompany it with the information you received as to the offer to distribute + corresponding source code. (This alternative is allowed only for noncommercial + distribution and only if you received the program in object code or executable form + with such an offer, in accord with Subsection b above.) + + + + + + + + + + The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. + + + + + + + If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. + + + Section 4 + + + + + + + You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. + + + Section 5 + + + + + + + You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. + + + Section 6 + + + + + + + Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients’ exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. + + + Section 7 + + + + + + + If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty‐free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. + + + + + + + If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. + + + + + + + It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. + + + + + + + This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. + + + Section 8 + + + + + + + If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. + + + Section 9 + + + + + + + The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. + + + + + + + Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and “any later version”, you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. + + + Section 10 + + + + + + + If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. + + + NO WARRANTY Section 11 + + + + + + + BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + + Section 12 + + + + + + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + + + + + + + END OF TERMS AND CONDITIONS + + + How to Apply These Terms to Your New Programs + + + + + + + If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. + + + + + + + To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the “copyright” line and a pointer to where the full notice is found. + + + + + + + 〈one line to give the program’s name and a brief idea of what it does.〉 Copyright (C) 〈year〉 〈name of author〉 + + + + + + + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. + + + + + + + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + + + + + + You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + + + + + + + Also add information on how to contact you by electronic and paper mail. + + + + + + + If the program is interactive, make it output a short notice like this when it starts in an interactive mode: + + + + + + + Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type ‘show w’. This is free software, and you are welcome to redistribute it under certain conditions; type ‘show c’ for details. + + + + + + + The hypothetical commands ‘show w’ and ‘show c’ should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than ‘show w’ and ‘show c’; they could even be mouse‐clicks or menu items — whatever suits your program. + + + + + + + You should also get your employer (if you work as a programmer) or your school, if any, to sign a “copyright disclaimer” for the program, if necessary. Here is a sample; alter the names: + + + + + + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program ‘Gnomovision’ (which makes passes at compilers) written by James Hacker. + + + + + + + 〈signature of Ty Coon〉, 1 April 1989 Ty Coon, President of Vice + + + + + + + This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/share/tutorials/making_markers.svg b/share/tutorials/making_markers.svg new file mode 100644 index 000000000..22d3a22f8 --- /dev/null +++ b/share/tutorials/making_markers.svg @@ -0,0 +1,905 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Making Markers : A short howto by John Cliff (Simarilius)Creating a new marker is pretty simple, just follow the steps below:* Draw the marker you want on the left end of the red line at the top left of this page, pointing left (unless you want it to point into the line when applied as a marker)* Apply the "template" marker to any other line in the file (thats what I use the box around the red line for)* Open the XML Editor (Shift-Ctrl-X)* Expand the <defs>, and find the marker with id="template"* Expand the template marker, and delete its contents* Rename the marker to something more descriptive by editing its id* Drag the shape that you created for your marker from the document section of the XML editor onto the empty marker, so that it becomes the child.* Apply your new marker to a line to check that it looks how you expected* Copy the <marker> from here to markers.svg to make the new marker available to all inkscape sessions. This is easiest to do with a text editor at the moment.If you make some cool markers, we'd love to see 'em (and include them in markers.svg if you're willing). Drop a note to the users mailing list, it's always nice to see the end product.Hope that's helpful,John + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/share/tutorials/oldguitar.jpg b/share/tutorials/oldguitar.jpg new file mode 100644 index 0000000000000000000000000000000000000000..7db5e35b54b6316d2cb81d897fa9c1757e026b40 GIT binary patch literal 19785 zcmb5VWl$W?8!f!JyE{P>GQaWk|dOB)aT1FNgc19*HW?I^}BJa4~^9c$HGO&wEe&Cnj z5fJ46Ul1fLEG%3cTuMAVO8z&rZ}|V8+e*rq!FnoEj)PVJiNH33s5fuj-lEqyuGIfv#0DM<{ygqk$2I&+Dav#7%u9a)pybf80;?gPOp z>efh*SS&-N@nwhVrQwDYy?s<>u4%IpVr&5bjo^>KR#t=Qlha87ouP>g0l zHsr(^#NGH_TV4QnS;k4+ zK~6qVY`cF!rjhqRk*?~Y%(#H-Fd1Kl0Pn1ExaWVP6Fk>v`Vj7H4Uj}@UMgRDTc*)0 zU@8vsB(7Bo{X~X zFe%km8(w$K(Nn4m+FxBsI$(l*a6O##`VwuFMtUEAwP2v;n#4_LIFtwCq^>@(!u&WV zIgyAvFuUVr#$h;|xgEe3ou-}Pn3Y{DVK{xr|8eA3r9!)dA<@t>hX>06x~P^gcn4b4 z@h-Te(+;dX-9KnMT^X|iot-nMZOKseyw1#;d>_-VZr+#{|A~zIUsFD1RIBtz(|)h` zf9(MmD*!ke(jp_DDbMzQwp>Ry1Ky|5#kmi%U6Pmr{@w{yRq(pJM?CG?%*qMigTZtWpnXtU0yz{dqL)zQO_k4$j`?~HN>T(qyB^9@xp{1JmNfUbcHjWe!pSWQZ>|H<@ z`uX>;*I~c#VeB{+OPWXV;8=r)s=R`&blS77rQlmT-c7UK11j=>olm*fq`+y~vL}O`&!9q7(DMS=unrju+5aMIJR?z! zOwpoNPC}?2Q0HFiXTwKQtnQUjyMf)A3=fDl!umYgndxC2S4FOP$5sapWsJwDR>fDG zO%@_9o1&ihxg9Js!;2d^aOi*fO9In?vW2<0`X`gE4krg)fM2tyh!v^( zl^~2`6!i*J487pBv0hXS*D-8NsoU0md~Vu4-{af*sOAggwz^O3GwS%}W=k-2au0N$ zj5n#nV6U*T`1}GWPBX{BdHhn^Zk;CVv*U9SlVi1`WCpmte*thSeU-9tRUXkk3*qY8{1sAUH4hSf zrisR4;OIXa9T_XXZj+J<-c0>-0&nm<;fC1|esnZFme4h6*Y`Gsud0@tw)-o!5$SBO z`O*N3limK~v>>)YGeSllAg*SfNfW@9f5T%8BECn)bOSgOaDyE6(HhnJ-m4jQG?b`Ya<>82&leuPV_EEB)o{8rbkQqF(xIoGuqBh4mt$BE)*t^{5>MXdDT}Y& z|B?%DHD9N&OnPg@)aG5Z0n-Mf|9@}qZ|;FoO;FA9E49w*Ak&f7Hz5ZJZBla8g;Yv_ zP$S^r#>%g%k;QbbPq0{FlS-e)VBBj6{bwQQX|?IH(;t_=2_YLNre@-78hH)LN*TLt zmP|GmxJMoWuEbU8u?)??@E21cJ+xue^8(5-2bd!lAPN{r1<)0Qr;o+ohKRE(OEoba)B zG&CXq2z2aM96W521@B+mmu_W#S}FTtX{;{FPfJdLDu|#@G28K|J#}g0Pb@w=<~SB8 zK%PkUSr#Faslk-#4&`75UB;+4=2P<2^;Bq`QVhhXbJO(^3^X)-x_nN#jxj!Y)6wm( zWBKtRYcE&3!>%8c4O-ox<6ag=sX)&wi0;)Pa4l$pPyguED(;p>sHVnLXw{3^>-2k! z+vZ5R`2W}tseb6yC%&2=WLy2)>XKk5N3hE=%3+Q|;VnbZx{KyY>qK6RRAqqyxxA`) zo5eWHL@*5rgXBaE?mCWHHreYRT(>!X19ZwKFyXK5mYNbJA2hc`DEzrzC-cTKaTbic zCL4hpPow7vuYXr~cb+KjsjUo-pqV9>nn?;P-d=Ba>U-#+jgw!?`svU~aL8E^0Q~Q; zFAD=CySA{c;W|$-?)(Zm$|v>zd4afYcRgyk8ZB-gYmRX z6b#K0EnOzZ;wtrHa2cZ7a`9@=%vb+zaPKVK0zJ;u+S!2O;#)i=iO+QBF~xVO8%NCk}W0^Bfjl$9FhHG?OLh?SO=%N0+X)PgD9x$}C-Hu4XpyRMxJg zRx6{ib0=LokFe@h*{G{!Clf&&8&So${MlvhPWtZl+4ILY&SbI`@Opwh!^vT0!%auv zr~if?KNJPhFyliM@RxN#EsBNZRLQC?9;Fqq!Py zQLHE0R9dwW4n%C3s#bVMQ(;?sT?@sG{N71%2X3J~$kJ;S<5`I?%l(2h_O%53p(L!21Y6+SO^UulSWoYJ`g@M$9=9<&P zb>K&lsJNeZ{#}hAyUkhekkpAae{-+n0#6ifBiBk%3(~jzG6;;i6T|k7lz7V6N4>!= zFV=Afg4C|XhiSnYYf>FJ(n$b80J@D-`;Xv=Srh{s#wx<@A;uo`@W9i_KGj*i2?Fh| z7l2@1Tg&AGY_>Yg*q0VPf zD@ZBr7$86w@{m1Q+E6pfT_QIMAHZBKVEM z*Qb)~k1+e|Q9`Y=L6a$2rDR=zmZqH2_eZAgvk5EN^HxeZ$v;j}osT7toOT1kByda# z86ijWN6&kM^kMFub)2&W1kIBr811`0u7abPHPltq0m@aqMV3b8o6=K(a9LrQRcoE$ z`fHts8^KjOvX(p7;n8xP#=PWWXoTmzsn^>c==%a#SJ7ON;>$FmXyDo~ecE{}ZCSh? z{Rt&x5NOAnczk$RB6`#?Sb-i?4DsnoX?0ER!04N6|)9udu{EaEisO9(=fIw26a!t)F7SJIvK}`Oj42 zN7^x#f)xSU^JTDw(TtOy~9sKwWv*&zj~$)4K1EO0GWlqHjJ9 z6=wqU)B0NA(%V^{ien&wP{alDZpmRW2neP7leKJWFC_#VRTUlmrcE8jmaohj{IA*viD79G{sQpI%g?WO5`L81 zz;YQ6uufHM3pWkL6AvLRCt*tsJ#4M!K+eP7bQxy%1KUn5U&bD$@ho@v(sPl~P2ET{ z3-R~5gFWUPjBO&OUusJlY&`t8iQ3!*FG5eQ3Z=_o1)>3 zWorng8U9FG3Eem2n;Q+>$?j9>Z*?3%a`IQmC})~RmmRczJgn~J7;8|_D2oc2tMVT% z+&&WWto)F4KYO|NZS7Y7$~@Danfl*vcSb6S$>^fUjsfjitPzA$4fKbJfG)E zLkg2m)66PQ#U|{8{@S-4<;JyC@Jdu0*<8i8Uw7D=IOeBv6#3^m0X4Rz;G0P;l}l*K z*jP-O$gRytZKK7N3|!HGB$*^FDfnm0o@>d2O7H9bE^GZpPIs?JZh^xlRAhUvNfq-m@lN}kZj8~|q!WW^Fb`ni7|SUq^H z@fN@%dy6KRFClu;YOq6nWzJ85A?9)9F9bK>Ik@t4N{>@oHySyUCgcTBEroOBLs92` zoP^s>`FNNL;#!?y>+Wo*Kz}Z6orlIMd9x>4MA1fH>;?PB4L9Q4E*M;=U4FL~PiQwe zvpo^D7lp+CKAvJ0bPD?YAM&NU5X>tud?3!TiTpmyW-EUfiq_NO zEilNSR6J-VC6N1X^P8V{@oAUQfcMmD z+6048&FuLS$NwT&gnI*`@#X2>DDQa!S&@+d<3JPX+knc<9J%96DU1k$;zZ4T)1WSz z-h<|?>&8{*7>kjbOqlO-+jgJbb>VxNEVOvZxAb~Gk%iC?m}O;FCr{J9*JNbY@oQ}9 z!JN%mqDkg)r`z&vZBb_O{ue}iW>f<7)5XYtlW1nAD{GdeKevF}Nd$Caz+4e(PQKVV zUq6Pg&?Rg*R5PetEVX^}4<{D6T5AQKsWo^W-Pk1M)9uz(H~Faqicx-hGkfFNC<;+miQ2iTwpf?C z?IfLCkF=ur#K-c1Kh|8X-?u6GssR*u4KdbEem|_Fg~p zUrRODqpHR8cn@ZmSIv3#%8oTqFo&Hz(!|SCL!k zkIV_h^?5uLn{mb>bVR4hS3f|lq$MapDbvE~NBxduD7(y5^f8=(Js^x3TE@QCL{<7Q z_p#uSA?{k^s|RL8Xa62N^xhy(yyLHTiXkHI5Fd2qbgY)S1|u7I19_nTU6>jby38TC z!xnD+b^Y?_m8WS=>FICGxO^K(#3uSc?qx z^_awE$#fi9Or5DGU-DuU<;s#)d^S_uWRvbD5Zq5cZ)ZrNa9{p{GFqnU4G!LJCG;!ovvqDef8+%TI z8BM6cds%0scn|Sr5$oexx3S$~g^FMO1ja!JeQ8kGN1n-W@CPDz?#g3TE|o~iyQzTG zv5v!vSp?YthECg^jDXp0{ffsg!38O<){KSfOY^Y1j5L7AukHlHD@aJoHaukhQPyjJ zop5`l)s=oVdp-f-z9d+yE1~(I?lt>VG+BQiTzoJ{gW$AVvO+OU#;A)zQ%w@0G*gG1^16})A_%C%drNeQ5xE(5bnN|D5(m*7U1RaNJVwJIT86n%Vs z9=WL50RVjm!F+nbq20*F<>-fv$OdQL4bI5~QJ3WxKzy#z&)s9Qn=8-zh0>M?CdYS5 zSCaOAcU|34 zJ3~S=T)p(0v!mKU2xc59mO3fTv1i~g>VD=ygy2Hz5b^)Z0CEzhak>ArB-X6i?1U#Z znHaMNRThum$aCy(rZ57R#Sf56AHvX9+t=N8Am9XHAFb?=aI)4ZD72rW@mGXYO{B4 zZXrp=Rs&_5x#j#9=sdbao-v|0H=&mTL)Di(KdWXKTD+-U}ci)!f}( z$#u_2E3%xJDc?nF=WB7`I8u_*r?FXWBiHBR*A>^dygIDB{j)^Y)o?R)0+z#9?s6{F%p*=ua&Fwe((&ZnwOmTT zEsizJxJ@Jfr_2;-w=tj~QJY&UJzYN_7-2fy!%RYb%qC~Ux)Jo=&_SU4#Hi(1h$oo_ z>`k*z1x&vCYpT!Dd(Id=cy?HFvu>+)Q~+)&Rw5Re#^aGVSFNYL(KlI$tN$iT&ysQ( zomxT6Pz5&;M)=|R%gnwB3pIra&tLs^Rlm&!kTs_}?s7R3tbh8Iu%pY1AKafgk%i(h zV3rgz-q-4Idc8=v{)21~=w7BsQsNDE#;;hY*+upk9}IM1AB%w|Unnhh;H`FR zWDoQl_3g{HS~CYl)>msaXtwHcBFK>r02D=C(8jGADZ<_5z+u3R&g8?p8k&*6KUphw150BH!nB{Ljd(t-Ky? zxEqPvkWO^_ML)6n*P<2&P#^Rrtd)~u#q}fUv-+UU0%yv~pU3)Fo_E9pvEPccA*!HO ztLd~@eB%Lp!y{X&tLofhG0+v6(4AeUkh268y4;Fby#w89wXi96*Bs5@8c4jP0qG(m z>r}AM`n`@llcD8=wzFw=mhvKs^v}80?FS(xv69p`E>+0>bIe(jjYez9ywXcgpMx9h~W>&IO z*lKZYTT3(X+K9%*qTZk7a!48z(%rmC=y&QgjTwF2qinnR#5bj~)k^(Gfr@*}8Bd#F zk6=fKuT8b_BmXrXe=b?3Ipi*`5DVFlpVi_OzzGodY?3AAqC3E6?4heHUrhVU$M_Kp zbTPv47eR)?T}Y$RbrouVP3(g0SrpL&l}Yq}#)_*UAi|&K%QH(5E4Z=xKZh**@>>ri z10Qq?RvLo!1<1Y)jBL;94dR&%RIfX?o%@#mNM%vFpAyv~d|Oya$I^3MUY(0xFjM#6 z7mpm+cQkTiaVlsz->!bK>kFX4%%~j1)3m^-oTK=mvU@E!oTy4I@9oX2<_aheOzcbB zMRjk|7UEtZM+Q5sbcf8njq><2-Ir2_tno0b8zeL%fU;c3vQ+PCI>qS1KLCjToUb@& z;`Lp0@spLoN4#lbE9xHesJ|?|jy05n5&w4&|@n`nTgp=fE|28fPQIM68p2 zEzuF2bga}1;zH52njWm*RdBX{KJ4CR8-erslivgWp-)K8r!>9+ubkz~mx>03<|fSo zX5EgzN&@R1GeVZ1C0+nZOO!X@P{>?=-r2kAu{szq*!h^<5L&pXuJ!SYasN*1AMn>! z*5)c~NUNK$GEs$Jg7K_Xge(`Shhu$%>?VAw==dI(@3`_4J;VzS=4wpGWRi5?h*|lj zGZkgeF?y2`(NAg>l(K)KWULD3M!QA#Qn^TOutOn}1NM)jQ zcK5SxrLmTzx3m@0F*}?XFCfBsOtKvbaIHgLhn?~7r&B_>ZpGqpAd;##xeUusmSa)$ z`lW-hFf8Wv`D|4*;_D@V#Bjz@!Jj&DFfm6 zM~2icOaFzp6ICS4E+p`>0WZuezU9dBb2DHWs~se8D z>7i1b&JBy6<_YM{&AhCeDi~(~j1d^G1djS>vmjgt(Sg)46WK8bO8XdrOX-2%N4?Jl z6TRSNTB1pl`gO0rNxam!YV^LkP7p=6aQh7d2Zj)WgtN=l5%Xv#3M5&nFZe#AJnUVf zU7VOk%DxbK5&mC`?SvNq_47~C5n1vfL)`XBzY{YmdiVjFTp|QHWs>3EAwoElJduD) zIp0b;%mOej;Zupf&|h0ss-NQbH_Wf{2R}Okh*DqizA(6wgXJrgl2}iuOd)D=+gHSa z11o&cr+xv_nTU~!baE~+TZP*>2Fh0Oif~6gA_$NR-Avvz8Nysl6~|tUO|T%F|3)v1 zE_KOpsH@Ugw+V@09|OQ==MR6$jBqrAsKUx@B@Zc}g++|vUL-BtFso)UN&*(1!8IuH z<35ntx;A?JmvdK1xK;Vc2k2-v_+Au2J3BGveq9wW!dbp(y$P?gTjsbUltJzk4pB{A z4VJJ;(Na`()Qe)zIpl|gvU()~n5>%e8M{}eWgf-VSvEO^X3y21^LLb{zoNYW0&Z?= zull#nZ99^*Do_a-Z>s0528*nc@eSd@@0z!qe&k6%n{|A+Xj}oSg%oD-yZ>npb#p#E zk)CMXOg+2cgc@4sk!2hNbG!gl-Pz63q&}jYGr@9s1xa1w$D4Aj!S>map6lGBuM zCHs?=6z65kU5ux@J|CMG>c=CW_n`D@Jq5HGlH!ysel7Md6?Q<#WOx1W?tl&w(ICkL zV>izpFd2+dc=YZse-$MkU2XMPg);QhhtKC@Gb=NW;tjDkSEI(-Te|h%$dRU$`JvLm z%8T|5EJA+*P}H#HW_X#`ZS(+ya)+5IPfkAdbd5YFecaXT_tBF~^E2P3^o0mv1Krn< zdAB_de7SdB{_u{>y?|{$5C=W=`4O9a{8ie2d+&85di4V5mR1)t%c5#LTHa*;wmv2(+w7NB6+L?+0QUNDle z4`TrEn#ry?JjS~xjZLbwd28<-<-{S4k%0oPGE3&(eCN*^G$B1qn&czWpaYYu3Ms`J z`Vp(8W*gT6i--HHyE}O5YM}doHOo6_%FeXf*u%Y!b6aT0=sN}m7L?CDv_3C@)kD*5 z+x}lQjdNB35v&uLx$`D&?coQoxL{uTkXyvYB!fw@eXC2~S9y8`r$C!Gt(o~=gJc-g zXqSb*gozX!`S8~34A1jcYt9%{u(Rc_KSKmb#6t9;3gVw;$EhP3dHx6)iAL``#daTv zBS^Kvp+9iAlGTt%F@lkMC?e8l>dR>YlnZg2Q=^ForZ7dcm!rwm|5S%b6)}8KbCD4j z;l|10C4h}mf8`h>%d^5-2}L|P{!=oE+q#`Bzq9npRif4MT(fJsiB9&_Zp|t;q4@GS z{~S)D>@UTQKo`+S(*|H(K{9;?B$=)l=ZS;;Ih#Bu6zg=Fx?S1F!XyvzdL)#>FRKw; zLW}&V$SkwXc3Gc(%)%ZTO3yuz%qH>E1t#%HcWEqthlu7nOA{VR?x?p^>Yidtj#bz3l3spK|=@TA#r z{t-j7k1v2rKZsNi%H z)-(E3G*?POTG03(ou`fe zQdw$Gq0-Feyb~_~Ec3j9j>UPxHZuFT!(Da6;WF8IT5(in3fT;;kF!VzHVM0Jaxj`v z0zb{RbN@=j@KE3wvo<_rwQ4uci|#Px_)%?xleA@HVfJt{S2fPgw>n}H zd0XD>dob_EFHf{VucZV1&CEOI3$fu@7=cqCe6lbS+V2DZm|CDL{xMb)Px@{>{Iq-{ z^^=h1I_(E_uQJiHbO}&BSvVP!Q0B4<_gw7P4Pnpl>3|KRf)ZxxRgauK@Sa@iuc| zKAhZPYXX%Hi+IzZ);XJC65;{g(&rnDx0)eNeyP(|a=&v}b6k^IT||_fP~~2^t3{SW zlo_32mGAhjiAptD)RF!A4gV#g=S!AC28~?B zDL86b$c>QSqB++F2Q=@>f-4RiC2|y%a}ElkHL7p7)X~xy#Rz3tkpEm&Yfv>fFb=wz~nBdjpWfvl24C56$FZZfX9Uu54q6%3$1gy6t*fJ<08Ju~u}t zuG{Q>Y)#Xe_Vf81p2iq>16iPRFB4Cj1A2mtndW8K{lp>;b+$W!`X@@zxMUA3yaF#4 zU+eYLC#Uhf<^|1<5g>&B7ACR?vRy|=4G`+MDi-PTtnWoymvOQPEHv*0zU@s}8JuXG zSn7)9NAc$L>%Mad8(f5*-5FG!)y=jVq)(`A-l_zMdb$(h9;nY;fTQ| zeWuB({9{!goILgdNb4#=b23d&nkba6{+v#)F_Xrc*y;iM~VI0$r=HUW3?~Xc-ZSwR}*(G z`!&F75}J~&Tfb|UZDW)er_wJucB=m7g_TzqNuFB4!UN~RdDX6_pIPM|fReF|KFI}M z$=~8655_*Ird2AMmBQjDXHMR<{MVb6?swgwulYp`(X2P@3G#V!t9y73d6u-mmRouZ__W?7TPTxF>YUH5=v!~I ztB-We7%KExT@Ulq;mTsnx|@F*>g8F>8*DIEemjb$%p`i`H0c~*LnXtc6fTtg93MYV zHSts2g}I5P0`$8p$q666-XQ}G&pQh=P;+lJQ{-=;YU{SMfr4z0(jOKm8v_ic1{q9) z&1vhe+mRjXPg0TN-i@Y+tAc1lx{Gn|1{=3Q<}{jCpg8caC_&dGk&XS7)-z@$m| zci9|i7C@z?=ThZ>`;TON6ZRxrJY=OlgNInx&P`^Sm;z8H$JT32AHeW|={_ zc^4FqEH{@Ghx~2I!JwXj&K=|Nxp)2=*=a+OQgas_Yn9eUc4)0k`yynJ77|9>dP{ztv}^8)U;sO=KOKLBUo!$zX(H;kXLDA1w& zz=WQ2SBd|=!+>cH+Cq9#g5L{rbl^Us8Q9S4Z$r+Im~YG$TUQ-^lifXot;DsVcO`-X z%1I^-8S2F=S~xVA&yE7#>t8wrRKLd+$w+CQ$Zg)Nt2+&di#c@XLT&E;KGzJ^yDA+` zjRn;UjXIOr)J3MSBwJ;9+iuX=3yll?nZ(=lZky>g)x{t8FEeL7CK}O%-%q?>eXv^ zMYF1Sv#5vI3Yn_8RdD6xi{0kY=O2)4WaWORmqNBZ0w0CPUS$zfSv@tNB}q)+m*^sN z2h$;@Wy!8&=me&d`vpX_{4Cv;EP*KIYn=TeG`T5fyy~|<7>=kap{}(v1ug!UQcX26 zunZ87(88^K^>-)U7eMc@<_eKdARMfw*Mx;AqQ3La|)65?Aa3k>8GSOHAD-27lw z?pQ-HdGxbZedL;d4ezema9P=zU9~Yub(D?}!RGdkxi~%S9DJKy{tJ}bGBVgVZ1%$~ z1$E)e;MocHLf&LIZ4L14*{- zY!7li&n28*%Y88MMYQJ1a(sk&{1=sdGlj?n_aO1O7l7O13jpToOi_UM!GICaeJb2{6c=FxvyxnyGTP{m_Ob_vNVXklg6GNn_twCV*#pa<1FU?X%!K0&g|^r9KzgaLg|{W}Y+x|88b^m~bgi8HSF%YCx2d*($VTNvLFz8-Fxfu8&(S zJ^j$x*J7|;NUHx#{yG=EpOLeZ;wNjQeAB|}>-v=CfQ*0xSM`pO_}iGj_=BfDH5oog zsb&yjf7ik9QxIkfqRMdZd}o3zXY;19cLj@~#H#8~4Ud#`&gHS+RYg@gVXEw02xF7Y zKM}lIRMbx$>myBve7j|$=A;z5(v^ayx^dBd=2Wm(-g+_Y7a$RW<6rSE)SiH{qy(q) zV)%X``HsgRy=>b01D9M9b0#W1r&`2+D@3e;`ma^9W#%pFg7z*T-D;cQ?V z$3F7{c>VvM?-B@14ZP&`ttbJw72&;_LcQbTzNf1Szado``SP{zH3PQU`IdM3{mHx7Yq?+NYyG(*HNa%S4(;~DaIBoQta*%= zegPOizh)_7EBSgXE-*(vg{E13=daFTnpRFar8%x*uH@uD>EUO_SV>t6)NK z=}U<(L^V5W^lY-hNWatq`u)1tIa}##&;@`H71>-(vYh~7e3P(0e0;61uH~;vz;J^- zb9Y*+cO;73xX-h=-O5R_YTIS#*o=5z{~J z;>`2w>OeT0*x}nPC|Q`lVgE$8QYHUQ~{8lbRvo?$) zADR=jr9@(EvxDDji>UnStai*nIPFV_QB5r&3U_&WSF6nJE{_5oklfd5)^}OO#>5%A zP$wEKUinIuafCc@#T3a^T^5t;A^nZ6Y)_xWgM2I*nE=oIUG0bt&qz(#2nI2!1QnNX$!D8Ul(hue|HPyjcCF6@x`6d zIhcLAZ96BYE{#9mv@0o6pWh|zvaOWn?BoiPx4_Qht}$>RytbUlm7mGzA9_PJDNUcl zcm7y~=G`WbX(N8*cS$yxNoOyS+YdEk^c9Np_(!+@a|RG9WTO}3vSplT{knNVJBgAI zD`{Vc6@yQviB0jrK#jKEHel-oFj>KTVwlr@VP34_LV((7cy3lrC)MUo)MA?sJ`M`=uC0evX1wLyDR1jC-*V%anl|6jTYuD^ge zVnj>}@6Cs&jt#L88CdqfGZCcABzg(g`98~~(OSNXQ<9mfN_ZsuGSF(t_4e*##W}Ai z$0}!l;#pTqah7@v2+<`L1sK?BYKadtPOPupJ1<8r-GNSb=botu(g~HJ$+8JiVN5Oj zm=wxg>%v>3CVCtbj550>n-D{BSN&UVu14^?nHP7F?l9IwcKM5#q8AOGn)YUzpJkJI zYfQi5&_4h28I3ZAE&HVqI4F;k%I~>PaB`@>9k&D&A51Xj3rVN?X=UqHEg4(Wv}Mw! z#d2P>*zeEZJHLN8$osj$tHO@`Rfrn7Zpzvvi(z)U5zl z0dakKpSXV?WN8>mNQ(!VU)>(uno)Oci+$ALjeu7><=E%}UplqRr>jI%a6rM4-^)eM zLf1WX9>mdPjFnZ z%j#K*jAA_IKnT8d(*}yq7Av%*)zhUtm3Y%lGJ#iq@lrIx6^Q5BeP%hnFJkwvB3dgx zcw_?OCc#=u&KXebQ;pq9l?=v2nrWXCQzsM8JN;qZOGr{SWhX4K?_l9;B(y*psq4_Z zhIXD;$~V=3iL)pp#?!p-g!cZA+Vy22X082>Oyz$kQh#LohI2!_@M!@U>;Z9@-)`Mk zuF}WR?zR^|Y=VEg^E+df)IS zd-jt#5&cQ%dz{c7@nEa=iC>-HsE&>8FhKq%8hT74{`3|chIRON-k($roB6S zB}8a^iZ+ouBUGRfSXUtjoRW_lCNh@Cn_Pa2gKQK1#(25HelvSMxfn4vg6uE{VToKW z%_5?$KhRjIR`)2WKl7dnFBlv1t+Ge9s|S--Ok=EN?d>-$vzZ&##ovh-bDN+QwToC@ z3C&PV;@bM{{O}DNn;0-EuDi;tQOoj=)v9MXQgHZyw5TN}j4nb$jW13`ijA4*KpO8r zOAW|ViK8zYvT>Cy?Q83@s@wS=R$%`Y!bCk8mmxP?$$ikbi!|(rB=%V=muXY`gVr|~ z^y?dxMR_gzPiguC1>Wuwv^!^%eB~h!$m1`>bb~z(4$^j_pI+AbpglR!Fdmk^MGt|> z_R8;B;1Dvqs;nna!Dc5;$AT+9*wS0BxSKuwx+Gii>cm;<&<@?msj$0e{ZEtvEEO|a zPVnivf;-M#XZ{J?F6MK8VX`v9SH&R&SFj%eT#`*}trT#au=LH7I@zXCQPZh~iK3@x zmi#iSsS`uA4{xr2!oPdw>;1xUzPH(sajD63TO?KgSE>(RX}5uTDYgb;VELX?$%4zo zfT+osb^-_47h9N2Fj(j~NA~MV!tdPD35rNSIaA<_YQq&F5-ywUO-WQ^_AzKtw>Xn7 zfh^Xq&BQJ<1U5ThQp%kyL1WT@(jan9_U~*P;uPWUqEWOrNcLyU%S%qSi7~;PBb*zK zi(F53Q=&`%$B4t5w;CXm(;6LW5#EoiT=;4gi+%n zPIO%i-q#!R8mpGWa~uf{4d|DeH0J}*nXS#b!fi_a5)-LKTt9L`?lhL(an#q-%zvnU z0Sss~UZ4M1Ixe3RcO|o{APETORe`H^F!@-g$D@->y|tEb&kFC zcynt{NuHyX- znxk5gd<9e!bY%>fmV%Q{^=*0vN8Bj2ua~>1wl`1n_F+TB1QdQEg8D$eyc3ZndR)h5<2FS%HJfERgc;bTPYY()nk#D`9_ z-iJ#4B+y>;J<--s#;YTOk(KvyUvtu1KD?6u=*(%POtu&`T$~i~IeF5%F=}LGTlR}$ z&d<|FwcU*=or!9J(UZ1n4Rx^C-vMYTg zmymRFTOU`2-v<`y+Mvx9bEpUd-}+T?8^V>#UiY79i*M#yuVldu2u@tKx1!&sz6fs4 znx9BsZr-@QpUY&gnK_2=D9v}(xA`;t{%livq^KRxKV-fZ;Y26QIGVBGOuyGLcdbrT zV@<&VcaZ$qFM_AVV+tMr%LR~p;&>OgYo*@pTk&6vq&z##u{rzVF((C;@pT2({K+dP z|NLo%QYd@-iEHwj_j)IX{n@BTBF;qbnPcHxCgGFcjN@-aw;db!?0NL>6QlWXS8^|c z>!|2E4Z-g=H5=>Y1)LEuwh18q@0{(}r299{5W&AhE=d=aKlrjuWmztID)T>m;=3%T zPRBohS6r2s)^hwAqSZ!4*Vrmd_9G%SK3i%aHNl9sbDo7qPX^&Iap^c8FQR{Cc*QijSPrPFhr3a8w}RK7$gO;#G} zr)ADD^DA@;iMiHiWD8W3?JCW)WQc5wBoAQ>nB&&OzckPf#zc8!f13H?O=85lW#hwF zaUh6WwYc3#oagB#diz&h2j~HZz2vfEfjf2Ph);TeLRE82!G5{9ykhK@xy;P!b;fK@ zqTIyXo!rgcsJ}b!#5?%V-4p|@|4-wmnBfzi(XW43_9w>e310BFIG2HCIwk2GCwIa4 zu^&0i`}!z$y1$>j$+}587=A~(Zy)Dn7G}##D?UuILHeG((A0adJP2Si>b_H%GH}<% zIrX15#Hi({x(=U+iuo?908JTD;&h=1g?AQu_fwde<)T?Clb}m{4A+2neRuXS1-JJY z^o`opJ#g1*SxB$q1G#iY$ScI-781&^i~$p2+h>(O6BQws@-nCw=+R7~s-d$vs_V1b z6i>Y6eusq@s;~QLjN9x347)w#6;nDGR3@5KweyIa{~EXb7#jH4B9?WwTU-&To3%Rm4 zC1xl}lUv=4eU(Tg3aDe;s;Rb~k54Qv4~K2qT)t&qgn@Y(BBE?fG$%y?3%lXjG&!q_ z*zw`%8Z$6TAs1+i$R_{=!>Sw-t7_f)6j$a{c9U%~rM9AKGmwU8PMTCHEcT6_v46~DCp2_rAMFzu z&=jmBm8#u+UKD^1PC3taV-vp0R|U;arbeGIM%R%;#YW%gY#bba45+Z!g9udU$##iV zHdu-6RlpwPWHDSS5t6`+RRyzAe*=f4o{Fn#H?^3Eb8=J?B9yagfuhs;xTdMY3R!dv zrY12JXkA+S=g)WN|6c%u41Dt|Ie7NC<*wEi^5vk&it^tbj?*YLn}Db))sIUW+0Sr+ zJ?COOR{ega+1|C#ar4~Xvlenp`J-n({{Ho;m7Sw4dm8RF<6`<0bvz#b0M55A(t&Ug zVs|xJHsa2}M--$-AdWd5>NMtthMEN=9z@MuhKU40`cy)jgszsE6jMU|C>&=%2iIyL zpp!*&tVD4@GOG$aKe}JgP-B2PeSnIrQmKU_ z)Ky0fx0(byN%o?+2^&!px_3>x)i16!ouhYi!jI=os!o4Ezl$Mv(j(_u(-Nv3Zdo8) zMpN2EROzEjlO%6IRJit;Lbx&oHY8ijdrk@8)K%L$TVY+ZbhE9)w%{J#)u_!(wc$Gl zRw`q5t$S%c2{~5o5F1c&3d6R>q_XzBor9T@Es=CcU8m)>Pff-4u{kr&>jaS#AIhZh zue+{g2X!6ef*|u*xVJJBBOe<+&xL(ega~iqQ&MAemh#B;UWb=~s`5?yM9#Gvugp+W zo58pG(_l=*9aFVMaWHicx_S1h7JK%h8zw}0)CzerH=saC+)zJb5^99w>qT=gP(=en zPdn5NStckr@G2?xfKWb8Je z;(3}52V+ET{t(9SdP%-i2fuK#lifz&&a9tJrFB)e;M{wRiWKfo6I~dwS7)PL>J|m} zL1~GVBe?a7U28-P{2hJu6lDf>3~M@F)GMC}XD!2_2-6eZo~>2Sf#m2VBi8Z;MiEtd*)O=LBjj-OH?qfX<{?;^8F zwLW)2!_S+T@AiBA{{Y%gzola1rInb@>DgU9wB*|$c5%9&twxZ86+WtH9ySu2j^cq; z)R6`~XoWk;21Nr20D4tdYXncF5Sq_wib7|4qk(}?Ia_)wh}ALLfmd&8iv?9?ZNVan z+jR7vn~S&iDf$WwKBM7)YO+mVS*nKvyih4S&^djClfa@^r(xRr2T!q%cJOTlC)D@+ z>#n#(KUlMSBd6U6%NoNp`U<$svv>!jb*ok|QqERZmQq5HvOx5wsk8DvEVhak(`qAa zY=|Sh(bLLV{4-h zl1`r~Jo;0Ga%;pZ~)RzG&HcY z)UK45P+C4z(3592%UvE~kMBz=L9Y-=V4#EPNgBG?X8N-DPNL)_Z&+LW&k4=I{*hY6=7?kbt~x1 zEa;BT+DZCTbkYt*i`dtEJNDTe2?4v+K!KoH+JR^~fx?P-8;z(Ws|`J<)IC1&5JumP z2JffaAKAFOH||sP6drCEl@yGeII4vk8LBw*28glfxZi2&mJ>{>uy)^I2la}jdI^6J z666_a;H6vlQz)xTS z+NHB(hPBr)6qx*~ZFJy;gwFK`cyM<#4_$~G{xuY^rAX2Y9%|?$L4_nxcZkct)O~89 z>5$9af$cm~Voj{a)Cb-j=Cv|Q6YO;-LI*3{R-|QOx9sGofhR}J{09u|SanyPf~KvWW-`_yU;Y)pbr5kcr3JwNHVzH|GO{RIb^ zFWnVm6hNo9dZ|@*-2Q##9 zxQ<6PcA6g-B- zl@dhqDX-Ey66wgWWC;rs?OL3bMb!%%_dz=Y1A4|pR)yNRwpgk-P&jcw>ILsnMYl3G zqeBBbQ5%k(b-%MQIQ`0h`ic)dSSX{~tY(}V7CY5K5+mM8xlMGzE#^9G3ASQS@V>>ZUAG?f1O*DG=Y_p;65txn+fQmCe9gd^_Nb=ngSycO%O*h}`iiPPE>+7n2IE%o=+&u{HZ7a} zdd0Tz{4%6)cAC}Y4!qfVTfzaPM1cekm1@t@L3&m@TE`{%KD5GcTA}JfF5D3iO=CE? ztA}dl+o%*!JaItp;rF0&fdn@ZLLLMtAkm|c>6#6{PG9X>jUs(!ifJ)G$&scus3c=$ zy_W&l>Fj+zb*YhLXmRrwN|3%|_kizRCTx18DUcQjwsbH(RNFk zbwmmwBoPocph*M(Py#tLLy-e&Z95KkpjB0mx<48O2`wCN6;y>~pfKj58hId|D5RL6 ze4R7B5P|^Ul4ztbIpfgKAq)iR+t!M9sa-L#qE!3~;?sq=+zDTmZyhsN7B8#nLcktt zs|a0fOIo*bBn^#B`HLC05X2hux;v3YcN7j33I}=zoRFjRK~&mYY+V-C;|-jXu-dJ=YO-4bOBZ{(#mUCIG zs2X*t;PVx^lNKf%j~^ewBoM>DV_Ua|b;^qRMbbNtYmIb)#YJ;=^r##vg&XbL6f z{lG{b)dH&!A`ZrRs?k;zw+0U;Xg7U1U;8f;Z|+n70Mt-po2QUt#p7?g{c12KE<0mg z@de3_&_w_`01^#1@_1sDX6-jDo$tpa_B zjl5s<{{UJA7-nb1{{T<*pmD-2&B6ZwkM*iM>?D7BKk@#x2OKh^_n+zhwAf(9Bm2+v z(_s!F{{S=nG}!O5pYuP{LEmK~`_Iez(0AF4eewSQjW!x_$RB)v<3OKhAbtM;%7KEx znb-MIOW@AMzbX!EBrss`epE!Gv=OoHYWpB}tP6|cYJ>9TrMpx^WP=*NDuH|h{x8a+ zyTL!=AB6*jqy9h2sN-zM-u$X5%V*0vzbc`0X;wRa6-L{q+>V=y2q*R_-`G%p|Jki% BkcUC;Gg_kBOV-}Ae#=XtIt+3%RUijtNR001f; za94i-kVDJnjE(ZLv5cL3Tm~rnd7pr_Hw$ElR4Q%f5Zmb>mjtyVl`${?U`u2)3&mdIU`fm{xe!65<|8kR1@%gD9>SH=RM9ROrgZ%d^$SOBoYfN;7*T7w4ws8m8H z(}{K%np7&m*GRDdD3OWq038m%;dGg*LHM4#mIq{DWC4}X;S3TKz{@0XtSu2sr^&J~ zn#*dWQY?vx#ei5_z|I!L0#G{u%4nv+0e~*4fdex6T1hgej7tZxB$>X3YzqYdJQ*Y7 z@K{?YmjseYAVbDtWbMc(I32#W2`s(Ljzp}%!{K=R#|w9A0bo<8hpY36YiB2NZ`0_9 zwkH_{eYZZW_?>>WpDx|iFZDnnD>As7AU@hxKg5l7=_w`fgDD!5r~P(XY`v48bW)XB zoYbt>>pgxW7w4@0zkux8?8x1Xd#_XKF5X{>oB!Zz4@M(udK#Tjhg@^9YAn|d*UO^tojRmo2>e=Gb2vnE zbHlCNnZSKEA--(fLis)1U}NWRZ$3ipj~&iieV~xwyZH#3;EI2tl}DQ5V8q#u?>?b# zCg`h(G7N6u)g2`8I_)E*x+RPE}m7ccQk zq=Lh>ryPP2_Q<;`5s%fp<5q@3?t*k{xHH_?BBuEWU1Z!Ak9$po>z%xb#m2;kt$cH=H2ZNzaNFPIkeS% zRSy>aj>?*!zC~&1i$YfBAvf%YZFLGct!H|9E`OmZu-sMd@oUQXTQ3`iwzc-PPNbt# z^ydu%$S||mQyrIRG+3XW6rBQ~DeJp$t#e3ZJ9H=f;Q%QNCozr$d zz{3CI`WZ1R_9^vfN@=E&dfkV=MP2b}<(-AG9!jBIgqVW)J?3Mi{*#S_9A|C9(m;^r z?I4y)@`Lfd;+zjH?+xkVBv9q*g>w_x?pR$$skaWtId%`+a(d3{5VE z>Z3%PLTk`kW1rM-W(tiPenv_O229){ZC2bfz1wX@E}LZXwTW~PBA=+hhrKC=-zzAz z(MSE!__y}rYGYxiMRxY)b2)S3E71HuXT~p;brGr!(N@slo0P&$O&^udBNt0QFgLyS z7jV673_=9b)B8_r&51?Ve@%Xec_%ZseD6|Jo8WKzPfFEU7xk2 zqpO%_?iOu}^KqOT3RG1UM3%L0XV^VaQF>;GTS;aD#*LZWTVTI^*fVD!q$%ueO zG5f$JcSMXMsP*@4T(kESkAOq|4VgJv@&ZWC22~X z2P&*V>K%XxjjYt;7-;{NrOAW-*;OQ4q1FZW-00xf7X?e~;NwdnVz&dTR};#_Zef9=ME^SyD=+XO-tku_f- zSP;^5yIfgl7XBOJzF(_$yR^Ubiux%NA7}yeMG=gBjJ^8KRil9_j;V717sSKv%%75K zWaGE}0rzuD^I>dX8E-b)cV_2up`v00z4pPoE f0qCX3ZKQRu7B3a?Isc!s4=CUPJLdZ8XdwCD_$6OH literal 0 HcmV?d00001 diff --git a/share/tutorials/potrace-fr.png b/share/tutorials/potrace-fr.png new file mode 100644 index 0000000000000000000000000000000000000000..14069e1e3d24ec7179be91760fefc474628844f5 GIT binary patch literal 6468 zcmeHrXH-*Lw>FAW6fkHaML-0^(4<2QUDyz*0Yj4m1Zkn81_?a^N(@C1P^w@;2?PWI z6%a&F=^~LLC{22iBE55Sj;Flid}Dm$jyvwpJIAy4UVE+eW9?aT3wYA!K}!FdPzwKx!gT2rGmp5`{ooA&|czt>{1_(MW_ZQq$K8fyP*2e9<^hv@Z_h z8;tSA`r?9dIJ_?|(icbY#lyJqs@w!sZoDQpfesz+cuo3P5U&FzAfN<889WjeZwQS? z%HUC&cr=oLv5NP!!uw+IIA44)E*^`<$KVKfTuLO45Q!%c=pYbc2!td&AqAfjgO86V z#Ao2+GYIi?Ns3RQBZZEXl#G=4Y(jhvA%zY~d^Y_pJB30=WlA<(a+nYP-=xpxnrr$d| zyF2^n=VQ;MEGTZ+(jijN~9fr zDTM1IjyOn!=X(P#_mv9+T*P@Zt0AeQWWF9YNNgMin8+e27TcfJ2sKn}4s(`B3onKA z6k7Piq{yX25=8|)fhR(ja-Y}dpcLRFNKdV0c5_nglVXiBh*9JhVo_nU8+zgQwV^l7 zN)n@QFxML_Q2a0Zt9|45dps&nALGt-~AN+a&liSYmIk;S~YSea_4^NQ-b4 zn&~9;s{(dR8(7j5yUv_{D3^dia?-!~1f*V@ZkZ{zS@%$J-t^R&_Er{1Y)5;AO1anj z*FC!^1*Kw$`7JY=PD~DEz&v3eYgVy;%2L5*@jKKFR1FpH*wuqb9VyQLc*AMA@yFY$ zSA8FvIf$*tFS7z4-pf~QKBEqLgzB7pJb#L4(bTzrBVFtsTv&b`D8DW`Ln$F0kK_z1 zSMs;bN`BN3!8a1ujzUdm#)52L&BH8{oe}sS)8muw#P(n;;0MYex3)rhgn3^ISVqj` zG`C+R7ItauT{E4UuAXm-EWUsgVTJTC5^WO}O9Ht}oj$ywB$Ax4gGaR@cl?k}h9P(~ z9E%+#cwg+L1kP~T`fGvIze?!)1*W=kxs<;+XKwmwy1KZDReq)6KyDpyaLtFh@7g*= zd+?1u*J0HC;-%IY$y^#6b-c&qYym}J`rx8F{B^0*rTM(M(Quj8OK>@n8ty}XD0Hd9 zqC5EZ9X5jpd=@AL_VU}Y%?@fBkUMns|Dp8@ys$Qo=(klYZA{WWKzZ`xIGyemM& z?M~JM{1|7uCP<(~Q-#nAeXmEPr1{bsqXU;n!G{lwkJwam z=1M{CGM_C5bDlBcp|q4PzW^l4hKf+#9JUG1jTHNennh~QLwLkbPFwSPZ9T&Yt6$Pi z7M8W?kkGr9{}#;=cE}SrX(t^XMI50A357*K{I4MfyPctB`_Tk&d{-2=BtsQetvSjj z;NlkwoHGTI=L;(|&y7&ll(DBjx%OUgMi*c3OJ}lE>^C@0B5u9^p*pe6vt$^?Fu@-**w5 zT)&0d?qbSQfiB-v@@t*#157JK9eaM$EZT3>y1*uB_BodGwj* ziny})vEwO*rjk@gZOgN6yL;f4fW79LN)q~L^5Rub^AExG%AK-5ibB@kAlfEjzgaZR zW)>@D`(ZPG9y7pVTlA#Tt@QFsvQ?_em1uF#%*J1^kNIHvx410FUHppFxjT#E^1?V1 zC5J0A)Ekss{01sW0}z?wytuMhE@7o-P#<+ha9-o5b+a z82k`%H#?#+wE!VrSl8p1tt(0B{>?2l#eT zN3#&1=lRpuI{72m__?Ecb#@A)y^H!EIP}IJ4&mzH6pB>M?6F^=`zI~N8fVE2^P`x! zhKj6^zD~r8p(Bl1UGBnrUq6r8K6K_FQ@YH8#0rfM*m9edL6P17WQ!w_C@0ZYlH~?I z|Co0nniqWEpA%53Be$6)L2NC<&dqU1>m{7Nql{3vVP;Crjq9X+D2I#IX~_chM?MxK zuAV9=>ih9-J~~j^j}6eb&@<6|Db%HF>fNg=TP%kW1oj^B4s)gQ0kL(_bRE#*_-((W zyr2cG#T93`il4Zl`Q=u@9TL`}DI4PVaTeC>joV03ppIP}?2_mEn+Jan{`OfGx?|b> zO%Zgj3#RMz>?Aqj7k4xwb8JJ#@5Xd&ZcX1ic3Hkv<}<65GkSP7hop61%q-%{3$*Fa zNMGsr0-Sx6IOb_y4yP2AOsKsaove1*7M7pU>ctl%_e>6&)CLvf)Lx?eM^i)G%rjW$H zqSPMB2kK4Tb?vRSQG>H6o@b8IaXNlRgo`j0)-M6q#EI8T2zmmXA5oPPgVV-*e z{d@)#%x~LHwT%U%5nwgri`vaz1wV z8yie%(-m(5J_J=fr!jdsck@ZkH!SpkcF>@s?5*5HrCKAdm~-IdpA|R3JTbSGOXxLF zF6nu5O#m?eu>!n-Qh=o@mmJw(gl!-qBbt4khH5S=G5grviE^#}{;%ZqA9?KGLx+t8 zU6m954N#v=S6xq^>F{9Dq#?4%%a2&GPtsbSo~Lo$w%19SJd);JP7;UD8#47`2bGFz zurDW0(;0GS(9G!>2NjX@_~JRs1cBQ=vvtl%wcFg`?zpYa!&4C%0&zFrab-5A#t2H* zJ<-2uH&q^1cgMnxpG#a|20gxVID@whso>vR&XGus{z6{(;IUR89rK>tx8$sRR@_YZ z%U<)$DRH8c2FSG}?BlLXIDBVl0HSy5WcmLmF zV}|iUeNCq%l?GC%le2hY__Co@Q9femJ?JX<_-p0c+(5cgf?368$C(X62X5!dZTgNh zNWiI=fi606LWu<|pSy~T4HnJaUR>CC38jp*FK^$*-gni-Maguy&Yw1L&HkAerM<^5 zto&_wV1#gytmtn|DGRtq6eZiNbx<(y|Ezre?J@sPY4pFj zAw2(%s}^vIPD`fcHjz~g`^i6AvpNMJ#i6^fng{Cn;j1UEs!LB0| z%;j0Vn-u}S&k#zWi*AQe3g_(BT=EL@Nv!lhSO#yIoXRG#es@FtP1pbZ`1l`xZR#hu z7SQDY7lLpax&yZk>*o@(e{t=f4a#41!T#XZO*DR#g7I}31%G3J7y$3&<$GGv%V$$z zp@CCMA53YT7~)s8-8P9h;yuwqO7N=X8rz9APV~*bYM3~0TBXnd&3?jT4}HSl%9Ibn zZba`NeO8&v@19U1kz|`KMa~{_nG5Ye(wZwgfKf%95ZpK@LGZjw}lDhn%w$dQ)+z?R`;t+2k!gw!(0$IP+ zMH?U%+A<^qn5*egcPC(BPDn&hsQvllkoIO+B< z_bAtpHY=mal=j%`!mOr+tUwUO$KJm@Z?omJV_bo4zWjnZX z%*Mg)6RY*LZx;%J!}w=M8`24}SLG*|H3qcplh1+8J-Ci2Z4TcXDN7966RVjPaRD7? zdDi~=j9GCMMr=q%wpF^j%HPKR$!~gow%zlFCJtokXKmAo3oniqgIlhx*QFQo&d-57 zpWZk)LL8lQs$DJzyM3cdL*ZL2#2PCm%Y=cIw%+-?(=rZ5K>)Q_FH=@KK~DGTc(PAS zmlW{sX#>wFF=O^8^ST9U-yo#rBqP}|)8|g`84oo_F?TEDGUupoJU+laF^Yd*kZ9;$ zP8t%T+Vr4n$Sd0M3X5q%j)R>2#0n1RbK~!9-``G(1xge?hA=5j^Jnr|)tI_)$_MCS z*A6EiWhS;}z;#b^LyvKM$&j?@c$zG!bLne&BlXDK#U85YEABb(EXtE-M5Q=4J`n#5 z)Tl%0r)Y)4aY*WJK>;S*%Oj+<4a?2=l2u@Y$O7>?^dFItOES_xKYA}anj}&0l#A)I z2R}r=v8b5IS4cc^MlAqX&ihDYHWzTFip6mrndLV^+^@2pB5($uUi=!`!uk(`P1>$S$H*erAvakPCa0B^Eo++Lwa!c%R;UT6ke+Z1Q3n|PrPf&qOYxwHH8K2 z)RWtyHZ;Oi;9vGbtGn3%< S4f!pDzVpD8z53>OOOwg|kA<9KPtkP?`-Y2RfirhEGF5LZZ>&sp?2kk-YixIu@`E-# z)m*}!wJTccfpfs~w%=B+aYD`)NGuJd8w+TJjxM~K{Is_@vi51XHh4+GM7@spxlgoc zd0pLp`R1$HnHnzI-g)qRrk%Bbmoy|~rZp>w*sGMPUAepR^14(I_q9RE~)mD=>Q>~-d>}f+YVZQ~f()2X2 z6Rmpc+pA$=m|E$ZK5j8Xy%JtOa!5fws-aW!O>r7KW8|%slG>f6&-K!wYyA^T&L6qd z3pH-<mkf3++kD6syO&+Z2wF1_QaL?^!d9lAk~a>9zt4S= z;#0%<9$eK}tDRW-e0S;j^@Wg!DtRfS+Ag1A=+@Wd;ljA7m>|dEe2PG!q{Cxy?ec}F zy3p0QgG+&XDIF-0WzcC4Jbq5{DI#r@DDc7 z>WbO-Xz7{u#ScKihIY*Apom9nEVv7GA|t(b_r9LV_r}& z44e%fzcA1ST2_x*H|UcEZm%~;57aD9+GGX3OI*CPANs&7(UogkNzkA5bzbvOz)wb# z{c+2%?f$Sz|DpWu##`9hep_I@$I=eB)xS76bDqG}$b9$v`Md2xY96$n2=$r86z5N%*7ZX zlx3znlWjDXTw6$##2EeO-tO)HKj(kWyFBMT=Y7t5&ij0x?-zCEw5_;^q6h#0;xIdF zR{#K=;>9Jxe7v>2+Q@~sfg|j^qX0lu=C26?ii+iVhe9`DPBubsMMZY&YF3B^(*Zza zFU;D)9nM{XpTn>Fgc^}d=mr89d z#Ua8zs+5ZYvbpfY#DqvVP)-148v(zD0Okw;i3b5N{%7|yKd}bbRvhSX8VIwS@O^vd z^3Ld*Y@Q_W*?|)NQN>5$p&3h-(?-KYXRznP`2id0m4Xr{>98Gr(7V%p%ikNw6cP61 z0g3>yslo1cZXH*Sz1A%(!EdeslSCCq3mp0)1?U^Ch7o(0mRKP-SSgU8fVN$LJ?vPS zK^yx(iSapU0?7UaNfWSB1b)6wC&+NLjYP{IRhHx2L*Bk0d;YpzM23E z8rT?~%WEOCmvfBF74JFInM)%xk>CsPQw)IpUSaXc!!j@;j%lPm4%Dl!tJDO-#s+Ql z^M#O7qxkgE1Ca5HbYUeNU+-}oH14F5!STWbrqPW1fbTniB%7CR*K%n2><6r&5Hv<| zw)EXuujLS*ILRFoD^v2O#dz6gND+5LKKx#&3+uOe&(`Z^j(t<`EqJ^XUjyaSkwJI# z@2z4BwACZ5&-C7=`N?xeoTn}hoRf|5_n)7TajW%^`cmnweoAUvIh2AcDK9O z_P!B?8IFRx$hB~+o59NK?33e)5i#mt|7FY7V`-98_;&YDS?}f`Bn{Ch2ByvQPOG6dIE$kz%~R9MGZ81i0pK$KGhs-T z0;a|?(e{KWmC%FuGDq@cjInpP>!EKK=bL)W=Z8D%BvQuus(a@I`Yq{L{+kS3HA+Dd zRn{nA^H8yyi^2yFWna~r?{8B`ovTyB_ol+8&QnRwOrzRZ>ZJWM)97SgzOAp+nB@zP z8bMx$2|<*;QGR}8v7B6v(TfUsgF9Vop8HB|7=W}4#nmBCaQ<~Pxzx81Wu^V%F%Pu= zE$bh#t^=bWp3gDUDK|KZbe!JOIYO+d63xDelSjE}5+GVo8JK*knAEX>pxX z)@G40QF*A%ZbJIVkPIc=Z!lNl>YzbZ&bhqa8{_Z$TpN+-qfG+j9+%yA6hrH^r0`27 z5;*twSa*G$%8O1I8i@ZD22OswhLxSc_#Iwq`?IYpI)2Xu@vxN@j1*|dyv{1v_3bWX z(U%*-`6)-^1ikDanFXLSU<1zoqgm(^eH8s-@umxp4}W!goMVJc?;*~GMC*PlIIb>^ zlcsyA?v3BN&4FK47uPp*T>&{@p8NU=xWxkUIZhP?SjKzqI=TjQ5Jwr?(rYbIE&Xfg zeVO(^_ zt9wlchU@DpTRqrKblh*VziYoJNtB@32r11B_(!pfuZ9$ktU0!ye&xNaY$*9zy!$q% zR%Nb7afvCAhNA8574(3a!J7;&*CofW?z^%km4}3LRiqb_g92&?su;d6Yn&IiVfm2M zbkRAj$Sj*s0kn8ahxrnEdbF*m`og(xF5lV|d`&4;$uB6;*T+rnQmM&k$+stW^gr$T zrF>#UwV~ck4a=+kxL21eyzsrZF36s=iy}KS@!*rQo#}`SKgUCFlXN*bgAZHXX&880 zTS)+x1CKwd?A+m{_AUFUt@e7s0WII*&{ElL*;cK}GeD zT0_Y(x3F40>GO@N-1WlHABb$!s}&c)F@dF?^JGXIEHv5Co7bK%t+uOa?q=AZaWIr?KTSRV|Ni_BamccR(l)9gMkfSG%95&fX+j}EB( zfsLw3xf_axhz98d!B@HqxKu(^FKez!X0=#;q==Kd1apKLXq@Wfz3=?|(L4u>~1{Y;>3NM5~H0M2ltVAb3{ z*AyTmsh@mjD^j1~puqzYfO{sxVC7t9cvTIwoqKj9%1q}St#~MFu+F%8wneUPW!IbR z$=$~${O=w9#j|5$_(}&!Q?sMLmS#;if1har1cCocSrd;kkH0BvCtB|h0Z{)>S$X`w zl&Nmy=!Ud33zw|{`f3l|4UQAKIExCG_}$H8FMd8%ePw@;R(*Jp=7WkR871>GX|DT2 zh6!AI-=k4yXe|LxsloaKrLCJ5-z&CdHMVxO9fUpHz1MAJ3ZAPsF>^~#hdd{h@COc| zKTn+NlcZXwRQHA}G+{6(2>r|6+sX#QI~G~7XWkrWAFrP@*z=Ca))-UoAI)b*#hcZ} z+(Ibhhx{u^eXij#qiDo)fzld^?aexBFs|_2YiY6V8z&aLMsgZiT^~AE|AdM_U-Zv5 ze~D1&r^$)038qY?JWZIkUDC{6!e4mcImocme4emThgQ2t(Nhc*6QriuVy3-_mbB8p zN$6zsjPbNex;qyaUpU!8fX@3M^%P&F?GJ}Q92>-(DJj*ny@Tsf2H^34GRK(1oO@(B zWcNyac zECWJioe;b$8Fl2>%z%GI!E{Sb(947;3dH>Z$S%W&iwq#@(o1>SzLTlNdtm%_=p#^1 zy;VUk@E98reOXiD5s<+L`=_n`@L)gv7*72=$XF{clCb%}iRT>wn9XVHDoelQ{{T)p B9BKdn literal 0 HcmV?d00001 diff --git a/share/tutorials/tutorial-advanced.es.svg b/share/tutorials/tutorial-advanced.es.svg new file mode 100644 index 000000000..043e64990 --- /dev/null +++ b/share/tutorials/tutorial-advanced.es.svg @@ -0,0 +1,467 @@ + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ::AVANZADO + + + + + + + + +Este tutorial cubre los siguientes temas: copiar/pegar, edición de nodos, dibujo +de curvas bezier y a mano alzada, manipulación de rutas, booleanos, desvio, simplificación y herramienta texto. + +Use Ctrl+flechas, ruedad del ratón o arrastran con botón central del ratón +para situar la página. Para las bases acerca de la creación de objetos, selección y transformación, observe el tutorial básico en +Ayuda > Tutoriales. + + + + +Técnicas de pegado + +Después de que usted copia algún(os) objeto(s) mediante Ctrl+C o corta mediante +Ctrl+X, el comando regular Pegar +(Ctrl+V) pega el/los objeto(s) copiados, bajo el cursor del ratón o cursor o +si el cursor se encuentra fuera de la ventana, en el centro de la ventana del documento. Sin embargo, +el/los objeto(s) en el portapapeles aún recuerdan el lugar original donde fue(ron) copiado(s) y usted puede +copiarlos de nuevo en ese lugar mediante Pegar en el sitio +(Ctrl+Alt+V). + + +Otro comando, Pegar estilo (Mayus+Ctrl+V), +aplica el estilo del (primer) objeto en el portapapeles a la selección actual. Así el "estilo" +pegado incluye la configuración de relleno, trazo y fuente, pero no la forma, tamaño o +parámetros específicos de un tipo de forma, tales como el número de puntas de una estrella. + + +Note que Inkscape posee su propio portapapeles interno; este no emplea el portapapeles del sistema salvo en +el caso de copiado/pegado de texto mediante la herramienta Texto. + + + + +Dibujando a mano alzada y trazos regulares + +La forma más sencilla para crear formas arbitrarias es dibujar usando la herramienta Lapiz (dibujar líneas a mano alzada) +(F6): + + + + +Si desea figuras más regulares, use la herramienta Pluma (Bezier) (Mayus+F6): + + + + +Con la herramienta pluma, cada click crea un nodo sin ningún manejador de curva, +así una serie de clicks produce una secuencia de segmentos rectos de línea. +Click y arrastrar crea un suave nodo Bezier con dos manejadores colineales opuestos . +Presione Mayus mientras arrastra un manejador para rotar solo un +manejador y arreglar el otro. Como usualmente, Ctrl limita la dirección o del segmento de línea actual o +el incremento del manejador Bezier en 15 grados. Presionando Enter finaliza la línea, +Esc la cancela. Para cancelar tan solo el último segmento de una línea sin finalizar, presione Barra espaceadora. + + +En ambas herramientas, el trazo actualmente seleccionado muestra una pequeña ancla cuadrada en ambos finales. +Estas anclas le permiten continuar este trazo (mediante arrastrado desde uno de las anclas) o +cierrelo (mediante arrastrado de una ancla a la otra) en vez de crear una nueva. + + + + +Editando trazos + +Diferente a las formas creadas con la herramienta Forma, las herramientas Pluma y Lápiz crean lo que es denominado +trazos. Un trazo es una secuencia de segmentos de línea recta y/o como las curvas Bezier, como cualquier +otro objeto de Inkscape, puede tener unas propiedades arbitrarias de relleno y borde. Pero diferente a una forma, un trazo puede ser editado mediante arrastrado libre de cualquiera de sus nodos (y no sólo mediante manejadores predeterminados). Seleccione este trazo y active la herramienta Nodo (F2): + + + + +Usted puede observar un número de cuadrados grices, son los nodos del trazo. Estos nodos +pueden ser seleccionados mediante click, +Mayus+click o mediantearrastadode uno de los lazos elásticos o rectas — +exactamente como los objetos que son seleccionados por la herramienta Selección. Los nodos seleccionados son resaltados +y muestran sus manejadores de nodos — uno o dos círculos conectan cada nodo seleccionado +mediante una línea recta. + + +Los trazos son editados mediante arrastrado de sus nodos y nodos manejadores. (Intente arrastrar +algunos nodos y manejadores del siguiente trazo.) Ctrl trabaja usualmente restringiendo movimientos y rotación. +Las teclas: flechas, Tab, +[, ], <, > +von sus modificadores trabajan como lo hace el selector, pero aplica a los nodos en vez de a los objetos. +Puede borrar (Del) o duplicar (Mayus+D) +los nodos seleccionados. El trazo puede ser roto (Mayus+B) en los nodos seleccionados, +o si selecciona dos nodos finales en un trazo, los puede agrupar mediante (Mayus+J). + + +Un nodo puede hacerse agudo (Mayus+C), lo cual indica +que sus dos manejadores pueden moverse independientemente den cualquier ángulo para cada uno; +suave (Mayus+S), el cual indica que sus manejadores siempre están +sobre la misma línea recta (colineal); y simetrico +(Mayus+Y), que es lo mismo que suave, pero los manejadores también tienene la misma longitud. + + +Usted, también puede retraer completamente el manejador de un nodo mediante +Ctrl+click sobre él. Si dos nodos adyacentes poseen sus manejadores retraidos, el segmento de trazo entre ellos es una línea recta. Para salir del nodo retraido, haga Mayus+drag lejos del nodo. + + + + +Subtrazos y combinación +Un objeto trazo puede contener más de un subtrazo. Un subtrazo es una secuencia +de nodos concetados entre si. (Por lo tanto, si un trazo tiene más de un subtrazo +no todos los nodos están conectados.) Abajo a la izquierda, tres subtrazos pertenecen a un +trazo simple compuesto; los mismos tres subtrazos den la derecha son objetos de trazo independientes: + + + + +Note que un trazo compuesto no es lo mismo que un grupo. Es un objeto sencillo el cual es sólo +seleccionable como uno entero. Si usted selecciona el objeto de la izquierda a continuación +y tome la herramienta nodo, podrá observar los nodos mostrados en los tres subtrazos. En la derecha, +puede solo editar-nodos sobre un solo trazo a la vez. + + +Inkscape puede Combinar trazos en un trazo compuesto +(Ctrl+K) y Separar un trazo compuesto en +trazos separados (Mayus+Ctrl+K). Intente estos comandos sobre los ejemplos de a continuación. +Desde que un objeta solo posea un relleno y estilo de trazo, un nuevo trazo compuesto toma +el estilo del primer (menores en orden-z) objeto siendo combinado. + + +Cuando combina trazos superpuestos con relleno, usualmente el relleno puede desaparecer +en las áreas donde el trazo se superpone: + + + + +Este es el modo más sencillo para crear objetos con agujeros en el. Para comandos de trazo más poderosos, +observe "Operaciones Booleanas" más adelante. + + + + +Convirtiendo a trazo + +Cualquier forma o objeto de texto puede ser convertido a trazo +(Mayus+Ctrl+C). Esta operación no cambia la apariencia del +objeto pero remueve todas la capacidades específicas de su tipo (e.g usted no puede +redondear las esquinas de una rectángulo o editar más el texto); en vez de esto, ahora puede editar +nodos. He aquí dos estrellas — la de la izquierda se mantiene como forma y la de la derecha está convertida a trazo. +Seleccione la herramienta nodo y compare su editabilidad cuendo sea seleccionada: + + + + +Además, usted puede convertir a trazo ("delineado") el Borde de cualquier +objeto. Adelante, el primer objeto es el trazo original (sin relleno, borde negro), mientras que +el segundo es el resultado del comando Borde a Trazo (relleno negro, +sin borde): + + + + + + +Operaciones booleanas +Los comandos en el menú Trazo le permiten combinar dos o más objetos usando +operaciones booleanas: + + +Original shapesUnion (Ctrl++)Difference (Ctrl+-)(bottom minus top)Intersection(Ctrl+*)Exclusion(Ctrl+^)Division(Ctrl+/)Cut Path(Ctrl+Alt+/) + +Los atajos por teclado para estos comandos hacen alusión a los análogos aritméticos de +las operaciones booleanas (union es adición, diferencia es sustracción, etc.). Los +comandos Diferencia y Exclusión sólo pueden ser aplicados +a dos objetos seleccionados; otros pueden procesar cualquier número de objetos a la vez. El resultado +siempre recibe el estilo del objeto del fondo. + + +El resultado del comando Exclusión se parece a Combinar (observe adelante), +pero es diferente a Exclusion en el hecho que este último agrega nodos donde estaban las intersecciones de +trazos originales. La diferencia entre División y Cortar Trazo radica en que +el primero de ellos corta completamente el objeto del fondo por el trazo del objeto de la parte superior, mientras el último +solo corta el borde del objeto del fondo y remueve cualquier relleno (esto es conveniente para +cortado en piezas de bordes sin-relleno). + + + + +Reducir y ampliar +Inkscape puede expandir y contraer formas no solo mediante escalado, también puede mediante +desvio de trazo de un objeto, i.e. desplazándolo perpendicularmente +al trazo de cada punto. Los comandos correspondientes son llamados +Ampliar (Ctrl+() y Reducir +(Ctrl+)). Mostrados adelante como el trazo original (rojo) y un número de trazos ampliados y reducidos del +original: + + + + +Los comandos directos Ampliar y Reducir producen trazos +(convirtiendo el objeto original a trazo si aún no es trazo ). Muchas veces, más conveniente +es Desvío Dinamico (Ctrl+J) el cual crea un objeto +con manejadores arrastrables (similar al manejador de formas) contralando la distancia +de desviado. Seleccione el objeto de abajo, cambie a la herramienta nodo y arrastre su manejador para +obtener una idea: + + + + +Como un objeto desviado dinámicamente recuerda el trazo original, este no "degrada" +cuando usted cambia la distancia de desviado una y otra vez. Cuando usted no lo requiere ajustar +más, siempre puede volver a convertir un objeto desviado a trazo. + + +Aún más conveniente es el Desvío Enlazado, el cual es similar a la variedad dinámica +pero es conectado a otro trazo el cual se mantiene editable. Usted puede tener cualquier número +de desvíos enlazadas para un trazo fuente. Adelante, el trazo fuente es rojo, un desvío enlazado a este tiene +borde negro y no posee relleno, el otro posee relleno negro y no tiene borde. + + +Seleccione el objeto rojo y edit nodos; observe como ambas desviaciones enlazadas resoinden. Ahora +seleccione cualquiera de las desviaciones y arrastre sus manejadores para ajustar el radio de desviación. Finalmente, note +como moviendo o transformando el fuente mueve todos los objetos desviados enlazados a el y como usted +puede mover o transformar objetos desviados independientemente sin perder su conexión +con el fuente. + + + + + + + +Simplificación + +El uso principal del comando Simplificar (Ctrl+L) es +reducir el número de nodos de un trazo mientras casi preserve su +forma. Esto puede ser útil para trazos creados mediante la herramienta Lápiz, ya que la herramienta +en ocasiones crea más nodos de los ncesarios. Adelante, la forma en la izquierda es creada mediante +la herramienta nano alzada y la de la derecha es una copia pero simplifiacada. El trazo original tiene 28 +nodos, mientras que el simplificado posee 17 (lo cual significa que es mucho más sencillo de trabajar +con la herramienta Nodo) y es más suave. + + + + +El monto de la simplificación (llamado umbral) depende del +tamaño de la selección. Por lo tanto, si usted selecciona un trazo a lo largo con algún +objeto grande, este será simplificado más agresivamente que si usted selecciona +ese trazo pero solo. Además, el comando Simplificar es +acelerado. Esto indica que si usted presiona Ctrl+L +en múltiples ocasiones en una suseción rápida (o sea que la llamada sea en 0.5 seg entre cada uno). +El umbral es incrementado en cada llamado. (Si hace otro Simplificar después +de una pausa, el umbral es devuelto a su valor por defecto.) Haciendo uso de la aceleración, es +fácil de aplicar para el monto exacto de simplificación que usted requiere en cada caso. + + +Más allá de suavidad en los bordes a mana alzada, Simplificar puede ser usada para varios +efectos creativos. A menudo, una forma que es rígida y geométrica beneficia desde algunos montos +de simplificación que crea interesantes generalizaciones como la vida real a partir del original desde — +la fundición de esquinas afiladas e introduciéndo distorsiones muy naturales, en algunas ocasiones estilizado y +en otras divertidas. He aquí un ejemplo de las formas prediseñadas (clipart) que se ven mucho más +vistozas despues de usar Simplificar: + + +OriginalSlight simplificationAggressive simplification + + + +Creando texto + +Inkscape es capaz de crear textos largos y complejos. Sin embargo, esto el algo +muy conveniente para la creación de textos pequeños como cabeceras, banners, logos, etiquetas +de diagramas y captura, etc. Esta sección es una introducción muy básica acerca de las +capacidades de texto de Inkscape. + + +Crear un texto es tan sencillo como cambiar a la herramienta de Texto (F8), +dando click donde en el documento y escribiendo su texto. Para cambiar la familia de fuente, estilo, +tamaño y alineación, abra el dialogo Texto y Fuente (Mayus+Ctrl+T). Este +dialogo tambien tiene una pestaña de entreda de texto donde usted puede editar el objeto de texto seleccionado - en algunas +situaciones, esto puede ser más conveniente que editar sobre la pizarra (en +particular, esta etiqueta soporta revisión de como-usted-escribe). + + +Así como otras herramientas, la herramienta Texto puede seleccionar objetos de su mismo tipo — objetos de texto +— así usted puede dar click para seleccionar y posiciones el cursor en algún objeto de texto existente +(tal como este parrafo). + + +Una de las operaciones más comunes en el diseño de texto es el ajustar el espaceado entre letras +y líneas. Como siempre, Inkscape provee atajos por teclado para esto. Cuando se encuentra editando texto, +las teclas Alt+< y Alt+> cambian +el espaceado de letras en la línea actual de un objeto de texto, así que la +longitud total de las líneas cambian en 1 pixel en la visualización actual (compare con la herramienta +Selector donde la misma tecla hace un excalado de objeto tamaño-pixel). Como una regla, si el tamaño de fuente en +un objeto de texto es más largo que el por defecto, se notará un apretujado de letras +un poco más ajustado que el por defecto. Aquí un ejemplo: + + +OriginalLetter spacing decreasedInspirationInspiration + +Las variantes de ajustados parecen un poco mejor que un encabezado, pero aún no es perfecto: las +distancias entre letras no son uniformes, por ejemplo la "a" y la "t" están muy separadas +mientra que la "t" y la "i" están muy cerca. El monto de de dicho kern erroneo (especialmente visible en +tamaños de fuente grandes) es mayor en fuentes de baja calidad que en las otras de buena calidad; sin embargo, en +cualquier cadena de texto y en cualquier fuente probablemente buscará un par de letras que puedan +beneficiar el ajuste del espaceado. + + +Inkscape hace estos ajustes de una manera muy sencilla. Tan sólo mueva su cursor de edición de texto entre +los caracteres mal espaceados y use Alt+flechas para mover las letras a partir del cursor. +He aquí el mismo encabezado de nuevo, en esta ocasión con ajuste manuales para un posisionado +de letras visualmente uniforme: + + +Letter spacing decreased, some letter pairs manually kernedInspiration + +Adicionalmente, para movimiento horizontal de letras es mediante Alt+Izquierda o +Alt+Derecha, también puede moverlas verticalmente mediante +Alt+Arriba o Alt+Abajo: + + +Inspiration + +Por supuesto es posible convertir texto a trazo (Mayus+Ctrl+C) y +mueva las letras como objetos de trazo regulares. Sin embargo, este es mucho más conveniente para mantener +texto como texto — este se mantiene editable, usted puede intentar diferentes fuentes sin remover +los kerns y espacios y esto toma mucho menos espacio en el archivo guardado. La única desventaja +del enfoque "texto a texto" is que usted necesita taner la fuente original instalada sobre cualquer sistema +donde intenta abrir dicho documento SVG. + + +Similar al espaceado de letras, usted también puede ajustar espaceado de línea en +objetos de texto multi-línea. Intente las teclas Ctrl+Alt+< y Ctrl+Alt+> +sobre cualquier parrafo en este tutorial para espacearlo dentro o fuera así que la altura total +de los objetos de texto cambian en 1 pixel en el zoom actual. +Como en Selección, presionando Mayus con cualquier atajo de espaceado o kern +produce efectos 10 veces más grande que sin el Mayus. + + + + +Editor XML + +Las última herramienta poderosa de XML es el editor XML (Mayus+Ctrl+X). +Este muestra todo el arbol XML del documento, simpre refleja su actual estado. +Usted puede editar sus dibujos y observar los cambios correspondientes en el arbol XML. +Además, usted puede editar cualquier texto, elemento o atributo de nodos en el editor de XML y +observe el resultado en su pizarra. Esta es la mejor herramienta imaginable para aprender interactivamente +SVG y este le permite hacer trucos que pueden ser imposibles con herramientas regulares +de edición. + + + + +Conclusión + +este tutorial muestra solo una pequeña parte de las capacidades de Inkscape. Esperamos que lo +haya divertido. No tema experimentar y dividir lo que crea. Por favor visite www.inkscape.org para más información, últimas versiones +y ayuda para usuarios y la comunidad de desarrolladores. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/share/tutorials/tutorial-advanced.fr.svg b/share/tutorials/tutorial-advanced.fr.svg new file mode 100644 index 000000000..85b1945cc --- /dev/null +++ b/share/tutorials/tutorial-advanced.fr.svg @@ -0,0 +1,325 @@ + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ::AVANCÉ + + + + + + + + +Ce didacticiel couvre le copier/coller, l'édition de nœuds, le dessin à main levée, le tracé de courbes de Bézier, la manipulation de chemins, les opérations booléennes, les objets offset, la simplification et l'outil texte. + + +Faites défiler la page avec Ctrl+flèche, ou avec la souris (molette ou bouton du milieu). Pour les bases de la création, sélection et transformation d'objets, voyez le didacticiel basique du menu Aide > didacticiels. + + + + + +Techniques de collage + +Après avoir copié (Ctrl+C) ou coupé (Ctrl+X) des objets, la commande coller (Ctrl+V) permet de coller les objets copiés juste sous le curseur de la souris (ou au centre du document si le curseur est en dehors de la fenêtre). Cependant, les objets du presse-papiers retiennent leur emplacement d'origine, et vous pouvez les recollez à ce même emplacement avec coller sur place (Ctrl+Alt+V). + + +En appuyant sur Maj+Ctrl+V, vous pouvez coller le style, c'est à dire appliquer le style du premier objet du presse-papiers à la sélection courante. Le "style" ainsi collé inclut le remplissage, le contour et les paramètres de la police, mais pas le type de forme, la taille ou les paramètres spécifiques à un type de forme (comme le nombre de sommets d'une étoile). + + +Notez qu'Inkscape possède son propre presse-papiers; il n'utilise pas le presse papiers système sauf pour copier/coller du texte avec l'outil Texte. + + + + + +Dessiner à main levée ou tracer des chemins + +La façon la plus simple de dessiner une forme quelconque est d'utiliser l'outil dessin à main levée (crayon) (F6) : + + + + +Pour obtenir des formes plus régulières, utilisez plutôt les courbes de Bézier (stylo) (Maj+F6) : + + + + +Avec l'outil stylo, chaque cliquer crée un nœud dur sans poignée d'incurvation, et donc une série de clics produit une séquence de segments de droite. Cliquer-déplacer crée un nœud de Bézier doux, avec deux poignées de contrôles colinéaires opposées. Appuyez sur Maj tout en déplaçant une poignée de contrôle pour la faire tourner en gardant l'autre fixe. Comme d'habitude, Ctrl limite la modification de la direction d'un segment ou des poignées de contrôle par incréments de 15 degrés. Appuyer sur Entrée finalise le tracé, Esc l'annule. Pour annuler uniquement le dernier segment d'une ligne non finalisée, appuyez sur Effacement arrière. + + +Dans les outils dessin à main levée et courbes de Bézier, tout chemin sélectionné affiche des petites ancres carrées à ses extrémités. Ces ancres vous permettent de prolonger ce chemin (en dessinant en partant de ces ancres) ou de le fermer (en dessinant d'une ancre à l'autre) au lieu d'en créer un nouveau. + + + + + +Editer des chemins + +Contrairement aux formes créées par les outils forme, les outils dessin à main levée et courbes de Bézier créent ce que l'on appelle des chemins. Un chemin est une séquence de segments et/ou de courbes de Bézier qui, comme tout autre objet d'Inkscape, peut avoir des propriétés de remplissage et de contour. Mais contrairement à une forme, un chemin peut être modifé en déplaçant indépendamment n'importe lequel de ses nœuds (et pas seulement des poignées prédéfinies). Sélectionnez ce chemin et utilisez l'outil nœud (F2) : + + + + +Vous devez voir un certain nombre de nœuds carrés gris sur le chemin. Ces nœuds peuvent être sélectionnés avec un cliquer, Maj+cliquer ou avec une bande étirable — Comme des objets avec le sélecteur. Les nœuds sélectionnés sont mis en valeur et affichent leurs poignées de contrôle — les petits cercles connectés à leurs nœuds par des segments. + + +Les chemins peuvent être édités en déplaçant leurs nœuds ou les poignées de contrôle de ces nœuds (essayez de déplacer certains nœuds et poignées de contrôle du chemin ci-dessus). Ctrl permet comme d'habitude de restreindre les déplacements et rotations. Les touches flèche, Tab, [, ], <, > et les combinaisons qui y sont associées fonctionnent comme dans le sélecteur mais s'appliquent aux nœuds au lieu des objets. Vous pouvez supprimer (Suppr) ou dupliquer (Maj+D) les nœuds sélectionnés. Un chemin peut être brisé (Maj+B) aux nœuds sélectionnés; si vous sélectionnez deux nœuds terminaux, vous pouvez les joindre (Maj+J). + + +Un nœud peut être rendu dur (Maj+C), ses poignées de contrôle pouvant alors être déplacées indépendamment; doux (Maj+S), les poignées restant alignées; ou symétrique (Maj+Y), poignées alignées et équidistantes. + + +Vous pouvez aussi rétracter les poignées de contrôle d'un nœud en effectuant un Ctrl+cliquer sur ce dernier. Si deux nœuds adjacents ont leurs poignées rétractées, le chemin entre ces deux nœuds devient un segment de droite. Pour faire ressortir les poignées rétractées d'un nœud, effectuer un Maj+déplacersur celui-ci + + + + + +Sous-chemins et combinaisons +Un objet chemin peut contenir plus d'un sous-chemin. Un sous-chemin est une séquence de nœuds connectés les uns aux autres (donc, si un chemin a plusieurs sous-chemins, tous ses nœuds ne sont donc pas forcément interconnectés). Ci-dessous à gauche, les trois sous-chemins appartiennent à un même chemin composé, les trois mêmes sous-chemins à droite sont des objets chemins indépendants : + + + + +Notez qu'un chemin composé n'est pas un groupe, c'est un objet unique sélectionnable comme un tout. Si vous sélectionnez l'objet à gauche ci-dessus et utilisez l'outil chemin, vous verrez les nœuds des trois sous-chemins affichés simultanément. A droite, vous ne pouvez éditer les nœuds que d'un sous-chemin à la fois. + + +Inkscape peut combiner des chemins en un chemin composé (Ctrl+K) et séparer un chemin composé en sous-chemins (Maj+Ctrl+K). Essayez ces commandes sur les exemples ci-dessus. Comme un objet ne peut avoir qu'un unique couple remplissage et contour, un chemin combiné reçoit le style du premier objet (le plus bas dans l'ordre-z) de la combinaison. + + +Si vous combinez des chemins avec remplissage qui se chevauchent, le remplissage disparaîtra dans les zones de chevauchement : + + + + +Ceci est la façon la plus facile de créer des objets troués. Pour des opérations encore plus puissantes sur des chemins, utilisez les opérations booléennes (voir plus bas). + + + + + +Convertir en chemin + +Tout objet texte ou forme peut être converti en chemin (Maj+Ctrl+C), ce qui ne modifie pas son apparence mais lui enlève les capacités liées à cette forme (par exemple, vous ne pouvez plus modifier l'arrondi des coins d'un rectangle ou éditer un texte après cette opération); par contre cela vous permet d'éditer ses nœuds à la place. Voici deux étoiles, celle de gauche est une forme et la même à droite a été convertie en chemin. Sélectionnez l'une ou l'autre, et comparez les possibilités d'édition : + + + + +De plus, vous pouvez convertir en chemin (ou détourer) (Ctrl+Alt+C) le contour de n'importe quel objet. Ci-dessous, le premier objet est le chemin original (pas de remplissage, contour noir), tandis que le second est le résultat d'une commande Contour en chemin (remplissage noir, pas de contour) : + + + + + + + +Opérations booléennes +Les commandes du menu Chemin vous permettent de combiner deux objets ou plus en utilisant des opérations booléennes : + + +Formes originalesUnion (Ctrl++)Différence (Ctrl+-)(bas moins haut)Intersection(Ctrl+*)Exclusion(Ctrl+^)Division(Ctrl+/)Découper les chemins(Ctrl+Alt+/) + +Les raccourcis de ces commandes font allusion à leurs analogues arithmétiques pour les opération booléennes (union pour addition, difference pour soustraction, etc.). Les commandes Différence et Exclusion ne peuvent s'appliquer qu'à deux objets sélectionnés, les autres à un nombre quelconque. Le résultat reçoit toujours le style de l'objet du fond dans l'ordre-z. + + +Le résultat d'une commande Exclure ressemble à celui d'une Combinaison (voir plus haut), mais en diffère en ce que l'exclusion ajoute des nœuds en plus aux intersections des chemins. La Division qui intercepte l'objet du dessous selon celui du dessus diffère de Découper les chemins qui se limite à intercepter le contour de l'objet du dessous et à supprimer les remplissages (ceci est pratique pour découper en morceaux des tracés sans remplissage). + + + + + +Eroder et dilater +Inkscape peut étendre et contracter des objets par une modification de leurs dimensions, mais aussi par offset du chemin, c'est à dire par un déplacement perpendiculaire en tout point du chemin. Les commandes correspondantes sont Eroder (Ctrl+() et Dilater (Ctrl+)). Par exemple, ci-dessous, voyez le chemin original (en rouge) et des érosions et dilatations de celui-ci : + + + + +Les commandes éroder et dilater produisent des chemins (si nécessaire en convertissant l'objet original en chemin). Un offset dynamique (Ctrl+J) sera souvent plus pratique : il crée un objet avec une poignée déplaçable qui contrôle le rayon d'offset. Voyez avec l'objet ci-dessous; sélectionnez-le et passez en édition de nœuds pour vous faire une idée: + + + + +Un tel objet offset dynamique retient le chemin d'origine, et ainsi ne se "dégrade" pas quand vous modifiez la distance d'offset encore et encore. Quand vous n'avez plus besoin de l'ajuster, vous pouvez toujours le convertir en chemin. + + +Encore plus pratique : l'offset lié, similaire à un offset dynamique mais connecté au chemin qui reste éditable. Vous pouvez en créer autant que vous voulez à partir d'un chemin source. Ci dessous, le chemin source est en rouge, le premier offset lié à celui-ci a un contour noir et pas de remplissage, l'autre un remplissage noir et pas de contour. + + +Sélectionnez l'objet rouge et éditez ses nœuds; voyez le comportement des offsets liés. Maintenant sélectionnez un des offsets et déplacez sa poignée pour ajuster le rayon d'offset. Enfin, constatez que le déplacement ou la transformation de l'objet source affecte les offsets qui lui sont liés et que vous pouvez déplacer et transformer les offsets liés indépendament sans perdre leur lien avec l'objet source. + + + + + + + + +Simplification + +L'utilisation principale de la commande simplifier (Ctrl+L) est réduire le nombre de nœuds d'un chemin tout en préservant au maximum son aspect. Cela peut être utile pour les chemins tracés à main levée car cet outil crée parfois plus de nœuds que nécessaire. Ci dessous, le dessin de gauche a été crée à main levée et celui de droite est une copie qui a été quelque peu simplifiée. Le chemin original comporte 28 nœuds, tandis que le simplifié n'en a que 17 (et est donc bien plus facile à retravailler avec l'outil nœuds) et est plus lisse. + + + + +L'importance de la simplification (appelée seuil) dépend de la taille de la sélection. Ainsi, si vous sélectionnez un chemin et en plus un autre objet plus important, la simplification sera plus aggressive que pour le chemin seul. De plus, la commande simplifier est accélérée : si vous appuyez sur Ctrl+L plusieurs fois de suite rapidement (avec moins de 0,5 sec entre 2 appuis consécutifs) le seuil est incrémenté à chaque appui. Après une pause le seuil de simplification revient à sa valeur par défaut. Grâce à cette accélération, il est facile d'ajuster précisement la simplification dont vous avez besoin pour chaque cas. + + +En plus d'adoucir les tracés à main, simplifier peut être utilisé avec succès pour générer des effets créatifs ou originaux. Une forme plutôt rigide et géométrique bénéficiera souvent d'un brin de simplification qui lui donnera un peu de vie — adoucissant certains coins et introduisant des distorsions très naturelles, parfois très stylées et d'autres fois plutôt amusantes. Voici un exemple de dessin (clipart) bien plus réussi après avoir été simplifié : + + +OriginalSimplification légèreSimplification aggressive + + + + +Créer du texte + +Inkscape permet la composition de textes longs ou complexes. Cependant, il convient aussi assez bien pour la création de petits textes comme des titres, banières, logos, des légendes de diagrammes, etc. Cette section est une introduction très basique aux possibilités de création de textes avec Inkscape + + +Créer un objet texte est aussi simple que de passer à l'outil texte (F8), cliquer quelque part sur le canevas et taper votre texte. Pour changer la police, le style ou la taille d'un texte, ouvrez la boîte de dialogue texte et police (Maj+Ctrl+T). Cette boîte de dialogue a aussi un onglet texte que vous pouvez utiliser à des fins d'édition - dans certaines situations, il peut être plus pratique que l'édition directement sur le canevas (en particulier cet onglet supporte la vérification d'orthographe à la volée). + + +Comme les autres outils, l'outil texte peut sélectionner des objets de son propre type — les objets texte donc — de sorte que vous pouvez cliquer afin de sélectionner et positionner votre curseur sur tout objet texte (comme ce paragraphe). + + +Une des opérations les plus courantes sur les textes est l'ajustement de l'espacement entre des lettres ou des lignes. Comme toujours, Inkscape fournit des racccourcis clavier pour cela. Les combinaisons Alt+< et Alt+> modifient l'inter-lettrage de la ligne courante d'un objet texte, de sorte que la longueur de cette ligne change d'1 pixel au zoom courant (à comparer avec le comportement du sélecteur où elles permettent de modifier les dimensions au pixel près). La plupart des objets texte (pour une taille de police plus grande que celle du contenu d'un livre) présente un meilleur rendu après en avoir légèrement resserré les lettres. Voici un exemple : + + +OriginalInter lettrage diminuéInspirationInspiration + +La version remaniée rend un peu mieux, mais n'est toujours pas parfaite : les distances entre les lettres ne sont pas uniformes; par exemple, le "a" et le "t" sont trop éloignés tandis que le "t" et le "i" sont trop proches. L'imperfection des crénages (particulièrement visible avec des grandes tailles de police) est plus importante dans des fontes de mauvaise qualité, mais, vous trouverez toujours (pour tout texte et toute police) des paires de lettres qui bénéficieront d'un ajustement de crénage. + + +Inkscape facilite ces ajustements; vous n'avez qu'à positionner votre curseur de texte entre les caractères qui posent problème et à utiliser Alt+flèche pour déplacer les lettres autour du curseur. Vous trouverez ci-dessous le même exemple, mais cette fois avec des ajustements manuels, de sorte que les lettres sont positionnées uniformément. + + +Inter lettrage diminué et crénage manuel de certaines paires de lettresInspiration + +En plus de pouvoir déplacer les lettres horizontalement avec Alt+Gauche ou Alt+Droite, vous pouvez aussi les déplacer verticalement avec Alt+Haut or Alt+Bas : + + +Inspiration + +Bien sûr, vous pourriez convertir votre texte en chemin (Maj+Ctrl+C) et déplacer les lettres comme tout objet chemin. Cependant, il est bien plus pratique de conserver ses propriétés de texte : il reste éditable, vous pouvez essayer différentes fontes tout en préservant vos crénages et espacements, et la taille du fichier sauvé reste plus petite. Le seul désavantage de conserver le "texte en texte" est que vous devrez avoir sa fonte originale installée sur tout système où vous voudriez ouvrir votre document SVG; si Inkscape ne peut retrouver la fonte correspondante, il affiche un message d'avertissement. + + +De la même façon, vous pouvez ajuster l'inter-lignage des objets texte de plusieurs lignes. Essayez les raccourcis Ctrl+Alt+< et Ctrl+Alt+> sur n'importe quel paragraphe de ce didacticiel pour faire varier la hauteur globale de l'objet texte de 1 pixel au zoom courant. Comme dans le sélecteur, combiner un raccourci d'espacement ou de crénage avec la touche Maj multipliera son action par 10. + + + + + +Editeur XML + +L'outil le plus puissant d'Inkscape est l'éditeur XML (Maj+Ctrl+X). Affichant l'arborescence XML complète du document, il en reflète en permanence l'état courant. Vous pouvez modifier votre dessin et observer les changements correspondant dans la structure XML. De plus, vous pouvez éditer tout texte, élément ou attribut dans l'éditeur XML et voir le résultat sur le canevas. Cela permet des astuces et des modifications qui seraient impossibles avec un outil d'édition normal et c'est le meilleur moyen pour apprendre le SVG de façon interactive. + + + + + +Conclusion + +Ce didacticiel ne montre qu'une petite partie des possibilités d'Inkscape. Nous espérons que vous l'avez apprécié. N'ayez pas peur d'expérimenter et de nous faire part vos créations. Veuillez consulter www.inkscape.org pour avoir accès à plus d'information, aux dernières versions et à l'aide des communeautés de développeurs et utilisateurs. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/share/tutorials/tutorial-advanced.ja.svg b/share/tutorials/tutorial-advanced.ja.svg new file mode 100644 index 000000000..dd0800d9e --- /dev/null +++ b/share/tutorials/tutorial-advanced.ja.svg @@ -0,0 +1,314 @@ + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ::上級 + + + + + + + + +このチュートリアルはコピー/ペースト、ノード編集、自由曲線、ベジェ、パス操作、ブーリアン、オフセット、簡略化、テキストツールについて解説している。 +Ctrl+arrows 、 mouse wheel 、または middle button drag を使ってページをスクロールすることができる。基本的なオブジェクトの作成、選択、変形については、 ヘルプ > チュートリアル. から 基本 をみよ。 + + + + +ペースト術 + +あるオブジェクトをコピー Ctrl+C またはカット Ctrl+X +してから、通常のペーストコマンド( Ctrl+V )はマウスカーソルの下にオブジェクトをペーストする。もし、カーソルがウインドウの外にあればドキュメントウインドウの中心にペーストする。しかし、クリップボードにあるオブジェクトはコピーしてきた元の位置を記憶しているので、同じ場所にペースト( Ctrl+Alt+V ) +でその位置にペーストできる。 + + +別のコマンド、スタイルをペースト(Shift+Ctrl+V )は、現在のセッションのクリップボード中の(最初の)オブジェクトのスタイルを現在の選択に適用する。"スタイル"というのは、フィル、ストローク、フォント設定の全てであるが、シェイプと大きさ、星型の頂点数のようなシェイプタイプに固有のパラメータは含まれない。 + + +Inkscapeは自前のクリップボードを持っている; そしてテキストのコピー/ペースト以外ではシステムのクリップボードは使用しない。 + + + + +自由曲線と規則正しいパス + +任意のシェイプを作る最も簡単な方法は、ペンシル(自由曲線)ツールを使って描くことだ( F6): + + + + +もし、もっと規則正しい線が欲しければペン(ベジェ)ツール( Shift+F6 +)を使おう: + + + + +ペンツールでは clickごとにカーブハンドルを持たない鋭いノードができるので、複数のクリックは一連の線分を作る。 Click and dragでは同一直線上にある向かい合った2つのハンドルを持つベジェノードができる。ハンドルをドラッグ中に Shiftを押すと、ハンドルの一方を回転させ、もう一方を固定することができる。通常の使い方と同じように、 Ctrlは、現在の線分や、ベジェハンドルの方向を15度毎に制限する。 Enter で描画は確定する、 Escは描画を取り消す。終了していない線の最後の線分だけを取り消すには Backspaceを押せばよい。 + +自由曲線でもベジェでも、現在選択されているパスは両端に小さなアンカーが表示される。これらのアンカーから、新しい線を作る代わりにパスの継続(アンカーの一方から描画する)を行うことができるし、閉じる(一方のアンカーからもう一方に線を描く)こともできる。 + + + + +パスの編集 + +シェイプツールで作られたシェイプと異なり、ペンツールとペンシルツールはパスを作る。パスというのは一連の線分と、ベジェ曲線から成っており、他の Inkscape オブジェクトと同様に任意のフィルとストローク属性を持つことができる。しかし、シェイプと異なりパスはノード(と備え付けではないハンドルで)をドラッグすることで自由に編集することができる。このパスを選択してノードツール( F2)に切り替えよ: + + + + +沢山の灰色の正方形のノードがパスに上にあるだろう。このノードは click、 Shift+click で選択できるし、オブジェクトがセレクタで選択できるようにラバーバンドで dragして選択することも出来る。選択されたノードはハイライト表示され、ノードから直線で繋がれた1つもしくは2つの円、ノードハンドルが表示される。 + + +パスはノードとノードハンドルを dragして編集する(上のパスのノードとハンドルをドラッグしてみよ)。通常の使い方と同じように Ctrl は移動と回転を制限する。 arrowキー、 Tab 、 [ 、 ]、 < 、 >キーとその修飾キーはオブジェクトに対するセレクタと同じようにノードに対して働く。選択したノードを削除( Del)や複製( Shift+D )することもできる。パスは選択したノードから分割( Shift+B)でき、選択したノードが一つのパスの端点であれば連結( Shift+J )することもできる。 + + +ノードは角( Shift+C)にすることもできる、これは2つのハンドルが独立してどんな角度にでもできること;滑らか( Shift+S)にすることもできる、これはハンドルが常に一つの直線上にある(コリニア)こと;そして対称( Shift+Y)にすることもできる、これは滑らかと同じだがハンドルの長さが等しい。 + + +また、ハンドルの上で Ctrl+click するとノードのハンドルを引っ込めることができる。もし2つの近接するノードのハンドルが引っ込んでいると2つのノード間のパス区間が直線になる。ハンドルの引っ込んだノードからハンドルを引き出すにはノードから Shift+drag で引っ張り出す。 + + + + +サブパスと結合 +パスオブジェクトは1つ以上のサブパスを含んでいる。サブパスは各ノードごとの序列である(しかしながら、もしパスが1つ以上のサブパスを持っていても全てのノードが連結している訳ではない)。下の左図では1つの複合パスに3つのサブパスが属している;右図は同じサブパスが3つの独立したパスオブジェクトになっている: + + + + +複合パスはグループとは違うことを覚えておいて欲しい。複合パスは全体として選択できる一つのオブジェクトなのだ。もし、もし左図のオブジェクトを選択してノードツールに切り替えたら、3つのサブパスが表示されるのが分かるだろう。右図を選択すると1度に1つのパスのノード編集しかできないだろう。 + + +Inkscape はパスを結合して複合パスにすることができる( Ctrl+K )。また、複合パスを分割して独立したパスにすることもできる( Shift+Ctrl+K)。上図の例にこれらのコマンドを試してみよ。1つのオブジェクトは1つのフィルとストロークしか持てないので複合パスは最初(z順序で最背面)のオブジェクトのスタイルになる。 + + +フィルされている重なっているパスを結合すると、通常、重なっている部分のフィルが消える: + + + + +これは、穴のあるオブジェクトを作る最も簡単な方法である。さらに強力なパスコマンドについては、下の"ブーリアン操作"を見よ。 + + + + +パスに変換 + +シェイプとやテキストパスに変換(Shift+Ctrl+C )することができる。この変換はオブジェクトの見た目を変化させないが、オブジェクトの種類に固有の特徴を削除する(例えば、矩形やテキストの角を丸めることはできなくなる);代わりにノードの編集が可能になる。ここに2つの星型がある。左はシェイプを保っているが、右はパスに変換されている。ノードツールに切り替え、選択したときの編集性を比較せよ: + + + + +その上、どんなオブジェクトのストロークもパス("輪郭")に変換できる。下の最初のオブジェクトは元のパス(フィルなし、黒いストローク)、一方2番目のオブジェクトは"パスに変換"コマンドの結果である(フィルが黒でストロークなし): + + + + + + +ブーリアン操作 +パスメニューにあるコマンド、ブーリアン操作で2個以上のオブジェクトを結合することができる: + + +Original shapesUnion (Ctrl++)Difference (Ctrl+-)(bottom minus top)Intersection(Ctrl+*)Exclusion(Ctrl+^)Division(Ctrl+/)Cut Path(Ctrl+Alt+/) + +これらのコマンドのキーボードショートカットは代数演算とブーリアン操作の類似性で関連付けられている。(統合は加法、差分は減法等)。差分と切抜きコマンドは選択したオブジェクトが2つのときにのみ適用できる;その他は一回にいくつのオブジェクトを選択しても処理できる。結果は常に最背面のオブジェクトのスタイルを受け継ぐ。 + + +切抜きの結果は結合(上を見よ)の結果に似ている 、しかし切抜きは重なり合った部分にノードを追加するところが異なっている。分離とパスをカットは、前者は下のオブジェクトの全てを切り取るのに対し、後者はストロークのみを切断しフィルを取り除くところが異なる(フィルのないストロークをばらばらにするのに便利)。 + + + + +インセットとアウトセット +Inkscape はスケールだけではなくオブジェクトのパスをオフセットすることでもシェイプを拡張、収縮することができる、つまりパス上の全ての点を垂直に移動することができる。相当するコマンドはインセット( Ctrl+()アウトセット( Ctrl+))である。下に元になるパス(赤)とそこからの幾つかのインセットとアウトセットを示す: + + + + +普通のインセットとアウトセットコマンドはパスを生成する(元のオブジェクトがパスになっていない場合にはパスに変換する)。ときに、ダイナミックオフセット( Ctrl+J )が便利である。ダイナミックオフセットはオフセットの距離を制御するためのドラッグできるハンドル(シェイプのハンドルに似ている)を備えたオブジェクトを作る。下のオブジェクトを選択し、ノードツールに切り替えハンドルをドラッグして理解せよ: + + + + +このすばらしいダイナミックオフセットオブジェクトは元の形を覚えているので何度オフセットの距離を変更しても形状が"なまる"ことがない。変更可能な状態にしておく必要がなくなれば、このオフセットオブジェクトをいつでも元のパスに戻すことができる。 + + +さらにもっと便利なのはリンクしたオフセットである。これは動的オフセットの変更に似ているが、他の編集可能なパスに結合している。1つの元になるパスに対していくつでもリンクしたオフセットを作成できる。下の元にある赤いパスにはフィルなしの黒いストロークと、ストロークなしの黒いフィルがある。 + + +赤いオブジェクトを選択してノード編集をしてみよ;どのように両方のリンクしたオフセットが変化するか見てみよ。そして、オフセットオブジェクトを選択しオフセット値を変化させるハンドルをドラッグせよ。最後に、元のオブジェクトを変形したときに、リンクしているオブジェクトがどのように動いたか、どうやれば元のオブジェクトとの結合を切らさずにオフセットオブジェクトを独立して変形、移動できるかに注意せよ。 + + + + + + + +簡略化 + +主なパスの簡略化コマンドの( Ctrl+L )の用法は、形状をほぼ維持しつつパスのノード数を減らすことである。これはペンシルツールで作成したパスに有効である。なぜならペンシルツールは時に必要以上のノードを生成するからである。下の左のシェイプは自由曲線ツールで作成したもの、右のパスは左のパスをコピーして簡略化したものである。元のパスは28ノードあるが、簡略化した方は17ノード(これはノードツールでの作業が楽になることを意味している)でより滑らかである。 + + + + +簡略化の度合いは(閾値と呼ばれる)は選択オブジェクトの大きさによる。結果としてもし大きいオブジェクトに沿ったパスを選択したら、それは一つのパスを選択したばあいより積極的に簡略化しなくてはならないと言うことだ。その上簡略化コマンドは、高速化されている。 これはもし Ctrl+Lを何回も連続して押したら(各呼び出しの間隔が0.5秒以内になるぐらい)、閾値は呼び出しごとに大きくなる(一度休んだあとに次の呼び出しをすると閾値は既定の値にもどる)。高速化を使うことで、個々の場合に応じて正しく簡略化できる。 + + +自由曲線を滑らかにするのに加え、簡略化は様々な創造的効果として使うことができる。しばしば、ある度合いの簡略化は硬い幾何学的な元のシェイプの角をなめらかにし自然な歪みを加え、生物的な総合化を生み出す効果を与える。あるときそれはスタイリッシュであり、あるときそれは面白みを帯びる。ここに切り絵のシェイプが簡略化のあとでよりスタイリッシュになる例がある。 + + +OriginalSlight simplificationAggressive simplification + + + +テキストの作成 + +Inkscape は長くて複雑なテキストを作成できる。しかし、見出し、バナー、ロゴ、図表、注釈その他の小さなオブジェクトを作るのにも非常に便利である。この章ではとても基本的な Inkscape のテキスト機能について紹介する。 + + +テキストの作成はテキストツールに切り替える( F8 )のと同じくらい簡単で、ドキュメントのどこかをクリックしてテキストを打ち込むだけである。フォントファミリ、スタイル、サイズ、位置揃えの変更にはテキストアンドフォントダイアログを開けば ( Shift+Ctrl+T)よい。このダイアログにはテキスト入力タブがあり、選択したオブジェクトのテキストを変更できる。これはキャンバス上で直接編集を行うより便利な場合がある(特に、このタブはスペルチェック機能をもっている)。 + + +他のツールと同様に、テキストツールは "テキスト オブジェクト"; タイプを選択することができるので既存のテキストオブジェクトの上にカーソルを置いてクリックすると選択が可能である(この段落のように)。 + + +テキストデザインでもっとも一般的な操作は文字と文字列の隙間を調節することだ。いつものように Inkscapeはショートカットを用意している。テキストを編集するとき、 Alt+< と Alt+>キーでテキストオブジェクトの文字列の全長が現在のズーム(セレクタツールが同じキーでピクセル単位でオブジェクトをスケールするのと比較せよ)で1ピクセル分増減するように、字間を変えることができる。決まりとして、もしテキストオブジェクトのフォントサイズがデフォルトより大きい場合には、字間はデフォルトより少し狭めた方がいい感じになる。例を示す: + + +OriginalLetter spacing decreasedInspirationInspiration + +バリアントを狭めると見出し向けにはちょっと良くなったようだが、まだ完璧ではない:字間が均一なのだ、例えば "a" と "t" の間は離れ過ぎているし、"t" と "i" の間は狭すぎる。このようなまずい字間(特に大きなフォントサイズでは)は低品位のフォントで大きく、高品位のフォントでは小さい; しかし、おそらくどんなフォントのどんな文字列にも、カーニングの調整をすると良くなる文字の組み合わせというがあるだろう。 + + +Inkscape はこの調節を実に簡単に実行する。カーソルを気に入らない文字の間に移動して Alt+arrowsでカーソルの右側の文字を動かすことができる。また同じ見出しを見てみよう、今度は手作業で文字の位置が均等になるように調整したものだ: + + +Letter spacing decreased, some letter pairs manually kernedInspiration + +加えて、 Alt+Left と Alt+Rightで文字を水平方向にシフトできる。また Alt+Up と Alt+Downで垂直方向にシフトすることもできる。 + + +Inspiration + +もちろん、テキストをパスに変換( Shift+Ctrl+C)して、パスとして動かすことも可能だ。しかし、テキストはテキストのままで編集可能にしておく方がより便利だ。カーンの削除や字間の調整を施していない異なるフォントで試してみると、テキストは保存ファイルがとても小さくなるのがわかる。テキストをテキストとしておくことの唯一の欠点は SVGドキュメントを開くときにオリジナルのフォントをインストールしておく必要があることだ。 + + +字間の調節と似て、複数行のテキストオブジェクトの行間の調節も行うことができる。 Ctrl+Alt+< と Ctrl+Alt+>キーでチュートリアル中のどの段落の高さでも現在のズームで1ピクセルごとに調整できることを試してみよ。セレクタと同様、 Shiftを押すことで字間調整のショートカットも10倍の値で変化する。 + + + + +XML エディタ + +Inkscape における究極の強力なツールは XML エディタ ( Shift+Ctrl+X +)である。XML エディタはドキュメントの XML ツリー全体を表示し、現在の状態を常に反映する。絵を編集して、相当する XMLツリーの変化を見ることができる。さらに、XML エディタ上で、テキスト、要素、属性ノードを編集してキャンバスでその結果を確認することもできる。これは SVG を対話的に学ぶための想像しうる最高のツールであり、通常の編集ツールではできないワザを使うこともできる。 + + + + +最後に + +このチュートリアルは Inkscape の機能のごく一部について紹介している。このチュートリアルを楽しんでいただけたことを望んでいる。実験することを恐れず、作り出したものは共有しよう。www.inkscape.orgを訪れてより多くの情報と、最新のバージョン、ユーザと開発者からのヘルプを手に入れよ。 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/share/tutorials/tutorial-advanced.sl.svg b/share/tutorials/tutorial-advanced.sl.svg new file mode 100644 index 000000000..f77958a5f --- /dev/null +++ b/share/tutorials/tutorial-advanced.sl.svg @@ -0,0 +1,411 @@ + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ::NAPREDNE TEHNIKE + + + + + + + +Ta vodič zajema urejanje oblike in vozlišč, prostoročno risanje in risanje +bezier krivulj, urejanje poti, matematične operacije, zamikanje, poenostavljanje, +uporabo besedil. + +Pomikajte se navzdol s Ctrl+smerniki, miškinim koleščkom, ali potegom s srednjim gumbom. Za osnove ustvarjanja predmetov, izbiranje in preoblikovanje si oglejte osnovnega vodiča v Pomoč > Vodiči. + + + + +Metode lepljenja + +Potem ko ste nekaj predmetov skopirali (Ctrl+C) ali izrezali (Ctrl+X) na odložišče, jih lahko z običajnim ukazom prilepi (Ctrl+V) vlepite pod miškin kazalec, ali v središče okna, če je kazalec izven njega. Predmeti na odložišču si sicer zapomnijo svoja izvirna mesta, kamor jih lahko vplepite z +ukazom Prilepi naravnost (Ctrl+Alt+V). + + +S kombinacijo Shift+Ctrl+V lahko prilepite slog, torej slog prvega predmeta z odložišča uporabite na trenutno izbranem. "Slog" obsega +vse nastavitve polnjenja, poteze in pisave, ne pa lastnosti značilnih +za posamezne like, kot je na primer število kotov večkotnika. + + +Inkscape uporablja svoje lastno odložišče, ne pa sistemskega, razen pri delu z besedili. + + + + +Risanje prostoročnih in običajnih črt + +Najlažji način za stvaritev poljubne oblike je, da jo narišete z orodjem +za prostoročno risanje - svinčnikom (F6): + + + + +Za pravilnejše oblike je orodje za bezier krivulje - pero (Shift+F6): + + + + +S tem orodjem vsak klik ustvari ostro vozlišče, brez kontrolnih ročic, tako da zaporedje klikov ustvari zaporedje ravnih črt. Vsak klik in poteg ustvari mehko Bezier vozlišče z dvema povezanima ročicama. Med vlečenjem ročice držite Shift, če želite premakniti le eno ročico. Kot običajno, držanje Ctrl omeji +usmeritev odseka črte ali ročice na 15-stopinjske korake. Enter +dokonča črto, Esc jo prekliče. Če želite preklicati le zadnji odsek nedokončane črte pritisnite Backspace. + +V obeh orodjih pritisk na "a" pokaže sidra prikaza na obeh koncih izbrane poti, tako da jo lahko nadaljujete, namesto da začenjate novo; ali pa jo zaključite, tako da povežete nasprotni sidri. + + + + +Urejanje poti + +Za razliko od orodij, ki ustvarijo like, orodji za prostoročno risanje +in risanje krivulj ustvarita tako imenovane poti. Pot je zaporedje +odsekov črt ali krivulj, ki ima - kot vsak drug predmet - poljubno polnilo +in obris. V nasprotju z liki lahko poti preurejamo tako, da poljubno +premikamo katerakoli vozlišča, ne le vnaprej določenih ročic. Izberite +naslednjo pot z izbirnikom in nato izberite orodje za urejanje vozlišč +(F2): + + + + +Na poti boste videli več sivih kvadratnih vozlišč. Kot pri izbiranju +predmetov lahko tudi ta vozlišča izberete s klikom, Shift+klikom ali s potegom elastike. Izbrana vozlišča se osvetlijo in pokažejo svoje ročice — mali krogci, ki so povezani z vozlišči. + + +Poti urejate s premikanjem vozlišč ali njihovih ročic. Ctrl kot +ponavadi omejuje gibanje ali vrtenje. Smerne tipke, Tab, +[, ], <, > zopet delujejo kot pri izbirniku, le da se tu nanašajo na vozlišča. Izbrana vozlišča lahko izbrišete (Del) ali podvojite (Shift+D), na njih lahko prelomite pot (Shift+B). Če izberete dve končni vozlišči na isti poti, ju lahko združite (Shift+J). + + +Vozlišča so lahko groba (Shift+C), kar pomeni, da se njihove ročice premikajo neodvisno; gladka (Shift+S), kar pomeni, da so ročice vedno na isti ravni črti; ali simetrična (Shift+Y), kar je isto kot mehko, le da so ročice tudi enako dolge. + + +Ročico vozlišča lahko tudi popolnoma skrajšate s Ctrl+klikom nanjo. Če dvema sosednjima vozliščema skrajšate ročici, postane odsek poti med njima ravna črta. Če želite spet izvleči ročico, jo Shift+potegnite iz vozlišča. + + + + +Podpoti in združevanje +Pot lahko obsega več podpoti. Podpot je zaporedje povezanih vozlišč. +Tako ni treba, da so vsa vozlišča v poti povezana. Tri podpoti spodaj +levo pripadajo eni sestavljeni poti; iste tri podpoti na desni so +neodvisni predmeti: + + + + +Vendar pa sestavljena pot ni isto kot skupina. Je enoten predmet, izberemo +ga lahko le v celoti. Če izberete zgornji levi predmet in preklopite na +orodje za vozlišča, boste videli vozlišča po vseh treh podpoteh. Na +desni lahko urejate le vsako pot posebej. + + +Inkscape zna sestaviti poti v sestavljeno pot (Ctrl+K) in razstaviti sestavljeno pot v ločene podpoti (Shift+Ctrl+K). Poskusite te ukaze na gornjih primerih. Ker ima predmet lahko le eno polnilo in obrobo, dobi +sestavljena pot slog prvega, tj. najnižjega predmeta. + + +Če sestavljate prekrivajoče poti s polnilom, bo na mestih, kjer se poti +prekrivajo, polnilo izginilo: + + + + +To je najlažji način za ustvarjanje objektov z luknjami. Za močnejše operacije s potmi si oglejte "Matematične operacije" spodaj. + + + +------------------------------------ + + +Pretvarjanje v poti + +Vsako obliko ali besedilo lahko pretvorite v pot (Shift+Ctrl+C), kar ne bo spremenilo oblike predmeta, bo pa odstranilo vse posebne +zmožnosti tiste oblike. (Ne morete več, na primer, zaobljiti robov pretvorjenega pravokotnika, ali urejati besedila); namesto tega boste lahko urejali vozlišča. Tu +imamo dve zvezdi, ena je še vedno lik, druga pa je pretvorjena v pot. +Preklopite na orodje za vozlišča in primerjajte možnosti urejanja: + + + + +Še več, tudi vsaka poteza je lahko obrisana, tj. pretvorjena v pot ("obris"). Prvi predmet spodaj je izvirna pot (brez polnila, črna črta), +drugi pa je pretvorjen v pot (črno polnilo, brez obrisa) z ukazom Poteza v pot: + + + + + + +Matematične operacije +Ukazi v meniju Pot vam omogočajo sestavljanje dveh ali več +predmetov z matematičnimi operacijami: + + +Original shapesUnion (Ctrl++)Difference (Ctrl+-)(bottom minus top)Intersection(Ctrl+*)Exclusion(Ctrl+^)Division(Ctrl+/)Cut Path(Ctrl+Alt+/) + +Bližnjice za te ukaze spominjajo na aritmetični pomen teh +matematičnih operacij (Unija je dodajanje, Razlika je odštevanje,...). +Razlika in Odvzem delujeta le na dveh izbranih predmetih, ostali pa na poljubnem številu predmetov hkrati. Rezultat vedno prevzame slog najnižjega +predmeta. + + +Rezultat Odvzema spominja na Sestavljanje (glej zgoraj), a doda vozlišča na mestih, kjer se poti sekajo. Razlika med Deljenjem in +Izrezom poti je, da Deljenje izreže celoten spodnji predmet po poti +zgornjega, Izrez poti pa izreže le obris spodnjega predmeta in odstrani +polnilo (to je prikladno za razrez nezapolnjenih potez na koščke). + + + + +Razširjenje in zožanje +Inkscape zna tudi brez raztegovanja razširiti in zožati oblike. To naredi z zamikanjem predmetove poti, t.j. vzporednim premikom vsake +točke poti. Ustrezna ukaza sta Razširi (Ctrl+() in Zožaj (Ctrl+)). Spodaj vidite izvirno pot (rdeča) in več poti, ki so razširjenja ali zožanja: + + + + +Običajna raba teh ukazov ustvari pot (in pretvori tudi izvorni predmet +v pot). Pogosteje nam koristi Dinamični zamik (Ctrl+J), ki ustvari predmet s premično ročico, ki nadzoruje razdaljo odmika. Izberite +spodnji predmet, preklopite na orodje za vozlišča in preknite ročice: + + + + + + +Predmet, ki je dinamičen zamik svojega izvirnika, si zapomni izvorno pot, tako da se +natančnost ne izgublja z večkratnim spreminjanjem. Ko ste končali, +ga lahko vedno pretvorite nazaj v pot. + + + +Še bolj udoben je povezan zamik, ki deluje podobno kot dinamičen, +le da je povezan z neko drugo potjo, ki pa jo lahko še vedno urejate. Iz ene izvorne poti lahko ustvarite praktično neomejeno število povezanih zamikov. Spodaj vidite +rdečo izvorno pot in en povezan zamik s črnim polnilom in brez obrisa, +ter drugi povezan zamik brez polnila s črno črto. + + +Izberite rdeči predmet in mu spremenite vozlišča. Opazujte spreminjanje +povezanih predmetov. Izberite kakega od njiju in mu prilagodite zamik. +Poskusite tudi premakniti izvirnik - povezani zamiki mu sledijo, hkrati +pa jih lahko ločeno premikate ali preoblikujete. + + + + + + + +Poenostavljanje + +Glavna uporaba ukaza Poenostavi (Ctrl+L) je zmanjšanje števila vozlišč na poti, ob približnem ohranjanju oblike. To je koristno pri prostoročnih poteh, ki so včasih bolj zapletene, kot bi bilo treba. Spodaj levo je oblika +narisana prostoročno, desno pa njen poenostavljeni dvojnik. Izvirna +pot ima 28 vozlišč, poenostavljena pa 17. Poenostavljena je zato +gladkejša in lažje ji urejamo vozlišča. + + + + +Količina poenostavljanja (ali grobost) je odvisna od velikosti izbire. +Zato bo, če izberete pot, skupaj s kakim večjim predmetom, ta +agresivneje poenostavljena, kot če bi jo izbrali samo. Ta ukaz je tudi +pospešen. To pomeni, da če večkrat zaporedoma in s kratkimi +presledki (manj kot pol sekunde) pritisnete Ctrl+L, bo agresivnost +vsakič večja. Po krajšem premoru bo agresivnost spet privzeta. Z +uporabo poseševanja je enostavna natančna uporaba poenostavljanja. + + +Razen za glajenje prostoročnih črt je ta ukaz koristen za kreativne +učinke. Pogosto kaka ostra oblika pridobi na življenjskosti, če jo malce +zgladimo. Tu je primer risbe, ki tako precej pridobi na privlačnosti: + + +OriginalSlight simplificationAggressive simplification + + + +Ustvarjanje besedil + +Inkscape je sposoben urejati daljša in zapletena besedila, hkrati pa je priročen pri ustvarjanju kratkih besednih predmetov, kot so naslovi, oglasi, logotipi, diagrami, nalepke,... V tem delu bomo na kratko predstavili te možnosti. + + +Ustvarjanje besedilnega predmeta je enostavno - izberete orodje za +besedila (F8), kliknete nekam v dokument in pišete. Za +spreminjanje pisave, sloga in velikosti odprite pogovorno okno +Besedilo in pisava (Shift+Ctrl+T). Tam lahko besedilo tudi pišete v +posebno okence, kar je včasih lažje, kot pa neposredno na platno (če +nič drugega, to okence podpira kopiranje in lepljenje iz sistemskega +odložišča, ter sprotno preverjanje črkovanja). + + +Kot ostala orodja, lahko tudi z orodjem za besedila izberete predmete svoje +vrste (besedilne predmete). Tako lahko enostavno kliknete in s tem +izberete in takoj nastavite kazalec v katerikoli besedilni predmet (kot +je na primer ta odstavek). + + +Ena pogostejših operacij pri oblikovanju besedila je popravljanje +razmikov med črkami in črtami. Kot vedno imamo tudi za to priročne +bližnjice: Alt+< in Alt+>. S tem spremenite razmik med črkami v trenutni vrstici tako, da se dolžina vrstice spremeni za eno točko pri trenutnem pogledu. Večina besedil z velikostjo pisave večjo od +običajne izgleda bolje, če jo malce stisnemo. Tu imamo primer: + + +OriginalLetter spacing decreasedInspirationInspiration + +Stisnjena različica bi bila boljši naslov, a še vedno ni popolna: presledki +med črkami niso enakomerni. "a" in "t" sta recimo predaleč narazen, +medtem ko sta "t" in "i" preblizu. Količina takšnih slabih presledkov je +odvisna od kakovosti uporabljene pisave, a celo pri najboljših boste +našli pare črk, ki jih bo potrebno popraviti. + + +V Inkscapu je to enostavno; enostavno premaknite kazalec za +urejanje besedila med željeni črki in uporabite Alt+smerne tipke, da +premaknete črko na desni od kazalca. Še enkrat isti naslov, to pot z +ročno popravljenimi razmaki: + + +Letter spacing decreased, some letter pairs manually kernedInspiration + +Poleg premikanja črk levo in desno z ukazi Alt+levo ali +Alt+desno jih lahko zamaknete tudi gor in dol, če pritisnete Alt+gor ali Alt+dol. Poskusite te kombinacije na kateremkoli odstavku tega vodiča. + + +Inspiration + +Lahko pa bi seveda tudi pretvorili besedilo v pot (Shift+Ctrl+C) in +premikali črke kot običajne poti. Vendar pa je precej bolj koristno obdržati +besedilo kot besedilo, saj ga tako lahko popravljamo, preiskušamo +različne pisave (ne da bi odstranili zgoščevanja), pa še manj prostora +zasede v datoteki. Edina slabost je, da morate za pravilen izris imeti +nameščeno enako pisavo na vsakem računalniku, kjer želite dokument +odpreti. Če Inkscape ne bo našel natanko iste pisave, vas bo na to opozoril. + + +Podobno kot razmik med črkami lahko prilagajate tudi razmik med vrsticami. Poskusite Ctrl+Alt+< in +Ctrl+Alt+> na kateremkoli odstavku tega vodiča. S tem +spremenite razmike tako, da se celotna višina predmeta spremeni za +1 točko pri trenutnem pogledu. Kot tudi pri Izbirniku, hkratno držanje Shifta +podeseteri učinek. + + + + +Urejevalnik XML + +Inkscapovo najmočnejše orodje je Urejevalnik XML (Shift+Ctrl+X). +Prikazuje celotno XML drevo dokumenta in vedno odraža trenutno +stanje. V njem lahko urejate vašo risbo in opazujete spremembe, +lahko pa v njem tudi prilagajate lastnosti in rezultat takoj vidite na platnu. To je +tudi najboljše orodje za spoznavanje SVGja, saj omogoča nekatere +trike, ki jih ne morete opraviti z običajnimi orodji. + + + + +Zaključek + +Ta vodič pokaže le del vseh zmogljivosti Inkscapa. Upamo, da vam +je bil všeč. Ne bojte se eksperimentiranja in svoje stvaritve delite z drugimi. +Za več informacij, najnovejše različice in nadaljno pomoč s strani uporabnikov +in razvijalcev obiščite www.inkscape.org. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/share/tutorials/tutorial-advanced.svg b/share/tutorials/tutorial-advanced.svg new file mode 100644 index 000000000..cb5bea2cd --- /dev/null +++ b/share/tutorials/tutorial-advanced.svg @@ -0,0 +1,475 @@ + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ::ADVANCED + + + + + + + +This tutorial covers copy/paste, node editing, freehand and bezier +drawing, path manipulation, booleans, offsets, simplification, and text tool. + +Use Ctrl+arrows, mouse wheel, or middle button +drag to scroll the page down. For basics of object creation, selection, and +transformation, see the Basic tutorial in Help > Tutorials. + + + + +Pasting techniques + +After you copy some object(s) by Ctrl+C or cut by +Ctrl+X, the regular Paste command +(Ctrl+V) pastes the copied object(s) right under the mouse cursor or, +if the cursor is outside the window, to the center of the document window. However, the +object(s) in the clipboard still remember the original place from which they were +copied, and you can paste back there by Paste in Place +(Ctrl+Alt+V). + + +Yet another command, Paste Style (Shift+Ctrl+V), +applies the style of the (first) object on the clipboard to the current selection. The +"style" thus pasted includes all the fill, stroke, and font settings, but not the shape, +size, or parameters specific to a shape type, such as the number of tips of a star. + + +Note that Inkscape has its own internal clipboard; it does not use the system clipboard +except for copying/pasting text by the Text tool. + + + + +Drawing freehand and regular paths + +The easiest way to create an arbitrary shape is to draw it using the +Pencil (freehand) tool (F6): + + + + +If you want more regular shapes, use the Pen (Bezier) tool (Shift+F6): + + + + +With the Pen tool, each click creates a sharp node without any curve +handles, so a series of clicks produces a sequence of straight line segments. +Click and drag creates a smooth Bezier node with two collinear opposite +handles. Press Shift while dragging out a handle to rotate only one +handle and fix the other. As usual, Ctrl limits the direction of either +the current line segment or the Bezier handles to 15 degree increments. Pressing +Enter finalizes the line, Esc cancels it. To cancel +only the last segment of an unfinished line, press Backspace. + +In both freehand and bezier tools, the currently selected path displays small square +anchors at both ends. These anchors allow you to +continue this path (by drawing from one of the anchors) or +close it (by drawing from one anchor to the other) instead of creating a +new one. + + + + +Editing paths + +Unlike shapes created by shape tools, the Pen and Pencil tools create what is called +paths. A path is a sequence of straight line segments and/or +Bezier curves which, as any other Inkscape object, may have arbitrary fill and stroke +properties. But unlike a shape, a path can be edited by freely dragging any of its nodes +(and not just predefined handles). Select this path and switch to Node tool +(F2): + + + + +You will see a number of gray square nodes on the path. These +nodes can be selected by click, +Shift+click, or by dragging a rubberband — +exactly like objects are selected by the Selector tool. Selected nodes become +highlighted and show their node handles — one or two +small circles connected to each selected node by straight lines. + + +Paths are edited by dragging their nodes and node handles. (Try to drag +some nodes and handles of the above path.) Ctrl works as usual to +restrict movement and rotation. The arrow keys, Tab, +[, ], <, > keys +with their modifiers all work just as they do in selector, but apply to nodes instead of +objects. You can delete (Del) or duplicate (Shift+D) +selected nodes. The path can be broken (Shift+B) at the selected nodes, +or if you select two endnodes on one path, you can join them (Shift+J). + + +A node can be made cusp (Shift+C), which means +its two handles can move independently at any angle to each other; +smooth (Shift+S), which means its handles are +always on the same straight line (collinear); and symmetric +(Shift+Y), which is the same as smooth, but the handles also have the +same length. + + +Also, you can retract a node's handle altogether by +Ctrl+clicking on it. If two adjacent nodes have their handles +retracted, the path segment between them is a straight line. To pull out the retracted +node, Shift+drag away from the node. + + + + +Subpaths and combining +A path object may contain more than one subpath. A subpath is a +sequence of nodes connected to each other. (Therefore, if a path has more than one +subpath, not all of its nodes are connected.) Below left, three subpaths belong to a +single compound path; the same three subpaths on the right are independent path objects: + + + + +Note that a compound path is not the same as a group. It's a single object which is only +selectable as a whole. If you select the left object above and switch to node tool, you +will see nodes displayed on all three subpaths. On the right, you can only node-edit one +path at a time. + + +Inkscape can Combine paths into a compound path +(Ctrl+K) and Break Apart a compound path into +separate paths (Shift+Ctrl+K). Try these commands on the above +examples. Since an object can only have one fill and stroke, a new compound path gets +the style of the first (lowest in z-order) object being combined. + + +When you combine overlapping paths with fill, usually the fill will disappear +in the areas where the paths overlap: + + + + +This is the easiest way to create objects with holes in them. For more powerful path +commands, see "Boolean operations" below. + + + + +Converting to path + +Any shape or text object can be converted to path +(Shift+Ctrl+C). This operation does not change the appearance of the +object but removes all capabilities specific to its type (e.g. you can't round the +corners of a rectangle or edit the text anymore); instead, you can now edit its +nodes. Here are two stars — the left one is kept a shape and the right one is +converted to path. Switch to node tool and compare their editability when selected: + + + + +Moreover, you can convert to a path ("outline") the stroke of any +object. Below, the first object is the original path (no fill, black stroke), while the +second one is the result of the Stroke to Path command (black fill, +no stroke): + + + + + + +Boolean operations +The commands in the Path menu let you combine two or more objects using +boolean operations: + + +Original shapesUnion (Ctrl++)Difference (Ctrl+-)(bottom minus top)Intersection(Ctrl+*)Exclusion(Ctrl+^)Division(Ctrl+/)Cut Path(Ctrl+Alt+/) + +The keyboard shortcuts for these commands allude to the arithmetic analogs of the +boolean operations (union is addition, difference is subtraction, etc.). The +Difference and Exclusion commands can only apply +to two selected objects; others may process any number of objects at once. The result +always receives the style of the bottom object. + + +The result of the Exclusion command looks similar to +Combine (see above), but it is different in that +Exclusion adds extra nodes where the original paths intersect. The +difference between Division and Cut Path is that +the former cuts the entire bottom object by the path of the top object, while the latter +only cuts the bottom object's stroke and removes any fill (this is convenient for +cutting fill-less strokes into pieces). + + + + +Inset and outset +Inkscape can expand and contract shapes not only by scaling, but also by +offsetting an object's path, i.e. by displacing it perpendicular +to the path in each point. The corresponding commands are called +Inset (Ctrl+() and Outset +(Ctrl+)). Shown below is the original path (red) and a number of paths +inset or outset from that original: + + + + +The plain Inset and Outset commands produce paths +(converting the original object to path if it's not a path yet). Often, more convenient +is the Dynamic Offset (Ctrl+J) which creates an +object with a draggable handle (similar to a shape's handle) controlling the offset +distance. Select the object below, switch to the node tool, and drag its handle to get +an idea: + + + + +Such a dynamic offset object remembers the original path, so it +does not "degrade" when you change the offset distance again and again. When you don't +need it to be adjustable anymore, you can always convert an offset object back to path. + + +Still more convenient is a linked offset, which is similar to the +dynamic variety but is connected to another path which remains editable. You can have +any number of linked offsets for one source path. Below, the source path is red, one +offset linked to it has black stroke and no fill, the other has black fill and no +stroke. + + +Select the red object and node-edit it; watch how both linked offsets respond. Now +select any of the offsets and drag its handle to adjust the offset radius. Finally, note +how moving or transforming the source moves all offset objects linked to it, and how you +can move or transform the offset objects independently without losing their connection +with the source. + + + + + + + +Simplification + +The main use of the Simplify command (Ctrl+L) is +reducing the number of nodes on a path while almost preserving its +shape. This may be useful for paths created by the Pencil tool, since that tool +sometimes creates more nodes than necessary. Below, the left shape is as created by the +freehand tool, and the right one is a copy that was simplified. The original path has 28 +nodes, while the simplified one has 17 (which means it is much easier to work with in +node tool) and is smoother. + + + + +The amount of simplification (called the threshold) depends on +the size of the selection. Therefore, if you select a path along with some larger +object, it will be simplified more aggressively than if you select that path +alone. Moreover, the Simplify command is +accelerated. This means that if you press Ctrl+L +several times in quick succession (so that the calls are within 0.5 sec from each +other), the threshold is increased on each call. (If you do another Simplify after a +pause, the threshold is back to its default value.) By making use of the acceleration, it +is easy to apply the exact amount of simplification you need for each case. + + +Besides smoothing freehand strokes, Simplify can be used for various +creative effects. Often, a shape which is rigid and geometric benefits from some amount +of simplification that creates cool life-like generalizations of the original form — +melting sharp corners and introducing very natural distortions, sometimes stylish and +sometimes plain funny. Here's an example of a clipart shape that looks much nicer after +Simplify: + + +OriginalSlight simplificationAggressive simplification + + + +Creating text + +Inkscape is capable of creating long and complex texts. However, it's also pretty +convenient for creating small text objects such as heading, banners, logos, diagram +labels and captions, etc. This section is a very basic introduiction into Inkscape's +text capabilities. + + +Creating a text object is as simple as switching to the Text tool (F8), +clicking somewhere in the document, and typing your text. To change font family, style, +size, and alignment, open the Text and Font dialog (Shift+Ctrl+T). That +dialog also has a text entry tab where you can edit the selected text object - in some +situations, it may be more convenient than editing it right on the canvas (in +particular, that tab supports as-you-type spell checking). + + +Like other tools, Text tool can select objects of its own type — text objects +— so you can click to select and position the cursor in any existing text object +(such as this paragraph). + + +One of the most common operations in text design is adjusting spacing between letters +and lines. As always, Inkscape provides keyboard shortcuts for this. When you are +editing text, the Alt+< and Alt+> keys change +the letter spacing in the current line of a text object, so that +the total length of the line changes by 1 pixel at the current zoom (compare to Selector +tool where the same keys do pixel-sized object scaling). As a rule, if the font size in +a text object is larger than the default, it will likely benefit from squeezing letters +a bit tighter than the default. Here's an example: + + +OriginalLetter spacing decreasedInspirationInspiration + +The tightened variant looks a bit better as a heading, but it's still not perfect: the +distances between letters are not uniform, for example the "a" and "t" are too far apart +while "t" and "i" are too close. The amount of such bad kerns (especially visible in +large font sizes) is greater in low quality fonts than in high quality ones; however, in +any text string and in any font you will probably find pairs of letters that will +benefit from kerning adjustments. + + +Inkscape makes these adjustments really easy. Just move your text editing cursor between +the offending characters and use Alt+arrows to move the letters right +of the cursor. Here is the same heading again, this time with manual adjustments +for visually uniform letter positioning: + + +Letter spacing decreased, some letter pairs manually kernedInspiration + +In addition to shifting letters horizontally by Alt+Left or +Alt+Right, you can also move them vertically by using +Alt+Up or Alt+Down: + + +Inspiration + +Of course you could just convert your text to path (Shift+Ctrl+C) and +move the letters as regular path objects. However, it is much more convenient to keep +text as text — it remains editable, you can try different fonts without removing +the kerns and spacing, and it takes much less space in the saved file. The only +disadvantage to the "text as text" approach is that you need to have the original font +installed on any system where you want to open that SVG document. + + +Similar to letter spacing, you can also adjust line spacing in +multi-line text objects. Try the Ctrl+Alt+< and +Ctrl+Alt+> keys on any paragraph in this tutorial to space it in or out +so that the overall height of the text object changes by 1 pixel at the current zoom. +As in Selector, pressing Shift with any spacing or kerning shortcut +produces 10 times greater effect than without Shift. + + + + +XML editor + +The ultimate power tool of Inkscape is the XML editor (Shift+Ctrl+X). +It displays the entire XML tree of the document, always reflecting its current +state. You can edit your drawing and watch the corresponding changes in the XML +tree. Moreover, you can edit any text, element, or attribute nodes in the XML editor and +see the result on your canvas. This is the best tool imaginable for learning SVG +interactively, and it allows you to do tricks that would be impossible with regular +editing tools. + + + + +Conclusion + +This tutorial shows only a small part of all capabilities of Inkscape. We hope you +enjoyed it. Don't be afraid to experiment and share what you create. Please visit www.inkscape.org for more information, latest +versions, and help from user and developer communities. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/share/tutorials/tutorial-basic.ca.svg b/share/tutorials/tutorial-basic.ca.svg new file mode 100644 index 000000000..07cdda472 --- /dev/null +++ b/share/tutorials/tutorial-basic.ca.svg @@ -0,0 +1,650 @@ + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ::BASIC + + + + + + + +Aquest tutorial us mostrarà l'ús bàsic de l'Inkscape. Aquest és un document +Inkscape normal. Podeu visualitzar-lo, editar-lo i fins i tot desar-lo. + + +El tutorial bàsic cobreix el desplaçament i l'ampliació, la gestió de documents, +les eines de forma, la transformació d'objectes amb el selector, les tècniques +de selecció, l'agrupació, la configuració de l'emplenat i el contorn, +l'alineació i l'ordenació en z. Per a altres temes, consulteu el tutorial +avançat al menú d'Ajuda. + + + + + + +Desplaçament de l'àrea de dibuix + + + + +Hi ha vàries maneres de desplaçar l'àrea de dibuix. Proveu-ho +amb les tecles Ctrl+fletxa per a desplaçar-la amb el teclat. +(Proveu de moure aquest document avall.) També podeu arrossegar-la amb el +botó central del ratolí. Podeu usar les barres de desplaçament +(premeu Ctrl+B per a veure-les o amagar-les). També funciona el +desplaçament vertical amb la rodeta del vostre ratolí; +i si premeu Maj., l'horitzontal. + + + + + +Ampliació i reducció +La forma més fàcil d'ampliar/reduir és amb les tecles - +i + (o =). També podeu usar +Ctrl+botó central o Ctrl+botó dret per ampliar, +Maj+botó central o Maj+botó dret per allunyar, +o girant la rodeta del ratolí amb Ctrl. També clicant al +camp d'entrada d'ampliació (a l'angle inferior esquerra de la finestra del +document), entreu un valor precís en %, i premeu Entrar. També tenim +l'eina ampliar (a la barra d'eines de l'esquerra) que ens permet ampliar +una zona enmarcant-la. +L'Inkscape manté un historial dels nivells d'ampliació usats. Premeu la tecla +` per anar a l'anterior ampliació, i Maj+` per anar +al següent. + + + + + +Les eines de l'Inkscape +La barra d'eines vertical a l'esquerra mostra les eines de dibuix i edició +de l'Inkscape. Sota el menú, hi ha la Barra d'ordres amb +botons d'ordres generals i la Barra de controls +d'eina amb controls específics per a cada eina. La barra +d'estat a la part inferior de la finestra mostrarà consells i +missatges útils mentre esteu treballant. + +Moltes operacions són accessibles mitjançant dreceres de teclat. Obriu +Ajuda > Tecles i ratolí per a veure la referència completa. + + + +Creació i gestió de documents +Per a crear un nou document en blanc, useu Fitxer > Nou o +Ctrl+N. Per a obrir un document SVG existent, useu Fitxer > +Obre (Ctrl+O). Per a desar, premeu Fitxer > Desa +(Ctrl+S), o Anomena i desa (Maj+Ctrl+S) +per a desar amb un nom nou. L'Inkscape encara es pot considerar inestable, per tant +deseu la feina sovint! + +L'Inkscape usa el format SVG (Imatges de vectors escalables) per als seus +fitxers. L'SVG és un estàndard obert àmpliament suportat pel programari d'imatges. +Els fitxers SVG es basen en XML i poden ser editats per qualsevol editor +de text o XML (a banda de l'Inkscape, és clar). A més d'SVG, l'Inkscape +pot importar i exportar diferents tipus de format (EPS, PNG). + +L'Inkscape obre una finestra separada per a cada document. Podeu navegar entre +elles usant el vostre gestor de finetres (per exemple amb Alt+Tab), +o podeu usar la drecera de l'Inkscape, Ctrl+Tab, que es mourà en +cicle entre totes les finestres obertes. (Creeu un nou document i canvieu entre +aquest i l'altre per a practicar). + + + + + +Creació de formes +I ara, unes formes boniques! Cliqueu a l'eina del rectangle a la barra +d'eines (o premeu F4) i cliqueu i arrossegueu, en un nou document en +blanc o bé aquí mateix: + + + +Com podeu veure, el rectangles per defecte són blaus, amb una vora (contorn) negra, +d'1 pt, i parcialment transparents. Tot seguit veurem com canviar-ho. +També podeu crear el·lipsis, estrelles i espirals: + + + +Aquestes eines es coneixen col·lectivament com a eines de forma. Cada +forma que creeu mostra un o més manejadors. Proveu +d'arrossegar-los per veure com respon la forma. El panell superior per a +les eines de forma té alguns controls que també podeu tocar per canviar +els paràmetres de la forma. Aquests controls afecten la forma que hi ha +seleccionada (la que mostren els manejadors) i defineix els valors per defecte +que s'aplicaran a les noves formes que es creïn. + +Per a desfer la vostra última acció, premeu +Ctrl+Z. (O si torneu a canviar d'idea, podeu +tornar-la a fer amb Maj+Ctrl+Z). + + + + + +Moviment, escalat, gir + +L'eina més usada de l'Inkscape és el +Selector. Cliqueu el botó amb la +fletxa que hi ha a dalt de tot de la barra d'eines (o premeu +F1 o Espai). Ara podeu seleccionar qualsevol +objecte de l'àrea de dibuix. Cliqueu +sobre el rectangle de sota. + + + + + +Veureu com apareixen vuit manejadors en forma de fletxa al voltant. +Ara podeu: + + +Mourel'objecte arrossegant-lo. (Premeu Ctrl per limitar el moviment +a horitzontal i vertical). + + +Escalar l'objecte original arrossegant un manejador. (Premeu Ctrl per +conservar la relació alçada/amplada original). + + + + + + + +Ara torneu a clicar el rectangle. Els manejadors canvien. Ara podeu: + + + +Girar l'objecte arrossegant +els manejadors de les cantonades. (Amb Ctrl limiteu +la rotació a passos de 15 graus. Arrossegueu la marca de la +creu per posicionar el centre de rotació). + + +Esbiaixar (cisallar) l'objecte arrossegant +els manejadors dels costats. (Amb Ctrl limiteu +la rotació a passos de 15 graus. Arrossegueu la marca de la +creu per posicionar el centre de rotació). + + + + +També podeu usar els camps d'entrada numèrica del panell superior per a +introduir valors exactes per a les coordenades (X i Y) i la mida (alçada i amplada) de +la selecció. + + + + + +Transformació mitjançant tecles + +Una de les característiques de l'Inkscape que el fa diferent de la majoria +d'editors vectorials és l'èmfasi en l'accessibilitat pel teclat. Difícilment +trobarem cap ordre o acció que no sigui possible fer des del teclat, i la +transformació d'objectes no és cap excepció. + +Podeu usar el teclat per moure (tecles de les fletxes), escalar +(tecles < i >), i girar (tecles [ +i ]) objectes. Els moviments i les escales per +defecte són per 2 pt; amb Maj., moveu o escaleu 10 vegades més. Ctrl+> +i Ctrl+< amplien al 200% o redueixen al 50% de l'original, +respectivament. Per defecte, els girs són de 15º, i amb Ctrl, +de 90. + + + +Però potser les més útils són les transformacions a nivell de píxel, +invocades prement Alt amb les tecles de transformació. +Per exemple, Alt+fletxes mourà la selecció 1 píxel +al nivell d'ampliació actual (per exemple 1 píxel de pantalla, +no ho confongueu amb les unitats de px, una unitat +SVG independent de l'ampliació). Això significa que si amplieu, amb +Alt+fletxa produïreu un moviment absolut +menor que seguirà veient-se a la pantalla com una empenteta +d'un píxel. És per tant possible posicionar objectes amb precissió +arbitrària només ampliant o reduint segons les vostres necessitats. + + + + +De forma similar, Alt+> i Alt+< +escalen la selecció de tal manera que la seva mida visible varia un píxel, i +Alt+[ i Alt+]la giren de tal manera +que el seu punt més allunyat del centre es mou un píxel. + + + + + +Seleccions múltiples +Podeu seleccionar simultàniament qualsevol nombre d'objectes amb +Maj+clic. O podeu seleccionar arrossegant al voltant dels +objectes que voleu seleccionar; això es diu la selecció de la cinta de +goma. (El selector crea una cinta de goma en arrossegar des d'un +espai buit; però si premeu Maj abans de començar a arrossegar, l'Inkscape +crearà sempre la cinta de goma.) Practiqueu seleccionant les tres +formes següents: + + + + + +Ara useu la cinta de goma (amb arrossegar o Maj+arrossegar) per +a seleccionar les dues el·lipsis, però no el rectangle: + + + + + +Cada objecte individual dins d'una selecció mostra una petita marca — +per defecte, un diamant rectangular. Aquestes marques fan que sigui fàcil veure +què hi ha seleccionat i què no. Per exemple, +si seleccioneu les dues el·lipsis i el rectangle, sense les marques de +diamant us seria difícil endevinar si les el·lipsis estan seleccionades o +no. + +Fent Maj+clic sobre un objecte seleccionat se l'exclou de la selecció. +Seleccioneu els tres objectes anteriors i després useu Maj+clic per a +excloure les dues el·lipsis de la selecció i deixar només el rectangle. + +Prement Esc es desfà la selecció de tots els objectes. +Ctrl+A selecciona +tots els objectes del document (això pot ser lent en documents grans +com aquest). + + + + + +Agrupació + +Poden combinar-se varis objectes en un grup. Un grup es comporta com +un únic objecte quan l'arrossegueu o el transformeu. A sota, els tres +objectes de l'esquerra són independents; els mateixos tres objectes a la +dreta estan agrupats. Proveu d'arrossegar el grup. + + + + + + + + + +Per a agrupar, seleccioneu un o més objectes i feu +Ctrl+G. Per a desagrupar un o més grups, seleccioneu-los i premeu +Ctrl+U. Els propis grups poden agrupar-se, com qualsevol altre objecte; aquests +grups recursius poden descendir fins un nivell d'agrupació arbitrari. +Però Ctrl+U només desfà el nivell superior d'agrupació en una +selecció. Si voleu desfer completament una agrupació de grups en grups +de molts nivells, haureu de fer Ctrl+U repetidament. + + + +Si voleu editar un objecte de dins d'un grup, no cal que desfeu el grup. +Només cal que feu Ctrl+clic sobre aquest objecte per seleccionar-lo i el +podreu editar individualment, o feu Maj+Ctrl+clic sobre objectes +(dins o fora de qualsevol grup) per a una selecció múltiple sense tenir en +compte els grups. Proveu de moure o transformar les formes individuals +del grup (a dalt a la dreta) sense desfer el grup, despres desfeu la +selecció i seleccioneu el grup normalment per veure que encara queda +agrupat. + + + + + +Emplenat i contorn + +Moltes de les funcions de l'Inkscape són accessibles a través de diàlegs. +Probablement, la manera més simple de pintar un objecte amb un color és obrir +el diàleg Swatches des del menú Objectes, seleccionar un objecte, i clicar-ne un +per pintar-hi (es canvia el color de l'emplenat). + +El diàleg Emplenat i contorn (Maj+Ctrl+F) resulta més útil. +Seleccioneu la forma d'abaix i obriu el diàleg Emplenat i +contorn. + + + + + +Veureu que el diàleg té tres pestanyes: Emplenat, Pinta el contorn, i Estil +del contorn. La pestanya Emplenat permet editar l'emplenat (interior) de +les formes. Usant els botons de sota la pestanya, podeu seleccionar +sense emplenat (el botó amb la X), color, degradat lineal o radial. La +forma anterior té acitvada el botó corresponent al color llis. + +Més avall veureu els selectors de color, cadascun a la seva pròpia pestanya: +RGB, HSV, CMYK, i rodona. Potser el més adequat és el selector de la +rodona, on podeu girar el triangle per escollir un to a la rodona, i +després seleccionar el color d'aquest to dins del triangle. Tots els +selectors de color tenen un control per ajustar +l'alfa (opacitat) +dels objectes. + +Quan seleccioneu un objecte, el selector de color s'actualitza amb el seu +emplenat i contorn (quan se selecciona més d'un objecte, es mostra el seu +color mitjà). Jugueu amb aquestes mostres o creeu la vostra pròpia: + + + + + +Usant la pestanya Pinta el contorn, podeu eliminar el contorn +(línia) de l'objecte, o assignar-li qualsevol color o transparència: + + + + + +L'última pestanya, Estil del contorn, us permet definir el gruix i altres +paràmetres del contorn: + + + + +Finalment, en comptes de simples colors, podeu crear degradats de color +tant per als emplenats com per als contorns: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Quan canvieu d'un color simple a un degradat, el nou degradat usa l'anterior +color simple, des de l'opac al transparent. Canvieu a l'eina de degradat +(Ctrl+F1) per a arrossegar els manejadors de degradat — +els controls apareixen connectats per línies que defineixen la direcció i la longitud del degradat. +Quan algun dels manejadors de degradats se selecciona (ressaltat en blau), el +diàleg d'Emplenat i contorn estableix el color del manejador en comptes del color +de tot l'objecte seleccionat. + + + +Hi ha una altra manera de canviar el color d'un objecte: fent servir l'eina +comptagotes (F7). Cliqueu en qualsevol lloc +del dibuix amb aquesta eina, i el color seleccionat s'assignarà a l'emplenat +de l'objecte seleccionat. (Maj+clic assignarà el color del contorn). + + + +Duplicació, alineació, distribució + + + +Una de les operacions més comunes és duplicar un objecte +(Ctrl+D). El duplicat se sitúa exactament al damunt de l'original i està seleccionat, +de manera que el podeu arrossegar amb el ratolí o les tecles de la fletxa. +Per practicar, intenteu omplir la línia amb còpies d'aquest quadrat negre: + + + + + + +És probable que les còpies del quadrat no estiguin convenientment +alineades. Aquí és on entra en joc el diàleg Alinea (Ctrl+Maj+A). Seleccioneu tots els +quadrats (Maj+clic o arrossegant una cinta de goma), +obriu el diàleg i premeu el botó "Centra en l'eix horitzontal", després +el botó "Separeu equidistantment els objectes" +(llegiu els consells dels botons). Ara els objectes estan distribuïts de manera +que els intervals horitzontals entre ells són iguals. Altres exemples d'alineació i distribució: + + + + + + + + + + + + + + + + + + + + + + + + + + + +Ordenació en Z + + + +El terme ordenació en z es refereix a l'ordre d'apilament dels objectes en +un dibuix, és a dir quins objectes són a dalt i tapen d'altres. Les dues +ordres al menú Objecte, Alça a dalt (Inici) i Baixa a baix +Fi), mouran els vostres objectes seleccionats a dalt de tot o a sota de tot +de l'ordenació en z del vostre document. Dues ordres més, Alça (AvPg) +i Baixa (RePg), enfonsaran o aixecaran només un pas, +és a dir, moure després d'un objecte no seleccionat en l'ordenció en z (només +compten els objectes amb superposició; si no hi ha res superposat a la +selecció, Alça i Baixa ho mouen tot a dalt de tot o a baix de tot segons +correspongui). + + + +Practiqueu usant aquestes ordres invertint l'ordre en z dels objectes +següents, de forma que l'el·lipse de més a l'esquerra quedi a dalt de tot +i la de més a la dreta a sota de tot: + + + + +Una drecera per a seleccionar molt útil és la tecla Tab. +Si no se selecciona res, se selecciona l'objecte inferior; en cas contrari se +selecciona l'objecte per sobre de l'objecte seleccionat +en l'ordre z. Maj+Tab ho fa a l'inrevés, +començant des del superior i baixant fins a l'inferior. Ja que els objectes creats +s'afegeixen al damunt de la pila, Maj+Tab sense res seleccionat +us permet seleccionar convenientment el darrer objecte creat. +Practiqueu amb Tab i Maj+Tab a la pila d'el·lipses +d'adalt. + + + +Selecció per sota i arrossegar la selecció + + + +Què fer si l'objecte que necessiteu està amagat darrera un altre objecte? +Encara podeu veure l'objecte de sota si el de sobre és parcialment +transparent, però en clicar al damunt seleccionareu l'objecte de sobre, +no pas el que necessiteu. + + +Per a això serveix Alt+clic. Primer Alt+clic +selecciona l'objecte que hi ha més amunt, com faria un clic normal; en canvi el +següent Alt+clic en el mateix punt seleccionarà l'objecte +que hi ha a sota del superior; després el següent, etc. Per tant, +Alt+clic passarà d'adalt a baix per tots els objectes a la pila +sota el punt on es va fer clic. Quan s'arriba a l'últim objecte, el següent +Alt+clic tornarà a seleccionar l'objecte superior. + + + +Bé, però un cop seleccionat l'objecte sota la superfície, què podem fer-li? +Podem usar tecles per transformar-lo, i podem arrossegar els manejadors de +selecció. Però arrossegar el propi objecte tornarà a reiniciar la selecció +a l'objecte de dalt de tot. Així és com ha de funcionar clica-i-arrossega — +primer selecciona l'objecte (de dalt de tot) sota el cursor, seguidament +arrossega la selecció. Per a dir-li a l'Inkscape que arrossegui el que hi ha +seleccionat sense seleccionar res més, useu Alt+arrossega. +Això mourà la selecció actual independentment d'on arrossegueu el ratolí. + + + +Practiqueu Alt+clic i Alt+arrossega sobre +les dues formes marrons sota el rectangle verd transparent: + + + + + + + +Conclusió + + + +Hem acabat el tutorial bàsic. Hi ha encara molt més sobre l'Inkscape, +però amb les tècniques descrites aquí podreu crear gràfics simples +i útils. Per a aspectes més complicats, aneu al tutorial avançat a +Ajuda > Tutorials. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/share/tutorials/tutorial-basic.de.svg b/share/tutorials/tutorial-basic.de.svg new file mode 100644 index 000000000..bce8dbd9c --- /dev/null +++ b/share/tutorials/tutorial-basic.de.svg @@ -0,0 +1,535 @@ + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ::GRUNDLAGEN + + + + + + + + +Diese Einführung beschreibt die Grundlagen von Inkscape. Dies ist +ein gewöhnliches Inkscape Dokument, das man anschauen, verändern, Teile herauskopieren, oder speichern kann. + + +Diese Grundlagen Einführung behandelt Seiten Navigation, Dokumenten Erstellung und Benutzung, Form-Werkzeug Grundlagen +, Objektauswahl Techniken, Objektmanipulation mit Auswahlrahmen, Gruppierung, Füllfarbe und Umrandungsänderung, Ausrichtung und Z-Ordnung. + Um anspruchsvollere Themen zu üben, benutzen Sie bitte die anderen Einführungen im Hilfe-Menü. + + + + + +Seiten Navigation + +Es gibt viele Möglichkeiten den Arbeitsbereich zu verschieben. Man benutzt +Strg+Pfeiltasten zum Verschieben mit der Tastatur. (Probieren Sie es gerade mal aus, um dieses +Dokument herunter zu bewegen). Man kann den Arbeitsbereich auch mit der mittleren Maustaste +bewegen, oder die seitlichen Verschiebeleisten verwenden, welche man mit Strg+B erscheinen lassen oder +verstecken kann. Das Rad der Maus funktioniert auch um den Arbeitsbereich Vertikal zu bewegen. +Durch gleichzeitiges drücken der Shift Taste auch Horizontal. + + + +Herein- und Herauszoomen +Der einfachste Weg zu zoomen, ist durch die Tasten - und + . Oder auch Strg+mittel Klick oder +Strg+rechts Klick zum Hereinzoomen, Shift+mittel Klick oder +Shift+rechts Klick zum Herauszoomen, oder man dreht am Mausrad mit gedrückter +Strg Taste. Ausserdem kann man den Zoomwert in % direkt in das Zoomeingabefeld (in der unteren, linken Ecke +des Dokumenten Fensters) eingeben und mit Enter bestätigen. +Mit dem Zoom-Werkzeug links in der Werkzeugleiste hat man mehr Möglichkeiten die Vergrößerung einzustellen. + +Inkscape behält die gewählten Zoomstufen gespeichert. Durch drücken der ` Taste, springt man direkt zur vorherigen Zoomstufe , oder durch + Shift+` zur nächsten . + + + + +Inkscape Werkzeuge + +Die Senkrechte Werkzeugleiste auf der linken Seite zeigt Inkscape's Zeichen- und Manipulationswerkzeuge. Im +oberen Bereich des Fensters, unter der Fensterleiste liegt die Befehlsleiste + mit Standard-Menüs und die Werkzeug-Eingabeleiste + für Werkzeug abhängige Eingaben. Die Statusleiste + am Boden des Fensters zeigt, wärend man arbeitet, nützliche Hinweise und Informationen an. + +Viele Funktionen sind durch Tastaturkurzbefehle erreichbar. Öffnen Sie +Hilfe > Tastatur und Maus, um alle Befehle zu sehen. + + + +Erstellen und Benutzen von Dokumenten + +Um eine Leere Seite zu erzeugen, benutzt man Datei > Neu oder drückt +Strg+N. Um ein bestehendes SVG Dokument zu öffnen benutzt man Datei > +Öffnen (Strg+O). Zum Speichern wählt man Datei > Speichern +(Strg+S), oder Speichern Als (Shift+Strg+S) +um das Dokument unter neuem Namen zu speichern. (Inkscape kann gelegentlich noch abstürzen, also besser öfters speichern!) + +Inkscape benutzt das SVG (Scalable Vector Graphics) Format für seine Dateien. SVG ist ein offener Standard, breit +unterstützt von Zeichenprogrammen. SVG Dateien basieren auf dem XML Standard und können +von jedem Text- oder XML Editor (zusätzlich zu Inkscape natürlich) verändert werden. Neben SVG +kann Inkscape auch einige andere Formate importieren und exportieren (EPS, PNG). + +Inkscape öffnet ein separates Programm für jedes einzelne Dokument. Man kann mit dem Fenster-Manager +jedes einzelne anwählen (z.B. durch Alt+Tab), oder durch einen Inkscape eingenen Kurzbefehl + Strg+Tab, welcher durch alle offenen Dokument-Fenster wandert. (Erstellen Sie jetzt ein neues Dokument und schalten Sie zwischen dem und diesem zur Übung hin und her.) + + + +Formen erstellen +Nun ist es Zeit, um ein paar Formen zu erstellen. Klicken Sie bitte auf das Rechteck-Werkzeug in der Werkzeugleiste links +oder drücken F4) und Klick-und-zieh, entweder in eine leere Seite oder direkt hier: + + + +Wie Sie sehen können, Standard-Rechtecke sind Blau mit einer schwarzen Umrandung +und leicht durchscheinend. Wir werden noch sehen, wie man das ändert. Mit den anderen Werkzeugen kann man auch +Ellipsen, Sterne und Spiralen erstellen. + + + +Diese Werkzeuge sind gemeinhin bekannt als Form-Werkzeuge. Jede hergestellte Form + zeigt einen, oder mehrere Rautenförmige Anfasser. Versuchen Sie sie zu ziehen, + um zu sehen wie die Form reagiert. Das Form-Werkzeug Menü ist eine andere Möglichkeit die Form eines +Objektes anzupassen. Dieses Menü beeinflusst die gerade markierten Objekte +(Die, welche die Anfasser anzeigen) und setzt den Standard +für alle neuen Objekte. + +Zum Rückgängig machen der letzten Aktion, drückt man +Strg+Z. (Oder, wenn Sie es sich wieder anders überlegen, benutzen Sie +Wiederherstellen durch Shift+Strg+Z.) + + + + +Bewegen, Drehen, Grösse ändern Das meistbenutzte Werkzeug in Inkscape ist +der Markieren-Pfeil. Klicken Sie den obersten Knopf (mit dem Pfeil) in der +Werkzeugleiste, oder drücken Sie F1 oder Leertaste. Nun können Sie jedes +Objekt auf der Seite anwählen. Klicken Sie auf das Rechteck unten. + + + +Sie sehen jetzt acht pfeilförmige Anfasser um das markierte Objekt. +Jetzt können Sie: + + +Bewegen des Objekts durch Klicken-und-ziehen. (Drücken Sie Strg zum Beschränken der Bewegung +auf Horizontal und Vertikal.) + + +Grösse ändern des Objektes durch Klicken-und-ziehen eines Anfassers. (Drücken Sie Strg zum +bewahren des Höhen/Seiten verhältnisses.) + + + +Nun drücken Sie das Rechteck nocheinmal. Die Anfasser ändern sich. Jetzt können Sie: + + + +Drehen des Objektes durch Klicken-und-ziehen der Eck-Anfasser. (Drücken Sie Strg zum +Stufenweisen drehen in Schritten von 15 Grad. Ziehen Sie das Kreuz, um die Mitte der Drehung +festzulegen.) + + +Schären des Objektes durch Klicken-und-ziehen der anderen Anfasser. (Drücken Sie Strg zum Stufenweisen schären in +Schritten von 15 Grad.) + + +Während das Objekt noch markiert ist, kann man auch die Eingabefelder (über der Seite) benutzen, um +genaue Werte für die Koordinaten (X und Y) und Grösse (W und H) +einzugeben. + + + +Verändern durch die Tastatur + +Eine der Eigenschaften von Inkscape, die es von vielen anderen Vektorzeichenprogrammen unterscheidet, +ist die Betonung auf Tastaturbedienbarkeit. Es gibt fast keinen Befehl oder Aktion, die nicht +mit der Tastatur ausführbar ist, und Objektmanipulation ist da keine Ausnahme. + +Man kann die Tastatur zum Bewegen (Pfeil Tasten), Größenänderung +(< und > Tasten), und Rotieren ([ +und ] Tasten) des Objekts benutzen. Die Standardweite der Bewegung und Größenänderung mit der Tastatur ist 2 px. Mit +Shift das Zehnfache davon. Strg+< +und Strg+> vergrößern auf 200% oder verkleinern auf 50% der Originalgröße. + Standardmäßig rotiert man in 15 Grad Schritten. Mit Gedrückter Strg Taste in 90 Grad Schritten. + +Besonders nützlich sind Pixelgenaue-Manipulationen +. Durch gleichzeitiges Drücken von Alt mit den Manipulationstasten + Alt+Pfeiltaste bewegt man das markierte Objekt auf dem Bildschirm um 1 Pixel +bei gewähltem Zoomfaktor (entspricht 1 Bildschirm Pixel) +. Nicht zu Verwechseln mit der px-Einheit welche eine SVG-Längeneinheit unabhängig vom Zoomfaktor ist. + Das bedeutet, wenn man Hineinzoomt, ein Alt+Pfeil entspricht einer +kleineren (Absolut)Bewegung, obwohl es auf dem Bildschirm so aussieht wie ein "Ein-Pixel-Stups". + Dadurch ist es möglich Objekte mit einer beliebig hohen Präzision zu positionieren. + +Genauso ändern Alt+< und Alt+> +die Objektgröße so, das die Sichtbare Größe um jeweils ein Bildschirmpixel verändert wird. Die Tasten +Alt+[ und Alt+] rotieren den "Am weitest vom Zentrum entfernten Punkt" um einen Bildschirmpixel. + + + +Vielfachauswahl Man kann jede Anzahl von Objekten gleichzeitig +durch Shift+Klickauswählen. Oder durch +ziehen um die benötigten Objekte. Dies wird +Gummibandauswahl genannt. (Der Markierpfeil erzeugt das Gummiband durch ziehen +über einen leeren Teil der Seite. Jedoch auch durch Drücken von Shift vor dem Ziehen.) Üben Sie durch Markieren +aller drei Körper unterhalb: + + + +Jetzt benutzen Sie das Gummiband (durch ziehen oder Shift+ziehen), um beide Ellipsen aber nicht +das Rechteck zu markieren: + + + +Jedes Einzelne Objekt einer Auswahl zeigt einen Markierungsrahmen + — normalerweise einen gestrichelten, Quadratischen Rahmen. Diese Hinweise erleichtern es + auf einen Blick zu sehen, was Ausgewählt ist und was nicht. Zum Beispiel, wenn man beide Ellipsen und das Rechteck auswählt, hätte man +es ohne diese Hinweise schwer zu sagen, ob die Ellipsen markiert sind oder nicht. + +Durch Shift+Klickauf ein markiertes Objekt, schliesst man es von der Auswahl aus. + Wählen Sie alle drei Objekte oben, dann benutzen Sie Shift+Klick ,um beide Ellipsen +von der Auswahl auszuschliessen und das Rechteck alleine markiert zu lassen. + +Mit Esc hebt man jede Markierung auf. +Strg+A Markiert alle Objekte der momentan aktivierten Ebene (Wenn Sie keine weiteren Ebenen erstellt +haben, markieren Sie dadurch alle Objekte der Seite). + + + +Gruppieren + +Verschiedene Objekte können zu einer Gruppe zusammengefasst werden. Eine Gruppe +verhält sich wie ein einzelnes Objekt, wenn man es zieht oder verändert. Die drei Objekte unten links sind unabhängig +; die gleichen drei Objekte auf der rechten Seite sind Gruppiert. Versuchen Sie die Gruppe +zu ziehen. + + + + + + + +Um eine Gruppe zu erzeugen, wählt man ein oder mehrere Objekte und drückt +Strg+G. Um die Gruppierung bei einer oder mehreren Gruppen aufzuheben, markiert man sie und drückt +Strg+U. Gruppierungen selbst können auch Gruppiert werden, wie jedes andere Objekt. + Solch rekursive Gruppierungen können beliebig tief weitergeführt werden. Einmaliges +Strg+U hebt nur die oberste (letzte) Gruppierung einer selektierten Gruppe auf. +Um alle Gruppierungen der Selektion aufzuheben, muss man mehrfach Strg+U drücken. + +Es ist nicht zwingend notwendig alle Gruppierungen aufzuheben, wenn man ein Objekt in einer +Gruppe ändern will. Einfach Strg+Klick drücken, das Objekt ist jetzt markiert und einzeln +veränderbar. Um mehrere Objekte innerhalb oder ausserhalb einer Gruppe zu selektieren drückt man Shift+Strg+Klick. +Versuchen Sie einzelne Objekte in der Gruppe ( oben Rechts ) zu bewegen oder zu verändern, ohne die Gruppierung aufzuheben. + Anschliessend heben Sie die Markierung wieder auf und markieren die Gruppe wieder normal. + Dann sehen Sie, dass die Gruppierung erhalten geblieben ist. + + + +Füllung und Linie + +Viele der Funktionen von Inkscape sind verfügbar durch Dialoge. Wahrscheinlich +der einfachste Weg einem Objekt eine Farbe zuzuweisen, ist den Farb-Dialog im Objekt Menü zu öffnen, das Objekt zu markieren, + und ein Farbfeld zu wählen (Das ändert die Füllfarbe). + +Viel leistungsfähiger ist der Füllung und Linie-Dialog +(Shift+Strg+F). Benutzen Sie das Objekt unten mit dem Füllung und Linie-Dialog. + + + +Man kann sehen, das der Dialog drei Abschnitte (Reiter) hat: Füllen, Linienfarbe, und Linienstil +. Der Füllen-Abschnitt ist zum Ändern der Füllfarbe (Innenfarbe) des +markierten Objekts. Mit den Knöpfen in diesem Abschnitt kann man die Füllungsart verändern. +Beziehungsweise die Füllung ganz ausschalten (Der Knopf mit dem X).Einfarbig füllen, genauso wie Linear- und Radialverlauf +. Bei dem oberen Objekt ist der Knopf "Einfarbig" aktiviert. + +Weiter unten sieht man verschiedene Farbauswahlen. Jedes in +seinem eigenen Abschnitt: RGB, CMYK, HSL, und Farbrad. Das wahrscheinlich praktischte von denen ist das Farbrad, + bei dem man das Dreieck auf dem Rad bewegt, um den Farbton zu wählen und dann auf die gewünschte Helligkeit im Dreieck klicken. + Alle Farbwähler besitzen einen Schieberegler, um den +Alpha-Kanal (Durchsichtigkeit) der Objektfarbe einzustellen. + +Jedes mal wenn ein Objekt markiert wird, wird die aktuelle Farbe und Umrandung vom Füllung und Linie-Werkzeug übernommen. +Bei mehr als einem markierten Objekt wird die Durchschnittsfarbe angezeigt. Üben Sie an diesen Beispielobjekten oder benutzen Sie selbst erstellte Objekte: + + + +Mit dem Linienfarb-Werkzeug kann man die Umrandung +(Aussenlinie) des Objektes entfernen, oder eine beliebige Farbe und Transparenz zuordnen: + + + +Der letzte Abschnitt Linienstil ist zum Einstellen der Breite und anderer Werte + des Randes: + + + +Statt Einfarbig kann man auch den Farbverlauf für +Farbausfüllung und/oder Rand benutzen: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Wenn man von Einfarbig auf Farbverlauf umschaltet, geht der neue Farbverlauf zunächst +von der eingestellte Farbe stufenlos zu komplett Durchsichtig. Im Farbverlaufswerkzeug benutzt man +(Strg+F1) um die Verlaufs-Anfasser zu benutzen. — +Die Verlaufs-Anfasser sind durch Linien verbunden, durch die man die Richtung und die Länge des Verlaufs einstellen kann. + Wenn einer der Verlaufs-Anfasser ausgewählt ist(Blau hervorgehoben), + setzt der Füllung und Linie-Dialog nur die Farbe dieses einen Anfassers, statt des ganzen Objektes. + +Eine andere, praktische Möglichkeit die Farbe eines Objektes zu ändern, ist die Pipette + (F7)zu benutzen. Einfach mit der Pipette auf ein anderes Objekt klicken, + und die Farbe des Objekts wird automatisch als Füllfarbe für das aktuelle Objekt benutzt. Ein +(Shift+Klick auf das Objekt stellt die Randfarbe ein. + + + +Vervielfältigen, Anordnen, Verteilen + +Eines der häufigsten Arbeitsschritte ist es Objekte zu Vervielfältigen. Dies wird durch die Tastenkombination +(Strg+D)erreicht. Die Kopie des Objektes ist dann exakt über dem kopierten Objekt, bereit mit der Maus oder den Pfeiltasten verschoben zu werden. +Zur Übung, versuchen Sie Kopien des schwarzen Vierecks in einer Linie nebeneinander anzuordnen: + + + +Es ist gut möglich, dass die platzierten Vierecke jetzt unterschiedlich weit voneinander Entfernt sind. Das ist ein guter + Moment, um den Ausrichtungs-Dialog (Strg+Shift+A) zu benutzen. Markieren Sie alle Vierecke mit +(Shift+Klick oder Gummiband benutzen), öffnen Sie dann den Dialog und drücken +"Horizontal zentrieren" . Dann den "Horizontale Abstände zwischen Objekten angleichen" Knopf (lesen Sie die eingeblendeten Knopfhilfen). Die Objekte sind jetzt gleichmässig Ausgerichtet und Verteilt. + Hier sind weitere Übungsmöglichkeiten für Sie: + + + + + + + + + + + + + + + + + + + + + + + + + + + +Z-Ordnung + +Die Bezeichnung Z-Ordnung beschreibt die Anordnung von Objekten einer Zeichnung übereinander (Ebenen). Zum Beispiel wenn zwei Objekte sich überschneiden/überdecken Welches ist oben ? +Die zwei Befehle im Objekt-Menü +, oberste Ebene (die Pos 1 Taste) und unterste Ebene (die +Ende Taste), bringt das markierte Objekt auf die oberste Ebene oder auf die unterste +Ebene der Z-Ordnung. Zwei weitere Befehle, heben (Bild hoch) +und senken (Bild runter), hebt oder senkt das markierte Objekt um eine Stufe. +Zum Beispiel:"Bewege das Objekt an einem nichtmarkierten Objekt in der Z-Ordnung vorbei (Dazu zählen nur Objekte, die sich gegenseitig überdecken. + Wenn sich in der Mitte der Z-Ordnung nichts überlagert, bewirkt Bild hoch und Bild runter das gleiche wie die +Tasten Pos1 und Ende). + +Üben Sie diese Befehle durch Umkehren der Z-Ordnung an den Objekten unten. Bringen Sie die linke Ellipse nach oben +und die rechte Ellipse nach unten (in der Z-Ordnung): + + + +Eine sehr nützliche Auswahlhilfe ist die Tab Taste. Wenn nichts ausgewählt ist +benutzt es das unterste Objekt; andernfalls benutzt es das Objekt über dem(den) markierten Objekte(n) in Z-Ordnung. + Shift+Tab arbeitet genau anders herum. Es beginnt bei dem obersten Objekt und geht hinunter. + Da es so ist das die neu hinzugekommenen Objekte oben auf dem Stapel landen, wird das Letzte +Objekt,wenn vorher nichts markiert ist praktischerweise durch Drücken von Shift+Tab markiert. +Üben Sie Tab und Shift+Tab Tasten an dem Stapel Ellipsen oben. + + + +Verdeckte Objekte markieren und ziehen + +Was kann man tun, wenn ein benötigtes Objekt von einem anderen verdeckt wird ? +Es kann sein, das man das unterste Objekt sieht, weil das oberste Objekt (teilweise) durchsichtig ist. + Doch bei dem Versuch es auszuwählen, markiert man das oberste Objekt, welches man nicht braucht. + +Das ist die Situation, bei der Alt+Klick nützlich ist. Das erste Alt+Klick +markiert das oberste Objekt, genau wie ein gewöhnlicher Klick. Jedoch, das nächste +Alt+Klick an der gleichen Stelle wählt das Objekt unter dem Obersten. + Dann, das Objekt darunter u.s.w.. Auf diese Weise kommt man durch mehrere +Alt+Klick nacheinander, von ganz Oben nach ganz Unten, durch den gesamten Z-Ordungs Stapel von Objekten. + Wenn das unterste Objekt erreicht ist, wird durch das nächste +Alt+Klick natürlich wieder das oberste Objekt markiert. + +Das ist ja schön, aber was kann man mit einem markierten und verdeckten Objekt anfangen ? + Man kann es durch Tastaturbefehle verändern und man kann die Anfasser benutzen. + Aber, bei dem Versuch das Objekt selbst, zu ziehen wird automatisch wieder das oberste Objekt markiert + (Das ist zum Beispiel wie "Klicken-und-ziehen" funktioniert — es markiert das (oberste) +Objekt unter dem Cursor, dann zieht es das gewählte Objekt). Um Inkscape mitzuteilen das gerade gewählte + zu ziehen, ohne etwas anderes zu markieren, benutzt man Alt+ziehen. +Das bewegt das aktuell markierte Objekt, wohin man auch will. + +Benutzen Sie Alt+Klick und Alt+ziehen an den zwei braunen Objekten +unter dem transparent-grünem Rechteck: + + + + + + + +Schlusswort + +Dies ist das Ende der Grundlagen-Einführung. Das war lange noch nicht alles in Inkscape, aber +mit den hier vermittelten Techniken, sind Sie auf jeden Fall gut gerüstet um einfache und nützliche Grafiken + zu erstellen. Um kompliziertere Techniken zu lernen, üben Sie die Fortgeschrittenen-Einführung und weitere in +Hilfe > Einführungen. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/share/tutorials/tutorial-basic.es.svg b/share/tutorials/tutorial-basic.es.svg new file mode 100644 index 000000000..a852b08b0 --- /dev/null +++ b/share/tutorials/tutorial-basic.es.svg @@ -0,0 +1,479 @@ + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ::BÁSICO + + + + + + + + + +Este tutorial demostrará los usos básicos de Inkscape. Este es un documento +regular de Inkscape que usted puede ver, editar, copiar, descargar o guardar. + + +El tutorial Básico cubre la navegación en canvas (pizarra), manejo de documentos, herramientas de formas básicas, técnicas de selección, transformación de objetos por medio del selector, agrupado, configuración de relleno y borde, alineación y orden-z. Para +visualizar otros temas más avanzados, ingrese al menú Ayuda. + + + + + +Configurando la pizarra + +Existen varias maneras para configurar la pizarra. Primero intentemos: +Ctrl+Flecha Teclas para desplazarse por la pizarra. (Puede intentar esto en este mismo documento) También es posible por medio del arrastre a través del botón intermedio de ratón. O también por medio de las barras de desplazamiento (presione Ctrl+B para visualizarlas o/u ocultarlas). La rueda del ratón también funciona para el desplazamiento de manera vertical; presione Mayus con la rueda para realizar desplazamientos horizontales. + + + +Acercar y alejar (Zoom) +La manera más sencilla de para activar el zoom es por medio de las teclas - y + (o +=). También puede emplear Ctrl+Click del botón central o +Ctrl+Click del botón derecha para acercamiento, Mayus+Click del botón central o +Mayus+Click del botón derecho para alejar, o rote la rueda del ratón junto con +Ctrl. O puede seleccionar en la parte inferior izquierda el campo de zoom que le permite ingresar el valor del porcentaje % para la visualización, luego presione Enter. Disponemos además de los anteriores métodos, la herramienta Zoom (Ubicada en la barra de Herramientas a la izquierda) la cual permite hacer un zoom alrededor de un aea por medio de un click sostenido alrededor de ella. + +Inkscape también conserva un historial de los niveles de zoom que ha usado en el trabajo, en la última sesión. Presione la tecla ` para ir al zoom previo o +Mayus+` para ir al siguiente. + + + + +Herramientas del Inkscape + +La barra vertical de herramientas sobre la izquierda muestra las herramientas de dibujo y edición de Inkscape. En la parte superior de la ventana, debajo del menú;, está la Barra de comandos con los botones de control general y la barra de contro, de herramientas con los controles que son especiales para cada herramienta. La barra de estado en la parte superior de la ventana mostrará consejos útiles y mensajes de como trabaja usted. + +Algunas operaciones están disponibles a través de atajos de teclado. Abra Ayuda > Teclas y ratón para observar la referencia completa. + + + +Creando y Administrando documentos + +Para crear un nuevo documento vacio, use File > New o presione +Ctrl+N. Para abrir un documento SVG existente, File > +Open (Ctrl+O). Para guardar, use File > Save +(Ctrl+S), o Save As (Mayus+Ctrl+S) +para guardar bajo un nuevo nombre. (Inkscape puede aún ser inestable, así que recuerde guardar a menudo!) + +Inkscape usa el formato SVG (Scalable Vector Graphics/Gráficos de Vectores Escalables) para estos archivos. SVG es un estandar abierto extensamente soportado por software gráficos. Los archivos SVG están basados en XML y pueden ser editados +con cualquier editor de XML (aparte de Inkscape, por supuesto). Además de SVG, +Inkscape puede importar y exportar muchos otros formatos (EPS, PNG) + +Inkscape abre una ventana aparte para cada documento. Usted puede navegar a través de ellas usando su manejador de ventanas (ejemplo por medio de Alt+Tab), o puede usar los atajos de Inkscape Ctrl+Tab, el cual haráa un ciclo a través de las ventanas de documentos. (Ahora cree un nuevo documento y cambie entre estos documentos para practicar.) + + + +Creando Formas +Es hora para algunas formas fantásticas! Haga Click sobre la herramienta Rectángulo (o presione F4) y haga click y arrastre, o en un nuevo documento o aquí: + + + +Como puede observar, los rectángulos por defecto se muestran azules, con un relleno azul y (delineado), +en parte transparente. Podemos observar como editarlos más adelante. Con otras herramientas, también podemos crear elipses, +estrellas y espirales: + + + +Estas herramientas son colectivamente conocidas como herramientas de formas. Cada forma que cree +muestran uno o más manejadores en forma de diamante; intente arrastrándolos +para observar como responden las formas. El panel de control para una herramienta de forma +es otra manera para transformar una forma; estos controles afectan a las formas actualmente seleecionadas +(i.e. aquellas que muestren los manejadores) y configure el por defecto que +aplicará a las formas recien creadas. + +Para deshacer su última acción, presione +Ctrl+Z. (O, si cambia de parecer, puede +rehacer la acción deshecha mediante Mayus+Ctrl+Z.) + + + + +Moviendo, Escalando, Rotando La herramienta más utilizada en Inkscape es +el Selector. Click en el botón más superior (con la forma de cursor) sobre la +barra de herramientas, o presione F1 o Barra Espaceadora. Ahora puede seleccionar +cualquier objeto en la pizarra. Click sobre el rectángulo de más abajo. + + + +Usted podrá observar que ocho manejadores en forma de flecha aparecen alrededor del objeto. +Ahora puede: + + +Mover los objetos al arrastralos. (Presione Ctrl para restringir movimientos a +horizontal y vertical.) + + +Escalar los objetos mediante el arrastrado de cualquier manejador. (Presione Ctrl para preservar el radio de alto/ancho original.) + + + +Ahora click en el rectángulo de nuevo. Los manejadores cambian. Ahora puede: + + + +Rotar los objetos mediante el arrastrado de los manejadores de las esquinas. (Presione Ctrl para restringir la rotación a pasos de 15 grados. Arrastre la marca en forma de cruz para la posición del eje de rotación.) + + +Inclinar (esquilar) los objetos mediante el arrastre de los manejadores no-esquinas. (Presione Ctrl para restringir inclinaciones a pasos de 15 grados.) + + +Mientras use el Selector, también podrá usar los campos de entradas numéricos en la barra de control (Sobre la pizarra) para configurar valores exactos para cordenadas (X y Y) y tamaño (W y H) de la selección. + + + +Transformación por medio del teclado + +Una de las características de Inkscape que lo diferencian de otros muchos editores vectoriales es su énfasis en la accesibilidad por teclado. Existe dificilmente algún comando o acción que +sea imposible realizar por teclado y la transformación no es la excepción. + +Usted puede usar el teclado para mover (teclas de flecha), escalar +(teclas < y >), y rotar (teclas [ +y ]) objetos. Las distancias por defecto de mover y escalar es de 2 px; con +Mayus, puede mover o escalar por 10 veces. Ctrl+> +y Ctrl+< escalan más y menos al 200% o 50% del original, +respectivamente. Por defecto la rotación es de 15 grados; con Ctrl, rota +por 90 grados. + +Más sin embargo considere como el más útil latransformaciones tamaño-pixel, invocada mediante el uso de Alt con la tecla de tranformación. Por ejemplo, Alt+flechas moverá la selección 1 pixel +en el zoom actual (i.e. por 1 pixel de pantalla, +no se confunda con la unidad px la cual es una uidad de medida SVG independiente del +zoom). Esto significa que si usted amplia, un Alt+flecha resultará un +movimiento absolutamente pequeño el cual aún se observa como si +empujase un pixel sobre su pantalla. Así esto es posible para posicionar objetos con presición +arbitaria simplemente mediante un acercamiento o alejamiento como lo requiera. + +Igualmente, Alt+> y Alt+< +escalan selecciones haciendola visibles en un tamaño de un pixel de pantalla, y +Alt+[ y Alt+] lo rotan de la manera más alejada del punto central +movido mediante un pixel de pantalla. + + + +Selecciones Multiples Puede seleccionar cualquier número de objetos +simultáneamente mediante Mayus+clicksobre los objetos deseados a selaccionar. O, puede +arrastrar alrededor de los objetos que requiere seleccionar; esto es llamado +Selección elástica. (El selector crea selcciones elásticas cuando se arrastra a desde un espacio vacio; sin embargo, si presiona Mayus antes de iniciar el arrastrado, Inkscape siempre creará la selección elástica.) Practique mediante la sección de todas las tres formas a continuación: + + + +Ahora, utilice selecciones elásticas (mediante arrastrado o Mayus+arrastrar) para seleccionar las dos elipses pero no el rectángulo: + + + +Cada objeto individual dentro de una selección muestra una señal de selección + — por defecto, un marco rectángular. Estos marcos hacen más sencillo el observar +que está selccionado y que no loo está. Por ejemplo, si selecciona ambas elipses +y el rectágulo, sin los marcos le sería muy difícil adivinar cual de las elipses +están seleccionadas y cuales no. + +Mayus+click sobre un objeto selccionado lo excluye de la selección. Seleccione los tres objetos de a continuación, después emplee Mayus+click para excluir ambas elipses de la selección, dejando solo +seleccionado el rectángulo. + +Presionando Esc deseleciona cualquier objeto selccionado. +Ctrl+A selecciona todos los objetos en la capa actual (si no ha creado capas, esto es lo mismo que todos los objetos en el documento). + + + +Agrupando + +Muchos objetos pueden ser combinados en un grupo. Un grupo +se comporta como un objeto sencillo cuando usted lo arrastra o lo transforma. adelante, los tres objetos +sobre la izquierda son independientes; los mismo tres objetos sobre la derecha son están agrupadas. Intente arrastrar +el grupo. + + + + + + + +Para crear un grupo, seleccione uno o más objetos y presiones +Ctrl+G. Para desagrupar uno o más grupos, seleccionélos y presione +Ctrl+U. Los mismo grupos pueden ser agrupados, así como cualquier otro objeto; +dichos grupos recursivos pueden ir atras en una profundidad arbitraria. Sin embargo, +Ctrl+U solo desagrupa el nivel superior de agrupación en una selección; necesitará presionar Ctrl+U repetidamente si quiere desagrupar completamente un grupo profundo dentro de un grupo. + +No tiene necesariamente que desagrupar, sin embargo, si desea editar +un objeto dentro de un grupo. Solo Ctrl+click sobre el objeto y este +será seleccionado y editable solo, o Mayus+Ctrl+click sobre varios objetos +(dentro o afuera de cualquier grupo) por múltiples selecciones sea cual sea la agrupación. +Intente mover o transformar las formas individuales en el grupo +(adelante a la derecha) sin desagrupar, entonces deseleccione y seleccione +el grupo normalmente para observar que continua aún agrupado. + + + +Relleno y borde + +Algunas funciones de Inkscape están disponibles vía dialogos. Probablemente la +forma más sencilla de pintar un objeto de algún color es abrir el dialogo -- desde el +menú de Objetos, selccione un objeto y click en un -- para pintarlo (cambia su color de relleno). + +Es más poderoso el dialogo de Relleno y Borde (Mayus+Ctrl+F). +Seleccione la forma de adelante y abra el dialogo de Relleno y Borde. + + + +Podrá observar que el dialogo posee tres pestañas: Relleno, Color de trazo y Estilo de +trazo. La pestaña Relleno le permite editar el relleno (interior) del objeto(s) seleccionado(s). +Usando el botón más abajo de la pestañ puede seleccionar los tipos de relleno, +incluyendo sin relleno (el botón con la X), color uniforme, así como gradientes lineales o radiales. +Para las siguientes formas, el botón de relleno uniforme será activado. + +Más abajo, puede observar una colección de selectores de color, cada +uno esta se encuentra en su propia pestaña: RGB, CMYK, HSL y Rueda. Considere el Selector de Rueda , donde +puede rotar el triángulo para escoger un matiz en la rueda, y después seleccione +una sombra que es el matiz del triángulo. Todos los selectores de color contienen un desplazador +para configurar el alfa (opacidad) de el/los objeto(s) seleccionado(s). + +Cuando selecciona un objeto, el selector de color es actualizado para mostrar su relleno y borde actual (para selecciones de múltiples objetos, el dialogo muestra su color promedio). Trabaje con estos ejemplos o cree sus propios: + + + +Usando la pestaña color de borde, remueva el borde +(reborde) del objeto, o asignele cualquier color o transparencia: + + + +La última pestaña Estilo de borde, le permite configurar el grosor y otros parámetros +del borde: + + + +Finalmente, en vez de un color uniforme, puede usar gradientes para +rellenos y/o bordes: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Cuando cambia de color uniforme a gradiente, el nuevo gradiente creado usa el color uniforme previo, presentandolo de opaco a transparente. CAmbie a la herramienta Gradiente +(Ctrl+F1) para arrastrar el manejador gradiente — +los controles conectads por líneas que defiene la dirección y longitud del gradiente. Cuando alguno de los manejadores de gradiente es seleccionado (Azul claro), el dialogo de relleno y el borde configura el color del manejador en vez de todo el color del objeto seleccionado. + +Otas manera conveniente para cambiar el color de un objeto es usando la herramienta Balde??? +(F7). Solo haga click dentro del dibujo con la herramienta y el color seleccionado será asignado al relleno del objeto seleccionado (Mayus+click asignará el color de borde). + + + +Duplicado, Alineación, Distribución + +Una de las operaciones más comunes es el duplicar un objeto +(Ctrl+D). El duplicado es colocadi exactamente debajo del original y es seleccionado, así, así se le posibilita el arrastrar mediante el ratón o las teclas de flechas. Para practicar, intente llenar la línea con copias de estos +cuadrados negros: + + + +Las opciones son, sus copias del cuadrado son colocados más o menos aleatoriamente. Este dialogo de Alineación (Ctrl+Mayus+A) es útil. Seleccione todos los cuadrados +(Mayus+click o arrastre una selección elástica), abra el dialogo y presione el botón "Centro en las equis horizontales", entonces el botán "Hacer espacios horizontales entre objetos iguales"(lea los mensajes de las herramientas). Ahora los objetos son alineados ordenada y distribuida equis-espacialmente. Estos son otros ejemplos de alineación y distribución: + + + + + + + + + + + + + + + + + + + + + + + + + + + +orden-Z + +El término orden-z se refiere al orden de apilado de los objetosen un gráfico, i.e dichos objetos están en la parte superior y son más oscuros que el resto. Los dos comandos en el menú Objetos, Llevar al Frente, +(la tecla Inicio) y Llevar al Fondo (la tecla Fin), moverá sus objetos seleccionados al nivel superior o al fondo de la capa del orden-z actual. Otros dos comandos, Arriba (PgUp) y Abajo (PgDn), podrán hundir o emerger la selección un sólo paso, +i.e. mueve el último objeto no seleccionado en el orden-z (sólo cuente objetos seleccionados; si nada superpone la selección, muévalo Arriba o Abajo hacia la parte superior o el fondo correspondiente). + +Practique usando estos comandos mediante el revertimiento del orden-z de los objetos de adelante, de esta manera que la elipse más a la izquierda está en el nivel superior y la elipse de más a la derecha está en el fondo: + + + +Una atajo de selección muy útil es la tecla Tab. +Si no hay nada seleccionado, este selecciona el objeto de más al fondo; de otra forma este selecciona el objeto debajo del objeto(s) seleccionado(s) en orden-z. Mayus+Tab trabaja a la inversa, iniciando desde el objeto en el nivel más superior y procede con los siguientes. LLos objetos que crea son agregados +al nivel superior de la pila, presionando Mayus+Tab con nada +seleccionado convenientemente seleccionará los últimos objetos que usted ha creado. +Practica con las teclas Tab y Mayus+Tab en la pila de elipse de abajo. + + +Seleccionando debajo y arrastrando seleccionados + +¿Qué hacer si el objeto que requiere está oculto tras otro objeto? +Usted podrí aún observar el objeto del fondo si el del nivel superior está +(parciamente) transparente, pero dando click en el selecionará el objeto superior, no el que usted requiere. + +Esto es para lo que Alt+click está hecho. Primero Alt+click selecciona el objeto superior como un sencillo click. sin embargo, el siguiente Alt+click en el mismo punto seleccionará el objeto de abajo del superior; el siguiente, el objeto bajo siguiente, etc. +Muchos Alt+clicks en una línea hará un ciclo, superior-al-fondo, a través de la pila de objetos en orden-z en el punto del click. Cuando el objeto del fondo es alcanzado, el siguiente Alt+click naturalmente, seleccionará el objeto más superior. + +Esto es bueno, pero una vez qe usted selecciona un objeto bajo-la-superficie, ¿Qué puede hacer usted con el?. Puede usar teclas para transformarlo y puede arrastrar los manejadores selección. Sin embargo, arrastrando sobre el objeto mismo deseleccionará +el objeto superior de nuevo (esto es como el click-y-arrastrado está diseñado para trabajar — este selecciona el objeto (superior) bajo el primer cursor, entonces arrastre la aselección). Para indicarle a Inkscape el arrastrar que está seleccionado ahora sin seleccionar nada más, use Alt+arrastrar. Esto moverá la selección sin importar donde arrastra usted el ratón. + +Practique Alt+click y Alt+drag sobre las dos formas cafés debajo del rectángulo verde transparente: + + + + + + + +Conclusión + +Así concluye el tutorial básico. Hay mucho más en el Inkscape, más sin embargo las técnicas descritas aquí ya le permitirán crear gráficos simples muy útiles. Para conceptos y utilidades más complicadas, vaya a través del tutorial Avanzado en Ayuda > Tutoriales. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/share/tutorials/tutorial-basic.fr.svg b/share/tutorials/tutorial-basic.fr.svg new file mode 100644 index 000000000..e80b661a3 --- /dev/null +++ b/share/tutorials/tutorial-basic.fr.svg @@ -0,0 +1,452 @@ + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ::BASIQUE + + + + + + + + +Ce didacticiel présente les opérations de base d'Inkscape. C'est un document réalisé avec Inkscape que vous pouvez afficher, éditer et éventuellement sauver. + + +Le didacticiel basique aborde la navigation sur le canevas, la gestion des documents, les bases des outils de formes, la transformation d'objets à l'aide du sélecteur, les techniques de sélection, le groupement, les remplissages et contours, l'alignement et la superposition. Pour d'autres sujets, consultez les autres didacticiels dans le menu d'aide. + + + + + +Se déplacer sur le canevas + +Il existe plusieurs façons de se déplacer sur le canevas. Vous pouvez essayer le raccourci Ctrl+flèche pour vous déplacer dans ce document (essayez donc dès maintenant de faire défiler ce document vers le bas). Vous pouvez aussi vous déplacer à l'aide du bouton milieu de la souris ou utiliser les barres de défilement (Ctrl+B permet de les afficher ou non). La molette de la souris permet les déplacements verticaux, et même horizontaux en combinaison avec la touche Maj. + + + + + +Zoomer ou dézoomer + +Le moyen le plus simple est d'utiliser les touches - et + (ou =). Vous pouvez aussi zoomer avec Ctrl+clic-milieu ou Ctrl+clic-droit, et dézoomer avec Maj+clic-milieu ou Maj+clic-droit, ou bien utiliser la molette de la souris en tout en appuyant sur Ctrl. Vous pouvez aussi cliquer sur le champ de saisie (dans le coin en bas à gauche de la fenêtre), y entrer une valeur de zoom, et la valider en pressant la touche entrée. Enfin, il reste l'outil de zoom (dans la barre d'outils à gauche) qui vous permet de définir une région sur laquelle zoomer à l'aide de la souris. + + +Inkscape garde aussi en mémoire un historique des niveaux de zoom. Appuyez sur les touches ` pour y naviguer en avant et Maj+` en arrière. + + + + + +Les outils d'Inkscape + +La barre d'outils verticale à gauche affiche les outils de dessin et d'édition d'Inkscape. En haut de la fenêtre, sous les menus, la barre de commandes affiche les boutons des commandes générales tandis que la barre de contrôle des outils montre les contrôles spécifiques à chaque outil.La barre d'état en bas de la fenêtre affiche des indications et des messages utiles lors de votre session. + + +Beaucoup d'autres opérations sont disponibles via les raccourcis clavier. Pour consulter tous les raccourcis disponibles, ouvrez le menu Aide > Clavier et souris. + + + + + +Créer et gérer des documents + +Pour créer un nouveau document vide, utilisez Fichier > Nouveau ou appuyez sur Ctrl+N. Pour ouvrir un fichier SVG existant, utilisez Fichier > Ouvrir (Ctrl+O). Utilisez Fichier > Enregistrer (Ctrl+S) pour sauver ou Enregistrer sous (Maj+Ctrl+S) pour sauver sous un nouveau nom (Inkscape est encore en développement, n'oubliez pas d'enregistrer votre travail fréquemment !). + + +Inkscape utilise le format SVG (Scalable Vector Graphics) pour ses fichiers. Le format SVG est un standard ouvert largement utilisé par les logiciels de graphisme. Les fichiers SVG sont basés sur le format XML et peuvent être édités à l'aide de n'importe quel éditeur de texte ou XML (ou avec Inkscape, bien sûr). Inkscape peut aussi importer ou exporter plusieurs autres autres formats (EPS, PNG). + + +Inkscape ouvre une nouvelle fenêtre pour chaque document. Naviguez entre elles avec votre gestionnaire de fenêtre (ex. avec le raccourci Alt+Tab), ou utilisez le raccourci Ctrl+Tab, qui permet de circuler parmi les documents ouverts (créez dès maintenant un nouveau document et passez de celui-ci à ce document en guise d'exercice). + + + + + +Créer des formes + +Il est temps de passer aux formes! Cliquez sur l'outil Rectangle dans la barre d'outils (ou appuyez sur F4) et avec un cliquer-déplacer, créez un rectangle, soit dans un nouveau document vide, soit dans celui-ci : + + + + +Comme vous pouvez le voir, par défaut, les rectangles sont bleus, partiellement transparents et avec une épaisseur de contour de 1 pt. Nous allons bientôt voir comment changer cela. Avec les autres outils, vous pouvez aussi créer des ellipses, des étoiles et des spirales : + + + + +Ces outils sont les outils de formes. Chaque forme créée affiche une ou plusieurs poignées en forme de diamant; essayez de les déplacer pour voir comment la forme réagit. Pour chacun des outils de formes, la barre de contrôle fournit une façon supplémentaire de modifier la forme; ces contrôles affectent la forme sélectionnée (c'est à dire celle qui a ses poignées affichées) et définissent les paramètres par défaut qui s'appliqueront lors de la création de toute nouvelle forme. + + +Pour annuler votre dernière action, appuyez sur Ctrl+Z (ou si vous changez d'avis, vous pouvez refaire l'action annulée avec Maj+Ctrl+Z). + + + + + +Déplacer, redimensionner et tourner + +L'outil d'Inkscape le plus utilisé est le sélecteur. Cliquez sur le bouton tout en haut (celui avec la flèche) dans la barre d'outils (ou appuyez sur F1 ou sur la barre d'espace). Vous pouvez alors sélectionner n'importe quel objet sur le canevas. Exemple : cliquez sur le rectangle ci-dessous. + + + + +Vous devez voir apparaître huit poignées en forme de flèche autour des bords de l'objet. Vous pouvez maintenant : + + + + +Déplacer l'objet à la souris avec un cliquer-déplacer (appuyez sur Ctrl pour restreindre le mouvement à l'horizontale et à la verticale). + + + + +Redimensionner l'objet, en déplaçant une poignée (appuyez sur Ctrl pour préserver ses proportions). + + + + +Cliquez à nouveau sur le rectangle. Les poignées changent de forme. Vous pouvez maintenant : + + + + +Tourner l'objet en déplaçant une poignée de coin (appuyez sur Ctrl pour forcer une rotation par incréments de 15 degrés; déplacez la croix pour définir le centre de rotation). + + + + +Incliner l'objet en déplaçant une poignée autre que celle d'un coin (appuyez sur Ctrl pour forcer une inclinaison par incréments de 15 degrés). + + + + +Toujours avec le sélecteur, dans les champs numériques de la barre supérieure, vous pouvez définir précisément les coordonnées (X et Y) et la taille (L et H) de la sélection. + + + + + +Transformer à l'aide des raccourcis clavier + +Une des capacités d'Inkscape le distinguant d'autres éditeurs vectoriels est la possibilité d'utiliser le clavier de façon intensive. Il n'y a pratiquement pas d'action ou de commande qui ne soit pas accessible depuis le clavier, et la transformation d'objet ne fait pas exception. + + +Vous pouvez utiliser le clavier pour déplacer (flèches), redimensionner (< et >) et tourner ([ et ]) les objets. L'incrément par défaut de modification des dimensions et de déplacement est de 2 px; avec la touche Maj, l'effet est multiplié par 10. Ctrl+> et Ctrl+< redimensionnent respectivement de 200% et 50% par rapport à l'original. L'incrément de rotation par défaut est de 15 degrés; ou de 90 degrés si vous appuyez sur simultanément sur Ctrl. + + +Mais les transformations à l'échelle du pixel sont peut-être les plus utiles, obtenues par la combinaison de la touche Alt avec un raccourci. Par exemple, Alt+flèche déplace la sélection d'1 pixel, au zoom courant (c'est à dire d'un pixel sur l'écran, à ne pas confondre avec l'unité px qui est une unité SVG de longueur indépendante du zoom). Ceci implique que si vous zoomez plus, un raccourci Alt+flèche provoquera un mouvement absolu plus petit, correspondant toujours à un pixel à l'écran. Il est ainsi possible de positionner des objets avec une précision arbitraire simplement en zoomant ou dézoommant selon les besoins. + + +De même, Alt+> et Alt+< changent les dimensions de la sélection d'1 pixel à l'écran, et Alt+[ et Alt+] la tournent de telle façon que le point le plus éloigné du centre bouge d'un seul pixel à l'écran. + + + + + +Sélections multiples + +Avec Maj+cliquer, vous pouvez simultanément sélectionner plusieurs objets. Avec un cliquer-déplacerVous pouvez aussi définir une zone autour des objets; on appelle ceci une sélection par bande étirable (le sélecteur crée une bande étirable quand on commence un cliquer-déplacer sur une zone vide; mais si vous appuyez sur Maj avant de cliquer, Inkscape forcera la création d'une bande étirable). Entraînez vous avec les trois formes ci-dessous : + + + + +Maintenant, utilisez la bande étirable (déplacer ou Maj+déplacer) à titre d'exemple pour sélectionner les deux ellipses mais pas le rectangle : + + + + +Tout objet sélectionné affiche une marque de sélection — par défaut une boîte l'entourant en pointillés. Ceci permet de distinguer facilement ce qui est sélectionné de ce qui ne l'est pas. Si, par exemple, vous sélectionnez les deux ellipses et le rectangle ci-dessus, sans ces indications, il vous sera difficile de savoir si les ellipses sont bien sélectionnées ou non. + + +Maj+cliquer sur un objet sélectionné l'exclut de la sélection. Sélectionnez les trois objets ci-dessus, puis utilisez Maj+cliquer pour exclure les deux ellipses de la sélection, en n'y conservant que le rectangle. + + +Appuyer sur Esc désélectionne tous les objets sélectionnés. Ctrl+A sélectionne tous les objets du calque courant (si vous n'avez pas créé de calque, vous sélectionnerez tous les objets du document). + + + + + +Grouper + +Plusieurs objets peuvent être réunis dans un groupe. Un groupe se comporte comme un simple objet quand vous le déplacez ou le transformez. Ci-dessous, les trois objets de gauche sont indépendants; les trois mêmes objets de doite sont groupés. Essayez de les déplacer. + + + + + + + + +Pour créer un groupe, sélectionnez un ou plusieurs objets et appuyez sur Ctrl+G. Pour dégrouper un ou plusieurs groupes, sélectionnez-les et appuyez sur Ctrl+U. Les groupes peuvent eux-mêmes être groupés, comme n'importe quels autres objets; de tels groupes récursifs peuvent avoir une profondeur quelconque. Mais, Ctrl+U ne dégroupe que le dernier niveau de groupe de la sélection; vous devrez répéter Ctrl+U si vous voulez dégrouper complètement des groupes de groupes. + + +Cependant, vous n'avez pas nécessairement besoin de dégrouper pour éditer un objet au sein d'un groupe. Un simple Ctrl+cliquer sur cet objet permet de le sélectionner seul et de l'éditer, ou Maj+Ctrl+cliquer sur plusieurs objets (inclus ou non dans des groupes quelconques) pour une sélection multiple. Essayez de déplacer ou transformer sans les dégrouper les formes du groupe ci-dessus à droite, puis de les désélectionner, et resélectionnez le groupe normalement pour vérifier qu'elles sont toujours groupées. + + + + + +Remplissage et contour + +Beaucoup de fonctions d'Inkscape sont accessibles par des boîtes de dialogues. La façon la plus simple d'attribuer une couleur à un objet est d'ouvrir la boîte de dialogue Montres du menu Objet, sélectionner un objet et cliquer sur une montre (couleur) pour le peindre (modifier sa couleur de remplissage). + + +La boîte de dialogue Remplissage et contour (Maj+Ctrl+F) est plus puissante. Sélectionnez la forme ci-dessous et ouvrez la boîte de dialogue Remplissage et contour. + + + + +Vous constatez que la boîte de dialogue a trois onglets : Remplissage, Contour et Style de contour. L'onglet Remplissage permet d'éditer le remplissage (l'intérieur) de(s) objet(s) sélectionné(s). L'utilisation des boutons juste sous l'onglet vous permet de choisir le type de remplissage, incluant sans remplissage (le bouton avec un X), couleur uniforme, ou encore dégradé linéaire ou radial. Pour la forme ci-dessus, le bouton couleur uniforme devrait être activé. + + +Plus bas, vous pouvez voir la collection de sélecteurs de couleur chacun dans un onglet : RVB, TSL, CMJN, et Roue. Le plus pratique est peut-être la roue, dans laquelle vous pouvez tourner un triangle pour choisir une teinte sur la roue, puis une nuance dans le triangle. Tous les sélecteurs de couleur comportent une réglette pour définir l'alpha (opacité) de(s) objet(s) sélectionné(s). + + +Quand vous sélectionnez un objet, la boîte de dialogue Remplissage et contour est mise à jour pour afficher ses remplissage et contour courants (quand plusieurs objets sont sélectionnés, elle affiche la moyenne de leurs couleurs). Jouez avec les exemples ci-dessous ou créez les votres : + + + + +En utilisant l'onglet Contour, vous pouvez enlever le contour d'un objet ou lui attribuer n'importe quelle couleur ou transparence : + + + + +Le dernier onglet, Style de contour, vous permet de définir la largeur et les autres paramètres du contour : + + + + +Enfin, vous pouvez utiliser des dégradés au lieu de couleurs uniformes pour les remplissages comme pour les contours : + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Quand vous passez d'une couleur uniforme à un dégradé, le dégradé nouvellement créé utilise cette même couleur, allant d'opaque à transparente. Utilisez l'outil de Dégradé (Ctrl+F1) pour déplacer les poignées de dégradé — les poignées de contrôle connectées par des lignes qui définissent la direction et la longueur du dégradé. Quand l'une de ces poignées est sélectionnée (surlignée en bleu), la boîte de dialogue Remplissage et contour permet de définir la couleur liée à cette poignée à la place de la couleur de l'objet sélectionné. + + +Une autre façon pratique de changer la couleur d'un objet est d'utiliser l'outil Pipette (F7). Un simple cliquer n'importe où sur le dessin avec cet outil permet d'attribuer la couleur ainsi capturée au remplissage de l'objet sélectionné (Maj+cliquer l'attribuera à son contour). + + + + + +Duplication, alignement, distribution + +Une des opérations les plus courantes est la duplication d'un objet (Ctrl+D). Le dupliqué est placé juste au dessus de l'original et est sélectionné, vous permettant ainsi de le déplacer à la souris ou avec des raccourcis. Pour vous exercer, essayer de remplir la ligne avec des copies du carré noir ci-dessous : + + + + +Il y a des chances que vos copies du carré ne soient pas bien alignées. La boîte de +dialogue Aligner et distribuer (Ctrl+Maj+A) devient alors utile. Sélectionnez tous les carrés (avec Maj+cliquer ou une bande étirable), ouvrez la boîte de dialogue et appuyez sur le bouton "Centrer selon l'axe horizontal", puis sur "Distribuer des distances horizontalement entre les objets" (consultez les indications affichées quand la souris passe au-dessus des boutons). Les objets sont maintenant alignés et distribués de façon équidistante. Voici d'autres exemples d'objets alignés et distribués : + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Ordre-z (ou superposition) + +Le terme ordre-z correspond à l'ordre d'empilement des objets sur un dessin, les objets du dessus masquant les autres. Les deux commandes du menu Objet, Monter au premier plan (Début) et Descendre à l'arrière plan (Fin), feront passer les objets sélectionnés tout au dessus ou tout au fond dans la superposition des objets du calque courant. Deux autres commandes, Monter (Page Précédente) et Descendre (Page Suivante), les déplaceront d'un cran seulement, c'est à dire juste au-delà d'un objet non sélectionné (seuls les objets chevauchant la sélection comptent; si rien ne chevauche la sélection, Monter et Descendre la déplacent tout au dessus ou tout au fond respectivement. + + +Exercez-vous à l'utilisation de ces commandes en inversant la superposition des objets ci-dessous, de telle sorte que l'ellipse la plus à gauche soit tout au-dessus et la plus à droite tout au fond : + + + + +Un raccourci de sélection très utile est la touche Tab. Si rien n'est sélectionné, il sélectionne l'objet le plus au fond; sinon, il sélectionne l'objet juste au-dessus de l'objet sélectionné dans l'ordre-z. Maj+Tab fait l'inverse, commençant par l'objet tout au-dessus en allant vers le fond. Comme les objets que vous créez sont ajoutés au-dessus de la superposition, appuyer sur Maj+Tab quand aucun objet n'est sélectionné vous permettra de retrouver facilement le dernier objet que vous avez créé. Essayez Tab et Maj+Tab sur les ellipses superposées ci-dessus. + + + + + +Sélectionner en-dessous et déplacer + +Que faire si l'objet dont vous avez besoin est caché derrière un autre objet ? Vous pouvez encore voir l'objet en dessous si celui du dessus est (partiellement) transparent, mais en cliquant dessus, vous sélectionnerez l'objet du dessus, pas celui dont vous avez besoin. + + +Pour cela, il faut utiliser Alt+cliquer. Alt+cliquer sélectionne d'abord l'objet du dessus, comme un cliquer normal; mais le Alt+cliquer suivant au même endroit sélectionne l'objet juste en-dessous; et ainsi de suite. Donc, plusieurs Alt+cliquer à la suite vous permettront de naviguer du dessus vers le fond à travers la superposition de différents objets sous le pointeur de la souris. Quand l'objet du fond est sélectionné, un Alt+cliquer de plus sélectionne de nouveau l'objet du dessus. + + +D'accord, mais une fois l'objet recouvert sélectionné, qu'en faire ? Vous pouvez le transformer grâce aux raccourcis et déplacer ses poignées de sélection. Cependant, déplacer l'objet lui-même resélectionnera l'objet tout au dessus à nouveau (le cliquer-déplacer est conçu comme cela : d'abord sélectionner l'objet le plus haut juste sous le curseur puis déplacer la sélection). Pour demander à Inkscape de déplacer la sélection présente (éventuellement en-dessous d'autres objets) sans rien sélectionner d'autre, utilisez Alt+déplacer. Cela vous permettra de déplacer la sélection courante où que vous placiez la souris. + + +Essayez Alt+cliquer et Alt+déplacer sur les deux formes brunes sous le rectangle vert transparent : + + + + + + + +Conclusion + +Ceci conclut le didacticiel basique. Inkscape offre beaucoup d'autres fonctionnalités, mais les techniques décrites ci-dessus vous permettront déjà de créer des dessins simples mais utiles. Pour un usage plus avancé, consultez le didacticiel avancé dans Aide > Didacticiels. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/share/tutorials/tutorial-basic.ja.svg b/share/tutorials/tutorial-basic.ja.svg new file mode 100644 index 000000000..61ab8a538 --- /dev/null +++ b/share/tutorials/tutorial-basic.ja.svg @@ -0,0 +1,401 @@ + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ::基本 + + + + + + + + +このチュートリアルは Inkscape の基本的な使用法について示している。これは Inkscape +正規のドキュメントであり閲覧、編集、複製、保存が可能である。 + + +この基本的なチュートリアルは、キャンバスの操作、書類の取り扱い、シェイプツールの基本、選択法、セレクタを用いてオブジェクトを変換すること、グループ化、フィルとストロークの設定、レイアウト、z順序について記述している。さら進んだトピックについてはヘルプメニューのその他のチュートリアルを確認すること。 + + + + + +キャンバスのパン + +ドキュメントを表示しているキャンバスをパン(スクロール)する方法はいくつかある。Ctrl+arrow キーでキーボードからスクロールを行うことが出来る(このドキュメントを下にスクロールしてみるといい)。マウスの中ボタンでキャンバスをドラッグすることも出来る。またスクロールバー( Ctrl+B で表示、非表示出来る)を使うこともできる。マウスの ホイール を使って垂直方向のスクロールを行うことも可能だ。Shift キーを押しながらマウスホイールを使うと水平方向にスクロールする。 + + + + +ズームインとズームアウト +ズームを行う最も簡単な方法は - と + (または = ) キーを押すことだ。; Ctrl+middle click か Ctrl+right click でズームイン、 Shift+middle click か Shift+right click でズームアウトすることもできるし、 Ctrl を押しながら、マウスホイールを使うこともできる。また、ズーム入力域(ドキュメントウインドウの左下の角)をクリックし、正確なズーム値を%で入力してエンターキーを押すこともできる。ドラッグした領域をズームすることのできるズームツール(左のツールバーにある)もある。 + +Inkscape はセッションでのズームレベルの履歴を保持している。 ` を押すと前のズーム状態に戻り、 Shift+` で次に進む。 + + + + +Inkscape のツール + +左側の垂直なツールバーには Inkscape の描画ならびに編集ツールを表示している。ウインドウの一番上、メニューの下に一般的なコマンドボタンのあるコマンドバー、そして各ツール固有のの入力域を表示するツールコントロールバーが配置されている。ウインドウの下にあるステイタスバーには作業に応じて有用なヒントとメッセージが表示される。 + +多くの操作がキーボードショートカットから利用できる。ヘルプ > キー/マウス を開いて完全なリファレンスを見るといいだろう。 + + + +ドキュメントの作成と管理 + +新しい空のドキュメントを作成するにはメニュー、ファイル > 新規か Ctrl+N を押す。既存の SVG ドキュメントを開くには、メニューの ファイル > 開く (Ctrl+O) 。保存には、ファイル > 保存 ( Ctrl+S )、もしくは新しい名前を付けて保存する場合に 名前を付けて保存 (Shift+Ctrl+S)を使用する。(Inkscape はまだ不安定かもしれない、こまめに保存することをお忘れなく!) + + +Inkscape はファイルに SVG (Scalable Vector Graphics) フォーマットを使用している。SVG は広くグラフィックソフトウェアで使用されているオープンな標準である。SVG ファイルは、XML を基準としていてあらゆるテキストエディタと XML エディタで編集することができる(そう、Inkscape をはなれても)。Inkscape は SVG 以外のフォーマットを入力、出力することができる(EPS, PNG)。 + + +Inkscape はドキュメントごとに個別のウインドウを開く。複数のドキュメントはウインドウマネージャを使い操作することができる (例えば Alt+Tab を使って)、また Inkscape のショートカット、 Ctrl+Tab で全ての開いているドキュメントを巡回できる。(練習のためドキュメントの新規作成をして、このドキュメントと切り替えよ) + + + +シェイプの作成 +格好いいシェイプを作ってみよう! ツールバーの矩形ツールをクリック(か F4 を押す)し、新しいドキュメントの中か、こ +こでクリックしてドラッグ: + + + +見ての通り、デフォルトの矩形は青く、黒いストローク(輪郭)で半透明だ。これがどう変わるかを見ていこう。他のツール、楕円、星型、らせんを作ってみよう + + + +これらのツールは総称シェイプツールとして知られている。各シェイプには一つ以上のひし形のハンドルがある; このハンドルをドラッグしてシェイプがどう変るか見てみよう。シェイプのコントロールパネルはシェイプを調整するもう一つの方法だ; コントロールは選択中のシェイプに効果がある(すなわち、ハンドルの表示されているシェイプ)、そして新しく作成したシェイプにはデフォルト値が適用される。 + + +最後に行った操作をアンドゥするには、 Ctrl+Z を押す。(そして、もしまた気が変ったなら、アンドゥした操作を Shift+Ctrl+Z を押すことでリドゥすることができる。) + + + + +移動、スケール、回転 +Inkscape で最もよく使われるツールはセレクタである。ツールバーの一番上にあるボタン(矢印の)をクリックする、または F1 か Space を押す。するとキャンバス上の全てのオブジェクトが選択可能になる。この矩形をクリックしてみよう。 + + + + +矢印型の8個のハンドルがオブジェクトの回りに表示される。ここで: + + +ドラッグしてオブジェクトの移動ができる。( Ctrl を押すことで、移動を水平、垂直に限定できる) + + +ハンドルをドラッグしてオブジェクトのスケールができる。( Ctrl を押すことで、元の縦横比を維持してスケールできる。) + + + +今一度矩形をクリックしよう。ハンドルが変るはずだ。ここで: + + + +角にあるハンドルをドラッグすることでオブジェクトを回転することができる。( Ctrl を押すことで、回転を15度ごとに限定できる。十字のマークをドラッグすることで回転の中心を移動できる) + + +角以外にあるハンドルでオブジェクトを歪める(せん断変形させる)ことができる。( Ctrl を押すことで、変形を15度ごとに限定できる。) + + + +セレクタの状態で、正確な座標(XとY)と大きさ(WとH)を入力するためにコントロールバーの数値入力域(キャンバスの上にある)を使うこともできる。 + + + +キーによる変形 + +Inkscape を他のベクタエディタと大きく隔てているのは、キーボード操作の重視である。キーボードから操作できないコマンドや操作はほとんど無い、そして変形も例外ではない。 + +キーボードからオブジェクトの移動( arrow キー)、スケール( < と > キー)そして回転( [ と ] キー) が可能である。デフォルトの移動は 2px ごと; Shift を押すと10倍で移動、スケールする。Ctrl+> と Ctrl+< でそれぞれ元の200%、50%で拡大縮小する。デフォルトの回転は15度ごと; Ctrl を使うと90度ごとに回転する。 + +しかし、もっとも有用なのは、 Alt キーと変形キーを用いて行うピクセル単位の変形だろう。例えば、 Alt+arrows は、選択したオブジェクトを、そのときのズーム状態で1ピクセル移動する(すなわち、1スクリーンピクセル、ズーム状態と関係ない SVG の長さの単位 px と混乱しないように)。こういうことだ、もしズームインした状態 Alt+arrow を実行すると画面上では1ピクセル動くが絶対量としてより小さい移動になる。したがって、ズームイン、ズームアウトを行うことで任意の精度でオブジェクトの位置決めを行うことができる。 + +同様に、 Alt+> と Alt+< で、選択したオブジェクトの見た目の大きさをスクリーンピクセルでスケールできる。また Alt+[ と Alt+] でオブジェクトの中心点から最も遠い点が、1スクリーンピクセル移動するだけ回転する。 + + + +複数選択 +Shift+click でいくつのオブジェクトでも同時に選択することができる。また、オブジェクトの周りを drag することでも選択することが可能; これはラバーバンド選択と呼ばれている(セレクタは何も無いところからドラッグを始めるとラバーバンドを作る; しかし、ドラッグを始める前に Shift を押すと常にラバーバンドが作られる)。下の3つのシェイプで練習せよ: + + + + +それでは、ラバーバンドを使って(ドラッグか Shift+drag で)矩形以外の +2つの楕円を選択してみよう: + + + + +選択されている各オブジェクトは、デフォルトで破線の矩形である選択キューを表示する。このキューは何が選択されていて何が選択されていないのかを一度に見るのに役立つ。例えば、もし2つの楕円と矩形を選択した場合、選択キューがないと楕円が選択されているかどうかを判断するのが難しいだろう。 + +選択したオブジェクトに対して Shift+click を行うとそのオブジェクトは選択から除外される。上の3つのオブジェクトを選択して、 Shift+click を3つの楕円に対して行うと、選択の中には一つの矩形だけが残される。 + +Esc を押すことで全てのオブジェクトを非選択にすることができる。 Ctrl+A で現在のレイヤーにある全てのオブジェクトを選択する(もしレイヤーを作成していない場合これはドキュメントの全てのオブジェクトを選択するのと同じである) + + + +グループ化 + +複数のオブジェクトを結合してグループにすることができる。グループはドラッグや変形をすると一つのオブジェクトのように振舞う。下の左の3つのオブジェクトは別個のもので、右の3つのオブジェクトはグループである。グループをドラッグしてみよ。 + + + + + + + + +グループを作るには、1つ以上のオブジェクトを選択して Ctrl+G を押す。グループを解除するには、選択してから Ctrl+U を押す。グループ自体も他のオブジェクトと同じようにグループ化される; このような再帰的グループ化は任意の深さにできる。しかし、 Ctrl+U は選択の最上位のグループのみを非グループ化する; 深くグループ化したグループを完全に非グループ化するには何度も Ctrl+U を押す必要がある。 + +しかし、もしグループ化されたオブジェクトの1つを編集したいのなら、非グループ化をする必要は無い。 Ctrl+click するだけで、オブジェクトを選択、単独で編集でき、 Shift+Ctrl+click で複数のオブジェクト(グループ内であれ外であれ)をグループ化を気にせず選択できる。グループ中の個々のオブジェクト(上図右)を非グループ化せずに移動や変形せよ、そして選択を解除してから普通にグループを選択してグループ化が維持されていることを確認せよ。 + + + +フィルとストローク + +Inkscapeの多くの機能はダイアログを利用している。おそらくオブジェクトに色をつける最も簡単な方法はオブジェクトメニューからスウォッチダイアログを開いて、オブジェクトを選択し、スウォッチをクリックして色を塗る(フィル色を変える)ことだろう。 + + +もっと有効なのはフィルとストロークダイアログを開くことだ( Shift+Ctrl+F )。 +下のシェイプを選択してフィルとストロークダイアログを開いてみよ。 + + + +このダイアログには3つのタブがある: フィル、ストロークペイント、ストロークスタイルだ。フィルタブは選択したオブジェクトのフィル(内部)を編集する。タブのすぐ下のボタンでフィルの有無(Xのボタン)とタイプ、単色、線形グラディエント、放射状グラディエントを選択できる。上のシェイプでは単色が有効になっている。 + +さらに下には、数種のカラーピッカがあるのが分かる。各ピッカはタブになっている:RGB、CMYK、HSL、そしてホイール。おそらくもっとも便利なのは3角形を回して色を選択し、三角形の中で彩度を選択するホイールだろう。全てのピッカはオブジェクトのアルファ値(不透明度)を 設定するためのスライダを備えている。 + +オブジェクトの選択をするとカラーピッカは現在のオブジェクトのフィルとストロークを表示するために更新される(複数のオブジェクトが選択されているばあい、平均の色が表示される)。以下のサンプルや、自分で作ったオブジェクトで試してみよ: + + + +ストロークペイントタブで、ストローク(輪郭)を取り除くことや色と透明度の設定ができる: + + + + +>最後のストロークスタイルタブでは、ストロークの幅とその他のパラメータを設定できる: + + + +最後に、フィルやストロークに単色に代えて、グラディエントを適用できる: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +単色をグラディエントに切り替えるときに、新しく作成されたグラディエントはその前に使っていた色を不透明から透明に変化させている。グラディエントツールに切り替え( Ctrl+F1 )グラディエントハンドルをドラッグしてみよう。グラディエントツールではグラディエントの方向と長さを線によって連結されたコントロールが決めている。グラディエントハンドルを選択すると(青くハイライトされる)、 フィルダイアログとストロークダイアログは選択したオブジェクトの色に代えてハンドルで示した色を適用する。 + +他にオブジェクトの色を変える便利な方法としてドロッパーツール( F7 )もある。絵のどの部分でも click するだけで、抽出した色が選択中のオブジェクトのフィルに(Shift+click でストロークの色に)適用される。 + + + +複製、整列、配置 + +もっとも一般的な操作にオブジェクトの複製がある( Ctrl+D )。複製は正確に元のオブジェクトの上に位置し選択状態になってるので矢印キーやマウスでドラッグすることで移動できる。練習としてこの黒い正方形で線を描いてみよ: + + + +ちょうどいいことに、あなたがコピーした正方形はいくらか乱れて並んでいることだろう。ここでレイアウトダイアログが役に立つ( Ctrl+Shift+A )。すべての正方形を選択して( Shift+click かラバーバンドを使う)、レイアウトダイアログを開き、「水平方向で中央に配置」ボタンを押し、さらに「オブジェクトの間隔を水平方向に等幅にして配置」ボタン(ボタンのツールティップを読む)。これでオブジェクトはきちんと位置が揃い等間隔に並ぶ: + + + + + + + + + + + + + + + + + + + + + + + + + + + +z順序 + +z順序はオブジェクトを描くときの重なりの順序を意味する、つまりどのオブジェクトが上になって他のオブジェクトを隠しているかである。オブジェクトメニューにある2つのコマンド、最前面へ( Home キー)、最背面へ( End キー)は選択したオブジェクトを現在のレイヤーのz順序の最前面、最背面に移動する。もう2つのコマンド、前面へ( PgUp )と背面へ( PgDn )は選択したオブジェクトを1つだけ前後に移動する、つまり選択していないオブジェクトを1つかわしていくということだ(もしなにも選択したオブジェクトを覆い隠していないときには前面へと背面へは最前面、最背面に移動を行う)。 + +これらのコマンドを使って左の楕円が一番上、右の楕円が一番下にくるように下のオブジェクトのz順序を反転せよ: + + + +Tab は非常に便利なショートカットキーである。もし何も選択されていない場合には一番下にあるオブジェクトを選択する;さもなければz順序でみて選択されたオブジェクトの上にあるオブジェクトを選択する。 Shift+Tab は逆に働く、最上位のオブジェクトから下に向かって働く。新しく作ったオブジェクトは一番上に重ねられるので、何も選択しないで Shift+Tab を押すことは最後に作ったオブジェク + + + +隠れているオブジェクトの選択とドラッグでの選択 + +他のオブジェクトの下にあって隠れているオブジェクトはどうやって選択したらいいのか?上のオブジェクトが(半)透明なら下のオブジェクトを見ることはできる、しかしクリックするとあなたが必要としていない上のオブジェクトが選択される。 + +ここで Alt+click の出番だ。はじめの Alt+click では普通のクリックと同じように1番上のオブジェクトが選択される。しかし、同じ場所で次の Alt+click を行うと1番上のオブジェクトの下にあるオブジェクトが選択される;次のクリックでは、その下。こうして Alt+click を何回か行うとクリックした点にあるオブジェクトのz順序の重なりを前面から背面に循環する。最下層のオブジェクトまで到達すると、次の Alt+click では自然にもう一度最上位のオブジェクトが選択される。 + +これは良いことだ、しかし表面にないオブジェクトを選択したとしてそれで何ができるのか?変形できるし、選択ハンドルをドラッグすることができる。しかし、オブジェクト自体のドラッグすると選択はリセットされ最上位のオブジェクトが選択される(これはクリック-アンド-ドラッグの設計がそうなってるため。選択をドラッグする場合カーソル位置の(最上位)のオブジェクトが選択されるのである)。Inkscapeに何かを選択せずに、今選択されているものをドラッグするよう知らせるには Alt+drag を使う。 こうすればマウスをどこでドラッグしても現在の選択を移動できるのである。 + +緑の半透明の矩形の中にある2つの茶色のシェイプで Alt+click と Alt+drag の練習をせよ: + + + + + + + +最後に + +これで基本チュートリアルを終わる。Inkscape にはもっと沢山の機能がある。しかしここで説明したテクニックですでに簡単かつ有用なグラフィックを作成することができるであろう。もっと複雑な作業については ヘルプ > チュートリアル から上級、その他のチュートリアルを実行するといいだろう。 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/share/tutorials/tutorial-basic.nn.svg b/share/tutorials/tutorial-basic.nn.svg new file mode 100644 index 000000000..a9212c847 --- /dev/null +++ b/share/tutorials/tutorial-basic.nn.svg @@ -0,0 +1,379 @@ + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ::DET GRUNNLEGGJANDE + + + + + + + +Her er ei kort innføring i dei vanlegaste funksjonane i Inkscape. Dokumentet er eit heilt vanleg Inkscape-dokument, som du kan endra som du vil. + +Innføringa dekkjer flytting og forstørring av lerret og objekt, opning og lagring av dokument, figurverktøy, merking og omforming av objekt, snøggtastar, gruppering, fargar og figurfyll, samt objektjustering og z-ordning. Du finn òg fleire emne i dei andre innføringane tilgjengelege frå Hjelp-menyen. + + + + +Flytting av lerretet + +Det er mange måtar du kan flytta lerretet rundt på. Med tastaturet kan du trykkja Ctrl + piltastar. (Prøv gjerne dette no.) Du kan òg dra lerretet ved å halda inne midtre museknapp (rullehjulet) og flytta på musa. Ein tredje måte er å bruka rullefelta (trykk Ctrl + B for å visa eller skjula dei). Og har du eit rullehjul på musa kan du flytta loddrett med dette. Hald inne Shift for å flytta vassrett. + + + +Forstørring +Du kan lettast forstørra og forminska lerretet med - og +. Du kan òg bruka Ctrl + midtklikk eller Ctrl + høgreklikk for å forstørra, og Shift + midtklikk og Shift + høgreklikk for å forminska. Har du ei mus med rullehjul, kan du òg halda inne Ctrl og rulla med dette. Ein fjerde måte er å bruka forstørringsfeltet nede til venstre og skriva inn ein nøyaktig verdi, og ein siste måte er å bruka forstørringsverktøyet i verktøylinja til venstre. Berre dra ein boks rundt området du vil sjå nærare på. +I tillegg held Inkscape ein logg over dei forstørringsnivå du har brukt. Trykk ` for å gå til førre forstørringsnivå, og Shift + ` for å gå til neste. + + + +Inkscape-verktøy + +Den loddrette verktøylinja til venstre inneheld dei ulike teikne- og redigeringsverktøya, mens kommandolinja oppe inneheld generelle kommandoknappar, og kontrollinja under denne inneheld kontrollar for kvar av desse igjen. Statuslinja nede viser nyttige tips og meldingar når du arbeidar med dei ulike verktøya. + +Dei fleste operasjonane er òg tilgjengelege frå snøggtastar. Sjå Hjelp | Tastatur og mus for ei fullstendig oversikt. + + + +Opning og lagring av dokument + +Bruk Fil | Nytt eller trykk Ctrl + N for å laga eit nytt dokument, og Fil | Opna eller Ctrl + O for å opna eit gammalt. Lagra gjer du med Fil | Lagra (Ctrl + S), eventuelt med Fil | Lagra som (Ctrl + Shift + S) for å lagra under eit anna filnamn. (Inkscape er framleis ikkje 100 % stabil, så du bør lagra ofte!) + +Inkscape brukar SVG (Scalable Vector Graphics) som lagringsformat. SVG er ein open standard, og breitt støtta av andre biletprogram. SVG er basert på XML, og kan endrast med vanlege skriveprogram og XML-verktøy. Inkscape kan i tillegg importera og eksportera fleire andre filformat (blant anna EPS og PNG). + +Kvart dokument vert opna i eit eige vindauge, og du kan flytta mellom dei på vanleg måte (til dømes med Alt + Tab), eller ved å bruka Inkscape-snøggtasten Ctrl + Tab for å gå gjennom alle Inkscape-dokument. (Lag gjerne eit nytt dokument no, og øv deg på å byta fram og tilbake mellom dokumenta.) + + + +Teikning av figurar +På tide med litt teikning! Trykk på rektangelverktøyet i verktøylinja til venstre (eller trykk F4) og klikk og dra, anten i eit nytt dokument eller her: + + + +Som du ser er alle rektangla som standard blå, delvis gjennomsiktige og med eit 1 punkts breitt omriss. Me skal læra å endra på alt dette nedanfor. Du kan òg teikna ellipsar, stjerner og spiralar: + + + +Dette er alle dei forskjellige figurverktøya. Som du ser, har kvar figur du teiknar eitt eller fleire ruterforma kontrollpunkt. Prøv å dra i desse, og sjå kva som skjer med figuren. Verktøylinja oppe har òg nokre kontrollar du kan stilla for å endra på figuren på forskjellige måtar. Desse påverkar den merkte figuren (han med kontrollpunkta), og set standardverdiar for nye figurar. + +Du kan angra den siste endringa du har gjort ved å trykkja Ctrl + Z.Og viss du ombestemmer deg, kan du gjera om angringa ved å trykkja Shift + Ctrl + Z. + + + + +Flytting, skalering og rotering Det mest brukte Inkscape-verktøyet er objektveljaren. Vel den øvste knappen (pilknappen) i verktøylinja til venstre (eller trykk F1 eller mellomromstasten). No kan du merkja objekta på lerretet. Prøv å merkja firkanten nedanfor: + + + +Det dukkar no opp åtte pilforma kontrollpunkt rundt heile objektet, og du kan: + + +Flytta objektet ved å dra det. Hald inne Ctrl for å avgrensa til vassrett eller loddrett rørsle. + + +Skalera objektet ved å dra i eit av kontrollpunkta. Hald inneCtrl for å halda på det opphavlege høgd/breidd-forholdet. + + +Trykk på firkanten igjen. Kontrollpunkta vert no endra, og du kan: + + + +Rotera objektet ved å dra i hjørnepunkta. Hald inne Ctrl for avgrensa til 15 gradars rotering. Dra krossmerket for å velja midtpunktet for roteringa. + + +Vri objektet ved å dra i sidepunkta. Hald inne Ctrl for å avgrensa til 15 gradars vriing. + + +Du kan òg bruka talboksane øvst i vindauget for å velja nøyaktige koordinatar («X» og «Y») og storleik («B» og «H») for utvalet. + + + +Omforming med tastaturet + +Eitt område Inkscape skil seg frå dei fleste andre teikneprogramma på, er den omfattande støtta for snøggtastar. Det finst knapt ein einaste kommando du ikkje kan nå direkte frå tastaturet, og omformering av objekt er ikkje noko unntak. + +Du kan bruka tastaturet for å flytta (piltastane), skalera (< og +>)og rotera ([ og ]) objekt. Som standard vert objekta flytta og skalerte med 2 punkt, men held du inne Shift vert dei flytta og skalerte 10 gongar så mykje. Ctrl + +> og Ctrl + < skalerer opp eller ned 200 % eller 50 %. Som standard roterer du objekta 15 gradar, men du kan halda inne Ctrl for å rotera dei 90 gradar. + +Men kanskje det nyttigaste er pikselbaserte omformingar, som du gjer ved å halda inne Alt og bruka omformingstastane. Til dømes vil Alt + piltastane flytta utvalet 1 skjermpiksel ved gjeldande forstørring.Du vil altså flytta kortare ved høg forstørring enn ved låg. Du kan såleis plassera objekta så nøyaktig du vil, berre ved å forstørra inn eller ut. + +Tilsvarande vil Alt + +> og Alt + < skalera utvalet slik at den synlege storleiken vert endra med éin skjermpiksel, og Alt + [ og Alt +] skalera utvalet slik at det ytste punktet vert flytta éin skjermpiksel. + + + +Fleirmerking Du kan merkja fleire objekt samtidig ved å halda inne Shift når du trykkjer på dei. Eventuelt kan du dra rundt dei du vil merkja. Dette heiter gummistrikkmerking. (Objektveljaren lagar ein gummistrikk når du drar frå eit tomt område, men viss du held inne Shift før set i gang å dra, vil du alltid få ein gummistrikk.) Øv deg no på å merkja alle tre figurane nedanfor. + + + +Bruk no gummistrikken (ved å dra eller halda inne Shift og dra) for å merkja dei to ellipsane men ikkje rektangelet: + + + +På kvart objekt i eit utval kan du sjå eit lite utvalsmerke – som standard ei stipla linje rundt – øvst i venstre hjørne. Dette gjer det lett å sjå kva som er, og ikkje er, merkt. Det hadde til dømes vore vanskeleg å sjå om ellipsane ovanfor var merkte om òg rektangelet var merkt om du ikkje hadde hatt dette utvalsmerket. + +Du kan òg fjerna objekt frå utval ved å halda inne Shift og trykkja på dei. Prøv det no, ved å merkja alle dei tre objekta ovanfor, og bruk så Shift + klikk for å fjerna dei to ellipsane frå utvalet, slik at berre rektangelet er merkt. + +Du kan trykkja Escape for å fjerna all merking. Og for å velja alle objekta i gjeldande lag trykkjer du Ctrl + A. (Dette kan ta lang tid i store dokument som dette.) + + + +Gruppering + +Du kan setja saman fleire objekt til ei gruppe, og denne fungerer då som som eit einskildobjekt når du dreg eller formar ho om. Nedanfor er dei tre figurane til venstre einskildobjekt, mens dei tre til høgre er ei gruppe. Prøv å flytta på gruppa. + + + + + + + +Merk eitt eller fleire objekt og trykk Ctrl + G for å gruppera dei, og trykk Ctrl + U for å løysa opp éi eller fleire merkte grupper. Du kan òg gruppera grupper, akkurat som med andre objekt. Du kan ha mange grupper inni kvarandre, men Ctrl + U vil berre løysa opp den øvste grupperinga i utvalet. Ønskjer du å løysa opp ei djup «gruppegruppe» må du altså trykkja Ctrl + U mange gongar. + +Men du er ikkje nøydd til å løysa opp ei gruppe berre for å endra på dei grupperte objekta. Berre hald inne Ctrl og trykk på objektet for å merkja det, eller hald inne både Shift og Ctrl for å merkja fleire objekt (både inni og utanfor grupper). Prøv å flytta og forma om figurane i gruppa oppe til høgre utan å løysa opp gruppa. Fjern så merkinga, og trykk på gruppa igjen. Som du ser er objekta framleis grupperte. + + + +Fyll og strek + +Mange av funksjonane i Inkscape er tilgjengelege frå dialogvindauge. Den enklaste måten å fargeleggja eit objekt er å opna fargesamlingsdialogen frå Objekt | Fargesamlingar. Vel så eit objekt, og trykk på ein farge for å fargeleggja det. + +Men Fyll og strek-dialogen (Shift + Ctrl + F) er kraftigare. Vel figuren nedanfor, og opna Fyll og strek-dialogen. + + + +Som du ser har dialogvindauget tre faner: «Fyll», «Strekfarge» og «Strekstil». I «Fyll»-fana kan du redigera fyllet til (det indre av) dei merkte objekta. Ved å bruka knappane under fanelinja kan du byta mellom ingen fyll («X»-knappen), heildekkjande farge og lineær eller hjulforma fargeovergang. For ellipsen ovanfor vil knappen for heildekkjande farge vera vald. + +Lengre nede i dialogvindauget ser du fargeveljarane, kvar i si eiga fane: RGB (raud, grøn og blå), HSV (nyanse, metting og lysstyrke), CMYK (cyanblå, magentaraud, gul og svart) og fargehjulet. Sistnemnte er kanskje den fargeveljaren som er greiast å bruka. Du roterer trekanten for å velja fargenyanse, og vel vidare nøyaktig fargen inni trekanten. Alle fargeveljarane har òg ein glidebrytar for å velja gjennomsikt («alfaverdi»). + +Når du merkjer eit objekt, vert fargeveljaren fyllt med fargen og streken til objektet. (For fleire merkte objekt vert gjennomsnittsfargen vist.) Prøv deg fram no, og vel forskjellige fargar. Ta gjerne utgangspunkt i figurane nedanfor: + + + +I «Strekfarge»-fana kan du fjerna streken (omrisset) rundt objekt, eller endra fargen eller gjennomsikta: + + + +I den siste fanen, «Strekstil», kan du velja breidda og andre eigenskapar ved streken: + + + +Du kan òg laga fargeovergangar i staden for heildekkjande fargar, både for fyll og strek: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Når du går frå heildekkjande fargar til fargeovergangar, vil dei nye overgangane bruka same farge, men gå frå heildekkjande til gjennomsiktig. Byt til fargeovergangsverktøyet (Ctrl + F1) for å dra overgangspunkta – punkta som bind saman linjene som definerer retninga og lengda til overgangen. Når eit overgangspunkt er merkja, vil «Fyll og strek»-dialogen setja fargen til punktet i staden for fargen til heile objektet. + +Fargehentaren (F7) er ein siste, praktisk måte å endra fargane på. Berre klikk ein plass i teikninga med verktøyet, og fargen under peikaren vert brukt som fyllfarge for objektet (hald inne Shift viss du vil endra strekfargen). + + + +Kopiering, justering og fordeling + +Noko av det du kjem til å gjera mykje av, er å laga kopiar av objekt(Ctrl + D). Kopien vert plassert rett oppå opphavet, og du kan som vanleg flytta han med musa eller med piltastane. Prøv no å fylla linja under med kopiar av denne svarte firkanten: + + + +Truleg vart ikkje kopiane plasserte nøyaktig på rett linje. Her er «Juster og fordel»-dialogen (Ctrl + Shift + A) nyttig. Merk alle firkantane (Shift + klikk eller dra ein gummistrikk), opna dialogen og trykk «Sentrer vassrett» og «Fordel vassrett luft jamnt mellom objekt» (les verktøytipsa som dukkar opp når du held peikaren over knappane). Her er nokre fleire døme på justering og fordeling: + + + + + + + + + + + + + + + + + + + + + + + + + + + +Z-ordning + +Omgrepet z-ordning viser til rekkjefølgja objekta vert lagt oppå kvarandre i teikninga, altså kva objekt som ligg over og dekkjer andre. Dei to kommandoane Send fremst (Home) og Send bakarst (End) på Objekt-menyen flyttar objekta framfor eller bak alle andre objekt i det gjeldande laget. Du kan òg bruka Hev (Page Up) og Senk (PageDown) for å heva eller senka dei berre eitt steg, og altså flytta dei forbi eitt objekt i z-ordninga. Berre objekt som overlappar utvalet vert tekne omsyn til her. Til dømes vil Hev og Senk flytta utvalet heilt fremst eller bakarst i z-ordninga dersom ingen objekt overlappar utvalet. + +Øv deg no på å bruka desse kommandoane på objekta nedanfor, slik at ellipsen heilt til venstre vert liggjande øvst, og den heilt til høgre vert liggjande nedst: + + + +Ein veldig nyttig snøggtast når det gjeld objektmerking er Tab. Viss ingenting er merkt, vil han merkja det bakarste objektet. Elles vil han merkja objektet som ligg rett over utvalet i z-ordninga. Shift + Tab verkar motsett, og startar altså med det fremste objektet og arbeidar seg bakover. Sidan alle nye objekt vil leggja seg fremst, vil Shift + Tab merkja det objektet du teikna sist, så lenge ingen objekt er merkte. Øv deg no med Tab og Shift + Tab på ellipsane ovanfor. + + + +Merking og draging av underliggjande objekt + +Kva skal du gjera viss objektet du treng er skjult under eit anna objekt? Du ser kanskje det nedste objektet viss det over er (delvis) gjennomsiktig, men trykkjer du på det, vil du merkja det øvste objektet. + +Dette er kva Alt + klikk er her for. Alt + klikk merkjer først det øvste objektet, akkurat som eit vanlig objekt. Men neste gong du trykkjer Alt + klikk på same punkt, vil du merkja objektet under det øvste, gongen etter vil du merkja objektet under der igjen, og så vidare. Når du når det nedste objektet, vil Alt + klikk naturlegvis merkja det øvste objektet igjen. + +Dette er greitt nok, men kva kan du sjå gjera med eit underliggjande objekt du har merkja? Vel, du kan bruka snøggtastar til å forma det om, og du kan dra kontrollpunkta. Men dreg du objektet sjølv, vil dra det øvste objektet igjen. For å be Inkscape dra det objektet som no er merkt utan å merkja noko anna, ka du bruka Alt + dra. Dette vil flytta det gjeldande utvalet uavhengig av kor du plasserer peikaren. + +Øv no på Alt + klikk og Alt + dra på dei to brune figurane under det grøne, gjennomsiktige rektangelet: + + + + + + + +Konklusjon + +Dette var altså ei kort innføring i dei mest grunnleggjande funksjonane i Inkscape. Det finst mange fleire, men med det du har lært til no kan du klara å laga rett så flotte teikningar. Og er du interessert i å læra endå meir, finn du fleire innføringar under Hjelp | Innføringar. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/share/tutorials/tutorial-basic.ru.svg b/share/tutorials/tutorial-basic.ru.svg new file mode 100644 index 000000000..3d8c75596 --- /dev/null +++ b/share/tutorials/tutorial-basic.ru.svg @@ -0,0 +1,3036 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Этот учебник демонстрирует основы работы с Inkscape. Кроме того,это обычный документ Inkscape, который вы можете просматривать, редактировать и сохранять.Учебник первого уровня охватывает приемы прокрутки и масштабирования,экран Inkscape, инструменты рисования фигур, трансформацию объектов, выделение, группировку, заливку и штрих, выравнивание и распределение объектов. Более сложные темы см. в учебнике второго уровня в меню "Справка". + Прокрутка холста + Есть много способов проматывать рабочий холст документа.C клавиатуры используйте Ctrl+стрелки (попробуйте,например, Ctrl+вниз для прокрутки этого учебника). Кроме того,можно проматывать холст перетаскиванием средней кнопкой мыши.Можно также использовать полосы прокрутки (их можновключать/выключать клавишами Ctrl+B). Колесо мыши прокручиваетхолст по вертикали, а с нажатой клавишей Shift - по горизонтали. + Инструменты Inkscape + Панель в левой части окна содержит основные инструментыдля рисования и редактирования объектов. Верхняя панель(под меню) содержит элементы, специфичные для каждогоконкретного инструмента. На полосу состояния внизу окнавыводятся полезные подсказки и рабочие сообщения.Многие действия можно совершать при помощи клавиатуры.Полный справочник по клавишам можно вызвать через пункт меню Справка > Клавиатура и мышь. + + Изменение масштаба + Проще всего изменять масштаб клавишами - и + (или =). Такжеможно использовать щелчок средней клавишей мыши (shift+щелчокуменьшает масштаб), или вращение колеса мыши с нажатойклавишей Ctrl. Еще можно ввести нужный масштаб в поле вводав левом нижнем углу окна и нажать Enter. И, наконец, на панелислева есть инструмент "Изменение масштаба", при помощи которогоможно изменять масштаб, обводя мышью нужную область. + Документы + Для создания нового документа используйте меню "Файл > Создать" или клавиши Ctrl+N. Чтобы открыть существующий документ, используйте "Файл > Открыть" (Ctrl+O). Чтобы сохранить, нажимайте Ctrl+S, или, чтобы сохранить с другим именем, Shift+Ctrl+S (помните: Inkscape все еще нестабилен; сохраняйтесь чаще!).Inkscape открывает отдельное окно для каждого документа.Переключаться между окнами можно командой менеджера окон(обычно это Alt+Tab), или командой Inkscape Ctrl+Tab, котораяциклически переключает рабочие окна (попробуйте сейчассоздать несколько документов и попереключаться между ними). + Создание фигур + Теперь пора и порисовать. Выберите инструмент "Прямоугольник" налевой панели (или нажмите F4) и нарисуйте прямоугольник - в новом документе или прямо здесь: + Как видите, по умолчанию прямоугольник закрашен синим, имеетконтур (штрих) толщиной в 1 pt и частично прозрачен. Ниже мы покажем, как это изменить. А пока попробуйте рисовать эллипсы,звезды и спирали с помощью трех других инструментов: + Перемещение, изменение размера и вращение + Чаще всего в Inkscape используется инструмент выделения (селектор). Щелкните мышью по самой верхней кнопке на панели инструментов (или нажмите F1 или пробел). Теперь щелкните по любому объекту на холсте. Например, по этому квадрату: + Вокруг объекта вы увидите восемь инверсных стрелок. Теперь выможете: + Рассмотренные 4 инструмента называются инструментамисоздания фигур. Каждая вновь созданная фигура имеет белые"ручки" в некоторых точках контура; подвигайте их, чтобы увидеть, как изменяется фигура. Верхняя панель содержит поля ввода дляточной настройки параметров фигуры. Они (так же как и "ручки") изменяют ту фигуру, которая в данный момент выделена, а также определяют параметры, с которыми создаются новые фигуры.Чтобы отменить последнее действие, нажмите Ctrl+Z (а если еще разпередумали, верните изменение клавишами Shift+Ctrl+Z). + Перетаскивать сам объект мышью (нажмите Ctrl, чтобы двигатьсястрого по горизонтали или вертикали).Изменять размер объекта, перетаскивая мышью любую из стрелок(нажмите Ctrl, чтобы сохранить исходное отношениеширины и высоты). + Щелкните по прямоугольнику еще раз. Вид стрелок изменится.Теперь можно: + Поворачивать объект мышью при помощи угловых стрелок (с нажатой Ctrl объект поворачивается на углы, кратные 15 градусам).Перекашивать объект с помощью не-угловых стрелок. + Одна из особенностей Inkscape, отличающая его от большинствадругих векторных редакторов - это упор на использование клавиатуры.Вряд ли можно найти команду, которую невозможно выполнитьпри помощи клавиатуры, и трансформация объектов - не исключение.При помощи клавиатуры вы можете перемещать объекты (клавиши сострелками), изменять их размер (клавиши < и >) и вращать их(клавиши [ и ]). По умолчанию размеры и координаты изменяются на 2 пункта; с нажатой клавишей Shift - на 20 pt. Ctrl+> и Ctrl+< изменяют размер в 2 раза. Угол вращения по умолчанию - 15 градусов;с клавишей Ctrl фигура поворачивается на 90 градусов.Особенно удобны пиксельные трансформации, которые включаются с клавишей Alt. К примеру, Alt+стрелки будут перемещать выбранныйобъект на 1 пиксел в текущем масштабе. Т.е. если увеличитьмасштаб, то Alt+стрелка вызовет меньшее абсолютное смещение,которое на экране будет по-прежнему выглядеть смещением ровнона 1 пиксел. Точно так же работают пиксельное изменение размера (Alt+> и Alt+<) и пиксельное вращение (Alt+[ и Alt+]). + Выделение нескольких объектов + Вы можете выделить мышью сразу несколько объектов (Shift+щелчокна каждом). Можно обвести мышью все объекты, которые вы хотитевыбрать; это так называемое "резиновое" (rubberband) выделение(селектор рисует "резиновый" прямоугольник вокруг объектов, еслиначать на свободном пространстве листа; с нажатой клавишей Shift выделение начинается в любом случае, даже если начинать с объекта).Попрактикуйтесь в выделении на этих трех фигурах: + Теперь, используя "резиновое" выделение (без или с клавишей Shift), попробуйте выделить эллипсы, не выделяя прямоугольник под ними: + Заливка и штрих + Многие функции Inkscape доступны через диалоги. Все команды дляих открытия находятся в меню "Диалоги". Сейчас мы познакомимся сдиалогом "Заливка и штрих" (Shift+Ctrl+F) для изменения раскраскиобъекта. Выделите красный эллипс и откройте этот диалог. + Диалог содержит три вкладки: "Заливка", "Цвет штриха"и "Стиль штриха". Вкладка "Заливка" позволяет редактироватьокраску внутренней области фигуры. Используя кнопки внизувкладки, можно убрать окраску (кнопка со знаком Х), выбратьсплошную заливку, линейный или радиальный градиенты. Дляпоказанной выше фигуры выбрана заливка сплошным цветом.Ниже расположена панель выбора цвета, точнее - несколькопанелей, каждая на отдельной вкладке: "RGB", "HSV", "CMYK"и "Диск". Вероятно, самой удобной является "Диск", гдеможно выбрать тон цвета, вращая треугольник, а затем подобратьнасыщенность и яркость, перетаскивая маркер внутри треугольника. Все панели содержат ползунок для регулирования альфа-канала (прозрачности) объектов.Каждый раз, когда выделяется объект, в панели появляютсятекущие значения цветов. Поэкспериментируйте на этих примерах: + Используя вкладку "Цвет штриха", можно убрать штрих (контур) объекта или установить его цвет и прозрачность: + Последняя вкладка, "Стиль штриха", подволяет установить толщинуи другие параметры штриха: + И, наконец, вместо сплошной окраски, можно использоватьградиенты как для заливки, так и для штриха: + Дублирование, выравнивание и распределение + Одна из самых распространенных операций - дублирование объекта (Ctrl+D). Дубликат располагается точно над исходным объектом, становится выделенным, и можно сразу перемещать его мышью иликлавишами со стрелками. Для практики попробуйте выстроить в линиюдубликаты этого черного квадрата: + Вероятнее всего, копии квадрата после перетаскивания мышью стоят неровно. Здесь может оказаться полезным диалог "Выравнивание". Выберите все квадраты (Shift+щелчками, или обведя мышью), откройте диалог (из меню "Диалоги" или клавишами Shift+Ctrl+A) и нажмите эту кнопку на вкладке "Расставить":Теперь объекты распределены так, что горизонтальные интервалы между ними одинаковы. Вот другие примеры выравнивания и расстановки: + Z-порядок + Термин "Z-порядок" ("порядок по оси Z") относится к перекрыванию объектами друг друга на рисунке. Иначе говоря, Z-порядок определяет, какой объект находится выше и закрывает собой другие. Две команды в меню "Объект", "Поднять на передний план" (клавиша Home) и "Опустить на задний план" (клавиша End), поставят выделенные объекты на самую верхнюю или самую нижнюю позицию по оси Z. Две других команды, "Поднять" (PgUp) и "Опустить" (PgDn), опустят или поднимут выделенные объекты на один уровень относительно ближайшего невыделенного объекта (считаются только объекты, перекрывающие выделенные; если выделение ничем не перекрывается, оно будет поставлено на самую верхнюю или самую нижнюю позицию).Попрактикуйтесь в использовании этих команд, перевернув Z-порядокэтих эллипсов так, чтобы крайний левый эллипс оказался в самомверху, а крайний правый - в самом низу: + + Очень полезная клавиша для работы с выделениями - Tab. Если ничего не выделено, Tab выделяет самый нижний по оси Z объект; иначе Tab переключает выделение на объект, следующий непосредственно за выделенным объектом по оси Z. Shift-Tab работает в обратную сторону: начинает выделять с самого верхнего объекта и спускается вниз. Поскольку только что созданный объект становится самым верхним по оси Z, нажатие Shift-Tab в случае, если ничего еще не выделено, выделяет последний созданный объект. Проверьте работу клавиш Tab и Shift-Tab на эллипсах вверху. + + + + + Группировка + Можно объединить несколько объектов в группу. При перемещениии трансформации группа ведет себя как один объект. Левые три объектавнизу этого абзаца независимы; такие же объекты справа объединеныв группу. Попробуйте переместить группу. + Чтобы сгруппировать несколько объектов, нужно выделить их все и нажать Ctrl+G. Чтобы разгруппировать одну или несколько групп, выберите их и нажмите Shift+Ctrl+G. Сами группы можно объединять в группы, как и любые другие объекты; таким образом, группы могут быть рекурсивными с неограниченными уровнями вложенности. Shift+Ctrl+G отменяет только группирование верхнего уровня; нажмите Shift+Ctrl+G несколько раз, чтобы полностью разгруппировать все группы-в-группе.Не обязательно разбивать группу, если нужно отредактироватьодин объект из нее. Достаточно щелкнуть по объекту с нажатойCtrl (или Shift+Ctrl, если нужно отобрать несколько объектов), и можнобудет работать с объектом в группе отдельно. Попробуйте переместитьили трансформировать отдельные объекты группы из предыдущегопримера, не разъединяя ее, а потом снова выделите группу, чтобыубедиться, что объекты остались связанными. + Каждый выделенный объект показывает небольшой инверсный маркер в левом верхнем углу. Маркеры помогают легко видеть, какой объект выбран, а какой нет. К примеру, если выбрать оба эллипса и прямоугольник, то без маркеров трудно будет определить, выделены эллипсы или нет.Shift+щелчок на выделенном объекте исключает его из выделения. Выделите все три объекта вверху, а потом, используя Shift+щелчок, исключите эллипсы из выделения, оставив выделенным только прямоугольник.Нажатие Esc снимает любое имеющееся выделение. Ctrl+Aвыделяет все объекты в документе (это может занять значительноевремя, если документ большой - как, например, этот). + ::1 УРОВЕНЬ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Заключение + Учебник первого уровня завершен. Это лишь малая часть возможностей Inkscape, но и они уже позволяют создавать полезную графику. Описание более сложных вещей можно найти в учебнике второго уровня в меню Справка > Учебники. + Трансформация при помощи клавиатуры + Можно использовать поля ввода на верхней панели дляустановки точных значений координат (X и Y) и размеров (W и H)выделенных объектов. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/share/tutorials/tutorial-basic.sl.svg b/share/tutorials/tutorial-basic.sl.svg new file mode 100644 index 000000000..b0bf936e9 --- /dev/null +++ b/share/tutorials/tutorial-basic.sl.svg @@ -0,0 +1,437 @@ + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ::OSNOVE + + + + + + + +V tem vodiču vam bomo predstavili osnove uporabe Inkscapa. To je običajen dokument, ki ga lahko odprete, spreminjate in shranjujete. + + +Osnovni vodič po Inkscapu zajema gibanje, približevanje, upravljanje z dokumenti, risanje oblik, spreminjanje predmetov, metode izbiranja predmetov, združevanje, nastavljanje polnila in obrisa, poravnave in prekrivanje. Za ostale teme si poglejte Napredni vodič v meniju Pomoč. + + + + + +Gibanje po platnu + +Po dokumentu se lahko gibate na mnogo načinov. S tipkovnico držite tipko Ctrl in pritiskate na smerne tipke Ctrl+smerne tipke. (Poskusite se sedaj tako premakniti navzdol.) Platno lahko povlečete s srednjim miškinim gumbom. Uporabite lahko tudi drsnike (pritisnite Ctrl+B, da jih pokažete ali skrijete). Miškin kolešček vas premika po navpični osi; hkratno držanje tipke Shift po vodoravni. + + + +Približevanje in oddaljevanje pogleda +Najlažji način je pritiskanje tipk +, - ali =. Uporabite lahko tudi Ctrl+srednji gumb ali Ctrl+desni gumb za približanje pogleda, Shift+srednji gumb ali Shift+desni gumb za oddaljitev podgleda, ali pa držite Ctrl in vrtite miškin kolešček. V spodnjem desnem kotu okna lahko stopnjo povečave tudi izberete ali vpišete v odstotkih. Končno pa imamo tudi orodje za Pogled (v levi orodjarni), s katerim lahko približate območje tako, da ga obkrožite. + +Inkscape si zapomni tudi zgodovino povečav, ki ste jih med delom uporabili. Pritisnite ` za premikanje skozi prejšnje povečave ali Shift+` za prejšnje bodoče. + + + + +Orodja v Inkscapu + +Navpična orodjarna na levi strani vsebuje orodja za risanje in urejanje. V gornjem delu zaslona, pod meniji najdete Vrstico ukazov s splošnimi funkcijami, in Vrstico orodja, ki prikazuje možnosti posameznega orodja. +Vrstica stanja na dnu okna med delom prikazuje uporabne nasvete +in sporočila. + +Mnogo dejanj lahko napravite s pomočjo kombinacij tipk na tipkovnici. Odprite Pomoč > Miška in tipkovnica za celoten spisek. (V naslednjem razdelku bomo s tipkovnico prilagajali pogled). + + + +Ustvarjanje in urejanje dokumentov + +Da ustvarite nov, prazen dokument, izberite Datoteka > Nova ali +pritisnite Ctrl+N. Da odprete obstoječ SVG dokument, izberite +Datoteka > Odpri. Za shranjevanje uporabite Datoteka > Shrani ali pritisnite Ctrl+S, za shranjevanje pod novim imenom pa Shrani kot (Shift+Ctrl+S). (Inkscape je še v razvoju, zato shranjujte pogosto!) + +Inkscape za zapis datotek uporablja obliko SVG (Scalable Vector Graphics - raztegljiva vektorska grafika). SVG je odprt in široko podprt standard. SVG datoteke temeljijo na XML jeziku in jih lahko odpremo tudi s katerimkoli urejevalnikom besedil. Razen SVG zna Inkscape uvažati in izvažati tudi v različne druge zapise (EPS, PNG). + +Inkscape odpre ločeno okno za vsak odprt dokument. Med njimi +se lahko premikate s svojim upravljalnikom oken (na primer z Alt+Tab), +ali pa uporabite Inkscapovo bližnjico Ctrl+Tab, ki omogoča kroženje +med odprtimi okni. (Za vajo poskusite ustvariti nov dokument in +preizkusite preklapljanje med njim in tem vodičem). + + + +Risanje likov +Čas za risanje! Iz orodjarne izberite orodje za pravokotnike (ali pritisnite +F4) in povlecite po platnu. To lahko storite kar tu ali pa v novem dokumentu: + + + +Kot vidite, so pravokotniki najprej modri, delno prosojni, z obrobo +široko 1 točko. Kasneje se bomo naučili to spremeniti, sedaj pa +raje poskusite narisati še kako elipso, zvezdo in spiralo: + + + +To so orodja za like. Vsak lik, ki ga narišete, ima vsaj eno ročico v obliki romboida; poskusite jih premikati, da vidite, kako se lik odziva. V zgornji orodjarni je nekaj nastavitev za vsako orodje. Tudi tu lahko prilagajate obliko. Te nastavitve spremenijo trenutno izbran lik (tisti z ročicami) in se shranijo za bodoče novoustvarjene like. + +Zadnje dejanje lahko razveljavite s pritiskom na Ctrl+Z. (Če se še enkrat premislite, lahko obnovite razveljavljeno dejanje s Shift+Ctrl+Z). + + + + +Premikanje, raztezanje, vrtenje +Najpogosteje uporabljano orodje v Inkscapu je Izbirnik. Kliknite +na najvišji gumb v orodjarni, tisti s puščico (ali pritisnite F1 ali +preslednico). Sedaj lahko izberete katerikoli predmet na platnu. +Kliknite na spodnji pravokotnik. + + + +Okrog predmeta se pojavi osem ročic v obliki puščic. Sedaj lahko: + + +Predmet premikate tako, da ga povlečete. (Držite Ctrl, da gibanje omejite na vodoravno in navpično. + + +Umerjate (spreminjate velikost) tako, da povlečete poljubno ročico (Držite Ctrl, da ohranite izvirno razmerje višine in širine) + + + +Ponovno kliknite na pravokotnik. Ročice se spremenijo. Sedaj lahko: + + + +Vrtite predmet tako, da vlečete ročice v kotih. (Držite Ctrl, da preskakujete po 15 stopinj. Povlecite križec iz središča, da premaknete os vrtenja.) + + +Z vlečenjem srednjih ročic, lahko predmet nagibate (Držite Ctrl, da omejite nagibanje na 15-stopinjske kote.) + + +Ko delate z izbirnikom, lahko uporabljate tudi vnosna polja v vrstici za orodja (nad platnom). Z njmi lahko natančno določite koordinate in velikosti izbranih predmetov. + + + +Urejanje s tipkovnico + +Inkscape je v primerjavi z drugimi programi za vektorsko risanje poseben, saj daje velik poudarek delu s tipkovnico. Skorajda vsako dejanje lahko opravite s kombinacijo tipk. Tudi preoblikovanja predmetov niso izjema. + +S tipkovnico lahko premikate (smerne tipke), umerjate +(< in >), in vrtite ([ +in ]) predmete. Premikanje in umerjanje je privzeto 2 px; s +Shift, premikate ali umerjate za 10 x več. Ctrl+> +in Ctrl+< enakomerno umerjata na 200% or 50% velikosti izvirnika. Privzeta vrtenja so po 15 stopinj; s Ctrl, vrtite po 90 stopinj. + +Verjetno najbolj uporabna pa so preoblikovanja po pikah, ki jih +opravljamo s pritiskom na Alt in ustrezne tipke. Na primer, +Alt+smerniki bo izbiro premaknilo za eno piko pri trenutni povečavi. +(oz. za eno zaslonsko piko, česar ne smete zamešati z enoto imenovano pika, ki je dolžinska enota SVG, neodvisna od povečave) To pomeni, da bo, če približate pogled, dejanski premik predmeta manjši, izgledal pa bo še vedno eno točko. Tako lahko premete postavljate z poljubno natančnostjo enostavno tako, da približujete pogled. + +Podobno bosta Alt+> in Alt+< raztegnila izbiro, tako da bo njen prikaz spremenjen za 1 točko, in Alt+[ in Alt+] zavrtela izbiro tako, da so bo od osi najbolj oddaljena točka premaknila za 1 točko. + + + +Širše izbiranje +Več predmetov hkrati lahko izberete tako, da držite Shift in klikate +nanje, ali pa povlečete Izbirnik okrog njih. Temu rečemo elastika. (Izbirnik naredi elastiko, če začnete vleči na prazni površini; če pred tem že držite Shift pa v vsakem primeru.) Poskusite izbrati naslednje tri predmete: + + + + +In sedaj uporabite elastiko (poteg ali Shift+poteg), da izberete obe +elipsi, ne pa tudi pravokotnika: + + + + +Vsak od izbranih predmetov pokaže oznako izbire, majhen romboid v zgornjem +levem kotu. Ta oznaka vam olajša pregled nad tem, kaj je izbrano +in kaj ne. Če bi, na primer, izbrali obe elipsi in pravokotnik, brez +teh oznak ne bi mogli ugotoviti ali sta elipsi izbrani. + +Če sedaj kliknete na predmet in ob tem držite Shift, ga izključite iz +izbire. Izberite vse tri gornje predmete, nato uporabite ta prijem, da izključite obe elipsi, tako da vam ostane izbran le še pravokotnik. + + +Če pritisnete Esc, ni več izbran noben predmet. Ctrl+A izbere vse predmete na trenutnem sloju (če niste ustvarili nobenih slojev, je to isto kot izbira vseh predmetov v dokumentu). + + + +Združevanje + +Več predmetov lahko združite v skupino. Skupina se nato obnaša kot +enoten predmet, če jo premikate ali preoblikujete. Spodnji levi trije predmeti so neodvisni; enaki trije predmeti na desni, pa so združeni. Poskusite premakniti skupino. + + + + + + + +Za združitev izberite enega ali več predmetov in pritisnite Ctrl+G. Za razdružitev ene ali več skupin jih izberite in pritisnite Ctrl+U. +Tudi skupine lahko združujete med seboj, tako kot ostale predmete. Za takšne rekurzivne skupine ni omejitve v globini, vendar pa bo razdruževanje učinkovalo le na zadnjo raven združevanja, zato boste morali večkrat pritisniti Ctrl+U, da boste do konca razdružili takšno globoko skupino v skupini. + + +Če želite spreminjati predmet znotraj skupine, vam je ni treba +razdruževati. Ctrl+kliknite na predmet, pa ga boste lahko +samostojno preoblikovali, ali pa Shift+Ctrl+clicknite na več +predmetov znotraj ali zunaj katerekoli skupine. Poskusite spreminjati +posamezne like zgoraj desno, ne da bi jih razdružili, nato pa poskusite +spet premakniti skupino. Opazili boste, da je še vedno povezana. + + + + +Polnjenje in obroba + +Mnogo Inkscapovih možnosti je dostopnih preko pogovornih oken. +Najlažji način za pobarvanje predmeta je, da odprete pogovorno okno Paleta v meniju Predmet, izberete željen predmet in kliknete na željeno barvo (tako mu spremenite barvo polnila). + +Več možnosti ponuja pogovorno okno Polnjenje in obroba. (Shift+Ctrl+F). Izberite spodnji lik in odprite pogovorno okno Polnjenje in obroba. + + + +Pogovorno okno ima tri zavihke: Polnilo, Barva črte in Slog črte. V prvem lahko nastavite barvo (notranjost) izbranega lika. Z gumbi pod zavihkom lahko izberete prazno (gumb z X-om), čisto barvo, ravne ali krožne prelive, polnjenje z vzorcem. Za zgornji lik bo izbran gumb za čisto barvo. + +Niže spodaj lahko vidite izbirnik barve - ali natančeje, zbirko raznih izbirnikov, vsakega v svojem zavihku: RGB, HSV, CMYK, Barvni krog. Najbolj udoben je barvni krog, kjer z vrtenjem trikotnika določite odtenek, nato pa še motnost tega odtenka. Vsi izbirniki imajo tudi drsnik za motnost predmetov. + +Kadarkoli izberete predmet se izbirnik barve nastavi na njegovo barvo polnila in obrobe (če izberete več predmetov, se nastavi na povprečne barve). Malce se igrajte z naslednjimi primeri ali naredite svojega: + + + +V zavihku za barvo črte lahko odstranite obrobo predmeta ali pa mu +določite barvo in prosojnost: + + + +Zadnji zavihek, Slog črte, vam omogoči nastavitev debeline črte in njene oblike: + + + +Namesto čistih barv lahko za oboje, obris in polnilo uporabite tudi prelive: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Ko preklopite s čistih barv na prelive, nov preliv uporabi prej določeno barvo, ki prehaja od povsem prosojne do povsem čiste. Preklopite na orodje za prelive (Ctrl+F1) in povlecite ročice preliva — vozlišči sta povezani z črto, ki določa smer in dolžino preliva. Ko je ročica preliva izbrana (modro osvetljena) se pogovorno okno Polnilo in obroba nastavi na barvo ročice, namesto na barvo celotnega predmeta. + +Naslednji priročen način določanja barve predmetom je Kapalka (F7). Kliknite z njo kamorkoli in barva pod njo bo določena izbranemu predmetu. (Shift+klik določi barvo obrobe). + + + +Podvojevanje, poravnavanje, razporeditev + +Zelo pogosto dejanje je podvojevanje predmeta (Ctrl+D). Dvojnik se pojavi natanko na mestu izvirnika in je takoj izbran, tako da ga lahko +z miško povlečete proč ali pa ga premaknete s smernimi tipkami. +Poskusite za vajo z dvojniki črnega kvadratka zapolniti vrsto: + + + +Morda dvojniki niso natančno poravnani. Zato pride prav pogovorno okno +Poravnava (Ctrl+Shift+A). Izberite vse kvadratke (Shift+click ali elastika), odprite pogovorno okno in pritisnite na ustrezen gumb v zavihku Porazdeli. Tu je še nekaj primerov poravnave: + + + + + + + + + + + + + + + + + + + + + + + + + + + +Prekrivanje + +Pojem prekrivanje pomeni zaporedje zlaganja predmetov v risbi, t.j. +kateri predmeti so nad drugimi. V meniju Predmet imate ukaze Dvigni na vrh (tipka Home), Spusti na dno (tipka End), ki izbrani predmet premakneta čez ali pod vse ostale. Druga dva ukaza sta še Dvigni (PgUp) in Spusti (PgDn), ki taisto naredita le za eno raven. Če noben predmet ne prekriva izbranega predmeta, bosta tudi ta dva ukaza predmet poslala do konca. + +Vadite te ukaze tako, da popolnoma spremenite urejenost spodnjih predmetov - naj bo skrajno leva elipsa na vrhu in skrajno desna na dnu: + + + +Zelo uporabna bližnjica je tabulator. Če ni izbran noben predmet, Tab izbere najnižji predmet v dokumentu, sicer pa naslednjega nad izbranim. Shift+Tab deluje v nasprotno smer, začenši z najvišjim in navzdol. Ker se novoustvarjeni predmeti pojavijo na vrhu, bo Shift+Tab izbral ravno zadnji ustvarjeni predmet. Vadite uporabo tabulatorja na zgornjem kupčku elips. + + + +Izbiranje pod in premikanje izbire + +------------------------------------ + +Kaj pa če je predmet, ki ga potrebujete, skrit za drugimi predmeti? Še vedno ga lahko vidite, če so zgornji predmeti (delno) prosojni, klik nanje pa bo vendarle izbral zgornji predmet, ne pa tistega, ki ga želite. + +Zato imamo Alt+klik. Prvi Alt+klik +izbere prvi predmet, tako kot običajni klik. Naslednji Alt+klik pa bo obenem izbral še predmet pod vrhnjim; naslednji klik predmet še nižje... Tako zaporedni Alt+kliki krožijo od vrha do dna, skozi celotno navpično ureditev predmetov na točki klikanja. Ko dosežete najnižji predmet vas naslednji Alt+klik seveda vrne nazaj na vrh. + +Toda kaj lahko počnemo s tako izbranim predmetom? Lahko ga preoblikujemo s tipkovnico in lahko upravljamo z izbiro. Vlečenje predmeta pa bo zopet izbralo najvišji predmet (ker je klikni-in-povleci tako pripravljen). Da bi Inkscapu povedali, naj premika zgolj tisto, kar je trenutno izbrano, uporabite Alt+poteg. S tem boste premaknili trenutno izbrane predele, ne glede na to, kje je miškin kazalec trenutno. + +------------------------------------------- + +Vadite Alt+klik in Alt+poteg na spodnjih dveh rjavih oblikah, pod zelenim prosojnim trikotnikom: + + + + + + + +Zaključek + +Tu zaključujemo Osnovni vodič. Inkscape zmore še veliko več, +kot smo vam pokazali tu, a že zgolj te metode vam omogočajo +ustvarjanje enostavnih, a zato uporabnih risb. Za zahtevnejše reči +si preberite še Napredni vodič pod Pomoč > Vodiči. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/share/tutorials/tutorial-basic.svg b/share/tutorials/tutorial-basic.svg new file mode 100644 index 000000000..9676a4d13 --- /dev/null +++ b/share/tutorials/tutorial-basic.svg @@ -0,0 +1,562 @@ + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ::BASIC + + + + + + + +This tutorial demonstrates the basics of using Inkscape. This is a +regular Inkscape document that you can view, edit, copy from, or save. + + +The Basic Tutorial covers canvas navigation, managing documents, shape tool +basics, selection techniques, transforming objects with selector, grouping, setting fill +and stroke, alignment, and z-order. For more advanced topics, check out the other +tutorials in the Help menu. + + + + + +Panning the canvas + +There are many ways to pan (scroll) the document canvas. Try +Ctrl+arrow keys to scroll by keyboard. (Try this now to scroll this +document down.) You can also drag the canvas by the middle mouse +button. Or, you can use the scrollbars (press Ctrl+B to show or hide +them). The wheel on your mouse also works for scrolling vertically; +press Shift with the wheel to scroll horizontally. + + + +Zooming in or out +The easiest way to zoom is by pressing - and + (or +=) keys. You can also use Ctrl+middle click or +Ctrl+right click to zoom in, Shift+middle click or +Shift+right click to zoom out, or rotate the mouse wheel with +Ctrl. Or, you can click in the zoom entry field (in the bottom left +corner of the document window), type a precise zoom value in %, and press Enter. We also +have the Zoom tool (in the toolbar on left) which lets you to zoom into an area by +dragging around it. + +Inkscape also keeps a history of the zoom levels you've used in this work +session. Press the ` key to go back to the previous zoom, or +Shift+` to go forward. + + + + +Inkscape tools + +The vertical toolbar on the left shows Inkscape's drawing and editing tools. In +the top part of the window, below the menu, there's the Commands +bar with general command buttons and the Tool Controls +bar with controls that are specific to each tool. The status +bar at the bottom of the window will display useful hints and messages as +you work. + +Many operations are available through keyboard shortcuts. Open +Help > Keys and Mouse to see the complete reference. + + + +Creating and managing documents + +To create a new empty document, use File > New or press +Ctrl+N. To open an existing SVG document, use File > +Open (Ctrl+O). To save, use File > Save +(Ctrl+S), or Save As (Shift+Ctrl+S) +to save under a new name. (Inkscape may still be unstable, so remember to save +often!) + +Inkscape uses the SVG (Scalable Vector Graphics) format for its files. SVG is an open standard widely +supported by graphic software. SVG files are based on XML and can be edited with any +text or XML editor (apart from Inkscape, that is). Besides SVG, +Inkscape can import and export several other formats (EPS, PNG). + +Inkscape opens a separate document window for each document. You can navigate +among them using your window manager (e.g. by Alt+Tab), or you can use +the Inkscape shortcut, Ctrl+Tab, which will cycle through all open +document windows. (Create a new document now and switch between it and this document for +practice.) + + + +Creating shapes +Time for some nice shapes! Click on the Rectangle tool in the toolbar +(or press F4) and click-and-drag, either in a new empty document or +right here: + + + +As you can see, default rectangles come up blue, with a black stroke (outline), +and partly transparent. We'll see how to change that below. With other tools, you can +also create ellipses, stars, and spirals: + + + +These tools are collectively known as shape tools. Each shape you +create displays one or more diamond-shaped handles; try dragging +them to see how the shape responds. The Controls panel for a shape +tool is another way to tweak a shape; these controls affect the currently selected +shapes (i.e. those that display the handles) and set the default that +will apply to newly created shapes. + +To undo your last action, press +Ctrl+Z. (Or, if you change your mind again, you can +redo the undone action by Shift+Ctrl+Z.) + + + + +Moving, scaling, rotating The most frequently used Inkscape tool is +the Selector. Click the topmost button (with the arrow) on the +toolbar, or press F1 or Space. Now you can select +any object on the canvas. Click on the rectangle below. + + + +You will see eight arrow-shaped handles appear around the object. +Now you can: + + +Move the object by dragging it. (Press Ctrl to restrict movement +to horizontal and vertical.) + + +Scale the object by dragging any handle. (Press Ctrl to preserve +the original height/width ratio.) + + + +Now click the rectangle again. The handles change. Now you can: + + + +Rotate the object by dragging corner handles. (Press Ctrl to +restrict rotation to 15 degree steps. Drag the cross mark to +position the center of rotation.) + + +Skew (shear) the object by dragging non-corner +handles. (Press Ctrl to restrict skewing to 15 degree +steps.) + + +While in Selector, you can also use the numeric entry fields in the Controls bar +(above the canvas) to set exact values for coordinates (X and Y) and size (W and H) of +the selection. + + + +Transforming by keys + +One of Inkscape's features that set it apart from most other vector editors is its +emphasis on keyboard accessibility. There's hardly any command or action that is +impossible to do from keyboard, and transforming objects is no exception. + +You can use the keyboard to move (arrow keys), scale +(< and > keys), and rotate ([ +and ] keys) objects. Default moves and scales are by 2 px; with +Shift, you move or scale by 10 times that. Ctrl+> +and Ctrl+< scale up or down to 200% or 50% of the original, +respectively. Default rotates are by 15 degrees; with Ctrl, you rotate +by 90 degrees. + +However, perhaps the most useful are pixel-size +transformations, invoked by using Alt with the transform +keys. For example, Alt+arrows will move the selection by 1 pixel +at the current zoom (i.e. by 1 screen pixel, +not to be confused with the px unit which is an SVG length unit independent of +zoom). This means that if you zoom in, one Alt+arrow will result in a +smaller absolute movement which will still look like one-pixel +nudge on your screen. It is thus possible to position objects with arbitrary precision +simply by zooming in or out as needed. + +Similarly, Alt+> and Alt+< +scale selection so that its visible size changes by one screen pixel, and +Alt+[ and Alt+] rotate it so that its +farthest-from-center point moves by one screen pixel. + + + +Multiple selections You can select any number of objects +simultaneously by Shift+clicking them. Or, you can +drag around the objects you need to select; this is called +rubberband selection. (Selector creates rubberband when dragging +from an empty space; however, if you press Shift before starting to +drag, Inkscape will always create the rubberband.) Practice by selecting all three of +the shapes below: + + + +Now, use rubberband (by drag or Shift+drag) to select the two ellipses +but not the rectangle: + + + +Each individual object within a selection displays a selection +cue — by default, a dashed rectangular frame. These cues make it easy +to see at once what is selected and what is not. For example, if you select both the two +ellipses and the rectangle, without the cues you would have hard time guessing whether +the ellipses are selected or not. + +Shift+clicking on a selected object excludes it from the selection. +Select all three objects above, then use Shift+click to exclude both +ellipses from the selection leaving only the rectangle selected. + +Pressing Esc deselects any selected +objects. Ctrl+A selects all objects in the current layer (if you did +not create layers, this is the same as all objects in the document). + + + +Grouping + +Several objects can be combined into a group. A group +behaves as a single object when you drag or transform it. Below, the three objects on +the left are independent; the same three objects on the right are grouped. Try to drag +the group. + + + + + + + +To create a group, you select one or more objects and press +Ctrl+G. To ungroup one or more groups, select them and press +Ctrl+U. Groups themselves may be grouped, just like any other +objects; such recursive groups may go down to arbitrary depth. However, +Ctrl+U only ungroups the topmost level of grouping in a +selection; you'll need to press Ctrl+U repeatedly if you want to +completely ungroup a deep group-in-group. + +You don't necessarily have to ungroup, however, if you want to edit +an object within a group. Just Ctrl+click that object and it will be +selected and editable alone, or Shift+Ctrl+click several objects +(inside or outside any groups) for multiple selection regardless of +grouping. Try to move or transform the individual shapes in the +group (above right) without ungrouping it, then deselect and select +the group normally to see that it still remains grouped. + + + +Fill and stroke + +Many of Inkscape's functions are available via dialogs. Probably the +simplest way to paint an object some color is to open the Swatches dialog from the +Objects menu, select an object, and click a swatch to paint it (change its fill +color). + +More powerful is the Fill and Stroke dialog +(Shift+Ctrl+F). Select the shape below and open the Fill and Stroke +dialog. + + + +You will see that the dialog has three tabs: Fill, Stroke paint, and Stroke +style. The Fill tab lets you edit the fill (interior) of the +selected object(s). Using the buttons just below the tab, you can select types of fill, +including no fill (the button with the X), flat color fill, as well as linear or radial +gradients. For the above shape, the flat fill button will be activated. + +Further below, you see a collection of color pickers, each +in its own tab: RGB, CMYK, HSL, and Wheel. Perhaps the most convenient is the Wheel +picker, where you can rotate the triangle to choose a hue on the wheel, and then select +a shade of that hue within the triangle. All color pickers contain a slider to set the +alpha (opacity) of the selected object(s). + +Whenever you select an object, the color picker is updated to display its current +fill and stroke (for multiple selected objects, the dialog shows their +average color). Play with these samples or create your own: + + + +Using the Stroke paint tab, you can remove the stroke +(outline) of the object, or assign any color or transparency to it: + + + +The last tab, Stroke style, lets you set the width and other parameters +of the stroke: + + + +Finally, instead of flat color, you can use gradients for +fills and/or strokes: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +When you switch from flat color to gradient, the newly created gradient uses the +previous flat color, going from opaque to transparent. Switch to the Gradient tool +(Ctrl+F1) to drag the gradient handles — +the controls connected by lines that define the direction and length of the +gradient. When any of the gradient handles is selected (highlighted blue), the Fill and +Stroke dialog sets the color of that handle instead of the color of the entire selected +object. + +Yet another convenient way to change a color of an object is by using the Dropper +tool (F7). Just click anywhere in the drawing with +that tool, and the picked color will be assigned to the selected object's fill +(Shift+click will assign stroke color). + + + +Duplication, alignment, distribution + +One of the most common operations is duplicating an object +(Ctrl+D). The duplicate is placed exactly above the original and is +selected, so you can drag it away by mouse or by arrow keys. For practice, try to fill +the line with copies of this black square: + + + +Chances are, your copies of the square are placed more or less randomly. This is +where the Align dialog (Ctrl+Shift+A) is useful. Select all the squares +(Shift+click or drag a rubberband), open the dialog and press the +"Center on horizontal axis" button, then the "Make horizontal gaps between objects +equal" button (read the button tooltips). The objects are now neatly aligned and +distributed equispacedly. Here are some other alignment and distribution +examples: + + + + + + + + + + + + + + + + + + + + + + + + + + + +Z-order + +The term z-order refers to the stacking order of objects in a drawing, +i.e. to which objects are on top and obscure others. The two commands in the Object +menu, Raise to Top (the Home key) and Lower to Bottom (the +End key), will move your selected objects to the very top or very +bottom of the current layer's z-order. Two more commands, Raise (PgUp) +and Lower (PgDn), will sink or emerge the selection one step only, +i.e. move it past one non-selected object in z-order (only objects that overlap the +selection count; if nothing overlaps the selection, Raise and Lower move it all the way +to the top or bottom correspondingly). + +Practice using these commands by reversing the z-order of the +objects below, so that the leftmost ellipse is on top and the rightmost +one is at the bottom: + + + +A very useful selection shortcut is the Tab key. If nothing is +selected, it selects the bottommost object; otherwise it selects the object above the +selected object(s) in z-order. Shift+Tab works in reverse, +starting from the topmost object and proceeding downwards. Since the objects you +create are added to the top of the stack, pressing Shift+Tab with +nothing selected will conveniently select the object you created last. Practice +the Tab and Shift+Tab keys on the stack of ellipses +above. + + + +Selecting under and dragging selected + +What to do if the object you need is hidden behind another object? +You may still see the bottom object if the top one is (partially) +transparent, but clicking on it will select the top object, not the +one you need. + +This is what Alt+click is for. First Alt+click +selects the top object just like the regular click. However, the next +Alt+click at the same point will select the object below the top +one; the next one, the object still lower, etc. Thus, several +Alt+clicks in a row will cycle, top-to-bottom, through the entire +z-order stack of objects at the click point. When the bottom object is reached, next +Alt+click will, naturally, again select the topmost object. + +This is nice, but once you selected an under-the-surface object, what can you do +with it? You can use keys to transform it, and you can drag the selection +handles. However, dragging the object itself will reset the selection to the top object +again (this is how click-and-drag is designed to work — it selects the (top) +object under cursor first, then drags the selection). To tell Inkscape to drag what +is selected now without selecting anything else, use Alt+drag. +This will move the current selection no matter where you drag your mouse. + +Practice Alt+click and Alt+drag on the two brown +shapes under the green transparent rectangle: + + + + + + + +Conclusion + +This concludes the Basic tutorial. There's much more than that to Inkscape, but +with the techniques described here, you will already be able to create simple yet useful +graphics. For more complicated stuff, go through the Advanced and other tutorials in +Help > Tutorials. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/share/tutorials/tutorial-calligraphy.es.svg b/share/tutorials/tutorial-calligraphy.es.svg new file mode 100644 index 000000000..14e7e17b4 --- /dev/null +++ b/share/tutorials/tutorial-calligraphy.es.svg @@ -0,0 +1,548 @@ + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ::CALIGRAFÍA + + + + + + + + +Una de las grandes herramientas disponibles en Inkscape es la herramienta de Caligrafía. Este tutorial le ayudará a conocer como trabaja la herramienta, o mejor aú demostrar alguna técnicas básicas del arte de la Caligrafía. + + + + +Historia y éstilos + +Dirigiéndonos a la definición del diccionario, caligrafía significa "escritura hermosa" o "escritura elegante o vistoza". Escencialmente, la caligrafí es el arte de hacer escritura a mano de manera hermosa o elegante. Esto puede sonar intimidante, pero con un poco de práctica, cualquiera puede ser un maestro en las bases de este arte. + + +Las primeras formas de caligrafía se remontan a los gráficos rupestres. Después del año 1440 D.C. y antes de la creación de la prensa de impresión, la caligrafía se encontraba en los libros y otras publicaciones que eran realizadas. +Un escriba tenía que realizar a mano cada copia de cada libro o publiciación. La +escritura a mano era realizada con una pluma y tinta hechas sobre vitelas o pergaminos. Los éstilos de letra usados a traés de esos años incluían: Rústico, Carolingio, Letraoscura, etc. Hoy en día el uso más común de la caligrafía son las invitaciones a bodas. + + +Existen tres tipos principales de caligrafía: + + + +Occidental o Roman + +Arabiga + +China u Oriental + + + +Este tutorial se enfoca fundamentalmente en la caligrafía Occidental, como los otros dos éstilos tienden al uso de la brocha (En vez de un esfero con mina), lo cual no se relaciona al funcionamiento actual de nuestra herramienta de Caligrafía. + + +Una de las grandes ventajas que tenemos sobre los escribas del pasado, es el comando +Deshacer: Si usted comete un error, no se daña toda la página . La herramienta Caligrafía de Inkscape permite algunas otras técnicas que no serían posibles con una pluma y tinta tradicional. + + + + +Hardware + +Obtendráa unos mejores resultados si usa una tableta y lápiz +(eje. Wacom). Sin embargo, por medio del ratón usted puede hacer algunos trazos caligráficos iniciales, piense que tendrá dificultad para producir trazos rápidos. + + +Inkscape no usa aún sensibilidad de presión de un lápiz de tabla, pero esto no es un problema, por que una pluma de caligrafía tradicional (diferente a una brocha) también no es muy sensible a la presión. La +pluma caligráfica de Inkscape puede ser sensible a la velocidad del +trazo (Observe "Adelgazar" más adelante), entonces si usa el ratón, probablemente deseará en ver este parámetro. + + + + +Opciones de la Herramienta de Caligrafía + +Cambie a la herramienta de caligrafía presionando Ctrl+F6 o dando click en su botón en la barra de herramientas. Sobre la barra de herramientas en la parte superior, podrá observar que hay 6 opciones: Ancho & Adelgazar; ángulo & Fijación; y Masa & Resistencia. + + + + + + + + + + + + + + + + 1.00 + + + + + + + + + Drag: + + 0.02 + + + + + + + + + Mass: + + 0.90 + + + + + + + + + Fixation: + + 30 + + + + + + + + + Angle: + + 0.10 + + + + + + + + + Thinning: + + 0.15 + + + + + + + + + Width: + + + Defaults + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Ancho & Adelgazar + +Este par de opciones controlan el ancho de la pluma. El ancho puede variar de 0 a 1 y es medido en unidades relativas al tamaño de su ventana de edición +pero independiente al zoom. Esto tiene sentido, por que la "unidad natural de medida" en la caligrafía es el rango del movimiento de su mano y esto es por lo tanto conveniente para tener el ancho de la punta de su pluma en un radio constante al tamaño de su "espacio de dibujo" y no en alguna unidad real la cual podría depender del zoom. + + +Desde que el ancho de la pluma sea cambiado a menudo, usted puede ajustarlo sin ir a la barra de herramientas, usando las teclas de flechas izquierda y derecha. Lo mejor de estas teclas es que trabajan de esta forma sólo mientras dibuja, así que puede cambiar el ancho de su pluma gradualmente en medio del trazo: + + +width=0.01, growing.... reaching 0.47, decreasing... back to 0 + +El ancho de la pluma puede depender de la velocidad, así siendo controlado mediante el parámetro adelgazar. Este parámetro puede tomar valores entre -1 y 1; cero significa que el ancho es independiente a la velocidad, valores positivos hacen los trazos rápidos más delgados , valores negativos hacen los trazos rápidos más amplios. El valor 0.1, por defecto significa adelgazamiento moderado de trazos rápidos. He aquí algunos pocos ejemplos, todos dibujados con ancho=0.2 y ángulo=90: + + +thinning = 0 (uniform width) thinning = 0.1thinning = 0.4thinning = -0.2thinning = -0.6 + +Para divertirse, configure Ancho y Adelgazar, ambos en 1 (máximo) y dibuje con movimientos accidentados para obtener naturalidad estratégicamente, como formas neuróticas: + + + + + + + +ángulo & Fijación + +Despué del Ancho, el ángulo es el parámetro caligráfico más importante. Este se refiere al ángulo de su pluma en grados, cambiando desde 0 (horizontal) hasta 90 (vértical en sentido anti-horario) o hasta -90 (vértical en sentido horario) : + + + + + + + + + + angle = 90 degangle = 30 (default)angle = 0angle = -90 deg + + + + + + + + + +Cada éstilo de caligrafía tradicional tiene su propio ángulo prevalente de pluma. Por ejemplo, el éstilo Unicial usa un ángulo de 25 grados. éstilos más complejos y experimentados pueden variar a menudo el ángulo, mientras dibuja e Inkscape hace esto posible mediante las teclas de flechas arriba y abajo, para lecciones de caligrafía para principiantes, sin embargo, manteniendo el ángulo constante trabajará mejor. He aquí ejemplos de dibujo de trazos de diferentes ángulos (con fijación = 1): + + +angle = 30angle = 60angle = 90angle = 0angle = 15angle = -45 + +Como podemos observar, el trazo es más delgado cuando es dibujado paralelo a su ángulo y es más amplio cuando se dibuja perpendicular a este. ángulos posítivos son más naturales y tradicionales para caligrafía con dibujo hecho con mano derecha . + + +El nivel de contraste entre el adelgazado y densidad, es controlada mediante el parámetro fijación. El valor 1 significa que el ángulo es siempre constante a como es configurado en el campo de ángulo. Disminuyendo la fijación le permite a la pluma girar un poco en contra de la dirección del trazo. Con fijación=0, la pluma rota libremente para ser siempre perpendicular al trazo y el ángulo no tiene más efecto: + + + + + + + angle = 30fixation = 1angle = 30fixation = 0.8angle = 30fixation = 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Hablando tipográficamente, la fijación máxima y por consiguiente el contraste del ancho máximo del trazo son las características (más adelante) de las fuentes antique serif, como las Times o Bodoni (por que estas fuentes son históricamente una imitación de la caligrafí de la pluma-arreglada). La fijación Cero y el ancho de contraste Cero (Arriba a la derecha), sobre la otra mano, sugiere la fuente actual Sans Serif, así como la Helvetica. + + + + + +Masa & Resistencia + +Diferente al ancho y al ángulo, estos dos últimos parámetros definen como "siente" la herramienta, más allá de como afectan su salida visual. A razón de esto en esta sección no habrán ilustraciones; en vez de esto intente usted mismo para poder tener una mejor idea de lo que hacen estos parámetros. + + +En física, la masa es la cusante de la inercia; A mayor masa de la herramienta de caligrafía de Inkscape, el trazo del contorno hecho a partir del ratón se retrazará más y realiza un mayor alisado de giros y tirones. Por defecto este valor es muy pequeóo (0.02) así que la herramienta es rápida y sensible, pero es posible incrementar la masa para obtener una pluma más lenta y alisada. + + +La Resistenacia es la resistencia del papel a los movimientos de la pluma. Por defecto está al máximo (1), y a medida que dismuniye el papel se hace más "deslizable": si la masa es grande, la pluma tiende a perderse en los giros de las curvas; si la masa es cero, la baja resisencia hace mover violentamente la pluma. + + + + +Ejemplos de caligrafía + +Ahora que ya posee las capacidades básicas de la herramienta, puede intentar producir algunas caligrafís reales. Si es usted nuevo en este arte, adquiera un buen libro de caligrafía y estudielo junto con el Inkscape. Esta sección le mostrará unos pocos ejemplos. + + +Primero que todo, para hacer letras, requiere crear un par de reglas para guiarse. Si usted va a escribir con éstilo inclinado o cursiva, agregue algunas guías inclinadas a través de las dos reglas, por ejemplo: + + + + +Entonces haga zoom de tal manera que la longitud entre las reglas corresponda al rango natural de su escritura, ajuste el ancho y el ángulo, y ¡aquí vamos! + + +Probablemente lo primero que puede hacer siendo un principiante es practicar los elementos básicos de las letras — barras horizontales y vérticales; contornos redondos, barras inclinadas. He aquí algunos elementos de las letras del éstilo Unicial. + + + + +Algunos trucos interesantes: + + + +Si siente comodidad sobre la tabla, no la mueva. En vez de eso, acomode la pizarra +(Ctrl+tecla de flecha) con su mano izquierda después de finalizar cada letra. + +Si su último contorno no está bien, tan sólo deshágalo +(Ctrl+Z). Sin embargo, si una forma es buena pero la posición o el tamaóo no son correctos, es mejor utilizar temporalmente el Selector +(Barra Espaceadora) y perfile/escale/rote de ser necesario (usando el ratón o las teclas), luego presione Barra Espaceadora de nuevo para retornar a la herramienta Caligrafía. + + +Habiendo realizado una palabra, cambie al selector de nuevo para ajustar las barras y espaceado entre letras uniformemente. No exagere con esto, sin embargo; la buena caligrafía debe conservar un éstilo similar. Resista la tentación de copiar letras y sus elementos; cada contorno debe ser original. + + + +Y aquí podemos observar alguno ejemplos completos: + + +Unicial handCarolingian handGothic handBâtarde handFlourished Italic hand + + + + + + +Conclusión + +La caligrafía no es sólo divertida; es además un arte espiritual que puede transformar su visión sobre todo lo que hace y puede ver. La herramienta de caligrafía de Inkscape puede servirle como una modesta introducción para este arte. Y aún +es muy divertido jugar jugar con ella y puede ser muy útil en el diseño real. ¡Disfrutela! + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/share/tutorials/tutorial-calligraphy.fr.svg b/share/tutorials/tutorial-calligraphy.fr.svg new file mode 100644 index 000000000..b7355aa66 --- /dev/null +++ b/share/tutorials/tutorial-calligraphy.fr.svg @@ -0,0 +1,480 @@ + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ::CALLIGRAPHIE + + + + + + + + + +Un des nombreux outils d'Inkscape est l'outil calligraphie. Ce didacticiel vous aidera à découvrir le fonctionnement de cet outil, ainsi que les bases et techniques de l'art de la calligraphie. + + + + +Histoire et styles + +Par définition, la calligraphie signifie "belle écriture" ou "faculté d'écrire élégamment". La calligraphie est essentiellement l'art de former à la main de beaux caractères d'écriture. Cela peut sembler intimidant, mais avec un peu de pratique, n'importe qui peut maîtriser les bases de cet art. + + +Les premières formes de calligraphie apparaissent avec les peintures des hommes des cavernes. Et jusqu'à l'apparition de l'imprimerie, en 1440 environ, les livres et autres publications étaient calligraphiés. Un scribe devait transcrire à la main toute copie de livre ou publication. L'écriture se faisait avec une plume (d'oie) et de l'encre sur des matériaux tels que du parchemin ou du vélin. Les styles de lettrage utilisés au cours des âges incluent le Rustique, la minuscule Caroline, le Blackletter, etc. Les endroits les plus courants pour trouver des calligraphies aujourd'hui sont peut-être les faire-part de mariage. + + +Il existe trois principales familles de calligraphie : + + + + +Occidentale ou romane + + + + +Arabe + + + + +Chinoise ou orientale + + + + +Ce didacticiel se focalise principalement sur la calligraphie occidentale, étant donné que les deux autres styles nécessitent généralement un pinceau (au lieu d'une plume), qui ne fait pas encore partie des fonctions de notre outil de calligraphie + + +Un des grands avantages que nous avons sur les scribes du passé est la commande annuler. Si vous faites une erreur, la page entière n'est pas perdue. L'outil calligraphie d'Inkscape permet aussi des techniques qui ne seraient pas possible avec les plumes et encres traditionnelles. + + + + + +Matériel + +Vous obtiendrez de meilleurs résultats si vous utilisez une tablette graphique (ex. : une Wacom) avec un stylet. Mais vous pouvez obtenir des résultats décents avec une souris aussi, même s'il vous sera plus difficile de produire des tracés rapides réguliers. + + +Inkscape ne gère pas encore la sensibilité à la pression des tablettes graphiques, mais ce n'est pas un problème car les plumes traditionnelles (contrairement aux pinceaux) ne sont pas non plus très sensibles à la pression. La plume calligraphique d'Inkscape est par contre sensible à la vélocité du tracé (voir "Mincissement" plus bas), donc si vous utilisez une souris, vous préférez sans doute mettre ce paramètre à zéro. + + + + + +Options de l'outil Calligraphie + +Passez à l'outil calligraphie en appuyant sur Ctrl+F6 ou en cliquant sur son bouton dans la barre d'outils. Vous remarquerez alors 6 options dans la barre de contrôle : largeur & mincissement; angle & fixité; et masse & frottement. + + +1.00 + + + + + + Frottement :0.02 + + + + + + Masse :0.90 + + + + + + Fixité :30 + + + + + + Angle :0.10 + + + + + + Mincissement :0.15 + + + + + + Largeur :RAZ + + + + +Largeur et Mincissement + +Cette paire d'options contrôle la largeur de votre plume. La largeur peut varier entre 0 et 1 et est mesurée selon une unité relative à la taille de votre fenêtre d'édition, mais indépendante du zoom. Ceci prend son sens du fait que l'"unité de mesure" naturelle en calligraphie est l'amplitude du mouvement de votre main et il est donc pratique d'avoir votre largeur de plume en rapport constant par rapport à votre "plan d'écriture" et non pas en unités réelles, ce qui la ferait dépendre du zoom. + + +Comme la largeur de plume varie souvent, vous pouvez l'ajuster sans devoir utiliser la barre de contrôle, en utilisant les flèches gauche et droite. L'avantage de ces raccourcis est qu'ils fonctionnent même pendant que vous dessinez, de sorte que vous pouvez faire varier la largeur de votre plume progressivement pendant un tracé : + + +largeur=0.01, augmentant.... atteignant 0.47, diminuant... de nouveau à 0 + +La largeur de la plume peut aussi dépendre de la vélocité, et ceci est contrôlé par le paramètre mincissement. Ce paramètre peut prendre une valeur entre -1 et 1; zéro signifie que la largeur est indépendante de la vélocité, des valeurs positives font que des tracés plus rapides sont plus fins, des valeurs négatives font que des tracés plus rapides deviennent plus épais. La valeur par défaut de 0.1 implique un mincissement modéré des tracés rapides. Voici quelques exemples, tous tracés avec une largeur de 0.2 et un angle de 90° : + + +mincissement = 0 (largeur uniforme) mincissement = 0.1mincissement = 0.4mincissement = -0.2mincissement = -0.6 + +Pour vous amuser, donnez une valeur de 1 (maximale) à la largeur et au mincissement puis dessinez avec des mouvements brusques pour obtenir des formes étrangement naturelles, ressemblant à des neurones. + + + + + + + +Angle et Fixité + +Après la largeur, l'angle est le paramètre calligraphique le plus important. Il s'agit de l'angle de votre plume en degrés, allant de 0° (épaisseur de la plume à l'horizontale) à 90° (verticale en sens anti-horaire) ou -90° (verticale en sens horaire) : + + + + + + + + + + angle = 90°angle = 30° (par défaut)angle = 0°angle = -90° + + + + + + + + + +Chaque style de calligraphie traditionnelle possède son propre angle prédominant. Par exemple, l'écriture Unicial nécessite un angle de 25 degrés. Des styles plus complexes et des calligraphes plus expérimentés demanderont une variation de cet angle pendant un tracé, et Inkscape authorise ceci par l'appui sur les flèches haut et bas. Pour les débutants cependant, garder un angle constant sera plus approprié. Voici des exemples de tracés dessinés selon différents angles (fixité = 1) : + + +angle = 30°angle = 60°angle = 90°angle = 0°angle = 15°angle = -45° + +Comme vous pouvez le voir, le tracé est plus fin quand il est parallèle à l'angle, et plus épais quand il est perpendiculaire. Des angles positifs sont plus naturels et traditionnels pour une calligraphie tracée de la main droite. + + +Le niveau de contraste entre l'épaisseur et la finesse maximales est contrôlé par le paramètre fixité. Une valeur de 1 signifie que l'angle est toujours constant, égal à la valeur définie dans le champ angle. Diminuer la fixité permet à la plume de tourner légèrement dans la direction opposée au tracé. Avec fixité=0, la plume tourne librement pour être toujours perpendiculaire au tracé, et la valeur angle n'a plus d'effet : + + + + + + + angle = 30fixité = 1angle = 30fixité = 0.8angle = 30fixité = 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Typographiquement parlant, une fixité maximum et donc un contraste maximum de largeur de tracé (ci-dessus à gauche) sont les caractéristiques des antiques fontes serif, comme les Times ou Bodoni (parce que ces fontes étaient historiquement une imitation d'une calligraphie effectuée avec une plume orientée de façon fixe). De l'autre côté, une fixité nulle et donc un contraste de largeur nul (ci-dessus à droite) font plutôt penser à une fonte sans serif moderne, comme l'Helvetica. + + + + + +Masse et Frottement + +Contrairement à la largeur et à l'angle, ces deux dernier paramètres caractérisent "l'impression" laissée par l'outil plutôt que la façon dont il affecte le rendu visuel. Il n'y aura donc pas d'illustration dans cette section; à la place, essayez simplement par vous-même pour vous en faire une idée. + + +En physique, la masse est ce qui génère l'inertie; plus la masse de l'outil calligraphie d'Inkscape est importante, et plus celui-ci traîne derrière votre stylet (ou pointeur de souris) et lisse les changements de direction et mouvements brusques de votre tracé. Par défaut cette valeur est assez faible (0.02) de façon à ce que l'outil soit rapide et réactif, mais vous pouvez augmenter la masse pour obtenir une plume plus lente et douce. + + +Le frottement est la résistance du papier au mouvement de la plume. La valeur par défaut est au maximum (1), et diminuer ce paramètre rendra le papier glissant : si la masse est grande, la plume a tendance à partir dans des changements de directions brusques; si la masse est nulle, un frottement faible provoquera des tortillements incontrôlables de la plume. + + + + + +Exemples de calligraphies + +Maintenant que vous connaissez les possibilités de base de l'outil, vous pouvez essayer de produire de vraies calligraphies. Si vous êtes débutant dans cette discipline, procurez-vous un bon livre sur la calligraphie et étudiez-le avec Inkscape. Cette section vous montrera juste quelques exemples simples. + + +Tout d'abord pour tracer des lettres, vous avez besoin d'une paire de règles pour vous guider. Si vous devez avoir une écriture inclinée ou cursive, ajoutez aussi des guides inclinés en travers des deux règles horizontales. Par exemple : + + + + +Ensuite le zoom devra être réglé de telle sorte que la hauteur entre les règles corresponde à votre amplitude naturelle de mouvement de main. Ajustez les paramètres largeur et angle, et c'est parti ! + + +La première chose que vous devriez probablement faire en tant que calligraphe débutant est de vous entraîner à dessiner les éléments de base des lettres — des traits horizontaux et verticaux, des tracés ronds et des traits inclinés. Voici quelques éléments de lettres pour l'écriture Unicial : + + + + +Plusieurs astuces utiles : + + + + +Si votre main est confortablement installée sur la tablette, ne la déplacez pas. Faites plutôt défiler le canevas (touches Ctrl+flèche) avec votre main gauche après avoir fini chaque lettre. + + + + +Si votre dernier coup de plume est mauvais, annulez le (Ctrl+Z). Cependant, si sa forme est bonne, mais que la position et la taille doivent être légèrement rectifiées, il vaut mieux utiliser le sélecteur temporairement (espace) et opérer les déplacement/redimensionnement/rotation nécessaires (en utilisant la souris ou le clavier), puis appuyer sur espace de nouveau pour revenir à l'outil calligraphie. + + + + +Quand vous avez fini un mot, passez au sélecteur de nouveau pour ajuster l'uniformité des traits et l'inter-lettrage. N'en faites pas trop cependant; une belle calligraphie doit garder le côté légèrement irrégulier d'une écriture manuscrite; chaque coup de plume doit être original. + + + + +Et voici quelques exemples de lettrages complets + + +Ecriture UnicialEcriture carolingienne (minuscule Caroline)Ecriture GothiqueEcriture bâtardeEcriture italique florissante + + + + +Conclusion + +La calligraphie n'est pas seulement amusante; c'est un art profondément spirituel qui peut changer votre approche quant à ce que vous voyez et faites. L'outil calligraphie d'Inkscape ne peut servir que d'introduction modeste. Mais il est agréable d'utilisation et peut être utile pour des travaux concrets. Faites-vous plaisir ! + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/share/tutorials/tutorial-calligraphy.sl.svg b/share/tutorials/tutorial-calligraphy.sl.svg new file mode 100644 index 000000000..10f507ab0 --- /dev/null +++ b/share/tutorials/tutorial-calligraphy.sl.svg @@ -0,0 +1,627 @@ + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ::KALIGRAFIJA + + + + + + + +Eno od mnogih imenitnih Inkscapovih orodij je kaligrafsko orodje. +Ta vodič vam bo pomagal pri spoznavanju z njegovimi funkcijami, ter vas uvedel +v osnove in tehnike kaligrafije. + + + + +Zgodovina in stili + +Po definiciji je kaligrafija "pisanje z lepimi, +čitljivimi črkami" oziroma "lepopisje". V splošnem pa lahko rečemo, da je kaligrafija +veščina lepega in elegantnega pisanja. To se morda sliši zahtevno, vendar lahko prav +vsak z nekaj vaje zaobvlada osnove te umetnosti. + + +Zgodnje oblike kaligrafije segajo v čas jamskega slikarstva in vse do +iznajdbe tiska (približno 1440 n.št.) je bila kaligrafija edini način, s +katerim so bile narejene knjige in druge publikacije. Vsak posamezen +izvod je moral pisar s peresom in črnilom ročno prenesti na pergament. +Pisali so v rustiki, karolinški minuskuli, gotici, itd. +Dandanes se kaligrafija v glavnem uporablja le še na raznih vabilih, +npr. vabilu na poroko. + + +Obstajajo trije glavni stili kaligrafije: + + + +zahodni oz. romanski + +arabski + +kitajski oz. orientalski + + + +Ta vodič se v glavnem osredotoča na zahodno kaligrafijo in le bežno +preleti druga dva stila, ki se, namesto k uporabi peresa, nagibata k +uporabi čopiča, česar pa naše orodje trenutno ne omogoča. + + +Pred pisarskimi mojstri iz preteklosti nam Scribus nudi eno veliko prednost: ukaz +Razveljavi; če naredite napako, vam to ne uniči večih ur dela. +Kaligrafsko orodje v Inkscapu prav tako omogoča nekatere tehnike, ki bi s +tradicionalnim peresom in črnilom ne bile mogoče. + + + + +Strojna oprema + +Najboljše rezultate boste dosegli z uporabo +grafične tablice in peresa (npr. Wacom). +Spodobno kaligrafijo boste ustvarili tudi z miško, vendar +boste imeli težave pri ustvarjanju hitrih krožnih potez. + + +Inkscape še ne uporablja občutljivosti na pritisk, ki jo omogočajo +nekatere grafične tablice, vendar to ni težava, saj je tradicionalno +kaligrafsko pero (v nasprotju s čopičem) skoraj neobčutljivo na pritisk. +Inkscapovo kaligrafsko pero je lahko občutljivo na hitrost poteze +(glejte Tanjšanje spodaj), zaradi česar boste ob uporabi miške ta +parameter verjetno želeli zmanjšati na 0. + + + + +Kaligrafsko orodje - opcije + +Na kaligrafsko orodje preklopite s kombinacijo tipk Ctrl+F6 ali s klikom +na gumb v navpični orodjarni. Na vodoravni orodni vrstici boste opazili 6 možnosti: +Širina, Tanjšanje, Kot, Stalnost, Masa in Upor. + + + + + + + + + + + + + + + + 1.00 + + + + + + + + + Drag: + + 0.02 + + + + + + + + + Mass: + + 0.90 + + + + + + + + + Fixation: + + 30 + + + + + + + + + Angle: + + 0.10 + + + + + + + + + Thinning: + + 0.15 + + + + + + + + + Width: + + + Defaults + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Širina & tanjšanje + +Ti dve možnosti nadzirata širino vašega peresa. Širina lahko variira +od 0 do 1 in se meri v enotah, ki so relativne glede na velikost vašega +delovnega okna, vendar neodvisne od povečave. Ker je v kaligrafiji +naravna "merska enota" obseg premika roke, je smiselno in pripravno +imeti širino peresa v konstantnem razmerju do velikosti vaše "risarske +deske" in ne v kaki realni enoti, ki bi bila odvisna od povečave. + + +Ker se širino peresa pogosto spreminja, jo lahko spremenite brez +uporabe orodne vrstice in sicer z uporabo desne in leve smerne tipke. +Najboljše pri teh tipkah je, da delujejo med samim risanje, kar pomeni, +da lahko širino peresa spreminjate postopno, med vlečenjem poteze: + + +width=0.01, growing.... reaching 0.47, decreasing... back to 0 + +Širina peresa pa je, glede na parameter tanjšanja, lahko odvisna tudi od +hitrosti. Ta parameter lahko zavzame vrednosti od -1 do 1, pri čemer +vrednost 0 pomeni, da je širina neodvisna od hitrosti, pozitivne vrednosti +naredijo hitrejše poteze ožje, negativne vrednosti pa naredijo hitrejše +poteze širše. Privzeta vrednost 0,1 pomeni tanjšanje hitrih potez. Tu je +nekaj primerov, pri vseh je širina = 0,2 in kot = 90 stopinj: + + +thinning = 0 (uniform width) thinning = 0.1thinning = 0.4thinning = -0.2thinning = -0.6 + +Za zabavo nastavite širino in tanjšanje na 1 (maksimum) in rišite s +sunkovitimi potezami, s čimer boste dobili presenetljivo naturalistične, +nevronske oblike: + + + + + + + +Kot & stalnost + +Za širino peresa je drugi najpomembnejši kaligrafski parameter kot, ki +predstavlja kot peresa in zavzema vrednosti od 0 (vodoraven) do 90 +(navpičen v obratni smeri urinega kazalca) ali do -90 (navpičen v +smeri urinega kazalca): + + + + + + + + + + angle = 90 degangle = 30 (default)angle = 0angle = -90 deg + + + + + + + + + +Vsaka tradicionalna kaligrafska pisava ima svoj prevladujoč kot peresa. +Tako na primer Uniciala uporablja kot 25 stopnj. Bolj kompleksne pisave +in bolj izkušeni kaligrafi pogosto spreminjajo kot med risanjem, kar +Inkscape omogoča s pritiski na smerni tipki gor in dol. Vendar pa je za +začetek kaligrafske lekcije najbolj primerna uporaba konstantnega kota. +Nekaj primerov potez, narisanih pod različnimi koti (stalnost = 1): + + +angle = 30angle = 60angle = 90angle = 0angle = 15angle = -45 + +Kot lahko vidite, je poteza najtanjša, ko je risana vzporedno s svojim +kotom, in najdebelejša, ko je risana pravokotno nanj. Za desničarje so +pozitivni koti najbolj naravni in zato tudi najbolj običajni. + + +Stopnjo kontrasta med najtanjšim in najdebelejšim delom določa +parameter Stalnosti. Vrednost 1 pomeni, da je kot vedno konstanten +in enak vrednosti, določeni v polju Kot. Zmanjševanje stalnosti +omogoči majhno rotacijo peresa proti smeri poteze. S stalnostjo 0 se +pero svobodno obrača in je vedno pravokotno na potezo, zaradi česar +kot nima nobenega učinka več: + + + + + + + angle = 30fixation = 1angle = 30fixation = 0.8angle = 30fixation = 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Tipografsko gledano sta največja stalnost in največji kontrast širine +poteze (zgoraj levo) značilnosti antičnih tipografij s serifi (npr. Times +ali Bodoni, ki sta že historično imitaciji kaligrafije s peresom). +Stalnost = 0 in ničelni kontrast širine (zgoraj desno) pa je značilnost +modernih tipografij brez serifov (npr. Helvetica). + + + + +Masa & upor + +Zadnja dva parametra, za razliko od kota in širine, definirata kako orodje "čuti" +in ne vplivata na njegov vizualni učinek. V tem delu ni nikakršnih +ilustracij; namesto tega maso in upor raje raziščite sami! + + +V fiziki masa povzroči inercijo (vztrajnost); večja Masa Inkscapovega +kaligrafskega orodja povzroči zaostajanje za miškinim kazalcem in bolj +zgladi ostre obrate in hitre sunke v potezi. Privzeta vrednost tega parametra je +precej majhna (0,02), tako da je orodje hitro in občutljivo, lahko pa +maso povečate in dobite počasnejše in bolj gladko pero. + + +Upor je odpor papirja na premikanje peresa. Privzeta vrednost je +največja (1), zniževanje tega parametra pa spreminja papir v bolj +"drsljivega", zato pri veliki masi in nizkem uporu pero zdrsne pri ostrih +obratih; če je masa = 0 in upor nizek, pero na široko vijuga. + + + + +Kaligrafski primeri + +Zdaj, ko poznate osnovne zmožnosti orodja, lahko s kaligrafijo +poizkusite sami. Če ste v tem novi, si priskrbite dobro kaligrafsko +knjigo ter jo predelajte z Inkscapom. Ta del vam bo pokazal nekaj +enostavnih primerov. + + +Na začetku je za pisanje črk potrebno ustvariti nekaj ravnil, po katerih se +boste ravnali. Če boste pisali v poševni pisavi, potrebujete tudi nekaj +poševnih smernic, npr.: + + + + +Nato povečajte platno, da bo višina med ravniloma ustrezala vašemu +najbolj naravnemu obsegu premika roke, prilagodite širino ter kot in… +Ustvarjajte! + + +Verjetno je prva vaja za kaligrafa začetnika risanje osnovnih elementov +črk – navpičnih in vodoravnih črt, okroglih oblik in poševnic. +Tu je nekaj črkovnih elementov za Unicialo: + + + + +Nekaj uporabnih nasvetov: + + + +Če imate roko udobno nameščeno na tablici, je ne premikajte. Namesto +tega z levico premaknite platno po vsaki črki, ki jo napišete (pritisnite +Ctrl+smerne tipke). + + +Če z vašo zadnjo potezo niste zadovoljni, jo razveljavite (pritisnite Ctrl+Z). +Če pa je oblika dobra, vendar odstopata položaj ali velikost, +začasno preklopite na orodje Izberi (pritisnite preslednico) in +premaknite, raztegnite ali zavrtite potezo kolikor je potrebno (z uporabo miške +ali tipk). Za vrnitev na kaligrafsko orodje ponovno pritisnite preslednico. + + +Ko napišete besedo, ponovno preklopite v orodje Izberi in prilagodite +enotnost in razmak med znaki. Vendar pa nikar ne pretiravajte. Dobra +kaligrafija mora do neke mere ohraniti videz ročne pisave. Uprite se +skušnjavi kopiranja črk in črkovnih elementov; vsaka poteza naj bo +originalna! + + + +Nekaj zaključenih črkovnih primerov: + + +Unicial handCarolingian handGothic handBâtarde handFlourished Italic hand + + + + + + +Zaključek + +Kaligrafija ni le zabava, temveč globoko duhovna veščina, ki lahko +spremeni vaš pogled na vse, kar delate in vidite. Inkscapovo +kaligrafsko orodje služi le kot skromno uvajanje v vse to. In čeprav se je +z njim lepo igrati, je lahko uporabno tudi v resničnem oblikovanju. Uživajte! + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/share/tutorials/tutorial-calligraphy.svg b/share/tutorials/tutorial-calligraphy.svg new file mode 100644 index 000000000..d854e87c1 --- /dev/null +++ b/share/tutorials/tutorial-calligraphy.svg @@ -0,0 +1,637 @@ + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ::CALLIGRAPHY + + + +bulia byak, buliabyak@users.sf.net and josh andler, scislac@users.sf.net + + + +One of the many great tools available in Inkscape is the Calligraphy tool. This tutorial +will help you become acquainted with how that tool works, as well as demonstrate some +basic techniques of the art of Calligraphy. + + + + +History and Styles + +Going by the dictionary definition, calligraphy means "beautiful +writing" or "fair or elegant penmanship". Essentially, calligraphy is the art of making +beautiful or elegant handwriting. It may sound intimidating, but with a little practice, +anyone can master the basics of this art. + + +The earliest forms of calligraphy date back to cave-man paintings. Up until roughly 1440 +AD, before the printing press was around, calligraphy was the way books and other +publications were made. A scribe had to handwrite every individual copy of every book or +publication. The handwriting was done with a quill and ink onto materials such as +parchment or vellum. The lettering styles used throughout the ages include Rustic, +Carolingian, Blackletter, etc. Perhaps the most common place where the average person +will run across calligraphy today is on wedding invitations. + + +There are three main styles of calligraphy: + + + +Western or Roman + +Arabic + +Chinese or Oriental + + + +This tutorial focuses mainly on Western calligraphy, as the other two styles tend to use +a brush (instead of a pen with nib), which is not how our Calligraphy tool +currently functions. + + +One great advantage that we have over the scribes of the past is the +Undo command: If you make a mistake, the entire page is not +ruined. Inkscape's Calligraphy tool also enables some techniques which would not be +possible with a traditional pen-and-ink. + + + + +Hardware + +You will get the best results if you use a tablet and pen +(e.g. Wacom). Thanks to the flexibility of our tool, even those with only a mouse can do +some fairly intricate calligraphy, though there will be some difficulty producing fast +sweeping strokes. + + +Inkscape is able to utilize pressure sensitivity and +tilt sensitivity of a tablet pen that supports these features. The sensitivity functions are disabled by +default because they require configuration. Also, keep in mind that calligraphy with a +quill or pen with nib are also not very sensitive to pressure, unlike a brush. + + +If you have a tablet and would like to utilize the sensitivity features, you will need +to configure your device. This configuration will only need to be performed once and +the settings are saved. To enable this support you must have the tablet plugged in +prior to starting inkscape and then proceed to open the Input Devices... +dialog through the File menu. With this dialog open you can choose the +preferred device and settings for your tablet pen. Lastly, after choosing those settings, switch +to the Calligraphy tool and toggle the toolbar buttons for pressure and tilt. From +now on, Inkscape will remember those settings on startup. + + +The Inkscape calligraphy pen can be sensitive to the velocity of +the stroke (see "Thinning" below), so if you are using a mouse, you'll probably want to +zero this parameter. + + + + +Calligraphy Tool Options + +Switch to the Calligraphy tool by pressing Ctrl+F6, pressing the C key, or by clicking on its toolbar button. On the top toolbar, you will +notice there are 6 options: Width & Thinning; Angle & Fixation; and Mass & Drag and two +buttons to toggle tablet Pressure and Tilt sensitivity on and off (for drawing tablets). + + + + + + + + + + + + + + + + 1.00 + + + + + + + + + Drag: + + 0.02 + + + + + + + + + Mass: + + 0.90 + + + + + + + + + Fixation: + + 30 + + + + + + + + + Angle: + + 0.10 + + + + + + + + + Thinning: + + 0.15 + + + + + + + + + Width: + + + Defaults + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Width & Thinning + +This pair of options control the width of your pen. The width can +vary from 0 to 1 and is measured in units relative to the size of your editing window, +but independent of zoom. This makes sense, because the natural "unit of measure" in +calligraphy is the range of your hand's movement, and it is therefore convenient to have +the width of your pen nib in constant ratio to the size of your "drawing board" and not +in some real units which would make it depend on zoom. + + +Since pen width is changed often, you can adjust it without going to +the toolbar, using the left and right arrow keys or with a +tablet that supports the pressure sensitivity function. The best thing about +these keys is that they work while you are drawing, so you can change +the width of your pen gradually in the middle of the stroke: + + +width=0.01, growing.... reaching 0.47, decreasing... back to 0 + +Pen width may also depend on the velocity, as controlled by the +thinning parameter. This parameter can take values from -1 to 1; +zero means the width is independent of velocity, positive values make faster strokes +thinner, negative values make faster strokes broader. The default of 0.1 means moderate +thinning of fast strokes. Here are a few examples, all drawn with width=0.2 and +angle=90: + + +thinning = 0 (uniform width) thinning = 0.1thinning = 0.4thinning = -0.2thinning = -0.6 + +For fun, set Width and Thinning both to 1 (maximum) and draw with +jerky movements to get strangely naturalistic, neuron-like shapes: + + + + + + + +Angle & Fixation + +After width, angle is the most important calligraphy +parameter. It is the angle of your pen in degrees, changing from 0 (horizontal) to +90 (vertical counterclockwise) or to -90 (vertical clockwise). Note that if you +turn tilt sensitivity on for a tablet, the angle parameter is greyed out and +the angle is determined by the tilt of the pen. + + + + + + + + + + angle = 90 degangle = 30 (default)angle = 0angle = -90 deg + + + + + + + + + +Each traditional calligraphy style has its own prevalent pen angle. For example, the +Unicial hand uses the angle of 25 degrees. More complex hands and more experienced +calligraphers will often vary the angle while drawing, and Inkscape makes this possible +by pressing up and down arrow keys or with a tablet that +supports the tilt sensitivity feature. For beginning calligraphy lessons, however, +keeping the angle constant will work best. Here are examples of strokes drawn at +different angles (fixation = 1): + + +angle = 30angle = 60angle = 90angle = 0angle = 15angle = -45 + +As you can see, the stroke is at its thinnest when it is drawn parallel to its angle, +and at its broadest when drawn perpendicular. Positive angles are the most +natural and traditional for right-handed calligraphy. + + +The level of contrast between the thinnest and the thickest is controlled by the +fixation parameter. The value of 1 means that the angle is always +constant, as set in the Angle field. Decreasing fixation lets the pen turn a little +against the direction of the stroke. With fixation=0, pen rotates freely to be always +perpendicular to the stroke, and Angle has no effect anymore: + + + + + + + angle = 30fixation = 1angle = 30fixation = 0.8angle = 30fixation = 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Typographically speaking, maximum fixation and therefore maximum stroke width contrast +(above left) are the features of antique serif typefaces, such as Times or Bodoni +(because these typefaces were historically an imitation of fixed-pen calligraphy). Zero +fixation and zero width contrast (above right), on the other hand, suggest modern sans +serif typefaces such as Helvetica. + + + + +Mass & Drag + +Unlike width and angle, these two last parameters define how the tool "feels" rather +than affect its visual output. So there won't be any illustrations in this section; +instead just try them yourself to get a better idea. + + +In physics, mass is what causes inertia; the higher the mass of +the Inkscape calligraphy tool, the more it lags behind your mouse pointer and the more +it smoothes out sharp turns and quick jerks in your stroke. By default this value is +quite small (0.02) so that the tool is fast and responsive, but you can increase mass to +get slower and smoother pen. + + +Drag is the resistance of the paper to the movement of the +pen. The default is at maximum (1), and lowering this parameter makes paper "slippery": +if the mass is big, the pen tends to run away on sharp turns; if the mass is zero, low +drag makes the pen to wiggle wildly. + + + + +Calligraphy examples + +Now that you know the basic capabilities of the tool, you can try to produce some real +calligraphy. If you are new to this art, get yourself a good calligraphy book and study +it with Inkscape. This section will show you just a few simple examples. + + +First of all, to do letters, you need to create a pair of rulers to guide you. If you're +going to write in a slanted or cursive hand, add some slanted guides across the two +rulers as well, for example: + + + + +Then zoom in so that the height between the rulers corresponds to your most natural hand +movement range, adjust width and angle, and off you go! + + +Probably the first thing you would do as a beginner calligrapher is practice the basic +elements of letters — vertical and horizontal stems, round strokes, slanted +stems. Here are some letter elements for the Unicial hand: + + + + +Several useful tips: + + + +If your hand is comfortable on the tablet, don't move it. Instead, +scroll the canvas (Ctrl+arrow keys) with your left hand after finishing +each letter. + +If your last stroke is bad, just undo it +(Ctrl+Z). However, if its shape is good but the position or size are +slightly off, it's better to switch to Selector temporarily (Space) and +nudge/scale/rotate it as needed (using mouse or keys), then press Space +again to return to Calligraphy tool. + + +Having done a word, switch to Selector again to adjust stem uniformity +and letterspacing. Don't overdo this, however; good calligraphy must retain somewhat +irregular handwritten look. Resist the temptation to copy over letters and letter +elements; each stroke must be original. + + + +And here are some complete lettering examples: + + +Unicial handCarolingian handGothic handBâtarde handFlourished Italic hand + + + + + + +Conclusion + +Calligraphy is not only fun; it's a deeply spiritual art that may +transform your outlook on everything you do and see. Inkscape's +calligraphy tool can only serve as a modest introduction. And yet +it is very nice to play with and may be useful in real design. Enjoy! + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/share/tutorials/tutorial-elements.es.svg b/share/tutorials/tutorial-elements.es.svg new file mode 100644 index 000000000..c6ef622e4 --- /dev/null +++ b/share/tutorials/tutorial-elements.es.svg @@ -0,0 +1,582 @@ + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ::ELEMENTOS + + + + + + +Este tutorial demostrará los principios y elementos del diseño, los cuales son impartidos a estudiantes principiantes de artes, esto para entender varias propiedades usadas en la creación de arte. Esta no es una lista exhaustiva, así que por favor agregue, sustriaga y combine para hacer este tutorial más completo. + + + +ElementsPrinciplesColorLineShapeSpaceTextureValueSizeBalanceContrastEmphasisProportionPatternGradationCompositionOverview + + +Elementos del Diseño +Los siguientes elementos son las bases que costruyen el Diseño. + + +Línea +Una línea es definida como una marca con longitud y dirección, creada mediante un punto que se mueve a lo largo de una superficie. Una línea puede variar en longitud, ancho, dirección, curvatura y color. La línea puede ser de dos dimensiones (una línea de lápiz sobre papel), o tres dimensiones implícitas. + + + + + + + + + + + + + + + + + +Forma +Un fígura plana o una forma es creada cuando líneas actuales o implícitas se encuentran alrededor de un espacio. Un cambio en el color o el sombreado puede definir una forma. +Las formas pueden ser clasificadas en varios tipos: geométricas (cuadrado, triángulo, círculo) y orgánicas (irregulares en contorno). + + + + + + + + + + + +Tamaño +Este se refiere a las variaciones de las proporciones de los objetos, líneas o formas. +Hay una variación de tamaño en objetos ya sean reales o imáginarios. + + +BIGsmall + + + +Espacio +Espacio es el área vacia o abierta entre, alrededor, arriba, debajo o entre objetos. Figuras y formas son realizadas en el espacio alrededor y entre él. El espacio también es llamado bidimensional o tridimensional. El espacio positivo es rellenado con formas o fíguras. El espacio negativo rodea una forma o fígura. + + + + + + +Color +El Color es el caracter percibido de una superficie de acuerdo con la longitud de onda o la luz reflejada desde esta. El Color posee tres dimensiones: TINTE (otra palabra para color, indicada por su nombre así como rojo o amarillo), VALOR (su luminosidad o oscuridad), INTENSIDAD (su brillo u opacidad). + + + + + + + + + + + + + + + + + +Textura +La Textura es la forma como se siente la superficie (textura actual) o como puede ser observada (textura ímplicita). Las Texturas son descritas con palabras como áspero, sedoso o rugoso. + + + + + + + + + + + + + + + + +Valores +El Valor es que tan oscuro o claro se ve algo. Podemos alcanzar cambios de valores en el color por medio de la adición de blanco o negro a dicho color. Claroscuro usa valores en los dibujo mediante contrastes de claros y oscuros en una composición. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Principios de Diseño +Los principios emplean elementos del diseño para crear composiciones. + + +Balance +El Balance es el sentido de equidad visual en una forma, fígura, valor, calor, etc. El Balance puede balancear simétricamente o uniformemente Objetos, valores, colores, texturas, formas, etc., igualmente puede ser usada en la creación de balances en la composición. + + + + + + +Contraste +El contraste es la juxtaposición (fusión) de los elementos opuestos + + + + + +Énfasis +El Énfasis es usado para crear ciertas partes de sus trabajos artísticos a través de llamado atención de manera especial. El centro de interés o punto foco es el lugar del dibujo que le invita a enfocar su mirada. + + + + + + +Proporción +La Proporción describe el tamaño, ubicación o el monto de una cosa comparada con otra. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Random Ant & 4WDSVG Image Created by Andrew FitzsimonCourtesy of Open Clip Art Libraryhttp://www.openclipart.org/ + + + + + + + + + + + + + + + + + + + + + + +Patrones +Los Patrones son creados mediante la repetición de un elemento (línea, forma o color) una y otra vez. + + + + + + + + + + + + + + + +Gradación +La Gradación es el tamaño y dirección producidas por una perspectiva lineal. +La Gradación del color es desde gamas calidas a frías y por su parte los tonos oscuros a claros producen unas perspectiva aérea. La Gradación puede agregar interés y movimiento a una forma. Una Gradación desde oscuro a claro causará que la vitas se transporte a lo largo de la forma. + + + + + + + + + + + + + + + + + + + + + + + + + +Composición +La combinación de distintos elementos para formar un todo. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Bibliografía +Esta es una bibliografía parcial usada para construir este documento. + + + + +http://sanford-artedventures.com/study/study.html + + +http://www.makart.com/resources/artclass/EPlist.html + + +http://www.princetonol.com/groups/iad/Files/elements2.htm + + +http://oswego.org/staff/bpeterso/web/elements_and_principles.htm + + +http://www.johnlovett.com/test.htm + + + +Agradecimientos especiales a Linda Kim (http://www.redlucite.org) por colaborarme +(http://www.rejon.org/) con este tutorial. También, agradecimientos a la Librería Libre de Clip Art (http://www.openclipart.org/) y a los diseñadores gráficos y afines que han colaborado con este proyecto. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/share/tutorials/tutorial-elements.fr.svg b/share/tutorials/tutorial-elements.fr.svg new file mode 100644 index 000000000..3559c9b20 --- /dev/null +++ b/share/tutorials/tutorial-elements.fr.svg @@ -0,0 +1,619 @@ + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ::RUDIMENTS DE DESIGN + + + + + +Ce didacticiel s'attache à montrer les éléments et principes de design habituellement enseignés aux étudiants débutants en art afin de comprendre les différentes notions impliquées dans une création. Cette liste n'est pas exhaustive, aussi n'hésitez pas à enrichir (modifier, ajouter, supprimer, combiner des paragraphes) ce didacticiel pour le rendre plus complet. + + + +ElémentsPrincipesCouleurLigneFormeEspaceTextureLuminositéTailleEquilibreContrasteEmphaseProportionMotifGradationCompositionVue d'ensemble + + +Rudiments de design +Les éléments suivant forment les bases de l'élaboration d'un design. + + + + +La ligne + +Une ligne est définie comme une marque avec une longueur et une direction, créée par un point se déplaçant sur une surface. Une ligne peut varier en longueur, largeur, direction, courbure et en couleur. Une ligne peut être bi-dimensionnelle (un trait de crayon sur du papier) ou tri-dimensionnelle. + + + + + + + + + + + + + + + + + + +La forme + +Une forme est créée par la rencontre ou l'intersection de signes entourant un espace. Une variation de couleur ou une ombre peuvent définir une forme. Les formes peuvent être classées en deux catégories : géometriques (un carré, un triangle, un cercle) et organiques (contour irrégulier). + + + + + + + + + + + +La taille + +La taille se réfère aux proportions des objets, lignes ou formes. Les variations de taille entre des objets peuvent être réelles ou imaginaires. + + +BIGsmall + + + +L'espace + +L'espace est l'aire vide (ou ouverte) entre, autour, au-dessus, en-dessous, devant ou dans des objets. Les formes peuvent être définies par l'espace qu'elles contiennent et qui les entoure. L'espace est souvent qualifié de tri- ou bi-dimensionnel. L'espace positif est celui rempli par une forme. L'espace négatif est celui qui entoure une forme. + + + + + + +La couleur + +La couleur est la perception que l'on a d'une surface d'après la longueur d'onde de la lumière qu'elle reflète. La couleur a trois composantes : une Teinte (un autre mot pour couleur, indiquée par des mots comme rouge ou jaune), une Saturation (éclatante ou terne), une Luminosité (claire ou sombre). + + + + + + + + + + + + + + + + + + +La texture + +La texture est associée au toucher (texture réelle) d'une surface ou à la façon dont elle rend visuellement (texture visuelle). Une texture peut être décrite par des qualificatifs tels que rude, soyeuse ou rocailleuse. + + + + + + + + + + + + + + + + + +Luminosité + +La luminosité représente le niveau de clarté ou d'obscurité d'une chose. La modification de luminosité d'une couleur peut être obtenue en y adjoignant du blanc ou du noir. Le clair-obscur se sert de variations de luminosité pour faire contraster dramatiquement des zones claires et sombres dans une composition. Notez que la luminosité est parfois appelée valeur par les peintres. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Principes de design + +Les principes combinent les éléments de design pour produire une composition. + + + + +L'équilibre + +L'équilibre est une impression visuelle de parité dans la forme, la valeur, la couleur... L'équilibre peut être symétrique (équilibré) ou asymétrique (déséquilibré). Les objets, luminosités, couleurs, textures, formes, etc., peuvent être mis à contribution pour créer un équilibre dans la composition. + + + + + + + +Le contraste + +Le contraste est la juxtaposition d'éléments qui s'opposent. + + + + + + +L'emphase + +L'emphase est utilisée pour accentuer certaines parties d'une œuvre et attirer l'attention. Le centre d'intérêt ou le point focal est l'endroit qui attire l'œil en premier. + + + + + + + +La proportion + +La proportion décrit la taille, l'emplacement ou la quantité d'une chose comparativement à une autre. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Random Ant & 4WDSVG Image Created by Andrew FitzsimonCourtesy of Open Clip Art Libraryhttp://www.openclipart.org/ + + + + + + + + + + + + + + + + + + + + + + + +Le motif + +Un motif est créé par la répétition d'un élément (ligne, forme ou couleur) encore et encore. + + + + + + + + + + + + + + + + +Gradation + +Une gradation de taille et de direction produit une perspective linéaire. Une gradation de couleur, chaud vers froid et tonique ou de sombre à clair, produit une perspective aérienne. La gradation peut ajouter de l'intérêt et du mouvement à une forme. Une gradation de l'obscur vers le clair peut guider le regard le long d'une forme. + + + + + + + + + + + + + + + + + + + + + + + + + + +La composition +La disposition de différents éléments pour former un tout. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Bibliographie + +Voici une bibliographie (partielle) utilisée pour la réalisation de ce document : + + + + + +http://sanford-artedventures.com/study/study.html + + + + + +http://www.makart.com/resources/artclass/EPlist.html + + + + + +http://www.princetonol.com/groups/iad/Files/elements2.htm + + + + + +http://oswego.org/staff/bpeterso/web/elements_and_principles.htm + + + + + +http://www.johnlovett.com/test.htm + + + + +Remerciements spéciaux à Linda Kim (http://www.redlucite.org) qui m'a (http://www.rejon.org/) bien aidé sur ce didacticiel. Merci également à l'Open Clip Art Library (http://www.openclipart.org/) et aux gens qui ont soumis des dessins pour ce projet. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/share/tutorials/tutorial-elements.sl.svg b/share/tutorials/tutorial-elements.sl.svg new file mode 100644 index 000000000..6ccc90024 --- /dev/null +++ b/share/tutorials/tutorial-elements.sl.svg @@ -0,0 +1,596 @@ + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ::ELEMENTI + + + + + +V tem vodiču vam bomo predstavili temeljne koncepte in načela oblikovanja, kot jih običajno učijo v začetnih letih študija umetnosti da pokažejo pomen različnih lastnosti oblikovanja. Spisek ne bo popoln, zato ga razširite, povežite in naredite bolj izčrpnega s svojimi lastnimi izkušnjami in znanjem. + + + +ElementsPrinciplesColorLineShapeSpaceTextureValueSizeBalanceContrastEmphasisProportionPatternGradationCompositionOverview + + +Sestavine oblikovanja +Sledeče sestavine so gradniki oblikovanja. + + +Črta +Črta je definirana kot znak z dolžino in smerjo, ustvarjen s točko, ki se +giblje po površini. Črte imajo lahko različne dolžine, debeline, smeri, +krivost, barvo. Črta je lahko dvorazsežna (sled svinčnika na papirju), +trorazsežna (žica) ali namišljena. + + + + + + + + + + + + + + + + +Oblika +Ravna figura oz. oblika nastane, ko se več dejanskih ali namišljenih črt +združi in zajame prostor. Spremeba v barvi ali senci lahko določi obliko. +Poznamo več vrst oblik: geometrijske (kvadrat, trikotnik, krog) in +organske (nepravilnega obrisa). + + + + + + + + + + +Velikost +To se nanaša na raznolikost razmerij predmetov, črt ali oblik. Ta je +lahko resnična ali namišljena. + +BIGsmall + + + +Prostor +Prostor je prazna ali odprta površina med, okrog, nad, pod ali znotraj +predmeta. Oblike ustvarja prostor okrog in znotraj njih. Prostor je +dvo- ali trorazsežen. Pozitiven prostor je zapolnjen z obliko, negativen +jo obkroža. + + + + + +Barva +Barva je zaznana lastnost površine glede na valovno dolžino svetlobe, +ki se od nje odbija. Barva ima tri razsežnosti: Barvnost (drugo ime za +barvo, označen z imenom, kot na primer rdeča ali rumena), Svetlost +(svetlost ali temnost), ter Nasičenost (čistost ali motnost). + + + + + + + + + + + + + + + + +Tekstura +Tekstura izraža, kako občutimo površino (dejanska) ali kako površina +izgleda (namišljena). Označimo jih z besedami, kot so groba, svilena,... + + + + + + + + + + + + + + + +Vrednost +Vrednost pove, kako svetlo ali temno nekaj izgleda. Spreminjanje +vrednosti barve dosežemo z dodajanjem črne ali bele. Tehnika +chiaroscuro pri risanju uporablja barvno vrednost tako, da dramatično +poudarja razlike med svetlimi in temnimi deli kompozicije. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Načela oblikovanja +S temi načeli iz sestavin ustvarimo kompozicijo. + + +Ravnovesje +Ravnovesje je občutje grafične enakomernosti oblike, vrednosti, barve,.. +Ravnovesje je lahko simetrično ali enakomerno urejeno ali pa +asimetrično ali neenakomerno razporejeno. Za ustvarjanje ravnovesja v +kompoziciji lahko uporabljamo predmete, vrednosti, barve, teksture,... + + + + + +Kontrast +Kontrast je postavitev nasprotujočih si sestavin v neko celoto + + + + + +Poudarek +Poudarek uporabimo, če želimo, da nek del izdelka izstopa in privlači +pozornost. Središče zanimanja ali žarišče pogleda je točka, k kateri +izdelek najprej pritegne pogled. + + + + + +Razmerje +Razmerje opisuje velikost, položaj ali količino nečesa v primerjavi z +nečim drugim. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Random Ant & 4WDSVG Image Created by Andrew FitzsimonCourtesy of Open Clip Art Libraryhttp://www.openclipart.org/ + + + + + + + + + + + + + + + + + + + + + + +Vzorec +Vzorec nastane s ponavljanjem sestavine (črte, oblike, barve). + + + + + + + + + + + + + + +Gradacija +Gradacija velikosti in smeri ustvari linerano perspektivo. Gradacija barve +od tople do hladne in tona od temnega do svetlega ustvari zračno +perspektivo. Gradacija lahko obliki doda zanimivost in gibanje. Gradacija +od temne k svetli povzroči gibanje očesa skupaj z obliko. + + + + + + + + + + + + + + + + + + + + + + + + +Kompozicija +Združevanje elementov v zaključeno celoto. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Literatura +Delen seznam literature, ki je bila uporabljena pri pripravi tega dokumenta. + + +http://sanford-artedventures.com/study/study.html + + +http://www.makart.com/resources/artclass/EPlist.html + + +http://www.princetonol.com/groups/iad/Files/elements2.htm + + +http://oswego.org/staff/bpeterso/web/elements_and_principles.htm + + +http://www.johnlovett.com/test.htm + + + +http://digital-web.com/articles/elements_of_design/ + + + +http://digital-web.com/articles/principles_of_design/ + + + + +Posebej se zahvaljujem Lindi Kim (http://www.redlucite.org) za pomoč (http://www.rejon.org/) pri tem vodiču. Prav tako se zahvaljujem Open Clip Art zbirki (http://www.openclipart.org/) in pa ljudem, ki so prispevali grafike za ta projekt. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/share/tutorials/tutorial-elements.svg b/share/tutorials/tutorial-elements.svg new file mode 100755 index 000000000..a4ce5f9a6 --- /dev/null +++ b/share/tutorials/tutorial-elements.svg @@ -0,0 +1,606 @@ + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ::ELEMENTS + + + + + +This tutorial will demonstrate the elements and principles of design which +are normally taught to early art students in order to understand various +properties used in art making. This is not an exhaustive list, so please add, +subtract, and combine to make this tutorial more comprehensive. + + + +ElementsPrinciplesColorLineShapeSpaceTextureValueSizeBalanceContrastEmphasisProportionPatternGradationCompositionOverview + + +Elements of Design +The following elements are the building blocks of design. + + +Line +A line is defined as a mark with length and direction, created by a point +that moves across a surface. A line can vary in length, width, direction, +curvature, and color. Line can be two-dimensional (a pencil line on +paper), or implied three-dimensional. + + + + + + + + + + + + + + + + +Shape +A flat figure, shape is created when actual or implied lines meet to +surround a space. A change in color or shading can define a shape. +Shapes can be divided into several types: geometric (square, triangle, +circle) and organic (irregular in outline). + + + + + + + + + + +Size +This refers to variations in the proportions of objects, lines or shapes. +There is a variation of sizes in objects either real or imagined. + +BIGsmall + + + +Space +Space is the empty or open area between, around, above, below, or +within objects. Shapes and forms are made by the space around and +within them. Space is often called three-dimensional or two- +dimensional. Positive space is filled by a shape or form. Negative +space surrounds a shape or form. + + + + + +Color +Color is the perceived character of a surface according to the +wavelength of light reflected from it. Color has three dimensions: HUE +(another word for color, indicated by its name such as red or yellow), +VALUE (its lightness or darkness), INTENSITY (its brightness or +dullness). + + + + + + + + + + + + + + + + +Texture +Texture is the way a surface feels (actual texture) or how it may look +(implied texture). Textures are described by word such as rough, silky, +or pebbly. + + + + + + + + + + + + + + + +Value +Value is how dark or how light something looks. We achieve value +changes in color by adding black or white to the color. Chiaroscuro +uses value in drawing by dramatically contrasting lights and darks +in a composition. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Principles of Design +The principles use the elements of design to create a composition. + + +Balance +Balance is a feeling of visual equality in shape, form, value, color, etc. +Balance can be symmetrical or evenly balanced or asymmetrical and +un-evenly balanced. Objects, values, colors, textures, shapes, forms, +etc., can be used in creating a balance in a composition. + + + + + +Contrast +Contrast is the juxtaposition of opposing elements + + + + + +Emphasis +Emphasis is used to make certain parts of their artwork stand out +and grab your attention. The center of interest or focal point is the +place a work draws your eye to first. + + + + + +Proportion +Proportion describes the size, location or amount of one thing compared +to another. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Random Ant & 4WDSVG Image Created by Andrew FitzsimonCourtesy of Open Clip Art Libraryhttp://www.openclipart.org/ + + + + + + + + + + + + + + + + + + + + + + +Pattern +Pattern is created by repeating an element (line, shape or color) over +and over again. + + + + + + + + + + + + + + +Gradation +Gradation of size and direction produce linear perspective. Gradation +of color from warm to cool and tone from dark to light produce aerial +perspective. Gradation can add interest and movement to a shape. A +gradation from dark to light will cause the eye to move along a shape. + + + + + + + + + + + + + + + + + + + + + + + + +Composition +The combining of distinct elements to form a whole. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Bibliography +This is a partial bibliography used to build this document. + + +http://sanford-artedventures.com/study/study.html + + +http://www.makart.com/resources/artclass/EPlist.html + + +http://www.princetonol.com/groups/iad/Files/elements2.htm + + +http://oswego.org/staff/bpeterso/web/elements_and_principles.htm + + +http://www.johnlovett.com/test.htm + + + +http://digital-web.com/articles/elements_of_design/ + + + +http://digital-web.com/articles/principles_of_design/ + + + + +Special thanks to Linda Kim (http://www.redlucite.org) for helping +me (http://www.rejon.org/) with this tutorial. Also, thanks to the +Open Clip Art Library (http://www.openclipart.org/) and the graphics +people have submitted to that project. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/share/tutorials/tutorial-shapes.ca.svg b/share/tutorials/tutorial-shapes.ca.svg new file mode 100644 index 000000000..6cde10fe4 --- /dev/null +++ b/share/tutorials/tutorial-shapes.ca.svg @@ -0,0 +1,6689 @@ + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ::FORMES + + + + + + + Aquest tutorial cobreix les quatre eines de forma bàsiques: Rectangle, El·lipse, Estrella i Espiral. Mostrarem les capacitats de les eines de forma de l'Inkscape i exemple de com es poden usar. + + + + + + Useu Ctrl+Fletxes, la rodeta del ratolí, o arrossegueu amb el botó central per a moure avall la pàgina. Per als aspectes bàsics de creació, selecció i transformació d'objectes, veieu el tutorial Bàsic a Ajuda > Tutorials. + + + + + + L'Inkscape té quatre versàtils eines de forma, cadascuna de les quals pot crear i editar el seu propi tipus de formes. Una forma és un objecte que podeu modificar de maneres úniques per a aquest tipus de forma, usant manejadors que es poden arrossegar i paràmetres numèrics que en determinen l'aparença. + + + + + + + Per exemple, en una estrella podeu variar el nombre de puntes, la seva longitud, l'angle, l'arrodoniment, etc. — però una estrella sempre és una estrella. Una forma és "menys lliure" que un simple camí, però sovint és més interessant i útil. Sempre podeu convertir una forma en un camí (Ctrl+Maj+C), però no a l'inrevés. + + + + + + Les eines de forma són Rectangle, El·lipse, Estrella i Espiral. Veiem primer com funcionen les eines de forma en general; després explorarem cada tipus de forma en detall. + + Trucs generals + + + + + + + Es crea una nova forma arrossegant per l'àrea de dibuix amb l'eina corresponent. Un cop creada la forma (i mentres estigui seleccionada), mostra els seus manejadors com unes marques blanques en forma de diamant, de manera que podeu editar immediatament el que heu creat arrossegant aquests manejadors. + + + + + + Els quatre tipus de formes mostren els seus manejadors en les quatre eines de forma així com també en l'eina de Nodes (F2). Quan passeu el ratolí sobre un manejador, us diu a la barra d'estat què farà aquest manejador en arrossegar-lo o clicar-lo amb diferents modificadors. + + + + + + També cada forma mostra els seus paràmetres a la barra de Controls d'Eina (que s'estén horitzontalment damunt de l'àrea de dibuix). Normalment té uns pocs camps d'entrada numèrics i un botó per a restaurar els valors per defecte. Quan se seleccionen les formes del tipus natiu de l'eina actual, l'edició dels valors de la barra de Controls canvia les formes seleccionades. + + + + + + Tots els canvis fets als controls de l'eina són recordats i usats pel següent objecte que dibuixeu amb aquesta eina. Per exemple, després de canviar el nombre de puntes d'una estrella, en dibuixar noves estrelles, aquestes tindran aquest mateix nombre de puntes. A més, encara que només seleccionem una forma, aquesta envia els seus paràmetres a la barra de controls de l'eina i així fixa els valors per les noves formes creades d'aquest tipus. + + + + + + Quan som en una eina de forma, podem seleccionar un objecte clicant al damunt. Ctrl+clic (selecciona en grup) i Alt+Clic (selecciona a sota) van com en l'eina Selector. Esc desselecciona. + + Rectangles + + + + + + + Un rectangle és la forma més simple i potser la més comú en disseny i il·lustració. L'Inkscape intenta fer que la creació i edició de rectangles sigui el més fàcil i còmode possible. + + + + + + Canvieu a l'eina Rectangle amb F4 o clicant el seu botó a la barra d'eines. Dibuixeu un nou rectangle al costat del blau: + dibuixeu aquí + + + + + + + Ara, sense deixar l'eina Rectangle, canvieu la selecció d'un rectangle a l'altre clicant al damunt. + + + + + + Dreceres de dibuix del Rectangle: + + + + + + + Amb Ctrl, dibuixeu un quadrat o un rectangle amb un ratio enter (2:1, 3:1, etc). + + + + + + + Amb Shift, dibuixa al voltant del punt inicial com a centre. + + + + + + Com veieu, el rectangle seleccionat (sempre està seleccionat el rectangle que acabeu de dibuixar) mostra tres manejadors a tres de les seves cantonades. De fet, són quatre manejadors, però dos d'ells (al cantó superior dret) se superposen si el rectangle no està arrodonit. Aquests dos són els manejadors d'arrodoniment; els altres dos (a dalt a l'esquerra i a baix a la dreta) són els manejadors de canvi de mida. + + + + + + Fixeu-vos primer en els manejadors d'arrodoniment. Agafeu-ne un i arrossegueu-lo cap avall. Els quatre cantons del rectangle s'arrodoneixen, i ara podeu veure el segon manejador d'arrodoniment — és a la posició original a la cantonada. Si voleu cantonades circulars, no cal que feu res més. Si voleu cantonades més arrodonides per un costat que per l'altre, moveu l'altre manejador cap a l'esquerra. + + + + + + Aquí els primers dos rectangles tenen cantonades arrodonides circulars, i els altres dos el·liptiques: + Cantonades arrodonides el·líptiques + Cantonades arrodonides circulars + + + + + + + + + + Encara a l'eina Rectangle, cliqueu sobre aquests rectangles per a seleccionar-los, i observeu els seus manejadors d'arrodoniment. + + + + + + Sovint, cal que el radi i la forma de les cantonades arrodonides sigui constant en tota la composició, encara que les mides dels rectangles siguin diferents (diagrames mentals amb caixes arrodonides de vàries mides). L'Inkscape ho fa fàcil. Canvieu a l'eina Selector; a la seva barra de Controls d'Eina, hi ha un conjunt de quatre botons de canvi. El segon des de l'esquerra mostra dos cantonades arrodonides concèntriques. Així és com controleu si les cantonades arrodonides s'escalen o no en escalar el rectangle. + + + + + + Per exemple, aquí el rectangle vermell original es duplicat i escalat vàries vegades, amunt i avall, a diferents proporcions amb el botó "Escala les cantonades arrodonides" deshabilitat: + Escalant rectangles arrodonits amb "Escala les cantonades arrodonides" OFF + + + + + + + + + + + + + + Veieu com la mida i la forma de les cantonades arrodonides són les mateixes en tots els rectangles, de manera que els arrodoniments s'alineen exactament a la cantonada superior dreta on coincideixen totes. Tots els rectangles blaus de punts s'obtenen a partir del rectangle vermell original escalant al Selector, sense cap reajustament manual dels manejadors d'arrodoniment. + + + + + + Com a comparació, aquí hi ha la mateixa composició, però ara creada amb el botó "Escala les cantonades arrodonides" habilitat: + Escalant rectangles arrodonits amb "Escala les cantonades arrodonides" ON + + + + + + + + + + + + + + Ara les cantonades arrodonides són diferents segons a quin rectangle pertanyen, i no hi ha la més mínima coincidència a la cantonada superior dreta (amplieu per a veure-ho). Aquest és el mateix resultat (visible) que tindrieu convertint el rectangle original en un camí (Ctrl+Maj+C) i escalant-lo com a camí. + + + + + + Aquí teniu les dreceres per als manejadors d'arrodoniment d'un rectangle: + + + + + + + Arrossegueu amb Ctrl per a fer l'altre radi igual (arrodoniment circular). + + + + + + + Ctrl+clic per a fer l'altre radi igual sense arrossegar. + + + + + + + Maj+clic per a eliminar l'arrodoniment. + + + + + + Potser haureu notat que la barra de Control de l'eina Rectangle mostra els radis d'arrodoniment horitzontal (Rx) i vertical (Ry) per al rectangle seleccionat i us permet definir-los amb precisió usant qualsevol unitat de longitud. El botó NO arrodonit fa el que diu — elimina els arrodoniments dels rectangles seleccionats. + + + + + + Un avantatge important d'aquests controls és que poden afectar molts rectangles al mateix temps. Per exemple, si voleu canviar tots els rectangles a la capa, feu Ctrl+A (Selecciona-ho tot) i fixeu els paràmetres que necessiteu a la barra de Controls. Si es selecciona qualsevol no-rectangle, s'ignorarà — només es canviaran els rectangles. + + + + + + Ara donem un cop d'ull als manejadors de mida del rectangle. Us preguntareu, per què els necessitem si també podem canviar de mida el rectangle amb el Selector? + + + + + + El problema amb el Selector és que la noció d'horitzontal i vertical sempre és la de la pàgina del document. En canvi, els manejadors de mida l'escalen al llarg de les cares del rectangle, encara que estigui girat o esbiaixat. Per exemple, proveu de canviar de mida aquest rectangle primer amb el Selector i després amb els manejadors de mida de l'eina Rectangle: + + + + + + + Com que hi ha dos manejadors de mida, podeu canviar la mida del rectangle en qualsevol direcció o fins i tot moure'l al llarg de les seves cares. Els manejadors de mida conserven sempre el radi d'arrodoniment. + + + + + + Aquí hi ha les dreceres per als manejadors de mida: + + + + + + + Arrossegueu amb Ctrl per a moure cap als costats o la diagonal del rectangle. Amb altres paraules, Ctrl conserva l'amplada, o l'alçada, o el ratio amplada/alçada del rectangle (novament, en el seu propi sistema de coordinades, que pot estar girat o esbiaixat). + + + + + + Aquí hi ha el mateix rectangle, amb les línies grises de punts mostrant les direccions que tenen fixats els manejadors de mida quan s'arrosseguen amb Ctrl (proveu-ho): + Desplaçament dels manejadors de mida d'un rectangle amb Ctrl + + + + + + + + + + + + + + Inclinant i girant un rectangle, duplicant-lo i canviant-lo de mida amb els manejadors de mida, podeu crear fàcilment composicions 3D: + 3 rectanglesoriginals + Varis rectanglescopiats i redimensionats amb els manejadors,la majoria amb Ctrl + + + + + + + + + + + + + + + + + + + + + + + + + + Aquí hi ha alguns exemples més de composicions amb rectangles, incloent arrodoniment i ompliments amb gradients: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + El·lipses + + + + + + + L'eina El·lipse (F5) pot crear el·lipses i cercles, que podeu convertir en segments o arcs. Les dreceres són les mateixes de l'eina Rectangle: + + + + + + + Amb Ctrl, dibuixeu un cercle o una el·lipse de ratio enter (2:1, 3:1, etc.). + + + + + + + Amb Maj, dibuixeu al voltant del punt inicial com a centre. + + + + + + Explorem els manejadors d'una el·lipse. Seleccioneu aquesta: + + + + + + + Novament, veureu inicialment tres manejadors, però de fet n'hi ha quatre. El manejador de més a la dreta són dos manejadors solapats que us permeten "obrir" l'el·lipse. Arrossegueu el manejador de més a la dreta, després arrossegueu l'altre que apareix visible a sota seu, per obtenir una varietat de diagrames de pastís, segments o arcs: + + + + + + + + + + + + + Per a obtenir un segment (un arc i dos radis), arrossegueu a fora de l'el·lipse; per a obtenir un arc, arrossegueu a dins. A sobre hi ha 4 segments a l'esquerra i 3 arcs a la dreta. Noteu que els arcs són formes no tancades, és a dir, el contorn només va al llarg de l'el·lipse, però no connecta els extrems de l'arc. Podeu fer-ho evident si elimineu l'emplenat, deixant només el contorn: + + + + + 15 + + + Segments + Arcs + + + + + + + + + + + + + + + + + + + + + + + + + Veieu el grup en ventall de segments estrets a l'esquerra. Va ser fàcil de crear usant els passos angulars del manejador amb Ctrl. Aquí teniu les dreceres d'arc/segment: + + + + + + + Amb Ctrl, moveu el manejador en salts de 15 graus a l'arrossegar. + + + + + + + Maj+clic per a fer l'el·lipse completa (no arc o segment). + + + + + + El pas angular es pot canviar a les preferències de l'Inkscape (la pestanya Passos). + + + + + + Els altres dos manejadors de l'el·lipse són per canviar la seva mida al voltant del centre. Les seves dreceres són similars a les dels manejadors d'arrodoniment d'un rectangle: + + + + + + + Arrossegueu amb Ctrl per a fer un cercle (fer l'altre radi igual). + + + + + + + Ctrl+clic per a fer un cercle sense arrossegar. + + + + + + I com els manejadors de mida del rectangle, aquests manejadors d'el·lipse ajusten l'alçada i amplada de l'el·lipse en les coordinades pròpies de l'el·lipse. Això vol dir que una el·lipse girada o esbiaixada pot estirar-se o comprimir-se fàcilment al llarg dels seus eixos mantenint-se girada o esbiaixada. Intenteu canviar la mida de qualsevol d'aquestes el·lipses amb els seus manejadors de mida: + + + + + + + + Estels + + + + + + + Els estels són la forma més complexa i emocionant de l'Inkscape. Si voleu que els vostres amics es quedin amb la boca oberta amb l'Inkscape, deixeu-los jugar amb l'eina Estel. És una font de diversió inesgotable — totalment addictiva! + + + + + + L'eina Estel pot crear dos tipus d'objectes similars però diferents: estels i polígons. Un estel té dos manejadors les posicions dels quals defineixen la longitud y la forma de les seves puntes; un polígon té només un manejador que gira i redimensiona el polígon quan s'arrossega: + Estel + Polígon + + + + + + + + A la barra de Controls de l'eina Estel, primer hi ha una caixa de selecció per a convertir un estel en polígon i a l'inrevés. Després, un camp numèric defineix el nombre de vèrtexs d'un estel o polígon. Aquest paràmetre només és editable a través de la barra de Controls. El marge de valors va des de 3 (òbviament) a 1024, però haurieu d'evitar els nombres grans (diguem, més grans de 200) si el vostre ordinador és lent. + + + + + + En dibuixar un nou estel o polígon, + + + + + + + Arrossegueu amb Ctrl per incrementar l'angle en passos de 15 graus. + + + + + + Naturalment, un estel és una forma molt més interessant (si bé en la pràctica, sovint els polígons són més útils). Els dos manejadors d'un estel tenen funcions lleugerament diferents. El primer (inicialment sobre un vèrtex, és a dir en una cantonada convexa de l'estel) fa els raigs de l'estel més llargs o curts, però si el gireu (en relació al centre de la forma), l'altre manejador gira de la forma corresponent. És a dir, amb aquest manejador no podem esbiaixar els raigs de l'estel. + + + + + + L'altre manejador (inicialment en una cantonada cóncava entre dos vèrtexs) al contrari, és lliure de moure's tant radialment com tangencial, sense afectar el manejador del vèrtex. (De fet, aquest propi manejador pot convertirse en vèrtex si el movem més lluny del centre que l'altre manejador.) Aquest és el manejador que pot esbiaixar les punxes de l'estel per a formar tota mena de cristalls, mandales, flocs de neu i porcs espins: + + + + + + + + + + + + + + + Si només voleu un estel senzill i regular sense aquesta mena de llaços, podeu fer que el manejador interior no faci cap esbiaix: + + + + + + + Arrossegueu amb Ctrl per a mantenir els raigs de l'estel estrictament radials (sense esbiaix). + + + + + + + Ctrl+clic per a eliminar l'esbiaix sense arrossegar. + + + + + + Com un complement a l'arrossegament del manejador a l'àrea de dibuix, la barra de Controls té el camp Radi de la punxa, que defineix el ratio de les distàncies dels manejadors al centre. + + + + + + Els estels de l'Inkscape tenen dos trucs més a la bossa. En geometria, un polígon és una forma amb costats rectes i cantonades en punta. Però al món real sovint hi ha presents diversos graus de corbatura i arrodoniment — i l'Inkscape també ho pot fer. Però arrodonir un estel o polígon funciona una mica diferent que arrodonir un rectangle. No hi ha un manejador dedicat a això, però + + + + + + + Maj+arrossega un manejador tangencialment per a arrodonir l'estel o el polígon. + + + + + + + Maj+clica un manejador per a eliminar l'arrodoniment. + + + + + + "Tangencialment" significa en direcció perpendicular a la direcció del centre. Si "gireu" un manejador amb Maj al voltant del centre en setit contrari a les busques, tindreu un arrodoniment positiu; en sentit contrari a les busques, tindreu arrodoniment negatiu. (Veieu a sota exemples d'arrodoniment negatiu.) + + + + + + Aquí hi ha una comparació entre un quadrat arrodonit (eina Rectangle) amb un polígon arrodonit de quatre costats (eina Estel): + + + Polígonarrodonit + Rectanglearrodonit + + + + + + Com podeu veure, un rectangle arrodonit te segments rectes a les seves cares i arrodoniments circulars (en general, el·líptics), en canvi un polígon o un estel arrodonit no té cap línia recta; la seva corbatura varia suaument del màxim (a ñes cantonades) al mínim (a mig camí entre cantonades). L'Inkscape fa això simplement afegint tangents de Bezier colineals a cada node de la forma (podeu veure'ls si convertiu la forma en camí i l'examineu amb l'eina Node). + + + + + + El paràmetre Arrodoniment que podeu ajustar a la barra de Controls és el ratio de la longitud d'aquestes tangents respecte la longitud de les cares del polígon/estel a que són adjacents. Aquest paràmetre pot ser negatiu, la qual cosa inverteix la direcció de les tangents. Valors entre 0.2 i 0.4 donen un arrodoniment "normal" del tipus que esperarieu; altres valors tendeixen a produir patrons bells, intrincats i totalment impredictibles. Un estel amb un gran arrodoniment es pot estendre molt més enllà de les posicions dels seus manejadors. Heus aquí alguns exemples, indicant cadascun el seu valor d'arrodoniment: + + + + + + + + + + + + + + 0.25 + 0.25 + 0.25 + 0.37 + + 0.43 + 3.00 + -3.00 + + 0.41 + 5.43 + 1.85 + 0.21 + -3.00 + + -0.43 + + -8.94 + + 0.39 + + + + + + Si voleu que les puntes d'un estel siguin agudes i les concavitats suaus o viceversa, és fàcil fer-ho creant un offset (Ctrl+J) de l'estel: + Estel original + Linked offset, inset + Linked offset, outset + + + + + + + + + Maj+arrossegar els manejadors d'un estel a l'Inkscape és un dels passatemps més refinats coneguts per l'home. Però pot ser encara millor. + + + + + + Per a imitar millor les formes del món real, l'Inkscape pot aleatoritzar (distorsionar aleatòriament) els estels i polígons. Un lleuger factor aleatori fa un estel menys regular, més humà, sovint divertit; un factor aleatori fort és una forma emocionant d'obtenir una varietat de formes bojament impredictibles. Un estel arrodonit resta arrodonit en aleatoritzar. Heus aquí dues dreceres: + + + + + + + Alt+arrossegar un manejador tangencialment per a aleatoritzar l'estel o polígon. + + + + + + + Alt+clicar un manejador per a eliminar l'aleatorització. + + + + + + Mentres dibuixeu o editeu els manejadors d'un estel, "tremolarà" perquè cada única posició dels manejadors es correspon a la seva pròpia i única aleatorització. Així, movent un manejador sense Alt re-aleatoritza la forma amb el mateix nivell d'aleatorietat, mentres que Alt-arrossegar manté la mateixa aleatorització però ajusta el seu nivell. Aquí tenim un estel amb exactament els mateixos paràmetres, però cadascun és re-aleatoritzat movent lleugerament el seu manejador (el nivell d'aleatorització és 0.1 en tots): + + + + + + + + + + + I aquí tenim l'estel central de la filera anterior, amb el nivell d'aleatorització que varia de -0.2 a 0.2: + +0.2 + +0.1 + 0 + -0.1 + -0.2 + + + + + + + + + + + Alt+arrossegueu un manejador de l'estel central de la filera i observeu com es transforma en els seus veïns a la dreta i a l'esquerra — i més enllà. + + + + + + Segurament trobareu les vostres pròpies aplicacions per als estels aleatoris, però a mi m'agraden molt les taques arrodonides en forma d'ameba i els planetes grans i aspres amb paisatges fantàstics: + + + + + + + + + + + Espirals + + + + + + + L'espiral de l'Inkscape és una forma versàtil, i si bé no és tan engrescadora com l'estel, a vegades pot resultar molt útil. Una espiral, com un estel es dibuixa des del centre; tant en dibuixar com en editar, + + + + + + + Ctrl+arrossegar per incrementar l'angle de 15 en 15 graus. + + + + + + Un cop dibuixada, una espiral té dos manejadors als extrems interior i exterior. Simplement en arrossegar-los l'enrotlla i desenrotlla l'espiral (és a dir la "continua"), canviant el nombre de voltes. Altres dreceres: + + + + + + Manejador exterior: + + + + + + + Maj+arrossegar per a escalar/girar al voltant del centre (no enrotlla/desenrotlla). + + + + + + + Alt+arrossegar per a bloquejar el radi a l'enrotllar/desenrotllar. + + + + + + Manejador interior: + + + + + + + Alt+arrossegar verticalment per a convergir/divergir. + + + + + + + Alt+clicar per a reiniciar la divergència. + + + + + + + Maj+clicar per a moure el manejador intern cap al centre. + + + + + + La divergència d'una espiral és la mesura de no-linealitat de les seves voltes. Quan és igual a 1, l'espiral és uniforme; si és menor que 1 (Alt+arrossega amunt), l'espiral és més densa a la perifèria; si és més gran que 1 (Alt+arrossega avall), l'espiral és més densa cap al centre: + 0.2 + 0.5 + 6 + 2 + 1 + + + + + + + + + + + El màxim nombre de voltes d'una espiral és 1024. + + + + + + Així com l'eina El·lipse no només serveix per a fer el·lipses, sinó també per a arcs (línies ode corbatura constant), l'eina Espiral és útil per a fer corbes amb corbatura de variació suau. Comparades amb una corba de Bezier simple, un arc o una espiral, sovint és més adequat perquè les podeu fer més curtes o llargues estirant un manejador al llarg de la corba sense afectar-ne la forma. A més, encara que una espiral normalment es dibuixa sense emplenat, podeu omplir-la i eliminar el contorn per a obtenir interessants efectes. + + + + + + + + + + + + + + + + + + + + + + + + + + Especialment interessants són les espirals amb contorn de punts — combinen la concentració suau de la forma amb marques regulars equiespaiades (punts o ratlles) per a uns bonics efectes moiré: + + + + + Conclusió + + + + + + + Les eines de forma de l'Inkscape's són molt potents. Apreneu-ne els trucs i jugueu-hi en les estones d'oci — això valdrà la pena en la vostra feina de disseny, perquè l'ús de formes en comptes de simples camins sovint fa l'art vectorial més ràpid de crear i més fàcil de modificar. Si teniu cap idea de millora per a les formes contacteu amb els desenvolupadors. + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/share/tutorials/tutorial-shapes.es.svg b/share/tutorials/tutorial-shapes.es.svg new file mode 100644 index 000000000..40f11b11f --- /dev/null +++ b/share/tutorials/tutorial-shapes.es.svg @@ -0,0 +1,619 @@ + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ::FORMAS + + + + + + + +Este tutorial cubre las cuatro herramientas de formas: Rectángulo, Elipse, Estrella y Espiral. +Demostraremos las capacidades de las formas de Inkscape y presentáremos ejemplos de como y cuando pueden ser usadas. + + +Use Ctrl+Flechas, rueda del ratón o arrastrar con el botón del medio para bajar la pizarra. Para las bases de la creación de objetos, la selección y sus transformaciones, observe el tutorial Básico en Ayuda > Tutoriales. + + + + +Inkscape cuenta con cuatro versátiles herramientas de formas, cada herramienta es capaz de crear y editar su propio tipo de formas. Una forma es un objeto el cual puede ser modificado en un único modo dependiendo del tipo de forma, usando los manejadores arrastrables y los parámetros numéricos que determinan la apariencia de la forma. + + +Por ejemplo, con una estrella le es posible alterar el número de esquinas, su tamaño, ángulo, +redondez, etc. — pero la ésta continua siendo una estrella. Una forma es "menos libre" que un simple trazo, pero es más interesante y útil. Siempre le es posible convertir una figura a trazo (Ctrl+Shift+C), pero el proceso inverso no es posible. + + +Las herramientas de forma son: Rectángulo, Elipse, Estrella y Espiral. Primero, observaremos como funcionan las herramientas en general; más adelante exporaremos cada tipo de forma más a fondo. + + + + +Trucos Generales +Una nueva forma es creada por medio de arrastar(ado) sobre la pizarra con la herramienta correspondiente. Una vez que la forma es creada (y del modo en que sea seleccionada), mostrará sus manejadores en forma de diamantes, así le es posible editar inmediatamente lo que ha creado, mediante el arrastrado de estos manejadores. + + +Todos los cuatro tipos de formas muestran sus manejadores en las cuatro herramientas de formas como lo hace la herramienta Nodo(F2). Cuando mueve el ratón sobre un manejador, este le indicará en la barra de estado que hará este manejador cuando sea arrastrado o dado un click con modificadores diferentes. + + +También, cada herramienta de forma muestra sus parámetros en los Controles de Herramientas (la cual se encuentran en la parte superior de la pizarra). Usualmente este posee un campo pequeño de ingreso numérico y un botón para formatear los valores a valor por defecto. Cuando una(s) forma(s) son seleccionadasla con la herramienta actual, al editar los valores en los Controles de Herramientas la(s) forma(s) seleccionadas cambiará(n). + + +Cualquier cambio hecho a la barra de control es recordada y usada para el próximo objeto que usted dibuje con dicha herramienta. Por ejemplo, después de que ha cambiado el número de esquinas de una estrella, la nueva estrella tendrá este número de esquinas cuando sea dibujada. Además, con una simple selección de una forma le serán enviados los parámetros a la barra de Control y así configurará los valores para las nuevas formas que sean creadas de este mismo tipo. + + +Cuando se posee la herramienta de formas, la selección puede realizarse por medio de un click sobre la forma. Ctrl+click (selección en grupo) y Alt+Click (Selección de abajo) también trabajan como con la herramienta Selección. Esc deselecciona. + + + + +Rectángulos +Un rectángulo es la más simple pero consideramos, es la forma más común en el diseño y la ilustración. Inkscape permite la creación y edición de rectángulos de la manera más fácil y sencilla posible. + + +Cambie a la herramienta Rectángulo mediante F4 o mediante click sobre el botón en la barra de Herramientas. Dibuje un nuevo rectángulo al lado de este rectángulo azul: + + +draw here + +Después, sin dejar la herramienta Rectángulo, cambie la selección de uno a otro por medio de click. + + +Atajos para dibujo de Rectángulos: + + +Con Ctrl, dibuje un cuadrado o un rectángulo de radio-entero (2:1, 3:1, etc). + +Con Shift, dibuje alrededor del punto inicial como centro de esta forma. + + + +Como podemos observar, el rectángulo seleccionado (El Rectángulo recien dibujado es siempre seleccionado) muestra tres manejadores en tres de sus esquinas. De hecho, estos son tres manejadores, pero dos de ellos (en la esquina superior derecha) se sobreponen si el rectángulo no está redondeado. Estos dos son los manejadores de redondeado; los otros dos (superior izquierdo e inferior derecho) son los manejadores de tamaño. + + +Vamos primero con los manejadores de redondez. Tome uno de ellos y arrastrelo hacia abajo. Las cuatro esquinas del rectángulo son redondeadas y le es posible observar el segundo manejador de redondeado — este se encuentra en la posición original de la esquina. Si desea esquinas con un redondeado circular, esto es lo que debe hacer. Si desea esquinas cuya redondez sea mayor o menor de un lado que del otro, mueva el otro manejador verticalmente. + + +Aquí, los primeros dos rectángulos poseen esquinas redondeadas y los otros dos tienen esquinas redondeadas elipticamente: + + +Elliptic rounded cornersCircular rounded corners + +Aún con la herramienta Rectángulo, de click sobre estos rectángulos para seleccionar y observe sus manejadores de redondeado. + + +La mayoría de ocasiones, el radio y la forma de redondeo de las esquinas deben ser constantes dentro de la composición entera, incluso si el tamaño de los rectángulos son diferentes (piense en diagramas con cajas redondeadas de varios tamaños). Inkscape lo hace sencillo. Cambie a la herramienta Selección; en su Control de herramientas, hay un grupo de cuatro botones de selección, el segundo desde la izquierda muestra dos esquinas redondeadas concéntricas. Así es como usted controla si las esquinas redondeadas son escaladas, cuando el rectángulo es escalado o no. + + +Por ejemplo, aquí el rectángulo rojo original es duplicado y escalado varias veces, arriba y abajo, en diferentes proporciones, por medio del botón "Escalar los radios de los ángulos redondeados" +off: + + +Scaling rounded rectangles with "Scale rounded corners" OFF + +Note como el tamaño y forma de la esquinas redondeadas es el mismo en todos los rectángulos, +así que los redondeados se alínean perfectamente en la esquina superior derecha donde ellos se encuentran. Todos los rectángulos punteados de color azul son obtenidos del rectángulo rojo original tan sólo escalándolos mediante la Selección, sin ningún reajuste manual de los manejadores de redondeado. + + +Para una comparación, aquí encontramos la misma composición pero creado ahora por medio del botón +activo "Escalar los radios de los ángulos redondeados": + + +Scaling rounded rectangles with "Scale rounded corners" ON + +Ahora las esquinas redondeadas son tan diferentes como los rectángulos a los que pertenecen y +no hay un encuentro leve en la parte superior de la esquina derecha (haga zoom para visualizar). +Este es el mismo resultado (visible) que puede obtener mediante la conversión del rectángulo original a un trazo (Ctrl+Shift+C) y escálelo como un trazo. + + +He aquí los atajos para el redondeado de manejadores de redondeado de un rectángulo: + + +Arrastre con Ctrl para hacer igual el otro radio (redondeado circular). + +Ctrl+click para hacer igual el otro radio sin necesidad de arrastrar. + + +Shift+click para remover el redondeado. + + + +Debe de haber notado que la barra de Control de Herramientas muestra el radio del redondeado horizontal (Rx) y vértical (Ry) del rectángulo seleccionado y le permite configurarlos precisamente usando cualquier unidad de medida. +El botón No redondeado hace lo que dice — remueve el redondeado del/los rectángulo(s). + +Una ventaja importante de estos controles es que pueden afectar algunos rectángulos +a la vez. Por ejemplo, si desea cambiar todos los rectángulos en la capa, solo haga +Ctrl+A (Seleccionar Todo) y configure los parámetros que requiera en la barra de Control. Si cualquier objeto no-rectángulo es seleccionado, este objeto(s) será ignorado —, sólo serán cambiados los rectángulos. + + +Ahora vamos a redimensionar los manejadores de un rectángulo. Se preguntará, +¿al fin, por qué los necesitamos, si sólo deseamos cambiar el tamaño del rectángulo con Selección? + + +El problema con Selección radica en que su noción de horizontal y vértical es respecto a +la hoja del documento. A diferencia, la escala de los manejadores redimensionadores del rectángulo es a lo largo de los lados de rectángulo, uniformemente si el rectángulo es rotado o inclinado. Por ejemplo, intente redimensionar este rectángulo, primero con Selección y luego con sus manejadores de redimensionado con la herramienta Rectángulo: + + + + +Desde que los manejadores de redimensionamiento sean dos, usted puede redimensionar el rectángulo en cualquier dirección o moverlo uniformemente a lo largo de sus lado. Los manejadores de redimensionado siempre preservan el redondeado del radio. + + +He aquí algunos atajos para los manejadores de redimensionado: + + + +Arrastre con Ctrl para encajar los lados o la diagonal del rectángulo. En otras palabras, Ctrl preserva o el ancho o el alto, o el radio de ancho/alto del rectángulo (de nuevo, en su propio sistemas de coordenadas el cual puede ser rotado o inclinado) + + + +Aquí está el mismo rectángulo con las líneas punteadas grices, mostrando las direcciones para las barras de los manejadores de redimensionado cuando son arrastrados con Ctrl (inténtelo): + + +Snapping of rectangle resize handles with Ctrl + + + + + + + +Mediante inclinación y rotación de un rectángulo, luego duplicándolo y redimensionando a partir de sus manejadores de redimensionado, pueden ser creadas composiciones 3D fácilmente: + + +3 originalrectanglesSeveral rectanglescopied and resizedby handles,mostly with Ctrl + +Aquó podemos observar algunos ejemplos de composiciones de rectángulos, incluyendo redondeado y relleno con gradientes: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Elipses +La herramienta Elipse (F5) puede crear elipses y círculos, los cuales pueden volverse segmentos y arcos. Los atajos de dibujo son los mismo que la herramienta rectángulo: + + +Con Ctrl, dibuje un círculo o una elipse radio-entero (2:1, 3:1, etc.). + +Con Shift, dibuje alrededor del punto inicial como centro de esta forma. + + + +Vamos a explorar los manejadores de una elipse. Seleccione una: + + + + +Una vez más, puede observar tres manejadores inicialmente, pero de hecho, son cuatro. El manejador más al extremo derecho consiste en dos manejadores superpuestos que le permiten "abrir" la elipse. Arrastre el manejador que se encuentra más al extremo derecho, después arrastre el otro manejador el cual se hace visible debajo de este, para obtener una variedad de segmentos tipo gráfica-torta o arcos: + + + + +Para obtener un segmento (un arco más dos radios), arrastre +fuera de la elipse; para obtener un arco, arrástrelo +dentro. Abajo, hay 4 segmentos a la izquierda y 3 arcos a la derecha. Note +que los arcos son figuras no cerradas, IMPORTANTE: el borde solo va a lo largo de la elipse pero +no se conecta con el final del arco. Usted puede hacer esto obvio si usted remueve el relleno, dejándo sólo el borde: + + + + + + + 15 + + SegmentsArcs + +Note el grupo de segmentos angostos a la izquierda. Esto fue sencillo de crear usando +ángulo de rotación del manejador con Ctrl. He aquí algunos atajos para manejadores de arcos/segmentos: + + + +Con Ctrl, rote los manejadores 15 grados cuando sea arrastrado. + +Shift+click para completar la elipse (no un arco o un segmento). + + + +El ángulo de rotación puede ser cambiado en las Preferencias de Inkscape (la pestaña Pasos). + + +Los otros dos manejadores de la elipse son usados para redimensionarla alrededor de su centro. Sus atajos son similares a los de manejadores de redondeado de un rectángulo: + + + +Arrastre con Ctrl para hacer círculos (Haga el otro radio igual). + +Ctrl+click Para hacer círculo sin arrastrado. + + + +Y, como los manejadores de redimensionado de rectángulos, estos manejadores de elipse ajustan el ancho y alto de la elipse en las coordenadas propias de la elipse. Esto significa que una elipse rotada o inclinada puede ser alargada o ensachada a lo largo de sus equis originales mientras el resto es rotado o inclinado. Intente redimensionar cualquiera de estas elipses a través de sus nodos de redimensionamiento: + + + + + + + +Estrellas +Las estrellas son más complejas pero son las formas más emocionantes de Inkscape. Si desea sorprender a sus amigos con Inkscape, permítales jugar con la herramienta Estrella. —¡Este es un entretenimiento francamente adictivo, y por supuesto, sin fin!. + + +La herramienta estrella puede crear dos objetos similares pero de distinta clase: estrellas y polígonos. Una estrella tiene dos manejadores cuyas posiciones definen la longitud y forma de sus estrellas; un polígono posee un sólo manejador el cual simplemente rota y redimensiona el polígono cuando es arrastrado: + + +StarPolygon + +En la bara de Control de la herramienta Estrella, primero está un botón de selección (checkbox) para volver una estrella en su polígono correspondiente y viceversa. Sigue, un campo numérico que configura el número de vértices de una estrella o un polígono. Este parámetro es sólo editable por medio de la barra de Control. El rango permitido es desde 3 (obviamente) hasta 1024, pero no intente con números grandes (más de 200) si su computador es lento. + +Cuando dibuje una estrella o un polígono, + + + +Arrastre con Ctrl para incrementar la rotación del ángulo en 15 grados. + + + +Naturalmente, una estrella es la forma más interesante (aunque los polígonos en la práctica, son más útiles). Los dos manejadores de una estrella tienen funciones levemente diferentes. El primer manejador (inicialmente se encuentra sobre una cima, sobre una esquina convexa de la estrella) hace los rayos de la estrella más largos o cortos, pero cuando los rota (relativo al centro de la figura), el otro manejador rota de acuerdo a este. Esto significa que no puede inclinar los rayos de la estrella con este manejador. + + +El otro manejador (inicialmente en una esquina concava en medio de los dos vértices) es, convenientemente, libre para mover ambos radialmente y tangencialmente, sin afectar el manejador cima. (De hecho, este manejador puede convertirse por si mismo en una cima por medio del movimiento más lejano desde el centro que el otro manejador.) Este es el manejador que puede inclinar las puntas de las estrellas para obtener gran variedad de cristales, mandalas, cristales de nieve y puercoespines: + + + + +Si sólo desea una estrella regular plana sin algún trazo especial, puede hacer que el +manejador de inclinado se comporte como el otro que no lo es: + + + +Arrastre con Ctrl para mantener los rayos de la estrella estrictamente radiales (no inclinados). + +Ctrl+click para remover la inclinación sin arrastrar. + + + +Como un complemento útil para el arrastrado del manejador sobre la pizarra, la barra de Control tiene el campo de longitud de Radio el cual define el radio de las distancias en el centro. + + +Las estrellas de Inkscape posee otros dos trucos más en la manga. En geometría, un polígono es una forma con bordes de líneas rectas y esquinas afiladas. En el mundo real, sin embargo, varios grados de curvalinealidad y redondeado son normalmente presentes — e Inkscape puede hacerlo también. El redondeando de una estrella o polígono trabaja un poco diferente al redondeado de un rectángulo, sin embargo, usted no emplea un manejador especializado. + + + +Shift+arrastrar en un manejado tangencialmente, para redondear la estrella o polígono. + +Shift+click en un manejador para remover el redondeado. + + + +"Tangencialmente" significa en una dirección perpendicular a la dirección del centro. Si "rota" +un manejador con Shift en sentido anti-horario alrededor del centro, obtendrá redondeado positivo; con rotación horaria, obtendrá redondeado negativo. (Observe más adelante los ejemplos de redondeado negativo). + + +Aquí podemos encontar una comparación de un cuadrado redondeado (herramienta Rectángulo) con un polígono redondeado de 4-lados (herramienta Estrella): + + +RoundedpolygonRoundedrectangle + +Como podemos observar, mientras un rectángulo redondeado posee segmenntos de líneas rectas en sus lados, y redondeado circular (generalmente, elíptico), un polígono o estrella redondeada no posee líneas rectas; sus curvaturas varían suavemente desde el máximo (en las esquinas) al mínimo (en la mitad entre las estrellas). Inkscape lo hace simple mediante la adición colineal de tangentes Bezier para cada nodo de la forma (puede observarlo si convierte la forma en trazo y lo examina con la herramienta Nodo). + + +El parámetro Redondez el cual puede ajustar en la barra de Control, es el radio de la longitud de dichas tangentes para la longitud de los lados del polígono/estrella a los que son adyacentes. Este parámetro puede ser negativo, lo cual invierte la dirección de las tangentes. Los valores entre 0.2 a 0.4 dan un redondeado "normal" de la clase que usted espera; otros valores tienden a producir patrones hermosos, difíciles y totalmente impredecibles. +Una estrella con valores de redondez muy grandes puede alcanzar una posición lejana más allá de la posición de sus manejadores. He aquí unos cuantos ejemplos, cada uno indicando su valor de redondez: + + +0.250.250.250.370.433.00-3.000.415.431.850.21-3.00-0.43-8.940.39 + +Si desea que las puntas de las estrellas sean afiladas pero concavas suavemente o viceversa, es fácil de hacer creando un Desvio automático (Ctrl+J) +desde la estrella: + + +Original starLinked offset, insetLinked offset, outset + +Shift+arrastraren los manejadores de la estrella en Inkscape es una de las más finas búsqueda conocidas por el hombre. Pero aún pueden ser conseguidas mejor. + + +Para imitar más de cerca las formas del mundo real, Inkscape puede hacer aleatorio (i.e. distorsión aleatoria) en sus estrellas y polígonos. La aleatoriedad baja hace a la estrella menos regular, más humana, más divertida; aleatoriedad alta es una forma emocionante para obtener una variedad de alocadas formas impredecibles. Una estrella redondeada conservan redondeado suave cuando es aleatorizado. He aquí los atajos: + + + +Alt+arrastrar sobre un nodo, de forma tangencial para aleatorizar la estrella o polígono. + +Alt+click sobre un nodo remueve la aleatoriedad. + + + +Como usted dibuja o edita a mano por arrastrado una estrella aleatorizada, esta puede "temblar" a causa de que cada posición única de los manejadores corresponde a su única aletoredad propia. Así, moviendo un manejador sin Alt re-aleatoriza la forma al mismo nivel de aletoriedad. Aquí están las estrellas cuyos parámetros son exactamente los mismos, pero cada una es re-aleatorizada por movimientos muy suaves de sus manejadores (nivel de aletoriedad es a través de 0.1): + + + + +Y aquí está la estrella media desde la fila previa, con el nivel de aletoriedad varia desde -0.2 hasta 0.2: + + ++0.2+0.10-0.1-0.2 + +Alt+arrastrar sobre un manejador de la estrella media en su fila y observe como cambian en sus vecinos de la derecha y de la izquierda —. + + +Usted probablemente busque sus propias aplicaciones para aleatorizar estrellas, pero yo especialmente me encariñe con los broches en forma de amebas y grandes planetas ásperos con hermosos paisajes: + + + + + + + +Espirales +Las espirales de Inkscape son unas formas versátiles, aunque no tan enviciantes como las estrellas, pero en ocasiones es muy útil. Una espiral, como una estrella, se dibuja desde el centro; mientras es dibujada como puede ser editada, + + + +Ctrl+arratrar para lograr una rotación de 15 grados. + + + +Una vez dibujada, una espiral posee dos manejadores en siçu inicio y finalización interna y externa. Ambos manejadores, cuando son arrastrados, simplemente enrollan o desenrrollan la espiral (i.e. "continue" cambiando el número de giros). Otros atajos: + + +Manejador Externo: + + + +Shift+arrastrar para escalar/rotar alrededro del centro (no enrrollar/desenrrollar). + +Alt+arrastrar para bloquear el radio mientras enrrollamos/desenrrollamos. + + + +Manejador interno: + + + +Alt+arrastrar verticalmente para lograr convergencia/divergencia. + +Alt+click para formatear la divergencia. + +Shift+click para mover el manejador interno para el centro. + + + +La divergencia de una espiral es la medida no lineal de sus giros. +Cuando es igual a 1, la espiral es uniforme; cuando es menor a 1 (Alt+arrastrar de manera ascencente), la espiral es más densa sobre la periferia; cuando es mayor que 1 (Alt+arrastrar de manera descendente), la espiral es más densa a través del centro: + + +0.20.5621 + +El número máximo de giros para la espiral es 1024. + + +Así como la herramienta Elipse es buena no sólo para elipses, sino también para arcos (líneas de curvatura constante), la herramienta Espiral es útil para hacer curvas con curvatura de suavidad variable curvature. Comparada con la curva plana Bezier, un arco o una espiral es mucho más conveniente a causa de que usted puede hacerlos más cortos o largo mediante el arrastrado de un manejador +a lo largo de la curva sin afectar su forma. También, mientras una espiral es dibujada normalmente sin un relleno, le puede agregar relleno y remover borde para crear efectos interesantes. + + + + +Algo especialmente interesantes son las espirales con borde punteado — ya que combinan la suave concentración de la forma con marcas equis-espaceadas (puntos o guiones) para hermosos efectos moire: + + + + + + + +Conclusión +Las herramientas de formas de Inkscape son muy poderosos. Aprenda sus trucos y juegue con ellas en sus tiempos libres — +esto puede dar fruto en sus trabajos de diseño, ya que usando formas en vez de simples trazos permiten hacer arte con vectores más rápido y con facilidad de edición. Si usted posee alguna idea para algunas mejores, no dude en contactar a los desarrolladores. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/share/tutorials/tutorial-shapes.fr.svg b/share/tutorials/tutorial-shapes.fr.svg new file mode 100644 index 000000000..858021dd5 --- /dev/null +++ b/share/tutorials/tutorial-shapes.fr.svg @@ -0,0 +1,670 @@ + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ::FORMES + + + + + + + + +Ce didacticiel aborde les quatre outils de formes : rectangle, ellipse, étoile et spirale. Nous verrons des exemples montrant les possibilités des formes d'Inkscape et suggérerons quand et comment les utiliser. + + +Faites défiler la page avec Ctrl+flèche ou avec la souris (molette ou bouton du milieu). Pour les bases de la création, sélection ou transformation d'objets, voyez le didacticiel basique du menu Aide > Didacticiels. + + + + + +Inkscape possède plusieurs outils de formes versatiles, chacun créant son propre type de forme. Une forme est un objet ayant un certain type de poignées déplaçables et des paramètres numériques permettant de modifier cette forme tout en conservant son type. + + +Par exemple, vous pouvez modifier le nombre de sommets d'une étoile, ou ses dimension, angle, arrondi etc. — mais une étoile reste une étoile. Une forme est donc "moins libre" qu'un chemin, mais souvent plus pratique et intéressante. Vous pouvez convertir une forme en chemin (Ctrl+Maj+C), mais pas l'inverse. + + +Les outils de formes sont : l'outil rectangle, l'outil ellipse, l'outil étoile et l'outil spirale. Nous allons d'abord voir comment ces outils fonctionnent de manière générale, puis nous explorerons les possibilités particulières de chacun d'entre eux. + + + + + +Principes généraux + +Une forme est créée sur le canevas par un cliquer-déplacer avec l'outil lui correspondant. Une fois la forme créée (et tant qu'elle est sélectionnée), elle affiche ses poignées (des marques en forme de diamant), de sorte que vous pouvez toujours la modifier en déplaçant ces poignées. + + +Les quatre types de formes affichent leurs poignées dans les quatre outils de forme, mais aussi dans l'outil nœud (F2). Lorsque vous faites passer le curseur de la souris au-dessus d'une poignée, la barre d'état affiche des messages vous indiquant ce que vous pouvez faire en lui cliquant dessus ou en la déplaçant en combinaison avec différents raccourcis. + + +De plus chaque outil de forme affiche ses paramètres dans la barre de contrôle d'outil (qui est affichée horizontalement au dessus du canevas). Elle comporte habituellement plusieurs champs numériques et un bouton de remise à zéro (retour aux valeurs par défaut) de ces champs. Quand une (ou des) formes de l'outil en cours d'utilisation est sélectionnée, modifier les valeurs de ces champs de la barre de contrôle permet de modifier la (ou les) forme sélectionnée. + + +Toute modification effectuée via la barre de contrôle est retenue afin d'être réappliquée à la prochaine forme que vous dessinerez avec cet outil. Par exemple, après avoir changé le nombre de sommets d'une étoile, les étoiles que vous créerez par la suite auront le même nombre de sommets. De plus, le simple fait de sélectionner une forme donnée envoie ses paramètres à la barre de contrôle d'outil et donc permet de définir les valeurs pour les formes de ce type que vous créerez après. + + +Lorsque vous utilisez un outil de forme, vous pouvez sélectionner un objet en cliquant dessus.Ctrl+ cliquer (sélectionner au sein d'un groupe) et Alt+cliquer (sélectionner dessous) fonctionne aussi comme dans le sélecteur. Esc permet de désélectionner. + + + + + +Rectangles + +Le rectangle est la forme la plus simple mais sans doute la plus courante en design et en illustration. Inkscape tente de rendre la création et la modification des rectangles aussi simple et efficace que possible. + + +Passez à l'outil Rectangle en appuyant sur F4 ou en cliquant sur son bouton dans la barre d'outils. Dessinez un nouveau rectangle à côté de celui-ci : + + +dessinez ici + +Puis, sans quitter l'outil rectangle, passez d'un rectangle à l'autre en cliquant dessus. + + +Raccourcis de dessin des rectangle : + + + + +En appuyant sur Ctrl, vous pouvez dessiner un carré ou un rectangle de rapport de dimensions entier (2:1, 3:1, etc.). + + + + +En appuyant sur Maj, vous pouvez dessiner autour du point de départ. + + + + +Comme vous pouvez le voir, le rectangle sélectionné (le rectangle qui vient d'être créé est toujours sélectionné) affiche trois poignées dans trois de ses coins. En fait, il y a quatre poignées, mais deux d'entre elles (dans le coin supérieur droit) se chevauchent si le rectangle n'est pas arrondi. Ces deux-là sont les poignées d'arrondi; les deux autres (en haut à gauche, et en bas à droite) sont les poignées de redimensionnement. + + +Voyons les poignées d'arrondi d'abord. Saisissez l'une d'elles, et déplacez-la vers le bas. Les quatres coins du rectangle deviennent arrondis, et vous pouvez maintenant voir la deuxième poignée d'arrondi — qui est toujours au même emplacement dans le coin. Si vous voulez obtenir des coins arrondis circulairement, vous n'avez plus rien à faire. Si vous voulez des arrondis avec un rayon différent selon le côté, vous pouvez déplacer la deuxième poignée vers la gauche. + + +Ici, les deux premiers rectangles ont des coins arrondis circulairement et les deux autres des coins arrondis elliptiquement : + + +Coins arrondis elliptiquementCoins arrondis circulairement + +Toujours avec l'outil rectangle, cliquez sur ces rectangle pour les sélectionner et observez leurs poignées d'arrondi. + + +Souvent, le rayon et la forme des coins arrondis doivent garder les mêmes proportions au sein d'une composition, même si les dimensions des rectangles sont différentes (comme dans des diagrammes formés de boîtes arrondies de différentes tailles). Inkscape permet cela facilement. Passez à l'outil sélecteur; dans la barre de contrôle de cet outil, il y a un groupe de quatre boutons enfonçables, le second affichant deux coins arrondis concentriques. Ce bouton vous permet de déterminer si les rayons des coins arrondis doivent être mis à l'échelle ou non quand vous redimensionnez un rectangle. + + +Ici par exemple, le rectangle original rouge a été dupliqué et ses dimensions changées (augmentées et diminuées) plusieurs fois selon différentes proportions, le bouton "préserver l'échelle des arrondis" étant décoché : + + +Rectangles arrondis redimensionnés avec "préserver l'échelle des arrondis" décoché + +Notez que la taille et la forme des coins arrondis restent les mêmes pour tous les rectangles, de sorte que les coins arrondis se superposent exactement en haut à droite de la figure. Tous les rectangles bleus en pointillés ont été obtenus après un redimensionnement de l'original dans le sélecteur, sans avoir réajusté les poignées d'arrondi. + + +Pour comparer, voici la même composition, mais créée cette fois-ci le bouton "préserver l'échelle des arrondis" étant coché : + + +Rectangles arrondis redimensionnés avec "préserver l'échelle des arrondis" coché + +Maintenant, les rectangles ont tous des coins arrondis différemment, et il n'y a plus aucune superposition en haut à droite (zommez pour le vérifier). Ce résultat (visible) est le même que celui que vous auriez obtenu en convertissant le rectangle original en chemin (Ctrl+Maj+C) puis en modifiant les dimensions de ce chemin. + + +Voici les raccourcis permettant de manipuler les poignées d'arrondi d'un rectangle : + + + + +Déplacez-les en appuyant sur Ctrl pour garder égaux les deux rayons (arrondi circulaire). + + + + +Ctrl+cliquer sur une poignée rendra son rayon égal à celui de la deuxième sans avoir à la déplacer. + + + + +Maj+clicquer permet de supprimer l'arrondi. + + + + +Vous avez peut-être remarqué que la barre de contrôle de l'outil rectangle affiche deux champs pour les rayons horizontal (Rx) et vertical (Ry) d'arrondi pour le rectangle sélectionné , vous permettant ainsi de modifier précisément ces rayons dans l'unité de votre choix. Le bouton Pas d'arrondi fait simplement ce qu'il indique : il supprime l'arrondi des rectangles sélectionnés. + +Un avantage important de ces contrôles est qu'ils peuvent affecter plusieurs rectangles en même temps. Par exemple, si vous voulez modifier tous les rectangles d'un calque, vous n'avez qu'à appuyer sur Ctrl+A (tout sélectionner) et définir les paramètres voulus dans la barre de contrôle. Si des objets autres que des rectangles sont sélectionnés, ils seront ignorés — seuls les formes rectangles seront modifiées. + + +Maintenant, observons les poignées de redimensionnement d'un rectangle. Vous vous demandez peut-être à quoi elles servent puisqu'il est possible de redimensionner un rectangle avec le sélecteur ? + + +Le problème avec le sélecteur est que pour lui, les notions d'horizontale et de verticale sont celles de la page. En revanche, les poignées de redimensionnement d'un rectangle agissent parallèlement à ses côtés, même si le rectangle a été tourné ou incliné. Par exemple, essayez de redimensionner ce rectangle d'abord avec le sélecteur puis avec ses poignées de redimensionnement dans l'outil rectangle : + + + +Comme il y a deux poignées de redimensionnement, vous pouvez modifier les dimensions du rectangle +selon n'importe quelle direction et même parallèlement à ses côtés. Le redimensionnement préserve les rayons d'arrondi des coins. + + +Voici les raccourcis permettant de manipuler les poignées de redimensionnement d'un rectangle : + + + + +Déplacez-les en appuyant sur Ctrl pour forcer leur déplacement parallèlement aux côtés du rectangle ou à sa diagonale. Autrement dit, Ctrl permet de préserver la largeur ou la hauteur ou encore le ratio largeur/hauteur du rectangle (dans son propre système de coordonnées qui peut être tourné ou incliné). + + + + +Voici le même rectangle, entouré de lignes pointillées grises indiquant les directions dans lesquelles vous pouvez déplacer ses poignées de redimensionnement en appuyant sur Ctrl (essayez): + + +Déplacement des poignées deredimensionnement d'un rectangletout en appuyant sur Ctrl + + + + + + + +En inclinant et en tournant un rectangle, puis en le dupliquant et en modifiant ses dimensions avec ses poignées de redimensionnement, vous pouvez facilement créer des dessins en 3D : + + +3 rectanglesd'originePlusieurs rectanglescopiés et redimensionnéspar leurs poignées,principalement avec Ctrl + +Voici quelques exemples de plus de compositions avec des rectangles, incluant des coins arrondis et des dégradés de remplissage : + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Ellipses + +L'outil ellipse (F5) permet de créer des ellipses et des cercles, que vous pouvez transformer en camemberts ou en arcs. Les raccourcis sont les mêmes que ceux de l'outil rectangle : + + + +En appuyant sur Ctrl, vous pouvez dessiner un cercle ou une ellipse de ratio entier (2:1, 3:1, etc.). + + + + +En appuyant sur Maj, vous pouvez dessiner autour du point de départ. + + + + +Intéressons-nous aux poignées d'une ellipse. Sélectionnez l'ellipse suivante : + + + + +une fois de plus, vous ne voyez d'abord que trois poignées, mais en fait il y en a quatre. Celle de droite est en fait deux poignées qui se superposent et qui permettent "d'ouvrir" l'ellipse. En déplaçant la première de ces poignées, la deuxième devient visible; déplacer ces poignées vous permettent d'obtenir toute sorte d'arcs ou de camemberts (portions d'ellipse en forme de part de tarte) : + + + + +Pour obtenir un camembert (un arc avec ses deux rayons), déplacez la poignée vers l'extérieur de l'ellipse; pour obtenir un arc, déplacez-la vers l'intérieur. Ci-dessus, vous pouvez voir 4 camemberts à gauche et 3 arcs à droite. Notez que les arcs sont des formes ouvertes, c'est à dire que le contour court le long de l'ellipse mais ne relie pas les extrémités de l'arc. Ceci devient évident si vous supprimez le remplissage, ne gardant visible que le contour : + + + + + + + 15 + + CamembertsArcs + +Voyez le groupe de camemberts ressemblant à un ventilateur sur la gauche. Le créer a été facile, en déplaçant les poignées par incréments d'angle avec la touche Ctrl. Voici les raccourcis des poignées arc/camembert : + + + + +En appuyant sur Ctrl, forcez des modifications d'angle par incréments de 15 degrés lors des déplacements de ces poignées. + + + + +Maj+cliquer sur ces poignées permet de refermer ces arcs/camemberts pour en refaire des ellipses. + + + + +L'incrément d'angle par défaut peut être modifié dans les préférences d'Inkscape (dans l'onglet Incréments). + + +Les deux autres poignées d'une ellipse sont utilisées pour la redimensionner autour de son centre. Les raccourcis qui y sont associés sont similaires à ceux des poignées d'arrondi d'un rectangle : + + + + +Déplacez-les tout en appuyant sur Ctrl pour faire un cercle (garder les deux rayons égaux). + + + + +Ctrl+cliquer sur une de ces poignées permet de transformer l'ellipse en cercle sans déplacer de poignée. + + + + +Et, tout comme les poignées de redimensionnement d'un rectangle, ces poignées permettent d'ajuster la largeur et la hauteur d'une ellipse dans son propre système de coordonnées. Ce qui signifie qu'une ellipse qui a été tournée ou inclinée peut facilement être redimensionnée parallèlement à ses axes. Essayez de modifier les dimensions de ces ellipses en utilisant leurs poignées de redimensionnement : + + + + + + + +Etoiles + +Les étoiles sont les formes les plus complexes et les plus intéressantes. Si vous voulez épater vos amis avec Inkscape, laissez-les s'amuser un peu avec l'outil étoile. Il est particulièrement amusant — ça devient presque une drogue ! + + +L'outil étoile permet de créer deux types de formes similaires : des étoiles et des polygones. Une étoile a deux poignées dont les positions définissent la longueur et la forme de ses branches; un polygone n'a qu'une poignée qui permet en la déplaçant de redimensionner et tourner ce polygone : + + +EtoilePolygone + +Dans la barre de contrôle de l'outil étoile vient d'abord une boîte permettant de passer du mode étoile à polygone et inversement. Puis un champ numérique permet de définir le nombre de sommets d'une étoile ou d'un polygone. Ce paramètre n'est modifiable que depuis cette barre de contrôle, et peut varier de 3 (évidemment) à 1024, mais vous devriez éviter d'entrer un trop grand nombre (disons, plus de 200) si votre ordinateur n'est pas très puissant. + + +Quand vous dessinez une nouvelle étoile ou un nouveau polygone, + + + + +Déplacez une poignée en appuyant sur Ctrl pour forcer des modifications d'angle par incréments de 15 degrés. + + + + +Par nature, une étoile est une des formes les plus intéressantes (bien qu'en pratique les polygones soient souvent plus utiles). Les deux poignées d'une étoile ont des fonctions légèrement différentes. La première poignée (lors de la création de l'étoile, elle se trouve sur une pointe, c'est à dire un coin convexe de l'étoile) permet d'allonger ou raccourcir les branches de l'étoile, mais si vous la tournez (relativement au centre de la forme), l'autre poignée accompagne cette rotation. Ceci implique que vous ne pouvez pas incliner les branches de l'étoile avec cette poignée. + + +Par contre, l'autre poignée (située initialement sur un coin concave entre deux pointes) est libre de se déplacer radialement et tangentiellement, sans affecter la poignée au bout d'une pointe (en fait cette poignée peut devenir à son tour la poignée de pointe si elle est déplacée plus loin du centre que l'autre poignée). Avec cette poignée, vous pouvez incliner les branches de l'étoile pour obtenir toutes sortes de cristaux, mandalas et flocons : + + + + +Si vous voulez juste obtenir une étoile simple, sans de telles dentelles, vous pouvez restreindre le comportement de cette poignée de façon à éviter toute inclinaison : + + + + +Déplacer la poignée en appuyant sur Ctrl permet de garder l'étoile strictement radiale (sans inclinaison). + + + + +Ctrl+cliquer sur la poignée permet de supprimer l'inclinaison sans la déplacer. + + + + +En complément utile des possibilités de déplacement des poignées sur le canevas, la barre de contrôle comprend un champ Ratio des rayons qui définit le rapport entre les distances séparant chacune des poignée du centre. + + +Les étoiles d'Inkscape ont deux astuces de plus dans leur sac. En géométrie, un polygone est une forme composée de segments de droites avec des coins anguleux. Dans le monde réel, un certain degré de courbure est parfois présent — et Inkscape peut gérer cela aussi. Cependant, arrondir une étoile ou un polygone est un peu différent d'arrondir un rectangle. Vous n'avez pas de poignée dédiée à cette operation, mais, + + + + +Maj+cliquer-déplacer tangentiellement une poignée permet d'arrondir une étoile ou un polygone. + + + + +Maj+cliquer sur une poignée permet de supprimer l'arrondi. + + + + +"Tangentiellement" signifie dans une direction perpendiculaire à celle d'un rayon. Si vous 'tournez' une poignée en sens anti-horaire, vous augmentez l'arrondi; en sens horaire, vous le diminuez (voyez plus loin ci-dessous pour des exemples d'arrondi négatif). + + +Voici une comparaison entre un carré arrondi (issu de l'outil rectangle) et un quadrilatère arrondi (issu de l'outil étoile) : + + +PolygonearrondiRectanglearrondi + +Comme vous pouvez le voir, alors qu'un rectangle arrondi a des côtés droits et des coins arrondis (circulairement ou elliptiquement), un polygone ou une étoile arrondi n'a aucun segment rectiligne; ses courbures varient régulièrement entre un maximum (dans les coins) et un miminum (entre deux coins). Inkscape opère ceci en ajoutant deux tangentes de Bézier colineaires à chaque nœud de la forme (vous pouvez les voir en convertissant la forme en chemin et en l'examinant avec l'outil nœud). + + +Le paramètre d'arrondi que vous pouvez ajuster dans la barre de contrôle est le rapport entre la longueur de ces tangentes et celle du côté adjacent de l'étoile/polygone. Ce paramètre peut être négatif, inversant ainsi la direction des tangentes. Des valeurs de 0.2 à 0.4 donnent une courbure 'normale' (assez courante); des valeurs plus importantes conduisent à des formes superbes, inextricables et totalement imprévisibles. Une étoile avec une grande valeur d'arrondi peut facilement dépasser les limites fixées habituellement par ses poignées. Voici quelques exemples, indiquant chacun sa valeur d'arrondi : + + +0.250.250.250.370.433.00-3.000.415.431.850.21-3.00-0.43-8.940.39 + +Si vous voulez que les pointes d'une étoile soient pointues et que les creux soient arrondis ou l'inverse, il suffit simplement de créer un offset (Ctrl+J) de cette étoile : + + +Etoile originaleOffset lié, érodéOffset lié, dilaté + +Maj+cliquer-déplacer les poignées d'une étoile dans Inkscape est une des plus merveilleuses activités connues de l'être humain. Mais on peut faire encore mieux. + + +Afin d'imiter encore mieux les formes du monde réel, Inkscape peut rendre aléatoires (c'est à dire déformer aléatoirement) ses étoiles et polygones. Un peu de hasard rend une étoile moins régulière, plus 'humaine', souvent amusante; un hasard plus important est une façon distrayante d'obtenir toute une variété de formes complètement imprédictibles. Une étoile arrondie garde des courbures douces quand elle est rendue aléatoire. Voici les raccourcis : + + + + +Alt+cliquer-déplacer tangentiellement une poignée permet de rendre une étoile ou un polygone aléatoire. + + + + +Alt+cliquer sur une poignée permet de supprimer le hasard. + + + + +Lors de l'édition (avec les poignées) d'une étoile aléatoire, celle-ci 'tremblera' car chaque position précise de ses poignées correspond à une unique quantité de hasard. Donc, déplacer une poignée sans appuyer sur Alt réinitialise ce hasard en conservant son niveau, tandis que Alt+cliquer-déplacer préserve ce hasard mais ajuste son niveau. Voici des étoiles dont les paramètres sont identiques, mais chacune d'entre elle a vu sa quantité de hasard mise à jour en déplaçant très légèrement sa poignée (la quantité de hasard varie de 0.1 tout au long de la figure suivante) : + + + + +Et voici l'étoile du milieu de la figure ci-dessus, avec une quantité de hasard variant entre -0.2 et 0.2 : + + ++0.2+0.10-0.1-0.2 + +Essayez de Alt+cliquer-déplacer une poignée de l'étoile du milieu de la figure ci-dessus et observez comment elle passe de la forme de celle de gauche à la forme de celle de droite — et même au delà. + + +Vous trouverez probablement vos propres applications aux étoiles aléatoires, j'avoue aimer particulièrement les éclaboussures en forme d'amibes et les grandes planètes irrégulières aux paysages fantastiques : + + + + + + + + +Spirales +Les spirales d'Inkscape sont des formes versatiles, et bien qu'elles ne soient pas aussi captivantes que les étoiles, elles sont parfois utiles. Une spirale, comme une étoile, est dessinée autour de son centre; lors de sa création tout comme lors de son édition, + + + + +Déplacez une poignée en appuyant sur Ctrl pour forcer des modifications d'angle par incréments de 15 degrés. + + + + +Une fois créée, une spirale possède deux poignées, intérieure et extérieure. Les deux poignées peuvent être simplement déplacées pour enrouler ou dérouler (c'est à dire la prolonger, en modifiant le nombre de ses tours) la spirale. Voici les autres raccourcis : + + +Poignée extérieure : + + + + +Maj+cliquer-déplacer permet de redimensionner/tourner la spirale autour de son centre (sans l'enrouler ou la dérouler). + + + + +Alt+cliquer-déplacer pour verrouiller le rayon de la spirale pendant que vous l'enroulez ou la déroulez. + + + + +Poignée intérieure : + + + + +Alt+cliquer-déplacer verticalement permet de faire converger/diverger la spirale. + + + + +Alt+cliquer permet de remettre la divergence à zéro. + + + + +Maj+cliquer permet de déplacer la poignée intérieure au centre. + + + + +La divergence d'une spirale est la mesure de la non-linéarité de ses enroulements. Quand la divergence vaut 1, la spirale est uniforme; inférieure à 1 (Alt+cliquer-déplacer vers le haut), la spirale devient plus dense à sa périphérie; supérieure à 1 (Alt+cliquer-déplacer vers le bas), la spirale est plus dense en son centre : + + +0.20.5621 + +Le nombre maximum de tours d'une spirale est 1024. + + +Tout comme l'outil ellipse ne se limite pas aux ellipses, mais permet de créer des arcs (des lignes à la courbure constante), l'outil spirale permet de créer des lignes à la courbure variant régulièrement. Comparé à une courbe de Bézier, un arc de spirale est souvent plus pratique car vous pouvez l'allonger ou le racourcir en déplaçant une poignée le long de la courbe sans modifier sa forme. De plus, alors qu'une spirale est habituellement dessinée sans remplissage, vous pouvez en ajouter un et retirer le contour afin d'obtenir des effets intéressants. + + + + +Les spirales avec des contours en pointillés sont particulièrement intéressantes — elles combinent la concentration naturelle de la forme avec l'espacement régulier des pointillés pour fournir de superbes effets de moiré : + + + + + + + +Conclusion +Les outils de formes d'Inkscape sont particulièrement puissants. Initiez-vous à leurs astuces à loisir — ce sera payant pour tout travail de design car, utiliser des formes au lieu de chemins rend la création d'un dessin vectoriel plus rapide et sa modification plus facile. Si vous avez des idées pour améliorer d'une façon quelconque les outils de formes, n'hésitez pas à contacter les développeurs. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/share/tutorials/tutorial-shapes.ja.svg b/share/tutorials/tutorial-shapes.ja.svg new file mode 100644 index 000000000..be625883b --- /dev/null +++ b/share/tutorials/tutorial-shapes.ja.svg @@ -0,0 +1,600 @@ + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ::シェイプ + + + + + + + + +このチュートリアルは4つのシェイプツールについて説明している: 矩形、楕円、星型、螺旋。Inkscapeのシェイプで何ができるかについて披露し、どのような場合にどのように使用するかについて示す。 + + +Ctrl+Arrows、 mousewheel、もしくは middle button dragを使いページを下にスクロールせよ。オブジェクトの作成、選択、変形の基本については、Help >ヘルプ > チュートリアル から基本チュートリアルを見よ。 + + + + +Inkscape には多用途の4つのシェイプツールがあり、どのツールもシェイプの作成と編集をすることができる。シェイプはドラッグ可能なハンドルと形を決めている数値パラメータを使用して、シェイプに特有の方法で変更を加えることが可能なオブジェクトである。 + + +例えば、星型では頂点の数、長さ、角度、丸めその他を変更することができるが、星型は星型のままである。形状は、単純なパスより"自由度が少ない" 、しかしときにそれはより興味深く便利である。シェイプはいつでもパスに変換することができる(Ctrl+Shift+C)、しかし逆に変換することはできない。 + + +シェイプツールは、矩形、楕円、星型、螺旋である。はじめに、一般的にどう働くか見てみよう;それから各シェイプについてみてみよう。 + + + + +一般的な用法 +新しいシェイプは、対応するツールでキャンバスを dragして作成する。一度、作成されると(そして選択されている限り)、ドラッグすることで直ちに形状の編集が可能なひし形のハンドルが表示される。 + + +4種のシェイプは全て、ノードツールと同じくシェイプツールでハンドルを表示する(F2)。ますカーソルをハンドルの上に置くと、ステータスバーにハンドルが異なる修飾キーを押した場合にドラッグやクリックでどう変化するかが表示される。 + + +また、各シェイプツールはツールコントロールバー(キャンバスの上)に、パラメータを表示する。通常そこにはいくつかの数値入力域と既定値に戻す一つのボタンがある。現在ののツールタイプのオブジェクトが選択されると、コントロールバーの値を変更すると選択したシェイプが変形する。 + + +ツールコントロールに加えられた変更は、記憶されてツールを使って次のオブジェクトを描くときに使用される。例えば、星型の頂点の数を変更したあと新規に作成した星型の頂点数は前に描いた星の頂点数になる。さらに、選択してツールコントロールバーに値を反映しただけでも、新しい星型にはその値が適用される。 + + +シェイプツールを使用しているときオブジェクトの上でclickすると選択が可能である。Ctrl+click (グループから選択)と、Alt+Click(隠れているオブジェクトの選択)もセレクタツールと同様に働く。 Escで選択は解除される。 + + + + +矩形 +矩形は簡単だがおそらくデザインやイラストで最も一般的なシェイプだろう。Inkscape は矩形の作成と編集をできる限り簡単かつ便利に行えるように設計されている。 + + +F4を押すかツールバーのボタンを押して矩形ツールに切り替える。新しく矩形をこの青い矩形の横に描いてみよ: + + +draw here + +そして、矩形ツールを抜けることなく、クリックして他の矩形に選択を切り替えよ。 + + +矩形描画のショートカット: + + +Ctrlを押しながら、整数の縦横比(2:3、3:1等)で正方形や矩形を描画。 + +Shiftを押しながら、始点を中心点として描画。 + + + +見てのとおり選択された矩形(出来たての矩形はつねに選択状態にある)には3つのハンドルが角にある。実際には4つのハンドルがあるが、そのうちの2つ(右上)は矩形の角が丸まっていないときには重なってる。この2つは丸めハンドル;他の2つはリサイズハンドルである。 + + +はじめに丸めハンドルを見てみよう。そのうちの一つをつかんで引き下げてみよう。矩形の4つの角がまるくなり、角の元の場所に2つ目の丸めハンドルが見えたはずだ。円状に丸めたいのであればこれだけで事足りる。もし一方の角をより遠くまで丸めたいのであればもう一つのハンドルを左に動かすことが出来る。 + + +最初の2つは角を円状に丸めた矩形、他の2つは角を楕円状に丸めた矩形: + + +Elliptic rounded cornersCircular rounded corners + +矩形を選択して、矩形ツールの丸めハンドルについてもう少しみてみよう。 + + +しばしば、角を持つシェイプの丸め半径と形状は作品全体にわたり一定であることが必要である。矩形の大きさが異なっていても(色々な大きさの角を丸めた箱で描かれた図を考えて欲しい)これは必要なことである。Inkscape でこれを実現するのは容易である。セレクタツールに切り替え;ツールコントロールバーに4つのトグルボタンがあり、その左から2番目に同心の丸めた角が表示されている。このボタンで、丸めた角を、矩形がスケールされたときに丸めをスケールするかを制御する方法である。 + + +例えば、ここにオリジナルの赤い矩形と、"丸めた角にスケールをかける" ボタンをオフにして複製され、スケールを掛けたいくつかの矩形がある: + + +Scaling rounded rectangles with "Scale rounded corners" OFF + +右上で全てのすべて丸めた角が正確に一致して、矩形の角の形か等しいのを確認して欲しい。全ての破線で描かれた矩形は元の赤い矩形から派生したものでセレクタでスケールだけを掛けてあり、丸めハンドルでの調整は行っていない。 + + +比較のために、同じ画像を "丸めた角にスケールをかける" ボタンをオンにして作成した: + + +Scaling rounded rectangles with "Scale rounded corners" ON + +今や、丸めた角は属する矩形と同じぐらいに違っている、そして右上の角ではわずかな一致も見られない(ズームインして見よ)。これは、元の矩形をパスに変換(Ctrl+Shift+C)して、それをパスとしてスケールした場合と同じ(視覚的)結果である。 + + +矩形の丸めハンドルのショートカットには: + + +Ctrlを押しながらドラッグして、もう一方の半径を等しくする(円状の丸め)。 + +Ctrl+clickでドラッグしないでもう一方の半径を同じにする。 + + +Shift+click で丸めを取り除く。 + + + +矩形ツールのコントロールバーには水平(Rx)と垂直(Ry)の丸め半径が表示されており、どの単位を使っても正確に半径を設定することができることに注意。鋭利に ボタンは選択した矩形から丸めを取り除く意味である。 + + +コントロールを使うことの重要な利点は、たくさんの矩形に一度に効力を及ぼすことが出来ることである。例えば、もしレイヤー内の全ての矩形を変更したい場合、Ctrl+A(全てを選択)とコントロールバーのパラメータを必要な値に設定するだけである。もし、矩形でないオブジェクトが選択されていたとしてもそれらは無視され矩形のみが変更される。 + + +今度は、矩形のリサイズハンドルを見てみよう。あなたは不思議に思うだろう、なぜこれが必要なのか、セレクタでうまく矩形をリサイズできるのではないか? + + +セレクタの問題点は、セレクタの水平と垂直の概念はつねにドキュメントページの水平と垂直であることだ。決まりとして、矩形のリサイズハンドルは、矩形が回転しても歪んでいても、矩形の辺に沿ってスケールを行う。例えば、最初にセレクタでリサイズした矩形を次に矩形ツールのリサイズツールでリサイズしてみよ: + + + + +リサイズハンドルは2つあるので、どの方向へもリサイズすることができるし、辺に沿って移動することさえ可能だ。リサイズハンドルはつねに丸め半径を保持している。 + + +リサイズハンドルのショートカットは: + + + +Ctrlを押してドラッグすることで、矩形の辺や対角線をスナップする。言い換えると、Ctrlは、矩形の幅、高さのどちらか、もしくは縦横比を保持する(再び言うが、回転していても歪んでいても矩形の座標系で)。 + + + +ここに上図と同じ矩形がある、灰色の破線はリサイズハンドルがCtrlを押しながらドラッグしたときに張り付く方向を示している(試してみよ): + + +Snapping of rectangle resize handles with Ctrl + + + + + + + +傾けたり回転した矩形を複製しリサイズハンドルでリサイズして、3Dの構図を簡単に作ることができる: + + +3 originalrectanglesSeveral rectanglescopied and resizedby handles,mostly with Ctrl + +丸めやグラディエントのフィルを使った矩形の構図の例をさらに挙げる: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +楕円 +楕円ツール(F5)は楕円や円を作成することができる。楕円や円は弧や扇形にも変換できる。描画のショートカットは矩形ツールと同じである: + + + +Ctrlを押しながら、整数の縦横比(2:3、3:1等)で楕円を描画。 + +Shiftを押しながら、始点を中心点として描画。 + + + +楕円のハンドルをいじってみよう。この楕円を選択せよ: + + + + +またもや、3つのハンドルがあることに気が付いたと思う、しかし実は4つなのだ。左のハンドルは楕円を "開く"ことの出来る2つのハンドルが重なっている。右にあるハンドルをドラッグするともう一つのハンドルが下から見える。これで弧や扇形を作ることができる: + + + + +扇形(弧と2つの半径からなる)を作るには、楕円の外側をドラッグし; 弧を作るためには内側をドラッグする。上図の左側には4つの扇形、右側には3つの弧がある。弧は閉じていないシェイプであることをに注意せよ、つまりストロークは楕円にそっているが端点はつながっていない。フィルを削除してストロークだけにするとそのことは明らかになる: + + + + + + + 15 + + SegmentsArcs + +左図にあるせまい扇形は、 Ctrlを押しながら角度をスナップすることで簡単に作ることが出来る。弧/扇形のショートカットは: + + + +Ctrlを押しながらドラッグするとハンドルは15度ごとにスナップする。 + +Shift+click で楕円全形になる(弧や扇形ではなく)。 + + + +スナップ角度は Inkscape 設定(変化度タブ)で変更できる。 + + +楕円のその他の2つハンドルは中心まわりのリサイズに使用する。ショートカットは矩形の丸めハンドルに似ている: + + + +Ctrlを押しながらドラッグで、円になる(もう一方の半径が等しくなる)。 + +Ctrl+click でドラッグしないで円を作成。 + + + +そして、矩形のリサイズハンドルの様に、楕円のリサイズハンドルも楕円の高さと幅を楕円の座標系で変更する。これは回転したりや歪んだりしている楕円でも、回転や歪みはそのままで元の座標系に沿って伸張したり圧縮したりできることを意味する。これらの楕円のリサイズハンドルでリサイズを試してみよ: + + + + + + + +星形 +星形はもっとも複雑で刺激的な Inkscape のシェイプだ。もし友人を Inkscape で驚かせるなら、星形ツールを使わせよう。これはもう飽きの来ない面白さ、まさに中毒的! + + +星形ツールは2つの良く似た、しかし異なった種類のオブジェクト、星形と多角形を作成する。星型は頂点の長さと形を決める2つのハンドルを持つ:多角形はドラッグして回転とリサイズを行う1つのハンドルを持つ: + + +StarPolygon + +まずコントロールバーにはチェックボックスがある。これは星型を多角形に、また逆に変換する。次に、星形と多角形の頂点数を設定する入力域。このパラメータはコントロールバーでしか編集できない。許されている数値は3(明白である)から1024までである、しかしコンピュータが遅い場合には、大きな値(200以上)は入れるべきではない。 + + +新規に星形や多角形を作るときは、 + + + +Ctrlを押しながらドラッグすると角度の増分が15度にスナップされる。 + + + +生来、星形は断然面白いシェイプである(しかし、多角形はしばしばより有用である)。星型の二つのハンドルはわずかに異なる機能を持っている。はじめのハンドル(初期状態で頂点にあるハンドル、つまり星形の凸な角にある方)は星の光芒を長くしたり短くしたりする、しかし、ハンドルを回すと(シェイプの中心で相対的に)、もう一方のハンドルもそれに応じて回転する。このことは星型の光芒はこのハンドルでは歪められないことを意味する。 + + +もう一方のハンドル(初期状態で頂点の間の凹な角にある)は、逆に、半径方向にも接線方向にも頂点ハンドルに影響をあたえずに自由に動く(実際、このハンドルはもう一方のハンドルより遠くに動いて頂点になることもできる)。このハンドルは星型の頂点を歪ませ、光芒をあらゆる種類の結晶型、曼荼羅模様、雪片形、ヤマアラシ形にする: + + + + +もし、飾りのない普通の星形を作りたいなら、ハンドルの歪みの動きを規制することができる: + + + + +Ctrlを押しながらドラッグすることで、光芒を半径方向に限定することができる(歪みなし)。 + +Ctrl+click でドラッグをせずに歪みをとることができる。 + + + +キャンバス上でのハンドルのドラッグの有用な補足として、2つのハンドルの中心からの距離の比、スポーク比 がコントロールバーにある。 + + +Inkscape の星形はまだ2つの仕掛けを隠している。幾何学の世界では多角形は鋭角から直線の辺を持つ。しかし現実世界では様々な度数の曲がりや丸さが存在する、そして Inkscape もそれを実現可能としている。しかし、多角形の丸めは矩形の丸めとは少し異なる作用をする。丸めのために、用意されたされたハンドルを使う必要がないのである、しかし + + + +接線方向にShift+drag で星形や多角形を丸めることができる。 + +Shift+click で丸めを取り除くことができる。 + + + +"接線方向" は中心方向とは直角と言う意味である。Shift を押しながらハンドルを反時計方向に "回転" すると、丸めの値は正になり; 時計方向に回すと負の丸めになる(下の負の丸めの例を見よ)。 + + +ここで、丸めた正方形(矩形ツール)と丸めた正4角形(星形ツール)を比較する: + + +RoundedpolygonRoundedrectangle + +見て分かるように、丸めた矩形は辺に直線区間と円弧状(一般的には楕円弧)の区間がある、丸めた多角形と星形には直線区間が全くない;曲率は最大(角の部分)から最小(角と角の中間)へと滑らかに変化する。 Inkscapeはただ連続なベジェのハンドルをシェイプの頂点に追加しているだけである(シェイプをパスに変換すればベジェハンドルを見ること、調べることができる)。 + + +コントロールバーの丸めパラメータは接線と近接する多角形/星形の辺の長さの比である。このパラメータは負の値を取りうる。負の場合は接線の向きを反転する。0.2から0.4の値であると予測した "普通" の丸めになる;他の値にすると美しい、入り組んだ、予測不可能な形になる傾向がある。大きな丸め値の星形はハンドルの位置を大きく上回る形状になる。いくつかの例を示す、数値は丸め値を表す: + + +0.250.250.250.370.433.00-3.000.415.431.850.21-3.00-0.43-8.940.39 + +頂点を鋭く、凹な辺を滑らかにしたい場合、もしくはその逆の形状がほしい場合、星形からオフセット(Ctrl+J)を作ることで簡単に実現できる: + + +Original starLinked offset, insetLinked offset, outset + +Inkscape の星形のハンドルをShift+dragすることは、人間の最もすばらしい楽しみである。しかしもっと楽しむことができる。 + + +現実世界の形状により似せるために、Inkscape は星形と多角形に乱雑さを備えている(つまり、乱雑なひずみ)。わずかな乱雑さは、星形を少し乱す、より人間らしく、より可笑しく;強い乱雑さは様々な熱狂的予測不可能な形状を作り出すための刺激的な方法である。丸めを施した星形は乱雑さを加えても丸まったままである。ショートカットは: + + + +ハンドルを接線方向にAlt+dragすると、星形と多角形は乱雑になる。 + +ハンドルをAlt+click すると乱雑さが取り除かれる。 + + + +乱雑な星形を描いたり、ハンドルをドラッグして編集したりすると星形は "振動" する。なぜならハンドルの固有の位置はその固有の乱雑さに対応しているからである。そう、Alt を押しながら乱雑さを調整しないと、同じ乱雑さのレベルでハンドルは動く、一方 Alt を押しながらドラッグすると乱雑さは変らず同じレベルを保つ。ここに少しだけハンドルを動かして乱雑にした(乱雑さは 0.1 まで)以外は同じパラメータをもつ星形がある: + + + + +そして、ここに上の真中の星形の乱雑さを -0.2 から 0.2 まで変化させたものがある: + + ++0.2+0.10-0.1-0.2 + +真ん中の星形のハンドルをAlt+dragして、左右の、そしてさらに隣の星形に変形していくところを観察せよ。 + + +そのうち、自分なりの乱雑な星形の使い道が見つかるだろう、しかし私は特に丸めたアメーバ状のしみと大きく荒れた幻想的な稜線をもつ惑星の形が気に入っている: + + + + + + + +螺旋 +Inkscape の螺旋は多機能なシェイプである、そして星形ほど夢中になれないが、ときにとても有用である。螺旋は星形のように中心から描画される;これは描画中も編集中と同様である、 + + + +Ctrl+drag で角度の増分を15度にスナップする。 + + + +描画されると、螺旋は内側と外側の端点に2つのハンドルをもつ。どちらのハンドルも螺旋を巻いたり、解いたりする(つまり、"続けて" 巻き数を変える)。その他のショートカット: + + +外側のハンドル: + + + +Shift+dragで螺旋の中心からのスケール/回転(巻き/解きはしない)。 + +Alt+drag で、巻き/解きの間、半径を固定する。 + + + +内側のハンドル: + + + +Alt+drag 垂直に動かすと収束/発散。 + +Alt+click で収束/発散を取り消し。 + +Shift+click で内側のハンドルを中心に移動。 + + + +螺旋の発散度は巻きの非線形度の尺度である。 発散度が1なら、螺旋は一様である; これが1より小さければ(Alt+dragで上)、外周で密度が高くなる;1より大きければ(Alt+dragで下)、中心に向かって密度が高くなる: + + +0.20.5621 + +巻き数の最大値は 1024 である。 + + +楕円ツールが楕円だけでなく弧(曲率が一定の線)も作成できるように、螺旋ツールは滑らかに変化する曲線を作ることもできる。通常のベジェ曲線に比べ、弧や螺旋はより利便性が高い、なぜなら形状に変更を加えずに曲線に沿ってハンドルを動かすことで長くしたり短くしたりできるからだ。また通常、螺旋はフィルなしで描かれるが、フィルの追加やストロークの削除で面白い効果が出せる。 + + + + +特に面白いのは螺旋に破線のストロークを与えることである。滑らかな収束と等間隔の印(点や短い線)は相まって美しいモアレ効果となる: + + + + + + + +最後に +Inkscape のシェイプツールはとても強力である。技術を学び、暇なときに遊んでみることはあなたがデザインを行うときに力になる、なぜなら簡単なパスの代わりにシェイプを使うことでベクタアートを速く作り、簡単に変更することができるからだ。もし、さらなるシェイプの改善の提案があれば、開発者に連絡して欲しい。 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/share/tutorials/tutorial-shapes.sl.svg b/share/tutorials/tutorial-shapes.sl.svg new file mode 100644 index 000000000..4a2004b98 --- /dev/null +++ b/share/tutorials/tutorial-shapes.sl.svg @@ -0,0 +1,751 @@ + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ::LIKI + + + + + + + +Ta vodič obsega štiri orodja za like: pravokotnik, elipsa, zvezda in spirala. +Pokazali vam bomo zmogljivosti Inkscapovega orodja za like in predlagali, kako in kdaj +jih je smiselno uporabiti. + + +Uporabite Ctrl+smerne tipke, miškino kolesce ali poteg s pritisnjenim srednjim gumbom, da se premaknete po strani navzdol. Za osnove ustvarjanja, izbiranja in preoblikovanja objektov glejte vodič Osnove v meniju Pomoč > Vodiči. + + + + +Inkscape vsebuje štiri vsestranska orodja za risanje likov, z vsakim od njih pa lahko ustvarite in urejate določen tip likov. Lik je predmet, ki mu lahko spreminjate izgled preko različnih parametrov: preko premičnih ročic in številčnih vrednosti. + + +Zvezdi lahko npr. spreminjate število krakov, njihovo dolžino in +kot – pa vendar zvezda ostane zvezda. Lik je bolj +omejen kot pa pot, po drugi strani pa je bolj zanimiv in uporaben. Lik +lahko vedno spremenite v pot (Ctrl+Shift+C), obratna sprememba pa ni mogoča. + + +Orodja za like so: Pravokotnik, Elipsa, Zvezda in Spirala. +Najprej si bomo pogledali, kako orodja za risanje oblik delujejo v +splošnem, nato pa bomo podrobno raziskali posamezna orodja. + + + + +Splošni nasveti +Nov lik ustvarite z vlečenjem po platnu z ustreznim orodjem. +Ko je lik ustvarjen (in dokler je izbran), prikazuje svoje ročice +kot bele rombaste znake, z vlečenjem katerih lahko takoj +spreminjate svojo stvaritev. + + +Vse štiri vrste likov prikazujejo svoje ročice v vseh štirih Orodjih za +like, kot tudi v Orodju za urejanje vozlišč (F2). +Ko lebdite z miško nad ročico, se v statusni vrstici prikaže +namig, ki pove, kaj se zgodi, ko ročico potegnete ali nanjo kliknete, ter pokaže tudi vse dodatne možnosti, ki so pri tem na voljo. + + +Vsako Orodje za like prikazuje svoje možnosti v Nadzorni vrstici orodja +(ki leži nad platnom). Ponavadi vsebuje +nekaj številskih vnosnih polj in gumb za ponastavitev privzetih +vrednosti. Če je na platnu izbran lik oziroma več likov, jih lahko preoblikujete tudi s spreminjanjem vrednosti v Nadzorni vrstici. + + +Vse spremembe, ki jih naredite v nastavitvah orodja se ohranijo v +spominu, in bodo uporabljene za naslednji predmet, ki ga s tem orodjem narišete. +Ko npr. spremenite število krakov pri zvezdi, ima tudi naslednja zvezda enako število +krakov. Še več, celo sama izbira lika na platnu spremeni vrednosti v nadzorni vrstici +in določi vrednosti za novoustvarjene like enake vrste. + + +Ko delate z Orodjem za like, lahko predmet izberete s klikom nanj. +Ctrl+klik (izberi v skupini) in Alt+klik +(izberi pod) delujeta prav tako kot pri orodju za izbiranje. Tipka Esc +pa prekliče izbiro. + + + + +Pravokotniki +A Pravokotnik je najenostavnejši, a verjetno najpogosteje uporabljan lik v oblikovanju. Inkscape poskuša ustvarjanje in +spreminjanje pravokotnikov narediti kolikor je mogoče enostavno in +pripravno. + + +Na orodje za pravokotnike preklopite s pritiskom na tipko F4 ali s +sklikom na gumb v orodjarni. Ob modrem pravokotniku narišite novega: + + +draw here + +Ne da bi zapustili Orodje za pravokotnike, preklopite +izbor iz enega pravokotnika na drugega s klikom nanj. + + +Bližnjice za risanje pravokotnikov: + + +S tipko Ctrl boste narisali kvadrat ali pravokotnik s +stranicama v razmerju celih števil (2:1, 3:1, itd.). + +S tipko Shift boste pravokotnik narisali iz središčne točke. + + + +Kot lahko vidite, izbran pravokotnik (pravkar narisan pravokotnik je +vedno izbran) prikazuje tri ročice v treh vogalih. V bistvu obstajajo +štiri ročice, vendar se dve od njih (v zgornjem desnem kotu) prekrivata, +če pravokotnik ni zaobljen. Ti dve ročici sta ročici za zaobljenje; +drugi dve (zgoraj levo in spodaj desno) pa sta ročici za umerjanje. + + +Poglejmo najprej ročici za zaobljenje. Zgrabite eno od ročic in potegnite +dol. Vsa oglišča pravokotnika se zaoblijo, hkrati pa lahko zdaj +vidite drugo ročico za zaobljenje - v oglišču je ostala v prvotni legi. +Če želite krožno zaobljena oglišča, je to vse, kar morate storiti. +Če želite oglišča bolj zaobljiti ob eni kot ob drugi stranici, +premaknite proti drugo ročico v levo. + + + +Na tej sliki imata prva dva pravokotnika krožno zaobljena oglišča (druga +ročica ni uporabljena), druga dva pa imata eliptično zaobljena oglišča: + + +Elliptic rounded cornersCircular rounded corners + +Ne zapuščajte orodja za pravokotnike, temveč s klikom izberite te +pravokotnike in si oglejte položaje njihovih ročic za zaobljenje. + + + +Pogosto morata biti polmer in oblika zaobljenih oglišč v okviru celotne kompozicije konstantna, čeprav so pravokotniki različnih velikosti (predstavljajte si diagrame s polji z zaobljenimi robovi različnih +velikosti). Inkscape to poenostavi. Preklopite na orodje za izbiranje; +v vrstici za nadzor je skupina gumbov in drugi z leve +prikazuje dve koncentrično zaobljeni oglišči. S tem določate, ali se pri bo pri raztegovanju pravokotnika ustrezno večala ali manjšala tudi zaobljenost oglišča, ali naj le-ta ostaja stalna. + + +Tukaj je npr. izvirni rdeč pravokotnik večkrat kopiran, kopije pa so različno povečane ali pomanjšane, opcija "Spreminjaj zaobljena oglišča z likom" pa je izključena: + + +Scaling rounded rectangles with "Scale rounded corners" OFF + +Bodite pozorni na velikost in obliko zaobljenih oglišč, ki so enaka +pri vseh pravokotnikih, tako da so zaobljena oglišča v zgornjem desnem kotu popolnoma enaka. Vsi modri pikčasti pravokotniki so kopije originalnega rdečega +pravokotnika - z Izbirnikom smo le spreminjali le njihovo velikost, zaobljenost oglišč pa smo pustili pri miru. + + +Za primerjavo je tukaj enaka kompozicija, tokrat ustvarjenja z +vključeno opcijo "Spreminjaj zaobljena oglišča z likom": + + +Scaling rounded rectangles with "Scale rounded corners" ON + +Tokrat so zaobljena oglišča relativna glede na velikost lika in se v zgornjem desnem kotu ne skladajo (približajte za +boljši pogled). Enak (vizualni) učinek bi dobili tudi s pretvorbo izvirnega pravokotnika +v pot (Ctrl+Shift+C), ki bi ji potem spreminjali velikost. + + +Bližnjice za ročice za zaobljenje pravokotnikov: + + +Vlecite s pritisnjeno tipko Ctrl, da drug polmer postane enak +(krožno zaobljenje). + +S kombinacijo Ctrl+klik drug polmer postane enak brez vlečenja. + + +Shift+klik odstrani zaobljenje. + + + +Verjetno ste opazili, da nadzorna vrstica za izbran pravokotnik prikazuje vodoravni (Rx) +in navpični (Ry) polmer zaobljenja ter vam omogoča natančno nastavljanje v katerikoli dolžinski meri. +Gumb "Nezaobljeno" naredi ravno to - iz izbranih +pravokotnikov odstrani zaobljenje. + + +Pomembna prednost teh nastavitev je, da lahko vplivajo na več pravokotnikov hkrati. +Če želite spremeniti vse pravokotnike v sloju, označite vse s kombinacijo +Ctrl+A (Izberi vse) in nastavite potrebne +parametre v vrstici z nastavitvami. Če so izbrani tudi liki, ki niso pravokotniki, +nanje sprememba parametrov ne bo vplivala. + + +Poglejmo zdaj pravokotnikove ročice za umerjanje. Morda se +sprašujete, zakaj jih sploh potrebujemo, ko pa lahko spreminjamo velikost pravokotnika tudi z Izbirnikom? + + +Težava Izbirnika je v tem, da vedno deluje glede na stran. Nasprotno pa s pravokotnikovimi +ročicami velikost spreminjamo vzporedno s pravokotnikovimi +stranicami, tudi če je pravokotnik zasukan ali nagnjen. Kot primer +poizkusite spremeniti velikost spodnjega pravokotnika najprej z Izbirnikom, nato pa +še z ročicami v Orodju za pravokotnike: + + + + +Z ročicama za spreminjanje velikosti lahko prvokotnik raztezate v +vse smeri ali ga celo premaknete vzporedno s stranicami. Ročice za +spreminjanje velikosti vedno ohranjajo polmer zaobljenja. + + +Bližnjice za ročice za spreminjanje velikosti: + + + + +Spreminjanje velikosti stranic ob pritisnjeni tipki Ctrl ohrani širino ali višino, ali pa +razmerje med širino in višino v pravokotniku. (v lastnem +koordinatnem sistemu, ki je lahko zasukan ali nagnjen). + + + + +Tu je enak pravokotnik, sive črtkane črte pa prikazujejo smeri, +ki se jih držijo ročice za umerjanje, ko jih vlečete s tipko +Ctrl (poskusite): + + +Snapping of rectangle resize handles with Ctrl + + + + + + + +S vrtenjem in nagibanjem pravokotnika, ki ga nato kopiramo in mu z ročicami spremenimo velikost, lahko enostavno ustvarimo trodimenzionalne kompozicije: + + +3 originalrectanglesSeveral rectanglescopied and resizedby handles,mostly with Ctrl + +Še nekaj primerov pravokotniških kompozicij, vključno z +zaobljenjem in prelivnimi polnili: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Elipse +Z orodjem za elipse (F5) lahko ustvarjate elipse in kroge, te pa lahko nato spremenite v odseke ali loke. Bližnjice za risanje so enake bližnjicam +Orodja za pravokotnike: + + + +S tipko Ctrl boste narisali krog ali elipso v razmerju celih +števil (2:1, 3:1, itd.) + +S tipko Shift boste pravokotnik ali elipso narisali iz središčne točke. + + + +Raziščimo ročice elipse! Izberite to: + + + + +Ponovno najprej vidite tri ročice, čeprav so v resnici štiri. Na desni sta dve +prekrivajoči se ročici, ki vam omogočata "odpiranje" +elipse. Potegnite desno ročico, nato pa potegnite še ročico, ki postane +vidna pod njo, da dobite različne odseke tortnega diagrama ali loke: + + + + +Če želite dobiti odsek (lok in dva polmera), vlecite +zunaj elipse; če pa želite dobiti lok, vlecite znotraj elipse. +Zgoraj so štirje odseki na levi in trije loki na desni strani. Bodite pozorni na +loke, ki niso zaprti liki - obroba gre okrog elipse, vendar ne poveže koncev +loka. To postane očitno, če odstranite polnilo in ostane le obroba: + + + + + + + 15 + + SegmentsArcs + +Poglejte skupino na levi. Enostavno jo je ustvariti z uporabo +preskakovanja kotov s tipko Ctrl. +Bližnjice za ročice lokov/odsekov: + + + +S Ctrl bo ročica med vlečenjem delala korake po 15 stopinj. + +Uporabite Shift+klik, da narišete elipso celo (torej ne samo loka ali odseka. + + + +Kot koraka lahko spremenite v Splošnih nastavitvah +(zavihek Koraki). + + +Drugi dve ročici sta namenjeni spreminjanju velikosti okrog središča +in delujeta podobno kot ročici za zaobljenje pri pravokotniku: + + + +Vlecite s Ctrl, da narišete krog (oba polmera sta enaka). + +S Ctrl+klik narišete krog brez vlečenja. + + + +Kot pravokotnikove ročice za spreminjanje velikosti tudi ročice elipse +prilagodijo višino in širino elipse v njenih koordinatah. +To pomeni, da se elipsa razteguje ali krči po svojih lastnih oseh, tudi če je zasukana ali nagnjena - tudi med spreminjanjem velikosti bo ostala zasukana oz. nagnjena. Poizkusite z ročicami spremeniti velikost katerekoli od spodnjih elips: + + + + + + + +Zvezde +Zvezde so najbolj kompleksni in najbolj zanimivi Inkscapovi liki. +Če želite nad Inkscapom navdušiti prijatelje, jim pokažite Orodje +za zvezde. Neskončno zabavno je - popolnoma zasvajujoče! + + +Z Orodjem za zvezde lahko ustvarite dve podobni, a vendar različni +vrsti predmetov: zvezde in mnogokotnike. Zvezda ime dve ročici, +katerih položaja določata dolžino in obliko krakov; mnogokotnik ima +le eno ročico, s katero pri potegu zavrtimo mnogokotnik ali pa mu spremenimo velikost: + + +StarPolygon + +Prvo polje v vrstici za nadzor orodja za zvezde omogoča spremembo zvezde v +ustrezen mnogokotnik in obratno. Naslendnje določa število +vrhov (pri zvezdah so to kraki, pri mnogokotnikih pa oglišča). Vnesete lahko vrednosti od 3 +(očitno) do 1024, vendar pa ne uporabljajte visokih vrednosti (preko 200), +če imate počasen računalnik. + + +Ko rišete novo zvezdo ali mnogokotnik, + + + +Vlecite s pritisnjeno tipko Ctrl za povečanje kota v korakih po 15 stopinj. + + + +Seveda je zvezda veliko bolj zanimiva oblika (čeprav je pri delu +mnogokotnik pogosto bolj uporaben). Ročici zvezde imata rahlo +različni funkciji. Prva ročica (prvotno na vrhu kraka, torej na +izbočenem oglišču zvezde) vam omogoča daljšanje in krajšanje +zvezdinih krakov, ko pa jo zasukate (relativno glede na središče lika), +se skladno zasuka tudi druga ročica. To pomeni, da s to ročico +zvezdinih krakov ne morete nagniti. + + +Drugo ročico (prvotno na vbočenem oglišču, med dvema krakoma) +lahko, nasprotno, prosto premikate radialno in tangencialno, ne da bi +vplivali na ročico na vrhu kota. (Pravzaprav lahko ta ročica postane +ročica na vrhu kota, če jo premaknemo bolj stran od središča kot +prvo ročico.) S to ročico lahko nagibamo zvezdine krake, in tako dobime različne vrste kristalov, mandal, snežink in ježkov: + + + + +Če želite preprosto zvezdo brez okraskov, lahko ročici za nagnjenost začasno odvzamete sposobnost nagibanja: + + + +Vlecite s Ctrl in kraki bodo povsem radialni (brez nagnjenosti). + +S kombinacijo Ctrl+klik odstranite nagnjenost brez vlečenja. + + + +V nadzorni vrstici je tudi polje Razmerje višine krakov, ki določa razmerje med razdaljama obeh ročic do središča. + + +Inkscapove zvezde pa skrivajo še nekaj trikov. V geometriji je +mnogokotnik lik z ravnimi stranicami in ostrimi koti. V realnem svetu pa so lahko prisotne tudi različne stopnje ukrivljenosti in zaobljenosti — Inkscape zna narediti tudi to. Zaobljenje zvezde ali mnogokotnika +deluje nekoliko drugače kot zaobljenje pravokotnika, saj za to ne +potrebujete posebne ročice, temveč: + + + +Pritisnite Shift+vlecite tangencialno na ročico, da zaobljite zvezdo/mnogokotnik. + +Uporabite Shift+kliknite na ročico, da odstranite zaobljenje. + + + +"Tangencialno" pomeni pravokotno na smer proti središču. +Če ročico "zavrtite" s tipko Shift v obratni smeri urinega kazalca okrog +središča, dobite pozitivno zaobljenost; z rotacijo v smeri urinega +kazalca pa dobite negativno zaobljenost. (Spodaj glejte primere +negativne zaobljenosti.) + + +Tu je primerjava zaobljenega kvadrata (Orodje za pravokotnike) z +zaobljenim 4-straničnim mnogokotnikom (Orodje za zvezde): + + +RoundedpolygonRoundedrectangle + +Kot lahko vidite, ima zaobljen pravokotnik ravne stranice in krožno +(ponavadi eliptično) zaobljena oglišča; zaobljen mnogokotnik ali +zvezda pa nimata nobene ravne črte; ukrivljenost se spreminja od +največje (v ogliščih) do najmanjše (na sredini med oglišči) z gladkimi prehodi. Inkscape to naredi z dodajanjem istosmernih Bezierjevih tangent vsakemu vozlišču lika (vidite jih lahko, če lik pretvorite v pot in si jo ogledate z Orodjem za vozlišča). + + +Vrednost "Zaobljenost", ki jo lahko nastavite v nadzorni vrstici, je razmerje med dolžino teh tangent in dolžino +mnogokotnikovih/zvezdinih stranic, ki ob njih ležijo. Ta vrednost je lahko +negativna, kar obrne smer tangent. Vrednosti od približno 0,2 do 0,4 +povzročijo "normalno" zaobljenje, torej takšno, kot bi ga pričakovali; +druge vrednosti težijo k ustvarjanju lepih, kompliciranih in povsem +nepredvidljivih vzorcev. Zvezda z visoko vrednostjo zaobljenosti +lahko seže daleč preko položaja svojih ročic. Tukaj je nekaj primerov, +ki kažejo vrednost zaobljenosti: + + +0.250.250.250.370.433.00-3.000.415.431.850.21-3.00-0.43-8.940.39 + +Če želite, da so vrhovi zvezde ostri, vbokline pa zaobljene, ali pa obratno, to +najlažje dosežete, če iz zvezde ustvarite zamik (Ctrl+J): + + +Original starLinked offset, insetLinked offset, outset + +Vlečenje zvezdinih ročic s pritisnjeno tipko Shift je eno izmed najbolj zabavnih opravil v Inkscapu. Pa vendar je zadeva še boljša! + + +Za boljšo imitacijo oblik iz resničnega sveta lahko Inkscape +naključno popači zvezde in mnogokotnike. +Majhno popačenje naredi zvezdo manj pravilno, bolj človeško, +pogosto smešno; močno popačenje je zanimiv način za +doseganje zanimivih in nepredvidljivih oblik. Zaobljena zvezda ostane +po naključnem popačenju še vedno gladko zaobljena. Bližnjice: + + + +Uporabite Alt+potegnite ročico tangencialno za naključno popačenje zvezde/mnogokotnika. + +Uporabite Alt+kliknite na ročico da odstranite vsa naključna popačenja. + + + +Ko rišete ali s potegom ročic spreminjate popačeno zvezdo, le-ta +"trepeta" saj vsaka posamezna pozicija njenih ročic odgovarja +posameznemu popačenju. Vsak premik ročice brez uporabe tipke Alt torej ponovno popači lik na isti stopnji popačenosti, Alt+poteg pa +obdrži enako popačenost, vendar ji spreminja stopnjo. Tu +so zvezde s popolnoma enakimi parametri, vsaka od njih pa je +ponovno popačena z rahlim pomikom ročice (stopnja +popačenja je vedno 0,1): + + + + +In tukaj je srednja zvezda iz prejšnje vrstice s stopnjo popačenosti +od -0,2 to 0,2: + + ++0.2+0.10-0.1-0.2 + +Uporabite Alt+potegnite ročico srednje zvezde v tej vrstici; opazujte, kako se preoblikuje v sosednje zvezde na desni in levi in preko njih. + + +Verjetno ima vsak svojo najljubšo zvezdo; meni so všeč predvsem zaobljene, amebam podobne packe in veliki, +grobi planeti s sanjskimi pokrajinami: + + + + + + + +Spirale +Inkscapovo Orodje za spirale je precej vsestransko in je, čeprav ni +tako fascinantno kot Orodje za zvezde, včasih zelo uporabno. +Podobno kot zvezdo tudi spiralo rišemo in spreminjamo iz središča; + + + +Uporabite Ctrl+vlecite za povečevanje kota v korakih po 15 stopinj. + + + +Narisana spirala ima dve ročici - na notranjem in zunanjem koncu. +Če ju povlečemo, obe ročici navijeta ali odvijeta spiralo (jo +"nadaljujeta" oz. spreminjata število vrtljajev). Ostale bližnjice so: + + +Zunanja ročica: + + + +Uporabite Shift+vlecite, da zavrtite spiralo okrog središča (brez navijanja/odvijanja) oziroma ji spremenite velikost. + +Uporabite Alt+vlecite, da zaklenete polmer med navijanjem/odvijanjem. + + + +Notranja ročica: + + + +Uporabite Alt+poteg navpično za zgoščevanje/redčenje. + +Alt+klik ponastavi zgoščevanje. + +Shift+klik premakne notranjo ročico v središče. + + + +Zgoščevanje spirale je stopnja spremenljivosti vrtljajev. +Ko je vrednost enaka 1, je spirala enakomerna; ko je vrednost manjša od 1 +(Alt+poteg gor), spirala postane gostejša na robu; ko je vrednost +večja od 1 (Alt+poteg dol), je spirala gostejša proti središču. + + +0.20.5621 + +Največje število obratov spirale je 1024. + + +Podobno kot Orodje za elipse ni uporabno le za risanje elips, temveč +tudi za risanje lokov (ćrte s stalno ukrivljenostjo), je Orodje za spirale +uporabno tudi za ustvarjanje krivulj z gladko spremenljivo +ukrivljenostjo. V primerjavi z enostavnimi Bezierjevimi krivuljami sta lok ali spirala +pogosto bolj uporabna, ker ju lahko skrajšate ali podaljšate z vlečenjem +ročice ob krivulji, ne da bi s tem tudi spremenili njuno obliko. Poleg tega pa lahko spirali dodate tudi polnilo, obrobo, ali oboje, in tako ustvarite zanimive učinke. + + + + +Zanimive so tudi spirale, ki uporabljajo pikčasto obrobo, saj združujejo enakomerno zgoščevanje lika z enakomerno oddaljenimi pikami oz. črticami v lepe efekte moire: + + + + + + + +Zaključek +Inkscapova orodja za risanje oblik so zelo močna. Naučite se njihovih posebnosti +in se z njimi igrajte v prostem času – to se bo verjetno izplačalo že pri +prvem resnem oblikovanju, saj uporaba likov namesto poti pogosto +pohitri oblikovanje, spreminjanje pa poenostavi. V kolikor imate kakršnekoli ideje +za nadaljnje izboljšave tega orodja, vas prosimo, da kontaktirate razvijalce. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/share/tutorials/tutorial-shapes.svg b/share/tutorials/tutorial-shapes.svg new file mode 100644 index 000000000..bbcfdbed0 --- /dev/null +++ b/share/tutorials/tutorial-shapes.svg @@ -0,0 +1,766 @@ + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ::SHAPES + + + + + + + +This tutorial covers the four shape tools: Rectangle, Ellipse, Star, and Spiral. +We will demonstrate the capabilities of Inkscape shapes and show +examples of how and when they could be used. + + +Use Ctrl+Arrows, mousewheel, or middle button +drag to scroll the page down. +For basics of object creation, selection, and transformation, see the Basic +tutorial in Help > Tutorials. + + + + +Inkscape has four versatile shape tools, each tool capable of +creating and editing its own type of shapes. A shape is an object which you can modify +in ways unique to this shape type, using draggable handles and +numeric parameters that determine the shape's appearance. + + +For example, with a star you can alter the number of tips, their length, angle, +rounding, etc. — but a star remains a star. A shape is "less free" than a simple +path, but it's often more interesting and useful. You can always convert a shape +to a path (Ctrl+Shift+C), but the reverse conversion is not possible. + + +The shape tools are Rectangle, Ellipse, +Star, and Spiral. First, let's look at how +shape tools work in general; then we'll explore each shape type in detail. + + + + +General tips +A new shape is created by dragging on canvas with the +corresponding tool. Once the shape is created (and so long as it is +selected), it displays its handles as white diamond-shaped marks, so +you can immediately edit what you created by dragging these handles. + + +All four kinds of shapes display their handles in all four shape tools as well as in the +Node tool (F2). When you hover your mouse over a handle, it tells you +in the statusbar what this handle will do when dragged or clicked with different modifiers. + + +Also, each shape tool displays its parameters in the Tool Controls +bar (which runs horizontally above the canvas). Usually it has a few numeric +entry fields and a button to reset the values to defaults. When shape(s) of the current +tool's native type are selected, editing the values in the Controls bar changes the +selected shape(s). + +Any changes made to the Tool Controls are remembered and used for the next object you +draw with that tool. For example, after you change the number of tips of a star, new +stars will have this number of tips as well when drawn. Moreover, even simply selecting +a shape sends its parameters to the Tool Controls bar and thus sets the values for newly +created shapes of this type. + + +When in a shape tool, selecting an object can be done by clicking +on it. Ctrl+click (select in group) and Alt+Click +(select under) also work as they do in Selector tool. Esc deselects. + + + + +Rectangles +A rectangle is the simplest but perhaps the most common shape in +design and illustration. Inkscape attempts to make creating and +editing rectangles as easy and convenient as possible. + + +Switch to the Rectangle tool by F4 or by clicking its toolbar button. +Draw a new rectangle alongside this blue one: + + +draw here + +Then, without leaving the Rectangle tool, switch selection from one +rectangle to the other by clicking on them. + + +Rectangle drawing shortcuts: + + +With Ctrl, draw a square or an integer-ratio (2:1, 3:1, etc) rectangle. + +With Shift, draw around the starting point as center. + + + +As you see, the selected rectangle (the just-drawn rectangle is always selected) shows +three handles in three of its corners. In fact, these are four handles, but two of them +(in the top right corner) overlap if the rectangle is not rounded. These two are the +rounding handles; the other two (top left and bottom right) are +resize handles. + + +Let's look at the rounding handles first. Grab one of them and drag down. All four +corners of the rectangle become rounded, and you can now see the second rounding handle +— it stays in the original position in the corner. If you want circular rounded +corners, that is all you need to do. If you want corners which are rounded farther along +one side than along the other, you can move that other handle leftwards. + + +Here, the first two rectangles have circular rounded corners, and the other two have +elliptic rounded corners: + + +Elliptic rounded cornersCircular rounded corners + +Still in the Rectangle tool, click on these rectangles to select, and +observe their rounding handles. + + +Often, the radius and shape of the rounded corners must be constant within the entire +composition, even if the sizes of the rectangles are different (think diagrams with +rounded boxes of various sizes). Inkscape makes this easy. Switch to the Selector tool; +in its Tool Controls bar, there's a group of four toggle buttons, the second from the +left showing two concentric rounded corners. This is how you control whether the +rounded corners are scaled when the rectangle is scaled or not. + + +For example, here the original red rectangle is duplicated and scaled several times, up +and down, to different proportions, with the "Scale rounded corners" button +off: + + +Scaling rounded rectangles with "Scale rounded corners" OFF + +Note how the size and shape of the rounded corners is the same +in all rectangles, so that the roundings align exactly in the top +right corner where they all meet. All the dotted blue rectangles are +obtained from the original red rectangle just by scaling in Selector, +without any manual readjustment of the rounding handles. + + +For a comparison, here is the same composition but now created +with the "Scale rounded corners" button on: + + +Scaling rounded rectangles with "Scale rounded corners" ON + +Now the rounded corners are as different as the rectangles they belong to, and there +isn't a slightest agreement in the top right corner (zoom in to see). This is the same +(visible) result as you would get by converting the original rectangle to a path +(Ctrl+Shift+C) and scaling it as path. + + +Here are the shortcuts for the rounding handles of a rectangle: + + +Drag with Ctrl to make the other radius the same (circular rounding). + +Ctrl+click to make the other radius the same without dragging. + + +Shift+click to remove rounding. + + + +You may have noticed that the Rectangle tool's Controls bar shows the horizontal +(Rx) and vertical (Ry) rounding radii for +the selected rectangle and lets you set them precisely using any length units. The +Not rounded button does what is says — removes rounding from +the selected rectangle(s). + +An important advantage of these controls is that they can affect many rectangles +at once. For example, if you want to change all rectangles in the layer, just do +Ctrl+A (Select All) and set the parameters you need +in the Controls bar. If any non-rectangles are selected, they will be ignored — only +rectangles will be changed. + + +Now let's look at the resize handles of a rectangle. You might wonder, +why do we need them at all, if we can just as well resize the rectangle +with Selector? + + +The problem with Selector is that its notion of horizontal and vertical is always that +of the document page. By contrast, a rectangle's resize handles scale it along +that rectangle's sides, even if the rectangle is rotated or skewed. For +example, try to resize this rectangle first with Selector and then with its resize +handles in Rectangle tool: + + + + +Since the resize handles are two, you can resize the rectangle into +any direction or even move it along its sides. Resize handles +always preserve the rounding radii. + + +Here are the shortcuts for the resize handles: + + + +Drag with Ctrl to snap to the sides or the diagonal of +the rectangle. In other words, Ctrl preserves either width, or height, +or the width/height ratio of the rectangle (again, in its own coordinate system which +may be rotated or skewed). + + +Here is the same rectangle, with the gray dotted lines showing the +directions to which the resize handles stick when dragged with +Ctrl (try it): + + +Snapping of rectangle resize handles with Ctrl + + + + + + + +By slanting and rotating a rectangle, then duplicating it and resizing with its resize +handles, 3D compositions can be created easily: + + +3 originalrectanglesSeveral rectanglescopied and resizedby handles,mostly with Ctrl + +Here are some more examples of rectangle compositions, including +rounding and gradient fills: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Ellipses +The Ellipse tool (F5) can create ellipses and circles, which you can +turn into segments or arcs. The drawing shortcuts are the same as +those of the rectangle tool: + + + +With Ctrl, draw a circle or an integer-ratio (2:1, 3:1, etc.) ellipse. + +With Shift, draw around the starting point as center. + + + +Let's explore the handles of an ellipse. Select this one: + + + + +Once again, you see three handles initially, but in fact they are four. The rightmost +handle is two overlapping handles that let you "open" the ellipse. Drag that rightmost +handle, then drag the other handle which becomes visible under it, to get a variety +of pie-chart segments or arcs: + + + + +To get a segment (an arc plus two radii), drag +outside the ellipse; to get an arc, drag +inside it. Above, there are 4 segments on the left and 3 arcs on +the right. Note that arcs are unclosed shapes, i.e. the stroke only goes along the +ellipse but does not connect the ends of the arc. You can make this obvious if you +remove the fill, leaving only stroke: + + + + + + + 15 + + SegmentsArcs + +Note the fan-like group of narrow segments on the left. It was easy +to create using angle snapping of the handle with Ctrl. Here are the +arc/segment handle shortcuts: + + + +With Ctrl, snap the handle every 15 degrees when dragging. + +Shift+click to make the ellipse whole (not arc or segment). + + + +The snap angle can be changed in Inkscape Preferences (the Steps tab). + + +The other two handles of the ellipse are used for resizing it around its center. Their +shortcuts are similar to those of the rounding handles of a rectangle: + + + +Drag with Ctrl to make a circle (make the other radius the same). + +Ctrl+click to make a circle without dragging. + + + +And, like the rectangle resize handles, these ellipse handles adjust the height and +width of the ellipse in the ellipse's own coordinates. This means +that a rotated or skewed ellipse can easily be stretched or squeezed along its original +axes while remaining rotated or skewed. Try to resize any of these ellipses by their +resize handles: + + + + + + + +Stars +Stars are the most complex and the most exciting Inkscape shape. If you want to wow your +friends by Inkscape, let them play with the Star tool. It's endlessly entertaining +— outright addictive! + + +The Star tool can create two similar but distinct kinds of objects: stars and +polygons. A star has two handles whose positions define the length and shape of its +tips; a polygon has just one handle which simply rotates and resizes the polygon when +dragged: + + +StarPolygon + +In the Controls bar of the Star tool, first comes a checkbox to turn a star into the +corresponding polygon and back. Next, a numeric field sets the number of +vertices of a star or polygon. This parameter is only editable via the +Controls bar. The allowed range is from 3 (obviously) to 1024, but you shouldn't try +large numbers (say, over 200) if your computer is slow. + + +When drawing a new star or polygon, + + + +Drag with Ctrl to snap the angle to 15 degree increments. + + + +Naturally, a star is a much more interesting shape (though polygons are often more +useful in practice). The two handles of a star have slightly different functions. The +first handle (initially it is on a vertex, i.e. on a convex corner +of the star) makes the star rays longer or shorter, but when you rotate it (relative to +the center of the shape), the other handle rotates accordingly. This means you cannot +skew the star's rays with this handle. + + +The other handle (initially in a concave corner between two +vertices) is, conversely, free to move both radially and tangentially, without affecting +the vertex handle. (In fact, this handle can itself become vertex by moving farther from +the center than the other handle.) This is the handle that can skew the star's tips to +get all sorts of crystals, mandalas, snowflakes, and porcupines: + + + + +If you want just a plain regular star without any such lacework, you +can make the skewing handle behave as the non-skewing one: + + + +Drag with Ctrl to keep the star rays strictly radial (no skew). + +Ctrl+click to remove the skew without dragging. + + + +As a useful complement for the on-canvas handle dragging, the Controls bar has the +Spoke ratio field which defines the ratio of the two handles' +distances to the center. + + +Inkscape stars have two more tricks in their bag. In geometry, a polygon is a shape with +straight line edges and sharp corners. In the real world, however, various degrees of +curvilinearity and roundedness are normally present — and Inkscape can do that +too. Rounding a star or polygon works a bit differently from rounding a rectangle, +however. You don't use a dedicated handle for this, but + + + +Shift+drag a handle tangentially to round the star or polygon. + +Shift+click a handle to remove rounding. + + + +"Tangentially" means in a direction perpendicular to the direction to the center. If you +"rotate" a handle with Shift counterclockwise around the center, you get positive +roundedness; with clockwise rotation, you get negative roundedness. (See below for +examples of negative roundedness.) + + +Here's a comparison of a rounded square (Rectangle tool) with a rounded 4-sided polygon +(Star tool): + + +RoundedpolygonRoundedrectangle + +As you can see, while a rounded rectangle has straight line segments in its sides and +circular (generally, elliptic) roundings, a rounded polygon or star has no straight +lines at all; its curvature varies smoothly from the maximum (in the corners) to the +minimum (mid-way between the corners). Inkscape does this simply by adding collinear +Bezier tangents to each node of the shape (you can see them if you convert the shape to +path and examine it in Node tool). + + +The Rounded parameter which you can adjust in the Controls bar is the +ratio of the length of these tangents to the length of the polygon/star sides to which +they are adjacent. This parameter can be negative, which reverses the direction of +tangents. The values of about 0.2 to 0.4 give "normal" rounding of the kind you would +expect; other values tend to produce beautiful, intricate, and totally unpredictable +patterns. A star with a large roundedness value may reach far beyond the positions of +its handles. Here are a few examples, each indicating its roundedness value: + + +0.250.250.250.370.433.00-3.000.415.431.850.21-3.00-0.43-8.940.39 + +If you want the tips of a star to be sharp but the concaves smooth or vice versa, this +is easy to do by creating an offset (Ctrl+J) +from the star: + + +Original starLinked offset, insetLinked offset, outset + +Shift+dragging star handles in Inkscape is one of the finest pursuits +known to man. But it can get better still. + + +To closer imitate real world shapes, Inkscape can randomize (i.e. +randomly distort) its stars and polygons. Slight randomization makes a star less +regular, more humane, often funny; strong randomization is an exciting way to obtain a +variety of crazily unpredictable shapes. A rounded star remains smoothly rounded when +randomized. Here are the shortcuts: + + + +Alt+drag a handle tangentially to randomize the star or polygon. + +Alt+click a handle to remove randomization. + + + +As you draw or handle-drag-edit a randomized star, it will "tremble" because each unique +position of its handles corresponds to its own unique randomization. So, moving a handle +without Alt re-randomizes the shape at the same randomization level, while Alt-dragging +it keeps the same randomization but adjusts its level. Here are stars whose parameters +are exactly the same, but each one is re-randomized by very slightly moving its handle +(randomization level is 0.1 throughout): + + + + +And here is the middle star from the previous row, with the randomization level varying +from -0.2 to 0.2: + + ++0.2+0.10-0.1-0.2 + +Alt+drag a handle of the middle star in this row and observe as it +morphs into its neighbors on the right and left — and beyond. + + +You will probably find your own applications for randomized stars, but I am especially +fond of rounded amoeba-like blotches and large roughened planets with fantastic +landscapes: + + + + + + + +Spirals +Inkscape's spiral is a versatile shape, and though not as immersing as the star, +it is sometimes very useful. A spiral, like a star, is drawn from the center; while +drawing as well as while editing, + + + +Ctrl+drag to snap angle to 15 degree increments. + + + +Once drawn, a spiral has two handles at its inner and outer ends. Both handles, when +simply dragged, roll or unroll the spiral (i.e. "continue" it, changing the number of +turns). Other shortcuts: + + +Outer handle: + + + +Shift+drag to scale/rotate around center (no rolling/unrolling). + +Alt+drag to lock radius while rolling/unrolling. + + + +Inner handle: + + + +Alt+drag vertically to converge/diverge. + +Alt+click to reset divergence. + +Shift+click to move the inner handle to the center. + + + +The divergence of a spiral is the measure of nonlinearity of its +winds. When it is equal to 1, the spiral is uniform; when it is less than 1 +(Alt+drag upwards), the spiral is denser on the periphery; when it +is greater than 1 (Alt+drag downwards), the spiral is denser +towards the center: + + +0.20.5621 + +The maximum number of spiral turns is 1024. + + +Just as the Ellipse tool is good not only for ellipses but also for arcs (lines of +constant curvature), the Spiral tool is useful for making curves of smoothly +varying curvature. Compared to a plain Bezier curve, an arc or a spiral is +often more convenient because you can make it shorter or longer by dragging a handle +along the curve without affecting its shape. Also, while a spiral is normally drawn +without fill, you can add fill and remove stroke for interesting effects. + + + + +Especially interesting are spirals with dotted stroke — they combine the smooth +concentration of the shape with regular equispaced marks (dots or dashes) for beautiful +moire effects: + + + + + + + +Conclusion +Inkscape's shape tools are very powerful. Learn their tricks and play with them at your +leisure — this will pay off when you do your design work, because using shapes +instead of simple paths often makes vector art faster to create and easier to modify. If +you have any ideas for further shape improvements, please contact the developers. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/share/tutorials/tutorial-tips.es.svg b/share/tutorials/tutorial-tips.es.svg new file mode 100644 index 000000000..474a9a4de --- /dev/null +++ b/share/tutorials/tutorial-tips.es.svg @@ -0,0 +1,535 @@ + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ::TRUCOS Y CONSEJOS + + + + + + +Este tutorial mostrará varios trucos y consejos que los usuarios han aprendido a través +del uso de Inkscape y algunas caracterñsiticas y opciones "ocultas" que le ayudaran a aumentar +la velocidad en la producción de sus trabajos. + + + + +Colocación Radial con Colenes en Mosaico +Es sencillo observar como usar el diálogo Clones en Mosaico para rejillas rectangulares y +patrones. Pero que pasa si lo que necesita es colocación radial, donde +comparten los objetos un centro de rotación común? Esto también es posible! + +Si su patrón radial requiere tener sólo 3, 4, 6, 8 o 12 elementos, entonces usted puede intentar las +simetrías P3, P31M, P3M1, P4, P4M, P6, o P6M. Estas pueden funcionar perfecto para copos de nieve y similares. +Un método más general es el siguiente. + +Escoja la simetría P1 (traslación simple) y después compensar para que +esa traslación vaya a la pestaña Desplazamiento y configure Por +Fila/Y y Por columna/X ambos a -100%. Ahora todos +los clones serán colocados en la parte superior del original. Todo lo que queda por hacer es ir +a la pestaña Rotación y configurar con algún ángulo de rotación por columna, +después cree el patrón con una fila con múltiples columnas. Por ejemplo, he aquí un patrón hecho +a partir de una línea horizontal, con 30 columnas, cada columna rotada 6 grados: + + + + +Para obtener un radio de reloj, todo lo que tiene que hacer es cortar o simplemente superponer +la parte central mediante un círculo blanco (para hacer operaciones booleanas sobre clones, desconéctelos primero). + +Efectos más interesantes pueden ser creados mediante el uso de ambas filas y columnas. Aquí hay un patrón +con 10 columnas y 8 filas, con rotación de 2 grados por fila y 18 grados por +columna. Aquí cada grupo de líneas es una "columna", así los grupos están a 18 grados del otro; +en cada columna, líneas individuales están 2 grados aparte: + + + + +En los siguientes ejemplos, la línea fue rotada sobre su centro. Pero que pasa si usted desea +que el centro este afuera de la forma? Sólo cree un rectángulo invisible (sin relleno, sin borde) +el cual puede cubrir la forma y cuyo centro está en el punto que usted necesita, agrupe la forma y +el rectángulo y después use Clones en Mosaico sobre ese grupo. +Así es como puede hacer interesantes "explosiones" o "nebulosas" mediante la escala aleatoria, +rotación y posiblemente opcidad: + + + + + + + + + +Como hacer para crear rodajas (múltiples áreas rectangulares exportadas)? +Cree una nueva capa, en esa capa cree rectángulos infilenamevisibles cubriendo las partes que +usted imagine. Asegurese que sus documentos usan la unidad px (por defecto), active rejilla y ajuste +las rectas a la rejilla de tal manera que cada uno tenga un lapso de número entero de unidades px. Asigne ID's +representativas a las rectas y exporte cada uno en su propio archivo. Después las rectas +recordarán sus nombres de exportación. Después de eso, es muy sencillo re-exportar algunas algunas de las rectas: +cambie a exportar capa, use Tab para selccionada la que requiere (o use Buscar para id) y +de click en el diálogo Exportar. O, usted puede escribir archivos script o batch (por lotes) para exportar todas +sus áreas con un comando como: + +inkscape -i <area-id> -t <nombredelarchivo.svg> + +para cada área exportada. La opción -t le dice que use la pauta de nombre recordado, +de otra manera usted puede proveer el nombre de archivo con la opción -e. Alternativamente,usted puede +usar la utilidad svgslice la cual automatiza la exportación +desde documentos SVG de Inkscape, usando o una capa rodaja o guías. + + + + +Gradientes No-lineales +La versión 1.1 de SVG no soporta gradientes no-lineales (i.e. aquellos que poseen una +traslación no-lineal entre colores). Usted puede, sin embargo, los emula mediante +los gradientes multiparada. + + +Inicie con un simple gradiente dos-puntos. Abra el editor de Gradiente (e.g. mediante +doble-click en cualquier manejador de gradiente en la herramienta Gradiente). Agregue un nuevo punto de gradiente en +el medio; arrastrelo un poco. Entonces adiciones dos puntos más antes y después del punto medio y arrastrelos tanbién, +así el gradiente es suave. A mayor número de puntos que sean agregados, más suave va a ser el gradiente resultante. Aquí podemos observar el gradiente inicial negro-blanco con dos puntos: + + + + + + + + + + +Y aquí hay varios gradientes "no-lineales" multi-punto (examínelos en el Editor de +Gradientes): + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Gradientes Radiales Excentricos +Los gradientes radiales no tienen por que ser simétricos. En la herramienta Gradiente, arrastre el manejador central +de un gradiente elíptico con Mayus. Esto moverá el manejador de foco del gradiente lejos de su centro. cuando usted no lo necesite, puede ajustar el foco a un esto anterior arrastrándolo cerca del centro. + + + + + + + + + + + + + + + + + + + + + +Alineando al centro de la página +Para alinear algo al centro o lado de la página, seleccione el objeto o grupo y entonces escoja +Página desde la lista Relativo a: en el +diálogo Formato (Ctrl+Mayus+A). + + + + +Limpiar el documento +Algunos de gradientes-usados, patrones y marcas (más precisamente, aquella que ha editado manualmente) +permanecen en la patetas correspondientes y pueden ser reusadas para nuevos +objetos. Sin embargo si usted desea optimizar su documento, use el comando Eliminar +Defs en el menú archivo. El podrá remover gradientes, patrones o marcas +que no son usadas en el documento, haciendo el archivo más liviano. + + + + +Clips o máscaras en mapa de bits + +Por defecto, un mapa de bit importado (ejemplo una fotografía) en un elemento <imagen> el cual no es +editable por la herramienta Nodo. Para trabajar alrededor de estos, convierta esta imágen en un rectángulo +con relleno de patrón Objeto a Patrón (Alt+I). Esto le creará un rectángulo +relleno con su mapa de bits. Ahora este objeto puede ser convertido +a trazo, editado por nodos, intersectado con otras formas, etc. En las +Preferencias de Inkscape (pestaña Misc), usted puede configurar la opción +para que siempre importe mapa de bits como rectángulos rellenos de patrón. + + + + +Características ocultas del editor de XML +El editor de XML permite cambiar casi todos los aspectos del documento si usar un editor de texto externo. +Inkscape también soporta más funciones de SVG que las que son accesibles desde la Interfaz Gráfica. Por ejemplo, +ahora podemos soportar el mostrado de máscaras y clips, pero no existe una Interfaz Gráfica para crearlos o modificarlos. +El editor de XML es una vía para obtener acceso a estas funciones (si usted conoce del formato SVG). + + + + +Cambiando las unidades de medida de las reglas +En la plantilla por defecto, la unidad de medida usada por las reglas es el px ("unidad de usuario SVG", en Inkscape +esto es igual a 0.8pt o 1/90 de pulgada). Esta también es la unidad empleada en +el desplegado de coordenadas an la esquina inferior-izquierda y preseleccionada en todas los menús de unidades. (Usted +siempre puede situar el ratón sobre la regla para observar el mensaje con la unidad que usa.) Para cambiar esto, +abra las Preferencias de Documento y cambie las Unidades por defecto sobre la pestaña +Página. + + + + +Estampado +Para crear varias copias de un objeto, use estampado. Tan sólo +arrastre un objeto (o escálelo o rótelo), y mientras lo mantiene presionado con el ratón, presione +Barra Espaceadora. Esto permite una "estampilla" del objeto o forma actual. Usted puede +repetir tantas veces como lo desee. + + + + +Trucos de la herramienta Pluma +En la herramienta Pluma (Bezier), usted puede obtener las siguientes opciones para finalizar la línea actual: + + +Presione Enter + +Doble click con el botón izquiero del ratón + +Seleccione la herramienta Pluma de nuevo + +Seleccione otra herramienta + + + +Note que mientras el trazo no está finalizado (i.e. es mostrado verde, con el segmento actual +de color rojo) este no existe aún como un objeto en el documento. aemás, para cancelar esto, use +o Esc (cancela todo el trazo) o Barra Espaceadora +(remueva el último segmento del trazo sin finalizar) en vez del comando Deshacer. + + +Para agregar un nuevo subtrazo para un trazo existente, seleccione el trazoo y inicie a dibujar con +Mayus desde un punto arbitrario. Si, sin embargo, lo que quiere simplificarIf, however, what you want is to simply +continue an existing path, Mayus is not necessary; just start +drawing from one of the end anchors of the selected path. + + + + +Ingresando valores Unicode +Mientras este en la herramienta Texto, presionando Ctrl+U cambiaba entre modo +Unicode y normal. En modo Unicode, cada grupo de 4 dígito hexadecimales que usted ingrese +se convierten en un caracter sencillo Unicode, así permitiendo que usted ingrese símbolos +arbitrariamente (de la manera que usted conozca sus puntos de código Unicode y la fuente los +soporte). Para salir del modo Unicode, puede preionar Esc. +Por ejemplo, Ctrl+U 2 0 1 4 Esc inserta lo siguiente: (—). + + + + +Usando la rejilla para dibujar íconos +Supongamos que desea crear íconos de 24x24 pixeles. Cree una pizarra de 24x24 pixeles +(use Preferencias de Documento) y configure la pizarra a 0.5 px (48x48 líneas de rejilla). +Ahora, si desea alinear objetos rellenos hasta las líneas de rejilla, y +objetos bordeados a líneas de rejillas impares con el ancho del borde en +px siendo un número costante, y exportelos al por defecto 90dpi (así que 1 px se convierta en 1 pixel de +mapa de bits), uste puede obtener una imagen interesante sin necesidad de antializado. + + + + +Rotación de Objetos +Estando con la herramienta Selección, haga clicksobre un objeto para ver las flechas +de escalado, entonces haga click nuevamente sobre el objeto para observar +las flechas de rotación y cambio. Si +Las flechas en las esquinas son clickeadas y arrastradas, el objeto rotará alrededor del centro +(mostrado con una marca de cruz). Si mantiene presionada la tecla Mayus mientras +hace esto, la rotación será alrededor de la esquina opuesta. También puede arrastrar el centro +de rotación a cualquier lugar. + + +O, puede rotar desde el teclado presionando [ y ] +(por 15 grados) o Ctrl+[ y Ctrl+] (por 90 +grados). Las mismas teclas [] junto con Alt desarrollan +una lenta rotación a partir del tamaño de pixel. + + + + +Abrir diálogos como un objeto paleta +Si usted tiene un número pequeño de archivos SVG cuyos contenidos usa a menudo en otros +documentos, usted puede usar el diálogo Abrir como una paleta. Agregue el directorio con +sus fuentes SVG en la lista de favoritos de tal manera que pueda abrirlos rápidamente. Después +ese directorio mirando las vistas preliminares. Una vez haya encontrado el archivo que necesita, +simplemente arrastrelo a la pizarra y este será importado a su documento actual. + + + + +Mapa de bits arrojando sombras +Mientras Inkscape no soporte aún el filtro SVG para distorsión Gaussiana, usted puede crear fácilmente +distorsiones arrojando sombras de objetos como mapas de bits, por medio del comando +"Crear copia en Mapa de Bits" con un script de filtro. Observe share/extensions/inkscape-shadow.README +para detalles y limitaciones de este método. + + + + +Colocando texto sobre un trazo +Para colocar texto a lo largo de una curva, seleccione el texto y la curva y escoja +Poner en trayecto desde el menú Texto. El texto iniciará en el +principio del trazo. En general este es la mejor manera de crear un trazo explícito +del cual desea que el texto este ajustado, mejor que esto, ajústelo a otros elementos de dibujo +— esto le dará un mayor control sin tener que atornillarlo a su dibujo. + + + + +Selecting the original +When you have a text on path, a linked offset, or a clone, their source object/path may +be difficult to select because it may be directly underneath, or made invisible and/or +locked. The magic key Mayus+D will help you; select the text, linked +offset, or clone, and press Mayus+D to move selection to the +corresponding path, offset source, or clone original. + + + + +Recuperación de la salida de la ventana +Cuando mueve documentos entre diferentes sisemas con diferentes resoluciones o número de +pantallas, usted puede buscar que Inkscape haya guardado una posición de ventana +que ubica la ventana de manera correcta en la pantalla. Simplemente amplie la ventana (lo cual recuperará +la vista previa, para esto use la barra de tareas), guarde y recargue. Usted puede evitar esto, +deseleccionando la opción global para mantener la geometría de la ventana (Preferencias de Inkscape, +pestaña Ventanas). + + + + +Exporte de Trasparencias, gradientes y PostScript +Los formatos PostScript o EPS no admiten trasparencias, así que usted nunca +los emplea si los va a exportar a PS/EPS. En el caso de trsparencias planas las cuales superpongan +colores planos, es sencillo arreglar esto: seleccione uno de los +objetos trasparentes; cambie a la herramienta Cuentagotas (F7); +asegurese que este está en el modo "escoger color visible sin alfa"; de click sobre ese mismo +objeto. Este escogerá el color visible y lo asignará al objeto, pero esta vez sin +trasparencia. Repita para todos los objetos trasparentes. Si sus colores trasparentes +superponen múltiples áreas de color, usted necesitará el quebrales en piezas respectivamente +y aplicar este procedimiento a cada pieza. + + +Exportar gradientes a PS o EPS no funciona para texto +(a menos que este convertido a texto) o para bordes pintados. También, desde que la trasparencia +este perdida en el PS o EPS exportado, no los puede usar ejemplo. un gradiente desde un +azul opaco a un azul trasparente; Reemplaze por un +gradiente desde azul opaco a un color de fondo opaco. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/share/tutorials/tutorial-tips.fr.svg b/share/tutorials/tutorial-tips.fr.svg new file mode 100644 index 000000000..69df5be34 --- /dev/null +++ b/share/tutorials/tutorial-tips.fr.svg @@ -0,0 +1,472 @@ + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ::TRUCS ET ASTUCES + + + + + + +Ce didacticiel est là pour vous montrer divers trucs et astuces trouvés par des utilisateurs au cours de leur utilisation d'Inkscape, ainsi que quelques fonctionalités cachées qui peuvent vous aider à accélérer votre production. + + + + + +Disposition radiale grâce au pavage de clones + +Il est facile de comprendre comment se servir de la boîte de dialogue Paver avec des clones pour créer des motifs ou des grilles rectangulaires. Mais que faire si vous voulez un placement radial, où les objets partagent un même centre de rotation ? C'est possible aussi ! + + +Si votre motif radial ne doit comporter que 3, 4, 6, 8, ou 12 éléments, vous pouvez alors essayer les symétries P3, P31M, P3M1, P4, P4M, P6, ou P6M. Celles-ci offrent de bons résultats pour obtenir des flocons ou des formes similaires. Voici une méthode plus générale : + + +Choisissez la symétrie P1 (translation) puis compensez cette translation en allant dans l'onglet Translation et définissez Par ligne/Translation Y et Parr colonne/Translation X à -100%. Les clones seront alors empilés juste au-dessus de l'original. Tout ce qu'il reste à faire est d'aller dans l'onglet Rotation et définir un angle par colonne, puis créer le motif avec une ligne et plusieurs colonnes. Par exemple, voici un motif fait d'une ligne horizontale et de 30 colonnes, chacune de ces colonnes étant tournée de 6 degrés : + + + + +Pour en faire un cadran, il suffit de découper ce motif ou recouvrir sa partie par un disque blanc (pour effectuer des opérations booléennes sur des clones, déliez-les d'abord) + + +Des effets plus intéressants peuvent créés en utilisant à la fois les lignes et les colonnes. Voici un motif de 10 colonnes et 8 lignes, avec une rotation de 2 degrés par lignes et 18 par colonne. Chaque groupe de segments ici est "une colonne", donc les groupes sont séparés entre eux de 18 degrés; en sein de chaque "colonne", les segments sont séparés de 2 degrés : + + + + +Dans les exemples ci-dessus, le segment a été tourné autour de son centre. Et au cas où vous voudriez que le centre soit en-dehors de votre forme ? Il suffit de créer un rectangle invisible (sans remplissage ni contour) recouvrant votre forme et dont le centre est à l'emplacement désiré; groupez la forme et le rectangle puis utilisez Paver avec des clones sur ce groupe. Vous pouvez maintenant créer des belles "explosions" ou "éclaboussures" en rendant aléatoire le redimensionnement, la rotation ou l'opacité : + + + + + + + + + + +Trancher plusieurs zones d'export rectangulaires + +Créez un nouveau calque, et dans ce calque, créez des rectangles invisibles recouvrant des parties de votre image. Assurez-vous que votre document adopte le px (défini par défaut) comme unité, affichez la grille et faites coller les rectangles à cette grille de sorte que chacun d'entre-eux comporte un nombre entier de px. Assignez des ids significatifs aux rectangles, et exportez chacun d'entre-eux dans un fichier différent (chacun des rectangles se "souviendra" ainsi de son nom de fichier d'export). Après cela, il est facile de réexporter certains de ces rectangles : passez dans le calque d'export, utilisez Tab pour sélectionner celui dont vous avez besoin (ou utilisez une Recherche par id), et enfin cliquez sur Exporter dans la boîte de dialogue Exporter en bitmap. Vous pouvez aussi écrire un script shell (ou un fichier batch) pour exporter ces zones avec une commande telle que : + + +inkscape -i <area-id> -t <nomdefichier.svg> + + +pour chaque zone. L'option -t rappelle à Inkscape d'utiliser le nomdefichier enregistré avec la zone; sinon vous pouvez fournir un autre nom pour l'export avec l'option -e. Une autre possibilité est d'utiliser l'outil svgslice permettant d'automatiser l'export depuis des documents SVG Inkscape, en utilisant au choix des guides ou un calque de découpage. + + + + + +Dégradés non-linéaires + +La version 1.1 du SVG ne supporte pas les dégradés non-linéaires (c'est à dire ayant des transitions non linéaires entre les couleurs). Vous pouvez cependant les émuler grâce à des dégradés multi-stops. + + +Commencez par créer un dégradé avec deux stops, et ouvrez l'éditeur de dégradés (par exemple, en double-cliquant sur une poignée du dégradé dans l'outil dégradé). Ajoutez un nouveau stop au milieu du dégradé, et déplacez-le légèrement. Puis, ajoutez d'autres stops de part et d'autre celui du milieu et déplacez-les aussi de sorte que le dégradé soit régulier. Plus vous ajoutez de stops, plus vous pouvez rendre le dégradé résultant régulier. Voici le dégradé initial avec deux stops (noir et blanc) : + + + + + + + + + + +Et voici quelques dégradés multi-stops non-linéaires (examinez-les dans l'éditeur de dégradés) : + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Dégradés radiaux excentriques + +Les dégradés radiaux ne sont pas nécessairement symétriques. Dans l'outil dégradés, déplacez la poignée centrale d'un dégradé elliptique tout en appuyant sur Maj. Cela vous permettra de déplacer la poignée du foyer (en forme de "x") du dégradé et de la séparer du centre. Si vous n'en avez plus besoin, vous pouvez redéplacer la poignée de foyer près du centre. + + + + + + + + + + + + + + + + + + + + + + +Alignement au centre de la page + +Pour aligner quelquechose au centre ou le long d'un côté de la page, sélectionnez l'objet ou le groupe à aligner puis ouvrez la boîte de dialogue Aligner et distribuer (Ctrl+Shift+A). Vous pouvez alors choisir la page dans la liste relativement à et enfin aligner votre sélection comme vous le désirez. + + + + + +Nettoyage du document + +Quand ils ne sont plus utilisés, beaucoup de dégradés, motifs et marqueurs (plus précisément, ceux que vous avez édité manuellement) restent dans les palettes correspondantes et peuvent être utilisés dans de nouveaux objets. Cependant, si vous voulez optimiser votre document, utilisez la commande Nettoyer les Defs du menu Fichier. Elle supprimera tout dégradé, motif ou marqueur qui n'est plus utilisé par aucun objet du document, réduisant ainsi la taille du fichier. + + + + + +Massicotter ou masquer un bitmap + +Par défaut, un bitmap importé (par exemple, une photo) est un élément <image> non modifiable avec l'outil Nœud. Pour contourner cela, convertissez l'image en un rectangle rempli par un motif avec la commande Objet en motif (Alt+I). Vous obtenez alors un rectangle dont le remplissage est votre bitmap. Vous pouvez maintenant convertir cet objet en chemin, éditer ses nœuds, le faire intersecter avec d'autres formes, etc. Dans les Préférences d'Inkscape (onglet Divers), vous pouvez définir une option forçant l'import systématique des bitmaps en tant que rectangles remplis. + + + + +Fonctionnalités cachées et éditeur XML + +L'éditeur XML vous permet de modifier la plupart des aspects du document sans avoir à utiliser un éditeur de texte externe. De plus, Inkscape supporte souvent des fonctionnalités SVG pas encore accessibles depuis l'interface graphique. Par exemple, nous supportons actuellement les masques et les chemins de massicotage, même si l'interface graphique n'y donne pas encore accès. L'éditeur XML offre la possibilité d'accéder à ces fonctionnalités (à condition de connaître le SVG) + + + + + +Changer l'unité de mesure des règles + +Dans le patron (template) par défaut, l'unité de mesure utilisée par les règles est le px ("unité utilisateur SVG", égale à 0.8pt ou 1/90 de pouce dans Inkscape). C'est aussi l'unité utilisée pour l'affichage des coordonnées dans le coin inférieur gauche, et celle présélectionnée dans les menus qui font intervenir des unités (vous pouvez déplacer votre souris au-dessus d'une règle pour voir un indicateur affichant l'unité utilisée). Pour modifier ceci, ouvrez les Préférences du document (Ctrl+Maj+D) et changez les Unités par défaut dans l'onglet Page. + + + + + +Appliquer des coups de tampon + +Pour créer rapidement plusieurs copies d'un objet, utilisez le coup de tampon. Déplacez simplement un objet (ou redimensionnez/tournez le) et, alors que le bouton de la souris est toujours pressé, appuyez sur Espace. Ceci appose un "tampon" de l'objet courant. Vous pouvez répéter ce coup de tampon autant de fois que vous le voulez. + + + + + +Astuces du stylo + +Dans l'outil courbes de Bézier (stylo), vous pouvez terminer la ligne courante de plusieurs façons : + + + + +Appuyer sur Entrée. + + + + +Effectuer un double-clic avec le bouton gauche de la souris. + + + + +Sélectionner le stylo de nouveau. + + + + +Sélectionner un autre outil. + + + + +Notez que tant que le chemin n'est pas terminé (c'est à dire qu'il est affiché en vert, avec le segment courant en rouge), il n'existe pas encore en tant qu'objet dans le document. Pour l'annuler, vous pouvez donc utiliser les raccourcis Esc (abandonner complètement le chemin) ou Backspace (supprimer le dernier segment du chemin non terminé) à la place d'Annuler. + + +Pour ajouter un nouveau sous-chemin à un chemin existant, sélectionnez ce chemin et commencez à dessiner (d'où vous voulez) tout en appuyant sur Maj. Cependant, si vous voulez simplement prolonger un chemin existant, Maj n'est pas nécessaire; commencez simplement à dessiner depuis l'une des ancres situées aux extrémités du chemin sélectionné. + + + + + +Entrer des valeurs Unicode + +Quand vous êtes dans l'outil texte, appuyer sur Ctrl+U permet d'alterner les modes Normal et Unicode. En mode Unicode, chaque groupe de 4 chiffres hexadécimaux que vous tapez devient un caractère Unicode, vous permettant ainsi de taper les symboles que vous voulez (si vous connaissez leur numéro Unicode, et si la police les supporte). Pour quitter le mode Unicode, vous pouvez aussi appuyer sur Esc. Par example, Ctrl+U 2 0 1 4 Esc insère un tiret long (—). + + + + + +Utilisation de la grille pour dessiner des icônes + +Supposons que vous vouliez créer une icône de 24x24 pixels. Créez un canevas de 24x24 px (utilisez les Préférences du document)(notez que dans le menu Créer un nouveau document, vous pouvez accéder à une liste de modèles, dont certains d'icônes) et définissez une taille de grille de 0.5 px (une grille de 48x48, donc). Maintenant, si vous alignez les remplissages d'objets sur les lignes paires de grille et les contours sur les lignes impaires, avec un nombre pair (en px) comme largeur de contour, en exportant le document à la résolution par défaut de 90ppp (de sorte qu'1px corresponde à 1 pixel bitmap), vous obtiendrez une icône bitmap nette ne nécessitant pas d'anticrénelage. + + + + + +Rotation d'objets + +Dans le sélecteur, cliquer sur un objet permet d'afficher les flèches de redimensionnement, cliquer une fois de plus sur cet objet permet d'afficher les flèches d'inclinaison et de rotation. Si vous déplacez les flèches des coins, l'objet tournera autour du centre (marqué d'une croix). Si vous appuyez sur Maj pendant cette opération, le rotation se fera autour du coin opposé. Vous pouvez aussi déplacer le centre de rotation (la croix) où vous le désirez. + + +Ou bien tourner en utilisant les raccourcis clavier : [ et ] (de 15 degrés) ou Ctrl+[ et Ctrl+] (de 90 degrés). Ces mêmes raccourcis [] combinés avec Alt permettent des rotations lentes à l'échelle du pixel. + + + + + +Utiliser la boîte de dialogue "Ouvrir" comme palette d'objets + +Si vous avez un certain nombre de petits fichiers SVG dont vous réutilisez fréquemment le contenu dans d'autres documents, vous trouverez peut-être pratique d'utiliser la boîte de dialogue Ouvrir comme une palette. Ajoutez le répertoire contenant vos éléments SVG dans la liste des favoris (de cette boîte de dialogue) afin de pouvoir le parcourir rapidement. Puis naviguez dans ce répertoire en consultant les aperçus. Lorsque vous avez trouvé le fichier dont vous avez besoin, cliquez-déplacez le simplement sur le canevas, et il sera automatiquement importé dans votre document courant. + + + + + + +Des ombres portées grâce aux bitmaps +Bien qu'Inkscape ne supporte pas encore le filtre SVG "flou gaussien", vous pouvez facilement créer des ombrages bitmap floutés pour les objets, grâce à la commande Créer une copie bitmap et un script de filtrage. Voir le fichier share/extensions/inkscape-shadow.README (en anglais) pour plus de détails et les limitations de cette méthode. + + + + + +Placement d'un texte le long d'un chemin + +Pour placer du texte le long d'une courbe, sélectionnez le texte et la courbe puis utilisez la commande Mettre suivant un chemin du menu Texte. Le texte commencera au début du chemin. En général, il vaut mieux créer un chemin auquel vous voulez que le texte s'adapte plutôt que d'adapter ce texte à un autre élément (préexistant) du dessin — cela vous autorisera un meilleur contrôle sans avoir à "bricoler" votre dessin. + + + + + +Sélection de l'original + +Quand vous avez affaire à un texte suivant un chemin, un offset lié ou un clone, leur objet/chemin source peut être difficile à sélectionner (caché sous d'autres objets, rendu invisible et/ou verrouillé). le raccourci magique Maj+D peut alors vous aider; sélectionnez le texte, l'offset lié ou le clone et appuyez sur Maj+D pour sélectionner alors le chemin correspondant, la source de l'offset ou l'original du clone. + + + + + +Au cas où la fenêtre serait hors de l'écran + +Quand vous transférez des documents entre des systèmes avec des résolutions ou un nombre d'écrans différents, vous pouvez être confronté au problème suivant : Inkscape a enregistré une position de fenêtre qui fait que vous ne pouvez plus atteindre Inkscape sur votre écran. Il suffit de maximiser la fenêtre (ce qui devrait la rendre de nouveau visible a l'écran)(utilisez la barre des tâches), d'enregistrer le document et de le recharger. Vous pouvez éviter tout cela en désactivant l'option "enregistrer la taille et la position des fenêtres" (dans l'onglet Fenêtres des Préférences d'Inkscape). + + + + + +Transparence, dégradés et export en Postscript + +Les formats PostScript ou EPS ne supportent pas la transparence, aussi vous ne devriez pas utiliser cette fonctionnalité si vous comptez exporter en PS/EPS. Dans le cas d'une transparence uniforme chevauchant une couleur uniforme, il est facile d'y remédier : sélectionnez l'un des objets transparents et passez à l'outil Pipette (F7); Assurez vous qu'il est en mode "capturer la couleur visible sans alpha" et cliquez sur ce même objet. La couleur visible sera capturée et réassignée à l'objet mais cette fois, sans transparence. Répétez cette opération pour tous les objets transparents. Si votre objet transparent chevauche plusieurs zones de différentes couleurs uniformes, vous devrez le découper en morceaux (un morceau par zone) puis appliquer la procédure ci-dessus à chacun des morceaux. + + +L'export de dégradés en PS ou EPS ne fonctionne pas pour du texte (à moins que ce texte ne soit converti en chemin) ou pour les remplissages des contours. Et, comme la transparence est perdu lors d'un export au format PS ou EPS, vous ne pouvez pas utiliser, par exemple, un dégradé depuis un bleu opaque vers un bleu transparent; pour contourner cela, remplacez-le par un dégradé depuis un bleu opaque vers la couleur du fond opaque. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/share/tutorials/tutorial-tips.sl.svg b/share/tutorials/tutorial-tips.sl.svg new file mode 100644 index 000000000..aab48fbde --- /dev/null +++ b/share/tutorials/tutorial-tips.sl.svg @@ -0,0 +1,533 @@ + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ::NASVETI + + + + + +V tem vodiču vam bomo predstavili razne trike, ki so jih naši uporabniki +spoznali med uporabljanjem Inkscapa, pa tudi nekatere bolj "skrite" +možnosti programa, ki vam lahko pomagajo pri delu. + + + + +Krožno tlakovanje z ukazom Tlakuj klone +Uporaba ukaza Tlakuj klone za +pravokotne vzorce in mreže je precej intuitivna. Kaj pa v primeru, da potrebujete krožno +tlakovanje, kjer si objekti delijo skupno središče vrtenja? Tudi to je mogoče. + +Če vaš krožni vzorec potrebuje le 3, 4, 6, 8 ali 12 elementov, potem lahko poskusite +vrste tlakovanja P3, P31M, P3M1, P4, P4M, P6, ali P6M. Ta tlakovanja so uporabna za npr. +snežinke in podobne vzorce. Bolj splošen način pa je opisan tu. + +Izberite tlakovanje P1 (enostavni premik) in potem kompenzirajte ta +prenos v zavihku Premik, kjer nastavite obe opciji +Na vrsto/Premik Y and Na stolpec/Premik X na -100 %. +Sedaj bodo vsi kloni zloženi na vrh originala. Sedaj je treba samo še v zavihku +Vrtenje nastaviti nekaj vrtenj na stolpec, ustvariti vzorec z +eno vrstico in večimi stolpci. +Primer: vzorec, sestavljen iz vodoravne črte, s 30 stolpci, vsak od njih je zavrten +za 6 stopinj: + + + + +Če želite iz tega ustvariti urino krožnico, preprosto izrežite ali prekrijte sredinski del +z belim krogom (če želite izvajati matematične operacije na klonih, jih prej razvežite). + +Bolj zanimivi učinki se dajo doseči z uporabo tako stolpcev kot tudi vrstic. Tu je vzorec +z desetimi stolpci in osmimi vrsticami, vrtenjem 2 stopinji na vrstico in 18 stopinj na +stolpec. Vsaka skupina črt je "stolpec", tako da so skupine 18 stopinj vsaksebi. Znotraj +vsakega stolpca so posamezne črte 2 stopinji vsaksebi. + + + + +V zgornjih primerih je bila črta vrtena okoli svojega središča. Če želite središče postaviti +zunaj svojega lika, ustvarite neviden pravokotnik (brez polnila in črte), ki bi pokril +vaš lik. Pravokotnik postavite tako, da je njegovo središče tam, kjer želite imeti središče +svojega lika, nato pa združite skupaj lik in pravokotnik in na skupini uporabite ukaz +Tlakuj klone. Na ta način lahko ustvarjate lepe "eksplozije" in "zvezdne +vzorce" z naključnimi vrednostmi pri parametrih velikosti, vrtenja in motnosti. + + + + + + + + + +Kako razrezati (več pravokotnih površin za izvoz)? +Ustvarite nov sloj in v njem ustvarite nevidne pravokotnike, ki pokrivajo dele +vaše slike. Prepričajte se, da uporabljate enote px (privzeto), vklopite mrežo in +pripnite pravokotnike na mrežo tako, da vsak zasede neko celo število enot px. +Pravokotnikom tudi določite smiselne identifikacije, nato pa vsakega posameznega +izvozite v svojo datoteko. Pravokotniki si bodo zapomnili imena, pod katerimi +so bili izvoženi. Kasneje je zelo lahko ponovno izvoziti te pravokotnike: preklopite +na sloj za izvoz, uporabite tipko Tab za izbiro pravokotnika, ki ga potrebujete (ali +pa poiščite njegovo identifikacijo preko Iskanja), ter kliknite Izvoz. Lahko pa tudi +napišete lupinsko skripto ali ukazno datoteko za izvoz vseh ploskev, npr.: + +inkscape -i <area-id> -t <filename.svg> + +za vsako izvoženo ploskev. Stikalo -t pove, da naj program izvozi površino v datoteko z istim imenom, kot je identifikacija te površine +lahko pa uporabite tudi stikalo -e za prosto poimenovanje izvožene datoteke. V nasprotnem primeru lahko +uporabite tudi pripomoček svgslice, +ki avtomatizira izvažanje iz Inkscapovih SVG dokumentov z uporabo bodisi razreznih slojev ali vodil. + + + + +Nezvezni prelivi +Trenutna različica SVGja ne podpira nezveznih prelivov. Lahko pa +jih ustvarite z večstopenjskimi prelivi. + + +Začnite s preprostim dvostopenjskim prelivom. Odprite Urejevalnik prelivov (npr. z dvoklikom +na katerokoli ročico na orodju Prelivi). Dodajte nov postanek na sredino +in ga malce premaknite. Nato dodajte še nekaj postankov okrog tega in popravite preliv, +da postane spet gladek. Več postankov boste dodali, bolj natančno ga boste lahko zmehčali. +Tu je primer osnovnega črno-belega preliva z dvema postankoma: + + + + + + + + + + +Tu pa je nekaj "nezveznih" prelivov z več postanki (raziskujte jih z +Urejevalnikom prelivov (ki ga najdete pod gumbom Uredi v pogovornem +oknu Polnilo in obroba): + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Nesredinski krožni prelivi +Krožni prelivi niso nujno simetrični. Če v polju za prelive v pogovornem +oknu Polnilo in obroba držite tipko Shift in povlečete srednjo ročico, boste +premaknili središče preliva. Ko tega ne potrebujete več, lahko +središče premaknete nazaj na sredino tako, da ga povlečete blizu sredine. + + + + + + + + + + + + + + + + + + + + + +Poravnava na sredino strani +Če želite nekaj poravnati na sredino strani, izberite predmet ali skupino, +izberite Poravnavo na stran v pogovornem oknu Poravnava +(Ctrl+Shift+A). + + + + +Čiščenje dokumenta +Veliko prelivov, vzorcev in oznak (bolj natančno: tiste, ki ste jih ročno uredili), +ki jih ne uporabljate več, ostane v svojih paletah in lahko jih ponovno uporabite za nove objekte. Če pa bi želeli optimizirati vaš dokument, uporabite ukaz +Počisti definicije iz menija Datoteka. Izbrisal bo vse prelive, vzorce +in markerje, ki niso uporabljeni v dokumentu, in tako zmanjšal datoteko. + + + + +Obrezovanje ali maskiranje rastrske slike + +Uvožene rastrske slike (npr. fotografije) so <image> elementi, ki jih ne moremo +urejati z orodjem za Vozlišča. Da se temu izognete, preoblikujte sliko v pravokotnik +z vzorčastim polnilom preko ukaza Predmet v vzorec (Alt+I). +Pokazal se bo pravokotnik, napolnjen z vašim rastrom. Ta objekt pa lahko spremenimo +v pot, mu urejamo vozlišča, presekamo z drugimi objekti itd. V meniju +Nastavitve Inkscapa (zavihek Drugo), lahko +nastavite opcijo, da se rastrske slike vedno uvažajo kot pravokotniki z rastrskim polnilom. + + + + +Skrite možnosti in urejevalnik XML +Urejevalnik XML omogoča spreminjanje skoraj vseh parametrov dokumenta brez uporabe +zunanjega urejevalnika teksta. Inkscape podpira nekaj več možnosti SVGja, +kot jih je dostopnih preko grafičnega vmesnika. V trenutni verziji podpira prikazovanje +mask in clipping poti, čeprav ni nobenega grafičnega vmesnika za ustvarjanje ali +spreminjanje le-teh. Urejevalnik XML je en izmed načinov, kako dostopati do tega +(če poznate SVG). + + + + +Spreminjanje enote ravnila +Privzeta enota merjenja je px ("uporabniška enota SVG" - v Inkscapu je enaka 0,8 pt oziroma +1/90 palca). Ta enota je prav tako uporabljana za izpis koordinat v spodnjem levem kotu +in je privzeta enota v vseh menijih. Če z miško lebdite nad ravnilom, se vam bo pokazal namig z enotami, ki so trenutno v uporabi. To lahko spremenite v Nastavitvah dokumenta +(Ctrl+Shift+D), v zavihku Stran spremenite +Privzete enote. + + + + +Žigosanje +Za hitro kopiranje predmetov lahko uporabite žig. Povlecite predmet z miško (ali pa ga vrtite oz. mu spreminjajte velikost) in pritiskajte +na preslednico. Vsak pritisk pusti za seboj odtis predmeta. + + + + +Nasveti za orodje Pero +Za dokončanje črte z orodjem Pero (Bezier) imate več možnosti: + + +Pritisnite Enter + +Dvokliknite z levim gumbom miške + +Ponovno izberite Pero + +Izberite kako drugo orodje + + + +Dokler je pot nedokončana (obarvana je zeleno, izbrani segment pa rdeče), v dokumentu +ne obstaja kot objekt. Za prekinitev poti uporabite Esc (izbris +celotne poti) ali Backscape (izbris zadnjega segmenta še nedokončane +poti) namesto ukaza Razveljavi. + + +Za dodajanje podpoti že obstoječi poti označite pot in držite tipko Shift +ter začnite risati iz poljubne točke. Če pa želite le nadaljevati že obstoječo pot, +Shift ni potreben - vse, kar morate storiti je, da začnete risati iz enega izmed končnih +sider na izbrani poti. + + + + +Vnašanje Unicode simbolov +Ko imate izbrano orodje za besedila, pritisk na Ctrl+U vključi ali izključi +način za Unicode simbole. V tem načinu se vsaka skupina štirih osmiških +številk prevede v ustrezen Unicode simbol in na ta način omogoča vnašanje poljubnih +simbolov - seveda, če poznate njihovo Unicode kodo in če jih izbrana pisava podpira. +Za izhod iz načina Unicode pritisnite tipko Esc. +Primer: zaporedje Ctrl+U 2 0 1 4 Esc v dokument vnese vezaj (—). + + + + +Uporaba mreže pri risanju ikon +Recimo, da želimo narisati ikono veliko 24x24 pik. Za to bi naredili +dokument velikosti 24x24 milimetrov (z ukazom Nastavitve dokumenta, nastavili mrežo na 0,5 mm +(48x48 črt). Sedaj poravnavamo polne predmete na sode črte, prazne, +obrisane predmete pa na lihe črte. Ko izvozimo sliko tako pri konfiguraciji 1 mm = 1 piksel (90 dpi), dobimo prepričljivo sliko brez potrebe po mehčanju robov. + + + + +Vrtenje predmeta +Z Izbirnikom kliknite na predmet, da se pokažejo puščice za spreminjanje +velikosti. Če kliknete še enkrat, se pokažejo puščice za vrtenje. Če kotne +puščice kliknete in vlečete, se predmet vrti okrog svoje osi (označeno s križcem). +Če medtem držite Shift, se predmet vrti okrog nasprotnega kota. +Os vrtenja lahko premaknete tako, da kliknete na središčno točko in jo odvlečete +na poljuben položaj. + + +Predmete lahko vrtite tudi s pomočjo tipkovnice, in sicer z naslednjimi tipkami: [ in ] +(za 15 stopinj) ali Ctrl+[ in Ctrl+] (za 90 +stopinj). Če poleg tipk [] držite še tipko Alt, boste predmete +lahko vrteli točko po točko. + + + + +Ukaz Odpri kot paleta objektov +Če imate veliko količino majhnih SVG dokumentov, katerih vsebino večkrat uporabljate +v drugih dokumentih, lahko ukaz Odpri uporabljate kot paleto objektov. Mapo s SVG +dokumenti dodajte na seznam zaznamkov, da lahko hitro dostopate do nje. Nato lahko +brskate po tej mapi, v katerih se vam bodo kazali predogledi vaših dokumentov. Ko najdete +dokument, ki ste ga iskali, ga preprosto povlečete na platno. + + + + +Rastrske padajoče sence +Inkscape trenutno še ne podpira SVG filtra za Gaussian mehčanje, vendar lahko objektom kljub temu +zlahka ustvarite rastrske padajoče sence. To storite z ukazom "Ustvari rastrsko kopijo" in +filtrirno skripto. Za več podrobnosti in omejitve te metode poglejte v datoteko +share/extensions/inkscape-shadow.README . + + + + +Postavljanje besedila na krivuljo +Besedilo postavite na krivuljo tako, da označite tako besedilo kot tudi krivuljo in izberete +ukaz Postavi na pot iz menija Besedilo. Začetek besedila bo na začetku poti. +V splošnem je bolje ustvariti točno določeno pot, na katero želite postaviti tekst, kot pa +prilagajati tekst kakemu drugemu elementu — ta metoda omogoča več nadzora in manj skrbi, da bi uničili svojo risbo. + + + + +Izbiranje originala +Če imate besedilo postavljeno na pot, povezan zamik ali klon, je včasih težko izbrati +originalen objekt oz. pot, saj je takoj pod tekstom, nevidna in/ali zaklenjena. Čarobna +kombinacija Shift+D vam bo pomagala v tem primeru; označite besedilo, +linked offset ali klon in pritisnite Shift+D, nato pa premaknite izbran +objekt do originialne poti, izvirnik zamika ali klona. + + + + +Obnova oken +Ko premikate dokumente med sistemi z različnimi resolucijami ali števili enkranov, se lahko +zgodi, da Inkscape shrani postavitev oken na tak način, da določeno okno na drugem sistemu ni več dostopno oz. +se nahaja zunaj zaslona. V takem primeru preprosto povečajte okno preko gumba v opravilni vrstici +(kar ga bo priklicalo nazaj na ekran), shranite dokument in ga ponovno odprite. Temu se lahko +tudi povsem izognete tako, da izključite globalno možnost shranjevanja okenske postavitve +(Nastavitve Inkscapa, zavihek Okna). + + + + +Prosojnost, polnila in izvoz v PostScript +PostScript oz. EPS formati ne podpirajo prosojnosti, zato je ne +uporabljajte, če želite izvažati svoje dokumente v formatih PS/EPS. V primeru +enakomerne prosojnosti, ki pokrije enakomerno barvo, je to preprosto popraviti: izberite +enega izmed prosojnih objektov, izberite Kapalko (F7) in se prepričajte, +da je Kapalka v načinu "izberi vidno barvo brez alpha kanala", nato pa kliknite na isti +objekt. To bo izbralo vidno barvo in jo določilo objektu, tokrat brez prosojnosti. +Postopek ponovite za vse prosojne objekte. Če prosojen objekt pokriva več ploskev +s plosko barvo, ga boste morali razdeliti na posamezne dele (glede na barvo) in ponoviti +postopek za vsak posamezen del. + + +Izvažanje polnil v formate PS ali EPS ne deluje v primeru besedil +(razen v primeru, da tekst pretvorjen v pot) ali barvo obrobe. Ker se ob izvažanju +v formate PS ali EPS transparenca izgubi, prav tako ne morete uporabljati polnila za +prehod iz npr. motno modre v prosojno modro. +Namesto tega jo nadomestite s prehodom iz motno modre v +motno barvo ozadja. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/share/tutorials/tutorial-tips.svg b/share/tutorials/tutorial-tips.svg new file mode 100644 index 000000000..0cfe1b9a3 --- /dev/null +++ b/share/tutorials/tutorial-tips.svg @@ -0,0 +1,536 @@ + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ::TIPS AND TRICKS + + + + + +This tutorial will demonstrate various tips and tricks that users have learned through +the use of Inkscape and some "hidden" features that can help you speed up production +tasks. + + + + +Radial placement with Tile Clones +It's easy to see how to use the Tile Clones dialog for rectangular grids and +patterns. But what if you need radial placement, where objects +share a common center of rotation? It's possible too! + +If your radial pattern need only have 3, 4, 6, 8, or 12 elements, then you can try the +P3, P31M, P3M1, P4, P4M, P6, or P6M symmetries. These would work nicely for snowflakes +and the like. A more general method, however, is as follows. + +Choose the P1 symmetry (simple translation) and then compensate for +that translation by going to the Shift tab and setting Per +row/Shift Y and Per column/Shift X both to -100%. Now all +clones will be stacked exactly on top of the original. All that remains to do is to go +to the Rotation tab and set some rotation angle per column, then +create the pattern with one row and multiple columns. For example, here's a pattern made +out of a horizontal line, with 30 columns, each column rotated 6 degrees: + + + + +To get a clock dial out of this, all you need to do is cut out or simply overlay the +central part by a white circle (to do boolean operations on clones, unlink them first). + +More interesting effects can be created by using both rows and columns. Here's a pattern +with 10 columns and 8 rows, with rotation of 2 degrees per row and 18 degrees per +column. Each group of lines here is a "column", so the groups are 18 degrees from each +other; within each column, individual lines are 2 degrees apart: + + + + +In the above examples, the line was rotated around its center. But what if you want the +center to be outside of your shape? Just create an invisible (no fill, no stroke) +rectangle which would cover your shape and whose center is in the point you need, group +the shape and the rectangle together, and then use Tile Clones on +that group. This is how you can do nice "explosions" or "starbursts" by randomizing +scale, rotation, and possibly opacity: + + + + + + + + + +How to do slicing (multiple rectangluar export areas)? +Create a new layer, in that layer create invisible rectangles covering parts of your +image. Make sure your document uses the px unit (default), turn on grid and snap the +rects to the grid so that each one spans a whole number of px units. Assign meaningful +ids to the rects, and export each one to its own file. Then the rects will remember +their export filenames. After that, it's very easy to re-export some of the rects: +switch to the export layer, use Tab to select the one you need (or use Find by id), and +click Export in the dialog. Or, you can write a shell script or batch file to export all +of your areas, with a command like: + +inkscape -i <area-id> -t <filename.svg> + +for each exported area. The -t switch tells it to use the remembered filename hint, +otherwise you can provide the export filename with the -e switch. Alternatively, you can +use the svgslice utility to +automate exporting from Inkscape SVG documents, using either a slice layer or guides. + + + + +Non-linear gradients +The version 1.1 of SVG does not support non-linear gradients (i.e. those which have a +non-linear translations between colors). You can, however, emulate them by +multistop gradients. + +Start with a simple two-stop gradient. Open the Gradient editor (e.g. by +double-clicking on any gradient handle in the Gradient tool). Add a new gradient stop in +the middle; drag it a bit. Then add more stops before and after the middle stop and drag +them too, so that the gradient is smooth. The more stops you add, the smoother you can +make the resulting gradient. Here's the initial black-white gradient with two stops: + + + + + + + + + + +And here are various "non-linear" multi-stop gradients (examine them in the Gradient +Editor): + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Excentric radial gradients +Radial gradients don't have to be symmetric. In Gradient tool, drag the central handle +of an elliptic gradient with Shift. This will move the x-shaped +focus handle of the gradient away from its center. When you don't +need it, you can snap the focus back by dragging it close to the center. + + + + + + + + + + + + + + + + + + + + + +Aligning to the center of the page +To align something to the center or side of a page, select the object or group and then +choose Page from the Relative to: list in the +Align dialog (Ctrl+Shift+A). + + + + +Cleaning up the document +Many of the no-longer-used gradients, patterns, and markers (more precisely, those which +you edited manually) remain in the corresponding palettes and can be reused for new +objects. However if you want to optimize your document, use the Vacuum +Defs command in File menu. It will remove any gradients, patterns, or markers +which are not used by anything in the document, making the file smaller. + + + + +Clipping or masking a bitmap + +By default, an imported bitmap (e.g. a photo) is an <image> element which is not +editable by the Node tool. To work around this, convert the image into a rectangle with +pattern fill by Object to Pattern (Alt+I). This will +give you a rectangle filled with your bitmap. Now this object can +be converted to path, node-edited, intersected with other shapes etc. In +Inkscape Preferences (Misc tab), you can set the +option of always importing bitmaps as pattern-filled rectangles. + + + + +Hidden features and the XML editor +The XML editor allows you to change almost all aspects of the document without using an +external text editor. Also, Inkscape usually supports more SVG features than are +accessible from the GUI. For example, we now support displaying masks and clipping +paths, even though there's no GUI for creating or modifying them. The XML editor is one +way to get access to these features (if you know SVG). + + + + +Changing the rulers' unit of measure +In the default template, the unit of measure used by the rulers is px ("SVG user unit", +in Inkscape it's equal to 0.8pt or 1/90 of the inch). This is also the unit used in +displaying coordinates at the lower-left corner and preselected in all units menus. (You +can always hover your mouse over a ruler to see the tooltip with the units it uses.) To +change this, open Document Preferences +(Ctrl+Shift+D) and change the Default units on the +Page tab. + + + + +Stamping +To quickly create many copies of an object, use stamping. Just +drag an object (or scale or rotate it), and while holding the mouse button down, press +Space. This leaves a "stamp" of the current object shape. You can +repeat it as many times as you wish. + + + + +Pen tool tricks +In the Pen (Bezier) tool, you have the following options to finish the current line: + + +Press Enter + +Double click with the left mouse button + +Select the Pen tool again + +Select another tool + + + +Note that while the path is unfinished (i.e. is shown green, with the current segment +red) it does not yet exist as an object in the document. Therefore, to cancel it, use +either Esc (cancel the whole path) or Backspace +(remove the last segment of the unfinished path) instead of Undo. + + +To add a new subpath to an existing path, select that path and start drawing with +Shift from an arbitrary point. If, however, what you want is to simply +continue an existing path, Shift is not necessary; just start +drawing from one of the end anchors of the selected path. + + + + +Entering Unicode values +While in the Text tool, pressing Ctrl+U toggles between Unicode and +normal mode. In Unicode mode, each group of 4 hexadecimal digits you type becomes a +single Unicode character, thus allowing you to enter arbitrary symbols (as long as you +know their Unicode codepoints and the font supports them). To quit the Unicode mode, you +can press Esc. For example, Ctrl+U 2 0 1 4 Esc inserts +an em-dash (—). + + + + +Using the grid for drawing icons +Suppose you want to create a 24x24 pixel icon. Create a 24x24 px canvas (use the +Document Preferences) and set the grid to 0.5 px (48x48 gridlines). +Now, if you align filled objects to even gridlines, and stroked +objects to odd gridlines with the stroke width in px being an even +number, and export it at the default 90dpi (so that 1 px becomes 1 bitmap pixel), you +get a crisp bitmap image without unneeded antialiasing. + + + + +Object rotation +When in the Select tool, click on an object to see the scaling arrows, +then click again on the object to see the rotation and shift arrows. If +the arrows at the corners are clicked and dragged, the object will rotate around the +center (shown as a cross mark). If you hold down the Shift key while +doing this, the rotation will occur around the opposite corner. You can also drag the +rotation center to any place. + + +Or, you can rotate from keyboard by pressing [ and ] +(by 15 degrees) or Ctrl+[ and Ctrl+] (by 90 +degrees). The same [] keys with Alt perform slow +pixel-size rotation. + + + + +Open dialog as an object palette +If you have a number of small SVG files whose contents you often reuse in other +documents, you can conveniently use the Open dialog as a palette. Add the directory with +your SVG sources into the bookmarks list so you can open it quickly. Then browse that +directory looking at the previews. Once you found the file you need, simply drag it to +the canvas and it will be imported into your current document. + + + + +Bitmap drop shadows +While Inkscape does not yet support the Gaussian blur SVG filter, you can easily create +blurred drop shadows for objects as bitmaps, via the "Create a Bitmap Copy" command with +a filter script. See share/extensions/inkscape-shadow.README for details and limitations +of this method. + + + + +Placing text on a path +To place text along a curve, select the text and the curve together and choose +Put on Path from the Text menu. The text will start at the beginning +of the path. In general it is best to create an explicit path that you want the text to +be fitted to, rather than fitting it to some other drawing element — this will give you +more control without screwing over your drawing. + + + + +Selecting the original +When you have a text on path, a linked offset, or a clone, their source object/path may +be difficult to select because it may be directly underneath, or made invisible and/or +locked. The magic key Shift+D will help you; select the text, linked +offset, or clone, and press Shift+D to move selection to the +corresponding path, offset source, or clone original. + + + + +Window off-screen recovery +When moving documents between systems with different resolutions or number of displays, +you may find Inkscape has saved a window position that places the window out of reach on +your screen. Simply maximise the window (which will bring it back into view, use the +task bar), save and reload. You can avoid this altogether by unchecking the global +option to save window geometry (Inkscape Preferences, +Windows tab). + + + + +Transparency, gradients, and PostScript export +PostScript or EPS formats do not support transparency, so you +should never use it if you are going to export to PS/EPS. In the case of flat +transparency which overlays flat color, it's easy to fix it: Select one of the +transparent objects; switch to the Dropper tool (F7); make sure it's in +the "pick visible color without alpha" mode; click on that same object. That will pick +the visible color and assign it back to the object, but this time without +transparency. Repeat for all transparent objects. If your transparent object overlays +several flat color areas, you will need to break it correspondingly into pieces and +apply this procedure to each piece. + + +Exporting gradients to PS or EPS does not work for text +(unless text is converted to path) or for stroke paint. Also, since transparency is lost +on PS or EPS export, you can't use e.g. a gradient from an opaque +blue to transparent blue; as a workaround, replace it by a gradient +from opaque blue to opaque background +color. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/share/tutorials/tutorial-tracing.de.svg b/share/tutorials/tutorial-tracing.de.svg new file mode 100644 index 000000000..b9f3b7e36 --- /dev/null +++ b/share/tutorials/tutorial-tracing.de.svg @@ -0,0 +1,186 @@ + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ::VEKTORISIEREN + + + + + + + + +Inkscape beinhaltet ein Werkzeug, mit dem Sie ein Bitmap-Bild in ein <Pfad> Element ihrer SVG Zeichnung umwandeln können. Diese kurzen Ausführungen sollen Ihnen dabei helfen, damit vertraut zu werden. + + + + + +Derzeit setzt Inkscape potrace, eine Bitmap-Vektorisierungsengine, von Peter Selinger (potrace.sourceforge.net) ein. In Zukunft möchten wir alternative Vektorisierungsprogramme einsetzen, jedoch ist im Moment dieses Werkzeug für unsere Ansprüche mehr als ausreichend. + + +Denken Sie daran, dass die Herangehensweise eines Vektorisierungsprogramms weder die Reproduktion des Orginalbildes sein kann, noch ist es beabsichtigt von vorne herein ein hundertprozentiges Endergebnis zu erhalten. Kein automatisiertes Vektorisierungsprogramm ist dazu in der Lage. Es erstellt einen Satz an Kurven, den Sie als Ausgangsmaterial für die Weiterverarbeitung Ihrer Zeichnung nutzen können. + + +Potrace interpretiert ein Schwarzweiß-Bitmap und wandelt es in Pfade um. Es hat für die Konvertierung eines Rohbildes drei Arten von Inputfiltern. + + +Generell kann man sagen, je höher der Anteil dunkler Pixel im Zwischenbild-Bitmap ist, desto höher ist die Vektorisierungsleistung von potrace. Steigt der Vektorisierungsanteil, wird der CPU eine höhere Rechenleistung abverlangt und dadurch wird auch das <Pfad> Element sehr viel größer. Um die gewünschte Proportion und Komplexität des Ergebnispfades zu erreichen, raten wir dem Benutzer, zuerst mit einem schwächer schwarz-eingefärbten Zwischenbild zu experimentieren, und gegebenenfalls den Schwarzanteil graduell zu erhöhen. + + +Laden oder importieren Sie das Bild, das Sie vektorisieren wollen, markieren es, und wählen Pfad > Bitmap vektorisieren, oder Shift+Alt+B. + + +Hauptoptionen innerhalb des Vektorisierungsdialogs + +Dem Benutzer stehen drei Filter zur Verfügung: + + + + + Bildhelligkeit + + + +Dieser verwendet mehrheitlich die Summe der Rot-, Grün- und Blau-Anteile der Pixel (oder Grauschattierungen) als Indikator und überprüft, ob diesem Bereich entweder schwarz oder weiß zugeordnet werden soll. Der Schwellwert kann zwischen 0.0 (schwarz) bis 1.0 (weiß) eingestellt werden. Je höher der Schwellwert, desto niedriger ist die Anzahl der Pixel, die als weiß eingestuft werden und das Zwischenbild wird dunkler. + + +OriginalbildHelligkeitsgrenzwertGefüllt, ohne UmrissHelligkeitsgrenzwertUmriss, nicht gefüllt + + + + Optimale Kantenerkennung + + + +Dieser Filter verwendet einen von J. Canny festgelegten Kantenerkennungs-Algorithmus, der auf schnelle Art und Weise die Isoklinen (Linien gleicher Neigung) des Kontrastes aufspürt. Es wird ein Zwischenbild produziert, das dem Orginal weniger Nahe kommt, wie das bei dem Ergebnis des Filters über Bildhelligkeit der Fall ist, aber es erzeugt eine Kurveninformation die andernfalls verloren ginge. Die Grenzwerte hier (0.0 - 1.0), passen den Helligkeitgrenzwert an und entscheiden, ob angrenzende Pixel zu einer kontrastreichen Kante mit in das Ergebnis eingeschlossen werden. Diese Einstellungen können die Dunkelheit oder die Kantendicke des Endergebnisses beeinflussen. + + +OrginalbildKantenerkennungGefüllt, ohne UmrissKantenerkennungUmriss, nicht gefüllt + + + + Farbquantisierung + + + +Als Ergebnis produziert dieser Filter ein anderes Zwischenbild, als bei den vorherigen Varianten, aber er ist im Prinzip auch sehr nützlich. Statt über Isoklinen der Helligkeit und des Kontrasts zu suchen, erzeugt dieser Filter bei gleichen Helligkeits- und Kontrastwerten an Farbwechseln, Kanten. Die Einstellung der Anzahl der Farben entscheidet darüber, wieviel Farben sich im Endergebnis befinden würden, wenn das Zwischenbild ein Farbbild wäre. Anschließend entscheidet sich, ob schwarz/weiß einen geraden oder ungeraden Index der Farbe erhält. + + +OrginalbildQuantisierung (12 Farben)Gefüllt, ohne UmrissQuantisierung (12 Farben)Umriss, nicht gefüllt + +Der Benutzer sollte alle drei Möglichkeiten der Filterwahl ausschöpfen und die verschiedenen Endergebnisse mit dem Ursprungsbildes vergleichen. Es wird immer ein Bild dabei herauskommen, bei dem ein Ergebnis immer besser ist als bei den anderen Filtermöglichkeiten. + + +Dem Anwender wird nach dem Vektorisierungsvorgang geraten, auf das Ergebnis Pfad > Vereinfachen (Strg+L) anzuwenden, um die Anzahl der Knoten zu verringern. Dadurch kann das potrace-Ergebnis viel leichter weiterverarbeitet werden. Zum Beispiel hier, ist eine Bitmap Vektorisierung eines alten Mannes der Gitarre spielt: + + + +OriginalbildVektorisiertes Bild / Ergebnispfad(1,551 Knoten) + +Beachten Sie die große Anzahl der Knoten in einem Pfad. Nach dem Drücken von Strg+L, ist dies ein typisches Ergebnis: + + + +OrginalbildVektorisiertes Bild / Ergebnispfad - vereinfacht(384 Knoten) + +Die Darstellung ist ein wenig grob, aber die Zeichnung ist nun viel einfacher zu bearbeiten. Vergessen Sie nicht, dass Sie kein exaktes Rendering ihres Bildes erzielen, sondern einen Satz an Kurven, den Sie für Ihre Zeichnung weiterverwenden können. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/share/tutorials/tutorial-tracing.es.svg b/share/tutorials/tutorial-tracing.es.svg new file mode 100644 index 000000000..df5f72795 --- /dev/null +++ b/share/tutorials/tutorial-tracing.es.svg @@ -0,0 +1,184 @@ + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ::VECTORIZAR + + + + + + + + +Una de las funciones de Inkscape es una herramienta para vectorizado de imágenes de mapas de bits en un <trazo> elemento para el dibujado de SVG. Estas cortas notas le ayudarán a conocer como trabaja esto. + + + + +Actualmente Inkscape emplea el motor de vectorizado de mapa de bits Potrace (potrace.sourceforge.net) por Peter Selinger. +En el futuro, esperamos que permita alternar programas de vectorizado; por ahora, sin embargo, esta fina herramienta es más que suficiente para lo que necesita. + + +Tenga en mente que el propósito del Vectorizar no es reproducir un duplicado exacto de la imágen original; o intentar producir un producto final. El autotrazado no hace eso. Lo que hace es darle un set de curvas las cuales usted puede emplear como una fuente de ayuda para sus dibujos. + + +Potrace interpreta mapas de bits blanco y negro y produce un set de curvas. Para Potrace, actualmente poseemos tres tipos de filtros de salida, para convertir desde imágenes brutas a algo que Potrace pueda usar. + + +Generalmente los pixeles más oscuros en un mapa de bit intermedio, es el mayor trazo que Potrace puede desarrollar. A mayor cantidad de trazos, más tiempo la CPU requerira y el elemento <trazo> se convertirá en uno más grande. Se sugiere que los usuarios experimenten primero con imágenes intermédias clara, configurando gradualmente la opacidad para obener la proporción y complejidad del trazo resultante. + + +Para usar el vectorizado, cargue o importe una imágen, selecciónela, y seleccione Trazo > Vectorizar un mapa de bits, o Mayus+Alt+B. + + +main options within the trace dialog + +El usuario observará las tres opciones de filtro disponibles: + + + +Luminosidad de la imágen + + + +Esta usa realmente la suma del rojo, verde y azul (o escala de grices) de un pixel como un +indicador de si este puede ser considerado blanco o negro. La luminosidad puede ser configurada desde 0.0 (negro) a 1.0 (blanco). La mayor configuración del umbral, el menor número de pixeles que serán considerados para ser \u201cwhite\u201d, y la imágen intermedia que se convertirá en oscura. + + +Original ImageBrightness ThresholdFill, no StrokeBrightness ThresholdStroke, no Fill + + +Detección de Bordes Óptima + + + +Este filtro usa el arlgoritmo de detección de bordes desarrollado por J. Canny, el cual es un modo de búsqueda rápida de isóclinas de contrastes similares. Esto producirá un mapa de bits intermedio que será visto un poco diferente a la imágen original que como lo hace la lumínusidad de la imágen, pero provee la curva de información que de otra manera será ignorado. La configuración del umbral es (0.0 \u2013 1.0) ajustada por la luminosidad de la imágen si es un pixel adjacente al borde del contasre que será incluido en el resultado. Esta configuración puede ajustar la opacidad o grosor del borde en el resultado. + + +Original ImageEdge DetectedFill, no StrokeEdge DetectedStroke, no Fill + + +REDUCCIÓN + + + +El resultado de este filtro producirá una imágen intermedia que es muy diferente de la otra segunda, pero es de hecho muy útil. En vez de mostrar las isóclinas o brillo o contraste, esta buscará los bordes donde los colores cambian, uniformemente igual a brillo y contraste. Las opciones de configuración aquí son: Número de colores, decide cuantos colores de salida pueden haber, si el mapa de bits intermedio era de color. Este entonces decide blanco/negro según si el color ha sido uniforme o posee un indice raro. + + +Original ImageQuantization (12 colors)Fill, no StrokeQuantization (12 colors)Stroke, no Fill + +El usuario puede intentar todos los tres filtros y observar los diferentes tipos de resultados para diferentes tipos de imágenes de entrada. Siempre habrá una imágen donde uno trabajará mejor que otro. + + +Después del trazo, también se sugiere al usuario intentar Trazo > Simplificar +(Ctrl+L) sobre el trazo resultante, para reducir el número de nodos. Esto puede hacer el resultado del Potrace mucho más simple de editar. Por ejemplo, aquí podemos observar el típico trazo del Hombre Viejo Tocando Guitarra: + + +Original ImageTraced Image / Output Path(1,551 nodes) + +Note la gran cantidad de nodos en el trazo. Después de realizar Ctrl+L, este es un resultado típico: + + +Original ImageTraced Image / Output Path - Simplified(384 nodes) + +La representación es un poco más aproximada y áspera, pero el dibujo es mucho más simple y sencillo de editar. +Mantenga en mente que lo que quiere no es una réplica exacta de la imágen, pero un set de de curvas es lo que puede usar en su dibujo. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/share/tutorials/tutorial-tracing.fr.svg b/share/tutorials/tutorial-tracing.fr.svg new file mode 100644 index 000000000..504462900 --- /dev/null +++ b/share/tutorials/tutorial-tracing.fr.svg @@ -0,0 +1,187 @@ + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ::VECTORISATION + + + + + + +Une des fonctionnalités d'Inkscape est la vectorisation d'une image bitmap en un élément chemin inséré dans votre dessin SVG. Ce didacticiel devrait vous aider à comprendre le fonctionnement de cet outil. + + + + + +A l'heure actuelle, Inkscape utilise le moteur de vectorisation de bitmap Potrace (potrace.sourceforge.net) créé par Peter Selinger. Dans le futur, nous espérons permettre l'utilisation d'autres programmes/moteurs de vectorisation; pour le moment, cependant, cet excellent outil est plus que suffisant pour nos besoins. + + +Gardez à l'esprit que le but de la vectorisation avec cet outil n'est pas de produire une duplication exacte de l'image originale, ni de produire un résultat finalisé. Aucun outil de vectorisation automatique ne peut produire cela. Vous obtiendrez un ensemble de courbes que vous pourrez utiliser comme ressources dans votre dessin. + + +Potrace interprète un bitmap en noir et blanc, et produit un ensemble de courbes. Nous avons trois types de filtres d'entrée pour Potrace, afin de convertir les images brutes en quelquechose que Potrace peut exploiter. + + +En général, plus il y a de pixels sombres dans l'image intermédiaire, plus la vectorisation générée par Potrace sera importante. Plus la vectorisation est importante, et plus le temps du processus sera grand et plus le chemin résultant sera important. Nous vous suggérons d'expérimenter cela avec des images intermédiares plutôt claires, en les assombrissant autant que nécessaire afin d'obtenir les taille et complexité désirées pour le chemin résultant. + + +Pour utiliser l'outil de vectorisation, ouvrez ou importez une image, sélectionnez-la, et lancez la commande Chemin > Vectoriser le bitmap ou appuyez sur Maj+Alt+B. + + +Options principales de la boîte de dialogue vectoriser + +Vous voyez trois options de filtrage disponibles : + + + + +Seuil de luminosité + + + + +Cette option utilise simplement la somme des composantes rouge, bleue et verte (ou la nuance de gris) d'un pixel pour déterminer s'il doit être considéré comme blanc ou noir. le seuil peut être réglé entre 0.0 (noir) et 1.0 (blanc). Plus ce seuil est grand, moins les pixels considérés comme "blancs" seront nombreux et plus l'image intermédiaire sera sombre. + + +Image originaleSeuil de luminositéRemplissage,sans contourSeuil de luminositéContoursans remplissage + + + +Détection optimale des arrêtes + + + + +Cette option utilise l'algorithme de détection des arrêtes énoncé par J. Canny, afin de trouver rapidement des isoclines de contraste similaire. Cela produit une image intermédiaire qui ressemble moins à l'image originale que le résultat d'un seuil de luminosité mais qui contient souvent des courbes qui seraient ignorées autrement. Le seuil à régler ici (de 0.0 à 1.0) ajuste le seuil de luminosité afin de déterminer si un pixel adjacent à une courbe de contraste doit être inclus dans le résultat. Le réglage permet d'ajuster l'obscurité ou l'épaisseur des arrêtes du résultat. + + +Image originaleArrêtes detectéesRemplissage,sans contourArrêtes detectéesContour,sans remplissage + + + +Quantification des couleur + + + + +Le résultat de ce filtre produira une image intermédiaire très différente de celle produite avec les deux autres, mais pouvant être aussi très utile. Au lieu de chercher les isoclines de contraste ou de luminosité, il cherche les limites des changements de couleur, même à contraste ou luminosité constants. Le réglage ici, nombre de couleurs, permet de déterminer le nombre de couleurs que l'image intermédiaire devrait avoir si elle était en couleurs. Il exécute ensuite la détermination blanc/noir d'après l'indice pair ou impair des couleurs. + + +Image originaleQuantification(12 couleurs)Remplissage, sans contourQuantification(12 couleurs)Contour, sans remplissage + +Vous devriez essayer ces trois filtres et observer les résultats différents qu'ils produisent pour différents types d'images. Pour une image donnée, il y en aura un qui donnera de meilleurs résultats que les autres. + + +Après la vectorisation, vous devriez essayer d'appliquer la commande Chemin > Simplifier (Ctrl+L) au chemin résultant, afin de diminuer le nombre de nœuds. Cela peut rendre l'édition du résultat de Potrace bien plus facile. Par exemple, voici un exemple typique de vectorisation du "Vieil homme jouant de la guitare" : + + +Image originaleImage vectorisée / Chemin résultant(1,551 nœuds) + +Notez le très grand nombre de nœuds du chemin. Après avoir appuyé sur Ctrl+L, voici un résultat typique : + + +Image originaleImage vectorisée / Chemin résultant - Simplifié(384 nœuds) + +La représentation est un peu plus approximative et grossière, mais le dessin est plus simple et plus facile à éditer. Gardez à l'esprit que ce que vous devez obtenir n'est pas un rendu exact de l'image mais un ensemble de courbes que vous pourrez utiliser dans votre dessin. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/share/tutorials/tutorial-tracing.sl.svg b/share/tutorials/tutorial-tracing.sl.svg new file mode 100644 index 000000000..ece391c40 --- /dev/null +++ b/share/tutorials/tutorial-tracing.sl.svg @@ -0,0 +1,208 @@ + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ::PRERISOVANJE + + + + + + +Inkscape vsebuje tudi orodje za prerisovanje rastrskih slik +v <path> elemente vaših SVG risb. Ta vodič vam bo +pomagal pri spoznavanju tega orodja. + + + + +Ta verzija Inkscapa uporablja prerisovalni rastrski pogon Potrace +(potrace.sourceforge.net), +ki ga je napisal Peter Selinger. V prihodnosti bo Inkscape verjetno podpiral tudi +druge prerisovalne programe, zaenkrat pa to orodje popolnoma zadostuje +našim potrebam. + + +Vedeti morate, da orodje za prerisovanje ni namenjeno točni reprodukciji originalne slike; +prav tako ni namenjeno izdelavi končnih izdelkov, saj to ni naloga orodij za prerisovanje. +Prerisovalna orodja so namenjena samodejnemu ustvarjanju skupka krivulj - nekakšne skice, +ki jo lahko uporabite kot osnovo za vaš izdelek. + + +Potrace predela črnobelo rastrsko sliko v skupek krivulj. Za Potrace trenutno obstajajo +trije tipi filtrov za uvažanje, ki rastrsko sliko spremenijo v Potracu uporabne podatke. + + +Načeloma velja, da temnejši kot je raster, boljše rezultate bo pokazal Potrace. Več prerisovanja pomeni večjo obremenitev za procesor računalnika in <path> element bo precej večji. Najbolje je, da najprej eksperimentirate z bolj svetlimi slikami, nato pa postopoma preidete na +temnejše ter s tem dosežete željeno kompleksnost dobljene poti. + + +Prerisovanje uporabite tako, da naložite ali uvozite sliko, jo označite in izberete +Pot > Preriši raster ali pritisnete Shift+Alt+B. + + +main options within the trace dialog + +Na voljo so vam trije filtri: + + + +Prag svetlosti + + + +Ta filter uporabi seštevek vrednosti rdeče, zelene in modre (oziroma odtenkov sive) barve posamezne točke +za orientacijo, ali naj posamezno točko smatra kot črno ali belo. Prag lahko nastavite od +0,0 (črna) do 1,0 (bela). Višji kot je prag, manjše je število točk, ki jih orodje prepozna kot +\u201cbele\u201d, in vmesna slika bo postala temnejša. + + +Original ImageBrightness ThresholdFill, no StrokeBrightness ThresholdStroke, no Fill + + +Najboljše zaznavanje robov + + + +Ta filter za hitro zaznavanje izoklin podobnega kontrasta uporablja algoritem za +zaznavanje robov, ki ga je razvil J. Canny. Rezultat tega postopka je vmesna slika, +ki bo manj podobna originalu kot pa vmesna slika, ki bi jo naredil filter Prag svetlosti, +vendar pa bo nudila informacije o krivuljah, ki jih drugače ne bi dobili. Prag pri tem +filtru (0,0 \u2013 1,0) nastavlja prag svetlosti, ki določa, ali bo točka ob +kontrastnem robu vključena v rezultat ali ne. Ta izbira določa temnost in debelino +robov vmesne poti. + + +Original ImageEdge DetectedFill, no StrokeEdge DetectedStroke, no Fill + + +Kvantizacija barv + + + +Rezultat tega filtra je vmesna slika, ki je precej različna od ostalih dveh, vendar +je zelo uporabna. Namesto izoklin, svetlosti ali kontrasta ta postopek najde +robove, kjer se spremeni barva, celo pri enaki svetlosti ali kontrastu. Nastavitev +Število barv določa koliko barv bi bilo v izhodni sliki, če bi bil vmesni raster +v barvah. Črna oz. bela se določa na podlagi lihega ali sodega indeksa. + + +Original ImageQuantization (12 colors)Fill, no StrokeQuantization (12 colors)Stroke, no Fill + +Preizkusite vse tri filtre in opazujte različne rezultate, ki jih dajo različni tipi vhodnih slik. Za nekatere slike je najbolj primeren en filter, za druge pa kak drug. + + +Ko je proces prerisovanja končan, na dobljeni poti preizkusite tudi ukaz Pot > Poenostavi +(Ctrl+L), in tako zmanjšajte število vozlišč. To bo dobljeno pot +naredilo lažjo za urejanje. Tu je tipičen preris Starca, ki igra kitaro. + + +Original ImageTraced Image / Output Path(1,551 nodes) + +Poglejte veliko število vozlišč na poti. Po ukazu Pot > Poenostavi bo tipičen rezultat +izgledal tako: + + +Original ImageTraced Image / Output Path - Simplified(384 nodes) + +Poenostavljena pot je malce bolj približna in groba, vendar je slika zato precej +enostavnejša za urejanje. Zapomnite si tudi, da to ni kopija slike, temveč +le skupek krivulj, ki so vam lahko v pomoč pri risanju. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/share/tutorials/tutorial-tracing.svg b/share/tutorials/tutorial-tracing.svg new file mode 100644 index 000000000..4397e472e --- /dev/null +++ b/share/tutorials/tutorial-tracing.svg @@ -0,0 +1,215 @@ + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ::TRACING + + + + + + +One of the features in Inkscape is a tool for tracing a bitmap image +into a <path> element for your SVG drawing. These short notes +should help you become acquainted with how it works. + + + + +Currently Inkscape employs the Potrace bitmap tracing engine (potrace.sourceforge.net) by Peter Selinger. +In the future we expect to allow alternate tracing programs; for now, however, this fine +tool is more than sufficient for our needs. + + +Keep in mind that the Tracer's purpose is not to reproduce an exact duplicate of the +original image; nor is it intended to produce a final product. No autotracer can do +that. What is does is give you a set of curves which you can use as a resource for your +drawing. + + +Potrace interprets a black and white bitmap, and produces a set of curves. For Potrace, +we currently have three types of input filters, to convert from the raw image to +something that Potrace can use. + + +Generally the more dark pixels in the intermediate bitmap, the more tracing that Potrace +will perform. As the amount of tracing increases, more CPU time will be required, and +the <path> element will become much larger. It is suggested that the user experiment +with lighter intermediate images first, getting gradually darker to get the desired +proportion and complexity of the output path. + + +To use the tracer, load or import an image, select it, +and select the Path > Trace Bitmap item, or Shift+Alt+B. + + +main options within the trace dialog + +The user will see the three filter options available: + + + +Brightness Threshold + + + +This merely uses the sum of the red, green and blue (or shades of gray) of a pixel as an +indicator of whether it should be considered black or white. The threshold can be set +from 0.0 (black) to 1.0 (white). The higher the threshold setting, the fewer the number +pixels that will be considered to be \u201cwhite\u201d, and the intermediate image with +become darker. + + +Original ImageBrightness ThresholdFill, no StrokeBrightness ThresholdStroke, no Fill + + +Optimal Edge Detection + + + +This uses the edge detection algorithm devised by J. Canny, as a way of quickly finding +isoclines of similar contrast. This will produce an intermediate bitmap that will look +less like the original image than does the result of Brightness Threshold, but will +likely provide curve information that would otherwise be ignored. The threshold setting +here (0.0 \u2013 1.0) adjusts the brightness threshold of whether a pixel adjacent to a +contrast edge will be included in the output. This setting can adjust the darkness or +thickness of the edge in the output. + + +Original ImageEdge DetectedFill, no StrokeEdge DetectedStroke, no Fill + + +Color Quantization + + + +The result of this filter will produce an intermediate image that is very different from +the other two, but is very useful indeed. Instead of showing isoclines of brightness or +contrast, this will find edges where colors change, even at equal brightness and +contrast. The setting here, Number of Colors, decides how many output colors there +would be if the intermediate bitmap were in color. It then decides black/white on +whether the color has an even or odd index. + + +Original ImageQuantization (12 colors)Fill, no StrokeQuantization (12 colors)Stroke, no Fill + +The user should try all three filters, and observe the different types of output for +different types of input images. There will always be an image where one works better +than the others. + + +After tracing, it is also suggested that the user try Path > Simplify +(Ctrl+L) on the output path, to reduce the number of nodes. This can +make the output of Potrace much easier to edit. For example, here is a typical tracing +of the Old Man Playing Guitar: + + +Original ImageTraced Image / Output Path(1,551 nodes) + +Note the enormous number of nodes in the path. After hitting Ctrl+L, +this is a typical result: + + +Original ImageTraced Image / Output Path - Simplified(384 nodes) + +The representation is a bit more approximate and rough, but the drawing is much simpler +and easier to edit. Keep in mind, that what you want is not an exact rendering of the +image, but a set of curves that you can use in your drawing. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/share/tutorials/tux.png b/share/tutorials/tux.png new file mode 100644 index 0000000000000000000000000000000000000000..49e669c4e7d3998567b29eda421ebeab681d1fd6 GIT binary patch literal 8085 zcmV;GA8O!*00090P)t-s1_KEJ z0uKNN2?PKJ3j_iP1q%WR35(5wv z784W_78n&E7X}*`7aABF8XOrX8wDU9As!$dA|4$r9s?pIAul2cC?q2%B`7r|1|}#a zJSqn(Eh;Z7Dn2L^D=jZOED%911vf7nM=l63Gc__aF*h?ZOfm&YHwid7H%vJKQZ@rP zJ3T%+IXpZyST_e%IR{ca2tGhPUOWUtKR;MP1yey9K|?}bKn7((0!BwgZbS!bMh8ku zNoY$6bV&nLPd;)?0#i;+O;J-%QBH1A1$$2bRaaD6S4x0W1$|crg;oHIRs&&PQC(hK zY+XZLU}KA01%X}>hG7PeUI3F^0A*%mnPCK$WCV|C3YBOMn`jJdZfv1w0gP)amTmx# za1xts0-tLGba7;uY$2p?33GLFn{^4SZ~&-t0HSmahInFndw8XL1EGBco_Qy;b^&;O zf3J86ta}QwdjN`mTz-IkqI@{AfCaaH1g(VwwSE(sfl`EpgR+7kyn_wCg#fsP61#^0 z!-)lqj*GaF1f`2xzmNmMjSa_)4a$xHyN@czkpQ`lIn9v*l$MjVlTXx<3dxuU(Uc0# zmkZXI0L7sI%AN(&n*gtxZpNB0(VhUEpPbj81lybiqMe+soq)HVWZIz()t)ZSs1DVo z4Bn&wz@%l=tpMVu1E;8^+pPrIrz_yA2j;5{>a76cvH<6>0IsjByRDSjw-M{K1K+y= z@UjNvx&^(mpS!cB>bVNlw@&r90PnaC^R^G^z5wpL0Q0&4wz#yswzKiR0O`X3_Pqeh zx{2<>0Peje^uYtWy}H4?y6(sb!@sfc#2xF)3+lgFz{0=A!N2v+0qxBs#mB_T#l-Q^ z8uil!?8j!z$-2qQ$n@9`@z)^q*D%h|&Gpzj)zQQD*hbUU(dE~%+}O$3+SlaZ(caKh-=Iie2_3`5H^6&Nc^ZEPt`uzF({rdd>`vy~p<^TWy0d!JMQvg8b*k%9# z00Cl4M??UK1szBL000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2h<825h4OXT)oQ$`veNXj7;h!3NRe8rVE+Q@ycDZ`@@WNt55h>ptIy zUmhqRmWTL9zpW7x$?u)d^XK#Z{==3YtDg<&r9tDwQ%qg1)}_MzSwyv}(=fB(+j12@2U5U`lmz zTH0ofQV|Soj^U4CN^NR(c50F;S{ekhvA|*hEIlgF3lU_chMQbT;*>pQR;9ZVwmhCRVk61g-qBq(GQK`K{7M#?241&nxgR7kME zB+?K`m~v@+gebrrLu6sH5K)Bo9;GNaV5oQw4VBG`Q_c4)^JTN+?^?fpMO5hQrME`} zNn#=4w_13=T!p%_t)`WogkOQ7|MnC#CG%;E>Dd_@YuN7+8A!pv%KD9)|Ha zI}5e4>5ms+VT%jDa5{&a9*%Ktrjm)PcQ8EX?5k`Z^e}E)dQ33D#Oh9$qc|<6+0C)< zBGE`hB5j|G5^6q}ur($6{6QmGSMtN zq9RiIf41a~)jwSQ4|gp3k=2zd1TQ49_#l9VBn|f6gQO$*r*|HE^(0zvzwp>Q|Cc|T zV1zq3PgyW*OuWMCD2x(`W-R&1fuqK@w$rCi9zFc_iGTmY4{+w5mBz5noN!SPz+%dr z_TP=<*)wwSApxwm5)CBQ`>=C zgCH`=vdlbvNqL*hzrP8|c(c#0d zR@5BdH7^K(OtB%iprpJ8Vg&-j0t1J{SRk&Kk5trDRqUE8ns&bwOIJU9@HbVp0QO1O z+1_5Tu&YoZfSVPG=hmG3lf3MWVUp5gCZ|u>#ibIX%9S?4M^k_p{ckji|0SpQ2g#%CJ9x{NuDh#i^@#fD}NK#>%^yku& zmWE9mm`MJQzxe64T~8i9@gd6JCl0@GP^Zh)ml_P^6~8I@-M@Wsra28YBcaNa=klLR zjhiNsA+Xfu-#@hP;fJ4m8m$8d3-tPu(jx{#Y3ZTY|M2l2dwQ&8Y9z8yb^3G938M;>|R&3DcKSKk*7H^Xuq0 zyU*I=N7mOr=y1AyTs%wKb-yK_GG)pmBBdg+)(V$rJdS=WDav(ez&_;iFg`AxcNWec zwwWoKBF_{{6cKXq>@p_{m*w34%CrrF7CoFl7th$VlIhurL-rdYTkjzD?HL*n$RJ2K zQIy~V7U#^FGc9|BA1FG!KtuQ$j|MqGS(wCBnF!_Q649 z^9;w2v|MSSQx8VpcZHSlyRyeM1fDp8uqb+Q)Rb@d(svEdaRyx416cg1i|bTR`BpT2 zQ*EcmUuzsQiW2F|gAYiin2f&VtaOKm4FDUHi*=^WncD4pAq}f5hXTOHB;y#5yEuGG z4;FZj6s2?y1LH^6CFAk9-PRb%6q0#UN@Q9mlv{o>L0A8#PqG}#FdmoF<#Iaw_NFJD z%$Mt;vzrH;9vb4|>L3%iyoZ5jpg2T-SU`fO(epzNhhu0cNiLasFv;S=daKRq=R`=RN@RX#J=A5D&3yxe1cAA*RNz~N#i)=9 z901hc-*2;hVe7jDg=60XvZ*>*<9n+}ZDnPBr_GM)E~Gq$aXHY}41>%KY>V+Y9gach zEAi^-xpZm3(YXTUOHp{(WP|yY#>ynbg$o?&0iGeJ$G@mR5rPQK26UG$_1Ol8>X)L7 zp}8|gHo0Ve1*kH$zNg;-)(=L`BQ(zAbhCmdq6cLDVEdqA#D>HM|Gp4nSxAglvv~Go z4)dr#;?oxDvP**?Aso3FpkNUgcq7Nax9D%IQ0$!$Er#p^Hru7XL8m=!7V?}ZwOToe z`x1mpt`LhuqtlT~vMfl40KoN;u>lYHpFyvnxPiYRXqRkumsLZ|Y^g>mn^Z87GCndy z9Hu#EM@Ejv~3i*I0{~i063v6^qdNZT${c4%sl2Ext=RS;K71wNMiUI*7>! zt0(fIbR<&}6_PKIz*r(c^f!1ZkPSHd?j-$^B>wgY(d2>2HSzGilB7OVsDhMuLLo46 z!lGGNQ$b zM5H=OG$~*UwNZE*+#?{6P>-V-XpN|qp&m*8@c02gay009@}-Jc%^FR7gjA)LPZ$iv zp4*VX!cqpgVGH3v`N|63$x-$jO|11_ANJ>?sAqI1w1WIEiaQ#6aKE zNQNT^`o{g7*BRyaC?=>&R8iao!8KH4^En(kLh9muS+aUJCD_NOuWI&@TnCo*@^*dsDZ7>-~acQC_G+I=yE^MCu9pC1f{6 zQaI|`I$0X+NhQG(Cvc;gnD@$li$*i-58jW{f2Wsa>0MzH(Iwh(QEDL@iL^sFLh(HB z)hJw;b%Df4xbOxr^3O<=U}?mqAg^EG&{SQBC7SvvaC8 z?1v1_P`IifQbR66vN^{&Qhi`6CQ|$0%1(pQWPCG2f+eZHSfL3=U@Tr(Fhb#vY7C(z z_BAS;Gu;O^q2qYSO6O}p=AxtlhE%PjUSM%LVhI?9WGOi>kRS&ov6dme$-A<>(QD~M zPQ8)R^>%o((6k}Hj7?*v7mTIm&f@x-7i^#A0wKP@zw#6c`je?Aa2A#Lwel_iQxv;- z*5CD5lD46_g%-d+NztI@tJb{M4}Uzxg2l@;6KIx5iLTVbr&QK^gtCIg;feSk>v0e; zmh(XqGRB8X)Q>e^EX0Uens49u(nzRGf@q=YWT?yYf-12UAuxu94vzQ6e~xByp~<9; z6VH?hIcdH|GC?p|OmZj`187c-^BqHsn;}LnfboO`wF0!77F^X=hr?G)89nqVj#Yna zFzj7+yjiHGM8#Tk@aL!;=;&6eL$M|wN>&@lp34xET6ii;F6i*B+BvO?!ODszs z5c+GL7cPn}prXlYOS3n8ev2pFjy0_qNL%z-l~E|l@I34@74pzMjl+ikSrryU0p z0_%1-$;@ByLy{wX8xutBEGd9EccF~jNUoHHNF|bqfr&$vDrLHZR>^oeN2+C9StE(j z`T-|#tTlL<<^9qsZPR%cRTrZ0IJGKL9;u9tjhsafmR+aqOXe=Rbfd zbS_6ae~=j7C809|8Y*!2!Fcl%bzr1qM~YY$sZvHLB;qhdgfcchK6d_fA4ZbSTfOVm zqpv=8hg2+Inm#}ZRE8y&r@bVyF%RRHyjg1RBrg!dqLnyOvF*;#$Y|lfgGdq<6{k(s zD6SJMVcW}fW{bsmbi+*X?0epI()`H!Pbe@L8`zw)-ufbNvH=?RRK`R^h5A>np)tv+ z>N(eUupsxf2J;12mg5gfMT+(HZklRv{u6>N0uw?AFXVPAJJzd8h!kJ{9oGN;VqWyH zQNL8PUOWH#z)EVGS}stsnW6|yrHiA5DorvhRV5veF?fhgyI~rEh1!<=`+xl>TJJyh z{lFvZ;s`aGWn2%K-cW1mun1%`L}5V22sx6+Ss6?YgOMtl7aAydiHwUmPH4tG|843< zht|8_z9SGUBvutWXTcAzhYOvfHWRQ5mbbyq!c>KJw8e%C8j1%g3C-47(%E4#`Z7HA zP=x&TN#m!Vp>wi_1CP>+6w2rb`G&X8UkBKc>PA6g7cQ7zT`d($RXGEA=K+^|SR6R= zv)+jv$)`g4W;t3{a{Sjdb>^<_&pzvYA@E$dcy^>zy6DN)D_6$LRa9cAZ8TXdl&q`m z=_L}eBsSIRrV)YmMD8JIc>Rn&u=4ljQ~)zsE_~YC`s9K@Fo{S!^T89nSFT(fuOiV& zeL<6m?9^j(#Ug3s`gdI{=Qo;Q(1?JhYwv~<>#L3^3G9N8?Dz(F%MiJ`(kYAwu)#APMkomJ$iO=bVuhJC!uu|7nyH0g?cYWG+bX2MWP~Wj*2198{iJ_vZuBpWj3)b0Jm*9xFIDNpo3CLk# zk#<(t-D3TM1kDm2*Wcc+ZLwI)4OItM&KMTQ9z5FG+V+XX^x9}#&+854HMO<1HC0tr zwRMfg0C~acZhe#-&ks+vda$ptB>aQHlZpsW5~+~LfB>tPaXI?`3=%V&O?6d8+ivkM zDkL*jzt+&&W;Rt(*<`FO*XuSckchlkw`?k^YB&wd?Tsa)aJ{H6uWdB8m`o;P z6Ii{)G90X{xAg@Ygl21s2g&%0<{V*z(mO||c>z}$j(!XVAGWEkyrdv=(=Bsn$mJ6G z%y~=h+f`twMK?BCEG-qIft8^9KRVjM63oM>1d*LTwQDZ@sLHefk8d2naNe4NWK)dB zl5pz*fdN+1dJu#iwfB2zm(0UK_(t|q-LFHB?civ;Xns{x>?v8Eiz3UYOsnVDI+dC%)htLj=z z@&4#`jdUyeg5qqdUJ4CQm2P!{P+J@ zUpA*>0aWx;FarW>s;enS=fxo+!2?8rx)$Nno6W|W5y5_qY|L!2i~(lp>TW%-NN_2U zJQeH=<1iGEgbQJ=Pf{1-u_NPu9h7E7BCDw`FE`*-0a2;R?0frBtn46wff-&HYjt&> zKe@|01Q#tVbWsB*nq!2yFeii#Y-89fUoSzrG#MM}AW&A9S5#C~)ztb2aR4)oNLFyD z9NlCzhAy!(TaWr~PLwA*$Y_f8Ktg%%H8{LHLjwp5-ri_Lv8b+=uDS-J-}OKt9j1{& zMgfXrEgfTnfyhojy1*N^R}6Cg!l5mi(5ln?&A0|_m+F80GE^%q5GGrU5WvxbSZ)ju z1juYeGedX&T?-6C#`&WUdPSxhAT^h8%7SP8nsuQ_V_bIIxgR~H$6y`ijutRABS0C^ z?R=I%FtfR#W`xQxu+SNi3=-4n=a&e{ZiStsZqB=xL`RN7M}h}^0G9KE#{mo~9~39e zD7}E_T3XPz!#?>4LMtk*9$R7-6mh${drv*Oh>ns9U4r`&k7Vd(14mj)7LQR_SAYKE zC0WQ)Of5KOwc{{u_K)R0GK;0*_&34Elo*b?mhRrOM>ot6iAA!QY&*j--ptL>xnl}Q$z;DI|Lw~xuFSZ_7Ha|v_-s~j1q$FJMjQ{2{ z=dBhQdv+AMOH^M`+hDR-#xxb-LgvN*8+!}lMaSqLMQ}{8|C0~>OPOtm5vpm{dsKk) z3mRC6tfxOcN+g!AL|{!O^LWUh(g*}At*$j%Xri=?L3Z|h>(OWa?2Dx&d;6*jU(pZI z)w&r?>So-R`EmtmZY3Kn+;#r^sh3`H3p;_{?Cp2Fhia5{ zSCUQ1xoZ)a(bPU3F0;9@&W|e(gZWj6Bfp1*i0t@NXBdtS@95AUKa!CJOP_NV$B{|v zybYN}RF&5RGq*I>)dWO-6fWAYC2aKiCm^!l{M6=c(pX;L<9uh2c-GmxUKpUl5Tn=C$ zvD&dDhKh?85Ld;Kk`aeH*F?kaYHVmY{&MEpMVg#Gw{Q0kA1+`$E?ZgJU4c`4>GDmF z7ahZvGFspUn}>p^+EDV1q6d7kk+ub+1TqW7f;iLAQ1zN_Yr@QMb!u^QzuoC_56-$Z= zMk*6apb>|Hsl^Qcb##oWQUI&1D9PQu?pEozeubjsmbr!`$w(Ihsbn`0J_+1z9^c-aSt=POz<61*jYGD|>Ko zKvXr=hC>BeqtDLs@}LJjgm3gNFR!kt!FW)Wn?QE$)a>YLX{p%UKJ7^z_kdI0}@`%O||8v1^f4H zA1|2XmQ`E!?nm_=8bY+=8n)eRYHCF7Z>j#-%xexf_hn>cX6W`mixjIz;xl070$dA* zYlqL-ZbpjK=Vt8Ly6*1rN^IrEJ^S+xfqTKHgi^l)VyV$si)>3@pd05@c;CLvOx^zd zxw*NZ+kzqxpP`}}B-aG71X2o$gH?u-f~>teHm*$=uZ<;a+>yB-{oW329ni%!K{Q3u z%F|_D$B2LDj@^Klk&%(5+phyY2qgwEyISNDNc^Sxg8h4UY`OpLW!Ln|n=#mer=an-VACJ}$(zb?esc+jnf;x@F78`x93#|K9cd{Icb%)^6Fp zCo>}x{hyh+Z|9axlXS1(s>HQx*KI`W{`=P^u1vV~`hI-bvV_ESNbY<0?b*F^`<8Wy z36pkvWkSN;iFn<;GGW>GuKUNAEl)@U!EfBSY2DiURxQ72Qda_A%a?t-pI!z(yK?2K jmGIY1->vV~jj;Y7G)7EL_7$wT00000NkvXXu0mjfki|%{ literal 0 HcmV?d00001 diff --git a/share/ui/.cvsignore b/share/ui/.cvsignore new file mode 100644 index 000000000..282522db0 --- /dev/null +++ b/share/ui/.cvsignore @@ -0,0 +1,2 @@ +Makefile +Makefile.in diff --git a/share/ui/Makefile.am b/share/ui/Makefile.am new file mode 100644 index 000000000..d65668115 --- /dev/null +++ b/share/ui/Makefile.am @@ -0,0 +1,11 @@ + +uidir = $(datadir)/inkscape/ui + +ui_DATA = \ + keybindings.rc \ + menus-bars.xml \ + toolbox.xml \ + units.txt \ + units.xml + +EXTRA_DIST = $(ui_DATA) diff --git a/share/ui/keybindings.rc b/share/ui/keybindings.rc new file mode 100644 index 000000000..968678249 --- /dev/null +++ b/share/ui/keybindings.rc @@ -0,0 +1,126 @@ +; inkscape GtkAccelMap rc-file -*- scheme -*- +; Simply edit the key bindings you wish to override and restart Inkscape. +; +; File menu +;TODO: VacuumDefs +(gtk_accel_path "//New" "n") +(gtk_accel_path "//Open" "o") +(gtk_accel_path "//Revert" "r") +(gtk_accel_path "//Save" "s") +(gtk_accel_path "//SaveAs" "s") +(gtk_accel_path "//Import" "i") +(gtk_accel_path "//Export" "e") +(gtk_accel_path "//Print" "p") +(gtk_accel_path "//PrintPreview" "p") +(gtk_accel_path "//DocumentProperties" "d") +(gtk_accel_path "//InkscapePreferences" "p") +(gtk_accel_path "//Close" "w") +(gtk_accel_path "//Quit" "q") +; +; Edit menu +(gtk_accel_path "//Undo" "z") +(gtk_accel_path "//Redo" "y") +(gtk_accel_path "//Cut" "x") +(gtk_accel_path "//Copy" "c") +(gtk_accel_path "//Paste" "v") +(gtk_accel_path "//PasteInPlace" "v") +(gtk_accel_path "//PasteStyle" "v") +(gtk_accel_path "//Find" "f") +(gtk_accel_path "//Duplicate" "d") +(gtk_accel_path "//Clone" "d") +(gtk_accel_path "//CloneUnlink" "d") +(gtk_accel_path "//CloneSelectOrig" "d") +(gtk_accel_path "//MakeBitmap" "b") +(gtk_accel_path "//Tile" "i") +(gtk_accel_path "//Untile" "i") +(gtk_accel_path "//Delete" "Delete") +(gtk_accel_path "//SelectAll" "a") +(gtk_accel_path "//SelectNone" "a") +(gtk_accel_path "//XmlEditor" "x") +; +; View menu +;TODO: ShowHide Messages WindowDuplicate +(gtk_accel_path "//ZoomIn" "plus") +(gtk_accel_path "//ZoomOut" "minus") +(gtk_accel_path "//Zoom100" "1") +(gtk_accel_path "//Zoom50" "2") +(gtk_accel_path "//Zoom200" "") +(gtk_accel_path "//ZoomSelection" "3") +(gtk_accel_path "//ZoomDrawing" "4") +(gtk_accel_path "//ZoomPage" "5") +(gtk_accel_path "//ZoomWidth" "6") +(gtk_accel_path "//ZoomPrevious" "grave") +(gtk_accel_path "//ZoomNext" "grave") +(gtk_accel_path "//ShowHideDialogs" "F12") +(gtk_accel_path "//Messages" "") +(gtk_accel_path "//Grid" "numbersign") +(gtk_accel_path "//Guides" "bar") +(gtk_accel_path "//Fullscreen" "F11") +(gtk_accel_path "//WindowPrevious" "Tab") +(gtk_accel_path "//WindowNext" "Tab") +; +; Layer menu +;TODO: NewLayer RenameLayer SwitchToNextLayer SwitchToPrevLayer DeleteCurrentLayer +(gtk_accel_path "//RaiseLayer" "Page_Up") +(gtk_accel_path "//LowerLayer" "Page_Down") +(gtk_accel_path "//LayerToTop" "Home") +(gtk_accel_path "//LayerToBottom" "End") +; +; Object menu +;TODO: MoveToNewLayer MoveToNextLayer MoveToPrevLayer MoveToTopLayer MoveToBottomLayer +(gtk_accel_path "//FillAndStroke" "f") +(gtk_accel_path "//ObjectProperties" "o") +(gtk_accel_path "//Group" "g") +(gtk_accel_path "//Ungroup" "u") +(gtk_accel_path "//Raise" "Page_Up") +(gtk_accel_path "//Lower" "Page_Down") +(gtk_accel_path "//RaiseToTop" "Home") +(gtk_accel_path "//LowerToBottom" "End") +(gtk_accel_path "//Rotate90CW" "Right") +(gtk_accel_path "//Rotate90CCW" "Left") +(gtk_accel_path "//FlipHoriz" "h") +(gtk_accel_path "//FlipVert" "v") +(gtk_accel_path "//Transform" "m") +(gtk_accel_path "//AlignAndDistribute" "a") +; +; Path menu +;TODO: Reverse Cleanup +(gtk_accel_path "//ObjectToPath" "c") +(gtk_accel_path "//StrokeToPath" "c") +(gtk_accel_path "//Trace" "b") +(gtk_accel_path "//Union" "plus") +(gtk_accel_path "//Difference" "minus") +(gtk_accel_path "//Intersection" "asterisk") +(gtk_accel_path "//Exclusion" "asciicircum") +(gtk_accel_path "//Division" "slash") +(gtk_accel_path "//CutPath" "slash") +(gtk_accel_path "//Combine" "k") +(gtk_accel_path "//BreakApart" "k") +(gtk_accel_path "//Inset" "parenleft") +(gtk_accel_path "//Outset" "parenright") +(gtk_accel_path "//OffsetDynamic" "j") +(gtk_accel_path "//OffsetLinked" "j") +(gtk_accel_path "//Simplify" "l") +; +; Text menu +;TODO: PutOnPath RemoveFromPath RemoveManualKerns +(gtk_accel_path "//TextProperties" "t") +; +; About menu +;TODO: KeysAndMouse Tutorials About +; +; Tools toolbox +(gtk_accel_path "//ToolSelect" "F1") +(gtk_accel_path "//ToolNode" "F2") +(gtk_accel_path "//ToolZoom" "F3") +(gtk_accel_path "//ToolRect" "F4") +(gtk_accel_path "//ToolArc" "F5") +(gtk_accel_path "//ToolStar" "asterisk") +(gtk_accel_path "//ToolSpiral" "F9") +(gtk_accel_path "//ToolFreehand" "F6") +(gtk_accel_path "//ToolPen" "F6") +(gtk_accel_path "//ToolDynaDraw" "F6") +(gtk_accel_path "//ToolText" "F8") +(gtk_accel_path "//ToolDropper" "F7") +; +;TODO: tool controls and other actions diff --git a/share/ui/menus-bars.xml b/share/ui/menus-bars.xml new file mode 100644 index 000000000..ceb9aaa50 --- /dev/null +++ b/share/ui/menus-bars.xml @@ -0,0 +1,280 @@ + + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/share/ui/toolbox.xml b/share/ui/toolbox.xml new file mode 100644 index 000000000..53994651f --- /dev/null +++ b/share/ui/toolbox.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/share/ui/units.txt b/share/ui/units.txt new file mode 100644 index 000000000..a82cec529 --- /dev/null +++ b/share/ui/units.txt @@ -0,0 +1,20 @@ +# Simple unit configuration file +# +# This is a space-delimited list of unit definitions. + +# name name_plural abbr type factor PRI description +# --------------------------------------------------------------------------- + % % % DIMENSIONLESS 1.00 Y Percentage + pixel pixels px LINEAR 1.00 Y CSS Pixels (90/inch) + point points pt LINEAR 1.25 N PostScript points (72/inch) + pica picas pc LINEAR 15.0 N 12 points + inch inches in LINEAR 90.0 N Inches (90 px/in) + millimeter millimeters mm LINEAR 3.543307 N Millimeters (25.4 mm/in) + centimeter centimeters cm LINEAR 35.43307 N Centimeters (10 mm/cm) + meter meters m LINEAR 3543.307 N Meters (100 cm/m) + foot feet ft LINEAR 1080 N Feet (12 in/ft) + degree degrees deg RADIAL 1.00 Y Degrees + radian radians rad RADIAL 57.296 N Radians (57.296 deg/rad) + font-height font-heights em FONT_HEIGHT 1.00 Y Font height + x-height x-heights ex FONT_HEIGHT 0.50 N Height of letter 'x' + half-em half-ems en FONT_HEIGHT 0.50 N Half of font height diff --git a/share/ui/units.xml b/share/ui/units.xml new file mode 100644 index 000000000..e4a07fe06 --- /dev/null +++ b/share/ui/units.xml @@ -0,0 +1,101 @@ + + + + % + % + % + 1.00 + Percentage + + + pixel + pixels + px + 1.00 + CSS Pixels (90/inch) + + + point + points + pt + 1.25 + PostScript points (72/inch) + + + pica + picas + pc + 15.0 + 12 points + + + inch + inches + in + 90.0 + Inches (90 px/in) + + + millimeter + millimeters + mm + 3.543307 + Millimeters (25.4 mm/in) + + + centimeter + centimeters + cm + 35.43307 + Centimeters (10 mm/cm) + + + meter + meters + m + 3543.307 + Meters (100 cm/m) + + + foot + feet + ft + 1080 + Feet (12 in/ft) + + + degree + degrees + deg + 1.00 + Degrees + + + radian + radians + rad + 57.296 + Radians (57.296 deg/rad) + + + font-height + font-heights + em + 1.00 + Font height + + + x-height + x-heights + ex + 0.50 + Height of letter 'x' + + + half-em + half-ems + en + 0.50 + Half of font height + + diff --git a/src/.cvsignore b/src/.cvsignore new file mode 100644 index 000000000..4cdeae202 --- /dev/null +++ b/src/.cvsignore @@ -0,0 +1,19 @@ +*.la +*.lo +*.o +*.a +.deps +.libs +Makefile +Makefile.in +TAGS +tags +check-header-compile +doxygen-log +inkscape +inkscape_version.h +inkview +spsvgview +inkscape.def +*.dll +*-test diff --git a/src/Doxyfile b/src/Doxyfile new file mode 100644 index 000000000..fae65d053 --- /dev/null +++ b/src/Doxyfile @@ -0,0 +1,269 @@ +# Doxyfile: default configuration for `doxygen'. + +# We'll explicitly list inputs (for faster doxygen runs), but will probably +# switch to recursive scan once we have a large number of inputs. +#FILE_PATTERNS = *.cpp *.h +#RECURSIVE = yes +# find -name '*.cpp' -o -name '*.h'|xargs grep -l '\\file'|sort|sed 's,^./, ,;s,$, \\,' +# (and remove the non source files sp-skeleton.*). +INPUT = \ + application/application.cpp \ + application/application.h \ + application/editor.cpp \ + application/editor.h \ + arc-context.cpp \ + attributes.cpp \ + attributes.h \ + color-rgba.h \ + color.cpp \ + color.h \ + composite-undo-stack-observer.h \ + desktop-style.cpp \ + desktop.cpp \ + desktop.h \ + dialogs/color-picker.h \ + dialogs/desktop-properties.cpp \ + dialogs/export.cpp \ + dialogs/filedialog.h \ + dialogs/unclump.h \ + dir-util.cpp \ + display/bezier-utils.cpp \ + display/curve.cpp \ + display/curve.h \ + display/sp-canvas.cpp \ + display/sp-canvas.h \ + document-undo.cpp \ + document.cpp \ + document.h \ + draw-anchor.cpp \ + draw-anchor.h \ + event-context.cpp \ + event-context.h \ + extension/extension.cpp \ + extension/extension.h \ + extension/implementation/plugin-link.h \ + extension/implementation/plugin.cpp \ + extension/implementation/plugin.h \ + extension/implementation/script.cpp \ + extension/internal/bluredge.cpp \ + extension/internal/gimpgrad.cpp \ + extension/internal/gimpgrad.h \ + extension/internal/grid.cpp \ + extension/internal/ps.cpp \ + extension/internal/ps.h \ + extension/parameter.cpp \ + extension/parameter.h \ + fill-or-stroke.h \ + gc-anchored.h \ + gc-managed.h \ + geom.cpp \ + geom.h \ + grid-snapper.cpp \ + grid-snapper.h \ + guide-snapper.cpp \ + guide-snapper.h \ + helper/action.cpp \ + helper/action.h \ + jabber_whiteboard/buddy-list-manager.h \ + jabber_whiteboard/callbacks.h \ + jabber_whiteboard/chat-handler.h \ + jabber_whiteboard/defines.h \ + jabber_whiteboard/deserializer.h \ + jabber_whiteboard/error-codes.h \ + jabber_whiteboard/internal-constants.h \ + jabber_whiteboard/invitation-confirm-dialog.h \ + jabber_whiteboard/jabber-handlers.h \ + jabber_whiteboard/message-aggregator.h \ + jabber_whiteboard/message-contexts.h \ + jabber_whiteboard/message-handler.h \ + jabber_whiteboard/message-node.h \ + jabber_whiteboard/message-processors.cpp \ + jabber_whiteboard/message-processors.h \ + jabber_whiteboard/message-queue.h \ + jabber_whiteboard/message-tags.h \ + jabber_whiteboard/message-utilities.h \ + jabber_whiteboard/node-tracker-event-tracker.h \ + jabber_whiteboard/node-tracker-observer.h \ + jabber_whiteboard/node-tracker.cpp \ + jabber_whiteboard/node-tracker.h \ + jabber_whiteboard/node-utilities.h \ + jabber_whiteboard/session-file-player.h \ + jabber_whiteboard/session-file-selector.h \ + jabber_whiteboard/session-file.h \ + jabber_whiteboard/session-manager.h \ + jabber_whiteboard/tracker-node.h \ + jabber_whiteboard/typedefs.h \ + jabber_whiteboard/undo-stack-observer.h \ + knot-enums.h \ + knot-holder-entity.h \ + knot.cpp \ + knot.h \ + libnr/n-art-bpath.h \ + libnr/nr-matrix-scale-ops.h \ + libnr/nr-matrix-translate-ops.h \ + libnr/nr-matrix.cpp \ + libnr/nr-matrix.h \ + libnr/nr-path-code.h \ + libnr/nr-pixblock.cpp \ + libnr/nr-pixblock.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate-fns.cpp \ + libnr/nr-rotate-fns.h \ + libnr/nr-rotate.h \ + libnr/nr-scale-matrix-ops.h \ + libnr/nr-types.cpp \ + libnrtype/boundary-type.h \ + libnrtype/one-box.h \ + libnrtype/one-glyph.h \ + libnrtype/text-boundary.h \ + livarot/float-line.cpp \ + livarot/float-line.h \ + livarot/int-line.cpp \ + livarot/int-line.h \ + livarot/sweep-event-queue.h \ + livarot/sweep-event.h \ + livarot/sweep-tree-list.h \ + main.cpp \ + message-context.h \ + message-stack.h \ + modifier-fns.h \ + nodepath.cpp \ + nodepath.h \ + object-hierarchy.cpp \ + object-hierarchy.h \ + pen-context.cpp \ + pen-context.h \ + pencil-context.cpp \ + pencil-context.h \ + preferences.cpp \ + preferences.h \ + print.cpp \ + print.h \ + removeoverlap/remove_rectangle_overlap.h \ + selection.cpp \ + selection.h \ + shortcuts.cpp \ + snap.cpp \ + snap.h \ + snapper.cpp \ + snapper.h \ + sp-animation.cpp \ + sp-gradient-fns.h \ + sp-gradient.cpp \ + sp-gradient.h \ + sp-item-notify-moveto.cpp \ + sp-item.cpp \ + sp-item.h \ + sp-linear-gradient-fns.h \ + sp-linear-gradient.h \ + sp-object.cpp \ + sp-object.h \ + sp-offset.cpp \ + sp-offset.h \ + sp-radial-gradient-fns.h \ + sp-radial-gradient.h \ + sp-root.cpp \ + sp-root.h \ + sp-spiral.cpp \ + sp-spiral.h \ + sp-stop.h \ + style.cpp \ + style.h \ + svg-view-widget.cpp \ + svg-view-widget.h \ + svg-view.cpp \ + svg-view.h \ + ui/dialog/document-preferences.cpp \ + ui/dialog/document-preferences.h \ + ui/view/edit-widget-interface.h \ + ui/view/view-widget.cpp \ + ui/view/view-widget.h \ + ui/view/view.cpp \ + ui/view/view.h \ + ui/widget/color-picker.cpp \ + ui/widget/color-picker.h \ + ui/widget/color-preview.cpp \ + ui/widget/color-preview.h \ + ui/widget/entity-entry.cpp \ + ui/widget/entity-entry.h \ + ui/widget/licensor.cpp \ + ui/widget/licensor.h \ + ui/widget/page-sizer.cpp \ + ui/widget/page-sizer.h \ + ui/widget/registered-widget.cpp \ + ui/widget/registered-widget.h \ + ui/widget/registry.cpp \ + ui/widget/registry.h \ + ui/widget/ruler.cpp \ + ui/widget/ruler.h \ + ui/widget/svg-canvas.cpp \ + ui/widget/svg-canvas.h \ + ui/widget/zoom-status.cpp \ + ui/widget/zoom-status.h \ + undo-stack-observer.h \ + uri.cpp \ + uri.h \ + util/list.h \ + verbs.cpp \ + verbs.h \ + widgets/desktop-widget.cpp \ + widgets/desktop-widget.h \ + widgets/icon.cpp \ + widgets/paint-selector.cpp \ + widgets/paint-selector.h \ + widgets/toolbox.cpp \ + xml/quote.cpp \ + xml/repr-sorting.h \ + xml/repr-util.cpp \ + xml/repr.cpp \ + xml/repr.h + + +# Uncomment this to treat undocumented things as if they had an empty +# documentation string; comment it out to suppress all undocumented things from +# the output. +# Leaving it uncommented allows using doxygen output as the primary information +# source about a class (without needing to look at the source code to look for +# undocumented things). +# OTOH, you may find it annoying to have reems of relatively unhelpful +# information: commenting it out gives more compact display of the helpful +# bits. +# I'm commenting it out for now to facilitate checking existing doc comments +# for doxygen correctness. +#EXTRACT_ALL = yes + +# I'll disable this for the moment, to reduce the number of files in the output. +SOURCE_BROWSER = no + +# Keep the output out of the src directory so that it doesn't get in the way of +# `rgrep'. +OUTPUT_DIRECTORY = ../doxygen + +# In absence of explicit `\brief', treat the first "sentence" as the brief part +# and the rest as detail. (With explicit `\brief', the first _paragraph_ is +# considered the brief part.) +# +# It's unclear whether programmers should deliberately use this facility. +# Advantage: Less clutter. +# Disadvantage: Absence of `\brief' may indicate that the comment was written +# by someone unfamiliar with doxygen and not giving thought to what the brief +# description should be. Using explicit `\brief' may facilitate checking +# non-\briefed comments for doxygen correctness. +# OTOH, using `\brief' may be parrot-like: it doesn't necessarily indicate +# doxygen familiarity. +JAVADOC_AUTOBRIEF = yes + +WARN_IF_UNDOCUMENTED = yes + +GENERATE_TODOLIST = yes + +GENERATE_BUGLIST = yes + +REFERENCED_BY_RELATION = yes + +EXTRACT_STATIC = yes + +WARN_LOGFILE = doxygen-log + diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 000000000..73e6deb36 --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,261 @@ +## Process this file with automake to produce Makefile.in + + +# ################################################ +# +# G L O B A L +# +# ################################################ + +# Should work in either automake1.7 or 1.8, but 1.6 doesn't +# handle foo/libfoo_a_CPPFLAGS properly (if at all). +# Update: We now avoid setting foo/libfoo_a_CPPFLAGS, +# so perhaps 1.6 will work. +AUTOMAKE_OPTIONS = 1.7 subdir-objects + +INCLUDES = \ + $(PERL_CFLAGS) $(PYTHON_CFLAGS) \ + $(FREETYPE_CFLAGS) \ + $(GNOME_PRINT_CFLAGS) \ + $(GNOME_VFS_CFLAGS) \ + $(LIBLOUDMOUTH_CFLAGS) \ + $(XFT_CFLAGS) \ + -DPOTRACE=\"potrace\" \ + $(INKSCAPE_CFLAGS) \ + -I$(top_srcdir)/cxxtest + +include Makefile_insert +include application/Makefile_insert +include dialogs/Makefile_insert +include display/Makefile_insert +include dom/Makefile_insert +include extension/Makefile_insert +include extension/implementation/Makefile_insert +include extension/internal/Makefile_insert +include extension/script/Makefile_insert +include helper/Makefile_insert +include inkjar/Makefile_insert +include io/Makefile_insert +include jabber_whiteboard/Makefile_insert +include libcroco/Makefile_insert +include libnr/Makefile_insert +include libnrtype/Makefile_insert +include libavoid/Makefile_insert +include livarot/Makefile_insert +include removeoverlap/Makefile_insert +include svg/Makefile_insert +include utest/Makefile_insert +include widgets/Makefile_insert +include debug/Makefile_insert +include xml/Makefile_insert +include traits/Makefile_insert +include algorithms/Makefile_insert +include ui/Makefile_insert +include ui/dialog/Makefile_insert +include ui/view/Makefile_insert +include ui/widget/Makefile_insert +include util/Makefile_insert +include trace/Makefile_insert + +bin_PROGRAMS = inkscape inkview + +noinst_LIBRARIES = \ + libinkpre.a \ + application/libinkapp.a \ + dialogs/libspdialogs.a \ + jabber_whiteboard/libjabber_whiteboard.a \ + display/libspdisplay.a \ + dom/libdom.a \ + extension/implementation/libimplementation.a \ + extension/internal/libinternal.a \ + extension/libextension.a \ + extension/script/libscript.a \ + helper/libspchelp.a \ + io/libio.a \ + libcroco/libcroco.a \ + ui/libui.a \ + ui/dialog/libuidialog.a \ + ui/view/libuiview.a \ + ui/widget/libuiwidget.a \ + util/libinkutil.a \ + debug/libinkdebug.a \ + $(inkjar_libs) \ + libnr/libnr.a \ + libnrtype/libnrtype.a \ + libavoid/libavoid.a \ + livarot/libvarot.a \ + removeoverlap/libremoveoverlap.a \ + svg/libspsvg.a \ + widgets/libspwidgets.a \ + trace/libtrace.a \ + xml/libspxml.a \ + libinkpost.a + +check_LIBRARIES = \ + libnr/libtest-nr.a \ + svg/libtest-svg.a \ + xml/libtest-xml.a + +DISTCLEANFILES = \ + helper/sp-marshal.cpp \ + helper/sp-marshal.h \ + inkscape_version.h + +EXTRA_DIST = \ + mkdep.pl \ + mkfiles.pl \ + make.exclude \ + make.dep \ + make.files \ + make.ofiles \ + Doxyfile \ + sp-skeleton.cpp sp-skeleton.h \ + algorithms/makefile.in \ + application/makefile.in \ + debug/makefile.in \ + dialogs/makefile.in \ + dialogs/filedialog-win32.cpp \ + display/makefile.in \ + dom/makefile.in \ + extension/implementation/makefile.in \ + extension/internal/makefile.in \ + extension/makefile.in \ + extension/plugin/makefile.in \ + extension/script/makefile.in \ + helper/makefile.in \ + inkjar/makefile.in \ + io/makefile.in \ + io/crystalegg.xml \ + io/doc2html.xsl \ + jabber_whiteboard/makefile.in \ + libcroco/makefile.in \ + libnr/makefile.in \ + libnrtype/makefile.in \ + libavoid/makefile.in \ + livarot/makefile.in \ + removeoverlap/makefile.in \ + svg/makefile.in \ + trace/makefile.in \ + traits/makefile.in \ + utest/makefile.in \ + ui/makefile.in \ + ui/dialog/makefile.in \ + ui/view/makefile.in \ + ui/widget/makefile.in \ + util/makefile.in \ + widgets/makefile.in \ + xml/makefile.in \ + extension/internal/gnome.cpp \ + extension/internal/gnome.h \ + extension/internal/win32.cpp \ + extension/internal/win32.h \ + helper/sp-marshal.list \ + utest/utest.h \ + utest/test-1ary-cases.h \ + traits/copy.h \ + traits/function.h \ + traits/list-copy.h \ + traits/reference.h \ + $(jabber_whiteboard_SOURCES) + +EXTRA_PROGRAMS = \ + inkview \ + libnr/testnr + +TESTS = \ + test-all$(EXEEXT) \ + attributes-test$(EXEEXT) \ + dir-util-test$(EXEEXT) \ + extract-uri-test$(EXEEXT) \ + mod360-test$(EXEEXT) \ + round-test$(EXEEXT) \ + sp-gradient-test$(EXEEXT) \ + sp-style-elem-test$(EXEEXT) \ + style-test$(EXEEXT) \ + display/bezier-utils-test$(EXEEXT) \ + helper/units-test$(EXEEXT) \ + libnr/in-svg-plane-test$(EXEEXT) \ + libnr/nr-matrix-test$(EXEEXT) \ + libnr/nr-point-fns-test$(EXEEXT) \ + libnr/nr-rotate-test$(EXEEXT) \ + libnr/nr-rotate-fns-test$(EXEEXT) \ + libnr/nr-scale-test$(EXEEXT) \ + libnr/nr-translate-test$(EXEEXT) \ + libnr/nr-types-test$(EXEEXT) \ + libnr/test-nr$(EXEEXT) \ + removeoverlap/remove_rectangle_overlap-test$(EXEEXT) \ + svg/test-svg$(EXEEXT) \ + util/list-container-test$(EXEEXT) \ + xml/test-xml$(EXEEXT) \ + xml/quote-test$(EXEEXT) \ + xml/repr-action-test$(EXEEXT) + +# streamtest is unfinished and can't handle the relocations done during +# "make distcheck". Not needed for the 0.41 release. +# io/streamtest$(EXEEXT) + +# automake adds $(EXEEXT) to check_PROGRAMS items but not to TESTS items: +# TESTS items can be scripts etc. + +check_PROGRAMS = \ + test-all \ + attributes-test \ + dir-util-test \ + extract-uri-test \ + mod360-test \ + round-test \ + sp-gradient-test \ + sp-style-elem-test \ + style-test \ + display/bezier-utils-test \ + helper/units-test \ + libnr/in-svg-plane-test \ + libnr/nr-matrix-test \ + libnr/nr-point-fns-test \ + libnr/nr-rotate-test \ + libnr/nr-rotate-fns-test \ + libnr/nr-scale-test \ + libnr/nr-translate-test \ + libnr/nr-types-test \ + libnr/test-nr \ + removeoverlap/remove_rectangle_overlap-test \ + svg/test-svg \ + util/list-container-test \ + xml/test-xml \ + xml/quote-test \ + xml/repr-action-test + +# io/streamtest + + +test-all.cpp: \ + $(libnr_test_nr_a_SOURCES) \ + $(svg_test_svg_a_SOURCES) \ + $(xml_test_xml_a_SOURCES) \ + $(libnr_test_nr_includes) \ + $(svg_test_svg_includes) \ + $(xml_test_xml_includes) + $(top_srcdir)/cxxtest/cxxtestgen.pl --error-printer -root -o test-all.cpp \ + $(libnr_test_nr_includes) \ + $(svg_test_svg_includes) \ + $(xml_test_xml_includes) + +test_all_SOURCES = \ + test-all.cpp + +test_all_LDADD = \ + $(libnr_test_nr_LDADD) \ + $(svg_test_svg_LDADD) \ + $(xml_test_xml_LDADD) + + +# ################################################ +# +# D I S T +# +# ################################################ + +dist-hook: + mkdir $(distdir)/pixmaps + cp $(srcdir)/pixmaps/*xpm $(distdir)/pixmaps + diff --git a/src/Makefile.mingw b/src/Makefile.mingw new file mode 100644 index 000000000..b3afb5cfe --- /dev/null +++ b/src/Makefile.mingw @@ -0,0 +1,123 @@ +########################################################################### +# $Id$ +########################################################################### +# Makefile for building with MinGW +########################################################################### + +include ../Makefile.mingw.common + +all: generated outputs + +################################### +# G E N E R A T E D F I L E S +################################### + +generated: helper/sp-marshal.h helper/sp-marshal.cpp inkscape_version.h + + + +helper/sp-marshal.h: helper/sp-marshal.h.mingw + $(CP) $(subst /,$(S), $<) $(subst /,$(S), $@) + +helper/sp-marshal.cpp: helper/sp-marshal.cpp.mingw + $(CP) $(subst /,$(S), $<) $(subst /,$(S), $@) + +inkscape_version.h: inkscape_version.h.mingw + $(CP) inkscape_version.h.mingw inkscape_version.h + + +################################### +# D E P E N D E N C I E S +################################### + +include ./make.ofiles +include ./make.dep + +INC += $(INCLUDEPATH) + +OBJ = $(OBJECTS) + + + +################################### +# O U T P U T S +################################### + +outputs: inkscape.exe inkview.exe + + +RES=inkres.o + +inkscape.exe: libinkscape.a main.o winmain.o $(RES) + $(CXX) --export-dynamic -o inkscape.exe main.o winmain.o $(RES) libinkscape.a $(LIBS) +# strip inkscape.exe + +# DLL version. we need to make this work +#inkscape.exe: inkscape.dll main.o winmain.o $(RES) +# $(CXX) -o inkscape.exe main.o winmain.o $(RES) inkscape.la $(LIBS) +# strip inkscape.exe + +inkview.exe: libinkscape.a inkview.o $(RES) + $(CXX) -o inkview.exe inkview.o $(RES) libinkscape.a $(LIBS) +# strip inkview.exe + +# DLL version. we need to make this work +# inkview.exe: inkscape.dll inkview.o $(RES) +# $(CXX) -o inkview.exe inkview.o $(RES) libinkscapedll.a $(LIBS) +# strip inkview.exe + +inkres.o: inkscape.rc + $(WINDRES) inkscape.rc $(RES) + +inkscape.dll: libinkscape.a inkscape.def + $(DLLWRAP) --output-lib=inkscape.la \ + --def=inkscape.def --driver-name=g++ \ + -o inkscape.dll libinkscape.a $(LIBS) + +inkscape.def: libinkscape.a + perl makedef.pl + +libinkscape.a: $(OBJ) + -$(RM) libinkscape.a + ar crv libinkscape.a $(OBJ) + $(RANLIB) libinkscape.a + +inkscape.la: inkscape.dll + + + +################################### +# P L U G I N S +################################### + +.o.dll: $< + $(DLLWRAP) --def=plugin.def --driver-name=g++ \ + -o $@ $< $(LIBS) + +PLUGS = extension/plugin/gimpgrad.dll + +plugins: $(PLUGS) + +extension/plugin/gimpgrad.dll: extension/plugin/gimpgrad.o inkscape.la + $(DLLWRAP) --def=plugin.def --driver-name=g++ \ + -dllname $@ $< inkscape.la $(LIBS) -lgc + strip $@ + + + + +################################### +# C L E A N U P +################################### + +clean: + $(foreach a, $(OBJ), $(shell $(RM) $(subst /,$(S), $(a)))) + -$(RM) main.o winmain.o inkview.o + -$(RM) *.a + -$(RM) *.la + -$(RM) inkscape.def + -$(RM) *.dll + -$(RM) extension$(S)plugin$(S)*.o + -$(RM) extension$(S)plugin$(S)*.dll + + diff --git a/src/Makefile.mingw.old b/src/Makefile.mingw.old new file mode 100644 index 000000000..1483746c8 --- /dev/null +++ b/src/Makefile.mingw.old @@ -0,0 +1,53 @@ +########################################################################### +# $Id$ +########################################################################### +# Makefile for building with MinGW +########################################################################### + +include ../Makefile.mingw.common + + + +#Check for 'generated' files +all: helper/sp-marshal.h helper/sp-marshal.cpp inkscape_version.h inkscape.exe + +helper/sp-marshal.h: helper/sp-marshal.h.mingw + $(CP) $(subst /,$(S), $<) $(subst /,$(S), $@) + +helper/sp-marshal.cpp: helper/sp-marshal.cpp.mingw + $(CP) $(subst /,$(S), $<) $(subst /,$(S), $@) + +inkscape_version.h: inkscape_version.h.mingw + $(CP) inkscape_version.h.mingw inkscape_version.h + +include ./make.ofiles +include ./make.dep + +INC += $(INCLUDEPATH) + +OBJ = $(OBJECTS) + +RES=inkres.o + +inkscape.exe: libinkscape.a main.o winmain.o $(RES) + $(CXX) -o inkscape.exe main.o winmain.o $(RES) libinkscape.a $(LIBS) +# strip inkscape.exe + +inkview.exe: libinkscape.a inkview.o $(RES) + $(CXX) -o inkview.exe inkview.o $(RES) libinkscape.a $(LIBS) + strip inkview.exe + +inkres.o: inkscape.rc + $(WINDRES) inkscape.rc $(RES) + +libinkscape.a: $(OBJ) + $(RM) libinkscape.a + ar crv libinkscape.a $(OBJ) + $(RANLIB) libinkscape.a + + +clean: + $(foreach a, $(OBJ), $(shell $(RM) $(subst /,$(S), $(a)))) + $(RM) *.a + + diff --git a/src/Makefile_insert b/src/Makefile_insert new file mode 100644 index 000000000..44439f164 --- /dev/null +++ b/src/Makefile_insert @@ -0,0 +1,339 @@ +## Makefile.am fragment, included by src/Makefile.am. + + +# ################################################ +# +# E X T R A +# +# ################################################ + +if PLATFORM_WIN32 +win32_sources = winmain.cpp +win32ldflags = -lcomdlg32 +endif + +if INKJAR +inkjar_dir = inkjar +inkjar_libs = inkjar/libinkjar.a +endif + + +# ################################################ +# +# I N K S C A P E +# +# ################################################ + +# libinkpre.a: any object that's sharable between inkscape & inkview, +# and isn't needed by object files in subdirectories (i.e. libinkpre.a +# comes before subdirectory libraries on the link line). +# +# Excludes winmain.cpp (a gui wrapper around main): I'm guessing that +# it needs to be explicitly listed as a source of each graphical +# binary: it isn't (to my knowledge) called by main (whether directly +# or indirectly), so I don't think that putting it in a library will +# suffice to get it linked in. Windows devel please confirm. -- pjrm. + +libinkpre_a_SOURCES = \ + algorithms/find-last-if.h \ + algorithms/longest-common-suffix.h \ + approx-equal.h remove-last.h \ + arc-context.cpp arc-context.h \ + attributes.cpp attributes.h \ + bad-uri-exception.h \ + brokenimage.xpm \ + color-rgba.h \ + conn-avoid-ref.cpp conn-avoid-ref.h \ + connector-context.cpp connector-context.h \ + context-fns.cpp context-fns.h \ + desktop-affine.cpp desktop-affine.h \ + desktop-events.cpp desktop-events.h \ + desktop-handles.cpp desktop-handles.h \ + desktop-style.cpp desktop-style.h \ + desktop.cpp desktop.h \ + document-undo.cpp \ + document.cpp document.h document-private.h \ + draw-anchor.cpp \ + draw-anchor.h \ + draw-context.cpp draw-context.h \ + dropper-context.cpp dropper-context.h \ + dyna-draw-context.cpp dyna-draw-context.h \ + enums.h \ + event-context.cpp event-context.h \ + extract-uri.cpp extract-uri.h \ + file.cpp file.h \ + fontsize-expansion.cpp fontsize-expansion.h \ + forward.h \ + geom.cpp geom.h \ + gnuc-attribute.h \ + gradient-context.cpp gradient-context.h \ + gradient-drag.cpp gradient-drag.h \ + help.cpp help.h \ + inkscape-stock.cpp inkscape-stock.h\ + inkscape.cpp inkscape.h inkscape-private.h \ + interface.cpp interface.h \ + isnan.h \ + knot-enums.h \ + knot-holder-entity.h \ + knot.cpp knot.h \ + knotholder.cpp knotholder.h \ + layer-fns.cpp layer-fns.h \ + macros.h \ + marker-status.cpp marker-status.h \ + media.cpp media.h \ + message-context.cpp message-context.h \ + message-stack.cpp message-stack.h \ + message.h \ + mod360.cpp mod360.h \ + modifier-fns.h \ + node-context.cpp node-context.h \ + nodepath.cpp nodepath.h \ + object-edit.cpp object-edit.h \ + object-hierarchy.cpp object-hierarchy.h \ + object-ui.cpp object-ui.h \ + path-chemistry.cpp path-chemistry.h \ + path-prefix.h \ + pen-context.cpp \ + pen-context.h \ + pencil-context.cpp \ + pencil-context.h \ + preferences.cpp preferences.h \ + preferences-skeleton.h \ + menus-skeleton.h \ + prefix.cpp \ + prefix.h \ + prefs-utils.cpp \ + prefs-utils.h \ + print.cpp print.h \ + rect-context.cpp rect-context.h \ + require-config.h \ + rubberband.cpp rubberband.h \ + satisfied-guide-cns.cpp satisfied-guide-cns.h \ + selcue.cpp selcue.h \ + select-context.cpp select-context.h \ + selection-chemistry.cpp selection-chemistry.h \ + selection-describer.cpp selection-describer.h \ + selection.cpp selection.h \ + seltrans-handles.cpp seltrans-handles.h \ + seltrans.cpp seltrans.h \ + shortcuts-default-xml.cpp \ + shortcuts.cpp shortcuts.h \ + slideshow.cpp slideshow.h \ + snap.cpp snap.h \ + snapped-point.cpp snapped-point.h \ + snapper.cpp snapper.h \ + line-snapper.cpp line-snapper.h \ + grid-snapper.cpp grid-snapper.h \ + guide-snapper.cpp guide-snapper.h \ + object-snapper.cpp object-snapper.h \ + sp-anchor.cpp sp-anchor.h \ + sp-clippath.cpp sp-clippath.h \ + sp-conn-end-pair.cpp sp-conn-end-pair.h \ + sp-conn-end.cpp sp-conn-end.h \ + sp-cursor.cpp sp-cursor.h \ + sp-defs.cpp sp-defs.h \ + sp-ellipse.cpp sp-ellipse.h \ + sp-flowdiv.h sp-flowdiv.cpp \ + sp-flowregion.h sp-flowregion.cpp \ + sp-flowtext.h sp-flowtext.cpp \ + sp-gradient-fns.h \ + sp-gradient-reference.cpp \ + sp-gradient-reference.h \ + sp-gradient-spread.h \ + sp-gradient-units.h \ + sp-gradient-vector.h \ + sp-gradient.cpp sp-gradient.h \ + sp-guide-attachment.h \ + sp-guide-constraint.h \ + sp-guide.cpp sp-guide.h \ + sp-image.cpp sp-image.h \ + sp-item-group.cpp sp-item-group.h \ + sp-item-notify-moveto.cpp sp-item-notify-moveto.h \ + sp-item-rm-unsatisfied-cns.cpp sp-item-rm-unsatisfied-cns.h \ + sp-item-transform.cpp sp-item-transform.h \ + sp-item-update-cns.cpp sp-item-update-cns.h \ + sp-item.cpp sp-item.h \ + sp-line.cpp sp-line.h \ + sp-linear-gradient-fns.h \ + sp-linear-gradient.h \ + sp-marker-loc.h \ + sp-marker.cpp sp-marker.h \ + sp-mask.cpp sp-mask.h \ + sp-metadata.cpp sp-metadata.h \ + sp-metric.h \ + sp-metrics.cpp sp-metrics.h \ + sp-namedview.cpp sp-namedview.h \ + sp-object-group.cpp sp-object-group.h \ + sp-object-repr.cpp sp-object-repr.h \ + sp-object.cpp sp-object.h \ + sp-offset.cpp sp-offset.h \ + sp-paint-server.cpp sp-paint-server.h \ + sp-path.cpp sp-path.h \ + sp-pattern.cpp sp-pattern.h \ + sp-polygon.cpp sp-polygon.h \ + sp-polyline.cpp sp-polyline.h \ + sp-radial-gradient-fns.h \ + sp-radial-gradient.h \ + sp-rect.cpp sp-rect.h \ + sp-root.cpp sp-root.h \ + sp-shape.cpp sp-shape.h \ + sp-spiral.cpp sp-spiral.h \ + sp-star.cpp sp-star.h \ + sp-stop-fns.h \ + sp-stop.h \ + sp-string.cpp sp-string.h \ + sp-symbol.cpp sp-symbol.h \ + sp-text.cpp sp-text.h \ + sp-textpath.h \ + sp-tspan.cpp sp-tspan.h \ + sp-use-reference.cpp sp-use-reference.h \ + sp-use.cpp sp-use.h \ + spiral-context.cpp spiral-context.h \ + splivarot.cpp splivarot.h \ + star-context.cpp star-context.h \ + streams-gzip.h streams-gzip.cpp \ + streams-handles.h streams-handles.cpp \ + streams-jar.h streams-jar.cpp \ + streams-zlib.h streams-zlib.cpp \ + style.cpp style.h \ + sp-style-elem.cpp sp-style-elem.h \ + svg-profile.h \ + svg-view.cpp svg-view.h \ + svg-view-widget.cpp svg-view-widget.h \ + text-chemistry.cpp text-chemistry.h \ + text-context.cpp text-context.h \ + text-editing.cpp text-editing.h \ + text-tag-attributes.h \ + tools-switch.cpp tools-switch.h\ + uri-references.cpp uri-references.h \ + verbs.cpp verbs.h \ + version.cpp version.h \ + zoom-context.cpp zoom-context.h + +# Force libinkpost.a to be rebuilt if we add files to libinkpost_a_SOURCES. +libinkpost_a_DEPENDENCIES = Makefile_insert + +# libinkpost.a: Any object file that needs to be near the end of the link line. +# gradient-chemistry.o is called by some things in display/. +libinkpost_a_SOURCES = \ + color.cpp color.h \ + decimal-round.h \ + dir-util.cpp dir-util.h \ + fill-or-stroke.h \ + fixes.cpp \ + gc-alloc.h \ + gc-anchored.h gc-anchored.cpp \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + gc.cpp \ + gradient-chemistry.cpp gradient-chemistry.h \ + memeq.h \ + round.h \ + streq.h \ + strneq.h \ + composite-undo-stack-observer.h \ + composite-undo-stack-observer.cpp \ + undo-stack-observer.h \ + unit-constants.h \ + uri.cpp uri.h + +inkscape_private_libs = \ + libinkpre.a \ + application/libinkapp.a \ + ui/dialog/libuidialog.a \ + dialogs/libspdialogs.a \ + dom/libdom.a \ + jabber_whiteboard/libjabber_whiteboard.a \ + trace/libtrace.a \ + svg/libspsvg.a \ + widgets/libspwidgets.a \ + display/libspdisplay.a \ + helper/libspchelp.a \ + libcroco/libcroco.a \ + libnrtype/libnrtype.a \ + libnr/libnr.a \ + libavoid/libavoid.a \ + livarot/libvarot.a \ + ui/view/libuiview.a \ + ui/libui.a \ + ui/widget/libuiwidget.a \ + removeoverlap/libremoveoverlap.a \ + extension/libextension.a \ + extension/implementation/libimplementation.a \ + extension/internal/libinternal.a \ + extension/script/libscript.a \ + xml/libspxml.a \ + util/libinkutil.a \ + io/libio.a \ + $(inkjar_libs) \ + libinkpost.a \ + debug/libinkdebug.a + +all_libs = \ + $(inkscape_private_libs) \ + $(INKSCAPE_LIBS) \ + $(GNOME_PRINT_LIBS) \ + $(GNOME_VFS_LIBS) \ + $(XFT_LIBS) \ + $(FREETYPE_LIBS) \ + $(kdeldadd) \ + $(win32ldflags) \ + $(PERL_LDFLAGS) \ + $(PYTHON_LIBS) \ + $(LIBLOUDMOUTH_LIBS) + +desktop.$(OBJEXT): helper/sp-marshal.h +document.$(OBJEXT): helper/sp-marshal.h inkscape_version.h +extension/internal/latex-pstricks.$(OBJEXT): inkscape_version.h +extension/internal/ps.$(OBJEXT): inkscape_version.h +inkscape.$(OBJEXT): helper/sp-marshal.h inkscape_version.h +knot.$(OBJEXT): helper/sp-marshal.h +main.$(OBJEXT): inkscape_version.h +selection.$(OBJEXT): helper/sp-marshal.h +sp-object.$(OBJEXT): helper/sp-marshal.h +sp-root.$(OBJEXT): inkscape_version.h +view.$(OBJEXT): helper/sp-marshal.h +help.$(OBJEXT): inkscape_version.h + + +# ################################################ +# +# B I N A R I E S +# +# ################################################ + + +inkscape_SOURCES = main.cpp $(win32_sources) +inkscape_LDADD = $(all_libs) +inkscape_LDFLAGS = --export-dynamic $(kdeldflags) + +inkview_SOURCES = inkview.cpp $(win32_sources) +inkview_LDADD = $(all_libs) + +attributes_test_SOURCES = attributes-test.cpp +attributes_test_LDADD = attributes.$(OBJEXT) -lglib-2.0 + +dir_util_test_SOURCES = dir-util-test.cpp utest/test-2ary-cases.h +dir_util_test_LDADD = dir-util.$(OBJEXT) -lglib-2.0 + +mod360_test_SOURCES = mod360-test.cpp +mod360_test_LDADD = libinkpre.a -lglib-2.0 + +extract_uri_test_SOURCES = extract-uri-test.cpp +extract_uri_test_LDADD = libinkpre.a -lglib-2.0 + +round_test_SOURCES = round-test.cpp +round_test_LDADD = libinkpost.a + +sp_gradient_test_SOURCES = sp-gradient-test.cpp +sp_gradient_test_LDADD = $(all_libs) + +sp_style_elem_test_SOURCES = sp-style-elem-test.cpp +sp_style_elem_test_LDADD = $(all_libs) + +style_test_SOURCES = style-test.cpp +style_test_LDADD = $(all_libs) + +inkscape_version.h: ../configure.ac + echo '#define INKSCAPE_VERSION "$(VERSION)"' > inkscape_version.h diff --git a/src/algorithms/.cvsignore b/src/algorithms/.cvsignore new file mode 100644 index 000000000..b4fcd8525 --- /dev/null +++ b/src/algorithms/.cvsignore @@ -0,0 +1,2 @@ +makefile + diff --git a/src/algorithms/Makefile_insert b/src/algorithms/Makefile_insert new file mode 100644 index 000000000..dff5b578d --- /dev/null +++ b/src/algorithms/Makefile_insert @@ -0,0 +1,5 @@ + +algorithms/all: + +algorithms/clean: + diff --git a/src/algorithms/find-if-before.h b/src/algorithms/find-if-before.h new file mode 100644 index 000000000..6a0f63be6 --- /dev/null +++ b/src/algorithms/find-if-before.h @@ -0,0 +1,51 @@ +/* + * Inkscape::Algorithms::find_if_before - finds the position before + * the first value that satisifes + * the predicate + * + * Authors: + * MenTaLguY + * + * Copyright (C) 2005 MenTaLguY + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifndef SEEN_INKSCAPE_ALGORITHMS_FIND_IF_BEFORE_H +#define SEEN_INKSCAPE_ALGORITHMS_FIND_IF_BEFORE_H + +#include + +namespace Inkscape { + +namespace Algorithms { + +template +inline ForwardIterator find_if_before(ForwardIterator start, + ForwardIterator end, + UnaryPredicate pred) +{ + ForwardIterator before=end; + while ( start != end && !pred(*start) ) { + before = start; + ++start; + } + return ( start != end ) ? before : end; +} + +} + +} + +#endif + +/* + 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 : diff --git a/src/algorithms/find-last-if.h b/src/algorithms/find-last-if.h new file mode 100644 index 000000000..1ffd63b9c --- /dev/null +++ b/src/algorithms/find-last-if.h @@ -0,0 +1,51 @@ +/* + * Inkscape::Algorithms::find_last_if + * + * Authors: + * MenTaLguY + * + * Copyright (C) 2004 MenTaLguY + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifndef SEEN_INKSCAPE_ALGORITHMS_FIND_LAST_IF_H +#define SEEN_INKSCAPE_ALGORITHMS_FIND_LAST_IF_H + +#include + +namespace Inkscape { + +namespace Algorithms { + +template +inline ForwardIterator find_last_if(ForwardIterator start, ForwardIterator end, + UnaryPredicate pred) +{ + ForwardIterator last_found(end); + while ( start != end ) { + start = std::find_if(start, end, pred); + if ( start != end ) { + last_found = start; + ++start; + } + } + return last_found; +} + +} + +} + +#endif + +/* + 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 : diff --git a/src/algorithms/longest-common-suffix.h b/src/algorithms/longest-common-suffix.h new file mode 100644 index 000000000..04d2b179d --- /dev/null +++ b/src/algorithms/longest-common-suffix.h @@ -0,0 +1,114 @@ +/* + * Inkscape::Algorithms::longest_common_suffix + * + * Authors: + * MenTaLguY + * + * Copyright (C) 2004 MenTaLguY + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifndef SEEN_INKSCAPE_ALGORITHMS_LONGEST_COMMON_SUFFIX_H +#define SEEN_INKSCAPE_ALGORITHMS_LONGEST_COMMON_SUFFIX_H + +#include +#include +#include "util/list.h" + +namespace Inkscape { + +namespace Algorithms { + +/** + * Time costs: + * + * The case of sharing a common successor is handled in O(1) time. + * + * If \a a is the longest common suffix, then runs in O(len(rest of b)) time. + * + * Otherwise, runs in O(len(a) + len(b)) time. + */ + +template +ForwardIterator longest_common_suffix(ForwardIterator a, ForwardIterator b, + ForwardIterator end) +{ + typedef typename std::iterator_traits::value_type value_type; + return longest_common_suffix(a, b, end, std::equal_to()); +} + +template +ForwardIterator longest_common_suffix(ForwardIterator a, ForwardIterator b, + ForwardIterator end, BinaryPredicate pred) +{ + if ( a == end || b == end ) { + return end; + } + + /* Handle in O(1) time the common cases of identical lists or tails. */ + { + /* identical lists? */ + if ( a == b ) { + return a; + } + + /* identical tails? */ + ForwardIterator tail_a(a); + ForwardIterator tail_b(b); + if ( ++tail_a == ++tail_b ) { + return tail_a; + } + } + + /* Build parallel lists of suffixes, ordered by increasing length. */ + + using Inkscape::Util::List; + using Inkscape::Util::cons; + ForwardIterator lists[2] = { a, b }; + List suffixes[2]; + + for ( int i=0 ; i < 2 ; i++ ) { + for ( ForwardIterator iter(lists[i]) ; iter != end ; ++iter ) { + if ( iter == lists[1-i] ) { + // the other list is a suffix of this one + return lists[1-i]; + } + + suffixes[i] = cons(iter, suffixes[i]); + } + } + + /* Iterate in parallel through the lists of suffix lists from shortest to + * longest, stopping before the first pair of suffixes that differs + */ + + ForwardIterator longest_common(end); + + while ( suffixes[0] && suffixes[1] && + pred(**suffixes[0], **suffixes[1]) ) + { + longest_common = *suffixes[0]; + ++suffixes[0]; + ++suffixes[1]; + } + + return longest_common; +} + +} + +} + +#endif /* !SEEN_INKSCAPE_ALGORITHMS_LONGEST_COMMON_SUFFIX_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 : diff --git a/src/algorithms/makefile.in b/src/algorithms/makefile.in new file mode 100644 index 000000000..293b5e8ca --- /dev/null +++ b/src/algorithms/makefile.in @@ -0,0 +1,17 @@ +# Convenience stub makefile to call the real Makefile. + +@SET_MAKE@ + +# Explicit so that it's the default rule. +all: + cd .. && $(MAKE) algorithms/all + +clean %.a %.o: + cd .. && $(MAKE) algorithms/$@ + +.PHONY: all clean + +OBJEXT = @OBJEXT@ + +.SUFFIXES: +.SUFFIXES: .a .$(OBJEXT) diff --git a/src/application/.cvsignore b/src/application/.cvsignore new file mode 100644 index 000000000..38efca7bc --- /dev/null +++ b/src/application/.cvsignore @@ -0,0 +1,3 @@ +.deps +.dirstamp +makefile diff --git a/src/application/Makefile_insert b/src/application/Makefile_insert new file mode 100644 index 000000000..9a5306ec7 --- /dev/null +++ b/src/application/Makefile_insert @@ -0,0 +1,14 @@ +## Makefile.am fragment sourced by src/Makefile.am. + +application/all: application/libinkapp.a + +application/clean: + rm -f application/libinkapp.a $(application_libinkapp_a_OBJECTS) + +application_libinkapp_a_SOURCES = \ + application/editor.cpp \ + application/editor.h \ + application/application.cpp \ + application/application.h \ + application/app-prototype.cpp \ + application/app-prototype.h diff --git a/src/application/app-prototype.cpp b/src/application/app-prototype.cpp new file mode 100644 index 000000000..b94f5ea05 --- /dev/null +++ b/src/application/app-prototype.cpp @@ -0,0 +1,43 @@ +/** + * \brief Base class for different application modes + * + * Author: + * Bryce W. Harrington + * + * Copyright (C) 2005 Bryce Harrington + * + * Released under GNU GPL. Read the file 'COPYING' for more information. + */ + +#include "app-prototype.h" + +namespace Inkscape { +namespace NSApplication { + +AppPrototype::AppPrototype() +{ +} + +AppPrototype::AppPrototype(int argc, const char **argv) +{ +} + +AppPrototype::~AppPrototype() +{ +} + + +} // namespace NSApplication +} // 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:textwidth=99 : diff --git a/src/application/app-prototype.h b/src/application/app-prototype.h new file mode 100644 index 000000000..a7c8ad86f --- /dev/null +++ b/src/application/app-prototype.h @@ -0,0 +1,53 @@ +/** + * \brief Base class for different application modes + * + * Author: + * Bryce W. Harrington + * + * Copyright (C) 2005 Bryce Harrington + * + * Released under GNU GPL. Read the file 'COPYING' for more information. + */ + +#ifndef INKSCAPE_APPLICATION_APP_PROTOTYPE_H +#define INKSCAPE_APPLICATION_APP_PROTOTYPE_H + +namespace Gtk { +class Window; +} + + +namespace Inkscape { +namespace NSApplication { + +class AppPrototype +{ +public: + AppPrototype(); + AppPrototype(int argc, const char **argv); + virtual ~AppPrototype(); + + virtual void* getWindow() = 0; + +protected: + AppPrototype(AppPrototype const &); + AppPrototype& operator=(AppPrototype const &); + +}; + +} // namespace NSApplication +} // namespace Inkscape + + +#endif /* !INKSCAPE_APPLICATION_APP_PROTOTYPE_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:encoding=utf-8:textwidth=99 : diff --git a/src/application/application.cpp b/src/application/application.cpp new file mode 100644 index 000000000..4b1ea03df --- /dev/null +++ b/src/application/application.cpp @@ -0,0 +1,163 @@ +/** \file + * \brief The top level class for managing the application. + * + * Authors: + * Bryce W. Harrington + * Ralf Stephan + * + * Copyright (C) 2005 Authors + * + * Released under GNU GPL. Read the file 'COPYING' for more information. + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#include "preferences.h" +#include "application.h" +#include "editor.h" + +int sp_main_gui(int argc, char const **argv); +int sp_main_console(int argc, char const **argv); + +static Gtk::Main *_gtk_main; +static bool _use_gui, _new_gui; + +namespace Inkscape { +namespace NSApplication { + +Application::Application(int argc, char **argv, bool use_gui, bool new_gui) + : _argc(argc), + _argv(NULL), + _app_impl(NULL), + _path_home(NULL) +{ + _use_gui = use_gui; + _new_gui = new_gui; + + if (argv != NULL) { + _argv = argv; // TODO: Is this correct? + } + + Inkscape::Preferences::loadSkeleton(); + if (new_gui) { + _gtk_main = new Gtk::Main(argc, argv, true); + + // TODO: Determine class by arguments + g_warning("Creating new Editor"); + _app_impl = (AppPrototype*) Editor::create(_argc, _argv); + + } else if (use_gui) { + // No op - we'll use the old interface + } else { + _app_impl = NULL; // = Cmdline(_argc, _argv); + } + + /// \todo Install segv handler here? + +// Inkscape::Extension::init(); +} + +Application::~Application() +{ + g_free(_path_home); +} + + +/** Returns the current home directory location */ +gchar const* +Application::homedir() const +{ + if ( !_path_home ) { + _path_home = g_strdup(g_get_home_dir()); + gchar* utf8Path = g_filename_to_utf8( _path_home, -1, NULL, NULL, NULL ); + if ( utf8Path ) { + _path_home = utf8Path; + if ( !g_utf8_validate(_path_home, -1, NULL) ) { + g_warning( "Home directory is non-UTF-8" ); + } + } + } + if ( !_path_home && _argv != NULL) { + gchar * path = g_path_get_dirname(_argv[0]); + gchar * utf8Path = g_filename_to_utf8( path, -1, NULL, NULL, NULL ); + g_free(path); + if (utf8Path) { + _path_home = utf8Path; + if ( !g_utf8_validate(_path_home, -1, NULL) ) { + g_warning( "Application run directory is non-UTF-8" ); + } + } + } + return _path_home; +} + +gint +Application::run() +{ + gint result = 0; + + /* Note: This if loop should be replaced by calls to the + * various subclasses of I::A::AppPrototype. + */ + if (_gtk_main != NULL) { + g_assert(_app_impl != NULL); + + Inkscape::Preferences::load(); + g_warning("Running main window"); + Gtk::Window *win = static_cast(_app_impl->getWindow()); + g_assert(win != NULL); + _gtk_main->run(*win); + result = 0; + + } else if (_use_gui) { + result = sp_main_gui(_argc, (const char**)_argv); + + } else { + result = sp_main_console(_argc, (const char**)_argv); + } + + return result; +} + +void +Application::exit() +{ + Inkscape::Preferences::save(); + + if (_gtk_main != NULL) { + _gtk_main->quit(); + } + +} + +bool +Application::getUseGui() +{ + return _use_gui; +} + +bool +Application::getNewGui() +{ + return _new_gui; +} + + +} // namespace NSApplication +} // 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:textwidth=99 : diff --git a/src/application/application.h b/src/application/application.h new file mode 100644 index 000000000..212add9e8 --- /dev/null +++ b/src/application/application.h @@ -0,0 +1,65 @@ +/** \file + * \brief The top level class for managing the application. + * + * Authors: + * Bryce W. Harrington + * Ralf Stephan + * + * Copyright (C) 2005 Authors + * + * Released under GNU GPL. Read the file 'COPYING' for more information. + */ + +#ifndef INKSCAPE_APPLICATION_APPLICATION_H +#define INKSCAPE_APPLICATION_APPLICATION_H + +#include + +namespace Gtk { +class Main; +} + +namespace Inkscape { +namespace NSApplication { +class AppPrototype; + +class Application +{ +public: + Application(int argc, char **argv, bool use_gui=true, bool new_gui=false); + virtual ~Application(); + + gchar const *homedir() const; + + gint run(); + + static bool getUseGui(); + static bool getNewGui(); + static void exit(); + +protected: + Application(Application const &); + Application& operator=(Application const &); + + gint _argc; + char **_argv; + AppPrototype *_app_impl; + + mutable gchar *_path_home; +}; + +} // namespace NSApplication +} // namespace Inkscape + +#endif /* !INKSCAPE_APPLICATION_APPLICATION_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:encoding=utf-8:textwidth=99 : diff --git a/src/application/editor.cpp b/src/application/editor.cpp new file mode 100644 index 000000000..6c3dbf896 --- /dev/null +++ b/src/application/editor.cpp @@ -0,0 +1,416 @@ +/** \file + * \brief Editor Implementation class declaration for Inkscape. This + * singleton class implements much of the functionality of the former + * 'inkscape' object and its services and signals. + * + * Authors: + * Bryce W. Harrington + * Derek P. Moore + * Ralf Stephan + * + * Copyright (C) 2004-2005 Authors + * + * Released under GNU GPL. Read the file 'COPYING' for more information. + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +/* + TODO: Replace SPDocument with the new Inkscape::Document + TODO: Change 'desktop's to 'view*'s + TODO: Add derivation from Inkscape::Application::RunMode +*/ + + +#include "path-prefix.h" +#include "io/sys.h" +#include "sp-object-repr.h" +#include +#include "document.h" +#include "sp-namedview.h" +#include "event-context.h" +#include "sp-guide.h" +#include "selection.h" +#include "editor.h" +#include "application/application.h" +#include "preferences.h" +#include "ui/view/edit-widget.h" + +namespace Inkscape { +namespace NSApplication { + +static Editor *_instance = 0; +static void *_window; + +Editor* +Editor::create (gint argc, char **argv) +{ + if (_instance == 0) + { + _instance = new Editor (argc, argv); + _instance->init(); + } + return _instance; +} + +Editor::Editor (gint argc, char **argv) +: _documents (0), + _desktops (0), + _argv0 (argv[0]), + _dialogs_toggle (true) + +{ + sp_object_type_register ("sodipodi:namedview", SP_TYPE_NAMEDVIEW); + sp_object_type_register ("sodipodi:guide", SP_TYPE_GUIDE); + + Inkscape::Preferences::load(); +} + +bool +Editor::init() +{ + // Load non-local template until we have everything right + // This code formerly lived in file.cpp + // + gchar const *tmpl = g_build_filename ((INKSCAPE_TEMPLATESDIR), "default.svg", NULL); + bool have_default = Inkscape::IO::file_test (tmpl, G_FILE_TEST_IS_REGULAR); + SPDocument *doc = sp_document_new (have_default? tmpl:0, true, true); + g_return_val_if_fail (doc != 0, false); + Inkscape::UI::View::EditWidget *ew = new Inkscape::UI::View::EditWidget (doc); + sp_document_unref (doc); + _window = ew->getWindow(); + return ew != 0; +} + +Editor::~Editor() +{ +} + +/// Returns the Window representation of this application object +void* +Editor::getWindow() +{ + return _window; +} + +/// Returns the active document +SPDocument* +Editor::getActiveDocument() +{ + if (getActiveDesktop()) { + return SP_DT_DOCUMENT (getActiveDesktop()); + } + + return NULL; +} + +void +Editor::addDocument (SPDocument *doc) +{ + g_assert (!g_slist_find (_instance->_documents, doc)); + _instance->_documents = g_slist_append (_instance->_documents, doc); +} + +void +Editor::removeDocument (SPDocument *doc) +{ + g_assert (g_slist_find (_instance->_documents, doc)); + _instance->_documents = g_slist_remove (_instance->_documents, doc); +} + +SPDesktop* +Editor::createDesktop (SPDocument* doc) +{ + g_assert (doc != 0); + (new Inkscape::UI::View::EditWidget (doc))->present(); + sp_document_unref (doc); + SPDesktop *dt = getActiveDesktop(); + reactivateDesktop (dt); + return dt; +} + +/// Returns the currently active desktop +SPDesktop* +Editor::getActiveDesktop() +{ + if (_instance->_desktops == NULL) { + return NULL; + } + + return (SPDesktop *) _instance->_desktops->data; +} + +/// Add desktop to list of desktops +void +Editor::addDesktop (SPDesktop *dt) +{ + g_return_if_fail (dt != 0); + g_assert (!g_slist_find (_instance->_desktops, dt)); + + _instance->_desktops = g_slist_append (_instance->_desktops, dt); + + if (isDesktopActive (dt)) { + _instance->_desktop_activated_signal.emit (dt); + _instance->_event_context_set_signal.emit (SP_DT_EVENTCONTEXT (dt)); + _instance->_selection_set_signal.emit (SP_DT_SELECTION (dt)); + _instance->_selection_changed_signal.emit (SP_DT_SELECTION (dt)); + } +} + +/// Remove desktop from list of desktops +void +Editor::removeDesktop (SPDesktop *dt) +{ + g_return_if_fail (dt != 0); + g_assert (g_slist_find (_instance->_desktops, dt)); + + if (dt == _instance->_desktops->data) { // is it the active desktop? + _instance->_desktop_deactivated_signal.emit (dt); + if (_instance->_desktops->next != 0) { + SPDesktop * new_desktop = (SPDesktop *) _instance->_desktops->next->data; + _instance->_desktops = g_slist_remove (_instance->_desktops, new_desktop); + _instance->_desktops = g_slist_prepend (_instance->_desktops, new_desktop); + _instance->_desktop_activated_signal.emit (new_desktop); + _instance->_event_context_set_signal.emit (SP_DT_EVENTCONTEXT (new_desktop)); + _instance->_selection_set_signal.emit (SP_DT_SELECTION (new_desktop)); + _instance->_selection_changed_signal.emit (SP_DT_SELECTION (new_desktop)); + } else { + _instance->_event_context_set_signal.emit (0); + if (SP_DT_SELECTION(dt)) + SP_DT_SELECTION(dt)->clear(); + } + } + + _instance->_desktops = g_slist_remove (_instance->_desktops, dt); + + // if this was the last desktop, shut down the program + if (_instance->_desktops == NULL) { + _instance->_shutdown_signal.emit(); + Inkscape::NSApplication::Application::exit(); + } +} + +void +Editor::activateDesktop (SPDesktop* dt) +{ + g_assert (dt != 0); + if (isDesktopActive (dt)) + return; + + g_assert (g_slist_find (_instance->_desktops, dt)); + SPDesktop *curr = (SPDesktop*)_instance->_desktops->data; + _instance->_desktop_deactivated_signal.emit (curr); + + _instance->_desktops = g_slist_remove (_instance->_desktops, dt); + _instance->_desktops = g_slist_prepend (_instance->_desktops, dt); + + _instance->_desktop_activated_signal.emit (dt); + _instance->_event_context_set_signal.emit (SP_DT_EVENTCONTEXT(dt)); + _instance->_selection_set_signal.emit (SP_DT_SELECTION(dt)); + _instance->_selection_changed_signal.emit (SP_DT_SELECTION(dt)); +} + +void +Editor::reactivateDesktop (SPDesktop* dt) +{ + g_assert (dt != 0); + if (isDesktopActive(dt)) + _instance->_desktop_activated_signal.emit (dt); +} + +bool +Editor::isDuplicatedView (SPDesktop* dt) +{ + SPDocument const* document = dt->doc(); + if (!document) { + return false; + } + for ( GSList *iter = _instance->_desktops ; iter ; iter = iter->next ) { + SPDesktop *other_desktop=(SPDesktop *)iter->data; + SPDocument *other_document=other_desktop->doc(); + if ( other_document == document && other_desktop != dt ) { + return true; + } + } + return false; +} + + /// Returns the event context +//SPEventContext* +//Editor::getEventContext() +//{ +// if (getActiveDesktop()) { +// return SP_DT_EVENTCONTEXT (getActiveDesktop()); +// } +// +// return NULL; +//} + + +void +Editor::selectionModified (Inkscape::Selection* sel, guint flags) +{ + g_return_if_fail (sel != NULL); + if (isDesktopActive (sel->desktop())) + _instance->_selection_modified_signal.emit (sel, flags); +} + +void +Editor::selectionChanged (Inkscape::Selection* sel) +{ + g_return_if_fail (sel != NULL); + if (isDesktopActive (sel->desktop())) + _instance->_selection_changed_signal.emit (sel); +} + +void +Editor::subSelectionChanged (SPDesktop* dt) +{ + g_return_if_fail (dt != NULL); + if (isDesktopActive (dt)) + _instance->_subselection_changed_signal.emit (dt); +} + +void +Editor::selectionSet (Inkscape::Selection* sel) +{ + g_return_if_fail (sel != NULL); + if (isDesktopActive (sel->desktop())) { + _instance->_selection_set_signal.emit (sel); + _instance->_selection_changed_signal.emit (sel); + } +} + +void +Editor::eventContextSet (SPEventContext* ec) +{ + g_return_if_fail (ec != NULL); + g_return_if_fail (SP_IS_EVENT_CONTEXT (ec)); + if (isDesktopActive (ec->desktop)) + _instance->_event_context_set_signal.emit (ec); +} + +void +Editor::hideDialogs() +{ + _instance->_dialogs_hidden_signal.emit(); + _instance->_dialogs_toggle = false; +} + +void +Editor::unhideDialogs() +{ + _instance->_dialogs_unhidden_signal.emit(); + _instance->_dialogs_toggle = true; +} + +void +Editor::toggleDialogs() +{ + if (_dialogs_toggle) { + hideDialogs(); + } else { + unhideDialogs(); + } +} + +void +Editor::refreshDisplay() +{ + // TODO +} + +void +Editor::exit() +{ + //emit shutdown signal so that dialogs could remember layout + _shutdown_signal.emit(); + Inkscape::Preferences::save(); +} + +//================================================================== + +sigc::connection +Editor::connectSelectionModified +(const sigc::slot &slot) +{ + return _instance->_selection_modified_signal.connect (slot); +} + +sigc::connection +Editor::connectSelectionChanged +(const sigc::slot &slot) +{ + return _instance->_selection_changed_signal.connect (slot); +} + +sigc::connection +Editor::connectSubselectionChanged (const sigc::slot &slot) +{ + return _instance->_subselection_changed_signal.connect (slot); +} + +sigc::connection +Editor::connectSelectionSet (const sigc::slot &slot) +{ + return _instance->_selection_set_signal.connect (slot); +} + +sigc::connection +Editor::connectEventContextSet (const sigc::slot &slot) +{ + return _instance->_event_context_set_signal.connect (slot); +} + +sigc::connection +Editor::connectDesktopActivated (const sigc::slot &slot) +{ + return _instance->_desktop_activated_signal.connect (slot); +} + +sigc::connection +Editor::connectDesktopDeactivated (const sigc::slot &slot) +{ + return _instance->_desktop_deactivated_signal.connect (slot); +} + +sigc::connection +Editor::connectShutdown (const sigc::slot &slot) +{ + return _instance->_shutdown_signal.connect (slot); +} + +sigc::connection +Editor::connectDialogsHidden (const sigc::slot &slot) +{ + return _instance->_dialogs_hidden_signal.connect (slot); +} + +sigc::connection +Editor::connectDialogsUnhidden (const sigc::slot &slot) +{ + return _instance->_dialogs_unhidden_signal.connect (slot); +} + +sigc::connection +Editor::connectExternalChange (const sigc::slot &slot) +{ + return _instance->_external_change_signal.connect (slot); +} + + +} // namespace NSApplication +} // 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:textwidth=99 : diff --git a/src/application/editor.h b/src/application/editor.h new file mode 100644 index 000000000..9d2ce493c --- /dev/null +++ b/src/application/editor.h @@ -0,0 +1,139 @@ +/** \file + * \brief Class to manage an application used for editing SVG documents + * using GUI views + * + * \note This class is a Singleton + * + * Authors: + * Bryce W. Harrington + * Ralf Stephan + * + * Copyright (C) 2004 Bryce Harrington + * + * Released under GNU GPL. Read the file 'COPYING' for more information. + */ + +#ifndef INKSCAPE_APPLICATION_EDITOR_H +#define INKSCAPE_APPLICATION_EDITOR_H + +#include +#include +#include +#include "app-prototype.h" + +class SPDesktop; +class SPDocument; +class SPEventContext; + +namespace Inkscape { + class Selection; + namespace XML { + class Document; + } + namespace UI { + namespace View { + class Edit; + } + } + namespace NSApplication { + +class Editor : public AppPrototype +{ +public: + static Editor *create (int argc, char **argv); + virtual ~Editor(); + + void* getWindow(); + + void toggleDialogs(); + void nextDesktop(); + void prevDesktop(); + + void refreshDisplay(); + void exit(); + + bool lastViewOfDocument(SPDocument* doc, SPDesktop* view) const; + + bool addView(SPDesktop* view); + bool deleteView(SPDesktop* view); + + static Inkscape::XML::Document *getPreferences(); + static SPDesktop* getActiveDesktop(); + static bool isDesktopActive (SPDesktop* dt) { return getActiveDesktop()==dt; } + static SPDesktop* createDesktop (SPDocument* doc); + static void addDesktop (SPDesktop* dt); + static void removeDesktop (SPDesktop* dt); + static void activateDesktop (SPDesktop* dt); + static void reactivateDesktop (SPDesktop* dt); + static bool isDuplicatedView (SPDesktop* dt); + + static SPDocument* getActiveDocument(); + static void addDocument (SPDocument* doc); + static void removeDocument (SPDocument* doc); + + static void selectionModified (Inkscape::Selection*, guint); + static void selectionChanged (Inkscape::Selection*); + static void subSelectionChanged (SPDesktop*); + static void selectionSet (Inkscape::Selection*); + static void eventContextSet (SPEventContext*); + static void hideDialogs(); + static void unhideDialogs(); + + static sigc::connection connectSelectionModified (const sigc::slot &slot); + static sigc::connection connectSelectionChanged (const sigc::slot &slot); + static sigc::connection connectSubselectionChanged (const sigc::slot &slot); + static sigc::connection connectSelectionSet (const sigc::slot &slot); + static sigc::connection connectEventContextSet (const sigc::slot &slot); + static sigc::connection connectDesktopActivated (const sigc::slot &slot); + static sigc::connection connectDesktopDeactivated (const sigc::slot &slot); + static sigc::connection connectShutdown (const sigc::slot &slot); + static sigc::connection connectDialogsHidden (const sigc::slot &slot); + static sigc::connection connectDialogsUnhidden (const sigc::slot &slot); + static sigc::connection connectExternalChange (const sigc::slot &slot); + + +protected: + Editor(Editor const &); + Editor& operator=(Editor const &); + + GSList *_documents; + GSList *_desktops; + gchar *_argv0; + + bool _dialogs_toggle; + + sigc::signal _selection_modified_signal; + sigc::signal _selection_changed_signal; + sigc::signal _subselection_changed_signal; + sigc::signal _selection_set_signal; + sigc::signal _event_context_set_signal; + sigc::signal _desktop_activated_signal; + sigc::signal _desktop_deactivated_signal; + sigc::signal _shutdown_signal; + sigc::signal _dialogs_hidden_signal; + sigc::signal _dialogs_unhidden_signal; + sigc::signal _external_change_signal; + +private: + Editor(int argc, char **argv); + bool init(); +}; + +#define ACTIVE_DESKTOP Inkscape::NSApplication::Editor::getActiveDesktop() + +} // namespace NSApplication +} // namespace Inkscape + + +#endif /* !INKSCAPE_APPLICATION_EDITOR_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:encoding=utf-8:textwidth=99 : diff --git a/src/application/makefile.in b/src/application/makefile.in new file mode 100644 index 000000000..d35d0b1f3 --- /dev/null +++ b/src/application/makefile.in @@ -0,0 +1,17 @@ +# Convenience stub makefile to call the real Makefile. + +@SET_MAKE@ + +# Explicit so that it's the default rule. +all: + cd .. && $(MAKE) application/all + +clean %.a %.o: + cd .. && $(MAKE) application/$@ + +.PHONY: all clean + +OBJEXT = @OBJEXT@ + +.SUFFIXES: +.SUFFIXES: .a .$(OBJEXT) diff --git a/src/approx-equal.h b/src/approx-equal.h new file mode 100644 index 000000000..3f5ebf109 --- /dev/null +++ b/src/approx-equal.h @@ -0,0 +1,25 @@ +#ifndef __APROX_EQUAL_H__ +#define __APROX_EQUAL_H__ + +#include + +inline bool approx_equal(double const a, double const b) +{ + return ( (a == b) + || ( fabs( a - b ) < 1e-2 ) + || ( fabs( a / b - 1.0 ) < 1e-2 ) ); +} + + +#endif /* !__APROX_EQUAL_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:encoding=utf-8:textwidth=99 : diff --git a/src/arc-context.cpp b/src/arc-context.cpp new file mode 100644 index 000000000..48e153638 --- /dev/null +++ b/src/arc-context.cpp @@ -0,0 +1,447 @@ +#define __SP_ARC_CONTEXT_C__ + +/** \file Ellipse drawing context. */ + +/* + * Authors: + * Mitsuru Oka + * Lauris Kaplinski + * bulia byak + * + * Copyright (C) 2000-2002 Lauris Kaplinski + * Copyright (C) 2000-2001 Ximian, Inc. + * Copyright (C) 2002 Mitsuru Oka + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifdef HAVE_CONFIG_H +# include +#endif +#include + +#include "macros.h" +#include +#include "display/sp-canvas.h" +#include "sp-ellipse.h" +#include "document.h" +#include "sp-namedview.h" +#include "selection.h" +#include "desktop-handles.h" +#include "snap.h" +#include "pixmaps/cursor-ellipse.xpm" +#include "sp-metrics.h" +#include "xml/repr.h" +#include "xml/node-event-vector.h" +#include "object-edit.h" +#include "prefs-utils.h" +#include "message-context.h" +#include "desktop.h" +#include "desktop-style.h" +#include "context-fns.h" + +#include "arc-context.h" + +static void sp_arc_context_class_init(SPArcContextClass *klass); +static void sp_arc_context_init(SPArcContext *arc_context); +static void sp_arc_context_dispose(GObject *object); + +static void sp_arc_context_setup(SPEventContext *ec); +static gint sp_arc_context_root_handler(SPEventContext *event_context, GdkEvent *event); +static gint sp_arc_context_item_handler(SPEventContext *event_context, SPItem *item, GdkEvent *event); + +static void sp_arc_drag(SPArcContext *ec, NR::Point pt, guint state); +static void sp_arc_finish(SPArcContext *ec); + +static SPEventContextClass *parent_class; + +GtkType sp_arc_context_get_type() +{ + static GType type = 0; + if (!type) { + GTypeInfo info = { + sizeof(SPArcContextClass), + NULL, NULL, + (GClassInitFunc) sp_arc_context_class_init, + NULL, NULL, + sizeof(SPArcContext), + 4, + (GInstanceInitFunc) sp_arc_context_init, + NULL, /* value_table */ + }; + type = g_type_register_static(SP_TYPE_EVENT_CONTEXT, "SPArcContext", &info, (GTypeFlags) 0); + } + return type; +} + +static void sp_arc_context_class_init(SPArcContextClass *klass) +{ + + GObjectClass *object_class = (GObjectClass *) klass; + SPEventContextClass *event_context_class = (SPEventContextClass *) klass; + + parent_class = (SPEventContextClass*) g_type_class_peek_parent(klass); + + object_class->dispose = sp_arc_context_dispose; + + event_context_class->setup = sp_arc_context_setup; + event_context_class->root_handler = sp_arc_context_root_handler; + event_context_class->item_handler = sp_arc_context_item_handler; +} + +static void sp_arc_context_init(SPArcContext *arc_context) +{ + SPEventContext *event_context = SP_EVENT_CONTEXT(arc_context); + + event_context->cursor_shape = cursor_ellipse_xpm; + event_context->hot_x = 4; + event_context->hot_y = 4; + event_context->xp = 0; + event_context->yp = 0; + event_context->tolerance = 0; + event_context->within_tolerance = false; + event_context->item_to_select = NULL; + + event_context->shape_repr = NULL; + event_context->shape_knot_holder = NULL; + + arc_context->item = NULL; + + new (&arc_context->sel_changed_connection) sigc::connection(); +} + +static void sp_arc_context_dispose(GObject *object) +{ + SPEventContext *ec = SP_EVENT_CONTEXT(object); + SPArcContext *ac = SP_ARC_CONTEXT(object); + + ec->enableGrDrag(false); + + ac->sel_changed_connection.disconnect(); + ac->sel_changed_connection.~connection(); + + if (ec->shape_knot_holder) { + sp_knot_holder_destroy(ec->shape_knot_holder); + ec->shape_knot_holder = NULL; + } + + if (ec->shape_repr) { // remove old listener + sp_repr_remove_listener_by_data(ec->shape_repr, ec); + Inkscape::GC::release(ec->shape_repr); + ec->shape_repr = 0; + } + + /* fixme: This is necessary because we do not grab */ + if (ac->item) { + sp_arc_finish(ac); + } + + delete ac->_message_context; + + G_OBJECT_CLASS(parent_class)->dispose(object); +} + +static Inkscape::XML::NodeEventVector ec_shape_repr_events = { + NULL, /* child_added */ + NULL, /* child_removed */ + ec_shape_event_attr_changed, + NULL, /* content_changed */ + NULL /* order_changed */ +}; + +/** +\brief Callback that processes the "changed" signal on the selection; +destroys old and creates new knotholder. +*/ +void sp_arc_context_selection_changed(Inkscape::Selection * selection, gpointer data) +{ + SPArcContext *ac = SP_ARC_CONTEXT(data); + SPEventContext *ec = SP_EVENT_CONTEXT(ac); + + if (ec->shape_knot_holder) { // desktroy knotholder + sp_knot_holder_destroy(ec->shape_knot_holder); + ec->shape_knot_holder = NULL; + } + + if (ec->shape_repr) { // remove old listener + sp_repr_remove_listener_by_data(ec->shape_repr, ec); + Inkscape::GC::release(ec->shape_repr); + ec->shape_repr = 0; + } + + SPItem *item = selection ? selection->singleItem() : NULL; + if (item) { + ec->shape_knot_holder = sp_item_knot_holder(item, ec->desktop); + Inkscape::XML::Node *shape_repr = SP_OBJECT_REPR(item); + if (shape_repr) { + ec->shape_repr = shape_repr; + Inkscape::GC::anchor(shape_repr); + sp_repr_add_listener(shape_repr, &ec_shape_repr_events, ec); + sp_repr_synthesize_events(shape_repr, &ec_shape_repr_events, ec); + } + } +} + +static void sp_arc_context_setup(SPEventContext *ec) +{ + SPArcContext *ac = SP_ARC_CONTEXT(ec); + Inkscape::Selection *selection = SP_DT_SELECTION(ec->desktop); + + if (((SPEventContextClass *) parent_class)->setup) { + ((SPEventContextClass *) parent_class)->setup(ec); + } + + SPItem *item = selection->singleItem(); + + if (item) { + ec->shape_knot_holder = sp_item_knot_holder(item, ec->desktop); + Inkscape::XML::Node *shape_repr = SP_OBJECT_REPR(item); + if (shape_repr) { + ec->shape_repr = shape_repr; + Inkscape::GC::anchor(shape_repr); + sp_repr_add_listener(shape_repr, &ec_shape_repr_events, ec); + sp_repr_synthesize_events(shape_repr, &ec_shape_repr_events, ec); + } + } + + ac->sel_changed_connection.disconnect(); + ac->sel_changed_connection = selection->connectChanged( + sigc::bind(sigc::ptr_fun(&sp_arc_context_selection_changed), (gpointer) ac) + ); + + if (prefs_get_int_attribute("tools.shapes", "selcue", 0) != 0) { + ec->enableSelectionCue(); + } + + if (prefs_get_int_attribute("tools.shapes", "gradientdrag", 0) != 0) { + ec->enableGrDrag(); + } + + ac->_message_context = new Inkscape::MessageContext(ec->desktop->messageStack()); +} + +static gint sp_arc_context_item_handler(SPEventContext *event_context, SPItem *item, GdkEvent *event) +{ + SPDesktop *desktop = event_context->desktop; + gint ret = FALSE; + + switch (event->type) { + case GDK_BUTTON_PRESS: + if (event->button.button == 1) { + Inkscape::setup_for_drag_start(desktop, event_context, event); + ret = TRUE; + } + break; + // motion and release are always on root (why?) + default: + break; + } + + if (((SPEventContextClass *) parent_class)->item_handler) { + ret = ((SPEventContextClass *) parent_class)->item_handler(event_context, item, event); + } + + return ret; +} + +static gint sp_arc_context_root_handler(SPEventContext *event_context, GdkEvent *event) +{ + static bool dragging; + + SPDesktop *desktop = event_context->desktop; + Inkscape::Selection *selection = SP_DT_SELECTION(desktop); + SPArcContext *ac = SP_ARC_CONTEXT(event_context); + + event_context->tolerance = prefs_get_int_attribute_limited("options.dragtolerance", "value", 0, 0, 100); + + gint ret = FALSE; + + switch (event->type) { + case GDK_BUTTON_PRESS: + if (event->button.button == 1) { + + dragging = true; + ac->center = Inkscape::setup_for_drag_start(desktop, event_context, event); + + SnapManager const m(desktop->namedview); + ac->center = m.freeSnap(Inkscape::Snapper::SNAP_POINT, ac->center, ac->item).getPoint(); + sp_canvas_item_grab(SP_CANVAS_ITEM(desktop->acetate), + GDK_KEY_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | + GDK_POINTER_MOTION_MASK | GDK_BUTTON_PRESS_MASK, + NULL, event->button.time); + ret = TRUE; + } + break; + case GDK_MOTION_NOTIFY: + if (dragging && event->motion.state && GDK_BUTTON1_MASK) { + + if ( event_context->within_tolerance + && ( abs( (gint) event->motion.x - event_context->xp ) < event_context->tolerance ) + && ( abs( (gint) event->motion.y - event_context->yp ) < event_context->tolerance ) ) { + break; // do not drag if we're within tolerance from origin + } + // Once the user has moved farther than tolerance from the original location + // (indicating they intend to draw, not click), then always process the + // motion notify coordinates as given (no snapping back to origin) + event_context->within_tolerance = false; + + NR::Point const motion_w(event->motion.x, event->motion.y); + NR::Point const motion_dt(desktop->w2d(motion_w)); + sp_arc_drag(ac, motion_dt, event->motion.state); + ret = TRUE; + } + break; + case GDK_BUTTON_RELEASE: + event_context->xp = event_context->yp = 0; + if (event->button.button == 1) { + dragging = false; + if (!event_context->within_tolerance) { + // we've been dragging, finish the arc + sp_arc_finish(ac); + } else if (event_context->item_to_select) { + // no dragging, select clicked item if any + if (event->button.state & GDK_SHIFT_MASK) { + selection->toggle(event_context->item_to_select); + } else { + selection->set(event_context->item_to_select); + } + } else { + // click in an empty space + selection->clear(); + } + event_context->xp = 0; + event_context->yp = 0; + event_context->item_to_select = NULL; + ret = TRUE; + } + sp_canvas_item_ungrab(SP_CANVAS_ITEM(desktop->acetate), event->button.time); + break; + case GDK_KEY_PRESS: + switch (get_group0_keyval (&event->key)) { + case GDK_Alt_L: + case GDK_Alt_R: + case GDK_Control_L: + case GDK_Control_R: + case GDK_Shift_L: + case GDK_Shift_R: + case GDK_Meta_L: // Meta is when you press Shift+Alt (at least on my machine) + case GDK_Meta_R: + sp_event_show_modifier_tip(event_context->defaultMessageContext(), event, + _("Ctrl: make circle or integer-ratio ellipse, snap arc/segment angle"), + _("Shift: draw around the starting point"), + NULL); + break; + case GDK_Up: + case GDK_Down: + case GDK_KP_Up: + case GDK_KP_Down: + // prevent the zoom field from activation + if (!MOD__CTRL_ONLY) + ret = TRUE; + break; + case GDK_x: + case GDK_X: + if (MOD__ALT_ONLY) { + desktop->setToolboxFocusTo ("altx-arc"); + ret = TRUE; + } + break; + case GDK_Escape: + SP_DT_SELECTION(desktop)->clear(); + //TODO: make dragging escapable by Esc + default: + break; + } + break; + case GDK_KEY_RELEASE: + switch (event->key.keyval) { + case GDK_Alt_L: + case GDK_Alt_R: + case GDK_Control_L: + case GDK_Control_R: + case GDK_Shift_L: + case GDK_Shift_R: + case GDK_Meta_L: // Meta is when you press Shift+Alt + case GDK_Meta_R: + event_context->defaultMessageContext()->clear(); + break; + default: + break; + } + break; + default: + break; + } + + if (!ret) { + if (((SPEventContextClass *) parent_class)->root_handler) { + ret = ((SPEventContextClass *) parent_class)->root_handler(event_context, event); + } + } + + return ret; +} + +static void sp_arc_drag(SPArcContext *ac, NR::Point pt, guint state) +{ + SPDesktop *desktop = SP_EVENT_CONTEXT(ac)->desktop; + + if (!ac->item) { + + if (Inkscape::have_viable_layer(desktop, ac->_message_context) == false) { + return; + } + + /* Create object */ + Inkscape::XML::Node *repr = sp_repr_new("svg:path"); + repr->setAttribute("sodipodi:type", "arc"); + + /* Set style */ + sp_desktop_apply_style_tool(desktop, repr, "tools.shapes.arc", false); + + ac->item = SP_ITEM(desktop->currentLayer()->appendChildRepr(repr)); + Inkscape::GC::release(repr); + ac->item->transform = SP_ITEM(desktop->currentRoot())->getRelativeTransform(desktop->currentLayer()); + ac->item->updateRepr(); + } + + NR::Rect const r = Inkscape::snap_rectangular_box(desktop, ac->item, pt, ac->center, state); + + sp_arc_position_set(SP_ARC(ac->item), + r.midpoint()[NR::X], r.midpoint()[NR::Y], + r.dimensions()[NR::X] / 2, r.dimensions()[NR::Y] / 2); + + GString *xs = SP_PX_TO_METRIC_STRING(r.dimensions()[NR::X], desktop->namedview->getDefaultMetric()); + GString *ys = SP_PX_TO_METRIC_STRING(r.dimensions()[NR::Y], desktop->namedview->getDefaultMetric()); + ac->_message_context->setF(Inkscape::NORMAL_MESSAGE, _("Ellipse: %s × %s; with Ctrl to make circle or integer-ratio ellipse; with Shift to draw around the starting point"), xs->str, ys->str); + g_string_free(xs, FALSE); + g_string_free(ys, FALSE); +} + +static void sp_arc_finish(SPArcContext *ac) +{ + ac->_message_context->clear(); + + if (ac->item != NULL) { + SPDesktop *desktop = SP_EVENT_CONTEXT(ac)->desktop; + + SP_OBJECT(ac->item)->updateRepr(); + + SP_DT_SELECTION(desktop)->set(ac->item); + sp_document_done(SP_DT_DOCUMENT(desktop)); + + ac->item = NULL; + } +} + + +/* + 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:textwidth=99 : diff --git a/src/arc-context.h b/src/arc-context.h new file mode 100644 index 000000000..2ce008b43 --- /dev/null +++ b/src/arc-context.h @@ -0,0 +1,62 @@ +#ifndef SEEN_ARC_CONTEXT_H +#define SEEN_ARC_CONTEXT_H + +/* + * Ellipse drawing context + * + * Authors: + * Mitsuru Oka + * Lauris Kaplinski + * + * Copyright (C) 2000-2002 Lauris Kaplinski + * Copyright (C) 2000-2001 Ximian, Inc. + * Copyright (C) 2002 Mitsuru Oka + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include + +#include +#include "event-context.h" +struct SPKnotHolder; + +#define SP_TYPE_ARC_CONTEXT (sp_arc_context_get_type()) +#define SP_ARC_CONTEXT(obj) (GTK_CHECK_CAST((obj), SP_TYPE_ARC_CONTEXT, SPArcContext)) +#define SP_ARC_CONTEXT_CLASS(klass) (GTK_CHECK_CLASS_CAST((klass), SP_TYPE_ARC_CONTEXT, SPArcContextClass)) +#define SP_IS_ARC_CONTEXT(obj) (GTK_CHECK_TYPE((obj), SP_TYPE_ARC_CONTEXT)) +#define SP_IS_ARC_CONTEXT_CLASS(klass) (GTK_CHECK_CLASS_TYPE((klass), SP_TYPE_ARC_CONTEXT)) + +class SPArcContext; +class SPArcContextClass; + +struct SPArcContext : public SPEventContext { + SPItem *item; + NR::Point center; + + sigc::connection sel_changed_connection; + + Inkscape::MessageContext *_message_context; +}; + +struct SPArcContextClass { + SPEventContextClass parent_class; +}; + +/* Standard Gtk function */ + +GtkType sp_arc_context_get_type(void); + + +#endif /* !SEEN_ARC_CONTEXT_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 : diff --git a/src/attributes-test.cpp b/src/attributes-test.cpp new file mode 100644 index 000000000..50d2e81bd --- /dev/null +++ b/src/attributes-test.cpp @@ -0,0 +1,473 @@ +#include +#include "utest/utest.h" +#include "attributes.h" +#include "streq.h" + +/* Extracted mechanically from http://www.w3.org/TR/SVG11/attindex.html: + + tidy -wrap 999 -asxml < attindex.html 2>/dev/null | + tr -d \\n | + sed 's,,@,g' | + tr @ \\n | + sed 's,.*,,;s,^,,;1,/^%/d;/^%/d;s,^, {",;s/$/", false},/' | + uniq + + attindex.html lacks attributeName, begin, additive, font, marker; + I've added these manually. +*/ +static struct {char const *attr; bool supported;} const all_attrs[] = { + {"attributeName", true}, + {"begin", true}, + {"additive", true}, + {"font", true}, + {"marker", true}, + {"line-height", true}, + + {"accent-height", false}, + {"accumulate", true}, + {"alignment-baseline", true}, + {"alphabetic", false}, + {"amplitude", false}, + {"animate", false}, + {"arabic-form", false}, + {"ascent", false}, + {"attributeType", true}, + {"azimuth", false}, + {"baseFrequency", false}, + {"baseline-shift", true}, + {"baseProfile", false}, + {"bbox", false}, + {"bias", false}, + {"block-progression", true}, + {"by", true}, + {"calcMode", true}, + {"cap-height", false}, + {"class", false}, + {"clip", true}, + {"clip-path", true}, + {"clip-rule", true}, + {"clipPathUnits", true}, + {"color", true}, + {"color-interpolation", true}, + {"color-interpolation-filters", true}, + {"color-profile", true}, + {"color-rendering", true}, + {"contentScriptType", false}, + {"contentStyleType", false}, + {"cursor", true}, + {"cx", true}, + {"cy", true}, + {"d", true}, + {"descent", false}, + {"diffuseConstant", false}, + {"direction", true}, + {"display", true}, + {"divisor", false}, + {"dominant-baseline", true}, + {"dur", true}, + {"dx", true}, + {"dy", true}, + {"edgeMode", false}, + {"elevation", false}, + {"enable-background", true}, + {"end", true}, + {"exponent", false}, + {"externalResourcesRequired", false}, + {"feColorMatrix", false}, + {"feComposite", false}, + {"feGaussianBlur", false}, + {"feMorphology", false}, + {"feTile", false}, + {"fill", true}, + {"fill-opacity", true}, + {"fill-rule", true}, + {"filter", true}, + {"filterRes", false}, + {"filterUnits", false}, + {"flood-color", true}, + {"flood-opacity", true}, + {"font-family", true}, + {"font-size", true}, + {"font-size-adjust", true}, + {"font-stretch", true}, + {"font-style", true}, + {"font-variant", true}, + {"font-weight", true}, + {"format", false}, + {"from", true}, + {"fx", true}, + {"fy", true}, + {"g1", false}, + {"g2", false}, + {"glyph-name", false}, + {"glyph-orientation-horizontal", true}, + {"glyph-orientation-vertical", true}, + {"glyphRef", false}, + {"gradientTransform", true}, + {"gradientUnits", true}, + {"hanging", false}, + {"height", true}, + {"horiz-adv-x", false}, + {"horiz-origin-x", false}, + {"horiz-origin-y", false}, + {"ideographic", false}, + {"image-rendering", true}, + {"in", false}, + {"in2", false}, + {"intercept", false}, + {"k", false}, + {"k1", false}, + {"k2", false}, + {"k3", false}, + {"k4", false}, + {"kernelMatrix", false}, + {"kernelUnitLength", false}, + {"kerning", true}, + {"keyPoints", false}, + {"keySplines", true}, + {"keyTimes", true}, + {"lang", false}, + {"lengthAdjust", false}, + {"letter-spacing", true}, + {"lighting-color", true}, + {"limitingConeAngle", false}, + {"local", false}, + {"marker-end", true}, + {"marker-mid", true}, + {"marker-start", true}, + {"markerHeight", true}, + {"markerUnits", true}, + {"markerWidth", true}, + {"mask", true}, + {"maskContentUnits", true}, + {"maskUnits", true}, + {"mathematical", false}, + {"max", true}, + {"media", false}, + {"method", false}, + {"min", true}, + {"mode", false}, + {"name", false}, + {"numOctaves", false}, + {"offset", true}, + {"onabort", false}, + {"onactivate", false}, + {"onbegin", false}, + {"onclick", false}, + {"onend", false}, + {"onerror", false}, + {"onfocusin", false}, + {"onfocusout", false}, + {"onload", false}, + {"onmousedown", false}, + {"onmousemove", false}, + {"onmouseout", false}, + {"onmouseover", false}, + {"onmouseup", false}, + {"onrepeat", false}, + {"onresize", false}, + {"onscroll", false}, + {"onunload", false}, + {"onzoom", false}, + {"opacity", true}, + {"operator", false}, + {"order", false}, + {"orient", true}, + {"orientation", true}, + {"origin", false}, + {"overflow", true}, + {"overline-position", false}, + {"overline-thickness", false}, + {"panose-1", false}, + {"path", false}, + {"pathLength", false}, + {"patternContentUnits", true}, + {"patternTransform", true}, + {"patternUnits", true}, + {"pointer-events", true}, + {"points", true}, + {"pointsAtX", false}, + {"pointsAtY", false}, + {"pointsAtZ", false}, + {"preserveAlpha", false}, + {"preserveAspectRatio", true}, + {"primitiveUnits", false}, + {"r", true}, + {"radius", false}, + {"refX", true}, + {"refY", true}, + {"rendering-intent", false}, + {"repeatCount", true}, + {"repeatDur", true}, + {"requiredExtensions", false}, + {"restart", true}, + {"result", false}, + {"rotate", true}, + {"rx", true}, + {"ry", true}, + {"scale", false}, + {"seed", false}, + {"shape-rendering", true}, + {"slope", false}, + {"spacing", false}, + {"specularConstant", false}, + {"specularExponent", false}, + {"spreadMethod", true}, + {"startOffset", true}, + {"stdDeviation", false}, + {"stemh", false}, + {"stemv", false}, + {"stitchTiles", false}, + {"stop-color", true}, + {"stop-opacity", true}, + {"strikethrough-position", false}, + {"strikethrough-thickness", false}, + {"stroke", true}, + {"stroke-dasharray", true}, + {"stroke-dashoffset", true}, + {"stroke-linecap", true}, + {"stroke-linejoin", true}, + {"stroke-miterlimit", true}, + {"stroke-opacity", true}, + {"stroke-width", true}, + {"style", true}, + {"surfaceScale", false}, + {"systemLanguage", false}, + {"tableValues", false}, + {"target", true}, + {"targetX", false}, + {"targetY", false}, + {"text-align", true}, + {"text-anchor", true}, + {"text-decoration", true}, + {"text-indent", true}, + {"text-rendering", true}, + {"text-transform", true}, + {"textLength", false}, + {"title", false}, + {"to", true}, + {"transform", true}, + {"type", true}, + {"u1", false}, + {"u2", false}, + {"underline-position", false}, + {"underline-thickness", false}, + {"unicode", false}, + {"unicode-bidi", true}, + {"unicode-range", false}, + {"units-per-em", false}, + {"v-alphabetic", false}, + {"v-hanging", false}, + {"v-ideographic", false}, + {"v-mathematical", false}, + {"values", true}, + {"version", true}, + {"vert-adv-y", false}, + {"vert-origin-x", false}, + {"vert-origin-y", false}, + {"viewBox", true}, + {"viewTarget", false}, + {"visibility", true}, + {"width", true}, + {"widths", false}, + {"word-spacing", true}, + {"writing-mode", true}, + {"x", true}, + {"x-height", false}, + {"x1", true}, + {"x2", true}, + {"xChannelSelector", false}, + {"xlink:actuate", true}, + {"xlink:arcrole", true}, + {"xlink:href", true}, + {"xlink:role", true}, + {"xlink:show", true}, + {"xlink:title", true}, + {"xlink:type", true}, + {"xml:base", false}, + {"xml:space", true}, + {"xmlns", false}, + {"xmlns:xlink", false}, + {"y", true}, + {"y1", true}, + {"y2", true}, + {"yChannelSelector", false}, + {"z", false}, + {"zoomAndPan", false}, + + /* Extra attributes. */ + {"id", true}, + {"inkscape:collect", true}, + {"inkscape:document-units", true}, + {"inkscape:label", true}, + {"sodipodi:insensitive", true}, + {"sodipodi:nonprintable", true}, + {"inkscape:groupmode", true}, + {"sodipodi:version", true}, + {"inkscape:version", true}, + {"inkscape:pageopacity", true}, + {"inkscape:pageshadow", true}, + {"inkscape:zoom", true}, + {"inkscape:cx", true}, + {"inkscape:cy", true}, + {"inkscape:window-width", true}, + {"inkscape:window-height", true}, + {"inkscape:window-x", true}, + {"inkscape:window-y", true}, + {"inkscape:grid-bbox", true}, + {"inkscape:guide-bbox", true}, + {"inkscape:grid-points", true}, + {"inkscape:guide-points", true}, + {"inkscape:current-layer", true}, + {"inkscape:connector-type", true}, + {"inkscape:connection-start", true}, + {"inkscape:connection-end", true}, + {"inkscape:connector-avoid", true}, + {"sodipodi:cx", true}, + {"sodipodi:cy", true}, + {"sodipodi:rx", true}, + {"sodipodi:ry", true}, + {"sodipodi:start", true}, + {"sodipodi:end", true}, + {"sodipodi:open", true}, + {"sodipodi:sides", true}, + {"sodipodi:r1", true}, + {"sodipodi:r2", true}, + {"sodipodi:arg1", true}, + {"sodipodi:arg2", true}, + {"inkscape:flatsided", true}, + {"inkscape:rounded", true}, + {"inkscape:randomized", true}, + {"sodipodi:expansion", true}, + {"sodipodi:revolution", true}, + {"sodipodi:radius", true}, + {"sodipodi:argument", true}, + {"sodipodi:t0", true}, + {"sodipodi:original", true}, + {"inkscape:original", true}, + {"inkscape:href", true}, + {"inkscape:radius", true}, + {"sodipodi:role", true}, + {"sodipodi:linespacing", true}, + {"inkscape:srcNoMarkup", true}, + {"inkscape:srcPango", true}, + {"inkscape:dstShape", true}, + {"inkscape:dstPath", true}, + {"inkscape:dstBox", true}, + {"inkscape:dstColumn", true}, + {"inkscape:excludeShape", true}, + {"inkscape:layoutOptions", true}, + + /* SPNamedView */ + {"viewonly", true}, + {"showgrid", true}, + {"showguides", true}, + {"gridtolerance", true}, + {"guidetolerance", true}, + {"gridoriginx", true}, + {"gridoriginy", true}, + {"gridspacingx", true}, + {"gridspacingy", true}, + {"gridcolor", true}, + {"gridopacity", true}, + {"gridempcolor", true}, + {"gridempopacity", true}, + {"gridempspacing", true}, + {"guidecolor", true}, + {"guideopacity", true}, + {"guidehicolor", true}, + {"guidehiopacity", true}, + {"showborder", true}, + {"inkscape:showpageshadow", true}, + {"borderlayer", true}, + {"bordercolor", true}, + {"borderopacity", true}, + {"pagecolor", true}, + + /* SPGuide */ + {"position", true} + +}; + +static bool +test_attributes() +{ + utest_start("attributes"); + + std::vector ids; + ids.reserve(256); + UTEST_TEST("attribute lookup") { + for (unsigned i = 0; i < G_N_ELEMENTS(all_attrs); ++i) { + char const *const attr_str = all_attrs[i].attr; + unsigned const id = sp_attribute_lookup(attr_str); + bool const recognized(id); + UTEST_ASSERT(recognized == all_attrs[i].supported); + if (recognized) { + if (ids.size() <= id) { + ids.resize(id + 1); + } + UTEST_ASSERT(!ids[id]); + ids[id] = true; + + unsigned char const *reverse_ustr = sp_attribute_name(id); + char const *reverse_str = reinterpret_cast(reverse_ustr); + UTEST_ASSERT(streq(reverse_str, attr_str)); + } + } + + /* Test for any attributes that this test program doesn't know about. + * + * If any are found, then: + * + * If it is in the `inkscape:' namespace then simply add it to all_attrs with + * `true' as the second field (`supported'). + * + * If it is in the `sodipodi:' namespace then check the spelling against sodipodi + * sources. If you don't have sodipodi sources, then don't add it: leave to someone + * else. + * + * Otherwise, it's probably a bug: ~all SVG 1.1 attributes should already be + * in the all_attrs table. However, the comment above all_attrs does mention + * some things missing from attindex.html, so there may be more. Check the SVG + * spec. Another possibility is that the attribute is new in SVG 1.2. In this case, + * check the spelling against the [draft] SVG 1.2 spec before adding to all_attrs. + * (If you can't be bothered checking the spec, then don't update all_attrs.) + * + * If the attribute isn't in either SVG 1.1 or 1.2 then it's probably a mistake + * for it not to be in the inkscape namespace. (Not sure about attributes used only + * on elements in the inkscape namespace though.) + * + * In any case, make sure that the attribute's source is documented accordingly. + */ + bool found = false; + unsigned const n_ids = ids.size(); + for (unsigned id = 1; id < n_ids; ++id) { + if (!ids[id]) { + unsigned char const *str = sp_attribute_name(id); + printf("%s\n", (const char *)str); /* Apparently printf doesn't like unsigned strings -- Ted */ + found = true; + } + } + UTEST_ASSERT(!found); + } + + return utest_end(); +} + +int main() +{ + return ( test_attributes() + ? EXIT_SUCCESS + : EXIT_FAILURE ); +} + +/* + 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:textwidth=99 : diff --git a/src/attributes.cpp b/src/attributes.cpp new file mode 100644 index 000000000..4d182179c --- /dev/null +++ b/src/attributes.cpp @@ -0,0 +1,348 @@ +#define __SP_ATTRIBUTES_C__ + +/** \file + * Lookup dictionary for attributes/properties. + */ +/* + * Author: + * Lauris Kaplinski + * + * Copyright (C) 2002 Lauris Kaplinski + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include "attributes.h" + +typedef struct { + gint code; + gchar const *name; +} SPStyleProp; + +static SPStyleProp const props[] = { + {SP_ATTR_INVALID, NULL}, + /* SPObject */ + {SP_ATTR_ID, "id"}, + {SP_ATTR_INKSCAPE_COLLECT, "inkscape:collect"}, + {SP_ATTR_INKSCAPE_LABEL, "inkscape:label"}, + /* SPItem */ + {SP_ATTR_TRANSFORM, "transform"}, + {SP_ATTR_SODIPODI_INSENSITIVE, "sodipodi:insensitive"}, + {SP_ATTR_SODIPODI_NONPRINTABLE, "sodipodi:nonprintable"}, + {SP_ATTR_CONNECTOR_AVOID, "inkscape:connector-avoid"}, + {SP_ATTR_STYLE, "style"}, + /* SPAnchor */ + {SP_ATTR_XLINK_HREF, "xlink:href"}, + {SP_ATTR_XLINK_TYPE, "xlink:type"}, + {SP_ATTR_XLINK_ROLE, "xlink:role"}, + {SP_ATTR_XLINK_ARCROLE, "xlink:arcrole"}, + {SP_ATTR_XLINK_TITLE, "xlink:title"}, + {SP_ATTR_XLINK_SHOW, "xlink:show"}, + {SP_ATTR_XLINK_ACTUATE, "xlink:actuate"}, + {SP_ATTR_TARGET, "target"}, + {SP_ATTR_INKSCAPE_GROUPMODE, "inkscape:groupmode"}, + /* SPRoot */ + {SP_ATTR_VERSION, "version"}, + {SP_ATTR_WIDTH, "width"}, + {SP_ATTR_HEIGHT, "height"}, + {SP_ATTR_VIEWBOX, "viewBox"}, + {SP_ATTR_PRESERVEASPECTRATIO, "preserveAspectRatio"}, + {SP_ATTR_SODIPODI_VERSION, "sodipodi:version"}, + {SP_ATTR_INKSCAPE_VERSION, "inkscape:version"}, + /* SPNamedView */ + {SP_ATTR_VIEWONLY, "viewonly"}, + {SP_ATTR_SHOWGRID, "showgrid"}, + {SP_ATTR_SHOWGUIDES, "showguides"}, + {SP_ATTR_GRIDTOLERANCE, "gridtolerance"}, + {SP_ATTR_GUIDETOLERANCE, "guidetolerance"}, + {SP_ATTR_OBJECTTOLERANCE, "objecttolerance"}, + {SP_ATTR_ABS_TOLERANCE, "has_abs_tolerance"}, + {SP_ATTR_GRIDORIGINX, "gridoriginx"}, + {SP_ATTR_GRIDORIGINY, "gridoriginy"}, + {SP_ATTR_GRIDSPACINGX, "gridspacingx"}, + {SP_ATTR_GRIDSPACINGY, "gridspacingy"}, + {SP_ATTR_GRIDCOLOR, "gridcolor"}, + {SP_ATTR_GRIDOPACITY, "gridopacity"}, + {SP_ATTR_GRIDEMPCOLOR, "gridempcolor"}, + {SP_ATTR_GRIDEMPOPACITY, "gridempopacity"}, + {SP_ATTR_GRIDEMPSPACING, "gridempspacing"}, + {SP_ATTR_GUIDECOLOR, "guidecolor"}, + {SP_ATTR_GUIDEOPACITY, "guideopacity"}, + {SP_ATTR_GUIDEHICOLOR, "guidehicolor"}, + {SP_ATTR_GUIDEHIOPACITY, "guidehiopacity"}, + {SP_ATTR_SHOWBORDER, "showborder"}, + {SP_ATTR_SHOWPAGESHADOW, "inkscape:showpageshadow"}, + {SP_ATTR_BORDERLAYER, "borderlayer"}, + {SP_ATTR_BORDERCOLOR, "bordercolor"}, + {SP_ATTR_BORDEROPACITY, "borderopacity"}, + {SP_ATTR_PAGECOLOR, "pagecolor"}, + {SP_ATTR_INKSCAPE_PAGEOPACITY, "inkscape:pageopacity"}, + {SP_ATTR_INKSCAPE_PAGESHADOW, "inkscape:pageshadow"}, + {SP_ATTR_INKSCAPE_ZOOM, "inkscape:zoom"}, + {SP_ATTR_INKSCAPE_CX, "inkscape:cx"}, + {SP_ATTR_INKSCAPE_CY, "inkscape:cy"}, + {SP_ATTR_INKSCAPE_WINDOW_WIDTH, "inkscape:window-width"}, + {SP_ATTR_INKSCAPE_WINDOW_HEIGHT, "inkscape:window-height"}, + {SP_ATTR_INKSCAPE_WINDOW_X, "inkscape:window-x"}, + {SP_ATTR_INKSCAPE_WINDOW_Y, "inkscape:window-y"}, + {SP_ATTR_INKSCAPE_GRID_BBOX, "inkscape:grid-bbox"}, + {SP_ATTR_INKSCAPE_GUIDE_BBOX, "inkscape:guide-bbox"}, + {SP_ATTR_INKSCAPE_OBJECT_BBOX, "inkscape:object-bbox"}, + {SP_ATTR_INKSCAPE_GRID_POINTS, "inkscape:grid-points"}, + {SP_ATTR_INKSCAPE_GUIDE_POINTS, "inkscape:guide-points"}, + {SP_ATTR_INKSCAPE_OBJECT_POINTS, "inkscape:object-points"}, + {SP_ATTR_INKSCAPE_OBJECT_PATHS, "inkscape:object-paths"}, + {SP_ATTR_INKSCAPE_OBJECT_NODES, "inkscape:object-nodes"}, + {SP_ATTR_INKSCAPE_CURRENT_LAYER, "inkscape:current-layer"}, + {SP_ATTR_INKSCAPE_DOCUMENT_UNITS, "inkscape:document-units"}, + /* SPGuide */ + {SP_ATTR_ORIENTATION, "orientation"}, + {SP_ATTR_POSITION, "position"}, + /* SPImage */ + {SP_ATTR_X, "x"}, + {SP_ATTR_Y, "y"}, + /* SPPath */ + {SP_ATTR_D, "d"}, + /* (Note: XML representation of connectors may change in future.) */ + {SP_ATTR_CONNECTOR_TYPE, "inkscape:connector-type"}, + {SP_ATTR_CONNECTION_START, "inkscape:connection-start"}, + {SP_ATTR_CONNECTION_END, "inkscape:connection-end"}, + /* SPRect */ + {SP_ATTR_RX, "rx"}, + {SP_ATTR_RY, "ry"}, + /* SPEllipse */ + {SP_ATTR_R, "r"}, + {SP_ATTR_CX, "cx"}, + {SP_ATTR_CY, "cy"}, + {SP_ATTR_SODIPODI_CX, "sodipodi:cx"}, + {SP_ATTR_SODIPODI_CY, "sodipodi:cy"}, + {SP_ATTR_SODIPODI_RX, "sodipodi:rx"}, + {SP_ATTR_SODIPODI_RY, "sodipodi:ry"}, + {SP_ATTR_SODIPODI_START, "sodipodi:start"}, + {SP_ATTR_SODIPODI_END, "sodipodi:end"}, + {SP_ATTR_SODIPODI_OPEN, "sodipodi:open"}, + /* SPStar */ + {SP_ATTR_SODIPODI_SIDES, "sodipodi:sides"}, + {SP_ATTR_SODIPODI_R1, "sodipodi:r1"}, + {SP_ATTR_SODIPODI_R2, "sodipodi:r2"}, + {SP_ATTR_SODIPODI_ARG1, "sodipodi:arg1"}, + {SP_ATTR_SODIPODI_ARG2, "sodipodi:arg2"}, + {SP_ATTR_INKSCAPE_FLATSIDED, "inkscape:flatsided"}, + {SP_ATTR_INKSCAPE_ROUNDED, "inkscape:rounded"}, + {SP_ATTR_INKSCAPE_RANDOMIZED, "inkscape:randomized"}, + /* SPSpiral */ + {SP_ATTR_SODIPODI_EXPANSION, "sodipodi:expansion"}, + {SP_ATTR_SODIPODI_REVOLUTION, "sodipodi:revolution"}, + {SP_ATTR_SODIPODI_RADIUS, "sodipodi:radius"}, + {SP_ATTR_SODIPODI_ARGUMENT, "sodipodi:argument"}, + {SP_ATTR_SODIPODI_T0, "sodipodi:t0"}, + /* SPOffset */ + {SP_ATTR_SODIPODI_ORIGINAL, "sodipodi:original"}, + {SP_ATTR_INKSCAPE_ORIGINAL, "inkscape:original"}, + {SP_ATTR_INKSCAPE_HREF, "inkscape:href"}, + {SP_ATTR_INKSCAPE_RADIUS, "inkscape:radius"}, + /* SPLine */ + {SP_ATTR_X1, "x1"}, + {SP_ATTR_Y1, "y1"}, + {SP_ATTR_X2, "x2"}, + {SP_ATTR_Y2, "y2"}, + /* SPPolyline */ + {SP_ATTR_POINTS, "points"}, + /* SPTSpan */ + {SP_ATTR_DX, "dx"}, + {SP_ATTR_DY, "dy"}, + {SP_ATTR_ROTATE, "rotate"}, + {SP_ATTR_SODIPODI_ROLE, "sodipodi:role"}, + /* SPText */ + {SP_ATTR_SODIPODI_LINESPACING, "sodipodi:linespacing"}, + /* SPTextPath */ + {SP_ATTR_STARTOFFSET, "startOffset"}, + /* SPStop */ + {SP_ATTR_OFFSET, "offset"}, + /* SPGradient */ + {SP_ATTR_GRADIENTUNITS, "gradientUnits"}, + {SP_ATTR_GRADIENTTRANSFORM, "gradientTransform"}, + {SP_ATTR_SPREADMETHOD, "spreadMethod"}, + /* SPRadialGradient */ + {SP_ATTR_FX, "fx"}, + {SP_ATTR_FY, "fy"}, + /* SPPattern */ + {SP_ATTR_PATTERNUNITS, "patternUnits"}, + {SP_ATTR_PATTERNCONTENTUNITS, "patternContentUnits"}, + {SP_ATTR_PATTERNTRANSFORM, "patternTransform"}, + /* SPClipPath */ + {SP_ATTR_CLIPPATHUNITS, "clipPathUnits"}, + /* SPMask */ + {SP_ATTR_MASKUNITS, "maskUnits"}, + {SP_ATTR_MASKCONTENTUNITS, "maskContentUnits"}, + /* SPMarker */ + {SP_ATTR_MARKERUNITS, "markerUnits"}, + {SP_ATTR_REFX, "refX"}, + {SP_ATTR_REFY, "refY"}, + {SP_ATTR_MARKERWIDTH, "markerWidth"}, + {SP_ATTR_MARKERHEIGHT, "markerHeight"}, + {SP_ATTR_ORIENT, "orient"}, + /* SPStyleElem */ + {SP_ATTR_TYPE, "type"}, + /* Animations */ + {SP_ATTR_ATTRIBUTENAME, "attributeName"}, + {SP_ATTR_ATTRIBUTETYPE, "attributeType"}, + {SP_ATTR_BEGIN, "begin"}, + {SP_ATTR_DUR, "dur"}, + {SP_ATTR_END, "end"}, + {SP_ATTR_MIN, "min"}, + {SP_ATTR_MAX, "max"}, + {SP_ATTR_RESTART, "restart"}, + {SP_ATTR_REPEATCOUNT, "repeatCount"}, + {SP_ATTR_REPEATDUR, "repeatDur"}, + /* Interpolating animations */ + {SP_ATTR_CALCMODE, "calcMode"}, + {SP_ATTR_VALUES, "values"}, + {SP_ATTR_KEYTIMES, "keyTimes"}, + {SP_ATTR_KEYSPLINES, "keySplines"}, + {SP_ATTR_FROM, "from"}, + {SP_ATTR_TO, "to"}, + {SP_ATTR_BY, "by"}, + {SP_ATTR_ADDITIVE, "additive"}, + {SP_ATTR_ACCUMULATE, "accumulate"}, + + /* XML */ + {SP_ATTR_XML_SPACE, "xml:space"}, + + /* typeset */ + {SP_ATTR_TEXT_NOMARKUP, "inkscape:srcNoMarkup"}, + {SP_ATTR_TEXT_PANGOMARKUP, "inkscape:srcPango" }, + {SP_ATTR_TEXT_INSHAPE, "inkscape:dstShape"}, + {SP_ATTR_TEXT_ONPATH, "inkscape:dstPath"}, + {SP_ATTR_TEXT_INBOX,"inkscape:dstBox"}, + {SP_ATTR_TEXT_INCOLUMN,"inkscape:dstColumn"}, + {SP_ATTR_TEXT_EXCLUDE,"inkscape:excludeShape"}, + {SP_ATTR_LAYOUT_OPTIONS,"inkscape:layoutOptions"}, + + /* CSS2 */ + /* Font */ + {SP_PROP_FONT, "font"}, + {SP_PROP_FONT_FAMILY, "font-family"}, + {SP_PROP_FONT_SIZE, "font-size"}, + {SP_PROP_FONT_SIZE_ADJUST, "font-size-adjust"}, + {SP_PROP_FONT_STRETCH, "font-stretch"}, + {SP_PROP_FONT_STYLE, "font-style"}, + {SP_PROP_FONT_VARIANT, "font-variant"}, + {SP_PROP_FONT_WEIGHT, "font-weight"}, + /* Text */ + {SP_PROP_TEXT_INDENT, "text-indent"}, + {SP_PROP_TEXT_ALIGN, "text-align"}, + {SP_PROP_TEXT_DECORATION, "text-decoration"}, + {SP_PROP_LINE_HEIGHT, "line-height"}, + {SP_PROP_LETTER_SPACING, "letter-spacing"}, + {SP_PROP_WORD_SPACING, "word-spacing"}, + {SP_PROP_TEXT_TRANSFORM, "text-transform"}, + /* Text (css3) */ + {SP_PROP_DIRECTION, "direction"}, + {SP_PROP_BLOCK_PROGRESSION, "block-progression"}, + {SP_PROP_WRITING_MODE, "writing-mode"}, + {SP_PROP_UNICODE_BIDI, "unicode-bidi"}, + {SP_PROP_ALIGNMENT_BASELINE, "alignment-baseline"}, + {SP_PROP_BASELINE_SHIFT, "baseline-shift"}, + {SP_PROP_DOMINANT_BASELINE, "dominant-baseline"}, + {SP_PROP_GLYPH_ORIENTATION_HORIZONTAL, "glyph-orientation-horizontal"}, + {SP_PROP_GLYPH_ORIENTATION_VERTICAL, "glyph-orientation-vertical"}, + {SP_PROP_KERNING, "kerning"}, + {SP_PROP_TEXT_ANCHOR, "text-anchor"}, + /* Misc */ + {SP_PROP_CLIP, "clip"}, + {SP_PROP_COLOR, "color"}, + {SP_PROP_CURSOR, "cursor"}, + {SP_PROP_DISPLAY, "display"}, + {SP_PROP_OVERFLOW, "overflow"}, + {SP_PROP_VISIBILITY, "visibility"}, + /* SVG */ + /* Clip/Mask */ + {SP_PROP_CLIP_PATH, "clip-path"}, + {SP_PROP_CLIP_RULE, "clip-rule"}, + {SP_PROP_MASK, "mask"}, + {SP_PROP_OPACITY, "opacity"}, + /* Filter */ + {SP_PROP_ENABLE_BACKGROUND, "enable-background"}, + {SP_PROP_FILTER, "filter"}, + {SP_PROP_FLOOD_COLOR, "flood-color"}, + {SP_PROP_FLOOD_OPACITY, "flood-opacity"}, + {SP_PROP_LIGHTING_COLOR, "lighting-color"}, + /* Gradient */ + {SP_PROP_STOP_COLOR, "stop-color"}, + {SP_PROP_STOP_OPACITY, "stop-opacity"}, + /* Interactivity */ + {SP_PROP_POINTER_EVENTS, "pointer-events"}, + /* Paint */ + {SP_PROP_COLOR_INTERPOLATION, "color-interpolation"}, + {SP_PROP_COLOR_INTERPOLATION_FILTERS, "color-interpolation-filters"}, + {SP_PROP_COLOR_PROFILE, "color-profile"}, + {SP_PROP_COLOR_RENDERING, "color-rendering"}, + {SP_PROP_FILL, "fill"}, + {SP_PROP_FILL_OPACITY, "fill-opacity"}, + {SP_PROP_FILL_RULE, "fill-rule"}, + {SP_PROP_IMAGE_RENDERING, "image-rendering"}, + {SP_PROP_MARKER, "marker"}, + {SP_PROP_MARKER_END, "marker-end"}, + {SP_PROP_MARKER_MID, "marker-mid"}, + {SP_PROP_MARKER_START, "marker-start"}, + {SP_PROP_SHAPE_RENDERING, "shape-rendering"}, + {SP_PROP_STROKE, "stroke"}, + {SP_PROP_STROKE_DASHARRAY, "stroke-dasharray"}, + {SP_PROP_STROKE_DASHOFFSET, "stroke-dashoffset"}, + {SP_PROP_STROKE_LINECAP, "stroke-linecap"}, + {SP_PROP_STROKE_LINEJOIN, "stroke-linejoin"}, + {SP_PROP_STROKE_MITERLIMIT, "stroke-miterlimit"}, + {SP_PROP_STROKE_OPACITY, "stroke-opacity"}, + {SP_PROP_STROKE_WIDTH, "stroke-width"}, + {SP_PROP_TEXT_RENDERING, "text-rendering"}, +}; + +#define n_attrs (sizeof(props) / sizeof(props[0])) + +/** Returns an SPAttributeEnum; SP_ATTR_INVALID (of value 0) if key isn't recognized. */ +unsigned +sp_attribute_lookup(gchar const *key) +{ + static GHashTable *propdict = NULL; + + if (!propdict) { + unsigned int i; + propdict = g_hash_table_new(g_str_hash, g_str_equal); + for (i = 1; i < n_attrs; i++) { + g_assert(props[i].code == static_cast< gint >(i) ); + g_hash_table_insert(propdict, + const_cast(static_cast(props[i].name)), + GINT_TO_POINTER(props[i].code)); + } + } + + return GPOINTER_TO_UINT(g_hash_table_lookup(propdict, key)); +} + +unsigned char const * +sp_attribute_name(unsigned int id) +{ + if (id >= n_attrs) { + return NULL; + } + + return (unsigned char*)props[id].name; +} + + +/* + 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:textwidth=99 : diff --git a/src/attributes.h b/src/attributes.h new file mode 100644 index 000000000..24b87fc1c --- /dev/null +++ b/src/attributes.h @@ -0,0 +1,318 @@ +#ifndef __SP_ATTRIBUTES_H__ +#define __SP_ATTRIBUTES_H__ + +/** \file + * Lookup dictionary for attributes/properties. + */ +/* + * Author: + * Lauris Kaplinski + * + * Copyright (C) 2002 Lauris Kaplinski + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ +#include +#include + +unsigned int sp_attribute_lookup(gchar const *key); +unsigned char const *sp_attribute_name(unsigned int id); + +/** + * True iff k is a property in SVG, i.e. something that can be written either in a style attribute + * or as its own XML attribute. + */ +#define SP_ATTRIBUTE_IS_CSS(k) (((k) >= SP_PROP_FONT) && ((k) <= SP_PROP_TEXT_RENDERING)) + +enum SPAttributeEnum { + SP_ATTR_INVALID, ///< Must have value 0. + /* SPObject */ + SP_ATTR_ID, + SP_ATTR_INKSCAPE_COLLECT, + SP_ATTR_INKSCAPE_LABEL, + /* SPItem */ + SP_ATTR_TRANSFORM, + SP_ATTR_SODIPODI_INSENSITIVE, + SP_ATTR_SODIPODI_NONPRINTABLE, + SP_ATTR_CONNECTOR_AVOID, + SP_ATTR_STYLE, + /* SPAnchor */ + SP_ATTR_XLINK_HREF, + SP_ATTR_XLINK_TYPE, + SP_ATTR_XLINK_ROLE, + SP_ATTR_XLINK_ARCROLE, + SP_ATTR_XLINK_TITLE, + SP_ATTR_XLINK_SHOW, + SP_ATTR_XLINK_ACTUATE, + SP_ATTR_TARGET, + /* SPGroup */ + SP_ATTR_INKSCAPE_GROUPMODE, + /* SPRoot */ + SP_ATTR_VERSION, + SP_ATTR_WIDTH, + SP_ATTR_HEIGHT, + SP_ATTR_VIEWBOX, + SP_ATTR_PRESERVEASPECTRATIO, + SP_ATTR_SODIPODI_VERSION, + SP_ATTR_INKSCAPE_VERSION, + /* SPNamedView */ + SP_ATTR_VIEWONLY, + SP_ATTR_SHOWGRID, + SP_ATTR_SHOWGUIDES, + SP_ATTR_GRIDTOLERANCE, + SP_ATTR_GUIDETOLERANCE, + SP_ATTR_OBJECTTOLERANCE, + SP_ATTR_ABS_TOLERANCE, + SP_ATTR_GRIDORIGINX, + SP_ATTR_GRIDORIGINY, + SP_ATTR_GRIDSPACINGX, + SP_ATTR_GRIDSPACINGY, + SP_ATTR_GRIDCOLOR, + SP_ATTR_GRIDOPACITY, + SP_ATTR_GRIDEMPCOLOR, + SP_ATTR_GRIDEMPOPACITY, + SP_ATTR_GRIDEMPSPACING, + SP_ATTR_GUIDECOLOR, + SP_ATTR_GUIDEOPACITY, + SP_ATTR_GUIDEHICOLOR, + SP_ATTR_GUIDEHIOPACITY, + SP_ATTR_SHOWBORDER, + SP_ATTR_SHOWPAGESHADOW, + SP_ATTR_BORDERLAYER, + SP_ATTR_BORDERCOLOR, + SP_ATTR_BORDEROPACITY, + SP_ATTR_PAGECOLOR, + SP_ATTR_INKSCAPE_PAGEOPACITY, + SP_ATTR_INKSCAPE_PAGESHADOW, + SP_ATTR_INKSCAPE_ZOOM, + SP_ATTR_INKSCAPE_CX, + SP_ATTR_INKSCAPE_CY, + SP_ATTR_INKSCAPE_WINDOW_WIDTH, + SP_ATTR_INKSCAPE_WINDOW_HEIGHT, + SP_ATTR_INKSCAPE_WINDOW_X, + SP_ATTR_INKSCAPE_WINDOW_Y, + SP_ATTR_INKSCAPE_GRID_BBOX, + SP_ATTR_INKSCAPE_GUIDE_BBOX, + SP_ATTR_INKSCAPE_OBJECT_BBOX, + SP_ATTR_INKSCAPE_GRID_POINTS, + SP_ATTR_INKSCAPE_GUIDE_POINTS, + SP_ATTR_INKSCAPE_OBJECT_POINTS, + SP_ATTR_INKSCAPE_OBJECT_PATHS, + SP_ATTR_INKSCAPE_OBJECT_NODES, + SP_ATTR_INKSCAPE_CURRENT_LAYER, + SP_ATTR_INKSCAPE_DOCUMENT_UNITS, + /* SPGuide */ + SP_ATTR_ORIENTATION, + SP_ATTR_POSITION, + /* SPImage */ + SP_ATTR_X, + SP_ATTR_Y, + /* SPPath */ + SP_ATTR_D, + SP_ATTR_CONNECTOR_TYPE, + SP_ATTR_CONNECTION_START, + SP_ATTR_CONNECTION_END, + /* SPRect */ + SP_ATTR_RX, + SP_ATTR_RY, + /* SPEllipse */ + SP_ATTR_R, + SP_ATTR_CX, + SP_ATTR_CY, + SP_ATTR_SODIPODI_CX, + SP_ATTR_SODIPODI_CY, + SP_ATTR_SODIPODI_RX, + SP_ATTR_SODIPODI_RY, + SP_ATTR_SODIPODI_START, + SP_ATTR_SODIPODI_END, + SP_ATTR_SODIPODI_OPEN, + /* SPStar */ + SP_ATTR_SODIPODI_SIDES, + SP_ATTR_SODIPODI_R1, + SP_ATTR_SODIPODI_R2, + SP_ATTR_SODIPODI_ARG1, + SP_ATTR_SODIPODI_ARG2, + SP_ATTR_INKSCAPE_FLATSIDED, + SP_ATTR_INKSCAPE_ROUNDED, + SP_ATTR_INKSCAPE_RANDOMIZED, + /* SPSpiral */ + SP_ATTR_SODIPODI_EXPANSION, + SP_ATTR_SODIPODI_REVOLUTION, + SP_ATTR_SODIPODI_RADIUS, + SP_ATTR_SODIPODI_ARGUMENT, + SP_ATTR_SODIPODI_T0, + /* SPOffset */ + SP_ATTR_SODIPODI_ORIGINAL, + SP_ATTR_INKSCAPE_ORIGINAL, + SP_ATTR_INKSCAPE_HREF, + SP_ATTR_INKSCAPE_RADIUS, + /* SPLine */ + SP_ATTR_X1, + SP_ATTR_Y1, + SP_ATTR_X2, + SP_ATTR_Y2, + /* SPPolyline */ + SP_ATTR_POINTS, + /* SPTSpan */ + SP_ATTR_DX, + SP_ATTR_DY, + SP_ATTR_ROTATE, + SP_ATTR_SODIPODI_ROLE, + /* SPText */ + SP_ATTR_SODIPODI_LINESPACING, + /* SPTextPath */ + SP_ATTR_STARTOFFSET, + /* SPStop */ + SP_ATTR_OFFSET, + /* SPGradient */ + SP_ATTR_GRADIENTUNITS, + SP_ATTR_GRADIENTTRANSFORM, + SP_ATTR_SPREADMETHOD, + /* SPRadialGradient */ + SP_ATTR_FX, + SP_ATTR_FY, + /* SPPattern */ + SP_ATTR_PATTERNUNITS, + SP_ATTR_PATTERNCONTENTUNITS, + SP_ATTR_PATTERNTRANSFORM, + /* SPClipPath */ + SP_ATTR_CLIPPATHUNITS, + /* SPMask */ + SP_ATTR_MASKUNITS, + SP_ATTR_MASKCONTENTUNITS, + /* SPMarker */ + SP_ATTR_MARKERUNITS, + SP_ATTR_REFX, + SP_ATTR_REFY, + SP_ATTR_MARKERWIDTH, + SP_ATTR_MARKERHEIGHT, + SP_ATTR_ORIENT, + /* SPStyleElem */ + SP_ATTR_TYPE, + /* Animations */ + SP_ATTR_ATTRIBUTENAME, + SP_ATTR_ATTRIBUTETYPE, + SP_ATTR_BEGIN, + SP_ATTR_DUR, + SP_ATTR_END, + SP_ATTR_MIN, + SP_ATTR_MAX, + SP_ATTR_RESTART, + SP_ATTR_REPEATCOUNT, + SP_ATTR_REPEATDUR, + /* Interpolating animations */ + SP_ATTR_CALCMODE, + SP_ATTR_VALUES, + SP_ATTR_KEYTIMES, + SP_ATTR_KEYSPLINES, + SP_ATTR_FROM, + SP_ATTR_TO, + SP_ATTR_BY, + SP_ATTR_ADDITIVE, + SP_ATTR_ACCUMULATE, + + /* XML */ + SP_ATTR_XML_SPACE, + + /* typeset */ + SP_ATTR_TEXT_NOMARKUP, + SP_ATTR_TEXT_PANGOMARKUP, + SP_ATTR_TEXT_INSHAPE, + SP_ATTR_TEXT_ONPATH, + SP_ATTR_TEXT_INBOX, + SP_ATTR_TEXT_INCOLUMN, + SP_ATTR_TEXT_EXCLUDE, + SP_ATTR_LAYOUT_OPTIONS, + + /* CSS2 */ + /* Font */ + SP_PROP_FONT, + SP_PROP_FONT_FAMILY, + SP_PROP_FONT_SIZE, + SP_PROP_FONT_SIZE_ADJUST, + SP_PROP_FONT_STRETCH, + SP_PROP_FONT_STYLE, + SP_PROP_FONT_VARIANT, + SP_PROP_FONT_WEIGHT, + /* Text */ + SP_PROP_TEXT_INDENT, + SP_PROP_TEXT_ALIGN, + SP_PROP_TEXT_DECORATION, + SP_PROP_LINE_HEIGHT, + SP_PROP_LETTER_SPACING, + SP_PROP_WORD_SPACING, + SP_PROP_TEXT_TRANSFORM, + /* text (css3) */ + SP_PROP_DIRECTION, + SP_PROP_BLOCK_PROGRESSION, + SP_PROP_WRITING_MODE, + SP_PROP_UNICODE_BIDI, + SP_PROP_ALIGNMENT_BASELINE, + SP_PROP_BASELINE_SHIFT, + SP_PROP_DOMINANT_BASELINE, + SP_PROP_GLYPH_ORIENTATION_HORIZONTAL, + SP_PROP_GLYPH_ORIENTATION_VERTICAL, + SP_PROP_KERNING, + SP_PROP_TEXT_ANCHOR, + /* Misc */ + SP_PROP_CLIP, + SP_PROP_COLOR, + SP_PROP_CURSOR, + SP_PROP_DISPLAY, + SP_PROP_OVERFLOW, + SP_PROP_VISIBILITY, + /* SVG */ + /* Clip/Mask */ + SP_PROP_CLIP_PATH, + SP_PROP_CLIP_RULE, + SP_PROP_MASK, + SP_PROP_OPACITY, + /* Filter */ + SP_PROP_ENABLE_BACKGROUND, + SP_PROP_FILTER, + SP_PROP_FLOOD_COLOR, + SP_PROP_FLOOD_OPACITY, + SP_PROP_LIGHTING_COLOR, + /* Gradient */ + SP_PROP_STOP_COLOR, + SP_PROP_STOP_OPACITY, + /* Interactivity */ + SP_PROP_POINTER_EVENTS, + /* Paint */ + SP_PROP_COLOR_INTERPOLATION, + SP_PROP_COLOR_INTERPOLATION_FILTERS, + SP_PROP_COLOR_PROFILE, + SP_PROP_COLOR_RENDERING, + SP_PROP_FILL, + SP_PROP_FILL_OPACITY, + SP_PROP_FILL_RULE, + SP_PROP_IMAGE_RENDERING, + SP_PROP_MARKER, + SP_PROP_MARKER_END, + SP_PROP_MARKER_MID, + SP_PROP_MARKER_START, + SP_PROP_SHAPE_RENDERING, + SP_PROP_STROKE, + SP_PROP_STROKE_DASHARRAY, + SP_PROP_STROKE_DASHOFFSET, + SP_PROP_STROKE_LINECAP, + SP_PROP_STROKE_LINEJOIN, + SP_PROP_STROKE_MITERLIMIT, + SP_PROP_STROKE_OPACITY, + SP_PROP_STROKE_WIDTH, + SP_PROP_TEXT_RENDERING +}; + +#endif + + +/* + 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:textwidth=99 : diff --git a/src/bad-uri-exception.h b/src/bad-uri-exception.h new file mode 100644 index 000000000..322b9ae58 --- /dev/null +++ b/src/bad-uri-exception.h @@ -0,0 +1,34 @@ +#ifndef SEEN_BAD_URI_EXCEPTION_H +#define SEEN_BAD_URI_EXCEPTION_H + +#include + +namespace Inkscape { + +class BadURIException : public std::exception {}; + +class UnsupportedURIException : public BadURIException { +public: + char const *what() const throw() { return "Unsupported URI"; } +}; + +class MalformedURIException : public BadURIException { +public: + char const *what() const throw() { return "Malformed URI"; } +}; + +} + + +#endif /* !SEEN_BAD_URI_EXCEPTION_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 : diff --git a/src/brokenimage.xpm b/src/brokenimage.xpm new file mode 100644 index 000000000..39d23548e --- /dev/null +++ b/src/brokenimage.xpm @@ -0,0 +1,88 @@ +/* XPM */ +static char * brokenimage_xpm[] = { +"64 64 21 1", +" c None", +". c #FAB1BE", +"+ c #FDD2D8", +"@ c #FEFBFA", +"# c #F98FA1", +"$ c #F66F85", +"% c #F54F6A", +"& c #F32D4E", +"* c #F01237", +"= c #9F6F77", +"- c #9F8F92", +"; c #D0CAC9", +"> c #110609", +", c #4C3237", +"' c #594E4F", +") c #BAAFB1", +"! c #9C2D40", +"~ c #727172", +"{ c #580F1B", +"] c #950E24", +"^ c #A54E5D", +".+.++@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@+++##$%%%&%$", +"##..+++@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@+..#$%&&*&&%", +"$$$#..++@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@+++..#$%%&***&%", +"&%%$#.+++@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@+++##%%&&*****%", +"*&&%$$..+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@++++.##$%&******&%", +"**&&%$#.++@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@++++..#$%%&&*****&&%", +"****&%%#..+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@+@++.##$$%%&&*****&&%$", +"****&&%$#.++@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@++..#$$%%%&&*****&&%$#", +"*****&&%##.++@@@@@@@@@@@@@@@@@@@@@@@@@@@++..##$%%&&********&%$#.", +"******&%%#=---;@@@@@@@@@@@@@@@@@@;+@@@+++..#$%%&&&*******&%%$$..", +"&******&%$>,,'>,@@@@@@@@@@@@@@@@@,)@@+++.##$%%&*********&&%$#..+", +"%&******&&>#..;>)@@@@@@@@@@@@@@@@>;+++..#$%%&&*********&&%$$.+++", +"%%&*****&!>$$..>)@';'~@@;,>>~@@@;>+++='#$%{>>>]***{*{>>{$$#..+@@", +"$%&&*****{{%$#,>++>,~+@->;@;>'@@-'+.=>$%%>{**]>]**>{]%^>!#.+++@@", +"#$%&*****{{{{>>#+->)@@)>@@@@;>)+''.=>%%%>]&***]{*]>&%%$^>.++@@@@", +".#$%&&***>]]!,>^#~'+@@>-@@@@@>-+,=$>^%&*>******>&!{$$#.=>+++@@@@", +"+.#$%&***>**&&!>#,~+@)>@@@@@+>-.>^>!&&&{>>>>>>>>&,!##..~,@@@@@@@", +"+..$$%&*]>****!>${=++->@@@@+->.$>>{>&**{{****&&%$>=.+++''@@@@@@@", +"@+..#$%&]{****{{%>$.+)>;@@++>'#^>!&>]**]>**&&%>$#>).++@>)@@@@@@@", +"@++.##$%{{]]]>{*!>$#.+'>-@-,,#${{**]>***>{]!!>^#=>++@@@>;@@@@@@@", +"@@@+..$$!{{{{]***{%$#++~'>,=#%%!]***{]**&{>{,$..)=+@@@;'@@@@@@@@", +"@@@++..#$%&******&%$#.+++..#$%&&******&&%%$##..++@@@@@@@@@@@@@@@", +"@@@@@+.##%%&******&%$#...##%%&&******&&%$$#..++@@@@@@@@@@@@@@@@@", +"@@@@@@+..$$%&******%%$###$$%&*******&%%$##.+++@+@@@@@@@@@@@@@@@@", +"@@@@@+@+.##%%&****&&%$$$$$%&&*****&&%%$#..++@@@@@@@@@@@@@@@@@@@@", +"@@@@@@+@+.#$%&&*****&%%%%%&&******&%%##.+++@@@@@@@@@@@@@@@@@@@@@", +"@@@@@@@@++.#$%&*****&&&%&&*******&%$$..++@@@@@@@@@@@@@@@@@@@@@@@", +"@@@@@@@@@++.$%&******&*&*******&&%$$..++@@@@@@@@@@@@@@@@@@@@@@@@", +"@@@@@@@@@++.#$&&**************&&%$#..+@@@@@@@@@@@@@@@@@@@@@@@@@@", +"@@@@@@@@@@++#$%***************&%$$..+@+@@@@@@@@@@@@@@@@@@@@@@@@@", +"@@@@@@@@@@++.#%&*************&%%#..++@@@@@@@@@@@@@@@@@@@@@@@@@@@", +"@@@@@@@@@@@+.#%%*************%%$#.+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@", +"@@@@@@@@@@++.#%%************&%$#.++@@@@@@@@@@@@@@@@@@@@@@@@@@@@@", +"@@@@@@@@@;;..#%&************&%$#.++@@@@@@@@@@@@@@@@@@@@@@@@@@@@@", +"@@@@@@@@@>;.#$%%************&%%#.++@@@@@@@@@@@@@@@@@@@@@@@@@@@@@", +"@@@@@@@@;>..#$&&*************%%$#.++@@@@@@@@@@@@@@@@@@@@@@@@@@@@", +"@@@@@@++-,.^!!>>{**{>>]****]{>>!#,++++~>>,@~;@@+'>>,@@@@@@@@@@@@", +"@@@@@@++',#^>{**>{>]*]>]**{>]*&,{>.+-,-@;',>+@)>-@@'>+@@@@@@@@@@", +"@@@@+++.,^${>&**]>]**&{{*]>***&&>,$#>)+@@@,>@@>@@@@@'-@@@@@@@@@@", +"@@@@++.#>^%{]***]>*&&&{{*>]*****{{$',.++@@-'@~~@@@@@-'@@@@@@@@@@", +"@@++..#$>&&>****]{&&%%>!!>******{!%>^..++@~'@>>>>>>>>'@@@@@@@@@@", +"@++..$$!>&*>****{{%$$$>=!>&&****>]&>^##.++>-@>)@@@@@@@@@@@@@@@@@", +"++..$$%!{*]>****{!%$#=>#=>!&***{>*&>]$$#.~>)@,~@@@@-,@@@@@@@@@@@", +"+.##%%&{]*{{***&>%##.=,.#,>!&]{>>**]>!%^,,>++->-;)''+@@@@@@@@@@@", +".#$$%&*]]*]**&&%,$..+~=++.^>>{]*]***]{>{!^,..+)'>'-@@@@@@@@@@@@@", +"#$%&&*******&%%$##+++@@++..#$%&***]>**&&%>!#..+++@@@@@@@@@@@@@@@", +"$%%&******&&%%$#..+@@@@@++..#$%&***>{**!>{%$$#..++@@@@@@@@@@@@@@", +"%&&*******&%$##.++@+@@@@@@+..$$%&***{>>{]&&%%$##.;++@@@@@@@@@@@@", +"&********&%$$#+++@@@@@@@@@++..#$%&&********&&%%$#..++@@@@@@@@@@@", +"&******&&%$$..+++@@@@@@@@@@@+..#$%&&********&&%%$$..+++@@@@@@@@@", +"******&&%$#..++@@@@@@@@@@@@@+++.#$%%&&********&&%$$#.+++@@@@@@@@", +"*****&%%$##++@@@@@@@@@@@@@@@@+++..$$%%&*********&%$$#.+++@@@@@@@", +"****&%%$#.+++@@@@@@@@@@@@@@@@@+++.##$%%&&&*******&&%$##+++@@@@@@", +"**&&%%##.+++@@@@@@@@@@@@@@@@@@@@+++.##$%%&&*******&&%$$.+++@@@@@", +"*&&%$$#.++@@@@@@@@@@@@@@@@@@@@@@@+++..#$$%%&*******&&%$#.+@@@@@@", +"&%%$#..++@@@@@@@@@@@@@@@@@@@@@@@@@@+++.##$%%&&*******&%$#.++@@@@", +"$$$#..++@@@@@@@@@@@@@@@@@@@@@@@@@@@@+++..#$%%&********%$#++@@@@@", +"##..+++@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@+++##%%&*******&$#.++@@@@", +"..+++@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@+++.##$%&&****&%$#++@@@@@", +"++++@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@+@+.##$%%&&*&&%##+++@@@@", +"@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@+++.#$$%%%%$$#.+@@@@@@", +"+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@+++..##$$$#..+++@@@@@", +"@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@++++...#...++@@@@@@@", +"@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@+++++.+++++@@@@@@@"}; diff --git a/src/check-header-compile.in b/src/check-header-compile.in new file mode 100755 index 000000000..6d0e10789 --- /dev/null +++ b/src/check-header-compile.in @@ -0,0 +1,41 @@ +#! /bin/sh +# Check that each .h file has all the includes it needs. + +# Probably requires gnu find (for -printf '%P\n'). + +# This script hereby placed into the public domain. + +set -e +mydir=`dirname "$0"` +cd "$mydir" +srcdir="@srcdir@" +CXX="@CXX@" +INKSCAPE_CFLAGS="@INKSCAPE_CFLAGS@" +OBJEXT="@OBJEXT@" +config_h_dir=.. + +check_compile () { + (echo "#include "; echo "#include <$1>"; echo "int header_tst_dummy;") > header-tst.cpp + $CXX -c -I. -I"$srcdir" -I$config_h_dir $INKSCAPE_CFLAGS header-tst.cpp +} + +if [ $# = 0 ]; then + for i in `find "$srcdir" \ + -name bonobo -prune \ + -o -name ecma -prune \ + -o -name render -prune \ + -o -name xpath -prune \ + -o -path '*/extension/script/js' -prune \ + -o -name '*.h' \ + \! -name gnome.h \! -name win32.h \! -name nr-type-gnome.h \! -name nr-type-w32.h \! -name Livarot.h \! -name radial.h \ + \! -name '*-test.h' \ + -printf '%P\n'` + do + check_compile "$i" + done +else + for i in "$@"; do + check_compile "$i" + done +fi +rm header-tst.cpp header-tst.$OBJEXT diff --git a/src/color-rgba.h b/src/color-rgba.h new file mode 100644 index 000000000..24bc63b52 --- /dev/null +++ b/src/color-rgba.h @@ -0,0 +1,194 @@ +/** \file color-rgba.h + + A class to handle a RGBA color as one unit. + + Authors: + bulia byak + + Copyright (C) 2004 Authors + + Released under GNU GPL, read the file 'COPYING' for more information +*/ +#ifndef SEEN_COLOR_RGBA_H +#define SEEN_COLOR_RGBA_H + +#include +#include "libnr/nr-pixops.h" +#include "decimal-round.h" + +/** + \brief A class to contain a floating point RGBA color. +*/ +class ColorRGBA { +public: + /** + \brief A constructor to create the color from four floating + point values. + \param c0 Red + \param c1 Green + \param c2 Blue + \param c3 Alpha + + Load the values into the array of floats in this object. + */ + ColorRGBA(float c0, float c1, float c2, float c3) + { + _c[0] = c0; _c[1] = c1; + _c[2] = c2; _c[3] = c3; + } + + /** + \brief Create a quick ColorRGBA with all zeros + */ + ColorRGBA(void) + { + for (int i = 0; i < 4; i++) + _c[i] = 0.0; + } + + /** + \brief A constructor to create the color from an unsigned + int, as found everywhere when dealing with colors + \param intcolor rgba32 "unsigned int representation (0xRRGGBBAA) + + Separate the values and load them into the array of floats in this object. + TODO : maybe get rid of the NR_RGBA32_x C-style functions and replace + the calls with the bitshifting they do + */ + ColorRGBA(unsigned int intcolor) + { + _c[0] = NR_RGBA32_R(intcolor)/255.0; + _c[1] = NR_RGBA32_G(intcolor)/255.0; + _c[2] = NR_RGBA32_B(intcolor)/255.0; + _c[3] = NR_RGBA32_A(intcolor)/255.0; + + } + + /** + \brief Create a ColorRGBA using an array of floats + \param in_array The values to be placed into the object + + Go through each entry in the array and put it into \c _c. + */ + ColorRGBA(float in_array[4]) + { + for (int i = 0; i < 4; i++) + _c[i] = in_array[i]; + } + + /** + \brief Overwrite the values in this object with another \c ColorRGBA. + \param m Values to use for the array + \return This ColorRGBA object + + Copy all the values from \c m into \c this. + */ + ColorRGBA &operator=(ColorRGBA const &m) { + for (unsigned i = 0 ; i < 4 ; ++i) { + _c[i] = m._c[i]; + } + return *this; + } + + /** + \brief Grab a particular value from the ColorRGBA object + \param i Which value to grab + \return The requested value. + + First checks to make sure that the value is within the array, + and then return the value if it is. + */ + float operator[](unsigned int const i) const { + g_assert( unsigned(i) < 4 ); + return _c[i]; + } + + /** + \brief Check to ensure that two \c ColorRGBA's are equal + \param other The guy to check against + \return Whether or not they are equal + + Check each value to see if they are equal. If they all are, + return TRUE. + */ + bool operator== (const ColorRGBA other) const { + for (int i = 0; i < 4; i++) { + if (_c[i] != other[i]) + return FALSE; + } + return TRUE; + } + + /** + \brief Average two \c ColorRGBAs to create another one. + \param second The second RGBA, with this being the first + \param weight How much of each should be used. Zero is all + this while one is all the second. Default is + half and half. + + This function goes through all the points in the two objects and + merges them together based on the weighting. The current objects + value are multiplied by 1.0 - weight and the second object by weight. + This means that they should always be balanced by the parameter. + */ + ColorRGBA average (const ColorRGBA second, const float weight = 0.5) const { + float returnval[4]; + + for (int i = 0; i < 4; i++) { + returnval[i] = _c[i] * (1.0 - weight) + second[i] * weight; + } + + return ColorRGBA(returnval[0], returnval[1], returnval[2], returnval[3]); + } + + /** + \brief Create a ColorRGBA with the inverse color of the current ColorRGBA + + do 1 minus each color components (but not the alpha) and put it into \c _c. + */ + ColorRGBA getInverse() const { + return ColorRGBA( (1.0 - _c[0]), (1.0 - _c[1]), (1.0 - _c[2]), _c[3] ); + } + + /** + \brief Create a ColorRGBA with the inverse color of a given ColorRGBA + + do 1 minus each color components (but not the alpha) and put it into \c _c. + */ + ColorRGBA getInverse(const ColorRGBA ref) const { + return getInverse(ref); + } + + /** + \brief Give the rgba32 "unsigned int" representation of the color + + round each components*255 and combine them (RRGGBBAA). + WARNING : this reduces color precision (from float to 0->255 int per component) + but it should be expected since we request this kind of output + */ + unsigned int getIntValue() const { + + return (int(Inkscape::decimal_round(_c[0]*255, 0)) << 24) | + (int(Inkscape::decimal_round(_c[1]*255, 0)) << 16) | + (int(Inkscape::decimal_round(_c[2]*255, 0)) << 8) | + (int(Inkscape::decimal_round(_c[3]*255, 0))); + } + +private: + /** \brief Array of values that are stored. */ + float _c[4]; +}; + + +#endif /* !SEEN_COLOR_RGBA_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 : diff --git a/src/color.cpp b/src/color.cpp new file mode 100644 index 000000000..c968d334f --- /dev/null +++ b/src/color.cpp @@ -0,0 +1,468 @@ +#define __SP_COLOR_C__ + +/** \file + * Colors and colorspaces. + * + * Author: + * Lauris Kaplinski + * bulia byak + * + * Copyright (C) 2001-2002 Lauris Kaplinski + * Copyright (C) 2001 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include +#include "color.h" + +/// A color space is just a name. +struct SPColorSpace { + gchar const *name; +}; + +static SPColorSpace const RGB = {"RGB"}; +static SPColorSpace const CMYK = {"CMYK"}; + +/** + * Returns one of three values depending on if color is valid and if it + * has a valid color space. Likely redundant as soon as this is C++. + */ +SPColorSpaceClass +sp_color_get_colorspace_class(SPColor const *color) +{ + g_return_val_if_fail (color != NULL, SP_COLORSPACE_CLASS_INVALID); + + if (color->colorspace == &RGB) return SP_COLORSPACE_CLASS_PROCESS; + if (color->colorspace == &CMYK) return SP_COLORSPACE_CLASS_PROCESS; + + return SP_COLORSPACE_CLASS_UNKNOWN; +} + +/** + * Returns the SPColorSpaceType corresponding to color's color space. + * \todo color->colorspace should simply be a named enum. + */ +SPColorSpaceType +sp_color_get_colorspace_type(SPColor const *color) +{ + g_return_val_if_fail (color != NULL, SP_COLORSPACE_TYPE_INVALID); + + if (color->colorspace == &RGB) return SP_COLORSPACE_TYPE_RGB; + if (color->colorspace == &CMYK) return SP_COLORSPACE_TYPE_CMYK; + + return SP_COLORSPACE_TYPE_UNKNOWN; +} + +/** + * Shallow copy of color struct with NULL check. + */ +void +sp_color_copy(SPColor *dst, SPColor const *src) +{ + g_return_if_fail (dst != NULL); + g_return_if_fail (src != NULL); + + *dst = *src; +} + +/** + * Returns TRUE if c0 or c1 is NULL, or if colors/opacities differ. + */ +gboolean +sp_color_is_equal (SPColor const *c0, SPColor const *c1) +{ + g_return_val_if_fail (c0 != NULL, TRUE); + g_return_val_if_fail (c1 != NULL, TRUE); + + if (c0->colorspace != c1->colorspace) return FALSE; + if (c0->v.c[0] != c1->v.c[0]) return FALSE; + if (c0->v.c[1] != c1->v.c[1]) return FALSE; + if (c0->v.c[2] != c1->v.c[2]) return FALSE; + if ((c0->colorspace == &CMYK) && (c0->v.c[3] != c1->v.c[3])) return FALSE; + + return TRUE; +} + +/** + * Returns TRUE if no RGB value differs epsilon or more in both colors, + * with CMYK aditionally comparing opacity, or if c0 or c1 is NULL. + * \note Do we want the latter? + */ +gboolean +sp_color_is_close (SPColor const *c0, SPColor const *c1, float epsilon) +{ + g_return_val_if_fail (c0 != NULL, TRUE); + g_return_val_if_fail (c1 != NULL, TRUE); + + if (c0->colorspace != c1->colorspace) return FALSE; + if (fabs ((c0->v.c[0]) - (c1->v.c[0])) >= epsilon) return FALSE; + if (fabs ((c0->v.c[1]) - (c1->v.c[1])) >= epsilon) return FALSE; + if (fabs ((c0->v.c[2]) - (c1->v.c[2])) >= epsilon) return FALSE; + if ((c0->colorspace == &CMYK) && (fabs ((c0->v.c[3]) - (c1->v.c[3])) >= epsilon)) return FALSE; + + return TRUE; +} + +/** + * Sets RGB values and colorspace in color. + * \pre color != NULL && 0 <={r,g,b}<=1 + */ +void +sp_color_set_rgb_float(SPColor *color, float r, float g, float b) +{ + g_return_if_fail(color != NULL); + g_return_if_fail(r >= 0.0); + g_return_if_fail(r <= 1.0); + g_return_if_fail(g >= 0.0); + g_return_if_fail(g <= 1.0); + g_return_if_fail(b >= 0.0); + g_return_if_fail(b <= 1.0); + + color->colorspace = &RGB; + color->v.c[0] = r; + color->v.c[1] = g; + color->v.c[2] = b; + color->v.c[3] = 0; +} + +/** + * Converts 32bit value to RGB floats and sets color. + * \pre color != NULL + */ +void +sp_color_set_rgb_rgba32(SPColor *color, guint32 value) +{ + g_return_if_fail (color != NULL); + + color->colorspace = &RGB; + color->v.c[0] = (value >> 24) / 255.0F; + color->v.c[1] = ((value >> 16) & 0xff) / 255.0F; + color->v.c[2] = ((value >> 8) & 0xff) / 255.0F; + color->v.c[3] = 0; +} + +/** + * Sets CMYK values and colorspace in color. + * \pre color != NULL && 0 <={c,m,y,k}<=1 + */ +void +sp_color_set_cmyk_float(SPColor *color, float c, float m, float y, float k) +{ + g_return_if_fail(color != NULL); + g_return_if_fail(c >= 0.0); + g_return_if_fail(c <= 1.0); + g_return_if_fail(m >= 0.0); + g_return_if_fail(m <= 1.0); + g_return_if_fail(y >= 0.0); + g_return_if_fail(y <= 1.0); + g_return_if_fail(k >= 0.0); + g_return_if_fail(k <= 1.0); + + color->colorspace = &CMYK; + color->v.c[0] = c; + color->v.c[1] = m; + color->v.c[2] = y; + color->v.c[3] = k; +} + +/** + * Convert SPColor with integer alpha value to 32bit RGBA value. + * \pre color != NULL && alpha < 256 + */ +guint32 +sp_color_get_rgba32_ualpha(SPColor const *color, guint32 alpha) +{ + guint32 rgba; + + g_return_val_if_fail (color != NULL, 0x0); + g_return_val_if_fail (alpha <= 0xff, 0x0); + + if (color->colorspace == &RGB) { + rgba = SP_RGBA32_U_COMPOSE(SP_COLOR_F_TO_U(color->v.c[0]), + SP_COLOR_F_TO_U(color->v.c[1]), + SP_COLOR_F_TO_U(color->v.c[2]), + alpha); + } else { + float rgb[3]; + sp_color_get_rgb_floatv (color, rgb); + rgba = SP_RGBA32_U_COMPOSE(SP_COLOR_F_TO_U(rgb[0]), + SP_COLOR_F_TO_U(rgb[1]), + SP_COLOR_F_TO_U(rgb[2]), + alpha); + } + + return rgba; +} + +/** + * Convert SPColor with float alpha value to 32bit RGBA value. + * \pre color != NULL && 0 <= alpha <= 1 + */ +guint32 +sp_color_get_rgba32_falpha(SPColor const *color, float alpha) +{ + g_return_val_if_fail(color != NULL, 0x0); + g_return_val_if_fail(alpha >= 0.0, 0x0); + g_return_val_if_fail(alpha <= 1.0, 0x0); + + return sp_color_get_rgba32_ualpha(color, SP_COLOR_F_TO_U(alpha)); +} + +/** + * Fill rgb float array with values from SPColor. + * \pre color != NULL && rgb != NULL && rgb[0-2] is meaningful + */ +void +sp_color_get_rgb_floatv(SPColor const *color, float *rgb) +{ + g_return_if_fail (color != NULL); + g_return_if_fail (rgb != NULL); + + if (color->colorspace == &RGB) { + rgb[0] = color->v.c[0]; + rgb[1] = color->v.c[1]; + rgb[2] = color->v.c[2]; + } else if (color->colorspace == &CMYK) { + sp_color_cmyk_to_rgb_floatv(rgb, + color->v.c[0], + color->v.c[1], + color->v.c[2], + color->v.c[3]); + } +} + +/** + * Fill cmyk float array with values from SPColor. + * \pre color != NULL && cmyk != NULL && cmyk[0-3] is meaningful + */ +void +sp_color_get_cmyk_floatv(SPColor const *color, float *cmyk) +{ + g_return_if_fail (color != NULL); + g_return_if_fail (cmyk != NULL); + + if (color->colorspace == &CMYK) { + cmyk[0] = color->v.c[0]; + cmyk[1] = color->v.c[1]; + cmyk[2] = color->v.c[2]; + cmyk[3] = color->v.c[3]; + } else if (color->colorspace == &RGB) { + sp_color_rgb_to_cmyk_floatv(cmyk, + color->v.c[0], + color->v.c[1], + color->v.c[2]); + } +} + +/* Plain mode helpers */ + +/** + * Fill hsv float array from r,g,b float values. + */ +void +sp_color_rgb_to_hsv_floatv (float *hsv, float r, float g, float b) +{ + float max, min, delta; + + max = MAX (MAX (r, g), b); + min = MIN (MIN (r, g), b); + delta = max - min; + + hsv[2] = max; + + if (max > 0) { + hsv[1] = delta / max; + } else { + hsv[1] = 0.0; + } + + if (hsv[1] != 0.0) { + if (r == max) { + hsv[0] = (g - b) / delta; + } else if (g == max) { + hsv[0] = 2.0 + (b - r) / delta; + } else { + hsv[0] = 4.0 + (r - g) / delta; + } + + hsv[0] = hsv[0] / 6.0; + + if (hsv[0] < 0) hsv[0] += 1.0; + } +} + +/** + * Fill rgb float array from h,s,v float values. + */ +void +sp_color_hsv_to_rgb_floatv (float *rgb, float h, float s, float v) +{ + gdouble f, w, q, t, d; + + d = h * 5.99999999; + f = d - floor (d); + w = v * (1.0 - s); + q = v * (1.0 - (s * f)); + t = v * (1.0 - (s * (1.0 - f))); + + if (d < 1.0) { + *rgb++ = v; + *rgb++ = t; + *rgb++ = w; + } else if (d < 2.0) { + *rgb++ = q; + *rgb++ = v; + *rgb++ = w; + } else if (d < 3.0) { + *rgb++ = w; + *rgb++ = v; + *rgb++ = t; + } else if (d < 4.0) { + *rgb++ = w; + *rgb++ = q; + *rgb++ = v; + } else if (d < 5.0) { + *rgb++ = t; + *rgb++ = w; + *rgb++ = v; + } else { + *rgb++ = v; + *rgb++ = w; + *rgb++ = q; + } +} + +/** + * Fill hsl float array from r,g,b float values. + */ +void +sp_color_rgb_to_hsl_floatv (float *hsl, float r, float g, float b) +{ + float max = MAX (MAX (r, g), b); + float min = MIN (MIN (r, g), b); + float delta = max - min; + + hsl[2] = (max + min)/2.0; + + if (delta == 0) { + hsl[0] = 0; + hsl[1] = 0; + } else { + if (hsl[2] <= 0.5) + hsl[1] = delta / (max + min); + else + hsl[1] = delta / (2 - max - min); + + if (r == max) hsl[0] = (g - b) / delta; + else if (g == max) hsl[0] = 2.0 + (b - r) / delta; + else if (b == max) hsl[0] = 4.0 + (r - g) / delta; + + hsl[0] = hsl[0] / 6.0; + + if (hsl[0] < 0) hsl[0] += 1; + if (hsl[0] > 1) hsl[0] -= 1; + } +} + +float +hue_2_rgb (float v1, float v2, float h) +{ + if (h < 0) h += 6.0; + if (h > 6) h -= 6.0; + + if (h < 1) return v1 + (v2 - v1) * h; + if (h < 3) return v2; + if (h < 4) return v1 + (v2 - v1) * (4 - h); + return v1; +} + +/** + * Fill rgb float array from h,s,l float values. + */ +void +sp_color_hsl_to_rgb_floatv (float *rgb, float h, float s, float l) +{ + if (s == 0) { + rgb[0] = l; + rgb[1] = l; + rgb[2] = l; + } else { + float v2; + if (l < 0.5) { + v2 = l * (1 + s); + } else { + v2 = l + s - l*s; + } + float v1 = 2*l - v2; + + rgb[0] = hue_2_rgb (v1, v2, h*6 + 2.0); + rgb[1] = hue_2_rgb (v1, v2, h*6); + rgb[2] = hue_2_rgb (v1, v2, h*6 - 2.0); + } +} + +/** + * Fill cmyk float array from r,g,b float values. + */ +void +sp_color_rgb_to_cmyk_floatv (float *cmyk, float r, float g, float b) +{ + float c, m, y, k, kd; + + c = 1.0 - r; + m = 1.0 - g; + y = 1.0 - b; + k = MIN (MIN (c, m), y); + + c = c - k; + m = m - k; + y = y - k; + + kd = 1.0 - k; + + if (kd > 1e-9) { + c = c / kd; + m = m / kd; + y = y / kd; + } + + cmyk[0] = c; + cmyk[1] = m; + cmyk[2] = y; + cmyk[3] = k; +} + +/** + * Fill rgb float array from c,m,y,k float values. + */ +void +sp_color_cmyk_to_rgb_floatv (float *rgb, float c, float m, float y, float k) +{ + float kd; + + kd = 1.0 - k; + + c = c * kd; + m = m * kd; + y = y * kd; + + c = c + k; + m = m + k; + y = y + k; + + rgb[0] = 1.0 - c; + rgb[1] = 1.0 - m; + rgb[2] = 1.0 - y; +} + +/* + 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:textwidth=99 : diff --git a/src/color.h b/src/color.h new file mode 100644 index 000000000..2c3f91fe7 --- /dev/null +++ b/src/color.h @@ -0,0 +1,95 @@ +#ifndef __SP_COLOR_H__ +#define __SP_COLOR_H__ + +/** \file + * Colors and colorspaces + * + * Author: + * Lauris Kaplinski + * bulia byak + * + * Copyright (C) 2001-2002 Lauris Kaplinski + * Copyright (C) 2001 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include + +struct SPColorSpace; + +/* Useful composition macros */ + +#define SP_RGBA32_R_U(v) (((v) >> 24) & 0xff) +#define SP_RGBA32_G_U(v) (((v) >> 16) & 0xff) +#define SP_RGBA32_B_U(v) (((v) >> 8) & 0xff) +#define SP_RGBA32_A_U(v) ((v) & 0xff) +#define SP_COLOR_U_TO_F(v) ((v) / 255.0) +#define SP_COLOR_F_TO_U(v) ((unsigned int) ((v) * 255.9999)) +#define SP_RGBA32_R_F(v) SP_COLOR_U_TO_F (SP_RGBA32_R_U (v)) +#define SP_RGBA32_G_F(v) SP_COLOR_U_TO_F (SP_RGBA32_G_U (v)) +#define SP_RGBA32_B_F(v) SP_COLOR_U_TO_F (SP_RGBA32_B_U (v)) +#define SP_RGBA32_A_F(v) SP_COLOR_U_TO_F (SP_RGBA32_A_U (v)) +#define SP_RGBA32_U_COMPOSE(r,g,b,a) ((((r) & 0xff) << 24) | (((g) & 0xff) << 16) | (((b) & 0xff) << 8) | ((a) & 0xff)) +#define SP_RGBA32_F_COMPOSE(r,g,b,a) SP_RGBA32_U_COMPOSE (SP_COLOR_F_TO_U (r), SP_COLOR_F_TO_U (g), SP_COLOR_F_TO_U (b), SP_COLOR_F_TO_U (a)) + +typedef enum { + SP_COLORSPACE_CLASS_INVALID, + SP_COLORSPACE_CLASS_NONE, + SP_COLORSPACE_CLASS_UNKNOWN, + SP_COLORSPACE_CLASS_PROCESS, + SP_COLORSPACE_CLASS_SPOT +} SPColorSpaceClass; + +typedef enum { + SP_COLORSPACE_TYPE_INVALID, + SP_COLORSPACE_TYPE_NONE, + SP_COLORSPACE_TYPE_UNKNOWN, + SP_COLORSPACE_TYPE_RGB, + SP_COLORSPACE_TYPE_CMYK +} SPColorSpaceType; + +/** + * An RGBA color in an SPColorSpace + */ +struct SPColor { + const SPColorSpace *colorspace; + union { + float c[4]; + } v; +}; + +SPColorSpaceClass sp_color_get_colorspace_class (const SPColor *color); +SPColorSpaceType sp_color_get_colorspace_type (const SPColor *color); + +void sp_color_copy (SPColor *dst, const SPColor *src); + +gboolean sp_color_is_equal (const SPColor *c0, const SPColor *c1); +gboolean sp_color_is_close (const SPColor *c0, const SPColor *c1, float epsilon); + +void sp_color_set_rgb_float (SPColor *color, float r, float g, float b); +void sp_color_set_rgb_rgba32 (SPColor *color, guint32 value); + +void sp_color_set_cmyk_float (SPColor *color, float c, float m, float y, float k); + +guint32 sp_color_get_rgba32_ualpha (const SPColor *color, guint32 alpha); +guint32 sp_color_get_rgba32_falpha (const SPColor *color, float alpha); + +void sp_color_get_rgb_floatv (const SPColor *color, float *rgb); +void sp_color_get_cmyk_floatv (const SPColor *color, float *cmyk); + +/* Plain mode helpers */ + +void sp_color_rgb_to_hsv_floatv (float *hsv, float r, float g, float b); +void sp_color_hsv_to_rgb_floatv (float *rgb, float h, float s, float v); + +void sp_color_rgb_to_hsl_floatv (float *hsl, float r, float g, float b); +void sp_color_hsl_to_rgb_floatv (float *rgb, float h, float s, float l); + +void sp_color_rgb_to_cmyk_floatv (float *cmyk, float r, float g, float b); +void sp_color_cmyk_to_rgb_floatv (float *rgb, float c, float m, float y, float k); + + + +#endif + diff --git a/src/composite-undo-stack-observer.cpp b/src/composite-undo-stack-observer.cpp new file mode 100644 index 000000000..04890711b --- /dev/null +++ b/src/composite-undo-stack-observer.cpp @@ -0,0 +1,136 @@ +/** + * Aggregates undo stack observers for convenient management and triggering in SPDocument + * + * Heavily inspired by Inkscape::XML::CompositeNodeObserver. + * + * Authors: + * David Yip + * + * Copyright (c) 2005 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + + +#include "composite-undo-stack-observer.h" +#include "xml/event.h" + +namespace Inkscape { + +CompositeUndoStackObserver::CompositeUndoStackObserver() : _iterating(0) { } +CompositeUndoStackObserver::~CompositeUndoStackObserver() { } + +void +CompositeUndoStackObserver::add(UndoStackObserver& observer) +{ + if (!this->_iterating) { + this->_active.push_back(UndoStackObserverRecord(observer)); + } else { + this->_pending.push_back(UndoStackObserverRecord(observer)); + } +} + +void +CompositeUndoStackObserver::remove(UndoStackObserver& observer) +{ + if (!this->_iterating) { + // logical-or operator short-circuits + this->_remove_one(this->_active, observer) || this->_remove_one(this->_pending, observer); + } else { + this->_mark_one(this->_active, observer) || this->_mark_one(this->_pending, observer); + } +} + +void +CompositeUndoStackObserver::notifyUndoEvent(XML::Event* log) +{ + this->_lock(); + for(UndoObserverRecordList::iterator i = this->_active.begin(); i != _active.end(); ++i) { + if (!i->to_remove) { + i->issueUndo(log); + } + } + this->_unlock(); +} + +void +CompositeUndoStackObserver::notifyRedoEvent(XML::Event* log) +{ + + this->_lock(); + for(UndoObserverRecordList::iterator i = this->_active.begin(); i != _active.end(); ++i) { + if (!i->to_remove) { + i->issueRedo(log); + } + } + this->_unlock(); +} + +void +CompositeUndoStackObserver::notifyUndoCommitEvent(XML::Event* log) +{ + this->_lock(); + for(UndoObserverRecordList::iterator i = this->_active.begin(); i != _active.end(); ++i) { + if (!i->to_remove) { + i->issueUndoCommit(log); + } + } + this->_unlock(); +} + +bool +CompositeUndoStackObserver::_remove_one(UndoObserverRecordList& list, UndoStackObserver& o) +{ + UndoStackObserverRecord eq_comp(o); + + UndoObserverRecordList::iterator i = std::find_if(list.begin(), list.end(), std::bind1st(std::equal_to< UndoStackObserverRecord >(), eq_comp)); + + if (i != list.end()) { + list.erase(i); + return true; + } else { + return false; + } +} + +bool +CompositeUndoStackObserver::_mark_one(UndoObserverRecordList& list, UndoStackObserver& o) +{ + UndoStackObserverRecord eq_comp(o); + + UndoObserverRecordList::iterator i = std::find_if(list.begin(), list.end(), std::bind1st(std::equal_to< UndoStackObserverRecord >(), eq_comp)); + + if (i != list.end()) { + (*i).to_remove = true; + return true; + } else { + return false; + } +} + +void +CompositeUndoStackObserver::_unlock() +{ + if (!--this->_iterating) { + // Remove marked observers + UndoObserverRecordList::iterator i = this->_active.begin(); + for(; i != this->_active.begin(); i++) { + if (i->to_remove) { + this->_active.erase(i); + } + } + + i = this->_pending.begin(); + for(; i != this->_pending.begin(); i++) { + if (i->to_remove) { + this->_active.erase(i); + } + } + + // Merge pending and active + this->_active.insert(this->_active.end(), this->_pending.begin(), this->_pending.end()); + this->_pending.clear(); + } +} + +} diff --git a/src/composite-undo-stack-observer.h b/src/composite-undo-stack-observer.h new file mode 100644 index 000000000..908610135 --- /dev/null +++ b/src/composite-undo-stack-observer.h @@ -0,0 +1,165 @@ +/** + * Aggregates undo stack observers for management and triggering in SPDocument + * + * Heavily inspired by Inkscape::XML::CompositeNodeObserver. + * + * Authors: + * David Yip + * + * Copyright (c) 2005 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifndef __COMPOSITE_UNDO_COMMIT_OBSERVER_H__ +#define __COMPOSITE_UNDO_COMMIT_OBSERVER_H__ + +#include "undo-stack-observer.h" + +#include + +namespace Inkscape { + +namespace XML { + +class Event; + +} + +class UndoStackObserver; + +/** + * Aggregates UndoStackObservers for management and triggering in an SPDocument's undo/redo + * system. + */ +class CompositeUndoStackObserver { +public: + + /** + * Structure for tracking UndoStackObservers. + */ + struct UndoStackObserverRecord { + public: + /** + * Constructor. + * + * \param o Reference to the UndoStackObserver that this UndoStackObserverRecord + * will track. + */ + UndoStackObserverRecord(UndoStackObserver& o) : to_remove(false), _observer(o) { } + bool to_remove; + + /** + * Overloaded equality test operator to facilitate usage of STL find algorithms. + */ + bool operator==(UndoStackObserverRecord const& _x) const + { + return &(this->_observer) == &(_x._observer); + } + + /** + * Issue a redo event to the UndoStackObserver that is associated with this UndoStackObserverRecord. + * + * \param log The event log generated by the redo event. + */ + void issueRedo(XML::Event* log) + { + this->_observer.notifyRedoEvent(log); + } + + /** + * Issue an undo event to the UndoStackObserver that is associated with this + * UndoStackObserverRecord. + * + * \param log The event log generated by the undo event. + */ + void issueUndo(XML::Event* log) + { + this->_observer.notifyUndoEvent(log); + } + + /** + * Issues a committed event to the UndoStackObserver that is associated with this + * UndoStackObserverRecord. + * + * \param log The event log being committed to the undo stack. + */ + void issueUndoCommit(XML::Event* log) + { + this->_observer.notifyUndoCommitEvent(log); + } + + private: + UndoStackObserver& _observer; + }; + + /// A list of UndoStackObserverRecords, used to aggregate multiple UndoStackObservers. + typedef std::list< UndoStackObserverRecord > UndoObserverRecordList; + + /** + * Constructor. + */ + CompositeUndoStackObserver(); + + ~CompositeUndoStackObserver(); + + /** + * Add an UndoStackObserver. + * + * \param observer Reference to an UndoStackObserver to add. + */ + void add(UndoStackObserver& observer); + + /** + * Remove an UndoStackObserver. + * + * \param observer Reference to an UndoStackObserver to remove. + */ + void remove(UndoStackObserver& observer); + + /** + * Notify all registered UndoStackObservers of an undo event. + * + * \param log The event log generated by the undo event. + */ + void notifyUndoEvent(XML::Event* log); + + /** + * Notify all registered UndoStackObservers of a redo event. + * + * \param log The event log generated by the redo event. + */ + void notifyRedoEvent(XML::Event* log); + + /** + * Notify all registered UndoStackObservers of an event log being committed to the undo stack. + * + * \param log The event log being committed to the undo stack. + */ + void notifyUndoCommitEvent(XML::Event* log); + +private: + // Remove an observer from a given list + bool _remove_one(UndoObserverRecordList& list, UndoStackObserver& rec); + + // Mark an observer for removal from a given list + bool _mark_one(UndoObserverRecordList& list, UndoStackObserver& rec); + + // Keep track of whether or not we are notifying observers + unsigned int _iterating; + + // Observers in the active list + UndoObserverRecordList _active; + + // Observers to be added + UndoObserverRecordList _pending; + + // Prevents the observer vector from modifications during + // iteration through the vector + void _lock() { this->_iterating++; } + void _unlock(); +}; + +} + +#endif diff --git a/src/conn-avoid-ref.cpp b/src/conn-avoid-ref.cpp new file mode 100644 index 000000000..0dbd8c730 --- /dev/null +++ b/src/conn-avoid-ref.cpp @@ -0,0 +1,176 @@ +/* + * A class for handling shape interaction with libavoid. + * + * Authors: + * Michael Wybrow + * + * Copyright (C) 2005 Michael Wybrow + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + + + +#include "sp-item.h" +#include "conn-avoid-ref.h" +#include "libnr/nr-rect-ops.h" +#include "libavoid/polyutil.h" +#include "libavoid/incremental.h" +#include "xml/simple-node.cpp" +#include "document.h" + + +static Avoid::Polygn avoid_item_poly(SPItem const *item); +static void avoid_item_move(NR::Matrix const *mp, SPItem *moved_item); + + +SPAvoidRef::SPAvoidRef(SPItem *spitem) + : shapeRef(NULL) + , item(spitem) + , setting(false) + , new_setting(false) + , _transformed_connection() +{ +} + + +SPAvoidRef::~SPAvoidRef() +{ + _transformed_connection.disconnect(); + if (shapeRef) { + // shapeRef is finalised by delShape, + // so no memory is lost here. + Avoid::delShape(shapeRef); + shapeRef = NULL; + } +} + + +void SPAvoidRef::setAvoid(char const *value) +{ + if (SP_OBJECT_IS_CLONED(item)) { + // Don't keep avoidance information for cloned objects. + return; + } + new_setting = false; + if (value && (strcmp(value, "true") == 0)) { + new_setting = true; + } +} + + +void SPAvoidRef::handleSettingChange(void) +{ + if (new_setting == setting) { + // Don't need to make any changes + return; + } + + _transformed_connection.disconnect(); + if (new_setting) { + _transformed_connection = item->connectTransformed( + sigc::ptr_fun(&avoid_item_move)); + + Avoid::Polygn poly = avoid_item_poly(item); + if (poly.pn > 0) { + const char *id = SP_OBJECT_REPR(item)->attribute("id"); + g_assert(id != NULL); + + // Get a unique ID for the item. + GQuark itemID = g_quark_from_string(id); + + shapeRef = new Avoid::ShapeRef(itemID, poly); + Avoid::freePoly(poly); + + Avoid::addShape(shapeRef); + } + } + else + { + g_assert(shapeRef); + + // shapeRef is finalised by delShape, + // so no memory is lost here. + Avoid::delShape(shapeRef); + shapeRef = NULL; + } + setting = new_setting; +} + + +static Avoid::Polygn avoid_item_poly(SPItem const *item) +{ + Avoid::Polygn poly; + + // TODO: The right way to do this is to return the convex hull of + // the object, or an approximation in the case of a rounded + // object. Specific SPItems will need to have a new + // function that returns points for the convex hull. + // For some objects it is enough to feed the snappoints to + // some convex hull code, though not NR::ConvexHull as this + // only keeps the bounding box of the convex hull currently. + + // TODO: SPItem::invokeBbox gives the wrong result for some objects + // that have internal representations that are updated later + // by the sp_*_update functions, e.g., text. + sp_document_ensure_up_to_date(item->document); + + NR::Rect rHull = item->invokeBbox(sp_item_i2doc_affine(item)); + + // Add a little buffer around the edge of each object. + NR::Rect rExpandedHull = NR::expand(rHull, -10.0); + poly = Avoid::newPoly(4); + + for (unsigned n = 0; n < 4; ++n) { + // TODO: I think the winding order in libavoid or inkscape might + // be backwards, probably due to the inverse y co-ordinates + // used for the screen. The '3 - n' reverses the order. + /* On "correct" winding order: Winding order of NR::Rect::corner is in a positive + * direction, like libart. "Positive direction" means the same as in most of Inkscape and + * SVG: if you visualize y as increasing upwards, as is the convention in mathematics, then + * positive angle is visualized as anticlockwise, as in mathematics; so if you visualize y + * as increasing downwards, as is common outside of mathematics, then positive angle + * direction is visualized as clockwise, as is common outside of mathematics. This + * convention makes it easier mix pure mathematics code with graphics code: the important + * thing when mixing code is that the number values stored in variables (representing y + * coordinate, angle) match up; variables store numbers, not visualized positions, and the + * programmer is free to switch between visualizations when thinking about a given piece of + * code. + * + * MathWorld, libart and NR::Rect::corner all seem to take positive winding (i.e. winding + * that yields +1 winding number inside a simple closed shape) to mean winding in a + * positive angle. This, together with the observation that variables store numbers rather + * than positions, suggests that NR::Rect::corner uses the right direction. + */ + NR::Point hullPoint = rExpandedHull.corner(3 - n); + poly.ps[n].x = hullPoint[NR::X]; + poly.ps[n].y = hullPoint[NR::Y]; + } + + return poly; +} + + +static void avoid_item_move(NR::Matrix const *mp, SPItem *moved_item) +{ + Avoid::ShapeRef *shapeRef = moved_item->avoidRef->shapeRef; + g_assert(shapeRef); + + Avoid::Polygn poly = avoid_item_poly(moved_item); + if (poly.pn > 0) { + // moveShape actually destroys the old shapeRef and returns a new one. + moved_item->avoidRef->shapeRef = Avoid::moveShape(shapeRef, &poly); + Avoid::freePoly(poly); + } +} + +/* + 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 : diff --git a/src/conn-avoid-ref.h b/src/conn-avoid-ref.h new file mode 100644 index 000000000..3b5e6d3b5 --- /dev/null +++ b/src/conn-avoid-ref.h @@ -0,0 +1,57 @@ +#ifndef SEEN_CONN_AVOID_REF +#define SEEN_CONN_AVOID_REF + +/* + * A class for handling shape interaction with libavoid. + * + * Authors: + * Michael Wybrow + * + * Copyright (C) 2005 Michael Wybrow + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + + +#include + +struct SPItem; +namespace Avoid { + class ShapeRef; +} + +class SPAvoidRef { +public: + SPAvoidRef(SPItem *spitem); + ~SPAvoidRef(); + + // libavoid's internal representation of the item. + Avoid::ShapeRef *shapeRef; + + void setAvoid(char const *value); + void handleSettingChange(void); + +private: + SPItem *item; + + // true if avoiding, false if not. + bool setting; + bool new_setting; + + // A sigc connection for transformed signal. + sigc::connection _transformed_connection; +}; + + +#endif /* !SEEN_CONN_AVOID_REF */ + +/* + 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 : diff --git a/src/connector-context.cpp b/src/connector-context.cpp new file mode 100644 index 000000000..34f5ba3ed --- /dev/null +++ b/src/connector-context.cpp @@ -0,0 +1,1350 @@ +/* + * Connector creation tool + * + * Authors: + * Michael Wybrow + * + * Copyright (C) 2005 Michael Wybrow + * + * Released under GNU GPL, read the file 'COPYING' for more information + * + * TODO: + * o Have shapes avoid coonvex hulls of objects, rather than their + * bounding box. Possibly implement the unfinished ConvexHull + * class in libnr. + * (HOWEVER, using the convex hull C of a shape S does the wrong thing if a + * connector starts outside of S but inside C, or if the best route around + * an object involves going inside C but without entering S.) + * o Draw connectors to shape edges rather than bounding box. + * o Show a visual indicator for objects with the 'avoid' property set. + * o Create an interface for setting markers (arrow heads). + * o Better distinguish between paths and connectors to prevent problems + * in the node tool and paths accidently being turned into connectors + * in the connector tool. Perhaps have a way to convert between. + * o Only call libavoid's updateEndPoint as required. Currently we do it + * for both endpoints, even if only one is moving. + * o Cleanup to remove unecessary borrowed DrawContext code. + * o Allow user-placeable connection points. + * o Deal sanely with connectors with both endpoints attached to the + * same connection point, and drawing of connectors attaching + * overlaping shapes (currently tries to adjust connector to be + * outside both bounding boxes). + * o Fix many special cases related to connectors updating, + * e.g., copying a couple of shapes and a connector that are + * attached to each other. + * e.g., detach connector when it is moved or transformed in + * one of the other contexts. + * o Cope with shapes whose ids change when they have attached + * connectors. + * o gobble_motion_events(GDK_BUTTON1_MASK)?; + * + */ + +#include + +#include "connector-context.h" +#include "pixmaps/cursor-connector.xpm" +#include "xml/node-event-vector.h" +#include "xml/repr.h" +#include "svg/svg.h" +#include "desktop.h" +#include "desktop-style.h" +#include "desktop-affine.h" +#include "desktop-handles.h" +#include "document.h" +#include "message-context.h" +#include "message-stack.h" +#include "selection.h" +#include "inkscape.h" +#include "prefs-utils.h" +#include "sp-path.h" +#include "display/canvas-bpath.h" +#include "display/sodipodi-ctrl.h" +#include +#include "snap.h" +#include "knot.h" +#include "sp-conn-end.h" +#include "conn-avoid-ref.h" +#include "libavoid/vertices.h" +#include "context-fns.h" + + + +static void sp_connector_context_class_init(SPConnectorContextClass *klass); +static void sp_connector_context_init(SPConnectorContext *conn_context); +static void sp_connector_context_dispose(GObject *object); + +static void sp_connector_context_setup(SPEventContext *ec); +static void sp_connector_context_finish(SPEventContext *ec); +static gint sp_connector_context_root_handler(SPEventContext *ec, GdkEvent *event); +static gint sp_connector_context_item_handler(SPEventContext *event_context, SPItem *item, GdkEvent *event); + +// Stuff borrowed from DrawContext +static void spcc_connector_set_initial_point(SPConnectorContext *cc, NR::Point const p); +static void spcc_connector_set_subsequent_point(SPConnectorContext *cc, NR::Point const p); +static void spcc_connector_finish_segment(SPConnectorContext *cc, NR::Point p); +static void spcc_reset_colors(SPConnectorContext *cc); +static void spcc_connector_finish(SPConnectorContext *cc); +static void spcc_concat_colors_and_flush(SPConnectorContext *cc); +static void spcc_flush_white(SPConnectorContext *cc, SPCurve *gc); + +// Context event handlers +static gint connector_handle_button_press(SPConnectorContext *const cc, GdkEventButton const &bevent); +static gint connector_handle_motion_notify(SPConnectorContext *const cc, GdkEventMotion const &mevent); +static gint connector_handle_button_release(SPConnectorContext *const cc, GdkEventButton const &revent); +static gint connector_handle_key_press(SPConnectorContext *const cc, guint const keyval); + +static void cc_set_active_shape(SPConnectorContext *cc, SPItem *item); +static void cc_clear_active_shape(SPConnectorContext *cc); +static void cc_set_active_conn(SPConnectorContext *cc, SPItem *item); +static void cc_clear_active_conn(SPConnectorContext *cc); +static gchar *conn_pt_handle_test(SPConnectorContext *cc, NR::Point& w); +static bool cc_item_is_shape(SPItem *item); +static void cc_selection_changed(Inkscape::Selection *selection, gpointer data); + +static void shape_event_attr_deleted(Inkscape::XML::Node *repr, + Inkscape::XML::Node *child, Inkscape::XML::Node *ref, gpointer data); +static void shape_event_attr_changed(Inkscape::XML::Node *repr, gchar const *name, + gchar const *old_value, gchar const *new_value, bool is_interactive, + gpointer data); + + +static NR::Point connector_drag_origin_w(0, 0); +static bool connector_within_tolerance = false; +static SPEventContextClass *parent_class; + + +static Inkscape::XML::NodeEventVector shape_repr_events = { + NULL, /* child_added */ + NULL, /* child_added */ + shape_event_attr_changed, + NULL, /* content_changed */ + NULL /* order_changed */ +}; + +static Inkscape::XML::NodeEventVector layer_repr_events = { + NULL, /* child_added */ + shape_event_attr_deleted, + NULL, /* child_added */ + NULL, /* content_changed */ + NULL /* order_changed */ +}; + + +GType +sp_connector_context_get_type(void) +{ + static GType type = 0; + if (!type) { + GTypeInfo info = { + sizeof(SPConnectorContextClass), + NULL, NULL, + (GClassInitFunc) sp_connector_context_class_init, + NULL, NULL, + sizeof(SPConnectorContext), + 4, + (GInstanceInitFunc) sp_connector_context_init, + NULL, /* value_table */ + }; + type = g_type_register_static(SP_TYPE_EVENT_CONTEXT, "SPConnectorContext", &info, (GTypeFlags)0); + } + return type; +} + +static void +sp_connector_context_class_init(SPConnectorContextClass *klass) +{ + GObjectClass *object_class; + SPEventContextClass *event_context_class; + + object_class = (GObjectClass *) klass; + event_context_class = (SPEventContextClass *) klass; + + parent_class = (SPEventContextClass*)g_type_class_peek_parent(klass); + + object_class->dispose = sp_connector_context_dispose; + + event_context_class->setup = sp_connector_context_setup; + event_context_class->finish = sp_connector_context_finish; + event_context_class->root_handler = sp_connector_context_root_handler; + event_context_class->item_handler = sp_connector_context_item_handler; +} + + +static void +sp_connector_context_init(SPConnectorContext *cc) +{ + SPEventContext *ec = SP_EVENT_CONTEXT(cc); + + ec->cursor_shape = cursor_connector_xpm; + ec->hot_x = 1; + ec->hot_y = 1; + ec->xp = 0; + ec->yp = 0; + + cc->red_color = 0xff00007f; + + cc->newconn = NULL; + cc->newConnRef = NULL; + + cc->sel_changed_connection = sigc::connection(); + + cc->active_shape = NULL; + cc->active_shape_repr = NULL; + cc->active_shape_layer_repr = NULL; + + cc->active_conn = NULL; + cc->active_conn_repr = NULL; + + cc->active_handle = NULL; + + cc->clickeditem = NULL; + cc->clickedhandle = NULL; + + cc->connpthandle = NULL; + for (int i = 0; i < 2; ++i) { + cc->endpt_handle[i] = NULL; + cc->endpt_handler_id[i] = 0; + } + cc->sid = NULL; + cc->eid = NULL; + cc->npoints = 0; + cc->state = SP_CONNECTOR_CONTEXT_IDLE; +} + + +static void +sp_connector_context_dispose(GObject *object) +{ + SPConnectorContext *cc = SP_CONNECTOR_CONTEXT(object); + + cc->sel_changed_connection.disconnect(); + + if (cc->connpthandle) { + g_object_unref(cc->connpthandle); + cc->connpthandle = NULL; + } + for (int i = 0; i < 2; ++i) { + if (cc->endpt_handle[1]) { + g_object_unref(cc->endpt_handle[i]); + cc->endpt_handle[i] = NULL; + } + } + if (cc->sid) { + g_free(cc->sid); + cc->sid = NULL; + } + if (cc->eid) { + g_free(cc->eid); + cc->eid = NULL; + } + g_assert( cc->newConnRef == NULL ); + + G_OBJECT_CLASS(parent_class)->dispose(object); +} + + +static void +sp_connector_context_setup(SPEventContext *ec) +{ + SPConnectorContext *cc = SP_CONNECTOR_CONTEXT(ec); + SPDesktop *dt = ec->desktop; + + if (((SPEventContextClass *) parent_class)->setup) { + ((SPEventContextClass *) parent_class)->setup(ec); + } + + cc->selection = SP_DT_SELECTION(dt); + + cc->sel_changed_connection.disconnect(); + cc->sel_changed_connection = cc->selection->connectChanged( + sigc::bind(sigc::ptr_fun(&cc_selection_changed), + (gpointer) cc)); + + /* Create red bpath */ + cc->red_bpath = sp_canvas_bpath_new(SP_DT_SKETCH(ec->desktop), NULL); + sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(cc->red_bpath), cc->red_color, + 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); + sp_canvas_bpath_set_fill(SP_CANVAS_BPATH(cc->red_bpath), 0x00000000, + SP_WIND_RULE_NONZERO); + /* Create red curve */ + cc->red_curve = sp_curve_new_sized(4); + + /* Create green curve */ + cc->green_curve = sp_curve_new_sized(64); + + // Notice the initial selection. + cc_selection_changed(cc->selection, (gpointer) cc); + + if (prefs_get_int_attribute("tools.connector", "selcue", 0) != 0) { + ec->enableSelectionCue(); + } +} + + +static void +sp_connector_context_finish(SPEventContext *ec) +{ + SPConnectorContext *cc = SP_CONNECTOR_CONTEXT(ec); + + spcc_connector_finish(cc); + + if (((SPEventContextClass *) parent_class)->finish) { + ((SPEventContextClass *) parent_class)->finish(ec); + } + + if (cc->selection) { + cc->selection = NULL; + } + cc_clear_active_shape(cc); + cc_clear_active_conn(cc); +} + + +//----------------------------------------------------------------------------- + + +static void +cc_clear_active_shape(SPConnectorContext *cc) +{ + if (cc->active_shape == NULL) { + return; + } + g_assert( cc->active_shape_repr ); + g_assert( cc->active_shape_layer_repr ); + + cc->active_shape = NULL; + + if (cc->active_shape_repr) { + sp_repr_remove_listener_by_data(cc->active_shape_repr, cc); + Inkscape::GC::release(cc->active_shape_repr); + cc->active_shape_repr = NULL; + + sp_repr_remove_listener_by_data(cc->active_shape_layer_repr, cc); + Inkscape::GC::release(cc->active_shape_layer_repr); + cc->active_shape_layer_repr = NULL; + } + + // Hide the center connection point if it exists. + if (cc->connpthandle) { + sp_knot_hide(cc->connpthandle); + } +} + + +static void +cc_clear_active_conn(SPConnectorContext *cc) +{ + if (cc->active_conn == NULL) { + return; + } + g_assert( cc->active_conn_repr ); + + cc->active_conn = NULL; + + if (cc->active_conn_repr) { + sp_repr_remove_listener_by_data(cc->active_conn_repr, cc); + Inkscape::GC::release(cc->active_conn_repr); + cc->active_conn_repr = NULL; + } + + // Hide the endpoint handles. + for (int i = 0; i < 2; ++i) { + if (cc->endpt_handle[i]) { + sp_knot_hide(cc->endpt_handle[i]); + } + } +} + + +static gchar * +conn_pt_handle_test(SPConnectorContext *cc, NR::Point& p) +{ + // TODO: this will need to change when there are more connection + // points available for each shape. + + SPKnot *centerpt = cc->connpthandle; + if (cc->active_handle && (cc->active_handle == centerpt)) + { + p = centerpt->pos; + return g_strdup_printf("#%s", SP_OBJECT_ID(cc->active_shape)); + } + return NULL; +} + + + +static gint +sp_connector_context_item_handler(SPEventContext *ec, SPItem *item, GdkEvent *event) +{ + gint ret = FALSE; + + SPDesktop *desktop = ec->desktop; + + SPConnectorContext *cc = SP_CONNECTOR_CONTEXT(ec); + + NR::Point p(event->button.x, event->button.y); + + switch (event->type) { + case GDK_BUTTON_RELEASE: + if (event->button.button == 1) { + if ((cc->state == SP_CONNECTOR_CONTEXT_DRAGGING) && + (connector_within_tolerance)) + { + spcc_reset_colors(cc); + cc->state = SP_CONNECTOR_CONTEXT_IDLE; + } + if (cc->state != SP_CONNECTOR_CONTEXT_IDLE) { + // Doing simething else like rerouting. + break; + } + // find out clicked item, disregarding groups, honoring Alt + SPItem *item_ungrouped = sp_event_context_find_item(desktop, + p, event->button.state & GDK_MOD1_MASK, TRUE); + + if (event->button.state & GDK_SHIFT_MASK) { + cc->selection->toggle(item_ungrouped); + } else { + cc->selection->set(item_ungrouped); + } + ret = TRUE; + } + break; + case GDK_ENTER_NOTIFY: + { + if (cc_item_is_shape(item)) { + // This is a shape, so show connection point(s). + if (!(cc->active_shape) || + // Don't show handle for another handle. + (item != ((SPItem *) cc->connpthandle))) { + cc_set_active_shape(cc, item); + } + } + ret = TRUE; + break; + } + default: + break; + } + + return ret; +} + + +gint +sp_connector_context_root_handler(SPEventContext *ec, GdkEvent *event) +{ + SPConnectorContext *const cc = SP_CONNECTOR_CONTEXT(ec); + + gint ret = FALSE; + + switch (event->type) { + case GDK_BUTTON_PRESS: + ret = connector_handle_button_press(cc, event->button); + break; + + case GDK_MOTION_NOTIFY: + ret = connector_handle_motion_notify(cc, event->motion); + break; + + case GDK_BUTTON_RELEASE: + ret = connector_handle_button_release(cc, event->button); + break; + case GDK_KEY_PRESS: + ret = connector_handle_key_press(cc, get_group0_keyval (&event->key)); + break; + + default: + break; + } + + if (!ret) { + gint (*const parent_root_handler)(SPEventContext *, GdkEvent *) + = ((SPEventContextClass *) parent_class)->root_handler; + if (parent_root_handler) { + ret = parent_root_handler(ec, event); + } + } + + return ret; +} + + +static gint +connector_handle_button_press(SPConnectorContext *const cc, GdkEventButton const &bevent) +{ + NR::Point const event_w(bevent.x, bevent.y); + /* Find desktop coordinates */ + NR::Point p = cc->desktop->w2d(event_w); + + gint ret = FALSE; + if ( bevent.button == 1 ) { + + SPDesktop *desktop = SP_EVENT_CONTEXT_DESKTOP(cc); + + if (Inkscape::have_viable_layer(desktop, cc->_message_context) == false) { + return TRUE; + } + + NR::Point const event_w(bevent.x, + bevent.y); + connector_drag_origin_w = event_w; + connector_within_tolerance = true; + + NR::Point const event_dt = cc->desktop->w2d(event_w); + switch (cc->state) { + case SP_CONNECTOR_CONTEXT_STOP: + /* This is allowed, if we just cancelled curve */ + case SP_CONNECTOR_CONTEXT_IDLE: + { + if ( cc->npoints == 0 ) { + /* Set start anchor */ + NR::Point p; + + cc_clear_active_conn(cc); + + SP_EVENT_CONTEXT_DESKTOP(cc)->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Creating new connector")); + + /* Create green anchor */ + p = event_dt; + + // Test whether we clicked on a connection point + cc->sid = conn_pt_handle_test(cc, p); + + if (!cc->sid) { + // This is the first point, so just snap it to the grid + // as there's no other points to go off. + SnapManager const m(cc->desktop->namedview); + p = m.freeSnap(Inkscape::Snapper::SNAP_POINT | Inkscape::Snapper::BBOX_POINT, + p, NULL).getPoint(); + } + spcc_connector_set_initial_point(cc, p); + + } + cc->state = SP_CONNECTOR_CONTEXT_DRAGGING; + ret = TRUE; + break; + } + case SP_CONNECTOR_CONTEXT_DRAGGING: + { + // This is the second click of a connector creation. + + spcc_connector_set_subsequent_point(cc, p); + spcc_connector_finish_segment(cc, p); + // Test whether we clicked on a connection point + cc->eid = conn_pt_handle_test(cc, p); + if (cc->npoints != 0) { + spcc_connector_finish(cc); + } + cc_set_active_conn(cc, cc->newconn); + cc->state = SP_CONNECTOR_CONTEXT_IDLE; + ret = TRUE; + break; + } + case SP_CONNECTOR_CONTEXT_CLOSE: + { + g_warning("Button down in CLOSE state"); + break; + } + default: + break; + } + } else if (bevent.button == 3) { + if (cc->npoints != 0) { + spcc_connector_finish(cc); + ret = TRUE; + } + } + return ret; +} + + +static gint +connector_handle_motion_notify(SPConnectorContext *const cc, GdkEventMotion const &mevent) +{ + gint ret = FALSE; + + if (mevent.state & GDK_BUTTON2_MASK || mevent.state & GDK_BUTTON3_MASK) { + // allow middle-button scrolling + return FALSE; + } + + NR::Point const event_w(mevent.x, mevent.y); + + if (connector_within_tolerance) { + gint const tolerance = prefs_get_int_attribute_limited("options.dragtolerance", + "value", 0, 0, 100); + if ( NR::LInfty( event_w - connector_drag_origin_w ) < tolerance ) { + return FALSE; // Do not drag if we're within tolerance from origin. + } + } + // Once the user has moved farther than tolerance from the original location + // (indicating they intend to move the object, not click), then always process + // the motion notify coordinates as given (no snapping back to origin) + connector_within_tolerance = false; + + SPDesktop *const dt = cc->desktop; + + /* Find desktop coordinates */ + NR::Point p = dt->w2d(event_w); + + switch (cc->state) { + case SP_CONNECTOR_CONTEXT_DRAGGING: + { + // This is movement during a connector creation. + + if ( cc->npoints > 0 ) { + cc->selection->clear(); + spcc_connector_set_subsequent_point(cc, p); + ret = TRUE; + } + break; + } + case SP_CONNECTOR_CONTEXT_REROUTING: + { + g_assert( SP_IS_PATH(cc->clickeditem)); + + // Update the hidden path + NR::Matrix i2d = sp_item_i2d_affine(cc->clickeditem); + NR::Matrix d2i = i2d.inverse(); + SPPath *path = SP_PATH(cc->clickeditem); + SPCurve *curve = (SP_SHAPE(path))->curve; + if (cc->clickedhandle == cc->endpt_handle[0]) { + NR::Point o = cc->endpt_handle[1]->pos; + sp_curve_stretch_endpoints(curve, p * d2i, o * d2i); + } + else { + NR::Point o = cc->endpt_handle[0]->pos; + sp_curve_stretch_endpoints(curve, o * d2i, p * d2i); + } + sp_conn_adjust_path(path); + + // Copy this to the temporary visible path + cc->red_curve = sp_curve_copy(SP_SHAPE(path)->curve); + sp_curve_transform(cc->red_curve, i2d); + + sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(cc->red_bpath), cc->red_curve); + ret = TRUE; + break; + } + case SP_CONNECTOR_CONTEXT_STOP: + /* This is perfectly valid */ + break; + default: + break; + } + + return ret; +} + + +static gint +connector_handle_button_release(SPConnectorContext *const cc, GdkEventButton const &revent) +{ + gint ret = FALSE; + if ( revent.button == 1 ) { + + SPDesktop *desktop = SP_EVENT_CONTEXT_DESKTOP(cc); + SPDocument *doc = SP_DT_DOCUMENT(desktop); + + NR::Point const event_w(revent.x, revent.y); + + /* Find desktop coordinates */ + NR::Point p = cc->desktop->w2d(event_w); + + switch (cc->state) { + //case SP_CONNECTOR_CONTEXT_POINT: + case SP_CONNECTOR_CONTEXT_DRAGGING: + { + if (connector_within_tolerance) + { + spcc_connector_finish_segment(cc, p); + return TRUE; + } + // Connector has been created via a drag, end it now. + spcc_connector_set_subsequent_point(cc, p); + spcc_connector_finish_segment(cc, p); + // Test whether we clicked on a connection point + cc->eid = conn_pt_handle_test(cc, p); + if (cc->npoints != 0) { + spcc_connector_finish(cc); + } + cc_set_active_conn(cc, cc->newconn); + cc->state = SP_CONNECTOR_CONTEXT_IDLE; + break; + } + case SP_CONNECTOR_CONTEXT_REROUTING: + { + // Clear the temporary path: + sp_curve_reset(cc->red_curve); + sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(cc->red_bpath), NULL); + + // Test whether we clicked on a connection point + gchar *shape_label = conn_pt_handle_test(cc, p); + + if (shape_label) { + if (cc->clickedhandle == cc->endpt_handle[0]) { + sp_object_setAttribute(cc->clickeditem, + "inkscape:connection-start",shape_label, false); + } + else { + sp_object_setAttribute(cc->clickeditem, + "inkscape:connection-end",shape_label, false); + } + g_free(shape_label); + } + cc->clickeditem->setHidden(false); + sp_conn_adjust_path(SP_PATH(cc->clickeditem)); + cc->clickeditem->updateRepr(); + sp_document_done(doc); + cc_set_active_conn(cc, cc->clickeditem); + sp_document_ensure_up_to_date(doc); + cc->state = SP_CONNECTOR_CONTEXT_IDLE; + return TRUE; + break; + } + case SP_CONNECTOR_CONTEXT_STOP: + /* This is allowed, if we just cancelled curve */ + break; + default: + break; + } + ret = TRUE; + } + + return ret; +} + + +static gint +connector_handle_key_press(SPConnectorContext *const cc, guint const keyval) +{ + gint ret = FALSE; + /* fixme: */ + switch (keyval) { + case GDK_Return: + case GDK_KP_Enter: + if (cc->npoints != 0) { + spcc_connector_finish(cc); + ret = TRUE; + } + break; + case GDK_Escape: + if (cc->npoints != 0) { + // if drawing, cancel, otherwise pass it up for deselecting + cc->state = SP_CONNECTOR_CONTEXT_STOP; + spcc_reset_colors(cc); + ret = TRUE; + } + break; + default: + break; + } + return ret; +} + + +static void +spcc_reset_colors(SPConnectorContext *cc) +{ + /* Red */ + sp_curve_reset(cc->red_curve); + sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(cc->red_bpath), NULL); + + sp_curve_reset(cc->green_curve); + cc->npoints = 0; +} + + +static void +spcc_connector_set_initial_point(SPConnectorContext *const cc, NR::Point const p) +{ + g_assert( cc->npoints == 0 ); + + cc->p[0] = p; + cc->p[1] = p; + cc->npoints = 2; + sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(cc->red_bpath), NULL); +} + + +static void +spcc_connector_set_subsequent_point(SPConnectorContext *const cc, NR::Point const p) +{ + g_assert( cc->npoints != 0 ); + + SPDesktop *dt = cc->desktop; + NR::Point o = dt->dt2doc(cc->p[0]); + NR::Point d = dt->dt2doc(p); + Avoid::Point src = { o[NR::X], o[NR::Y] }; + Avoid::Point dst = { d[NR::X], d[NR::Y] }; + + if (!cc->newConnRef) { + cc->newConnRef = new Avoid::ConnRef(0, src, dst); + cc->newConnRef->updateEndPoint(Avoid::VertID::src, src); + } + cc->newConnRef->updateEndPoint(Avoid::VertID::tar, dst); + + cc->newConnRef->makePathInvalid(); + cc->newConnRef->generatePath(src, dst); + + Avoid::PolyLine route = cc->newConnRef->route(); + cc->newConnRef->calcRouteDist(); + + sp_curve_reset(cc->red_curve); + NR::Point pt(route.ps[0].x, route.ps[0].y); + sp_curve_moveto(cc->red_curve, pt); + + for (int i = 1; i < route.pn; ++i) { + NR::Point p(route.ps[i].x, route.ps[i].y); + sp_curve_lineto(cc->red_curve, p); + } + sp_curve_transform(cc->red_curve, dt->doc2dt()); + sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(cc->red_bpath), cc->red_curve); +} + + +/** + * Concats red, blue and green. + * If any anchors are defined, process these, optionally removing curves from white list + * Invoke _flush_white to write result back to object. + */ +static void +spcc_concat_colors_and_flush(SPConnectorContext *cc) +{ + SPCurve *c = cc->green_curve; + cc->green_curve = sp_curve_new_sized(64); + + sp_curve_reset(cc->red_curve); + sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(cc->red_bpath), NULL); + + if (sp_curve_empty(c)) { + sp_curve_unref(c); + return; + } + + spcc_flush_white(cc, c); + + sp_curve_unref(c); +} + + +/* + * Flushes white curve(s) and additional curve into object + * + * No cleaning of colored curves - this has to be done by caller + * No rereading of white data, so if you cannot rely on ::modified, do it in caller + * + */ + +static void +spcc_flush_white(SPConnectorContext *cc, SPCurve *gc) +{ + SPCurve *c; + + if (gc) { + c = gc; + sp_curve_ref(c); + } else { + return; + } + + /* Now we have to go back to item coordinates at last */ + sp_curve_transform(c, + sp_desktop_dt2root_affine(SP_EVENT_CONTEXT_DESKTOP(cc))); + + SPDesktop *desktop = SP_EVENT_CONTEXT_DESKTOP(cc); + SPDocument *doc = SP_DT_DOCUMENT(desktop); + + if ( c && !sp_curve_empty(c) ) { + /* We actually have something to write */ + + Inkscape::XML::Node *repr = sp_repr_new("svg:path"); + /* Set style */ + sp_desktop_apply_style_tool(desktop, repr, "tools.connector", false); + + gchar *str = sp_svg_write_path(SP_CURVE_BPATH(c)); + g_assert( str != NULL ); + repr->setAttribute("d", str); + g_free(str); + + /* Attach repr */ + cc->newconn = SP_ITEM(desktop->currentLayer()->appendChildRepr(repr)); + cc->selection->set(repr); + Inkscape::GC::release(repr); + cc->newconn->transform = i2i_affine(desktop->currentRoot(), desktop->currentLayer()); + cc->newconn->updateRepr(); + + bool connection = false; + sp_object_setAttribute(cc->newconn, "inkscape:connector-type", + "polyline", false); + if (cc->sid) + { + sp_object_setAttribute(cc->newconn, "inkscape:connection-start", + cc->sid, false); + connection = true; + } + + if (cc->eid) + { + sp_object_setAttribute(cc->newconn, "inkscape:connection-end", + cc->eid, false); + connection = true; + } + cc->newconn->updateRepr(); + if (connection) { + // Adjust endpoints to shape edge. + sp_conn_adjust_path(SP_PATH(cc->newconn)); + } + cc->newconn->updateRepr(); + } + + sp_curve_unref(c); + + /* Flush pending updates */ + sp_document_done(doc); + sp_document_ensure_up_to_date(doc); +} + + +static void +spcc_connector_finish_segment(SPConnectorContext *const cc, NR::Point const p) +{ + if (!sp_curve_empty(cc->red_curve)) { + sp_curve_append_continuous(cc->green_curve, cc->red_curve, 0.0625); + + cc->p[0] = cc->p[3]; + cc->p[1] = cc->p[4]; + cc->npoints = 2; + + sp_curve_reset(cc->red_curve); + } +} + + +static void +spcc_connector_finish(SPConnectorContext *const cc) +{ + SPDesktop *const desktop = cc->desktop; + desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Finishing connector")); + + sp_curve_reset(cc->red_curve); + spcc_concat_colors_and_flush(cc); + + cc->npoints = 0; + + if (cc->newConnRef) { + cc->newConnRef->removeFromGraph(); + delete cc->newConnRef; + cc->newConnRef = NULL; + } + cc->state = SP_CONNECTOR_CONTEXT_IDLE; +} + + +static gboolean +cc_generic_knot_handler(SPCanvasItem *, GdkEvent *event, SPKnot *knot) +{ + g_assert (knot != NULL); + + SPConnectorContext *cc = SP_CONNECTOR_CONTEXT( + knot->desktop->event_context); + + gboolean consumed = FALSE; + + switch (event->type) { + case GDK_ENTER_NOTIFY: + gtk_object_set (GTK_OBJECT (knot->item), "fill_color", + knot->fill [SP_KNOT_STATE_MOUSEOVER], NULL); + gtk_object_set (GTK_OBJECT (knot->item), "stroke_color", + knot->stroke [SP_KNOT_STATE_MOUSEOVER], NULL); + + cc->active_handle = knot; + + if (knot->tip) + { + knot->desktop->event_context->defaultMessageContext()->set( + Inkscape::NORMAL_MESSAGE, knot->tip); + } + + consumed = TRUE; + break; + case GDK_LEAVE_NOTIFY: + gtk_object_set (GTK_OBJECT (knot->item), "fill_color", + knot->fill [SP_KNOT_STATE_NORMAL], NULL); + gtk_object_set (GTK_OBJECT (knot->item), "stroke_color", + knot->stroke [SP_KNOT_STATE_NORMAL], NULL); + + cc->active_handle = NULL; + + if (knot->tip) { + knot->desktop->event_context->defaultMessageContext()->clear(); + } + + consumed = TRUE; + break; + default: + break; + } + + return consumed; +} + + +static gboolean +endpt_handler(SPKnot *knot, GdkEvent *event, SPConnectorContext *cc) +{ + g_assert( SP_IS_CONNECTOR_CONTEXT(cc) ); + + gboolean consumed = FALSE; + + switch (event->type) { + case GDK_BUTTON_PRESS: + g_assert( (cc->active_handle == cc->endpt_handle[0]) || + (cc->active_handle == cc->endpt_handle[1]) ); + if (cc->state == SP_CONNECTOR_CONTEXT_IDLE) { + cc->clickeditem = cc->active_conn; + cc->clickedhandle = cc->active_handle; + cc_clear_active_conn(cc); + cc->state = SP_CONNECTOR_CONTEXT_REROUTING; + + // Disconnect from attached shape + unsigned ind = (cc->active_handle == cc->endpt_handle[0]) ? 0 : 1; + sp_conn_end_detach(cc->clickeditem, ind); + + NR::Point origin; + if (cc->clickedhandle == cc->endpt_handle[0]) { + origin = cc->endpt_handle[1]->pos; + } + else { + origin = cc->endpt_handle[0]->pos; + } + + // Show the red path for dragging. + cc->red_curve = sp_curve_copy(SP_PATH(cc->clickeditem)->curve); + NR::Matrix i2d = sp_item_i2d_affine(cc->clickeditem); + sp_curve_transform(cc->red_curve, i2d); + sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(cc->red_bpath), + cc->red_curve); + + cc->clickeditem->setHidden(true); + + // The rest of the interaction rerouting the connector is + // handled by the context root handler. + consumed = TRUE; + } + break; + default: + break; + } + + return consumed; +} + + +static void cc_set_active_shape(SPConnectorContext *cc, SPItem *item) +{ + g_assert(item != NULL ); + + cc->active_shape = item; + + // Remove existing active shape listeners + if (cc->active_shape_repr) { + sp_repr_remove_listener_by_data(cc->active_shape_repr, cc); + Inkscape::GC::release(cc->active_shape_repr); + + sp_repr_remove_listener_by_data(cc->active_shape_layer_repr, cc); + Inkscape::GC::release(cc->active_shape_layer_repr); + } + + // Listen in case the active shape changes + cc->active_shape_repr = SP_OBJECT_REPR(item); + if (cc->active_shape_repr) { + Inkscape::GC::anchor(cc->active_shape_repr); + sp_repr_add_listener(cc->active_shape_repr, &shape_repr_events, cc); + + cc->active_shape_layer_repr = cc->active_shape_repr->parent(); + Inkscape::GC::anchor(cc->active_shape_layer_repr); + sp_repr_add_listener(cc->active_shape_layer_repr, &layer_repr_events, cc); + } + + + // Set center connection point. + if ( cc->connpthandle == NULL ) { + SPKnot * knot = (SPKnot*)g_object_new (SP_TYPE_KNOT, 0); + + knot->desktop = cc->desktop; + knot->flags = SP_KNOT_VISIBLE; + + knot->item = sp_canvas_item_new (SP_DT_CONTROLS(cc->desktop), + SP_TYPE_CTRL, + "anchor", GTK_ANCHOR_CENTER, + "filled", TRUE, + "stroked", TRUE, + "mode", SP_KNOT_MODE_XOR, + NULL); + + gtk_signal_connect (GTK_OBJECT (knot->item), "event", + GTK_SIGNAL_FUNC (cc_generic_knot_handler), knot); + + knot->fill [SP_KNOT_STATE_NORMAL] = 0xffffff00; + knot->fill [SP_KNOT_STATE_MOUSEOVER] = 0xff0000ff; + knot->stroke [SP_KNOT_STATE_NORMAL] = 0x01000000; + + g_object_set(G_OBJECT(knot), + "shape", SP_KNOT_SHAPE_SQUARE, + "size", 8, + "anchor", GTK_ANCHOR_CENTER, + "tip", _("Connection point: click or drag to create a new connector"), + NULL); + + cc->connpthandle = knot; + } + + + NR::Rect bbox = sp_item_bbox_desktop(cc->active_shape); + NR::Point center = bbox.midpoint(); + sp_knot_set_position(cc->connpthandle, ¢er, 0); + + sp_knot_show(cc->connpthandle); + +} + + +static void +cc_set_active_conn(SPConnectorContext *cc, SPItem *item) +{ + g_assert( SP_IS_PATH(item) ); + + SPCurve *curve = SP_SHAPE(SP_PATH(item))->curve; + NR::Matrix i2d = sp_item_i2d_affine(item); + + if (cc->active_conn == item) + { + // Just adjust handle positions. + NR::Point startpt = sp_curve_first_point(curve) * i2d; + sp_knot_set_position(cc->endpt_handle[0], &startpt, 0); + + NR::Point endpt = sp_curve_last_point(curve) * i2d; + sp_knot_set_position(cc->endpt_handle[1], &endpt, 0); + + return; + } + + cc->active_conn = item; + + // Remove existing active conn listeners + if (cc->active_conn_repr) { + sp_repr_remove_listener_by_data(cc->active_conn_repr, cc); + Inkscape::GC::release(cc->active_conn_repr); + cc->active_conn_repr = NULL; + } + + // Listen in case the active conn changes + cc->active_conn_repr = SP_OBJECT_REPR(item); + if (cc->active_conn_repr) { + Inkscape::GC::anchor(cc->active_conn_repr); + sp_repr_add_listener(cc->active_conn_repr, &shape_repr_events, cc); + } + + for (int i = 0; i < 2; ++i) { + + // Create the handle if it doesn't exist + if ( cc->endpt_handle[i] == NULL ) { + SPKnot * knot = (SPKnot*) g_object_new (SP_TYPE_KNOT, 0); + + knot->desktop = cc->desktop; + knot->flags = SP_KNOT_VISIBLE; + + knot->item = sp_canvas_item_new (SP_DT_CONTROLS (cc->desktop), + SP_TYPE_CTRL, + "anchor", GTK_ANCHOR_CENTER, + "filled", TRUE, + "stroked", TRUE, + "mode", SP_KNOT_MODE_XOR, + NULL); + + knot->fill [SP_KNOT_STATE_NORMAL] = 0xffffff00; + knot->stroke [SP_KNOT_STATE_NORMAL] = 0x000000ff; + knot->stroke [SP_KNOT_STATE_DRAGGING] = 0x000000ff; + knot->stroke [SP_KNOT_STATE_MOUSEOVER] = 0x000000ff; + + g_object_set(G_OBJECT(knot), + "shape", SP_KNOT_SHAPE_DIAMOND, + "size", 10, + "tip", _("Connector endpoint: drag to reroute or connect to new shapes"), + NULL); + + gtk_signal_connect (GTK_OBJECT (knot->item), "event", + GTK_SIGNAL_FUNC (cc_generic_knot_handler), knot); + + cc->endpt_handle[i] = knot; + } + + // Remove any existing handlers + if (cc->endpt_handler_id[i]) { + g_signal_handlers_disconnect_by_func( + G_OBJECT(cc->endpt_handle[i]->item), + (void*)G_CALLBACK(endpt_handler), (gpointer) cc ); + cc->endpt_handler_id[i] = 0; + } + + // Setup handlers for connector endpoints, this is + // is as 'after' so that cc_generic_knot_handler is + // triggered first for any endpoint. + cc->endpt_handler_id[i] = g_signal_connect_after( + G_OBJECT(cc->endpt_handle[i]->item), "event", + G_CALLBACK(endpt_handler), cc); + } + + NR::Point startpt = sp_curve_first_point(curve) * i2d; + sp_knot_set_position(cc->endpt_handle[0], &startpt, 0); + + NR::Point endpt = sp_curve_last_point(curve) * i2d; + sp_knot_set_position(cc->endpt_handle[1], &endpt, 0); + + sp_knot_show(cc->endpt_handle[0]); + sp_knot_show(cc->endpt_handle[1]); +} + + +static bool cc_item_is_shape(SPItem *item) +{ + if (SP_IS_PATH(item)) { + SPCurve *curve = (SP_SHAPE(item))->curve; + if ( curve && !(curve->closed) ) { + // Open paths are connectors. + return false; + } + } + return true; +} + + +bool cc_item_is_connector(SPItem *item) +{ + if (SP_IS_PATH(item)) { + if (SP_PATH(item)->connEndPair.isAutoRoutingConn()) { + g_assert( !(SP_SHAPE(item)->curve->closed) ); + return true; + } + } + return false; +} + + +void cc_selection_set_avoid(bool const set_avoid) +{ + SPDesktop *desktop = inkscape_active_desktop(); + if (desktop == NULL) { + return; + } + + SPDocument *document = SP_DT_DOCUMENT(desktop); + + Inkscape::Selection *selection = SP_DT_SELECTION(desktop); + + GSList *l = (GSList *) selection->itemList(); + + int changes = 0; + + while (l) { + SPItem *item = (SPItem *) l->data; + + char const *value = (set_avoid) ? "true" : NULL; + + if (cc_item_is_shape(item)) { + sp_object_setAttribute(item, "inkscape:connector-avoid", + value, false); + item->avoidRef->handleSettingChange(); + changes++; + } + + l = l->next; + } + + if (changes == 0) { + desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, + _("Select at least one non-connector object.")); + return; + } + + sp_document_done(document); +} + + +static void +cc_selection_changed(Inkscape::Selection *selection, gpointer data) +{ + SPConnectorContext *cc = SP_CONNECTOR_CONTEXT(data); + //SPEventContext *ec = SP_EVENT_CONTEXT(cc); + + SPItem *item = selection->singleItem(); + + if (cc->active_conn == item) + { + // Noting to change. + return; + } + if (item == NULL) + { + cc_clear_active_conn(cc); + return; + } + + if (cc_item_is_connector(item)) { + cc_set_active_conn(cc, item); + } +} + + +static void +shape_event_attr_deleted(Inkscape::XML::Node *repr, Inkscape::XML::Node *child, + Inkscape::XML::Node *ref, gpointer data) +{ + g_assert(data); + SPConnectorContext *cc = SP_CONNECTOR_CONTEXT(data); + + if (child == cc->active_shape_repr) { + // The active shape has been deleted. Clear active shape. + cc_clear_active_shape(cc); + } +} + + +static void +shape_event_attr_changed(Inkscape::XML::Node *repr, gchar const *name, + gchar const *old_value, gchar const *new_value, + bool is_interactive, gpointer data) +{ + g_assert(data); + SPConnectorContext *cc = SP_CONNECTOR_CONTEXT(data); + + // Look for changes than result in onscreen movement. + if (!strcmp(name, "d") || !strcmp(name, "x") || !strcmp(name, "y") || + !strcmp(name, "width") || !strcmp(name, "height") || + !strcmp(name, "transform")) + { + if (repr == cc->active_shape_repr) { + // Active shape has moved. Clear active shape. + cc_clear_active_shape(cc); + } + else if (repr == cc->active_conn_repr) { + // The active conn has been moved. + // Set it again, which just sets new handle positions. + cc_set_active_conn(cc, cc->active_conn); + } + } +} + + +/* + 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:textwidth=99 : diff --git a/src/connector-context.h b/src/connector-context.h new file mode 100644 index 000000000..49c4c2a81 --- /dev/null +++ b/src/connector-context.h @@ -0,0 +1,112 @@ +#ifndef SEEN_CONNECTOR_CONTEXT_H +#define SEEN_CONNECTOR_CONTEXT_H + +/* + * Connector creation tool + * + * Authors: + * Michael Wybrow + * + * Copyright (C) 2005 Michael Wybrow + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include +#include +#include "display/curve.h" +#include "event-context.h" +#include +#include +#include +#include "libavoid/connector.h" + + +#define SP_TYPE_CONNECTOR_CONTEXT (sp_connector_context_get_type()) +#define SP_CONNECTOR_CONTEXT(o) (G_TYPE_CHECK_INSTANCE_CAST((o), SP_TYPE_CONNECTOR_CONTEXT, SPConnectorContext)) +#define SP_CONNECTOR_CONTEXT_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), SP_TYPE_CONNECTOR_CONTEXT, SPConnectorContextClass)) +#define SP_IS_CONNECTOR_CONTEXT(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), SP_TYPE_CONNECTOR_CONTEXT)) +#define SP_IS_CONNECTOR_CONTEXT_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE((k), SP_TYPE_CONNECTOR_CONTEXT)) + +struct SPKnot; +namespace Inkscape +{ + class Selection; +} + +enum { + SP_CONNECTOR_CONTEXT_IDLE, + SP_CONNECTOR_CONTEXT_DRAGGING, + SP_CONNECTOR_CONTEXT_CLOSE, + SP_CONNECTOR_CONTEXT_STOP, + SP_CONNECTOR_CONTEXT_REROUTING +}; + + +struct SPConnectorContext : public SPEventContext { + Inkscape::Selection *selection; + NR::Point p[5]; + + /** \invar npoints in {0, 2}. */ + gint npoints; + + unsigned int mode : 1; + unsigned int state : 4; + + // Red curve + SPCanvasItem *red_bpath; + SPCurve *red_curve; + guint32 red_color; + + // Green curve + SPCurve *green_curve; + + // The new connector + SPItem *newconn; + Avoid::ConnRef *newConnRef; + + // The active shape + SPItem *active_shape; + Inkscape::XML::Node *active_shape_repr; + Inkscape::XML::Node *active_shape_layer_repr; + + // Same as above, but for the active connector + SPItem *active_conn; + Inkscape::XML::Node *active_conn_repr; + sigc::connection sel_changed_connection; + + + // The activehandle + SPKnot *active_handle; + + SPItem *clickeditem; + SPKnot *clickedhandle; + + SPKnot *connpthandle; + SPKnot *endpt_handle[2]; + guint endpt_handler_id[2]; + gchar *sid; + gchar *eid; + SPCanvasItem *c0, *c1, *cl0, *cl1; +}; + +struct SPConnectorContextClass : public SPEventContextClass { }; + +GType sp_connector_context_get_type(); + +void cc_selection_set_avoid(bool const set_ignore); +bool cc_item_is_connector(SPItem *item); + + +#endif /* !SEEN_CONNECTOR_CONTEXT_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:encoding=utf-8:textwidth=99 : diff --git a/src/context-fns.cpp b/src/context-fns.cpp new file mode 100644 index 000000000..42100d49a --- /dev/null +++ b/src/context-fns.cpp @@ -0,0 +1,192 @@ +#include +#include "sp-item.h" +#include "desktop.h" +#include "message-context.h" +#include "message-stack.h" +#include "context-fns.h" +#include "snap.h" +#include "desktop-affine.h" +#include "event-context.h" + +/* FIXME: could probably use a template here */ + +/** + * Check to see if the current layer is both unhidden and unlocked. If not, + * set a message about it on the given context. + * + * \param desktop Desktop. + * \param message Message context to put messages on. + * \return true if the current layer is both unhidden and unlocked, otherwise false. + */ + +bool Inkscape::have_viable_layer(SPDesktop *desktop, MessageContext *message) +{ + SPItem const *layer = SP_ITEM(desktop->currentLayer()); + + if ( !layer || desktop->itemIsHidden(layer) ) { + message->flash(Inkscape::ERROR_MESSAGE, + _("Current layer is hidden. Unhide it to be able to draw on it.")); + return false; + } + + if ( !layer || layer->isLocked() ) { + message->flash(Inkscape::ERROR_MESSAGE, + _("Current layer is locked. Unlock it to be able to draw on it.")); + return false; + } + + return true; +} + + +/** + * Check to see if the current layer is both unhidden and unlocked. If not, + * set a message about it on the given context. + * + * \param desktop Desktop. + * \param message Message context to put messages on. + * \return true if the current layer is both unhidden and unlocked, otherwise false. + */ + +bool Inkscape::have_viable_layer(SPDesktop *desktop, MessageStack *message) +{ + SPItem const *layer = SP_ITEM(desktop->currentLayer()); + + if ( !layer || desktop->itemIsHidden(layer) ) { + message->flash(Inkscape::WARNING_MESSAGE, + _("Current layer is hidden. Unhide it to be able to draw on it.")); + return false; + } + + if ( !layer || layer->isLocked() ) { + message->flash(Inkscape::WARNING_MESSAGE, + _("Current layer is locked. Unlock it to be able to draw on it.")); + return false; + } + + return true; +} + + +NR::Rect Inkscape::snap_rectangular_box(SPDesktop const *desktop, SPItem *item, + NR::Point const &pt, NR::Point const ¢er, int state) +{ + NR::Point p[2]; + + bool const shift = state & GDK_SHIFT_MASK; + bool const control = state & GDK_CONTROL_MASK; + + SnapManager const m(desktop->namedview); + + if (control) { + + /* Control is down: we are constrained to producing integer-ratio rectangles */ + + /* Vector from the centre of the box to the point we are dragging to */ + NR::Point delta = pt - center; + + /* Round it so that we have an integer-ratio box */ + if (fabs(delta[NR::X]) > fabs(delta[NR::Y]) && (delta[NR::Y] != 0.0)) { + delta[NR::X] = floor(delta[NR::X] / delta[NR::Y] + 0.5) * delta[NR::Y]; + } else if (delta[NR::X] != 0.0) { + delta[NR::Y] = floor(delta[NR::Y] / delta[NR::X] + 0.5) * delta[NR::X]; + } + + /* p[1] is the dragged point with the integer-ratio constraint */ + p[1] = center + delta; + + if (shift) { + + /* Shift is down, so our origin is the centre point rather than the corner + ** point; this means that corner-point movements are bound to each other. + */ + + /* p[0] is the opposite corner of our box */ + p[0] = center - delta; + + Inkscape::SnappedPoint s[2]; + + /* Try to snap p[0] (the opposite corner) along the constraint vector */ + s[0] = m.constrainedSnap(Inkscape::Snapper::SNAP_POINT, + p[0], p[0] - p[1], item); + + /* Try to snap p[1] (the dragged corner) along the constraint vector */ + s[1] = m.constrainedSnap(Inkscape::Snapper::SNAP_POINT, + p[1], p[1] - p[0], item); + + /* Choose the best snap and update points accordingly */ + if (s[0].getDistance() < s[1].getDistance()) { + p[0] = s[0].getPoint(); + p[1] = 2 * center - s[0].getPoint(); + } else { + p[0] = 2 * center - s[1].getPoint(); + p[1] = s[1].getPoint(); + } + + } else { + + /* Our origin is the opposite corner. Snap the drag point along the constraint vector */ + p[0] = center; + p[1] = m.constrainedSnap(Inkscape::Snapper::SNAP_POINT, p[1], p[1] - p[0], item).getPoint(); + } + + } else if (shift) { + + /* Shift is down, so our origin is the centre point rather than the corner point; + ** this means that corner-point movements are bound to each other. + */ + + p[1] = pt; + p[0] = 2 * center - p[1]; + + Inkscape::SnappedPoint s[2]; + + s[0] = m.freeSnap(Inkscape::Snapper::SNAP_POINT, p[0], item); + s[1] = m.freeSnap(Inkscape::Snapper::SNAP_POINT, p[1], item); + + if (s[0].getDistance() < s[1].getDistance()) { + p[0] = s[0].getPoint(); + p[1] = 2 * center - s[0].getPoint(); + } else { + p[0] = 2 * center - s[1].getPoint(); + p[1] = s[1].getPoint(); + } + + } else { + + /* There's no constraint on the corner point, so just snap it to anything */ + p[0] = center; + p[1] = m.freeSnap(Inkscape::Snapper::SNAP_POINT, pt, item).getPoint(); + } + + p[0] = sp_desktop_dt2root_xy_point(desktop, p[0]); + p[1] = sp_desktop_dt2root_xy_point(desktop, p[1]); + + return NR::Rect(NR::Point(MIN(p[0][NR::X], p[1][NR::X]), MIN(p[0][NR::Y], p[1][NR::Y])), + NR::Point(MAX(p[0][NR::X], p[1][NR::X]), MAX(p[0][NR::Y], p[1][NR::Y]))); +} + + + +NR::Point Inkscape::setup_for_drag_start(SPDesktop *desktop, SPEventContext* ec, GdkEvent *ev) +{ + ec->xp = static_cast(ev->button.x); + ec->yp = static_cast(ev->button.y); + ec->within_tolerance = true; + + NR::Point const p(ev->button.x, ev->button.y); + ec->item_to_select = sp_event_context_find_item(desktop, p, ev->button.state & GDK_MOD1_MASK, TRUE); + return ec->desktop->w2d(p); +} + + +/* + 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:textwidth=99 : diff --git a/src/context-fns.h b/src/context-fns.h new file mode 100644 index 000000000..beb132ca9 --- /dev/null +++ b/src/context-fns.h @@ -0,0 +1,27 @@ +#include +struct SPDesktop; + +namespace Inkscape +{ + +class MessageContext; +class MessageStack; + +extern bool have_viable_layer(SPDesktop *desktop, MessageContext *message); +extern bool have_viable_layer(SPDesktop *desktop, MessageStack *message); +NR::Rect snap_rectangular_box(SPDesktop const *desktop, SPItem *item, + NR::Point const &pt, NR::Point const ¢er, int state); +NR::Point setup_for_drag_start(SPDesktop *desktop, SPEventContext* ec, GdkEvent *ev); + +} + +/* + 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:textwidth=99 : diff --git a/src/debug/.cvsignore b/src/debug/.cvsignore new file mode 100644 index 000000000..38efca7bc --- /dev/null +++ b/src/debug/.cvsignore @@ -0,0 +1,3 @@ +.deps +.dirstamp +makefile diff --git a/src/debug/Makefile_insert b/src/debug/Makefile_insert new file mode 100644 index 000000000..ec4e0ceea --- /dev/null +++ b/src/debug/Makefile_insert @@ -0,0 +1,15 @@ + +debug/all: debug/libinkdebug.a + +debug/clean: + rm -f debug/libinkdebug.a $(debug_libinkdebug_a_OBJECTS) + +debug_libinkdebug_a_SOURCES = \ + debug/event.h \ + debug/event-tracker.h \ + debug/heap.cpp debug/heap.h \ + debug/gc-heap.h \ + debug/logger.cpp debug/logger.h \ + debug/simple-event.h \ + debug/sysv-heap.cpp debug/sysv-heap.h + diff --git a/src/debug/event-tracker.h b/src/debug/event-tracker.h new file mode 100644 index 000000000..362175f94 --- /dev/null +++ b/src/debug/event-tracker.h @@ -0,0 +1,224 @@ +/* + * Inkscape::Debug::EventTracker - semi-automatically track event lifetimes + * + * Authors: + * MenTaLguY + * + * Copyright (C) 2005 MenTaLguY + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifndef SEEN_INKSCAPE_DEBUG_EVENT_TRACKER_H +#define SEEN_INKSCAPE_DEBUG_EVENT_TRACKER_H + +#include "debug/logger.h" + +namespace Inkscape { + +namespace Debug { + +struct NoInitialEvent {}; + +template class EventTracker; + +class EventTrackerBase { +public: + ~EventTrackerBase() { + if (_active) { + Logger::finish(); + } + } + + template + inline void set() { + if (_active) { + Logger::finish(); + } + Logger::start(); + _active = true; + } + + template + inline void set(A const &a) { + if (_active) { + Logger::finish(); + } + Logger::start(a); + _active = true; + } + + template + inline void set(A const &a, B const &b) { + if (_active) { + Logger::finish(); + } + Logger::start(a, b); + _active = true; + } + + template + inline void set(A const &a, B const &b, C const &c) { + if (_active) { + Logger::finish(); + } + Logger::start(a, b, c); + _active = true; + } + + template + inline void set(A const &a, B const &b, C const &c, D const &d) { + if (_active) { + Logger::finish(); + } + Logger::start(a, b, c, d); + _active = true; + } + + template + inline void set(A const &a, B const &b, C const &c, D const &d, E const &e) + { + if (_active) { + Logger::finish(); + } + Logger::start(a, b, c, d, e); + _active = true; + } + + template + inline void set(A const &a, B const &b, C const &c, + D const &d, E const &e, F const &f) + { + if (_active) { + Logger::finish(); + } + Logger::start(a, b, c, d, e, f); + _active = true; + } + + template + inline void set(A const &a, B const &b, C const &c, D const &d, + E const &e, F const &f, G const &g) + { + if (_active) { + Logger::finish(); + } + Logger::start(a, b, c, d, e, f, g); + _active = true; + } + + template + inline void set(A const &a, B const &b, C const &c, D const &d, + E const &e, F const &f, G const &g, H const &h) + { + if (_active) { + Logger::finish(); + } + Logger::start(a, b, c, d, e, f, g, h); + _active = true; + } + + void clear() { + if (_active) { + Logger::finish(); + _active = false; + } + } + +protected: + EventTrackerBase(bool active) : _active(active) {} + +private: + EventTrackerBase(EventTrackerBase const &); // no copy + void operator=(EventTrackerBase const &); // no assign + bool _active; +}; + +template class EventTracker : public EventTrackerBase { +public: + EventTracker() : EventTrackerBase(true) { Logger::start(); } + + template + EventTracker(A const &a) : EventTrackerBase(true) { + Logger::start(a); + } + + template + EventTracker(A const &a, B const &b) : EventTrackerBase(true) { + Logger::start(a, b); + } + + template + EventTracker(A const &a, B const &b, C const &c) : EventTrackerBase(true) { + Logger::start(a, b, c); + } + + template + EventTracker(A const &a, B const &b, C const &c, D const &d) + : EventTrackerBase(true) + { + Logger::start(a, b, c, d); + } + + template + EventTracker(A const &a, B const &b, C const &c, D const &d, E const &e) + : EventTrackerBase(true) + { + Logger::start(a, b, c, d, e); + } + + template + EventTracker(A const &a, B const &b, C const &c, D const &d, + E const &e, F const &f) + : EventTrackerBase(true) + { + Logger::start(a, b, c, d, e, f); + } + + template + EventTracker(A const &a, B const &b, C const &c, D const &d, + E const &e, F const &f, G const &g) + : EventTrackerBase(true) + { + Logger::start(a, b, c, d, e, f, g); + } + + template + EventTracker(A const &a, B const &b, C const &c, D const &d, + E const &e, F const &f, G const &g, H const &h) + : EventTrackerBase(true) + { + Logger::start(a, b, c, d, e, f, g, h); + } +}; + +template <> class EventTracker : public EventTrackerBase { +public: + EventTracker() : EventTrackerBase(false) {} +}; + +} + +} + +#endif +/* + 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:textwidth=99 : diff --git a/src/debug/event.h b/src/debug/event.h new file mode 100644 index 000000000..c3b3a83fb --- /dev/null +++ b/src/debug/event.h @@ -0,0 +1,75 @@ +/* + * Inkscape::Debug::Event - event for debug tracing + * + * Authors: + * MenTaLguY + * + * Copyright (C) 2005 MenTaLguY + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifndef SEEN_INKSCAPE_DEBUG_EVENT_H +#define SEEN_INKSCAPE_DEBUG_EVENT_H + +#include +#include "util/shared-c-string-ptr.h" + +namespace Inkscape { + +namespace Debug { + +class Event { +public: + virtual ~Event() {} + + enum Category { + CORE=0, + XML, + SPOBJECT, + DOCUMENT, + REFCOUNT, + EXTENSION, + OTHER + }; + enum { N_CATEGORIES=OTHER+1 }; + + struct PropertyPair { + public: + PropertyPair() {} + PropertyPair(Util::SharedCStringPtr n, Util::SharedCStringPtr v) + : name(n), value(v) {} + PropertyPair(char const *n, Util::SharedCStringPtr v) + : name(Util::SharedCStringPtr::copy(n)), value(v) {} + PropertyPair(Util::SharedCStringPtr n, char const *v) + : name(n), value(Util::SharedCStringPtr::copy(v)) {} + PropertyPair(char const *n, char const *v) + : name(Util::SharedCStringPtr::copy(n)), + value(Util::SharedCStringPtr::copy(v)) {} + + Util::SharedCStringPtr name; + Util::SharedCStringPtr value; + }; + + static Category category() { return OTHER; } + + virtual Util::SharedCStringPtr name() const=0; + virtual unsigned propertyCount() const=0; + virtual PropertyPair property(unsigned property) const=0; +}; + +} + +} + +#endif +/* + 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:textwidth=99 : diff --git a/src/debug/gc-heap.h b/src/debug/gc-heap.h new file mode 100644 index 000000000..b3042432e --- /dev/null +++ b/src/debug/gc-heap.h @@ -0,0 +1,52 @@ +/* + * Inkscape::Debug::GCHeap - heap statistics for libgc heap + * + * Authors: + * MenTaLguY + * + * Copyright (C) 2004 MenTaLguY + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifndef SEEN_INKSCAPE_DEBUG_GC_HEAP_H +#define SEEN_INKSCAPE_DEBUG_GC_HEAP_H + +#include "gc-core.h" +#include "debug/heap.h" + +namespace Inkscape { +namespace Debug { + +class GCHeap : public Debug::Heap { +public: + int features() const { + return SIZE_AVAILABLE | USED_AVAILABLE | GARBAGE_COLLECTED; + } + Util::SharedCStringPtr name() const { + return Util::SharedCStringPtr::coerce("libgc"); + } + Heap::Stats stats() const { + Stats stats; + stats.size = GC::Core::get_heap_size(); + stats.bytes_used = stats.size - GC::Core::get_free_bytes(); + return stats; + } + void force_collect() { GC::Core::gcollect(); } +}; + +} +} + +#endif + +/* + 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:textwidth=99 : diff --git a/src/debug/heap.cpp b/src/debug/heap.cpp new file mode 100644 index 000000000..c0452f26b --- /dev/null +++ b/src/debug/heap.cpp @@ -0,0 +1,65 @@ +/* + * Inkscape::Debug::Heap - interface for gathering heap statistics + * + * Authors: + * MenTaLguY + * + * Copyright (C) 2005 MenTaLguY + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "gc-alloc.h" +#include "debug/gc-heap.h" +#include "debug/sysv-heap.h" +#include + +namespace Inkscape { +namespace Debug { + +namespace { + +typedef std::vector > HeapCollection; + +HeapCollection &heaps() { + static bool is_initialized=false; + static HeapCollection heaps; + if (!is_initialized) { + heaps.push_back(new SysVHeap()); + heaps.push_back(new GCHeap()); + is_initialized = true; + } + return heaps; +} + +} + +unsigned heap_count() { + return heaps().size(); +} + +Heap *get_heap(unsigned i) { + return heaps()[i]; +} + +void register_extra_heap(Heap &heap) { + heaps().push_back(&heap); +} + +} +} + +/* + 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:textwidth=99 : diff --git a/src/debug/heap.h b/src/debug/heap.h new file mode 100644 index 000000000..d07cf74a1 --- /dev/null +++ b/src/debug/heap.h @@ -0,0 +1,63 @@ +/* + * Inkscape::Debug::Heap - interface for gathering heap statistics + * + * Authors: + * MenTaLguY + * + * Copyright (C) 2005 MenTaLguY + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifndef SEEN_INKSCAPE_DEBUG_HEAP_H +#define SEEN_INKSCAPE_DEBUG_HEAP_H + +#include +#include "util/shared-c-string-ptr.h" + +namespace Inkscape { + +namespace Debug { + +class Heap { +public: + virtual ~Heap() {} + + struct Stats { + std::size_t size; + std::size_t bytes_used; + }; + + enum { + SIZE_AVAILABLE = ( 1 << 0 ), + USED_AVAILABLE = ( 1 << 1 ), + GARBAGE_COLLECTED = ( 1 << 2 ) + }; + + virtual int features() const=0; + + virtual Util::SharedCStringPtr name() const=0; + virtual Stats stats() const=0; + virtual void force_collect()=0; +}; + +unsigned heap_count(); +Heap *get_heap(unsigned i); + +void register_extra_heap(Heap &heap); + +} + +} + +#endif +/* + 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:textwidth=99 : diff --git a/src/debug/logger.cpp b/src/debug/logger.cpp new file mode 100644 index 000000000..a3c7b0430 --- /dev/null +++ b/src/debug/logger.cpp @@ -0,0 +1,204 @@ +/* + * Inkscape::Debug::Logger - debug logging facility + * + * Authors: + * MenTaLguY + * + * Copyright (C) 2005 MenTaLguY + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include +#include +#include +#include "debug/logger.h" +#include "debug/simple-event.h" +#include "gc-alloc.h" + +namespace Inkscape { + +namespace Debug { + +bool Logger::_enabled=false; +bool Logger::_category_mask[Event::N_CATEGORIES]; + +namespace { + +static void write_escaped_value(std::ostream &os, Util::SharedCStringPtr value) { + for ( char const *current=value ; *current ; ++current ) { + switch (*current) { + case '&': + os << "&"; + break; + case '"': + os << """; + break; + case '\'': + os << "'"; + break; + case '<': + os << "<"; + break; + case '>': + os << ">"; + break; + default: + os.put(*current); + } + } +} + +static void write_indent(std::ostream &os, unsigned depth) { + for ( unsigned i = 0 ; i < depth ; i++ ) { + os.write(" ", 2); + } +} + +static std::ofstream log_stream; +static bool empty_tag=false; +typedef std::vector > TagStack; +static TagStack &tag_stack() { + static TagStack stack; + return stack; +} + +static void do_shutdown() { + Debug::Logger::shutdown(); +} + +static bool equal_range(char const *c_string, + char const *start, char const *end) +{ + return !std::strncmp(start, c_string, end - start) && + !c_string[end - start]; +} + +static void set_category_mask(bool * const mask, char const *filter) { + if (!filter) { + for ( unsigned i = 0 ; i < Event::N_CATEGORIES ; i++ ) { + mask[i] = true; + } + return; + } else { + for ( unsigned i = 0 ; i < Event::N_CATEGORIES ; i++ ) { + mask[i] = false; + } + mask[Event::CORE] = true; + } + + char const *start; + char const *end; + start = end = filter; + while (*end) { + while ( *end && *end != ',' ) { end++; } + if ( start != end ) { + if (equal_range("CORE", start, end)) { + mask[Event::CORE] = true; + } else if (equal_range("XML", start, end)) { + mask[Event::XML] = true; + } else if (equal_range("SPOBJECT", start, end)) { + mask[Event::SPOBJECT] = true; + } else if (equal_range("DOCUMENT", start, end)) { + mask[Event::DOCUMENT] = true; + } else if (equal_range("REFCOUNT", start, end)) { + mask[Event::REFCOUNT] = true; + } else if (equal_range("EXTENSION", start, end)) { + mask[Event::EXTENSION] = true; + } else { + g_warning("Unknown debugging category %*s", end - start, start); + } + } + if (*end) { + start = end = end + 1; + } + } +} + +} + +void Logger::init() { + if (!_enabled) { + char const *log_filename=std::getenv("INKSCAPE_DEBUG_LOG"); + if (log_filename) { + log_stream.open(log_filename); + if (log_stream.is_open()) { + char const *log_filter=std::getenv("INKSCAPE_DEBUG_FILTER"); + set_category_mask(_category_mask, log_filter); + log_stream << "\n"; + log_stream.flush(); + _enabled = true; + start >(Util::SharedCStringPtr::coerce("session")); + std::atexit(&do_shutdown); + } + } + } +} + +void Logger::_start(Event const &event) { + Util::SharedCStringPtr name=event.name(); + + if (empty_tag) { + log_stream << ">\n"; + } + + write_indent(log_stream, tag_stack().size()); + + log_stream << "<" << name.cString(); + + unsigned property_count=event.propertyCount(); + for ( unsigned i = 0 ; i < property_count ; i++ ) { + Event::PropertyPair property=event.property(i); + log_stream << " " << property.name.cString() << "=\""; + write_escaped_value(log_stream, property.value); + log_stream << "\""; + } + + log_stream.flush(); + + tag_stack().push_back(name); + empty_tag = true; +} + +void Logger::_skip() { + tag_stack().push_back(Util::SharedCStringPtr()); +} + +void Logger::_finish() { + if (tag_stack().back()) { + if (empty_tag) { + log_stream << "/>\n"; + } else { + write_indent(log_stream, tag_stack().size() - 1); + log_stream << "\n"; + } + log_stream.flush(); + + empty_tag = false; + } + + tag_stack().pop_back(); +} + +void Logger::shutdown() { + if (_enabled) { + while (!tag_stack().empty()) { + finish(); + } + } +} + +} + +} + +/* + 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:textwidth=99 : diff --git a/src/debug/logger.h b/src/debug/logger.h new file mode 100644 index 000000000..61f9c2764 --- /dev/null +++ b/src/debug/logger.h @@ -0,0 +1,171 @@ +/* + * Inkscape::Debug::Logger - debug logging facility + * + * Authors: + * MenTaLguY + * + * Copyright (C) 2005 MenTaLguY + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifndef SEEN_INKSCAPE_DEBUG_LOGGER_H +#define SEEN_INKSCAPE_DEBUG_LOGGER_H + +#include "debug/event.h" + +namespace Inkscape { + +namespace Debug { + +class Logger { +public: + static void init(); + + template + inline static void start() { + if (_enabled) { + if (_category_mask[EventType::category()]) { + _start(EventType()); + } else { + _skip(); + } + } + } + + template + inline static void start(A const &a) { + if (_enabled) { + if (_category_mask[EventType::category()]) { + _start(EventType(a)); + } else { + _skip(); + } + } + } + + template + inline static void start(A const &a, B const &b) { + if (_enabled) { + if (_category_mask[EventType::category()]) { + _start(EventType(a, b)); + } else { + _skip(); + } + } + } + + template + inline static void start(A const &a, B const &b, C const &c) { + if (_enabled) { + if (_category_mask[EventType::category()]) { + _start(EventType(a, b, c)); + } else { + _skip(); + } + } + } + + template + inline static void start(A const &a, B const &b, C const &c, D const &d) { + if (_enabled) { + if (_category_mask[EventType::category()]) { + _start(EventType(a, b, c, d)); + } else { + _skip(); + } + } + } + + template + inline static void start(A const &a, B const &b, C const &c, + D const &d, E const &e) + { + if (_enabled) { + if (_category_mask[EventType::category()]) { + _start(EventType(a, b, c, d, e)); + } else { + _skip(); + } + } + } + + template + inline static void start(A const &a, B const &b, C const &c, + D const &d, E const &e, F const &f) + { + if (_enabled) { + if (_category_mask[EventType::category()]) { + _start(EventType(a, b, c, d, e, f)); + } else { + _skip(); + } + } + } + + template + inline static void start(A const &a, B const &b, C const &c, D const &d, + E const &e, F const &f, G const &g) + { + if (_enabled) { + if (_category_mask[EventType::category()]) { + _start(EventType(a, b, c, d, e, f, g)); + } else { + _skip(); + } + } + } + + template + inline static void start(A const &a, B const &b, C const &c, D const &d, + E const &e, F const &f, G const &g, H const &h) + { + if (_enabled) { + if (_category_mask[EventType::category()]) { + _start(EventType(a, b, c, d, e, f, g, h)); + } else { + _skip(); + } + } + } + + inline static void finish() { + if (_enabled) { + _finish(); + } + } + + static void shutdown(); + +private: + static bool _enabled; + + static void _start(Event const &event); + static void _skip(); + static void _finish(); + + static bool _category_mask[Event::N_CATEGORIES]; +}; + +} + +} + +#endif +/* + 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:textwidth=99 : diff --git a/src/debug/makefile.in b/src/debug/makefile.in new file mode 100644 index 000000000..89533f16d --- /dev/null +++ b/src/debug/makefile.in @@ -0,0 +1,17 @@ +# Convenience stub makefile to call the real Makefile. + +@SET_MAKE@ + +# Explicit so that it's the default rule. +all: + cd .. && $(MAKE) debug/all + +clean %.a %.o: + cd .. && $(MAKE) debug/$@ + +.PHONY: all clean + +OBJEXT = @OBJEXT@ + +.SUFFIXES: +.SUFFIXES: .a .$(OBJEXT) diff --git a/src/debug/simple-event.h b/src/debug/simple-event.h new file mode 100644 index 000000000..3a3adae3c --- /dev/null +++ b/src/debug/simple-event.h @@ -0,0 +1,51 @@ +/* + * Inkscape::Debug::SimpleEvent - trivial implementation of Debug::Event + * + * Authors: + * MenTaLguY + * + * Copyright (C) 2005 MenTaLguY + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifndef SEEN_INKSCAPE_DEBUG_SIMPLE_EVENT_H +#define SEEN_INKSCAPE_DEBUG_SIMPLE_EVENT_H + +#include "debug/event.h" + +namespace Inkscape { + +namespace Debug { + +template +class SimpleEvent : public Event { +public: + SimpleEvent(Util::SharedCStringPtr name) : _name(name) {} + SimpleEvent(char const *name) : _name(Util::SharedCStringPtr::copy(name)) {} + + static Category category() { return C; } + + Util::SharedCStringPtr name() const { return _name; } + unsigned propertyCount() const { return 0; } + PropertyPair property(unsigned property) const { return PropertyPair(); } + +private: + Util::SharedCStringPtr _name; +}; + +} + +} + +#endif +/* + 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:textwidth=99 : diff --git a/src/debug/sysv-heap.cpp b/src/debug/sysv-heap.cpp new file mode 100644 index 000000000..9ca6ea549 --- /dev/null +++ b/src/debug/sysv-heap.cpp @@ -0,0 +1,79 @@ +/* + * Inkscape::Debug::SysVHeap - malloc() statistics via System V interface + * + * Authors: + * MenTaLguY + * + * Copyright (C) 2005 MenTaLguY + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#ifdef HAVE_MALLOC_H +# include +#endif + +#include "debug/sysv-heap.h" + +namespace Inkscape { +namespace Debug { + +int SysVHeap::features() const { +#ifdef HAVE_MALLINFO + return SIZE_AVAILABLE | USED_AVAILABLE; +#else + return 0; +#endif +} + +Heap::Stats SysVHeap::stats() const { + Stats stats = { 0, 0 }; + +#ifdef HAVE_MALLINFO + struct mallinfo info=mallinfo(); + +#ifdef HAVE_STRUCT_MALLINFO_USMBLKS + stats.size += info.usmblks; + stats.bytes_used += info.usmblks; +#endif + +#ifdef HAVE_STRUCT_MALLINFO_FSMBLKS + stats.size += info.fsmblks; +#endif + +#ifdef HAVE_STRUCT_MALLINFO_UORDBLKS + stats.size += info.uordblks; + stats.bytes_used += info.uordblks; +#endif + +#ifdef HAVE_STRUCT_MALLINFO_FORDBLKS + stats.size += info.fordblks; +#endif + +#ifdef HAVE_STRUCT_MALLINFO_HBLKHD + stats.size += info.hblkhd; + stats.bytes_used += info.hblkhd; +#endif + +#endif + + return stats; +} + +} +} + +/* + 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:textwidth=99 : diff --git a/src/debug/sysv-heap.h b/src/debug/sysv-heap.h new file mode 100644 index 000000000..2ba24b2b5 --- /dev/null +++ b/src/debug/sysv-heap.h @@ -0,0 +1,47 @@ +/* + * Inkscape::Debug::SysVHeap - malloc() statistics via System V interface + * + * Authors: + * MenTaLguY + * + * Copyright (C) 2005 MenTaLguY + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifndef SEEN_INKSCAPE_DEBUG_SYSV_HEAP_H +#define SEEN_INKSCAPE_DEBUG_SYSV_HEAP_H + +#include "debug/heap.h" + +namespace Inkscape { +namespace Debug { + +class SysVHeap : public Heap { +public: + SysVHeap() {} + + int features() const; + + Util::SharedCStringPtr name() const { + return Util::SharedCStringPtr::coerce("standard malloc()"); + } + Stats stats() const; + void force_collect() {} +}; + +} +} + +#endif + +/* + 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:textwidth=99 : diff --git a/src/decimal-round.h b/src/decimal-round.h new file mode 100644 index 000000000..6b412685e --- /dev/null +++ b/src/decimal-round.h @@ -0,0 +1,44 @@ +#ifndef SEEN_DECIMAL_ROUND_H +#define SEEN_DECIMAL_ROUND_H + +#include + +#include "round.h" + + +namespace Inkscape { + +/** Returns x rounded to the nearest \a nplaces decimal places. + + Implemented in terms of Inkscape::round, i.e. we make no guarantees as to what happens if x is + half way between two rounded numbers. Add a note to the documentation if you care which + candidate is chosen for such case (round towards -infinity, +infinity, 0, or "even"). + + Note: nplaces is the number of decimal places without using scientific (e) notation, not the + number of significant figures. This function may not be suitable for values of x whose + magnitude is so far from 1 that one would want to use scientific (e) notation. + + The current implementation happens to allow nplaces to be negative: e.g. nplaces=-2 means + rounding to a multiple of 100. May or may not be useful. +**/ +inline double +decimal_round(double const x, int const nplaces) +{ + double const multiplier = std::pow(10.0, nplaces); + return Inkscape::round( x * multiplier ) / multiplier; +} + +} + +#endif /* !SEEN_DECIMAL_ROUND_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 : diff --git a/src/desktop-affine.cpp b/src/desktop-affine.cpp new file mode 100644 index 000000000..7ad2c7bfe --- /dev/null +++ b/src/desktop-affine.cpp @@ -0,0 +1,40 @@ +#define __SP_DESKTOP_AFFINE_C__ + +/* + * Editable view and widget implementation + * + * Author: + * Lauris Kaplinski + * + * Copyright (C) 1999-2002 Lauris Kaplinski + * Copyright (C) 2000-2001 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "desktop.h" +#include "document.h" +#include "sp-root.h" +#include "libnr/nr-matrix-ops.h" + +NR::Matrix const sp_desktop_root2dt_affine (SPDesktop const *dt) +{ + SPRoot const *root = SP_ROOT(SP_DOCUMENT_ROOT(dt->doc())); + return root->c2p * dt->doc2dt(); +} + +NR::Matrix const sp_desktop_dt2root_affine (SPDesktop const *dt) +{ + return sp_desktop_root2dt_affine(dt).inverse(); +} + +NR::Point sp_desktop_root2dt_xy_point(SPDesktop const *dt, NR::Point const p) +{ + return p * sp_desktop_root2dt_affine(dt); +} + +NR::Point sp_desktop_dt2root_xy_point(SPDesktop const *dt, NR::Point const p) +{ + return p * sp_desktop_dt2root_affine(dt); +} + diff --git a/src/desktop-affine.h b/src/desktop-affine.h new file mode 100644 index 000000000..00dc9faf0 --- /dev/null +++ b/src/desktop-affine.h @@ -0,0 +1,36 @@ +#ifndef __SP_DESKTOP_AFFINE_H__ +#define __SP_DESKTOP_AFFINE_H__ + +/* + * Desktop transformations + * + * Authors: + * Lauris Kaplinski + * + * Copyright (C) 1999-2002 Lauris Kaplinski + * Copyright (C) 2000-2001 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "forward.h" +#include + +NR::Matrix const sp_desktop_root2dt_affine(SPDesktop const *dt); +NR::Matrix const sp_desktop_dt2root_affine(SPDesktop const *dt); + +NR::Point sp_desktop_root2dt_xy_point(SPDesktop const *dt, const NR::Point p); +NR::Point sp_desktop_dt2root_xy_point(SPDesktop const *dt, const NR::Point p); + +#endif + +/* + 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:textwidth=99 : diff --git a/src/desktop-events.cpp b/src/desktop-events.cpp new file mode 100644 index 000000000..226b9d997 --- /dev/null +++ b/src/desktop-events.cpp @@ -0,0 +1,452 @@ +#define __SP_DESKTOP_EVENTS_C__ + +/* + * Event handlers for SPDesktop + * + * Author: + * Lauris Kaplinski + * + * Copyright (C) 1999-2002 Lauris Kaplinski + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifdef HAVE_CONFIG_H +# include +#endif +#include +#include +#include +#include +#include +#include +#include "display/guideline.h" +#include "helper/unit-menu.h" +#include "helper/units.h" +#include "desktop.h" +#include "document.h" +#include "sp-guide.h" +#include "sp-namedview.h" +#include "desktop-handles.h" +#include "event-context.h" +#include "widgets/desktop-widget.h" +#include "sp-metrics.h" +#include +#include "dialogs/dialog-events.h" +#include "message-context.h" +#include "xml/repr.h" + +static void sp_dt_simple_guide_dialog(SPGuide *guide, SPDesktop *desktop); + + +/* Root item handler */ + + +int sp_desktop_root_handler(SPCanvasItem *item, GdkEvent *event, SPDesktop *desktop) +{ + return sp_event_context_root_handler(desktop->event_context, event); +} + +/* + * fixme: this conatins a hack, to deal with deleting a view, which is + * completely on another view, in which case active_desktop will not be updated + * + */ + +int sp_desktop_item_handler(SPCanvasItem *item, GdkEvent *event, gpointer data) +{ + gpointer ddata = gtk_object_get_data(GTK_OBJECT(item->canvas), "SPDesktop"); + g_return_val_if_fail(ddata != NULL, FALSE); + + SPDesktop *desktop = static_cast(ddata); + + return sp_event_context_item_handler(desktop->event_context, SP_ITEM(data), event); +} + + +static gint sp_dt_ruler_event(GtkWidget *widget, GdkEvent *event, SPDesktopWidget *dtw, bool horiz) +{ + static bool dragging = false; + static SPCanvasItem *guide = NULL; + int wx, wy; + + SPDesktop *desktop = dtw->desktop; + Inkscape::XML::Node *repr = SP_OBJECT_REPR(desktop->namedview); + + gdk_window_get_pointer(GTK_WIDGET(dtw->canvas)->window, &wx, &wy, NULL); + NR::Point const event_win(wx, wy); + + switch (event->type) { + case GDK_BUTTON_PRESS: + if (event->button.button == 1) { + dragging = true; + NR::Point const event_w(sp_canvas_window_to_world(dtw->canvas, event_win)); + NR::Point const event_dt(desktop->w2d(event_w)); + + // explicitly show guidelines; if I draw a guide, I want them on + sp_repr_set_boolean(repr, "showguides", TRUE); + sp_repr_set_boolean(repr, "inkscape:guide-bbox", TRUE); + + double const guide_pos_dt = event_dt[ horiz + ? NR::Y + : NR::X ]; + guide = sp_guideline_new(desktop->guides, guide_pos_dt, !horiz); + sp_guideline_set_color(SP_GUIDELINE(guide), desktop->namedview->guidehicolor); + gdk_pointer_grab(widget->window, FALSE, + (GdkEventMask)(GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK), + NULL, NULL, + event->button.time); + } + break; + case GDK_MOTION_NOTIFY: + if (dragging) { + NR::Point const event_w(sp_canvas_window_to_world(dtw->canvas, event_win)); + NR::Point const event_dt(desktop->w2d(event_w)); + double const guide_pos_dt = event_dt[ horiz + ? NR::Y + : NR::X ]; + sp_guideline_set_position(SP_GUIDELINE(guide), guide_pos_dt); + desktop->set_coordinate_status(event_dt); + desktop->setPosition (event_dt); + } + break; + case GDK_BUTTON_RELEASE: + if (dragging && event->button.button == 1) { + gdk_pointer_ungrab(event->button.time); + NR::Point const event_w(sp_canvas_window_to_world(dtw->canvas, event_win)); + NR::Point const event_dt(desktop->w2d(event_w)); + dragging = false; + gtk_object_destroy(GTK_OBJECT(guide)); + guide = NULL; + if ( ( horiz + ? wy + : wx ) + >= 0 ) + { + Inkscape::XML::Node *repr = sp_repr_new("sodipodi:guide"); + repr->setAttribute("orientation", (horiz) ? "horizontal" : "vertical"); + double const guide_pos_dt = event_dt[ horiz + ? NR::Y + : NR::X ]; + sp_repr_set_svg_double(repr, "position", guide_pos_dt); + SP_OBJECT_REPR(desktop->namedview)->appendChild(repr); + Inkscape::GC::release(repr); + sp_document_done(SP_DT_DOCUMENT(desktop)); + } + desktop->set_coordinate_status(event_dt); + } + default: + break; + } + + return FALSE; +} + +int sp_dt_hruler_event(GtkWidget *widget, GdkEvent *event, SPDesktopWidget *dtw) +{ + return sp_dt_ruler_event(widget, event, dtw, true); +} + +int sp_dt_vruler_event(GtkWidget *widget, GdkEvent *event, SPDesktopWidget *dtw) +{ + return sp_dt_ruler_event(widget, event, dtw, false); +} + +/* Guides */ + +gint sp_dt_guide_event(SPCanvasItem *item, GdkEvent *event, gpointer data) +{ + static bool dragging = false; + static bool moved = false; + gint ret = FALSE; + + SPGuide *guide = SP_GUIDE(data); + SPDesktop *desktop = static_cast(gtk_object_get_data(GTK_OBJECT(item->canvas), "SPDesktop")); + + switch (event->type) { + case GDK_2BUTTON_PRESS: + if (event->button.button == 1) { + dragging = false; + sp_canvas_item_ungrab(item, event->button.time); + sp_dt_simple_guide_dialog(guide, desktop); + ret = TRUE; + } + break; + case GDK_BUTTON_PRESS: + if (event->button.button == 1) { + dragging = true; + sp_canvas_item_grab(item, + ( GDK_BUTTON_RELEASE_MASK | + GDK_BUTTON_PRESS_MASK | + GDK_POINTER_MOTION_MASK | + GDK_POINTER_MOTION_HINT_MASK ), + NULL, + event->button.time); + ret = TRUE; + } + break; + case GDK_MOTION_NOTIFY: + if (dragging) { + NR::Point const motion_w(event->motion.x, + event->motion.y); + NR::Point const motion_dt(desktop->w2d(motion_w)); + sp_guide_moveto(*guide, sp_guide_position_from_pt(guide, motion_dt), false); + moved = true; + desktop->set_coordinate_status(motion_dt); + desktop->setPosition (motion_dt); + ret = TRUE; + } + break; + case GDK_BUTTON_RELEASE: + if (dragging && event->button.button == 1) { + if (moved) { + NR::Point const event_w(event->button.x, + event->button.y); + NR::Point const event_dt(desktop->w2d(event_w)); + if (sp_canvas_world_pt_inside_window(item->canvas, event_w)) { + sp_guide_moveto(*guide, sp_guide_position_from_pt(guide, event_dt), true); + } else { + /* Undo movement of any attached shapes. */ + sp_guide_moveto(*guide, guide->position, false); + sp_guide_remove(guide); + } + moved = false; + sp_document_done(SP_DT_DOCUMENT(desktop)); + desktop->set_coordinate_status(event_dt); + desktop->setPosition (event_dt); + } + dragging = false; + sp_canvas_item_ungrab(item, event->button.time); + ret=TRUE; + } + case GDK_ENTER_NOTIFY: + { + + sp_guideline_set_color(SP_GUIDELINE(item), guide->hicolor); + + GString *position_string = SP_PX_TO_METRIC_STRING(guide->position, desktop->namedview->getDefaultMetric()); + char *guide_description = sp_guide_description(guide); + + desktop->guidesMessageContext()->setF(Inkscape::NORMAL_MESSAGE, _("%s at %s"), guide_description, position_string->str); + + g_free(guide_description); + g_string_free(position_string, TRUE); + break; + } + case GDK_LEAVE_NOTIFY: + sp_guideline_set_color(SP_GUIDELINE(item), guide->color); + desktop->guidesMessageContext()->clear(); + break; + default: + break; + } + + return ret; +} + + + +/* + * simple guideline dialog + */ + +static GtkWidget *d = NULL; +static GtkWidget *l1; +static GtkWidget *l2; +static GtkWidget *e; +static GtkWidget *u; +static GtkWidget *m; +static gdouble oldpos; +static bool mode; +static gpointer g; + + +static void guide_dialog_mode_changed(GtkWidget *widget) +{ + if (mode) { + // TRANSLATORS: This string appears when double-clicking on a guide. + // This is the distance by which the guide is to be moved. + gtk_label_set_text(GTK_LABEL(m), _(" relative by ")); + mode = false; + } else { + // TRANSLATORS: This string appears when double-clicking on a guide. + // This is the target location where the guide is to be moved. + gtk_label_set_text(GTK_LABEL(m), _(" absolute to ")); + mode = true; + } +} + +static void guide_dialog_close(GtkWidget *widget, gpointer data) +{ + gtk_widget_hide(GTK_WIDGET(d)); +} + +static void guide_dialog_apply(SPGuide &guide) +{ + gdouble const raw_dist = gtk_spin_button_get_value_as_float(GTK_SPIN_BUTTON(e)); + SPUnit const &unit = *sp_unit_selector_get_unit(SP_UNIT_SELECTOR(u)); + gdouble const points = sp_units_get_pixels(raw_dist, unit); + gdouble const newpos = ( mode + ? points + : guide.position + points ); + sp_guide_moveto(guide, newpos, true); + sp_document_done(SP_OBJECT_DOCUMENT(&guide)); +} + +static void guide_dialog_ok(GtkWidget *widget, gpointer g) +{ + SPGuide &guide = **static_cast(g); + guide_dialog_apply(guide); + guide_dialog_close(NULL, GTK_DIALOG(widget)); +} + +static void guide_dialog_delete(GtkWidget *widget, SPGuide **guide) +{ + SPDocument *doc = SP_OBJECT_DOCUMENT(*guide); + sp_guide_remove(*guide); + sp_document_done(doc); + guide_dialog_close(NULL, GTK_DIALOG(widget)); +} + +static void guide_dialog_response(GtkDialog *dialog, gint response, gpointer data) +{ + GtkWidget *widget = GTK_WIDGET(dialog); + + switch (response) { + case GTK_RESPONSE_OK: + guide_dialog_ok(widget, data); + break; + case -12: + guide_dialog_delete(widget, (SPGuide**) data); + break; + case GTK_RESPONSE_CLOSE: + guide_dialog_close(widget, (GtkDialog*) data); + break; + case GTK_RESPONSE_DELETE_EVENT: + break; +/* case GTK_RESPONSE_APPLY: + guide_dialog_apply(widget, data); + break; +*/ + default: + g_assert_not_reached(); + } +} + +static void sp_dt_simple_guide_dialog(SPGuide *guide, SPDesktop *desktop) +{ + if (!GTK_IS_WIDGET(d)) { + // create dialog + d = gtk_dialog_new_with_buttons(_("Guideline"), + NULL, + GTK_DIALOG_MODAL, + GTK_STOCK_OK, + GTK_RESPONSE_OK, + GTK_STOCK_DELETE, + -12, /* DELETE */ + GTK_STOCK_CLOSE, + GTK_RESPONSE_CLOSE, + NULL); + sp_transientize(d); + gtk_widget_hide(d); + + GtkWidget *b1 = gtk_hbox_new(FALSE, 4); + gtk_box_pack_start(GTK_BOX(GTK_DIALOG(d)->vbox), b1, FALSE, FALSE, 0); + gtk_container_set_border_width(GTK_CONTAINER(b1), 4); + gtk_widget_show(b1); + + GtkWidget *b2 = gtk_vbox_new(FALSE, 4); + gtk_box_pack_end(GTK_BOX(b1), b2, TRUE, TRUE, 0); + gtk_widget_show(b2); + + //labels + GtkWidget *b3 = gtk_hbox_new(FALSE, 4); + gtk_box_pack_start(GTK_BOX(b2), b3, TRUE, TRUE, 0); + gtk_widget_show(b3); + + l1 = gtk_label_new("foo1"); + gtk_box_pack_start(GTK_BOX(b3), l1, TRUE, TRUE, 0); + gtk_misc_set_alignment(GTK_MISC(l1), 1.0, 0.5); + gtk_widget_show(l1); + + l2 = gtk_label_new("foo2"); + gtk_box_pack_start(GTK_BOX(b3), l2, TRUE, TRUE, 0); + gtk_misc_set_alignment(GTK_MISC(l2), 0.0, 0.5); + gtk_widget_show(l2); + + GtkWidget *b4 = gtk_hbox_new(FALSE, 4); + gtk_box_pack_start(GTK_BOX(b2), b4, FALSE, FALSE, 0); + gtk_widget_show(b4); + // mode button + GtkWidget *but = gtk_button_new(); + gtk_button_set_relief(GTK_BUTTON(but), GTK_RELIEF_NONE); + gtk_box_pack_start(GTK_BOX(b4), but, FALSE, TRUE, 0); + gtk_signal_connect_while_alive(GTK_OBJECT(but), "clicked", GTK_SIGNAL_FUNC(guide_dialog_mode_changed), + NULL , GTK_OBJECT(but)); + gtk_widget_show(but); + m = gtk_label_new(_(" absolute to ")); + mode = true; + gtk_container_add(GTK_CONTAINER(but), m); + gtk_widget_show(m); + + // unitmenu + /* fixme: We should allow percents here too, as percents of the canvas size */ + u = sp_unit_selector_new(SP_UNIT_ABSOLUTE | SP_UNIT_DEVICE); + sp_unit_selector_set_unit(SP_UNIT_SELECTOR(u), desktop->namedview->doc_units); + + // spinbutton + GtkObject *a = gtk_adjustment_new(0.0, -SP_DESKTOP_SCROLL_LIMIT, SP_DESKTOP_SCROLL_LIMIT, 1.0, 10.0, 10.0); + sp_unit_selector_add_adjustment(SP_UNIT_SELECTOR(u), GTK_ADJUSTMENT(a)); + e = gtk_spin_button_new(GTK_ADJUSTMENT(a), 1.0 , 2); + gtk_widget_show(e); + gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(e), TRUE); + gtk_box_pack_start(GTK_BOX(b4), e, TRUE, TRUE, 0); + gtk_signal_connect_object(GTK_OBJECT(e), "activate", + GTK_SIGNAL_FUNC(gtk_window_activate_default), + GTK_OBJECT(d)); +/* gnome_dialog_editable_enters(GNOME_DIALOG(d), GTK_EDITABLE(e)); */ + + gtk_widget_show(u); + gtk_box_pack_start(GTK_BOX(b4), u, FALSE, FALSE, 0); + + + // dialog + gtk_dialog_set_default_response(GTK_DIALOG(d), GTK_RESPONSE_OK); + gtk_signal_connect(GTK_OBJECT(d), "response", GTK_SIGNAL_FUNC(guide_dialog_response), &g); + gtk_signal_connect(GTK_OBJECT(d), "delete_event", GTK_SIGNAL_FUNC(gtk_widget_hide_on_delete), GTK_WIDGET(d)); + } + + // initialize dialog + g = guide; + oldpos = guide->position; + { + char *guide_description = sp_guide_description(guide); + char *label = g_strdup_printf(_("Move %s"), guide_description); + g_free(guide_description); + gtk_label_set(GTK_LABEL(l1), label); + g_free(label); + } + + SPUnit const &unit = *sp_unit_selector_get_unit(SP_UNIT_SELECTOR(u)); + gdouble const val = sp_pixels_get_units(oldpos, unit); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(e), val); + gtk_spin_button_set_value(GTK_SPIN_BUTTON(e), val); + gtk_widget_grab_focus(e); + gtk_editable_select_region(GTK_EDITABLE(e), 0, 20); + gtk_window_set_position(GTK_WINDOW(d), GTK_WIN_POS_MOUSE); + + gtk_widget_show(d); +} + + +/* + 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:textwidth=99 : + diff --git a/src/desktop-events.h b/src/desktop-events.h new file mode 100644 index 000000000..3964b5d07 --- /dev/null +++ b/src/desktop-events.h @@ -0,0 +1,55 @@ +#ifndef __DESKTOP_EVENTS_H__ +#define __DESKTOP_EVENTS_H__ + +/* + * Entry points for event distribution + * + * Authors: + * Lauris Kaplinski + * + * Copyright (C) 1999-2002 authors + * Copyright (C) 2001-2002 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include +#include + +class SPDesktop; +class SPDesktopWidget; +class SPCanvasItem; + +/* Item handlers */ + +int sp_desktop_root_handler (SPCanvasItem *item, GdkEvent *event, SPDesktop *desktop); +int sp_desktop_item_handler (SPCanvasItem *item, GdkEvent *event, gpointer data); + +/* Default handlers */ + +gint sp_canvas_enter_notify (GtkWidget *widget, GdkEventCrossing *event, SPDesktop *desktop); +gint sp_canvas_leave_notify (GtkWidget *widget, GdkEventCrossing *event, SPDesktop *desktop); +gint sp_canvas_motion_notify (GtkWidget *widget,GdkEventMotion *motion, SPDesktop *desktop); + +/* Rulers */ + +int sp_dt_hruler_event (GtkWidget *widget, GdkEvent *event, SPDesktopWidget *dtw); +int sp_dt_vruler_event (GtkWidget *widget, GdkEvent *event, SPDesktopWidget *dtw); + +/* Guides */ + +gint sp_dt_guide_event (SPCanvasItem *item, GdkEvent *event, gpointer data); + +#endif + + +/* + 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:textwidth=99 : diff --git a/src/desktop-handles.cpp b/src/desktop-handles.cpp new file mode 100644 index 000000000..75584c6ee --- /dev/null +++ b/src/desktop-handles.cpp @@ -0,0 +1,122 @@ +#define __SP_DESKTOP_HANDLES_C__ + +/* + * Frontends + * + * Author: + * Lauris Kaplinski + * + * Copyright (C) 2001-2002 Lauris Kaplinski + * Copyright (C) 2001 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "display/sp-canvas.h" +#include "desktop.h" + +SPEventContext * +sp_desktop_event_context (SPDesktop const * desktop) +{ + g_return_val_if_fail (desktop != NULL, NULL); + + return desktop->event_context; +} + +Inkscape::Selection * +sp_desktop_selection (SPDesktop const * desktop) +{ + g_assert(desktop != NULL); + + return desktop->selection; +} + +SPDocument * +sp_desktop_document (SPDesktop const * desktop) +{ + g_return_val_if_fail (desktop != NULL, NULL); + + return desktop->doc(); +} + +SPCanvas * +sp_desktop_canvas (SPDesktop const * desktop) +{ + g_return_val_if_fail (desktop != NULL, NULL); + + return ((SPCanvasItem *) desktop->main)->canvas; +} + +SPCanvasItem * +sp_desktop_acetate (SPDesktop const * desktop) +{ + g_return_val_if_fail (desktop != NULL, NULL); + + return desktop->acetate; +} + +SPCanvasGroup * +sp_desktop_main (SPDesktop const * desktop) +{ + g_return_val_if_fail (desktop != NULL, NULL); + + return desktop->main; +} + +SPCanvasGroup * +sp_desktop_grid (SPDesktop const * desktop) +{ + g_return_val_if_fail (desktop != NULL, NULL); + + return desktop->grid; +} + +SPCanvasGroup * +sp_desktop_guides (SPDesktop const * desktop) +{ + g_return_val_if_fail (desktop != NULL, NULL); + + return desktop->guides; +} + +SPCanvasItem * +sp_desktop_drawing (SPDesktop const *desktop) +{ + g_return_val_if_fail (desktop != NULL, NULL); + + return desktop->drawing; +} + +SPCanvasGroup * +sp_desktop_sketch (SPDesktop const * desktop) +{ + g_return_val_if_fail (desktop != NULL, NULL); + + return desktop->sketch; +} + +SPCanvasGroup * +sp_desktop_controls (SPDesktop const * desktop) +{ + g_return_val_if_fail (desktop != NULL, NULL); + + return desktop->controls; +} + +Inkscape::MessageStack * +sp_desktop_message_stack (SPDesktop const * desktop) +{ + g_return_val_if_fail (desktop != NULL, NULL); + + return desktop->messageStack(); +} + +SPNamedView * +sp_desktop_namedview (SPDesktop const * desktop) +{ + g_return_val_if_fail (desktop != NULL, NULL); + + return desktop->namedview; +} + + diff --git a/src/desktop-handles.h b/src/desktop-handles.h new file mode 100644 index 000000000..0a7e5e7be --- /dev/null +++ b/src/desktop-handles.h @@ -0,0 +1,71 @@ +#ifndef __SP_DESKTOP_HANDLES_H__ +#define __SP_DESKTOP_HANDLES_H__ + +/* + * Frontends + * + * Authors: + * Lauris Kaplinski + * + * Copyright (C) 1999-2002 Lauris Kaplinski + * Copyright (C) 2000-2001 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "display/display-forward.h" +#include "forward.h" + +namespace Inkscape { + class MessageStack; + class Selection; +} + +#define SP_DESKTOP_SCROLL_LIMIT 4000.0 +#define SP_DESKTOP_ZOOM_MAX 256.0 +#define SP_DESKTOP_ZOOM_MIN 0.01 + +#define SP_COORDINATES_UNDERLINE_NONE (0) +#define SP_COORDINATES_UNDERLINE_X (1 << NR::X) +#define SP_COORDINATES_UNDERLINE_Y (1 << NR::Y) + +#define SP_DT_EVENTCONTEXT(d) sp_desktop_event_context (d) +#define SP_DT_SELECTION(d) sp_desktop_selection (d) +#define SP_DT_DOCUMENT(d) sp_desktop_document (d) +#define SP_DT_CANVAS(d) sp_desktop_canvas (d) +#define SP_DT_ACETATE(d) sp_desktop_acetate (d) +#define SP_DT_MAIN(d) sp_desktop_main (d) +#define SP_DT_GRID(d) sp_desktop_grid (d) +#define SP_DT_GUIDES(d) sp_desktop_guides (d) +#define SP_DT_DRAWING(d) sp_desktop_drawing (d) +#define SP_DT_SKETCH(d) sp_desktop_sketch (d) +#define SP_DT_CONTROLS(d) sp_desktop_controls (d) +#define SP_DT_MSGSTACK(d) sp_desktop_message_stack (d) +#define SP_DT_NAMEDVIEW(d) sp_desktop_namedview (d) + +SPEventContext * sp_desktop_event_context (SPDesktop const * desktop); +Inkscape::Selection * sp_desktop_selection (SPDesktop const * desktop); +SPDocument * sp_desktop_document (SPDesktop const * desktop); +SPCanvas * sp_desktop_canvas (SPDesktop const * desktop); +SPCanvasItem * sp_desktop_acetate (SPDesktop const * desktop); +SPCanvasGroup * sp_desktop_main (SPDesktop const * desktop); +SPCanvasGroup * sp_desktop_grid (SPDesktop const * desktop); +SPCanvasGroup * sp_desktop_guides (SPDesktop const * desktop); +SPCanvasItem *sp_desktop_drawing (SPDesktop const *desktop); +SPCanvasGroup * sp_desktop_sketch (SPDesktop const * desktop); +SPCanvasGroup * sp_desktop_controls (SPDesktop const * desktop); +Inkscape::MessageStack * sp_desktop_message_stack (SPDesktop const * desktop); +SPNamedView * sp_desktop_namedview (SPDesktop const * desktop); + +#endif + +/* + 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:textwidth=99 : diff --git a/src/desktop-style.cpp b/src/desktop-style.cpp new file mode 100644 index 000000000..540fd1637 --- /dev/null +++ b/src/desktop-style.cpp @@ -0,0 +1,1006 @@ +#define __SP_DESKTOP_STYLE_C__ + +/** \file + * Desktop style management + * + * Authors: + * bulia byak + * + * Copyright (C) 2004 authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "desktop.h" +#include "color-rgba.h" +#include "svg/css-ostringstream.h" +#include "svg/svg.h" +#include "selection.h" +#include "sp-tspan.h" +#include "sp-textpath.h" +#include "inkscape.h" +#include "style.h" +#include "prefs-utils.h" +#include "sp-use.h" +#include "sp-flowtext.h" +#include "sp-flowregion.h" +#include "sp-flowdiv.h" +#include "sp-linear-gradient.h" +#include "sp-radial-gradient.h" +#include "sp-pattern.h" +#include "xml/repr.h" +#include "libnrtype/font-style-to-pos.h" + +#include "desktop-style.h" + +/** + * Set color on selection on desktop. + */ +void +sp_desktop_set_color(SPDesktop *desktop, ColorRGBA const &color, bool is_relative, bool fill) +{ + /// \todo relative color setting + if (is_relative) { + g_warning("FIXME: relative color setting not yet implemented"); + return; + } + + guint32 rgba = SP_RGBA32_F_COMPOSE(color[0], color[1], color[2], color[3]); + gchar b[64]; + sp_svg_write_color(b, 64, rgba); + SPCSSAttr *css = sp_repr_css_attr_new(); + if (fill) { + sp_repr_css_set_property(css, "fill", b); + Inkscape::CSSOStringStream osalpha; + osalpha << color[3]; + sp_repr_css_set_property(css, "fill-opacity", osalpha.str().c_str()); + } else { + sp_repr_css_set_property(css, "stroke", b); + Inkscape::CSSOStringStream osalpha; + osalpha << color[3]; + sp_repr_css_set_property(css, "stroke-opacity", osalpha.str().c_str()); + } + + sp_desktop_set_style(desktop, css); + + sp_repr_css_attr_unref(css); +} + +/** + * Apply style on object and children, recursively. + */ +void +sp_desktop_apply_css_recursive(SPObject *o, SPCSSAttr *css, bool skip_lines) +{ + // non-items should not have style + if (!SP_IS_ITEM(o)) + return; + + // 1. tspans with role=line are not regular objects in that they are not supposed to have style of their own, + // but must always inherit from the parent text. Same for textPath. + // However, if the line tspan or textPath contains some style (old file?), we reluctantly set our style to it too. + + // 2. Generally we allow setting style on clones, but when it's inside flowRegion, do not touch + // it, be it clone or not; it's just styleless shape (because that's how Inkscape does + // flowtext). + + if (!(skip_lines + && ((SP_IS_TSPAN(o) && SP_TSPAN(o)->role == SP_TSPAN_ROLE_LINE) + || SP_IS_FLOWDIV(o) + || SP_IS_FLOWPARA(o) + || SP_IS_TEXTPATH(o)) + && !SP_OBJECT_REPR(o)->attribute("style")) + && + !(SP_IS_FLOWREGION(o) || + SP_IS_FLOWREGIONEXCLUDE(o) || + (SP_IS_USE(o) && + SP_OBJECT_PARENT(o) && + (SP_IS_FLOWREGION(SP_OBJECT_PARENT(o)) || + SP_IS_FLOWREGIONEXCLUDE(SP_OBJECT_PARENT(o)) + ) + ) + ) + ) { + + SPCSSAttr *css_set = sp_repr_css_attr_new(); + sp_repr_css_merge(css_set, css); + + // Scale the style by the inverse of the accumulated parent transform in the paste context. + { + NR::Matrix const local(sp_item_i2doc_affine(SP_ITEM(o))); + double const ex(NR::expansion(local)); + if ( ( ex != 0. ) + && ( ex != 1. ) ) { + sp_css_attr_scale(css_set, 1/ex); + } + } + + sp_repr_css_change(SP_OBJECT_REPR(o), css_set, "style"); + + sp_repr_css_attr_unref(css_set); + } + + // setting style on child of clone spills into the clone original (via shared repr), don't do it! + if (SP_IS_USE(o)) + return; + + for (SPObject *child = sp_object_first_child(SP_OBJECT(o)) ; child != NULL ; child = SP_OBJECT_NEXT(child) ) { + if (sp_repr_css_property(css, "opacity", NULL) != NULL) { + // Unset properties which are accumulating and thus should not be set recursively. + // For example, setting opacity 0.5 on a group recursively would result in the visible opacity of 0.25 for an item in the group. + SPCSSAttr *css_recurse = sp_repr_css_attr_new(); + sp_repr_css_merge(css_recurse, css); + sp_repr_css_set_property(css_recurse, "opacity", NULL); + sp_desktop_apply_css_recursive(child, css_recurse, skip_lines); + sp_repr_css_attr_unref(css_recurse); + } else { + sp_desktop_apply_css_recursive(child, css, skip_lines); + } + } +} + +/** + * Apply style on selection on desktop. + */ +void +sp_desktop_set_style(SPDesktop *desktop, SPCSSAttr *css, bool change, bool write_current) +{ + if (write_current) { +// 1. Set internal value + sp_repr_css_merge(desktop->current, css); + +// 1a. Write to prefs; make a copy and unset any URIs first + SPCSSAttr *css_write = sp_repr_css_attr_new(); + sp_repr_css_merge(css_write, css); + sp_css_attr_unset_uris(css_write); + sp_repr_css_change(inkscape_get_repr(INKSCAPE, "desktop"), css_write, "style"); + sp_repr_css_attr_unref(css_write); + } + + if (!change) + return; + +// 2. Emit signal + bool intercepted = desktop->_set_style_signal.emit(css); + +/** \todo + * FIXME: in set_style, compensate pattern and gradient fills, stroke width, + * rect corners, font size for the object's own transform so that pasting + * fills does not depend on preserve/optimize. + */ + +// 3. If nobody has intercepted the signal, apply the style to the selection + if (!intercepted) { + for (GSList const *i = desktop->selection->itemList(); i != NULL; i = i->next) { + /// \todo if the style is text-only, apply only to texts? + sp_desktop_apply_css_recursive(SP_OBJECT(i->data), css, true); + } + } +} + +/** + * Return the desktop's current style. + */ +SPCSSAttr * +sp_desktop_get_style(SPDesktop *desktop, bool with_text) +{ + SPCSSAttr *css = sp_repr_css_attr_new(); + sp_repr_css_merge(css, desktop->current); + if (!css->attributeList()) { + sp_repr_css_attr_unref(css); + return NULL; + } else { + if (!with_text) { + css = sp_css_attr_unset_text(css); + } + return css; + } +} + +/** + * Return the desktop's current color. + */ +guint32 +sp_desktop_get_color(SPDesktop *desktop, bool is_fill) +{ + guint32 r = 0; // if there's no color, return black + gchar const *property = sp_repr_css_property(desktop->current, + is_fill ? "fill" : "stroke", + "#000"); + + if (desktop->current && property) { // if there is style and the property in it, + if (strncmp(property, "url", 3)) { // and if it's not url, + // read it + r = sp_svg_read_color(property, r); + } + } + + return r; +} + +/** + * Apply the desktop's current style or the tool style to repr. + */ +void +sp_desktop_apply_style_tool(SPDesktop *desktop, Inkscape::XML::Node *repr, char const *tool, bool with_text) +{ + SPCSSAttr *css_current = sp_desktop_get_style(desktop, with_text); + if ((prefs_get_int_attribute(tool, "usecurrent", 0) != 0) && css_current) { + sp_repr_css_set(repr, css_current, "style"); + } else { + Inkscape::XML::Node *tool_repr = inkscape_get_repr(INKSCAPE, tool); + if (tool_repr) { + SPCSSAttr *css = sp_repr_css_attr_inherited(tool_repr, "style"); + sp_repr_css_set(repr, css, "style"); + sp_repr_css_attr_unref(css); + } + } + if (css_current) { + sp_repr_css_attr_unref(css_current); + } +} + +/** + * Returns the font size (in SVG pixels) of the text tool style (if text + * tool uses its own style) or desktop style (otherwise). +*/ +double +sp_desktop_get_font_size_tool(SPDesktop *desktop) +{ + gchar const *desktop_style = inkscape_get_repr(INKSCAPE, "desktop")->attribute("style"); + gchar const *style_str = NULL; + if ((prefs_get_int_attribute("tools.text", "usecurrent", 0) != 0) && desktop_style) { + style_str = desktop_style; + } else { + Inkscape::XML::Node *tool_repr = inkscape_get_repr(INKSCAPE, "tools.text"); + if (tool_repr) { + style_str = tool_repr->attribute("style"); + } + } + + double ret = 12; + if (style_str) { + SPStyle *style = sp_style_new(); + sp_style_merge_from_style_string(style, style_str); + ret = style->font_size.computed; + sp_style_unref(style); + } + return ret; +} + +/** Determine average stroke width, simple method */ +// see TODO in dialogs/stroke-style.cpp on how to get rid of this eventually +gdouble +stroke_average_width (GSList const *objects) +{ + if (g_slist_length ((GSList *) objects) == 0) + return NR_HUGE; + + gdouble avgwidth = 0.0; + bool notstroked = true; + int n_notstroked = 0; + + for (GSList const *l = objects; l != NULL; l = l->next) { + if (!SP_IS_ITEM (l->data)) + continue; + + NR::Matrix i2d = sp_item_i2d_affine (SP_ITEM(l->data)); + + SPObject *object = SP_OBJECT(l->data); + + if ( object->style->stroke.type == SP_PAINT_TYPE_NONE ) { + ++n_notstroked; // do not count nonstroked objects + continue; + } else { + notstroked = false; + } + + avgwidth += SP_OBJECT_STYLE (object)->stroke_width.computed * i2d.expansion(); + } + + if (notstroked) + return NR_HUGE; + + return avgwidth / (g_slist_length ((GSList *) objects) - n_notstroked); +} + +/** + * Write to style_res the average fill or stroke of list of objects, if applicable. + */ +int +objects_query_fillstroke (GSList *objects, SPStyle *style_res, bool const isfill) +{ + if (g_slist_length(objects) == 0) { + /* No objects, set empty */ + return QUERY_STYLE_NOTHING; + } + + SPIPaint *paint_res = isfill? &style_res->fill : &style_res->stroke; + paint_res->type = SP_PAINT_TYPE_IMPOSSIBLE; + paint_res->set = TRUE; + + gfloat c[4]; + c[0] = c[1] = c[2] = c[3] = 0.0; + gint num = 0; + + gfloat prev[4]; + prev[0] = prev[1] = prev[2] = prev[3] = 0.0; + bool same_color = true; + + for (GSList const *i = objects; i != NULL; i = i->next) { + SPObject *obj = SP_OBJECT (i->data); + SPStyle *style = SP_OBJECT_STYLE (obj); + if (!style) continue; + + SPIPaint *paint = isfill? &style->fill : &style->stroke; + + // We consider paint "effectively set" for anything within text hierarchy + SPObject *parent = SP_OBJECT_PARENT (obj); + bool paint_effectively_set = paint->set || (SP_IS_TEXT(parent) || SP_IS_TEXTPATH(parent) || SP_IS_TSPAN(parent) || SP_IS_FLOWTEXT(parent) || SP_IS_FLOWDIV(parent) || SP_IS_FLOWPARA(parent) || SP_IS_FLOWTSPAN(parent) || SP_IS_FLOWLINE(parent)); + + // 1. Bail out with QUERY_STYLE_MULTIPLE_DIFFERENT if necessary + + if ((paint_res->type != SP_PAINT_TYPE_IMPOSSIBLE) && (paint->type != paint_res->type || (paint_res->set != paint_effectively_set))) { + return QUERY_STYLE_MULTIPLE_DIFFERENT; // different types of paint + } + + if (paint_res->set && paint->set && paint_res->type == SP_PAINT_TYPE_PAINTSERVER) { + // both previous paint and this paint were a server, see if the servers are compatible + + SPPaintServer *server_res = isfill? SP_STYLE_FILL_SERVER (style_res) : SP_STYLE_STROKE_SERVER (style_res); + SPPaintServer *server = isfill? SP_STYLE_FILL_SERVER (style) : SP_STYLE_STROKE_SERVER (style); + + if (SP_IS_LINEARGRADIENT (server_res)) { + + if (!SP_IS_LINEARGRADIENT(server)) + return QUERY_STYLE_MULTIPLE_DIFFERENT; // different kind of server + + SPGradient *vector = sp_gradient_get_vector ( SP_GRADIENT (server), FALSE ); + SPGradient *vector_res = sp_gradient_get_vector ( SP_GRADIENT (server_res), FALSE ); + if (vector_res != vector) + return QUERY_STYLE_MULTIPLE_DIFFERENT; // different gradient vectors + + } else if (SP_IS_RADIALGRADIENT (server_res)) { + + if (!SP_IS_RADIALGRADIENT(server)) + return QUERY_STYLE_MULTIPLE_DIFFERENT; // different kind of server + + SPGradient *vector = sp_gradient_get_vector ( SP_GRADIENT (server), FALSE ); + SPGradient *vector_res = sp_gradient_get_vector ( SP_GRADIENT (server_res), FALSE ); + if (vector_res != vector) + return QUERY_STYLE_MULTIPLE_DIFFERENT; // different gradient vectors + + } else if (SP_IS_PATTERN (server_res)) { + + if (!SP_IS_PATTERN(server)) + return QUERY_STYLE_MULTIPLE_DIFFERENT; // different kind of server + + SPPattern *pat = pattern_getroot (SP_PATTERN (server)); + SPPattern *pat_res = pattern_getroot (SP_PATTERN (server_res)); + if (pat_res != pat) + return QUERY_STYLE_MULTIPLE_DIFFERENT; // different pattern roots + } + } + + // 2. Sum color, copy server from paint to paint_res + + if (paint_res->set && paint_effectively_set && paint->type == SP_PAINT_TYPE_COLOR) { + + gfloat d[3]; + sp_color_get_rgb_floatv (&paint->value.color, d); + + // Check if this color is the same as previous + if (paint_res->type == SP_PAINT_TYPE_IMPOSSIBLE) { + prev[0] = d[0]; + prev[1] = d[1]; + prev[2] = d[2]; + prev[3] = d[3]; + } else { + if (same_color && (prev[0] != d[0] || prev[1] != d[1] || prev[2] != d[2] || prev[3] != d[3])) + same_color = false; + } + + // average color + c[0] += d[0]; + c[1] += d[1]; + c[2] += d[2]; + c[3] += SP_SCALE24_TO_FLOAT (isfill? style->fill_opacity.value : style->stroke_opacity.value); + num ++; + } + + if (paint_res->set && paint->set && paint->type == SP_PAINT_TYPE_PAINTSERVER) { // copy the server + if (isfill) { + SP_STYLE_FILL_SERVER (style_res) = SP_STYLE_FILL_SERVER (style); + } else { + SP_STYLE_STROKE_SERVER (style_res) = SP_STYLE_STROKE_SERVER (style); + } + } + paint_res->type = paint->type; + paint_res->set = paint_effectively_set; + style_res->fill_rule.computed = style->fill_rule.computed; // no averaging on this, just use the last one + } + + // After all objects processed, divide the color if necessary and return + if (paint_res->set && paint_res->type == SP_PAINT_TYPE_COLOR) { // set the color + g_assert (num >= 1); + + c[0] /= num; + c[1] /= num; + c[2] /= num; + c[3] /= num; + sp_color_set_rgb_float(&paint_res->value.color, c[0], c[1], c[2]); + if (isfill) { + style_res->fill_opacity.value = SP_SCALE24_FROM_FLOAT (c[3]); + } else { + style_res->stroke_opacity.value = SP_SCALE24_FROM_FLOAT (c[3]); + } + if (num > 1) { + if (same_color) + return QUERY_STYLE_MULTIPLE_SAME; + else + return QUERY_STYLE_MULTIPLE_AVERAGED; + } else { + return QUERY_STYLE_SINGLE; + } + } + + // Not color + if (g_slist_length(objects) > 1) { + return QUERY_STYLE_MULTIPLE_SAME; + } else { + return QUERY_STYLE_SINGLE; + } +} + +/** + * Write to style_res the average opacity of a list of objects. + */ +int +objects_query_opacity (GSList *objects, SPStyle *style_res) +{ + if (g_slist_length(objects) == 0) { + /* No objects, set empty */ + return QUERY_STYLE_NOTHING; + } + + gdouble opacity_sum = 0; + gdouble opacity_prev = -1; + bool same_opacity = true; + guint opacity_items = 0; + + + for (GSList const *i = objects; i != NULL; i = i->next) { + SPObject *obj = SP_OBJECT (i->data); + SPStyle *style = SP_OBJECT_STYLE (obj); + if (!style) continue; + + double opacity = SP_SCALE24_TO_FLOAT(style->opacity.value); + opacity_sum += opacity; + if (opacity_prev != -1 && opacity != opacity_prev) + same_opacity = false; + opacity_prev = opacity; + opacity_items ++; + } + if (opacity_items > 1) + opacity_sum /= opacity_items; + + style_res->opacity.value = SP_SCALE24_FROM_FLOAT(opacity_sum); + + if (opacity_items == 0) { + return QUERY_STYLE_NOTHING; + } else if (opacity_items == 1) { + return QUERY_STYLE_SINGLE; + } else { + if (same_opacity) + return QUERY_STYLE_MULTIPLE_SAME; + else + return QUERY_STYLE_MULTIPLE_AVERAGED; + } +} + +/** + * Write to style_res the average stroke width of a list of objects. + */ +int +objects_query_strokewidth (GSList *objects, SPStyle *style_res) +{ + if (g_slist_length(objects) == 0) { + /* No objects, set empty */ + return QUERY_STYLE_NOTHING; + } + + gdouble avgwidth = 0.0; + + gdouble prev_sw = -1; + bool same_sw = true; + + int n_stroked = 0; + + for (GSList const *i = objects; i != NULL; i = i->next) { + SPObject *obj = SP_OBJECT (i->data); + if (!SP_IS_ITEM(obj)) continue; + SPStyle *style = SP_OBJECT_STYLE (obj); + if (!style) continue; + + if ( style->stroke.type == SP_PAINT_TYPE_NONE ) { + continue; + } + + n_stroked ++; + + NR::Matrix i2d = sp_item_i2d_affine (SP_ITEM(obj)); + double sw = style->stroke_width.computed * i2d.expansion(); + + if (prev_sw != -1 && fabs(sw - prev_sw) > 1e-3) + same_sw = false; + prev_sw = sw; + + avgwidth += sw; + } + + if (n_stroked > 1) + avgwidth /= (n_stroked); + + style_res->stroke_width.computed = avgwidth; + style_res->stroke_width.set = true; + + if (n_stroked == 0) { + return QUERY_STYLE_NOTHING; + } else if (n_stroked == 1) { + return QUERY_STYLE_SINGLE; + } else { + if (same_sw) + return QUERY_STYLE_MULTIPLE_SAME; + else + return QUERY_STYLE_MULTIPLE_AVERAGED; + } +} + +/** + * Write to style_res the average miter limit of a list of objects. + */ +int +objects_query_miterlimit (GSList *objects, SPStyle *style_res) +{ + if (g_slist_length(objects) == 0) { + /* No objects, set empty */ + return QUERY_STYLE_NOTHING; + } + + gdouble avgml = 0.0; + int n_stroked = 0; + + gdouble prev_ml = -1; + bool same_ml = true; + + for (GSList const *i = objects; i != NULL; i = i->next) { + SPObject *obj = SP_OBJECT (i->data); + if (!SP_IS_ITEM(obj)) continue; + SPStyle *style = SP_OBJECT_STYLE (obj); + if (!style) continue; + + if ( style->stroke.type == SP_PAINT_TYPE_NONE ) { + continue; + } + + n_stroked ++; + + if (prev_ml != -1 && fabs(style->stroke_miterlimit.value - prev_ml) > 1e-3) + same_ml = false; + prev_ml = style->stroke_miterlimit.value; + + avgml += style->stroke_miterlimit.value; + } + + if (n_stroked > 1) + avgml /= (n_stroked); + + style_res->stroke_miterlimit.value = avgml; + style_res->stroke_miterlimit.set = true; + + if (n_stroked == 0) { + return QUERY_STYLE_NOTHING; + } else if (n_stroked == 1) { + return QUERY_STYLE_SINGLE; + } else { + if (same_ml) + return QUERY_STYLE_MULTIPLE_SAME; + else + return QUERY_STYLE_MULTIPLE_AVERAGED; + } +} + +/** + * Write to style_res the stroke cap of a list of objects. + */ +int +objects_query_strokecap (GSList *objects, SPStyle *style_res) +{ + if (g_slist_length(objects) == 0) { + /* No objects, set empty */ + return QUERY_STYLE_NOTHING; + } + + int cap = -1; + gdouble prev_cap = -1; + bool same_cap = true; + int n_stroked = 0; + + for (GSList const *i = objects; i != NULL; i = i->next) { + SPObject *obj = SP_OBJECT (i->data); + if (!SP_IS_ITEM(obj)) continue; + SPStyle *style = SP_OBJECT_STYLE (obj); + if (!style) continue; + + if ( style->stroke.type == SP_PAINT_TYPE_NONE ) { + continue; + } + + n_stroked ++; + + if (prev_cap != -1 && style->stroke_linecap.value != prev_cap) + same_cap = false; + prev_cap = style->stroke_linecap.value; + + cap = style->stroke_linecap.value; + } + + style_res->stroke_linecap.value = cap; + style_res->stroke_linecap.set = true; + + if (n_stroked == 0) { + return QUERY_STYLE_NOTHING; + } else if (n_stroked == 1) { + return QUERY_STYLE_SINGLE; + } else { + if (same_cap) + return QUERY_STYLE_MULTIPLE_SAME; + else + return QUERY_STYLE_MULTIPLE_DIFFERENT; + } +} + +/** + * Write to style_res the stroke join of a list of objects. + */ +int +objects_query_strokejoin (GSList *objects, SPStyle *style_res) +{ + if (g_slist_length(objects) == 0) { + /* No objects, set empty */ + return QUERY_STYLE_NOTHING; + } + + int join = -1; + gdouble prev_join = -1; + bool same_join = true; + int n_stroked = 0; + + for (GSList const *i = objects; i != NULL; i = i->next) { + SPObject *obj = SP_OBJECT (i->data); + if (!SP_IS_ITEM(obj)) continue; + SPStyle *style = SP_OBJECT_STYLE (obj); + if (!style) continue; + + if ( style->stroke.type == SP_PAINT_TYPE_NONE ) { + continue; + } + + n_stroked ++; + + if (prev_join != -1 && style->stroke_linejoin.value != prev_join) + same_join = false; + prev_join = style->stroke_linejoin.value; + + join = style->stroke_linejoin.value; + } + + style_res->stroke_linejoin.value = join; + style_res->stroke_linejoin.set = true; + + if (n_stroked == 0) { + return QUERY_STYLE_NOTHING; + } else if (n_stroked == 1) { + return QUERY_STYLE_SINGLE; + } else { + if (same_join) + return QUERY_STYLE_MULTIPLE_SAME; + else + return QUERY_STYLE_MULTIPLE_DIFFERENT; + } +} + +/** + * Write to style_res the average font size and spacing of objects. + */ +int +objects_query_fontnumbers (GSList *objects, SPStyle *style_res) +{ + bool different = false; + + double size = 0; + double letterspacing = 0; + double linespacing = 0; + bool linespacing_normal = false; + bool letterspacing_normal = false; + + double size_prev = 0; + double letterspacing_prev = 0; + double linespacing_prev = 0; + + /// \todo FIXME: add word spacing, kerns? rotates? + + int texts = 0; + + for (GSList const *i = objects; i != NULL; i = i->next) { + SPObject *obj = SP_OBJECT (i->data); + + if (!SP_IS_TEXT(obj) && !SP_IS_FLOWTEXT(obj) + && !SP_IS_TSPAN(obj) && !SP_IS_TEXTPATH(obj) + && !SP_IS_FLOWDIV(obj) && !SP_IS_FLOWPARA(obj) && !SP_IS_FLOWTSPAN(obj)) + continue; + + SPStyle *style = SP_OBJECT_STYLE (obj); + if (!style) continue; + + texts ++; + size += style->font_size.computed * NR::expansion(sp_item_i2d_affine(SP_ITEM(obj))); /// \todo FIXME: we assume non-% units here + + if (style->letter_spacing.normal) { + if (!different && (letterspacing_prev == 0 || letterspacing_prev == letterspacing)) + letterspacing_normal = true; + } else { + letterspacing += style->letter_spacing.computed; /// \todo FIXME: we assume non-% units here + letterspacing_normal = false; + } + + double linespacing_current; + if (style->line_height.normal) { + linespacing_current = Inkscape::Text::Layout::LINE_HEIGHT_NORMAL; + if (!different && (linespacing_prev == 0 || linespacing_prev == linespacing_current)) + linespacing_normal = true; + } else if (style->line_height.unit == SP_CSS_UNIT_PERCENT || style->font_size.computed == 0) { + linespacing_current = style->line_height.value; + linespacing_normal = false; + } else { // we need % here + linespacing_current = style->line_height.computed / style->font_size.computed; + linespacing_normal = false; + } + linespacing += linespacing_current; + + if ((size_prev != 0 && style->font_size.computed != size_prev) || + (letterspacing_prev != 0 && style->letter_spacing.computed != letterspacing_prev) || + (linespacing_prev != 0 && linespacing_current != linespacing_prev)) { + different = true; + } + + size_prev = style->font_size.computed; + letterspacing_prev = style->letter_spacing.computed; + linespacing_prev = linespacing_current; + + // FIXME: we must detect MULTIPLE_DIFFERENT for these too + style_res->text_anchor.computed = style->text_anchor.computed; + style_res->writing_mode.computed = style->writing_mode.computed; + } + + if (texts == 0) + return QUERY_STYLE_NOTHING; + + if (texts > 1) { + size /= texts; + letterspacing /= texts; + linespacing /= texts; + } + + style_res->font_size.computed = size; + style_res->font_size.type = SP_FONT_SIZE_LENGTH; + + style_res->letter_spacing.normal = letterspacing_normal; + style_res->letter_spacing.computed = letterspacing; + + style_res->line_height.normal = linespacing_normal; + style_res->line_height.computed = linespacing; + style_res->line_height.value = linespacing; + style_res->line_height.unit = SP_CSS_UNIT_PERCENT; + + if (texts > 1) { + if (different) { + return QUERY_STYLE_MULTIPLE_AVERAGED; + } else { + return QUERY_STYLE_MULTIPLE_SAME; + } + } else { + return QUERY_STYLE_SINGLE; + } +} + +/** + * Write to style_res the average font style of objects. + */ +int +objects_query_fontstyle (GSList *objects, SPStyle *style_res) +{ + bool different = false; + bool set = false; + + int texts = 0; + + for (GSList const *i = objects; i != NULL; i = i->next) { + SPObject *obj = SP_OBJECT (i->data); + + if (!SP_IS_TEXT(obj) && !SP_IS_FLOWTEXT(obj) + && !SP_IS_TSPAN(obj) && !SP_IS_TEXTPATH(obj) + && !SP_IS_FLOWDIV(obj) && !SP_IS_FLOWPARA(obj) && !SP_IS_FLOWTSPAN(obj)) + continue; + + SPStyle *style = SP_OBJECT_STYLE (obj); + if (!style) continue; + + texts ++; + + if (set && + font_style_to_pos(*style_res).signature() != font_style_to_pos(*style).signature() ) { + different = true; // different styles + } + + set = TRUE; + style_res->font_weight.value = style_res->font_weight.computed = style->font_weight.computed; + style_res->font_style.value = style_res->font_style.computed = style->font_style.computed; + style_res->font_stretch.value = style_res->font_stretch.computed = style->font_stretch.computed; + style_res->font_variant.value = style_res->font_variant.computed = style->font_variant.computed; + } + + if (texts == 0 || !set) + return QUERY_STYLE_NOTHING; + + if (texts > 1) { + if (different) { + return QUERY_STYLE_MULTIPLE_DIFFERENT; + } else { + return QUERY_STYLE_MULTIPLE_SAME; + } + } else { + return QUERY_STYLE_SINGLE; + } +} + +/** + * Write to style_res the average font family of objects. + */ +int +objects_query_fontfamily (GSList *objects, SPStyle *style_res) +{ + bool different = false; + int texts = 0; + + if (style_res->text->font_family.value) { + g_free(style_res->text->font_family.value); + style_res->text->font_family.value = NULL; + } + style_res->text->font_family.set = FALSE; + + for (GSList const *i = objects; i != NULL; i = i->next) { + SPObject *obj = SP_OBJECT (i->data); + + if (!SP_IS_TEXT(obj) && !SP_IS_FLOWTEXT(obj) + && !SP_IS_TSPAN(obj) && !SP_IS_TEXTPATH(obj) + && !SP_IS_FLOWDIV(obj) && !SP_IS_FLOWPARA(obj) && !SP_IS_FLOWTSPAN(obj)) + continue; + + SPStyle *style = SP_OBJECT_STYLE (obj); + if (!style) continue; + + texts ++; + + if (style_res->text->font_family.value && style->text->font_family.value && + strcmp (style_res->text->font_family.value, style->text->font_family.value)) { + different = true; // different fonts + } + + if (style_res->text->font_family.value) { + g_free(style_res->text->font_family.value); + style_res->text->font_family.value = NULL; + } + + style_res->text->font_family.set = TRUE; + style_res->text->font_family.value = g_strdup(style->text->font_family.value); + } + + if (texts == 0 || !style_res->text->font_family.set) + return QUERY_STYLE_NOTHING; + + if (texts > 1) { + if (different) { + return QUERY_STYLE_MULTIPLE_DIFFERENT; + } else { + return QUERY_STYLE_MULTIPLE_SAME; + } + } else { + return QUERY_STYLE_SINGLE; + } +} + +/** + * Query the given list of objects for the given property, write + * the result to style, return appropriate flag. + */ +int +sp_desktop_query_style_from_list (GSList *list, SPStyle *style, int property) +{ + if (property == QUERY_STYLE_PROPERTY_FILL) { + return objects_query_fillstroke (list, style, true); + } else if (property == QUERY_STYLE_PROPERTY_STROKE) { + return objects_query_fillstroke (list, style, false); + + } else if (property == QUERY_STYLE_PROPERTY_STROKEWIDTH) { + return objects_query_strokewidth (list, style); + } else if (property == QUERY_STYLE_PROPERTY_STROKEMITERLIMIT) { + return objects_query_miterlimit (list, style); + } else if (property == QUERY_STYLE_PROPERTY_STROKECAP) { + return objects_query_strokecap (list, style); + } else if (property == QUERY_STYLE_PROPERTY_STROKEJOIN) { + return objects_query_strokejoin (list, style); + + } else if (property == QUERY_STYLE_PROPERTY_MASTEROPACITY) { + return objects_query_opacity (list, style); + + } else if (property == QUERY_STYLE_PROPERTY_FONTFAMILY) { + return objects_query_fontfamily (list, style); + } else if (property == QUERY_STYLE_PROPERTY_FONTSTYLE) { + return objects_query_fontstyle (list, style); + } else if (property == QUERY_STYLE_PROPERTY_FONTNUMBERS) { + return objects_query_fontnumbers (list, style); + } + + return QUERY_STYLE_NOTHING; +} + + +/** + * Query the subselection (if any) or selection on the given desktop for the given property, write + * the result to style, return appropriate flag. + */ +int +sp_desktop_query_style(SPDesktop *desktop, SPStyle *style, int property) +{ + int ret = desktop->_query_style_signal.emit(style, property); + + if (ret != QUERY_STYLE_NOTHING) + return ret; // subselection returned a style, pass it on + + // otherwise, do querying and averaging over selection + return sp_desktop_query_style_from_list ((GSList *) desktop->selection->itemList(), style, property); +} + +/** + * Do the same as sp_desktop_query_style for all (defined) style properties, return true if none of + * the properties returned QUERY_STYLE_NOTHING. + */ +bool +sp_desktop_query_style_all (SPDesktop *desktop, SPStyle *query) +{ + int result_family = sp_desktop_query_style (desktop, query, QUERY_STYLE_PROPERTY_FONTFAMILY); + int result_fstyle = sp_desktop_query_style (desktop, query, QUERY_STYLE_PROPERTY_FONTSTYLE); + int result_fnumbers = sp_desktop_query_style (desktop, query, QUERY_STYLE_PROPERTY_FONTNUMBERS); + int result_fill = sp_desktop_query_style (desktop, query, QUERY_STYLE_PROPERTY_FILL); + int result_stroke = sp_desktop_query_style (desktop, query, QUERY_STYLE_PROPERTY_STROKE); + int result_strokewidth = sp_desktop_query_style (desktop, query, QUERY_STYLE_PROPERTY_STROKEWIDTH); + int result_strokemiterlimit = sp_desktop_query_style (desktop, query, QUERY_STYLE_PROPERTY_STROKEMITERLIMIT); + int result_strokecap = sp_desktop_query_style (desktop, query, QUERY_STYLE_PROPERTY_STROKECAP); + int result_strokejoin = sp_desktop_query_style (desktop, query, QUERY_STYLE_PROPERTY_STROKEJOIN); + int result_opacity = sp_desktop_query_style (desktop, query, QUERY_STYLE_PROPERTY_MASTEROPACITY); + + return (result_family != QUERY_STYLE_NOTHING && result_fstyle != QUERY_STYLE_NOTHING && result_fnumbers != QUERY_STYLE_NOTHING && result_fill != QUERY_STYLE_NOTHING && result_stroke != QUERY_STYLE_NOTHING && result_opacity != QUERY_STYLE_NOTHING && result_strokewidth != QUERY_STYLE_NOTHING && result_strokemiterlimit != QUERY_STYLE_NOTHING && result_strokecap != QUERY_STYLE_NOTHING && result_strokejoin != QUERY_STYLE_NOTHING); +} + + +/* + 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 : diff --git a/src/desktop-style.h b/src/desktop-style.h new file mode 100644 index 000000000..3ebf4f238 --- /dev/null +++ b/src/desktop-style.h @@ -0,0 +1,87 @@ +#ifndef __SP_DESKTOP_STYLE_H__ +#define __SP_DESKTOP_STYLE_H__ + +/* + * Desktop style management + * + * Authors: + * bulia byak + * + * Copyright (C) 2004 authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include + +class ColorRGBA; +struct SPCSSAttr; +struct SPDesktop; +struct SPObject; +struct SPStyle; +namespace Inkscape { +namespace XML { +struct Node; +} +} + +enum { // what kind of a style the query is returning + QUERY_STYLE_NOTHING, // nothing was queried - e.g. no selection + QUERY_STYLE_SINGLE, // single object was queried + QUERY_STYLE_MULTIPLE_SAME, // multiple objects were queried, the results were the same + QUERY_STYLE_MULTIPLE_DIFFERENT, // multiple objects were queried, the results could NOT be meaningfully averaged + QUERY_STYLE_MULTIPLE_AVERAGED // multiple objects were queried, the results were meaningfully averaged +}; + +enum { // which property was queried (add when you need more) + QUERY_STYLE_PROPERTY_EVERYTHING, + QUERY_STYLE_PROPERTY_FILL, // fill, fill-opacity + QUERY_STYLE_PROPERTY_STROKE, // stroke, stroke-opacity + QUERY_STYLE_PROPERTY_STROKEWIDTH, // stroke-width + QUERY_STYLE_PROPERTY_STROKEMITERLIMIT, // miter limit + QUERY_STYLE_PROPERTY_STROKEJOIN, // stroke join + QUERY_STYLE_PROPERTY_STROKECAP, // stroke cap + QUERY_STYLE_PROPERTY_STROKESTYLE, // markers, dasharray, miterlimit, stroke-width, stroke-cap, stroke-join + QUERY_STYLE_PROPERTY_FONTFAMILY, // font-family + QUERY_STYLE_PROPERTY_FONTSTYLE, // font style + QUERY_STYLE_PROPERTY_FONTNUMBERS, // size, spacings + QUERY_STYLE_PROPERTY_MASTEROPACITY // opacity +}; + +void sp_desktop_apply_css_recursive(SPObject *o, SPCSSAttr *css, bool skip_lines); +void sp_desktop_set_color(SPDesktop *desktop, ColorRGBA const &color, bool is_relative, bool fill); +void sp_desktop_set_style(SPDesktop *desktop, SPCSSAttr *css, bool change = true, bool write_current = true); +SPCSSAttr *sp_desktop_get_style(SPDesktop *desktop, bool with_text); +guint32 sp_desktop_get_color (SPDesktop *desktop, bool is_fill); +double sp_desktop_get_font_size_tool (SPDesktop *desktop); +void sp_desktop_apply_style_tool(SPDesktop *desktop, Inkscape::XML::Node *repr, char const *tool, bool with_text); + +gdouble stroke_average_width (GSList const *objects); + +int objects_query_fillstroke (GSList *objects, SPStyle *style_res, bool const isfill); +int objects_query_fontnumbers (GSList *objects, SPStyle *style_res); +int objects_query_fontstyle (GSList *objects, SPStyle *style_res); +int objects_query_fontfamily (GSList *objects, SPStyle *style_res); +int objects_query_opacity (GSList *objects, SPStyle *style_res); +int objects_query_strokewidth (GSList *objects, SPStyle *style_res); +int objects_query_miterlimit (GSList *objects, SPStyle *style_res); +int objects_query_strokecap (GSList *objects, SPStyle *style_res); +int objects_query_strokejoin (GSList *objects, SPStyle *style_res); + +int sp_desktop_query_style_from_list (GSList *list, SPStyle *style, int property); +int sp_desktop_query_style(SPDesktop *desktop, SPStyle *style, int property); +bool sp_desktop_query_style_all (SPDesktop *desktop, SPStyle *query); + +#endif + + +/* + 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:textwidth=99 : diff --git a/src/desktop.cpp b/src/desktop.cpp new file mode 100644 index 000000000..9a2274bea --- /dev/null +++ b/src/desktop.cpp @@ -0,0 +1,1400 @@ +#define __SP_DESKTOP_C__ + +/** \file + * Editable view implementation + * + * Authors: + * Lauris Kaplinski + * MenTaLguY + * bulia byak + * Ralf Stephan + * + * Copyright (C) 2004 MenTaLguY + * Copyright (C) 1999-2002 Lauris Kaplinski + * Copyright (C) 2000-2001 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +/** \class SPDesktop + * SPDesktop is a subclass of View, implementing an editable document + * canvas. It is extensively used by many UI controls that need certain + * visual representations of their own. + * + * SPDesktop provides a certain set of SPCanvasItems, serving as GUI + * layers of different control objects. The one containing the whole + * document is the drawing layer. In addition to it, there are grid, + * guide, sketch and control layers. The sketch layer is used for + * temporary drawing objects, before the real objects in document are + * created. The control layer contains editing knots, rubberband and + * similar non-document UI objects. + * + * Each SPDesktop is associated with a SPNamedView node of the document + * tree. Currently, all desktops are created from a single main named + * view, but in the future there may be support for different ones. + * SPNamedView serves as an in-document container for desktop-related + * data, like grid and guideline placement, snapping options and so on. + * + * Associated with each SPDesktop are the two most important editing + * related objects - SPSelection and SPEventContext. + * + * Sodipodi keeps track of the active desktop and invokes notification + * signals whenever it changes. UI elements can use these to update their + * display to the selection of the currently active editing window. + * (Lauris Kaplinski) + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "macros.h" +#include "inkscape-private.h" +#include "desktop.h" +#include "desktop-events.h" +#include "desktop-handles.h" +#include "document.h" +#include "message-stack.h" +#include "selection.h" +#include "select-context.h" +#include "sp-namedview.h" +#include "color.h" +#include "sp-item-group.h" +#include "prefs-utils.h" +#include "object-hierarchy.h" +#include "helper/units.h" +#include "display/canvas-arena.h" +#include "display/nr-arena.h" +#include "display/gnome-canvas-acetate.h" +#include "display/sodipodi-ctrlrect.h" +#include "display/sp-canvas-util.h" +#include "libnr/nr-matrix-div.h" +#include "libnr/nr-rect-ops.h" +#include "ui/dialog/dialog-manager.h" +#include "xml/repr.h" +#include "message-context.h" + +#ifdef WITH_INKBOARD +#include "jabber_whiteboard/session-manager.h" +#endif + +namespace Inkscape { namespace XML { class Node; }} + +// Callback declarations +static void _onSelectionChanged (Inkscape::Selection *selection, SPDesktop *desktop); +static gint _arena_handler (SPCanvasArena *arena, NRArenaItem *ai, GdkEvent *event, SPDesktop *desktop); +static void _layer_activated(SPObject *layer, SPDesktop *desktop); +static void _layer_deactivated(SPObject *layer, SPDesktop *desktop); +static void _layer_hierarchy_changed(SPObject *top, SPObject *bottom, SPDesktop *desktop); +static void _reconstruction_start(SPDesktop * desktop); +static void _reconstruction_finish(SPDesktop * desktop); +static void _namedview_modified (SPNamedView *nv, guint flags, SPDesktop *desktop); +static void _update_snap_distances (SPDesktop *desktop); + +/** + * Return new desktop object. + * \pre namedview != NULL. + * \pre canvas != NULL. + */ +SPDesktop::SPDesktop() +{ + _dlg_mgr = NULL; + _widget = 0; + namedview = NULL; + selection = NULL; + acetate = NULL; + main = NULL; + grid = NULL; + guides = NULL; + drawing = NULL; + sketch = NULL; + controls = NULL; + event_context = 0; + + _d2w.set_identity(); + _w2d.set_identity(); + _doc2dt = NR::Matrix(NR::scale(1, -1)); + + guides_active = false; + + zooms_past = NULL; + zooms_future = NULL; + + is_fullscreen = false; + + gr_item = NULL; + gr_point_num = 0; + gr_fill_or_stroke = true; + + _layer_hierarchy = NULL; + _active = false; + + selection = Inkscape::GC::release (new Inkscape::Selection (this)); +} + +void +SPDesktop::init (SPNamedView *nv, SPCanvas *aCanvas) + +{ + _guides_message_context = new Inkscape::MessageContext(const_cast(messageStack())); + + current = sp_repr_css_attr_inherited (inkscape_get_repr (INKSCAPE, "desktop"), "style"); + + namedview = nv; + canvas = aCanvas; + + SPDocument *document = SP_OBJECT_DOCUMENT (namedview); + /* Kill flicker */ + sp_document_ensure_up_to_date (document); + + /* Setup Dialog Manager */ + _dlg_mgr = new Inkscape::UI::Dialog::DialogManager(); + + dkey = sp_item_display_key_new (1); + + /* Connect document */ + setDocument (document); + + number = namedview->getViewCount(); + + + /* Setup Canvas */ + g_object_set_data (G_OBJECT (canvas), "SPDesktop", this); + + SPCanvasGroup *root = sp_canvas_root (canvas); + + /* Setup adminstrative layers */ + acetate = sp_canvas_item_new (root, GNOME_TYPE_CANVAS_ACETATE, NULL); + g_signal_connect (G_OBJECT (acetate), "event", G_CALLBACK (sp_desktop_root_handler), this); + main = (SPCanvasGroup *) sp_canvas_item_new (root, SP_TYPE_CANVAS_GROUP, NULL); + g_signal_connect (G_OBJECT (main), "event", G_CALLBACK (sp_desktop_root_handler), this); + + table = sp_canvas_item_new (main, SP_TYPE_CTRLRECT, NULL); + SP_CTRLRECT(table)->setRectangle(NR::Rect(NR::Point(-80000, -80000), NR::Point(80000, 80000))); + SP_CTRLRECT(table)->setColor(0x00000000, true, 0x00000000); + sp_canvas_item_move_to_z (table, 0); + + page = sp_canvas_item_new (main, SP_TYPE_CTRLRECT, NULL); + ((CtrlRect *) page)->setColor(0x00000000, FALSE, 0x00000000); + page_border = sp_canvas_item_new (main, SP_TYPE_CTRLRECT, NULL); + + drawing = sp_canvas_item_new (main, SP_TYPE_CANVAS_ARENA, NULL); + g_signal_connect (G_OBJECT (drawing), "arena_event", G_CALLBACK (_arena_handler), this); + + SP_CANVAS_ARENA (drawing)->arena->delta = prefs_get_double_attribute ("options.cursortolerance", "value", 1.0); // default is 1 px + + // Start always in normal mode + SP_CANVAS_ARENA (drawing)->arena->rendermode = RENDERMODE_NORMAL; + canvas->rendermode = RENDERMODE_NORMAL; // canvas needs that for choosing the best buffer size + + grid = (SPCanvasGroup *) sp_canvas_item_new (main, SP_TYPE_CANVAS_GROUP, NULL); + guides = (SPCanvasGroup *) sp_canvas_item_new (main, SP_TYPE_CANVAS_GROUP, NULL); + sketch = (SPCanvasGroup *) sp_canvas_item_new (main, SP_TYPE_CANVAS_GROUP, NULL); + controls = (SPCanvasGroup *) sp_canvas_item_new (main, SP_TYPE_CANVAS_GROUP, NULL); + + /* Push select tool to the bottom of stack */ + /** \todo + * FIXME: this is the only call to this. Everything else seems to just + * call "set" instead of "push". Can we assume that there is only one + * context ever? + */ + push_event_context (SP_TYPE_SELECT_CONTEXT, "tools.select", SP_EVENT_CONTEXT_STATIC); + + // display rect and zoom are now handled in sp_desktop_widget_realize() + + NR::Rect const d(NR::Point(0.0, 0.0), + NR::Point(sp_document_width(document), sp_document_height(document))); + + SP_CTRLRECT(page)->setRectangle(d); + SP_CTRLRECT(page_border)->setRectangle(d); + + /* the following sets the page shadow on the canvas + It was originally set to 5, which is really cheesy! + It now is an attribute in the document's namedview. If a value of + 0 is used, then the constructor for a shadow is not initialized. + */ + + if ( namedview->pageshadow != 0 && namedview->showpageshadow ) { + SP_CTRLRECT(page_border)->setShadow(namedview->pageshadow, 0x3f3f3fff); + } + + + /* Connect event for page resize */ + _doc2dt[5] = sp_document_height (document); + sp_canvas_item_affine_absolute (SP_CANVAS_ITEM (drawing), _doc2dt); + + g_signal_connect (G_OBJECT (namedview), "modified", G_CALLBACK (_namedview_modified), this); + + + NRArenaItem *ai = sp_item_invoke_show (SP_ITEM (sp_document_root (document)), + SP_CANVAS_ARENA (drawing)->arena, + dkey, + SP_ITEM_SHOW_DISPLAY); + if (ai) { + nr_arena_item_add_child (SP_CANVAS_ARENA (drawing)->root, ai, NULL); + nr_arena_item_unref (ai); + } + + namedview->show(this); + /* Ugly hack */ + activate_guides (true); + /* Ugly hack */ + _namedview_modified (namedview, SP_OBJECT_MODIFIED_FLAG, this); + + /* Construct SessionManager + * + * SessionManager construction needs to be done after document connection + */ +#ifdef WITH_INKBOARD + _whiteboard_session_manager = new Inkscape::Whiteboard::SessionManager(this); +#endif + +/* Set up notification of rebuilding the document, this allows + for saving object related settings in the document. */ + _reconstruction_start_connection = + document->connectReconstructionStart(sigc::bind(sigc::ptr_fun(_reconstruction_start), this)); + _reconstruction_finish_connection = + document->connectReconstructionFinish(sigc::bind(sigc::ptr_fun(_reconstruction_finish), this)); + _reconstruction_old_layer_id = NULL; + + // ? + // sp_active_desktop_set (desktop); + _inkscape = INKSCAPE; + + _activate_connection = _activate_signal.connect( + sigc::bind( + sigc::ptr_fun(_onActivate), + this + ) + ); + _deactivate_connection = _deactivate_signal.connect( + sigc::bind( + sigc::ptr_fun(_onDeactivate), + this + ) + ); + + _sel_modified_connection = selection->connectModified( + sigc::bind( + sigc::ptr_fun(&_onSelectionModified), + this + ) + ); + _sel_changed_connection = selection->connectChanged( + sigc::bind( + sigc::ptr_fun(&_onSelectionChanged), + this + ) + ); + +} + + +void SPDesktop::destroy() +{ + _activate_connection.disconnect(); + _deactivate_connection.disconnect(); + _sel_modified_connection.disconnect(); + _sel_changed_connection.disconnect(); + + while (event_context) { + SPEventContext *ec = event_context; + event_context = ec->next; + sp_event_context_finish (ec); + g_object_unref (G_OBJECT (ec)); + } + + if (_layer_hierarchy) { + delete _layer_hierarchy; + } + + if (_inkscape) { + _inkscape = NULL; + } + + if (drawing) { + sp_item_invoke_hide (SP_ITEM (sp_document_root (doc())), dkey); + drawing = NULL; + } + +#ifdef WITH_INKBOARD + if (_whiteboard_session_manager) { + delete _whiteboard_session_manager; + } +#endif + + delete _guides_message_context; + _guides_message_context = NULL; + + sp_signal_disconnect_by_data (G_OBJECT (namedview), this); + + g_list_free (zooms_past); + g_list_free (zooms_future); +} + +SPDesktop::~SPDesktop() {} + +//-------------------------------------------------------------------- +/* Public methods */ + +void SPDesktop::setDisplayModeNormal() +{ + SP_CANVAS_ARENA (drawing)->arena->rendermode = RENDERMODE_NORMAL; + canvas->rendermode = RENDERMODE_NORMAL; // canvas needs that for choosing the best buffer size + sp_canvas_item_affine_absolute (SP_CANVAS_ITEM (main), _d2w); // redraw +} + +void SPDesktop::setDisplayModeOutline() +{ + SP_CANVAS_ARENA (drawing)->arena->rendermode = RENDERMODE_OUTLINE; + canvas->rendermode = RENDERMODE_OUTLINE; // canvas needs that for choosing the best buffer size + sp_canvas_item_affine_absolute (SP_CANVAS_ITEM (main), _d2w); // redraw +} + +/** + * Returns current root (=bottom) layer. + */ +SPObject *SPDesktop::currentRoot() const +{ + return _layer_hierarchy ? _layer_hierarchy->top() : NULL; +} + +/** + * Returns current top layer. + */ +SPObject *SPDesktop::currentLayer() const +{ + return _layer_hierarchy ? _layer_hierarchy->bottom() : NULL; +} + +/** + * Make \a object the top layer. + */ +void SPDesktop::setCurrentLayer(SPObject *object) { + g_return_if_fail(SP_IS_GROUP(object)); + g_return_if_fail( currentRoot() == object || currentRoot()->isAncestorOf(object)); + // printf("Set Layer to ID: %s\n", SP_OBJECT_ID(object)); + _layer_hierarchy->setBottom(object); +} + +/** + * Return layer that contains \a object. + */ +SPObject *SPDesktop::layerForObject(SPObject *object) { + g_return_val_if_fail(object != NULL, NULL); + + SPObject *root=currentRoot(); + object = SP_OBJECT_PARENT(object); + while ( object && object != root && !isLayer(object) ) { + object = SP_OBJECT_PARENT(object); + } + return object; +} + +/** + * True if object is a layer. + */ +bool SPDesktop::isLayer(SPObject *object) const { + return ( SP_IS_GROUP(object) + && ( SP_GROUP(object)->effectiveLayerMode(this->dkey) + == SPGroup::LAYER ) ); +} + +/** + * True if desktop viewport fully contains \a item's bbox. + */ +bool SPDesktop::isWithinViewport (SPItem *item) const +{ + NR::Rect const viewport = get_display_area(); + NR::Rect const bbox = sp_item_bbox_desktop(item); + return viewport.contains(bbox); +} + +/// +bool SPDesktop::itemIsHidden(SPItem const *item) const { + return item->isHidden(this->dkey); +} + +/** + * Set activate property of desktop; emit signal if changed. + */ +void +SPDesktop::set_active (bool new_active) +{ + if (new_active != _active) { + _active = new_active; + if (new_active) { + _activate_signal.emit(); + } else { + _deactivate_signal.emit(); + } + } +} + +/** + * Set activate status of current desktop's named view. + */ +void +SPDesktop::activate_guides(bool activate) +{ + guides_active = activate; + namedview->activateGuides(this, activate); +} + +/** + * Make desktop switch documents. + */ +void +SPDesktop::change_document (SPDocument *theDocument) +{ + g_return_if_fail (theDocument != NULL); + + /* unselect everything before switching documents */ + selection->clear(); + + setDocument (theDocument); + _namedview_modified (namedview, SP_OBJECT_MODIFIED_FLAG, this); + _document_replaced_signal.emit (this, theDocument); +} + +/** + * Make desktop switch event contexts. + */ +void +SPDesktop::set_event_context (GtkType type, const gchar *config) +{ + SPEventContext *ec; + while (event_context) { + ec = event_context; + sp_event_context_deactivate (ec); + event_context = ec->next; + sp_event_context_finish (ec); + g_object_unref (G_OBJECT (ec)); + } + + Inkscape::XML::Node *repr = (config) ? inkscape_get_repr (_inkscape, config) : NULL; + ec = sp_event_context_new (type, this, repr, SP_EVENT_CONTEXT_STATIC); + ec->next = event_context; + event_context = ec; + sp_event_context_activate (ec); + _event_context_changed_signal.emit (this, ec); +} + +/** + * Push event context onto desktop's context stack. + */ +void +SPDesktop::push_event_context (GtkType type, const gchar *config, unsigned int key) +{ + SPEventContext *ref, *ec; + Inkscape::XML::Node *repr; + + if (event_context && event_context->key == key) return; + ref = event_context; + while (ref && ref->next && ref->next->key != key) ref = ref->next; + if (ref && ref->next) { + ec = ref->next; + ref->next = ec->next; + sp_event_context_finish (ec); + g_object_unref (G_OBJECT (ec)); + } + + if (event_context) sp_event_context_deactivate (event_context); + repr = (config) ? inkscape_get_repr (INKSCAPE, config) : NULL; + ec = sp_event_context_new (type, this, repr, key); + ec->next = event_context; + event_context = ec; + sp_event_context_activate (ec); + _event_context_changed_signal.emit (this, ec); +} + +void +SPDesktop::set_coordinate_status (NR::Point p) { + _widget->setCoordinateStatus(p); +} + + +SPItem * +SPDesktop::item_from_list_at_point_bottom (const GSList *list, NR::Point const p) const +{ + g_return_val_if_fail (doc() != NULL, NULL); + return sp_document_item_from_list_at_point_bottom (dkey, SP_GROUP (doc()->root), list, p); +} + +SPItem * +SPDesktop::item_at_point (NR::Point const p, bool into_groups, SPItem *upto) const +{ + g_return_val_if_fail (doc() != NULL, NULL); + return sp_document_item_at_point (doc(), dkey, p, into_groups, upto); +} + +SPItem * +SPDesktop::group_at_point (NR::Point const p) const +{ + g_return_val_if_fail (doc() != NULL, NULL); + return sp_document_group_at_point (doc(), dkey, p); +} + +/** + * \brief Returns the mouse point in document coordinates; if mouse is + * outside the canvas, returns the center of canvas viewpoint + */ +NR::Point +SPDesktop::point() const +{ + NR::Point p = _widget->getPointer(); + NR::Point pw = sp_canvas_window_to_world (canvas, p); + p = w2d(pw); + + NR::Rect const r = canvas->getViewbox(); + + NR::Point r0 = w2d(r.min()); + NR::Point r1 = w2d(r.max()); + + if (p[NR::X] >= r0[NR::X] && + p[NR::X] <= r1[NR::X] && + p[NR::Y] >= r1[NR::Y] && + p[NR::Y] <= r0[NR::Y]) + { + return p; + } else { + return (r0 + r1) / 2; + } +} + +/** + * Put current zoom data in history list. + */ +void +SPDesktop::push_current_zoom (GList **history) +{ + NR::Rect const area = get_display_area(); + + NRRect *old_zoom = g_new(NRRect, 1); + old_zoom->x0 = area.min()[NR::X]; + old_zoom->x1 = area.max()[NR::X]; + old_zoom->y0 = area.min()[NR::Y]; + old_zoom->y1 = area.max()[NR::Y]; + if ( *history == NULL + || !( ( ((NRRect *) ((*history)->data))->x0 == old_zoom->x0 ) && + ( ((NRRect *) ((*history)->data))->x1 == old_zoom->x1 ) && + ( ((NRRect *) ((*history)->data))->y0 == old_zoom->y0 ) && + ( ((NRRect *) ((*history)->data))->y1 == old_zoom->y1 ) ) ) + { + *history = g_list_prepend (*history, old_zoom); + } +} + +/** + * Set viewbox. + */ +void +SPDesktop::set_display_area (double x0, double y0, double x1, double y1, double border, bool log) +{ + g_assert(_widget); + + // save the zoom + if (log) { + push_current_zoom(&zooms_past); + // if we do a logged zoom, our zoom-forward list is invalidated, so delete it + g_list_free (zooms_future); + zooms_future = NULL; + } + + double const cx = 0.5 * (x0 + x1); + double const cy = 0.5 * (y0 + y1); + + NR::Rect const viewbox = NR::expand(canvas->getViewbox(), border); + + double scale = expansion(_d2w); + double newscale; + if (((x1 - x0) * viewbox.dimensions()[NR::Y]) > ((y1 - y0) * viewbox.dimensions()[NR::X])) { + newscale = viewbox.dimensions()[NR::X] / (x1 - x0); + } else { + newscale = viewbox.dimensions()[NR::Y] / (y1 - y0); + } + + newscale = CLAMP(newscale, SP_DESKTOP_ZOOM_MIN, SP_DESKTOP_ZOOM_MAX); + + int clear = FALSE; + if (!NR_DF_TEST_CLOSE (newscale, scale, 1e-4 * scale)) { + /* Set zoom factors */ + _d2w = NR::Matrix(NR::scale(newscale, -newscale)); + _w2d = NR::Matrix(NR::scale(1/newscale, 1/-newscale)); + sp_canvas_item_affine_absolute(SP_CANVAS_ITEM(main), _d2w); + clear = TRUE; + } + + /* Calculate top left corner */ + x0 = cx - 0.5 * viewbox.dimensions()[NR::X] / newscale; + y1 = cy + 0.5 * viewbox.dimensions()[NR::Y] / newscale; + + /* Scroll */ + sp_canvas_scroll_to (canvas, x0 * newscale - border, y1 * -newscale - border, clear); + + _widget->updateRulers(); + _widget->updateScrollbars(expansion(_d2w)); + _widget->updateZoom(); +} + +void SPDesktop::set_display_area(NR::Rect const &a, NR::Coord b, bool log) +{ + set_display_area(a.min()[NR::X], a.min()[NR::Y], a.max()[NR::X], a.max()[NR::Y], b, log); +} + +/** + * Return viewbox dimensions. + */ +NR::Rect SPDesktop::get_display_area() const +{ + NR::Rect const viewbox = canvas->getViewbox(); + + double const scale = _d2w[0]; + + return NR::Rect(NR::Point(viewbox.min()[NR::X] / scale, viewbox.max()[NR::Y] / -scale), + NR::Point(viewbox.max()[NR::X] / scale, viewbox.min()[NR::Y] / -scale)); +} + +/** + * Revert back to previous zoom if possible. + */ +void +SPDesktop::prev_zoom() +{ + if (zooms_past == NULL) { + messageStack()->flash(Inkscape::WARNING_MESSAGE, _("No previous zoom.")); + return; + } + + // push current zoom into forward zooms list + push_current_zoom (&zooms_future); + + // restore previous zoom + set_display_area (((NRRect *) zooms_past->data)->x0, + ((NRRect *) zooms_past->data)->y0, + ((NRRect *) zooms_past->data)->x1, + ((NRRect *) zooms_past->data)->y1, + 0, false); + + // remove the just-added zoom from the past zooms list + zooms_past = g_list_remove (zooms_past, ((NRRect *) zooms_past->data)); +} + +/** + * Set zoom to next in list. + */ +void +SPDesktop::next_zoom() +{ + if (zooms_future == NULL) { + this->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("No next zoom.")); + return; + } + + // push current zoom into past zooms list + push_current_zoom (&zooms_past); + + // restore next zoom + set_display_area (((NRRect *) zooms_future->data)->x0, + ((NRRect *) zooms_future->data)->y0, + ((NRRect *) zooms_future->data)->x1, + ((NRRect *) zooms_future->data)->y1, + 0, false); + + // remove the just-used zoom from the zooms_future list + zooms_future = g_list_remove (zooms_future, ((NRRect *) zooms_future->data)); +} + +/** + * Zoom to point with absolute zoom factor. + */ +void +SPDesktop::zoom_absolute_keep_point (double cx, double cy, double px, double py, double zoom) +{ + zoom = CLAMP (zoom, SP_DESKTOP_ZOOM_MIN, SP_DESKTOP_ZOOM_MAX); + + // maximum or minimum zoom reached, but there's no exact equality because of rounding errors; + // this check prevents "sliding" when trying to zoom in at maximum zoom; + /// \todo someone please fix calculations properly and remove this hack + if (fabs(expansion(_d2w) - zoom) < 0.0001*zoom && (fabs(SP_DESKTOP_ZOOM_MAX - zoom) < 0.01 || fabs(SP_DESKTOP_ZOOM_MIN - zoom) < 0.000001)) + return; + + NR::Rect const viewbox = canvas->getViewbox(); + + double const width2 = viewbox.dimensions()[NR::X] / zoom; + double const height2 = viewbox.dimensions()[NR::Y] / zoom; + + set_display_area(cx - px * width2, + cy - py * height2, + cx + (1 - px) * width2, + cy + (1 - py) * height2, + 0.0); +} + +/** + * Zoom to center with absolute zoom factor. + */ +void +SPDesktop::zoom_absolute (double cx, double cy, double zoom) +{ + zoom_absolute_keep_point (cx, cy, 0.5, 0.5, zoom); +} + +/** + * Zoom to point with relative zoom factor. + */ +void +SPDesktop::zoom_relative_keep_point (double cx, double cy, double zoom) +{ + NR::Rect const area = get_display_area(); + + if (cx < area.min()[NR::X]) { + cx = area.min()[NR::X]; + } + if (cx > area.max()[NR::X]) { + cx = area.max()[NR::X]; + } + if (cy < area.min()[NR::Y]) { + cy = area.min()[NR::Y]; + } + if (cy > area.max()[NR::Y]) { + cy = area.max()[NR::Y]; + } + + gdouble const scale = expansion(_d2w) * zoom; + double const px = (cx - area.min()[NR::X]) / area.dimensions()[NR::X]; + double const py = (cy - area.min()[NR::Y]) / area.dimensions()[NR::Y]; + + zoom_absolute_keep_point(cx, cy, px, py, scale); +} + +/** + * Zoom to center with relative zoom factor. + */ +void +SPDesktop::zoom_relative (double cx, double cy, double zoom) +{ + gdouble scale = expansion(_d2w) * zoom; + zoom_absolute (cx, cy, scale); +} + +/** + * Set display area to origin and current document dimensions. + */ +void +SPDesktop::zoom_page() +{ + NR::Rect d(NR::Point(0, 0), + NR::Point(sp_document_width(doc()), sp_document_height(doc()))); + + if (d.dimensions()[NR::X] < 1.0 || d.dimensions()[NR::Y] < 1.0) { + return; + } + + set_display_area(d, 10); +} + +/** + * Set display area to current document width. + */ +void +SPDesktop::zoom_page_width() +{ + NR::Rect const a = get_display_area(); + + if (sp_document_width(doc()) < 1.0) { + return; + } + + NR::Rect d(NR::Point(0, a.midpoint()[NR::Y]), + NR::Point(sp_document_width(doc()), a.midpoint()[NR::Y])); + + set_display_area(d, 10); +} + +/** + * Zoom to selection. + */ +void +SPDesktop::zoom_selection() +{ + NR::Rect const d = selection->bounds(); + + if (d.dimensions()[NR::X] < 0.1 || d.dimensions()[NR::Y] < 0.1) { + return; + } + + set_display_area(d, 10); +} + +/** + * Tell widget to let zoom widget grab keyboard focus. + */ +void +SPDesktop::zoom_grab_focus() +{ + _widget->letZoomGrabFocus(); +} + +/** + * Zoom to whole drawing. + */ +void +SPDesktop::zoom_drawing() +{ + g_return_if_fail (doc() != NULL); + SPItem *docitem = SP_ITEM (sp_document_root (doc())); + g_return_if_fail (docitem != NULL); + + NR::Rect d = sp_item_bbox_desktop(docitem); + + /* Note that the second condition here indicates that + ** there are no items in the drawing. + */ + if ( d.dimensions()[NR::X] < 1.0 || d.dimensions()[NR::Y] < 1.0 ) { + return; + } + + set_display_area(d, 10); +} + +/** + * Scroll canvas by specific coordinate amount. + */ +void +SPDesktop::scroll_world (double dx, double dy) +{ + g_assert(_widget); + + NR::Rect const viewbox = canvas->getViewbox(); + + sp_canvas_scroll_to(canvas, viewbox.min()[NR::X] - dx, viewbox.min()[NR::Y] - dy, FALSE); + + _widget->updateRulers(); + _widget->updateScrollbars(expansion(_d2w)); +} + +bool +SPDesktop::scroll_to_point (NR::Point const *p, gdouble autoscrollspeed) +{ + gdouble autoscrolldistance = (gdouble) prefs_get_int_attribute_limited ("options.autoscrolldistance", "value", 0, -1000, 10000); + + // autoscrolldistance is in screen pixels, but the display area is in document units + autoscrolldistance /= expansion(_d2w); + NR::Rect const dbox = NR::expand(get_display_area(), -autoscrolldistance); + + if (!((*p)[NR::X] > dbox.min()[NR::X] && (*p)[NR::X] < dbox.max()[NR::X]) || + !((*p)[NR::Y] > dbox.min()[NR::Y] && (*p)[NR::Y] < dbox.max()[NR::Y]) ) { + + NR::Point const s_w( (*p) * _d2w ); + + gdouble x_to; + if ((*p)[NR::X] < dbox.min()[NR::X]) + x_to = dbox.min()[NR::X]; + else if ((*p)[NR::X] > dbox.max()[NR::X]) + x_to = dbox.max()[NR::X]; + else + x_to = (*p)[NR::X]; + + gdouble y_to; + if ((*p)[NR::Y] < dbox.min()[NR::Y]) + y_to = dbox.min()[NR::Y]; + else if ((*p)[NR::Y] > dbox.max()[NR::Y]) + y_to = dbox.max()[NR::Y]; + else + y_to = (*p)[NR::Y]; + + NR::Point const d_dt(x_to, y_to); + NR::Point const d_w( d_dt * _d2w ); + NR::Point const moved_w( d_w - s_w ); + + if (autoscrollspeed == 0) + autoscrollspeed = prefs_get_double_attribute_limited ("options.autoscrollspeed", "value", 1, 0, 10); + + if (autoscrollspeed != 0) + scroll_world (autoscrollspeed * moved_w); + + return true; + } + return false; +} + +void +SPDesktop::fullscreen() +{ + _widget->setFullscreen(); +} + +void +SPDesktop::getWindowGeometry (gint &x, gint &y, gint &w, gint &h) +{ + _widget->getGeometry (x, y, w, h); +} + +void +SPDesktop::setWindowPosition (NR::Point p) +{ + _widget->setPosition (p); +} + +void +SPDesktop::setWindowSize (gint w, gint h) +{ + _widget->setSize (w, h); +} + +void +SPDesktop::setWindowTransient (void *p, int transient_policy) +{ + _widget->setTransient (p, transient_policy); +} + +void +SPDesktop::presentWindow() +{ + _widget->present(); +} + +bool +SPDesktop::warnDialog (gchar *text) +{ + return _widget->warnDialog (text); +} + +void +SPDesktop::toggleRulers() +{ + _widget->toggleRulers(); +} + +void +SPDesktop::toggleScrollbars() +{ + _widget->toggleScrollbars(); +} + +void +SPDesktop::layoutWidget() +{ + _widget->layout(); +} + +void +SPDesktop::destroyWidget() +{ + _widget->destroy(); +} + +bool +SPDesktop::shutdown() +{ + return _widget->shutdown(); +} + +void +SPDesktop::setToolboxFocusTo (gchar const *label) +{ + _widget->setToolboxFocusTo (label); +} + +void +SPDesktop::setToolboxAdjustmentValue (gchar const* id, double val) +{ + _widget->setToolboxAdjustmentValue (id, val); +} + +bool +SPDesktop::isToolboxButtonActive (gchar const *id) +{ + return _widget->isToolboxButtonActive (id); +} + +void +SPDesktop::emitToolSubselectionChanged(gpointer data) +{ + _tool_subselection_changed.emit(data); + inkscape_subselection_changed (this); +} + +//---------------------------------------------------------------------- +// Callback implementations. The virtual ones are connected by the view. + +void +SPDesktop::onPositionSet (double x, double y) +{ + _widget->viewSetPosition (NR::Point(x,y)); +} + +void +SPDesktop::onResized (double x, double y) +{ + // Nothing called here +} + +/** + * Redraw callback; queues Gtk redraw; connected by View. + */ +void +SPDesktop::onRedrawRequested () +{ + if (main) { + _widget->requestCanvasUpdate(); + } +} + +/** + * Associate document with desktop. + */ +void +SPDesktop::setDocument (SPDocument *doc) +{ + if (this->doc() && doc) { + namedview->hide(this); + sp_item_invoke_hide (SP_ITEM (sp_document_root (this->doc())), dkey); + } + + if (_layer_hierarchy) { + _layer_hierarchy->clear(); + delete _layer_hierarchy; + } + _layer_hierarchy = new Inkscape::ObjectHierarchy(NULL); + _layer_hierarchy->connectAdded(sigc::bind(sigc::ptr_fun(_layer_activated), this)); + _layer_hierarchy->connectRemoved(sigc::bind(sigc::ptr_fun(_layer_deactivated), this)); + _layer_hierarchy->connectChanged(sigc::bind(sigc::ptr_fun(_layer_hierarchy_changed), this)); + _layer_hierarchy->setTop(SP_DOCUMENT_ROOT(doc)); + + /// \todo fixme: This condition exists to make sure the code + /// inside is called only once on initialization. But there + /// are surely more safe methods to accomplish this. + if (drawing) { + NRArenaItem *ai; + + namedview = sp_document_namedview (doc, NULL); + g_signal_connect (G_OBJECT (namedview), "modified", G_CALLBACK (_namedview_modified), this); + number = namedview->getViewCount(); + + ai = sp_item_invoke_show (SP_ITEM (sp_document_root (doc)), + SP_CANVAS_ARENA (drawing)->arena, + dkey, + SP_ITEM_SHOW_DISPLAY); + if (ai) { + nr_arena_item_add_child (SP_CANVAS_ARENA (drawing)->root, ai, NULL); + nr_arena_item_unref (ai); + } + namedview->show(this); + /* Ugly hack */ + activate_guides (true); + /* Ugly hack */ + _namedview_modified (namedview, SP_OBJECT_MODIFIED_FLAG, this); + } + + _document_replaced_signal.emit (this, doc); + + View::setDocument (doc); +} + +void +SPDesktop::onStatusMessage +(Inkscape::MessageType type, gchar const *message) +{ + if (_widget) { + _widget->setMessage(type, message); + } +} + +void +SPDesktop::onDocumentURISet (gchar const* uri) +{ + _widget->setTitle(uri); +} + +/** + * Resized callback. + */ +void +SPDesktop::onDocumentResized (gdouble width, gdouble height) +{ + _doc2dt[5] = height; + sp_canvas_item_affine_absolute (SP_CANVAS_ITEM (drawing), _doc2dt); + NR::Rect const a(NR::Point(0, 0), NR::Point(width, height)); + SP_CTRLRECT(page)->setRectangle(a); + SP_CTRLRECT(page_border)->setRectangle(a); +} + + +void +SPDesktop::_onActivate (SPDesktop* dt) +{ + if (!dt->_widget) return; + dt->_widget->activateDesktop(); +} + +void +SPDesktop::_onDeactivate (SPDesktop* dt) +{ + if (!dt->_widget) return; + dt->_widget->deactivateDesktop(); +} + +void +SPDesktop::_onSelectionModified +(Inkscape::Selection *selection, guint flags, SPDesktop *dt) +{ + if (!dt->_widget) return; + dt->_widget->updateScrollbars (expansion(dt->_d2w)); +} + +static void +_onSelectionChanged +(Inkscape::Selection *selection, SPDesktop *desktop) +{ + /** \todo + * only change the layer for single selections, or what? + * This seems reasonable -- for multiple selections there can be many + * different layers involved. + */ + SPItem *item=selection->singleItem(); + if (item) { + SPObject *layer=desktop->layerForObject(item); + if ( layer && layer != desktop->currentLayer() ) { + desktop->setCurrentLayer(layer); + } + } +} + +/** + * Calls event handler of current event context. + * \param arena Unused + * \todo fixme + */ +static gint +_arena_handler (SPCanvasArena *arena, NRArenaItem *ai, GdkEvent *event, SPDesktop *desktop) +{ + if (ai) { + SPItem *spi = (SPItem*)NR_ARENA_ITEM_GET_DATA (ai); + return sp_event_context_item_handler (desktop->event_context, spi, event); + } else { + return sp_event_context_root_handler (desktop->event_context, event); + } +} + +static void +_layer_activated(SPObject *layer, SPDesktop *desktop) { + g_return_if_fail(SP_IS_GROUP(layer)); + SP_GROUP(layer)->setLayerDisplayMode(desktop->dkey, SPGroup::LAYER); +} + +/// Callback +static void +_layer_deactivated(SPObject *layer, SPDesktop *desktop) { + g_return_if_fail(SP_IS_GROUP(layer)); + SP_GROUP(layer)->setLayerDisplayMode(desktop->dkey, SPGroup::GROUP); +} + +/// Callback +static void +_layer_hierarchy_changed(SPObject *top, SPObject *bottom, + SPDesktop *desktop) +{ + desktop->_layer_changed_signal.emit (bottom); +} + +/// Called when document is starting to be rebuilt. +static void +_reconstruction_start (SPDesktop * desktop) +{ + // printf("Desktop, starting reconstruction\n"); + desktop->_reconstruction_old_layer_id = g_strdup(SP_OBJECT_ID(desktop->currentLayer())); + desktop->_layer_hierarchy->setBottom(desktop->currentRoot()); + + /* + GSList const * selection_objs = desktop->selection->list(); + for (; selection_objs != NULL; selection_objs = selection_objs->next) { + + } + */ + desktop->selection->clear(); + + // printf("Desktop, starting reconstruction end\n"); +} + +/// Called when document rebuild is finished. +static void +_reconstruction_finish (SPDesktop * desktop) +{ + // printf("Desktop, finishing reconstruction\n"); + if (desktop->_reconstruction_old_layer_id == NULL) + return; + + SPObject * newLayer = SP_OBJECT_DOCUMENT(desktop->namedview)->getObjectById(desktop->_reconstruction_old_layer_id); + if (newLayer != NULL) + desktop->setCurrentLayer(newLayer); + + g_free(desktop->_reconstruction_old_layer_id); + desktop->_reconstruction_old_layer_id = NULL; + // printf("Desktop, finishing reconstruction end\n"); + return; +} + +/** + * Namedview_modified callback. + */ +static void +_namedview_modified (SPNamedView *nv, guint flags, SPDesktop *desktop) +{ + if (flags & SP_OBJECT_MODIFIED_FLAG) { + + /* Recalculate snap distances */ + _update_snap_distances (desktop); + + /* Show/hide page background */ + if (nv->pagecolor & 0xff) { + sp_canvas_item_show (desktop->table); + ((CtrlRect *) desktop->table)->setColor(0x00000000, true, nv->pagecolor); + sp_canvas_item_move_to_z (desktop->table, 0); + } else { + sp_canvas_item_hide (desktop->table); + } + + /* Show/hide page border */ + if (nv->showborder) { + // show + sp_canvas_item_show (desktop->page_border); + // set color and shadow + ((CtrlRect *) desktop->page_border)->setColor(nv->bordercolor, false, 0x00000000); + if (nv->pageshadow) { + ((CtrlRect *) desktop->page_border)->setShadow(nv->pageshadow, nv->bordercolor); + } + // place in the z-order stack + if (nv->borderlayer == SP_BORDER_LAYER_BOTTOM) { + sp_canvas_item_move_to_z (desktop->page_border, 2); + } else { + int order = sp_canvas_item_order (desktop->page_border); + int morder = sp_canvas_item_order (desktop->drawing); + if (morder > order) sp_canvas_item_raise (desktop->page_border, + morder - order); + } + } else { + sp_canvas_item_hide (desktop->page_border); + if (nv->pageshadow) { + ((CtrlRect *) desktop->page)->setShadow(0, 0x00000000); + } + } + + /* Show/hide page shadow */ + if (nv->showpageshadow && nv->pageshadow) { + ((CtrlRect *) desktop->page_border)->setShadow(nv->pageshadow, nv->bordercolor); + } else { + ((CtrlRect *) desktop->page_border)->setShadow(0, 0x00000000); + } + + if (SP_RGBA32_A_U(nv->pagecolor) < 128 || + (SP_RGBA32_R_U(nv->pagecolor) + + SP_RGBA32_G_U(nv->pagecolor) + + SP_RGBA32_B_U(nv->pagecolor)) >= 384) { + // the background color is light or transparent, use black outline + SP_CANVAS_ARENA (desktop->drawing)->arena->outlinecolor = 0xff; + } else { // use white outline + SP_CANVAS_ARENA (desktop->drawing)->arena->outlinecolor = 0xffffffff; + } + } +} + +/** + * Callback to reset snapper's distances. + */ +static void +_update_snap_distances (SPDesktop *desktop) +{ + SPUnit const &px = sp_unit_get_by_id(SP_UNIT_PX); + + SPNamedView &nv = *desktop->namedview; + + nv.grid_snapper.setDistance(sp_convert_distance_full(nv.gridtolerance, + *nv.gridtoleranceunit, + px)); + nv.guide_snapper.setDistance(sp_convert_distance_full(nv.guidetolerance, + *nv.guidetoleranceunit, + px)); + nv.object_snapper.setDistance(sp_convert_distance_full(nv.objecttolerance, + *nv.objecttoleranceunit, + px)); +} + + +NR::Matrix SPDesktop::w2d() const +{ + return _w2d; +} + +NR::Point SPDesktop::w2d(NR::Point const &p) const +{ + return p * _w2d; +} + +NR::Point SPDesktop::d2w(NR::Point const &p) const +{ + return p * _d2w; +} + +NR::Matrix SPDesktop::doc2dt() const +{ + return _doc2dt; +} + +NR::Point SPDesktop::doc2dt(NR::Point const &p) const +{ + return p * _doc2dt; +} + +NR::Point SPDesktop::dt2doc(NR::Point const &p) const +{ + return p / _doc2dt; +} + + +/** + * Pop event context from desktop's context stack. Never used. + */ +// void +// SPDesktop::pop_event_context (unsigned int key) +// { +// SPEventContext *ec = NULL; +// +// if (event_context && event_context->key == key) { +// g_return_if_fail (event_context); +// g_return_if_fail (event_context->next); +// ec = event_context; +// sp_event_context_deactivate (ec); +// event_context = ec->next; +// sp_event_context_activate (event_context); +// _event_context_changed_signal.emit (this, ec); +// } +// +// SPEventContext *ref = event_context; +// while (ref && ref->next && ref->next->key != key) +// ref = ref->next; +// +// if (ref && ref->next) { +// ec = ref->next; +// ref->next = ec->next; +// } +// +// if (ec) { +// sp_event_context_finish (ec); +// g_object_unref (G_OBJECT (ec)); +// } +// } + +/* + 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 : diff --git a/src/desktop.h b/src/desktop.h new file mode 100644 index 000000000..55d824e0a --- /dev/null +++ b/src/desktop.h @@ -0,0 +1,289 @@ +#ifndef __SP_DESKTOP_H__ +#define __SP_DESKTOP_H__ + +/** \file + * SPDesktop: an editable view. + * + * Author: + * Lauris Kaplinski + * Frank Felfe + * bulia byak + * Ralf Stephan + * + * Copyright (C) 1999-2005 authors + * Copyright (C) 2000-2001 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include "libnr/nr-matrix.h" +#include "libnr/nr-matrix-fns.h" +#include "libnr/nr-rect.h" +#include "ui/view/view.h" +#include "ui/view/edit-widget-interface.h" + +class NRRect; +class SPCSSAttr; +struct SPCanvas; +struct SPCanvasItem; +struct SPCanvasGroup; +struct SPDesktopWidget; +struct SPEventContext; +struct SPItem; +struct SPNamedView; +struct SPObject; +struct SPStyle; +struct SPViewWidget; + +typedef int sp_verb_t; + +namespace Inkscape { + class Application; + class MessageContext; + class Selection; + class ObjectHierarchy; + namespace UI { + namespace Dialog { + class DialogManager; + } + } + namespace Whiteboard { + class SessionManager; + } +} + +/** + * Editable view. + * + * @see \ref desktop-handles.h for desktop macros. + */ +struct SPDesktop : public Inkscape::UI::View::View +{ + Inkscape::UI::Dialog::DialogManager *_dlg_mgr; + SPNamedView *namedview; + SPCanvas *canvas; + /// current selection; will never generally be NULL + Inkscape::Selection *selection; + SPEventContext *event_context; + + SPCanvasItem *acetate; + SPCanvasGroup *main; + SPCanvasGroup *grid; + SPCanvasGroup *guides; + SPCanvasItem *drawing; + SPCanvasGroup *sketch; + SPCanvasGroup *controls; + SPCanvasItem *table; ///< outside-of-page background + SPCanvasItem *page; ///< page background + SPCanvasItem *page_border; ///< page border + SPCSSAttr *current; ///< current style + + GList *zooms_past; + GList *zooms_future; + unsigned int dkey; + unsigned int number; + bool is_fullscreen; + + /// \todo fixme: This has to be implemented in different way */ + guint guides_active : 1; + + // storage for selected dragger used by GrDrag as it's + // created and deleted by tools + SPItem *gr_item; + guint gr_point_num; + bool gr_fill_or_stroke; + + Inkscape::ObjectHierarchy *_layer_hierarchy; + gchar * _reconstruction_old_layer_id; + + sigc::signal _tool_changed; + sigc::signal _layer_changed_signal; + sigc::signal::accumulated _set_style_signal; + sigc::signal::accumulated _query_style_signal; + sigc::connection connectDocumentReplaced (const sigc::slot & slot) + { + return _document_replaced_signal.connect (slot); + } + + sigc::connection connectEventContextChanged (const sigc::slot & slot) + { + return _event_context_changed_signal.connect (slot); + } + sigc::connection connectSetStyle (const sigc::slot & slot) + { + return _set_style_signal.connect (slot); + } + sigc::connection connectQueryStyle (const sigc::slot & slot) + { + return _query_style_signal.connect (slot); + } + // subselection is some sort of selection which is specific to the tool, such as a handle in gradient tool, or a text selection + sigc::connection connectToolSubselectionChanged(const sigc::slot & slot) { + return _tool_subselection_changed.connect(slot); + } + void emitToolSubselectionChanged(gpointer data); + sigc::connection connectCurrentLayerChanged(const sigc::slot & slot) { + return _layer_changed_signal.connect(slot); + } + + // Whiteboard changes + +#ifdef WITH_INKBOARD + Inkscape::Whiteboard::SessionManager* whiteboard_session_manager() { + return _whiteboard_session_manager; + } + + Inkscape::Whiteboard::SessionManager* _whiteboard_session_manager; +#endif + + SPDesktop(); + void init (SPNamedView* nv, SPCanvas* canvas); + ~SPDesktop(); + void destroy(); + + Inkscape::MessageContext *guidesMessageContext() const { + return _guides_message_context; + } + + void setDisplayModeNormal(); + void setDisplayModeOutline(); + + void set_active (bool new_active); + SPObject *currentRoot() const; + SPObject *currentLayer() const; + void setCurrentLayer(SPObject *object); + SPObject *layerForObject(SPObject *object); + bool isLayer(SPObject *object) const; + bool isWithinViewport(SPItem *item) const; + bool itemIsHidden(SPItem const *item) const; + + void activate_guides (bool activate); + void change_document (SPDocument *document); + + void set_event_context (GtkType type, const gchar *config); + void push_event_context (GtkType type, const gchar *config, unsigned int key); + + void set_coordinate_status (NR::Point p); + SPItem *item_from_list_at_point_bottom (const GSList *list, NR::Point const p) const; + SPItem *item_at_point (NR::Point const p, bool into_groups, SPItem *upto = NULL) const; + SPItem *group_at_point (NR::Point const p) const; + NR::Point point() const; + + NR::Rect get_display_area() const; + void set_display_area (double x0, double y0, double x1, double y1, double border, bool log = true); + void set_display_area(NR::Rect const &a, NR::Coord border, bool log = true); + void zoom_absolute (double cx, double cy, double zoom); + void zoom_relative (double cx, double cy, double zoom); + void zoom_absolute_keep_point (double cx, double cy, double px, double py, double zoom); + void zoom_relative_keep_point (double cx, double cy, double zoom); + void zoom_relative_keep_point (NR::Point const &c, double const zoom) + { + using NR::X; + using NR::Y; + zoom_relative_keep_point (c[X], c[Y], zoom); + } + + void zoom_page(); + void zoom_page_width(); + void zoom_drawing(); + void zoom_selection(); + void zoom_grab_focus(); + double current_zoom() const { return _d2w.expansion(); } + void prev_zoom(); + void next_zoom(); + + bool scroll_to_point (NR::Point const *s_dt, gdouble autoscrollspeed = 0); + void scroll_world (double dx, double dy); + void scroll_world (NR::Point const scroll) + { + using NR::X; + using NR::Y; + scroll_world(scroll[X], scroll[Y]); + } + + void getWindowGeometry (gint &x, gint &y, gint &w, gint &h); + void setWindowPosition (NR::Point p); + void setWindowSize (gint w, gint h); + void setWindowTransient (void* p, int transient_policy=1); + void presentWindow(); + bool warnDialog (gchar *text); + void toggleRulers(); + void toggleScrollbars(); + void layoutWidget(); + void destroyWidget(); + void setToolboxFocusTo (gchar const* label); + void setToolboxAdjustmentValue (gchar const* id, double val); + bool isToolboxButtonActive (gchar const *id); + + void fullscreen(); + + void registerEditWidget (Inkscape::UI::View::EditWidgetInterface *widget) + { _widget = widget; } + + NR::Matrix w2d() const; + NR::Point w2d(NR::Point const &p) const; + NR::Point d2w(NR::Point const &p) const; + NR::Matrix doc2dt() const; + NR::Point doc2dt(NR::Point const &p) const; + NR::Point dt2doc(NR::Point const &p) const; + + virtual void setDocument (SPDocument* doc); + virtual bool shutdown(); + virtual void mouseover() {} + virtual void mouseout() {} + +private: + Inkscape::UI::View::EditWidgetInterface *_widget; + Inkscape::Application *_inkscape; + Inkscape::MessageContext *_guides_message_context; + bool _active; + NR::Matrix _w2d; + NR::Matrix _d2w; + NR::Matrix _doc2dt; + + void push_current_zoom (GList**); + + sigc::signal _document_replaced_signal; + sigc::signal _activate_signal; + sigc::signal _deactivate_signal; + sigc::signal _event_context_changed_signal; + sigc::signal _tool_subselection_changed; + + sigc::connection _activate_connection; + sigc::connection _deactivate_connection; + sigc::connection _sel_modified_connection; + sigc::connection _sel_changed_connection; + sigc::connection _reconstruction_start_connection; + sigc::connection _reconstruction_finish_connection; + + virtual void onPositionSet (double, double); + virtual void onResized (double, double); + virtual void onRedrawRequested(); + virtual void onStatusMessage (Inkscape::MessageType type, gchar const *message); + virtual void onDocumentURISet (gchar const* uri); + virtual void onDocumentResized (double, double); + + static void _onActivate (SPDesktop* dt); + static void _onDeactivate (SPDesktop* dt); + static void _onSelectionModified (Inkscape::Selection *selection, guint flags, SPDesktop *dt); +}; + +#endif + +/* + 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 : diff --git a/src/dialogs/.cvsignore b/src/dialogs/.cvsignore new file mode 100644 index 000000000..e8014d011 --- /dev/null +++ b/src/dialogs/.cvsignore @@ -0,0 +1,5 @@ +Makefile +Makefile.in +.deps +makefile +.dirstamp diff --git a/src/dialogs/Makefile_insert b/src/dialogs/Makefile_insert new file mode 100644 index 000000000..06ef2975c --- /dev/null +++ b/src/dialogs/Makefile_insert @@ -0,0 +1,75 @@ +## Makefile.am fragment sourced by src/Makefile.am. +# +# Several object property dialogs +# Author: Lauris Kaplinski +# +# Here should be things, that use only xml interface, not objects themselves +# Currently we still have selection_changed functions, but these will be +# replaced by selection 'changed' signal handlers +# + +dialogs/all: dialogs/libspdialogs.a + +dialogs/clean: + rm -f dialogs/libspdialogs.a $(dialogs_libspdialogs_a_OBJECTS) + +dialogs_libspdialogs_a_SOURCES = \ + dialogs/debugdialog.cpp \ + dialogs/debugdialog.h \ + dialogs/dialog-events.cpp \ + dialogs/dialog-events.h \ + dialogs/display-settings.cpp \ + dialogs/display-settings.h \ + dialogs/eek-preview.h \ + dialogs/eek-preview.cpp \ + dialogs/export.cpp \ + dialogs/export.h \ + dialogs/extensions.cpp \ + dialogs/extensions.h \ + dialogs/filedialog.cpp \ + dialogs/filedialog.h \ + dialogs/fill-style.cpp \ + dialogs/fill-style.h \ + dialogs/in-dt-coordsys.cpp \ + dialogs/in-dt-coordsys.h \ + dialogs/input.cpp \ + dialogs/input.h \ + dialogs/item-properties.cpp \ + dialogs/item-properties.h \ + dialogs/layer-properties.cpp \ + dialogs/layer-properties.h \ + dialogs/object-attributes.cpp \ + dialogs/object-attributes.h \ + dialogs/object-properties.cpp \ + dialogs/object-properties.h \ + dialogs/sp-attribute-widget.cpp \ + dialogs/sp-attribute-widget.h \ + dialogs/stroke-style.cpp \ + dialogs/stroke-style.h \ + dialogs/swatches.cpp \ + dialogs/swatches.h \ + dialogs/text-edit.cpp \ + dialogs/text-edit.h \ + dialogs/tiledialog.cpp \ + dialogs/tiledialog.h \ + dialogs/xml-tree.cpp \ + dialogs/xml-tree.h \ + dialogs/rdf.cpp \ + dialogs/rdf.h \ + dialogs/find.cpp \ + dialogs/find.h \ + dialogs/clonetiler.cpp \ + dialogs/clonetiler.h \ + dialogs/unclump.cpp \ + dialogs/unclump.h \ + dialogs/iconpreview.cpp \ + dialogs/iconpreview.h + + +# dialogs/sp-widget.c \ +# dialogs/sp-widget.h \ +# dialogs/gradient-vector.c \ +# dialogs/gradient-vector.h \ +# dialogs/gradient-selector.c \ +# dialogs/gradient-selector.h + diff --git a/src/dialogs/clonetiler.cpp b/src/dialogs/clonetiler.cpp new file mode 100644 index 000000000..72cae3c47 --- /dev/null +++ b/src/dialogs/clonetiler.cpp @@ -0,0 +1,2578 @@ +#define __SP_CLONE_TILER_C__ + +/* + * Clone tiling dialog + * + * Authors: + * bulia byak + * + * Copyright (C) 2004-2005 Authors + * Released under GNU GPL + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif +#include +#include + +#include "application/application.h" +#include "application/editor.h" +#include "helper/window.h" +#include "helper/unit-menu.h" +#include "helper/units.h" +#include "widgets/icon.h" +#include "../inkscape.h" +#include "../prefs-utils.h" +#include "dialog-events.h" +#include "../macros.h" +#include "../verbs.h" +#include "../interface.h" +#include "../selection.h" +#include "../style.h" +#include "../desktop-handles.h" +#include "../sp-namedview.h" +#include "../document.h" +#include "../message-stack.h" +#include "../sp-use.h" +#include "unclump.h" + +#include "xml/repr.h" + +#include "svg/svg.h" + +#include "libnr/nr-matrix-fns.h" +#include "libnr/nr-matrix-ops.h" + +#include "libnr/nr-matrix-translate-ops.h" +#include "libnr/nr-translate-ops.h" +#include "libnr/nr-translate-rotate-ops.h" +#include "libnr/nr-translate-scale-ops.h" + +#include "display/nr-arena.h" +#include "display/nr-arena-item.h" + +#include "ui/widget/color-picker.h" + +static GtkWidget *dlg = NULL; +static win_data wd; + +// impossible original values to make sure they are read from prefs +static gint x = -1000, y = -1000, w = 0, h = 0; +static gchar *prefs_path = "dialogs.clonetiler"; + +#define SB_MARGIN 1 +#define VB_MARGIN 4 + +enum { + PICK_COLOR, + PICK_OPACITY, + PICK_R, + PICK_G, + PICK_B, + PICK_H, + PICK_S, + PICK_L +}; + +static GtkSizeGroup* table_row_labels = NULL; + +static sigc::connection _shutdown_connection; +static sigc::connection _dialogs_hidden_connection; +static sigc::connection _dialogs_unhidden_connection; +static sigc::connection _desktop_activated_connection; +static sigc::connection _color_changed_connection; + +static Inkscape::UI::Widget::ColorPicker *color_picker; + +static void +clonetiler_dialog_destroy (GtkObject *object, gpointer data) +{ + if (Inkscape::NSApplication::Application::getNewGui()) + { + _shutdown_connection.disconnect(); + _dialogs_hidden_connection.disconnect(); + _dialogs_unhidden_connection.disconnect(); + _desktop_activated_connection.disconnect(); + } else { + sp_signal_disconnect_by_data (INKSCAPE, dlg); + } + _color_changed_connection.disconnect(); + + delete color_picker; + + wd.win = dlg = NULL; + wd.stop = 0; + +} + +static gboolean +clonetiler_dialog_delete (GtkObject *object, GdkEvent * /*event*/, gpointer data) +{ + gtk_window_get_position ((GtkWindow *) dlg, &x, &y); + gtk_window_get_size ((GtkWindow *) dlg, &w, &h); + + prefs_set_int_attribute (prefs_path, "x", x); + prefs_set_int_attribute (prefs_path, "y", y); + prefs_set_int_attribute (prefs_path, "w", w); + prefs_set_int_attribute (prefs_path, "h", h); + + return FALSE; // which means, go ahead and destroy it + +} + +static void on_delete() +{ + (void)clonetiler_dialog_delete (0, 0, NULL); +} + +static void +on_picker_color_changed (guint rgba) +{ + static bool is_updating = false; + if (is_updating || !SP_ACTIVE_DESKTOP) + return; + + is_updating = true; + + Inkscape::XML::Node *repr = inkscape_get_repr(INKSCAPE, prefs_path); + gchar c[32]; + sp_svg_write_color(c, 32, rgba); + repr->setAttribute("initial_color", c); + + is_updating = false; +} + +static guint clonetiler_number_of_clones (SPObject *obj); + +static void +clonetiler_change_selection (Inkscape::Application * /*inkscape*/, Inkscape::Selection *selection, GtkWidget *dlg) +{ + GtkWidget *buttons = (GtkWidget *) g_object_get_data (G_OBJECT(dlg), "buttons_on_tiles"); + GtkWidget *status = (GtkWidget *) g_object_get_data (G_OBJECT(dlg), "status"); + + if (selection->isEmpty()) { + gtk_widget_set_sensitive (buttons, FALSE); + gtk_label_set_markup (GTK_LABEL(status), _("Nothing selected.")); + return; + } + + if (g_slist_length ((GSList *) selection->itemList()) > 1) { + gtk_widget_set_sensitive (buttons, FALSE); + gtk_label_set_markup (GTK_LABEL(status), _("More than one object selected.")); + return; + } + + guint n = clonetiler_number_of_clones(selection->singleItem()); + if (n > 0) { + gtk_widget_set_sensitive (buttons, TRUE); + gchar *sta = g_strdup_printf (_("Object has %d tiled clones."), n); + gtk_label_set_markup (GTK_LABEL(status), sta); + g_free (sta); + } else { + gtk_widget_set_sensitive (buttons, FALSE); + gtk_label_set_markup (GTK_LABEL(status), _("Object has no tiled clones.")); + } +} + +static void +clonetiler_external_change (Inkscape::Application * /*inkscape*/, GtkWidget *dlg) +{ + clonetiler_change_selection (NULL, SP_DT_SELECTION(SP_ACTIVE_DESKTOP), dlg); +} + +static void clonetiler_disconnect_gsignal (GObject *widget, gpointer source) { + if (source && G_IS_OBJECT(source)) + sp_signal_disconnect_by_data (source, widget); +} + + +enum { + TILE_P1, + TILE_P2, + TILE_PM, + TILE_PG, + TILE_CM, + TILE_PMM, + TILE_PMG, + TILE_PGG, + TILE_CMM, + TILE_P4, + TILE_P4M, + TILE_P4G, + TILE_P3, + TILE_P31M, + TILE_P3M1, + TILE_P6, + TILE_P6M +}; + + +static NR::Matrix +clonetiler_get_transform ( + // symmetry group + int type, + // row, column + int x, int y, + // center, width, height of the tile + double cx, double cy, + double w, double h, + + // values from the dialog: + double d_x_per_x, double d_y_per_x, double d_x_per_y, double d_y_per_y, + int alternate_x, int alternate_y, double rand_x, double rand_y, + double d_per_x_exp, double d_per_y_exp, + double d_rot_per_x, double d_rot_per_y, int alternate_rotx, int alternate_roty, double rand_rot, + double d_scalex_per_x, double d_scaley_per_x, double d_scalex_per_y, double d_scaley_per_y, + int alternate_scalex, int alternate_scaley, double rand_scalex, double rand_scaley + ) +{ + // in abs units + double eff_x = (alternate_x? (x%2) : pow ((double) x, d_per_x_exp)); + double eff_y = (alternate_y? (y%2) : pow ((double) y, d_per_y_exp)); + double dx = d_x_per_x * w * eff_x + d_x_per_y * w * eff_y + rand_x * w * g_random_double_range (-1, 1); + double dy = d_y_per_x * h * eff_x + d_y_per_y * h * eff_y + rand_y * h * g_random_double_range (-1, 1); + + NR::Matrix rect_translate (NR::translate (w * pow ((double) x, d_per_x_exp) + dx, h * pow ((double) y, d_per_y_exp) + dy)); + + // in deg + double eff_x_rot = (alternate_rotx? (x%2) : (x)); + double eff_y_rot = (alternate_roty? (y%2) : (y)); + double drot = d_rot_per_x * eff_x_rot + d_rot_per_y * eff_y_rot + rand_rot * 180 * g_random_double_range (-1, 1); + + // times the original + double eff_x_s = (alternate_scalex? (x%2) : (x)); + double eff_y_s = (alternate_scaley? (y%2) : (y)); + double rand_scale_x, rand_scale_y; + if (rand_scaley == rand_scalex) { + // if rands are equal, scale proportionally + rand_scale_x = rand_scale_y = rand_scalex * 1 * g_random_double_range (-1, 1); + } else { + rand_scale_x = rand_scalex * 1 * g_random_double_range (-1, 1); + rand_scale_y = rand_scaley * 1 * g_random_double_range (-1, 1); + } + double dscalex = 1 + d_scalex_per_x * eff_x_s + d_scalex_per_y * eff_y_s + rand_scale_x; + if (dscalex < 0) dscalex = 0; + double dscaley = 1 + d_scaley_per_x * eff_x_s + d_scaley_per_y * eff_y_s + rand_scale_y; + if (dscaley < 0) dscaley = 0; + + NR::Matrix drot_c = NR::translate(-cx, -cy) * NR::rotate (M_PI*drot/180) * NR::translate(cx, cy); + + NR::Matrix dscale_c = NR::translate(-cx, -cy) * NR::scale (dscalex, dscaley) * NR::translate(cx, cy); + + NR::Matrix d_s_r = dscale_c * drot_c; + + NR::Matrix rotate_180_c = NR::translate(-cx, -cy) * NR::rotate (M_PI) * NR::translate(cx, cy); + + NR::Matrix rotate_90_c = NR::translate(-cx, -cy) * NR::rotate (-M_PI/2) * NR::translate(cx, cy); + NR::Matrix rotate_m90_c = NR::translate(-cx, -cy) * NR::rotate (M_PI/2) * NR::translate(cx, cy); + + NR::Matrix rotate_120_c = NR::translate(-cx, -cy) * NR::rotate (-2*M_PI/3) * NR::translate(cx, cy); + NR::Matrix rotate_m120_c = NR::translate(-cx, -cy) * NR::rotate (2*M_PI/3) * NR::translate(cx, cy); + + NR::Matrix rotate_60_c = NR::translate(-cx, -cy) * NR::rotate (-M_PI/3) * NR::translate(cx, cy); + NR::Matrix rotate_m60_c = NR::translate(-cx, -cy) * NR::rotate (M_PI/3) * NR::translate(cx, cy); + + double cos60 = cos(M_PI/3); + double sin60 = sin(M_PI/3); + double cos30 = cos(M_PI/6); + double sin30 = sin(M_PI/6); + + NR::Matrix flip_x = NR::translate(-cx, -cy) * NR::scale (-1, 1) * NR::translate(cx, cy); + NR::Matrix flip_y = NR::translate(-cx, -cy) * NR::scale (1, -1) * NR::translate(cx, cy); + + x = (int) pow ((double) x, d_per_x_exp); + y = (int) pow ((double) y, d_per_y_exp); + + switch (type) { + + case TILE_P1: + return d_s_r * rect_translate; + break; + + case TILE_P2: + if (x % 2 == 0) { + return d_s_r * rect_translate; + } else { + return d_s_r * rotate_180_c * rect_translate; + } + break; + + case TILE_PM: + if (x % 2 == 0) { + return d_s_r * rect_translate; + } else { + return d_s_r * flip_x * rect_translate; + } + break; + + case TILE_PG: + if (y % 2 == 0) { + return d_s_r * rect_translate; + } else { + return d_s_r * flip_x * rect_translate; + } + break; + + case TILE_CM: + if ((x + y) % 2 == 0) { + return d_s_r * rect_translate; + } else { + return d_s_r * flip_x * rect_translate; + } + break; + + case TILE_PMM: + if (y % 2 == 0) { + if (x % 2 == 0) { + return d_s_r * rect_translate; + } else { + return d_s_r * flip_x * rect_translate; + } + } else { + if (x % 2 == 0) { + return d_s_r * flip_y * rect_translate; + } else { + return d_s_r * flip_x * flip_y * rect_translate; + } + } + break; + + case TILE_PMG: + if (y % 4 == 0) { + return d_s_r * rect_translate; + } else if (y % 4 == 1) { + return d_s_r * flip_y * rect_translate; + } else if (y % 4 == 2) { + return d_s_r * flip_x * rect_translate; + } else if (y % 4 == 3) { + return d_s_r * flip_x * flip_y * rect_translate; + } + break; + + case TILE_PGG: + if (y % 2 == 0) { + if (x % 2 == 0) { + return d_s_r * rect_translate; + } else { + return d_s_r * flip_y * rect_translate; + } + } else { + if (x % 2 == 0) { + return d_s_r * rotate_180_c * rect_translate; + } else { + return d_s_r * rotate_180_c * flip_y * rect_translate; + } + } + break; + + case TILE_CMM: + if (y % 4 == 0) { + if (x % 2 == 0) { + return d_s_r * rect_translate; + } else { + return d_s_r * flip_x * rect_translate; + } + } else if (y % 4 == 1) { + if (x % 2 == 0) { + return d_s_r * flip_y * rect_translate; + } else { + return d_s_r * flip_x * flip_y * rect_translate; + } + } else if (y % 4 == 2) { + if (x % 2 == 1) { + return d_s_r * rect_translate; + } else { + return d_s_r * flip_x * rect_translate; + } + } else { + if (x % 2 == 1) { + return d_s_r * flip_y * rect_translate; + } else { + return d_s_r * flip_x * flip_y * rect_translate; + } + } + break; + + case TILE_P4: + { + NR::Matrix ori (NR::translate ((w + h) * (x/2) + dx, (h + w) * (y/2) + dy)); + NR::Matrix dia1 (NR::translate (w/2 + h/2, -h/2 + w/2)); + NR::Matrix dia2 (NR::translate (-w/2 + h/2, h/2 + w/2)); + if (y % 2 == 0) { + if (x % 2 == 0) { + return d_s_r * ori; + } else { + return d_s_r * rotate_m90_c * dia1 * ori; + } + } else { + if (x % 2 == 0) { + return d_s_r * rotate_90_c * dia2 * ori; + } else { + return d_s_r * rotate_180_c * dia1 * dia2 * ori; + } + } + } + break; + + case TILE_P4M: + { + double max = MAX(w, h); + NR::Matrix ori (NR::translate ((max + max) * (x/4) + dx, (max + max) * (y/2) + dy)); + NR::Matrix dia1 (NR::translate (w/2 - h/2, h/2 - w/2)); + NR::Matrix dia2 (NR::translate (-h/2 + w/2, w/2 - h/2)); + if (y % 2 == 0) { + if (x % 4 == 0) { + return d_s_r * ori; + } else if (x % 4 == 1) { + return d_s_r * flip_y * rotate_m90_c * dia1 * ori; + } else if (x % 4 == 2) { + return d_s_r * rotate_m90_c * dia1 * NR::translate (h, 0) * ori; + } else if (x % 4 == 3) { + return d_s_r * flip_x * NR::translate (w, 0) * ori; + } + } else { + if (x % 4 == 0) { + return d_s_r * flip_y * NR::translate(0, h) * ori; + } else if (x % 4 == 1) { + return d_s_r * rotate_90_c * dia2 * NR::translate(0, h) * ori; + } else if (x % 4 == 2) { + return d_s_r * flip_y * rotate_90_c * dia2 * NR::translate(h, 0) * NR::translate(0, h) * ori; + } else if (x % 4 == 3) { + return d_s_r * flip_y * flip_x * NR::translate(w, 0) * NR::translate(0, h) * ori; + } + } + } + break; + + case TILE_P4G: + { + double max = MAX(w, h); + NR::Matrix ori (NR::translate ((max + max) * (x/4) + dx, (max + max) * y + dy)); + NR::Matrix dia1 (NR::translate (w/2 + h/2, h/2 - w/2)); + NR::Matrix dia2 (NR::translate (-h/2 + w/2, w/2 + h/2)); + if (((x/4) + y) % 2 == 0) { + if (x % 4 == 0) { + return d_s_r * ori; + } else if (x % 4 == 1) { + return d_s_r * rotate_m90_c * dia1 * ori; + } else if (x % 4 == 2) { + return d_s_r * rotate_90_c * dia2 * ori; + } else if (x % 4 == 3) { + return d_s_r * rotate_180_c * dia1 * dia2 * ori; + } + } else { + if (x % 4 == 0) { + return d_s_r * flip_y * NR::translate (0, h) * ori; + } else if (x % 4 == 1) { + return d_s_r * flip_y * rotate_m90_c * dia1 * NR::translate (-h, 0) * ori; + } else if (x % 4 == 2) { + return d_s_r * flip_y * rotate_90_c * dia2 * NR::translate (h, 0) * ori; + } else if (x % 4 == 3) { + return d_s_r * flip_x * NR::translate (w, 0) * ori; + } + } + } + break; + + case TILE_P3: + { + double width; + double height; + NR::Matrix dia1; + NR::Matrix dia2; + if (w > h) { + width = w + w * cos60; + height = 2 * w * sin60; + dia1 = NR::Matrix (NR::translate (w/2 + w/2 * cos60, -(w/2 * sin60))); + dia2 = dia1 * NR::Matrix (NR::translate (0, 2 * (w/2 * sin60))); + } else { + width = h * cos (M_PI/6); + height = h; + dia1 = NR::Matrix (NR::translate (h/2 * cos30, -(h/2 * sin30))); + dia2 = dia1 * NR::Matrix (NR::translate (0, h/2)); + } + NR::Matrix ori (NR::translate (width * (2*(x/3) + y%2) + dx, (height/2) * y + dy)); + if (x % 3 == 0) { + return d_s_r * ori; + } else if (x % 3 == 1) { + return d_s_r * rotate_m120_c * dia1 * ori; + } else if (x % 3 == 2) { + return d_s_r * rotate_120_c * dia2 * ori; + } + } + break; + + case TILE_P31M: + { + NR::Matrix ori; + NR::Matrix dia1; + NR::Matrix dia2; + NR::Matrix dia3; + NR::Matrix dia4; + if (w > h) { + ori = NR::Matrix(NR::translate (w * (x/6) + w/2 * (y%2) + dx, (w * cos30) * y + dy)); + dia1 = NR::Matrix (NR::translate (0, h/2) * NR::translate (w/2, 0) * NR::translate (w/2 * cos60, -w/2 * sin60) * NR::translate (-h/2 * cos30, -h/2 * sin30) ); + dia2 = dia1 * NR::Matrix (NR::translate (h * cos30, h * sin30)); + dia3 = dia2 * NR::Matrix (NR::translate (0, 2 * (w/2 * sin60 - h/2 * sin30))); + dia4 = dia3 * NR::Matrix (NR::translate (-h * cos30, h * sin30)); + } else { + ori = NR::Matrix (NR::translate (2*h * cos30 * (x/6 + 0.5*(y%2)) + dx, (2*h - h * sin30) * y + dy)); + dia1 = NR::Matrix (NR::translate (0, -h/2) * NR::translate (h/2 * cos30, h/2 * sin30)); + dia2 = dia1 * NR::Matrix (NR::translate (h * cos30, h * sin30)); + dia3 = dia2 * NR::Matrix (NR::translate (0, h/2)); + dia4 = dia3 * NR::Matrix (NR::translate (-h * cos30, h * sin30)); + } + if (x % 6 == 0) { + return d_s_r * ori; + } else if (x % 6 == 1) { + return d_s_r * flip_y * rotate_m120_c * dia1 * ori; + } else if (x % 6 == 2) { + return d_s_r * rotate_m120_c * dia2 * ori; + } else if (x % 6 == 3) { + return d_s_r * flip_y * rotate_120_c * dia3 * ori; + } else if (x % 6 == 4) { + return d_s_r * rotate_120_c * dia4 * ori; + } else if (x % 6 == 5) { + return d_s_r * flip_y * NR::translate(0, h) * ori; + } + } + break; + + case TILE_P3M1: + { + double width; + double height; + NR::Matrix dia1; + NR::Matrix dia2; + NR::Matrix dia3; + NR::Matrix dia4; + if (w > h) { + width = w + w * cos60; + height = 2 * w * sin60; + dia1 = NR::Matrix (NR::translate (0, h/2) * NR::translate (w/2, 0) * NR::translate (w/2 * cos60, -w/2 * sin60) * NR::translate (-h/2 * cos30, -h/2 * sin30) ); + dia2 = dia1 * NR::Matrix (NR::translate (h * cos30, h * sin30)); + dia3 = dia2 * NR::Matrix (NR::translate (0, 2 * (w/2 * sin60 - h/2 * sin30))); + dia4 = dia3 * NR::Matrix (NR::translate (-h * cos30, h * sin30)); + } else { + width = 2 * h * cos (M_PI/6); + height = 2 * h; + dia1 = NR::Matrix (NR::translate (0, -h/2) * NR::translate (h/2 * cos30, h/2 * sin30)); + dia2 = dia1 * NR::Matrix (NR::translate (h * cos30, h * sin30)); + dia3 = dia2 * NR::Matrix (NR::translate (0, h/2)); + dia4 = dia3 * NR::Matrix (NR::translate (-h * cos30, h * sin30)); + } + NR::Matrix ori (NR::translate (width * (2*(x/6) + y%2) + dx, (height/2) * y + dy)); + if (x % 6 == 0) { + return d_s_r * ori; + } else if (x % 6 == 1) { + return d_s_r * flip_y * rotate_m120_c * dia1 * ori; + } else if (x % 6 == 2) { + return d_s_r * rotate_m120_c * dia2 * ori; + } else if (x % 6 == 3) { + return d_s_r * flip_y * rotate_120_c * dia3 * ori; + } else if (x % 6 == 4) { + return d_s_r * rotate_120_c * dia4 * ori; + } else if (x % 6 == 5) { + return d_s_r * flip_y * NR::translate(0, h) * ori; + } + } + break; + + case TILE_P6: + { + NR::Matrix ori; + NR::Matrix dia1; + NR::Matrix dia2; + NR::Matrix dia3; + NR::Matrix dia4; + NR::Matrix dia5; + if (w > h) { + ori = NR::Matrix(NR::translate (2*w * (x/6) + w * (y%2) + dx, (2*w * sin60) * y + dy)); + dia1 = NR::Matrix (NR::translate (w/2 * cos60, -w/2 * sin60)); + dia2 = dia1 * NR::Matrix (NR::translate (w/2, 0)); + dia3 = dia2 * NR::Matrix (NR::translate (w/2 * cos60, w/2 * sin60)); + dia4 = dia3 * NR::Matrix (NR::translate (-w/2 * cos60, w/2 * sin60)); + dia5 = dia4 * NR::Matrix (NR::translate (-w/2, 0)); + } else { + ori = NR::Matrix(NR::translate (2*h * cos30 * (x/6 + 0.5*(y%2)) + dx, (h + h * sin30) * y + dy)); + dia1 = NR::Matrix (NR::translate (-w/2, -h/2) * NR::translate (h/2 * cos30, -h/2 * sin30) * NR::translate (w/2 * cos60, w/2 * sin60)); + dia2 = dia1 * NR::Matrix (NR::translate (-w/2 * cos60, -w/2 * sin60) * NR::translate (h/2 * cos30, -h/2 * sin30) * NR::translate (h/2 * cos30, h/2 * sin30) * NR::translate (-w/2 * cos60, w/2 * sin60)); + dia3 = dia2 * NR::Matrix (NR::translate (w/2 * cos60, -w/2 * sin60) * NR::translate (h/2 * cos30, h/2 * sin30) * NR::translate (-w/2, h/2)); + dia4 = dia3 * dia1.inverse(); + dia5 = dia3 * dia2.inverse(); + } + if (x % 6 == 0) { + return d_s_r * ori; + } else if (x % 6 == 1) { + return d_s_r * rotate_m60_c * dia1 * ori; + } else if (x % 6 == 2) { + return d_s_r * rotate_m120_c * dia2 * ori; + } else if (x % 6 == 3) { + return d_s_r * rotate_180_c * dia3 * ori; + } else if (x % 6 == 4) { + return d_s_r * rotate_120_c * dia4 * ori; + } else if (x % 6 == 5) { + return d_s_r * rotate_60_c * dia5 * ori; + } + } + break; + + case TILE_P6M: + { + + NR::Matrix ori; + NR::Matrix dia1, dia2, dia3, dia4, dia5, dia6, dia7, dia8, dia9, dia10; + if (w > h) { + ori = NR::Matrix(NR::translate (2*w * (x/12) + w * (y%2) + dx, (2*w * sin60) * y + dy)); + dia1 = NR::Matrix (NR::translate (w/2, h/2) * NR::translate (-w/2 * cos60, -w/2 * sin60) * NR::translate (-h/2 * cos30, h/2 * sin30)); + dia2 = dia1 * NR::Matrix (NR::translate (h * cos30, -h * sin30)); + dia3 = dia2 * NR::Matrix (NR::translate (-h/2 * cos30, h/2 * sin30) * NR::translate (w * cos60, 0) * NR::translate (-h/2 * cos30, -h/2 * sin30)); + dia4 = dia3 * NR::Matrix (NR::translate (h * cos30, h * sin30)); + dia5 = dia4 * NR::Matrix (NR::translate (-h/2 * cos30, -h/2 * sin30) * NR::translate (-w/2 * cos60, w/2 * sin60) * NR::translate (w/2, -h/2)); + dia6 = dia5 * NR::Matrix (NR::translate (0, h)); + dia7 = dia6 * dia1.inverse(); + dia8 = dia6 * dia2.inverse(); + dia9 = dia6 * dia3.inverse(); + dia10 = dia6 * dia4.inverse(); + } else { + ori = NR::Matrix(NR::translate (4*h * cos30 * (x/12 + 0.5*(y%2)) + dx, (2*h + 2*h * sin30) * y + dy)); + dia1 = NR::Matrix (NR::translate (-w/2, -h/2) * NR::translate (h/2 * cos30, -h/2 * sin30) * NR::translate (w/2 * cos60, w/2 * sin60)); + dia2 = dia1 * NR::Matrix (NR::translate (h * cos30, -h * sin30)); + dia3 = dia2 * NR::Matrix (NR::translate (-w/2 * cos60, -w/2 * sin60) * NR::translate (h * cos30, 0) * NR::translate (-w/2 * cos60, w/2 * sin60)); + dia4 = dia3 * NR::Matrix (NR::translate (h * cos30, h * sin30)); + dia5 = dia4 * NR::Matrix (NR::translate (w/2 * cos60, -w/2 * sin60) * NR::translate (h/2 * cos30, h/2 * sin30) * NR::translate (-w/2, h/2)); + dia6 = dia5 * NR::Matrix (NR::translate (0, h)); + dia7 = dia6 * dia1.inverse(); + dia8 = dia6 * dia2.inverse(); + dia9 = dia6 * dia3.inverse(); + dia10 = dia6 * dia4.inverse(); + } + if (x % 12 == 0) { + return d_s_r * ori; + } else if (x % 12 == 1) { + return d_s_r * flip_y * rotate_m60_c * dia1 * ori; + } else if (x % 12 == 2) { + return d_s_r * rotate_m60_c * dia2 * ori; + } else if (x % 12 == 3) { + return d_s_r * flip_y * rotate_m120_c * dia3 * ori; + } else if (x % 12 == 4) { + return d_s_r * rotate_m120_c * dia4 * ori; + } else if (x % 12 == 5) { + return d_s_r * flip_x * dia5 * ori; + } else if (x % 12 == 6) { + return d_s_r * flip_x * flip_y * dia6 * ori; + } else if (x % 12 == 7) { + return d_s_r * flip_y * rotate_120_c * dia7 * ori; + } else if (x % 12 == 8) { + return d_s_r * rotate_120_c * dia8 * ori; + } else if (x % 12 == 9) { + return d_s_r * flip_y * rotate_60_c * dia9 * ori; + } else if (x % 12 == 10) { + return d_s_r * rotate_60_c * dia10 * ori; + } else if (x % 12 == 11) { + return d_s_r * flip_y * NR::translate (0, h) * ori; + } + } + break; + + default: + break; + } + + return NR::identity(); +} + +static bool +clonetiler_is_a_clone_of (SPObject *tile, SPObject *obj) +{ + char *id_href = NULL; + + if (obj) { + Inkscape::XML::Node *obj_repr = SP_OBJECT_REPR(obj); + id_href = g_strdup_printf("#%s", obj_repr->attribute("id")); + } + + if (SP_IS_USE(tile) && + SP_OBJECT_REPR(tile)->attribute("xlink:href") && + (!id_href || !strcmp(id_href, SP_OBJECT_REPR(tile)->attribute("xlink:href"))) && + SP_OBJECT_REPR(tile)->attribute("inkscape:tiled-clone-of") && + (!id_href || !strcmp(id_href, SP_OBJECT_REPR(tile)->attribute("inkscape:tiled-clone-of")))) + { + if (id_href) + g_free (id_href); + return true; + } else { + if (id_href) + g_free (id_href); + return false; + } +} + +static NRArena const *trace_arena = NULL; +static unsigned trace_visionkey; +static NRArenaItem *trace_root; +static gdouble trace_zoom; + +static void +clonetiler_trace_hide_tiled_clones_recursively (SPObject *from) +{ + if (!trace_arena) + return; + + for (SPObject *o = sp_object_first_child(from); o != NULL; o = SP_OBJECT_NEXT(o)) { + if (SP_IS_ITEM(o) && clonetiler_is_a_clone_of (o, NULL)) + sp_item_invoke_hide(SP_ITEM(o), trace_visionkey); // FIXME: hide each tiled clone's original too! + clonetiler_trace_hide_tiled_clones_recursively (o); + } +} + +static void +clonetiler_trace_setup (SPDocument *doc, gdouble zoom, SPItem *original) +{ + trace_arena = NRArena::create(); + /* Create ArenaItem and set transform */ + trace_visionkey = sp_item_display_key_new(1); + trace_root = sp_item_invoke_show( SP_ITEM(SP_DOCUMENT_ROOT (doc)), + (NRArena *) trace_arena, trace_visionkey, SP_ITEM_SHOW_DISPLAY); + + // hide the (current) original and any tiled clones, we only want to pick the background + sp_item_invoke_hide(original, trace_visionkey); + clonetiler_trace_hide_tiled_clones_recursively (SP_OBJECT(SP_DOCUMENT_ROOT (doc))); + + sp_document_root (doc)->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + sp_document_ensure_up_to_date(doc); + + trace_zoom = zoom; +} + +static guint32 +clonetiler_trace_pick (NR::Rect box) +{ + if (!trace_arena) + return 0; + + NRMatrix t; + nr_matrix_set_scale(&t, trace_zoom, trace_zoom); + nr_arena_item_set_transform(trace_root, &t); + NRGC gc(NULL); + nr_matrix_set_identity(&gc.transform); + nr_arena_item_invoke_update( trace_root, NULL, &gc, + NR_ARENA_ITEM_STATE_ALL, + NR_ARENA_ITEM_STATE_NONE ); + + /* Item integer bbox in points */ + NRRectL ibox; + ibox.x0 = (int) floor(trace_zoom * box.min()[NR::X] + 0.5); + ibox.y0 = (int) floor(trace_zoom * box.min()[NR::Y] + 0.5); + ibox.x1 = (int) floor(trace_zoom * box.max()[NR::X] + 0.5); + ibox.y1 = (int) floor(trace_zoom * box.max()[NR::Y] + 0.5); + + /* Find visible area */ + int width = ibox.x1 - ibox.x0; + int height = ibox.y1 - ibox.y0; + + /* Set up pixblock */ + guchar *px = nr_new(guchar, 4 * width * height); + memset(px, 0x00, 4 * width * height); + + /* Render */ + NRPixBlock pb; + nr_pixblock_setup_extern( &pb, NR_PIXBLOCK_MODE_R8G8B8A8N, + ibox.x0, ibox.y0, ibox.x1, ibox.y1, + px, 4 * width, FALSE, FALSE ); + nr_arena_item_invoke_render( trace_root, &ibox, &pb, + NR_ARENA_ITEM_RENDER_NO_CACHE ); + + double R = 0, G = 0, B = 0, A = 0; + double count = 0; + double weight = 0; + + for (int y = ibox.y0; y < ibox.y1; y++) { + const unsigned char *s = NR_PIXBLOCK_PX (&pb) + (y - ibox.y0) * pb.rs; + for (int x = ibox.x0; x < ibox.x1; x++) { + count += 1; + weight += s[3] / 255.0; + R += s[0] / 255.0; + G += s[1] / 255.0; + B += s[2] / 255.0; + A += s[3] / 255.0; + s += 4; + } + } + + nr_pixblock_release(&pb); + + R = R / weight; + G = G / weight; + B = B / weight; + A = A / count; + + R = CLAMP (R, 0.0, 1.0); + G = CLAMP (G, 0.0, 1.0); + B = CLAMP (B, 0.0, 1.0); + A = CLAMP (A, 0.0, 1.0); + + return SP_RGBA32_F_COMPOSE (R, G, B, A); +} + +static void +clonetiler_trace_finish () +{ + if (trace_arena) { + ((NRObject *) trace_arena)->unreference(); + trace_arena = NULL; + } +} + +static void +clonetiler_unclump (GtkWidget *widget, void *) +{ + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + if (desktop == NULL) + return; + + Inkscape::Selection *selection = SP_DT_SELECTION(desktop); + + // check if something is selected + if (selection->isEmpty() || g_slist_length((GSList *) selection->itemList()) > 1) { + SP_DT_MSGSTACK(desktop)->flash(Inkscape::WARNING_MESSAGE, _("Select one object whose tiled clones to unclump.")); + return; + } + + SPObject *obj = SP_OBJECT(selection->singleItem()); + SPObject *parent = SP_OBJECT_PARENT (obj); + + GSList *to_unclump = NULL; // not including the original + + for (SPObject *child = sp_object_first_child(parent); child != NULL; child = SP_OBJECT_NEXT(child)) { + if (clonetiler_is_a_clone_of (child, obj)) { + to_unclump = g_slist_prepend (to_unclump, child); + } + } + + sp_document_ensure_up_to_date(SP_DT_DOCUMENT(desktop)); + + unclump (to_unclump); + + g_slist_free (to_unclump); + + sp_document_done (SP_DT_DOCUMENT (desktop)); +} + +static guint +clonetiler_number_of_clones (SPObject *obj) +{ + SPObject *parent = SP_OBJECT_PARENT (obj); + + guint n = 0; + + for (SPObject *child = sp_object_first_child(parent); child != NULL; child = SP_OBJECT_NEXT(child)) { + if (clonetiler_is_a_clone_of (child, obj)) { + n ++; + } + } + + return n; +} + +static void +clonetiler_remove (GtkWidget *widget, void *, bool do_undo = true) +{ + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + if (desktop == NULL) + return; + + Inkscape::Selection *selection = SP_DT_SELECTION(desktop); + + // check if something is selected + if (selection->isEmpty() || g_slist_length((GSList *) selection->itemList()) > 1) { + SP_DT_MSGSTACK(desktop)->flash(Inkscape::WARNING_MESSAGE, _("Select one object whose tiled clones to remove.")); + return; + } + + SPObject *obj = SP_OBJECT(selection->singleItem()); + SPObject *parent = SP_OBJECT_PARENT (obj); + +// remove old tiling + GSList *to_delete = NULL; + for (SPObject *child = sp_object_first_child(parent); child != NULL; child = SP_OBJECT_NEXT(child)) { + if (clonetiler_is_a_clone_of (child, obj)) { + to_delete = g_slist_prepend (to_delete, child); + } + } + for (GSList *i = to_delete; i; i = i->next) { + SP_OBJECT(i->data)->deleteObject(); + } + g_slist_free (to_delete); + + clonetiler_change_selection (NULL, selection, dlg); + + if (do_undo) + sp_document_done (SP_DT_DOCUMENT (desktop)); +} + +static NR::Rect +transform_rect(NR::Rect const &r, NR::Matrix const &m) +{ + using NR::X; + using NR::Y; + NR::Point const p1 = r.corner(1) * m; + NR::Point const p2 = r.corner(2) * m; + NR::Point const p3 = r.corner(3) * m; + NR::Point const p4 = r.corner(4) * m; + return NR::Rect( + NR::Point( + std::min(std::min(p1[X], p2[X]), std::min(p3[X], p4[X])), + std::min(std::min(p1[Y], p2[Y]), std::min(p3[Y], p4[Y]))), + NR::Point( + std::max(std::max(p1[X], p2[X]), std::max(p3[X], p4[X])), + std::max(std::max(p1[Y], p2[Y]), std::max(p3[Y], p4[Y])))); +} + +/** +Randomizes \a val by \a rand, with 0 < val < 1 and all values (including 0, 1) having the same +probability of being displaced. + */ +static double +randomize01 (double val, double rand) +{ + double base = MIN (val - rand, 1 - 2*rand); + if (base < 0) base = 0; + val = base + g_random_double_range (0, MIN (2 * rand, 1 - base)); + return CLAMP(val, 0, 1); // this should be unnecessary with the above provisions, but just in case... +} + + +static void +clonetiler_apply (GtkWidget *widget, void *) +{ + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + if (desktop == NULL) + return; + + Inkscape::Selection *selection = SP_DT_SELECTION(desktop); + + // check if something is selected + if (selection->isEmpty()) { + SP_DT_MSGSTACK(desktop)->flash(Inkscape::WARNING_MESSAGE, _("Select an object to clone.")); + return; + } + + // Check if more than one object is selected. + if (g_slist_length((GSList *) selection->itemList()) > 1) { + SP_DT_MSGSTACK(desktop)->flash(Inkscape::ERROR_MESSAGE, _("If you want to clone several objects, group them and clone the group.")); + return; + } + + SPObject *obj = SP_OBJECT(selection->singleItem()); + Inkscape::XML::Node *obj_repr = SP_OBJECT_REPR(obj); + const char *id_href = g_strdup_printf("#%s", obj_repr->attribute("id")); + SPObject *parent = SP_OBJECT_PARENT (obj); + + clonetiler_remove (NULL, NULL, false); + + double d_x_per_x = 0.01 * prefs_get_double_attribute_limited (prefs_path, "d_x_per_x", 0, -100, 1000); + double d_y_per_x = 0.01 * prefs_get_double_attribute_limited (prefs_path, "d_y_per_x", 0, -100, 1000); + double d_per_x_exp = prefs_get_double_attribute_limited (prefs_path, "d_per_x_exp", 1, 0, 10); + double d_x_per_y = 0.01 * prefs_get_double_attribute_limited (prefs_path, "d_x_per_y", 0, -100, 1000); + double d_y_per_y = 0.01 * prefs_get_double_attribute_limited (prefs_path, "d_y_per_y", 0, -100, 1000); + double d_per_y_exp = prefs_get_double_attribute_limited (prefs_path, "d_per_y_exp", 1, 0, 10); + int alternate_x = prefs_get_int_attribute (prefs_path, "alternate_x", 0); + int alternate_y = prefs_get_int_attribute (prefs_path, "alternate_y", 0); + double rand_x = 0.01 * prefs_get_double_attribute_limited (prefs_path, "rand_x", 0, 0, 1000); + double rand_y = 0.01 * prefs_get_double_attribute_limited (prefs_path, "rand_y", 0, 0, 1000); + + double d_scalex_per_x = 0.01 * prefs_get_double_attribute_limited (prefs_path, "d_scalex_per_x", 0, -100, 1000); + double d_scaley_per_x = 0.01 * prefs_get_double_attribute_limited (prefs_path, "d_scaley_per_x", 0, -100, 1000); + double d_scalex_per_y = 0.01 * prefs_get_double_attribute_limited (prefs_path, "d_scalex_per_y", 0, -100, 1000); + double d_scaley_per_y = 0.01 * prefs_get_double_attribute_limited (prefs_path, "d_scaley_per_y", 0, -100, 1000); + int alternate_scalex = prefs_get_int_attribute (prefs_path, "alternate_scalex", 0); + int alternate_scaley = prefs_get_int_attribute (prefs_path, "alternate_scaley", 0); + double rand_scalex = 0.01 * prefs_get_double_attribute_limited (prefs_path, "rand_scalex", 0, 0, 1000); + double rand_scaley = 0.01 * prefs_get_double_attribute_limited (prefs_path, "rand_scaley", 0, 0, 1000); + + double d_rot_per_x = prefs_get_double_attribute_limited (prefs_path, "d_rot_per_x", 0, -180, 180); + double d_rot_per_y = prefs_get_double_attribute_limited (prefs_path, "d_rot_per_y", 0, -180, 180); + int alternate_rotx = prefs_get_int_attribute (prefs_path, "alternate_rotx", 0); + int alternate_roty = prefs_get_int_attribute (prefs_path, "alternate_roty", 0); + double rand_rot = 0.01 * prefs_get_double_attribute_limited (prefs_path, "rand_rot", 0, 0, 100); + + double d_opacity_per_y = 0.01 * prefs_get_double_attribute_limited (prefs_path, "d_opacity_per_y", 0, 0, 100); + double d_opacity_per_x = 0.01 * prefs_get_double_attribute_limited (prefs_path, "d_opacity_per_x", 0, 0, 100); + int alternate_opacityy = prefs_get_int_attribute (prefs_path, "alternate_opacityy", 0); + int alternate_opacityx = prefs_get_int_attribute (prefs_path, "alternate_opacityx", 0); + double rand_opacity = 0.01 * prefs_get_double_attribute_limited (prefs_path, "rand_opacity", 0, 0, 100); + + const gchar *initial_color = prefs_get_string_attribute (prefs_path, "initial_color"); + double d_hue_per_y = 0.01 * prefs_get_double_attribute_limited (prefs_path, "d_hue_per_y", 0, -100, 100); + double d_hue_per_x = 0.01 * prefs_get_double_attribute_limited (prefs_path, "d_hue_per_x", 0, -100, 100); + double rand_hue = 0.01 * prefs_get_double_attribute_limited (prefs_path, "rand_hue", 0, 0, 100); + double d_saturation_per_y = 0.01 * prefs_get_double_attribute_limited (prefs_path, "d_saturation_per_y", 0, -100, 100); + double d_saturation_per_x = 0.01 * prefs_get_double_attribute_limited (prefs_path, "d_saturation_per_x", 0, -100, 100); + double rand_saturation = 0.01 * prefs_get_double_attribute_limited (prefs_path, "rand_saturation", 0, 0, 100); + double d_lightness_per_y = 0.01 * prefs_get_double_attribute_limited (prefs_path, "d_lightness_per_y", 0, -100, 100); + double d_lightness_per_x = 0.01 * prefs_get_double_attribute_limited (prefs_path, "d_lightness_per_x", 0, -100, 100); + double rand_lightness = 0.01 * prefs_get_double_attribute_limited (prefs_path, "rand_lightness", 0, 0, 100); + int alternate_color_y = prefs_get_int_attribute (prefs_path, "alternate_color_y", 0); + int alternate_color_x = prefs_get_int_attribute (prefs_path, "alternate_color_x", 0); + + int type = prefs_get_int_attribute (prefs_path, "symmetrygroup", 0); + + int keepbbox = prefs_get_int_attribute (prefs_path, "keepbbox", 1); + + int xmax = prefs_get_int_attribute (prefs_path, "xmax", 2); + int ymax = prefs_get_int_attribute (prefs_path, "ymax", 2); + + int fillrect = prefs_get_int_attribute (prefs_path, "fillrect", 0); + double fillwidth = prefs_get_double_attribute_limited (prefs_path, "fillwidth", 50, 0, 6000); + double fillheight = prefs_get_double_attribute_limited (prefs_path, "fillheight", 50, 0, 6000); + + int dotrace = prefs_get_int_attribute (prefs_path, "dotrace", 0); + int pick = prefs_get_int_attribute (prefs_path, "pick", 0); + int pick_to_presence = prefs_get_int_attribute (prefs_path, "pick_to_presence", 0); + int pick_to_size = prefs_get_int_attribute (prefs_path, "pick_to_size", 0); + int pick_to_color = prefs_get_int_attribute (prefs_path, "pick_to_color", 0); + int pick_to_opacity = prefs_get_int_attribute (prefs_path, "pick_to_opacity", 0); + double rand_picked = 0.01 * prefs_get_double_attribute_limited (prefs_path, "rand_picked", 0, 0, 100); + int invert_picked = prefs_get_int_attribute (prefs_path, "invert_picked", 0); + double gamma_picked = prefs_get_double_attribute_limited (prefs_path, "gamma_picked", 0, -10, 10); + + if (dotrace) { + clonetiler_trace_setup (SP_DT_DOCUMENT(desktop), 1.0, SP_ITEM (obj)); + } + + NR::Point c; + double w; + double h; + + if (keepbbox && + obj_repr->attribute("inkscape:tile-w") && + obj_repr->attribute("inkscape:tile-h") && + obj_repr->attribute("inkscape:tile-cx") && + obj_repr->attribute("inkscape:tile-cy")) { + + double cx = sp_repr_get_double_attribute (obj_repr, "inkscape:tile-cx", 0); + double cy = sp_repr_get_double_attribute (obj_repr, "inkscape:tile-cy", 0); + + c = NR::Point (cx, cy); + + w = sp_repr_get_double_attribute (obj_repr, "inkscape:tile-w", 0); + h = sp_repr_get_double_attribute (obj_repr, "inkscape:tile-h", 0); + } else { + NR::Rect const r = SP_ITEM(obj)->invokeBbox(sp_item_i2doc_affine(SP_ITEM(obj))); + c = r.midpoint(); + w = r.dimensions()[NR::X]; + h = r.dimensions()[NR::Y]; + + sp_repr_set_svg_double(obj_repr, "inkscape:tile-w", w); + sp_repr_set_svg_double(obj_repr, "inkscape:tile-h", h); + sp_repr_set_svg_double(obj_repr, "inkscape:tile-cx", c[NR::X]); + sp_repr_set_svg_double(obj_repr, "inkscape:tile-cy", c[NR::Y]); + } + + NR::Point cur = NR::Point (0, 0); + NR::Rect bbox_original = NR::Rect (NR::Point (c[NR::X] - w/2, c[NR::Y] - h/2), NR::Point (c[NR::X] + w/2, c[NR::Y] + h/2)); + + for (int x = 0; + fillrect? + (fabs(cur[NR::X]) < fillwidth && x < 200) // prevent "freezing" with too large fillrect, arbitrarily limit rows + : (x < xmax); + x ++) { + for (int y = 0; + fillrect? + (fabs(cur[NR::Y]) < fillheight && y < 200) // prevent "freezing" with too large fillrect, arbitrarily limit cols + : (y < ymax); + y ++) { + + // Note: We create a clone at 0,0 too, right over the original, in case our clones are colored + + // Get transform from symmetry, shift, scale, rotation + NR::Matrix t = clonetiler_get_transform (type, x, y, c[NR::X], c[NR::Y], w, h, + d_x_per_x, d_y_per_x, d_x_per_y, d_y_per_y, alternate_x, alternate_y, rand_x, rand_y, + d_per_x_exp, d_per_y_exp, + d_rot_per_x, d_rot_per_y, alternate_rotx, alternate_roty, rand_rot, + d_scalex_per_x, d_scaley_per_x, d_scalex_per_y, d_scaley_per_y, + alternate_scalex, alternate_scaley, rand_scalex, rand_scaley); + + cur = c * t - c; + if (fillrect) { + if ((cur[NR::X] > fillwidth) || (cur[NR::Y] > fillheight)) { // off limits + continue; + } + } + + gchar color_string[32]; *color_string = 0; + + // Color tab + if (initial_color) { + guint32 rgba = sp_svg_read_color (initial_color, 0x000000ff); + float hsl[3]; + sp_color_rgb_to_hsl_floatv (hsl, SP_RGBA32_R_F(rgba), SP_RGBA32_G_F(rgba), SP_RGBA32_B_F(rgba)); + + double eff_x = (alternate_color_x? (x%2) : (x)); + double eff_y = (alternate_color_y? (y%2) : (y)); + + hsl[0] += d_hue_per_x * eff_x + d_hue_per_y * eff_y + rand_hue * g_random_double_range (-1, 1); + if (hsl[0] < 0) hsl[0] += 1; + if (hsl[0] > 1) hsl[0] -= 1; + hsl[1] += d_saturation_per_x * eff_x + d_saturation_per_y * eff_y + rand_saturation * g_random_double_range (-1, 1); + hsl[1] = CLAMP (hsl[1], 0, 1); + hsl[2] += d_lightness_per_x * eff_x + d_lightness_per_y * eff_y + rand_lightness * g_random_double_range (-1, 1); + hsl[2] = CLAMP (hsl[2], 0, 1); + + float rgb[3]; + sp_color_hsl_to_rgb_floatv (rgb, hsl[0], hsl[1], hsl[2]); + sp_svg_write_color(color_string, 32, SP_RGBA32_F_COMPOSE(rgb[0], rgb[1], rgb[2], 1.0)); + } + + // Opacity tab + double opacity = 1.0; + int eff_x = (alternate_opacityx? (x%2) : (x)); + int eff_y = (alternate_opacityy? (y%2) : (y)); + opacity = 1 - (d_opacity_per_x * eff_x + d_opacity_per_y * eff_y + rand_opacity * g_random_double_range (-1, 1)); + opacity = CLAMP (opacity, 0, 1); + + // Trace tab + if (dotrace) { + NR::Rect bbox_t = transform_rect (bbox_original, t); + + guint32 rgba = clonetiler_trace_pick (bbox_t); + float r = SP_RGBA32_R_F(rgba); + float g = SP_RGBA32_G_F(rgba); + float b = SP_RGBA32_B_F(rgba); + float a = SP_RGBA32_A_F(rgba); + + float hsl[3]; + sp_color_rgb_to_hsl_floatv (hsl, r, g, b); + + gdouble val = 0; + switch (pick) { + case PICK_COLOR: + val = 1 - hsl[2]; // inverse lightness; to match other picks where black = max + break; + case PICK_OPACITY: + val = a; + break; + case PICK_R: + val = r; + break; + case PICK_G: + val = g; + break; + case PICK_B: + val = b; + break; + case PICK_H: + val = hsl[0]; + break; + case PICK_S: + val = hsl[1]; + break; + case PICK_L: + val = 1 - hsl[2]; + break; + default: + break; + } + + if (rand_picked > 0) { + val = randomize01 (val, rand_picked); + r = randomize01 (r, rand_picked); + g = randomize01 (g, rand_picked); + b = randomize01 (b, rand_picked); + } + + if (gamma_picked != 0) { + double power; + if (gamma_picked < 0) + power = 1/(1 + fabs(gamma_picked)); + else + power = 1 + gamma_picked; + + val = pow (val, power); + r = pow (r, power); + g = pow (g, power); + b = pow (b, power); + } + + if (invert_picked) { + val = 1 - val; + r = 1 - r; + g = 1 - g; + b = 1 - b; + } + + val = CLAMP (val, 0, 1); + r = CLAMP (r, 0, 1); + g = CLAMP (g, 0, 1); + b = CLAMP (b, 0, 1); + + // recompose tweaked color + rgba = SP_RGBA32_F_COMPOSE(r, g, b, a); + + if (pick_to_presence) { + if (g_random_double_range (0, 1) > val) { + continue; // skip! + } + } + if (pick_to_size) { + t = NR::translate(-c[NR::X], -c[NR::Y]) * NR::scale (val, val) * NR::translate(c[NR::X], c[NR::Y]) * t; + } + if (pick_to_opacity) { + opacity *= val; + } + if (pick_to_color) { + sp_svg_write_color(color_string, 32, rgba); + } + } + + if (opacity < 1e-6) { // invisibly transparent, skip + continue; + } + + if (fabs(t[0]) + fabs (t[1]) + fabs(t[2]) + fabs(t[3]) < 1e-6) { // too small, skip + continue; + } + + // Create the clone + Inkscape::XML::Node *clone = sp_repr_new("svg:use"); + clone->setAttribute("x", "0"); + clone->setAttribute("y", "0"); + clone->setAttribute("inkscape:tiled-clone-of", id_href); + clone->setAttribute("xlink:href", id_href); + + gchar affinestr[80]; + if (sp_svg_transform_write(affinestr, 79, t)) { + clone->setAttribute("transform", affinestr); + } else { + clone->setAttribute("transform", NULL); + } + + if (opacity < 1.0) { + sp_repr_set_css_double(clone, "opacity", opacity); + } + + if (*color_string) { + clone->setAttribute("fill", color_string); + clone->setAttribute("stroke", color_string); + } + + // add the new clone to the top of the original's parent + SP_OBJECT_REPR(parent)->appendChild(clone); + Inkscape::GC::release(clone); + } + cur[NR::Y] = 0; + } + + if (dotrace) { + clonetiler_trace_finish (); + } + + clonetiler_change_selection (NULL, selection, dlg); + + sp_document_done(SP_DT_DOCUMENT(desktop)); +} + +static GtkWidget * +clonetiler_new_tab (GtkWidget *nb, const gchar *label) +{ + GtkWidget *l = gtk_label_new_with_mnemonic (label); + GtkWidget *vb = gtk_vbox_new (FALSE, VB_MARGIN); + gtk_container_set_border_width (GTK_CONTAINER (vb), VB_MARGIN); + gtk_notebook_append_page (GTK_NOTEBOOK (nb), vb, l); + return vb; +} + +static void +clonetiler_checkbox_toggled (GtkToggleButton *tb, gpointer *data) +{ + const gchar *attr = (const gchar *) data; + prefs_set_int_attribute (prefs_path, attr, gtk_toggle_button_get_active (tb)); +} + +static GtkWidget * +clonetiler_checkbox (GtkTooltips *tt, const char *tip, const char *attr) +{ + GtkWidget *hb = gtk_hbox_new(FALSE, VB_MARGIN); + + GtkWidget *b = gtk_check_button_new (); + gtk_tooltips_set_tip (GTK_TOOLTIPS (tt), b, tip, NULL); + + int value = prefs_get_int_attribute (prefs_path, attr, 0); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(b), value); + + gtk_box_pack_end (GTK_BOX (hb), b, FALSE, TRUE, 0); + gtk_signal_connect ( GTK_OBJECT (b), "clicked", + GTK_SIGNAL_FUNC (clonetiler_checkbox_toggled), (gpointer) attr); + + g_object_set_data (G_OBJECT(b), "uncheckable", GINT_TO_POINTER(TRUE)); + + return hb; +} + + +static void +clonetiler_value_changed (GtkAdjustment *adj, gpointer data) +{ + const gchar *pref = (const gchar *) data; + prefs_set_double_attribute (prefs_path, pref, adj->value); +} + +static GtkWidget * +clonetiler_spinbox (GtkTooltips *tt, const char *tip, const char *attr, double lower, double upper, const gchar *suffix, bool exponent = false) +{ + GtkWidget *hb = gtk_hbox_new(FALSE, 0); + + { + GtkObject *a; + if (exponent) + a = gtk_adjustment_new(1.0, lower, upper, 0.01, 0.05, 0.1); + else + a = gtk_adjustment_new(0.0, lower, upper, 0.1, 0.5, 2); + + GtkWidget *sb; + if (exponent) + sb = gtk_spin_button_new (GTK_ADJUSTMENT (a), 0.01, 2); + else + sb = gtk_spin_button_new (GTK_ADJUSTMENT (a), 0.1, 1); + + gtk_tooltips_set_tip (GTK_TOOLTIPS (tt), sb, tip, NULL); + gtk_entry_set_width_chars (GTK_ENTRY (sb), 4); + gtk_box_pack_start (GTK_BOX (hb), sb, FALSE, FALSE, SB_MARGIN); + + double value = prefs_get_double_attribute_limited (prefs_path, attr, exponent? 1 : 0, lower, upper); + gtk_adjustment_set_value (GTK_ADJUSTMENT (a), value); + gtk_signal_connect(GTK_OBJECT(a), "value_changed", + GTK_SIGNAL_FUNC(clonetiler_value_changed), (gpointer) attr); + + if (exponent) + g_object_set_data (G_OBJECT(sb), "oneable", GINT_TO_POINTER(TRUE)); + else + g_object_set_data (G_OBJECT(sb), "zeroable", GINT_TO_POINTER(TRUE)); + } + + { + GtkWidget *l = gtk_label_new (""); + gtk_label_set_markup (GTK_LABEL(l), suffix); + gtk_misc_set_alignment (GTK_MISC (l), 1.0, 0); + gtk_box_pack_start (GTK_BOX (hb), l, FALSE, FALSE, 0); + } + + return hb; +} + +static void +clonetiler_symgroup_changed (GtkMenuItem *item, gpointer data) +{ + gint group_new = GPOINTER_TO_INT (data); + prefs_set_int_attribute ( prefs_path, "symmetrygroup", group_new ); +} + +static void +clonetiler_xy_changed (GtkAdjustment *adj, gpointer data) +{ + const gchar *pref = (const gchar *) data; + prefs_set_int_attribute (prefs_path, pref, (int) floor(adj->value + 0.5)); +} + +static void +clonetiler_keep_bbox_toggled (GtkToggleButton *tb, gpointer data) +{ + prefs_set_int_attribute (prefs_path, "keepbbox", gtk_toggle_button_get_active (tb)); +} + +static void +clonetiler_pick_to (GtkToggleButton *tb, gpointer data) +{ + const gchar *pref = (const gchar *) data; + prefs_set_int_attribute (prefs_path, pref, gtk_toggle_button_get_active (tb)); +} + + +static void +clonetiler_reset_recursive (GtkWidget *w) +{ + if (w && GTK_IS_OBJECT(w)) { + { + int r = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT(w), "zeroable")); + if (r && GTK_IS_SPIN_BUTTON(w)) { // spinbutton + GtkAdjustment *a = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON(w)); + gtk_adjustment_set_value (a, 0); + } + } + { + int r = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT(w), "oneable")); + if (r && GTK_IS_SPIN_BUTTON(w)) { // spinbutton + GtkAdjustment *a = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON(w)); + gtk_adjustment_set_value (a, 1); + } + } + { + int r = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT(w), "uncheckable")); + if (r && GTK_IS_TOGGLE_BUTTON(w)) { // checkbox + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(w), FALSE); + } + } + } + + if (GTK_IS_CONTAINER(w)) { + GList *ch = gtk_container_get_children (GTK_CONTAINER(w)); + for (GList *i = ch; i != NULL; i = i->next) { + clonetiler_reset_recursive (GTK_WIDGET(i->data)); + } + g_list_free (ch); + } +} + +static void +clonetiler_reset (GtkWidget *widget, void *) +{ + clonetiler_reset_recursive (dlg); +} + +static void +clonetiler_table_attach (GtkWidget *table, GtkWidget *widget, float align, int row, int col) +{ + GtkWidget *a = gtk_alignment_new (align, 0, 0, 0); + gtk_container_add(GTK_CONTAINER(a), widget); + gtk_table_attach ( GTK_TABLE (table), a, col, col + 1, row, row + 1, (GtkAttachOptions)4, (GtkAttachOptions)0, 0, 0 ); +} + +static GtkWidget * +clonetiler_table_x_y_rand (int values) +{ + GtkWidget *table = gtk_table_new (values + 2, 5, FALSE); + gtk_container_set_border_width (GTK_CONTAINER (table), VB_MARGIN); + gtk_table_set_row_spacings (GTK_TABLE (table), 6); + gtk_table_set_col_spacings (GTK_TABLE (table), 8); + + { + GtkWidget *hb = gtk_hbox_new (FALSE, 0); + + GtkWidget *i = sp_icon_new (GTK_ICON_SIZE_MENU, "clonetiler_per_row"); + gtk_box_pack_start (GTK_BOX (hb), i, FALSE, FALSE, 2); + + GtkWidget *l = gtk_label_new (""); + gtk_label_set_markup (GTK_LABEL(l), _("Per row:")); + gtk_box_pack_start (GTK_BOX (hb), l, FALSE, FALSE, 2); + + clonetiler_table_attach (table, hb, 0, 1, 2); + } + + { + GtkWidget *hb = gtk_hbox_new (FALSE, 0); + + GtkWidget *i = sp_icon_new (GTK_ICON_SIZE_MENU, "clonetiler_per_column"); + gtk_box_pack_start (GTK_BOX (hb), i, FALSE, FALSE, 2); + + GtkWidget *l = gtk_label_new (""); + gtk_label_set_markup (GTK_LABEL(l), _("Per column:")); + gtk_box_pack_start (GTK_BOX (hb), l, FALSE, FALSE, 2); + + clonetiler_table_attach (table, hb, 0, 1, 3); + } + + { + GtkWidget *l = gtk_label_new (""); + gtk_label_set_markup (GTK_LABEL(l), _("Randomize:")); + clonetiler_table_attach (table, l, 0, 1, 4); + } + + return table; +} + +static void +clonetiler_pick_switched (GtkToggleButton *tb, gpointer data) +{ + guint v = GPOINTER_TO_INT (data); + prefs_set_int_attribute (prefs_path, "pick", v); +} + + +static void +clonetiler_switch_to_create (GtkToggleButton *tb, GtkWidget *dlg) +{ + GtkWidget *rowscols = (GtkWidget *) g_object_get_data (G_OBJECT(dlg), "rowscols"); + GtkWidget *widthheight = (GtkWidget *) g_object_get_data (G_OBJECT(dlg), "widthheight"); + + if (rowscols) { + gtk_widget_set_sensitive (rowscols, TRUE); + } + if (widthheight) { + gtk_widget_set_sensitive (widthheight, FALSE); + } + + prefs_set_int_attribute (prefs_path, "fillrect", 0); +} + + +static void +clonetiler_switch_to_fill (GtkToggleButton *tb, GtkWidget *dlg) +{ + GtkWidget *rowscols = (GtkWidget *) g_object_get_data (G_OBJECT(dlg), "rowscols"); + GtkWidget *widthheight = (GtkWidget *) g_object_get_data (G_OBJECT(dlg), "widthheight"); + + if (rowscols) { + gtk_widget_set_sensitive (rowscols, FALSE); + } + if (widthheight) { + gtk_widget_set_sensitive (widthheight, TRUE); + } + + prefs_set_int_attribute (prefs_path, "fillrect", 1); +} + + + + +static void +clonetiler_fill_width_changed (GtkAdjustment *adj, GtkWidget *u) +{ + gdouble const raw_dist = adj->value; + SPUnit const &unit = *sp_unit_selector_get_unit(SP_UNIT_SELECTOR(u)); + gdouble const pixels = sp_units_get_pixels (raw_dist, unit); + + prefs_set_double_attribute (prefs_path, "fillwidth", pixels); +} + +static void +clonetiler_fill_height_changed (GtkAdjustment *adj, GtkWidget *u) +{ + gdouble const raw_dist = adj->value; + SPUnit const &unit = *sp_unit_selector_get_unit(SP_UNIT_SELECTOR(u)); + gdouble const pixels = sp_units_get_pixels (raw_dist, unit); + + prefs_set_double_attribute (prefs_path, "fillheight", pixels); +} + + +static void +clonetiler_do_pick_toggled (GtkToggleButton *tb, gpointer data) +{ + GtkWidget *vvb = (GtkWidget *) g_object_get_data (G_OBJECT(dlg), "dotrace"); + + prefs_set_int_attribute (prefs_path, "dotrace", gtk_toggle_button_get_active (tb)); + + if (vvb) + gtk_widget_set_sensitive (vvb, gtk_toggle_button_get_active (tb)); +} + + + + +void +clonetiler_dialog (void) +{ + if (!dlg) + { + gchar title[500]; + sp_ui_dialog_title_string (Inkscape::Verb::get(SP_VERB_DIALOG_CLONETILER), title); + + dlg = sp_window_new (title, TRUE); + if (x == -1000 || y == -1000) { + x = prefs_get_int_attribute (prefs_path, "x", 0); + y = prefs_get_int_attribute (prefs_path, "y", 0); + } + + if (w ==0 || h == 0) { + w = prefs_get_int_attribute (prefs_path, "w", 0); + h = prefs_get_int_attribute (prefs_path, "h", 0); + } + + if (x != 0 || y != 0) { + gtk_window_move ((GtkWindow *) dlg, x, y); + + } else { + gtk_window_set_position(GTK_WINDOW(dlg), GTK_WIN_POS_CENTER); + } + + if (w && h) { + gtk_window_resize ((GtkWindow *) dlg, w, h); + } + + sp_transientize (dlg); + wd.win = dlg; + wd.stop = 0; + + + gtk_signal_connect ( GTK_OBJECT (dlg), "event", GTK_SIGNAL_FUNC (sp_dialog_event_handler), dlg); + + gtk_signal_connect ( GTK_OBJECT (dlg), "destroy", G_CALLBACK (clonetiler_dialog_destroy), dlg); + gtk_signal_connect ( GTK_OBJECT (dlg), "delete_event", G_CALLBACK (clonetiler_dialog_delete), dlg); + + if (Inkscape::NSApplication::Application::getNewGui()) + { + _shutdown_connection = Inkscape::NSApplication::Editor::connectShutdown (&on_delete); + _dialogs_hidden_connection = Inkscape::NSApplication::Editor::connectDialogsHidden (sigc::bind (&on_dialog_hide, dlg)); + _dialogs_unhidden_connection = Inkscape::NSApplication::Editor::connectDialogsUnhidden (sigc::bind (&on_dialog_unhide, dlg)); + _desktop_activated_connection = Inkscape::NSApplication::Editor::connectDesktopActivated (sigc::bind (&on_transientize, &wd)); + } else { + g_signal_connect ( G_OBJECT (INKSCAPE), "shut_down", G_CALLBACK (clonetiler_dialog_delete), dlg); + g_signal_connect ( G_OBJECT (INKSCAPE), "dialogs_hide", G_CALLBACK (sp_dialog_hide), dlg); + g_signal_connect ( G_OBJECT (INKSCAPE), "dialogs_unhide", G_CALLBACK (sp_dialog_unhide), dlg); + g_signal_connect ( G_OBJECT (INKSCAPE), "activate_desktop", G_CALLBACK (sp_transientize_callback), &wd); + } + + GtkTooltips *tt = gtk_tooltips_new(); + + GtkWidget *mainbox = gtk_vbox_new(FALSE, 4); + gtk_container_set_border_width (GTK_CONTAINER (mainbox), 6); + gtk_container_add (GTK_CONTAINER (dlg), mainbox); + + GtkWidget *nb = gtk_notebook_new (); + gtk_box_pack_start (GTK_BOX (mainbox), nb, FALSE, FALSE, 0); + + +// Symmetry + { + GtkWidget *vb = clonetiler_new_tab (nb, _("_Symmetry")); + + GtkWidget *om = gtk_option_menu_new (); + /* TRANSLATORS: For the following 17 symmetry groups, see + * http://www.bib.ulb.ac.be/coursmath/doc/17.htm (visual examples); + * http://www.clarku.edu/~djoyce/wallpaper/seventeen.html (English vocabulary); or + * http://membres.lycos.fr/villemingerard/Geometri/Sym1D.htm (French vocabulary). + */ + gtk_tooltips_set_tip (GTK_TOOLTIPS (tt), om, _("Select one of the 17 symmetry groups for the tiling"), NULL); + gtk_box_pack_start (GTK_BOX (vb), om, FALSE, FALSE, SB_MARGIN); + + GtkWidget *m = gtk_menu_new (); + int current = prefs_get_int_attribute (prefs_path, "symmetrygroup", 0); + + struct SymGroups { + int group; + gchar const *label; + } const sym_groups[] = { + // TRANSLATORS: "translation" means "shift" / "displacement" here. + {TILE_P1, _("P1: simple translation")}, + {TILE_P2, _("P2: 180° rotation")}, + {TILE_PM, _("PM: reflection")}, + // TRANSLATORS: "glide reflection" is a reflection and a translation combined. + // For more info, see http://mathforum.org/sum95/suzanne/symsusan.html + {TILE_PG, _("PG: glide reflection")}, + {TILE_CM, _("CM: reflection + glide reflection")}, + {TILE_PMM, _("PMM: reflection + reflection")}, + {TILE_PMG, _("PMG: reflection + 180° rotation")}, + {TILE_PGG, _("PGG: glide reflection + 180° rotation")}, + {TILE_CMM, _("CMM: reflection + reflection + 180° rotation")}, + {TILE_P4, _("P4: 90° rotation")}, + {TILE_P4M, _("P4M: 90° rotation + 45° reflection")}, + {TILE_P4G, _("P4G: 90° rotation + 90° reflection")}, + {TILE_P3, _("P3: 120° rotation")}, + {TILE_P31M, _("P31M: reflection + 120° rotation, dense")}, + {TILE_P3M1, _("P3M1: reflection + 120° rotation, sparse")}, + {TILE_P6, _("P6: 60° rotation")}, + {TILE_P6M, _("P6M: reflection + 60° rotation")}, + }; + + for (unsigned j = 0; j < G_N_ELEMENTS(sym_groups); ++j) { + SymGroups const &sg = sym_groups[j]; + + GtkWidget *l = gtk_label_new (""); + gtk_label_set_markup (GTK_LABEL(l), sg.label); + gtk_misc_set_alignment (GTK_MISC(l), 0, 0.5); + + GtkWidget *item = gtk_menu_item_new (); + gtk_container_add (GTK_CONTAINER (item), l); + + gtk_signal_connect ( GTK_OBJECT (item), "activate", + GTK_SIGNAL_FUNC (clonetiler_symgroup_changed), + GINT_TO_POINTER (sg.group) ); + + gtk_menu_append (GTK_MENU (m), item); + } + + gtk_option_menu_set_menu (GTK_OPTION_MENU (om), m); + gtk_option_menu_set_history ( GTK_OPTION_MENU (om), current); + } + + table_row_labels = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); + +// Shift + { + GtkWidget *vb = clonetiler_new_tab (nb, _("S_hift")); + + GtkWidget *table = clonetiler_table_x_y_rand (3); + gtk_box_pack_start (GTK_BOX (vb), table, FALSE, FALSE, 0); + + // X + { + GtkWidget *l = gtk_label_new (""); + // TRANSLATORS: "shift" means: the tiles will be shifted (offset) horizontally by this amount + // xgettext:no-c-format + gtk_label_set_markup (GTK_LABEL(l), _("Shift X:")); + gtk_size_group_add_widget(table_row_labels, l); + clonetiler_table_attach (table, l, 1, 2, 1); + } + + { + GtkWidget *l = clonetiler_spinbox (tt, + // xgettext:no-c-format + _("Horizontal shift per row (in % of tile width)"), "d_x_per_y", + -100, 1000, "%"); + clonetiler_table_attach (table, l, 0, 2, 2); + } + + { + GtkWidget *l = clonetiler_spinbox (tt, + // xgettext:no-c-format + _("Horizontal shift per column (in % of tile width)"), "d_x_per_x", + -100, 1000, "%"); + clonetiler_table_attach (table, l, 0, 2, 3); + } + + { + GtkWidget *l = clonetiler_spinbox (tt, + _("Randomize the horizontal shift by this percentage"), "rand_x", + 0, 1000, "%"); + clonetiler_table_attach (table, l, 0, 2, 4); + } + + // Y + { + GtkWidget *l = gtk_label_new (""); + // TRANSLATORS: "shift" means: the tiles will be shifted (offset) vertically by this amount + // xgettext:no-c-format + gtk_label_set_markup (GTK_LABEL(l), _("Shift Y:")); + gtk_size_group_add_widget(table_row_labels, l); + clonetiler_table_attach (table, l, 1, 3, 1); + } + + { + GtkWidget *l = clonetiler_spinbox (tt, + // xgettext:no-c-format + _("Vertical shift per row (in % of tile height)"), "d_y_per_y", + -100, 1000, "%"); + clonetiler_table_attach (table, l, 0, 3, 2); + } + + { + GtkWidget *l = clonetiler_spinbox (tt, + // xgettext:no-c-format + _("Vertical shift per column (in % of tile height)"), "d_y_per_x", + -100, 1000, "%"); + clonetiler_table_attach (table, l, 0, 3, 3); + } + + { + GtkWidget *l = clonetiler_spinbox (tt, + _("Randomize the vertical shift by this percentage"), "rand_y", + 0, 1000, "%"); + clonetiler_table_attach (table, l, 0, 3, 4); + } + + // Exponent + { + GtkWidget *l = gtk_label_new (""); + gtk_label_set_markup (GTK_LABEL(l), _("Exponent:")); + gtk_size_group_add_widget(table_row_labels, l); + clonetiler_table_attach (table, l, 1, 4, 1); + } + + { + GtkWidget *l = clonetiler_spinbox (tt, + _("Whether rows are spaced evenly (1), converge (<1) or diverge (>1)"), "d_per_y_exp", + 0, 10, "", true); + clonetiler_table_attach (table, l, 0, 4, 2); + } + + { + GtkWidget *l = clonetiler_spinbox (tt, + _("Whether columns are spaced evenly (1), converge (<1) or diverge (>1)"), "d_per_x_exp", + 0, 10, "", true); + clonetiler_table_attach (table, l, 0, 4, 3); + } + + { // alternates + GtkWidget *l = gtk_label_new (""); + // TRANSLATORS: "Alternate" is a verb here + gtk_label_set_markup (GTK_LABEL(l), _("Alternate:")); + gtk_size_group_add_widget(table_row_labels, l); + clonetiler_table_attach (table, l, 1, 5, 1); + } + + { + GtkWidget *l = clonetiler_checkbox (tt, _("Alternate the sign of shifts for each row"), "alternate_y"); + clonetiler_table_attach (table, l, 0, 5, 2); + } + + { + GtkWidget *l = clonetiler_checkbox (tt, _("Alternate the sign of shifts for each column"), "alternate_x"); + clonetiler_table_attach (table, l, 0, 5, 3); + } + + } + + +// Scale + { + GtkWidget *vb = clonetiler_new_tab (nb, _("Sc_ale")); + + GtkWidget *table = clonetiler_table_x_y_rand (2); + gtk_box_pack_start (GTK_BOX (vb), table, FALSE, FALSE, 0); + + // X + { + GtkWidget *l = gtk_label_new (""); + gtk_label_set_markup (GTK_LABEL(l), _("Scale X:")); + gtk_size_group_add_widget(table_row_labels, l); + clonetiler_table_attach (table, l, 1, 2, 1); + } + + { + GtkWidget *l = clonetiler_spinbox (tt, + // xgettext:no-c-format + _("Horizontal scale per row (in % of tile width)"), "d_scalex_per_y", + -100, 1000, "%"); + clonetiler_table_attach (table, l, 0, 2, 2); + } + + { + GtkWidget *l = clonetiler_spinbox (tt, + // xgettext:no-c-format + _("Horizontal scale per column (in % of tile width)"), "d_scalex_per_x", + -100, 1000, "%"); + clonetiler_table_attach (table, l, 0, 2, 3); + } + + { + GtkWidget *l = clonetiler_spinbox (tt, + _("Randomize the horizontal scale by this percentage"), "rand_scalex", + 0, 1000, "%"); + clonetiler_table_attach (table, l, 0, 2, 4); + } + + // Y + { + GtkWidget *l = gtk_label_new (""); + gtk_label_set_markup (GTK_LABEL(l), _("Scale Y:")); + gtk_size_group_add_widget(table_row_labels, l); + clonetiler_table_attach (table, l, 1, 3, 1); + } + + { + GtkWidget *l = clonetiler_spinbox (tt, + // xgettext:no-c-format + _("Vertical scale per row (in % of tile height)"), "d_scaley_per_y", + -100, 1000, "%"); + clonetiler_table_attach (table, l, 0, 3, 2); + } + + { + GtkWidget *l = clonetiler_spinbox (tt, + // xgettext:no-c-format + _("Vertical scale per column (in % of tile height)"), "d_scaley_per_x", + -100, 1000, "%"); + clonetiler_table_attach (table, l, 0, 3, 3); + } + + { + GtkWidget *l = clonetiler_spinbox (tt, + _("Randomize the vertical scale by this percentage"), "rand_scaley", + 0, 1000, "%"); + clonetiler_table_attach (table, l, 0, 3, 4); + } + + { // alternates + GtkWidget *l = gtk_label_new (""); + // TRANSLATORS: "Alternate" is a verb here + gtk_label_set_markup (GTK_LABEL(l), _("Alternate:")); + gtk_size_group_add_widget(table_row_labels, l); + clonetiler_table_attach (table, l, 1, 4, 1); + } + + { + GtkWidget *l = clonetiler_checkbox (tt, _("Alternate the sign of scales for each row"), "alternate_scaley"); + clonetiler_table_attach (table, l, 0, 4, 2); + } + + { + GtkWidget *l = clonetiler_checkbox (tt, _("Alternate the sign of scales for each column"), "alternate_scalex"); + clonetiler_table_attach (table, l, 0, 4, 3); + } + + } + + +// Rotation + { + GtkWidget *vb = clonetiler_new_tab (nb, _("_Rotation")); + + GtkWidget *table = clonetiler_table_x_y_rand (1); + gtk_box_pack_start (GTK_BOX (vb), table, FALSE, FALSE, 0); + + // Angle + { + GtkWidget *l = gtk_label_new (""); + gtk_label_set_markup (GTK_LABEL(l), _("Angle:")); + gtk_size_group_add_widget(table_row_labels, l); + clonetiler_table_attach (table, l, 1, 2, 1); + } + + { + GtkWidget *l = clonetiler_spinbox (tt, + // xgettext:no-c-format + _("Rotate tiles by this angle for each row"), "d_rot_per_y", + -180, 180, "°"); + clonetiler_table_attach (table, l, 0, 2, 2); + } + + { + GtkWidget *l = clonetiler_spinbox (tt, + // xgettext:no-c-format + _("Rotate tiles by this angle for each column"), "d_rot_per_x", + -180, 180, "°"); + clonetiler_table_attach (table, l, 0, 2, 3); + } + + { + GtkWidget *l = clonetiler_spinbox (tt, + _("Randomize the rotation angle by this percentage"), "rand_rot", + 0, 100, "%"); + clonetiler_table_attach (table, l, 0, 2, 4); + } + + { // alternates + GtkWidget *l = gtk_label_new (""); + // TRANSLATORS: "Alternate" is a verb here + gtk_label_set_markup (GTK_LABEL(l), _("Alternate:")); + gtk_size_group_add_widget(table_row_labels, l); + clonetiler_table_attach (table, l, 1, 3, 1); + } + + { + GtkWidget *l = clonetiler_checkbox (tt, _("Alternate the rotation direction for each row"), "alternate_roty"); + clonetiler_table_attach (table, l, 0, 3, 2); + } + + { + GtkWidget *l = clonetiler_checkbox (tt, _("Alternate the rotation direction for each column"), "alternate_rotx"); + clonetiler_table_attach (table, l, 0, 3, 3); + } + } + + +// Opacity + { + GtkWidget *vb = clonetiler_new_tab (nb, _("_Opacity")); + + GtkWidget *table = clonetiler_table_x_y_rand (1); + gtk_box_pack_start (GTK_BOX (vb), table, FALSE, FALSE, 0); + + // Dissolve + { + GtkWidget *l = gtk_label_new (""); + gtk_label_set_markup (GTK_LABEL(l), _("Fade out:")); + gtk_size_group_add_widget(table_row_labels, l); + clonetiler_table_attach (table, l, 1, 2, 1); + } + + { + GtkWidget *l = clonetiler_spinbox (tt, + _("Decrease tile opacity by this percentage for each row"), "d_opacity_per_y", + 0, 100, "%"); + clonetiler_table_attach (table, l, 0, 2, 2); + } + + { + GtkWidget *l = clonetiler_spinbox (tt, + _("Decrease tile opacity by this percentage for each column"), "d_opacity_per_x", + 0, 100, "%"); + clonetiler_table_attach (table, l, 0, 2, 3); + } + + { + GtkWidget *l = clonetiler_spinbox (tt, + _("Randomize the tile opacity by this percentage"), "rand_opacity", + 0, 100, "%"); + clonetiler_table_attach (table, l, 0, 2, 4); + } + + { // alternates + GtkWidget *l = gtk_label_new (""); + // TRANSLATORS: "Alternate" is a verb here + gtk_label_set_markup (GTK_LABEL(l), _("Alternate:")); + gtk_size_group_add_widget(table_row_labels, l); + clonetiler_table_attach (table, l, 1, 3, 1); + } + + { + GtkWidget *l = clonetiler_checkbox (tt, _("Alternate the sign of opacity change for each row"), "alternate_opacityy"); + clonetiler_table_attach (table, l, 0, 3, 2); + } + + { + GtkWidget *l = clonetiler_checkbox (tt, _("Alternate the sign of opacity change for each column"), "alternate_opacityx"); + clonetiler_table_attach (table, l, 0, 3, 3); + } + } + + +// Color + { + GtkWidget *vb = clonetiler_new_tab (nb, _("Co_lor")); + + { + GtkWidget *hb = gtk_hbox_new (FALSE, 0); + + GtkWidget *l = gtk_label_new (_("Initial color: ")); + gtk_box_pack_start (GTK_BOX (hb), l, FALSE, FALSE, 0); + + guint32 rgba = 0x000000ff | sp_svg_read_color (prefs_get_string_attribute(prefs_path, "initial_color"), 0x000000ff); + color_picker = new Inkscape::UI::Widget::ColorPicker (*new Glib::ustring(_("Initial color of tiled clones")), *new Glib::ustring(_("Initial color for clones (works only if the original has unset fill or stroke)")), rgba, false); + _color_changed_connection = color_picker->connectChanged (sigc::ptr_fun(on_picker_color_changed)); + + gtk_box_pack_start (GTK_BOX (hb), reinterpret_cast(color_picker->gobj()), FALSE, FALSE, 0); + + gtk_box_pack_start (GTK_BOX (vb), hb, FALSE, FALSE, 0); + } + + + GtkWidget *table = clonetiler_table_x_y_rand (3); + gtk_box_pack_start (GTK_BOX (vb), table, FALSE, FALSE, 0); + + // Hue + { + GtkWidget *l = gtk_label_new (""); + gtk_label_set_markup (GTK_LABEL(l), _("H:")); + gtk_size_group_add_widget(table_row_labels, l); + clonetiler_table_attach (table, l, 1, 2, 1); + } + + { + GtkWidget *l = clonetiler_spinbox (tt, + _("Change the tile hue by this percentage for each row"), "d_hue_per_y", + -100, 100, "%"); + clonetiler_table_attach (table, l, 0, 2, 2); + } + + { + GtkWidget *l = clonetiler_spinbox (tt, + _("Change the tile hue by this percentage for each column"), "d_hue_per_x", + -100, 100, "%"); + clonetiler_table_attach (table, l, 0, 2, 3); + } + + { + GtkWidget *l = clonetiler_spinbox (tt, + _("Randomize the tile hue by this percentage"), "rand_hue", + 0, 100, "%"); + clonetiler_table_attach (table, l, 0, 2, 4); + } + + + // Saturation + { + GtkWidget *l = gtk_label_new (""); + gtk_label_set_markup (GTK_LABEL(l), _("S:")); + gtk_size_group_add_widget(table_row_labels, l); + clonetiler_table_attach (table, l, 1, 3, 1); + } + + { + GtkWidget *l = clonetiler_spinbox (tt, + _("Change the color saturation by this percentage for each row"), "d_saturation_per_y", + -100, 100, "%"); + clonetiler_table_attach (table, l, 0, 3, 2); + } + + { + GtkWidget *l = clonetiler_spinbox (tt, + _("Change the color saturation by this percentage for each column"), "d_saturation_per_x", + -100, 100, "%"); + clonetiler_table_attach (table, l, 0, 3, 3); + } + + { + GtkWidget *l = clonetiler_spinbox (tt, + _("Randomize the color saturation by this percentage"), "rand_saturation", + 0, 100, "%"); + clonetiler_table_attach (table, l, 0, 3, 4); + } + + // Lightness + { + GtkWidget *l = gtk_label_new (""); + gtk_label_set_markup (GTK_LABEL(l), _("L:")); + gtk_size_group_add_widget(table_row_labels, l); + clonetiler_table_attach (table, l, 1, 4, 1); + } + + { + GtkWidget *l = clonetiler_spinbox (tt, + _("Change the color lightness by this percentage for each row"), "d_lightness_per_y", + -100, 100, "%"); + clonetiler_table_attach (table, l, 0, 4, 2); + } + + { + GtkWidget *l = clonetiler_spinbox (tt, + _("Change the color lightness by this percentage for each column"), "d_lightness_per_x", + -100, 100, "%"); + clonetiler_table_attach (table, l, 0, 4, 3); + } + + { + GtkWidget *l = clonetiler_spinbox (tt, + _("Randomize the color lightness by this percentage"), "rand_lightness", + 0, 100, "%"); + clonetiler_table_attach (table, l, 0, 4, 4); + } + + + { // alternates + GtkWidget *l = gtk_label_new (""); + gtk_label_set_markup (GTK_LABEL(l), _("Alternate:")); + gtk_size_group_add_widget(table_row_labels, l); + clonetiler_table_attach (table, l, 1, 5, 1); + } + + { + GtkWidget *l = clonetiler_checkbox (tt, _("Alternate the sign of color changes for each row"), "alternate_color_y"); + clonetiler_table_attach (table, l, 0, 5, 2); + } + + { + GtkWidget *l = clonetiler_checkbox (tt, _("Alternate the sign of color changes for each column"), "alternate_color_x"); + clonetiler_table_attach (table, l, 0, 5, 3); + } + + } + +// Trace + { + GtkWidget *vb = clonetiler_new_tab (nb, _("_Trace")); + + + { + GtkWidget *hb = gtk_hbox_new(FALSE, VB_MARGIN); + gtk_box_pack_start (GTK_BOX (vb), hb, FALSE, FALSE, 0); + + GtkWidget *b = gtk_check_button_new_with_label (_("Trace the drawing under the tiles")); + g_object_set_data (G_OBJECT(b), "uncheckable", GINT_TO_POINTER(TRUE)); + gint old = prefs_get_int_attribute (prefs_path, "dotrace", 0); + gtk_toggle_button_set_active ((GtkToggleButton *) b, old != 0); + gtk_tooltips_set_tip (GTK_TOOLTIPS (tt), b, _("For each clone, pick a value from the drawing in that clone's location and apply it to the clone"), NULL); + gtk_box_pack_start (GTK_BOX (hb), b, FALSE, FALSE, 0); + + gtk_signal_connect(GTK_OBJECT(b), "toggled", + GTK_SIGNAL_FUNC(clonetiler_do_pick_toggled), dlg); + } + + { + GtkWidget *vvb = gtk_vbox_new (FALSE, 0); + gtk_box_pack_start (GTK_BOX (vb), vvb, FALSE, FALSE, 0); + g_object_set_data (G_OBJECT(dlg), "dotrace", (gpointer) vvb); + + + { + GtkWidget *frame = gtk_frame_new (_("1. Pick from the drawing:")); + gtk_box_pack_start (GTK_BOX (vvb), frame, FALSE, FALSE, 0); + + GtkWidget *table = gtk_table_new (3, 3, FALSE); + gtk_table_set_row_spacings (GTK_TABLE (table), 4); + gtk_table_set_col_spacings (GTK_TABLE (table), 6); + gtk_container_add(GTK_CONTAINER(frame), table); + + + GtkWidget* radio; + { + radio = gtk_radio_button_new_with_label (NULL, _("Color")); + gtk_tooltips_set_tip (GTK_TOOLTIPS (tt), radio, _("Pick the visible color and opacity"), NULL); + clonetiler_table_attach (table, radio, 0.0, 1, 1); + gtk_signal_connect (GTK_OBJECT (radio), "toggled", + GTK_SIGNAL_FUNC (clonetiler_pick_switched), GINT_TO_POINTER(PICK_COLOR)); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radio), prefs_get_int_attribute(prefs_path, "pick", 0) == PICK_COLOR); + } + { + radio = gtk_radio_button_new_with_label (gtk_radio_button_group (GTK_RADIO_BUTTON (radio)), _("Opacity")); + gtk_tooltips_set_tip (GTK_TOOLTIPS (tt), radio, _("Pick the total accumulated opacity"), NULL); + clonetiler_table_attach (table, radio, 0.0, 2, 1); + gtk_signal_connect (GTK_OBJECT (radio), "toggled", + GTK_SIGNAL_FUNC (clonetiler_pick_switched), GINT_TO_POINTER(PICK_OPACITY)); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radio), prefs_get_int_attribute(prefs_path, "pick", 0) == PICK_OPACITY); + } + { + radio = gtk_radio_button_new_with_label (gtk_radio_button_group (GTK_RADIO_BUTTON (radio)), _("R")); + gtk_tooltips_set_tip (GTK_TOOLTIPS (tt), radio, _("Pick the Red component of the color"), NULL); + clonetiler_table_attach (table, radio, 0.0, 1, 2); + gtk_signal_connect (GTK_OBJECT (radio), "toggled", + GTK_SIGNAL_FUNC (clonetiler_pick_switched), GINT_TO_POINTER(PICK_R)); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radio), prefs_get_int_attribute(prefs_path, "pick", 0) == PICK_R); + } + { + radio = gtk_radio_button_new_with_label (gtk_radio_button_group (GTK_RADIO_BUTTON (radio)), _("G")); + gtk_tooltips_set_tip (GTK_TOOLTIPS (tt), radio, _("Pick the Green component of the color"), NULL); + clonetiler_table_attach (table, radio, 0.0, 2, 2); + gtk_signal_connect (GTK_OBJECT (radio), "toggled", + GTK_SIGNAL_FUNC (clonetiler_pick_switched), GINT_TO_POINTER(PICK_G)); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radio), prefs_get_int_attribute(prefs_path, "pick", 0) == PICK_G); + } + { + radio = gtk_radio_button_new_with_label (gtk_radio_button_group (GTK_RADIO_BUTTON (radio)), _("B")); + gtk_tooltips_set_tip (GTK_TOOLTIPS (tt), radio, _("Pick the Blue component of the color"), NULL); + clonetiler_table_attach (table, radio, 0.0, 3, 2); + gtk_signal_connect (GTK_OBJECT (radio), "toggled", + GTK_SIGNAL_FUNC (clonetiler_pick_switched), GINT_TO_POINTER(PICK_B)); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radio), prefs_get_int_attribute(prefs_path, "pick", 0) == PICK_B); + } + { + //TRANSLATORS: only translate "string" in "context|string". + // For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS + radio = gtk_radio_button_new_with_label (gtk_radio_button_group (GTK_RADIO_BUTTON (radio)), Q_("clonetiler|H")); + gtk_tooltips_set_tip (GTK_TOOLTIPS (tt), radio, _("Pick the hue of the color"), NULL); + clonetiler_table_attach (table, radio, 0.0, 1, 3); + gtk_signal_connect (GTK_OBJECT (radio), "toggled", + GTK_SIGNAL_FUNC (clonetiler_pick_switched), GINT_TO_POINTER(PICK_H)); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radio), prefs_get_int_attribute(prefs_path, "pick", 0) == PICK_H); + } + { + //TRANSLATORS: only translate "string" in "context|string". + // For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS + radio = gtk_radio_button_new_with_label (gtk_radio_button_group (GTK_RADIO_BUTTON (radio)), Q_("clonetiler|S")); + gtk_tooltips_set_tip (GTK_TOOLTIPS (tt), radio, _("Pick the saturation of the color"), NULL); + clonetiler_table_attach (table, radio, 0.0, 2, 3); + gtk_signal_connect (GTK_OBJECT (radio), "toggled", + GTK_SIGNAL_FUNC (clonetiler_pick_switched), GINT_TO_POINTER(PICK_S)); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radio), prefs_get_int_attribute(prefs_path, "pick", 0) == PICK_S); + } + { + //TRANSLATORS: only translate "string" in "context|string". + // For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS + radio = gtk_radio_button_new_with_label (gtk_radio_button_group (GTK_RADIO_BUTTON (radio)), Q_("clonetiler|L")); + gtk_tooltips_set_tip (GTK_TOOLTIPS (tt), radio, _("Pick the lightness of the color"), NULL); + clonetiler_table_attach (table, radio, 0.0, 3, 3); + gtk_signal_connect (GTK_OBJECT (radio), "toggled", + GTK_SIGNAL_FUNC (clonetiler_pick_switched), GINT_TO_POINTER(PICK_L)); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radio), prefs_get_int_attribute(prefs_path, "pick", 0) == PICK_L); + } + + } + + { + GtkWidget *frame = gtk_frame_new (_("2. Tweak the picked value:")); + gtk_box_pack_start (GTK_BOX (vvb), frame, FALSE, FALSE, VB_MARGIN); + + GtkWidget *table = gtk_table_new (4, 2, FALSE); + gtk_table_set_row_spacings (GTK_TABLE (table), 4); + gtk_table_set_col_spacings (GTK_TABLE (table), 6); + gtk_container_add(GTK_CONTAINER(frame), table); + + { + GtkWidget *l = gtk_label_new (""); + gtk_label_set_markup (GTK_LABEL(l), _("Gamma-correct:")); + clonetiler_table_attach (table, l, 1.0, 1, 1); + } + { + GtkWidget *l = clonetiler_spinbox (tt, + _("Shift the mid-range of the picked value upwards (>0) or downwards (<0)"), "gamma_picked", + -10, 10, ""); + clonetiler_table_attach (table, l, 0.0, 1, 2); + } + + { + GtkWidget *l = gtk_label_new (""); + gtk_label_set_markup (GTK_LABEL(l), _("Randomize:")); + clonetiler_table_attach (table, l, 1.0, 1, 3); + } + { + GtkWidget *l = clonetiler_spinbox (tt, + _("Randomize the picked value by this percentage"), "rand_picked", + 0, 100, "%"); + clonetiler_table_attach (table, l, 0.0, 1, 4); + } + + { + GtkWidget *l = gtk_label_new (""); + gtk_label_set_markup (GTK_LABEL(l), _("Invert:")); + clonetiler_table_attach (table, l, 1.0, 2, 1); + } + { + GtkWidget *l = clonetiler_checkbox (tt, _("Invert the picked value"), "invert_picked"); + clonetiler_table_attach (table, l, 0.0, 2, 2); + } + } + + { + GtkWidget *frame = gtk_frame_new (_("3. Apply the value to the clones':")); + gtk_box_pack_start (GTK_BOX (vvb), frame, FALSE, FALSE, 0); + + + GtkWidget *table = gtk_table_new (2, 2, FALSE); + gtk_table_set_row_spacings (GTK_TABLE (table), 4); + gtk_table_set_col_spacings (GTK_TABLE (table), 6); + gtk_container_add(GTK_CONTAINER(frame), table); + + { + GtkWidget *b = gtk_check_button_new_with_label (_("Presence")); + gint old = prefs_get_int_attribute (prefs_path, "pick_to_presence", 1); + gtk_toggle_button_set_active ((GtkToggleButton *) b, old != 0); + gtk_tooltips_set_tip (GTK_TOOLTIPS (tt), b, _("Each clone is created with the probability determined by the picked value in that point"), NULL); + clonetiler_table_attach (table, b, 0.0, 1, 1); + gtk_signal_connect(GTK_OBJECT(b), "toggled", + GTK_SIGNAL_FUNC(clonetiler_pick_to), (gpointer) "pick_to_presence"); + } + + { + GtkWidget *b = gtk_check_button_new_with_label (_("Size")); + gint old = prefs_get_int_attribute (prefs_path, "pick_to_size", 0); + gtk_toggle_button_set_active ((GtkToggleButton *) b, old != 0); + gtk_tooltips_set_tip (GTK_TOOLTIPS (tt), b, _("Each clone's size is determined by the picked value in that point"), NULL); + clonetiler_table_attach (table, b, 0.0, 2, 1); + gtk_signal_connect(GTK_OBJECT(b), "toggled", + GTK_SIGNAL_FUNC(clonetiler_pick_to), (gpointer) "pick_to_size"); + } + + { + GtkWidget *b = gtk_check_button_new_with_label (_("Color")); + gint old = prefs_get_int_attribute (prefs_path, "pick_to_color", 0); + gtk_toggle_button_set_active ((GtkToggleButton *) b, old != 0); + gtk_tooltips_set_tip (GTK_TOOLTIPS (tt), b, _("Each clone is painted by the picked color (the original must have unset fill or stroke)"), NULL); + clonetiler_table_attach (table, b, 0.0, 1, 2); + gtk_signal_connect(GTK_OBJECT(b), "toggled", + GTK_SIGNAL_FUNC(clonetiler_pick_to), (gpointer) "pick_to_color"); + } + + { + GtkWidget *b = gtk_check_button_new_with_label (_("Opacity")); + gint old = prefs_get_int_attribute (prefs_path, "pick_to_opacity", 0); + gtk_toggle_button_set_active ((GtkToggleButton *) b, old != 0); + gtk_tooltips_set_tip (GTK_TOOLTIPS (tt), b, _("Each clone's opacity is determined by the picked value in that point"), NULL); + clonetiler_table_attach (table, b, 0.0, 2, 2); + gtk_signal_connect(GTK_OBJECT(b), "toggled", + GTK_SIGNAL_FUNC(clonetiler_pick_to), (gpointer) "pick_to_opacity"); + } + } + gtk_widget_set_sensitive (vvb, prefs_get_int_attribute (prefs_path, "dotrace", 0)); + } + } + +// Rows/columns, width/height + { + GtkWidget *table = gtk_table_new (2, 2, FALSE); + gtk_container_set_border_width (GTK_CONTAINER (table), VB_MARGIN); + gtk_table_set_row_spacings (GTK_TABLE (table), 4); + gtk_table_set_col_spacings (GTK_TABLE (table), 6); + gtk_box_pack_start (GTK_BOX (mainbox), table, FALSE, FALSE, 0); + + { + GtkWidget *hb = gtk_hbox_new(FALSE, VB_MARGIN); + g_object_set_data (G_OBJECT(dlg), "rowscols", (gpointer) hb); + + { + GtkObject *a = gtk_adjustment_new(0.0, 1, 500, 1, 10, 10); + int value = prefs_get_int_attribute (prefs_path, "ymax", 2); + gtk_adjustment_set_value (GTK_ADJUSTMENT (a), value); + GtkWidget *sb = gtk_spin_button_new (GTK_ADJUSTMENT (a), 1.0, 0); + gtk_tooltips_set_tip (GTK_TOOLTIPS (tt), sb, _("How many rows in the tiling"), NULL); + gtk_entry_set_width_chars (GTK_ENTRY (sb), 5); + gtk_box_pack_start (GTK_BOX (hb), sb, TRUE, TRUE, 0); + + gtk_signal_connect(GTK_OBJECT(a), "value_changed", + GTK_SIGNAL_FUNC(clonetiler_xy_changed), (gpointer) "ymax"); + } + + { + GtkWidget *l = gtk_label_new (""); + gtk_label_set_markup (GTK_LABEL(l), "×"); + gtk_misc_set_alignment (GTK_MISC (l), 1.0, 0.5); + gtk_box_pack_start (GTK_BOX (hb), l, TRUE, TRUE, 0); + } + + { + GtkObject *a = gtk_adjustment_new(0.0, 1, 500, 1, 10, 10); + int value = prefs_get_int_attribute (prefs_path, "xmax", 2); + gtk_adjustment_set_value (GTK_ADJUSTMENT (a), value); + GtkWidget *sb = gtk_spin_button_new (GTK_ADJUSTMENT (a), 1.0, 0); + gtk_tooltips_set_tip (GTK_TOOLTIPS (tt), sb, _("How many columns in the tiling"), NULL); + gtk_entry_set_width_chars (GTK_ENTRY (sb), 5); + gtk_box_pack_start (GTK_BOX (hb), sb, TRUE, TRUE, 0); + + gtk_signal_connect(GTK_OBJECT(a), "value_changed", + GTK_SIGNAL_FUNC(clonetiler_xy_changed), (gpointer) "xmax"); + } + + clonetiler_table_attach (table, hb, 0.0, 1, 2); + } + + { + GtkWidget *hb = gtk_hbox_new(FALSE, VB_MARGIN); + g_object_set_data (G_OBJECT(dlg), "widthheight", (gpointer) hb); + + // unitmenu + GtkWidget *u = sp_unit_selector_new (SP_UNIT_ABSOLUTE | SP_UNIT_DEVICE); + sp_unit_selector_set_unit (SP_UNIT_SELECTOR(u), SP_DT_NAMEDVIEW(SP_ACTIVE_DESKTOP)->doc_units); + + { + // Width spinbutton + GtkObject *a = gtk_adjustment_new (0.0, -SP_DESKTOP_SCROLL_LIMIT, SP_DESKTOP_SCROLL_LIMIT, 1.0, 10.0, 10.0); + sp_unit_selector_add_adjustment (SP_UNIT_SELECTOR (u), GTK_ADJUSTMENT (a)); + + double value = prefs_get_double_attribute (prefs_path, "fillwidth", 50); + SPUnit const &unit = *sp_unit_selector_get_unit(SP_UNIT_SELECTOR(u)); + gdouble const units = sp_pixels_get_units (value, unit); + gtk_adjustment_set_value (GTK_ADJUSTMENT (a), units); + + GtkWidget *e = gtk_spin_button_new (GTK_ADJUSTMENT (a), 1.0 , 2); + gtk_tooltips_set_tip (GTK_TOOLTIPS (tt), e, _("Width of the rectangle to be filled"), NULL); + gtk_entry_set_width_chars (GTK_ENTRY (e), 5); + gtk_box_pack_start (GTK_BOX (hb), e, TRUE, TRUE, 0); + gtk_signal_connect(GTK_OBJECT(a), "value_changed", + GTK_SIGNAL_FUNC(clonetiler_fill_width_changed), u); + } + { + GtkWidget *l = gtk_label_new (""); + gtk_label_set_markup (GTK_LABEL(l), "×"); + gtk_misc_set_alignment (GTK_MISC (l), 1.0, 0.5); + gtk_box_pack_start (GTK_BOX (hb), l, TRUE, TRUE, 0); + } + + { + // Height spinbutton + GtkObject *a = gtk_adjustment_new (0.0, -SP_DESKTOP_SCROLL_LIMIT, SP_DESKTOP_SCROLL_LIMIT, 1.0, 10.0, 10.0); + sp_unit_selector_add_adjustment (SP_UNIT_SELECTOR (u), GTK_ADJUSTMENT (a)); + + double value = prefs_get_double_attribute (prefs_path, "fillheight", 50); + SPUnit const &unit = *sp_unit_selector_get_unit(SP_UNIT_SELECTOR(u)); + gdouble const units = sp_pixels_get_units (value, unit); + gtk_adjustment_set_value (GTK_ADJUSTMENT (a), units); + + + GtkWidget *e = gtk_spin_button_new (GTK_ADJUSTMENT (a), 1.0 , 2); + gtk_tooltips_set_tip (GTK_TOOLTIPS (tt), e, _("Height of the rectangle to be filled"), NULL); + gtk_entry_set_width_chars (GTK_ENTRY (e), 5); + gtk_box_pack_start (GTK_BOX (hb), e, TRUE, TRUE, 0); + gtk_signal_connect(GTK_OBJECT(a), "value_changed", + GTK_SIGNAL_FUNC(clonetiler_fill_height_changed), u); + } + + gtk_box_pack_start (GTK_BOX (hb), u, TRUE, TRUE, 0); + clonetiler_table_attach (table, hb, 0.0, 2, 2); + + } + + // Switch + GtkWidget* radio; + { + radio = gtk_radio_button_new_with_label (NULL, _("Rows, columns: ")); + gtk_tooltips_set_tip (GTK_TOOLTIPS (tt), radio, _("Create the specified number of rows and columns"), NULL); + clonetiler_table_attach (table, radio, 0.0, 1, 1); + gtk_signal_connect (GTK_OBJECT (radio), "toggled", GTK_SIGNAL_FUNC (clonetiler_switch_to_create), (gpointer) dlg); + } + if (prefs_get_int_attribute(prefs_path, "fillrect", 0) == 0) { + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radio), TRUE); + gtk_toggle_button_toggled (GTK_TOGGLE_BUTTON (radio)); + } + { + radio = gtk_radio_button_new_with_label (gtk_radio_button_group (GTK_RADIO_BUTTON (radio)), _("Width, height: ")); + gtk_tooltips_set_tip (GTK_TOOLTIPS (tt), radio, _("Fill the specified width and height with the tiling"), NULL); + clonetiler_table_attach (table, radio, 0.0, 2, 1); + gtk_signal_connect (GTK_OBJECT (radio), "toggled", GTK_SIGNAL_FUNC (clonetiler_switch_to_fill), (gpointer) dlg); + } + if (prefs_get_int_attribute(prefs_path, "fillrect", 0) == 1) { + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radio), TRUE); + gtk_toggle_button_toggled (GTK_TOGGLE_BUTTON (radio)); + } + } + + +// Use saved pos + { + GtkWidget *hb = gtk_hbox_new(FALSE, VB_MARGIN); + gtk_box_pack_start (GTK_BOX (mainbox), hb, FALSE, FALSE, 0); + + GtkWidget *b = gtk_check_button_new_with_label (_("Use saved size and position of the tile")); + gint keepbbox = prefs_get_int_attribute (prefs_path, "keepbbox", 1); + gtk_toggle_button_set_active ((GtkToggleButton *) b, keepbbox != 0); + gtk_tooltips_set_tip (GTK_TOOLTIPS (tt), b, _("Pretend that the size and position of the tile are the same as the last time you tiled it (if any), instead of using the current size"), NULL); + gtk_box_pack_start (GTK_BOX (hb), b, FALSE, FALSE, 0); + + gtk_signal_connect(GTK_OBJECT(b), "toggled", + GTK_SIGNAL_FUNC(clonetiler_keep_bbox_toggled), NULL); + } + +// Statusbar + { + GtkWidget *hb = gtk_hbox_new(FALSE, VB_MARGIN); + gtk_box_pack_end (GTK_BOX (mainbox), hb, FALSE, FALSE, 0); + GtkWidget *l = gtk_label_new(""); + g_object_set_data (G_OBJECT(dlg), "status", (gpointer) l); + gtk_box_pack_start (GTK_BOX (hb), l, FALSE, FALSE, 0); + } + +// Buttons + { + GtkWidget *hb = gtk_hbox_new(FALSE, VB_MARGIN); + gtk_box_pack_start (GTK_BOX (mainbox), hb, FALSE, FALSE, 0); + + { + GtkWidget *b = gtk_button_new (); + GtkWidget *l = gtk_label_new (""); + gtk_label_set_markup_with_mnemonic (GTK_LABEL(l), _(" _Create ")); + gtk_container_add (GTK_CONTAINER(b), l); + gtk_tooltips_set_tip (tt, b, _("Create and tile the clones of the selection"), NULL); + gtk_signal_connect (GTK_OBJECT (b), "clicked", GTK_SIGNAL_FUNC (clonetiler_apply), NULL); + gtk_box_pack_end (GTK_BOX (hb), b, FALSE, FALSE, 0); + } + + { // buttons which are enabled only when there are tiled clones + GtkWidget *sb = gtk_hbox_new(FALSE, 0); + gtk_box_pack_end (GTK_BOX (hb), sb, FALSE, FALSE, 0); + g_object_set_data (G_OBJECT(dlg), "buttons_on_tiles", (gpointer) sb); + { + // TRANSLATORS: if a group of objects are "clumped" together, then they + // are unevenly spread in the given amount of space - as shown in the + // diagrams on the left in the following screenshot: + // http://www.inkscape.org/screenshots/gallery/inkscape-0.42-CVS-tiles-unclump.png + // So unclumping is the process of spreading a number of objects out more evenly. + GtkWidget *b = gtk_button_new_with_mnemonic (_(" _Unclump ")); + gtk_tooltips_set_tip (tt, b, _("Spread out clones to reduce clumping; can be applied repeatedly"), NULL); + gtk_signal_connect (GTK_OBJECT (b), "clicked", GTK_SIGNAL_FUNC (clonetiler_unclump), NULL); + gtk_box_pack_end (GTK_BOX (sb), b, FALSE, FALSE, 0); + } + + { + GtkWidget *b = gtk_button_new_with_mnemonic (_(" Re_move ")); + gtk_tooltips_set_tip (tt, b, _("Remove existing tiled clones of the selected object (siblings only)"), NULL); + gtk_signal_connect (GTK_OBJECT (b), "clicked", GTK_SIGNAL_FUNC (clonetiler_remove), NULL); + gtk_box_pack_end (GTK_BOX (sb), b, FALSE, FALSE, 0); + } + + // connect to global selection changed signal (so we can change desktops) and + // external_change (so we're not fooled by undo) + g_signal_connect (G_OBJECT (INKSCAPE), "change_selection", G_CALLBACK (clonetiler_change_selection), dlg); + g_signal_connect (G_OBJECT (INKSCAPE), "external_change", G_CALLBACK (clonetiler_external_change), dlg); + g_signal_connect(G_OBJECT(dlg), "destroy", G_CALLBACK(clonetiler_disconnect_gsignal), G_OBJECT (INKSCAPE)); + + // update now + clonetiler_change_selection (NULL, SP_DT_SELECTION(SP_ACTIVE_DESKTOP), dlg); + } + + { + GtkWidget *b = gtk_button_new_with_mnemonic (_(" R_eset ")); + // TRANSLATORS: "change" is a noun here + gtk_tooltips_set_tip (tt, b, _("Reset all shifts, scales, rotates, opacity and color changes in the dialog to zero"), NULL); + gtk_signal_connect (GTK_OBJECT (b), "clicked", GTK_SIGNAL_FUNC (clonetiler_reset), NULL); + gtk_box_pack_start (GTK_BOX (hb), b, FALSE, FALSE, 0); + } + } + + gtk_widget_show_all (mainbox); + + } // end of if (!dlg) + + gtk_window_present ((GtkWindow *) dlg); +} + + +/* + 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:textwidth=99 : diff --git a/src/dialogs/clonetiler.h b/src/dialogs/clonetiler.h new file mode 100644 index 000000000..82206818c --- /dev/null +++ b/src/dialogs/clonetiler.h @@ -0,0 +1,31 @@ +#ifndef __SP_CLONE_TILER_H__ +#define __SP_CLONE_TILER_H__ + +/** + * \brief Clone tiling dialog + * + * Authors: + * bulia byak + * + * Copyright (C) 2004 Authors + * + */ + +#include + +#include + +void clonetiler_dialog ( void ); + +#endif + +/* + 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:textwidth=99 : diff --git a/src/dialogs/debugdialog.cpp b/src/dialogs/debugdialog.cpp new file mode 100644 index 000000000..e90f0a419 --- /dev/null +++ b/src/dialogs/debugdialog.cpp @@ -0,0 +1,348 @@ +/* + * A very simple dialog for displaying Inkscape messages. Messages + * sent to g_log(), g_warning(), g_message(), ets, are routed here, + * in order to avoid messing with the startup console. + * + * Authors: + * Bob Jamison + * Other dudes from The Inkscape Organization + * + * Copyright (C) 2004 The Inkscape Organization + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include "debugdialog.h" + +namespace Inkscape { +namespace UI { +namespace Dialogs { + + +//######################################################################### +//## I M P L E M E N T A T I O N +//######################################################################### + +/** + * A dialog that displays log messages + */ +class DebugDialogImpl : public DebugDialog, public Gtk::Dialog +{ + + public: + + + /** + * Constructor + */ + DebugDialogImpl(); + + /** + * Destructor + */ + ~DebugDialogImpl(); + + + /** + * Show the dialog + */ + void show(); + + /** + * Do not show the dialog + */ + void hide(); + + /** + * Clear all information from the dialog + */ + void clear(); + + /** + * Display a message + */ + void message(char const *msg); + + /** + * Redirect g_log() messages to this widget + */ + void captureLogMessages(); + + /** + * Return g_log() messages to normal handling + */ + void releaseLogMessages(); + + + + private: + + + Gtk::MenuBar menuBar; + + Gtk::Menu fileMenu; + + Gtk::ScrolledWindow textScroll; + + Gtk::TextView messageText; + + //Handler ID's + guint handlerDefault; + guint handlerGlibmm; + guint handlerAtkmm; + guint handlerPangomm; + guint handlerGdkmm; + guint handlerGtkmm; + +}; + + + + +//######################################################################### +//## E V E N T S +//######################################################################### + +/** + * Also a public method. Remove all text from the dialog + */ +void DebugDialogImpl::clear() +{ + Glib::RefPtr buffer = messageText.get_buffer(); + buffer->erase(buffer->begin(), buffer->end()); +} + + +//######################################################################### +//## C O N S T R U C T O R / D E S T R U C T O R +//######################################################################### +/** + * Constructor + */ +DebugDialogImpl::DebugDialogImpl() +{ + set_title(_("Messages")); + set_size_request(300, 400); + + Gtk::VBox *mainVBox = get_vbox(); + + //## Add a menu for clear() + menuBar.items().push_back( Gtk::Menu_Helpers::MenuElem(_("_File"), fileMenu) ); + fileMenu.items().push_back( Gtk::Menu_Helpers::MenuElem(_("_Clear"), + sigc::mem_fun(*this, &DebugDialogImpl::clear) ) ); + fileMenu.items().push_back( Gtk::Menu_Helpers::MenuElem(_("Capture log messages"), + sigc::mem_fun(*this, &DebugDialogImpl::captureLogMessages) ) ); + fileMenu.items().push_back( Gtk::Menu_Helpers::MenuElem(_("Release log messages"), + sigc::mem_fun(*this, &DebugDialogImpl::releaseLogMessages) ) ); + mainVBox->pack_start(menuBar, Gtk::PACK_SHRINK); + + + //### Set up the text widget + messageText.set_editable(false); + textScroll.add(messageText); + textScroll.set_policy(Gtk::POLICY_ALWAYS, Gtk::POLICY_ALWAYS); + mainVBox->pack_start(textScroll); + + show_all_children(); + + message("ready."); + message("enable log display by setting "); + message("dialogs.debug 'redirect' attribute to 1 in preferences.xml"); + + handlerDefault = 0; + handlerGlibmm = 0; + handlerAtkmm = 0; + handlerPangomm = 0; + handlerGdkmm = 0; + handlerGtkmm = 0; +} + +/** + * Factory method. Use this to create a new DebugDialog + */ +DebugDialog *DebugDialog::create() +{ + DebugDialog *dialog = new DebugDialogImpl(); + return dialog; +} + + +/** + * Constructor + */ +DebugDialogImpl::~DebugDialogImpl() +{ + + +} + + +//######################################################################### +//## M E T H O D S +//######################################################################### + +void DebugDialogImpl::show() +{ + //call super() + Gtk::Dialog::show(); + //sp_transientize((GtkWidget *)gobj()); //Make transient + raise(); + Gtk::Dialog::present(); +} + + + +void DebugDialogImpl::hide() +{ + //call super() + Gtk::Dialog::hide(); +} + + + +void DebugDialogImpl::message(char const *msg) +{ + Glib::RefPtr buffer = messageText.get_buffer(); + Glib::ustring uMsg = msg; + if (uMsg[uMsg.length()-1] != '\n') + uMsg += '\n'; + buffer->insert (buffer->end(), uMsg); +} + + +/* static instance, to reduce dependencies */ +static DebugDialog *debugDialogInstance = NULL; + +DebugDialog *DebugDialog::getInstance() +{ + if ( !debugDialogInstance ) + { + debugDialogInstance = new DebugDialogImpl(); + } + return debugDialogInstance; +} + + + +void DebugDialog::showInstance() +{ + DebugDialog *debugDialog = getInstance(); + debugDialog->show(); +} + + + + +/*##### THIS IS THE IMPORTANT PART ##### */ +void dialogLoggingFunction(const gchar *log_domain, + GLogLevelFlags log_level, + const gchar *messageText, + gpointer user_data) +{ + DebugDialogImpl *dlg = (DebugDialogImpl *)user_data; + + dlg->message(messageText); + +} + + +void DebugDialogImpl::captureLogMessages() +{ + /* + This might likely need more code, to capture Gtkmm + and Glibmm warnings, or maybe just simply grab stdout/stderr + */ + GLogLevelFlags flags = (GLogLevelFlags) (G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL | + G_LOG_LEVEL_WARNING | G_LOG_LEVEL_MESSAGE | + G_LOG_LEVEL_INFO | G_LOG_LEVEL_DEBUG); + if ( !handlerDefault ) + { + handlerDefault = g_log_set_handler(NULL, flags, + dialogLoggingFunction, (gpointer)this); + } + if ( !handlerGlibmm ) + { + handlerGlibmm = g_log_set_handler("glibmm", flags, + dialogLoggingFunction, (gpointer)this); + } + if ( !handlerAtkmm ) + { + handlerAtkmm = g_log_set_handler("atkmm", flags, + dialogLoggingFunction, (gpointer)this); + } + if ( !handlerPangomm ) + { + handlerPangomm = g_log_set_handler("pangomm", flags, + dialogLoggingFunction, (gpointer)this); + } + if ( !handlerGdkmm ) + { + handlerGdkmm = g_log_set_handler("gdkmm", flags, + dialogLoggingFunction, (gpointer)this); + } + if ( !handlerGtkmm ) + { + handlerGtkmm = g_log_set_handler("gtkmm", flags, + dialogLoggingFunction, (gpointer)this); + } + message("log capture started"); +} + +void DebugDialogImpl::releaseLogMessages() +{ + if ( handlerDefault ) + { + g_log_remove_handler(NULL, handlerDefault); + handlerDefault = 0; + } + if ( handlerGlibmm ) + { + g_log_remove_handler("glibmm", handlerGlibmm); + handlerGlibmm = 0; + } + if ( handlerAtkmm ) + { + g_log_remove_handler("atkmm", handlerAtkmm); + handlerAtkmm = 0; + } + if ( handlerPangomm ) + { + g_log_remove_handler("pangomm", handlerPangomm); + handlerPangomm = 0; + } + if ( handlerGdkmm ) + { + g_log_remove_handler("gdkmm", handlerGdkmm); + handlerGdkmm = 0; + } + if ( handlerGtkmm ) + { + g_log_remove_handler("gtkmm", handlerGtkmm); + handlerGtkmm = 0; + } + message("log capture discontinued"); +} + + + +} //namespace Dialogs +} //namespace UI +} //namespace Inkscape + +//######################################################################### +//## E N D O F F I L E +//######################################################################### + + + diff --git a/src/dialogs/debugdialog.h b/src/dialogs/debugdialog.h new file mode 100644 index 000000000..1a4a036fd --- /dev/null +++ b/src/dialogs/debugdialog.h @@ -0,0 +1,104 @@ +#ifndef __DEBUGDIALOG_H__ +#define __DEBUGDIALOG_H__ +/* + * A very simple dialog for displaying Inkscape messages. Messages + * sent to g_log(), g_warning(), g_message(), ets, are routed here, + * in order to avoid messing with the startup console. + * + * Authors: + * Bob Jamison + * Other dudes from The Inkscape Organization + * + * Copyright (C) 2004 The Inkscape Organization + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + + + +namespace Inkscape { +namespace UI { +namespace Dialogs { + + +/** + * A dialog that displays log messages + */ +class DebugDialog +{ + + public: + + + /** + * Constructor + */ + DebugDialog() {}; + + + /** + * Factory method + */ + static DebugDialog *create(); + + /** + * Destructor + */ + virtual ~DebugDialog() {}; + + + /** + * Show the dialog + */ + virtual void show() = 0; + + /** + * Do not show the dialog + */ + virtual void hide() = 0; + + /** + * Clear all information from the dialog + */ + virtual void clear() = 0; + + /** + * Display a message + */ + virtual void message(char const *msg) = 0; + + /** + * Redirect g_log() messages to this widget + */ + virtual void captureLogMessages() = 0; + + /** + * Return g_log() messages to normal handling + */ + virtual void releaseLogMessages() = 0; + + /** + * Get a shared singleton instance + */ + static DebugDialog *getInstance(); + + /** + * Show the instance above + */ + static void showInstance(); + + + + +}; + + +} //namespace Dialogs +} //namespace UI +} //namespace Inkscape + + + + +#endif /* __DEBUGDIALOG_H__ */ + diff --git a/src/dialogs/dialog-events.cpp b/src/dialogs/dialog-events.cpp new file mode 100644 index 000000000..4e6a93729 --- /dev/null +++ b/src/dialogs/dialog-events.cpp @@ -0,0 +1,247 @@ +#define __DIALOG_EVENTS_C__ + +/** + * \brief Event handler for dialog windows + * + * Authors: + * bulia byak + * + * Copyright (C) 2003 authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include "macros.h" +#include +#include "desktop.h" +#include "inkscape-private.h" +#include "prefs-utils.h" +#include "event-context.h" + +#include "dialog-events.h" + + + +/** +* \brief This function is called to zero the transientize semaphore by a +* timeout. +*/ +gboolean +sp_allow_again (gpointer *wd) +{ + ((win_data *) wd)->stop = 0; + return FALSE; // so that it is only called once +} + + + +/** + * \brief Remove focus from window to whoever it is transient for... + * + */ +void +sp_dialog_defocus (GtkWindow *win) +{ + GtkWindow *w; + //find out the document window we're transient for + w = gtk_window_get_transient_for ((GtkWindow *) win); + //switch to it + + if (w) { + gtk_window_present (w); + } +} + + + +/** + * \brief Callback to defocus a widget's parent dialog. + * + */ +void +sp_dialog_defocus_callback (GtkWindow *win, gpointer data) +{ + sp_dialog_defocus ((GtkWindow *) + gtk_widget_get_toplevel ((GtkWidget *) data)); +} + + + +void +sp_dialog_defocus_on_enter (GtkWidget *w) +{ + g_signal_connect ( G_OBJECT (w), "activate", + G_CALLBACK (sp_dialog_defocus_callback), w ); +} + + + +gboolean +sp_dialog_event_handler (GtkWindow *win, GdkEvent *event, gpointer data) +{ + +// if the focus is inside the Text and Font textview, do nothing + GObject *dlg = (GObject *) data; + if (g_object_get_data (dlg, "eatkeys")) { + return FALSE; + } + + gboolean ret = FALSE; + + switch (event->type) { + + case GDK_KEY_PRESS: + + switch (get_group0_keyval (&event->key)) { + case GDK_Escape: + sp_dialog_defocus (win); + ret = TRUE; + break; + case GDK_F4: + case GDK_w: + case GDK_W: + // close dialog + if (MOD__CTRL_ONLY) { + + /* this code sends a delete_event to the dialog, + * instead of just destroying it, so that the + * dialog can do some housekeeping, such as remember + * its position. + */ + GdkEventAny event; + GtkWidget *widget = (GtkWidget *) win; + event.type = GDK_DELETE; + event.window = widget->window; + event.send_event = TRUE; + g_object_ref (G_OBJECT (event.window)); + gtk_main_do_event ((GdkEvent*)&event); + g_object_unref (G_OBJECT (event.window)); + + ret = TRUE; + } + break; + default: // pass keypress to the canvas + break; + } + default: + ; + } + + return ret; + +} + + + +/** + * \brief Make the argument dialog transient to the currently active document + window. + */ +void +sp_transientize (GtkWidget *dialog) +{ + if (prefs_get_int_attribute ( "options.dialogsskiptaskbar", "value", 0)) { + gtk_window_set_skip_taskbar_hint (GTK_WINDOW (dialog), TRUE); + } + + gint transient_policy = prefs_get_int_attribute_limited ( "options.transientpolicy", "value", 1, 0, 2 ); + + if (transient_policy) { + + // if there's an active document window, attach dialog to it as a transient: + + if ( SP_ACTIVE_DESKTOP ) + { + SP_ACTIVE_DESKTOP->setWindowTransient (dialog, transient_policy); + } + } +} // end of sp_transientize() + +void on_transientize (SPDesktop *desktop, win_data *wd ) +{ + sp_transientize_callback (0, desktop, wd); +} + +void +sp_transientize_callback ( Inkscape::Application * /*inkscape*/, + SPDesktop *desktop, win_data *wd ) +{ + gint transient_policy = + prefs_get_int_attribute_limited ( "options.transientpolicy", "value", + 1, 0, 2); + + if (!transient_policy) + return; + + if (wd->stop) { + /* + * if retransientizing of this dialog is still forbidden after + * previous call warning turned off because it was confusingly fired + * when loading many files from command line + */ + // g_warning("Retranzientize aborted! You're switching windows too fast!"); + return; + } + + if (wd->win) + { + wd->stop = 1; // disallow other attempts to retranzientize this dialog + desktop->setWindowTransient (wd->win, transient_policy); + } + + // we're done, allow next retransientizing not sooner than after 6 msec + gtk_timeout_add (6, (GtkFunction) sp_allow_again, (gpointer) wd); +} + +void on_dialog_hide (GtkWidget *w) +{ + if (w) + gtk_widget_hide (w); +} + +void on_dialog_unhide (GtkWidget *w) +{ + if (w) + gtk_widget_show (w); +} + +gboolean +sp_dialog_hide (GtkObject *object, gpointer data) +{ + GtkWidget *dlg = (GtkWidget *) data; + + if (dlg) + gtk_widget_hide (dlg); + + return TRUE; +} + + + +gboolean +sp_dialog_unhide (GtkObject *object, gpointer data) +{ + GtkWidget *dlg = (GtkWidget *) data; + + if (dlg) + gtk_widget_show (dlg); + + return TRUE; +} + + +/* + 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:textwidth=99 : diff --git a/src/dialogs/dialog-events.h b/src/dialogs/dialog-events.h new file mode 100644 index 000000000..7cc64c6a2 --- /dev/null +++ b/src/dialogs/dialog-events.h @@ -0,0 +1,66 @@ +#ifndef __DIALOG_EVENTS_H__ +#define __DIALOG_EVENTS_H__ + +/** + * \brief Event handler for dialog windows + * + * Authors: + * bulia byak + * + * Copyright (C) 2003 authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include +#include +#include + +/* + * event callback can only accept one argument, but we need two, + * hence this struct. + * each dialog has a local static copy: + * win is the dialog window + * stop is the transientize semaphore: when 0, retransientizing this dialog + * is allowed + */ + +typedef struct { + GtkWidget *win; + guint stop; +} win_data; + + +gboolean sp_dialog_event_handler ( GtkWindow *win, + GdkEvent *event, + gpointer data ); + +void sp_dialog_defocus ( GtkWindow *win ); +void sp_dialog_defocus_callback ( GtkWindow *win, gpointer data ); +void sp_dialog_defocus_on_enter ( GtkWidget *w ); +void sp_transientize ( GtkWidget *win ); + +void on_transientize ( SPDesktop *desktop, + win_data *wd ); + +void sp_transientize_callback ( Inkscape::Application *inkscape, + SPDesktop *desktop, + win_data *wd ); + +void on_dialog_hide (GtkWidget *w); +void on_dialog_unhide (GtkWidget *w); +gboolean sp_dialog_hide (GtkObject *object, gpointer data); +gboolean sp_dialog_unhide (GtkObject *object, gpointer data); + +#endif + +/* + 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:textwidth=99 : diff --git a/src/dialogs/display-settings.cpp b/src/dialogs/display-settings.cpp new file mode 100644 index 000000000..f083cca06 --- /dev/null +++ b/src/dialogs/display-settings.cpp @@ -0,0 +1,1575 @@ +#define __SP_DISPLAY_SETTINGS_C__ + +/* +* Inkscape Preferences dialog +* +* Authors: +* Lauris Kaplinski +* bulia byak +* +* Copyright (C) 2001 Ximian, Inc. +* Copyright (C) 2001-2004 Authors +* +*/ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif +#include + +#include "helper/window.h" +#include "../inkscape.h" +#include "../prefs-utils.h" +#include "dialog-events.h" +#include "../macros.h" +#include "../prefs-utils.h" +#include "../verbs.h" +#include "../interface.h" +#include "../message-stack.h" +#include "../enums.h" +#include "../selcue.h" +#include "../selection.h" +#include "../selection-chemistry.h" +#include "../style.h" +#include "../desktop-handles.h" +#include "../unit-constants.h" +#include "xml/repr.h" +#include "ui/widget/style-swatch.h" + + + + +static GtkWidget *dlg = NULL; +static win_data wd; + +// impossible original values to make sure they are read from prefs +static gint x = -1000, y = -1000; +static gchar *prefs_path = "dialogs.preferences"; + +extern gint nr_arena_image_x_sample; +extern gint nr_arena_image_y_sample; + +#define SB_WIDTH 90 +#define SB_LONG_ADJUSTMENT 20 +#define SB_MARGIN 1 +#define SUFFIX_WIDTH 70 +#define HB_MARGIN 4 +#define VB_MARGIN 4 +#define VB_SKIP 1 + +static void +sp_display_dialog_destroy (GtkObject *object, gpointer data) +{ + + sp_signal_disconnect_by_data (INKSCAPE, dlg); + wd.win = dlg = NULL; + wd.stop = 0; + +} // edn of sp_display_dialog_destroy() + + + +static gboolean +sp_display_dialog_delete (GtkObject *object, GdkEvent *event, gpointer data) +{ + gtk_window_get_position ((GtkWindow *) dlg, &x, &y); + + prefs_set_int_attribute (prefs_path, "x", x); + prefs_set_int_attribute (prefs_path, "y", y); + + return FALSE; // which means, go ahead and destroy it + +} // end of sp_display_dialog_delete() + +static void +prefs_switch_page (GtkNotebook *notebook, + GtkNotebookPage *page, + guint page_num, + gchar *attr) +{ + prefs_set_int_attribute ("dialogs.preferences", attr, page_num); +} + +static gint +get_int_value_data(GtkToggleButton *button) +{ + return GPOINTER_TO_INT((gchar const*)gtk_object_get_data(GTK_OBJECT(button), "value")); +} + +static void +options_selector_show_toggled (GtkToggleButton *button) +{ + if (gtk_toggle_button_get_active (button)) { + gchar const *val = (gchar const*)gtk_object_get_data(GTK_OBJECT(button), "value"); + prefs_set_string_attribute ("tools.select", "show", val); + } +} + +static void +options_store_transform_toggled (GtkToggleButton *button) +{ + if (gtk_toggle_button_get_active (button)) { + guint const val = get_int_value_data(button); + prefs_set_int_attribute ("options.preservetransform", "value", val); + } +} + +static void +options_clone_compensation_toggled (GtkToggleButton *button) +{ + if (gtk_toggle_button_get_active (button)) { + guint const val = get_int_value_data(button); + prefs_set_int_attribute ("options.clonecompensation", "value", val); + } +} + +static void +options_clone_orphans_toggled (GtkToggleButton *button) +{ + if (gtk_toggle_button_get_active (button)) { + guint const val = get_int_value_data(button); + prefs_set_int_attribute ("options.cloneorphans", "value", val); + } +} + +static void +options_selcue_toggled (GtkToggleButton *button) +{ + if (gtk_toggle_button_get_active (button)) { + guint const val = get_int_value_data(button); + prefs_set_int_attribute ("options.selcue", "value", val); + } +} + +static void +options_scale_origin_toggled (GtkToggleButton *button) +{ + if (gtk_toggle_button_get_active (button)) { + gchar const *val = (gchar const *) gtk_object_get_data(GTK_OBJECT(button), "value"); + prefs_set_string_attribute ("tools.select", "scale_origin", val); + } +} + + +/** +* Small helper function to make options_selector a little less +* verbose. +* +* \param b Another radio button in the group, or NULL for the first. +* \param fb Box to add the button to. +* \param n Label for the button. +* \param tip Tooltip. +* \param v_string Key for the button's value, if it is a string. +* \param v_uint Key for the button's value, if it is a uint. +* \param isint Whether this is astring or uint. +* \param s Initial state of the button. +* \param h Toggled handler function. +*/ +static GtkWidget* sp_select_context_add_radio ( + GtkWidget *b, + GtkWidget *fb, + GtkTooltips *tt, + gchar const *n, + gchar const *tip, + char const *v_string, + guint v_uint, + bool isint, + gboolean s, + void (*h)(GtkToggleButton*) + ) +{ + GtkWidget* r = gtk_radio_button_new_with_label ( + b ? gtk_radio_button_group (GTK_RADIO_BUTTON (b)) : NULL, n + ); + gtk_tooltips_set_tip (GTK_TOOLTIPS (tt), r, tip, NULL); + gtk_widget_show (r); + + if (isint) + gtk_object_set_data (GTK_OBJECT (r), "value", GUINT_TO_POINTER (v_uint)); + else + gtk_object_set_data (GTK_OBJECT (r), "value", (void*) v_string); + + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (r), s); + gtk_box_pack_start (GTK_BOX (fb), r, FALSE, FALSE, 0); + gtk_signal_connect (GTK_OBJECT (r), "toggled", GTK_SIGNAL_FUNC (h), NULL); + + return r; +} + +static GtkWidget * +options_selector () +{ + GtkWidget *vb, *f, *fb, *b; + + GtkTooltips *tt = gtk_tooltips_new(); + + vb = gtk_vbox_new (FALSE, VB_MARGIN); + + f = gtk_frame_new (_("When transforming, show:")); + gtk_widget_show (f); + gtk_box_pack_start (GTK_BOX (vb), f, FALSE, FALSE, 0); + + fb = gtk_hbox_new (FALSE, 10); + gtk_widget_show (fb); + gtk_container_add (GTK_CONTAINER (f), fb); + + gchar const *show = prefs_get_string_attribute ("tools.select", "show"); + + b = sp_select_context_add_radio ( + NULL, fb, tt, _("Objects"), + _("Show the actual objects when moving or transforming"), + "content", 0, false, + (show == NULL) || !strcmp (show, "content"), + options_selector_show_toggled + ); + + sp_select_context_add_radio( + b, fb, tt, _("Box outline"), + _("Show only a box outline of the objects when moving or transforming"), + "outline", 0, false, + show && !strcmp (show, "outline"), + options_selector_show_toggled + ); + + f = gtk_frame_new (_("Per-object selection cue:")); + gtk_widget_show (f); + gtk_box_pack_start (GTK_BOX (vb), f, FALSE, FALSE, 0); + + fb = gtk_hbox_new (FALSE, 10); + gtk_widget_show (fb); + gtk_container_add (GTK_CONTAINER (f), fb); + + gint cue = prefs_get_int_attribute ("options.selcue", "value", Inkscape::SelCue::MARK); + + b = sp_select_context_add_radio ( + NULL, fb, tt, _("None"), + _("No per-object selection indication"), NULL, Inkscape::SelCue::NONE, true, + cue == Inkscape::SelCue::NONE, + options_selcue_toggled + ); + + b = sp_select_context_add_radio ( + b, fb, tt, _("Mark"), + _("Each selected object has a diamond mark in the top left corner"), + NULL, Inkscape::SelCue::MARK, true, + cue == Inkscape::SelCue::MARK, + options_selcue_toggled + ); + + sp_select_context_add_radio ( + b, fb, tt, _("Box"), + _("Each selected object displays its bounding box"), NULL, Inkscape::SelCue::BBOX, true, + cue == Inkscape::SelCue::BBOX, + options_selcue_toggled + ); + + f = gtk_frame_new (_("Default scale origin:")); + gtk_widget_show (f); + gtk_box_pack_start (GTK_BOX (vb), f, FALSE, FALSE, 0); + + fb = gtk_hbox_new (FALSE, 10); + gtk_widget_show (fb); + gtk_container_add (GTK_CONTAINER (f), fb); + + gchar const *scale_orig = prefs_get_string_attribute ("tools.select", "scale_origin"); + + b = sp_select_context_add_radio ( + NULL, fb, tt, _("Opposite bounding box edge"), + _("Default scale origin will be on the bounding box of the item"), "bbox", 0, false, + (scale_orig == NULL) || !strcmp (scale_orig, "bbox"), + options_scale_origin_toggled + ); + + sp_select_context_add_radio ( + b, fb, tt, _("Farthest opposite node"), + _("Default scale origin will be on the bounding box of the item's points"), + "points", 0, false, + scale_orig && !strcmp (scale_orig, "points"), + options_scale_origin_toggled + ); + + return vb; +} + + +static void +sp_display_dialog_set_oversample (GtkMenuItem *item, gpointer data) +{ + gint os; + + os = GPOINTER_TO_INT (data); + + g_return_if_fail (os >= 0); + g_return_if_fail (os <= 4); + + nr_arena_image_x_sample = os; + nr_arena_image_y_sample = os; + + inkscape_refresh_display (INKSCAPE); + + prefs_set_int_attribute ( "options.bitmapoversample", "value", os ); + +} + + +static void +options_rotation_steps_changed (GtkMenuItem *item, gpointer data) +{ + gint snaps_new = GPOINTER_TO_INT (data); + prefs_set_int_attribute ( "options.rotationsnapsperpi", "value", snaps_new ); +} + +static void +options_dialogs_ontop_changed (GtkMenuItem *item, gpointer data) +{ + gint policy_new = GPOINTER_TO_INT (data); + prefs_set_int_attribute ( "options.transientpolicy", "value", policy_new ); +} + +void +options_rotation_steps (GtkWidget *vb, GtkTooltips *tt) +{ + GtkWidget *hb = gtk_hbox_new (FALSE, HB_MARGIN); + gtk_widget_show (hb); + gtk_box_pack_start (GTK_BOX (vb), hb, FALSE, FALSE, 0); + + { + GtkWidget *l = gtk_label_new (_("degrees")); + gtk_misc_set_alignment (GTK_MISC (l), 0.0, 0.5); + gtk_widget_set_size_request (l, SUFFIX_WIDTH, -1); + gtk_widget_show (l); + gtk_box_pack_end (GTK_BOX (hb), l, FALSE, FALSE, 0); + } + + { + GtkWidget *om = gtk_option_menu_new (); + gtk_tooltips_set_tip (GTK_TOOLTIPS (tt), om, _("Rotating with Ctrl pressed snaps every that much degrees; also, pressing [ or ] rotates by this amount"), NULL); + gtk_widget_set_size_request (om, SB_WIDTH, -1); + gtk_widget_show (om); + gtk_box_pack_end (GTK_BOX (hb), om, FALSE, FALSE, SB_MARGIN); + + GtkWidget *m = gtk_menu_new (); + gtk_widget_show (m); + + int snaps_current = prefs_get_int_attribute ("options.rotationsnapsperpi", "value", 12); + int position_current = 0; + + struct RotSteps { + double degrees; + int snaps; + } const rot_snaps[] = { + {90, 2}, + {60, 3}, + {45, 4}, + {30, 6}, + {15, 12}, + {10, 18}, + {7.5, 24}, + {6, 30}, + {5, 36}, + {3, 60}, + {2, 90}, + {1, 180}, + {1, 0}, + }; + + for (unsigned j = 0; j < G_N_ELEMENTS(rot_snaps); ++j) { + RotSteps const &rs = rot_snaps[j]; + + gchar const *label = NULL; + if (rs.snaps == 0) { + // sorationsnapsperpi == 0 means no snapping + label = _("None"); + } else { + label = g_strdup_printf ("%.2g", rs.degrees); + } + + if (rs.snaps == snaps_current) + position_current = j; + + GtkWidget *item = gtk_menu_item_new_with_label (label); + gtk_signal_connect ( GTK_OBJECT (item), "activate", + GTK_SIGNAL_FUNC (options_rotation_steps_changed), + GINT_TO_POINTER (rs.snaps) ); + gtk_widget_show (item); + gtk_menu_append (GTK_MENU (m), item); + } + + gtk_option_menu_set_menu (GTK_OPTION_MENU (om), m); + gtk_option_menu_set_history ( GTK_OPTION_MENU (om), position_current); + } + + { + GtkWidget *l = gtk_label_new (_("Rotation snaps every:")); + gtk_misc_set_alignment (GTK_MISC (l), 1.0, 0.5); + gtk_widget_show (l); + gtk_box_pack_start (GTK_BOX (hb), l, TRUE, TRUE, 0); + } +} + +void +options_dialogs_ontop (GtkWidget *vb, GtkTooltips *tt) +{ + GtkWidget *hb = gtk_hbox_new (FALSE, HB_MARGIN); + gtk_widget_show (hb); + gtk_box_pack_start (GTK_BOX (vb), hb, FALSE, FALSE, 0); + + { // empty label for alignment + GtkWidget *l = gtk_label_new (""); + gtk_widget_set_size_request (l, SUFFIX_WIDTH - SB_LONG_ADJUSTMENT, -1); + gtk_widget_show (l); + gtk_box_pack_end (GTK_BOX (hb), l, FALSE, FALSE, 0); + } + + { + GtkWidget *om = gtk_option_menu_new (); + gtk_tooltips_set_tip (GTK_TOOLTIPS (tt), om, _("None: dialogs are treated as regular windows; Normal: dialogs stay on top of document windows; Aggressive: same as Normal but may work better with some window managers."), NULL); + gtk_widget_set_size_request (om, SB_WIDTH + SB_LONG_ADJUSTMENT, -1); + gtk_widget_show (om); + gtk_box_pack_end (GTK_BOX (hb), om, FALSE, FALSE, SB_MARGIN); + + GtkWidget *m = gtk_menu_new (); + gtk_widget_show (m); + + int current = prefs_get_int_attribute ("options.transientpolicy", "value", 1); + + { + const gchar *label = _("None"); + GtkWidget *item = gtk_menu_item_new_with_label (label); + gtk_signal_connect ( GTK_OBJECT (item), "activate", + GTK_SIGNAL_FUNC (options_dialogs_ontop_changed), + GINT_TO_POINTER (0) ); + gtk_widget_show (item); + gtk_menu_append (GTK_MENU (m), item); + } + + { + const gchar *label = _("Normal"); + GtkWidget *item = gtk_menu_item_new_with_label (label); + gtk_signal_connect ( GTK_OBJECT (item), "activate", + GTK_SIGNAL_FUNC (options_dialogs_ontop_changed), + GINT_TO_POINTER (1) ); + gtk_widget_show (item); + gtk_menu_append (GTK_MENU (m), item); + } + + { + const gchar *label = _("Aggressive"); + GtkWidget *item = gtk_menu_item_new_with_label (label); + gtk_signal_connect ( GTK_OBJECT (item), "activate", + GTK_SIGNAL_FUNC (options_dialogs_ontop_changed), + GINT_TO_POINTER (2) ); + gtk_widget_show (item); + gtk_menu_append (GTK_MENU (m), item); + } + + gtk_option_menu_set_menu (GTK_OPTION_MENU (om), m); + gtk_option_menu_set_history ( GTK_OPTION_MENU (om), current); + } + + { + GtkWidget *l = gtk_label_new (_("Dialogs on top:")); + gtk_misc_set_alignment (GTK_MISC (l), 1.0, 0.5); + gtk_widget_show (l); + gtk_box_pack_start (GTK_BOX (hb), l, TRUE, TRUE, 0); + } +} + + +static void +sp_display_dialog_cursor_tolerance_changed (GtkAdjustment *adj, gpointer data) +{ + prefs_set_double_attribute ( "options.cursortolerance", "value", + adj->value ); +} + +static void +options_freehand_tolerance_changed (GtkAdjustment *adj, gpointer data) +{ + prefs_set_double_attribute ("tools.freehand.pencil", "tolerance", adj->value); +} + +static void +options_changed_double (GtkAdjustment *adj, gpointer data) +{ + const gchar *prefs_path = (const gchar *) data; + prefs_set_double_attribute (prefs_path, "value", adj->value); +} + +static void +options_changed_int (GtkAdjustment *adj, gpointer data) +{ + const gchar *prefs_path = (const gchar *) data; + prefs_set_int_attribute (prefs_path, "value", (int) adj->value); +} + +static void +options_changed_percent (GtkAdjustment *adj, gpointer data) +{ + const gchar *prefs_path = (const gchar *) data; + prefs_set_double_attribute (prefs_path, "value", (adj->value)/100.0); +} + +static void +options_changed_boolean (GtkToggleButton *tb, gpointer data) +{ + const gchar *prefs_path = (const gchar *) data; + const gchar *prefs_attr = (const gchar *) g_object_get_data (G_OBJECT(tb), "attr"); + prefs_set_int_attribute (prefs_path, prefs_attr, gtk_toggle_button_get_active (tb)); +} + +void +options_sb ( + gchar const *label, + gchar const *tooltip, GtkTooltips *tt, + gchar const *suffix, + GtkWidget *box, + gdouble lower, gdouble upper, gdouble step_increment, gdouble page_increment, gdouble page_size, + gchar const *prefs_path, gchar const *attr, gdouble def, + bool isint, bool ispercent, + void (*changed)(GtkAdjustment *, gpointer) +) +{ + GtkWidget *hb = gtk_hbox_new (FALSE, HB_MARGIN); + gtk_widget_show (hb); + gtk_box_pack_start (GTK_BOX (box), hb, FALSE, FALSE, VB_SKIP); + + { + GtkWidget *l = gtk_label_new (suffix); + gtk_misc_set_alignment (GTK_MISC (l), 0.0, 0.5); + gtk_widget_set_size_request (l, SUFFIX_WIDTH, -1); + gtk_widget_show (l); + gtk_box_pack_end (GTK_BOX (hb), l, FALSE, FALSE, 0); + } + + { + GtkObject *a = gtk_adjustment_new(0.0, lower, upper, step_increment, page_increment, page_size); + + gdouble value; + if (isint) + if (ispercent) + value = 100 * (gdouble) prefs_get_double_attribute_limited (prefs_path, attr, def, lower/100.0, upper/100.0); + else + value = (gdouble) prefs_get_int_attribute_limited (prefs_path, attr, (int) def, (int) lower, (int) upper); + else + value = prefs_get_double_attribute_limited (prefs_path, attr, def, lower, upper); + + gtk_adjustment_set_value (GTK_ADJUSTMENT (a), value); + + GtkWidget *sb; + if (isint) { + sb = gtk_spin_button_new (GTK_ADJUSTMENT (a), 1.0, 0); + } else { + if (step_increment < 0.1) + sb = gtk_spin_button_new (GTK_ADJUSTMENT (a), 0.01, 3); + else + sb = gtk_spin_button_new (GTK_ADJUSTMENT (a), 0.01, 2); + } + + gtk_tooltips_set_tip (GTK_TOOLTIPS (tt), sb, tooltip, NULL); + gtk_entry_set_width_chars (GTK_ENTRY (sb), 6); + gtk_widget_set_size_request (sb, SB_WIDTH, -1); + gtk_widget_show (sb); + gtk_box_pack_end (GTK_BOX (hb), sb, FALSE, FALSE, SB_MARGIN); + + gtk_signal_connect(GTK_OBJECT(a), "value_changed", + GTK_SIGNAL_FUNC(changed), (gpointer) prefs_path); + } + + { + GtkWidget *l = gtk_label_new (label); + gtk_misc_set_alignment (GTK_MISC (l), 1.0, 0.5); + gtk_widget_show (l); + gtk_box_pack_start (GTK_BOX (hb), l, TRUE, TRUE, 0); + } + +} + + +void +options_checkbox ( + gchar const *label, + gchar const *tooltip, GtkTooltips *tt, + GtkWidget *box, + gchar const *prefs_path, gchar const *attr, gint def, + void (*changed)(GtkToggleButton *, gpointer) +) +{ + GtkWidget *hb = gtk_hbox_new (FALSE, HB_MARGIN); + gtk_widget_show (hb); + gtk_box_pack_start (GTK_BOX (box), hb, FALSE, FALSE, VB_SKIP); + + { // empty label for alignment + GtkWidget *l = gtk_label_new (""); + gtk_widget_set_size_request (l, SUFFIX_WIDTH, -1); + gtk_widget_show (l); + gtk_box_pack_end (GTK_BOX (hb), l, FALSE, FALSE, 0); + } + + { + + GtkWidget *b = gtk_check_button_new (); + + gint value = prefs_get_int_attribute (prefs_path, attr, def); + + gtk_toggle_button_set_active ((GtkToggleButton *) b, value != 0); + + gtk_tooltips_set_tip (GTK_TOOLTIPS (tt), b, tooltip, NULL); + + gtk_widget_set_size_request (b, SB_WIDTH, -1); + gtk_widget_show (b); + gtk_box_pack_end (GTK_BOX (hb), b, FALSE, FALSE, SB_MARGIN); + + g_object_set_data (G_OBJECT(b), "attr", (void *) attr); + + gtk_signal_connect(GTK_OBJECT(b), "toggled", + GTK_SIGNAL_FUNC(changed), (gpointer) prefs_path); + } + + { + GtkWidget *l = gtk_label_new (label); + gtk_misc_set_alignment (GTK_MISC (l), 1.0, 0.5); + gtk_widget_show (l); + gtk_box_pack_start (GTK_BOX (hb), l, TRUE, TRUE, 0); + } +} + +void +selcue_checkbox (GtkWidget *vb, GtkTooltips *tt, const gchar *path) +{ + options_checkbox ( + _("Show selection cue"), + _("Whether selected objects display a selection cue (the same as in selector)"), tt, + vb, + path, "selcue", 1, + options_changed_boolean + ); +} + +void +gradientdrag_checkbox (GtkWidget *vb, GtkTooltips *tt, const gchar *path) +{ + options_checkbox ( + _("Enable gradient editing"), + _("Whether selected objects display gradient editing controls"), tt, + vb, + path, "gradientdrag", 1, + options_changed_boolean + ); +} + + +/** +* Helper function for new_objects_style +* +* \param b Another radio button in the group, or NULL for the first. +* \param fb Box to add the button to. +* \param n Label for the button. +* \param tip Tooltip. +* \param v_uint Key for the button's value +* \param s Initial state of the button. +* \param h Toggled handler function. +*/ +static GtkWidget* new_objects_style_add_radio ( + GtkWidget* b, + GtkWidget* fb, + GtkTooltips* tt, + const gchar* n, + const gchar* tip, + guint v_uint, + gboolean s, + void (*h)(GtkToggleButton*, gpointer), + gchar const *prefs_path, + gchar const *attr, + GtkWidget *button + ) +{ + GtkWidget* r = gtk_radio_button_new_with_label ( + b ? gtk_radio_button_group (GTK_RADIO_BUTTON (b)) : NULL, n + ); + gtk_tooltips_set_tip (GTK_TOOLTIPS (tt), r, tip, NULL); + gtk_widget_show (r); + + gtk_object_set_data (GTK_OBJECT (r), "value", GUINT_TO_POINTER (v_uint)); + gtk_object_set_data (GTK_OBJECT (r), "attr", (gpointer) attr); + gtk_object_set_data (GTK_OBJECT (r), "button_to_activate", (gpointer) button); + + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (r), s); + gtk_signal_connect (GTK_OBJECT (r), "toggled", GTK_SIGNAL_FUNC (h), (gpointer) prefs_path); + + return r; +} + +static void +style_from_selection_to_tool(GtkWidget *widget, gchar const *prefs_path) +{ + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + if (desktop == NULL) + return; + + Inkscape::Selection *selection = SP_DT_SELECTION(desktop); + + if (selection->isEmpty()) { + SP_DT_MSGSTACK(desktop)->flash(Inkscape::ERROR_MESSAGE, + _("No objects selected to take the style from.")); + return; + } + SPItem *item = selection->singleItem(); + if (!item) { + /* TODO: If each item in the selection has the same style then don't consider it an error. + * Maybe we should try to handle multiple selections anyway, e.g. the intersection of the + * style attributes for the selected items. */ + SP_DT_MSGSTACK(desktop)->flash(Inkscape::ERROR_MESSAGE, + _("More than one object selected. Cannot take style from multiple objects.")); + return; + } + + SPCSSAttr *css = take_style_from_item (item); + + if (!css) return; + + // only store text style for the text tool + if (!g_strrstr ((const gchar *) prefs_path, "text")) { + css = sp_css_attr_unset_text (css); + } + + // we cannot store properties with uris - they will be invalid in other documents + css = sp_css_attr_unset_uris (css); + + sp_repr_css_change (inkscape_get_repr (INKSCAPE, prefs_path), css, "style"); + sp_repr_css_attr_unref (css); + + // update the swatch + Inkscape::UI::Widget::StyleSwatch *swatch = + (Inkscape::UI::Widget::StyleSwatch *) gtk_object_get_data (GTK_OBJECT (widget), "swatch"); + if (swatch) { + Inkscape::XML::Node *tool_repr = inkscape_get_repr(INKSCAPE, prefs_path); + if (tool_repr) { + SPCSSAttr *css = sp_repr_css_attr_inherited(tool_repr, "style"); + + swatch->setStyle (css); + + sp_repr_css_attr_unref(css); + } + } +} + +static void +options_changed_radio (GtkToggleButton *tb, gpointer data) +{ + const gchar *prefs_path = (const gchar *) data; + const gchar *prefs_attr = (const gchar *) g_object_get_data (G_OBJECT(tb), "attr"); + const guint val = GPOINTER_TO_INT((const gchar*)gtk_object_get_data(GTK_OBJECT(tb), "value")); + + if (prefs_path && prefs_attr && gtk_toggle_button_get_active (tb)) { + prefs_set_int_attribute (prefs_path, prefs_attr, val); + } + + GtkWidget *button = (GtkWidget *) g_object_get_data (G_OBJECT(tb), "button_to_activate"); + if (button) + gtk_widget_set_sensitive (button, !val); +} + +void +new_objects_style (GtkWidget *vb, GtkTooltips *tt, const gchar *path) +{ + GtkWidget *f = gtk_frame_new (_("Create new objects with:")); + gtk_widget_show (f); + gtk_box_pack_start (GTK_BOX (vb), f, FALSE, FALSE, 0); + + GtkWidget *fb = gtk_vbox_new (FALSE, 0); + gtk_widget_show (fb); + gtk_container_add (GTK_CONTAINER (f), fb); + + guint usecurrent = prefs_get_int_attribute (path, "usecurrent", 0); + + GtkWidget *take = gtk_button_new_with_label (_("Take from selection")); + gtk_tooltips_set_tip (tt, take, _("Remember the style of the (first) selected object as this tool's style"), NULL); + gtk_widget_show (take); + + GtkWidget *b; + { + b = new_objects_style_add_radio ( + NULL, fb, tt, _("Last used style"), _("Apply the style you last set on an object"), + 1, + usecurrent != 0, + options_changed_radio, + path, "usecurrent", take + ); + + GtkWidget *hb = gtk_hbox_new(FALSE, HB_MARGIN); + gtk_box_pack_start (GTK_BOX (hb), b, FALSE, FALSE, 0); + gtk_widget_show_all(hb); + + gtk_box_pack_start (GTK_BOX (fb), hb, FALSE, FALSE, 0); + } + + { + b = new_objects_style_add_radio ( + b, fb, tt, _("This tool's own style:"), _("Each tool may store its own style to apply to the newly created objects. Use the button below to set it."), + 0, + usecurrent == 0, + options_changed_radio, + path, "usecurrent", take + ); + + GtkWidget *hb = gtk_hbox_new(FALSE, HB_MARGIN); + gtk_box_pack_start (GTK_BOX (hb), b, FALSE, FALSE, 0); + + // style swatch + Inkscape::XML::Node *tool_repr = inkscape_get_repr(INKSCAPE, path); + if (tool_repr) { + SPCSSAttr *css = sp_repr_css_attr_inherited(tool_repr, "style"); + Inkscape::UI::Widget::StyleSwatch *swatch = new Inkscape::UI::Widget::StyleSwatch(css); + gtk_box_pack_start (GTK_BOX (hb), (GtkWidget *) swatch->gobj(), FALSE, FALSE, 0); + sp_repr_css_attr_unref(css); + gtk_object_set_data (GTK_OBJECT (take), "swatch", (gpointer) swatch); + } + + // add "take from selection" button + gtk_widget_set_sensitive (take, (usecurrent == 0)); + gtk_box_pack_start (GTK_BOX (hb), take, FALSE, FALSE, 0); + gtk_signal_connect (GTK_OBJECT (take), "clicked", GTK_SIGNAL_FUNC (style_from_selection_to_tool), (void *) path); + + gtk_widget_show_all(hb); + + gtk_box_pack_start (GTK_BOX (fb), hb, FALSE, FALSE, 0); + } +} + + +static GtkWidget * +options_dropper () +{ + GtkTooltips *tt = gtk_tooltips_new(); + + GtkWidget *vb = gtk_vbox_new (FALSE, VB_MARGIN); + + selcue_checkbox (vb, tt, "tools.dropper"); + gradientdrag_checkbox (vb, tt, "tools.dropper"); + + return vb; +} + +GtkWidget * +new_tab (GtkWidget *nb, const gchar *label) +{ + GtkWidget *l = gtk_label_new (label); + gtk_widget_show (l); + GtkWidget *vb = gtk_vbox_new (FALSE, VB_MARGIN); + gtk_widget_show (vb); + gtk_container_set_border_width (GTK_CONTAINER (vb), VB_MARGIN); + gtk_notebook_append_page (GTK_NOTEBOOK (nb), vb, l); + return vb; +} + +void +sp_display_dialog (void) +{ + + GtkWidget *nb, *l, *vb, *vbvb, *hb, *om, *m, *i, *frame; + + if (!dlg) + { + + gchar title[500]; + sp_ui_dialog_title_string (Inkscape::Verb::get(SP_VERB_DIALOG_DISPLAY), title); + + dlg = sp_window_new (title, TRUE); + gtk_window_set_resizable ((GtkWindow *) dlg, FALSE); + if (x == -1000 || y == -1000) { + x = prefs_get_int_attribute (prefs_path, "x", 0); + y = prefs_get_int_attribute (prefs_path, "y", 0); + } + + if (x != 0 || y != 0) { + gtk_window_move ((GtkWindow *) dlg, x, y); + } else { + gtk_window_set_position(GTK_WINDOW(dlg), GTK_WIN_POS_CENTER); + } + + + sp_transientize (dlg); + wd.win = dlg; + wd.stop = 0; + + g_signal_connect ( G_OBJECT (INKSCAPE), "activate_desktop", + G_CALLBACK (sp_transientize_callback), &wd); + + gtk_signal_connect ( GTK_OBJECT (dlg), "event", GTK_SIGNAL_FUNC (sp_dialog_event_handler), dlg); + + gtk_signal_connect ( GTK_OBJECT (dlg), "destroy", G_CALLBACK (sp_display_dialog_destroy), dlg); + gtk_signal_connect ( GTK_OBJECT (dlg), "delete_event", G_CALLBACK (sp_display_dialog_delete), dlg); + g_signal_connect ( G_OBJECT (INKSCAPE), "shut_down", G_CALLBACK (sp_display_dialog_delete), dlg); + + g_signal_connect ( G_OBJECT (INKSCAPE), "dialogs_hide", G_CALLBACK (sp_dialog_hide), dlg); + g_signal_connect ( G_OBJECT (INKSCAPE), "dialogs_unhide", G_CALLBACK (sp_dialog_unhide), dlg); + + GtkTooltips *tt = gtk_tooltips_new(); + + nb = gtk_notebook_new (); + gtk_widget_show (nb); + gtk_container_add (GTK_CONTAINER (dlg), nb); + +// Mouse + vb = new_tab (nb, _("Mouse")); + + options_sb ( + /* TRANSLATORS: "Grab" is a noun here. "Grab sensitivity" is intended to mean how + * close on the screen you need to be to an object to be able to grab it with mouse (in + * pixels). */ + _("Grab sensitivity:"), + _("How close on the screen you need to be to an object to be able to grab it with mouse (in screen pixels)"), tt, + _("pixels"), + /* todo: allow real-world units. */ + vb, + 0.0, 30.0, 1.0, 1.0, 1.0, + "options.cursortolerance", "value", 8.0, + true, false, + sp_display_dialog_cursor_tolerance_changed + ); + + options_sb ( + _("Click/drag threshold:"), + _("Maximum mouse drag (in screen pixels) which is considered a click, not a drag"), tt, + _("pixels"), + vb, + 0.0, 20.0, 1.0, 1.0, 1.0, + "options.dragtolerance", "value", 4.0, + true, false, + options_changed_int + ); + + +// Scrolling + vb = new_tab (nb, _("Scrolling")); + + options_sb ( + _("Mouse wheel scrolls by:"), + _("One mouse wheel notch scrolls by this distance in screen pixels (horizontally with Shift)"), tt, + _("pixels"), + vb, + 0.0, 1000.0, 1.0, 1.0, 1.0, + "options.wheelscroll", "value", 40.0, + true, false, + options_changed_int + ); + + frame = gtk_frame_new (_("Ctrl+arrows")); + gtk_widget_show (frame); + gtk_box_pack_start (GTK_BOX (vb), frame, FALSE, FALSE, 0); + vbvb = gtk_vbox_new (FALSE, VB_MARGIN); + gtk_widget_show (vbvb); + gtk_container_add (GTK_CONTAINER (frame), vbvb); + + options_sb ( + _("Scroll by:"), + _("Pressing Ctrl+arrow key scrolls by this distance (in screen pixels)"), tt, + _("pixels"), + vbvb, + 0.0, 1000.0, 1.0, 1.0, 1.0, + "options.keyscroll", "value", 10.0, + true, false, + options_changed_int + ); + + options_sb ( + _("Acceleration:"), + _("Pressing and holding Ctrl+arrow will gradually speed up scrolling (0 for no acceleration)"), tt, + "", + vbvb, + 0.0, 5.0, 0.01, 1.0, 1.0, + "options.scrollingacceleration", "value", 0.35, + false, false, + options_changed_double + ); + + frame = gtk_frame_new (_("Autoscrolling")); + gtk_widget_show (frame); + gtk_box_pack_start (GTK_BOX (vb), frame, FALSE, FALSE, 0); + vbvb = gtk_vbox_new (FALSE, VB_MARGIN); + gtk_widget_show (vbvb); + gtk_container_add (GTK_CONTAINER (frame), vbvb); + + options_sb ( + _("Speed:"), + _("How fast the canvas autoscrolls when you drag beyond canvas edge (0 to turn autoscroll off)"), tt, + "", + vbvb, + 0.0, 5.0, 0.01, 1.0, 1.0, + "options.autoscrollspeed", "value", 0.7, + false, false, + options_changed_double + ); + + options_sb ( + _("Threshold:"), + _("How far (in screen pixels) you need to be from the canvas edge to trigger autoscroll; positive is outside the canvas, negative is within the canvas"), tt, + _("pixels"), + vbvb, + -600.0, 600.0, 1.0, 1.0, 1.0, + "options.autoscrolldistance", "value", -10.0, + true, false, + options_changed_int + ); + +// Steps + vb = new_tab (nb, _("Steps")); + + options_sb ( + _("Arrow keys move by:"), + _("Pressing an arrow key moves selected object(s) or node(s) by this distance (in px units)"), tt, + _("px"), + vb, + 0.0, 3000.0, 0.01, 1.0, 1.0, + "options.nudgedistance", "value", 2.0, + false, false, + options_changed_double + ); + + options_sb ( + _("> and < scale by:"), + _("Pressing > or < scales selection up or down by this increment (in px units)"), tt, + _("px"), + vb, + 0.0, 3000.0, 0.01, 1.0, 1.0, + "options.defaultscale", "value", 2.0, + false, false, + options_changed_double + ); + + options_sb ( + _("Inset/Outset by:"), + _("Inset and Outset commands displace the path by this distance (in px units)"), tt, + _("px"), + vb, + 0.0, 3000.0, 0.01, 1.0, 1.0, + "options.defaultoffsetwidth", "value", 2.0, + false, false, + options_changed_double + ); + + options_rotation_steps (vb, tt); + +options_checkbox ( + _("Compass-like display of angles"), + // TRANSLATORS: "positive clockwise" means "increasing in clockwise direction" + _("When on, angles are displayed with 0 at north, 0 to 360 range, positive clockwise; otherwise with 0 at east, -180 to 180 range, positive counterclockwise"), tt, + vb, + "options.compassangledisplay", "value", 1, + options_changed_boolean + ); + + options_sb ( + _("Zoom in/out by:"), + _("Zoom tool click, +/- keys, and middle click zoom in and out by this multiplier"), tt, + _("%"), + vb, + 101.0, 500.0, 1.0, 1.0, 1.0, + "options.zoomincrement", "value", 1.414213562, + true, true, + options_changed_percent + ); + +// Tools + vb = new_tab (nb, _("Tools")); + + GtkWidget *nb_tools = gtk_notebook_new (); + gtk_widget_show (nb_tools); + gtk_container_add (GTK_CONTAINER (vb), nb_tools); + + // Selector + { + GtkWidget *vb_tool = new_tab (nb_tools, _("Selector")); + + GtkWidget *selector_page = options_selector (); + gtk_widget_show (selector_page); + gtk_container_add (GTK_CONTAINER (vb_tool), selector_page); + + gradientdrag_checkbox (vb_tool, tt, "tools.select"); + } + + // Node + { + GtkWidget *vb_tool = new_tab (nb_tools, _("Node")); + + selcue_checkbox (vb_tool, tt, "tools.nodes"); + gradientdrag_checkbox (vb_tool, tt, "tools.nodes"); + } + + // Zoom + { + GtkWidget *vb_tool = new_tab (nb_tools, _("Zoom")); + + selcue_checkbox (vb_tool, tt, "tools.zoom"); + gradientdrag_checkbox (vb_tool, tt, "tools.zoom"); + } + + { // The 4 shape tools + GtkWidget *vb_shapes = new_tab (nb_tools, _("Shapes")); + + GtkWidget *nb_shapes = gtk_notebook_new (); + gtk_widget_show (nb_shapes); + gtk_container_add (GTK_CONTAINER (vb_shapes), nb_shapes); + + // Rect + { + GtkWidget *vb_tool = new_tab(nb_shapes, _("Rectangle")); + new_objects_style (vb_tool, tt, "tools.shapes.rect"); + } + + // Ellipse + { + GtkWidget *vb_tool = new_tab(nb_shapes, _("Ellipse")); + new_objects_style (vb_tool, tt, "tools.shapes.arc"); + } + + // Star + { + GtkWidget *vb_tool = new_tab(nb_shapes, _("Star")); + new_objects_style (vb_tool, tt, "tools.shapes.star"); + } + + // Spiral + { + GtkWidget *vb_tool = new_tab(nb_shapes, _("Spiral")); + new_objects_style (vb_tool, tt, "tools.shapes.spiral"); + } + + // common for all shapes + selcue_checkbox (vb_shapes, tt, "tools.shapes"); + gradientdrag_checkbox (vb_shapes, tt, "tools.shapes"); + + g_signal_connect(GTK_OBJECT (nb_shapes), "switch-page", GTK_SIGNAL_FUNC (prefs_switch_page), (void *) "page_shapes"); + gtk_notebook_set_current_page (GTK_NOTEBOOK (nb_shapes), prefs_get_int_attribute ("dialogs.preferences", "page_shapes", 0)); + } + + // Pencil + { + GtkWidget *vb_tool = new_tab (nb_tools, _("Pencil")); + + options_sb ( + _("Tolerance:"), + _("This value affects the amount of smoothing applied to freehand lines; lower values produce more uneven paths with more nodes"), tt, + "", + vb_tool, + 0.0, 100.0, 0.5, 1.0, 1.0, + "tools.freehand.pencil", "tolerance", 10.0, + false, false, + options_freehand_tolerance_changed + ); + + new_objects_style (vb_tool, tt, "tools.freehand.pencil"); + + selcue_checkbox (vb_tool, tt, "tools.freehand.pencil"); + } + + // Pen + { + GtkWidget *vb_tool = new_tab (nb_tools, _("Pen")); + + new_objects_style (vb_tool, tt, "tools.freehand.pen"); + + selcue_checkbox (vb_tool, tt, "tools.freehand.pen"); + } + + // Calligraphy + { + GtkWidget *vb_tool = new_tab (nb_tools, _("Calligraphy")); + + new_objects_style (vb_tool, tt, "tools.calligraphic"); + } + + // Text + { + GtkWidget *vb_tool = new_tab (nb_tools, _("Text")); + + new_objects_style (vb_tool, tt, "tools.text"); + + selcue_checkbox (vb_tool, tt, "tools.text"); + gradientdrag_checkbox (vb_tool, tt, "tools.text"); + } + + // Gradient + { + GtkWidget *vb_tool = new_tab (nb_tools, _("Gradient")); + + selcue_checkbox (vb_tool, tt, "tools.gradient"); + } + + // Connector + { + GtkWidget *vb_tool = new_tab (nb_tools, _("Connector")); + + selcue_checkbox (vb_tool, tt, "tools.connector"); + } + + // Dropper + { + GtkWidget *vb_tool = new_tab (nb_tools, _("Dropper")); + + GtkWidget *dropper_page = options_dropper (); + gtk_widget_show (dropper_page); + gtk_container_add (GTK_CONTAINER (vb_tool), dropper_page); + } + + g_signal_connect(GTK_OBJECT (nb_tools), "switch-page", GTK_SIGNAL_FUNC (prefs_switch_page), (void *) "page_tools"); + gtk_notebook_set_current_page (GTK_NOTEBOOK (nb_tools), prefs_get_int_attribute ("dialogs.preferences", "page_tools", 0)); + + +// Windows + vb = new_tab (nb, _("Windows")); + + options_dialogs_ontop (vb, tt); + +options_checkbox ( + _("Save window geometry"), + _("Save the window size and position with each document (only for Inkscape SVG format)"), tt, + vb, + "options.savewindowgeometry", "value", 1, + options_changed_boolean + ); + +options_checkbox ( + _("Dialogs are hidden in taskbar"), + _("Whether dialog windows are to be hidden in the window manager taskbar"), tt, + vb, + "options.dialogsskiptaskbar", "value", 1, + options_changed_boolean + ); + +options_checkbox ( + _("Zoom when window is resized"), + _("Zoom drawing when document window is resized, to keep the same area visible (this is the default which can be changed in any window using the button above the right scrollbar)"), tt, + vb, + "options.stickyzoom", "value", 0, + options_changed_boolean + ); + + +// Clones + vb = new_tab (nb, _("Clones")); + + // Clone compensation + { + GtkWidget *f = gtk_frame_new (_("When the original moves, its clones and linked offsets:")); + gtk_widget_show (f); + gtk_box_pack_start (GTK_BOX (vb), f, FALSE, FALSE, 0); + + GtkWidget *fb = gtk_vbox_new (FALSE, 0); + gtk_widget_show (fb); + gtk_container_add (GTK_CONTAINER (f), fb); + + gint compense = prefs_get_int_attribute ("options.clonecompensation", "value", SP_CLONE_COMPENSATION_PARALLEL); + + GtkWidget *b = + sp_select_context_add_radio ( + NULL, fb, tt, _("Move in parallel"), + _("Clones are translated by the same vector as their original."), + NULL, SP_CLONE_COMPENSATION_PARALLEL, true, + compense == SP_CLONE_COMPENSATION_PARALLEL, + options_clone_compensation_toggled + ); + + sp_select_context_add_radio ( + b, fb, tt, _("Stay unmoved"), + _("Clones preserve their positions when their original is moved."), + NULL, SP_CLONE_COMPENSATION_UNMOVED, true, + compense == SP_CLONE_COMPENSATION_UNMOVED, + options_clone_compensation_toggled + ); + + sp_select_context_add_radio ( + b, fb, tt, _("Move according to transform"), + _("Each clone moves according to the value of its transform= attribute. For example, a rotated clone will move in a different direction than its original."), + NULL, SP_CLONE_COMPENSATION_NONE, true, + compense == SP_CLONE_COMPENSATION_NONE, + options_clone_compensation_toggled + ); + } + + // Original deletion + { + GtkWidget *f = gtk_frame_new (_("When the original is deleted, its clones:")); + gtk_widget_show (f); + gtk_box_pack_start (GTK_BOX (vb), f, FALSE, FALSE, 0); + + GtkWidget *fb = gtk_vbox_new (FALSE, 0); + gtk_widget_show (fb); + gtk_container_add (GTK_CONTAINER (f), fb); + + gint orphans = prefs_get_int_attribute ("options.cloneorphans", "value", SP_CLONE_ORPHANS_UNLINK); + + GtkWidget *b = + sp_select_context_add_radio ( + NULL, fb, tt, _("Are unlinked"), _("Orphaned clones are converted to regular objects."), NULL, SP_CLONE_ORPHANS_UNLINK, true, + orphans == SP_CLONE_ORPHANS_UNLINK, + options_clone_orphans_toggled + ); + + sp_select_context_add_radio ( + b, fb, tt, _("Are deleted"), _("Orphaned clones are deleted along with their original."), NULL, SP_CLONE_ORPHANS_DELETE, true, + orphans == SP_CLONE_ORPHANS_DELETE, + options_clone_orphans_toggled + ); + +/* + sp_select_context_add_radio ( + b, fb, tt, _("Ask me"), _("Ask me what to do with the clones when their originals are deleted."), NULL, SP_CLONE_ORPHANS_ASKME, true, + orphans == SP_CLONE_ORPHANS_ASKME, + options_clone_orphans_toggled + ); +*/ + } + +// Transforms + /* TRANSLATORS: Noun, i.e. transformations. */ + vb = new_tab (nb, _("Transforms")); + +options_checkbox ( + _("Scale stroke width"), + _("When scaling objects, scale the stroke width by the same proportion"), tt, + vb, + "options.transform", "stroke", 1, + options_changed_boolean + ); + +options_checkbox ( + _("Scale rounded corners in rectangles"), + _("When scaling rectangles, scale the radii of rounded corners"), tt, + vb, + "options.transform", "rectcorners", 0, + options_changed_boolean + ); + +options_checkbox ( + _("Transform gradients"), + _("Transform gradients (in fill or stroke) along with the objects"), tt, + vb, + "options.transform", "gradient", 1, + options_changed_boolean + ); + +options_checkbox ( + _("Transform patterns"), + _("Transform patterns (in fill or stroke) along with the objects"), tt, + vb, + "options.transform", "pattern", 1, + options_changed_boolean + ); + + + // Store transformation (global) + { + /* TRANSLATORS: How to specify the affine transformation in the SVG file. */ + GtkWidget *f = gtk_frame_new (_("Store transformation:")); + gtk_widget_show (f); + gtk_box_pack_start (GTK_BOX (vb), f, FALSE, FALSE, 0); + + GtkWidget *fb = gtk_vbox_new (FALSE, 0); + gtk_widget_show (fb); + gtk_container_add (GTK_CONTAINER (f), fb); + + gint preserve = prefs_get_int_attribute ("options.preservetransform", "value", 0); + + GtkWidget *b = sp_select_context_add_radio ( + NULL, fb, tt, _("Optimized"), + _("If possible, apply transformation to objects without adding a transform= attribute"), + NULL, 0, true, + preserve == 0, + options_store_transform_toggled + ); + + sp_select_context_add_radio ( + b, fb, tt, _("Preserved"), + _("Always store transformation as a transform= attribute on objects"), + NULL, 1, true, + preserve != 0, + options_store_transform_toggled + ); + } + +// Selecting + vb = new_tab (nb, _("Selecting")); + + GtkWidget *f = gtk_frame_new (_("Ctrl+A, Tab, Shift+Tab:")); + gtk_widget_show (f); + gtk_box_pack_start (GTK_BOX (vb), f, FALSE, FALSE, 0); + + GtkWidget *fb = gtk_vbox_new (FALSE, 0); + gtk_widget_show (fb); + gtk_container_add (GTK_CONTAINER (f), fb); + +options_checkbox ( + _("Select only within current layer"), + _("Uncheck this to make keyboard selection commands work on objects in all layers"), tt, + fb, + "options.kbselection", "inlayer", 1, + options_changed_boolean + ); + +options_checkbox ( + _("Ignore hidden objects"), + _("Uncheck this to be able to select objects that are hidden (either by themselves or by being in a hidden group or layer)"), tt, + fb, + "options.kbselection", "onlyvisible", 1, + options_changed_boolean + ); + +options_checkbox ( + _("Ignore locked objects"), + _("Uncheck this to be able to select objects that are locked (either by themselves or by being in a locked group or layer)"), tt, + fb, + "options.kbselection", "onlysensitive", 1, + options_changed_boolean + ); + + +// To be broken into: Display, Save, Export, SVG, Commands + vb = new_tab (nb, _("Misc")); + + options_sb ( + _("Default export resolution:"), + _("Default bitmap resolution (in dots per inch) in the Export dialog"), tt, // FIXME: add "Used for new exports; once exported, documents remember this value on per-object basis" when implemented + _("dpi"), + vb, + 0.0, 6000.0, 1.0, 1.0, 1.0, + "dialogs.export.defaultxdpi", "value", PX_PER_IN, + true, false, + options_changed_int + ); + + options_checkbox ( + /* TRANSLATORS: When on, an imported bitmap creates an element; otherwise it is a + * rectangle with bitmap fill. */ + _("Import bitmap as "), + _("When on, an imported bitmap creates an element; otherwise it is a rectangle with bitmap fill"), tt, + vb, + "options.importbitmapsasimages", "value", 1, + options_changed_boolean + ); + + options_checkbox ( + /* TRANSLATORS: When on, the print out (currently Postscript) will have + * a comment with the each object's label visible, marking the section + * of the printing commands that represent the given object. */ + _("Add label comments to printing output"), + _("When on, a comment will be added to the raw print output, marking the rendered output for an object with its label"), tt, + vb, + "printing.debug", "show-label-comments", 0, + options_changed_boolean + ); + + options_checkbox ( + /* TRANSLATORS: When on, enable the effects menu, default is off */ + _("Enable script effects (requires restart) - EXPERIMENTAL"), + _("When on, the effects menu is enabled, allowing external effect scripts to be called, requires restart before effective - EXPERIMENTAL"), tt, + vb, + "extensions", "show-effects-menu", 0, + options_changed_boolean + ); + + options_sb ( + /* TRANSLATORS: The maximum length of the Open Recent list in the File menu. */ + _("Max recent documents:"), + _("The maximum length of the Open Recent list in the File menu"), tt, + "", + vb, + 0.0, 1000.0, 1.0, 1.0, 1.0, + "options.maxrecentdocuments", "value", 20.0, + true, false, + options_changed_int + ); + + options_sb ( + _("Simplification threshold:"), + _("How strong is the Simplify command by default. If you invoke this command several times in quick succession, it will act more and more aggressively; invoking it again after a pause restores the default threshold."), tt, + "", + vb, + 0.0, 1.0, 0.001, 0.01, 0.01, + "options.simplifythreshold", "value", 0.002, + false, false, + options_changed_double + ); + + + /* Oversample */ + hb = gtk_hbox_new (FALSE, HB_MARGIN); + gtk_widget_show (hb); + gtk_box_pack_start (GTK_BOX (vb), hb, FALSE, FALSE, 0); + + // empty label for alignment + l = gtk_label_new (""); + gtk_widget_set_size_request (l, SUFFIX_WIDTH, -1); + gtk_widget_show (l); + gtk_box_pack_end (GTK_BOX (hb), l, FALSE, FALSE, 0); + + l = gtk_label_new (_("Oversample bitmaps:")); + gtk_misc_set_alignment (GTK_MISC (l), 1.0, 0.5); + gtk_widget_show (l); + gtk_box_pack_start (GTK_BOX (hb), l, TRUE, TRUE, 0); + + om = gtk_option_menu_new (); + gtk_widget_set_size_request (om, SB_WIDTH, -1); + gtk_widget_show (om); + gtk_box_pack_end (GTK_BOX (hb), om, FALSE, FALSE, SB_MARGIN); + + m = gtk_menu_new (); + gtk_widget_show (m); + + i = gtk_menu_item_new_with_label (_("None")); + gtk_signal_connect ( GTK_OBJECT (i), "activate", + GTK_SIGNAL_FUNC (sp_display_dialog_set_oversample), + GINT_TO_POINTER (0) ); + gtk_widget_show (i); + gtk_menu_append (GTK_MENU (m), i); + i = gtk_menu_item_new_with_label (_("2x2")); + gtk_signal_connect ( GTK_OBJECT (i), "activate", + GTK_SIGNAL_FUNC (sp_display_dialog_set_oversample), + GINT_TO_POINTER (1) ); + gtk_widget_show (i); + gtk_menu_append (GTK_MENU (m), i); + i = gtk_menu_item_new_with_label (_("4x4")); + gtk_signal_connect ( GTK_OBJECT (i), "activate", + GTK_SIGNAL_FUNC (sp_display_dialog_set_oversample), + GINT_TO_POINTER (2) ); + gtk_widget_show (i); + gtk_menu_append (GTK_MENU (m), i); + i = gtk_menu_item_new_with_label (_("8x8")); + gtk_signal_connect ( GTK_OBJECT (i), "activate", + GTK_SIGNAL_FUNC (sp_display_dialog_set_oversample), + GINT_TO_POINTER (3)); + gtk_widget_show (i); + gtk_menu_append (GTK_MENU (m), i); + i = gtk_menu_item_new_with_label (_("16x16")); + gtk_signal_connect ( GTK_OBJECT (i), "activate", + GTK_SIGNAL_FUNC (sp_display_dialog_set_oversample), + GINT_TO_POINTER (4) ); + gtk_widget_show (i); + gtk_menu_append (GTK_MENU (m), i); + + gtk_option_menu_set_menu (GTK_OPTION_MENU (om), m); + + gtk_option_menu_set_history ( GTK_OPTION_MENU (om), + nr_arena_image_x_sample); + + g_signal_connect(GTK_OBJECT (nb), "switch-page", GTK_SIGNAL_FUNC (prefs_switch_page), (void *) "page_top"); + gtk_notebook_set_current_page (GTK_NOTEBOOK (nb), prefs_get_int_attribute ("dialogs.preferences", "page_top", 0)); + + } // end of if (!dlg) + + gtk_window_present ((GtkWindow *) dlg); + +} // end of sp_display_dialog() + + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/dialogs/display-settings.h b/src/dialogs/display-settings.h new file mode 100644 index 000000000..2a28ea971 --- /dev/null +++ b/src/dialogs/display-settings.h @@ -0,0 +1,69 @@ +#ifndef __SP_DISPLAY_SETTINGS_H__ +#define __SP_DISPLAY_SETTINGS_H__ + +/** + * \brief Display settings dialog + * + * Author: + * Lauris Kaplinski + * + * Copyright (C) 2001 Ximian, Inc. + * + */ + +#include + +#include + +void sp_display_dialog ( void ); +void sp_display_dialog_apply ( GtkWidget * widget ); +void sp_display_dialog_close ( GtkWidget * widget ); + +// UPDATE THIS IF YOU'RE CHANGING OR REARRANGING PREFS PAGES. +// Otherwise the commands that open the dialog with a given page may become out of sync. + +enum { + PREFS_PAGE_MOUSE, + PREFS_PAGE_SCROLLING, + PREFS_PAGE_STEPS, + PREFS_PAGE_TOOLS, + PREFS_PAGE_WINDOWS, + PREFS_PAGE_CLONES, + PREFS_PAGE_TRANSFORMS, + PREFS_PAGE_SELECTING, + PREFS_PAGE_MISC +}; + +enum { + PREFS_PAGE_TOOLS_SELECTOR, + PREFS_PAGE_TOOLS_NODE, + PREFS_PAGE_TOOLS_ZOOM, + PREFS_PAGE_TOOLS_SHAPES, + PREFS_PAGE_TOOLS_PENCIL, + PREFS_PAGE_TOOLS_PEN, + PREFS_PAGE_TOOLS_CALLIGRAPHY, + PREFS_PAGE_TOOLS_TEXT, + PREFS_PAGE_TOOLS_GRADIENT, + PREFS_PAGE_TOOLS_CONNECTOR, + PREFS_PAGE_TOOLS_DROPPER +}; + +enum { + PREFS_PAGE_TOOLS_SHAPES_RECT, + PREFS_PAGE_TOOLS_SHAPES_ELLIPSE, + PREFS_PAGE_TOOLS_SHAPES_STAR, + PREFS_PAGE_TOOLS_SHAPES_SPIRAL +}; + +#endif + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/dialogs/eek-preview.cpp b/src/dialogs/eek-preview.cpp new file mode 100644 index 000000000..74cf0abf7 --- /dev/null +++ b/src/dialogs/eek-preview.cpp @@ -0,0 +1,522 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Eek Preview Stuffs. + * + * The Initial Developer of the Original Code is + * Jon A. Cruz. + * Portions created by the Initial Developer are Copyright (C) 2005 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include +#include "eek-preview.h" + +#define PRIME_BUTTON_MAGIC_NUMBER 1 + +#define FOCUS_PROP_ID 1 + + + +static void eek_preview_class_init( EekPreviewClass *klass ); +static void eek_preview_init( EekPreview *preview ); + +static GtkWidgetClass* parent_class = 0; + +void eek_preview_set_color( EekPreview* preview, int r, int g, int b ) +{ + preview->_r = r; + preview->_g = g; + preview->_b = b; +} + + +GType eek_preview_get_type(void) +{ + static GType preview_type = 0; + + if (!preview_type) { + static const GTypeInfo preview_info = { + sizeof( EekPreviewClass ), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc)eek_preview_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof( EekPreview ), + 0, /* n_preallocs */ + (GInstanceInitFunc)eek_preview_init, + NULL /* value_table */ + }; + + + preview_type = g_type_register_static( GTK_TYPE_DRAWING_AREA, "EekPreview", &preview_info, (GTypeFlags)0 ); + } + + return preview_type; +} + +GtkWidget* eek_preview_area_new(void) +{ + return NULL; +} + +static void eek_preview_size_request( GtkWidget* widget, GtkRequisition* req ) +{ + gint width = 0; + gint height = 0; + EekPreview* preview = EEK_PREVIEW(widget); + gboolean worked = gtk_icon_size_lookup( preview->_size, &width, &height ); + if ( !worked ) { + width = 16; + height = 16; + } + if ( preview->_view == VIEW_TYPE_LIST ) { + width *= 3; + } + req->width = width; + req->height = height; +} + +enum { + CLICKED_SIGNAL, + ALTCLICKED_SIGNAL, + LAST_SIGNAL +}; + + +static guint eek_preview_signals[LAST_SIGNAL] = { 0 }; + + +gboolean eek_preview_expose_event( GtkWidget* widget, GdkEventExpose* event ) +{ +/* g_message("Exposed!!! %s", GTK_WIDGET_HAS_FOCUS(widget) ? "XXX" : "---" ); */ + gint insetX = 0; + gint insetY = 0; + +/* + gint lower = widget->allocation.width; + lower = (widget->allocation.height < lower) ? widget->allocation.height : lower; + if ( lower > 16 ) { + insetX++; + if ( lower > 18 ) { + insetX++; + if ( lower > 22 ) { + insetX++; + if ( lower > 24 ) { + insetX++; + if ( lower > 32 ) { + insetX++; + } + } + } + } + insetY = insetX; + } +*/ + + if ( GTK_WIDGET_DRAWABLE( widget ) ) { + GtkStyle* style = gtk_widget_get_style( widget ); + + if ( insetX > 0 || insetY > 0 ) { + gtk_paint_flat_box( style, + widget->window, + (GtkStateType)GTK_WIDGET_STATE(widget), + GTK_SHADOW_NONE, + NULL, + widget, + NULL, + 0, 0, + widget->allocation.width, widget->allocation.height); + } + + GdkGC *gc = gdk_gc_new( widget->window ); + EekPreview* preview = EEK_PREVIEW(widget); + GdkColor fg = {0, preview->_r, preview->_g, preview->_b}; + gdk_colormap_alloc_color( gdk_colormap_get_system(), &fg, FALSE, TRUE ); + + gdk_gc_set_foreground( gc, &fg ); + + gdk_draw_rectangle( widget->window, + gc, + TRUE, + insetX, insetY, + widget->allocation.width - (insetX * 2), widget->allocation.height - (insetY * 2) ); + + if ( GTK_WIDGET_HAS_FOCUS(widget) ) { + gtk_paint_focus( style, + widget->window, + GTK_STATE_NORMAL, + NULL, /* GdkRectangle *area, */ + widget, + NULL, + 0 + 1, 0 + 1, + widget->allocation.width - 2, widget->allocation.height - 2 ); + } + } + + + return FALSE; +} + + +static gboolean eek_preview_enter_cb( GtkWidget* widget, GdkEventCrossing* event ) +{ + if ( gtk_get_event_widget( (GdkEvent*)event ) == widget ) { + EekPreview* preview = EEK_PREVIEW(widget); + preview->_within = TRUE; + gtk_widget_set_state( widget, preview->_hot ? GTK_STATE_ACTIVE : GTK_STATE_PRELIGHT ); + } + return FALSE; +} + +static gboolean eek_preview_leave_cb( GtkWidget* widget, GdkEventCrossing* event ) +{ + if ( gtk_get_event_widget( (GdkEvent*)event ) == widget ) { + EekPreview* preview = EEK_PREVIEW(widget); + preview->_within = FALSE; + gtk_widget_set_state( widget, GTK_STATE_NORMAL ); + } + return FALSE; +} + +/* +static gboolean eek_preview_focus_in_event( GtkWidget* widget, GdkEventFocus* event ) +{ + g_message("focus IN"); + gboolean blip = parent_class->focus_in_event ? parent_class->focus_in_event(widget, event) : FALSE; + return blip; +} + +static gboolean eek_preview_focus_out_event( GtkWidget* widget, GdkEventFocus* event ) +{ + g_message("focus OUT"); + gboolean blip = parent_class->focus_out_event ? parent_class->focus_out_event(widget, event) : FALSE; + return blip; +} +*/ + +static gboolean eek_preview_button_press_cb( GtkWidget* widget, GdkEventButton* event ) +{ + if ( gtk_get_event_widget( (GdkEvent*)event ) == widget ) { + EekPreview* preview = EEK_PREVIEW(widget); + + if ( preview->_takesFocus && !GTK_WIDGET_HAS_FOCUS(widget) ) { + gtk_widget_grab_focus(widget); + } + + if ( event->button == PRIME_BUTTON_MAGIC_NUMBER ) { + preview->_hot = TRUE; + if ( preview->_within ) { + gtk_widget_set_state( widget, GTK_STATE_ACTIVE ); + } + } + } + + return FALSE; +} + +static gboolean eek_preview_button_release_cb( GtkWidget* widget, GdkEventButton* event ) +{ + if ( gtk_get_event_widget( (GdkEvent*)event ) == widget ) { + EekPreview* preview = EEK_PREVIEW(widget); + preview->_hot = FALSE; + gtk_widget_set_state( widget, GTK_STATE_NORMAL ); + if ( preview->_within && event->button == PRIME_BUTTON_MAGIC_NUMBER ) { + gboolean isAlt = (event->state & GDK_SHIFT_MASK) == GDK_SHIFT_MASK; + + if ( isAlt ) { + g_signal_emit( widget, eek_preview_signals[ALTCLICKED_SIGNAL], 0, 2 ); + } else { + g_signal_emit( widget, eek_preview_signals[CLICKED_SIGNAL], 0 ); + } + } + } + return FALSE; +} + +gboolean eek_preview_key_press_event( GtkWidget* widget, GdkEventKey* event) +{ + g_message("TICK"); + return FALSE; +} + +gboolean eek_preview_key_release_event( GtkWidget* widget, GdkEventKey* event) +{ + g_message("tock"); + return FALSE; +} + +static void eek_preview_get_property( GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + GObjectClass* gobjClass = G_OBJECT_CLASS(parent_class); + switch ( property_id ) { + case FOCUS_PROP_ID: + { + EekPreview* preview = EEK_PREVIEW( object ); + g_value_set_boolean( value, preview->_takesFocus ); + } + break; + default: + { + if ( gobjClass->get_property ) { + gobjClass->get_property( object, property_id, value, pspec ); + } + } + } +} + +static void eek_preview_set_property( GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + GObjectClass* gobjClass = G_OBJECT_CLASS(parent_class); + switch ( property_id ) { + case FOCUS_PROP_ID: + { + EekPreview* preview = EEK_PREVIEW( object ); + gboolean val = g_value_get_boolean( value ); + if ( val != preview->_takesFocus ) { + preview->_takesFocus = val; + } + } + break; + default: + { + if ( gobjClass->set_property ) { + gobjClass->set_property( object, property_id, value, pspec ); + } + } + } +} + + +static gboolean eek_preview_popup_menu( GtkWidget* widget ) +{ +/* g_message("Do the popup!"); */ + gboolean blip = parent_class->popup_menu ? parent_class->popup_menu(widget) : FALSE; + return blip; +} + + +static void eek_preview_class_init( EekPreviewClass *klass ) +{ + GObjectClass* gobjClass = G_OBJECT_CLASS(klass); + /*GtkObjectClass* objectClass = (GtkObjectClass*)klass;*/ + GtkWidgetClass* widgetClass = (GtkWidgetClass*)klass; + + gobjClass->set_property = eek_preview_set_property; + gobjClass->get_property = eek_preview_get_property; + + /*objectClass->destroy = eek_preview_destroy;*/ + + parent_class = (GtkWidgetClass*)g_type_class_peek_parent( klass ); + + /*widgetClass->map = ;*/ + /*widgetClass->unmap = ;*/ + /*widgetClass->realize = ;*/ + /*widgetClass->unrealize = ;*/ + widgetClass->size_request = eek_preview_size_request; + /*widgetClass->size_allocate = ;*/ + /*widgetClass->state_changed = ;*/ + /*widgetClass->style_set = ;*/ + /*widgetClass->grab_notify = ;*/ + + widgetClass->button_press_event = eek_preview_button_press_cb; + widgetClass->button_release_event = eek_preview_button_release_cb; + /*widgetClass->delete_event = ;*/ + /*widgetClass->destroy_event = ;*/ + widgetClass->expose_event = eek_preview_expose_event; +/* widgetClass->key_press_event = eek_preview_key_press_event; */ +/* widgetClass->key_release_event = eek_preview_key_release_event; */ + widgetClass->enter_notify_event = eek_preview_enter_cb; + widgetClass->leave_notify_event = eek_preview_leave_cb; + /*widgetClass->configure_event = ;*/ + /*widgetClass->focus_in_event = eek_preview_focus_in_event;*/ + /*widgetClass->focus_out_event = eek_preview_focus_out_event;*/ + + /* selection */ + /*widgetClass->selection_get = ;*/ + /*widgetClass->selection_received = ;*/ + + + /* drag source: */ + /*widgetClass->drag_begin = ;*/ + /*widgetClass->drag_end = ;*/ + /*widgetClass->drag_data_get = ;*/ + /*widgetClass->drag_data_delete = ;*/ + + /* drag target: */ + /*widgetClass->drag_leave = ;*/ + /*widgetClass->drag_motion = ;*/ + /*widgetClass->drag_drop = ;*/ + /*widgetClass->drag_data_received = ;*/ + + /* For keybindings: */ + widgetClass->popup_menu = eek_preview_popup_menu; + /*widgetClass->show_help = ;*/ + + /* Accessibility support: */ + /*widgetClass->get_accessible = ;*/ + /*widgetClass->screen_changed = ;*/ + /*widgetClass->can_activate_accel = ;*/ + + + eek_preview_signals[CLICKED_SIGNAL] = + g_signal_new( "clicked", + G_TYPE_FROM_CLASS( klass ), + (GSignalFlags)(G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION), + G_STRUCT_OFFSET( EekPreviewClass, clicked ), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0 ); + + eek_preview_signals[ALTCLICKED_SIGNAL] = + g_signal_new( "alt-clicked", + G_TYPE_FROM_CLASS( klass ), + (GSignalFlags)(G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION), + G_STRUCT_OFFSET( EekPreviewClass, clicked ), + NULL, NULL, + g_cclosure_marshal_VOID__INT, G_TYPE_NONE, + 1, G_TYPE_INT ); + + + g_object_class_install_property( gobjClass, + FOCUS_PROP_ID, + g_param_spec_boolean( + "focus-on-click", + NULL, + "flag to grab focus when clicked", + TRUE, + (GParamFlags)(G_PARAM_READWRITE | G_PARAM_CONSTRUCT) + ) + ); +} + +gboolean eek_preview_get_focus_on_click( EekPreview* preview ) +{ + return preview->_takesFocus; +} + +void eek_preview_set_focus_on_click( EekPreview* preview, gboolean focus_on_click ) +{ + if ( focus_on_click != preview->_takesFocus ) { + preview->_takesFocus = focus_on_click; + } +} + +void eek_preview_set_details( EekPreview* preview, PreviewStyle prevstyle, ViewType view, GtkIconSize size ) +{ + preview->_prevstyle = prevstyle; + preview->_view = view; + preview->_size = size; + + gtk_widget_queue_draw(GTK_WIDGET(preview)); +} + +static void eek_preview_init( EekPreview *preview ) +{ + GtkWidget* widg = GTK_WIDGET(preview); + GTK_WIDGET_SET_FLAGS( widg, GTK_CAN_FOCUS ); + GTK_WIDGET_SET_FLAGS( widg, GTK_RECEIVES_DEFAULT ); + + gtk_widget_set_sensitive( widg, TRUE ); + + gtk_widget_add_events(widg, GDK_BUTTON_PRESS_MASK + | GDK_BUTTON_RELEASE_MASK + | GDK_KEY_PRESS_MASK + | GDK_KEY_RELEASE_MASK + | GDK_FOCUS_CHANGE_MASK + | GDK_ENTER_NOTIFY_MASK + | GDK_LEAVE_NOTIFY_MASK ); + +/* gtk_widget_add_events( widg, GDK_ALL_EVENTS_MASK );*/ + + preview->_r = 0x80; + preview->_g = 0x80; + preview->_b = 0xcc; + + preview->_hot = FALSE; + preview->_within = FALSE; + preview->_takesFocus = FALSE; + + preview->_prevstyle = PREVIEW_STYLE_ICON; + preview->_view = VIEW_TYPE_LIST; + preview->_size = GTK_ICON_SIZE_BUTTON; + +/* + GdkColor color = {0}; + color.red = (255 << 8) | 255; + + GdkColor whack = {0}; + whack.green = (255 << 8) | 255; + + gtk_widget_modify_bg( widg, GTK_STATE_NORMAL, &color ); + gtk_widget_modify_bg( widg, GTK_STATE_PRELIGHT, &whack ); +*/ + +/* GTK_STATE_ACTIVE, */ +/* GTK_STATE_PRELIGHT, */ +/* GTK_STATE_SELECTED, */ +/* GTK_STATE_INSENSITIVE */ + + if ( 0 ) { + GdkColor color = {0,0,0,0}; + + color.red = 0xffff; + color.green = 0; + color.blue = 0xffff; + gdk_colormap_alloc_color( gdk_colormap_get_system(), &color, FALSE, TRUE ); + gtk_widget_modify_bg(widg, GTK_STATE_ACTIVE, &color); + + color.red = 0; + color.green = 0xffff; + color.blue = 0; + gdk_colormap_alloc_color( gdk_colormap_get_system(), &color, FALSE, TRUE ); + gtk_widget_modify_bg(widg, GTK_STATE_SELECTED, &color); + + color.red = 0xffff; + color.green = 0; + color.blue = 0; + gdk_colormap_alloc_color( gdk_colormap_get_system(), &color, FALSE, TRUE ); + gtk_widget_modify_bg( widg, GTK_STATE_PRELIGHT, &color ); + } +} + + +GtkWidget* eek_preview_new(void) +{ + return GTK_WIDGET( g_object_new( EEK_PREVIEW_TYPE, NULL ) ); +} + diff --git a/src/dialogs/eek-preview.h b/src/dialogs/eek-preview.h new file mode 100644 index 000000000..1d4e445a5 --- /dev/null +++ b/src/dialogs/eek-preview.h @@ -0,0 +1,112 @@ +#ifndef SEEN_EEK_PREVIEW_H +#define SEEN_EEK_PREVIEW_H +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Eek Preview Stuffs. + * + * The Initial Developer of the Original Code is + * Jon A. Cruz. + * Portions created by the Initial Developer are Copyright (C) 2005 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include + +G_BEGIN_DECLS + + +#define EEK_PREVIEW_TYPE (eek_preview_get_type()) +#define EEK_PREVIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST( (obj), EEK_PREVIEW_TYPE, EekPreview)) +#define EEK_PREVIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST( (klass), EEK_PREVIEW_TYPE, EekPreviewClass)) +#define IS_EEK_PREVIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE( (obj), EEK_PREVIEW_TYPE)) +#define IS_EEK_PREVIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE( (klass), EEK_PREVIEW_TYPE)) +#define EEK_PREVIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS( (obj), EEK_PREVIEW_TYPE, EekPreviewClass)) + +typedef enum { + PREVIEW_STYLE_ICON = 0, + PREVIEW_STYLE_PREVIEW, + PREVIEW_STYLE_NAME, + PREVIEW_STYLE_BLURB, + PREVIEW_STYLE_ICON_NAME, + PREVIEW_STYLE_ICON_BLURB, + PREVIEW_STYLE_PREVIEW_NAME, + PREVIEW_STYLE_PREVIEW_BLURB +} PreviewStyle; + +typedef enum { + VIEW_TYPE_LIST = 0, + VIEW_TYPE_GRID +} ViewType; + + +typedef struct _EekPreview EekPreview; +typedef struct _EekPreviewClass EekPreviewClass; + + +struct _EekPreview +{ + GtkDrawingArea drawing; + + int _r; + int _g; + int _b; + + gboolean _hot; + gboolean _within; + gboolean _takesFocus; + + PreviewStyle _prevstyle; + ViewType _view; + GtkIconSize _size; +}; + +struct _EekPreviewClass +{ + GtkDrawingAreaClass parent_class; + + void (*clicked) (EekPreview* splat); +}; + + +GType eek_preview_get_type(void) G_GNUC_CONST; +GtkWidget* eek_preview_new(void); + +void eek_preview_set_details( EekPreview* splat, PreviewStyle prevstyle, ViewType view, GtkIconSize size ); +void eek_preview_set_color( EekPreview* splat, int r, int g, int b ); + +gboolean eek_preview_get_focus_on_click( EekPreview* preview ); +void eek_preview_set_focus_on_click( EekPreview* preview, gboolean focus_on_click ); + +G_END_DECLS + + +#endif /* SEEN_EEK_PREVIEW_H */ diff --git a/src/dialogs/export.cpp b/src/dialogs/export.cpp new file mode 100644 index 000000000..9f758bf9e --- /dev/null +++ b/src/dialogs/export.cpp @@ -0,0 +1,1753 @@ +#define __SP_EXPORT_C__ + +/** \file + * \brief PNG export dialog + */ + +/* + * Authors: + * Lauris Kaplinski + * bulia byak + * + * Copyright (C) 1999-2005 Authors + * Copyright (C) 2001-2002 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include +#include "helper/unit-menu.h" +#include "helper/units.h" +#include "unit-constants.h" +#include "helper/window.h" +#include "inkscape-private.h" +#include "document.h" +#include "desktop-handles.h" +#include "sp-item.h" +#include "selection.h" +#include "file.h" +#include "macros.h" +#include "sp-namedview.h" + +#include "dialog-events.h" +#include "../prefs-utils.h" +#include "../verbs.h" +#include "../interface.h" + +#include "extension/output.h" +#include "extension/db.h" + +#include "io/sys.h" + + +#define SP_EXPORT_MIN_SIZE 1.0 + +#define DPI_BASE PX_PER_IN + +#define EXPORT_COORD_PRECISION 3 + +static void sp_export_area_toggled ( GtkToggleButton *tb, GtkObject *base ); +static void sp_export_export_clicked ( GtkButton *button, GtkObject *base ); +static void sp_export_browse_clicked ( GtkButton *button, gpointer userdata ); +static void sp_export_browse_store ( GtkButton *button, gpointer userdata ); + + +static void sp_export_area_x_value_changed ( GtkAdjustment *adj, + GtkObject *base); + +static void sp_export_area_y_value_changed ( GtkAdjustment *adj, + GtkObject *base); + +static void sp_export_area_width_value_changed ( GtkAdjustment *adj, + GtkObject *base); + +static void sp_export_area_height_value_changed ( GtkAdjustment *adj, + GtkObject *base); + +static void sp_export_bitmap_width_value_changed ( GtkAdjustment *adj, + GtkObject *base); + +static void sp_export_xdpi_value_changed ( GtkAdjustment *adj, + GtkObject *base); + +static void sp_export_selection_changed ( Inkscape::Application *inkscape, + Inkscape::Selection *selection, + GtkObject *base); +static void sp_export_selection_modified ( Inkscape::Application *inkscape, + Inkscape::Selection *selection, + guint flags, + GtkObject *base ); + +static void sp_export_set_area (GtkObject *base, double x0, double y0, double x1, double y1); +static void sp_export_value_set (GtkObject *base, const gchar *key, double val); +static void sp_export_value_set_px (GtkObject *base, const gchar *key, double val); +static float sp_export_value_get ( GtkObject *base, const gchar *key ); +static float sp_export_value_get_px ( GtkObject *base, const gchar *key ); + +static void sp_export_filename_modified (GtkObject * object, gpointer data); +static inline void sp_export_find_default_selection(GtkWidget * dlg); +static void sp_export_detect_size(GtkObject * base); + +static const gchar *prefs_path = "dialogs.export"; + +// these all need to be reinitialized to their defaults during dialog_destroy +static GtkWidget *dlg = NULL; +static win_data wd; +static gint x = -1000, y = -1000, w = 0, h = 0; // impossible original values to make sure they are read from prefs +static gchar * original_name = NULL; +static gchar * doc_export_name = NULL; +static bool was_empty = TRUE; + +/** What type of button is being pressed */ +enum selection_type { + SELECTION_PAGE = 0, /**< Export the whole page */ + SELECTION_DRAWING, /**< Export everything drawn on the page */ + SELECTION_SELECTION, /**< Export everything that is selected */ + SELECTION_CUSTOM, /**< Allows the user to set the region exported */ + SELECTION_NUMBER_OF /**< A counter for the number of these guys */ +}; + +/** A list of strings that is used both in the preferences, and in the + data fields to describe the various values of \c selection_type. */ +static const char * selection_names[SELECTION_NUMBER_OF] = { + "page", "drawing", "selection", "custom"}; + +/** The names on the buttons for the various selection types. */ +static const char * selection_labels[SELECTION_NUMBER_OF] = { + N_("_Page"), N_("_Drawing"), N_("_Selection"), N_("_Custom")}; + +static void +sp_export_dialog_destroy ( GtkObject *object, gpointer data ) +{ + sp_signal_disconnect_by_data (INKSCAPE, dlg); + + wd.win = dlg = NULL; + wd.stop = 0; + x = -1000; y = -1000; w = 0; h = 0; + g_free(original_name); + original_name = NULL; + g_free(doc_export_name); + doc_export_name = NULL; + was_empty = TRUE; + + return; +} // end of sp_export_dialog_destroy() + +/// Called when dialog is closed or inkscape is shut down. +static bool +sp_export_dialog_delete ( GtkObject *object, GdkEvent *event, gpointer data ) +{ + + gtk_window_get_position ((GtkWindow *) dlg, &x, &y); + gtk_window_get_size ((GtkWindow *) dlg, &w, &h); + + prefs_set_int_attribute (prefs_path, "x", x); + prefs_set_int_attribute (prefs_path, "y", y); + prefs_set_int_attribute (prefs_path, "w", w); + prefs_set_int_attribute (prefs_path, "h", h); + + return FALSE; // which means, go ahead and destroy it + +} // end of sp_export_dialog_delete() + +/** + \brief Creates a new spin button for the export dialog + \param key The name of the spin button + \param val A default value for the spin button + \param min Minimum value for the spin button + \param max Maximum value for the spin button + \param step The step size for the spin button + \param page Size of the page increment + \param us Unit selector that effects this spin button + \param t Table to put the spin button in + \param x X location in the table \c t to start with + \param y Y location in the table \c t to start with + \param ll Text to put on the left side of the spin button (optional) + \param lr Text to put on the right side of the spin button (optional) + \param digits Number of digits to display after the decimal + \param sensitive Whether the spin button is sensitive or not + \param cb Callback for when this spin button is changed (optional) + \param dlg Export dialog the spin button is being placed in + +*/ +static void +sp_export_spinbutton_new ( gchar *key, float val, float min, float max, + float step, float page, GtkWidget *us, + GtkWidget *t, int x, int y, + const gchar *ll, const gchar *lr, + int digits, unsigned int sensitive, + GCallback cb, GtkWidget *dlg ) +{ + GtkObject *a = gtk_adjustment_new (val, min, max, step, page, page); + gtk_object_set_data (a, "key", key); + gtk_object_set_data (GTK_OBJECT (dlg), (const gchar *)key, a); + + if (us) { + sp_unit_selector_add_adjustment ( SP_UNIT_SELECTOR (us), + GTK_ADJUSTMENT (a) ); + } + + int pos = 0; + + GtkWidget *l = NULL; + + if (ll) { + + l = gtk_label_new_with_mnemonic ((const gchar *)ll); + gtk_misc_set_alignment (GTK_MISC (l), 1.0, 0.5); + gtk_table_attach ( GTK_TABLE (t), l, x + pos, x + pos + 1, y, y + 1, + (GtkAttachOptions)0, (GtkAttachOptions)0, 0, 0 ); + gtk_widget_set_sensitive (l, sensitive); + pos += 1; + + } + + GtkWidget *sb = gtk_spin_button_new (GTK_ADJUSTMENT (a), 1.0, digits); + gtk_table_attach ( GTK_TABLE (t), sb, x + pos, x + pos + 1, y, y + 1, + (GtkAttachOptions)0, (GtkAttachOptions)0, 0, 0 ); + gtk_widget_set_size_request (sb, 80, -1); + gtk_widget_set_sensitive (sb, sensitive); + pos += 1; + + if (ll) { gtk_label_set_mnemonic_widget (GTK_LABEL(l), sb); } + + if (lr) { + + l = gtk_label_new_with_mnemonic ((const gchar *)lr); + gtk_misc_set_alignment (GTK_MISC (l), 0.0, 0.5); + gtk_table_attach ( GTK_TABLE (t), l, x + pos, x + pos + 1, y, y + 1, + (GtkAttachOptions)0, (GtkAttachOptions)0, 0, 0 ); + gtk_widget_set_sensitive (l, sensitive); + pos += 1; + + gtk_label_set_mnemonic_widget (GTK_LABEL(l), sb); + } + + if (cb) + gtk_signal_connect (a, "value_changed", cb, dlg); + + return; +} // end of sp_export_spinbutton_new() + + +static GtkWidget * +sp_export_dialog_area_frame (GtkWidget * dlg) +{ + GtkWidget * f, * t, * hb, * b, * us, * l, * vb, * unitbox; + + f = gtk_frame_new (_("Export area")); + vb = gtk_vbox_new (FALSE, 2); + gtk_container_add (GTK_CONTAINER (f), vb); + + /* Units box */ + unitbox = gtk_hbox_new (FALSE, 0); + gtk_container_set_border_width (GTK_CONTAINER (unitbox), 4); + /* gets added to the vbox later, but the unit selector is needed + earlier than that */ + + us = sp_unit_selector_new (SP_UNIT_ABSOLUTE | SP_UNIT_DEVICE); + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + if (desktop) + sp_unit_selector_set_unit (SP_UNIT_SELECTOR(us), SP_DT_NAMEDVIEW(desktop)->doc_units); + gtk_box_pack_end (GTK_BOX (unitbox), us, FALSE, FALSE, 0); + l = gtk_label_new (_("Units:")); + gtk_box_pack_end (GTK_BOX (unitbox), l, FALSE, FALSE, 3); + gtk_object_set_data (GTK_OBJECT (dlg), "units", us); + + hb = gtk_hbox_new (TRUE, 0); + gtk_container_set_border_width (GTK_CONTAINER (hb), 4); + gtk_box_pack_start(GTK_BOX(vb), hb, FALSE, FALSE, 3); + + for (int i = 0; i < SELECTION_NUMBER_OF; i++) { + b = gtk_toggle_button_new_with_mnemonic (_(selection_labels[i])); + gtk_object_set_data (GTK_OBJECT (b), "key", GINT_TO_POINTER(i)); + gtk_object_set_data (GTK_OBJECT (dlg), selection_names[i], b); + gtk_box_pack_start (GTK_BOX (hb), b, FALSE, TRUE, 0); + gtk_signal_connect ( GTK_OBJECT (b), "clicked", + GTK_SIGNAL_FUNC (sp_export_area_toggled), dlg ); + } + + g_signal_connect ( G_OBJECT (INKSCAPE), "change_selection", + G_CALLBACK (sp_export_selection_changed), dlg ); + g_signal_connect ( G_OBJECT (INKSCAPE), "modify_selection", + G_CALLBACK (sp_export_selection_modified), dlg ); + g_signal_connect ( G_OBJECT (INKSCAPE), "activate_desktop", + G_CALLBACK (sp_export_selection_changed), dlg ); + + t = gtk_table_new (2, 6, FALSE); + gtk_box_pack_start(GTK_BOX(vb), t, FALSE, FALSE, 0); + gtk_table_set_row_spacings (GTK_TABLE (t), 4); + gtk_table_set_col_spacings (GTK_TABLE (t), 4); + gtk_container_set_border_width (GTK_CONTAINER (t), 4); + + sp_export_spinbutton_new ( "x0", 0.0, -1000000.0, 1000000.0, 0.1, 1.0, us, + t, 0, 0, _("_x0:"), NULL, EXPORT_COORD_PRECISION, 1, + G_CALLBACK ( sp_export_area_x_value_changed), + dlg ); + + sp_export_spinbutton_new ( "x1", 0.0, -1000000.0, 1000000.0, 0.1, 1.0, us, + t, 2, 0, _("x_1:"), NULL, EXPORT_COORD_PRECISION, 1, + G_CALLBACK (sp_export_area_x_value_changed), + dlg ); + + sp_export_spinbutton_new ( "width", 0.0, -1000000.0, 1000000.0, 0.1, 1.0, + us, t, 4, 0, _("Width:"), NULL, EXPORT_COORD_PRECISION, 1, + G_CALLBACK + (sp_export_area_width_value_changed), + dlg ); + + sp_export_spinbutton_new ( "y0", 0.0, -1000000.0, 1000000.0, 0.1, 1.0, us, + t, 0, 1, _("_y0:"), NULL, EXPORT_COORD_PRECISION, 1, + G_CALLBACK (sp_export_area_y_value_changed), + dlg ); + + sp_export_spinbutton_new ( "y1", 0.0, -1000000.0, 1000000.0, 0.1, 1.0, us, + t, 2, 1, _("y_1:"), NULL, EXPORT_COORD_PRECISION, 1, + G_CALLBACK (sp_export_area_y_value_changed), + dlg ); + + sp_export_spinbutton_new ( "height", 0.0, -1000000.0, 1000000.0, 0.1, 1.0, + us, t, 4, 1, _("Height:"), NULL, EXPORT_COORD_PRECISION, 1, + G_CALLBACK (sp_export_area_height_value_changed), + dlg ); + + /* Adding in the unit box */ + gtk_box_pack_start(GTK_BOX(vb), unitbox, FALSE, FALSE, 0); + + return f; +} // end of sp_export_dialog_area_frame + + +void +sp_export_dialog (void) +{ + if (!dlg) { + GtkWidget *vb, *hb; + + gchar title[500]; + sp_ui_dialog_title_string (Inkscape::Verb::get(SP_VERB_FILE_EXPORT), title); + + dlg = sp_window_new (title, TRUE); + + if (x == -1000 || y == -1000) { + x = prefs_get_int_attribute (prefs_path, "x", 0); + y = prefs_get_int_attribute (prefs_path, "y", 0); + } + + if (w ==0 || h == 0) { + w = prefs_get_int_attribute (prefs_path, "w", 0); + h = prefs_get_int_attribute (prefs_path, "h", 0); + } + + if (x != 0 || y != 0) { + gtk_window_move ((GtkWindow *) dlg, x, y); + } else { + gtk_window_set_position(GTK_WINDOW(dlg), GTK_WIN_POS_CENTER); + } + + if (w && h) + gtk_window_resize ((GtkWindow *) dlg, w, h); + + sp_transientize (dlg); + wd.win = dlg; + wd.stop = 0; + + g_signal_connect ( G_OBJECT (INKSCAPE), "activate_desktop", + G_CALLBACK (sp_transientize_callback), &wd); + + gtk_signal_connect ( GTK_OBJECT (dlg), "event", + GTK_SIGNAL_FUNC (sp_dialog_event_handler), dlg); + + gtk_signal_connect ( GTK_OBJECT (dlg), "destroy", + G_CALLBACK (sp_export_dialog_destroy), dlg); + + gtk_signal_connect ( GTK_OBJECT (dlg), "delete_event", + G_CALLBACK (sp_export_dialog_delete), dlg); + + g_signal_connect ( G_OBJECT (INKSCAPE), "shut_down", + G_CALLBACK (sp_export_dialog_delete), dlg); + + g_signal_connect ( G_OBJECT (INKSCAPE), "dialogs_hide", + G_CALLBACK (sp_dialog_hide), dlg); + + g_signal_connect ( G_OBJECT (INKSCAPE), "dialogs_unhide", + G_CALLBACK (sp_dialog_unhide), dlg); + + GtkTooltips *tt = gtk_tooltips_new(); + + vb = gtk_vbox_new (FALSE, 4); + gtk_container_set_border_width (GTK_CONTAINER (vb), 0); + gtk_container_add (GTK_CONTAINER (dlg), vb); + + /* Export area frame */ + { + GtkWidget *f = sp_export_dialog_area_frame(dlg); + gtk_box_pack_start (GTK_BOX (vb), f, FALSE, FALSE, 0); + } + + /* Bitmap size frame */ + { + GtkWidget *f = gtk_frame_new (_("Bitmap size")); + gtk_box_pack_start (GTK_BOX (vb), f, FALSE, FALSE, 0); + GtkWidget *t = gtk_table_new (2, 5, FALSE); + gtk_table_set_row_spacings (GTK_TABLE (t), 4); + gtk_table_set_col_spacings (GTK_TABLE (t), 4); + gtk_container_set_border_width (GTK_CONTAINER (t), 4); + gtk_container_add (GTK_CONTAINER (f), t); + + sp_export_spinbutton_new ( "bmwidth", 16.0, 1.0, 1000000.0, 1.0, 10.0, + NULL, t, 0, 0, + _("_Width:"), _("pixels at"), 0, 1, + G_CALLBACK + (sp_export_bitmap_width_value_changed), + dlg ); + + sp_export_spinbutton_new ( "xdpi", + prefs_get_double_attribute + ( "dialogs.export.defaultxdpi", + "value", DPI_BASE), + 1.0, 9600.0, 0.1, 1.0, NULL, t, 3, 0, + NULL, _("dp_i"), 2, 1, + G_CALLBACK (sp_export_xdpi_value_changed), + dlg ); + + sp_export_spinbutton_new ( "bmheight", 16.0, 1.0, 1000000.0, 1, 10.0, + NULL, t, 0, 1, _("Height:"), _("pixels at"), + 0, 0, NULL, dlg ); + + /** \todo + * Needs fixing: there's no way to set ydpi currently, so we use + * the defaultxdpi value here, too... + */ + sp_export_spinbutton_new ( "ydpi", prefs_get_double_attribute + ( "dialogs.export.defaultxdpi", + "value", DPI_BASE), + 1.0, 9600.0, 0.1, 1.0, NULL, t, 3, 1, + NULL, _("dpi"), 2, 0, NULL, dlg ); + } + + /* File entry */ + { + GtkWidget *frame = gtk_frame_new (""); + GtkWidget *flabel = gtk_label_new_with_mnemonic (_("_Filename")); + gtk_frame_set_label_widget (GTK_FRAME(frame), flabel); + gtk_box_pack_start (GTK_BOX (vb), frame, FALSE, FALSE, 0); + + GtkWidget *fe = gtk_entry_new (); + + /* + * set the default filename to be that of the current path + document + * with .png extension + * + * One thing to notice here is that this filename may get + * overwritten, but it won't happen here. The filename gets + * written into the text field, but then the button to select + * the area gets set. In that code the filename can be changed + * if there are some with presidence in the document. So, while + * this code sets the name first, it may not be the one users + * really see. + */ + if (SP_ACTIVE_DOCUMENT && SP_DOCUMENT_URI (SP_ACTIVE_DOCUMENT)) + { + gchar *name; + SPDocument * doc = SP_ACTIVE_DOCUMENT; + const gchar *uri = SP_DOCUMENT_URI (doc); + Inkscape::XML::Node * repr = sp_document_repr_root(doc); + const gchar * text_extension = repr->attribute("inkscape:output_extension"); + Inkscape::Extension::Output * oextension = NULL; + + if (text_extension != NULL) { + oextension = dynamic_cast(Inkscape::Extension::db.get(text_extension)); + } + + if (oextension != NULL) { + gchar * old_extension = oextension->get_extension(); + if (g_str_has_suffix(uri, old_extension)) { + gchar * uri_copy; + gchar * extension_point; + gchar * final_name; + + uri_copy = g_strdup(uri); + extension_point = g_strrstr(uri_copy, old_extension); + extension_point[0] = '\0'; + + final_name = g_strconcat(uri_copy, ".png", NULL); + gtk_entry_set_text (GTK_ENTRY (fe), final_name); + + g_free(final_name); + g_free(uri_copy); + } + } else { + name = g_strconcat(uri, ".png", NULL); + gtk_entry_set_text (GTK_ENTRY (fe), name); + g_free(name); + } + + doc_export_name = g_strdup(gtk_entry_get_text(GTK_ENTRY(fe))); + } + g_signal_connect ( G_OBJECT (fe), "changed", + G_CALLBACK (sp_export_filename_modified), dlg); + + hb = gtk_hbox_new (FALSE, 5); + gtk_container_add (GTK_CONTAINER (frame), hb); + gtk_container_set_border_width (GTK_CONTAINER (hb), 4); + + { + GtkWidget *b = gtk_button_new_with_mnemonic (_("_Browse...")); + gtk_box_pack_end (GTK_BOX (hb), b, FALSE, FALSE, 4); + g_signal_connect ( G_OBJECT (b), "clicked", + G_CALLBACK (sp_export_browse_clicked), NULL ); + } + + gtk_box_pack_start (GTK_BOX (hb), fe, TRUE, TRUE, 0); + gtk_object_set_data (GTK_OBJECT (dlg), "filename", fe); + gtk_object_set_data (GTK_OBJECT (dlg), "filename-modified", (gpointer)FALSE); + original_name = g_strdup(gtk_entry_get_text (GTK_ENTRY (fe))); + // pressing enter in the filename field is the same as clicking export: + g_signal_connect ( G_OBJECT (fe), "activate", + G_CALLBACK (sp_export_export_clicked), dlg ); + // focus is in the filename initially: + gtk_widget_grab_focus (GTK_WIDGET (fe)); + + // mnemonic in frame label moves focus to filename: + gtk_label_set_mnemonic_widget (GTK_LABEL(flabel), fe); + } + + /* Buttons */ + hb = gtk_hbox_new (FALSE, 0); + gtk_box_pack_end (GTK_BOX (vb), hb, FALSE, FALSE, 0); + + { + GtkWidget *b = gtk_button_new (); + GtkWidget *l = gtk_label_new (""); + gtk_label_set_markup_with_mnemonic (GTK_LABEL(l), _(" _Export ")); + gtk_container_add (GTK_CONTAINER(b), l); + gtk_tooltips_set_tip (tt, b, _("Export the bitmap file with these settings"), NULL); + gtk_signal_connect ( GTK_OBJECT (b), "clicked", + GTK_SIGNAL_FUNC (sp_export_export_clicked), dlg ); + gtk_box_pack_end (GTK_BOX (hb), b, FALSE, FALSE, 0); + } + + gtk_widget_show_all (vb); + + } // end of if (!dlg) + + sp_export_find_default_selection(dlg); + + gtk_window_present ((GtkWindow *) dlg); + + return; +} // end of sp_export_dialog() + +static inline void +sp_export_find_default_selection(GtkWidget * dlg) +{ + selection_type key = SELECTION_NUMBER_OF; + + if ((SP_DT_SELECTION(SP_ACTIVE_DESKTOP))->isEmpty() == false) { + key = SELECTION_SELECTION; + } + + /* Try using the preferences */ + if (key == SELECTION_NUMBER_OF) { + const gchar *what = NULL; + int i = SELECTION_NUMBER_OF; + + what = prefs_get_string_attribute ("dialogs.export.exportarea", "value"); + + if (what != NULL) { + for (i = 0; i < SELECTION_NUMBER_OF; i++) { + if (!strcmp (what, selection_names[i])) { + break; + } + } + } + + key = (selection_type)i; + } + + if (key == SELECTION_NUMBER_OF) { + key = SELECTION_SELECTION; + } + + GtkWidget *button = (GtkWidget *)g_object_get_data(G_OBJECT(dlg), + selection_names[key]); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE); + + return; +} + + +/** + * \brief If selection changed or a different document activated, we must + * recalculate any chosen areas + * + */ +static void +sp_export_selection_changed ( Inkscape::Application *inkscape, + Inkscape::Selection *selection, + GtkObject *base ) +{ + selection_type current_key; + current_key = (selection_type)(GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(base), "selection-type"))); + + if ((current_key == SELECTION_DRAWING || current_key == SELECTION_PAGE) && + (SP_DT_SELECTION(SP_ACTIVE_DESKTOP))->isEmpty() == false && + was_empty) { + gtk_toggle_button_set_active + ( GTK_TOGGLE_BUTTON ( gtk_object_get_data (base, selection_names[SELECTION_SELECTION])), + TRUE ); + } + was_empty = (SP_DT_SELECTION(SP_ACTIVE_DESKTOP))->isEmpty(); + + current_key = (selection_type)(GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(base), "selection-type"))); + + if (inkscape && + SP_IS_INKSCAPE (inkscape) && + selection && + SELECTION_CUSTOM != current_key) { + GtkToggleButton * button; + button = (GtkToggleButton *)gtk_object_get_data(base, selection_names[current_key]); + sp_export_area_toggled(button, base); + } // end of if() + + return; +} // end of sp_export_selection_changed() + +static void +sp_export_selection_modified ( Inkscape::Application *inkscape, + Inkscape::Selection *selection, + guint flags, + GtkObject *base ) +{ + selection_type current_key; + current_key = (selection_type)(GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(base), "selection-type"))); + + switch (current_key) { + case SELECTION_DRAWING: + if ( SP_ACTIVE_DESKTOP ) { + SPDocument *doc; + NRRect bbox; + doc = SP_DT_DOCUMENT (SP_ACTIVE_DESKTOP); + sp_item_bbox_desktop (SP_ITEM (SP_DOCUMENT_ROOT (doc)), &bbox); + + if (!(bbox.x0 > bbox.x1 && bbox.y0 > bbox.y1)) { + sp_export_set_area (base, bbox.x0, bbox.y0, bbox.x1, bbox.y1); + } + } + break; + case SELECTION_SELECTION: + if ((SP_DT_SELECTION(SP_ACTIVE_DESKTOP))->isEmpty() == false) { + NRRect bbox; + (SP_DT_SELECTION (SP_ACTIVE_DESKTOP))->bounds(&bbox); + sp_export_set_area (base, bbox.x0, bbox.y0, bbox.x1, bbox.y1); + } + break; + default: + /* Do nothing for page or for custom */ + break; + } + + return; +} + +/// Called when one of the selection buttons was toggled. +static void +sp_export_area_toggled (GtkToggleButton *tb, GtkObject *base) +{ + if (gtk_object_get_data (base, "update")) + return; + + selection_type key, old_key; + key = (selection_type)(GPOINTER_TO_INT(gtk_object_get_data (GTK_OBJECT (tb), "key"))); + old_key = (selection_type)(GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(base), "selection-type"))); + + /* Ignore all "turned off" events unless we're the only active button */ + if (!gtk_toggle_button_get_active (tb) ) { + + /* Don't let the current selection be deactived - but rerun the + activate to allow the user to renew the values */ + if (key == old_key) { + gtk_toggle_button_set_active ( tb, TRUE ); + } + + return; + } + + /* Turn off the currently active button unless it's us */ + gtk_object_set_data(GTK_OBJECT(base), "selection-type", (gpointer)key); + + if (old_key != key) { + gtk_toggle_button_set_active + ( GTK_TOGGLE_BUTTON ( gtk_object_get_data (base, selection_names[old_key])), + FALSE ); + } + + if ( SP_ACTIVE_DESKTOP ) + { + SPDocument *doc; + NRRect bbox; + doc = SP_DT_DOCUMENT (SP_ACTIVE_DESKTOP); + + /* Notice how the switch is used to 'fall through' here to get + various backups. If you modify this without noticing you'll + probabaly screw something up. */ + switch (key) { + case SELECTION_SELECTION: + if ((SP_DT_SELECTION(SP_ACTIVE_DESKTOP))->isEmpty() == false) + { + (SP_DT_SELECTION (SP_ACTIVE_DESKTOP))->bounds(&bbox); + /* Only if there is a selection that we can set + do we break, otherwise we fall through to the + drawing */ + // std::cout << "Using selection: SELECTION" << std::endl; + key = SELECTION_SELECTION; + break; + } + case SELECTION_DRAWING: + /** \todo + * This returns wrong values if the document has a viewBox. + */ + sp_item_bbox_desktop (SP_ITEM (SP_DOCUMENT_ROOT (doc)), &bbox); + + /* If the drawing is valid, then we'll use it and break + otherwise we drop through to the page settings */ + if (!(bbox.x0 > bbox.x1 && bbox.y0 > bbox.y1)) { + // std::cout << "Using selection: DRAWING" << std::endl; + key = SELECTION_DRAWING; + break; + } + case SELECTION_PAGE: + bbox.x0 = 0.0; + bbox.y0 = 0.0; + bbox.x1 = sp_document_width (doc); + bbox.y1 = sp_document_height (doc); + // std::cout << "Using selection: PAGE" << std::endl; + key = SELECTION_PAGE; + break; + case SELECTION_CUSTOM: + default: + break; + } // switch + + // remember area setting + prefs_set_string_attribute ( "dialogs.export.exportarea", + "value", selection_names[key]); + + if (key != SELECTION_CUSTOM) { + sp_export_set_area (base, bbox.x0, bbox.y0, bbox.x1, bbox.y1); + } + + } // end of if ( SP_ACTIVE_DESKTOP ) + + + if (SP_ACTIVE_DESKTOP && !gtk_object_get_data(GTK_OBJECT(base), "filename-modified")) { + GtkWidget * file_entry; + const gchar * filename = NULL; + float xdpi = 0.0, ydpi = 0.0; + + file_entry = (GtkWidget *)gtk_object_get_data (base, "filename"); + + switch (key) { + case SELECTION_PAGE: + case SELECTION_DRAWING: { + SPDocument * doc = SP_ACTIVE_DOCUMENT; + Inkscape::XML::Node * repr = sp_document_repr_root(doc); + const gchar * dpi_string; + + filename = repr->attribute("inkscape:export-filename"); + + dpi_string = NULL; + dpi_string = repr->attribute("inkscape:export-xdpi"); + if (dpi_string != NULL) { + xdpi = atof(dpi_string); + } + + dpi_string = NULL; + dpi_string = repr->attribute("inkscape:export-ydpi"); + if (dpi_string != NULL) { + ydpi = atof(dpi_string); + } + + if (filename == NULL) { + if (doc_export_name != NULL) { + filename = g_strdup(doc_export_name); + } else { + filename = g_strdup(""); + } + } + + break; + } + case SELECTION_SELECTION: + if ((SP_DT_SELECTION(SP_ACTIVE_DESKTOP))->isEmpty() == false) { + const GSList * reprlst; + bool filename_search = TRUE; + bool xdpi_search = TRUE; + bool ydpi_search = TRUE; + + reprlst = SP_DT_SELECTION(SP_ACTIVE_DESKTOP)->reprList(); + for(; reprlst != NULL && + filename_search && + xdpi_search && + ydpi_search; + reprlst = reprlst->next) { + const gchar * dpi_string; + Inkscape::XML::Node * repr = (Inkscape::XML::Node *)reprlst->data; + + if (filename_search) { + filename = repr->attribute("inkscape:export-filename"); + if (filename != NULL) + filename_search = FALSE; + } + + if (xdpi_search) { + dpi_string = NULL; + dpi_string = repr->attribute("inkscape:export-xdpi"); + if (dpi_string != NULL) { + xdpi = atof(dpi_string); + xdpi_search = FALSE; + } + } + + if (ydpi_search) { + dpi_string = NULL; + dpi_string = repr->attribute("inkscape:export-ydpi"); + if (dpi_string != NULL) { + ydpi = atof(dpi_string); + ydpi_search = FALSE; + } + } + } + + /* If we still don't have a filename -- let's build + one that's nice */ + if (filename == NULL) { + const gchar * id = NULL; + reprlst = SP_DT_SELECTION(SP_ACTIVE_DESKTOP)->reprList(); + for(; reprlst != NULL; reprlst = reprlst->next) { + Inkscape::XML::Node * repr = (Inkscape::XML::Node *)reprlst->data; + if (repr->attribute("id")) { + id = repr->attribute("id"); + break; + } + } + if (id == NULL) /* This should never happen */ + id = "bitmap"; + + gchar * directory = NULL; + const gchar * file_entry_text; + + file_entry_text = gtk_entry_get_text(GTK_ENTRY(file_entry)); + if (directory == NULL && file_entry_text != NULL && file_entry_text[0] != '\0') { + // std::cout << "Directory from dialog" << std::endl; + directory = g_dirname(file_entry_text); + } + + if (directory == NULL) { + /* Grab document directory */ + if (SP_DOCUMENT_URI(SP_ACTIVE_DOCUMENT)) { + // std::cout << "Directory from document" << std::endl; + directory = g_dirname(SP_DOCUMENT_URI(SP_ACTIVE_DOCUMENT)); + } + } + + if (directory == NULL) { + // std::cout << "Home Directory" << std::endl; + directory = homedir_path(NULL); + } + + gchar * id_ext = g_strconcat(id, ".png", NULL); + filename = g_build_filename(directory, id_ext, NULL); + g_free(directory); + g_free(id_ext); + } + } + break; + case SELECTION_CUSTOM: + default: + break; + } + + if (filename != NULL) { + g_free(original_name); + original_name = g_strdup(filename); + gtk_entry_set_text(GTK_ENTRY(file_entry), filename); + } + + if (xdpi != 0.0) { + sp_export_value_set(base, "xdpi", xdpi); + } + + /* These can't be seperate, and setting x sets y, so for + now setting this is disabled. Hopefully it won't be in + the future */ + if (FALSE && ydpi != 0.0) { + sp_export_value_set(base, "ydpi", ydpi); + } + } + + return; +} // end of sp_export_area_toggled() + +/// Called when dialog is deleted +static gint +sp_export_progress_delete ( GtkWidget *widget, GdkEvent *event, GObject *base ) +{ + g_object_set_data (base, "cancel", (gpointer) 1); + return TRUE; +} // end of sp_export_progress_delete() + +/// Called when progress is cancelled +static void +sp_export_progress_cancel ( GtkWidget *widget, GObject *base ) +{ + g_object_set_data (base, "cancel", (gpointer) 1); +} // end of sp_export_progress_cancel() + +/// Called for every progress iteration +static unsigned int +sp_export_progress_callback (float value, void *data) +{ + GtkWidget *prg; + int evtcount; + + if (g_object_get_data ((GObject *) data, "cancel")) + return FALSE; + + prg = (GtkWidget *) g_object_get_data ((GObject *) data, "progress"); + gtk_progress_bar_set_fraction ((GtkProgressBar *) prg, value); + + evtcount = 0; + while ((evtcount < 16) && gdk_events_pending ()) { + gtk_main_iteration_do (FALSE); + evtcount += 1; + } + + gtk_main_iteration_do (FALSE); + + return TRUE; + +} // end of sp_export_progress_callback() + +/// Called when export button is clicked +static void +sp_export_export_clicked (GtkButton *button, GtkObject *base) +{ + if (!SP_ACTIVE_DESKTOP) return; + + GtkWidget *fe = (GtkWidget *)gtk_object_get_data(base, "filename"); + gchar const *filename = gtk_entry_get_text(GTK_ENTRY(fe)); + + float const x0 = sp_export_value_get_px(base, "x0"); + float const y0 = sp_export_value_get_px(base, "y0"); + float const x1 = sp_export_value_get_px(base, "x1"); + float const y1 = sp_export_value_get_px(base, "y1"); + float const xdpi = sp_export_value_get(base, "xdpi"); + float const ydpi = sp_export_value_get(base, "ydpi"); + int const width = int(sp_export_value_get(base, "bmwidth") + 0.5); + int const height = int(sp_export_value_get(base, "bmheight") + 0.5); + + if (filename == NULL || *filename == '\0') { + sp_ui_error_dialog(_("You have to enter a filename")); + return; + } + + if (!((x1 > x0) && (y1 > y0) && (width > 0) && (height > 0))) { + sp_ui_error_dialog (_("The chosen area to be exported is invalid")); + return; + } + + gchar *dirname = g_dirname(filename); + if ( dirname == NULL + || !Inkscape::IO::file_test(dirname, (GFileTest)(G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)) ) + { + gchar *safeDir = Inkscape::IO::sanitizeString(dirname); + gchar *error = g_strdup_printf(_("Directory %s does not exist or is not a directory.\n"), + safeDir); + sp_ui_error_dialog(error); + g_free(safeDir); + g_free(error); + g_free(dirname); + return; + } + g_free(dirname); + + SPNamedView *nv = SP_DT_NAMEDVIEW(SP_ACTIVE_DESKTOP); + GtkWidget *dlg, *prg, *btn; /* progressbar-stuff */ + char *fn; + gchar *text; + + dlg = gtk_dialog_new (); + gtk_window_set_title (GTK_WINDOW (dlg), _("Export in progress")); + prg = gtk_progress_bar_new (); + sp_transientize (dlg); + gtk_window_set_resizable (GTK_WINDOW (dlg), FALSE); + g_object_set_data ((GObject *) base, "progress", prg); + fn = g_path_get_basename (filename); + text = g_strdup_printf ( _("Exporting %s (%d x %d)"), + fn, width, height); + g_free (fn); + gtk_progress_bar_set_text ((GtkProgressBar *) prg, text); + g_free (text); + gtk_progress_bar_set_orientation ( (GtkProgressBar *) prg, + GTK_PROGRESS_LEFT_TO_RIGHT); + gtk_box_pack_start ((GtkBox *) ((GtkDialog *) dlg)->vbox, + prg, FALSE, FALSE, 4 ); + btn = gtk_dialog_add_button ( GTK_DIALOG (dlg), + GTK_STOCK_CANCEL, + GTK_RESPONSE_CANCEL ); + + g_signal_connect ( (GObject *) dlg, "delete_event", + (GCallback) sp_export_progress_delete, base); + g_signal_connect ( (GObject *) btn, "clicked", + (GCallback) sp_export_progress_cancel, base); + gtk_window_set_modal ((GtkWindow *) dlg, TRUE); + gtk_widget_show_all (dlg); + + /* Do export */ + if (!sp_export_png_file (SP_DT_DOCUMENT (SP_ACTIVE_DESKTOP), filename, + x0, y0, x1, y1, width, height, + nv->pagecolor, + sp_export_progress_callback, base)) { + gchar * error; + gchar * safeFile = Inkscape::IO::sanitizeString(filename); + error = g_strdup_printf(_("Could not export to filename %s.\n"), safeFile); + sp_ui_error_dialog(error); + g_free(safeFile); + g_free(error); + } + + /* Reset the filename so that it can be changed again by changing + selections and all that */ + g_free(original_name); + original_name = g_strdup(filename); + gtk_object_set_data (GTK_OBJECT (base), "filename-modified", (gpointer)FALSE); + + gtk_widget_destroy (dlg); + g_object_set_data (G_OBJECT (base), "cancel", (gpointer) 0); + + /* Setup the values in the document */ + switch ((selection_type)(GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(base), "selection-type")))) { + case SELECTION_PAGE: + case SELECTION_DRAWING: { + SPDocument * doc = SP_ACTIVE_DOCUMENT; + Inkscape::XML::Node * repr = sp_document_repr_root(doc); + bool modified = FALSE; + const gchar * temp_string; + + bool saved = sp_document_get_undo_sensitive(doc); + sp_document_set_undo_sensitive(doc, FALSE); + + temp_string = repr->attribute("inkscape:export-filename"); + if (temp_string == NULL || strcmp(temp_string, filename)) { + repr->setAttribute("inkscape:export-filename", filename); + modified = TRUE; + } + temp_string = repr->attribute("inkscape:export-xdpi"); + if (temp_string == NULL || xdpi != atof(temp_string)) { + sp_repr_set_svg_double(repr, "inkscape:export-xdpi", xdpi); + modified = TRUE; + } + temp_string = repr->attribute("inkscape:export-ydpi"); + if (temp_string == NULL || xdpi != atof(temp_string)) { + sp_repr_set_svg_double(repr, "inkscape:export-ydpi", ydpi); + modified = TRUE; + } + + if (modified) + repr->setAttribute("sodipodi:modified", "TRUE"); + sp_document_set_undo_sensitive(doc, saved); + break; + } + case SELECTION_SELECTION: { + const GSList * reprlst; + SPDocument * doc = SP_ACTIVE_DOCUMENT; + bool modified = FALSE; + + bool saved = sp_document_get_undo_sensitive(doc); + sp_document_set_undo_sensitive(doc, FALSE); + reprlst = SP_DT_SELECTION(SP_ACTIVE_DESKTOP)->reprList(); + + for(; reprlst != NULL; reprlst = reprlst->next) { + Inkscape::XML::Node * repr = (Inkscape::XML::Node *)reprlst->data; + const gchar * temp_string; + + if (repr->attribute("id") == NULL || + !(g_strrstr(filename, repr->attribute("id")) != NULL && + (!SP_DOCUMENT_URI(SP_ACTIVE_DOCUMENT) || + strcmp(g_dirname(filename), g_dirname(SP_DOCUMENT_URI(SP_ACTIVE_DOCUMENT))) == 0))) { + temp_string = repr->attribute("inkscape:export-filename"); + if (temp_string == NULL || strcmp(temp_string, filename)) { + repr->setAttribute("inkscape:export-filename", filename); + modified = TRUE; + } + } + temp_string = repr->attribute("inkscape:export-xdpi"); + if (temp_string == NULL || xdpi != atof(temp_string)) { + sp_repr_set_svg_double(repr, "inkscape:export-xdpi", xdpi); + modified = TRUE; + } + temp_string = repr->attribute("inkscape:export-ydpi"); + if (temp_string == NULL || xdpi != atof(temp_string)) { + sp_repr_set_svg_double(repr, "inkscape:export-ydpi", ydpi); + modified = TRUE; + } + } + + if (modified) { + Inkscape::XML::Node * repr = sp_document_repr_root(doc); + repr->setAttribute("sodipodi:modified", "TRUE"); + } + + sp_document_set_undo_sensitive(doc, saved); + break; + } + default: + break; + } + + + return; +} // end of sp_export_export_clicked() + +/// Called when Browse button is clicked +static void +sp_export_browse_clicked (GtkButton *button, gpointer userdata) +{ + GtkWidget *fs, *fe; + const gchar *filename; + + fs = gtk_file_selection_new (_("Select a filename for exporting")); + fe = (GtkWidget *)g_object_get_data (G_OBJECT (dlg), "filename"); + + sp_transientize (fs); + + gtk_window_set_modal(GTK_WINDOW (fs), true); + + filename = gtk_entry_get_text (GTK_ENTRY (fe)); + + if (*filename == '\0') { + filename = homedir_path(NULL); + } + + gtk_file_selection_set_filename (GTK_FILE_SELECTION (fs), filename); + + g_signal_connect ( GTK_OBJECT (GTK_FILE_SELECTION (fs)->ok_button), + "clicked", + G_CALLBACK (sp_export_browse_store), + (gpointer) fs ); + + g_signal_connect_swapped ( GTK_OBJECT (GTK_FILE_SELECTION (fs)->ok_button), + "clicked", + G_CALLBACK (gtk_widget_destroy), + (gpointer) fs ); + + g_signal_connect_swapped ( GTK_OBJECT + (GTK_FILE_SELECTION (fs)->cancel_button), + "clicked", + G_CALLBACK (gtk_widget_destroy), + (gpointer) fs ); + + gtk_widget_show (fs); + + return; +} // end of sp_export_browse_clicked() + +/// Called when OK clicked in file dialog +static void +sp_export_browse_store (GtkButton *button, gpointer userdata) +{ + GtkWidget *fs = (GtkWidget *)userdata, *fe; + const gchar *file; + + fe = (GtkWidget *)g_object_get_data (G_OBJECT (dlg), "filename"); + + file = gtk_file_selection_get_filename (GTK_FILE_SELECTION (fs)); + gchar * utf8file = g_filename_to_utf8( file, -1, NULL, NULL, NULL ); + gtk_entry_set_text (GTK_ENTRY (fe), utf8file); + g_free(utf8file); + + g_object_set_data (G_OBJECT (dlg), "filename", fe); + + return; +} // end of sp_export_browse_store() + +// TODO: Move this to nr-rect-fns.h. +static bool +sp_export_bbox_equal(NR::Rect const &one, NR::Rect const &two) +{ + double const epsilon = pow(10.0, -EXPORT_COORD_PRECISION); + return ( + (fabs(one.min()[NR::X] - two.min()[NR::X]) < epsilon) && + (fabs(one.min()[NR::Y] - two.min()[NR::Y]) < epsilon) && + (fabs(one.max()[NR::X] - two.max()[NR::X]) < epsilon) && + (fabs(one.max()[NR::Y] - two.max()[NR::Y]) < epsilon) + ); +} + +/** + \brief This function is used to detect the current selection setting + based on the values in the x0, y0, x1 and y0 fields. + \param base The export dialog itself + + One of the most confusing parts of this function is why the array + is built at the beginning. What needs to happen here is that we + should always check the current selection to see if it is the valid + one. While this is a performance improvement it is also a usability + one during the cases where things like selections and drawings match + size. This way buttons change less 'randomly' (atleast in the eyes + of the user). To do this an array is built where the current selection + type is placed first, and then the others in an order from smallest + to largest (this can be configured by reshuffling \c test_order). + + All of the values in this function are rounded to two decimal places + because that is what is shown to the user. While everything is kept + more accurate than that, the user can't control more acurrate than + that, so for this to work for them - it needs to check on that level + of accuracy. + + \todo finish writing this up +*/ +static void +sp_export_detect_size(GtkObject * base) { + static const selection_type test_order[SELECTION_NUMBER_OF] = {SELECTION_SELECTION, SELECTION_DRAWING, SELECTION_PAGE, SELECTION_CUSTOM}; + selection_type this_test[SELECTION_NUMBER_OF + 1]; + selection_type key = SELECTION_NUMBER_OF; + + NR::Point x(sp_export_value_get_px (base, "x0"), + sp_export_value_get_px (base, "y0")); + NR::Point y(sp_export_value_get_px (base, "x1"), + sp_export_value_get_px (base, "y1")); + NR::Rect current_bbox(x, y); + //std::cout << "Current " << current_bbox; + + this_test[0] = (selection_type)(GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(base), "selection-type"))); + for (int i = 0; i < SELECTION_NUMBER_OF; i++) { + this_test[i + 1] = test_order[i]; + } + + for (int i = 0; + i < SELECTION_NUMBER_OF + 1 && + key == SELECTION_NUMBER_OF && + SP_ACTIVE_DESKTOP != NULL; + i++) { + // std::cout << "Looking at: " << selection_names[this_test[i]] << std::endl; + switch (this_test[i]) { + case SELECTION_SELECTION: + if ((SP_DT_SELECTION(SP_ACTIVE_DESKTOP))->isEmpty() == false) { + NR::Rect bbox = (SP_DT_SELECTION (SP_ACTIVE_DESKTOP))->bounds(); + + //std::cout << "Selection " << bbox; + if (sp_export_bbox_equal(bbox,current_bbox)) { + key = SELECTION_SELECTION; + } + } + break; + case SELECTION_DRAWING: { + SPDocument *doc = SP_DT_DOCUMENT (SP_ACTIVE_DESKTOP); + + NR::Rect bbox = sp_item_bbox_desktop (SP_ITEM (SP_DOCUMENT_ROOT (doc))); + + // std::cout << "Drawing " << bbox2; + if (sp_export_bbox_equal(bbox,current_bbox)) { + key = SELECTION_DRAWING; + } + break; + } + + case SELECTION_PAGE: { + SPDocument *doc; + + doc = SP_DT_DOCUMENT (SP_ACTIVE_DESKTOP); + + NR::Point x(0.0, 0.0); + NR::Point y(sp_document_width(doc), + sp_document_height(doc)); + NR::Rect bbox(x, y); + + // std::cout << "Page " << bbox; + if (sp_export_bbox_equal(bbox,current_bbox)) { + key = SELECTION_PAGE; + } + + break; + } + default: + break; + } + } + // std::cout << std::endl; + + if (key == SELECTION_NUMBER_OF) { + key = SELECTION_CUSTOM; + } + + /* We're now using a custom size, not a fixed one */ + /* printf("Detecting state: %s\n", selection_names[key]); */ + selection_type old = (selection_type)(GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(base), "selection-type"))); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(gtk_object_get_data(base, selection_names[old])), FALSE); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(gtk_object_get_data(base, selection_names[key])), TRUE); + gtk_object_set_data(GTK_OBJECT(base), "selection-type", (gpointer)key); + + return; +} /* sp_export_detect_size */ + +/// Called when area x0 value is changed +static void +sp_export_area_x_value_changed (GtkAdjustment *adj, GtkObject *base) +{ + float x0, x1, xdpi, width; + + if (gtk_object_get_data (base, "update")) + return; + + if (sp_unit_selector_update_test ((SPUnitSelector *)gtk_object_get_data + (base, "units"))) + { + return; + } + + gtk_object_set_data ( base, "update", GUINT_TO_POINTER (TRUE) ); + + x0 = sp_export_value_get_px (base, "x0"); + x1 = sp_export_value_get_px (base, "x1"); + xdpi = sp_export_value_get (base, "xdpi"); + + width = floor ((x1 - x0) * xdpi / DPI_BASE + 0.5); + + if (width < SP_EXPORT_MIN_SIZE) { + const gchar *key; + width = SP_EXPORT_MIN_SIZE; + key = (const gchar *)gtk_object_get_data (GTK_OBJECT (adj), "key"); + + if (!strcmp (key, "x0")) { + x1 = x0 + width * DPI_BASE / xdpi; + sp_export_value_set_px (base, "x1", x1); + } else { + x0 = x1 - width * DPI_BASE / xdpi; + sp_export_value_set_px (base, "x0", x0); + } + } + + sp_export_value_set_px (base, "width", x1 - x0); + sp_export_value_set (base, "bmwidth", width); + + sp_export_detect_size(base); + + gtk_object_set_data (base, "update", GUINT_TO_POINTER (FALSE)); + + return; +} // end of sp_export_area_x_value_changed() + +/// Called when area y0 value is changed. +static void +sp_export_area_y_value_changed (GtkAdjustment *adj, GtkObject *base) +{ + float y0, y1, ydpi, height; + + if (gtk_object_get_data (base, "update")) + return; + + if (sp_unit_selector_update_test ((SPUnitSelector *)gtk_object_get_data + (base, "units"))) + { + return; + } + + gtk_object_set_data (base, "update", GUINT_TO_POINTER (TRUE)); + + y0 = sp_export_value_get_px (base, "y0"); + y1 = sp_export_value_get_px (base, "y1"); + ydpi = sp_export_value_get (base, "ydpi"); + + height = floor ((y1 - y0) * ydpi / DPI_BASE + 0.5); + + if (height < SP_EXPORT_MIN_SIZE) { + const gchar *key; + height = SP_EXPORT_MIN_SIZE; + key = (const gchar *)gtk_object_get_data (GTK_OBJECT (adj), "key"); + if (!strcmp (key, "y0")) { + y1 = y0 + height * DPI_BASE / ydpi; + sp_export_value_set_px (base, "y1", y1); + } else { + y0 = y1 - height * DPI_BASE / ydpi; + sp_export_value_set_px (base, "y0", y0); + } + } + + sp_export_value_set_px (base, "height", y1 - y0); + sp_export_value_set (base, "bmheight", height); + + sp_export_detect_size(base); + + gtk_object_set_data (base, "update", GUINT_TO_POINTER (FALSE)); + + return; +} // end of sp_export_area_y_value_changed() + +/// Called when x1-x0 or area width is changed +static void +sp_export_area_width_value_changed (GtkAdjustment *adj, GtkObject *base) +{ + float x0, x1, xdpi, width, bmwidth; + + if (gtk_object_get_data (base, "update")) + return; + + if (sp_unit_selector_update_test ((SPUnitSelector *)gtk_object_get_data + (base, "units"))) { + return; + } + + gtk_object_set_data (base, "update", GUINT_TO_POINTER (TRUE)); + + x0 = sp_export_value_get_px (base, "x0"); + x1 = sp_export_value_get_px (base, "x1"); + xdpi = sp_export_value_get (base, "xdpi"); + width = sp_export_value_get_px (base, "width"); + bmwidth = floor (width * xdpi / DPI_BASE + 0.5); + + if (bmwidth < SP_EXPORT_MIN_SIZE) { + + bmwidth = SP_EXPORT_MIN_SIZE; + width = bmwidth * DPI_BASE / xdpi; + sp_export_value_set_px (base, "width", width); + } + + sp_export_value_set_px (base, "x1", x0 + width); + sp_export_value_set (base, "bmwidth", bmwidth); + + gtk_object_set_data (base, "update", GUINT_TO_POINTER (FALSE)); + + return; +} // end of sp_export_area_width_value_changed() + +/// Called when y1-y0 or area height is changed. +static void +sp_export_area_height_value_changed (GtkAdjustment *adj, GtkObject *base) +{ + + float y0, y1, ydpi, height, bmheight; + + if (gtk_object_get_data (base, "update")) + return; + + if (sp_unit_selector_update_test ((SPUnitSelector *)gtk_object_get_data + (base, "units"))) { + return; + } + + gtk_object_set_data (base, "update", GUINT_TO_POINTER (TRUE)); + + y0 = sp_export_value_get_px (base, "y0"); + y1 = sp_export_value_get_px (base, "y1"); + ydpi = sp_export_value_get (base, "ydpi"); + height = sp_export_value_get_px (base, "height"); + bmheight = floor (height * ydpi / DPI_BASE + 0.5); + + if (bmheight < SP_EXPORT_MIN_SIZE) { + bmheight = SP_EXPORT_MIN_SIZE; + height = bmheight * DPI_BASE / ydpi; + sp_export_value_set_px (base, "height", height); + } + + sp_export_value_set_px (base, "y1", y0 + height); + sp_export_value_set (base, "bmheight", bmheight); + + gtk_object_set_data (base, "update", GUINT_TO_POINTER (FALSE)); + + return; +} // end of sp_export_area_height_value_changed() + +/** + \brief A function to set the ydpi + \param base The export dialog + + This function grabs all of the y values and then figures out the + new bitmap size based on the changing dpi value. The dpi value is + gotten from the xdpi setting as these can not currently be independent. +*/ +static void +sp_export_set_image_y (GtkObject *base) +{ + float y0, y1, xdpi; + + y0 = sp_export_value_get_px (base, "y0"); + y1 = sp_export_value_get_px (base, "y1"); + xdpi = sp_export_value_get (base, "xdpi"); + + sp_export_value_set (base, "ydpi", xdpi); + sp_export_value_set (base, "bmheight", (y1 - y0) * xdpi / DPI_BASE); + + return; +} // end of sp_export_set_image_y() + +/// Called when pixel width is changed +static void +sp_export_bitmap_width_value_changed (GtkAdjustment *adj, GtkObject *base) +{ + float x0, x1, bmwidth, xdpi; + + if (gtk_object_get_data (base, "update")) + return; + + if (sp_unit_selector_update_test ((SPUnitSelector *)gtk_object_get_data + (base, "units"))) { + return; + } + + gtk_object_set_data (base, "update", GUINT_TO_POINTER (TRUE)); + + x0 = sp_export_value_get_px (base, "x0"); + x1 = sp_export_value_get_px (base, "x1"); + bmwidth = sp_export_value_get (base, "bmwidth"); + + if (bmwidth < SP_EXPORT_MIN_SIZE) { + bmwidth = SP_EXPORT_MIN_SIZE; + sp_export_value_set (base, "bmwidth", bmwidth); + } + + xdpi = bmwidth * DPI_BASE / (x1 - x0); + sp_export_value_set (base, "xdpi", xdpi); + + sp_export_set_image_y (base); + + gtk_object_set_data (base, "update", GUINT_TO_POINTER (FALSE)); + + return; +} // end of sp_export_bitmap_width_value_changed() + +/** + \brief A function to adjust the bitmap width when the xdpi value changes + \param adj The adjustment that was changed + \param base The export dialog itself + + The first thing this function checks is to see if we are doing an + update. If we are, this function just returns because there is another + instance of it that will handle everything for us. If there is a + units change, we also assume that everyone is being updated appropriately + and there is nothing for us to do. + + If we're the highest level function, we set the update flag, and + continue on our way. + + All of the values are grabbed using the \c sp_export_value_get functions + (call to the _pt ones for x0 and x1 but just standard for xdpi). The + xdpi value is saved in the preferences for the next time the dialog + is opened. (does the selection dpi need to be set here?) + + A check is done to to ensure that we aren't outputing an invalid width, + this is set by SP_EXPORT_MIN_SIZE. If that is the case the dpi is + changed to make it valid. + + After all of this the bitmap width is changed. + + We also change the ydpi. This is a temporary hack as these can not + currently be independent. This is likely to change in the future. +*/ +void +sp_export_xdpi_value_changed (GtkAdjustment *adj, GtkObject *base) +{ + float x0, x1, xdpi, bmwidth; + + if (gtk_object_get_data (base, "update")) + return; + + if (sp_unit_selector_update_test ((SPUnitSelector *)gtk_object_get_data + (base, "units"))) { + return; + } + + gtk_object_set_data (base, "update", GUINT_TO_POINTER (TRUE)); + + x0 = sp_export_value_get_px (base, "x0"); + x1 = sp_export_value_get_px (base, "x1"); + xdpi = sp_export_value_get (base, "xdpi"); + + // remember xdpi setting + prefs_set_double_attribute ("dialogs.export.defaultxdpi", "value", xdpi); + + bmwidth = (x1 - x0) * xdpi / DPI_BASE; + + if (bmwidth < SP_EXPORT_MIN_SIZE) { + bmwidth = SP_EXPORT_MIN_SIZE; + if (x1 != x0) + xdpi = bmwidth * DPI_BASE / (x1 - x0); + else + xdpi = DPI_BASE; + sp_export_value_set (base, "xdpi", xdpi); + } + + sp_export_value_set (base, "bmwidth", bmwidth); + + sp_export_set_image_y (base); + + gtk_object_set_data (base, "update", GUINT_TO_POINTER (FALSE)); + + return; +} // end of sp_export_xdpi_value_changed() + + +/** + \brief A function to change the area that is used for the exported + bitmap. + \param base This is the export dialog + \param x0 Horizontal upper left hand corner of the picture in points + \param y0 Vertical upper left hand corner of the picture in points + \param x1 Horizontal lower right hand corner of the picture in points + \param y1 Vertical lower right hand corner of the picture in points + + This function just calls \c sp_export_value_set_px for each of the + parameters that is passed in. This allows for setting them all in + one convient area. + + Update is set to suspend all of the other test running while all the + values are being set up. This allows for a performance increase, but + it also means that the wrong type won't be detected with only some of + the values set. After all the values are set everyone is told that + there has been an update. +*/ +static void +sp_export_set_area ( GtkObject *base, double x0, double y0, double x1, double y1 ) +{ + gtk_object_set_data ( base, "update", GUINT_TO_POINTER (TRUE) ); + sp_export_value_set_px (base, "x1", x1); + sp_export_value_set_px (base, "y1", y1); + sp_export_value_set_px (base, "x0", x0); + sp_export_value_set_px (base, "y0", y0); + gtk_object_set_data ( base, "update", GUINT_TO_POINTER (FALSE) ); + + sp_export_area_x_value_changed ((GtkAdjustment *)gtk_object_get_data (base, "x1"), base); + sp_export_area_y_value_changed ((GtkAdjustment *)gtk_object_get_data (base, "y1"), base); + + return; +} + +/** + \brief Sets the value of an adjustment + \param base The export dialog + \param key Which adjustment to set + \param val What value to set it to + + This function finds the adjustment using the data stored in the + export dialog. After finding the adjustment it then sets + the value of it. +*/ +static void +sp_export_value_set ( GtkObject *base, const gchar *key, double val ) +{ + GtkAdjustment *adj; + + adj = (GtkAdjustment *)gtk_object_get_data (base, key); + + gtk_adjustment_set_value (adj, val); +} + +/** + \brief A function to set a value using the units points + \param base The export dialog + \param key Which value should be set + \param val What the value should be in points + + This function first gets the adjustment for the key that is passed + in. It then figures out what units are currently being used in the + dialog. After doing all of that, it then converts the incoming + value and sets the adjustment. +*/ +static void +sp_export_value_set_px (GtkObject *base, const gchar *key, double val) +{ + const SPUnit *unit = sp_unit_selector_get_unit ((SPUnitSelector *)gtk_object_get_data (base, "units") ); + + sp_export_value_set (base, key, sp_pixels_get_units (val, *unit)); + + return; +} + +/** + \brief Get the value of an adjustment in the export dialog + \param base The export dialog + \param key Which adjustment is being looked for + \return The value in the specified adjustment + + This function gets the adjustment from the data field in the export + dialog. It then grabs the value from the adjustment. +*/ +static float +sp_export_value_get ( GtkObject *base, const gchar *key ) +{ + GtkAdjustment *adj; + + adj = (GtkAdjustment *)gtk_object_get_data (base, key); + + return adj->value; +} // end of sp_export_value_get() + +/** + \brief Grabs a value in the export dialog and converts the unit + to points + \param base The export dialog + \param key Which value should be returned + \return The value in the adjustment in points + + This function, at its most basic, is a call to \c sp_export_value_get + to get the value of the adjustment. It then finds the units that + are being used by looking at the "units" attribute of the export + dialog. Using that it converts the returned value into points. +*/ +static float +sp_export_value_get_px ( GtkObject *base, const gchar *key ) +{ + float value = sp_export_value_get(base, key); + const SPUnit *unit = sp_unit_selector_get_unit ((SPUnitSelector *)gtk_object_get_data (base, "units")); + + return sp_units_get_pixels (value, *unit); +} // end of sp_export_value_get_px() + +/** + \brief This function is called when the filename is changed by + anyone. It resets the virgin bit. + \param object Text entry box + \param data The export dialog + \return None + + This function gets called when the text area is modified. It is + looking for the case where the text area is modified from its + original value. In that case it sets the "filename-modified" bit + to TRUE. If the text dialog returns back to the original text, the + bit gets reset. This should stop simple mistakes. +*/ +static void +sp_export_filename_modified (GtkObject * object, gpointer data) +{ + GtkWidget * text_entry = (GtkWidget *)object; + GtkWidget * export_dialog = (GtkWidget *)data; + + if (!strcmp(original_name, gtk_entry_get_text(GTK_ENTRY(text_entry)))) { + gtk_object_set_data (GTK_OBJECT (export_dialog), "filename-modified", (gpointer)FALSE); +// printf("Modified: FALSE\n"); + } else { + gtk_object_set_data (GTK_OBJECT (export_dialog), "filename-modified", (gpointer)TRUE); +// printf("Modified: TRUE\n"); + } + + return; +} // end sp_export_filename_modified + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/dialogs/export.h b/src/dialogs/export.h new file mode 100644 index 000000000..4fb6ce2a4 --- /dev/null +++ b/src/dialogs/export.h @@ -0,0 +1,24 @@ +#ifndef SP_EXPORT_H +#define SP_EXPORT_H + +/** + * \brief text-edit + * + * Text editing and font changes + * + */ + +void sp_export_dialog (void); + +#endif + +/* + 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:textwidth=99 : diff --git a/src/dialogs/extensions.cpp b/src/dialogs/extensions.cpp new file mode 100644 index 000000000..36ec67744 --- /dev/null +++ b/src/dialogs/extensions.cpp @@ -0,0 +1,128 @@ +/* + * A simple dialog for previewing icon representation. + * + * Authors: + * Jon A. Cruz + * + * Copyright (C) 2005 Jon A. Cruz + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include //for GTK_RESPONSE* types +#include + +#include "extension/db.h" +#include "extensions.h" + + +namespace Inkscape { +namespace UI { +namespace Dialogs { + +using Inkscape::Extension::Extension; + +ExtensionsPanel* ExtensionsPanel::instance = 0; + + +ExtensionsPanel& ExtensionsPanel::getInstance() +{ + if ( !instance ) { + instance = new ExtensionsPanel(); + } + + instance->rescan(); + + return *instance; +} + + + +/** + * Constructor + */ +ExtensionsPanel::ExtensionsPanel() : + _showAll(false) +{ + Gtk::ScrolledWindow* scroller = new Gtk::ScrolledWindow(); + + _view.set_editable(false); + + scroller->add(_view); + add(*scroller); + + rescan(); + + show_all_children(); +} + +void ExtensionsPanel::set_full(bool full) +{ + if ( full != _showAll ) { + _showAll = full; + rescan(); + } +} + +void ExtensionsPanel::listCB( Inkscape::Extension::Extension * in_plug, gpointer in_data ) +{ + ExtensionsPanel * self = (ExtensionsPanel*)in_data; + + const char* stateStr; + Extension::state_t state = in_plug->get_state(); + switch ( state ) { + case Extension::STATE_LOADED: + { + stateStr = "loaded"; + } + break; + case Extension::STATE_UNLOADED: + { + stateStr = "unloaded"; + } + break; + case Extension::STATE_DEACTIVATED: + { + stateStr = "deactivated"; + } + break; + default: + stateStr = "unknown"; + } + + if ( self->_showAll || in_plug->deactivated() ) { +// gchar* line = g_strdup_printf( " extension %c %c %s |%s|%s|", +// (in_plug->loaded() ? 'X' : '-'), +// (in_plug->deactivated() ? 'X' : '-'), +// stateStr, in_plug->get_id(), +// in_plug->get_name() ); + gchar* line = g_strdup_printf( "%s %s\n \"%s\"", stateStr, in_plug->get_name(), in_plug->get_id() ); + + self->_view.get_buffer()->insert( self->_view.get_buffer()->end(), line ); + self->_view.get_buffer()->insert( self->_view.get_buffer()->end(), "\n" ); + //g_message( "%s", line ); + } + + + + return; +} + +void ExtensionsPanel::rescan() +{ + _view.get_buffer()->set_text("Extensions:\n"); +// g_message("/------------------"); + + Inkscape::Extension::db.foreach(listCB, (gpointer)this); + +// g_message("\\------------------"); +} + + + +} //namespace Dialogs +} //namespace UI +} //namespace Inkscape diff --git a/src/dialogs/extensions.h b/src/dialogs/extensions.h new file mode 100644 index 000000000..f4dbada9e --- /dev/null +++ b/src/dialogs/extensions.h @@ -0,0 +1,61 @@ + +#ifndef SEEN_EXTENSIONS_H +#define SEEN_EXTENSIONS_H +/* + * A simple dialog for previewing icon representation. + * + * Authors: + * Jon A. Cruz + * + * Copyright (C) 2005 The Inkscape Organization + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include +#include "ui/widget/panel.h" + +namespace Inkscape { + namespace Extension { + class Extension; + } +} + +namespace Inkscape { +namespace UI { +namespace Dialogs { + + +/** + * A panel that displays information about extensions. + */ +class ExtensionsPanel : public Inkscape::UI::Widget::Panel +{ +public: + ExtensionsPanel(); + + static ExtensionsPanel& getInstance(); + + void set_full(bool full); + +private: + ExtensionsPanel(ExtensionsPanel const &); // no copy + ExtensionsPanel &operator=(ExtensionsPanel const &); // no assign + + static ExtensionsPanel* instance; + + static void listCB( Inkscape::Extension::Extension * in_plug, gpointer in_data ); + + void rescan(); + + bool _showAll; + Gtk::TextView _view; +}; + +} //namespace Dialogs +} //namespace UI +} //namespace Inkscape + + + +#endif // SEEN_EXTENSIONS_H diff --git a/src/dialogs/filedialog-win32.cpp b/src/dialogs/filedialog-win32.cpp new file mode 100644 index 000000000..ca9ce5f6c --- /dev/null +++ b/src/dialogs/filedialog-win32.cpp @@ -0,0 +1,381 @@ + +#ifdef HAVE_CONFIG_H +# include +#endif +#include "filedialog.h" + +//#include "extension/internal/win32.h" + +#include + +#include + +#include +#include + +#define UNSAFE_SCRATCH_BUFFER_SIZE 4096 + +namespace Inkscape +{ +namespace UI +{ +namespace Dialogs +{ + +/*################################# +# U T I L I T Y +#################################*/ +static gboolean +win32_is_os_wide() +{ + static gboolean initialized = FALSE; + static gboolean is_wide = FALSE; + static OSVERSIONINFOA osver; + + if ( !initialized ) + { + BOOL result; + + initialized = TRUE; + + memset (&osver, 0, sizeof(OSVERSIONINFOA)); + osver.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA); + result = GetVersionExA (&osver); + if (result) + { + if (osver.dwPlatformId == VER_PLATFORM_WIN32_NT) + is_wide = TRUE; + } + // If we can't even call to get the version, fall back to ANSI API + } + + return is_wide; +} + +/*################################# +# F I L E O P E N +#################################*/ + +struct FileOpenNativeData_def { + char *dir; + FileDialogType fileTypes; + char *title; +}; + +FileOpenDialog::FileOpenDialog( + const char *dir, FileDialogType fileTypes, const char *title) { + + nativeData = (FileOpenNativeData *) + g_malloc(sizeof (FileOpenNativeData)); + if ( !nativeData ) { + // do we want exceptions? + return; + } + + if ( !dir ) + dir = ""; + nativeData->dir = g_strdup(dir); + nativeData->fileTypes = fileTypes; + nativeData->title = g_strdup(title); + + extension = NULL; + filename = NULL; +} + + + +FileOpenDialog::~FileOpenDialog() { + + //do any cleanup here + if ( nativeData ) { + g_free(nativeData->dir); + g_free(nativeData->title); + g_free(nativeData); + } + + if (filename) g_free(filename); + extension = NULL; +} + + + +bool +FileOpenDialog::show() { + + if ( !nativeData ) { + //error + return FALSE; + } + + gint retval = FALSE; + + + //Jon's UNICODE patch + if ( win32_is_os_wide() ) { + gunichar2 fnbufW[UNSAFE_SCRATCH_BUFFER_SIZE * sizeof(gunichar2)] = {0}; + gunichar2* dirW = + g_utf8_to_utf16( nativeData->dir, -1, NULL, NULL, NULL ); + gunichar2 *filterW = (gunichar2 *) L""; + if ( nativeData->fileTypes == SVG_TYPES ) + filterW = (gunichar2 *) L"SVG files\0*.svg;*.svgz\0All files\0*\0"; + else if ( nativeData->fileTypes == IMPORT_TYPES ) + filterW = (gunichar2 *) L"Image files\0*.svg;*.png;*.jpg;*.jpeg;*.bmp;*.gif;*.tiff;*.xpm\0" + L"SVG files\0*.svg\0" + L"All files\0*\0"; + gunichar2* titleW = + g_utf8_to_utf16( nativeData->title, -1, NULL, NULL, NULL ); + OPENFILENAMEW ofn = { + sizeof (OPENFILENAMEW), + NULL, // hwndOwner + NULL, // hInstance + (const WCHAR *)filterW, // lpstrFilter + NULL, // lpstrCustomFilter + 0, // nMaxCustFilter + 1, // nFilterIndex + (WCHAR *)fnbufW, // lpstrFile + sizeof (fnbufW) / sizeof(WCHAR), // nMaxFile + NULL, // lpstrFileTitle + 0, // nMaxFileTitle + (const WCHAR *)dirW, // lpstrInitialDir + (const WCHAR *)titleW, // lpstrTitle + OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY | OFN_NOCHANGEDIR, // Flags + 0, // nFileOffset + 0, // nFileExtension + NULL, // lpstrDefExt + 0, // lCustData + NULL, // lpfnHook + NULL // lpTemplateName + }; + + retval = GetOpenFileNameW (&ofn); + if (retval) + filename = g_utf16_to_utf8( fnbufW, -1, NULL, NULL, NULL ); + + g_free( dirW ); + g_free( titleW ); + + } else { + gchar *dir = nativeData->dir; + gchar *title = nativeData->title; + gchar fnbuf[UNSAFE_SCRATCH_BUFFER_SIZE] = {0}; + + gchar *filter = ""; + if ( nativeData->fileTypes == SVG_TYPES ) + filter = "SVG files\0*.svg;*.svgz\0All files\0*\0"; + else if ( nativeData->fileTypes == IMPORT_TYPES ) + filter = "Image files\0*.svg;*.png;*.jpg;*.jpeg;*.bmp;*.gif;*.tiff;*.xpm\0" + "SVG files\0*.svg\0" + "All files\0*\0"; + + OPENFILENAMEA ofn = { + sizeof (OPENFILENAMEA), + NULL, // hwndOwner + NULL, // hInstance + (const CHAR *)filter, // lpstrFilter + NULL, // lpstrCustomFilter + 0, // nMaxCustFilter + 1, // nFilterIndex + fnbuf, // lpstrFile + sizeof (fnbuf), // nMaxFile + NULL, // lpstrFileTitle + 0, // nMaxFileTitle + (const CHAR *)dir, // lpstrInitialDir + (const CHAR *)title, // lpstrTitle + OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY | OFN_NOCHANGEDIR, // Flags + 0, // nFileOffset + 0, // nFileExtension + NULL, // lpstrDefExt + 0, // lCustData + NULL, // lpfnHook + NULL // lpTemplateName + }; + + retval = GetOpenFileNameA (&ofn); + if ( retval ) { + filename = g_strdup( fnbuf ); + /* ### We need to try something like this instead: + GError *err = NULL; + filename = g_filename_to_utf8(fnbuf, -1, NULL, NULL, &err); + if ( !filename && err ) { + g_warning("Charset conversion in show()[%d]%s\n", + err->code, err->message); + } + */ + } + } + + if ( !retval ) { + //int errcode = CommDlgExtendedError(); + return FALSE; + } + + return TRUE; + +} + + + +/*################################# +# F I L E S A V E +#################################*/ + +struct FileSaveNativeData_def { + OPENFILENAME ofn; + gchar filter[UNSAFE_SCRATCH_BUFFER_SIZE]; + gchar fnbuf[4096]; +}; + + + +FileSaveDialog::FileSaveDialog( + const char *dir, FileDialogType fileTypes, const char *title, const char * default_key) { + + nativeData = (FileSaveNativeData *) + g_malloc(sizeof (FileSaveNativeData)); + if ( !nativeData ) { + //do we want exceptions? + return; + } + + extension = NULL; + filename = NULL; + + int default_item = 0; + + GSList* extension_list = Inkscape::Extension::db.get_output_list(); + g_assert (extension_list != NULL); + + /* Make up the filter string for the save dialogue using the list + ** of available output types. + */ + + gchar *p = nativeData->filter; + int N = UNSAFE_SCRATCH_BUFFER_SIZE; + + int n = 1; + for (GSList* i = g_slist_next (extension_list); i != NULL; i = g_slist_next(i)) { + + Inkscape::Extension::DB::IOExtensionDescription* d = + reinterpret_cast(i->data); + + if (!d->sensitive) + continue; + + int w = snprintf (p, N, "%s", d->name); + N -= w + 1; + p += w + 1; + + w = snprintf (p, N, "*"); + N -= w + 1; + p += w + 1; + + g_assert (N >= 0); + + /* Look to see if this extension is the default */ + if (default_key && + d->extension->get_id() && + strcmp (default_key, d->extension->get_id()) == 0) { + default_item = n; + extension = d->extension; + } + + n++; + } + + *p = '\0'; + + nativeData->fnbuf[0] = '\0'; + + if (dir) { + /* We must check that dir is not something like + ** c:\foo\ (ie with a trailing \). If it is, + ** GetSaveFileName will give an error. + */ + int n = strlen(dir); + if (n > 0 && dir[n - 1] != '\\') { + strncpy(nativeData->fnbuf, dir, sizeof(nativeData->fnbuf)); + } + } + + OPENFILENAME ofn = { + sizeof (OPENFILENAME), + NULL, // hwndOwner + NULL, // hInstance + nativeData->filter, // lpstrFilter + NULL, // lpstrCustomFilter + 0, // nMaxCustFilter + default_item, // nFilterIndex + nativeData->fnbuf, // lpstrFile + sizeof (nativeData->fnbuf), // nMaxFile + NULL, // lpstrFileTitle + 0, // nMaxFileTitle + (const CHAR *)dir, // lpstrInitialDir + (const CHAR *)title, // lpstrTitle + OFN_HIDEREADONLY | OFN_NOCHANGEDIR, // Flags + 0, // nFileOffset + 0, // nFileExtension + NULL, // lpstrDefExt + 0, // lCustData + NULL, // lpfnHook + NULL // lpTemplateName + }; + + nativeData->ofn = ofn; +} + +FileSaveDialog::~FileSaveDialog() { + + //do any cleanup here + g_free(nativeData); + if (filename) g_free(filename); + extension = NULL; +} + +bool +FileSaveDialog::show() { + + if (!nativeData) + return FALSE; + int retval = GetSaveFileName (&(nativeData->ofn)); + if (!retval) { + //int errcode = CommDlgExtendedError(); + return FALSE; + } + + GSList* extension_list = Inkscape::Extension::db.get_output_list(); + g_assert (extension_list != NULL); + + /* Work out which extension corresponds to the user's choice of + ** file type. + */ + int n = nativeData->ofn.nFilterIndex - 1; + GSList* i = g_slist_next (extension_list); + + while (n > 0 && i) { + n--; + i = g_slist_next(i); + } + + Inkscape::Extension::DB::IOExtensionDescription* d = + reinterpret_cast(i->data); + + extension = d->extension; + + filename = g_strdup (nativeData->fnbuf); + return TRUE; +} + + + + + + + + +} //namespace Dialogs +} //namespace UI +} //namespace Inkscape + + + + diff --git a/src/dialogs/filedialog.cpp b/src/dialogs/filedialog.cpp new file mode 100644 index 000000000..bf9eaceb5 --- /dev/null +++ b/src/dialogs/filedialog.cpp @@ -0,0 +1,1439 @@ +/* + * Implementation of the file dialog interfaces defined in filedialog.h + * + * Authors: + * Bob Jamison + * Other dudes from The Inkscape Organization + * + * Copyright (C) 2004 The Inkscape Organization + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + + + +//Temporary ugly hack +//Remove these after the get_filter() calls in +//show() on both classes are fixed +#include + +//Another hack +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "prefs-utils.h" +#include +#include +#include +#include +#include "inkscape.h" +#include "svg-view-widget.h" +#include "filedialog.h" + +#undef INK_DUMP_FILENAME_CONV + +#ifdef INK_DUMP_FILENAME_CONV +void dump_str( const gchar* str, const gchar* prefix ); +void dump_ustr( const Glib::ustring& ustr ); +#endif + +namespace Inkscape { +namespace UI { +namespace Dialogs { + +void FileDialogExtensionToPattern (Glib::ustring &pattern, gchar * in_file_extension); + +/*######################################################################### +### SVG Preview Widget +#########################################################################*/ +/** + * Simple class for displaying an SVG file in the "preview widget." + * Currently, this is just a wrapper of the sp_svg_view Gtk widget. + * Hopefully we will eventually replace with a pure Gtkmm widget. + */ +class SVGPreview : public Gtk::VBox +{ +public: + SVGPreview(); + ~SVGPreview(); + + bool setDocument(SPDocument *doc); + + bool setFileName(Glib::ustring &fileName); + + bool setFromMem(char const *xmlBuffer); + + bool set(Glib::ustring &fileName, int dialogType); + + bool setURI(URI &uri); + + /** + * Show image embedded in SVG + */ + void showImage(Glib::ustring &fileName); + + /** + * Show the "No preview" image + */ + void showNoPreview(); + + /** + * Show the "Too large" image + */ + void showTooLarge(long fileLength); + +private: + /** + * The svg document we are currently showing + */ + SPDocument *document; + + /** + * The sp_svg_view widget + */ + GtkWidget *viewerGtk; + + /** + * are we currently showing the "no preview" image? + */ + bool showingNoPreview; + +}; + + +bool SVGPreview::setDocument(SPDocument *doc) +{ + if (document) + sp_document_unref(document); + + sp_document_ref(doc); + document = doc; + + //This should remove it from the box, and free resources + if (viewerGtk) { + gtk_widget_destroy(viewerGtk); + } + + viewerGtk = sp_svg_view_widget_new(doc); + GtkWidget *vbox = (GtkWidget *)gobj(); + gtk_box_pack_start(GTK_BOX(vbox), viewerGtk, TRUE, TRUE, 0); + gtk_widget_show(viewerGtk); + + return true; +} + +bool SVGPreview::setFileName(Glib::ustring &theFileName) +{ + Glib::ustring fileName = theFileName; + + fileName = Glib::filename_to_utf8(fileName); + + SPDocument *doc = sp_document_new (fileName.c_str(), 0); + if (!doc) { + g_warning("SVGView: error loading document '%s'\n", fileName.c_str()); + return false; + } + + setDocument(doc); + + sp_document_unref(doc); + + return true; +} + + + +bool SVGPreview::setFromMem(char const *xmlBuffer) +{ + if (!xmlBuffer) + return false; + + gint len = (gint)strlen(xmlBuffer); + SPDocument *doc = sp_document_new_from_mem(xmlBuffer, len, 0); + if (!doc) { + g_warning("SVGView: error loading buffer '%s'\n",xmlBuffer); + return false; + } + + setDocument(doc); + + sp_document_unref(doc); + + return true; +} + + + +void SVGPreview::showImage(Glib::ustring &theFileName) +{ + Glib::ustring fileName = theFileName; + + + /*##################################### + # LET'S HAVE SOME FUN WITH SVG! + # Instead of just loading an image, why + # don't we make a lovely little svg and + # display it nicely? + #####################################*/ + + //Arbitrary size of svg doc -- rather 'portrait' shaped + gint previewWidth = 400; + gint previewHeight = 600; + + //Get some image info. Smart pointer does not need to be deleted + Glib::RefPtr img = Gdk::Pixbuf::create_from_file(fileName); + gint imgWidth = img->get_width(); + gint imgHeight = img->get_height(); + + //Find the minimum scale to fit the image inside the preview area + double scaleFactorX = (0.9 *(double)previewWidth) / ((double)imgWidth); + double scaleFactorY = (0.9 *(double)previewHeight) / ((double)imgHeight); + double scaleFactor = scaleFactorX; + if (scaleFactorX > scaleFactorY) + scaleFactor = scaleFactorY; + + //Now get the resized values + gint scaledImgWidth = (int) (scaleFactor * (double)imgWidth); + gint scaledImgHeight = (int) (scaleFactor * (double)imgHeight); + + //center the image on the area + gint imgX = (previewWidth - scaledImgWidth) / 2; + gint imgY = (previewHeight - scaledImgHeight) / 2; + + //wrap a rectangle around the image + gint rectX = imgX-1; + gint rectY = imgY-1; + gint rectWidth = scaledImgWidth +2; + gint rectHeight = scaledImgHeight+2; + + //Our template. Modify to taste + gchar const *xformat = + "\n" + "\n" + "\n" + "\n" + "\n" + "%d x %d\n" + "\n\n"; + + //if (!Glib::get_charset()) //If we are not utf8 + fileName = Glib::filename_to_utf8(fileName); + + //Fill in the template + /* FIXME: Do proper XML quoting for fileName. */ + gchar *xmlBuffer = g_strdup_printf(xformat, + previewWidth, previewHeight, + imgX, imgY, scaledImgWidth, scaledImgHeight, + fileName.c_str(), + rectX, rectY, rectWidth, rectHeight, + imgWidth, imgHeight); + + //g_message("%s\n", xmlBuffer); + + //now show it! + setFromMem(xmlBuffer); + g_free(xmlBuffer); +} + + + +void SVGPreview::showNoPreview() +{ + //Are we already showing it? + if (showingNoPreview) + return; + + //Arbitrary size of svg doc -- rather 'portrait' shaped + gint previewWidth = 300; + gint previewHeight = 600; + + //Our template. Modify to taste + gchar const *xformat = + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + " \n" + "%s\n" + "\n\n"; + + //Fill in the template + gchar *xmlBuffer = g_strdup_printf(xformat, + previewWidth, previewHeight, _("No preview")); + + //g_message("%s\n", xmlBuffer); + + //now show it! + setFromMem(xmlBuffer); + g_free(xmlBuffer); + showingNoPreview = true; + +} + +void SVGPreview::showTooLarge(long fileLength) +{ + + //Arbitrary size of svg doc -- rather 'portrait' shaped + gint previewWidth = 300; + gint previewHeight = 600; + + //Our template. Modify to taste + gchar const *xformat = + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "%5.1f MB\n" + "%s\n" + "\n\n"; + + //Fill in the template + double floatFileLength = ((double)fileLength) / 1048576.0; + //printf("%ld %f\n", fileLength, floatFileLength); + gchar *xmlBuffer = g_strdup_printf(xformat, + previewWidth, previewHeight, floatFileLength, + _("too large for preview")); + + //g_message("%s\n", xmlBuffer); + + //now show it! + setFromMem(xmlBuffer); + g_free(xmlBuffer); + +} + +static bool +hasSuffix(Glib::ustring &str, Glib::ustring &ext) +{ + int strLen = str.length(); + int extLen = ext.length(); + if (extLen > strLen) + { + return false; + } + int strpos = strLen-1; + for (int extpos = extLen-1 ; extpos>=0 ; extpos--, strpos--) + { + Glib::ustring::value_type ch = str[strpos]; + if (ch != ext[extpos]) + { + if ( ((ch & 0xff80) != 0) || + static_cast( g_ascii_tolower( static_cast(0x07f & ch) ) ) != ext[extpos] ) + { + return false; + } + } + } + return true; +} + + +/** + * Return true if the image is loadable by Gdk, else false + */ +static bool +isValidImageFile(Glib::ustring &fileName) +{ + std::vectorformats = Gdk::Pixbuf::get_formats(); + for (unsigned int i=0; iextensions = format.get_extensions(); + for (unsigned int j=0; j 0x150000L) + { + showingNoPreview = false; + showTooLarge(fileLen); + return FALSE; + } + } + + Glib::ustring svg = ".svg"; + Glib::ustring svgz = ".svgz"; + + if ((dialogType == SVG_TYPES || dialogType == IMPORT_TYPES) && + (hasSuffix(fileName, svg) || hasSuffix(fileName, svgz) ) + ) + { + bool retval = setFileName(fileName); + showingNoPreview = false; + return retval; + } + else if (isValidImageFile(fileName)) + { + showImage(fileName); + showingNoPreview = false; + return true; + } + else + { + showNoPreview(); + return false; + } +} + + +SVGPreview::SVGPreview() +{ + if (!INKSCAPE) + inkscape_application_init("",false); + document = NULL; + viewerGtk = NULL; + set_size_request(150,150); + showingNoPreview = false; +} + +SVGPreview::~SVGPreview() +{ + +} + + + + + +/*######################################################################### +### F I L E O P E N +#########################################################################*/ + +/** + * Our implementation class for the FileOpenDialog interface.. + */ +class FileOpenDialogImpl : public FileOpenDialog, public Gtk::FileChooserDialog +{ +public: + FileOpenDialogImpl(char const *dir, + FileDialogType fileTypes, + char const *title); + + virtual ~FileOpenDialogImpl(); + + bool show(); + + Inkscape::Extension::Extension *getSelectionType(); + + gchar *getFilename(); + + Glib::SListHandle getFilenames (); +protected: + + + +private: + + + /** + * What type of 'open' are we? (open, import, place, etc) + */ + FileDialogType dialogType; + + /** + * Our svg preview widget + */ + SVGPreview svgPreview; + + /** + * Callback for seeing if the preview needs to be drawn + */ + void updatePreviewCallback(); + + /** + * Fix to allow the user to type the file name + */ + Gtk::Entry fileNameEntry; + + /** + * Create a filter menu for this type of dialog + */ + void createFilterMenu(); + + /** + * Callback for user input into fileNameEntry + */ + void fileNameEntryChangedCallback(); + + /** + * Callback for user changing which item is selected on the list + */ + void fileSelectedCallback(); + + + /** + * Filter name->extension lookup + */ + std::map extensionMap; + + /** + * The extension to use to write this file + */ + Inkscape::Extension::Extension *extension; + + /** + * Filename that was given + */ + Glib::ustring myFilename; + +}; + + + + + +/** + * Callback for checking if the preview needs to be redrawn + */ +void FileOpenDialogImpl::updatePreviewCallback() +{ + Glib::ustring fileName = get_preview_filename(); + + if (fileName.length() < 1) + return; + + svgPreview.set(fileName, dialogType); +} + + + + + +/** + * Callback for fileNameEntry widget + */ +void FileOpenDialogImpl::fileNameEntryChangedCallback() +{ + Glib::ustring fileName = fileNameEntry.get_text(); + + // TODO remove this leak + fileName = Glib::filename_from_utf8(fileName); + + //g_message("User hit return. Text is '%s'\n", fName.c_str()); + + if (!Glib::path_is_absolute(fileName)) { + //try appending to the current path + // not this way: fileName = get_current_folder() + "/" + fName; + std::vector pathSegments; + pathSegments.push_back( get_current_folder() ); + pathSegments.push_back( fileName ); + fileName = Glib::build_filename(pathSegments); + } + + //g_message("path:'%s'\n", fName.c_str()); + + if (Glib::file_test(fileName, Glib::FILE_TEST_IS_DIR)) { + set_current_folder(fileName); + } else if (Glib::file_test(fileName, Glib::FILE_TEST_IS_REGULAR)) { + //dialog with either (1) select a regular file or (2) cd to dir + //simulate an 'OK' + set_filename(fileName); + response(Gtk::RESPONSE_OK); + } +} + + + + + +/** + * Callback for fileNameEntry widget + */ +void FileOpenDialogImpl::fileSelectedCallback() +{ + Glib::ustring fileName = get_filename(); + if (!Glib::get_charset()) //If we are not utf8 + fileName = Glib::filename_to_utf8(fileName); + //g_message("User selected '%s'\n", + // filename().c_str()); + +#ifdef INK_DUMP_FILENAME_CONV + ::dump_ustr( get_filename() ); +#endif + fileNameEntry.set_text(fileName); +} + + + + +void FileOpenDialogImpl::createFilterMenu() +{ + //patterns added dynamically below + Gtk::FileFilter allImageFilter; + allImageFilter.set_name(_("All Images")); + extensionMap[Glib::ustring(_("All Images"))]=NULL; + add_filter(allImageFilter); + + Gtk::FileFilter allFilter; + allFilter.set_name(_("All Files")); + extensionMap[Glib::ustring(_("All Files"))]=NULL; + allFilter.add_pattern("*"); + add_filter(allFilter); + + //patterns added dynamically below + Gtk::FileFilter allInkscapeFilter; + allInkscapeFilter.set_name(_("All Inkscape Files")); + extensionMap[Glib::ustring(_("All Inkscape Files"))]=NULL; + add_filter(allInkscapeFilter); + + Inkscape::Extension::DB::InputList extension_list; + Inkscape::Extension::db.get_input_list(extension_list); + + for (Inkscape::Extension::DB::InputList::iterator current_item = extension_list.begin(); + current_item != extension_list.end(); current_item++) + { + Inkscape::Extension::Input * imod = *current_item; + + // FIXME: would be nice to grey them out instead of not listing them + if (imod->deactivated()) continue; + + Glib::ustring upattern("*"); + FileDialogExtensionToPattern (upattern, imod->get_extension()); + + Gtk::FileFilter filter; + Glib::ustring uname(_(imod->get_filetypename())); + filter.set_name(uname); + filter.add_pattern(upattern); + add_filter(filter); + extensionMap[uname] = imod; + + //g_message("ext %s:%s '%s'\n", ioext->name, ioext->mimetype, upattern.c_str()); + allInkscapeFilter.add_pattern(upattern); + if ( strncmp("image", imod->get_mimetype(), 5)==0 ) + allImageFilter.add_pattern(upattern); + } + + return; +} + + + +/** + * Constructor. Not called directly. Use the factory. + */ +FileOpenDialogImpl::FileOpenDialogImpl(char const *dir, + FileDialogType fileTypes, + char const *title) : + Gtk::FileChooserDialog(Glib::ustring(title)) +{ + + + /* One file at a time */ + /* And also Multiple Files */ + set_select_multiple(true); + + /* Initalize to Autodetect */ + extension = NULL; + /* No filename to start out with */ + myFilename = ""; + + /* Set our dialog type (open, import, etc...)*/ + dialogType = fileTypes; + + + /* Set the pwd and/or the filename */ + if (dir != NULL) + { + Glib::ustring udir(dir); + Glib::ustring::size_type len = udir.length(); + // leaving a trailing backslash on the directory name leads to the infamous + // double-directory bug on win32 + if (len != 0 && udir[len - 1] == '\\') udir.erase(len - 1); + set_current_folder(udir.c_str()); + } + + //###### Add the file types menu + createFilterMenu(); + + //###### Add a preview widget + set_preview_widget(svgPreview); + set_preview_widget_active(true); + set_use_preview_label (false); + + //Catch selection-changed events, so we can adjust the text widget + signal_update_preview().connect( + sigc::mem_fun(*this, &FileOpenDialogImpl::updatePreviewCallback) ); + + + //###### Add a text entry bar, and tie it to file chooser events + fileNameEntry.set_text(get_current_folder()); + set_extra_widget(fileNameEntry); + fileNameEntry.grab_focus(); + + //Catch when user hits [return] on the text field + fileNameEntry.signal_activate().connect( + sigc::mem_fun(*this, &FileOpenDialogImpl::fileNameEntryChangedCallback) ); + + //Catch selection-changed events, so we can adjust the text widget + signal_selection_changed().connect( + sigc::mem_fun(*this, &FileOpenDialogImpl::fileSelectedCallback) ); + + add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); + add_button(Gtk::Stock::OPEN, Gtk::RESPONSE_OK); + +} + + + + + +/** + * Public factory. Called by file.cpp, among others. + */ +FileOpenDialog *FileOpenDialog::create(char const *path, + FileDialogType fileTypes, + char const *title) +{ + FileOpenDialog *dialog = new FileOpenDialogImpl(path, fileTypes, title); + return dialog; +} + + + + +/** + * Destructor + */ +FileOpenDialogImpl::~FileOpenDialogImpl() +{ + +} + + +/** + * Show this dialog modally. Return true if user hits [OK] + */ +bool +FileOpenDialogImpl::show() +{ + set_current_folder(get_current_folder()); //hack to force initial dir listing + set_modal (TRUE); //Window + sp_transientize((GtkWidget *)gobj()); //Make transient + gint b = run(); //Dialog + hide(); + + if (b == Gtk::RESPONSE_OK) + { + //This is a hack, to avoid the warning messages that + //Gtk::FileChooser::get_filter() returns + //should be: Gtk::FileFilter *filter = get_filter(); + GtkFileChooser *gtkFileChooser = Gtk::FileChooser::gobj(); + GtkFileFilter *filter = gtk_file_chooser_get_filter(gtkFileChooser); + if (filter) + { + //Get which extension was chosen, if any + extension = extensionMap[gtk_file_filter_get_name(filter)]; + } + myFilename = get_filename(); + return TRUE; + } + else + { + return FALSE; + } +} + + + + +/** + * Get the file extension type that was selected by the user. Valid after an [OK] + */ +Inkscape::Extension::Extension * +FileOpenDialogImpl::getSelectionType() +{ + return extension; +} + + +/** + * Get the file name chosen by the user. Valid after an [OK] + */ +gchar * +FileOpenDialogImpl::getFilename (void) +{ + return g_strdup(myFilename.c_str()); +} + + +/** + * To Get Multiple filenames selected at-once. + */ +Glib::SListHandleFileOpenDialogImpl::getFilenames() +{ + return get_filenames(); +} + + + + + + +/*######################################################################### +# F I L E S A V E +#########################################################################*/ + +class FileType +{ + public: + FileType() {} + ~FileType() {} + Glib::ustring name; + Glib::ustring pattern; + Inkscape::Extension::Extension *extension; +}; + +/** + * Our implementation of the FileSaveDialog interface. + */ +class FileSaveDialogImpl : public FileSaveDialog, public Gtk::FileChooserDialog +{ + +public: + FileSaveDialogImpl(char const *dir, + FileDialogType fileTypes, + char const *title, + char const *default_key); + + virtual ~FileSaveDialogImpl(); + + bool show(); + + Inkscape::Extension::Extension *getSelectionType(); + + gchar *getFilename(); + + +private: + + /** + * What type of 'open' are we? (save, export, etc) + */ + FileDialogType dialogType; + + /** + * Our svg preview widget + */ + SVGPreview svgPreview; + + /** + * Fix to allow the user to type the file name + */ + Gtk::Entry *fileNameEntry; + + /** + * Callback for seeing if the preview needs to be drawn + */ + void updatePreviewCallback(); + + + + /** + * Allow the specification of the output file type + */ + Gtk::HBox fileTypeBox; + + /** + * Allow the specification of the output file type + */ + Gtk::ComboBoxText fileTypeComboBox; + + + /** + * Data mirror of the combo box + */ + std::vector fileTypes; + + //# Child widgets + Gtk::CheckButton fileTypeCheckbox; + + + /** + * Callback for user input into fileNameEntry + */ + void fileTypeChangedCallback(); + + /** + * Create a filter menu for this type of dialog + */ + void createFileTypeMenu(); + + + bool append_extension; + + /** + * The extension to use to write this file + */ + Inkscape::Extension::Extension *extension; + + /** + * Callback for user input into fileNameEntry + */ + void fileNameEntryChangedCallback(); + + /** + * Filename that was given + */ + Glib::ustring myFilename; +}; + + + + + + +/** + * Callback for checking if the preview needs to be redrawn + */ +void FileSaveDialogImpl::updatePreviewCallback() +{ + Glib::ustring fileName = get_preview_filename(); + if (!fileName.c_str()) + return; + bool retval = svgPreview.set(fileName, dialogType); + set_preview_widget_active(retval); +} + + + +/** + * Callback for fileNameEntry widget + */ +void FileSaveDialogImpl::fileNameEntryChangedCallback() +{ + if (!fileNameEntry) + return; + + Glib::ustring fileName = fileNameEntry->get_text(); + if (!Glib::get_charset()) //If we are not utf8 + fileName = Glib::filename_to_utf8(fileName); + + //g_message("User hit return. Text is '%s'\n", fileName.c_str()); + + if (!Glib::path_is_absolute(fileName)) { + //try appending to the current path + // not this way: fileName = get_current_folder() + "/" + fileName; + std::vector pathSegments; + pathSegments.push_back( get_current_folder() ); + pathSegments.push_back( fileName ); + fileName = Glib::build_filename(pathSegments); + } + + //g_message("path:'%s'\n", fileName.c_str()); + + if (Glib::file_test(fileName, Glib::FILE_TEST_IS_DIR)) { + set_current_folder(fileName); + } else if (/*Glib::file_test(fileName, Glib::FILE_TEST_IS_REGULAR)*/1) { + //dialog with either (1) select a regular file or (2) cd to dir + //simulate an 'OK' + set_filename(fileName); + response(Gtk::RESPONSE_OK); + } +} + + + +/** + * Callback for fileNameEntry widget + */ +void FileSaveDialogImpl::fileTypeChangedCallback() +{ + int sel = fileTypeComboBox.get_active_row_number(); + if (sel<0 || sel >= (int)fileTypes.size()) + return; + FileType type = fileTypes[sel]; + //g_message("selected: %s\n", type.name.c_str()); + Gtk::FileFilter filter; + filter.add_pattern(type.pattern); + set_filter(filter); +} + + + +void FileSaveDialogImpl::createFileTypeMenu() +{ + Inkscape::Extension::DB::OutputList extension_list; + Inkscape::Extension::db.get_output_list(extension_list); + + for (Inkscape::Extension::DB::OutputList::iterator current_item = extension_list.begin(); + current_item != extension_list.end(); current_item++) + { + Inkscape::Extension::Output * omod = *current_item; + + // FIXME: would be nice to grey them out instead of not listing them + if (omod->deactivated()) continue; + + FileType type; + type.name = (_(omod->get_filetypename())); + type.pattern = "*"; + FileDialogExtensionToPattern (type.pattern, omod->get_extension()); + type.extension= omod; + fileTypeComboBox.append_text(type.name); + fileTypes.push_back(type); + } + + //#Let user choose + FileType guessType; + guessType.name = _("Guess from extension"); + guessType.pattern = "*"; + guessType.extension = NULL; + fileTypeComboBox.append_text(guessType.name); + fileTypes.push_back(guessType); + + + fileTypeComboBox.set_active(0); + fileTypeChangedCallback(); //call at least once to set the filter +} + + +void findEntryWidgets(Gtk::Container *parent, std::vector &result) +{ + if (!parent) + return; + std::vector children = parent->get_children(); + for (unsigned int i=0; igobj(); + if (GTK_IS_ENTRY(wid)) + result.push_back((Gtk::Entry *)child); + else if (GTK_IS_CONTAINER(wid)) + findEntryWidgets((Gtk::Container *)child, result); + } + +} + +void findExpanderWidgets(Gtk::Container *parent, std::vector &result) +{ + if (!parent) + return; + std::vector children = parent->get_children(); + for (unsigned int i=0; igobj(); + if (GTK_IS_EXPANDER(wid)) + result.push_back((Gtk::Expander *)child); + else if (GTK_IS_CONTAINER(wid)) + findExpanderWidgets((Gtk::Container *)child, result); + } + +} + + +/** + * Constructor + */ +FileSaveDialogImpl::FileSaveDialogImpl(char const *dir, + FileDialogType fileTypes, + char const *title, + char const *default_key) : + Gtk::FileChooserDialog(Glib::ustring(title), + Gtk::FILE_CHOOSER_ACTION_SAVE) +{ + append_extension = (bool)prefs_get_int_attribute("dialogs.save_as", "append_extension", 1); + + /* One file at a time */ + set_select_multiple(false); + + /* Initalize to Autodetect */ + extension = NULL; + /* No filename to start out with */ + myFilename = ""; + + /* Set our dialog type (save, export, etc...)*/ + dialogType = fileTypes; + + /* Set the pwd and/or the filename */ + if (dir != NULL) + { + Glib::ustring udir(dir); + Glib::ustring::size_type len = udir.length(); + // leaving a trailing backslash on the directory name leads to the infamous + // double-directory bug on win32 + if (len != 0 && udir[len - 1] == '\\') udir.erase(len - 1); + set_current_folder(udir.c_str()); + } + + //###### Add the file types menu + //createFilterMenu(); + + //###### Do we want the .xxx extension automatically added? + fileTypeCheckbox.set_label(Glib::ustring(_("Append filename extension automatically"))); + fileTypeCheckbox.set_active(append_extension); + + fileTypeBox.pack_start(fileTypeCheckbox); + createFileTypeMenu(); + fileTypeComboBox.set_size_request(200,40); + fileTypeComboBox.signal_changed().connect( + sigc::mem_fun(*this, &FileSaveDialogImpl::fileTypeChangedCallback) ); + + fileTypeBox.pack_start(fileTypeComboBox); + + set_extra_widget(fileTypeBox); + //get_vbox()->pack_start(fileTypeBox, false, false, 0); + //get_vbox()->reorder_child(fileTypeBox, 2); + + //###### Add a preview widget + set_preview_widget(svgPreview); + set_preview_widget_active(true); + set_use_preview_label (false); + + //Catch selection-changed events, so we can adjust the text widget + signal_update_preview().connect( + sigc::mem_fun(*this, &FileSaveDialogImpl::updatePreviewCallback) ); + + + //Let's do some customization + fileNameEntry = NULL; + Gtk::Container *cont = get_toplevel(); + std::vector entries; + findEntryWidgets(cont, entries); + //g_message("Found %d entry widgets\n", entries.size()); + if (entries.size() >=1 ) + { + //Catch when user hits [return] on the text field + fileNameEntry = entries[0]; + fileNameEntry->signal_activate().connect( + sigc::mem_fun(*this, &FileSaveDialogImpl::fileNameEntryChangedCallback) ); + } + + //Let's do more customization + std::vector expanders; + findExpanderWidgets(cont, expanders); + //g_message("Found %d expander widgets\n", expanders.size()); + if (expanders.size() >=1 ) + { + //Always show the file list + Gtk::Expander *expander = expanders[0]; + expander->set_expanded(true); + } + + + //if (extension == NULL) + // checkbox.set_sensitive(FALSE); + + add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); + add_button(Gtk::Stock::SAVE, Gtk::RESPONSE_OK); + + show_all_children(); +} + + + +/** + * Public factory method. Used in file.cpp + */ +FileSaveDialog *FileSaveDialog::create(char const *path, + FileDialogType fileTypes, + char const *title, + char const *default_key) +{ + FileSaveDialog *dialog = new FileSaveDialogImpl(path, fileTypes, title, default_key); + return dialog; +} + + + + + +/** + * Destructor + */ +FileSaveDialogImpl::~FileSaveDialogImpl() +{ +} + + + + +/** + * Show this dialog modally. Return true if user hits [OK] + */ +bool +FileSaveDialogImpl::show() +{ + set_current_folder(get_current_folder()); //hack to force initial dir listing + set_modal (TRUE); //Window + sp_transientize((GtkWidget *)gobj()); //Make transient + gint b = run(); //Dialog + hide(); + + if (b == Gtk::RESPONSE_OK) + { + int sel = fileTypeComboBox.get_active_row_number (); + if (sel>=0 && sel< (int)fileTypes.size()) + { + FileType &type = fileTypes[sel]; + extension = type.extension; + } + myFilename = get_filename(); + + /* + + // FIXME: Why do we have more code + + append_extension = checkbox.get_active(); + prefs_set_int_attribute("dialogs.save_as", "append_extension", append_extension); + prefs_set_string_attribute("dialogs.save_as", "default", + ( extension != NULL ? extension->get_id() : "" )); + */ + return TRUE; + } + else + { + return FALSE; + } +} + + +/** + * Get the file extension type that was selected by the user. Valid after an [OK] + */ +Inkscape::Extension::Extension * +FileSaveDialogImpl::getSelectionType() +{ + return extension; +} + + +/** + * Get the file name chosen by the user. Valid after an [OK] + */ +gchar * +FileSaveDialogImpl::getFilename() +{ + return g_strdup(myFilename.c_str()); +} + +/** + \brief A quick function to turn a standard extension into a searchable + pattern for the file dialogs + \param pattern The patter that the extension should be written to + \param in_file_extension The C string that represents the extension + + This function just goes through the string, and takes all characters + and puts a [] so that both are searched and shown in + the file dialog. This function edits the pattern string to make + this happen. +*/ +void +FileDialogExtensionToPattern (Glib::ustring &pattern, gchar * in_file_extension) +{ + Glib::ustring tmp(in_file_extension); + + for ( guint i = 0; i < tmp.length(); i++ ) { + Glib::ustring::value_type ch = tmp.at(i); + if ( Glib::Unicode::isalpha(ch) ) { + pattern += '['; + pattern += Glib::Unicode::toupper(ch); + pattern += Glib::Unicode::tolower(ch); + pattern += ']'; + } else { + pattern += ch; + } + } +} + +} //namespace Dialogs +} //namespace UI +} //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 : diff --git a/src/dialogs/filedialog.h b/src/dialogs/filedialog.h new file mode 100644 index 000000000..ab3615bf6 --- /dev/null +++ b/src/dialogs/filedialog.h @@ -0,0 +1,172 @@ +#ifndef __FILE_DIALOG_H__ +#define __FILE_DIALOG_H__ + +/** \file Defines classes FileOpenDialog, FileSaveDialog, + * and enums FileDialogType, FileDialogSelectionType. */ + +#include +#include + +namespace Inkscape { + +namespace Extension { +class Extension; +} + +namespace UI { +namespace Dialogs { + + +/** + * Used for setting filters and options, and + * reading them back from user selections. + */ +typedef enum { + SVG_TYPES, + IMPORT_TYPES, + EXPORT_TYPES + } FileDialogType; + +/** + * Used for returning the type selected in a SaveAs + */ +typedef enum { + SVG_NAMESPACE, + SVG_NAMESPACE_WITH_EXTENSIONS + } FileDialogSelectionType; + +/** + * Architecture-specific data + */ +typedef struct FileOpenNativeData_def FileOpenNativeData; + + +/** + * This class provides an implementation-independent API for + * file "Open" dialogs. Using a standard interface obviates the need + * for ugly #ifdefs in file open code + */ +class FileOpenDialog +{ +public: + + + /** + * Constructor .. do not call directly + * @param path the directory where to start searching + * @param fileTypes one of FileDialogTypes + * @param title the title of the dialog + */ + FileOpenDialog() + {}; + + /** + * Factory. + * @param path the directory where to start searching + * @param fileTypes one of FileDialogTypes + * @param title the title of the dialog + */ + static FileOpenDialog *create(const char *path, FileDialogType fileTypes, const char *title); + + + /** + * Destructor. + * Perform any necessary cleanups. + */ + virtual ~FileOpenDialog() {}; + + /** + * Show an OpenFile file selector. + * @return the selected path if user selected one, else NULL + */ + virtual bool show() =0; + + /** + * Return the 'key' (filetype) of the selection, if any + * @return a pointer to a string if successful (which must + * be later freed with g_free(), else NULL. + */ + virtual Inkscape::Extension::Extension * getSelectionType() = 0; + + virtual gchar * getFilename () =0; + + virtual Glib::SListHandle getFilenames () = 0; + +}; //FileOpenDialog + + + + + + +/** + * This class provides an implementation-independent API for + * file "Save" dialogs. + */ +class FileSaveDialog +{ +public: + + /** + * Constructor. Do not call directly . Use the factory. + * @param path the directory where to start searching + * @param fileTypes one of FileDialogTypes + * @param title the title of the dialog + * @param key a list of file types from which the user can select + */ + FileSaveDialog () + {}; + + /** + * Factory. + * @param path the directory where to start searching + * @param fileTypes one of FileDialogTypes + * @param title the title of the dialog + * @param key a list of file types from which the user can select + */ + static FileSaveDialog *create(const char *path, FileDialogType fileTypes, const char *title, const char * default_key); + + + /** + * Destructor. + * Perform any necessary cleanups. + */ + virtual ~FileSaveDialog() {}; + + + /** + * Show an SaveAs file selector. + * @return the selected path if user selected one, else NULL + */ + virtual bool show() =0; + + /** + * Return the 'key' (filetype) of the selection, if any + * @return a pointer to a string if successful (which must + * be later freed with g_free(), else NULL. + */ + virtual Inkscape::Extension::Extension * getSelectionType() = 0; + + virtual gchar * getFilename () =0; + + +}; //FileSaveDialog + + +} //namespace Dialogs +} //namespace UI +} //namespace Inkscape + + +#endif /* __FILE_DIALOG_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:encoding=utf-8:textwidth=99 : diff --git a/src/dialogs/fill-style.cpp b/src/dialogs/fill-style.cpp new file mode 100644 index 000000000..1c151deeb --- /dev/null +++ b/src/dialogs/fill-style.cpp @@ -0,0 +1,546 @@ +#define __SP_FILL_STYLE_C__ + +/** + * \brief Fill style widget + * + * Authors: + * Lauris Kaplinski + * Frank Felfe + * bulia byak + * + * Copyright (C) 1999-2005 authors + * Copyright (C) 2001-2002 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#define noSP_FS_VERBOSE + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +// These can be deleted once we sort out the libart dependence. + +#define ART_WIND_RULE_NONZERO 0 + +static void sp_fill_style_widget_construct ( SPWidget *spw, + SPPaintSelector *psel ); + +static void sp_fill_style_widget_modify_selection ( SPWidget *spw, + Inkscape::Selection *selection, + guint flags, + SPPaintSelector *psel ); + +static void sp_fill_style_widget_change_subselection ( Inkscape::Application *inkscape, SPDesktop *desktop, SPWidget *spw ); + +static void sp_fill_style_widget_change_selection ( SPWidget *spw, + Inkscape::Selection *selection, + SPPaintSelector *psel ); + +static void sp_fill_style_widget_update (SPWidget *spw); + +static void sp_fill_style_widget_paint_mode_changed ( SPPaintSelector *psel, + SPPaintSelectorMode mode, + SPWidget *spw ); +static void sp_fill_style_widget_fillrule_changed ( SPPaintSelector *psel, + SPPaintSelectorFillRule mode, + SPWidget *spw ); + +static void sp_fill_style_widget_paint_dragged (SPPaintSelector *psel, SPWidget *spw ); +static void sp_fill_style_widget_paint_changed (SPPaintSelector *psel, SPWidget *spw ); + +GtkWidget * +sp_fill_style_widget_new (void) +{ + GtkWidget *spw = sp_widget_new_global (INKSCAPE); + + GtkWidget *vb = gtk_vbox_new (FALSE, 0); + gtk_widget_show (vb); + gtk_container_add (GTK_CONTAINER (spw), vb); + + GtkWidget *psel = sp_paint_selector_new (true); // with fillrule selector + gtk_widget_show (psel); + gtk_box_pack_start (GTK_BOX (vb), psel, TRUE, TRUE, 0); + g_object_set_data (G_OBJECT (spw), "paint-selector", psel); + + g_signal_connect ( G_OBJECT (psel), "mode_changed", + G_CALLBACK (sp_fill_style_widget_paint_mode_changed), + spw ); + + g_signal_connect ( G_OBJECT (psel), "dragged", + G_CALLBACK (sp_fill_style_widget_paint_dragged), + spw ); + + g_signal_connect ( G_OBJECT (psel), "changed", + G_CALLBACK (sp_fill_style_widget_paint_changed), + spw ); + + g_signal_connect ( G_OBJECT (psel), "fillrule_changed", + G_CALLBACK (sp_fill_style_widget_fillrule_changed), + spw ); + + + g_signal_connect ( G_OBJECT (spw), "construct", + G_CALLBACK (sp_fill_style_widget_construct), psel); + +//FIXME: switch these from spw signals to global inkscape object signals; spw just retranslates +//those anyway; then eliminate spw + g_signal_connect ( G_OBJECT (spw), "modify_selection", + G_CALLBACK (sp_fill_style_widget_modify_selection), psel); + + g_signal_connect ( G_OBJECT (spw), "change_selection", + G_CALLBACK (sp_fill_style_widget_change_selection), psel); + + g_signal_connect (INKSCAPE, "change_subselection", G_CALLBACK (sp_fill_style_widget_change_subselection), spw); + + sp_fill_style_widget_update (SP_WIDGET (spw)); + + return spw; + +} // end of sp_fill_style_widget_new() + + + +static void +sp_fill_style_widget_construct ( SPWidget *spw, SPPaintSelector *psel ) +{ + +#ifdef SP_FS_VERBOSE + g_print ( "Fill style widget constructed: inkscape %p repr %p\n", + spw->inkscape, spw->repr ); +#endif + if (spw->inkscape) { + + sp_fill_style_widget_update (spw); + + } + +} // end of sp_fill_style_widget_construct() + +static void +sp_fill_style_widget_modify_selection ( SPWidget *spw, + Inkscape::Selection *selection, + guint flags, + SPPaintSelector *psel ) +{ + if (flags & ( SP_OBJECT_MODIFIED_FLAG | + SP_OBJECT_PARENT_MODIFIED_FLAG | + SP_OBJECT_STYLE_MODIFIED_FLAG) ) + { + sp_fill_style_widget_update (spw); + } +} + +static void +sp_fill_style_widget_change_subselection ( Inkscape::Application *inkscape, + SPDesktop *desktop, + SPWidget *spw ) +{ + sp_fill_style_widget_update (spw); +} + +static void +sp_fill_style_widget_change_selection ( SPWidget *spw, + Inkscape::Selection *selection, + SPPaintSelector *psel ) +{ + sp_fill_style_widget_update (spw); +} + +/** +* \param sel Selection to use, or NULL. +*/ +static void +sp_fill_style_widget_update (SPWidget *spw) +{ + if (g_object_get_data (G_OBJECT (spw), "update")) + return; + + if (g_object_get_data (G_OBJECT (spw), "local")) { + g_object_set_data (G_OBJECT (spw), "local", GINT_TO_POINTER (FALSE)); // local change; do nothing, but reset the flag + return; + } + + g_object_set_data (G_OBJECT (spw), "update", GINT_TO_POINTER (TRUE)); + + SPPaintSelector *psel = SP_PAINT_SELECTOR (g_object_get_data (G_OBJECT (spw), "paint-selector")); + + // create temporary style + SPStyle *query = sp_style_new (); + // query style from desktop into it. This returns a result flag and fills query with the style of subselection, if any, or selection + int result = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FILL); + + switch (result) { + case QUERY_STYLE_NOTHING: + { + /* No paint at all */ + sp_paint_selector_set_mode (psel, SP_PAINT_SELECTOR_MODE_EMPTY); + break; + } + + case QUERY_STYLE_SINGLE: + case QUERY_STYLE_MULTIPLE_AVERAGED: // TODO: treat this slightly differently, e.g. display "averaged" somewhere in paint selector + case QUERY_STYLE_MULTIPLE_SAME: + { + SPPaintSelectorMode pselmode = sp_style_determine_paint_selector_mode (query, true); + sp_paint_selector_set_mode (psel, pselmode); + + sp_paint_selector_set_fillrule (psel, query->fill_rule.computed == ART_WIND_RULE_NONZERO? + SP_PAINT_SELECTOR_FILLRULE_NONZERO : SP_PAINT_SELECTOR_FILLRULE_EVENODD); + + if (query->fill.set && query->fill.type == SP_PAINT_TYPE_COLOR) { + gfloat d[3]; + sp_color_get_rgb_floatv (&query->fill.value.color, d); + SPColor color; + sp_color_set_rgb_float (&color, d[0], d[1], d[2]); + sp_paint_selector_set_color_alpha (psel, &color, SP_SCALE24_TO_FLOAT (query->fill_opacity.value)); + + } else if (query->fill.set && query->fill.type == SP_PAINT_TYPE_PAINTSERVER) { + + SPPaintServer *server = SP_STYLE_FILL_SERVER (query); + + if (SP_IS_LINEARGRADIENT (server)) { + SPGradient *vector = sp_gradient_get_vector (SP_GRADIENT (server), FALSE); + sp_paint_selector_set_gradient_linear (psel, vector); + + SPLinearGradient *lg = SP_LINEARGRADIENT (server); + sp_paint_selector_set_gradient_properties (psel, + SP_GRADIENT_UNITS (lg), + SP_GRADIENT_SPREAD (lg)); + } else if (SP_IS_RADIALGRADIENT (server)) { + SPGradient *vector = sp_gradient_get_vector (SP_GRADIENT (server), FALSE); + sp_paint_selector_set_gradient_radial (psel, vector); + + SPRadialGradient *rg = SP_RADIALGRADIENT (server); + sp_paint_selector_set_gradient_properties (psel, + SP_GRADIENT_UNITS (rg), + SP_GRADIENT_SPREAD (rg)); + } else if (SP_IS_PATTERN (server)) { + SPPattern *pat = pattern_getroot (SP_PATTERN (server)); + sp_update_pattern_list (psel, pat); + } + } + break; + } + + case QUERY_STYLE_MULTIPLE_DIFFERENT: + { + sp_paint_selector_set_mode (psel, SP_PAINT_SELECTOR_MODE_MULTIPLE); + break; + } + } + + g_free (query); + + g_object_set_data (G_OBJECT (spw), "update", GINT_TO_POINTER (FALSE)); + +} + + +static void +sp_fill_style_widget_paint_mode_changed ( SPPaintSelector *psel, + SPPaintSelectorMode mode, + SPWidget *spw ) +{ + if (g_object_get_data (G_OBJECT (spw), "update")) + return; + + /* TODO: Does this work? */ + /* TODO: Not really, here we have to get old color back from object */ + /* Instead of relying on paint widget having meaningful colors set */ + sp_fill_style_widget_paint_changed (psel, spw); +} + +static void +sp_fill_style_widget_fillrule_changed ( SPPaintSelector *psel, + SPPaintSelectorFillRule mode, + SPWidget *spw ) +{ + if (g_object_get_data (G_OBJECT (spw), "update")) + return; + + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + + SPCSSAttr *css = sp_repr_css_attr_new (); + sp_repr_css_set_property (css, "fill-rule", mode == SP_PAINT_SELECTOR_FILLRULE_EVENODD? "evenodd":"nonzero"); + + sp_desktop_set_style (desktop, css); + + sp_repr_css_attr_unref (css); + + sp_document_done (SP_ACTIVE_DOCUMENT); +} + +static gchar *undo_label_1 = "fill:flatcolor:1"; +static gchar *undo_label_2 = "fill:flatcolor:2"; +static gchar *undo_label = undo_label_1; + +/** +This is called repeatedly while you are dragging a color slider, only for flat color +modes. Previously it set the color in style but did not update the repr for efficiency, however +this was flakey and didn't buy us almost anything. So now it does the same as _changed, except +lumps all its changes for undo. + */ +static void +sp_fill_style_widget_paint_dragged (SPPaintSelector *psel, SPWidget *spw) +{ + if (!spw->inkscape) { + return; + } + + if (g_object_get_data (G_OBJECT (spw), "update")) { + return; + } + + if (g_object_get_data (G_OBJECT (spw), "local")) { + // previous local flag not cleared yet; + // this means dragged events come too fast, so we better skip this one to speed up display + // (it's safe to do this in any case) + return; + } + + g_object_set_data (G_OBJECT (spw), "update", GINT_TO_POINTER (TRUE)); + + switch (psel->mode) { + + case SP_PAINT_SELECTOR_MODE_COLOR_RGB: + case SP_PAINT_SELECTOR_MODE_COLOR_CMYK: + { + sp_paint_selector_set_flat_color (psel, SP_ACTIVE_DESKTOP, "fill", "fill-opacity"); + sp_document_maybe_done (SP_DT_DOCUMENT(SP_ACTIVE_DESKTOP), undo_label); + g_object_set_data (G_OBJECT (spw), "local", GINT_TO_POINTER (TRUE)); // local change, do not update from selection + break; + } + + default: + g_warning ( "file %s: line %d: Paint %d should not emit 'dragged'", + __FILE__, __LINE__, psel->mode ); + break; + + } + g_object_set_data (G_OBJECT (spw), "update", GINT_TO_POINTER (FALSE)); +} + + +/** +This is called (at least) when: +1 paint selector mode is switched (e.g. flat color -> gradient) +2 you finished dragging a gradient node and released mouse +3 you changed a gradient selector parameter (e.g. spread) +Must update repr. + */ +static void +sp_fill_style_widget_paint_changed ( SPPaintSelector *psel, + SPWidget *spw ) +{ + if (g_object_get_data (G_OBJECT (spw), "update")) { + return; + } + g_object_set_data (G_OBJECT (spw), "update", GINT_TO_POINTER (TRUE)); + + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + if (!desktop) { + return; + } + SPDocument *document = SP_DT_DOCUMENT (desktop); + Inkscape::Selection *selection = SP_DT_SELECTION (desktop); + + GSList const *items = selection->itemList(); + + switch (psel->mode) { + + case SP_PAINT_SELECTOR_MODE_EMPTY: + // This should not happen. + g_warning ( "file %s: line %d: Paint %d should not emit 'changed'", + __FILE__, __LINE__, psel->mode); + break; + case SP_PAINT_SELECTOR_MODE_MULTIPLE: + // This happens when you switch multiple objects with different gradients to flat color; + // nothing to do here. + break; + + case SP_PAINT_SELECTOR_MODE_NONE: + { + SPCSSAttr *css = sp_repr_css_attr_new (); + sp_repr_css_set_property (css, "fill", "none"); + + sp_desktop_set_style (desktop, css); + + sp_repr_css_attr_unref (css); + + sp_document_done (document); + break; + } + + case SP_PAINT_SELECTOR_MODE_COLOR_RGB: + case SP_PAINT_SELECTOR_MODE_COLOR_CMYK: + { + sp_paint_selector_set_flat_color (psel, desktop, "fill", "fill-opacity"); + sp_document_maybe_done (SP_DT_DOCUMENT(desktop), undo_label); + + // on release, toggle undo_label so that the next drag will not be lumped with this one + if (undo_label == undo_label_1) + undo_label = undo_label_2; + else + undo_label = undo_label_1; + + break; + } + + case SP_PAINT_SELECTOR_MODE_GRADIENT_LINEAR: + case SP_PAINT_SELECTOR_MODE_GRADIENT_RADIAL: + if (items) { + SPGradientType const gradient_type = ( psel->mode == SP_PAINT_SELECTOR_MODE_GRADIENT_LINEAR + ? SP_GRADIENT_TYPE_LINEAR + : SP_GRADIENT_TYPE_RADIAL ); + + // HACK: reset fill-opacity - that 0.75 is annoying; BUT remove this when we have an opacity slider for all tabs + SPCSSAttr *css = sp_repr_css_attr_new(); + sp_repr_css_set_property(css, "fill-opacity", "1.0"); + + SPGradient *vector = sp_paint_selector_get_gradient_vector(psel); + if (!vector) { + /* No vector in paint selector should mean that we just changed mode */ + + SPStyle *query = sp_style_new (); + int result = objects_query_fillstroke ((GSList *) items, query, true); + guint32 common_rgb = 0; + if (result == QUERY_STYLE_MULTIPLE_SAME) { + if (query->fill.type != SP_PAINT_TYPE_COLOR) { + common_rgb = sp_desktop_get_color(desktop, true); + } else { + common_rgb = sp_color_get_rgba32_ualpha(&query->fill.value.color, 0xff); + } + vector = sp_document_default_gradient_vector(document, common_rgb); + } + g_free (query); + + for (GSList const *i = items; i != NULL; i = i->next) { + //FIXME: see above + sp_repr_css_change_recursive(SP_OBJECT_REPR(i->data), css, "style"); + + if (!vector) { + sp_item_set_gradient(SP_ITEM(i->data), + sp_gradient_vector_for_object(document, desktop, SP_OBJECT(i->data), true), + gradient_type, true); + } else { + sp_item_set_gradient(SP_ITEM(i->data), vector, gradient_type, true); + } + } + } else { + /* We have changed from another gradient type, or modified spread/units within + * this gradient type. */ + vector = sp_gradient_ensure_vector_normalized (vector); + for (GSList const *i = items; i != NULL; i = i->next) { + //FIXME: see above + sp_repr_css_change_recursive (SP_OBJECT_REPR (i->data), css, "style"); + + SPGradient *gr = sp_item_set_gradient(SP_ITEM(i->data), vector, gradient_type, true); + sp_gradient_selector_attrs_to_gradient (gr, psel); + } + } + + sp_repr_css_attr_unref (css); + + sp_document_done (document); + } + break; + + case SP_PAINT_SELECTOR_MODE_PATTERN: + + if (items) { + + SPPattern *pattern = sp_paint_selector_get_pattern (psel); + if (!pattern) { + + /* No Pattern in paint selector should mean that we just + * changed mode - dont do jack. + */ + + } else { + Inkscape::XML::Node *patrepr = SP_OBJECT_REPR(pattern); + SPCSSAttr *css = sp_repr_css_attr_new (); + gchar *urltext = g_strdup_printf ("url(#%s)", patrepr->attribute("id")); + sp_repr_css_set_property (css, "fill", urltext); + + // HACK: reset fill-opacity - that 0.75 is annoying; BUT remove this when we have an opacity slider for all tabs + sp_repr_css_set_property(css, "fill-opacity", "1.0"); + + // cannot just call sp_desktop_set_style, because we don't want to touch those + // objects who already have the same root pattern but through a different href + // chain. FIXME: move this to a sp_item_set_pattern + for (GSList const *i = items; i != NULL; i = i->next) { + SPObject *selobj = SP_OBJECT (i->data); + + SPStyle *style = SP_OBJECT_STYLE (selobj); + if (style && style->fill.type == SP_PAINT_TYPE_PAINTSERVER) { + SPObject *server = SP_OBJECT_STYLE_FILL_SERVER (selobj); + if (SP_IS_PATTERN (server) && pattern_getroot (SP_PATTERN(server)) == pattern) + // only if this object's pattern is not rooted in our selected pattern, apply + continue; + } + + sp_desktop_apply_css_recursive (selobj, css, true); + } + + sp_repr_css_attr_unref (css); + g_free (urltext); + + } // end if + + sp_document_done (document); + + } // end if + + break; + + case SP_PAINT_SELECTOR_MODE_UNSET: + if (items) { + SPCSSAttr *css = sp_repr_css_attr_new (); + sp_repr_css_unset_property (css, "fill"); + + sp_desktop_set_style (desktop, css); + sp_repr_css_attr_unref (css); + + sp_document_done (document); + } + break; + + default: + g_warning ( "file %s: line %d: Paint selector should not be in " + "mode %d", + __FILE__, __LINE__, psel->mode ); + break; + } + + g_object_set_data (G_OBJECT (spw), "update", GINT_TO_POINTER (FALSE)); +} + + +/* + 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:textwidth=99 : diff --git a/src/dialogs/fill-style.h b/src/dialogs/fill-style.h new file mode 100644 index 000000000..96cb06987 --- /dev/null +++ b/src/dialogs/fill-style.h @@ -0,0 +1,35 @@ +#ifndef __SP_FILL_STYLE_H__ +#define __SP_FILL_STYLE_H__ + +/** + * \brief Fill style configuration + * + * Authors: + * Lauris Kaplinski + * + * Copyright (C) 2002 Lauris Kaplinski + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include + +#include + +#include "forward.h" + + +GtkWidget *sp_fill_style_widget_new (void); + +#endif + +/* + 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:textwidth=99 : diff --git a/src/dialogs/find.cpp b/src/dialogs/find.cpp new file mode 100644 index 000000000..85146f8a3 --- /dev/null +++ b/src/dialogs/find.cpp @@ -0,0 +1,763 @@ +#define __SP_TRANSFORMATION_C__ + +/** + * \brief Find dialog + * + * Authors: + * bulia byak + * + * Copyright (C) 2004 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + + +#include "widgets/icon.h" + +#include "message-stack.h" + +//TODO : delete this +GtkWidget * sp_find_dialog_old (void); + +void +//GtkWidget * +sp_find_dialog(){ + // DialogFind::get().present(); + sp_find_dialog_old (); + return; +} + + +#include + +#include +#include "helper/window.h" +#include "macros.h" +#include "inkscape.h" +#include "document.h" +#include "desktop.h" +#include "selection.h" +#include "desktop-handles.h" + +#include "dialog-events.h" +#include "../prefs-utils.h" +#include "../verbs.h" +#include "../interface.h" +#include "../sp-text.h" +#include "../sp-flowtext.h" +#include "../text-editing.h" +#include "../sp-tspan.h" +#include "../selection-chemistry.h" +#include "../sp-defs.h" +#include "../sp-rect.h" +#include "../sp-ellipse.h" +#include "../sp-star.h" +#include "../sp-spiral.h" +#include "../sp-path.h" +#include "../sp-line.h" +#include "../sp-polyline.h" +#include "../sp-item-group.h" +#include "../sp-use.h" +#include "../sp-image.h" +#include "../sp-offset.h" +#include + +using NR::X; +using NR::Y; + +static GtkWidget *dlg = NULL; +static win_data wd; + +// impossible original values to make sure they are read from prefs +static gint x = -1000, y = -1000, w = 0, h = 0; +static gchar *prefs_path = "dialogs.find"; + + + + +static void sp_find_dialog_destroy(GtkObject *object, gpointer) +{ + sp_signal_disconnect_by_data (INKSCAPE, object); + wd.win = dlg = NULL; + wd.stop = 0; +} + + + +static gboolean sp_find_dialog_delete(GtkObject *, GdkEvent *, gpointer data) +{ + gtk_window_get_position (GTK_WINDOW (dlg), &x, &y); + gtk_window_get_size (GTK_WINDOW (dlg), &w, &h); + + prefs_set_int_attribute (prefs_path, "x", x); + prefs_set_int_attribute (prefs_path, "y", y); + prefs_set_int_attribute (prefs_path, "w", w); + prefs_set_int_attribute (prefs_path, "h", h); + + return FALSE; // which means, go ahead and destroy it +} + +void +sp_find_squeeze_window() +{ + GtkRequisition r; + gtk_widget_size_request(dlg, &r); + gtk_window_resize ((GtkWindow *) dlg, r.width, r.height); +} + +bool +item_id_match (SPItem *item, const gchar *id, bool exact) +{ + if (SP_OBJECT_REPR (item) == NULL) + return false; + + if (SP_IS_STRING(item)) // SPStrings have "on demand" ids which are useless for searching + return false; + + const gchar *item_id = (SP_OBJECT_REPR (item))->attribute("id"); + if (item_id == NULL) + return false; + + if (exact) { + return ((bool) !strcmp(item_id, id)); + } else { +// g_print ("strstr: %s %s: %s\n", item_id, id, strstr(item_id, id) != NULL? "yes":"no"); + return ((bool) (strstr(item_id, id) != NULL)); + } +} + +bool +item_text_match (SPItem *item, const gchar *text, bool exact) +{ + if (SP_OBJECT_REPR (item) == NULL) + return false; + + if (SP_IS_TEXT(item) || SP_IS_FLOWTEXT(item)) { + const gchar *item_text = sp_te_get_string_multiline (item); + if (item_text == NULL) + return false; + bool ret; + if (exact) { + ret = ((bool) !strcasecmp(item_text, text)); + } else { + //FIXME: strcasestr + ret = ((bool) (strstr(item_text, text) != NULL)); + } + g_free ((void*) item_text); + return ret; + } + return false; +} + +bool +item_style_match (SPItem *item, const gchar *text, bool exact) +{ + if (SP_OBJECT_REPR (item) == NULL) + return false; + + const gchar *item_text = (SP_OBJECT_REPR (item))->attribute("style"); + if (item_text == NULL) + return false; + + if (exact) { + return ((bool) !strcmp(item_text, text)); + } else { + return ((bool) (strstr(item_text, text) != NULL)); + } +} + +bool +item_attr_match (SPItem *item, const gchar *name, bool exact) +{ + if (SP_OBJECT_REPR (item) == NULL) + return false; + + if (exact) { + const gchar *attr_value = (SP_OBJECT_REPR (item))->attribute(name); + return ((bool) (attr_value != NULL)); + } else { + return SP_OBJECT_REPR (item)->matchAttributeName(name); + } +} + + +GSList * +filter_onefield (GSList *l, GObject *dlg, const gchar *field, bool (*match_function)(SPItem *, const gchar *, bool), bool exact) +{ + GtkWidget *widget = GTK_WIDGET (gtk_object_get_data (GTK_OBJECT (dlg), field)); + const gchar *text = gtk_entry_get_text (GTK_ENTRY(widget)); + + if (strlen (text) != 0) { + GSList *n = NULL; + for (GSList *i = l; i != NULL; i = i->next) { + if (match_function (SP_ITEM(i->data), text, exact)) { + n = g_slist_prepend (n, i->data); + } + } + return n; + } else { + return l; + } + + return NULL; +} + + +bool +type_checkbox (GtkWidget *widget, const gchar *data) +{ + return gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (gtk_object_get_data (GTK_OBJECT (widget), data))); +} + +bool +item_type_match (SPItem *item, GtkWidget *widget) +{ + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + + if (SP_IS_RECT(item)) { + return (type_checkbox (widget, "shapes") || type_checkbox (widget, "rects")); + + } else if (SP_IS_GENERICELLIPSE(item) || SP_IS_ELLIPSE(item) || SP_IS_ARC(item) || SP_IS_CIRCLE(item)) { + return (type_checkbox (widget, "shapes") || type_checkbox (widget, "ellipses")); + + } else if (SP_IS_STAR(item) || SP_IS_POLYGON(item)) { + return (type_checkbox (widget, "shapes") || type_checkbox (widget, "stars")); + + } else if (SP_IS_SPIRAL(item)) { + return (type_checkbox (widget, "shapes") || type_checkbox (widget, "spirals")); + + } else if (SP_IS_PATH(item) || SP_IS_LINE(item) || SP_IS_POLYLINE(item)) { + return (type_checkbox (widget, "paths")); + + } else if (SP_IS_TEXT(item) || SP_IS_TSPAN(item) || SP_IS_STRING(item)) { + return (type_checkbox (widget, "texts")); + + } else if (SP_IS_GROUP(item) && !desktop->isLayer(item) ) { // never select layers! + return (type_checkbox (widget, "groups")); + + } else if (SP_IS_USE(item)) { + return (type_checkbox (widget, "clones")); + + } else if (SP_IS_IMAGE(item)) { + return (type_checkbox (widget, "images")); + + } else if (SP_IS_OFFSET(item)) { + return (type_checkbox (widget, "offsets")); + } + + return false; +} + +GSList * +filter_types (GSList *l, GObject *dlg, bool (*match_function)(SPItem *, GtkWidget *)) +{ + GtkWidget *widget = GTK_WIDGET (gtk_object_get_data (GTK_OBJECT (dlg), "types")); + + GtkWidget *alltypes = GTK_WIDGET (gtk_object_get_data (GTK_OBJECT (widget), "all")); + if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (alltypes))) + return l; + + + GSList *n = NULL; + for (GSList *i = l; i != NULL; i = i->next) { + if (match_function (SP_ITEM(i->data), widget)) { + n = g_slist_prepend (n, i->data); + } + } + return n; +} + + +GSList * +filter_list (GSList *l, GObject *dlg, bool exact) +{ + l = filter_onefield (l, dlg, "text", item_text_match, exact); + l = filter_onefield (l, dlg, "id", item_id_match, exact); + l = filter_onefield (l, dlg, "style", item_style_match, exact); + l = filter_onefield (l, dlg, "attr", item_attr_match, exact); + + l = filter_types (l, dlg, item_type_match); + + return l; +} + +GSList * +all_items (SPObject *r, GSList *l, bool hidden, bool locked) +{ + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + + if (SP_IS_DEFS(r)) + return l; // we're not interested in items in defs + + if (!strcmp (SP_OBJECT_REPR (r)->name(), "svg:metadata")) + return l; // we're not interested in metadata + + for (SPObject *child = sp_object_first_child(r); child; child = SP_OBJECT_NEXT (child)) { + if (SP_IS_ITEM (child) && !SP_OBJECT_IS_CLONED (child) && !desktop->isLayer(SP_ITEM(child))) { + if ((hidden || !desktop->itemIsHidden(SP_ITEM(child))) && (locked || !SP_ITEM(child)->isLocked())) { + l = g_slist_prepend (l, child); + } + } + l = all_items (child, l, hidden, locked); + } + return l; +} + +GSList * +all_selection_items (Inkscape::Selection *s, GSList *l, SPObject *ancestor, bool hidden, bool locked) +{ + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + + for (GSList *i = (GSList *) s->itemList(); i != NULL; i = i->next) { + if (SP_IS_ITEM (i->data) && !SP_OBJECT_IS_CLONED (i->data) && !desktop->isLayer(SP_ITEM(i->data))) { + if (!ancestor || ancestor->isAncestorOf(SP_OBJECT (i->data))) { + if ((hidden || !desktop->itemIsHidden(SP_ITEM(i->data))) && (locked || !SP_ITEM(i->data)->isLocked())) { + l = g_slist_prepend (l, i->data); + } + } + } + if (!ancestor || ancestor->isAncestorOf(SP_OBJECT (i->data))) { + l = all_items (SP_OBJECT (i->data), l, hidden, locked); + } + } + return l; +} + + +void sp_find_dialog_find(GObject *, GObject *dlg) +{ + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + + bool hidden = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (gtk_object_get_data (GTK_OBJECT (dlg), "includehidden"))); + bool locked = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (gtk_object_get_data (GTK_OBJECT (dlg), "includelocked"))); + + GSList *l = NULL; + if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (gtk_object_get_data (GTK_OBJECT (dlg), "inselection")))) { + if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (gtk_object_get_data (GTK_OBJECT (dlg), "inlayer")))) { + l = all_selection_items (desktop->selection, l, desktop->currentLayer(), hidden, locked); + } else { + l = all_selection_items (desktop->selection, l, NULL, hidden, locked); + } + } else { + if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (gtk_object_get_data (GTK_OBJECT (dlg), "inlayer")))) { + l = all_items (desktop->currentLayer(), l, hidden, locked); + } else { + l = all_items (SP_DOCUMENT_ROOT (SP_DT_DOCUMENT (desktop)), l, hidden, locked); + } + } + guint all = g_slist_length (l); + + bool exact = true; + GSList *n = NULL; + n = filter_list (l, dlg, exact); + if (n == NULL) { + exact = false; + n = filter_list (l, dlg, exact); + } + + if (n != NULL) { + int count = g_slist_length (n); + desktop->messageStack()->flashF(Inkscape::NORMAL_MESSAGE, + // TRANSLATORS: "%s" is replaced with "exact" or "partial" when this string is displayed + ngettext("%d object found (out of %d), %s match.", + "%d objects found (out of %d), %s match.", + count), + count, all, exact? _("exact") : _("partial")); + + Inkscape::Selection *selection = SP_DT_SELECTION (desktop); + selection->clear(); + selection->setList(n); + scroll_to_show_item (desktop, SP_ITEM(n->data)); + } else { + desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("No objects found")); + } +} + +void +sp_find_reset_searchfield (GObject *dlg, const gchar *field) +{ + GtkWidget *widget = GTK_WIDGET (gtk_object_get_data (GTK_OBJECT (dlg), field)); + gtk_entry_set_text (GTK_ENTRY(widget), ""); +} + + +void +sp_find_dialog_reset (GObject *, GObject *dlg) +{ + sp_find_reset_searchfield (dlg, "text"); + sp_find_reset_searchfield (dlg, "id"); + sp_find_reset_searchfield (dlg, "style"); + sp_find_reset_searchfield (dlg, "attr"); + + GtkWidget *types = GTK_WIDGET (gtk_object_get_data (GTK_OBJECT (dlg), "types")); + GtkToggleButton *tb = GTK_TOGGLE_BUTTON (gtk_object_get_data (GTK_OBJECT (types), "all")); + gtk_toggle_button_toggled (tb); + gtk_toggle_button_set_active (tb, TRUE); +} + + +#define FIND_LABELWIDTH 80 + +void +sp_find_new_searchfield (GtkWidget *dlg, GtkWidget *vb, const gchar *label, const gchar *id, GtkTooltips *tt, const gchar *tip) +{ + GtkWidget *hb = gtk_hbox_new (FALSE, 0); + GtkWidget *l = gtk_label_new_with_mnemonic (label); + gtk_widget_set_size_request (l, FIND_LABELWIDTH, -1); + gtk_misc_set_alignment (GTK_MISC (l), 1.0, 0.5); + gtk_box_pack_start (GTK_BOX (hb), l, FALSE, FALSE, 0); + + GtkWidget *tf = gtk_entry_new (); + gtk_entry_set_max_length (GTK_ENTRY (tf), 64); + gtk_box_pack_start (GTK_BOX (hb), tf, TRUE, TRUE, 0); + gtk_object_set_data (GTK_OBJECT (dlg), id, tf); + gtk_tooltips_set_tip (tt, tf, tip, NULL); + g_signal_connect ( G_OBJECT (tf), "activate", G_CALLBACK (sp_find_dialog_find), dlg ); + gtk_label_set_mnemonic_widget (GTK_LABEL(l), tf); + + gtk_box_pack_start (GTK_BOX (vb), hb, FALSE, FALSE, 0); +} + +void +sp_find_new_button (GtkWidget *dlg, GtkWidget *hb, const gchar *label, GtkTooltips *tt, const gchar *tip, void (*function) (GObject *, GObject *)) +{ + GtkWidget *b = gtk_button_new_with_mnemonic (label); + gtk_tooltips_set_tip (tt, b, tip, NULL); + gtk_box_pack_start (GTK_BOX (hb), b, TRUE, TRUE, 0); + g_signal_connect ( G_OBJECT (b), "clicked", G_CALLBACK (function), dlg ); + gtk_widget_show (b); +} + +void +toggle_alltypes (GtkToggleButton *tb, gpointer data) +{ + GtkWidget *alltypes_pane = GTK_WIDGET (gtk_object_get_data (GTK_OBJECT (data), "all-pane")); + if (gtk_toggle_button_get_active (tb)) { + gtk_widget_hide_all (alltypes_pane); + } else { + gtk_widget_show_all (alltypes_pane); + + // excplicit toggle to make sure its handler gets called, no matter what was the original state + gtk_toggle_button_toggled (GTK_TOGGLE_BUTTON (gtk_object_get_data (GTK_OBJECT (data), "shapes"))); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (gtk_object_get_data (GTK_OBJECT (data), "shapes")), TRUE); + + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (gtk_object_get_data (GTK_OBJECT (data), "paths")), TRUE); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (gtk_object_get_data (GTK_OBJECT (data), "texts")), TRUE); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (gtk_object_get_data (GTK_OBJECT (data), "groups")), TRUE); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (gtk_object_get_data (GTK_OBJECT (data), "clones")), TRUE); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (gtk_object_get_data (GTK_OBJECT (data), "images")), TRUE); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (gtk_object_get_data (GTK_OBJECT (data), "offsets")), TRUE); + } + sp_find_squeeze_window(); +} + +void +toggle_shapes (GtkToggleButton *tb, gpointer data) +{ + GtkWidget *shapes_pane = GTK_WIDGET (gtk_object_get_data (GTK_OBJECT (data), "shapes-pane")); + if (gtk_toggle_button_get_active (tb)) { + gtk_widget_hide_all (shapes_pane); + } else { + gtk_widget_show_all (shapes_pane); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (gtk_object_get_data (GTK_OBJECT (data), "rects")), FALSE); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (gtk_object_get_data (GTK_OBJECT (data), "ellipses")), FALSE); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (gtk_object_get_data (GTK_OBJECT (data), "stars")), FALSE); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (gtk_object_get_data (GTK_OBJECT (data), "spirals")), FALSE); + } + sp_find_squeeze_window(); +} + + +GtkWidget * +sp_find_types_checkbox (GtkWidget *w, const gchar *data, gboolean active, + GtkTooltips *tt, const gchar *tip, + const gchar *label, + void (*toggled)(GtkToggleButton *, gpointer)) +{ + GtkWidget *hb = gtk_hbox_new (FALSE, 0); + gtk_widget_show (hb); + + { + GtkWidget *b = gtk_check_button_new_with_label (label); + gtk_widget_show (b); + gtk_toggle_button_set_active ((GtkToggleButton *) b, active); + gtk_object_set_data (GTK_OBJECT (w), data, b); + gtk_tooltips_set_tip (GTK_TOOLTIPS (tt), b, tip, NULL); + if (toggled) + gtk_signal_connect (GTK_OBJECT (b), "toggled", GTK_SIGNAL_FUNC (toggled), w); + gtk_box_pack_start (GTK_BOX (hb), b, FALSE, FALSE, 0); + } + + return hb; +} + +GtkWidget * +sp_find_types_checkbox_indented (GtkWidget *w, const gchar *data, gboolean active, + GtkTooltips *tt, const gchar *tip, + const gchar *label, + void (*toggled)(GtkToggleButton *, gpointer), guint indent) +{ + GtkWidget *hb = gtk_hbox_new (FALSE, 0); + gtk_widget_show (hb); + + { // empty label for indent + GtkWidget *l = gtk_label_new (""); + gtk_widget_show (l); + gtk_widget_set_size_request (l, FIND_LABELWIDTH + indent, -1); + gtk_box_pack_start (GTK_BOX (hb), l, FALSE, FALSE, 0); + } + + GtkWidget *c = sp_find_types_checkbox (w, data, active, tt, tip, label, toggled); + gtk_box_pack_start (GTK_BOX (hb), c, FALSE, FALSE, 0); + + return hb; +} + + +GtkWidget * +sp_find_types () +{ + GtkTooltips *tt = gtk_tooltips_new (); + + GtkWidget *vb = gtk_vbox_new (FALSE, 4); + gtk_widget_show (vb); + + { + GtkWidget *hb = gtk_hbox_new (FALSE, 0); + gtk_widget_show (hb); + + { + GtkWidget *l = gtk_label_new_with_mnemonic (_("T_ype: ")); + gtk_widget_show (l); + gtk_widget_set_size_request (l, FIND_LABELWIDTH, -1); + gtk_misc_set_alignment (GTK_MISC (l), 1.0, 0.5); + gtk_box_pack_start (GTK_BOX (hb), l, FALSE, FALSE, 0); + } + + GtkWidget *alltypes = sp_find_types_checkbox (vb, "all", TRUE, tt, _("Search in all object types"), _("All types"), toggle_alltypes); + gtk_box_pack_start (GTK_BOX (hb), alltypes, FALSE, FALSE, 0); + + gtk_box_pack_start (GTK_BOX (vb), hb, FALSE, FALSE, 0); + } + + { + GtkWidget *vb_all = gtk_vbox_new (FALSE, 0); + gtk_widget_show (vb_all); + + { + GtkWidget *c = sp_find_types_checkbox_indented (vb, "shapes", FALSE, tt, _("Search all shapes"), _("All shapes"), toggle_shapes, 10); + gtk_box_pack_start (GTK_BOX (vb_all), c, FALSE, FALSE, 0); + } + + + { + GtkWidget *hb = gtk_hbox_new (FALSE, 0); + gtk_widget_show (hb); + + { // empty label for alignment + GtkWidget *l = gtk_label_new (""); + gtk_widget_show (l); + gtk_widget_set_size_request (l, FIND_LABELWIDTH + 20, -1); + gtk_box_pack_start (GTK_BOX (hb), l, FALSE, FALSE, 0); + } + + { + GtkWidget *c = sp_find_types_checkbox (vb, "rects", FALSE, tt, _("Search rectangles"), _("Rectangles"), NULL); + gtk_box_pack_start (GTK_BOX (hb), c, FALSE, FALSE, 0); + } + + { + GtkWidget *c = sp_find_types_checkbox (vb, "ellipses", FALSE, tt, _("Search ellipses, arcs, circles"), _("Ellipses"), NULL); + gtk_box_pack_start (GTK_BOX (hb), c, FALSE, FALSE, 0); + } + + { + GtkWidget *c = sp_find_types_checkbox (vb, "stars", FALSE, tt, _("Search stars and polygons"), _("Stars"), NULL); + gtk_box_pack_start (GTK_BOX (hb), c, FALSE, FALSE, 0); + } + + { + GtkWidget *c = sp_find_types_checkbox (vb, "spirals", FALSE, tt, _("Search spirals"), _("Spirals"), NULL); + gtk_box_pack_start (GTK_BOX (hb), c, FALSE, FALSE, 0); + } + + gtk_object_set_data (GTK_OBJECT (vb), "shapes-pane", hb); + + gtk_box_pack_start (GTK_BOX (vb_all), hb, FALSE, FALSE, 0); + gtk_widget_hide_all (hb); + } + + { + // TRANSLATORS: polyline is a set of connected straight line segments + // http://www.w3.org/TR/SVG11/shapes.html#PolylineElement + GtkWidget *c = sp_find_types_checkbox_indented (vb, "paths", TRUE, tt, _("Search paths, lines, polylines"), _("Paths"), NULL, 10); + gtk_box_pack_start (GTK_BOX (vb_all), c, FALSE, FALSE, 0); + } + + { + GtkWidget *c = sp_find_types_checkbox_indented (vb, "texts", TRUE, tt, _("Search text objects"), _("Texts"), NULL, 10); + gtk_box_pack_start (GTK_BOX (vb_all), c, FALSE, FALSE, 0); + } + + { + GtkWidget *c = sp_find_types_checkbox_indented (vb, "groups", TRUE, tt, _("Search groups"), _("Groups"), NULL, 10); + gtk_box_pack_start (GTK_BOX (vb_all), c, FALSE, FALSE, 0); + } + + { + GtkWidget *c = sp_find_types_checkbox_indented (vb, "clones", TRUE, tt, _("Search clones"), _("Clones"), NULL, 10); + gtk_box_pack_start (GTK_BOX (vb_all), c, FALSE, FALSE, 0); + } + + { + GtkWidget *c = sp_find_types_checkbox_indented (vb, "images", TRUE, tt, _("Search images"), _("Images"), NULL, 10); + gtk_box_pack_start (GTK_BOX (vb_all), c, FALSE, FALSE, 0); + } + + { + GtkWidget *c = sp_find_types_checkbox_indented (vb, "offsets", TRUE, tt, _("Search offset objects"), _("Offsets"), NULL, 10); + gtk_box_pack_start (GTK_BOX (vb_all), c, FALSE, FALSE, 0); + } + + gtk_box_pack_start (GTK_BOX (vb), vb_all, FALSE, FALSE, 0); + gtk_object_set_data (GTK_OBJECT (vb), "all-pane", vb_all); + gtk_widget_hide_all (vb_all); + } + + return vb; +} + + +GtkWidget * +sp_find_dialog_old (void) +{ + if (!dlg) + { + gchar title[500]; + sp_ui_dialog_title_string (Inkscape::Verb::get(SP_VERB_DIALOG_FIND), title); + + dlg = sp_window_new (title, TRUE); + if (x == -1000 || y == -1000) { + x = prefs_get_int_attribute (prefs_path, "x", 0); + y = prefs_get_int_attribute (prefs_path, "y", 0); + } + if (w ==0 || h == 0) { + w = prefs_get_int_attribute (prefs_path, "w", 0); + h = prefs_get_int_attribute (prefs_path, "h", 0); + } + if (x != 0 || y != 0) { + gtk_window_move ((GtkWindow *) dlg, x, y); + } else { + gtk_window_set_position(GTK_WINDOW(dlg), GTK_WIN_POS_CENTER); + } + if (w && h) + gtk_window_resize ((GtkWindow *) dlg, w, h); + + sp_transientize (dlg); + wd.win = dlg; + wd.stop = 0; + g_signal_connect ( G_OBJECT (INKSCAPE), "activate_desktop", G_CALLBACK (sp_transientize_callback), &wd ); + + gtk_signal_connect ( GTK_OBJECT (dlg), "event", GTK_SIGNAL_FUNC (sp_dialog_event_handler), dlg); + + gtk_signal_connect ( GTK_OBJECT (dlg), "destroy", G_CALLBACK (sp_find_dialog_destroy), NULL ); + gtk_signal_connect ( GTK_OBJECT (dlg), "delete_event", G_CALLBACK (sp_find_dialog_delete), dlg); + g_signal_connect ( G_OBJECT (INKSCAPE), "shut_down", G_CALLBACK (sp_find_dialog_delete), dlg); + + g_signal_connect ( G_OBJECT (INKSCAPE), "dialogs_hide", G_CALLBACK (sp_dialog_hide), dlg); + g_signal_connect ( G_OBJECT (INKSCAPE), "dialogs_unhide", G_CALLBACK (sp_dialog_unhide), dlg); + + GtkTooltips *tt = gtk_tooltips_new (); + + gtk_container_set_border_width (GTK_CONTAINER (dlg), 4); + + /* Toplevel vbox */ + GtkWidget *vb = gtk_vbox_new (FALSE, 0); + gtk_container_add (GTK_CONTAINER (dlg), vb); + + sp_find_new_searchfield (dlg, vb, _("_Text: "), "text", tt, _("Find objects by their text content (exact or partial match)")); + sp_find_new_searchfield (dlg, vb, _("_ID: "), "id", tt, _("Find objects by the value of the id attribute (exact or partial match)")); + sp_find_new_searchfield (dlg, vb, _("_Style: "), "style", tt, _("Find objects by the value of the style attribute (exact or partial match)")); + sp_find_new_searchfield (dlg, vb, _("_Attribute: "), "attr", tt ,_("Find objects by the name of an attribute (exact or partial match)")); + + gtk_widget_show_all (vb); + + GtkWidget *types = sp_find_types (); + gtk_object_set_data (GTK_OBJECT (dlg), "types", types); + gtk_box_pack_start (GTK_BOX (vb), types, FALSE, FALSE, 0); + + { + GtkWidget *w = gtk_hseparator_new (); + gtk_widget_show (w); + gtk_box_pack_start (GTK_BOX (vb), w, FALSE, FALSE, 3); + + { + GtkWidget *b = gtk_check_button_new_with_mnemonic (_("Search in s_election")); + gtk_widget_show (b); + gtk_toggle_button_set_active ((GtkToggleButton *) b, FALSE); + gtk_object_set_data (GTK_OBJECT (dlg), "inselection", b); + gtk_tooltips_set_tip (GTK_TOOLTIPS (tt), b, _("Limit search to the current selection"), NULL); + gtk_box_pack_start (GTK_BOX (vb), b, FALSE, FALSE, 0); + } + + { + GtkWidget *b = gtk_check_button_new_with_mnemonic (_("Search in current _layer")); + gtk_widget_show (b); + gtk_toggle_button_set_active ((GtkToggleButton *) b, FALSE); + gtk_object_set_data (GTK_OBJECT (dlg), "inlayer", b); + gtk_tooltips_set_tip (GTK_TOOLTIPS (tt), b, _("Limit search to the current layer"), NULL); + gtk_box_pack_start (GTK_BOX (vb), b, FALSE, FALSE, 0); + } + + { + GtkWidget *b = gtk_check_button_new_with_mnemonic (_("Include _hidden")); + gtk_widget_show (b); + gtk_toggle_button_set_active ((GtkToggleButton *) b, FALSE); + gtk_object_set_data (GTK_OBJECT (dlg), "includehidden", b); + gtk_tooltips_set_tip (GTK_TOOLTIPS (tt), b, _("Include hidden objects in search"), NULL); + gtk_box_pack_start (GTK_BOX (vb), b, FALSE, FALSE, 0); + } + + { + GtkWidget *b = gtk_check_button_new_with_mnemonic (_("Include l_ocked")); + gtk_widget_show (b); + gtk_toggle_button_set_active ((GtkToggleButton *) b, FALSE); + gtk_object_set_data (GTK_OBJECT (dlg), "includelocked", b); + gtk_tooltips_set_tip (GTK_TOOLTIPS (tt), b, _("Include locked objects in search"), NULL); + gtk_box_pack_start (GTK_BOX (vb), b, FALSE, FALSE, 0); + } + } + + { + GtkWidget *hb = gtk_hbox_new (FALSE, 0); + gtk_widget_show (hb); + gtk_box_pack_start (GTK_BOX (vb), hb, FALSE, FALSE, 0); + + // TRANSLATORS: "Clear" is a verb here + sp_find_new_button (dlg, hb, _("_Clear"), tt, _("Clear values"), sp_find_dialog_reset); + sp_find_new_button (dlg, hb, _("_Find"), tt, _("Select objects matching all of the fields you filled in"), sp_find_dialog_find); + } + } + + gtk_widget_show((GtkWidget *) dlg); + gtk_window_present ((GtkWindow *) dlg); + sp_find_dialog_reset (NULL, G_OBJECT (dlg)); + + return dlg; +} + + +/* + 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:textwidth=99 : diff --git a/src/dialogs/find.h b/src/dialogs/find.h new file mode 100644 index 000000000..38200d532 --- /dev/null +++ b/src/dialogs/find.h @@ -0,0 +1,31 @@ +#ifndef SEEN_FIND_H +#define SEEN_FIND_H + +/** + * \brief Find dialog + * + * Authors: + * bulia byak + * + * Copyright (C) 2004 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include + +void sp_find_dialog(); + + +#endif /* !SEEN_FIND_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 : diff --git a/src/dialogs/iconpreview.cpp b/src/dialogs/iconpreview.cpp new file mode 100644 index 000000000..b3ea55df3 --- /dev/null +++ b/src/dialogs/iconpreview.cpp @@ -0,0 +1,320 @@ +/* + * A simple dialog for previewing icon representation. + * + * Authors: + * Jon A. Cruz + * Bob Jamison + * Other dudes from The Inkscape Organization + * + * Copyright (C) 2004 Bob Jamison + * Copyright (C) 2005 Jon A. Cruz + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "iconpreview.h" + +#include + +#include //for GTK_RESPONSE* types +#include +#include +#include + +#include "prefs-utils.h" +#include "inkscape.h" +#include "document.h" +#include "desktop-handles.h" +#include "selection.h" +#include "desktop.h" +#include "display/nr-arena.h" +#include "sp-root.h" +#include "xml/repr.h" + +extern "C" { +// takes doc, root, icon, and icon name to produce pixels +guchar * +sp_icon_doc_icon( SPDocument *doc, NRArenaItem *root, + const gchar *name, unsigned int psize ); +} + +namespace Inkscape { +namespace UI { +namespace Dialogs { + + +IconPreviewPanel* IconPreviewPanel::instance = 0; + + +IconPreviewPanel& IconPreviewPanel::getInstance() +{ + if ( !instance ) { + instance = new IconPreviewPanel(); + } + + instance->refreshPreview(); + + return *instance; +} + +//######################################################################### +//## E V E N T S +//######################################################################### + +void IconPreviewPanel::on_button_clicked(int which) +{ + if ( hot != which ) { + buttons[hot]->set_active( false ); + + hot = which; + updateMagnify(); + queue_draw(); + } +} + + + + +//######################################################################### +//## C O N S T R U C T O R / D E S T R U C T O R +//######################################################################### +/** + * Constructor + */ +IconPreviewPanel::IconPreviewPanel() : + Panel(), + hot(1), + refreshButton(0), + selectionButton(0) +{ + numEntries = 0; + Inkscape::XML::Node *things = inkscape_get_repr(INKSCAPE, "iconpreview.sizes.default"); + if (things) { + std::vector rawSizes; + for ( Inkscape::XML::Node *child = things->firstChild(); child; child = child->next() ) + { + gchar const *id = child->attribute("id"); + if ( id ) + { + std::string path("iconpreview.sizes.default."); + path += id; + gint show = prefs_get_int_attribute_limited( path.c_str(), "show", 1, 0, 1 ); + gint sizeVal = prefs_get_int_attribute( path.c_str(), "value", -1 ); + if ( show && (sizeVal > 0) ) + { + rawSizes.push_back( sizeVal ); + } + } + } + + if ( !rawSizes.empty() ) + { + numEntries = rawSizes.size(); + sizes = new int[numEntries]; + int i = 0; + for ( std::vector::iterator it = rawSizes.begin(); it != rawSizes.end(); ++it, ++i ) { + sizes[i] = *it; + } + } + } + + if ( numEntries < 1 ) + { + numEntries = 5; + sizes = new int[numEntries]; + sizes[0] = 16; + sizes[1] = 24; + sizes[2] = 32; + sizes[3] = 48; + sizes[5] = 128; + } + + pixMem = new guchar*[numEntries]; + images = new Gtk::Image*[numEntries]; + labels = new Glib::ustring*[numEntries]; + buttons = new Gtk::ToggleToolButton*[numEntries]; + + + for ( int i = 0; i < numEntries; i++ ) { + char *label = g_strdup_printf(_("%d x %d"), sizes[i], sizes[i]); + labels[i] = new Glib::ustring(label); + g_free(label); + pixMem[i] = 0; + images[i] = 0; + } + + + magLabel.set_label( *labels[hot] ); + + Gtk::VBox* magBox = new Gtk::VBox(); + + magBox->pack_start( magnified ); + magBox->pack_start( magLabel, Gtk::PACK_SHRINK ); + + + Gtk::VBox * verts = new Gtk::VBox(); + for ( int i = 0; i < numEntries; i++ ) { + pixMem[i] = new guchar[4 * sizes[i] * sizes[i]]; + memset( pixMem[i], 0x00, 4 * sizes[i] * sizes[i] ); + + GdkPixbuf *pb = gdk_pixbuf_new_from_data( pixMem[i], GDK_COLORSPACE_RGB, TRUE, 8, sizes[i], sizes[i], sizes[i] * 4, /*(GdkPixbufDestroyNotify)nr_free*/NULL, NULL ); + GtkImage* img = GTK_IMAGE( gtk_image_new_from_pixbuf( pb ) ); + images[i] = Glib::wrap(img); + Glib::ustring label(*labels[i]); + buttons[i] = new Gtk::ToggleToolButton(label); + buttons[i]->set_active( i == hot ); + buttons[i]->set_icon_widget(*images[i]); + + tips.set_tip((*buttons[i]), label); + + buttons[i]->signal_clicked().connect( sigc::bind( sigc::mem_fun(*this, &IconPreviewPanel::on_button_clicked), i) ); + + + verts->add(*buttons[i]); + } + + iconBox.pack_start(splitter); + splitter.pack1( *magBox, true, true ); + splitter.pack2( *verts, false, false ); + + + //## The Refresh button + + + Gtk::HButtonBox* holder = new Gtk::HButtonBox( Gtk::BUTTONBOX_END ); + pack_end( *holder, false, false ); + + selectionButton = new Gtk::ToggleButton(_("Selection")); // , GTK_RESPONSE_APPLY + holder->pack_start( *selectionButton, false, false ); + tips.set_tip((*selectionButton), _("Selection only or whole document")); + selectionButton->signal_clicked().connect( sigc::mem_fun(*this, &IconPreviewPanel::modeToggled) ); + + gint val = prefs_get_int_attribute_limited( "iconpreview", "selectionOnly", 0, 0, 1 ); + selectionButton->set_active( val != 0 ); + + refreshButton = new Gtk::Button(Gtk::Stock::REFRESH); // , GTK_RESPONSE_APPLY + holder->pack_end( *refreshButton, false, false ); + tips.set_tip((*refreshButton), _("Refresh the icons")); + refreshButton->signal_clicked().connect( sigc::mem_fun(*this, &IconPreviewPanel::refreshPreview) ); + + + pack_start(iconBox, Gtk::PACK_EXPAND_WIDGET); + + show_all_children(); +} + +//######################################################################### +//## M E T H O D S +//######################################################################### + + +void IconPreviewPanel::refreshPreview() +{ + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + if ( desktop ) { + + if ( selectionButton && selectionButton->get_active() ) + { + Inkscape::Selection * sel = SP_DT_SELECTION(desktop); + if ( sel ) { + //g_message("found a selection to play with"); + + GSList const *items = sel->itemList(); + SPObject *target = 0; + while ( items && !target ) { + SPItem* item = SP_ITEM( items->data ); + SPObject * obj = SP_OBJECT(item); + gchar const *id = SP_OBJECT_ID( obj ); + if ( id ) { + target = obj; + } + + items = g_slist_next(items); + } + if ( target ) { + renderPreview(target); + } + } + } + else + { + SPObject *target = desktop->currentRoot(); + if ( target ) { + renderPreview(target); + } + } + } +} + +void IconPreviewPanel::modeToggled() +{ + prefs_set_int_attribute( "iconpreview", "selectionOnly", (selectionButton && selectionButton->get_active()) ? 1 : 0 ); + + refreshPreview(); +} + +void IconPreviewPanel::renderPreview( SPObject* obj ) +{ + SPDocument * doc = SP_OBJECT_DOCUMENT(obj); + gchar * id = SP_OBJECT_ID(obj); + +// g_message(" setting up to render '%s' as the icon", id ); + + NRArenaItem *root = NULL; + + /* Create new arena */ + NRArena *arena = NRArena::create(); + + /* Create ArenaItem and set transform */ + unsigned int visionkey = sp_item_display_key_new(1); + + /* fixme: Memory manage root if needed (Lauris) */ + root = sp_item_invoke_show ( SP_ITEM( SP_DOCUMENT_ROOT(doc) ), + arena, visionkey, SP_ITEM_SHOW_DISPLAY ); + + for ( int i = 0; i < numEntries; i++ ) { + guchar * px = sp_icon_doc_icon( doc, root, id, sizes[i] ); +// g_message( " size %d %s", sizes[i], (px ? "worked" : "failed") ); + if ( px ) { + memcpy( pixMem[i], px, sizes[i] * sizes[i] * 4 ); + g_free( px ); + px = 0; + } else { + memset( pixMem[i], 0, sizes[i] * sizes[i] * 4 ); + } + images[i]->queue_draw(); + } + updateMagnify(); +} + +void IconPreviewPanel::updateMagnify() +{ + Glib::RefPtr buf = images[hot]->get_pixbuf()->scale_simple( 128, 128, Gdk::INTERP_NEAREST ); + magLabel.set_label( *labels[hot] ); + magnified.set( buf ); + magnified.queue_draw(); + magnified.get_parent()->queue_draw(); +} + + +} //namespace Dialogs +} //namespace UI +} //namespace Inkscape + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : + +//######################################################################### +//## E N D O F F I L E +//######################################################################### diff --git a/src/dialogs/iconpreview.h b/src/dialogs/iconpreview.h new file mode 100644 index 000000000..e4be831d3 --- /dev/null +++ b/src/dialogs/iconpreview.h @@ -0,0 +1,84 @@ +#ifndef SEEN_ICON_PREVIEW_H +#define SEEN_ICON_PREVIEW_H +/* + * A simple dialog for previewing icon representation. + * + * Authors: + * Jon A. Cruz + * Bob Jamison + * Other dudes from The Inkscape Organization + * + * Copyright (C) 2004,2005 The Inkscape Organization + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include +#include +#include +#include +#include +#include + +#include "ui/widget/panel.h" + +struct SPObject; + +namespace Inkscape { +namespace UI { +namespace Dialogs { + + +/** + * A panel that displays an icon preview + */ +class IconPreviewPanel : public Inkscape::UI::Widget::Panel +{ +public: + IconPreviewPanel(); + //IconPreviewPanel(Glib::ustring const &label); + + static IconPreviewPanel& getInstance(); + + void refreshPreview(); + void modeToggled(); + +private: + IconPreviewPanel(IconPreviewPanel const &); // no copy + IconPreviewPanel &operator=(IconPreviewPanel const &); // no assign + + + void on_button_clicked(int which); + void renderPreview( SPObject* obj ); + void updateMagnify(); + + static IconPreviewPanel* instance; + + Gtk::Tooltips tips; + + Gtk::VBox iconBox; + Gtk::HPaned splitter; + + int hot; + int numEntries; + int* sizes; + + Gtk::Image magnified; + Gtk::Label magLabel; + + Gtk::Button *refreshButton; + Gtk::ToggleButton *selectionButton; + + guchar** pixMem; + Gtk::Image** images; + Glib::ustring** labels; + Gtk::ToggleToolButton** buttons; +}; + +} //namespace Dialogs +} //namespace UI +} //namespace Inkscape + + + +#endif // SEEN_ICON_PREVIEW_H diff --git a/src/dialogs/in-dt-coordsys.cpp b/src/dialogs/in-dt-coordsys.cpp new file mode 100644 index 000000000..54d9ac326 --- /dev/null +++ b/src/dialogs/in-dt-coordsys.cpp @@ -0,0 +1,37 @@ +#include "sp-root.h" + +/** Returns true iff \a item is suitable to be included in the selection, in particular + whether it has a bounding box in the desktop coordinate system for rendering resize handles. + + Descendents of nodes (markers etc.) return false, for example. +*/ +bool in_dt_coordsys(SPObject const &item) +{ + /* Definition based on sp_item_i2doc_affine. */ + SPObject const *child = &item; + g_return_val_if_fail(child != NULL, false); + for(;;) { + if (!SP_IS_ITEM(child)) { + return false; + } + SPObject const * const parent = SP_OBJECT_PARENT(child); + if (parent == NULL) { + break; + } + child = parent; + } + g_assert(SP_IS_ROOT(child)); + /* Relevance: Otherwise, I'm not sure whether to return true or false. */ + return true; +} + +/* + 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:textwidth=99 : diff --git a/src/dialogs/in-dt-coordsys.h b/src/dialogs/in-dt-coordsys.h new file mode 100644 index 000000000..6078f9b41 --- /dev/null +++ b/src/dialogs/in-dt-coordsys.h @@ -0,0 +1,19 @@ +#ifndef SEEN_IN_DT_COORDSYS +#define SEEN_IN_DT_COORDSYS +#include "forward.h" + +bool in_dt_coordsys(SPObject const &item); + + +#endif /* !SEEN_IN_DT_COORDSYS */ + +/* + 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:textwidth=99 : diff --git a/src/dialogs/input.cpp b/src/dialogs/input.cpp new file mode 100644 index 000000000..da8eba196 --- /dev/null +++ b/src/dialogs/input.cpp @@ -0,0 +1,273 @@ +#define __SP_INPUT_C__ + +/* + * Extended input devices dialog + * + * Authors: + * Nicklas Lindgren + * + * Copyright (C) 2005 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif +#include + +#include "../inkscape.h" +#include "../macros.h" +#include "../verbs.h" +#include "../interface.h" +#include "../xml/repr.h" + +#include "dialog-events.h" +#include "../prefs-utils.h" + + +static GtkWidget *dlg = NULL; +static win_data wd; + +// impossible original values to make sure they are read from prefs +static gint x = -1000, y = -1000, w = 0, h = 0; +static gchar *prefs_path = "dialogs.input"; + +static void +sp_input_dialog_destroy (GtkObject *object, gpointer data) +{ + sp_signal_disconnect_by_data (INKSCAPE, dlg); + wd.win = dlg = NULL; + wd.stop = 0; +} + +static gboolean +sp_input_dialog_delete (GtkObject *object, GdkEvent *event, gpointer data) +{ + gtk_window_get_position ((GtkWindow *) dlg, &x, &y); + gtk_window_get_size ((GtkWindow *) dlg, &w, &h); + + prefs_set_int_attribute (prefs_path, "x", x); + prefs_set_int_attribute (prefs_path, "y", y); + prefs_set_int_attribute (prefs_path, "w", w); + prefs_set_int_attribute (prefs_path, "h", h); + + return FALSE; // which means, go ahead and destroy it + +} + +static gchar *axis_use_strings[GDK_AXIS_LAST] = { + "ignore", "x", "y", "pressure", "xtilt", "ytilt", "wheel" +}; + +void +sp_input_load_from_preferences (void) +{ + Inkscape::XML::Node *devices = inkscape_get_repr(INKSCAPE, "devices"); + if (devices == NULL) + return; + + Inkscape::XML::Node *repr; + GList *list_ptr; + + for (list_ptr = gdk_devices_list(); list_ptr != NULL; list_ptr = list_ptr->next) { + GdkDevice *device = static_cast(list_ptr->data); + repr = sp_repr_lookup_child(devices, "id", device->name); + if (repr != NULL) { + GdkInputMode mode; + const gchar *attribute = repr->attribute("mode"); + + if (attribute == NULL) + mode = GDK_MODE_DISABLED; + else if (!strcmp(attribute, "screen")) + mode = GDK_MODE_SCREEN; + else if (!strcmp(attribute, "window")) + mode = GDK_MODE_WINDOW; + else + mode = GDK_MODE_DISABLED; + + if (device->mode != mode) { + gdk_device_set_mode(device, mode); + } + + const gchar *temp_ptr; + std::string::size_type pos0; + std::string::size_type pos1; + gint i; + gint j; + + GdkAxisUse axis_use; + + temp_ptr = repr->attribute("axes"); + if (temp_ptr != NULL) { + const std::string temp_str = temp_ptr; + pos0 = pos1 = 0; + for (i=0; i < device->num_axes; i++) { + pos1 = temp_str.find(";", pos0); + if (pos1 == std::string::npos) + break; // Too few axis specifications + + axis_use = GDK_AXIS_IGNORE; + for (j=0; j < GDK_AXIS_LAST; j++) + if (!strcmp(temp_str.substr(pos0, pos1-pos0).c_str(), axis_use_strings[j])) { + axis_use = static_cast(j); + break; + } + gdk_device_set_axis_use(device, i, axis_use); + pos0 = pos1 + 1; + } + } + + guint keyval; + GdkModifierType modifier; + + temp_ptr = repr->attribute("keys"); + if (temp_ptr != NULL) { + const std::string temp_str = temp_ptr; + pos0 = pos1 = 0; + for (i=0; i < device->num_keys; i++) { + pos1 = temp_str.find(";", pos0); + if (pos1 == std::string::npos) + break; // Too few key specifications + + gtk_accelerator_parse(temp_str.substr(pos0, pos1-pos0).c_str(), &keyval, &modifier); + gdk_device_set_key(device, i, keyval, modifier); + pos0 = pos1 + 1; + } + } + } + } +} + +void +sp_input_save_to_preferences (void) +{ + Inkscape::XML::Node *devices = inkscape_get_repr(INKSCAPE, "devices"); + if (devices == NULL) + // TODO: find a clean way to add a node to the preferences root, or + // give an error message + return; + + Inkscape::XML::Node *repr; + GList *list_ptr; + + for (list_ptr = gdk_devices_list(); list_ptr != NULL; list_ptr = list_ptr->next) { + gint i; + std::string temp_attribute; + GdkDevice *device = static_cast(list_ptr->data); + + repr = sp_repr_lookup_child(devices, "id", device->name); + if (repr == NULL) { + repr = sp_repr_new("group"); + repr->setAttribute("id", device->name); + devices->appendChild(repr); + Inkscape::GC::release(repr); + } + switch (device->mode) { + default: + case GDK_MODE_DISABLED: { + repr->setAttribute("mode", "disabled"); + break; + } + case GDK_MODE_SCREEN: { + repr->setAttribute("mode", "screen"); + break; + } + case GDK_MODE_WINDOW: { + repr->setAttribute("mode", "window"); + break; + } + } + + temp_attribute = ""; + for (i=0; i < device->num_axes; i++) { + temp_attribute += axis_use_strings[device->axes[i].use]; + temp_attribute += ";"; + } + repr->setAttribute("axes", temp_attribute.c_str()); + + temp_attribute = ""; + for (i=0; i < device->num_keys; i++) { + temp_attribute += gtk_accelerator_name(device->keys[i].keyval, device->keys[i].modifiers); + temp_attribute += ";"; + } + repr->setAttribute("keys", temp_attribute.c_str()); + } +} + +static void +sp_input_save_button (GtkObject *object, gpointer data) +{ + sp_input_save_to_preferences(); +} + +/** + * \brief Dialog + * + */ +void +sp_input_dialog (void) +{ + if (dlg == NULL) { + + gchar title[500]; + sp_ui_dialog_title_string (Inkscape::Verb::get(SP_VERB_DIALOG_INPUT), title); + + dlg = gtk_input_dialog_new(); + + if (x == -1000 || y == -1000) { + x = prefs_get_int_attribute (prefs_path, "x", 0); + y = prefs_get_int_attribute (prefs_path, "y", 0); + } + + if (w ==0 || h == 0) { + w = prefs_get_int_attribute (prefs_path, "w", 0); + h = prefs_get_int_attribute (prefs_path, "h", 0); + } + + if (x != 0 || y != 0) { + gtk_window_move ((GtkWindow *) dlg, x, y); + } else { + gtk_window_set_position(GTK_WINDOW(dlg), GTK_WIN_POS_CENTER); + } + + if (w && h) { + gtk_window_resize ((GtkWindow *) dlg, w, h); + } + + sp_transientize (dlg); + wd.win = dlg; + wd.stop = 0; + + g_signal_connect ( G_OBJECT (INKSCAPE), "activate_desktop", G_CALLBACK (sp_transientize_callback), &wd); + gtk_signal_connect ( GTK_OBJECT (dlg), "event", GTK_SIGNAL_FUNC (sp_dialog_event_handler), dlg); + gtk_signal_connect ( GTK_OBJECT (dlg), "destroy", G_CALLBACK (sp_input_dialog_destroy), dlg); + gtk_signal_connect ( GTK_OBJECT (dlg), "delete_event", G_CALLBACK (sp_input_dialog_delete), dlg); + g_signal_connect ( G_OBJECT (INKSCAPE), "shut_down", G_CALLBACK (sp_input_dialog_delete), dlg); + g_signal_connect ( G_OBJECT (INKSCAPE), "dialogs_hide", G_CALLBACK (sp_dialog_hide), dlg); + g_signal_connect ( G_OBJECT (INKSCAPE), "dialogs_unhide", G_CALLBACK (sp_dialog_unhide), dlg); + + // Dialog-specific stuff + gtk_signal_connect_object (GTK_OBJECT(GTK_INPUT_DIALOG(dlg)->close_button), + "clicked", + (GtkSignalFunc)gtk_widget_destroy, + GTK_OBJECT(dlg)); + gtk_signal_connect (GTK_OBJECT(GTK_INPUT_DIALOG(dlg)->save_button), + "clicked", + (GtkSignalFunc)sp_input_save_button, NULL); + } + + gtk_window_present ((GtkWindow *) dlg); +} + + +/* + 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:textwidth=99 : diff --git a/src/dialogs/input.h b/src/dialogs/input.h new file mode 100644 index 000000000..70e68774e --- /dev/null +++ b/src/dialogs/input.h @@ -0,0 +1,32 @@ +#ifndef __SP_INPUT_H__ +#define __SP_INPUT_H__ + +/** + * \brief Extended input device dialog + * + * Author: + * Nicklas Lindgren + * + * Copyright (C) 2005 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + + +void sp_input_load_from_preferences (void); +void sp_input_save_to_preferences (void); +void sp_input_dialog (void); + + +#endif + +/* + 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:textwidth=99 : diff --git a/src/dialogs/item-properties.cpp b/src/dialogs/item-properties.cpp new file mode 100644 index 000000000..a8031b13e --- /dev/null +++ b/src/dialogs/item-properties.cpp @@ -0,0 +1,497 @@ +#define __SP_ITEM_PROPERTIES_C__ + +/* + * Object properties dialog + * + * Authors: + * Lauris Kaplinski + * bulia byak + * + * Copyright (C) 1999-2005 Authors + * Copyright (C) 2001 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "helper/window.h" +#include "../widgets/sp-widget.h" +#include "../inkscape.h" +#include "../document.h" +#include "../desktop-handles.h" +#include "../selection.h" +#include "../sp-item.h" +#include "../macros.h" +#include "../verbs.h" +#include "../interface.h" + +#include "dialog-events.h" +#include "../prefs-utils.h" + + +static GtkWidget *dlg = NULL; +static win_data wd; + +// impossible original values to make sure they are read from prefs +static gint x = -1000, y = -1000, w = 0, h = 0; +static gchar *prefs_path = "dialogs.object"; + +static void sp_item_widget_modify_selection (SPWidget *spw, Inkscape::Selection *selection, guint flags, GtkWidget *itemw); +static void sp_item_widget_change_selection (SPWidget *spw, Inkscape::Selection *selection, GtkWidget *itemw); +static void sp_item_widget_setup (SPWidget *spw, Inkscape::Selection *selection); +static void sp_item_widget_sensitivity_toggled (GtkWidget *widget, SPWidget *spw); +static void sp_item_widget_hidden_toggled (GtkWidget *widget, SPWidget *spw); +static void sp_item_widget_label_changed (GtkWidget *widget, SPWidget *spw); + +static void +sp_item_dialog_destroy (GtkObject *object, gpointer data) +{ + sp_signal_disconnect_by_data (INKSCAPE, dlg); + wd.win = dlg = NULL; + wd.stop = 0; +} + +static gboolean +sp_item_dialog_delete (GtkObject *object, GdkEvent *event, gpointer data) +{ + gtk_window_get_position ((GtkWindow *) dlg, &x, &y); + gtk_window_get_size ((GtkWindow *) dlg, &w, &h); + + prefs_set_int_attribute (prefs_path, "x", x); + prefs_set_int_attribute (prefs_path, "y", y); + prefs_set_int_attribute (prefs_path, "w", w); + prefs_set_int_attribute (prefs_path, "h", h); + + return FALSE; // which means, go ahead and destroy it + +} + +/** + * \brief Creates new instance of item properties widget + * + */ +GtkWidget * +sp_item_widget_new (void) +{ + + GtkWidget *spw, *vb, *t, *cb, *l, *f, *tf, *pb; + GtkTextBuffer *desc_buffer; + + GtkTooltips *tt = gtk_tooltips_new(); + + /* Create container widget */ + spw = sp_widget_new_global (INKSCAPE); + gtk_signal_connect ( GTK_OBJECT (spw), "modify_selection", + GTK_SIGNAL_FUNC (sp_item_widget_modify_selection), + spw ); + gtk_signal_connect ( GTK_OBJECT (spw), "change_selection", + GTK_SIGNAL_FUNC (sp_item_widget_change_selection), + spw ); + + vb = gtk_vbox_new (FALSE, 0); + gtk_container_add (GTK_CONTAINER (spw), vb); + + t = gtk_table_new (3, 4, FALSE); + gtk_container_set_border_width(GTK_CONTAINER(t), 4); + gtk_table_set_row_spacings (GTK_TABLE (t), 4); + gtk_table_set_col_spacings (GTK_TABLE (t), 4); + gtk_box_pack_start (GTK_BOX (vb), t, TRUE, TRUE, 0); + + + /* Create the label for the object id */ + l = gtk_label_new_with_mnemonic (_("_Id")); + gtk_misc_set_alignment (GTK_MISC (l), 1, 0.5); + gtk_table_attach ( GTK_TABLE (t), l, 0, 1, 0, 1, + (GtkAttachOptions)( GTK_SHRINK | GTK_FILL ), + (GtkAttachOptions)0, 0, 0 ); + gtk_object_set_data (GTK_OBJECT (spw), "id_label", l); + + /* Create the entry box for the object id */ + tf = gtk_entry_new (); + gtk_tooltips_set_tip (tt, tf, _("The id= attribute (only letters, digits, and the characters .-_: allowed)"), NULL); + gtk_entry_set_max_length (GTK_ENTRY (tf), 64); + gtk_table_attach ( GTK_TABLE (t), tf, 1, 2, 0, 1, + (GtkAttachOptions)( GTK_EXPAND | GTK_FILL ), + (GtkAttachOptions)0, 0, 0 ); + gtk_object_set_data (GTK_OBJECT (spw), "id", tf); + gtk_label_set_mnemonic_widget (GTK_LABEL(l), tf); + + // pressing enter in the id field is the same as clicking Set: + g_signal_connect ( G_OBJECT (tf), "activate", G_CALLBACK (sp_item_widget_label_changed), spw); + // focus is in the id field initially: + gtk_widget_grab_focus (GTK_WIDGET (tf)); + + /* Button for setting the object's id, label, title and description. */ + pb = gtk_button_new_with_mnemonic (_("_Set")); + gtk_table_attach ( GTK_TABLE (t), pb, 2, 3, 0, 1, + (GtkAttachOptions)( GTK_SHRINK | GTK_FILL ), + (GtkAttachOptions)0, 0, 0 ); + gtk_signal_connect ( GTK_OBJECT (pb), "clicked", + GTK_SIGNAL_FUNC (sp_item_widget_label_changed), + spw ); + + /* Create the label for the object label */ + l = gtk_label_new_with_mnemonic (_("_Label")); + gtk_misc_set_alignment (GTK_MISC (l), 1, 0.5); + gtk_table_attach ( GTK_TABLE (t), l, 0, 1, 1, 2, + (GtkAttachOptions)( GTK_SHRINK | GTK_FILL ), + (GtkAttachOptions)0, 0, 0 ); + gtk_object_set_data (GTK_OBJECT (spw), "label_label", l); + + /* Create the entry box for the object label */ + tf = gtk_entry_new (); + gtk_tooltips_set_tip (tt, tf, _("A freeform label for the object"), NULL); + gtk_entry_set_max_length (GTK_ENTRY (tf), 256); + gtk_table_attach ( GTK_TABLE (t), tf, 1, 2, 1, 2, + (GtkAttachOptions)( GTK_EXPAND | GTK_FILL ), + (GtkAttachOptions)0, 0, 0 ); + gtk_object_set_data (GTK_OBJECT (spw), "label", tf); + gtk_label_set_mnemonic_widget (GTK_LABEL(l), tf); + + // pressing enter in the label field is the same as clicking Set: + g_signal_connect ( G_OBJECT (tf), "activate", G_CALLBACK (sp_item_widget_label_changed), spw); + + /* Create the label for the object title */ + l = gtk_label_new (_("Title")); + gtk_misc_set_alignment (GTK_MISC (l), 1, 0.5); + gtk_table_attach ( GTK_TABLE (t), l, 0, 1, 2, 3, + (GtkAttachOptions)( GTK_SHRINK | GTK_FILL ), + (GtkAttachOptions)0, 0, 0 ); + gtk_object_set_data (GTK_OBJECT (spw), "title_label", l); + + /* Create the entry box for the object title */ + tf = gtk_entry_new (); + gtk_widget_set_sensitive (GTK_WIDGET (tf), FALSE); + gtk_entry_set_max_length (GTK_ENTRY (tf), 256); + gtk_table_attach ( GTK_TABLE (t), tf, 1, 3, 2, 3, + (GtkAttachOptions)( GTK_EXPAND | GTK_FILL ), + (GtkAttachOptions)0, 0, 0 ); + gtk_object_set_data (GTK_OBJECT (spw), "title", tf); + + /* Create the frame for the object description */ + f = gtk_frame_new (_("Description")); + gtk_table_attach ( GTK_TABLE (t), f, 0, 3, 3, 4, + (GtkAttachOptions)( GTK_EXPAND | GTK_FILL ), + (GtkAttachOptions)( GTK_EXPAND | GTK_FILL ), 0, 0 ); + gtk_object_set_data (GTK_OBJECT (spw), "desc_frame", l); + + /* Create the text view box for the object description */ + GtkWidget *textframe = gtk_frame_new(NULL); + gtk_container_set_border_width(GTK_CONTAINER(textframe), 4); + gtk_widget_set_sensitive (GTK_WIDGET (textframe), FALSE); + gtk_container_add (GTK_CONTAINER (f), textframe); + gtk_frame_set_shadow_type (GTK_FRAME (textframe), GTK_SHADOW_IN); + + tf = gtk_text_view_new(); + desc_buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(tf)); + gtk_text_buffer_set_text(desc_buffer, "", -1); + gtk_container_add (GTK_CONTAINER (textframe), tf); + gtk_object_set_data (GTK_OBJECT (spw), "desc", tf); + + /* Check boxes */ + GtkWidget *hb_cb = gtk_hbox_new (FALSE, 0); + gtk_box_pack_start (GTK_BOX (vb), hb_cb, FALSE, FALSE, 0); + t = gtk_table_new (1, 2, TRUE); + gtk_container_set_border_width(GTK_CONTAINER(t), 0); + gtk_box_pack_start (GTK_BOX (hb_cb), t, TRUE, TRUE, 10); + + /* Hide */ + cb = gtk_check_button_new_with_mnemonic (_("_Hide")); + gtk_tooltips_set_tip (tt, cb, _("Check to make the object invisible"), NULL); + gtk_table_attach ( GTK_TABLE (t), cb, 0, 1, 0, 1, + (GtkAttachOptions)( GTK_EXPAND | GTK_FILL ), + (GtkAttachOptions)0, 0, 0 ); + g_signal_connect (G_OBJECT(cb), "toggled", G_CALLBACK(sp_item_widget_hidden_toggled), spw); + gtk_object_set_data(GTK_OBJECT(spw), "hidden", cb); + + /* Lock */ + // TRANSLATORS: "Lock" is a verb here + cb = gtk_check_button_new_with_mnemonic (_("L_ock")); + gtk_tooltips_set_tip (tt, cb, _("Check to make the object insensitive (not selectable by mouse)"), NULL); + gtk_table_attach ( GTK_TABLE (t), cb, 1, 2, 0, 1, + (GtkAttachOptions)( GTK_EXPAND | GTK_FILL ), + (GtkAttachOptions)0, 0, 0 ); + gtk_signal_connect ( GTK_OBJECT (cb), "toggled", + GTK_SIGNAL_FUNC (sp_item_widget_sensitivity_toggled), + spw ); + gtk_object_set_data (GTK_OBJECT (spw), "sensitive", cb); + + gtk_widget_show_all (spw); + + sp_item_widget_setup (SP_WIDGET (spw), SP_DT_SELECTION (SP_ACTIVE_DESKTOP)); + + return (GtkWidget *) spw; + +} //end of sp_item_widget_new() + + + +static void +sp_item_widget_modify_selection ( SPWidget *spw, + Inkscape::Selection *selection, + guint flags, + GtkWidget *itemw ) +{ + sp_item_widget_setup (spw, selection); +} + + + +static void +sp_item_widget_change_selection ( SPWidget *spw, + Inkscape::Selection *selection, + GtkWidget *itemw ) +{ + sp_item_widget_setup (spw, selection); +} + + +/** +* \param selection Selection to use; should not be NULL. +*/ +static void +sp_item_widget_setup ( SPWidget *spw, Inkscape::Selection *selection ) +{ + g_assert (selection != NULL); + + if (gtk_object_get_data (GTK_OBJECT (spw), "blocked")) + return; + + if (!selection->singleItem()) { + gtk_widget_set_sensitive (GTK_WIDGET (spw), FALSE); + return; + } else { + gtk_widget_set_sensitive (GTK_WIDGET (spw), TRUE); + } + + gtk_object_set_data (GTK_OBJECT (spw), "blocked", GUINT_TO_POINTER (TRUE)); + + SPItem *item = selection->singleItem(); + + /* Sensitive */ + GtkWidget *w = GTK_WIDGET(gtk_object_get_data (GTK_OBJECT (spw), "sensitive")); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w), item->isLocked()); + + /* Hidden */ + w = GTK_WIDGET(gtk_object_get_data (GTK_OBJECT (spw), "hidden")); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), item->isExplicitlyHidden()); + + if (SP_OBJECT_IS_CLONED (item)) { + + /* ID */ + w = GTK_WIDGET(gtk_object_get_data (GTK_OBJECT (spw), "id")); + gtk_entry_set_text (GTK_ENTRY (w), ""); + gtk_widget_set_sensitive (w, FALSE); + w = GTK_WIDGET(gtk_object_get_data (GTK_OBJECT (spw), "id_label")); + gtk_label_set_text (GTK_LABEL (w), _("Ref")); + + /* Label */ + w = GTK_WIDGET(gtk_object_get_data (GTK_OBJECT (spw), "label")); + gtk_entry_set_text (GTK_ENTRY (w), ""); + gtk_widget_set_sensitive (w, FALSE); + w = GTK_WIDGET(gtk_object_get_data (GTK_OBJECT (spw), "label_label")); + gtk_label_set_text (GTK_LABEL (w), _("Ref")); + + } else { + SPObject *obj = (SPObject*)item; + + /* ID */ + w = GTK_WIDGET(gtk_object_get_data (GTK_OBJECT (spw), "id")); + gtk_entry_set_text (GTK_ENTRY (w), obj->id); + gtk_widget_set_sensitive (w, TRUE); + w = GTK_WIDGET(gtk_object_get_data (GTK_OBJECT (spw), "id_label")); + gtk_label_set_markup_with_mnemonic (GTK_LABEL (w), _("_Id")); + + /* Label */ + w = GTK_WIDGET(gtk_object_get_data (GTK_OBJECT (spw), "label")); + gtk_entry_set_text (GTK_ENTRY (w), obj->defaultLabel()); + gtk_widget_set_sensitive (w, TRUE); + w = GTK_WIDGET(gtk_object_get_data (GTK_OBJECT (spw), "label_label")); + } + + gtk_object_set_data (GTK_OBJECT (spw), "blocked", GUINT_TO_POINTER (FALSE)); + + +} // end of sp_item_widget_setup() + + + +static void +sp_item_widget_sensitivity_toggled (GtkWidget *widget, SPWidget *spw) +{ + if (gtk_object_get_data (GTK_OBJECT (spw), "blocked")) + return; + + SPItem *item = SP_DT_SELECTION(SP_ACTIVE_DESKTOP)->singleItem(); + g_return_if_fail (item != NULL); + + gtk_object_set_data (GTK_OBJECT (spw), "blocked", GUINT_TO_POINTER (TRUE)); + + item->setLocked(gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget))); + + sp_document_maybe_done (SP_ACTIVE_DOCUMENT, "ItemDialog:insensitive"); + + gtk_object_set_data (GTK_OBJECT (spw), "blocked", GUINT_TO_POINTER (FALSE)); +} + +void +sp_item_widget_hidden_toggled(GtkWidget *widget, SPWidget *spw) +{ + if (gtk_object_get_data (GTK_OBJECT (spw), "blocked")) + return; + + SPItem *item = SP_DT_SELECTION(SP_ACTIVE_DESKTOP)->singleItem(); + g_return_if_fail (item != NULL); + + gtk_object_set_data (GTK_OBJECT (spw), "blocked", GUINT_TO_POINTER (TRUE)); + + item->setExplicitlyHidden(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))); + + sp_document_maybe_done (SP_ACTIVE_DOCUMENT, "ItemDialog:visiblity"); + + gtk_object_set_data (GTK_OBJECT (spw), "blocked", GUINT_TO_POINTER (FALSE)); +} + +static void +sp_item_widget_label_changed (GtkWidget *widget, SPWidget *spw) +{ + if (gtk_object_get_data (GTK_OBJECT (spw), "blocked")) + return; + + SPItem *item = SP_DT_SELECTION(SP_ACTIVE_DESKTOP)->singleItem(); + g_return_if_fail (item != NULL); + + gtk_object_set_data (GTK_OBJECT (spw), "blocked", GUINT_TO_POINTER (TRUE)); + + /* Retrieve the label widget for the object's id */ + GtkWidget *id_entry = GTK_WIDGET(gtk_object_get_data (GTK_OBJECT (spw), "id")); + gchar *id = (gchar *) gtk_entry_get_text (GTK_ENTRY (id_entry)); + g_strcanon (id, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.:", '_'); + GtkWidget *id_label = GTK_WIDGET(gtk_object_get_data (GTK_OBJECT (spw), "id_label")); + if (!strcmp (id, SP_OBJECT_ID(item))) { + gtk_label_set_markup_with_mnemonic (GTK_LABEL (id_label), _("_Id")); + } else if (!*id || !isalnum (*id)) { + gtk_label_set_text (GTK_LABEL (id_label), _("Id invalid! ")); + } else if (SP_ACTIVE_DOCUMENT->getObjectById(id) != NULL) { + gtk_label_set_text (GTK_LABEL (id_label), _("Id exists! ")); + } else { + SPException ex; + gtk_label_set_markup_with_mnemonic (GTK_LABEL (id_label), _("_Id")); + SP_EXCEPTION_INIT (&ex); + sp_object_setAttribute (SP_OBJECT (item), "id", id, &ex); + sp_document_maybe_done (SP_ACTIVE_DOCUMENT, "ItemDialog:id"); + } + + /* Retrieve the label widget for the object's label */ + GtkWidget *label_entry = GTK_WIDGET(gtk_object_get_data (GTK_OBJECT (spw), "label")); + gchar *label = (gchar *)gtk_entry_get_text (GTK_ENTRY (label_entry)); + g_assert(label != NULL); + + /* Give feedback on success of setting the drawing object's label + * using the widget's label text + */ + SPObject *obj = (SPObject*)item; + if (strcmp (label, obj->defaultLabel())) { + obj->setLabel(label); + sp_document_maybe_done (SP_ACTIVE_DOCUMENT, "inkscape:label"); + } + + /* Retrieve the title */ + GtkWidget *w = GTK_WIDGET(gtk_object_get_data (GTK_OBJECT (spw), "title")); + gchar *title = (gchar *)gtk_entry_get_text (GTK_ENTRY (w)); + if (title != NULL) { + obj->setTitle(title); + sp_document_maybe_done (SP_ACTIVE_DOCUMENT, "title"); + } + + /* Retrieve the description */ + gchar *desc = NULL; /* TODO: get text from text buffer */ + if (desc != NULL) { + obj->setDesc(desc); + sp_document_maybe_done (SP_ACTIVE_DOCUMENT, "desc"); + } + + gtk_object_set_data (GTK_OBJECT (spw), "blocked", GUINT_TO_POINTER (FALSE)); + +} // end of sp_item_widget_label_changed() + + +/** + * \brief Dialog + * + */ +void +sp_item_dialog (void) +{ + if (dlg == NULL) { + + gchar title[500]; + sp_ui_dialog_title_string (Inkscape::Verb::get(SP_VERB_DIALOG_ITEM), title); + + dlg = sp_window_new (title, TRUE); + if (x == -1000 || y == -1000) { + x = prefs_get_int_attribute (prefs_path, "x", 0); + y = prefs_get_int_attribute (prefs_path, "y", 0); + } + + if (w ==0 || h == 0) { + w = prefs_get_int_attribute (prefs_path, "w", 0); + h = prefs_get_int_attribute (prefs_path, "h", 0); + } + + if (x != 0 || y != 0) { + gtk_window_move ((GtkWindow *) dlg, x, y); + } else { + gtk_window_set_position(GTK_WINDOW(dlg), GTK_WIN_POS_CENTER); + } + + if (w && h) { + gtk_window_resize ((GtkWindow *) dlg, w, h); + } + + sp_transientize (dlg); + wd.win = dlg; + wd.stop = 0; + + g_signal_connect ( G_OBJECT (INKSCAPE), "activate_desktop", G_CALLBACK (sp_transientize_callback), &wd); + gtk_signal_connect ( GTK_OBJECT (dlg), "event", GTK_SIGNAL_FUNC (sp_dialog_event_handler), dlg); + gtk_signal_connect ( GTK_OBJECT (dlg), "destroy", G_CALLBACK (sp_item_dialog_destroy), dlg); + gtk_signal_connect ( GTK_OBJECT (dlg), "delete_event", G_CALLBACK (sp_item_dialog_delete), dlg); + g_signal_connect ( G_OBJECT (INKSCAPE), "shut_down", G_CALLBACK (sp_item_dialog_delete), dlg); + g_signal_connect ( G_OBJECT (INKSCAPE), "dialogs_hide", G_CALLBACK (sp_dialog_hide), dlg); + g_signal_connect ( G_OBJECT (INKSCAPE), "dialogs_unhide", G_CALLBACK (sp_dialog_unhide), dlg); + + // Dialog-specific stuff + GtkWidget *itemw = sp_item_widget_new (); + gtk_widget_show (itemw); + gtk_container_add (GTK_CONTAINER (dlg), itemw); + + } + + gtk_window_present ((GtkWindow *) dlg); +} + + +/* + 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:textwidth=99 : diff --git a/src/dialogs/item-properties.h b/src/dialogs/item-properties.h new file mode 100644 index 000000000..a81034aae --- /dev/null +++ b/src/dialogs/item-properties.h @@ -0,0 +1,38 @@ +#ifndef __SP_ITEM_PROPERTIES_H__ +#define __SP_ITEM_PROPERTIES_H__ + +/** + * \brief Display settings dialog + * + * Author: + * Lauris Kaplinski + * + * Copyright (C) 2001 Ximian, Inc. + * + */ + +#include + + + +#include +#include "../forward.h" + +GtkWidget *sp_item_widget_new (void); + +void sp_item_dialog (void); + + + +#endif + +/* + 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:textwidth=99 : diff --git a/src/dialogs/layer-properties.cpp b/src/dialogs/layer-properties.cpp new file mode 100644 index 000000000..8806e97f0 --- /dev/null +++ b/src/dialogs/layer-properties.cpp @@ -0,0 +1,199 @@ +/** + * + * \brief Dialog for renaming layers + * + * Author: + * Bryce W. Harrington + * + * Copyright (C) 2004 Bryce Harrington + * + * Released under GNU GPL. Read the file 'COPYING' for more information + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#include +#include "inkscape.h" +#include "desktop.h" +#include "document.h" +#include "message-stack.h" +#include "desktop-handles.h" +#include "layer-fns.h" +#include "sp-object.h" + +#include "layer-properties.h" + +namespace Inkscape { +namespace UI { +namespace Dialogs { + +LayerPropertiesDialog::LayerPropertiesDialog() +: _strategy(NULL), _desktop(NULL), _layer(NULL) +{ + GtkWidget *dlg = GTK_WIDGET(gobj()); + g_assert(dlg); + + Gtk::VBox *mainVBox = get_vbox(); + + // Layer name widgets + _layer_name_entry.set_activates_default(true); + _layer_name_hbox.pack_end(_layer_name_entry, false, false, 4); + _layer_name_label.set_label(_("Layer name:")); + _layer_name_hbox.pack_end(_layer_name_label, false, false, 4); + mainVBox->pack_start(_layer_name_hbox, false, false, 4); + + // Buttons + _close_button.set_use_stock(true); + _close_button.set_label(Gtk::Stock::CANCEL.id); + _close_button.set_flags(Gtk::CAN_DEFAULT); + + _apply_button.set_use_underline(true); + _apply_button.set_flags(Gtk::CAN_DEFAULT); + + _close_button.signal_clicked() + .connect(sigc::mem_fun(*this, &LayerPropertiesDialog::_close)); + _apply_button.signal_clicked() + .connect(sigc::mem_fun(*this, &LayerPropertiesDialog::_apply)); + + signal_delete_event().connect( + sigc::bind_return( + sigc::hide(sigc::mem_fun(*this, &LayerPropertiesDialog::_close)), + true + ) + ); + + add_action_widget(_close_button, Gtk::RESPONSE_CLOSE); + add_action_widget(_apply_button, Gtk::RESPONSE_APPLY); + + _apply_button.grab_default(); + + show_all_children(); +} + +LayerPropertiesDialog::~LayerPropertiesDialog() { + _setDesktop(NULL); + _setLayer(NULL); +} + +void LayerPropertiesDialog::_showDialog(LayerPropertiesDialog::Strategy &strategy, + SPDesktop *desktop, SPObject *layer) +{ + LayerPropertiesDialog *dialog = new LayerPropertiesDialog(); + + dialog->_strategy = &strategy; + dialog->_setDesktop(desktop); + dialog->_setLayer(layer); + + dialog->_strategy->setup(*dialog); + + dialog->set_modal(true); + desktop->setWindowTransient (dialog->gobj()); + dialog->property_destroy_with_parent() = true; + + dialog->show(); + dialog->present(); +} + +void +LayerPropertiesDialog::_apply() +{ + g_assert(_strategy != NULL); + + _strategy->perform(*this); + sp_document_done(SP_DT_DOCUMENT(SP_ACTIVE_DESKTOP)); + + _close(); +} + +void +LayerPropertiesDialog::_close() +{ + _setLayer(NULL); + _setDesktop(NULL); + destroy_(); + Glib::signal_idle().connect( + sigc::bind_return( + sigc::bind(sigc::ptr_fun(&::operator delete), this), + false + ) + ); +} + +void LayerPropertiesDialog::Rename::setup(LayerPropertiesDialog &dialog) { + SPDesktop *desktop=dialog._desktop; + dialog.set_title(_("Rename Layer")); + gchar const *name = desktop->currentLayer()->label(); + dialog._layer_name_entry.set_text(( name ? name : "" )); + dialog._apply_button.set_label(_("_Rename")); +} + +void LayerPropertiesDialog::Rename::perform(LayerPropertiesDialog &dialog) { + SPDesktop *desktop=dialog._desktop; + Glib::ustring name(dialog._layer_name_entry.get_text()); + desktop->currentLayer()->setLabel( + ( name.empty() ? NULL : (gchar *)name.c_str() ) + ); + sp_document_done(SP_DT_DOCUMENT(desktop)); + // TRANSLATORS: This means "The layer has been renamed" + desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Renamed layer")); +} + +void LayerPropertiesDialog::Create::setup(LayerPropertiesDialog &dialog) { + dialog.set_title(_("Add Layer")); + dialog._layer_name_entry.set_text(""); + dialog._apply_button.set_label(_("_Add")); +} + +void LayerPropertiesDialog::Create::perform(LayerPropertiesDialog &dialog) { + SPDesktop *desktop=dialog._desktop; + SPObject *new_layer=Inkscape::create_layer( + desktop->currentRoot(), dialog._layer + ); + Glib::ustring name(dialog._layer_name_entry.get_text()); + if (!name.empty()) { + new_layer->setLabel((gchar *)name.c_str()); + } + SP_DT_SELECTION(desktop)->clear(); + desktop->setCurrentLayer(new_layer); + desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("New layer created.")); +} + +void LayerPropertiesDialog::_setDesktop(SPDesktop *desktop) { + if (desktop) { + Inkscape::GC::anchor (desktop); + } + if (_desktop) { + Inkscape::GC::release (_desktop); + } + _desktop = desktop; +} + +void LayerPropertiesDialog::_setLayer(SPObject *layer) { + if (layer) { + sp_object_ref(layer, NULL); + } + if (_layer) { + sp_object_unref(_layer, NULL); + } + _layer = layer; +} + +} // namespace +} // namespace +} // namespace + + +/* + 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:textwidth=99 : diff --git a/src/dialogs/layer-properties.h b/src/dialogs/layer-properties.h new file mode 100644 index 000000000..15404b2e5 --- /dev/null +++ b/src/dialogs/layer-properties.h @@ -0,0 +1,110 @@ +/** + * + * \brief Dialog for renaming layers + * + * Author: + * Bryce W. Harrington + * + * Copyright (C) 2004 Bryce Harrington + * + * Released under GNU GPL. Read the file 'COPYING' for more information + */ + +#ifndef INKSCAPE_DIALOG_LAYER_PROPERTIES_H +#define INKSCAPE_DIALOG_LAYER_PROPERTIES_H + +#include +#include +#include +#include +#include +#include +#include + +#include "selection.h" + +namespace Inkscape { +namespace UI { +namespace Dialogs { + +class LayerPropertiesDialog : public Gtk::Dialog { + public: + LayerPropertiesDialog(); + virtual ~LayerPropertiesDialog(); + + Glib::ustring getName() const { return "LayerPropertiesDialog"; } + + static void showRename(SPDesktop *desktop, SPObject *layer) { + _showDialog(Rename::instance(), desktop, layer); + } + static void showCreate(SPDesktop *desktop, SPObject *layer) { + _showDialog(Create::instance(), desktop, layer); + } + +protected: + struct Strategy { + virtual ~Strategy() {} + virtual void setup(LayerPropertiesDialog &)=0; + virtual void perform(LayerPropertiesDialog &)=0; + }; + struct Rename : public Strategy { + static Rename &instance() { static Rename instance; return instance; } + void setup(LayerPropertiesDialog &dialog); + void perform(LayerPropertiesDialog &dialog); + }; + struct Create : public Strategy { + static Create &instance() { static Create instance; return instance; } + void setup(LayerPropertiesDialog &dialog); + void perform(LayerPropertiesDialog &dialog); + }; + + friend class Rename; + friend class Create; + + Strategy *_strategy; + SPDesktop *_desktop; + SPObject *_layer; + + Gtk::HBox _layer_name_hbox; + Gtk::Label _layer_name_label; + Gtk::Entry _layer_name_entry; + + Gtk::Button _close_button; + Gtk::Button _apply_button; + + sigc::connection _destroy_connection; + + static LayerPropertiesDialog &_instance() { + static LayerPropertiesDialog instance; + return instance; + } + + void _setDesktop(SPDesktop *desktop); + void _setLayer(SPObject *layer); + + static void _showDialog(Strategy &strategy, SPDesktop *desktop, SPObject *layer); + void _apply(); + void _close(); + +private: + LayerPropertiesDialog(LayerPropertiesDialog const &); // no copy + LayerPropertiesDialog &operator=(LayerPropertiesDialog const &); // no assign +}; + +} // namespace +} // namespace +} // namespace + + +#endif //INKSCAPE_DIALOG_LAYER_PROPERTIES_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:encoding=utf-8:textwidth=99 : diff --git a/src/dialogs/makefile.in b/src/dialogs/makefile.in new file mode 100644 index 000000000..5f39e1899 --- /dev/null +++ b/src/dialogs/makefile.in @@ -0,0 +1,17 @@ +# Convenience stub makefile to call the real Makefile. + +@SET_MAKE@ + +# Explicit so that it's the default rule. +all: + cd .. && $(MAKE) dialogs/all + +clean %.a %.o: + cd .. && $(MAKE) dialogs/$@ + +.PHONY: all clean + +OBJEXT = @OBJEXT@ + +.SUFFIXES: +.SUFFIXES: .a .$(OBJEXT) diff --git a/src/dialogs/object-attributes.cpp b/src/dialogs/object-attributes.cpp new file mode 100644 index 000000000..05370d1d0 --- /dev/null +++ b/src/dialogs/object-attributes.cpp @@ -0,0 +1,140 @@ +#define __SP_OBJECT_ATTRIBUTES_C__ + +/** + * \brief Generic properties editor + * + * Authors: + * Lauris Kaplinski + * bulia byak + * + * Copyright (C) 1999-2005 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif +#include +#include "helper/window.h" +#include "macros.h" +#include "sp-anchor.h" +#include "sp-attribute-widget.h" + +struct SPAttrDesc { + gchar const *label; + gchar const *attribute; +}; + +static const SPAttrDesc anchor_desc[] = { + { N_("Href:"), "xlink:href"}, + { N_("Target:"), "target"}, + { N_("Type:"), "xlink:type"}, + // TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkRoleAttribute + // Identifies the type of the related resource with an absolute URI + { N_("Role:"), "xlink:role"}, + // TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkArcRoleAttribute + // For situations where the nature/role alone isn't enough, this offers an additional URI defining the purpose of the link. + { N_("Arcrole:"), "xlink:arcrole"}, + // TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkTitleAttribute + { N_("Title:"), "xlink:title"}, + { N_("Show:"), "xlink:show"}, + // TRANSLATORS: for info, see http://www.w3.org/TR/2000/CR-SVG-20000802/linking.html#AElementXLinkActuateAttribute + { N_("Actuate:"), "xlink:actuate"}, + { NULL, NULL} +}; + +static const SPAttrDesc image_desc[] = { + { N_("URL:"), "xlink:href"}, + { N_("X:"), "x"}, + { N_("Y:"), "y"}, + { N_("Width:"), "width"}, + { N_("Height:"), "height"}, + { NULL, NULL} +}; + + +static void +object_released (GtkObject *object, GtkWidget *widget) +{ + gtk_widget_destroy (widget); +} + + + +static void +window_destroyed (GtkObject *window, GtkObject *object) +{ + sp_signal_disconnect_by_data (object, window); +} + + + +static void +sp_object_attr_show_dialog ( SPObject *object, + const SPAttrDesc *desc, + const gchar *tag ) +{ + const gchar **labels, **attrs; + gint len, i; + gchar *title; + GtkWidget *w, *t; + + len = 0; + while (desc[len].label) len += 1; + + labels = (const gchar **)alloca (len * sizeof (char *)); + attrs = (const gchar **)alloca (len * sizeof (char *)); + + for (i = 0; i < len; i++) { + labels[i] = desc[i].label; + attrs[i] = desc[i].attribute; + } + + title = g_strdup_printf (_("%s attributes"), tag); + w = sp_window_new (title, TRUE); + g_free (title); + + t = sp_attribute_table_new (object, len, labels, attrs); + gtk_widget_show (t); + gtk_container_add (GTK_CONTAINER (w), t); + + g_signal_connect ( G_OBJECT (w), "destroy", + G_CALLBACK (window_destroyed), object ); + + g_signal_connect ( G_OBJECT (object), "release", + G_CALLBACK (object_released), w ); + + gtk_widget_show (w); + +} // end of sp_object_attr_show_dialog() + + + +void +sp_object_attributes_dialog (SPObject *object, const gchar *tag) +{ + g_return_if_fail (object != NULL); + g_return_if_fail (SP_IS_OBJECT (object)); + g_return_if_fail (tag != NULL); + + if (!strcmp (tag, "Link")) { + sp_object_attr_show_dialog (object, anchor_desc, tag); + } else if (!strcmp (tag, "Image")) { + sp_object_attr_show_dialog (object, image_desc, tag); + } + +} // end of sp_object_attributes_dialog() + + + +/* + 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:textwidth=99 : diff --git a/src/dialogs/object-attributes.h b/src/dialogs/object-attributes.h new file mode 100644 index 000000000..2fc562e16 --- /dev/null +++ b/src/dialogs/object-attributes.h @@ -0,0 +1,37 @@ +#ifndef __SP_OBJECT_ATTRIBUTES_H__ +#define __SP_OBJECT_ATTRIBUTES_H__ + +/** + * \brief Generic object attribute editor + * + * Author: + * Lauris Kaplinski + * + * Copyright (C) 2001 Ximian, Inc. + * + * Licensed under GNU GPL + */ + +#include + + + +#include +#include "../forward.h" + +void sp_object_attributes_dialog (SPObject *object, const gchar *tag); + + + +#endif + +/* + 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:textwidth=99 : diff --git a/src/dialogs/object-properties.cpp b/src/dialogs/object-properties.cpp new file mode 100644 index 000000000..9cbf1c3ea --- /dev/null +++ b/src/dialogs/object-properties.cpp @@ -0,0 +1,318 @@ +#define __OBJECT_PROPERTIES_C__ + +/** + * \brief Fill, stroke, and stroke style dialog + * + * Authors: + * Lauris Kaplinski + * Frank Felfe + * bulia byak + * + * Copyright (C) 1999-2005 authors + * Copyright (C) 2001-2002 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include +#include "helper/window.h" +#include "widgets/sp-widget.h" +#include "widgets/icon.h" +#include "macros.h" +#include "inkscape.h" +#include "fill-style.h" +#include "stroke-style.h" +#include "dialog-events.h" +#include "verbs.h" +#include "interface.h" +#include "style.h" +#include "inkscape-stock.h" +#include "prefs-utils.h" +#include "svg/css-ostringstream.h" +#include "desktop-handles.h" +#include "desktop-style.h" +#include "document.h" +#include "xml/repr.h" + +static GtkWidget *dlg = NULL; +static win_data wd; + +// impossible original values to make sure they are read from prefs +static gint x = -1000, y = -1000, w = 0, h = 0; +static gchar *prefs_path = "dialogs.fillstroke"; + +static void sp_fillstroke_selection_modified ( Inkscape::Application *inkscape, Inkscape::Selection *selection, guint flags, GtkObject *base ); +static void sp_fillstroke_selection_changed ( Inkscape::Application *inkscape, Inkscape::Selection *selection, GtkObject *base ); +static void sp_fillstroke_opacity_changed (GtkAdjustment *a, SPWidget *dlg); + +static void +sp_object_properties_dialog_destroy (GtkObject *object, gpointer data) +{ + sp_signal_disconnect_by_data (INKSCAPE, dlg); + wd.win = dlg = NULL; + wd.stop = 0; +} + +static gboolean +sp_object_properties_dialog_delete ( GtkObject *object, + GdkEvent *event, + gpointer data ) +{ + + gtk_window_get_position ((GtkWindow *) dlg, &x, &y); + gtk_window_get_size ((GtkWindow *) dlg, &w, &h); + + prefs_set_int_attribute (prefs_path, "x", x); + prefs_set_int_attribute (prefs_path, "y", y); + prefs_set_int_attribute (prefs_path, "w", w); + prefs_set_int_attribute (prefs_path, "h", h); + + return FALSE; // which means, go ahead and destroy it + +} + + +void +sp_object_properties_page( GtkWidget *nb, + GtkWidget *page, + char *label, + char *dlg_name, + char *label_image ) +{ + GtkWidget *hb, *l, *px; + + hb = gtk_hbox_new (FALSE, 0); + gtk_widget_show (hb); + + px = sp_icon_new( GTK_ICON_SIZE_MENU, label_image ); + gtk_widget_show (px); + gtk_box_pack_start (GTK_BOX (hb), px, FALSE, FALSE, 2); + + l = gtk_label_new_with_mnemonic (label); + gtk_widget_show (l); + gtk_box_pack_start (GTK_BOX (hb), l, FALSE, FALSE, 0); + + gtk_widget_show (page); + gtk_notebook_append_page (GTK_NOTEBOOK (nb), page, hb); + gtk_object_set_data (GTK_OBJECT (dlg), dlg_name, page); +} + +void +sp_object_properties_dialog (void) +{ + if (!dlg) { + gchar title[500]; + sp_ui_dialog_title_string (Inkscape::Verb::get(SP_VERB_DIALOG_FILL_STROKE), title); + + dlg = sp_window_new (title, TRUE); + if (x == -1000 || y == -1000) { + x = prefs_get_int_attribute (prefs_path, "x", 0); + y = prefs_get_int_attribute (prefs_path, "y", 0); + } + if (w ==0 || h == 0) { + w = prefs_get_int_attribute (prefs_path, "w", 0); + h = prefs_get_int_attribute (prefs_path, "h", 0); + } + if (x != 0 || y != 0) + gtk_window_move ((GtkWindow *) dlg, x, y); + else + gtk_window_set_position(GTK_WINDOW(dlg), GTK_WIN_POS_CENTER); + if (w && h) gtk_window_resize ((GtkWindow *) dlg, w, h); + sp_transientize (dlg); + wd.win = dlg; + wd.stop = 0; + + g_signal_connect ( G_OBJECT (INKSCAPE), "activate_desktop", G_CALLBACK (sp_transientize_callback), &wd ); + + gtk_signal_connect ( GTK_OBJECT (dlg), "event", GTK_SIGNAL_FUNC (sp_dialog_event_handler), dlg ); + + gtk_signal_connect ( GTK_OBJECT (dlg), "destroy", G_CALLBACK (sp_object_properties_dialog_destroy), dlg ); + gtk_signal_connect ( GTK_OBJECT (dlg), "delete_event", G_CALLBACK (sp_object_properties_dialog_delete), dlg ); + g_signal_connect ( G_OBJECT (INKSCAPE), "shut_down", G_CALLBACK (sp_object_properties_dialog_delete), dlg ); + + g_signal_connect ( G_OBJECT (INKSCAPE), "dialogs_hide", G_CALLBACK (sp_dialog_hide), dlg ); + g_signal_connect ( G_OBJECT (INKSCAPE), "dialogs_unhide", G_CALLBACK (sp_dialog_unhide), dlg ); + + GtkWidget *vb = gtk_vbox_new (FALSE, 0); + gtk_widget_show (vb); + gtk_container_add (GTK_CONTAINER (dlg), vb); + + GtkWidget *nb = gtk_notebook_new (); + gtk_widget_show (nb); + gtk_box_pack_start (GTK_BOX (vb), nb, TRUE, TRUE, 0); + gtk_object_set_data (GTK_OBJECT (dlg), "notebook", nb); + + /* Fill page */ + { + GtkWidget *page = sp_fill_style_widget_new (); + sp_object_properties_page(nb, page, _("_Fill"), "fill", + INKSCAPE_STOCK_PROPERTIES_FILL_PAGE); + } + + /* Stroke paint page */ + { + GtkWidget *page = sp_stroke_style_paint_widget_new (); + sp_object_properties_page(nb, page, _("Stroke _paint"), "stroke-paint", + INKSCAPE_STOCK_PROPERTIES_STROKE_PAINT_PAGE); + } + + /* Stroke style page */ + { + GtkWidget *page = sp_stroke_style_line_widget_new (); + sp_object_properties_page(nb, page, _("Stroke st_yle"), "stroke-line", + INKSCAPE_STOCK_PROPERTIES_STROKE_PAGE); + } + + /* Opacity */ + + GtkWidget *o_vb = gtk_vbox_new (FALSE, 0); + gtk_box_pack_start (GTK_BOX (vb), o_vb, FALSE, FALSE, 2); + gtk_object_set_data (GTK_OBJECT (dlg), "master_opacity", o_vb); + + GtkWidget *l_hb = gtk_hbox_new (FALSE, 4); + GtkWidget *l = gtk_label_new_with_mnemonic (_("Master _opacity")); + gtk_misc_set_alignment (GTK_MISC (l), 0.0, 1.0); + gtk_box_pack_start (GTK_BOX (l_hb), l, FALSE, FALSE, 4); + gtk_box_pack_start (GTK_BOX (o_vb), l_hb, FALSE, FALSE, 0); + + GtkWidget *hb = gtk_hbox_new (FALSE, 4); + gtk_box_pack_start (GTK_BOX (o_vb), hb, FALSE, FALSE, 0); + + GtkObject *a = gtk_adjustment_new (1.0, 0.0, 1.0, 0.01, 0.1, 0.0); + gtk_object_set_data(GTK_OBJECT(dlg), "master_opacity_adjustment", a); + + GtkWidget *s = gtk_hscale_new (GTK_ADJUSTMENT (a)); + gtk_scale_set_draw_value (GTK_SCALE (s), FALSE); + gtk_box_pack_start (GTK_BOX (hb), s, TRUE, TRUE, 4); + gtk_label_set_mnemonic_widget (GTK_LABEL(l), s); + + GtkWidget *sb = gtk_spin_button_new (GTK_ADJUSTMENT (a), 0.01, 3); + gtk_box_pack_start (GTK_BOX (hb), sb, FALSE, FALSE, 0); + + gtk_signal_connect ( a, "value_changed", + GTK_SIGNAL_FUNC (sp_fillstroke_opacity_changed), + dlg ); + + gtk_widget_show_all (o_vb); + + // these callbacks are only for the master opacity update; the tabs above take care of themselves + g_signal_connect ( G_OBJECT (INKSCAPE), "change_selection", G_CALLBACK (sp_fillstroke_selection_changed), dlg ); + g_signal_connect ( G_OBJECT (INKSCAPE), "modify_selection", G_CALLBACK (sp_fillstroke_selection_modified), dlg ); + g_signal_connect ( G_OBJECT (INKSCAPE), "activate_desktop", G_CALLBACK (sp_fillstroke_selection_changed), dlg ); + + sp_fillstroke_selection_changed(NULL, NULL, NULL); + + gtk_widget_show (dlg); + + } else { + gtk_window_present (GTK_WINDOW (dlg)); + } + +} // end of sp_object_properties_dialog() + +void sp_object_properties_fill (void) +{ + sp_object_properties_dialog (); + GtkWidget *nb = (GtkWidget *)gtk_object_get_data (GTK_OBJECT (dlg), "notebook"); + gtk_notebook_set_page (GTK_NOTEBOOK (nb), 0); +} + +void sp_object_properties_stroke (void) +{ + sp_object_properties_dialog (); + GtkWidget *nb = (GtkWidget *)gtk_object_get_data (GTK_OBJECT (dlg), "notebook"); + gtk_notebook_set_page (GTK_NOTEBOOK (nb), 1); +} + +void sp_object_properties_stroke_style (void) +{ + sp_object_properties_dialog (); + GtkWidget *nb = (GtkWidget *)gtk_object_get_data (GTK_OBJECT (dlg), "notebook"); + gtk_notebook_set_page (GTK_NOTEBOOK (nb), 2); +} + + + +static void +sp_fillstroke_selection_modified ( Inkscape::Application *inkscape, + Inkscape::Selection *selection, + guint flags, + GtkObject *base ) +{ + sp_fillstroke_selection_changed ( inkscape, selection, base ); +} + + +static void +sp_fillstroke_selection_changed ( Inkscape::Application *inkscape, + Inkscape::Selection *selection, + GtkObject *base ) +{ + if (gtk_object_get_data (GTK_OBJECT (dlg), "blocked")) + return; + gtk_object_set_data (GTK_OBJECT (dlg), "blocked", GUINT_TO_POINTER (TRUE)); + + GtkWidget *opa = GTK_WIDGET (gtk_object_get_data (GTK_OBJECT (dlg), "master_opacity")); + GtkAdjustment *a = GTK_ADJUSTMENT(gtk_object_get_data(GTK_OBJECT(dlg), "master_opacity_adjustment")); + + // create temporary style + SPStyle *query = sp_style_new (); + // query style from desktop into it. This returns a result flag and fills query with the style of subselection, if any, or selection + int result = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_MASTEROPACITY); + + switch (result) { + case QUERY_STYLE_NOTHING: + gtk_widget_set_sensitive (opa, FALSE); + break; + case QUERY_STYLE_SINGLE: + case QUERY_STYLE_MULTIPLE_AVERAGED: // TODO: treat this slightly differently + case QUERY_STYLE_MULTIPLE_SAME: + gtk_widget_set_sensitive (opa, TRUE); + gtk_adjustment_set_value(a, SP_SCALE24_TO_FLOAT(query->opacity.value)); + break; + } + + g_free (query); + gtk_object_set_data (GTK_OBJECT (dlg), "blocked", GUINT_TO_POINTER (FALSE)); +} + +static void +sp_fillstroke_opacity_changed (GtkAdjustment *a, SPWidget *dlg) +{ + if (gtk_object_get_data (GTK_OBJECT (dlg), "blocked")) + return; + + gtk_object_set_data (GTK_OBJECT (dlg), "blocked", GUINT_TO_POINTER (TRUE)); + + SPCSSAttr *css = sp_repr_css_attr_new (); + + Inkscape::CSSOStringStream os; + os << CLAMP (a->value, 0.0, 1.0); + sp_repr_css_set_property (css, "opacity", os.str().c_str()); + + sp_desktop_set_style (SP_ACTIVE_DESKTOP, css); + + sp_repr_css_attr_unref (css); + + sp_document_maybe_done (SP_DT_DOCUMENT (SP_ACTIVE_DESKTOP), "fillstroke:opacity"); + + gtk_object_set_data (GTK_OBJECT (dlg), "blocked", GUINT_TO_POINTER (FALSE)); +} + + +/* + 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:textwidth=99 : diff --git a/src/dialogs/object-properties.h b/src/dialogs/object-properties.h new file mode 100644 index 000000000..c78142095 --- /dev/null +++ b/src/dialogs/object-properties.h @@ -0,0 +1,34 @@ +#ifndef __OBJECT_PROPERTIES_H__ +#define __OBJECT_PROPERTIES_H__ + +/** + * \brief Basic object style dialog + * + * Authors: + * Lauris Kaplinski + * Frank Felfe + * + * Copyright (C) 2000-2001 Lauris Kaplinski and Frank Felfe + * Copyright (C) 2001-2002 Ximian, Inc. and Lauris Kaplinski + * + * Released under GNU GPL + */ + +void sp_object_properties_dialog (void); + +void sp_object_properties_fill (void); +void sp_object_properties_stroke (void); +void sp_object_properties_stroke_style (void); + +#endif + +/* + 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:textwidth=99 : diff --git a/src/dialogs/rdf.cpp b/src/dialogs/rdf.cpp new file mode 100644 index 000000000..d9949c05b --- /dev/null +++ b/src/dialogs/rdf.cpp @@ -0,0 +1,1002 @@ +/** + * \brief RDF manipulation functions + * + * FIXME: move these to xml/ instead of dialogs/ + * + * Authors: + * Kees Cook + * + * Copyright (C) 2004 Kees Cook + * + * Released under GNU GPL, read the file 'COPYING' for more information + * + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + + + +#include "xml/repr.h" +#include "rdf.h" +#include "sp-item-group.h" + +/* + + Example RDF XML from various places... + + + + title of work + year + description of work + + creator + + + holder + + + + + + + + + + SVG Road Signs + + John Cliff + + + + + + + + + + + + + + +Bag example: + + + +open clip art logo +images +logo +clip art +ocal +logotype +filetype + + + + +*/ + +struct rdf_double_t rdf_license_empty [] = { + { NULL, NULL } +}; + +struct rdf_double_t rdf_license_cc_a [] = { + { "cc:permits", "http://web.resource.org/cc/Reproduction", }, + { "cc:permits", "http://web.resource.org/cc/Distribution", }, + { "cc:requires", "http://web.resource.org/cc/Notice", }, + { "cc:requires", "http://web.resource.org/cc/Attribution", }, + { "cc:permits", "http://web.resource.org/cc/DerivativeWorks", }, + { NULL, NULL } +}; + +struct rdf_double_t rdf_license_cc_a_sa [] = { + { "cc:permits", "http://web.resource.org/cc/Reproduction", }, + { "cc:permits", "http://web.resource.org/cc/Distribution", }, + { "cc:requires", "http://web.resource.org/cc/Notice", }, + { "cc:requires", "http://web.resource.org/cc/Attribution", }, + { "cc:permits", "http://web.resource.org/cc/DerivativeWorks", }, + { "cc:requires", "http://web.resource.org/cc/ShareAlike", }, + { NULL, NULL } +}; + +struct rdf_double_t rdf_license_cc_a_nd [] = { + { "cc:permits", "http://web.resource.org/cc/Reproduction", }, + { "cc:permits", "http://web.resource.org/cc/Distribution", }, + { "cc:requires", "http://web.resource.org/cc/Notice", }, + { "cc:requires", "http://web.resource.org/cc/Attribution", }, + { NULL, NULL } +}; + +struct rdf_double_t rdf_license_cc_a_nc [] = { + { "cc:permits", "http://web.resource.org/cc/Reproduction", }, + { "cc:permits", "http://web.resource.org/cc/Distribution", }, + { "cc:requires", "http://web.resource.org/cc/Notice", }, + { "cc:requires", "http://web.resource.org/cc/Attribution", }, + { "cc:prohibits", "http://web.resource.org/cc/CommercialUse", }, + { "cc:permits", "http://web.resource.org/cc/DerivativeWorks", }, + { NULL, NULL } +}; + +struct rdf_double_t rdf_license_cc_a_nc_sa [] = { + { "cc:permits", "http://web.resource.org/cc/Reproduction", }, + { "cc:permits", "http://web.resource.org/cc/Distribution", }, + { "cc:requires", "http://web.resource.org/cc/Notice", }, + { "cc:requires", "http://web.resource.org/cc/Attribution", }, + { "cc:prohibits", "http://web.resource.org/cc/CommercialUse", }, + { "cc:permits", "http://web.resource.org/cc/DerivativeWorks", }, + { "cc:requires", "http://web.resource.org/cc/ShareAlike", }, + { NULL, NULL } +}; + +struct rdf_double_t rdf_license_cc_a_nc_nd [] = { + { "cc:permits", "http://web.resource.org/cc/Reproduction", }, + { "cc:permits", "http://web.resource.org/cc/Distribution", }, + { "cc:requires", "http://web.resource.org/cc/Notice", }, + { "cc:requires", "http://web.resource.org/cc/Attribution", }, + { "cc:prohibits", "http://web.resource.org/cc/CommercialUse", }, + { NULL, NULL } +}; + +struct rdf_double_t rdf_license_gpl [] = { + { "cc:permits", "http://web.resource.org/cc/Reproduction", }, + { "cc:permits", "http://web.resource.org/cc/Distribution", }, + { "cc:requires", "http://web.resource.org/cc/Notice", }, + { "cc:permits", "http://web.resource.org/cc/DerivativeWorks", }, + { "cc:requires", "http://web.resource.org/cc/ShareAlike", }, + { "cc:requires", "http://web.resource.org/cc/SourceCode", }, + { NULL, NULL } +}; + +struct rdf_double_t rdf_license_pd [] = { + { "cc:permits", "http://web.resource.org/cc/Reproduction", }, + { "cc:permits", "http://web.resource.org/cc/Distribution", }, + { "cc:permits", "http://web.resource.org/cc/DerivativeWorks", }, + { NULL, NULL } +}; + +struct rdf_double_t rdf_license_freeart [] = { + { "cc:permits", "http://web.resource.org/cc/Reproduction", }, + { "cc:permits", "http://web.resource.org/cc/Distribution", }, + { "cc:permits", "http://web.resource.org/cc/DerivativeWorks", }, + { "cc:requires", "http://web.resource.org/cc/ShareAlike", }, + { "cc:requires", "http://web.resource.org/cc/Notice", }, + { "cc:requires", "http://web.resource.org/cc/Attribution", }, + { NULL, NULL } +}; + +struct rdf_license_t rdf_licenses [] = { + { "CC Attribution", + "http://creativecommons.org/licenses/by/2.0/", + rdf_license_cc_a, + }, + + { "CC Attribution-ShareAlike", + "http://creativecommons.org/licenses/by-sa/2.0/", + rdf_license_cc_a_sa, + }, + + { "CC Attribution-NoDerivs", + "http://creativecommons.org/licenses/by-nd/2.0/", + rdf_license_cc_a_nd, + }, + + { "CC Attribution-NonCommercial", + "http://creativecommons.org/licenses/by-nc/2.0/", + rdf_license_cc_a_nc, + }, + + { "CC Attribution-NonCommercial-ShareAlike", + "http://creativecommons.org/licenses/by-nc-sa/2.0/", + rdf_license_cc_a_nc_sa, + }, + + { "CC Attribution-NonCommercial-NoDerivs", + "http://creativecommons.org/licenses/by-nc-nd/2.0/", + rdf_license_cc_a_nc_nd, + }, + + { "GNU General Public License", + "http://creativecommons.org/licenses/GPL/2.0/", + rdf_license_gpl, + }, + + { "GNU Lesser General Public License", + "http://creativecommons.org/licenses/LGPL/2.1/", + rdf_license_gpl, + }, + + { "Public Domain", + "http://web.resource.org/cc/PublicDomain", + rdf_license_pd, + }, + + { "FreeArt", + "http://artlibre.org/licence.php/lalgb.html", + rdf_license_freeart, + }, + + { NULL, NULL, rdf_license_empty, } +}; + +#define XML_TAG_NAME_SVG "svg:svg" +#define XML_TAG_NAME_METADATA "svg:metadata" +#define XML_TAG_NAME_RDF "rdf:RDF" +#define XML_TAG_NAME_WORK "cc:Work" +#define XML_TAG_NAME_LICENSE "cc:License" + +// Remember when using the "title" and "tip" elements to pass them through +// the localization functions when you use them! +struct rdf_work_entity_t rdf_work_entities [] = { + { "title", N_("Title"), "dc:title", RDF_CONTENT, + N_("Name by which this document is formally known."), RDF_FORMAT_LINE, RDF_EDIT_GENERIC, + }, + { "date", N_("Date"), "dc:date", RDF_CONTENT, + N_("Date associated with the creation of this document (YYYY-MM-DD)."), RDF_FORMAT_LINE, RDF_EDIT_GENERIC, + }, + { "format", N_("Format"), "dc:format", RDF_CONTENT, + N_("The physical or digital manifestation of this document (MIME type)."), RDF_FORMAT_LINE, RDF_EDIT_HARDCODED, + }, + { "type", N_("Type"), "dc:type", RDF_RESOURCE, + N_("Type of document (DCMI Type)."), RDF_FORMAT_LINE, RDF_EDIT_HARDCODED, + }, + + { "creator", N_("Creator"), "dc:creator", RDF_AGENT, + N_("Name of entity primarily responsible for making the content of this document."), RDF_FORMAT_LINE, RDF_EDIT_GENERIC, + }, + { "rights", N_("Rights"), "dc:rights", RDF_AGENT, + N_("Name of entity with rights to the Intellectual Property of this document."), RDF_FORMAT_LINE, RDF_EDIT_GENERIC, + }, + { "publisher", N_("Publisher"), "dc:publisher", RDF_AGENT, + N_("Name of entity responsible for making this document available."), RDF_FORMAT_LINE, RDF_EDIT_GENERIC, + }, + + { "identifier", N_("Identifier"), "dc:identifier", RDF_CONTENT, + N_("Unique URI to reference this document."), RDF_FORMAT_LINE, RDF_EDIT_GENERIC, + }, + { "source", N_("Source"), "dc:source", RDF_CONTENT, + N_("Unique URI to reference the source of this document."), RDF_FORMAT_LINE, RDF_EDIT_GENERIC, + }, + { "relation", N_("Relation"), "dc:relation", RDF_CONTENT, + N_("Unique URI to a related document."), RDF_FORMAT_LINE, RDF_EDIT_GENERIC, + }, + { "language", N_("Language"), "dc:language", RDF_CONTENT, + N_("Two-letter language tag with optional subtags for the language of this document. (e.g. 'en-GB')"), RDF_FORMAT_LINE, RDF_EDIT_GENERIC, + }, + { "subject", N_("Keywords"), "dc:subject", RDF_BAG, + N_("The topic of this document as comma-separated key words, phrases, or classifications."), RDF_FORMAT_LINE, RDF_EDIT_GENERIC, + }, + // TRANSLATORS: "Coverage": the spatial or temporal characteristics of the content. + // For info, see Appendix D of http://www.w3.org/TR/1998/WD-rdf-schema-19980409/ + { "coverage", N_("Coverage"), "dc:coverage", RDF_CONTENT, + N_("Extent or scope of this document."), RDF_FORMAT_LINE, RDF_EDIT_GENERIC, + }, + + { "description", N_("Description"), "dc:description", RDF_CONTENT, + N_("A short account of the content of this document."), RDF_FORMAT_MULTILINE, RDF_EDIT_GENERIC, + }, + + // FIXME: need to handle 1 agent per line of input + { "contributor", N_("Contributors"), "dc:contributor", RDF_AGENT, + N_("Names of entities responsible for making contributions to the content of this document."), RDF_FORMAT_MULTILINE, RDF_EDIT_GENERIC, + }, + + // TRANSLATORS: URL to a page that defines the license for the document + { "license_uri", N_("URI"), "cc:license", RDF_RESOURCE, + // TRANSLATORS: this is where you put a URL to a page that defines the license + N_("URI to this document's license's namespace definition."), RDF_FORMAT_LINE, RDF_EDIT_SPECIAL, + }, + + // TRANSLATORS: fragment of XML representing the license of the document + { "license_fragment", N_("Fragment"), "License", RDF_XML, + N_("XML fragment for the RDF 'License' section."), RDF_FORMAT_MULTILINE, RDF_EDIT_SPECIAL, + }, + + { NULL, NULL, NULL, RDF_CONTENT, + NULL, RDF_FORMAT_LINE, RDF_EDIT_HARDCODED, + } +}; + +/** + * \brief Retrieves a known RDF/Work entity by name + * \return A pointer to an RDF/Work entity + * \param name The desired RDF/Work entity + * + */ +struct rdf_work_entity_t * +rdf_find_entity(gchar const * name) +{ + struct rdf_work_entity_t *entity; + for (entity=rdf_work_entities; entity->name; entity++) { + if (strcmp(entity->name,name)==0) break; + } + if (entity->name) return entity; + return NULL; +} + +/* + * Takes the inkscape rdf struct and spits out a static RDF, which is only + * useful for testing. We must merge the rdf struct into the XML DOM for + * changes to be saved. + */ +/* + + Since g_markup_printf_escaped doesn't exist for most people's glib + right now, this function will remain commented out since it's only + for generic debug anyway. --Kees + +gchar * +rdf_string(struct rdf_t * rdf) +{ + gulong overall=0; + gchar *string=NULL; + + gchar *rdf_head="\ +\ +"; + gchar *work_head="\ +\ + \ +"; + gchar *work_title=NULL; + gchar *work_date=NULL; + gchar *work_description=NULL; + gchar *work_creator=NULL; + gchar *work_owner=NULL; + gchar *work_source=NULL; + gchar *work_license=NULL; + gchar *license_head=NULL; + gchar *license=NULL; + gchar *license_end="\n"; + gchar *work_end="\n"; + gchar *rdf_end="\n"; + + if (rdf && rdf->work_title && rdf->work_title[0]) { + work_title=g_markup_printf_escaped(" %s\n", + rdf->work_title); + overall+=strlen(work_title); + } + if (rdf && rdf->work_date && rdf->work_date[0]) { + work_date=g_markup_printf_escaped(" %s\n", + rdf->work_date); + overall+=strlen(work_date); + } + if (rdf && rdf->work_description && rdf->work_description[0]) { + work_description=g_markup_printf_escaped(" %s\n", + rdf->work_description); + overall+=strlen(work_description); + } + if (rdf && rdf->work_creator && rdf->work_creator[0]) { + work_creator=g_markup_printf_escaped(" \ + %s\ + \n", + rdf->work_creator); + overall+=strlen(work_creator); + } + if (rdf && rdf->work_owner && rdf->work_owner[0]) { + work_owner=g_markup_printf_escaped(" \ + %s\ + \n", + rdf->work_owner); + overall+=strlen(work_owner); + } + if (rdf && rdf->work_source && rdf->work_source[0]) { + work_source=g_markup_printf_escaped(" \n", + rdf->work_source); + overall+=strlen(work_source); + } + if (rdf && rdf->license && rdf->license->work_rdf && rdf->license->work_rdf[0]) { + work_license=g_markup_printf_escaped(" \n", + rdf->license->work_rdf); + overall+=strlen(work_license); + + license_head=g_markup_printf_escaped("\n", + rdf->license->work_rdf); + overall+=strlen(license_head); + overall+=strlen(rdf->license->license_rdf); + overall+=strlen(license_end); + } + + overall+=strlen(rdf_head)+strlen(rdf_end); + overall+=strlen(work_head)+strlen(work_end); + + overall++; // NULL term + + if (!(string=(gchar*)g_malloc(overall))) { + return NULL; + } + + string[0]='\0'; + strcat(string,rdf_head); + strcat(string,work_head); + + if (work_title) strcat(string,work_title); + if (work_date) strcat(string,work_date); + if (work_description) strcat(string,work_description); + if (work_creator) strcat(string,work_creator); + if (work_owner) strcat(string,work_owner); + if (work_source) strcat(string,work_source); + if (work_license) strcat(string,work_license); + + strcat(string,work_end); + if (license_head) { + strcat(string,license_head); + strcat(string,rdf->license->license_rdf); + strcat(string,license_end); + } + strcat(string,rdf_end); + + return string; +} +*/ + + +/** + * \brief Pull the text out of an RDF entity, depends on how it's stored + * \return A pointer to the entity's static contents as a string + * \param repr The XML element to extract from + * \param entity The desired RDF/Work entity + * + */ +const gchar * +rdf_get_repr_text ( Inkscape::XML::Node * repr, struct rdf_work_entity_t * entity ) +{ + g_return_val_if_fail (repr != NULL, NULL); + g_return_val_if_fail (entity != NULL, NULL); + static gchar * bag = NULL; + gchar * holder = NULL; + + Inkscape::XML::Node * temp=NULL; + switch (entity->datatype) { + case RDF_CONTENT: + temp = sp_repr_children(repr); + if ( temp == NULL ) return NULL; + + return temp->content(); + + case RDF_AGENT: + temp = sp_repr_lookup_name ( repr, "cc:Agent", 1 ); + if ( temp == NULL ) return NULL; + + temp = sp_repr_lookup_name ( temp, "dc:title", 1 ); + if ( temp == NULL ) return NULL; + + temp = sp_repr_children(temp); + if ( temp == NULL ) return NULL; + + return temp->content(); + + case RDF_RESOURCE: + return repr->attribute("rdf:resource"); + + case RDF_XML: + return "xml goes here"; + + case RDF_BAG: + /* clear the static string. yucky. */ + if (bag) g_free(bag); + bag = NULL; + + temp = sp_repr_lookup_name ( repr, "rdf:Bag", 1 ); + if ( temp == NULL ) { + /* backwards compatible: read contents */ + temp = sp_repr_children(repr); + if ( temp == NULL ) return NULL; + + return temp->content(); + } + + for ( temp = sp_repr_children(temp) ; + temp ; + temp = sp_repr_next(temp) ) { + if (!strcmp(temp->name(),"rdf:li") && + temp->firstChild()) { + const gchar * str = temp->firstChild()->content(); + if (bag) { + holder = bag; + bag = g_strconcat(holder, ", ", str, NULL); + g_free(holder); + } + else { + bag = g_strdup(str); + } + } + } + return bag; + + default: + break; + } + return NULL; +} + +unsigned int +rdf_set_repr_text ( Inkscape::XML::Node * repr, + struct rdf_work_entity_t * entity, + gchar const * text ) +{ + g_return_val_if_fail ( repr != NULL, 0); + g_return_val_if_fail ( entity != NULL, 0); + g_return_val_if_fail ( text != NULL, 0); + gchar * str = NULL; + gchar** strlist = NULL; + int i; + + Inkscape::XML::Node * temp=NULL; + Inkscape::XML::Node * child=NULL; + Inkscape::XML::Node * parent=repr; + switch (entity->datatype) { + case RDF_CONTENT: + temp = sp_repr_children(parent); + if ( temp == NULL ) { + temp = sp_repr_new_text( text ); + g_return_val_if_fail (temp != NULL, 0); + + parent->appendChild(temp); + Inkscape::GC::release(temp); + + return TRUE; + } + else { + temp->setContent(text); + return TRUE; + } + + case RDF_AGENT: + temp = sp_repr_lookup_name ( parent, "cc:Agent", 1 ); + if ( temp == NULL ) { + temp = sp_repr_new ( "cc:Agent" ); + g_return_val_if_fail (temp != NULL, 0); + + parent->appendChild(temp); + Inkscape::GC::release(temp); + } + parent = temp; + + temp = sp_repr_lookup_name ( parent, "dc:title", 1 ); + if ( temp == NULL ) { + temp = sp_repr_new ( "dc:title" ); + g_return_val_if_fail (temp != NULL, 0); + + parent->appendChild(temp); + Inkscape::GC::release(temp); + } + parent = temp; + + temp = sp_repr_children(parent); + if ( temp == NULL ) { + temp = sp_repr_new_text( text ); + g_return_val_if_fail (temp != NULL, 0); + + parent->appendChild(temp); + Inkscape::GC::release(temp); + + return TRUE; + } + else { + temp->setContent(text); + return TRUE; + } + + case RDF_RESOURCE: + parent->setAttribute("rdf:resource", text ); + return true; + + case RDF_XML: + return 1; + + case RDF_BAG: + /* find/create the rdf:Bag item */ + temp = sp_repr_lookup_name ( parent, "rdf:Bag", 1 ); + if ( temp == NULL ) { + /* backward compatibility: drop the dc:subject contents */ + while ( (temp = sp_repr_children( parent )) ) { + parent->removeChild(temp); + } + + temp = sp_repr_new ( "rdf:Bag" ); + g_return_val_if_fail (temp != NULL, 0); + + parent->appendChild(temp); + Inkscape::GC::release(temp); + } + parent = temp; + + /* toss all the old list items */ + while ( (temp = sp_repr_children( parent )) ) { + parent->removeChild(temp); + } + + /* chop our list up on commas */ + strlist = g_strsplit( text, ",", 0); + + for (i = 0; (str = strlist[i]); i++) { + temp = sp_repr_new ( "rdf:li" ); + g_return_val_if_fail (temp != NULL, 0); + + parent->appendChild(temp); + Inkscape::GC::release(temp); + + child = sp_repr_new_text( g_strstrip(str) ); + g_return_val_if_fail (child != NULL, 0); + + temp->appendChild(child); + Inkscape::GC::release(child); + } + g_strfreev( strlist ); + + return 1; + + default: + break; + } + return 0; +} + +Inkscape::XML::Node * +rdf_get_rdf_root_repr ( SPDocument * doc, bool build ) +{ + g_return_val_if_fail (doc != NULL, NULL); + g_return_val_if_fail (doc->rroot != NULL, NULL); + + Inkscape::XML::Node * rdf = sp_repr_lookup_name ( doc->rroot, XML_TAG_NAME_RDF ); + + if (rdf == NULL) { + //printf("missing XML '%s'\n",XML_TAG_NAME_RDF); + if (!build) return NULL; + + Inkscape::XML::Node * svg = sp_repr_lookup_name ( doc->rroot, XML_TAG_NAME_SVG ); + g_return_val_if_fail ( svg != NULL, NULL ); + + Inkscape::XML::Node * parent = sp_repr_lookup_name ( svg, XML_TAG_NAME_METADATA ); + if ( parent == NULL ) { + parent = sp_repr_new( XML_TAG_NAME_METADATA ); + g_return_val_if_fail ( parent != NULL, NULL); + + svg->appendChild(parent); + Inkscape::GC::release(parent); + } + + rdf = sp_repr_new( XML_TAG_NAME_RDF ); + g_return_val_if_fail (rdf != NULL, NULL); + + parent->appendChild(rdf); + Inkscape::GC::release(rdf); + } + + /* + * some implementations do not put RDF stuff inside , + * so we need to check for it and add it if we don't see it + */ + Inkscape::XML::Node * want_metadata = sp_repr_parent ( rdf ); + g_return_val_if_fail (want_metadata != NULL, NULL); + if (strcmp( want_metadata->name(), XML_TAG_NAME_METADATA )) { + Inkscape::XML::Node * metadata = sp_repr_new( XML_TAG_NAME_METADATA ); + g_return_val_if_fail (metadata != NULL, NULL); + + /* attach the metadata node */ + want_metadata->appendChild(metadata); + Inkscape::GC::release(metadata); + + /* move the RDF into it */ + Inkscape::GC::anchor(rdf); + sp_repr_unparent ( rdf ); + metadata->appendChild(rdf); + Inkscape::GC::release(rdf); + } + + return rdf; +} + +Inkscape::XML::Node * +rdf_get_xml_repr( SPDocument * doc, gchar const * name, bool build ) +{ + g_return_val_if_fail (name != NULL, NULL); + g_return_val_if_fail (doc != NULL, NULL); + g_return_val_if_fail (doc->rroot != NULL, NULL); + + Inkscape::XML::Node * rdf = rdf_get_rdf_root_repr ( doc, build ); + if (!rdf) return NULL; + + Inkscape::XML::Node * xml = sp_repr_lookup_name ( rdf, name ); + if (xml == NULL) { + //printf("missing XML '%s'\n",name); + if (!build) return NULL; + + xml = sp_repr_new( name ); + g_return_val_if_fail (xml != NULL, NULL); + + xml->setAttribute("rdf:about", "" ); + + rdf->appendChild(xml); + Inkscape::GC::release(xml); + } + + return xml; +} + +Inkscape::XML::Node * +rdf_get_work_repr( SPDocument * doc, gchar const * name, bool build ) +{ + g_return_val_if_fail (name != NULL, NULL); + g_return_val_if_fail (doc != NULL, NULL); + g_return_val_if_fail (doc->rroot != NULL, NULL); + + Inkscape::XML::Node * work = rdf_get_xml_repr ( doc, XML_TAG_NAME_WORK, build ); + if (!work) return NULL; + + Inkscape::XML::Node * item = sp_repr_lookup_name ( work, name, 1 ); + if (item == NULL) { + //printf("missing XML '%s'\n",name); + if (!build) return NULL; + + item = sp_repr_new( name ); + g_return_val_if_fail (item != NULL, NULL); + + work->appendChild(item); + Inkscape::GC::release(item); + } + + return item; +} + + + +/** + * \brief Retrieves a known RDF/Work entity's contents from the document XML by name + * \return A pointer to the entity's static contents as a string, or NULL if no entity exists + * \param entity The desired RDF/Work entity + * + */ +const gchar * +rdf_get_work_entity(SPDocument * doc, struct rdf_work_entity_t * entity) +{ + g_return_val_if_fail (doc != NULL, NULL); + if ( entity == NULL ) return NULL; + //printf("want '%s'\n",entity->title); + + Inkscape::XML::Node * item; + if ( entity->datatype == RDF_XML ) { + item = rdf_get_xml_repr ( doc, entity->tag, FALSE ); + } + else { + item = rdf_get_work_repr( doc, entity->tag, FALSE ); + } + if ( item == NULL ) return NULL; + + const gchar * result = rdf_get_repr_text ( item, entity ); + //printf("found '%s' == '%s'\n", entity->title, result ); + return result; +} + +/** + * \brief Stores a string into a named RDF/Work entity in the document XML + * \param entity The desired RDF/Work entity to replace + * \param string The string to replace the entity contents with + * + */ +unsigned int +rdf_set_work_entity(SPDocument * doc, struct rdf_work_entity_t * entity, + const gchar * text) +{ + g_return_val_if_fail ( entity != NULL, 0 ); + if (text == NULL) { + // FIXME: on a "NULL" text, delete the entity. For now, blank it. + text=""; + } + + /* + printf("changing '%s' (%s) to '%s'\n", + entity->title, + entity->tag, + text); + */ + + Inkscape::XML::Node * item = rdf_get_work_repr( doc, entity->tag, TRUE ); + g_return_val_if_fail ( item != NULL, 0 ); + + return rdf_set_repr_text ( item, entity, text ); +} + +#undef DEBUG_MATCH + +bool +rdf_match_license ( Inkscape::XML::Node * repr, struct rdf_license_t * license ) +{ + g_assert ( repr != NULL ); + g_assert ( license != NULL ); + + bool result=TRUE; +#ifdef DEBUG_MATCH + printf("checking against '%s'\n",license->name); +#endif + + int count = 0; + for (struct rdf_double_t * details = license->details; + details->name; details++ ) { + count++; + } + bool * matched = (bool*)calloc(count,sizeof(bool)); + + for (Inkscape::XML::Node * current = sp_repr_children ( repr ); + current; + current = sp_repr_next ( current ) ) { + + gchar const * attr = current->attribute("rdf:resource"); + if ( attr == NULL ) continue; + +#ifdef DEBUG_MATCH + printf("\texamining '%s' => '%s'\n", current->name(), attr); +#endif + + bool found_match=FALSE; + for (int i=0; iname(), license->details[i].name); + printf("\t\t'%s' vs '%s'\n", attr, license->details[i].resource); +#endif + + if (!strcmp( current->name(), + license->details[i].name ) && + !strcmp( attr, + license->details[i].resource )) { + matched[i]=TRUE; + found_match=TRUE; +#ifdef DEBUG_MATCH + printf("\t\tgood!\n"); +#endif + break; + } + } + if (!found_match) { + // if we checked each known item of the license + // and didn't find it, we must abort + result=FALSE; +#ifdef DEBUG_MATCH + printf("\t\tno '%s' element matched XML (bong)!\n",license->name); +#endif + break; + } + } +#ifdef DEBUG_MATCH + if (result) printf("\t\tall XML found matching elements!\n"); +#endif + for (int i=0; result && iname); +#endif + } + } + +#ifdef DEBUG_MATCH + printf("\t\tall '%s' elements used to match!\n",license->name); +#endif + + free(matched); + +#ifdef DEBUG_MATCH + if (result) printf("matched '%s'\n",license->name); +#endif + return result; +} + +/** + * \brief Attempts to match and retrieve a known RDF/License from the document XML + * \return A pointer to the static RDF license structure + * + */ +struct rdf_license_t * +rdf_get_license(SPDocument * document) +{ + Inkscape::XML::Node * repr = rdf_get_xml_repr ( document, XML_TAG_NAME_LICENSE, FALSE ); + if (repr) { + for (struct rdf_license_t * license = rdf_licenses; + license->name; license++ ) { + if ( rdf_match_license ( repr, license ) ) return license; + } + } +#ifdef DEBUG_MATCH + else { + printf("no license XML\n"); + } +#endif + return NULL; +} + +/** + * \brief Stores an RDF/License XML in the document XML + * \param document Which document to update + * \param license The desired RDF/License structure to store; NULL drops old license, so can be used for proprietary license. + * + */ +void +rdf_set_license(SPDocument * document, struct rdf_license_t const * license) +{ + // drop old license section + Inkscape::XML::Node * repr = rdf_get_xml_repr ( document, XML_TAG_NAME_LICENSE, FALSE ); + if (repr) sp_repr_unparent(repr); + + if (!license) return; + + // build new license section + repr = rdf_get_xml_repr ( document, XML_TAG_NAME_LICENSE, TRUE ); + g_assert ( repr ); + + repr->setAttribute("rdf:about", license->uri ); + + for (struct rdf_double_t * detail = license->details; + detail->name; detail++) { + Inkscape::XML::Node * child = sp_repr_new( detail->name ); + g_assert ( child != NULL ); + + child->setAttribute("rdf:resource", detail->resource ); + repr->appendChild(child); + Inkscape::GC::release(child); + } +} + +struct rdf_entity_default_t { + gchar const * name; + gchar const * text; +}; +struct rdf_entity_default_t rdf_defaults[] = { + { "format", "image/svg+xml", }, + { "type", "http://purl.org/dc/dcmitype/StillImage", }, + { NULL, NULL, } +}; + +void +rdf_set_defaults ( SPDocument * document ) +{ + g_assert ( document != NULL ); + + // Create metadata node if it doesn't already exist + if (!sp_item_group_get_child_by_name ((SPGroup *) document->root, NULL, + XML_TAG_NAME_METADATA)) { + // create repr + Inkscape::XML::Node * rnew = sp_repr_new (XML_TAG_NAME_METADATA); + // insert into the document + document->rroot->addChild(rnew, NULL); + // clean up + Inkscape::GC::release(rnew); + } + + /* install defaults */ + for ( struct rdf_entity_default_t * rdf_default = rdf_defaults; + rdf_default->name; + rdf_default++) { + struct rdf_work_entity_t * entity = rdf_find_entity ( rdf_default->name ); + g_assert ( entity != NULL ); + + if ( rdf_get_work_entity ( document, entity ) == NULL ) { + rdf_set_work_entity ( document, entity, rdf_default->text ); + } + } +} + + +/* + 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 : diff --git a/src/dialogs/rdf.h b/src/dialogs/rdf.h new file mode 100644 index 000000000..29da859c2 --- /dev/null +++ b/src/dialogs/rdf.h @@ -0,0 +1,124 @@ +/** + * + * \brief headers for RDF types + * + * Authors: + * Kees Cook + * + * Copyright (C) 2004 Kees Cook + * + * Released under GNU GPL, read the file 'COPYING' for more information + * + */ +#ifndef _RDF_H_ +#define _RDF_H_ + +#include + +#include +#include "document.h" + +// yeah, it's not a triple yet... +/** + * \brief Holds license name/resource doubles for rdf_license_t entries + */ +struct rdf_double_t { + gchar *name; + gchar *resource; +}; + +/** + * \brief Holds license name and RDF information + */ +struct rdf_license_t { + gchar *name; /* localized name of this license */ + gchar *uri; /* URL for the RDF/Work/license element */ + struct rdf_double_t *details; /* the license details */ +// gchar *fragment; /* XML contents for the RDF/License tag */ +}; + +extern rdf_license_t rdf_licenses []; + +/** + * \brief Describes how a given RDF entity is stored in XML + */ +enum RDFType { + RDF_CONTENT, // direct between-XML-tags content + RDF_AGENT, // requires the "Agent" hierarchy before doing content + RDF_RESOURCE, // stored in "rdf:resource" element + RDF_XML, // literal XML + RDF_BAG // rdf:Bag resources +}; + +/** + * \brief Describes how a given RDF entity should be edited + */ +enum RDF_Format { + RDF_FORMAT_LINE, // uses single line data (GtkEntry) + RDF_FORMAT_MULTILINE, // uses multiline data (GtkTextView) + RDF_FORMAT_SPECIAL // uses some other edit methods +}; + +enum RDF_Editable { + RDF_EDIT_GENERIC, // editable via generic widgets + RDF_EDIT_SPECIAL, // special widgets are needed + RDF_EDIT_HARDCODED // isn't editable +}; + +/** + * \brief Holds known RDF/Work tags + */ +struct rdf_work_entity_t { + char *name; /* unique name of this entity for internal reference */ + gchar *title; /* localized title of this entity for data entry */ + gchar *tag; /* namespace tag for the RDF/Work element */ + RDFType datatype; /* how to extract/inject the RDF information */ + gchar *tip; /* tool tip to explain the meaning of the entity */ + RDF_Format format; /* in what format is this data edited? */ + RDF_Editable editable;/* in what way is the data editable? */ +}; + +extern rdf_work_entity_t rdf_work_entities []; + +/** + * \brief Generic collection of RDF information for the RDF debug function + */ +struct rdf_t { + gchar* work_title; + gchar* work_date; + gchar* work_creator; + gchar* work_owner; + gchar* work_publisher; + gchar* work_type; + gchar* work_source; + gchar* work_subject; + gchar* work_description; + struct rdf_license_t* license; +}; + +struct rdf_work_entity_t * rdf_find_entity(gchar const * name); + +const gchar * rdf_get_work_entity(SPDocument * doc, + struct rdf_work_entity_t * entity); +unsigned int rdf_set_work_entity(SPDocument * doc, + struct rdf_work_entity_t * entity, + const gchar * text); + +struct rdf_license_t * rdf_get_license(SPDocument * doc); +void rdf_set_license(SPDocument * doc, + struct rdf_license_t const * license); + +void rdf_set_defaults ( SPDocument * document ); + +#endif // _RDF_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 : diff --git a/src/dialogs/sp-attribute-widget.cpp b/src/dialogs/sp-attribute-widget.cpp new file mode 100644 index 000000000..d7c4316e1 --- /dev/null +++ b/src/dialogs/sp-attribute-widget.cpp @@ -0,0 +1,802 @@ +#define __SP_ATTRIBUTE_WIDGET_C__ + +/** + * \brief SPAttributeWidget + * + * Widget, that listens and modifies repr attributes + * + * Authors: + * Lauris Kaplinski + * + * Copyright (C) 2001 Ximian, Inc. + * + * Licensed under GNU GPL + */ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include "xml/repr.h" +#include "macros.h" +#include "document.h" +#include "sp-object.h" +#include + +#include "sp-attribute-widget.h" + +static void sp_attribute_widget_class_init (SPAttributeWidgetClass *klass); +static void sp_attribute_widget_init (SPAttributeWidget *widget); +static void sp_attribute_widget_destroy (GtkObject *object); + +static void sp_attribute_widget_changed (GtkEditable *editable); + +static void sp_attribute_widget_object_modified ( SPObject *object, + guint flags, + SPAttributeWidget *spaw ); +static void sp_attribute_widget_object_release ( SPObject *object, + SPAttributeWidget *spaw ); + +static GtkEntryClass *parent_class; + + + + +GtkType +sp_attribute_widget_get_type (void) +{ + static GtkType type = 0; + if (!type) { + static const GtkTypeInfo info = { + "SPAttributeWidget", + sizeof (SPAttributeWidget), + sizeof (SPAttributeWidgetClass), + (GtkClassInitFunc) sp_attribute_widget_class_init, + (GtkObjectInitFunc) sp_attribute_widget_init, + NULL, NULL, NULL + }; + type = gtk_type_unique (GTK_TYPE_ENTRY, &info); + } + return type; + +} // end of sp_attribute_widget_get_type() + + + +static void +sp_attribute_widget_class_init (SPAttributeWidgetClass *klass) +{ + GtkObjectClass *object_class; + GtkWidgetClass *widget_class; + GtkEditableClass *editable_class; + + object_class = GTK_OBJECT_CLASS (klass); + widget_class = GTK_WIDGET_CLASS (klass); + editable_class = GTK_EDITABLE_CLASS (klass); + + parent_class = (GtkEntryClass*)gtk_type_class (GTK_TYPE_ENTRY); + + object_class->destroy = sp_attribute_widget_destroy; + + editable_class->changed = sp_attribute_widget_changed; + +} // end of sp_attribute_widget_class_init() + + + +static void +sp_attribute_widget_init (SPAttributeWidget *spaw) +{ + spaw->blocked = FALSE; + spaw->hasobj = FALSE; + + spaw->src.object = NULL; + + spaw->attribute = NULL; +} + + + +static void +sp_attribute_widget_destroy (GtkObject *object) +{ + + SPAttributeWidget *spaw; + + spaw = SP_ATTRIBUTE_WIDGET (object); + + if (spaw->attribute) { + g_free (spaw->attribute); + spaw->attribute = NULL; + } + + + if (spaw->hasobj) { + + if (spaw->src.object) { + sp_signal_disconnect_by_data (spaw->src.object, spaw); + spaw->src.object = NULL; + } + } else { + + if (spaw->src.repr) { + spaw->src.repr = Inkscape::GC::release(spaw->src.repr); + } + } // end of if() + + ((GtkObjectClass *) parent_class)->destroy (object); + +} + + + +static void +sp_attribute_widget_changed (GtkEditable *editable) +{ + + SPAttributeWidget *spaw; + + spaw = SP_ATTRIBUTE_WIDGET (editable); + + if (!spaw->blocked) { + + const gchar *text; + spaw->blocked = TRUE; + text = gtk_entry_get_text (GTK_ENTRY (spaw)); + if (!*text) + text = NULL; + + if (spaw->hasobj && spaw->src.object) { + + if (!sp_repr_set_attr ( SP_OBJECT_REPR (spaw->src.object), + spaw->attribute, text) ) + { + /* Cannot set attribute */ + text = SP_OBJECT_REPR (spaw->src.object)->attribute(spaw->attribute); + gtk_entry_set_text (GTK_ENTRY (spaw), text ? text : ""); + } + sp_document_done (SP_OBJECT_DOCUMENT (spaw->src.object)); + + } else if (spaw->src.repr) { + + if (!sp_repr_set_attr (spaw->src.repr, spaw->attribute, text)) + { + /* Cannot set attribute */ + text = spaw->src.repr->attribute(spaw->attribute); + gtk_entry_set_text (GTK_ENTRY (spaw), text ? text : ""); + } + /* TODO: Warning! Undo will not be flushed in given case */ + } + spaw->blocked = FALSE; + } + +} // end of sp_attribute_widget_changed() + + + +GtkWidget * +sp_attribute_widget_new ( SPObject *object, const gchar *attribute ) +{ + SPAttributeWidget *spaw; + + g_return_val_if_fail (!object || SP_IS_OBJECT (object), NULL); + g_return_val_if_fail (!object || attribute, NULL); + + spaw = (SPAttributeWidget*)gtk_type_new (SP_TYPE_ATTRIBUTE_WIDGET); + + sp_attribute_widget_set_object (spaw, object, attribute); + + return GTK_WIDGET (spaw); + +} // end of sp_attribute_widget_new() + + + +GtkWidget * +sp_attribute_widget_new_repr ( Inkscape::XML::Node *repr, const gchar *attribute ) +{ + SPAttributeWidget *spaw; + + spaw = (SPAttributeWidget*)gtk_type_new (SP_TYPE_ATTRIBUTE_WIDGET); + + sp_attribute_widget_set_repr (spaw, repr, attribute); + + return GTK_WIDGET (spaw); +} + + + +void +sp_attribute_widget_set_object ( SPAttributeWidget *spaw, + SPObject *object, + const gchar *attribute ) +{ + + g_return_if_fail (spaw != NULL); + g_return_if_fail (SP_IS_ATTRIBUTE_WIDGET (spaw)); + g_return_if_fail (!object || SP_IS_OBJECT (object)); + g_return_if_fail (!object || attribute); + g_return_if_fail (attribute != NULL); + + if (spaw->attribute) { + g_free (spaw->attribute); + spaw->attribute = NULL; + } + + if (spaw->hasobj) { + + if (spaw->src.object) { + sp_signal_disconnect_by_data (spaw->src.object, spaw); + spaw->src.object = NULL; + } + } else { + + if (spaw->src.repr) { + spaw->src.repr = Inkscape::GC::release(spaw->src.repr); + } + } + + spaw->hasobj = TRUE; + + if (object) { + const gchar *val; + + spaw->blocked = TRUE; + spaw->src.object = object; + g_signal_connect ( G_OBJECT (object), "modified", + G_CALLBACK (sp_attribute_widget_object_modified), + spaw ); + g_signal_connect ( G_OBJECT (object), "release", + G_CALLBACK (sp_attribute_widget_object_release), + spaw ); + + spaw->attribute = g_strdup (attribute); + + val = SP_OBJECT_REPR (object)->attribute(attribute); + gtk_entry_set_text (GTK_ENTRY (spaw), val ? val : (const gchar *) ""); + spaw->blocked = FALSE; + } + + gtk_widget_set_sensitive (GTK_WIDGET (spaw), (spaw->src.object != NULL)); + +} // end of sp_attribute_widget_set_object() + + + +void +sp_attribute_widget_set_repr ( SPAttributeWidget *spaw, + Inkscape::XML::Node *repr, + const gchar *attribute ) +{ + + g_return_if_fail (spaw != NULL); + g_return_if_fail (SP_IS_ATTRIBUTE_WIDGET (spaw)); + g_return_if_fail (attribute != NULL); + + if (spaw->attribute) { + g_free (spaw->attribute); + spaw->attribute = NULL; + } + + if (spaw->hasobj) { + + if (spaw->src.object) { + sp_signal_disconnect_by_data (spaw->src.object, spaw); + spaw->src.object = NULL; + } + } else { + + if (spaw->src.repr) { + spaw->src.repr = Inkscape::GC::release(spaw->src.repr); + } + } + + spaw->hasobj = FALSE; + + if (repr) { + const gchar *val; + + spaw->blocked = TRUE; + spaw->src.repr = Inkscape::GC::anchor(repr); + spaw->attribute = g_strdup (attribute); + + val = repr->attribute(attribute); + gtk_entry_set_text (GTK_ENTRY (spaw), val ? val : (const gchar *) ""); + spaw->blocked = FALSE; + } + + gtk_widget_set_sensitive (GTK_WIDGET (spaw), (spaw->src.repr != NULL)); + +} // end of sp_attribute_widget_set_repr() + + + +static void +sp_attribute_widget_object_modified ( SPObject *object, + guint flags, + SPAttributeWidget *spaw ) +{ + + if (flags && SP_OBJECT_MODIFIED_FLAG) { + + const gchar *val, *text; + val = SP_OBJECT_REPR (spaw->src.object)->attribute(spaw->attribute); + text = gtk_entry_get_text (GTK_ENTRY (spaw)); + + if (val || text) { + + if (!val || !text || strcmp (val, text)) { + /* We are different */ + spaw->blocked = TRUE; + gtk_entry_set_text ( GTK_ENTRY (spaw), + val ? val : (const gchar *) ""); + spaw->blocked = FALSE; + } // end of if() + + } // end of if() + + } //end of if() + +} // end of sp_attribute_widget_object_modified() + + + +static void +sp_attribute_widget_object_release ( SPObject *object, + SPAttributeWidget *spaw ) +{ + sp_attribute_widget_set_object (spaw, NULL, NULL); +} + + + +/* SPAttributeTable */ + +static void sp_attribute_table_class_init (SPAttributeTableClass *klass); +static void sp_attribute_table_init (SPAttributeTable *widget); +static void sp_attribute_table_destroy (GtkObject *object); + +static void sp_attribute_table_object_modified (SPObject *object, guint flags, SPAttributeTable *spaw); +static void sp_attribute_table_object_release (SPObject *object, SPAttributeTable *spaw); +static void sp_attribute_table_entry_changed (GtkEditable *editable, SPAttributeTable *spat); + +static GtkVBoxClass *table_parent_class; + + + + +GtkType +sp_attribute_table_get_type (void) +{ + static GtkType type = 0; + if (!type) { + static const GtkTypeInfo info = { + "SPAttributeTable", + sizeof (SPAttributeTable), + sizeof (SPAttributeTableClass), + (GtkClassInitFunc) sp_attribute_table_class_init, + (GtkObjectInitFunc) sp_attribute_table_init, + NULL, NULL, NULL + }; + type = gtk_type_unique (GTK_TYPE_VBOX, &info); + } + return type; + +} // end of sp_attribute_table_get_type() + + + +static void +sp_attribute_table_class_init (SPAttributeTableClass *klass) +{ + GtkObjectClass *object_class; + GtkWidgetClass *widget_class; + + object_class = GTK_OBJECT_CLASS (klass); + widget_class = GTK_WIDGET_CLASS (klass); + + table_parent_class = (GtkVBoxClass*)gtk_type_class (GTK_TYPE_VBOX); + + object_class->destroy = sp_attribute_table_destroy; + +} // end of sp_attribute_table_class_init() + + + +static void +sp_attribute_table_init ( SPAttributeTable *spat ) +{ + spat->blocked = FALSE; + spat->hasobj = FALSE; + spat->table = NULL; + spat->src.object = NULL; + spat->num_attr = 0; + spat->attributes = NULL; + spat->entries = NULL; +} + +static void +sp_attribute_table_destroy ( GtkObject *object ) +{ + SPAttributeTable *spat; + + spat = SP_ATTRIBUTE_TABLE (object); + + if (spat->attributes) { + gint i; + for (i = 0; i < spat->num_attr; i++) { + g_free (spat->attributes[i]); + } + g_free (spat->attributes); + spat->attributes = NULL; + } + + if (spat->hasobj) { + + if (spat->src.object) { + sp_signal_disconnect_by_data (spat->src.object, spat); + spat->src.object = NULL; + } + } else { + if (spat->src.repr) { + spat->src.repr = Inkscape::GC::release(spat->src.repr); + } + } // end of if() + + + if (spat->entries) { + g_free (spat->entries); + spat->entries = NULL; + } + + spat->table = NULL; + + if (((GtkObjectClass *) table_parent_class)->destroy) { + (* ((GtkObjectClass *) table_parent_class)->destroy) (object); + } + +} // end of sp_attribute_table_destroy() + + +GtkWidget * +sp_attribute_table_new ( SPObject *object, + gint num_attr, + const gchar **labels, + const gchar **attributes ) +{ + SPAttributeTable *spat; + + g_return_val_if_fail (!object || SP_IS_OBJECT (object), NULL); + g_return_val_if_fail (!object || (num_attr > 0), NULL); + g_return_val_if_fail (!num_attr || (labels && attributes), NULL); + + spat = (SPAttributeTable*)gtk_type_new (SP_TYPE_ATTRIBUTE_TABLE); + + sp_attribute_table_set_object (spat, object, num_attr, labels, attributes); + + return GTK_WIDGET (spat); + +} // end of sp_attribute_table_new() + + + +GtkWidget * +sp_attribute_table_new_repr ( Inkscape::XML::Node *repr, + gint num_attr, + const gchar **labels, + const gchar **attributes ) +{ + SPAttributeTable *spat; + + g_return_val_if_fail (!num_attr || (labels && attributes), NULL); + + spat = (SPAttributeTable*)gtk_type_new (SP_TYPE_ATTRIBUTE_TABLE); + + sp_attribute_table_set_repr (spat, repr, num_attr, labels, attributes); + + return GTK_WIDGET (spat); + +} // end of sp_attribute_table_new_repr() + + + +#define XPAD 4 +#define YPAD 0 + +void +sp_attribute_table_set_object ( SPAttributeTable *spat, + SPObject *object, + gint num_attr, + const gchar **labels, + const gchar **attributes ) +{ + + g_return_if_fail (spat != NULL); + g_return_if_fail (SP_IS_ATTRIBUTE_TABLE (spat)); + g_return_if_fail (!object || SP_IS_OBJECT (object)); + g_return_if_fail (!object || (num_attr > 0)); + g_return_if_fail (!num_attr || (labels && attributes)); + + if (spat->table) { + gtk_widget_destroy (spat->table); + spat->table = NULL; + } + + if (spat->attributes) { + gint i; + for (i = 0; i < spat->num_attr; i++) { + g_free (spat->attributes[i]); + } + g_free (spat->attributes); + spat->attributes = NULL; + } + + if (spat->entries) { + g_free (spat->entries); + spat->entries = NULL; + } + + if (spat->hasobj) { + if (spat->src.object) { + sp_signal_disconnect_by_data (spat->src.object, spat); + spat->src.object = NULL; + } + } else { + if (spat->src.repr) { + spat->src.repr = Inkscape::GC::release(spat->src.repr); + } + } + + spat->hasobj = TRUE; + + if (object) { + gint i; + + spat->blocked = TRUE; + + /* Set up object */ + spat->src.object = object; + spat->num_attr = num_attr; + g_signal_connect ( G_OBJECT (object), "modified", + G_CALLBACK (sp_attribute_table_object_modified), + spat ); + g_signal_connect ( G_OBJECT (object), "release", + G_CALLBACK (sp_attribute_table_object_release), + spat ); + /* Create table */ + spat->table = gtk_table_new (num_attr, 2, FALSE); + gtk_container_add (GTK_CONTAINER (spat), spat->table); + /* Arrays */ + spat->attributes = g_new0 (gchar *, num_attr); + spat->entries = g_new0 (GtkWidget *, num_attr); + /* Fill rows */ + for (i = 0; i < num_attr; i++) { + GtkWidget *w; + const gchar *val; + + spat->attributes[i] = g_strdup (attributes[i]); + w = gtk_label_new (_(labels[i])); + gtk_widget_show (w); + gtk_misc_set_alignment (GTK_MISC (w), 1.0, 0.5); + gtk_table_attach ( GTK_TABLE (spat->table), w, 0, 1, i, i + 1, + GTK_FILL, + (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), + XPAD, YPAD ); + w = gtk_entry_new (); + gtk_widget_show (w); + val = SP_OBJECT_REPR (object)->attribute(attributes[i]); + gtk_entry_set_text (GTK_ENTRY (w), val ? val : (const gchar *) ""); + gtk_table_attach ( GTK_TABLE (spat->table), w, 1, 2, i, i + 1, + (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), + (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), + XPAD, YPAD ); + spat->entries[i] = w; + g_signal_connect ( G_OBJECT (w), "changed", + G_CALLBACK (sp_attribute_table_entry_changed), + spat ); + } + /* Show table */ + gtk_widget_show (spat->table); + + spat->blocked = FALSE; + } + + gtk_widget_set_sensitive ( GTK_WIDGET (spat), + (spat->src.object != NULL) ); + +} // end of sp_attribute_table_set_object() + + + +void +sp_attribute_table_set_repr ( SPAttributeTable *spat, + Inkscape::XML::Node *repr, + gint num_attr, + const gchar **labels, + const gchar **attributes ) +{ + g_return_if_fail (spat != NULL); + g_return_if_fail (SP_IS_ATTRIBUTE_TABLE (spat)); + g_return_if_fail (!num_attr || (labels && attributes)); + + if (spat->table) { + gtk_widget_destroy (spat->table); + spat->table = NULL; + } + + if (spat->attributes) { + gint i; + for (i = 0; i < spat->num_attr; i++) { + g_free (spat->attributes[i]); + } + g_free (spat->attributes); + spat->attributes = NULL; + } + + if (spat->entries) { + g_free (spat->entries); + spat->entries = NULL; + } + + if (spat->hasobj) { + if (spat->src.object) { + sp_signal_disconnect_by_data (spat->src.object, spat); + spat->src.object = NULL; + } + } else { + if (spat->src.repr) { + spat->src.repr = Inkscape::GC::release(spat->src.repr); + } + } + + spat->hasobj = FALSE; + + if (repr) { + gint i; + + spat->blocked = TRUE; + + /* Set up repr */ + spat->src.repr = Inkscape::GC::anchor(repr); + spat->num_attr = num_attr; + /* Create table */ + spat->table = gtk_table_new (num_attr, 2, FALSE); + gtk_container_add (GTK_CONTAINER (spat), spat->table); + /* Arrays */ + spat->attributes = g_new0 (gchar *, num_attr); + spat->entries = g_new0 (GtkWidget *, num_attr); + + /* Fill rows */ + for (i = 0; i < num_attr; i++) { + GtkWidget *w; + const gchar *val; + + spat->attributes[i] = g_strdup (attributes[i]); + w = gtk_label_new (labels[i]); + gtk_widget_show (w); + gtk_misc_set_alignment (GTK_MISC (w), 1.0, 0.5); + gtk_table_attach ( GTK_TABLE (spat->table), w, 0, 1, i, i + 1, + GTK_FILL, + (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), + XPAD, YPAD ); + w = gtk_entry_new (); + gtk_widget_show (w); + val = repr->attribute(attributes[i]); + gtk_entry_set_text (GTK_ENTRY (w), val ? val : (const gchar *) ""); + gtk_table_attach ( GTK_TABLE (spat->table), w, 1, 2, i, i + 1, + (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), + (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), + XPAD, YPAD ); + spat->entries[i] = w; + g_signal_connect ( G_OBJECT (w), "changed", + G_CALLBACK (sp_attribute_table_entry_changed), + spat ); + } + /* Show table */ + gtk_widget_show (spat->table); + + spat->blocked = FALSE; + } + + gtk_widget_set_sensitive (GTK_WIDGET (spat), (spat->src.repr != NULL)); + +} // end of sp_attribute_table_set_repr() + + + +static void +sp_attribute_table_object_modified ( SPObject *object, + guint flags, + SPAttributeTable *spat ) +{ + if (flags && SP_OBJECT_MODIFIED_FLAG) + { + gint i; + for (i = 0; i < spat->num_attr; i++) { + const gchar *val, *text; + val = SP_OBJECT_REPR (spat->src.object)->attribute(spat->attributes[i]); + text = gtk_entry_get_text (GTK_ENTRY (spat->entries[i])); + if (val || text) { + if (!val || !text || strcmp (val, text)) { + /* We are different */ + spat->blocked = TRUE; + gtk_entry_set_text ( GTK_ENTRY (spat->entries[i]), + val ? val : (const gchar *) ""); + spat->blocked = FALSE; + } + } + } + } // end of if() + +} // end of sp_attribute_table_object_modified() + + + +static void +sp_attribute_table_object_release (SPObject *object, SPAttributeTable *spat) +{ + sp_attribute_table_set_object (spat, NULL, 0, NULL, NULL); +} + + + +static void +sp_attribute_table_entry_changed ( GtkEditable *editable, + SPAttributeTable *spat ) +{ + if (!spat->blocked) + { + gint i; + for (i = 0; i < spat->num_attr; i++) { + + if (GTK_WIDGET (editable) == spat->entries[i]) { + const gchar *text; + spat->blocked = TRUE; + text = gtk_entry_get_text (GTK_ENTRY (spat->entries[i])); + + if (!*text) + text = NULL; + + if (spat->hasobj && spat->src.object) { + if (!sp_repr_set_attr ( SP_OBJECT_REPR (spat->src.object), + spat->attributes[i], text)) + { + /* Cannot set attribute */ + text = SP_OBJECT_REPR (spat->src.object)->attribute(spat->attributes[i]); + gtk_entry_set_text ( GTK_ENTRY (spat->entries[i]), + text ? text : (const gchar *) ""); + } + sp_document_done (SP_OBJECT_DOCUMENT (spat->src.object)); + + } else if (spat->src.repr) { + + if (!sp_repr_set_attr (spat->src.repr, + spat->attributes[i], text)) + { + /* Cannot set attribute */ + text = spat->src.repr->attribute(spat->attributes[i]); + gtk_entry_set_text ( GTK_ENTRY (spat->entries[i]), + text ? text : (const gchar *) "" ); + } + /* TODO: Warning! Undo will not be flushed in given case */ + } + spat->blocked = FALSE; + return; + } + } + g_warning ("file %s: line %d: Entry signalled change, but there is no such entry", __FILE__, __LINE__); + } // end of if() + +} // end of sp_attribute_table_entry_changed() + +/* + 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:textwidth=99 : diff --git a/src/dialogs/sp-attribute-widget.h b/src/dialogs/sp-attribute-widget.h new file mode 100644 index 000000000..d5b2075ce --- /dev/null +++ b/src/dialogs/sp-attribute-widget.h @@ -0,0 +1,128 @@ +#ifndef __SP_ATTRIBUTE_WIDGET_H__ +#define __SP_ATTRIBUTE_WIDGET_H__ + +/** + * \brief SPAttributeWidget + * + * Widget, that listens and modifies repr attributes + * + * Authors: + * Lauris Kaplinski + * + * Copyright (C) 2002 authors + * Copyright (C) 2001 Ximian, Inc. + * + * Licensed under GNU GPL, read the file 'COPYING' for more information + */ + +#include + + + +#define SP_TYPE_ATTRIBUTE_WIDGET (sp_attribute_widget_get_type ()) +#define SP_ATTRIBUTE_WIDGET(obj) (GTK_CHECK_CAST ((obj), SP_TYPE_ATTRIBUTE_WIDGET, SPAttributeWidget)) +#define SP_ATTRIBUTE_WIDGET_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), SP_TYPE_ATTRIBUTE_WIDGET, SPAttributeWidgetClass)) +#define SP_IS_ATTRIBUTE_WIDGET(obj) (GTK_CHECK_TYPE ((obj), SP_TYPE_ATTRIBUTE_WIDGET)) +#define SP_IS_ATTRIBUTE_WIDGET_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), SP_TYPE_ATTRIBUTE_WIDGET)) + +#define SP_TYPE_ATTRIBUTE_TABLE (sp_attribute_table_get_type ()) +#define SP_ATTRIBUTE_TABLE(obj) (GTK_CHECK_CAST ((obj), SP_TYPE_ATTRIBUTE_TABLE, SPAttributeTable)) +#define SP_ATTRIBUTE_TABLE_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), SP_TYPE_ATTRIBUTE_TABLE, SPAttributeTableClass)) +#define SP_IS_ATTRIBUTE_TABLE(obj) (GTK_CHECK_TYPE ((obj), SP_TYPE_ATTRIBUTE_TABLE)) +#define SP_IS_ATTRIBUTE_TABLE_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), SP_TYPE_ATTRIBUTE_TABLE)) + +namespace Inkscape { +namespace XML { +class Node; +} +} + + +struct SPAttributeWidget; +struct SPAttributeWidgetClass; + +struct SPAttributeTable; +struct SPAttributeTableClass; + +#include +#include + +#include + +struct SPAttributeWidget { + GtkEntry entry; + guint blocked : 1; + guint hasobj : 1; + union { + SPObject *object; + Inkscape::XML::Node *repr; + } src; + gchar *attribute; +}; + +struct SPAttributeWidgetClass { + GtkEntryClass entry_class; +}; + +GtkType sp_attribute_widget_get_type (void); + +GtkWidget *sp_attribute_widget_new (SPObject *object, const gchar *attribute); +GtkWidget *sp_attribute_widget_new_repr (Inkscape::XML::Node *repr, const gchar *attribute); + +void sp_attribute_widget_set_object ( SPAttributeWidget *spw, + SPObject *object, + const gchar *attribute ); +void sp_attribute_widget_set_repr ( SPAttributeWidget *spw, + Inkscape::XML::Node *repr, + const gchar *attribute ); + +/* SPAttributeTable */ + +struct SPAttributeTable { + GtkVBox vbox; + guint blocked : 1; + guint hasobj : 1; + GtkWidget *table; + union { + SPObject *object; + Inkscape::XML::Node *repr; + } src; + gint num_attr; + gchar **attributes; + GtkWidget **entries; +}; + +struct SPAttributeTableClass { + GtkEntryClass entry_class; +}; + +GtkType sp_attribute_table_get_type (void); + +GtkWidget *sp_attribute_table_new ( SPObject *object, gint num_attr, + const gchar **labels, + const gchar **attributes ); +GtkWidget *sp_attribute_table_new_repr ( Inkscape::XML::Node *repr, gint num_attr, + const gchar **labels, + const gchar **attributes ); +void sp_attribute_table_set_object ( SPAttributeTable *spw, + SPObject *object, gint num_attr, + const gchar **labels, + const gchar **attrs ); +void sp_attribute_table_set_repr ( SPAttributeTable *spw, + Inkscape::XML::Node *repr, gint num_attr, + const gchar **labels, + const gchar **attrs ); + + +#endif + +/* + 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:textwidth=99 : diff --git a/src/dialogs/stroke-style.cpp b/src/dialogs/stroke-style.cpp new file mode 100644 index 000000000..b252cd125 --- /dev/null +++ b/src/dialogs/stroke-style.cpp @@ -0,0 +1,1726 @@ +#define __SP_STROKE_STYLE_C__ + +/** + * \brief Stroke style dialog + * + * Authors: + * Lauris Kaplinski + * Bryce Harrington + * bulia byak + * + * Copyright (C) 2001-2005 authors + * Copyright (C) 2001 Ximian, Inc. + * Copyright (C) 2004 John Cliff + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#define noSP_SS_VERBOSE + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + + + +#include + +#include +#include "helper/unit-menu.h" +#include "helper/units.h" +#include "svg/css-ostringstream.h" +#include "widgets/sp-widget.h" +#include "widgets/spw-utilities.h" +#include "sp-linear-gradient.h" +#include "sp-radial-gradient.h" +#include "sp-marker.h" +#include +#include +#include +#include "style.h" +#include "gradient-chemistry.h" +#include "sp-namedview.h" +#include "desktop-handles.h" +#include "desktop-style.h" +#include "selection.h" +#include "inkscape.h" +#include "inkscape-stock.h" +#include "dialogs/dialog-events.h" +#include "sp-text.h" +#include "sp-rect.h" +#include "document-private.h" +#include "display/nr-arena.h" +#include "display/nr-arena-item.h" +#include "path-prefix.h" +#include "widgets/icon.h" +#include "helper/stock-items.h" +#include "io/sys.h" + +#include "dialogs/stroke-style.h" + +/* Paint */ + +static void sp_stroke_style_paint_construct(SPWidget *spw, SPPaintSelector *psel); +static void sp_stroke_style_paint_selection_modified (SPWidget *spw, Inkscape::Selection *selection, guint flags, SPPaintSelector *psel); +static void sp_stroke_style_paint_selection_changed (SPWidget *spw, Inkscape::Selection *selection, SPPaintSelector *psel); +static void sp_stroke_style_paint_update(SPWidget *spw); + +static void sp_stroke_style_paint_mode_changed(SPPaintSelector *psel, SPPaintSelectorMode mode, SPWidget *spw); +static void sp_stroke_style_paint_dragged(SPPaintSelector *psel, SPWidget *spw); +static void sp_stroke_style_paint_changed(SPPaintSelector *psel, SPWidget *spw); + +static void sp_stroke_style_widget_change_subselection ( Inkscape::Application *inkscape, SPDesktop *desktop, SPWidget *spw ); + +GtkWidget * +sp_stroke_style_paint_widget_new(void) +{ + GtkWidget *spw, *psel; + + spw = sp_widget_new_global(INKSCAPE); + + psel = sp_paint_selector_new(false); // without fillrule selector + gtk_widget_show(psel); + gtk_container_add(GTK_CONTAINER(spw), psel); + gtk_object_set_data(GTK_OBJECT(spw), "paint-selector", psel); + + gtk_signal_connect(GTK_OBJECT(spw), "construct", + GTK_SIGNAL_FUNC(sp_stroke_style_paint_construct), + psel); + gtk_signal_connect(GTK_OBJECT(spw), "modify_selection", + GTK_SIGNAL_FUNC(sp_stroke_style_paint_selection_modified), + psel); + gtk_signal_connect(GTK_OBJECT(spw), "change_selection", + GTK_SIGNAL_FUNC(sp_stroke_style_paint_selection_changed), + psel); + + g_signal_connect (INKSCAPE, "change_subselection", G_CALLBACK (sp_stroke_style_widget_change_subselection), spw); + + gtk_signal_connect(GTK_OBJECT(psel), "mode_changed", + GTK_SIGNAL_FUNC(sp_stroke_style_paint_mode_changed), + spw); + gtk_signal_connect(GTK_OBJECT(psel), "dragged", + GTK_SIGNAL_FUNC(sp_stroke_style_paint_dragged), + spw); + gtk_signal_connect(GTK_OBJECT(psel), "changed", + GTK_SIGNAL_FUNC(sp_stroke_style_paint_changed), + spw); + + sp_stroke_style_paint_update (SP_WIDGET(spw)); + return spw; +} + +static void +sp_stroke_style_paint_construct(SPWidget *spw, SPPaintSelector *psel) +{ +#ifdef SP_SS_VERBOSE + g_print( "Stroke style widget constructed: inkscape %p repr %p\n", + spw->inkscape, spw->repr ); +#endif + if (spw->inkscape) { + sp_stroke_style_paint_update (spw); + } +} + +static void +sp_stroke_style_paint_selection_modified ( SPWidget *spw, + Inkscape::Selection *selection, + guint flags, + SPPaintSelector *psel) +{ + if (flags & ( SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_PARENT_MODIFIED_FLAG | + SP_OBJECT_STYLE_MODIFIED_FLAG) ) { + sp_stroke_style_paint_update(spw); + } +} + + +static void +sp_stroke_style_paint_selection_changed ( SPWidget *spw, + Inkscape::Selection *selection, + SPPaintSelector *psel ) +{ + sp_stroke_style_paint_update (spw); +} + +static void +sp_stroke_style_widget_change_subselection ( Inkscape::Application *inkscape, + SPDesktop *desktop, + SPWidget *spw ) +{ + sp_stroke_style_paint_update (spw); +} + +static void +sp_stroke_style_paint_update (SPWidget *spw) +{ + if (gtk_object_get_data(GTK_OBJECT(spw), "update")) { + return; + } + + gtk_object_set_data(GTK_OBJECT(spw), "update", GINT_TO_POINTER(TRUE)); + + SPPaintSelector *psel = SP_PAINT_SELECTOR(gtk_object_get_data(GTK_OBJECT(spw), "paint-selector")); + + // create temporary style + SPStyle *query = sp_style_new (); + // query into it + int result = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_STROKE); + + switch (result) { + case QUERY_STYLE_NOTHING: + { + /* No paint at all */ + sp_paint_selector_set_mode (psel, SP_PAINT_SELECTOR_MODE_EMPTY); + break; + } + + case QUERY_STYLE_SINGLE: + case QUERY_STYLE_MULTIPLE_AVERAGED: // TODO: treat this slightly differently, e.g. display "averaged" somewhere in paint selector + case QUERY_STYLE_MULTIPLE_SAME: + { + SPPaintSelectorMode pselmode = sp_style_determine_paint_selector_mode (query, false); + sp_paint_selector_set_mode (psel, pselmode); + + if (query->stroke.set && query->stroke.type == SP_PAINT_TYPE_COLOR) { + gfloat d[3]; + sp_color_get_rgb_floatv (&query->stroke.value.color, d); + SPColor color; + sp_color_set_rgb_float (&color, d[0], d[1], d[2]); + sp_paint_selector_set_color_alpha (psel, &color, SP_SCALE24_TO_FLOAT (query->stroke_opacity.value)); + + } else if (query->stroke.set && query->stroke.type == SP_PAINT_TYPE_PAINTSERVER) { + + SPPaintServer *server = SP_STYLE_STROKE_SERVER (query); + + if (SP_IS_LINEARGRADIENT (server)) { + SPGradient *vector = sp_gradient_get_vector (SP_GRADIENT (server), FALSE); + sp_paint_selector_set_gradient_linear (psel, vector); + + SPLinearGradient *lg = SP_LINEARGRADIENT (server); + sp_paint_selector_set_gradient_properties (psel, + SP_GRADIENT_UNITS (lg), + SP_GRADIENT_SPREAD (lg)); + } else if (SP_IS_RADIALGRADIENT (server)) { + SPGradient *vector = sp_gradient_get_vector (SP_GRADIENT (server), FALSE); + sp_paint_selector_set_gradient_radial (psel, vector); + + SPRadialGradient *rg = SP_RADIALGRADIENT (server); + sp_paint_selector_set_gradient_properties (psel, + SP_GRADIENT_UNITS (rg), + SP_GRADIENT_SPREAD (rg)); + } else if (SP_IS_PATTERN (server)) { + SPPattern *pat = pattern_getroot (SP_PATTERN (server)); + sp_update_pattern_list (psel, pat); + } + } + break; + } + + case QUERY_STYLE_MULTIPLE_DIFFERENT: + { + sp_paint_selector_set_mode (psel, SP_PAINT_SELECTOR_MODE_MULTIPLE); + break; + } + } + + g_free (query); + + gtk_object_set_data(GTK_OBJECT(spw), "update", GINT_TO_POINTER(FALSE)); +} + +static void +sp_stroke_style_paint_mode_changed( SPPaintSelector *psel, + SPPaintSelectorMode mode, + SPWidget *spw ) +{ + if (gtk_object_get_data(GTK_OBJECT(spw), "update")) { + return; + } + + /* TODO: Does this work? + * Not really, here we have to get old color back from object + * Instead of relying on paint widget having meaningful colors set + */ + sp_stroke_style_paint_changed(psel, spw); +} + +static gchar *undo_label_1 = "stroke:flatcolor:1"; +static gchar *undo_label_2 = "stroke:flatcolor:2"; +static gchar *undo_label = undo_label_1; + +static void +sp_stroke_style_paint_dragged(SPPaintSelector *psel, SPWidget *spw) +{ + if (gtk_object_get_data(GTK_OBJECT(spw), "update")) { + return; + } + + switch (psel->mode) { + case SP_PAINT_SELECTOR_MODE_COLOR_RGB: + case SP_PAINT_SELECTOR_MODE_COLOR_CMYK: + { + sp_paint_selector_set_flat_color (psel, SP_ACTIVE_DESKTOP, "stroke", "stroke-opacity"); + sp_document_maybe_done (SP_DT_DOCUMENT(SP_ACTIVE_DESKTOP), undo_label); + break; + } + + default: + g_warning( "file %s: line %d: Paint %d should not emit 'dragged'", + __FILE__, __LINE__, psel->mode); + break; + } +} + +static void +sp_stroke_style_paint_changed(SPPaintSelector *psel, SPWidget *spw) +{ + if (gtk_object_get_data(GTK_OBJECT(spw), "update")) { + return; + } + g_object_set_data (G_OBJECT (spw), "update", GINT_TO_POINTER (TRUE)); + + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + SPDocument *document = SP_DT_DOCUMENT (desktop); + Inkscape::Selection *selection = SP_DT_SELECTION (desktop); + + GSList const *items = selection->itemList(); + + switch (psel->mode) { + case SP_PAINT_SELECTOR_MODE_EMPTY: + // This should not happen. + g_warning ( "file %s: line %d: Paint %d should not emit 'changed'", + __FILE__, __LINE__, psel->mode); + break; + case SP_PAINT_SELECTOR_MODE_MULTIPLE: + // This happens when you switch multiple objects with different gradients to flat color; + // nothing to do here. + break; + + case SP_PAINT_SELECTOR_MODE_NONE: + { + SPCSSAttr *css = sp_repr_css_attr_new(); + sp_repr_css_set_property(css, "stroke", "none"); + + sp_desktop_set_style (desktop, css); + + sp_repr_css_attr_unref(css); + + sp_document_done(document); + break; + } + + case SP_PAINT_SELECTOR_MODE_COLOR_RGB: + case SP_PAINT_SELECTOR_MODE_COLOR_CMYK: + { + sp_paint_selector_set_flat_color (psel, desktop, "stroke", "stroke-opacity"); + sp_document_maybe_done (SP_DT_DOCUMENT(desktop), undo_label); + + // on release, toggle undo_label so that the next drag will not be lumped with this one + if (undo_label == undo_label_1) + undo_label = undo_label_2; + else + undo_label = undo_label_1; + + break; + } + + case SP_PAINT_SELECTOR_MODE_GRADIENT_LINEAR: + case SP_PAINT_SELECTOR_MODE_GRADIENT_RADIAL: + if (items) { + SPGradientType const gradient_type = ( psel->mode == SP_PAINT_SELECTOR_MODE_GRADIENT_LINEAR + ? SP_GRADIENT_TYPE_LINEAR + : SP_GRADIENT_TYPE_RADIAL ); + SPGradient *vector = sp_paint_selector_get_gradient_vector(psel); + if (!vector) { + /* No vector in paint selector should mean that we just changed mode */ + + SPStyle *query = sp_style_new (); + int result = objects_query_fillstroke ((GSList *) items, query, false); + guint32 common_rgb = 0; + if (result == QUERY_STYLE_MULTIPLE_SAME) { + if (query->fill.type != SP_PAINT_TYPE_COLOR) { + common_rgb = sp_desktop_get_color(desktop, false); + } else { + common_rgb = sp_color_get_rgba32_ualpha(&query->stroke.value.color, 0xff); + } + vector = sp_document_default_gradient_vector(document, common_rgb); + } + g_free (query); + + for (GSList const *i = items; i != NULL; i = i->next) { + if (!vector) { + sp_item_set_gradient(SP_ITEM(i->data), + sp_gradient_vector_for_object(document, desktop, SP_OBJECT(i->data), false), + gradient_type, false); + } else { + sp_item_set_gradient(SP_ITEM(i->data), vector, gradient_type, false); + } + } + } else { + vector = sp_gradient_ensure_vector_normalized(vector); + for (GSList const *i = items; i != NULL; i = i->next) { + SPGradient *gr = sp_item_set_gradient(SP_ITEM(i->data), vector, gradient_type, false); + sp_gradient_selector_attrs_to_gradient(gr, psel); + } + } + + sp_document_done(document); + } + break; + + case SP_PAINT_SELECTOR_MODE_PATTERN: + + if (items) { + + SPPattern *pattern = sp_paint_selector_get_pattern (psel); + if (!pattern) { + + /* No Pattern in paint selector should mean that we just + * changed mode - dont do jack. + */ + + } else { + Inkscape::XML::Node *patrepr = SP_OBJECT_REPR(pattern); + SPCSSAttr *css = sp_repr_css_attr_new (); + gchar *urltext = g_strdup_printf ("url(#%s)", patrepr->attribute("id")); + sp_repr_css_set_property (css, "stroke", urltext); + + for (GSList const *i = items; i != NULL; i = i->next) { + Inkscape::XML::Node *selrepr = SP_OBJECT_REPR (i->data); + SPObject *selobj = SP_OBJECT (i->data); + if (!selrepr) + continue; + + SPStyle *style = SP_OBJECT_STYLE (selobj); + if (style && style->stroke.type == SP_PAINT_TYPE_PAINTSERVER) { + SPObject *server = SP_OBJECT_STYLE_STROKE_SERVER (selobj); + if (SP_IS_PATTERN (server) && pattern_getroot (SP_PATTERN(server)) == pattern) + // only if this object's pattern is not rooted in our selected pattern, apply + continue; + } + + sp_repr_css_change_recursive (selrepr, css, "style"); + } + + sp_repr_css_attr_unref (css); + g_free (urltext); + + } // end if + + sp_document_done (document); + } // end if + + break; + + case SP_PAINT_SELECTOR_MODE_UNSET: + if (items) { + SPCSSAttr *css = sp_repr_css_attr_new (); + sp_repr_css_unset_property (css, "stroke"); + + sp_desktop_set_style (desktop, css); + sp_repr_css_attr_unref (css); + + sp_document_done (document); + } + break; + + default: + g_warning( "file %s: line %d: Paint selector should not be in " + "mode %d", + __FILE__, __LINE__, + psel->mode ); + break; + } + + g_object_set_data (G_OBJECT (spw), "update", GINT_TO_POINTER (FALSE)); +} + + + + + +/* Line */ + +static void sp_stroke_style_line_construct(SPWidget *spw, gpointer data); +static void sp_stroke_style_line_selection_modified (SPWidget *spw, + Inkscape::Selection *selection, + guint flags, + gpointer data); + +static void sp_stroke_style_line_selection_changed (SPWidget *spw, + Inkscape::Selection *selection, + gpointer data ); + +static void sp_stroke_style_line_update(SPWidget *spw, Inkscape::Selection *sel); + +static void sp_stroke_style_set_join_buttons(SPWidget *spw, + GtkWidget *active); + +static void sp_stroke_style_set_cap_buttons(SPWidget *spw, + GtkWidget *active); + +static void sp_stroke_style_width_changed(GtkAdjustment *adj, SPWidget *spw); +static void sp_stroke_style_miterlimit_changed(GtkAdjustment *adj, SPWidget *spw); +static void sp_stroke_style_any_toggled(GtkToggleButton *tb, SPWidget *spw); +static void sp_stroke_style_line_dash_changed(SPDashSelector *dsel, + SPWidget *spw); + +static void sp_stroke_style_update_marker_menus(SPWidget *spw, GSList const *objects); + +static SPObject *ink_extract_marker_name(gchar const *n); + + +/** + * Helper function for creating radio buttons. This should probably be re-thought out + * when reimplementing this with Gtkmm. + */ +static GtkWidget * +sp_stroke_radio_button(GtkWidget *tb, char const *icon, + GtkWidget *hb, GtkWidget *spw, + gchar const *key, gchar const *data) +{ + g_assert(icon != NULL); + g_assert(hb != NULL); + g_assert(spw != NULL); + + if (tb == NULL) { + tb = gtk_radio_button_new(NULL); + } else { + tb = gtk_radio_button_new(gtk_radio_button_group(GTK_RADIO_BUTTON(tb)) ); + } + + gtk_widget_show(tb); + gtk_toggle_button_set_mode(GTK_TOGGLE_BUTTON(tb), FALSE); + gtk_box_pack_start(GTK_BOX(hb), tb, FALSE, FALSE, 0); + gtk_object_set_data(GTK_OBJECT(spw), icon, tb); + gtk_object_set_data(GTK_OBJECT(tb), key, (gpointer*)data); + gtk_signal_connect(GTK_OBJECT(tb), "toggled", + GTK_SIGNAL_FUNC(sp_stroke_style_any_toggled), + spw); + GtkWidget *px = sp_icon_new(GTK_ICON_SIZE_LARGE_TOOLBAR, icon); + g_assert(px != NULL); + gtk_widget_show(px); + gtk_container_add(GTK_CONTAINER(tb), px); + + return tb; + +} + +static GtkWidget * +sp_marker_prev_new(unsigned size, gchar const *mname, + SPDocument *source, SPDocument *sandbox, + gchar *menu_id, NRArena const *arena, unsigned visionkey, NRArenaItem *root) +{ + // the object of the marker + SPObject const *marker = source->getObjectById(mname); + if (marker == NULL) + return NULL; + + // the repr of the marker; make a copy with id="sample" + Inkscape::XML::Node *mrepr = SP_OBJECT_REPR (marker)->duplicate(); + mrepr->setAttribute("id", "sample"); + + // replace the old sample in the sandbox by the new one + Inkscape::XML::Node *defsrepr = SP_OBJECT_REPR (sandbox->getObjectById("defs")); + SPObject *oldmarker = sandbox->getObjectById("sample"); + if (oldmarker) + oldmarker->deleteObject(false); + defsrepr->appendChild(mrepr); + Inkscape::GC::release(mrepr); + +// Uncomment this to get the sandbox documents saved (useful for debugging) + //FILE *fp = fopen (g_strconcat(mname, ".svg", NULL), "w"); + //sp_repr_save_stream (sp_document_repr_doc (sandbox), fp); + //fclose (fp); + + // object to render; note that the id is the same as that of the menu we're building + SPObject *object = sandbox->getObjectById(menu_id); + sp_document_root (sandbox)->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + sp_document_ensure_up_to_date(sandbox); + + if (object == NULL || !SP_IS_ITEM(object)) + return NULL; // sandbox broken? + + // Find object's bbox in document + NR::Matrix const i2doc(sp_item_i2doc_affine(SP_ITEM(object))); + + NR::Rect const dbox = SP_ITEM(object)->invokeBbox(i2doc); + + if (dbox.isEmpty()) { + return NULL; + } + + /* Update to renderable state */ + NRMatrix t; + double sf = 0.8; + nr_matrix_set_scale(&t, sf, sf); + nr_arena_item_set_transform(root, &t); + NRGC gc(NULL); + nr_matrix_set_identity(&gc.transform); + nr_arena_item_invoke_update( root, NULL, &gc, + NR_ARENA_ITEM_STATE_ALL, + NR_ARENA_ITEM_STATE_NONE ); + + /* Item integer bbox in points */ + NRRectL ibox; + ibox.x0 = (int) floor(sf * dbox.min()[NR::X] + 0.5); + ibox.y0 = (int) floor(sf * dbox.min()[NR::Y] + 0.5); + ibox.x1 = (int) floor(sf * dbox.max()[NR::X] + 0.5); + ibox.y1 = (int) floor(sf * dbox.max()[NR::Y] + 0.5); + + /* Find visible area */ + int width = ibox.x1 - ibox.x0; + int height = ibox.y1 - ibox.y0; + int dx = size; + int dy = size; + dx=(dx - width)/2; // watch out for size, since 'unsigned'-'signed' can cause problems if the result is negative + dy=(dy - height)/2; + + NRRectL area; + area.x0 = ibox.x0 - dx; + area.y0 = ibox.y0 - dy; + area.x1 = area.x0 + size; + area.y1 = area.y0 + size; + + /* Actual renderable area */ + NRRectL ua; + ua.x0 = MAX(ibox.x0, area.x0); + ua.y0 = MAX(ibox.y0, area.y0); + ua.x1 = MIN(ibox.x1, area.x1); + ua.y1 = MIN(ibox.y1, area.y1); + + /* Set up pixblock */ + guchar *px = nr_new(guchar, 4 * size * size); + memset(px, 0x00, 4 * size * size); + + /* Render */ + NRPixBlock B; + nr_pixblock_setup_extern( &B, NR_PIXBLOCK_MODE_R8G8B8A8N, + ua.x0, ua.y0, ua.x1, ua.y1, + px + 4 * size * (ua.y0 - area.y0) + + 4 * (ua.x0 - area.x0), + 4 * size, FALSE, FALSE ); + nr_arena_item_invoke_render( root, &ua, &B, + NR_ARENA_ITEM_RENDER_NO_CACHE ); + nr_pixblock_release(&B); + + // Create widget + GtkWidget *pb = gtk_image_new_from_pixbuf(gdk_pixbuf_new_from_data(px, + GDK_COLORSPACE_RGB, + TRUE, + 8, size, size, size * 4, + (GdkPixbufDestroyNotify)nr_free, + NULL)); + return pb; +} + + +#define MARKER_ITEM_MARGIN 0 + + +/** + * sp_marker_list_from_doc() + * + * \brief Pick up all markers from source, except those that are in + * current_doc (if non-NULL), and add items to the m menu + * + */ +static void +sp_marker_list_from_doc (GtkWidget *m, SPDocument *current_doc, SPDocument *source, SPDocument *markers_doc, SPDocument *sandbox, gchar *menu_id) +{ + + // search through defs + GSList *ml = NULL; + SPDefs *defs= (SPDefs *) SP_DOCUMENT_DEFS (source); + for ( SPObject *ochild = sp_object_first_child(SP_OBJECT(defs)) ; ochild != NULL ; ochild = SP_OBJECT_NEXT (ochild) ) { + if (SP_IS_MARKER(ochild)) { + ml = g_slist_prepend (ml, ochild); + } + } + + // Do this here, outside of loop, to speed up preview generation: + /* Create new arena */ + NRArena const *arena = NRArena::create(); + /* Create ArenaItem and set transform */ + unsigned const visionkey = sp_item_display_key_new(1); + NRArenaItem *root = sp_item_invoke_show( SP_ITEM(SP_DOCUMENT_ROOT (sandbox)), (NRArena *) arena, visionkey, SP_ITEM_SHOW_DISPLAY ); + + for (; ml != NULL; ml = ml->next) { + + if (!SP_IS_MARKER(ml->data)) + continue; + + Inkscape::XML::Node *repr = SP_OBJECT_REPR((SPItem *) ml->data); + + bool stock_dupe = false; + + if (markers_doc && repr->attribute("inkscape:stockid")) { + // find out if markers_doc has a marker with the same stockid, and if so, skip this + for (SPObject *child = sp_object_first_child(SP_OBJECT(SP_DOCUMENT_DEFS(markers_doc))) ; + child != NULL; + child = SP_OBJECT_NEXT(child) ) + { + if (SP_IS_MARKER(child) && + SP_OBJECT_REPR(child)->attribute("inkscape:stockid") && + !strcmp(repr->attribute("inkscape:stockid"), SP_OBJECT_REPR(child)->attribute("inkscape:stockid"))) { + stock_dupe = true; + } + } + } + + if (stock_dupe) // stock item, dont add to list from current doc + continue; + + GtkWidget *i = gtk_menu_item_new(); + gtk_widget_show(i); + + if (repr->attribute("inkscape:stockid")) + g_object_set_data (G_OBJECT(i), "stockid", (void *) "true"); + else + g_object_set_data (G_OBJECT(i), "stockid", (void *) "false"); + + gchar const *markid = repr->attribute("id"); + g_object_set_data (G_OBJECT(i), "marker", (void *) markid); + + GtkWidget *hb = gtk_hbox_new(FALSE, MARKER_ITEM_MARGIN); + gtk_widget_show(hb); + + // generate preview + GtkWidget *prv = sp_marker_prev_new (22, markid, source, sandbox, menu_id, arena, visionkey, root); + gtk_widget_show(prv); + gtk_box_pack_start(GTK_BOX(hb), prv, FALSE, FALSE, 6); + + // create label + GtkWidget *l = gtk_label_new(repr->attribute("id")); + gtk_widget_show(l); + gtk_misc_set_alignment(GTK_MISC(l), 0.0, 0.5); + + gtk_box_pack_start(GTK_BOX(hb), l, TRUE, TRUE, 0); + + gtk_widget_show(hb); + gtk_container_add(GTK_CONTAINER(i), hb); + + gtk_menu_append(GTK_MENU(m), i); + } + + g_slist_free (ml); +} + + +SPDocument * +ink_markers_preview_doc () +{ +gchar const *buffer = "" +" " + +" " +" " +" " +" " + +" " +" " +" " +" " + +" " +" " +" " +" " + +""; + + return sp_document_new_from_mem (buffer, strlen(buffer), FALSE); +} + + + +static GtkWidget * +ink_marker_menu( GtkWidget *tbl, gchar *menu_id, SPDocument *sandbox) +{ + SPDesktop *desktop = inkscape_active_desktop(); + SPDocument *doc = SP_DT_DOCUMENT(desktop); + GtkWidget *mnu = gtk_option_menu_new(); + + /* Create new menu widget */ + GtkWidget *m = gtk_menu_new(); + gtk_widget_show(m); + + g_object_set_data(G_OBJECT(mnu), "updating", (gpointer) FALSE); + + if (!doc) { + GtkWidget *i = gtk_menu_item_new_with_label(_("No document selected")); + gtk_widget_show(i); + gtk_menu_append(GTK_MENU(m), i); + gtk_widget_set_sensitive(mnu, FALSE); + + } else { + + // add "None" + { + GtkWidget *i = gtk_menu_item_new(); + gtk_widget_show(i); + + g_object_set_data(G_OBJECT(i), "marker", (void *) "none"); + + GtkWidget *hb = gtk_hbox_new(FALSE, MARKER_ITEM_MARGIN); + gtk_widget_show(hb); + + GtkWidget *l = gtk_label_new( _("None") ); + gtk_widget_show(l); + gtk_misc_set_alignment(GTK_MISC(l), 0.0, 0.5); + + gtk_box_pack_start(GTK_BOX(hb), l, TRUE, TRUE, 0); + + gtk_widget_show(hb); + gtk_container_add(GTK_CONTAINER(i), hb); + gtk_menu_append(GTK_MENU(m), i); + } + + // find and load markers.svg + static SPDocument *markers_doc = NULL; + char *markers_source = g_build_filename(INKSCAPE_MARKERSDIR, "markers.svg", NULL); + if (Inkscape::IO::file_test(markers_source, G_FILE_TEST_IS_REGULAR)) { + markers_doc = sp_document_new(markers_source, FALSE); + } + g_free(markers_source); + + // suck in from current doc + sp_marker_list_from_doc ( m, NULL, doc, markers_doc, sandbox, menu_id ); + + // add separator + { + GtkWidget *i = gtk_separator_menu_item_new(); + gtk_widget_show(i); + gtk_menu_append(GTK_MENU(m), i); + } + + // suck in from markers.svg + if (markers_doc) { + sp_document_ensure_up_to_date(doc); + sp_marker_list_from_doc ( m, doc, markers_doc, NULL, sandbox, menu_id ); + } + + gtk_widget_set_sensitive(mnu, TRUE); + } + + gtk_object_set_data(GTK_OBJECT(mnu), "menu_id", menu_id); + gtk_option_menu_set_menu(GTK_OPTION_MENU(mnu), m); + + /* Set history */ + gtk_option_menu_set_history(GTK_OPTION_MENU(mnu), 0); + + return mnu; +} + + +/*user selected existing marker from list*/ +static void +sp_marker_select(GtkOptionMenu *mnu, GtkWidget *spw) +{ + if (gtk_object_get_data(GTK_OBJECT(spw), "update")) { + return; + } + + SPDesktop *desktop = inkscape_active_desktop(); + SPDocument *document = SP_DT_DOCUMENT(desktop); + if (!document) { + return; + } + + /* Get Marker */ + if (!g_object_get_data(G_OBJECT(gtk_menu_get_active(GTK_MENU(gtk_option_menu_get_menu(mnu)))), + "marker")) + { + return; + } + gchar *markid = (gchar *) g_object_get_data(G_OBJECT(gtk_menu_get_active(GTK_MENU(gtk_option_menu_get_menu(mnu)))), + "marker"); + gchar *marker = ""; + if (strcmp(markid, "none")){ + gchar *stockid = (gchar *) g_object_get_data(G_OBJECT(gtk_menu_get_active(GTK_MENU(gtk_option_menu_get_menu(mnu)))), + "stockid"); + + gchar *markurn = markid; + if (!strcmp(stockid,"true")) markurn = g_strconcat("urn:inkscape:marker:",markid,NULL); + SPObject *mark = get_stock_item(markurn); + if (mark) { + Inkscape::XML::Node *repr = SP_OBJECT_REPR(mark); + marker = g_strconcat("url(#", repr->attribute("id"), ")", NULL); + } + } else { + marker = markid; + } + + SPCSSAttr *css = sp_repr_css_attr_new(); + gchar *menu_id = (gchar *) g_object_get_data(G_OBJECT(mnu), "menu_id"); + sp_repr_css_set_property(css, menu_id, marker); + + Inkscape::Selection *selection = SP_DT_SELECTION(desktop); + GSList const *items = selection->itemList(); + for (; items != NULL; items = items->next) { + SPItem *item = (SPItem *) items->data; + if (!SP_IS_SHAPE(item) || SP_IS_RECT(item)) // can't set marker to rect, until it's converted to using + continue; + Inkscape::XML::Node *selrepr = SP_OBJECT_REPR((SPItem *) items->data); + if (selrepr) { + sp_repr_css_change_recursive(selrepr, css, "style"); + } + SP_OBJECT(items->data)->requestModified(SP_OBJECT_MODIFIED_FLAG); + SP_OBJECT(items->data)->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG); + } + + sp_repr_css_attr_unref(css); + + sp_document_done(document); +} + +static gboolean stroke_width_set_unit(SPUnitSelector *, + SPUnit const *old, + SPUnit const *new_units, + GObject *spw) +{ + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + + if (!desktop) { + return FALSE; + } + + Inkscape::Selection *selection = SP_DT_SELECTION (desktop); + + if (selection->isEmpty()) + return FALSE; + + GSList const *objects = selection->itemList(); + + if ((old->base == SP_UNIT_ABSOLUTE || old->base == SP_UNIT_DEVICE) && + (new_units->base == SP_UNIT_DIMENSIONLESS)) { + + /* Absolute to percentage */ + g_object_set_data (spw, "update", GUINT_TO_POINTER (TRUE)); + + GtkAdjustment *a = GTK_ADJUSTMENT(g_object_get_data (spw, "width")); + float w = sp_units_get_pixels (a->value, *old); + + gdouble average = stroke_average_width (objects); + + if (average == NR_HUGE || average == 0) + return FALSE; + + gtk_adjustment_set_value (a, 100.0 * w / average); + + g_object_set_data (spw, "update", GUINT_TO_POINTER (FALSE)); + return TRUE; + + } else if ((old->base == SP_UNIT_DIMENSIONLESS) && + (new_units->base == SP_UNIT_ABSOLUTE || new_units->base == SP_UNIT_DEVICE)) { + + /* Percentage to absolute */ + g_object_set_data (spw, "update", GUINT_TO_POINTER (TRUE)); + + GtkAdjustment *a = GTK_ADJUSTMENT(g_object_get_data (spw, "width")); + + gdouble average = stroke_average_width (objects); + + gtk_adjustment_set_value (a, sp_pixels_get_units (0.01 * a->value * average, *new_units)); + + g_object_set_data (spw, "update", GUINT_TO_POINTER (FALSE)); + return TRUE; + } + + return FALSE; +} + + +/** + * \brief Creates a new widget for the line stroke style. + * + */ +GtkWidget * +sp_stroke_style_line_widget_new(void) +{ + GtkWidget *spw, *f, *t, *hb, *sb, *us, *tb, *ds; + GtkObject *a; + + GtkTooltips *tt = gtk_tooltips_new(); + + spw = sp_widget_new_global(INKSCAPE); + + f = gtk_hbox_new (FALSE, 0); + gtk_widget_show(f); + gtk_container_add(GTK_CONTAINER(spw), f); + + t = gtk_table_new(3, 6, FALSE); + gtk_widget_show(t); + gtk_container_set_border_width(GTK_CONTAINER(t), 4); + gtk_table_set_row_spacings(GTK_TABLE(t), 4); + gtk_container_add(GTK_CONTAINER(f), t); + gtk_object_set_data(GTK_OBJECT(spw), "stroke", t); + + gint i = 0; + + /* Stroke width */ + spw_label(t, _("Width:"), 0, i); + + hb = spw_hbox(t, 3, 1, i); + +// TODO: when this is gtkmmified, use an Inkscape::UI::Widget::ScalarUnit instead of the separate +// spinbutton and unit selector for stroke width. In sp_stroke_style_line_update, use +// setHundredPercent to remember the aeraged width corresponding to 100%. Then the +// stroke_width_set_unit will be removed (because ScalarUnit takes care of conversions itself), and +// with it, the two remaining calls of stroke_average_width, allowing us to get rid of that +// function in desktop-style. + + a = gtk_adjustment_new(1.0, 0.0, 1000.0, 0.1, 10.0, 10.0); + gtk_object_set_data(GTK_OBJECT(spw), "width", a); + sb = gtk_spin_button_new(GTK_ADJUSTMENT(a), 0.1, 3); + gtk_tooltips_set_tip(tt, sb, _("Stroke width"), NULL); + gtk_widget_show(sb); + + sp_dialog_defocus_on_enter(sb); + + gtk_box_pack_start(GTK_BOX(hb), sb, FALSE, FALSE, 0); + us = sp_unit_selector_new(SP_UNIT_ABSOLUTE | SP_UNIT_DEVICE); + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + if (desktop) + sp_unit_selector_set_unit (SP_UNIT_SELECTOR(us), SP_DT_NAMEDVIEW(desktop)->doc_units); + sp_unit_selector_add_unit(SP_UNIT_SELECTOR(us), &sp_unit_get_by_id(SP_UNIT_PERCENT), 0); + g_signal_connect ( G_OBJECT (us), "set_unit", G_CALLBACK (stroke_width_set_unit), spw ); + gtk_widget_show(us); + sp_unit_selector_add_adjustment( SP_UNIT_SELECTOR(us), GTK_ADJUSTMENT(a) ); + gtk_box_pack_start(GTK_BOX(hb), us, FALSE, FALSE, 0); + gtk_object_set_data(GTK_OBJECT(spw), "units", us); + + gtk_signal_connect( GTK_OBJECT(a), "value_changed", GTK_SIGNAL_FUNC(sp_stroke_style_width_changed), spw ); + i++; + + /* Join type */ + // TRANSLATORS: The line join style specifies the shape to be used at the + // corners of paths. It can be "miter", "round" or "bevel". + spw_label(t, _("Join:"), 0, i); + + hb = spw_hbox(t, 3, 1, i); + + tb = NULL; + + tb = sp_stroke_radio_button(tb, INKSCAPE_STOCK_JOIN_MITER, + hb, spw, "join", "miter"); + + // TRANSLATORS: Miter join: joining lines with a sharp (pointed) corner. + // For an example, draw a triangle with a large stroke width and modify the + // "Join" option (in the Fill and Stroke dialog). + gtk_tooltips_set_tip(tt, tb, _("Miter join"), NULL); + + tb = sp_stroke_radio_button(tb, INKSCAPE_STOCK_JOIN_ROUND, + hb, spw, "join", "round"); + + // TRANSLATORS: Round join: joining lines with a rounded corner. + // For an example, draw a triangle with a large stroke width and modify the + // "Join" option (in the Fill and Stroke dialog). + gtk_tooltips_set_tip(tt, tb, _("Round join"), NULL); + + tb = sp_stroke_radio_button(tb, INKSCAPE_STOCK_JOIN_BEVEL, + hb, spw, "join", "bevel"); + + // TRANSLATORS: Bevel join: joining lines with a blunted (flattened) corner. + // For an example, draw a triangle with a large stroke width and modify the + // "Join" option (in the Fill and Stroke dialog). + gtk_tooltips_set_tip(tt, tb, _("Bevel join"), NULL); + + i++; + + /* Miterlimit */ + // TRANSLATORS: Miter limit: only for "miter join", this limits the length + // of the sharp "spike" when the lines connect at too sharp an angle. + // When two line segments meet at a sharp angle, a miter join results in a + // spike that extends well beyond the connection point. The purpose of the + // miter limit is to cut off such spikes (i.e. convert them into bevels) + // when they become too long. + spw_label(t, _("Miter limit:"), 0, i); + + hb = spw_hbox(t, 3, 1, i); + + a = gtk_adjustment_new(4.0, 0.0, 100.0, 0.1, 10.0, 10.0); + gtk_object_set_data(GTK_OBJECT(spw), "miterlimit", a); + + sb = gtk_spin_button_new(GTK_ADJUSTMENT(a), 0.1, 2); + gtk_tooltips_set_tip(tt, sb, _("Maximum length of the miter (in units of stroke width)"), NULL); + gtk_widget_show(sb); + gtk_object_set_data(GTK_OBJECT(spw), "miterlimit_sb", sb); + sp_dialog_defocus_on_enter(sb); + + gtk_box_pack_start(GTK_BOX(hb), sb, FALSE, FALSE, 0); + + gtk_signal_connect( GTK_OBJECT(a), "value_changed", + GTK_SIGNAL_FUNC(sp_stroke_style_miterlimit_changed), spw ); + i++; + + /* Cap type */ + // TRANSLATORS: cap type specifies the shape for the ends of lines + spw_label(t, _("Cap:"), 0, i); + + hb = spw_hbox(t, 3, 1, i); + + tb = NULL; + + tb = sp_stroke_radio_button(tb, INKSCAPE_STOCK_CAP_BUTT, + hb, spw, "cap", "butt"); + + // TRANSLATORS: Butt cap: the line shape does not extend beyond the end point + // of the line; the ends of the line are square + gtk_tooltips_set_tip(tt, tb, _("Butt cap"), NULL); + + tb = sp_stroke_radio_button(tb, INKSCAPE_STOCK_CAP_ROUND, + hb, spw, "cap", "round"); + + // TRANSLATORS: Round cap: the line shape extends beyond the end point of the + // line; the ends of the line are rounded + gtk_tooltips_set_tip(tt, tb, _("Round cap"), NULL); + + tb = sp_stroke_radio_button(tb, INKSCAPE_STOCK_CAP_SQUARE, + hb, spw, "cap", "square"); + + // TRANSLATORS: Square cap: the line shape extends beyond the end point of the + // line; the ends of the line are square + gtk_tooltips_set_tip(tt, tb, _("Square cap"), NULL); + + i++; + + + /* Dash */ + spw_label(t, _("Dashes:"), 0, i); + ds = sp_dash_selector_new( inkscape_get_repr( INKSCAPE, + "palette.dashes") ); + + gtk_widget_show(ds); + gtk_table_attach( GTK_TABLE(t), ds, 1, 4, i, i+1, + (GtkAttachOptions)( GTK_EXPAND | GTK_FILL ), + (GtkAttachOptions)0, 0, 0 ); + gtk_object_set_data(GTK_OBJECT(spw), "dash", ds); + gtk_signal_connect( GTK_OBJECT(ds), "changed", + GTK_SIGNAL_FUNC(sp_stroke_style_line_dash_changed), + spw ); + i++; + + /* Drop down marker selectors*/ + + // doing this here once, instead of for each preview, to speed things up + SPDocument *sandbox = ink_markers_preview_doc (); + + // TRANSLATORS: Path markers are an SVG feature that allows you to attach arbitrary shapes + // (arrowheads, bullets, faces, whatever) to the start, end, or middle nodes of a path. + spw_label(t, _("Start Markers:"), 0, i); + GtkWidget *mnu = ink_marker_menu( spw ,"marker-start", sandbox); + gtk_signal_connect( GTK_OBJECT(mnu), "changed", GTK_SIGNAL_FUNC(sp_marker_select), spw ); + gtk_widget_show(mnu); + gtk_table_attach( GTK_TABLE(t), mnu, 1, 4, i, i+1, + (GtkAttachOptions)( GTK_EXPAND | GTK_FILL ), + (GtkAttachOptions)0, 0, 0 ); + gtk_object_set_data(GTK_OBJECT(spw), "start_mark_menu", mnu); + + i++; + spw_label(t, _("Mid Markers:"), 0, i); + mnu = NULL; + mnu = ink_marker_menu( spw ,"marker-mid", sandbox); + gtk_signal_connect( GTK_OBJECT(mnu), "changed", GTK_SIGNAL_FUNC(sp_marker_select), spw ); + gtk_widget_show(mnu); + gtk_table_attach( GTK_TABLE(t), mnu, 1, 4, i, i+1, + (GtkAttachOptions)( GTK_EXPAND | GTK_FILL ), + (GtkAttachOptions)0, 0, 0 ); + gtk_object_set_data(GTK_OBJECT(spw), "mid_mark_menu", mnu); + + i++; + spw_label(t, _("End Markers:"), 0, i); + mnu = NULL; + mnu = ink_marker_menu( spw ,"marker-end", sandbox); + gtk_signal_connect( GTK_OBJECT(mnu), "changed", GTK_SIGNAL_FUNC(sp_marker_select), spw ); + gtk_widget_show(mnu); + gtk_table_attach( GTK_TABLE(t), mnu, 1, 4, i, i+1, + (GtkAttachOptions)( GTK_EXPAND | GTK_FILL ), + (GtkAttachOptions)0, 0, 0 ); + gtk_object_set_data(GTK_OBJECT(spw), "end_mark_menu", mnu); + + i++; + + gtk_signal_connect( GTK_OBJECT(spw), "construct", + GTK_SIGNAL_FUNC(sp_stroke_style_line_construct), + NULL ); + gtk_signal_connect( GTK_OBJECT(spw), "modify_selection", + GTK_SIGNAL_FUNC(sp_stroke_style_line_selection_modified), + NULL ); + gtk_signal_connect( GTK_OBJECT(spw), "change_selection", + GTK_SIGNAL_FUNC(sp_stroke_style_line_selection_changed), + NULL ); + + sp_stroke_style_line_update( SP_WIDGET(spw), desktop ? SP_DT_SELECTION(desktop) : NULL); + + return spw; +} + + + +static void +sp_stroke_style_line_construct(SPWidget *spw, gpointer data) +{ + +#ifdef SP_SS_VERBOSE + g_print( "Stroke style widget constructed: inkscape %p repr %p\n", + spw->inkscape, spw->repr ); +#endif + if (spw->inkscape) { + sp_stroke_style_line_update(spw, + ( SP_ACTIVE_DESKTOP + ? SP_DT_SELECTION(SP_ACTIVE_DESKTOP) + : NULL )); + } +} + +static void +sp_stroke_style_line_selection_modified ( SPWidget *spw, + Inkscape::Selection *selection, + guint flags, + gpointer data ) +{ + if (flags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_PARENT_MODIFIED_FLAG)) { + sp_stroke_style_line_update (spw, selection); + } + +} + +static void +sp_stroke_style_line_selection_changed ( SPWidget *spw, + Inkscape::Selection *selection, + gpointer data ) +{ + sp_stroke_style_line_update (spw, selection); +} + + +static void +sp_dash_selector_set_from_style (GtkWidget *dsel, SPStyle *style) +{ + if (style->stroke_dash.n_dash > 0) { + double d[64]; + int len = MIN(style->stroke_dash.n_dash, 64); + for (int i = 0; i < len; i++) { + if (style->stroke_width.computed != 0) + d[i] = style->stroke_dash.dash[i] / style->stroke_width.computed; + else + d[i] = style->stroke_dash.dash[i]; // is there a better thing to do for stroke_width==0? + } + sp_dash_selector_set_dash(SP_DASH_SELECTOR(dsel), len, d, + style->stroke_width.computed != 0? + style->stroke_dash.offset / style->stroke_width.computed : + style->stroke_dash.offset); + } else { + sp_dash_selector_set_dash(SP_DASH_SELECTOR(dsel), 0, NULL, 0.0); + } +} + +static void +sp_jointype_set (SPWidget *spw, unsigned const jointype) +{ + GtkWidget *tb = NULL; + switch (jointype) { + case SP_STROKE_LINEJOIN_MITER: + tb = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(spw), INKSCAPE_STOCK_JOIN_MITER)); + break; + case SP_STROKE_LINEJOIN_ROUND: + tb = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(spw), INKSCAPE_STOCK_JOIN_ROUND)); + break; + case SP_STROKE_LINEJOIN_BEVEL: + tb = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(spw), INKSCAPE_STOCK_JOIN_BEVEL)); + break; + default: + break; + } + sp_stroke_style_set_join_buttons (spw, tb); +} + +static void +sp_captype_set (SPWidget *spw, unsigned const captype) +{ + GtkWidget *tb = NULL; + switch (captype) { + case SP_STROKE_LINECAP_BUTT: + tb = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(spw), INKSCAPE_STOCK_CAP_BUTT)); + break; + case SP_STROKE_LINECAP_ROUND: + tb = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(spw), INKSCAPE_STOCK_CAP_ROUND)); + break; + case SP_STROKE_LINECAP_SQUARE: + tb = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(spw), INKSCAPE_STOCK_CAP_SQUARE)); + break; + default: + break; + } + sp_stroke_style_set_cap_buttons (spw, tb); +} + +static void +sp_stroke_style_line_update(SPWidget *spw, Inkscape::Selection *sel) +{ + if (gtk_object_get_data(GTK_OBJECT(spw), "update")) { + return; + } + + gtk_object_set_data(GTK_OBJECT(spw), "update", GINT_TO_POINTER(TRUE)); + + GtkWidget *sset = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(spw), "stroke")); + GtkObject *width = GTK_OBJECT(gtk_object_get_data(GTK_OBJECT(spw), "width")); + GtkObject *ml = GTK_OBJECT(gtk_object_get_data(GTK_OBJECT(spw), "miterlimit")); + GtkWidget *us = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(spw), "units")); + GtkWidget *dsel = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(spw), "dash")); + + // create temporary style + SPStyle *query = sp_style_new (); + // query into it + int result_sw = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_STROKEWIDTH); + int result_ml = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_STROKEMITERLIMIT); + int result_cap = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_STROKECAP); + int result_join = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_STROKEJOIN); + + if (result_sw == QUERY_STYLE_NOTHING) { + /* No objects stroked, set insensitive */ + gtk_widget_set_sensitive(sset, FALSE); + + gtk_object_set_data(GTK_OBJECT(spw), "update", GINT_TO_POINTER(FALSE)); + return; + } else { + gtk_widget_set_sensitive(sset, TRUE); + + SPUnit const *unit = sp_unit_selector_get_unit(SP_UNIT_SELECTOR(us)); + + if (result_sw == QUERY_STYLE_MULTIPLE_AVERAGED) { + sp_unit_selector_set_unit(SP_UNIT_SELECTOR(us), &sp_unit_get_by_id(SP_UNIT_PERCENT)); + } else { + // same width, or only one object; no sense to keep percent, switch to absolute + if (unit->base != SP_UNIT_ABSOLUTE && unit->base != SP_UNIT_DEVICE) { + sp_unit_selector_set_unit(SP_UNIT_SELECTOR(us), SP_DT_NAMEDVIEW(SP_ACTIVE_DESKTOP)->doc_units); + } + } + + unit = sp_unit_selector_get_unit (SP_UNIT_SELECTOR (us)); + + if (unit->base == SP_UNIT_ABSOLUTE || unit->base == SP_UNIT_DEVICE) { + double avgwidth = sp_pixels_get_units (query->stroke_width.computed, *unit); + gtk_adjustment_set_value(GTK_ADJUSTMENT(width), avgwidth); + } else { + gtk_adjustment_set_value(GTK_ADJUSTMENT(width), 100); + } + } + + if (result_ml != QUERY_STYLE_NOTHING) + gtk_adjustment_set_value(GTK_ADJUSTMENT(ml), query->stroke_miterlimit.value); // TODO: reflect averagedness? + + if (result_join != QUERY_STYLE_MULTIPLE_DIFFERENT) { + sp_jointype_set (spw, query->stroke_linejoin.value); + } else { + sp_stroke_style_set_join_buttons(spw, NULL); + } + + if (result_cap != QUERY_STYLE_MULTIPLE_DIFFERENT) { + sp_captype_set (spw, query->stroke_linecap.value); + } else { + sp_stroke_style_set_cap_buttons(spw, NULL); + } + + g_free (query); + + GSList const *objects = sel->itemList(); + SPObject * const object = SP_OBJECT(objects->data); + SPStyle * const style = SP_OBJECT_STYLE(object); + + /* Markers */ + sp_stroke_style_update_marker_menus(spw, objects); // FIXME: make this desktop query too + + /* Dash */ + sp_dash_selector_set_from_style (dsel, style); // FIXME: make this desktop query too + + gtk_widget_set_sensitive(sset, TRUE); + + gtk_object_set_data(GTK_OBJECT(spw), "update", + GINT_TO_POINTER(FALSE)); +} + +static void +sp_stroke_style_set_scaled_dash(SPCSSAttr *css, + int ndash, double *dash, double offset, + double scale) +{ + if (ndash > 0) { + Inkscape::CSSOStringStream osarray; + for (int i = 0; i < ndash; i++) { + osarray << dash[i] * scale; + if (i < (ndash - 1)) { + osarray << ","; + } + } + sp_repr_css_set_property(css, "stroke-dasharray", osarray.str().c_str()); + + Inkscape::CSSOStringStream osoffset; + osoffset << offset * scale; + sp_repr_css_set_property(css, "stroke-dashoffset", osoffset.str().c_str()); + } else { + sp_repr_css_set_property(css, "stroke-dasharray", "none"); + sp_repr_css_set_property(css, "stroke-dashoffset", NULL); + } +} + +static void +sp_stroke_style_scale_line(SPWidget *spw) +{ + if (gtk_object_get_data(GTK_OBJECT(spw), "update")) { + return; + } + + gtk_object_set_data(GTK_OBJECT(spw), "update", GINT_TO_POINTER(TRUE)); + + GtkAdjustment *wadj = GTK_ADJUSTMENT(gtk_object_get_data(GTK_OBJECT(spw), "width")); + SPUnitSelector *us = SP_UNIT_SELECTOR(gtk_object_get_data(GTK_OBJECT(spw), "units")); + SPDashSelector *dsel = SP_DASH_SELECTOR(gtk_object_get_data(GTK_OBJECT(spw), "dash")); + GtkAdjustment *ml = GTK_ADJUSTMENT(gtk_object_get_data(GTK_OBJECT(spw), "miterlimit")); + + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + SPDocument *document = SP_DT_DOCUMENT (desktop); + Inkscape::Selection *selection = SP_DT_SELECTION (desktop); + + GSList const *items = selection->itemList(); + + /* TODO: Create some standardized method */ + SPCSSAttr *css = sp_repr_css_attr_new(); + + if (items) { + + double width_typed = wadj->value; + double const miterlimit = ml->value; + + SPUnit const *const unit = sp_unit_selector_get_unit(SP_UNIT_SELECTOR(us)); + + double *dash, offset; + int ndash; + sp_dash_selector_get_dash(dsel, &ndash, &dash, &offset); + + for (GSList const *i = items; i != NULL; i = i->next) { + /* Set stroke width */ + double width; + if (unit->base == SP_UNIT_ABSOLUTE || unit->base == SP_UNIT_DEVICE) { + width = sp_units_get_pixels (width_typed, *unit); + } else { // percentage + gdouble old_w = SP_OBJECT_STYLE (i->data)->stroke_width.computed; + width = old_w * width_typed / 100; + } + + { + Inkscape::CSSOStringStream os_width; + os_width << width; + sp_repr_css_set_property(css, "stroke-width", os_width.str().c_str()); + } + + { + Inkscape::CSSOStringStream os_ml; + os_ml << miterlimit; + sp_repr_css_set_property(css, "stroke-miterlimit", os_ml.str().c_str()); + } + + /* Set dash */ + sp_stroke_style_set_scaled_dash(css, ndash, dash, offset, width); + + sp_desktop_apply_css_recursive (SP_OBJECT(i->data), css, true); + } + + g_free(dash); + + if (unit->base != SP_UNIT_ABSOLUTE && unit->base != SP_UNIT_DEVICE) { + // reset to 100 percent + gtk_adjustment_set_value (wadj, 100.0); + } + + } + + // we have already changed the items, so set style without changing selection + // FIXME: move the above stroke-setting stuff, including percentages, to desktop-style + sp_desktop_set_style (desktop, css, false); + + sp_repr_css_attr_unref(css); + + sp_document_done(document); + + gtk_object_set_data(GTK_OBJECT(spw), "update", GINT_TO_POINTER(FALSE)); +} + + + +static void +sp_stroke_style_width_changed(GtkAdjustment *adj, SPWidget *spw) +{ + if (gtk_object_get_data(GTK_OBJECT(spw), "update")) { + return; + } + + sp_stroke_style_scale_line(spw); +} + +static void +sp_stroke_style_miterlimit_changed(GtkAdjustment *adj, SPWidget *spw) +{ + if (gtk_object_get_data(GTK_OBJECT(spw), "update")) { + return; + } + + sp_stroke_style_scale_line(spw); +} + +static void +sp_stroke_style_line_dash_changed(SPDashSelector *dsel, SPWidget *spw) +{ + if (gtk_object_get_data(GTK_OBJECT(spw), "update")) { + return; + } + + sp_stroke_style_scale_line(spw); +} + + + +/** + * \brief This routine handles toggle events for buttons in the stroke style + * dialog. + * When activated, this routine gets the data for the various widgets, and then + * calls the respective routines to update css properties, etc. + * + */ +static void +sp_stroke_style_any_toggled(GtkToggleButton *tb, SPWidget *spw) +{ + if (gtk_object_get_data(GTK_OBJECT(spw), "update")) { + return; + } + + if (gtk_toggle_button_get_active(tb)) { + + gchar const *join + = static_cast(gtk_object_get_data(GTK_OBJECT(tb), "join")); + gchar const *cap + = static_cast(gtk_object_get_data(GTK_OBJECT(tb), "cap")); + + if (join) { + GtkWidget *ml = GTK_WIDGET(g_object_get_data(G_OBJECT(spw), "miterlimit_sb")); + gtk_widget_set_sensitive (ml, !strcmp(join, "miter")); + } + + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + + /* TODO: Create some standardized method */ + SPCSSAttr *css = sp_repr_css_attr_new(); + + if (join) { + sp_repr_css_set_property(css, "stroke-linejoin", join); + + sp_desktop_set_style (desktop, css); + + sp_stroke_style_set_join_buttons(spw, GTK_WIDGET(tb)); + } else if (cap) { + sp_repr_css_set_property(css, "stroke-linecap", cap); + + sp_desktop_set_style (desktop, css); + + sp_stroke_style_set_cap_buttons(spw, GTK_WIDGET(tb)); + } + + sp_repr_css_attr_unref(css); + + sp_document_done(SP_DT_DOCUMENT(desktop)); + } +} + + +static void +sp_stroke_style_set_join_buttons(SPWidget *spw, GtkWidget *active) +{ + GtkWidget *tb; + + tb = GTK_WIDGET(gtk_object_get_data( GTK_OBJECT(spw), + INKSCAPE_STOCK_JOIN_MITER) ); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(tb), (active == tb)); + + GtkWidget *ml = GTK_WIDGET(g_object_get_data(G_OBJECT(spw), "miterlimit_sb")); + gtk_widget_set_sensitive(ml, (active == tb)); + + tb = GTK_WIDGET(gtk_object_get_data( GTK_OBJECT(spw), + INKSCAPE_STOCK_JOIN_ROUND) ); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(tb), (active == tb)); + tb = GTK_WIDGET(gtk_object_get_data( GTK_OBJECT(spw), + INKSCAPE_STOCK_JOIN_BEVEL) ); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(tb), (active == tb)); +} + + + +static void +sp_stroke_style_set_cap_buttons(SPWidget *spw, GtkWidget *active) +{ + GtkWidget *tb; + + tb = GTK_WIDGET(gtk_object_get_data( GTK_OBJECT(spw), + INKSCAPE_STOCK_CAP_BUTT)); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(tb), (active == tb)); + tb = GTK_WIDGET(gtk_object_get_data( GTK_OBJECT(spw), + INKSCAPE_STOCK_CAP_ROUND) ); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(tb), (active == tb)); + tb = GTK_WIDGET(gtk_object_get_data( GTK_OBJECT(spw), + INKSCAPE_STOCK_CAP_SQUARE) ); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(tb), (active == tb)); +} + +static void +ink_marker_menu_set_current(SPObject *marker, GtkOptionMenu *mnu) +{ + gtk_object_set_data(GTK_OBJECT(mnu), "update", GINT_TO_POINTER(TRUE)); + + GtkMenu *m = GTK_MENU(gtk_option_menu_get_menu(mnu)); + if (marker != NULL) { + bool mark_is_stock = false; + if (SP_OBJECT_REPR(marker)->attribute("inkscape:stockid")) + mark_is_stock = true; + + gchar *markname; + if (mark_is_stock) + markname = g_strdup(SP_OBJECT_REPR(marker)->attribute("inkscape:stockid")); + else + markname = g_strdup(SP_OBJECT_REPR(marker)->attribute("id")); + + int markpos = 0; + GList *kids = GTK_MENU_SHELL(m)->children; + int i = 0; + for (; kids != NULL; kids = kids->next) { + gchar *mark = (gchar *) g_object_get_data(G_OBJECT(kids->data), "marker"); + if ( mark && strcmp(mark, markname) == 0 ) { + if ( mark_is_stock && !strcmp((gchar *) g_object_get_data(G_OBJECT(kids->data), "stockid"), "true")) + markpos = i; + if ( !mark_is_stock && !strcmp((gchar *) g_object_get_data(G_OBJECT(kids->data), "stockid"), "false")) + markpos = i; + } + i++; + } + gtk_option_menu_set_history(GTK_OPTION_MENU(mnu), markpos); + + g_free (markname); + } + else { + gtk_option_menu_set_history(GTK_OPTION_MENU(mnu), 0); + } + gtk_object_set_data(GTK_OBJECT(mnu), "update", GINT_TO_POINTER(FALSE)); +} + +static void +sp_stroke_style_update_marker_menus( SPWidget *spw, + GSList const *objects) +{ + struct { char const *key; int loc; } const keyloc[] = { + { "start_mark_menu", SP_MARKER_LOC_START }, + { "mid_mark_menu", SP_MARKER_LOC_MID }, + { "end_mark_menu", SP_MARKER_LOC_END } + }; + + bool all_texts = true; + for (GSList *i = (GSList *) objects; i != NULL; i = i->next) { + if (!SP_IS_TEXT (i->data)) { + all_texts = false; + } + } + + for (unsigned i = 0; i < G_N_ELEMENTS(keyloc); ++i) { + GtkOptionMenu *mnu = (GtkOptionMenu *) g_object_get_data(G_OBJECT(spw), keyloc[i].key); + if (all_texts) { + // Per SVG spec, text objects cannot have markers; disable menus if only texts are selected + gtk_widget_set_sensitive (GTK_WIDGET(mnu), FALSE); + } else { + gtk_widget_set_sensitive (GTK_WIDGET(mnu), TRUE); + } + } + + // We show markers of the first object in the list only + // FIXME: use the first in the list that has the marker of each type, if any + SPObject *object = SP_OBJECT(objects->data); + + for (unsigned i = 0; i < G_N_ELEMENTS(keyloc); ++i) { + // For all three marker types, + + // find the corresponding menu + GtkOptionMenu *mnu = (GtkOptionMenu *) g_object_get_data(G_OBJECT(spw), keyloc[i].key); + + // Quit if we're in update state + if (gtk_object_get_data(GTK_OBJECT(mnu), "update")) { + return; + } + + if (object->style->marker[keyloc[i].loc].value != NULL && !all_texts) { + // If the object has this type of markers, + + // Extract the name of the marker that the object uses + SPObject *marker = ink_extract_marker_name(object->style->marker[keyloc[i].loc].value); + // Scroll the menu to that marker + ink_marker_menu_set_current (marker, mnu); + + } else { + gtk_option_menu_set_history(GTK_OPTION_MENU(mnu), 0); + } + } +} + + +/** Extract the actual name of the link + * e.g. get mTriangle from url(#mTriangle). + * \return Buffer containing the actual name, allocated from GLib; + * the caller should free the buffer when they no longer need it. + */ +static SPObject* +ink_extract_marker_name(gchar const *n) +{ + gchar const *p = n; + while (*p != '\0' && *p != '#') { + p++; + } + + if (*p == '\0' || p[1] == '\0') { + return NULL; + } + + p++; + int c = 0; + while (p[c] != '\0' && p[c] != ')') { + c++; + } + + if (p[c] == '\0') { + return NULL; + } + + gchar* b = g_strdup(p); + b[c] = '\0'; + + + SPDesktop *desktop = inkscape_active_desktop(); + SPDocument *doc = SP_DT_DOCUMENT(desktop); + SPObject *marker = doc->getObjectById(b); + return marker; +} + + +/* + 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=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/dialogs/stroke-style.h b/src/dialogs/stroke-style.h new file mode 100644 index 000000000..209407b3f --- /dev/null +++ b/src/dialogs/stroke-style.h @@ -0,0 +1,35 @@ +#ifndef __SP_STROKE_STYLE_H__ +#define __SP_STROKE_STYLE_H__ + +/** + * \brief Stroke style dialog + * + * Author: + * Lauris Kaplinski + * + * Copyright (C) 2001 Ximian, Inc. + * + */ + +#include + +#include + +#include "forward.h" +#include "display/canvas-bpath.h" + +GtkWidget *sp_stroke_style_paint_widget_new (void); +GtkWidget *sp_stroke_style_line_widget_new (void); + +#endif + +/* + 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:textwidth=99 : diff --git a/src/dialogs/swatches.cpp b/src/dialogs/swatches.cpp new file mode 100644 index 000000000..739cda3b2 --- /dev/null +++ b/src/dialogs/swatches.cpp @@ -0,0 +1,516 @@ +/* + * A simple panel for color swatches + * + * Authors: + * Jon A. Cruz + * + * Copyright (C) 2005 Jon A. Cruz + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include //for GTK_RESPONSE* types +#include + +#include +#include "inkscape.h" +#include "document.h" +#include "desktop-handles.h" +#include "extension/db.h" +#include "inkscape.h" +#include "svg/svg.h" +#include "desktop-style.h" +#include "io/sys.h" +#include "path-prefix.h" +#include "swatches.h" + +#include "eek-preview.h" + +namespace Inkscape { +namespace UI { +namespace Dialogs { + +SwatchesPanel* SwatchesPanel::instance = 0; + + +ColorItem::ColorItem( unsigned int r, unsigned int g, unsigned int b, Glib::ustring& name ) : + _r(r), + _g(g), + _b(b), + _name(name) +{ +} + +ColorItem::~ColorItem() +{ +} + +ColorItem::ColorItem(ColorItem const &other) : + Inkscape::UI::Previewable() +{ + if ( this != &other ) { + *this = other; + } +} + +ColorItem &ColorItem::operator=(ColorItem const &other) +{ + if ( this != &other ) { + _r = other._r; + _g = other._g; + _b = other._b; + _name = other._name; + } + return *this; +} + +typedef enum { + XCOLOR_DATA = 0, + TEXT_DATA +} colorFlavorType; + +static const GtkTargetEntry color_entries[] = { + {"application/x-color", 0, XCOLOR_DATA}, + {"text/plain", 0, TEXT_DATA}, +}; + +static void dragGetColorData( GtkWidget *widget, + GdkDragContext *drag_context, + GtkSelectionData *data, + guint info, + guint time, + gpointer user_data) +{ + static GdkAtom typeXColor = gdk_atom_intern("application/x-color", FALSE); + static GdkAtom typeText = gdk_atom_intern("text/plain", FALSE); + + ColorItem* item = reinterpret_cast(user_data); + if ( info == 1 ) { + gchar* tmp = g_strdup_printf("#%02x%02x%02x", item->_r, item->_g, item->_b); + + gtk_selection_data_set( data, + typeText, + 8, // format + (guchar*)tmp, + strlen((const char*)tmp) + 1); + g_free(tmp); + tmp = 0; + } else { + guchar tmp[8]; + tmp[0] = item->_r; + tmp[1] = item->_r; + tmp[2] = item->_g; + tmp[3] = item->_g; + tmp[4] = item->_b; + tmp[5] = item->_b; + tmp[6] = 0x0ff; + tmp[7] = 0x0ff; + gtk_selection_data_set( data, + typeXColor, + 8, // format + tmp, + (3+1) * 2); + } +} + +//"drag-drop" +gboolean dragDropColorData( GtkWidget *widget, + GdkDragContext *drag_context, + gint x, + gint y, + guint time, + gpointer user_data) +{ +// TODO finish + return TRUE; +} + +static void bouncy( GtkWidget* widget, gpointer callback_data ) { + ColorItem* item = reinterpret_cast(callback_data); + if ( item ) { + item->buttonClicked(false); + } +} + +static void bouncy2( GtkWidget* widget, gint arg1, gpointer callback_data ) { + ColorItem* item = reinterpret_cast(callback_data); + if ( item ) { + item->buttonClicked(true); + } +} + +Gtk::Widget* ColorItem::getPreview(PreviewStyle style, ViewType view, Gtk::BuiltinIconSize size) +{ + Gtk::Widget* widget = 0; + if ( style == PREVIEW_STYLE_BLURB ) { + Gtk::Label *lbl = new Gtk::Label(_name); + lbl->set_alignment(Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER); + widget = lbl; + } else { + Glib::ustring blank(" "); + if ( size == Gtk::ICON_SIZE_MENU ) { + blank = " "; + } + + GtkWidget* eekWidget = eek_preview_new(); + EekPreview * preview = EEK_PREVIEW(eekWidget); + Gtk::Widget* newBlot = Glib::wrap(eekWidget); + + eek_preview_set_color( preview, (_r << 8)|_r, (_g << 8)|_g, (_b << 8)|_b); + + eek_preview_set_details( preview, (::PreviewStyle)style, (::ViewType)view, (::GtkIconSize)size ); + + GValue val = {0, {{0}, {0}}}; + g_value_init( &val, G_TYPE_BOOLEAN ); + g_value_set_boolean( &val, FALSE ); + g_object_set_property( G_OBJECT(preview), "focus-on-click", &val ); + +/* + Gtk::Button *btn = new Gtk::Button(blank); + Gdk::Color color; + color.set_rgb((_r << 8)|_r, (_g << 8)|_g, (_b << 8)|_b); + btn->modify_bg(Gtk::STATE_NORMAL, color); + btn->modify_bg(Gtk::STATE_ACTIVE, color); + btn->modify_bg(Gtk::STATE_PRELIGHT, color); + btn->modify_bg(Gtk::STATE_SELECTED, color); + + Gtk::Widget* newBlot = btn; +*/ + + tips.set_tip((*newBlot), _name); + +/* + newBlot->signal_clicked().connect( sigc::mem_fun(*this, &ColorItem::buttonClicked) ); + + sigc::signal type_signal_something; +*/ + g_signal_connect( G_OBJECT(newBlot->gobj()), + "clicked", + G_CALLBACK(bouncy), + this); + + g_signal_connect( G_OBJECT(newBlot->gobj()), + "alt-clicked", + G_CALLBACK(bouncy2), + this); + + gtk_drag_source_set( GTK_WIDGET(newBlot->gobj()), + GDK_BUTTON1_MASK, + color_entries, + G_N_ELEMENTS(color_entries), + GdkDragAction(GDK_ACTION_MOVE | GDK_ACTION_COPY) ); + + g_signal_connect( G_OBJECT(newBlot->gobj()), + "drag-data-get", + G_CALLBACK(dragGetColorData), + this); + + g_signal_connect( G_OBJECT(newBlot->gobj()), + "drag-drop", + G_CALLBACK(dragDropColorData), + this); + + widget = newBlot; + } + + return widget; +} + +void ColorItem::buttonClicked(bool secondary) +{ + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + if (desktop) { + char const * attrName = secondary ? "stroke" : "fill"; + guint32 rgba = (_r << 24) | (_g << 16) | (_b << 8) | 0xff; + gchar c[64]; + sp_svg_write_color(c, 64, rgba); + + SPCSSAttr *css = sp_repr_css_attr_new(); + sp_repr_css_set_property( css, attrName, c ); + sp_desktop_set_style(desktop, css); + + sp_repr_css_attr_unref(css); + sp_document_done (SP_DT_DOCUMENT (desktop)); + } +} + + + + +static char* trim( char* str ) { + char* ret = str; + while ( *str && (*str == ' ' || *str == '\t') ) { + str++; + } + ret = str; + while ( *str ) { + str++; + } + str--; + while ( str > ret && ( *str == ' ' || *str == '\t' ) || *str == '\r' || *str == '\n' ) { + *str-- = 0; + } + return ret; +} + +void skipWhitespace( char*& str ) { + while ( *str == ' ' || *str == '\t' ) { + str++; + } +} + +bool parseNum( char*& str, int& val ) { + val = 0; + while ( '0' <= *str && *str <= '9' ) { + val = val * 10 + (*str - '0'); + str++; + } + bool retval = !(*str == 0 || *str == ' ' || *str == '\t' || *str == '\r' || *str == '\n'); + return retval; +} + + +class JustForNow +{ +public: + Glib::ustring _name; + std::vector _colors; +}; + +static std::vector possible; + +static void loadPaletteFile( gchar const *filename ) +{ + char block[1024]; + FILE *f = Inkscape::IO::fopen_utf8name( filename, "r" ); + if ( f ) { + char* result = fgets( block, sizeof(block), f ); + if ( result ) { + if ( strncmp( "GIMP Palette", block, 12 ) == 0 ) { + bool inHeader = true; + bool hasErr = false; + + JustForNow *onceMore = new JustForNow(); + + do { + result = fgets( block, sizeof(block), f ); + block[sizeof(block) - 1] = 0; + if ( result ) { + if ( block[0] == '#' ) { + // ignore comment + } else { + char *ptr = block; + // very simple check for header versus entry + while ( *ptr == ' ' || *ptr == '\t' ) { + ptr++; + } + if ( *ptr == 0 ) { + // blank line. skip it. + } else if ( '0' <= *ptr && *ptr <= '9' ) { + // should be an entry link + inHeader = false; + ptr = block; + Glib::ustring name(""); + int r = 0; + int g = 0; + int b = 0; + skipWhitespace(ptr); + if ( *ptr ) { + hasErr = parseNum(ptr, r); + if ( !hasErr ) { + skipWhitespace(ptr); + hasErr = parseNum(ptr, g); + } + if ( !hasErr ) { + skipWhitespace(ptr); + hasErr = parseNum(ptr, b); + } + if ( !hasErr && *ptr ) { + char* n = trim(ptr); + if (n != NULL) { + name = n; + } + } + if ( !hasErr ) { + // Add the entry now + Glib::ustring nameStr(name); + ColorItem* item = new ColorItem( r, g, b, nameStr ); + onceMore->_colors.push_back(item); + } + } else { + hasErr = true; + } + } else { + if ( !inHeader ) { + // Hmmm... probably bad. Not quite the format we want? + hasErr = true; + } else { + char* sep = strchr(result, ':'); + if ( sep ) { + *sep = 0; + char* val = trim(sep + 1); + char* name = trim(result); + if ( *name ) { + if ( strcmp( "Name", name ) == 0 ) { + onceMore->_name = val; + } + } else { + // error + hasErr = true; + } + } else { + // error + hasErr = true; + } + } + } + } + } + } while ( result && !hasErr ); + if ( !hasErr ) { + possible.push_back(onceMore); + } else { + delete onceMore; + } + } + } + + fclose(f); + } +} + +static void loadEmUp() +{ + static bool beenHere = false; + if ( !beenHere ) { + beenHere = true; + + std::list sources; + sources.push_back( profile_path("palettes") ); + sources.push_back( g_strdup(INKSCAPE_PALETTESDIR) ); + + // Use this loop to iterate through a list of possible document locations. + while (!sources.empty()) { + gchar *dirname = sources.front(); + + if ( Inkscape::IO::file_test( dirname, (GFileTest)(G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR) ) ) { + GError *err = 0; + GDir *directory = g_dir_open(dirname, 0, &err); + if (!directory) { + gchar *safeDir = Inkscape::IO::sanitizeString(dirname); + g_warning(_("Palettes directory (%s) is unavailable."), safeDir); + g_free(safeDir); + } else { + gchar *filename = 0; + while ((filename = (gchar *)g_dir_read_name(directory)) != NULL) { + gchar* full = g_build_filename(dirname, filename, NULL); + if ( !Inkscape::IO::file_test( full, (GFileTest)(G_FILE_TEST_IS_DIR ) ) ) { + loadPaletteFile(full); + } + g_free(full); + } + g_dir_close(directory); + } + } + + // toss the dirname + g_free(dirname); + sources.pop_front(); + } + } +} + + + + + + + + + +SwatchesPanel& SwatchesPanel::getInstance() +{ + if ( !instance ) { + instance = new SwatchesPanel(); + } + + return *instance; +} + + + +/** + * Constructor + */ +SwatchesPanel::SwatchesPanel() : + Inkscape::UI::Widget::Panel ("dialogs.swatches"), + _holder(0) +{ + _holder = new PreviewHolder(); + loadEmUp(); + + if ( !possible.empty() ) { + JustForNow* first = possible.front(); + for ( std::vector::iterator it = first->_colors.begin(); it != first->_colors.end(); it++ ) { + _holder->addPreview(*it); + } + + Gtk::RadioMenuItem::Group groupOne; + int i = 0; + for ( std::vector::iterator it = possible.begin(); it != possible.end(); it++ ) { + JustForNow* curr = *it; + Gtk::RadioMenuItem* single = manage(new Gtk::RadioMenuItem(groupOne, curr->_name)); + _regItem( single, 3, i ); + i++; + } + + } + + + pack_start(*_holder, Gtk::PACK_EXPAND_WIDGET); + _setTargetFillable(_holder); + + show_all_children(); + + restorePanelPrefs(); +} + +SwatchesPanel::~SwatchesPanel() +{ +} + +void SwatchesPanel::_handleAction( int setId, int itemId ) +{ + switch( setId ) { + case 3: + { + if ( itemId >= 0 && itemId < static_cast(possible.size()) ) { + _holder->clear(); + JustForNow* curr = possible[itemId]; + for ( std::vector::iterator it = curr->_colors.begin(); it != curr->_colors.end(); it++ ) { + _holder->addPreview(*it); + } + } + } + break; + } +} + +} //namespace Dialogs +} //namespace UI +} //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:textwidth=99 : diff --git a/src/dialogs/swatches.h b/src/dialogs/swatches.h new file mode 100644 index 000000000..ca17cd066 --- /dev/null +++ b/src/dialogs/swatches.h @@ -0,0 +1,93 @@ + +#ifndef SEEN_SWATCHES_H +#define SEEN_SWATCHES_H +/* + * A simple dialog for previewing icon representation. + * + * Authors: + * Jon A. Cruz + * + * Copyright (C) 2005 Jon A. Cruz + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include +#include + +#include "ui/widget/panel.h" +#include "ui/previewholder.h" + +namespace Inkscape { +namespace UI { +namespace Dialogs { + + + +/** + * The color swatch you see on screen as a clickable box. + */ +class ColorItem : public Inkscape::UI::Previewable +{ +public: + ColorItem( unsigned int r, unsigned int g, unsigned int b, + Glib::ustring& name ); + virtual ~ColorItem(); + ColorItem(ColorItem const &other); + virtual ColorItem &operator=(ColorItem const &other); + virtual Gtk::Widget* getPreview(PreviewStyle style, + ViewType view, + Gtk::BuiltinIconSize size); + void buttonClicked(bool secondary = false); + unsigned int _r; + unsigned int _g; + unsigned int _b; + Glib::ustring _name; + +private: + Gtk::Tooltips tips; +}; + + + +/** + * A panel that displays color swatches. + */ +class SwatchesPanel : public Inkscape::UI::Widget::Panel +{ +public: + SwatchesPanel(); + virtual ~SwatchesPanel(); + + static SwatchesPanel& getInstance(); + +protected: + virtual void _handleAction( int setId, int itemId ); + +private: + SwatchesPanel(SwatchesPanel const &); // no copy + SwatchesPanel &operator=(SwatchesPanel const &); // no assign + + static SwatchesPanel* instance; + + PreviewHolder* _holder; +}; + +} //namespace Dialogs +} //namespace UI +} //namespace Inkscape + + + +#endif // SEEN_SWATCHES_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:encoding=utf-8:textwidth=99 : diff --git a/src/dialogs/text-edit.cpp b/src/dialogs/text-edit.cpp new file mode 100644 index 000000000..b4dcd4bce --- /dev/null +++ b/src/dialogs/text-edit.cpp @@ -0,0 +1,915 @@ +#define __SP_TEXT_EDIT_C__ + +/** + * \brief Text editing dialog + * + * Author: + * Lauris Kaplinski + * bulia byak + * + * Copyright (C) 1999-2002 Lauris Kaplinski + * Copyright (C) 2000-2001 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include + +#ifdef WITH_GTKSPELL +extern "C" { +# include +} +#endif + +#include "macros.h" +#include +#include "helper/window.h" +#include "../widgets/font-selector.h" +#include "../inkscape.h" +#include "../document.h" +#include "../desktop-style.h" +#include "../desktop-handles.h" +#include "../selection.h" +#include "../style.h" +#include "../sp-text.h" +#include "../sp-flowtext.h" +#include "../text-editing.h" +#include "../inkscape-stock.h" +#include + +#include "dialog-events.h" +#include "../prefs-utils.h" +#include "../verbs.h" +#include "../interface.h" +#include "svg/css-ostringstream.h" +#include "widgets/icon.h" +#include + + +#define VB_MARGIN 4 + +static void sp_text_edit_dialog_selection_modified (Inkscape::Application *inkscape, Inkscape::Selection *sel, guint flags, GtkWidget *dlg); +static void sp_text_edit_dialog_selection_changed (Inkscape::Application *inkscape, Inkscape::Selection *sel, GtkWidget *dlg); +static void sp_text_edit_dialog_subselection_changed ( Inkscape::Application *inkscape, SPDesktop *desktop, GtkWidget *dlg); + +static void sp_text_edit_dialog_set_default (GtkButton *button, GtkWidget *dlg); +static void sp_text_edit_dialog_apply (GtkButton *button, GtkWidget *dlg); +static void sp_text_edit_dialog_close (GtkButton *button, GtkWidget *dlg); + +static void sp_text_edit_dialog_read_selection (GtkWidget *dlg, gboolean style, gboolean content); + +static void sp_text_edit_dialog_text_changed (GtkTextBuffer *tb, GtkWidget *dlg); +static void sp_text_edit_dialog_font_changed (SPFontSelector *fontsel, font_instance *font, GtkWidget *dlg); +static void sp_text_edit_dialog_any_toggled (GtkToggleButton *tb, GtkWidget *dlg); +static void sp_text_edit_dialog_line_spacing_changed (GtkEditable *editable, GtkWidget *dlg); + +static SPItem *sp_ted_get_selected_text_item (void); +static unsigned sp_ted_get_selected_text_count (void); + + +static const gchar *spacings[] = {"50%", "80%", "90%", "100%", "110%", "120%", "130%", "140%", "150%", "200%", "300%", NULL}; + +static GtkWidget *dlg = NULL; +static win_data wd; +// impossible original values to make sure they are read from prefs +static gint x = -1000, y = -1000, w = 0, h = 0; +static gchar const *prefs_path = "dialogs.textandfont"; + + + + +static void +sp_text_edit_dialog_destroy (GtkObject *object, gpointer data) +{ + sp_signal_disconnect_by_data (INKSCAPE, dlg); + wd.win = dlg = NULL; + wd.stop = 0; +} + + + +static gboolean +sp_text_edit_dialog_delete (GtkObject *object, GdkEvent *event, gpointer data) +{ + gtk_window_get_position ((GtkWindow *) dlg, &x, &y); + gtk_window_get_size ((GtkWindow *) dlg, &w, &h); + + prefs_set_int_attribute (prefs_path, "x", x); + prefs_set_int_attribute (prefs_path, "y", y); + prefs_set_int_attribute (prefs_path, "w", w); + prefs_set_int_attribute (prefs_path, "h", h); + + return FALSE; // which means, go ahead and destroy it +} + + +/** + These callbacks set the eatkeys flag when the text editor is entered and cancel it when it's left. + This flag is used to prevent passing keys from the dialog to canvas, so that the text editor + can handle keys like Esc and Ctrl+Z itself. + */ +gboolean +text_view_focus_in (GtkWidget *w, GdkEventKey *event, gpointer data) +{ + GObject *dlg = (GObject *) data; + g_object_set_data (dlg, "eatkeys", GINT_TO_POINTER (TRUE)); + return FALSE; +} + +gboolean +text_view_focus_out (GtkWidget *w, GdkEventKey *event, gpointer data) +{ + GObject *dlg = (GObject *) data; + g_object_set_data (dlg, "eatkeys", GINT_TO_POINTER (FALSE)); + return FALSE; +} + + +void +sp_text_edit_dialog (void) +{ + + if (!dlg) { + + gchar title[500]; + sp_ui_dialog_title_string (Inkscape::Verb::get(SP_VERB_DIALOG_TEXT), title); + + dlg = sp_window_new (title, TRUE); + if (x == -1000 || y == -1000) { + x = prefs_get_int_attribute (prefs_path, "x", 0); + y = prefs_get_int_attribute (prefs_path, "y", 0); + } + + if (w ==0 || h == 0) { + w = prefs_get_int_attribute (prefs_path, "w", 0); + h = prefs_get_int_attribute (prefs_path, "h", 0); + } + + if (x != 0 || y != 0) { + gtk_window_move ((GtkWindow *) dlg, x, y); + } else { + gtk_window_set_position(GTK_WINDOW(dlg), GTK_WIN_POS_CENTER); + } + + if (w && h) + gtk_window_resize ((GtkWindow *) dlg, w, h); + + sp_transientize (dlg); + wd.win = dlg; + wd.stop = 0; + g_signal_connect ( G_OBJECT (INKSCAPE), "activate_desktop", G_CALLBACK (sp_transientize_callback), &wd ); + + gtk_signal_connect ( GTK_OBJECT (dlg), "event", GTK_SIGNAL_FUNC (sp_dialog_event_handler), dlg ); + + gtk_signal_connect ( GTK_OBJECT (dlg), "destroy", G_CALLBACK (sp_text_edit_dialog_destroy), dlg ); + gtk_signal_connect ( GTK_OBJECT (dlg), "delete_event", G_CALLBACK (sp_text_edit_dialog_delete), dlg ); + g_signal_connect ( G_OBJECT (INKSCAPE), "shut_down", G_CALLBACK (sp_text_edit_dialog_delete), dlg ); + + g_signal_connect ( G_OBJECT (INKSCAPE), "dialogs_hide", G_CALLBACK (sp_dialog_hide), dlg ); + g_signal_connect ( G_OBJECT (INKSCAPE), "dialogs_unhide", G_CALLBACK (sp_dialog_unhide), dlg ); + + gtk_window_set_policy (GTK_WINDOW (dlg), TRUE, TRUE, FALSE); + + GtkTooltips *tt = gtk_tooltips_new(); + + // box containing the notebook and the bottom buttons + GtkWidget *mainvb = gtk_vbox_new (FALSE, 0); + gtk_container_add (GTK_CONTAINER (dlg), mainvb); + + // notebook + GtkWidget *nb = gtk_notebook_new (); + gtk_box_pack_start (GTK_BOX (mainvb), nb, TRUE, TRUE, 0); + g_object_set_data (G_OBJECT (dlg), "notebook", nb); + + + + // Font tab + { + GtkWidget *l = gtk_label_new (_("Font")); + GtkWidget *vb = gtk_vbox_new (FALSE, VB_MARGIN); + gtk_container_set_border_width (GTK_CONTAINER (vb), VB_MARGIN); + gtk_notebook_append_page (GTK_NOTEBOOK (nb), vb, l); + + /* HBox containing font selection and layout */ + GtkWidget *hb = gtk_hbox_new (FALSE, 0); + gtk_box_pack_start (GTK_BOX (vb), hb, TRUE, TRUE, 0); + + // font and style selector + GtkWidget *fontsel = sp_font_selector_new (); + g_signal_connect ( G_OBJECT (fontsel), "font_set", G_CALLBACK (sp_text_edit_dialog_font_changed), dlg ); + gtk_box_pack_start (GTK_BOX (hb), fontsel, TRUE, TRUE, 0); + g_object_set_data (G_OBJECT (dlg), "fontsel", fontsel); + + // Layout + { + GtkWidget *f = gtk_frame_new (_("Layout")); + gtk_box_pack_start (GTK_BOX (hb), f, FALSE, FALSE, 4); + GtkWidget *l_vb = gtk_vbox_new (FALSE, VB_MARGIN); + gtk_container_add (GTK_CONTAINER (f), l_vb); + + { + GtkWidget *row = gtk_hbox_new (FALSE, VB_MARGIN); + GtkWidget *group; + + // align left + { + GtkWidget *px = gtk_image_new_from_stock ( GTK_STOCK_JUSTIFY_LEFT, GTK_ICON_SIZE_LARGE_TOOLBAR ); + GtkWidget *b = group = gtk_radio_button_new (NULL); + gtk_tooltips_set_tip (tt, b, _("Align lines left"), NULL); + gtk_button_set_relief (GTK_BUTTON (b), GTK_RELIEF_NONE); + g_signal_connect ( G_OBJECT (b), "toggled", G_CALLBACK (sp_text_edit_dialog_any_toggled), dlg); + gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (b), FALSE ); + gtk_container_add (GTK_CONTAINER (b), px); + gtk_box_pack_start (GTK_BOX (row), b, FALSE, FALSE, 0); + g_object_set_data (G_OBJECT (dlg), "text_anchor_start", b); + } + + // align center + { + GtkWidget *px = gtk_image_new_from_stock ( GTK_STOCK_JUSTIFY_CENTER, GTK_ICON_SIZE_LARGE_TOOLBAR ); + GtkWidget *b = gtk_radio_button_new (gtk_radio_button_group (GTK_RADIO_BUTTON (group))); + /* TRANSLATORS: `Center' here is a verb. */ + gtk_tooltips_set_tip (tt, b, _("Center lines"), NULL); + gtk_button_set_relief (GTK_BUTTON (b), GTK_RELIEF_NONE); + g_signal_connect ( G_OBJECT (b), "toggled", G_CALLBACK (sp_text_edit_dialog_any_toggled), dlg ); + gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (b), FALSE); + gtk_container_add (GTK_CONTAINER (b), px); + gtk_box_pack_start (GTK_BOX (row), b, FALSE, FALSE, 0); + g_object_set_data (G_OBJECT (dlg), "text_anchor_middle", b); + } + + // align right + { + GtkWidget *px = gtk_image_new_from_stock ( GTK_STOCK_JUSTIFY_RIGHT, GTK_ICON_SIZE_LARGE_TOOLBAR ); + GtkWidget *b = gtk_radio_button_new (gtk_radio_button_group (GTK_RADIO_BUTTON (group))); + gtk_tooltips_set_tip (tt, b, _("Align lines right"), NULL); + gtk_button_set_relief (GTK_BUTTON (b), GTK_RELIEF_NONE); + g_signal_connect ( G_OBJECT (b), "toggled", G_CALLBACK (sp_text_edit_dialog_any_toggled), dlg ); + gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (b), FALSE); + gtk_container_add (GTK_CONTAINER (b), px); + gtk_box_pack_start (GTK_BOX (row), b, FALSE, FALSE, 0); + g_object_set_data (G_OBJECT (dlg), "text_anchor_end", b); + } + + gtk_box_pack_start (GTK_BOX (l_vb), row, FALSE, FALSE, 0); + } + + + { + GtkWidget *row = gtk_hbox_new (FALSE, VB_MARGIN); + GtkWidget *group; + + // horizontal + { + GtkWidget *px = sp_icon_new( GTK_ICON_SIZE_LARGE_TOOLBAR, + INKSCAPE_STOCK_WRITING_MODE_LR ); + GtkWidget *b = group = gtk_radio_button_new (NULL); + gtk_tooltips_set_tip (tt, b, _("Horizontal text"), NULL); + gtk_button_set_relief (GTK_BUTTON (b), GTK_RELIEF_NONE); + g_signal_connect ( G_OBJECT (b), "toggled", G_CALLBACK (sp_text_edit_dialog_any_toggled), dlg ); + gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (b), FALSE); + gtk_container_add (GTK_CONTAINER (b), px); + gtk_box_pack_start (GTK_BOX (row), b, FALSE, FALSE, 0); + g_object_set_data (G_OBJECT (dlg), INKSCAPE_STOCK_WRITING_MODE_LR, b); + } + + // vertical + { + GtkWidget *px = sp_icon_new( GTK_ICON_SIZE_LARGE_TOOLBAR, + INKSCAPE_STOCK_WRITING_MODE_TB ); + GtkWidget *b = gtk_radio_button_new (gtk_radio_button_group (GTK_RADIO_BUTTON (group))); + gtk_tooltips_set_tip (tt, b, _("Vertical text"), NULL); + gtk_button_set_relief (GTK_BUTTON (b), GTK_RELIEF_NONE); + g_signal_connect ( G_OBJECT (b), "toggled", G_CALLBACK (sp_text_edit_dialog_any_toggled), dlg ); + gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (b), FALSE); + gtk_container_add (GTK_CONTAINER (b), px); + gtk_box_pack_start (GTK_BOX (row), b, FALSE, FALSE, 0); + g_object_set_data (G_OBJECT (dlg), INKSCAPE_STOCK_WRITING_MODE_TB, b); + } + + gtk_box_pack_start (GTK_BOX (l_vb), row, FALSE, FALSE, 0); + } + + { + GtkWidget *row = gtk_hbox_new (FALSE, VB_MARGIN); + + l = gtk_label_new (_("Line spacing:")); + gtk_misc_set_alignment (GTK_MISC (l), 1.0, 0.5); + gtk_box_pack_start (GTK_BOX (row), l, FALSE, FALSE, VB_MARGIN); + + gtk_box_pack_start (GTK_BOX (l_vb), row, FALSE, FALSE, 0); + } + + { + GtkWidget *row = gtk_hbox_new (FALSE, VB_MARGIN); + + GtkWidget *c = gtk_combo_new (); + gtk_combo_set_value_in_list ((GtkCombo *) c, FALSE, FALSE); + gtk_combo_set_use_arrows ((GtkCombo *) c, TRUE); + gtk_combo_set_use_arrows_always ((GtkCombo *) c, TRUE); + gtk_widget_set_size_request (c, 90, -1); + + { /* Setup strings */ + GList *sl = NULL; + for (int i = 0; spacings[i]; i++) { + sl = g_list_prepend (sl, (void *) spacings[i]); + } + sl = g_list_reverse (sl); + gtk_combo_set_popdown_strings ((GtkCombo *) c, sl); + g_list_free (sl); + } + + g_signal_connect ( (GObject *) ((GtkCombo *) c)->entry, + "changed", + (GCallback) sp_text_edit_dialog_line_spacing_changed, + dlg ); + gtk_box_pack_start (GTK_BOX (row), c, FALSE, FALSE, VB_MARGIN); + g_object_set_data (G_OBJECT (dlg), "line_spacing", c); + + gtk_box_pack_start (GTK_BOX (l_vb), row, FALSE, FALSE, VB_MARGIN); + } + } + + /* Font preview */ + GtkWidget *preview = sp_font_preview_new (); + gtk_box_pack_start (GTK_BOX (vb), preview, TRUE, TRUE, 4); + g_object_set_data (G_OBJECT (dlg), "preview", preview); + } + + + // Text tab + { + GtkWidget *l = gtk_label_new (_("Text")); + GtkWidget *vb = gtk_vbox_new (FALSE, VB_MARGIN); + gtk_container_set_border_width (GTK_CONTAINER (vb), VB_MARGIN); + gtk_notebook_append_page (GTK_NOTEBOOK (nb), vb, l); + + GtkWidget *scroller = gtk_scrolled_window_new ( NULL, NULL ); + gtk_scrolled_window_set_policy ( GTK_SCROLLED_WINDOW (scroller), + GTK_POLICY_AUTOMATIC, + GTK_POLICY_AUTOMATIC ); + gtk_scrolled_window_set_shadow_type ( GTK_SCROLLED_WINDOW(scroller), GTK_SHADOW_IN ); + gtk_widget_show (scroller); + + GtkTextBuffer *tb = gtk_text_buffer_new (NULL); + GtkWidget *txt = gtk_text_view_new_with_buffer (tb); + gtk_text_view_set_wrap_mode ((GtkTextView *) txt, GTK_WRAP_WORD); +#ifdef WITH_GTKSPELL + GError *error = NULL; + char *errortext = NULL; + /* todo: Use computed xml:lang attribute of relevant element, if present, to specify the + language (either as 2nd arg of gtkspell_new_attach, or with explicit + gtkspell_set_language call in; see advanced.c example in gtkspell docs). + sp_text_edit_dialog_read_selection looks like a suitable place. */ + if (gtkspell_new_attach(GTK_TEXT_VIEW(txt), NULL, &error) == NULL) { + g_print("gtkspell error: %s\n", error->message); + errortext = g_strdup_printf("GtkSpell was unable to initialize.\n" + "%s", error->message); + g_error_free(error); + } +#endif + gtk_widget_set_size_request (txt, -1, 64); + gtk_text_view_set_editable (GTK_TEXT_VIEW (txt), TRUE); + gtk_container_add (GTK_CONTAINER (scroller), txt); + gtk_box_pack_start (GTK_BOX (vb), scroller, TRUE, TRUE, 0); + g_signal_connect ( G_OBJECT (tb), "changed", + G_CALLBACK (sp_text_edit_dialog_text_changed), dlg ); + g_signal_connect (G_OBJECT (txt), "focus-in-event", G_CALLBACK (text_view_focus_in), dlg); + g_signal_connect (G_OBJECT (txt), "focus-out-event", G_CALLBACK (text_view_focus_out), dlg); + g_object_set_data (G_OBJECT (dlg), "text", tb); + g_object_set_data (G_OBJECT (dlg), "textw", txt); + } + + /* Buttons */ + GtkWidget *hb = gtk_hbox_new (FALSE, VB_MARGIN); + gtk_container_set_border_width (GTK_CONTAINER (hb), 4); + gtk_box_pack_start (GTK_BOX (mainvb), hb, FALSE, FALSE, 0); + + { + GtkWidget *b = gtk_button_new_with_label (_("Set as default")); + g_signal_connect ( G_OBJECT (b), "clicked", + G_CALLBACK (sp_text_edit_dialog_set_default), + dlg ); + gtk_box_pack_start (GTK_BOX (hb), b, FALSE, FALSE, 0); + g_object_set_data (G_OBJECT (dlg), "default", b); + } + + { + GtkWidget *b = gtk_button_new_from_stock (GTK_STOCK_CLOSE); + g_signal_connect ( G_OBJECT (b), "clicked", + G_CALLBACK (sp_text_edit_dialog_close), dlg ); + gtk_box_pack_end (GTK_BOX (hb), b, FALSE, FALSE, 0); + } + + { + GtkWidget *b = gtk_button_new_from_stock (GTK_STOCK_APPLY); + g_signal_connect ( G_OBJECT (b), "clicked", + G_CALLBACK (sp_text_edit_dialog_apply), dlg ); + gtk_box_pack_end ( GTK_BOX (hb), b, FALSE, FALSE, 0 ); + g_object_set_data (G_OBJECT (dlg), "apply", b); + } + + g_signal_connect ( G_OBJECT (INKSCAPE), "modify_selection", + G_CALLBACK (sp_text_edit_dialog_selection_modified), dlg); + g_signal_connect ( G_OBJECT (INKSCAPE), "change_selection", + G_CALLBACK (sp_text_edit_dialog_selection_changed), dlg); + g_signal_connect (INKSCAPE, "change_subselection", G_CALLBACK (sp_text_edit_dialog_subselection_changed), dlg); + + gtk_widget_show_all (dlg); + + sp_text_edit_dialog_read_selection (dlg, TRUE, TRUE); + } + + gtk_window_present ((GtkWindow *) dlg); + +} // end of sp_text_edit_dialog() + + + +static void +sp_text_edit_dialog_selection_modified ( Inkscape::Application *inkscape, + Inkscape::Selection *sel, + guint flags, + GtkWidget *dlg ) +{ + gboolean style, content; + + style = + ((flags & ( SP_OBJECT_CHILD_MODIFIED_FLAG | + SP_OBJECT_STYLE_MODIFIED_FLAG )) != 0 ); + + content = + ((flags & ( SP_OBJECT_CHILD_MODIFIED_FLAG | + SP_TEXT_CONTENT_MODIFIED_FLAG )) != 0 ); + + sp_text_edit_dialog_read_selection (dlg, style, content); + +} + + + +static void +sp_text_edit_dialog_selection_changed ( Inkscape::Application *inkscape, + Inkscape::Selection *sel, + GtkWidget *dlg ) +{ + sp_text_edit_dialog_read_selection (dlg, TRUE, TRUE); +} + +static void sp_text_edit_dialog_subselection_changed ( Inkscape::Application *inkscape, SPDesktop *desktop, GtkWidget *dlg ) +{ + sp_text_edit_dialog_read_selection (dlg, TRUE, FALSE); +} + +static void +sp_text_edit_dialog_update_object_text ( SPItem *text ) +{ + GtkTextBuffer *tb; + GtkTextIter start, end; + gchar *str; + + tb = (GtkTextBuffer*)g_object_get_data (G_OBJECT (dlg), "text"); + + /* write text */ + if (gtk_text_buffer_get_modified (tb)) { + gtk_text_buffer_get_bounds (tb, &start, &end); + str = gtk_text_buffer_get_text (tb, &start, &end, TRUE); + sp_te_set_repr_text_multiline (text, str); + g_free (str); + gtk_text_buffer_set_modified (tb, FALSE); + } +} + +SPCSSAttr * +sp_get_text_dialog_style () +{ + GtkWidget *fontsel = (GtkWidget*)g_object_get_data (G_OBJECT (dlg), "fontsel"); + + SPCSSAttr *css = sp_repr_css_attr_new (); + + /* font */ + font_instance *font = sp_font_selector_get_font (SP_FONT_SELECTOR (fontsel)); + + if ( font ) { + gchar c[256]; + font->Family(c, 256); + sp_repr_css_set_property (css, "font-family", c); + + font->Attribute( "weight", c, 256); + sp_repr_css_set_property (css, "font-weight", c); + + font->Attribute("style", c, 256); + sp_repr_css_set_property (css, "font-style", c); + + font->Attribute("stretch", c, 256); + sp_repr_css_set_property (css, "font-stretch", c); + + font->Attribute("variant", c, 256); + sp_repr_css_set_property (css, "font-variant", c); + + Inkscape::CSSOStringStream os; + os << sp_font_selector_get_size (SP_FONT_SELECTOR (fontsel)); + sp_repr_css_set_property (css, "font-size", os.str().c_str()); + + font->Unref(); + font=NULL; + } + + /* Layout */ + GtkWidget *b = (GtkWidget*)g_object_get_data (G_OBJECT (dlg), "text_anchor_start"); + + if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (b))) { + sp_repr_css_set_property (css, "text-anchor", "start"); + sp_repr_css_set_property (css, "text-align", "start"); + } else { + b = (GtkWidget*)g_object_get_data ( G_OBJECT (dlg), + "text_anchor_middle"); + if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (b))) { + sp_repr_css_set_property (css, "text-anchor", "middle"); + sp_repr_css_set_property (css, "text-align", "center"); + } else { + sp_repr_css_set_property (css, "text-anchor", "end"); + sp_repr_css_set_property (css, "text-align", "end"); + } + } + + b = (GtkWidget*)g_object_get_data (G_OBJECT (dlg), INKSCAPE_STOCK_WRITING_MODE_LR ); + + if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (b))) { + sp_repr_css_set_property (css, "writing-mode", "lr"); + } else { + sp_repr_css_set_property (css, "writing-mode", "tb"); + } + + // Note that CSS 1.1 does not support line-height; we set it for consistency, but also set + // sodipodi:linespacing for backwards compatibility; in 1.2 we use line-height for flowtext + GtkWidget *combo = (GtkWidget*)g_object_get_data ((GObject *) dlg, "line_spacing"); + const char *sstr = gtk_entry_get_text ((GtkEntry *) ((GtkCombo *) (combo))->entry); + sp_repr_css_set_property (css, "line-height", sstr); + + return css; +} + + +static void +sp_text_edit_dialog_set_default (GtkButton *button, GtkWidget *dlg) +{ + GtkWidget *def = (GtkWidget*)g_object_get_data (G_OBJECT (dlg), "default"); + + SPCSSAttr *css = sp_get_text_dialog_style (); + + g_object_set_data (G_OBJECT (dlg), "blocked", GINT_TO_POINTER (TRUE)); + sp_repr_css_change (inkscape_get_repr (INKSCAPE, "tools.text"), css, "style"); + g_object_set_data (G_OBJECT (dlg), "blocked", GINT_TO_POINTER (FALSE)); + + sp_repr_css_attr_unref (css); + + gtk_widget_set_sensitive (def, FALSE); +} + + + +static void +sp_text_edit_dialog_apply (GtkButton *button, GtkWidget *dlg) +{ + g_object_set_data (G_OBJECT (dlg), "blocked", GINT_TO_POINTER (TRUE)); + + GtkWidget *apply = (GtkWidget*)g_object_get_data (G_OBJECT (dlg), "apply"); + GtkWidget *def = (GtkWidget*)g_object_get_data (G_OBJECT (dlg), "default"); + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + + unsigned items = 0; + const GSList *item_list = SP_DT_SELECTION(desktop)->itemList(); + + SPCSSAttr *css = sp_get_text_dialog_style (); + + sp_desktop_set_style(desktop, css, true); + + for (; item_list != NULL; item_list = item_list->next) { + // apply style to the reprs of all text objects in the selection + if (SP_IS_TEXT (item_list->data)) { + + // backwards compatibility: + SP_OBJECT_REPR(item_list->data)->setAttribute("sodipodi:linespacing", sp_repr_css_property (css, "line-height", NULL)); + + ++items; + } + else if (SP_IS_FLOWTEXT (item_list->data)) + // no need to set sodipodi:linespacing, because Inkscape never supported it on flowtext + ++items; + } + + if (items == 0) { + // no text objects; apply style to prefs for new objects + sp_repr_css_change (inkscape_get_repr (INKSCAPE, "tools.text"), css, "style"); + gtk_widget_set_sensitive (def, FALSE); + } else if (items == 1) { + /* exactly one text object; now set its text, too */ + SPItem *item = SP_DT_SELECTION(SP_ACTIVE_DESKTOP)->singleItem(); + if (SP_IS_TEXT (item) || SP_IS_FLOWTEXT(item)) { + sp_text_edit_dialog_update_object_text (item); + } + } + + // complete the transaction + sp_document_done (SP_DT_DOCUMENT (SP_ACTIVE_DESKTOP)); + + gtk_widget_set_sensitive (apply, FALSE); + + sp_repr_css_attr_unref (css); + + g_object_set_data (G_OBJECT (dlg), "blocked", GINT_TO_POINTER (FALSE)); +} + + + +static void +sp_text_edit_dialog_close (GtkButton *button, GtkWidget *dlg) +{ + gtk_widget_destroy (GTK_WIDGET (dlg)); +} + +static void +sp_text_edit_dialog_read_selection ( GtkWidget *dlg, + gboolean dostyle, + gboolean docontent ) +{ + if (g_object_get_data (G_OBJECT (dlg), "blocked")) + return; + + g_object_set_data (G_OBJECT (dlg), "blocked", GINT_TO_POINTER (TRUE)); + + GtkWidget *notebook = (GtkWidget*)g_object_get_data (G_OBJECT (dlg), "notebook"); + GtkWidget *textw = (GtkWidget*)g_object_get_data (G_OBJECT (dlg), "textw"); + GtkWidget *fontsel = (GtkWidget*)g_object_get_data (G_OBJECT (dlg), "fontsel"); + GtkWidget *preview = (GtkWidget*)g_object_get_data (G_OBJECT (dlg), "preview"); + GtkWidget *apply = (GtkWidget*)g_object_get_data (G_OBJECT (dlg), "apply"); + GtkWidget *def = (GtkWidget*)g_object_get_data (G_OBJECT (dlg), "default"); + + GtkTextBuffer *tb = (GtkTextBuffer*)g_object_get_data (G_OBJECT (dlg), "text"); + + SPItem *text = sp_ted_get_selected_text_item (); + + Inkscape::XML::Node *repr; + if (text) + { + guint items = sp_ted_get_selected_text_count (); + if (items == 1) { + gtk_widget_set_sensitive (textw, TRUE); + } else { + gtk_widget_set_sensitive (textw, FALSE); + } + gtk_widget_set_sensitive (apply, FALSE); + gtk_widget_set_sensitive (def, TRUE); + + if (docontent) { + gchar *str; + str = sp_te_get_string_multiline (text); + + if (str) { + int pos; + pos = 0; + + if (items == 1) { + gtk_text_buffer_set_text (tb, str, strlen (str)); + gtk_text_buffer_set_modified (tb, FALSE); + } + sp_font_preview_set_phrase (SP_FONT_PREVIEW (preview), str); + g_free (str); + + } else { + gtk_text_buffer_set_text (tb, "", 0); + sp_font_preview_set_phrase (SP_FONT_PREVIEW (preview), NULL); + } + } // end of if (docontent) + repr = SP_OBJECT_REPR (text); + + } else { + gtk_widget_set_sensitive (textw, FALSE); + gtk_widget_set_sensitive (apply, FALSE); + gtk_widget_set_sensitive (def, FALSE); + } + + if (dostyle) { + + // create temporary style + SPStyle *query = sp_style_new (); + // query style from desktop into it. This returns a result flag and fills query with the style of subselection, if any, or selection + int result_family = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTFAMILY); + int result_style = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTSTYLE); + int result_numbers = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTNUMBERS); + + // If querying returned nothing, read the style from the text tool prefs (default style for new texts) + if (result_family == QUERY_STYLE_NOTHING || result_style == QUERY_STYLE_NOTHING || result_numbers == QUERY_STYLE_NOTHING) { + repr = inkscape_get_repr (INKSCAPE, "tools.text"); + if (repr) { + gtk_widget_set_sensitive (notebook, TRUE); + sp_style_read_from_repr (query, repr); + } else { + gtk_widget_set_sensitive (notebook, FALSE); + } + } + + // FIXME: process result_family/style == QUERY_STYLE_MULTIPLE_DIFFERENT by showing "Many" in the lists + font_instance *font = (font_factory::Default())->Face ( query->text->font_family.value, font_style_to_pos(*query) ); + if (font) { + // the font is oversized, so we need to pass the true size separately + sp_font_selector_set_font (SP_FONT_SELECTOR (fontsel), font, query->font_size.computed); + sp_font_preview_set_font (SP_FONT_PREVIEW (preview), font, SP_FONT_SELECTOR(fontsel)); + font->Unref(); + font=NULL; + } + + GtkWidget *b; + if (query->text_anchor.computed == SP_CSS_TEXT_ANCHOR_START) { + b = (GtkWidget*)g_object_get_data ( G_OBJECT (dlg), "text_anchor_start" ); + } else if (query->text_anchor.computed == SP_CSS_TEXT_ANCHOR_MIDDLE) { + b = (GtkWidget*)g_object_get_data ( G_OBJECT (dlg), "text_anchor_middle" ); + } else { + b = (GtkWidget*)g_object_get_data ( G_OBJECT (dlg), "text_anchor_end" ); + } + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b), TRUE); + + if (query->writing_mode.computed == SP_CSS_WRITING_MODE_LR_TB) { + b = (GtkWidget*)g_object_get_data ( G_OBJECT (dlg), INKSCAPE_STOCK_WRITING_MODE_LR ); + } else { + b = (GtkWidget*)g_object_get_data ( G_OBJECT (dlg), INKSCAPE_STOCK_WRITING_MODE_TB ); + } + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b), TRUE); + + GtkWidget *combo = (GtkWidget*)g_object_get_data ( G_OBJECT (dlg), "line_spacing" ); + double height; + if (query->line_height.normal) height = Inkscape::Text::Layout::LINE_HEIGHT_NORMAL; + else if (query->line_height.unit == SP_CSS_UNIT_PERCENT) + height = query->line_height.value; + else height = query->line_height.computed; + gchar *sstr = g_strdup_printf ("%d%%", (int) floor(height * 100 + 0.5)); + gtk_entry_set_text ((GtkEntry *) ((GtkCombo *) (combo))->entry, sstr); + g_free(sstr); + + g_free (query); + } + + g_object_set_data (G_OBJECT (dlg), "blocked", NULL); +} + + +static void +sp_text_edit_dialog_text_changed (GtkTextBuffer *tb, GtkWidget *dlg) +{ + GtkWidget *textw, *preview, *apply, *def; + GtkTextIter start, end; + gchar *str; + + if (g_object_get_data (G_OBJECT (dlg), "blocked")) + return; + + SPItem *text = sp_ted_get_selected_text_item (); + + textw = (GtkWidget*)g_object_get_data (G_OBJECT (dlg), "textw"); + preview = (GtkWidget*)g_object_get_data (G_OBJECT (dlg), "preview"); + apply = (GtkWidget*)g_object_get_data (G_OBJECT (dlg), "apply"); + def = (GtkWidget*)g_object_get_data (G_OBJECT (dlg), "default"); + + gtk_text_buffer_get_bounds (tb, &start, &end); + str = gtk_text_buffer_get_text (tb, &start, &end, TRUE); + + if (str && *str) { + sp_font_preview_set_phrase (SP_FONT_PREVIEW (preview), str); + } else { + sp_font_preview_set_phrase (SP_FONT_PREVIEW (preview), NULL); + } + g_free (str); + + if (text) { + gtk_widget_set_sensitive (apply, TRUE); + } + gtk_widget_set_sensitive (def, TRUE); + +} // end of sp_text_edit_dialog_text_changed() + + + +static void +sp_text_edit_dialog_font_changed ( SPFontSelector *fsel, + font_instance *font, + GtkWidget *dlg ) +{ + GtkWidget *preview, *apply, *def; + + if (g_object_get_data (G_OBJECT (dlg), "blocked")) + return; + + SPItem *text = sp_ted_get_selected_text_item (); + + preview = (GtkWidget*)g_object_get_data (G_OBJECT (dlg), "preview"); + apply = (GtkWidget*)g_object_get_data (G_OBJECT (dlg), "apply"); + def = (GtkWidget*)g_object_get_data (G_OBJECT (dlg), "default"); + + sp_font_preview_set_font (SP_FONT_PREVIEW (preview), font, SP_FONT_SELECTOR(fsel)); + + if (text) { + gtk_widget_set_sensitive (apply, TRUE); + } + gtk_widget_set_sensitive (def, TRUE); + +} // end of sp_text_edit_dialog_font_changed() + + + +static void +sp_text_edit_dialog_any_toggled (GtkToggleButton *tb, GtkWidget *dlg) +{ + GtkWidget *apply, *def; + + if (g_object_get_data (G_OBJECT (dlg), "blocked")) + return; + + SPItem *text = sp_ted_get_selected_text_item (); + + apply = (GtkWidget*)g_object_get_data (G_OBJECT (dlg), "apply"); + def = (GtkWidget*)g_object_get_data (G_OBJECT (dlg), "default"); + + if (text) { + gtk_widget_set_sensitive (apply, TRUE); + } + gtk_widget_set_sensitive (def, TRUE); +} + + + +static void +sp_text_edit_dialog_line_spacing_changed (GtkEditable *editable, GtkWidget *dlg) +{ + GtkWidget *apply, *def; + + if (g_object_get_data ((GObject *) dlg, "blocked")) + return; + + SPItem *text = sp_ted_get_selected_text_item (); + + apply = (GtkWidget*)g_object_get_data (G_OBJECT (dlg), "apply"); + def = (GtkWidget*)g_object_get_data (G_OBJECT (dlg), "default"); + + if (text) { + gtk_widget_set_sensitive (apply, TRUE); + } + gtk_widget_set_sensitive (def, TRUE); +} + + + +static SPItem * +sp_ted_get_selected_text_item (void) +{ + if (!SP_ACTIVE_DESKTOP) + return NULL; + + for (const GSList *item = SP_DT_SELECTION(SP_ACTIVE_DESKTOP)->itemList(); + item != NULL; + item = item->next) + { + if (SP_IS_TEXT(item->data) || SP_IS_FLOWTEXT(item->data)) + return SP_ITEM (item->data); + } + + return NULL; +} + + + +static unsigned +sp_ted_get_selected_text_count (void) +{ + if (!SP_ACTIVE_DESKTOP) + return 0; + + unsigned int items = 0; + + for (const GSList *item = SP_DT_SELECTION(SP_ACTIVE_DESKTOP)->itemList(); + item != NULL; + item = item->next) + { + if (SP_IS_TEXT(item->data) || SP_IS_FLOWTEXT(item->data)) + ++items; + } + + return items; +} + +/* + 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:textwidth=99 : diff --git a/src/dialogs/text-edit.h b/src/dialogs/text-edit.h new file mode 100644 index 000000000..9350de219 --- /dev/null +++ b/src/dialogs/text-edit.h @@ -0,0 +1,24 @@ +#ifndef SP_TEXT_EDIT_H +#define SP_TEXT_EDIT_H + +/** + * \brief text-edit + * + * Text editing and font changes + * + */ + +void sp_text_edit_dialog (void); + +#endif + +/* + 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:textwidth=99 : diff --git a/src/dialogs/tiledialog.cpp b/src/dialogs/tiledialog.cpp new file mode 100644 index 000000000..12c94ed81 --- /dev/null +++ b/src/dialogs/tiledialog.cpp @@ -0,0 +1,872 @@ +/* + * A simple dialog for creating grid type arrangements of selected objects + * + * Authors: + * Bob Jamison ( based off trace dialog) + * John Cliff + * Other dudes from The Inkscape Organization + * + * Copyright (C) 2004 Bob Jamison + * Copyright (C) 2004 John Cliff + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ +//#define DEBUG_GRID_ARRANGE 1 + +#ifdef HAVE_CONFIG_H +# include +#endif + + +#include //for GTK_RESPONSE* types +#include +#include +#include + +#include "libnr/nr-matrix-ops.h" +#include "verbs.h" +#include "prefs-utils.h" +#include "inkscape.h" +#include "desktop-handles.h" +#include "selection.h" +#include "document.h" +#include "sp-item.h" +#include "widgets/icon.h" +#include "tiledialog.h" + + + +/* + * Sort items by their x co-ordinates, taking account of y (keeps rows intact) + * + * <0 *elem1 goes before *elem2 + * 0 *elem1 == *elem2 + * >0 *elem1 goes after *elem2 + */ +int +sp_compare_x_position(SPItem *first, SPItem *second) +{ + using NR::X; + using NR::Y; + + NR::Rect const a = first->invokeBbox(sp_item_i2doc_affine(first)); + double const a_height = a.dimensions()[Y]; + + NR::Rect const b = second->invokeBbox(sp_item_i2doc_affine(second)); + double const b_height = b.dimensions()[Y]; + + bool a_in_b_vert = false; + if ((a.min()[Y] < b.min()[Y] + 0.1) && (a.min()[Y] > b.min()[Y] - b_height)) { + a_in_b_vert = true; + } else if ((b.min()[Y] < a.min()[Y] + 0.1) && (b.min()[Y] > a.min()[Y] - a_height)) { + a_in_b_vert = true; + } else if (b.min()[Y] == a.min()[Y]) { + a_in_b_vert = true; + } else { + a_in_b_vert = false; + } + + if (!a_in_b_vert) { + return -1; + } + if (a_in_b_vert && a.min()[X] > b.min()[X]) { + return 1; + } + if (a_in_b_vert && a.min()[X] < b.min()[X]) { + return -1; + } + return 0; +} + +/* + * Sort items by their y co-ordinates. + */ +int +sp_compare_y_position(SPItem *first, SPItem *second) +{ + NR::Rect const a = first->invokeBbox(sp_item_i2doc_affine(first)); + NR::Rect const b = second->invokeBbox(sp_item_i2doc_affine(second)); + + if (a.min()[NR::Y] > b.min()[NR::Y]) { + return 1; + } + if (a.min()[NR::Y] < b.min()[NR::Y]) { + return -1; + } + + return 0; +} + +namespace Inkscape { +namespace UI { +namespace Dialog { + + +//######################################################################### +//## E V E N T S +//######################################################################### + +/* + * + * This arranges the selection in a grid pattern. + * + */ + +void TileDialog::Grid_Arrange () +{ + + int cnt,row_cnt,col_cnt,a,row,col; + double grid_left,grid_top,col_width,row_height,paddingx,paddingy,width, height, new_x, new_y,cx,cy; + double total_col_width,total_row_height; + col_width = 0; + row_height = 0; + total_col_width=0; + total_row_height=0; + + + // set padding to manual values + paddingx = XPadSpinner.get_value(); + paddingy = YPadSpinner.get_value(); + + std::vector row_heights; + std::vector col_widths; + std::vector row_ys; + std::vector col_xs; + + int NoOfCols = NoOfColsSpinner.get_value_as_int(); + int NoOfRows = NoOfRowsSpinner.get_value_as_int(); + + width = 0; + for (a=0;aitemList(); + cnt=0; + for (; items != NULL; items = items->next) { + SPItem *item = SP_ITEM(items->data); + NR::Rect const b = item->invokeBbox(sp_item_i2doc_affine(item)); + width = b.dimensions()[NR::X]; + height = b.dimensions()[NR::Y]; + cx = b.midpoint()[NR::X]; + cy = b.midpoint()[NR::Y]; + + if (b.min()[NR::X] < grid_left) { + grid_left = b.min()[NR::X]; + } + if (b.min()[NR::Y] < grid_top) { + grid_top = b.min()[NR::Y]; + } + if (width > col_width) { + col_width = width; + } + if (height > row_height) { + row_height = height; + } + } + + + // require the sorting done before we can calculate row heights etc. + + const GSList *items2 = selection->itemList(); + GSList *rev = g_slist_copy((GSList *) items2); + GSList *sorted = NULL; + rev = g_slist_sort(rev, (GCompareFunc) sp_compare_y_position); + sorted = g_slist_sort(rev, (GCompareFunc) sp_compare_x_position); + + + // Calculate individual Row and Column sizes if necessary + + + cnt=0; + const GSList *sizes = sorted; + for (; sizes != NULL; sizes = sizes->next) { + SPItem *item = SP_ITEM(sizes->data); + NR::Rect const b = item->invokeBbox(sp_item_i2doc_affine(item)); + width = b.dimensions()[NR::X]; + height = b.dimensions()[NR::Y]; + if (width > col_widths[(cnt % NoOfCols)]) { + col_widths[(cnt % NoOfCols)] = width; + } + if (height > row_heights[(cnt / NoOfCols)]) { + row_heights[(cnt / NoOfCols)] = height; + } + cnt++; + } + + + /// Make sure the top and left of the grid dont move by compensating for align values. + if (RowHeightButton.get_active()){ + grid_top = grid_top - (((row_height - row_heights[0]) / 2)*(VertAlign)); + } + if (ColumnWidthButton.get_active()){ + grid_left = grid_left - (((col_width - col_widths[0]) /2)*(HorizAlign)); + } + + #ifdef DEBUG_GRID_ARRANGE + g_print("\n cx = %f cy= %f gridleft=%f",cx,cy,grid_left); + #endif + + // Calculate total widths and heights, allowing for columns and rows non uniformly sized. + + if (ColumnWidthButton.get_active()){ + total_col_width = col_width * NoOfCols; + col_widths.clear(); + for (a=0;abounds(); +#ifdef DEBUG_GRID_ARRANGE +g_print("\n row = %f col = %f selection x= %f selection y = %f", total_row_height,total_col_width, b.extent(NR::X), b.extent(NR::Y)); +#endif + paddingx = (b.extent(NR::X) - total_col_width) / (NoOfCols -1); + paddingy = (b.extent(NR::Y) - total_row_height) / (NoOfRows -1); + } + +/* + Horizontal align - Left = 0 + Centre = 1 + Right = 2 + + Vertical align - Top = 0 + Middle = 1 + Bottom = 2 + + X position is calculated by taking the grids left co-ord, adding the distance to the column, + then adding 1/2 the spacing multiplied by the align variable above, + Y position likewise, takes the top of the grid, adds the y to the current row then adds the padding in to align it. + +*/ + + // Calculate row and column x and y coords required to allow for columns and rows which are non uniformly sized. + + for (a=0;adata); + sorted = sorted->next; + } + + for (; current_row != NULL; current_row = current_row->next) { + SPItem *item=SP_ITEM(current_row->data); + Inkscape::XML::Node *repr = SP_OBJECT_REPR(item); + NR::Rect const b = item->invokeBbox(sp_item_i2doc_affine(item)); + width = b.dimensions()[NR::X]; + height = b.dimensions()[NR::Y]; + row = cnt / NoOfCols; + col = cnt % NoOfCols; + + // original before I started fecking about with it. + // new_x = grid_left + (((col_width - width)/2)*HorizAlign) + (( col_width + paddingx ) * (cnt % NoOfCols)); + // new_y = grid_top + (((row_height - height)/2)*VertAlign) +(( row_height + paddingy ) * (cnt / NoOfCols)); + + new_x = grid_left + (((col_widths[col] - width)/2)*HorizAlign) + col_xs[col]; + new_y = grid_top + (((row_heights[row] - height)/2)*VertAlign) + row_ys[row]; + + NR::Point move = NR::Point(new_x - b.min()[NR::X], b.min()[NR::Y] - new_y); // why are the two args the opposite ways round??? + NR::Matrix const &affine = NR::Matrix(NR::translate(move)); + sp_item_set_i2d_affine(item, sp_item_i2d_affine(item) * affine); + sp_item_write_transform(item, repr, item->transform, NULL); + SP_OBJECT (current_row->data)->updateRepr(repr, SP_OBJECT_WRITE_EXT); + cnt +=1; + } + g_slist_free (current_row); + } + + NRRect b; + selection->bounds(&b); + + sp_document_done (SP_DT_DOCUMENT (desktop)); + +} + + +//######################################################################### +//## E V E N T S +//######################################################################### + + +void TileDialog::_apply() +{ + Grid_Arrange(); +} + + +/** + * changed value in # of columns spinbox. + */ +void TileDialog::on_row_spinbutton_changed() +{ + // quit if run by the attr_changed listener + if (updating) { + return; + } + + // in turn, prevent listener from responding + updating = true; + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + + Inkscape::Selection *selection = SP_DT_SELECTION (desktop); + + GSList const *items = selection->itemList(); + int selcount = g_slist_length((GSList *)items); + + double PerCol = ceil(selcount / NoOfColsSpinner.get_value()); + NoOfRowsSpinner.set_value(PerCol); + prefs_set_double_attribute ("dialogs.gridtiler", "NoOfCols", NoOfColsSpinner.get_value()); + updating=false; +} + +/** + * changed value in # of rows spinbox. + */ +void TileDialog::on_col_spinbutton_changed() +{ + // quit if run by the attr_changed listener + if (updating) { + return; + } + + // in turn, prevent listener from responding + updating = true; + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + Inkscape::Selection *selection = SP_DT_SELECTION (desktop); + + GSList const *items = selection->itemList(); + int selcount = g_slist_length((GSList *)items); + + double PerRow = ceil(selcount / NoOfRowsSpinner.get_value()); + NoOfColsSpinner.set_value(PerRow); + prefs_set_double_attribute ("dialogs.gridtiler", "NoOfCols", PerRow); + + updating=false; +} + +/** + * changed value in x padding spinbox. + */ +void TileDialog::on_xpad_spinbutton_changed() +{ + + prefs_set_double_attribute ("dialogs.gridtiler", "XPad", XPadSpinner.get_value()); + +} + +/** + * changed value in y padding spinbox. + */ +void TileDialog::on_ypad_spinbutton_changed() +{ + + prefs_set_double_attribute ("dialogs.gridtiler", "YPad", YPadSpinner.get_value()); + +} + + +/** + * checked/unchecked autosize Rows button. + */ +void TileDialog::on_RowSize_checkbutton_changed() +{ + + if (RowHeightButton.get_active()) { + prefs_set_double_attribute ("dialogs.gridtiler", "AutoRowSize", 20); + } else { + prefs_set_double_attribute ("dialogs.gridtiler", "AutoRowSize", -20); + } + RowHeightBox.set_sensitive ( !RowHeightButton.get_active()); +} + +/** + * checked/unchecked autosize Rows button. + */ +void TileDialog::on_ColSize_checkbutton_changed() +{ + + if (ColumnWidthButton.get_active()) { + prefs_set_double_attribute ("dialogs.gridtiler", "AutoColSize", 20); + } else { + prefs_set_double_attribute ("dialogs.gridtiler", "AutoColSize", -20); + } + ColumnWidthBox.set_sensitive ( !ColumnWidthButton.get_active()); + +} + +/** + * changed value in columns spinbox. + */ +void TileDialog::on_rowSize_spinbutton_changed() +{ + // quit if run by the attr_changed listener + if (updating) { + return; + } + + // in turn, prevent listener from responding + updating = true; + prefs_set_double_attribute ("dialogs.gridtiler", "RowHeight", RowHeightSpinner.get_value()); + updating=false; + +} + +/** + * changed value in rows spinbox. + */ +void TileDialog::on_colSize_spinbutton_changed() +{ + // quit if run by the attr_changed listener + if (updating) { + return; + } + + // in turn, prevent listener from responding + updating = true; + prefs_set_double_attribute ("dialogs.gridtiler", "ColWidth", ColumnWidthSpinner.get_value()); + updating=false; + +} + +/** + * changed Radio button in Spacing group. + */ +void TileDialog::Spacing_button_changed() +{ + if (SpaceManualRadioButton.get_active()) { + prefs_set_double_attribute ("dialogs.gridtiler", "SpacingType", 20); + } else { + prefs_set_double_attribute ("dialogs.gridtiler", "SpacingType", -20); + } + + SizesHBox.set_sensitive ( SpaceManualRadioButton.get_active()); +} + +/** + * changed Radio button in Vertical Align group. + */ +void TileDialog::VertAlign_changed() +{ + if (VertTopRadioButton.get_active()) { + VertAlign = 0; + prefs_set_double_attribute ("dialogs.gridtiler", "VertAlign", 0); + } else if (VertCentreRadioButton.get_active()){ + VertAlign = 1; + prefs_set_double_attribute ("dialogs.gridtiler", "VertAlign", 1); + } else if (VertBotRadioButton.get_active()){ + VertAlign = 2; + prefs_set_double_attribute ("dialogs.gridtiler", "VertAlign", 2); + } + +} + +/** + * changed Radio button in Vertical Align group. + */ +void TileDialog::HorizAlign_changed() +{ + if (HorizLeftRadioButton.get_active()) { + HorizAlign = 0; + prefs_set_double_attribute ("dialogs.gridtiler", "HorizAlign", 0); + } else if (HorizCentreRadioButton.get_active()){ + HorizAlign = 1; + prefs_set_double_attribute ("dialogs.gridtiler", "HorizAlign", 1); + } else if (HorizRightRadioButton.get_active()){ + HorizAlign = 2; + prefs_set_double_attribute ("dialogs.gridtiler", "HorizAlign", 2); + } + +} + +/** + * Desktop selection changed + */ +void TileDialog::updateSelection() +{ + double col_width, row_height; + // quit if run by the attr_changed listener + if (updating) { + return; + } + + col_width=0; + row_height=0; + // in turn, prevent listener from responding + updating = true; + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + Inkscape::Selection *selection = SP_DT_SELECTION (desktop); + const GSList *items = selection->itemList(); + int selcount = g_slist_length((GSList *)items); + + if (NoOfColsSpinner.get_value()>1){ + // Update the number of rows assuming number of columns wanted remains same. + double NoOfRows = ceil(selcount / NoOfColsSpinner.get_value()); + NoOfRowsSpinner.set_value(NoOfRows); + + // if the selection has less than the number set for one row, reduce it appropriately + if (selcountupdateSelection(); +} + + +//######################################################################### +//## C O N S T R U C T O R / D E S T R U C T O R +//######################################################################### +/** + * Constructor + */ +TileDialog::TileDialog() + : Dialog ("dialogs.gridtiler", SP_VERB_SELECTION_GRIDTILE) +{ + // bool used by spin button callbacks to stop loops where they change each other. + updating = false; + + // could not do this in gtkmm - there's no Gtk::SizeGroup public constructor (!) + GtkSizeGroup *_col1 = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); + GtkSizeGroup *_col2 = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); + GtkSizeGroup *_col3 = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); + + { + // Selection Change signal + g_signal_connect ( G_OBJECT (INKSCAPE), "change_selection", G_CALLBACK (updateSelectionCallback), this); + } + + Gtk::VBox *mainVBox = get_vbox(); + +#define MARGIN 2 + + //##Set up the panel + + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + + Inkscape::Selection *selection = SP_DT_SELECTION (desktop); + int selcount = 1; + if (!selection->isEmpty()) { + GSList const *items = selection->itemList(); + selcount = g_slist_length((GSList *)items); + } + + + /*#### Number of Rows ####*/ + + double PerRow = selcount; + double PerCol = 1; + + #ifdef DEBUG_GRID_ARRANGE + g_print("/n PerRox = %f PerCol = %f selcount = %d",PerRow,PerCol,selcount); + #endif + + NoOfRowsLabel.set_label(_("Rows:")); + NoOfRowsBox.pack_start(NoOfRowsLabel, false, false, MARGIN); + + NoOfRowsSpinner.set_digits(0); + NoOfRowsSpinner.set_increments(1, 5); + NoOfRowsSpinner.set_range(1.0, 100.0); + NoOfRowsSpinner.set_value(PerCol); + NoOfRowsSpinner.signal_changed().connect(sigc::mem_fun(*this, &TileDialog::on_col_spinbutton_changed)); + tips.set_tip(NoOfRowsSpinner, _("Number of rows")); + NoOfRowsBox.pack_start(NoOfRowsSpinner, false, false, MARGIN); + gtk_size_group_add_widget(_col1, (GtkWidget *) NoOfRowsBox.gobj()); + + RowHeightButton.set_label(_("Equal height")); + double AutoRow = prefs_get_double_attribute ("dialogs.gridtiler", "AutoRowSize", 15); + if (AutoRow>0) + AutoRowSize=true; + else + AutoRowSize=false; + RowHeightButton.set_active(AutoRowSize); + + NoOfRowsBox.pack_start(RowHeightButton, false, false, MARGIN); + + tips.set_tip(RowHeightButton, _("If not set, each row has the height of the tallest object in it")); + RowHeightButton.signal_toggled().connect(sigc::mem_fun(*this, &TileDialog::on_RowSize_checkbutton_changed)); + + { + /*#### Radio buttons to control vertical alignment ####*/ + + VertAlignLabel.set_label(_("Align:")); + VertAlignHBox.pack_start(VertAlignLabel, false, false, MARGIN); + + VertTopRadioButton.signal_toggled().connect(sigc::mem_fun(*this, &TileDialog::VertAlign_changed)); + VertAlignGroup = VertTopRadioButton.get_group(); + VertAlignVBox.pack_start(VertTopRadioButton, false, false, 0); + + VertCentreRadioButton.set_group(VertAlignGroup); + VertCentreRadioButton.signal_toggled().connect(sigc::mem_fun(*this, &TileDialog::VertAlign_changed)); + VertAlignVBox.pack_start(VertCentreRadioButton, false, false, 0); + + VertBotRadioButton.set_group(VertAlignGroup); + VertBotRadioButton.signal_toggled().connect(sigc::mem_fun(*this, &TileDialog::VertAlign_changed)); + VertAlignVBox.pack_start(VertBotRadioButton, false, false, 0); + + VertAlign = prefs_get_double_attribute ("dialogs.gridtiler", "VertAlign", 1); + if (VertAlign == 0) { + VertTopRadioButton.set_active(TRUE); + } + else if (VertAlign == 1) { + VertCentreRadioButton.set_active(TRUE); + } + else if (VertAlign == 2){ + VertBotRadioButton.set_active(TRUE); + } + VertAlignHBox.pack_start(VertAlignVBox, false, false, MARGIN); + NoOfRowsBox.pack_start(VertAlignHBox, false, false, MARGIN); + } + + SpinsHBox.pack_start(NoOfRowsBox, false, false, MARGIN); + + + /*#### Label for X ####*/ + padXByYLabel.set_label(" "); + XByYLabelVBox.pack_start(padXByYLabel, false, false, MARGIN); + XByYLabel.set_markup(" × "); + XByYLabelVBox.pack_start(XByYLabel, false, false, MARGIN); + SpinsHBox.pack_start(XByYLabelVBox, false, false, MARGIN); + gtk_size_group_add_widget(_col2, (GtkWidget *) XByYLabelVBox.gobj()); + + /*#### Number of columns ####*/ + + NoOfColsLabel.set_label(_("Columns:")); + NoOfColsBox.pack_start(NoOfColsLabel, false, false, MARGIN); + + NoOfColsSpinner.set_digits(0); + NoOfColsSpinner.set_increments(1, 5); + NoOfColsSpinner.set_range(1.0, 100.0); + NoOfColsSpinner.set_value(PerRow); + NoOfColsSpinner.signal_changed().connect(sigc::mem_fun(*this, &TileDialog::on_row_spinbutton_changed)); + tips.set_tip(NoOfColsSpinner, _("Number of columns")); + NoOfColsBox.pack_start(NoOfColsSpinner, false, false, MARGIN); + gtk_size_group_add_widget(_col3, (GtkWidget *) NoOfColsBox.gobj()); + + ColumnWidthButton.set_label(_("Equal width")); + double AutoCol = prefs_get_double_attribute ("dialogs.gridtiler", "AutoColSize", 15); + if (AutoCol>0) + AutoColSize=true; + else + AutoColSize=false; + ColumnWidthButton.set_active(AutoColSize); + NoOfColsBox.pack_start(ColumnWidthButton, false, false, MARGIN); + + tips.set_tip(ColumnWidthButton, _("If not set, each column has the width of the widest object in it")); + ColumnWidthButton.signal_toggled().connect(sigc::mem_fun(*this, &TileDialog::on_ColSize_checkbutton_changed)); + + + { + /*#### Radio buttons to control horizontal alignment ####*/ + + HorizAlignLabel.set_label(_("Align:")); + HorizAlignVBox.pack_start(HorizAlignLabel, false, false, MARGIN); + + HorizAlignHBox.pack_start(*(new Gtk::HBox()), true, true, 0); // centering strut + + HorizLeftRadioButton.signal_toggled().connect(sigc::mem_fun(*this, &TileDialog::HorizAlign_changed)); + HorizAlignGroup = HorizLeftRadioButton.get_group(); + HorizAlignHBox.pack_start(HorizLeftRadioButton, false, false, 0); + + HorizCentreRadioButton.set_group(HorizAlignGroup); + HorizCentreRadioButton.signal_toggled().connect(sigc::mem_fun(*this, &TileDialog::HorizAlign_changed)); + HorizAlignHBox.pack_start(HorizCentreRadioButton, false, false, 0); + + HorizRightRadioButton.set_group(HorizAlignGroup); + HorizRightRadioButton.signal_toggled().connect(sigc::mem_fun(*this, &TileDialog::HorizAlign_changed)); + HorizAlignHBox.pack_start(HorizRightRadioButton, false, false, 0); + + HorizAlignHBox.pack_start(*(new Gtk::HBox()), true, true, 0); // centering strut + + HorizAlign = prefs_get_double_attribute ("dialogs.gridtiler", "HorizAlign", 1); + if (HorizAlign == 0) { + HorizLeftRadioButton.set_active(TRUE); + } + else if (HorizAlign == 1) { + HorizCentreRadioButton.set_active(TRUE); + } + else if (HorizAlign == 2) { + HorizRightRadioButton.set_active(TRUE); + } + HorizAlignVBox.pack_start(HorizAlignHBox, false, false, MARGIN); + NoOfColsBox.pack_start(HorizAlignVBox, false, false, MARGIN); + } + + SpinsHBox.pack_start(NoOfColsBox, false, false, MARGIN); + + TileBox.pack_start(SpinsHBox, false, false, MARGIN); + + { + /*#### Radio buttons to control spacing manually or to fit selection bbox ####*/ + SpaceByBBoxRadioButton.set_label(_("Fit into selection box")); + SpaceByBBoxRadioButton.signal_toggled().connect(sigc::mem_fun(*this, &TileDialog::Spacing_button_changed)); + SpacingGroup = SpaceByBBoxRadioButton.get_group(); + + SpacingVBox.pack_start(SpaceByBBoxRadioButton, false, false, MARGIN); + + SpaceManualRadioButton.set_label(_("Set spacing:")); + SpaceManualRadioButton.set_group(SpacingGroup); + SpaceManualRadioButton.signal_toggled().connect(sigc::mem_fun(*this, &TileDialog::Spacing_button_changed)); + SpacingVBox.pack_start(SpaceManualRadioButton, false, false, MARGIN); + + TileBox.pack_start(SpacingVBox, false, false, MARGIN); + } + + { + /*#### Y Padding ####*/ + + GtkWidget *i = sp_icon_new (GTK_ICON_SIZE_MENU, "clonetiler_per_row"); + YPadBox.pack_start (*(Glib::wrap(i)), false, false, MARGIN); + + YPadSpinner.set_digits(1); + YPadSpinner.set_increments(0.2, 2); + YPadSpinner.set_range(-10000, 10000); + double YPad = prefs_get_double_attribute ("dialogs.gridtiler", "YPad", 15); + YPadSpinner.set_value(YPad); + YPadBox.pack_start(YPadSpinner, true, true, MARGIN); + tips.set_tip(YPadSpinner, _("Vertical spacing between rows (px units)")); + YPadSpinner.signal_changed().connect(sigc::mem_fun(*this, &TileDialog::on_ypad_spinbutton_changed)); + gtk_size_group_add_widget(_col1, (GtkWidget *) YPadBox.gobj()); + + SizesHBox.pack_start(YPadBox, false, false, MARGIN); + } + + { + Gtk::HBox *spacer = new Gtk::HBox; + SizesHBox.pack_start(*spacer, false, false, 0); + gtk_size_group_add_widget(_col2, (GtkWidget *) spacer->gobj()); + } + + { + /*#### X padding ####*/ + + GtkWidget *i = sp_icon_new (GTK_ICON_SIZE_MENU, "clonetiler_per_column"); + XPadBox.pack_start (*(Glib::wrap(i)), false, false, MARGIN); + + XPadSpinner.set_digits(1); + XPadSpinner.set_increments(0.2, 2); + XPadSpinner.set_range(-10000, 10000); + double XPad = prefs_get_double_attribute ("dialogs.gridtiler", "XPad", 15); + XPadSpinner.set_value(XPad); + XPadBox.pack_start(XPadSpinner, true, true, MARGIN); + tips.set_tip(XPadSpinner, _("Horizontal spacing between columns (px units)")); + XPadSpinner.signal_changed().connect(sigc::mem_fun(*this, &TileDialog::on_xpad_spinbutton_changed)); + gtk_size_group_add_widget(_col3, (GtkWidget *) XPadBox.gobj()); + + SizesHBox.pack_start(XPadBox, false, false, MARGIN); + } + + + TileBox.pack_start(SizesHBox, false, false, MARGIN); + + mainVBox->pack_start(TileBox); + + double SpacingType = prefs_get_double_attribute ("dialogs.gridtiler", "SpacingType", 15); + if (SpacingType>0) { + ManualSpacing=true; + } else { + ManualSpacing=false; + } + SpaceManualRadioButton.set_active(ManualSpacing); + SpaceByBBoxRadioButton.set_active(!ManualSpacing); + SizesHBox.set_sensitive (ManualSpacing); + + //## The OK button + TileOkButton = add_button(Gtk::Stock::APPLY, GTK_RESPONSE_APPLY); + tips.set_tip((*TileOkButton), _("Arrange selected objects")); + + show_all_children(); +} + + + + + + +} //namespace Dialog +} //namespace UI +} //namespace Inkscape + +//######################################################################### +//## E N D O F F I L E +//######################################################################### + + +/* + 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 : + + + diff --git a/src/dialogs/tiledialog.h b/src/dialogs/tiledialog.h new file mode 100644 index 000000000..69a5ea3e2 --- /dev/null +++ b/src/dialogs/tiledialog.h @@ -0,0 +1,190 @@ +#ifndef __TILEDIALOG_H__ +#define __TILEDIALOG_H__ +/* + * A simple dialog for creating grid type arrangements of selected objects + * + * Authors: + * Bob Jamison ( based off trace dialog) + * John Cliff + * Other dudes from The Inkscape Organization + * + * Copyright (C) 2004 Bob Jamison + * Copyright (C) 2004 John Cliff + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + + +#include +#include +#include +#include +#include +#include +#include + +#include "ui/dialog/dialog.h" + +namespace Inkscape { +namespace UI { +namespace Dialog { + + +/** + * A dialog that displays log messages + */ +class TileDialog : public Dialog { + +public: + + /** + * Constructor + */ + TileDialog() ; + + + /** + * Factory method + */ + static TileDialog *create() { return new TileDialog(); } + + /** + * Destructor + */ + virtual ~TileDialog() {}; + + /** + * Do the actual work + */ + void Grid_Arrange(); + + /** + * Respond to selection change + */ + void updateSelection(); + + + /** + * Callback from Apply + */ + virtual void _apply(); + + /** + * Callback from spinbuttons + */ + void on_row_spinbutton_changed(); + void on_col_spinbutton_changed(); + void on_xpad_spinbutton_changed(); + void on_ypad_spinbutton_changed(); + void on_RowSize_checkbutton_changed(); + void on_ColSize_checkbutton_changed(); + void on_rowSize_spinbutton_changed(); + void on_colSize_spinbutton_changed(); + void Spacing_button_changed(); + void VertAlign_changed(); + void HorizAlign_changed(); + + +private: + TileDialog(TileDialog const &d); // no copy + void operator=(TileDialog const &d); // no assign + + bool userHidden; + bool updating; + + + + Gtk::Notebook notebook; + Gtk::Tooltips tips; + + Gtk::VBox TileBox; + Gtk::Button *TileOkButton; + Gtk::Button *TileCancelButton; + + // Number selected label + Gtk::Label SelectionContentsLabel; + + + Gtk::HBox AlignHBox; + Gtk::HBox SpinsHBox; + Gtk::HBox SizesHBox; + + // Number per Row + Gtk::VBox NoOfColsBox; + Gtk::Label NoOfColsLabel; + Gtk::SpinButton NoOfColsSpinner; + bool AutoRowSize; + Gtk::CheckButton RowHeightButton; + + Gtk::VBox XByYLabelVBox; + Gtk::Label padXByYLabel; + Gtk::Label XByYLabel; + + // Number per Column + Gtk::VBox NoOfRowsBox; + Gtk::Label NoOfRowsLabel; + Gtk::SpinButton NoOfRowsSpinner; + bool AutoColSize; + Gtk::CheckButton ColumnWidthButton; + + // Vertical align + Gtk::Label VertAlignLabel; + Gtk::HBox VertAlignHBox; + Gtk::VBox VertAlignVBox; + Gtk::RadioButtonGroup VertAlignGroup; + Gtk::RadioButton VertCentreRadioButton; + Gtk::RadioButton VertTopRadioButton; + Gtk::RadioButton VertBotRadioButton; + double VertAlign; + + // Horizontal align + Gtk::Label HorizAlignLabel; + Gtk::VBox HorizAlignVBox; + Gtk::HBox HorizAlignHBox; + Gtk::RadioButtonGroup HorizAlignGroup; + Gtk::RadioButton HorizCentreRadioButton; + Gtk::RadioButton HorizLeftRadioButton; + Gtk::RadioButton HorizRightRadioButton; + double HorizAlign; + + // padding in x + Gtk::VBox XPadBox; + Gtk::Label XPadLabel; + Gtk::SpinButton XPadSpinner; + + // padding in y + Gtk::VBox YPadBox; + Gtk::Label YPadLabel; + Gtk::SpinButton YPadSpinner; + + // BBox or manual spacing + Gtk::VBox SpacingVBox; + Gtk::RadioButtonGroup SpacingGroup; + Gtk::RadioButton SpaceByBBoxRadioButton; + Gtk::RadioButton SpaceManualRadioButton; + bool ManualSpacing; + + + + // Row height + Gtk::VBox RowHeightVBox; + Gtk::HBox RowHeightBox; + Gtk::Label RowHeightLabel; + Gtk::SpinButton RowHeightSpinner; + + // Column width + Gtk::VBox ColumnWidthVBox; + Gtk::HBox ColumnWidthBox; + Gtk::Label ColumnWidthLabel; + Gtk::SpinButton ColumnWidthSpinner; + +}; + + +} //namespace Dialog +} //namespace UI +} //namespace Inkscape + + +#endif /* __TILEDIALOG_H__ */ + diff --git a/src/dialogs/unclump.cpp b/src/dialogs/unclump.cpp new file mode 100644 index 000000000..64c348be5 --- /dev/null +++ b/src/dialogs/unclump.cpp @@ -0,0 +1,371 @@ +#define __UNCLUMP_C__ + +/* + * Unclumping objects + * + * Authors: + * bulia byak + * + * Copyright (C) 2005 Authors + * Released under GNU GPL + */ + + +#include +#include "libnr/nr-matrix-ops.h" +#include "sp-item.h" + + +// Taking bbox of an item is an expensive operation, and we need to do it many times, so here we +// cache the centers, widths, and heights of items + +//FIXME: make a class with these cashes as members instead of globals +std::map c_cache; +std::map wh_cache; + +/** +Center of bbox of item +*/ +NR::Point +unclump_center (SPItem *item) +{ + std::map::iterator i = c_cache.find(SP_OBJECT_ID(item)); + if ( i != c_cache.end() ) { + return i->second; + } + + NR::Rect const r = item->invokeBbox(sp_item_i2d_affine(item)); + NR::Point const c = r.midpoint(); + c_cache[SP_OBJECT_ID(item)] = c; + return c; +} + +NR::Point +unclump_wh (SPItem *item) +{ + NR::Point wh; + std::map::iterator i = wh_cache.find(SP_OBJECT_ID(item)); + if ( i != wh_cache.end() ) { + wh = i->second; + } else { + NR::Rect const r = item->invokeBbox(sp_item_i2d_affine(item)); + wh = r.dimensions(); + wh_cache[SP_OBJECT_ID(item)] = wh; + } + + return wh; +} + +/** +Distance between "edges" of item1 and item2. An item is considered to be an ellipse inscribed into its w/h, +so its radius (distance from center to edge) depends on the w/h and the angle towards the other item. +May be negative if the edge of item1 is between the center and the edge of item2. +*/ +double +unclump_dist (SPItem *item1, SPItem *item2) +{ + NR::Point c1 = unclump_center (item1); + NR::Point c2 = unclump_center (item2); + + NR::Point wh1 = unclump_wh (item1); + NR::Point wh2 = unclump_wh (item2); + + // angle from each item's center to the other's, unsqueezed by its w/h, normalized to 0..pi/2 + double a1 = atan2 ((c2 - c1)[NR::Y], (c2 - c1)[NR::X] * wh1[NR::Y]/wh1[NR::X]); + a1 = fabs (a1); + if (a1 > M_PI/2) a1 = M_PI - a1; + + double a2 = atan2 ((c1 - c2)[NR::Y], (c1 - c2)[NR::X] * wh2[NR::Y]/wh2[NR::X]); + a2 = fabs (a2); + if (a2 > M_PI/2) a2 = M_PI - a2; + + // get the radius of each item for the given angle + double r1 = 0.5 * (wh1[NR::X] + (wh1[NR::Y] - wh1[NR::X]) * (a1/(M_PI/2))); + double r2 = 0.5 * (wh2[NR::X] + (wh2[NR::Y] - wh2[NR::X]) * (a2/(M_PI/2))); + + // dist between centers minus angle-adjusted radii + double dist_r = (NR::L2 (c2 - c1) - r1 - r2); + + double stretch1 = wh1[NR::Y]/wh1[NR::X]; + double stretch2 = wh2[NR::Y]/wh2[NR::X]; + + if ((stretch1 > 1.5 || stretch1 < 0.66) && (stretch2 > 1.5 || stretch2 < 0.66)) { + + std::vector dists; + dists.push_back (dist_r); + + // If both objects are not circle-like, find dists between four corners + std::vector c1_points(2); + { + double y_closest; + if (c2[NR::Y] > c1[NR::Y] + wh1[NR::Y]/2) { + y_closest = c1[NR::Y] + wh1[NR::Y]/2; + } else if (c2[NR::Y] < c1[NR::Y] - wh1[NR::Y]/2) { + y_closest = c1[NR::Y] - wh1[NR::Y]/2; + } else { + y_closest = c2[NR::Y]; + } + c1_points[0] = NR::Point (c1[NR::X], y_closest); + double x_closest; + if (c2[NR::X] > c1[NR::X] + wh1[NR::X]/2) { + x_closest = c1[NR::X] + wh1[NR::X]/2; + } else if (c2[NR::X] < c1[NR::X] - wh1[NR::X]/2) { + x_closest = c1[NR::X] - wh1[NR::X]/2; + } else { + x_closest = c2[NR::X]; + } + c1_points[1] = NR::Point (x_closest, c1[NR::Y]); + } + + + std::vector c2_points(2); + { + double y_closest; + if (c1[NR::Y] > c2[NR::Y] + wh2[NR::Y]/2) { + y_closest = c2[NR::Y] + wh2[NR::Y]/2; + } else if (c1[NR::Y] < c2[NR::Y] - wh2[NR::Y]/2) { + y_closest = c2[NR::Y] - wh2[NR::Y]/2; + } else { + y_closest = c1[NR::Y]; + } + c2_points[0] = NR::Point (c2[NR::X], y_closest); + double x_closest; + if (c1[NR::X] > c2[NR::X] + wh2[NR::X]/2) { + x_closest = c2[NR::X] + wh2[NR::X]/2; + } else if (c1[NR::X] < c2[NR::X] - wh2[NR::X]/2) { + x_closest = c2[NR::X] - wh2[NR::X]/2; + } else { + x_closest = c1[NR::X]; + } + c2_points[1] = NR::Point (x_closest, c2[NR::Y]); + } + + for (int i = 0; i < 2; i ++) { + for (int j = 0; j < 2; j ++) { + dists.push_back (NR::L2 (c1_points[i] - c2_points[j])); + } + } + + // return the minimum of all dists + return *std::min_element(dists.begin(), dists.end()); + } else { + return dist_r; + } +} + +/** +Average unclump_dist from item to others +*/ +double unclump_average (SPItem *item, GSList *others) +{ + int n = 0; + double sum = 0; + + for (GSList *i = others; i != NULL; i = i->next) { + SPItem *other = SP_ITEM (i->data); + + if (other == item) + continue; + + n++; + sum += unclump_dist (item, other); + } + + if (n != 0) + return sum/n; + else + return 0; +} + +/** +Closest to item among others + */ +SPItem *unclump_closest (SPItem *item, GSList *others) +{ + double min = HUGE_VAL; + SPItem *closest = NULL; + + for (GSList *i = others; i != NULL; i = i->next) { + SPItem *other = SP_ITEM (i->data); + + if (other == item) + continue; + + double dist = unclump_dist (item, other); + if (dist < min && fabs (dist) < 1e6) { + min = dist; + closest = other; + } + } + + return closest; +} + +/** +Most distant from item among others + */ +SPItem *unclump_farest (SPItem *item, GSList *others) +{ + double max = -HUGE_VAL; + SPItem *farest = NULL; + + for (GSList *i = others; i != NULL; i = i->next) { + SPItem *other = SP_ITEM (i->data); + + if (other == item) + continue; + + double dist = unclump_dist (item, other); + if (dist > max && fabs (dist) < 1e6) { + max = dist; + farest = other; + } + } + + return farest; +} + +/** +Removes from the \a rest list those items that are "behind" \a closest as seen from \a item, +i.e. those on the other side of the line through \a closest perpendicular to the direction from \a +item to \a closest. Returns a newly created list which must be freed. + */ +GSList * +unclump_remove_behind (SPItem *item, SPItem *closest, GSList *rest) +{ + NR::Point it = unclump_center (item); + NR::Point p1 = unclump_center (closest); + + // perpendicular through closest to the direction to item: + NR::Point perp = NR::rot90(it - p1); + NR::Point p2 = p1 + perp; + + // get the standard Ax + By + C = 0 form for p1-p2: + double A = p1[NR::Y] - p2[NR::Y]; + double B = p2[NR::X] - p1[NR::X]; + double C = p2[NR::Y] * p1[NR::X] - p1[NR::Y] * p2[NR::X]; + + // substitute the item into it: + double val_item = A * it[NR::X] + B * it[NR::Y] + C; + + GSList *out = NULL; + + for (GSList *i = rest; i != NULL; i = i->next) { + SPItem *other = SP_ITEM (i->data); + + if (other == item) + continue; + + NR::Point o = unclump_center (other); + double val_other = A * o[NR::X] + B * o[NR::Y] + C; + + if (val_item * val_other <= 1e-6) { + // different signs, which means item and other are on the different sides of p1-p2 line; skip + } else { + out = g_slist_prepend (out, other); + } + } + + return out; +} + +/** +Moves \a what away from \a from by \a dist + */ +void +unclump_push (SPItem *from, SPItem *what, double dist) +{ + NR::Point it = unclump_center (what); + NR::Point p = unclump_center (from); + NR::Point by = dist * NR::unit_vector (- (p - it)); + + NR::Matrix move = NR::Matrix (NR::translate (by)); + + std::map::iterator i = c_cache.find(SP_OBJECT_ID(what)); + if ( i != c_cache.end() ) { + i->second *= move; + } + + //g_print ("push %s at %g,%g from %g,%g by %g,%g, dist %g\n", SP_OBJECT_ID(what), it[NR::X],it[NR::Y], p[NR::X],p[NR::Y], by[NR::X],by[NR::Y], dist); + + sp_item_set_i2d_affine(what, sp_item_i2d_affine(what) * move); + sp_item_write_transform(what, SP_OBJECT_REPR(what), what->transform, NULL); +} + +/** +Moves \a what towards \a to by \a dist + */ +void +unclump_pull (SPItem *to, SPItem *what, double dist) +{ + NR::Point it = unclump_center (what); + NR::Point p = unclump_center (to); + NR::Point by = dist * NR::unit_vector (p - it); + + NR::Matrix move = NR::Matrix (NR::translate (by)); + + std::map::iterator i = c_cache.find(SP_OBJECT_ID(what)); + if ( i != c_cache.end() ) { + i->second *= move; + } + + //g_print ("pull %s at %g,%g to %g,%g by %g,%g, dist %g\n", SP_OBJECT_ID(what), it[NR::X],it[NR::Y], p[NR::X],p[NR::Y], by[NR::X],by[NR::Y], dist); + + sp_item_set_i2d_affine(what, sp_item_i2d_affine(what) * move); + sp_item_write_transform(what, SP_OBJECT_REPR(what), what->transform, NULL); +} + + +/** +Unclumps the items in \a items, reducing local unevenness in their distribution. Produces an effect +similar to "engraver dots". The only distribution which is unchanged by unclumping is a hexagonal +grid. May be called repeatedly for stronger effect. + */ +void +unclump (GSList *items) +{ + c_cache.clear(); + wh_cache.clear(); + + for (GSList *i = items; i != NULL; i = i->next) { // for each original/clone x: + SPItem *item = SP_ITEM (i->data); + + GSList *nei = NULL; + + GSList *rest = g_slist_copy (items); + rest = g_slist_remove (rest, item); + + while (rest != NULL) { + SPItem *closest = unclump_closest (item, rest); + if (closest) { + nei = g_slist_prepend (nei, closest); + rest = g_slist_remove (rest, closest); + GSList *new_rest = unclump_remove_behind (item, closest, rest); + g_slist_free (rest); + rest = new_rest; + } else { + g_slist_free (rest); + break; + } + } + + if (g_slist_length (nei) >= 2) { + double ave = unclump_average (item, nei); + + SPItem *closest = unclump_closest (item, nei); + SPItem *farest = unclump_farest (item, nei); + + double dist_closest = unclump_dist (closest, item); + double dist_farest = unclump_dist (farest, item); + + //g_print ("NEI %d for item %s closest %s at %g farest %s at %g ave %g\n", g_slist_length(nei), SP_OBJECT_ID(item), SP_OBJECT_ID(closest), dist_closest, SP_OBJECT_ID(farest), dist_farest, ave); + + if (fabs (ave) < 1e6 && fabs (dist_closest) < 1e6 && fabs (dist_farest) < 1e6) { // otherwise the items are bogus + // increase these coefficients to make unclumping more aggressive and less stable + // the pull coefficient is a bit bigger to counteract the long-term expansion trend + unclump_push (closest, item, 0.3 * (ave - dist_closest)); + unclump_pull (farest, item, 0.35 * (dist_farest - ave)); + } + } + } +} diff --git a/src/dialogs/unclump.h b/src/dialogs/unclump.h new file mode 100644 index 000000000..6cebc0caf --- /dev/null +++ b/src/dialogs/unclump.h @@ -0,0 +1,20 @@ +#ifndef UNCLUMP_H_SEEN +#define UNCLUMP_H_SEEN + +/** \file + * Unclumping objects + */ +/* + * Authors: + * bulia byak + * + * Copyright (C) 2005 Authors + * Released under GNU GPL + */ + +#include + +void unclump(GSList *items); + + +#endif /* !UNCLUMP_H_SEEN */ diff --git a/src/dialogs/xml-tree.cpp b/src/dialogs/xml-tree.cpp new file mode 100644 index 000000000..079a09b5a --- /dev/null +++ b/src/dialogs/xml-tree.cpp @@ -0,0 +1,1575 @@ +#define __SP_XMLVIEW_TREE_C__ + +/** + * \brief XML View + * + * Authors: + * Lauris Kaplinski + * MenTaLguY + * bulia byak + * + * Copyright (C) 1999-2005 Authors + * Copyright (C) 2004 David Turner + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "helper/window.h" +#include "macros.h" +#include "../inkscape.h" +#include "../document.h" +#include "../desktop-handles.h" +#include "desktop.h" +#include "../selection.h" +#include "../sp-string.h" +#include "../sp-tspan.h" +#include "../sp-root.h" +#include "../event-context.h" +#include "in-dt-coordsys.h" + + +#include "../widgets/sp-xmlview-tree.h" +#include "../widgets/sp-xmlview-content.h" +#include "../widgets/sp-xmlview-attr-list.h" + +#include "../inkscape-stock.h" +#include "widgets/icon.h" + +#include "dialog-events.h" +#include "../prefs-utils.h" +#include "../verbs.h" +#include "../interface.h" + +#include "shortcuts.h" +#include + +#include "message-stack.h" +#include "message-context.h" + +struct EditableDest { + GtkEditable *editable; + gchar *text; +}; + +static GtkWidget *dlg = NULL; +static sigc::connection sel_changed_connection; +static sigc::connection document_uri_set_connection; +static sigc::connection document_replaced_connection; +static win_data wd; +// impossible original values to make sure they are read from prefs +static gint x = -1000, y = -1000, w = 0, h = 0; +static gchar *prefs_path = "dialogs.xml"; +static GtkWidget *status = NULL; +static Inkscape::MessageStack *_message_stack = NULL; +static Inkscape::MessageContext *_message_context = NULL; +static sigc::connection _message_changed_connection; + +static GtkTooltips *tooltips = NULL; +static GtkEditable *attr_name = NULL; +static GtkTextView *attr_value = NULL; +static SPXMLViewTree *tree = NULL; +static SPXMLViewAttrList *attributes = NULL; +static SPXMLViewContent *content = NULL; + +static gint blocked = 0; +static SPDesktop *current_desktop = NULL; +static SPDocument *current_document = NULL; +static gint selected_attr = 0; +static Inkscape::XML::Node *selected_repr = NULL; + +static void sp_xmltree_desktop_change( Inkscape::Application *inkscape, SPDesktop *desktop, GtkWidget *dialog ); + +static void set_tree_desktop(SPDesktop *desktop); +static void set_tree_document(SPDocument *document); +static void set_tree_repr(Inkscape::XML::Node *repr); + +static void set_tree_select(Inkscape::XML::Node *repr); +static void propagate_tree_select(Inkscape::XML::Node *repr); + +static Inkscape::XML::Node *get_dt_select(); +static void set_dt_select(Inkscape::XML::Node *repr); + +static void on_tree_select_row(GtkCTree *tree, GtkCTreeNode *node, gint column, gpointer data); +static void on_tree_unselect_row(GtkCTree *tree, GtkCTreeNode *node, gint column, gpointer data); +static void after_tree_move(GtkCTree *tree, GtkCTreeNode *node, GtkCTreeNode *new_parent, GtkCTreeNode *new_sibling, gpointer data); +static void on_destroy(GtkObject *object, gpointer data); +static gboolean on_delete(GtkObject *object, GdkEvent *event, gpointer data); + +static void on_tree_select_row_enable_if_element(GtkCTree *tree, GtkCTreeNode *node, gint column, gpointer data); +static void on_tree_select_row_enable_if_mutable(GtkCTree *tree, GtkCTreeNode *node, gint column, gpointer data); +static void on_tree_select_row_show_if_element(GtkCTree *tree, GtkCTreeNode *node, gint column, gpointer data); +static void on_tree_select_row_show_if_text(GtkCTree *tree, GtkCTreeNode *node, gint column, gpointer data); +static void on_tree_select_row_enable_if_indentable(GtkCTree *tree, GtkCTreeNode *node, gint column, gpointer data); +static void on_tree_select_row_enable_if_not_first_child(GtkCTree *tree, GtkCTreeNode *node, gint column, gpointer data); +static void on_tree_select_row_enable_if_not_last_child(GtkCTree *tree, GtkCTreeNode *node, gint column, gpointer data); +static void on_tree_select_row_enable_if_has_grandparent(GtkCTree *tree, GtkCTreeNode *node, gint column, gpointer data); + +static void on_tree_unselect_row_clear_text(GtkCTree *tree, GtkCTreeNode *node, gint column, gpointer data); +static void on_tree_unselect_row_disable(GtkCTree *tree, GtkCTreeNode *node, gint column, gpointer data); +static void on_tree_unselect_row_hide(GtkCTree *tree, GtkCTreeNode *node, gint column, gpointer data); + +static void on_attr_select_row(GtkCList *list, gint row, gint column, GdkEventButton *event, gpointer data); +static void on_attr_unselect_row(GtkCList *list, gint row, gint column, GdkEventButton *event, gpointer data); +static void on_attr_row_changed( GtkCList *list, gint row, gpointer data ); + +static void on_attr_select_row_enable(GtkCList *list, gint row, gint column, GdkEventButton *event, gpointer data); +static void on_attr_unselect_row_disable(GtkCList *list, gint row, gint column, GdkEventButton *event, gpointer data); + +static void on_attr_select_row_set_name_content(GtkCList *list, gint row, gint column, GdkEventButton *event, gpointer data); +static void on_attr_select_row_set_value_content(GtkCList *list, gint row, gint column, GdkEventButton *event, gpointer data); +static void on_attr_unselect_row_clear_text(GtkCList *list, gint row, gint column, GdkEventButton *event, gpointer data); + +static void on_editable_changed_enable_if_valid_xml_name(GtkEditable *editable, gpointer data); + +static void on_desktop_selection_changed(Inkscape::Selection *selection); +static void on_document_replaced(SPDesktop *dt, SPDocument *document); +static void on_document_uri_set(gchar const *uri, SPDocument *document); + +static void on_clicked_get_editable_text(GtkWidget *widget, gpointer data); + +static void _set_status_message(Inkscape::MessageType type, const gchar *message, GtkWidget *dialog); + +static void cmd_new_element_node(GtkObject *object, gpointer data); +static void cmd_new_text_node(GtkObject *object, gpointer data); +static void cmd_duplicate_node(GtkObject *object, gpointer data); +static void cmd_delete_node(GtkObject *object, gpointer data); + +static void cmd_raise_node(GtkObject *object, gpointer data); +static void cmd_lower_node(GtkObject *object, gpointer data); +static void cmd_indent_node(GtkObject *object, gpointer data); +static void cmd_unindent_node(GtkObject *object, gpointer data); + +static void cmd_delete_attr(GtkObject *object, gpointer data); +static void cmd_set_attr(GtkObject *object, gpointer data); + +static gboolean sp_xml_tree_key_press(GtkWidget *widget, GdkEventKey *event); + + +/* + * \brief Sets the XML status bar when the tree is selected. + */ +void tree_reset_context() +{ + _message_context->set(Inkscape::NORMAL_MESSAGE, + _("Click to select nodes, drag to rearrange.")); +} + + +/* + * \brief Sets the XML status bar, depending on which attr is selected. + */ +void attr_reset_context(gint attr) +{ + if (attr == 0) { + _message_context->set(Inkscape::NORMAL_MESSAGE, + _("Click attribute to edit.")); + } + else { + const gchar *name = g_quark_to_string(attr); + gchar *message = g_strdup_printf(_("Attribute %s selected. Press Ctrl+Enter when done editing to commit changes."), name); + _message_context->set(Inkscape::NORMAL_MESSAGE, message); + g_free(message); + } +} + + +void sp_xml_tree_dialog() +{ + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + + if (!desktop) { + return; + } + + if (dlg == NULL) + { // very long block + + GtkWidget *box, *sw, *paned, *toolbar, *button; + GtkWidget *text_container, *attr_container, *attr_subpaned_container, *box2; + GtkWidget *set_attr; + + tooltips = gtk_tooltips_new(); + gtk_tooltips_enable(tooltips); + + dlg = sp_window_new("", TRUE); + if (x == -1000 || y == -1000) { + x = prefs_get_int_attribute(prefs_path, "x", 0); + y = prefs_get_int_attribute(prefs_path, "y", 0); + } + if (w ==0 || h == 0) { + w = prefs_get_int_attribute(prefs_path, "w", 0); + h = prefs_get_int_attribute(prefs_path, "h", 0); + } + if (x != 0 || y != 0) { + gtk_window_move((GtkWindow *) dlg, x, y); + } else { + gtk_window_set_position(GTK_WINDOW(dlg), GTK_WIN_POS_CENTER); + } + + if (w && h) { + gtk_window_resize((GtkWindow *) dlg, w, h); + } + sp_transientize(dlg); + wd.win = dlg; + wd.stop = 0; + g_signal_connect ( G_OBJECT(INKSCAPE), "activate_desktop", G_CALLBACK(sp_transientize_callback), &wd ); + + gtk_signal_connect( GTK_OBJECT(dlg), "event", GTK_SIGNAL_FUNC(sp_dialog_event_handler), dlg ); + + gtk_signal_connect( GTK_OBJECT(dlg), "destroy", G_CALLBACK(on_destroy), dlg); + gtk_signal_connect( GTK_OBJECT(dlg), "delete_event", G_CALLBACK(on_delete), dlg); + g_signal_connect ( G_OBJECT(INKSCAPE), "shut_down", G_CALLBACK(on_delete), dlg); + + g_signal_connect ( G_OBJECT(INKSCAPE), "dialogs_hide", G_CALLBACK(sp_dialog_hide), dlg); + g_signal_connect ( G_OBJECT(INKSCAPE), "dialogs_unhide", G_CALLBACK(sp_dialog_unhide), dlg); + + + gtk_container_set_border_width(GTK_CONTAINER(dlg), 0); + gtk_window_set_default_size(GTK_WINDOW(dlg), 640, 384); + + GtkWidget *vbox = gtk_vbox_new(FALSE, 0); + gtk_container_add(GTK_CONTAINER(dlg), vbox); + + GtkWidget *hbox = gtk_hbox_new(FALSE, 0); + gtk_box_pack_end(GTK_BOX(vbox), hbox, FALSE, FALSE, 2); + + status = gtk_label_new(NULL); + gtk_misc_set_alignment(GTK_MISC(status), 0.0, 0.5); + gtk_widget_set_size_request(status, 1, -1); + gtk_label_set_markup(GTK_LABEL(status), ""); + gtk_box_pack_start(GTK_BOX(hbox), gtk_hbox_new(FALSE, 0), FALSE, FALSE, 4); + gtk_box_pack_start(GTK_BOX(hbox), status, TRUE, TRUE, 0); + + paned = gtk_hpaned_new(); + gtk_paned_set_position(GTK_PANED(paned), 256); + gtk_box_pack_start(GTK_BOX(vbox), paned, TRUE, TRUE, 0); + + _message_stack = new Inkscape::MessageStack(); + _message_context = new Inkscape::MessageContext(_message_stack); + _message_changed_connection = _message_stack->connectChanged( + sigc::bind(sigc::ptr_fun(_set_status_message), dlg) + ); + + /* tree view */ + + box = gtk_vbox_new(FALSE, 0); + gtk_paned_pack1(GTK_PANED(paned), box, FALSE, FALSE); + + tree = SP_XMLVIEW_TREE(sp_xmlview_tree_new(NULL, NULL, NULL)); + gtk_tooltips_set_tip( tooltips, GTK_WIDGET(tree), + _("Drag to reorder nodes"), NULL ); + + g_signal_connect( G_OBJECT(tree), "tree_select_row", + G_CALLBACK(on_tree_select_row), NULL ); + + g_signal_connect( G_OBJECT(tree), "tree_unselect_row", + G_CALLBACK(on_tree_unselect_row), NULL ); + + g_signal_connect_after( G_OBJECT(tree), "tree_move", + G_CALLBACK(after_tree_move), NULL); + + /* TODO: replace gtk_signal_connect_while_alive() with something + * else... + */ + toolbar = gtk_toolbar_new(); + gtk_toolbar_set_style(GTK_TOOLBAR(toolbar), GTK_TOOLBAR_ICONS); + gtk_container_set_border_width(GTK_CONTAINER(toolbar), 0); + + button = gtk_toolbar_append_item(GTK_TOOLBAR(toolbar), + NULL, + _("New element node"), + NULL, + sp_icon_new( GTK_ICON_SIZE_LARGE_TOOLBAR, + INKSCAPE_STOCK_ADD_XML_ELEMENT_NODE ), + G_CALLBACK(cmd_new_element_node), + NULL); + + gtk_signal_connect_while_alive( GTK_OBJECT(tree), + "tree_select_row", + G_CALLBACK(on_tree_select_row_enable_if_element), + button, + GTK_OBJECT(button)); + + gtk_signal_connect_while_alive(GTK_OBJECT(tree), + "tree_unselect_row", + G_CALLBACK(on_tree_unselect_row_disable), + button, + GTK_OBJECT(button)); + + gtk_widget_set_sensitive(GTK_WIDGET(button), FALSE); + + button = gtk_toolbar_append_item(GTK_TOOLBAR(toolbar), + NULL, _("New text node"), NULL, + sp_icon_new( GTK_ICON_SIZE_LARGE_TOOLBAR, + INKSCAPE_STOCK_ADD_XML_TEXT_NODE ), + G_CALLBACK(cmd_new_text_node), + NULL); + + gtk_signal_connect_while_alive(GTK_OBJECT(tree), + "tree_select_row", + G_CALLBACK(on_tree_select_row_enable_if_element), + button, + GTK_OBJECT(button)); + + gtk_signal_connect_while_alive(GTK_OBJECT(tree), + "tree_unselect_row", + G_CALLBACK(on_tree_unselect_row_disable), + button, + GTK_OBJECT(button)); + + gtk_widget_set_sensitive(GTK_WIDGET(button), FALSE); + + button = gtk_toolbar_append_item(GTK_TOOLBAR(toolbar), + NULL, _("Duplicate node"), NULL, + sp_icon_new( GTK_ICON_SIZE_LARGE_TOOLBAR, + INKSCAPE_STOCK_DUPLICATE_XML_NODE ), + G_CALLBACK(cmd_duplicate_node), + NULL); + + gtk_signal_connect_while_alive(GTK_OBJECT(tree), + "tree_select_row", + G_CALLBACK(on_tree_select_row_enable_if_mutable), + button, + GTK_OBJECT(button)); + + gtk_signal_connect_while_alive(GTK_OBJECT(tree), "tree_unselect_row", + G_CALLBACK(on_tree_unselect_row_disable), + button, GTK_OBJECT(button)); + + gtk_widget_set_sensitive(GTK_WIDGET(button), FALSE); + + gtk_toolbar_append_space(GTK_TOOLBAR(toolbar)); + + button = gtk_toolbar_append_item(GTK_TOOLBAR(toolbar), + NULL, _("Delete node"), NULL, + sp_icon_new( GTK_ICON_SIZE_LARGE_TOOLBAR, + INKSCAPE_STOCK_DELETE_XML_NODE ), + G_CALLBACK(cmd_delete_node), NULL ); + + gtk_signal_connect_while_alive(GTK_OBJECT(tree), "tree_select_row", + G_CALLBACK(on_tree_select_row_enable_if_mutable), + button, GTK_OBJECT(button)); + gtk_signal_connect_while_alive(GTK_OBJECT(tree), "tree_unselect_row", + G_CALLBACK(on_tree_unselect_row_disable), + button, GTK_OBJECT(button)); + gtk_widget_set_sensitive(GTK_WIDGET(button), FALSE); + + gtk_toolbar_append_space(GTK_TOOLBAR(toolbar)); + + button = gtk_toolbar_append_item( GTK_TOOLBAR(toolbar), "<", + _("Unindent node"), NULL, + gtk_arrow_new(GTK_ARROW_LEFT, GTK_SHADOW_IN), + G_CALLBACK(cmd_unindent_node), NULL); + + gtk_signal_connect_while_alive(GTK_OBJECT(tree), "tree_select_row", + G_CALLBACK(on_tree_select_row_enable_if_has_grandparent), + button, GTK_OBJECT(button)); + + gtk_signal_connect_while_alive(GTK_OBJECT(tree), "tree_unselect_row", + G_CALLBACK(on_tree_unselect_row_disable), + button, GTK_OBJECT(button)); + + gtk_widget_set_sensitive(GTK_WIDGET(button), FALSE); + + button = gtk_toolbar_append_item(GTK_TOOLBAR(toolbar), ">", + _("Indent node"), NULL, + gtk_arrow_new(GTK_ARROW_RIGHT, GTK_SHADOW_IN), + G_CALLBACK(cmd_indent_node), NULL); + gtk_signal_connect_while_alive(GTK_OBJECT(tree), "tree_select_row", + G_CALLBACK(on_tree_select_row_enable_if_indentable), + button, GTK_OBJECT(button)); + gtk_signal_connect_while_alive(GTK_OBJECT(tree), "tree_unselect_row", + (GCallback) on_tree_unselect_row_disable, + button, GTK_OBJECT(button)); + gtk_widget_set_sensitive(GTK_WIDGET(button), FALSE); + + button = gtk_toolbar_append_item(GTK_TOOLBAR(toolbar), "^", + _("Raise node"), NULL, + gtk_arrow_new(GTK_ARROW_UP, GTK_SHADOW_IN), + G_CALLBACK(cmd_raise_node), NULL); + gtk_signal_connect_while_alive(GTK_OBJECT(tree), "tree_select_row", + G_CALLBACK(on_tree_select_row_enable_if_not_first_child), + button, GTK_OBJECT(button)); + gtk_signal_connect_while_alive(GTK_OBJECT(tree), "tree_unselect_row", + G_CALLBACK(on_tree_unselect_row_disable), + button, GTK_OBJECT(button)); + gtk_widget_set_sensitive(GTK_WIDGET(button), FALSE); + + button = gtk_toolbar_append_item(GTK_TOOLBAR(toolbar), "v", + _("Lower node"), NULL, + gtk_arrow_new(GTK_ARROW_DOWN, GTK_SHADOW_IN), + G_CALLBACK(cmd_lower_node), NULL); + gtk_signal_connect_while_alive(GTK_OBJECT(tree), "tree_select_row", + G_CALLBACK(on_tree_select_row_enable_if_not_last_child), + button, GTK_OBJECT(button)); + gtk_signal_connect_while_alive(GTK_OBJECT(tree), "tree_unselect_row", + G_CALLBACK(on_tree_unselect_row_disable), + button, GTK_OBJECT(button)); + gtk_widget_set_sensitive(GTK_WIDGET(button), FALSE); + + gtk_box_pack_start(GTK_BOX(box), toolbar, FALSE, TRUE, 0); + + sw = gtk_scrolled_window_new(NULL, NULL); + gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW(sw), + GTK_POLICY_AUTOMATIC, + GTK_POLICY_AUTOMATIC ); + gtk_box_pack_start(GTK_BOX(box), sw, TRUE, TRUE, 0); + + gtk_container_add(GTK_CONTAINER(sw), GTK_WIDGET(tree)); + + /* node view */ + + box = gtk_vbox_new(FALSE, 0); + gtk_paned_pack2(GTK_PANED(paned), box, TRUE, TRUE); + + /* attributes */ + + attr_container = gtk_vbox_new(FALSE, 0); + gtk_box_pack_start( GTK_BOX(box), GTK_WIDGET(attr_container), + TRUE, TRUE, 0 ); + + attributes = SP_XMLVIEW_ATTR_LIST(sp_xmlview_attr_list_new(NULL)); + g_signal_connect( G_OBJECT(attributes), "select_row", + G_CALLBACK(on_attr_select_row), NULL); + g_signal_connect( G_OBJECT(attributes), "unselect_row", + G_CALLBACK(on_attr_unselect_row), NULL); + g_signal_connect( G_OBJECT(attributes), "row-value-changed", + G_CALLBACK(on_attr_row_changed), NULL); + + toolbar = gtk_toolbar_new(); + gtk_toolbar_set_style(GTK_TOOLBAR(toolbar), GTK_TOOLBAR_ICONS); + gtk_container_set_border_width(GTK_CONTAINER(toolbar), 0); + + button = gtk_toolbar_append_item(GTK_TOOLBAR(toolbar), + NULL, _("Delete attribute"), NULL, + sp_icon_new( GTK_ICON_SIZE_LARGE_TOOLBAR, + INKSCAPE_STOCK_DELETE_XML_ATTRIBUTE ), + (GCallback) cmd_delete_attr, NULL); + + gtk_signal_connect_while_alive(GTK_OBJECT(attributes), "select_row", + (GCallback) on_attr_select_row_enable, button, + GTK_OBJECT(button)); + + gtk_signal_connect_while_alive(GTK_OBJECT(attributes), "unselect_row", + (GCallback) on_attr_unselect_row_disable, button, + GTK_OBJECT(button)); + + gtk_signal_connect_while_alive(GTK_OBJECT(tree), "tree_unselect_row", + (GCallback) on_tree_unselect_row_disable, button, + GTK_OBJECT(button)); + + gtk_widget_set_sensitive(GTK_WIDGET(button), FALSE); + + gtk_box_pack_start( GTK_BOX(attr_container), + GTK_WIDGET(toolbar), FALSE, TRUE, 0 ); + + attr_subpaned_container = gtk_vpaned_new(); + gtk_box_pack_start( GTK_BOX(attr_container), + GTK_WIDGET(attr_subpaned_container), + TRUE, TRUE, 0 ); + gtk_widget_show(attr_subpaned_container); + + sw = gtk_scrolled_window_new(NULL, NULL); + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), + GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + gtk_paned_pack1( GTK_PANED(attr_subpaned_container), + GTK_WIDGET(sw), TRUE, TRUE ); + gtk_container_add(GTK_CONTAINER(sw), GTK_WIDGET(attributes)); + + toolbar = gtk_vbox_new(FALSE, 4); + gtk_container_set_border_width(GTK_CONTAINER(toolbar), 4); + + box2 = gtk_hbox_new(FALSE, 4); + gtk_box_pack_start( GTK_BOX(toolbar), GTK_WIDGET(box2), + FALSE, TRUE, 0); + + attr_name = GTK_EDITABLE(gtk_entry_new()); + gtk_tooltips_set_tip( tooltips, GTK_WIDGET(attr_name), + // TRANSLATORS: "Attribute" is a noun here + _("Attribute name"), NULL ); + + gtk_signal_connect( GTK_OBJECT(attributes), "select_row", + (GCallback) on_attr_select_row_set_name_content, + attr_name); + + gtk_signal_connect( GTK_OBJECT(attributes), "unselect_row", + (GCallback) on_attr_unselect_row_clear_text, + attr_name); + + gtk_signal_connect( GTK_OBJECT(tree), "tree_unselect_row", + (GCallback) on_tree_unselect_row_clear_text, + attr_name); + + gtk_box_pack_start( GTK_BOX(box2), GTK_WIDGET(attr_name), + TRUE, TRUE, 0); + + set_attr = gtk_button_new(); + gtk_tooltips_set_tip( tooltips, GTK_WIDGET(set_attr), + // TRANSLATORS: "Set" is a verb here + _("Set attribute"), NULL ); + // TRANSLATORS: "Set" is a verb here + GtkWidget *set_label = gtk_label_new(_("Set")); + gtk_container_add(GTK_CONTAINER(set_attr), set_label); + + gtk_signal_connect( GTK_OBJECT(set_attr), "clicked", + (GCallback) cmd_set_attr, NULL); + gtk_signal_connect( GTK_OBJECT(attr_name), "changed", + (GCallback) on_editable_changed_enable_if_valid_xml_name, + set_attr ); + gtk_widget_set_sensitive(GTK_WIDGET(set_attr), FALSE); + + gtk_box_pack_start(GTK_BOX(box2), set_attr, FALSE, FALSE, 0); + + sw = gtk_scrolled_window_new(NULL, NULL); + gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW(sw), + GTK_POLICY_AUTOMATIC, + GTK_POLICY_AUTOMATIC ); + gtk_scrolled_window_set_shadow_type( GTK_SCROLLED_WINDOW(sw), GTK_SHADOW_IN ); + gtk_box_pack_start(GTK_BOX(toolbar), sw, TRUE, TRUE, 0); + + attr_value =(GtkTextView *) gtk_text_view_new(); + gtk_text_view_set_wrap_mode((GtkTextView *) attr_value, GTK_WRAP_CHAR); + gtk_tooltips_set_tip( tooltips, GTK_WIDGET(attr_value), + // TRANSLATORS: "Attribute" is a noun here + _("Attribute value"), NULL ); + gtk_signal_connect( GTK_OBJECT(attributes), "select_row", + (GCallback) on_attr_select_row_set_value_content, + attr_value ); + gtk_signal_connect( GTK_OBJECT(attributes), "unselect_row", + (GCallback) on_attr_unselect_row_clear_text, + attr_value ); + gtk_signal_connect( GTK_OBJECT(tree), "tree_unselect_row", + (GCallback) on_tree_unselect_row_clear_text, + attr_value ); + gtk_text_view_set_editable(attr_value, TRUE); + gtk_container_add( GTK_CONTAINER(sw), + GTK_WIDGET(attr_value) ); + + gtk_paned_pack2( GTK_PANED(attr_subpaned_container), + GTK_WIDGET(toolbar), FALSE, TRUE ); + + /* text */ + + sw = gtk_scrolled_window_new(NULL, NULL); + gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW(sw), + GTK_POLICY_AUTOMATIC, + GTK_POLICY_AUTOMATIC ); + gtk_scrolled_window_set_shadow_type( GTK_SCROLLED_WINDOW(sw), GTK_SHADOW_IN ); + gtk_box_pack_start(GTK_BOX(box), GTK_WIDGET(sw), TRUE, TRUE, 0); + + content = SP_XMLVIEW_CONTENT(sp_xmlview_content_new(NULL)); + gtk_container_add(GTK_CONTAINER(sw), GTK_WIDGET(content)); + + text_container = sw; + + /* initial show/hide */ + + gtk_widget_show_all(GTK_WIDGET(dlg)); + + gtk_signal_connect_while_alive(GTK_OBJECT(tree), "tree_select_row", + (GCallback) on_tree_select_row_show_if_element, + attr_container, GTK_OBJECT(attr_container)); + + gtk_signal_connect_while_alive(GTK_OBJECT(tree), "tree_unselect_row", + (GCallback) on_tree_unselect_row_hide, + attr_container, GTK_OBJECT(attr_container)); + + gtk_widget_hide(attr_container); + + gtk_signal_connect_while_alive(GTK_OBJECT(tree), "tree_select_row", + (GCallback) on_tree_select_row_show_if_text, + text_container, GTK_OBJECT(text_container)); + + gtk_signal_connect_while_alive(GTK_OBJECT(tree), "tree_unselect_row", + (GCallback) on_tree_unselect_row_hide, + text_container, GTK_OBJECT(text_container)); + + gtk_widget_hide(text_container); + + g_signal_connect( G_OBJECT(INKSCAPE), "activate_desktop", + G_CALLBACK(sp_xmltree_desktop_change), dlg); + + g_signal_connect( G_OBJECT(INKSCAPE), "deactivate_desktop", + G_CALLBACK(sp_xmltree_desktop_change), dlg); + + g_signal_connect((GObject *) dlg, "key_press_event", (GCallback) sp_xml_tree_key_press, NULL); + + tree_reset_context(); + } // end of if (dlg == NULL) + + gtk_window_present((GtkWindow *) dlg); + + g_assert(desktop != NULL); + set_tree_desktop(desktop); + +} // end of sp_xml_tree_dialog() + +static gboolean sp_xml_tree_key_press(GtkWidget *widget, GdkEventKey *event) +{ + + unsigned int shortcut = get_group0_keyval(event) | + ( event->state & GDK_SHIFT_MASK ? + SP_SHORTCUT_SHIFT_MASK : 0 ) | + ( event->state & GDK_CONTROL_MASK ? + SP_SHORTCUT_CONTROL_MASK : 0 ) | + ( event->state & GDK_MOD1_MASK ? + SP_SHORTCUT_ALT_MASK : 0 ); + + /* fixme: if you need to add more xml-tree-specific callbacks, you should probably upgrade + * the sp_shortcut mechanism to take into account windows. */ + if (shortcut == (SP_SHORTCUT_CONTROL_MASK | GDK_Return)) { + cmd_set_attr(NULL, NULL); + return true; + } + return false; +} + + +static void sp_xmltree_desktop_change(Inkscape::Application *inkscape, + SPDesktop *desktop, + GtkWidget *dialog ) +{ + if (!desktop) { + return; + } + set_tree_desktop(desktop); +} + + +void set_tree_desktop(SPDesktop *desktop) +{ + if ( desktop == current_desktop ) { + return; + } + + if (current_desktop) { + sel_changed_connection.disconnect(); + document_replaced_connection.disconnect(); + } + current_desktop = desktop; + if (desktop) { + sel_changed_connection = SP_DT_SELECTION(desktop)->connectChanged(&on_desktop_selection_changed); + document_replaced_connection = desktop->connectDocumentReplaced(&on_document_replaced); + set_tree_document(SP_DT_DOCUMENT(desktop)); + } else { + set_tree_document(NULL); + } + +} // end of set_tree_desktop() + + + +void set_tree_document(SPDocument *document) +{ + if (document == current_document) { + return; + } + + if (current_document) { + document_uri_set_connection.disconnect(); + } + current_document = document; + if (current_document) { + + document_uri_set_connection = current_document->connectURISet(sigc::bind(sigc::ptr_fun(&on_document_uri_set), current_document)); + on_document_uri_set(SP_DOCUMENT_URI(current_document), current_document); + set_tree_repr(sp_document_repr_root(current_document)); + + } else { + set_tree_repr(NULL); + } +} + + + +void set_tree_repr(Inkscape::XML::Node *repr) +{ + if (repr == selected_repr) { + return; + } + + gtk_clist_freeze(GTK_CLIST(tree)); + + sp_xmlview_tree_set_repr(tree, repr); + + if (repr) { + set_tree_select(get_dt_select()); + } else { + set_tree_select(NULL); + } + + gtk_clist_thaw(GTK_CLIST(tree)); + + propagate_tree_select(selected_repr); + +} + + + +void set_tree_select(Inkscape::XML::Node *repr) +{ + if (selected_repr) { + Inkscape::GC::release(selected_repr); + } + + selected_repr = repr; + if (repr) { + GtkCTreeNode *node; + + Inkscape::GC::anchor(selected_repr); + + node = sp_xmlview_tree_get_repr_node(SP_XMLVIEW_TREE(tree), repr); + if (node) { + GtkCTreeNode *parent; + + gtk_ctree_select(GTK_CTREE(tree), node); + + parent = GTK_CTREE_ROW(node)->parent; + while (parent) { + gtk_ctree_expand(GTK_CTREE(tree), parent); + parent = GTK_CTREE_ROW(parent)->parent; + } + + gtk_ctree_node_moveto(GTK_CTREE(tree), node, 0, 0.66, 0.0); + } + } else { + gtk_clist_unselect_all(GTK_CLIST(tree)); + } + propagate_tree_select(repr); +} + + + +void propagate_tree_select(Inkscape::XML::Node *repr) +{ + if (repr && repr->type() == Inkscape::XML::ELEMENT_NODE) { + sp_xmlview_attr_list_set_repr(attributes, repr); + } else { + sp_xmlview_attr_list_set_repr(attributes, NULL); + } + + if (repr && ( repr->type() == Inkscape::XML::TEXT_NODE || repr->type() == Inkscape::XML::COMMENT_NODE ) ) { + sp_xmlview_content_set_repr(content, repr); + } else { + sp_xmlview_content_set_repr(content, NULL); + } +} + + +Inkscape::XML::Node *get_dt_select() +{ + if (!current_desktop) { + return NULL; + } + + return SP_DT_SELECTION(current_desktop)->singleRepr(); +} + + + +void set_dt_select(Inkscape::XML::Node *repr) +{ + if (!current_desktop) { + return; + } + + Inkscape::Selection *selection = SP_DT_SELECTION(current_desktop); + + SPObject *object; + if (repr) { + while ( ( repr->type() != Inkscape::XML::ELEMENT_NODE ) + && sp_repr_parent(repr) ) + { + repr = sp_repr_parent(repr); + } // end of while loop + + object = SP_DT_DOCUMENT(current_desktop)->getObjectByRepr(repr); + } else { + object = NULL; + } + + blocked++; + if ( object && in_dt_coordsys(*object) + && !( SP_IS_TSPAN(object) || + SP_IS_STRING(object) || + SP_IS_ROOT(object) ) ) + { + /* We cannot set selection to tspan, string, or root; failures and + * crashes will occur. */ + /* TODO: when a tspan is highlighted, set selection to its parent + * text + */ + selection->set(SP_ITEM(object)); + } + blocked--; + +} // end of set_dt_select() + + +void on_tree_select_row(GtkCTree *tree, + GtkCTreeNode *node, + gint column, + gpointer data) +{ + if (blocked) { + return; + } + + Inkscape::XML::Node *repr = sp_xmlview_tree_node_get_repr(SP_XMLVIEW_TREE(tree), node); + g_assert(repr != NULL); + + if (selected_repr == repr) { + return; + } + + if (selected_repr) { + Inkscape::GC::release(selected_repr); + selected_repr = NULL; + } + selected_repr = repr; + Inkscape::GC::anchor(selected_repr); + + propagate_tree_select(selected_repr); + + set_dt_select(selected_repr); + + tree_reset_context(); +} + +void on_tree_unselect_row(GtkCTree *tree, + GtkCTreeNode *node, + gint column, + gpointer data) +{ + if (blocked) { + return; + } + + Inkscape::XML::Node *repr = sp_xmlview_tree_node_get_repr(SP_XMLVIEW_TREE(tree), node); + propagate_tree_select(NULL); + set_dt_select(NULL); + + if (selected_repr && (selected_repr == repr)) { + Inkscape::GC::release(selected_repr); + selected_repr = NULL; + selected_attr = 0; + } +} + + + +void after_tree_move(GtkCTree *tree, + GtkCTreeNode *node, + GtkCTreeNode *new_parent, + GtkCTreeNode *new_sibling, + gpointer data) +{ + if (GTK_CTREE_ROW(node)->parent == new_parent && + GTK_CTREE_ROW(node)->sibling == new_sibling) + { + sp_document_done(current_document); + } else { + sp_document_cancel(current_document); + } +} + + +static void on_destroy(GtkObject *object, gpointer data) +{ + set_tree_desktop(NULL); + gtk_object_destroy(GTK_OBJECT(tooltips)); + tooltips = NULL; + sp_signal_disconnect_by_data(INKSCAPE, dlg); + wd.win = dlg = NULL; + wd.stop = 0; + + _message_changed_connection.disconnect(); + delete _message_context; + _message_context = NULL; + Inkscape::GC::release(_message_stack); + _message_stack = NULL; + _message_changed_connection.~connection(); + + status = NULL; +} + + + +static gboolean on_delete(GtkObject *object, GdkEvent *event, gpointer data) +{ + gtk_window_get_position((GtkWindow *) dlg, &x, &y); + gtk_window_get_size((GtkWindow *) dlg, &w, &h); + + prefs_set_int_attribute(prefs_path, "x", x); + prefs_set_int_attribute(prefs_path, "y", y); + prefs_set_int_attribute(prefs_path, "w", w); + prefs_set_int_attribute(prefs_path, "h", h); + + return FALSE; // which means, go ahead and destroy it +} + + +static void _set_status_message(Inkscape::MessageType type, const gchar *message, GtkWidget *dialog) +{ + if (status) { + gtk_label_set_markup(GTK_LABEL(status), message ? message : ""); + } +} + + +void on_tree_select_row_enable(GtkCTree *tree, + GtkCTreeNode *node, + gint column, + gpointer data) +{ + gtk_widget_set_sensitive(GTK_WIDGET(data), TRUE); +} + + + +void on_tree_select_row_enable_if_element(GtkCTree *tree, + GtkCTreeNode *node, + gint column, + gpointer data ) +{ + Inkscape::XML::Node *repr = sp_xmlview_tree_node_get_repr(SP_XMLVIEW_TREE(tree), node); + + if (repr->type() == Inkscape::XML::ELEMENT_NODE) { + gtk_widget_set_sensitive(GTK_WIDGET(data), TRUE); + } else { + gtk_widget_set_sensitive(GTK_WIDGET(data), FALSE); + } +} + + + +void on_tree_select_row_show_if_element(GtkCTree *tree, GtkCTreeNode *node, + gint column, gpointer data) +{ + Inkscape::XML::Node *repr = sp_xmlview_tree_node_get_repr(SP_XMLVIEW_TREE(tree), node); + + if (repr->type() == Inkscape::XML::ELEMENT_NODE) { + gtk_widget_show(GTK_WIDGET(data)); + } else { + gtk_widget_hide(GTK_WIDGET(data)); + } +} + + + +void on_tree_select_row_show_if_text(GtkCTree *tree, GtkCTreeNode *node, + gint column, gpointer data) +{ + Inkscape::XML::Node *repr = sp_xmlview_tree_node_get_repr(SP_XMLVIEW_TREE(tree), node); + + if ( repr->type() == Inkscape::XML::TEXT_NODE || repr->type() == Inkscape::XML::COMMENT_NODE ) { + gtk_widget_show(GTK_WIDGET(data)); + } else { + gtk_widget_hide(GTK_WIDGET(data)); + } +} + + +gboolean xml_tree_node_mutable(GtkCTreeNode *node) +{ + // top-level is immutable, obviously + if (!GTK_CTREE_ROW(node)->parent) { + return false; + } + + // if not in base level (where namedview, defs, etc go), we're mutable + if (GTK_CTREE_ROW(GTK_CTREE_ROW(node)->parent)->parent) { + return true; + } + + Inkscape::XML::Node *repr; + repr = sp_xmlview_tree_node_get_repr(SP_XMLVIEW_TREE(tree), node); + g_assert(repr); + + // don't let "defs" or "namedview" disappear + if ( !strcmp(repr->name(),"svg:defs") || + !strcmp(repr->name(),"sodipodi:namedview") ) { + return false; + } + + // everyone else is okay, I guess. :) + return true; +} + + +void on_tree_select_row_enable_if_mutable(GtkCTree *tree, GtkCTreeNode *node, + gint column, gpointer data) +{ + gtk_widget_set_sensitive(GTK_WIDGET(data), xml_tree_node_mutable(node)); +} + + + +void on_tree_unselect_row_disable(GtkCTree *tree, GtkCTreeNode *node, + gint column, gpointer data) +{ + gtk_widget_set_sensitive(GTK_WIDGET(data), FALSE); +} + + + +void on_tree_unselect_row_hide(GtkCTree *tree, GtkCTreeNode *node, + gint column, gpointer data) +{ + gtk_widget_hide(GTK_WIDGET(data)); +} + + + +void on_tree_unselect_row_clear_text(GtkCTree *tree, GtkCTreeNode *node, + gint column, gpointer data) +{ + if (GTK_IS_EDITABLE(data)) { + gtk_editable_delete_text(GTK_EDITABLE(data), 0, -1); + } else if (GTK_IS_TEXT_VIEW(data)) { + GtkTextBuffer *tb; + tb = gtk_text_view_get_buffer(GTK_TEXT_VIEW(data)); + gtk_text_buffer_set_text(tb, "", 0); + } +} + + +void on_attr_select_row(GtkCList *list, gint row, gint column, + GdkEventButton *event, gpointer data) +{ + selected_attr = sp_xmlview_attr_list_get_row_key(list, row); + gtk_window_set_focus(GTK_WINDOW(dlg), GTK_WIDGET(attr_value)); + + attr_reset_context(selected_attr); +} + + +void on_attr_unselect_row(GtkCList *list, gint row, gint column, + GdkEventButton *event, gpointer data) +{ + selected_attr = 0; + attr_reset_context(selected_attr); +} + + +void on_attr_row_changed(GtkCList *list, gint row, gpointer data) +{ + gint attr = sp_xmlview_attr_list_get_row_key(list, row); + + if (attr == selected_attr) { + /* if the attr changed, reselect the row in the list to sync + the edit box */ + + /* + // get current attr values + const gchar * name = g_quark_to_string (sp_xmlview_attr_list_get_row_key (list, row)); + const gchar * value = selected_repr->attribute(name); + + g_warning("value: '%s'",value); + + // get the edit box value + GtkTextIter start, end; + gtk_text_buffer_get_bounds ( gtk_text_view_get_buffer (attr_value), + &start, &end ); + gchar * text = gtk_text_buffer_get_text ( gtk_text_view_get_buffer (attr_value), + &start, &end, TRUE ); + g_warning("text: '%s'",text); + + // compare to edit box + if (strcmp(text,value)) { + // issue warning if they're different + _message_stack->flash(Inkscape::WARNING_MESSAGE, + _("Attribute changed in GUI while editing values!")); + } + g_free (text); + + */ + gtk_clist_unselect_row( GTK_CLIST(list), row, 0 ); + gtk_clist_select_row( GTK_CLIST(list), row, 0 ); + } +} + + +void on_attr_select_row_set_name_content(GtkCList *list, gint row, + gint column, GdkEventButton *event, + gpointer data) +{ + GtkEditable *editable = GTK_EDITABLE(data); + const gchar *name = g_quark_to_string(sp_xmlview_attr_list_get_row_key(list, row)); + gtk_editable_delete_text(editable, 0, -1); + gint pos = 0; + gtk_editable_insert_text(editable, name, strlen(name), &pos); +} + + + +void on_attr_select_row_set_value_content(GtkCList *list, gint row, gint column, + GdkEventButton *event, + gpointer data) +{ + GtkTextBuffer *tb = gtk_text_view_get_buffer(GTK_TEXT_VIEW(data)); + const gchar *name = g_quark_to_string(sp_xmlview_attr_list_get_row_key(list, row)); + const gchar *value = selected_repr->attribute(name); + if (!value) { + value = ""; + } + gtk_text_buffer_set_text(tb, value, strlen(value)); +} + + +void on_tree_select_row_enable_if_indentable(GtkCTree *tree, GtkCTreeNode *node, + gint column, gpointer data) +{ + gboolean indentable = FALSE; + + if (xml_tree_node_mutable(node)) { + Inkscape::XML::Node *repr, *prev; + repr = sp_xmlview_tree_node_get_repr(SP_XMLVIEW_TREE(tree), node); + + Inkscape::XML::Node *parent=repr->parent(); + if ( parent && repr != parent->firstChild() ) { + g_assert(parent->firstChild()); + + // skip to the child just before the current repr + for ( prev = parent->firstChild() ; + prev && prev->next() != repr ; + prev = prev->next() ); + + if (prev && prev->type() == Inkscape::XML::ELEMENT_NODE) { + indentable = TRUE; + } + } + } + + gtk_widget_set_sensitive(GTK_WIDGET(data), indentable); +} + + + +void on_tree_select_row_enable_if_not_first_child(GtkCTree *tree, + GtkCTreeNode *node, + gint column, + gpointer data) +{ + Inkscape::XML::Node *repr = sp_xmlview_tree_node_get_repr(SP_XMLVIEW_TREE(tree), node); + + Inkscape::XML::Node *parent=repr->parent(); + if ( parent && repr != parent->firstChild() ) { + gtk_widget_set_sensitive(GTK_WIDGET(data), TRUE); + } else { + gtk_widget_set_sensitive(GTK_WIDGET(data), FALSE); + } +} + + + +void on_tree_select_row_enable_if_not_last_child(GtkCTree *tree, + GtkCTreeNode *node, + gint column, gpointer data) +{ + Inkscape::XML::Node *repr = sp_xmlview_tree_node_get_repr(SP_XMLVIEW_TREE(tree), node); + + Inkscape::XML::Node *parent=repr->parent(); + if ( parent && parent->parent() && repr->next() ) { + gtk_widget_set_sensitive(GTK_WIDGET(data), TRUE); + } else { + gtk_widget_set_sensitive(GTK_WIDGET(data), FALSE); + } +} + + + +void on_tree_select_row_enable_if_has_grandparent(GtkCTree *tree, + GtkCTreeNode *node, + gint column, gpointer data) +{ + GtkCTreeNode *parent = GTK_CTREE_ROW(node)->parent; + + if (parent) { + GtkCTreeNode *grandparent = GTK_CTREE_ROW(parent)->parent; + if (grandparent) { + gtk_widget_set_sensitive(GTK_WIDGET(data), TRUE); + } else { + gtk_widget_set_sensitive(GTK_WIDGET(data), FALSE); + } + } else { + gtk_widget_set_sensitive(GTK_WIDGET(data), FALSE); + } +} + + + +void on_attr_select_row_enable(GtkCList *list, gint row, gint column, + GdkEventButton *event, gpointer data) +{ + gtk_widget_set_sensitive(GTK_WIDGET(data), TRUE); +} + + + +void on_attr_unselect_row_disable(GtkCList *list, gint row, gint column, + GdkEventButton *event, gpointer data) +{ + gtk_widget_set_sensitive(GTK_WIDGET(data), FALSE); +} + + + +void on_attr_unselect_row_clear_text(GtkCList *list, gint row, gint column, + GdkEventButton *event, gpointer data) +{ + if (GTK_IS_EDITABLE(data)) { + gtk_editable_delete_text(GTK_EDITABLE(data), 0, -1); + } else if (GTK_IS_TEXT_VIEW(data)) { + GtkTextBuffer *tb; + tb = gtk_text_view_get_buffer(GTK_TEXT_VIEW(data)); + gtk_text_buffer_set_text(tb, "", 0); + } +} + + + +void on_editable_changed_enable_if_valid_xml_name(GtkEditable *editable, + gpointer data) +{ + gchar *text = gtk_editable_get_chars(editable, 0, -1); + + /* TODO: need to do checking a little more rigorous than this */ + + if (strlen(text)) { + gtk_widget_set_sensitive(GTK_WIDGET(data), TRUE); + } else { + gtk_widget_set_sensitive(GTK_WIDGET(data), FALSE); + } + g_free(text); +} + + + +void on_desktop_selection_changed(Inkscape::Selection *selection) +{ + if (!blocked++) { + set_tree_select(get_dt_select()); + } + blocked--; +} + +static void on_document_replaced(SPDesktop *dt, SPDocument *doc) +{ + if (current_desktop) + sel_changed_connection.disconnect(); + + sel_changed_connection = SP_DT_SELECTION(dt)->connectChanged(&on_desktop_selection_changed); + set_tree_document(doc); +} + +void on_document_uri_set(gchar const *uri, SPDocument *document) +{ + gchar title[500]; + sp_ui_dialog_title_string(Inkscape::Verb::get(SP_VERB_DIALOG_XML_EDITOR), title); + gchar *t = g_strdup_printf("%s: %s", SP_DOCUMENT_NAME(document), title); + gtk_window_set_title(GTK_WINDOW(dlg), t); + g_free(t); +} + + + +void on_clicked_get_editable_text(GtkWidget *widget, gpointer data) +{ + EditableDest *dest = (EditableDest *) data; + dest->text = gtk_editable_get_chars(dest->editable, 0, -1); +} + + + +void cmd_new_element_node(GtkObject *object, gpointer data) +{ + EditableDest name; + GtkWidget *window, *create, *cancel, *vbox, *entry, *bbox, *sep; + + g_assert(selected_repr != NULL); + + window = sp_window_new(NULL, TRUE); + gtk_container_set_border_width(GTK_CONTAINER(window), 4); + gtk_window_set_title(GTK_WINDOW(window), _("New element node...")); + gtk_window_set_policy(GTK_WINDOW(window), FALSE, FALSE, TRUE); + gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); + gtk_window_set_transient_for(GTK_WINDOW(window), GTK_WINDOW(dlg)); + gtk_window_set_modal(GTK_WINDOW(window), TRUE); + gtk_signal_connect(GTK_OBJECT(window), "destroy", gtk_main_quit, NULL); + + vbox = gtk_vbox_new(FALSE, 4); + gtk_container_add(GTK_CONTAINER(window), vbox); + + entry = gtk_entry_new(); + gtk_box_pack_start(GTK_BOX(vbox), entry, FALSE, TRUE, 0); + + sep = gtk_hseparator_new(); + gtk_box_pack_start(GTK_BOX(vbox), sep, FALSE, TRUE, 0); + + bbox = gtk_hbutton_box_new(); + gtk_container_set_border_width(GTK_CONTAINER(bbox), 4); + gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END); + gtk_box_pack_start(GTK_BOX(vbox), bbox, FALSE, TRUE, 0); + + cancel = gtk_button_new_with_label(_("Cancel")); + gtk_signal_connect_object( GTK_OBJECT(cancel), "clicked", + G_CALLBACK(gtk_widget_destroy), + GTK_OBJECT(window) ); + gtk_container_add(GTK_CONTAINER(bbox), cancel); + + create = gtk_button_new_with_label(_("Create")); + gtk_widget_set_sensitive(GTK_WIDGET(create), FALSE); + gtk_signal_connect( GTK_OBJECT(entry), "changed", + G_CALLBACK(on_editable_changed_enable_if_valid_xml_name), + create ); + gtk_signal_connect( GTK_OBJECT(create), "clicked", + G_CALLBACK(on_clicked_get_editable_text), &name ); + gtk_signal_connect_object( GTK_OBJECT(create), "clicked", + G_CALLBACK(gtk_widget_destroy), + GTK_OBJECT(window) ); + GTK_WIDGET_SET_FLAGS( GTK_WIDGET(create), + GTK_CAN_DEFAULT | GTK_RECEIVES_DEFAULT ); + gtk_container_add(GTK_CONTAINER(bbox), create); + + gtk_widget_show_all(GTK_WIDGET(window)); + gtk_window_set_default(GTK_WINDOW(window), GTK_WIDGET(create)); + gtk_window_set_focus(GTK_WINDOW(window), GTK_WIDGET(entry)); + + name.editable = GTK_EDITABLE(entry); + name.text = NULL; + + gtk_main(); + + g_assert(selected_repr != NULL); + + if (name.text) { + Inkscape::XML::Node *new_repr; + new_repr = sp_repr_new(name.text); + g_free(name.text); + selected_repr->appendChild(new_repr); + set_tree_select(new_repr); + set_dt_select(new_repr); + } + +} // end of cmd_new_element_node() + + + +void cmd_new_text_node(GtkObject *object, gpointer data) +{ + g_assert(selected_repr != NULL); + + Inkscape::XML::Node *text = sp_repr_new_text(""); + selected_repr->appendChild(text); + + sp_document_done(current_document); + + set_tree_select(text); + set_dt_select(text); + + gtk_window_set_focus(GTK_WINDOW(dlg), GTK_WIDGET(content)); + +} + +void cmd_duplicate_node(GtkObject *object, gpointer data) +{ + g_assert(selected_repr != NULL); + + Inkscape::XML::Node *parent = sp_repr_parent(selected_repr); + Inkscape::XML::Node *dup = selected_repr->duplicate(); + parent->addChild(dup, selected_repr); + + sp_document_done(current_document); + + GtkCTreeNode *node = sp_xmlview_tree_get_repr_node(SP_XMLVIEW_TREE(tree), dup); + + if (node) { + gtk_ctree_select(GTK_CTREE(tree), node); + } +} + + + +void cmd_delete_node(GtkObject *object, gpointer data) +{ + g_assert(selected_repr != NULL); + sp_repr_unparent(selected_repr); + + sp_document_done(current_document); +} + + + +void cmd_delete_attr(GtkObject *object, gpointer data) +{ + g_assert(selected_repr != NULL); + g_assert(selected_attr != 0); + selected_repr->setAttribute(g_quark_to_string(selected_attr), NULL); + + SPObject *updated=current_document->getObjectByRepr(selected_repr); + if (updated) { + // force immediate update of dependant attributes + updated->updateRepr(); + } + + sp_document_done(current_document); +} + + + +void cmd_set_attr(GtkObject *object, gpointer data) +{ + g_assert(selected_repr != NULL); + + gchar *name = gtk_editable_get_chars(attr_name, 0, -1); + GtkTextIter start; + GtkTextIter end; + gtk_text_buffer_get_bounds( gtk_text_view_get_buffer(attr_value), + &start, &end ); + gchar *value = gtk_text_buffer_get_text( gtk_text_view_get_buffer(attr_value), + &start, &end, TRUE ); + + if (!sp_repr_set_attr(selected_repr, name, value)) { + gchar *message = g_strdup_printf(_("Cannot set %s: Another element with value %s already exists!"), name, value); + _message_stack->flash(Inkscape::WARNING_MESSAGE, message); + g_free(message); + } + + g_free(name); + g_free(value); + + SPObject *updated = current_document->getObjectByRepr(selected_repr); + if (updated) { + // force immediate update of dependant attributes + updated->updateRepr(); + } + + sp_document_done(current_document); + + /* TODO: actually, the row won't have been created yet. why? */ + gint row = sp_xmlview_attr_list_find_row_from_key(GTK_CLIST(attributes), + g_quark_from_string(name)); + if (row != -1) { + gtk_clist_select_row(GTK_CLIST(attributes), row, 0); + } +} + + + +void cmd_raise_node(GtkObject *object, gpointer data) +{ + g_assert(selected_repr != NULL); + + Inkscape::XML::Node *parent = sp_repr_parent(selected_repr); + g_return_if_fail(parent != NULL); + g_return_if_fail(parent->firstChild() != selected_repr); + + Inkscape::XML::Node *ref = NULL; + Inkscape::XML::Node *before = parent->firstChild(); + while (before && before->next() != selected_repr) { + ref = before; + before = before->next(); + } + + parent->changeOrder(selected_repr, ref); + + sp_document_done(current_document); + + set_tree_select(selected_repr); + set_dt_select(selected_repr); +} + + + +void cmd_lower_node(GtkObject *object, gpointer data) +{ + g_assert(selected_repr != NULL); + g_return_if_fail(selected_repr->next() != NULL); + Inkscape::XML::Node *parent = sp_repr_parent(selected_repr); + + parent->changeOrder(selected_repr, selected_repr->next()); + + sp_document_done(current_document); + + set_tree_select(selected_repr); + set_dt_select(selected_repr); +} + +void cmd_indent_node(GtkObject *object, gpointer data) +{ + Inkscape::XML::Node *repr = selected_repr; + g_assert(repr != NULL); + Inkscape::XML::Node *parent = sp_repr_parent(repr); + g_return_if_fail(parent != NULL); + g_return_if_fail(parent->firstChild() != repr); + + Inkscape::XML::Node* prev = parent->firstChild(); + while (prev && prev->next() != repr) { + prev = prev->next(); + } + g_return_if_fail(prev != NULL); + g_return_if_fail(prev->type() == Inkscape::XML::ELEMENT_NODE); + + Inkscape::XML::Node* ref = NULL; + if (prev->firstChild()) { + for( ref = prev->firstChild() ; ref->next() ; ref = ref->next() ); + } + + parent->removeChild(repr); + prev->addChild(repr, ref); + + sp_document_done(current_document); + set_tree_select(repr); + set_dt_select(repr); + +} // end of cmd_indent_node() + + + +void cmd_unindent_node(GtkObject *object, gpointer data) +{ + Inkscape::XML::Node *repr = selected_repr; + g_assert(repr != NULL); + Inkscape::XML::Node *parent = sp_repr_parent(repr); + g_return_if_fail(parent); + Inkscape::XML::Node *grandparent = sp_repr_parent(parent); + g_return_if_fail(grandparent); + + parent->removeChild(repr); + grandparent->addChild(repr, parent); + + sp_document_done(current_document); + set_tree_select(repr); + set_dt_select(repr); + +} // end of cmd_unindent_node() + + +/* + 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:textwidth=99 : diff --git a/src/dialogs/xml-tree.h b/src/dialogs/xml-tree.h new file mode 100644 index 000000000..6d0d44a7d --- /dev/null +++ b/src/dialogs/xml-tree.h @@ -0,0 +1,29 @@ +#ifndef SP_XML_TREE_H +#define SP_XML_TREE_H + +/** + * \brief XML tree editing dialog for Inkscape + * + * Copyright Lauris Kaplinski, 2000 + * + * Released under GNU General Public License. + * + * This is XML tree editor, which allows direct modifying of all elements + * of Inkscape document, including foreign ones. + * + */ + +void sp_xml_tree_dialog (void); + +#endif + +/* + 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:textwidth=99 : diff --git a/src/dir-util-test.cpp b/src/dir-util-test.cpp new file mode 100644 index 000000000..691f6fee1 --- /dev/null +++ b/src/dir-util-test.cpp @@ -0,0 +1,48 @@ +#include "utest/test-2ary-cases.h" +#include "dir-util.h" +#include "streq.h" + +struct streq_functor { + bool operator()(char const *a, char const *b) + { + return streq(a, b); + } +}; + +static bool +test_sp_relative_path_from_path() +{ + utest_start("sp_relative_path_from_path"); + struct Case2 cases[] = { + {"/foo/bar", "/foo", "bar"}, + {"/foo/barney", "/foo/bar", "/foo/barney"}, + {"/foo/bar/baz", "/foo/", "bar/baz"}, + {"/foo/bar/baz", "/", "foo/bar/baz"}, + {"/foo/bar/baz", "/foo/qux", "/foo/bar/baz"}, + {"/foo", NULL, "/foo"} + }; + test_2ary_cases + ("sp_relative_path_from_path", + sp_relative_path_from_path, + G_N_ELEMENTS(cases), cases); + return utest_end(); +} + +int main() +{ + return ( test_sp_relative_path_from_path() + ? EXIT_SUCCESS + : EXIT_FAILURE ); +} + + +/* + 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:textwidth=99 : diff --git a/src/dir-util.cpp b/src/dir-util.cpp new file mode 100644 index 000000000..b83eec002 --- /dev/null +++ b/src/dir-util.cpp @@ -0,0 +1,278 @@ +/** \file Some utility functions for filenames. */ + +#define DIR_UTIL_C + +#include +#include +#include +#include +#include +#include +#include + +/** Returns a form of \a path relative to \a base if that is easy to construct (e.g. if \a path + appears to be in the directory specified by \a base), otherwise returns \a path. + + N.B. The return value is a pointer into the \a path string. + + \a base is expected to be either NULL or the absolute path of a directory. + + \a path is expected to be an absolute path. + + \see inkscape_abs2rel for a more sophisticated version. + \see prepend_current_dir_if_relative. +*/ +char const * +sp_relative_path_from_path(char const *const path, char const *const base) +{ + if (base == NULL || path == NULL) { + return path; + } + + size_t base_len = strlen(base); + while (base_len != 0 + && (base[base_len - 1] == G_DIR_SEPARATOR)) + { + --base_len; + } + + if ((memcmp(path, base, base_len) == 0) + && (path[base_len] == G_DIR_SEPARATOR)) + { + char const *ret = path + base_len + 1; + while (*ret == G_DIR_SEPARATOR) { + ++ret; + } + if (*ret != '\0') { + return ret; + } + } + + return path; +} + +char const * +sp_extension_from_path(char const *const path) +{ + if (path == NULL) { + return NULL; + } + + char const *p = path; + while (*p != '\0') p++; + + while ((p >= path) && (*p != G_DIR_SEPARATOR) && (*p != '.')) p--; + if (* p != '.') return NULL; + p++; + + return p; +} + + +/* current == "./", parent == "../" */ +static char const dots[] = {'.', '.', G_DIR_SEPARATOR, '\0'}; +static char const *const parent = dots; +static char const *const current = dots + 1; + +/** + * \brief Convert a relative path name into absolute. If path is already absolute, does nothing except copying path to result. + * + * \param path relative path + * \param base base directory (must be absolute path) + * \param result result buffer + * \param size size of result buffer + * \return != NULL: absolute path + * == NULL: error + +\comment + based on functions by Shigio Yamaguchi. + FIXME:TODO: force it to also do path normalization of the entire resulting path, + i.e. get rid of any .. and . in any place, even if 'path' is already absolute + (now it returns it unchanged in this case) + + */ +char * +inkscape_rel2abs (const char *path, const char *base, char *result, const size_t size) +{ + const char *pp, *bp; + /* endp points the last position which is safe in the result buffer. */ + const char *endp = result + size - 1; + char *rp; + int length; + if (*path == G_DIR_SEPARATOR) + { + if (strlen (path) >= size) + goto erange; + strcpy (result, path); + goto finish; + } + else if (*base != G_DIR_SEPARATOR || !size) + { + errno = EINVAL; + return (NULL); + } + else if (size == 1) + goto erange; + if (!strcmp (path, ".") || !strcmp (path, current)) + { + if (strlen (base) >= size) + goto erange; + strcpy (result, base); + /* rp points the last char. */ + rp = result + strlen (base) - 1; + if (*rp == G_DIR_SEPARATOR) + *rp = 0; + else + rp++; + /* rp point NULL char */ + if (*++path == G_DIR_SEPARATOR) + { + /* Append G_DIR_SEPARATOR to the tail of path name. */ + *rp++ = G_DIR_SEPARATOR; + if (rp > endp) + goto erange; + *rp = 0; + } + goto finish; + } + bp = base + strlen (base); + if (*(bp - 1) == G_DIR_SEPARATOR) + --bp; + /* up to root. */ + for (pp = path; *pp && *pp == '.';) + { + if (!strncmp (pp, parent, 3)) + { + pp += 3; + while (bp > base && *--bp != G_DIR_SEPARATOR) + ; + } + else if (!strncmp (pp, current, 2)) + { + pp += 2; + } + else if (!strncmp (pp, "..\0", 3)) + { + pp += 2; + while (bp > base && *--bp != G_DIR_SEPARATOR) + ; + } + else + break; + } + /* down to leaf. */ + length = bp - base; + if (length >= static_cast(size)) + goto erange; + strncpy (result, base, length); + rp = result + length; + if (*pp || *(pp - 1) == G_DIR_SEPARATOR || length == 0) + *rp++ = G_DIR_SEPARATOR; + if (rp + strlen (pp) > endp) + goto erange; + strcpy (rp, pp); +finish: + return result; +erange: + errno = ERANGE; + return (NULL); +} + +char * +inkscape_abs2rel (const char *path, const char *base, char *result, const size_t size) +{ + const char *pp, *bp, *branch; + /* endp points the last position which is safe in the result buffer. */ + const char *endp = result + size - 1; + char *rp; + + if (*path != G_DIR_SEPARATOR) + { + if (strlen (path) >= size) + goto erange; + strcpy (result, path); + goto finish; + } + else if (*base != G_DIR_SEPARATOR || !size) + { + errno = EINVAL; + return (NULL); + } + else if (size == 1) + goto erange; + /* seek to branched point. */ + branch = path; + for (pp = path, bp = base; *pp && *bp && *pp == *bp; pp++, bp++) + if (*pp == G_DIR_SEPARATOR) + branch = pp; + if ((*pp == 0 || *pp == G_DIR_SEPARATOR && *(pp + 1) == 0) && + (*bp == 0 || *bp == G_DIR_SEPARATOR && *(bp + 1) == 0)) + { + rp = result; + *rp++ = '.'; + if (*pp == G_DIR_SEPARATOR || *(pp - 1) == G_DIR_SEPARATOR) + *rp++ = G_DIR_SEPARATOR; + if (rp > endp) + goto erange; + *rp = 0; + goto finish; + } + if (*pp == 0 && *bp == G_DIR_SEPARATOR || *pp == G_DIR_SEPARATOR && *bp == 0) + branch = pp; + /* up to root. */ + rp = result; + for (bp = base + (branch - path); *bp; bp++) + if (*bp == G_DIR_SEPARATOR && *(bp + 1) != 0) + { + if (rp + 3 > endp) + goto erange; + *rp++ = '.'; + *rp++ = '.'; + *rp++ = G_DIR_SEPARATOR; + } + if (rp > endp) + goto erange; + *rp = 0; + /* down to leaf. */ + if (*branch) + { + if (rp + strlen (branch + 1) > endp) + goto erange; + strcpy (rp, branch + 1); + } + else + *--rp = 0; +finish: + return result; +erange: + errno = ERANGE; + return (NULL); +} + +void +prepend_current_dir_if_relative (char **result, const gchar *uri) +{ + if (!uri) { + *(result) = NULL; + return; + } + + char *full_path = (char *) g_malloc (1001); + char *cwd = g_get_current_dir(); + + gsize bytesRead = 0; + gsize bytesWritten = 0; + GError* error = NULL; + gchar* cwd_utf8 = g_filename_to_utf8 ( cwd, + -1, + &bytesRead, + &bytesWritten, + &error); + + inkscape_rel2abs (uri, cwd_utf8, full_path, 1000); + *(result) = g_strdup (full_path); + g_free (full_path); + g_free (cwd); +} + + diff --git a/src/dir-util.h b/src/dir-util.h new file mode 100644 index 000000000..f7d75e8e4 --- /dev/null +++ b/src/dir-util.h @@ -0,0 +1,33 @@ +#ifndef SEEN_DIR_UTIL_H +#define SEEN_DIR_UTIL_H + +/* + * path-util.h + * + * here are functions sp_relative_path & cousins + * maybe they are already implemented in standard libs + * + */ + +#include +#include + +char const *sp_relative_path_from_path(char const *path, char const *base); +char const *sp_extension_from_path(char const *path); +char *inkscape_rel2abs(char const *path, char const *base, char *result, size_t const size); +char *inkscape_abs2rel(char const *path, char const *base, char *result, size_t const size); +void prepend_current_dir_if_relative(char **result, gchar const *uri); + + +#endif /* !SEEN_DIR_UTIL_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:encoding=utf-8:textwidth=99 : diff --git a/src/display/.cvsignore b/src/display/.cvsignore new file mode 100644 index 000000000..49cf2d7a9 --- /dev/null +++ b/src/display/.cvsignore @@ -0,0 +1,7 @@ +.deps +.dirstamp +.libs +Makefile +Makefile.in +makefile +*-test diff --git a/src/display/Makefile_insert b/src/display/Makefile_insert new file mode 100644 index 000000000..de6ec85c2 --- /dev/null +++ b/src/display/Makefile_insert @@ -0,0 +1,66 @@ +## Makefile.am fragment sourced by src/Makefile.am. +# +# Sodipodi GnomeCanvas objects +# Author: Lauris Kaplinski +# +# Here are major objects, used for displaying things +# + +display/all: display/libspdisplay.a + +display/clean: + rm -f display/libspdisplay.a $(display_libspdisplay_a_OBJECTS) + +display/canvas-arena.$(OBJEXT): helper/sp-marshal.h +display/sp-canvas.$(OBJEXT): helper/sp-marshal.h + +display_libspdisplay_a_SOURCES = \ + display/nr-arena-forward.h \ + display/nr-arena.cpp \ + display/nr-arena.h \ + display/nr-arena-item.cpp \ + display/nr-arena-item.h \ + display/nr-arena-group.cpp \ + display/nr-arena-group.h \ + display/nr-arena-image.cpp \ + display/nr-arena-image.h \ + display/nr-arena-shape.cpp \ + display/nr-arena-shape.h \ + display/nr-arena-glyphs.cpp \ + display/nr-arena-glyphs.h \ + display/canvas-arena.cpp \ + display/canvas-arena.h \ + display/bezier-utils.cpp \ + display/bezier-utils.h \ + display/canvas-bpath.cpp \ + display/canvas-bpath.h \ + display/canvas-grid.cpp \ + display/canvas-grid.h \ + display/curve.cpp \ + display/curve.h \ + display/display-forward.h \ + display/gnome-canvas-acetate.cpp \ + display/gnome-canvas-acetate.h \ + display/guideline.cpp \ + display/guideline.h \ + display/nr-gradient-gpl.cpp \ + display/nr-gradient-gpl.h \ + display/nr-plain-stuff-gdk.cpp \ + display/nr-plain-stuff-gdk.h \ + display/nr-plain-stuff.cpp \ + display/nr-plain-stuff.h \ + display/sodipodi-ctrl.cpp \ + display/sodipodi-ctrl.h \ + display/sodipodi-ctrlrect.cpp \ + display/sodipodi-ctrlrect.h \ + display/sp-canvas-util.cpp \ + display/sp-canvas-util.h \ + display/sp-canvas.cpp \ + display/sp-canvas.h \ + display/sp-ctrlline.cpp \ + display/sp-ctrlline.h \ + display/sp-ctrlquadr.cpp \ + display/sp-ctrlquadr.h + +display_bezier_utils_test_SOURCES = display/bezier-utils-test.cpp +display_bezier_utils_test_LDADD = libnr/libnr.a -lglib-2.0 diff --git a/src/display/bezier-utils-test.cpp b/src/display/bezier-utils-test.cpp new file mode 100644 index 000000000..d42672113 --- /dev/null +++ b/src/display/bezier-utils-test.cpp @@ -0,0 +1,334 @@ +#include "../utest/utest.h" +#include +#include /* NR_DF_TEST_CLOSE */ + +/* mental disclaims all responsibility for this evil idea for testing + static functions. The main disadvantages are that we retain the + #define's and `using' directives of the included file. */ +#include "bezier-utils.cpp" + +using NR::Point; + +static bool range_approx_equal(double const a[], double const b[], unsigned len); + +/* (Returns false if NaN encountered.) */ +template +static bool range_equal(T const a[], T const b[], unsigned len) { + for (unsigned i = 0; i < len; ++i) { + if ( a[i] != b[i] ) { + return false; + } + } + return true; +} + +inline bool point_approx_equal(NR::Point const &a, NR::Point const &b, double const eps) +{ + using NR::X; using NR::Y; + return ( NR_DF_TEST_CLOSE(a[X], b[X], eps) && + NR_DF_TEST_CLOSE(a[Y], b[Y], eps) ); +} + +static inline double square(double const x) { + return x * x; +} + +/** Determine whether the found control points are the same as previously found on some developer's + machine. Doesn't call utest__fail, just writes a message to stdout for diagnostic purposes: + the most important test is that the root-mean-square of errors in the estimation are low rather + than that the control points found are the same. +**/ +static void compare_ctlpts(Point const est_b[], Point const exp_est_b[]) +{ + unsigned diff_mask = 0; + for (unsigned i = 0; i < 4; ++i) { + for (unsigned d = 0; d < 2; ++d) { + if ( fabs( est_b[i][d] - exp_est_b[i][d] ) > 1.1e-5 ) { + diff_mask |= 1 << ( i * 2 + d ); + } + } + } + if ( diff_mask != 0 ) { + printf("Warning: got different control points from previously-coded (diffs=0x%x).\n", + diff_mask); + printf(" Previous:"); + for (unsigned i = 0; i < 4; ++i) { + printf(" (%g, %g)", exp_est_b[i][0], exp_est_b[i][1]); // localizing ok + } + putchar('\n'); + printf(" Found: "); + for (unsigned i = 0; i < 4; ++i) { + printf(" (%g, %g)", est_b[i][0], est_b[i][1]); // localizing ok + } + putchar('\n'); + } +} + +static void compare_rms(Point const est_b[], double const t[], Point const d[], unsigned const n, + double const exp_rms_error) +{ + double sum_errsq = 0.0; + for (unsigned i = 0; i < n; ++i) { + Point const fit_pt = bezier_pt(3, est_b, t[i]); + Point const diff = fit_pt - d[i]; + sum_errsq += dot(diff, diff); + } + double const rms_error = sqrt( sum_errsq / n ); + UTEST_ASSERT( rms_error <= exp_rms_error + 1.1e-6 ); + if ( rms_error < exp_rms_error - 1.1e-6 ) { + /* The fitter code appears to have improved [or the floating point calculations differ + on this machine from the machine where exp_rms_error was calculated]. */ + printf("N.B. rms_error regression requirement can be decreased: have rms_error=%g.\n", rms_error); // localizing ok + } +} + +int main(int argc, char *argv[]) { + utest_start("bezier-utils.cpp"); + + UTEST_TEST("copy_without_nans_or_adjacent_duplicates") { + NR::Point const src[] = { + Point(2., 3.), + Point(2., 3.), + Point(0., 0.), + Point(2., 3.), + Point(2., 3.), + Point(1., 9.), + Point(1., 9.) + }; + Point const exp_dest[] = { + Point(2., 3.), + Point(0., 0.), + Point(2., 3.), + Point(1., 9.) + }; + g_assert( G_N_ELEMENTS(src) == 7 ); + Point dest[7]; + struct tst { + unsigned src_ix0; + unsigned src_len; + unsigned exp_dest_ix0; + unsigned exp_dest_len; + } const test_data[] = { + /* src start ix, src len, exp_dest start ix, exp dest len */ + {0, 0, 0, 0}, + {2, 1, 1, 1}, + {0, 1, 0, 1}, + {0, 2, 0, 1}, + {0, 3, 0, 2}, + {1, 3, 0, 3}, + {0, 5, 0, 3}, + {0, 6, 0, 4}, + {0, 7, 0, 4} + }; + for (unsigned i = 0 ; i < G_N_ELEMENTS(test_data) ; ++i) { + tst const &t = test_data[i]; + UTEST_ASSERT( t.exp_dest_len + == copy_without_nans_or_adjacent_duplicates(src + t.src_ix0, + t.src_len, + dest) ); + UTEST_ASSERT(range_equal(dest, + exp_dest + t.exp_dest_ix0, + t.exp_dest_len)); + } + } + + UTEST_TEST("bezier_pt(1)") { + Point const a[] = {Point(2.0, 4.0), + Point(1.0, 8.0)}; + UTEST_ASSERT( bezier_pt(1, a, 0.0) == a[0] ); + UTEST_ASSERT( bezier_pt(1, a, 1.0) == a[1] ); + UTEST_ASSERT( bezier_pt(1, a, 0.5) == Point(1.5, 6.0) ); + double const t[] = {0.5, 0.25, 0.3, 0.6}; + for (unsigned i = 0; i < G_N_ELEMENTS(t); ++i) { + double const ti = t[i], si = 1.0 - ti; + UTEST_ASSERT( bezier_pt(1, a, ti) == si * a[0] + ti * a[1] ); + } + } + + UTEST_TEST("bezier_pt(2)") { + Point const b[] = {Point(1.0, 2.0), + Point(8.0, 4.0), + Point(3.0, 1.0)}; + UTEST_ASSERT( bezier_pt(2, b, 0.0) == b[0] ); + UTEST_ASSERT( bezier_pt(2, b, 1.0) == b[2] ); + UTEST_ASSERT( bezier_pt(2, b, 0.5) == Point(5.0, 2.75) ); + double const t[] = {0.5, 0.25, 0.3, 0.6}; + for (unsigned i = 0; i < G_N_ELEMENTS(t); ++i) { + double const ti = t[i], si = 1.0 - ti; + Point const exp_pt( si*si * b[0] + 2*si*ti * b[1] + ti*ti * b[2] ); + Point const pt(bezier_pt(2, b, ti)); + UTEST_ASSERT(point_approx_equal(pt, exp_pt, 1e-11)); + } + } + + Point const c[] = {Point(1.0, 2.0), + Point(8.0, 4.0), + Point(3.0, 1.0), + Point(-2.0, -4.0)}; + UTEST_TEST("bezier_pt(3)") { + UTEST_ASSERT( bezier_pt(3, c, 0.0) == c[0] ); + UTEST_ASSERT( bezier_pt(3, c, 1.0) == c[3] ); + UTEST_ASSERT( bezier_pt(3, c, 0.5) == Point(4.0, 13.0/8.0) ); + double const t[] = {0.5, 0.25, 0.3, 0.6}; + for (unsigned i = 0; i < G_N_ELEMENTS(t); ++i) { + double const ti = t[i], si = 1.0 - ti; + UTEST_ASSERT( LInfty( bezier_pt(3, c, ti) + - ( si*si*si * c[0] + + 3*si*si*ti * c[1] + + 3*si*ti*ti * c[2] + + ti*ti*ti * c[3] ) ) + < 1e-4 ); + } + } + + struct Err_tst { + Point pt; + double u; + double err; + } const err_tst[] = { + {c[0], 0.0, 0.0}, + {Point(4.0, 13.0/8.0), 0.5, 0.0}, + {Point(4.0, 2.0), 0.5, 9.0/64.0}, + {Point(3.0, 2.0), 0.5, 1.0 + 9.0/64.0}, + {Point(6.0, 2.0), 0.5, 4.0 + 9.0/64.0}, + {c[3], 1.0, 0.0}, + }; + + UTEST_TEST("compute_max_error_ratio") { + Point d[G_N_ELEMENTS(err_tst)]; + double u[G_N_ELEMENTS(err_tst)]; + for (unsigned i = 0; i < G_N_ELEMENTS(err_tst); ++i) { + Err_tst const &t = err_tst[i]; + d[i] = t.pt; + u[i] = t.u; + } + g_assert( G_N_ELEMENTS(u) == G_N_ELEMENTS(d) ); + unsigned max_ix = ~0u; + double const err_ratio = compute_max_error_ratio(d, u, G_N_ELEMENTS(d), c, 1.0, &max_ix); + UTEST_ASSERT( fabs( sqrt(err_tst[4].err) - err_ratio ) < 1e-12 ); + UTEST_ASSERT( max_ix == 4 ); + } + + UTEST_TEST("chord_length_parameterize") { + /* n == 2 */ + { + Point const d[] = {Point(2.9415, -5.8149), + Point(23.021, 4.9814)}; + double u[G_N_ELEMENTS(d)]; + double const exp_u[] = {0.0, 1.0}; + g_assert( G_N_ELEMENTS(u) == G_N_ELEMENTS(exp_u) ); + chord_length_parameterize(d, u, G_N_ELEMENTS(d)); + UTEST_ASSERT(range_equal(u, exp_u, G_N_ELEMENTS(exp_u))); + } + + /* Straight line. */ + { + double const exp_u[] = {0.0, 0.1829, 0.2105, 0.2105, 0.619, 0.815, 0.999, 1.0}; + unsigned const n = G_N_ELEMENTS(exp_u); + Point d[n]; + double u[n]; + Point const a(-23.985, 4.915), b(4.9127, 5.203); + for (unsigned i = 0; i < n; ++i) { + double bi = exp_u[i], ai = 1.0 - bi; + d[i] = ai * a + bi * b; + } + chord_length_parameterize(d, u, n); + UTEST_ASSERT(range_approx_equal(u, exp_u, n)); + } + } + + /* Feed it some points that can be fit exactly with a single bezier segment, and see how + well it manages. */ + Point const src_b[4] = {Point(5., -3.), + Point(8., 0.), + Point(4., 2.), + Point(3., 3.)}; + double const t[] = {0.0, .001, .03, .05, .09, .13, .18, .25, .29, .33, .39, .44, + .51, .57, .62, .69, .75, .81, .91, .93, .97, .98, .999, 1.0}; + unsigned const n = G_N_ELEMENTS(t); + Point d[n]; + for (unsigned i = 0; i < n; ++i) { + d[i] = bezier_pt(3, src_b, t[i]); + } + Point const tHat1(unit_vector( src_b[1] - src_b[0] )); + Point const tHat2(unit_vector( src_b[2] - src_b[3] )); + + UTEST_TEST("generate_bezier") { + Point est_b[4]; + generate_bezier(est_b, d, t, n, tHat1, tHat2, 1.0); + + compare_ctlpts(est_b, src_b); + + /* We're being unfair here in using our t[] rather than best t[] for est_b: we + may over-estimate RMS of errors. */ + compare_rms(est_b, t, d, n, 1e-8); + } + + UTEST_TEST("sp_bezier_fit_cubic_full") { + Point est_b[4]; + int splitpoints[2]; + gint const succ = sp_bezier_fit_cubic_full(est_b, splitpoints, d, n, tHat1, tHat2, square(1.2), 1); + UTEST_ASSERT( succ == 1 ); + + Point const exp_est_b[4] = { + Point(5.000000, -3.000000), + Point(7.5753, -0.4247), + Point(4.77533, 1.22467), + Point(3, 3) + }; + compare_ctlpts(est_b, exp_est_b); + + /* We're being unfair here in using our t[] rather than best t[] for est_b: we + may over-estimate RMS of errors. */ + compare_rms(est_b, t, d, n, .307911); + } + + UTEST_TEST("sp_bezier_fit_cubic") { + Point est_b[4]; + gint const succ = sp_bezier_fit_cubic(est_b, d, n, square(1.2)); + UTEST_ASSERT( succ == 1 ); + + Point const exp_est_b[4] = { + Point(5.000000, -3.000000), + Point(7.57134, -0.423509), + Point(4.77929, 1.22426), + Point(3, 3) + }; + compare_ctlpts(est_b, exp_est_b); + +#if 1 /* A change has been made to right_tangent. I believe that usually this change + will result in better fitting, but it won't do as well for this example where + we happen to be feeding a t=0.999 point to the fitter. */ + printf("TODO: Update this test case for revised right_tangent implementation.\n"); + /* In particular, have a test case to show whether the new implementation + really is likely to be better on average. */ +#else + /* We're being unfair here in using our t[] rather than best t[] for est_b: we + may over-estimate RMS of errors. */ + compare_rms(est_b, t, d, n, .307983); +#endif + } + + return !utest_end(); +} + +/* (Returns false if NaN encountered.) */ +static bool range_approx_equal(double const a[], double const b[], unsigned const len) { + for (unsigned i = 0; i < len; ++i) { + if (!( fabs( a[i] - b[i] ) < 1e-4 )) { + return false; + } + } + return true; +} + +/* + 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:textwidth=99 : diff --git a/src/display/bezier-utils-work.txt b/src/display/bezier-utils-work.txt new file mode 100644 index 000000000..8604c1207 --- /dev/null +++ b/src/display/bezier-utils-work.txt @@ -0,0 +1,34 @@ +min .5 * sum_i lensq(bez_pt(b, u[i]) - d[i]) + +lensq(d)=dot(d, d) = d.x * d.x + d.y * d.y + +sum_i (f(i) + g(i)) = sum_i f(i) + sum_i g(i), so +we can separate into x,y parts. Since they are the same, we write `z' in the below +to mean either x or y. + +.5 * sum_i (bez_pt(b, u[i]) - d[i]).z^2 + += .5 * sum_i (B0(u[i]) * b[0] + + B1(u[i]) * b[1] + + B2(u[i]) * b[2] + + B3(u[i]) * b[3] + - d[i] ).z^2 + += H. + +Suppose that b[0,1,3] are fixed (with b[1] perhaps being calculated +from a prior call to existing generate_bezier). + +d H / d b[2].z = sum_i B2(u[i]) * (bez_pt(b, u[i]) - d[i]).z + +Solve for dH/db[2].z==0: + +-sum_i B2(u[i]) B2(u[i]) * b[2].z = sum_i B2(u[i]) * (B0(u[i]) * b[0] + + B1(u[i]) * b[1] + + B3(u[i]) * b[3] + - d[i] ).z +b[2].z = ((sum_i B2(u[i]) * (B0(u[i]) * b[0] + + B1(u[i]) * b[1] + + B3(u[i]) * b[3] + - d[i] ).z) + / -sum_i (B2(u[i]))^2) diff --git a/src/display/bezier-utils.cpp b/src/display/bezier-utils.cpp new file mode 100644 index 000000000..8316c86cc --- /dev/null +++ b/src/display/bezier-utils.cpp @@ -0,0 +1,983 @@ +#define __SP_BEZIER_UTILS_C__ + +/** \file + * Bezier interpolation for inkscape drawing code. + */ +/* + * Original code published in: + * An Algorithm for Automatically Fitting Digitized Curves + * by Philip J. Schneider + * "Graphics Gems", Academic Press, 1990 + * + * Authors: + * Philip J. Schneider + * Lauris Kaplinski + * Peter Moulder + * + * Copyright (C) 1990 Philip J. Schneider + * Copyright (C) 2001 Lauris Kaplinski + * Copyright (C) 2001 Ximian, Inc. + * Copyright (C) 2003,2004 Monash University + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#define SP_HUGE 1e5 +#define noBEZIER_DEBUG + +#ifdef HAVE_CONFIG_H +# include +#endif + +#ifdef HAVE_IEEEFP_H +# include +#endif + +#include +#include +#include "bezier-utils.h" +#include + +#include "isnan.h" + + +typedef NR::Point BezierCurve[]; + +/* Forward declarations */ +static void generate_bezier(NR::Point b[], NR::Point const d[], gdouble const u[], unsigned len, + NR::Point const &tHat1, NR::Point const &tHat2, double tolerance_sq); +static void estimate_lengths(NR::Point bezier[], + NR::Point const data[], gdouble const u[], unsigned len, + NR::Point const &tHat1, NR::Point const &tHat2); +static void estimate_bi(NR::Point b[4], unsigned ei, + NR::Point const data[], double const u[], unsigned len); +static void reparameterize(NR::Point const d[], unsigned len, double u[], BezierCurve const bezCurve); +static gdouble NewtonRaphsonRootFind(BezierCurve const Q, NR::Point const &P, gdouble u); +static NR::Point bezier_pt(unsigned degree, NR::Point const V[], gdouble t); +static NR::Point sp_darray_center_tangent(NR::Point const d[], unsigned center, unsigned length); +static NR::Point sp_darray_right_tangent(NR::Point const d[], unsigned const len); +static unsigned copy_without_nans_or_adjacent_duplicates(NR::Point const src[], unsigned src_len, NR::Point dest[]); +static void chord_length_parameterize(NR::Point const d[], gdouble u[], unsigned len); +static double compute_max_error_ratio(NR::Point const d[], double const u[], unsigned len, + BezierCurve const bezCurve, double tolerance, + unsigned *splitPoint); +static double compute_hook(NR::Point const &a, NR::Point const &b, double const u, BezierCurve const bezCurve, + double const tolerance); + + +static NR::Point const unconstrained_tangent(0, 0); + + +/* + * B0, B1, B2, B3 : Bezier multipliers + */ + +#define B0(u) ( ( 1.0 - u ) * ( 1.0 - u ) * ( 1.0 - u ) ) +#define B1(u) ( 3 * u * ( 1.0 - u ) * ( 1.0 - u ) ) +#define B2(u) ( 3 * u * u * ( 1.0 - u ) ) +#define B3(u) ( u * u * u ) + +#ifdef BEZIER_DEBUG +# define DOUBLE_ASSERT(x) g_assert( ( (x) > -SP_HUGE ) && ( (x) < SP_HUGE ) ) +# define BEZIER_ASSERT(b) do { \ + DOUBLE_ASSERT((b)[0][NR::X]); DOUBLE_ASSERT((b)[0][NR::Y]); \ + DOUBLE_ASSERT((b)[1][NR::X]); DOUBLE_ASSERT((b)[1][NR::Y]); \ + DOUBLE_ASSERT((b)[2][NR::X]); DOUBLE_ASSERT((b)[2][NR::Y]); \ + DOUBLE_ASSERT((b)[3][NR::X]); DOUBLE_ASSERT((b)[3][NR::Y]); \ + } while(0) +#else +# define DOUBLE_ASSERT(x) do { } while(0) +# define BEZIER_ASSERT(b) do { } while(0) +#endif + + +/** + * Fit a single-segment Bezier curve to a set of digitized points. + * + * \return Number of segments generated, or -1 on error. + */ +gint +sp_bezier_fit_cubic(NR::Point *bezier, NR::Point const *data, gint len, gdouble error) +{ + return sp_bezier_fit_cubic_r(bezier, data, len, error, 1); +} + +/** + * Fit a multi-segment Bezier curve to a set of digitized points, with + * possible weedout of identical points and NaNs. + * + * \param max_beziers Maximum number of generated segments + * \param Result array, must be large enough for n. segments * 4 elements. + * + * \return Number of segments generated, or -1 on error. + */ +gint +sp_bezier_fit_cubic_r(NR::Point bezier[], NR::Point const data[], gint const len, gdouble const error, unsigned const max_beziers) +{ + g_return_val_if_fail(bezier != NULL, -1); + g_return_val_if_fail(data != NULL, -1); + g_return_val_if_fail(len > 0, -1); + g_return_val_if_fail(max_beziers < (1ul << (31 - 2 - 1 - 3)), -1); + + NR::Point *uniqued_data = g_new(NR::Point, len); + unsigned uniqued_len = copy_without_nans_or_adjacent_duplicates(data, len, uniqued_data); + + if ( uniqued_len < 2 ) { + g_free(uniqued_data); + return 0; + } + + /* Call fit-cubic function with recursion. */ + gint const ret = sp_bezier_fit_cubic_full(bezier, NULL, uniqued_data, uniqued_len, + unconstrained_tangent, unconstrained_tangent, + error, max_beziers); + g_free(uniqued_data); + return ret; +} + +/** + * Copy points from src to dest, filter out points containing NaN and + * adjacent points with equal x and y. + * \return length of dest + */ +static unsigned +copy_without_nans_or_adjacent_duplicates(NR::Point const src[], unsigned src_len, NR::Point dest[]) +{ + unsigned si = 0; + for (;;) { + if ( si == src_len ) { + return 0; + } + if (!isNaN(src[si][NR::X]) && + !isNaN(src[si][NR::Y])) { + dest[0] = NR::Point(src[si]); + ++si; + break; + } + } + unsigned di = 0; + for (; si < src_len; ++si) { + NR::Point const src_pt = NR::Point(src[si]); + if ( src_pt != dest[di] + && !isNaN(src_pt[NR::X]) + && !isNaN(src_pt[NR::Y])) { + dest[++di] = src_pt; + } + } + unsigned dest_len = di + 1; + g_assert( dest_len <= src_len ); + return dest_len; +} + +/** + * Fit a multi-segment Bezier curve to a set of digitized points, without + * possible weedout of identical points and NaNs. + * + * \pre data is uniqued, i.e. not exist i: data[i] == data[i + 1]. + * \param max_beziers Maximum number of generated segments + * \param Result array, must be large enough for n. segments * 4 elements. + */ +gint +sp_bezier_fit_cubic_full(NR::Point bezier[], int split_points[], + NR::Point const data[], gint const len, + NR::Point const &tHat1, NR::Point const &tHat2, + double const error, unsigned const max_beziers) +{ + int const maxIterations = 4; /* Max times to try iterating */ + + g_return_val_if_fail(bezier != NULL, -1); + g_return_val_if_fail(data != NULL, -1); + g_return_val_if_fail(len > 0, -1); + g_return_val_if_fail(max_beziers >= 1, -1); + g_return_val_if_fail(error >= 0.0, -1); + + if ( len < 2 ) return 0; + + if ( len == 2 ) { + /* We have 2 points, which can be fitted trivially. */ + bezier[0] = data[0]; + bezier[3] = data[len - 1]; + double const dist = ( L2( data[len - 1] + - data[0] ) + / 3.0 ); + if (isNaN(dist)) { + /* Numerical problem, fall back to straight line segment. */ + bezier[1] = bezier[0]; + bezier[2] = bezier[3]; + } else { + bezier[1] = ( is_zero(tHat1) + ? ( 2 * bezier[0] + bezier[3] ) / 3. + : bezier[0] + dist * tHat1 ); + bezier[2] = ( is_zero(tHat2) + ? ( bezier[0] + 2 * bezier[3] ) / 3. + : bezier[3] + dist * tHat2 ); + } + BEZIER_ASSERT(bezier); + return 1; + } + + /* Parameterize points, and attempt to fit curve */ + unsigned splitPoint; /* Point to split point set at. */ + bool is_corner; + { + double *u = g_new(double, len); + chord_length_parameterize(data, u, len); + if ( u[len - 1] == 0.0 ) { + /* Zero-length path: every point in data[] is the same. + * + * (Clients aren't allowed to pass such data; handling the case is defensive + * programming.) + */ + g_free(u); + return 0; + } + + generate_bezier(bezier, data, u, len, tHat1, tHat2, error); + reparameterize(data, len, u, bezier); + + /* Find max deviation of points to fitted curve. */ + double const tolerance = sqrt(error + 1e-9); + double maxErrorRatio = compute_max_error_ratio(data, u, len, bezier, tolerance, &splitPoint); + + if ( fabs(maxErrorRatio) <= 1.0 ) { + BEZIER_ASSERT(bezier); + g_free(u); + return 1; + } + + /* If error not too large, then try some reparameterization and iteration. */ + if ( 0.0 <= maxErrorRatio && maxErrorRatio <= 3.0 ) { + for (int i = 0; i < maxIterations; i++) { + generate_bezier(bezier, data, u, len, tHat1, tHat2, error); + reparameterize(data, len, u, bezier); + maxErrorRatio = compute_max_error_ratio(data, u, len, bezier, tolerance, &splitPoint); + if ( fabs(maxErrorRatio) <= 1.0 ) { + BEZIER_ASSERT(bezier); + g_free(u); + return 1; + } + } + } + g_free(u); + is_corner = (maxErrorRatio < 0); + } + + if (is_corner) { + g_assert(splitPoint < unsigned(len)); + if (splitPoint == 0) { + if (is_zero(tHat1)) { + /* Got spike even with unconstrained initial tangent. */ + ++splitPoint; + } else { + return sp_bezier_fit_cubic_full(bezier, split_points, data, len, unconstrained_tangent, tHat2, + error, max_beziers); + } + } else if (splitPoint == unsigned(len - 1)) { + if (is_zero(tHat2)) { + /* Got spike even with unconstrained final tangent. */ + --splitPoint; + } else { + return sp_bezier_fit_cubic_full(bezier, split_points, data, len, tHat1, unconstrained_tangent, + error, max_beziers); + } + } + } + + if ( 1 < max_beziers ) { + /* + * Fitting failed -- split at max error point and fit recursively + */ + unsigned const rec_max_beziers1 = max_beziers - 1; + + NR::Point recTHat2, recTHat1; + if (is_corner) { + g_return_val_if_fail(0 < splitPoint && splitPoint < unsigned(len - 1), -1); + recTHat1 = recTHat2 = unconstrained_tangent; + } else { + /* Unit tangent vector at splitPoint. */ + recTHat2 = sp_darray_center_tangent(data, splitPoint, len); + recTHat1 = -recTHat2; + } + gint const nsegs1 = sp_bezier_fit_cubic_full(bezier, split_points, data, splitPoint + 1, + tHat1, recTHat2, error, rec_max_beziers1); + if ( nsegs1 < 0 ) { +#ifdef BEZIER_DEBUG + g_print("fit_cubic[1]: recursive call failed\n"); +#endif + return -1; + } + g_assert( nsegs1 != 0 ); + if (split_points != NULL) { + split_points[nsegs1 - 1] = splitPoint; + } + unsigned const rec_max_beziers2 = max_beziers - nsegs1; + gint const nsegs2 = sp_bezier_fit_cubic_full(bezier + nsegs1*4, + ( split_points == NULL + ? NULL + : split_points + nsegs1 ), + data + splitPoint, len - splitPoint, + recTHat1, tHat2, error, rec_max_beziers2); + if ( nsegs2 < 0 ) { +#ifdef BEZIER_DEBUG + g_print("fit_cubic[2]: recursive call failed\n"); +#endif + return -1; + } + +#ifdef BEZIER_DEBUG + g_print("fit_cubic: success[nsegs: %d+%d=%d] on max_beziers:%u\n", + nsegs1, nsegs2, nsegs1 + nsegs2, max_beziers); +#endif + return nsegs1 + nsegs2; + } else { + return -1; + } +} + + +/** + * Fill in \a bezier[] based on the given data and tangent requirements, using + * a least-squares fit. + * + * Each of tHat1 and tHat2 should be either a zero vector or a unit vector. + * If it is zero, then bezier[1 or 2] is estimated without constraint; otherwise, + * it bezier[1 or 2] is placed in the specified direction from bezier[0 or 3]. + * + * \param tolerance_sq Used only for an initial guess as to tangent directions + * when \a tHat1 or \a tHat2 is zero. + */ +static void +generate_bezier(NR::Point bezier[], + NR::Point const data[], gdouble const u[], unsigned const len, + NR::Point const &tHat1, NR::Point const &tHat2, + double const tolerance_sq) +{ + bool const est1 = is_zero(tHat1); + bool const est2 = is_zero(tHat2); + NR::Point est_tHat1( est1 + ? sp_darray_left_tangent(data, len, tolerance_sq) + : tHat1 ); + NR::Point est_tHat2( est2 + ? sp_darray_right_tangent(data, len, tolerance_sq) + : tHat2 ); + estimate_lengths(bezier, data, u, len, est_tHat1, est_tHat2); + /* We find that sp_darray_right_tangent tends to produce better results + for our current freehand tool than full estimation. */ + if (est1) { + estimate_bi(bezier, 1, data, u, len); + if (bezier[1] != bezier[0]) { + est_tHat1 = unit_vector(bezier[1] - bezier[0]); + } + estimate_lengths(bezier, data, u, len, est_tHat1, est_tHat2); + } +} + + +static void +estimate_lengths(NR::Point bezier[], + NR::Point const data[], gdouble const uPrime[], unsigned const len, + NR::Point const &tHat1, NR::Point const &tHat2) +{ + double C[2][2]; /* Matrix C. */ + double X[2]; /* Matrix X. */ + + /* Create the C and X matrices. */ + C[0][0] = 0.0; + C[0][1] = 0.0; + C[1][0] = 0.0; + C[1][1] = 0.0; + X[0] = 0.0; + X[1] = 0.0; + + /* First and last control points of the Bezier curve are positioned exactly at the first and + last data points. */ + bezier[0] = data[0]; + bezier[3] = data[len - 1]; + + for (unsigned i = 0; i < len; i++) { + /* Bezier control point coefficients. */ + double const b0 = B0(uPrime[i]); + double const b1 = B1(uPrime[i]); + double const b2 = B2(uPrime[i]); + double const b3 = B3(uPrime[i]); + + /* rhs for eqn */ + NR::Point const a1 = b1 * tHat1; + NR::Point const a2 = b2 * tHat2; + + C[0][0] += dot(a1, a1); + C[0][1] += dot(a1, a2); + C[1][0] = C[0][1]; + C[1][1] += dot(a2, a2); + + /* Additional offset to the data point from the predicted point if we were to set bezier[1] + to bezier[0] and bezier[2] to bezier[3]. */ + NR::Point const shortfall + = ( data[i] + - ( ( b0 + b1 ) * bezier[0] ) + - ( ( b2 + b3 ) * bezier[3] ) ); + X[0] += dot(a1, shortfall); + X[1] += dot(a2, shortfall); + } + + /* We've constructed a pair of equations in the form of a matrix product C * alpha = X. + Now solve for alpha. */ + double alpha_l, alpha_r; + + /* Compute the determinants of C and X. */ + double const det_C0_C1 = C[0][0] * C[1][1] - C[1][0] * C[0][1]; + if ( det_C0_C1 != 0 ) { + /* Apparently Kramer's rule. */ + double const det_C0_X = C[0][0] * X[1] - C[0][1] * X[0]; + double const det_X_C1 = X[0] * C[1][1] - X[1] * C[0][1]; + alpha_l = det_X_C1 / det_C0_C1; + alpha_r = det_C0_X / det_C0_C1; + } else { + /* The matrix is under-determined. Try requiring alpha_l == alpha_r. + * + * One way of implementing the constraint alpha_l == alpha_r is to treat them as the same + * variable in the equations. We can do this by adding the columns of C to form a single + * column, to be multiplied by alpha to give the column vector X. + * + * We try each row in turn. + */ + double const c0 = C[0][0] + C[0][1]; + if (c0 != 0) { + alpha_l = alpha_r = X[0] / c0; + } else { + double const c1 = C[1][0] + C[1][1]; + if (c1 != 0) { + alpha_l = alpha_r = X[1] / c1; + } else { + /* Let the below code handle this. */ + alpha_l = alpha_r = 0.; + } + } + } + + /* If alpha negative, use the Wu/Barsky heuristic (see text). (If alpha is 0, you get + coincident control points that lead to divide by zero in any subsequent + NewtonRaphsonRootFind() call.) */ + /// \todo Check whether this special-casing is necessary now that + /// NewtonRaphsonRootFind handles non-positive denominator. + if ( alpha_l < 1.0e-6 || + alpha_r < 1.0e-6 ) + { + alpha_l = alpha_r = ( L2( data[len - 1] + - data[0] ) + / 3.0 ); + } + + /* Control points 1 and 2 are positioned an alpha distance out on the tangent vectors, left and + right, respectively. */ + bezier[1] = alpha_l * tHat1 + bezier[0]; + bezier[2] = alpha_r * tHat2 + bezier[3]; + + return; +} + +static double lensq(NR::Point const p) { + return dot(p, p); +} + +static void +estimate_bi(NR::Point bezier[4], unsigned const ei, + NR::Point const data[], double const u[], unsigned const len) +{ + g_return_if_fail(1 <= ei && ei <= 2); + unsigned const oi = 3 - ei; + double num[2] = {0., 0.}; + double den = 0.; + for (unsigned i = 0; i < len; ++i) { + double const ui = u[i]; + double const b[4] = { + B0(ui), + B1(ui), + B2(ui), + B3(ui) + }; + + for (unsigned d = 0; d < 2; ++d) { + num[d] += b[ei] * (b[0] * bezier[0][d] + + b[oi] * bezier[oi][d] + + b[3] * bezier[3][d] + + - data[i][d]); + } + den -= b[ei] * b[ei]; + } + + if (den != 0.) { + for (unsigned d = 0; d < 2; ++d) { + bezier[ei][d] = num[d] / den; + } + } else { + bezier[ei] = ( oi * bezier[0] + ei * bezier[3] ) / 3.; + } +} + +/** + * Given set of points and their parameterization, try to find a better assignment of parameter + * values for the points. + * + * \param d Array of digitized points. + * \param u Current parameter values. + * \param bezCurve Current fitted curve. + * \param len Number of values in both d and u arrays. + * Also the size of the array that is allocated for return. + */ +static void +reparameterize(NR::Point const d[], + unsigned const len, + double u[], + BezierCurve const bezCurve) +{ + g_assert( 2 <= len ); + + unsigned const last = len - 1; + g_assert( bezCurve[0] == d[0] ); + g_assert( bezCurve[3] == d[last] ); + g_assert( u[0] == 0.0 ); + g_assert( u[last] == 1.0 ); + /* Otherwise, consider including 0 and last in the below loop. */ + + for (unsigned i = 1; i < last; i++) { + u[i] = NewtonRaphsonRootFind(bezCurve, d[i], u[i]); + } +} + +/** + * Use Newton-Raphson iteration to find better root. + * + * \param Q Current fitted curve + * \param P Digitized point + * \param u Parameter value for "P" + * + * \return Improved u + */ +static gdouble +NewtonRaphsonRootFind(BezierCurve const Q, NR::Point const &P, gdouble const u) +{ + g_assert( 0.0 <= u ); + g_assert( u <= 1.0 ); + + /* Generate control vertices for Q'. */ + NR::Point Q1[3]; + for (unsigned i = 0; i < 3; i++) { + Q1[i] = 3.0 * ( Q[i+1] - Q[i] ); + } + + /* Generate control vertices for Q''. */ + NR::Point Q2[2]; + for (unsigned i = 0; i < 2; i++) { + Q2[i] = 2.0 * ( Q1[i+1] - Q1[i] ); + } + + /* Compute Q(u), Q'(u) and Q''(u). */ + NR::Point const Q_u = bezier_pt(3, Q, u); + NR::Point const Q1_u = bezier_pt(2, Q1, u); + NR::Point const Q2_u = bezier_pt(1, Q2, u); + + /* Compute f(u)/f'(u), where f is the derivative wrt u of distsq(u) = 0.5 * the square of the + distance from P to Q(u). Here we're using Newton-Raphson to find a stationary point in the + distsq(u), hopefully corresponding to a local minimum in distsq (and hence a local minimum + distance from P to Q(u)). */ + NR::Point const diff = Q_u - P; + double numerator = dot(diff, Q1_u); + double denominator = dot(Q1_u, Q1_u) + dot(diff, Q2_u); + + double improved_u; + if ( denominator > 0. ) { + /* One iteration of Newton-Raphson: + improved_u = u - f(u)/f'(u) */ + improved_u = u - ( numerator / denominator ); + } else { + /* Using Newton-Raphson would move in the wrong direction (towards a local maximum rather + than local minimum), so we move an arbitrary amount in the right direction. */ + if ( numerator > 0. ) { + improved_u = u * .98 - .01; + } else if ( numerator < 0. ) { + /* Deliberately asymmetrical, to reduce the chance of cycling. */ + improved_u = .031 + u * .98; + } else { + improved_u = u; + } + } + + if (!isFinite(improved_u)) { + improved_u = u; + } else if ( improved_u < 0.0 ) { + improved_u = 0.0; + } else if ( improved_u > 1.0 ) { + improved_u = 1.0; + } + + /* Ensure that improved_u isn't actually worse. */ + { + double const diff_lensq = lensq(diff); + for (double proportion = .125; ; proportion += .125) { + if ( lensq( bezier_pt(3, Q, improved_u) - P ) > diff_lensq ) { + if ( proportion > 1.0 ) { + //g_warning("found proportion %g", proportion); + improved_u = u; + break; + } + improved_u = ( ( 1 - proportion ) * improved_u + + proportion * u ); + } else { + break; + } + } + } + + DOUBLE_ASSERT(improved_u); + return improved_u; +} + +/** + * Evaluate a Bezier curve at parameter value \a t. + * + * \param degree The degree of the Bezier curve: 3 for cubic, 2 for quadratic etc. + * \param V The control points for the Bezier curve. Must have (\a degree+1) + * elements. + * \param t The "parameter" value, specifying whereabouts along the curve to + * evaluate. Typically in the range [0.0, 1.0]. + * + * Let s = 1 - t. + * BezierII(1, V) gives (s, t) * V, i.e. t of the way + * from V[0] to V[1]. + * BezierII(2, V) gives (s**2, 2*s*t, t**2) * V. + * BezierII(3, V) gives (s**3, 3 s**2 t, 3s t**2, t**3) * V. + * + * The derivative of BezierII(i, V) with respect to t + * is i * BezierII(i-1, V'), where for all j, V'[j] = + * V[j + 1] - V[j]. + */ +static NR::Point +bezier_pt(unsigned const degree, NR::Point const V[], gdouble const t) +{ + /** Pascal's triangle. */ + static int const pascal[4][4] = {{1}, + {1, 1}, + {1, 2, 1}, + {1, 3, 3, 1}}; + g_assert( degree < G_N_ELEMENTS(pascal) ); + gdouble const s = 1.0 - t; + + /* Calculate powers of t and s. */ + double spow[4]; + double tpow[4]; + spow[0] = 1.0; spow[1] = s; + tpow[0] = 1.0; tpow[1] = t; + for (unsigned i = 1; i < degree; ++i) { + spow[i + 1] = spow[i] * s; + tpow[i + 1] = tpow[i] * t; + } + + NR::Point ret = spow[degree] * V[0]; + for (unsigned i = 1; i <= degree; ++i) { + ret += pascal[degree][i] * spow[degree - i] * tpow[i] * V[i]; + } + return ret; +} + +/* + * ComputeLeftTangent, ComputeRightTangent, ComputeCenterTangent : + * Approximate unit tangents at endpoints and "center" of digitized curve + */ + +/** + * Estimate the (forward) tangent at point d[first + 0.5]. + * + * Unlike the center and right versions, this calculates the tangent in + * the way one might expect, i.e., wrt increasing index into d. + * \pre (2 \<= len) and (d[0] != d[1]). + **/ +NR::Point +sp_darray_left_tangent(NR::Point const d[], unsigned const len) +{ + g_assert( len >= 2 ); + g_assert( d[0] != d[1] ); + return unit_vector( d[1] - d[0] ); +} + +/** + * Estimates the (backward) tangent at d[last - 0.5]. + * + * \note The tangent is "backwards", i.e. it is with respect to + * decreasing index rather than increasing index. + * + * \pre 2 \<= len. + * \pre d[len - 1] != d[len - 2]. + * \pre all[p in d] in_svg_plane(p). + */ +static NR::Point +sp_darray_right_tangent(NR::Point const d[], unsigned const len) +{ + g_assert( 2 <= len ); + unsigned const last = len - 1; + unsigned const prev = last - 1; + g_assert( d[last] != d[prev] ); + return unit_vector( d[prev] - d[last] ); +} + +/** + * Estimate the (forward) tangent at point d[0]. + * + * Unlike the center and right versions, this calculates the tangent in + * the way one might expect, i.e., wrt increasing index into d. + * + * \pre 2 \<= len. + * \pre d[0] != d[1]. + * \pre all[p in d] in_svg_plane(p). + * \post is_unit_vector(ret). + **/ +NR::Point +sp_darray_left_tangent(NR::Point const d[], unsigned const len, double const tolerance_sq) +{ + g_assert( 2 <= len ); + g_assert( 0 <= tolerance_sq ); + for (unsigned i = 1;;) { + NR::Point const pi(d[i]); + NR::Point const t(pi - d[0]); + double const distsq = dot(t, t); + if ( tolerance_sq < distsq ) { + return unit_vector(t); + } + ++i; + if (i == len) { + return ( distsq == 0 + ? sp_darray_left_tangent(d, len) + : unit_vector(t) ); + } + } +} + +/** + * Estimates the (backward) tangent at d[last]. + * + * \note The tangent is "backwards", i.e. it is with respect to + * decreasing index rather than increasing index. + * + * \pre 2 \<= len. + * \pre d[len - 1] != d[len - 2]. + * \pre all[p in d] in_svg_plane(p). + */ +NR::Point +sp_darray_right_tangent(NR::Point const d[], unsigned const len, double const tolerance_sq) +{ + g_assert( 2 <= len ); + g_assert( 0 <= tolerance_sq ); + unsigned const last = len - 1; + for (unsigned i = last - 1;; i--) { + NR::Point const pi(d[i]); + NR::Point const t(pi - d[last]); + double const distsq = dot(t, t); + if ( tolerance_sq < distsq ) { + return unit_vector(t); + } + if (i == 0) { + return ( distsq == 0 + ? sp_darray_right_tangent(d, len) + : unit_vector(t) ); + } + } +} + +/** + * Estimates the (backward) tangent at d[center], by averaging the two + * segments connected to d[center] (and then normalizing the result). + * + * \note The tangent is "backwards", i.e. it is with respect to + * decreasing index rather than increasing index. + * + * \pre (0 \< center \< len - 1) and d is uniqued (at least in + * the immediate vicinity of \a center). + */ +static NR::Point +sp_darray_center_tangent(NR::Point const d[], + unsigned const center, + unsigned const len) +{ + g_assert( center != 0 ); + g_assert( center < len - 1 ); + + NR::Point ret; + if ( d[center + 1] == d[center - 1] ) { + /* Rotate 90 degrees in an arbitrary direction. */ + NR::Point const diff = d[center] - d[center - 1]; + ret = NR::rot90(diff); + } else { + ret = d[center - 1] - d[center + 1]; + } + ret.normalize(); + return ret; +} + + +/** + * Assign parameter values to digitized points using relative distances between points. + * + * \pre Parameter array u must have space for \a len items. + */ +static void +chord_length_parameterize(NR::Point const d[], gdouble u[], unsigned const len) +{ + g_return_if_fail( 2 <= len ); + + /* First let u[i] equal the distance travelled along the path from d[0] to d[i]. */ + u[0] = 0.0; + for (unsigned i = 1; i < len; i++) { + double const dist = L2( d[i] - d[i-1] ); + u[i] = u[i-1] + dist; + } + + /* Then scale to [0.0 .. 1.0]. */ + gdouble tot_len = u[len - 1]; + g_return_if_fail( tot_len != 0 ); + if (isFinite(tot_len)) { + for (unsigned i = 1; i < len; ++i) { + u[i] /= tot_len; + } + } else { + /* We could do better, but this probably never happens anyway. */ + for (unsigned i = 1; i < len; ++i) { + u[i] = i / (gdouble) ( len - 1 ); + } + } + + /** \todo + * It's been reported that u[len - 1] can differ from 1.0 on some + * systems (amd64), despite it having been calculated as x / x where x + * is isFinite and non-zero. + */ + if (u[len - 1] != 1) { + double const diff = u[len - 1] - 1; + if (fabs(diff) > 1e-13) { + g_warning("u[len - 1] = %19g (= 1 + %19g), expecting exactly 1", + u[len - 1], diff); + } + u[len - 1] = 1; + } + +#ifdef BEZIER_DEBUG + g_assert( u[0] == 0.0 && u[len - 1] == 1.0 ); + for (unsigned i = 1; i < len; i++) { + g_assert( u[i] >= u[i-1] ); + } +#endif +} + + + + +/** + * Find the maximum squared distance of digitized points to fitted curve, and (if this maximum + * error is non-zero) set \a *splitPoint to the corresponding index. + * + * \pre 2 \<= len. + * \pre u[0] == 0. + * \pre u[len - 1] == 1.0. + * \post ((ret == 0.0) + * || ((*splitPoint \< len - 1) + * \&\& (*splitPoint != 0 || ret \< 0.0))). + */ +static gdouble +compute_max_error_ratio(NR::Point const d[], double const u[], unsigned const len, + BezierCurve const bezCurve, double const tolerance, + unsigned *const splitPoint) +{ + g_assert( 2 <= len ); + unsigned const last = len - 1; + g_assert( bezCurve[0] == d[0] ); + g_assert( bezCurve[3] == d[last] ); + g_assert( u[0] == 0.0 ); + g_assert( u[last] == 1.0 ); + /* I.e. assert that the error for the first & last points is zero. + * Otherwise we should include those points in the below loop. + * The assertion is also necessary to ensure 0 < splitPoint < last. + */ + + double maxDistsq = 0.0; /* Maximum error */ + double max_hook_ratio = 0.0; + unsigned snap_end = 0; + NR::Point prev = bezCurve[0]; + for (unsigned i = 1; i <= last; i++) { + NR::Point const curr = bezier_pt(3, bezCurve, u[i]); + double const distsq = lensq( curr - d[i] ); + if ( distsq > maxDistsq ) { + maxDistsq = distsq; + *splitPoint = i; + } + double const hook_ratio = compute_hook(prev, curr, .5 * (u[i - 1] + u[i]), bezCurve, tolerance); + if (max_hook_ratio < hook_ratio) { + max_hook_ratio = hook_ratio; + snap_end = i; + } + prev = curr; + } + + double const dist_ratio = sqrt(maxDistsq) / tolerance; + double ret; + if (max_hook_ratio <= dist_ratio) { + ret = dist_ratio; + } else { + g_assert(0 < snap_end); + ret = -max_hook_ratio; + *splitPoint = snap_end - 1; + } + g_assert( ret == 0.0 + || ( ( *splitPoint < last ) + && ( *splitPoint != 0 || ret < 0. ) ) ); + return ret; +} + +/** + * Whereas compute_max_error_ratio() checks for itself that each data point + * is near some point on the curve, this function checks that each point on + * the curve is near some data point (or near some point on the polyline + * defined by the data points, or something like that: we allow for a + * "reasonable curviness" from such a polyline). "Reasonable curviness" + * means we draw a circle centred at the midpoint of a..b, of radius + * proportional to the length |a - b|, and require that each point on the + * segment of bezCurve between the parameters of a and b be within that circle. + * If any point P on the bezCurve segment is outside of that allowable + * region (circle), then we return some metric that increases with the + * distance from P to the circle. + * + * Given that this is a fairly arbitrary criterion for finding appropriate + * places for sharp corners, we test only one point on bezCurve, namely + * the point on bezCurve with parameter halfway between our estimated + * parameters for a and b. (Alternatives are taking the farthest of a + * few parameters between those of a and b, or even using a variant of + * NewtonRaphsonFindRoot() for finding the maximum rather than minimum + * distance.) + */ +static double +compute_hook(NR::Point const &a, NR::Point const &b, double const u, BezierCurve const bezCurve, + double const tolerance) +{ + NR::Point const P = bezier_pt(3, bezCurve, u); + NR::Point const diff = .5 * (a + b) - P; + double const dist = NR::L2(diff); + if (dist < tolerance) { + return 0; + } + double const allowed = NR::L2(b - a) + tolerance; + return dist / allowed; + /** \todo + * effic: Hooks are very rare. We could start by comparing + * distsq, only resorting to the more expensive L2 in cases of + * uncertainty. + */ +} + +/* + 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:textwidth=99 : diff --git a/src/display/bezier-utils.h b/src/display/bezier-utils.h new file mode 100644 index 000000000..f281ab220 --- /dev/null +++ b/src/display/bezier-utils.h @@ -0,0 +1,49 @@ +#ifndef __SP_BEZIER_UTILS_H__ +#define __SP_BEZIER_UTILS_H__ + +/* + * An Algorithm for Automatically Fitting Digitized Curves + * by Philip J. Schneider + * from "Graphics Gems", Academic Press, 1990 + * + * Authors: + * Philip J. Schneider + * Lauris Kaplinski + * + * Copyright (C) 1990 Philip J. Schneider + * Copyright (C) 2001 Lauris Kaplinski and Ximian, Inc. + * + * Released under GNU GPL + */ + +#include +#include + +/* Bezier approximation utils */ + +gint sp_bezier_fit_cubic(NR::Point bezier[], NR::Point const data[], gint len, gdouble error); + +gint sp_bezier_fit_cubic_r(NR::Point bezier[], NR::Point const data[], gint len, gdouble error, + unsigned max_beziers); + +gint sp_bezier_fit_cubic_full(NR::Point bezier[], int split_points[], NR::Point const data[], gint len, + NR::Point const &tHat1, NR::Point const &tHat2, + gdouble error, unsigned max_beziers); + +NR::Point sp_darray_left_tangent(NR::Point const d[], unsigned const len); +NR::Point sp_darray_left_tangent(NR::Point const d[], unsigned const len, double const tolerance_sq); +NR::Point sp_darray_right_tangent(NR::Point const d[], unsigned const length, double const tolerance_sq); + + +#endif /* __SP_BEZIER_UTILS_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:encoding=utf-8:textwidth=99 : diff --git a/src/display/canvas-arena.cpp b/src/display/canvas-arena.cpp new file mode 100644 index 000000000..1d77de158 --- /dev/null +++ b/src/display/canvas-arena.cpp @@ -0,0 +1,451 @@ +#define __SP_CANVAS_ARENA_C__ + +/* + * RGBA display list system for inkscape + * + * Author: + * Lauris Kaplinski + * + * Copyright (C) 2001-2002 Lauris Kaplinski + * Copyright (C) 2001 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include +#include + +#include +#include +#include +#include +#include +#include + +enum { + ARENA_EVENT, + LAST_SIGNAL +}; + +static void sp_canvas_arena_class_init(SPCanvasArenaClass *klass); +static void sp_canvas_arena_init(SPCanvasArena *group); +static void sp_canvas_arena_destroy(GtkObject *object); + +static void sp_canvas_arena_update (SPCanvasItem *item, NR::Matrix const &affine, unsigned int flags); +static void sp_canvas_arena_render (SPCanvasItem *item, SPCanvasBuf *buf); +static double sp_canvas_arena_point (SPCanvasItem *item, NR::Point p, SPCanvasItem **actual_item); +static gint sp_canvas_arena_event (SPCanvasItem *item, GdkEvent *event); + +static gint sp_canvas_arena_send_event (SPCanvasArena *arena, GdkEvent *event); + +static void sp_canvas_arena_request_update (NRArena *arena, NRArenaItem *item, void *data); +static void sp_canvas_arena_request_render (NRArena *arena, NRRectL *area, void *data); + +NRArenaEventVector carenaev = { + {NULL}, + sp_canvas_arena_request_update, + sp_canvas_arena_request_render +}; + +static SPCanvasItemClass *parent_class; +static guint signals[LAST_SIGNAL] = {0}; + +GtkType +sp_canvas_arena_get_type (void) +{ + static GtkType type = 0; + if (!type) { + GtkTypeInfo info = { + "SPCanvasArena", + sizeof (SPCanvasArena), + sizeof (SPCanvasArenaClass), + (GtkClassInitFunc) sp_canvas_arena_class_init, + (GtkObjectInitFunc) sp_canvas_arena_init, + NULL, NULL, NULL + }; + type = gtk_type_unique (SP_TYPE_CANVAS_ITEM, &info); + } + return type; +} + +static void +sp_canvas_arena_class_init (SPCanvasArenaClass *klass) +{ + GtkObjectClass *object_class; + SPCanvasItemClass *item_class; + + object_class = (GtkObjectClass *) klass; + item_class = (SPCanvasItemClass *) klass; + + parent_class = (SPCanvasItemClass*)gtk_type_class (SP_TYPE_CANVAS_ITEM); + + signals[ARENA_EVENT] = gtk_signal_new ("arena_event", + GTK_RUN_LAST, + GTK_CLASS_TYPE(object_class), + GTK_SIGNAL_OFFSET (SPCanvasArenaClass, arena_event), + sp_marshal_INT__POINTER_POINTER, + GTK_TYPE_INT, 2, GTK_TYPE_POINTER, GTK_TYPE_POINTER); + + object_class->destroy = sp_canvas_arena_destroy; + + item_class->update = sp_canvas_arena_update; + item_class->render = sp_canvas_arena_render; + item_class->point = sp_canvas_arena_point; + item_class->event = sp_canvas_arena_event; +} + +static void +sp_canvas_arena_init (SPCanvasArena *arena) +{ + arena->sticky = FALSE; + + arena->arena = NRArena::create(); + arena->root = NRArenaGroup::create(arena->arena); + nr_arena_group_set_transparent (NR_ARENA_GROUP (arena->root), TRUE); + +#ifdef arena_item_tile_cache + arena->root->skipCaching=true; +#endif + + arena->active = NULL; + + nr_active_object_add_listener ((NRActiveObject *) arena->arena, (NRObjectEventVector *) &carenaev, sizeof (carenaev), arena); +} + +static void +sp_canvas_arena_destroy (GtkObject *object) +{ + SPCanvasArena *arena = SP_CANVAS_ARENA (object); + + if (arena->active) { + nr_object_unref ((NRObject *) arena->active); + arena->active = NULL; + } + + if (arena->root) { + nr_arena_item_unref (arena->root); + arena->root = NULL; + } + + if (arena->arena) { + nr_active_object_remove_listener_by_data ((NRActiveObject *) arena->arena, arena); + + nr_object_unref ((NRObject *) arena->arena); + arena->arena = NULL; + } + + if (GTK_OBJECT_CLASS (parent_class)->destroy) + (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); +} + +static void +sp_canvas_arena_update (SPCanvasItem *item, NR::Matrix const &affine, unsigned int flags) +{ + SPCanvasArena *arena = SP_CANVAS_ARENA (item); + + if (((SPCanvasItemClass *) parent_class)->update) + (* ((SPCanvasItemClass *) parent_class)->update) (item, affine, flags); + + arena->gc.transform = affine; + + guint reset; + reset = (flags & SP_CANVAS_UPDATE_AFFINE)? NR_ARENA_ITEM_STATE_ALL : NR_ARENA_ITEM_STATE_NONE; + + nr_arena_item_invoke_update (arena->root, NULL, &arena->gc, NR_ARENA_ITEM_STATE_ALL, reset); + + item->x1 = arena->root->bbox.x0 - 1; + item->y1 = arena->root->bbox.y0 - 1; + item->x2 = arena->root->bbox.x1 + 1; + item->y2 = arena->root->bbox.y1 + 1; + + if (arena->cursor) { + /* Mess with enter/leave notifiers */ + NRArenaItem *new_arena = nr_arena_item_invoke_pick (arena->root, arena->c, arena->arena->delta, arena->sticky); + if (new_arena != arena->active) { + GdkEventCrossing ec; + ec.window = GTK_WIDGET (item->canvas)->window; + ec.send_event = TRUE; + ec.subwindow = ec.window; + ec.time = GDK_CURRENT_TIME; + ec.x = arena->c[NR::X]; + ec.y = arena->c[NR::Y]; + /* fixme: */ + if (arena->active) { + ec.type = GDK_LEAVE_NOTIFY; + sp_canvas_arena_send_event (arena, (GdkEvent *) &ec); + } + /* fixme: This is not optimal - better track ::destroy (Lauris) */ + if (arena->active) nr_object_unref ((NRObject *) arena->active); + arena->active = new_arena; + if (arena->active) nr_object_ref ((NRObject *) arena->active); + if (arena->active) { + ec.type = GDK_ENTER_NOTIFY; + sp_canvas_arena_send_event (arena, (GdkEvent *) &ec); + } + } + } +} + +#ifdef arena_item_tile_cache +extern void age_cache(void); +#endif + +static void +sp_canvas_arena_render (SPCanvasItem *item, SPCanvasBuf *buf) +{ + gint bw, bh, sw, sh; + gint x, y; + + SPCanvasArena *arena = SP_CANVAS_ARENA (item); + + nr_arena_item_invoke_update (arena->root, NULL, &arena->gc, + NR_ARENA_ITEM_STATE_BBOX | NR_ARENA_ITEM_STATE_RENDER, + NR_ARENA_ITEM_STATE_NONE); + + sp_canvas_prepare_buffer(buf); + +#ifdef arena_item_tile_cache + age_cache(); +#endif + bw = buf->rect.x1 - buf->rect.x0; + bh = buf->rect.y1 - buf->rect.y0; + if ((bw < 1) || (bh < 1)) return; + + if (arena->arena->rendermode != RENDERMODE_OUTLINE) { // use 256K as a compromise to not slow down gradients + /* 256K is the cached buffer and we need 4 channels */ + if (bw * bh < 65536) { // 256K/4 + /* We can go with single buffer */ + sw = bw; + sh = bh; + } else if (bw <= 4096) { + /* Go with row buffer */ + sw = bw; + sh = 65536 / bw; + } else if (bh <= 4096) { + /* Go with column buffer */ + sw = 65536 / bh; + sh = bh; + } else { + sw = 256; + sh = 256; + } + } else { // paths only, so 1M works faster + /* 1M is the cached buffer and we need 4 channels */ + if (bw * bh < 262144) { // 1M/4 + /* We can go with single buffer */ + sw = bw; + sh = bh; + } else if (bw <= 8192) { + /* Go with row buffer */ + sw = bw; + sh = 262144 / bw; + } else if (bh <= 8192) { + /* Go with column buffer */ + sw = 262144 / bh; + sh = bh; + } else { + sw = 512; + sh = 512; + } + } + +/* fixme: RGB transformed bitmap blit is not implemented (Lauris) */ +/* And even if it would be, unless it uses MMX there is little reason to go RGB */ +#define STRICT_RGBA + + for (y = buf->rect.y0; y < buf->rect.y1; y += sh) { + for (x = buf->rect.x0; x < buf->rect.x1; x += sw) { + NRRectL area; +#ifdef STRICT_RGBA + NRPixBlock pb; +#endif + NRPixBlock cb; + + area.x0 = x; + area.y0 = y; + area.x1 = MIN (x + sw, buf->rect.x1); + area.y1 = MIN (y + sh, buf->rect.y1); + +#ifdef STRICT_RGBA + nr_pixblock_setup_fast (&pb, NR_PIXBLOCK_MODE_R8G8B8A8P, area.x0, area.y0, area.x1, area.y1, TRUE); + /* fixme: */ + pb.empty = FALSE; +#endif + + nr_pixblock_setup_extern (&cb, NR_PIXBLOCK_MODE_R8G8B8, area.x0, area.y0, area.x1, area.y1, + buf->buf + (y - buf->rect.y0) * buf->buf_rowstride + 3 * (x - buf->rect.x0), + buf->buf_rowstride, + FALSE, FALSE); + +#ifdef STRICT_RGBA + nr_arena_item_invoke_render (arena->root, &area, &pb, 0); + nr_blit_pixblock_pixblock (&cb, &pb); + nr_pixblock_release (&pb); +#else + nr_arena_item_invoke_render (arena->root, &area, &cb, 0); +#endif + + nr_pixblock_release (&cb); + } + } +} + +static double +sp_canvas_arena_point (SPCanvasItem *item, NR::Point p, SPCanvasItem **actual_item) +{ + SPCanvasArena *arena = SP_CANVAS_ARENA (item); + + nr_arena_item_invoke_update (arena->root, NULL, &arena->gc, + NR_ARENA_ITEM_STATE_BBOX | NR_ARENA_ITEM_STATE_PICK, + NR_ARENA_ITEM_STATE_NONE); + + NRArenaItem *picked = nr_arena_item_invoke_pick (arena->root, p, arena->arena->delta, arena->sticky); + + arena->picked = picked; + + if (picked) { + *actual_item = item; + return 0.0; + } + + return 1e18; +} + +static gint +sp_canvas_arena_event (SPCanvasItem *item, GdkEvent *event) +{ + NRArenaItem *new_arena; + /* fixme: This sucks, we have to handle enter/leave notifiers */ + + SPCanvasArena *arena = SP_CANVAS_ARENA (item); + + gint ret = FALSE; + + switch (event->type) { + case GDK_ENTER_NOTIFY: + if (!arena->cursor) { + if (arena->active) { + //g_warning ("Cursor entered to arena with already active item"); + nr_object_unref ((NRObject *) arena->active); + } + arena->cursor = TRUE; + + /* TODO ... event -> arena transform? */ + arena->c = NR::Point(event->crossing.x, event->crossing.y); + + /* fixme: Not sure abut this, but seems the right thing (Lauris) */ + nr_arena_item_invoke_update (arena->root, NULL, &arena->gc, NR_ARENA_ITEM_STATE_PICK, NR_ARENA_ITEM_STATE_NONE); + arena->active = nr_arena_item_invoke_pick (arena->root, arena->c, arena->arena->delta, arena->sticky); + if (arena->active) nr_object_ref ((NRObject *) arena->active); + ret = sp_canvas_arena_send_event (arena, event); + } + break; + case GDK_LEAVE_NOTIFY: + if (arena->cursor) { + ret = sp_canvas_arena_send_event (arena, event); + if (arena->active) nr_object_unref ((NRObject *) arena->active); + arena->active = NULL; + arena->cursor = FALSE; + } + break; + case GDK_MOTION_NOTIFY: + /* TODO ... event -> arena transform? */ + arena->c = NR::Point(event->motion.x, event->motion.y); + + /* fixme: Not sure abut this, but seems the right thing (Lauris) */ + nr_arena_item_invoke_update (arena->root, NULL, &arena->gc, NR_ARENA_ITEM_STATE_PICK, NR_ARENA_ITEM_STATE_NONE); + new_arena = nr_arena_item_invoke_pick (arena->root, arena->c, arena->arena->delta, arena->sticky); + if (new_arena != arena->active) { + GdkEventCrossing ec; + ec.window = event->motion.window; + ec.send_event = event->motion.send_event; + ec.subwindow = event->motion.window; + ec.time = event->motion.time; + ec.x = event->motion.x; + ec.y = event->motion.y; + /* fixme: */ + if (arena->active) { + ec.type = GDK_LEAVE_NOTIFY; + ret = sp_canvas_arena_send_event (arena, (GdkEvent *) &ec); + } + if (arena->active) nr_object_unref ((NRObject *) arena->active); + arena->active = new_arena; + if (arena->active) nr_object_ref ((NRObject *) arena->active); + if (arena->active) { + ec.type = GDK_ENTER_NOTIFY; + ret = sp_canvas_arena_send_event (arena, (GdkEvent *) &ec); + } + } + ret = sp_canvas_arena_send_event (arena, event); + break; + default: + /* Just send event */ + ret = sp_canvas_arena_send_event (arena, event); + break; + } + + return ret; +} + +static gint +sp_canvas_arena_send_event (SPCanvasArena *arena, GdkEvent *event) +{ + gint ret = FALSE; + + /* Send event to arena */ + gtk_signal_emit (GTK_OBJECT (arena), signals[ARENA_EVENT], arena->active, event, &ret); + + return ret; +} + +static void +sp_canvas_arena_request_update (NRArena *arena, NRArenaItem *item, void *data) +{ + sp_canvas_item_request_update (SP_CANVAS_ITEM (data)); +} + +static void +sp_canvas_arena_request_render (NRArena *arena, NRRectL *area, void *data) +{ + sp_canvas_request_redraw (SP_CANVAS_ITEM (data)->canvas, area->x0, area->y0, area->x1, area->y1); +} + +void +sp_canvas_arena_set_pick_delta (SPCanvasArena *ca, gdouble delta) +{ + g_return_if_fail (ca != NULL); + g_return_if_fail (SP_IS_CANVAS_ARENA (ca)); + + /* fixme: repick? */ + ca->delta = delta; +} + +void +sp_canvas_arena_set_sticky (SPCanvasArena *ca, gboolean sticky) +{ + g_return_if_fail (ca != NULL); + g_return_if_fail (SP_IS_CANVAS_ARENA (ca)); + + /* fixme: repick? */ + ca->sticky = sticky; +} + +void +sp_canvas_arena_render_pixblock (SPCanvasArena *ca, NRPixBlock *pb) +{ + NRRectL area; + + g_return_if_fail (ca != NULL); + g_return_if_fail (SP_IS_CANVAS_ARENA (ca)); + + /* fixme: */ + pb->empty = FALSE; + + area.x0 = pb->area.x0; + area.y0 = pb->area.y0; + area.x1 = pb->area.x1; + area.y1 = pb->area.y1; + + nr_arena_item_invoke_render (ca->root, &area, pb, 0); +} + diff --git a/src/display/canvas-arena.h b/src/display/canvas-arena.h new file mode 100644 index 000000000..805bee60a --- /dev/null +++ b/src/display/canvas-arena.h @@ -0,0 +1,58 @@ +#ifndef __SP_CANVAS_ARENA_H__ +#define __SP_CANVAS_ARENA_H__ + +/* + * RGBA display list system for inkscape + * + * Author: + * Lauris Kaplinski + * + * Copyright (C) 2001-2002 Lauris Kaplinski + * Copyright (C) 2001 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +struct SPCanvasArena; +struct SPCanvasArenaClass; + +#define SP_TYPE_CANVAS_ARENA (sp_canvas_arena_get_type ()) +#define SP_CANVAS_ARENA(obj) (GTK_CHECK_CAST ((obj), SP_TYPE_CANVAS_ARENA, SPCanvasArena)) +#define SP_CANVAS_ARENA_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), SP_TYPE_CANVAS_ARENA, SPCanvasArenaClass)) +#define SP_IS_CANVAS_ARENA(obj) (GTK_CHECK_TYPE ((obj), SP_TYPE_CANVAS_ARENA)) +#define SP_IS_CANVAS_ARENA_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), SP_TYPE_CANVAS_ARENA)) + +#include "../display/sp-canvas.h" +#include "nr-arena-item.h" + +struct SPCanvasArena { + SPCanvasItem item; + + guint cursor : 1; + guint sticky : 1; + NR::Point c; // what is this? + + NRArena *arena; + NRArenaItem *root; + NRGC gc; + + NRArenaItem *active; + /* fixme: */ + NRArenaItem *picked; + gdouble delta; +}; + +struct SPCanvasArenaClass { + SPCanvasItemClass parent_class; + + gint (* arena_event) (SPCanvasArena *carena, NRArenaItem *item, GdkEvent *event); +}; + +GtkType sp_canvas_arena_get_type (void); + +void sp_canvas_arena_set_pick_delta (SPCanvasArena *ca, gdouble delta); +void sp_canvas_arena_set_sticky (SPCanvasArena *ca, gboolean sticky); + +void sp_canvas_arena_render_pixblock (SPCanvasArena *ca, NRPixBlock *pb); + +#endif diff --git a/src/display/canvas-bpath.cpp b/src/display/canvas-bpath.cpp new file mode 100644 index 000000000..a6434ae3d --- /dev/null +++ b/src/display/canvas-bpath.cpp @@ -0,0 +1,485 @@ +#define __SP_CANVAS_BPATH_C__ + +/* + * Simple bezier bpath CanvasItem for inkscape + * + * Authors: + * Lauris Kaplinski + * + * Copyright (C) 2001 Lauris Kaplinski and Ximian, Inc. + * + * Released under GNU GPL + * + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif +#include "sp-canvas-util.h" +#include "canvas-bpath.h" +#include "display/display-forward.h" +#include "display/curve.h" +#include +#include +#include +#include +#include + +void nr_pixblock_render_bpath_rgba (Shape* theS,uint32_t color,NRRectL &area,char* destBuf,int stride); + +static void sp_canvas_bpath_class_init (SPCanvasBPathClass *klass); +static void sp_canvas_bpath_init (SPCanvasBPath *path); +static void sp_canvas_bpath_destroy (GtkObject *object); + +static void sp_canvas_bpath_update (SPCanvasItem *item, NR::Matrix const &affine, unsigned int flags); +static void sp_canvas_bpath_render (SPCanvasItem *item, SPCanvasBuf *buf); +static double sp_canvas_bpath_point (SPCanvasItem *item, NR::Point p, SPCanvasItem **actual_item); + +static SPCanvasItemClass *parent_class; + +GtkType +sp_canvas_bpath_get_type (void) +{ + static GtkType type = 0; + if (!type) { + GtkTypeInfo info = { + "SPCanvasBPath", + sizeof (SPCanvasBPath), + sizeof (SPCanvasBPathClass), + (GtkClassInitFunc) sp_canvas_bpath_class_init, + (GtkObjectInitFunc) sp_canvas_bpath_init, + NULL, NULL, NULL + }; + type = gtk_type_unique (SP_TYPE_CANVAS_ITEM, &info); + } + return type; +} + +static void +sp_canvas_bpath_class_init (SPCanvasBPathClass *klass) +{ + GtkObjectClass *object_class; + SPCanvasItemClass *item_class; + + object_class = GTK_OBJECT_CLASS (klass); + item_class = (SPCanvasItemClass *) klass; + + parent_class = (SPCanvasItemClass*)gtk_type_class (SP_TYPE_CANVAS_ITEM); + + object_class->destroy = sp_canvas_bpath_destroy; + + item_class->update = sp_canvas_bpath_update; + item_class->render = sp_canvas_bpath_render; + item_class->point = sp_canvas_bpath_point; +} + +static void +sp_canvas_bpath_init (SPCanvasBPath * bpath) +{ + bpath->fill_rgba = 0x000000ff; + bpath->fill_rule = SP_WIND_RULE_EVENODD; + + bpath->stroke_rgba = 0x00000000; + bpath->stroke_width = 1.0; + bpath->stroke_linejoin = SP_STROKE_LINEJOIN_MITER; + bpath->stroke_linecap = SP_STROKE_LINECAP_BUTT; + bpath->stroke_miterlimit = 11.0; + + bpath->fill_shp=NULL; + bpath->stroke_shp=NULL; +} + +static void +sp_canvas_bpath_destroy (GtkObject *object) +{ + SPCanvasBPath *cbp = SP_CANVAS_BPATH (object); + if (cbp->fill_shp) { + delete cbp->fill_shp; + cbp->fill_shp = NULL; + } + + if (cbp->stroke_shp) { + delete cbp->stroke_shp; + cbp->stroke_shp = NULL; + } + if (cbp->curve) { + cbp->curve = sp_curve_unref (cbp->curve); + } + + if (GTK_OBJECT_CLASS (parent_class)->destroy) + (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); +} + +static void +sp_canvas_bpath_update (SPCanvasItem *item, NR::Matrix const &affine, unsigned int flags) +{ + SPCanvasBPath *cbp = SP_CANVAS_BPATH (item); + + sp_canvas_request_redraw (item->canvas, (int)item->x1, (int)item->y1, (int)item->x2, (int)item->y2); + + if (((SPCanvasItemClass *) parent_class)->update) + ((SPCanvasItemClass *) parent_class)->update (item, affine, flags); + + sp_canvas_item_reset_bounds (item); + + if (cbp->fill_shp) { + delete cbp->fill_shp; + cbp->fill_shp = NULL; + } + + if (cbp->stroke_shp) { + delete cbp->stroke_shp; + cbp->stroke_shp = NULL; + } + if (!cbp->curve) return; + + NRRect dbox; + + dbox.x0 = dbox.y0 = 0.0; + dbox.x1 = dbox.y1 = -1.0; + + if ((cbp->fill_rgba & 0xff) || (cbp->stroke_rgba & 0xff)) { + Path* thePath=new Path; + thePath->LoadArtBPath(cbp->curve->bpath, affine, true); + thePath->Convert(0.25); + if ((cbp->fill_rgba & 0xff) && (cbp->curve->end > 2)) { + Shape* theShape=new Shape; + thePath->Fill(theShape,0); + if ( cbp->fill_shp == NULL ) cbp->fill_shp=new Shape; + if ( cbp->fill_rule == SP_WIND_RULE_EVENODD ) { + cbp->fill_shp->ConvertToShape(theShape,fill_oddEven); + } else { + cbp->fill_shp->ConvertToShape(theShape,fill_nonZero); + } + delete theShape; + cbp->fill_shp->CalcBBox(); + if ( cbp->fill_shp->leftX < cbp->fill_shp->rightX ) { + if ( dbox.x0 >= dbox.x1 ) { + dbox.x0 = cbp->fill_shp->leftX; dbox.x1 = cbp->fill_shp->rightX; + dbox.y0 = cbp->fill_shp->topY; dbox.y1 = cbp->fill_shp->bottomY; + } else { + if ( cbp->fill_shp->leftX < dbox.x0 ) dbox.x0=cbp->fill_shp->leftX; + if ( cbp->fill_shp->rightX > dbox.x1 ) dbox.x1=cbp->fill_shp->rightX; + if ( cbp->fill_shp->topY < dbox.y0 ) dbox.y0=cbp->fill_shp->topY; + if ( cbp->fill_shp->bottomY > dbox.y1 ) dbox.y1=cbp->fill_shp->bottomY; + } + } + } + if ((cbp->stroke_rgba & 0xff) && (cbp->curve->end > 1)) { + JoinType join=join_straight; +// Shape* theShape=new Shape; + ButtType butt=butt_straight; + if ( cbp->stroke_shp == NULL ) cbp->stroke_shp=new Shape; + if ( cbp->stroke_linecap == SP_STROKE_LINECAP_BUTT ) butt=butt_straight; + if ( cbp->stroke_linecap == SP_STROKE_LINECAP_ROUND ) butt=butt_round; + if ( cbp->stroke_linecap == SP_STROKE_LINECAP_SQUARE ) butt=butt_square; + if ( cbp->stroke_linejoin == SP_STROKE_LINEJOIN_MITER ) join=join_pointy; + if ( cbp->stroke_linejoin == SP_STROKE_LINEJOIN_ROUND ) join=join_round; + if ( cbp->stroke_linejoin == SP_STROKE_LINEJOIN_BEVEL ) join=join_straight; + thePath->Stroke(cbp->stroke_shp,false,0.5*cbp->stroke_width, join,butt,cbp->stroke_width*cbp->stroke_miterlimit ); + // thePath->Stroke(theShape,false,0.5*cbp->stroke_width, join,butt,cbp->stroke_width*cbp->stroke_miterlimit ); + // cbp->stroke_shp->ConvertToShape(theShape,fill_nonZero); + + cbp->stroke_shp->CalcBBox(); + if ( cbp->stroke_shp->leftX < cbp->stroke_shp->rightX ) { + if ( dbox.x0 >= dbox.x1 ) { + dbox.x0 = cbp->stroke_shp->leftX;dbox.x1 = cbp->stroke_shp->rightX; + dbox.y0 = cbp->stroke_shp->topY;dbox.y1 = cbp->stroke_shp->bottomY; + } else { + if ( cbp->stroke_shp->leftX < dbox.x0 ) dbox.x0 = cbp->stroke_shp->leftX; + if ( cbp->stroke_shp->rightX > dbox.x1 ) dbox.x1 = cbp->stroke_shp->rightX; + if ( cbp->stroke_shp->topY < dbox.y0 ) dbox.y0 = cbp->stroke_shp->topY; + if ( cbp->stroke_shp->bottomY > dbox.y1 ) dbox.y1 = cbp->stroke_shp->bottomY; + } + } +// delete theShape; + } + delete thePath; + } + + + item->x1 = (int)dbox.x0; + item->y1 = (int)dbox.y0; + item->x2 = (int)dbox.x1; + item->y2 = (int)dbox.y1; + + sp_canvas_request_redraw (item->canvas, (int)item->x1, (int)item->y1, (int)item->x2, (int)item->y2); +} + +static void +sp_canvas_bpath_render (SPCanvasItem *item, SPCanvasBuf *buf) +{ + SPCanvasBPath *cbp = SP_CANVAS_BPATH (item); + + sp_canvas_prepare_buffer(buf); + + NRRectL area; + area.x0=buf->rect.x0; + area.x1=buf->rect.x1; + area.y0=buf->rect.y0; + area.y1=buf->rect.y1; + if ( cbp->fill_shp ) { + nr_pixblock_render_bpath_rgba (cbp->fill_shp,cbp->fill_rgba,area,(char*)buf->buf, buf->buf_rowstride); + } + if ( cbp->stroke_shp ) { + nr_pixblock_render_bpath_rgba (cbp->stroke_shp,cbp->stroke_rgba,area,(char*)buf->buf, buf->buf_rowstride); + } + +} + +#define BIGVAL 1e18 + +static double +sp_canvas_bpath_point (SPCanvasItem *item, NR::Point p, SPCanvasItem **actual_item) +{ + SPCanvasBPath *cbp = SP_CANVAS_BPATH (item); + + if (cbp->fill_shp && (cbp->fill_shp->PtWinding(p) > 0 )) { + *actual_item = item; + return 0.0; + } + if (cbp->stroke_shp ) { + if (cbp->stroke_shp->PtWinding(p) > 0 ) { + *actual_item = item; + return 0.0; + } + return distance(cbp->stroke_shp, p); + } + if (cbp->fill_shp) { + return distance(cbp->fill_shp, p); + } + + return BIGVAL; +} + +SPCanvasItem * +sp_canvas_bpath_new (SPCanvasGroup *parent, SPCurve *curve) +{ + g_return_val_if_fail (parent != NULL, NULL); + g_return_val_if_fail (SP_IS_CANVAS_GROUP (parent), NULL); + + SPCanvasItem *item = sp_canvas_item_new (parent, SP_TYPE_CANVAS_BPATH, NULL); + + sp_canvas_bpath_set_bpath (SP_CANVAS_BPATH (item), curve); + + return item; +} + +void +sp_canvas_bpath_set_bpath (SPCanvasBPath *cbp, SPCurve *curve) +{ + g_return_if_fail (cbp != NULL); + g_return_if_fail (SP_IS_CANVAS_BPATH (cbp)); + + if (cbp->curve) { + cbp->curve = sp_curve_unref (cbp->curve); + } + + if (curve) { + cbp->curve = sp_curve_ref (curve); + } + + sp_canvas_item_request_update (SP_CANVAS_ITEM (cbp)); +} + +void +sp_canvas_bpath_set_fill (SPCanvasBPath *cbp, guint32 rgba, SPWindRule rule) +{ + g_return_if_fail (cbp != NULL); + g_return_if_fail (SP_IS_CANVAS_BPATH (cbp)); + + cbp->fill_rgba = rgba; + cbp->fill_rule = rule; + + sp_canvas_item_request_update (SP_CANVAS_ITEM (cbp)); +} + +void +sp_canvas_bpath_set_stroke (SPCanvasBPath *cbp, guint32 rgba, gdouble width, SPStrokeJoinType join, SPStrokeCapType cap) +{ + g_return_if_fail (cbp != NULL); + g_return_if_fail (SP_IS_CANVAS_BPATH (cbp)); + + cbp->stroke_rgba = rgba; + cbp->stroke_width = MAX (width, 0.1); + cbp->stroke_linejoin = join; + cbp->stroke_linecap = cap; + + sp_canvas_item_request_update (SP_CANVAS_ITEM (cbp)); +} + + + +static void +bpath_run_A8_OR (raster_info &dest,void *data,int st,float vst,int en,float ven) +{ + union { + uint8_t comp[4]; + uint32_t col; + } tempCol; + if ( st >= en ) return; + tempCol.col=*(uint32_t*)data; + + unsigned int r, g, b, a; + r = NR_RGBA32_R (tempCol.col); + g = NR_RGBA32_G (tempCol.col); + b = NR_RGBA32_B (tempCol.col); + a = NR_RGBA32_A (tempCol.col); + if (a == 0) return; + + vst*=a; + ven*=a; + + if ( vst < 0 ) vst=0; + if ( vst > 255 ) vst=255; + if ( ven < 0 ) ven=0; + if ( ven > 255 ) ven=255; + float sv=vst; + float dv=ven-vst; + int len=en-st; + uint8_t* d=(uint8_t*)dest.buffer; + + d+=3*(st-dest.startPix); + if ( fabs(dv) < 0.001 ) { + if ( sv > 249.999 ) { + /* Simple copy */ + while (len > 0) { + d[0] = NR_COMPOSEN11 (r, 255, d[0]); + d[1] = NR_COMPOSEN11 (g, 255, d[1]); + d[2] = NR_COMPOSEN11 (b, 255, d[2]); + d += 3; + len -= 1; + } + } else { + unsigned int c0_24=(int)sv; + c0_24&=0xFF; + while (len > 0) { + d[0] = NR_COMPOSEN11 (r, c0_24, d[0]); + d[1] = NR_COMPOSEN11 (g, c0_24, d[1]); + d[2] = NR_COMPOSEN11 (b, c0_24, d[2]); + d += 3; + len -= 1; + } + } + } else { + if ( en <= st+1 ) { + sv=0.5*(vst+ven); + unsigned int c0_24=(int)sv; + c0_24&=0xFF; + d[0] = NR_COMPOSEN11 (r, c0_24, d[0]); + d[1] = NR_COMPOSEN11 (g, c0_24, d[1]); + d[2] = NR_COMPOSEN11 (b, c0_24, d[2]); + } else { + dv/=len; + sv+=0.5*dv; // correction trapezoidale + sv*=65536; + dv*=65536; + int c0_24 = static_cast(CLAMP(sv, 0, 16777216)); + int s0_24 = static_cast(dv); + while (len > 0) { + unsigned int ca; + /* Draw */ + ca = c0_24 >> 16; + if ( ca > 255 ) ca=255; + d[0] = NR_COMPOSEN11 (r, ca, d[0]); + d[1] = NR_COMPOSEN11 (g, ca, d[1]); + d[2] = NR_COMPOSEN11 (b, ca, d[2]); + d += 3; + c0_24 += s0_24; + c0_24 = CLAMP (c0_24, 0, 16777216); + len -= 1; + } + } + } +} + +void nr_pixblock_render_bpath_rgba (Shape* theS,uint32_t color,NRRectL &area,char* destBuf,int stride) +{ + + theS->CalcBBox(); + float l=theS->leftX,r=theS->rightX,t=theS->topY,b=theS->bottomY; + int il,ir,it,ib; + il=(int)floor(l); + ir=(int)ceil(r); + it=(int)floor(t); + ib=(int)ceil(b); + + if ( il >= area.x1 || ir <= area.x0 || it >= area.y1 || ib <= area.y0 ) return; + if ( il < area.x0 ) il=area.x0; + if ( it < area.y0 ) it=area.y0; + if ( ir > area.x1 ) ir=area.x1; + if ( ib > area.y1 ) ib=area.y1; + +/* // version par FloatLigne + int curPt; + float curY; + theS->BeginRaster(curY,curPt,1.0); + + FloatLigne* theI=new FloatLigne(); + IntLigne* theIL=new IntLigne(); + + theS->Scan(curY,curPt,(float)(it),1.0); + + char* mdata=(char*)destBuf; + uint32_t* ligStart=((uint32_t*)(mdata+(3*(il-area.x0)+stride*(it-area.y0)))); + for (int y=it;yReset(); + if ( y&0x00000003 ) { + theS->Scan(curY,curPt,((float)(y+1)),theI,false,1.0); + } else { + theS->Scan(curY,curPt,((float)(y+1)),theI,true,1.0); + } + theI->Flatten(); + theIL->Copy(theI); + + raster_info dest; + dest.startPix=il; + dest.endPix=ir; + dest.sth=il; + dest.stv=y; + dest.buffer=ligStart; + theIL->Raster(dest,&color,bpath_run_A8_OR); + ligStart=((uint32_t*)(((char*)ligStart)+stride)); + } + theS->EndRaster(); + delete theI; + delete theIL; */ + + // version par BitLigne directe + int curPt; + float curY; + theS->BeginQuickRaster(curY, curPt); + + BitLigne* theI[4]; + for (int i=0;i<4;i++) theI[i]=new BitLigne(il,ir); + IntLigne* theIL=new IntLigne(); + + theS->DirectQuickScan(curY,curPt,(float)(it),true,0.25); + + char* mdata=(char*)destBuf; + uint32_t* ligStart=((uint32_t*)(mdata+(3*(il-area.x0)+stride*(it-area.y0)))); + for (int y=it;yReset(); + + for (int i = 0; i < 4; i++) + theS->QuickScan(curY, curPt, ((float)(y+0.25*(i+1))), + fill_oddEven, theI[i], 0.25); + + theIL->Copy(4,theI); + // theI[0]->Affiche(); + // theIL->Affiche(); + + raster_info dest; + dest.startPix=il; + dest.endPix=ir; + dest.sth=il; + dest.stv=y; + dest.buffer=ligStart; + theIL->Raster(dest,&color,bpath_run_A8_OR); + ligStart=((uint32_t*)(((char*)ligStart)+stride)); + } + theS->EndQuickRaster(); + for (int i=0;i<4;i++) delete theI[i]; + delete theIL; +} diff --git a/src/display/canvas-bpath.h b/src/display/canvas-bpath.h new file mode 100644 index 000000000..072fe1087 --- /dev/null +++ b/src/display/canvas-bpath.h @@ -0,0 +1,99 @@ +#ifndef __SP_CANVAS_BPATH_H__ +#define __SP_CANVAS_BPATH_H__ + +/* + * Simple bezier bpath CanvasItem for inkscape + * + * Authors: + * Lauris Kaplinski + * + * Copyright (C) 2001 Lauris Kaplinski and Ximian, Inc. + * + * Released under GNU GPL + * + */ + +#include + +#include + +struct SPCanvasBPath; +struct SPCanvasBPathClass; +struct SPCurve; + +#define SP_TYPE_CANVAS_BPATH (sp_canvas_bpath_get_type ()) +#define SP_CANVAS_BPATH(obj) (GTK_CHECK_CAST ((obj), SP_TYPE_CANVAS_BPATH, SPCanvasBPath)) +#define SP_CANVAS_BPATH_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), SP_TYPE_CANVAS_BPATH, SPCanvasBPathClass)) +#define SP_IS_CANVAS_BPATH(obj) (GTK_CHECK_TYPE ((obj), SP_TYPE_CANVAS_BPATH)) +#define SP_IS_CANVAS_BPATH_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), SP_TYPE_CANVAS_BPATH)) + +#define bpath_liv + +class Shape; + +/* stroke-linejoin */ + +typedef enum { + SP_STROKE_LINEJOIN_MITER, + SP_STROKE_LINEJOIN_ROUND, + SP_STROKE_LINEJOIN_BEVEL +} SPStrokeJoinType; + +/* stroke-linecap */ + +typedef enum { + SP_STROKE_LINECAP_BUTT, + SP_STROKE_LINECAP_ROUND, + SP_STROKE_LINECAP_SQUARE +} SPStrokeCapType; + + +/* fill-rule */ +/* clip-rule */ + +typedef enum { + SP_WIND_RULE_NONZERO, + SP_WIND_RULE_INTERSECT, + SP_WIND_RULE_EVENODD, + SP_WIND_RULE_POSITIVE +} SPWindRule; + + +struct SPCanvasBPath { + SPCanvasItem item; + + /* Line def */ + SPCurve *curve; + + /* Fill attributes */ + guint32 fill_rgba; + SPWindRule fill_rule; + + /* Line attributes */ + guint32 stroke_rgba; + gdouble stroke_width; + SPStrokeJoinType stroke_linejoin; + SPStrokeCapType stroke_linecap; + gdouble stroke_miterlimit; + + /* State */ + Shape *fill_shp; + Shape *stroke_shp; +}; + +struct SPCanvasBPathClass { + SPCanvasItemClass parent_class; +}; + +GtkType sp_canvas_bpath_get_type (void); + +SPCanvasItem *sp_canvas_bpath_new (SPCanvasGroup *parent, SPCurve *curve); + +void sp_canvas_bpath_set_bpath (SPCanvasBPath *cbp, SPCurve *curve); +void sp_canvas_bpath_set_fill (SPCanvasBPath *cbp, guint32 rgba, SPWindRule rule); +void sp_canvas_bpath_set_stroke (SPCanvasBPath *cbp, guint32 rgba, gdouble width, SPStrokeJoinType join, SPStrokeCapType cap); + + + +#endif + diff --git a/src/display/canvas-grid.cpp b/src/display/canvas-grid.cpp new file mode 100644 index 000000000..6618c2358 --- /dev/null +++ b/src/display/canvas-grid.cpp @@ -0,0 +1,308 @@ +#define SP_CANVAS_GRID_C + +/* + * SPCGrid + * + * Copyright (C) Lauris Kaplinski 2000 + * + */ + + +#include "sp-canvas-util.h" +#include "canvas-grid.h" +#include "display-forward.h" +#include + +enum { + ARG_0, + ARG_ORIGINX, + ARG_ORIGINY, + ARG_SPACINGX, + ARG_SPACINGY, + ARG_COLOR, + ARG_EMPCOLOR, + ARG_EMPSPACING +}; + + +static void sp_cgrid_class_init (SPCGridClass *klass); +static void sp_cgrid_init (SPCGrid *grid); +static void sp_cgrid_destroy (GtkObject *object); +static void sp_cgrid_set_arg (GtkObject *object, GtkArg *arg, guint arg_id); + +static void sp_cgrid_update (SPCanvasItem *item, NR::Matrix const &affine, unsigned int flags); +static void sp_cgrid_render (SPCanvasItem *item, SPCanvasBuf *buf); + +static SPCanvasItemClass * parent_class; + +GtkType +sp_cgrid_get_type (void) +{ + static GtkType cgrid_type = 0; + + if (!cgrid_type) { + GtkTypeInfo cgrid_info = { + "SPCGrid", + sizeof (SPCGrid), + sizeof (SPCGridClass), + (GtkClassInitFunc) sp_cgrid_class_init, + (GtkObjectInitFunc) sp_cgrid_init, + NULL, NULL, + (GtkClassInitFunc) NULL + }; + cgrid_type = gtk_type_unique (sp_canvas_item_get_type (), &cgrid_info); + } + return cgrid_type; +} + +static void +sp_cgrid_class_init (SPCGridClass *klass) +{ + GtkObjectClass *object_class; + SPCanvasItemClass *item_class; + + object_class = (GtkObjectClass *) klass; + item_class = (SPCanvasItemClass *) klass; + + parent_class = (SPCanvasItemClass*)gtk_type_class (sp_canvas_item_get_type ()); + + gtk_object_add_arg_type ("SPCGrid::originx", GTK_TYPE_DOUBLE, GTK_ARG_WRITABLE, ARG_ORIGINX); + gtk_object_add_arg_type ("SPCGrid::originy", GTK_TYPE_DOUBLE, GTK_ARG_WRITABLE, ARG_ORIGINY); + gtk_object_add_arg_type ("SPCGrid::spacingx", GTK_TYPE_DOUBLE, GTK_ARG_WRITABLE, ARG_SPACINGX); + gtk_object_add_arg_type ("SPCGrid::spacingy", GTK_TYPE_DOUBLE, GTK_ARG_WRITABLE, ARG_SPACINGY); + gtk_object_add_arg_type ("SPCGrid::color", GTK_TYPE_INT, GTK_ARG_WRITABLE, ARG_COLOR); + gtk_object_add_arg_type ("SPCGrid::empcolor", GTK_TYPE_INT, GTK_ARG_WRITABLE, ARG_EMPCOLOR); + gtk_object_add_arg_type ("SPCGrid::empspacing", GTK_TYPE_INT, GTK_ARG_WRITABLE, ARG_EMPSPACING); + + object_class->destroy = sp_cgrid_destroy; + object_class->set_arg = sp_cgrid_set_arg; + + item_class->update = sp_cgrid_update; + item_class->render = sp_cgrid_render; +} + +static void +sp_cgrid_init (SPCGrid *grid) +{ + grid->origin[NR::X] = grid->origin[NR::Y] = 0.0; + grid->spacing[NR::X] = grid->spacing[NR::Y] = 8.0; + grid->color = 0x0000ff7f; + grid->empcolor = 0x3F3FFF40; + grid->empspacing = 5; +} + +static void +sp_cgrid_destroy (GtkObject *object) +{ + g_return_if_fail (object != NULL); + g_return_if_fail (SP_IS_CGRID (object)); + + if (GTK_OBJECT_CLASS (parent_class)->destroy) + (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); +} + +static void +sp_cgrid_set_arg (GtkObject *object, GtkArg *arg, guint arg_id) +{ + SPCanvasItem *item = SP_CANVAS_ITEM (object); + SPCGrid *grid = SP_CGRID (object); + + switch (arg_id) { + case ARG_ORIGINX: + grid->origin[NR::X] = GTK_VALUE_DOUBLE (* arg); + sp_canvas_item_request_update (item); + break; + case ARG_ORIGINY: + grid->origin[NR::Y] = GTK_VALUE_DOUBLE (* arg); + sp_canvas_item_request_update (item); + break; + case ARG_SPACINGX: + grid->spacing[NR::X] = GTK_VALUE_DOUBLE (* arg); + if (grid->spacing[NR::X] < 0.01) grid->spacing[NR::X] = 0.01; + sp_canvas_item_request_update (item); + break; + case ARG_SPACINGY: + grid->spacing[NR::Y] = GTK_VALUE_DOUBLE (* arg); + if (grid->spacing[NR::Y] < 0.01) grid->spacing[NR::Y] = 0.01; + sp_canvas_item_request_update (item); + break; + case ARG_COLOR: + grid->color = GTK_VALUE_INT (* arg); + sp_canvas_item_request_update (item); + break; + case ARG_EMPCOLOR: + grid->empcolor = GTK_VALUE_INT (* arg); + sp_canvas_item_request_update (item); + break; + case ARG_EMPSPACING: + grid->empspacing = GTK_VALUE_INT (* arg); + // std::cout << "Emphasis Spacing: " << grid->empspacing << std::endl; + sp_canvas_item_request_update (item); + break; + default: + break; + } +} + +static void +sp_grid_hline (SPCanvasBuf *buf, gint y, gint xs, gint xe, guint32 rgba) +{ + if ((y >= buf->rect.y0) && (y < buf->rect.y1)) { + guint r, g, b, a; + gint x0, x1, x; + guchar *p; + r = NR_RGBA32_R (rgba); + g = NR_RGBA32_G (rgba); + b = NR_RGBA32_B (rgba); + a = NR_RGBA32_A (rgba); + x0 = MAX (buf->rect.x0, xs); + x1 = MIN (buf->rect.x1, xe + 1); + p = buf->buf + (y - buf->rect.y0) * buf->buf_rowstride + (x0 - buf->rect.x0) * 3; + for (x = x0; x < x1; x++) { + p[0] = NR_COMPOSEN11 (r, a, p[0]); + p[1] = NR_COMPOSEN11 (g, a, p[1]); + p[2] = NR_COMPOSEN11 (b, a, p[2]); + p += 3; + } + } +} + +static void +sp_grid_vline (SPCanvasBuf *buf, gint x, gint ys, gint ye, guint32 rgba) +{ + if ((x >= buf->rect.x0) && (x < buf->rect.x1)) { + guint r, g, b, a; + gint y0, y1, y; + guchar *p; + r = NR_RGBA32_R(rgba); + g = NR_RGBA32_G (rgba); + b = NR_RGBA32_B (rgba); + a = NR_RGBA32_A (rgba); + y0 = MAX (buf->rect.y0, ys); + y1 = MIN (buf->rect.y1, ye + 1); + p = buf->buf + (y0 - buf->rect.y0) * buf->buf_rowstride + (x - buf->rect.x0) * 3; + for (y = y0; y < y1; y++) { + p[0] = NR_COMPOSEN11 (r, a, p[0]); + p[1] = NR_COMPOSEN11 (g, a, p[1]); + p[2] = NR_COMPOSEN11 (b, a, p[2]); + p += buf->buf_rowstride; + } + } +} + +/** + \brief This function renders the grid on a particular canvas buffer + \param item The grid to render on the buffer + \param buf The buffer to render the grid on + + This function gets called a touch more than you might believe, + about once per tile. This means that it could probably be optimized + and help things out. + + Basically this function has to determine where in the canvas it is, + and how that associates with the grid. It does this first by looking + at the bounding box of the buffer, and then calculates where the grid + starts in that buffer. It will then step through grid lines until + it is outside of the buffer. + + For each grid line it is drawn using the function \c sp_grid_hline + or \c sp_grid_vline. These are convience functions for the sake + of making the function easier to read. + + Also, there are emphisized lines on the grid. While the \c syg and + \c sxg variable track grid positioning, the \c xlinestart and \c + ylinestart variables track the 'count' of what lines they are. If + that count is a multiple of the line seperation between emphisis + lines, then that line is drawn in the emphisis color. +*/ +static void +sp_cgrid_render (SPCanvasItem * item, SPCanvasBuf * buf) +{ + SPCGrid *grid = SP_CGRID (item); + + sp_canvas_prepare_buffer (buf); + + const gdouble sxg = floor ((buf->rect.x0 - grid->ow[NR::X]) / grid->sw[NR::X]) * grid->sw[NR::X] + grid->ow[NR::X]; + const gint xlinestart = (gint) Inkscape::round((sxg - grid->ow[NR::X]) / grid->sw[NR::X]); + const gdouble syg = floor ((buf->rect.y0 - grid->ow[NR::Y]) / grid->sw[NR::Y]) * grid->sw[NR::Y] + grid->ow[NR::Y]; + const gint ylinestart = (gint) Inkscape::round((syg - grid->ow[NR::Y]) / grid->sw[NR::Y]); + + gint ylinenum; + gdouble y; + for (y = syg, ylinenum = ylinestart; y < buf->rect.y1; y += grid->sw[NR::Y], ylinenum++) { + const gint y0 = (gint) Inkscape::round(y); + const gint y1 = (gint) Inkscape::round(y + grid->sw[NR::Y]); + + if (!grid->scaled[NR::Y] && + (ylinenum % grid->empspacing) == 0) { + sp_grid_hline (buf, y0, buf->rect.x0, buf->rect.x1 - 1, grid->empcolor); + } else { + sp_grid_hline (buf, y0, buf->rect.x0, buf->rect.x1 - 1, grid->color); + } + + gint xlinenum; + gdouble x; + for (x = sxg, xlinenum = xlinestart; x < buf->rect.x1; x += grid->sw[NR::X], xlinenum++) { + const gint ix = (gint) Inkscape::round(x); + if (!grid->scaled[NR::X] && + (xlinenum % grid->empspacing) == 0) { + sp_grid_vline (buf, ix, y0 + 1, y1 - 1, grid->empcolor); + } else { + sp_grid_vline (buf, ix, y0 + 1, y1 - 1, grid->color); + } + } + } +} + +static void +sp_cgrid_update (SPCanvasItem *item, NR::Matrix const &affine, unsigned int flags) +{ + SPCGrid *grid = SP_CGRID (item); + + if (parent_class->update) + (* parent_class->update) (item, affine, flags); + + grid->ow = grid->origin * affine; + grid->sw = grid->spacing * affine; + grid->sw -= NR::Point(affine[4], affine[5]); + + for(int dim = 0; dim < 2; dim++) { + gint scaling_factor = grid->empspacing; + + if (scaling_factor <= 1) + scaling_factor = 5; + + grid->scaled[dim] = FALSE; + grid->sw[dim] = fabs (grid->sw[dim]); + while (grid->sw[dim] < 8.0) { + grid->scaled[dim] = TRUE; + grid->sw[dim] *= scaling_factor; + /* First pass, go up to the major line spacing, then + keep increasing by two. */ + scaling_factor = 2; + } + } + + if (grid->empspacing == 0) { + grid->scaled[NR::Y] = TRUE; + grid->scaled[NR::X] = TRUE; + } + + sp_canvas_request_redraw (item->canvas, + -1000000, -1000000, + 1000000, 1000000); + + item->x1 = item->y1 = -1000000; + item->x2 = item->y2 = 1000000; +} + +/* + 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 : diff --git a/src/display/canvas-grid.h b/src/display/canvas-grid.h new file mode 100644 index 000000000..0f3791773 --- /dev/null +++ b/src/display/canvas-grid.h @@ -0,0 +1,49 @@ +#ifndef SP_CANVAS_GRID_H +#define SP_CANVAS_GRID_H + +/* + * SPCGrid + * + * Generic (and quite unintelligent) grid item for gnome canvas + * + * Copyright (C) Lauris Kaplinski 2000 + * + */ + +#include + + + +#define SP_TYPE_CGRID (sp_cgrid_get_type ()) +#define SP_CGRID(obj) (GTK_CHECK_CAST ((obj), SP_TYPE_CGRID, SPCGrid)) +#define SP_CGRID_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), SP_TYPE_CGRID, SPCGridClass)) +#define SP_IS_CGRID(obj) (GTK_CHECK_TYPE ((obj), SP_TYPE_CGRID)) +#define SP_IS_CGRID_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), SP_TYPE_CGRID)) + + +/** \brief All the variables that are tracked for a grid specific + canvas item. */ +struct SPCGrid : public SPCanvasItem{ + NR::Point origin; /**< Origin of the grid */ + NR::Point spacing; /**< Spacing between elements of the grid */ + guint32 color; /**< Color for normal lines */ + guint32 empcolor; /**< Color for emphisis lines */ + gint empspacing; /**< Spacing between emphisis lines */ + bool scaled[2]; /**< Whether the grid is in scaled mode, which can + be different in the X or Y direction, hense two + variables */ + NR::Point ow; /**< Transformed origin by the affine for the zoom */ + NR::Point sw; /**< Transformed spacing by the affine for the zoom */ +}; + +struct SPCGridClass { + SPCanvasItemClass parent_class; +}; + + +/* Standard Gtk function */ +GtkType sp_cgrid_get_type (void); + + + +#endif diff --git a/src/display/curve.cpp b/src/display/curve.cpp new file mode 100644 index 000000000..a8a6e354e --- /dev/null +++ b/src/display/curve.cpp @@ -0,0 +1,1289 @@ +#define __CURVE_C__ + +/** \file + * Routines for SPCurve and for NArtBpath arrays in general. + */ + +/* + * Author: + * Lauris Kaplinski + * + * Copyright (C) 2000 Lauris Kaplinski + * Copyright (C) 2000-2001 Ximian, Inc. + * Copyright (C) 2002 Lauris Kaplinski + * + * Released under GNU GPL + */ + + +#include +#include +#include +#include + +#define SP_CURVE_LENSTEP 32 + +static bool sp_bpath_good(NArtBpath const bpath[]); +static NArtBpath *sp_bpath_clean(NArtBpath const bpath[]); +static NArtBpath const *sp_bpath_check_subpath(NArtBpath const bpath[]); +static unsigned sp_bpath_length(NArtBpath const bpath[]); +static bool sp_bpath_closed(NArtBpath const bpath[]); + +/* Constructors */ + +/** + * The returned curve's state is as if sp_curve_reset has just been called on it. + */ +SPCurve * +sp_curve_new() +{ + return sp_curve_new_sized(SP_CURVE_LENSTEP); +} + +/** + * Like sp_curve_new, but overriding the default initial capacity. + * + * The returned curve's state is as if sp_curve_reset has just been called on it. + * + * \param length Initial number of NArtBpath elements allocated for bpath (including NR_END + * element). + */ +SPCurve * +sp_curve_new_sized(gint length) +{ + g_return_val_if_fail(length > 0, NULL); + + SPCurve *curve = g_new(SPCurve, 1); + + curve->refcount = 1; + curve->bpath = nr_new(NArtBpath, length); + curve->bpath->code = NR_END; + curve->end = 0; + curve->length = length; + curve->substart = 0; + curve->sbpath = false; + curve->hascpt = false; + curve->posSet = false; + curve->moving = false; + curve->closed = false; + + return curve; +} + +/** + * Convert NArtBpath object to SPCurve object. + * + * \return new SPCurve, or NULL if the curve was not created for some reason. + */ +SPCurve * +sp_curve_new_from_bpath(NArtBpath *bpath) +{ + g_return_val_if_fail(bpath != NULL, NULL); + + if (!sp_bpath_good(bpath)) { + NArtBpath *new_bpath = sp_bpath_clean(bpath); + if (new_bpath == NULL) { + return NULL; + } + nr_free(bpath); + bpath = new_bpath; + } + + SPCurve *curve = g_new(SPCurve, 1); + + curve->refcount = 1; + curve->bpath = bpath; + curve->length = sp_bpath_length(bpath); + curve->end = curve->length - 1; + gint i = curve->end; + for (; i > 0; i--) + if ((curve->bpath[i].code == NR_MOVETO) || + (curve->bpath[i].code == NR_MOVETO_OPEN)) + break; + curve->substart = i; + curve->sbpath = false; + curve->hascpt = false; + curve->posSet = false; + curve->moving = false; + curve->closed = sp_bpath_closed(bpath); + + return curve; +} + +/** + * Construct an SPCurve from read-only, static storage. + * + * We could treat read-onliness and staticness (i.e. can't call free on bpath) as orthogonal + * attributes, but at the time of writing we have only one caller. + */ +SPCurve * +sp_curve_new_from_static_bpath(NArtBpath const *bpath) +{ + g_return_val_if_fail(bpath != NULL, NULL); + + bool sbpath; + if (!sp_bpath_good(bpath)) { + NArtBpath *new_bpath = sp_bpath_clean(bpath); + g_return_val_if_fail(new_bpath != NULL, NULL); + sbpath = false; + bpath = new_bpath; + } else { + sbpath = true; + } + + SPCurve *curve = g_new(SPCurve, 1); + + curve->refcount = 1; + curve->bpath = const_cast(bpath); + curve->length = sp_bpath_length(bpath); + curve->end = curve->length - 1; + gint i = curve->end; + for (; i > 0; i--) + if ((curve->bpath[i].code == NR_MOVETO) || + (curve->bpath[i].code == NR_MOVETO_OPEN)) + break; + curve->substart = i; + curve->sbpath = sbpath; + curve->hascpt = false; + curve->posSet = false; + curve->moving = false; + curve->closed = sp_bpath_closed(bpath); + + return curve; +} + +/** + * Convert const NArtBpath array to SPCurve. + * + * \return new SPCurve, or NULL if the curve was not created for some reason. + */ +SPCurve *sp_curve_new_from_foreign_bpath(NArtBpath const bpath[]) +{ + g_return_val_if_fail(bpath != NULL, NULL); + + NArtBpath *new_bpath; + if (!sp_bpath_good(bpath)) { + new_bpath = sp_bpath_clean(bpath); + g_return_val_if_fail(new_bpath != NULL, NULL); + } else { + unsigned const len = sp_bpath_length(bpath); + new_bpath = nr_new(NArtBpath, len); + memcpy(new_bpath, bpath, len * sizeof(NArtBpath)); + } + + SPCurve *curve = sp_curve_new_from_bpath(new_bpath); + + if (!curve) + nr_free(new_bpath); + + return curve; +} + +/** + * Increase refcount of curve. + * + * \todo should this be shared with other refcounting code? + */ +SPCurve * +sp_curve_ref(SPCurve *curve) +{ + g_return_val_if_fail(curve != NULL, NULL); + + curve->refcount += 1; + + return curve; +} + +/** + * Decrease refcount of curve, with possible destruction. + * + * \todo should this be shared with other refcounting code? + */ +SPCurve * +sp_curve_unref(SPCurve *curve) +{ + g_return_val_if_fail(curve != NULL, NULL); + + curve->refcount -= 1; + + if (curve->refcount < 1) { + if ((!curve->sbpath) && (curve->bpath)) { + nr_free(curve->bpath); + } + g_free(curve); + } + + return NULL; +} + +/** + * Add space for more paths in curve. + */ +static void +sp_curve_ensure_space(SPCurve *curve, gint space) +{ + g_return_if_fail(curve != NULL); + g_return_if_fail(space > 0); + + if (curve->end + space < curve->length) + return; + + if (space < SP_CURVE_LENSTEP) + space = SP_CURVE_LENSTEP; + + curve->bpath = nr_renew(curve->bpath, NArtBpath, curve->length + space); + + curve->length += space; +} + +/** + * Create new curve from its own bpath array. + */ +SPCurve * +sp_curve_copy(SPCurve *curve) +{ + g_return_val_if_fail(curve != NULL, NULL); + + return sp_curve_new_from_foreign_bpath(curve->bpath); +} + +/** + * Return new curve that is the concatenation of all curves in list. + */ +SPCurve * +sp_curve_concat(GSList const *list) +{ + g_return_val_if_fail(list != NULL, NULL); + + gint length = 0; + + for (GSList const *l = list; l != NULL; l = l->next) { + SPCurve *c = (SPCurve *) l->data; + length += c->end; + } + + SPCurve *new_curve = sp_curve_new_sized(length + 1); + + NArtBpath *bp = new_curve->bpath; + + for (GSList const *l = list; l != NULL; l = l->next) { + SPCurve *c = (SPCurve *) l->data; + memcpy(bp, c->bpath, c->end * sizeof(NArtBpath)); + bp += c->end; + } + + bp->code = NR_END; + + new_curve->end = length; + gint i; + for (i = new_curve->end; i > 0; i--) { + if ((new_curve->bpath[i].code == NR_MOVETO) || + (new_curve->bpath[i].code == NR_MOVETO_OPEN) ) + break; + } + + new_curve->substart = i; + + return new_curve; +} + +/** + * Returns a list of new curves corresponding to the subpaths in \a curve. + */ +GSList * +sp_curve_split(SPCurve const *curve) +{ + g_return_val_if_fail(curve != NULL, NULL); + + gint p = 0; + GSList *l = NULL; + + while (p < curve->end) { + gint i = 1; + while ((curve->bpath[p + i].code == NR_LINETO) || + (curve->bpath[p + i].code == NR_CURVETO)) + i++; + SPCurve *new_curve = sp_curve_new_sized(i + 1); + memcpy(new_curve->bpath, curve->bpath + p, i * sizeof(NArtBpath)); + new_curve->end = i; + new_curve->bpath[i].code = NR_END; + new_curve->substart = 0; + new_curve->closed = (new_curve->bpath->code == NR_MOVETO); + new_curve->hascpt = (new_curve->bpath->code == NR_MOVETO_OPEN); + l = g_slist_append(l, new_curve); + /** \todo + * effic: Use g_slist_prepend instead. Either work backwards from + * the end of curve, or work forwards as at present but do + * g_slist_reverse before returning. + */ + p += i; + } + + return l; +} + +/** + * Transform all paths in curve, template helper. + */ +template +static void +tmpl_curve_transform(SPCurve *const curve, M const &m) +{ + g_return_if_fail(curve != NULL); + g_return_if_fail(!curve->sbpath); + + for (gint i = 0; i < curve->end; i++) { + NArtBpath *p = curve->bpath + i; + switch (p->code) { + case NR_MOVETO: + case NR_MOVETO_OPEN: + case NR_LINETO: { + p->setC(3, p->c(3) * m); + break; + } + case NR_CURVETO: + for (unsigned i = 1; i <= 3; ++i) { + p->setC(i, p->c(i) * m); + } + break; + default: + g_warning("Illegal pathcode %d", p->code); + break; + } + } +} + +/** + * Transform all paths in curve using matrix. + */ +void +sp_curve_transform(SPCurve *const curve, NR::Matrix const &m) +{ + tmpl_curve_transform(curve, m); +} + +/** + * Transform all paths in curve using NR::translate. + */ +void +sp_curve_transform(SPCurve *const curve, NR::translate const &m) +{ + tmpl_curve_transform(curve, m); +} + + +/* Methods */ + +/** + * Set curve to empty curve. + */ +void +sp_curve_reset(SPCurve *curve) +{ + g_return_if_fail(curve != NULL); + g_return_if_fail(!curve->sbpath); + + curve->bpath->code = NR_END; + curve->end = 0; + curve->substart = 0; + curve->hascpt = false; + curve->posSet = false; + curve->moving = false; + curve->closed = false; +} + +/* Several consecutive movetos are ALLOWED */ + +/** + * Calls sp_curve_moveto() with point made of given coordinates. + */ +void +sp_curve_moveto(SPCurve *curve, gdouble x, gdouble y) +{ + sp_curve_moveto(curve, NR::Point(x, y)); +} + +/** + * Perform a moveto to a point, thus starting a new subpath. + */ +void +sp_curve_moveto(SPCurve *curve, NR::Point const &p) +{ + g_return_if_fail(curve != NULL); + g_return_if_fail(!curve->sbpath); + g_return_if_fail(!curve->moving); + + curve->substart = curve->end; + curve->hascpt = true; + curve->posSet = true; + curve->movePos = p; +} + +/** + * Calls sp_curve_lineto() with a point's coordinates. + */ +void +sp_curve_lineto(SPCurve *curve, NR::Point const &p) +{ + sp_curve_lineto(curve, p[NR::X], p[NR::Y]); +} + +/** + * Adds a line to the current subpath. + */ +void +sp_curve_lineto(SPCurve *curve, gdouble x, gdouble y) +{ + g_return_if_fail(curve != NULL); + g_return_if_fail(!curve->sbpath); + g_return_if_fail(curve->hascpt); + + if (curve->moving) { + /* fix endpoint */ + g_return_if_fail(!curve->posSet); + g_return_if_fail(curve->end > 1); + NArtBpath *bp = curve->bpath + curve->end - 1; + g_return_if_fail(bp->code == NR_LINETO); + bp->x3 = x; + bp->y3 = y; + curve->moving = false; + return; + } + + if (curve->posSet) { + /* start a new segment */ + sp_curve_ensure_space(curve, 2); + NArtBpath *bp = curve->bpath + curve->end; + bp->code = NR_MOVETO_OPEN; + bp->setC(3, curve->movePos); + bp++; + bp->code = NR_LINETO; + bp->x3 = x; + bp->y3 = y; + bp++; + bp->code = NR_END; + curve->end += 2; + curve->posSet = false; + curve->closed = false; + return; + } + + /* add line */ + + g_return_if_fail(curve->end > 1); + sp_curve_ensure_space(curve, 1); + NArtBpath *bp = curve->bpath + curve->end; + bp->code = NR_LINETO; + bp->x3 = x; + bp->y3 = y; + bp++; + bp->code = NR_END; + curve->end++; +} + +/// Unused +void +sp_curve_lineto_moving(SPCurve *curve, gdouble x, gdouble y) +{ + g_return_if_fail(curve != NULL); + g_return_if_fail(!curve->sbpath); + g_return_if_fail(curve->hascpt); + + if (curve->moving) { + /* change endpoint */ + g_return_if_fail(!curve->posSet); + g_return_if_fail(curve->end > 1); + NArtBpath *bp = curve->bpath + curve->end - 1; + g_return_if_fail(bp->code == NR_LINETO); + bp->x3 = x; + bp->y3 = y; + return; + } + + if (curve->posSet) { + /* start a new segment */ + sp_curve_ensure_space(curve, 2); + NArtBpath *bp = curve->bpath + curve->end; + bp->code = NR_MOVETO_OPEN; + bp->setC(3, curve->movePos); + bp++; + bp->code = NR_LINETO; + bp->x3 = x; + bp->y3 = y; + bp++; + bp->code = NR_END; + curve->end += 2; + curve->posSet = false; + curve->moving = true; + curve->closed = false; + return; + } + + /* add line */ + + g_return_if_fail(curve->end > 1); + sp_curve_ensure_space(curve, 1); + NArtBpath *bp = curve->bpath + curve->end; + bp->code = NR_LINETO; + bp->x3 = x; + bp->y3 = y; + bp++; + bp->code = NR_END; + curve->end++; + curve->moving = true; +} + +/** + * Calls sp_curve_curveto() with coordinates of three points. + */ +void +sp_curve_curveto(SPCurve *curve, NR::Point const &p0, NR::Point const &p1, NR::Point const &p2) +{ + using NR::X; + using NR::Y; + sp_curve_curveto(curve, + p0[X], p0[Y], + p1[X], p1[Y], + p2[X], p2[Y]); +} + +/** + * Adds a bezier segment to the current subpath. + */ +void +sp_curve_curveto(SPCurve *curve, gdouble x0, gdouble y0, gdouble x1, gdouble y1, gdouble x2, gdouble y2) +{ + g_return_if_fail(curve != NULL); + g_return_if_fail(!curve->sbpath); + g_return_if_fail(curve->hascpt); + g_return_if_fail(!curve->moving); + + if (curve->posSet) { + /* start a new segment */ + sp_curve_ensure_space(curve, 2); + NArtBpath *bp = curve->bpath + curve->end; + bp->code = NR_MOVETO_OPEN; + bp->setC(3, curve->movePos); + bp++; + bp->code = NR_CURVETO; + bp->x1 = x0; + bp->y1 = y0; + bp->x2 = x1; + bp->y2 = y1; + bp->x3 = x2; + bp->y3 = y2; + bp++; + bp->code = NR_END; + curve->end += 2; + curve->posSet = false; + curve->closed = false; + return; + } + + /* add curve */ + + g_return_if_fail(curve->end > 1); + sp_curve_ensure_space(curve, 1); + NArtBpath *bp = curve->bpath + curve->end; + bp->code = NR_CURVETO; + bp->x1 = x0; + bp->y1 = y0; + bp->x2 = x1; + bp->y2 = y1; + bp->x3 = x2; + bp->y3 = y2; + bp++; + bp->code = NR_END; + curve->end++; +} + +/** + * Close current subpath by possibly adding a line between start and end. + */ +void +sp_curve_closepath(SPCurve *curve) +{ + g_return_if_fail(curve != NULL); + g_return_if_fail(!curve->sbpath); + g_return_if_fail(curve->hascpt); + g_return_if_fail(!curve->posSet); + g_return_if_fail(!curve->moving); + g_return_if_fail(!curve->closed); + /* We need at least moveto, curveto, end. */ + g_return_if_fail(curve->end - curve->substart > 1); + + { + NArtBpath *bs = curve->bpath + curve->substart; + NArtBpath *be = curve->bpath + curve->end - 1; + + if (bs->c(3) != be->c(3)) { + sp_curve_lineto(curve, bs->c(3)); + bs = curve->bpath + curve->substart; + } + + bs->code = NR_MOVETO; + } + curve->closed = true; + + for (NArtBpath const *bp = curve->bpath; bp->code != NR_END; bp++) { + /** \todo + * effic: Maintain a count of NR_MOVETO_OPEN's (e.g. instead of + * the closed boolean). + */ + if (bp->code == NR_MOVETO_OPEN) { + curve->closed = false; + break; + } + } + + curve->hascpt = false; +} + +/** Like sp_curve_closepath() but sets the end point of the current + command to the subpath start point instead of adding a new lineto. + + Used for freehand drawing when the user draws back to the start point. +**/ +void +sp_curve_closepath_current(SPCurve *curve) +{ + g_return_if_fail(curve != NULL); + g_return_if_fail(!curve->sbpath); + g_return_if_fail(curve->hascpt); + g_return_if_fail(!curve->posSet); + g_return_if_fail(!curve->closed); + /* We need at least moveto, curveto, end. */ + g_return_if_fail(curve->end - curve->substart > 1); + + { + NArtBpath *bs = curve->bpath + curve->substart; + NArtBpath *be = curve->bpath + curve->end - 1; + + be->x3 = bs->x3; + be->y3 = bs->y3; + + bs->code = NR_MOVETO; + } + curve->closed = true; + + for (NArtBpath const *bp = curve->bpath; bp->code != NR_END; bp++) { + /** \todo + * effic: Maintain a count of NR_MOVETO_OPEN's (e.g. instead of + * the closed boolean). + */ + if (bp->code == NR_MOVETO_OPEN) { + curve->closed = false; + break; + } + } + + curve->hascpt = false; + curve->moving = false; +} + +/** + * True if no paths are in curve. + */ +bool +sp_curve_empty(SPCurve *curve) +{ + g_return_val_if_fail(curve != NULL, TRUE); + + return (curve->bpath->code == NR_END); +} + +/** + * Return last subpath or NULL. + */ +NArtBpath * +sp_curve_last_bpath(SPCurve const *curve) +{ + g_return_val_if_fail(curve != NULL, NULL); + + if (curve->end == 0) { + return NULL; + } + + return curve->bpath + curve->end - 1; +} + +/** + * Return first subpath or NULL. + */ +NArtBpath * +sp_curve_first_bpath(SPCurve const *curve) +{ + g_return_val_if_fail(curve != NULL, NULL); + + if (curve->end == 0) { + return NULL; + } + + return curve->bpath; +} + +/** + * Return first point of first subpath or (0,0). + */ +NR::Point +sp_curve_first_point(SPCurve const *const curve) +{ + NArtBpath *const bpath = sp_curve_first_bpath(curve); + g_return_val_if_fail(bpath != NULL, NR::Point(0, 0)); + return bpath->c(3); +} + +/** + * Return the second point of first subpath or curve->movePos if curve too short. + */ +NR::Point +sp_curve_second_point(SPCurve const *const curve) +{ + g_return_val_if_fail(curve != NULL, NR::Point(0, 0)); + + if (curve->end < 1) { + return curve->movePos; + } + + NArtBpath *bpath = NULL; + if (curve->end < 2) { + bpath = curve->bpath; + } else { + bpath = curve->bpath + 1; + } + g_return_val_if_fail(bpath != NULL, NR::Point(0, 0)); + return bpath->c(3); +} + +/** + * Return the second-last point of last subpath or curve->movePos if curve too short. + */ +NR::Point +sp_curve_penultimate_point(SPCurve const *const curve) +{ + g_return_val_if_fail(curve != NULL, NR::Point(0, 0)); + + if (curve->end < 2) { + return curve->movePos; + } + + NArtBpath *const bpath = curve->bpath + curve->end - 2; + g_return_val_if_fail(bpath != NULL, NR::Point(0, 0)); + return bpath->c(3); +} + +/** + * Return last point of last subpath or (0,0). + */ +NR::Point +sp_curve_last_point(SPCurve const *const curve) +{ + NArtBpath *const bpath = sp_curve_last_bpath(curve); + g_return_val_if_fail(bpath != NULL, NR::Point(0, 0)); + return bpath->c(3); +} + +inline static bool +is_moveto(NRPathcode const c) +{ + return c == NR_MOVETO || c == NR_MOVETO_OPEN; +} + +/** + * Returns \a curve but drawn in the opposite direction. + * Should result in the same shape, but + * with all its markers drawn facing the other direction. + **/ +SPCurve * +sp_curve_reverse(SPCurve const *curve) +{ + /* We need at least moveto, curveto, end. */ + g_return_val_if_fail(curve->end - curve->substart > 1, NULL); + + NArtBpath const *be = curve->bpath + curve->end - 1; + + g_assert(is_moveto(curve->bpath[curve->substart].code)); + g_assert(is_moveto(curve->bpath[0].code)); + g_assert((be+1)->code == NR_END); + + SPCurve *new_curve = sp_curve_new_sized(curve->length); + sp_curve_moveto(new_curve, be->c(3)); + + for (NArtBpath const *bp = be; ; --bp) { + switch (bp->code) { + case NR_MOVETO: + g_assert(new_curve->bpath[new_curve->substart].code == NR_MOVETO_OPEN); + new_curve->bpath[new_curve->substart].code = NR_MOVETO; + /* FALL-THROUGH */ + case NR_MOVETO_OPEN: + if (bp == curve->bpath) { + return new_curve; + } + sp_curve_moveto(new_curve, (bp-1)->c(3)); + break; + + case NR_LINETO: + sp_curve_lineto(new_curve, (bp-1)->c(3)); + break; + + case NR_CURVETO: + sp_curve_curveto(new_curve, bp->c(2), bp->c(1), (bp-1)->c(3)); + break; + + default: + g_assert_not_reached(); + } + } +} + +/** + * Append \a curve2 to \a curve. + */ +void +sp_curve_append(SPCurve *curve, + SPCurve const *curve2, + bool use_lineto) +{ + g_return_if_fail(curve != NULL); + g_return_if_fail(curve2 != NULL); + + if (curve2->end < 1) + return; + + NArtBpath const *bs = curve2->bpath; + + bool closed = curve->closed; + + for (NArtBpath const *bp = bs; bp->code != NR_END; bp++) { + switch (bp->code) { + case NR_MOVETO_OPEN: + if (use_lineto && curve->hascpt) { + sp_curve_lineto(curve, bp->x3, bp->y3); + use_lineto = FALSE; + } else { + if (closed) sp_curve_closepath(curve); + sp_curve_moveto(curve, bp->x3, bp->y3); + } + closed = false; + break; + + case NR_MOVETO: + if (use_lineto && curve->hascpt) { + sp_curve_lineto(curve, bp->x3, bp->y3); + use_lineto = FALSE; + } else { + if (closed) sp_curve_closepath(curve); + sp_curve_moveto(curve, bp->x3, bp->y3); + } + closed = true; + break; + + case NR_LINETO: + sp_curve_lineto(curve, bp->x3, bp->y3); + break; + + case NR_CURVETO: + sp_curve_curveto(curve, bp->x1, bp->y1, bp->x2, bp->y2, bp->x3, bp->y3); + break; + + case NR_END: + g_assert_not_reached(); + } + } + + if (closed) { + sp_curve_closepath(curve); + } +} + +/** + * Append \a c1 to \a c0 with possible fusing of close endpoints. + */ +SPCurve * +sp_curve_append_continuous(SPCurve *c0, SPCurve const *c1, gdouble tolerance) +{ + g_return_val_if_fail(c0 != NULL, NULL); + g_return_val_if_fail(c1 != NULL, NULL); + g_return_val_if_fail(!c0->closed, NULL); + g_return_val_if_fail(!c1->closed, NULL); + + if (c1->end < 1) { + return c0; + } + + NArtBpath *be = sp_curve_last_bpath(c0); + if (be) { + NArtBpath const *bs = sp_curve_first_bpath(c1); + if ( bs + && ( fabs( bs->x3 - be->x3 ) <= tolerance ) + && ( fabs( bs->y3 - be->y3 ) <= tolerance ) ) + { + /** \todo + * fixme: Strictly we mess in case of multisegment mixed + * open/close curves + */ + bool closed = false; + for (bs = bs + 1; bs->code != NR_END; bs++) { + switch (bs->code) { + case NR_MOVETO_OPEN: + if (closed) sp_curve_closepath(c0); + sp_curve_moveto(c0, bs->x3, bs->y3); + closed = false; + break; + case NR_MOVETO: + if (closed) sp_curve_closepath(c0); + sp_curve_moveto(c0, bs->x3, bs->y3); + closed = true; + break; + case NR_LINETO: + sp_curve_lineto(c0, bs->x3, bs->y3); + break; + case NR_CURVETO: + sp_curve_curveto(c0, bs->x1, bs->y1, bs->x2, bs->y2, bs->x3, bs->y3); + break; + case NR_END: + g_assert_not_reached(); + } + } + } else { + sp_curve_append(c0, c1, TRUE); + } + } else { + sp_curve_append(c0, c1, TRUE); + } + + return c0; +} + +/** + * Remove last segment of curve. + */ +void +sp_curve_backspace(SPCurve *curve) +{ + g_return_if_fail(curve != NULL); + + if (curve->end > 0) { + curve->end -= 1; + if (curve->end > 0) { + NArtBpath *bp = curve->bpath + curve->end - 1; + if ((bp->code == NR_MOVETO) || + (bp->code == NR_MOVETO_OPEN) ) + { + curve->hascpt = true; + curve->posSet = true; + curve->closed = false; + curve->movePos = bp->c(3); + curve->end -= 1; + } + } + curve->bpath[curve->end].code = NR_END; + } +} + +/* Private methods */ + +/** + * True if all subpaths in bpath array pass consistency check. + */ +static bool sp_bpath_good(NArtBpath const bpath[]) +{ + g_return_val_if_fail(bpath != NULL, FALSE); + + NArtBpath const *bp = bpath; + while (bp->code != NR_END) { + bp = sp_bpath_check_subpath(bp); + if (bp == NULL) + return false; + } + + return true; +} + +/** + * Return copy of a bpath array, discarding any inconsistencies. + */ +static NArtBpath *sp_bpath_clean(NArtBpath const bpath[]) +{ + NArtBpath *new_bpath = nr_new(NArtBpath, sp_bpath_length(bpath)); + + NArtBpath const *bp = bpath; + NArtBpath *np = new_bpath; + + while (bp->code != NR_END) { + if (sp_bpath_check_subpath(bp)) { + *np++ = *bp++; + while ((bp->code == NR_LINETO) || + (bp->code == NR_CURVETO)) + *np++ = *bp++; + } else { + bp++; + while ((bp->code == NR_LINETO) || + (bp->code == NR_CURVETO)) + bp++; + } + } + + if (np == new_bpath) { + nr_free(new_bpath); + return NULL; + } + + np->code = NR_END; + np += 1; + + new_bpath = nr_renew(new_bpath, NArtBpath, np - new_bpath); + + return new_bpath; +} + +/** + * Perform consistency check of bpath array. + * \return Address of NR_END node or NULL. + */ +static NArtBpath const *sp_bpath_check_subpath(NArtBpath const bpath[]) +{ + g_return_val_if_fail(bpath != NULL, NULL); + + bool closed; + if (bpath->code == NR_MOVETO) { + closed = true; + } else if (bpath->code == NR_MOVETO_OPEN) { + closed = false; + } else { + return NULL; + } + + gint len = 0; + gint i; + /** \todo + * effic: consider checking for END/MOVE/MOVETO inside switch block + */ + for (i = 1; (bpath[i].code != NR_END) && (bpath[i].code != NR_MOVETO) && (bpath[i].code != NR_MOVETO_OPEN); i++) { + switch (bpath[i].code) { + case NR_LINETO: + case NR_CURVETO: + len++; + break; + default: + return NULL; + } + } + + if (closed) { + if (len < 1) + return NULL; + + if ((bpath->x3 != bpath[i-1].x3) || (bpath->y3 != bpath[i-1].y3)) + return NULL; + } else { + if (len < 1) + return NULL; + } + + return bpath + i; +} + +/** + * Returns index of first NR_END bpath in array. + */ +static unsigned sp_bpath_length(NArtBpath const bpath[]) +{ + g_return_val_if_fail(bpath != NULL, FALSE); + + unsigned ret = 0; + while ( bpath[ret].code != NR_END ) { + ++ret; + } + ++ret; + + return ret; +} + +/** + * \brief + * + * \todo + * fixme: this is bogus -- it doesn't check for nr_moveto, which will indicate + * a closing of the subpath it's nonsense to talk about a path as a whole + * being closed, although maybe someone would want that for some other reason? + * Oh, also, if the bpath just ends, then it's *open*. I hope nobody is using + * this code for anything. + */ +static bool sp_bpath_closed(NArtBpath const bpath[]) +{ + g_return_val_if_fail(bpath != NULL, FALSE); + + for (NArtBpath const *bp = bpath; bp->code != NR_END; bp++) { + if (bp->code == NR_MOVETO_OPEN) { + return false; + } + } + + return true; +} + +/** + * Returns length of bezier segment. + */ +static double +bezier_len(NR::Point const &c0, + NR::Point const &c1, + NR::Point const &c2, + NR::Point const &c3, + double const threshold) +{ + /** \todo + * The SVG spec claims that a closed form exists, but for the moment I'll + * use a stupid algorithm. + */ + double const lbound = L2( c3 - c0 ); + double const ubound = L2( c1 - c0 ) + L2( c2 - c1 ) + L2( c3 - c2 ); + double ret; + if ( ubound - lbound <= threshold ) { + ret = .5 * ( lbound + ubound ); + } else { + NR::Point const a1( .5 * ( c0 + c1 ) ); + NR::Point const b2( .5 * ( c2 + c3 ) ); + NR::Point const c12( .5 * ( c1 + c2 ) ); + NR::Point const a2( .5 * ( a1 + c12 ) ); + NR::Point const b1( .5 * ( c12 + b2 ) ); + NR::Point const midpoint( .5 * ( a2 + b1 ) ); + double const rec_threshold = .625 * threshold; + ret = bezier_len(c0, a1, a2, midpoint, rec_threshold) + bezier_len(midpoint, b1, b2, c3, rec_threshold); + if (!(lbound - 1e-2 <= ret && ret <= ubound + 1e-2)) { + using NR::X; using NR::Y; + g_warning("ret=%f outside of expected bounds [%f, %f] for {(%.0f %.0f) (%.0f %.0f) (%.0f %.0f) (%.0f %.0f)}", + ret, lbound, ubound, c0[X], c0[Y], c1[X], c1[Y], c2[X], c2[Y], c3[X], c3[Y]); + } + } + return ret; +} + +/** + * Returns total length of curve, excluding length of closepath segments. + */ +static double +sp_curve_distance_including_space(SPCurve const *const curve, double seg2len[]) +{ + g_return_val_if_fail(curve != NULL, 0.); + + double ret = 0.0; + + if ( curve->bpath->code == NR_END ) { + return ret; + } + + NR::Point prev(curve->bpath->c(3)); + for (gint i = 1; i < curve->end; ++i) { + NArtBpath &p = curve->bpath[i]; + double seg_len = 0; + switch (p.code) { + case NR_MOVETO_OPEN: + case NR_MOVETO: + case NR_LINETO: + seg_len = L2(p.c(3) - prev); + break; + + case NR_CURVETO: + seg_len = bezier_len(prev, p.c(1), p.c(2), p.c(3), 1.); + break; + + case NR_END: + return ret; + } + seg2len[i - 1] = seg_len; + ret += seg_len; + prev = p.c(3); + } + g_assert(!(ret < 0)); + return ret; +} + +/** + * Like sp_curve_distance_including_space(), but ensures that the + * result >= 1e-18: uses 1 per segment if necessary. + */ +static double +sp_curve_nonzero_distance_including_space(SPCurve const *const curve, double seg2len[]) +{ + double const real_dist(sp_curve_distance_including_space(curve, seg2len)); + if (real_dist >= 1e-18) { + return real_dist; + } else { + unsigned const nSegs = SP_CURVE_LENGTH(curve) - 1; + for (unsigned i = 0; i < nSegs; ++i) { + seg2len[i] = 1.; + } + return (double) nSegs; + } +} + +void +sp_curve_stretch_endpoints(SPCurve *curve, NR::Point const &new_p0, NR::Point const &new_p1) +{ + if (sp_curve_empty(curve)) { + return; + } + g_assert(unsigned(SP_CURVE_LENGTH(curve)) + 1 == sp_bpath_length(curve->bpath)); + unsigned const nSegs = SP_CURVE_LENGTH(curve) - 1; + g_assert(nSegs != 0); + double *const seg2len = new double[nSegs]; + double const tot_len = sp_curve_nonzero_distance_including_space(curve, seg2len); + NR::Point const offset0( new_p0 - sp_curve_first_point(curve) ); + NR::Point const offset1( new_p1 - sp_curve_last_point(curve) ); + curve->bpath->setC(3, new_p0); + double begin_dist = 0.; + for (unsigned si = 0; si < nSegs; ++si) { + double const end_dist = begin_dist + seg2len[si]; + NArtBpath &p = curve->bpath[1 + si]; + switch (p.code) { + case NR_LINETO: + case NR_MOVETO: + case NR_MOVETO_OPEN: + p.setC(3, p.c(3) + NR::Lerp(end_dist / tot_len, offset0, offset1)); + break; + + case NR_CURVETO: + for (unsigned ci = 1; ci <= 3; ++ci) { + p.setC(ci, p.c(ci) + Lerp((begin_dist + ci * seg2len[si] / 3.) / tot_len, offset0, offset1)); + } + break; + + default: + g_assert_not_reached(); + } + + begin_dist = end_dist; + } + g_assert(L1(curve->bpath[nSegs].c(3) - new_p1) < 1.); + /* Explicit set for better numerical properties. */ + curve->bpath[nSegs].setC(3, new_p1); + delete [] seg2len; +} + +void +sp_curve_move_endpoints(SPCurve *curve, NR::Point const &new_p0, + NR::Point const &new_p1) +{ + if (sp_curve_empty(curve)) { + return; + } + unsigned const nSegs = SP_CURVE_LENGTH(curve) - 1; + g_assert(nSegs != 0); + + curve->bpath->setC(3, new_p0); + curve->bpath[nSegs].setC(3, new_p1); +} + + +/* + 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 : diff --git a/src/display/curve.h b/src/display/curve.h new file mode 100644 index 000000000..d63796140 --- /dev/null +++ b/src/display/curve.h @@ -0,0 +1,133 @@ +#ifndef SEEN_DISPLAY_CURVE_H +#define SEEN_DISPLAY_CURVE_H + +/** \file + * Wrapper around an array of NArtBpath objects. + * + * Author: + * Lauris Kaplinski + * + * Copyright (C) 2000 Lauris Kaplinski + * Copyright (C) 2000-2001 Ximian, Inc. + * Copyright (C) 2002 Lauris Kaplinski + * + * Released under GNU GPL + */ + +#include +#include + +#include "libnr/nr-forward.h" +#include "libnr/nr-point.h" + +/// Wrapper around NArtBpath. +struct SPCurve { + gint refcount; + NArtBpath *bpath; + + /// Index in bpath[] of NR_END element. + gint end; + + /// Allocated size (i.e., capacity) of bpath[] array. Not to be confused + /// with the SP_CURVE_LENGTH macro, which returns the logical length of + /// the path (i.e., index of NR_END). + gint length; + + /// Index in bpath[] of the start (i.e., moveto element) of the last + /// subpath in this path. + gint substart; + + /// Previous moveto position. + /// \note This is used for coalescing moveto's, whereas if we're to + /// conform to the SVG spec then we mustn't coalesce movetos if we have + /// midpoint markers. Ref: + /// http://www.w3.org/TR/SVG11/implnote.html#PathElementImplementationNotes + /// (first subitem of the item about zero-length path segments) + NR::Point movePos; + + /// True iff bpath points to read-only, static storage (see callers of + /// sp_curve_new_from_static_bpath), in which case we shouldn't free + /// bpath and shouldn't write through it. + bool sbpath : 1; + + /// True iff current point is defined. Initially false for a new curve; + /// becomes true after moveto; becomes false on closepath. Curveto, + /// lineto etc. require hascpt; hascpt remains true after lineto/curveto. + bool hascpt : 1; + + /// True iff previous was moveto. + bool posSet : 1; + + /// True iff bpath end is moving. + bool moving : 1; + + /// True iff all subpaths are closed. + bool closed : 1; +}; + +#define SP_CURVE_LENGTH(c) (((SPCurve const *)(c))->end) +#define SP_CURVE_BPATH(c) (((SPCurve const *)(c))->bpath) +#define SP_CURVE_SEGMENT(c,i) (((SPCurve const *)(c))->bpath + (i)) + +/* Constructors */ + +SPCurve *sp_curve_new(); +SPCurve *sp_curve_new_sized(gint length); +SPCurve *sp_curve_new_from_bpath(NArtBpath *bpath); +SPCurve *sp_curve_new_from_static_bpath(NArtBpath const *bpath); +SPCurve *sp_curve_new_from_foreign_bpath(NArtBpath const bpath[]); + +SPCurve *sp_curve_ref(SPCurve *curve); +SPCurve *sp_curve_unref(SPCurve *curve); + +SPCurve *sp_curve_copy(SPCurve *curve); +SPCurve *sp_curve_concat(GSList const *list); +GSList *sp_curve_split(SPCurve const *curve); +void sp_curve_transform(SPCurve *curve, NR::Matrix const &); +void sp_curve_transform(SPCurve *curve, NR::translate const &); +void sp_curve_stretch_endpoints(SPCurve *curve, NR::Point const &, NR::Point const &); +void sp_curve_move_endpoints(SPCurve *curve, NR::Point const &, + NR::Point const &); + +/* Methods */ + +void sp_curve_reset(SPCurve *curve); + +void sp_curve_moveto(SPCurve *curve, NR::Point const &p); +void sp_curve_moveto(SPCurve *curve, gdouble x, gdouble y); +void sp_curve_lineto(SPCurve *curve, NR::Point const &p); +void sp_curve_lineto(SPCurve *curve, gdouble x, gdouble y); +void sp_curve_lineto_moving(SPCurve *curve, gdouble x, gdouble y); +void sp_curve_curveto(SPCurve *curve, NR::Point const &p0, NR::Point const &p1, NR::Point const &p2); +void sp_curve_curveto(SPCurve *curve, gdouble x0, gdouble y0, gdouble x1, gdouble y1, gdouble x2, gdouble y2); +void sp_curve_closepath(SPCurve *curve); +void sp_curve_closepath_current(SPCurve *curve); + +SPCurve *sp_curve_append_continuous(SPCurve *c0, SPCurve const *c1, gdouble tolerance); + +#define sp_curve_is_empty sp_curve_empty +bool sp_curve_empty(SPCurve *curve); +NArtBpath *sp_curve_last_bpath(SPCurve const *curve); +NArtBpath *sp_curve_first_bpath(SPCurve const *curve); +NR::Point sp_curve_first_point(SPCurve const *curve); +NR::Point sp_curve_last_point(SPCurve const *curve); +NR::Point sp_curve_second_point(SPCurve const *curve); +NR::Point sp_curve_penultimate_point(SPCurve const *curve); + +void sp_curve_append(SPCurve *curve, SPCurve const *curve2, bool use_lineto); +SPCurve *sp_curve_reverse(SPCurve const *curve); +void sp_curve_backspace(SPCurve *curve); + + +#endif /* !SEEN_DISPLAY_CURVE_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 : diff --git a/src/display/display-forward.h b/src/display/display-forward.h new file mode 100644 index 000000000..2af6f2c44 --- /dev/null +++ b/src/display/display-forward.h @@ -0,0 +1,46 @@ +#ifndef SEEN_DISPLAY_DISPLAY_FORWARD_H +#define SEEN_DISPLAY_DISPLAY_FORWARD_H + +#include + +struct SPCanvas; +struct SPCanvasClass; +struct SPCanvasItem; +struct SPCanvasItemClass; +struct SPCanvasGroup; +struct SPCanvasGroupClass; +struct SPCurve; + + +#define SP_TYPE_CANVAS_ITEM (sp_canvas_item_get_type()) +#define SP_CANVAS_ITEM(obj) (GTK_CHECK_CAST((obj), SP_TYPE_CANVAS_ITEM, SPCanvasItem)) +#define SP_IS_CANVAS_ITEM(obj) (GTK_CHECK_TYPE((obj), SP_TYPE_CANVAS_ITEM)) +#define SP_CANVAS_ITEM_GET_CLASS(o) (GTK_CHECK_GET_CLASS((o), SP_TYPE_CANVAS_ITEM, SPCanvasItemClass)) + +GType sp_canvas_item_get_type(); + +#define SP_TYPE_CANVAS_GROUP (sp_canvas_group_get_type()) +#define SP_CANVAS_GROUP(obj) (GTK_CHECK_CAST((obj), SP_TYPE_CANVAS_GROUP, SPCanvasGroup)) +#define SP_IS_CANVAS_GROUP(obj) (GTK_CHECK_TYPE((obj), SP_TYPE_CANVAS_GROUP)) + +GType sp_canvas_group_get_type(); + +#define SP_TYPE_CANVAS (sp_canvas_get_type()) +#define SP_CANVAS(obj) (GTK_CHECK_CAST((obj), SP_TYPE_CANVAS, SPCanvas)) +#define SP_IS_CANVAS(obj) (GTK_CHECK_TYPE((obj), SP_TYPE_CANVAS)) + +GType sp_canvas_get_type(); + + +#endif /* !SEEN_DISPLAY_DISPLAY_FORWARD_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 : diff --git a/src/display/gnome-canvas-acetate.cpp b/src/display/gnome-canvas-acetate.cpp new file mode 100644 index 000000000..1a58c4b19 --- /dev/null +++ b/src/display/gnome-canvas-acetate.cpp @@ -0,0 +1,100 @@ +#define __SP_CANVAS_ACETATE_C__ + +/* + * Infinite invisible canvas item + * + * Author: + * Federico Mena + * Raph Levien + * Lauris Kaplinski + * + * Copyright (C) 1998-1999 The Free Software Foundation + * Copyright (C) 2002 Lauris Kaplinski + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "display-forward.h" +#include "gnome-canvas-acetate.h" + +static void sp_canvas_acetate_class_init (SPCanvasAcetateClass *klass); +static void sp_canvas_acetate_init (SPCanvasAcetate *acetate); +static void sp_canvas_acetate_destroy (GtkObject *object); + +static void sp_canvas_acetate_update (SPCanvasItem *item, NR::Matrix const &affine, unsigned int flags); +static double sp_canvas_acetate_point (SPCanvasItem *item, NR::Point p, SPCanvasItem **actual_item); + +static SPCanvasItemClass *parent_class; + +GtkType +sp_canvas_acetate_get_type (void) +{ + static GtkType acetate_type = 0; + if (!acetate_type) { + GtkTypeInfo acetate_info = { + "SPCanvasAcetate", + sizeof (SPCanvasAcetate), + sizeof (SPCanvasAcetateClass), + (GtkClassInitFunc) sp_canvas_acetate_class_init, + (GtkObjectInitFunc) sp_canvas_acetate_init, + NULL, NULL, NULL + }; + acetate_type = gtk_type_unique (sp_canvas_item_get_type (), &acetate_info); + } + return acetate_type; +} + +static void +sp_canvas_acetate_class_init (SPCanvasAcetateClass *klass) +{ + GtkObjectClass *object_class; + SPCanvasItemClass *item_class; + + object_class = (GtkObjectClass *) klass; + item_class = (SPCanvasItemClass *) klass; + + parent_class = (SPCanvasItemClass*)gtk_type_class (sp_canvas_item_get_type ()); + + object_class->destroy = sp_canvas_acetate_destroy; + + item_class->update = sp_canvas_acetate_update; + item_class->point = sp_canvas_acetate_point; +} + +static void +sp_canvas_acetate_init (SPCanvasAcetate *acetate) +{ + /* Nothing here */ +} + +static void +sp_canvas_acetate_destroy (GtkObject *object) +{ + SPCanvasAcetate *acetate; + + g_return_if_fail (object != NULL); + g_return_if_fail (GNOME_IS_CANVAS_ACETATE (object)); + + acetate = SP_CANVAS_ACETATE (object); + + if (GTK_OBJECT_CLASS (parent_class)->destroy) + (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); +} + +static void +sp_canvas_acetate_update (SPCanvasItem *item, NR::Matrix const &affine, unsigned int flags) +{ + item->x1 = -G_MAXINT; + item->y1 = -G_MAXINT; + item->x2 = G_MAXINT; + item->y2 = G_MAXINT; +} + +static double +sp_canvas_acetate_point (SPCanvasItem *item, NR::Point p, SPCanvasItem **actual_item) +{ + *actual_item = item; + + return 0.0; +} + diff --git a/src/display/gnome-canvas-acetate.h b/src/display/gnome-canvas-acetate.h new file mode 100644 index 000000000..40574e1bf --- /dev/null +++ b/src/display/gnome-canvas-acetate.h @@ -0,0 +1,41 @@ +#ifndef __SP_CANVAS_ACETATE_H__ +#define __SP_CANVAS_ACETATE_H__ + +/* + * Infinite invisible canvas item + * + * Author: + * Federico Mena + * Raph Levien + * Lauris Kaplinski + * + * Copyright (C) 1998-1999 The Free Software Foundation + * Copyright (C) 2002 Lauris Kaplinski + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include +#include "display/sp-canvas.h" + + +#define GNOME_TYPE_CANVAS_ACETATE (sp_canvas_acetate_get_type ()) +#define SP_CANVAS_ACETATE(obj) (GTK_CHECK_CAST ((obj), GNOME_TYPE_CANVAS_ACETATE, SPCanvasAcetate)) +#define SP_CANVAS_ACETATE_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), GNOME_TYPE_CANVAS_ACETATE, SPCanvasAcetateClass)) +#define GNOME_IS_CANVAS_ACETATE(obj) (GTK_CHECK_TYPE ((obj), GNOME_TYPE_CANVAS_ACETATE)) +#define GNOME_IS_CANVAS_ACETATE_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GNOME_TYPE_CANVAS_ACETATE)) + + +struct SPCanvasAcetate { + SPCanvasItem item; +}; + +struct SPCanvasAcetateClass { + SPCanvasItemClass parent_class; +}; + +GtkType sp_canvas_acetate_get_type (void); + + + +#endif diff --git a/src/display/guideline.cpp b/src/display/guideline.cpp new file mode 100644 index 000000000..d44ac8ab8 --- /dev/null +++ b/src/display/guideline.cpp @@ -0,0 +1,198 @@ +#define __SP_GUIDELINE_C__ + +/* + * Infinite horizontal/vertical line + * + * Author: + * Lauris Kaplinski + * + * Copyright (C) 2000-2002 Lauris Kaplinski + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + + +#include +#include "display-forward.h" +#include "sp-canvas-util.h" +#include "guideline.h" + +static void sp_guideline_class_init(SPGuideLineClass *c); +static void sp_guideline_init(SPGuideLine *guideline); +static void sp_guideline_destroy(GtkObject *object); + +static void sp_guideline_update(SPCanvasItem *item, NR::Matrix const &affine, unsigned int flags); +static void sp_guideline_render(SPCanvasItem *item, SPCanvasBuf *buf); + +static double sp_guideline_point(SPCanvasItem *item, NR::Point p, SPCanvasItem **actual_item); + +static SPCanvasItemClass *parent_class; + +GType sp_guideline_get_type() +{ + static GType guideline_type = 0; + + if (!guideline_type) { + static const GTypeInfo guideline_info = + { + sizeof (SPGuideLineClass), + NULL, NULL, + (GClassInitFunc) sp_guideline_class_init, + NULL, NULL, + sizeof (SPGuideLine), + 16, + (GInstanceInitFunc) sp_guideline_init, + NULL, + }; + + guideline_type = g_type_register_static(SP_TYPE_CANVAS_ITEM, "SPGuideLine", &guideline_info, (GTypeFlags) 0); + } + + return guideline_type; +} + +static void sp_guideline_class_init(SPGuideLineClass *c) +{ + parent_class = (SPCanvasItemClass*) g_type_class_peek_parent(c); + + GtkObjectClass *object_class = (GtkObjectClass *) c; + object_class->destroy = sp_guideline_destroy; + + SPCanvasItemClass *item_class = (SPCanvasItemClass *) c; + item_class->update = sp_guideline_update; + item_class->render = sp_guideline_render; + item_class->point = sp_guideline_point; +} + +static void sp_guideline_init(SPGuideLine *gl) +{ + gl->rgba = 0x0000ff7f; + + gl->vertical = 0; + gl->sensitive = 0; +} + +static void sp_guideline_destroy(GtkObject *object) +{ + GTK_OBJECT_CLASS(parent_class)->destroy(object); +} + +static void sp_guideline_render(SPCanvasItem *item, SPCanvasBuf *buf) +{ + SPGuideLine const *gl = SP_GUIDELINE (item); + + sp_canvas_prepare_buffer(buf); + + unsigned int const r = NR_RGBA32_R (gl->rgba); + unsigned int const g = NR_RGBA32_G (gl->rgba); + unsigned int const b = NR_RGBA32_B (gl->rgba); + unsigned int const a = NR_RGBA32_A (gl->rgba); + + int p0, p1, step; + unsigned char *d; + + if (gl->vertical) { + + if (gl->position < buf->rect.x0 || gl->position >= buf->rect.x1) { + return; + } + + p0 = buf->rect.y0; + p1 = buf->rect.y1; + step = buf->buf_rowstride; + d = buf->buf + 3 * (gl->position - buf->rect.x0); + + } else { + + if (gl->position < buf->rect.y0 || gl->position >= buf->rect.y1) { + return; + } + + p0 = buf->rect.x0; + p1 = buf->rect.x1; + step = 3; + d = buf->buf + (gl->position - buf->rect.y0) * buf->buf_rowstride; + } + + for (int p = p0; p < p1; p++) { + d[0] = NR_COMPOSEN11(r, a, d[0]); + d[1] = NR_COMPOSEN11(g, a, d[1]); + d[2] = NR_COMPOSEN11(b, a, d[2]); + d += step; + } +} + +static void sp_guideline_update(SPCanvasItem *item, NR::Matrix const &affine, unsigned int flags) +{ + SPGuideLine *gl = SP_GUIDELINE(item); + + if (((SPCanvasItemClass *) parent_class)->update) { + ((SPCanvasItemClass *) parent_class)->update(item, affine, flags); + } + + if (gl->vertical) { + gl->position = (int) (affine[4] + 0.5); + sp_canvas_update_bbox (item, gl->position, -1000000, gl->position + 1, 1000000); + } else { + gl->position = (int) (affine[5] - 0.5); + sp_canvas_update_bbox (item, -1000000, gl->position, 1000000, gl->position + 1); + } +} + +static double sp_guideline_point(SPCanvasItem *item, NR::Point p, SPCanvasItem **actual_item) +{ + SPGuideLine *gl = SP_GUIDELINE (item); + + if (!gl->sensitive) { + return NR_HUGE; + } + + *actual_item = item; + + if (gl->vertical) { + return MAX(fabs(gl->position - p[NR::X])-1, 0); + } else { + return MAX(fabs(gl->position - p[NR::Y])-1, 0); + } +} + +SPCanvasItem *sp_guideline_new(SPCanvasGroup *parent, double position, unsigned int vertical) +{ + SPCanvasItem *item = sp_canvas_item_new(parent, SP_TYPE_GUIDELINE, NULL); + + SPGuideLine *gl = SP_GUIDELINE(item); + + gl->vertical = vertical; + sp_guideline_set_position(gl, position); + + return item; +} + +void sp_guideline_set_position(SPGuideLine *gl, double position) +{ + sp_canvas_item_affine_absolute(SP_CANVAS_ITEM (gl), + NR::Matrix(NR::translate(position, position))); +} + +void sp_guideline_set_color(SPGuideLine *gl, unsigned int rgba) +{ + gl->rgba = rgba; + + sp_canvas_item_request_update(SP_CANVAS_ITEM(gl)); +} + +void sp_guideline_set_sensitive(SPGuideLine *gl, int sensitive) +{ + gl->sensitive = sensitive; +} + +/* + 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 : diff --git a/src/display/guideline.h b/src/display/guideline.h new file mode 100644 index 000000000..22f0af69a --- /dev/null +++ b/src/display/guideline.h @@ -0,0 +1,55 @@ +#ifndef __SP_GUIDELINE_H__ +#define __SP_GUIDELINE_H__ + +/* + * Infinite horizontal/vertical line; the visual representation of SPGuide. + * + * Author: + * Lauris Kaplinski + * + * Copyright (C) 2000-2002 Lauris Kaplinski + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "sp-canvas.h" + +#define SP_TYPE_GUIDELINE (sp_guideline_get_type()) +#define SP_GUIDELINE(o) (GTK_CHECK_CAST((o), SP_TYPE_GUIDELINE, SPGuideLine)) +#define SP_IS_GUIDELINE(o) (GTK_CHECK_TYPE((o), SP_TYPE_GUIDELINE)) + +struct SPGuideLine { + SPCanvasItem item; + + guint32 rgba; + + int position; + + unsigned int vertical : 1; + unsigned int sensitive : 1; +}; + +struct SPGuideLineClass { + SPCanvasItemClass parent_class; +}; + +GType sp_guideline_get_type(); + +SPCanvasItem *sp_guideline_new(SPCanvasGroup *parent, double position, unsigned int vertical); + +void sp_guideline_set_position(SPGuideLine *gl, double position); +void sp_guideline_set_color(SPGuideLine *gl, unsigned int rgba); +void sp_guideline_set_sensitive(SPGuideLine *gl, int sensitive); + +#endif + +/* + 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 : diff --git a/src/display/makefile.in b/src/display/makefile.in new file mode 100644 index 000000000..9d9426809 --- /dev/null +++ b/src/display/makefile.in @@ -0,0 +1,17 @@ +# Convenience stub makefile to call the real Makefile. + +@SET_MAKE@ + +# Explicit so that it's the default rule. +all: + cd .. && $(MAKE) display/all + +clean %.a %.o: + cd .. && $(MAKE) display/$@ + +.PHONY: all clean + +OBJEXT = @OBJEXT@ + +.SUFFIXES: +.SUFFIXES: .a .$(OBJEXT) diff --git a/src/display/nr-arena-forward.h b/src/display/nr-arena-forward.h new file mode 100644 index 000000000..67f62a78b --- /dev/null +++ b/src/display/nr-arena-forward.h @@ -0,0 +1,51 @@ +#ifndef __NR_ARENA_FORWARD_H__ +#define __NR_ARENA_FORWARD_H__ + +/* + * RGBA display list system for inkscape + * + * Author: + * Lauris Kaplinski + * + * Copyright (C) 2001-2002 Lauris Kaplinski + * Copyright (C) 2001 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +struct NRArena; +struct NRArenaClass; + +struct NRArenaItem; +struct NRArenaItemClass; + +struct NRArenaGroup; +struct NRArenaGroupClass; + +struct NRArenaShape; +struct NRArenaShapeClass; + +struct NRArenaShapeGroup; +struct NRArenaShapeGroupClass; + +struct NRArenaImage; +struct NRArenaImageClass; + +struct NRArenaGlyphs; +struct NRArenaGlyphsClass; + +struct NRArenaGlyphsGroup; +struct NRArenaGlyphsGroupClass; + +#endif + +/* + 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:textwidth=99 : diff --git a/src/display/nr-arena-glyphs.cpp b/src/display/nr-arena-glyphs.cpp new file mode 100644 index 000000000..861b8baf8 --- /dev/null +++ b/src/display/nr-arena-glyphs.cpp @@ -0,0 +1,679 @@ +#define __NR_ARENA_GLYPHS_C__ + +/* + * RGBA display list system for inkscape + * + * Author: + * Lauris Kaplinski + * + * Copyright (C) 2002 Lauris Kaplinski + * + * Released under GNU GPL + * + */ + + +#ifdef HAVE_CONFIG_H +# include +#endif +#include +#include +#include "../style.h" +#include "nr-arena.h" +#include "nr-arena-glyphs.h" + +#ifdef test_glyph_liv +#include "../display/canvas-bpath.h" +#include +#include +#include + +// defined in nr-arena-shape.cpp +void nr_pixblock_render_shape_mask_or (NRPixBlock &m,Shape* theS); +#endif + +static void nr_arena_glyphs_class_init (NRArenaGlyphsClass *klass); +static void nr_arena_glyphs_init (NRArenaGlyphs *glyphs); +static void nr_arena_glyphs_finalize (NRObject *object); + +static guint nr_arena_glyphs_update (NRArenaItem *item, NRRectL *area, NRGC *gc, guint state, guint reset); +static guint nr_arena_glyphs_clip (NRArenaItem *item, NRRectL *area, NRPixBlock *pb); +static NRArenaItem *nr_arena_glyphs_pick (NRArenaItem *item, NR::Point p, double delta, unsigned int sticky); + +static NRArenaItemClass *glyphs_parent_class; + +NRType +nr_arena_glyphs_get_type (void) +{ + static NRType type = 0; + if (!type) { + type = nr_object_register_type (NR_TYPE_ARENA_ITEM, + "NRArenaGlyphs", + sizeof (NRArenaGlyphsClass), + sizeof (NRArenaGlyphs), + (void (*) (NRObjectClass *)) nr_arena_glyphs_class_init, + (void (*) (NRObject *)) nr_arena_glyphs_init); + } + return type; +} + +static void +nr_arena_glyphs_class_init (NRArenaGlyphsClass *klass) +{ + NRObjectClass *object_class; + NRArenaItemClass *item_class; + + object_class = (NRObjectClass *) klass; + item_class = (NRArenaItemClass *) klass; + + glyphs_parent_class = (NRArenaItemClass *) ((NRObjectClass *) klass)->parent; + + object_class->finalize = nr_arena_glyphs_finalize; + object_class->cpp_ctor = NRObject::invoke_ctor; + + item_class->update = nr_arena_glyphs_update; + item_class->clip = nr_arena_glyphs_clip; + item_class->pick = nr_arena_glyphs_pick; +} + +static void +nr_arena_glyphs_init (NRArenaGlyphs *glyphs) +{ + glyphs->style = NULL; + nr_matrix_set_identity(&glyphs->g_transform); + glyphs->font = NULL; + glyphs->glyph = 0; + + glyphs->rfont = NULL; + glyphs->sfont = NULL; + glyphs->x = glyphs->y = 0.0; + +// nr_matrix_set_identity(&glyphs->cached_tr); +// glyphs->cached_shp=NULL; +// glyphs->cached_shp_dirty=false; +// glyphs->cached_style_dirty=false; + +// glyphs->stroke_shp=NULL; +} + +static void +nr_arena_glyphs_finalize (NRObject *object) +{ + NRArenaGlyphs *glyphs=static_cast(object); + +// if (glyphs->cached_shp) { +// delete glyphs->cached_shp; +// glyphs->cached_shp = NULL; +// } +// if (glyphs->stroke_shp) { +// delete glyphs->stroke_shp; +// glyphs->stroke_shp = NULL; +// } + + if (glyphs->rfont) { + glyphs->rfont->Unref(); + glyphs->rfont=NULL; + } + if (glyphs->sfont) { + glyphs->sfont->Unref(); + glyphs->sfont=NULL; + } + + if (glyphs->font) { + glyphs->font->Unref(); + glyphs->font=NULL; + } + + if (glyphs->style) { + sp_style_unref (glyphs->style); + glyphs->style = NULL; + } + + ((NRObjectClass *) glyphs_parent_class)->finalize (object); +} + +static guint +nr_arena_glyphs_update (NRArenaItem *item, NRRectL *area, NRGC *gc, guint state, guint reset) +{ + NRArenaGlyphs *glyphs; + raster_font *rfont; + + glyphs = NR_ARENA_GLYPHS (item); + + if (!glyphs->font || !glyphs->style) return NR_ARENA_ITEM_STATE_ALL; + if ((glyphs->style->fill.type == SP_PAINT_TYPE_NONE) && (glyphs->style->stroke.type == SP_PAINT_TYPE_NONE)) return NR_ARENA_ITEM_STATE_ALL; + + NRRect bbox; + bbox.x0 = bbox.y0 = NR_HUGE; + bbox.x1 = bbox.y1 = -NR_HUGE; + + if (glyphs->style->fill.type != SP_PAINT_TYPE_NONE) { + NRMatrix t; + nr_matrix_multiply (&t, &glyphs->g_transform, &gc->transform); + glyphs->x = t.c[4]; + glyphs->y = t.c[5]; + t.c[4]=0; + t.c[5]=0; + rfont = glyphs->font->RasterFont(t, 0); + if (glyphs->rfont) glyphs->rfont->Unref(); + glyphs->rfont = rfont; + + if (glyphs->style->stroke.type == SP_PAINT_TYPE_NONE) { // Optimization: do fill bbox only if there's no stroke + NRRect narea; + if ( glyphs->rfont ) glyphs->rfont->BBox(glyphs->glyph, &narea); + bbox.x0 = narea.x0 + glyphs->x; + bbox.y0 = narea.y0 + glyphs->y; + bbox.x1 = narea.x1 + glyphs->x; + bbox.y1 = narea.y1 + glyphs->y; + } + } + + if (glyphs->style->stroke.type != SP_PAINT_TYPE_NONE) { + /* Build state data */ + NRMatrix t; + nr_matrix_multiply (&t, &glyphs->g_transform, &gc->transform); + glyphs->x = t.c[4]; + glyphs->y = t.c[5]; + t.c[4]=0; + t.c[5]=0; + + const float scale = NR_MATRIX_DF_EXPANSION (&gc->transform); + if ( fabs(glyphs->style->stroke_width.computed * scale) > 0.01 ) { // sinon c'est 0=oon veut pas de bord + font_style nstyl; + nstyl.transform = t; + nstyl.stroke_width=MAX (0.125, glyphs->style->stroke_width.computed * scale); + if ( glyphs->style->stroke_linecap.computed == SP_STROKE_LINECAP_BUTT ) nstyl.stroke_cap=butt_straight; + if ( glyphs->style->stroke_linecap.computed == SP_STROKE_LINECAP_ROUND ) nstyl.stroke_cap=butt_round; + if ( glyphs->style->stroke_linecap.computed == SP_STROKE_LINECAP_SQUARE ) nstyl.stroke_cap=butt_square; + if ( glyphs->style->stroke_linejoin.computed == SP_STROKE_LINEJOIN_MITER ) nstyl.stroke_join=join_pointy; + if ( glyphs->style->stroke_linejoin.computed == SP_STROKE_LINEJOIN_ROUND ) nstyl.stroke_join=join_round; + if ( glyphs->style->stroke_linejoin.computed == SP_STROKE_LINEJOIN_BEVEL ) nstyl.stroke_join=join_straight; + nstyl.stroke_miter_limit = glyphs->style->stroke_miterlimit.value; + nstyl.nbDash=0; + nstyl.dashes=NULL; + if ( glyphs->style->stroke_dash.n_dash > 0 ) { + nstyl.nbDash=glyphs->style->stroke_dash.n_dash; + nstyl.dashes=(double*)malloc(nstyl.nbDash*sizeof(double)); + for (int i = 0; i < nstyl.nbDash; i++) nstyl.dashes[i]= glyphs->style->stroke_dash.dash[i] * scale; + } + rfont = glyphs->font->RasterFont( nstyl); + if ( nstyl.dashes ) free(nstyl.dashes); + if (glyphs->sfont) glyphs->sfont->Unref(); + glyphs->sfont = rfont; + + NRRect narea; + if ( glyphs->sfont ) glyphs->sfont->BBox(glyphs->glyph, &narea); + narea.x0-=nstyl.stroke_width; + narea.y0-=nstyl.stroke_width; + narea.x1+=nstyl.stroke_width; + narea.y1+=nstyl.stroke_width; + bbox.x0 = narea.x0 + glyphs->x; + bbox.y0 = narea.y0 + glyphs->y; + bbox.x1 = narea.x1 + glyphs->x; + bbox.y1 = narea.y1 + glyphs->y; + } + } + if (nr_rect_d_test_empty(&bbox)) return NR_ARENA_ITEM_STATE_ALL; + + item->bbox.x0 = (gint32)(bbox.x0 - 1.0); + item->bbox.y0 = (gint32)(bbox.y0 - 1.0); + item->bbox.x1 = (gint32)(bbox.x1 + 1.0); + item->bbox.y1 = (gint32)(bbox.y1 + 1.0); + nr_arena_request_render_rect (item->arena, &item->bbox); + + return NR_ARENA_ITEM_STATE_ALL; +} + +static guint +nr_arena_glyphs_clip (NRArenaItem *item, NRRectL *area, NRPixBlock *pb) +{ + NRArenaGlyphs *glyphs; + + glyphs = NR_ARENA_GLYPHS (item); + + if (!glyphs->font ) return item->state; + + /* TODO : render to greyscale pixblock provided for clipping */ + + return item->state; +} + +static NRArenaItem * +nr_arena_glyphs_pick (NRArenaItem *item, NR::Point p, gdouble delta, unsigned int sticky) +{ + NRArenaGlyphs *glyphs; + + glyphs = NR_ARENA_GLYPHS (item); + + if (!glyphs->font ) return NULL; + if (!glyphs->style) return NULL; + + const double x = p[NR::X]; + const double y = p[NR::Y]; + /* With text we take a simple approach: pick if the point is in a characher bbox */ + if ((x >= item->bbox.x0) && (y >= item->bbox.y0) && (x <= item->bbox.x1) && (y <= item->bbox.y1)) return item; + +/* NR::Point const thePt = p; + if (glyphs->stroke_shp && (glyphs->style->stroke.type != SP_PAINT_TYPE_NONE)) { + if (glyphs->stroke_shp->PtWinding(thePt) > 0 ) return item; + } + if (delta > 1e-3) { + if (glyphs->stroke_shp && (glyphs->style->stroke.type != SP_PAINT_TYPE_NONE)) { + if ( glyphs->stroke_shp->DistanceLE(thePt, delta)) return item; + } + }*/ + + return NULL; +} + +void +nr_arena_glyphs_set_path (NRArenaGlyphs *glyphs, SPCurve *curve, unsigned int lieutenant, font_instance *font, gint glyph, const NRMatrix *transform) +{ + nr_return_if_fail (glyphs != NULL); + nr_return_if_fail (NR_IS_ARENA_GLYPHS (glyphs)); + + nr_arena_item_request_render (NR_ARENA_ITEM (glyphs)); + + // glyphs->cached_shp_dirty=true; + + if (transform) { + glyphs->g_transform = *transform; + } else { + nr_matrix_set_identity (&glyphs->g_transform); + } + + //printf("glyph_setpath "); + if ( font ) font->Ref(); + if ( glyphs->font ) glyphs->font->Unref(); + glyphs->font=font; + glyphs->glyph = glyph; + + nr_arena_item_request_update (NR_ARENA_ITEM (glyphs), NR_ARENA_ITEM_STATE_ALL, FALSE); +} + +void +nr_arena_glyphs_set_style (NRArenaGlyphs *glyphs, SPStyle *style) +{ + nr_return_if_fail (glyphs != NULL); + nr_return_if_fail (NR_IS_ARENA_GLYPHS (glyphs)); + +// glyphs->cached_style_dirty=true; + + if (style) sp_style_ref (style); + if (glyphs->style) sp_style_unref (glyphs->style); + glyphs->style = style; + + nr_arena_item_request_update (NR_ARENA_ITEM (glyphs), NR_ARENA_ITEM_STATE_ALL, FALSE); +} + +static guint +nr_arena_glyphs_fill_mask (NRArenaGlyphs *glyphs, NRRectL *area, NRPixBlock *m) +{ + NRArenaItem *item; + + /* fixme: area == m->area, so merge these */ + + item = NR_ARENA_ITEM (glyphs); + + if (glyphs->rfont && nr_rect_l_test_intersect (area, &item->bbox)) { + raster_glyph* g=glyphs->rfont->GetGlyph(glyphs->glyph); + if ( g ) g->Blit(NR::Point(glyphs->x, glyphs->y),*m); + } + + return item->state; +} + +static guint +nr_arena_glyphs_stroke_mask (NRArenaGlyphs *glyphs, NRRectL *area, NRPixBlock *m) +{ + NRArenaItem *item; + + item = NR_ARENA_ITEM (glyphs); + if (glyphs->sfont && nr_rect_l_test_intersect (area, &item->bbox)) { + raster_glyph* g=glyphs->sfont->GetGlyph(glyphs->glyph); + if ( g ) g->Blit(NR::Point(glyphs->x, glyphs->y),*m); + } +/* if (glyphs->stroke_shp && nr_rect_l_test_intersect (area, &item->bbox)) { + NRPixBlock gb; + gint x, y; + nr_pixblock_setup_fast (&gb, NR_PIXBLOCK_MODE_A8, area->x0, area->y0, area->x1, area->y1, TRUE); + // art_gray_svp_aa is just fillung apparently + // dunno why it's used here instead of its libnr counterpart + nr_pixblock_render_shape_mask_or (gb,glyphs->stroke_shp); + for (y = area->y0; y < area->y1; y++) { + guchar *d, *s; + d = NR_PIXBLOCK_PX (m) + (y - area->y0) * m->rs; + s = NR_PIXBLOCK_PX (&gb) + (y - area->y0) * gb.rs; + for (x = area->x0; x < area->x1; x++) { + *d = (*d) + ((255 - *d) * (*s) / 255); + d += 1; + s += 1; + } + } + nr_pixblock_release (&gb); + m->empty = FALSE; + }*/ + + return item->state; +} + +static void nr_arena_glyphs_group_class_init (NRArenaGlyphsGroupClass *klass); +static void nr_arena_glyphs_group_init (NRArenaGlyphsGroup *group); +static void nr_arena_glyphs_group_finalize (NRObject *object); + +static guint nr_arena_glyphs_group_update (NRArenaItem *item, NRRectL *area, NRGC *gc, guint state, guint reset); +static unsigned int nr_arena_glyphs_group_render (NRArenaItem *item, NRRectL *area, NRPixBlock *pb, unsigned int flags); +static unsigned int nr_arena_glyphs_group_clip (NRArenaItem *item, NRRectL *area, NRPixBlock *pb); +static NRArenaItem *nr_arena_glyphs_group_pick (NRArenaItem *item, NR::Point p, gdouble delta, unsigned int sticky); + +static NRArenaGroupClass *group_parent_class; + +NRType +nr_arena_glyphs_group_get_type (void) +{ + static NRType type = 0; + if (!type) { + type = nr_object_register_type (NR_TYPE_ARENA_GROUP, + "NRArenaGlyphsGroup", + sizeof (NRArenaGlyphsGroupClass), + sizeof (NRArenaGlyphsGroup), + (void (*) (NRObjectClass *)) nr_arena_glyphs_group_class_init, + (void (*) (NRObject *)) nr_arena_glyphs_group_init); + } + return type; +} + +static void +nr_arena_glyphs_group_class_init (NRArenaGlyphsGroupClass *klass) +{ + NRObjectClass *object_class; + NRArenaItemClass *item_class; + + object_class = (NRObjectClass *) klass; + item_class = (NRArenaItemClass *) klass; + + group_parent_class = (NRArenaGroupClass *) ((NRObjectClass *) klass)->parent; + + object_class->finalize = nr_arena_glyphs_group_finalize; + object_class->cpp_ctor = NRObject::invoke_ctor; + + item_class->update = nr_arena_glyphs_group_update; + item_class->render = nr_arena_glyphs_group_render; + item_class->clip = nr_arena_glyphs_group_clip; + item_class->pick = nr_arena_glyphs_group_pick; +} + +static void +nr_arena_glyphs_group_init (NRArenaGlyphsGroup *group) +{ + group->style = NULL; + group->paintbox.x0 = group->paintbox.y0 = 0.0F; + group->paintbox.x1 = group->paintbox.y1 = 1.0F; + + group->fill_painter = NULL; + group->stroke_painter = NULL; +} + +static void +nr_arena_glyphs_group_finalize (NRObject *object) +{ + NRArenaGlyphsGroup *group=static_cast(object); + + if (group->fill_painter) { + sp_painter_free (group->fill_painter); + group->fill_painter = NULL; + } + + if (group->stroke_painter) { + sp_painter_free (group->stroke_painter); + group->stroke_painter = NULL; + } + + if (group->style) { + sp_style_unref (group->style); + group->style = NULL; + } + + ((NRObjectClass *) group_parent_class)->finalize (object); +} + +static guint +nr_arena_glyphs_group_update (NRArenaItem *item, NRRectL *area, NRGC *gc, guint state, guint reset) +{ + NRArenaGlyphsGroup *group = NR_ARENA_GLYPHS_GROUP (item); + + if (group->fill_painter) { + sp_painter_free (group->fill_painter); + group->fill_painter = NULL; + } + + if (group->stroke_painter) { + sp_painter_free (group->stroke_painter); + group->stroke_painter = NULL; + } + + item->render_opacity = TRUE; + if (group->style->fill.type == SP_PAINT_TYPE_PAINTSERVER) { + group->fill_painter = sp_paint_server_painter_new (SP_STYLE_FILL_SERVER (group->style), + NR::Matrix (&gc->transform), NR::Matrix (&gc->parent->transform), + &group->paintbox); + item->render_opacity = FALSE; + } + + if (group->style->stroke.type == SP_PAINT_TYPE_PAINTSERVER) { + group->stroke_painter = sp_paint_server_painter_new (SP_STYLE_STROKE_SERVER (group->style), + NR::Matrix (&gc->transform), NR::Matrix (&gc->parent->transform), + &group->paintbox); + item->render_opacity = FALSE; + } + + if ( item->render_opacity == TRUE && group->style->stroke.type != SP_PAINT_TYPE_NONE && group->style->fill.type != SP_PAINT_TYPE_NONE ) { + item->render_opacity=FALSE; + } + + if (((NRArenaItemClass *) group_parent_class)->update) + return ((NRArenaItemClass *) group_parent_class)->update (item, area, gc, state, reset); + + return NR_ARENA_ITEM_STATE_ALL; +} + +/* This sucks - as soon, as we have inheritable renderprops, do something with that opacity */ + +static unsigned int +nr_arena_glyphs_group_render (NRArenaItem *item, NRRectL *area, NRPixBlock *pb, unsigned int flags) +{ + NRArenaItem *child; + + NRArenaGroup *group = NR_ARENA_GROUP (item); + NRArenaGlyphsGroup *ggroup = NR_ARENA_GLYPHS_GROUP (item); + SPStyle const *style = ggroup->style; + + guint ret = item->state; + + /* Fill */ + if (style->fill.type != SP_PAINT_TYPE_NONE || item->arena->rendermode == RENDERMODE_OUTLINE) { + NRPixBlock m; + nr_pixblock_setup_fast (&m, NR_PIXBLOCK_MODE_A8, area->x0, area->y0, area->x1, area->y1, TRUE); + + /* Render children fill mask */ + for (child = group->children; child != NULL; child = child->next) { + ret = nr_arena_glyphs_fill_mask (NR_ARENA_GLYPHS (child), area, &m); + if (!(ret & NR_ARENA_ITEM_STATE_RENDER)) { + nr_pixblock_release (&m); + return ret; + } + } + + /* Composite into buffer */ + if (style->fill.type == SP_PAINT_TYPE_COLOR || item->arena->rendermode == RENDERMODE_OUTLINE) { + guint32 rgba; + if (item->arena->rendermode == RENDERMODE_OUTLINE) { + // In outline mode, render fill only, using outlinecolor + rgba = item->arena->outlinecolor; + } else if ( item->render_opacity ) { + rgba = sp_color_get_rgba32_falpha (&style->fill.value.color, + SP_SCALE24_TO_FLOAT (style->fill_opacity.value) * + SP_SCALE24_TO_FLOAT (style->opacity.value)); + } else { + rgba = sp_color_get_rgba32_falpha (&style->fill.value.color, SP_SCALE24_TO_FLOAT (style->fill_opacity.value)); + } + nr_blit_pixblock_mask_rgba32 (pb, &m, rgba); + pb->empty = FALSE; + } else if (style->fill.type == SP_PAINT_TYPE_PAINTSERVER) { + if (ggroup->fill_painter) { + nr_arena_render_paintserver_fill (pb, area, ggroup->fill_painter, SP_SCALE24_TO_FLOAT (style->fill_opacity.value), &m); + } + } + + nr_pixblock_release (&m); + } + + /* Stroke */ + if (style->stroke.type != SP_PAINT_TYPE_NONE && !(item->arena->rendermode == RENDERMODE_OUTLINE)) { + NRPixBlock m; + guint32 rgba; + nr_pixblock_setup_fast (&m, NR_PIXBLOCK_MODE_A8, area->x0, area->y0, area->x1, area->y1, TRUE); + /* Render children stroke mask */ + for (child = group->children; child != NULL; child = child->next) { + ret = nr_arena_glyphs_stroke_mask (NR_ARENA_GLYPHS (child), area, &m); + if (!(ret & NR_ARENA_ITEM_STATE_RENDER)) { + nr_pixblock_release (&m); + return ret; + } + } + /* Composite into buffer */ + switch (style->stroke.type) { + case SP_PAINT_TYPE_COLOR: + if ( item->render_opacity ) { + rgba = sp_color_get_rgba32_falpha (&style->stroke.value.color, + SP_SCALE24_TO_FLOAT (style->stroke_opacity.value) * + SP_SCALE24_TO_FLOAT (style->opacity.value)); + } else { + rgba = sp_color_get_rgba32_falpha (&style->stroke.value.color, + SP_SCALE24_TO_FLOAT (style->stroke_opacity.value)); + } + nr_blit_pixblock_mask_rgba32 (pb, &m, rgba); + pb->empty = FALSE; + break; + case SP_PAINT_TYPE_PAINTSERVER: + if (ggroup->stroke_painter) { + nr_arena_render_paintserver_fill (pb, area, ggroup->stroke_painter, SP_SCALE24_TO_FLOAT (style->stroke_opacity.value), &m); + } + break; + default: + break; + } + nr_pixblock_release (&m); + } + + return ret; +} + +static unsigned int +nr_arena_glyphs_group_clip (NRArenaItem *item, NRRectL *area, NRPixBlock *pb) +{ + NRArenaGroup *group = NR_ARENA_GROUP (item); + + guint ret = item->state; + + /* Render children fill mask */ + for (NRArenaItem *child = group->children; child != NULL; child = child->next) { + ret = nr_arena_glyphs_fill_mask (NR_ARENA_GLYPHS (child), area, pb); + if (!(ret & NR_ARENA_ITEM_STATE_RENDER)) return ret; + } + + return ret; +} + +static NRArenaItem * +nr_arena_glyphs_group_pick (NRArenaItem *item, NR::Point p, gdouble delta, unsigned int sticky) +{ + NRArenaItem *picked = NULL; + + if (((NRArenaItemClass *) group_parent_class)->pick) + picked = ((NRArenaItemClass *) group_parent_class)->pick (item, p, delta, sticky); + + if (picked) picked = item; + + return picked; +} + +void +nr_arena_glyphs_group_clear (NRArenaGlyphsGroup *sg) +{ + NRArenaGroup *group = NR_ARENA_GROUP (sg); + + nr_arena_item_request_render (NR_ARENA_ITEM (group)); + + while (group->children) { + nr_arena_item_remove_child (NR_ARENA_ITEM (group), group->children); + } +} + +void +nr_arena_glyphs_group_add_component (NRArenaGlyphsGroup *sg, font_instance *font, int glyph, const NRMatrix *transform) +{ + NRArenaGroup *group; + NRBPath bpath; + + group = NR_ARENA_GROUP (sg); + + if ( font ) bpath.path=(NArtBpath*)font->ArtBPath(glyph); else bpath.path=NULL; + if ( bpath.path ) { + + nr_arena_item_request_render (NR_ARENA_ITEM (group)); + + NRArenaItem *new_arena; + new_arena = NRArenaGlyphs::create(group->arena); + nr_arena_item_append_child (NR_ARENA_ITEM (group), new_arena); + nr_arena_item_unref (new_arena); + nr_arena_glyphs_set_path (NR_ARENA_GLYPHS (new_arena), NULL, FALSE, font, glyph, transform); + nr_arena_glyphs_set_style (NR_ARENA_GLYPHS (new_arena), sg->style); + } + +} + +void +nr_arena_glyphs_group_set_style (NRArenaGlyphsGroup *sg, SPStyle *style) +{ + NRArenaGroup *group; + NRArenaItem *child; + + nr_return_if_fail (sg != NULL); + nr_return_if_fail (NR_IS_ARENA_GLYPHS_GROUP (sg)); + + group = NR_ARENA_GROUP (sg); + + if (style) sp_style_ref (style); + if (sg->style) sp_style_unref (sg->style); + sg->style = style; + + for (child = group->children; child != NULL; child = child->next) { + nr_return_if_fail (NR_IS_ARENA_GLYPHS (child)); + nr_arena_glyphs_set_style (NR_ARENA_GLYPHS (child), sg->style); + } + + nr_arena_item_request_update (NR_ARENA_ITEM (sg), NR_ARENA_ITEM_STATE_ALL, FALSE); +} + +void +nr_arena_glyphs_group_set_paintbox (NRArenaGlyphsGroup *gg, const NRRect *pbox) +{ + nr_return_if_fail (gg != NULL); + nr_return_if_fail (NR_IS_ARENA_GLYPHS_GROUP (gg)); + nr_return_if_fail (pbox != NULL); + + if ((pbox->x0 < pbox->x1) && (pbox->y0 < pbox->y1)) { + gg->paintbox.x0 = pbox->x0; + gg->paintbox.y0 = pbox->y0; + gg->paintbox.x1 = pbox->x1; + gg->paintbox.y1 = pbox->y1; + } else { + /* fixme: We kill warning, although not sure what to do here (Lauris) */ + gg->paintbox.x0 = gg->paintbox.y0 = 0.0F; + gg->paintbox.x1 = gg->paintbox.y1 = 256.0F; + } + + nr_arena_item_request_update (NR_ARENA_ITEM (gg), NR_ARENA_ITEM_STATE_ALL, FALSE); +} + diff --git a/src/display/nr-arena-glyphs.h b/src/display/nr-arena-glyphs.h new file mode 100644 index 000000000..23b74a378 --- /dev/null +++ b/src/display/nr-arena-glyphs.h @@ -0,0 +1,109 @@ +#ifndef __NR_ARENA_GLYPHS_H__ +#define __NR_ARENA_GLYPHS_H__ + +/* + * RGBA display list system for inkscape + * + * Author: + * Lauris Kaplinski + * + * Copyright (C) 2002 Lauris Kaplinski + * + * Released under GNU GPL + * + */ + +#define NR_TYPE_ARENA_GLYPHS (nr_arena_glyphs_get_type ()) +#define NR_ARENA_GLYPHS(obj) (NR_CHECK_INSTANCE_CAST ((obj), NR_TYPE_ARENA_GLYPHS, NRArenaGlyphs)) +#define NR_IS_ARENA_GLYPHS(obj) (NR_CHECK_INSTANCE_TYPE ((obj), NR_TYPE_ARENA_GLYPHS)) + +#include + +#include +#include +#include +#include + +#define test_glyph_liv + +class Shape; + +NRType nr_arena_glyphs_get_type (void); + +struct NRArenaGlyphs : public NRArenaItem { + /* Glyphs data */ + SPStyle *style; + NRMatrix g_transform; + font_instance *font; + gint glyph; + + raster_font *rfont; + raster_font *sfont; + float x, y; + +// NRMatrix cached_tr; +// Shape *cached_shp; +// bool cached_shp_dirty; +// bool cached_style_dirty; + +// Shape *stroke_shp; + + static NRArenaGlyphs *create(NRArena *arena) { + NRArenaGlyphs *obj=reinterpret_cast(nr_object_new(NR_TYPE_ARENA_GLYPHS)); + obj->init(arena); + return obj; + } +}; + +struct NRArenaGlyphsClass { + NRArenaItemClass parent_class; +}; + +void nr_arena_glyphs_set_path (NRArenaGlyphs *glyphs, + SPCurve *curve, unsigned int lieutenant, + font_instance *font, int glyph, + const NRMatrix *transform); +void nr_arena_glyphs_set_style (NRArenaGlyphs *glyphs, SPStyle *style); + +/* Integrated group of component glyphss */ + +typedef struct NRArenaGlyphsGroup NRArenaGlyphsGroup; +typedef struct NRArenaGlyphsGroupClass NRArenaGlyphsGroupClass; + +#include "nr-arena-group.h" + +#define NR_TYPE_ARENA_GLYPHS_GROUP (nr_arena_glyphs_group_get_type ()) +#define NR_ARENA_GLYPHS_GROUP(obj) (NR_CHECK_INSTANCE_CAST ((obj), NR_TYPE_ARENA_GLYPHS_GROUP, NRArenaGlyphsGroup)) +#define NR_IS_ARENA_GLYPHS_GROUP(obj) (NR_CHECK_INSTANCE_TYPE ((obj), NR_TYPE_ARENA_GLYPHS_GROUP)) + +NRType nr_arena_glyphs_group_get_type (void); + +struct NRArenaGlyphsGroup : public NRArenaGroup { + SPStyle *style; + NRRect paintbox; + /* State data */ + SPPainter *fill_painter; + SPPainter *stroke_painter; + + static NRArenaGlyphsGroup *create(NRArena *arena) { + NRArenaGlyphsGroup *obj=reinterpret_cast(nr_object_new(NR_TYPE_ARENA_GLYPHS_GROUP)); + obj->init(arena); + return obj; + } +}; + +struct NRArenaGlyphsGroupClass { + NRArenaGroupClass parent_class; +}; + +/* Utility functions */ + +void nr_arena_glyphs_group_clear (NRArenaGlyphsGroup *group); + +void nr_arena_glyphs_group_add_component (NRArenaGlyphsGroup *group, font_instance *font, int glyph, const NRMatrix *transform); + +void nr_arena_glyphs_group_set_style (NRArenaGlyphsGroup *group, SPStyle *style); + +void nr_arena_glyphs_group_set_paintbox (NRArenaGlyphsGroup *group, const NRRect *pbox); + +#endif diff --git a/src/display/nr-arena-group.cpp b/src/display/nr-arena-group.cpp new file mode 100644 index 000000000..64274202f --- /dev/null +++ b/src/display/nr-arena-group.cpp @@ -0,0 +1,256 @@ +#define __NR_ARENA_GROUP_C__ + +/* + * RGBA display list system for inkscape + * + * Author: + * Lauris Kaplinski + * + * Copyright (C) 2001-2002 Lauris Kaplinski + * Copyright (C) 2001 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "nr-arena-group.h" + +static void nr_arena_group_class_init (NRArenaGroupClass *klass); +static void nr_arena_group_init (NRArenaGroup *group); + +static NRArenaItem *nr_arena_group_children (NRArenaItem *item); +static NRArenaItem *nr_arena_group_last_child (NRArenaItem *item); +static void nr_arena_group_add_child (NRArenaItem *item, NRArenaItem *child, NRArenaItem *ref); +static void nr_arena_group_remove_child (NRArenaItem *item, NRArenaItem *child); +static void nr_arena_group_set_child_position (NRArenaItem *item, NRArenaItem *child, NRArenaItem *ref); + +static unsigned int nr_arena_group_update (NRArenaItem *item, NRRectL *area, NRGC *gc, unsigned int state, unsigned int reset); +static unsigned int nr_arena_group_render (NRArenaItem *item, NRRectL *area, NRPixBlock *pb, unsigned int flags); +static unsigned int nr_arena_group_clip (NRArenaItem *item, NRRectL *area, NRPixBlock *pb); +static NRArenaItem *nr_arena_group_pick (NRArenaItem *item, NR::Point p, double delta, unsigned int sticky); + +static NRArenaItemClass *parent_class; + +NRType +nr_arena_group_get_type (void) +{ + static NRType type = 0; + if (!type) { + type = nr_object_register_type (NR_TYPE_ARENA_ITEM, + "NRArenaGroup", + sizeof (NRArenaGroupClass), + sizeof (NRArenaGroup), + (void (*) (NRObjectClass *)) nr_arena_group_class_init, + (void (*) (NRObject *)) nr_arena_group_init); + } + return type; +} + +static void +nr_arena_group_class_init (NRArenaGroupClass *klass) +{ + NRObjectClass *object_class; + NRArenaItemClass *item_class; + + object_class = (NRObjectClass *) klass; + item_class = (NRArenaItemClass *) klass; + + parent_class = (NRArenaItemClass *) ((NRObjectClass *) klass)->parent; + + object_class->cpp_ctor = NRObject::invoke_ctor; + + item_class->children = nr_arena_group_children; + item_class->last_child = nr_arena_group_last_child; + item_class->add_child = nr_arena_group_add_child; + item_class->set_child_position = nr_arena_group_set_child_position; + item_class->remove_child = nr_arena_group_remove_child; + item_class->update = nr_arena_group_update; + item_class->render = nr_arena_group_render; + item_class->clip = nr_arena_group_clip; + item_class->pick = nr_arena_group_pick; +} + +static void +nr_arena_group_init (NRArenaGroup *group) +{ + group->transparent = FALSE; + group->children = NULL; + group->last = NULL; + nr_matrix_set_identity (&group->child_transform); + +#ifdef arena_item_tile_cache + group->skipCaching=true; +#endif + +} + +static NRArenaItem * +nr_arena_group_children (NRArenaItem *item) +{ + NRArenaGroup *group = NR_ARENA_GROUP (item); + + return group->children; +} + +static NRArenaItem * +nr_arena_group_last_child (NRArenaItem *item) +{ + NRArenaGroup *group = NR_ARENA_GROUP (item); + + return group->last; +} + +static void +nr_arena_group_add_child (NRArenaItem *item, NRArenaItem *child, NRArenaItem *ref) +{ + NRArenaGroup *group = NR_ARENA_GROUP (item); + + if (!ref) { + group->children = nr_arena_item_attach_ref (item, child, NULL, group->children); + } else { + ref->next = nr_arena_item_attach_ref (item, child, ref, ref->next); + } + + if (ref == group->last) group->last = child; + + nr_arena_item_request_update (item, NR_ARENA_ITEM_STATE_ALL, FALSE); +} + +static void +nr_arena_group_remove_child (NRArenaItem *item, NRArenaItem *child) +{ + NRArenaGroup *group = NR_ARENA_GROUP (item); + + if (child == group->last) group->last = child->prev; + + if (child->prev) { + nr_arena_item_detach_unref (item, child); + } else { + group->children = nr_arena_item_detach_unref (item, child); + } + + nr_arena_item_request_update (item, NR_ARENA_ITEM_STATE_ALL, FALSE); +} + +static void +nr_arena_group_set_child_position (NRArenaItem *item, NRArenaItem *child, NRArenaItem *ref) +{ + NRArenaGroup *group = NR_ARENA_GROUP (item); + + if (child == group->last) group->last = child->prev; + + if (child->prev) { + nr_arena_item_detach_unref (item, child); + } else { + group->children = nr_arena_item_detach_unref (item, child); + } + + if (!ref) { + group->children = nr_arena_item_attach_ref (item, child, NULL, group->children); + } else { + ref->next = nr_arena_item_attach_ref (item, child, ref, ref->next); + } + + if (ref == group->last) group->last = child; + + nr_arena_item_request_render (child); +} + +static unsigned int +nr_arena_group_update (NRArenaItem *item, NRRectL *area, NRGC *gc, unsigned int state, unsigned int reset) +{ + unsigned int newstate; + + NRArenaGroup *group = NR_ARENA_GROUP (item); + + unsigned int beststate = NR_ARENA_ITEM_STATE_ALL; + + for (NRArenaItem *child = group->children; child != NULL; child = child->next) { + NRGC cgc(gc); + nr_matrix_multiply (&cgc.transform, &group->child_transform, &gc->transform); + newstate = nr_arena_item_invoke_update (child, area, &cgc, state, reset); + beststate = beststate & newstate; + } + + if (beststate & NR_ARENA_ITEM_STATE_BBOX) { + nr_rect_l_set_empty (&item->bbox); + for (NRArenaItem *child = group->children; child != NULL; child = child->next) { + nr_rect_l_union (&item->bbox, &item->bbox, &child->bbox); + } + } + + return beststate; +} + +static unsigned int +nr_arena_group_render (NRArenaItem *item, NRRectL *area, NRPixBlock *pb, unsigned int flags) +{ + NRArenaGroup *group = NR_ARENA_GROUP (item); + + unsigned int ret = item->state; + + /* Just compose children into parent buffer */ + for (NRArenaItem *child = group->children; child != NULL; child = child->next) { + ret = nr_arena_item_invoke_render (child, area, pb, flags); + if (ret & NR_ARENA_ITEM_STATE_INVALID) break; + } + + return ret; +} + +static unsigned int +nr_arena_group_clip (NRArenaItem *item, NRRectL *area, NRPixBlock *pb) +{ + NRArenaGroup *group = NR_ARENA_GROUP (item); + + unsigned int ret = item->state; + + /* Just compose children into parent buffer */ + for (NRArenaItem *child = group->children; child != NULL; child = child->next) { + ret = nr_arena_item_invoke_clip (child, area, pb); + if (ret & NR_ARENA_ITEM_STATE_INVALID) break; + } + + return ret; +} + +static NRArenaItem * +nr_arena_group_pick (NRArenaItem *item, NR::Point p, double delta, unsigned int sticky) +{ + NRArenaGroup *group = NR_ARENA_GROUP (item); + + for (NRArenaItem *child = group->last; child != NULL; child = child->prev) { + NRArenaItem *picked = nr_arena_item_invoke_pick (child, p, delta, sticky); + if (picked) + return (group->transparent) ? picked : item; + } + + return NULL; +} + +void +nr_arena_group_set_transparent (NRArenaGroup *group, unsigned int transparent) +{ + nr_return_if_fail (group != NULL); + nr_return_if_fail (NR_IS_ARENA_GROUP (group)); + + group->transparent = transparent; +} + +void nr_arena_group_set_child_transform(NRArenaGroup *group, NR::Matrix const &t) +{ + NRMatrix nt(t); + nr_arena_group_set_child_transform(group, &nt); +} + +void nr_arena_group_set_child_transform(NRArenaGroup *group, NRMatrix const *t) +{ + if (!t) t = &NR_MATRIX_IDENTITY; + + if (!NR_MATRIX_DF_TEST_CLOSE (t, &group->child_transform, NR_EPSILON)) { + nr_arena_item_request_render (NR_ARENA_ITEM (group)); + group->child_transform = *t; + nr_arena_item_request_update (NR_ARENA_ITEM (group), NR_ARENA_ITEM_STATE_ALL, TRUE); + } +} + + diff --git a/src/display/nr-arena-group.h b/src/display/nr-arena-group.h new file mode 100644 index 000000000..b33495362 --- /dev/null +++ b/src/display/nr-arena-group.h @@ -0,0 +1,46 @@ +#ifndef __NR_ARENA_GROUP_H__ +#define __NR_ARENA_GROUP_H__ + +/* + * RGBA display list system for inkscape + * + * Author: + * Lauris Kaplinski + * + * Copyright (C) 2001 Lauris Kaplinski and Ximian, Inc. + * + * Released under GNU GPL + * + */ + +#define NR_TYPE_ARENA_GROUP (nr_arena_group_get_type ()) +#define NR_ARENA_GROUP(o) (NR_CHECK_INSTANCE_CAST ((o), NR_TYPE_ARENA_GROUP, NRArenaGroup)) +#define NR_IS_ARENA_GROUP(o) (NR_CHECK_INSTANCE_TYPE ((o), NR_TYPE_ARENA_GROUP)) + +#include "nr-arena-item.h" + +NRType nr_arena_group_get_type (void); + +struct NRArenaGroup : public NRArenaItem{ + unsigned int transparent : 1; + NRArenaItem *children; + NRArenaItem *last; + NRMatrix child_transform; + + static NRArenaGroup *create(NRArena *arena) { + NRArenaGroup *obj=reinterpret_cast(nr_object_new(NR_TYPE_ARENA_GROUP)); + obj->init(arena); + return obj; + } +}; + +struct NRArenaGroupClass { + NRArenaItemClass parent_class; +}; + +void nr_arena_group_set_transparent (NRArenaGroup *group, unsigned int transparent); + +void nr_arena_group_set_child_transform(NRArenaGroup *group, NR::Matrix const &t); +void nr_arena_group_set_child_transform(NRArenaGroup *group, NRMatrix const *t); + +#endif diff --git a/src/display/nr-arena-image.cpp b/src/display/nr-arena-image.cpp new file mode 100644 index 000000000..ee566d2dc --- /dev/null +++ b/src/display/nr-arena-image.cpp @@ -0,0 +1,258 @@ +#define __NR_ARENA_IMAGE_C__ + +/* + * RGBA display list system for inkscape + * + * Author: + * Lauris Kaplinski + * + * Copyright (C) 2001-2002 Lauris Kaplinski + * Copyright (C) 2001 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include +#include "../prefs-utils.h" +#include "nr-arena-image.h" + +int nr_arena_image_x_sample = 1; +int nr_arena_image_y_sample = 1; + +/* + * NRArenaCanvasImage + * + */ + +static void nr_arena_image_class_init (NRArenaImageClass *klass); +static void nr_arena_image_init (NRArenaImage *image); +static void nr_arena_image_finalize (NRObject *object); + +static unsigned int nr_arena_image_update (NRArenaItem *item, NRRectL *area, NRGC *gc, unsigned int state, unsigned int reset); +static unsigned int nr_arena_image_render (NRArenaItem *item, NRRectL *area, NRPixBlock *pb, unsigned int flags); +static NRArenaItem *nr_arena_image_pick (NRArenaItem *item, NR::Point p, double delta, unsigned int sticky); + +static NRArenaItemClass *parent_class; + +NRType +nr_arena_image_get_type (void) +{ + static NRType type = 0; + if (!type) { + type = nr_object_register_type (NR_TYPE_ARENA_ITEM, + "NRArenaImage", + sizeof (NRArenaImageClass), + sizeof (NRArenaImage), + (void (*) (NRObjectClass *)) nr_arena_image_class_init, + (void (*) (NRObject *)) nr_arena_image_init); + } + return type; +} + +static void +nr_arena_image_class_init (NRArenaImageClass *klass) +{ + NRObjectClass *object_class; + NRArenaItemClass *item_class; + + object_class = (NRObjectClass *) klass; + item_class = (NRArenaItemClass *) klass; + + parent_class = (NRArenaItemClass *) ((NRObjectClass *) klass)->parent; + + object_class->finalize = nr_arena_image_finalize; + object_class->cpp_ctor = NRObject::invoke_ctor; + + item_class->update = nr_arena_image_update; + item_class->render = nr_arena_image_render; + item_class->pick = nr_arena_image_pick; +} + +static void +nr_arena_image_init (NRArenaImage *image) +{ + image->px = NULL; + + image->pxw = image->pxh = image->pxrs = 0; + image->x = image->y = 0.0; + image->width = 256.0; + image->height = 256.0; + + nr_matrix_set_identity (&image->grid2px); +} + +static void +nr_arena_image_finalize (NRObject *object) +{ + NRArenaImage *image = NR_ARENA_IMAGE (object); + + image->px = NULL; + + ((NRObjectClass *) parent_class)->finalize (object); +} + +static unsigned int +nr_arena_image_update (NRArenaItem *item, NRRectL *area, NRGC *gc, unsigned int state, unsigned int reset) +{ + NRMatrix grid2px; + + NRArenaImage *image = NR_ARENA_IMAGE (item); + + /* Request render old */ + nr_arena_item_request_render (item); + + /* Copy affine */ + nr_matrix_invert (&grid2px, &gc->transform); + double hscale, vscale; // todo: replace with NR::scale + if (image->px) { + hscale = image->pxw / image->width; + vscale = image->pxh / image->height; + } else { + hscale = 1.0; + vscale = 1.0; + } + + image->grid2px[0] = grid2px.c[0] * hscale; + image->grid2px[2] = grid2px.c[2] * hscale; + image->grid2px[4] = grid2px.c[4] * hscale; + image->grid2px[1] = grid2px.c[1] * vscale; + image->grid2px[3] = grid2px.c[3] * vscale; + image->grid2px[5] = grid2px.c[5] * vscale; + + image->grid2px[4] -= image->x * hscale; + image->grid2px[5] -= image->y * vscale; + + /* Calculate bbox */ + if (image->px) { + NRRect bbox; + + bbox.x0 = image->x; + bbox.y0 = image->y; + bbox.x1 = image->x + image->width; + bbox.y1 = image->y + image->height; + nr_rect_d_matrix_transform (&bbox, &bbox, &gc->transform); + + item->bbox.x0 = (int) floor (bbox.x0); + item->bbox.y0 = (int) floor (bbox.y0); + item->bbox.x1 = (int) ceil (bbox.x1); + item->bbox.y1 = (int) ceil (bbox.y1); + } else { + item->bbox.x0 = (int) gc->transform[4]; + item->bbox.y0 = (int) gc->transform[5]; + item->bbox.x1 = item->bbox.x0 - 1; + item->bbox.y1 = item->bbox.y0 - 1; + } + + nr_arena_item_request_render (item); + + return NR_ARENA_ITEM_STATE_ALL; +} + +#define FBITS 12 +#define b2i (image->grid2px) + +static unsigned int +nr_arena_image_render (NRArenaItem *item, NRRectL *area, NRPixBlock *pb, unsigned int flags) +{ + nr_arena_image_x_sample = prefs_get_int_attribute ("options.bitmapoversample", "value", 1); + nr_arena_image_y_sample = nr_arena_image_x_sample; + + NRArenaImage *image = NR_ARENA_IMAGE (item); + + if (!image->px) return item->state; + + guint32 Falpha = item->opacity; + if (Falpha < 1) return item->state; + + unsigned char * dpx = NR_PIXBLOCK_PX (pb); + const int drs = pb->rs; + const int dw = pb->area.x1 - pb->area.x0; + const int dh = pb->area.y1 - pb->area.y0; + + unsigned char * spx = image->px; + const int srs = image->pxrs; + const int sw = image->pxw; + const int sh = image->pxh; + + NR::Matrix d2s; + + d2s[0] = b2i[0]; + d2s[1] = b2i[1]; + d2s[2] = b2i[2]; + d2s[3] = b2i[3]; + d2s[4] = b2i[0] * pb->area.x0 + b2i[2] * pb->area.y0 + b2i[4]; + d2s[5] = b2i[1] * pb->area.x0 + b2i[3] * pb->area.y0 + b2i[5]; + + if (pb->mode == NR_PIXBLOCK_MODE_R8G8B8) { + /* fixme: This is not implemented yet (Lauris) */ + /* nr_R8G8B8_R8G8B8_R8G8B8A8_N_TRANSFORM (dpx, dw, dh, drs, spx, sw, sh, srs, d2s, Falpha, nr_arena_image_x_sample, nr_arena_image_y_sample); */ + } else if (pb->mode == NR_PIXBLOCK_MODE_R8G8B8A8P) { + nr_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_TRANSFORM (dpx, dw, dh, drs, spx, sw, sh, srs, d2s, Falpha, nr_arena_image_x_sample, nr_arena_image_y_sample); + } else if (pb->mode == NR_PIXBLOCK_MODE_R8G8B8A8N) { + + //FIXME: The _N_N_N_ version gives a gray border around images, see bug 906376 + // This mode is only used when exporting, screen rendering always has _P_P_P_, so I decided to simply replace it for now + // Feel free to propose a better fix + + //nr_R8G8B8A8_N_R8G8B8A8_N_R8G8B8A8_N_TRANSFORM (dpx, dw, dh, drs, spx, sw, sh, srs, d2s, Falpha, nr_arena_image_x_sample, nr_arena_image_y_sample); + nr_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_TRANSFORM (dpx, dw, dh, drs, spx, sw, sh, srs, d2s, Falpha, nr_arena_image_x_sample, nr_arena_image_y_sample); + } + + pb->empty = FALSE; + + return item->state; +} + +static NRArenaItem * +nr_arena_image_pick (NRArenaItem *item, NR::Point p, double delta, unsigned int sticky) +{ + NRArenaImage *image = NR_ARENA_IMAGE (item); + + if (!image->px) return NULL; + + unsigned char * const pixels = image->px; + const int width = image->pxw; + const int height = image->pxh; + const int rowstride = image->pxrs; + NR::Point tp = p * image->grid2px; + const int ix = (int)(tp[NR::X]); + const int iy = (int)(tp[NR::Y]); + + if ((ix < 0) || (iy < 0) || (ix >= width) || (iy >= height)) + return NULL; + + unsigned char *pix_ptr = pixels + iy * rowstride + ix * 4; + // is the alpha not transparent? + return (pix_ptr[3] > 0) ? item : NULL; +} + +/* Utility */ + +void +nr_arena_image_set_pixels (NRArenaImage *image, const unsigned char *px, unsigned int pxw, unsigned int pxh, unsigned int pxrs) +{ + nr_return_if_fail (image != NULL); + nr_return_if_fail (NR_IS_ARENA_IMAGE (image)); + + image->px = (unsigned char *) px; + image->pxw = pxw; + image->pxh = pxh; + image->pxrs = pxrs; + + nr_arena_item_request_update (NR_ARENA_ITEM (image), NR_ARENA_ITEM_STATE_ALL, FALSE); +} + +void +nr_arena_image_set_geometry (NRArenaImage *image, double x, double y, double width, double height) +{ + nr_return_if_fail (image != NULL); + nr_return_if_fail (NR_IS_ARENA_IMAGE (image)); + + image->x = x; + image->y = y; + image->width = width; + image->height = height; + + nr_arena_item_request_update (NR_ARENA_ITEM (image), NR_ARENA_ITEM_STATE_ALL, FALSE); +} + diff --git a/src/display/nr-arena-image.h b/src/display/nr-arena-image.h new file mode 100644 index 000000000..8c5afc55f --- /dev/null +++ b/src/display/nr-arena-image.h @@ -0,0 +1,51 @@ +#ifndef __NR_ARENA_IMAGE_H__ +#define __NR_ARENA_IMAGE_H__ + +/* + * RGBA display list system for inkscape + * + * Author: + * Lauris Kaplinski + * + * Copyright (C) 2001-2002 Lauris Kaplinski + * Copyright (C) 2001 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#define NR_TYPE_ARENA_IMAGE (nr_arena_image_get_type ()) +#define NR_ARENA_IMAGE(o) (NR_CHECK_INSTANCE_CAST ((o), NR_TYPE_ARENA_IMAGE, NRArenaImage)) +#define NR_IS_ARENA_IMAGE(o) (NR_CHECK_INSTANCE_TYPE ((o), NR_TYPE_ARENA_IMAGE)) + +#include +#include "nr-arena-item.h" + +NRType nr_arena_image_get_type (void); + +struct NRArenaImage : public NRArenaItem { + unsigned char *px; + unsigned int pxw; + unsigned int pxh; + unsigned int pxrs; + + double x, y; + double width, height; + + /* From GRID to PIXELS */ + NR::Matrix grid2px; + + static NRArenaImage *create(NRArena *arena) { + NRArenaImage *obj=reinterpret_cast(nr_object_new(NR_TYPE_ARENA_IMAGE)); + obj->init(arena); + return obj; + } +}; + +struct NRArenaImageClass { + NRArenaItemClass parent_class; +}; + +void nr_arena_image_set_pixels (NRArenaImage *image, const unsigned char *px, unsigned int pxw, unsigned int pxh, unsigned int pxrs); +void nr_arena_image_set_geometry (NRArenaImage *image, double x, double y, double width, double height); + +#endif diff --git a/src/display/nr-arena-item.cpp b/src/display/nr-arena-item.cpp new file mode 100644 index 000000000..ccabe7b28 --- /dev/null +++ b/src/display/nr-arena-item.cpp @@ -0,0 +1,1155 @@ +#define __NR_ARENA_ITEM_C__ + +/* + * RGBA display list system for inkscape + * + * Author: + * Lauris Kaplinski + * + * Copyright (C) 2001-2002 Lauris Kaplinski + * Copyright (C) 2001 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#define noNR_ARENA_ITEM_VERBOSE +#define noNR_ARENA_ITEM_DEBUG_CASCADE + + +#include +#include +#include "nr-arena.h" +#include "nr-arena-item.h" +//#include "nr-arena-group.h" + + +static void nr_arena_item_class_init (NRArenaItemClass *klass); +static void nr_arena_item_init (NRArenaItem *item); +static void nr_arena_item_private_finalize (NRObject *object); + +#ifdef arena_item_tile_cache +bool insert_cache(NRArenaItem* owner,int th,int tv,NRPixBlock *ipb,NRPixBlock *mpb,double activity,double duration); +void remove_caches(NRArenaItem* owner); +bool test_cache(NRArenaItem* owner,int th,int tv,NRPixBlock &ipb,NRPixBlock &mpb,bool &hasMask); +#endif + +static NRObjectClass *parent_class; + +NRType +nr_arena_item_get_type (void) +{ + static NRType type = 0; + if (!type) { + type = nr_object_register_type (NR_TYPE_OBJECT, + "NRArenaItem", + sizeof (NRArenaItemClass), + sizeof (NRArenaItem), + (void (*) (NRObjectClass *)) nr_arena_item_class_init, + (void (*) (NRObject *)) nr_arena_item_init); + } + return type; +} + +static void +nr_arena_item_class_init (NRArenaItemClass *klass) +{ + NRObjectClass *object_class; + + object_class = (NRObjectClass *) klass; + + parent_class = ((NRObjectClass *) klass)->parent; + + object_class->finalize = nr_arena_item_private_finalize; + object_class->cpp_ctor = NRObject::invoke_ctor; +} + +NRArenaItem::NRArenaItem() { + // clear all reverse-pointing pointers before finalization + clearOnceInaccessible(&arena); + clearOnceInaccessible(&parent); + clearOnceInaccessible(&prev); +} + +static void +nr_arena_item_init (NRArenaItem *item) +{ + item->arena = NULL; + item->parent = NULL; + item->next = item->prev = NULL; + + item->key = 0; + + item->state = 0; + item->sensitive = TRUE; + item->visible = TRUE; + + memset(&item->bbox, 0, sizeof(item->bbox)); + item->transform = NULL; + item->opacity = 255; + item->render_opacity = FALSE; + +#ifdef arena_item_tile_cache + item->activity=0.0; + item->skipCaching=false; +#endif + + item->transform = NULL; + item->clip = NULL; + item->mask = NULL; + item->px = NULL; + item->data = NULL; +} + +static void +nr_arena_item_private_finalize (NRObject *object) +{ + NRArenaItem *item=static_cast(object); + +#ifdef arena_item_tile_cache + remove_caches(item); +#endif + + if (item->px) { + nr_free (item->px); + } + + if (item->transform) { + nr_free (item->transform); + } + + ((NRObjectClass *) (parent_class))->finalize (object); +} + +NRArenaItem * +nr_arena_item_children (NRArenaItem *item) +{ + nr_return_val_if_fail (item != NULL, NULL); + nr_return_val_if_fail (NR_IS_ARENA_ITEM (item), NULL); + + if (NR_ARENA_ITEM_VIRTUAL (item, children)) + return NR_ARENA_ITEM_VIRTUAL (item, children) (item); + + return NULL; +} + +NRArenaItem * +nr_arena_item_last_child (NRArenaItem *item) +{ + nr_return_val_if_fail (item != NULL, NULL); + nr_return_val_if_fail (NR_IS_ARENA_ITEM (item), NULL); + + if (NR_ARENA_ITEM_VIRTUAL (item, last_child)) { + return NR_ARENA_ITEM_VIRTUAL (item, last_child) (item); + } else { + NRArenaItem *ref; + ref = nr_arena_item_children (item); + if (ref) while (ref->next) ref = ref->next; + return ref; + } +} + +void +nr_arena_item_add_child (NRArenaItem *item, NRArenaItem *child, NRArenaItem *ref) +{ + nr_return_if_fail (item != NULL); + nr_return_if_fail (NR_IS_ARENA_ITEM (item)); + nr_return_if_fail (child != NULL); + nr_return_if_fail (NR_IS_ARENA_ITEM (child)); + nr_return_if_fail (child->parent == NULL); + nr_return_if_fail (child->prev == NULL); + nr_return_if_fail (child->next == NULL); + nr_return_if_fail (child->arena == item->arena); + nr_return_if_fail (child != ref); + nr_return_if_fail (!ref || NR_IS_ARENA_ITEM (ref)); + nr_return_if_fail (!ref || (ref->parent == item)); + + if (NR_ARENA_ITEM_VIRTUAL (item, add_child)) + NR_ARENA_ITEM_VIRTUAL (item, add_child) (item, child, ref); +} + +void +nr_arena_item_remove_child (NRArenaItem *item, NRArenaItem *child) +{ + nr_return_if_fail (item != NULL); + nr_return_if_fail (NR_IS_ARENA_ITEM (item)); + nr_return_if_fail (child != NULL); + nr_return_if_fail (NR_IS_ARENA_ITEM (child)); + nr_return_if_fail (child->parent == item); + + if (NR_ARENA_ITEM_VIRTUAL (item, remove_child)) + NR_ARENA_ITEM_VIRTUAL (item, remove_child) (item, child); +} + +void +nr_arena_item_set_child_position (NRArenaItem *item, NRArenaItem *child, NRArenaItem *ref) +{ + nr_return_if_fail (item != NULL); + nr_return_if_fail (NR_IS_ARENA_ITEM (item)); + nr_return_if_fail (child != NULL); + nr_return_if_fail (NR_IS_ARENA_ITEM (child)); + nr_return_if_fail (child->parent == item); + nr_return_if_fail (!ref || NR_IS_ARENA_ITEM (ref)); + nr_return_if_fail (!ref || (ref->parent == item)); + + if (NR_ARENA_ITEM_VIRTUAL (item, set_child_position)) + NR_ARENA_ITEM_VIRTUAL (item, set_child_position) (item, child, ref); +} + +NRArenaItem * +nr_arena_item_ref (NRArenaItem *item) +{ + nr_object_ref ((NRObject *) item); + + return item; +} + +NRArenaItem * +nr_arena_item_unref (NRArenaItem *item) +{ + nr_object_unref ((NRObject *) item); + + return NULL; +} + +unsigned int +nr_arena_item_invoke_update (NRArenaItem *item, NRRectL *area, NRGC *gc, unsigned int state, unsigned int reset) +{ + NRGC childgc(gc); + + nr_return_val_if_fail (item != NULL, NR_ARENA_ITEM_STATE_INVALID); + nr_return_val_if_fail (NR_IS_ARENA_ITEM (item), NR_ARENA_ITEM_STATE_INVALID); + nr_return_val_if_fail (!(state & NR_ARENA_ITEM_STATE_INVALID), NR_ARENA_ITEM_STATE_INVALID); + +#ifdef NR_ARENA_ITEM_DEBUG_CASCADE + printf ("Update %s:%p %x %x %x\n", nr_type_name_from_instance ((GTypeInstance *) item), item, state, item->state, reset); +#endif + + /* return if in error */ + if (item->state & NR_ARENA_ITEM_STATE_INVALID) return item->state; + /* Set reset flags according to propagation status */ + if (item->propagate) { + reset |= ~item->state; + item->propagate = FALSE; + } + /* Reset our state */ + item->state &= ~reset; + /* Return if NOP */ + if (!(~item->state & state)) return item->state; + /* Test whether to return immediately */ + if (area && (item->state & NR_ARENA_ITEM_STATE_BBOX)) { + if (!nr_rect_l_test_intersect (area, &item->bbox)) return item->state; + } + + /* Reset image cache, if not to be kept */ + if (!(item->state & NR_ARENA_ITEM_STATE_IMAGE) && (item->px)) { + nr_free (item->px); + item->px = NULL; + } +#ifdef arena_item_tile_cache + remove_caches(item); +#endif + + /* Set up local gc */ + childgc = *gc; + if (item->transform) { + nr_matrix_multiply (&childgc.transform, item->transform, &childgc.transform); + } + + /* Invoke the real method */ + item->state = NR_ARENA_ITEM_VIRTUAL (item, update) (item, area, &childgc, state, reset); + if (item->state & NR_ARENA_ITEM_STATE_INVALID) return item->state; + /* Clipping */ + if (item->clip) { + unsigned int newstate; + newstate = nr_arena_item_invoke_update (item->clip, area, &childgc, state, reset); + if (newstate & NR_ARENA_ITEM_STATE_INVALID) { + item->state |= NR_ARENA_ITEM_STATE_INVALID; + return item->state; + } + nr_rect_l_intersect (&item->bbox, &item->bbox, &item->clip->bbox); + } + /* Masking */ + if (item->mask) { + unsigned int newstate; + newstate = nr_arena_item_invoke_update (item->mask, area, &childgc, state, reset); + if (newstate & NR_ARENA_ITEM_STATE_INVALID) { + item->state |= NR_ARENA_ITEM_STATE_INVALID; + return item->state; + } + nr_rect_l_intersect (&item->bbox, &item->bbox, &item->mask->bbox); + } + + return item->state; +} + +/** + * Render item to pixblock. + * + * \return Has NR_ARENA_ITEM_STATE_RENDER set on success. + */ + +unsigned int nr_arena_item_invoke_render(NRArenaItem *item, NRRectL const *area, NRPixBlock *pb, unsigned int flags) +{ + NRRectL carea; + NRPixBlock *dpb; + NRPixBlock cpb; + unsigned int state; + + nr_return_val_if_fail (item != NULL, NR_ARENA_ITEM_STATE_INVALID); + nr_return_val_if_fail (NR_IS_ARENA_ITEM (item), NR_ARENA_ITEM_STATE_INVALID); + nr_return_val_if_fail (item->state & NR_ARENA_ITEM_STATE_BBOX, item->state); + +#ifdef NR_ARENA_ITEM_VERBOSE + printf ("Invoke render %p: %d %d - %d %d\n", item, area->x0, area->y0, area->x1, area->y1); +#endif + +#ifdef arena_item_tile_cache + item->activity*=0.5; +#endif + + /* If we are outside bbox just return successfully */ + if (!item->visible) return item->state | NR_ARENA_ITEM_STATE_RENDER; + nr_rect_l_intersect (&carea, area, &item->bbox); + if (nr_rect_l_test_empty (&carea)) return item->state | NR_ARENA_ITEM_STATE_RENDER; + + if (item->px) { + /* Has cache pixblock, render this and return */ + nr_pixblock_setup_extern (&cpb, NR_PIXBLOCK_MODE_R8G8B8A8P, + /* fixme: This probably cannot overflow, because we render only if visible */ + /* fixme: and pixel cache is there only for small items */ + /* fixme: But this still needs extra check (Lauris) */ + item->bbox.x0, item->bbox.y0, + item->bbox.x1, item->bbox.y1, + item->px, 4 * (item->bbox.x1 - item->bbox.x0), FALSE, FALSE); + nr_blit_pixblock_pixblock (pb, &cpb); + nr_pixblock_release (&cpb); + pb->empty = FALSE; + return item->state | NR_ARENA_ITEM_STATE_RENDER; + } + + dpb = pb; + bool canCache=false; +#ifdef arena_item_tile_cache + bool checkCache=false; + int tile_h=0,tile_v=0; +#endif + /* Setup cache if we can */ + if ((!(flags & NR_ARENA_ITEM_RENDER_NO_CACHE)) && + (carea.x0 <= item->bbox.x0) && (carea.y0 <= item->bbox.y0) && + (carea.x1 >= item->bbox.x1) && (carea.y1 >= item->bbox.y1) && + (((item->bbox.x1 - item->bbox.x0) * (item->bbox.y1 - item->bbox.y0)) <= 4096)) { + // Item bbox is fully in renderable area and size is acceptable + carea.x0 = item->bbox.x0; + carea.y0 = item->bbox.y0; + carea.x1 = item->bbox.x1; + carea.y1 = item->bbox.y1; + item->px = nr_new (unsigned char, 4 * (carea.x1 - carea.x0) * (carea.y1 - carea.y0)); + nr_pixblock_setup_extern (&cpb, NR_PIXBLOCK_MODE_R8G8B8A8P, + carea.x0, carea.y0, carea.x1, carea.y1, + item->px, 4 * (carea.x1 - carea.x0), TRUE, TRUE); + dpb = &cpb; + // Set nocache flag for downstream rendering + flags |= NR_ARENA_ITEM_RENDER_NO_CACHE; + } else { +#ifdef arena_item_tile_cache + if ( item->skipCaching ) { + } else { + int tl=area->x0&(~127); + int tt=area->y0&(~127); + if ( area->x1 <= tl+128 && area->y1 <= tt+128 ) { + checkCache=true; + tile_h=tl/128; + tile_v=tt/128; + int surf=(area->x1-area->x0)*(area->y1-area->y0); + if ( surf >= 4096 ) { + canCache=true; + carea.x0=tl; + carea.y0=tt; + carea.x1=tl+128; + carea.y1=tt+128; + } + } + } +#endif + } + +#ifdef arena_item_tile_cache + item->activity+=1.0; +#endif + +#ifdef arena_item_tile_cache + if ( checkCache ) { + NRPixBlock ipb, mpb; + bool hasMask; + if ( test_cache(item,tile_h,tile_v,ipb,mpb,hasMask) ) { + // youpi! c'etait deja cache + if ( hasMask ) { + nr_blit_pixblock_pixblock_mask (dpb, &ipb, &mpb); + } else if ( ((item->opacity != 255) && !item->render_opacity) ) { + nr_blit_pixblock_pixblock_alpha (dpb, &ipb, item->opacity); + } else { + nr_blit_pixblock_pixblock (pb, &ipb); + } + pb->empty = FALSE; + return item->state | NR_ARENA_ITEM_STATE_RENDER; + } + } +#endif + if ( canCache ) { +#ifdef arena_item_tile_cache + // nota: exclusif de dpb != pb, donc pas de cas particulier a la fin + NRPixBlock ipb, mpb; + + // struct timeval start_time,end_time; + // gettimeofday(&start_time,NULL); + GTimeVal start_time,end_time; + g_get_current_time (&start_time); + int duration=0; + + /* Setup and render item buffer */ + nr_pixblock_setup_fast (&ipb, NR_PIXBLOCK_MODE_R8G8B8A8P, carea.x0, carea.y0, carea.x1, carea.y1, TRUE); + state = NR_ARENA_ITEM_VIRTUAL (item, render) (item, &carea, &ipb, flags); + if (state & NR_ARENA_ITEM_STATE_INVALID) { + /* Clean up and return error */ + nr_pixblock_release (&ipb); + if (dpb != pb) nr_pixblock_release (dpb); + item->state |= NR_ARENA_ITEM_STATE_INVALID; + return item->state; + } + ipb.empty = FALSE; + + if (item->clip || item->mask) { + /* Setup mask pixblock */ + nr_pixblock_setup_fast (&mpb, NR_PIXBLOCK_MODE_A8, carea.x0, carea.y0, carea.x1, carea.y1, TRUE); + /* Do clip if needed */ + if (item->clip) { + state = nr_arena_item_invoke_clip (item->clip, &carea, &mpb); + if (state & NR_ARENA_ITEM_STATE_INVALID) { + /* Clean up and return error */ + nr_pixblock_release (&mpb); + nr_pixblock_release (&ipb); + if (dpb != pb) nr_pixblock_release (dpb); + item->state |= NR_ARENA_ITEM_STATE_INVALID; + return item->state; + } + mpb.empty = FALSE; + } + /* Do mask if needed */ + if (item->mask) { + NRPixBlock tpb; + /* Set up yet another temporary pixblock */ + nr_pixblock_setup_fast (&tpb, NR_PIXBLOCK_MODE_R8G8B8A8N, carea.x0, carea.y0, carea.x1, carea.y1, TRUE); + state = NR_ARENA_ITEM_VIRTUAL (item->mask, render) (item->mask, &carea, &tpb, flags); + if (state & NR_ARENA_ITEM_STATE_INVALID) { + /* Clean up and return error */ + nr_pixblock_release (&tpb); + nr_pixblock_release (&mpb); + nr_pixblock_release (&ipb); + if (dpb != pb) nr_pixblock_release (dpb); + item->state |= NR_ARENA_ITEM_STATE_INVALID; + return item->state; + } + /* Composite with clip */ + if (item->clip) { + int x, y; + for (y = carea.y0; y < carea.y1; y++) { + unsigned char *s, *d; + s = NR_PIXBLOCK_PX (&tpb) + (y - carea.y0) * tpb.rs; + d = NR_PIXBLOCK_PX (&mpb) + (y - carea.y0) * mpb.rs; + for (x = carea.x0; x < carea.x1; x++) { + unsigned int m; + m = ((s[0] + s[1] + s[2]) * s[3] + 127) / (3 * 255); + d[0] = NR_PREMUL (d[0], m); + s += 4; + d += 1; + } + } + } else { + int x, y; + for (y = carea.y0; y < carea.y1; y++) { + unsigned char *s, *d; + s = NR_PIXBLOCK_PX (&tpb) + (y - carea.y0) * tpb.rs; + d = NR_PIXBLOCK_PX (&mpb) + (y - carea.y0) * mpb.rs; + for (x = carea.x0; x < carea.x1; x++) { + unsigned int m; + m = ((s[0] + s[1] + s[2]) * s[3] + 127) / (3 * 255); + d[0] = m; + s += 4; + d += 1; + } + } + mpb.empty = FALSE; + } + nr_pixblock_release (&tpb); + } + /* Multiply with opacity if needed */ + if ((item->opacity != 255) && !item->render_opacity && item->arena->rendermode != RENDERMODE_OUTLINE) { + int x, y; + unsigned int a; + a = item->opacity; + for (y = carea.y0; y < carea.y1; y++) { + unsigned char *d; + d = NR_PIXBLOCK_PX (&mpb) + (y - carea.y0) * mpb.rs; + for (x = carea.x0; x < carea.x1; x++) { + d[0] = NR_PREMUL (d[0], a); + d += 1; + } + } + } + /* Compose rendering pixblock int destination */ + // gettimeofday(&end_time,NULL); + g_get_current_time (&end_time); + duration=(end_time.tv_sec-start_time.tv_sec)*1000+(end_time.tv_usec-start_time.tv_usec)/1000; + if ( !(ipb.empty) ) { + nr_blit_pixblock_pixblock_mask (dpb, &ipb, &mpb); + if ( insert_cache(item,tile_h,tile_v,&ipb,&mpb,item->activity,(double)duration) ) { + } else { + nr_pixblock_release (&mpb); + nr_pixblock_release (&ipb); + } + dpb->empty = FALSE; + } else { + nr_pixblock_release (&ipb); + } + } else if ( ((item->opacity != 255) && !item->render_opacity && item->arena->rendermode != RENDERMODE_OUTLINE) ) { + /* Opacity only */ + // gettimeofday(&end_time,NULL); + g_get_current_time (&end_time); + duration=(end_time.tv_sec-start_time.tv_sec)*1000+(end_time.tv_usec-start_time.tv_usec)/1000; + if ( !(ipb.empty) ) { + nr_blit_pixblock_pixblock_alpha (dpb, &ipb, item->opacity); + if ( insert_cache(item,tile_h,tile_v,&ipb,NULL,item->activity,(double)duration) ) { + } else { + nr_pixblock_release (&ipb); + } + dpb->empty = FALSE; + } else { + nr_pixblock_release (&ipb); + } + } else { + // gettimeofday(&end_time,NULL); + g_get_current_time (&end_time); + duration=(end_time.tv_sec-start_time.tv_sec)*1000+(end_time.tv_usec-start_time.tv_usec)/1000; + if ( !(ipb.empty) ) { + nr_blit_pixblock_pixblock (dpb, &ipb); + if ( insert_cache(item,tile_h,tile_v,&ipb,NULL,item->activity,(double)duration) ) { + } else { + nr_pixblock_release (&ipb); + } + dpb->empty = FALSE; + } else { + nr_pixblock_release (&ipb); + } + } +#endif + } else { + /* Determine, whether we need temporary buffer */ + if (item->clip || item->mask || ((item->opacity != 255) && !item->render_opacity && item->arena->rendermode != RENDERMODE_OUTLINE)) { + NRPixBlock ipb, mpb; + + /* Setup and render item buffer */ + nr_pixblock_setup_fast (&ipb, NR_PIXBLOCK_MODE_R8G8B8A8P, carea.x0, carea.y0, carea.x1, carea.y1, TRUE); + state = NR_ARENA_ITEM_VIRTUAL (item, render) (item, &carea, &ipb, flags); + if (state & NR_ARENA_ITEM_STATE_INVALID) { + /* Clean up and return error */ + nr_pixblock_release (&ipb); + if (dpb != pb) nr_pixblock_release (dpb); + item->state |= NR_ARENA_ITEM_STATE_INVALID; + return item->state; + } + ipb.empty = FALSE; + + if (item->clip || item->mask) { + /* Setup mask pixblock */ + nr_pixblock_setup_fast (&mpb, NR_PIXBLOCK_MODE_A8, carea.x0, carea.y0, carea.x1, carea.y1, TRUE); + /* Do clip if needed */ + if (item->clip) { + state = nr_arena_item_invoke_clip (item->clip, &carea, &mpb); + if (state & NR_ARENA_ITEM_STATE_INVALID) { + /* Clean up and return error */ + nr_pixblock_release (&mpb); + nr_pixblock_release (&ipb); + if (dpb != pb) nr_pixblock_release (dpb); + item->state |= NR_ARENA_ITEM_STATE_INVALID; + return item->state; + } + mpb.empty = FALSE; + } + /* Do mask if needed */ + if (item->mask) { + NRPixBlock tpb; + /* Set up yet another temporary pixblock */ + nr_pixblock_setup_fast (&tpb, NR_PIXBLOCK_MODE_R8G8B8A8N, carea.x0, carea.y0, carea.x1, carea.y1, TRUE); + state = NR_ARENA_ITEM_VIRTUAL (item->mask, render) (item->mask, &carea, &tpb, flags); + if (state & NR_ARENA_ITEM_STATE_INVALID) { + /* Clean up and return error */ + nr_pixblock_release (&tpb); + nr_pixblock_release (&mpb); + nr_pixblock_release (&ipb); + if (dpb != pb) nr_pixblock_release (dpb); + item->state |= NR_ARENA_ITEM_STATE_INVALID; + return item->state; + } + /* Composite with clip */ + if (item->clip) { + int x, y; + for (y = carea.y0; y < carea.y1; y++) { + unsigned char *s, *d; + s = NR_PIXBLOCK_PX (&tpb) + (y - carea.y0) * tpb.rs; + d = NR_PIXBLOCK_PX (&mpb) + (y - carea.y0) * mpb.rs; + for (x = carea.x0; x < carea.x1; x++) { + unsigned int m; + m = ((s[0] + s[1] + s[2]) * s[3] + 127) / (3 * 255); + d[0] = NR_PREMUL (d[0], m); + s += 4; + d += 1; + } + } + } else { + int x, y; + for (y = carea.y0; y < carea.y1; y++) { + unsigned char *s, *d; + s = NR_PIXBLOCK_PX (&tpb) + (y - carea.y0) * tpb.rs; + d = NR_PIXBLOCK_PX (&mpb) + (y - carea.y0) * mpb.rs; + for (x = carea.x0; x < carea.x1; x++) { + unsigned int m; + m = ((s[0] + s[1] + s[2]) * s[3] + 127) / (3 * 255); + d[0] = m; + s += 4; + d += 1; + } + } + mpb.empty = FALSE; + } + nr_pixblock_release (&tpb); + } + /* Multiply with opacity if needed */ + if ((item->opacity != 255) && !item->render_opacity && item->arena->rendermode != RENDERMODE_OUTLINE) { + int x, y; + unsigned int a; + a = item->opacity; + for (y = carea.y0; y < carea.y1; y++) { + unsigned char *d; + d = NR_PIXBLOCK_PX (&mpb) + (y - carea.y0) * mpb.rs; + for (x = carea.x0; x < carea.x1; x++) { + d[0] = NR_PREMUL (d[0], a); + d += 1; + } + } + } + /* Compose rendering pixblock int destination */ + nr_blit_pixblock_pixblock_mask (dpb, &ipb, &mpb); + nr_pixblock_release (&mpb); + } else { + /* Opacity only */ + nr_blit_pixblock_pixblock_alpha (dpb, &ipb, item->opacity); + } + nr_pixblock_release (&ipb); + dpb->empty = FALSE; + } else { + /* Just render */ + state = NR_ARENA_ITEM_VIRTUAL (item, render) (item, &carea, dpb, flags); + if (state & NR_ARENA_ITEM_STATE_INVALID) { + /* Clean up and return error */ + if (dpb != pb) nr_pixblock_release (dpb); + item->state |= NR_ARENA_ITEM_STATE_INVALID; + return item->state; + } + dpb->empty = FALSE; + } + + if (dpb != pb) { + /* Have to blit from cache */ + nr_blit_pixblock_pixblock (pb, dpb); + nr_pixblock_release (dpb); + pb->empty = FALSE; + item->state |= NR_ARENA_ITEM_STATE_IMAGE; + } + } + return item->state | NR_ARENA_ITEM_STATE_RENDER; +} + +unsigned int +nr_arena_item_invoke_clip (NRArenaItem *item, NRRectL *area, NRPixBlock *pb) +{ + nr_return_val_if_fail (item != NULL, NR_ARENA_ITEM_STATE_INVALID); + nr_return_val_if_fail (NR_IS_ARENA_ITEM (item), NR_ARENA_ITEM_STATE_INVALID); + /* we originally short-circuited if the object state included + * NR_ARENA_ITEM_STATE_CLIP (and showed a warning on the console); + * anyone know why we stopped doing so? + */ + nr_return_val_if_fail ((pb->area.x1 - pb->area.x0) >= (area->x1 - area->x0), NR_ARENA_ITEM_STATE_INVALID); + nr_return_val_if_fail ((pb->area.y1 - pb->area.y0) >= (area->y1 - area->y0), NR_ARENA_ITEM_STATE_INVALID); + +#ifdef NR_ARENA_ITEM_VERBOSE + printf ("Invoke render %p: %d %d - %d %d\n", item, area->x0, area->y0, area->x1, area->y1); +#endif + + if (item->visible && nr_rect_l_test_intersect (area, &item->bbox)) { + /* Need render that item */ + if (((NRArenaItemClass *) NR_OBJECT_GET_CLASS (item))->clip) + return ((NRArenaItemClass *) NR_OBJECT_GET_CLASS(item))->clip (item, area, pb); + } + + return item->state; +} + +NRArenaItem * +nr_arena_item_invoke_pick (NRArenaItem *item, NR::Point p, double delta, unsigned int sticky) +{ + nr_return_val_if_fail (item != NULL, NULL); + nr_return_val_if_fail (NR_IS_ARENA_ITEM (item), NULL); + + // Sometimes there's no BBOX in item->state, reason unknown (bug 992817); I made this not an assert to remove the warning + if (!(item->state & NR_ARENA_ITEM_STATE_BBOX) || !(item->state & NR_ARENA_ITEM_STATE_PICK)) + return NULL; + + if (!sticky && !(item->visible && item->sensitive)) return NULL; + + // TODO: rewrite using NR::Rect + const double x = p[NR::X]; + const double y = p[NR::Y]; + + if (((x + delta) >= item->bbox.x0) && + ((x - delta) < item->bbox.x1) && + ((y + delta) >= item->bbox.y0) && + ((y - delta) < item->bbox.y1)) { + if (((NRArenaItemClass *) NR_OBJECT_GET_CLASS (item))->pick) + return ((NRArenaItemClass *) NR_OBJECT_GET_CLASS (item))->pick (item, p, delta, sticky); + } + + return NULL; +} + +void +nr_arena_item_request_update (NRArenaItem *item, unsigned int reset, unsigned int propagate) +{ + nr_return_if_fail (item != NULL); + nr_return_if_fail (NR_IS_ARENA_ITEM (item)); + nr_return_if_fail (!(reset & NR_ARENA_ITEM_STATE_INVALID)); + + if (propagate && !item->propagate) item->propagate = TRUE; + + if (item->state & reset) { + item->state &= ~reset; + if (item->parent) { + nr_arena_item_request_update (item->parent, reset, FALSE); + } else { + nr_arena_request_update (item->arena, item); + } + } +} + +void +nr_arena_item_request_render (NRArenaItem *item) +{ + nr_return_if_fail (item != NULL); + nr_return_if_fail (NR_IS_ARENA_ITEM (item)); + + nr_arena_request_render_rect (item->arena, &item->bbox); +} + +/* Public */ + +NRArenaItem * +nr_arena_item_unparent (NRArenaItem *item) +{ + nr_return_val_if_fail (item != NULL, NULL); + nr_return_val_if_fail (NR_IS_ARENA_ITEM (item), NULL); + + nr_arena_item_request_render (item); + + if (item->parent) { + nr_arena_item_remove_child (item->parent, item); + } + + return NULL; +} + +void +nr_arena_item_append_child (NRArenaItem *parent, NRArenaItem *child) +{ + nr_return_if_fail (parent != NULL); + nr_return_if_fail (NR_IS_ARENA_ITEM (parent)); + nr_return_if_fail (child != NULL); + nr_return_if_fail (NR_IS_ARENA_ITEM (child)); + nr_return_if_fail (parent->arena == child->arena); + nr_return_if_fail (child->parent == NULL); + nr_return_if_fail (child->prev == NULL); + nr_return_if_fail (child->next == NULL); + + nr_arena_item_add_child (parent, child, nr_arena_item_last_child (parent)); +} + +void +nr_arena_item_set_transform(NRArenaItem *item, NR::Matrix const &transform) +{ + NRMatrix const t(transform); + nr_arena_item_set_transform(item, &t); +} + +void +nr_arena_item_set_transform(NRArenaItem *item, NRMatrix const *transform) +{ + const NRMatrix *ms, *md; + + nr_return_if_fail (item != NULL); + nr_return_if_fail (NR_IS_ARENA_ITEM (item)); + + if (!transform && !item->transform) return; + + md = (item->transform) ? item->transform : &NR_MATRIX_IDENTITY; + ms = (transform) ? transform : &NR_MATRIX_IDENTITY; + + if (!NR_MATRIX_DF_TEST_CLOSE (md, ms, NR_EPSILON)) { + nr_arena_item_request_render (item); + if (!transform || nr_matrix_test_identity (transform, NR_EPSILON)) { + /* Set to identity affine */ + if (item->transform) nr_free (item->transform); + item->transform = NULL; + } else { + if (!item->transform) item->transform = nr_new (NRMatrix, 1); + *item->transform = *transform; + } + nr_arena_item_request_update (item, NR_ARENA_ITEM_STATE_ALL, TRUE); + } +} + +void +nr_arena_item_set_opacity (NRArenaItem *item, double opacity) +{ + nr_return_if_fail (item != NULL); + nr_return_if_fail (NR_IS_ARENA_ITEM (item)); + + nr_arena_item_request_render (item); + + item->opacity = (unsigned int) (opacity * 255.9999); +} + +void +nr_arena_item_set_sensitive (NRArenaItem *item, unsigned int sensitive) +{ + nr_return_if_fail (item != NULL); + nr_return_if_fail (NR_IS_ARENA_ITEM (item)); + + /* fixme: mess with pick/repick... */ + + item->sensitive = sensitive; +} + +void +nr_arena_item_set_visible (NRArenaItem *item, unsigned int visible) +{ + nr_return_if_fail (item != NULL); + nr_return_if_fail (NR_IS_ARENA_ITEM (item)); + + item->visible = visible; + + nr_arena_item_request_render (item); +} + +void +nr_arena_item_set_clip (NRArenaItem *item, NRArenaItem *clip) +{ + nr_return_if_fail (item != NULL); + nr_return_if_fail (NR_IS_ARENA_ITEM (item)); + nr_return_if_fail (!clip || NR_IS_ARENA_ITEM (clip)); + + if (clip != item->clip) { + nr_arena_item_request_render (item); + if (item->clip) item->clip = nr_arena_item_detach_unref (item, item->clip); + if (clip) item->clip = nr_arena_item_attach_ref (item, clip, NULL, NULL); + nr_arena_item_request_update (item, NR_ARENA_ITEM_STATE_ALL, TRUE); + } +} + +void +nr_arena_item_set_mask (NRArenaItem *item, NRArenaItem *mask) +{ + nr_return_if_fail (item != NULL); + nr_return_if_fail (NR_IS_ARENA_ITEM (item)); + nr_return_if_fail (!mask || NR_IS_ARENA_ITEM (mask)); + + if (mask != item->mask) { + nr_arena_item_request_render (item); + if (item->mask) item->mask = nr_arena_item_detach_unref (item, item->mask); + if (mask) item->mask = nr_arena_item_attach_ref (item, mask, NULL, NULL); + nr_arena_item_request_update (item, NR_ARENA_ITEM_STATE_ALL, TRUE); + } +} + +void +nr_arena_item_set_order (NRArenaItem *item, int order) +{ + NRArenaItem *children, *child, *ref; + int pos; + + nr_return_if_fail (item != NULL); + nr_return_if_fail (NR_IS_ARENA_ITEM (item)); + + if (!item->parent) return; + + children = nr_arena_item_children (item->parent); + + ref = NULL; + pos = 0; + for (child = children; child != NULL; child = child->next) { + if (pos >= order) break; + if (child != item) { + ref = child; + pos += 1; + } + } + + nr_arena_item_set_child_position (item->parent, item, ref); +} + +/* Helpers */ + +NRArenaItem * +nr_arena_item_attach_ref (NRArenaItem *parent, NRArenaItem *child, NRArenaItem *prev, NRArenaItem *next) +{ + nr_return_val_if_fail (parent != NULL, NULL); + nr_return_val_if_fail (NR_IS_ARENA_ITEM (parent), NULL); + nr_return_val_if_fail (child != NULL, NULL); + nr_return_val_if_fail (NR_IS_ARENA_ITEM (child), NULL); + nr_return_val_if_fail (child->parent == NULL, NULL); + nr_return_val_if_fail (child->prev == NULL, NULL); + nr_return_val_if_fail (child->next == NULL, NULL); + nr_return_val_if_fail (!prev || NR_IS_ARENA_ITEM (prev), NULL); + nr_return_val_if_fail (!prev || (prev->parent == parent), NULL); + nr_return_val_if_fail (!prev || (prev->next == next), NULL); + nr_return_val_if_fail (!next || NR_IS_ARENA_ITEM (next), NULL); + nr_return_val_if_fail (!next || (next->parent == parent), NULL); + nr_return_val_if_fail (!next || (next->prev == prev), NULL); + + child->parent = parent; + child->prev = prev; + child->next = next; + + if (prev) prev->next = child; + if (next) next->prev = child; + + return child; +} + +NRArenaItem * +nr_arena_item_detach_unref (NRArenaItem *parent, NRArenaItem *child) +{ + NRArenaItem *prev, *next; + + nr_return_val_if_fail (parent != NULL, NULL); + nr_return_val_if_fail (NR_IS_ARENA_ITEM (parent), NULL); + nr_return_val_if_fail (child != NULL, NULL); + nr_return_val_if_fail (NR_IS_ARENA_ITEM (child), NULL); + nr_return_val_if_fail (child->parent == parent, NULL); + + prev = child->prev; + next = child->next; + + child->parent = NULL; + child->prev = NULL; + child->next = NULL; + + if (prev) prev->next = next; + if (next) next->prev = prev; + + return next; +} + +/* + * + * caches + * + */ + +#ifdef arena_item_tile_cache +typedef struct cache_entry { + int key; + double score; + NRArenaItem* owner; + int th,tv; + int prev,next; + NRPixBlock ipb; + bool hasMask; + NRPixBlock mpb; +} cache_entry; + +int hash_max=2048,hash_fill=1024; + +int *keys=NULL; +int nbCch=0; + +int nbEnt=0,maxEnt=0; +cache_entry* entries=NULL; + +//#define tile_cache_stats +#ifdef tile_cache_stats +double hits=0,misses=0; +int hitMissCount=0; +#endif + +int hash_that(NRArenaItem* owner,int th,int tv) +{ + int res=GPOINTER_TO_INT(owner); + res*=17; + res+=th; + res*=59; + res+=tv; + res*=217; + if ( res < 0 ) res=-res; + res%=hash_max; + return res; +} + +bool test_cache(NRArenaItem* owner,int th,int tv,NRPixBlock &ipb,NRPixBlock &mpb,bool &hasMask) +{ + if ( keys == NULL ) { + hash_max = prefs_get_int_attribute ("options.arenatilescachesize", "value", 2048); + hash_fill=(hash_max*3)/4; + keys=(int*)malloc(hash_max*sizeof(int)); + for (int i=0;i= 0 && cur < nbEnt ) { + if ( entries[cur].owner == owner && entries[cur].th == th && entries[cur].tv == tv ) { + hasMask=entries[cur].hasMask; + ipb=entries[cur].ipb; + mpb=entries[cur].mpb; +#ifdef tile_cache_stats + hits+=1.0; +#endif + return true; + } + cur=entries[cur].next; + } +#ifdef tile_cache_stats + misses+=1.0; +#endif + return false; +} +void remove_one_cache(int no) +{ + if ( no < 0 || no >= nbEnt ) return; + + nr_pixblock_release(&entries[no].ipb); + if ( entries[no].hasMask ) nr_pixblock_release(&entries[no].mpb); + + if ( entries[no].prev >= 0 ) entries[entries[no].prev].next=entries[no].next; + if ( entries[no].next >= 0 ) entries[entries[no].next].prev=entries[no].prev; + if ( entries[no].prev < 0 ) keys[entries[no].key]=entries[no].next; + entries[no].prev=entries[no].next=entries[no].key=-1; + + if ( no == nbEnt-1 ) { + nbEnt--; + return; + } + entries[no]=entries[--nbEnt]; + if ( entries[no].prev >= 0 ) entries[entries[no].prev].next=no; + if ( entries[no].next >= 0 ) entries[entries[no].next].prev=no; + if ( entries[no].prev < 0 ) keys[entries[no].key]=no; +} +void remove_caches(NRArenaItem* owner) +{ + if ( keys == NULL ) { + hash_max = prefs_get_int_attribute ("options.arenatilescachesize", "value", 2048); + hash_fill=(hash_max*3)/4; + keys=(int*)malloc(hash_max*sizeof(int)); + for (int i=0;i=0;i--) { + if ( entries[i].owner == owner ) { + remove_one_cache(i); + } + } +} +void age_cache(void) +{ + for (int i=0;i 100 ) { + hitMissCount=0; + printf("hit/miss = %f used/total=%i/%i\n",(misses>0.001)?hits/misses:100000.0,nbEnt,hash_max); // localizing ok + } +#endif + int key=hash_that(owner,th,tv); + double nScore=/*activity**/duration; + + if ( keys[key] >= 0 ) { + int cur=keys[key]; + while ( cur >= 0 && cur < nbEnt ) { + if ( entries[cur].owner == owner && entries[cur].th == th && entries[cur].tv == tv ) { + remove_one_cache(cur); + break; + } + cur=entries[cur].next; + } + } + + bool doAdd=false; + if ( nbEnt < hash_fill ) { + doAdd=true; + } else { + double worstS=entries[0].score; + int worstE=0; + for (int i=1;i= maxEnt ) { + maxEnt=2*nbEnt+1; + entries=(cache_entry*)realloc(entries,maxEnt*sizeof(cache_entry)); + } + entries[nbEnt].key=key; + entries[nbEnt].score=nScore; + entries[nbEnt].owner=owner; + entries[nbEnt].th=th; + entries[nbEnt].tv=tv; + entries[nbEnt].prev=entries[nbEnt].next=-1; + entries[nbEnt].ipb=*ipb; + if ( mpb ) { + entries[nbEnt].hasMask=true; + entries[nbEnt].mpb=*mpb; + } else { + entries[nbEnt].hasMask=false; + } + entries[nbEnt].next=keys[key]; + if ( entries[nbEnt].next >= 0 ) entries[entries[nbEnt].next].prev=nbEnt; + keys[key]=nbEnt; + + nbEnt++; + return true; +} +#endif + + + + diff --git a/src/display/nr-arena-item.h b/src/display/nr-arena-item.h new file mode 100644 index 000000000..f43152ff9 --- /dev/null +++ b/src/display/nr-arena-item.h @@ -0,0 +1,188 @@ +#ifndef __NR_ARENA_ITEM_H__ +#define __NR_ARENA_ITEM_H__ + +/* + * RGBA display list system for inkscape + * + * Author: + * Lauris Kaplinski + * + * Copyright (C) 2001-2002 Lauris Kaplinski + * Copyright (C) 2001 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#define NR_TYPE_ARENA_ITEM (nr_arena_item_get_type ()) +#define NR_ARENA_ITEM(o) (NR_CHECK_INSTANCE_CAST ((o), NR_TYPE_ARENA_ITEM, NRArenaItem)) +#define NR_IS_ARENA_ITEM(o) (NR_CHECK_INSTANCE_TYPE ((o), NR_TYPE_ARENA_ITEM)) + +#define NR_ARENA_ITEM_VIRTUAL(i,m) (((NRArenaItemClass *) NR_OBJECT_GET_CLASS (i))->m) + +/* + * NRArenaItem state flags + */ + +/* + * NR_ARENA_ITEM_STATE_INVALID + * + * If set or retuned indicates, that given object is in error. + * Calling method has to return immediately, with appropriate + * error flag. + */ + +#define NR_ARENA_ITEM_STATE_INVALID (1 << 0) + + +#define NR_ARENA_ITEM_STATE_BBOX (1 << 1) +#define NR_ARENA_ITEM_STATE_COVERAGE (1 << 2) +#define NR_ARENA_ITEM_STATE_DRAFT (1 << 3) +#define NR_ARENA_ITEM_STATE_RENDER (1 << 4) +#define NR_ARENA_ITEM_STATE_CLIP (1 << 5) +#define NR_ARENA_ITEM_STATE_MASK (1 << 6) +#define NR_ARENA_ITEM_STATE_PICK (1 << 7) +#define NR_ARENA_ITEM_STATE_IMAGE (1 << 8) + +#define NR_ARENA_ITEM_STATE_NONE 0x0000 +#define NR_ARENA_ITEM_STATE_ALL 0x01fe + +#define NR_ARENA_ITEM_STATE(i,s) (NR_ARENA_ITEM (i)->state & (s)) +#define NR_ARENA_ITEM_SET_STATE(i,s) (NR_ARENA_ITEM (i)->state |= (s)) +#define NR_ARENA_ITEM_UNSET_STATE(i,s) (NR_ARENA_ITEM (i)->state &= ~(s)) + +#define NR_ARENA_ITEM_RENDER_NO_CACHE (1 << 0) + +#include +#include +#include +#include +#include "nr-arena-forward.h" + +// My testing shows that disabling cache reduces the amount +// of leaked memory when many documents are loaded one from the other, +// while there's no noticeable change in speed +//#define arena_item_tile_cache + +struct NRGC { + NRGC(NRGC const *p) : parent(p) {} + NRGC const *parent; + NRMatrix transform; +}; + +struct NRArenaItem : public NRObject { + NRArenaItem(); + + NRArena *arena; + NRArenaItem *parent; + NRArenaItem *next; + NRArenaItem *prev; + + /* Item state */ + unsigned int state : 16; + unsigned int propagate : 1; + unsigned int sensitive : 1; + unsigned int visible : 1; + /* Whether items renders opacity itself */ + unsigned int render_opacity : 1; + /* Opacity itself */ + unsigned int opacity : 8; + + /* Key for secondary rendering */ + unsigned int key; + +#ifdef arena_item_tile_cache + bool skipCaching; + double activity; +#endif + + /* BBox in grid coordinates */ + NRRectL bbox; + /* Our affine */ + NRMatrix *transform; + /* Clip item */ + NRArenaItem *clip; + /* Mask item */ + NRArenaItem *mask; + /* Rendered buffer */ + unsigned char *px; + + /* Single data member */ + void *data; + + void init(NRArena *arena) { + this->arena = arena; + } +}; + +struct NRArenaItemClass : public NRObjectClass { + NRArenaItem * (* children) (NRArenaItem *item); + NRArenaItem * (* last_child) (NRArenaItem *item); + void (* add_child) (NRArenaItem *item, NRArenaItem *child, NRArenaItem *ref); + void (* remove_child) (NRArenaItem *item, NRArenaItem *child); + void (* set_child_position) (NRArenaItem *item, NRArenaItem *child, NRArenaItem *ref); + + unsigned int (* update) (NRArenaItem *item, NRRectL *area, NRGC *gc, unsigned int state, unsigned int reset); + unsigned int (* render) (NRArenaItem *item, NRRectL *area, NRPixBlock *pb, unsigned int flags); + unsigned int (* clip) (NRArenaItem *item, NRRectL *area, NRPixBlock *pb); + NRArenaItem * (* pick) (NRArenaItem *item, NR::Point p, double delta, unsigned int sticky); +}; + +#define NR_ARENA_ITEM_ARENA(ai) (((NRArenaItem *) (ai))->arena) + +NRType nr_arena_item_get_type (void); + +NRArenaItem *nr_arena_item_ref (NRArenaItem *item); +NRArenaItem *nr_arena_item_unref (NRArenaItem *item); + +NRArenaItem *nr_arena_item_children (NRArenaItem *item); +NRArenaItem *nr_arena_item_last_child (NRArenaItem *item); +void nr_arena_item_add_child (NRArenaItem *item, NRArenaItem *child, NRArenaItem *ref); +void nr_arena_item_remove_child (NRArenaItem *item, NRArenaItem *child); +void nr_arena_item_set_child_position (NRArenaItem *item, NRArenaItem *child, NRArenaItem *ref); + +/* + * Invoke update to given state, if item is inside area + * + * area == NULL is infinite + * gc is PARENT gc for invoke, CHILD gc in corresponding virtual method + * state - requested to state (bitwise or of requested flags) + * reset - reset to state (bitwise or of flags to reset) + */ + +unsigned int nr_arena_item_invoke_update (NRArenaItem *item, NRRectL *area, NRGC *gc, unsigned int state, unsigned int reset); + +unsigned int nr_arena_item_invoke_render(NRArenaItem *item, NRRectL const *area, NRPixBlock *pb, unsigned int flags); + +unsigned int nr_arena_item_invoke_clip (NRArenaItem *item, NRRectL *area, NRPixBlock *pb); +NRArenaItem *nr_arena_item_invoke_pick (NRArenaItem *item, NR::Point p, double delta, unsigned int sticky); + +void nr_arena_item_request_update (NRArenaItem *item, unsigned int reset, unsigned int propagate); +void nr_arena_item_request_render (NRArenaItem *item); + +/* Public */ + +NRArenaItem *nr_arena_item_unparent (NRArenaItem *item); + +void nr_arena_item_append_child (NRArenaItem *parent, NRArenaItem *child); + +void nr_arena_item_set_transform(NRArenaItem *item, NR::Matrix const &transform); +void nr_arena_item_set_transform(NRArenaItem *item, NRMatrix const *transform); +void nr_arena_item_set_opacity (NRArenaItem *item, double opacity); +void nr_arena_item_set_sensitive (NRArenaItem *item, unsigned int sensitive); +void nr_arena_item_set_visible (NRArenaItem *item, unsigned int visible); +void nr_arena_item_set_clip (NRArenaItem *item, NRArenaItem *clip); +void nr_arena_item_set_mask (NRArenaItem *item, NRArenaItem *mask); +void nr_arena_item_set_order (NRArenaItem *item, int order); + +/* Helpers */ + +NRArenaItem *nr_arena_item_attach_ref (NRArenaItem *parent, NRArenaItem *child, NRArenaItem *prev, NRArenaItem *next); +NRArenaItem *nr_arena_item_detach_unref (NRArenaItem *parent, NRArenaItem *child); + +#define NR_ARENA_ITEM_SET_DATA(i,v) (((NRArenaItem *) (i))->data = (v)) +#define NR_ARENA_ITEM_GET_DATA(i) (((NRArenaItem *) (i))->data) + +#define NR_ARENA_ITEM_SET_KEY(i,k) (((NRArenaItem *) (i))->key = (k)) +#define NR_ARENA_ITEM_GET_KEY(i) (((NRArenaItem *) (i))->key) + +#endif diff --git a/src/display/nr-arena-shape.cpp b/src/display/nr-arena-shape.cpp new file mode 100644 index 000000000..4fd381ad4 --- /dev/null +++ b/src/display/nr-arena-shape.cpp @@ -0,0 +1,1298 @@ +#define __NR_ARENA_SHAPE_C__ + +/* + * RGBA display list system for inkscape + * + * Author: + * Lauris Kaplinski + * + * Copyright (C) 2001-2002 Lauris Kaplinski + * Copyright (C) 2001 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//int showRuns=0; +void nr_pixblock_render_shape_mask_or (NRPixBlock &m,Shape* theS); + +static void nr_arena_shape_class_init (NRArenaShapeClass *klass); +static void nr_arena_shape_init (NRArenaShape *shape); +static void nr_arena_shape_finalize (NRObject *object); + +static NRArenaItem *nr_arena_shape_children (NRArenaItem *item); +static void nr_arena_shape_add_child (NRArenaItem *item, NRArenaItem *child, NRArenaItem *ref); +static void nr_arena_shape_remove_child (NRArenaItem *item, NRArenaItem *child); +static void nr_arena_shape_set_child_position (NRArenaItem *item, NRArenaItem *child, NRArenaItem *ref); + +static guint nr_arena_shape_update (NRArenaItem *item, NRRectL *area, NRGC *gc, guint state, guint reset); +static unsigned int nr_arena_shape_render (NRArenaItem *item, NRRectL *area, NRPixBlock *pb, unsigned int flags); +static guint nr_arena_shape_clip (NRArenaItem *item, NRRectL *area, NRPixBlock *pb); +static NRArenaItem *nr_arena_shape_pick (NRArenaItem *item, NR::Point p, double delta, unsigned int sticky); + +static NRArenaItemClass *shape_parent_class; + +NRType +nr_arena_shape_get_type (void) +{ + static NRType type = 0; + if (!type) { + type = nr_object_register_type (NR_TYPE_ARENA_ITEM, + "NRArenaShape", + sizeof (NRArenaShapeClass), + sizeof (NRArenaShape), + (void (*) (NRObjectClass *)) nr_arena_shape_class_init, + (void (*) (NRObject *)) nr_arena_shape_init); + } + return type; +} + +static void +nr_arena_shape_class_init (NRArenaShapeClass *klass) +{ + NRObjectClass *object_class; + NRArenaItemClass *item_class; + + object_class = (NRObjectClass *) klass; + item_class = (NRArenaItemClass *) klass; + + shape_parent_class = (NRArenaItemClass *) ((NRObjectClass *) klass)->parent; + + object_class->finalize = nr_arena_shape_finalize; + object_class->cpp_ctor = NRObject::invoke_ctor; + + item_class->children = nr_arena_shape_children; + item_class->add_child = nr_arena_shape_add_child; + item_class->set_child_position = nr_arena_shape_set_child_position; + item_class->remove_child = nr_arena_shape_remove_child; + item_class->update = nr_arena_shape_update; + item_class->render = nr_arena_shape_render; + item_class->clip = nr_arena_shape_clip; + item_class->pick = nr_arena_shape_pick; +} + +static void +nr_arena_shape_init (NRArenaShape *shape) +{ + shape->curve = NULL; + shape->style = NULL; + shape->paintbox.x0 = shape->paintbox.y0 = 0.0F; + shape->paintbox.x1 = shape->paintbox.y1 = 256.0F; + + nr_matrix_set_identity (&shape->ctm); + shape->fill_painter = NULL; + shape->stroke_painter = NULL; + shape->cached_fill = NULL; + shape->cached_stroke = NULL; + shape->fill_shp = NULL; + shape->stroke_shp = NULL; + + shape->delayed_shp = false; + + shape->approx_bbox.x0 = shape->approx_bbox.y0 = 0; + shape->approx_bbox.x1 = shape->approx_bbox.y1 = 0; + nr_matrix_set_identity(&shape->cached_fctm); + nr_matrix_set_identity(&shape->cached_sctm); + + shape->markers = NULL; +} + +static void +nr_arena_shape_finalize (NRObject *object) +{ + NRArenaShape *shape = (NRArenaShape *) (object); + + if (shape->fill_shp) delete shape->fill_shp; + if (shape->stroke_shp) delete shape->stroke_shp; + if (shape->cached_fill) delete shape->cached_fill; + if (shape->cached_stroke) delete shape->cached_stroke; + if (shape->fill_painter) sp_painter_free (shape->fill_painter); + if (shape->stroke_painter) sp_painter_free (shape->stroke_painter); + + if (shape->style) sp_style_unref (shape->style); + if (shape->curve) sp_curve_unref (shape->curve); + + ((NRObjectClass *) shape_parent_class)->finalize (object); +} + +static NRArenaItem * +nr_arena_shape_children (NRArenaItem *item) +{ + NRArenaShape *shape = (NRArenaShape *) item; + + return shape->markers; +} + +static void +nr_arena_shape_add_child (NRArenaItem *item, NRArenaItem *child, NRArenaItem *ref) +{ + NRArenaShape *shape = (NRArenaShape *) item; + + if (!ref) { + shape->markers = nr_arena_item_attach_ref (item, child, NULL, shape->markers); + } else { + ref->next = nr_arena_item_attach_ref (item, child, ref, ref->next); + } + + nr_arena_item_request_update (item, NR_ARENA_ITEM_STATE_ALL, FALSE); +} + +static void +nr_arena_shape_remove_child (NRArenaItem *item, NRArenaItem *child) +{ + NRArenaShape *shape = (NRArenaShape *) item; + + if (child->prev) { + nr_arena_item_detach_unref (item, child); + } else { + shape->markers = nr_arena_item_detach_unref (item, child); + } + + nr_arena_item_request_update (item, NR_ARENA_ITEM_STATE_ALL, FALSE); +} + +static void +nr_arena_shape_set_child_position (NRArenaItem *item, NRArenaItem *child, NRArenaItem *ref) +{ + NRArenaShape *shape = (NRArenaShape *) item; + + if (child->prev) { + nr_arena_item_detach_unref (item, child); + } else { + shape->markers = nr_arena_item_detach_unref (item, child); + } + + if (!ref) { + shape->markers = nr_arena_item_attach_ref (item, child, NULL, shape->markers); + } else { + ref->next = nr_arena_item_attach_ref (item, child, ref, ref->next); + } + + nr_arena_item_request_render (child); +} + +void nr_arena_shape_update_stroke(NRArenaShape *shape,NRGC* gc); +void nr_arena_shape_update_fill(NRArenaShape *shape,NRGC *gc); +void nr_arena_shape_add_bboxes(NRArenaShape* shape,NRRect &bbox); + +static guint +nr_arena_shape_update (NRArenaItem *item, NRRectL *area, NRGC *gc, guint state, guint reset) +{ + NRRect bbox; + + NRArenaShape *shape = NR_ARENA_SHAPE (item); + + unsigned int beststate = NR_ARENA_ITEM_STATE_ALL; + + unsigned int newstate; + for (NRArenaItem *child = shape->markers; child != NULL; child = child->next) { + newstate = nr_arena_item_invoke_update (child, area, gc, state, reset); + beststate = beststate & newstate; + } + + if (!(state & NR_ARENA_ITEM_STATE_RENDER)) { + /* We do not have to create rendering structures */ + shape->ctm = gc->transform; + if (state & NR_ARENA_ITEM_STATE_BBOX) { + if (shape->curve) { + NRBPath bp; + /* fixme: */ + bbox.x0 = bbox.y0 = NR_HUGE; + bbox.x1 = bbox.y1 = -NR_HUGE; + bp.path = shape->curve->bpath; + nr_path_matrix_bbox_union(&bp, gc->transform, &bbox); + item->bbox.x0 = (gint32)(bbox.x0 - 1.0F); + item->bbox.y0 = (gint32)(bbox.y0 - 1.0F); + item->bbox.x1 = (gint32)(bbox.x1 + 1.9999F); + item->bbox.y1 = (gint32)(bbox.y1 + 1.9999F); + } + if (beststate & NR_ARENA_ITEM_STATE_BBOX) { + for (NRArenaItem *child = shape->markers; child != NULL; child = child->next) { + nr_rect_l_union (&item->bbox, &item->bbox, &child->bbox); + } + } + } + return (state | item->state); + } + + shape->delayed_shp=true; + shape->ctm = gc->transform; + bbox.x0 = bbox.y0 = NR_HUGE; + bbox.x1 = bbox.y1 = -NR_HUGE; + + if (shape->curve) { + NRBPath bp; + /* fixme: */ + bbox.x0 = bbox.y0 = NR_HUGE; + bbox.x1 = bbox.y1 = -NR_HUGE; + bp.path = shape->curve->bpath; + nr_path_matrix_bbox_union(&bp, gc->transform, &bbox); + if (shape->_stroke.paint.type() != NRArenaShape::Paint::NONE) { + float width, scale; + scale = NR_MATRIX_DF_EXPANSION (&gc->transform); + width = MAX (0.125, shape->_stroke.width * scale); + if ( fabs(shape->_stroke.width * scale) > 0.01 ) { // sinon c'est 0=oon veut pas de bord + bbox.x0-=width; + bbox.x1+=width; + bbox.y0-=width; + bbox.y1+=width; + } + // those pesky miters, now + float miterMax=width*shape->_stroke.mitre_limit; + if ( miterMax > 0.01 ) { + // grunt mode. we should compute the various miters instead (one for each point on the curve) + bbox.x0-=miterMax; + bbox.x1+=miterMax; + bbox.y0-=miterMax; + bbox.y1+=miterMax; + } + } + } else { + } + shape->approx_bbox.x0 = (gint32)(bbox.x0 - 1.0F); + shape->approx_bbox.y0 = (gint32)(bbox.y0 - 1.0F); + shape->approx_bbox.x1 = (gint32)(bbox.x1 + 1.9999F); + shape->approx_bbox.y1 = (gint32)(bbox.y1 + 1.9999F); + if ( area && nr_rect_l_test_intersect (area, &shape->approx_bbox) ) shape->delayed_shp=false; + + /* Release state data */ + if (TRUE || !nr_matrix_test_transform_equal (&gc->transform, &shape->ctm, NR_EPSILON)) { + /* Concept test */ + if (shape->fill_shp) { + delete shape->fill_shp; + shape->fill_shp = NULL; + } + } + if (shape->stroke_shp) { + delete shape->stroke_shp; + shape->stroke_shp = NULL; + } + if (shape->fill_painter) { + sp_painter_free (shape->fill_painter); + shape->fill_painter = NULL; + } + if (shape->stroke_painter) { + sp_painter_free (shape->stroke_painter); + shape->stroke_painter = NULL; + } + + if (!shape->curve || !shape->style) return NR_ARENA_ITEM_STATE_ALL; + if (sp_curve_is_empty (shape->curve)) return NR_ARENA_ITEM_STATE_ALL; + if ( ( shape->_fill.paint.type() == NRArenaShape::Paint::NONE ) && + ( shape->_stroke.paint.type() == NRArenaShape::Paint::NONE ) ) + { + return NR_ARENA_ITEM_STATE_ALL; + } + + /* Build state data */ + if ( shape->delayed_shp ) { + item->bbox=shape->approx_bbox; + } else { + nr_arena_shape_update_stroke(shape,gc); + nr_arena_shape_update_fill(shape,gc); + + bbox.x0 = bbox.y0 = bbox.x1 = bbox.y1 = 0.0; + nr_arena_shape_add_bboxes(shape,bbox); + + shape->approx_bbox.x0 = (gint32)(bbox.x0 - 1.0F); + shape->approx_bbox.y0 = (gint32)(bbox.y0 - 1.0F); + shape->approx_bbox.x1 = (gint32)(bbox.x1 + 1.9999F); + shape->approx_bbox.y1 = (gint32)(bbox.y1 + 1.9999F); + } + + if (nr_rect_d_test_empty (&bbox)) return NR_ARENA_ITEM_STATE_ALL; + + item->bbox.x0 = (gint32)(bbox.x0 - 1.0F); + item->bbox.y0 = (gint32)(bbox.y0 - 1.0F); + item->bbox.x1 = (gint32)(bbox.x1 + 1.0F); + item->bbox.y1 = (gint32)(bbox.y1 + 1.0F); + nr_arena_request_render_rect (item->arena, &item->bbox); + + item->render_opacity = TRUE; + if ( shape->_fill.paint.type() == NRArenaShape::Paint::SERVER ) { + if (gc && gc->parent) { + shape->fill_painter = sp_paint_server_painter_new (shape->_fill.paint.server(), + NR::Matrix (&gc->transform), NR::Matrix (&gc->parent->transform), + &shape->paintbox); + } + item->render_opacity = FALSE; + } + if ( shape->_stroke.paint.type() == NRArenaShape::Paint::SERVER ) { + if (gc && gc->parent) { + shape->stroke_painter = sp_paint_server_painter_new (shape->_stroke.paint.server(), + NR::Matrix (&gc->transform), NR::Matrix (&gc->parent->transform), + &shape->paintbox); + } + item->render_opacity = FALSE; + } + if ( item->render_opacity == TRUE && + shape->_fill.paint.type() != NRArenaShape::Paint::NONE && + shape->_stroke.paint.type() != NRArenaShape::Paint::NONE ) + { + // don't merge item opacity with paint opacity if there is a stroke on the fill + item->render_opacity = FALSE; + } + + if (beststate & NR_ARENA_ITEM_STATE_BBOX) { + for (NRArenaItem *child = shape->markers; child != NULL; child = child->next) { + nr_rect_l_union (&item->bbox, &item->bbox, &child->bbox); + } + } + + return NR_ARENA_ITEM_STATE_ALL; +} + +int matrix_is_isometry(NR::Matrix p) { + NR::Matrix tp; + // transposition + tp[0]=p[0]; + tp[1]=p[2]; + tp[2]=p[1]; + tp[3]=p[3]; + for(int i = 4; i < 6; i++) // shut valgrind up :) + tp[i] = p[i] = 0; + NR::Matrix isom = tp*p; // A^T * A = adjunct? + // Is the adjunct nearly an identity function? + if (isom.is_translation(0.01)) { + // the transformation is an isometry -> no need to recompute + // the uncrossed polygon + if ( p.det() < 0 ) + return -1; + else + return 1; + } + return 0; +} + +void +nr_arena_shape_update_fill(NRArenaShape *shape,NRGC *gc) +{ + shape->delayed_shp = false; + if ((shape->_fill.paint.type() != NRArenaShape::Paint::NONE) && + ((shape->curve->end > 2) || (shape->curve->bpath[1].code == NR_CURVETO)) ) { + if (TRUE || !shape->fill_shp) { + NR::Matrix cached_to_new; + int isometry = 0; + if ( shape->cached_fill ) { + cached_to_new = shape->cached_fctm.inverse()*gc->transform; + isometry = matrix_is_isometry(cached_to_new); + } + if ( isometry == 0 ) { + if ( shape->cached_fill == NULL ) shape->cached_fill=new Shape; + shape->cached_fill->Reset(); + + Path* thePath=new Path; + Shape* theShape=new Shape; + { + NR::Matrix tempMat(gc->transform); + thePath->LoadArtBPath(shape->curve->bpath,tempMat,true); + } + + thePath->Convert(1.0); + + thePath->Fill(theShape, 0); + + if ( shape->_fill.rule == NRArenaShape::EVEN_ODD ) { + shape->cached_fill->ConvertToShape(theShape, fill_oddEven); + // alternatively, this speeds up rendering of oddeven shapes but disables AA :( + //shape->cached_fill->Copy(theShape); + } else { + shape->cached_fill->ConvertToShape(theShape, fill_nonZero); + } + shape->cached_fctm=gc->transform; + delete theShape; + delete thePath; + if ( shape->fill_shp == NULL ) + shape->fill_shp = new Shape; + + shape->fill_shp->Copy(shape->cached_fill); + + } else { + + if ( shape->fill_shp == NULL ) + shape->fill_shp=new Shape; + shape->fill_shp->Reset(shape->cached_fill->numberOfPoints(), + shape->cached_fill->numberOfEdges()); + for (int i = 0; i < shape->cached_fill->numberOfPoints(); i++) + shape->fill_shp->AddPoint(shape->cached_fill->getPoint(i).x * cached_to_new); + if ( isometry == 1 ) { + for (int i = 0; i < shape->cached_fill->numberOfEdges(); i++) + shape->fill_shp->AddEdge(shape->cached_fill->getEdge(i).st, + shape->cached_fill->getEdge(i).en); + } else if ( isometry == -1 ) { // need to flip poly. + for (int i = 0; i < shape->cached_fill->numberOfEdges(); i++) + shape->fill_shp->AddEdge(shape->cached_fill->getEdge(i).en, + shape->cached_fill->getEdge(i).st); + } + shape->fill_shp->ForceToPolygon(); + shape->fill_shp->needPointsSorting(); + shape->fill_shp->needEdgesSorting(); + } + } + } +} + +void +nr_arena_shape_update_stroke(NRArenaShape *shape,NRGC* gc) +{ + SPStyle* style = shape->style; + + shape->delayed_shp = false; + + const float scale = NR_MATRIX_DF_EXPANSION (&gc->transform); + + if (NR_ARENA_ITEM(shape)->arena->rendermode == RENDERMODE_OUTLINE || + ((shape->_stroke.paint.type() != NRArenaShape::Paint::NONE) && + ( fabs(shape->_stroke.width * scale) > 0.01 ))) { // sinon c'est 0=oon veut pas de bord + + float width = MAX (0.125, shape->_stroke.width * scale); + if (NR_ARENA_ITEM(shape)->arena->rendermode == RENDERMODE_OUTLINE) + width = 0.5; // 1 pixel wide, independent of zoom + + NR::Matrix cached_to_new; + + int isometry = 0; + if ( shape->cached_stroke ) { + cached_to_new = shape->cached_sctm.inverse() * gc->transform; + isometry = matrix_is_isometry(cached_to_new); + } + + if ( isometry == 0 ) { + if ( shape->cached_stroke == NULL ) shape->cached_stroke=new Shape; + shape->cached_stroke->Reset(); + Path* thePath = new Path; + Shape* theShape = new Shape; + { + NR::Matrix tempMat(gc->transform); + thePath->LoadArtBPath(shape->curve->bpath, tempMat, true); + } + + if (NR_ARENA_ITEM(shape)->arena->rendermode != RENDERMODE_OUTLINE) + thePath->Convert(1.0); + else + thePath->Convert(4.0); // slightly rougher & faster + + if (style->stroke_dash.n_dash && NR_ARENA_ITEM(shape)->arena->rendermode != RENDERMODE_OUTLINE) { + double dlen = 0.0; + for (int i = 0; i < style->stroke_dash.n_dash; i++) { + dlen += style->stroke_dash.dash[i] * scale; + } + if (dlen >= 1.0) { + NRVpathDash dash; + dash.offset = style->stroke_dash.offset * scale; + dash.n_dash = style->stroke_dash.n_dash; + dash.dash = g_new (double, dash.n_dash); + for (int i = 0; i < dash.n_dash; i++) { + dash.dash[i] = style->stroke_dash.dash[i] * scale; + } + int nbD=dash.n_dash; + float *dashs=(float*)malloc((nbD+1)*sizeof(float)); + while ( dash.offset >= dlen ) dash.offset-=dlen; + dashs[0]=dash.dash[0]; + for (int i=1; iDashPolyline(0.0,0.0,dlen,nbD,dashs,true,dash.offset); + free(dashs); + g_free (dash.dash); + } + } + ButtType butt=butt_straight; + switch(shape->_stroke.cap) { + case NRArenaShape::BUTT_CAP: + butt = butt_straight; + break; + case NRArenaShape::ROUND_CAP: + butt = butt_round; + break; + case NRArenaShape::SQUARE_CAP: + butt = butt_square; + break; + } + JoinType join=join_straight; + switch(shape->_stroke.join) { + case NRArenaShape::MITRE_JOIN: + join = join_pointy; + break; + case NRArenaShape::ROUND_JOIN: + join = join_round; + break; + case NRArenaShape::BEVEL_JOIN: + join = join_straight; + break; + } + + if (NR_ARENA_ITEM(shape)->arena->rendermode == RENDERMODE_OUTLINE) { + butt = butt_straight; + join = join_straight; + } + + thePath->Stroke(theShape, false, 0.5*width, join, butt, + 0.5*width*shape->_stroke.mitre_limit); + + + if (NR_ARENA_ITEM(shape)->arena->rendermode == RENDERMODE_OUTLINE) { + // speeds it up, but uses evenodd for the stroke shape (which does not matter for 1-pixel wide outline) + shape->cached_stroke->Copy(theShape); + } else { + shape->cached_stroke->ConvertToShape(theShape, fill_nonZero); + } + + shape->cached_sctm=gc->transform; + delete thePath; + delete theShape; + if ( shape->stroke_shp == NULL ) shape->stroke_shp=new Shape; + + shape->stroke_shp->Copy(shape->cached_stroke); + + } else { + + if ( shape->stroke_shp == NULL ) + shape->stroke_shp=new Shape; + shape->stroke_shp->Reset(shape->cached_stroke->numberOfPoints(), shape->cached_stroke->numberOfEdges()); + for (int i = 0; i < shape->cached_stroke->numberOfPoints(); i++) + shape->stroke_shp->AddPoint(shape->cached_stroke->getPoint(i).x * cached_to_new); + if ( isometry == 1 ) { + for (int i = 0; i < shape->cached_stroke->numberOfEdges(); i++) + shape->stroke_shp->AddEdge(shape->cached_stroke->getEdge(i).st, + shape->cached_stroke->getEdge(i).en); + } else if ( isometry == -1 ) { + for (int i = 0; i < shape->cached_stroke->numberOfEdges(); i++) + shape->stroke_shp->AddEdge(shape->cached_stroke->getEdge(i).en, + shape->cached_stroke->getEdge(i).st); + } + shape->stroke_shp->ForceToPolygon(); + shape->stroke_shp->needPointsSorting(); + shape->stroke_shp->needEdgesSorting(); + } + } +} + + +void +nr_arena_shape_add_bboxes(NRArenaShape* shape, NRRect &bbox) +{ + if ( shape->stroke_shp ) { + shape->stroke_shp->CalcBBox(); + shape->stroke_shp->leftX=floor(shape->stroke_shp->leftX); + shape->stroke_shp->rightX=ceil(shape->stroke_shp->rightX); + shape->stroke_shp->topY=floor(shape->stroke_shp->topY); + shape->stroke_shp->bottomY=ceil(shape->stroke_shp->bottomY); + if ( bbox.x0 >= bbox.x1 ) { + if ( shape->stroke_shp->leftX < shape->stroke_shp->rightX ) { + bbox.x0=shape->stroke_shp->leftX; + bbox.x1=shape->stroke_shp->rightX; + } + } else { + if ( shape->stroke_shp->leftX < bbox.x0 ) + bbox.x0=shape->stroke_shp->leftX; + if ( shape->stroke_shp->rightX > bbox.x1 ) + bbox.x1=shape->stroke_shp->rightX; + } + if ( bbox.y0 >= bbox.y1 ) { + if ( shape->stroke_shp->topY < shape->stroke_shp->bottomY ) { + bbox.y0=shape->stroke_shp->topY; + bbox.y1=shape->stroke_shp->bottomY; + } + } else { + if ( shape->stroke_shp->topY < bbox.y0 ) + bbox.y0=shape->stroke_shp->topY; + if ( shape->stroke_shp->bottomY > bbox.y1 ) + bbox.y1=shape->stroke_shp->bottomY; + } + } + if ( shape->fill_shp ) { + shape->fill_shp->CalcBBox(); + shape->fill_shp->leftX=floor(shape->fill_shp->leftX); + shape->fill_shp->rightX=ceil(shape->fill_shp->rightX); + shape->fill_shp->topY=floor(shape->fill_shp->topY); + shape->fill_shp->bottomY=ceil(shape->fill_shp->bottomY); + if ( bbox.x0 >= bbox.x1 ) { + if ( shape->fill_shp->leftX < shape->fill_shp->rightX ) { + bbox.x0=shape->fill_shp->leftX; + bbox.x1=shape->fill_shp->rightX; + } + } else { + if ( shape->fill_shp->leftX < bbox.x0 ) bbox.x0=shape->fill_shp->leftX; + if ( shape->fill_shp->rightX > bbox.x1 ) bbox.x1=shape->fill_shp->rightX; + } + if ( bbox.y0 >= bbox.y1 ) { + if ( shape->fill_shp->topY < shape->fill_shp->bottomY ) { + bbox.y0=shape->fill_shp->topY; + bbox.y1=shape->fill_shp->bottomY; + } + } else { + if ( shape->fill_shp->topY < bbox.y0 ) bbox.y0=shape->fill_shp->topY; + if ( shape->fill_shp->bottomY > bbox.y1 ) bbox.y1=shape->fill_shp->bottomY; + } + } +} +static unsigned int +nr_arena_shape_render (NRArenaItem *item, NRRectL *area, NRPixBlock *pb, unsigned int flags) +{ + NRArenaShape *shape = NR_ARENA_SHAPE (item); + + if (!shape->curve) return item->state; + if (!shape->style) return item->state; + + if ( shape->delayed_shp ) { + if ( nr_rect_l_test_intersect (area, &item->bbox) ) { + NRGC tempGC(NULL); + tempGC.transform=shape->ctm; + nr_arena_shape_update_stroke(shape,&tempGC); + nr_arena_shape_update_fill(shape,&tempGC); +/* NRRect bbox; + bbox.x0 = bbox.y0 = bbox.x1 = bbox.y1 = 0.0; + nr_arena_shape_add_bboxes(shape,bbox); + item->bbox.x0 = (gint32)(bbox.x0 - 1.0F); + item->bbox.y0 = (gint32)(bbox.y0 - 1.0F); + item->bbox.x1 = (gint32)(bbox.x1 + 1.0F); + item->bbox.y1 = (gint32)(bbox.y1 + 1.0F); + shape->approx_bbox=item->bbox;*/ + } + } + + SPStyle const *style = shape->style; + if ( shape->fill_shp && NR_ARENA_ITEM(shape)->arena->rendermode != RENDERMODE_OUTLINE) { + NRPixBlock m; + guint32 rgba; + + nr_pixblock_setup_fast (&m, NR_PIXBLOCK_MODE_A8, area->x0, area->y0, area->x1, area->y1, TRUE); + nr_pixblock_render_shape_mask_or (m,shape->fill_shp); + m.empty = FALSE; + + if (shape->_fill.paint.type() == NRArenaShape::Paint::NONE) { + // do not render fill in any way + } else if (shape->_fill.paint.type() == NRArenaShape::Paint::COLOR) { + if ( item->render_opacity ) { + rgba = sp_color_get_rgba32_falpha (&shape->_fill.paint.color(), + shape->_fill.opacity * + SP_SCALE24_TO_FLOAT (style->opacity.value)); + } else { + rgba = sp_color_get_rgba32_falpha (&shape->_fill.paint.color(), + shape->_fill.opacity); + } + nr_blit_pixblock_mask_rgba32 (pb, &m, rgba); + pb->empty = FALSE; + } else if (shape->_fill.paint.type() == NRArenaShape::Paint::SERVER) { + if (shape->fill_painter) { + nr_arena_render_paintserver_fill (pb, area, shape->fill_painter, shape->_fill.opacity, &m); + } + } + + nr_pixblock_release (&m); + } + + if ( shape->stroke_shp ) { + NRPixBlock m; + guint32 rgba; + + nr_pixblock_setup_fast (&m, NR_PIXBLOCK_MODE_A8, area->x0, area->y0, area->x1, area->y1, TRUE); + nr_pixblock_render_shape_mask_or (m, shape->stroke_shp); + m.empty = FALSE; + + if (shape->_stroke.paint.type() == NRArenaShape::Paint::COLOR || + NR_ARENA_ITEM(shape)->arena->rendermode == RENDERMODE_OUTLINE) { + if ( NR_ARENA_ITEM(shape)->arena->rendermode == RENDERMODE_OUTLINE) { + rgba = NR_ARENA_ITEM(shape)->arena->outlinecolor; + } else if ( item->render_opacity ) { + rgba = sp_color_get_rgba32_falpha (&shape->_stroke.paint.color(), + shape->_stroke.opacity * + SP_SCALE24_TO_FLOAT (style->opacity.value)); + } else { + rgba = sp_color_get_rgba32_falpha (&shape->_stroke.paint.color(), + shape->_stroke.opacity); + } + nr_blit_pixblock_mask_rgba32 (pb, &m, rgba); + pb->empty = FALSE; + } else if (shape->_stroke.paint.type() == NRArenaShape::Paint::SERVER) { + if (shape->stroke_painter) { + nr_arena_render_paintserver_fill (pb, area, shape->stroke_painter, shape->_stroke.opacity, &m); + } + } + + nr_pixblock_release (&m); + } + + /* Just compose children into parent buffer */ + for (NRArenaItem *child = shape->markers; child != NULL; child = child->next) { + unsigned int ret; + ret = nr_arena_item_invoke_render (child, area, pb, flags); + if (ret & NR_ARENA_ITEM_STATE_INVALID) return ret; + } + + return item->state; +} + +static guint +nr_arena_shape_clip (NRArenaItem *item, NRRectL *area, NRPixBlock *pb) +{ + NRArenaShape *shape = NR_ARENA_SHAPE (item); + + if (!shape->curve) return item->state; + + if ( shape->delayed_shp ) { + if ( nr_rect_l_test_intersect (area, &item->bbox) ) { + NRGC tempGC(NULL); + tempGC.transform=shape->ctm; + nr_arena_shape_update_stroke(shape,&tempGC); + nr_arena_shape_update_fill(shape,&tempGC); + /* NRRect bbox; + bbox.x0 = bbox.y0 = bbox.x1 = bbox.y1 = 0.0; + nr_arena_shape_add_bboxes(shape,bbox); + item->bbox.x0 = (gint32)(bbox.x0 - 1.0F); + item->bbox.y0 = (gint32)(bbox.y0 - 1.0F); + item->bbox.x1 = (gint32)(bbox.x1 + 1.0F); + item->bbox.y1 = (gint32)(bbox.y1 + 1.0F); + shape->approx_bbox=item->bbox;*/ + } + } + + if ( shape->fill_shp ) { + NRPixBlock m; + + /* fixme: We can OR in one step (Lauris) */ + nr_pixblock_setup_fast (&m, NR_PIXBLOCK_MODE_A8, area->x0, area->y0, area->x1, area->y1, TRUE); + nr_pixblock_render_shape_mask_or (m,shape->fill_shp); + + for (int y = area->y0; y < area->y1; y++) { + unsigned char *s, *d; + s = NR_PIXBLOCK_PX (&m) + (y - area->y0) * m.rs; + d = NR_PIXBLOCK_PX (pb) + (y - area->y0) * pb->rs; + for (int x = area->x0; x < area->x1; x++) { + *d = NR_A7_NORMALIZED(*s,*d); + d ++; + s ++; + } + } + nr_pixblock_release (&m); + pb->empty = FALSE; + } + + return item->state; +} + +static NRArenaItem * +nr_arena_shape_pick (NRArenaItem *item, NR::Point p, double delta, unsigned int /*sticky*/) +{ + NRArenaShape *shape = NR_ARENA_SHAPE (item); + + if (!shape->curve) return NULL; + if (!shape->style) return NULL; + if ( shape->delayed_shp ) { + NRRectL area; + area.x0=(int)floor(p[NR::X]); + area.x1=(int)ceil(p[NR::X]); + area.y0=(int)floor(p[NR::Y]); + area.y1=(int)ceil(p[NR::Y]); + int idelta = (int)ceil(delta) + 1; + // njh: inset rect + area.x0-=idelta; + area.x1+=idelta; + area.y0-=idelta; + area.y1+=idelta; + if ( nr_rect_l_test_intersect (&area, &item->bbox) ) { + NRGC tempGC(NULL); + tempGC.transform=shape->ctm; + nr_arena_shape_update_stroke(shape,&tempGC); + nr_arena_shape_update_fill(shape,&tempGC); + /* NRRect bbox; + bbox.x0 = bbox.y0 = bbox.x1 = bbox.y1 = 0.0; + nr_arena_shape_add_bboxes(shape,bbox); + item->bbox.x0 = (gint32)(bbox.x0 - 1.0F); + item->bbox.y0 = (gint32)(bbox.y0 - 1.0F); + item->bbox.x1 = (gint32)(bbox.x1 + 1.0F); + item->bbox.y1 = (gint32)(bbox.y1 + 1.0F); + shape->approx_bbox=item->bbox;*/ + } + } + + if (item->state & NR_ARENA_ITEM_STATE_RENDER) { + if (shape->fill_shp && (shape->_fill.paint.type() != NRArenaShape::Paint::NONE)) { + if (shape->fill_shp->PtWinding(p) > 0 ) return item; + } + if (shape->stroke_shp && (shape->_stroke.paint.type() != NRArenaShape::Paint::NONE)) { + if (shape->stroke_shp->PtWinding(p) > 0 ) return item; + } + if (delta > 1e-3) { + if (shape->fill_shp && (shape->_fill.paint.type() != NRArenaShape::Paint::NONE)) { + if (distanceLessThanOrEqual(shape->fill_shp, p, delta)) return item; + } + if (shape->stroke_shp && (shape->_stroke.paint.type() != NRArenaShape::Paint::NONE)) { + if (distanceLessThanOrEqual(shape->stroke_shp, p, delta)) return item; + } + } + } else { + NRBPath bp; + bp.path = shape->curve->bpath; + double dist = NR_HUGE; + int wind = 0; + nr_path_matrix_point_bbox_wind_distance(&bp, shape->ctm, p, NULL, &wind, &dist, NR_EPSILON); + if (shape->_fill.paint.type() != NRArenaShape::Paint::NONE) { + if (!shape->style->fill_rule.computed) { + if (wind != 0) return item; + } else { + if (wind & 0x1) return item; + } + } + if (shape->_stroke.paint.type() != NRArenaShape::Paint::NONE) { + /* fixme: We do not take stroke width into account here (Lauris) */ + if (dist < delta) return item; + } + } + + return NULL; +} + +/** + * + * Requests a render of the shape, then if the shape is already a curve it + * unrefs the old curve; if the new curve is valid it creates a copy of the + * curve and adds it to the shape. Finally, it requests an update of the + * arena for the shape. + */ +void nr_arena_shape_set_path(NRArenaShape *shape, SPCurve *curve,bool justTrans) +{ + g_return_if_fail (shape != NULL); + g_return_if_fail (NR_IS_ARENA_SHAPE (shape)); + + if ( justTrans == false ) { + // dirty cached versions + if ( shape->cached_fill ) { + delete shape->cached_fill; + shape->cached_fill=NULL; + } + if ( shape->cached_stroke ) { + delete shape->cached_stroke; + shape->cached_stroke=NULL; + } + } + + nr_arena_item_request_render (NR_ARENA_ITEM (shape)); + + if (shape->curve) { + sp_curve_unref (shape->curve); + shape->curve = NULL; + } + + if (curve) { + shape->curve = curve; + sp_curve_ref (curve); + } + + nr_arena_item_request_update (NR_ARENA_ITEM (shape), NR_ARENA_ITEM_STATE_ALL, FALSE); +} + +void NRArenaShape::setFill(SPPaintServer *server) { + _fill.paint.set(server); + _invalidateCachedFill(); +} + +void NRArenaShape::setFill(SPColor const &color) { + _fill.paint.set(color); + _invalidateCachedFill(); +} + +void NRArenaShape::setFillOpacity(double opacity) { + _fill.opacity = opacity; + _invalidateCachedFill(); +} + +void NRArenaShape::setFillRule(NRArenaShape::FillRule rule) { + _fill.rule = rule; + _invalidateCachedFill(); +} + +void NRArenaShape::setStroke(SPPaintServer *server) { + _stroke.paint.set(server); + _invalidateCachedStroke(); +} + +void NRArenaShape::setStroke(SPColor const &color) { + _stroke.paint.set(color); + _invalidateCachedStroke(); +} + +void NRArenaShape::setStrokeOpacity(double opacity) { + _stroke.opacity = opacity; + _invalidateCachedStroke(); +} + +void NRArenaShape::setStrokeWidth(double width) { + _stroke.width = width; + _invalidateCachedStroke(); +} + +void NRArenaShape::setMitreLimit(double limit) { + _stroke.mitre_limit = limit; + _invalidateCachedStroke(); +} + +void NRArenaShape::setLineCap(NRArenaShape::CapType cap) { + _stroke.cap = cap; + _invalidateCachedStroke(); +} + +void NRArenaShape::setLineJoin(NRArenaShape::JoinType join) { + _stroke.join = join; + _invalidateCachedStroke(); +} + +/** nr_arena_shape_set_style + * + * Unrefs any existing style and ref's to the given one, then requests an update of the arena + */ +void +nr_arena_shape_set_style (NRArenaShape *shape, SPStyle *style) +{ + g_return_if_fail (shape != NULL); + g_return_if_fail (NR_IS_ARENA_SHAPE (shape)); + + if (style) sp_style_ref (style); + if (shape->style) sp_style_unref (shape->style); + shape->style = style; + + switch (style->fill.type) { + case SP_PAINT_TYPE_NONE: { + shape->setFill(NULL); + break; + } + case SP_PAINT_TYPE_COLOR: { + shape->setFill(style->fill.value.color); + break; + } + case SP_PAINT_TYPE_PAINTSERVER: { + shape->setFill(style->fill.value.paint.server); + break; + } + default: { + g_assert_not_reached(); + } + } + shape->setFillOpacity(SP_SCALE24_TO_FLOAT(style->fill_opacity.value)); + switch (style->fill_rule.computed) { + case SP_WIND_RULE_EVENODD: { + shape->setFillRule(NRArenaShape::EVEN_ODD); + break; + } + case SP_WIND_RULE_NONZERO: { + shape->setFillRule(NRArenaShape::NONZERO); + break; + } + default: { + g_assert_not_reached(); + } + } + + switch (style->stroke.type) { + case SP_PAINT_TYPE_NONE: { + shape->setStroke(NULL); + break; + } + case SP_PAINT_TYPE_COLOR: { + shape->setStroke(style->stroke.value.color); + break; + } + case SP_PAINT_TYPE_PAINTSERVER: { + shape->setStroke(style->stroke.value.paint.server); + break; + } + default: { + g_assert_not_reached(); + } + } + shape->setStrokeWidth(style->stroke_width.computed); + shape->setStrokeOpacity(SP_SCALE24_TO_FLOAT(style->stroke_opacity.value)); + switch (style->stroke_linecap.computed) { + case SP_STROKE_LINECAP_ROUND: { + shape->setLineCap(NRArenaShape::ROUND_CAP); + break; + } + case SP_STROKE_LINECAP_SQUARE: { + shape->setLineCap(NRArenaShape::SQUARE_CAP); + break; + } + case SP_STROKE_LINECAP_BUTT: { + shape->setLineCap(NRArenaShape::BUTT_CAP); + break; + } + default: { + g_assert_not_reached(); + } + } + switch (style->stroke_linejoin.computed) { + case SP_STROKE_LINEJOIN_ROUND: { + shape->setLineJoin(NRArenaShape::ROUND_JOIN); + break; + } + case SP_STROKE_LINEJOIN_BEVEL: { + shape->setLineJoin(NRArenaShape::BEVEL_JOIN); + break; + } + case SP_STROKE_LINEJOIN_MITER: { + shape->setLineJoin(NRArenaShape::MITRE_JOIN); + break; + } + default: { + g_assert_not_reached(); + } + } + shape->setMitreLimit(style->stroke_miterlimit.value); + + nr_arena_item_request_update(shape, NR_ARENA_ITEM_STATE_ALL, FALSE); +} + +void +nr_arena_shape_set_paintbox (NRArenaShape *shape, const NRRect *pbox) +{ + g_return_if_fail (shape != NULL); + g_return_if_fail (NR_IS_ARENA_SHAPE (shape)); + g_return_if_fail (pbox != NULL); + + if ((pbox->x0 < pbox->x1) && (pbox->y0 < pbox->y1)) { + shape->paintbox = *pbox; + } else { + /* fixme: We kill warning, although not sure what to do here (Lauris) */ + shape->paintbox.x0 = shape->paintbox.y0 = 0.0F; + shape->paintbox.x1 = shape->paintbox.y1 = 256.0F; + } + + nr_arena_item_request_update(shape, NR_ARENA_ITEM_STATE_ALL, FALSE); +} + +void NRArenaShape::setPaintBox(NR::Rect const &pbox) +{ + paintbox.x0 = pbox.min()[NR::X]; + paintbox.y0 = pbox.min()[NR::Y]; + paintbox.x1 = pbox.max()[NR::X]; + paintbox.y1 = pbox.max()[NR::Y]; + + nr_arena_item_request_update(this, NR_ARENA_ITEM_STATE_ALL, FALSE); +} + +static void +shape_run_A8_OR (raster_info &dest,void */*data*/,int st,float vst,int en,float ven) +{ + if ( st >= en ) return; + if ( vst < 0 ) vst=0; + if ( vst > 1 ) vst=1; + if ( ven < 0 ) ven=0; + if ( ven > 1 ) ven=1; + float sv=vst; + float dv=ven-vst; + int len=en-st; + unsigned char* d=(unsigned char*)dest.buffer; + d+=(st-dest.startPix); + if ( fabs(dv) < 0.001 ) { + if ( vst > 0.999 ) { + /* Simple copy */ + while (len > 0) { + d[0] = 255; + d += 1; + len -= 1; + } + } else { + sv*=256; + unsigned int c0_24=(int)sv; + c0_24&=0xFF; + while (len > 0) { + unsigned int da; + /* Draw */ + da = NR_A7(c0_24,d[0]); + d[0] = NR_PREMUL_SINGLE(da); + d += 1; + len -= 1; + } + } + } else { + if ( en <= st+1 ) { + sv=0.5*(vst+ven); + sv*=256; + unsigned int c0_24=(int)sv; + c0_24&=0xFF; + unsigned int da; + /* Draw */ + da = NR_A7(c0_24,d[0]); + d[0] = NR_PREMUL_SINGLE(da); + } else { + dv/=len; + sv+=0.5*dv; // correction trapezoidale + sv*=16777216; + dv*=16777216; + int c0_24 = static_cast(CLAMP(sv, 0, 16777216)); + int s0_24 = static_cast(dv); + while (len > 0) { + unsigned int ca, da; + /* Draw */ + ca = c0_24 >> 16; + if ( ca > 255 ) ca=255; + da = NR_A7(ca,d[0]); + d[0] = NR_PREMUL_SINGLE(da); + d += 1; + c0_24 += s0_24; + c0_24 = CLAMP (c0_24, 0, 16777216); + len -= 1; + } + } + } +} + +void nr_pixblock_render_shape_mask_or (NRPixBlock &m,Shape* theS) +{ + + theS->CalcBBox(); + float l=theS->leftX,r=theS->rightX,t=theS->topY,b=theS->bottomY; + int il,ir,it,ib; + il=(int)floor(l); + ir=(int)ceil(r); + it=(int)floor(t); + ib=(int)ceil(b); + + if ( il >= m.area.x1 || ir <= m.area.x0 || it >= m.area.y1 || ib <= m.area.y0 ) return; + if ( il < m.area.x0 ) il=m.area.x0; + if ( it < m.area.y0 ) it=m.area.y0; + if ( ir > m.area.x1 ) ir=m.area.x1; + if ( ib > m.area.y1 ) ib=m.area.y1; + + // version par FloatLigne + int curPt; + float curY; + theS->BeginQuickRaster(curY, curPt); + + FloatLigne* theI=new FloatLigne(); + IntLigne* theIL=new IntLigne(); + + theS->DirectQuickScan(curY,curPt,(float)(it),true,1.0); + + char* mdata=(char*)m.data.px; + if ( m.size == NR_PIXBLOCK_SIZE_TINY ) mdata=(char*)m.data.p; + uint32_t* ligStart=((uint32_t*)(mdata+((il-m.area.x0)+m.rs*(it-m.area.y0)))); + for (int y=it;yReset(); + theS->QuickScan(curY,curPt,((float)(y+1)),theI,1.0); + theI->Flatten(); + theIL->Copy(theI); + + raster_info dest; + dest.startPix=il; + dest.endPix=ir; + dest.sth=il; + dest.stv=y; + dest.buffer=ligStart; + theIL->Raster(dest,NULL,shape_run_A8_OR); + ligStart=((uint32_t*)(((char*)ligStart)+m.rs)); + } + theS->EndQuickRaster(); + delete theI; + delete theIL; + + /* // version par BitLigne + int curPt; + float curY; + theS->BeginRaster(curY,curPt,1.0); + + BitLigne* theI[4]; + for (int i=0;i<4;i++) theI[i]=new BitLigne(il,ir); + IntLigne* theIL=new IntLigne(); + + theS->Scan(curY,curPt,(float)(it),0.25); + + char* mdata=(char*)m.data.px; + if ( m.size == NR_PIXBLOCK_SIZE_TINY ) mdata=(char*)m.data.p; + uint32_t* ligStart=((uint32_t*)(mdata+((il-m.area.x0)+m.rs*(it-m.area.y0)))); + for (int y=it;yReset(); + if ( y&0x00000003 ) { + theS->Scan(curY,curPt,((float)(y+0.25)),fill_oddEven,theI[0],false,0.25); + theS->Scan(curY,curPt,((float)(y+0.5)),fill_oddEven,theI[1],false,0.25); + theS->Scan(curY,curPt,((float)(y+0.75)),fill_oddEven,theI[2],false,0.25); + theS->Scan(curY,curPt,((float)(y+1.0)),fill_oddEven,theI[3],false,0.25); + } else { + theS->Scan(curY,curPt,((float)(y+0.25)),fill_oddEven,theI[0],true,0.25); + theS->Scan(curY,curPt,((float)(y+0.5)),fill_oddEven,theI[1],true,0.25); + theS->Scan(curY,curPt,((float)(y+0.75)),fill_oddEven,theI[2],true,0.25); + theS->Scan(curY,curPt,((float)(y+1.0)),fill_oddEven,theI[3],true,0.25); + } + theIL->Copy(4,theI); + + raster_info dest; + dest.startPix=il; + dest.endPix=ir; + dest.sth=il; + dest.stv=y; + dest.buffer=ligStart; + theIL->Raster(dest,NULL,shape_run_A8_OR); + ligStart=((uint32_t*)(((char*)ligStart)+m.rs)); + } + theS->EndRaster(); + for (int i=0;i<4;i++) delete theI[i]; + delete theIL;*/ + +/* // version par BitLigne directe + int curPt; + float curY; + theS->BeginQuickRaster(curY,curPt,1.0); + + BitLigne* theI[4]; + for (int i=0;i<4;i++) theI[i]=new BitLigne(il,ir); + IntLigne* theIL=new IntLigne(); + + theS->DirectQuickScan(curY,curPt,(float)(it),true,0.25); + + char* mdata=(char*)m.data.px; + if ( m.size == NR_PIXBLOCK_SIZE_TINY ) mdata=(char*)m.data.p; + uint32_t* ligStart=((uint32_t*)(mdata+((il-m.area.x0)+m.rs*(it-m.area.y0)))); + for (int y=it;yReset(); + if ( y&0x00000003 ) { + theS->QuickScan(curY,curPt,((float)(y+0.25)),fill_oddEven,theI[0],false,0.25); + theS->QuickScan(curY,curPt,((float)(y+0.5)),fill_oddEven,theI[1],false,0.25); + theS->QuickScan(curY,curPt,((float)(y+0.75)),fill_oddEven,theI[2],false,0.25); + theS->QuickScan(curY,curPt,((float)(y+1.0)),fill_oddEven,theI[3],false,0.25); + } else { + theS->QuickScan(curY,curPt,((float)(y+0.25)),fill_oddEven,theI[0],true,0.25); + theS->QuickScan(curY,curPt,((float)(y+0.5)),fill_oddEven,theI[1],true,0.25); + theS->QuickScan(curY,curPt,((float)(y+0.75)),fill_oddEven,theI[2],true,0.25); + theS->QuickScan(curY,curPt,((float)(y+1.0)),fill_oddEven,theI[3],true,0.25); + } + theIL->Copy(4,theI); + + raster_info dest; + dest.startPix=il; + dest.endPix=ir; + dest.sth=il; + dest.stv=y; + dest.buffer=ligStart; + theIL->Raster(dest,NULL,shape_run_A8_OR); + ligStart=((uint32_t*)(((char*)ligStart)+m.rs)); + } + theS->EndQuickRaster(); + for (int i=0;i<4;i++) delete theI[i]; + delete theIL;*/ +} + + +/* + 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:textwidth=99 : diff --git a/src/display/nr-arena-shape.h b/src/display/nr-arena-shape.h new file mode 100644 index 000000000..f7991bf4d --- /dev/null +++ b/src/display/nr-arena-shape.h @@ -0,0 +1,213 @@ +#ifndef __NR_ARENA_SHAPE_H__ +#define __NR_ARENA_SHAPE_H__ + +/* + * RGBA display list system for inkscape + * + * Author: + * Lauris Kaplinski + * + * Copyright (C) 2001-2002 Lauris Kaplinski + * Copyright (C) 2001 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#define NR_TYPE_ARENA_SHAPE (nr_arena_shape_get_type ()) +#define NR_ARENA_SHAPE(obj) (NR_CHECK_INSTANCE_CAST ((obj), NR_TYPE_ARENA_SHAPE, NRArenaShape)) +#define NR_IS_ARENA_SHAPE(obj) (NR_CHECK_INSTANCE_TYPE ((obj), NR_TYPE_ARENA_SHAPE)) + +//#include + +#include "display/curve.h" +#include "display/canvas-bpath.h" +#include "forward.h" +#include "sp-paint-server.h" +#include "nr-arena-item.h" + +#include "../color.h" + +#include "../livarot/Shape.h" + +NRType nr_arena_shape_get_type (void); + +struct NRArenaShape : public NRArenaItem { + class Paint { + public: + enum Type { + NONE, + COLOR, + SERVER + }; + + Paint() : _type(NONE), _server(NULL) { + sp_color_set_rgb_rgba32(&_color, 0); + } + Paint(Paint const &p) { _assign(p); } + ~Paint() { clear(); } + + Type type() const { return _type; } + SPPaintServer *server() const { return _server; } + SPColor const &color() const { return _color; } + + Paint &operator=(Paint const &p) { + set(p); + return *this; + } + + void set(Paint const &p) { + clear(); + _assign(p); + } + void set(SPColor const &color) { + clear(); + _type = COLOR; + sp_color_copy(&_color, &color); + } + void set(SPPaintServer *server) { + clear(); + if (server) { + _type = SERVER; + _server = server; + sp_object_ref(_server, NULL); + } + } + void clear() { + if ( _type == SERVER ) { + sp_object_unref(_server, NULL); + _server = NULL; + } + _type = NONE; + } + + private: + Type _type; + SPColor _color; + SPPaintServer *_server; + + void _assign(Paint const &p) { + _type = p._type; + _server = p._server; + sp_color_copy(&_color, &p._color); + if (_server) { + sp_object_ref(_server, NULL); + } + } + }; + + enum FillRule { + EVEN_ODD, + NONZERO + }; + + enum CapType { + ROUND_CAP, + SQUARE_CAP, + BUTT_CAP + }; + + enum JoinType { + ROUND_JOIN, + BEVEL_JOIN, + MITRE_JOIN + }; + + /* Shape data */ + SPCurve *curve; + SPStyle *style; + NRRect paintbox; + /* State data */ + NR::Matrix ctm; + + SPPainter *fill_painter; + SPPainter *stroke_painter; + // the 2 cached polygons, for rasterizations uses + Shape *fill_shp; + Shape *stroke_shp; + // delayed_shp=true means the *_shp polygons are not computed yet + // they'll be computed on demand in *_render(), *_pick() or *_clip() + // the goal is to not uncross polygons that are outside the viewing region + bool delayed_shp; + // approximate bounding box, for the case when the polygons have been delayed + NRRectL approx_bbox; + // cache for transformations: cached_fill and cached_stroke are + // polygons computed for the cached_fctm and cache_sctm respectively + // when the transformation changes interactively (tracked by the + // SP_OBJECT_USER_MODIFIED_FLAG_B), we check if it's an isometry wrt + // the cached ctm. if it's an isometry, just apply it to the cached + // polygon to get the *_shp polygon. Otherwise, recompute so this + // works fine for translation and rotation, but not scaling and + // skewing + NR::Matrix cached_fctm; + NR::Matrix cached_sctm; + + Shape *cached_fill; + Shape *cached_stroke; + /* Markers */ + NRArenaItem *markers; + + static NRArenaShape *create(NRArena *arena) { + NRArenaShape *obj=reinterpret_cast(nr_object_new(NR_TYPE_ARENA_SHAPE)); + obj->init(arena); + return obj; + } + + void setFill(SPPaintServer *server); + void setFill(SPColor const &color); + void setFillOpacity(double opacity); + void setFillRule(FillRule rule); + + void setStroke(SPPaintServer *server); + void setStroke(SPColor const &color); + void setStrokeOpacity(double opacity); + void setStrokeWidth(double width); + void setLineCap(CapType cap); + void setLineJoin(JoinType join); + void setMitreLimit(double limit); + + void setPaintBox(NR::Rect const &pbox); + + void _invalidateCachedFill() { + if (cached_fill) { + delete cached_fill; + cached_fill = NULL; + } + } + void _invalidateCachedStroke() { + if (cached_stroke) { + delete cached_stroke; + cached_stroke = NULL; + } + } + + struct Style { + Style() : opacity(0.0) {} + Paint paint; + double opacity; + }; + struct FillStyle : public Style { + FillStyle() : rule(EVEN_ODD) {} + FillRule rule; + } _fill; + struct StrokeStyle : public Style { + StrokeStyle() + : cap(ROUND_CAP), join(ROUND_JOIN), + width(0.0), mitre_limit(0.0) + {} + + CapType cap; + JoinType join; + double width; + double mitre_limit; + } _stroke; +}; + +struct NRArenaShapeClass { + NRArenaItemClass parent_class; +}; + +void nr_arena_shape_set_path(NRArenaShape *shape, SPCurve *curve, bool justTrans); +void nr_arena_shape_set_style (NRArenaShape *shape, SPStyle *style); +void nr_arena_shape_set_paintbox (NRArenaShape *shape, const NRRect *pbox); + +#endif diff --git a/src/display/nr-arena.cpp b/src/display/nr-arena.cpp new file mode 100644 index 000000000..f54bfbb90 --- /dev/null +++ b/src/display/nr-arena.cpp @@ -0,0 +1,131 @@ +#define __NR_ARENA_C__ + +/* + * RGBA display list system for inkscape + * + * Author: + * Lauris Kaplinski + * + * Copyright (C) 2001-2002 Lauris Kaplinski + * Copyright (C) 2001 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "nr-arena-item.h" +#include "nr-arena.h" +#include + +static void nr_arena_class_init (NRArenaClass *klass); +static void nr_arena_init (NRArena *arena); +static void nr_arena_finalize (NRObject *object); + +static NRActiveObjectClass *parent_class; + +NRType +nr_arena_get_type (void) +{ + static NRType type = 0; + if (!type) { + type = nr_object_register_type (NR_TYPE_ACTIVE_OBJECT, + "NRArena", + sizeof (NRArenaClass), + sizeof (NRArena), + (void (*) (NRObjectClass *)) nr_arena_class_init, + (void (*) (NRObject *)) nr_arena_init); + } + return type; +} + +static void +nr_arena_class_init (NRArenaClass *klass) +{ + NRObjectClass *object_class = (NRObjectClass *) klass; + + parent_class = (NRActiveObjectClass *) (((NRObjectClass *) klass)->parent); + + object_class->finalize = nr_arena_finalize; + object_class->cpp_ctor = NRObject::invoke_ctor; +} + +static void +nr_arena_init (NRArena *arena) +{ + arena->delta = 0; // to be set by desktop from prefs + arena->rendermode = RENDERMODE_NORMAL; // default is normal render + arena->outlinecolor = 0xff; // black; to be set by desktop from bg color +} + +static void +nr_arena_finalize (NRObject *object) +{ + ((NRObjectClass *) (parent_class))->finalize (object); +} + +void +nr_arena_request_update (NRArena *arena, NRArenaItem *item) +{ + NRActiveObject *aobject = (NRActiveObject *) arena; + + nr_return_if_fail (arena != NULL); + nr_return_if_fail (NR_IS_ARENA (arena)); + nr_return_if_fail (item != NULL); + nr_return_if_fail (NR_IS_ARENA_ITEM (item)); + + if (aobject->callbacks) { + for (unsigned int i = 0; i < aobject->callbacks->length; i++) { + NRObjectListener *listener = aobject->callbacks->listeners + i; + NRArenaEventVector *avector = (NRArenaEventVector *) listener->vector; + if ((listener->size >= sizeof (NRArenaEventVector)) && avector->request_update) { + avector->request_update (arena, item, listener->data); + } + } + } +} + +void +nr_arena_request_render_rect (NRArena *arena, NRRectL *area) +{ + NRActiveObject *aobject = (NRActiveObject *) arena; + + nr_return_if_fail (arena != NULL); + nr_return_if_fail (NR_IS_ARENA (arena)); + nr_return_if_fail (area != NULL); + + if (aobject->callbacks && area && !nr_rect_l_test_empty (area)) { + for (unsigned int i = 0; i < aobject->callbacks->length; i++) { + NRObjectListener *listener = aobject->callbacks->listeners + i; + NRArenaEventVector *avector = (NRArenaEventVector *) listener->vector; + if ((listener->size >= sizeof (NRArenaEventVector)) && avector->request_render) { + avector->request_render (arena, area, listener->data); + } + } + } +} + +void +nr_arena_render_paintserver_fill (NRPixBlock *pb, NRRectL *area, SPPainter *painter, float opacity, NRPixBlock *mask) +{ + NRPixBlock cb, cb_opa; + nr_pixblock_setup_fast (&cb, NR_PIXBLOCK_MODE_R8G8B8A8N, area->x0, area->y0, area->x1, area->y1, TRUE); + nr_pixblock_setup_fast (&cb_opa, NR_PIXBLOCK_MODE_R8G8B8A8N, area->x0, area->y0, area->x1, area->y1, TRUE); + + /* Need separate gradient buffer (lauris)*/ + // do the filling + painter->fill (painter, &cb); + cb.empty = FALSE; + + // do the fill-opacity and mask composite + if (opacity < 1.0) { + nr_blit_pixblock_pixblock_alpha (&cb_opa, &cb, (int) floor (255 * opacity)); + cb_opa.empty = FALSE; + nr_blit_pixblock_pixblock_mask (pb, &cb_opa, mask); + } else { + nr_blit_pixblock_pixblock_mask (pb, &cb, mask); + } + + pb->empty = FALSE; + + nr_pixblock_release (&cb); + nr_pixblock_release (&cb_opa); +} diff --git a/src/display/nr-arena.h b/src/display/nr-arena.h new file mode 100644 index 000000000..245ce14db --- /dev/null +++ b/src/display/nr-arena.h @@ -0,0 +1,57 @@ +#ifndef __NR_ARENA_H__ +#define __NR_ARENA_H__ + +/* + * RGBA display list system for inkscape + * + * Author: + * Lauris Kaplinski + * + * Copyright (C) 2001-2002 Lauris Kaplinski + * Copyright (C) 2001 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#define NR_TYPE_ARENA (nr_arena_get_type ()) +#define NR_ARENA(o) (NR_CHECK_INSTANCE_CAST ((o), NR_TYPE_ARENA, NRArena)) +#define NR_IS_ARENA(o) (NR_CHECK_INSTANCE_TYPE ((o), NR_TYPE_ARENA)) + +#include +#include +#include "nr-arena-forward.h" +#include "sp-paint-server.h" + +NRType nr_arena_get_type (void); + +struct NRArenaEventVector { + NRObjectEventVector parent; + void (* request_update) (NRArena *arena, NRArenaItem *item, void *data); + void (* request_render) (NRArena *arena, NRRectL *area, void *data); +}; + +enum { + RENDERMODE_NORMAL, + RENDERMODE_NOAA, + RENDERMODE_OUTLINE +}; + +struct NRArena : public NRActiveObject { + static NRArena *create() { + return reinterpret_cast(nr_object_new(NR_TYPE_ARENA)); + } + + double delta; + int rendermode; + guint32 outlinecolor; +}; + +struct NRArenaClass : public NRActiveObjectClass { +}; + +void nr_arena_request_update (NRArena *arena, NRArenaItem *item); +void nr_arena_request_render_rect (NRArena *arena, NRRectL *area); + +void nr_arena_render_paintserver_fill (NRPixBlock *pb, NRRectL *area, SPPainter *painter, float opacity, NRPixBlock *mask); + +#endif diff --git a/src/display/nr-gradient-gpl.cpp b/src/display/nr-gradient-gpl.cpp new file mode 100644 index 000000000..54a33cfdb --- /dev/null +++ b/src/display/nr-gradient-gpl.cpp @@ -0,0 +1,306 @@ +#define __NR_GRADIENT_C__ + +/* + * Pixel buffer rendering library + * + * Authors: + * Lauris Kaplinski + * + * Copyright (C) 2001-2002 Lauris Kaplinski + * Copyright (C) 2001-2002 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include +#include + +#include "nr-gradient-gpl.h" + +#define noNR_USE_GENERIC_RENDERER + +#define NRG_MASK (NR_GRADIENT_VECTOR_LENGTH - 1) +#define NRG_2MASK ((NR_GRADIENT_VECTOR_LENGTH << 1) - 1) + +static void nr_lgradient_render_block (NRRenderer *r, NRPixBlock *pb, NRPixBlock *m); +static void nr_lgradient_render_R8G8B8A8N_EMPTY (NRLGradientRenderer *lgr, unsigned char *px, int x0, int y0, int width, int height, int rs); +static void nr_lgradient_render_R8G8B8A8N (NRLGradientRenderer *lgr, unsigned char *px, int x0, int y0, int width, int height, int rs); +static void nr_lgradient_render_R8G8B8 (NRLGradientRenderer *lgr, unsigned char *px, int x0, int y0, int width, int height, int rs); +static void nr_lgradient_render_generic (NRLGradientRenderer *lgr, NRPixBlock *pb); + +NRRenderer * +nr_lgradient_renderer_setup (NRLGradientRenderer *lgr, + const unsigned char *cv, + unsigned int spread, + const NRMatrix *gs2px, + float x0, float y0, + float x1, float y1) +{ + NRMatrix n2gs, n2px, px2n; + + lgr->renderer.render = nr_lgradient_render_block; + + lgr->vector = cv; + lgr->spread = spread; + + n2gs.c[0] = x1 - x0; + n2gs.c[1] = y1 - y0; + n2gs.c[2] = y1 - y0; + n2gs.c[3] = x0 - x1; + n2gs.c[4] = x0; + n2gs.c[5] = y0; + + nr_matrix_multiply (&n2px, &n2gs, gs2px); + nr_matrix_invert (&px2n, &n2px); + + lgr->x0 = n2px.c[4] - 0.5; + lgr->y0 = n2px.c[5] - 0.5; + lgr->dx = px2n.c[0] * NR_GRADIENT_VECTOR_LENGTH; + lgr->dy = px2n.c[2] * NR_GRADIENT_VECTOR_LENGTH; + + return (NRRenderer *) lgr; +} + +static void +nr_lgradient_render_block (NRRenderer *r, NRPixBlock *pb, NRPixBlock *m) +{ + NRLGradientRenderer *lgr; + int width, height; + + lgr = (NRLGradientRenderer *) r; + + width = pb->area.x1 - pb->area.x0; + height = pb->area.y1 - pb->area.y0; + +#ifdef NR_USE_GENERIC_RENDERER + nr_lgradient_render_generic (lgr, pb); +#else + if (pb->empty) { + switch (pb->mode) { + case NR_PIXBLOCK_MODE_A8: + nr_lgradient_render_generic (lgr, pb); + break; + case NR_PIXBLOCK_MODE_R8G8B8: + nr_lgradient_render_generic (lgr, pb); + break; + case NR_PIXBLOCK_MODE_R8G8B8A8N: + nr_lgradient_render_R8G8B8A8N_EMPTY (lgr, NR_PIXBLOCK_PX (pb), pb->area.x0, pb->area.y0, width, height, pb->rs); + break; + case NR_PIXBLOCK_MODE_R8G8B8A8P: + nr_lgradient_render_generic (lgr, pb); + break; + default: + break; + } + } else { + switch (pb->mode) { + case NR_PIXBLOCK_MODE_A8: + nr_lgradient_render_generic (lgr, pb); + break; + case NR_PIXBLOCK_MODE_R8G8B8: + nr_lgradient_render_R8G8B8 (lgr, NR_PIXBLOCK_PX (pb), pb->area.x0, pb->area.y0, width, height, pb->rs); + break; + case NR_PIXBLOCK_MODE_R8G8B8A8N: + nr_lgradient_render_R8G8B8A8N (lgr, NR_PIXBLOCK_PX (pb), pb->area.x0, pb->area.y0, width, height, pb->rs); + break; + case NR_PIXBLOCK_MODE_R8G8B8A8P: + nr_lgradient_render_generic (lgr, pb); + break; + default: + break; + } + } +#endif +} + +static void +nr_lgradient_render_R8G8B8A8N_EMPTY (NRLGradientRenderer *lgr, unsigned char *px, int x0, int y0, int width, int height, int rs) +{ + int x, y; + double pos; + + for (y = 0; y < height; y++) { + const unsigned char *s; + unsigned char *d; + int idx; + d = px + y * rs; + pos = (y + y0 - lgr->y0) * lgr->dy + (0 + x0 - lgr->x0) * lgr->dx; + if (lgr->spread == NR_GRADIENT_SPREAD_PAD) { + for (x = 0; x < width; x++) { + idx = (int) CLAMP (pos, 0, (double) NRG_MASK); + s = lgr->vector + 4 * idx; + d[0] = s[0]; + d[1] = s[1]; + d[2] = s[2]; + d[3] = s[3]; + d += 4; + pos += lgr->dx; + } + } else if (lgr->spread == NR_GRADIENT_SPREAD_REFLECT) { + for (x = 0; x < width; x++) { + idx = (int) ((long long) pos & NRG_2MASK); + if (idx > NRG_MASK) idx = NRG_2MASK - idx; + s = lgr->vector + 4 * idx; + d[0] = s[0]; + d[1] = s[1]; + d[2] = s[2]; + d[3] = s[3]; + d += 4; + pos += lgr->dx; + } + } else { + for (x = 0; x < width; x++) { + idx = (int) ((long long) pos & NRG_MASK); + s = lgr->vector + 4 * idx; + d[0] = s[0]; + d[1] = s[1]; + d[2] = s[2]; + d[3] = s[3]; + d += 4; + pos += lgr->dx; + } + } + } +} + +static void +nr_lgradient_render_R8G8B8A8N (NRLGradientRenderer *lgr, unsigned char *px, int x0, int y0, int width, int height, int rs) +{ + int x, y; + unsigned char *d; + double pos; + + for (y = 0; y < height; y++) { + d = px + y * rs; + pos = (y + y0 - lgr->y0) * lgr->dy + (0 + x0 - lgr->x0) * lgr->dx; + for (x = 0; x < width; x++) { + int idx; + unsigned int ca; + const unsigned char *s; + switch (lgr->spread) { + case NR_GRADIENT_SPREAD_PAD: + idx = (int) CLAMP (pos, 0, (double) NRG_MASK); + break; + case NR_GRADIENT_SPREAD_REFLECT: + idx = (int) ((long long) pos & NRG_2MASK); + if (idx > NRG_MASK) idx = NRG_2MASK - idx; + break; + case NR_GRADIENT_SPREAD_REPEAT: + idx = (int) ((long long) pos & NRG_MASK); + break; + default: + idx = 0; + break; + } + /* Full composition */ + s = lgr->vector + 4 * idx; + if (s[3] == 255) { + d[0] = s[0]; + d[1] = s[1]; + d[2] = s[2]; + d[3] = 255; + } else if (s[3] != 0) { + ca = NR_A7(s[3],d[3]); + d[0] = NR_COMPOSENNN_A7 (s[0], s[3], d[0], d[3], ca); + d[1] = NR_COMPOSENNN_A7 (s[1], s[3], d[1], d[3], ca); + d[2] = NR_COMPOSENNN_A7 (s[2], s[3], d[2], d[3], ca); + d[3] = NR_PREMUL_SINGLE(ca); + } + d += 4; + pos += lgr->dx; + } + } +} + +static void +nr_lgradient_render_R8G8B8 (NRLGradientRenderer *lgr, unsigned char *px, int x0, int y0, int width, int height, int rs) +{ + int x, y; + unsigned char *d; + double pos; + + for (y = 0; y < height; y++) { + d = px + y * rs; + pos = (y + y0 - lgr->y0) * lgr->dy + (0 + x0 - lgr->x0) * lgr->dx; + for (x = 0; x < width; x++) { + int idx; + const unsigned char *s; + switch (lgr->spread) { + case NR_GRADIENT_SPREAD_PAD: + idx = (int) CLAMP (pos, 0, (double) NRG_MASK); + break; + case NR_GRADIENT_SPREAD_REFLECT: + idx = (int) ((long long) pos & NRG_2MASK); + if (idx > NRG_MASK) idx = NRG_2MASK - idx; + break; + case NR_GRADIENT_SPREAD_REPEAT: + idx = (int) ((long long) pos & NRG_MASK); + break; + default: + idx = 0; + break; + } + /* Full composition */ + s = lgr->vector + 4 * idx; + d[0] = NR_COMPOSEN11 (s[0], s[3], d[0]); + d[1] = NR_COMPOSEN11 (s[1], s[3], d[1]); + d[2] = NR_COMPOSEN11 (s[2], s[3], d[2]); + d += 3; + pos += lgr->dx; + } + } +} + +static void +nr_lgradient_render_generic (NRLGradientRenderer *lgr, NRPixBlock *pb) +{ + int x, y; + unsigned char *d; + double pos; + int bpp; + NRPixBlock spb; + int x0, y0, width, height, rs; + + x0 = pb->area.x0; + y0 = pb->area.y0; + width = pb->area.x1 - pb->area.x0; + height = pb->area.y1 - pb->area.y0; + rs = pb->rs; + + nr_pixblock_setup_extern (&spb, NR_PIXBLOCK_MODE_R8G8B8A8N, 0, 0, NR_GRADIENT_VECTOR_LENGTH, 1, + (unsigned char *) lgr->vector, + 4 * NR_GRADIENT_VECTOR_LENGTH, + 0, 0); + bpp = (pb->mode == NR_PIXBLOCK_MODE_A8) ? 1 : (pb->mode == NR_PIXBLOCK_MODE_R8G8B8) ? 3 : 4; + + for (y = 0; y < height; y++) { + d = NR_PIXBLOCK_PX (pb) + y * rs; + pos = (y + y0 - lgr->y0) * lgr->dy + (0 + x0 - lgr->x0) * lgr->dx; + for (x = 0; x < width; x++) { + int idx; + const unsigned char *s; + switch (lgr->spread) { + case NR_GRADIENT_SPREAD_PAD: + idx = (int) CLAMP (pos, 0, (double) NRG_MASK); + break; + case NR_GRADIENT_SPREAD_REFLECT: + idx = (int) ((long long) pos & NRG_2MASK); + if (idx > NRG_MASK) idx = NRG_2MASK - idx; + break; + case NR_GRADIENT_SPREAD_REPEAT: + idx = (int) ((long long) pos & NRG_MASK); + break; + default: + idx = 0; + break; + } + s = lgr->vector + 4 * idx; + nr_compose_pixblock_pixblock_pixel (pb, d, &spb, s); + d += bpp; + pos += lgr->dx; + } + } + + nr_pixblock_release (&spb); +} + diff --git a/src/display/nr-gradient-gpl.h b/src/display/nr-gradient-gpl.h new file mode 100644 index 000000000..db7d9bb54 --- /dev/null +++ b/src/display/nr-gradient-gpl.h @@ -0,0 +1,41 @@ +#ifndef __NR_GRADIENT_GPL_H__ +#define __NR_GRADIENT_GPL_H__ + +/* + * Pixel buffer rendering library + * + * Authors: + * Lauris Kaplinski + * + * Copyright (C) 2001-2002 Lauris Kaplinski + * Copyright (C) 2001-2002 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +/* + * Here is GPL code, unlike other libnr wihich is public domain + */ + +#include + +/* Linear */ + +struct NRLGradientRenderer { + NRRenderer renderer; + const unsigned char *vector; + unsigned int spread; + double x0, y0; + double dx, dy; +}; + +NRRenderer *nr_lgradient_renderer_setup (NRLGradientRenderer *lgr, + const unsigned char *cv, + unsigned int spread, + const NRMatrix *gs2px, + float x0, float y0, + float x1, float y1); + + + +#endif diff --git a/src/display/nr-plain-stuff-gdk.cpp b/src/display/nr-plain-stuff-gdk.cpp new file mode 100644 index 000000000..d5b43f4ea --- /dev/null +++ b/src/display/nr-plain-stuff-gdk.cpp @@ -0,0 +1,46 @@ +#define __NR_PLAIN_STUFF_GDK_C__ + +/* + * Miscellaneous simple rendering utilities + * + * Author: + * Lauris Kaplinski + * + * Copyright (C) 2001 Lauris Kaplinski and Ximian, Inc. + * + * Released under GNU GPL + */ + +#include +#include "nr-plain-stuff.h" +#include "nr-plain-stuff-gdk.h" + +void +nr_gdk_draw_rgba32_solid (GdkDrawable *drawable, GdkGC *gc, gint x, gint y, gint w, gint h, guint32 rgba) +{ + NRPixBlock pb; + + nr_pixblock_setup_fast (&pb, NR_PIXBLOCK_MODE_R8G8B8A8N, 0, 0, w, h, FALSE); + + nr_render_rgba32_rgb (NR_PIXBLOCK_PX (&pb), w, h, pb.rs, x, y, rgba); + gdk_draw_rgb_image (drawable, gc, x, y, w, h, GDK_RGB_DITHER_MAX, NR_PIXBLOCK_PX (&pb), pb.rs); + + nr_pixblock_release (&pb); +} + +void +nr_gdk_draw_gray_garbage (GdkDrawable *drawable, GdkGC *gc, gint x, gint y, gint w, gint h) +{ + for (gint yy = y; yy < y + h; yy += 64) { + for (gint xx = x; xx < x + w; xx += 64) { + NRPixBlock pb; + gint ex = MIN (xx + 64, x + w); + gint ey = MIN (yy + 64, y + h); + nr_pixblock_setup_fast (&pb, NR_PIXBLOCK_MODE_R8G8B8, xx, yy, ex, ey, FALSE); + nr_pixblock_render_gray_noise (&pb, NULL); + gdk_draw_rgb_image (drawable, gc, xx, yy, ex - xx, ey - yy, GDK_RGB_DITHER_NONE, NR_PIXBLOCK_PX (&pb), pb.rs); + nr_pixblock_release (&pb); + } + } +} + diff --git a/src/display/nr-plain-stuff-gdk.h b/src/display/nr-plain-stuff-gdk.h new file mode 100644 index 000000000..7c83792a8 --- /dev/null +++ b/src/display/nr-plain-stuff-gdk.h @@ -0,0 +1,32 @@ +#ifndef __NR_PLAIN_STUFF_GDK_H__ +#define __NR_PLAIN_STUFF_GDK_H__ + +/* + * Miscellaneous simple rendering utilities + * + * Author: + * Lauris Kaplinski + * + * Copyright (C) 2001 Lauris Kaplinski and Ximian, Inc. + * + * Released under GNU GPL + */ + +#include + +void nr_gdk_draw_rgba32_solid (GdkDrawable *drawable, GdkGC *gc, gint x, gint y, gint w, gint h, guint32 rgba); + +void nr_gdk_draw_gray_garbage (GdkDrawable *drawable, GdkGC *gc, gint x, gint y, gint w, gint h); + +#endif + +/* + 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:textwidth=99 : diff --git a/src/display/nr-plain-stuff.cpp b/src/display/nr-plain-stuff.cpp new file mode 100644 index 000000000..af6e002ec --- /dev/null +++ b/src/display/nr-plain-stuff.cpp @@ -0,0 +1,94 @@ +#define __NR_PLAIN_STUFF_C__ + +/* + * Miscellaneous simple rendering utilities + * + * Author: + * Lauris Kaplinski + * + * Copyright (C) 2001 Lauris Kaplinski and Ximian, Inc. + * + * Released under GNU GPL + */ + +#include +#include +#include "nr-plain-stuff.h" + +#define NR_DEFAULT_CHECKERSIZEP2 2 +#define NR_DEFAULT_CHECKERCOLOR0 0xbfbfbfff +#define NR_DEFAULT_CHECKERCOLOR1 0x808080ff + +void +nr_render_checkerboard_rgb (guchar *px, gint w, gint h, gint rs, gint xoff, gint yoff) +{ + g_return_if_fail (px != NULL); + + nr_render_checkerboard_rgb_custom (px, w, h, rs, xoff, yoff, NR_DEFAULT_CHECKERCOLOR0, NR_DEFAULT_CHECKERCOLOR1, NR_DEFAULT_CHECKERSIZEP2); +} + +void +nr_render_checkerboard_rgb_custom (guchar *px, gint w, gint h, gint rs, gint xoff, gint yoff, guint32 c0, guint32 c1, gint sizep2) +{ + gint x, y, m; + guint r0, g0, b0; + guint r1, g1, b1; + + g_return_if_fail (px != NULL); + g_return_if_fail (sizep2 >= 0); + g_return_if_fail (sizep2 <= 8); + + xoff &= 0x1ff; + yoff &= 0x1ff; + m = 0x1 << sizep2; + r0 = NR_RGBA32_R (c0); + g0 = NR_RGBA32_G (c0); + b0 = NR_RGBA32_B (c0); + r1 = NR_RGBA32_R (c1); + g1 = NR_RGBA32_G (c1); + b1 = NR_RGBA32_B (c1); + + for (y = 0; y < h; y++) { + guchar *p; + p = px; + for (x = 0; x < w; x++) { + if (((x + xoff) ^ (y + yoff)) & m) { + *p++ = r0; + *p++ = g0; + *p++ = b0; + } else { + *p++ = r1; + *p++ = g1; + *p++ = b1; + } + } + px += rs; + } +} + +void +nr_render_rgba32_rgb (guchar *px, gint w, gint h, gint rs, gint xoff, gint yoff, guint32 c) +{ + guint32 c0, c1; + gint a, r, g, b, cr, cg, cb; + + g_return_if_fail (px != NULL); + + r = NR_RGBA32_R (c); + g = NR_RGBA32_G (c); + b = NR_RGBA32_B (c); + a = NR_RGBA32_A (c); + + cr = NR_COMPOSEN11 (r, a, NR_RGBA32_R (NR_DEFAULT_CHECKERCOLOR0)); + cg = NR_COMPOSEN11 (g, a, NR_RGBA32_G (NR_DEFAULT_CHECKERCOLOR0)); + cb = NR_COMPOSEN11 (b, a, NR_RGBA32_B (NR_DEFAULT_CHECKERCOLOR0)); + c0 = (cr << 24) | (cg << 16) | (cb << 8) | 0xff; + + cr = NR_COMPOSEN11 (r, a, NR_RGBA32_R (NR_DEFAULT_CHECKERCOLOR1)); + cg = NR_COMPOSEN11 (g, a, NR_RGBA32_G (NR_DEFAULT_CHECKERCOLOR1)); + cb = NR_COMPOSEN11 (b, a, NR_RGBA32_B (NR_DEFAULT_CHECKERCOLOR1)); + c1 = (cr << 24) | (cg << 16) | (cb << 8) | 0xff; + + nr_render_checkerboard_rgb_custom (px, w, h, rs, xoff, yoff, c0, c1, NR_DEFAULT_CHECKERSIZEP2); +} + diff --git a/src/display/nr-plain-stuff.h b/src/display/nr-plain-stuff.h new file mode 100644 index 000000000..c568f38a6 --- /dev/null +++ b/src/display/nr-plain-stuff.h @@ -0,0 +1,33 @@ +#ifndef __NR_PLAIN_STUFF_H__ +#define __NR_PLAIN_STUFF_H__ + +/* + * Miscellaneous simple rendering utilities + * + * Author: + * Lauris Kaplinski + * + * Copyright (C) 2001 Lauris Kaplinski and Ximian, Inc. + * + * Released under GNU GPL + */ + +#include + +void nr_render_checkerboard_rgb (guchar *px, gint w, gint h, gint rs, gint xoff, gint yoff); +void nr_render_checkerboard_rgb_custom (guchar *px, gint w, gint h, gint rs, gint xoff, gint yoff, guint32 c0, guint32 c1, gint sizep2); + +void nr_render_rgba32_rgb (guchar *px, gint w, gint h, gint rs, gint xoff, gint yoff, guint32 c); + +#endif + +/* + 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:textwidth=99 : diff --git a/src/display/sodipodi-ctrl.cpp b/src/display/sodipodi-ctrl.cpp new file mode 100644 index 000000000..71786fd96 --- /dev/null +++ b/src/display/sodipodi-ctrl.cpp @@ -0,0 +1,494 @@ +#define INKSCAPE_CTRL_C + +/* + * SPCtrl + * + * We render it by hand to reduce allocing/freeing svps & to get clean + * (non-aa) images + * + */ + +#include "sp-canvas-util.h" +#include "display-forward.h" +#include "sodipodi-ctrl.h" + +enum { + ARG_0, + ARG_SHAPE, + ARG_MODE, + ARG_ANCHOR, + ARG_SIZE, + ARG_FILLED, + ARG_FILL_COLOR, + ARG_STROKED, + ARG_STROKE_COLOR, + ARG_PIXBUF +}; + + +static void sp_ctrl_class_init (SPCtrlClass *klass); +static void sp_ctrl_init (SPCtrl *ctrl); +static void sp_ctrl_destroy (GtkObject *object); +static void sp_ctrl_set_arg (GtkObject *object, GtkArg *arg, guint arg_id); + +static void sp_ctrl_update (SPCanvasItem *item, NR::Matrix const &affine, unsigned int flags); +static void sp_ctrl_render (SPCanvasItem *item, SPCanvasBuf *buf); + +static double sp_ctrl_point (SPCanvasItem *item, NR::Point p, SPCanvasItem **actual_item); + + +static SPCanvasItemClass *parent_class; + +GtkType +sp_ctrl_get_type (void) +{ + static GtkType ctrl_type = 0; + if (!ctrl_type) { + static const GTypeInfo ctrl_info = { + sizeof (SPCtrlClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) sp_ctrl_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (SPCtrl), + 0, /* n_preallocs */ + (GInstanceInitFunc) sp_ctrl_init, + NULL + }; + ctrl_type = g_type_register_static (SP_TYPE_CANVAS_ITEM, "SPCtrl", &ctrl_info, (GTypeFlags)0); + } + return ctrl_type; +} + +static void +sp_ctrl_class_init (SPCtrlClass *klass) +{ + GtkObjectClass *object_class; + SPCanvasItemClass *item_class; + + object_class = (GtkObjectClass *) klass; + item_class = (SPCanvasItemClass *) klass; + + parent_class = (SPCanvasItemClass *)gtk_type_class (sp_canvas_item_get_type ()); + + gtk_object_add_arg_type ("SPCtrl::shape", GTK_TYPE_INT, GTK_ARG_READWRITE, ARG_SHAPE); + gtk_object_add_arg_type ("SPCtrl::mode", GTK_TYPE_INT, GTK_ARG_READWRITE, ARG_MODE); + gtk_object_add_arg_type ("SPCtrl::anchor", GTK_TYPE_ANCHOR_TYPE, GTK_ARG_READWRITE, ARG_ANCHOR); + gtk_object_add_arg_type ("SPCtrl::size", GTK_TYPE_DOUBLE, GTK_ARG_READWRITE, ARG_SIZE); + gtk_object_add_arg_type ("SPCtrl::pixbuf", GTK_TYPE_POINTER, GTK_ARG_READWRITE, ARG_PIXBUF); + gtk_object_add_arg_type ("SPCtrl::filled", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_FILLED); + gtk_object_add_arg_type ("SPCtrl::fill_color", GTK_TYPE_INT, GTK_ARG_READWRITE, ARG_FILL_COLOR); + gtk_object_add_arg_type ("SPCtrl::stroked", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_STROKED); + gtk_object_add_arg_type ("SPCtrl::stroke_color", GTK_TYPE_INT, GTK_ARG_READWRITE, ARG_STROKE_COLOR); + + object_class->destroy = sp_ctrl_destroy; + object_class->set_arg = sp_ctrl_set_arg; + + item_class->update = sp_ctrl_update; + item_class->render = sp_ctrl_render; + item_class->point = sp_ctrl_point; +} + +static void +sp_ctrl_init (SPCtrl *ctrl) +{ + ctrl->shape = SP_CTRL_SHAPE_SQUARE; + ctrl->mode = SP_CTRL_MODE_COLOR; + ctrl->anchor = GTK_ANCHOR_CENTER; + ctrl->span = 3; + ctrl->defined = TRUE; + ctrl->shown = FALSE; + ctrl->build = FALSE; + ctrl->filled = 1; + ctrl->stroked = 0; + ctrl->fill_color = 0x000000ff; + ctrl->stroke_color = 0x000000ff; + + ctrl->box.x0 = ctrl->box.y0 = ctrl->box.x1 = ctrl->box.y1 = 0; + ctrl->cache = NULL; + ctrl->pixbuf = NULL; +} + +static void +sp_ctrl_destroy (GtkObject *object) +{ + SPCtrl *ctrl; + + g_return_if_fail (object != NULL); + g_return_if_fail (SP_IS_CTRL (object)); + + ctrl = SP_CTRL (object); + + if (GTK_OBJECT_CLASS (parent_class)->destroy) + (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); +} + +static void +sp_ctrl_set_arg (GtkObject *object, GtkArg *arg, guint arg_id) +{ + SPCanvasItem *item; + SPCtrl *ctrl; + GdkPixbuf * pixbuf = NULL; + + item = SP_CANVAS_ITEM (object); + ctrl = SP_CTRL (object); + + switch (arg_id) { + case ARG_SHAPE: + ctrl->shape = (SPCtrlShapeType)(GTK_VALUE_INT (*arg)); + ctrl->build = FALSE; + sp_canvas_item_request_update (item); + break; + case ARG_MODE: + ctrl->mode = (SPCtrlModeType)(GTK_VALUE_INT (*arg)); + ctrl->build = FALSE; + sp_canvas_item_request_update (item); + break; + case ARG_ANCHOR: + ctrl->anchor = (GtkAnchorType)(GTK_VALUE_INT (*arg)); + ctrl->build = FALSE; + sp_canvas_item_request_update (item); + break; + case ARG_SIZE: + ctrl->span = (gint) ((GTK_VALUE_DOUBLE (*arg) - 1.0) / 2.0 + 0.5); + ctrl->defined = (ctrl->span > 0); + ctrl->build = FALSE; + sp_canvas_item_request_update (item); + break; + case ARG_FILLED: + ctrl->filled = GTK_VALUE_BOOL (*arg); + ctrl->build = FALSE; + sp_canvas_item_request_update (item); + break; + case ARG_FILL_COLOR: + ctrl->fill_color = GTK_VALUE_INT (*arg); + ctrl->build = FALSE; + sp_canvas_item_request_update (item); + break; + case ARG_STROKED: + ctrl->stroked = GTK_VALUE_BOOL (*arg); + ctrl->build = FALSE; + sp_canvas_item_request_update (item); + break; + case ARG_STROKE_COLOR: + ctrl->stroke_color = GTK_VALUE_INT (*arg); + ctrl->build = FALSE; + sp_canvas_item_request_update (item); + break; + case ARG_PIXBUF: + pixbuf = (GdkPixbuf*)(GTK_VALUE_POINTER (*arg)); + if (gdk_pixbuf_get_has_alpha (pixbuf)) { + ctrl->pixbuf = pixbuf; + } else { + ctrl->pixbuf = gdk_pixbuf_add_alpha (pixbuf, FALSE, 0, 0, 0); + gdk_pixbuf_unref (pixbuf); + } + ctrl->build = FALSE; + break; + default: + break; + } +} + +static void +sp_ctrl_update (SPCanvasItem *item, NR::Matrix const &affine, unsigned int flags) +{ + SPCtrl *ctrl; + gint x, y; + + ctrl = SP_CTRL (item); + + if (((SPCanvasItemClass *) parent_class)->update) + (* ((SPCanvasItemClass *) parent_class)->update) (item, affine, flags); + + sp_canvas_item_reset_bounds (item); + + if (ctrl->shown) { + sp_canvas_request_redraw (item->canvas, ctrl->box.x0, ctrl->box.y0, ctrl->box.x1 + 1, ctrl->box.y1 + 1); + } + + if (!ctrl->defined) return; + + x = (gint) ((affine[4] > 0) ? (affine[4] + 0.5) : (affine[4] - 0.5)) - ctrl->span; + y = (gint) ((affine[5] > 0) ? (affine[5] + 0.5) : (affine[5] - 0.5)) - ctrl->span; + + switch (ctrl->anchor) { + case GTK_ANCHOR_N: + case GTK_ANCHOR_CENTER: + case GTK_ANCHOR_S: + break; + case GTK_ANCHOR_NW: + case GTK_ANCHOR_W: + case GTK_ANCHOR_SW: + x += ctrl->span; + break; + case GTK_ANCHOR_NE: + case GTK_ANCHOR_E: + case GTK_ANCHOR_SE: + x -= (ctrl->span + 1); + break; + } + + switch (ctrl->anchor) { + case GTK_ANCHOR_W: + case GTK_ANCHOR_CENTER: + case GTK_ANCHOR_E: + break; + case GTK_ANCHOR_NW: + case GTK_ANCHOR_N: + case GTK_ANCHOR_NE: + y += ctrl->span; + break; + case GTK_ANCHOR_SW: + case GTK_ANCHOR_S: + case GTK_ANCHOR_SE: + y -= (ctrl->span + 1); + break; + } + + ctrl->box.x0 = x; + ctrl->box.y0 = y; + ctrl->box.x1 = ctrl->box.x0 + 2 * ctrl->span; + ctrl->box.y1 = ctrl->box.y0 + 2 * ctrl->span; + + sp_canvas_update_bbox (item, ctrl->box.x0, ctrl->box.y0, ctrl->box.x1 + 1, ctrl->box.y1 + 1); + +} + +static double +sp_ctrl_point (SPCanvasItem *item, NR::Point p, SPCanvasItem **actual_item) +{ + SPCtrl *ctrl = SP_CTRL (item); + + *actual_item = item; + + const double x = p[NR::X]; + const double y = p[NR::Y]; + + if ((x >= ctrl->box.x0) && (x <= ctrl->box.x1) && (y >= ctrl->box.y0) && (y <= ctrl->box.y1)) return 0.0; + + return 1e18; +} + +static void +sp_ctrl_build_cache (SPCtrl *ctrl) +{ + guchar * p, *q; + gint size, x, y, z, s, a, side, c; + guint8 fr, fg, fb, fa, sr, sg, sb, sa; + + if (ctrl->filled) { + fr = (ctrl->fill_color >> 24) & 0xff; + fg = (ctrl->fill_color >> 16) & 0xff; + fb = (ctrl->fill_color >> 8) & 0xff; + fa = (ctrl->fill_color) & 0xff; + } else { fr = 0x00; fg = 0x00; fb = 0x00; fa = 0x00; } + if (ctrl->stroked) { + sr = (ctrl->stroke_color >> 24) & 0xff; + sg = (ctrl->stroke_color >> 16) & 0xff; + sb = (ctrl->stroke_color >> 8) & 0xff; + sa = (ctrl->stroke_color) & 0xff; + } else { sr = fr; sg = fg; sb = fb; sa = fa; } + + + side = (ctrl->span * 2 +1); + c = ctrl->span ; + g_free (ctrl->cache); + size = (side) * (side) * 4; + ctrl->cache = (guchar*)g_malloc (size); + if (side < 2) return; + + switch (ctrl->shape) { + case SP_CTRL_SHAPE_SQUARE: + p = ctrl->cache; + for (x=0; x < side; x++) { *p++ = sr; *p++ = sg; *p++ = sb; *p++ = sa; } + for (y = 2; y < side; y++) { + *p++ = sr; *p++ = sg; *p++ = sb; *p++ = sa; + for (x=2; x < side; x++) { *p++ = fr; *p++ = fg; *p++ = fb; *p++ = fa; } + *p++ = sr; *p++ = sg; *p++ = sb; *p++ = sa; + } + for (x=0; x < side; x++) { *p++ = sr; *p++ = sg; *p++ = sb; *p++ = sa; } + ctrl->build = TRUE; + break; + case SP_CTRL_SHAPE_DIAMOND: + p = ctrl->cache; + for (y = 0; y < side; y++) { + z = abs (c - y); + for (x = 0; x < z; x++) {*p++ = 0x00; *p++ = 0x00; *p++ = 0x00; *p++ = 0x00;} + *p++ = sr; *p++ = sg; *p++ = sb; *p++ = sa; x++; + for (; x < side - z -1; x++) { *p++ = fr; *p++ = fg; *p++ = fb; *p++ = fa; } + if (z != c) {*p++ = sr; *p++ = sg; *p++ = sb; *p++ = sa; x++;} + for (; x < side; x++) {*p++ = 0x00; *p++ = 0x00; *p++ = 0x00; *p++ = 0x00;} + } + break; + case SP_CTRL_SHAPE_CIRCLE: + p = ctrl->cache; + q = p + size -1; + s = -1; + for (y = 0; y <= c ; y++) { + a = abs (c - y); + z = (gint)(0.0 + sqrt ((c+.4)*(c+.4) - a*a)); + x = 0; + while (x < c-z) { + *p++ = 0x00; *p++ = 0x00; *p++ = 0x00; *p++ = 0x00; + *q-- = 0x00; *q-- = 0x00; *q-- = 0x00; *q-- = 0x00; + x++; + } + do { + *p++ = sr; *p++ = sg; *p++ = sb; *p++ = sa; + *q-- = sa; *q-- = sb; *q-- = sg; *q-- = sr; + x++; + } while (x < c-s); + while (x < MIN(c+s+1, c+z)) { + *p++ = fr; *p++ = fg; *p++ = fb; *p++ = fa; + *q-- = fa; *q-- = fb; *q-- = fg; *q-- = fr; + x++; + } + do { + *p++ = sr; *p++ = sg; *p++ = sb; *p++ = sa; + *q-- = sa; *q-- = sb; *q-- = sg; *q-- = sr; + x++; + } while (x <= c+z); + while (x < side) { + *p++ = 0x00; *p++ = 0x00; *p++ = 0x00; *p++ = 0x00; + *q-- = 0x00; *q-- = 0x00; *q-- = 0x00; *q-- = 0x00; + x++; + } + s = z; + } + ctrl->build = TRUE; + break; + case SP_CTRL_SHAPE_CROSS: + p = ctrl->cache; + for (y = 0; y < side; y++) { + z = abs (c - y); + for (x = 0; x < c-z; x++) {*p++ = 0x00; *p++ = 0x00; *p++ = 0x00; *p++ = 0x00;} + *p++ = sr; *p++ = sg; *p++ = sb; *p++ = sa; x++; + for (; x < c + z; x++) {*p++ = 0x00; *p++ = 0x00; *p++ = 0x00; *p++ = 0x00;} + if (z != 0) {*p++ = sr; *p++ = sg; *p++ = sb; *p++ = sa; x++;} + for (; x < side; x++) {*p++ = 0x00; *p++ = 0x00; *p++ = 0x00; *p++ = 0x00;} + } + ctrl->build = TRUE; + break; + case SP_CTRL_SHAPE_BITMAP: + if (ctrl->pixbuf) { + unsigned char *px; + unsigned int rs; + px = gdk_pixbuf_get_pixels (ctrl->pixbuf); + rs = gdk_pixbuf_get_rowstride (ctrl->pixbuf); + for (y = 0; y < side; y++){ + unsigned char *s, *d; + s = px + y * rs; + d = ctrl->cache + 4 * side * y; + for (x = 0; x < side; x++) { + if (s[3] < 0x80) { + d[0] = 0x00; + d[1] = 0x00; + d[2] = 0x00; + d[3] = 0x00; + } else if (s[0] < 0x80) { + d[0] = sr; + d[1] = sg; + d[2] = sb; + d[3] = sa; + } else { + d[0] = fr; + d[1] = fg; + d[2] = fb; + d[3] = fa; + } + s += 4; + d += 4; + } + } + } else { + g_print ("control has no pixmap\n"); + } + ctrl->build = TRUE; + break; + case SP_CTRL_SHAPE_IMAGE: + if (ctrl->pixbuf) { + guint r = gdk_pixbuf_get_rowstride (ctrl->pixbuf); + guchar * pix; + q = gdk_pixbuf_get_pixels (ctrl->pixbuf); + p = ctrl->cache; + for (y = 0; y < side; y++){ + pix = q + (y * r); + for (x = 0; x < side; x++) { + *p++ = *pix++; + *p++ = *pix++; + *p++ = *pix++; + *p++ = *pix++; + } + } + } else { g_print ("control has no pixmap\n"); } + ctrl->build = TRUE; + break; + default: + break; + } + +} + +// composite background, foreground, alpha for xor mode +#define COMPOSE_X(b,f,a) ( ( ((guchar) b) * ((guchar) (0xff - a)) + ((guchar) ((b ^ ~f) + b/4 - (b>127? 63 : 0))) * ((guchar) a) ) / 0xff ) +// composite background, foreground, alpha for color mode +#define COMPOSE_N(b,f,a) ( ( ((guchar) b) * ((guchar) (0xff - a)) + ((guchar) f) * ((guchar) a) ) / 0xff ) + +static void +sp_ctrl_render (SPCanvasItem *item, SPCanvasBuf *buf) +{ + gint y0, y1, y, x0,x1,x; + guchar * p, * q, a; + + SPCtrl *ctrl = SP_CTRL (item); + + if (!ctrl->defined) return; + if ((!ctrl->filled) && (!ctrl->stroked)) return; + + sp_canvas_prepare_buffer (buf); + + // the control-image is rendered into ctrl->cache + if (!ctrl->build) sp_ctrl_build_cache (ctrl); + + // then we render from ctrl->cache + y0 = MAX (ctrl->box.y0, buf->rect.y0); + y1 = MIN (ctrl->box.y1, buf->rect.y1 - 1); + x0 = MAX (ctrl->box.x0, buf->rect.x0); + x1 = MIN (ctrl->box.x1, buf->rect.x1 - 1); + + bool colormode; + + for (y = y0; y <= y1; y++) { + p = buf->buf + (y - buf->rect.y0) * buf->buf_rowstride + (x0 - buf->rect.x0) * 3; + q = ctrl->cache + ((y - ctrl->box.y0) * (ctrl->span*2+1) + (x0 - ctrl->box.x0)) * 4; + for (x = x0; x <= x1; x++) { + a = *(q + 3); + // 00000000 is the only way to get invisible; all other colors with alpha 00 are treated as mode_color with alpha ff + colormode = false; + if (a == 0x00 && !(q[0] == 0x00 && q[1] == 0x00 && q[2] == 0x00)) { + a = 0xff; + colormode = true; + } + if (ctrl->mode == SP_CTRL_MODE_COLOR || colormode) { + p[0] = COMPOSE_N (p[0], q[0], a); + p[1] = COMPOSE_N (p[1], q[1], a); + p[2] = COMPOSE_N (p[2], q[2], a); + q += 4; + p += 3; + } else if (ctrl->mode == SP_CTRL_MODE_XOR) { + p[0] = COMPOSE_X (p[0], q[0], a); + p[1] = COMPOSE_X (p[1], q[1], a); + p[2] = COMPOSE_X (p[2], q[2], a); + q += 4; + p += 3; + } + } + } + ctrl->shown = TRUE; +} + +void SPCtrl::moveto (NR::Point const p) { + sp_canvas_item_affine_absolute (SP_CANVAS_ITEM (this), NR::Matrix(NR::translate (p))); +} diff --git a/src/display/sodipodi-ctrl.h b/src/display/sodipodi-ctrl.h new file mode 100644 index 000000000..c0e584ce2 --- /dev/null +++ b/src/display/sodipodi-ctrl.h @@ -0,0 +1,65 @@ +#ifndef INKSCAPE_CTRL_H +#define INKSCAPE_CTRL_H + +/* sodipodi-ctrl + * + * It is simply small square, which does not scale nor rotate + * + */ + +#include +#include "sp-canvas.h" +#include +#include + + + +#define SP_TYPE_CTRL (sp_ctrl_get_type ()) +#define SP_CTRL(obj) (GTK_CHECK_CAST ((obj), SP_TYPE_CTRL, SPCtrl)) +#define SP_CTRL_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), SP_TYPE_CTRL, SPCtrlClass)) +#define SP_IS_CTRL(obj) (GTK_CHECK_TYPE ((obj), SP_TYPE_CTRL)) +#define SP_IS_CTRL_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), SP_TYPE_CTRL)) + +typedef enum { + SP_CTRL_SHAPE_SQUARE, + SP_CTRL_SHAPE_DIAMOND, + SP_CTRL_SHAPE_CIRCLE, + SP_CTRL_SHAPE_CROSS, + SP_CTRL_SHAPE_BITMAP, + SP_CTRL_SHAPE_IMAGE +} SPCtrlShapeType; + + +typedef enum { + SP_CTRL_MODE_COLOR, + SP_CTRL_MODE_XOR +} SPCtrlModeType; + +struct SPCtrl : public SPCanvasItem{ + SPCtrlShapeType shape; + SPCtrlModeType mode; + GtkAnchorType anchor; + gint span; + guint defined : 1; + guint shown : 1; + guint build : 1; + guint filled : 1; + guint stroked : 1; + guint32 fill_color; + guint32 stroke_color; + + NRRectL box; /* NB! x1 & y1 are included */ + guchar *cache; + GdkPixbuf * pixbuf; + + void moveto(NR::Point const p); +}; + +struct SPCtrlClass : public SPCanvasItemClass{ +}; + + + +/* Standard Gtk function */ +GtkType sp_ctrl_get_type (void); +#endif diff --git a/src/display/sodipodi-ctrlrect.cpp b/src/display/sodipodi-ctrlrect.cpp new file mode 100644 index 000000000..05449f2bb --- /dev/null +++ b/src/display/sodipodi-ctrlrect.cpp @@ -0,0 +1,330 @@ +#define __INKSCAPE_CTRLRECT_C__ + +/* + * Simple non-transformed rectangle, usable for rubberband + * + * Author: + * Lauris Kaplinski + * bulia byak + * Carl Hetherington + * + * Copyright (C) 1999-2001 Lauris Kaplinski + * Copyright (C) 2000-2001 Ximian, Inc. + * + * Released under GNU GPL + * + */ + +#include "display-forward.h" +#include "sp-canvas-util.h" +#include "sodipodi-ctrlrect.h" + +/* + * Currently we do not have point method, as it should always be painted + * during some transformation, which takes care of events... + * + * Corner coords can be in any order - i.e. x1 < x0 is allowed + */ + +static void sp_ctrlrect_class_init(SPCtrlRectClass *c); +static void sp_ctrlrect_init(CtrlRect *ctrlrect); +static void sp_ctrlrect_destroy(GtkObject *object); + +static void sp_ctrlrect_update(SPCanvasItem *item, NR::Matrix const &affine, unsigned int flags); +static void sp_ctrlrect_render(SPCanvasItem *item, SPCanvasBuf *buf); + +static SPCanvasItemClass *parent_class; + +static const guint DASH_LENGTH = 4; + +GtkType sp_ctrlrect_get_type() +{ + static GtkType ctrlrect_type = 0; + + if (!ctrlrect_type) { + GtkTypeInfo ctrlrect_info = { + "SPCtrlRect", + sizeof(CtrlRect), + sizeof(SPCtrlRectClass), + (GtkClassInitFunc) sp_ctrlrect_class_init, + (GtkObjectInitFunc) sp_ctrlrect_init, + NULL, NULL, NULL + }; + ctrlrect_type = gtk_type_unique(SP_TYPE_CANVAS_ITEM, &ctrlrect_info); + } + return ctrlrect_type; +} + +static void sp_ctrlrect_class_init(SPCtrlRectClass *c) +{ + GtkObjectClass *object_class = (GtkObjectClass *) c; + SPCanvasItemClass *item_class = (SPCanvasItemClass *) c; + + parent_class = (SPCanvasItemClass*) gtk_type_class(sp_canvas_item_get_type()); + + object_class->destroy = sp_ctrlrect_destroy; + + item_class->update = sp_ctrlrect_update; + item_class->render = sp_ctrlrect_render; +} + +static void sp_ctrlrect_init(CtrlRect *cr) +{ + cr->init(); +} + +static void sp_ctrlrect_destroy(GtkObject *object) +{ + if (GTK_OBJECT_CLASS(parent_class)->destroy) { + (* GTK_OBJECT_CLASS(parent_class)->destroy)(object); + } +} + +/* FIXME: use definitions from somewhere else */ +#define RGBA_R(v) ((v) >> 24) +#define RGBA_G(v) (((v) >> 16) & 0xff) +#define RGBA_B(v) (((v) >> 8) & 0xff) +#define RGBA_A(v) ((v) & 0xff) +#define COMPOSE(b,f,a) ( ( ((guchar) b) * ((guchar) (0xff - a)) + ((guchar) ((b ^ ~f) + b/4 - (b>127? 63 : 0))) * ((guchar) a) ) / 0xff ) + +static void sp_ctrlrect_hline(SPCanvasBuf *buf, gint y, gint xs, gint xe, guint32 rgba, guint dashed) +{ + if (y >= buf->rect.y0 && y < buf->rect.y1) { + guint const r = RGBA_R(rgba); + guint const g = RGBA_G(rgba); + guint const b = RGBA_B(rgba); + guint const a = RGBA_A(rgba); + gint const x0 = MAX(buf->rect.x0, xs); + gint const x1 = MIN(buf->rect.x1, xe + 1); + guchar *p = buf->buf + (y - buf->rect.y0) * buf->buf_rowstride + (x0 - buf->rect.x0) * 3; + for (gint x = x0; x < x1; x++) { + if (!dashed || ((x / DASH_LENGTH) % 2)) { + p[0] = COMPOSE(p[0], r, a); + p[1] = COMPOSE(p[1], g, a); + p[2] = COMPOSE(p[2], b, a); + } + p += 3; + } + } +} + +static void sp_ctrlrect_vline(SPCanvasBuf *buf, gint x, gint ys, gint ye, guint32 rgba, guint dashed) +{ + if (x >= buf->rect.x0 && x < buf->rect.x1) { + guint const r = RGBA_R(rgba); + guint const g = RGBA_G(rgba); + guint const b = RGBA_B(rgba); + guint const a = RGBA_A(rgba); + gint const y0 = MAX(buf->rect.y0, ys); + gint const y1 = MIN(buf->rect.y1, ye + 1); + guchar *p = buf->buf + (y0 - buf->rect.y0) * buf->buf_rowstride + (x - buf->rect.x0) * 3; + for (gint y = y0; y < y1; y++) { + if (!dashed || ((y / DASH_LENGTH) % 2)) { + p[0] = COMPOSE(p[0], r, a); + p[1] = COMPOSE(p[1], g, a); + p[2] = COMPOSE(p[2], b, a); + } + p += buf->buf_rowstride; + } + } +} + +/** Fills the pixels in [xs, xe)*[ys,ye) clipped to the tile with rgb * a. */ +static void sp_ctrlrect_area(SPCanvasBuf *buf, gint xs, gint ys, gint xe, gint ye, guint32 rgba) +{ + guint const r = RGBA_R(rgba); + guint const g = RGBA_G(rgba); + guint const b = RGBA_B(rgba); + guint const a = RGBA_A(rgba); + gint const x0 = MAX(buf->rect.x0, xs); + gint const x1 = MIN(buf->rect.x1, xe + 1); + gint const y0 = MAX(buf->rect.y0, ys); + gint const y1 = MIN(buf->rect.y1, ye + 1); + for (gint y = y0; y < y1; y++) { + guchar *p = buf->buf + (y - buf->rect.y0) * buf->buf_rowstride + (x0 - buf->rect.x0) * 3; + for (gint x = x0; x < x1; x++) { + p[0] = COMPOSE(p[0], r, a); + p[1] = COMPOSE(p[1], g, a); + p[2] = COMPOSE(p[2], b, a); + p += 3; + } + } +} + +static void sp_ctrlrect_render(SPCanvasItem *item, SPCanvasBuf *buf) +{ + SP_CTRLRECT(item)->render(buf); +} + + +static void sp_ctrlrect_update(SPCanvasItem *item, NR::Matrix const &affine, unsigned int flags) +{ + SP_CTRLRECT(item)->update(affine, flags); +} + + + +void CtrlRect::init() +{ + _has_fill = false; + _dashed = false; + _shadow = 0; + + _area.x0 = _area.y0 = 0; + _area.x1 = _area.y1 = -1; + + _shadow_size = 0; + + _border_color = 0x000000ff; + _fill_color = 0xffffffff; + _shadow_color = 0x000000ff; +} + + +void CtrlRect::render(SPCanvasBuf *buf) +{ + if ((_area.x0 < buf->rect.x1) && + (_area.y0 < buf->rect.y1) && + ((_area.x1 + _shadow_size) >= buf->rect.x0) && + ((_area.y1 + _shadow_size) >= buf->rect.y0)) { + sp_canvas_prepare_buffer(buf); + + /* Top */ + sp_ctrlrect_hline(buf, _area.y0, _area.x0, _area.x1, _border_color, _dashed); + /* Bottom */ + sp_ctrlrect_hline(buf, _area.y1, _area.x0, _area.x1, _border_color, _dashed); + /* Left */ + sp_ctrlrect_vline(buf, _area.x0, _area.y0 + 1, _area.y1 - 1, _border_color, _dashed); + /* Right */ + sp_ctrlrect_vline(buf, _area.x1, _area.y0 + 1, _area.y1 - 1, _border_color, _dashed); + if (_shadow_size > 0) { + /* Right shadow */ + sp_ctrlrect_area(buf, _area.x1 + 1, _area.y0 + _shadow_size, + _area.x1 + _shadow_size, _area.y1 + _shadow_size, _shadow_color); + /* Bottom shadow */ + sp_ctrlrect_area(buf, _area.x0 + _shadow_size, _area.y1 + 1, + _area.x1, _area.y1 + _shadow_size, _shadow_color); + } + if (_has_fill) { + /* Fill */ + sp_ctrlrect_area(buf, _area.x0 + 1, _area.y0 + 1, + _area.x1 - 1, _area.y1 - 1, _fill_color); + } + } +} + + +void CtrlRect::update(NR::Matrix const &affine, unsigned int flags) +{ + if (((SPCanvasItemClass *) parent_class)->update) { + ((SPCanvasItemClass *) parent_class)->update(this, affine, flags); + } + + sp_canvas_item_reset_bounds(this); + + /* Request redraw old */ + if (!_has_fill) { + /* Top */ + sp_canvas_request_redraw(canvas, + _area.x0 - 1, _area.y0 - 1, + _area.x1 + 1, _area.y0 + 1); + /* Left */ + sp_canvas_request_redraw(canvas, + _area.x0 - 1, _area.y0 - 1, + _area.x0 + 1, _area.y1 + 1); + /* Right */ + sp_canvas_request_redraw(canvas, + _area.x1 - 1, _area.y0 - 1, + _area.x1 + _shadow_size + 1, _area.y1 + _shadow_size + 1); + /* Bottom */ + sp_canvas_request_redraw(canvas, + _area.x0 - 1, _area.y1 - 1, + _area.x1 + _shadow_size + 1, _area.y1 + _shadow_size + 1); + } else { + sp_canvas_request_redraw(canvas, + _area.x0 - 1, _area.y0 - 1, + _area.x1 + _shadow_size + 1, _area.y1 + _shadow_size + 1); + } + + NR::Rect bbox(_rect.min() * affine, _rect.max() * affine); + + _area.x0 = (int) floor(bbox.min()[NR::X] + 0.5); + _area.y0 = (int) floor(bbox.min()[NR::Y] + 0.5); + _area.x1 = (int) floor(bbox.max()[NR::X] + 0.5); + _area.y1 = (int) floor(bbox.max()[NR::Y] + 0.5); + + _shadow_size = _shadow; + + /* Request redraw new */ + if (!_has_fill) { + /* Top */ + sp_canvas_request_redraw(canvas, + _area.x0 - 1, _area.y0 - 1, + _area.x1 + 1, _area.y0 + 1); + /* Left */ + sp_canvas_request_redraw(canvas, + _area.x0 - 1, _area.y0 - 1, + _area.x0 + 1, _area.y1 + 1); + /* Right */ + sp_canvas_request_redraw(canvas, + _area.x1 - 1, _area.y0 - 1, + _area.x1 + _shadow_size + 1, _area.y1 + _shadow_size + 1); + /* Bottom */ + sp_canvas_request_redraw(canvas, + _area.x0 - 1, _area.y1 - 1, + _area.x1 + _shadow_size + 1, _area.y1 + _shadow_size + 1); + } else { + sp_canvas_request_redraw(canvas, + _area.x0 - 1, _area.y0 - 1, + _area.x1 + _shadow_size + 1, _area.y1 + _shadow_size + 1); + } + + x1 = _area.x0 - 1; + y1 = _area.y0 - 1; + x2 = _area.x1 + _shadow_size + 1; + y2 = _area.y1 + _shadow_size + 1; +} + + +void CtrlRect::setColor(guint32 b, bool h, guint f) +{ + _border_color = b; + _has_fill = h; + _fill_color = f; + _requestUpdate(); +} + +void CtrlRect::setShadow(int s, guint c) +{ + _shadow = s; + _shadow_color = c; + _requestUpdate(); +} + +void CtrlRect::setRectangle(NR::Rect const &r) +{ + _rect = r; + _requestUpdate(); +} + +void CtrlRect::setDashed(bool d) +{ + _dashed = d; + _requestUpdate(); +} + +void CtrlRect::_requestUpdate() +{ + sp_canvas_item_request_update(SP_CANVAS_ITEM(this)); +} + +/* + 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:textwidth=99 : diff --git a/src/display/sodipodi-ctrlrect.h b/src/display/sodipodi-ctrlrect.h new file mode 100644 index 000000000..dc931b7dc --- /dev/null +++ b/src/display/sodipodi-ctrlrect.h @@ -0,0 +1,70 @@ +#ifndef __INKSCAPE_CTRLRECT_H__ +#define __INKSCAPE_CTRLRECT_H__ + +/** + * \file sodipodi-ctrlrect.h + * \brief Simple non-transformed rectangle, usable for rubberband + * + * Authors: + * Lauris Kaplinski + * Carl Hetherington + * + * Copyright (C) 1999-2001 Lauris Kaplinski + * Copyright (C) 2000-2001 Ximian, Inc. + * + * Released under GNU GPL + * + */ + +#include +#include "sp-canvas.h" + +#define SP_TYPE_CTRLRECT (sp_ctrlrect_get_type ()) +#define SP_CTRLRECT(obj) (GTK_CHECK_CAST((obj), SP_TYPE_CTRLRECT, CtrlRect)) +#define SP_CTRLRECT_CLASS(c) (GTK_CHECK_CLASS_CAST((c), SP_TYPE_CTRLRECT, SPCtrlRectClass)) +#define SP_IS_CTRLRECT(obj) (GTK_CHECK_TYPE ((obj), SP_TYPE_CTRLRECT)) +#define SP_IS_CTRLRECT_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), SP_TYPE_CTRLRECT)) + +class CtrlRect : public SPCanvasItem +{ +public: + + void init(); + void setColor(guint32 b, bool h, guint f); + void setShadow(int s, guint c); + void setRectangle(NR::Rect const &r); + void setDashed(bool d); + + void render(SPCanvasBuf *buf); + void update(NR::Matrix const &affine, unsigned int flags); + +private: + void _requestUpdate(); + + NR::Rect _rect; + bool _has_fill; + bool _dashed; + NRRectL _area; + gint _shadow_size; + guint32 _border_color; + guint32 _fill_color; + guint32 _shadow_color; + int _shadow; +}; + +struct SPCtrlRectClass : public SPCanvasItemClass {}; + +GtkType sp_ctrlrect_get_type(); + +#endif + +/* + 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:textwidth=99 : diff --git a/src/display/sp-canvas-util.cpp b/src/display/sp-canvas-util.cpp new file mode 100644 index 000000000..e4f2c7b75 --- /dev/null +++ b/src/display/sp-canvas-util.cpp @@ -0,0 +1,307 @@ +#define __SP_CANVAS_UTILS_C__ + +/* + * Helper stuff for SPCanvas + * + * Authors: + * Lauris Kaplinski + * + * Copyright (C) 1999-2002 authors + * Copyright (C) 2001-2002 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + + +#include "libnr/nr-matrix-div.h" +#include "libnr/nr-pixops.h" +#include "sp-canvas-util.h" + +#include +#include +#include + +void +sp_canvas_update_bbox (SPCanvasItem *item, int x1, int y1, int x2, int y2) +{ + sp_canvas_request_redraw (item->canvas, (int)item->x1, (int)item->y1, (int)item->x2, (int)item->y2); + item->x1 = x1; + item->y1 = y1; + item->x2 = x2; + item->y2 = y2; + sp_canvas_request_redraw (item->canvas, (int)item->x1, (int)item->y1, (int)item->x2, (int)item->y2); +} + +void +sp_canvas_item_reset_bounds (SPCanvasItem *item) +{ + item->x1 = 0.0; + item->y1 = 0.0; + item->x2 = 0.0; + item->y2 = 0.0; +} + +void +sp_canvas_prepare_buffer (SPCanvasBuf *buf) +{ + if (buf->is_empty) { + sp_canvas_clear_buffer(buf); + buf->is_empty = false; + } +} + +void +sp_canvas_clear_buffer (SPCanvasBuf *buf) +{ + unsigned char r, g, b; + + r = (buf->bg_color >> 16) & 0xff; + g = (buf->bg_color >> 8) & 0xff; + b = buf->bg_color & 0xff; + + if ((r != g) || (r != b)) { + int x, y; + for (y = buf->rect.y0; y < buf->rect.y1; y++) { + unsigned char *p; + p = buf->buf + (y - buf->rect.y0) * buf->buf_rowstride; + for (x = buf->rect.x0; x < buf->rect.x1; x++) { + *p++ = r; + *p++ = g; + *p++ = b; + } + } + } else { + int y; + for (y = buf->rect.y0; y < buf->rect.y1; y++) { + memset (buf->buf + (y - buf->rect.y0) * buf->buf_rowstride, r, 3 * (buf->rect.x1 - buf->rect.x0)); + } + } +} + +NR::Matrix sp_canvas_item_i2p_affine (SPCanvasItem * item) +{ + g_assert (item != NULL); // this may be overly zealous - it is + // plausible that this gets called + // with item == 0 + + return item->xform; +} + +NR::Matrix sp_canvas_item_i2i_affine (SPCanvasItem * from, SPCanvasItem * to) +{ + g_assert (from != NULL); + g_assert (to != NULL); + + return sp_canvas_item_i2w_affine(from) / sp_canvas_item_i2w_affine(to); +} + +void sp_canvas_item_set_i2w_affine (SPCanvasItem * item, NR::Matrix const &i2w) +{ + g_assert (item != NULL); + + sp_canvas_item_affine_absolute(item, i2w / sp_canvas_item_i2w_affine(item->parent)); +} + +void sp_canvas_item_move_to_z (SPCanvasItem * item, gint z) +{ + g_assert (item != NULL); + + gint current_z = sp_canvas_item_order (item); + + if (current_z == -1) // not found in its parent + return; + + if (z == current_z) + return; + + if (z > current_z) + sp_canvas_item_raise (item, z - current_z); + + sp_canvas_item_lower (item, current_z - z); +} + +gint +sp_canvas_item_compare_z (SPCanvasItem * a, SPCanvasItem * b) +{ + const gint o_a = sp_canvas_item_order (a); + const gint o_b = sp_canvas_item_order (b); + + if (o_a > o_b) return -1; + if (o_a < o_b) return 1; + + return 0; +} + +// These two functions are used by canvasitems that use livarot (currently ctrlline and ctrlquadr) + +void +ctrl_run_A8_OR (raster_info &dest,void *data,int st,float vst,int en,float ven) +{ + union { + uint8_t comp[4]; + uint32_t col; + } tempCol; + if ( st >= en ) return; + tempCol.col=*(uint32_t*)data; + + unsigned int r, g, b, a; + r = NR_RGBA32_R (tempCol.col); + g = NR_RGBA32_G (tempCol.col); + b = NR_RGBA32_B (tempCol.col); + a = NR_RGBA32_A (tempCol.col); + if (a == 0) return; + + vst*=a; + ven*=a; + + if ( vst < 0 ) vst=0; + if ( vst > 255 ) vst=255; + if ( ven < 0 ) ven=0; + if ( ven > 255 ) ven=255; + float sv=vst; + float dv=ven-vst; + int len=en-st; + uint8_t* d=(uint8_t*)dest.buffer; + + d+=3*(st-dest.startPix); + if ( fabs(dv) < 0.001 ) { + if ( sv > 249.999 ) { + /* Simple copy */ + while (len > 0) { + d[0] = INK_COMPOSE (r, 255, d[0]); + d[1] = INK_COMPOSE (g, 255, d[1]); + d[2] = INK_COMPOSE (b, 255, d[2]); + d += 3; + len -= 1; + } + } else { + unsigned int c0_24=(int)sv; + c0_24&=0xFF; + while (len > 0) { + d[0] = INK_COMPOSE (r, c0_24, d[0]); + d[1] = INK_COMPOSE (g, c0_24, d[1]); + d[2] = INK_COMPOSE (b, c0_24, d[2]); + d += 3; + len -= 1; + } + } + } else { + if ( en <= st+1 ) { + sv=0.5*(vst+ven); + unsigned int c0_24=(int)sv; + c0_24&=0xFF; + d[0] = INK_COMPOSE (r, c0_24, d[0]); + d[1] = INK_COMPOSE (g, c0_24, d[1]); + d[2] = INK_COMPOSE (b, c0_24, d[2]); + } else { + dv/=len; + sv+=0.5*dv; // correction trapezoidale + sv*=65536; + dv*=65536; + int c0_24 = static_cast(CLAMP(sv, 0, 16777216)); + int s0_24 = static_cast(dv); + while (len > 0) { + unsigned int ca; + /* Draw */ + ca = c0_24 >> 16; + if ( ca > 255 ) ca=255; + d[0] = INK_COMPOSE (r, ca, d[0]); + d[1] = INK_COMPOSE (g, ca, d[1]); + d[2] = INK_COMPOSE (b, ca, d[2]); + d += 3; + c0_24 += s0_24; + c0_24 = CLAMP (c0_24, 0, 16777216); + len -= 1; + } + } + } +} + +void nr_pixblock_render_ctrl_rgba (Shape* theS,uint32_t color,NRRectL &area,char* destBuf,int stride) +{ + + theS->CalcBBox(); + float l=theS->leftX,r=theS->rightX,t=theS->topY,b=theS->bottomY; + int il,ir,it,ib; + il=(int)floor(l); + ir=(int)ceil(r); + it=(int)floor(t); + ib=(int)ceil(b); + +// printf("bbox %i %i %i %i render %i %i %i %i\n",il,it,ir,ib,area.x0,area.y0,area.x1,area.y1); + + if ( il >= area.x1 || ir <= area.x0 || it >= area.y1 || ib <= area.y0 ) return; + if ( il < area.x0 ) il=area.x0; + if ( it < area.y0 ) it=area.y0; + if ( ir > area.x1 ) ir=area.x1; + if ( ib > area.y1 ) ib=area.y1; + +/* // version par FloatLigne + int curPt; + float curY; + theS->BeginRaster(curY,curPt,1.0); + + FloatLigne* theI=new FloatLigne(); + IntLigne* theIL=new IntLigne(); + + theS->Scan(curY,curPt,(float)(it),1.0); + + char* mdata=(char*)destBuf; + uint32_t* ligStart=((uint32_t*)(mdata+(3*(il-area.x0)+stride*(it-area.y0)))); + for (int y=it;yReset(); + if ( y&0x00000003 ) { + theS->Scan(curY,curPt,((float)(y+1)),theI,false,1.0); + } else { + theS->Scan(curY,curPt,((float)(y+1)),theI,true,1.0); + } + theI->Flatten(); + theIL->Copy(theI); + + raster_info dest; + dest.startPix=il; + dest.endPix=ir; + dest.sth=il; + dest.stv=y; + dest.buffer=ligStart; + theIL->Raster(dest,&color,bpath_run_A8_OR); + ligStart=((uint32_t*)(((char*)ligStart)+stride)); + } + theS->EndRaster(); + delete theI; + delete theIL; */ + + // version par BitLigne directe + int curPt; + float curY; + theS->BeginQuickRaster(curY, curPt); + + BitLigne* theI[4]; + for (int i=0;i<4;i++) theI[i]=new BitLigne(il,ir); + IntLigne* theIL=new IntLigne(); + + theS->QuickScan(curY,curPt,(float)(it),true,0.25); + + char* mdata=(char*)destBuf; + uint32_t* ligStart=((uint32_t*)(mdata+(3*(il-area.x0)+stride*(it-area.y0)))); + for (int y=it;yReset(); + theS->QuickScan(curY,curPt,((float)(y+0.25)),fill_oddEven,theI[0],0.25); + theS->QuickScan(curY,curPt,((float)(y+0.5)),fill_oddEven,theI[1],0.25); + theS->QuickScan(curY,curPt,((float)(y+0.75)),fill_oddEven,theI[2],0.25); + theS->QuickScan(curY,curPt,((float)(y+1.0)),fill_oddEven,theI[3],0.25); + theIL->Copy(4,theI); + + raster_info dest; + dest.startPix=il; + dest.endPix=ir; + dest.sth=il; + dest.stv=y; + dest.buffer=ligStart; + theIL->Raster(dest,&color,ctrl_run_A8_OR); + ligStart=((uint32_t*)(((char*)ligStart)+stride)); + } + theS->EndQuickRaster(); + for (int i=0;i<4;i++) delete theI[i]; + delete theIL; +} diff --git a/src/display/sp-canvas-util.h b/src/display/sp-canvas-util.h new file mode 100644 index 000000000..b592ba1d0 --- /dev/null +++ b/src/display/sp-canvas-util.h @@ -0,0 +1,61 @@ +#ifndef __SP_CANVAS_UTILS_H__ +#define __SP_CANVAS_UTILS_H__ + +/* + * Helper stuff for SPCanvas + * + * Authors: + * Lauris Kaplinski + * + * Copyright (C) 1999-2002 authors + * Copyright (C) 2001-2002 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "sp-canvas.h" + +/* Miscellaneous utility & convenience functions for general canvas objects */ + +void sp_canvas_update_bbox (SPCanvasItem *item, int x1, int y1, int x2, int y2); +void sp_canvas_item_reset_bounds (SPCanvasItem *item); +void sp_canvas_prepare_buffer (SPCanvasBuf *buf); + +/* fill buffer with background color */ + +void +sp_canvas_clear_buffer (SPCanvasBuf * buf); + +/* get i2p (item to parent) affine transformation as general 6-element array */ + +NR::Matrix sp_canvas_item_i2p_affine (SPCanvasItem * item); + +/* get i2i (item to item) affine transformation as general 6-element array */ + +NR::Matrix sp_canvas_item_i2i_affine (SPCanvasItem * from, SPCanvasItem * to); + +/* set item affine matrix to achieve given i2w matrix */ + +void sp_canvas_item_set_i2w_affine (SPCanvasItem * item, NR::Matrix const & aff); + +void sp_canvas_item_move_to_z (SPCanvasItem * item, gint z); + +gint sp_canvas_item_compare_z (SPCanvasItem * a, SPCanvasItem * b); + +class Shape; +class raster_info; +void ctrl_run_A8_OR (raster_info &dest, void *data, int st, float vst, int en, float ven); +void nr_pixblock_render_ctrl_rgba (Shape* theS, uint32_t color, NRRectL &area, char* destBuf, int stride); + +#endif + +/* + 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:textwidth=99 : diff --git a/src/display/sp-canvas.cpp b/src/display/sp-canvas.cpp new file mode 100644 index 000000000..d1d7221f0 --- /dev/null +++ b/src/display/sp-canvas.cpp @@ -0,0 +1,2074 @@ +#define __SP_CANVAS_C__ + +/** \file + * Port of GnomeCanvas for Inkscape needs + * + * Authors: + * Federico Mena + * Raph Levien + * Lauris Kaplinski + * fred + * + * Copyright (C) 1998 The Free Software Foundation + * Copyright (C) 2002 Lauris Kaplinski + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include +#include + +#include +#include +#include "display-forward.h" +#include +#include +#include + +enum { + RENDERMODE_NORMAL, + RENDERMODE_NOAA, + RENDERMODE_OUTLINE +}; + +const gint sp_canvas_update_priority = G_PRIORITY_HIGH_IDLE; + +#define SP_CANVAS_WINDOW(c) (((GtkWidget *) (c))->window) + +enum { + SP_CANVAS_ITEM_VISIBLE = 1 << 7, + SP_CANVAS_ITEM_NEED_UPDATE = 1 << 8, + SP_CANVAS_ITEM_NEED_AFFINE = 1 << 9 +}; + +/** + * A group of Items. + */ +struct SPCanvasGroup { + SPCanvasItem item; + + GList *items, *last; +}; + +/** + * The SPCanvasGroup vtable. + */ +struct SPCanvasGroupClass { + SPCanvasItemClass parent_class; +}; + +/** + * The SPCanvas vtable. + */ +struct SPCanvasClass { + GtkWidgetClass parent_class; +}; + +static void group_add (SPCanvasGroup *group, SPCanvasItem *item); +static void group_remove (SPCanvasGroup *group, SPCanvasItem *item); + +/* SPCanvasItem */ + +enum {ITEM_EVENT, ITEM_LAST_SIGNAL}; + + +static void sp_canvas_request_update (SPCanvas *canvas); + +static void sp_canvas_item_class_init (SPCanvasItemClass *klass); +static void sp_canvas_item_init (SPCanvasItem *item); +static void sp_canvas_item_dispose (GObject *object); +static void sp_canvas_item_construct (SPCanvasItem *item, SPCanvasGroup *parent, const gchar *first_arg_name, va_list args); + +static int emit_event (SPCanvas *canvas, GdkEvent *event); + +static guint item_signals[ITEM_LAST_SIGNAL] = { 0 }; + +static GtkObjectClass *item_parent_class; + +/** + * Registers the SPCanvasItem class with Glib and returns its type number. + */ +GType +sp_canvas_item_get_type (void) +{ + static GType type = 0; + if (!type) { + static const GTypeInfo info = { + sizeof (SPCanvasItemClass), + NULL, NULL, + (GClassInitFunc) sp_canvas_item_class_init, + NULL, NULL, + sizeof (SPCanvasItem), + 0, + (GInstanceInitFunc) sp_canvas_item_init, + NULL + }; + type = g_type_register_static (GTK_TYPE_OBJECT, "SPCanvasItem", &info, (GTypeFlags)0); + } + + return type; +} + +/** + * Initializes the SPCanvasItem vtable and the "event" signal. + */ +static void +sp_canvas_item_class_init (SPCanvasItemClass *klass) +{ + GObjectClass *object_class = (GObjectClass *) klass; + + /* fixme: Derive from GObject */ + item_parent_class = (GtkObjectClass*)gtk_type_class (GTK_TYPE_OBJECT); + + item_signals[ITEM_EVENT] = g_signal_new ("event", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (SPCanvasItemClass, event), + NULL, NULL, + sp_marshal_BOOLEAN__POINTER, + G_TYPE_BOOLEAN, 1, + GDK_TYPE_EVENT); + + object_class->dispose = sp_canvas_item_dispose; +} + +/** + * Callback for initialization of SPCanvasItem. + */ +static void +sp_canvas_item_init (SPCanvasItem *item) +{ + item->flags |= SP_CANVAS_ITEM_VISIBLE; + item->xform = NR::Matrix(NR::identity()); +} + +/** + * Constructs new SPCanvasItem on SPCanvasGroup. + */ +SPCanvasItem * +sp_canvas_item_new (SPCanvasGroup *parent, GtkType type, const gchar *first_arg_name, ...) +{ + va_list args; + + g_return_val_if_fail (parent != NULL, NULL); + g_return_val_if_fail (SP_IS_CANVAS_GROUP (parent), NULL); + g_return_val_if_fail (gtk_type_is_a (type, sp_canvas_item_get_type ()), NULL); + + SPCanvasItem *item = SP_CANVAS_ITEM (gtk_type_new (type)); + + va_start (args, first_arg_name); + sp_canvas_item_construct (item, parent, first_arg_name, args); + va_end (args); + + return item; +} + +/** + * Sets up the newly created SPCanvasItem. + * + * We make it static for encapsulation reasons since it was nowhere used. + */ +static void +sp_canvas_item_construct (SPCanvasItem *item, SPCanvasGroup *parent, const gchar *first_arg_name, va_list args) +{ + g_return_if_fail (SP_IS_CANVAS_GROUP (parent)); + g_return_if_fail (SP_IS_CANVAS_ITEM (item)); + + item->parent = SP_CANVAS_ITEM (parent); + item->canvas = item->parent->canvas; + + g_object_set_valist (G_OBJECT (item), first_arg_name, args); + + group_add (SP_CANVAS_GROUP (item->parent), item); + + sp_canvas_item_request_update (item); + sp_canvas_request_redraw (item->canvas, (int)(item->x1), (int)(item->y1), (int)(item->x2 + 1), (int)(item->y2 + 1)); + item->canvas->need_repick = TRUE; +} + +/** + * Helper function that requests redraw only if item's visible flag is set. + */ +static void +redraw_if_visible (SPCanvasItem *item) +{ + if (item->flags & SP_CANVAS_ITEM_VISIBLE) { + sp_canvas_request_redraw (item->canvas, (int)(item->x1), (int)(item->y1), (int)(item->x2 + 1), (int)(item->y2 + 1)); + } +} + +/** + * Callback that removes item from all referers and destroys it. + */ +static void +sp_canvas_item_dispose (GObject *object) +{ + SPCanvasItem *item = SP_CANVAS_ITEM (object); + + redraw_if_visible (item); + item->flags &= ~SP_CANVAS_ITEM_VISIBLE; + + if (item == item->canvas->current_item) { + item->canvas->current_item = NULL; + item->canvas->need_repick = TRUE; + } + + if (item == item->canvas->new_current_item) { + item->canvas->new_current_item = NULL; + item->canvas->need_repick = TRUE; + } + + if (item == item->canvas->grabbed_item) { + item->canvas->grabbed_item = NULL; + gdk_pointer_ungrab (GDK_CURRENT_TIME); + } + + if (item == item->canvas->focused_item) + item->canvas->focused_item = NULL; + + if (item->parent) { + group_remove (SP_CANVAS_GROUP (item->parent), item); + } + + G_OBJECT_CLASS (item_parent_class)->dispose (object); +} + +/** + * Helper function to update item and its children. + * + * NB! affine is parent2canvas. + */ +static void +sp_canvas_item_invoke_update (SPCanvasItem *item, NR::Matrix const &affine, unsigned int flags) +{ + /* Apply the child item's transform */ + NR::Matrix child_affine = item->xform * affine; + + /* apply object flags to child flags */ + int child_flags = flags & ~SP_CANVAS_UPDATE_REQUESTED; + + if (item->flags & SP_CANVAS_ITEM_NEED_UPDATE) + child_flags |= SP_CANVAS_UPDATE_REQUESTED; + + if (item->flags & SP_CANVAS_ITEM_NEED_AFFINE) + child_flags |= SP_CANVAS_UPDATE_AFFINE; + + if (child_flags & (SP_CANVAS_UPDATE_REQUESTED | SP_CANVAS_UPDATE_AFFINE)) { + if (SP_CANVAS_ITEM_GET_CLASS (item)->update) + SP_CANVAS_ITEM_GET_CLASS (item)->update (item, child_affine, child_flags); + } + + GTK_OBJECT_UNSET_FLAGS (item, SP_CANVAS_ITEM_NEED_UPDATE); + GTK_OBJECT_UNSET_FLAGS (item, SP_CANVAS_ITEM_NEED_AFFINE); +} + +/** + * Helper function to invoke the point method of the item. + * + * The argument x, y should be in the parent's item-relative coordinate + * system. This routine applies the inverse of the item's transform, + * maintaining the affine invariant. + */ +static double +sp_canvas_item_invoke_point (SPCanvasItem *item, NR::Point p, SPCanvasItem **actual_item) +{ + if (SP_CANVAS_ITEM_GET_CLASS (item)->point) + return SP_CANVAS_ITEM_GET_CLASS (item)->point (item, p, actual_item); + + return NR_HUGE; +} + +/** + * Makes the item's affine transformation matrix be equal to the specified + * matrix. + * + * @item: A canvas item. + * @affine: An affine transformation matrix. + */ +void +sp_canvas_item_affine_absolute (SPCanvasItem *item, NR::Matrix const& affine) +{ + item->xform = affine; + + if (!(item->flags & SP_CANVAS_ITEM_NEED_AFFINE)) { + item->flags |= SP_CANVAS_ITEM_NEED_AFFINE; + if (item->parent != NULL) { + sp_canvas_item_request_update (item->parent); + } else { + sp_canvas_request_update (item->canvas); + } + } + + item->canvas->need_repick = TRUE; +} + +/** + * Convenience function to reorder items in a group's child list. + * + * This puts the specified link after the "before" link. + */ +static void +put_item_after (GList *link, GList *before) +{ + if (link == before) + return; + + SPCanvasGroup *parent = SP_CANVAS_GROUP (SP_CANVAS_ITEM (link->data)->parent); + + if (before == NULL) { + if (link == parent->items) return; + + link->prev->next = link->next; + + if (link->next) { + link->next->prev = link->prev; + } else { + parent->last = link->prev; + } + + link->prev = before; + link->next = parent->items; + link->next->prev = link; + parent->items = link; + } else { + if ((link == parent->last) && (before == parent->last->prev)) + return; + + if (link->next) + link->next->prev = link->prev; + + if (link->prev) + link->prev->next = link->next; + else { + parent->items = link->next; + parent->items->prev = NULL; + } + + link->prev = before; + link->next = before->next; + + link->prev->next = link; + + if (link->next) + link->next->prev = link; + else + parent->last = link; + } +} + + +/** + * Raises the item in its parent's stack by the specified number of positions. + * + * \param item A canvas item. + * \param positions Number of steps to raise the item. + * + * If the number of positions is greater than the distance to the top of the + * stack, then the item is put at the top. + */ +void +sp_canvas_item_raise (SPCanvasItem *item, int positions) +{ + g_return_if_fail (item != NULL); + g_return_if_fail (SP_IS_CANVAS_ITEM (item)); + g_return_if_fail (positions >= 0); + + if (!item->parent || positions == 0) + return; + + SPCanvasGroup *parent = SP_CANVAS_GROUP (item->parent); + GList *link = g_list_find (parent->items, item); + g_assert (link != NULL); + + GList *before; + for (before = link; positions && before; positions--) + before = before->next; + + if (!before) + before = parent->last; + + put_item_after (link, before); + + redraw_if_visible (item); + item->canvas->need_repick = TRUE; +} + + +/** + * Lowers the item in its parent's stack by the specified number of positions. + * + * \param item A canvas item. + * \param positions Number of steps to lower the item. + * + * If the number of positions is greater than the distance to the bottom of the + * stack, then the item is put at the bottom. + **/ +void +sp_canvas_item_lower (SPCanvasItem *item, int positions) +{ + g_return_if_fail (item != NULL); + g_return_if_fail (SP_IS_CANVAS_ITEM (item)); + g_return_if_fail (positions >= 1); + + if (!item->parent || positions == 0) + return; + + SPCanvasGroup *parent = SP_CANVAS_GROUP (item->parent); + GList *link = g_list_find (parent->items, item); + g_assert (link != NULL); + + GList *before; + if (link->prev) + for (before = link->prev; positions && before; positions--) + before = before->prev; + else + before = NULL; + + put_item_after (link, before); + + redraw_if_visible (item); + item->canvas->need_repick = TRUE; +} + +/** + * Sets visible flag on item and requests a redraw. + */ +void +sp_canvas_item_show (SPCanvasItem *item) +{ + g_return_if_fail (item != NULL); + g_return_if_fail (SP_IS_CANVAS_ITEM (item)); + + if (item->flags & SP_CANVAS_ITEM_VISIBLE) + return; + + item->flags |= SP_CANVAS_ITEM_VISIBLE; + + sp_canvas_request_redraw (item->canvas, (int)(item->x1), (int)(item->y1), (int)(item->x2 + 1), (int)(item->y2 + 1)); + item->canvas->need_repick = TRUE; +} + +/** + * Clears visible flag on item and requests a redraw. + */ +void +sp_canvas_item_hide (SPCanvasItem *item) +{ + g_return_if_fail (item != NULL); + g_return_if_fail (SP_IS_CANVAS_ITEM (item)); + + if (!(item->flags & SP_CANVAS_ITEM_VISIBLE)) + return; + + item->flags &= ~SP_CANVAS_ITEM_VISIBLE; + + sp_canvas_request_redraw (item->canvas, (int)item->x1, (int)item->y1, (int)(item->x2 + 1), (int)(item->y2 + 1)); + item->canvas->need_repick = TRUE; +} + +/** + * Grab item under cursor. + * + * \pre !canvas->grabbed_item && item->flags & SP_CANVAS_ITEM_VISIBLE + */ +int +sp_canvas_item_grab (SPCanvasItem *item, guint event_mask, GdkCursor *cursor, guint32 etime) +{ + g_return_val_if_fail (item != NULL, -1); + g_return_val_if_fail (SP_IS_CANVAS_ITEM (item), -1); + g_return_val_if_fail (GTK_WIDGET_MAPPED (item->canvas), -1); + + if (item->canvas->grabbed_item) + return -1; + + if (!(item->flags & SP_CANVAS_ITEM_VISIBLE)) + return -1; + + /* fixme: Top hack (Lauris) */ + /* fixme: If we add key masks to event mask, Gdk will abort (Lauris) */ + /* fixme: But Canvas actualle does get key events, so all we need is routing these here */ + gdk_pointer_grab (SP_CANVAS_WINDOW (item->canvas), FALSE, + (GdkEventMask)(event_mask & (~(GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK))), + NULL, cursor, etime); + + item->canvas->grabbed_item = item; + item->canvas->grabbed_event_mask = event_mask; + item->canvas->current_item = item; /* So that events go to the grabbed item */ + + return 0; +} + +/** + * Ungrabs the item, which must have been grabbed in the canvas, and ungrabs the + * mouse. + * + * \param item A canvas item that holds a grab. + * \param etime The timestamp for ungrabbing the mouse. + */ +void +sp_canvas_item_ungrab (SPCanvasItem *item, guint32 etime) +{ + g_return_if_fail (item != NULL); + g_return_if_fail (SP_IS_CANVAS_ITEM (item)); + + if (item->canvas->grabbed_item != item) + return; + + item->canvas->grabbed_item = NULL; + + gdk_pointer_ungrab (etime); +} + +/** + * Returns the product of all transformation matrices from the root item down + * to the item. + */ +NR::Matrix sp_canvas_item_i2w_affine(SPCanvasItem const *item) +{ + g_assert (SP_IS_CANVAS_ITEM (item)); // should we get this? + + NR::Matrix affine = NR::identity(); + + while (item) { + affine *= item->xform; + item = item->parent; + } + return affine; +} + +/** + * Helper that returns true iff item is descendant of parent. + */ +static bool is_descendant(SPCanvasItem const *item, SPCanvasItem const *parent) +{ + while (item) { + if (item == parent) + return true; + item = item->parent; + } + + return false; +} + +/** + * Focus canvas, and item under cursor if it is not already focussed. + */ +void +sp_canvas_item_grab_focus (SPCanvasItem *item) +{ + g_return_if_fail (item != NULL); + g_return_if_fail (SP_IS_CANVAS_ITEM (item)); + g_return_if_fail (GTK_WIDGET_CAN_FOCUS (GTK_WIDGET (item->canvas))); + + SPCanvasItem *focused_item = item->canvas->focused_item; + + if (focused_item) { + GdkEvent ev; + ev.focus_change.type = GDK_FOCUS_CHANGE; + ev.focus_change.window = SP_CANVAS_WINDOW (item->canvas); + ev.focus_change.send_event = FALSE; + ev.focus_change.in = FALSE; + + emit_event (item->canvas, &ev); + } + + item->canvas->focused_item = item; + gtk_widget_grab_focus (GTK_WIDGET (item->canvas)); + + if (focused_item) { + GdkEvent ev; + ev.focus_change.type = GDK_FOCUS_CHANGE; + ev.focus_change.window = SP_CANVAS_WINDOW (item->canvas); + ev.focus_change.send_event = FALSE; + ev.focus_change.in = TRUE; + + emit_event (item->canvas, &ev); + } +} + +/** + * Requests that the canvas queue an update for the specified item. + * + * To be used only by item implementations. + */ +void +sp_canvas_item_request_update (SPCanvasItem *item) +{ + if (item->flags & SP_CANVAS_ITEM_NEED_UPDATE) + return; + + item->flags |= SP_CANVAS_ITEM_NEED_UPDATE; + + if (item->parent != NULL) { + /* Recurse up the tree */ + sp_canvas_item_request_update (item->parent); + } else { + /* Have reached the top of the tree, make sure the update call gets scheduled. */ + sp_canvas_request_update (item->canvas); + } +} + +/** + * Returns position of item in group. + */ +gint sp_canvas_item_order (SPCanvasItem * item) +{ + return g_list_index (SP_CANVAS_GROUP (item->parent)->items, item); +} + +/* SPCanvasGroup */ + +static void sp_canvas_group_class_init (SPCanvasGroupClass *klass); +static void sp_canvas_group_init (SPCanvasGroup *group); +static void sp_canvas_group_destroy (GtkObject *object); + +static void sp_canvas_group_update (SPCanvasItem *item, NR::Matrix const &affine, unsigned int flags); +static double sp_canvas_group_point (SPCanvasItem *item, NR::Point p, SPCanvasItem **actual_item); +static void sp_canvas_group_render (SPCanvasItem *item, SPCanvasBuf *buf); + +static SPCanvasItemClass *group_parent_class; + +/** + * Registers SPCanvasGroup class with Gtk and returns its type number. + */ +GtkType +sp_canvas_group_get_type (void) +{ + static GtkType group_type = 0; + + if (!group_type) { + static const GtkTypeInfo group_info = { + "SPCanvasGroup", + sizeof (SPCanvasGroup), + sizeof (SPCanvasGroupClass), + (GtkClassInitFunc) sp_canvas_group_class_init, + (GtkObjectInitFunc) sp_canvas_group_init, + NULL, NULL, NULL + }; + + group_type = gtk_type_unique (sp_canvas_item_get_type (), &group_info); + } + + return group_type; +} + +/** + * Class initialization function for SPCanvasGroupClass + */ +static void +sp_canvas_group_class_init (SPCanvasGroupClass *klass) +{ + GtkObjectClass *object_class = (GtkObjectClass *) klass; + SPCanvasItemClass *item_class = (SPCanvasItemClass *) klass; + + group_parent_class = (SPCanvasItemClass*)gtk_type_class (sp_canvas_item_get_type ()); + + object_class->destroy = sp_canvas_group_destroy; + + item_class->update = sp_canvas_group_update; + item_class->render = sp_canvas_group_render; + item_class->point = sp_canvas_group_point; +} + +/** + * Callback. Empty. + */ +static void +sp_canvas_group_init (SPCanvasGroup */*group*/) +{ + /* Nothing here */ +} + +/** + * Callback that destroys all items in group and calls group's virtual + * destroy() function. + */ +static void +sp_canvas_group_destroy (GtkObject *object) +{ + g_return_if_fail (object != NULL); + g_return_if_fail (SP_IS_CANVAS_GROUP (object)); + + const SPCanvasGroup *group = SP_CANVAS_GROUP (object); + + GList *list = group->items; + while (list) { + SPCanvasItem *child = (SPCanvasItem *)list->data; + list = list->next; + + gtk_object_destroy (GTK_OBJECT (child)); + } + + if (GTK_OBJECT_CLASS (group_parent_class)->destroy) + (* GTK_OBJECT_CLASS (group_parent_class)->destroy) (object); +} + +/** + * Update handler for canvas groups + */ +static void +sp_canvas_group_update (SPCanvasItem *item, NR::Matrix const &affine, unsigned int flags) +{ + const SPCanvasGroup *group = SP_CANVAS_GROUP (item); + NR::ConvexHull corners(NR::Point(0, 0)); + bool empty=true; + + for (GList *list = group->items; list; list = list->next) { + SPCanvasItem *i = (SPCanvasItem *)list->data; + + sp_canvas_item_invoke_update (i, affine, flags); + + if ( i->x2 > i->x1 && i->y2 > i->y1 ) { + if (empty) { + corners = NR::ConvexHull(NR::Point(i->x1, i->y1)); + empty = false; + } else { + corners.add(NR::Point(i->x1, i->y1)); + } + corners.add(NR::Point(i->x2, i->y2)); + } + } + + NR::Rect const &bounds = corners.bounds(); + item->x1 = bounds.min()[NR::X]; + item->y1 = bounds.min()[NR::Y]; + item->x2 = bounds.max()[NR::X]; + item->y2 = bounds.max()[NR::Y]; +} + +/** + * Point handler for canvas groups. + */ +static double +sp_canvas_group_point (SPCanvasItem *item, NR::Point p, SPCanvasItem **actual_item) +{ + const SPCanvasGroup *group = SP_CANVAS_GROUP (item); + const double x = p[NR::X]; + const double y = p[NR::Y]; + int x1 = (int)(x - item->canvas->close_enough); + int y1 = (int)(y - item->canvas->close_enough); + int x2 = (int)(x + item->canvas->close_enough); + int y2 = (int)(y + item->canvas->close_enough); + + double best = 0.0; + *actual_item = NULL; + + double dist = 0.0; + + for (GList *list = group->items; list; list = list->next) { + SPCanvasItem *child = (SPCanvasItem *)list->data; + + if ((child->x1 <= x2) && (child->y1 <= y2) && (child->x2 >= x1) && (child->y2 >= y1)) { + SPCanvasItem *point_item = NULL; /* cater for incomplete item implementations */ + + int has_point; + if ((child->flags & SP_CANVAS_ITEM_VISIBLE) && SP_CANVAS_ITEM_GET_CLASS (child)->point) { + dist = sp_canvas_item_invoke_point (child, p, &point_item); + has_point = TRUE; + } else + has_point = FALSE; + + if (has_point && point_item && ((int) (dist + 0.5) <= item->canvas->close_enough)) { + best = dist; + *actual_item = point_item; + } + } + } + + return best; +} + +/** + * Renders all visible canvas group items in buf rectangle. + */ +static void +sp_canvas_group_render (SPCanvasItem *item, SPCanvasBuf *buf) +{ + const SPCanvasGroup *group = SP_CANVAS_GROUP (item); + + for (GList *list = group->items; list; list = list->next) { + SPCanvasItem *child = (SPCanvasItem *)list->data; + if (child->flags & SP_CANVAS_ITEM_VISIBLE) { + if ((child->x1 < buf->rect.x1) && + (child->y1 < buf->rect.y1) && + (child->x2 > buf->rect.x0) && + (child->y2 > buf->rect.y0)) { + if (SP_CANVAS_ITEM_GET_CLASS (child)->render) + SP_CANVAS_ITEM_GET_CLASS (child)->render (child, buf); + } + } + } +} + +/** + * Adds an item to a canvas group. + */ +static void +group_add (SPCanvasGroup *group, SPCanvasItem *item) +{ + gtk_object_ref (GTK_OBJECT (item)); + gtk_object_sink (GTK_OBJECT (item)); + + if (!group->items) { + group->items = g_list_append (group->items, item); + group->last = group->items; + } else { + group->last = g_list_append (group->last, item)->next; + } + + sp_canvas_item_request_update (item); +} + +/** + * Removes an item from a canvas group + */ +static void +group_remove (SPCanvasGroup *group, SPCanvasItem *item) +{ + g_return_if_fail (group != NULL); + g_return_if_fail (SP_IS_CANVAS_GROUP (group)); + g_return_if_fail (item != NULL); + + for (GList *children = group->items; children; children = children->next) { + if (children->data == item) { + + /* Unparent the child */ + + item->parent = NULL; + gtk_object_unref (GTK_OBJECT (item)); + + /* Remove it from the list */ + + if (children == group->last) group->last = children->prev; + + group->items = g_list_remove_link (group->items, children); + g_list_free (children); + break; + } + } +} + +/* SPCanvas */ + +static void sp_canvas_class_init (SPCanvasClass *klass); +static void sp_canvas_init (SPCanvas *canvas); +static void sp_canvas_destroy (GtkObject *object); + +static void sp_canvas_realize (GtkWidget *widget); +static void sp_canvas_unrealize (GtkWidget *widget); + +static void sp_canvas_size_request (GtkWidget *widget, GtkRequisition *req); +static void sp_canvas_size_allocate (GtkWidget *widget, GtkAllocation *allocation); + +static gint sp_canvas_button (GtkWidget *widget, GdkEventButton *event); +static gint sp_canvas_scroll (GtkWidget *widget, GdkEventScroll *event); +static gint sp_canvas_motion (GtkWidget *widget, GdkEventMotion *event); +static gint sp_canvas_expose (GtkWidget *widget, GdkEventExpose *event); +static gint sp_canvas_key (GtkWidget *widget, GdkEventKey *event); +static gint sp_canvas_crossing (GtkWidget *widget, GdkEventCrossing *event); +static gint sp_canvas_focus_in (GtkWidget *widget, GdkEventFocus *event); +static gint sp_canvas_focus_out (GtkWidget *widget, GdkEventFocus *event); + +static GtkWidgetClass *canvas_parent_class; + +void sp_canvas_resize_tiles(SPCanvas* canvas,int nl,int nt,int nr,int nb); +void sp_canvas_dirty_rect(SPCanvas* canvas,int nl,int nt,int nr,int nb); + +/** + * Registers the SPCanvas class if necessary, and returns the type ID + * associated to it. + * + * \return The type ID of the SPCanvas class. + **/ +GtkType +sp_canvas_get_type (void) +{ + static GtkType canvas_type = 0; + + if (!canvas_type) { + static const GtkTypeInfo canvas_info = { + "SPCanvas", + sizeof (SPCanvas), + sizeof (SPCanvasClass), + (GtkClassInitFunc) sp_canvas_class_init, + (GtkObjectInitFunc) sp_canvas_init, + NULL, NULL, NULL + }; + + canvas_type = gtk_type_unique (GTK_TYPE_WIDGET, &canvas_info); + } + + return canvas_type; +} + +/** + * Class initialization function for SPCanvasClass. + */ +static void +sp_canvas_class_init (SPCanvasClass *klass) +{ + GtkObjectClass *object_class = (GtkObjectClass *) klass; + GtkWidgetClass *widget_class = (GtkWidgetClass *) klass; + + canvas_parent_class = (GtkWidgetClass *)gtk_type_class (GTK_TYPE_WIDGET); + + object_class->destroy = sp_canvas_destroy; + + widget_class->realize = sp_canvas_realize; + widget_class->unrealize = sp_canvas_unrealize; + widget_class->size_request = sp_canvas_size_request; + widget_class->size_allocate = sp_canvas_size_allocate; + widget_class->button_press_event = sp_canvas_button; + widget_class->button_release_event = sp_canvas_button; + widget_class->motion_notify_event = sp_canvas_motion; + widget_class->scroll_event = sp_canvas_scroll; + widget_class->expose_event = sp_canvas_expose; + widget_class->key_press_event = sp_canvas_key; + widget_class->key_release_event = sp_canvas_key; + widget_class->enter_notify_event = sp_canvas_crossing; + widget_class->leave_notify_event = sp_canvas_crossing; + widget_class->focus_in_event = sp_canvas_focus_in; + widget_class->focus_out_event = sp_canvas_focus_out; +} + +/** + * Callback: object initialization for SPCanvas. + */ +static void +sp_canvas_init (SPCanvas *canvas) +{ + GTK_WIDGET_UNSET_FLAGS (canvas, GTK_NO_WINDOW); + GTK_WIDGET_UNSET_FLAGS (canvas, GTK_DOUBLE_BUFFERED); + GTK_WIDGET_SET_FLAGS (canvas, GTK_CAN_FOCUS); + + canvas->pick_event.type = GDK_LEAVE_NOTIFY; + canvas->pick_event.crossing.x = 0; + canvas->pick_event.crossing.y = 0; + + /* Create the root item as a special case */ + canvas->root = SP_CANVAS_ITEM (gtk_type_new (sp_canvas_group_get_type ())); + canvas->root->canvas = canvas; + + gtk_object_ref (GTK_OBJECT (canvas->root)); + gtk_object_sink (GTK_OBJECT (canvas->root)); + + canvas->need_repick = TRUE; + + canvas->tiles=NULL; + canvas->tLeft=canvas->tTop=canvas->tRight=canvas->tBottom=0; + canvas->tileH=canvas->tileV=0; +} + +/** + * Convenience function to remove the idle handler of a canvas. + */ +static void +remove_idle (SPCanvas *canvas) +{ + if (canvas->idle_id) { + gtk_idle_remove (canvas->idle_id); + canvas->idle_id = 0; + } +} + +/* + * Removes the transient state of the canvas (idle handler, grabs). + */ +static void +shutdown_transients (SPCanvas *canvas) +{ + /* We turn off the need_redraw flag, since if the canvas is mapped again + * it will request a redraw anyways. We do not turn off the need_update + * flag, though, because updates are not queued when the canvas remaps + * itself. + */ + if (canvas->need_redraw) { + canvas->need_redraw = FALSE; + } + if ( canvas->tiles ) free(canvas->tiles); + canvas->tiles=NULL; + canvas->tLeft=canvas->tTop=canvas->tRight=canvas->tBottom=0; + canvas->tileH=canvas->tileV=0; + + if (canvas->grabbed_item) { + canvas->grabbed_item = NULL; + gdk_pointer_ungrab (GDK_CURRENT_TIME); + } + + remove_idle (canvas); +} + +/** + * Destroy handler for SPCanvas. + */ +static void +sp_canvas_destroy (GtkObject *object) +{ + SPCanvas *canvas = SP_CANVAS (object); + + if (canvas->root) { + gtk_object_unref (GTK_OBJECT (canvas->root)); + canvas->root = NULL; + } + + shutdown_transients (canvas); + + if (GTK_OBJECT_CLASS (canvas_parent_class)->destroy) + (* GTK_OBJECT_CLASS (canvas_parent_class)->destroy) (object); +} + +/** + * Returns new canvas as widget. + */ +GtkWidget * +sp_canvas_new_aa (void) +{ + SPCanvas *canvas = (SPCanvas *)gtk_type_new (sp_canvas_get_type ()); + + return (GtkWidget *) canvas; +} + +/** + * The canvas widget's realize callback. + */ +static void +sp_canvas_realize (GtkWidget *widget) +{ + SPCanvas *canvas = SP_CANVAS (widget); + + GdkWindowAttr attributes; + attributes.window_type = GDK_WINDOW_CHILD; + attributes.x = widget->allocation.x; + attributes.y = widget->allocation.y; + attributes.width = widget->allocation.width; + attributes.height = widget->allocation.height; + attributes.wclass = GDK_INPUT_OUTPUT; + attributes.visual = gdk_rgb_get_visual (); + attributes.colormap = gdk_rgb_get_cmap (); + attributes.event_mask = (gtk_widget_get_events (widget) | + GDK_EXPOSURE_MASK | + GDK_BUTTON_PRESS_MASK | + GDK_BUTTON_RELEASE_MASK | + GDK_POINTER_MOTION_MASK | + GDK_PROXIMITY_IN_MASK | + GDK_PROXIMITY_OUT_MASK | + GDK_KEY_PRESS_MASK | + GDK_KEY_RELEASE_MASK | + GDK_ENTER_NOTIFY_MASK | + GDK_LEAVE_NOTIFY_MASK | + GDK_FOCUS_CHANGE_MASK); + gint attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP; + + widget->window = gdk_window_new (gtk_widget_get_parent_window (widget), &attributes, attributes_mask); + gdk_window_set_user_data (widget->window, widget); + gtk_widget_set_events(widget, attributes.event_mask); + + GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED); + + canvas->pixmap_gc = gdk_gc_new (SP_CANVAS_WINDOW (canvas)); +} + +/** + * The canvas widget's unrealize callback. + */ +static void +sp_canvas_unrealize (GtkWidget *widget) +{ + SPCanvas *canvas = SP_CANVAS (widget); + + shutdown_transients (canvas); + + gdk_gc_destroy (canvas->pixmap_gc); + canvas->pixmap_gc = NULL; + + if (GTK_WIDGET_CLASS (canvas_parent_class)->unrealize) + (* GTK_WIDGET_CLASS (canvas_parent_class)->unrealize) (widget); +} + +/** + * The canvas widget's size_request callback. + */ +static void +sp_canvas_size_request (GtkWidget *widget, GtkRequisition *req) +{ + static_cast(SP_CANVAS (widget)); + + req->width = 256; + req->height = 256; +} + +/** + * The canvas widget's size_allocate callback. + */ +static void +sp_canvas_size_allocate (GtkWidget *widget, GtkAllocation *allocation) +{ + SPCanvas *canvas = SP_CANVAS (widget); + + /* Schedule redraw of new region */ + sp_canvas_resize_tiles(canvas,canvas->x0,canvas->y0,canvas->x0+allocation->width,canvas->y0+allocation->height); + if (allocation->width > widget->allocation.width) { + sp_canvas_request_redraw (canvas, + canvas->x0 + widget->allocation.width, + 0, + canvas->x0 + allocation->width, + canvas->y0 + allocation->height); + } + if (allocation->height > widget->allocation.height) { + sp_canvas_request_redraw (canvas, + 0, + canvas->y0 + widget->allocation.height, + canvas->x0 + allocation->width, + canvas->y0 + allocation->height); + } + + widget->allocation = *allocation; + + if (GTK_WIDGET_REALIZED (widget)) { + gdk_window_move_resize (widget->window, + widget->allocation.x, widget->allocation.y, + widget->allocation.width, widget->allocation.height); + } +} + +/** + * Helper that emits an event for an item in the canvas, be it the current + * item, grabbed item, or focused item, as appropriate. + */ +static int +emit_event (SPCanvas *canvas, GdkEvent *event) +{ + guint mask; + + if (canvas->grabbed_item) { + switch (event->type) { + case GDK_ENTER_NOTIFY: + mask = GDK_ENTER_NOTIFY_MASK; + break; + case GDK_LEAVE_NOTIFY: + mask = GDK_LEAVE_NOTIFY_MASK; + break; + case GDK_MOTION_NOTIFY: + mask = GDK_POINTER_MOTION_MASK; + break; + case GDK_BUTTON_PRESS: + case GDK_2BUTTON_PRESS: + case GDK_3BUTTON_PRESS: + mask = GDK_BUTTON_PRESS_MASK; + break; + case GDK_BUTTON_RELEASE: + mask = GDK_BUTTON_RELEASE_MASK; + break; + case GDK_KEY_PRESS: + mask = GDK_KEY_PRESS_MASK; + break; + case GDK_KEY_RELEASE: + mask = GDK_KEY_RELEASE_MASK; + break; + case GDK_SCROLL: + mask = GDK_SCROLL; + break; + default: + mask = 0; + break; + } + + if (!(mask & canvas->grabbed_event_mask)) return FALSE; + } + + /* Convert to world coordinates -- we have two cases because of diferent + * offsets of the fields in the event structures. + */ + + GdkEvent ev = *event; + + switch (ev.type) { + case GDK_ENTER_NOTIFY: + case GDK_LEAVE_NOTIFY: + ev.crossing.x += canvas->x0; + ev.crossing.y += canvas->y0; + break; + case GDK_MOTION_NOTIFY: + case GDK_BUTTON_PRESS: + case GDK_2BUTTON_PRESS: + case GDK_3BUTTON_PRESS: + case GDK_BUTTON_RELEASE: + ev.motion.x += canvas->x0; + ev.motion.y += canvas->y0; + break; + default: + break; + } + + /* Choose where we send the event */ + + /* canvas->current_item becomes NULL in some cases under Win32 + ** (e.g. if the pointer leaves the window). So this is a hack that + ** Lauris applied to SP to get around the problem. + */ + SPCanvasItem* item = NULL; + if (canvas->grabbed_item && !is_descendant (canvas->current_item, canvas->grabbed_item)) { + item = canvas->grabbed_item; + } else { + item = canvas->current_item; + } + + if (canvas->focused_item && + ((event->type == GDK_KEY_PRESS) || + (event->type == GDK_KEY_RELEASE) || + (event->type == GDK_FOCUS_CHANGE))) { + item = canvas->focused_item; + } + + /* The event is propagated up the hierarchy (for if someone connected to + * a group instead of a leaf event), and emission is stopped if a + * handler returns TRUE, just like for GtkWidget events. + */ + + gint finished = FALSE; + + while (item && !finished) { + gtk_object_ref (GTK_OBJECT (item)); + gtk_signal_emit (GTK_OBJECT (item), item_signals[ITEM_EVENT], &ev, &finished); + SPCanvasItem *parent = item->parent; + gtk_object_unref (GTK_OBJECT (item)); + item = parent; + } + + return finished; +} + +/** + * Helper that re-picks the current item in the canvas, based on the event's + * coordinates and emits enter/leave events for items as appropriate. + */ +static int +pick_current_item (SPCanvas *canvas, GdkEvent *event) +{ + double x, y; + + int retval = FALSE; + + /* Save the event in the canvas. This is used to synthesize enter and + * leave events in case the current item changes. It is also used to + * re-pick the current item if the current one gets deleted. Also, + * synthesize an enter event. + */ + if (event != &canvas->pick_event) { + if ((event->type == GDK_MOTION_NOTIFY) || (event->type == GDK_BUTTON_RELEASE)) { + /* these fields have the same offsets in both types of events */ + + canvas->pick_event.crossing.type = GDK_ENTER_NOTIFY; + canvas->pick_event.crossing.window = event->motion.window; + canvas->pick_event.crossing.send_event = event->motion.send_event; + canvas->pick_event.crossing.subwindow = NULL; + canvas->pick_event.crossing.x = event->motion.x; + canvas->pick_event.crossing.y = event->motion.y; + canvas->pick_event.crossing.mode = GDK_CROSSING_NORMAL; + canvas->pick_event.crossing.detail = GDK_NOTIFY_NONLINEAR; + canvas->pick_event.crossing.focus = FALSE; + canvas->pick_event.crossing.state = event->motion.state; + + /* these fields don't have the same offsets in both types of events */ + + if (event->type == GDK_MOTION_NOTIFY) { + canvas->pick_event.crossing.x_root = event->motion.x_root; + canvas->pick_event.crossing.y_root = event->motion.y_root; + } else { + canvas->pick_event.crossing.x_root = event->button.x_root; + canvas->pick_event.crossing.y_root = event->button.y_root; + } + } else { + canvas->pick_event = *event; + } + } + + /* Don't do anything else if this is a recursive call */ + if (canvas->in_repick) return retval; + + /* LeaveNotify means that there is no current item, so we don't look for one */ + if (canvas->pick_event.type != GDK_LEAVE_NOTIFY) { + /* these fields don't have the same offsets in both types of events */ + + if (canvas->pick_event.type == GDK_ENTER_NOTIFY) { + x = canvas->pick_event.crossing.x; + y = canvas->pick_event.crossing.y; + } else { + x = canvas->pick_event.motion.x; + y = canvas->pick_event.motion.y; + } + + /* world coords */ + x += canvas->x0; + y += canvas->y0; + + /* find the closest item */ + if (canvas->root->flags & SP_CANVAS_ITEM_VISIBLE) { + sp_canvas_item_invoke_point (canvas->root, NR::Point(x, y), &canvas->new_current_item); + } else { + canvas->new_current_item = NULL; + } + } else { + canvas->new_current_item = NULL; + } + + if ((canvas->new_current_item == canvas->current_item) && !canvas->left_grabbed_item) { + return retval; /* current item did not change */ + } + + /* Synthesize events for old and new current items */ + + if ((canvas->new_current_item != canvas->current_item) + && (canvas->current_item != NULL) + && !canvas->left_grabbed_item) { + GdkEvent new_event; + SPCanvasItem *item; + + item = canvas->current_item; + + new_event = canvas->pick_event; + new_event.type = GDK_LEAVE_NOTIFY; + + new_event.crossing.detail = GDK_NOTIFY_ANCESTOR; + new_event.crossing.subwindow = NULL; + canvas->in_repick = TRUE; + retval = emit_event (canvas, &new_event); + canvas->in_repick = FALSE; + } + + /* Handle the rest of cases */ + + canvas->left_grabbed_item = FALSE; + canvas->current_item = canvas->new_current_item; + + if (canvas->current_item != NULL) { + GdkEvent new_event; + + new_event = canvas->pick_event; + new_event.type = GDK_ENTER_NOTIFY; + new_event.crossing.detail = GDK_NOTIFY_ANCESTOR; + new_event.crossing.subwindow = NULL; + retval = emit_event (canvas, &new_event); + } + + return retval; +} + +/** + * Button event handler for the canvas. + */ +static gint +sp_canvas_button (GtkWidget *widget, GdkEventButton *event) +{ + SPCanvas *canvas = SP_CANVAS (widget); + + int retval = FALSE; + + /* dispatch normally regardless of the event's window if an item has + has a pointer grab in effect */ + if (!canvas->grabbed_item && + event->window != SP_CANVAS_WINDOW (canvas)) + return retval; + + int mask; + switch (event->button) { + case 1: + mask = GDK_BUTTON1_MASK; + break; + case 2: + mask = GDK_BUTTON2_MASK; + break; + case 3: + mask = GDK_BUTTON3_MASK; + break; + case 4: + mask = GDK_BUTTON4_MASK; + break; + case 5: + mask = GDK_BUTTON5_MASK; + break; + default: + mask = 0; + } + + switch (event->type) { + case GDK_BUTTON_PRESS: + case GDK_2BUTTON_PRESS: + case GDK_3BUTTON_PRESS: + /* Pick the current item as if the button were not pressed, and + * then process the event. + */ + canvas->state = event->state; + pick_current_item (canvas, (GdkEvent *) event); + canvas->state ^= mask; + retval = emit_event (canvas, (GdkEvent *) event); + break; + + case GDK_BUTTON_RELEASE: + /* Process the event as if the button were pressed, then repick + * after the button has been released + */ + canvas->state = event->state; + retval = emit_event (canvas, (GdkEvent *) event); + event->state ^= mask; + canvas->state = event->state; + pick_current_item (canvas, (GdkEvent *) event); + event->state ^= mask; + break; + + default: + g_assert_not_reached (); + } + + return retval; +} + +/** + * Scroll event handler for the canvas. + * + * \todo FIXME: generate motion events to re-select items. + */ +static gint +sp_canvas_scroll (GtkWidget *widget, GdkEventScroll *event) +{ + return emit_event (SP_CANVAS (widget), (GdkEvent *) event); +} + +/** + * Motion event handler for the canvas. + */ +static int +sp_canvas_motion (GtkWidget *widget, GdkEventMotion *event) +{ + SPCanvas *canvas = SP_CANVAS (widget); + + if (event->window != SP_CANVAS_WINDOW (canvas)) + return FALSE; + + if (canvas->grabbed_event_mask & GDK_POINTER_MOTION_HINT_MASK) { + gint x, y; + gdk_window_get_pointer (widget->window, &x, &y, NULL); + event->x = x; + event->y = y; + } + + canvas->state = event->state; + pick_current_item (canvas, (GdkEvent *) event); + + return emit_event (canvas, (GdkEvent *) event); +} + +/** + * Helper that draws a specific rectangular part of the canvas. + */ +static void +sp_canvas_paint_rect (SPCanvas *canvas, int xx0, int yy0, int xx1, int yy1) +{ + g_return_if_fail (!canvas->need_update); + + GtkWidget *widget = GTK_WIDGET (canvas); + + int draw_x1 = MAX (xx0, canvas->x0); + int draw_y1 = MAX (yy0, canvas->y0); + int draw_x2 = MIN (xx1, canvas->x0/*draw_x1*/ + GTK_WIDGET (canvas)->allocation.width); + int draw_y2 = MIN (yy1, canvas->y0/*draw_y1*/ + GTK_WIDGET (canvas)->allocation.height); + + int bw = draw_x2 - draw_x1; + int bh = draw_y2 - draw_y1; + if ((bw < 1) || (bh < 1)) + return; + + int sw, sh; + if (canvas->rendermode != RENDERMODE_OUTLINE) { // use 256K as a compromise to not slow down gradients + /* 256K is the cached buffer and we need 3 channels */ + if (bw * bh < 87381) { // 256K/3 + // We can go with single buffer + sw = bw; + sh = bh; + } else if (bw <= (16 * 341)) { + // Go with row buffer + sw = bw; + sh = 87381 / bw; + } else if (bh <= (16 * 256)) { + // Go with column buffer + sw = 87381 / bh; + sh = bh; + } else { + sw = 341; + sh = 256; + } + } else { // paths only, so 1M works faster + /* 1M is the cached buffer and we need 3 channels */ + if (bw * bh < 349525) { // 1M/3 + // We can go with single buffer + sw = bw; + sh = bh; + } else if (bw <= (16 * 682)) { + // Go with row buffer + sw = bw; + sh = 349525 / bw; + } else if (bh <= (16 * 512)) { + // Go with column buffer + sw = 349525 / bh; + sh = bh; + } else { + sw = 682; + sh = 512; + } + } + + // As we can come from expose, we have to tile here + for (int y0 = draw_y1; y0 < draw_y2; y0 += sh) { + int y1 = MIN (y0 + sh, draw_y2); + for (int x0 = draw_x1; x0 < draw_x2; x0 += sw) { + int x1 = MIN (x0 + sw, draw_x2); + + SPCanvasBuf buf; + if (canvas->rendermode != RENDERMODE_OUTLINE) { + buf.buf = nr_pixelstore_256K_new (FALSE, 0); + } else { + buf.buf = nr_pixelstore_1M_new (FALSE, 0); + } + + buf.buf_rowstride = sw * 3; + buf.rect.x0 = x0; + buf.rect.y0 = y0; + buf.rect.x1 = x1; + buf.rect.y1 = y1; + GdkColor *color = &widget->style->bg[GTK_STATE_NORMAL]; + buf.bg_color = (((color->red & 0xff00) << 8) + | (color->green & 0xff00) + | (color->blue >> 8)); + buf.is_empty = true; + + if (canvas->root->flags & SP_CANVAS_ITEM_VISIBLE) { + SP_CANVAS_ITEM_GET_CLASS (canvas->root)->render (canvas->root, &buf); + } + + if (buf.is_empty) { + gdk_rgb_gc_set_foreground (canvas->pixmap_gc, buf.bg_color); + gdk_draw_rectangle (SP_CANVAS_WINDOW (canvas), + canvas->pixmap_gc, + TRUE, + x0 - canvas->x0, y0 - canvas->y0, + x1 - x0, y1 - y0); + } else { + gdk_draw_rgb_image_dithalign (SP_CANVAS_WINDOW (canvas), + canvas->pixmap_gc, + x0 - canvas->x0, y0 - canvas->y0, + x1 - x0, y1 - y0, + GDK_RGB_DITHER_MAX, + buf.buf, + sw * 3, + x0 - canvas->x0, y0 - canvas->y0); + } + + if (canvas->rendermode != RENDERMODE_OUTLINE) { + nr_pixelstore_256K_free (buf.buf); + } else { + nr_pixelstore_1M_free (buf.buf); + } + + } + } +} + +/** + * The canvas widget's expose callback. + */ +static gint +sp_canvas_expose (GtkWidget *widget, GdkEventExpose *event) +{ + SPCanvas *canvas = SP_CANVAS (widget); + + if (!GTK_WIDGET_DRAWABLE (widget) || + (event->window != SP_CANVAS_WINDOW (canvas))) + return FALSE; + + int n_rects; + GdkRectangle *rects; + gdk_region_get_rectangles (event->region, &rects, &n_rects); + + for (int i = 0; i < n_rects; i++) { + NRRectL rect; + + rect.x0 = rects[i].x + canvas->x0; + rect.y0 = rects[i].y + canvas->y0; + rect.x1 = rect.x0 + rects[i].width; + rect.y1 = rect.y0 + rects[i].height; + + if (canvas->need_update || canvas->need_redraw) { + sp_canvas_request_redraw (canvas, rect.x0, rect.y0, rect.x1, rect.y1); + } else { + /* No pending updates, draw exposed area immediately */ + sp_canvas_paint_rect (canvas, rect.x0, rect.y0, rect.x1, rect.y1); + } + } + + if (n_rects > 0) + g_free (rects); + + return FALSE; +} + +/** + * The canvas widget's keypress callback. + */ +static gint +sp_canvas_key (GtkWidget *widget, GdkEventKey *event) +{ + return emit_event (SP_CANVAS (widget), (GdkEvent *) event); +} + +/** + * Crossing event handler for the canvas. + */ +static gint +sp_canvas_crossing (GtkWidget *widget, GdkEventCrossing *event) +{ + SPCanvas *canvas = SP_CANVAS (widget); + + if (event->window != SP_CANVAS_WINDOW (canvas)) + return FALSE; + + canvas->state = event->state; + return pick_current_item (canvas, (GdkEvent *) event); +} + +/** + * Focus in handler for the canvas. + */ +static gint +sp_canvas_focus_in (GtkWidget *widget, GdkEventFocus *event) +{ + GTK_WIDGET_SET_FLAGS (widget, GTK_HAS_FOCUS); + + SPCanvas *canvas = SP_CANVAS (widget); + + if (canvas->focused_item) { + return emit_event (canvas, (GdkEvent *) event); + } else { + return FALSE; + } +} + +/** + * Focus out handler for the canvas. + */ +static gint +sp_canvas_focus_out (GtkWidget *widget, GdkEventFocus *event) +{ + GTK_WIDGET_UNSET_FLAGS (widget, GTK_HAS_FOCUS); + + SPCanvas *canvas = SP_CANVAS (widget); + + if (canvas->focused_item) + return emit_event (canvas, (GdkEvent *) event); + else + return FALSE; +} + +/** + * Helper that repaints the areas in the canvas that need it. + */ +static int +paint (SPCanvas *canvas) +{ + if (canvas->need_update) { + sp_canvas_item_invoke_update (canvas->root, NR::identity(), 0); + canvas->need_update = FALSE; + } + + if (!canvas->need_redraw) + return TRUE; + + GtkWidget const *widget = GTK_WIDGET(canvas); + int const canvas_x1 = canvas->x0 + widget->allocation.width; + int const canvas_y1 = canvas->y0 + widget->allocation.height; + + NRRectL topaint; + topaint.x0 = topaint.y0 = topaint.x1 = topaint.y1 = 0; + + for (int j=canvas->tTop&(~3);jtBottom;j+=4) { + for (int i=canvas->tLeft&(~3);itRight;i+=4) { + int mode=0; + + int pl=i+1,pr=i,pt=j+4,pb=j; + for (int l=MAX(j,canvas->tTop);ltBottom);l++) { + for (int k=MAX(i,canvas->tLeft);ktRight);k++) { + if ( canvas->tiles[(k-canvas->tLeft)+(l-canvas->tTop)*canvas->tileH] ) { + mode|=1<<((k-i)+(l-j)*4); + if ( k < pl ) pl=k; + if ( k+1 > pr ) pr=k+1; + if ( l < pt ) pt=l; + if ( l+1 > pb ) pb=l+1; + } + canvas->tiles[(k-canvas->tLeft)+(l-canvas->tTop)*canvas->tileH]=0; + } + } + + if ( mode ) { + NRRectL tile; + tile.x0 = MAX (pl*32, canvas->x0); + tile.y0 = MAX (pt*32, canvas->y0); + tile.x1 = MIN (pr*32, canvas_x1); + tile.y1 = MIN (pb*32, canvas_y1); + if ((tile.x0 < tile.x1) && (tile.y0 < tile.y1)) { + nr_rect_l_union (&topaint, &topaint, &tile); + } + + } + } + } + + sp_canvas_paint_rect (canvas, topaint.x0, topaint.y0, topaint.x1, topaint.y1); + + canvas->need_redraw = FALSE; + return TRUE; +} + +/** + * Helper that invokes update, paint, and repick on canvas. + */ +static int +do_update (SPCanvas *canvas) +{ + /* Cause the update if necessary */ + if (canvas->need_update) { + sp_canvas_item_invoke_update (canvas->root, NR::identity(), 0); + canvas->need_update = FALSE; + } + + /* Paint if able to */ + if (GTK_WIDGET_DRAWABLE (canvas)) { + return paint (canvas); + } + + /* Pick new current item */ + while (canvas->need_repick) { + canvas->need_repick = FALSE; + pick_current_item (canvas, &canvas->pick_event); + } + + return TRUE; +} + +/** + * Idle handler for the canvas that deals with pending updates and redraws. + */ +static gint +idle_handler (gpointer data) +{ + GDK_THREADS_ENTER (); + + SPCanvas *canvas = SP_CANVAS (data); + + const int ret = do_update (canvas); + + if (ret) { + /* Reset idle id */ + canvas->idle_id = 0; + } + + GDK_THREADS_LEAVE (); + + return !ret; +} + +/** + * Convenience function to add an idle handler to a canvas. + */ +static void +add_idle (SPCanvas *canvas) +{ + if (canvas->idle_id != 0) + return; + + canvas->idle_id = gtk_idle_add_priority (sp_canvas_update_priority, idle_handler, canvas); +} + +/** + * Returns the root group of the specified canvas. + */ +SPCanvasGroup * +sp_canvas_root (SPCanvas *canvas) +{ + g_return_val_if_fail (canvas != NULL, NULL); + g_return_val_if_fail (SP_IS_CANVAS (canvas), NULL); + + return SP_CANVAS_GROUP (canvas->root); +} + +/** + * Scrolls canvas to specific position. + */ +void +sp_canvas_scroll_to (SPCanvas *canvas, double cx, double cy, unsigned int clear) +{ + g_return_if_fail (canvas != NULL); + g_return_if_fail (SP_IS_CANVAS (canvas)); + + int ix = (int) (cx + 0.5); + int iy = (int) (cy + 0.5); + int dx = ix - canvas->x0; + int dy = iy - canvas->y0; + + canvas->dx0 = cx; + canvas->dy0 = cy; + canvas->x0 = ix; + canvas->y0 = iy; + + sp_canvas_resize_tiles(canvas,canvas->x0,canvas->y0,canvas->x0+canvas->widget.allocation.width,canvas->y0+canvas->widget.allocation.height); + + if (!clear) { + // scrolling without zoom; redraw only the newly exposed areas + if ((dx != 0) || (dy != 0)) { + int width, height; + width = canvas->widget.allocation.width; + height = canvas->widget.allocation.height; + if (GTK_WIDGET_REALIZED (canvas)) { + gdk_window_scroll (SP_CANVAS_WINDOW (canvas), -dx, -dy); + gdk_window_process_updates (SP_CANVAS_WINDOW (canvas), TRUE); + } + if (dx < 0) { + sp_canvas_request_redraw (canvas, ix + 0, iy + 0, ix - dx, iy + height); + } else if (dx > 0) { + sp_canvas_request_redraw (canvas, ix + width - dx, iy + 0, ix + width, iy + height); + } + if (dy < 0) { + sp_canvas_request_redraw (canvas, ix + 0, iy + 0, ix + width, iy - dy); + } else if (dy > 0) { + sp_canvas_request_redraw (canvas, ix + 0, iy + height - dy, ix + width, iy + height); + } + } + } else { + // scrolling as part of zoom; do nothing here - the next do_update will perform full redraw + } +} + +/** + * Updates canvas if necessary. + */ +void +sp_canvas_update_now (SPCanvas *canvas) +{ + g_return_if_fail (canvas != NULL); + g_return_if_fail (SP_IS_CANVAS (canvas)); + + if (!(canvas->need_update || + canvas->need_redraw)) + return; + + remove_idle (canvas); + do_update (canvas); +} + +/** + * Update callback for canvas widget. + */ +static void +sp_canvas_request_update (SPCanvas *canvas) +{ + canvas->need_update = TRUE; + add_idle (canvas); +} + +/** + * Forces redraw of rectangular canvas area. + */ +void +sp_canvas_request_redraw (SPCanvas *canvas, int x0, int y0, int x1, int y1) +{ + NRRectL bbox; + NRRectL visible; + NRRectL clip; + + g_return_if_fail (canvas != NULL); + g_return_if_fail (SP_IS_CANVAS (canvas)); + + if (!GTK_WIDGET_DRAWABLE (canvas)) return; + if ((x0 >= x1) || (y0 >= y1)) return; + + bbox.x0 = x0; + bbox.y0 = y0; + bbox.x1 = x1; + bbox.y1 = y1; + + visible.x0 = canvas->x0; + visible.y0 = canvas->y0; + visible.x1 = visible.x0 + GTK_WIDGET (canvas)->allocation.width; + visible.y1 = visible.y0 + GTK_WIDGET (canvas)->allocation.height; + + nr_rect_l_intersect (&clip, &bbox, &visible); + + sp_canvas_dirty_rect(canvas,x0,y0,x1,y1); + add_idle (canvas); +} + +/** + * Sets world coordinates from win and canvas. + */ +void sp_canvas_window_to_world(SPCanvas const *canvas, double winx, double winy, double *worldx, double *worldy) +{ + g_return_if_fail (canvas != NULL); + g_return_if_fail (SP_IS_CANVAS (canvas)); + + if (worldx) *worldx = canvas->x0 + winx; + if (worldy) *worldy = canvas->y0 + winy; +} + +/** + * Sets win coordinates from world and canvas. + */ +void sp_canvas_world_to_window(SPCanvas const *canvas, double worldx, double worldy, double *winx, double *winy) +{ + g_return_if_fail (canvas != NULL); + g_return_if_fail (SP_IS_CANVAS (canvas)); + + if (winx) *winx = worldx - canvas->x0; + if (winy) *winy = worldy - canvas->y0; +} + +/** + * Converts point from win to world coordinates. + */ +NR::Point sp_canvas_window_to_world(SPCanvas const *canvas, NR::Point const win) +{ + g_assert (canvas != NULL); + g_assert (SP_IS_CANVAS (canvas)); + + return NR::Point(canvas->x0 + win[0], canvas->y0 + win[1]); +} + +/** + * Converts point from world to win coordinates. + */ +NR::Point sp_canvas_world_to_window(SPCanvas const *canvas, NR::Point const world) +{ + g_assert (canvas != NULL); + g_assert (SP_IS_CANVAS (canvas)); + + return NR::Point(world[0] - canvas->x0, world[1] - canvas->y0); +} + +/** + * Returns true if point given in world coordinates is inside window. + */ +bool sp_canvas_world_pt_inside_window(SPCanvas const *canvas, NR::Point const &world) +{ + g_assert( canvas != NULL ); + g_assert(SP_IS_CANVAS(canvas)); + + using NR::X; + using NR::Y; + GtkWidget const &w = *GTK_WIDGET(canvas); + return ( ( canvas->x0 <= world[X] ) && + ( canvas->y0 <= world[Y] ) && + ( world[X] < canvas->x0 + w.allocation.width ) && + ( world[Y] < canvas->y0 + w.allocation.height ) ); +} + +/** + * Return canvas window coordinates as NRRect. + */ +NR::Rect SPCanvas::getViewbox() const +{ + GtkWidget const *w = GTK_WIDGET(this); + + return NR::Rect(NR::Point(dx0, dy0), + NR::Point(dx0 + w->allocation.width, dy0 + w->allocation.height)); +} + +inline int sp_canvas_tile_floor(int x) +{ + return (x&(~31))/32; +} + +inline int sp_canvas_tile_ceil(int x) +{ + return ((x+31)&(~31))/32; +} + +/** + * Helper that changes tile size for canvas redraw. + */ +void sp_canvas_resize_tiles(SPCanvas* canvas,int nl,int nt,int nr,int nb) +{ + if ( nl >= nr || nt >= nb ) { + if ( canvas->tiles ) free(canvas->tiles); + canvas->tLeft=canvas->tTop=canvas->tRight=canvas->tBottom=0; + canvas->tileH=canvas->tileV=0; + canvas->tiles=NULL; + return; + } + int tl=sp_canvas_tile_floor(nl); + int tt=sp_canvas_tile_floor(nt); + int tr=sp_canvas_tile_ceil(nr); + int tb=sp_canvas_tile_ceil(nb); + + int nh=tr-tl,nv=tb-tt; + uint8_t* ntiles=(uint8_t*)malloc(nh*nv*sizeof(uint8_t)); + for (int i=tl;i= canvas->tLeft && i < canvas->tRight && j >= canvas->tTop && j < canvas->tBottom ) { + ntiles[ind]=canvas->tiles[(i-canvas->tLeft)+(j-canvas->tTop)*canvas->tileH]; + } else { + ntiles[ind]=0; + } + } + } + if ( canvas->tiles ) free(canvas->tiles); + canvas->tiles=ntiles; + canvas->tLeft=tl; + canvas->tTop=tt; + canvas->tRight=tr; + canvas->tBottom=tb; + canvas->tileH=nh; + canvas->tileV=nv; +} + +/** + * Helper that marks specific canvas rectangle for redraw. + */ +void sp_canvas_dirty_rect(SPCanvas* canvas,int nl,int nt,int nr,int nb) +{ + if ( nl >= nr || nt >= nb ) { + return; + } + int tl=sp_canvas_tile_floor(nl); + int tt=sp_canvas_tile_floor(nt); + int tr=sp_canvas_tile_ceil(nr); + int tb=sp_canvas_tile_ceil(nb); + if ( tl >= canvas->tRight || tr <= canvas->tLeft || tt >= canvas->tBottom || tb <= canvas->tTop ) return; + if ( tl < canvas->tLeft ) tl=canvas->tLeft; + if ( tr > canvas->tRight ) tr=canvas->tRight; + if ( tt < canvas->tTop ) tt=canvas->tTop; + if ( tb > canvas->tBottom ) tb=canvas->tBottom; + + canvas->need_redraw = TRUE; + + for (int i=tl;itiles[(i-canvas->tLeft)+(j-canvas->tTop)*canvas->tileH]=1; + } + } +} + + +/* + 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 : diff --git a/src/display/sp-canvas.h b/src/display/sp-canvas.h new file mode 100644 index 000000000..905c9272f --- /dev/null +++ b/src/display/sp-canvas.h @@ -0,0 +1,186 @@ +#ifndef __SP_CANVAS_H__ +#define __SP_CANVAS_H__ + +/** \file + * SPCanvas, SPCanvasBuf, and SPCanvasItem. + * + * Authors: + * Federico Mena + * Raph Levien + * Lauris Kaplinski + * + * Copyright (C) 1998 The Free Software Foundation + * Copyright (C) 2002 Lauris Kaplinski + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +struct SPCanvas; +struct SPCanvasGroup; + +enum { + SP_CANVAS_UPDATE_REQUESTED = 1 << 0, + SP_CANVAS_UPDATE_AFFINE = 1 << 1 +}; + +/** + * The canvas buf contains the actual pixels. + */ +struct SPCanvasBuf{ + guchar *buf; + int buf_rowstride; + NRRectL rect; + /// Background color, given as 0xrrggbb + guint32 bg_color; + // If empty, ignore contents of buffer and use a solid area of bg_color + bool is_empty; +}; + +/** + * An SPCanvasItem refers to a SPCanvas and to its parent item; it has + * four coordinates, a bounding rectangle, and a transformation matrix. + */ +struct SPCanvasItem : public GtkObject { + SPCanvas *canvas; + SPCanvasItem *parent; + + double x1, y1, x2, y2; + NR::Rect bounds; + NR::Matrix xform; +}; + +/** + * The vtable of an SPCanvasItem. + */ +struct SPCanvasItemClass : public GtkObjectClass { + void (* update) (SPCanvasItem *item, NR::Matrix const &affine, unsigned int flags); + + void (* render) (SPCanvasItem *item, SPCanvasBuf *buf); + double (* point) (SPCanvasItem *item, NR::Point p, SPCanvasItem **actual_item); + + int (* event) (SPCanvasItem *item, GdkEvent *event); +}; + +SPCanvasItem *sp_canvas_item_new(SPCanvasGroup *parent, GtkType type, const gchar *first_arg_name, ...); + +#define sp_canvas_item_set gtk_object_set + +void sp_canvas_item_affine_absolute(SPCanvasItem *item, NR::Matrix const &aff); + +void sp_canvas_item_raise(SPCanvasItem *item, int positions); +void sp_canvas_item_lower(SPCanvasItem *item, int positions); +void sp_canvas_item_show(SPCanvasItem *item); +void sp_canvas_item_hide(SPCanvasItem *item); +int sp_canvas_item_grab(SPCanvasItem *item, unsigned int event_mask, GdkCursor *cursor, guint32 etime); +void sp_canvas_item_ungrab(SPCanvasItem *item, guint32 etime); + +NR::Matrix sp_canvas_item_i2w_affine(SPCanvasItem const *item); + +void sp_canvas_item_grab_focus(SPCanvasItem *item); + +void sp_canvas_item_request_update(SPCanvasItem *item); + +/* get item z-order in parent group */ + +gint sp_canvas_item_order(SPCanvasItem * item); + + +// SPCanvas ------------------------------------------------- +/** + * Port of GnomeCanvas for inkscape needs. + */ +struct SPCanvas { + GtkWidget widget; + + guint idle_id; + + SPCanvasItem *root; + + double dx0, dy0; + int x0, y0; + + /* Area that needs redrawing, stored as a microtile array */ + int tLeft,tTop,tRight,tBottom; + int tileH,tileV; + uint8_t *tiles; + + /* Last known modifier state, for deferred repick when a button is down */ + int state; + + /* The item containing the mouse pointer, or NULL if none */ + SPCanvasItem *current_item; + + /* Item that is about to become current (used to track deletions and such) */ + SPCanvasItem *new_current_item; + + /* Item that holds a pointer grab, or NULL if none */ + SPCanvasItem *grabbed_item; + + /* Event mask specified when grabbing an item */ + guint grabbed_event_mask; + + /* If non-NULL, the currently focused item */ + SPCanvasItem *focused_item; + + /* Event on which selection of current item is based */ + GdkEvent pick_event; + + int close_enough; + + /* GC for temporary draw pixmap */ + GdkGC *pixmap_gc; + + unsigned int need_update : 1; + unsigned int need_redraw : 1; + unsigned int need_repick : 1; + + /* For use by internal pick_current_item() function */ + unsigned int left_grabbed_item : 1; + /* For use by internal pick_current_item() function */ + unsigned int in_repick : 1; + + int rendermode; + + NR::Rect getViewbox() const; +}; + +GtkWidget *sp_canvas_new_aa(); + +SPCanvasGroup *sp_canvas_root(SPCanvas *canvas); + +void sp_canvas_scroll_to(SPCanvas *canvas, double cx, double cy, unsigned int clear); +void sp_canvas_update_now(SPCanvas *canvas); + +void sp_canvas_request_redraw(SPCanvas *canvas, int x1, int y1, int x2, int y2); + +void sp_canvas_window_to_world(SPCanvas const *canvas, double winx, double winy, double *worldx, double *worldy); +void sp_canvas_world_to_window(SPCanvas const *canvas, double worldx, double worldy, double *winx, double *winy); + +NR::Point sp_canvas_window_to_world(SPCanvas const *canvas, NR::Point const win); +NR::Point sp_canvas_world_to_window(SPCanvas const *canvas, NR::Point const world); + +bool sp_canvas_world_pt_inside_window(SPCanvas const *canvas, NR::Point const &world); + +#endif + +/* + 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 : diff --git a/src/display/sp-ctrlline.cpp b/src/display/sp-ctrlline.cpp new file mode 100644 index 000000000..0a278bb69 --- /dev/null +++ b/src/display/sp-ctrlline.cpp @@ -0,0 +1,217 @@ +#define __INKSCAPE_CTRLLINE_C__ + +/* + * Simple straight line + * + * Author: + * Lauris Kaplinski + * + * Copyright (C) 1999-2002 Lauris Kaplinski + * + * Released under GNU GPL + */ + +/* + * TODO: + * Draw it by hand - we really do not need aa stuff for it + * + */ + +#include "display-forward.h" +#include "sp-canvas-util.h" +#include "sp-ctrlline.h" + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif +#include +#include + +struct SPCtrlLine : public SPCanvasItem{ + guint32 rgba; + NRPoint s, e; + Shape* shp; +}; + +struct SPCtrlLineClass : public SPCanvasItemClass{}; + +static void sp_ctrlline_class_init (SPCtrlLineClass *klass); +static void sp_ctrlline_init (SPCtrlLine *ctrlline); +static void sp_ctrlline_destroy (GtkObject *object); + +static void sp_ctrlline_update (SPCanvasItem *item, NR::Matrix const &affine, unsigned int flags); +static void sp_ctrlline_render (SPCanvasItem *item, SPCanvasBuf *buf); + +static SPCanvasItemClass *parent_class; + +GtkType +sp_ctrlline_get_type (void) +{ + static GtkType type = 0; + + if (!type) { + GtkTypeInfo info = { + "SPCtrlLine", + sizeof (SPCtrlLine), + sizeof (SPCtrlLineClass), + (GtkClassInitFunc) sp_ctrlline_class_init, + (GtkObjectInitFunc) sp_ctrlline_init, + NULL, NULL, NULL + }; + type = gtk_type_unique (SP_TYPE_CANVAS_ITEM, &info); + } + return type; +} + +static void +sp_ctrlline_class_init (SPCtrlLineClass *klass) +{ + GtkObjectClass *object_class = (GtkObjectClass *) klass; + SPCanvasItemClass *item_class = (SPCanvasItemClass *) klass; + + parent_class = (SPCanvasItemClass*)gtk_type_class (SP_TYPE_CANVAS_ITEM); + + object_class->destroy = sp_ctrlline_destroy; + + item_class->update = sp_ctrlline_update; + item_class->render = sp_ctrlline_render; +} + +static void +sp_ctrlline_init (SPCtrlLine *ctrlline) +{ + ctrlline->rgba = 0x0000ff7f; + ctrlline->s.x = ctrlline->s.y = ctrlline->e.x = ctrlline->e.y = 0.0; + ctrlline->shp=NULL; +} + +static void +sp_ctrlline_destroy (GtkObject *object) +{ + g_return_if_fail (object != NULL); + g_return_if_fail (SP_IS_CTRLLINE (object)); + + SPCtrlLine *ctrlline = SP_CTRLLINE (object); + + if (ctrlline->shp) { + delete ctrlline->shp; + ctrlline->shp = NULL; + } + + if (GTK_OBJECT_CLASS (parent_class)->destroy) + (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); +} + +static void +sp_ctrlline_render (SPCanvasItem *item, SPCanvasBuf *buf) +{ + SPCtrlLine *ctrlline = SP_CTRLLINE (item); + + NRRectL area; + area.x0=buf->rect.x0; + area.x1=buf->rect.x1; + area.y0=buf->rect.y0; + area.y1=buf->rect.y1; + + if (ctrlline->shp) { + sp_canvas_prepare_buffer (buf); + nr_pixblock_render_ctrl_rgba (ctrlline->shp,ctrlline->rgba,area,(char*)buf->buf, buf->buf_rowstride); + } +} + +static void +sp_ctrlline_update (SPCanvasItem *item, NR::Matrix const &affine, unsigned int flags) +{ + NRRect dbox; + + SPCtrlLine *cl = SP_CTRLLINE (item); + + sp_canvas_request_redraw (item->canvas, (int)item->x1, (int)item->y1, (int)item->x2, (int)item->y2); + + if (parent_class->update) + (* parent_class->update) (item, affine, flags); + + sp_canvas_item_reset_bounds (item); + + dbox.x0=dbox.x1=dbox.y0=dbox.y1=0; + if (cl->shp) { + delete cl->shp; + cl->shp = NULL; + } + Path* thePath = new Path; + thePath->MoveTo(NR::Point(cl->s.x, cl->s.y) * affine); + thePath->LineTo(NR::Point(cl->e.x, cl->e.y) * affine); + + thePath->Convert(1.0); + if ( cl->shp == NULL ) cl->shp=new Shape; + thePath->Stroke(cl->shp,false,0.5,join_straight,butt_straight,20.0,false); + cl->shp->CalcBBox(); + if ( cl->shp->leftX < cl->shp->rightX ) { + if ( dbox.x0 >= dbox.x1 ) { + dbox.x0=cl->shp->leftX;dbox.x1=cl->shp->rightX; + dbox.y0=cl->shp->topY;dbox.y1=cl->shp->bottomY; + } else { + if ( cl->shp->leftX < dbox.x0 ) dbox.x0=cl->shp->leftX; + if ( cl->shp->rightX > dbox.x1 ) dbox.x1=cl->shp->rightX; + if ( cl->shp->topY < dbox.y0 ) dbox.y0=cl->shp->topY; + if ( cl->shp->bottomY > dbox.y1 ) dbox.y1=cl->shp->bottomY; + } + } + delete thePath; + + item->x1 = (int)dbox.x0; + item->y1 = (int)dbox.y0; + item->x2 = (int)dbox.x1; + item->y2 = (int)dbox.y1; + + sp_canvas_request_redraw (item->canvas, (int)item->x1, (int)item->y1, (int)item->x2, (int)item->y2); +} + +void +sp_ctrlline_set_rgba32 (SPCtrlLine *cl, guint32 rgba) +{ + g_return_if_fail (cl != NULL); + g_return_if_fail (SP_IS_CTRLLINE (cl)); + + if (rgba != cl->rgba) { + SPCanvasItem *item; + cl->rgba = rgba; + item = SP_CANVAS_ITEM (cl); + sp_canvas_request_redraw (item->canvas, (int)item->x1, (int)item->y1, (int)item->x2, (int)item->y2); + } +} + +#define EPSILON 1e-6 +#define DIFFER(a,b) (fabs ((a) - (b)) > EPSILON) + +void +sp_ctrlline_set_coords (SPCtrlLine *cl, gdouble x0, gdouble y0, gdouble x1, gdouble y1) +{ + g_return_if_fail (cl != NULL); + g_return_if_fail (SP_IS_CTRLLINE (cl)); + + if (DIFFER (x0, cl->s.x) || DIFFER (y0, cl->s.y) || DIFFER (x1, cl->e.x) || DIFFER (y1, cl->e.y)) { + cl->s.x = x0; + cl->s.y = y0; + cl->e.x = x1; + cl->e.y = y1; + sp_canvas_item_request_update (SP_CANVAS_ITEM (cl)); + } +} + +void +sp_ctrlline_set_coords (SPCtrlLine *cl, const NR::Point start, const NR::Point end) +{ + sp_ctrlline_set_coords(cl, start[0], start[1], end[0], end[1]); +} + +/* + 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:textwidth=99 : diff --git a/src/display/sp-ctrlline.h b/src/display/sp-ctrlline.h new file mode 100644 index 000000000..500fbf08f --- /dev/null +++ b/src/display/sp-ctrlline.h @@ -0,0 +1,45 @@ +#ifndef __INKSCAPE_CTRLLINE_H__ +#define __INKSCAPE_CTRLLINE_H__ + +/* + * Simple straight line + * + * Author: + * Lauris Kaplinski + * + * Copyright (C) 1999-2002 Lauris Kaplinski + * + * Released under GNU GPL + */ + +#include "sp-canvas.h" + + + +#define SP_TYPE_CTRLLINE (sp_ctrlline_get_type ()) +#define SP_CTRLLINE(obj) (GTK_CHECK_CAST ((obj), SP_TYPE_CTRLLINE, SPCtrlLine)) +#define SP_IS_CTRLLINE(obj) (GTK_CHECK_TYPE ((obj), SP_TYPE_CTRLLINE)) + +struct SPCtrlLine; +struct SPCtrlLineClass; + +GtkType sp_ctrlline_get_type (void); + +void sp_ctrlline_set_rgba32 (SPCtrlLine *cl, guint32 rgba); +void sp_ctrlline_set_coords (SPCtrlLine *cl, gdouble x0, gdouble y0, gdouble x1, gdouble y1); +void sp_ctrlline_set_coords (SPCtrlLine *cl, const NR::Point start, const NR::Point end); + + + +#endif + +/* + 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:textwidth=99 : diff --git a/src/display/sp-ctrlquadr.cpp b/src/display/sp-ctrlquadr.cpp new file mode 100644 index 000000000..e9488cdb5 --- /dev/null +++ b/src/display/sp-ctrlquadr.cpp @@ -0,0 +1,210 @@ +#define __INKSCAPE_CTRLQUADR_C__ + +/* + * Quadrilateral + * + * Authors: + * bulia byak + * + * Copyright (C) 2005 authors + * + * Released under GNU GPL + */ + +#include "display-forward.h" +#include "sp-canvas-util.h" +#include "sp-ctrlquadr.h" + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif +#include +#include + +struct SPCtrlQuadr : public SPCanvasItem{ + guint32 rgba; + NR::Point p1, p2, p3, p4; + Shape* shp; +}; + +struct SPCtrlQuadrClass : public SPCanvasItemClass{}; + +static void sp_ctrlquadr_class_init (SPCtrlQuadrClass *klass); +static void sp_ctrlquadr_init (SPCtrlQuadr *ctrlquadr); +static void sp_ctrlquadr_destroy (GtkObject *object); + +static void sp_ctrlquadr_update (SPCanvasItem *item, NR::Matrix const &affine, unsigned int flags); +static void sp_ctrlquadr_render (SPCanvasItem *item, SPCanvasBuf *buf); + +static SPCanvasItemClass *parent_class; + +GtkType +sp_ctrlquadr_get_type (void) +{ + static GtkType type = 0; + + if (!type) { + GtkTypeInfo info = { + "SPCtrlQuadr", + sizeof (SPCtrlQuadr), + sizeof (SPCtrlQuadrClass), + (GtkClassInitFunc) sp_ctrlquadr_class_init, + (GtkObjectInitFunc) sp_ctrlquadr_init, + NULL, NULL, NULL + }; + type = gtk_type_unique (SP_TYPE_CANVAS_ITEM, &info); + } + return type; +} + +static void +sp_ctrlquadr_class_init (SPCtrlQuadrClass *klass) +{ + GtkObjectClass *object_class = (GtkObjectClass *) klass; + SPCanvasItemClass *item_class = (SPCanvasItemClass *) klass; + + parent_class = (SPCanvasItemClass*)gtk_type_class (SP_TYPE_CANVAS_ITEM); + + object_class->destroy = sp_ctrlquadr_destroy; + + item_class->update = sp_ctrlquadr_update; + item_class->render = sp_ctrlquadr_render; +} + +static void +sp_ctrlquadr_init (SPCtrlQuadr *ctrlquadr) +{ + ctrlquadr->rgba = 0x000000ff; + ctrlquadr->p1 = NR::Point(0, 0); + ctrlquadr->p2 = NR::Point(0, 0); + ctrlquadr->p3 = NR::Point(0, 0); + ctrlquadr->p4 = NR::Point(0, 0); + ctrlquadr->shp=NULL; +} + +static void +sp_ctrlquadr_destroy (GtkObject *object) +{ + g_return_if_fail (object != NULL); + g_return_if_fail (SP_IS_CTRLQUADR (object)); + + SPCtrlQuadr *ctrlquadr = SP_CTRLQUADR (object); + + if (ctrlquadr->shp) { + delete ctrlquadr->shp; + ctrlquadr->shp = NULL; + } + + if (GTK_OBJECT_CLASS (parent_class)->destroy) + (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); +} + +static void +sp_ctrlquadr_render (SPCanvasItem *item, SPCanvasBuf *buf) +{ + SPCtrlQuadr *ctrlquadr = SP_CTRLQUADR (item); + + NRRectL area; + area.x0=buf->rect.x0; + area.x1=buf->rect.x1; + area.y0=buf->rect.y0; + area.y1=buf->rect.y1; + + if (ctrlquadr->shp) { + sp_canvas_prepare_buffer (buf); + nr_pixblock_render_ctrl_rgba (ctrlquadr->shp,ctrlquadr->rgba,area,(char*)buf->buf, buf->buf_rowstride); + } +} + +static void +sp_ctrlquadr_update (SPCanvasItem *item, NR::Matrix const &affine, unsigned int flags) +{ + NRRect dbox; + + SPCtrlQuadr *cl = SP_CTRLQUADR (item); + + sp_canvas_request_redraw (item->canvas, (int)item->x1, (int)item->y1, (int)item->x2, (int)item->y2); + + if (parent_class->update) + (* parent_class->update) (item, affine, flags); + + sp_canvas_item_reset_bounds (item); + + dbox.x0=dbox.x1=dbox.y0=dbox.y1=0; + if (cl->shp) { + delete cl->shp; + cl->shp = NULL; + } + Path* thePath = new Path; + thePath->MoveTo(cl->p1 * affine); + thePath->LineTo(cl->p2 * affine); + thePath->LineTo(cl->p3 * affine); + thePath->LineTo(cl->p4 * affine); + thePath->LineTo(cl->p1 * affine); + + thePath->Convert(1.0); + + if ( cl->shp == NULL ) cl->shp=new Shape; + thePath->Fill(cl->shp, 0); + + cl->shp->CalcBBox(); + if ( cl->shp->leftX < cl->shp->rightX ) { + if ( dbox.x0 >= dbox.x1 ) { + dbox.x0=cl->shp->leftX;dbox.x1=cl->shp->rightX; + dbox.y0=cl->shp->topY;dbox.y1=cl->shp->bottomY; + } else { + if ( cl->shp->leftX < dbox.x0 ) dbox.x0=cl->shp->leftX; + if ( cl->shp->rightX > dbox.x1 ) dbox.x1=cl->shp->rightX; + if ( cl->shp->topY < dbox.y0 ) dbox.y0=cl->shp->topY; + if ( cl->shp->bottomY > dbox.y1 ) dbox.y1=cl->shp->bottomY; + } + } + delete thePath; + + item->x1 = (int)dbox.x0; + item->y1 = (int)dbox.y0; + item->x2 = (int)dbox.x1; + item->y2 = (int)dbox.y1; + + sp_canvas_request_redraw (item->canvas, (int)item->x1, (int)item->y1, (int)item->x2, (int)item->y2); +} + +void +sp_ctrlquadr_set_rgba32 (SPCtrlQuadr *cl, guint32 rgba) +{ + g_return_if_fail (cl != NULL); + g_return_if_fail (SP_IS_CTRLQUADR (cl)); + + if (rgba != cl->rgba) { + SPCanvasItem *item; + cl->rgba = rgba; + item = SP_CANVAS_ITEM (cl); + sp_canvas_request_redraw (item->canvas, (int)item->x1, (int)item->y1, (int)item->x2, (int)item->y2); + } +} + +void +sp_ctrlquadr_set_coords (SPCtrlQuadr *cl, NR::Point p1, NR::Point p2, NR::Point p3, NR::Point p4) +{ + g_return_if_fail (cl != NULL); + g_return_if_fail (SP_IS_CTRLQUADR (cl)); + + if (p1 != cl->p1 || p2 != cl->p2 || p3 != cl->p3 || p4 != cl->p4) { + cl->p1 = p1; + cl->p2 = p2; + cl->p3 = p3; + cl->p4 = p4; + sp_canvas_item_request_update (SP_CANVAS_ITEM (cl)); + } +} + +/* + 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:textwidth=99 : diff --git a/src/display/sp-ctrlquadr.h b/src/display/sp-ctrlquadr.h new file mode 100644 index 000000000..38951448c --- /dev/null +++ b/src/display/sp-ctrlquadr.h @@ -0,0 +1,43 @@ +#ifndef __INKSCAPE_CTRLQUADR_H__ +#define __INKSCAPE_CTRLQUADR_H__ + +/* + * Quadrilateral + * + * Authors: + * bulia byak + * + * Copyright (C) 2005 authors + * + * Released under GNU GPL + */ + +#include "sp-canvas.h" + + + +#define SP_TYPE_CTRLQUADR (sp_ctrlquadr_get_type ()) +#define SP_CTRLQUADR(obj) (GTK_CHECK_CAST ((obj), SP_TYPE_CTRLQUADR, SPCtrlQuadr)) +#define SP_IS_CTRLQUADR(obj) (GTK_CHECK_TYPE ((obj), SP_TYPE_CTRLQUADR)) + +struct SPCtrlQuadr; +struct SPCtrlQuadrClass; + +GtkType sp_ctrlquadr_get_type (void); + +void sp_ctrlquadr_set_rgba32 (SPCtrlQuadr *cl, guint32 rgba); +void sp_ctrlquadr_set_coords (SPCtrlQuadr *cl, const NR::Point p1, const NR::Point p2, const NR::Point p3, const NR::Point p4); + + +#endif + +/* + 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:textwidth=99 : diff --git a/src/display/testnr.cpp b/src/display/testnr.cpp new file mode 100644 index 000000000..3a3478d28 --- /dev/null +++ b/src/display/testnr.cpp @@ -0,0 +1,24 @@ +#include +#include "sp-arena.h" + +int +main (int argc, char ** argv) +{ + GtkWidget * w, * c; + + gtk_init (&argc, &argv); + + w = gtk_window_new (GTK_WINDOW_TOPLEVEL); + + c = sp_arena_new (); + gtk_widget_show (c); + + gtk_container_add (GTK_CONTAINER (w), c); + + gtk_widget_show (w); + + gtk_main (); + + return 0; +} + diff --git a/src/document-private.h b/src/document-private.h new file mode 100644 index 000000000..34e61a9a0 --- /dev/null +++ b/src/document-private.h @@ -0,0 +1,67 @@ +#ifndef __SP_DOCUMENT_PRIVATE_H__ +#define __SP_DOCUMENT_PRIVATE_H__ + +/* + * Seldom needed document data + * + * Authors: + * Lauris Kaplinski + * + * Copyright (C) 1999-2002 Lauris Kaplinski + * Copyright (C) 2001-2002 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include +#include +#include "xml/event-fns.h" +#include "sp-defs.h" +#include "sp-root.h" +#include "document.h" + +#include "composite-undo-stack-observer.h" + +#define SP_DOCUMENT_DEFS(d) ((SPObject *) SP_ROOT (SP_DOCUMENT_ROOT (d))->defs) + +namespace Inkscape { +namespace XML { +class Event; +} +} + + +struct SPDocumentPrivate { + typedef std::map IDChangedSignalMap; + typedef std::map ResourcesChangedSignalMap; + + GHashTable *iddef; /**< Dictionary of id -> SPObject mappings */ + GHashTable *reprdef; /**< Dictionary of Inkscape::XML::Node -> SPObject mappings */ + + /** Dictionary of signals for id changes */ + IDChangedSignalMap id_changed_signals; + + /* Resources */ + /* It is GHashTable of GSLists */ + GHashTable *resources; + ResourcesChangedSignalMap resources_changed_signals; + + SPDocument::ModifiedSignal modified_signal; + SPDocument::URISetSignal uri_set_signal; + SPDocument::ResizedSignal resized_signal; + SPDocument::ReconstructionStart _reconstruction_start_signal; + SPDocument::ReconstructionFinish _reconstruction_finish_signal; + + /* Undo/Redo state */ + guint sensitive: 1; /* If we save actions to undo stack */ + Inkscape::XML::Event * partial; /* partial undo log when interrupted */ + int history_size; + GSList * undo; /* Undo stack of reprs */ + GSList * redo; /* Redo stack of reprs */ + + /* Undo listener */ + Inkscape::CompositeUndoStackObserver undoStackObservers; + +}; + +#endif diff --git a/src/document-undo.cpp b/src/document-undo.cpp new file mode 100644 index 000000000..226d38127 --- /dev/null +++ b/src/document-undo.cpp @@ -0,0 +1,322 @@ +#define __SP_DOCUMENT_UNDO_C__ + +/** \file + * Undo/Redo stack implementation + * + * Authors: + * Lauris Kaplinski + * MenTaLguY + * + * Copyright (C) 1999-2003 authors + * Copyright (C) 2001-2002 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + * + * Using the split document model gives sodipodi a very simple and clean + * undo implementation. Whenever mutation occurs in the XML tree, + * SPObject invokes one of the five corresponding handlers of its + * container document. This writes down a generic description of the + * given action, and appends it to the recent action list, kept by the + * document. There will be as many action records as there are mutation + * events, which are all kept and processed together in the undo + * stack. Two methods exist to indicate that the given action is completed: + * + * \verbatim + void sp_document_done (SPDocument *document) + void sp_document_maybe_done (SPDocument *document, const unsigned char *key) \endverbatim + * + * Both move the recent action list into the undo stack and clear the + * list afterwards. While the first method does an unconditional push, + * the second one first checks the key of the most recent stack entry. If + * the keys are identical, the current action list is appended to the + * existing stack entry, instead of pushing it onto its own. This + * behaviour can be used to collect multi-step actions (like winding the + * Gtk spinbutton) from the UI into a single undoable step. + * + * For controls implemented by Sodipodi itself, implementing undo as a + * single step is usually done in a more efficent way. Most controls have + * the abstract model of grab, drag, release, and change user + * action. During the grab phase, all modifications are done to the + * SPObject directly - i.e. they do not change XML tree, and thus do not + * generate undo actions either. Only at the release phase (normally + * associated with releasing the mousebutton), changes are written back + * to the XML tree, thus generating only a single set of undo actions. + * (Lauris Kaplinski) + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + + + +#if HAVE_STRING_H +#endif + + +#if HAVE_STDLIB_H +#endif + +#include "xml/repr.h" +#include "document-private.h" +#include "inkscape.h" +#include "debug/event-tracker.h" +#include "debug/simple-event.h" + + +/* + * Undo & redo + */ +/** + * Set undo sensitivity. + * + * \note + * Since undo sensitivity needs to be nested, setting undo sensitivity + * should be done like this: + *\verbatim + gboolean saved = sp_document_get_undo_sensitive(document); + sp_document_set_undo_sensitive(document, FALSE); + ... do stuff ... + sp_document_set_undo_sensitive(document, saved); \endverbatim + */ +void +sp_document_set_undo_sensitive (SPDocument *doc, gboolean sensitive) +{ + g_assert (doc != NULL); + g_assert (doc->priv != NULL); + + if ( !(sensitive) == !(doc->priv->sensitive) ) + return; + + if (sensitive) { + sp_repr_begin_transaction (doc->rdoc); + } else { + doc->priv->partial = sp_repr_coalesce_log ( + doc->priv->partial, + sp_repr_commit_undoable (doc->rdoc) + ); + } + + doc->priv->sensitive = !!sensitive; +} + +gboolean sp_document_get_undo_sensitive(SPDocument const *document) { + g_assert(document != NULL); + g_assert(document->priv != NULL); + + return document->priv->sensitive; +} + +void +sp_document_done (SPDocument *doc) +{ + sp_document_maybe_done (doc, NULL); +} + +void +sp_document_reset_key (Inkscape::Application *inkscape, SPDesktop *desktop, GtkObject *base) +{ + SPDocument *doc = (SPDocument *) base; + doc->actionkey = NULL; +} + +void +sp_document_maybe_done (SPDocument *doc, const gchar *key) +{ + g_assert (doc != NULL); + g_assert (doc->priv != NULL); + g_assert (doc->priv->sensitive); + + doc->collectOrphans(); + + sp_document_ensure_up_to_date (doc); + + sp_document_clear_redo (doc); + + Inkscape::XML::Event *log = sp_repr_coalesce_log (doc->priv->partial, sp_repr_commit_undoable (doc->rdoc)); + doc->priv->partial = NULL; + + if (!log) { + sp_repr_begin_transaction (doc->rdoc); + return; + } + + if (key && doc->actionkey && !strcmp (key, doc->actionkey) && doc->priv->undo) { + doc->priv->undo->data = sp_repr_coalesce_log ((Inkscape::XML::Event *)doc->priv->undo->data, log); + } else { + doc->priv->undo = g_slist_prepend (doc->priv->undo, log); + doc->priv->history_size++; + doc->priv->undoStackObservers.notifyUndoCommitEvent(log); + } + + doc->actionkey = key; + + doc->virgin = FALSE; + if (!doc->rroot->attribute("sodipodi:modified")) { + doc->rroot->setAttribute("sodipodi:modified", "true"); + } + + sp_repr_begin_transaction (doc->rdoc); +} + +void +sp_document_cancel (SPDocument *doc) +{ + g_assert (doc != NULL); + g_assert (doc->priv != NULL); + g_assert (doc->priv->sensitive); + + sp_repr_rollback (doc->rdoc); + + if (doc->priv->partial) { + sp_repr_undo_log (doc->priv->partial); + sp_repr_free_log (doc->priv->partial); + doc->priv->partial = NULL; + } + + sp_repr_begin_transaction (doc->rdoc); +} + +namespace { + +void finish_incomplete_transaction(SPDocument &doc) { + SPDocumentPrivate &priv=*doc.priv; + Inkscape::XML::Event *log=sp_repr_commit_undoable(doc.rdoc); + if (log || priv.partial) { + g_warning ("Incomplete undo transaction:"); + priv.partial = sp_repr_coalesce_log(priv.partial, log); + sp_repr_debug_print_log(priv.partial); + priv.undo = g_slist_prepend(priv.undo, priv.partial); + priv.partial = NULL; + } +} + +} + +gboolean +sp_document_undo (SPDocument *doc) +{ + using Inkscape::Debug::EventTracker; + using Inkscape::Debug::SimpleEvent; + + gboolean ret; + + EventTracker > tracker("undo"); + + g_assert (doc != NULL); + g_assert (doc->priv != NULL); + g_assert (doc->priv->sensitive); + + doc->priv->sensitive = FALSE; + + doc->actionkey = NULL; + + finish_incomplete_transaction(*doc); + + if (doc->priv->undo) { + Inkscape::XML::Event *log=(Inkscape::XML::Event *)doc->priv->undo->data; + doc->priv->undo = g_slist_remove (doc->priv->undo, log); + sp_repr_undo_log (log); + doc->priv->redo = g_slist_prepend (doc->priv->redo, log); + + doc->rroot->setAttribute("sodipodi:modified", "true"); + doc->priv->undoStackObservers.notifyUndoEvent(log); + + ret = TRUE; + } else { + ret = FALSE; + } + + sp_repr_begin_transaction (doc->rdoc); + + doc->priv->sensitive = TRUE; + + if (ret) + inkscape_external_change(); + + return ret; +} + +gboolean +sp_document_redo (SPDocument *doc) +{ + using Inkscape::Debug::EventTracker; + using Inkscape::Debug::SimpleEvent; + + gboolean ret; + + EventTracker > tracker("redo"); + + g_assert (doc != NULL); + g_assert (doc->priv != NULL); + g_assert (doc->priv->sensitive); + + doc->priv->sensitive = FALSE; + + doc->actionkey = NULL; + + finish_incomplete_transaction(*doc); + + if (doc->priv->redo) { + Inkscape::XML::Event *log=(Inkscape::XML::Event *)doc->priv->redo->data; + doc->priv->redo = g_slist_remove (doc->priv->redo, log); + sp_repr_replay_log (log); + doc->priv->undo = g_slist_prepend (doc->priv->undo, log); + + doc->rroot->setAttribute("sodipodi:modified", "true"); + doc->priv->undoStackObservers.notifyRedoEvent(log); + + ret = TRUE; + } else { + ret = FALSE; + } + + sp_repr_begin_transaction (doc->rdoc); + + doc->priv->sensitive = TRUE; + + if (ret) + inkscape_external_change(); + + return ret; +} + +void +sp_document_clear_undo (SPDocument *doc) +{ + while (doc->priv->undo) { + GSList *current; + + current = doc->priv->undo; + doc->priv->undo = current->next; + doc->priv->history_size--; + + sp_repr_free_log ((Inkscape::XML::Event *)current->data); + g_slist_free_1 (current); + } +} + +void +sp_document_clear_redo (SPDocument *doc) +{ + while (doc->priv->redo) { + GSList *current; + + current = doc->priv->redo; + doc->priv->redo = current->next; + doc->priv->history_size--; + + sp_repr_free_log ((Inkscape::XML::Event *)current->data); + g_slist_free_1 (current); + } +} +/* + 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 : diff --git a/src/document.cpp b/src/document.cpp new file mode 100644 index 000000000..f69c480f7 --- /dev/null +++ b/src/document.cpp @@ -0,0 +1,1093 @@ +#define __SP_DOCUMENT_C__ + +/** \file + * SPDocument manipulation + * + * Authors: + * Lauris Kaplinski + * MenTaLguY + * bulia byak + * + * Copyright (C) 2004-2005 MenTaLguY + * Copyright (C) 1999-2002 Lauris Kaplinski + * Copyright (C) 2000-2001 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +/** \class SPDocument + * SPDocument serves as the container of both model trees (agnostic XML + * and typed object tree), and implements all of the document-level + * functionality used by the program. Many document level operations, like + * load, save, print, export and so on, use SPDocument as their basic datatype. + * + * SPDocument implements undo and redo stacks and an id-based object + * dictionary. Thanks to unique id attributes, the latter can be used to + * map from the XML tree back to the object tree. + * + * SPDocument performs the basic operations needed for asynchronous + * update notification (SPObject ::modified virtual method), and implements + * the 'modified' signal, as well. + */ + + +#define noSP_DOCUMENT_DEBUG_IDLE +#define noSP_DOCUMENT_DEBUG_UNDO + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif +#include +#include "application/application.h" +#include "application/editor.h" +#include "libnr/nr-matrix-fns.h" +#include "xml/repr.h" +#include "helper/units.h" +#include "inkscape-private.h" +#include "inkscape_version.h" +#include "sp-object-repr.h" +#include "document-private.h" +#include "dir-util.h" +#include "unit-constants.h" +#include "prefs-utils.h" + +#include "display/nr-arena-item.h" + +#include "dialogs/rdf.h" + +#define A4_WIDTH_STR "210mm" +#define A4_HEIGHT_STR "297mm" + +#define SP_DOCUMENT_UPDATE_PRIORITY (G_PRIORITY_HIGH_IDLE - 1) + + +static gint sp_document_idle_handler(gpointer data); + +gboolean sp_document_resource_list_free(gpointer key, gpointer value, gpointer data); + +static gint doc_count = 0; + +SPDocument::SPDocument() { + SPDocumentPrivate *p; + + keepalive = FALSE; + virgin = TRUE; + + modified_id = 0; + + rdoc = NULL; + rroot = NULL; + root = NULL; + style_cascade = cr_cascade_new(NULL, NULL, NULL); + + uri = NULL; + base = NULL; + name = NULL; + + _collection_queue = NULL; + + p = new SPDocumentPrivate(); + + p->iddef = g_hash_table_new(g_direct_hash, g_direct_equal); + p->reprdef = g_hash_table_new(g_direct_hash, g_direct_equal); + + p->resources = g_hash_table_new(g_str_hash, g_str_equal); + + p->sensitive = FALSE; + p->partial = NULL; + p->history_size = 0; + p->undo = NULL; + p->redo = NULL; + + priv = p; +} + +SPDocument::~SPDocument() { + collectOrphans(); + + if (priv) { + inkscape_remove_document(this); + + if (priv->partial) { + sp_repr_free_log(priv->partial); + priv->partial = NULL; + } + + sp_document_clear_redo(this); + sp_document_clear_undo(this); + + if (root) { + sp_object_invoke_release(root); + g_object_unref(G_OBJECT(root)); + root = NULL; + } + + if (priv->iddef) g_hash_table_destroy(priv->iddef); + if (priv->reprdef) g_hash_table_destroy(priv->reprdef); + + if (rdoc) Inkscape::GC::release(rdoc); + + /* Free resources */ + g_hash_table_foreach_remove(priv->resources, sp_document_resource_list_free, this); + g_hash_table_destroy(priv->resources); + + delete priv; + priv = NULL; + } + + cr_cascade_unref(style_cascade); + style_cascade = NULL; + + if (name) { + g_free(name); + name = NULL; + } + if (base) { + g_free(base); + base = NULL; + } + if (uri) { + g_free(uri); + uri = NULL; + } + + if (modified_id) { + gtk_idle_remove(modified_id); + modified_id = 0; + } + + _selection_changed_connection.disconnect(); + _desktop_activated_connection.disconnect(); + + if (keepalive) { + inkscape_unref(); + keepalive = FALSE; + } + + //delete this->_whiteboard_session_manager; +} + +void SPDocument::queueForOrphanCollection(SPObject *object) { + g_return_if_fail(object != NULL); + g_return_if_fail(SP_OBJECT_DOCUMENT(object) == this); + + sp_object_ref(object, NULL); + _collection_queue = g_slist_prepend(_collection_queue, object); +} + +void SPDocument::collectOrphans() { + while (_collection_queue) { + GSList *objects=_collection_queue; + _collection_queue = NULL; + for ( GSList *iter=objects ; iter ; iter = iter->next ) { + SPObject *object=reinterpret_cast(iter->data); + object->collectOrphan(); + sp_object_unref(object, NULL); + } + g_slist_free(objects); + } +} + +void SPDocument::reset_key (void *dummy) +{ + actionkey = NULL; +} + +static SPDocument * +sp_document_create(Inkscape::XML::Document *rdoc, + gchar const *uri, + gchar const *base, + gchar const *name, + unsigned int keepalive) +{ + SPDocument *document; + Inkscape::XML::Node *rroot; + Inkscape::Version sodipodi_version; + + rroot = sp_repr_document_root(rdoc); + + document = new SPDocument(); + + document->keepalive = keepalive; + + document->rdoc = rdoc; + document->rroot = rroot; + +#ifndef WIN32 + prepend_current_dir_if_relative(&(document->uri), uri); +#else + // FIXME: it may be that prepend_current_dir_if_relative works OK on windows too, test! + document->uri = uri? g_strdup(uri) : NULL; +#endif + + // base is simply the part of the path before filename; e.g. when running "inkscape ../file.svg" the base is "../" + // which is why we use g_get_current_dir() in calculating the abs path above + //This is NULL for a new document + if (base) + document->base = g_strdup(base); + else + document->base = NULL; + document->name = g_strdup(name); + + document->root = sp_object_repr_build_tree(document, rroot); + + sodipodi_version = SP_ROOT(document->root)->version.sodipodi; + + /* fixme: Not sure about this, but lets assume ::build updates */ + rroot->setAttribute("sodipodi:version", SODIPODI_VERSION); + rroot->setAttribute("inkscape:version", INKSCAPE_VERSION); + /* fixme: Again, I moved these here to allow version determining in ::build (Lauris) */ + + /* Quick hack 2 - get default image size into document */ + if (!rroot->attribute("width")) rroot->setAttribute("width", A4_WIDTH_STR); + if (!rroot->attribute("height")) rroot->setAttribute("height", A4_HEIGHT_STR); + /* End of quick hack 2 */ + + /* Quick hack 3 - Set uri attributes */ + if (uri) { + /* fixme: Think, what this means for images (Lauris) */ + rroot->setAttribute("sodipodi:docname", uri); + if (document->base) + rroot->setAttribute("sodipodi:docbase", document->base); + } + /* End of quick hack 3 */ + + // creating namedview + if (!sp_item_group_get_child_by_name((SPGroup *) document->root, NULL, "sodipodi:namedview")) { + // if there's none in the document already, + Inkscape::XML::Node *r = NULL; + Inkscape::XML::Node *rnew = NULL; + r = inkscape_get_repr(INKSCAPE, "template.base"); + // see if there's a template with id="base" in the preferences + if (!r) { + // if there's none, create an empty element + rnew = sp_repr_new("sodipodi:namedview"); + rnew->setAttribute("id", "base"); + } else { + // otherwise, take from preferences + rnew = r->duplicate(); + } + // insert into the document + rroot->addChild(rnew, NULL); + // clean up + Inkscape::GC::release(rnew); + } + + /* Defs */ + if (!SP_ROOT(document->root)->defs) { + Inkscape::XML::Node *r; + r = sp_repr_new("svg:defs"); + rroot->addChild(r, NULL); + Inkscape::GC::release(r); + g_assert(SP_ROOT(document->root)->defs); + } + + /* Default RDF */ + rdf_set_defaults( document ); + + if (keepalive) { + inkscape_ref(); + } + + sp_document_set_undo_sensitive(document, TRUE); + + // reset undo key when selection changes, so that same-key actions on different objects are not coalesced + if (!Inkscape::NSApplication::Application::getNewGui()) { + g_signal_connect(G_OBJECT(INKSCAPE), "change_selection", + G_CALLBACK(sp_document_reset_key), document); + g_signal_connect(G_OBJECT(INKSCAPE), "activate_desktop", + G_CALLBACK(sp_document_reset_key), document); + } else { + document->_selection_changed_connection = Inkscape::NSApplication::Editor::connectSelectionChanged (sigc::mem_fun (*document, &SPDocument::reset_key)); + document->_desktop_activated_connection = Inkscape::NSApplication::Editor::connectDesktopActivated (sigc::mem_fun (*document, &SPDocument::reset_key)); + } + inkscape_add_document(document); + + return document; +} + +/** + * Fetches document from URI, or creates new, if NULL; public document + * appears in document list. + */ +SPDocument * +sp_document_new(gchar const *uri, unsigned int keepalive, bool make_new) +{ + SPDocument *doc; + Inkscape::XML::Document *rdoc; + gchar *base = NULL; + gchar *name = NULL; + + if (uri) { + Inkscape::XML::Node *rroot; + gchar *s, *p; + /* Try to fetch repr from file */ + rdoc = sp_repr_read_file(uri, SP_SVG_NS_URI); + /* If file cannot be loaded, return NULL without warning */ + if (rdoc == NULL) return NULL; + rroot = sp_repr_document_root(rdoc); + /* If xml file is not svg, return NULL without warning */ + /* fixme: destroy document */ + if (strcmp(rroot->name(), "svg:svg") != 0) return NULL; + s = g_strdup(uri); + p = strrchr(s, '/'); + if (p) { + name = g_strdup(p + 1); + p[1] = '\0'; + base = g_strdup(s); + } else { + base = NULL; + name = g_strdup(uri); + } + g_free(s); + } else { + rdoc = sp_repr_document_new("svg:svg"); + } + + if (make_new) { + base = NULL; + uri = NULL; + name = g_strdup_printf(_("New document %d"), ++doc_count); + } + + //# These should be set by now + g_assert(name); + + doc = sp_document_create(rdoc, uri, base, name, keepalive); + + g_free(base); + g_free(name); + + return doc; +} + +SPDocument * +sp_document_new_from_mem(gchar const *buffer, gint length, unsigned int keepalive) +{ + SPDocument *doc; + Inkscape::XML::Document *rdoc; + Inkscape::XML::Node *rroot; + gchar *name; + + rdoc = sp_repr_read_mem(buffer, length, SP_SVG_NS_URI); + + /* If it cannot be loaded, return NULL without warning */ + if (rdoc == NULL) return NULL; + + rroot = sp_repr_document_root(rdoc); + /* If xml file is not svg, return NULL without warning */ + /* fixme: destroy document */ + if (strcmp(rroot->name(), "svg:svg") != 0) return NULL; + + name = g_strdup_printf(_("Memory document %d"), ++doc_count); + + doc = sp_document_create(rdoc, NULL, NULL, name, keepalive); + + return doc; +} + +SPDocument *sp_document_new_dummy() { + SPDocument *document = new SPDocument(); + inkscape_add_document(document); + return document; +} + +SPDocument * +sp_document_ref(SPDocument *doc) +{ + g_return_val_if_fail(doc != NULL, NULL); + Inkscape::GC::anchor(doc); + return doc; +} + +SPDocument * +sp_document_unref(SPDocument *doc) +{ + g_return_val_if_fail(doc != NULL, NULL); + Inkscape::GC::release(doc); + return NULL; +} + +gdouble sp_document_width(SPDocument *document) +{ + g_return_val_if_fail(document != NULL, 0.0); + g_return_val_if_fail(document->priv != NULL, 0.0); + g_return_val_if_fail(document->root != NULL, 0.0); + + return SP_ROOT(document->root)->width.computed; +} + +void +sp_document_set_width (SPDocument *document, gdouble width, const SPUnit *unit) +{ + SPRoot *root = SP_ROOT(document->root); + + if (root->width.unit == SVGLength::PERCENT && root->viewBox_set) { // set to viewBox= + root->viewBox.x1 = root->viewBox.x0 + sp_units_get_pixels (width, *unit); + } else { // set to width= + root->width.computed = sp_units_get_pixels (width, *unit); + /* SVG does not support meters as a unit, so we must translate meters to + * cm when writing */ + if (!strcmp(unit->abbr, "m")) { + root->width.value = 100*width; + root->width.unit = SVGLength::CM; + } else { + root->width.value = width; + root->width.unit = (SVGLength::Unit) sp_unit_get_svg_unit(unit); + } + } + + SP_OBJECT (root)->updateRepr(); +} + +void sp_document_set_height (SPDocument * document, gdouble height, const SPUnit *unit) +{ + SPRoot *root = SP_ROOT(document->root); + + if (root->height.unit == SVGLength::PERCENT && root->viewBox_set) { // set to viewBox= + root->viewBox.y1 = root->viewBox.y0 + sp_units_get_pixels (height, *unit); + } else { // set to height= + root->height.computed = sp_units_get_pixels (height, *unit); + /* SVG does not support meters as a unit, so we must translate meters to + * cm when writing */ + if (!strcmp(unit->abbr, "m")) { + root->height.value = 100*height; + root->height.unit = SVGLength::CM; + } else { + root->height.value = height; + root->height.unit = (SVGLength::Unit) sp_unit_get_svg_unit(unit); + } + } + + SP_OBJECT (root)->updateRepr(); +} + +gdouble sp_document_height(SPDocument *document) +{ + g_return_val_if_fail(document != NULL, 0.0); + g_return_val_if_fail(document->priv != NULL, 0.0); + g_return_val_if_fail(document->root != NULL, 0.0); + + return SP_ROOT(document->root)->height.computed; +} + +void sp_document_set_uri(SPDocument *document, gchar const *uri) +{ + g_return_if_fail(document != NULL); + + if (document->name) { + g_free(document->name); + document->name = NULL; + } + if (document->base) { + g_free(document->base); + document->base = NULL; + } + if (document->uri) { + g_free(document->uri); + document->uri = NULL; + } + + if (uri) { + +#ifndef WIN32 + prepend_current_dir_if_relative(&(document->uri), uri); +#else + // FIXME: it may be that prepend_current_dir_if_relative works OK on windows too, test! + document->uri = g_strdup(uri); +#endif + + /* fixme: Think, what this means for images (Lauris) */ + document->base = g_path_get_dirname(document->uri); + document->name = g_path_get_basename(document->uri); + + } else { + document->uri = g_strdup_printf(_("Unnamed document %d"), ++doc_count); + document->base = NULL; + document->name = g_strdup(document->uri); + } + + // Update saveable repr attributes. + Inkscape::XML::Node *repr = sp_document_repr_root(document); + // changing uri in the document repr must not be not undoable + gboolean saved = sp_document_get_undo_sensitive(document); + sp_document_set_undo_sensitive(document, FALSE); + if (document->base) + repr->setAttribute("sodipodi:docbase", document->base); + + repr->setAttribute("sodipodi:docname", document->name); + sp_document_set_undo_sensitive(document, saved); + + document->priv->uri_set_signal.emit(document->uri); +} + +void +sp_document_resized_signal_emit(SPDocument *doc, gdouble width, gdouble height) +{ + g_return_if_fail(doc != NULL); + + doc->priv->resized_signal.emit(width, height); +} + +sigc::connection SPDocument::connectModified(SPDocument::ModifiedSignal::slot_type slot) +{ + return priv->modified_signal.connect(slot); +} + +sigc::connection SPDocument::connectURISet(SPDocument::URISetSignal::slot_type slot) +{ + return priv->uri_set_signal.connect(slot); +} + +sigc::connection SPDocument::connectResized(SPDocument::ResizedSignal::slot_type slot) +{ + return priv->resized_signal.connect(slot); +} + +sigc::connection +SPDocument::connectReconstructionStart(SPDocument::ReconstructionStart::slot_type slot) +{ + return priv->_reconstruction_start_signal.connect(slot); +} + +void +SPDocument::emitReconstructionStart(void) +{ + // printf("Starting Reconstruction\n"); + priv->_reconstruction_start_signal.emit(); + return; +} + +sigc::connection +SPDocument::connectReconstructionFinish(SPDocument::ReconstructionFinish::slot_type slot) +{ + return priv->_reconstruction_finish_signal.connect(slot); +} + +void +SPDocument::emitReconstructionFinish(void) +{ + // printf("Finishing Reconstruction\n"); + priv->_reconstruction_finish_signal.emit(); + return; +} + + +void SPDocument::_emitModified() { + static guint const flags = SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG | SP_OBJECT_PARENT_MODIFIED_FLAG; + root->emitModified(0); + priv->modified_signal.emit(flags); +} + +void SPDocument::bindObjectToId(gchar const *id, SPObject *object) { + GQuark idq = g_quark_from_string(id); + + if (object) { + g_assert(g_hash_table_lookup(priv->iddef, GINT_TO_POINTER(idq)) == NULL); + g_hash_table_insert(priv->iddef, GINT_TO_POINTER(idq), object); + } else { + g_assert(g_hash_table_lookup(priv->iddef, GINT_TO_POINTER(idq)) != NULL); + g_hash_table_remove(priv->iddef, GINT_TO_POINTER(idq)); + } + + SPDocumentPrivate::IDChangedSignalMap::iterator pos; + + pos = priv->id_changed_signals.find(idq); + if ( pos != priv->id_changed_signals.end() ) { + if (!(*pos).second.empty()) { + (*pos).second.emit(object); + } else { // discard unused signal + priv->id_changed_signals.erase(pos); + } + } +} + +void +SPDocument::addUndoObserver(Inkscape::UndoStackObserver& observer) +{ + this->priv->undoStackObservers.add(observer); +} + +void +SPDocument::removeUndoObserver(Inkscape::UndoStackObserver& observer) +{ + this->priv->undoStackObservers.remove(observer); +} + +SPObject *SPDocument::getObjectById(gchar const *id) { + g_return_val_if_fail(id != NULL, NULL); + + GQuark idq = g_quark_from_string(id); + return (SPObject*)g_hash_table_lookup(priv->iddef, GINT_TO_POINTER(idq)); +} + +sigc::connection SPDocument::connectIdChanged(gchar const *id, + SPDocument::IDChangedSignal::slot_type slot) +{ + return priv->id_changed_signals[g_quark_from_string(id)].connect(slot); +} + +void SPDocument::bindObjectToRepr(Inkscape::XML::Node *repr, SPObject *object) { + if (object) { + g_assert(g_hash_table_lookup(priv->reprdef, repr) == NULL); + g_hash_table_insert(priv->reprdef, repr, object); + } else { + g_assert(g_hash_table_lookup(priv->reprdef, repr) != NULL); + g_hash_table_remove(priv->reprdef, repr); + } +} + +SPObject *SPDocument::getObjectByRepr(Inkscape::XML::Node *repr) { + g_return_val_if_fail(repr != NULL, NULL); + return (SPObject*)g_hash_table_lookup(priv->reprdef, repr); +} + +/* Object modification root handler */ + +void +sp_document_request_modified(SPDocument *doc) +{ + if (!doc->modified_id) { + doc->modified_id = gtk_idle_add_priority(SP_DOCUMENT_UPDATE_PRIORITY, sp_document_idle_handler, doc); + } +} + +void +sp_document_setup_viewport (SPDocument *doc, SPItemCtx *ctx) +{ + ctx->ctx.flags = 0; + ctx->i2doc = NR::identity(); + /* Set up viewport in case svg has it defined as percentages */ + if (SP_ROOT(doc->root)->viewBox_set) { // if set, take from viewBox + ctx->vp.x0 = SP_ROOT(doc->root)->viewBox.x0; + ctx->vp.y0 = SP_ROOT(doc->root)->viewBox.y0; + ctx->vp.x1 = SP_ROOT(doc->root)->viewBox.x1; + ctx->vp.y1 = SP_ROOT(doc->root)->viewBox.y1; + } else { // as a last resort, set size to A4 + ctx->vp.x0 = 0.0; + ctx->vp.y0 = 0.0; + ctx->vp.x1 = 210 * PX_PER_MM; + ctx->vp.y1 = 297 * PX_PER_MM; + } + ctx->i2vp = NR::identity(); +} + +gint +sp_document_ensure_up_to_date(SPDocument *doc) +{ + int lc; + lc = 32; + while (doc->root->uflags || doc->root->mflags) { + lc -= 1; + if (lc < 0) { + g_warning("More than 32 iterations while updating document '%s'", doc->uri); + if (doc->modified_id) { + /* Remove handler */ + gtk_idle_remove(doc->modified_id); + doc->modified_id = 0; + } + return FALSE; + } + /* Process updates */ + if (doc->root->uflags) { + SPItemCtx ctx; + sp_document_setup_viewport (doc, &ctx); + doc->root->updateDisplay((SPCtx *)&ctx, 0); + } + doc->_emitModified(); + } + if (doc->modified_id) { + /* Remove handler */ + gtk_idle_remove(doc->modified_id); + doc->modified_id = 0; + } + return TRUE; +} + +static gint +sp_document_idle_handler(gpointer data) +{ + SPDocument *doc; + int repeat; + + doc = static_cast(data); + +#ifdef SP_DOCUMENT_DEBUG_IDLE + g_print("->\n"); +#endif + + /* Process updates */ + if (doc->root->uflags) { + SPItemCtx ctx; + sp_document_setup_viewport (doc, &ctx); + + gboolean saved = sp_document_get_undo_sensitive(doc); + sp_document_set_undo_sensitive(doc, FALSE); + + doc->root->updateDisplay((SPCtx *)&ctx, 0); + + sp_document_set_undo_sensitive(doc, saved); + /* if (doc->root->uflags & SP_OBJECT_MODIFIED_FLAG) return TRUE; */ + } + + doc->_emitModified(); + + repeat = (doc->root->uflags || doc->root->mflags); + if (!repeat) doc->modified_id = 0; + return repeat; +} + +static bool is_within(NR::Rect const &area, NR::Rect const &box) +{ + return area.contains(box); +} + +static bool overlaps(NR::Rect const &area, NR::Rect const &box) +{ + return area.intersects(box); +} + +static GSList *find_items_in_area(GSList *s, SPGroup *group, unsigned int dkey, NR::Rect const &area, + bool (*test)(NR::Rect const &, NR::Rect const &), bool take_insensitive = false) +{ + g_return_val_if_fail(SP_IS_GROUP(group), s); + + for (SPObject *o = sp_object_first_child(SP_OBJECT(group)) ; o != NULL ; o = SP_OBJECT_NEXT(o) ) { + if (!SP_IS_ITEM(o)) { + continue; + } + if (SP_IS_GROUP(o) && SP_GROUP(o)->effectiveLayerMode(dkey) == SPGroup::LAYER ) { + s = find_items_in_area(s, SP_GROUP(o), dkey, area, test); + } else { + SPItem *child = SP_ITEM(o); + NR::Rect box = sp_item_bbox_desktop(child); + if (test(area, box) && (take_insensitive || child->isVisibleAndUnlocked(dkey))) { + s = g_slist_append(s, child); + } + } + } + + return s; +} + +/** +Returns true if an item is among the descendants of group (recursively). + */ +bool item_is_in_group(SPItem *item, SPGroup *group) +{ + for (SPObject *o = sp_object_first_child(SP_OBJECT(group)) ; o != NULL ; o = SP_OBJECT_NEXT(o) ) { + if (!SP_IS_ITEM(o)) continue; + if (SP_ITEM(o) == item) + return true; + if (SP_IS_GROUP(o)) + if (item_is_in_group(item, SP_GROUP(o))) + return true; + } + return false; +} + +/** +Returns the bottommost item from the list which is at the point, or NULL if none. +*/ +SPItem* +sp_document_item_from_list_at_point_bottom(unsigned int dkey, SPGroup *group, GSList const *list, + NR::Point const p, bool take_insensitive) +{ + g_return_val_if_fail(group, NULL); + + gdouble delta = prefs_get_double_attribute ("options.cursortolerance", "value", 1.0); + + for (SPObject *o = sp_object_first_child(SP_OBJECT(group)) ; o != NULL ; o = SP_OBJECT_NEXT(o) ) { + + if (!SP_IS_ITEM(o)) continue; + + SPItem *item = SP_ITEM(o); + NRArenaItem *arenaitem = sp_item_get_arenaitem(item, dkey); + if (arenaitem && nr_arena_item_invoke_pick(arenaitem, p, delta, 1) != NULL + && (take_insensitive || item->isVisibleAndUnlocked(dkey))) { + if (g_slist_find((GSList *) list, item) != NULL) + return item; + } + + if (SP_IS_GROUP(o)) { + SPItem *found = sp_document_item_from_list_at_point_bottom(dkey, SP_GROUP(o), list, p, take_insensitive); + if (found) + return found; + } + + } + return NULL; +} + +/** +Returns the topmost (in z-order) item from the descendants of group (recursively) which +is at the point p, or NULL if none. Honors into_groups on whether to recurse into +non-layer groups or not. Honors take_insensitive on whether to return insensitive +items. If upto != NULL, then if item upto is encountered (at any level), stops searching +upwards in z-order and returns what it has found so far (i.e. the found item is +guaranteed to be lower than upto). + */ +SPItem* +find_item_at_point(unsigned int dkey, SPGroup *group, NR::Point const p, gboolean into_groups, bool take_insensitive = false, SPItem *upto = NULL) +{ + SPItem *seen = NULL, *newseen = NULL; + + gdouble delta = prefs_get_double_attribute ("options.cursortolerance", "value", 1.0); + + for (SPObject *o = sp_object_first_child(SP_OBJECT(group)) ; o != NULL ; o = SP_OBJECT_NEXT(o) ) { + if (!SP_IS_ITEM(o)) continue; + + if (upto && SP_ITEM(o) == upto) + break; + + if (SP_IS_GROUP(o) && (SP_GROUP(o)->effectiveLayerMode(dkey) == SPGroup::LAYER || into_groups)) { + // if nothing found yet, recurse into the group + newseen = find_item_at_point(dkey, SP_GROUP(o), p, into_groups, take_insensitive, upto); + if (newseen) { + seen = newseen; + newseen = NULL; + } + + if (item_is_in_group(upto, SP_GROUP(o))) + break; + + } else { + SPItem *child = SP_ITEM(o); + NRArenaItem *arenaitem = sp_item_get_arenaitem(child, dkey); + + // seen remembers the last (topmost) of items pickable at this point + if (arenaitem && nr_arena_item_invoke_pick(arenaitem, p, delta, 1) != NULL + && (take_insensitive || child->isVisibleAndUnlocked(dkey))) { + seen = child; + } + } + } + return seen; +} + +/** +Returns the topmost non-layer group from the descendants of group which is at point +p, or NULL if none. Recurses into layers but not into groups. + */ +SPItem* +find_group_at_point(unsigned int dkey, SPGroup *group, NR::Point const p) +{ + SPItem *seen = NULL; + + gdouble delta = prefs_get_double_attribute ("options.cursortolerance", "value", 1.0); + + for (SPObject *o = sp_object_first_child(SP_OBJECT(group)) ; o != NULL ; o = SP_OBJECT_NEXT(o) ) { + if (!SP_IS_ITEM(o)) continue; + if (SP_IS_GROUP(o) && SP_GROUP(o)->effectiveLayerMode(dkey) == SPGroup::LAYER) { + SPItem *newseen = find_group_at_point(dkey, SP_GROUP(o), p); + if (newseen) { + seen = newseen; + } + } + if (SP_IS_GROUP(o) && SP_GROUP(o)->effectiveLayerMode(dkey) != SPGroup::LAYER ) { + SPItem *child = SP_ITEM(o); + NRArenaItem *arenaitem = sp_item_get_arenaitem(child, dkey); + + // seen remembers the last (topmost) of groups pickable at this point + if (arenaitem && nr_arena_item_invoke_pick(arenaitem, p, delta, 1) != NULL) { + seen = child; + } + } + } + return seen; +} + +/* + * Return list of items, contained in box + * + * Assumes box is normalized (and g_asserts it!) + * + */ + +GSList *sp_document_items_in_box(SPDocument *document, unsigned int dkey, NR::Rect const &box) +{ + g_return_val_if_fail(document != NULL, NULL); + g_return_val_if_fail(document->priv != NULL, NULL); + + return find_items_in_area(NULL, SP_GROUP(document->root), dkey, box, is_within); +} + +/* + * Return list of items, that the parts of the item contained in box + * + * Assumes box is normalized (and g_asserts it!) + * + */ + +GSList *sp_document_partial_items_in_box(SPDocument *document, unsigned int dkey, NR::Rect const &box) +{ + g_return_val_if_fail(document != NULL, NULL); + g_return_val_if_fail(document->priv != NULL, NULL); + + return find_items_in_area(NULL, SP_GROUP(document->root), dkey, box, overlaps); +} + +SPItem * +sp_document_item_at_point(SPDocument *document, unsigned const key, NR::Point const p, + gboolean const into_groups, SPItem *upto) +{ + g_return_val_if_fail(document != NULL, NULL); + g_return_val_if_fail(document->priv != NULL, NULL); + + return find_item_at_point(key, SP_GROUP(document->root), p, into_groups, false, upto); +} + +SPItem* +sp_document_group_at_point(SPDocument *document, unsigned int key, NR::Point const p) +{ + g_return_val_if_fail(document != NULL, NULL); + g_return_val_if_fail(document->priv != NULL, NULL); + + return find_group_at_point(key, SP_GROUP(document->root), p); +} + + +/* Resource management */ + +gboolean +sp_document_add_resource(SPDocument *document, gchar const *key, SPObject *object) +{ + GSList *rlist; + GQuark q = g_quark_from_string(key); + + g_return_val_if_fail(document != NULL, FALSE); + g_return_val_if_fail(key != NULL, FALSE); + g_return_val_if_fail(*key != '\0', FALSE); + g_return_val_if_fail(object != NULL, FALSE); + g_return_val_if_fail(SP_IS_OBJECT(object), FALSE); + + if (SP_OBJECT_IS_CLONED(object)) + return FALSE; + + rlist = (GSList*)g_hash_table_lookup(document->priv->resources, key); + g_return_val_if_fail(!g_slist_find(rlist, object), FALSE); + rlist = g_slist_prepend(rlist, object); + g_hash_table_insert(document->priv->resources, (gpointer) key, rlist); + + document->priv->resources_changed_signals[q].emit(); + + return TRUE; +} + +gboolean +sp_document_remove_resource(SPDocument *document, gchar const *key, SPObject *object) +{ + GSList *rlist; + GQuark q = g_quark_from_string(key); + + g_return_val_if_fail(document != NULL, FALSE); + g_return_val_if_fail(key != NULL, FALSE); + g_return_val_if_fail(*key != '\0', FALSE); + g_return_val_if_fail(object != NULL, FALSE); + g_return_val_if_fail(SP_IS_OBJECT(object), FALSE); + + rlist = (GSList*)g_hash_table_lookup(document->priv->resources, key); + g_return_val_if_fail(rlist != NULL, FALSE); + g_return_val_if_fail(g_slist_find(rlist, object), FALSE); + rlist = g_slist_remove(rlist, object); + g_hash_table_insert(document->priv->resources, (gpointer) key, rlist); + + document->priv->resources_changed_signals[q].emit(); + + return TRUE; +} + +GSList const * +sp_document_get_resource_list(SPDocument *document, gchar const *key) +{ + g_return_val_if_fail(document != NULL, NULL); + g_return_val_if_fail(key != NULL, NULL); + g_return_val_if_fail(*key != '\0', NULL); + + return (GSList*)g_hash_table_lookup(document->priv->resources, key); +} + +sigc::connection sp_document_resources_changed_connect(SPDocument *document, + gchar const *key, + SPDocument::ResourcesChangedSignal::slot_type slot) +{ + GQuark q = g_quark_from_string(key); + return document->priv->resources_changed_signals[q].connect(slot); +} + +/* Helpers */ + +gboolean +sp_document_resource_list_free(gpointer key, gpointer value, gpointer data) +{ + g_slist_free((GSList *) value); + return TRUE; +} + +unsigned int +count_objects_recursive(SPObject *obj, unsigned int count) +{ + count++; // obj itself + + for (SPObject *i = sp_object_first_child(obj); i != NULL; i = SP_OBJECT_NEXT(i)) { + count = count_objects_recursive(i, count); + } + + return count; +} + +unsigned int +objects_in_document(SPDocument *document) +{ + return count_objects_recursive(SP_DOCUMENT_ROOT(document), 0); +} + +void +vacuum_document_recursive(SPObject *obj) +{ + if (SP_IS_DEFS(obj)) { + for (SPObject *def = obj->firstChild(); def; def = SP_OBJECT_NEXT(def)) { + /* fixme: some inkscape-internal nodes in the future might not be collectable */ + def->requestOrphanCollection(); + } + } else { + for (SPObject *i = sp_object_first_child(obj); i != NULL; i = SP_OBJECT_NEXT(i)) { + vacuum_document_recursive(i); + } + } +} + +unsigned int +vacuum_document(SPDocument *document) +{ + unsigned int start = objects_in_document(document); + unsigned int end; + unsigned int newend = start; + + unsigned int iterations = 0; + + do { + end = newend; + + vacuum_document_recursive(SP_DOCUMENT_ROOT(document)); + document->collectOrphans(); + iterations++; + + newend = objects_in_document(document); + + } while (iterations < 100 && newend < end); + + return start - newend; +} + + +/* + 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:textwidth=99 : diff --git a/src/document.h b/src/document.h new file mode 100644 index 000000000..da8b656ef --- /dev/null +++ b/src/document.h @@ -0,0 +1,218 @@ +#ifndef __SP_DOCUMENT_H__ +#define __SP_DOCUMENT_H__ + +/** \file + * SPDocument: Typed SVG document implementation + * + * Authors: + * Lauris Kaplinski + * MenTaLguY + * + * Copyright (C) 2004-2005 MenTaLguY + * Copyright (C) 1999-2002 Lauris Kaplinski + * Copyright (C) 2000-2001 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include +#include +#include +#include + +#include "libcroco/cr-cascade.h" +#include "libnr/nr-forward.h" + +#include "gc-managed.h" +#include "gc-finalized.h" +#include "gc-anchored.h" + +struct SPDesktop; +struct SPItem; +struct SPObject; +struct SPGroup; + +namespace Inkscape { + struct Application; + class Selection; + class UndoStackObserver; + namespace XML { + class Document; + class Node; + } +} + +class SPDocumentPrivate; + +/// Typed SVG document implementation. +struct SPDocument : public Inkscape::GC::Managed<>, + public Inkscape::GC::Finalized, + public Inkscape::GC::Anchored +{ + typedef sigc::signal IDChangedSignal; + typedef sigc::signal ResourcesChangedSignal; + typedef sigc::signal ModifiedSignal; + typedef sigc::signal URISetSignal; + typedef sigc::signal ResizedSignal; + typedef sigc::signal ReconstructionStart; + typedef sigc::signal ReconstructionFinish; + + SPDocument(); + ~SPDocument(); + + unsigned int keepalive : 1; + unsigned int virgin : 1; ///< Has the document never been touched? + + Inkscape::XML::Document *rdoc; ///< Our Inkscape::XML::Document + Inkscape::XML::Node *rroot; ///< Root element of Inkscape::XML::Document + SPObject *root; ///< Our SPRoot + CRCascade *style_cascade; + + gchar *uri; ///< URI string or NULL + gchar *base; + gchar *name; + + SPDocumentPrivate *priv; + + /// Last action key + const gchar *actionkey; + /// Handler ID + guint modified_id; + + sigc::connection connectModified(ModifiedSignal::slot_type slot); + sigc::connection connectURISet(URISetSignal::slot_type slot); + sigc::connection connectResized(ResizedSignal::slot_type slot); + + void bindObjectToId(gchar const *id, SPObject *object); + SPObject *getObjectById(gchar const *id); + sigc::connection connectIdChanged(const gchar *id, IDChangedSignal::slot_type slot); + + void bindObjectToRepr(Inkscape::XML::Node *repr, SPObject *object); + SPObject *getObjectByRepr(Inkscape::XML::Node *repr); + + void queueForOrphanCollection(SPObject *object); + void collectOrphans(); + + void _emitModified(); + + GSList *_collection_queue; + + void addUndoObserver(Inkscape::UndoStackObserver& observer); + void removeUndoObserver(Inkscape::UndoStackObserver& observer); + +private: + SPDocument(SPDocument const &); // no copy + void operator=(SPDocument const &); // no assign + +public: + sigc::connection connectReconstructionStart(ReconstructionStart::slot_type slot); + sigc::connection connectReconstructionFinish (ReconstructionFinish::slot_type slot); + void emitReconstructionStart (void); + void emitReconstructionFinish (void); + + void reset_key (void *dummy); + sigc::connection _selection_changed_connection; + sigc::connection _desktop_activated_connection; +}; + +SPDocument *sp_document_new (const gchar *uri, unsigned int keepalive, bool make_new = false); +SPDocument *sp_document_new_from_mem (const gchar *buffer, gint length, unsigned int keepalive); +SPDocument *sp_document_new_dummy(); + +SPDocument *sp_document_ref (SPDocument *doc); +SPDocument *sp_document_unref (SPDocument *doc); + +/* + * Access methods + */ + +#define sp_document_repr_doc(d) (d->rdoc) +#define sp_document_repr_root(d) (d->rroot) +#define sp_document_root(d) (d->root) +#define SP_DOCUMENT_ROOT(d) (d->root) + +gdouble sp_document_width (SPDocument * document); +gdouble sp_document_height (SPDocument * document); + +struct SPUnit; + +void sp_document_set_width (SPDocument * document, gdouble width, const SPUnit *unit); +void sp_document_set_height (SPDocument * document, gdouble height, const SPUnit *unit); + +#define SP_DOCUMENT_URI(d) (d->uri) +#define SP_DOCUMENT_NAME(d) (d->name) +#define SP_DOCUMENT_BASE(d) (d->base) + +/* + * Dictionary + */ + +/* + * Undo & redo + */ + +void sp_document_set_undo_sensitive (SPDocument * document, gboolean sensitive); +gboolean sp_document_get_undo_sensitive (SPDocument const * document); + +void sp_document_clear_undo (SPDocument * document); +void sp_document_clear_redo (SPDocument * document); + +void sp_document_child_added (SPDocument *doc, SPObject *object, Inkscape::XML::Node *child, Inkscape::XML::Node *ref); +void sp_document_child_removed (SPDocument *doc, SPObject *object, Inkscape::XML::Node *child, Inkscape::XML::Node *ref); +void sp_document_attr_changed (SPDocument *doc, SPObject *object, const gchar *key, const gchar *oldval, const gchar *newval); +void sp_document_content_changed (SPDocument *doc, SPObject *object, const gchar *oldcontent, const gchar *newcontent); +void sp_document_order_changed (SPDocument *doc, SPObject *object, Inkscape::XML::Node *child, Inkscape::XML::Node *oldref, Inkscape::XML::Node *newref); + +/* Object modification root handler */ +void sp_document_request_modified (SPDocument *doc); +gint sp_document_ensure_up_to_date (SPDocument *doc); + +/* Save all previous actions to stack, as one undo step */ +void sp_document_done (SPDocument *document); +void sp_document_maybe_done (SPDocument *document, const gchar *key); +void sp_document_reset_key (Inkscape::Application *inkscape, SPDesktop *desktop, GtkObject *base); + +/* Cancel (and revert) current unsaved actions */ +void sp_document_cancel (SPDocument *document); + +/* Undo and redo */ +gboolean sp_document_undo (SPDocument * document); +gboolean sp_document_redo (SPDocument * document); + +/* Resource management */ +gboolean sp_document_add_resource (SPDocument *document, const gchar *key, SPObject *object); +gboolean sp_document_remove_resource (SPDocument *document, const gchar *key, SPObject *object); +const GSList *sp_document_get_resource_list (SPDocument *document, const gchar *key); +sigc::connection sp_document_resources_changed_connect(SPDocument *document, const gchar *key, SPDocument::ResourcesChangedSignal::slot_type slot); + + +/* + * Ideas: How to overcome style invalidation nightmare + * + * 1. There is reference request dictionary, that contains + * objects (styles) needing certain id. Object::build checks + * final id against it, and invokes necesary methods + * + * 2. Removing referenced object is simply prohibited - + * needs analyse, how we can deal with situations, where + * we simply want to ungroup etc. - probably we need + * Repr::reparent method :( [Or was it ;)] + * + */ + +/* + * Misc + */ + +GSList * sp_document_items_in_box(SPDocument *document, unsigned int dkey, NR::Rect const &box); +GSList * sp_document_partial_items_in_box(SPDocument *document, unsigned int dkey, NR::Rect const &box); +SPItem* sp_document_item_from_list_at_point_bottom (unsigned int dkey, SPGroup *group, const GSList *list, NR::Point const p, bool take_insensitive = false); +SPItem * sp_document_item_at_point (SPDocument *document, unsigned int key, NR::Point const p, gboolean into_groups, SPItem *upto = NULL); +SPItem * sp_document_group_at_point (SPDocument *document, unsigned int key, NR::Point const p); + +void sp_document_set_uri (SPDocument *document, const gchar *uri); +void sp_document_resized_signal_emit (SPDocument *doc, gdouble width, gdouble height); + +unsigned int vacuum_document (SPDocument *document); + +#endif diff --git a/src/dom/.cvsignore b/src/dom/.cvsignore new file mode 100644 index 000000000..38efca7bc --- /dev/null +++ b/src/dom/.cvsignore @@ -0,0 +1,3 @@ +.deps +.dirstamp +makefile diff --git a/src/dom/001.css b/src/dom/001.css new file mode 100755 index 000000000..db0207e05 --- /dev/null +++ b/src/dom/001.css @@ -0,0 +1,214 @@ +/* css Zen Garden default style - 'Tranquille' by Dave Shea - http://www.mezzoblue.com/ */ +/* css released under Creative Commons License - http://creativecommons.org/licenses/by-nc-sa/1.0/ */ +/* All associated graphics copyright 2003, Dave Shea */ +/* Added: May 7th, 2003 */ + + +/* IMPORTANT */ +/* This design is not a template. You may not reproduce it elsewhere without the + designer's written permission. However, feel free to study the CSS and use + techniques you learn from it elsewhere. */ + + +/* The Zen Garden default was the first I put together, and almost didn't make the cut. I briefly flirted with using + 'Salmon Cream Cheese' as the main style for the Garden, but switched back to this one before launch. + + All graphics in this design were illustrated by me in Photoshop. Google Image Search provided inspiration for + some of the elements. I did a bit of research on Kanji to come up with the characters on the top left. Anyone who + can read that will most likely tell you it makes no sense, but the best I could do was putting together the + characters for 'beginning' 'complete' and 'skill' to roughly say something like 'we're breaking fresh ground.' + + It's a stretch. */ + + +/* basic elements */ +html { + margin: 0px; + padding: 0px; + } +body { + font: 9pt/17pt georgia; + color: #555753; + background: #fff url(/001/blossoms.jpg) no-repeat bottom right; + margin: 0px; + padding: 0px; + } +p { + font: 9pt/17pt georgia; + margin-top: 0px; + text-align: justify; + } +h3 { + font: italic normal 12pt georgia; + letter-spacing: 1px; + margin-bottom: 0px; + color: #7D775C; + } +a:link { + font-weight: bold; + text-decoration: none; + color: #B7A5DF; + } +a:visited { + font-weight: bold; + text-decoration: none; + color: #D4CDDC; + } +a:hover, a:active { + text-decoration: underline; + color: #9685BA; + } +acronym { + border-bottom: none; + } + + +/* specific divs */ +#container { + background: url(/001/zen-bg.jpg) no-repeat top left; + padding: 0px 175px 0px 110px; + margin: 0px; + position: absolute; + top: 0px; + left: 0px; + } + +#intro { + min-width: 470px; + } +#pageHeader { + margin-bottom: 20px; + } + +/* using an image to replace text in an h1. This trick courtesy Douglas Bowman, http://www.stopdesign.com/articles/css/replace-text/ */ +#pageHeader h1 { + background: transparent url(/001/h1.gif) no-repeat top left; + margin-top: 10px; + width: 219px; + height: 87px; + float: left; + } +#pageHeader h1 span { + display:none + } +#pageHeader h2 { + background: transparent url(/001/h2.gif) no-repeat top left; + margin-top: 58px; + margin-bottom: 40px; + width: 200px; + height: 18px; + float: right; + } +#pageHeader h2 span { + display:none + } + +#quickSummary { + clear:both; + margin: 20px 20px 20px 10px; + width: 160px; + float: left; + } +#quickSummary p { + font: italic 10pt/22pt georgia; + text-align:center; + } + +#preamble { + clear: right; + padding: 0px 10px 0px 10px; + } +#supportingText { + padding-left: 10px; + margin-bottom: 40px; + } + +#footer { + text-align: center; + } +#footer a:link, #footer a:visited { + margin-right: 20px; + } + +#linkList { + margin-left: 600px; + position: absolute; + top: 0px; + right: 0px; + } +#linkList2 { + font: 10px verdana, sans-serif; + background: transparent url(/001/paper-bg.jpg) top left repeat-y; + padding: 10px; + margin-top: 150px; + width: 130px; + } +#linkList h3.select { + background: transparent url(/001/h3.gif) no-repeat top left; + margin: 10px 0px 5px 0px; + width: 97px; + height: 16px; + } +#linkList h3.select span { + display:none + } +#linkList h3.favorites { + background: transparent url(/001/h4.gif) no-repeat top left; + margin: 25px 0px 5px 0px; + width: 60px; + height: 18px; + } +#linkList h3.favorites span { + display:none + } +#linkList h3.archives { + background: transparent url(/001/h5.gif) no-repeat top left; + margin: 25px 0px 5px 0px; + width:57px; + height: 14px; + } +#linkList h3.archives span { + display:none + } +#linkList h3.resources { + background: transparent url(/001/h6.gif) no-repeat top left; + margin: 25px 0px 5px 0px; + width:63px; + height: 10px; + } +#linkList h3.resources span { + display:none + } + + +#linkList ul { + margin: 0px; + padding: 0px; + } +#linkList li { + line-height: 2.5ex; + background: transparent url(/001/cr1.gif) no-repeat top center; + display: block; + padding-top: 5px; + margin-bottom: 5px; + list-style-type: none; + } +#linkList li a:link { + color: #988F5E; + } +#linkList li a:visited { + color: #B3AE94; + } + + +#extraDiv1 { + background: transparent url(/001/cr2.gif) top left no-repeat; + position: absolute; + top: 40px; + right: 0px; + width: 148px; + height: 110px; + } +.accesskey { + text-decoration: underline; + } \ No newline at end of file diff --git a/src/dom/Filt.java b/src/dom/Filt.java new file mode 100755 index 000000000..a2c10550f --- /dev/null +++ b/src/dom/Filt.java @@ -0,0 +1,77 @@ + + +import java.io.*; + +public class Filt +{ + +void p(String s) +{ + System.out.println(s); +} + +void output(String s) +{ + String name = s.trim(); + if (name == null || name.length()<2) + return; + String ucName = name.substring(0,1).toUpperCase() + + name.substring(1); + + p("/**"); + p(" * return the '" + name + "' property" ); + p(" */"); + p("DOMString CSS2PropertiesImpl::get" + ucName + "()"); + p("{"); + p(" return " + name + ";"); + p("}"); + p(""); + p("/**"); + p(" * set the '" + name + "' property"); + p(" */"); + p("void CSS2PropertiesImpl::set" + ucName + "(const DOMString &val)"); + p(" throw (dom::DOMException)"); + p("{"); + p(" " + name + " = val;"); + p("}"); + p(""); + + +} + + +void doIt() +{ + try + { + BufferedReader in = new BufferedReader(new FileReader("cssprop.txt")); + + while (true) + { + String s = in.readLine(); + if (s == null) + break; + output(s); + } + + in.close(); + } + catch (Exception e) + { + } + +} + + + +public static void main(String argv[]) +{ + Filt f = new Filt(); + f.doIt(); + +} + + + +} + diff --git a/src/dom/ImplGen.java b/src/dom/ImplGen.java new file mode 100755 index 000000000..b79f70725 --- /dev/null +++ b/src/dom/ImplGen.java @@ -0,0 +1,180 @@ + + +import java.io.*; +import java.util.StringTokenizer; + + + +public class ImplGen +{ +BufferedWriter out; +String className; +String defaultReturn; + +void trace(String msg) +{ + System.out.println(msg); +} + +void err(String msg) +{ + System.out.print("error:"); + System.out.println(msg); +} + +void p(String s) +{ + try + { + out.write(s); + } + catch (IOException e) + { + } +} + +void sp(int count) +{ + for (int i=0 ; i0 && Character.isLetter(s.charAt(0))) + { + defaultReturn = "NULL"; + } + else if (s.startsWith("~")) + { + defaultReturn = ""; + } + + int pos = s.indexOf("("); + if (!s.startsWith("~") && pos > 0 && + Character.isLetterOrDigit(s.charAt(pos-1))) + { + while (Character.isLetterOrDigit(s.charAt(pos-1))) + pos--; + String news = s.substring(0, pos) + + className + "::" + + s.substring(pos); + s = news; + } + + if (s.startsWith("~")) + { + p(className); p("::"); + p(s); p("\n"); + } + else if (s.startsWith("}") && defaultReturn.length()>0) + { + p(" return "); p(defaultReturn); p(";"); p("\n"); + p(s); p("\n"); + } + else + { + p(s); p("\n"); + } + + + +} + + + + + +void doIt(String inName) +{ + String cppName = inName + ".cpp"; + try + { + BufferedReader in = new BufferedReader(new FileReader(inName)); + out = new BufferedWriter(new FileWriter(cppName)); + while (true) + { + String s = in.readLine(); + if (s == null) + break; + process(s); + } + + in.close(); + out.close(); + } + catch (Exception e) + { + } + +} + + +public ImplGen() +{ +} + + +public static void main(String argv[]) +{ + if (argv.length != 1) + { + System.out.println("usage: ImplGen "); + return; + } + ImplGen ig = new ImplGen(); + ig.doIt(argv[0]); + +} + + + + + + + + + + + + + + + + + + + +} diff --git a/src/dom/Makefile.static b/src/dom/Makefile.static new file mode 100755 index 000000000..907fe9cce --- /dev/null +++ b/src/dom/Makefile.static @@ -0,0 +1,71 @@ +########################################################################### +# +# Makefile for testing DOM code +# +########################################################################### + + +CC = gcc +CXX = g++ + +INC = -I. +CFLAGS = -g -Wall +LIBS = + +OBJ = \ +charclass.o \ +cssparser.o \ +domimpl.o \ +domstream.o \ +domstring.o \ +lsimpl.o \ +smilimpl.o \ +stringstream.o \ +svgimpl.o \ +svglsimpl.o \ +svgparser.o \ +uri.o \ +uristream.o \ +xmlreader.o \ +xpathimpl.o \ +xpathparser.o + +all: testsvg uritest xpathtest + +testdom: libdom.a testdom.o + $(CXX) -o testdom testdom.o libdom.a $(LIBS) + +testsvg: libdom.a testsvg.o + $(CXX) -o testsvg testsvg.o libdom.a $(LIBS) + +uritest: libdom.a uritest.o + $(CXX) -o uritest uritest.o libdom.a $(LIBS) + +xpathtest: libdom.a xpathtest.o + $(CXX) -o xpathtest xpathtest.o libdom.a $(LIBS) + +libdom.a: $(OBJ) + ar crv libdom.a $(OBJ) + +.cpp.o: + $(CXX) $(CFLAGS) $(INC) -c -o $@ $< + +clean: + -$(RM) *.o + -$(RM) *.a + -$(RM) *.gch + -$(RM) *.class + -$(RM) testdom + -$(RM) testdom.exe + -$(RM) testsvg + -$(RM) testsvg.exe + -$(RM) uritest + -$(RM) uritest.exe + -$(RM) xpathtest + -$(RM) xpathtest.exe + -$(RM) core.* + +########################################################################### +# E N D O F F I L E +########################################################################### + diff --git a/src/dom/Makefile_insert b/src/dom/Makefile_insert new file mode 100644 index 000000000..19be5c9f9 --- /dev/null +++ b/src/dom/Makefile_insert @@ -0,0 +1,57 @@ +## Makefile.am fragment sourced by src/Makefile.am. + +dom/all: dom/libdom.a + +dom/clean: + rm -f dom/libdom.a $(dom_libdom_a_OBJECTS) + +dom_libdom_a_SOURCES = \ + dom/charclass.cpp \ + dom/charclass.h \ + dom/css.h \ + dom/cssparser.cpp \ + dom/cssparser.h \ + dom/dom.h \ + dom/domimpl.cpp \ + dom/domimpl.h \ + dom/domstream.cpp \ + dom/domstream.h \ + dom/domstring.cpp \ + dom/domstring.h \ + dom/domstringimpl.h \ + dom/events.h \ + dom/ls.h \ + dom/lsimpl.cpp \ + dom/lsimpl.h \ + dom/phoebedom.h \ + dom/prop-css2.cpp \ + dom/prop-css.cpp \ + dom/prop-svg.cpp \ + dom/smil.h \ + dom/smilimpl.cpp \ + dom/smilimpl.h \ + dom/stringstream.cpp \ + dom/stringstream.h \ + dom/stylesheets.h \ + dom/svg.h \ + dom/svgimpl.cpp \ + dom/svgimpl.h \ + dom/svglsimpl.cpp \ + dom/svglsimpl.h \ + dom/svgparser.cpp \ + dom/svgparser.h \ + dom/svgtypes.h \ + dom/traversal.h \ + dom/uri.cpp \ + dom/uri.h \ + dom/uristream.cpp \ + dom/uristream.h \ + dom/views.h \ + dom/xmlreader.cpp \ + dom/xmlreader.h \ + dom/xpath.h \ + dom/xpathimpl.cpp \ + dom/xpathimpl.h \ + dom/xpathparser.cpp \ + dom/xpathparser.h + diff --git a/src/dom/README b/src/dom/README new file mode 100644 index 000000000..142d67ef3 --- /dev/null +++ b/src/dom/README @@ -0,0 +1,25 @@ +Phoebe DOM +========== + +This is the DOM library that is going to provide +Inkscape with a w3c DOM-idl interface, hopefully +aiding in scripting and animation. + +The name 'Phoebe' in inherited from an older project +which had its own DOM implementation. The name itself +is of a moon of Saturn. + +The library is intended to be 'vanilla' and generic. The +library has its own parser, even if it is not used. +The base code should never be modified to be Inkscape-specific. +It should not have any dependencies beyond STL, nor +should it veer away from adherence to the W3C DOM APIs. + +The most common usage of this library would probably be +limited to the classes defined in dom.h. A scriptable +item would inherit and extend org::w3c::dom::Node, and modify +the behaviour of the getters and setters for its attributes. + + + +Bob Jamison diff --git a/src/dom/acid.css b/src/dom/acid.css new file mode 100755 index 000000000..7ea8750f5 --- /dev/null +++ b/src/dom/acid.css @@ -0,0 +1,110 @@ + /* section numbers refer to CSS2.1 */ + + /* page setup */ + html { font: 12px sans-serif; margin: 0; padding: 0; overflow: hidden; /* hides scrollbars on viewport, see 11.1.1:3 */ background: white; color: red; } + body { margin: 0; padding: 0; } + + /* introduction message */ + .intro { font: 2em sans-serif; margin: 3.5em 2em; padding: 0.5em; border: solid thin; background: white; color: black; position: relative; z-index: 2; /* should cover the black and red bars that are fixed-positioned */ } + .intro * { font: inherit; margin: 0; padding: 0; } + .intro h1 { font-size: 1em; font-weight: bolder; margin: 0; padding: 0; } + .intro :link { color: blue; } + .intro :visited { color: purple; } + + /* picture setup */ + #top { margin: 100em 3em 0; padding: 2em 0 0 .5em; text-align: left; font: 2em/24px sans-serif; color: navy; white-space: pre; } /* "Hello World!" text */ + .picture { position: relative; border: 1em solid transparent; margin: 0 0 100em 3em; } /* containing block for face */ + .picture { background: red; } /* overriden by preferred stylesheet below */ + + /* top line of face (scalp): fixed positioning and min/max height/width */ + .picture p { position: fixed; margin: 0; padding: 0; border: 0; top: 9em; left: 11em; width: 140%; max-width: 4em; height: 8px; min-height: 1em; max-height: 2mm; /* min-height overrides max-height, see 10.7 */ background: black; border-bottom: 0.5em yellow solid; } + + /* bits that shouldn't be part of the top line (and shouldn't be visible at all): HTML parsing, "+" combinator, stacking order */ + .picture p.bad { border-bottom: red solid; /* shouldn't matter, because the "p + table + p" rule below should match it too, thus hiding it */ } + .picture p + p { background: maroon; z-index: 1; } /* shouldn't match anything */ + .picture p + table + p { margin-top: 3em; /* should end up under the absolutely positioned table below, and thus not be visible */ } + + /* second line of face: attribute selectors, float positioning */ + [class~=one].first.one { position: absolute; top: 0; margin: 36px 0 0 60px; padding: 0; border: black 2em; border-style: none solid; /* shrink wraps around float */ } + [class~=one][class~=first] [class=second\ two][class="second two"] { float: right; width: 48px; height: 12px; background: yellow; margin: 0; padding: 0; } /* only content of abs pos block */ + + /* third line of face: width and overflow */ + .forehead { margin: 4em; width: 8em; border-left: solid black 1em; border-right: solid black 1em; background: red url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVR42mP4%2F58BAAT%2FAf9jgNErAAAAAElFTkSuQmCC); /* that's a 1x1 yellow pixel PNG */ } + .forehead * { width: 12em; line-height: 1em; } + + /* class selectors headache */ + .two.error.two { background: maroon; } /* shouldn't match */ + .forehead.error.forehead { background: red; } /* shouldn't match */ + [class=second two] { background: red; } /* this should be ignored (invalid selector -- grammar says it only accepts IDENTs or STRINGs) */ + + /* fourth and fifth lines of face, with eyes: paint order test (see appendix E) and fixed backgrounds */ + /* the two images are identical: 2-by-2 squares with the top left + and bottom right pixels set to yellow and the other two set to + transparent. Since they are offset by one pixel from each other, + the second one paints exactly over the transparent parts of the + first one, thus creating a solid yellow block. */ + .eyes { position: absolute; top: 5em; left: 3em; margin: 0; padding: 0; background: red; } + #eyes-a { height: 0; line-height: 2em; text-align: right; } /* contents should paint top-most because they're inline */ + #eyes-a object { display: inline; vertical-align: bottom; } + #eyes-a object[type] { width: 7.5em; height: 2.5em; } /* should have no effect since that object should fallback to being inline (height/width don't apply to inlines) */ + #eyes-a object object object { border-right: solid 1em black; padding: 0 12px 0 11px; background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAIAAAD91JpzAAAABnRSTlMAAAAAAABupgeRAAAABmJLR0QA%2FwD%2FAP%2BgvaeTAAAAEUlEQVR42mP4%2F58BCv7%2FZwAAHfAD%2FabwPj4AAAAASUVORK5CYII%3D) fixed 1px 0; } + #eyes-b { float: left; width: 10em; height: 2em; background: fixed url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAIAAAD91JpzAAAABnRSTlMAAAAAAABupgeRAAAABmJLR0QA%2FwD%2FAP%2BgvaeTAAAAEUlEQVR42mP4%2F58BCv7%2FZwAAHfAD%2FabwPj4AAAAASUVORK5CYII%3D); border-left: solid 1em black; border-right: solid 1em red; } /* should paint in the middle layer because it is a float */ + #eyes-c { display: block; background: red; border-left: 2em solid yellow; width: 10em; height: 2em; } /* should paint bottom most because it is a block */ + + /* lines six to nine, with nose: auto margins */ + .nose { float: left; margin: -2em 2em -1em; border: solid 1em black; border-top: 0; min-height: 80%; height: 60%; max-height: 3em; /* percentages become auto (see 10.5 and 10.7) and intrinsic height is more than 3em, so 3em wins */ padding: 0; width: 12em; } + .nose > div { padding: 1em 1em 3em; height: 0; background: yellow; } + .nose div div { width: 2em; height: 2em; background: red; margin: auto; } + .nose :hover div { border-color: blue; } + .nose div:hover :before { border-bottom-color: inherit; } + .nose div:hover :after { border-top-color: inherit; } + .nose div div:before { display: block; border-style: none solid solid; border-color: red yellow black yellow; border-width: 1em; content: ''; height: 0; } + .nose div :after { display: block; border-style: solid solid none; border-color: black yellow red yellow; border-width: 1em; content: ''; height: 0; } + + /* between lines nine and ten: margin collapsing with 'float' and 'clear' */ + .empty { margin: 6.25em; height: 10%; /* computes to auto which makes it empty per 8.3.1:7 (own margins) */ } + .empty div { margin: 0 2em -6em 4em; } + .smile { margin: 5em 3em; clear: both; /* clearance is negative (see 8.3.1 and 9.5.1) */ } + + /* line ten and eleven: containing block for abs pos */ + .smile div { margin-top: 0.25em; background: black; width: 12em; height: 2em; position: relative; bottom: -1em; } + .smile div div { position: absolute; top: 0; right: 1em; width: auto; height: 0; margin: 0; border: yellow solid 1em; } + + /* smile (over lines ten and eleven): backgrounds behind borders, inheritance of 'float', nested floats, negative heights */ + .smile div div span { display: inline; margin: -1em 0 0 0; border: solid 1em transparent; border-style: none solid; float: right; background: black; height: 1em; } + .smile div div span em { float: inherit; border-top: solid yellow 1em; border-bottom: solid black 1em; } /* zero-height block; width comes from (zero-height) child. */ + .smile div div span em strong { width: 6em; display: block; margin-bottom: -1em; /* should have no effect, since parent has top&bottom borders, so this margin doesn't collapse */ } + + /* line twelve: line-height */ + .chin { margin: -4em 4em 0; width: 8em; line-height: 1em; border-left: solid 1em black; border-right: solid 1em black; background: yellow url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAIAAAFSDNYfAAAAaklEQVR42u3XQQrAIAwAQeP%2F%2F6wf8CJBJTK9lnQ7FpHGaOurt1I34nfH9pMMZAZ8BwMGEvvh%2BBsJCAgICLwIOA8EBAQEBAQEBAQEBK79H5RfIQAAAAAAAAAAAAAAAAAAAAAAAAAAAID%2FABMSqAfj%2FsLmvAAAAABJRU5ErkJggg%3D%3D) /* 64x64 red square */ no-repeat fixed /* shouldn't be visible unless the smiley is moved to the top left of the viewport */; } + .chin div { display: inline; font: 2px/4px serif; } + + /* line thirteen: cascade and selector tests */ + .parser-container div { color: maroon; border: solid; color: orange; } /* setup */ + div.parser-container * { border-color: black; /* overrides (implied) border-color on previous line */ } /* setup */ + * div.parser { border-width: 0 2em; /* overrides (implied) declarations on earlier line */ } /* setup */ + + /* line thirteen continued: parser tests */ + .parser { /* comment parsing test -- comment ends before the end of this line, the backslash should have no effect: \*/ } + .parser { margin: 0 5em 1em; padding: 0 1em; width: 2em; height: 1em; error: \}; background: yellow; } /* setup with parsing test */ + * html .parser { background: gray; } + \.parser { padding: 2em; } + .parser { m\argin: 2em; }; + .parser { height: 3em; } + .parser { width: 200; } + .parser { border: 5em solid red ! error; } + .parser { background: red pink; } + + /* line fourteen (last line of face): table */ + ul { display: table; padding: 0; margin: -1em 7em 0; background: red; } + ul li { padding: 0; margin: 0; } + ul li.first-part { display: table-cell; height: 1em; width: 1em; background: black; } + ul li.second-part { display: table; height: 1em; width: 1em; background: black; } /* anonymous table cell wraps around this */ + ul li.third-part { display: table-cell; height: 0.5em; /* gets stretched to fit row */ width: 1em; background: black; } + ul li.fourth-part { list-style: none; height: 1em; width: 1em; background: black; } /* anonymous table cell wraps around this */ + + /* bits that shouldn't appear: inline alignment in cells */ + .image-height-test { height: 10px; overflow: hidden; font: 20em serif; } /* only the area between the top of the line box and the top of the image should be visible */ + table { margin: 0; border-spacing: 0; } + td { padding: 0; } + diff --git a/src/dom/base.css b/src/dom/base.css new file mode 100755 index 000000000..7176bbf94 --- /dev/null +++ b/src/dom/base.css @@ -0,0 +1,32 @@ +/* recover from old-browser styling */ + +*.oldbl {display: block !important;} +*.oldin {display: inline !important;} +*.ahem {display: none !important;} +img.pic {display: block !important;} + +/* NS6.x-specific fix(es) */ + +/*|*:-moz-list-bullet, *|*:-moz-list-number {font-size: 1em;}/ + +/* misc */ + +.skipper {display: none !important;} + +* {font-size: 100%;} +h1 {font-size: 2em;} +h2 {font-size: 1.5em;} +h3 {font-size: 1.33em;} +h4 {font-size: 1.1em;} +h5 {font-size: 0.9em;} +h6 {font-size: 0.75em;} +pre, code, tt {font: 95% "Andale Mono", Courier, "Courier New", monospace;} + +img.pic {float: right; margin: 0.25em 0 0.66em 1.5em;} +img.border {border: 3px double;} + +p.contact {margin: 0 1em !important; text-align: right; font-size: 90%;} + +#main {min-height: 30em;} +#header h1 a, #nav a {text-decoration: none;} +#nav {padding-top: 0.75em;} diff --git a/src/dom/charclass.cpp b/src/dom/charclass.cpp new file mode 100755 index 000000000..81c3fb18e --- /dev/null +++ b/src/dom/charclass.cpp @@ -0,0 +1,451 @@ +/** + * Phoebe DOM Implementation. + * + * This is a C++ approximation of the W3C DOM model, which follows + * fairly closely the specifications in the various .idl files, copies of + * which are provided for reference. Most important is this one: + * + * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/idl-definitions.html + * + * Authors: + * Bob Jamison + * + * Copyright (C) 2005 Bob Jamison + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "charclass.h" + + +/** + * (impl) LetterOrDigit ::= + * Letter | Digit + */ +bool isLetterOrDigit(int ch) +{ + if (isLetter(ch)) + return true; + if (isDigit(ch)) + return true; + return false; +} + +/** + * (84) Letter ::= + * BaseChar | Ideographic + */ +bool isLetter(int ch) +{ + if (isBaseChar(ch)) + return true; + if (isIdeographic(ch)) + return true; + return false; +} + + +/** + * (85) BaseChar ::= + */ +bool isBaseChar(int ch) +{ + + if ( (0x0041 <= ch && ch <= 0x005A) | + (0x0061 <= ch && ch <= 0x007A) | + (0x00C0 <= ch && ch <= 0x00D6) | + (0x00D8 <= ch && ch <= 0x00F6) | + (0x00F8 <= ch && ch <= 0x00FF) | + (0x0100 <= ch && ch <= 0x0131) | + (0x0134 <= ch && ch <= 0x013E) | + (0x0141 <= ch && ch <= 0x0148) | + (0x014A <= ch && ch <= 0x017E) | + (0x0180 <= ch && ch <= 0x01C3) | + (0x01CD <= ch && ch <= 0x01F0) | + (0x01F4 <= ch && ch <= 0x01F5) | + (0x01FA <= ch && ch <= 0x0217) | + (0x0250 <= ch && ch <= 0x02A8) | + (0x02BB <= ch && ch <= 0x02C1) | + ch == 0x0386 | + (0x0388 <= ch && ch <= 0x038A) | + ch == 0x038C | + (0x038E <= ch && ch <= 0x03A1) | + (0x03A3 <= ch && ch <= 0x03CE) | + (0x03D0 <= ch && ch <= 0x03D6) | + ch == 0x03DA | + ch == 0x03DC | + ch == 0x03DE | + ch == 0x03E0 | + (0x03E2 <= ch && ch <= 0x03F3) | + (0x0401 <= ch && ch <= 0x040C) | + (0x040E <= ch && ch <= 0x044F) | + (0x0451 <= ch && ch <= 0x045C) | + (0x045E <= ch && ch <= 0x0481) | + (0x0490 <= ch && ch <= 0x04C4) | + (0x04C7 <= ch && ch <= 0x04C8) | + (0x04CB <= ch && ch <= 0x04CC) | + (0x04D0 <= ch && ch <= 0x04EB) | + (0x04EE <= ch && ch <= 0x04F5) | + (0x04F8 <= ch && ch <= 0x04F9) | + (0x0531 <= ch && ch <= 0x0556) | + ch == 0x0559 | + (0x0561 <= ch && ch <= 0x0586) | + (0x05D0 <= ch && ch <= 0x05EA) | + (0x05F0 <= ch && ch <= 0x05F2) | + (0x0621 <= ch && ch <= 0x063A) | + (0x0641 <= ch && ch <= 0x064A) | + (0x0671 <= ch && ch <= 0x06B7) | + (0x06BA <= ch && ch <= 0x06BE) | + (0x06C0 <= ch && ch <= 0x06CE) | + (0x06D0 <= ch && ch <= 0x06D3) | + ch == 0x06D5 | + (0x06E5 <= ch && ch <= 0x06E6) | + (0x0905 <= ch && ch <= 0x0939) | + ch == 0x093D | + (0x0958 <= ch && ch <= 0x0961) | + (0x0985 <= ch && ch <= 0x098C) | + (0x098F <= ch && ch <= 0x0990) | + (0x0993 <= ch && ch <= 0x09A8) | + (0x09AA <= ch && ch <= 0x09B0) | + ch == 0x09B2 | + (0x09B6 <= ch && ch <= 0x09B9) | + (0x09DC <= ch && ch <= 0x09DD) | + (0x09DF <= ch && ch <= 0x09E1) | + (0x09F0 <= ch && ch <= 0x09F1) | + (0x0A05 <= ch && ch <= 0x0A0A) | + (0x0A0F <= ch && ch <= 0x0A10) | + (0x0A13 <= ch && ch <= 0x0A28) | + (0x0A2A <= ch && ch <= 0x0A30) | + (0x0A32 <= ch && ch <= 0x0A33) | + (0x0A35 <= ch && ch <= 0x0A36) | + (0x0A38 <= ch && ch <= 0x0A39) | + (0x0A59 <= ch && ch <= 0x0A5C) | + ch == 0x0A5E | + (0x0A72 <= ch && ch <= 0x0A74) | + (0x0A85 <= ch && ch <= 0x0A8B) | + ch == 0x0A8D | + (0x0A8F <= ch && ch <= 0x0A91) | + (0x0A93 <= ch && ch <= 0x0AA8) | + (0x0AAA <= ch && ch <= 0x0AB0) | + (0x0AB2 <= ch && ch <= 0x0AB3) | + (0x0AB5 <= ch && ch <= 0x0AB9) | + ch == 0x0ABD | + ch == 0x0AE0 | + (0x0B05 <= ch && ch <= 0x0B0C) | + (0x0B0F <= ch && ch <= 0x0B10) | + (0x0B13 <= ch && ch <= 0x0B28) | + (0x0B2A <= ch && ch <= 0x0B30) | + (0x0B32 <= ch && ch <= 0x0B33) | + (0x0B36 <= ch && ch <= 0x0B39) | + ch == 0x0B3D | + (0x0B5C <= ch && ch <= 0x0B5D) | + (0x0B5F <= ch && ch <= 0x0B61) | + (0x0B85 <= ch && ch <= 0x0B8A) | + (0x0B8E <= ch && ch <= 0x0B90) | + (0x0B92 <= ch && ch <= 0x0B95) | + (0x0B99 <= ch && ch <= 0x0B9A) | + ch == 0x0B9C | + (0x0B9E <= ch && ch <= 0x0B9F) | + (0x0BA3 <= ch && ch <= 0x0BA4) | + (0x0BA8 <= ch && ch <= 0x0BAA) | + (0x0BAE <= ch && ch <= 0x0BB5) | + (0x0BB7 <= ch && ch <= 0x0BB9) | + (0x0C05 <= ch && ch <= 0x0C0C) | + (0x0C0E <= ch && ch <= 0x0C10) | + (0x0C12 <= ch && ch <= 0x0C28) | + (0x0C2A <= ch && ch <= 0x0C33) | + (0x0C35 <= ch && ch <= 0x0C39) | + (0x0C60 <= ch && ch <= 0x0C61) | + (0x0C85 <= ch && ch <= 0x0C8C) | + (0x0C8E <= ch && ch <= 0x0C90) | + (0x0C92 <= ch && ch <= 0x0CA8) | + (0x0CAA <= ch && ch <= 0x0CB3) | + (0x0CB5 <= ch && ch <= 0x0CB9) | + ch == 0x0CDE | + (0x0CE0 <= ch && ch <= 0x0CE1) | + (0x0D05 <= ch && ch <= 0x0D0C) | + (0x0D0E <= ch && ch <= 0x0D10) | + (0x0D12 <= ch && ch <= 0x0D28) | + (0x0D2A <= ch && ch <= 0x0D39) | + (0x0D60 <= ch && ch <= 0x0D61) | + (0x0E01 <= ch && ch <= 0x0E2E) | + ch == 0x0E30 | + (0x0E32 <= ch && ch <= 0x0E33) | + (0x0E40 <= ch && ch <= 0x0E45) | + (0x0E81 <= ch && ch <= 0x0E82) | + ch == 0x0E84 | + (0x0E87 <= ch && ch <= 0x0E88) | + ch == 0x0E8A | + ch == 0x0E8D | + (0x0E94 <= ch && ch <= 0x0E97) | + (0x0E99 <= ch && ch <= 0x0E9F) | + (0x0EA1 <= ch && ch <= 0x0EA3) | + ch == 0x0EA5 | + ch == 0x0EA7 | + (0x0EAA <= ch && ch <= 0x0EAB) | + (0x0EAD <= ch && ch <= 0x0EAE) | + ch == 0x0EB0 | + (0x0EB2 <= ch && ch <= 0x0EB3) | + ch == 0x0EBD | + (0x0EC0 <= ch && ch <= 0x0EC4) | + (0x0F40 <= ch && ch <= 0x0F47) | + (0x0F49 <= ch && ch <= 0x0F69) | + (0x10A0 <= ch && ch <= 0x10C5) | + (0x10D0 <= ch && ch <= 0x10F6) | + ch == 0x1100 | + (0x1102 <= ch && ch <= 0x1103) | + (0x1105 <= ch && ch <= 0x1107) | + ch == 0x1109 | + (0x110B <= ch && ch <= 0x110C) | + (0x110E <= ch && ch <= 0x1112) | + ch == 0x113C | + ch == 0x113E | + ch == 0x1140 | + ch == 0x114C | + ch == 0x114E | + ch == 0x1150 | + (0x1154 <= ch && ch <= 0x1155) | + ch == 0x1159 | + (0x115F <= ch && ch <= 0x1161) | + ch == 0x1163 | + ch == 0x1165 | + ch == 0x1167 | + ch == 0x1169 | + (0x116D <= ch && ch <= 0x116E) | + (0x1172 <= ch && ch <= 0x1173) | + ch == 0x1175 | + ch == 0x119E | + ch == 0x11A8 | + ch == 0x11AB | + (0x11AE <= ch && ch <= 0x11AF) | + (0x11B7 <= ch && ch <= 0x11B8) | + ch == 0x11BA | + (0x11BC <= ch && ch <= 0x11C2) | + ch == 0x11EB | + ch == 0x11F0 | + ch == 0x11F9 | + (0x1E00 <= ch && ch <= 0x1E9B) | + (0x1EA0 <= ch && ch <= 0x1EF9) | + (0x1F00 <= ch && ch <= 0x1F15) | + (0x1F18 <= ch && ch <= 0x1F1D) | + (0x1F20 <= ch && ch <= 0x1F45) | + (0x1F48 <= ch && ch <= 0x1F4D) | + (0x1F50 <= ch && ch <= 0x1F57) | + ch == 0x1F59 | + ch == 0x1F5B | + ch == 0x1F5D | + (0x1F5F <= ch && ch <= 0x1F7D) | + (0x1F80 <= ch && ch <= 0x1FB4) | + (0x1FB6 <= ch && ch <= 0x1FBC) | + ch == 0x1FBE | + (0x1FC2 <= ch && ch <= 0x1FC4) | + (0x1FC6 <= ch && ch <= 0x1FCC) | + (0x1FD0 <= ch && ch <= 0x1FD3) | + (0x1FD6 <= ch && ch <= 0x1FDB) | + (0x1FE0 <= ch && ch <= 0x1FEC) | + (0x1FF2 <= ch && ch <= 0x1FF4) | + (0x1FF6 <= ch && ch <= 0x1FFC) | + ch == 0x2126 | + (0x212A <= ch && ch <= 0x212B) | + ch == 0x212E | + (0x2180 <= ch && ch <= 0x2182) | + (0x3041 <= ch && ch <= 0x3094) | + (0x30A1 <= ch && ch <= 0x30FA) | + (0x3105 <= ch && ch <= 0x312C) | + (0xAC00 <= ch && ch <= 0xD7A3) ) + return true; + return false; +} + + + +/** + * (86) Ideographic ::= + */ +bool isIdeographic(int ch) +{ + if ( (0x4E00 <= ch && ch <=0x9FA5) | + ch == 0x3007 | + (0x3021 <= ch && ch <=0x3029) ) + return true; + return false; +} + +/** + * (87) CombiningChar ::= + */ +bool isCombiningChar(int ch) +{ + if ( (0x0300 <= ch && ch <= 0x0345) | + (0x0360 <= ch && ch <= 0x0361) | + (0x0483 <= ch && ch <= 0x0486) | + (0x0591 <= ch && ch <= 0x05A1) | + (0x05A3 <= ch && ch <= 0x05B9) | + (0x05BB <= ch && ch <= 0x05BD) | + ch == 0x05BF | + (0x05C1 <= ch && ch <= 0x05C2) | + ch == 0x05C4 | + (0x064B <= ch && ch <= 0x0652) | + ch == 0x0670 | + (0x06D6 <= ch && ch <= 0x06DC) | + (0x06DD <= ch && ch <= 0x06DF) | + (0x06E0 <= ch && ch <= 0x06E4) | + (0x06E7 <= ch && ch <= 0x06E8) | + (0x06EA <= ch && ch <= 0x06ED) | + (0x0901 <= ch && ch <= 0x0903) | + ch == 0x093C | + (0x093E <= ch && ch <= 0x094C) | + ch == 0x094D | + (0x0951 <= ch && ch <= 0x0954) | + (0x0962 <= ch && ch <= 0x0963) | + (0x0981 <= ch && ch <= 0x0983) | + ch == 0x09BC | + ch == 0x09BE | + ch == 0x09BF | + (0x09C0 <= ch && ch <= 0x09C4) | + (0x09C7 <= ch && ch <= 0x09C8) | + (0x09CB <= ch && ch <= 0x09CD) | + ch == 0x09D7 | + (0x09E2 <= ch && ch <= 0x09E3) | + ch == 0x0A02 | + ch == 0x0A3C | + ch == 0x0A3E | + ch == 0x0A3F | + (0x0A40 <= ch && ch <= 0x0A42) | + (0x0A47 <= ch && ch <= 0x0A48) | + (0x0A4B <= ch && ch <= 0x0A4D) | + (0x0A70 <= ch && ch <= 0x0A71) | + (0x0A81 <= ch && ch <= 0x0A83) | + ch == 0x0ABC | + (0x0ABE <= ch && ch <= 0x0AC5) | + (0x0AC7 <= ch && ch <= 0x0AC9) | + (0x0ACB <= ch && ch <= 0x0ACD) | + (0x0B01 <= ch && ch <= 0x0B03) | + ch == 0x0B3C | + (0x0B3E <= ch && ch <= 0x0B43) | + (0x0B47 <= ch && ch <= 0x0B48) | + (0x0B4B <= ch && ch <= 0x0B4D) | + (0x0B56 <= ch && ch <= 0x0B57) | + (0x0B82 <= ch && ch <= 0x0B83) | + (0x0BBE <= ch && ch <= 0x0BC2) | + (0x0BC6 <= ch && ch <= 0x0BC8) | + (0x0BCA <= ch && ch <= 0x0BCD) | + ch == 0x0BD7 | + (0x0C01 <= ch && ch <= 0x0C03) | + (0x0C3E <= ch && ch <= 0x0C44) | + (0x0C46 <= ch && ch <= 0x0C48) | + (0x0C4A <= ch && ch <= 0x0C4D) | + (0x0C55 <= ch && ch <= 0x0C56) | + (0x0C82 <= ch && ch <= 0x0C83) | + (0x0CBE <= ch && ch <= 0x0CC4) | + (0x0CC6 <= ch && ch <= 0x0CC8) | + (0x0CCA <= ch && ch <= 0x0CCD) | + (0x0CD5 <= ch && ch <= 0x0CD6) | + (0x0D02 <= ch && ch <= 0x0D03) | + (0x0D3E <= ch && ch <= 0x0D43) | + (0x0D46 <= ch && ch <= 0x0D48) | + (0x0D4A <= ch && ch <= 0x0D4D) | + ch == 0x0D57 | + ch == 0x0E31 | + (0x0E34 <= ch && ch <= 0x0E3A) | + (0x0E47 <= ch && ch <= 0x0E4E) | + ch == 0x0EB1 | + (0x0EB4 <= ch && ch <= 0x0EB9) | + (0x0EBB <= ch && ch <= 0x0EBC) | + (0x0EC8 <= ch && ch <= 0x0ECD) | + (0x0F18 <= ch && ch <= 0x0F19) | + ch == 0x0F35 | + ch == 0x0F37 | + ch == 0x0F39 | + ch == 0x0F3E | + ch == 0x0F3F | + (0x0F71 <= ch && ch <= 0x0F84) | + (0x0F86 <= ch && ch <= 0x0F8B) | + (0x0F90 <= ch && ch <= 0x0F95) | + ch == 0x0F97 | + (0x0F99 <= ch && ch <= 0x0FAD) | + (0x0FB1 <= ch && ch <= 0x0FB7) | + ch == 0x0FB9 | + (0x20D0 <= ch && ch <= 0x20DC) | + ch == 0x20E1 | + (0x302A <= ch && ch <= 0x302F) | + ch == 0x3099 | + ch == 0x309A ) + return true; + return false; +} + + +/** + * (88) Digit ::= + */ +bool isDigit(int ch) +{ + if ( (0x0030 <= ch && ch <= 0x0039) | + (0x0660 <= ch && ch <= 0x0669) | + (0x06F0 <= ch && ch <= 0x06F9) | + (0x0966 <= ch && ch <= 0x096F) | + (0x09E6 <= ch && ch <= 0x09EF) | + (0x0A66 <= ch && ch <= 0x0A6F) | + (0x0AE6 <= ch && ch <= 0x0AEF) | + (0x0B66 <= ch && ch <= 0x0B6F) | + (0x0BE7 <= ch && ch <= 0x0BEF) | + (0x0C66 <= ch && ch <= 0x0C6F) | + (0x0CE6 <= ch && ch <= 0x0CEF) | + (0x0D66 <= ch && ch <= 0x0D6F) | + (0x0E50 <= ch && ch <= 0x0E59) | + (0x0ED0 <= ch && ch <= 0x0ED9) | + (0x0F20 <= ch && ch <= 0x0F29) ) + return true; + return false; +} + + +/** + * (89) Extender ::= + */ +bool isExtender(int ch) +{ + if ( ch == 0x00B7 | + ch == 0x02D0 | + ch == 0x02D1 | + ch == 0x0387 | + ch == 0x0640 | + ch == 0x0E46 | + ch == 0x0EC6 | + ch == 0x3005 | + (0x3031 <= ch && ch <= 0x3035) | + (0x309D <= ch && ch <= 0x309E) | + (0x30FC <= ch && ch <= 0x30FE) ) + return true; + return false; +} + + + + + + + + + + + + + + + + + diff --git a/src/dom/charclass.h b/src/dom/charclass.h new file mode 100755 index 000000000..5de08c0d4 --- /dev/null +++ b/src/dom/charclass.h @@ -0,0 +1,185 @@ +#ifndef __CHARCLASS_H__ +#define __CHARCLASS_H__ +/** + * Phoebe DOM Implementation. + * + * This is a C++ approximation of the W3C DOM model, which follows + * fairly closely the specifications in the various .idl files, copies of + * which are provided for reference. Most important is this one: + * + * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/idl-definitions.html + * + * Authors: + * Bob Jamison + * + * Copyright (C) 2005 Bob Jamison + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + + +/** + * Utility classes to test characters for their class, as specified in + * http://www.w3.org/TR/REC-xml/#CharClasses + */ + +/** + * Convenience method. Not in spec + * [impl] LetterOrDigit ::= + * Letter | Digit + */ +bool isLetterOrDigit(int ch); + + +/** + * [84] Letter ::= + * BaseChar | Ideographic + */ +bool isLetter(int ch); + + +/** + * [85] BaseChar ::= + * [#x0041-#x005A] | [#x0061-#x007A] | [#x00C0-#x00D6] | [#x00D8-#x00F6] | + * [#x00F8-#x00FF] | [#x0100-#x0131] | [#x0134-#x013E] | [#x0141-#x0148] | + * [#x014A-#x017E] | [#x0180-#x01C3] | [#x01CD-#x01F0] | [#x01F4-#x01F5] | + * [#x01FA-#x0217] | [#x0250-#x02A8] | [#x02BB-#x02C1] | #x0386 | + * [#x0388-#x038A] | #x038C | [#x038E-#x03A1] | [#x03A3-#x03CE] | + * [#x03D0-#x03D6] | #x03DA | #x03DC | #x03DE | #x03E0 | [#x03E2-#x03F3] | + * [#x0401-#x040C] | [#x040E-#x044F] | [#x0451-#x045C] | [#x045E-#x0481] | + * [#x0490-#x04C4] | [#x04C7-#x04C8] | [#x04CB-#x04CC] | [#x04D0-#x04EB] | + * [#x04EE-#x04F5] | [#x04F8-#x04F9] | [#x0531-#x0556] | #x0559 | + * [#x0561-#x0586] | [#x05D0-#x05EA] | [#x05F0-#x05F2] | [#x0621-#x063A] | + * [#x0641-#x064A] | [#x0671-#x06B7] | [#x06BA-#x06BE] | [#x06C0-#x06CE] | + * [#x06D0-#x06D3] | #x06D5 | [#x06E5-#x06E6] | [#x0905-#x0939] | #x093D | + * [#x0958-#x0961] | [#x0985-#x098C] | [#x098F-#x0990] | [#x0993-#x09A8] | + * [#x09AA-#x09B0] | #x09B2 | [#x09B6-#x09B9] | [#x09DC-#x09DD] | + * [#x09DF-#x09E1] | [#x09F0-#x09F1] | [#x0A05-#x0A0A] | [#x0A0F-#x0A10] | + * [#x0A13-#x0A28] | [#x0A2A-#x0A30] | [#x0A32-#x0A33] | [#x0A35-#x0A36] | + * [#x0A38-#x0A39] | [#x0A59-#x0A5C] | #x0A5E | [#x0A72-#x0A74] | + * [#x0A85-#x0A8B] | #x0A8D | [#x0A8F-#x0A91] | [#x0A93-#x0AA8] | + * [#x0AAA-#x0AB0] | [#x0AB2-#x0AB3] | [#x0AB5-#x0AB9] | #x0ABD | #x0AE0 | + * [#x0B05-#x0B0C] | [#x0B0F-#x0B10] | [#x0B13-#x0B28] | [#x0B2A-#x0B30] | + * [#x0B32-#x0B33] | [#x0B36-#x0B39] | #x0B3D | [#x0B5C-#x0B5D] | + * [#x0B5F-#x0B61] | [#x0B85-#x0B8A] | [#x0B8E-#x0B90] | [#x0B92-#x0B95] | + * [#x0B99-#x0B9A] | #x0B9C | [#x0B9E-#x0B9F] | [#x0BA3-#x0BA4] | + * [#x0BA8-#x0BAA] | [#x0BAE-#x0BB5] | [#x0BB7-#x0BB9] | [#x0C05-#x0C0C] | + * [#x0C0E-#x0C10] | [#x0C12-#x0C28] | [#x0C2A-#x0C33] | + * [#x0C35-#x0C39] | [#x0C60-#x0C61] | [#x0C85-#x0C8C] | [#x0C8E-#x0C90] | + * [#x0C92-#x0CA8] | [#x0CAA-#x0CB3] | [#x0CB5-#x0CB9] | #x0CDE | + * [#x0CE0-#x0CE1] | [#x0D05-#x0D0C] | [#x0D0E-#x0D10] | [#x0D12-#x0D28] | + * [#x0D2A-#x0D39] | [#x0D60-#x0D61] | [#x0E01-#x0E2E] | #x0E30 | + * [#x0E32-#x0E33] | [#x0E40-#x0E45] | [#x0E81-#x0E82] | #x0E84 | + * [#x0E87-#x0E88] | #x0E8A | #x0E8D | [#x0E94-#x0E97] | [#x0E99-#x0E9F] | + * [#x0EA1-#x0EA3] | #x0EA5 | #x0EA7 | [#x0EAA-#x0EAB] | [#x0EAD-#x0EAE] | + * #x0EB0 | [#x0EB2-#x0EB3] | #x0EBD | [#x0EC0-#x0EC4] | [#x0F40-#x0F47] | + * [#x0F49-#x0F69] | [#x10A0-#x10C5] | [#x10D0-#x10F6] | #x1100 | + * [#x1102-#x1103] | [#x1105-#x1107] | #x1109 | [#x110B-#x110C] | + * [#x110E-#x1112] | #x113C | #x113E | #x1140 | #x114C | #x114E | + * #x1150 | [#x1154-#x1155] | #x1159 | [#x115F-#x1161] | #x1163 | + * #x1165 | #x1167 | #x1169 | [#x116D-#x116E] | [#x1172-#x1173] | #x1175 | + * #x119E | #x11A8 | #x11AB | [#x11AE-#x11AF] | [#x11B7-#x11B8] | #x11BA | + * [#x11BC-#x11C2] | #x11EB | #x11F0 | #x11F9 | [#x1E00-#x1E9B] | + * [#x1EA0-#x1EF9] | [#x1F00-#x1F15] | [#x1F18-#x1F1D] | [#x1F20-#x1F45] | + * [#x1F48-#x1F4D] | [#x1F50-#x1F57] | #x1F59 | #x1F5B | #x1F5D | + * [#x1F5F-#x1F7D] | [#x1F80-#x1FB4] | [#x1FB6-#x1FBC] | #x1FBE | + * [#x1FC2-#x1FC4] | [#x1FC6-#x1FCC] | [#x1FD0-#x1FD3] | [#x1FD6-#x1FDB] | + * [#x1FE0-#x1FEC] | [#x1FF2-#x1FF4] | [#x1FF6-#x1FFC] | #x2126 | + * [#x212A-#x212B] | #x212E | [#x2180-#x2182] | [#x3041-#x3094] | + * [#x30A1-#x30FA] | [#x3105-#x312C] | [#xAC00-#xD7A3] + */ +bool isBaseChar(int ch); + + +/** + * [86] Ideographic ::= + * [#x4E00-#x9FA5] | #x3007 | [#x3021-#x3029] + */ +bool isIdeographic(int ch); + + + + + +/** + * [87] CombiningChar ::= + * [#x0300-#x0345] | [#x0360-#x0361] | [#x0483-#x0486] | [#x0591-#x05A1] | + * [#x05A3-#x05B9] | [#x05BB-#x05BD] | #x05BF | [#x05C1-#x05C2] | #x05C4 | + * [#x064B-#x0652] | #x0670 | [#x06D6-#x06DC] | [#x06DD-#x06DF] | + * [#x06E0-#x06E4] | [#x06E7-#x06E8] | [#x06EA-#x06ED] | [#x0901-#x0903] | + * #x093C | [#x093E-#x094C] | #x094D | [#x0951-#x0954] |[#x0962-#x0963] | + * [#x0981-#x0983] | #x09BC | #x09BE | #x09BF | [#x09C0-#x09C4] | + * [#x09C7-#x09C8] | [#x09CB-#x09CD] | #x09D7 | [#x09E2-#x09E3] | + * #x0A02 | #x0A3C | #x0A3E | #x0A3F | [#x0A40-#x0A42] | [#x0A47-#x0A48] | + * [#x0A4B-#x0A4D] | [#x0A70-#x0A71] | [#x0A81-#x0A83] | #x0ABC | + * [#x0ABE-#x0AC5] | [#x0AC7-#x0AC9] | [#x0ACB-#x0ACD] | [#x0B01-#x0B03] | + * #x0B3C | [#x0B3E-#x0B43] | [#x0B47-#x0B48] | [#x0B4B-#x0B4D] | + * [#x0B56-#x0B57] | [#x0B82-#x0B83] | [#x0BBE-#x0BC2] | [#x0BC6-#x0BC8] | + * [#x0BCA-#x0BCD] | #x0BD7 | [#x0C01-#x0C03] | [#x0C3E-#x0C44] | + * [#x0C46-#x0C48] | [#x0C4A-#x0C4D] | [#x0C55-#x0C56] | [#x0C82-#x0C83] | + * [#x0CBE-#x0CC4] | [#x0CC6-#x0CC8] | [#x0CCA-#x0CCD] | [#x0CD5-#x0CD6] | + * [#x0D02-#x0D03] | [#x0D3E-#x0D43] | [#x0D46-#x0D48] | [#x0D4A-#x0D4D] | + * #x0D57 | #x0E31 | [#x0E34-#x0E3A] | [#x0E47-#x0E4E] | #x0EB1 | + * [#x0EB4-#x0EB9] | [#x0EBB-#x0EBC] | [#x0EC8-#x0ECD] | [#x0F18-#x0F19] | + * #x0F35 | #x0F37 | #x0F39 | #x0F3E | #x0F3F | [#x0F71-#x0F84] | + * [#x0F86-#x0F8B] | [#x0F90-#x0F95] | #x0F97 | [#x0F99-#x0FAD] | + * [#x0FB1-#x0FB7] | #x0FB9 | [#x20D0-#x20DC] | #x20E1 | [#x302A-#x302F] | + * #x3099 | #x309A + */ +bool isCombiningChar(int ch); + + + +/** + * [88] Digit ::= + * [#x0030-#x0039] | [#x0660-#x0669] | [#x06F0-#x06F9] | + * [#x0966-#x096F] | [#x09E6-#x09EF] | [#x0A66-#x0A6F] | [#x0AE6-#x0AEF] | + * [#x0B66-#x0B6F] | [#x0BE7-#x0BEF] | [#x0C66-#x0C6F] | [#x0CE6-#x0CEF] | + * [#x0D66-#x0D6F] | [#x0E50-#x0E59] | [#x0ED0-#x0ED9] | [#x0F20-#x0F29] + */ +bool isDigit(int ch); + + + + +/** + * [89] Extender ::= + * #x00B7 | #x02D0 | #x02D1 | #x0387 | #x0640 | #x0E46 | #x0EC6 | + * #x3005 | [#x3031-#x3035] | [#x309D-#x309E] | [#x30FC-#x30FE] + */ +bool isExtender(int ch); + + + + +#endif /* __CHARCLASS_H__ */ + + + + + + + + + + + + + + + + + diff --git a/src/dom/css.h b/src/dom/css.h new file mode 100755 index 000000000..6ab92389e --- /dev/null +++ b/src/dom/css.h @@ -0,0 +1,4121 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program is distributed the + * hope that it will be useful, but WITHOUT ANY WARRANTY; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. + * See W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +// File: http://www.w3.org/TR/2000/REC-DOM-Level-2-Style-20001113/css.idl + +#ifndef __CSS_H__ +#define __CSS_H__ + +#include "dom.h" +#include "stylesheets.h" +#include "views.h" + +#include +#include + + +namespace org { +namespace w3c { +namespace dom { +namespace css { + + + + +//Make local definitions +typedef dom::DOMString DOMString; +typedef dom::Element Element; +typedef dom::DOMImplementation DOMImplementation; + +//forward declarations +class CSSRule; +class CSSStyleSheet; +class CSSStyleDeclaration; +class CSSValue; +class Counter; +class Rect; +class RGBColor; + + + + + +/*######################################################################### +## CSSRule +#########################################################################*/ + +/** + * + */ +class CSSRule +{ +public: + + typedef enum + { + UNKNOWN_RULE = 0, + STYLE_RULE = 1, + CHARSET_RULE = 2, + IMPORT_RULE = 3, + MEDIA_RULE = 4, + FONT_FACE_RULE = 5, + PAGE_RULE = 6 + } RuleType; + + + /** + * + */ + virtual unsigned short getType() + { + return type; + } + + /** + * + */ + virtual DOMString getCssText() + { + return cssText; + } + + /** + * + */ + virtual void setCssText(const DOMString &val) throw (dom::DOMException) + { + cssText = val; + } + + /** + * + */ + virtual CSSStyleSheet *getParentStyleSheet() + { + return parentStyleSheet; + } + + /** + * + */ + virtual CSSRule *getParentRule() + { + return parentRule; + } + + + + //################## + //# Non-API methods + //################## + + /** + * + */ + CSSRule() + { + type = UNKNOWN_RULE; + cssText = ""; + parentStyleSheet = NULL; + parentRule = NULL; + } + + /** + * + */ + CSSRule(const CSSRule &other) + { + type = other.type; + cssText = other.cssText; + parentStyleSheet = other.parentStyleSheet; + parentRule = other.parentRule; + } + + /** + * + */ + virtual ~CSSRule() {} + +protected: + + int type; + + DOMString cssText; + + CSSStyleSheet *parentStyleSheet; + + CSSRule *parentRule; +}; + + + +/*######################################################################### +## CSSRuleList +#########################################################################*/ + +/** + * + */ +class CSSRuleList +{ +public: + + /** + * + */ + virtual unsigned long getLength() + { + return rules.size(); + } + + /** + * + */ + virtual CSSRule item(unsigned long index) + { + if (index>=rules.size()) + { + CSSRule rule; + return rule; + } + return rules[index]; + } + + + //################## + //# Non-API methods + //################## + + /** + * + */ + CSSRuleList() {} + + + /** + * + */ + CSSRuleList(const CSSRuleList &other) + { + rules = other.rules; + } + + /** + * + */ + virtual ~CSSRuleList() {} + +protected: + +friend class CSSMediaRule; +friend class CSSStyleSheet; + + /** + * + */ + virtual void addRule(const CSSRule &rule) + { + rules.push_back(rule); + } + + + /** + * + */ + virtual void deleteRule(unsigned long index) + { + if (index>=rules.size()) + return; + std::vector::iterator iter = rules.begin() + index; + rules.erase(iter); + } + + + /** + * + */ + virtual long insertRule(const CSSRule &rule, unsigned long index) + { + if (index>=rules.size()) + return -1; + std::vector::iterator iter = rules.begin() + index; + rules.insert(iter, rule); + return index; + } + + std::vectorrules; +}; + + +/*######################################################################### +## CSSStyleSheet +#########################################################################*/ + +/** + * + */ +class CSSStyleSheet : virtual public stylesheets::StyleSheet +{ +public: + + /** + * + */ + virtual CSSRule *getOwnerRule() + { + return ownerRule; + } + + /** + * + */ + virtual CSSRuleList getCssRules() + { + return rules; + } + + /** + * + */ + virtual unsigned long insertRule(const DOMString &ruleStr, + unsigned long index) + throw (dom::DOMException) + { + CSSRule rule; + return rules.insertRule(rule, index); + } + + /** + * + */ + virtual void deleteRule(unsigned long index) + throw (dom::DOMException) + { + rules.deleteRule(index); + } + + //################## + //# Non-API methods + //################## + + /** + * + */ + CSSStyleSheet() : stylesheets::StyleSheet() + { + } + + /** + * + */ + CSSStyleSheet(const CSSStyleSheet &other) : + stylesheets::StyleSheet(other) + { + ownerRule = other.ownerRule; + rules = other.rules; + } + + /** + * + */ + virtual ~CSSStyleSheet() {} + +protected: + + CSSRule *ownerRule; + + CSSRuleList rules; +}; + + +/*######################################################################### +## CSSValue +#########################################################################*/ + +/** + * + */ +class CSSValue +{ +public: + + /** + * UnitTypes + */ + enum + { + CSS_INHERIT = 0, + CSS_PRIMITIVE_VALUE = 1, + CSS_VALUE_LIST = 2, + CSS_CUSTOM = 3 + }; + + /** + * + */ + virtual DOMString getCssText() + { + return cssText; + } + + /** + * + */ + virtual void setCssText(const DOMString &val) + throw (dom::DOMException) + { + cssText = val; + } + + /** + * + */ + virtual unsigned short getCssValueType() + { + return valueType; + } + + //################## + //# Non-API methods + //################## + + /** + * + */ + CSSValue() + { + valueType = CSS_INHERIT; + } + + /** + * + */ + CSSValue(const CSSValue &other) + { + cssText = other.cssText; + valueType = other.valueType; + } + + /** + * + */ + virtual ~CSSValue() {} + +protected: + + DOMString cssText; + int valueType; +}; + + + + + +/*######################################################################### +## CSSStyleDeclaration +#########################################################################*/ + +class CSSStyleDeclarationEntry +{ +public: + CSSStyleDeclarationEntry(const DOMString &nameArg, + const DOMString &valueArg, + const DOMString &prioArg) + { + name = nameArg; + value = valueArg; + prio = prioArg; + } + ~CSSStyleDeclarationEntry(){} + DOMString name; + DOMString value; + DOMString prio; +}; + + + +/** + * + */ +class CSSStyleDeclaration +{ +public: + + /** + * + */ + virtual DOMString getCssText() + { + return cssText; + } + + /** + * + */ + virtual void setCssText(const DOMString &val) + throw (dom::DOMException) + { + cssText = val; + } + + /** + * + */ + virtual DOMString getPropertyValue(const DOMString &propertyName) + { + std::vector::iterator iter; + for (iter=items.begin() ; iter!=items.end() ; iter++) + { + if (iter->name == propertyName) + return iter->value; + } + return ""; + } + + /** + * + */ + virtual CSSValue getPropertyCSSValue(const DOMString &propertyName) + { + CSSValue value; + return value; + } + + /** + * + */ + virtual DOMString removeProperty(const DOMString &propertyName) + throw (dom::DOMException) + { + std::vector::iterator iter; + for (iter=items.begin() ; iter!=items.end() ; iter++) + { + if (iter->name == propertyName) + items.erase(iter); + } + return propertyName; + } + + /** + * + */ + virtual DOMString getPropertyPriority(const DOMString &propertyName) + { + std::vector::iterator iter; + for (iter=items.begin() ; iter!=items.end() ; iter++) + { + if (iter->name == propertyName) + return iter->prio; + } + return ""; + } + + /** + * + */ + virtual void setProperty(const DOMString &propertyName, + const DOMString &value, + const DOMString &priority) + throw (dom::DOMException) + { + std::vector::iterator iter; + for (iter=items.begin() ; iter!=items.end() ; iter++) + { + if (iter->name == propertyName) + { + iter->name = propertyName; + iter->value = value; + iter->prio = priority; + return; + } + } + CSSStyleDeclarationEntry entry(propertyName, value, priority); + items.push_back(entry); + } + + /** + * + */ + virtual unsigned long getLength() + { + return items.size(); + } + + /** + * + */ + virtual DOMString item(unsigned long index) + { + if (index>=items.size()) + return ""; + DOMString ret = items[index].name; + ret.append(":"); + ret.append(items[index].value); + return ret; + } + + /** + * + */ + virtual CSSRule *getParentRule() + { + return parentRule; + } + + //################## + //# Non-API methods + //################## + + /** + * + */ + CSSStyleDeclaration() + { + parentRule = NULL; + } + + /** + * + */ + CSSStyleDeclaration(const CSSStyleDeclaration &other) + { + } + + /** + * + */ + virtual ~CSSStyleDeclaration() {} + +protected: + + DOMString cssText; + + CSSRule *parentRule; + + std::vector items; +}; + + + + +/*######################################################################### +## CSSStyleRule +#########################################################################*/ + +/** + * + */ +class CSSStyleRule : virtual public CSSRule +{ +public: + + /** + * + */ + virtual DOMString getSelectorText() + { + return selectorText; + } + + /** + * + */ + virtual void setSelectorText(const DOMString &val) + throw (dom::DOMException) + { + selectorText = val; + } + + + /** + * + */ + virtual CSSStyleDeclaration &getStyle() + { + return style; + } + + //################## + //# Non-API methods + //################## + + /** + * + */ + CSSStyleRule() : CSSRule() + { + type = STYLE_RULE; + selectorText = ""; + } + + + /** + * + */ + CSSStyleRule(const CSSStyleRule &other) : CSSRule(other) + { + selectorText = other.selectorText; + style = other.style; + } + + /** + * + */ + virtual ~CSSStyleRule() {} + +protected: + + DOMString selectorText; + + CSSStyleDeclaration style; + +}; + +/*######################################################################### +## CSSMediaRule +#########################################################################*/ + +/** + * + */ +class CSSMediaRule : virtual public CSSRule +{ +public: + + /** + * + */ + virtual stylesheets::MediaList getMedia() + { + return mediaList; + } + + /** + * + */ + virtual CSSRuleList getCssRules() + { + return cssRules; + } + + /** + * + */ + virtual unsigned long insertRule(const DOMString &ruleStr, + unsigned long index) + throw (dom::DOMException) + { + if (index>cssRules.getLength()) + return 0; + CSSRule rule; + cssRules.insertRule(rule, index); + return index; + } + + /** + * + */ + virtual void deleteRule(unsigned long index) + throw(dom::DOMException) + { + cssRules.deleteRule(index); + } + + //################## + //# Non-API methods + //################## + + /** + * + */ + CSSMediaRule() : CSSRule() + { + type = MEDIA_RULE; + } + + /** + * + */ + CSSMediaRule(const CSSMediaRule &other) : CSSRule(other) + { + mediaList = other.mediaList; + cssRules = other.cssRules; + } + + /** + * + */ + virtual ~CSSMediaRule() {} + +protected: + + stylesheets::MediaList mediaList; + + CSSRuleList cssRules; +}; + + + + +/*######################################################################### +## CSSFontFaceRule +#########################################################################*/ + +/** + * + */ +class CSSFontFaceRule : virtual public CSSRule +{ +public: + + /** + * + */ + virtual CSSStyleDeclaration getStyle() + { + return style; + } + + + //################## + //# Non-API methods + //################## + + /** + * + */ + CSSFontFaceRule() : CSSRule() + { + type = FONT_FACE_RULE; + } + + /** + * + */ + CSSFontFaceRule(const CSSFontFaceRule &other) : CSSRule(other) + { + style = other.style; + } + + /** + * + */ + virtual ~CSSFontFaceRule() {} + +protected: + + CSSStyleDeclaration style; +}; + + + + +/*######################################################################### +## CSSPageRule +#########################################################################*/ + +/** + * + */ +class CSSPageRule : virtual public CSSRule +{ +public: + + /** + * + */ + virtual DOMString getSelectorText() + { + return selectorText; + } + + /** + * + */ + virtual void setSelectorText(const DOMString &val) + throw(dom::DOMException) + { + selectorText = val; + } + + + /** + * + */ + virtual CSSStyleDeclaration getStyle() + { + return style; + } + + + //################## + //# Non-API methods + //################## + + /** + * + */ + CSSPageRule() : CSSRule() + { + type = PAGE_RULE; + } + + /** + * + */ + CSSPageRule(const CSSPageRule &other) : CSSRule(other) + { + selectorText = other.selectorText; + style = other.style; + } + + /** + * + */ + virtual ~CSSPageRule() {} + +protected: + + DOMString selectorText; + + CSSStyleDeclaration style; +}; + + + + + +/*######################################################################### +## CSSImportRule +#########################################################################*/ + +/** + * + */ +class CSSImportRule : virtual public CSSRule +{ +public: + + /** + * + */ + virtual DOMString getHref() + { + return href; + } + + /** + * + */ + virtual stylesheets::MediaList getMedia() + { + return mediaList; + } + + /** + * + */ + virtual CSSStyleSheet getStyleSheet() + { + return styleSheet; + } + + + //################## + //# Non-API methods + //################## + + /** + * + */ + CSSImportRule() : CSSRule() + { + type = IMPORT_RULE; + } + + /** + * + */ + CSSImportRule(const CSSImportRule &other) : CSSRule(other) + { + mediaList = other.mediaList; + styleSheet = other.styleSheet; + } + + /** + * + */ + virtual ~CSSImportRule() {} + +protected: + + DOMString href; + + stylesheets::MediaList mediaList; + + CSSStyleSheet styleSheet; +}; + + + + + + +/*######################################################################### +## CSSCharsetRule +#########################################################################*/ + +/** + * + */ +class CSSCharsetRule : virtual public CSSRule +{ +public: + + /** + * + */ + virtual DOMString getEncoding() + { + return encoding; + } + + /** + * + */ + virtual void setEncoding(const DOMString &val) throw (dom::DOMException) + { + encoding = val; + } + + //################## + //# Non-API methods + //################## + + /** + * + */ + CSSCharsetRule() : CSSRule() + { + type = CHARSET_RULE; + } + + /** + * + */ + CSSCharsetRule(const CSSCharsetRule &other) : CSSRule(other) + { + encoding = other.encoding; + } + + /** + * + */ + virtual ~CSSCharsetRule() {} + +protected: + + DOMString encoding; + +}; + + + + + +/*######################################################################### +## CSSUnknownRule +#########################################################################*/ + +/** + * + */ +class CSSUnknownRule : virtual public CSSRule +{ +public: + + //################## + //# Non-API methods + //################## + + /** + * + */ + CSSUnknownRule() : CSSRule() + { + type = UNKNOWN_RULE; + } + + /** + * + */ + CSSUnknownRule(const CSSUnknownRule &other) : CSSRule(other) + { + } + + /** + * + */ + virtual ~CSSUnknownRule() {} +}; + + + + + + + +/*######################################################################### +## CSSValueList +#########################################################################*/ + +/** + * + */ +class CSSValueList : virtual public CSSValue +{ +public: + + /** + * + */ + virtual unsigned long getLength() + { + return items.size(); + } + + /** + * + */ + virtual CSSValue item(unsigned long index) + { + if (index>=items.size()) + { + CSSValue dummy; + return dummy; + } + return items[index]; + } + + //################## + //# Non-API methods + //################## + + /** + * + */ + CSSValueList() + { + } + + /** + * + */ + CSSValueList(const CSSValueList &other) : CSSValue(other) + { + items = other.items; + } + + /** + * + */ + virtual ~CSSValueList() {} + +protected: + + std::vector items; +}; + + + + +/*######################################################################### +## CSSPrimitiveValue +#########################################################################*/ + +/** + * + */ +class CSSPrimitiveValue : virtual public CSSValue +{ +public: + + /** + * UnitTypes + */ + enum + { + CSS_UNKNOWN = 0, + CSS_NUMBER = 1, + CSS_PERCENTAGE = 2, + CSS_EMS = 3, + CSS_EXS = 4, + CSS_PX = 5, + CSS_CM = 6, + CSS_MM = 7, + CSS_IN = 8, + CSS_PT = 9, + CSS_PC = 10, + CSS_DEG = 11, + CSS_RAD = 12, + CSS_GRAD = 13, + CSS_MS = 14, + CSS_S = 15, + CSS_HZ = 16, + CSS_KHZ = 17, + CSS_DIMENSION = 18, + CSS_STRING = 19, + CSS_URI = 20, + CSS_IDENT = 21, + CSS_ATTR = 22, + CSS_COUNTER = 23, + CSS_RECT = 24, + CSS_RGBCOLOR = 25 + }; + + + /** + * + */ + virtual unsigned short getPrimitiveType() + { + return primitiveType; + } + + /** + * + */ + virtual void setFloatValue(unsigned short unitType, + double doubleValueArg) + throw (dom::DOMException) + { + primitiveType = unitType; + doubleValue = doubleValueArg; + } + /** + * + */ + virtual double getFloatValue(unsigned short unitType) + throw (dom::DOMException) + { + return doubleValue; + } + + /** + * + */ + virtual void setStringValue(unsigned short stringType, + const DOMString &stringValueArg) + throw (dom::DOMException) + { + stringValue = stringValueArg; + } + + /** + * + */ + virtual DOMString getStringValue() throw (dom::DOMException) + { + return stringValue; + } + + /** + * + */ + virtual Counter *getCounterValue() throw (dom::DOMException) + { + return NULL; + } + + /** + * + */ + virtual Rect *getRectValue() throw (dom::DOMException) + { + return NULL; + } + + /** + * + */ + virtual RGBColor *getRGBColorValue() throw (dom::DOMException) + { + return NULL; + } + + //################## + //# Non-API methods + //################## + + /** + * + */ + CSSPrimitiveValue() : CSSValue() + { + } + + /** + * + */ + CSSPrimitiveValue(const CSSPrimitiveValue &other) : CSSValue(other) + { + } + + /** + * + */ + virtual ~CSSPrimitiveValue() {} + +protected: + + int primitiveType; + + double doubleValue; + + DOMString stringValue; + + +}; + + + +/*######################################################################### +## RGBColor +#########################################################################*/ + +/** + * + */ +class RGBColor +{ +public: + + /** + * + */ + virtual CSSPrimitiveValue getRed() + { + return red; + } + + /** + * + */ + virtual CSSPrimitiveValue getGreen() + { + return green; + } + + /** + * + */ + virtual CSSPrimitiveValue getBlue() + { + return blue; + } + + /** + * REPLACES: RGBColor CSSPrimitiveValue::getRGBColorValue() throw (dom::DOMException) + */ + static RGBColor getRGBColorValue(const CSSPrimitiveValue &val) + { + RGBColor col; + return col; + } + + //################## + //# Non-API methods + //################## + + /** + * + */ + RGBColor() {} + + /** + * + */ + RGBColor(const RGBColor &other) + { + red = other.red; + green = other.green; + blue = other.blue; + } + + /** + * + */ + virtual ~RGBColor() {} + +protected: + + CSSPrimitiveValue red; + CSSPrimitiveValue green; + CSSPrimitiveValue blue; +}; + + + + +/*######################################################################### +## Rect +#########################################################################*/ + +/** + * + */ +class Rect +{ +public: + + /** + * + */ + virtual CSSPrimitiveValue getTop() + { + return top; + } + + /** + * + */ + virtual CSSPrimitiveValue getRight() + { + return right; + } + + /** + * + */ + virtual CSSPrimitiveValue getBottom() + { + return bottom; + } + + /** + * + */ + virtual CSSPrimitiveValue getLeft() + { + return left; + } + + /** + * REPLACES: Rect CSSPrimitiveValue::getRectValue() throw (dom::DOMException) + */ + static Rect getRectValue(const CSSPrimitiveValue &val) + { + Rect rect; + return rect; + } + + //################## + //# Non-API methods + //################## + + /** + * + */ + Rect() {} + + /** + * + */ + Rect(const Rect &other) + { + top = other.top; + right = other.right; + bottom = other.bottom; + left = other.left; + } + + /** + * + */ + virtual ~Rect() {} + +protected: + + CSSPrimitiveValue top; + CSSPrimitiveValue right; + CSSPrimitiveValue bottom; + CSSPrimitiveValue left; +}; + + + + + + +/*######################################################################### +## Counter +#########################################################################*/ + +/** + * + */ +class Counter +{ +public: + + /** + * + */ + virtual DOMString getIdentifier() + { + return identifier; + } + + /** + * + */ + virtual DOMString getListStyle() + { + return listStyle; + } + + /** + * + */ + virtual DOMString getSeparator() + { + return separator; + } + + /** + * REPLACES: Counter CSSPrimitiveValue::getCounterValue() throw (dom::DOMException) + */ + static Counter getCounterValue(const CSSPrimitiveValue &val) + { + Counter counter; + return counter; + } + + //################## + //# Non-API methods + //################## + + /** + * + */ + Counter() {} + + /** + * + */ + Counter(const Counter &other) + { + identifier = other.identifier; + listStyle = other.listStyle; + separator = other.separator; + } + + /** + * + */ + virtual ~Counter() {} + +protected: + + DOMString identifier; + DOMString listStyle; + DOMString separator; + +}; + + + + +/*######################################################################### +## ElementCSSInlineStyle +#########################################################################*/ + +/** + * + */ +class ElementCSSInlineStyle +{ +public: + + /** + * + */ + virtual CSSStyleDeclaration getStyle() + { + return style; + } + + //################## + //# Non-API methods + //################## + + /** + * + */ + ElementCSSInlineStyle() {} + + /** + * + */ + ElementCSSInlineStyle(const ElementCSSInlineStyle &other) + { + style = other.style; + } + + /** + * + */ + virtual ~ElementCSSInlineStyle() {} + +protected: + + CSSStyleDeclaration style; +}; + + + + + + +/*######################################################################### +## CSS2Properties +#########################################################################*/ + +/** + * + */ +class CSS2Properties +{ +public: + + + /** + * return the 'azimuth' property + */ + virtual DOMString getAzimuth() + { + return azimuth; + } + + /** + * set the 'azimuth' property + */ + virtual void setAzimuth(const DOMString &val) + throw (dom::DOMException) + { + azimuth = val; + } + + /** + * return the 'background' property + */ + virtual DOMString getBackground() + { + return background; + } + + /** + * set the 'background' property + */ + virtual void setBackground(const DOMString &val) + throw (dom::DOMException) + { + background = val; + } + + /** + * return the 'backgroundAttachment' property + */ + virtual DOMString getBackgroundAttachment() + { + return backgroundAttachment; + } + + /** + * set the 'backgroundAttachment' property + */ + virtual void setBackgroundAttachment(const DOMString &val) + throw (dom::DOMException) + { + backgroundAttachment = val; + } + + /** + * return the 'backgroundColor' property + */ + virtual DOMString getBackgroundColor() + { + return backgroundColor; + } + + /** + * set the 'backgroundColor' property + */ + virtual void setBackgroundColor(const DOMString &val) + throw (dom::DOMException) + { + backgroundColor = val; + } + + /** + * return the 'backgroundImage' property + */ + virtual DOMString getBackgroundImage() + { + return backgroundImage; + } + + /** + * set the 'backgroundImage' property + */ + virtual void setBackgroundImage(const DOMString &val) + throw (dom::DOMException) + { + backgroundImage = val; + } + + /** + * return the 'backgroundPosition' property + */ + virtual DOMString getBackgroundPosition() + { + return backgroundPosition; + } + + /** + * set the 'backgroundPosition' property + */ + virtual void setBackgroundPosition(const DOMString &val) + throw (dom::DOMException) + { + backgroundPosition = val; + } + + /** + * return the 'backgroundRepeat' property + */ + virtual DOMString getBackgroundRepeat() + { + return backgroundRepeat; + } + + /** + * set the 'backgroundRepeat' property + */ + virtual void setBackgroundRepeat(const DOMString &val) + throw (dom::DOMException) + { + backgroundRepeat = val; + } + + /** + * return the 'border' property + */ + virtual DOMString getBorder() + { + return border; + } + + /** + * set the 'border' property + */ + virtual void setBorder(const DOMString &val) + throw (dom::DOMException) + { + border = val; + } + + /** + * return the 'borderCollapse' property + */ + virtual DOMString getBorderCollapse() + { + return borderCollapse; + } + + /** + * set the 'borderCollapse' property + */ + virtual void setBorderCollapse(const DOMString &val) + throw (dom::DOMException) + { + borderCollapse = val; + } + + /** + * return the 'borderColor' property + */ + virtual DOMString getBorderColor() + { + return borderColor; + } + + /** + * set the 'borderColor' property + */ + virtual void setBorderColor(const DOMString &val) + throw (dom::DOMException) + { + borderColor = val; + } + + /** + * return the 'borderSpacing' property + */ + virtual DOMString getBorderSpacing() + { + return borderSpacing; + } + + /** + * set the 'borderSpacing' property + */ + virtual void setBorderSpacing(const DOMString &val) + throw (dom::DOMException) + { + borderSpacing = val; + } + + /** + * return the 'borderStyle' property + */ + virtual DOMString getBorderStyle() + { + return borderStyle; + } + + /** + * set the 'borderStyle' property + */ + virtual void setBorderStyle(const DOMString &val) + throw (dom::DOMException) + { + borderStyle = val; + } + + /** + * return the 'borderTop' property + */ + virtual DOMString getBorderTop() + { + return borderTop; + } + + /** + * set the 'borderTop' property + */ + virtual void setBorderTop(const DOMString &val) + throw (dom::DOMException) + { + borderTop = val; + } + + /** + * return the 'borderRight' property + */ + virtual DOMString getBorderRight() + { + return borderRight; + } + + /** + * set the 'borderRight' property + */ + virtual void setBorderRight(const DOMString &val) + throw (dom::DOMException) + { + borderRight = val; + } + + /** + * return the 'borderBottom' property + */ + virtual DOMString getBorderBottom() + { + return borderBottom; + } + + /** + * set the 'borderBottom' property + */ + virtual void setBorderBottom(const DOMString &val) + throw (dom::DOMException) + { + borderBottom = val; + } + + /** + * return the 'borderLeft' property + */ + virtual DOMString getBorderLeft() + { + return borderLeft; + } + + /** + * set the 'borderLeft' property + */ + virtual void setBorderLeft(const DOMString &val) + throw (dom::DOMException) + { + borderLeft = val; + } + + /** + * return the 'borderTopColor' property + */ + virtual DOMString getBorderTopColor() + { + return borderTopColor; + } + + /** + * set the 'borderTopColor' property + */ + virtual void setBorderTopColor(const DOMString &val) + throw (dom::DOMException) + { + borderTopColor = val; + } + + /** + * return the 'borderRightColor' property + */ + virtual DOMString getBorderRightColor() + { + return borderRightColor; + } + + /** + * set the 'borderRightColor' property + */ + virtual void setBorderRightColor(const DOMString &val) + throw (dom::DOMException) + { + borderRightColor = val; + } + + /** + * return the 'borderBottomColor' property + */ + virtual DOMString getBorderBottomColor() + { + return borderBottomColor; + } + + /** + * set the 'borderBottomColor' property + */ + virtual void setBorderBottomColor(const DOMString &val) + throw (dom::DOMException) + { + borderBottomColor = val; + } + + /** + * return the 'borderLeftColor' property + */ + virtual DOMString getBorderLeftColor() + { + return borderLeftColor; + } + + /** + * set the 'borderLeftColor' property + */ + virtual void setBorderLeftColor(const DOMString &val) + throw (dom::DOMException) + { + borderLeftColor = val; + } + + /** + * return the 'borderTopStyle' property + */ + virtual DOMString getBorderTopStyle() + { + return borderTopStyle; + } + + /** + * set the 'borderTopStyle' property + */ + virtual void setBorderTopStyle(const DOMString &val) + throw (dom::DOMException) + { + borderTopStyle = val; + } + + /** + * return the 'borderRightStyle' property + */ + virtual DOMString getBorderRightStyle() + { + return borderRightStyle; + } + + /** + * set the 'borderRightStyle' property + */ + virtual void setBorderRightStyle(const DOMString &val) + throw (dom::DOMException) + { + borderRightStyle = val; + } + + /** + * return the 'borderBottomStyle' property + */ + virtual DOMString getBorderBottomStyle() + { + return borderBottomStyle; + } + + /** + * set the 'borderBottomStyle' property + */ + virtual void setBorderBottomStyle(const DOMString &val) + throw (dom::DOMException) + { + borderBottomStyle = val; + } + + /** + * return the 'borderLeftStyle' property + */ + virtual DOMString getBorderLeftStyle() + { + return borderLeftStyle; + } + + /** + * set the 'borderLeftStyle' property + */ + virtual void setBorderLeftStyle(const DOMString &val) + throw (dom::DOMException) + { + borderLeftStyle = val; + } + + /** + * return the 'borderTopWidth' property + */ + virtual DOMString getBorderTopWidth() + { + return borderTopWidth; + } + + /** + * set the 'borderTopWidth' property + */ + virtual void setBorderTopWidth(const DOMString &val) + throw (dom::DOMException) + { + borderTopWidth = val; + } + + /** + * return the 'borderRightWidth' property + */ + virtual DOMString getBorderRightWidth() + { + return borderRightWidth; + } + + /** + * set the 'borderRightWidth' property + */ + virtual void setBorderRightWidth(const DOMString &val) + throw (dom::DOMException) + { + borderRightWidth = val; + } + + /** + * return the 'borderBottomWidth' property + */ + virtual DOMString getBorderBottomWidth() + { + return borderBottomWidth; + } + + /** + * set the 'borderBottomWidth' property + */ + virtual void setBorderBottomWidth(const DOMString &val) + throw (dom::DOMException) + { + borderBottomWidth = val; + } + + /** + * return the 'borderLeftWidth' property + */ + virtual DOMString getBorderLeftWidth() + { + return borderLeftWidth; + } + + /** + * set the 'borderLeftWidth' property + */ + virtual void setBorderLeftWidth(const DOMString &val) + throw (dom::DOMException) + { + borderLeftWidth = val; + } + + /** + * return the 'borderWidth' property + */ + virtual DOMString getBorderWidth() + { + return borderWidth; + } + + /** + * set the 'borderWidth' property + */ + virtual void setBorderWidth(const DOMString &val) + throw (dom::DOMException) + { + borderWidth = val; + } + + /** + * return the 'bottom' property + */ + virtual DOMString getBottom() + { + return bottom; + } + + /** + * set the 'bottom' property + */ + virtual void setBottom(const DOMString &val) + throw (dom::DOMException) + { + bottom = val; + } + + /** + * return the 'captionSide' property + */ + virtual DOMString getCaptionSide() + { + return captionSide; + } + + /** + * set the 'captionSide' property + */ + virtual void setCaptionSide(const DOMString &val) + throw (dom::DOMException) + { + captionSide = val; + } + + /** + * return the 'clear' property + */ + virtual DOMString getClear() + { + return clear; + } + + /** + * set the 'clear' property + */ + virtual void setClear(const DOMString &val) + throw (dom::DOMException) + { + clear = val; + } + + /** + * return the 'clip' property + */ + virtual DOMString getClip() + { + return clip; + } + + /** + * set the 'clip' property + */ + virtual void setClip(const DOMString &val) + throw (dom::DOMException) + { + clip = val; + } + + /** + * return the 'color' property + */ + virtual DOMString getColor() + { + return color; + } + + /** + * set the 'color' property + */ + virtual void setColor(const DOMString &val) + throw (dom::DOMException) + { + color = val; + } + + /** + * return the 'content' property + */ + virtual DOMString getContent() + { + return content; + } + + /** + * set the 'content' property + */ + virtual void setContent(const DOMString &val) + throw (dom::DOMException) + { + content = val; + } + + /** + * return the 'counterIncrement' property + */ + virtual DOMString getCounterIncrement() + { + return counterIncrement; + } + + /** + * set the 'counterIncrement' property + */ + virtual void setCounterIncrement(const DOMString &val) + throw (dom::DOMException) + { + counterIncrement = val; + } + + /** + * return the 'counterReset' property + */ + virtual DOMString getCounterReset() + { + return counterReset; + } + + /** + * set the 'counterReset' property + */ + virtual void setCounterReset(const DOMString &val) + throw (dom::DOMException) + { + counterReset = val; + } + + /** + * return the 'cue' property + */ + virtual DOMString getCue() + { + return cue; + } + + /** + * set the 'cue' property + */ + virtual void setCue(const DOMString &val) + throw (dom::DOMException) + { + cue = val; + } + + /** + * return the 'cueAfter' property + */ + virtual DOMString getCueAfter() + { + return cueAfter; + } + + /** + * set the 'cueAfter' property + */ + virtual void setCueAfter(const DOMString &val) + throw (dom::DOMException) + { + cueAfter = val; + } + + /** + * return the 'cueBefore' property + */ + virtual DOMString getCueBefore() + { + return cueBefore; + } + + /** + * set the 'cueBefore' property + */ + virtual void setCueBefore(const DOMString &val) + throw (dom::DOMException) + { + cueBefore = val; + } + + /** + * return the 'cursor' property + */ + virtual DOMString getCursor() + { + return cursor; + } + + /** + * set the 'cursor' property + */ + virtual void setCursor(const DOMString &val) + throw (dom::DOMException) + { + cursor = val; + } + + /** + * return the 'direction' property + */ + virtual DOMString getDirection() + { + return direction; + } + + /** + * set the 'direction' property + */ + virtual void setDirection(const DOMString &val) + throw (dom::DOMException) + { + direction = val; + } + + /** + * return the 'display' property + */ + virtual DOMString getDisplay() + { + return display; + } + + /** + * set the 'display' property + */ + virtual void setDisplay(const DOMString &val) + throw (dom::DOMException) + { + display = val; + } + + /** + * return the 'elevation' property + */ + virtual DOMString getElevation() + { + return elevation; + } + + /** + * set the 'elevation' property + */ + virtual void setElevation(const DOMString &val) + throw (dom::DOMException) + { + elevation = val; + } + + /** + * return the 'emptyCells' property + */ + virtual DOMString getEmptyCells() + { + return emptyCells; + } + + /** + * set the 'emptyCells' property + */ + virtual void setEmptyCells(const DOMString &val) + throw (dom::DOMException) + { + emptyCells = val; + } + + /** + * return the 'cssFloat' property + */ + virtual DOMString getCssFloat() + { + return cssFloat; + } + + /** + * set the 'cssFloat' property + */ + virtual void setCssFloat(const DOMString &val) + throw (dom::DOMException) + { + cssFloat = val; + } + + /** + * return the 'font' property + */ + virtual DOMString getFont() + { + return font; + } + + /** + * set the 'font' property + */ + virtual void setFont(const DOMString &val) + throw (dom::DOMException) + { + font = val; + } + + /** + * return the 'fontFamily' property + */ + virtual DOMString getFontFamily() + { + return fontFamily; + } + + /** + * set the 'fontFamily' property + */ + virtual void setFontFamily(const DOMString &val) + throw (dom::DOMException) + { + fontFamily = val; + } + + /** + * return the 'fontSize' property + */ + virtual DOMString getFontSize() + { + return fontSize; + } + + /** + * set the 'fontSize' property + */ + virtual void setFontSize(const DOMString &val) + throw (dom::DOMException) + { + fontSize = val; + } + + /** + * return the 'fontSizeAdjust' property + */ + virtual DOMString getFontSizeAdjust() + { + return fontSizeAdjust; + } + + /** + * set the 'fontSizeAdjust' property + */ + virtual void setFontSizeAdjust(const DOMString &val) + throw (dom::DOMException) + { + fontSizeAdjust = val; + } + + /** + * return the 'fontStretch' property + */ + virtual DOMString getFontStretch() + { + return fontStretch; + } + + /** + * set the 'fontStretch' property + */ + virtual void setFontStretch(const DOMString &val) + throw (dom::DOMException) + { + fontStretch = val; + } + + /** + * return the 'fontStyle' property + */ + virtual DOMString getFontStyle() + { + return fontStyle; + } + + /** + * set the 'fontStyle' property + */ + virtual void setFontStyle(const DOMString &val) + throw (dom::DOMException) + { + fontStyle = val; + } + + /** + * return the 'fontVariant' property + */ + virtual DOMString getFontVariant() + { + return fontVariant; + } + + /** + * set the 'fontVariant' property + */ + virtual void setFontVariant(const DOMString &val) + throw (dom::DOMException) + { + fontVariant = val; + } + + /** + * return the 'fontWeight' property + */ + virtual DOMString getFontWeight() + { + return fontWeight; + } + + /** + * set the 'fontWeight' property + */ + virtual void setFontWeight(const DOMString &val) + throw (dom::DOMException) + { + fontWeight = val; + } + + /** + * return the 'height' property + */ + virtual DOMString getHeight() + { + return height; + } + + /** + * set the 'height' property + */ + virtual void setHeight(const DOMString &val) + throw (dom::DOMException) + { + height = val; + } + + /** + * return the 'left' property + */ + virtual DOMString getLeft() + { + return left; + } + + /** + * set the 'left' property + */ + virtual void setLeft(const DOMString &val) + throw (dom::DOMException) + { + left = val; + } + + /** + * return the 'letterSpacing' property + */ + virtual DOMString getLetterSpacing() + { + return letterSpacing; + } + + /** + * set the 'letterSpacing' property + */ + virtual void setLetterSpacing(const DOMString &val) + throw (dom::DOMException) + { + letterSpacing = val; + } + + /** + * return the 'lineHeight' property + */ + virtual DOMString getLineHeight() + { + return lineHeight; + } + + /** + * set the 'lineHeight' property + */ + virtual void setLineHeight(const DOMString &val) + throw (dom::DOMException) + { + lineHeight = val; + } + + /** + * return the 'listStyle' property + */ + virtual DOMString getListStyle() + { + return listStyle; + } + + /** + * set the 'listStyle' property + */ + virtual void setListStyle(const DOMString &val) + throw (dom::DOMException) + { + listStyle = val; + } + + /** + * return the 'listStyleImage' property + */ + virtual DOMString getListStyleImage() + { + return listStyleImage; + } + + /** + * set the 'listStyleImage' property + */ + virtual void setListStyleImage(const DOMString &val) + throw (dom::DOMException) + { + listStyleImage = val; + } + + /** + * return the 'listStylePosition' property + */ + virtual DOMString getListStylePosition() + { + return listStylePosition; + } + + /** + * set the 'listStylePosition' property + */ + virtual void setListStylePosition(const DOMString &val) + throw (dom::DOMException) + { + listStylePosition = val; + } + + /** + * return the 'listStyleType' property + */ + virtual DOMString getListStyleType() + { + return listStyleType; + } + + /** + * set the 'listStyleType' property + */ + virtual void setListStyleType(const DOMString &val) + throw (dom::DOMException) + { + listStyleType = val; + } + + /** + * return the 'margin' property + */ + virtual DOMString getMargin() + { + return margin; + } + + /** + * set the 'margin' property + */ + virtual void setMargin(const DOMString &val) + throw (dom::DOMException) + { + margin = val; + } + + /** + * return the 'marginTop' property + */ + virtual DOMString getMarginTop() + { + return marginTop; + } + + /** + * set the 'marginTop' property + */ + virtual void setMarginTop(const DOMString &val) + throw (dom::DOMException) + { + marginTop = val; + } + + /** + * return the 'marginRight' property + */ + virtual DOMString getMarginRight() + { + return marginRight; + } + + /** + * set the 'marginRight' property + */ + virtual void setMarginRight(const DOMString &val) + throw (dom::DOMException) + { + marginRight = val; + } + + /** + * return the 'marginBottom' property + */ + virtual DOMString getMarginBottom() + { + return marginBottom; + } + + /** + * set the 'marginBottom' property + */ + virtual void setMarginBottom(const DOMString &val) + throw (dom::DOMException) + { + marginBottom = val; + } + + /** + * return the 'marginLeft' property + */ + virtual DOMString getMarginLeft() + { + return marginLeft; + } + + /** + * set the 'marginLeft' property + */ + virtual void setMarginLeft(const DOMString &val) + throw (dom::DOMException) + { + marginLeft = val; + } + + /** + * return the 'markerOffset' property + */ + virtual DOMString getMarkerOffset() + { + return markerOffset; + } + + /** + * set the 'markerOffset' property + */ + virtual void setMarkerOffset(const DOMString &val) + throw (dom::DOMException) + { + markerOffset = val; + } + + /** + * return the 'marks' property + */ + virtual DOMString getMarks() + { + return marks; + } + + /** + * set the 'marks' property + */ + virtual void setMarks(const DOMString &val) + throw (dom::DOMException) + { + marks = val; + } + + /** + * return the 'maxHeight' property + */ + virtual DOMString getMaxHeight() + { + return maxHeight; + } + + /** + * set the 'maxHeight' property + */ + virtual void setMaxHeight(const DOMString &val) + throw (dom::DOMException) + { + maxHeight = val; + } + + /** + * return the 'maxWidth' property + */ + virtual DOMString getMaxWidth() + { + return maxWidth; + } + + /** + * set the 'maxWidth' property + */ + virtual void setMaxWidth(const DOMString &val) + throw (dom::DOMException) + { + maxWidth = val; + } + + /** + * return the 'minHeight' property + */ + virtual DOMString getMinHeight() + { + return minHeight; + } + + /** + * set the 'minHeight' property + */ + virtual void setMinHeight(const DOMString &val) + throw (dom::DOMException) + { + minHeight = val; + } + + /** + * return the 'minWidth' property + */ + virtual DOMString getMinWidth() + { + return minWidth; + } + + /** + * set the 'minWidth' property + */ + virtual void setMinWidth(const DOMString &val) + throw (dom::DOMException) + { + minWidth = val; + } + + /** + * return the 'orphans' property + */ + virtual DOMString getOrphans() + { + return orphans; + } + + /** + * set the 'orphans' property + */ + virtual void setOrphans(const DOMString &val) + throw (dom::DOMException) + { + orphans = val; + } + + /** + * return the 'outline' property + */ + virtual DOMString getOutline() + { + return outline; + } + + /** + * set the 'outline' property + */ + virtual void setOutline(const DOMString &val) + throw (dom::DOMException) + { + outline = val; + } + + /** + * return the 'outlineColor' property + */ + virtual DOMString getOutlineColor() + { + return outlineColor; + } + + /** + * set the 'outlineColor' property + */ + virtual void setOutlineColor(const DOMString &val) + throw (dom::DOMException) + { + outlineColor = val; + } + + /** + * return the 'outlineStyle' property + */ + virtual DOMString getOutlineStyle() + { + return outlineStyle; + } + + /** + * set the 'outlineStyle' property + */ + virtual void setOutlineStyle(const DOMString &val) + throw (dom::DOMException) + { + outlineStyle = val; + } + + /** + * return the 'outlineWidth' property + */ + virtual DOMString getOutlineWidth() + { + return outlineWidth; + } + + /** + * set the 'outlineWidth' property + */ + virtual void setOutlineWidth(const DOMString &val) + throw (dom::DOMException) + { + outlineWidth = val; + } + + /** + * return the 'overflow' property + */ + virtual DOMString getOverflow() + { + return overflow; + } + + /** + * set the 'overflow' property + */ + virtual void setOverflow(const DOMString &val) + throw (dom::DOMException) + { + overflow = val; + } + + /** + * return the 'padding' property + */ + virtual DOMString getPadding() + { + return padding; + } + + /** + * set the 'padding' property + */ + virtual void setPadding(const DOMString &val) + throw (dom::DOMException) + { + padding = val; + } + + /** + * return the 'paddingTop' property + */ + virtual DOMString getPaddingTop() + { + return paddingTop; + } + + /** + * set the 'paddingTop' property + */ + virtual void setPaddingTop(const DOMString &val) + throw (dom::DOMException) + { + paddingTop = val; + } + + /** + * return the 'paddingRight' property + */ + virtual DOMString getPaddingRight() + { + return paddingRight; + } + + /** + * set the 'paddingRight' property + */ + virtual void setPaddingRight(const DOMString &val) + throw (dom::DOMException) + { + paddingRight = val; + } + + /** + * return the 'paddingBottom' property + */ + virtual DOMString getPaddingBottom() + { + return paddingBottom; + } + + /** + * set the 'paddingBottom' property + */ + virtual void setPaddingBottom(const DOMString &val) + throw (dom::DOMException) + { + paddingBottom = val; + } + + /** + * return the 'paddingLeft' property + */ + virtual DOMString getPaddingLeft() + { + return paddingLeft; + } + + /** + * set the 'paddingLeft' property + */ + virtual void setPaddingLeft(const DOMString &val) + throw (dom::DOMException) + { + paddingLeft = val; + } + + /** + * return the 'page' property + */ + virtual DOMString getPage() + { + return page; + } + + /** + * set the 'page' property + */ + virtual void setPage(const DOMString &val) + throw (dom::DOMException) + { + page = val; + } + + /** + * return the 'pageBreakAfter' property + */ + virtual DOMString getPageBreakAfter() + { + return pageBreakAfter; + } + + /** + * set the 'pageBreakAfter' property + */ + virtual void setPageBreakAfter(const DOMString &val) + throw (dom::DOMException) + { + pageBreakAfter = val; + } + + /** + * return the 'pageBreakBefore' property + */ + virtual DOMString getPageBreakBefore() + { + return pageBreakBefore; + } + + /** + * set the 'pageBreakBefore' property + */ + virtual void setPageBreakBefore(const DOMString &val) + throw (dom::DOMException) + { + pageBreakBefore = val; + } + + /** + * return the 'pageBreakInside' property + */ + virtual DOMString getPageBreakInside() + { + return pageBreakInside; + } + + /** + * set the 'pageBreakInside' property + */ + virtual void setPageBreakInside(const DOMString &val) + throw (dom::DOMException) + { + pageBreakInside = val; + } + + /** + * return the 'pause' property + */ + virtual DOMString getPause() + { + return pause; + } + + /** + * set the 'pause' property + */ + virtual void setPause(const DOMString &val) + throw (dom::DOMException) + { + pause = val; + } + + /** + * return the 'pauseAfter' property + */ + virtual DOMString getPauseAfter() + { + return pauseAfter; + } + + /** + * set the 'pauseAfter' property + */ + virtual void setPauseAfter(const DOMString &val) + throw (dom::DOMException) + { + pauseAfter = val; + } + + /** + * return the 'pauseBefore' property + */ + virtual DOMString getPauseBefore() + { + return pauseBefore; + } + + /** + * set the 'pauseBefore' property + */ + virtual void setPauseBefore(const DOMString &val) + throw (dom::DOMException) + { + pauseBefore = val; + } + + /** + * return the 'pitch' property + */ + virtual DOMString getPitch() + { + return pitch; + } + + /** + * set the 'pitch' property + */ + virtual void setPitch(const DOMString &val) + throw (dom::DOMException) + { + pitch = val; + } + + /** + * return the 'pitchRange' property + */ + virtual DOMString getPitchRange() + { + return pitchRange; + } + + /** + * set the 'pitchRange' property + */ + virtual void setPitchRange(const DOMString &val) + throw (dom::DOMException) + { + pitchRange = val; + } + + /** + * return the 'playDuring' property + */ + virtual DOMString getPlayDuring() + { + return playDuring; + } + + /** + * set the 'playDuring' property + */ + virtual void setPlayDuring(const DOMString &val) + throw (dom::DOMException) + { + playDuring = val; + } + + /** + * return the 'position' property + */ + virtual DOMString getPosition() + { + return position; + } + + /** + * set the 'position' property + */ + virtual void setPosition(const DOMString &val) + throw (dom::DOMException) + { + position = val; + } + + /** + * return the 'quotes' property + */ + virtual DOMString getQuotes() + { + return quotes; + } + + /** + * set the 'quotes' property + */ + virtual void setQuotes(const DOMString &val) + throw (dom::DOMException) + { + quotes = val; + } + + /** + * return the 'richness' property + */ + virtual DOMString getRichness() + { + return richness; + } + + /** + * set the 'richness' property + */ + virtual void setRichness(const DOMString &val) + throw (dom::DOMException) + { + richness = val; + } + + /** + * return the 'right' property + */ + virtual DOMString getRight() + { + return right; + } + + /** + * set the 'right' property + */ + virtual void setRight(const DOMString &val) + throw (dom::DOMException) + { + right = val; + } + + /** + * return the 'size' property + */ + virtual DOMString getSize() + { + return size; + } + + /** + * set the 'size' property + */ + virtual void setSize(const DOMString &val) + throw (dom::DOMException) + { + size = val; + } + + /** + * return the 'speak' property + */ + virtual DOMString getSpeak() + { + return speak; + } + + /** + * set the 'speak' property + */ + virtual void setSpeak(const DOMString &val) + throw (dom::DOMException) + { + speak = val; + } + + /** + * return the 'speakHeader' property + */ + virtual DOMString getSpeakHeader() + { + return speakHeader; + } + + /** + * set the 'speakHeader' property + */ + virtual void setSpeakHeader(const DOMString &val) + throw (dom::DOMException) + { + speakHeader = val; + } + + /** + * return the 'speakNumeral' property + */ + virtual DOMString getSpeakNumeral() + { + return speakNumeral; + } + + /** + * set the 'speakNumeral' property + */ + virtual void setSpeakNumeral(const DOMString &val) + throw (dom::DOMException) + { + speakNumeral = val; + } + + /** + * return the 'speakPunctuation' property + */ + virtual DOMString getSpeakPunctuation() + { + return speakPunctuation; + } + + /** + * set the 'speakPunctuation' property + */ + virtual void setSpeakPunctuation(const DOMString &val) + throw (dom::DOMException) + { + speakPunctuation = val; + } + + /** + * return the 'speechRate' property + */ + virtual DOMString getSpeechRate() + { + return speechRate; + } + + /** + * set the 'speechRate' property + */ + virtual void setSpeechRate(const DOMString &val) + throw (dom::DOMException) + { + speechRate = val; + } + + /** + * return the 'stress' property + */ + virtual DOMString getStress() + { + return stress; + } + + /** + * set the 'stress' property + */ + virtual void setStress(const DOMString &val) + throw (dom::DOMException) + { + stress = val; + } + + /** + * return the 'tableLayout' property + */ + virtual DOMString getTableLayout() + { + return tableLayout; + } + + /** + * set the 'tableLayout' property + */ + virtual void setTableLayout(const DOMString &val) + throw (dom::DOMException) + { + tableLayout = val; + } + + /** + * return the 'textAlign' property + */ + virtual DOMString getTextAlign() + { + return textAlign; + } + + /** + * set the 'textAlign' property + */ + virtual void setTextAlign(const DOMString &val) + throw (dom::DOMException) + { + textAlign = val; + } + + /** + * return the 'textDecoration' property + */ + virtual DOMString getTextDecoration() + { + return textDecoration; + } + + /** + * set the 'textDecoration' property + */ + virtual void setTextDecoration(const DOMString &val) + throw (dom::DOMException) + { + textDecoration = val; + } + + /** + * return the 'textIndent' property + */ + virtual DOMString getTextIndent() + { + return textIndent; + } + + /** + * set the 'textIndent' property + */ + virtual void setTextIndent(const DOMString &val) + throw (dom::DOMException) + { + textIndent = val; + } + + /** + * return the 'textShadow' property + */ + virtual DOMString getTextShadow() + { + return textShadow; + } + + /** + * set the 'textShadow' property + */ + virtual void setTextShadow(const DOMString &val) + throw (dom::DOMException) + { + textShadow = val; + } + + /** + * return the 'textTransform' property + */ + virtual DOMString getTextTransform() + { + return textTransform; + } + + /** + * set the 'textTransform' property + */ + virtual void setTextTransform(const DOMString &val) + throw (dom::DOMException) + { + textTransform = val; + } + + /** + * return the 'top' property + */ + virtual DOMString getTop() + { + return top; + } + + /** + * set the 'top' property + */ + virtual void setTop(const DOMString &val) + throw (dom::DOMException) + { + top = val; + } + + /** + * return the 'unicodeBidi' property + */ + virtual DOMString getUnicodeBidi() + { + return unicodeBidi; + } + + /** + * set the 'unicodeBidi' property + */ + virtual void setUnicodeBidi(const DOMString &val) + throw (dom::DOMException) + { + unicodeBidi = val; + } + + /** + * return the 'verticalAlign' property + */ + virtual DOMString getVerticalAlign() + { + return verticalAlign; + } + + /** + * set the 'verticalAlign' property + */ + virtual void setVerticalAlign(const DOMString &val) + throw (dom::DOMException) + { + verticalAlign = val; + } + + /** + * return the 'visibility' property + */ + virtual DOMString getVisibility() + { + return visibility; + } + + /** + * set the 'visibility' property + */ + virtual void setVisibility(const DOMString &val) + throw (dom::DOMException) + { + visibility = val; + } + + /** + * return the 'voiceFamily' property + */ + virtual DOMString getVoiceFamily() + { + return voiceFamily; + } + + /** + * set the 'voiceFamily' property + */ + virtual void setVoiceFamily(const DOMString &val) + throw (dom::DOMException) + { + voiceFamily = val; + } + + /** + * return the 'volume' property + */ + virtual DOMString getVolume() + { + return volume; + } + + /** + * set the 'volume' property + */ + virtual void setVolume(const DOMString &val) + throw (dom::DOMException) + { + volume = val; + } + + /** + * return the 'whiteSpace' property + */ + virtual DOMString getWhiteSpace() + { + return whiteSpace; + } + + /** + * set the 'whiteSpace' property + */ + virtual void setWhiteSpace(const DOMString &val) + throw (dom::DOMException) + { + whiteSpace = val; + } + + /** + * return the 'widows' property + */ + virtual DOMString getWidows() + { + return widows; + } + + /** + * set the 'widows' property + */ + virtual void setWidows(const DOMString &val) + throw (dom::DOMException) + { + widows = val; + } + + /** + * return the 'width' property + */ + virtual DOMString getWidth() + { + return width; + } + + /** + * set the 'width' property + */ + virtual void setWidth(const DOMString &val) + throw (dom::DOMException) + { + width = val; + } + + /** + * return the 'wordSpacing' property + */ + virtual DOMString getWordSpacing() + { + return wordSpacing; + } + + /** + * set the 'wordSpacing' property + */ + virtual void setWordSpacing(const DOMString &val) + throw (dom::DOMException) + { + wordSpacing = val; + } + + /** + * return the 'zIndex' property + */ + virtual DOMString getZIndex() + { + return zIndex; + } + + /** + * set the 'zIndex' property + */ + virtual void setZIndex(const DOMString &val) + throw (dom::DOMException) + { + zIndex = val; + } + + + + //################## + //# Non-API methods + //################## + + /** + * + */ + CSS2Properties() + { + } + + /** + * + */ + CSS2Properties(const CSS2Properties &other) + { + azimuth = other.azimuth; + background = other.background; + backgroundAttachment = other.backgroundAttachment; + backgroundColor = other.backgroundColor; + backgroundImage = other.backgroundImage; + backgroundPosition = other.backgroundPosition; + backgroundRepeat = other.backgroundRepeat; + border = other.border; + borderCollapse = other.borderCollapse; + borderColor = other.borderColor; + borderSpacing = other.borderSpacing; + borderStyle = other.borderStyle; + borderTop = other.borderTop; + borderRight = other.borderRight; + borderBottom = other.borderBottom; + borderLeft = other.borderLeft; + borderTopColor = other.borderTopColor; + borderRightColor = other.borderRightColor; + borderBottomColor = other.borderBottomColor; + borderLeftColor = other.borderLeftColor; + borderTopStyle = other.borderTopStyle; + borderRightStyle = other.borderRightStyle; + borderBottomStyle = other.borderBottomStyle; + borderLeftStyle = other.borderLeftStyle; + borderTopWidth = other.borderTopWidth; + borderRightWidth = other.borderRightWidth; + borderBottomWidth = other.borderBottomWidth; + borderLeftWidth = other.borderLeftWidth; + borderWidth = other.borderWidth; + bottom = other.bottom; + captionSide = other.captionSide; + clear = other.clear; + clip = other.clip; + color = other.color; + content = other.content; + counterIncrement = other.counterIncrement; + counterReset = other.counterReset; + cue = other.cue; + cueAfter = other.cueAfter; + cueBefore = other.cueBefore; + cursor = other.cursor; + direction = other.direction; + display = other.display; + elevation = other.elevation; + emptyCells = other.emptyCells; + cssFloat = other.cssFloat; + font = other.font; + fontFamily = other.fontFamily; + fontSize = other.fontSize; + fontSizeAdjust = other.fontSizeAdjust; + fontStretch = other.fontStretch; + fontStyle = other.fontStyle; + fontVariant = other.fontVariant; + fontWeight = other.fontWeight; + height = other.height; + left = other.left; + letterSpacing = other.letterSpacing; + lineHeight = other.lineHeight; + listStyle = other.listStyle; + listStyleImage = other.listStyleImage; + listStylePosition = other.listStylePosition; + listStyleType = other.listStyleType; + margin = other.margin; + marginTop = other.marginTop; + marginRight = other.marginRight; + marginBottom = other.marginBottom; + marginLeft = other.marginLeft; + markerOffset = other.markerOffset; + marks = other.marks; + maxHeight = other.maxHeight; + maxWidth = other.maxWidth; + minHeight = other.minHeight; + minWidth = other.minWidth; + orphans = other.orphans; + outline = other.outline; + outlineColor = other.outlineColor; + outlineStyle = other.outlineStyle; + outlineWidth = other.outlineWidth; + overflow = other.overflow; + padding = other.padding; + paddingTop = other.paddingTop; + paddingRight = other.paddingRight; + paddingBottom = other.paddingBottom; + paddingLeft = other.paddingLeft; + page = other.page; + pageBreakAfter = other.pageBreakAfter; + pageBreakBefore = other.pageBreakBefore; + pageBreakInside = other.pageBreakInside; + pause = other.pause; + pauseAfter = other.pauseAfter; + pauseBefore = other.pauseBefore; + pitch = other.pitch; + pitchRange = other.pitchRange; + playDuring = other.playDuring; + position = other.position; + quotes = other.quotes; + richness = other.richness; + right = other.right; + size = other.size; + speak = other.speak; + speakHeader = other.speakHeader; + speakNumeral = other.speakNumeral; + speakPunctuation = other.speakPunctuation; + speechRate = other.speechRate; + stress = other.stress; + tableLayout = other.tableLayout; + textAlign = other.textAlign; + textDecoration = other.textDecoration; + textIndent = other.textIndent; + textShadow = other.textShadow; + textTransform = other.textTransform; + top = other.top; + unicodeBidi = other.unicodeBidi; + verticalAlign = other.verticalAlign; + visibility = other.visibility; + voiceFamily = other.voiceFamily; + volume = other.volume; + whiteSpace = other.whiteSpace; + widows = other.widows; + width = other.width; + wordSpacing = other.wordSpacing; + zIndex = other.zIndex; + } + + /** + * + */ + virtual ~CSS2Properties() {} + +protected: + + //###################### + //# P R O P E R T I E S + //###################### + DOMString azimuth; + DOMString background; + DOMString backgroundAttachment; + DOMString backgroundColor; + DOMString backgroundImage; + DOMString backgroundPosition; + DOMString backgroundRepeat; + DOMString border; + DOMString borderCollapse; + DOMString borderColor; + DOMString borderSpacing; + DOMString borderStyle; + DOMString borderTop; + DOMString borderRight; + DOMString borderBottom; + DOMString borderLeft; + DOMString borderTopColor; + DOMString borderRightColor; + DOMString borderBottomColor; + DOMString borderLeftColor; + DOMString borderTopStyle; + DOMString borderRightStyle; + DOMString borderBottomStyle; + DOMString borderLeftStyle; + DOMString borderTopWidth; + DOMString borderRightWidth; + DOMString borderBottomWidth; + DOMString borderLeftWidth; + DOMString borderWidth; + DOMString bottom; + DOMString captionSide; + DOMString clear; + DOMString clip; + DOMString color; + DOMString content; + DOMString counterIncrement; + DOMString counterReset; + DOMString cue; + DOMString cueAfter; + DOMString cueBefore; + DOMString cursor; + DOMString direction; + DOMString display; + DOMString elevation; + DOMString emptyCells; + DOMString cssFloat; + DOMString font; + DOMString fontFamily; + DOMString fontSize; + DOMString fontSizeAdjust; + DOMString fontStretch; + DOMString fontStyle; + DOMString fontVariant; + DOMString fontWeight; + DOMString height; + DOMString left; + DOMString letterSpacing; + DOMString lineHeight; + DOMString listStyle; + DOMString listStyleImage; + DOMString listStylePosition; + DOMString listStyleType; + DOMString margin; + DOMString marginTop; + DOMString marginRight; + DOMString marginBottom; + DOMString marginLeft; + DOMString markerOffset; + DOMString marks; + DOMString maxHeight; + DOMString maxWidth; + DOMString minHeight; + DOMString minWidth; + DOMString orphans; + DOMString outline; + DOMString outlineColor; + DOMString outlineStyle; + DOMString outlineWidth; + DOMString overflow; + DOMString padding; + DOMString paddingTop; + DOMString paddingRight; + DOMString paddingBottom; + DOMString paddingLeft; + DOMString page; + DOMString pageBreakAfter; + DOMString pageBreakBefore; + DOMString pageBreakInside; + DOMString pause; + DOMString pauseAfter; + DOMString pauseBefore; + DOMString pitch; + DOMString pitchRange; + DOMString playDuring; + DOMString position; + DOMString quotes; + DOMString richness; + DOMString right; + DOMString size; + DOMString speak; + DOMString speakHeader; + DOMString speakNumeral; + DOMString speakPunctuation; + DOMString speechRate; + DOMString stress; + DOMString tableLayout; + DOMString textAlign; + DOMString textDecoration; + DOMString textIndent; + DOMString textShadow; + DOMString textTransform; + DOMString top; + DOMString unicodeBidi; + DOMString verticalAlign; + DOMString visibility; + DOMString voiceFamily; + DOMString volume; + DOMString whiteSpace; + DOMString widows; + DOMString width; + DOMString wordSpacing; + DOMString zIndex; + + +}; + + + + + + + + +/*######################################################################### +## ViewCSS +#########################################################################*/ + +/** + * again, a mismatch with views::View and views::AbstractView + */ +class ViewCSS : virtual public views::View +{ +public: + + /** + * + */ + virtual CSSStyleDeclaration getComputedStyle(const Element &elt, + const DOMString &pseudoElt) + { + CSSStyleDeclaration style; + return style; + } + + //################## + //# Non-API methods + //################## + + /** + * + */ + ViewCSS() : views::View() + { + } + + /** + * + */ + ViewCSS(const ViewCSS &other) : views::View(other) + { + } + + /** + * + */ + virtual ~ViewCSS() {} +}; + + + + + +/*######################################################################### +## DocumentCSS +#########################################################################*/ + +/** + * + */ +class DocumentCSS : virtual public stylesheets::DocumentStyle +{ +public: + + /** + * + */ + virtual CSSStyleDeclaration getOverrideStyle(const Element *elt, + const DOMString &pseudoElt) + { + CSSStyleDeclaration style; + return style; + } + + //################## + //# Non-API methods + //################## + + /** + * + */ + DocumentCSS() : stylesheets::DocumentStyle() + { + } + + /** + * + */ + DocumentCSS(const DocumentCSS &other) : stylesheets::DocumentStyle(other) + { + } + + /** + * + */ + virtual ~DocumentCSS() {} +}; + + + + + + +/*######################################################################### +## DOMImplementationCSS +#########################################################################*/ + +/** + * + */ +class DOMImplementationCSS : virtual public DOMImplementation +{ +public: + + /** + * + */ + virtual CSSStyleSheet createCSSStyleSheet(const DOMString &title, + const DOMString &media) + throw (dom::DOMException) + { + CSSStyleSheet sheet; + return sheet; + } + + //################## + //# Non-API methods + //################## + + /** + * + */ + DOMImplementationCSS() {} + + /** + * + */ + DOMImplementationCSS(const DOMImplementationCSS &other) + : DOMImplementation(other) + { + } + + /** + * + */ + virtual ~DOMImplementationCSS() {} +}; + + + + + + + + +} //namespace css +} //namespace dom +} //namespace org +} //namespace w3c + + +#endif // __CSS_H__ + +/*######################################################################### +## E N D O F F I L E +#########################################################################*/ diff --git a/src/dom/css.idl b/src/dom/css.idl new file mode 100755 index 000000000..5033f901c --- /dev/null +++ b/src/dom/css.idl @@ -0,0 +1,633 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program is distributed in the + * hope that it will be useful, but WITHOUT ANY WARRANTY; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. + * See W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +// File: http://www.w3.org/TR/2000/REC-DOM-Level-2-Style-20001113/css.idl + +#ifndef _CSS_IDL_ +#define _CSS_IDL_ + +#include "dom.idl" +#include "stylesheets.idl" +#include "views.idl" + +#pragma prefix "dom.w3c.org" +module css +{ + + typedef dom::DOMString DOMString; + typedef dom::Element Element; + typedef dom::DOMImplementation DOMImplementation; + + interface CSSRule; + interface CSSStyleSheet; + interface CSSStyleDeclaration; + interface CSSValue; + interface Counter; + interface Rect; + interface RGBColor; + + // Introduced in DOM Level 2: + interface CSSRuleList { + readonly attribute unsigned long length; + CSSRule item(in unsigned long index); + }; + + // Introduced in DOM Level 2: + interface CSSRule { + + // RuleType + const unsigned short UNKNOWN_RULE = 0; + const unsigned short STYLE_RULE = 1; + const unsigned short CHARSET_RULE = 2; + const unsigned short IMPORT_RULE = 3; + const unsigned short MEDIA_RULE = 4; + const unsigned short FONT_FACE_RULE = 5; + const unsigned short PAGE_RULE = 6; + + readonly attribute unsigned short type; + attribute DOMString cssText; + // raises(dom::DOMException) on setting + + readonly attribute CSSStyleSheet parentStyleSheet; + readonly attribute CSSRule parentRule; + }; + + // Introduced in DOM Level 2: + interface CSSStyleRule : CSSRule { + attribute DOMString selectorText; + // raises(dom::DOMException) on setting + + readonly attribute CSSStyleDeclaration style; + }; + + // Introduced in DOM Level 2: + interface CSSMediaRule : CSSRule { + readonly attribute stylesheets::MediaList media; + readonly attribute CSSRuleList cssRules; + unsigned long insertRule(in DOMString rule, + in unsigned long index) + raises(dom::DOMException); + void deleteRule(in unsigned long index) + raises(dom::DOMException); + }; + + // Introduced in DOM Level 2: + interface CSSFontFaceRule : CSSRule { + readonly attribute CSSStyleDeclaration style; + }; + + // Introduced in DOM Level 2: + interface CSSPageRule : CSSRule { + attribute DOMString selectorText; + // raises(dom::DOMException) on setting + + readonly attribute CSSStyleDeclaration style; + }; + + // Introduced in DOM Level 2: + interface CSSImportRule : CSSRule { + readonly attribute DOMString href; + readonly attribute stylesheets::MediaList media; + readonly attribute CSSStyleSheet styleSheet; + }; + + // Introduced in DOM Level 2: + interface CSSCharsetRule : CSSRule { + attribute DOMString encoding; + // raises(dom::DOMException) on setting + + }; + + // Introduced in DOM Level 2: + interface CSSUnknownRule : CSSRule { + }; + + // Introduced in DOM Level 2: + interface CSSStyleDeclaration { + attribute DOMString cssText; + // raises(dom::DOMException) on setting + + DOMString getPropertyValue(in DOMString propertyName); + CSSValue getPropertyCSSValue(in DOMString propertyName); + DOMString removeProperty(in DOMString propertyName) + raises(dom::DOMException); + DOMString getPropertyPriority(in DOMString propertyName); + void setProperty(in DOMString propertyName, + in DOMString value, + in DOMString priority) + raises(dom::DOMException); + readonly attribute unsigned long length; + DOMString item(in unsigned long index); + readonly attribute CSSRule parentRule; + }; + + // Introduced in DOM Level 2: + interface CSSValue { + + // UnitTypes + const unsigned short CSS_INHERIT = 0; + const unsigned short CSS_PRIMITIVE_VALUE = 1; + const unsigned short CSS_VALUE_LIST = 2; + const unsigned short CSS_CUSTOM = 3; + + attribute DOMString cssText; + // raises(dom::DOMException) on setting + + readonly attribute unsigned short cssValueType; + }; + + // Introduced in DOM Level 2: + interface CSSPrimitiveValue : CSSValue { + + // UnitTypes + const unsigned short CSS_UNKNOWN = 0; + const unsigned short CSS_NUMBER = 1; + const unsigned short CSS_PERCENTAGE = 2; + const unsigned short CSS_EMS = 3; + const unsigned short CSS_EXS = 4; + const unsigned short CSS_PX = 5; + const unsigned short CSS_CM = 6; + const unsigned short CSS_MM = 7; + const unsigned short CSS_IN = 8; + const unsigned short CSS_PT = 9; + const unsigned short CSS_PC = 10; + const unsigned short CSS_DEG = 11; + const unsigned short CSS_RAD = 12; + const unsigned short CSS_GRAD = 13; + const unsigned short CSS_MS = 14; + const unsigned short CSS_S = 15; + const unsigned short CSS_HZ = 16; + const unsigned short CSS_KHZ = 17; + const unsigned short CSS_DIMENSION = 18; + const unsigned short CSS_STRING = 19; + const unsigned short CSS_URI = 20; + const unsigned short CSS_IDENT = 21; + const unsigned short CSS_ATTR = 22; + const unsigned short CSS_COUNTER = 23; + const unsigned short CSS_RECT = 24; + const unsigned short CSS_RGBCOLOR = 25; + + readonly attribute unsigned short primitiveType; + void setFloatValue(in unsigned short unitType, + in float floatValue) + raises(dom::DOMException); + float getFloatValue(in unsigned short unitType) + raises(dom::DOMException); + void setStringValue(in unsigned short stringType, + in DOMString stringValue) + raises(dom::DOMException); + DOMString getStringValue() + raises(dom::DOMException); + Counter getCounterValue() + raises(dom::DOMException); + Rect getRectValue() + raises(dom::DOMException); + RGBColor getRGBColorValue() + raises(dom::DOMException); + }; + + // Introduced in DOM Level 2: + interface CSSValueList : CSSValue { + readonly attribute unsigned long length; + CSSValue item(in unsigned long index); + }; + + // Introduced in DOM Level 2: + interface RGBColor { + readonly attribute CSSPrimitiveValue red; + readonly attribute CSSPrimitiveValue green; + readonly attribute CSSPrimitiveValue blue; + }; + + // Introduced in DOM Level 2: + interface Rect { + readonly attribute CSSPrimitiveValue top; + readonly attribute CSSPrimitiveValue right; + readonly attribute CSSPrimitiveValue bottom; + readonly attribute CSSPrimitiveValue left; + }; + + // Introduced in DOM Level 2: + interface Counter { + readonly attribute DOMString identifier; + readonly attribute DOMString listStyle; + readonly attribute DOMString separator; + }; + + // Introduced in DOM Level 2: + interface ElementCSSInlineStyle { + readonly attribute CSSStyleDeclaration style; + }; + + // Introduced in DOM Level 2: + interface CSS2Properties { + attribute DOMString azimuth; + // raises(dom::DOMException) on setting + + attribute DOMString background; + // raises(dom::DOMException) on setting + + attribute DOMString backgroundAttachment; + // raises(dom::DOMException) on setting + + attribute DOMString backgroundColor; + // raises(dom::DOMException) on setting + + attribute DOMString backgroundImage; + // raises(dom::DOMException) on setting + + attribute DOMString backgroundPosition; + // raises(dom::DOMException) on setting + + attribute DOMString backgroundRepeat; + // raises(dom::DOMException) on setting + + attribute DOMString border; + // raises(dom::DOMException) on setting + + attribute DOMString borderCollapse; + // raises(dom::DOMException) on setting + + attribute DOMString borderColor; + // raises(dom::DOMException) on setting + + attribute DOMString borderSpacing; + // raises(dom::DOMException) on setting + + attribute DOMString borderStyle; + // raises(dom::DOMException) on setting + + attribute DOMString borderTop; + // raises(dom::DOMException) on setting + + attribute DOMString borderRight; + // raises(dom::DOMException) on setting + + attribute DOMString borderBottom; + // raises(dom::DOMException) on setting + + attribute DOMString borderLeft; + // raises(dom::DOMException) on setting + + attribute DOMString borderTopColor; + // raises(dom::DOMException) on setting + + attribute DOMString borderRightColor; + // raises(dom::DOMException) on setting + + attribute DOMString borderBottomColor; + // raises(dom::DOMException) on setting + + attribute DOMString borderLeftColor; + // raises(dom::DOMException) on setting + + attribute DOMString borderTopStyle; + // raises(dom::DOMException) on setting + + attribute DOMString borderRightStyle; + // raises(dom::DOMException) on setting + + attribute DOMString borderBottomStyle; + // raises(dom::DOMException) on setting + + attribute DOMString borderLeftStyle; + // raises(dom::DOMException) on setting + + attribute DOMString borderTopWidth; + // raises(dom::DOMException) on setting + + attribute DOMString borderRightWidth; + // raises(dom::DOMException) on setting + + attribute DOMString borderBottomWidth; + // raises(dom::DOMException) on setting + + attribute DOMString borderLeftWidth; + // raises(dom::DOMException) on setting + + attribute DOMString borderWidth; + // raises(dom::DOMException) on setting + + attribute DOMString bottom; + // raises(dom::DOMException) on setting + + attribute DOMString captionSide; + // raises(dom::DOMException) on setting + + attribute DOMString clear; + // raises(dom::DOMException) on setting + + attribute DOMString clip; + // raises(dom::DOMException) on setting + + attribute DOMString color; + // raises(dom::DOMException) on setting + + attribute DOMString content; + // raises(dom::DOMException) on setting + + attribute DOMString counterIncrement; + // raises(dom::DOMException) on setting + + attribute DOMString counterReset; + // raises(dom::DOMException) on setting + + attribute DOMString cue; + // raises(dom::DOMException) on setting + + attribute DOMString cueAfter; + // raises(dom::DOMException) on setting + + attribute DOMString cueBefore; + // raises(dom::DOMException) on setting + + attribute DOMString cursor; + // raises(dom::DOMException) on setting + + attribute DOMString direction; + // raises(dom::DOMException) on setting + + attribute DOMString display; + // raises(dom::DOMException) on setting + + attribute DOMString elevation; + // raises(dom::DOMException) on setting + + attribute DOMString emptyCells; + // raises(dom::DOMException) on setting + + attribute DOMString cssFloat; + // raises(dom::DOMException) on setting + + attribute DOMString font; + // raises(dom::DOMException) on setting + + attribute DOMString fontFamily; + // raises(dom::DOMException) on setting + + attribute DOMString fontSize; + // raises(dom::DOMException) on setting + + attribute DOMString fontSizeAdjust; + // raises(dom::DOMException) on setting + + attribute DOMString fontStretch; + // raises(dom::DOMException) on setting + + attribute DOMString fontStyle; + // raises(dom::DOMException) on setting + + attribute DOMString fontVariant; + // raises(dom::DOMException) on setting + + attribute DOMString fontWeight; + // raises(dom::DOMException) on setting + + attribute DOMString height; + // raises(dom::DOMException) on setting + + attribute DOMString left; + // raises(dom::DOMException) on setting + + attribute DOMString letterSpacing; + // raises(dom::DOMException) on setting + + attribute DOMString lineHeight; + // raises(dom::DOMException) on setting + + attribute DOMString listStyle; + // raises(dom::DOMException) on setting + + attribute DOMString listStyleImage; + // raises(dom::DOMException) on setting + + attribute DOMString listStylePosition; + // raises(dom::DOMException) on setting + + attribute DOMString listStyleType; + // raises(dom::DOMException) on setting + + attribute DOMString margin; + // raises(dom::DOMException) on setting + + attribute DOMString marginTop; + // raises(dom::DOMException) on setting + + attribute DOMString marginRight; + // raises(dom::DOMException) on setting + + attribute DOMString marginBottom; + // raises(dom::DOMException) on setting + + attribute DOMString marginLeft; + // raises(dom::DOMException) on setting + + attribute DOMString markerOffset; + // raises(dom::DOMException) on setting + + attribute DOMString marks; + // raises(dom::DOMException) on setting + + attribute DOMString maxHeight; + // raises(dom::DOMException) on setting + + attribute DOMString maxWidth; + // raises(dom::DOMException) on setting + + attribute DOMString minHeight; + // raises(dom::DOMException) on setting + + attribute DOMString minWidth; + // raises(dom::DOMException) on setting + + attribute DOMString orphans; + // raises(dom::DOMException) on setting + + attribute DOMString outline; + // raises(dom::DOMException) on setting + + attribute DOMString outlineColor; + // raises(dom::DOMException) on setting + + attribute DOMString outlineStyle; + // raises(dom::DOMException) on setting + + attribute DOMString outlineWidth; + // raises(dom::DOMException) on setting + + attribute DOMString overflow; + // raises(dom::DOMException) on setting + + attribute DOMString padding; + // raises(dom::DOMException) on setting + + attribute DOMString paddingTop; + // raises(dom::DOMException) on setting + + attribute DOMString paddingRight; + // raises(dom::DOMException) on setting + + attribute DOMString paddingBottom; + // raises(dom::DOMException) on setting + + attribute DOMString paddingLeft; + // raises(dom::DOMException) on setting + + attribute DOMString page; + // raises(dom::DOMException) on setting + + attribute DOMString pageBreakAfter; + // raises(dom::DOMException) on setting + + attribute DOMString pageBreakBefore; + // raises(dom::DOMException) on setting + + attribute DOMString pageBreakInside; + // raises(dom::DOMException) on setting + + attribute DOMString pause; + // raises(dom::DOMException) on setting + + attribute DOMString pauseAfter; + // raises(dom::DOMException) on setting + + attribute DOMString pauseBefore; + // raises(dom::DOMException) on setting + + attribute DOMString pitch; + // raises(dom::DOMException) on setting + + attribute DOMString pitchRange; + // raises(dom::DOMException) on setting + + attribute DOMString playDuring; + // raises(dom::DOMException) on setting + + attribute DOMString position; + // raises(dom::DOMException) on setting + + attribute DOMString quotes; + // raises(dom::DOMException) on setting + + attribute DOMString richness; + // raises(dom::DOMException) on setting + + attribute DOMString right; + // raises(dom::DOMException) on setting + + attribute DOMString size; + // raises(dom::DOMException) on setting + + attribute DOMString speak; + // raises(dom::DOMException) on setting + + attribute DOMString speakHeader; + // raises(dom::DOMException) on setting + + attribute DOMString speakNumeral; + // raises(dom::DOMException) on setting + + attribute DOMString speakPunctuation; + // raises(dom::DOMException) on setting + + attribute DOMString speechRate; + // raises(dom::DOMException) on setting + + attribute DOMString stress; + // raises(dom::DOMException) on setting + + attribute DOMString tableLayout; + // raises(dom::DOMException) on setting + + attribute DOMString textAlign; + // raises(dom::DOMException) on setting + + attribute DOMString textDecoration; + // raises(dom::DOMException) on setting + + attribute DOMString textIndent; + // raises(dom::DOMException) on setting + + attribute DOMString textShadow; + // raises(dom::DOMException) on setting + + attribute DOMString textTransform; + // raises(dom::DOMException) on setting + + attribute DOMString top; + // raises(dom::DOMException) on setting + + attribute DOMString unicodeBidi; + // raises(dom::DOMException) on setting + + attribute DOMString verticalAlign; + // raises(dom::DOMException) on setting + + attribute DOMString visibility; + // raises(dom::DOMException) on setting + + attribute DOMString voiceFamily; + // raises(dom::DOMException) on setting + + attribute DOMString volume; + // raises(dom::DOMException) on setting + + attribute DOMString whiteSpace; + // raises(dom::DOMException) on setting + + attribute DOMString widows; + // raises(dom::DOMException) on setting + + attribute DOMString width; + // raises(dom::DOMException) on setting + + attribute DOMString wordSpacing; + // raises(dom::DOMException) on setting + + attribute DOMString zIndex; + // raises(dom::DOMException) on setting + + }; + + // Introduced in DOM Level 2: + interface CSSStyleSheet : stylesheets::StyleSheet { + readonly attribute CSSRule ownerRule; + readonly attribute CSSRuleList cssRules; + unsigned long insertRule(in DOMString rule, + in unsigned long index) + raises(dom::DOMException); + void deleteRule(in unsigned long index) + raises(dom::DOMException); + }; + + // Introduced in DOM Level 2: + interface ViewCSS : views::AbstractView { + CSSStyleDeclaration getComputedStyle(in Element elt, + in DOMString pseudoElt); + }; + + // Introduced in DOM Level 2: + interface DocumentCSS : stylesheets::DocumentStyle { + CSSStyleDeclaration getOverrideStyle(in Element elt, + in DOMString pseudoElt); + }; + + // Introduced in DOM Level 2: + interface DOMImplementationCSS : DOMImplementation { + CSSStyleSheet createCSSStyleSheet(in DOMString title, + in DOMString media) + raises(dom::DOMException); + }; +}; + +#endif // _CSS_IDL_ + diff --git a/src/dom/cssparser.cpp b/src/dom/cssparser.cpp new file mode 100755 index 000000000..8f3b201ee --- /dev/null +++ b/src/dom/cssparser.cpp @@ -0,0 +1,1669 @@ +/** + * Phoebe DOM Implementation. + * + * This is a C++ approximation of the W3C DOM model, which follows + * fairly closely the specifications in the various .idl files, copies of + * which are provided for reference. Most important is this one: + * + * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/idl-definitions.html + * + * Authors: + * Bob Jamison + * + * Copyright (C) 2005 Bob Jamison + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "cssparser.h" +#include "charclass.h" + +#include + +namespace org +{ +namespace w3c +{ +namespace dom +{ +namespace css +{ + +//######################################################################### +//# M E S S A G E S +//######################################################################### + +/** + * Get the column and row number of the given character position + */ +void CssParser::getColumnAndRow(int p, int &colResult, int &rowResult, int &lastNL) +{ + int col = 1; + int row = 1; + int lastnl = 0; + + for (int i=0 ; i

+ +

+

= parselen) + return 0; + XMLCh ch = parsebuf[p]; + //printf("%c", ch); + lastPosition = p; + return ch; +} + + + +/** + * Test if the given substring exists at the given position + * in parsebuf. Use get() in case of out-of-bounds + */ +bool CssParser::match(int pos, char *str) +{ + while (*str) + { + if (get(pos++) != *str++) + return false; + } + return true; +} + +/** + * + */ +int CssParser::skipwhite(int p) +{ + while (p < parselen) + { + //# XML COMMENT + if (match(p, "")) + { + p+=3; + done=true; + break; + } + p++; + } + lastPosition = p; + if (!done) + { + error("unterminated comment"); + return -1; + } + } + //# C comment + else if (match(p, "/*")) + { + p+=2; + bool done=false; + while (p'9') + break; + str.push_back(ch); + p++; + } + if (get(p) == '.' && get(p+1)>='0' && get(p+1)<='9') + { + p++; + str.push_back('.'); + while (p < parselen) + { + XMLCh ch = get(p); + if (ch<'0' || ch>'9') + break; + str.push_back(ch); + p++; + } + } + if (p>p0) + { + char *start = (char *)str.c_str(); + char *end = NULL; + double val = strtod(start, &end); + if (end > start) + { + result = val; + return p; + } + } + + //not a number + return p0; +} + + + +/** + * Assume that we are starting on a quote. Ends on the char + * after the final '"' + */ +int CssParser::getQuoted(int p0, DOMString &result) +{ + + int p = p0; + + XMLCh quoteChar = get(p); + if (quoteChar != '"' && quoteChar != '\'') + return p0; + + p++; + + DOMString buf; + + bool done = false; + while (pp) + { + p = p2; + continue; + } + + //Media + p2 = getMedia(p); + if (p2<0) + { + return -1; + } + if (p2>p) + { + p = p2; + continue; + } + + //Page + p2 = getPage(p); + if (p2<0) + { + return -1; + } + if (p2>p) + { + p = p2; + continue; + } + + //none of the above + break; + } + + return p; +} + +/** + * import + * : IMPORT_SYM S* + * [STRING|URI] S* [ medium [ COMMA S* medium]* ]? ';' S* + * ; + */ +int CssParser::getImport(int p0) +{ + int p = p0; + if (!match(p, "@import")) + return p0; + p+=7; + p = skipwhite(p); + + //# STRING | URI + DOMString str; + int p2 = getQuoted(p, str); + if (p2<0) + { + return -1; + } + if (p2<=p) + { + p2 = getUri(p, str); + if (p2<0) + { + return -1; + } + if (p2<=p) + { + error("quoted string or URI required after @import"); + return -1; + } + } + p = p2; + p2 = getMedium(p); + if (p2<0) + return -1; + + p = p2; + p = skipwhite(p); + XMLCh ch = get(p); + if (ch != ';') + { + error("@import must be terminated with ';'"); + return -1; + } + p++; + return p; +} + +/** + * media + * : MEDIA_SYM S* medium [ COMMA S* medium ]* LBRACE S* ruleset* '}' S* + * ; + */ +int CssParser::getMedia(int p0) +{ + int p = p0; + XMLCh ch; + if (!match(p, "@media")) + return p0; + p+=6; + p = skipwhite(p); + + //# MEDIUM LIST + int p2 = getMedium(p); + if (p2<0) + return -1; + if (p2<=p) + { + error("@media must be followed by medium"); + return -1; + } + p = p2; + while (true) + { + ch = get(p); + if (ch != ',') + break; + p2 = getMedium(p); + if (p2<0) + return -1; + if (p2<=p) + { + error("',' in medium list must be followed by medium"); + return -1; + } + p = p2; + } + + p = skipwhite(p); + ch = get(p); + if (ch!='{') + { + error("@media requires '{' for ruleset"); + return -1; + } + p++; + p2 = getRuleSet(p); + if (p2<0) + return -1; + if (p2<=p) + { + error("@media requires ruleset after '{'"); + return -1; + } + p = p2; + ch = get(p); + if (ch != '}') + { + error("@media requires '}' after ruleset"); + return -1; + } + p++; + return p0; +} + +/** + * medium + * : IDENT S* + * ; + */ +int CssParser::getMedium(int p0) +{ + int p = p0; + p = skipwhite(p); + + DOMString ident; + int p2 = getWord(p, ident); + if (p2<0) + return -1; + if (p2<=p) + return p0; + p = p2; + + return p; +} + +/** + * page + * : PAGE_SYM S* pseudo_page? S* + * LBRACE S* declaration [ ';' S* declaration ]* '}' S* + * ; + */ +int CssParser::getPage(int p0) +{ + int p = p0; + + //# @PAGE + p = skipwhite(p); + if (!match(p, "@page")) + return p0; + p+= 5; + + //#PSEUDO PAGE 0 or 1 + p = skipwhite(p); + int p2 = getPseudoPage(p); + if (p2<0) + return -1; + if (p2>p) + { + p = p2; + } + + //# { + p=skipwhite(p); + XMLCh ch = get(p); + if (p != '{') + { + error("@page requires '{' before declarations"); + } + p++; + + //# DECLARATION LIST + p = skipwhite(p); + CSSStyleDeclaration declarationList; + p2 = getDeclaration(p, declarationList); + if (p2<0) + return -1; + if (p2<=p) + { + error("@page requires declaration(s) after '{'"); + return -1; + } + while (true) + { + p = skipwhite(p2); + ch = get(p); + if (ch != ';') + break; + p++; + p = skipwhite(p); + p2 = getDeclaration(p, declarationList); + if (p2<0) + return -1; + if (p2<= p) + { + error("@page requires declaration after ';'"); + return -1; + } + } + + //# } + p=skipwhite(p); + ch = get(p); + if (p != '}') + { + error("@page requires '}' after declarations"); + } + p++; + + return p; +} + +/** + * pseudo_page + * : ':' IDENT + * ; + */ +int CssParser::getPseudoPage(int p0) +{ + int p = p0; + if (!match(p, ":")) + return p0; + p++; + DOMString str; + int p2 = getWord(p, str); + if (p2<0) + return -1; + if (p2<=p) + { + error("pseudo-page requires identifier after ':'"); + return -1; + } + p = p2; + return p; +} + +/** + * ruleset + * : selector [ COMMA S* selector ]* + * LBRACE S* declaration [ ';' S* declaration ]* '}' S* + * ; + */ +int CssParser::getRuleSet(int p0) +{ + int p = p0; + XMLCh ch; + + //## SELECTOR + p = skipwhite(p); + int p2 = getSelector(p); + if (p2<0) + return -1; + if (p2<=p) //no selector + { + if (get(p) != '{')//check for selector-less rule + return p0;//not me + } + p = p2; + while (true) + { + p = skipwhite(p); + ch = get(p); + if (ch != ',') + break; + p++; + p = skipwhite(p); + int p2 = getSelector(p); + if (p2<0) + return -1; + if (p2<=p) + { + error("selector required after ',' in list"); + return -1; + } + p = p2; + } + + //## { + ch = get(p); + if (ch != '{') + { + error("'{' required before declarations of ruleset"); + return -1; + } + p++; + + //## DECLARATIONS ( 0 to many ) + CSSStyleDeclaration declarationList; + + p = skipwhite(p); + p2 = getDeclaration(p, declarationList); + if (p2<0) + return -1; + if (p2>p) + { + p = p2; + while (true) + { + p = skipwhite(p); + ch = get(p); + if (ch != ';') + break; + p++; + p = skipwhite(p); + p2 = getDeclaration(p, declarationList); + if (p2<0) + return -1; + if (p2<=p) + { + //apparently this is ok + //error("declaration required after ';' in ruleset"); + //return -1; + break; + } + p = p2; + } + } + //## } + ch = get(p); + if (ch != '}') + { + error("ruleset requires closing '}'"); + return -1; + } + p++; + p = skipwhite(p); + + return p; +} + +/** + * selector + * : simple_selector [ combinator simple_selector ]* + * ; + */ +int CssParser::getSelector(int p0) +{ + int p = p0; + + //## SIMPLE SELECTOR + p = skipwhite(p); + int p2 = getSimpleSelector(p); + if (p2<0) + return -1; + if (p2<=p) + return p0; //not me + p = p2; + + //## COMBINATORS + MORE SELECTORS + while (true) + { + XMLCh ch = get(p); + bool wasSpace = isspace(ch); + p = skipwhite(p); + ch = get(p); + //# Combinators + //easier to do here than have a getCombinator() + int visibleCombinator = false; + if (ch == '+') + { + visibleCombinator = true; + p++; + } + else if (ch == '>') + { + visibleCombinator = true; + p++; + } + else if (wasSpace) + { + } + else + { + break; + } + p = skipwhite(p); + p2 = getSimpleSelector(p); + if (p2<0) + return -1; + if (p2<=p) + { + if (visibleCombinator) + { + error("need simple selector after combinator"); + return -1; + } + else + { + break; + } + } + p = p2; + } + return p; +} + +/** + * simple_selector + * : element_name [ HASH | class | attrib | pseudo ]* + * | [ HASH | class | attrib | pseudo ]+ + * ; + */ +int CssParser::getSimpleSelector(int p0) +{ + int p = p0; + int p2; + + DOMString str; + + p = skipwhite(p); + + int selectorItems = 0; + + XMLCh ch = get(p); + + //###################### + //# Note: do NOT skipwhite between items. Only within the + //# pseudo function and attrib below + //###################### + + //#Element name 0 or 1 + if (isLetter(ch)) + { + p2 = getWord(p, str); + if (p2<0) + return -1; + if (p2<=p) + { + error("null element name"); + return -1; + } + selectorItems++; + p = p2; + } + else if (ch == '*') + { + str = "*"; + p++; + selectorItems++; + } + + + + //## HASH, CLASS, ATTRIB, PSEUDO (0 to many with elem name, 1 to many without) + while (true) + { + XMLCh ch = get(p); + + //# HASH + if (ch == '#') + { + p++; + p2 = getWord(p, str); + if (p2<0) + return -1; + if (p2<=p) + { + error("no name for hash"); + return -1; + } + p = p2; + selectorItems++; + } + + //# CLASS + else if (ch == '.') + { + p++; + p2 = getWord(p, str); + if (p2<0) + return -1; + if (p2<=p) + { + error("no name for class"); + return -1; + } + p = p2; + selectorItems++; + } + + //# ATTRIB + else if (ch == '[') + { + p++; + p = skipwhite(p); + p2 = getWord(p, str); + if (p2<0) + return -1; + if (p2<=p) + { + error("no name for class"); + return -1; + } + p = skipwhite(p2); + bool getRHS=false; + if (match(p, "=")) + { + p++; + getRHS=true; + } + else if (match(p, "~=")) + { + p+=2; + getRHS=true; + } + else if (match(p, "|=")) + { + p+=2; + getRHS=true; + } + if (getRHS) + { + p = skipwhite(p); + ch = get(p); + if (isLetter(ch)) + { + p2 = getWord(p, str); + if (p2<0) + return -1; + if (p2<=p) + { + error("null ident on rhs of attrib"); + return -1; + } + p = p2; + } + else if (ch == '\'' || ch =='"') + { + p2 = getQuoted(p, str); + if (p2<0) + return -1; + if (p2<=p) + { + error("null literal string on rhs of attrib"); + return -1; + } + p = p2; + } + }//getRHS + p = skipwhite(p); + ch = get(p); + if (ch != ']') + { + error("attrib needs closing ']'"); + //return -1; + p = skipBlock(p); + return p; + } + p++; + selectorItems++; + } + + //# PSEUDO + else if (ch == ':') + { + p++; + p2 = getWord(p, str); + if (p2<0) + return -1; + if (p2<=p) + { + error("no name for pseudo"); + return -1; + } + p = p2; + selectorItems++; + ch = get(p); + if (ch == '(') + { + p++; + p = skipwhite(p); + ch = get(p); + if (isLetter(ch)) + { + p2 = getWord(p, str); + if (p2<0) + return -1; + if (p2<=p) + { + error("null function parameter in pseudo"); + return -1; + } + p = skipwhite(p2); + ch = get(p); + } + if (ch != ')') + { + error("function in pseudo needs ')'"); + return -1; + } + p++; + }// ch==( -function- + }//pseudo + + //# none of the above + else + { + break; + } + + }//while + + + if (selectorItems > 0) + return p; + return p0; +} + +/** + * declaration + * : property ':' S* expr prio? + * | {empty} + * ; + */ +int CssParser::getDeclaration(int p0, CSSStyleDeclaration &declarationList) +{ + int p = p0; + + //## PROPERTY + p = skipwhite(p); + XMLCh ch = get(p); + if (!isLetter(ch)) + return p0; //not me + DOMString propName; + int p2 = getWord(p, propName); + if (p2<0) + return -1; + + //## ':' + p = skipwhite(p2); + ch = get(p); + if (ch != ':') + { + error("declaration requires ':' between name and value"); + return -1; + } + p++; + + //## EXPR + p = skipwhite(p); + p2 = getExpr(p); + if (p2<0) + return -1; + if (p2<=p) + { + error("declaration requires value after ':'"); + return -1; + } + DOMString propVal; + for (int i=p ; ip) + { + //do something + p = p2; + } + + return p; +} + +/** + * prio + * : IMPORTANT_SYM S* + * ; + */ +int CssParser::getPrio(int p0, DOMString &val) +{ + int p = p0; + + //## '!" + p = skipwhite(p); + XMLCh ch = get(p); + if (ch != '!') + return p0; + p++; + + //## "important" + p = skipwhite(p); + if (!match(p, "important")) + { + error("priority symbol is 'important'"); + return -1; + } + p += 9; + val = "important"; + return p; +} + +/** + * expr + * : term [ operator term ]* + * ; + */ +int CssParser::getExpr(int p0) +{ + int p = p0; + + //## TERM + p = skipwhite(p); + int p2 = getTerm(p); + if (p2<0) + return -1; + if (p2<=p) + return p0; //not me + p = p2; + while (p < parselen) + { + p = skipwhite(p); + //#Operator. do this instead of getOperator() + XMLCh ch = get(p); + int visibleTerm = false; + if (ch == '/') + { + visibleTerm = true; + p++; + } + else if (ch == ',') + { + visibleTerm = true; + p++; + } + else + { + //just space. this is allowable between terms, + // so we still need to check for another term + } + p = skipwhite(p); + p2 = getTerm(p); + if (p2<0) + return -1; + if (p2<=p) + { + if (visibleTerm) + { + error("expression requires term after operator"); + return -1; + } + else + { + break; + } + } + p = p2; + } + + return p; +} + +/** + * term + * : unary_operator? + * [ NUMBER S* | PERCENTAGE S* | LENGTH S* | EMS S* | EXS S* | ANGLE S* | + * TIME S* | FREQ S* | function ] + * | STRING S* | IDENT S* | URI S* | hexcolor + * ; + */ +int CssParser::getTerm(int p0) +{ + int p = p0; + p = skipwhite(p); + int unitType = CSSPrimitiveValue::CSS_UNKNOWN; + //# Unary operator + XMLCh ch = get(p); + bool hasUnary = false; + if (ch == '-') + { + p++; + hasUnary = true; + } + else if (ch == '+') + { + p++; + hasUnary = true; + } + //# NUMERIC + double numVal; + int p2 = getNumber(p, numVal); + if (p2<0) + return -1; + if (p2>p) + { + p = p2; + if (match(p, "%")) + { + unitType = CSSPrimitiveValue::CSS_PERCENTAGE; + p++; + } + else if (match(p, "em")) + { + unitType = CSSPrimitiveValue::CSS_EMS; + p+=2; + } + else if (match(p, "ex")) + { + unitType = CSSPrimitiveValue::CSS_EXS; + p+=2; + } + else if (match(p, "px")) + { + unitType = CSSPrimitiveValue::CSS_PX; + p+=2; + } + else if (match(p, "cm")) + { + unitType = CSSPrimitiveValue::CSS_CM; + p+=2; + } + else if (match(p, "mm")) + { + unitType = CSSPrimitiveValue::CSS_MM; + p+=2; + } + else if (match(p, "in")) + { + unitType = CSSPrimitiveValue::CSS_IN; + p+=2; + } + else if (match(p, "pt")) + { + unitType = CSSPrimitiveValue::CSS_PT; + p+=2; + } + else if (match(p, "pc")) + { + unitType = CSSPrimitiveValue::CSS_PC; + p+=2; + } + else if (match(p, "deg")) + { + unitType = CSSPrimitiveValue::CSS_DEG; + p+=3; + } + else if (match(p, "rad")) + { + unitType = CSSPrimitiveValue::CSS_RAD; + p+=3; + } + else if (match(p, "grad")) + { + unitType = CSSPrimitiveValue::CSS_GRAD; + p+=4; + } + else if (match(p, "ms")) + { + unitType = CSSPrimitiveValue::CSS_MS; + p+=2; + } + else if (match(p, "s")) + { + unitType = CSSPrimitiveValue::CSS_S; + p+=1; + } + else if (match(p, "Hz")) + { + unitType = CSSPrimitiveValue::CSS_HZ; + p+=2; + } + else if (match(p, "kHz")) + { + unitType = CSSPrimitiveValue::CSS_KHZ; + p+=2; + } + else if (isLetter(get(p)))//some other string + { + DOMString suffix; + p2 = getWord(p, suffix); + if (p2<0) + return -1; + unitType = CSSPrimitiveValue::CSS_DIMENSION; + p = p2; + } + else //plain number + { + unitType = CSSPrimitiveValue::CSS_NUMBER; + } + return p; + } + + DOMString str; + + //## URI --do before function, as syntax is similar + p2 = getUri(p, str); + if (p2<0) + return -1; + if (p2>p) + { + if (hasUnary) + { + error("+ or - not allowed on URI"); + return -1; + } + p = p2; + unitType = CSSPrimitiveValue::CSS_URI; + return p; + } + + //## FUNCTION + p2 = getFunction(p); + if (p2<0) + return -1; + if (p2>p) + { + p = p2; + return p; + } + + //## STRING + ch = get(p); + if (ch == '"' || ch == '\'') + { + p2 = getQuoted(p, str); + if (p2<0) + return -1; + if (p2>p) + { + if (hasUnary) + { + error("+ or - not allowed on a string"); + return -1; + } + p = p2; + unitType = CSSPrimitiveValue::CSS_STRING; + return p; + } + } + + //## IDENT + ch = get(p); + if (isLetter(ch)) + { + p2 = getWord(p, str); + if (p2<0) + return -1; + if (p2>p) + { + if (hasUnary) + { + error("+ or - not allowed on an identifier"); + return -1; + } + p = p2; + unitType = CSSPrimitiveValue::CSS_IDENT; + return p; + } + } + + + //## HEXCOLOR + p2 = getHexColor(p); + if (p2<0) + return -1; + if (p2>p) + { + if (hasUnary) + { + error("+ or - not allowed on hex color"); + return -1; + } + p = p2; + unitType = CSSPrimitiveValue::CSS_RGBCOLOR; + return p; + } + + + return p0; +} + +/** + * function + * : FUNCTION S* expr ')' S* + * ; + */ +int CssParser::getFunction(int p0) +{ + int p = p0; + + //## IDENT + ( (both) + DOMString name; + p = skipwhite(p); + int p2 = getWord(p, name); + if (p2<0) + return -1; + if (p2<=p) + return p0; //not me + if (name == "uri" || name=="url") + return p0; //not me + p = skipwhite(p2); + XMLCh ch = get(p); + if (ch != '(') + return p0; //still not me + p++; + + //## EXPR + p = skipwhite(p); + p2 = getExpr(p); + if (p2<0) + return -1; + if (p2<=p) + { + error("function requires expression"); + return -1; + } + p = p2; + + //## ')' + p = skipwhite(p); + ch = get(p); + if (ch != ')') + { + error("function requires closing ')'"); + return -1; + } + p++; + p = skipwhite(p); + + return p; +} + +/** + * There is a constraint on the color that it must + * have either 3 or 6 hex-digits (i.e., [0-9a-fA-F]) + * after the "#"; e.g., "#000" is OK, but "#abcd" is not. + * hexcolor + * : HASH S* + * ; + */ +int CssParser::getHexColor(int p0) +{ + int p = p0; + + //## '#' + p = skipwhite(p); + if (!match(p, "#")) + return p0; + p++; + + //## HEX + DOMString hex; + long hexVal = 0; + while (p < parselen) + { + XMLCh b = get(p); + if (b>='0' && b<='9') + { + hexVal = (hexVal << 4) + (b - '0'); + hex.push_back(b); + p++; + } + else if (b>='a' && b<='f') + { + hexVal = (hexVal << 4) + (b - 'a' + 10); + hex.push_back(b); + p++; + } + else if (b>='A' && b<='F') + { + hexVal = (hexVal << 4) + (b - 'A' + 10); + hex.push_back(b); + p++; + } + else + { + break; + } + } + + if (hex.size() != 3 && hex.size() != 6) + { + error("exactly 3 or 6 hex digits are required after '#'"); + return -1; + } + + return p; +} + + + +/** + * + */ +bool CssParser::parse(const DOMString &str) +{ + /* + int len = str.size(); + for (int i=0 ; i +#include + +#define OWN_STRING + +#ifdef OWN_STRING +#include "domstring.h" +#endif + +#define XMLNSNAME "http://www.w3.org/2000/xmlns/" + +namespace org +{ +namespace w3c +{ +namespace dom +{ + + + +#ifndef OWN_STRING +typedef unsigned short XMLCh; +typedef std::string DOMString; +#endif + +/** + * + */ +typedef unsigned long long DOMTimeStamp; + +/** + * + */ +typedef void DOMUserData; + +/** + * + */ +typedef void DOMObject; + + +class DOMException; +class DOMStringList; +class NameList; +class DOMImplementationList; +class DOMImplementationSource; +class DOMImplementation; +class Node; +class NodeList; +class NamedNodeMap; +class CharacterData; +class Attr; +class Element; +class Text; +class Comment; +class TypeInfo; +class UserDataHandler; +class DOMError; +class DOMErrorHandler; +class DOMLocator; +class DOMConfiguration; +class CDATASection; +class DocumentType; +class Notation; +class Entity; +class EntityReference; +class ProcessingInstruction; +class DocumentFragment; +class Document; + + +/** + * NOTE: We were originally intending to split ALL specifications into + * interface and implementation. After consideration, though, it behooves + * us to simplify things by implementing the base exception and + * container classes directly: + * + * DOMException + * DOMStringList + * NameList + * DOMImplementationList + * DOMImplementationSource + * DOMImplementation + * NodeList + * NamedNodeMap + */ + + +/*######################################################################### +## DOMException +#########################################################################*/ +/** + * This is the only non-interface class + */ +class DOMException +{ + +public: + + DOMException(const DOMString &reasonMsg) + { msg = reasonMsg; } + + DOMException(short theCode) + { + code = theCode; + } + + virtual ~DOMException() throw() + {} + + /** + * + */ + unsigned short code; + + /** + * + */ + DOMString msg; + + /** + * Get a string, translated from the code. + * Like std::exception. Not in spec. + */ + const char *what() + { return (const char *)msg.c_str(); } + + + +}; + + + + +/** + * ExceptionCode + */ +typedef enum +{ + INDEX_SIZE_ERR = 1, + DOMSTRING_SIZE_ERR = 2, + HIERARCHY_REQUEST_ERR = 3, + WRONG_DOCUMENT_ERR = 4, + INVALID_CHARACTER_ERR = 5, + NO_DATA_ALLOWED_ERR = 6, + NO_MODIFICATION_ALLOWED_ERR = 7, + NOT_FOUND_ERR = 8, + NOT_SUPPORTED_ERR = 9, + INUSE_ATTRIBUTE_ERR = 10, + INVALID_STATE_ERR = 11, + SYNTAX_ERR = 12, + INVALID_MODIFICATION_ERR = 13, + NAMESPACE_ERR = 14, + INVALID_ACCESS_ERR = 15, + VALIDATION_ERR = 16, + TYPE_MISMATCH_ERR = 17 +} ExceptionCode; + + +/*######################################################################### +## DOMStringList +#########################################################################*/ + +class DOMStringList +{ +public: + + /** + * + */ + virtual DOMString item(unsigned long index) + { + if (index>=strings.size()) + return ""; + return strings[index]; + } + + /** + * + */ + virtual unsigned long getLength() + { + return (unsigned long) strings.size(); + } + + /** + * + */ + virtual bool contains(const DOMString &str) + { + for (unsigned int i=0; istrings; + +}; + + + +/*######################################################################### +## NameList +#########################################################################*/ +class NamePair +{ +public: + NamePair(const DOMString &theNamespaceURI, const DOMString &theName) + { + namespaceURI = theNamespaceURI; + name = theName; + } + NamePair(const NamePair &other) + { + namespaceURI = other.namespaceURI; + name = other.name; + } + virtual ~NamePair() {} + + DOMString namespaceURI; + DOMString name; +}; + + + +class NameList +{ +public: + + /** + * + */ + virtual DOMString getName(unsigned long index) + { + if (index>=namePairs.size()) + return ""; + return namePairs[index].name; + } + + /** + * + */ + virtual DOMString getNamespaceURI(unsigned long index) + { + if (index>=namePairs.size()) + return ""; + return namePairs[index].namespaceURI; + } + + /** + * + */ + virtual unsigned long getLength() + { + return (unsigned long)namePairs.size(); + } + + /** + * + */ + virtual bool contains(const DOMString &name) + { + for (unsigned int i=0; i namePairs; + +}; + +/*######################################################################### +## DOMImplementationList +#########################################################################*/ + +class DOMImplementationList +{ +public: + + /** + * + */ + virtual DOMImplementation *getDOMImplementation(unsigned long index) + { + if (index >implementations.size()) + return NULL; + return implementations[index]; + } + + /** + * + */ + virtual unsigned long getLength() + { + return (unsigned long) implementations.size(); + } + + + + + //################## + //# Non-API methods + //################## + + /** + * + */ + DOMImplementationList() {} + + + /** + * + */ + DOMImplementationList(const DOMImplementationList &other) + { + implementations = other.implementations; + } + + /** + * + */ + virtual ~DOMImplementationList() {} + +protected: + + std::vectorimplementations; + +}; + + +/*######################################################################### +## DOMImplementationSource +#########################################################################*/ + +class DOMImplementationSource +{ +public: + + /** + * + */ + virtual DOMImplementation *getDOMImplementation(const DOMString &features) = 0; + + /** + * + */ + virtual DOMImplementationList getDOMImplementationList(const DOMString &features) = 0; + + //################## + //# Non-API methods + //################## + + /** + * + */ + virtual ~DOMImplementationSource() {} + +}; + + + + + +/*######################################################################### +## DOMImplementation +#########################################################################*/ +/** + * + */ +class DOMImplementation +{ +public: + /** + * + */ + virtual bool hasFeature(const DOMString& feature, const DOMString& version) = 0; + + + /** + * + */ + virtual DocumentType *createDocumentType(const DOMString& qualifiedName, + const DOMString& publicId, + const DOMString& systemId) + throw(DOMException) = 0; + + /** + * + */ + virtual Document *createDocument(const DOMString& namespaceURI, + const DOMString& qualifiedName, + DocumentType *doctype) + throw(DOMException) = 0; + /** + * + */ + virtual DOMObject *getFeature(const DOMString& feature, + const DOMString& version) = 0; + + + //################## + //# Non-API methods + //################## + + /** + * + */ + virtual ~DOMImplementation() {} + +}; + + + + +/*######################################################################### +## Node +#########################################################################*/ + +/** + * + */ +class Node +{ +public: + + typedef enum + { + ELEMENT_NODE = 1, + ATTRIBUTE_NODE = 2, + TEXT_NODE = 3, + CDATA_SECTION_NODE = 4, + ENTITY_REFERENCE_NODE = 5, + ENTITY_NODE = 6, + PROCESSING_INSTRUCTION_NODE = 7, + COMMENT_NODE = 8, + DOCUMENT_NODE = 9, + DOCUMENT_TYPE_NODE = 10, + DOCUMENT_FRAGMENT_NODE = 11, + NOTATION_NODE = 12 + } NodeType; + + /** + * + */ + virtual DOMString getNodeName() = 0; + + /** + * + */ + virtual DOMString getNodeValue() throw (DOMException) = 0; + + /** + * + */ + virtual void setNodeValue(const DOMString& val) throw (DOMException) = 0; + + /** + * + */ + virtual unsigned short getNodeType() = 0; + + /** + * + */ + virtual Node *getParentNode() = 0; + + /** + * + */ + virtual NodeList getChildNodes() = 0; + + /** + * + */ + virtual Node *getFirstChild() = 0; + + /** + * + */ + virtual Node *getLastChild() = 0; + + /** + * + */ + virtual Node *getPreviousSibling() = 0; + + /** + * + */ + virtual Node *getNextSibling() = 0; + + /** + * + */ + virtual NamedNodeMap &getAttributes() = 0; + + + /** + * + */ + virtual Document *getOwnerDocument() = 0; + + /** + * + */ + virtual Node *insertBefore(const Node *newChild, + const Node *refChild) + throw(DOMException) = 0; + + /** + * + */ + virtual Node *replaceChild(const Node *newChild, + const Node *oldChild) + throw(DOMException) = 0; + + /** + * + */ + virtual Node *removeChild(const Node *oldChild) + throw(DOMException) = 0; + + /** + * + */ + virtual Node *appendChild(const Node *newChild) + throw(DOMException) = 0; + + /** + * + */ + virtual bool hasChildNodes() = 0; + + /** + * + */ + virtual Node *cloneNode(bool deep) = 0; + + /** + * + */ + virtual void normalize() = 0; + + /** + * + */ + virtual bool isSupported(const DOMString& feature, + const DOMString& version) = 0; + + /** + * + */ + virtual DOMString getNamespaceURI() = 0; + + /** + * + */ + virtual DOMString getPrefix() = 0; + + /** + * + */ + virtual void setPrefix(const DOMString& val) throw(DOMException) = 0; + + /** + * + */ + virtual DOMString getLocalName() = 0; + + /** + * + */ + virtual bool hasAttributes() = 0; + + /** + * + */ + virtual DOMString getBaseURI() = 0; + + typedef enum + { + DOCUMENT_POSITION_DISCONNECTED = 0x01, + DOCUMENT_POSITION_PRECEDING = 0x02, + DOCUMENT_POSITION_FOLLOWING = 0x04, + DOCUMENT_POSITION_CONTAINS = 0x08, + DOCUMENT_POSITION_CONTAINED_BY = 0x10, + DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC = 0x20 + } DocumentPosition; + + + /** + * + */ + virtual unsigned short compareDocumentPosition(const Node *other) = 0; + + /** + * + */ + virtual DOMString getTextContext() throw(DOMException) = 0; + + + /** + * + */ + virtual void setTextContext(const DOMString &val) throw(DOMException) = 0; + + + /** + * + */ + virtual DOMString lookupPrefix(const DOMString &namespaceURI) =0; + + + /** + * + */ + virtual bool isDefaultNamespace(const DOMString &namespaceURI) =0; + + + /** + * + */ + virtual DOMString lookupNamespaceURI(const DOMString &prefix) =0; + + + /** + * + */ + virtual bool isEqualNode(const Node *node) =0; + + + + /** + * + */ + virtual DOMObject *getFeature(const DOMString &feature, + const DOMString &version) =0; + + /** + * + */ + virtual DOMUserData *setUserData(const DOMString &key, + const DOMUserData *data, + const UserDataHandler *handler) =0; + + + /** + * + */ + virtual DOMUserData *getUserData(const DOMString &namespaceURI) =0; + + //################## + //# Non-API methods + //################## + + + /** + * + */ + virtual ~Node() {} + + + + +}; + + + +/*######################################################################### +## NodeList +#########################################################################*/ + +/** + * + */ +class NodeList +{ +public: + /** + * + */ + virtual Node *item(unsigned long index) + { + if (index>=nodes.size()) + return NULL; + return nodes[index]; + } + + /** + * + */ + virtual unsigned long getLength() + { + return (unsigned long) nodes.size(); + } + + //################## + //# Non-API methods + //################## + + + /** + * + */ + NodeList() {} + + /** + * + */ + NodeList(const NodeList &other) + { + nodes = other.nodes; + } + + /** + * + */ + virtual ~NodeList() {} + +protected: + +friend class NodeImpl; +friend class ElementImpl; + + /* + * + */ + virtual void add(const Node *node) + { + nodes.push_back((Node *)node); + } + +protected: + + std::vector nodes; + +}; + + + + +/*######################################################################### +## NamedNodeMap +#########################################################################*/ + +class NamedNodeMapEntry +{ +public: + NamedNodeMapEntry(const DOMString &theNamespaceURI, + const DOMString &theName, + const Node *theNode) + { + namespaceURI = theNamespaceURI; + name = theName; + node = (Node *)theNode; + } + NamedNodeMapEntry(const NamedNodeMapEntry &other) + { + namespaceURI = other.namespaceURI; + name = other.name; + node = other.node; + } + virtual ~NamedNodeMapEntry() + { + } + DOMString namespaceURI; + DOMString name; + Node *node; +}; + +/** + * + */ +class NamedNodeMap +{ +public: + + /** + * + */ + virtual Node *getNamedItem(const DOMString& name) + { + std::vector::iterator iter; + for (iter = entries.begin() ; iter!=entries.end() ; iter++) + { + if (iter->name == name) + { + Node *node = iter->node; + return node; + } + } + return NULL; + } + + /** + * + */ + virtual Node *setNamedItem(Node *arg) throw(DOMException) + { + if (!arg) + return NULL; + DOMString namespaceURI = arg->getNamespaceURI(); + DOMString name = arg->getNodeName(); + std::vector::iterator iter; + for (iter = entries.begin() ; iter!=entries.end() ; iter++) + { + if (iter->name == name) + { + Node *node = iter->node; + iter->node = arg; + return node; + } + } + NamedNodeMapEntry entry(namespaceURI, name, arg); + entries.push_back(entry); + return arg; + } + + + /** + * + */ + virtual Node *removeNamedItem(const DOMString& name) throw(DOMException) + { + std::vector::iterator iter; + for (iter = entries.begin() ; iter!=entries.end() ; iter++) + { + if (iter->name == name) + { + Node *node = iter->node; + entries.erase(iter); + return node; + } + } + return NULL; + } + + /** + * + */ + virtual Node *item(unsigned long index) + { + if (index>=entries.size()) + return NULL; + return entries[index].node; + } + + /** + * + */ + virtual unsigned long getLength() + { + return (unsigned long)entries.size(); + } + + /** + * + */ + virtual Node *getNamedItemNS(const DOMString& namespaceURI, + const DOMString& localName) + { + std::vector::iterator iter; + for (iter = entries.begin() ; iter!=entries.end() ; iter++) + { + if (iter->namespaceURI == namespaceURI && iter->name == localName) + { + Node *node = iter->node; + return node; + } + } + return NULL; + } + + /** + * + */ + virtual Node *setNamedItemNS(Node *arg) throw(DOMException) + { + if (!arg) + return NULL; + DOMString namespaceURI = arg->getNamespaceURI(); + DOMString name = arg->getNodeName(); + std::vector::iterator iter; + for (iter = entries.begin() ; iter!=entries.end() ; iter++) + { + if (iter->namespaceURI == namespaceURI && iter->name == name) + { + Node *node = iter->node; + iter->node = arg; + return node; + } + } + NamedNodeMapEntry entry(namespaceURI, name, arg); + entries.push_back(entry); + return arg; + } + + /** + * + */ + virtual Node *removeNamedItemNS(const DOMString& namespaceURI, + const DOMString& localName) + throw(DOMException) + { + std::vector::iterator iter; + for (iter = entries.begin() ; iter!=entries.end() ; iter++) + { + if (iter->namespaceURI == namespaceURI && iter->name == localName) + { + Node *node = iter->node; + entries.erase(iter); + return node; + } + } + return NULL; + } + + //################## + //# Non-API methods + //################## + + /** + * + */ + NamedNodeMap() {} + + + /** + * + */ + NamedNodeMap(const NamedNodeMap &other) + { + entries = other.entries; + } + + + /** + * + */ + virtual ~NamedNodeMap() {} + +protected: + + std::vector entries; + +}; + + + + +/*######################################################################### +## CharacterData +#########################################################################*/ + +/** + * + */ +class CharacterData : virtual public Node +{ +public: + + /** + * + */ + virtual DOMString getData() throw(DOMException) = 0; + + /** + * + */ + virtual void setData(const DOMString& val) throw(DOMException) = 0; + + /** + * + */ + virtual unsigned long getLength() = 0; + + /** + * + */ + virtual DOMString substringData(unsigned long offset, + unsigned long count) + throw(DOMException) = 0; + + /** + * + */ + virtual void appendData(const DOMString& arg) throw(DOMException) = 0; + + /** + * + */ + virtual void insertData(unsigned long offset, + const DOMString& arg) + throw(DOMException) = 0; + + /** + * + */ + virtual void deleteData(unsigned long offset, + unsigned long count) + throw(DOMException) = 0; + + /** + * + */ + virtual void replaceData(unsigned long offset, + unsigned long count, + const DOMString& arg) + throw(DOMException) = 0; + + + //################## + //# Non-API methods + //################## + + + /** + * + */ + virtual ~CharacterData() {} + +}; + + + + + +/*######################################################################### +## Attr +#########################################################################*/ + +/** + * + */ +class Attr : virtual public Node +{ +public: + + /** + * + */ + virtual DOMString getName() = 0; + + /** + * + */ + virtual bool getSpecified() = 0; + + /** + * + */ + virtual DOMString getValue() = 0; + + /** + * + */ + virtual void setValue(const DOMString& val) throw(DOMException) = 0; + + /** + * + */ + virtual Element *getOwnerElement() = 0; + + + /** + * + */ + virtual TypeInfo *getSchemaTypeInfo() = 0; + + + /** + * + */ + virtual bool getIsId() = 0; + + //################## + //# Non-API methods + //################## + + + /** + * + */ + virtual ~Attr() {} + +}; + + + + + +/*######################################################################### +## Element +#########################################################################*/ + +/** + * + */ +class Element : virtual public Node +{ +public: + + + /** + * + */ + virtual DOMString getTagName() = 0; + + /** + * + */ + virtual DOMString getAttribute(const DOMString& name) = 0; + + /** + * + */ + virtual void setAttribute(const DOMString& name, + const DOMString& value) + throw(DOMException) = 0; + + /** + * + */ + virtual void removeAttribute(const DOMString& name) + throw(DOMException) = 0; + + /** + * + */ + virtual Attr *getAttributeNode(const DOMString& name) = 0; + + /** + * + */ + virtual Attr *setAttributeNode(Attr *newAttr) + throw(DOMException) = 0; + + /** + * + */ + virtual Attr *removeAttributeNode(Attr *oldAttr) + throw(DOMException) = 0; + + /** + * + */ + virtual NodeList getElementsByTagName(const DOMString& name) = 0; + + /** + * + */ + virtual DOMString getAttributeNS(const DOMString& namespaceURI, + const DOMString& localName) = 0; + + /** + * + */ + virtual void setAttributeNS(const DOMString& namespaceURI, + const DOMString& qualifiedName, + const DOMString& value) + throw(DOMException) = 0; + + /** + * + */ + virtual void removeAttributeNS(const DOMString& namespaceURI, + const DOMString& localName) + throw(DOMException) = 0; + + /** + * + */ + virtual Attr *getAttributeNodeNS(const DOMString& namespaceURI, + const DOMString& localName) = 0; + + /** + * + */ + virtual Attr *setAttributeNodeNS(Attr *newAttr) + throw(DOMException) = 0; + + /** + * + */ + virtual NodeList getElementsByTagNameNS(const DOMString& namespaceURI, + const DOMString& localName) = 0; + + /** + * + */ + virtual bool hasAttribute(const DOMString& name) = 0; + + /** + * + */ + virtual bool hasAttributeNS(const DOMString& namespaceURI, + const DOMString& localName) = 0; + + /** + * + */ + virtual TypeInfo *getSchemaTypeInto() = 0; + + + /** + * + */ + virtual void setIdAttribute(const DOMString &name, + bool isId) throw (DOMException) = 0; + + /** + * + */ + virtual void setIdAttributeNS(const DOMString &namespaceURI, + const DOMString &localName, + bool isId) throw (DOMException) = 0; + + /** + * + */ + virtual void setIdAttributeNode(const Attr *idAttr, + bool isId) throw (DOMException) = 0; + + //################## + //# Non-API methods + //################## + + /** + * + */ + virtual ~Element() {} + +}; + + + + + +/*######################################################################### +## Text +#########################################################################*/ + +/** + * + */ +class Text : virtual public CharacterData +{ +public: + + /** + * + */ + virtual Text *splitText(unsigned long offset) + throw(DOMException) = 0; + + /** + * + */ + virtual bool getIsElementContentWhitespace()= 0; + + /** + * + */ + virtual DOMString getWholeText() = 0; + + + /** + * + */ + virtual Text *replaceWholeText(const DOMString &content) + throw(DOMException) = 0; + + //################## + //# Non-API methods + //################## + + + /** + * + */ + virtual ~Text() {} + +}; + + + +/*######################################################################### +## Comment +#########################################################################*/ + +/** + * + */ +class Comment : virtual public CharacterData +{ +public: + + //################## + //# Non-API methods + //################## + + + /** + * + */ + virtual ~Comment() {} + + +}; + + + +/*######################################################################### +## TypeInfo +#########################################################################*/ + +/** + * + */ +class TypeInfo +{ +public: + + /** + * + */ + virtual DOMString getTypeName() =0; + + /** + * + */ + virtual DOMString getTypeNamespace() =0; + + typedef enum + { + DERIVATION_RESTRICTION = 0x00000001, + DERIVATION_EXTENSION = 0x00000002, + DERIVATION_UNION = 0x00000004, + DERIVATION_LIST = 0x00000008 + } DerivationMethod; + + + /** + * + */ + virtual bool isDerivedFrom(const DOMString &typeNamespaceArg, + const DOMString &typeNameArg, + DerivationMethod derivationMethod) =0; + + //################## + //# Non-API methods + //################## + + + /** + * + */ + virtual ~TypeInfo() {} + +}; + + + + +/*######################################################################### +## UserDataHandler +#########################################################################*/ + +/** + * + */ +class UserDataHandler +{ +public: + + typedef enum + { + NODE_CLONED = 1, + NODE_IMPORTED = 2, + NODE_DELETED = 3, + NODE_RENAMED = 4, + NODE_ADOPTED = 5 + } OperationType; + + + /** + * + */ + virtual void handle(unsigned short operation, + const DOMString &key, + const DOMUserData *data, + const Node *src, + const Node *dst) =0; + + //################## + //# Non-API methods + //################## + + + /** + * + */ + virtual ~UserDataHandler() {} + +}; + + +/*######################################################################### +## DOMError +#########################################################################*/ + +/** + * + */ +class DOMError +{ +public: + + typedef enum + { + SEVERITY_WARNING = 1, + SEVERITY_ERROR = 2, + SEVERITY_FATAL_ERROR = 3 + } ErrorSeverity; + + + /** + * + */ + virtual unsigned short getSeverity() =0; + + /** + * + */ + virtual DOMString getMessage() =0; + + /** + * + */ + virtual DOMString getType() =0; + + /** + * + */ + virtual DOMObject *getRelatedException() =0; + + /** + * + */ + virtual DOMObject *getRelatedData() =0; + + /** + * + */ + virtual DOMLocator *getLocation() =0; + + + //################## + //# Non-API methods + //################## + + + /** + * + */ + virtual ~DOMError() {} + +}; + + +/*######################################################################### +## DOMErrorHandler +#########################################################################*/ + +/** + * + */ +class DOMErrorHandler +{ +public: + /** + * + */ + virtual bool handleError(const DOMError *error) =0; + + //################## + //# Non-API methods + //################## + + + /** + * + */ + virtual ~DOMErrorHandler() {} + +}; + + + +/*######################################################################### +## DOMLocator +#########################################################################*/ + +/** + * + */ +class DOMLocator +{ +public: + + /** + * + */ + virtual long getLineNumber() =0; + + /** + * + */ + virtual long getColumnNumber() =0; + + /** + * + */ + virtual long getByteOffset() =0; + + /** + * + */ + virtual long getUtf16Offset() =0; + + + /** + * + */ + virtual Node *getRelatedNode() =0; + + + /** + * + */ + virtual DOMString getUri() =0; + + //################## + //# Non-API methods + //################## + + /** + * + */ + virtual ~DOMLocator() {} +}; + + +/*######################################################################### +## DOMConfiguration +#########################################################################*/ + +/** + * + */ +class DOMConfiguration +{ +public: + + /** + * + */ + virtual void setParameter(const DOMString &name, + const DOMUserData *value) throw (DOMException) =0; + + /** + * + */ + virtual DOMUserData *getParameter(const DOMString &name) + throw (DOMException) =0; + + /** + * + */ + virtual bool canSetParameter(const DOMString &name, + const DOMUserData *data) =0; + + /** + * + */ + virtual DOMStringList *getParameterNames() =0; + + //################## + //# Non-API methods + //################## + + + /** + * + */ + virtual ~DOMConfiguration() {} + +}; + + + + + + +/*######################################################################### +## CDATASection +#########################################################################*/ +/** + * + */ +class CDATASection : virtual public Text +{ +public: + + //################## + //# Non-API methods + //################## + + + /** + * + */ + virtual ~CDATASection() {} + +}; + + + + +/*######################################################################### +## DocumentType +#########################################################################*/ + +/** + * + */ +class DocumentType : virtual public Node +{ +public: + + /** + * + */ + virtual DOMString getName() = 0; + + /** + * + */ + virtual NamedNodeMap getEntities() = 0; + + /** + * + */ + virtual NamedNodeMap getNotations() = 0; + + /** + * + */ + virtual DOMString getPublicId() = 0; + + /** + * + */ + virtual DOMString getSystemId() = 0; + + /** + * + */ + virtual DOMString getInternalSubset() = 0; + + //################## + //# Non-API methods + //################## + + /** + * + */ + virtual ~DocumentType() {} + +}; + + + + + +/*######################################################################### +## Notation +#########################################################################*/ + +/** + * + */ +class Notation : virtual public Node +{ +public: + + /** + * + */ + virtual DOMString getPublicId() = 0; + + /** + * + */ + virtual DOMString getSystemId() = 0; + + //################## + //# Non-API methods + //################## + + + /** + * + */ + virtual ~Notation() {} +}; + + + + + + +/*######################################################################### +## Entity +#########################################################################*/ + +/** + * + */ +class Entity : virtual public Node +{ +public: + + /** + * + */ + virtual DOMString getPublicId() = 0; + + /** + * + */ + virtual DOMString getSystemId() = 0; + + /** + * + */ + virtual DOMString getNotationName() = 0; + + /** + * + */ + virtual DOMString getInputEncoding() = 0; + + /** + * + */ + virtual DOMString getXmlEncoding() = 0; + + /** + * + */ + virtual DOMString getXmlVersion() = 0; + + //################## + //# Non-API methods + //################## + + + /** + * + */ + virtual ~Entity() {} +}; + + + + + +/*######################################################################### +## EntityReference +#########################################################################*/ +/** + * + */ +class EntityReference : virtual public Node +{ +public: + + + //################## + //# Non-API methods + //################## + + /** + * + */ + virtual ~EntityReference() {} +}; + + + + + +/*######################################################################### +## ProcessingInstruction +#########################################################################*/ + +/** + * + */ +class ProcessingInstruction : virtual public Node +{ +public: + + /** + * + */ + virtual DOMString getTarget() = 0; + + /** + * + */ + virtual DOMString getData() = 0; + + /** + * + */ + virtual void setData(const DOMString& val) throw(DOMException) = 0; + + //################## + //# Non-API methods + //################## + + + /** + * + */ + virtual ~ProcessingInstruction() {} + +}; + + + + + +/*######################################################################### +## DocumentFragment +#########################################################################*/ +/** + * + */ +class DocumentFragment : virtual public Node +{ +public: + + //################## + //# Non-API methods + //################## + + + /** + * + */ + virtual ~DocumentFragment() {} +}; + + + + + + +/*######################################################################### +## Document +#########################################################################*/ + +/** + * + */ +class Document : virtual public Node +{ +public: + + /** + * + */ + virtual DocumentType *getDoctype() = 0; + + /** + * + */ + virtual DOMImplementation *getImplementation() = 0; + + /** + * + */ + virtual Element *getDocumentElement() = 0; + + /** + * + */ + virtual Element *createElement(const DOMString& tagName) + throw(DOMException) = 0; + + /** + * + */ + virtual DocumentFragment *createDocumentFragment() = 0; + + /** + * + */ + virtual Text *createTextNode(const DOMString& data) = 0; + + /** + * + */ + virtual Comment *createComment(const DOMString& data) = 0; + + /** + * + */ + virtual CDATASection *createCDATASection(const DOMString& data) + throw(DOMException) = 0; + + /** + * + */ + virtual ProcessingInstruction *createProcessingInstruction(const DOMString& target, + const DOMString& data) + throw(DOMException) = 0; + + /** + * + */ + virtual Attr *createAttribute(const DOMString& name) + throw(DOMException) = 0; + + /** + * + */ + virtual EntityReference *createEntityReference(const DOMString& name) + throw(DOMException) = 0; + + /** + * + */ + virtual NodeList getElementsByTagName(const DOMString& tagname) = 0; + + + /** + * + */ + virtual Node *importNode(const Node *importedNode, + bool deep) + throw(DOMException) = 0; + + /** + * + */ + virtual Element *createElementNS(const DOMString& namespaceURI, + const DOMString& qualifiedName) + throw(DOMException) = 0; + + /** + * + */ + virtual Attr *createAttributeNS(const DOMString& namespaceURI, + const DOMString& qualifiedName) + throw(DOMException) = 0; + + /** + * + */ + virtual NodeList getElementsByTagNameNS(const DOMString& namespaceURI, + const DOMString& localName) = 0; + + /** + * + */ + virtual Element *getElementById(const DOMString& elementId) = 0; + + + /** + * + */ + virtual DOMString getInputEncoding() = 0; + + + /** + * + */ + virtual DOMString getXmlEncoding() = 0; + + /** + * + */ + virtual bool getXmlStandalone() = 0; + + /** + * + */ + virtual void setXmlStandalone(bool val) throw (DOMException) = 0; + + /** + * + */ + virtual DOMString getXmlVersion() = 0; + + /** + * + */ + virtual void setXmlVersion(const DOMString &version) throw (DOMException) = 0; + + /** + * + */ + virtual bool getStrictErrorChecking() = 0; + + /** + * + */ + virtual void setStrictErrorChecking(bool val) = 0; + + + /** + * + */ + virtual DOMString getDocumentURI() = 0; + + /** + * + */ + virtual void setDocumentURI(const DOMString &uri) = 0; + + /** + * + */ + virtual Node *adoptNode(const Node *source) throw (DOMException) = 0; + + /** + * + */ + virtual DOMConfiguration *getDomConfig() = 0; + + /** + * + */ + virtual void normalizeDocument() = 0; + + /** + * + */ + virtual Node *renameNode(const Node *n, + const DOMString &namespaceURI, + const DOMString &qualifiedName) + throw (DOMException) = 0; + + + //################## + //# Non-API methods + //################## + + /** + * + */ + virtual ~Document() {} + +}; + + + + + + + + + + + +} //namespace dom +} //namespace w3c +} //namespace org + + +#endif // __DOM_H__ + + +/*######################################################################### +## E N D O F F I L E +#########################################################################*/ + + + + diff --git a/src/dom/dom.idl b/src/dom/dom.idl new file mode 100755 index 000000000..4c9dcbfe2 --- /dev/null +++ b/src/dom/dom.idl @@ -0,0 +1,548 @@ +/* + * Copyright (c) 2004 World Wide Web Consortium, + * + * (Massachusetts Institute of Technology, European Research Consortium for + * Informatics and Mathematics, Keio University). All Rights Reserved. This + * work is distributed under the W3C(r) Software License [1] in the hope that + * it will be useful, but WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * [1] http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 + */ + +// File: http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/dom.idl + +#ifndef _DOM_IDL_ +#define _DOM_IDL_ + +#pragma prefix "w3c.org" +module dom +{ + + valuetype DOMString sequence; + + typedef unsigned long long DOMTimeStamp; + + typedef any DOMUserData; + + typedef Object DOMObject; + + interface DOMImplementation; + interface DocumentType; + interface Document; + interface NodeList; + interface NamedNodeMap; + interface UserDataHandler; + interface Element; + interface TypeInfo; + interface DOMLocator; + + exception DOMException { + unsigned short code; + }; + // ExceptionCode + const unsigned short INDEX_SIZE_ERR = 1; + const unsigned short DOMSTRING_SIZE_ERR = 2; + const unsigned short HIERARCHY_REQUEST_ERR = 3; + const unsigned short WRONG_DOCUMENT_ERR = 4; + const unsigned short INVALID_CHARACTER_ERR = 5; + const unsigned short NO_DATA_ALLOWED_ERR = 6; + const unsigned short NO_MODIFICATION_ALLOWED_ERR = 7; + const unsigned short NOT_FOUND_ERR = 8; + const unsigned short NOT_SUPPORTED_ERR = 9; + const unsigned short INUSE_ATTRIBUTE_ERR = 10; + // Introduced in DOM Level 2: + const unsigned short INVALID_STATE_ERR = 11; + // Introduced in DOM Level 2: + const unsigned short SYNTAX_ERR = 12; + // Introduced in DOM Level 2: + const unsigned short INVALID_MODIFICATION_ERR = 13; + // Introduced in DOM Level 2: + const unsigned short NAMESPACE_ERR = 14; + // Introduced in DOM Level 2: + const unsigned short INVALID_ACCESS_ERR = 15; + // Introduced in DOM Level 3: + const unsigned short VALIDATION_ERR = 16; + // Introduced in DOM Level 3: + const unsigned short TYPE_MISMATCH_ERR = 17; + + + // Introduced in DOM Level 3: + interface DOMStringList { + DOMString item(in unsigned long index); + readonly attribute unsigned long length; + boolean contains(in DOMString str); + }; + + // Introduced in DOM Level 3: + interface NameList { + DOMString getName(in unsigned long index); + DOMString getNamespaceURI(in unsigned long index); + readonly attribute unsigned long length; + boolean contains(in DOMString str); + boolean containsNS(in DOMString namespaceURI, + in DOMString name); + }; + + // Introduced in DOM Level 3: + interface DOMImplementationList { + DOMImplementation item(in unsigned long index); + readonly attribute unsigned long length; + }; + + // Introduced in DOM Level 3: + interface DOMImplementationSource { + DOMImplementation getDOMImplementation(in DOMString features); + DOMImplementationList getDOMImplementationList(in DOMString features); + }; + + interface DOMImplementation { + boolean hasFeature(in DOMString feature, + in DOMString version); + // Introduced in DOM Level 2: + DocumentType createDocumentType(in DOMString qualifiedName, + in DOMString publicId, + in DOMString systemId) + raises(DOMException); + // Introduced in DOM Level 2: + Document createDocument(in DOMString namespaceURI, + in DOMString qualifiedName, + in DocumentType doctype) + raises(DOMException); + // Introduced in DOM Level 3: + DOMObject getFeature(in DOMString feature, + in DOMString version); + }; + + interface Node { + + // NodeType + const unsigned short ELEMENT_NODE = 1; + const unsigned short ATTRIBUTE_NODE = 2; + const unsigned short TEXT_NODE = 3; + const unsigned short CDATA_SECTION_NODE = 4; + const unsigned short ENTITY_REFERENCE_NODE = 5; + const unsigned short ENTITY_NODE = 6; + const unsigned short PROCESSING_INSTRUCTION_NODE = 7; + const unsigned short COMMENT_NODE = 8; + const unsigned short DOCUMENT_NODE = 9; + const unsigned short DOCUMENT_TYPE_NODE = 10; + const unsigned short DOCUMENT_FRAGMENT_NODE = 11; + const unsigned short NOTATION_NODE = 12; + + readonly attribute DOMString nodeName; + attribute DOMString nodeValue; + // raises(DOMException) on setting + // raises(DOMException) on retrieval + + readonly attribute unsigned short nodeType; + readonly attribute Node parentNode; + readonly attribute NodeList childNodes; + readonly attribute Node firstChild; + readonly attribute Node lastChild; + readonly attribute Node previousSibling; + readonly attribute Node nextSibling; + readonly attribute NamedNodeMap attributes; + // Modified in DOM Level 2: + readonly attribute Document ownerDocument; + // Modified in DOM Level 3: + Node insertBefore(in Node newChild, + in Node refChild) + raises(DOMException); + // Modified in DOM Level 3: + Node replaceChild(in Node newChild, + in Node oldChild) + raises(DOMException); + // Modified in DOM Level 3: + Node removeChild(in Node oldChild) + raises(DOMException); + // Modified in DOM Level 3: + Node appendChild(in Node newChild) + raises(DOMException); + boolean hasChildNodes(); + Node cloneNode(in boolean deep); + // Modified in DOM Level 3: + void normalize(); + // Introduced in DOM Level 2: + boolean isSupported(in DOMString feature, + in DOMString version); + // Introduced in DOM Level 2: + readonly attribute DOMString namespaceURI; + // Introduced in DOM Level 2: + attribute DOMString prefix; + // raises(DOMException) on setting + + // Introduced in DOM Level 2: + readonly attribute DOMString localName; + // Introduced in DOM Level 2: + boolean hasAttributes(); + // Introduced in DOM Level 3: + readonly attribute DOMString baseURI; + + // DocumentPosition + const unsigned short DOCUMENT_POSITION_DISCONNECTED = 0x01; + const unsigned short DOCUMENT_POSITION_PRECEDING = 0x02; + const unsigned short DOCUMENT_POSITION_FOLLOWING = 0x04; + const unsigned short DOCUMENT_POSITION_CONTAINS = 0x08; + const unsigned short DOCUMENT_POSITION_CONTAINED_BY = 0x10; + const unsigned short DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC = 0x20; + + // Introduced in DOM Level 3: + unsigned short compareDocumentPosition(in Node other) + raises(DOMException); + // Introduced in DOM Level 3: + attribute DOMString textContent; + // raises(DOMException) on setting + // raises(DOMException) on retrieval + + // Introduced in DOM Level 3: + boolean isSameNode(in Node other); + // Introduced in DOM Level 3: + DOMString lookupPrefix(in DOMString namespaceURI); + // Introduced in DOM Level 3: + boolean isDefaultNamespace(in DOMString namespaceURI); + // Introduced in DOM Level 3: + DOMString lookupNamespaceURI(in DOMString prefix); + // Introduced in DOM Level 3: + boolean isEqualNode(in Node arg); + // Introduced in DOM Level 3: + DOMObject getFeature(in DOMString feature, + in DOMString version); + // Introduced in DOM Level 3: + DOMUserData setUserData(in DOMString key, + in DOMUserData data, + in UserDataHandler handler); + // Introduced in DOM Level 3: + DOMUserData getUserData(in DOMString key); + }; + + interface NodeList { + Node item(in unsigned long index); + readonly attribute unsigned long length; + }; + + interface NamedNodeMap { + Node getNamedItem(in DOMString name); + Node setNamedItem(in Node arg) + raises(DOMException); + Node removeNamedItem(in DOMString name) + raises(DOMException); + Node item(in unsigned long index); + readonly attribute unsigned long length; + // Introduced in DOM Level 2: + Node getNamedItemNS(in DOMString namespaceURI, + in DOMString localName) + raises(DOMException); + // Introduced in DOM Level 2: + Node setNamedItemNS(in Node arg) + raises(DOMException); + // Introduced in DOM Level 2: + Node removeNamedItemNS(in DOMString namespaceURI, + in DOMString localName) + raises(DOMException); + }; + + interface CharacterData : Node { + attribute DOMString data; + // raises(DOMException) on setting + // raises(DOMException) on retrieval + + readonly attribute unsigned long length; + DOMString substringData(in unsigned long offset, + in unsigned long count) + raises(DOMException); + void appendData(in DOMString arg) + raises(DOMException); + void insertData(in unsigned long offset, + in DOMString arg) + raises(DOMException); + void deleteData(in unsigned long offset, + in unsigned long count) + raises(DOMException); + void replaceData(in unsigned long offset, + in unsigned long count, + in DOMString arg) + raises(DOMException); + }; + + interface Attr : Node { + readonly attribute DOMString name; + readonly attribute boolean specified; + attribute DOMString value; + // raises(DOMException) on setting + + // Introduced in DOM Level 2: + readonly attribute Element ownerElement; + // Introduced in DOM Level 3: + readonly attribute TypeInfo schemaTypeInfo; + // Introduced in DOM Level 3: + readonly attribute boolean isId; + }; + + interface Element : Node { + readonly attribute DOMString tagName; + DOMString getAttribute(in DOMString name); + void setAttribute(in DOMString name, + in DOMString value) + raises(DOMException); + void removeAttribute(in DOMString name) + raises(DOMException); + Attr getAttributeNode(in DOMString name); + Attr setAttributeNode(in Attr newAttr) + raises(DOMException); + Attr removeAttributeNode(in Attr oldAttr) + raises(DOMException); + NodeList getElementsByTagName(in DOMString name); + // Introduced in DOM Level 2: + DOMString getAttributeNS(in DOMString namespaceURI, + in DOMString localName) + raises(DOMException); + // Introduced in DOM Level 2: + void setAttributeNS(in DOMString namespaceURI, + in DOMString qualifiedName, + in DOMString value) + raises(DOMException); + // Introduced in DOM Level 2: + void removeAttributeNS(in DOMString namespaceURI, + in DOMString localName) + raises(DOMException); + // Introduced in DOM Level 2: + Attr getAttributeNodeNS(in DOMString namespaceURI, + in DOMString localName) + raises(DOMException); + // Introduced in DOM Level 2: + Attr setAttributeNodeNS(in Attr newAttr) + raises(DOMException); + // Introduced in DOM Level 2: + NodeList getElementsByTagNameNS(in DOMString namespaceURI, + in DOMString localName) + raises(DOMException); + // Introduced in DOM Level 2: + boolean hasAttribute(in DOMString name); + // Introduced in DOM Level 2: + boolean hasAttributeNS(in DOMString namespaceURI, + in DOMString localName) + raises(DOMException); + // Introduced in DOM Level 3: + readonly attribute TypeInfo schemaTypeInfo; + // Introduced in DOM Level 3: + void setIdAttribute(in DOMString name, + in boolean isId) + raises(DOMException); + // Introduced in DOM Level 3: + void setIdAttributeNS(in DOMString namespaceURI, + in DOMString localName, + in boolean isId) + raises(DOMException); + // Introduced in DOM Level 3: + void setIdAttributeNode(in Attr idAttr, + in boolean isId) + raises(DOMException); + }; + + interface Text : CharacterData { + Text splitText(in unsigned long offset) + raises(DOMException); + // Introduced in DOM Level 3: + readonly attribute boolean isElementContentWhitespace; + // Introduced in DOM Level 3: + readonly attribute DOMString wholeText; + // Introduced in DOM Level 3: + Text replaceWholeText(in DOMString content) + raises(DOMException); + }; + + interface Comment : CharacterData { + }; + + // Introduced in DOM Level 3: + interface TypeInfo { + readonly attribute DOMString typeName; + readonly attribute DOMString typeNamespace; + + // DerivationMethods + const unsigned long DERIVATION_RESTRICTION = 0x00000001; + const unsigned long DERIVATION_EXTENSION = 0x00000002; + const unsigned long DERIVATION_UNION = 0x00000004; + const unsigned long DERIVATION_LIST = 0x00000008; + + boolean isDerivedFrom(in DOMString typeNamespaceArg, + in DOMString typeNameArg, + in unsigned long derivationMethod); + }; + + // Introduced in DOM Level 3: + interface UserDataHandler { + + // OperationType + const unsigned short NODE_CLONED = 1; + const unsigned short NODE_IMPORTED = 2; + const unsigned short NODE_DELETED = 3; + const unsigned short NODE_RENAMED = 4; + const unsigned short NODE_ADOPTED = 5; + + void handle(in unsigned short operation, + in DOMString key, + in DOMUserData data, + in Node src, + in Node dst); + }; + + // Introduced in DOM Level 3: + interface DOMError { + + // ErrorSeverity + const unsigned short SEVERITY_WARNING = 1; + const unsigned short SEVERITY_ERROR = 2; + const unsigned short SEVERITY_FATAL_ERROR = 3; + + readonly attribute unsigned short severity; + readonly attribute DOMString message; + readonly attribute DOMString type; + readonly attribute DOMObject relatedException; + readonly attribute DOMObject relatedData; + readonly attribute DOMLocator location; + }; + + // Introduced in DOM Level 3: + interface DOMErrorHandler { + boolean handleError(in DOMError error); + }; + + // Introduced in DOM Level 3: + interface DOMLocator { + readonly attribute long lineNumber; + readonly attribute long columnNumber; + readonly attribute long byteOffset; + readonly attribute long utf16Offset; + readonly attribute Node relatedNode; + readonly attribute DOMString uri; + }; + + // Introduced in DOM Level 3: + interface DOMConfiguration { + void setParameter(in DOMString name, + in DOMUserData value) + raises(DOMException); + DOMUserData getParameter(in DOMString name) + raises(DOMException); + boolean canSetParameter(in DOMString name, + in DOMUserData value); + readonly attribute DOMStringList parameterNames; + }; + + interface CDATASection : Text { + }; + + interface DocumentType : Node { + readonly attribute DOMString name; + readonly attribute NamedNodeMap entities; + readonly attribute NamedNodeMap notations; + // Introduced in DOM Level 2: + readonly attribute DOMString publicId; + // Introduced in DOM Level 2: + readonly attribute DOMString systemId; + // Introduced in DOM Level 2: + readonly attribute DOMString internalSubset; + }; + + interface Notation : Node { + readonly attribute DOMString publicId; + readonly attribute DOMString systemId; + }; + + interface Entity : Node { + readonly attribute DOMString publicId; + readonly attribute DOMString systemId; + readonly attribute DOMString notationName; + // Introduced in DOM Level 3: + readonly attribute DOMString inputEncoding; + // Introduced in DOM Level 3: + readonly attribute DOMString xmlEncoding; + // Introduced in DOM Level 3: + readonly attribute DOMString xmlVersion; + }; + + interface EntityReference : Node { + }; + + interface ProcessingInstruction : Node { + readonly attribute DOMString target; + attribute DOMString data; + // raises(DOMException) on setting + + }; + + interface DocumentFragment : Node { + }; + + interface Document : Node { + // Modified in DOM Level 3: + readonly attribute DocumentType doctype; + readonly attribute DOMImplementation implementation; + readonly attribute Element documentElement; + Element createElement(in DOMString tagName) + raises(DOMException); + DocumentFragment createDocumentFragment(); + Text createTextNode(in DOMString data); + Comment createComment(in DOMString data); + CDATASection createCDATASection(in DOMString data) + raises(DOMException); + ProcessingInstruction createProcessingInstruction(in DOMString target, + in DOMString data) + raises(DOMException); + Attr createAttribute(in DOMString name) + raises(DOMException); + EntityReference createEntityReference(in DOMString name) + raises(DOMException); + NodeList getElementsByTagName(in DOMString tagname); + // Introduced in DOM Level 2: + Node importNode(in Node importedNode, + in boolean deep) + raises(DOMException); + // Introduced in DOM Level 2: + Element createElementNS(in DOMString namespaceURI, + in DOMString qualifiedName) + raises(DOMException); + // Introduced in DOM Level 2: + Attr createAttributeNS(in DOMString namespaceURI, + in DOMString qualifiedName) + raises(DOMException); + // Introduced in DOM Level 2: + NodeList getElementsByTagNameNS(in DOMString namespaceURI, + in DOMString localName); + // Introduced in DOM Level 2: + Element getElementById(in DOMString elementId); + // Introduced in DOM Level 3: + readonly attribute DOMString inputEncoding; + // Introduced in DOM Level 3: + readonly attribute DOMString xmlEncoding; + // Introduced in DOM Level 3: + attribute boolean xmlStandalone; + // raises(DOMException) on setting + + // Introduced in DOM Level 3: + attribute DOMString xmlVersion; + // raises(DOMException) on setting + + // Introduced in DOM Level 3: + attribute boolean strictErrorChecking; + // Introduced in DOM Level 3: + attribute DOMString documentURI; + // Introduced in DOM Level 3: + Node adoptNode(in Node source) + raises(DOMException); + // Introduced in DOM Level 3: + readonly attribute DOMConfiguration domConfig; + // Introduced in DOM Level 3: + void normalizeDocument(); + // Introduced in DOM Level 3: + Node renameNode(in Node n, + in DOMString namespaceURI, + in DOMString qualifiedName) + raises(DOMException); + }; +}; + +#endif // _DOM_IDL_ + diff --git a/src/dom/domimpl.cpp b/src/dom/domimpl.cpp new file mode 100755 index 000000000..b3197c948 --- /dev/null +++ b/src/dom/domimpl.cpp @@ -0,0 +1,2984 @@ +/** + * Phoebe DOM Implementation. + * + * This is a C++ approximation of the W3C DOM model, which follows + * fairly closely the specifications in the various .idl files, copies of + * which are provided for reference. Most important is this one: + * + * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/idl-definitions.html + * + * Authors: + * Bob Jamison + * + * Copyright (C) 2005 Bob Jamison + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +#include "domimpl.h" + +namespace org +{ +namespace w3c +{ +namespace dom +{ + + +/** + * Test if the given substring exists for the length of the string + * in a given buffer + */ +/* +static bool match(const DOMString &buf, char *str) +{ + int pos = 0; + while (*str) + { + if (buf[pos++] != *str++) + return false; + } + return true; +} +*/ + + + +/*######################################################################### +## DOMImplementationSourceImpl +#########################################################################*/ + + +/** + * + */ +DOMImplementationSourceImpl::DOMImplementationSourceImpl() +{ + domImpl = new DOMImplementationImpl(); +} + +/** + * + */ +DOMImplementationSourceImpl::~DOMImplementationSourceImpl() +{ + delete domImpl; +} + +/** + * + */ +DOMImplementation *DOMImplementationSourceImpl::getDOMImplementation( + const DOMString &features) +{ + return domImpl; +} + +/** + * + */ +DOMImplementationList DOMImplementationSourceImpl::getDOMImplementationList( + const DOMString &features) +{ + return domImplList; +} + + + + + + + +/*######################################################################### +## DOMImplementationImpl +#########################################################################*/ + + +/** + * + */ +DOMImplementationImpl::DOMImplementationImpl() +{ +} + +/** + * + */ +DOMImplementationImpl::~DOMImplementationImpl() +{ +} + +/** + * + */ +bool DOMImplementationImpl::hasFeature(const DOMString& feature, + const DOMString& version) +{ + return false; +} + + +/** + * + */ +DocumentType *DOMImplementationImpl::createDocumentType(const DOMString& qualifiedName, + const DOMString& publicId, + const DOMString& systemId) + throw(DOMException) +{ + DocumentTypeImpl *typeImpl = new DocumentTypeImpl(qualifiedName, + publicId, systemId); + return typeImpl; +} + +/** + * + */ +Document *DOMImplementationImpl::createDocument( + const DOMString& namespaceURI, + const DOMString& qualifiedName, + DocumentType *doctype) + throw(DOMException) +{ + DocumentImpl *doc = new DocumentImpl(this, + namespaceURI, + qualifiedName, + doctype); + return doc; +} + +/** + * + */ +DOMObject *DOMImplementationImpl::getFeature(const DOMString& feature, + const DOMString& version) + +{ + return NULL; +} + + + + + +/*######################################################################### +## NodeImpl +#########################################################################*/ + +/** + * Utility for finding the first Element above + * a given node. Used by several methods below + */ +static Node *getAncestorElement(Node *node) +{ + if (!node) + return NULL; + node = node->getParentNode(); + //Either quit because I am an element, or because I am null + while (node) + { + if (node->getNodeType() == Node::ELEMENT_NODE) + return node; + node = node->getParentNode(); + } + return node; +} + +/** + * + */ +DOMString NodeImpl::getNodeName() +{ + return nodeName; +} + +/** + * + */ +DOMString NodeImpl::getNodeValue() throw (DOMException) +{ + return nodeValue; +} + +/** + * + */ +void NodeImpl::setNodeValue(const DOMString& val) throw (DOMException) +{ + nodeValue = val; +} + +/** + * + */ +unsigned short NodeImpl::getNodeType() +{ + return nodeType; +} + +/** + * + */ +Node *NodeImpl::getParentNode() +{ + return parent; +} + +/** + * + */ +NodeList NodeImpl::getChildNodes() +{ + NodeList list; + for (NodeImpl *node = firstChild ; node ; node=node->next) + list.add(node); + return list; +} + +/** + * + */ +Node *NodeImpl::getFirstChild() +{ + return firstChild; +} + +/** + * + */ +Node *NodeImpl::getLastChild() +{ + return lastChild; +} + +/** + * + */ +Node *NodeImpl::getPreviousSibling() +{ + return prev; +} + +/** + * + */ +Node *NodeImpl::getNextSibling() +{ + return next; +} + +/** + * + */ +NamedNodeMap &NodeImpl::getAttributes() +{ + NamedNodeMap &attrs = attributes; + return attrs; +} + + +/** + * + */ +Document *NodeImpl::getOwnerDocument() +{ + return ownerDocument; +} + +/** + * + */ +Node *NodeImpl::insertBefore(const Node *newChild, + const Node *refChild) + throw(DOMException) +{ + Node *node = NULL; + return node; +} + +/** + * + */ +Node *NodeImpl::replaceChild(const Node *newChild, + const Node *oldChild) + throw(DOMException) +{ + Node *node = NULL; + return node; +} + +/** + * + */ +Node *NodeImpl::removeChild(const Node *oldChild) + throw(DOMException) +{ + Node *node = NULL; + return node; +} + +/** + * + */ +Node *NodeImpl::appendChild(const Node *newChild) + throw(DOMException) +{ + if (!newChild) + return NULL; + + Node *child = (Node *)newChild; + NodeImpl *childImpl = dynamic_cast (child); + + childImpl->parent = this; + childImpl->ownerDocument = ownerDocument; + + if (!firstChild || !lastChild) + { + //Set up our first member + firstChild = childImpl; + lastChild = childImpl; + } + else + { + //link at the last position + lastChild->next = childImpl; + childImpl->prev = lastChild; + lastChild = childImpl; + } + + return child; +} + +/** + * + */ +bool NodeImpl::hasChildNodes() +{ + return (firstChild != NULL); +} + +/** + * + */ +Node *NodeImpl::cloneNode(bool deep) +{ + NodeImpl *node = new NodeImpl(ownerDocument, nodeName); + node->parent = parent; + node->prev = prev; + node->next = next; + node->userData = userData; + node->nodeValue = nodeValue; + + if (deep) + { + node->firstChild = node->lastChild = NULL; + for (NodeImpl *child = firstChild ; child ; child=child->next) + { + node->appendChild(child->cloneNode(deep)); + } + } + else + { + node->firstChild = firstChild; + node->lastChild = lastChild; + } + + return node; +} + +/** + * Concatenate adjoining text subnodes, remove null-length nodes + */ +void NodeImpl::normalize() +{ + //First, concatenate adjoining text nodes + NodeImpl *next = NULL; + for (NodeImpl *child = firstChild ; child ; child=next) + { + if (child->getNodeType() != Node::TEXT_NODE) + continue; + next = NULL; + DOMString sval = child->getNodeValue(); + for (NodeImpl *sibling = child->next ; sibling ; sibling=next) + { + next = sibling->next; + if (sibling->getNodeType() != Node::TEXT_NODE) + break; + sval.append(sibling->getNodeValue()); + //unlink and delete + child->next = sibling->next; + if (sibling->next) + sibling->next->prev = child; + delete sibling; + } + child->setNodeValue(sval); + } + + //Next, we remove zero-length text subnodes + next = NULL; + for (NodeImpl *child = firstChild ; child ; child=next) + { + next = child->next; + if (child->getNodeType() != Node::TEXT_NODE) + continue; + if (child->getNodeValue().size() == 0) + { + //unlink and delete + if (child->prev) + child->prev->next = child->next; + if (child->next) + child->next->prev = child->prev; + delete child; + } + } + +} + +/** + * + */ +bool NodeImpl::isSupported(const DOMString& feature, + const DOMString& version) +{ + //again, no idea + return false; +} + +/** + * + */ +DOMString NodeImpl::getNamespaceURI() +{ + return namespaceURI; +} + +/** + * + */ +DOMString NodeImpl::getPrefix() +{ + return prefix; +} + +/** + * + */ +void NodeImpl::setPrefix(const DOMString& val) throw(DOMException) +{ + prefix = val; + if (prefix.size()>0) + nodeName = prefix + ":" + localName; + else + nodeName = localName; +} + +/** + * + */ +DOMString NodeImpl::getLocalName() +{ + return localName; +} + +/** + * + */ +bool NodeImpl::hasAttributes() +{ + return (attributes.getLength() > 0); +} + +/** + * + */ +DOMString NodeImpl::getBaseURI() +{ + return baseURI; +} + +/** + * + */ +unsigned short NodeImpl::compareDocumentPosition(const Node *otherArg) +{ + if (!otherArg || this == otherArg) + return 0;//no flags + + Node *node; + Node *other = (Node *)otherArg; + + //Look above me + for (node=getParentNode() ; node ; node=node->getParentNode()) + if (node == other) + return DOCUMENT_POSITION_CONTAINED_BY; + + //Look above the other guy. See me? + for (node=other->getParentNode() ; node ; node=node->getParentNode()) + if (node == this) + return DOCUMENT_POSITION_CONTAINS; + + + return DOCUMENT_POSITION_DISCONNECTED | + DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC; +} + +/** + * + */ +DOMString NodeImpl::getTextContext() throw(DOMException) +{ + //no idea + return DOMString(""); +} + + +/** + * + */ +void NodeImpl::setTextContext(const DOMString &val) throw(DOMException) +{ + //no idea +} + + +/** + * From DOM3 Namespace algorithms + */ +DOMString NodeImpl::lookupPrefix(const DOMString &theNamespaceURI) +{ + + if (theNamespaceURI.size()==0) + { + return DOMString(""); + } + + switch (nodeType) + { + case Node::ELEMENT_NODE: + { + ElementImpl *elem = (ElementImpl *)this; + return lookupNamespacePrefix(theNamespaceURI, elem); + } + case Node::DOCUMENT_NODE: + { + Document *doc = (Document *)this; + Element *elem = doc->getDocumentElement(); + return elem->lookupPrefix(theNamespaceURI); + } + case Node::ENTITY_NODE : + case Node::NOTATION_NODE: + case Node::DOCUMENT_FRAGMENT_NODE: + case Node::DOCUMENT_TYPE_NODE: + return DOMString(""); // type is unknown + case Node::ATTRIBUTE_NODE: + { + Attr *attr = (Attr *)this; + Element *elem = (Element *)attr->getOwnerElement(); + if ( elem ) + { + return elem->lookupPrefix(theNamespaceURI); + } + return DOMString(""); + } + default: + { + //Get ancestor element, if any + if ( Node *ancestor = getAncestorElement(this) ) + { + return ancestor->lookupPrefix(theNamespaceURI); + } + return DOMString(""); + } + }//switch + return DOMString(""); +} + + +/** + * + */ +bool NodeImpl::isDefaultNamespace(const DOMString &theNamespaceURI) +{ + switch (nodeType) + { + case ELEMENT_NODE: + if ( namespaceURI.size()>0 && prefix.size()==0 ) + { + return (namespaceURI == theNamespaceURI); + } + if ( Node *attr = attributes.getNamedItem("xmlns")) + { + return (attr->getNodeValue() == theNamespaceURI); + } + + + if ( Node *ancestor = getAncestorElement(this) ) + { + return ancestor->isDefaultNamespace(theNamespaceURI); + } + else + { + return false; + } + case DOCUMENT_NODE: + { //just use braces for local declaration + Document *doc = (Document *)this; + Element *elem = doc->getDocumentElement(); + return elem->isDefaultNamespace(theNamespaceURI); + } + case ENTITY_NODE: + case NOTATION_NODE: + case DOCUMENT_TYPE_NODE: + case DOCUMENT_FRAGMENT_NODE: + return false; + case ATTRIBUTE_NODE: + {//braces only for scope + Attr *attr = (Attr *)this; + Element *ownerElement = attr->getOwnerElement(); + if ( ownerElement ) + { + return ownerElement->isDefaultNamespace(theNamespaceURI); + } + else + { + return false; + } + } + default: + if ( Node *ancestor = getAncestorElement(this) ) + { + return ancestor->isDefaultNamespace(theNamespaceURI); + } + else + { + return false; + } + }//switch + + return false; +} + + +/** + * + */ +DOMString NodeImpl::lookupNamespaceURI(const DOMString &thePrefix) +{ + switch (nodeType) + { + case ELEMENT_NODE: + { + if ( namespaceURI.size()>0 && prefix == thePrefix ) + { + DOMString nsURI = namespaceURI; + return (nsURI); + } + if ( hasAttributes() ) + { + NamedNodeMap attributes = getAttributes(); + int nrAttrs = attributes.getLength(); + for (int i=0 ; igetPrefix() == "xmlns" && attr->getLocalName() == thePrefix ) + { // non default namespace + if (attr->getNodeValue().size()>0) + { + return (attr->getNodeValue()); + } + return DOMString(""); + } + else if (attr->getLocalName() == "xmlns" && thePrefix.size()==0) + { // default namespace + if (attr->getNodeValue().size()>0) + { + return (attr->getNodeValue()); + } + return DOMString(""); + } + } + } + + if ( Node *ancestor = getAncestorElement(this) ) + { + return ancestor->lookupNamespaceURI(thePrefix); + } + return DOMString(""); + } + case DOCUMENT_NODE: + { + Document *doc = (Document *)this; + Element *elem = doc->getDocumentElement(); + return elem->lookupNamespaceURI(thePrefix); + } + case ENTITY_NODE: + case NOTATION_NODE: + case DOCUMENT_TYPE_NODE: + case DOCUMENT_FRAGMENT_NODE: + return DOMString(""); + + case ATTRIBUTE_NODE: + { + if (Element *ownerElement = ((Attr *)this)->getOwnerElement()) + { + return ownerElement->lookupNamespaceURI(thePrefix); + } + else + { + return DOMString(""); + } + } + default: + if ( Node *ancestor = getAncestorElement(this) ) + { + return ancestor->lookupNamespaceURI(thePrefix); + } + else + { + return DOMString(""); + } + }//switch +} + + +/** + * + */ +bool NodeImpl::isEqualNode(const Node *nodeArg) +{ + if (!nodeArg) + return false; + + if (this == nodeArg) + return true; + + Node *node = (Node *)nodeArg; + + if (getNodeType() != node->getNodeType() || + getNodeName() != node->getNodeName() || + getLocalName() != node->getLocalName() || + getNamespaceURI() != node->getNamespaceURI() || + getPrefix() != node->getPrefix() || + getNodeValue() != node->getNodeValue() || + getBaseURI() != node->getBaseURI() ) + return false; + + return true; +} + + + +/** + * + */ +DOMObject *NodeImpl::getFeature(const DOMString &feature, + const DOMString &version) +{ + //dont know + return NULL; +} + +/** + * + */ +DOMUserData *NodeImpl::setUserData(const DOMString &key, + const DOMUserData *data, + const UserDataHandler *handler) +{ + UserDataEntry *entry = userDataEntries; + UserDataEntry *prev = NULL; + while (entry) + { + if (entry->key == key) + { + DOMUserData *oldData = entry->data; + entry->data = (DOMUserData *)data; + entry->handler = (UserDataHandler *)handler; + return oldData; + } + prev = entry; + entry = entry->next; + } + + //Make a new one + UserDataEntry *newEntry = new UserDataEntry(key, data, handler); + if (!prev) + userDataEntries = newEntry; + else + prev->next = newEntry; + + return NULL; +} + +/** + * + */ +DOMUserData *NodeImpl::getUserData(const DOMString &key) +{ + UserDataEntry *entry = userDataEntries; + while (entry) + { + if (entry->key == key) + return entry->data; + entry = entry->next; + } + return NULL; +} + + + +//################## +//# Non-API methods +//################## + +/** + * + */ +void NodeImpl::setNodeName(const DOMString &qualifiedName) +{ + nodeName = qualifiedName; + prefix = ""; + localName = ""; + for (unsigned int i=0 ; i0 && namespaceURI==theNamespaceURI && + prefix.size()>0 && + originalElement->lookupNamespaceURI(prefix) == theNamespaceURI) + { + return (prefix); + } + + if ( hasAttributes() ) + { + NamedNodeMap attributes = getAttributes(); + int nrAttrs = attributes.getLength(); + for (int i=0 ; igetLocalName(); + if (attr->getPrefix() == "xmlns" && + attr->getNodeValue() == theNamespaceURI && + originalElement->lookupNamespaceURI(attrLocalName) + == theNamespaceURI) + { + return (attrLocalName); + } + } + } + + //Get ancestor element, if any + NodeImpl *ancestor = parent; + while (ancestor && ancestor->getNodeType()!= Node::ELEMENT_NODE) + ancestor = ancestor->parent; + + if ( ancestor ) + { + return ancestor->lookupNamespacePrefix(theNamespaceURI, originalElement); + } + + return DOMString(""); +} + + +/** + * + */ +NodeImpl::NodeImpl() +{ + init(); +} + + + + +/** + * + */ +NodeImpl::NodeImpl(DocumentImpl *owner) +{ + init(); + ownerDocument = owner; +} + +/** + * + */ +NodeImpl::NodeImpl(DocumentImpl *owner, const DOMString &nodeName) +{ + init(); + ownerDocument = owner; + setNodeName(nodeName); +} + +/** + * + */ +NodeImpl::NodeImpl(DocumentImpl *owner, const DOMString &theNamespaceURI, + const DOMString &qualifiedName) +{ + init(); + ownerDocument = owner; + //if (owner) + // namespaceURI = owner->stringCache(theNamespaceURI); + setNodeName(qualifiedName); +} + + + +/** + * + */ +void NodeImpl::init() +{ + nodeType = 0; //none yet + nodeValue = ""; + setNodeName(""); + namespaceURI = ""; + parent = NULL; + prev = NULL; + next = NULL; + userData = NULL; + firstChild = NULL; + lastChild = NULL; + ownerDocument = NULL; + userDataEntries = NULL; +} + +/** + * + */ +void NodeImpl::assign(const NodeImpl &other) +{ + ownerDocument = other.ownerDocument; + prefix = other.prefix; + localName = other.localName; + nodeName = other.nodeName; + nodeValue = other.nodeValue; + namespaceURI = other.namespaceURI; + attributes = other.attributes; +} + + +/** + * + */ +NodeImpl::~NodeImpl() +{ + if (userDataEntries) + delete userDataEntries; +} + + + +/*######################################################################### +## CharacterDataImpl +#########################################################################*/ + + +/** + * + */ +CharacterDataImpl::CharacterDataImpl() : NodeImpl() +{ +} + +/** + * + */ +CharacterDataImpl::CharacterDataImpl(DocumentImpl *owner, + const DOMString &theValue) : NodeImpl() +{ + ownerDocument = owner; + nodeValue = theValue; +} + +/** + * + */ +CharacterDataImpl::~CharacterDataImpl() +{ +} + +/** + * + */ +DOMString CharacterDataImpl::getData() throw(DOMException) +{ + return nodeValue; +} + +/** + * + */ +void CharacterDataImpl::setData(const DOMString& val) throw(DOMException) +{ + nodeValue = val; +} + +/** + * + */ +unsigned long CharacterDataImpl::getLength() +{ + return nodeValue.size(); +} + +/** + * + */ +DOMString CharacterDataImpl::substringData(unsigned long offset, + unsigned long count) + throw(DOMException) +{ + return nodeValue.substr(offset, count); +} + +/** + * + */ +void CharacterDataImpl::appendData(const DOMString& arg) throw(DOMException) +{ + nodeValue += arg; +} + +/** + * + */ +void CharacterDataImpl::insertData(unsigned long offset, + const DOMString& arg) + throw(DOMException) +{ + nodeValue.insert(offset, arg); +} + +/** + * + */ +void CharacterDataImpl::deleteData(unsigned long offset, + unsigned long count) + throw(DOMException) +{ + nodeValue.erase(offset, count); +} + +/** + * + */ +void CharacterDataImpl::replaceData(unsigned long offset, + unsigned long count, + const DOMString& arg) + throw(DOMException) +{ + nodeValue.replace(offset, count, arg); +} + + + + + + +/*######################################################################### +## AttrImpl +#########################################################################*/ + +/** + * + */ +DOMString AttrImpl::getName() +{ + return nodeName; +} + +/** + * + */ +bool AttrImpl::getSpecified() +{ + return (nodeValue.size() > 0); +} + +/** + * + */ +DOMString AttrImpl::getValue() +{ + return nodeValue; +} + +/** + * + */ +void AttrImpl::setValue(const DOMString& val) throw(DOMException) +{ + nodeValue = val; +} + +/** + * + */ +Element *AttrImpl::getOwnerElement() +{ + return ownerElement; +} + + +/** + * + */ +TypeInfo *AttrImpl::getSchemaTypeInfo() +{ + return NULL; +} + + +/** + * + */ +bool AttrImpl::getIsId() +{ + return (nodeName == "id"); +} + + + +//################## +//# Non-API methods +//################## + + +void AttrImpl::setOwnerElement(const Element *elem) +{ + ownerElement = (Element *)elem; +} + +/** + * + */ +AttrImpl::AttrImpl(DocumentImpl *owner, const DOMString &theName) + : NodeImpl() +{ + nodeType = ATTRIBUTE_NODE; + ownerDocument = owner; + setNodeName(theName); +} + +/** + * + */ +AttrImpl::AttrImpl(DocumentImpl *owner, + const DOMString &theNamespaceURI, + const DOMString &theQualifiedName) + : NodeImpl() +{ + nodeType = ATTRIBUTE_NODE; + ownerDocument = owner; + //if (owner) + // namespaceURI = owner->stringCache(theNamespaceURI); + setNodeName(theQualifiedName); +} + +/** + * + */ +AttrImpl::~AttrImpl() +{ +} + + + + + +/*######################################################################### +## ElementImpl +#########################################################################*/ + + +/** + * + */ +DOMString ElementImpl::getTagName() +{ + if (prefix.size() > 0) + return prefix + ":" + nodeName; + else + return nodeName; +} + +/** + * + */ +DOMString ElementImpl::getAttribute(const DOMString& name) +{ + Node *node = attributes.getNamedItem(name); + if (!node || node->getNodeType() != ATTRIBUTE_NODE) + return DOMString(""); + Attr *attr = dynamic_cast(node); + return attr->getValue(); +} + +/** + * + */ +void ElementImpl::setAttribute(const DOMString& name, + const DOMString& value) + throw(DOMException) +{ + AttrImpl *attr = new AttrImpl(ownerDocument, name); + attr->setValue(value); + attr->setOwnerElement(this); + attributes.setNamedItem(attr); +} + +/** + * + */ +void ElementImpl::removeAttribute(const DOMString& name) + throw(DOMException) +{ + attributes.removeNamedItem(name); +} + +/** + * + */ +Attr *ElementImpl::getAttributeNode(const DOMString& name) +{ + Node *node = attributes.getNamedItem(name); + if (!node || node->getNodeType() != ATTRIBUTE_NODE) + return NULL; + Attr *attr = dynamic_cast(node); + return attr; +} + +/** + * + */ +Attr *ElementImpl::setAttributeNode(Attr *attr) + throw(DOMException) +{ + attributes.setNamedItem(attr); + return attr; +} + +/** + * + */ +Attr *ElementImpl::removeAttributeNode(Attr *attr) + throw(DOMException) +{ + if (!attr) + return NULL; + attributes.removeNamedItem(attr->getName()); + return attr; +} + + +/** + * + */ +void ElementImpl::getElementsByTagNameRecursive(NodeList &list, + const DOMString& name, Element *elem) +{ + if (!elem) + return; + + if (name == elem->getTagName()) + list.add(elem); + for (Node *node = elem->getFirstChild() ; node ; node=node->getNextSibling()) + { + if (node->getNodeType() != Node::ELEMENT_NODE) + continue; + Element *childElem = dynamic_cast(node); + getElementsByTagNameRecursive(list, name, childElem); + } +} + + +/** + * + */ +NodeList ElementImpl::getElementsByTagName(const DOMString& tagName) +{ + NodeList list; + getElementsByTagNameRecursive(list, tagName, this); + return list; +} + +/** + * + */ +DOMString ElementImpl::getAttributeNS(const DOMString& namespaceURI, + const DOMString& localName) +{ + Node *node = attributes.getNamedItemNS(namespaceURI, localName); + if (!node || node->getNodeType()!=ATTRIBUTE_NODE) + return DOMString(""); + Attr *attr = dynamic_cast(node); + return attr->getValue(); +} + +/** + * + */ +void ElementImpl::setAttributeNS(const DOMString& namespaceURI, + const DOMString& qualifiedName, + const DOMString& value) + throw(DOMException) +{ + AttrImpl *attr = new AttrImpl(ownerDocument, namespaceURI, qualifiedName); + attr->setValue(value); + attr->setOwnerElement(this); + attributes.setNamedItemNS(attr); +} + +/** + * + */ +void ElementImpl::removeAttributeNS(const DOMString& namespaceURI, + const DOMString& localName) + throw(DOMException) +{ + attributes.removeNamedItemNS(namespaceURI, localName); +} + +/** + * + */ + Attr *ElementImpl::getAttributeNodeNS(const DOMString& namespaceURI, + const DOMString& localName) +{ + Node *node = attributes.getNamedItemNS(namespaceURI, localName); + if (!node || node->getNodeType() != ATTRIBUTE_NODE) + return NULL; + Attr *attr = dynamic_cast(node); + return attr; +} + +/** + * + */ +Attr *ElementImpl::setAttributeNodeNS(Attr *attr) + throw(DOMException) +{ + attributes.setNamedItemNS(attr); + return attr; +} + + +/** + * + */ +void ElementImpl::getElementsByTagNameNSRecursive(NodeList &list, + const DOMString& namespaceURI, const DOMString& tagName, Element *elem) +{ + if (!elem) + return; + + if (namespaceURI == elem->getNamespaceURI() && tagName == elem->getTagName()) + list.add(elem); + for (Node *node = elem->getFirstChild() ; node ; node=node->getNextSibling()) + { + if (node->getNodeType() != Node::ELEMENT_NODE) + continue; + Element *childElem = dynamic_cast(node); + getElementsByTagNameNSRecursive(list, namespaceURI, tagName, childElem); + } +} + +/** + * + */ +NodeList ElementImpl::getElementsByTagNameNS(const DOMString& namespaceURI, + const DOMString& localName) +{ + NodeList list; + getElementsByTagNameNSRecursive(list, namespaceURI, localName, this); + return list; +} + +/** + * + */ +bool ElementImpl::hasAttribute(const DOMString& attrName) +{ + Node *node = attributes.getNamedItem(attrName); + if (!node || node->getNodeType() != ATTRIBUTE_NODE) + return false; + return true; +} + +/** + * + */ +bool ElementImpl::hasAttributeNS(const DOMString& namespaceURI, + const DOMString& localName) +{ + Node *node = attributes.getNamedItemNS(namespaceURI, localName); + if (!node || node->getNodeType() != ATTRIBUTE_NODE) + return false; + return true; +} + +/** + * + */ +TypeInfo *ElementImpl::getSchemaTypeInto() +{ + //fixme + return NULL; +} + + +/** + * + */ +void ElementImpl::setIdAttribute(const DOMString &name, + bool isId) throw (DOMException) +{ + //fixme +} + +/** + * + */ +void ElementImpl::setIdAttributeNS(const DOMString &namespaceURI, + const DOMString &localName, + bool isId) throw (DOMException) +{ + //fixme +} + +/** + * + */ +void ElementImpl::setIdAttributeNode(const Attr *idAttr, + bool isId) throw (DOMException) +{ + //fixme +} + + +//################## +//# Non-API methods +//################## + + +/** + * + */ +ElementImpl::ElementImpl() : NodeImpl() +{ + nodeType = ELEMENT_NODE; +} + +/** + * + */ +ElementImpl::ElementImpl(DocumentImpl *owner, const DOMString &tagName) + : NodeImpl() +{ + nodeType = ELEMENT_NODE; + ownerDocument = owner; + setNodeName(tagName); +} + +/** + * + */ +ElementImpl::ElementImpl(DocumentImpl *owner, + const DOMString &theNamespaceURI, + const DOMString &qualifiedName) : + NodeImpl() +{ + nodeType = ELEMENT_NODE; + ownerDocument = owner; + setNodeName(qualifiedName); +} + +/** + * + */ +ElementImpl::~ElementImpl() +{ +} + + +/** + * + */ +void ElementImpl::normalizeNamespaces() +{ + //printf("### NORMALIZE\n"); + + NamedNodeMap attrs = getAttributes(); + + //####################################### + //# Pick up local namespace declarations + //####################################### + bindingsClear(); //Reset bindings on this node + + int nrAttrs = attrs.getLength(); + for (int i=0; igetNodeType() != Node::ATTRIBUTE_NODE) + continue; + AttrImpl *attr = dynamic_cast(attrNode); + DOMString attrNS = attr->getNamespaceURI(); + DOMString attrName = attr->getLocalName(); + DOMString attrPrefix = attr->getPrefix(); + DOMString attrValue = attr->getNodeValue(); + if (attrName != "xmlns" && attrPrefix != "xmlns") + continue; + + //is the namespace declaration is invalid? + if (attrValue == XMLNSNAME || attrName == attrPrefix) + { + // Note: The prefix xmlns is used only to declare namespace bindings and + // is by definition bound to the namespace name http://www.w3.org/2000/xmlns/. + // It must not be declared. No other prefix may be bound to this namespace name. + + //==> Report an error. + printf("normalizeNamespaces() error: Namespace %s cannot be reassigned\n", + XMLNSNAME); + + } + else + { + //==> Record the namespace declaration + attr->setNamespaceURI(XMLNSNAME); + if (attrPrefix.size() > 0) + bindingsAdd(attrPrefix, attrValue); + else + bindingsAdd("*", attrValue);//default + + } + } + + + //####################################### + //# Fixup element's namespace + //####################################### + if ( namespaceURI.size() > 0 ) + { + DOMString key = prefix; + if (key.size() == 0) + key = "*"; + DOMString binding = bindingsFind(key); + //Element's prefix/namespace pair (or default namespace, if no prefix) + // are within the scope of a binding + if ( binding == namespaceURI ) + { + //==> do nothing, declaration in scope is inherited + + // See section "B.1.1: Scope of a binding" for an example + + } + else + { + + /* + ==> Create a local namespace declaration attr for this namespace, + with Element's current prefix (or a default namespace, if + no prefix). If there's a conflicting local declaration + already present, change its value to use this namespace. + + See section "B.1.2: Conflicting namespace declaration" for an example + */ + DOMString attrName = "xmlns"; + if (prefix.size() > 0) + { + attrName.append(":"); + attrName.append(prefix); + } + setAttribute(attrName, namespaceURI); + // NOTE that this may break other nodes within this Element's + // subtree, if they're already using this prefix. + // They will be repaired when we reach them. + } + } + else // Element has no namespace URI: + { + //############################################### + //# Bob -- alter this from the specs a bit. + //# Since the XmlReader does not set namespaces, + //# do it here + //############################################### + DOMString localName = getLocalName(); + if ( localName.size()==0 ) + { + // DOM Level 1 node + /* + ==> if in process of validation against a namespace aware schema + (i.e XML Schema) report a fatal error: the processor can not recover + in this situation. + Otherwise, report an error: no namespace fixup will be performed on this node. + */ + printf("normalizeNamespaces() error: no localName\n"); + } + else + { + // Element has no pseudo-prefix + //there's a conflicting local default namespace declaration already present + if ( prefix.size()==0 ) + { + //==> change its value to use this empty namespace. + namespaceURI = bindingsFind("*"); + //setAttribute("xmlns", ""); + } + else //#BOB . I added this. + { + namespaceURI = bindingsFind(prefix); + } + // NOTE that this may break other nodes within this Element's + // subtree, if they're already using the default namespaces. + // They will be repaired when we reach them. + } + } + + + //####################################### + //# Examine and polish the attributes + //####################################### + nrAttrs = attrs.getLength(); + for (int i=0; igetNodeType() != Node::ATTRIBUTE_NODE) + continue; + Attr *attr = dynamic_cast(attrNode); + DOMString attrNS = attr->getNamespaceURI(); + DOMString attrPrefix = attr->getPrefix(); + DOMString attrValue = attr->getNodeValue(); + if (attrNS == XMLNSNAME) + continue; + + if ( attrNS.size()>0 ) //Attr[i] has a namespace URI + { + DOMString attrBinding = bindingsFind(attrPrefix); + /* + if attribute has no prefix (default namespace decl does not apply to attributes) + OR + attribute prefix is not declared + OR + conflict: attribute has a prefix that conflicts with a binding + already active in scope + */ + if ( attrPrefix.size() == 0 || attrBinding.size() == 0) + { + //namespaceURI matches an in scope declaration of one or more prefixes) + DOMString prefixForNS = lookupNamespacePrefix(attrNS, this); + if ( prefixForNS.size() > 0 ) + { + // pick the most local binding available; + // if there is more than one pick one arbitrarily + + //==> change attribute's prefix. + attr->setPrefix(prefixForNS); + } + else + { + // the current prefix is not null and it has no in scope declaration) + if ( attrPrefix.size() > 0 || attrBinding.size() == 0 ) + { + //==> declare this prefix + DOMString newAttrName = "xmlns:"; + newAttrName.append(attrPrefix); + setAttribute(newAttrName, attrNS); + bindingsAdd(attrPrefix, attrNS); + } + else + { + // find a prefix following the pattern "NS" +index (starting at 1) + // make sure this prefix is not declared in the current scope. + // create a local namespace declaration attribute + + //==> declare this prefix + char buf[16]; + sprintf(buf, "%d" , ownerDocument->namespaceIndex++); + DOMString newPrefix = "NS"; + newPrefix.append(buf); + DOMString newAttrName = "xmlns:"; + newAttrName.append(newPrefix); + setAttribute(newAttrName, attrNS); + bindingsAdd(newPrefix, attrNS); + //==> change attribute's prefix. + } + } + } + } + else // Attr has no namespace URI + { + // Attr has no localName + if ( attr->getLocalName().size() == 0 ) + { + // DOM Level 1 node + /* + ==> if in process of validation against a namespace aware schema + (i.e XML Schema) report a fatal error: the processor can not recover + in this situation. + Otherwise, report an error: no namespace fixup will be performed on this node. + */ + printf("normalizeNamespaces: no local name for attribute\n"); + } + else + { + // attr has no namespace URI and no prefix + // no action is required, since attrs don't use default + //==> do nothing + } + } + } // end for-all-Attrs + + + //####################################### + //# Recursively normalize children + //####################################### + for (Node *child=getFirstChild() ; child ; child=child->getNextSibling()) + { + if (child->getNodeType() != Node::ELEMENT_NODE) + continue; + ElementImpl *childElement = dynamic_cast(child); + childElement->normalizeNamespaces(); + } + +} + + +/*######################################################################### +## TextImpl +#########################################################################*/ + + +/** + * + */ +TextImpl::TextImpl() : CharacterDataImpl() +{ + nodeType = TEXT_NODE; + nodeName = "#text"; +} + + +/** + * + */ +TextImpl::TextImpl(DocumentImpl *owner, const DOMString &value) + : CharacterDataImpl() +{ + nodeType = TEXT_NODE; + nodeName = "#text"; + ownerDocument = owner; + nodeValue = value; +} + + +/** + * + */ +TextImpl::~TextImpl() +{ +} + +/** + * + */ +Text *TextImpl::splitText(unsigned long offset) + throw(DOMException) +{ + return NULL; +} + +/** + * + */ +bool TextImpl::getIsElementContentWhitespace() +{ + return false; +} + +/** + * + */ +DOMString TextImpl::getWholeText() +{ + return nodeValue; +} + + +/** + * + */ +Text *TextImpl::replaceWholeText(const DOMString &content) + throw(DOMException) +{ + return NULL; +} + + +/*######################################################################### +## CommentImpl +#########################################################################*/ + +/** + * + */ +CommentImpl::CommentImpl() : CharacterDataImpl() +{ + nodeType = COMMENT_NODE; + nodeName = "#comment"; +} + + +/** + * + */ +CommentImpl::CommentImpl(DocumentImpl *owner, const DOMString &value) + : CharacterDataImpl() +{ + nodeType = COMMENT_NODE; + nodeName = "#comment"; + ownerDocument = owner; + nodeValue = value; +} + + +/** + * + */ +CommentImpl::~CommentImpl() +{ +} + + + + +/*######################################################################### +## TypeInfoImpl +#########################################################################*/ + + +/** + * + */ +TypeInfoImpl::TypeInfoImpl(const DOMString &typeNamespaceArg, + const DOMString &typeNameArg, + const DerivationMethod derivationMethodArg) +{ + typeNamespace = typeNamespaceArg; + typeName = typeNameArg; + derivationMethod = derivationMethodArg; +} + + +/** + * + */ +TypeInfoImpl::~TypeInfoImpl() +{ +} + + +/** + * + */ +DOMString TypeInfoImpl::getTypeName() +{ + return typeName; +} + +/** + * + */ +DOMString TypeInfoImpl::getTypeNamespace() +{ + return typeNamespace; +} + +/** + * + */ +bool TypeInfoImpl::isDerivedFrom(const DOMString &typeNamespaceArg, + const DOMString &typeNameArg, + const DerivationMethod derivationMethodArg) +{ + if (typeNamespaceArg == typeNamespace && + typeName == typeNameArg && + derivationMethod == derivationMethodArg) + return true; + return false; +} + + + +/*######################################################################### +## UserDataHandlerImpl +#########################################################################*/ + + + +/** + * + */ +UserDataHandlerImpl::UserDataHandlerImpl() +{ +} + + +/** + * + */ +UserDataHandlerImpl::~UserDataHandlerImpl() +{ +} + +/** + * + */ +void UserDataHandlerImpl::handle(unsigned short operation, + const DOMString &key, + const DOMUserData *data, + const Node *src, + const Node *dst) +{ + //do nothing. do we need anything here? +} + + + +/*######################################################################### +## DOMErrorImpl +#########################################################################*/ + + + +/** + * + */ +DOMErrorImpl::DOMErrorImpl() +{ +} + + +/** + * + */ +DOMErrorImpl::~DOMErrorImpl() +{ +} + +/** + * + */ +unsigned short DOMErrorImpl::getSeverity() +{ + return severity; +} + +/** + * + */ +DOMString DOMErrorImpl::getMessage() +{ + return message; +} + +/** + * + */ +DOMString DOMErrorImpl::getType() +{ + return type; +} + +/** + * + */ +DOMObject *DOMErrorImpl::getRelatedException() +{ + return NULL; +} + +/** + * + */ +DOMObject *DOMErrorImpl::getRelatedData() +{ + return NULL; +} + +/** + * + */ +DOMLocator *DOMErrorImpl::getLocation() +{ + //really should fill this in + return NULL; +} + + + + +/*######################################################################### +## DOMErrorHandlerImpl +#########################################################################*/ + + + +/** + * + */ +DOMErrorHandlerImpl::DOMErrorHandlerImpl() +{ +} + + +/** + * + */ +DOMErrorHandlerImpl::~DOMErrorHandlerImpl() +{ +} + +/** + * + */ +bool DOMErrorHandlerImpl::handleError(const DOMError *error) +{ + if (!error) + return false; + return true; +} + + + + +/*######################################################################### +## DOMLocatorImpl +#########################################################################*/ + + +/** + * + */ +DOMLocatorImpl::DOMLocatorImpl() +{ +} + + +/** + * + */ +DOMLocatorImpl::~DOMLocatorImpl() +{ +} + + +/** + * + */ +long DOMLocatorImpl::getLineNumber() +{ + return lineNumber; +} + +/** + * + */ +long DOMLocatorImpl::getColumnNumber() +{ + return columnNumber; +} + +/** + * + */ +long DOMLocatorImpl::getByteOffset() +{ + return byteOffset; +} + +/** + * + */ +long DOMLocatorImpl::getUtf16Offset() +{ + return utf16Offset; +} + + +/** + * + */ +Node *DOMLocatorImpl::getRelatedNode() +{ + return relatedNode; +} + + +/** + * + */ +DOMString DOMLocatorImpl::getUri() +{ + return uri; +} + + + +/*######################################################################### +## DOMConfigurationImpl +#########################################################################*/ + + +/** + * + */ +DOMConfigurationImpl::DOMConfigurationImpl() +{ +} + + +/** + * + */ +DOMConfigurationImpl::~DOMConfigurationImpl() +{ +} + +/** + * + */ +void DOMConfigurationImpl::setParameter(const DOMString &name, + const DOMUserData *value) throw (DOMException) +{ +} + +/** + * + */ +DOMUserData *DOMConfigurationImpl::getParameter(const DOMString &name) + throw (DOMException) +{ + return NULL; +} + +/** + * + */ +bool DOMConfigurationImpl::canSetParameter(const DOMString &name, + const DOMUserData *data) +{ + return false; +} + +/** + * + */ +DOMStringList *DOMConfigurationImpl::getParameterNames() +{ + return NULL; +} + + + +/*######################################################################### +## CDATASectionImpl +#########################################################################*/ + +/** + * + */ +CDATASectionImpl::CDATASectionImpl() : TextImpl() +{ + nodeType = CDATA_SECTION_NODE; + nodeName = "#cdata-section"; +} + +/** + * + */ +CDATASectionImpl::CDATASectionImpl(DocumentImpl *owner, const DOMString &theValue) + : TextImpl() +{ + nodeType = CDATA_SECTION_NODE; + nodeName = "#cdata-section"; + ownerDocument = owner; + nodeValue = theValue; +} + + +/** + * + */ +CDATASectionImpl::~CDATASectionImpl() +{ +} + + + + + +/*######################################################################### +## DocumentTypeImpl +#########################################################################*/ + +/** + * + */ +DocumentTypeImpl::DocumentTypeImpl(const DOMString& theName, + const DOMString& thePublicId, + const DOMString& theSystemId) + : NodeImpl() +{ + nodeType = DOCUMENT_TYPE_NODE; + nodeName = theName; + publicId = thePublicId; + systemId = theSystemId; +} + +/** + * + */ +DocumentTypeImpl::~DocumentTypeImpl() +{ +} + +/** + * + */ +DOMString DocumentTypeImpl::getName() +{ + return nodeName; +} + +/** + * + */ +NamedNodeMap DocumentTypeImpl::getEntities() +{ + return entities; +} + +/** + * + */ +NamedNodeMap DocumentTypeImpl::getNotations() +{ + return notations; +} + +/** + * + */ +DOMString DocumentTypeImpl::getPublicId() +{ + return publicId; +} + +/** + * + */ +DOMString DocumentTypeImpl::getSystemId() +{ + return systemId; +} + +/** + * + */ +DOMString DocumentTypeImpl::getInternalSubset() +{ + return DOMString(""); +} + + + + + + +/*######################################################################### +## NotationImpl +#########################################################################*/ + + + +/** + * + */ +NotationImpl::NotationImpl(DocumentImpl *owner) : NodeImpl() +{ + nodeType = NOTATION_NODE; + ownerDocument = owner; +} + + +/** + * + */ +NotationImpl::~NotationImpl() +{ +} + +/** + * + */ +DOMString NotationImpl::getPublicId() +{ + return publicId; +} + +/** + * + */ +DOMString NotationImpl::getSystemId() +{ + return systemId; +} + + + + + + + + +/*######################################################################### +## EntityImpl +#########################################################################*/ + + +/** + * + */ +EntityImpl::EntityImpl() : NodeImpl() +{ + nodeType = ENTITY_NODE; +} + + +/** + * + */ +EntityImpl::EntityImpl(DocumentImpl *owner) : NodeImpl() +{ + nodeType = ENTITY_NODE; + ownerDocument = owner; +} + + +/** + * + */ +EntityImpl::~EntityImpl() +{ +} + +/** + * + */ +DOMString EntityImpl::getPublicId() +{ + return publicId; +} + +/** + * + */ +DOMString EntityImpl::getSystemId() +{ + return systemId; +} + +/** + * + */ +DOMString EntityImpl::getNotationName() +{ + return notationName; +} + +/** + * + */ +DOMString EntityImpl::getInputEncoding() +{ + return inputEncoding; +} + +/** + * + */ +DOMString EntityImpl::getXmlEncoding() +{ + return xmlEncoding; +} + +/** + * + */ +DOMString EntityImpl::getXmlVersion() +{ + return xmlVersion; +} + + + + + + +/*######################################################################### +## EntityReferenceImpl +#########################################################################*/ + + + +/** + * + */ +EntityReferenceImpl::EntityReferenceImpl() : NodeImpl() +{ + nodeType = ENTITY_REFERENCE_NODE; +} + + +/** + * + */ +EntityReferenceImpl::EntityReferenceImpl(DocumentImpl *owner, + const DOMString &theName) + : NodeImpl() +{ + nodeType = ENTITY_REFERENCE_NODE; + nodeName = theName; + ownerDocument = owner; +} + + +/** + * + */ +EntityReferenceImpl::~EntityReferenceImpl() +{ +} + + + +/*######################################################################### +## ProcessingInstructionImpl +#########################################################################*/ + + + + +/** + * + */ +ProcessingInstructionImpl::ProcessingInstructionImpl(): NodeImpl() +{ + nodeType = PROCESSING_INSTRUCTION_NODE; +} + + + +/** + * + */ +ProcessingInstructionImpl::ProcessingInstructionImpl(DocumentImpl *owner, + const DOMString &target, + const DOMString &data) + : NodeImpl() +{ + nodeType = PROCESSING_INSTRUCTION_NODE; + ownerDocument = owner; + nodeName = target; + nodeValue = data; +} + + +/** + * + */ +ProcessingInstructionImpl::~ProcessingInstructionImpl() +{ +} + + + + +/** + * + */ +DOMString ProcessingInstructionImpl::getTarget() +{ + return nodeName; +} + +/** + * + */ +DOMString ProcessingInstructionImpl::getData() +{ + return nodeValue; +} + +/** + * + */ +void ProcessingInstructionImpl::setData(const DOMString& val) throw(DOMException) +{ + //do something here +} + + + + + + + +/*######################################################################### +## DocumentFragmentImpl +#########################################################################*/ + +/** + * + */ +DocumentFragmentImpl::DocumentFragmentImpl() : NodeImpl() +{ + nodeType = DOCUMENT_FRAGMENT_NODE; + nodeName = "#document-fragment"; +} + + +/** + * + */ +DocumentFragmentImpl::DocumentFragmentImpl(DocumentImpl *owner) : NodeImpl() +{ + nodeType = DOCUMENT_FRAGMENT_NODE; + nodeName = "#document-fragment"; + ownerDocument = owner; +} + + +/** + * + */ +DocumentFragmentImpl::~DocumentFragmentImpl() +{ +} + + + + + + +/*######################################################################### +## DocumentImpl +#########################################################################*/ + + + +/** + * + */ +DocumentType *DocumentImpl::getDoctype() +{ + return doctype; +} + +/** + * + */ +DOMImplementation *DocumentImpl::getImplementation() +{ + return parent; +} + +/** + * + */ +Element *DocumentImpl::getDocumentElement() +{ + return documentElement; +} + +/** + * + */ +Element *DocumentImpl::createElement(const DOMString& tagName) + throw(DOMException) +{ + ElementImpl *impl = new ElementImpl(this, tagName); + return impl; +} + +/** + * + */ +DocumentFragment *DocumentImpl::createDocumentFragment() +{ + DocumentFragmentImpl *frag = new DocumentFragmentImpl(this); + return frag; +} + +/** + * + */ +Text *DocumentImpl::createTextNode(const DOMString& data) +{ + TextImpl *text = new TextImpl(this, data); + return text; +} + +/** + * + */ +Comment *DocumentImpl::createComment(const DOMString& data) +{ + CommentImpl *comment = new CommentImpl(this, data); + return comment; +} + +/** + * + */ +CDATASection *DocumentImpl::createCDATASection(const DOMString& data) + throw(DOMException) +{ + CDATASectionImpl *cdata = new CDATASectionImpl(this, data); + return cdata; +} + +/** + * + */ +ProcessingInstruction *DocumentImpl::createProcessingInstruction(const DOMString& target, + const DOMString& data) + throw(DOMException) +{ + ProcessingInstructionImpl *cdata = + new ProcessingInstructionImpl(this, target, data); + return cdata; +} + +/** + * + */ +Attr *DocumentImpl::createAttribute(const DOMString& attrName) + throw(DOMException) +{ + AttrImpl *attr = new AttrImpl(this, attrName); + return attr; +} + +/** + * + */ +EntityReference *DocumentImpl::createEntityReference(const DOMString& erName) + throw(DOMException) +{ + EntityReferenceImpl *ref = new EntityReferenceImpl(this, erName); + return ref; +} + + +/** + * + */ +NodeList DocumentImpl::getElementsByTagName(const DOMString& tagname) +{ + NodeList list; + ElementImpl::getElementsByTagNameRecursive(list, + tagname, documentElement); + return list; +} + + +/** + * + */ +Node *DocumentImpl::importNode(const Node *importedNode, + bool deep) + throw(DOMException) +{ + return NULL; +} + +/** + * + */ +Element *DocumentImpl::createElementNS(const DOMString& namespaceURI, + const DOMString& qualifiedName) + throw(DOMException) +{ + ElementImpl *elem = new ElementImpl(this, namespaceURI, qualifiedName); + return elem; +} + +/** + * + */ +Attr *DocumentImpl::createAttributeNS(const DOMString& namespaceURI, + const DOMString& qualifiedName) + throw(DOMException) +{ + AttrImpl *attr = new AttrImpl(this, namespaceURI, qualifiedName); + return attr; +} + + +/** + * + */ +NodeList DocumentImpl::getElementsByTagNameNS(const DOMString& namespaceURI, + const DOMString& localName) +{ + NodeList list; + ElementImpl::getElementsByTagNameNSRecursive(list, namespaceURI, + localName, documentElement); + return list; +} + +/** + * + */ +Element *DocumentImpl::getElementById(const DOMString& elementId) +{ + for (NamedElementItem *entry = elementsById.next; entry ; entry=entry->next) + if (entry->name == elementId) + return entry->elem; + return NULL; +} + + +/** + * + */ +DOMString DocumentImpl::getInputEncoding() +{ + return inputEncoding; +} + + +/** + * + */ +DOMString DocumentImpl::getXmlEncoding() +{ + return xmlEncoding; +} + +/** + * + */ +bool DocumentImpl::getXmlStandalone() +{ + return xmlStandalone; +} + +/** + * + */ +void DocumentImpl::setXmlStandalone(bool val) throw (DOMException) +{ + xmlStandalone = val; +} + +/** + * + */ +DOMString DocumentImpl::getXmlVersion() +{ + return xmlVersion; +} + +/** + * + */ +void DocumentImpl::setXmlVersion(const DOMString &version) throw (DOMException) +{ + xmlVersion = version; +} + +/** + * + */ +bool DocumentImpl::getStrictErrorChecking() +{ + return strictErrorChecking; +} + +/** + * + */ +void DocumentImpl::setStrictErrorChecking(bool val) +{ + strictErrorChecking = val; +} + + +/** + * + */ +DOMString DocumentImpl::getDocumentURI() +{ + if (!documentURI) + return DOMString(""); + DOMString docURI = *documentURI; + return docURI; +} + +/** + * + */ +void DocumentImpl::setDocumentURI(const DOMString &uri) +{ + //documentURI = stringCache(uri); +} + +/** + * + */ +Node *DocumentImpl::adoptNode(const Node *source) throw (DOMException) +{ + return (Node *)source; +} + +/** + * + */ +DOMConfiguration *DocumentImpl::getDomConfig() +{ + return domConfig; +} + +/** + * + */ +void DocumentImpl::normalizeDocument() +{ + //i assume that this means adjusting namespaces & prefixes + if (documentElement) + documentElement->normalizeNamespaces(); +} + +/** + * + */ +Node *DocumentImpl::renameNode(const Node *n, + const DOMString &namespaceURI, + const DOMString &qualifiedName) + throw (DOMException) +{ + Node *node = (Node *) n; + NodeImpl *nodeImpl = dynamic_cast (node); + //nodeImpl->namespaceURI = stringCache(namespaceURI); + nodeImpl->setNodeName(qualifiedName); + return node; +} + + + +//################## +//# Non-API methods +//################## + +/** + * + */ +DocumentImpl::DocumentImpl(const DOMImplementation *domImpl, + const DOMString &theNamespaceURI, + const DOMString &theQualifiedName, + const DocumentType *theDoctype) : NodeImpl() +{ + nodeType = DOCUMENT_NODE; + nodeName = "#document"; + parent = (DOMImplementation *)domImpl; + //documentURI = stringCache(theNamespaceURI); + qualifiedName = theQualifiedName; + if (theDoctype) //only assign if not null. + doctype = (DocumentType *)theDoctype; + else + doctype = new DocumentTypeImpl("", "", ""); + documentElement = new ElementImpl(this, "root"); + namespaceIndex = 0; +} + + +/** + * + */ +DocumentImpl::~DocumentImpl() +{ + delete documentElement; +} + + + + + + + + + + + + +} //namespace dom +} //namespace w3c +} //namespace org + + + +/*######################################################################### +## E N D O F F I L E +#########################################################################*/ + + + + diff --git a/src/dom/domimpl.h b/src/dom/domimpl.h new file mode 100755 index 000000000..677f5eb8c --- /dev/null +++ b/src/dom/domimpl.h @@ -0,0 +1,2002 @@ +#ifndef __DOMIMPL_H__ +#define __DOMIMPL_H__ +/** + * Phoebe DOM Implementation. + * + * This is a C++ approximation of the W3C DOM model, which follows + * fairly closely the specifications in the various .idl files, copies of + * which are provided for reference. Most important is this one: + * + * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/idl-definitions.html + * + * Authors: + * Bob Jamison + * + * Copyright (C) 2005 Bob Jamison + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +#include "dom.h" + +#include + +namespace org +{ +namespace w3c +{ +namespace dom +{ + + + +class DOMImplementationSourceImpl; +class DOMImplementationImpl; +class NodeImpl; +class CharacterDataImpl; +class AttrImpl; +class ElementImpl; +class TextImpl; +class CommentImpl; +class TypeInfoImpl; +class UserDataHandlerImpl; +class DOMErrorImpl; +class DOMErrorHandlerImpl; +class DOMLocatorImpl; +class DOMConfigurationImpl; +class CDATASectionImpl; +class DocumentTypeImpl; +class NotationImpl; +class EntityImpl; +class EntityReferenceImpl; +class ProcessingInstructionImpl; +class DocumentFragmentImpl; +class DocumentImpl; + + + +/*######################################################################### +## DOMImplementationSourceImpl +#########################################################################*/ + +class DOMImplementationSourceImpl : public DOMImplementationSource +{ +public: + + /** + * + */ + virtual DOMImplementation *getDOMImplementation(const DOMString &features); + + /** + * + */ + virtual DOMImplementationList getDOMImplementationList(const DOMString &features); + + + //################## + //# Non-API methods + //################## + + /** + * + */ + DOMImplementationSourceImpl(); + + /** + * + */ + virtual ~DOMImplementationSourceImpl(); + +protected: + + + DOMImplementationImpl *domImpl; + DOMImplementationList domImplList; +}; + + + + + +/*######################################################################### +## DOMImplementationImpl +#########################################################################*/ +/** + * + */ +class DOMImplementationImpl : public DOMImplementation +{ +public: + + + /** + * + */ + DOMImplementationImpl(); + + /** + * + */ + virtual ~DOMImplementationImpl(); + + /** + * + */ + virtual bool hasFeature(const DOMString& feature, const DOMString& version); + + + /** + * + */ + virtual DocumentType *createDocumentType(const DOMString& qualifiedName, + const DOMString& publicId, + const DOMString& systemId) + throw(DOMException); + + /** + * + */ + virtual Document *createDocument(const DOMString& namespaceURI, + const DOMString& qualifiedName, + DocumentType *doctype) + throw(DOMException); + /** + * + */ + virtual DOMObject *getFeature(const DOMString& feature, + const DOMString& version); + + +protected: + +}; + + + + +/*######################################################################### +## NodeImpl +#########################################################################*/ + +/** + * + */ +class NodeImpl : virtual public Node +{ + + friend class DocumentImpl; + +public: + + /** + * + */ + virtual DOMString getNodeName(); + + /** + * + */ + virtual DOMString getNodeValue() throw (DOMException); + + /** + * + */ + virtual void setNodeValue(const DOMString& val) throw (DOMException); + + /** + * + */ + virtual unsigned short getNodeType(); + + /** + * + */ + virtual Node *getParentNode(); + + /** + * + */ + virtual NodeList getChildNodes(); + + /** + * + */ + virtual Node *getFirstChild(); + + /** + * + */ + virtual Node *getLastChild(); + + /** + * + */ + virtual Node *getPreviousSibling(); + + /** + * + */ + virtual Node *getNextSibling(); + + /** + * + */ + virtual NamedNodeMap &getAttributes(); + + + /** + * + */ + virtual Document *getOwnerDocument(); + + /** + * + */ + virtual Node *insertBefore(const Node *newChild, + const Node *refChild) + throw(DOMException); + + /** + * + */ + virtual Node *replaceChild(const Node *newChild, + const Node *oldChild) + throw(DOMException); + + /** + * + */ + virtual Node *removeChild(const Node *oldChild) + throw(DOMException); + + /** + * + */ + virtual Node *appendChild(const Node *newChild) + throw(DOMException); + + /** + * + */ + virtual bool hasChildNodes(); + + /** + * + */ + virtual Node *cloneNode(bool deep); + + /** + * + */ + virtual void normalize(); + + /** + * + */ + virtual bool isSupported(const DOMString& feature, + const DOMString& version); + + /** + * + */ + virtual DOMString getNamespaceURI(); + + /** + * + */ + virtual DOMString getPrefix(); + + /** + * + */ + virtual void setPrefix(const DOMString& val) throw(DOMException); + + /** + * + */ + virtual DOMString getLocalName(); + + /** + * + */ + virtual bool hasAttributes(); + + /** + * + */ + virtual DOMString getBaseURI(); + + /** + * + */ + virtual unsigned short compareDocumentPosition(const Node *other); + + /** + * + */ + virtual DOMString getTextContext() throw(DOMException); + + + /** + * + */ + virtual void setTextContext(const DOMString &val) throw(DOMException); + + + /** + * + */ + virtual DOMString lookupPrefix(const DOMString &namespaceURI); + + + /** + * + */ + virtual bool isDefaultNamespace(const DOMString &namespaceURI); + + + /** + * + */ + virtual DOMString lookupNamespaceURI(const DOMString &prefix); + + + /** + * + */ + virtual bool isEqualNode(const Node *node); + + + + /** + * + */ + virtual DOMObject *getFeature(const DOMString &feature, + const DOMString &version); + + /** + * + */ + virtual DOMUserData *setUserData(const DOMString &key, + const DOMUserData *data, + const UserDataHandler *handler); + + + /** + * + */ + virtual DOMUserData *getUserData(const DOMString &namespaceURI); + + + //################## + //# Non-API methods + //################## + + /** + * + */ + virtual void bindingsAdd(const DOMString &prefix, const DOMString &namespaceURI) + { + bindings[prefix] = namespaceURI; + } + + /** + * + */ + virtual void bindingsClear() + { + bindings.clear(); + } + + DOMString bindingsFind(const DOMString &prefix) + { + std::map::iterator iter = + bindings.find(prefix); + if (iter != bindings.end()) + { + DOMString ret = iter->second; + return ret; + } + if (parent) + { + DOMString ret = parent->bindingsFind(prefix); + if (ret.size() > 0) + return ret; + } + return ""; + } + + /** + * + */ + virtual void setNodeName(const DOMString &qualifiedName); + + /** + * + */ + virtual void setNamespaceURI(const DOMString &theNamespaceURI); + + /** + * + */ + DOMString lookupNamespacePrefix(const DOMString &namespaceURI, + Node *originalElement); + /** + * + */ + NodeImpl(); + + /** + * + */ + NodeImpl(DocumentImpl *owner); + + /** + * + */ + NodeImpl(DocumentImpl *owner, const DOMString &nodeName); + + /** + * + */ + NodeImpl(DocumentImpl *owner, const DOMString &namespaceURI, const DOMString &nodeName); + + /** + * + */ + virtual ~NodeImpl(); + + + /** + * + */ + void assign(const NodeImpl &other); + +protected: + + /** + * Set up the internal values + */ + void init(); + + unsigned short nodeType; + + NodeImpl *parent; + + NodeImpl *prev; + + NodeImpl *next; + + DOMUserData *userData; + + DOMString prefix; + + DOMString localName; + + DOMString nodeName; + + DOMString namespaceURI; + + DOMString baseURI; + + DOMString nodeValue; + + NodeImpl *firstChild; + NodeImpl *lastChild; + + DocumentImpl *ownerDocument; + + NamedNodeMap attributes; + + class UserDataEntry + { + public: + UserDataEntry(const DOMString &theKey, + const DOMUserData *theData, + const UserDataHandler *theHandler) + { + next = NULL; + key = theKey; + data = (DOMUserData *)theData; + handler = (UserDataHandler *)theHandler; + } + ~UserDataEntry() + { + //delete anything after me, too + if (next) + delete next; + } + + UserDataEntry *next; + DOMString key; + DOMUserData *data; + UserDataHandler *handler; + }; + + UserDataEntry *userDataEntries; + + //### Our prefix->namespaceURI bindings + + std::map bindings; + + +}; + + + +/*######################################################################### +## CharacterDataImpl +#########################################################################*/ + +/** + * + */ +class CharacterDataImpl : virtual public CharacterData, protected NodeImpl +{ +public: + + /** + * + */ + virtual DOMString getData() throw(DOMException); + + /** + * + */ + virtual void setData(const DOMString& val) throw(DOMException); + + /** + * + */ + virtual unsigned long getLength(); + + /** + * + */ + virtual DOMString substringData(unsigned long offset, + unsigned long count) + throw(DOMException); + + /** + * + */ + virtual void appendData(const DOMString& arg) throw(DOMException); + + /** + * + */ + virtual void insertData(unsigned long offset, + const DOMString& arg) + throw(DOMException); + + /** + * + */ + virtual void deleteData(unsigned long offset, + unsigned long count) + throw(DOMException); + + /** + * + */ + virtual void replaceData(unsigned long offset, + unsigned long count, + const DOMString& arg) + throw(DOMException); + + + //################## + //# Non-API methods + //################## + + /** + * + */ + CharacterDataImpl(); + + + /** + * + */ + CharacterDataImpl(DocumentImpl *owner, const DOMString &value); + + /** + * + */ + virtual ~CharacterDataImpl(); + +protected: + + //'data' is the nodeValue + +}; + + + + + +/*######################################################################### +## AttrImpl +#########################################################################*/ + +/** + * + */ +class AttrImpl : virtual public Attr, public NodeImpl +{ +public: + + /** + * + */ + virtual DOMString getName(); + + /** + * + */ + virtual bool getSpecified(); + + /** + * + */ + virtual DOMString getValue(); + + /** + * + */ + virtual void setValue(const DOMString& val) throw(DOMException); + + /** + * + */ + virtual Element *getOwnerElement(); + + + /** + * + */ + virtual TypeInfo *getSchemaTypeInfo(); + + + /** + * + */ + virtual bool getIsId(); + + + + //################## + //# Non-API methods + //################## + + /** + * + */ + virtual void setOwnerElement(const Element *elem); + + /** + * + */ + AttrImpl(DocumentImpl *owner, const DOMString &name); + + /** + * + */ + AttrImpl(DocumentImpl *owner, const DOMString &namespaceURI, const DOMString &name); + + /** + * + */ + virtual ~AttrImpl(); + +protected: + + + Element *ownerElement; + + +}; + + + + + +/*######################################################################### +## ElementImpl +#########################################################################*/ + +/** + * + */ +class ElementImpl : virtual public Element, public NodeImpl +{ +public: + + /** + * + */ + virtual DOMString getTagName(); + + /** + * + */ + virtual DOMString getAttribute(const DOMString& name); + + /** + * + */ + virtual void setAttribute(const DOMString& name, + const DOMString& value) + throw(DOMException); + + /** + * + */ + virtual void removeAttribute(const DOMString& name) + throw(DOMException); + + /** + * + */ + virtual Attr *getAttributeNode(const DOMString& name); + + /** + * + */ + virtual Attr *setAttributeNode(Attr *newAttr) + throw(DOMException); + + /** + * + */ + virtual Attr *removeAttributeNode(Attr *oldAttr) + throw(DOMException); + + /** + * + */ + virtual NodeList getElementsByTagName(const DOMString& name); + + /** + * + */ + virtual DOMString getAttributeNS(const DOMString& namespaceURI, + const DOMString& localName); + + /** + * + */ + virtual void setAttributeNS(const DOMString& namespaceURI, + const DOMString& qualifiedName, + const DOMString& value) + throw(DOMException); + + /** + * + */ + virtual void removeAttributeNS(const DOMString& namespaceURI, + const DOMString& localName) + throw(DOMException); + + /** + * + */ + virtual Attr *getAttributeNodeNS(const DOMString& namespaceURI, + const DOMString& localName); + + /** + * + */ + virtual Attr *setAttributeNodeNS(Attr *newAttr) + throw(DOMException); + + /** + * + */ + virtual NodeList getElementsByTagNameNS(const DOMString& namespaceURI, + const DOMString& localName); + + /** + * + */ + virtual bool hasAttribute(const DOMString& name); + + /** + * + */ + virtual bool hasAttributeNS(const DOMString& namespaceURI, + const DOMString& localName); + + /** + * + */ + virtual TypeInfo *getSchemaTypeInto(); + + + /** + * + */ + virtual void setIdAttribute(const DOMString &name, + bool isId) throw (DOMException); + + /** + * + */ + virtual void setIdAttributeNS(const DOMString &namespaceURI, + const DOMString &localName, + bool isId) throw (DOMException); + + /** + * + */ + virtual void setIdAttributeNode(const Attr *idAttr, + bool isId) throw (DOMException); + + + + //################## + //# Non-API methods + //################## + + + /** + * + */ + ElementImpl(); + + /** + * + */ + ElementImpl(DocumentImpl *owner, const DOMString &tagName); + + /** + * + */ + ElementImpl(DocumentImpl *owner, const DOMString &namespaceURI, const DOMString &tagName); + + /** + * + */ + virtual ~ElementImpl(); + + /** + * + */ + void normalizeNamespaces(); + +protected: + +friend class DocumentImpl; + + static void getElementsByTagNameRecursive(NodeList &list, + const DOMString& name, Element *elem); + static void getElementsByTagNameNSRecursive(NodeList &list, + const DOMString& namespaceURI, const DOMString& tagName, Element *elem); +}; + + + + + +/*######################################################################### +## TextImpl +#########################################################################*/ + +/** + * + */ +class TextImpl : virtual public Text, protected CharacterDataImpl +{ +public: + + /** + * + */ + virtual Text *splitText(unsigned long offset) + throw(DOMException); + + /** + * + */ + virtual bool getIsElementContentWhitespace(); + + /** + * + */ + virtual DOMString getWholeText(); + + + /** + * + */ + virtual Text *replaceWholeText(const DOMString &content) + throw(DOMException); + + //################## + //# Non-API methods + //################## + + /** + * + */ + TextImpl(); + + + /** + * + */ + TextImpl(DocumentImpl *owner, const DOMString &val); + + /** + * + */ + virtual ~TextImpl(); + +protected: + +}; + + + +/*######################################################################### +## CommentImpl +#########################################################################*/ + +/** + * + */ +class CommentImpl : virtual public Comment, protected CharacterDataImpl +{ +public: + + //################## + //# Non-API methods + //################## + + /** + * + */ + CommentImpl(); + + /** + * + */ + CommentImpl(DocumentImpl *owner, const DOMString &theValue); + + /** + * + */ + virtual ~CommentImpl(); +}; + + + +/*######################################################################### +## TypeInfoImpl +#########################################################################*/ + +/** + * + */ +class TypeInfoImpl : public TypeInfo +{ +public: + + /** + * + */ + virtual DOMString getTypeName(); + + /** + * + */ + virtual DOMString getTypeNamespace(); + + /** + * + */ + virtual bool isDerivedFrom(const DOMString &typeNamespaceArg, + const DOMString &typeNameArg, + const DerivationMethod derivationMethod); + + + //################## + //# Non-API methods + //################## + + + /** + * + */ + TypeInfoImpl(const DOMString &typeNamespaceArg, + const DOMString &typeNameArg, + const DerivationMethod derivationMethod); + + /** + * + */ + virtual ~TypeInfoImpl(); + +protected: + + DOMString typeName; + + DOMString typeNamespace; + + unsigned short derivationMethod; + +}; + + + + +/*######################################################################### +## UserDataHandlerImpl +#########################################################################*/ + +/** + * + */ +class UserDataHandlerImpl : public UserDataHandler +{ +public: + + /** + * + */ + virtual void handle(unsigned short operation, + const DOMString &key, + const DOMUserData *data, + const Node *src, + const Node *dst); + + //################## + //# Non-API methods + //################## + + +protected: + + /** + * + */ + UserDataHandlerImpl(); + + /** + * + */ + virtual ~UserDataHandlerImpl(); +}; + + +/*######################################################################### +## DOMErrorImpl +#########################################################################*/ + +/** + * + */ +class DOMErrorImpl : public DOMError +{ +public: + + /** + * + */ + virtual unsigned short getSeverity(); + + /** + * + */ + virtual DOMString getMessage(); + + /** + * + */ + virtual DOMString getType(); + + /** + * + */ + virtual DOMObject *getRelatedException(); + + /** + * + */ + virtual DOMObject *getRelatedData(); + + /** + * + */ + virtual DOMLocator *getLocation(); + + + //################## + //# Non-API methods + //################## + + +protected: + + /** + * + */ + DOMErrorImpl(); + + /** + * + */ + virtual ~DOMErrorImpl(); + + unsigned short severity; + + DOMString message; + + DOMString type; + + +}; + + +/*######################################################################### +## DOMErrorHandlerImpl +#########################################################################*/ + +/** + * + */ +class DOMErrorHandlerImpl : public DOMErrorHandler +{ +public: + + /** + * + */ + virtual bool handleError(const DOMError *error); + + + + //################## + //# Non-API methods + //################## + + + +protected: + + /** + * + */ + DOMErrorHandlerImpl(); + + /** + * + */ + virtual ~DOMErrorHandlerImpl(); + + +}; + + + +/*######################################################################### +## DOMLocatorImpl +#########################################################################*/ + +/** + * + */ +class DOMLocatorImpl : public DOMLocator +{ +public: + + /** + * + */ + virtual long getLineNumber(); + + /** + * + */ + virtual long getColumnNumber(); + + /** + * + */ + virtual long getByteOffset(); + + /** + * + */ + virtual long getUtf16Offset(); + + + /** + * + */ + virtual Node *getRelatedNode(); + + + /** + * + */ + virtual DOMString getUri(); + + + + //################## + //# Non-API methods + //################## + + + /** + * + */ + DOMLocatorImpl(); + + /** + * + */ + virtual ~DOMLocatorImpl(); + +protected: + + + long lineNumber; + + long columnNumber; + + long byteOffset; + + long utf16Offset; + + Node *relatedNode; + + DOMString uri; +}; + + +/*######################################################################### +## DOMConfigurationImpl +#########################################################################*/ + +/** + * + */ +class DOMConfigurationImpl : public DOMConfiguration +{ +public: + + /** + * + */ + virtual void setParameter(const DOMString &name, + const DOMUserData *value) throw (DOMException); + + /** + * + */ + virtual DOMUserData *getParameter(const DOMString &name) + throw (DOMException); + + /** + * + */ + virtual bool canSetParameter(const DOMString &name, + const DOMUserData *data); + + /** + * + */ + virtual DOMStringList *getParameterNames(); + + + //################## + //# Non-API methods + //################## + + /** + * + */ + DOMConfigurationImpl(); + + /** + * + */ + virtual ~DOMConfigurationImpl(); + +protected: + +}; + + + + + + +/*######################################################################### +## CDATASectionImpl +#########################################################################*/ +/** + * + */ +class CDATASectionImpl : public CDATASection, public TextImpl +{ +public: + + //################## + //# Non-API methods + //################## + + /** + * + */ + CDATASectionImpl(); + + + /** + * + */ + CDATASectionImpl(DocumentImpl *owner, const DOMString &value); + + /** + * + */ + virtual ~CDATASectionImpl(); + +}; + + + + +/*######################################################################### +## DocumentTypeImpl +#########################################################################*/ + +/** + * + */ +class DocumentTypeImpl : public DocumentType, public NodeImpl +{ +public: + + /** + * + */ + virtual DOMString getName(); + + /** + * + */ + virtual NamedNodeMap getEntities(); + + /** + * + */ + virtual NamedNodeMap getNotations(); + + /** + * + */ + virtual DOMString getPublicId(); + + /** + * + */ + virtual DOMString getSystemId(); + + /** + * + */ + virtual DOMString getInternalSubset(); + + //################## + //# Non-API methods + //################## + + /** + * + */ + DocumentTypeImpl(); + + /** + * + */ + DocumentTypeImpl(const DOMString& name, + const DOMString& publicId, + const DOMString& systemId); + /** + * + */ + virtual ~DocumentTypeImpl(); + + +protected: + DOMString name; + DOMString publicId; + DOMString systemId; + + NamedNodeMap entities; + NamedNodeMap notations; + +}; + + + + + +/*######################################################################### +## NotationImpl +#########################################################################*/ + +/** + * + */ +class NotationImpl : public Notation, public NodeImpl +{ +public: + + /** + * + */ + virtual DOMString getPublicId(); + + /** + * + */ + virtual DOMString getSystemId(); + + + //################## + //# Non-API methods + //################## + + /** + * + */ + NotationImpl(); + + /** + * + */ + NotationImpl(DocumentImpl *owner); + + /** + * + */ + virtual ~NotationImpl(); + + +protected: + + + + DOMString publicId; + + DOMString systemId; +}; + + + + + + +/*######################################################################### +## EntityImpl +#########################################################################*/ + +/** + * + */ +class EntityImpl : public Entity, public NodeImpl +{ +public: + + /** + * + */ + virtual DOMString getPublicId(); + + /** + * + */ + virtual DOMString getSystemId(); + + /** + * + */ + virtual DOMString getNotationName(); + + /** + * + */ + virtual DOMString getInputEncoding(); + + /** + * + */ + virtual DOMString getXmlEncoding(); + + /** + * + */ + virtual DOMString getXmlVersion(); + + + //################## + //# Non-API methods + //################## + + /** + * + */ + EntityImpl(); + + + /** + * + */ + EntityImpl(DocumentImpl *owner); + + /** + * + */ + virtual ~EntityImpl(); + +protected: + + + + DOMString publicId; + + DOMString systemId; + + DOMString notationName; + + DOMString inputEncoding; + + DOMString xmlEncoding; + + DOMString xmlVersion; + +}; + + + + + +/*######################################################################### +## EntityReferenceImpl +#########################################################################*/ +/** + * + */ +class EntityReferenceImpl : public EntityReference, public NodeImpl +{ +public: + + //################## + //# Non-API methods + //################## + + /** + * + */ + EntityReferenceImpl(); + + + /** + * + */ + EntityReferenceImpl(DocumentImpl *owner, const DOMString &theName); + + /** + * + */ + virtual ~EntityReferenceImpl(); + +}; + + + + + +/*######################################################################### +## ProcessingInstructionImpl +#########################################################################*/ + +/** + * + */ +class ProcessingInstructionImpl : public ProcessingInstruction, public NodeImpl +{ +public: + + /** + * + */ + virtual DOMString getTarget(); + + /** + * + */ + virtual DOMString getData(); + + /** + * + */ + virtual void setData(const DOMString& val) throw(DOMException); + + + //################## + //# Non-API methods + //################## + + + /** + * + */ + ProcessingInstructionImpl(); + + + /** + * + */ + ProcessingInstructionImpl(DocumentImpl *owner, + const DOMString &target, + const DOMString &data); + + /** + * + */ + virtual ~ProcessingInstructionImpl(); + + +protected: + + + //'target' is nodeName + + //'data' is nodeValue + + +}; + + + + + +/*######################################################################### +## DocumentFragmentImpl +#########################################################################*/ +/** + * + */ +class DocumentFragmentImpl : public DocumentFragment, public NodeImpl +{ + +public: + + //################## + //# Non-API methods + //################## + + /** + * + */ + DocumentFragmentImpl(); + + /** + * + */ + DocumentFragmentImpl(DocumentImpl *owner); + + /** + * + */ + virtual ~DocumentFragmentImpl(); + +}; + + + + + + +/*######################################################################### +## DocumentImpl +#########################################################################*/ + +/** + * + */ +class DocumentImpl : virtual public Document, public NodeImpl +{ +public: + + /** + * + */ + virtual DocumentType *getDoctype(); + + /** + * + */ + virtual DOMImplementation *getImplementation(); + + /** + * + */ + virtual Element *getDocumentElement(); + + /** + * + */ + virtual Element *createElement(const DOMString& tagName) + throw(DOMException); + + /** + * + */ + virtual DocumentFragment *createDocumentFragment(); + + /** + * + */ + virtual Text *createTextNode(const DOMString& data); + + /** + * + */ + virtual Comment *createComment(const DOMString& data); + + /** + * + */ + virtual CDATASection *createCDATASection(const DOMString& data) + throw(DOMException); + + /** + * + */ + virtual ProcessingInstruction *createProcessingInstruction(const DOMString& target, + const DOMString& data) + throw(DOMException); + + /** + * + */ + virtual Attr *createAttribute(const DOMString& name) + throw(DOMException); + + /** + * + */ + virtual EntityReference *createEntityReference(const DOMString& name) + throw(DOMException); + + /** + * + */ + virtual NodeList getElementsByTagName(const DOMString& tagname); + + + /** + * + */ + virtual Node *importNode(const Node *importedNode, + bool deep) + throw(DOMException); + + /** + * + */ + virtual Element *createElementNS(const DOMString& namespaceURI, + const DOMString& qualifiedName) + throw(DOMException); + + /** + * + */ + virtual Attr *createAttributeNS(const DOMString& namespaceURI, + const DOMString& qualifiedName) + throw(DOMException); + + /** + * + */ + virtual NodeList getElementsByTagNameNS(const DOMString& namespaceURI, + const DOMString& localName); + + /** + * + */ + virtual Element *getElementById(const DOMString& elementId); + + + /** + * + */ + virtual DOMString getInputEncoding(); + + + /** + * + */ + virtual DOMString getXmlEncoding(); + + /** + * + */ + virtual bool getXmlStandalone(); + + /** + * + */ + virtual void setXmlStandalone(bool val) throw (DOMException); + + /** + * + */ + virtual DOMString getXmlVersion(); + + /** + * + */ + virtual void setXmlVersion(const DOMString &version) throw (DOMException); + + /** + * + */ + virtual bool getStrictErrorChecking(); + + /** + * + */ + virtual void setStrictErrorChecking(bool val); + + + /** + * + */ + virtual DOMString getDocumentURI(); + + /** + * + */ + virtual void setDocumentURI(const DOMString &uri); + + /** + * + */ + virtual Node *adoptNode(const Node *source) throw (DOMException); + + /** + * + */ + virtual DOMConfiguration *getDomConfig(); + + /** + * + */ + virtual void normalizeDocument(); + + /** + * + */ + virtual Node *renameNode(const Node *n, + const DOMString &name, + const DOMString &qualifiedName) + throw (DOMException); + + + //################## + //# Non-API methods + //################## + + DocumentImpl(const DOMImplementation *domImpl, + const DOMString &namespaceURI, + const DOMString &qualifiedName, + const DocumentType *doctype); + + virtual ~DocumentImpl(); + + + DOMString *stringCache(const DOMString &val); + + int namespaceIndex; + +protected: + + DOMImplementation *parent; + + DOMString *documentURI; + + DOMString qualifiedName; + + DocumentType *doctype; + + ElementImpl *documentElement; + + class NamedElementItem + { + public: + NamedElementItem() + { + next = NULL; + } + NamedElementItem(const DOMString &nameArg, Element *elemArg) + { + next = NULL; + name = nameArg; + elem = elemArg; + } + ~NamedElementItem() + { + if (next) + delete next; + } + NamedElementItem *next; + DOMString name; + Element *elem; + }; + + NamedElementItem elementsById; + + + DOMString xmlEncoding; + + DOMString inputEncoding; + + DOMString xmlVersion; + + bool xmlStandalone; + + bool strictErrorChecking; + + DOMConfiguration *domConfig; + + NamedNodeMap namespaceURIs; + + +}; + + + + + + + + + + + +} //namespace dom +} //namespace w3c +} //namespace org + + +#endif // __DOMIMPL_H__ + + +/*######################################################################### +## E N D O F F I L E +#########################################################################*/ + + + + diff --git a/src/dom/domstream.cpp b/src/dom/domstream.cpp new file mode 100755 index 000000000..1129a7f46 --- /dev/null +++ b/src/dom/domstream.cpp @@ -0,0 +1,874 @@ +/** + * Phoebe DOM Implementation. + * + * This is a C++ approximation of the W3C DOM model, which follows + * fairly closely the specifications in the various .idl files, copies of + * which are provided for reference. Most important is this one: + * + * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/idl-definitions.html + * + * Authors: + * Bob Jamison + * + * Copyright (C) 2005 Bob Jamison + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * Our base input/output stream classes. These are is directly + * inherited from iostreams, and includes any extra + * functionality that we might need. + * + * Authors: + * Bob Jamison + * + * Copyright (C) 2004 Inkscape.org + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include + +#include "domstream.h" + +namespace org +{ +namespace w3c +{ +namespace dom +{ + + +//######################################################################### +//# U T I L I T Y +//######################################################################### + +void pipeStream(InputStream &source, OutputStream &dest) +{ + for (;;) + { + int ch = source.get(); + if (ch<0) + break; + dest.put(ch); + } + dest.flush(); +} + +//######################################################################### +//# B A S I C I N P U T S T R E A M +//######################################################################### + + +/** + * + */ +BasicInputStream::BasicInputStream(const InputStream &sourceStream) + : source((InputStream &)sourceStream) +{ + closed = false; +} + +/** + * Returns the number of bytes that can be read (or skipped over) from + * this input stream without blocking by the next caller of a method for + * this input stream. + */ +int BasicInputStream::available() +{ + if (closed) + return 0; + return source.available(); +} + + +/** + * Closes this input stream and releases any system resources + * associated with the stream. + */ +void BasicInputStream::close() +{ + if (closed) + return; + source.close(); + closed = true; +} + +/** + * Reads the next byte of data from the input stream. -1 if EOF + */ +int BasicInputStream::get() +{ + if (closed) + return -1; + return source.get(); +} + + + +//######################################################################### +//# B A S I C O U T P U T S T R E A M +//######################################################################### + +/** + * + */ +BasicOutputStream::BasicOutputStream(const OutputStream &destinationStream) + : destination((OutputStream &)destinationStream) +{ + closed = false; +} + +/** + * Closes this output stream and releases any system resources + * associated with this stream. + */ +void BasicOutputStream::close() +{ + if (closed) + return; + destination.close(); + closed = true; +} + +/** + * Flushes this output stream and forces any buffered output + * bytes to be written out. + */ +void BasicOutputStream::flush() +{ + if (closed) + return; + destination.flush(); +} + +/** + * Writes the specified byte to this output stream. + */ +void BasicOutputStream::put(XMLCh ch) +{ + if (closed) + return; + destination.put(ch); +} + + + +//######################################################################### +//# B A S I C R E A D E R +//######################################################################### + + +/** + * + */ +BasicReader::BasicReader(Reader &sourceReader) +{ + source = &sourceReader; +} + +/** + * Returns the number of bytes that can be read (or skipped over) from + * this reader without blocking by the next caller of a method for + * this reader. + */ +int BasicReader::available() +{ + if (source) + return source->available(); + else + return 0; +} + + +/** + * Closes this reader and releases any system resources + * associated with the reader. + */ +void BasicReader::close() +{ + if (source) + source->close(); +} + +/** + * Reads the next byte of data from the reader. + */ +int BasicReader::get() +{ + if (source) + return source->get(); + else + return -1; +} + + + + + + +/** + * Reads a line of data from the reader. + */ +DOMString BasicReader::readLine() +{ + DOMString str; + while (available() > 0) + { + XMLCh ch = get(); + if (ch == '\n') + break; + str.push_back(ch); + } + return str; +} + +/** + * Reads a line of data from the reader. + */ +DOMString BasicReader::readWord() +{ + DOMString str; + while (available() > 0) + { + XMLCh ch = get(); + if (!isprint(ch)) + break; + str.push_back(ch); + } + return str; +} + + +static bool getLong(DOMString &str, long *val) +{ + const char *begin = str.c_str(); + char *end; + long ival = strtol(begin, &end, 10); + if (str == end) + return false; + *val = ival; + return true; +} + +static bool getULong(const DOMString &str, unsigned long *val) +{ + DOMString tmp = str; + char *begin = (char *)tmp.c_str(); + char *end; + unsigned long ival = strtoul(begin, &end, 10); + if (begin == end) + return false; + *val = ival; + return true; +} + +static bool getDouble(const DOMString &str, double *val) +{ + DOMString tmp = str; + const char *begin = tmp.c_str(); + char *end; + double ival = strtod(begin, &end); + if (begin == end) + return false; + *val = ival; + return true; +} + + + + +/** + * + */ +Reader &BasicReader::readBool (bool& val ) +{ + DOMString buf = readWord(); + if (buf == "true") + val = true; + else + val = false; + return *this; +} + +/** + * + */ +Reader &BasicReader::readShort (short& val ) +{ + DOMString buf = readWord(); + long ival; + if (getLong(buf, &ival)) + val = (short) ival; + return *this; +} + +/** + * + */ +Reader &BasicReader::readUnsignedShort (unsigned short& val ) +{ + DOMString buf = readWord(); + unsigned long ival; + if (getULong(buf, &ival)) + val = (unsigned short) ival; + return *this; +} + +/** + * + */ +Reader &BasicReader::readInt (int& val ) +{ + DOMString buf = readWord(); + long ival; + if (getLong(buf, &ival)) + val = (int) ival; + return *this; +} + +/** + * + */ +Reader &BasicReader::readUnsignedInt (unsigned int& val ) +{ + DOMString buf = readWord(); + unsigned long ival; + if (getULong(buf, &ival)) + val = (unsigned int) ival; + return *this; +} + +/** + * + */ +Reader &BasicReader::readLong (long& val ) +{ + DOMString buf = readWord(); + long ival; + if (getLong(buf, &ival)) + val = ival; + return *this; +} + +/** + * + */ +Reader &BasicReader::readUnsignedLong (unsigned long& val ) +{ + DOMString buf = readWord(); + unsigned long ival; + if (getULong(buf, &ival)) + val = ival; + return *this; +} + +/** + * + */ +Reader &BasicReader::readFloat (float& val ) +{ + DOMString buf = readWord(); + double ival; + if (getDouble(buf, &ival)) + val = (float)ival; + return *this; +} + +/** + * + */ +Reader &BasicReader::readDouble (double& val ) +{ + DOMString buf = readWord(); + double ival; + if (getDouble(buf, &ival)) + val = ival; + return *this; +} + + + +//######################################################################### +//# I N P U T S T R E A M R E A D E R +//######################################################################### + + +InputStreamReader::InputStreamReader(const InputStream &inputStreamSource) + : inputStream((InputStream &)inputStreamSource) +{ +} + + + +/** + * Close the underlying OutputStream + */ +void InputStreamReader::close() +{ + inputStream.close(); +} + +/** + * Flush the underlying OutputStream + */ +int InputStreamReader::available() +{ + return inputStream.available(); +} + +/** + * Overloaded to receive its bytes from an InputStream + * rather than a Reader + */ +int InputStreamReader::get() +{ + //Do we need conversions here? + int ch = (XMLCh)inputStream.get(); + return ch; +} + + + +//######################################################################### +//# S T D R E A D E R +//######################################################################### + + +/** + * + */ +StdReader::StdReader() +{ + inputStream = new StdInputStream(); +} + +/** + * + */ +StdReader::~StdReader() +{ + delete inputStream; +} + + + +/** + * Close the underlying OutputStream + */ +void StdReader::close() +{ + inputStream->close(); +} + +/** + * Flush the underlying OutputStream + */ +int StdReader::available() +{ + return inputStream->available(); +} + +/** + * Overloaded to receive its bytes from an InputStream + * rather than a Reader + */ +int StdReader::get() +{ + //Do we need conversions here? + XMLCh ch = (XMLCh)inputStream->get(); + return ch; +} + + + + + +//######################################################################### +//# B A S I C W R I T E R +//######################################################################### + +/** + * + */ +BasicWriter::BasicWriter(const Writer &destinationWriter) +{ + destination = (Writer *)&destinationWriter; +} + +/** + * Closes this writer and releases any system resources + * associated with this writer. + */ +void BasicWriter::close() +{ + if (destination) + destination->close(); +} + +/** + * Flushes this output stream and forces any buffered output + * bytes to be written out. + */ +void BasicWriter::flush() +{ + if (destination) + destination->flush(); +} + +/** + * Writes the specified byte to this output writer. + */ +void BasicWriter::put(XMLCh ch) +{ + if (destination) + destination->put(ch); +} + +/** + * Provide printf()-like formatting + */ +Writer &BasicWriter::printf(char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + //replace this wish vsnprintf() + char buf[256]; + vsnprintf(buf, 255, fmt, args); + va_end(args); + if (buf) { + writeString(buf); + //free(buf); + } + return *this; +} +/** + * Writes the specified character to this output writer. + */ +Writer &BasicWriter::writeChar(char ch) +{ + XMLCh uch = ch; + put(uch); + return *this; +} + + +/** + * Writes the specified standard string to this output writer. + */ +Writer &BasicWriter::writeString(const DOMString &str) +{ + for (int i=0; i< (int)str.size(); i++) + put(str[i]); + return *this; +} + + +/** + * + */ +Writer &BasicWriter::writeBool (bool val ) +{ + if (val) + writeString("true"); + else + writeString("false"); + return *this; +} + + +/** + * + */ +Writer &BasicWriter::writeShort (short val ) +{ + char buf[32]; + snprintf(buf, 31, "%d", val); + writeString(buf); + return *this; +} + + + +/** + * + */ +Writer &BasicWriter::writeUnsignedShort (unsigned short val ) +{ + char buf[32]; + snprintf(buf, 31, "%u", val); + writeString(buf); + return *this; +} + +/** + * + */ +Writer &BasicWriter::writeInt (int val) +{ + char buf[32]; + snprintf(buf, 31, "%d", val); + writeString(buf); + return *this; +} + +/** + * + */ +Writer &BasicWriter::writeUnsignedInt (unsigned int val) +{ + char buf[32]; + snprintf(buf, 31, "%u", val); + writeString(buf); + return *this; +} + +/** + * + */ +Writer &BasicWriter::writeLong (long val) +{ + char buf[32]; + snprintf(buf, 31, "%ld", val); + writeString(buf); + return *this; +} + +/** + * + */ +Writer &BasicWriter::writeUnsignedLong(unsigned long val) +{ + char buf[32]; + snprintf(buf, 31, "%lu", val); + writeString(buf); + return *this; +} + +/** + * + */ +Writer &BasicWriter::writeFloat(float val) +{ + char buf[32]; + snprintf(buf, 31, "%8.3f", val); + writeString(buf); + return *this; +} + +/** + * + */ +Writer &BasicWriter::writeDouble(double val) +{ + char buf[32]; + snprintf(buf, 31, "%8.3f", val); + writeString(buf); + return *this; +} + + + + +//######################################################################### +//# O U T P U T S T R E A M W R I T E R +//######################################################################### + + +OutputStreamWriter::OutputStreamWriter(OutputStream &outputStreamDest) + : outputStream(outputStreamDest) +{ +} + + + +/** + * Close the underlying OutputStream + */ +void OutputStreamWriter::close() +{ + flush(); + outputStream.close(); +} + +/** + * Flush the underlying OutputStream + */ +void OutputStreamWriter::flush() +{ + outputStream.flush(); +} + +/** + * Overloaded to redirect the output chars from the next Writer + * in the chain to an OutputStream instead. + */ +void OutputStreamWriter::put(XMLCh ch) +{ + //Do we need conversions here? + int intCh = (int) ch; + outputStream.put(intCh); +} + +//######################################################################### +//# S T D W R I T E R +//######################################################################### + + +/** + * + */ +StdWriter::StdWriter() +{ + outputStream = new StdOutputStream(); +} + + +/** + * + */ +StdWriter::~StdWriter() +{ + delete outputStream; +} + + + +/** + * Close the underlying OutputStream + */ +void StdWriter::close() +{ + flush(); + outputStream->close(); +} + +/** + * Flush the underlying OutputStream + */ +void StdWriter::flush() +{ + outputStream->flush(); +} + +/** + * Overloaded to redirect the output chars from the next Writer + * in the chain to an OutputStream instead. + */ +void StdWriter::put(XMLCh ch) +{ + //Do we need conversions here? + int intCh = (int) ch; + outputStream->put(intCh); +} + + + + + + + + + + + + +//############################################### +//# O P E R A T O R S +//############################################### +//# Normally these would be in the .h, but we +//# just want to be absolutely certain that these +//# are never multiply defined. Easy to maintain, +//# though. Just occasionally copy/paste these +//# into the .h , and replace the {} with a ; +//############################################### + + + + +Reader& operator>> (Reader &reader, bool& val ) + { return reader.readBool(val); } + +Reader& operator>> (Reader &reader, short &val) + { return reader.readShort(val); } + +Reader& operator>> (Reader &reader, unsigned short &val) + { return reader.readUnsignedShort(val); } + +Reader& operator>> (Reader &reader, int &val) + { return reader.readInt(val); } + +Reader& operator>> (Reader &reader, unsigned int &val) + { return reader.readUnsignedInt(val); } + +Reader& operator>> (Reader &reader, long &val) + { return reader.readLong(val); } + +Reader& operator>> (Reader &reader, unsigned long &val) + { return reader.readUnsignedLong(val); } + +Reader& operator>> (Reader &reader, float &val) + { return reader.readFloat(val); } + +Reader& operator>> (Reader &reader, double &val) + { return reader.readDouble(val); } + + + + +Writer& operator<< (Writer &writer, char val) + { return writer.writeChar(val); } + +Writer& operator<< (Writer &writer, const DOMString &val) + { return writer.writeString(val); } + +Writer& operator<< (Writer &writer, bool val) + { return writer.writeBool(val); } + +Writer& operator<< (Writer &writer, short val) + { return writer.writeShort(val); } + +Writer& operator<< (Writer &writer, unsigned short val) + { return writer.writeUnsignedShort(val); } + +Writer& operator<< (Writer &writer, int val) + { return writer.writeInt(val); } + +Writer& operator<< (Writer &writer, unsigned int val) + { return writer.writeUnsignedInt(val); } + +Writer& operator<< (Writer &writer, long val) + { return writer.writeLong(val); } + +Writer& operator<< (Writer &writer, unsigned long val) + { return writer.writeUnsignedLong(val); } + +Writer& operator<< (Writer &writer, float val) + { return writer.writeFloat(val); } + +Writer& operator<< (Writer &writer, double val) + { return writer.writeDouble(val); } + + + +} //namespace dom +} //namespace w3c +} //namespace org + + +//######################################################################### +//# E N D O F F I L E +//######################################################################### diff --git a/src/dom/domstream.h b/src/dom/domstream.h new file mode 100755 index 000000000..64c3d0eb4 --- /dev/null +++ b/src/dom/domstream.h @@ -0,0 +1,674 @@ +#ifndef __DOMSTREAM_H__ +#define __DOMSTREAM_H__ +/** + * Phoebe DOM Implementation. + * + * This is a C++ approximation of the W3C DOM model, which follows + * fairly closely the specifications in the various .idl files, copies of + * which are provided for reference. Most important is this one: + * + * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/idl-definitions.html + * + * Authors: + * Bob Jamison + * + * Copyright (C) 2005 Bob Jamison + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + + +#include "dom.h" + +namespace org +{ +namespace w3c +{ +namespace dom +{ + + + +class StreamException +{ +public: + + StreamException(const DOMString &theReason) throw() + { reason = theReason; } + ~StreamException() throw() + { } + char const *what() + { return reason.c_str(); } + +private: + + DOMString reason; + +}; + +//######################################################################### +//# I N P U T S T R E A M +//######################################################################### + +/** + * This interface is the base of all input stream classes. Users who wish + * to make an InputStream that is part of a chain should inherit from + * BasicInputStream. Inherit from this class to make a source endpoint, + * such as a URI or buffer. + * + */ +class InputStream +{ + +public: + + /** + * Constructor. + */ + InputStream() {} + + /** + * Destructor + */ + virtual ~InputStream() {} + + /** + * Return the number of bytes that are currently available + * to be read + */ + virtual int available() = 0; + + /** + * Do whatever it takes to 'close' this input stream + * The most likely implementation of this method will be + * for endpoints that use a resource for their data. + */ + virtual void close() = 0; + + /** + * Read one byte from this input stream. This is a blocking + * call. If no data is currently available, this call will + * not return until it exists. If the user does not want + * their code to block, then the usual solution is: + * if (available() > 0) + * myChar = get(); + * This call returns -1 on end-of-file. + */ + virtual int get() = 0; + +}; // class InputStream + + + + +/** + * This is the class that most users should inherit, to provide + * their own streams. + * + */ +class BasicInputStream : public InputStream +{ + +public: + + BasicInputStream(const InputStream &sourceStream); + + virtual ~BasicInputStream() {} + + virtual int available(); + + virtual void close(); + + virtual int get(); + +protected: + + bool closed; + + InputStream &source; + +private: + + +}; // class BasicInputStream + + + +/** + * Convenience class for reading from standard input + */ +class StdInputStream : public InputStream +{ +public: + + int available() + { return 0; } + + void close() + { /* do nothing */ } + + int get() + { return getchar(); } + +}; + + + + + + +//######################################################################### +//# O U T P U T S T R E A M +//######################################################################### + +/** + * This interface is the base of all input stream classes. Users who wish + * to make an OutputStream that is part of a chain should inherit from + * BasicOutputStream. Inherit from this class to make a destination endpoint, + * such as a URI or buffer. + */ +class OutputStream +{ + +public: + + /** + * Constructor. + */ + OutputStream() {} + + /** + * Destructor + */ + virtual ~OutputStream() {} + + /** + * This call should + * 1. flush itself + * 2. close itself + * 3. close the destination stream + */ + virtual void close() = 0; + + /** + * This call should push any pending data it might have to + * the destination stream. It should NOT call flush() on + * the destination stream. + */ + virtual void flush() = 0; + + /** + * Send one byte to the destination stream. + */ + virtual void put(XMLCh ch) = 0; + + +}; // class OutputStream + + +/** + * This is the class that most users should inherit, to provide + * their own output streams. + */ +class BasicOutputStream : public OutputStream +{ + +public: + + BasicOutputStream(const OutputStream &destinationStream); + + virtual ~BasicOutputStream() {} + + virtual void close(); + + virtual void flush(); + + virtual void put(XMLCh ch); + +protected: + + bool closed; + + OutputStream &destination; + + +}; // class BasicOutputStream + + + +/** + * Convenience class for writing to standard output + */ +class StdOutputStream : public OutputStream +{ +public: + + void close() + { } + + void flush() + { } + + void put(XMLCh ch) + { putchar(ch); } + +}; + + + + +//######################################################################### +//# R E A D E R +//######################################################################### + + +/** + * This interface and its descendants are for unicode character-oriented input + * + */ +class Reader +{ + +public: + + /** + * Constructor. + */ + Reader() {} + + /** + * Destructor + */ + virtual ~Reader() {} + + + virtual int available() = 0; + + virtual void close() = 0; + + virtual int get() = 0; + + virtual DOMString readLine() = 0; + + virtual DOMString readWord() = 0; + + /* Input formatting */ + virtual Reader& readBool (bool& val ) = 0; + + virtual Reader& readShort (short &val) = 0; + + virtual Reader& readUnsignedShort (unsigned short &val) = 0; + + virtual Reader& readInt (int &val) = 0; + + virtual Reader& readUnsignedInt (unsigned int &val) = 0; + + virtual Reader& readLong (long &val) = 0; + + virtual Reader& readUnsignedLong (unsigned long &val) = 0; + + virtual Reader& readFloat (float &val) = 0; + + virtual Reader& readDouble (double &val) = 0; + +}; // interface Reader + + + +/** + * This class and its descendants are for unicode character-oriented input + * + */ +class BasicReader : public Reader +{ + +public: + + BasicReader(Reader &sourceStream); + + virtual ~BasicReader() {} + + virtual int available(); + + virtual void close(); + + virtual int get(); + + virtual DOMString readLine(); + + virtual DOMString readWord(); + + /* Input formatting */ + virtual Reader& readBool (bool& val ); + + virtual Reader& readShort (short &val) ; + + virtual Reader& readUnsignedShort (unsigned short &val) ; + + virtual Reader& readInt (int &val) ; + + virtual Reader& readUnsignedInt (unsigned int &val) ; + + virtual Reader& readLong (long &val) ; + + virtual Reader& readUnsignedLong (unsigned long &val) ; + + virtual Reader& readFloat (float &val) ; + + virtual Reader& readDouble (double &val) ; + +protected: + + Reader *source; + + BasicReader() + { source = NULL; } + +private: + +}; // class BasicReader + + + +Reader& operator>> (Reader &reader, bool& val ); + +Reader& operator>> (Reader &reader, short &val); + +Reader& operator>> (Reader &reader, unsigned short &val); + +Reader& operator>> (Reader &reader, int &val); + +Reader& operator>> (Reader &reader, unsigned int &val); + +Reader& operator>> (Reader &reader, long &val); + +Reader& operator>> (Reader &reader, unsigned long &val); + +Reader& operator>> (Reader &reader, float &val); + +Reader& operator>> (Reader &reader, double &val); + + + + +/** + * Class for placing a Reader on an open InputStream + * + */ +class InputStreamReader : public BasicReader +{ +public: + + InputStreamReader(const InputStream &inputStreamSource); + + /*Overload these 3 for your implementation*/ + virtual int available(); + + virtual void close(); + + virtual int get(); + + +private: + + InputStream &inputStream; + + +}; + +/** + * Convenience class for reading formatted from standard input + * + */ +class StdReader : public BasicReader +{ +public: + + StdReader(); + + ~StdReader(); + + /*Overload these 3 for your implementation*/ + virtual int available(); + + virtual void close(); + + virtual int get(); + + +private: + + InputStream *inputStream; + + +}; + + + + + +//######################################################################### +//# W R I T E R +//######################################################################### + +/** + * This interface and its descendants are for unicode character-oriented output + * + */ +class Writer +{ + +public: + + /** + * Constructor. + */ + Writer() {} + + /** + * Destructor + */ + virtual ~Writer() {} + + virtual void close() = 0; + + virtual void flush() = 0; + + virtual void put(XMLCh ch) = 0; + + /* Formatted output */ + virtual Writer& printf(char *fmt, ...) = 0; + + virtual Writer& writeChar(char val) = 0; + + virtual Writer& writeString(const DOMString &val) = 0; + + virtual Writer& writeBool (bool val ) = 0; + + virtual Writer& writeShort (short val ) = 0; + + virtual Writer& writeUnsignedShort (unsigned short val ) = 0; + + virtual Writer& writeInt (int val ) = 0; + + virtual Writer& writeUnsignedInt (unsigned int val ) = 0; + + virtual Writer& writeLong (long val ) = 0; + + virtual Writer& writeUnsignedLong (unsigned long val ) = 0; + + virtual Writer& writeFloat (float val ) = 0; + + virtual Writer& writeDouble (double val ) = 0; + + + +}; // interface Writer + + +/** + * This class and its descendants are for unicode character-oriented output + * + */ +class BasicWriter : public Writer +{ + +public: + + BasicWriter(const Writer &destinationWriter); + + virtual ~BasicWriter() {} + + /*Overload these 3 for your implementation*/ + virtual void close(); + + virtual void flush(); + + virtual void put(XMLCh ch); + + + + /* Formatted output */ + virtual Writer &printf(char *fmt, ...); + + virtual Writer& writeChar(char val); + + virtual Writer& writeString(const DOMString &val); + + virtual Writer& writeBool (bool val ); + + virtual Writer& writeShort (short val ); + + virtual Writer& writeUnsignedShort (unsigned short val ); + + virtual Writer& writeInt (int val ); + + virtual Writer& writeUnsignedInt (unsigned int val ); + + virtual Writer& writeLong (long val ); + + virtual Writer& writeUnsignedLong (unsigned long val ); + + virtual Writer& writeFloat (float val ); + + virtual Writer& writeDouble (double val ); + + +protected: + + Writer *destination; + + BasicWriter() + { destination = NULL; } + +private: + +}; // class BasicWriter + + + +Writer& operator<< (Writer &writer, char val); + +Writer& operator<< (Writer &writer, const DOMString &val); + +Writer& operator<< (Writer &writer, bool val); + +Writer& operator<< (Writer &writer, short val); + +Writer& operator<< (Writer &writer, unsigned short val); + +Writer& operator<< (Writer &writer, int val); + +Writer& operator<< (Writer &writer, unsigned int val); + +Writer& operator<< (Writer &writer, long val); + +Writer& operator<< (Writer &writer, unsigned long val); + +Writer& operator<< (Writer &writer, float val); + +Writer& operator<< (Writer &writer, double val); + + + + +/** + * Class for placing a Writer on an open OutputStream + * + */ +class OutputStreamWriter : public BasicWriter +{ +public: + + OutputStreamWriter(OutputStream &outputStreamDest); + + /*Overload these 3 for your implementation*/ + virtual void close(); + + virtual void flush(); + + virtual void put(XMLCh ch); + + +private: + + OutputStream &outputStream; + + +}; + + +/** + * Convenience class for writing to standard output + */ +class StdWriter : public BasicWriter +{ +public: + StdWriter(); + + ~StdWriter(); + + + virtual void close(); + + + virtual void flush(); + + + virtual void put(XMLCh ch); + + +private: + + OutputStream *outputStream; + +}; + +//######################################################################### +//# U T I L I T Y +//######################################################################### + +void pipeStream(InputStream &source, OutputStream &dest); + + + + +} //namespace dom +} //namespace w3c +} //namespace org + + +#endif /* __DOMSTREAM_H__ */ diff --git a/src/dom/domstring.cpp b/src/dom/domstring.cpp new file mode 100755 index 000000000..11b301066 --- /dev/null +++ b/src/dom/domstring.cpp @@ -0,0 +1,414 @@ +/** + * Phoebe DOM Implementation. + * + * This is a C++ approximation of the W3C DOM model, which follows + * fairly closely the specifications in the various .idl files, copies of + * which are provided for reference. Most important is this one: + * + * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/idl-definitions.html + * + * Authors: + * Bob Jamison + * + * Copyright (C) 2005 Bob Jamison + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +#include "domstring.h" + +namespace org +{ +namespace w3c +{ +namespace dom +{ + + +//######################################################################### +//# C O N S T R U C T O R S +//######################################################################### + +DOMString::DOMString() +{ + init(); +} + +DOMString::DOMString(const DOMString &other) +{ + init(); + chars = other.chars; +} + +DOMString::DOMString(const char *str) +{ + init(); + append(str); +} + + +DOMString::~DOMString() +{ + if (cstring) + free(cstring); +} + + +/** + * Called only by Constructors + */ +void DOMString::init() +{ + cstring = NULL; + chars.clear(); +} + +//######################################################################### +//# M O D I F Y +//######################################################################### + +DOMString &DOMString::append(const DOMString &str) +{ + unsigned int len = str.size(); + for (unsigned int i=0 ; i::iterator iter = chars.begin(); + chars.erase(iter, iter + count); +} + +DOMString &DOMString::insert(unsigned long pos, const DOMString &str) +{ + DOMString a = substr(0, pos); + DOMString b = substr(pos, size()); + clear(); + append(a); + append(str); + append(b); + return *this; +} + +DOMString &DOMString::insert(unsigned long pos, const char *str) +{ + DOMString a = substr(0, pos); + DOMString b = substr(pos, size()); + clear(); + append(a); + append(str); + append(b); + return *this; +} + +DOMString &DOMString::insert(unsigned long pos, const std::string &str) +{ + DOMString a = substr(0, pos); + DOMString b = substr(pos, size()); + clear(); + append(a); + append(str); + append(b); + return *this; +} + + +DOMString &DOMString::prepend(const DOMString &str) +{ + DOMString tmp = *this; + clear(); + append(str); + append(tmp); + return *this; +} + +DOMString &DOMString::prepend(const char *str) +{ + DOMString tmp = *this; + clear(); + append(str); + append(tmp); + return *this; +} + +DOMString &DOMString::prepend(const std::string &str) +{ + DOMString tmp = *this; + clear(); + append(str); + append(tmp); + return *this; +} + +DOMString &DOMString::replace(unsigned long pos, unsigned long count, + const DOMString &str) +{ + DOMString a = substr(0, pos); + DOMString b = substr(pos+count, size()); + clear(); + append(a); + append(str); + append(b); + return *this; +} + +DOMString &DOMString::replace(unsigned long pos, unsigned long count, + const char *str) +{ + DOMString a = substr(0, pos); + DOMString b = substr(pos+count, size()); + clear(); + append(a); + append(str); + append(b); + return *this; +} + +DOMString &DOMString::replace(unsigned long pos, unsigned long count, + const std::string &str) +{ + DOMString a = substr(0, pos); + DOMString b = substr(pos+count, size()); + clear(); + append(a); + append(str); + append(b); + return *this; +} + + +DOMString &DOMString::push_back(XMLCh ch) +{ + chars.push_back(ch); + return *this; +} + + + +void DOMString::clear() +{ + chars.clear(); + if (cstring) + { + free(cstring); + cstring = NULL; + } +} + +//######################################################################### +//# Q U E R Y +//######################################################################### + +XMLCh DOMString::charAt(unsigned long index) const +{ + return chars[index]; +} + +XMLCh DOMString::operator[](unsigned long index) const +{ + return chars[index]; +} + +DOMString DOMString::substr(unsigned long start, unsigned long end) const +{ + DOMString ret; + for (unsigned long i = start; i +#include + +namespace org +{ +namespace w3c +{ +namespace dom +{ + +/** + * + */ +typedef unsigned short XMLCh; + +class DOMString +{ +public: + + //############################### + //# C O N S T R U C T O R S + //############################### + + /** + * + */ + DOMString(); + + /** + * + */ + DOMString(const char *str); + + + /** + * + */ + DOMString(const DOMString &str); + + + /** + * + */ + DOMString(const std::string &str); + + /** + * + */ + virtual ~DOMString(); + + + //############################### + //# M O D I F Y + //############################### + + + + /** + * + */ + virtual DOMString &append(const DOMString &str); + virtual DOMString &operator +(const DOMString &str) + { return append(str); } + virtual DOMString &operator +=(const DOMString &str) + { return append(str); } + + /** + * + */ + virtual DOMString &append(const char *str); + + /** + * + */ + virtual DOMString &append(const std::string &str); + + + /** + * + */ + virtual DOMString &assign(const DOMString &str); + + /** + * + */ + virtual DOMString &assign(const char *str); + + /** + * + */ + virtual DOMString &assign(const std::string &str); + + /** + * + */ + virtual void erase(unsigned long pos, unsigned long count); + + /** + * + */ + virtual DOMString &insert(unsigned long pos, const DOMString &str); + + /** + * + */ + virtual DOMString &insert(unsigned long pos, const char *str); + + /** + * + */ + virtual DOMString &insert(unsigned long pos, const std::string &str); + + + /** + * + */ + virtual DOMString &prepend(const DOMString &str); + + /** + * + */ + virtual DOMString &prepend(const char *str); + + /** + * + */ + virtual DOMString &prepend(const std::string &str); + + + /** + * + */ + virtual DOMString &replace(unsigned long pos, unsigned long count, + const DOMString &str); + + /** + * + */ + virtual DOMString &replace(unsigned long pos, unsigned long count, + const char *str); + + /** + * + */ + virtual DOMString &replace(unsigned long pos, unsigned long count, + const std::string &str); + + /** + * + */ + virtual DOMString &push_back(XMLCh ch); + + /** + * + */ + virtual void clear(); + + //############################### + //# Q U E R Y + //############################### + + /** + * + */ + virtual DOMString substr(unsigned long start, unsigned long end) const; + + /** + * + */ + virtual XMLCh charAt(unsigned long index) const; + + /** + * + */ + virtual XMLCh operator[](unsigned long index) const; + + /** + * + */ + virtual unsigned long size() const; + + /** + * + */ + virtual const char *c_str(); + + //############################### + //# C O M P A R I S O N + //############################### + + /** + * + */ + virtual int compare(const DOMString &str) const; + virtual bool operator <(const DOMString &str) const + { return (compare(str)<0) ; } + virtual bool operator <=(const DOMString &str) const + { return (compare(str)<=0) ; } + virtual bool operator >(const DOMString &str) const + { return (compare(str)>0) ; } + virtual bool operator >=(const DOMString &str) const + { return (compare(str)>=0) ; } + virtual bool operator !=(const DOMString &str) const + { return (compare(str)!=0) ; } + virtual bool operator ==(const DOMString &str) const + { return (compare(str)==0) ; } + + /** + * + */ + virtual int compare(const char *str) const; + virtual bool operator <(const char *str) const + { return (compare(str)<0) ; } + virtual bool operator <=(const char *str) const + { return (compare(str)<=0) ; } + virtual bool operator >(const char *str) const + { return (compare(str)>0) ; } + virtual bool operator >=(const char *str) const + { return (compare(str)>=0) ; } + virtual bool operator !=(const char *str) const + { return (compare(str)!=0) ; } + virtual bool operator ==(const char *str) const + { return (compare(str)==0) ; } + + /** + * + */ + virtual int compare(const std::string &str) const; + virtual bool operator <(const std::string &str) const + { return (compare(str)<0) ; } + virtual bool operator <=(const std::string &str) const + { return (compare(str)<=0) ; } + virtual bool operator >(const std::string &str) const + { return (compare(str)>0) ; } + virtual bool operator >=(const std::string &str) const + { return (compare(str)>=0) ; } + virtual bool operator !=(const std::string &str) const + { return (compare(str)!=0) ; } + virtual bool operator ==(const std::string &str) const + { return (compare(str)==0) ; } + + + + +protected: + + void init(); + + char *cstring; + + std::vector chars; + +}; // class DOMString + + + + +//############################### +//# O P E R A T O R S +//############################### + +DOMString &operator +(DOMString &a, const char *b); + +DOMString &operator +(const char *b, DOMString &a); + + + +} //namespace dom +} //namespace w3c +} //namespace org + +#endif // __DOMSTRING_H__ +//######################################################################### +//## E N D O F F I L E +//######################################################################### + + diff --git a/src/dom/domstringimpl.h b/src/dom/domstringimpl.h new file mode 100755 index 000000000..965f9702d --- /dev/null +++ b/src/dom/domstringimpl.h @@ -0,0 +1,107 @@ +#ifndef __DOMSTRINGIMPL_H__ +#define __DOMSTRINGIMPL_H__ +/** + * Phoebe DOM Implementation. + * + * This is a C++ approximation of the W3C DOM model, which follows + * fairly closely the specifications in the various .idl files, copies of + * which are provided for reference. Most important is this one: + * + * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/idl-definitions.html + * + * Authors: + * Bob Jamison + * + * Copyright (C) 2005 Bob Jamison + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +class DOMStringImpl +{ +public: + + /** + * + */ + DOMString(); + + /** + * + */ + DOMString(const char *str); + + /** + * + */ + DOMString(const DOMString &str); + + /** + * + */ + virtual ~DOMString(); + + /** + * + */ + virtual void append(const DOMString &str); + + /** + * + */ + virtual void append(const char *str); + + /** + * + */ + virtual void push_back(int ch); + + /** + * + */ + virtual DOMString &substring(int start, int end); + + /** + * + */ + virtual int charAt(unsigned long index); + + /** + * + */ + virtual unsigned long size(); + + /** + * + */ + virtual const char *c_str(); + + +protected: + + void init(); + + char *cstring; + + unsigned long length; + +}; + + + + + + +#endif /* __DOMSTRINGIMPL_H__ */ diff --git a/src/dom/events.h b/src/dom/events.h new file mode 100755 index 000000000..5a8fe6ccd --- /dev/null +++ b/src/dom/events.h @@ -0,0 +1,1351 @@ +#ifndef __EVENTS_H__ +#define __EVENTS_H__ + +/** + * Phoebe DOM Implementation. + * + * This is a C++ approximation of the W3C DOM model, which follows + * fairly closely the specifications in the various .idl files, copies of + * which are provided for reference. Most important is this one: + * + * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/idl-definitions.html + * + * Authors: + * Bob Jamison + * + * Copyright (C) 2005 Bob Jamison + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +#include "dom.h" +#include "views.h" + + + + +namespace org { +namespace w3c { +namespace dom { +namespace events { + + + + +//Local definitions +typedef dom::DOMString DOMString; +typedef dom::DOMTimeStamp DOMTimeStamp; +typedef dom::Node Node; + + + + +//forward declarations +class Event; +class EventTarget; +class EventListener; +class DocumentEvent; +class CustomEvent; +class UIEvent; +class TextEvent; +class MouseEvent; +class KeyboardEvent; +class MutationEvent; +class MutationNameEvent; + + + +/*######################################################################### +## EventException +#########################################################################*/ + +/** + * + */ +class EventException +{ +public: + + EventException(short theCode) + { + code = theCode; + } + + ~EventException() throw() + {} + + unsigned short code; +}; + + /** + * EventExceptionCode + */ + enum + { + UNSPECIFIED_EVENT_TYPE_ERR = 0, + DISPATCH_REQUEST_ERR = 1 + }; + + + +/*######################################################################### +## Event +#########################################################################*/ + +/** + * + */ +class Event +{ +public: + + /** + * PhaseType + */ + typedef enum + { + CAPTURING_PHASE = 1, + AT_TARGET = 2, + BUBBLING_PHASE = 3 + } PhaseType; + + /** + * + */ + virtual DOMString getType() const + { return eventType; } + + /** + * + */ + virtual EventTarget *getTarget() + { return target; } + + /** + * + */ + virtual EventTarget *getCurrentTarget() + { return currentTarget; } + + /** + * + */ + virtual unsigned short getEventPhase() + { return eventPhase; } + + /** + * + */ + virtual bool getBubbles() + { return canBubble; } + + /** + * + */ + virtual bool getCancelable() + { return cancelable; } + + /** + * + */ + virtual DOMTimeStamp getTimeStamp() + { return timeStamp; } + + /** + * + */ + virtual void stopPropagation() + { + } + + /** + * + */ + virtual void preventDefault() + { + } + + /** + * + */ + virtual void initEvent(const DOMString &eventTypeArg, + bool canBubbleArg, + bool cancelableArg) + { + namespaceURI = ""; + eventType = eventTypeArg; + canBubble = canBubbleArg; + cancelable = cancelableArg; + } + + + /** + * + */ + virtual DOMString getNamespaceURI() const + { return namespaceURI; } + + /** + * + */ + virtual bool isCustom() + { return custom; } + + /** + * + */ + virtual void stopImmediatePropagation() + { + } + + /** + * + */ + virtual bool isDefaultPrevented() + { return defaultPrevented; } + + /** + * + */ + virtual void initEventNS(const DOMString &namespaceURIArg, + const DOMString &eventTypeArg, + bool canBubbleArg, + bool cancelableArg) + { + namespaceURI = namespaceURIArg; + eventType = eventTypeArg; + canBubble = canBubbleArg; + cancelable = cancelableArg; + } + + //################## + //# Non-API methods + //################## + + /** + * + */ + Event() + { + init(); + } + + /** + * + */ + Event(const DOMString &eventTypeArg) + { + init(); + eventType = eventTypeArg; + } + + + /** + * + */ + Event(const Event &other) + { + eventType = other.eventType; + target = other.target; + currentTarget = other.currentTarget; + eventPhase = other.eventPhase; + canBubble = other.canBubble; + cancelable = other.cancelable; + timeStamp = other.timeStamp; + namespaceURI = other.namespaceURI; + custom = other.custom; + defaultPrevented = other.defaultPrevented; + } + + /** + * + */ + virtual ~Event() {} + +protected: + + /** + * + */ + void init() + { + eventType = ""; + target = NULL; + currentTarget = NULL; + eventPhase = 0; + canBubble = false; + cancelable = false; + //timeStamp = other.timeStamp; + namespaceURI = ""; + custom = false; + defaultPrevented = false; + } + + DOMString eventType; + EventTarget *target; + EventTarget *currentTarget; + unsigned short eventPhase; + bool canBubble; + bool cancelable; + DOMTimeStamp timeStamp; + DOMString namespaceURI; + bool custom; + bool defaultPrevented; + +}; + + + + +/*######################################################################### +## EventListener +#########################################################################*/ + +/** + * + */ +class EventListener +{ +public: + + /** + * + */ + virtual void handleEvent(const Event &evt) + {} + + //################## + //# Non-API methods + //################## + + /** + * + */ + virtual ~EventListener() {} +}; + + + + + + +/*######################################################################### +## EventTarget +#########################################################################*/ + +class EventListenerEntry +{ +public: + EventListenerEntry(const DOMString &namespaceURIArg, + const DOMString &eventTypeArg, + const EventListener *listenerArg, + bool useCaptureArg) + { + namespaceURI = namespaceURIArg; + eventType = eventTypeArg; + listener = (EventListener *)listenerArg; + useCapture = useCaptureArg; + } + + EventListenerEntry(const EventListenerEntry &other) + { + namespaceURI = other.namespaceURI; + eventType = other.eventType; + listener = other.listener; + useCapture = other.useCapture; + } + + virtual ~EventListenerEntry() {} + + DOMString namespaceURI; + DOMString eventType; + EventListener *listener; + bool useCapture; +}; + + +/** + * + */ +class EventTarget +{ +public: + + /** + * + */ + virtual void addEventListener(const DOMString &type, + const EventListener *listener, + bool useCapture) + { + EventListenerEntry entry("", type, listener, useCapture); + listeners.push_back(entry); + } + + /** + * + */ + virtual void removeEventListener(const DOMString &type, + const EventListener *listener, + bool useCapture) + { + std::vector::iterator iter; + for (iter = listeners.begin() ; iter != listeners.end() ; iter++) + { + EventListenerEntry entry = *iter; + if (entry.eventType == type && + entry.listener == listener && + useCapture && entry.useCapture) + listeners.erase(iter); + } + } + + /** + * + */ + virtual bool dispatchEvent(const Event &evt) throw(EventException) + { + + for (unsigned int i=0 ; ihandleEvent(evt); + } + } + return true; + } + + + /** + * + */ + virtual void addEventListenerNS(const DOMString &namespaceURI, + const DOMString &type, + const EventListener *listener, + bool useCapture) + { + EventListenerEntry entry(namespaceURI, type, listener, useCapture); + listeners.push_back(entry); + } + + /** + * + */ + virtual void removeEventListenerNS(const DOMString &namespaceURI, + const DOMString &type, + const EventListener *listener, + bool useCapture) + { + std::vector::iterator iter; + for (iter = listeners.begin() ; iter != listeners.end() ; iter++) + { + EventListenerEntry entry = *iter; + if (entry.namespaceURI == namespaceURI && + entry.eventType == type && + entry.listener == listener && + useCapture && entry.useCapture) + listeners.erase(iter); + } + } + + /** + * + */ + virtual bool willTriggerNS(const DOMString &namespaceURI, + const DOMString &type) + { + std::vector::iterator iter; + for (iter = listeners.begin() ; iter != listeners.end() ; iter++) + { + EventListenerEntry entry = *iter; + if (entry.namespaceURI == namespaceURI && + entry.eventType == type) + return true; + } + return false; + } + + /** + * + */ + virtual bool hasEventListenerNS(const DOMString &namespaceURI, + const DOMString &type) + { + std::vector::iterator iter; + for (iter = listeners.begin() ; iter != listeners.end() ; iter++) + { + EventListenerEntry entry = *iter; + if (entry.namespaceURI == namespaceURI && + entry.eventType == type) + return true; + } + return false; + } + + + //################## + //# Non-API methods + //################## + + /** + * + */ + EventTarget() {} + + /** + * + */ + EventTarget(const EventTarget &other) + { + listeners = other.listeners; + } + + /** + * + */ + virtual ~EventTarget() {} + +protected: + + std::vector listeners; + +}; + + + + +/*######################################################################### +## DocumentEvent +#########################################################################*/ + +/* + * + */ +class DocumentEvent : virtual public Event +{ +public: + + /** + * + */ + virtual Event createEvent(const DOMString &eventType) + throw (dom::DOMException) + { + Event event; + return event; + } + + /** + * + */ + virtual bool canDispatch(const DOMString &namespaceURI, + const DOMString &type) + { + return dispatchable; + } + + //################## + //# Non-API methods + //################## + + /** + * + */ + DocumentEvent() {} + + /** + * + */ + DocumentEvent(const DocumentEvent &other) : Event(other) + { + dispatchable = other.dispatchable; + } + + /** + * + */ + virtual ~DocumentEvent() {} + +protected: + + bool dispatchable; + + +}; + + +/*######################################################################### +## CustomEvent +#########################################################################*/ + +/* + * + */ +class CustomEvent : virtual public Event +{ +public: + + /** + * + */ + virtual void setDispatchState(const EventTarget *target, + unsigned short phase) + { + } + + /** + * + */ + virtual bool isPropagationStopped() + { + return propagationStopped; + } + + /** + * + */ + virtual bool isImmediatePropagationStopped() + { + return immediatePropagationStopped; + } + + //################## + //# Non-API methods + //################## + + /** + * + */ + CustomEvent() {} + + /** + * + */ + CustomEvent(const CustomEvent &other) : Event(other) + { + propagationStopped = other.propagationStopped; + immediatePropagationStopped = other.immediatePropagationStopped; + } + + /** + * + */ + virtual ~CustomEvent() {} + +protected: + + bool propagationStopped; + bool immediatePropagationStopped; + + + +}; + + + + +/*######################################################################### +## UIEvent +#########################################################################*/ + +/** + * + */ +class UIEvent : virtual public Event +{ +public: + + /** + * Note that the return type as listed in level3 events.idl is + * AbstractView, while in level3 views.idl it is called View + */ + virtual views::View getView() + { return view; } + + /** + * + */ + virtual long getDetail() + { return detail; } + + /** + * Note that views.idl and events.idl disagree on the name of Views + */ + virtual void initUIEvent(const DOMString &typeArg, + bool canBubbleArg, + bool cancelableArg, + const views::View *viewArg, + long detailArg) + { + } + + /** + * Note that views.idl and events.idl disagree on the name of Views + */ + virtual void initUIEventNS(const DOMString &namespaceURI, + const DOMString &typeArg, + bool canBubbleArg, + bool cancelableArg, + const views::View *viewArg, + long detailArg) + { + } + + //################## + //# Non-API methods + //################## + + /** + * + */ + UIEvent() {} + + /** + * + */ + UIEvent(const UIEvent &other) : Event(other) + { + view = other.view; + detail = other.detail; + } + + /** + * + */ + virtual ~UIEvent() {} + +protected: + + views::View view; + long detail; +}; + + + + +/*######################################################################### +## TextEvent +#########################################################################*/ + +/** + * + */ +class TextEvent : virtual public UIEvent +{ +public: + + /** + * + */ + virtual DOMString getData() + { return data; } + + /** + * Note that views.idl and events.idl disagree on the name of Views + */ + virtual void initTextEvent(const DOMString &typeArg, + bool canBubbleArg, + bool cancelableArg, + const views::View *viewArg, + long detailArg) + { + } + + /** + * + */ + virtual void initTextEventNS(const DOMString &namespaceURI, + const DOMString &typeArg, + bool canBubbleArg, + bool cancelableArg, + const views::View *viewArg, + long detailArg) + { + } + + //################## + //# Non-API methods + //################## + + /** + * + */ + TextEvent() {} + + /** + * + */ + TextEvent(const TextEvent &other) : Event(other), UIEvent(other) + { + data = other.data; + } + + /** + * + */ + virtual ~TextEvent() {} + +protected: + + DOMString data; + +}; + + + + + + + + +/*######################################################################### +## MouseEvent +#########################################################################*/ + +/** + * + */ +class MouseEvent : virtual public UIEvent +{ +public: + + /** + * + */ + virtual long getScreenX() + { return screenX; } + + /** + * + */ + virtual long getScreenY() + { return screenY; } + + /** + * + */ + virtual long getClientX() + { return clientX; } + + /** + * + */ + virtual long getClientY() + { return clientY; } + + /** + * + */ + virtual bool getCtrlKey() + { return ctrlKey; } + + /** + * + */ + virtual bool getShiftKey() + { return shiftKey; } + + /** + * + */ + virtual bool getAltKey() + { return altKey; } + + /** + * + */ + virtual bool getMetaKey() + { return metaKey; } + + /** + * + */ + virtual unsigned short getButton() + { return button; } + + /** + * + */ + virtual EventTarget *getRelatedTarget() + { return relatedTarget; } + + + /** + * + */ + virtual bool getModifierState() + { return modifierState; } + + /** + * + */ + virtual void initMouseEvent(const DOMString &typeArg, + bool canBubbleArg, + bool cancelableArg, + const views::View *viewArg, + long detailArg, + long screenXArg, + long screenYArg, + long clientXArg, + long clientYArg, + bool ctrlKeyArg, + bool altKeyArg, + bool shiftKeyArg, + bool metaKeyArg, + unsigned short buttonArg, + const EventTarget *relatedTargetArg) + { + } + + + /** + * + */ + virtual void initMouseEventNS(const DOMString &namespaceURI, + const DOMString &typeArg, + bool canBubbleArg, + bool cancelableArg, + const views::View *viewArg, + long detailArg, + long screenXArg, + long screenYArg, + long clientXArg, + long clientYArg, + unsigned short buttonArg, + const EventTarget *relatedTargetArg, + const DOMString &modifiersList) + { + } + + //################## + //# Non-API methods + //################## + + /** + * + */ + MouseEvent() {} + + /** + * + */ + MouseEvent(const MouseEvent &other) : Event(other), UIEvent(other) + { + screenX = other.screenX; + screenY = other.screenY; + clientX = other.clientX; + clientY = other.clientY; + ctrlKey = other.ctrlKey; + shiftKey = other.shiftKey; + altKey = other.altKey; + metaKey = other.metaKey; + button = other.button; + relatedTarget = other.relatedTarget; + modifierState = other.modifierState; + } + + /** + * + */ + virtual ~MouseEvent() {} + +protected: + + long screenX; + long screenY; + long clientX; + long clientY; + bool ctrlKey; + bool shiftKey; + bool altKey; + bool metaKey; + unsigned short button; + EventTarget *relatedTarget; + bool modifierState; + + +}; + + + + +/*######################################################################### +## KeyboardEvent +#########################################################################*/ + +/** + * + */ +class KeyboardEvent : virtual public UIEvent +{ +public: + + typedef enum + { + DOM_KEY_LOCATION_STANDARD = 0x00, + DOM_KEY_LOCATION_LEFT = 0x01, + DOM_KEY_LOCATION_RIGHT = 0x02, + DOM_KEY_LOCATION_NUMPAD = 0x03 + } KeyLocationCode; + + /** + * + */ + virtual DOMString getKeyIdentifier() + { return keyIdentifier; } + + /** + * + */ + virtual unsigned long getKeyLocation() + { return keyLocation; } + + /** + * + */ + virtual bool getCtrlKey() + { return ctrlKey; } + + /** + * + */ + virtual bool getShiftKey() + { return shiftKey; } + + /** + * + */ + virtual bool getAltKey() + { return altKey; } + + /** + * + */ + virtual bool getMetaKey() + { return metaKey; } + + /** + * + */ + virtual bool getModifierState() + { return modifierState; } + + /** + * + */ + virtual void initKeyboardEvent(const DOMString &typeArg, + bool canBubbleArg, + bool cancelableArg, + const views::View *viewArg, + const DOMString &keyIdentifier, + unsigned long keyLocation, + const DOMString modifiersList) + { + } + + + + /** + * + */ + virtual void initKeyboardEventNS(const DOMString &namespaceURI, + const DOMString &typeArg, + bool canBubbleArg, + bool cancelableArg, + const views::View *viewArg, + const DOMString &keyIdentifier, + unsigned long keyLocation, + const DOMString modifiersList) + { + } + + //################## + //# Non-API methods + //################## + + /** + * + */ + KeyboardEvent() {} + + /** + * + */ + KeyboardEvent(const KeyboardEvent &other) : Event(other), UIEvent(other) + { + keyIdentifier = other.keyIdentifier; + keyLocation = other.keyLocation; + ctrlKey = other.ctrlKey; + shiftKey = other.shiftKey; + altKey = other.altKey; + metaKey = other.metaKey; + modifierState = other.modifierState; + } + + /** + * + */ + virtual ~KeyboardEvent() {} + +protected: + + DOMString keyIdentifier; + unsigned long keyLocation; + bool ctrlKey; + bool shiftKey; + bool altKey; + bool metaKey; + bool modifierState; +}; + + + + + + + + + +/*######################################################################### +## MutationEvent +#########################################################################*/ + +/** + * + */ +class MutationEvent : virtual public Event +{ +public: + + /** + * attrChangeType + */ + typedef enum + { + MODIFICATION = 1, + ADDITION = 2, + REMOVAL = 3 + } AttrChangeType; + + /** + * + */ + virtual Node *getRelatedNode() + { return relatedNode; } + + /** + * + */ + virtual DOMString getPrevValue() + { return prevValue; } + + /** + * + */ + virtual DOMString getNewValue() + { return newValue; } + + /** + * + */ + virtual DOMString getAttrName() + { return attrName; } + + /** + * + */ + virtual unsigned short getAttrChange() + { + return attrChange; + } + + /** + * + */ + virtual void initMutationEvent(const DOMString &typeArg, + bool canBubbleArg, + bool cancelableArg, + const Node *relatedNodeArg, + const DOMString &prevValueArg, + const DOMString &newValueArg, + const DOMString &attrNameArg, + unsigned short attrChangeArg) + { + } + + /** + * + */ + virtual void initMutationEventNS(const DOMString &namespaceURI, + const DOMString &typeArg, + bool canBubbleArg, + bool cancelableArg, + const Node *relatedNodeArg, + const DOMString &prevValueArg, + const DOMString &newValueArg, + const DOMString &attrNameArg, + unsigned short attrChangeArg) + { + } + + + //################## + //# Non-API methods + //################## + + /** + * + */ + MutationEvent() + { + relatedNode = NULL; + } + + /** + * + */ + MutationEvent(const MutationEvent &other) : Event(other) + { + relatedNode = other.relatedNode; + prevValue = other.prevValue; + newValue = other.newValue; + attrName = other.attrName; + attrChange = other.attrChange; + } + + /** + * + */ + virtual ~MutationEvent() {} + +protected: + + Node *relatedNode; + DOMString prevValue; + DOMString newValue; + DOMString attrName; + unsigned short attrChange; + +}; + + + + +/*######################################################################### +## MutationNameEvent +#########################################################################*/ + +/** + * + */ +class MutationNameEvent : virtual public MutationEvent +{ +public: + + /** + * + */ + virtual DOMString getPrevNamespaceURI() + { return prevNamespaceURI; } + + /** + * + */ + virtual DOMString getPrevNodeName() + { return prevNodeName; } + + /** + * + */ + virtual void initMutationNameEvent(const DOMString &typeArg, + bool canBubbleArg, + bool cancelableArg, + const Node *relatedNodeArg, + const DOMString &prevNamespaceURIArg, + const DOMString &prevNodeNameArg) + { + } + + + /** + * + */ + virtual void initMutationNameEventNS(const DOMString &namespaceURI, + const DOMString &typeArg, + bool canBubbleArg, + bool cancelableArg, + const Node *relatedNodeArg, + const DOMString &prevNamespaceURIArg, + const DOMString &prevNodeNameArg) + { + } + + + + //################## + //# Non-API methods + //################## + + /** + * + */ + MutationNameEvent() {} + + + /** + * + */ + MutationNameEvent(const MutationNameEvent &other) + : Event(other), MutationEvent(other) + { + prevNamespaceURI = other.prevNamespaceURI; + prevNodeName = other.prevNodeName; + } + + + /** + * + */ + virtual ~MutationNameEvent() {} + +protected: + + DOMString prevNamespaceURI; + DOMString prevNodeName; + + +}; + + + + + + +} //namespace events +} //namespace dom +} //namespace w3c +} //namespace org + +#endif /* __EVENTS_H__ */ + +/*######################################################################### +## E N D O F F I L E +#########################################################################*/ + diff --git a/src/dom/events.idl b/src/dom/events.idl new file mode 100755 index 000000000..5773dcaf6 --- /dev/null +++ b/src/dom/events.idl @@ -0,0 +1,298 @@ +/* + * Copyright (c) 2003 World Wide Web Consortium, + * + * (Massachusetts Institute of Technology, European Research Consortium for + * Informatics and Mathematics, Keio University). All Rights Reserved. This + * work is distributed under the W3C(r) Software License [1] in the hope that + * it will be useful, but WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * [1] http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 + */ + +// File: http://www.w3.org/TR/2003/NOTE-DOM-Level-3-Events-20031107/events.idl + +#ifndef _EVENTS_IDL_ +#define _EVENTS_IDL_ + +#include "dom.idl" +#include "views.idl" + +#pragma prefix "dom.w3c.org" +module events +{ + + typedef dom::DOMString DOMString; + typedef dom::DOMTimeStamp DOMTimeStamp; + typedef dom::DOMObject DOMObject; + typedef dom::Node Node; + + interface EventTarget; + interface EventListener; + + // Introduced in DOM Level 2: + exception EventException { + unsigned short code; + }; + // EventExceptionCode + const unsigned short UNSPECIFIED_EVENT_TYPE_ERR = 0; + // Introduced in DOM Level 3: + const unsigned short DISPATCH_REQUEST_ERR = 1; + + + // Introduced in DOM Level 2: + interface Event { + + // PhaseType + const unsigned short CAPTURING_PHASE = 1; + const unsigned short AT_TARGET = 2; + const unsigned short BUBBLING_PHASE = 3; + + readonly attribute DOMString type; + readonly attribute EventTarget target; + readonly attribute EventTarget currentTarget; + readonly attribute unsigned short eventPhase; + readonly attribute boolean bubbles; + readonly attribute boolean cancelable; + readonly attribute DOMTimeStamp timeStamp; + void stopPropagation(); + void preventDefault(); + void initEvent(in DOMString eventTypeArg, + in boolean canBubbleArg, + in boolean cancelableArg); + // Introduced in DOM Level 3: + readonly attribute DOMString namespaceURI; + // Introduced in DOM Level 3: + boolean isCustom(); + // Introduced in DOM Level 3: + void stopImmediatePropagation(); + // Introduced in DOM Level 3: + boolean isDefaultPrevented(); + // Introduced in DOM Level 3: + void initEventNS(in DOMString namespaceURIArg, + in DOMString eventTypeArg, + in boolean canBubbleArg, + in boolean cancelableArg); + }; + + // Introduced in DOM Level 2: + interface EventTarget { + void addEventListener(in DOMString type, + in EventListener listener, + in boolean useCapture); + void removeEventListener(in DOMString type, + in EventListener listener, + in boolean useCapture); + // Modified in DOM Level 3: + boolean dispatchEvent(in Event evt) + raises(EventException); + // Introduced in DOM Level 3: + void addEventListenerNS(in DOMString namespaceURI, + in DOMString type, + in EventListener listener, + in boolean useCapture, + in DOMObject evtGroup); + // Introduced in DOM Level 3: + void removeEventListenerNS(in DOMString namespaceURI, + in DOMString type, + in EventListener listener, + in boolean useCapture); + // Introduced in DOM Level 3: + boolean willTriggerNS(in DOMString namespaceURI, + in DOMString type); + // Introduced in DOM Level 3: + boolean hasEventListenerNS(in DOMString namespaceURI, + in DOMString type); + }; + + // Introduced in DOM Level 2: + interface EventListener { + void handleEvent(in Event evt); + }; + + // Introduced in DOM Level 2: + interface DocumentEvent { + Event createEvent(in DOMString eventType) + raises(dom::DOMException); + // Introduced in DOM Level 3: + boolean canDispatch(in DOMString namespaceURI, + in DOMString type); + }; + + // Introduced in DOM Level 3: + interface CustomEvent : Event { + void setDispatchState(in EventTarget target, + in unsigned short phase); + boolean isPropagationStopped(); + boolean isImmediatePropagationStopped(); + }; + + // Introduced in DOM Level 2: + interface UIEvent : Event { + readonly attribute views::AbstractView view; + readonly attribute long detail; + void initUIEvent(in DOMString typeArg, + in boolean canBubbleArg, + in boolean cancelableArg, + in views::AbstractView viewArg, + in long detailArg); + // Introduced in DOM Level 3: + void initUIEventNS(in DOMString namespaceURI, + in DOMString typeArg, + in boolean canBubbleArg, + in boolean cancelableArg, + in views::AbstractView viewArg, + in long detailArg); + }; + + // Introduced in DOM Level 3: + interface TextEvent : UIEvent { + readonly attribute DOMString data; + void initTextEvent(in DOMString typeArg, + in boolean canBubbleArg, + in boolean cancelableArg, + in views::AbstractView viewArg, + in DOMString dataArg); + void initTextEventNS(in DOMString namespaceURI, + in DOMString type, + in boolean canBubbleArg, + in boolean cancelableArg, + in views::AbstractView viewArg, + in DOMString dataArg); + }; + + // Introduced in DOM Level 2: + interface MouseEvent : UIEvent { + readonly attribute long screenX; + readonly attribute long screenY; + readonly attribute long clientX; + readonly attribute long clientY; + readonly attribute boolean ctrlKey; + readonly attribute boolean shiftKey; + readonly attribute boolean altKey; + readonly attribute boolean metaKey; + readonly attribute unsigned short button; + readonly attribute EventTarget relatedTarget; + void initMouseEvent(in DOMString typeArg, + in boolean canBubbleArg, + in boolean cancelableArg, + in views::AbstractView viewArg, + in long detailArg, + in long screenXArg, + in long screenYArg, + in long clientXArg, + in long clientYArg, + in boolean ctrlKeyArg, + in boolean altKeyArg, + in boolean shiftKeyArg, + in boolean metaKeyArg, + in unsigned short buttonArg, + in EventTarget relatedTargetArg); + // Introduced in DOM Level 3: + boolean getModifierState(in DOMString keyIdentifierArg); + // Introduced in DOM Level 3: + void initMouseEventNS(in DOMString namespaceURI, + in DOMString typeArg, + in boolean canBubbleArg, + in boolean cancelableArg, + in views::AbstractView viewArg, + in long detailArg, + in long screenXArg, + in long screenYArg, + in long clientXArg, + in long clientYArg, + in unsigned short buttonArg, + in EventTarget relatedTargetArg, + in DOMString modifiersList); + }; + + // Introduced in DOM Level 3: + interface KeyboardEvent : UIEvent { + + // KeyLocationCode + const unsigned long DOM_KEY_LOCATION_STANDARD = 0x00; + const unsigned long DOM_KEY_LOCATION_LEFT = 0x01; + const unsigned long DOM_KEY_LOCATION_RIGHT = 0x02; + const unsigned long DOM_KEY_LOCATION_NUMPAD = 0x03; + + readonly attribute DOMString keyIdentifier; + readonly attribute unsigned long keyLocation; + readonly attribute boolean ctrlKey; + readonly attribute boolean shiftKey; + readonly attribute boolean altKey; + readonly attribute boolean metaKey; + boolean getModifierState(in DOMString keyIdentifierArg); + void initKeyboardEvent(in DOMString typeArg, + in boolean canBubbleArg, + in boolean cancelableArg, + in views::AbstractView viewArg, + in DOMString keyIdentifierArg, + in unsigned long keyLocationArg, + in DOMString modifiersList); + void initKeyboardEventNS(in DOMString namespaceURI, + in DOMString typeArg, + in boolean canBubbleArg, + in boolean cancelableArg, + in views::AbstractView viewArg, + in DOMString keyIdentifierArg, + in unsigned long keyLocationArg, + in DOMString modifiersList); + }; + + // Introduced in DOM Level 2: + interface MutationEvent : Event { + + // attrChangeType + const unsigned short MODIFICATION = 1; + const unsigned short ADDITION = 2; + const unsigned short REMOVAL = 3; + + readonly attribute Node relatedNode; + readonly attribute DOMString prevValue; + readonly attribute DOMString newValue; + readonly attribute DOMString attrName; + readonly attribute unsigned short attrChange; + void initMutationEvent(in DOMString typeArg, + in boolean canBubbleArg, + in boolean cancelableArg, + in Node relatedNodeArg, + in DOMString prevValueArg, + in DOMString newValueArg, + in DOMString attrNameArg, + in unsigned short attrChangeArg); + // Introduced in DOM Level 3: + void initMutationEventNS(in DOMString namespaceURI, + in DOMString typeArg, + in boolean canBubbleArg, + in boolean cancelableArg, + in Node relatedNodeArg, + in DOMString prevValueArg, + in DOMString newValueArg, + in DOMString attrNameArg, + in unsigned short attrChangeArg); + }; + + // Introduced in DOM Level 3: + interface MutationNameEvent : MutationEvent { + readonly attribute DOMString prevNamespaceURI; + readonly attribute DOMString prevNodeName; + // Introduced in DOM Level 3: + void initMutationNameEvent(in DOMString typeArg, + in boolean canBubbleArg, + in boolean cancelableArg, + in Node relatedNodeArg, + in DOMString prevNamespaceURIArg, + in DOMString prevNodeNameArg); + // Introduced in DOM Level 3: + void initMutationNameEventNS(in DOMString namespaceURI, + in DOMString typeArg, + in boolean canBubbleArg, + in boolean cancelableArg, + in Node relatedNodeArg, + in DOMString prevNamespaceURIArg, + in DOMString prevNodeNameArg); + }; +}; + +#endif // _EVENTS_IDL_ + diff --git a/src/dom/inkscape.css b/src/dom/inkscape.css new file mode 100755 index 000000000..e73b15038 --- /dev/null +++ b/src/dom/inkscape.css @@ -0,0 +1,493 @@ +/* +* CSS for Inkscape Website (http://www.inkscape.org/) +* +* By: Tom von Schwerdtner | Etria LLP (http://www.etria.com/) +* +*/ + +body { + color: #000000; + background: #ffffff; + padding: 0px; + margin: 0px; + font-family: arial, Helvetica, 'Bitstream Vera Sans', 'Luxi Sans', Verdana, Sans-Serif; + font-size: 80%; +} + +a:link, a:visited, a:hover { + font-weight: bold; + color: #0081ac; + text-decoration: none; +} + +a:hover { + text-decoration: underline; +} + +a:visited { + color: #ac0011; +} + +div.top { + background:#0081ac; + width: 100%; + height: 100px; + border-bottom: 1px black solid; +} + +div.top a.logo, +div.top a.logo:link, +div.top a.logo:hover, +div.top a.logo:visited + { + color: #ffffff; + background: transparent; + border: none; + text-decoration: none; +} + +div.top h1 { + color: #ffffff; + background: transparent; + font-size: 40px; + font-family: arial; + margin: 0px; + padding: 20px; + float: left; +} + +img.logo { + float: right; + border: none; +} + +#menu { + float: left; + border: 1px #999999 solid; + width: 150px; + margin-left: 10px; + margin-top: 10px; + margin-bottom: 10px; +} + +#menu ul { + list-style: none; + padding: 0px; + margin: 0px; +} + +#menu li.sub { + color: #000000; + background: #d6d6d6; + font-weight: bold; + padding: 0px; +} + +#menu .title { + padding: 4px; + text-align: center; +} + +#menu ul.sub { + padding: 0px; + margin: 0px; + border-top: 1px #999999 solid; + border-bottom: 1px #999999 solid; + list-style: none; +} + +#menu li a { + display: block; + background: #f0f0f0; + color: #0081ac; + border-top: 1px #d6d6d6 solid; + border-bottom: 1px #d6d6d6 solid; + margin: 0px; + padding: 4px; + padding-left: 10px; + width: 100%; +} +#menu li a:visited { + color: #0081ac; +} + +html>body #menu li a { + width: auto; +} + +#menu li.item a:hover, ul.sub li.item a:hover { + display: block; + background: #ac0011; + /*background: #DC878F;*/ + color: #ffffff; + border-top: 1px #6F000B solid; + border-bottom: 1px #6F000B solid; + text-decoration: none; +} + +#sourceforge { + text-align: center; + border: none; +} + +html>body #sourceforge { + width: auto; +} + +div.content { + padding: 20px; + + /* this is a hack */ + margin-left: 160px; + margin-right: 20px; +} + + +#skipnav { + display: none; +} + +#togglecss { + position: absolute; + top: 110px; + right: 10px; +} + +div.news { +} + +div.news div.item { +} + +div.news div.item img { + margin: 10px; +} + +div.news div.item img.right { + float: right; + margin-right: 0px; +} + +div.news div.item img.left { + float: left; + margin-left: 0px; +} + +img.thumb { + border: 1px #999999 solid; +} + +div.news div.item h3 { + font-weight: bold; + border-left: 10px #999999 solid; + padding-left: 4px; + margin-bottom: 4px; + + clear: right; +} + +div.news div.item p { + margin-top: 0px; + margin-left: 20px; + margin-right: 20px; +} + +p { + text-align: justify; +} + +h2 { + border-bottom: 1px #000000 solid; + clear: right; +} + +pre { + border: 1px #006F02 solid; + background: #B0E4AE; + padding: 4px; +} + + +/* File Releases */ + +div.rss-files { +} + +div.rss-files div.file { + background: #f0f0f0; + color: #000000; + border: 1px #999999 solid; + padding: 2px; + margin: 20px; +} + +div.rss-files div.file div.title { + font-weight: bold; + padding: 4px; + padding-top: 2px; +} +div.rss-files div.file div.description { + font-weight: normal; + border: 1px #999999 solid; + background: #ffffff; + color: #000000; + padding: 4px; +} + +#footer { + text-align: center; + width: 100%; + border-top: 1px #000000 solid; + border-bottom: 1px #000000 solid; + padding-top: 4px; + padding-bottom: 4px; + background:#0081AC; + color: #ffffff; + clear: both; +} + +#footer img { + border: none; +} + +#footer a { + color: white; +} +/* We are overriding some earlier styles here, so this needs to be at the end + */ +/* +a.external:link, +a.external:visited, +a.external:hover, +#menu li a.external, +#menu li a.external:hover +{ + background-image: url('/images/globe.png'); + background-repeat: no-repeat; + background-position: center right; + padding-right: 18px; +} +*/ + +/* Doxygen Specific */ + +div.doxygen { +} + +div.doxygen pre { + background: #F8F8C6; + background: #fffff0; + color: #000000; + border: 1px #808000 solid; +} + +div.doxygen pre a:hover { +} + +div.doxygen pre .preprocessor { + font-weight: bold; + color: #006809; +} + +div.doxygen pre .keyword { + color: #68005F; +} + +div.doxygen pre .keywordflow { + color: #120053; + font-weight: bold; +} + +div.doxygen pre .keywordtype { + font-weight: bold; + color: #495300; +} + +div.doxygen pre .comment { + font-style: italic; + font-weight: bold; +} + + + + +table { + + margin-left: auto; + margin-right: auto; + width: 100%; + + clear: none; + + border-collapse: collapse; + + + background: none; + + +/* font-family: Arial, Helvetica, 'Bitstream Vera Sans', 'Luxi Sans', Verdana, Sans-Serif; */ + font-size: 13px; + +} + +td { + padding: 8px; + vertical-align: top; +} + + +table.roadmap { + background: #eee; +} + +table.roadmap td { + + border: 1px solid #999; + /* width: 50%; */ + + +} + +tr.header { + font-weight: bold; + background: #ddd; +} + +td.title { + text-align: center; + font-size: 16px; + font-weight: bold; + background: #ddd; +} + + + +img.float { + float: right; + + margin-top: 7px; + margin-left: 10px; + /* margin-right: 10px; */ + margin-bottom: 10px; +} + + + +/*@import: url(wiki.css)*/ + + + +/* FORM STUFF */ + +SELECT, option, textarea, input { + + color: #000000; + font-size: 10px; + text-decoration: none; + background: white; + border: 1px solid #666666; + + margin: 2px 0px 2px 0; + padding: 2px; + +} + +/* now make them all have nice hovers */ + + + +SELECT:hover, option:hover, textarea:hover, input:hover { + background: #ddd; +} + + +form.search { + /*display: inline; + background: #f0f0f0; + */ + + text-align: center; + + display: block; + background: #f0f0f0; + color: #0081ac; + border-top: 1px #d6d6d6 solid; + border-bottom: 1px #d6d6d6 solid; + margin: 0px; + padding: 4px; + padding-left: 10px; + + +} + +form.search:hover { + background: #ac0011; +} + + + +#post_news input +{ + width: 35%; +} + +#post_news textarea +{ + width: 100%; + height: 150px; +} + +input#login, +#post_news input#preview, +#post_news input#save, +#post_news input#reset +{ + width: 100px; +} + + +#post_news table +{ + padding: 0; +} + +#post_news td +{ + padding-left: 0; +} +#post_news table tr td.header +{ + width: 10%; + font-weight: bold; +} + +.alert +{ + color: red; +} + + +div.alert +{ + border: 1px solid red; + padding: 8px; +} + +.preview, +.message +{ + border: 1px solid #ccc; + padding: 8px; +} + + +#navbar +{ + padding: 8px; + background: #ccc; +} + +#navbar a +{ + padding-right: 12px; +} diff --git a/src/dom/inkscape.logo.svg b/src/dom/inkscape.logo.svg new file mode 100755 index 000000000..755603b11 --- /dev/null +++ b/src/dom/inkscape.logo.svg @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + diff --git a/src/dom/js/Makefile b/src/dom/js/Makefile new file mode 100644 index 000000000..bd7ee7360 --- /dev/null +++ b/src/dom/js/Makefile @@ -0,0 +1,1471 @@ +# ################################# +# Unix/Linux makefile for libjs.a +# ################################# + + +CC=gcc +CFLAGS= -O2 -DXP_UNIX + +all: js + +INC += -Ifdlibm + +OBJ = \ + fdlibm/e_acos.o \ + fdlibm/e_acosh.o \ + fdlibm/e_asin.o \ + fdlibm/e_atan2.o \ + fdlibm/e_atanh.o \ + fdlibm/e_cosh.o \ + fdlibm/e_exp.o \ + fdlibm/e_fmod.o \ + fdlibm/e_gamma.o \ + fdlibm/e_gamma_r.o \ + fdlibm/e_hypot.o \ + fdlibm/e_j0.o \ + fdlibm/e_j1.o \ + fdlibm/e_jn.o \ + fdlibm/e_lgamma.o \ + fdlibm/e_lgamma_r.o \ + fdlibm/e_log.o \ + fdlibm/e_log10.o \ + fdlibm/e_pow.o \ + fdlibm/e_rem_pio2.o \ + fdlibm/e_remainder.o \ + fdlibm/e_scalb.o \ + fdlibm/e_sinh.o \ + fdlibm/e_sqrt.o \ + fdlibm/k_cos.o \ + fdlibm/k_rem_pio2.o \ + fdlibm/k_sin.o \ + fdlibm/k_standard.o \ + fdlibm/k_tan.o \ + fdlibm/s_asinh.o \ + fdlibm/s_atan.o \ + fdlibm/s_cbrt.o \ + fdlibm/s_ceil.o \ + fdlibm/s_copysign.o \ + fdlibm/s_cos.o \ + fdlibm/s_erf.o \ + fdlibm/s_expm1.o \ + fdlibm/s_fabs.o \ + fdlibm/s_finite.o \ + fdlibm/s_floor.o \ + fdlibm/s_frexp.o \ + fdlibm/s_ilogb.o \ + fdlibm/s_isnan.o \ + fdlibm/s_ldexp.o \ + fdlibm/s_lib_version.o \ + fdlibm/s_log1p.o \ + fdlibm/s_logb.o \ + fdlibm/s_matherr.o \ + fdlibm/s_modf.o \ + fdlibm/s_nextafter.o \ + fdlibm/s_rint.o \ + fdlibm/s_scalbn.o \ + fdlibm/s_signgam.o \ + fdlibm/s_significand.o \ + fdlibm/s_sin.o \ + fdlibm/s_tan.o \ + fdlibm/s_tanh.o \ + fdlibm/w_acos.o \ + fdlibm/w_acosh.o \ + fdlibm/w_asin.o \ + fdlibm/w_atan2.o \ + fdlibm/w_atanh.o \ + fdlibm/w_cosh.o \ + fdlibm/w_exp.o \ + fdlibm/w_fmod.o \ + fdlibm/w_gamma.o \ + fdlibm/w_gamma_r.o \ + fdlibm/w_hypot.o \ + fdlibm/w_j0.o \ + fdlibm/w_j1.o \ + fdlibm/w_jn.o \ + fdlibm/w_lgamma.o \ + fdlibm/w_lgamma_r.o \ + fdlibm/w_log.o \ + fdlibm/w_log10.o \ + fdlibm/w_pow.o \ + fdlibm/w_remainder.o \ + fdlibm/w_scalb.o \ + fdlibm/w_sinh.o \ + fdlibm/w_sqrt.o \ + jsapi.o \ + jsarena.o \ + jsarray.o \ + jsatom.o \ + jsbool.o \ + jscntxt.o \ + jscpucfg.o \ + jsdate.o \ + jsdbgapi.o \ + jsdhash.o \ + jsdtoa.o \ + jsemit.o \ + jsexn.o \ + jsfile.o \ + jsfun.o \ + jsgc.o \ + jshash.o \ + jsinterp.o \ + jslock.o \ + jslog2.o \ + jslong.o \ + jsmath.o \ + jsnum.o \ + jsobj.o \ + jsopcode.o \ + jsparse.o \ + jsprf.o \ + jsregexp.o \ + jsscan.o \ + jsscope.o \ + jsscript.o \ + jsstr.o \ + jsutil.o \ + jsxdrapi.o \ + prmjtime.o + +js: js.o libjs.a + $(CC) -o js js.o libjs.a -lm + +libjs.a: $(OBJ) + ar crv libjs.a $(OBJ) + ranlib libjs.a + +clean: + $(RM) js libjs.a $(OBJ) + +# ########################### +# DEPENDENCIES +# ########################### + + +fdlibm/e_acos.o: \ + fdlibm/e_acos.c \ + fdlibm/fdlibm.h + +fdlibm/e_acosh.o: \ + fdlibm/e_acosh.c \ + fdlibm/fdlibm.h + +fdlibm/e_asin.o: \ + fdlibm/e_asin.c \ + fdlibm/fdlibm.h + +fdlibm/e_atan2.o: \ + fdlibm/e_atan2.c \ + fdlibm/fdlibm.h + +fdlibm/e_atanh.o: \ + fdlibm/e_atanh.c \ + fdlibm/fdlibm.h + +fdlibm/e_cosh.o: \ + fdlibm/e_cosh.c \ + fdlibm/fdlibm.h + +fdlibm/e_exp.o: \ + fdlibm/e_exp.c \ + fdlibm/fdlibm.h + +fdlibm/e_fmod.o: \ + fdlibm/e_fmod.c \ + fdlibm/fdlibm.h + +fdlibm/e_gamma.o: \ + fdlibm/e_gamma.c \ + fdlibm/fdlibm.h + +fdlibm/e_gamma_r.o: \ + fdlibm/e_gamma_r.c \ + fdlibm/fdlibm.h + +fdlibm/e_hypot.o: \ + fdlibm/e_hypot.c \ + fdlibm/fdlibm.h + +fdlibm/e_j0.o: \ + fdlibm/e_j0.c \ + fdlibm/fdlibm.h + +fdlibm/e_j1.o: \ + fdlibm/e_j1.c \ + fdlibm/fdlibm.h + +fdlibm/e_jn.o: \ + fdlibm/e_jn.c \ + fdlibm/fdlibm.h + +fdlibm/e_lgamma.o: \ + fdlibm/e_lgamma.c \ + fdlibm/fdlibm.h + +fdlibm/e_lgamma_r.o: \ + fdlibm/e_lgamma_r.c \ + fdlibm/fdlibm.h + +fdlibm/e_log.o: \ + fdlibm/e_log.c \ + fdlibm/fdlibm.h + +fdlibm/e_log10.o: \ + fdlibm/e_log10.c \ + fdlibm/fdlibm.h + +fdlibm/e_pow.o: \ + fdlibm/e_pow.c \ + fdlibm/fdlibm.h + +fdlibm/e_rem_pio2.o: \ + fdlibm/e_rem_pio2.c \ + fdlibm/fdlibm.h + +fdlibm/e_remainder.o: \ + fdlibm/e_remainder.c \ + fdlibm/fdlibm.h + +fdlibm/e_scalb.o: \ + fdlibm/e_scalb.c \ + fdlibm/fdlibm.h + +fdlibm/e_sinh.o: \ + fdlibm/e_sinh.c \ + fdlibm/fdlibm.h + +fdlibm/e_sqrt.o: \ + fdlibm/e_sqrt.c \ + fdlibm/fdlibm.h + +fdlibm/k_cos.o: \ + fdlibm/k_cos.c \ + fdlibm/fdlibm.h + +fdlibm/k_rem_pio2.o: \ + fdlibm/k_rem_pio2.c \ + fdlibm/fdlibm.h + +fdlibm/k_sin.o: \ + fdlibm/k_sin.c \ + fdlibm/fdlibm.h + +fdlibm/k_standard.o: \ + fdlibm/k_standard.c \ + fdlibm/fdlibm.h + +fdlibm/k_tan.o: \ + fdlibm/k_tan.c \ + fdlibm/fdlibm.h + +fdlibm/s_asinh.o: \ + fdlibm/s_asinh.c \ + fdlibm/fdlibm.h + +fdlibm/s_atan.o: \ + fdlibm/s_atan.c \ + fdlibm/fdlibm.h + +fdlibm/s_cbrt.o: \ + fdlibm/s_cbrt.c \ + fdlibm/fdlibm.h + +fdlibm/s_ceil.o: \ + fdlibm/s_ceil.c \ + fdlibm/fdlibm.h + +fdlibm/s_copysign.o: \ + fdlibm/s_copysign.c \ + fdlibm/fdlibm.h + +fdlibm/s_cos.o: \ + fdlibm/s_cos.c \ + fdlibm/fdlibm.h + +fdlibm/s_erf.o: \ + fdlibm/s_erf.c \ + fdlibm/fdlibm.h + +fdlibm/s_expm1.o: \ + fdlibm/s_expm1.c \ + fdlibm/fdlibm.h + +fdlibm/s_fabs.o: \ + fdlibm/s_fabs.c \ + fdlibm/fdlibm.h + +fdlibm/s_finite.o: \ + fdlibm/s_finite.c \ + fdlibm/fdlibm.h + +fdlibm/s_floor.o: \ + fdlibm/s_floor.c \ + fdlibm/fdlibm.h + +fdlibm/s_frexp.o: \ + fdlibm/s_frexp.c \ + fdlibm/fdlibm.h + +fdlibm/s_ilogb.o: \ + fdlibm/s_ilogb.c \ + fdlibm/fdlibm.h + +fdlibm/s_isnan.o: \ + fdlibm/s_isnan.c \ + fdlibm/fdlibm.h + +fdlibm/s_ldexp.o: \ + fdlibm/s_ldexp.c \ + fdlibm/fdlibm.h + +fdlibm/s_lib_version.o: \ + fdlibm/s_lib_version.c \ + fdlibm/fdlibm.h + +fdlibm/s_log1p.o: \ + fdlibm/s_log1p.c \ + fdlibm/fdlibm.h + +fdlibm/s_logb.o: \ + fdlibm/s_logb.c \ + fdlibm/fdlibm.h + +fdlibm/s_matherr.o: \ + fdlibm/s_matherr.c \ + fdlibm/fdlibm.h + +fdlibm/s_modf.o: \ + fdlibm/s_modf.c \ + fdlibm/fdlibm.h + +fdlibm/s_nextafter.o: \ + fdlibm/s_nextafter.c \ + fdlibm/fdlibm.h + +fdlibm/s_rint.o: \ + fdlibm/s_rint.c \ + fdlibm/fdlibm.h + +fdlibm/s_scalbn.o: \ + fdlibm/s_scalbn.c \ + fdlibm/fdlibm.h + +fdlibm/s_signgam.o: \ + fdlibm/s_signgam.c \ + fdlibm/fdlibm.h + +fdlibm/s_significand.o: \ + fdlibm/s_significand.c \ + fdlibm/fdlibm.h + +fdlibm/s_sin.o: \ + fdlibm/s_sin.c \ + fdlibm/fdlibm.h + +fdlibm/s_tan.o: \ + fdlibm/s_tan.c \ + fdlibm/fdlibm.h + +fdlibm/s_tanh.o: \ + fdlibm/s_tanh.c \ + fdlibm/fdlibm.h + +fdlibm/w_acos.o: \ + fdlibm/w_acos.c \ + fdlibm/fdlibm.h + +fdlibm/w_acosh.o: \ + fdlibm/w_acosh.c \ + fdlibm/fdlibm.h + +fdlibm/w_asin.o: \ + fdlibm/w_asin.c \ + fdlibm/fdlibm.h + +fdlibm/w_atan2.o: \ + fdlibm/w_atan2.c \ + fdlibm/fdlibm.h + +fdlibm/w_atanh.o: \ + fdlibm/w_atanh.c \ + fdlibm/fdlibm.h + +fdlibm/w_cosh.o: \ + fdlibm/w_cosh.c \ + fdlibm/fdlibm.h + +fdlibm/w_exp.o: \ + fdlibm/w_exp.c \ + fdlibm/fdlibm.h + +fdlibm/w_fmod.o: \ + fdlibm/w_fmod.c \ + fdlibm/fdlibm.h + +fdlibm/w_gamma.o: \ + fdlibm/w_gamma.c \ + fdlibm/fdlibm.h + +fdlibm/w_gamma_r.o: \ + fdlibm/w_gamma_r.c \ + fdlibm/fdlibm.h + +fdlibm/w_hypot.o: \ + fdlibm/w_hypot.c \ + fdlibm/fdlibm.h + +fdlibm/w_j0.o: \ + fdlibm/w_j0.c \ + fdlibm/fdlibm.h + +fdlibm/w_j1.o: \ + fdlibm/w_j1.c \ + fdlibm/fdlibm.h + +fdlibm/w_jn.o: \ + fdlibm/w_jn.c \ + fdlibm/fdlibm.h + +fdlibm/w_lgamma.o: \ + fdlibm/w_lgamma.c \ + fdlibm/fdlibm.h + +fdlibm/w_lgamma_r.o: \ + fdlibm/w_lgamma_r.c \ + fdlibm/fdlibm.h + +fdlibm/w_log.o: \ + fdlibm/w_log.c \ + fdlibm/fdlibm.h + +fdlibm/w_log10.o: \ + fdlibm/w_log10.c \ + fdlibm/fdlibm.h + +fdlibm/w_pow.o: \ + fdlibm/w_pow.c \ + fdlibm/fdlibm.h + +fdlibm/w_remainder.o: \ + fdlibm/w_remainder.c \ + fdlibm/fdlibm.h + +fdlibm/w_scalb.o: \ + fdlibm/w_scalb.c \ + fdlibm/fdlibm.h + +fdlibm/w_sinh.o: \ + fdlibm/w_sinh.c \ + fdlibm/fdlibm.h + +fdlibm/w_sqrt.o: \ + fdlibm/w_sqrt.c \ + fdlibm/fdlibm.h + +js.o: \ + js.c \ + jsapi.h \ + jsarena.h \ + jsatom.h \ + jsclist.h \ + jscntxt.h \ + jscompat.h \ + jsconfig.h \ + jscpucfg.h \ + jsdbgapi.h \ + jsdhash.h \ + jsemit.h \ + jsfun.h \ + jsgc.h \ + jshash.h \ + jsinterp.h \ + jslock.h \ + jslong.h \ + jsobj.h \ + jsopcode.h \ + jsosdep.h \ + jsotypes.h \ + jsparse.h \ + jsprf.h \ + jsprvtd.h \ + jspubtd.h \ + jsregexp.h \ + jsscan.h \ + jsscope.h \ + jsscript.h \ + jsstddef.h \ + jsstr.h \ + jstypes.h \ + jsutil.h + +jsapi.o: \ + jsapi.c \ + jsapi.h \ + jsarena.h \ + jsarray.h \ + jsatom.h \ + jsbool.h \ + jsclist.h \ + jscntxt.h \ + jscompat.h \ + jsconfig.h \ + jscpucfg.h \ + jsdate.h \ + jsdhash.h \ + jsdtoa.h \ + jsemit.h \ + jsexn.h \ + jsfile.h \ + jsfun.h \ + jsgc.h \ + jshash.h \ + jsinterp.h \ + jslock.h \ + jslong.h \ + jsmath.h \ + jsnum.h \ + jsobj.h \ + jsopcode.h \ + jsosdep.h \ + jsotypes.h \ + jsparse.h \ + jsprf.h \ + jsprvtd.h \ + jspubtd.h \ + jsregexp.h \ + jsscan.h \ + jsscope.h \ + jsscript.h \ + jsstddef.h \ + jsstr.h \ + jstypes.h \ + jsutil.h \ + prmjtime.h + +jsarena.o: \ + jsarena.c \ + jsarena.h \ + jsbit.h \ + jscompat.h \ + jscpucfg.h \ + jshash.h \ + jslock.h \ + jslong.h \ + jsobj.h \ + jsosdep.h \ + jsotypes.h \ + jsprvtd.h \ + jspubtd.h \ + jsscope.h \ + jsstddef.h \ + jstypes.h \ + jsutil.h + +jsarray.o: \ + jsarray.c \ + jsapi.h \ + jsarena.h \ + jsarray.h \ + jsatom.h \ + jsclist.h \ + jscntxt.h \ + jscompat.h \ + jsconfig.h \ + jscpucfg.h \ + jsdhash.h \ + jsfun.h \ + jsgc.h \ + jshash.h \ + jsinterp.h \ + jslock.h \ + jslong.h \ + jsnum.h \ + jsobj.h \ + jsosdep.h \ + jsotypes.h \ + jsprvtd.h \ + jspubtd.h \ + jsregexp.h \ + jsscope.h \ + jsstddef.h \ + jsstr.h \ + jstypes.h \ + jsutil.h + +jsatom.o: \ + jsatom.c \ + jsapi.h \ + jsarena.h \ + jsatom.h \ + jsclist.h \ + jscntxt.h \ + jscompat.h \ + jsconfig.h \ + jscpucfg.h \ + jsdhash.h \ + jsgc.h \ + jshash.h \ + jsinterp.h \ + jslock.h \ + jslong.h \ + jsnum.h \ + jsobj.h \ + jsopcode.h \ + jsosdep.h \ + jsotypes.h \ + jsprf.h \ + jsprvtd.h \ + jspubtd.h \ + jsregexp.h \ + jsscope.h \ + jsstddef.h \ + jsstr.h \ + jstypes.h \ + jsutil.h + +jsbool.o: \ + jsbool.c \ + jsapi.h \ + jsarena.h \ + jsatom.h \ + jsbool.h \ + jsclist.h \ + jscntxt.h \ + jscompat.h \ + jsconfig.h \ + jscpucfg.h \ + jsdhash.h \ + jsgc.h \ + jshash.h \ + jsinterp.h \ + jslock.h \ + jslong.h \ + jsnum.h \ + jsobj.h \ + jsosdep.h \ + jsotypes.h \ + jsprf.h \ + jsprvtd.h \ + jspubtd.h \ + jsregexp.h \ + jsscope.h \ + jsstddef.h \ + jsstr.h \ + jstypes.h \ + jsutil.h + +jscntxt.o: \ + jscntxt.c \ + jsapi.h \ + jsarena.h \ + jsatom.h \ + jsclist.h \ + jscntxt.h \ + jscompat.h \ + jsconfig.h \ + jscpucfg.h \ + jsdbgapi.h \ + jsdhash.h \ + jsexn.h \ + jsgc.h \ + jshash.h \ + jsinterp.h \ + jslock.h \ + jslong.h \ + jsnum.h \ + jsobj.h \ + jsopcode.h \ + jsosdep.h \ + jsotypes.h \ + jsprf.h \ + jsprvtd.h \ + jspubtd.h \ + jsregexp.h \ + jsscan.h \ + jsscope.h \ + jsscript.h \ + jsstddef.h \ + jsstr.h \ + jstypes.h \ + jsutil.h + +jscpucfg.o: \ + jscpucfg.c + +jsdate.o: \ + jsdate.c \ + jsapi.h \ + jsarena.h \ + jsatom.h \ + jsclist.h \ + jscntxt.h \ + jscompat.h \ + jsconfig.h \ + jscpucfg.h \ + jsdate.h \ + jsdhash.h \ + jsdtoa.h \ + jsgc.h \ + jshash.h \ + jsinterp.h \ + jslock.h \ + jslong.h \ + jsnum.h \ + jsobj.h \ + jsosdep.h \ + jsotypes.h \ + jsprf.h \ + jsprvtd.h \ + jspubtd.h \ + jsregexp.h \ + jsscope.h \ + jsstddef.h \ + jsstr.h \ + jstypes.h \ + jsutil.h \ + prmjtime.h + +jsdbgapi.o: \ + jsdbgapi.c \ + jsapi.h \ + jsarena.h \ + jsatom.h \ + jsclist.h \ + jscntxt.h \ + jscompat.h \ + jsconfig.h \ + jscpucfg.h \ + jsdbgapi.h \ + jsdhash.h \ + jsemit.h \ + jsfun.h \ + jsgc.h \ + jshash.h \ + jsinterp.h \ + jslock.h \ + jslong.h \ + jsobj.h \ + jsopcode.h \ + jsosdep.h \ + jsotypes.h \ + jsprvtd.h \ + jspubtd.h \ + jsregexp.h \ + jsscope.h \ + jsscript.h \ + jsstddef.h \ + jsstr.h \ + jstypes.h \ + jsutil.h + +jsdhash.o: \ + jsdhash.c \ + jsbit.h \ + jscpucfg.h \ + jsdhash.h \ + jsosdep.h \ + jsotypes.h \ + jstypes.h \ + jsutil.h + +jsdtoa.o: \ + jsdtoa.c \ + jscompat.h \ + jsconfig.h \ + jscpucfg.h \ + jsdtoa.h \ + jslibmath.h \ + jslong.h \ + jsnum.h \ + jsosdep.h \ + jsotypes.h \ + jsprf.h \ + jspubtd.h \ + jsstddef.h \ + jstypes.h \ + jsutil.h + +jsemit.o: \ + jsemit.c \ + jsapi.h \ + jsarena.h \ + jsatom.h \ + jsbit.h \ + jsclist.h \ + jscntxt.h \ + jscompat.h \ + jsconfig.h \ + jscpucfg.h \ + jsdhash.h \ + jsemit.h \ + jsfun.h \ + jsgc.h \ + jshash.h \ + jsinterp.h \ + jslock.h \ + jslong.h \ + jsnum.h \ + jsobj.h \ + jsopcode.h \ + jsosdep.h \ + jsotypes.h \ + jsparse.h \ + jsprf.h \ + jsprvtd.h \ + jspubtd.h \ + jsregexp.h \ + jsscan.h \ + jsscope.h \ + jsscript.h \ + jsstddef.h \ + jsstr.h \ + jstypes.h \ + jsutil.h + +jsexn.o: \ + jsexn.c \ + jsapi.h \ + jsarena.h \ + jsatom.h \ + jsbit.h \ + jsclist.h \ + jscntxt.h \ + jscompat.h \ + jsconfig.h \ + jscpucfg.h \ + jsdhash.h \ + jsexn.h \ + jsfun.h \ + jsgc.h \ + jshash.h \ + jsinterp.h \ + jslock.h \ + jslong.h \ + jsnum.h \ + jsobj.h \ + jsopcode.h \ + jsosdep.h \ + jsotypes.h \ + jsprf.h \ + jsprvtd.h \ + jspubtd.h \ + jsregexp.h \ + jsscope.h \ + jsscript.h \ + jsstddef.h \ + jsstr.h \ + jstypes.h \ + jsutil.h + +jsfile.o: \ + jsfile.c \ + jsapi.h \ + jsarena.h \ + jsatom.h \ + jsclist.h \ + jscntxt.h \ + jscompat.h \ + jsconfig.h \ + jscpucfg.h \ + jsdate.h \ + jsdbgapi.h \ + jsdhash.h \ + jsemit.h \ + jsfun.h \ + jsgc.h \ + jshash.h \ + jsinterp.h \ + jslock.h \ + jslong.h \ + jsobj.h \ + jsopcode.h \ + jsosdep.h \ + jsotypes.h \ + jsparse.h \ + jsprvtd.h \ + jspubtd.h \ + jsregexp.h \ + jsscan.h \ + jsscope.h \ + jsscript.h \ + jsstddef.h \ + jsstr.h \ + jstypes.h \ + jsutil.h + +jsfun.o: \ + jsfun.c \ + jsapi.h \ + jsarena.h \ + jsarray.h \ + jsatom.h \ + jsbit.h \ + jsclist.h \ + jscntxt.h \ + jscompat.h \ + jsconfig.h \ + jscpucfg.h \ + jsdbgapi.h \ + jsdhash.h \ + jsexn.h \ + jsfun.h \ + jsgc.h \ + jshash.h \ + jsinterp.h \ + jslock.h \ + jslong.h \ + jsnum.h \ + jsobj.h \ + jsopcode.h \ + jsosdep.h \ + jsotypes.h \ + jsparse.h \ + jsprvtd.h \ + jspubtd.h \ + jsregexp.h \ + jsscan.h \ + jsscope.h \ + jsscript.h \ + jsstddef.h \ + jsstr.h \ + jstypes.h \ + jsutil.h \ + jsxdrapi.h + +jsgc.o: \ + jsgc.c \ + jsapi.h \ + jsarena.h \ + jsatom.h \ + jsclist.h \ + jscntxt.h \ + jscompat.h \ + jsconfig.h \ + jscpucfg.h \ + jsdbgapi.h \ + jsdhash.h \ + jsfun.h \ + jsgc.h \ + jshash.h \ + jsinterp.h \ + jslock.h \ + jslong.h \ + jsnum.h \ + jsobj.h \ + jsopcode.h \ + jsosdep.h \ + jsotypes.h \ + jsprf.h \ + jsprvtd.h \ + jspubtd.h \ + jsregexp.h \ + jsscope.h \ + jsscript.h \ + jsstddef.h \ + jsstr.h \ + jstypes.h \ + jsutil.h + +jshash.o: \ + jshash.c \ + jsbit.h \ + jscompat.h \ + jscpucfg.h \ + jshash.h \ + jslong.h \ + jsosdep.h \ + jsotypes.h \ + jsstddef.h \ + jstypes.h \ + jsutil.h + +jsinterp.o: \ + jsinterp.c \ + jsapi.h \ + jsarena.h \ + jsarray.h \ + jsatom.h \ + jsbool.h \ + jsclist.h \ + jscntxt.h \ + jscompat.h \ + jsconfig.h \ + jscpucfg.h \ + jsdbgapi.h \ + jsdhash.h \ + jsfun.h \ + jsgc.h \ + jshash.h \ + jsinterp.h \ + jslock.h \ + jslong.h \ + jsnum.h \ + jsobj.h \ + jsopcode.h \ + jsosdep.h \ + jsotypes.h \ + jsprf.h \ + jsprvtd.h \ + jspubtd.h \ + jsregexp.h \ + jsscope.h \ + jsscript.h \ + jsstddef.h \ + jsstr.h \ + jstypes.h \ + jsutil.h + +jslock.o: \ + jslock.c \ + jsapi.h \ + jsarena.h \ + jsatom.h \ + jsbit.h \ + jsclist.h \ + jscntxt.h \ + jscompat.h \ + jsconfig.h \ + jscpucfg.h \ + jsdhash.h \ + jsdtoa.h \ + jsgc.h \ + jshash.h \ + jsinterp.h \ + jslock.h \ + jslong.h \ + jsobj.h \ + jsosdep.h \ + jsotypes.h \ + jsprvtd.h \ + jspubtd.h \ + jsregexp.h \ + jsscope.h \ + jsstddef.h \ + jsstr.h \ + jstypes.h \ + jsutil.h + +jslog2.o: \ + jslog2.c \ + jsbit.h \ + jscpucfg.h \ + jsosdep.h \ + jsotypes.h \ + jsstddef.h \ + jstypes.h + +jslong.o: \ + jslong.c \ + jscpucfg.h \ + jslong.h \ + jsosdep.h \ + jsotypes.h \ + jsstddef.h \ + jstypes.h + +jsmath.o: \ + jsmath.c \ + jsapi.h \ + jsarena.h \ + jsatom.h \ + jsclist.h \ + jscntxt.h \ + jscompat.h \ + jsconfig.h \ + jscpucfg.h \ + jsdhash.h \ + jsgc.h \ + jshash.h \ + jsinterp.h \ + jslibmath.h \ + jslock.h \ + jslong.h \ + jsmath.h \ + jsnum.h \ + jsobj.h \ + jsosdep.h \ + jsotypes.h \ + jsprvtd.h \ + jspubtd.h \ + jsregexp.h \ + jsscope.h \ + jsstddef.h \ + jsstr.h \ + jstypes.h \ + prmjtime.h + +jsnum.o: \ + jsnum.c \ + jsapi.h \ + jsarena.h \ + jsatom.h \ + jsclist.h \ + jscntxt.h \ + jscompat.h \ + jsconfig.h \ + jscpucfg.h \ + jsdhash.h \ + jsdtoa.h \ + jsgc.h \ + jshash.h \ + jsinterp.h \ + jslock.h \ + jslong.h \ + jsnum.h \ + jsobj.h \ + jsopcode.h \ + jsosdep.h \ + jsotypes.h \ + jsprf.h \ + jsprvtd.h \ + jspubtd.h \ + jsregexp.h \ + jsscope.h \ + jsstddef.h \ + jsstr.h \ + jstypes.h \ + jsutil.h + +jsobj.o: \ + jsobj.c \ + jsapi.h \ + jsarena.h \ + jsarray.h \ + jsatom.h \ + jsbool.h \ + jsclist.h \ + jscntxt.h \ + jscompat.h \ + jsconfig.h \ + jscpucfg.h \ + jsdbgapi.h \ + jsdhash.h \ + jsfun.h \ + jsgc.h \ + jshash.h \ + jsinterp.h \ + jslock.h \ + jslong.h \ + jsnum.h \ + jsobj.h \ + jsopcode.h \ + jsosdep.h \ + jsotypes.h \ + jsprf.h \ + jsprvtd.h \ + jspubtd.h \ + jsregexp.h \ + jsscope.h \ + jsscript.h \ + jsstddef.h \ + jsstr.h \ + jstypes.h \ + jsutil.h \ + jsxdrapi.h + +jsopcode.o: \ + jsopcode.c \ + jsapi.h \ + jsarena.h \ + jsarray.h \ + jsatom.h \ + jsclist.h \ + jscntxt.h \ + jscompat.h \ + jsconfig.h \ + jscpucfg.h \ + jsdbgapi.h \ + jsdhash.h \ + jsdtoa.h \ + jsemit.h \ + jsfun.h \ + jsgc.h \ + jshash.h \ + jsinterp.h \ + jslock.h \ + jslong.h \ + jsobj.h \ + jsopcode.h \ + jsosdep.h \ + jsotypes.h \ + jsprf.h \ + jsprvtd.h \ + jspubtd.h \ + jsregexp.h \ + jsscope.h \ + jsscript.h \ + jsstddef.h \ + jsstr.h \ + jstypes.h \ + jsutil.h + +jsparse.o: \ + jsparse.c \ + jsapi.h \ + jsarena.h \ + jsatom.h \ + jsclist.h \ + jscntxt.h \ + jscompat.h \ + jsconfig.h \ + jscpucfg.h \ + jsdhash.h \ + jsemit.h \ + jsfun.h \ + jsgc.h \ + jshash.h \ + jsinterp.h \ + jslock.h \ + jslong.h \ + jsnum.h \ + jsobj.h \ + jsopcode.h \ + jsosdep.h \ + jsotypes.h \ + jsparse.h \ + jsprvtd.h \ + jspubtd.h \ + jsregexp.h \ + jsscan.h \ + jsscope.h \ + jsscript.h \ + jsstddef.h \ + jsstr.h \ + jstypes.h \ + jsutil.h + +jsprf.o: \ + jsprf.c \ + jscpucfg.h \ + jslong.h \ + jsosdep.h \ + jsotypes.h \ + jsprf.h \ + jsstddef.h \ + jstypes.h \ + jsutil.h + +jsregexp.o: \ + jsregexp.c \ + jsapi.h \ + jsarena.h \ + jsarray.h \ + jsatom.h \ + jsclist.h \ + jscntxt.h \ + jscompat.h \ + jsconfig.h \ + jscpucfg.h \ + jsdhash.h \ + jsfun.h \ + jsgc.h \ + jshash.h \ + jsinterp.h \ + jslock.h \ + jslong.h \ + jsnum.h \ + jsobj.h \ + jsopcode.h \ + jsosdep.h \ + jsotypes.h \ + jsprvtd.h \ + jspubtd.h \ + jsregexp.h \ + jsscan.h \ + jsscope.h \ + jsstddef.h \ + jsstr.h \ + jstypes.h \ + jsutil.h \ + jsxdrapi.h + +jsscan.o: \ + jsscan.c \ + jsapi.h \ + jsarena.h \ + jsatom.h \ + jsclist.h \ + jscntxt.h \ + jscompat.h \ + jsconfig.h \ + jscpucfg.h \ + jsdhash.h \ + jsdtoa.h \ + jsemit.h \ + jsexn.h \ + jsgc.h \ + jshash.h \ + jsinterp.h \ + jslock.h \ + jslong.h \ + jsnum.h \ + jsobj.h \ + jsopcode.h \ + jsosdep.h \ + jsotypes.h \ + jsprf.h \ + jsprvtd.h \ + jspubtd.h \ + jsregexp.h \ + jsscan.h \ + jsscope.h \ + jsstddef.h \ + jsstr.h \ + jstypes.h \ + jsutil.h + +jsscope.o: \ + jsscope.c \ + jsapi.h \ + jsarena.h \ + jsatom.h \ + jsbit.h \ + jsclist.h \ + jscntxt.h \ + jscompat.h \ + jsconfig.h \ + jscpucfg.h \ + jsdbgapi.h \ + jsdhash.h \ + jsgc.h \ + jshash.h \ + jsinterp.h \ + jslock.h \ + jslong.h \ + jsnum.h \ + jsobj.h \ + jsopcode.h \ + jsosdep.h \ + jsotypes.h \ + jsprvtd.h \ + jspubtd.h \ + jsregexp.h \ + jsscope.h \ + jsstddef.h \ + jsstr.h \ + jstypes.h \ + jsutil.h + +jsscript.o: \ + jsscript.c \ + jsapi.h \ + jsarena.h \ + jsatom.h \ + jsclist.h \ + jscntxt.h \ + jscompat.h \ + jsconfig.h \ + jscpucfg.h \ + jsdbgapi.h \ + jsdhash.h \ + jsemit.h \ + jsfun.h \ + jsgc.h \ + jshash.h \ + jsinterp.h \ + jslock.h \ + jslong.h \ + jsnum.h \ + jsobj.h \ + jsopcode.h \ + jsosdep.h \ + jsotypes.h \ + jsprf.h \ + jsprvtd.h \ + jspubtd.h \ + jsregexp.h \ + jsscope.h \ + jsscript.h \ + jsstddef.h \ + jsstr.h \ + jstypes.h \ + jsutil.h \ + jsxdrapi.h + +jsstr.o: \ + jsstr.c \ + jsapi.h \ + jsarena.h \ + jsarray.h \ + jsatom.h \ + jsbool.h \ + jsclist.h \ + jscntxt.h \ + jscompat.h \ + jsconfig.h \ + jscpucfg.h \ + jsdhash.h \ + jsgc.h \ + jshash.h \ + jsinterp.h \ + jslock.h \ + jslong.h \ + jsnum.h \ + jsobj.h \ + jsopcode.h \ + jsosdep.h \ + jsotypes.h \ + jsprf.h \ + jsprvtd.h \ + jspubtd.h \ + jsregexp.h \ + jsscope.h \ + jsstddef.h \ + jsstr.h \ + jstypes.h \ + jsutil.h + +jsutil.o: \ + jsutil.c \ + jscpucfg.h \ + jsosdep.h \ + jsotypes.h \ + jsprf.h \ + jsstddef.h \ + jstypes.h \ + jsutil.h + +jsxdrapi.o: \ + jsxdrapi.c \ + jsapi.h \ + jsarena.h \ + jsatom.h \ + jsclist.h \ + jscntxt.h \ + jscompat.h \ + jsconfig.h \ + jscpucfg.h \ + jsdhash.h \ + jsgc.h \ + jshash.h \ + jsinterp.h \ + jslock.h \ + jslong.h \ + jsobj.h \ + jsosdep.h \ + jsotypes.h \ + jsprf.h \ + jsprvtd.h \ + jspubtd.h \ + jsregexp.h \ + jsscope.h \ + jsscript.h \ + jsstddef.h \ + jsstr.h \ + jstypes.h \ + jsutil.h \ + jsxdrapi.h + +prmjtime.o: \ + prmjtime.c \ + jscompat.h \ + jscpucfg.h \ + jslong.h \ + jsosdep.h \ + jsotypes.h \ + jsprf.h \ + jsstddef.h \ + jstypes.h \ + jsutil.h \ + prmjtime.h + diff --git a/src/dom/js/README b/src/dom/js/README new file mode 100644 index 000000000..cca453245 --- /dev/null +++ b/src/dom/js/README @@ -0,0 +1,20 @@ +//######################################################################### +//# $Id$ +//######################################################################### +See: + +$PROJECT/src/ecma/README + +for more information. + +The source is unchanged from Mozilla.org's distribution with +the minor difference: + +Line 142 in jstypes.h: +#if defined(_WIN32) && !defined(__MWERKS__) +is modified to +#if defined(_WIN32) && !defined(__MWERKS__) && !defined(__GNUC__) +to allow for static linking in Mingw on Win32. + + + diff --git a/src/dom/js/fdlibm/e_acos.c b/src/dom/js/fdlibm/e_acos.c new file mode 100644 index 000000000..a07c1eebc --- /dev/null +++ b/src/dom/js/fdlibm/e_acos.c @@ -0,0 +1,147 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Sun Microsystems, Inc. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* @(#)e_acos.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* __ieee754_acos(x) + * Method : + * acos(x) = pi/2 - asin(x) + * acos(-x) = pi/2 + asin(x) + * For |x|<=0.5 + * acos(x) = pi/2 - (x + x*x^2*R(x^2)) (see asin.c) + * For x>0.5 + * acos(x) = pi/2 - (pi/2 - 2asin(sqrt((1-x)/2))) + * = 2asin(sqrt((1-x)/2)) + * = 2s + 2s*z*R(z) ...z=(1-x)/2, s=sqrt(z) + * = 2f + (2c + 2s*z*R(z)) + * where f=hi part of s, and c = (z-f*f)/(s+f) is the correction term + * for f so that f+c ~ sqrt(z). + * For x<-0.5 + * acos(x) = pi - 2asin(sqrt((1-|x|)/2)) + * = pi - 0.5*(s+s*z*R(z)), where z=(1-|x|)/2,s=sqrt(z) + * + * Special cases: + * if x is NaN, return x itself; + * if |x|>1, return NaN with invalid signal. + * + * Function needed: sqrt + */ + +#include "fdlibm.h" + +#ifdef __STDC__ +static const double +#else +static double +#endif +one= 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */ +pi = 3.14159265358979311600e+00, /* 0x400921FB, 0x54442D18 */ +pio2_hi = 1.57079632679489655800e+00, /* 0x3FF921FB, 0x54442D18 */ +pio2_lo = 6.12323399573676603587e-17, /* 0x3C91A626, 0x33145C07 */ +pS0 = 1.66666666666666657415e-01, /* 0x3FC55555, 0x55555555 */ +pS1 = -3.25565818622400915405e-01, /* 0xBFD4D612, 0x03EB6F7D */ +pS2 = 2.01212532134862925881e-01, /* 0x3FC9C155, 0x0E884455 */ +pS3 = -4.00555345006794114027e-02, /* 0xBFA48228, 0xB5688F3B */ +pS4 = 7.91534994289814532176e-04, /* 0x3F49EFE0, 0x7501B288 */ +pS5 = 3.47933107596021167570e-05, /* 0x3F023DE1, 0x0DFDF709 */ +qS1 = -2.40339491173441421878e+00, /* 0xC0033A27, 0x1C8A2D4B */ +qS2 = 2.02094576023350569471e+00, /* 0x40002AE5, 0x9C598AC8 */ +qS3 = -6.88283971605453293030e-01, /* 0xBFE6066C, 0x1B8D0159 */ +qS4 = 7.70381505559019352791e-02; /* 0x3FB3B8C5, 0xB12E9282 */ + +#ifdef __STDC__ + double __ieee754_acos(double x) +#else + double __ieee754_acos(x) + double x; +#endif +{ + fd_twoints u; + double df; + double z,p,q,r,w,s,c; + int hx,ix; + u.d = x; + hx = __HI(u); + ix = hx&0x7fffffff; + if(ix>=0x3ff00000) { /* |x| >= 1 */ + if(((ix-0x3ff00000)|__LO(u))==0) { /* |x|==1 */ + if(hx>0) return 0.0; /* acos(1) = 0 */ + else return pi+2.0*pio2_lo; /* acos(-1)= pi */ + } + return (x-x)/(x-x); /* acos(|x|>1) is NaN */ + } + if(ix<0x3fe00000) { /* |x| < 0.5 */ + if(ix<=0x3c600000) return pio2_hi+pio2_lo;/*if|x|<2**-57*/ + z = x*x; + p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5))))); + q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4))); + r = p/q; + return pio2_hi - (x - (pio2_lo-x*r)); + } else if (hx<0) { /* x < -0.5 */ + z = (one+x)*0.5; + p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5))))); + q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4))); + s = fd_sqrt(z); + r = p/q; + w = r*s-pio2_lo; + return pi - 2.0*(s+w); + } else { /* x > 0.5 */ + z = (one-x)*0.5; + s = fd_sqrt(z); + u.d = s; + __LO(u) = 0; + df = u.d; + c = (z-df*df)/(s+df); + p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5))))); + q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4))); + r = p/q; + w = r*s+c; + return 2.0*(df+w); + } +} diff --git a/src/dom/js/fdlibm/e_acosh.c b/src/dom/js/fdlibm/e_acosh.c new file mode 100644 index 000000000..725cceefb --- /dev/null +++ b/src/dom/js/fdlibm/e_acosh.c @@ -0,0 +1,105 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Sun Microsystems, Inc. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* @(#)e_acosh.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + * + */ + +/* __ieee754_acosh(x) + * Method : + * Based on + * acosh(x) = log [ x + sqrt(x*x-1) ] + * we have + * acosh(x) := log(x)+ln2, if x is large; else + * acosh(x) := log(2x-1/(sqrt(x*x-1)+x)) if x>2; else + * acosh(x) := log1p(t+sqrt(2.0*t+t*t)); where t=x-1. + * + * Special cases: + * acosh(x) is NaN with signal if x<1. + * acosh(NaN) is NaN without signal. + */ + +#include "fdlibm.h" + +#ifdef __STDC__ +static const double +#else +static double +#endif +one = 1.0, +ln2 = 6.93147180559945286227e-01; /* 0x3FE62E42, 0xFEFA39EF */ + +#ifdef __STDC__ + double __ieee754_acosh(double x) +#else + double __ieee754_acosh(x) + double x; +#endif +{ + fd_twoints u; + double t; + int hx; + u.d = x; + hx = __HI(u); + if(hx<0x3ff00000) { /* x < 1 */ + return (x-x)/(x-x); + } else if(hx >=0x41b00000) { /* x > 2**28 */ + if(hx >=0x7ff00000) { /* x is inf of NaN */ + return x+x; + } else + return __ieee754_log(x)+ln2; /* acosh(huge)=log(2x) */ + } else if(((hx-0x3ff00000)|__LO(u))==0) { + return 0.0; /* acosh(1) = 0 */ + } else if (hx > 0x40000000) { /* 2**28 > x > 2 */ + t=x*x; + return __ieee754_log(2.0*x-one/(x+fd_sqrt(t-one))); + } else { /* 10.98 + * asin(x) = pi/2 - 2*(s+s*z*R(z)) + * = pio2_hi - (2*(s+s*z*R(z)) - pio2_lo) + * For x<=0.98, let pio4_hi = pio2_hi/2, then + * f = hi part of s; + * c = sqrt(z) - f = (z-f*f)/(s+f) ...f+c=sqrt(z) + * and + * asin(x) = pi/2 - 2*(s+s*z*R(z)) + * = pio4_hi+(pio4-2s)-(2s*z*R(z)-pio2_lo) + * = pio4_hi+(pio4-2f)-(2s*z*R(z)-(pio2_lo+2c)) + * + * Special cases: + * if x is NaN, return x itself; + * if |x|>1, return NaN with invalid signal. + * + */ + + +#include "fdlibm.h" + +#ifdef __STDC__ +static const double +#else +static double +#endif +one = 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */ +really_big = 1.000e+300, +pio2_hi = 1.57079632679489655800e+00, /* 0x3FF921FB, 0x54442D18 */ +pio2_lo = 6.12323399573676603587e-17, /* 0x3C91A626, 0x33145C07 */ +pio4_hi = 7.85398163397448278999e-01, /* 0x3FE921FB, 0x54442D18 */ + /* coefficient for R(x^2) */ +pS0 = 1.66666666666666657415e-01, /* 0x3FC55555, 0x55555555 */ +pS1 = -3.25565818622400915405e-01, /* 0xBFD4D612, 0x03EB6F7D */ +pS2 = 2.01212532134862925881e-01, /* 0x3FC9C155, 0x0E884455 */ +pS3 = -4.00555345006794114027e-02, /* 0xBFA48228, 0xB5688F3B */ +pS4 = 7.91534994289814532176e-04, /* 0x3F49EFE0, 0x7501B288 */ +pS5 = 3.47933107596021167570e-05, /* 0x3F023DE1, 0x0DFDF709 */ +qS1 = -2.40339491173441421878e+00, /* 0xC0033A27, 0x1C8A2D4B */ +qS2 = 2.02094576023350569471e+00, /* 0x40002AE5, 0x9C598AC8 */ +qS3 = -6.88283971605453293030e-01, /* 0xBFE6066C, 0x1B8D0159 */ +qS4 = 7.70381505559019352791e-02; /* 0x3FB3B8C5, 0xB12E9282 */ + +#ifdef __STDC__ + double __ieee754_asin(double x) +#else + double __ieee754_asin(x) + double x; +#endif +{ + fd_twoints u; + double w,t,p,q,c,r,s; + int hx,ix; + u.d = x; + hx = __HI(u); + x = u.d; + ix = hx&0x7fffffff; + if(ix>= 0x3ff00000) { /* |x|>= 1 */ + if(((ix-0x3ff00000)|__LO(u))==0) + /* asin(1)=+-pi/2 with inexact */ + return x*pio2_hi+x*pio2_lo; + return (x-x)/(x-x); /* asin(|x|>1) is NaN */ + } else if (ix<0x3fe00000) { /* |x|<0.5 */ + if(ix<0x3e400000) { /* if |x| < 2**-27 */ + if(really_big+x>one) return x;/* return x with inexact if x!=0*/ + } else + t = x*x; + p = t*(pS0+t*(pS1+t*(pS2+t*(pS3+t*(pS4+t*pS5))))); + q = one+t*(qS1+t*(qS2+t*(qS3+t*qS4))); + w = p/q; + return x+x*w; + } + /* 1> |x|>= 0.5 */ + w = one-fd_fabs(x); + t = w*0.5; + p = t*(pS0+t*(pS1+t*(pS2+t*(pS3+t*(pS4+t*pS5))))); + q = one+t*(qS1+t*(qS2+t*(qS3+t*qS4))); + s = fd_sqrt(t); + if(ix>=0x3FEF3333) { /* if |x| > 0.975 */ + w = p/q; + t = pio2_hi-(2.0*(s+s*w)-pio2_lo); + } else { + u.d = s; + __LO(u) = 0; + w = u.d; + c = (t-w*w)/(s+w); + r = p/q; + p = 2.0*s*r-(pio2_lo-2.0*c); + q = pio4_hi-2.0*w; + t = pio4_hi-(p-q); + } + if(hx>0) return t; else return -t; +} diff --git a/src/dom/js/fdlibm/e_atan2.c b/src/dom/js/fdlibm/e_atan2.c new file mode 100644 index 000000000..9c9a2c01f --- /dev/null +++ b/src/dom/js/fdlibm/e_atan2.c @@ -0,0 +1,165 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Sun Microsystems, Inc. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* @(#)e_atan2.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + * + */ + +/* __ieee754_atan2(y,x) + * Method : + * 1. Reduce y to positive by atan2(y,x)=-atan2(-y,x). + * 2. Reduce x to positive by (if x and y are unexceptional): + * ARG (x+iy) = arctan(y/x) ... if x > 0, + * ARG (x+iy) = pi - arctan[y/(-x)] ... if x < 0, + * + * Special cases: + * + * ATAN2((anything), NaN ) is NaN; + * ATAN2(NAN , (anything) ) is NaN; + * ATAN2(+-0, +(anything but NaN)) is +-0 ; + * ATAN2(+-0, -(anything but NaN)) is +-pi ; + * ATAN2(+-(anything but 0 and NaN), 0) is +-pi/2; + * ATAN2(+-(anything but INF and NaN), +INF) is +-0 ; + * ATAN2(+-(anything but INF and NaN), -INF) is +-pi; + * ATAN2(+-INF,+INF ) is +-pi/4 ; + * ATAN2(+-INF,-INF ) is +-3pi/4; + * ATAN2(+-INF, (anything but,0,NaN, and INF)) is +-pi/2; + * + * Constants: + * The hexadecimal values are the intended ones for the following + * constants. The decimal values may be used, provided that the + * compiler will convert from decimal to binary accurately enough + * to produce the hexadecimal values shown. + */ + +#include "fdlibm.h" + +#ifdef __STDC__ +static const double +#else +static double +#endif +tiny = 1.0e-300, +zero = 0.0, +pi_o_4 = 7.8539816339744827900E-01, /* 0x3FE921FB, 0x54442D18 */ +pi_o_2 = 1.5707963267948965580E+00, /* 0x3FF921FB, 0x54442D18 */ +pi = 3.1415926535897931160E+00, /* 0x400921FB, 0x54442D18 */ +pi_lo = 1.2246467991473531772E-16; /* 0x3CA1A626, 0x33145C07 */ + +#ifdef __STDC__ + double __ieee754_atan2(double y, double x) +#else + double __ieee754_atan2(y,x) + double y,x; +#endif +{ + fd_twoints ux, uy, uz; + double z; + int k,m,hx,hy,ix,iy; + unsigned lx,ly; + + ux.d = x; uy.d = y; + hx = __HI(ux); ix = hx&0x7fffffff; + lx = __LO(ux); + hy = __HI(uy); iy = hy&0x7fffffff; + ly = __LO(uy); + if(((ix|((lx|-(int)lx)>>31))>0x7ff00000)|| + ((iy|((ly|-(int)ly)>>31))>0x7ff00000)) /* x or y is NaN */ + return x+y; + if(((hx-0x3ff00000)|lx)==0) return fd_atan(y); /* x=1.0 */ + m = ((hy>>31)&1)|((hx>>30)&2); /* 2*sign(x)+sign(y) */ + + /* when y = 0 */ + if((iy|ly)==0) { + switch(m) { + case 0: + case 1: return y; /* atan(+-0,+anything)=+-0 */ + case 2: return pi+tiny;/* atan(+0,-anything) = pi */ + case 3: return -pi-tiny;/* atan(-0,-anything) =-pi */ + } + } + /* when x = 0 */ + if((ix|lx)==0) return (hy<0)? -pi_o_2-tiny: pi_o_2+tiny; + + /* when x is INF */ + if(ix==0x7ff00000) { + if(iy==0x7ff00000) { + switch(m) { + case 0: return pi_o_4+tiny;/* atan(+INF,+INF) */ + case 1: return -pi_o_4-tiny;/* atan(-INF,+INF) */ + case 2: return 3.0*pi_o_4+tiny;/*atan(+INF,-INF)*/ + case 3: return -3.0*pi_o_4-tiny;/*atan(-INF,-INF)*/ + } + } else { + switch(m) { + case 0: return zero ; /* atan(+...,+INF) */ + case 1: return -zero ; /* atan(-...,+INF) */ + case 2: return pi+tiny ; /* atan(+...,-INF) */ + case 3: return -pi-tiny ; /* atan(-...,-INF) */ + } + } + } + /* when y is INF */ + if(iy==0x7ff00000) return (hy<0)? -pi_o_2-tiny: pi_o_2+tiny; + + /* compute y/x */ + k = (iy-ix)>>20; + if(k > 60) z=pi_o_2+0.5*pi_lo; /* |y/x| > 2**60 */ + else if(hx<0&&k<-60) z=0.0; /* |y|/x < -2**60 */ + else z=fd_atan(fd_fabs(y/x)); /* safe to do y/x */ + switch (m) { + case 0: return z ; /* atan(+,+) */ + case 1: uz.d = z; + __HI(uz) ^= 0x80000000; + z = uz.d; + return z ; /* atan(-,+) */ + case 2: return pi-(z-pi_lo);/* atan(+,-) */ + default: /* case 3 */ + return (z-pi_lo)-pi;/* atan(-,-) */ + } +} diff --git a/src/dom/js/fdlibm/e_atanh.c b/src/dom/js/fdlibm/e_atanh.c new file mode 100644 index 000000000..dc4a90c8e --- /dev/null +++ b/src/dom/js/fdlibm/e_atanh.c @@ -0,0 +1,110 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Sun Microsystems, Inc. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* @(#)e_atanh.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + * + */ + +/* __ieee754_atanh(x) + * Method : + * 1.Reduced x to positive by atanh(-x) = -atanh(x) + * 2.For x>=0.5 + * 1 2x x + * atanh(x) = --- * log(1 + -------) = 0.5 * log1p(2 * --------) + * 2 1 - x 1 - x + * + * For x<0.5 + * atanh(x) = 0.5*log1p(2x+2x*x/(1-x)) + * + * Special cases: + * atanh(x) is NaN if |x| > 1 with signal; + * atanh(NaN) is that NaN with no signal; + * atanh(+-1) is +-INF with signal. + * + */ + +#include "fdlibm.h" + +#ifdef __STDC__ +static const double one = 1.0, really_big = 1e300; +#else +static double one = 1.0, really_big = 1e300; +#endif + +static double zero = 0.0; + +#ifdef __STDC__ + double __ieee754_atanh(double x) +#else + double __ieee754_atanh(x) + double x; +#endif +{ + double t; + int hx,ix; + unsigned lx; + fd_twoints u; + u.d = x; + hx = __HI(u); /* high word */ + lx = __LO(u); /* low word */ + ix = hx&0x7fffffff; + if ((ix|((lx|(-(int)lx))>>31))>0x3ff00000) /* |x|>1 */ + return (x-x)/(x-x); + if(ix==0x3ff00000) + return x/zero; + if(ix<0x3e300000&&(really_big+x)>zero) return x; /* x<2**-28 */ + u.d = x; + __HI(u) = ix; /* x <- |x| */ + x = u.d; + if(ix<0x3fe00000) { /* x < 0.5 */ + t = x+x; + t = 0.5*fd_log1p(t+t*x/(one-x)); + } else + t = 0.5*fd_log1p((x+x)/(one-x)); + if(hx>=0) return t; else return -t; +} diff --git a/src/dom/js/fdlibm/e_cosh.c b/src/dom/js/fdlibm/e_cosh.c new file mode 100644 index 000000000..4f8d4f769 --- /dev/null +++ b/src/dom/js/fdlibm/e_cosh.c @@ -0,0 +1,133 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Sun Microsystems, Inc. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* @(#)e_cosh.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* __ieee754_cosh(x) + * Method : + * mathematically cosh(x) if defined to be (exp(x)+exp(-x))/2 + * 1. Replace x by |x| (cosh(x) = cosh(-x)). + * 2. + * [ exp(x) - 1 ]^2 + * 0 <= x <= ln2/2 : cosh(x) := 1 + ------------------- + * 2*exp(x) + * + * exp(x) + 1/exp(x) + * ln2/2 <= x <= 22 : cosh(x) := ------------------- + * 2 + * 22 <= x <= lnovft : cosh(x) := exp(x)/2 + * lnovft <= x <= ln2ovft: cosh(x) := exp(x/2)/2 * exp(x/2) + * ln2ovft < x : cosh(x) := huge*huge (overflow) + * + * Special cases: + * cosh(x) is |x| if x is +INF, -INF, or NaN. + * only cosh(0)=1 is exact for finite x. + */ + +#include "fdlibm.h" + +#ifdef _WIN32 +#define huge myhuge +#endif + +#ifdef __STDC__ +static const double one = 1.0, half=0.5, really_big = 1.0e300; +#else +static double one = 1.0, half=0.5, really_big = 1.0e300; +#endif + +#ifdef __STDC__ + double __ieee754_cosh(double x) +#else + double __ieee754_cosh(x) + double x; +#endif +{ + fd_twoints u; + double t,w; + int ix; + unsigned lx; + + /* High word of |x|. */ + u.d = x; + ix = __HI(u); + ix &= 0x7fffffff; + + /* x is INF or NaN */ + if(ix>=0x7ff00000) return x*x; + + /* |x| in [0,0.5*ln2], return 1+expm1(|x|)^2/(2*exp(|x|)) */ + if(ix<0x3fd62e43) { + t = fd_expm1(fd_fabs(x)); + w = one+t; + if (ix<0x3c800000) return w; /* cosh(tiny) = 1 */ + return one+(t*t)/(w+w); + } + + /* |x| in [0.5*ln2,22], return (exp(|x|)+1/exp(|x|)/2; */ + if (ix < 0x40360000) { + t = __ieee754_exp(fd_fabs(x)); + return half*t+half/t; + } + + /* |x| in [22, log(maxdouble)] return half*exp(|x|) */ + if (ix < 0x40862E42) return half*__ieee754_exp(fd_fabs(x)); + + /* |x| in [log(maxdouble), overflowthresold] */ + lx = *( (((*(unsigned*)&one)>>29)) + (unsigned*)&x); + if (ix<0x408633CE || + (ix==0x408633ce)&&(lx<=(unsigned)0x8fb9f87d)) { + w = __ieee754_exp(half*fd_fabs(x)); + t = half*w; + return t*w; + } + + /* |x| > overflowthresold, cosh(x) overflow */ + return really_big*really_big; +} diff --git a/src/dom/js/fdlibm/e_exp.c b/src/dom/js/fdlibm/e_exp.c new file mode 100644 index 000000000..ad9cec124 --- /dev/null +++ b/src/dom/js/fdlibm/e_exp.c @@ -0,0 +1,202 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Sun Microsystems, Inc. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* @(#)e_exp.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* __ieee754_exp(x) + * Returns the exponential of x. + * + * Method + * 1. Argument reduction: + * Reduce x to an r so that |r| <= 0.5*ln2 ~ 0.34658. + * Given x, find r and integer k such that + * + * x = k*ln2 + r, |r| <= 0.5*ln2. + * + * Here r will be represented as r = hi-lo for better + * accuracy. + * + * 2. Approximation of exp(r) by a special rational function on + * the interval [0,0.34658]: + * Write + * R(r**2) = r*(exp(r)+1)/(exp(r)-1) = 2 + r*r/6 - r**4/360 + ... + * We use a special Reme algorithm on [0,0.34658] to generate + * a polynomial of degree 5 to approximate R. The maximum error + * of this polynomial approximation is bounded by 2**-59. In + * other words, + * R(z) ~ 2.0 + P1*z + P2*z**2 + P3*z**3 + P4*z**4 + P5*z**5 + * (where z=r*r, and the values of P1 to P5 are listed below) + * and + * | 5 | -59 + * | 2.0+P1*z+...+P5*z - R(z) | <= 2 + * | | + * The computation of exp(r) thus becomes + * 2*r + * exp(r) = 1 + ------- + * R - r + * r*R1(r) + * = 1 + r + ----------- (for better accuracy) + * 2 - R1(r) + * where + * 2 4 10 + * R1(r) = r - (P1*r + P2*r + ... + P5*r ). + * + * 3. Scale back to obtain exp(x): + * From step 1, we have + * exp(x) = 2^k * exp(r) + * + * Special cases: + * exp(INF) is INF, exp(NaN) is NaN; + * exp(-INF) is 0, and + * for finite argument, only exp(0)=1 is exact. + * + * Accuracy: + * according to an error analysis, the error is always less than + * 1 ulp (unit in the last place). + * + * Misc. info. + * For IEEE double + * if x > 7.09782712893383973096e+02 then exp(x) overflow + * if x < -7.45133219101941108420e+02 then exp(x) underflow + * + * Constants: + * The hexadecimal values are the intended ones for the following + * constants. The decimal values may be used, provided that the + * compiler will convert from decimal to binary accurately enough + * to produce the hexadecimal values shown. + */ + +#include "fdlibm.h" + +#ifdef __STDC__ +static const double +#else +static double +#endif +one = 1.0, +halF[2] = {0.5,-0.5,}, +really_big = 1.0e+300, +twom1000= 9.33263618503218878990e-302, /* 2**-1000=0x01700000,0*/ +o_threshold= 7.09782712893383973096e+02, /* 0x40862E42, 0xFEFA39EF */ +u_threshold= -7.45133219101941108420e+02, /* 0xc0874910, 0xD52D3051 */ +ln2HI[2] ={ 6.93147180369123816490e-01, /* 0x3fe62e42, 0xfee00000 */ + -6.93147180369123816490e-01,},/* 0xbfe62e42, 0xfee00000 */ +ln2LO[2] ={ 1.90821492927058770002e-10, /* 0x3dea39ef, 0x35793c76 */ + -1.90821492927058770002e-10,},/* 0xbdea39ef, 0x35793c76 */ +invln2 = 1.44269504088896338700e+00, /* 0x3ff71547, 0x652b82fe */ +P1 = 1.66666666666666019037e-01, /* 0x3FC55555, 0x5555553E */ +P2 = -2.77777777770155933842e-03, /* 0xBF66C16C, 0x16BEBD93 */ +P3 = 6.61375632143793436117e-05, /* 0x3F11566A, 0xAF25DE2C */ +P4 = -1.65339022054652515390e-06, /* 0xBEBBBD41, 0xC5D26BF1 */ +P5 = 4.13813679705723846039e-08; /* 0x3E663769, 0x72BEA4D0 */ + + +#ifdef __STDC__ + double __ieee754_exp(double x) /* default IEEE double exp */ +#else + double __ieee754_exp(x) /* default IEEE double exp */ + double x; +#endif +{ + fd_twoints u; + double y,hi,lo,c,t; + int k, xsb; + unsigned hx; + + u.d = x; + hx = __HI(u); /* high word of x */ + xsb = (hx>>31)&1; /* sign bit of x */ + hx &= 0x7fffffff; /* high word of |x| */ + + /* filter out non-finite argument */ + if(hx >= 0x40862E42) { /* if |x|>=709.78... */ + if(hx>=0x7ff00000) { + u.d = x; + if(((hx&0xfffff)|__LO(u))!=0) + return x+x; /* NaN */ + else return (xsb==0)? x:0.0; /* exp(+-inf)={inf,0} */ + } + if(x > o_threshold) return really_big*really_big; /* overflow */ + if(x < u_threshold) return twom1000*twom1000; /* underflow */ + } + + /* argument reduction */ + if(hx > 0x3fd62e42) { /* if |x| > 0.5 ln2 */ + if(hx < 0x3FF0A2B2) { /* and |x| < 1.5 ln2 */ + hi = x-ln2HI[xsb]; lo=ln2LO[xsb]; k = 1-xsb-xsb; + } else { + k = (int)(invln2*x+halF[xsb]); + t = k; + hi = x - t*ln2HI[0]; /* t*ln2HI is exact here */ + lo = t*ln2LO[0]; + } + x = hi - lo; + } + else if(hx < 0x3e300000) { /* when |x|<2**-28 */ + if(really_big+x>one) return one+x;/* trigger inexact */ + } + else k = 0; + + /* x is now in primary range */ + t = x*x; + c = x - t*(P1+t*(P2+t*(P3+t*(P4+t*P5)))); + if(k==0) return one-((x*c)/(c-2.0)-x); + else y = one-((lo-(x*c)/(2.0-c))-hi); + if(k >= -1021) { + u.d = y; + __HI(u) += (k<<20); /* add k to y's exponent */ + y = u.d; + return y; + } else { + u.d = y; + __HI(u) += ((k+1000)<<20);/* add k to y's exponent */ + y = u.d; + return y*twom1000; + } +} diff --git a/src/dom/js/fdlibm/e_fmod.c b/src/dom/js/fdlibm/e_fmod.c new file mode 100644 index 000000000..7b5ce780f --- /dev/null +++ b/src/dom/js/fdlibm/e_fmod.c @@ -0,0 +1,184 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Sun Microsystems, Inc. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* @(#)e_fmod.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * __ieee754_fmod(x,y) + * Return x mod y in exact arithmetic + * Method: shift and subtract + */ + +#include "fdlibm.h" + +#ifdef __STDC__ +static const double one = 1.0, Zero[] = {0.0, -0.0,}; +#else +static double one = 1.0, Zero[] = {0.0, -0.0,}; +#endif + +#ifdef __STDC__ + double __ieee754_fmod(double x, double y) +#else + double __ieee754_fmod(x,y) + double x,y ; +#endif +{ + fd_twoints ux, uy; + int n,hx,hy,hz,ix,iy,sx,i; + unsigned lx,ly,lz; + + ux.d = x; uy.d = y; + hx = __HI(ux); /* high word of x */ + lx = __LO(ux); /* low word of x */ + hy = __HI(uy); /* high word of y */ + ly = __LO(uy); /* low word of y */ + sx = hx&0x80000000; /* sign of x */ + hx ^=sx; /* |x| */ + hy &= 0x7fffffff; /* |y| */ + + /* purge off exception values */ + if((hy|ly)==0||(hx>=0x7ff00000)|| /* y=0,or x not finite */ + ((hy|((ly|-(int)ly)>>31))>0x7ff00000)) /* or y is NaN */ + return (x*y)/(x*y); + if(hx<=hy) { + if((hx>31]; /* |x|=|y| return x*0*/ + } + + /* determine ix = ilogb(x) */ + if(hx<0x00100000) { /* subnormal x */ + if(hx==0) { + for (ix = -1043, i=lx; i>0; i<<=1) ix -=1; + } else { + for (ix = -1022,i=(hx<<11); i>0; i<<=1) ix -=1; + } + } else ix = (hx>>20)-1023; + + /* determine iy = ilogb(y) */ + if(hy<0x00100000) { /* subnormal y */ + if(hy==0) { + for (iy = -1043, i=ly; i>0; i<<=1) iy -=1; + } else { + for (iy = -1022,i=(hy<<11); i>0; i<<=1) iy -=1; + } + } else iy = (hy>>20)-1023; + + /* set up {hx,lx}, {hy,ly} and align y to x */ + if(ix >= -1022) + hx = 0x00100000|(0x000fffff&hx); + else { /* subnormal x, shift x to normal */ + n = -1022-ix; + if(n<=31) { + hx = (hx<>(32-n)); + lx <<= n; + } else { + hx = lx<<(n-32); + lx = 0; + } + } + if(iy >= -1022) + hy = 0x00100000|(0x000fffff&hy); + else { /* subnormal y, shift y to normal */ + n = -1022-iy; + if(n<=31) { + hy = (hy<>(32-n)); + ly <<= n; + } else { + hy = ly<<(n-32); + ly = 0; + } + } + + /* fix point fmod */ + n = ix - iy; + while(n--) { + hz=hx-hy;lz=lx-ly; if(lx>31); lx = lx+lx;} + else { + if((hz|lz)==0) /* return sign(x)*0 */ + return Zero[(unsigned)sx>>31]; + hx = hz+hz+(lz>>31); lx = lz+lz; + } + } + hz=hx-hy;lz=lx-ly; if(lx=0) {hx=hz;lx=lz;} + + /* convert back to floating value and restore the sign */ + if((hx|lx)==0) /* return sign(x)*0 */ + return Zero[(unsigned)sx>>31]; + while(hx<0x00100000) { /* normalize x */ + hx = hx+hx+(lx>>31); lx = lx+lx; + iy -= 1; + } + if(iy>= -1022) { /* normalize output */ + hx = ((hx-0x00100000)|((iy+1023)<<20)); + ux.d = x; + __HI(ux) = hx|sx; + __LO(ux) = lx; + x = ux.d; + } else { /* subnormal output */ + n = -1022 - iy; + if(n<=20) { + lx = (lx>>n)|((unsigned)hx<<(32-n)); + hx >>= n; + } else if (n<=31) { + lx = (hx<<(32-n))|(lx>>n); hx = sx; + } else { + lx = hx>>(n-32); hx = sx; + } + ux.d = x; + __HI(ux) = hx|sx; + __LO(ux) = lx; + x = ux.d; + x *= one; /* create necessary signal */ + } + return x; /* exact output */ +} diff --git a/src/dom/js/fdlibm/e_gamma.c b/src/dom/js/fdlibm/e_gamma.c new file mode 100644 index 000000000..a34faa32c --- /dev/null +++ b/src/dom/js/fdlibm/e_gamma.c @@ -0,0 +1,71 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Sun Microsystems, Inc. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* @(#)e_gamma.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + * + */ + +/* __ieee754_gamma(x) + * Return the logarithm of the Gamma function of x. + * + * Method: call __ieee754_gamma_r + */ + +#include "fdlibm.h" + +extern int signgam; + +#ifdef __STDC__ + double __ieee754_gamma(double x) +#else + double __ieee754_gamma(x) + double x; +#endif +{ + return __ieee754_gamma_r(x,&signgam); +} diff --git a/src/dom/js/fdlibm/e_gamma_r.c b/src/dom/js/fdlibm/e_gamma_r.c new file mode 100644 index 000000000..f10e32e36 --- /dev/null +++ b/src/dom/js/fdlibm/e_gamma_r.c @@ -0,0 +1,70 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Sun Microsystems, Inc. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* @(#)e_gamma_r.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + * + */ + +/* __ieee754_gamma_r(x, signgamp) + * Reentrant version of the logarithm of the Gamma function + * with user provide pointer for the sign of Gamma(x). + * + * Method: See __ieee754_lgamma_r + */ + +#include "fdlibm.h" + +#ifdef __STDC__ + double __ieee754_gamma_r(double x, int *signgamp) +#else + double __ieee754_gamma_r(x,signgamp) + double x; int *signgamp; +#endif +{ + return __ieee754_lgamma_r(x,signgamp); +} diff --git a/src/dom/js/fdlibm/e_hypot.c b/src/dom/js/fdlibm/e_hypot.c new file mode 100644 index 000000000..390023087 --- /dev/null +++ b/src/dom/js/fdlibm/e_hypot.c @@ -0,0 +1,173 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Sun Microsystems, Inc. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* @(#)e_hypot.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* __ieee754_hypot(x,y) + * + * Method : + * If (assume round-to-nearest) z=x*x+y*y + * has error less than sqrt(2)/2 ulp, than + * sqrt(z) has error less than 1 ulp (exercise). + * + * So, compute sqrt(x*x+y*y) with some care as + * follows to get the error below 1 ulp: + * + * Assume x>y>0; + * (if possible, set rounding to round-to-nearest) + * 1. if x > 2y use + * x1*x1+(y*y+(x2*(x+x1))) for x*x+y*y + * where x1 = x with lower 32 bits cleared, x2 = x-x1; else + * 2. if x <= 2y use + * t1*y1+((x-y)*(x-y)+(t1*y2+t2*y)) + * where t1 = 2x with lower 32 bits cleared, t2 = 2x-t1, + * y1= y with lower 32 bits chopped, y2 = y-y1. + * + * NOTE: scaling may be necessary if some argument is too + * large or too tiny + * + * Special cases: + * hypot(x,y) is INF if x or y is +INF or -INF; else + * hypot(x,y) is NAN if x or y is NAN. + * + * Accuracy: + * hypot(x,y) returns sqrt(x^2+y^2) with error less + * than 1 ulps (units in the last place) + */ + +#include "fdlibm.h" + +#ifdef __STDC__ + double __ieee754_hypot(double x, double y) +#else + double __ieee754_hypot(x,y) + double x, y; +#endif +{ + fd_twoints ux, uy; + double a=x,b=y,t1,t2,y1,y2,w; + int j,k,ha,hb; + + ux.d = x; uy.d = y; + ha = __HI(ux)&0x7fffffff; /* high word of x */ + hb = __HI(uy)&0x7fffffff; /* high word of y */ + if(hb > ha) {a=y;b=x;j=ha; ha=hb;hb=j;} else {a=x;b=y;} + ux.d = a; uy.d = b; + __HI(ux) = ha; /* a <- |a| */ + __HI(uy) = hb; /* b <- |b| */ + a = ux.d; b = uy.d; + if((ha-hb)>0x3c00000) {return a+b;} /* x/y > 2**60 */ + k=0; + if(ha > 0x5f300000) { /* a>2**500 */ + if(ha >= 0x7ff00000) { /* Inf or NaN */ + w = a+b; /* for sNaN */ + ux.d = a; uy.d = b; + if(((ha&0xfffff)|__LO(ux))==0) w = a; + if(((hb^0x7ff00000)|__LO(uy))==0) w = b; + return w; + } + /* scale a and b by 2**-600 */ + ha -= 0x25800000; hb -= 0x25800000; k += 600; + ux.d = a; uy.d = b; + __HI(ux) = ha; + __HI(uy) = hb; + a = ux.d; b = uy.d; + } + if(hb < 0x20b00000) { /* b < 2**-500 */ + if(hb <= 0x000fffff) { /* subnormal b or 0 */ + uy.d = b; + if((hb|(__LO(uy)))==0) return a; + t1=0; + ux.d = t1; + __HI(ux) = 0x7fd00000; /* t1=2^1022 */ + t1 = ux.d; + b *= t1; + a *= t1; + k -= 1022; + } else { /* scale a and b by 2^600 */ + ha += 0x25800000; /* a *= 2^600 */ + hb += 0x25800000; /* b *= 2^600 */ + k -= 600; + ux.d = a; uy.d = b; + __HI(ux) = ha; + __HI(uy) = hb; + a = ux.d; b = uy.d; + } + } + /* medium size a and b */ + w = a-b; + if (w>b) { + t1 = 0; + ux.d = t1; + __HI(ux) = ha; + t1 = ux.d; + t2 = a-t1; + w = fd_sqrt(t1*t1-(b*(-b)-t2*(a+t1))); + } else { + a = a+a; + y1 = 0; + ux.d = y1; + __HI(ux) = hb; + y1 = ux.d; + y2 = b - y1; + t1 = 0; + ux.d = t1; + __HI(ux) = ha+0x00100000; + t1 = ux.d; + t2 = a - t1; + w = fd_sqrt(t1*y1-(w*(-w)-(t1*y2+t2*b))); + } + if(k!=0) { + t1 = 1.0; + ux.d = t1; + __HI(ux) += (k<<20); + t1 = ux.d; + return t1*w; + } else return w; +} diff --git a/src/dom/js/fdlibm/e_j0.c b/src/dom/js/fdlibm/e_j0.c new file mode 100644 index 000000000..078e09641 --- /dev/null +++ b/src/dom/js/fdlibm/e_j0.c @@ -0,0 +1,524 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Sun Microsystems, Inc. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* @(#)e_j0.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* __ieee754_j0(x), __ieee754_y0(x) + * Bessel function of the first and second kinds of order zero. + * Method -- j0(x): + * 1. For tiny x, we use j0(x) = 1 - x^2/4 + x^4/64 - ... + * 2. Reduce x to |x| since j0(x)=j0(-x), and + * for x in (0,2) + * j0(x) = 1-z/4+ z^2*R0/S0, where z = x*x; + * (precision: |j0-1+z/4-z^2R0/S0 |<2**-63.67 ) + * for x in (2,inf) + * j0(x) = sqrt(2/(pi*x))*(p0(x)*cos(x0)-q0(x)*sin(x0)) + * where x0 = x-pi/4. It is better to compute sin(x0),cos(x0) + * as follow: + * cos(x0) = cos(x)cos(pi/4)+sin(x)sin(pi/4) + * = 1/sqrt(2) * (cos(x) + sin(x)) + * sin(x0) = sin(x)cos(pi/4)-cos(x)sin(pi/4) + * = 1/sqrt(2) * (sin(x) - cos(x)) + * (To avoid cancellation, use + * sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x)) + * to compute the worse one.) + * + * 3 Special cases + * j0(nan)= nan + * j0(0) = 1 + * j0(inf) = 0 + * + * Method -- y0(x): + * 1. For x<2. + * Since + * y0(x) = 2/pi*(j0(x)*(ln(x/2)+Euler) + x^2/4 - ...) + * therefore y0(x)-2/pi*j0(x)*ln(x) is an even function. + * We use the following function to approximate y0, + * y0(x) = U(z)/V(z) + (2/pi)*(j0(x)*ln(x)), z= x^2 + * where + * U(z) = u00 + u01*z + ... + u06*z^6 + * V(z) = 1 + v01*z + ... + v04*z^4 + * with absolute approximation error bounded by 2**-72. + * Note: For tiny x, U/V = u0 and j0(x)~1, hence + * y0(tiny) = u0 + (2/pi)*ln(tiny), (choose tiny<2**-27) + * 2. For x>=2. + * y0(x) = sqrt(2/(pi*x))*(p0(x)*cos(x0)+q0(x)*sin(x0)) + * where x0 = x-pi/4. It is better to compute sin(x0),cos(x0) + * by the method mentioned above. + * 3. Special cases: y0(0)=-inf, y0(x<0)=NaN, y0(inf)=0. + */ + +#include "fdlibm.h" + +#ifdef __STDC__ +static double pzero(double), qzero(double); +#else +static double pzero(), qzero(); +#endif + +#ifdef __STDC__ +static const double +#else +static double +#endif +really_big = 1e300, +one = 1.0, +invsqrtpi= 5.64189583547756279280e-01, /* 0x3FE20DD7, 0x50429B6D */ +tpi = 6.36619772367581382433e-01, /* 0x3FE45F30, 0x6DC9C883 */ + /* R0/S0 on [0, 2.00] */ +R02 = 1.56249999999999947958e-02, /* 0x3F8FFFFF, 0xFFFFFFFD */ +R03 = -1.89979294238854721751e-04, /* 0xBF28E6A5, 0xB61AC6E9 */ +R04 = 1.82954049532700665670e-06, /* 0x3EBEB1D1, 0x0C503919 */ +R05 = -4.61832688532103189199e-09, /* 0xBE33D5E7, 0x73D63FCE */ +S01 = 1.56191029464890010492e-02, /* 0x3F8FFCE8, 0x82C8C2A4 */ +S02 = 1.16926784663337450260e-04, /* 0x3F1EA6D2, 0xDD57DBF4 */ +S03 = 5.13546550207318111446e-07, /* 0x3EA13B54, 0xCE84D5A9 */ +S04 = 1.16614003333790000205e-09; /* 0x3E1408BC, 0xF4745D8F */ + +static double zero = 0.0; + +#ifdef __STDC__ + double __ieee754_j0(double x) +#else + double __ieee754_j0(x) + double x; +#endif +{ + fd_twoints un; + double z, s,c,ss,cc,r,u,v; + int hx,ix; + + un.d = x; + hx = __HI(un); + ix = hx&0x7fffffff; + if(ix>=0x7ff00000) return one/(x*x); + x = fd_fabs(x); + if(ix >= 0x40000000) { /* |x| >= 2.0 */ + s = fd_sin(x); + c = fd_cos(x); + ss = s-c; + cc = s+c; + if(ix<0x7fe00000) { /* make sure x+x not overflow */ + z = -fd_cos(x+x); + if ((s*c)0x48000000) z = (invsqrtpi*cc)/fd_sqrt(x); + else { + u = pzero(x); v = qzero(x); + z = invsqrtpi*(u*cc-v*ss)/fd_sqrt(x); + } + return z; + } + if(ix<0x3f200000) { /* |x| < 2**-13 */ + if(really_big+x>one) { /* raise inexact if x != 0 */ + if(ix<0x3e400000) return one; /* |x|<2**-27 */ + else return one - 0.25*x*x; + } + } + z = x*x; + r = z*(R02+z*(R03+z*(R04+z*R05))); + s = one+z*(S01+z*(S02+z*(S03+z*S04))); + if(ix < 0x3FF00000) { /* |x| < 1.00 */ + return one + z*(-0.25+(r/s)); + } else { + u = 0.5*x; + return((one+u)*(one-u)+z*(r/s)); + } +} + +#ifdef __STDC__ +static const double +#else +static double +#endif +u00 = -7.38042951086872317523e-02, /* 0xBFB2E4D6, 0x99CBD01F */ +u01 = 1.76666452509181115538e-01, /* 0x3FC69D01, 0x9DE9E3FC */ +u02 = -1.38185671945596898896e-02, /* 0xBF8C4CE8, 0xB16CFA97 */ +u03 = 3.47453432093683650238e-04, /* 0x3F36C54D, 0x20B29B6B */ +u04 = -3.81407053724364161125e-06, /* 0xBECFFEA7, 0x73D25CAD */ +u05 = 1.95590137035022920206e-08, /* 0x3E550057, 0x3B4EABD4 */ +u06 = -3.98205194132103398453e-11, /* 0xBDC5E43D, 0x693FB3C8 */ +v01 = 1.27304834834123699328e-02, /* 0x3F8A1270, 0x91C9C71A */ +v02 = 7.60068627350353253702e-05, /* 0x3F13ECBB, 0xF578C6C1 */ +v03 = 2.59150851840457805467e-07, /* 0x3E91642D, 0x7FF202FD */ +v04 = 4.41110311332675467403e-10; /* 0x3DFE5018, 0x3BD6D9EF */ + +#ifdef __STDC__ + double __ieee754_y0(double x) +#else + double __ieee754_y0(x) + double x; +#endif +{ + fd_twoints un; + double z, s,c,ss,cc,u,v; + int hx,ix,lx; + + un.d = x; + hx = __HI(un); + ix = 0x7fffffff&hx; + lx = __LO(un); + /* Y0(NaN) is NaN, y0(-inf) is Nan, y0(inf) is 0 */ + if(ix>=0x7ff00000) return one/(x+x*x); + if((ix|lx)==0) return -one/zero; + if(hx<0) return zero/zero; + if(ix >= 0x40000000) { /* |x| >= 2.0 */ + /* y0(x) = sqrt(2/(pi*x))*(p0(x)*sin(x0)+q0(x)*cos(x0)) + * where x0 = x-pi/4 + * Better formula: + * cos(x0) = cos(x)cos(pi/4)+sin(x)sin(pi/4) + * = 1/sqrt(2) * (sin(x) + cos(x)) + * sin(x0) = sin(x)cos(3pi/4)-cos(x)sin(3pi/4) + * = 1/sqrt(2) * (sin(x) - cos(x)) + * To avoid cancellation, use + * sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x)) + * to compute the worse one. + */ + s = fd_sin(x); + c = fd_cos(x); + ss = s-c; + cc = s+c; + /* + * j0(x) = 1/sqrt(pi) * (P(0,x)*cc - Q(0,x)*ss) / sqrt(x) + * y0(x) = 1/sqrt(pi) * (P(0,x)*ss + Q(0,x)*cc) / sqrt(x) + */ + if(ix<0x7fe00000) { /* make sure x+x not overflow */ + z = -fd_cos(x+x); + if ((s*c)0x48000000) z = (invsqrtpi*ss)/fd_sqrt(x); + else { + u = pzero(x); v = qzero(x); + z = invsqrtpi*(u*ss+v*cc)/fd_sqrt(x); + } + return z; + } + if(ix<=0x3e400000) { /* x < 2**-27 */ + return(u00 + tpi*__ieee754_log(x)); + } + z = x*x; + u = u00+z*(u01+z*(u02+z*(u03+z*(u04+z*(u05+z*u06))))); + v = one+z*(v01+z*(v02+z*(v03+z*v04))); + return(u/v + tpi*(__ieee754_j0(x)*__ieee754_log(x))); +} + +/* The asymptotic expansions of pzero is + * 1 - 9/128 s^2 + 11025/98304 s^4 - ..., where s = 1/x. + * For x >= 2, We approximate pzero by + * pzero(x) = 1 + (R/S) + * where R = pR0 + pR1*s^2 + pR2*s^4 + ... + pR5*s^10 + * S = 1 + pS0*s^2 + ... + pS4*s^10 + * and + * | pzero(x)-1-R/S | <= 2 ** ( -60.26) + */ +#ifdef __STDC__ +static const double pR8[6] = { /* for x in [inf, 8]=1/[0,0.125] */ +#else +static double pR8[6] = { /* for x in [inf, 8]=1/[0,0.125] */ +#endif + 0.00000000000000000000e+00, /* 0x00000000, 0x00000000 */ + -7.03124999999900357484e-02, /* 0xBFB1FFFF, 0xFFFFFD32 */ + -8.08167041275349795626e+00, /* 0xC02029D0, 0xB44FA779 */ + -2.57063105679704847262e+02, /* 0xC0701102, 0x7B19E863 */ + -2.48521641009428822144e+03, /* 0xC0A36A6E, 0xCD4DCAFC */ + -5.25304380490729545272e+03, /* 0xC0B4850B, 0x36CC643D */ +}; +#ifdef __STDC__ +static const double pS8[5] = { +#else +static double pS8[5] = { +#endif + 1.16534364619668181717e+02, /* 0x405D2233, 0x07A96751 */ + 3.83374475364121826715e+03, /* 0x40ADF37D, 0x50596938 */ + 4.05978572648472545552e+04, /* 0x40E3D2BB, 0x6EB6B05F */ + 1.16752972564375915681e+05, /* 0x40FC810F, 0x8F9FA9BD */ + 4.76277284146730962675e+04, /* 0x40E74177, 0x4F2C49DC */ +}; + +#ifdef __STDC__ +static const double pR5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */ +#else +static double pR5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */ +#endif + -1.14125464691894502584e-11, /* 0xBDA918B1, 0x47E495CC */ + -7.03124940873599280078e-02, /* 0xBFB1FFFF, 0xE69AFBC6 */ + -4.15961064470587782438e+00, /* 0xC010A370, 0xF90C6BBF */ + -6.76747652265167261021e+01, /* 0xC050EB2F, 0x5A7D1783 */ + -3.31231299649172967747e+02, /* 0xC074B3B3, 0x6742CC63 */ + -3.46433388365604912451e+02, /* 0xC075A6EF, 0x28A38BD7 */ +}; +#ifdef __STDC__ +static const double pS5[5] = { +#else +static double pS5[5] = { +#endif + 6.07539382692300335975e+01, /* 0x404E6081, 0x0C98C5DE */ + 1.05125230595704579173e+03, /* 0x40906D02, 0x5C7E2864 */ + 5.97897094333855784498e+03, /* 0x40B75AF8, 0x8FBE1D60 */ + 9.62544514357774460223e+03, /* 0x40C2CCB8, 0xFA76FA38 */ + 2.40605815922939109441e+03, /* 0x40A2CC1D, 0xC70BE864 */ +}; + +#ifdef __STDC__ +static const double pR3[6] = {/* for x in [4.547,2.8571]=1/[0.2199,0.35001] */ +#else +static double pR3[6] = {/* for x in [4.547,2.8571]=1/[0.2199,0.35001] */ +#endif + -2.54704601771951915620e-09, /* 0xBE25E103, 0x6FE1AA86 */ + -7.03119616381481654654e-02, /* 0xBFB1FFF6, 0xF7C0E24B */ + -2.40903221549529611423e+00, /* 0xC00345B2, 0xAEA48074 */ + -2.19659774734883086467e+01, /* 0xC035F74A, 0x4CB94E14 */ + -5.80791704701737572236e+01, /* 0xC04D0A22, 0x420A1A45 */ + -3.14479470594888503854e+01, /* 0xC03F72AC, 0xA892D80F */ +}; +#ifdef __STDC__ +static const double pS3[5] = { +#else +static double pS3[5] = { +#endif + 3.58560338055209726349e+01, /* 0x4041ED92, 0x84077DD3 */ + 3.61513983050303863820e+02, /* 0x40769839, 0x464A7C0E */ + 1.19360783792111533330e+03, /* 0x4092A66E, 0x6D1061D6 */ + 1.12799679856907414432e+03, /* 0x40919FFC, 0xB8C39B7E */ + 1.73580930813335754692e+02, /* 0x4065B296, 0xFC379081 */ +}; + +#ifdef __STDC__ +static const double pR2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */ +#else +static double pR2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */ +#endif + -8.87534333032526411254e-08, /* 0xBE77D316, 0xE927026D */ + -7.03030995483624743247e-02, /* 0xBFB1FF62, 0x495E1E42 */ + -1.45073846780952986357e+00, /* 0xBFF73639, 0x8A24A843 */ + -7.63569613823527770791e+00, /* 0xC01E8AF3, 0xEDAFA7F3 */ + -1.11931668860356747786e+01, /* 0xC02662E6, 0xC5246303 */ + -3.23364579351335335033e+00, /* 0xC009DE81, 0xAF8FE70F */ +}; +#ifdef __STDC__ +static const double pS2[5] = { +#else +static double pS2[5] = { +#endif + 2.22202997532088808441e+01, /* 0x40363865, 0x908B5959 */ + 1.36206794218215208048e+02, /* 0x4061069E, 0x0EE8878F */ + 2.70470278658083486789e+02, /* 0x4070E786, 0x42EA079B */ + 1.53875394208320329881e+02, /* 0x40633C03, 0x3AB6FAFF */ + 1.46576176948256193810e+01, /* 0x402D50B3, 0x44391809 */ +}; + +#ifdef __STDC__ + static double pzero(double x) +#else + static double pzero(x) + double x; +#endif +{ +#ifdef __STDC__ + const double *p,*q; +#else + double *p,*q; +#endif + fd_twoints u; + double z,r,s; + int ix; + u.d = x; + ix = 0x7fffffff&__HI(u); + if(ix>=0x40200000) {p = pR8; q= pS8;} + else if(ix>=0x40122E8B){p = pR5; q= pS5;} + else if(ix>=0x4006DB6D){p = pR3; q= pS3;} + else if(ix>=0x40000000){p = pR2; q= pS2;} + z = one/(x*x); + r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5])))); + s = one+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*q[4])))); + return one+ r/s; +} + + +/* For x >= 8, the asymptotic expansions of qzero is + * -1/8 s + 75/1024 s^3 - ..., where s = 1/x. + * We approximate pzero by + * qzero(x) = s*(-1.25 + (R/S)) + * where R = qR0 + qR1*s^2 + qR2*s^4 + ... + qR5*s^10 + * S = 1 + qS0*s^2 + ... + qS5*s^12 + * and + * | qzero(x)/s +1.25-R/S | <= 2 ** ( -61.22) + */ +#ifdef __STDC__ +static const double qR8[6] = { /* for x in [inf, 8]=1/[0,0.125] */ +#else +static double qR8[6] = { /* for x in [inf, 8]=1/[0,0.125] */ +#endif + 0.00000000000000000000e+00, /* 0x00000000, 0x00000000 */ + 7.32421874999935051953e-02, /* 0x3FB2BFFF, 0xFFFFFE2C */ + 1.17682064682252693899e+01, /* 0x40278952, 0x5BB334D6 */ + 5.57673380256401856059e+02, /* 0x40816D63, 0x15301825 */ + 8.85919720756468632317e+03, /* 0x40C14D99, 0x3E18F46D */ + 3.70146267776887834771e+04, /* 0x40E212D4, 0x0E901566 */ +}; +#ifdef __STDC__ +static const double qS8[6] = { +#else +static double qS8[6] = { +#endif + 1.63776026895689824414e+02, /* 0x406478D5, 0x365B39BC */ + 8.09834494656449805916e+03, /* 0x40BFA258, 0x4E6B0563 */ + 1.42538291419120476348e+05, /* 0x41016652, 0x54D38C3F */ + 8.03309257119514397345e+05, /* 0x412883DA, 0x83A52B43 */ + 8.40501579819060512818e+05, /* 0x4129A66B, 0x28DE0B3D */ + -3.43899293537866615225e+05, /* 0xC114FD6D, 0x2C9530C5 */ +}; + +#ifdef __STDC__ +static const double qR5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */ +#else +static double qR5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */ +#endif + 1.84085963594515531381e-11, /* 0x3DB43D8F, 0x29CC8CD9 */ + 7.32421766612684765896e-02, /* 0x3FB2BFFF, 0xD172B04C */ + 5.83563508962056953777e+00, /* 0x401757B0, 0xB9953DD3 */ + 1.35111577286449829671e+02, /* 0x4060E392, 0x0A8788E9 */ + 1.02724376596164097464e+03, /* 0x40900CF9, 0x9DC8C481 */ + 1.98997785864605384631e+03, /* 0x409F17E9, 0x53C6E3A6 */ +}; +#ifdef __STDC__ +static const double qS5[6] = { +#else +static double qS5[6] = { +#endif + 8.27766102236537761883e+01, /* 0x4054B1B3, 0xFB5E1543 */ + 2.07781416421392987104e+03, /* 0x40A03BA0, 0xDA21C0CE */ + 1.88472887785718085070e+04, /* 0x40D267D2, 0x7B591E6D */ + 5.67511122894947329769e+04, /* 0x40EBB5E3, 0x97E02372 */ + 3.59767538425114471465e+04, /* 0x40E19118, 0x1F7A54A0 */ + -5.35434275601944773371e+03, /* 0xC0B4EA57, 0xBEDBC609 */ +}; + +#ifdef __STDC__ +static const double qR3[6] = {/* for x in [4.547,2.8571]=1/[0.2199,0.35001] */ +#else +static double qR3[6] = {/* for x in [4.547,2.8571]=1/[0.2199,0.35001] */ +#endif + 4.37741014089738620906e-09, /* 0x3E32CD03, 0x6ADECB82 */ + 7.32411180042911447163e-02, /* 0x3FB2BFEE, 0x0E8D0842 */ + 3.34423137516170720929e+00, /* 0x400AC0FC, 0x61149CF5 */ + 4.26218440745412650017e+01, /* 0x40454F98, 0x962DAEDD */ + 1.70808091340565596283e+02, /* 0x406559DB, 0xE25EFD1F */ + 1.66733948696651168575e+02, /* 0x4064D77C, 0x81FA21E0 */ +}; +#ifdef __STDC__ +static const double qS3[6] = { +#else +static double qS3[6] = { +#endif + 4.87588729724587182091e+01, /* 0x40486122, 0xBFE343A6 */ + 7.09689221056606015736e+02, /* 0x40862D83, 0x86544EB3 */ + 3.70414822620111362994e+03, /* 0x40ACF04B, 0xE44DFC63 */ + 6.46042516752568917582e+03, /* 0x40B93C6C, 0xD7C76A28 */ + 2.51633368920368957333e+03, /* 0x40A3A8AA, 0xD94FB1C0 */ + -1.49247451836156386662e+02, /* 0xC062A7EB, 0x201CF40F */ +}; + +#ifdef __STDC__ +static const double qR2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */ +#else +static double qR2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */ +#endif + 1.50444444886983272379e-07, /* 0x3E84313B, 0x54F76BDB */ + 7.32234265963079278272e-02, /* 0x3FB2BEC5, 0x3E883E34 */ + 1.99819174093815998816e+00, /* 0x3FFFF897, 0xE727779C */ + 1.44956029347885735348e+01, /* 0x402CFDBF, 0xAAF96FE5 */ + 3.16662317504781540833e+01, /* 0x403FAA8E, 0x29FBDC4A */ + 1.62527075710929267416e+01, /* 0x403040B1, 0x71814BB4 */ +}; +#ifdef __STDC__ +static const double qS2[6] = { +#else +static double qS2[6] = { +#endif + 3.03655848355219184498e+01, /* 0x403E5D96, 0xF7C07AED */ + 2.69348118608049844624e+02, /* 0x4070D591, 0xE4D14B40 */ + 8.44783757595320139444e+02, /* 0x408A6645, 0x22B3BF22 */ + 8.82935845112488550512e+02, /* 0x408B977C, 0x9C5CC214 */ + 2.12666388511798828631e+02, /* 0x406A9553, 0x0E001365 */ + -5.31095493882666946917e+00, /* 0xC0153E6A, 0xF8B32931 */ +}; + +#ifdef __STDC__ + static double qzero(double x) +#else + static double qzero(x) + double x; +#endif +{ +#ifdef __STDC__ + const double *p,*q; +#else + double *p,*q; +#endif + fd_twoints u; + double s,r,z; + int ix; + u.d = x; + ix = 0x7fffffff&__HI(u); + if(ix>=0x40200000) {p = qR8; q= qS8;} + else if(ix>=0x40122E8B){p = qR5; q= qS5;} + else if(ix>=0x4006DB6D){p = qR3; q= qS3;} + else if(ix>=0x40000000){p = qR2; q= qS2;} + z = one/(x*x); + r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5])))); + s = one+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*(q[4]+z*q[5]))))); + return (-.125 + r/s)/x; +} diff --git a/src/dom/js/fdlibm/e_j1.c b/src/dom/js/fdlibm/e_j1.c new file mode 100644 index 000000000..8982ac86a --- /dev/null +++ b/src/dom/js/fdlibm/e_j1.c @@ -0,0 +1,523 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Sun Microsystems, Inc. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* @(#)e_j1.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* __ieee754_j1(x), __ieee754_y1(x) + * Bessel function of the first and second kinds of order zero. + * Method -- j1(x): + * 1. For tiny x, we use j1(x) = x/2 - x^3/16 + x^5/384 - ... + * 2. Reduce x to |x| since j1(x)=-j1(-x), and + * for x in (0,2) + * j1(x) = x/2 + x*z*R0/S0, where z = x*x; + * (precision: |j1/x - 1/2 - R0/S0 |<2**-61.51 ) + * for x in (2,inf) + * j1(x) = sqrt(2/(pi*x))*(p1(x)*cos(x1)-q1(x)*sin(x1)) + * y1(x) = sqrt(2/(pi*x))*(p1(x)*sin(x1)+q1(x)*cos(x1)) + * where x1 = x-3*pi/4. It is better to compute sin(x1),cos(x1) + * as follow: + * cos(x1) = cos(x)cos(3pi/4)+sin(x)sin(3pi/4) + * = 1/sqrt(2) * (sin(x) - cos(x)) + * sin(x1) = sin(x)cos(3pi/4)-cos(x)sin(3pi/4) + * = -1/sqrt(2) * (sin(x) + cos(x)) + * (To avoid cancellation, use + * sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x)) + * to compute the worse one.) + * + * 3 Special cases + * j1(nan)= nan + * j1(0) = 0 + * j1(inf) = 0 + * + * Method -- y1(x): + * 1. screen out x<=0 cases: y1(0)=-inf, y1(x<0)=NaN + * 2. For x<2. + * Since + * y1(x) = 2/pi*(j1(x)*(ln(x/2)+Euler)-1/x-x/2+5/64*x^3-...) + * therefore y1(x)-2/pi*j1(x)*ln(x)-1/x is an odd function. + * We use the following function to approximate y1, + * y1(x) = x*U(z)/V(z) + (2/pi)*(j1(x)*ln(x)-1/x), z= x^2 + * where for x in [0,2] (abs err less than 2**-65.89) + * U(z) = U0[0] + U0[1]*z + ... + U0[4]*z^4 + * V(z) = 1 + v0[0]*z + ... + v0[4]*z^5 + * Note: For tiny x, 1/x dominate y1 and hence + * y1(tiny) = -2/pi/tiny, (choose tiny<2**-54) + * 3. For x>=2. + * y1(x) = sqrt(2/(pi*x))*(p1(x)*sin(x1)+q1(x)*cos(x1)) + * where x1 = x-3*pi/4. It is better to compute sin(x1),cos(x1) + * by method mentioned above. + */ + +#include "fdlibm.h" + +#ifdef __STDC__ +static double pone(double), qone(double); +#else +static double pone(), qone(); +#endif + +#ifdef __STDC__ +static const double +#else +static double +#endif +really_big = 1e300, +one = 1.0, +invsqrtpi= 5.64189583547756279280e-01, /* 0x3FE20DD7, 0x50429B6D */ +tpi = 6.36619772367581382433e-01, /* 0x3FE45F30, 0x6DC9C883 */ + /* R0/S0 on [0,2] */ +r00 = -6.25000000000000000000e-02, /* 0xBFB00000, 0x00000000 */ +r01 = 1.40705666955189706048e-03, /* 0x3F570D9F, 0x98472C61 */ +r02 = -1.59955631084035597520e-05, /* 0xBEF0C5C6, 0xBA169668 */ +r03 = 4.96727999609584448412e-08, /* 0x3E6AAAFA, 0x46CA0BD9 */ +s01 = 1.91537599538363460805e-02, /* 0x3F939D0B, 0x12637E53 */ +s02 = 1.85946785588630915560e-04, /* 0x3F285F56, 0xB9CDF664 */ +s03 = 1.17718464042623683263e-06, /* 0x3EB3BFF8, 0x333F8498 */ +s04 = 5.04636257076217042715e-09, /* 0x3E35AC88, 0xC97DFF2C */ +s05 = 1.23542274426137913908e-11; /* 0x3DAB2ACF, 0xCFB97ED8 */ + +static double zero = 0.0; + +#ifdef __STDC__ + double __ieee754_j1(double x) +#else + double __ieee754_j1(x) + double x; +#endif +{ + fd_twoints un; + double z, s,c,ss,cc,r,u,v,y; + int hx,ix; + + un.d = x; + hx = __HI(un); + ix = hx&0x7fffffff; + if(ix>=0x7ff00000) return one/x; + y = fd_fabs(x); + if(ix >= 0x40000000) { /* |x| >= 2.0 */ + s = fd_sin(y); + c = fd_cos(y); + ss = -s-c; + cc = s-c; + if(ix<0x7fe00000) { /* make sure y+y not overflow */ + z = fd_cos(y+y); + if ((s*c)>zero) cc = z/ss; + else ss = z/cc; + } + /* + * j1(x) = 1/sqrt(pi) * (P(1,x)*cc - Q(1,x)*ss) / sqrt(x) + * y1(x) = 1/sqrt(pi) * (P(1,x)*ss + Q(1,x)*cc) / sqrt(x) + */ + if(ix>0x48000000) z = (invsqrtpi*cc)/fd_sqrt(y); + else { + u = pone(y); v = qone(y); + z = invsqrtpi*(u*cc-v*ss)/fd_sqrt(y); + } + if(hx<0) return -z; + else return z; + } + if(ix<0x3e400000) { /* |x|<2**-27 */ + if(really_big+x>one) return 0.5*x;/* inexact if x!=0 necessary */ + } + z = x*x; + r = z*(r00+z*(r01+z*(r02+z*r03))); + s = one+z*(s01+z*(s02+z*(s03+z*(s04+z*s05)))); + r *= x; + return(x*0.5+r/s); +} + +#ifdef __STDC__ +static const double U0[5] = { +#else +static double U0[5] = { +#endif + -1.96057090646238940668e-01, /* 0xBFC91866, 0x143CBC8A */ + 5.04438716639811282616e-02, /* 0x3FA9D3C7, 0x76292CD1 */ + -1.91256895875763547298e-03, /* 0xBF5F55E5, 0x4844F50F */ + 2.35252600561610495928e-05, /* 0x3EF8AB03, 0x8FA6B88E */ + -9.19099158039878874504e-08, /* 0xBE78AC00, 0x569105B8 */ +}; +#ifdef __STDC__ +static const double V0[5] = { +#else +static double V0[5] = { +#endif + 1.99167318236649903973e-02, /* 0x3F94650D, 0x3F4DA9F0 */ + 2.02552581025135171496e-04, /* 0x3F2A8C89, 0x6C257764 */ + 1.35608801097516229404e-06, /* 0x3EB6C05A, 0x894E8CA6 */ + 6.22741452364621501295e-09, /* 0x3E3ABF1D, 0x5BA69A86 */ + 1.66559246207992079114e-11, /* 0x3DB25039, 0xDACA772A */ +}; + +#ifdef __STDC__ + double __ieee754_y1(double x) +#else + double __ieee754_y1(x) + double x; +#endif +{ + fd_twoints un; + double z, s,c,ss,cc,u,v; + int hx,ix,lx; + + un.d = x; + hx = __HI(un); + ix = 0x7fffffff&hx; + lx = __LO(un); + /* if Y1(NaN) is NaN, Y1(-inf) is NaN, Y1(inf) is 0 */ + if(ix>=0x7ff00000) return one/(x+x*x); + if((ix|lx)==0) return -one/zero; + if(hx<0) return zero/zero; + if(ix >= 0x40000000) { /* |x| >= 2.0 */ + s = fd_sin(x); + c = fd_cos(x); + ss = -s-c; + cc = s-c; + if(ix<0x7fe00000) { /* make sure x+x not overflow */ + z = fd_cos(x+x); + if ((s*c)>zero) cc = z/ss; + else ss = z/cc; + } + /* y1(x) = sqrt(2/(pi*x))*(p1(x)*sin(x0)+q1(x)*cos(x0)) + * where x0 = x-3pi/4 + * Better formula: + * cos(x0) = cos(x)cos(3pi/4)+sin(x)sin(3pi/4) + * = 1/sqrt(2) * (sin(x) - cos(x)) + * sin(x0) = sin(x)cos(3pi/4)-cos(x)sin(3pi/4) + * = -1/sqrt(2) * (cos(x) + sin(x)) + * To avoid cancellation, use + * sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x)) + * to compute the worse one. + */ + if(ix>0x48000000) z = (invsqrtpi*ss)/fd_sqrt(x); + else { + u = pone(x); v = qone(x); + z = invsqrtpi*(u*ss+v*cc)/fd_sqrt(x); + } + return z; + } + if(ix<=0x3c900000) { /* x < 2**-54 */ + return(-tpi/x); + } + z = x*x; + u = U0[0]+z*(U0[1]+z*(U0[2]+z*(U0[3]+z*U0[4]))); + v = one+z*(V0[0]+z*(V0[1]+z*(V0[2]+z*(V0[3]+z*V0[4])))); + return(x*(u/v) + tpi*(__ieee754_j1(x)*__ieee754_log(x)-one/x)); +} + +/* For x >= 8, the asymptotic expansions of pone is + * 1 + 15/128 s^2 - 4725/2^15 s^4 - ..., where s = 1/x. + * We approximate pone by + * pone(x) = 1 + (R/S) + * where R = pr0 + pr1*s^2 + pr2*s^4 + ... + pr5*s^10 + * S = 1 + ps0*s^2 + ... + ps4*s^10 + * and + * | pone(x)-1-R/S | <= 2 ** ( -60.06) + */ + +#ifdef __STDC__ +static const double pr8[6] = { /* for x in [inf, 8]=1/[0,0.125] */ +#else +static double pr8[6] = { /* for x in [inf, 8]=1/[0,0.125] */ +#endif + 0.00000000000000000000e+00, /* 0x00000000, 0x00000000 */ + 1.17187499999988647970e-01, /* 0x3FBDFFFF, 0xFFFFFCCE */ + 1.32394806593073575129e+01, /* 0x402A7A9D, 0x357F7FCE */ + 4.12051854307378562225e+02, /* 0x4079C0D4, 0x652EA590 */ + 3.87474538913960532227e+03, /* 0x40AE457D, 0xA3A532CC */ + 7.91447954031891731574e+03, /* 0x40BEEA7A, 0xC32782DD */ +}; +#ifdef __STDC__ +static const double ps8[5] = { +#else +static double ps8[5] = { +#endif + 1.14207370375678408436e+02, /* 0x405C8D45, 0x8E656CAC */ + 3.65093083420853463394e+03, /* 0x40AC85DC, 0x964D274F */ + 3.69562060269033463555e+04, /* 0x40E20B86, 0x97C5BB7F */ + 9.76027935934950801311e+04, /* 0x40F7D42C, 0xB28F17BB */ + 3.08042720627888811578e+04, /* 0x40DE1511, 0x697A0B2D */ +}; + +#ifdef __STDC__ +static const double pr5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */ +#else +static double pr5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */ +#endif + 1.31990519556243522749e-11, /* 0x3DAD0667, 0xDAE1CA7D */ + 1.17187493190614097638e-01, /* 0x3FBDFFFF, 0xE2C10043 */ + 6.80275127868432871736e+00, /* 0x401B3604, 0x6E6315E3 */ + 1.08308182990189109773e+02, /* 0x405B13B9, 0x452602ED */ + 5.17636139533199752805e+02, /* 0x40802D16, 0xD052D649 */ + 5.28715201363337541807e+02, /* 0x408085B8, 0xBB7E0CB7 */ +}; +#ifdef __STDC__ +static const double ps5[5] = { +#else +static double ps5[5] = { +#endif + 5.92805987221131331921e+01, /* 0x404DA3EA, 0xA8AF633D */ + 9.91401418733614377743e+02, /* 0x408EFB36, 0x1B066701 */ + 5.35326695291487976647e+03, /* 0x40B4E944, 0x5706B6FB */ + 7.84469031749551231769e+03, /* 0x40BEA4B0, 0xB8A5BB15 */ + 1.50404688810361062679e+03, /* 0x40978030, 0x036F5E51 */ +}; + +#ifdef __STDC__ +static const double pr3[6] = { +#else +static double pr3[6] = {/* for x in [4.547,2.8571]=1/[0.2199,0.35001] */ +#endif + 3.02503916137373618024e-09, /* 0x3E29FC21, 0xA7AD9EDD */ + 1.17186865567253592491e-01, /* 0x3FBDFFF5, 0x5B21D17B */ + 3.93297750033315640650e+00, /* 0x400F76BC, 0xE85EAD8A */ + 3.51194035591636932736e+01, /* 0x40418F48, 0x9DA6D129 */ + 9.10550110750781271918e+01, /* 0x4056C385, 0x4D2C1837 */ + 4.85590685197364919645e+01, /* 0x4048478F, 0x8EA83EE5 */ +}; +#ifdef __STDC__ +static const double ps3[5] = { +#else +static double ps3[5] = { +#endif + 3.47913095001251519989e+01, /* 0x40416549, 0xA134069C */ + 3.36762458747825746741e+02, /* 0x40750C33, 0x07F1A75F */ + 1.04687139975775130551e+03, /* 0x40905B7C, 0x5037D523 */ + 8.90811346398256432622e+02, /* 0x408BD67D, 0xA32E31E9 */ + 1.03787932439639277504e+02, /* 0x4059F26D, 0x7C2EED53 */ +}; + +#ifdef __STDC__ +static const double pr2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */ +#else +static double pr2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */ +#endif + 1.07710830106873743082e-07, /* 0x3E7CE9D4, 0xF65544F4 */ + 1.17176219462683348094e-01, /* 0x3FBDFF42, 0xBE760D83 */ + 2.36851496667608785174e+00, /* 0x4002F2B7, 0xF98FAEC0 */ + 1.22426109148261232917e+01, /* 0x40287C37, 0x7F71A964 */ + 1.76939711271687727390e+01, /* 0x4031B1A8, 0x177F8EE2 */ + 5.07352312588818499250e+00, /* 0x40144B49, 0xA574C1FE */ +}; +#ifdef __STDC__ +static const double ps2[5] = { +#else +static double ps2[5] = { +#endif + 2.14364859363821409488e+01, /* 0x40356FBD, 0x8AD5ECDC */ + 1.25290227168402751090e+02, /* 0x405F5293, 0x14F92CD5 */ + 2.32276469057162813669e+02, /* 0x406D08D8, 0xD5A2DBD9 */ + 1.17679373287147100768e+02, /* 0x405D6B7A, 0xDA1884A9 */ + 8.36463893371618283368e+00, /* 0x4020BAB1, 0xF44E5192 */ +}; + +#ifdef __STDC__ + static double pone(double x) +#else + static double pone(x) + double x; +#endif +{ +#ifdef __STDC__ + const double *p,*q; +#else + double *p,*q; +#endif + fd_twoints un; + double z,r,s; + int ix; + un.d = x; + ix = 0x7fffffff&__HI(un); + if(ix>=0x40200000) {p = pr8; q= ps8;} + else if(ix>=0x40122E8B){p = pr5; q= ps5;} + else if(ix>=0x4006DB6D){p = pr3; q= ps3;} + else if(ix>=0x40000000){p = pr2; q= ps2;} + z = one/(x*x); + r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5])))); + s = one+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*q[4])))); + return one+ r/s; +} + + +/* For x >= 8, the asymptotic expansions of qone is + * 3/8 s - 105/1024 s^3 - ..., where s = 1/x. + * We approximate pone by + * qone(x) = s*(0.375 + (R/S)) + * where R = qr1*s^2 + qr2*s^4 + ... + qr5*s^10 + * S = 1 + qs1*s^2 + ... + qs6*s^12 + * and + * | qone(x)/s -0.375-R/S | <= 2 ** ( -61.13) + */ + +#ifdef __STDC__ +static const double qr8[6] = { /* for x in [inf, 8]=1/[0,0.125] */ +#else +static double qr8[6] = { /* for x in [inf, 8]=1/[0,0.125] */ +#endif + 0.00000000000000000000e+00, /* 0x00000000, 0x00000000 */ + -1.02539062499992714161e-01, /* 0xBFBA3FFF, 0xFFFFFDF3 */ + -1.62717534544589987888e+01, /* 0xC0304591, 0xA26779F7 */ + -7.59601722513950107896e+02, /* 0xC087BCD0, 0x53E4B576 */ + -1.18498066702429587167e+04, /* 0xC0C724E7, 0x40F87415 */ + -4.84385124285750353010e+04, /* 0xC0E7A6D0, 0x65D09C6A */ +}; +#ifdef __STDC__ +static const double qs8[6] = { +#else +static double qs8[6] = { +#endif + 1.61395369700722909556e+02, /* 0x40642CA6, 0xDE5BCDE5 */ + 7.82538599923348465381e+03, /* 0x40BE9162, 0xD0D88419 */ + 1.33875336287249578163e+05, /* 0x4100579A, 0xB0B75E98 */ + 7.19657723683240939863e+05, /* 0x4125F653, 0x72869C19 */ + 6.66601232617776375264e+05, /* 0x412457D2, 0x7719AD5C */ + -2.94490264303834643215e+05, /* 0xC111F969, 0x0EA5AA18 */ +}; + +#ifdef __STDC__ +static const double qr5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */ +#else +static double qr5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */ +#endif + -2.08979931141764104297e-11, /* 0xBDB6FA43, 0x1AA1A098 */ + -1.02539050241375426231e-01, /* 0xBFBA3FFF, 0xCB597FEF */ + -8.05644828123936029840e+00, /* 0xC0201CE6, 0xCA03AD4B */ + -1.83669607474888380239e+02, /* 0xC066F56D, 0x6CA7B9B0 */ + -1.37319376065508163265e+03, /* 0xC09574C6, 0x6931734F */ + -2.61244440453215656817e+03, /* 0xC0A468E3, 0x88FDA79D */ +}; +#ifdef __STDC__ +static const double qs5[6] = { +#else +static double qs5[6] = { +#endif + 8.12765501384335777857e+01, /* 0x405451B2, 0xFF5A11B2 */ + 1.99179873460485964642e+03, /* 0x409F1F31, 0xE77BF839 */ + 1.74684851924908907677e+04, /* 0x40D10F1F, 0x0D64CE29 */ + 4.98514270910352279316e+04, /* 0x40E8576D, 0xAABAD197 */ + 2.79480751638918118260e+04, /* 0x40DB4B04, 0xCF7C364B */ + -4.71918354795128470869e+03, /* 0xC0B26F2E, 0xFCFFA004 */ +}; + +#ifdef __STDC__ +static const double qr3[6] = { +#else +static double qr3[6] = {/* for x in [4.547,2.8571]=1/[0.2199,0.35001] */ +#endif + -5.07831226461766561369e-09, /* 0xBE35CFA9, 0xD38FC84F */ + -1.02537829820837089745e-01, /* 0xBFBA3FEB, 0x51AEED54 */ + -4.61011581139473403113e+00, /* 0xC01270C2, 0x3302D9FF */ + -5.78472216562783643212e+01, /* 0xC04CEC71, 0xC25D16DA */ + -2.28244540737631695038e+02, /* 0xC06C87D3, 0x4718D55F */ + -2.19210128478909325622e+02, /* 0xC06B66B9, 0x5F5C1BF6 */ +}; +#ifdef __STDC__ +static const double qs3[6] = { +#else +static double qs3[6] = { +#endif + 4.76651550323729509273e+01, /* 0x4047D523, 0xCCD367E4 */ + 6.73865112676699709482e+02, /* 0x40850EEB, 0xC031EE3E */ + 3.38015286679526343505e+03, /* 0x40AA684E, 0x448E7C9A */ + 5.54772909720722782367e+03, /* 0x40B5ABBA, 0xA61D54A6 */ + 1.90311919338810798763e+03, /* 0x409DBC7A, 0x0DD4DF4B */ + -1.35201191444307340817e+02, /* 0xC060E670, 0x290A311F */ +}; + +#ifdef __STDC__ +static const double qr2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */ +#else +static double qr2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */ +#endif + -1.78381727510958865572e-07, /* 0xBE87F126, 0x44C626D2 */ + -1.02517042607985553460e-01, /* 0xBFBA3E8E, 0x9148B010 */ + -2.75220568278187460720e+00, /* 0xC0060484, 0x69BB4EDA */ + -1.96636162643703720221e+01, /* 0xC033A9E2, 0xC168907F */ + -4.23253133372830490089e+01, /* 0xC04529A3, 0xDE104AAA */ + -2.13719211703704061733e+01, /* 0xC0355F36, 0x39CF6E52 */ +}; +#ifdef __STDC__ +static const double qs2[6] = { +#else +static double qs2[6] = { +#endif + 2.95333629060523854548e+01, /* 0x403D888A, 0x78AE64FF */ + 2.52981549982190529136e+02, /* 0x406F9F68, 0xDB821CBA */ + 7.57502834868645436472e+02, /* 0x4087AC05, 0xCE49A0F7 */ + 7.39393205320467245656e+02, /* 0x40871B25, 0x48D4C029 */ + 1.55949003336666123687e+02, /* 0x40637E5E, 0x3C3ED8D4 */ + -4.95949898822628210127e+00, /* 0xC013D686, 0xE71BE86B */ +}; + +#ifdef __STDC__ + static double qone(double x) +#else + static double qone(x) + double x; +#endif +{ +#ifdef __STDC__ + const double *p,*q; +#else + double *p,*q; +#endif + fd_twoints un; + double s,r,z; + int ix; + un.d = x; + ix = 0x7fffffff&__HI(un); + if(ix>=0x40200000) {p = qr8; q= qs8;} + else if(ix>=0x40122E8B){p = qr5; q= qs5;} + else if(ix>=0x4006DB6D){p = qr3; q= qs3;} + else if(ix>=0x40000000){p = qr2; q= qs2;} + z = one/(x*x); + r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5])))); + s = one+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*(q[4]+z*q[5]))))); + return (.375 + r/s)/x; +} diff --git a/src/dom/js/fdlibm/e_jn.c b/src/dom/js/fdlibm/e_jn.c new file mode 100644 index 000000000..2b61b4439 --- /dev/null +++ b/src/dom/js/fdlibm/e_jn.c @@ -0,0 +1,315 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Sun Microsystems, Inc. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* @(#)e_jn.c 1.4 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * __ieee754_jn(n, x), __ieee754_yn(n, x) + * floating point Bessel's function of the 1st and 2nd kind + * of order n + * + * Special cases: + * y0(0)=y1(0)=yn(n,0) = -inf with division by zero signal; + * y0(-ve)=y1(-ve)=yn(n,-ve) are NaN with invalid signal. + * Note 2. About jn(n,x), yn(n,x) + * For n=0, j0(x) is called, + * for n=1, j1(x) is called, + * for nx, a continued fraction approximation to + * j(n,x)/j(n-1,x) is evaluated and then backward + * recursion is used starting from a supposed value + * for j(n,x). The resulting value of j(0,x) is + * compared with the actual value to correct the + * supposed value of j(n,x). + * + * yn(n,x) is similar in all respects, except + * that forward recursion is used for all + * values of n>1. + * + */ + +#include "fdlibm.h" + +#ifdef __STDC__ +static const double +#else +static double +#endif +invsqrtpi= 5.64189583547756279280e-01, /* 0x3FE20DD7, 0x50429B6D */ +two = 2.00000000000000000000e+00, /* 0x40000000, 0x00000000 */ +one = 1.00000000000000000000e+00; /* 0x3FF00000, 0x00000000 */ + +static double zero = 0.00000000000000000000e+00; + +#ifdef __STDC__ + double __ieee754_jn(int n, double x) +#else + double __ieee754_jn(n,x) + int n; double x; +#endif +{ + fd_twoints u; + int i,hx,ix,lx, sgn; + double a, b, temp, di; + double z, w; + + /* J(-n,x) = (-1)^n * J(n, x), J(n, -x) = (-1)^n * J(n, x) + * Thus, J(-n,x) = J(n,-x) + */ + u.d = x; + hx = __HI(u); + ix = 0x7fffffff&hx; + lx = __LO(u); + /* if J(n,NaN) is NaN */ + if((ix|((unsigned)(lx|-lx))>>31)>0x7ff00000) return x+x; + if(n<0){ + n = -n; + x = -x; + hx ^= 0x80000000; + } + if(n==0) return(__ieee754_j0(x)); + if(n==1) return(__ieee754_j1(x)); + sgn = (n&1)&(hx>>31); /* even n -- 0, odd n -- sign(x) */ + x = fd_fabs(x); + if((ix|lx)==0||ix>=0x7ff00000) /* if x is 0 or inf */ + b = zero; + else if((double)n<=x) { + /* Safe to use J(n+1,x)=2n/x *J(n,x)-J(n-1,x) */ + if(ix>=0x52D00000) { /* x > 2**302 */ + /* (x >> n**2) + * Jn(x) = cos(x-(2n+1)*pi/4)*sqrt(2/x*pi) + * Yn(x) = sin(x-(2n+1)*pi/4)*sqrt(2/x*pi) + * Let s=sin(x), c=cos(x), + * xn=x-(2n+1)*pi/4, sqt2 = sqrt(2),then + * + * n sin(xn)*sqt2 cos(xn)*sqt2 + * ---------------------------------- + * 0 s-c c+s + * 1 -s-c -c+s + * 2 -s+c -c-s + * 3 s+c c-s + */ + switch(n&3) { + case 0: temp = fd_cos(x)+fd_sin(x); break; + case 1: temp = -fd_cos(x)+fd_sin(x); break; + case 2: temp = -fd_cos(x)-fd_sin(x); break; + case 3: temp = fd_cos(x)-fd_sin(x); break; + } + b = invsqrtpi*temp/fd_sqrt(x); + } else { + a = __ieee754_j0(x); + b = __ieee754_j1(x); + for(i=1;i33) /* underflow */ + b = zero; + else { + temp = x*0.5; b = temp; + for (a=one,i=2;i<=n;i++) { + a *= (double)i; /* a = n! */ + b *= temp; /* b = (x/2)^n */ + } + b = b/a; + } + } else { + /* use backward recurrence */ + /* x x^2 x^2 + * J(n,x)/J(n-1,x) = ---- ------ ------ ..... + * 2n - 2(n+1) - 2(n+2) + * + * 1 1 1 + * (for large x) = ---- ------ ------ ..... + * 2n 2(n+1) 2(n+2) + * -- - ------ - ------ - + * x x x + * + * Let w = 2n/x and h=2/x, then the above quotient + * is equal to the continued fraction: + * 1 + * = ----------------------- + * 1 + * w - ----------------- + * 1 + * w+h - --------- + * w+2h - ... + * + * To determine how many terms needed, let + * Q(0) = w, Q(1) = w(w+h) - 1, + * Q(k) = (w+k*h)*Q(k-1) - Q(k-2), + * When Q(k) > 1e4 good for single + * When Q(k) > 1e9 good for double + * When Q(k) > 1e17 good for quadruple + */ + /* determine k */ + double t,v; + double q0,q1,h,tmp; int k,m; + w = (n+n)/(double)x; h = 2.0/(double)x; + q0 = w; z = w+h; q1 = w*z - 1.0; k=1; + while(q1<1.0e9) { + k += 1; z += h; + tmp = z*q1 - q0; + q0 = q1; + q1 = tmp; + } + m = n+n; + for(t=zero, i = 2*(n+k); i>=m; i -= 2) t = one/(i/x-t); + a = t; + b = one; + /* estimate log((2/x)^n*n!) = n*log(2/x)+n*ln(n) + * Hence, if n*(log(2n/x)) > ... + * single 8.8722839355e+01 + * double 7.09782712893383973096e+02 + * long double 1.1356523406294143949491931077970765006170e+04 + * then recurrent value may overflow and the result is + * likely underflow to zero + */ + tmp = n; + v = two/x; + tmp = tmp*__ieee754_log(fd_fabs(v*tmp)); + if(tmp<7.09782712893383973096e+02) { + for(i=n-1,di=(double)(i+i);i>0;i--){ + temp = b; + b *= di; + b = b/x - a; + a = temp; + di -= two; + } + } else { + for(i=n-1,di=(double)(i+i);i>0;i--){ + temp = b; + b *= di; + b = b/x - a; + a = temp; + di -= two; + /* scale b to avoid spurious overflow */ + if(b>1e100) { + a /= b; + t /= b; + b = one; + } + } + } + b = (t*__ieee754_j0(x)/b); + } + } + if(sgn==1) return -b; else return b; +} + +#ifdef __STDC__ + double __ieee754_yn(int n, double x) +#else + double __ieee754_yn(n,x) + int n; double x; +#endif +{ + fd_twoints u; + int i,hx,ix,lx; + int sign; + double a, b, temp; + + u.d = x; + hx = __HI(u); + ix = 0x7fffffff&hx; + lx = __LO(u); + /* if Y(n,NaN) is NaN */ + if((ix|((unsigned)(lx|-lx))>>31)>0x7ff00000) return x+x; + if((ix|lx)==0) return -one/zero; + if(hx<0) return zero/zero; + sign = 1; + if(n<0){ + n = -n; + sign = 1 - ((n&1)<<1); + } + if(n==0) return(__ieee754_y0(x)); + if(n==1) return(sign*__ieee754_y1(x)); + if(ix==0x7ff00000) return zero; + if(ix>=0x52D00000) { /* x > 2**302 */ + /* (x >> n**2) + * Jn(x) = cos(x-(2n+1)*pi/4)*sqrt(2/x*pi) + * Yn(x) = sin(x-(2n+1)*pi/4)*sqrt(2/x*pi) + * Let s=sin(x), c=cos(x), + * xn=x-(2n+1)*pi/4, sqt2 = sqrt(2),then + * + * n sin(xn)*sqt2 cos(xn)*sqt2 + * ---------------------------------- + * 0 s-c c+s + * 1 -s-c -c+s + * 2 -s+c -c-s + * 3 s+c c-s + */ + switch(n&3) { + case 0: temp = fd_sin(x)-fd_cos(x); break; + case 1: temp = -fd_sin(x)-fd_cos(x); break; + case 2: temp = -fd_sin(x)+fd_cos(x); break; + case 3: temp = fd_sin(x)+fd_cos(x); break; + } + b = invsqrtpi*temp/fd_sqrt(x); + } else { + a = __ieee754_y0(x); + b = __ieee754_y1(x); + /* quit if b is -inf */ + u.d = b; + for(i=1;i0) return b; else return -b; +} diff --git a/src/dom/js/fdlibm/e_lgamma.c b/src/dom/js/fdlibm/e_lgamma.c new file mode 100644 index 000000000..beb3bd932 --- /dev/null +++ b/src/dom/js/fdlibm/e_lgamma.c @@ -0,0 +1,71 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Sun Microsystems, Inc. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* @(#)e_lgamma.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + * + */ + +/* __ieee754_lgamma(x) + * Return the logarithm of the Gamma function of x. + * + * Method: call __ieee754_lgamma_r + */ + +#include "fdlibm.h" + +extern int signgam; + +#ifdef __STDC__ + double __ieee754_lgamma(double x) +#else + double __ieee754_lgamma(x) + double x; +#endif +{ + return __ieee754_lgamma_r(x,&signgam); +} diff --git a/src/dom/js/fdlibm/e_lgamma_r.c b/src/dom/js/fdlibm/e_lgamma_r.c new file mode 100644 index 000000000..df92e7a26 --- /dev/null +++ b/src/dom/js/fdlibm/e_lgamma_r.c @@ -0,0 +1,347 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Sun Microsystems, Inc. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* @(#)e_lgamma_r.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + * + */ + +/* __ieee754_lgamma_r(x, signgamp) + * Reentrant version of the logarithm of the Gamma function + * with user provide pointer for the sign of Gamma(x). + * + * Method: + * 1. Argument Reduction for 0 < x <= 8 + * Since gamma(1+s)=s*gamma(s), for x in [0,8], we may + * reduce x to a number in [1.5,2.5] by + * lgamma(1+s) = log(s) + lgamma(s) + * for example, + * lgamma(7.3) = log(6.3) + lgamma(6.3) + * = log(6.3*5.3) + lgamma(5.3) + * = log(6.3*5.3*4.3*3.3*2.3) + lgamma(2.3) + * 2. Polynomial approximation of lgamma around its + * minimun ymin=1.461632144968362245 to maintain monotonicity. + * On [ymin-0.23, ymin+0.27] (i.e., [1.23164,1.73163]), use + * Let z = x-ymin; + * lgamma(x) = -1.214862905358496078218 + z^2*poly(z) + * where + * poly(z) is a 14 degree polynomial. + * 2. Rational approximation in the primary interval [2,3] + * We use the following approximation: + * s = x-2.0; + * lgamma(x) = 0.5*s + s*P(s)/Q(s) + * with accuracy + * |P/Q - (lgamma(x)-0.5s)| < 2**-61.71 + * Our algorithms are based on the following observation + * + * zeta(2)-1 2 zeta(3)-1 3 + * lgamma(2+s) = s*(1-Euler) + --------- * s - --------- * s + ... + * 2 3 + * + * where Euler = 0.5771... is the Euler constant, which is very + * close to 0.5. + * + * 3. For x>=8, we have + * lgamma(x)~(x-0.5)log(x)-x+0.5*log(2pi)+1/(12x)-1/(360x**3)+.... + * (better formula: + * lgamma(x)~(x-0.5)*(log(x)-1)-.5*(log(2pi)-1) + ...) + * Let z = 1/x, then we approximation + * f(z) = lgamma(x) - (x-0.5)(log(x)-1) + * by + * 3 5 11 + * w = w0 + w1*z + w2*z + w3*z + ... + w6*z + * where + * |w - f(z)| < 2**-58.74 + * + * 4. For negative x, since (G is gamma function) + * -x*G(-x)*G(x) = pi/sin(pi*x), + * we have + * G(x) = pi/(sin(pi*x)*(-x)*G(-x)) + * since G(-x) is positive, sign(G(x)) = sign(sin(pi*x)) for x<0 + * Hence, for x<0, signgam = sign(sin(pi*x)) and + * lgamma(x) = log(|Gamma(x)|) + * = log(pi/(|x*sin(pi*x)|)) - lgamma(-x); + * Note: one should avoid compute pi*(-x) directly in the + * computation of sin(pi*(-x)). + * + * 5. Special Cases + * lgamma(2+s) ~ s*(1-Euler) for tiny s + * lgamma(1)=lgamma(2)=0 + * lgamma(x) ~ -log(x) for tiny x + * lgamma(0) = lgamma(inf) = inf + * lgamma(-integer) = +-inf + * + */ + +#include "fdlibm.h" + +#ifdef __STDC__ +static const double +#else +static double +#endif +two52= 4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */ +half= 5.00000000000000000000e-01, /* 0x3FE00000, 0x00000000 */ +one = 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */ +pi = 3.14159265358979311600e+00, /* 0x400921FB, 0x54442D18 */ +a0 = 7.72156649015328655494e-02, /* 0x3FB3C467, 0xE37DB0C8 */ +a1 = 3.22467033424113591611e-01, /* 0x3FD4A34C, 0xC4A60FAD */ +a2 = 6.73523010531292681824e-02, /* 0x3FB13E00, 0x1A5562A7 */ +a3 = 2.05808084325167332806e-02, /* 0x3F951322, 0xAC92547B */ +a4 = 7.38555086081402883957e-03, /* 0x3F7E404F, 0xB68FEFE8 */ +a5 = 2.89051383673415629091e-03, /* 0x3F67ADD8, 0xCCB7926B */ +a6 = 1.19270763183362067845e-03, /* 0x3F538A94, 0x116F3F5D */ +a7 = 5.10069792153511336608e-04, /* 0x3F40B6C6, 0x89B99C00 */ +a8 = 2.20862790713908385557e-04, /* 0x3F2CF2EC, 0xED10E54D */ +a9 = 1.08011567247583939954e-04, /* 0x3F1C5088, 0x987DFB07 */ +a10 = 2.52144565451257326939e-05, /* 0x3EFA7074, 0x428CFA52 */ +a11 = 4.48640949618915160150e-05, /* 0x3F07858E, 0x90A45837 */ +tc = 1.46163214496836224576e+00, /* 0x3FF762D8, 0x6356BE3F */ +tf = -1.21486290535849611461e-01, /* 0xBFBF19B9, 0xBCC38A42 */ +/* tt = -(tail of tf) */ +tt = -3.63867699703950536541e-18, /* 0xBC50C7CA, 0xA48A971F */ +t0 = 4.83836122723810047042e-01, /* 0x3FDEF72B, 0xC8EE38A2 */ +t1 = -1.47587722994593911752e-01, /* 0xBFC2E427, 0x8DC6C509 */ +t2 = 6.46249402391333854778e-02, /* 0x3FB08B42, 0x94D5419B */ +t3 = -3.27885410759859649565e-02, /* 0xBFA0C9A8, 0xDF35B713 */ +t4 = 1.79706750811820387126e-02, /* 0x3F9266E7, 0x970AF9EC */ +t5 = -1.03142241298341437450e-02, /* 0xBF851F9F, 0xBA91EC6A */ +t6 = 6.10053870246291332635e-03, /* 0x3F78FCE0, 0xE370E344 */ +t7 = -3.68452016781138256760e-03, /* 0xBF6E2EFF, 0xB3E914D7 */ +t8 = 2.25964780900612472250e-03, /* 0x3F6282D3, 0x2E15C915 */ +t9 = -1.40346469989232843813e-03, /* 0xBF56FE8E, 0xBF2D1AF1 */ +t10 = 8.81081882437654011382e-04, /* 0x3F4CDF0C, 0xEF61A8E9 */ +t11 = -5.38595305356740546715e-04, /* 0xBF41A610, 0x9C73E0EC */ +t12 = 3.15632070903625950361e-04, /* 0x3F34AF6D, 0x6C0EBBF7 */ +t13 = -3.12754168375120860518e-04, /* 0xBF347F24, 0xECC38C38 */ +t14 = 3.35529192635519073543e-04, /* 0x3F35FD3E, 0xE8C2D3F4 */ +u0 = -7.72156649015328655494e-02, /* 0xBFB3C467, 0xE37DB0C8 */ +u1 = 6.32827064025093366517e-01, /* 0x3FE4401E, 0x8B005DFF */ +u2 = 1.45492250137234768737e+00, /* 0x3FF7475C, 0xD119BD6F */ +u3 = 9.77717527963372745603e-01, /* 0x3FEF4976, 0x44EA8450 */ +u4 = 2.28963728064692451092e-01, /* 0x3FCD4EAE, 0xF6010924 */ +u5 = 1.33810918536787660377e-02, /* 0x3F8B678B, 0xBF2BAB09 */ +v1 = 2.45597793713041134822e+00, /* 0x4003A5D7, 0xC2BD619C */ +v2 = 2.12848976379893395361e+00, /* 0x40010725, 0xA42B18F5 */ +v3 = 7.69285150456672783825e-01, /* 0x3FE89DFB, 0xE45050AF */ +v4 = 1.04222645593369134254e-01, /* 0x3FBAAE55, 0xD6537C88 */ +v5 = 3.21709242282423911810e-03, /* 0x3F6A5ABB, 0x57D0CF61 */ +s0 = -7.72156649015328655494e-02, /* 0xBFB3C467, 0xE37DB0C8 */ +s1 = 2.14982415960608852501e-01, /* 0x3FCB848B, 0x36E20878 */ +s2 = 3.25778796408930981787e-01, /* 0x3FD4D98F, 0x4F139F59 */ +s3 = 1.46350472652464452805e-01, /* 0x3FC2BB9C, 0xBEE5F2F7 */ +s4 = 2.66422703033638609560e-02, /* 0x3F9B481C, 0x7E939961 */ +s5 = 1.84028451407337715652e-03, /* 0x3F5E26B6, 0x7368F239 */ +s6 = 3.19475326584100867617e-05, /* 0x3F00BFEC, 0xDD17E945 */ +r1 = 1.39200533467621045958e+00, /* 0x3FF645A7, 0x62C4AB74 */ +r2 = 7.21935547567138069525e-01, /* 0x3FE71A18, 0x93D3DCDC */ +r3 = 1.71933865632803078993e-01, /* 0x3FC601ED, 0xCCFBDF27 */ +r4 = 1.86459191715652901344e-02, /* 0x3F9317EA, 0x742ED475 */ +r5 = 7.77942496381893596434e-04, /* 0x3F497DDA, 0xCA41A95B */ +r6 = 7.32668430744625636189e-06, /* 0x3EDEBAF7, 0xA5B38140 */ +w0 = 4.18938533204672725052e-01, /* 0x3FDACFE3, 0x90C97D69 */ +w1 = 8.33333333333329678849e-02, /* 0x3FB55555, 0x5555553B */ +w2 = -2.77777777728775536470e-03, /* 0xBF66C16C, 0x16B02E5C */ +w3 = 7.93650558643019558500e-04, /* 0x3F4A019F, 0x98CF38B6 */ +w4 = -5.95187557450339963135e-04, /* 0xBF4380CB, 0x8C0FE741 */ +w5 = 8.36339918996282139126e-04, /* 0x3F4B67BA, 0x4CDAD5D1 */ +w6 = -1.63092934096575273989e-03; /* 0xBF5AB89D, 0x0B9E43E4 */ + +static double zero= 0.00000000000000000000e+00; + +#ifdef __STDC__ + static double sin_pi(double x) +#else + static double sin_pi(x) + double x; +#endif +{ + fd_twoints u; + double y,z; + int n,ix; + + u.d = x; + ix = 0x7fffffff&__HI(u); + + if(ix<0x3fd00000) return __kernel_sin(pi*x,zero,0); + y = -x; /* x is assume negative */ + + /* + * argument reduction, make sure inexact flag not raised if input + * is an integer + */ + z = fd_floor(y); + if(z!=y) { /* inexact anyway */ + y *= 0.5; + y = 2.0*(y - fd_floor(y)); /* y = |x| mod 2.0 */ + n = (int) (y*4.0); + } else { + if(ix>=0x43400000) { + y = zero; n = 0; /* y must be even */ + } else { + if(ix<0x43300000) z = y+two52; /* exact */ + u.d = z; + n = __LO(u)&1; /* lower word of z */ + y = n; + n<<= 2; + } + } + switch (n) { + case 0: y = __kernel_sin(pi*y,zero,0); break; + case 1: + case 2: y = __kernel_cos(pi*(0.5-y),zero); break; + case 3: + case 4: y = __kernel_sin(pi*(one-y),zero,0); break; + case 5: + case 6: y = -__kernel_cos(pi*(y-1.5),zero); break; + default: y = __kernel_sin(pi*(y-2.0),zero,0); break; + } + return -y; +} + + +#ifdef __STDC__ + double __ieee754_lgamma_r(double x, int *signgamp) +#else + double __ieee754_lgamma_r(x,signgamp) + double x; int *signgamp; +#endif +{ + fd_twoints u; + double t,y,z,nadj,p,p1,p2,p3,q,r,w; + int i,hx,lx,ix; + + u.d = x; + hx = __HI(u); + lx = __LO(u); + + /* purge off +-inf, NaN, +-0, and negative arguments */ + *signgamp = 1; + ix = hx&0x7fffffff; + if(ix>=0x7ff00000) return x*x; + if((ix|lx)==0) return one/zero; + if(ix<0x3b900000) { /* |x|<2**-70, return -log(|x|) */ + if(hx<0) { + *signgamp = -1; + return -__ieee754_log(-x); + } else return -__ieee754_log(x); + } + if(hx<0) { + if(ix>=0x43300000) /* |x|>=2**52, must be -integer */ + return one/zero; + t = sin_pi(x); + if(t==zero) return one/zero; /* -integer */ + nadj = __ieee754_log(pi/fd_fabs(t*x)); + if(t=0x3FE76944) {y = one-x; i= 0;} + else if(ix>=0x3FCDA661) {y= x-(tc-one); i=1;} + else {y = x; i=2;} + } else { + r = zero; + if(ix>=0x3FFBB4C3) {y=2.0-x;i=0;} /* [1.7316,2] */ + else if(ix>=0x3FF3B4C4) {y=x-tc;i=1;} /* [1.23,1.73] */ + else {y=x-one;i=2;} + } + switch(i) { + case 0: + z = y*y; + p1 = a0+z*(a2+z*(a4+z*(a6+z*(a8+z*a10)))); + p2 = z*(a1+z*(a3+z*(a5+z*(a7+z*(a9+z*a11))))); + p = y*p1+p2; + r += (p-0.5*y); break; + case 1: + z = y*y; + w = z*y; + p1 = t0+w*(t3+w*(t6+w*(t9 +w*t12))); /* parallel comp */ + p2 = t1+w*(t4+w*(t7+w*(t10+w*t13))); + p3 = t2+w*(t5+w*(t8+w*(t11+w*t14))); + p = z*p1-(tt-w*(p2+y*p3)); + r += (tf + p); break; + case 2: + p1 = y*(u0+y*(u1+y*(u2+y*(u3+y*(u4+y*u5))))); + p2 = one+y*(v1+y*(v2+y*(v3+y*(v4+y*v5)))); + r += (-0.5*y + p1/p2); + } + } + else if(ix<0x40200000) { /* x < 8.0 */ + i = (int)x; + t = zero; + y = x-(double)i; + p = y*(s0+y*(s1+y*(s2+y*(s3+y*(s4+y*(s5+y*s6)))))); + q = one+y*(r1+y*(r2+y*(r3+y*(r4+y*(r5+y*r6))))); + r = half*y+p/q; + z = one; /* lgamma(1+s) = log(s) + lgamma(s) */ + switch(i) { + case 7: z *= (y+6.0); /* FALLTHRU */ + case 6: z *= (y+5.0); /* FALLTHRU */ + case 5: z *= (y+4.0); /* FALLTHRU */ + case 4: z *= (y+3.0); /* FALLTHRU */ + case 3: z *= (y+2.0); /* FALLTHRU */ + r += __ieee754_log(z); break; + } + /* 8.0 <= x < 2**58 */ + } else if (ix < 0x43900000) { + t = __ieee754_log(x); + z = one/x; + y = z*z; + w = w0+z*(w1+y*(w2+y*(w3+y*(w4+y*(w5+y*w6))))); + r = (x-half)*(t-one)+w; + } else + /* 2**58 <= x <= inf */ + r = x*(__ieee754_log(x)-one); + if(hx<0) r = nadj - r; + return r; +} diff --git a/src/dom/js/fdlibm/e_log.c b/src/dom/js/fdlibm/e_log.c new file mode 100644 index 000000000..8645d6efd --- /dev/null +++ b/src/dom/js/fdlibm/e_log.c @@ -0,0 +1,184 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Sun Microsystems, Inc. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* @(#)e_log.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* __ieee754_log(x) + * Return the logrithm of x + * + * Method : + * 1. Argument Reduction: find k and f such that + * x = 2^k * (1+f), + * where sqrt(2)/2 < 1+f < sqrt(2) . + * + * 2. Approximation of log(1+f). + * Let s = f/(2+f) ; based on log(1+f) = log(1+s) - log(1-s) + * = 2s + 2/3 s**3 + 2/5 s**5 + ....., + * = 2s + s*R + * We use a special Reme algorithm on [0,0.1716] to generate + * a polynomial of degree 14 to approximate R The maximum error + * of this polynomial approximation is bounded by 2**-58.45. In + * other words, + * 2 4 6 8 10 12 14 + * R(z) ~ Lg1*s +Lg2*s +Lg3*s +Lg4*s +Lg5*s +Lg6*s +Lg7*s + * (the values of Lg1 to Lg7 are listed in the program) + * and + * | 2 14 | -58.45 + * | Lg1*s +...+Lg7*s - R(z) | <= 2 + * | | + * Note that 2s = f - s*f = f - hfsq + s*hfsq, where hfsq = f*f/2. + * In order to guarantee error in log below 1ulp, we compute log + * by + * log(1+f) = f - s*(f - R) (if f is not too large) + * log(1+f) = f - (hfsq - s*(hfsq+R)). (better accuracy) + * + * 3. Finally, log(x) = k*ln2 + log(1+f). + * = k*ln2_hi+(f-(hfsq-(s*(hfsq+R)+k*ln2_lo))) + * Here ln2 is split into two floating point number: + * ln2_hi + ln2_lo, + * where n*ln2_hi is always exact for |n| < 2000. + * + * Special cases: + * log(x) is NaN with signal if x < 0 (including -INF) ; + * log(+INF) is +INF; log(0) is -INF with signal; + * log(NaN) is that NaN with no signal. + * + * Accuracy: + * according to an error analysis, the error is always less than + * 1 ulp (unit in the last place). + * + * Constants: + * The hexadecimal values are the intended ones for the following + * constants. The decimal values may be used, provided that the + * compiler will convert from decimal to binary accurately enough + * to produce the hexadecimal values shown. + */ + +#include "fdlibm.h" + +#ifdef __STDC__ +static const double +#else +static double +#endif +ln2_hi = 6.93147180369123816490e-01, /* 3fe62e42 fee00000 */ +ln2_lo = 1.90821492927058770002e-10, /* 3dea39ef 35793c76 */ +two54 = 1.80143985094819840000e+16, /* 43500000 00000000 */ +Lg1 = 6.666666666666735130e-01, /* 3FE55555 55555593 */ +Lg2 = 3.999999999940941908e-01, /* 3FD99999 9997FA04 */ +Lg3 = 2.857142874366239149e-01, /* 3FD24924 94229359 */ +Lg4 = 2.222219843214978396e-01, /* 3FCC71C5 1D8E78AF */ +Lg5 = 1.818357216161805012e-01, /* 3FC74664 96CB03DE */ +Lg6 = 1.531383769920937332e-01, /* 3FC39A09 D078C69F */ +Lg7 = 1.479819860511658591e-01; /* 3FC2F112 DF3E5244 */ + +static double zero = 0.0; + +#ifdef __STDC__ + double __ieee754_log(double x) +#else + double __ieee754_log(x) + double x; +#endif +{ + fd_twoints u; + double hfsq,f,s,z,R,w,t1,t2,dk; + int k,hx,i,j; + unsigned lx; + + u.d = x; + hx = __HI(u); /* high word of x */ + lx = __LO(u); /* low word of x */ + + k=0; + if (hx < 0x00100000) { /* x < 2**-1022 */ + if (((hx&0x7fffffff)|lx)==0) + return -two54/zero; /* log(+-0)=-inf */ + if (hx<0) return (x-x)/zero; /* log(-#) = NaN */ + k -= 54; x *= two54; /* subnormal number, scale up x */ + u.d = x; + hx = __HI(u); /* high word of x */ + } + if (hx >= 0x7ff00000) return x+x; + k += (hx>>20)-1023; + hx &= 0x000fffff; + i = (hx+0x95f64)&0x100000; + u.d = x; + __HI(u) = hx|(i^0x3ff00000); /* normalize x or x/2 */ + x = u.d; + k += (i>>20); + f = x-1.0; + if((0x000fffff&(2+hx))<3) { /* |f| < 2**-20 */ + if(f==zero) { + if(k==0) return zero; else {dk=(double)k; + return dk*ln2_hi+dk*ln2_lo;} + } + R = f*f*(0.5-0.33333333333333333*f); + if(k==0) return f-R; else {dk=(double)k; + return dk*ln2_hi-((R-dk*ln2_lo)-f);} + } + s = f/(2.0+f); + dk = (double)k; + z = s*s; + i = hx-0x6147a; + w = z*z; + j = 0x6b851-hx; + t1= w*(Lg2+w*(Lg4+w*Lg6)); + t2= z*(Lg1+w*(Lg3+w*(Lg5+w*Lg7))); + i |= j; + R = t2+t1; + if(i>0) { + hfsq=0.5*f*f; + if(k==0) return f-(hfsq-s*(hfsq+R)); else + return dk*ln2_hi-((hfsq-(s*(hfsq+R)+dk*ln2_lo))-f); + } else { + if(k==0) return f-s*(f-R); else + return dk*ln2_hi-((s*(f-R)-dk*ln2_lo)-f); + } +} diff --git a/src/dom/js/fdlibm/e_log10.c b/src/dom/js/fdlibm/e_log10.c new file mode 100644 index 000000000..5f88f4b4c --- /dev/null +++ b/src/dom/js/fdlibm/e_log10.c @@ -0,0 +1,134 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Sun Microsystems, Inc. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* @(#)e_log10.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* __ieee754_log10(x) + * Return the base 10 logarithm of x + * + * Method : + * Let log10_2hi = leading 40 bits of log10(2) and + * log10_2lo = log10(2) - log10_2hi, + * ivln10 = 1/log(10) rounded. + * Then + * n = ilogb(x), + * if(n<0) n = n+1; + * x = scalbn(x,-n); + * log10(x) := n*log10_2hi + (n*log10_2lo + ivln10*log(x)) + * + * Note 1: + * To guarantee log10(10**n)=n, where 10**n is normal, the rounding + * mode must set to Round-to-Nearest. + * Note 2: + * [1/log(10)] rounded to 53 bits has error .198 ulps; + * log10 is monotonic at all binary break points. + * + * Special cases: + * log10(x) is NaN with signal if x < 0; + * log10(+INF) is +INF with no signal; log10(0) is -INF with signal; + * log10(NaN) is that NaN with no signal; + * log10(10**N) = N for N=0,1,...,22. + * + * Constants: + * The hexadecimal values are the intended ones for the following constants. + * The decimal values may be used, provided that the compiler will convert + * from decimal to binary accurately enough to produce the hexadecimal values + * shown. + */ + +#include "fdlibm.h" + +#ifdef __STDC__ +static const double +#else +static double +#endif +two54 = 1.80143985094819840000e+16, /* 0x43500000, 0x00000000 */ +ivln10 = 4.34294481903251816668e-01, /* 0x3FDBCB7B, 0x1526E50E */ +log10_2hi = 3.01029995663611771306e-01, /* 0x3FD34413, 0x509F6000 */ +log10_2lo = 3.69423907715893078616e-13; /* 0x3D59FEF3, 0x11F12B36 */ + +static double zero = 0.0; + +#ifdef __STDC__ + double __ieee754_log10(double x) +#else + double __ieee754_log10(x) + double x; +#endif +{ + fd_twoints u; + double y,z; + int i,k,hx; + unsigned lx; + + u.d = x; + hx = __HI(u); /* high word of x */ + lx = __LO(u); /* low word of x */ + + k=0; + if (hx < 0x00100000) { /* x < 2**-1022 */ + if (((hx&0x7fffffff)|lx)==0) + return -two54/zero; /* log(+-0)=-inf */ + if (hx<0) return (x-x)/zero; /* log(-#) = NaN */ + k -= 54; x *= two54; /* subnormal number, scale up x */ + u.d = x; + hx = __HI(u); /* high word of x */ + } + if (hx >= 0x7ff00000) return x+x; + k += (hx>>20)-1023; + i = ((unsigned)k&0x80000000)>>31; + hx = (hx&0x000fffff)|((0x3ff-i)<<20); + y = (double)(k+i); + u.d = x; + __HI(u) = hx; + x = u.d; + z = y*log10_2lo + ivln10*__ieee754_log(x); + return z+y*log10_2hi; +} diff --git a/src/dom/js/fdlibm/e_pow.c b/src/dom/js/fdlibm/e_pow.c new file mode 100644 index 000000000..18c8d0695 --- /dev/null +++ b/src/dom/js/fdlibm/e_pow.c @@ -0,0 +1,386 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Sun Microsystems, Inc. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* @(#)e_pow.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* __ieee754_pow(x,y) return x**y + * + * n + * Method: Let x = 2 * (1+f) + * 1. Compute and return log2(x) in two pieces: + * log2(x) = w1 + w2, + * where w1 has 53-24 = 29 bit trailing zeros. + * 2. Perform y*log2(x) = n+y' by simulating muti-precision + * arithmetic, where |y'|<=0.5. + * 3. Return x**y = 2**n*exp(y'*log2) + * + * Special cases: + * 1. (anything) ** 0 is 1 + * 2. (anything) ** 1 is itself + * 3. (anything) ** NAN is NAN + * 4. NAN ** (anything except 0) is NAN + * 5. +-(|x| > 1) ** +INF is +INF + * 6. +-(|x| > 1) ** -INF is +0 + * 7. +-(|x| < 1) ** +INF is +0 + * 8. +-(|x| < 1) ** -INF is +INF + * 9. +-1 ** +-INF is NAN + * 10. +0 ** (+anything except 0, NAN) is +0 + * 11. -0 ** (+anything except 0, NAN, odd integer) is +0 + * 12. +0 ** (-anything except 0, NAN) is +INF + * 13. -0 ** (-anything except 0, NAN, odd integer) is +INF + * 14. -0 ** (odd integer) = -( +0 ** (odd integer) ) + * 15. +INF ** (+anything except 0,NAN) is +INF + * 16. +INF ** (-anything except 0,NAN) is +0 + * 17. -INF ** (anything) = -0 ** (-anything) + * 18. (-anything) ** (integer) is (-1)**(integer)*(+anything**integer) + * 19. (-anything except 0 and inf) ** (non-integer) is NAN + * + * Accuracy: + * pow(x,y) returns x**y nearly rounded. In particular + * pow(integer,integer) + * always returns the correct integer provided it is + * representable. + * + * Constants : + * The hexadecimal values are the intended ones for the following + * constants. The decimal values may be used, provided that the + * compiler will convert from decimal to binary accurately enough + * to produce the hexadecimal values shown. + */ + +#include "fdlibm.h" + +#if defined(_MSC_VER) +/* Microsoft Compiler */ +#pragma warning( disable : 4723 ) /* disables potential divide by 0 warning */ +#endif + +#ifdef __STDC__ +static const double +#else +static double +#endif +bp[] = {1.0, 1.5,}, +dp_h[] = { 0.0, 5.84962487220764160156e-01,}, /* 0x3FE2B803, 0x40000000 */ +dp_l[] = { 0.0, 1.35003920212974897128e-08,}, /* 0x3E4CFDEB, 0x43CFD006 */ +zero = 0.0, +one = 1.0, +two = 2.0, +two53 = 9007199254740992.0, /* 0x43400000, 0x00000000 */ +really_big = 1.0e300, +tiny = 1.0e-300, + /* poly coefs for (3/2)*(log(x)-2s-2/3*s**3 */ +L1 = 5.99999999999994648725e-01, /* 0x3FE33333, 0x33333303 */ +L2 = 4.28571428578550184252e-01, /* 0x3FDB6DB6, 0xDB6FABFF */ +L3 = 3.33333329818377432918e-01, /* 0x3FD55555, 0x518F264D */ +L4 = 2.72728123808534006489e-01, /* 0x3FD17460, 0xA91D4101 */ +L5 = 2.30660745775561754067e-01, /* 0x3FCD864A, 0x93C9DB65 */ +L6 = 2.06975017800338417784e-01, /* 0x3FCA7E28, 0x4A454EEF */ +P1 = 1.66666666666666019037e-01, /* 0x3FC55555, 0x5555553E */ +P2 = -2.77777777770155933842e-03, /* 0xBF66C16C, 0x16BEBD93 */ +P3 = 6.61375632143793436117e-05, /* 0x3F11566A, 0xAF25DE2C */ +P4 = -1.65339022054652515390e-06, /* 0xBEBBBD41, 0xC5D26BF1 */ +P5 = 4.13813679705723846039e-08, /* 0x3E663769, 0x72BEA4D0 */ +lg2 = 6.93147180559945286227e-01, /* 0x3FE62E42, 0xFEFA39EF */ +lg2_h = 6.93147182464599609375e-01, /* 0x3FE62E43, 0x00000000 */ +lg2_l = -1.90465429995776804525e-09, /* 0xBE205C61, 0x0CA86C39 */ +ovt = 8.0085662595372944372e-0017, /* -(1024-log2(ovfl+.5ulp)) */ +cp = 9.61796693925975554329e-01, /* 0x3FEEC709, 0xDC3A03FD =2/(3ln2) */ +cp_h = 9.61796700954437255859e-01, /* 0x3FEEC709, 0xE0000000 =(float)cp */ +cp_l = -7.02846165095275826516e-09, /* 0xBE3E2FE0, 0x145B01F5 =tail of cp_h*/ +ivln2 = 1.44269504088896338700e+00, /* 0x3FF71547, 0x652B82FE =1/ln2 */ +ivln2_h = 1.44269502162933349609e+00, /* 0x3FF71547, 0x60000000 =24b 1/ln2*/ +ivln2_l = 1.92596299112661746887e-08; /* 0x3E54AE0B, 0xF85DDF44 =1/ln2 tail*/ + +#ifdef __STDC__ + double __ieee754_pow(double x, double y) +#else + double __ieee754_pow(x,y) + double x, y; +#endif +{ + fd_twoints ux, uy, uz; + double y1,t1,p_h,t,z,ax; + double z_h,z_l,p_l; + double t2,r,s,u,v,w; + int i,j,k,yisint,n; + int hx,hy,ix,iy; + unsigned lx,ly; + + ux.d = x; uy.d = y; + hx = __HI(ux); lx = __LO(ux); + hy = __HI(uy); ly = __LO(uy); + ix = hx&0x7fffffff; iy = hy&0x7fffffff; + + /* y==zero: x**0 = 1 */ + if((iy|ly)==0) return one; + + /* +-NaN return x+y */ + if(ix > 0x7ff00000 || ((ix==0x7ff00000)&&(lx!=0)) || + iy > 0x7ff00000 || ((iy==0x7ff00000)&&(ly!=0))) + return x+y; + + /* determine if y is an odd int when x < 0 + * yisint = 0 ... y is not an integer + * yisint = 1 ... y is an odd int + * yisint = 2 ... y is an even int + */ + yisint = 0; + if(hx<0) { + if(iy>=0x43400000) yisint = 2; /* even integer y */ + else if(iy>=0x3ff00000) { + k = (iy>>20)-0x3ff; /* exponent */ + if(k>20) { + j = ly>>(52-k); + if((j<<(52-k))==(int)ly) yisint = 2-(j&1); + } else if(ly==0) { + j = iy>>(20-k); + if((j<<(20-k))==iy) yisint = 2-(j&1); + } + } + } + + /* special value of y */ + if(ly==0) { + if (iy==0x7ff00000) { /* y is +-inf */ + if(((ix-0x3ff00000)|lx)==0) +#ifdef _WIN32 +/* VC++ optimizer reduces y - y to 0 */ + return y / y; +#else + return y - y; /* inf**+-1 is NaN */ +#endif + else if (ix >= 0x3ff00000)/* (|x|>1)**+-inf = inf,0 */ + return (hy>=0)? y: zero; + else /* (|x|<1)**-,+inf = inf,0 */ + return (hy<0)?-y: zero; + } + if(iy==0x3ff00000) { /* y is +-1 */ + if(hy<0) return one/x; else return x; + } + if(hy==0x40000000) return x*x; /* y is 2 */ + if(hy==0x3fe00000) { /* y is 0.5 */ + if(hx>=0) /* x >= +0 */ + return fd_sqrt(x); + } + } + + ax = fd_fabs(x); + /* special value of x */ + if(lx==0) { + if(ix==0x7ff00000||ix==0||ix==0x3ff00000){ + z = ax; /*x is +-0,+-inf,+-1*/ + if(hy<0) z = one/z; /* z = (1/|x|) */ + if(hx<0) { + if(((ix-0x3ff00000)|yisint)==0) { + z = (z-z)/(z-z); /* (-1)**non-int is NaN */ + } else if(yisint==1) { +#ifdef HPUX + uz.d = z; + __HI(uz) ^= 1<<31; /* some HPUXes cannot negate 0.. */ + z = uz.d; +#else + z = -z; /* (x<0)**odd = -(|x|**odd) */ +#endif + } + } + return z; + } + } + + /* (x<0)**(non-int) is NaN */ + if((((hx>>31)+1)|yisint)==0) return (x-x)/(x-x); + + /* |y| is really_big */ + if(iy>0x41e00000) { /* if |y| > 2**31 */ + if(iy>0x43f00000){ /* if |y| > 2**64, must o/uflow */ + if(ix<=0x3fefffff) return (hy<0)? really_big*really_big:tiny*tiny; + if(ix>=0x3ff00000) return (hy>0)? really_big*really_big:tiny*tiny; + } + /* over/underflow if x is not close to one */ + if(ix<0x3fefffff) return (hy<0)? really_big*really_big:tiny*tiny; + if(ix>0x3ff00000) return (hy>0)? really_big*really_big:tiny*tiny; + /* now |1-x| is tiny <= 2**-20, suffice to compute + log(x) by x-x^2/2+x^3/3-x^4/4 */ + t = x-1; /* t has 20 trailing zeros */ + w = (t*t)*(0.5-t*(0.3333333333333333333333-t*0.25)); + u = ivln2_h*t; /* ivln2_h has 21 sig. bits */ + v = t*ivln2_l-w*ivln2; + t1 = u+v; + uz.d = t1; + __LO(uz) = 0; + t1 = uz.d; + t2 = v-(t1-u); + } else { + double s_h,t_h; + double s2,s_l,t_l; + n = 0; + /* take care subnormal number */ + if(ix<0x00100000) + {ax *= two53; n -= 53; uz.d = ax; ix = __HI(uz); } + n += ((ix)>>20)-0x3ff; + j = ix&0x000fffff; + /* determine interval */ + ix = j|0x3ff00000; /* normalize ix */ + if(j<=0x3988E) k=0; /* |x|>1)|0x20000000)+0x00080000+(k<<18); + t_h = uz.d; + t_l = ax - (t_h-bp[k]); + s_l = v*((u-s_h*t_h)-s_h*t_l); + /* compute log(ax) */ + s2 = s*s; + r = s2*s2*(L1+s2*(L2+s2*(L3+s2*(L4+s2*(L5+s2*L6))))); + r += s_l*(s_h+s); + s2 = s_h*s_h; + t_h = 3.0+s2+r; + uz.d = t_h; + __LO(uz) = 0; + t_h = uz.d; + t_l = r-((t_h-3.0)-s2); + /* u+v = s*(1+...) */ + u = s_h*t_h; + v = s_l*t_h+t_l*s; + /* 2/(3log2)*(s+...) */ + p_h = u+v; + uz.d = p_h; + __LO(uz) = 0; + p_h = uz.d; + p_l = v-(p_h-u); + z_h = cp_h*p_h; /* cp_h+cp_l = 2/(3*log2) */ + z_l = cp_l*p_h+p_l*cp+dp_l[k]; + /* log2(ax) = (s+..)*2/(3*log2) = n + dp_h + z_h + z_l */ + t = (double)n; + t1 = (((z_h+z_l)+dp_h[k])+t); + uz.d = t1; + __LO(uz) = 0; + t1 = uz.d; + t2 = z_l-(((t1-t)-dp_h[k])-z_h); + } + + s = one; /* s (sign of result -ve**odd) = -1 else = 1 */ + if((((hx>>31)+1)|(yisint-1))==0) s = -one;/* (-ve)**(odd int) */ + + /* split up y into y1+y2 and compute (y1+y2)*(t1+t2) */ + y1 = y; + uy.d = y1; + __LO(uy) = 0; + y1 = uy.d; + p_l = (y-y1)*t1+y*t2; + p_h = y1*t1; + z = p_l+p_h; + uz.d = z; + j = __HI(uz); + i = __LO(uz); + + if (j>=0x40900000) { /* z >= 1024 */ + if(((j-0x40900000)|i)!=0) /* if z > 1024 */ + return s*really_big*really_big; /* overflow */ + else { + if(p_l+ovt>z-p_h) return s*really_big*really_big; /* overflow */ + } + } else if((j&0x7fffffff)>=0x4090cc00 ) { /* z <= -1075 */ + if(((j-0xc090cc00)|i)!=0) /* z < -1075 */ + return s*tiny*tiny; /* underflow */ + else { + if(p_l<=z-p_h) return s*tiny*tiny; /* underflow */ + } + } + /* + * compute 2**(p_h+p_l) + */ + i = j&0x7fffffff; + k = (i>>20)-0x3ff; + n = 0; + if(i>0x3fe00000) { /* if |z| > 0.5, set n = [z+0.5] */ + n = j+(0x00100000>>(k+1)); + k = ((n&0x7fffffff)>>20)-0x3ff; /* new k for n */ + t = zero; + uz.d = t; + __HI(uz) = (n&~(0x000fffff>>k)); + t = uz.d; + n = ((n&0x000fffff)|0x00100000)>>(20-k); + if(j<0) n = -n; + p_h -= t; + } + t = p_l+p_h; + uz.d = t; + __LO(uz) = 0; + t = uz.d; + u = t*lg2_h; + v = (p_l-(t-p_h))*lg2+t*lg2_l; + z = u+v; + w = v-(z-u); + t = z*z; + t1 = z - t*(P1+t*(P2+t*(P3+t*(P4+t*P5)))); + r = (z*t1)/(t1-two)-(w+z*w); + z = one-(r-z); + uz.d = z; + j = __HI(uz); + j += (n<<20); + if((j>>20)<=0) z = fd_scalbn(z,n); /* subnormal output */ + else { uz.d = z; __HI(uz) += (n<<20); z = uz.d; } + return s*z; +} diff --git a/src/dom/js/fdlibm/e_rem_pio2.c b/src/dom/js/fdlibm/e_rem_pio2.c new file mode 100644 index 000000000..6f9423551 --- /dev/null +++ b/src/dom/js/fdlibm/e_rem_pio2.c @@ -0,0 +1,221 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Sun Microsystems, Inc. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* @(#)e_rem_pio2.c 1.4 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + * + */ + +/* __ieee754_rem_pio2(x,y) + * + * return the remainder of x rem pi/2 in y[0]+y[1] + * use __kernel_rem_pio2() + */ + +#include "fdlibm.h" + +/* + * Table of constants for 2/pi, 396 Hex digits (476 decimal) of 2/pi + */ +#ifdef __STDC__ +static const int two_over_pi[] = { +#else +static int two_over_pi[] = { +#endif +0xA2F983, 0x6E4E44, 0x1529FC, 0x2757D1, 0xF534DD, 0xC0DB62, +0x95993C, 0x439041, 0xFE5163, 0xABDEBB, 0xC561B7, 0x246E3A, +0x424DD2, 0xE00649, 0x2EEA09, 0xD1921C, 0xFE1DEB, 0x1CB129, +0xA73EE8, 0x8235F5, 0x2EBB44, 0x84E99C, 0x7026B4, 0x5F7E41, +0x3991D6, 0x398353, 0x39F49C, 0x845F8B, 0xBDF928, 0x3B1FF8, +0x97FFDE, 0x05980F, 0xEF2F11, 0x8B5A0A, 0x6D1F6D, 0x367ECF, +0x27CB09, 0xB74F46, 0x3F669E, 0x5FEA2D, 0x7527BA, 0xC7EBE5, +0xF17B3D, 0x0739F7, 0x8A5292, 0xEA6BFB, 0x5FB11F, 0x8D5D08, +0x560330, 0x46FC7B, 0x6BABF0, 0xCFBC20, 0x9AF436, 0x1DA9E3, +0x91615E, 0xE61B08, 0x659985, 0x5F14A0, 0x68408D, 0xFFD880, +0x4D7327, 0x310606, 0x1556CA, 0x73A8C9, 0x60E27B, 0xC08C6B, +}; + +#ifdef __STDC__ +static const int npio2_hw[] = { +#else +static int npio2_hw[] = { +#endif +0x3FF921FB, 0x400921FB, 0x4012D97C, 0x401921FB, 0x401F6A7A, 0x4022D97C, +0x4025FDBB, 0x402921FB, 0x402C463A, 0x402F6A7A, 0x4031475C, 0x4032D97C, +0x40346B9C, 0x4035FDBB, 0x40378FDB, 0x403921FB, 0x403AB41B, 0x403C463A, +0x403DD85A, 0x403F6A7A, 0x40407E4C, 0x4041475C, 0x4042106C, 0x4042D97C, +0x4043A28C, 0x40446B9C, 0x404534AC, 0x4045FDBB, 0x4046C6CB, 0x40478FDB, +0x404858EB, 0x404921FB, +}; + +/* + * invpio2: 53 bits of 2/pi + * pio2_1: first 33 bit of pi/2 + * pio2_1t: pi/2 - pio2_1 + * pio2_2: second 33 bit of pi/2 + * pio2_2t: pi/2 - (pio2_1+pio2_2) + * pio2_3: third 33 bit of pi/2 + * pio2_3t: pi/2 - (pio2_1+pio2_2+pio2_3) + */ + +#ifdef __STDC__ +static const double +#else +static double +#endif +zero = 0.00000000000000000000e+00, /* 0x00000000, 0x00000000 */ +half = 5.00000000000000000000e-01, /* 0x3FE00000, 0x00000000 */ +two24 = 1.67772160000000000000e+07, /* 0x41700000, 0x00000000 */ +invpio2 = 6.36619772367581382433e-01, /* 0x3FE45F30, 0x6DC9C883 */ +pio2_1 = 1.57079632673412561417e+00, /* 0x3FF921FB, 0x54400000 */ +pio2_1t = 6.07710050650619224932e-11, /* 0x3DD0B461, 0x1A626331 */ +pio2_2 = 6.07710050630396597660e-11, /* 0x3DD0B461, 0x1A600000 */ +pio2_2t = 2.02226624879595063154e-21, /* 0x3BA3198A, 0x2E037073 */ +pio2_3 = 2.02226624871116645580e-21, /* 0x3BA3198A, 0x2E000000 */ +pio2_3t = 8.47842766036889956997e-32; /* 0x397B839A, 0x252049C1 */ + +#ifdef __STDC__ + int __ieee754_rem_pio2(double x, double *y) +#else + int __ieee754_rem_pio2(x,y) + double x,y[]; +#endif +{ + fd_twoints u, ux, uz; + double z,w,t,r,fn; + double tx[3]; + int e0,i,j,nx,n,ix,hx; + + u.d = x; + hx = __HI(u); /* high word of x */ + ix = hx&0x7fffffff; + if(ix<=0x3fe921fb) /* |x| ~<= pi/4 , no need for reduction */ + {y[0] = x; y[1] = 0; return 0;} + if(ix<0x4002d97c) { /* |x| < 3pi/4, special case with n=+-1 */ + if(hx>0) { + z = x - pio2_1; + if(ix!=0x3ff921fb) { /* 33+53 bit pi is good enough */ + y[0] = z - pio2_1t; + y[1] = (z-y[0])-pio2_1t; + } else { /* near pi/2, use 33+33+53 bit pi */ + z -= pio2_2; + y[0] = z - pio2_2t; + y[1] = (z-y[0])-pio2_2t; + } + return 1; + } else { /* negative x */ + z = x + pio2_1; + if(ix!=0x3ff921fb) { /* 33+53 bit pi is good enough */ + y[0] = z + pio2_1t; + y[1] = (z-y[0])+pio2_1t; + } else { /* near pi/2, use 33+33+53 bit pi */ + z += pio2_2; + y[0] = z + pio2_2t; + y[1] = (z-y[0])+pio2_2t; + } + return -1; + } + } + if(ix<=0x413921fb) { /* |x| ~<= 2^19*(pi/2), medium size */ + t = fd_fabs(x); + n = (int) (t*invpio2+half); + fn = (double)n; + r = t-fn*pio2_1; + w = fn*pio2_1t; /* 1st round good to 85 bit */ + if(n<32&&ix!=npio2_hw[n-1]) { + y[0] = r-w; /* quick check no cancellation */ + } else { + j = ix>>20; + y[0] = r-w; + u.d = y[0]; + i = j-(((__HI(u))>>20)&0x7ff); + if(i>16) { /* 2nd iteration needed, good to 118 */ + t = r; + w = fn*pio2_2; + r = t-w; + w = fn*pio2_2t-((t-r)-w); + y[0] = r-w; + u.d = y[0]; + i = j-(((__HI(u))>>20)&0x7ff); + if(i>49) { /* 3rd iteration need, 151 bits acc */ + t = r; /* will cover all possible cases */ + w = fn*pio2_3; + r = t-w; + w = fn*pio2_3t-((t-r)-w); + y[0] = r-w; + } + } + } + y[1] = (r-y[0])-w; + if(hx<0) {y[0] = -y[0]; y[1] = -y[1]; return -n;} + else return n; + } + /* + * all other (large) arguments + */ + if(ix>=0x7ff00000) { /* x is inf or NaN */ + y[0]=y[1]=x-x; return 0; + } + /* set z = scalbn(|x|,ilogb(x)-23) */ + ux.d = x; uz.d = z; + __LO(uz) = __LO(ux); + z = uz.d; + e0 = (ix>>20)-1046; /* e0 = ilogb(z)-23; */ + uz.d = z; + __HI(uz) = ix - (e0<<20); + z = uz.d; + for(i=0;i<2;i++) { + tx[i] = (double)((int)(z)); + z = (z-tx[i])*two24; + } + tx[2] = z; + nx = 3; + while(tx[nx-1]==zero) nx--; /* skip zero term */ + n = __kernel_rem_pio2(tx,y,e0,nx,2,two_over_pi); + if(hx<0) {y[0] = -y[0]; y[1] = -y[1]; return -n;} + return n; +} diff --git a/src/dom/js/fdlibm/e_remainder.c b/src/dom/js/fdlibm/e_remainder.c new file mode 100644 index 000000000..de40f0c2a --- /dev/null +++ b/src/dom/js/fdlibm/e_remainder.c @@ -0,0 +1,120 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Sun Microsystems, Inc. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* @(#)e_remainder.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* __ieee754_remainder(x,p) + * Return : + * returns x REM p = x - [x/p]*p as if in infinite + * precise arithmetic, where [x/p] is the (infinite bit) + * integer nearest x/p (in half way case choose the even one). + * Method : + * Based on fmod() return x-[x/p]chopped*p exactlp. + */ + +#include "fdlibm.h" + +#ifdef __STDC__ +static const double zero = 0.0; +#else +static double zero = 0.0; +#endif + + +#ifdef __STDC__ + double __ieee754_remainder(double x, double p) +#else + double __ieee754_remainder(x,p) + double x,p; +#endif +{ + fd_twoints u; + int hx,hp; + unsigned sx,lx,lp; + double p_half; + + u.d = x; + hx = __HI(u); /* high word of x */ + lx = __LO(u); /* low word of x */ + u.d = p; + hp = __HI(u); /* high word of p */ + lp = __LO(u); /* low word of p */ + sx = hx&0x80000000; + hp &= 0x7fffffff; + hx &= 0x7fffffff; + + /* purge off exception values */ + if((hp|lp)==0) return (x*p)/(x*p); /* p = 0 */ + if((hx>=0x7ff00000)|| /* x not finite */ + ((hp>=0x7ff00000)&& /* p is NaN */ + (((hp-0x7ff00000)|lp)!=0))) + return (x*p)/(x*p); + + + if (hp<=0x7fdfffff) x = __ieee754_fmod(x,p+p); /* now x < 2p */ + if (((hx-hp)|(lx-lp))==0) return zero*x; + x = fd_fabs(x); + p = fd_fabs(p); + if (hp<0x00200000) { + if(x+x>p) { + x-=p; + if(x+x>=p) x -= p; + } + } else { + p_half = 0.5*p; + if(x>p_half) { + x-=p; + if(x>=p_half) x -= p; + } + } + u.d = x; + __HI(u) ^= sx; + x = u.d; + return x; +} diff --git a/src/dom/js/fdlibm/e_scalb.c b/src/dom/js/fdlibm/e_scalb.c new file mode 100644 index 000000000..621704ea0 --- /dev/null +++ b/src/dom/js/fdlibm/e_scalb.c @@ -0,0 +1,89 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Sun Microsystems, Inc. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* @(#)e_scalb.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * __ieee754_scalb(x, fn) is provide for + * passing various standard test suite. One + * should use scalbn() instead. + */ + +#include "fdlibm.h" + +#ifdef _SCALB_INT +#ifdef __STDC__ + double __ieee754_scalb(double x, int fn) +#else + double __ieee754_scalb(x,fn) + double x; int fn; +#endif +#else +#ifdef __STDC__ + double __ieee754_scalb(double x, double fn) +#else + double __ieee754_scalb(x,fn) + double x, fn; +#endif +#endif +{ +#ifdef _SCALB_INT + return fd_scalbn(x,fn); +#else + if (fd_isnan(x)||fd_isnan(fn)) return x*fn; + if (!fd_finite(fn)) { + if(fn>0.0) return x*fn; + else return x/(-fn); + } + if (fd_rint(fn)!=fn) return (fn-fn)/(fn-fn); + if ( fn > 65000.0) return fd_scalbn(x, 65000); + if (-fn > 65000.0) return fd_scalbn(x,-65000); + return fd_scalbn(x,(int)fn); +#endif +} diff --git a/src/dom/js/fdlibm/e_sinh.c b/src/dom/js/fdlibm/e_sinh.c new file mode 100644 index 000000000..98ab9b5a3 --- /dev/null +++ b/src/dom/js/fdlibm/e_sinh.c @@ -0,0 +1,122 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Sun Microsystems, Inc. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* @(#)e_sinh.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* __ieee754_sinh(x) + * Method : + * mathematically sinh(x) if defined to be (exp(x)-exp(-x))/2 + * 1. Replace x by |x| (sinh(-x) = -sinh(x)). + * 2. + * E + E/(E+1) + * 0 <= x <= 22 : sinh(x) := --------------, E=expm1(x) + * 2 + * + * 22 <= x <= lnovft : sinh(x) := exp(x)/2 + * lnovft <= x <= ln2ovft: sinh(x) := exp(x/2)/2 * exp(x/2) + * ln2ovft < x : sinh(x) := x*shuge (overflow) + * + * Special cases: + * sinh(x) is |x| if x is +INF, -INF, or NaN. + * only sinh(0)=0 is exact for finite x. + */ + +#include "fdlibm.h" + +#ifdef __STDC__ +static const double one = 1.0, shuge = 1.0e307; +#else +static double one = 1.0, shuge = 1.0e307; +#endif + +#ifdef __STDC__ + double __ieee754_sinh(double x) +#else + double __ieee754_sinh(x) + double x; +#endif +{ + fd_twoints u; + double t,w,h; + int ix,jx; + unsigned lx; + + /* High word of |x|. */ + u.d = x; + jx = __HI(u); + ix = jx&0x7fffffff; + + /* x is INF or NaN */ + if(ix>=0x7ff00000) return x+x; + + h = 0.5; + if (jx<0) h = -h; + /* |x| in [0,22], return sign(x)*0.5*(E+E/(E+1))) */ + if (ix < 0x40360000) { /* |x|<22 */ + if (ix<0x3e300000) /* |x|<2**-28 */ + if(shuge+x>one) return x;/* sinh(tiny) = tiny with inexact */ + t = fd_expm1(fd_fabs(x)); + if(ix<0x3ff00000) return h*(2.0*t-t*t/(t+one)); + return h*(t+t/(t+one)); + } + + /* |x| in [22, log(maxdouble)] return 0.5*exp(|x|) */ + if (ix < 0x40862E42) return h*__ieee754_exp(fd_fabs(x)); + + /* |x| in [log(maxdouble), overflowthresold] */ + lx = *( (((*(unsigned*)&one)>>29)) + (unsigned*)&x); + if (ix<0x408633CE || (ix==0x408633ce)&&(lx<=(unsigned)0x8fb9f87d)) { + w = __ieee754_exp(0.5*fd_fabs(x)); + t = h*w; + return t*w; + } + + /* |x| > overflowthresold, sinh(x) overflow */ + return x*shuge; +} diff --git a/src/dom/js/fdlibm/e_sqrt.c b/src/dom/js/fdlibm/e_sqrt.c new file mode 100644 index 000000000..91802839b --- /dev/null +++ b/src/dom/js/fdlibm/e_sqrt.c @@ -0,0 +1,497 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Sun Microsystems, Inc. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ +/* @(#)e_sqrt.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* __ieee754_sqrt(x) + * Return correctly rounded sqrt. + * ------------------------------------------ + * | Use the hardware sqrt if you have one | + * ------------------------------------------ + * Method: + * Bit by bit method using integer arithmetic. (Slow, but portable) + * 1. Normalization + * Scale x to y in [1,4) with even powers of 2: + * find an integer k such that 1 <= (y=x*2^(2k)) < 4, then + * sqrt(y) = 2^k * sqrt(x) + * 2. Bit by bit computation + * Let q = sqrt(y) truncated to i bit after binary point (q = 1), + * i 0 + * i+1 2 + * s = 2*q , and y = 2 * ( y - q ). (1) + * i i i i + * + * To compute q from q , one checks whether + * i+1 i + * + * -(i+1) 2 + * (q + 2 ) <= y. (2) + * i + * -(i+1) + * If (2) is false, then q = q ; otherwise q = q + 2 . + * i+1 i i+1 i + * + * With some algebric manipulation, it is not difficult to see + * that (2) is equivalent to + * -(i+1) + * s + 2 <= y (3) + * i i + * + * The advantage of (3) is that s and y can be computed by + * i i + * the following recurrence formula: + * if (3) is false + * + * s = s , y = y ; (4) + * i+1 i i+1 i + * + * otherwise, + * -i -(i+1) + * s = s + 2 , y = y - s - 2 (5) + * i+1 i i+1 i i + * + * One may easily use induction to prove (4) and (5). + * Note. Since the left hand side of (3) contain only i+2 bits, + * it does not necessary to do a full (53-bit) comparison + * in (3). + * 3. Final rounding + * After generating the 53 bits result, we compute one more bit. + * Together with the remainder, we can decide whether the + * result is exact, bigger than 1/2ulp, or less than 1/2ulp + * (it will never equal to 1/2ulp). + * The rounding mode can be detected by checking whether + * huge + tiny is equal to huge, and whether huge - tiny is + * equal to huge for some floating point number "huge" and "tiny". + * + * Special cases: + * sqrt(+-0) = +-0 ... exact + * sqrt(inf) = inf + * sqrt(-ve) = NaN ... with invalid signal + * sqrt(NaN) = NaN ... with invalid signal for signaling NaN + * + * Other methods : see the appended file at the end of the program below. + *--------------- + */ + +#include "fdlibm.h" + +#if defined(_MSC_VER) +/* Microsoft Compiler */ +#pragma warning( disable : 4723 ) /* disables potential divide by 0 warning */ +#endif + +#ifdef __STDC__ +static const double one = 1.0, tiny=1.0e-300; +#else +static double one = 1.0, tiny=1.0e-300; +#endif + +#ifdef __STDC__ + double __ieee754_sqrt(double x) +#else + double __ieee754_sqrt(x) + double x; +#endif +{ + fd_twoints u; + double z; + int sign = (int)0x80000000; + unsigned r,t1,s1,ix1,q1; + int ix0,s0,q,m,t,i; + + u.d = x; + ix0 = __HI(u); /* high word of x */ + ix1 = __LO(u); /* low word of x */ + + /* take care of Inf and NaN */ + if((ix0&0x7ff00000)==0x7ff00000) { + return x*x+x; /* sqrt(NaN)=NaN, sqrt(+inf)=+inf + sqrt(-inf)=sNaN */ + } + /* take care of zero */ + if(ix0<=0) { + if(((ix0&(~sign))|ix1)==0) return x;/* sqrt(+-0) = +-0 */ + else if(ix0<0) + return (x-x)/(x-x); /* sqrt(-ve) = sNaN */ + } + /* normalize x */ + m = (ix0>>20); + if(m==0) { /* subnormal x */ + while(ix0==0) { + m -= 21; + ix0 |= (ix1>>11); ix1 <<= 21; + } + for(i=0;(ix0&0x00100000)==0;i++) ix0<<=1; + m -= i-1; + ix0 |= (ix1>>(32-i)); + ix1 <<= i; + } + m -= 1023; /* unbias exponent */ + ix0 = (ix0&0x000fffff)|0x00100000; + if(m&1){ /* odd m, double x to make it even */ + ix0 += ix0 + ((ix1&sign)>>31); + ix1 += ix1; + } + m >>= 1; /* m = [m/2] */ + + /* generate sqrt(x) bit by bit */ + ix0 += ix0 + ((ix1&sign)>>31); + ix1 += ix1; + q = q1 = s0 = s1 = 0; /* [q,q1] = sqrt(x) */ + r = 0x00200000; /* r = moving bit from right to left */ + + while(r!=0) { + t = s0+r; + if(t<=ix0) { + s0 = t+r; + ix0 -= t; + q += r; + } + ix0 += ix0 + ((ix1&sign)>>31); + ix1 += ix1; + r>>=1; + } + + r = sign; + while(r!=0) { + t1 = s1+r; + t = s0; + if((t>31); + ix1 += ix1; + r>>=1; + } + + /* use floating add to find out rounding direction */ + if((ix0|ix1)!=0) { + z = one-tiny; /* trigger inexact flag */ + if (z>=one) { + z = one+tiny; + if (q1==(unsigned)0xffffffff) { q1=0; q += 1;} + else if (z>one) { + if (q1==(unsigned)0xfffffffe) q+=1; + q1+=2; + } else + q1 += (q1&1); + } + } + ix0 = (q>>1)+0x3fe00000; + ix1 = q1>>1; + if ((q&1)==1) ix1 |= sign; + ix0 += (m <<20); + u.d = z; + __HI(u) = ix0; + __LO(u) = ix1; + z = u.d; + return z; +} + +/* +Other methods (use floating-point arithmetic) +------------- +(This is a copy of a drafted paper by Prof W. Kahan +and K.C. Ng, written in May, 1986) + + Two algorithms are given here to implement sqrt(x) + (IEEE double precision arithmetic) in software. + Both supply sqrt(x) correctly rounded. The first algorithm (in + Section A) uses newton iterations and involves four divisions. + The second one uses reciproot iterations to avoid division, but + requires more multiplications. Both algorithms need the ability + to chop results of arithmetic operations instead of round them, + and the INEXACT flag to indicate when an arithmetic operation + is executed exactly with no roundoff error, all part of the + standard (IEEE 754-1985). The ability to perform shift, add, + subtract and logical AND operations upon 32-bit words is needed + too, though not part of the standard. + +A. sqrt(x) by Newton Iteration + + (1) Initial approximation + + Let x0 and x1 be the leading and the trailing 32-bit words of + a floating point number x (in IEEE double format) respectively + + 1 11 52 ...widths + ------------------------------------------------------ + x: |s| e | f | + ------------------------------------------------------ + msb lsb msb lsb ...order + + + ------------------------ ------------------------ + x0: |s| e | f1 | x1: | f2 | + ------------------------ ------------------------ + + By performing shifts and subtracts on x0 and x1 (both regarded + as integers), we obtain an 8-bit approximation of sqrt(x) as + follows. + + k := (x0>>1) + 0x1ff80000; + y0 := k - T1[31&(k>>15)]. ... y ~ sqrt(x) to 8 bits + Here k is a 32-bit integer and T1[] is an integer array containing + correction terms. Now magically the floating value of y (y's + leading 32-bit word is y0, the value of its trailing word is 0) + approximates sqrt(x) to almost 8-bit. + + Value of T1: + static int T1[32]= { + 0, 1024, 3062, 5746, 9193, 13348, 18162, 23592, + 29598, 36145, 43202, 50740, 58733, 67158, 75992, 85215, + 83599, 71378, 60428, 50647, 41945, 34246, 27478, 21581, + 16499, 12183, 8588, 5674, 3403, 1742, 661, 130,}; + + (2) Iterative refinement + + Apply Heron's rule three times to y, we have y approximates + sqrt(x) to within 1 ulp (Unit in the Last Place): + + y := (y+x/y)/2 ... almost 17 sig. bits + y := (y+x/y)/2 ... almost 35 sig. bits + y := y-(y-x/y)/2 ... within 1 ulp + + + Remark 1. + Another way to improve y to within 1 ulp is: + + y := (y+x/y) ... almost 17 sig. bits to 2*sqrt(x) + y := y - 0x00100006 ... almost 18 sig. bits to sqrt(x) + + 2 + (x-y )*y + y := y + 2* ---------- ...within 1 ulp + 2 + 3y + x + + + This formula has one division fewer than the one above; however, + it requires more multiplications and additions. Also x must be + scaled in advance to avoid spurious overflow in evaluating the + expression 3y*y+x. Hence it is not recommended uless division + is slow. If division is very slow, then one should use the + reciproot algorithm given in section B. + + (3) Final adjustment + + By twiddling y's last bit it is possible to force y to be + correctly rounded according to the prevailing rounding mode + as follows. Let r and i be copies of the rounding mode and + inexact flag before entering the square root program. Also we + use the expression y+-ulp for the next representable floating + numbers (up and down) of y. Note that y+-ulp = either fixed + point y+-1, or multiply y by nextafter(1,+-inf) in chopped + mode. + + I := FALSE; ... reset INEXACT flag I + R := RZ; ... set rounding mode to round-toward-zero + z := x/y; ... chopped quotient, possibly inexact + If(not I) then { ... if the quotient is exact + if(z=y) { + I := i; ... restore inexact flag + R := r; ... restore rounded mode + return sqrt(x):=y. + } else { + z := z - ulp; ... special rounding + } + } + i := TRUE; ... sqrt(x) is inexact + If (r=RN) then z=z+ulp ... rounded-to-nearest + If (r=RP) then { ... round-toward-+inf + y = y+ulp; z=z+ulp; + } + y := y+z; ... chopped sum + y0:=y0-0x00100000; ... y := y/2 is correctly rounded. + I := i; ... restore inexact flag + R := r; ... restore rounded mode + return sqrt(x):=y. + + (4) Special cases + + Square root of +inf, +-0, or NaN is itself; + Square root of a negative number is NaN with invalid signal. + + +B. sqrt(x) by Reciproot Iteration + + (1) Initial approximation + + Let x0 and x1 be the leading and the trailing 32-bit words of + a floating point number x (in IEEE double format) respectively + (see section A). By performing shifs and subtracts on x0 and y0, + we obtain a 7.8-bit approximation of 1/sqrt(x) as follows. + + k := 0x5fe80000 - (x0>>1); + y0:= k - T2[63&(k>>14)]. ... y ~ 1/sqrt(x) to 7.8 bits + + Here k is a 32-bit integer and T2[] is an integer array + containing correction terms. Now magically the floating + value of y (y's leading 32-bit word is y0, the value of + its trailing word y1 is set to zero) approximates 1/sqrt(x) + to almost 7.8-bit. + + Value of T2: + static int T2[64]= { + 0x1500, 0x2ef8, 0x4d67, 0x6b02, 0x87be, 0xa395, 0xbe7a, 0xd866, + 0xf14a, 0x1091b,0x11fcd,0x13552,0x14999,0x15c98,0x16e34,0x17e5f, + 0x18d03,0x19a01,0x1a545,0x1ae8a,0x1b5c4,0x1bb01,0x1bfde,0x1c28d, + 0x1c2de,0x1c0db,0x1ba73,0x1b11c,0x1a4b5,0x1953d,0x18266,0x16be0, + 0x1683e,0x179d8,0x18a4d,0x19992,0x1a789,0x1b445,0x1bf61,0x1c989, + 0x1d16d,0x1d77b,0x1dddf,0x1e2ad,0x1e5bf,0x1e6e8,0x1e654,0x1e3cd, + 0x1df2a,0x1d635,0x1cb16,0x1be2c,0x1ae4e,0x19bde,0x1868e,0x16e2e, + 0x1527f,0x1334a,0x11051,0xe951, 0xbe01, 0x8e0d, 0x5924, 0x1edd,}; + + (2) Iterative refinement + + Apply Reciproot iteration three times to y and multiply the + result by x to get an approximation z that matches sqrt(x) + to about 1 ulp. To be exact, we will have + -1ulp < sqrt(x)-z<1.0625ulp. + + ... set rounding mode to Round-to-nearest + y := y*(1.5-0.5*x*y*y) ... almost 15 sig. bits to 1/sqrt(x) + y := y*((1.5-2^-30)+0.5*x*y*y)... about 29 sig. bits to 1/sqrt(x) + ... special arrangement for better accuracy + z := x*y ... 29 bits to sqrt(x), with z*y<1 + z := z + 0.5*z*(1-z*y) ... about 1 ulp to sqrt(x) + + Remark 2. The constant 1.5-2^-30 is chosen to bias the error so that + (a) the term z*y in the final iteration is always less than 1; + (b) the error in the final result is biased upward so that + -1 ulp < sqrt(x) - z < 1.0625 ulp + instead of |sqrt(x)-z|<1.03125ulp. + + (3) Final adjustment + + By twiddling y's last bit it is possible to force y to be + correctly rounded according to the prevailing rounding mode + as follows. Let r and i be copies of the rounding mode and + inexact flag before entering the square root program. Also we + use the expression y+-ulp for the next representable floating + numbers (up and down) of y. Note that y+-ulp = either fixed + point y+-1, or multiply y by nextafter(1,+-inf) in chopped + mode. + + R := RZ; ... set rounding mode to round-toward-zero + switch(r) { + case RN: ... round-to-nearest + if(x<= z*(z-ulp)...chopped) z = z - ulp; else + if(x<= z*(z+ulp)...chopped) z = z; else z = z+ulp; + break; + case RZ:case RM: ... round-to-zero or round-to--inf + R:=RP; ... reset rounding mod to round-to-+inf + if(x=(z+ulp)*(z+ulp) ...rounded up) z = z+ulp; + break; + case RP: ... round-to-+inf + if(x>(z+ulp)*(z+ulp)...chopped) z = z+2*ulp; else + if(x>z*z ...chopped) z = z+ulp; + break; + } + + Remark 3. The above comparisons can be done in fixed point. For + example, to compare x and w=z*z chopped, it suffices to compare + x1 and w1 (the trailing parts of x and w), regarding them as + two's complement integers. + + ...Is z an exact square root? + To determine whether z is an exact square root of x, let z1 be the + trailing part of z, and also let x0 and x1 be the leading and + trailing parts of x. + + If ((z1&0x03ffffff)!=0) ... not exact if trailing 26 bits of z!=0 + I := 1; ... Raise Inexact flag: z is not exact + else { + j := 1 - [(x0>>20)&1] ... j = logb(x) mod 2 + k := z1 >> 26; ... get z's 25-th and 26-th + fraction bits + I := i or (k&j) or ((k&(j+j+1))!=(x1&3)); + } + R:= r ... restore rounded mode + return sqrt(x):=z. + + If multiplication is cheaper then the foregoing red tape, the + Inexact flag can be evaluated by + + I := i; + I := (z*z!=x) or I. + + Note that z*z can overwrite I; this value must be sensed if it is + True. + + Remark 4. If z*z = x exactly, then bit 25 to bit 0 of z1 must be + zero. + + -------------------- + z1: | f2 | + -------------------- + bit 31 bit 0 + + Further more, bit 27 and 26 of z1, bit 0 and 1 of x1, and the odd + or even of logb(x) have the following relations: + + ------------------------------------------------- + bit 27,26 of z1 bit 1,0 of x1 logb(x) + ------------------------------------------------- + 00 00 odd and even + 01 01 even + 10 10 odd + 10 00 even + 11 01 even + ------------------------------------------------- + + (4) Special cases (see (4) of Section A). + + */ + diff --git a/src/dom/js/fdlibm/fdlibm.h b/src/dom/js/fdlibm/fdlibm.h new file mode 100644 index 000000000..b4063f82f --- /dev/null +++ b/src/dom/js/fdlibm/fdlibm.h @@ -0,0 +1,273 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Sun Microsystems, Inc. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* @(#)fdlibm.h 1.5 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* Modified defines start here.. */ +#undef __LITTLE_ENDIAN + +#ifdef _WIN32 +#define huge myhuge +#define __LITTLE_ENDIAN +#endif + +#ifdef XP_OS2 +#define __LITTLE_ENDIAN +#endif + +#if defined(linux) && defined(__i386__) +#define __LITTLE_ENDIAN +#endif + +/* End here. The rest is the standard file. */ + +#ifdef __NEWVALID /* special setup for Sun test regime */ +#if defined(i386) || defined(i486) || \ + defined(intel) || defined(x86) || defined(i86pc) +#define __LITTLE_ENDIAN +#endif +#endif + +typedef union { +#ifdef __LITTLE_ENDIAN + struct { int lo, hi; } ints; +#else + struct { int hi, lo; } ints; +#endif + double d; +} fd_twoints; + +#define __HI(x) x.ints.hi +#define __LO(x) x.ints.lo + +#undef __P +#ifdef __STDC__ +#define __P(p) p +#else +#define __P(p) () +#endif + +/* + * ANSI/POSIX + */ + +extern int signgam; + +#define MAXFLOAT ((float)3.40282346638528860e+38) + +enum fdversion {fdlibm_ieee = -1, fdlibm_svid, fdlibm_xopen, fdlibm_posix}; + +#define _LIB_VERSION_TYPE enum fdversion +#define _LIB_VERSION _fdlib_version + +/* if global variable _LIB_VERSION is not desirable, one may + * change the following to be a constant by: + * #define _LIB_VERSION_TYPE const enum version + * In that case, after one initializes the value _LIB_VERSION (see + * s_lib_version.c) during compile time, it cannot be modified + * in the middle of a program + */ +extern _LIB_VERSION_TYPE _LIB_VERSION; + +#define _IEEE_ fdlibm_ieee +#define _SVID_ fdlibm_svid +#define _XOPEN_ fdlibm_xopen +#define _POSIX_ fdlibm_posix + +struct exception { + int type; + char *name; + double arg1; + double arg2; + double retval; +}; + +#define HUGE MAXFLOAT + +/* + * set X_TLOSS = pi*2**52, which is possibly defined in + * (one may replace the following line by "#include ") + */ + +#define X_TLOSS 1.41484755040568800000e+16 + +#define DOMAIN 1 +#define SING 2 +#define OVERFLOW 3 +#define UNDERFLOW 4 +#define TLOSS 5 +#define PLOSS 6 + +/* + * ANSI/POSIX + */ + +extern double fd_acos __P((double)); +extern double fd_asin __P((double)); +extern double fd_atan __P((double)); +extern double fd_atan2 __P((double, double)); +extern double fd_cos __P((double)); +extern double fd_sin __P((double)); +extern double fd_tan __P((double)); + +extern double fd_cosh __P((double)); +extern double fd_sinh __P((double)); +extern double fd_tanh __P((double)); + +extern double fd_exp __P((double)); +extern double fd_frexp __P((double, int *)); +extern double fd_ldexp __P((double, int)); +extern double fd_log __P((double)); +extern double fd_log10 __P((double)); +extern double fd_modf __P((double, double *)); + +extern double fd_pow __P((double, double)); +extern double fd_sqrt __P((double)); + +extern double fd_ceil __P((double)); +extern double fd_fabs __P((double)); +extern double fd_floor __P((double)); +extern double fd_fmod __P((double, double)); + +extern double fd_erf __P((double)); +extern double fd_erfc __P((double)); +extern double fd_gamma __P((double)); +extern double fd_hypot __P((double, double)); +extern int fd_isnan __P((double)); +extern int fd_finite __P((double)); +extern double fd_j0 __P((double)); +extern double fd_j1 __P((double)); +extern double fd_jn __P((int, double)); +extern double fd_lgamma __P((double)); +extern double fd_y0 __P((double)); +extern double fd_y1 __P((double)); +extern double fd_yn __P((int, double)); + +extern double fd_acosh __P((double)); +extern double fd_asinh __P((double)); +extern double fd_atanh __P((double)); +extern double fd_cbrt __P((double)); +extern double fd_logb __P((double)); +extern double fd_nextafter __P((double, double)); +extern double fd_remainder __P((double, double)); +#ifdef _SCALB_INT +extern double fd_scalb __P((double, int)); +#else +extern double fd_scalb __P((double, double)); +#endif + +extern int fd_matherr __P((struct exception *)); + +/* + * IEEE Test Vector + */ +extern double significand __P((double)); + +/* + * Functions callable from C, intended to support IEEE arithmetic. + */ +extern double fd_copysign __P((double, double)); +extern int fd_ilogb __P((double)); +extern double fd_rint __P((double)); +extern double fd_scalbn __P((double, int)); + +/* + * BSD math library entry points + */ +extern double fd_expm1 __P((double)); +extern double fd_log1p __P((double)); + +/* + * Reentrant version of gamma & lgamma; passes signgam back by reference + * as the second argument; user must allocate space for signgam. + */ +#ifdef _REENTRANT +extern double gamma_r __P((double, int *)); +extern double lgamma_r __P((double, int *)); +#endif /* _REENTRANT */ + +/* ieee style elementary functions */ +extern double __ieee754_sqrt __P((double)); +extern double __ieee754_acos __P((double)); +extern double __ieee754_acosh __P((double)); +extern double __ieee754_log __P((double)); +extern double __ieee754_atanh __P((double)); +extern double __ieee754_asin __P((double)); +extern double __ieee754_atan2 __P((double,double)); +extern double __ieee754_exp __P((double)); +extern double __ieee754_cosh __P((double)); +extern double __ieee754_fmod __P((double,double)); +extern double __ieee754_pow __P((double,double)); +extern double __ieee754_lgamma_r __P((double,int *)); +extern double __ieee754_gamma_r __P((double,int *)); +extern double __ieee754_lgamma __P((double)); +extern double __ieee754_gamma __P((double)); +extern double __ieee754_log10 __P((double)); +extern double __ieee754_sinh __P((double)); +extern double __ieee754_hypot __P((double,double)); +extern double __ieee754_j0 __P((double)); +extern double __ieee754_j1 __P((double)); +extern double __ieee754_y0 __P((double)); +extern double __ieee754_y1 __P((double)); +extern double __ieee754_jn __P((int,double)); +extern double __ieee754_yn __P((int,double)); +extern double __ieee754_remainder __P((double,double)); +extern int __ieee754_rem_pio2 __P((double,double*)); +#ifdef _SCALB_INT +extern double __ieee754_scalb __P((double,int)); +#else +extern double __ieee754_scalb __P((double,double)); +#endif + +/* fdlibm kernel function */ +extern double __kernel_standard __P((double,double,int,int*)); +extern double __kernel_sin __P((double,double,int)); +extern double __kernel_cos __P((double,double)); +extern double __kernel_tan __P((double,double,int)); +extern int __kernel_rem_pio2 __P((double*,double*,int,int,int,const int*)); diff --git a/src/dom/js/fdlibm/k_cos.c b/src/dom/js/fdlibm/k_cos.c new file mode 100644 index 000000000..17b505d58 --- /dev/null +++ b/src/dom/js/fdlibm/k_cos.c @@ -0,0 +1,134 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Sun Microsystems, Inc. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* @(#)k_cos.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * __kernel_cos( x, y ) + * kernel cos function on [-pi/4, pi/4], pi/4 ~ 0.785398164 + * Input x is assumed to be bounded by ~pi/4 in magnitude. + * Input y is the tail of x. + * + * Algorithm + * 1. Since cos(-x) = cos(x), we need only to consider positive x. + * 2. if x < 2^-27 (hx<0x3e400000 0), return 1 with inexact if x!=0. + * 3. cos(x) is approximated by a polynomial of degree 14 on + * [0,pi/4] + * 4 14 + * cos(x) ~ 1 - x*x/2 + C1*x + ... + C6*x + * where the remez error is + * + * | 2 4 6 8 10 12 14 | -58 + * |cos(x)-(1-.5*x +C1*x +C2*x +C3*x +C4*x +C5*x +C6*x )| <= 2 + * | | + * + * 4 6 8 10 12 14 + * 4. let r = C1*x +C2*x +C3*x +C4*x +C5*x +C6*x , then + * cos(x) = 1 - x*x/2 + r + * since cos(x+y) ~ cos(x) - sin(x)*y + * ~ cos(x) - x*y, + * a correction term is necessary in cos(x) and hence + * cos(x+y) = 1 - (x*x/2 - (r - x*y)) + * For better accuracy when x > 0.3, let qx = |x|/4 with + * the last 32 bits mask off, and if x > 0.78125, let qx = 0.28125. + * Then + * cos(x+y) = (1-qx) - ((x*x/2-qx) - (r-x*y)). + * Note that 1-qx and (x*x/2-qx) is EXACT here, and the + * magnitude of the latter is at least a quarter of x*x/2, + * thus, reducing the rounding error in the subtraction. + */ + +#include "fdlibm.h" + +#ifdef __STDC__ +static const double +#else +static double +#endif +one = 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */ +C1 = 4.16666666666666019037e-02, /* 0x3FA55555, 0x5555554C */ +C2 = -1.38888888888741095749e-03, /* 0xBF56C16C, 0x16C15177 */ +C3 = 2.48015872894767294178e-05, /* 0x3EFA01A0, 0x19CB1590 */ +C4 = -2.75573143513906633035e-07, /* 0xBE927E4F, 0x809C52AD */ +C5 = 2.08757232129817482790e-09, /* 0x3E21EE9E, 0xBDB4B1C4 */ +C6 = -1.13596475577881948265e-11; /* 0xBDA8FAE9, 0xBE8838D4 */ + +#ifdef __STDC__ + double __kernel_cos(double x, double y) +#else + double __kernel_cos(x, y) + double x,y; +#endif +{ + fd_twoints u; + double a,hz,z,r,qx; + int ix; + u.d = x; + ix = __HI(u)&0x7fffffff; /* ix = |x|'s high word*/ + if(ix<0x3e400000) { /* if x < 2**27 */ + if(((int)x)==0) return one; /* generate inexact */ + } + z = x*x; + r = z*(C1+z*(C2+z*(C3+z*(C4+z*(C5+z*C6))))); + if(ix < 0x3FD33333) /* if |x| < 0.3 */ + return one - (0.5*z - (z*r - x*y)); + else { + if(ix > 0x3fe90000) { /* x > 0.78125 */ + qx = 0.28125; + } else { + u.d = qx; + __HI(u) = ix-0x00200000; /* x/4 */ + __LO(u) = 0; + qx = u.d; + } + hz = 0.5*z-qx; + a = one-qx; + return a - (hz - (z*r-x*y)); + } +} diff --git a/src/dom/js/fdlibm/k_rem_pio2.c b/src/dom/js/fdlibm/k_rem_pio2.c new file mode 100644 index 000000000..d261e190a --- /dev/null +++ b/src/dom/js/fdlibm/k_rem_pio2.c @@ -0,0 +1,354 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Sun Microsystems, Inc. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* @(#)k_rem_pio2.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * __kernel_rem_pio2(x,y,e0,nx,prec,ipio2) + * double x[],y[]; int e0,nx,prec; int ipio2[]; + * + * __kernel_rem_pio2 return the last three digits of N with + * y = x - N*pi/2 + * so that |y| < pi/2. + * + * The method is to compute the integer (mod 8) and fraction parts of + * (2/pi)*x without doing the full multiplication. In general we + * skip the part of the product that are known to be a huge integer ( + * more accurately, = 0 mod 8 ). Thus the number of operations are + * independent of the exponent of the input. + * + * (2/pi) is represented by an array of 24-bit integers in ipio2[]. + * + * Input parameters: + * x[] The input value (must be positive) is broken into nx + * pieces of 24-bit integers in double precision format. + * x[i] will be the i-th 24 bit of x. The scaled exponent + * of x[0] is given in input parameter e0 (i.e., x[0]*2^e0 + * match x's up to 24 bits. + * + * Example of breaking a double positive z into x[0]+x[1]+x[2]: + * e0 = ilogb(z)-23 + * z = scalbn(z,-e0) + * for i = 0,1,2 + * x[i] = floor(z) + * z = (z-x[i])*2**24 + * + * + * y[] ouput result in an array of double precision numbers. + * The dimension of y[] is: + * 24-bit precision 1 + * 53-bit precision 2 + * 64-bit precision 2 + * 113-bit precision 3 + * The actual value is the sum of them. Thus for 113-bit + * precison, one may have to do something like: + * + * long double t,w,r_head, r_tail; + * t = (long double)y[2] + (long double)y[1]; + * w = (long double)y[0]; + * r_head = t+w; + * r_tail = w - (r_head - t); + * + * e0 The exponent of x[0] + * + * nx dimension of x[] + * + * prec an integer indicating the precision: + * 0 24 bits (single) + * 1 53 bits (double) + * 2 64 bits (extended) + * 3 113 bits (quad) + * + * ipio2[] + * integer array, contains the (24*i)-th to (24*i+23)-th + * bit of 2/pi after binary point. The corresponding + * floating value is + * + * ipio2[i] * 2^(-24(i+1)). + * + * External function: + * double scalbn(), floor(); + * + * + * Here is the description of some local variables: + * + * jk jk+1 is the initial number of terms of ipio2[] needed + * in the computation. The recommended value is 2,3,4, + * 6 for single, double, extended,and quad. + * + * jz local integer variable indicating the number of + * terms of ipio2[] used. + * + * jx nx - 1 + * + * jv index for pointing to the suitable ipio2[] for the + * computation. In general, we want + * ( 2^e0*x[0] * ipio2[jv-1]*2^(-24jv) )/8 + * is an integer. Thus + * e0-3-24*jv >= 0 or (e0-3)/24 >= jv + * Hence jv = max(0,(e0-3)/24). + * + * jp jp+1 is the number of terms in PIo2[] needed, jp = jk. + * + * q[] double array with integral value, representing the + * 24-bits chunk of the product of x and 2/pi. + * + * q0 the corresponding exponent of q[0]. Note that the + * exponent for q[i] would be q0-24*i. + * + * PIo2[] double precision array, obtained by cutting pi/2 + * into 24 bits chunks. + * + * f[] ipio2[] in floating point + * + * iq[] integer array by breaking up q[] in 24-bits chunk. + * + * fq[] final product of x*(2/pi) in fq[0],..,fq[jk] + * + * ih integer. If >0 it indicates q[] is >= 0.5, hence + * it also indicates the *sign* of the result. + * + */ + + +/* + * Constants: + * The hexadecimal values are the intended ones for the following + * constants. The decimal values may be used, provided that the + * compiler will convert from decimal to binary accurately enough + * to produce the hexadecimal values shown. + */ + +#include "fdlibm.h" + +#ifdef __STDC__ +static const int init_jk[] = {2,3,4,6}; /* initial value for jk */ +#else +static int init_jk[] = {2,3,4,6}; +#endif + +#ifdef __STDC__ +static const double PIo2[] = { +#else +static double PIo2[] = { +#endif + 1.57079625129699707031e+00, /* 0x3FF921FB, 0x40000000 */ + 7.54978941586159635335e-08, /* 0x3E74442D, 0x00000000 */ + 5.39030252995776476554e-15, /* 0x3CF84698, 0x80000000 */ + 3.28200341580791294123e-22, /* 0x3B78CC51, 0x60000000 */ + 1.27065575308067607349e-29, /* 0x39F01B83, 0x80000000 */ + 1.22933308981111328932e-36, /* 0x387A2520, 0x40000000 */ + 2.73370053816464559624e-44, /* 0x36E38222, 0x80000000 */ + 2.16741683877804819444e-51, /* 0x3569F31D, 0x00000000 */ +}; + +#ifdef __STDC__ +static const double +#else +static double +#endif +zero = 0.0, +one = 1.0, +two24 = 1.67772160000000000000e+07, /* 0x41700000, 0x00000000 */ +twon24 = 5.96046447753906250000e-08; /* 0x3E700000, 0x00000000 */ + +#ifdef __STDC__ + int __kernel_rem_pio2(double *x, double *y, int e0, int nx, int prec, const int *ipio2) +#else + int __kernel_rem_pio2(x,y,e0,nx,prec,ipio2) + double x[], y[]; int e0,nx,prec; int ipio2[]; +#endif +{ + int jz,jx,jv,jp,jk,carry,n,iq[20],i,j,k,m,q0,ih; + double z,fw,f[20],fq[20],q[20]; + + /* initialize jk*/ + jk = init_jk[prec]; + jp = jk; + + /* determine jx,jv,q0, note that 3>q0 */ + jx = nx-1; + jv = (e0-3)/24; if(jv<0) jv=0; + q0 = e0-24*(jv+1); + + /* set up f[0] to f[jx+jk] where f[jx+jk] = ipio2[jv+jk] */ + j = jv-jx; m = jx+jk; + for(i=0;i<=m;i++,j++) f[i] = (j<0)? zero : (double) ipio2[j]; + + /* compute q[0],q[1],...q[jk] */ + for (i=0;i<=jk;i++) { + for(j=0,fw=0.0;j<=jx;j++) fw += x[j]*f[jx+i-j]; q[i] = fw; + } + + jz = jk; +recompute: + /* distill q[] into iq[] reversingly */ + for(i=0,j=jz,z=q[jz];j>0;i++,j--) { + fw = (double)((int)(twon24* z)); + iq[i] = (int)(z-two24*fw); + z = q[j-1]+fw; + } + + /* compute n */ + z = fd_scalbn(z,q0); /* actual value of z */ + z -= 8.0*fd_floor(z*0.125); /* trim off integer >= 8 */ + n = (int) z; + z -= (double)n; + ih = 0; + if(q0>0) { /* need iq[jz-1] to determine n */ + i = (iq[jz-1]>>(24-q0)); n += i; + iq[jz-1] -= i<<(24-q0); + ih = iq[jz-1]>>(23-q0); + } + else if(q0==0) ih = iq[jz-1]>>23; + else if(z>=0.5) ih=2; + + if(ih>0) { /* q > 0.5 */ + n += 1; carry = 0; + for(i=0;i0) { /* rare case: chance is 1 in 12 */ + switch(q0) { + case 1: + iq[jz-1] &= 0x7fffff; break; + case 2: + iq[jz-1] &= 0x3fffff; break; + } + } + if(ih==2) { + z = one - z; + if(carry!=0) z -= fd_scalbn(one,q0); + } + } + + /* check if recomputation is needed */ + if(z==zero) { + j = 0; + for (i=jz-1;i>=jk;i--) j |= iq[i]; + if(j==0) { /* need recomputation */ + for(k=1;iq[jk-k]==0;k++); /* k = no. of terms needed */ + + for(i=jz+1;i<=jz+k;i++) { /* add q[jz+1] to q[jz+k] */ + f[jx+i] = (double) ipio2[jv+i]; + for(j=0,fw=0.0;j<=jx;j++) fw += x[j]*f[jx+i-j]; + q[i] = fw; + } + jz += k; + goto recompute; + } + } + + /* chop off zero terms */ + if(z==0.0) { + jz -= 1; q0 -= 24; + while(iq[jz]==0) { jz--; q0-=24;} + } else { /* break z into 24-bit if necessary */ + z = fd_scalbn(z,-q0); + if(z>=two24) { + fw = (double)((int)(twon24*z)); + iq[jz] = (int)(z-two24*fw); + jz += 1; q0 += 24; + iq[jz] = (int) fw; + } else iq[jz] = (int) z ; + } + + /* convert integer "bit" chunk to floating-point value */ + fw = fd_scalbn(one,q0); + for(i=jz;i>=0;i--) { + q[i] = fw*(double)iq[i]; fw*=twon24; + } + + /* compute PIo2[0,...,jp]*q[jz,...,0] */ + for(i=jz;i>=0;i--) { + for(fw=0.0,k=0;k<=jp&&k<=jz-i;k++) fw += PIo2[k]*q[i+k]; + fq[jz-i] = fw; + } + + /* compress fq[] into y[] */ + switch(prec) { + case 0: + fw = 0.0; + for (i=jz;i>=0;i--) fw += fq[i]; + y[0] = (ih==0)? fw: -fw; + break; + case 1: + case 2: + fw = 0.0; + for (i=jz;i>=0;i--) fw += fq[i]; + y[0] = (ih==0)? fw: -fw; + fw = fq[0]-fw; + for (i=1;i<=jz;i++) fw += fq[i]; + y[1] = (ih==0)? fw: -fw; + break; + case 3: /* painful */ + for (i=jz;i>0;i--) { + fw = fq[i-1]+fq[i]; + fq[i] += fq[i-1]-fw; + fq[i-1] = fw; + } + for (i=jz;i>1;i--) { + fw = fq[i-1]+fq[i]; + fq[i] += fq[i-1]-fw; + fq[i-1] = fw; + } + for (fw=0.0,i=jz;i>=2;i--) fw += fq[i]; + if(ih==0) { + y[0] = fq[0]; y[1] = fq[1]; y[2] = fw; + } else { + y[0] = -fq[0]; y[1] = -fq[1]; y[2] = -fw; + } + } + return n&7; +} diff --git a/src/dom/js/fdlibm/k_sin.c b/src/dom/js/fdlibm/k_sin.c new file mode 100644 index 000000000..d2bdabd6d --- /dev/null +++ b/src/dom/js/fdlibm/k_sin.c @@ -0,0 +1,114 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Sun Microsystems, Inc. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* @(#)k_sin.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* __kernel_sin( x, y, iy) + * kernel sin function on [-pi/4, pi/4], pi/4 ~ 0.7854 + * Input x is assumed to be bounded by ~pi/4 in magnitude. + * Input y is the tail of x. + * Input iy indicates whether y is 0. (if iy=0, y assume to be 0). + * + * Algorithm + * 1. Since sin(-x) = -sin(x), we need only to consider positive x. + * 2. if x < 2^-27 (hx<0x3e400000 0), return x with inexact if x!=0. + * 3. sin(x) is approximated by a polynomial of degree 13 on + * [0,pi/4] + * 3 13 + * sin(x) ~ x + S1*x + ... + S6*x + * where + * + * |sin(x) 2 4 6 8 10 12 | -58 + * |----- - (1+S1*x +S2*x +S3*x +S4*x +S5*x +S6*x )| <= 2 + * | x | + * + * 4. sin(x+y) = sin(x) + sin'(x')*y + * ~ sin(x) + (1-x*x/2)*y + * For better accuracy, let + * 3 2 2 2 2 + * r = x *(S2+x *(S3+x *(S4+x *(S5+x *S6)))) + * then 3 2 + * sin(x) = x + (S1*x + (x *(r-y/2)+y)) + */ + +#include "fdlibm.h" + +#ifdef __STDC__ +static const double +#else +static double +#endif +half = 5.00000000000000000000e-01, /* 0x3FE00000, 0x00000000 */ +S1 = -1.66666666666666324348e-01, /* 0xBFC55555, 0x55555549 */ +S2 = 8.33333333332248946124e-03, /* 0x3F811111, 0x1110F8A6 */ +S3 = -1.98412698298579493134e-04, /* 0xBF2A01A0, 0x19C161D5 */ +S4 = 2.75573137070700676789e-06, /* 0x3EC71DE3, 0x57B1FE7D */ +S5 = -2.50507602534068634195e-08, /* 0xBE5AE5E6, 0x8A2B9CEB */ +S6 = 1.58969099521155010221e-10; /* 0x3DE5D93A, 0x5ACFD57C */ + +#ifdef __STDC__ + double __kernel_sin(double x, double y, int iy) +#else + double __kernel_sin(x, y, iy) + double x,y; int iy; /* iy=0 if y is zero */ +#endif +{ + fd_twoints u; + double z,r,v; + int ix; + u.d = x; + ix = __HI(u)&0x7fffffff; /* high word of x */ + if(ix<0x3e400000) /* |x| < 2**-27 */ + {if((int)x==0) return x;} /* generate inexact */ + z = x*x; + v = z*x; + r = S2+z*(S3+z*(S4+z*(S5+z*S6))); + if(iy==0) return x+v*(S1+z*r); + else return x-((z*(half*y-v*r)-y)-v*S1); +} diff --git a/src/dom/js/fdlibm/k_standard.c b/src/dom/js/fdlibm/k_standard.c new file mode 100644 index 000000000..720109c9d --- /dev/null +++ b/src/dom/js/fdlibm/k_standard.c @@ -0,0 +1,785 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Sun Microsystems, Inc. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* @(#)k_standard.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + * + */ + +#include "fdlibm.h" + +/* XXX ugly hack to get msvc to link without error. */ +#if _LIB_VERSION == _IEEE_ && !(defined(DARWIN) || defined(XP_MACOSX)) + int errno; +# define EDOM 0 +# define ERANGE 0 +#else +# include +#endif + + +#ifndef _USE_WRITE +#include /* fputs(), stderr */ +#define WRITE2(u,v) fputs(u, stderr) +#else /* !defined(_USE_WRITE) */ +#include /* write */ +#define WRITE2(u,v) write(2, u, v) +#undef fflush +#endif /* !defined(_USE_WRITE) */ + +static double zero = 0.0; /* used as const */ + +/* + * Standard conformance (non-IEEE) on exception cases. + * Mapping: + * 1 -- acos(|x|>1) + * 2 -- asin(|x|>1) + * 3 -- atan2(+-0,+-0) + * 4 -- hypot overflow + * 5 -- cosh overflow + * 6 -- exp overflow + * 7 -- exp underflow + * 8 -- y0(0) + * 9 -- y0(-ve) + * 10-- y1(0) + * 11-- y1(-ve) + * 12-- yn(0) + * 13-- yn(-ve) + * 14-- lgamma(finite) overflow + * 15-- lgamma(-integer) + * 16-- log(0) + * 17-- log(x<0) + * 18-- log10(0) + * 19-- log10(x<0) + * 20-- pow(0.0,0.0) + * 21-- pow(x,y) overflow + * 22-- pow(x,y) underflow + * 23-- pow(0,negative) + * 24-- pow(neg,non-integral) + * 25-- sinh(finite) overflow + * 26-- sqrt(negative) + * 27-- fmod(x,0) + * 28-- remainder(x,0) + * 29-- acosh(x<1) + * 30-- atanh(|x|>1) + * 31-- atanh(|x|=1) + * 32-- scalb overflow + * 33-- scalb underflow + * 34-- j0(|x|>X_TLOSS) + * 35-- y0(x>X_TLOSS) + * 36-- j1(|x|>X_TLOSS) + * 37-- y1(x>X_TLOSS) + * 38-- jn(|x|>X_TLOSS, n) + * 39-- yn(x>X_TLOSS, n) + * 40-- gamma(finite) overflow + * 41-- gamma(-integer) + * 42-- pow(NaN,0.0) + */ + + +#ifdef __STDC__ + double __kernel_standard(double x, double y, int type, int *err) +#else + double __kernel_standard(x,y,type, err) + double x,y; int type;int *err; +#endif +{ + struct exception exc; +#ifndef HUGE_VAL /* this is the only routine that uses HUGE_VAL */ +#define HUGE_VAL inf + double inf = 0.0; + fd_twoints u; + + u.d = inf; + __HI(u) = 0x7ff00000; /* set inf to infinite */ + inf = u.d; +#endif + + *err = 0; + +#ifdef _USE_WRITE + (void) fflush(stdout); +#endif + exc.arg1 = x; + exc.arg2 = y; + switch(type) { + case 1: + /* acos(|x|>1) */ + exc.type = DOMAIN; + exc.name = "acos"; + exc.retval = zero; + if (_LIB_VERSION == _POSIX_) + *err = EDOM; + else if (!fd_matherr(&exc)) { + if(_LIB_VERSION == _SVID_) { + (void) WRITE2("acos: DOMAIN error\n", 19); + } + *err = EDOM; + } + break; + case 2: + /* asin(|x|>1) */ + exc.type = DOMAIN; + exc.name = "asin"; + exc.retval = zero; + if(_LIB_VERSION == _POSIX_) + *err = EDOM; + else if (!fd_matherr(&exc)) { + if(_LIB_VERSION == _SVID_) { + (void) WRITE2("asin: DOMAIN error\n", 19); + } + *err = EDOM; + } + break; + case 3: + /* atan2(+-0,+-0) */ + exc.arg1 = y; + exc.arg2 = x; + exc.type = DOMAIN; + exc.name = "atan2"; + exc.retval = zero; + if(_LIB_VERSION == _POSIX_) + *err = EDOM; + else if (!fd_matherr(&exc)) { + if(_LIB_VERSION == _SVID_) { + (void) WRITE2("atan2: DOMAIN error\n", 20); + } + *err = EDOM; + } + break; + case 4: + /* hypot(finite,finite) overflow */ + exc.type = OVERFLOW; + exc.name = "hypot"; + if (_LIB_VERSION == _SVID_) + exc.retval = HUGE; + else + exc.retval = HUGE_VAL; + if (_LIB_VERSION == _POSIX_) + *err = ERANGE; + else if (!fd_matherr(&exc)) { + *err = ERANGE; + } + break; + case 5: + /* cosh(finite) overflow */ + exc.type = OVERFLOW; + exc.name = "cosh"; + if (_LIB_VERSION == _SVID_) + exc.retval = HUGE; + else + exc.retval = HUGE_VAL; + if (_LIB_VERSION == _POSIX_) + *err = ERANGE; + else if (!fd_matherr(&exc)) { + *err = ERANGE; + } + break; + case 6: + /* exp(finite) overflow */ + exc.type = OVERFLOW; + exc.name = "exp"; + if (_LIB_VERSION == _SVID_) + exc.retval = HUGE; + else + exc.retval = HUGE_VAL; + if (_LIB_VERSION == _POSIX_) + *err = ERANGE; + else if (!fd_matherr(&exc)) { + *err = ERANGE; + } + break; + case 7: + /* exp(finite) underflow */ + exc.type = UNDERFLOW; + exc.name = "exp"; + exc.retval = zero; + if (_LIB_VERSION == _POSIX_) + *err = ERANGE; + else if (!fd_matherr(&exc)) { + *err = ERANGE; + } + break; + case 8: + /* y0(0) = -inf */ + exc.type = DOMAIN; /* should be SING for IEEE */ + exc.name = "y0"; + if (_LIB_VERSION == _SVID_) + exc.retval = -HUGE; + else + exc.retval = -HUGE_VAL; + if (_LIB_VERSION == _POSIX_) + *err = EDOM; + else if (!fd_matherr(&exc)) { + if (_LIB_VERSION == _SVID_) { + (void) WRITE2("y0: DOMAIN error\n", 17); + } + *err = EDOM; + } + break; + case 9: + /* y0(x<0) = NaN */ + exc.type = DOMAIN; + exc.name = "y0"; + if (_LIB_VERSION == _SVID_) + exc.retval = -HUGE; + else + exc.retval = -HUGE_VAL; + if (_LIB_VERSION == _POSIX_) + *err = EDOM; + else if (!fd_matherr(&exc)) { + if (_LIB_VERSION == _SVID_) { + (void) WRITE2("y0: DOMAIN error\n", 17); + } + *err = EDOM; + } + break; + case 10: + /* y1(0) = -inf */ + exc.type = DOMAIN; /* should be SING for IEEE */ + exc.name = "y1"; + if (_LIB_VERSION == _SVID_) + exc.retval = -HUGE; + else + exc.retval = -HUGE_VAL; + if (_LIB_VERSION == _POSIX_) + *err = EDOM; + else if (!fd_matherr(&exc)) { + if (_LIB_VERSION == _SVID_) { + (void) WRITE2("y1: DOMAIN error\n", 17); + } + *err = EDOM; + } + break; + case 11: + /* y1(x<0) = NaN */ + exc.type = DOMAIN; + exc.name = "y1"; + if (_LIB_VERSION == _SVID_) + exc.retval = -HUGE; + else + exc.retval = -HUGE_VAL; + if (_LIB_VERSION == _POSIX_) + *err = EDOM; + else if (!fd_matherr(&exc)) { + if (_LIB_VERSION == _SVID_) { + (void) WRITE2("y1: DOMAIN error\n", 17); + } + *err = EDOM; + } + break; + case 12: + /* yn(n,0) = -inf */ + exc.type = DOMAIN; /* should be SING for IEEE */ + exc.name = "yn"; + if (_LIB_VERSION == _SVID_) + exc.retval = -HUGE; + else + exc.retval = -HUGE_VAL; + if (_LIB_VERSION == _POSIX_) + *err = EDOM; + else if (!fd_matherr(&exc)) { + if (_LIB_VERSION == _SVID_) { + (void) WRITE2("yn: DOMAIN error\n", 17); + } + *err = EDOM; + } + break; + case 13: + /* yn(x<0) = NaN */ + exc.type = DOMAIN; + exc.name = "yn"; + if (_LIB_VERSION == _SVID_) + exc.retval = -HUGE; + else + exc.retval = -HUGE_VAL; + if (_LIB_VERSION == _POSIX_) + *err = EDOM; + else if (!fd_matherr(&exc)) { + if (_LIB_VERSION == _SVID_) { + (void) WRITE2("yn: DOMAIN error\n", 17); + } + *err = EDOM; + } + break; + case 14: + /* lgamma(finite) overflow */ + exc.type = OVERFLOW; + exc.name = "lgamma"; + if (_LIB_VERSION == _SVID_) + exc.retval = HUGE; + else + exc.retval = HUGE_VAL; + if (_LIB_VERSION == _POSIX_) + *err = ERANGE; + else if (!fd_matherr(&exc)) { + *err = ERANGE; + } + break; + case 15: + /* lgamma(-integer) or lgamma(0) */ + exc.type = SING; + exc.name = "lgamma"; + if (_LIB_VERSION == _SVID_) + exc.retval = HUGE; + else + exc.retval = HUGE_VAL; + if (_LIB_VERSION == _POSIX_) + *err = EDOM; + else if (!fd_matherr(&exc)) { + if (_LIB_VERSION == _SVID_) { + (void) WRITE2("lgamma: SING error\n", 19); + } + *err = EDOM; + } + break; + case 16: + /* log(0) */ + exc.type = SING; + exc.name = "log"; + if (_LIB_VERSION == _SVID_) + exc.retval = -HUGE; + else + exc.retval = -HUGE_VAL; + if (_LIB_VERSION == _POSIX_) + *err = ERANGE; + else if (!fd_matherr(&exc)) { + if (_LIB_VERSION == _SVID_) { + (void) WRITE2("log: SING error\n", 16); + } + *err = EDOM; + } + break; + case 17: + /* log(x<0) */ + exc.type = DOMAIN; + exc.name = "log"; + if (_LIB_VERSION == _SVID_) + exc.retval = -HUGE; + else + exc.retval = -HUGE_VAL; + if (_LIB_VERSION == _POSIX_) + *err = EDOM; + else if (!fd_matherr(&exc)) { + if (_LIB_VERSION == _SVID_) { + (void) WRITE2("log: DOMAIN error\n", 18); + } + *err = EDOM; + } + break; + case 18: + /* log10(0) */ + exc.type = SING; + exc.name = "log10"; + if (_LIB_VERSION == _SVID_) + exc.retval = -HUGE; + else + exc.retval = -HUGE_VAL; + if (_LIB_VERSION == _POSIX_) + *err = ERANGE; + else if (!fd_matherr(&exc)) { + if (_LIB_VERSION == _SVID_) { + (void) WRITE2("log10: SING error\n", 18); + } + *err = EDOM; + } + break; + case 19: + /* log10(x<0) */ + exc.type = DOMAIN; + exc.name = "log10"; + if (_LIB_VERSION == _SVID_) + exc.retval = -HUGE; + else + exc.retval = -HUGE_VAL; + if (_LIB_VERSION == _POSIX_) + *err = EDOM; + else if (!fd_matherr(&exc)) { + if (_LIB_VERSION == _SVID_) { + (void) WRITE2("log10: DOMAIN error\n", 20); + } + *err = EDOM; + } + break; + case 20: + /* pow(0.0,0.0) */ + /* error only if _LIB_VERSION == _SVID_ */ + exc.type = DOMAIN; + exc.name = "pow"; + exc.retval = zero; + if (_LIB_VERSION != _SVID_) exc.retval = 1.0; + else if (!fd_matherr(&exc)) { + (void) WRITE2("pow(0,0): DOMAIN error\n", 23); + *err = EDOM; + } + break; + case 21: + /* pow(x,y) overflow */ + exc.type = OVERFLOW; + exc.name = "pow"; + if (_LIB_VERSION == _SVID_) { + exc.retval = HUGE; + y *= 0.5; + if(xzero) ? HUGE : -HUGE); + else + exc.retval = ( (x>zero) ? HUGE_VAL : -HUGE_VAL); + if (_LIB_VERSION == _POSIX_) + *err = ERANGE; + else if (!fd_matherr(&exc)) { + *err = ERANGE; + } + break; + case 26: + /* sqrt(x<0) */ + exc.type = DOMAIN; + exc.name = "sqrt"; + if (_LIB_VERSION == _SVID_) + exc.retval = zero; + else + exc.retval = zero/zero; + if (_LIB_VERSION == _POSIX_) + *err = EDOM; + else if (!fd_matherr(&exc)) { + if (_LIB_VERSION == _SVID_) { + (void) WRITE2("sqrt: DOMAIN error\n", 19); + } + *err = EDOM; + } + break; + case 27: + /* fmod(x,0) */ + exc.type = DOMAIN; + exc.name = "fmod"; + if (_LIB_VERSION == _SVID_) + exc.retval = x; + else + exc.retval = zero/zero; + if (_LIB_VERSION == _POSIX_) + *err = EDOM; + else if (!fd_matherr(&exc)) { + if (_LIB_VERSION == _SVID_) { + (void) WRITE2("fmod: DOMAIN error\n", 20); + } + *err = EDOM; + } + break; + case 28: + /* remainder(x,0) */ + exc.type = DOMAIN; + exc.name = "remainder"; + exc.retval = zero/zero; + if (_LIB_VERSION == _POSIX_) + *err = EDOM; + else if (!fd_matherr(&exc)) { + if (_LIB_VERSION == _SVID_) { + (void) WRITE2("remainder: DOMAIN error\n", 24); + } + *err = EDOM; + } + break; + case 29: + /* acosh(x<1) */ + exc.type = DOMAIN; + exc.name = "acosh"; + exc.retval = zero/zero; + if (_LIB_VERSION == _POSIX_) + *err = EDOM; + else if (!fd_matherr(&exc)) { + if (_LIB_VERSION == _SVID_) { + (void) WRITE2("acosh: DOMAIN error\n", 20); + } + *err = EDOM; + } + break; + case 30: + /* atanh(|x|>1) */ + exc.type = DOMAIN; + exc.name = "atanh"; + exc.retval = zero/zero; + if (_LIB_VERSION == _POSIX_) + *err = EDOM; + else if (!fd_matherr(&exc)) { + if (_LIB_VERSION == _SVID_) { + (void) WRITE2("atanh: DOMAIN error\n", 20); + } + *err = EDOM; + } + break; + case 31: + /* atanh(|x|=1) */ + exc.type = SING; + exc.name = "atanh"; + exc.retval = x/zero; /* sign(x)*inf */ + if (_LIB_VERSION == _POSIX_) + *err = EDOM; + else if (!fd_matherr(&exc)) { + if (_LIB_VERSION == _SVID_) { + (void) WRITE2("atanh: SING error\n", 18); + } + *err = EDOM; + } + break; + case 32: + /* scalb overflow; SVID also returns +-HUGE_VAL */ + exc.type = OVERFLOW; + exc.name = "scalb"; + exc.retval = x > zero ? HUGE_VAL : -HUGE_VAL; + if (_LIB_VERSION == _POSIX_) + *err = ERANGE; + else if (!fd_matherr(&exc)) { + *err = ERANGE; + } + break; + case 33: + /* scalb underflow */ + exc.type = UNDERFLOW; + exc.name = "scalb"; + exc.retval = fd_copysign(zero,x); + if (_LIB_VERSION == _POSIX_) + *err = ERANGE; + else if (!fd_matherr(&exc)) { + *err = ERANGE; + } + break; + case 34: + /* j0(|x|>X_TLOSS) */ + exc.type = TLOSS; + exc.name = "j0"; + exc.retval = zero; + if (_LIB_VERSION == _POSIX_) + *err = ERANGE; + else if (!fd_matherr(&exc)) { + if (_LIB_VERSION == _SVID_) { + (void) WRITE2(exc.name, 2); + (void) WRITE2(": TLOSS error\n", 14); + } + *err = ERANGE; + } + break; + case 35: + /* y0(x>X_TLOSS) */ + exc.type = TLOSS; + exc.name = "y0"; + exc.retval = zero; + if (_LIB_VERSION == _POSIX_) + *err = ERANGE; + else if (!fd_matherr(&exc)) { + if (_LIB_VERSION == _SVID_) { + (void) WRITE2(exc.name, 2); + (void) WRITE2(": TLOSS error\n", 14); + } + *err = ERANGE; + } + break; + case 36: + /* j1(|x|>X_TLOSS) */ + exc.type = TLOSS; + exc.name = "j1"; + exc.retval = zero; + if (_LIB_VERSION == _POSIX_) + *err = ERANGE; + else if (!fd_matherr(&exc)) { + if (_LIB_VERSION == _SVID_) { + (void) WRITE2(exc.name, 2); + (void) WRITE2(": TLOSS error\n", 14); + } + *err = ERANGE; + } + break; + case 37: + /* y1(x>X_TLOSS) */ + exc.type = TLOSS; + exc.name = "y1"; + exc.retval = zero; + if (_LIB_VERSION == _POSIX_) + *err = ERANGE; + else if (!fd_matherr(&exc)) { + if (_LIB_VERSION == _SVID_) { + (void) WRITE2(exc.name, 2); + (void) WRITE2(": TLOSS error\n", 14); + } + *err = ERANGE; + } + break; + case 38: + /* jn(|x|>X_TLOSS) */ + exc.type = TLOSS; + exc.name = "jn"; + exc.retval = zero; + if (_LIB_VERSION == _POSIX_) + *err = ERANGE; + else if (!fd_matherr(&exc)) { + if (_LIB_VERSION == _SVID_) { + (void) WRITE2(exc.name, 2); + (void) WRITE2(": TLOSS error\n", 14); + } + *err = ERANGE; + } + break; + case 39: + /* yn(x>X_TLOSS) */ + exc.type = TLOSS; + exc.name = "yn"; + exc.retval = zero; + if (_LIB_VERSION == _POSIX_) + *err = ERANGE; + else if (!fd_matherr(&exc)) { + if (_LIB_VERSION == _SVID_) { + (void) WRITE2(exc.name, 2); + (void) WRITE2(": TLOSS error\n", 14); + } + *err = ERANGE; + } + break; + case 40: + /* gamma(finite) overflow */ + exc.type = OVERFLOW; + exc.name = "gamma"; + if (_LIB_VERSION == _SVID_) + exc.retval = HUGE; + else + exc.retval = HUGE_VAL; + if (_LIB_VERSION == _POSIX_) + *err = ERANGE; + else if (!fd_matherr(&exc)) { + *err = ERANGE; + } + break; + case 41: + /* gamma(-integer) or gamma(0) */ + exc.type = SING; + exc.name = "gamma"; + if (_LIB_VERSION == _SVID_) + exc.retval = HUGE; + else + exc.retval = HUGE_VAL; + if (_LIB_VERSION == _POSIX_) + *err = EDOM; + else if (!fd_matherr(&exc)) { + if (_LIB_VERSION == _SVID_) { + (void) WRITE2("gamma: SING error\n", 18); + } + *err = EDOM; + } + break; + case 42: + /* pow(NaN,0.0) */ + /* error only if _LIB_VERSION == _SVID_ & _XOPEN_ */ + exc.type = DOMAIN; + exc.name = "pow"; + exc.retval = x; + if (_LIB_VERSION == _IEEE_ || + _LIB_VERSION == _POSIX_) exc.retval = 1.0; + else if (!fd_matherr(&exc)) { + *err = EDOM; + } + break; + } + return exc.retval; +} diff --git a/src/dom/js/fdlibm/k_tan.c b/src/dom/js/fdlibm/k_tan.c new file mode 100644 index 000000000..1e7681b88 --- /dev/null +++ b/src/dom/js/fdlibm/k_tan.c @@ -0,0 +1,170 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Sun Microsystems, Inc. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* @(#)k_tan.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* __kernel_tan( x, y, k ) + * kernel tan function on [-pi/4, pi/4], pi/4 ~ 0.7854 + * Input x is assumed to be bounded by ~pi/4 in magnitude. + * Input y is the tail of x. + * Input k indicates whether tan (if k=1) or + * -1/tan (if k= -1) is returned. + * + * Algorithm + * 1. Since tan(-x) = -tan(x), we need only to consider positive x. + * 2. if x < 2^-28 (hx<0x3e300000 0), return x with inexact if x!=0. + * 3. tan(x) is approximated by a odd polynomial of degree 27 on + * [0,0.67434] + * 3 27 + * tan(x) ~ x + T1*x + ... + T13*x + * where + * + * |tan(x) 2 4 26 | -59.2 + * |----- - (1+T1*x +T2*x +.... +T13*x )| <= 2 + * | x | + * + * Note: tan(x+y) = tan(x) + tan'(x)*y + * ~ tan(x) + (1+x*x)*y + * Therefore, for better accuracy in computing tan(x+y), let + * 3 2 2 2 2 + * r = x *(T2+x *(T3+x *(...+x *(T12+x *T13)))) + * then + * 3 2 + * tan(x+y) = x + (T1*x + (x *(r+y)+y)) + * + * 4. For x in [0.67434,pi/4], let y = pi/4 - x, then + * tan(x) = tan(pi/4-y) = (1-tan(y))/(1+tan(y)) + * = 1 - 2*(tan(y) - (tan(y)^2)/(1+tan(y))) + */ + +#include "fdlibm.h" +#ifdef __STDC__ +static const double +#else +static double +#endif +one = 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */ +pio4 = 7.85398163397448278999e-01, /* 0x3FE921FB, 0x54442D18 */ +pio4lo= 3.06161699786838301793e-17, /* 0x3C81A626, 0x33145C07 */ +T[] = { + 3.33333333333334091986e-01, /* 0x3FD55555, 0x55555563 */ + 1.33333333333201242699e-01, /* 0x3FC11111, 0x1110FE7A */ + 5.39682539762260521377e-02, /* 0x3FABA1BA, 0x1BB341FE */ + 2.18694882948595424599e-02, /* 0x3F9664F4, 0x8406D637 */ + 8.86323982359930005737e-03, /* 0x3F8226E3, 0xE96E8493 */ + 3.59207910759131235356e-03, /* 0x3F6D6D22, 0xC9560328 */ + 1.45620945432529025516e-03, /* 0x3F57DBC8, 0xFEE08315 */ + 5.88041240820264096874e-04, /* 0x3F4344D8, 0xF2F26501 */ + 2.46463134818469906812e-04, /* 0x3F3026F7, 0x1A8D1068 */ + 7.81794442939557092300e-05, /* 0x3F147E88, 0xA03792A6 */ + 7.14072491382608190305e-05, /* 0x3F12B80F, 0x32F0A7E9 */ + -1.85586374855275456654e-05, /* 0xBEF375CB, 0xDB605373 */ + 2.59073051863633712884e-05, /* 0x3EFB2A70, 0x74BF7AD4 */ +}; + +#ifdef __STDC__ + double __kernel_tan(double x, double y, int iy) +#else + double __kernel_tan(x, y, iy) + double x,y; int iy; +#endif +{ + fd_twoints u; + double z,r,v,w,s; + int ix,hx; + u.d = x; + hx = __HI(u); /* high word of x */ + ix = hx&0x7fffffff; /* high word of |x| */ + if(ix<0x3e300000) /* x < 2**-28 */ + {if((int)x==0) { /* generate inexact */ + u.d =x; + if(((ix|__LO(u))|(iy+1))==0) return one/fd_fabs(x); + else return (iy==1)? x: -one/x; + } + } + if(ix>=0x3FE59428) { /* |x|>=0.6744 */ + if(hx<0) {x = -x; y = -y;} + z = pio4-x; + w = pio4lo-y; + x = z+w; y = 0.0; + } + z = x*x; + w = z*z; + /* Break x^5*(T[1]+x^2*T[2]+...) into + * x^5(T[1]+x^4*T[3]+...+x^20*T[11]) + + * x^5(x^2*(T[2]+x^4*T[4]+...+x^22*[T12])) + */ + r = T[1]+w*(T[3]+w*(T[5]+w*(T[7]+w*(T[9]+w*T[11])))); + v = z*(T[2]+w*(T[4]+w*(T[6]+w*(T[8]+w*(T[10]+w*T[12]))))); + s = z*x; + r = y + z*(s*(r+v)+y); + r += T[0]*s; + w = x+r; + if(ix>=0x3FE59428) { + v = (double)iy; + return (double)(1-((hx>>30)&2))*(v-2.0*(x-(w*w/(w+v)-r))); + } + if(iy==1) return w; + else { /* if allow error up to 2 ulp, + simply return -1.0/(x+r) here */ + /* compute -1.0/(x+r) accurately */ + double a,t; + z = w; + u.d = z; + __LO(u) = 0; + z = u.d; + v = r-(z - x); /* z+v = r+x */ + t = a = -1.0/w; /* a = -1.0/w */ + u.d = t; + __LO(u) = 0; + t = u.d; + s = 1.0+t*z; + return t+a*(s+t*v); + } +} diff --git a/src/dom/js/fdlibm/s_asinh.c b/src/dom/js/fdlibm/s_asinh.c new file mode 100644 index 000000000..fdf70a91c --- /dev/null +++ b/src/dom/js/fdlibm/s_asinh.c @@ -0,0 +1,101 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Sun Microsystems, Inc. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* @(#)s_asinh.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* asinh(x) + * Method : + * Based on + * asinh(x) = sign(x) * log [ |x| + sqrt(x*x+1) ] + * we have + * asinh(x) := x if 1+x*x=1, + * := sign(x)*(log(x)+ln2)) for large |x|, else + * := sign(x)*log(2|x|+1/(|x|+sqrt(x*x+1))) if|x|>2, else + * := sign(x)*log1p(|x| + x^2/(1 + sqrt(1+x^2))) + */ + +#include "fdlibm.h" + +#ifdef __STDC__ +static const double +#else +static double +#endif +one = 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */ +ln2 = 6.93147180559945286227e-01, /* 0x3FE62E42, 0xFEFA39EF */ +really_big= 1.00000000000000000000e+300; + +#ifdef __STDC__ + double fd_asinh(double x) +#else + double fd_asinh(x) + double x; +#endif +{ + fd_twoints u; + double t,w; + int hx,ix; + u.d = x; + hx = __HI(u); + ix = hx&0x7fffffff; + if(ix>=0x7ff00000) return x+x; /* x is inf or NaN */ + if(ix< 0x3e300000) { /* |x|<2**-28 */ + if(really_big+x>one) return x; /* return x inexact except 0 */ + } + if(ix>0x41b00000) { /* |x| > 2**28 */ + w = __ieee754_log(fd_fabs(x))+ln2; + } else if (ix>0x40000000) { /* 2**28 > |x| > 2.0 */ + t = fd_fabs(x); + w = __ieee754_log(2.0*t+one/(fd_sqrt(x*x+one)+t)); + } else { /* 2.0 > |x| > 2**-28 */ + t = x*x; + w =fd_log1p(fd_fabs(x)+t/(one+fd_sqrt(one+t))); + } + if(hx>0) return w; else return -w; +} diff --git a/src/dom/js/fdlibm/s_atan.c b/src/dom/js/fdlibm/s_atan.c new file mode 100644 index 000000000..99a00c686 --- /dev/null +++ b/src/dom/js/fdlibm/s_atan.c @@ -0,0 +1,175 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Sun Microsystems, Inc. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* @(#)s_atan.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + * + */ + +/* atan(x) + * Method + * 1. Reduce x to positive by atan(x) = -atan(-x). + * 2. According to the integer k=4t+0.25 chopped, t=x, the argument + * is further reduced to one of the following intervals and the + * arctangent of t is evaluated by the corresponding formula: + * + * [0,7/16] atan(x) = t-t^3*(a1+t^2*(a2+...(a10+t^2*a11)...) + * [7/16,11/16] atan(x) = atan(1/2) + atan( (t-0.5)/(1+t/2) ) + * [11/16.19/16] atan(x) = atan( 1 ) + atan( (t-1)/(1+t) ) + * [19/16,39/16] atan(x) = atan(3/2) + atan( (t-1.5)/(1+1.5t) ) + * [39/16,INF] atan(x) = atan(INF) + atan( -1/t ) + * + * Constants: + * The hexadecimal values are the intended ones for the following + * constants. The decimal values may be used, provided that the + * compiler will convert from decimal to binary accurately enough + * to produce the hexadecimal values shown. + */ + +#include "fdlibm.h" + +#ifdef __STDC__ +static const double atanhi[] = { +#else +static double atanhi[] = { +#endif + 4.63647609000806093515e-01, /* atan(0.5)hi 0x3FDDAC67, 0x0561BB4F */ + 7.85398163397448278999e-01, /* atan(1.0)hi 0x3FE921FB, 0x54442D18 */ + 9.82793723247329054082e-01, /* atan(1.5)hi 0x3FEF730B, 0xD281F69B */ + 1.57079632679489655800e+00, /* atan(inf)hi 0x3FF921FB, 0x54442D18 */ +}; + +#ifdef __STDC__ +static const double atanlo[] = { +#else +static double atanlo[] = { +#endif + 2.26987774529616870924e-17, /* atan(0.5)lo 0x3C7A2B7F, 0x222F65E2 */ + 3.06161699786838301793e-17, /* atan(1.0)lo 0x3C81A626, 0x33145C07 */ + 1.39033110312309984516e-17, /* atan(1.5)lo 0x3C700788, 0x7AF0CBBD */ + 6.12323399573676603587e-17, /* atan(inf)lo 0x3C91A626, 0x33145C07 */ +}; + +#ifdef __STDC__ +static const double aT[] = { +#else +static double aT[] = { +#endif + 3.33333333333329318027e-01, /* 0x3FD55555, 0x5555550D */ + -1.99999999998764832476e-01, /* 0xBFC99999, 0x9998EBC4 */ + 1.42857142725034663711e-01, /* 0x3FC24924, 0x920083FF */ + -1.11111104054623557880e-01, /* 0xBFBC71C6, 0xFE231671 */ + 9.09088713343650656196e-02, /* 0x3FB745CD, 0xC54C206E */ + -7.69187620504482999495e-02, /* 0xBFB3B0F2, 0xAF749A6D */ + 6.66107313738753120669e-02, /* 0x3FB10D66, 0xA0D03D51 */ + -5.83357013379057348645e-02, /* 0xBFADDE2D, 0x52DEFD9A */ + 4.97687799461593236017e-02, /* 0x3FA97B4B, 0x24760DEB */ + -3.65315727442169155270e-02, /* 0xBFA2B444, 0x2C6A6C2F */ + 1.62858201153657823623e-02, /* 0x3F90AD3A, 0xE322DA11 */ +}; + +#ifdef __STDC__ + static const double +#else + static double +#endif +one = 1.0, +really_big = 1.0e300; + +#ifdef __STDC__ + double fd_atan(double x) +#else + double fd_atan(x) + double x; +#endif +{ + fd_twoints u; + double w,s1,s2,z; + int ix,hx,id; + + u.d = x; + hx = __HI(u); + ix = hx&0x7fffffff; + if(ix>=0x44100000) { /* if |x| >= 2^66 */ + u.d = x; + if(ix>0x7ff00000|| + (ix==0x7ff00000&&(__LO(u)!=0))) + return x+x; /* NaN */ + if(hx>0) return atanhi[3]+atanlo[3]; + else return -atanhi[3]-atanlo[3]; + } if (ix < 0x3fdc0000) { /* |x| < 0.4375 */ + if (ix < 0x3e200000) { /* |x| < 2^-29 */ + if(really_big+x>one) return x; /* raise inexact */ + } + id = -1; + } else { + x = fd_fabs(x); + if (ix < 0x3ff30000) { /* |x| < 1.1875 */ + if (ix < 0x3fe60000) { /* 7/16 <=|x|<11/16 */ + id = 0; x = (2.0*x-one)/(2.0+x); + } else { /* 11/16<=|x|< 19/16 */ + id = 1; x = (x-one)/(x+one); + } + } else { + if (ix < 0x40038000) { /* |x| < 2.4375 */ + id = 2; x = (x-1.5)/(one+1.5*x); + } else { /* 2.4375 <= |x| < 2^66 */ + id = 3; x = -1.0/x; + } + }} + /* end of argument reduction */ + z = x*x; + w = z*z; + /* break sum from i=0 to 10 aT[i]z**(i+1) into odd and even poly */ + s1 = z*(aT[0]+w*(aT[2]+w*(aT[4]+w*(aT[6]+w*(aT[8]+w*aT[10]))))); + s2 = w*(aT[1]+w*(aT[3]+w*(aT[5]+w*(aT[7]+w*aT[9])))); + if (id<0) return x - x*(s1+s2); + else { + z = atanhi[id] - ((x*(s1+s2) - atanlo[id]) - x); + return (hx<0)? -z:z; + } +} diff --git a/src/dom/js/fdlibm/s_cbrt.c b/src/dom/js/fdlibm/s_cbrt.c new file mode 100644 index 000000000..4aed19b1b --- /dev/null +++ b/src/dom/js/fdlibm/s_cbrt.c @@ -0,0 +1,133 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Sun Microsystems, Inc. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* @(#)s_cbrt.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + * + */ + +#include "fdlibm.h" + +/* cbrt(x) + * Return cube root of x + */ +#ifdef __STDC__ +static const unsigned +#else +static unsigned +#endif + B1 = 715094163, /* B1 = (682-0.03306235651)*2**20 */ + B2 = 696219795; /* B2 = (664-0.03306235651)*2**20 */ + +#ifdef __STDC__ +static const double +#else +static double +#endif +C = 5.42857142857142815906e-01, /* 19/35 = 0x3FE15F15, 0xF15F15F1 */ +D = -7.05306122448979611050e-01, /* -864/1225 = 0xBFE691DE, 0x2532C834 */ +E = 1.41428571428571436819e+00, /* 99/70 = 0x3FF6A0EA, 0x0EA0EA0F */ +F = 1.60714285714285720630e+00, /* 45/28 = 0x3FF9B6DB, 0x6DB6DB6E */ +G = 3.57142857142857150787e-01; /* 5/14 = 0x3FD6DB6D, 0xB6DB6DB7 */ + +#ifdef __STDC__ + double fd_cbrt(double x) +#else + double fd_cbrt(x) + double x; +#endif +{ + fd_twoints u; + int hx; + double r,s,t=0.0,w; + unsigned sign; + + u.d = x; + hx = __HI(u); /* high word of x */ + sign=hx&0x80000000; /* sign= sign(x) */ + hx ^=sign; + if(hx>=0x7ff00000) return(x+x); /* cbrt(NaN,INF) is itself */ + if((hx|__LO(u))==0) { + x = u.d; + return(x); /* cbrt(0) is itself */ + } + u.d = x; + __HI(u) = hx; /* x <- |x| */ + x = u.d; + /* rough cbrt to 5 bits */ + if(hx<0x00100000) /* subnormal number */ + {u.d = t; __HI(u)=0x43500000; t=u.d; /* set t= 2**54 */ + t*=x; __HI(u)=__HI(u)/3+B2; + } + else { + u.d = t; __HI(u)=hx/3+B1; t = u.d; + } + + + /* new cbrt to 23 bits, may be implemented in single precision */ + r=t*t/x; + s=C+r*t; + t*=G+F/(s+E+D/s); + + /* chopped to 20 bits and make it larger than cbrt(x) */ + u.d = t; + __LO(u)=0; __HI(u)+=0x00000001; + t = u.d; + + /* one step newton iteration to 53 bits with error less than 0.667 ulps */ + s=t*t; /* t*t is exact */ + r=x/s; + w=t+t; + r=(r-t)/(w+r); /* r-s is exact */ + t=t+t*r; + + /* retore the sign bit */ + u.d = t; + __HI(u) |= sign; + t = u.d; + return(t); +} diff --git a/src/dom/js/fdlibm/s_ceil.c b/src/dom/js/fdlibm/s_ceil.c new file mode 100644 index 000000000..826bcac6c --- /dev/null +++ b/src/dom/js/fdlibm/s_ceil.c @@ -0,0 +1,120 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Sun Microsystems, Inc. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* @(#)s_ceil.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * ceil(x) + * Return x rounded toward -inf to integral value + * Method: + * Bit twiddling. + * Exception: + * Inexact flag raised if x not equal to ceil(x). + */ + +#include "fdlibm.h" + +#ifdef __STDC__ +static const double really_big = 1.0e300; +#else +static double really_big = 1.0e300; +#endif + +#ifdef __STDC__ + double fd_ceil(double x) +#else + double fd_ceil(x) + double x; +#endif +{ + fd_twoints u; + int i0,i1,j0; + unsigned i,j; + u.d = x; + i0 = __HI(u); + i1 = __LO(u); + j0 = ((i0>>20)&0x7ff)-0x3ff; + if(j0<20) { + if(j0<0) { /* raise inexact if x != 0 */ + if(really_big+x>0.0) {/* return 0*sign(x) if |x|<1 */ + if(i0<0) {i0=0x80000000;i1=0;} + else if((i0|i1)!=0) { i0=0x3ff00000;i1=0;} + } + } else { + i = (0x000fffff)>>j0; + if(((i0&i)|i1)==0) return x; /* x is integral */ + if(really_big+x>0.0) { /* raise inexact flag */ + if(i0>0) i0 += (0x00100000)>>j0; + i0 &= (~i); i1=0; + } + } + } else if (j0>51) { + if(j0==0x400) return x+x; /* inf or NaN */ + else return x; /* x is integral */ + } else { + i = ((unsigned)(0xffffffff))>>(j0-20); + if((i1&i)==0) return x; /* x is integral */ + if(really_big+x>0.0) { /* raise inexact flag */ + if(i0>0) { + if(j0==20) i0+=1; + else { + j = i1 + (1<<(52-j0)); + if((int)j=0x7ff00000) return x-x; + + /* argument reduction needed */ + else { + n = __ieee754_rem_pio2(x,y); + switch(n&3) { + case 0: return __kernel_cos(y[0],y[1]); + case 1: return -__kernel_sin(y[0],y[1],1); + case 2: return -__kernel_cos(y[0],y[1]); + default: + return __kernel_sin(y[0],y[1],1); + } + } +} diff --git a/src/dom/js/fdlibm/s_erf.c b/src/dom/js/fdlibm/s_erf.c new file mode 100644 index 000000000..6eae8de3b --- /dev/null +++ b/src/dom/js/fdlibm/s_erf.c @@ -0,0 +1,356 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Sun Microsystems, Inc. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* @(#)s_erf.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* double erf(double x) + * double erfc(double x) + * x + * 2 |\ + * erf(x) = --------- | exp(-t*t)dt + * sqrt(pi) \| + * 0 + * + * erfc(x) = 1-erf(x) + * Note that + * erf(-x) = -erf(x) + * erfc(-x) = 2 - erfc(x) + * + * Method: + * 1. For |x| in [0, 0.84375] + * erf(x) = x + x*R(x^2) + * erfc(x) = 1 - erf(x) if x in [-.84375,0.25] + * = 0.5 + ((0.5-x)-x*R) if x in [0.25,0.84375] + * where R = P/Q where P is an odd poly of degree 8 and + * Q is an odd poly of degree 10. + * -57.90 + * | R - (erf(x)-x)/x | <= 2 + * + * + * Remark. The formula is derived by noting + * erf(x) = (2/sqrt(pi))*(x - x^3/3 + x^5/10 - x^7/42 + ....) + * and that + * 2/sqrt(pi) = 1.128379167095512573896158903121545171688 + * is close to one. The interval is chosen because the fix + * point of erf(x) is near 0.6174 (i.e., erf(x)=x when x is + * near 0.6174), and by some experiment, 0.84375 is chosen to + * guarantee the error is less than one ulp for erf. + * + * 2. For |x| in [0.84375,1.25], let s = |x| - 1, and + * c = 0.84506291151 rounded to single (24 bits) + * erf(x) = sign(x) * (c + P1(s)/Q1(s)) + * erfc(x) = (1-c) - P1(s)/Q1(s) if x > 0 + * 1+(c+P1(s)/Q1(s)) if x < 0 + * |P1/Q1 - (erf(|x|)-c)| <= 2**-59.06 + * Remark: here we use the taylor series expansion at x=1. + * erf(1+s) = erf(1) + s*Poly(s) + * = 0.845.. + P1(s)/Q1(s) + * That is, we use rational approximation to approximate + * erf(1+s) - (c = (single)0.84506291151) + * Note that |P1/Q1|< 0.078 for x in [0.84375,1.25] + * where + * P1(s) = degree 6 poly in s + * Q1(s) = degree 6 poly in s + * + * 3. For x in [1.25,1/0.35(~2.857143)], + * erfc(x) = (1/x)*exp(-x*x-0.5625+R1/S1) + * erf(x) = 1 - erfc(x) + * where + * R1(z) = degree 7 poly in z, (z=1/x^2) + * S1(z) = degree 8 poly in z + * + * 4. For x in [1/0.35,28] + * erfc(x) = (1/x)*exp(-x*x-0.5625+R2/S2) if x > 0 + * = 2.0 - (1/x)*exp(-x*x-0.5625+R2/S2) if -6 x >= 28 + * erf(x) = sign(x) *(1 - tiny) (raise inexact) + * erfc(x) = tiny*tiny (raise underflow) if x > 0 + * = 2 - tiny if x<0 + * + * 7. Special case: + * erf(0) = 0, erf(inf) = 1, erf(-inf) = -1, + * erfc(0) = 1, erfc(inf) = 0, erfc(-inf) = 2, + * erfc/erf(NaN) is NaN + */ + + +#include "fdlibm.h" + +#ifdef __STDC__ +static const double +#else +static double +#endif +tiny = 1e-300, +half= 5.00000000000000000000e-01, /* 0x3FE00000, 0x00000000 */ +one = 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */ +two = 2.00000000000000000000e+00, /* 0x40000000, 0x00000000 */ + /* c = (float)0.84506291151 */ +erx = 8.45062911510467529297e-01, /* 0x3FEB0AC1, 0x60000000 */ +/* + * Coefficients for approximation to erf on [0,0.84375] + */ +efx = 1.28379167095512586316e-01, /* 0x3FC06EBA, 0x8214DB69 */ +efx8= 1.02703333676410069053e+00, /* 0x3FF06EBA, 0x8214DB69 */ +pp0 = 1.28379167095512558561e-01, /* 0x3FC06EBA, 0x8214DB68 */ +pp1 = -3.25042107247001499370e-01, /* 0xBFD4CD7D, 0x691CB913 */ +pp2 = -2.84817495755985104766e-02, /* 0xBF9D2A51, 0xDBD7194F */ +pp3 = -5.77027029648944159157e-03, /* 0xBF77A291, 0x236668E4 */ +pp4 = -2.37630166566501626084e-05, /* 0xBEF8EAD6, 0x120016AC */ +qq1 = 3.97917223959155352819e-01, /* 0x3FD97779, 0xCDDADC09 */ +qq2 = 6.50222499887672944485e-02, /* 0x3FB0A54C, 0x5536CEBA */ +qq3 = 5.08130628187576562776e-03, /* 0x3F74D022, 0xC4D36B0F */ +qq4 = 1.32494738004321644526e-04, /* 0x3F215DC9, 0x221C1A10 */ +qq5 = -3.96022827877536812320e-06, /* 0xBED09C43, 0x42A26120 */ +/* + * Coefficients for approximation to erf in [0.84375,1.25] + */ +pa0 = -2.36211856075265944077e-03, /* 0xBF6359B8, 0xBEF77538 */ +pa1 = 4.14856118683748331666e-01, /* 0x3FDA8D00, 0xAD92B34D */ +pa2 = -3.72207876035701323847e-01, /* 0xBFD7D240, 0xFBB8C3F1 */ +pa3 = 3.18346619901161753674e-01, /* 0x3FD45FCA, 0x805120E4 */ +pa4 = -1.10894694282396677476e-01, /* 0xBFBC6398, 0x3D3E28EC */ +pa5 = 3.54783043256182359371e-02, /* 0x3FA22A36, 0x599795EB */ +pa6 = -2.16637559486879084300e-03, /* 0xBF61BF38, 0x0A96073F */ +qa1 = 1.06420880400844228286e-01, /* 0x3FBB3E66, 0x18EEE323 */ +qa2 = 5.40397917702171048937e-01, /* 0x3FE14AF0, 0x92EB6F33 */ +qa3 = 7.18286544141962662868e-02, /* 0x3FB2635C, 0xD99FE9A7 */ +qa4 = 1.26171219808761642112e-01, /* 0x3FC02660, 0xE763351F */ +qa5 = 1.36370839120290507362e-02, /* 0x3F8BEDC2, 0x6B51DD1C */ +qa6 = 1.19844998467991074170e-02, /* 0x3F888B54, 0x5735151D */ +/* + * Coefficients for approximation to erfc in [1.25,1/0.35] + */ +ra0 = -9.86494403484714822705e-03, /* 0xBF843412, 0x600D6435 */ +ra1 = -6.93858572707181764372e-01, /* 0xBFE63416, 0xE4BA7360 */ +ra2 = -1.05586262253232909814e+01, /* 0xC0251E04, 0x41B0E726 */ +ra3 = -6.23753324503260060396e+01, /* 0xC04F300A, 0xE4CBA38D */ +ra4 = -1.62396669462573470355e+02, /* 0xC0644CB1, 0x84282266 */ +ra5 = -1.84605092906711035994e+02, /* 0xC067135C, 0xEBCCABB2 */ +ra6 = -8.12874355063065934246e+01, /* 0xC0545265, 0x57E4D2F2 */ +ra7 = -9.81432934416914548592e+00, /* 0xC023A0EF, 0xC69AC25C */ +sa1 = 1.96512716674392571292e+01, /* 0x4033A6B9, 0xBD707687 */ +sa2 = 1.37657754143519042600e+02, /* 0x4061350C, 0x526AE721 */ +sa3 = 4.34565877475229228821e+02, /* 0x407B290D, 0xD58A1A71 */ +sa4 = 6.45387271733267880336e+02, /* 0x40842B19, 0x21EC2868 */ +sa5 = 4.29008140027567833386e+02, /* 0x407AD021, 0x57700314 */ +sa6 = 1.08635005541779435134e+02, /* 0x405B28A3, 0xEE48AE2C */ +sa7 = 6.57024977031928170135e+00, /* 0x401A47EF, 0x8E484A93 */ +sa8 = -6.04244152148580987438e-02, /* 0xBFAEEFF2, 0xEE749A62 */ +/* + * Coefficients for approximation to erfc in [1/.35,28] + */ +rb0 = -9.86494292470009928597e-03, /* 0xBF843412, 0x39E86F4A */ +rb1 = -7.99283237680523006574e-01, /* 0xBFE993BA, 0x70C285DE */ +rb2 = -1.77579549177547519889e+01, /* 0xC031C209, 0x555F995A */ +rb3 = -1.60636384855821916062e+02, /* 0xC064145D, 0x43C5ED98 */ +rb4 = -6.37566443368389627722e+02, /* 0xC083EC88, 0x1375F228 */ +rb5 = -1.02509513161107724954e+03, /* 0xC0900461, 0x6A2E5992 */ +rb6 = -4.83519191608651397019e+02, /* 0xC07E384E, 0x9BDC383F */ +sb1 = 3.03380607434824582924e+01, /* 0x403E568B, 0x261D5190 */ +sb2 = 3.25792512996573918826e+02, /* 0x40745CAE, 0x221B9F0A */ +sb3 = 1.53672958608443695994e+03, /* 0x409802EB, 0x189D5118 */ +sb4 = 3.19985821950859553908e+03, /* 0x40A8FFB7, 0x688C246A */ +sb5 = 2.55305040643316442583e+03, /* 0x40A3F219, 0xCEDF3BE6 */ +sb6 = 4.74528541206955367215e+02, /* 0x407DA874, 0xE79FE763 */ +sb7 = -2.24409524465858183362e+01; /* 0xC03670E2, 0x42712D62 */ + +#ifdef __STDC__ + double fd_erf(double x) +#else + double fd_erf(x) + double x; +#endif +{ + fd_twoints u; + int hx,ix,i; + double R,S,P,Q,s,y,z,r; + u.d = x; + hx = __HI(u); + ix = hx&0x7fffffff; + if(ix>=0x7ff00000) { /* erf(nan)=nan */ + i = ((unsigned)hx>>31)<<1; + return (double)(1-i)+one/x; /* erf(+-inf)=+-1 */ + } + + if(ix < 0x3feb0000) { /* |x|<0.84375 */ + if(ix < 0x3e300000) { /* |x|<2**-28 */ + if (ix < 0x00800000) + return 0.125*(8.0*x+efx8*x); /*avoid underflow */ + return x + efx*x; + } + z = x*x; + r = pp0+z*(pp1+z*(pp2+z*(pp3+z*pp4))); + s = one+z*(qq1+z*(qq2+z*(qq3+z*(qq4+z*qq5)))); + y = r/s; + return x + x*y; + } + if(ix < 0x3ff40000) { /* 0.84375 <= |x| < 1.25 */ + s = fd_fabs(x)-one; + P = pa0+s*(pa1+s*(pa2+s*(pa3+s*(pa4+s*(pa5+s*pa6))))); + Q = one+s*(qa1+s*(qa2+s*(qa3+s*(qa4+s*(qa5+s*qa6))))); + if(hx>=0) return erx + P/Q; else return -erx - P/Q; + } + if (ix >= 0x40180000) { /* inf>|x|>=6 */ + if(hx>=0) return one-tiny; else return tiny-one; + } + x = fd_fabs(x); + s = one/(x*x); + if(ix< 0x4006DB6E) { /* |x| < 1/0.35 */ + R=ra0+s*(ra1+s*(ra2+s*(ra3+s*(ra4+s*( + ra5+s*(ra6+s*ra7)))))); + S=one+s*(sa1+s*(sa2+s*(sa3+s*(sa4+s*( + sa5+s*(sa6+s*(sa7+s*sa8))))))); + } else { /* |x| >= 1/0.35 */ + R=rb0+s*(rb1+s*(rb2+s*(rb3+s*(rb4+s*( + rb5+s*rb6))))); + S=one+s*(sb1+s*(sb2+s*(sb3+s*(sb4+s*( + sb5+s*(sb6+s*sb7)))))); + } + z = x; + u.d = z; + __LO(u) = 0; + z = u.d; + r = __ieee754_exp(-z*z-0.5625)*__ieee754_exp((z-x)*(z+x)+R/S); + if(hx>=0) return one-r/x; else return r/x-one; +} + +#ifdef __STDC__ + double erfc(double x) +#else + double erfc(x) + double x; +#endif +{ + fd_twoints u; + int hx,ix; + double R,S,P,Q,s,y,z,r; + u.d = x; + hx = __HI(u); + ix = hx&0x7fffffff; + if(ix>=0x7ff00000) { /* erfc(nan)=nan */ + /* erfc(+-inf)=0,2 */ + return (double)(((unsigned)hx>>31)<<1)+one/x; + } + + if(ix < 0x3feb0000) { /* |x|<0.84375 */ + if(ix < 0x3c700000) /* |x|<2**-56 */ + return one-x; + z = x*x; + r = pp0+z*(pp1+z*(pp2+z*(pp3+z*pp4))); + s = one+z*(qq1+z*(qq2+z*(qq3+z*(qq4+z*qq5)))); + y = r/s; + if(hx < 0x3fd00000) { /* x<1/4 */ + return one-(x+x*y); + } else { + r = x*y; + r += (x-half); + return half - r ; + } + } + if(ix < 0x3ff40000) { /* 0.84375 <= |x| < 1.25 */ + s = fd_fabs(x)-one; + P = pa0+s*(pa1+s*(pa2+s*(pa3+s*(pa4+s*(pa5+s*pa6))))); + Q = one+s*(qa1+s*(qa2+s*(qa3+s*(qa4+s*(qa5+s*qa6))))); + if(hx>=0) { + z = one-erx; return z - P/Q; + } else { + z = erx+P/Q; return one+z; + } + } + if (ix < 0x403c0000) { /* |x|<28 */ + x = fd_fabs(x); + s = one/(x*x); + if(ix< 0x4006DB6D) { /* |x| < 1/.35 ~ 2.857143*/ + R=ra0+s*(ra1+s*(ra2+s*(ra3+s*(ra4+s*( + ra5+s*(ra6+s*ra7)))))); + S=one+s*(sa1+s*(sa2+s*(sa3+s*(sa4+s*( + sa5+s*(sa6+s*(sa7+s*sa8))))))); + } else { /* |x| >= 1/.35 ~ 2.857143 */ + if(hx<0&&ix>=0x40180000) return two-tiny;/* x < -6 */ + R=rb0+s*(rb1+s*(rb2+s*(rb3+s*(rb4+s*( + rb5+s*rb6))))); + S=one+s*(sb1+s*(sb2+s*(sb3+s*(sb4+s*( + sb5+s*(sb6+s*sb7)))))); + } + z = x; + u.d = z; + __LO(u) = 0; + z = u.d; + r = __ieee754_exp(-z*z-0.5625)* + __ieee754_exp((z-x)*(z+x)+R/S); + if(hx>0) return r/x; else return two-r/x; + } else { + if(hx>0) return tiny*tiny; else return two-tiny; + } +} diff --git a/src/dom/js/fdlibm/s_expm1.c b/src/dom/js/fdlibm/s_expm1.c new file mode 100644 index 000000000..578d2e144 --- /dev/null +++ b/src/dom/js/fdlibm/s_expm1.c @@ -0,0 +1,267 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Sun Microsystems, Inc. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* @(#)s_expm1.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* expm1(x) + * Returns exp(x)-1, the exponential of x minus 1. + * + * Method + * 1. Argument reduction: + * Given x, find r and integer k such that + * + * x = k*ln2 + r, |r| <= 0.5*ln2 ~ 0.34658 + * + * Here a correction term c will be computed to compensate + * the error in r when rounded to a floating-point number. + * + * 2. Approximating expm1(r) by a special rational function on + * the interval [0,0.34658]: + * Since + * r*(exp(r)+1)/(exp(r)-1) = 2+ r^2/6 - r^4/360 + ... + * we define R1(r*r) by + * r*(exp(r)+1)/(exp(r)-1) = 2+ r^2/6 * R1(r*r) + * That is, + * R1(r**2) = 6/r *((exp(r)+1)/(exp(r)-1) - 2/r) + * = 6/r * ( 1 + 2.0*(1/(exp(r)-1) - 1/r)) + * = 1 - r^2/60 + r^4/2520 - r^6/100800 + ... + * We use a special Reme algorithm on [0,0.347] to generate + * a polynomial of degree 5 in r*r to approximate R1. The + * maximum error of this polynomial approximation is bounded + * by 2**-61. In other words, + * R1(z) ~ 1.0 + Q1*z + Q2*z**2 + Q3*z**3 + Q4*z**4 + Q5*z**5 + * where Q1 = -1.6666666666666567384E-2, + * Q2 = 3.9682539681370365873E-4, + * Q3 = -9.9206344733435987357E-6, + * Q4 = 2.5051361420808517002E-7, + * Q5 = -6.2843505682382617102E-9; + * (where z=r*r, and the values of Q1 to Q5 are listed below) + * with error bounded by + * | 5 | -61 + * | 1.0+Q1*z+...+Q5*z - R1(z) | <= 2 + * | | + * + * expm1(r) = exp(r)-1 is then computed by the following + * specific way which minimize the accumulation rounding error: + * 2 3 + * r r [ 3 - (R1 + R1*r/2) ] + * expm1(r) = r + --- + --- * [--------------------] + * 2 2 [ 6 - r*(3 - R1*r/2) ] + * + * To compensate the error in the argument reduction, we use + * expm1(r+c) = expm1(r) + c + expm1(r)*c + * ~ expm1(r) + c + r*c + * Thus c+r*c will be added in as the correction terms for + * expm1(r+c). Now rearrange the term to avoid optimization + * screw up: + * ( 2 2 ) + * ({ ( r [ R1 - (3 - R1*r/2) ] ) } r ) + * expm1(r+c)~r - ({r*(--- * [--------------------]-c)-c} - --- ) + * ({ ( 2 [ 6 - r*(3 - R1*r/2) ] ) } 2 ) + * ( ) + * + * = r - E + * 3. Scale back to obtain expm1(x): + * From step 1, we have + * expm1(x) = either 2^k*[expm1(r)+1] - 1 + * = or 2^k*[expm1(r) + (1-2^-k)] + * 4. Implementation notes: + * (A). To save one multiplication, we scale the coefficient Qi + * to Qi*2^i, and replace z by (x^2)/2. + * (B). To achieve maximum accuracy, we compute expm1(x) by + * (i) if x < -56*ln2, return -1.0, (raise inexact if x!=inf) + * (ii) if k=0, return r-E + * (iii) if k=-1, return 0.5*(r-E)-0.5 + * (iv) if k=1 if r < -0.25, return 2*((r+0.5)- E) + * else return 1.0+2.0*(r-E); + * (v) if (k<-2||k>56) return 2^k(1-(E-r)) - 1 (or exp(x)-1) + * (vi) if k <= 20, return 2^k((1-2^-k)-(E-r)), else + * (vii) return 2^k(1-((E+2^-k)-r)) + * + * Special cases: + * expm1(INF) is INF, expm1(NaN) is NaN; + * expm1(-INF) is -1, and + * for finite argument, only expm1(0)=0 is exact. + * + * Accuracy: + * according to an error analysis, the error is always less than + * 1 ulp (unit in the last place). + * + * Misc. info. + * For IEEE double + * if x > 7.09782712893383973096e+02 then expm1(x) overflow + * + * Constants: + * The hexadecimal values are the intended ones for the following + * constants. The decimal values may be used, provided that the + * compiler will convert from decimal to binary accurately enough + * to produce the hexadecimal values shown. + */ + +#include "fdlibm.h" + +#ifdef __STDC__ +static const double +#else +static double +#endif +one = 1.0, +really_big = 1.0e+300, +tiny = 1.0e-300, +o_threshold = 7.09782712893383973096e+02,/* 0x40862E42, 0xFEFA39EF */ +ln2_hi = 6.93147180369123816490e-01,/* 0x3fe62e42, 0xfee00000 */ +ln2_lo = 1.90821492927058770002e-10,/* 0x3dea39ef, 0x35793c76 */ +invln2 = 1.44269504088896338700e+00,/* 0x3ff71547, 0x652b82fe */ + /* scaled coefficients related to expm1 */ +Q1 = -3.33333333333331316428e-02, /* BFA11111 111110F4 */ +Q2 = 1.58730158725481460165e-03, /* 3F5A01A0 19FE5585 */ +Q3 = -7.93650757867487942473e-05, /* BF14CE19 9EAADBB7 */ +Q4 = 4.00821782732936239552e-06, /* 3ED0CFCA 86E65239 */ +Q5 = -2.01099218183624371326e-07; /* BE8AFDB7 6E09C32D */ + +#ifdef __STDC__ + double fd_expm1(double x) +#else + double fd_expm1(x) + double x; +#endif +{ + fd_twoints u; + double y,hi,lo,c,t,e,hxs,hfx,r1; + int k,xsb; + unsigned hx; + + u.d = x; + hx = __HI(u); /* high word of x */ + xsb = hx&0x80000000; /* sign bit of x */ + if(xsb==0) y=x; else y= -x; /* y = |x| */ + hx &= 0x7fffffff; /* high word of |x| */ + + /* filter out huge and non-finite argument */ + if(hx >= 0x4043687A) { /* if |x|>=56*ln2 */ + if(hx >= 0x40862E42) { /* if |x|>=709.78... */ + if(hx>=0x7ff00000) { + u.d = x; + if(((hx&0xfffff)|__LO(u))!=0) + return x+x; /* NaN */ + else return (xsb==0)? x:-1.0;/* exp(+-inf)={inf,-1} */ + } + if(x > o_threshold) return really_big*really_big; /* overflow */ + } + if(xsb!=0) { /* x < -56*ln2, return -1.0 with inexact */ + if(x+tiny<0.0) /* raise inexact */ + return tiny-one; /* return -1 */ + } + } + + /* argument reduction */ + if(hx > 0x3fd62e42) { /* if |x| > 0.5 ln2 */ + if(hx < 0x3FF0A2B2) { /* and |x| < 1.5 ln2 */ + if(xsb==0) + {hi = x - ln2_hi; lo = ln2_lo; k = 1;} + else + {hi = x + ln2_hi; lo = -ln2_lo; k = -1;} + } else { + k = (int)(invln2*x+((xsb==0)?0.5:-0.5)); + t = k; + hi = x - t*ln2_hi; /* t*ln2_hi is exact here */ + lo = t*ln2_lo; + } + x = hi - lo; + c = (hi-x)-lo; + } + else if(hx < 0x3c900000) { /* when |x|<2**-54, return x */ + t = really_big+x; /* return x with inexact flags when x!=0 */ + return x - (t-(really_big+x)); + } + else k = 0; + + /* x is now in primary range */ + hfx = 0.5*x; + hxs = x*hfx; + r1 = one+hxs*(Q1+hxs*(Q2+hxs*(Q3+hxs*(Q4+hxs*Q5)))); + t = 3.0-r1*hfx; + e = hxs*((r1-t)/(6.0 - x*t)); + if(k==0) return x - (x*e-hxs); /* c is 0 */ + else { + e = (x*(e-c)-c); + e -= hxs; + if(k== -1) return 0.5*(x-e)-0.5; + if(k==1) + if(x < -0.25) return -2.0*(e-(x+0.5)); + else return one+2.0*(x-e); + if (k <= -2 || k>56) { /* suffice to return exp(x)-1 */ + y = one-(e-x); + u.d = y; + __HI(u) += (k<<20); /* add k to y's exponent */ + y = u.d; + return y-one; + } + t = one; + if(k<20) { + u.d = t; + __HI(u) = 0x3ff00000 - (0x200000>>k); /* t=1-2^-k */ + t = u.d; + y = t-(e-x); + u.d = y; + __HI(u) += (k<<20); /* add k to y's exponent */ + y = u.d; + } else { + u.d = t; + __HI(u) = ((0x3ff-k)<<20); /* 2^-k */ + t = u.d; + y = x-(e+t); + y += one; + u.d = y; + __HI(u) += (k<<20); /* add k to y's exponent */ + y = u.d; + } + } + return y; +} diff --git a/src/dom/js/fdlibm/s_fabs.c b/src/dom/js/fdlibm/s_fabs.c new file mode 100644 index 000000000..6b029da10 --- /dev/null +++ b/src/dom/js/fdlibm/s_fabs.c @@ -0,0 +1,70 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Sun Microsystems, Inc. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* @(#)s_fabs.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * fabs(x) returns the absolute value of x. + */ + +#include "fdlibm.h" + +#ifdef __STDC__ + double fd_fabs(double x) +#else + double fd_fabs(x) + double x; +#endif +{ + fd_twoints u; + u.d = x; + __HI(u) &= 0x7fffffff; + x = u.d; + return x; +} diff --git a/src/dom/js/fdlibm/s_finite.c b/src/dom/js/fdlibm/s_finite.c new file mode 100644 index 000000000..4a0a4d3c6 --- /dev/null +++ b/src/dom/js/fdlibm/s_finite.c @@ -0,0 +1,71 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Sun Microsystems, Inc. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* @(#)s_finite.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * finite(x) returns 1 is x is finite, else 0; + * no branching! + */ + +#include "fdlibm.h" + +#ifdef __STDC__ + int fd_finite(double x) +#else + int fd_finite(x) + double x; +#endif +{ + fd_twoints u; + int hx; + u.d = x; + hx = __HI(u); + return (unsigned)((hx&0x7fffffff)-0x7ff00000)>>31; +} diff --git a/src/dom/js/fdlibm/s_floor.c b/src/dom/js/fdlibm/s_floor.c new file mode 100644 index 000000000..6c23495f0 --- /dev/null +++ b/src/dom/js/fdlibm/s_floor.c @@ -0,0 +1,121 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Sun Microsystems, Inc. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* @(#)s_floor.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * floor(x) + * Return x rounded toward -inf to integral value + * Method: + * Bit twiddling. + * Exception: + * Inexact flag raised if x not equal to floor(x). + */ + +#include "fdlibm.h" + +#ifdef __STDC__ +static const double really_big = 1.0e300; +#else +static double really_big = 1.0e300; +#endif + +#ifdef __STDC__ + double fd_floor(double x) +#else + double fd_floor(x) + double x; +#endif +{ + fd_twoints u; + int i0,i1,j0; + unsigned i,j; + u.d = x; + i0 = __HI(u); + i1 = __LO(u); + j0 = ((i0>>20)&0x7ff)-0x3ff; + if(j0<20) { + if(j0<0) { /* raise inexact if x != 0 */ + if(really_big+x>0.0) {/* return 0*sign(x) if |x|<1 */ + if(i0>=0) {i0=i1=0;} + else if(((i0&0x7fffffff)|i1)!=0) + { i0=0xbff00000;i1=0;} + } + } else { + i = (0x000fffff)>>j0; + if(((i0&i)|i1)==0) return x; /* x is integral */ + if(really_big+x>0.0) { /* raise inexact flag */ + if(i0<0) i0 += (0x00100000)>>j0; + i0 &= (~i); i1=0; + } + } + } else if (j0>51) { + if(j0==0x400) return x+x; /* inf or NaN */ + else return x; /* x is integral */ + } else { + i = ((unsigned)(0xffffffff))>>(j0-20); + if((i1&i)==0) return x; /* x is integral */ + if(really_big+x>0.0) { /* raise inexact flag */ + if(i0<0) { + if(j0==20) i0+=1; + else { + j = i1+(1<<(52-j0)); + if((int)j=0x7ff00000||((ix|lx)==0)) return x; /* 0,inf,nan */ + if (ix<0x00100000) { /* subnormal */ + x *= two54; + u.d = x; + hx = __HI(u); + ix = hx&0x7fffffff; + *eptr = -54; + } + *eptr += (ix>>20)-1022; + hx = (hx&0x800fffff)|0x3fe00000; + u.d = x; + __HI(u) = hx; + x = u.d; + return x; +} diff --git a/src/dom/js/fdlibm/s_ilogb.c b/src/dom/js/fdlibm/s_ilogb.c new file mode 100644 index 000000000..f769781a6 --- /dev/null +++ b/src/dom/js/fdlibm/s_ilogb.c @@ -0,0 +1,85 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Sun Microsystems, Inc. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* @(#)s_ilogb.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* ilogb(double x) + * return the binary exponent of non-zero x + * ilogb(0) = 0x80000001 + * ilogb(inf/NaN) = 0x7fffffff (no signal is raised) + */ + +#include "fdlibm.h" + +#ifdef __STDC__ + int fd_ilogb(double x) +#else + int fd_ilogb(x) + double x; +#endif +{ + int hx,lx,ix; + fd_twoints u; + u.d = x; + hx = (__HI(u))&0x7fffffff; /* high word of x */ + if(hx<0x00100000) { + lx = __LO(u); + if((hx|lx)==0) + return 0x80000001; /* ilogb(0) = 0x80000001 */ + else /* subnormal x */ + if(hx==0) { + for (ix = -1043; lx>0; lx<<=1) ix -=1; + } else { + for (ix = -1022,hx<<=11; hx>0; hx<<=1) ix -=1; + } + return ix; + } + else if (hx<0x7ff00000) return (hx>>20)-1023; + else return 0x7fffffff; +} diff --git a/src/dom/js/fdlibm/s_isnan.c b/src/dom/js/fdlibm/s_isnan.c new file mode 100644 index 000000000..52f8759c7 --- /dev/null +++ b/src/dom/js/fdlibm/s_isnan.c @@ -0,0 +1,74 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Sun Microsystems, Inc. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* @(#)s_isnan.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * isnan(x) returns 1 is x is nan, else 0; + * no branching! + */ + +#include "fdlibm.h" + +#ifdef __STDC__ + int fd_isnan(double x) +#else + int fd_isnan(x) + double x; +#endif +{ + fd_twoints u; + int hx,lx; + u.d = x; + hx = (__HI(u)&0x7fffffff); + lx = __LO(u); + hx |= (unsigned)(lx|(-lx))>>31; + hx = 0x7ff00000 - hx; + return ((unsigned)(hx))>>31; +} diff --git a/src/dom/js/fdlibm/s_ldexp.c b/src/dom/js/fdlibm/s_ldexp.c new file mode 100644 index 000000000..9475520d4 --- /dev/null +++ b/src/dom/js/fdlibm/s_ldexp.c @@ -0,0 +1,66 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Sun Microsystems, Inc. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* @(#)s_ldexp.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include "fdlibm.h" +#include + +#ifdef __STDC__ + double fd_ldexp(double value, int exp) +#else + double fd_ldexp(value, exp) + double value; int exp; +#endif +{ + if(!fd_finite(value)||value==0.0) return value; + value = fd_scalbn(value,exp); + if(!fd_finite(value)||value==0.0) errno = ERANGE; + return value; +} diff --git a/src/dom/js/fdlibm/s_lib_version.c b/src/dom/js/fdlibm/s_lib_version.c new file mode 100644 index 000000000..2ccf67d51 --- /dev/null +++ b/src/dom/js/fdlibm/s_lib_version.c @@ -0,0 +1,73 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Sun Microsystems, Inc. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* @(#)s_lib_version.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * MACRO for standards + */ + +#include "fdlibm.h" + +/* + * define and initialize _LIB_VERSION + */ +#ifdef _POSIX_MODE +_LIB_VERSION_TYPE _LIB_VERSION = _POSIX_; +#else +#ifdef _XOPEN_MODE +_LIB_VERSION_TYPE _LIB_VERSION = _XOPEN_; +#else +#ifdef _SVID3_MODE +_LIB_VERSION_TYPE _LIB_VERSION = _SVID_; +#else /* default _IEEE_MODE */ +_LIB_VERSION_TYPE _LIB_VERSION = _IEEE_; +#endif +#endif +#endif diff --git a/src/dom/js/fdlibm/s_log1p.c b/src/dom/js/fdlibm/s_log1p.c new file mode 100644 index 000000000..1840156b1 --- /dev/null +++ b/src/dom/js/fdlibm/s_log1p.c @@ -0,0 +1,211 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Sun Microsystems, Inc. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* @(#)s_log1p.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* double log1p(double x) + * + * Method : + * 1. Argument Reduction: find k and f such that + * 1+x = 2^k * (1+f), + * where sqrt(2)/2 < 1+f < sqrt(2) . + * + * Note. If k=0, then f=x is exact. However, if k!=0, then f + * may not be representable exactly. In that case, a correction + * term is need. Let u=1+x rounded. Let c = (1+x)-u, then + * log(1+x) - log(u) ~ c/u. Thus, we proceed to compute log(u), + * and add back the correction term c/u. + * (Note: when x > 2**53, one can simply return log(x)) + * + * 2. Approximation of log1p(f). + * Let s = f/(2+f) ; based on log(1+f) = log(1+s) - log(1-s) + * = 2s + 2/3 s**3 + 2/5 s**5 + ....., + * = 2s + s*R + * We use a special Reme algorithm on [0,0.1716] to generate + * a polynomial of degree 14 to approximate R The maximum error + * of this polynomial approximation is bounded by 2**-58.45. In + * other words, + * 2 4 6 8 10 12 14 + * R(z) ~ Lp1*s +Lp2*s +Lp3*s +Lp4*s +Lp5*s +Lp6*s +Lp7*s + * (the values of Lp1 to Lp7 are listed in the program) + * and + * | 2 14 | -58.45 + * | Lp1*s +...+Lp7*s - R(z) | <= 2 + * | | + * Note that 2s = f - s*f = f - hfsq + s*hfsq, where hfsq = f*f/2. + * In order to guarantee error in log below 1ulp, we compute log + * by + * log1p(f) = f - (hfsq - s*(hfsq+R)). + * + * 3. Finally, log1p(x) = k*ln2 + log1p(f). + * = k*ln2_hi+(f-(hfsq-(s*(hfsq+R)+k*ln2_lo))) + * Here ln2 is split into two floating point number: + * ln2_hi + ln2_lo, + * where n*ln2_hi is always exact for |n| < 2000. + * + * Special cases: + * log1p(x) is NaN with signal if x < -1 (including -INF) ; + * log1p(+INF) is +INF; log1p(-1) is -INF with signal; + * log1p(NaN) is that NaN with no signal. + * + * Accuracy: + * according to an error analysis, the error is always less than + * 1 ulp (unit in the last place). + * + * Constants: + * The hexadecimal values are the intended ones for the following + * constants. The decimal values may be used, provided that the + * compiler will convert from decimal to binary accurately enough + * to produce the hexadecimal values shown. + * + * Note: Assuming log() return accurate answer, the following + * algorithm can be used to compute log1p(x) to within a few ULP: + * + * u = 1+x; + * if(u==1.0) return x ; else + * return log(u)*(x/(u-1.0)); + * + * See HP-15C Advanced Functions Handbook, p.193. + */ + +#include "fdlibm.h" + +#ifdef __STDC__ +static const double +#else +static double +#endif +ln2_hi = 6.93147180369123816490e-01, /* 3fe62e42 fee00000 */ +ln2_lo = 1.90821492927058770002e-10, /* 3dea39ef 35793c76 */ +two54 = 1.80143985094819840000e+16, /* 43500000 00000000 */ +Lp1 = 6.666666666666735130e-01, /* 3FE55555 55555593 */ +Lp2 = 3.999999999940941908e-01, /* 3FD99999 9997FA04 */ +Lp3 = 2.857142874366239149e-01, /* 3FD24924 94229359 */ +Lp4 = 2.222219843214978396e-01, /* 3FCC71C5 1D8E78AF */ +Lp5 = 1.818357216161805012e-01, /* 3FC74664 96CB03DE */ +Lp6 = 1.531383769920937332e-01, /* 3FC39A09 D078C69F */ +Lp7 = 1.479819860511658591e-01; /* 3FC2F112 DF3E5244 */ + +static double zero = 0.0; + +#ifdef __STDC__ + double fd_log1p(double x) +#else + double fd_log1p(x) + double x; +#endif +{ + double hfsq,f,c,s,z,R,u; + int k,hx,hu,ax; + fd_twoints un; + + un.d = x; + hx = __HI(un); /* high word of x */ + ax = hx&0x7fffffff; + + k = 1; + if (hx < 0x3FDA827A) { /* x < 0.41422 */ + if(ax>=0x3ff00000) { /* x <= -1.0 */ + if(x==-1.0) return -two54/zero; /* log1p(-1)=+inf */ + else return (x-x)/(x-x); /* log1p(x<-1)=NaN */ + } + if(ax<0x3e200000) { /* |x| < 2**-29 */ + if(two54+x>zero /* raise inexact */ + &&ax<0x3c900000) /* |x| < 2**-54 */ + return x; + else + return x - x*x*0.5; + } + if(hx>0||hx<=((int)0xbfd2bec3)) { + k=0;f=x;hu=1;} /* -0.2929= 0x7ff00000) return x+x; + if(k!=0) { + if(hx<0x43400000) { + u = 1.0+x; + un.d = u; + hu = __HI(un); /* high word of u */ + k = (hu>>20)-1023; + c = (k>0)? 1.0-(u-x):x-(u-1.0);/* correction term */ + c /= u; + } else { + u = x; + un.d = u; + hu = __HI(un); /* high word of u */ + k = (hu>>20)-1023; + c = 0; + } + hu &= 0x000fffff; + if(hu<0x6a09e) { + un.d = u; + __HI(un) = hu|0x3ff00000; /* normalize u */ + u = un.d; + } else { + k += 1; + un.d = u; + __HI(un) = hu|0x3fe00000; /* normalize u/2 */ + u = un.d; + hu = (0x00100000-hu)>>2; + } + f = u-1.0; + } + hfsq=0.5*f*f; + if(hu==0) { /* |f| < 2**-20 */ + if(f==zero) if(k==0) return zero; + else {c += k*ln2_lo; return k*ln2_hi+c;} + R = hfsq*(1.0-0.66666666666666666*f); + if(k==0) return f-R; else + return k*ln2_hi-((R-(k*ln2_lo+c))-f); + } + s = f/(2.0+f); + z = s*s; + R = z*(Lp1+z*(Lp2+z*(Lp3+z*(Lp4+z*(Lp5+z*(Lp6+z*Lp7)))))); + if(k==0) return f-(hfsq-s*(hfsq+R)); else + return k*ln2_hi-((hfsq-(s*(hfsq+R)+(k*ln2_lo+c)))-f); +} diff --git a/src/dom/js/fdlibm/s_logb.c b/src/dom/js/fdlibm/s_logb.c new file mode 100644 index 000000000..f885c4dc3 --- /dev/null +++ b/src/dom/js/fdlibm/s_logb.c @@ -0,0 +1,79 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Sun Microsystems, Inc. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* @(#)s_logb.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * double logb(x) + * IEEE 754 logb. Included to pass IEEE test suite. Not recommend. + * Use ilogb instead. + */ + +#include "fdlibm.h" + +#ifdef __STDC__ + double fd_logb(double x) +#else + double fd_logb(x) + double x; +#endif +{ + int lx,ix; + fd_twoints u; + + u.d = x; + ix = (__HI(u))&0x7fffffff; /* high |x| */ + lx = __LO(u); /* low x */ + if((ix|lx)==0) return -1.0/fd_fabs(x); + if(ix>=0x7ff00000) return x*x; + if((ix>>=20)==0) /* IEEE 754 logb */ + return -1022.0; + else + return (double) (ix-1023); +} diff --git a/src/dom/js/fdlibm/s_matherr.c b/src/dom/js/fdlibm/s_matherr.c new file mode 100644 index 000000000..cd99ca88f --- /dev/null +++ b/src/dom/js/fdlibm/s_matherr.c @@ -0,0 +1,64 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Sun Microsystems, Inc. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* @(#)s_matherr.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +#include "fdlibm.h" + +#ifdef __STDC__ + int fd_matherr(struct exception *x) +#else + int fd_matherr(x) + struct exception *x; +#endif +{ + int n=0; + if(x->arg1!=x->arg1) return 0; + return n; +} diff --git a/src/dom/js/fdlibm/s_modf.c b/src/dom/js/fdlibm/s_modf.c new file mode 100644 index 000000000..3b182bd3b --- /dev/null +++ b/src/dom/js/fdlibm/s_modf.c @@ -0,0 +1,132 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Sun Microsystems, Inc. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* @(#)s_modf.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * modf(double x, double *iptr) + * return fraction part of x, and return x's integral part in *iptr. + * Method: + * Bit twiddling. + * + * Exception: + * No exception. + */ + +#include "fdlibm.h" + +#ifdef __STDC__ +static const double one = 1.0; +#else +static double one = 1.0; +#endif + +#ifdef __STDC__ + double fd_modf(double x, double *iptr) +#else + double fd_modf(x, iptr) + double x,*iptr; +#endif +{ + int i0,i1,j0; + unsigned i; + fd_twoints u; + u.d = x; + i0 = __HI(u); /* high x */ + i1 = __LO(u); /* low x */ + j0 = ((i0>>20)&0x7ff)-0x3ff; /* exponent of x */ + if(j0<20) { /* integer part in high x */ + if(j0<0) { /* |x|<1 */ + u.d = *iptr; + __HI(u) = i0&0x80000000; + __LO(u) = 0; /* *iptr = +-0 */ + *iptr = u.d; + return x; + } else { + i = (0x000fffff)>>j0; + if(((i0&i)|i1)==0) { /* x is integral */ + *iptr = x; + u.d = x; + __HI(u) &= 0x80000000; + __LO(u) = 0; /* return +-0 */ + x = u.d; + return x; + } else { + u.d = *iptr; + __HI(u) = i0&(~i); + __LO(u) = 0; + *iptr = u.d; + return x - *iptr; + } + } + } else if (j0>51) { /* no fraction part */ + *iptr = x*one; + u.d = x; + __HI(u) &= 0x80000000; + __LO(u) = 0; /* return +-0 */ + x = u.d; + return x; + } else { /* fraction part in low x */ + i = ((unsigned)(0xffffffff))>>(j0-20); + if((i1&i)==0) { /* x is integral */ + *iptr = x; + u.d = x; + __HI(u) &= 0x80000000; + __LO(u) = 0; /* return +-0 */ + x = u.d; + return x; + } else { + u.d = *iptr; + __HI(u) = i0; + __LO(u) = i1&(~i); + *iptr = u.d; + return x - *iptr; + } + } +} diff --git a/src/dom/js/fdlibm/s_nextafter.c b/src/dom/js/fdlibm/s_nextafter.c new file mode 100644 index 000000000..f71c5c835 --- /dev/null +++ b/src/dom/js/fdlibm/s_nextafter.c @@ -0,0 +1,124 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Sun Microsystems, Inc. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* @(#)s_nextafter.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* IEEE functions + * nextafter(x,y) + * return the next machine floating-point number of x in the + * direction toward y. + * Special cases: + */ + +#include "fdlibm.h" + +#ifdef __STDC__ + double fd_nextafter(double x, double y) +#else + double fd_nextafter(x,y) + double x,y; +#endif +{ + int hx,hy,ix,iy; + unsigned lx,ly; + fd_twoints ux, uy; + + ux.d = x; uy.d = y; + hx = __HI(ux); /* high word of x */ + lx = __LO(ux); /* low word of x */ + hy = __HI(uy); /* high word of y */ + ly = __LO(uy); /* low word of y */ + ix = hx&0x7fffffff; /* |x| */ + iy = hy&0x7fffffff; /* |y| */ + + if(((ix>=0x7ff00000)&&((ix-0x7ff00000)|lx)!=0) || /* x is nan */ + ((iy>=0x7ff00000)&&((iy-0x7ff00000)|ly)!=0)) /* y is nan */ + return x+y; + if(x==y) return x; /* x=y, return x */ + if((ix|lx)==0) { /* x == 0 */ + ux.d = x; + __HI(ux) = hy&0x80000000; /* return +-minsubnormal */ + __LO(ux) = 1; + x = ux.d; + y = x*x; + if(y==x) return y; else return x; /* raise underflow flag */ + } + if(hx>=0) { /* x > 0 */ + if(hx>hy||((hx==hy)&&(lx>ly))) { /* x > y, x -= ulp */ + if(lx==0) hx -= 1; + lx -= 1; + } else { /* x < y, x += ulp */ + lx += 1; + if(lx==0) hx += 1; + } + } else { /* x < 0 */ + if(hy>=0||hx>hy||((hx==hy)&&(lx>ly))){/* x < y, x -= ulp */ + if(lx==0) hx -= 1; + lx -= 1; + } else { /* x > y, x += ulp */ + lx += 1; + if(lx==0) hx += 1; + } + } + hy = hx&0x7ff00000; + if(hy>=0x7ff00000) return x+x; /* overflow */ + if(hy<0x00100000) { /* underflow */ + y = x*x; + if(y!=x) { /* raise underflow flag */ + uy.d = y; + __HI(uy) = hx; __LO(uy) = lx; + y = uy.d; + return y; + } + } + ux.d = x; + __HI(ux) = hx; __LO(ux) = lx; + x = ux.d; + return x; +} diff --git a/src/dom/js/fdlibm/s_rint.c b/src/dom/js/fdlibm/s_rint.c new file mode 100644 index 000000000..3c4fab6d9 --- /dev/null +++ b/src/dom/js/fdlibm/s_rint.c @@ -0,0 +1,131 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Sun Microsystems, Inc. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* @(#)s_rint.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * rint(x) + * Return x rounded to integral value according to the prevailing + * rounding mode. + * Method: + * Using floating addition. + * Exception: + * Inexact flag raised if x not equal to rint(x). + */ + +#include "fdlibm.h" + +#ifdef __STDC__ +static const double +#else +static double +#endif +TWO52[2]={ + 4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */ + -4.50359962737049600000e+15, /* 0xC3300000, 0x00000000 */ +}; + +#ifdef __STDC__ + double fd_rint(double x) +#else + double fd_rint(x) + double x; +#endif +{ + int i0,j0,sx; + unsigned i,i1; + double w,t; + fd_twoints u; + + u.d = x; + i0 = __HI(u); + sx = (i0>>31)&1; + i1 = __LO(u); + j0 = ((i0>>20)&0x7ff)-0x3ff; + if(j0<20) { + if(j0<0) { + if(((i0&0x7fffffff)|i1)==0) return x; + i1 |= (i0&0x0fffff); + i0 &= 0xfffe0000; + i0 |= ((i1|-(int)i1)>>12)&0x80000; + u.d = x; + __HI(u)=i0; + x = u.d; + w = TWO52[sx]+x; + t = w-TWO52[sx]; + u.d = t; + i0 = __HI(u); + __HI(u) = (i0&0x7fffffff)|(sx<<31); + t = u.d; + return t; + } else { + i = (0x000fffff)>>j0; + if(((i0&i)|i1)==0) return x; /* x is integral */ + i>>=1; + if(((i0&i)|i1)!=0) { + if(j0==19) i1 = 0x40000000; else + i0 = (i0&(~i))|((0x20000)>>j0); + } + } + } else if (j0>51) { + if(j0==0x400) return x+x; /* inf or NaN */ + else return x; /* x is integral */ + } else { + i = ((unsigned)(0xffffffff))>>(j0-20); + if((i1&i)==0) return x; /* x is integral */ + i>>=1; + if((i1&i)!=0) i1 = (i1&(~i))|((0x40000000)>>(j0-20)); + } + u.d = x; + __HI(u) = i0; + __LO(u) = i1; + x = u.d; + w = TWO52[sx]+x; + return w-TWO52[sx]; +} diff --git a/src/dom/js/fdlibm/s_scalbn.c b/src/dom/js/fdlibm/s_scalbn.c new file mode 100644 index 000000000..3deeaa305 --- /dev/null +++ b/src/dom/js/fdlibm/s_scalbn.c @@ -0,0 +1,107 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Sun Microsystems, Inc. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* @(#)s_scalbn.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * scalbn (double x, int n) + * scalbn(x,n) returns x* 2**n computed by exponent + * manipulation rather than by actually performing an + * exponentiation or a multiplication. + */ + +#include "fdlibm.h" + +#ifdef __STDC__ +static const double +#else +static double +#endif +two54 = 1.80143985094819840000e+16, /* 0x43500000, 0x00000000 */ +twom54 = 5.55111512312578270212e-17, /* 0x3C900000, 0x00000000 */ +really_big = 1.0e+300, +tiny = 1.0e-300; + +#ifdef __STDC__ + double fd_scalbn (double x, int n) +#else + double fd_scalbn (x,n) + double x; int n; +#endif +{ + fd_twoints u; + int k,hx,lx; + u.d = x; + hx = __HI(u); + lx = __LO(u); + k = (hx&0x7ff00000)>>20; /* extract exponent */ + if (k==0) { /* 0 or subnormal x */ + if ((lx|(hx&0x7fffffff))==0) return x; /* +-0 */ + x *= two54; + u.d = x; + hx = __HI(u); + k = ((hx&0x7ff00000)>>20) - 54; + if (n< -50000) return tiny*x; /*underflow*/ + } + if (k==0x7ff) return x+x; /* NaN or Inf */ + k = k+n; + if (k > 0x7fe) return really_big*fd_copysign(really_big,x); /* overflow */ + if (k > 0) /* normal result */ + {u.d = x; __HI(u) = (hx&0x800fffff)|(k<<20); x = u.d; return x;} + if (k <= -54) { + if (n > 50000) /* in case integer overflow in n+k */ + return really_big*fd_copysign(really_big,x); /*overflow*/ + else return tiny*fd_copysign(tiny,x); /*underflow*/ + } + k += 54; /* subnormal result */ + u.d = x; + __HI(u) = (hx&0x800fffff)|(k<<20); + x = u.d; + return x*twom54; +} diff --git a/src/dom/js/fdlibm/s_signgam.c b/src/dom/js/fdlibm/s_signgam.c new file mode 100644 index 000000000..4eb8ce72f --- /dev/null +++ b/src/dom/js/fdlibm/s_signgam.c @@ -0,0 +1,40 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Sun Microsystems, Inc. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ +#include "fdlibm.h" +int signgam = 0; diff --git a/src/dom/js/fdlibm/s_significand.c b/src/dom/js/fdlibm/s_significand.c new file mode 100644 index 000000000..2e1c0b28f --- /dev/null +++ b/src/dom/js/fdlibm/s_significand.c @@ -0,0 +1,68 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Sun Microsystems, Inc. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* @(#)s_significand.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * significand(x) computes just + * scalb(x, (double) -ilogb(x)), + * for exercising the fraction-part(F) IEEE 754-1985 test vector. + */ + +#include "fdlibm.h" + +#ifdef __STDC__ + double fd_significand(double x) +#else + double fd_significand(x) + double x; +#endif +{ + return __ieee754_scalb(x,(double) -fd_ilogb(x)); +} diff --git a/src/dom/js/fdlibm/s_sin.c b/src/dom/js/fdlibm/s_sin.c new file mode 100644 index 000000000..8bbc5c62d --- /dev/null +++ b/src/dom/js/fdlibm/s_sin.c @@ -0,0 +1,118 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Sun Microsystems, Inc. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* @(#)s_sin.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* sin(x) + * Return sine function of x. + * + * kernel function: + * __kernel_sin ... sine function on [-pi/4,pi/4] + * __kernel_cos ... cose function on [-pi/4,pi/4] + * __ieee754_rem_pio2 ... argument reduction routine + * + * Method. + * Let S,C and T denote the sin, cos and tan respectively on + * [-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2 + * in [-pi/4 , +pi/4], and let n = k mod 4. + * We have + * + * n sin(x) cos(x) tan(x) + * ---------------------------------------------------------- + * 0 S C T + * 1 C -S -1/T + * 2 -S -C T + * 3 -C S -1/T + * ---------------------------------------------------------- + * + * Special cases: + * Let trig be any of sin, cos, or tan. + * trig(+-INF) is NaN, with signals; + * trig(NaN) is that NaN; + * + * Accuracy: + * TRIG(x) returns trig(x) nearly rounded + */ + +#include "fdlibm.h" + +#ifdef __STDC__ + double fd_sin(double x) +#else + double fd_sin(x) + double x; +#endif +{ + fd_twoints u; + double y[2],z=0.0; + int n, ix; + + /* High word of x. */ + u.d = x; + ix = __HI(u); + + /* |x| ~< pi/4 */ + ix &= 0x7fffffff; + if(ix <= 0x3fe921fb) return __kernel_sin(x,z,0); + + /* sin(Inf or NaN) is NaN */ + else if (ix>=0x7ff00000) return x-x; + + /* argument reduction needed */ + else { + n = __ieee754_rem_pio2(x,y); + switch(n&3) { + case 0: return __kernel_sin(y[0],y[1],1); + case 1: return __kernel_cos(y[0],y[1]); + case 2: return -__kernel_sin(y[0],y[1],1); + default: + return -__kernel_cos(y[0],y[1]); + } + } +} diff --git a/src/dom/js/fdlibm/s_tan.c b/src/dom/js/fdlibm/s_tan.c new file mode 100644 index 000000000..ded36c1d7 --- /dev/null +++ b/src/dom/js/fdlibm/s_tan.c @@ -0,0 +1,112 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Sun Microsystems, Inc. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* @(#)s_tan.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* tan(x) + * Return tangent function of x. + * + * kernel function: + * __kernel_tan ... tangent function on [-pi/4,pi/4] + * __ieee754_rem_pio2 ... argument reduction routine + * + * Method. + * Let S,C and T denote the sin, cos and tan respectively on + * [-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2 + * in [-pi/4 , +pi/4], and let n = k mod 4. + * We have + * + * n sin(x) cos(x) tan(x) + * ---------------------------------------------------------- + * 0 S C T + * 1 C -S -1/T + * 2 -S -C T + * 3 -C S -1/T + * ---------------------------------------------------------- + * + * Special cases: + * Let trig be any of sin, cos, or tan. + * trig(+-INF) is NaN, with signals; + * trig(NaN) is that NaN; + * + * Accuracy: + * TRIG(x) returns trig(x) nearly rounded + */ + +#include "fdlibm.h" + +#ifdef __STDC__ + double fd_tan(double x) +#else + double fd_tan(x) + double x; +#endif +{ + fd_twoints u; + double y[2],z=0.0; + int n, ix; + + /* High word of x. */ + u.d = x; + ix = __HI(u); + + /* |x| ~< pi/4 */ + ix &= 0x7fffffff; + if(ix <= 0x3fe921fb) return __kernel_tan(x,z,1); + + /* tan(Inf or NaN) is NaN */ + else if (ix>=0x7ff00000) return x-x; /* NaN */ + + /* argument reduction needed */ + else { + n = __ieee754_rem_pio2(x,y); + return __kernel_tan(y[0],y[1],1-((n&1)<<1)); /* 1 -- n even + -1 -- n odd */ + } +} diff --git a/src/dom/js/fdlibm/s_tanh.c b/src/dom/js/fdlibm/s_tanh.c new file mode 100644 index 000000000..aa6809f85 --- /dev/null +++ b/src/dom/js/fdlibm/s_tanh.c @@ -0,0 +1,122 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Sun Microsystems, Inc. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* @(#)s_tanh.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* Tanh(x) + * Return the Hyperbolic Tangent of x + * + * Method : + * x -x + * e - e + * 0. tanh(x) is defined to be ----------- + * x -x + * e + e + * 1. reduce x to non-negative by tanh(-x) = -tanh(x). + * 2. 0 <= x <= 2**-55 : tanh(x) := x*(one+x) + * -t + * 2**-55 < x <= 1 : tanh(x) := -----; t = expm1(-2x) + * t + 2 + * 2 + * 1 <= x <= 22.0 : tanh(x) := 1- ----- ; t=expm1(2x) + * t + 2 + * 22.0 < x <= INF : tanh(x) := 1. + * + * Special cases: + * tanh(NaN) is NaN; + * only tanh(0)=0 is exact for finite argument. + */ + +#include "fdlibm.h" + +#ifdef __STDC__ +static const double one=1.0, two=2.0, tiny = 1.0e-300; +#else +static double one=1.0, two=2.0, tiny = 1.0e-300; +#endif + +#ifdef __STDC__ + double fd_tanh(double x) +#else + double fd_tanh(x) + double x; +#endif +{ + double t,z; + int jx,ix; + fd_twoints u; + + /* High word of |x|. */ + u.d = x; + jx = __HI(u); + ix = jx&0x7fffffff; + + /* x is INF or NaN */ + if(ix>=0x7ff00000) { + if (jx>=0) return one/x+one; /* tanh(+-inf)=+-1 */ + else return one/x-one; /* tanh(NaN) = NaN */ + } + + /* |x| < 22 */ + if (ix < 0x40360000) { /* |x|<22 */ + if (ix<0x3c800000) /* |x|<2**-55 */ + return x*(one+x); /* tanh(small) = small */ + if (ix>=0x3ff00000) { /* |x|>=1 */ + t = fd_expm1(two*fd_fabs(x)); + z = one - two/(t+two); + } else { + t = fd_expm1(-two*fd_fabs(x)); + z= -t/(t+two); + } + /* |x| > 22, return +-1 */ + } else { + z = one - tiny; /* raised inexact flag */ + } + return (jx>=0)? z: -z; +} diff --git a/src/dom/js/fdlibm/w_acos.c b/src/dom/js/fdlibm/w_acos.c new file mode 100644 index 000000000..872c81d20 --- /dev/null +++ b/src/dom/js/fdlibm/w_acos.c @@ -0,0 +1,78 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Sun Microsystems, Inc. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* @(#)w_acos.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * wrap_acos(x) + */ + +#include "fdlibm.h" + + +#ifdef __STDC__ + double fd_acos(double x) /* wrapper acos */ +#else + double fd_acos(x) /* wrapper acos */ + double x; +#endif +{ +#ifdef _IEEE_LIBM + return __ieee754_acos(x); +#else + double z; + z = __ieee754_acos(x); + if(_LIB_VERSION == _IEEE_ || fd_isnan(x)) return z; + if(fd_fabs(x)>1.0) { + int err; + return __kernel_standard(x,x,1,&err); /* acos(|x|>1) */ + } else + return z; +#endif +} diff --git a/src/dom/js/fdlibm/w_acosh.c b/src/dom/js/fdlibm/w_acosh.c new file mode 100644 index 000000000..745d402ea --- /dev/null +++ b/src/dom/js/fdlibm/w_acosh.c @@ -0,0 +1,78 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Sun Microsystems, Inc. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* @(#)w_acosh.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + * + */ + +/* + * wrapper acosh(x) + */ + +#include "fdlibm.h" + +#ifdef __STDC__ + double fd_acosh(double x) /* wrapper acosh */ +#else + double fd_acosh(x) /* wrapper acosh */ + double x; +#endif +{ +#ifdef _IEEE_LIBM + return __ieee754_acosh(x); +#else + double z; + z = __ieee754_acosh(x); + if(_LIB_VERSION == _IEEE_ || fd_isnan(x)) return z; + if(x<1.0) { + int err; + return __kernel_standard(x,x,29,&err); /* acosh(x<1) */ + } else + return z; +#endif +} diff --git a/src/dom/js/fdlibm/w_asin.c b/src/dom/js/fdlibm/w_asin.c new file mode 100644 index 000000000..18aaefde9 --- /dev/null +++ b/src/dom/js/fdlibm/w_asin.c @@ -0,0 +1,80 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Sun Microsystems, Inc. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* @(#)w_asin.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + * + */ + +/* + * wrapper asin(x) + */ + + +#include "fdlibm.h" + + +#ifdef __STDC__ + double fd_asin(double x) /* wrapper asin */ +#else + double fd_asin(x) /* wrapper asin */ + double x; +#endif +{ +#ifdef _IEEE_LIBM + return __ieee754_asin(x); +#else + double z; + z = __ieee754_asin(x); + if(_LIB_VERSION == _IEEE_ || fd_isnan(x)) return z; + if(fd_fabs(x)>1.0) { + int err; + return __kernel_standard(x,x,2,&err); /* asin(|x|>1) */ + } else + return z; +#endif +} diff --git a/src/dom/js/fdlibm/w_atan2.c b/src/dom/js/fdlibm/w_atan2.c new file mode 100644 index 000000000..8cfa4bbbd --- /dev/null +++ b/src/dom/js/fdlibm/w_atan2.c @@ -0,0 +1,79 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Sun Microsystems, Inc. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* @(#)w_atan2.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + * + */ + +/* + * wrapper atan2(y,x) + */ + +#include "fdlibm.h" + + +#ifdef __STDC__ + double fd_atan2(double y, double x) /* wrapper atan2 */ +#else + double fd_atan2(y,x) /* wrapper atan2 */ + double y,x; +#endif +{ +#ifdef _IEEE_LIBM + return __ieee754_atan2(y,x); +#else + double z; + z = __ieee754_atan2(y,x); + if(_LIB_VERSION == _IEEE_||fd_isnan(x)||fd_isnan(y)) return z; + if(x==0.0&&y==0.0) { + int err; + return __kernel_standard(y,x,3,&err); /* atan2(+-0,+-0) */ + } else + return z; +#endif +} diff --git a/src/dom/js/fdlibm/w_atanh.c b/src/dom/js/fdlibm/w_atanh.c new file mode 100644 index 000000000..6ba52d1e2 --- /dev/null +++ b/src/dom/js/fdlibm/w_atanh.c @@ -0,0 +1,81 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Sun Microsystems, Inc. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* @(#)w_atanh.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ +/* + * wrapper atanh(x) + */ + +#include "fdlibm.h" + + +#ifdef __STDC__ + double fd_atanh(double x) /* wrapper atanh */ +#else + double fd_atanh(x) /* wrapper atanh */ + double x; +#endif +{ +#ifdef _IEEE_LIBM + return __ieee754_atanh(x); +#else + double z,y; + z = __ieee754_atanh(x); + if(_LIB_VERSION == _IEEE_ || fd_isnan(x)) return z; + y = fd_fabs(x); + if(y>=1.0) { + int err; + if(y>1.0) + return __kernel_standard(x,x,30,&err); /* atanh(|x|>1) */ + else + return __kernel_standard(x,x,31,&err); /* atanh(|x|==1) */ + } else + return z; +#endif +} diff --git a/src/dom/js/fdlibm/w_cosh.c b/src/dom/js/fdlibm/w_cosh.c new file mode 100644 index 000000000..146449e02 --- /dev/null +++ b/src/dom/js/fdlibm/w_cosh.c @@ -0,0 +1,77 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Sun Microsystems, Inc. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* @(#)w_cosh.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * wrapper cosh(x) + */ + +#include "fdlibm.h" + +#ifdef __STDC__ + double fd_cosh(double x) /* wrapper cosh */ +#else + double fd_cosh(x) /* wrapper cosh */ + double x; +#endif +{ +#ifdef _IEEE_LIBM + return __ieee754_cosh(x); +#else + double z; + z = __ieee754_cosh(x); + if(_LIB_VERSION == _IEEE_ || fd_isnan(x)) return z; + if(fd_fabs(x)>7.10475860073943863426e+02) { + int err; + return __kernel_standard(x,x,5,&err); /* cosh overflow */ + } else + return z; +#endif +} diff --git a/src/dom/js/fdlibm/w_exp.c b/src/dom/js/fdlibm/w_exp.c new file mode 100644 index 000000000..f5dea0b01 --- /dev/null +++ b/src/dom/js/fdlibm/w_exp.c @@ -0,0 +1,88 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Sun Microsystems, Inc. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* @(#)w_exp.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * wrapper exp(x) + */ + +#include "fdlibm.h" + +#ifdef __STDC__ +static const double +#else +static double +#endif +o_threshold= 7.09782712893383973096e+02, /* 0x40862E42, 0xFEFA39EF */ +u_threshold= -7.45133219101941108420e+02; /* 0xc0874910, 0xD52D3051 */ + +#ifdef __STDC__ + double fd_exp(double x) /* wrapper exp */ +#else + double fd_exp(x) /* wrapper exp */ + double x; +#endif +{ +#ifdef _IEEE_LIBM + return __ieee754_exp(x); +#else + double z; + z = __ieee754_exp(x); + if(_LIB_VERSION == _IEEE_) return z; + if(fd_finite(x)) { + int err; + if(x>o_threshold) + return __kernel_standard(x,x,6,&err); /* exp overflow */ + else if(xX_TLOSS) { + int err; + return __kernel_standard(x,x,34,&err); /* j0(|x|>X_TLOSS) */ + } else + return z; +#endif +} + +#ifdef __STDC__ + double y0(double x) /* wrapper y0 */ +#else + double y0(x) /* wrapper y0 */ + double x; +#endif +{ +#ifdef _IEEE_LIBM + return __ieee754_y0(x); +#else + double z; + int err; + z = __ieee754_y0(x); + if(_LIB_VERSION == _IEEE_ || fd_isnan(x) ) return z; + if(x <= 0.0){ + if(x==0.0) + /* d= -one/(x-x); */ + return __kernel_standard(x,x,8,&err); + else + /* d = zero/(x-x); */ + return __kernel_standard(x,x,9,&err); + } + if(x>X_TLOSS) { + return __kernel_standard(x,x,35,&err); /* y0(x>X_TLOSS) */ + } else + return z; +#endif +} diff --git a/src/dom/js/fdlibm/w_j1.c b/src/dom/js/fdlibm/w_j1.c new file mode 100644 index 000000000..86a506bc2 --- /dev/null +++ b/src/dom/js/fdlibm/w_j1.c @@ -0,0 +1,106 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Sun Microsystems, Inc. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* @(#)w_j1.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * wrapper of j1,y1 + */ + +#include "fdlibm.h" + +#ifdef __STDC__ + double fd_j1(double x) /* wrapper j1 */ +#else + double fd_j1(x) /* wrapper j1 */ + double x; +#endif +{ +#ifdef _IEEE_LIBM + return __ieee754_j1(x); +#else + double z; + z = __ieee754_j1(x); + if(_LIB_VERSION == _IEEE_ || fd_isnan(x) ) return z; + if(fd_fabs(x)>X_TLOSS) { + int err; + return __kernel_standard(x,x,36,&err); /* j1(|x|>X_TLOSS) */ + } else + return z; +#endif +} + +#ifdef __STDC__ + double y1(double x) /* wrapper y1 */ +#else + double y1(x) /* wrapper y1 */ + double x; +#endif +{ +#ifdef _IEEE_LIBM + return __ieee754_y1(x); +#else + double z; + int err; + z = __ieee754_y1(x); + if(_LIB_VERSION == _IEEE_ || fd_isnan(x) ) return z; + if(x <= 0.0){ + if(x==0.0) + /* d= -one/(x-x); */ + return __kernel_standard(x,x,10,&err); + else + /* d = zero/(x-x); */ + return __kernel_standard(x,x,11,&err); + } + if(x>X_TLOSS) { + return __kernel_standard(x,x,37,&err); /* y1(x>X_TLOSS) */ + } else + return z; +#endif +} diff --git a/src/dom/js/fdlibm/w_jn.c b/src/dom/js/fdlibm/w_jn.c new file mode 100644 index 000000000..6926b0da8 --- /dev/null +++ b/src/dom/js/fdlibm/w_jn.c @@ -0,0 +1,128 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Sun Microsystems, Inc. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* @(#)w_jn.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * wrapper jn(int n, double x), yn(int n, double x) + * floating point Bessel's function of the 1st and 2nd kind + * of order n + * + * Special cases: + * y0(0)=y1(0)=yn(n,0) = -inf with division by zero signal; + * y0(-ve)=y1(-ve)=yn(n,-ve) are NaN with invalid signal. + * Note 2. About jn(n,x), yn(n,x) + * For n=0, j0(x) is called, + * for n=1, j1(x) is called, + * for nx, a continued fraction approximation to + * j(n,x)/j(n-1,x) is evaluated and then backward + * recursion is used starting from a supposed value + * for j(n,x). The resulting value of j(0,x) is + * compared with the actual value to correct the + * supposed value of j(n,x). + * + * yn(n,x) is similar in all respects, except + * that forward recursion is used for all + * values of n>1. + * + */ + +#include "fdlibm.h" + +#ifdef __STDC__ + double fd_jn(int n, double x) /* wrapper jn */ +#else + double fd_jn(n,x) /* wrapper jn */ + double x; int n; +#endif +{ +#ifdef _IEEE_LIBM + return __ieee754_jn(n,x); +#else + double z; + z = __ieee754_jn(n,x); + if(_LIB_VERSION == _IEEE_ || fd_isnan(x) ) return z; + if(fd_fabs(x)>X_TLOSS) { + int err; + return __kernel_standard((double)n,x,38,&err); /* jn(|x|>X_TLOSS,n) */ + } else + return z; +#endif +} + +#ifdef __STDC__ + double yn(int n, double x) /* wrapper yn */ +#else + double yn(n,x) /* wrapper yn */ + double x; int n; +#endif +{ +#ifdef _IEEE_LIBM + return __ieee754_yn(n,x); +#else + double z; + int err; + z = __ieee754_yn(n,x); + if(_LIB_VERSION == _IEEE_ || fd_isnan(x) ) return z; + if(x <= 0.0){ + if(x==0.0) + /* d= -one/(x-x); */ + return __kernel_standard((double)n,x,12,&err); + else + /* d = zero/(x-x); */ + return __kernel_standard((double)n,x,13,&err); + } + if(x>X_TLOSS) { + return __kernel_standard((double)n,x,39,&err); /* yn(x>X_TLOSS,n) */ + } else + return z; +#endif +} diff --git a/src/dom/js/fdlibm/w_lgamma.c b/src/dom/js/fdlibm/w_lgamma.c new file mode 100644 index 000000000..f7576e892 --- /dev/null +++ b/src/dom/js/fdlibm/w_lgamma.c @@ -0,0 +1,85 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Sun Microsystems, Inc. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* @(#)w_lgamma.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + * + */ + +/* double lgamma(double x) + * Return the logarithm of the Gamma function of x. + * + * Method: call __ieee754_lgamma_r + */ + +#include "fdlibm.h" + +extern int signgam; + +#ifdef __STDC__ + double fd_lgamma(double x) +#else + double fd_lgamma(x) + double x; +#endif +{ +#ifdef _IEEE_LIBM + return __ieee754_lgamma_r(x,&signgam); +#else + double y; + y = __ieee754_lgamma_r(x,&signgam); + if(_LIB_VERSION == _IEEE_) return y; + if(!fd_finite(y)&&fd_finite(x)) { + int err; + if(fd_floor(x)==x&&x<=0.0) + return __kernel_standard(x,x,15,&err); /* lgamma pole */ + else + return __kernel_standard(x,x,14,&err); /* lgamma overflow */ + } else + return y; +#endif +} diff --git a/src/dom/js/fdlibm/w_lgamma_r.c b/src/dom/js/fdlibm/w_lgamma_r.c new file mode 100644 index 000000000..ba2ad5933 --- /dev/null +++ b/src/dom/js/fdlibm/w_lgamma_r.c @@ -0,0 +1,81 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Sun Microsystems, Inc. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* @(#)w_lgamma_r.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * wrapper double lgamma_r(double x, int *signgamp) + */ + +#include "fdlibm.h" + + +#ifdef __STDC__ + double fd_lgamma_r(double x, int *signgamp) /* wrapper lgamma_r */ +#else + double fd_lgamma_r(x,signgamp) /* wrapper lgamma_r */ + double x; int *signgamp; +#endif +{ +#ifdef _IEEE_LIBM + return __ieee754_lgamma_r(x,signgamp); +#else + double y; + y = __ieee754_lgamma_r(x,signgamp); + if(_LIB_VERSION == _IEEE_) return y; + if(!fd_finite(y)&&fd_finite(x)) { + int err; + if(fd_floor(x)==x&&x<=0.0) + return __kernel_standard(x,x,15,&err); /* lgamma pole */ + else + return __kernel_standard(x,x,14,&err); /* lgamma overflow */ + } else + return y; +#endif +} diff --git a/src/dom/js/fdlibm/w_log.c b/src/dom/js/fdlibm/w_log.c new file mode 100644 index 000000000..7e358fcf1 --- /dev/null +++ b/src/dom/js/fdlibm/w_log.c @@ -0,0 +1,78 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Sun Microsystems, Inc. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* @(#)w_log.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * wrapper log(x) + */ + +#include "fdlibm.h" + + +#ifdef __STDC__ + double fd_log(double x) /* wrapper log */ +#else + double fd_log(x) /* wrapper log */ + double x; +#endif +{ +#ifdef _IEEE_LIBM + return __ieee754_log(x); +#else + double z; + int err; + z = __ieee754_log(x); + if(_LIB_VERSION == _IEEE_ || fd_isnan(x) || x > 0.0) return z; + if(x==0.0) + return __kernel_standard(x,x,16,&err); /* log(0) */ + else + return __kernel_standard(x,x,17,&err); /* log(x<0) */ +#endif +} diff --git a/src/dom/js/fdlibm/w_log10.c b/src/dom/js/fdlibm/w_log10.c new file mode 100644 index 000000000..6b298b236 --- /dev/null +++ b/src/dom/js/fdlibm/w_log10.c @@ -0,0 +1,81 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Sun Microsystems, Inc. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* @(#)w_log10.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * wrapper log10(X) + */ + +#include "fdlibm.h" + + +#ifdef __STDC__ + double fd_log10(double x) /* wrapper log10 */ +#else + double fd_log10(x) /* wrapper log10 */ + double x; +#endif +{ +#ifdef _IEEE_LIBM + return __ieee754_log10(x); +#else + double z; + z = __ieee754_log10(x); + if(_LIB_VERSION == _IEEE_ || fd_isnan(x)) return z; + if(x<=0.0) { + int err; + if(x==0.0) + return __kernel_standard(x,x,18,&err); /* log10(0) */ + else + return __kernel_standard(x,x,19,&err); /* log10(x<0) */ + } else + return z; +#endif +} diff --git a/src/dom/js/fdlibm/w_pow.c b/src/dom/js/fdlibm/w_pow.c new file mode 100644 index 000000000..3d2c15ad3 --- /dev/null +++ b/src/dom/js/fdlibm/w_pow.c @@ -0,0 +1,99 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Sun Microsystems, Inc. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + + +/* @(#)w_pow.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * wrapper pow(x,y) return x**y + */ + +#include "fdlibm.h" + + +#ifdef __STDC__ + double fd_pow(double x, double y) /* wrapper pow */ +#else + double fd_pow(x,y) /* wrapper pow */ + double x,y; +#endif +{ +#ifdef _IEEE_LIBM + return __ieee754_pow(x,y); +#else + double z; + int err; + z=__ieee754_pow(x,y); + if(_LIB_VERSION == _IEEE_|| fd_isnan(y)) return z; + if(fd_isnan(x)) { + if(y==0.0) + return __kernel_standard(x,y,42,&err); /* pow(NaN,0.0) */ + else + return z; + } + if(x==0.0){ + if(y==0.0) + return __kernel_standard(x,y,20,&err); /* pow(0.0,0.0) */ + if(fd_finite(y)&&y<0.0) + return __kernel_standard(x,y,23,&err); /* pow(0.0,negative) */ + return z; + } + if(!fd_finite(z)) { + if(fd_finite(x)&&fd_finite(y)) { + if(fd_isnan(z)) + return __kernel_standard(x,y,24,&err); /* pow neg**non-int */ + else + return __kernel_standard(x,y,21,&err); /* pow overflow */ + } + } + if(z==0.0&&fd_finite(x)&&fd_finite(y)) + return __kernel_standard(x,y,22,&err); /* pow underflow */ + return z; +#endif +} diff --git a/src/dom/js/fdlibm/w_remainder.c b/src/dom/js/fdlibm/w_remainder.c new file mode 100644 index 000000000..25d1ba171 --- /dev/null +++ b/src/dom/js/fdlibm/w_remainder.c @@ -0,0 +1,77 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Sun Microsystems, Inc. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* @(#)w_remainder.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * wrapper remainder(x,p) + */ + +#include "fdlibm.h" + +#ifdef __STDC__ + double fd_remainder(double x, double y) /* wrapper remainder */ +#else + double fd_remainder(x,y) /* wrapper remainder */ + double x,y; +#endif +{ +#ifdef _IEEE_LIBM + return __ieee754_remainder(x,y); +#else + double z; + z = __ieee754_remainder(x,y); + if(_LIB_VERSION == _IEEE_ || fd_isnan(y)) return z; + if(y==0.0) { + int err; + return __kernel_standard(x,y,28,&err); /* remainder(x,0) */ + } else + return z; +#endif +} diff --git a/src/dom/js/fdlibm/w_scalb.c b/src/dom/js/fdlibm/w_scalb.c new file mode 100644 index 000000000..35c16a500 --- /dev/null +++ b/src/dom/js/fdlibm/w_scalb.c @@ -0,0 +1,95 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Sun Microsystems, Inc. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* @(#)w_scalb.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * wrapper scalb(double x, double fn) is provide for + * passing various standard test suite. One + * should use scalbn() instead. + */ + +#include "fdlibm.h" + +#include + +#ifdef __STDC__ +#ifdef _SCALB_INT + double fd_scalb(double x, int fn) /* wrapper scalb */ +#else + double fd_scalb(double x, double fn) /* wrapper scalb */ +#endif +#else + double fd_scalb(x,fn) /* wrapper scalb */ +#ifdef _SCALB_INT + double x; int fn; +#else + double x,fn; +#endif +#endif +{ +#ifdef _IEEE_LIBM + return __ieee754_scalb(x,fn); +#else + double z; + int err; + z = __ieee754_scalb(x,fn); + if(_LIB_VERSION == _IEEE_) return z; + if(!(fd_finite(z)||fd_isnan(z))&&fd_finite(x)) { + return __kernel_standard(x,(double)fn,32,&err); /* scalb overflow */ + } + if(z==0.0&&z!=x) { + return __kernel_standard(x,(double)fn,33,&err); /* scalb underflow */ + } +#ifndef _SCALB_INT + if(!fd_finite(fn)) errno = ERANGE; +#endif + return z; +#endif +} diff --git a/src/dom/js/fdlibm/w_sinh.c b/src/dom/js/fdlibm/w_sinh.c new file mode 100644 index 000000000..8b04ecb7f --- /dev/null +++ b/src/dom/js/fdlibm/w_sinh.c @@ -0,0 +1,77 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Sun Microsystems, Inc. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* @(#)w_sinh.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * wrapper sinh(x) + */ + +#include "fdlibm.h" + +#ifdef __STDC__ + double fd_sinh(double x) /* wrapper sinh */ +#else + double fd_sinh(x) /* wrapper sinh */ + double x; +#endif +{ +#ifdef _IEEE_LIBM + return __ieee754_sinh(x); +#else + double z; + z = __ieee754_sinh(x); + if(_LIB_VERSION == _IEEE_) return z; + if(!fd_finite(z)&&fd_finite(x)) { + int err; + return __kernel_standard(x,x,25,&err); /* sinh overflow */ + } else + return z; +#endif +} diff --git a/src/dom/js/fdlibm/w_sqrt.c b/src/dom/js/fdlibm/w_sqrt.c new file mode 100644 index 000000000..462d776f8 --- /dev/null +++ b/src/dom/js/fdlibm/w_sqrt.c @@ -0,0 +1,77 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Sun Microsystems, Inc. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* @(#)w_sqrt.c 1.3 95/01/18 */ +/* + * ==================================================== + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * ==================================================== + */ + +/* + * wrapper sqrt(x) + */ + +#include "fdlibm.h" + +#ifdef __STDC__ + double fd_sqrt(double x) /* wrapper sqrt */ +#else + double fd_sqrt(x) /* wrapper sqrt */ + double x; +#endif +{ +#ifdef _IEEE_LIBM + return __ieee754_sqrt(x); +#else + double z; + z = __ieee754_sqrt(x); + if(_LIB_VERSION == _IEEE_ || fd_isnan(x)) return z; + if(x<0.0) { + int err; + return __kernel_standard(x,x,26,&err); /* sqrt(negative) */ + } else + return z; +#endif +} diff --git a/src/dom/js/js.c b/src/dom/js/js.c new file mode 100644 index 000000000..5bd296223 --- /dev/null +++ b/src/dom/js/js.c @@ -0,0 +1,2333 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* + * JS shell. + */ +#include "jsstddef.h" +#include +#include +#include +#include +#include "jstypes.h" +#include "jsarena.h" +#include "jsutil.h" +#include "jsprf.h" +#include "jsapi.h" +#include "jsatom.h" +#include "jscntxt.h" +#include "jsdbgapi.h" +#include "jsemit.h" +#include "jsfun.h" +#include "jsgc.h" +#include "jslock.h" +#include "jsobj.h" +#include "jsparse.h" +#include "jsscope.h" +#include "jsscript.h" + +#ifdef PERLCONNECT +#include "perlconnect/jsperl.h" +#endif + +#ifdef LIVECONNECT +#include "jsjava.h" +#endif + +#ifdef JSDEBUGGER +#include "jsdebug.h" +#ifdef JSDEBUGGER_JAVA_UI +#include "jsdjava.h" +#endif /* JSDEBUGGER_JAVA_UI */ +#ifdef JSDEBUGGER_C_UI +#include "jsdb.h" +#endif /* JSDEBUGGER_C_UI */ +#endif /* JSDEBUGGER */ + +#ifdef XP_UNIX +#include +#include +#include +#include +#endif + +#if defined(XP_WIN) || defined(XP_OS2) +#include /* for isatty() */ +#endif + +#define EXITCODE_RUNTIME_ERROR 3 +#define EXITCODE_FILE_NOT_FOUND 4 + +size_t gStackChunkSize = 8192; +static size_t gMaxStackSize = 0; +static jsuword gStackBase; +int gExitCode = 0; +JSBool gQuitting = JS_FALSE; +FILE *gErrFile = NULL; +FILE *gOutFile = NULL; + +#ifdef XP_MAC +#if defined(MAC_TEST_HACK) || defined(XP_MAC_MPW) +/* this is the data file that all Print strings will be echoed into */ +FILE *gTestResultFile = NULL; +#define isatty(f) 0 +#else +#define isatty(f) 1 +#endif + +char *strdup(const char *str) +{ + char *copy = (char *) malloc(strlen(str)+1); + if (copy) + strcpy(copy, str); + return copy; +} + +#ifdef XP_MAC_MPW +/* Macintosh MPW replacements for the ANSI routines. These translate LF's to CR's because + the MPW libraries supplied by Metrowerks don't do that for some reason. */ +static void translateLFtoCR(char *str, int length) +{ + char *limit = str + length; + while (str != limit) { + if (*str == '\n') + *str = '\r'; + str++; + } +} + +int fputc(int c, FILE *file) +{ + char buffer = c; + if (buffer == '\n') + buffer = '\r'; + return fwrite(&buffer, 1, 1, file); +} + +int fputs(const char *s, FILE *file) +{ + char buffer[4096]; + int n = strlen(s); + int extra = 0; + + while (n > sizeof buffer) { + memcpy(buffer, s, sizeof buffer); + translateLFtoCR(buffer, sizeof buffer); + extra += fwrite(buffer, 1, sizeof buffer, file); + n -= sizeof buffer; + s += sizeof buffer; + } + memcpy(buffer, s, n); + translateLFtoCR(buffer, n); + return extra + fwrite(buffer, 1, n, file); +} + +int fprintf(FILE* file, const char *format, ...) +{ + va_list args; + char smallBuffer[4096]; + int n; + int bufferSize = sizeof smallBuffer; + char *buffer = smallBuffer; + int result; + + va_start(args, format); + n = vsnprintf(buffer, bufferSize, format, args); + va_end(args); + while (n < 0) { + if (buffer != smallBuffer) + free(buffer); + bufferSize <<= 1; + buffer = malloc(bufferSize); + if (!buffer) { + JS_ASSERT(JS_FALSE); + return 0; + } + va_start(args, format); + n = vsnprintf(buffer, bufferSize, format, args); + va_end(args); + } + translateLFtoCR(buffer, n); + result = fwrite(buffer, 1, n, file); + if (buffer != smallBuffer) + free(buffer); + return result; +} + + +#else +#include +#include + +static char* mac_argv[] = { "js", NULL }; + +static void initConsole(StringPtr consoleName, const char* startupMessage, int *argc, char** *argv) +{ + SIOUXSettings.autocloseonquit = true; + SIOUXSettings.asktosaveonclose = false; + /* SIOUXSettings.initializeTB = false; + SIOUXSettings.showstatusline = true;*/ + puts(startupMessage); + SIOUXSetTitle(consoleName); + + /* set up a buffer for stderr (otherwise it's a pig). */ + setvbuf(stderr, (char *) malloc(BUFSIZ), _IOLBF, BUFSIZ); + + *argc = 1; + *argv = mac_argv; +} + +#ifdef LIVECONNECT +/* Little hack to provide a default CLASSPATH on the Mac. */ +#define getenv(var) mac_getenv(var) +static char* mac_getenv(const char* var) +{ + if (strcmp(var, "CLASSPATH") == 0) { + static char class_path[] = "liveconnect.jar"; + return class_path; + } + return NULL; +} +#endif /* LIVECONNECT */ + +#endif +#endif + +#ifdef JSDEBUGGER +static JSDContext *_jsdc; +#ifdef JSDEBUGGER_JAVA_UI +static JSDJContext *_jsdjc; +#endif /* JSDEBUGGER_JAVA_UI */ +#endif /* JSDEBUGGER */ + +static JSBool reportWarnings = JS_TRUE; + +typedef enum JSShellErrNum { +#define MSG_DEF(name, number, count, exception, format) \ + name = number, +#include "jsshell.msg" +#undef MSG_DEF + JSShellErr_Limit +#undef MSGDEF +} JSShellErrNum; + +static const JSErrorFormatString * +my_GetErrorMessage(void *userRef, const char *locale, const uintN errorNumber); + +#ifdef EDITLINE +extern char *readline(const char *prompt); +extern void add_history(char *line); +#endif + +static JSBool +GetLine(JSContext *cx, char *bufp, FILE *file, const char *prompt) { +#ifdef EDITLINE + /* + * Use readline only if file is stdin, because there's no way to specify + * another handle. Are other filehandles interactive? + */ + if (file == stdin) { + char *linep = readline(prompt); + if (!linep) + return JS_FALSE; + if (linep[0] != '\0') + add_history(linep); + strcpy(bufp, linep); + JS_free(cx, linep); + bufp += strlen(bufp); + *bufp++ = '\n'; + *bufp = '\0'; + } else +#endif + { + char line[256]; + fprintf(gOutFile, prompt); + fflush(gOutFile); +#ifdef XP_MAC_MPW + /* Print a CR after the prompt because MPW grabs the entire line when entering an interactive command */ + fputc('\n', gOutFile); +#endif + if (!fgets(line, sizeof line, file)) + return JS_FALSE; + strcpy(bufp, line); + } + return JS_TRUE; +} + +static void +Process(JSContext *cx, JSObject *obj, char *filename) +{ + JSBool ok, hitEOF; + JSScript *script; + jsval result; + JSString *str; + char buffer[4096]; + char *bufp; + int lineno; + int startline; + FILE *file; + jsuword stackLimit; + + if (!filename || strcmp(filename, "-") == 0) { + file = stdin; + } else { + file = fopen(filename, "r"); + if (!file) { + JS_ReportErrorNumber(cx, my_GetErrorMessage, NULL, + JSSMSG_CANT_OPEN, filename, strerror(errno)); + gExitCode = EXITCODE_FILE_NOT_FOUND; + return; + } + } + + if (gMaxStackSize == 0) { + /* + * Disable checking for stack overflow if limit is zero. + */ + stackLimit = 0; + } else { +#if JS_STACK_GROWTH_DIRECTION > 0 + stackLimit = gStackBase + gMaxStackSize; +#else + stackLimit = gStackBase - gMaxStackSize; +#endif + } + JS_SetThreadStackLimit(cx, stackLimit); + + if (!isatty(fileno(file))) { + /* + * It's not interactive - just execute it. + * + * Support the UNIX #! shell hack; gobble the first line if it starts + * with '#'. TODO - this isn't quite compatible with sharp variables, + * as a legal js program (using sharp variables) might start with '#'. + * But that would require multi-character lookahead. + */ + int ch = fgetc(file); + if (ch == '#') { + while((ch = fgetc(file)) != EOF) { + if (ch == '\n' || ch == '\r') + break; + } + } + ungetc(ch, file); + script = JS_CompileFileHandle(cx, obj, filename, file); + if (script) { + (void)JS_ExecuteScript(cx, obj, script, &result); + JS_DestroyScript(cx, script); + } + return; + } + + /* It's an interactive filehandle; drop into read-eval-print loop. */ + lineno = 1; + hitEOF = JS_FALSE; + do { + bufp = buffer; + *bufp = '\0'; + + /* + * Accumulate lines until we get a 'compilable unit' - one that either + * generates an error (before running out of source) or that compiles + * cleanly. This should be whenever we get a complete statement that + * coincides with the end of a line. + */ + startline = lineno; + do { + if (!GetLine(cx, bufp, file, startline == lineno ? "js> " : "")) { + hitEOF = JS_TRUE; + break; + } + bufp += strlen(bufp); + lineno++; + } while (!JS_BufferIsCompilableUnit(cx, obj, buffer, strlen(buffer))); + + /* Clear any pending exception from previous failed compiles. */ + JS_ClearPendingException(cx); + script = JS_CompileScript(cx, obj, buffer, strlen(buffer), +#ifdef JSDEBUGGER + "typein", +#else + NULL, +#endif + startline); + if (script) { + ok = JS_ExecuteScript(cx, obj, script, &result); + if (ok && result != JSVAL_VOID) { + str = JS_ValueToString(cx, result); + if (str) + fprintf(gOutFile, "%s\n", JS_GetStringBytes(str)); + else + ok = JS_FALSE; + } + JS_DestroyScript(cx, script); + } + } while (!hitEOF && !gQuitting); + fprintf(gOutFile, "\n"); + return; +} + +static int +usage(void) +{ + fprintf(gErrFile, "%s\n", JS_GetImplementationVersion()); + fprintf(gErrFile, "usage: js [-PswW] [-b branchlimit] [-c stackchunksize] [-v version] [-f scriptfile] [-S maxstacksize] [scriptfile] [scriptarg...]\n"); + return 2; +} + +static uint32 gBranchCount; +static uint32 gBranchLimit; + +static JSBool +my_BranchCallback(JSContext *cx, JSScript *script) +{ + if (++gBranchCount == gBranchLimit) { + if (script->filename) + fprintf(gErrFile, "%s:", script->filename); + fprintf(gErrFile, "%u: script branches too much (%u callbacks)\n", + script->lineno, gBranchLimit); + gBranchCount = 0; + return JS_FALSE; + } + return JS_TRUE; +} + +extern JSClass global_class; + +static int +ProcessArgs(JSContext *cx, JSObject *obj, char **argv, int argc) +{ + int i, j, length; + JSObject *argsObj; + char *filename = NULL; + JSBool isInteractive = JS_TRUE; + + /* + * Scan past all optional arguments so we can create the arguments object + * before processing any -f options, which must interleave properly with + * -v and -w options. This requires two passes, and without getopt, we'll + * have to keep the option logic here and in the second for loop in sync. + */ + for (i = 0; i < argc; i++) { + if (argv[i][0] != '-' || argv[i][1] == '\0') { + ++i; + break; + } + switch (argv[i][1]) { + case 'b': + case 'c': + case 'f': + case 'v': + case 'S': + ++i; + break; + } + } + + /* + * Create arguments early and define it to root it, so it's safe from any + * GC calls nested below, and so it is available to -f arguments. + */ + argsObj = JS_NewArrayObject(cx, 0, NULL); + if (!argsObj) + return 1; + if (!JS_DefineProperty(cx, obj, "arguments", OBJECT_TO_JSVAL(argsObj), + NULL, NULL, 0)) { + return 1; + } + + length = argc - i; + for (j = 0; j < length; j++) { + JSString *str = JS_NewStringCopyZ(cx, argv[i++]); + if (!str) + return 1; + if (!JS_DefineElement(cx, argsObj, j, STRING_TO_JSVAL(str), + NULL, NULL, JSPROP_ENUMERATE)) { + return 1; + } + } + + for (i = 0; i < argc; i++) { + if (argv[i][0] != '-' || argv[i][1] == '\0') { + filename = argv[i++]; + isInteractive = JS_FALSE; + break; + } + + switch (argv[i][1]) { + case 'v': + if (++i == argc) { + return usage(); + } + JS_SetVersion(cx, (JSVersion) atoi(argv[i])); + break; + + case 'w': + reportWarnings = JS_TRUE; + break; + + case 'W': + reportWarnings = JS_FALSE; + break; + + case 's': + JS_ToggleOptions(cx, JSOPTION_STRICT); + break; + + case 'P': + if (JS_GET_CLASS(cx, JS_GetPrototype(cx, obj)) != &global_class) { + JSObject *gobj; + + if (!JS_SealObject(cx, obj, JS_TRUE)) + return JS_FALSE; + gobj = JS_NewObject(cx, &global_class, NULL, NULL); + if (!gobj) + return JS_FALSE; + if (!JS_SetPrototype(cx, gobj, obj)) + return JS_FALSE; + JS_SetParent(cx, gobj, NULL); + JS_SetGlobalObject(cx, gobj); + obj = gobj; + } + break; + + case 'b': + gBranchLimit = atoi(argv[++i]); + JS_SetBranchCallback(cx, my_BranchCallback); + break; + + case 'c': + /* set stack chunk size */ + gStackChunkSize = atoi(argv[++i]); + break; + + case 'f': + if (++i == argc) { + return usage(); + } + Process(cx, obj, argv[i]); + /* + * XXX: js -f foo.js should interpret foo.js and then + * drop into interactive mode, but that breaks test + * harness. Just execute foo.js for now. + */ + isInteractive = JS_FALSE; + break; + + case 'S': + if (++i == argc) { + return usage(); + } + /* Set maximum stack size. */ + gMaxStackSize = atoi(argv[i]); + break; + + default: + return usage(); + } + } + + if (filename || isInteractive) + Process(cx, obj, filename); + return gExitCode; +} + + +static JSBool +Version(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + if (argc > 0 && JSVAL_IS_INT(argv[0])) + *rval = INT_TO_JSVAL(JS_SetVersion(cx, (JSVersion) JSVAL_TO_INT(argv[0]))); + else + *rval = INT_TO_JSVAL(JS_GetVersion(cx)); + return JS_TRUE; +} + +static struct { + const char *name; + uint32 flag; +} js_options[] = { + {"strict", JSOPTION_STRICT}, + {"werror", JSOPTION_WERROR}, + {0, 0} +}; + +static JSBool +Options(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + uint32 optset, flag; + uintN i, j, found; + JSString *str; + const char *opt; + char *names; + + optset = 0; + for (i = 0; i < argc; i++) { + str = JS_ValueToString(cx, argv[i]); + if (!str) + return JS_FALSE; + opt = JS_GetStringBytes(str); + for (j = 0; js_options[j].name; j++) { + if (strcmp(js_options[j].name, opt) == 0) { + optset |= js_options[j].flag; + break; + } + } + } + optset = JS_ToggleOptions(cx, optset); + + names = NULL; + found = 0; + while (optset != 0) { + flag = optset; + optset &= optset - 1; + flag &= ~optset; + for (j = 0; js_options[j].name; j++) { + if (js_options[j].flag == flag) { + names = JS_sprintf_append(names, "%s%s", + names ? "," : "", js_options[j].name); + found++; + break; + } + } + } + if (!found) + names = strdup(""); + if (!names) { + JS_ReportOutOfMemory(cx); + return JS_FALSE; + } + + str = JS_NewString(cx, names, strlen(names)); + if (!str) { + free(names); + return JS_FALSE; + } + *rval = STRING_TO_JSVAL(str); + return JS_TRUE; +} + +static void +my_LoadErrorReporter(JSContext *cx, const char *message, JSErrorReport *report); + +static void +my_ErrorReporter(JSContext *cx, const char *message, JSErrorReport *report); + +static JSBool +Load(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + uintN i; + JSString *str; + const char *filename; + JSScript *script; + JSBool ok; + jsval result; + JSErrorReporter older; + + for (i = 0; i < argc; i++) { + str = JS_ValueToString(cx, argv[i]); + if (!str) + return JS_FALSE; + argv[i] = STRING_TO_JSVAL(str); + filename = JS_GetStringBytes(str); + errno = 0; + older = JS_SetErrorReporter(cx, my_LoadErrorReporter); + script = JS_CompileFile(cx, obj, filename); + if (!script) + ok = JS_FALSE; + else { + ok = JS_ExecuteScript(cx, obj, script, &result); + JS_DestroyScript(cx, script); + } + JS_SetErrorReporter(cx, older); + if (!ok) + return JS_FALSE; + } + + return JS_TRUE; +} + +static JSBool +Print(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + uintN i, n; + JSString *str; + + for (i = n = 0; i < argc; i++) { + str = JS_ValueToString(cx, argv[i]); + if (!str) + return JS_FALSE; + fprintf(gOutFile, "%s%s", i ? " " : "", JS_GetStringBytes(str)); + } + n++; + if (n) + fputc('\n', gOutFile); + return JS_TRUE; +} + +static JSBool +Help(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval); + +static JSBool +Quit(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ +#ifdef LIVECONNECT + JSJ_SimpleShutdown(); +#endif + + JS_ConvertArguments(cx, argc, argv,"/ i", &gExitCode); + + gQuitting = JS_TRUE; + return JS_FALSE; +} + +#ifdef GC_MARK_DEBUG +extern JS_FRIEND_DATA(FILE *) js_DumpGCHeap; +#endif + +static JSBool +GC(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + JSRuntime *rt; + uint32 preBytes; + + rt = cx->runtime; + preBytes = rt->gcBytes; +#ifdef GC_MARK_DEBUG + if (argc && JSVAL_IS_STRING(argv[0])) { + char *name = JS_GetStringBytes(JSVAL_TO_STRING(argv[0])); + FILE *file = fopen(name, "w"); + if (!file) { + fprintf(gErrFile, "gc: can't open %s: %s\n", strerror(errno)); + return JS_FALSE; + } + js_DumpGCHeap = file; + } else { + js_DumpGCHeap = stdout; + } +#endif + JS_GC(cx); +#ifdef GC_MARK_DEBUG + if (js_DumpGCHeap != stdout) + fclose(js_DumpGCHeap); + js_DumpGCHeap = NULL; +#endif + fprintf(gOutFile, "before %lu, after %lu, break %08lx\n", + (unsigned long)preBytes, (unsigned long)rt->gcBytes, +#ifdef XP_UNIX + (unsigned long)sbrk(0) +#else + 0 +#endif + ); +#ifdef JS_GCMETER + js_DumpGCStats(rt, stdout); +#endif + return JS_TRUE; +} + +static JSScript * +ValueToScript(JSContext *cx, jsval v) +{ + JSScript *script; + JSFunction *fun; + + if (JSVAL_IS_OBJECT(v) && + JS_GET_CLASS(cx, JSVAL_TO_OBJECT(v)) == &js_ScriptClass) { + script = (JSScript *) JS_GetPrivate(cx, JSVAL_TO_OBJECT(v)); + } else { + fun = JS_ValueToFunction(cx, v); + if (!fun) + return NULL; + script = fun->script; + } + return script; +} + +static JSBool +GetTrapArgs(JSContext *cx, uintN argc, jsval *argv, JSScript **scriptp, + int32 *ip) +{ + uintN intarg; + JSScript *script; + + *scriptp = cx->fp->down->script; + *ip = 0; + if (argc != 0) { + intarg = 0; + if (JS_TypeOfValue(cx, argv[0]) == JSTYPE_FUNCTION) { + script = ValueToScript(cx, argv[0]); + if (!script) + return JS_FALSE; + *scriptp = script; + intarg++; + } + if (argc > intarg) { + if (!JS_ValueToInt32(cx, argv[intarg], ip)) + return JS_FALSE; + } + } + return JS_TRUE; +} + +static JSTrapStatus +TrapHandler(JSContext *cx, JSScript *script, jsbytecode *pc, jsval *rval, + void *closure) +{ + JSString *str; + JSStackFrame *caller; + + str = (JSString *) closure; + caller = JS_GetScriptedCaller(cx, NULL); + if (!JS_EvaluateScript(cx, caller->scopeChain, + JS_GetStringBytes(str), JS_GetStringLength(str), + caller->script->filename, caller->script->lineno, + rval)) { + return JSTRAP_ERROR; + } + if (*rval != JSVAL_VOID) + return JSTRAP_RETURN; + return JSTRAP_CONTINUE; +} + +static JSBool +Trap(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + JSString *str; + JSScript *script; + int32 i; + + if (argc == 0) { + JS_ReportErrorNumber(cx, my_GetErrorMessage, NULL, JSSMSG_TRAP_USAGE); + return JS_FALSE; + } + argc--; + str = JS_ValueToString(cx, argv[argc]); + if (!str) + return JS_FALSE; + argv[argc] = STRING_TO_JSVAL(str); + if (!GetTrapArgs(cx, argc, argv, &script, &i)) + return JS_FALSE; + return JS_SetTrap(cx, script, script->code + i, TrapHandler, str); +} + +static JSBool +Untrap(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + JSScript *script; + int32 i; + + if (!GetTrapArgs(cx, argc, argv, &script, &i)) + return JS_FALSE; + JS_ClearTrap(cx, script, script->code + i, NULL, NULL); + return JS_TRUE; +} + +static JSBool +LineToPC(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + JSScript *script; + int32 i; + uintN lineno; + jsbytecode *pc; + + if (argc == 0) { + JS_ReportErrorNumber(cx, my_GetErrorMessage, NULL, JSSMSG_LINE2PC_USAGE); + return JS_FALSE; + } + script = cx->fp->down->script; + if (!GetTrapArgs(cx, argc, argv, &script, &i)) + return JS_FALSE; + lineno = (i == 0) ? script->lineno : (uintN)i; + pc = JS_LineNumberToPC(cx, script, lineno); + if (!pc) + return JS_FALSE; + *rval = INT_TO_JSVAL(PTRDIFF(pc, script->code, jsbytecode)); + return JS_TRUE; +} + +static JSBool +PCToLine(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + JSScript *script; + int32 i; + uintN lineno; + + if (!GetTrapArgs(cx, argc, argv, &script, &i)) + return JS_FALSE; + lineno = JS_PCToLineNumber(cx, script, script->code + i); + if (!lineno) + return JS_FALSE; + *rval = INT_TO_JSVAL(lineno); + return JS_TRUE; +} + +#ifdef DEBUG + +static void +SrcNotes(JSContext *cx, JSScript *script) +{ + uintN offset, delta, caseOff; + jssrcnote *notes, *sn; + JSSrcNoteType type; + jsatomid atomIndex; + JSAtom *atom; + + fprintf(gOutFile, "\nSource notes:\n"); + offset = 0; + notes = SCRIPT_NOTES(script); + for (sn = notes; !SN_IS_TERMINATOR(sn); sn = SN_NEXT(sn)) { + delta = SN_DELTA(sn); + offset += delta; + fprintf(gOutFile, "%3u: %5u [%4u] %-8s", + PTRDIFF(sn, notes, jssrcnote), offset, delta, + js_SrcNoteSpec[SN_TYPE(sn)].name); + type = (JSSrcNoteType) SN_TYPE(sn); + switch (type) { + case SRC_SETLINE: + fprintf(gOutFile, " lineno %u", (uintN) js_GetSrcNoteOffset(sn, 0)); + break; + case SRC_FOR: + fprintf(gOutFile, " cond %u update %u tail %u", + (uintN) js_GetSrcNoteOffset(sn, 0), + (uintN) js_GetSrcNoteOffset(sn, 1), + (uintN) js_GetSrcNoteOffset(sn, 2)); + break; + case SRC_COND: + case SRC_IF_ELSE: + case SRC_WHILE: + case SRC_PCBASE: + case SRC_PCDELTA: + fprintf(gOutFile, " offset %u", (uintN) js_GetSrcNoteOffset(sn, 0)); + break; + case SRC_LABEL: + case SRC_LABELBRACE: + case SRC_BREAK2LABEL: + case SRC_CONT2LABEL: + case SRC_FUNCDEF: { + const char *bytes; + JSFunction *fun; + JSString *str; + + atomIndex = (jsatomid) js_GetSrcNoteOffset(sn, 0); + atom = js_GetAtom(cx, &script->atomMap, atomIndex); + if (type != SRC_FUNCDEF) { + bytes = js_AtomToPrintableString(cx, atom); + } else { + fun = (JSFunction *) + JS_GetPrivate(cx, ATOM_TO_OBJECT(atom)); + str = JS_DecompileFunction(cx, fun, JS_DONT_PRETTY_PRINT); + bytes = str ? JS_GetStringBytes(str) : "N/A"; + } + fprintf(gOutFile, " atom %u (%s)", (uintN)atomIndex, bytes); + break; + } + case SRC_SWITCH: + fprintf(gOutFile, " length %u", (uintN) js_GetSrcNoteOffset(sn, 0)); + caseOff = (uintN) js_GetSrcNoteOffset(sn, 1); + if (caseOff) + fprintf(gOutFile, " first case offset %u", caseOff); + break; + case SRC_CATCH: + delta = (uintN) js_GetSrcNoteOffset(sn, 0); + if (delta) + fprintf(gOutFile, " guard size %u", delta); + break; + default:; + } + fputc('\n', gOutFile); + } +} + +static JSBool +Notes(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + uintN i; + JSScript *script; + + for (i = 0; i < argc; i++) { + script = ValueToScript(cx, argv[i]); + if (!script) + continue; + + SrcNotes(cx, script); + } + return JS_TRUE; +} + +static JSBool +TryNotes(JSContext *cx, JSScript *script) +{ + JSTryNote *tn = script->trynotes; + + if (!tn) + return JS_TRUE; + fprintf(gOutFile, "\nException table:\nstart\tend\tcatch\n"); + while (tn->start && tn->catchStart) { + fprintf(gOutFile, " %d\t%d\t%d\n", + tn->start, tn->start + tn->length, tn->catchStart); + tn++; + } + return JS_TRUE; +} + +static JSBool +Disassemble(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + JSBool lines; + uintN i; + JSScript *script; + + if (argc > 0 && + JSVAL_IS_STRING(argv[0]) && + !strcmp(JS_GetStringBytes(JSVAL_TO_STRING(argv[0])), "-l")) { + lines = JS_TRUE; + argv++, argc--; + } else { + lines = JS_FALSE; + } + for (i = 0; i < argc; i++) { + script = ValueToScript(cx, argv[i]); + if (!script) + continue; + + if (JSVAL_IS_FUNCTION(cx, argv[i])) { + JSFunction *fun = JS_ValueToFunction(cx, argv[i]); + if (fun && (fun->flags & JSFUN_FLAGS_MASK)) { + uint8 flags = fun->flags; + fputs("flags:", stdout); + +#define SHOW_FLAG(flag) if (flags & JSFUN_##flag) fputs(" " #flag, stdout); + + SHOW_FLAG(LAMBDA); + SHOW_FLAG(SETTER); + SHOW_FLAG(GETTER); + SHOW_FLAG(BOUND_METHOD); + SHOW_FLAG(HEAVYWEIGHT); + +#undef SHOW_FLAG + putchar('\n'); + } + } + + js_Disassemble(cx, script, lines, stdout); + SrcNotes(cx, script); + TryNotes(cx, script); + } + return JS_TRUE; +} + +static JSBool +DisassWithSrc(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval) +{ +#define LINE_BUF_LEN 512 + uintN i, len, line1, line2, bupline; + JSScript *script; + FILE *file; + char linebuf[LINE_BUF_LEN]; + jsbytecode *pc, *end; + static char sep[] = ";-------------------------"; + + for (i = 0; i < argc; i++) { + script = ValueToScript(cx, argv[i]); + if (!script) + continue; + + if (!script || !script->filename) { + JS_ReportErrorNumber(cx, my_GetErrorMessage, NULL, + JSSMSG_FILE_SCRIPTS_ONLY); + return JS_FALSE; + } + + file = fopen(script->filename, "r"); + if (!file) { + JS_ReportErrorNumber(cx, my_GetErrorMessage, NULL, + JSSMSG_CANT_OPEN, + script->filename, strerror(errno)); + return JS_FALSE; + } + + pc = script->code; + end = pc + script->length; + + /* burn the leading lines */ + line2 = JS_PCToLineNumber(cx, script, pc); + for (line1 = 0; line1 < line2 - 1; line1++) + fgets(linebuf, LINE_BUF_LEN, file); + + bupline = 0; + while (pc < end) { + line2 = JS_PCToLineNumber(cx, script, pc); + + if (line2 < line1) { + if (bupline != line2) { + bupline = line2; + fprintf(gOutFile, "%s %3u: BACKUP\n", sep, line2); + } + } else { + if (bupline && line1 == line2) + fprintf(gOutFile, "%s %3u: RESTORE\n", sep, line2); + bupline = 0; + while (line1 < line2) { + if (!fgets(linebuf, LINE_BUF_LEN, file)) { + JS_ReportErrorNumber(cx, my_GetErrorMessage, NULL, + JSSMSG_UNEXPECTED_EOF, + script->filename); + goto bail; + } + line1++; + fprintf(gOutFile, "%s %3u: %s", sep, line1, linebuf); + } + } + + len = js_Disassemble1(cx, script, pc, + PTRDIFF(pc, script->code, jsbytecode), + JS_TRUE, stdout); + if (!len) + return JS_FALSE; + pc += len; + } + + bail: + fclose(file); + } + return JS_TRUE; +#undef LINE_BUF_LEN +} + +static JSBool +Tracing(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + JSBool bval; + JSString *str; + + if (argc == 0) { + *rval = BOOLEAN_TO_JSVAL(cx->tracefp != 0); + return JS_TRUE; + } + + switch (JS_TypeOfValue(cx, argv[0])) { + case JSTYPE_NUMBER: + bval = JSVAL_IS_INT(argv[0]) + ? JSVAL_TO_INT(argv[0]) + : (jsint) *JSVAL_TO_DOUBLE(argv[0]); + break; + case JSTYPE_BOOLEAN: + bval = JSVAL_TO_BOOLEAN(argv[0]); + break; + default: + str = JS_ValueToString(cx, argv[0]); + if (!str) + return JS_FALSE; + fprintf(gErrFile, "tracing: illegal argument %s\n", + JS_GetStringBytes(str)); + return JS_TRUE; + } + cx->tracefp = bval ? stderr : NULL; + return JS_TRUE; +} + +typedef struct DumpAtomArgs { + JSContext *cx; + FILE *fp; +} DumpAtomArgs; + +static int +DumpAtom(JSHashEntry *he, int i, void *arg) +{ + DumpAtomArgs *args = (DumpAtomArgs *)arg; + FILE *fp = args->fp; + JSAtom *atom = (JSAtom *)he; + + fprintf(fp, "%3d %08x %5lu ", + i, (uintN)he->keyHash, (unsigned long)atom->number); + if (ATOM_IS_STRING(atom)) + fprintf(fp, "\"%s\"\n", js_AtomToPrintableString(args->cx, atom)); + else if (ATOM_IS_INT(atom)) + fprintf(fp, "%ld\n", (long)ATOM_TO_INT(atom)); + else + fprintf(fp, "%.16g\n", *ATOM_TO_DOUBLE(atom)); + return HT_ENUMERATE_NEXT; +} + +static void +DumpScope(JSContext *cx, JSObject *obj, FILE *fp) +{ + uintN i; + JSScope *scope; + JSScopeProperty *sprop; + + i = 0; + scope = OBJ_SCOPE(obj); + for (sprop = SCOPE_LAST_PROP(scope); sprop; sprop = sprop->parent) { + if (SCOPE_HAD_MIDDLE_DELETE(scope) && !SCOPE_HAS_PROPERTY(scope, sprop)) + continue; + fprintf(fp, "%3u %p", i, sprop); + if (JSVAL_IS_INT(sprop->id)) { + fprintf(fp, " [%ld]", (long)JSVAL_TO_INT(sprop->id)); + } else { + fprintf(fp, " \"%s\"", + js_AtomToPrintableString(cx, (JSAtom *)sprop->id)); + } + +#define DUMP_ATTR(name) if (sprop->attrs & JSPROP_##name) fputs(" " #name, fp) + DUMP_ATTR(ENUMERATE); + DUMP_ATTR(READONLY); + DUMP_ATTR(PERMANENT); + DUMP_ATTR(EXPORTED); + DUMP_ATTR(GETTER); + DUMP_ATTR(SETTER); +#undef DUMP_ATTR + + fprintf(fp, " slot %lu flags %x shortid %d\n", + sprop->slot, sprop->flags, sprop->shortid); + } +} + +static JSBool +DumpStats(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + uintN i; + JSString *str; + const char *bytes; + JSAtom *atom; + JSObject *obj2; + JSProperty *prop; + jsval value; + + for (i = 0; i < argc; i++) { + str = JS_ValueToString(cx, argv[i]); + if (!str) + return JS_FALSE; + bytes = JS_GetStringBytes(str); + if (strcmp(bytes, "arena") == 0) { +#ifdef JS_ARENAMETER + JS_DumpArenaStats(stdout); +#endif + } else if (strcmp(bytes, "atom") == 0) { + DumpAtomArgs args; + + fprintf(gOutFile, "\natom table contents:\n"); + args.cx = cx; + args.fp = stdout; + JS_HashTableEnumerateEntries(cx->runtime->atomState.table, + DumpAtom, + &args); +#ifdef HASHMETER + JS_HashTableDumpMeter(cx->runtime->atomState.table, + DumpAtom, + stdout); +#endif + } else if (strcmp(bytes, "global") == 0) { + DumpScope(cx, cx->globalObject, stdout); + } else { + atom = js_Atomize(cx, bytes, JS_GetStringLength(str), 0); + if (!atom) + return JS_FALSE; + if (!js_FindProperty(cx, (jsid)atom, &obj, &obj2, &prop)) + return JS_FALSE; + if (prop) { + OBJ_DROP_PROPERTY(cx, obj2, prop); + if (!OBJ_GET_PROPERTY(cx, obj, (jsid)atom, &value)) + return JS_FALSE; + } + if (!prop || !JSVAL_IS_OBJECT(value)) { + fprintf(gErrFile, "js: invalid stats argument %s\n", + bytes); + continue; + } + obj = JSVAL_TO_OBJECT(value); + if (obj) + DumpScope(cx, obj, stdout); + } + } + return JS_TRUE; +} + +#endif /* DEBUG */ + +#ifdef TEST_EXPORT +static JSBool +DoExport(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + JSAtom *atom; + JSObject *obj2; + JSProperty *prop; + JSBool ok; + uintN attrs; + + if (argc != 2) { + JS_ReportErrorNumber(cx, my_GetErrorMessage, NULL, JSSMSG_DOEXP_USAGE); + return JS_FALSE; + } + if (!JS_ValueToObject(cx, argv[0], &obj)) + return JS_FALSE; + argv[0] = OBJECT_TO_JSVAL(obj); + atom = js_ValueToStringAtom(cx, argv[1]); + if (!atom) + return JS_FALSE; + if (!OBJ_LOOKUP_PROPERTY(cx, obj, (jsid)atom, &obj2, &prop)) + return JS_FALSE; + if (!prop) { + ok = OBJ_DEFINE_PROPERTY(cx, obj, id, JSVAL_VOID, NULL, NULL, + JSPROP_EXPORTED, NULL); + } else { + ok = OBJ_GET_ATTRIBUTES(cx, obj, (jsid)atom, prop, &attrs); + if (ok) { + attrs |= JSPROP_EXPORTED; + ok = OBJ_SET_ATTRIBUTES(cx, obj, (jsid)atom, prop, &attrs); + } + OBJ_DROP_PROPERTY(cx, obj2, prop); + } + return ok; +} +#endif + +#ifdef TEST_CVTARGS +#include + +static const char * +EscapeWideString(jschar *w) +{ + static char enuf[80]; + static char hex[] = "0123456789abcdef"; + jschar u; + unsigned char b, c; + int i, j; + + if (!w) + return ""; + for (i = j = 0; i < sizeof enuf - 1; i++, j++) { + u = w[j]; + if (u == 0) + break; + b = (unsigned char)(u >> 8); + c = (unsigned char)(u); + if (b) { + if (i >= sizeof enuf - 6) + break; + enuf[i++] = '\\'; + enuf[i++] = 'u'; + enuf[i++] = hex[b >> 4]; + enuf[i++] = hex[b & 15]; + enuf[i++] = hex[c >> 4]; + enuf[i] = hex[c & 15]; + } else if (!isprint(c)) { + if (i >= sizeof enuf - 4) + break; + enuf[i++] = '\\'; + enuf[i++] = 'x'; + enuf[i++] = hex[c >> 4]; + enuf[i] = hex[c & 15]; + } else { + enuf[i] = (char)c; + } + } + enuf[i] = 0; + return enuf; +} + +#include + +static JSBool +ZZ_formatter(JSContext *cx, const char *format, JSBool fromJS, jsval **vpp, + va_list *app) +{ + jsval *vp; + va_list ap; + jsdouble re, im; + + printf("entering ZZ_formatter"); + vp = *vpp; + ap = *app; + if (fromJS) { + if (!JS_ValueToNumber(cx, vp[0], &re)) + return JS_FALSE; + if (!JS_ValueToNumber(cx, vp[1], &im)) + return JS_FALSE; + *va_arg(ap, jsdouble *) = re; + *va_arg(ap, jsdouble *) = im; + } else { + re = va_arg(ap, jsdouble); + im = va_arg(ap, jsdouble); + if (!JS_NewNumberValue(cx, re, &vp[0])) + return JS_FALSE; + if (!JS_NewNumberValue(cx, im, &vp[1])) + return JS_FALSE; + } + *vpp = vp + 2; + *app = ap; + printf("leaving ZZ_formatter"); + return JS_TRUE; +} + +static JSBool +ConvertArgs(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + JSBool b = JS_FALSE; + jschar c = 0; + int32 i = 0, j = 0; + uint32 u = 0; + jsdouble d = 0, I = 0, re = 0, im = 0; + char *s = NULL; + JSString *str = NULL; + jschar *w = NULL; + JSObject *obj2 = NULL; + JSFunction *fun = NULL; + jsval v = JSVAL_VOID; + JSBool ok; + + if (!JS_AddArgumentFormatter(cx, "ZZ", ZZ_formatter)) + return JS_FALSE;; + ok = JS_ConvertArguments(cx, argc, argv, "b/ciujdIsSWofvZZ*", + &b, &c, &i, &u, &j, &d, &I, &s, &str, &w, &obj2, + &fun, &v, &re, &im); + JS_RemoveArgumentFormatter(cx, "ZZ"); + if (!ok) + return JS_FALSE; + fprintf(gOutFile, + "b %u, c %x (%c), i %ld, u %lu, j %ld\n", + b, c, (char)c, i, u, j); + fprintf(gOutFile, + "d %g, I %g, s %s, S %s, W %s, obj %s, fun %s\n" + "v %s, re %g, im %g\n", + d, I, s, str ? JS_GetStringBytes(str) : "", EscapeWideString(w), + JS_GetStringBytes(JS_ValueToString(cx, OBJECT_TO_JSVAL(obj2))), + fun ? JS_GetStringBytes(JS_DecompileFunction(cx, fun, 4)) : "", + JS_GetStringBytes(JS_ValueToString(cx, v)), re, im); + return JS_TRUE; +} +#endif + +static JSBool +BuildDate(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + fprintf(gOutFile, "built on %s at %s\n", __DATE__, __TIME__); + return JS_TRUE; +} + +static JSBool +Clear(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + if (argc != 0 && !JS_ValueToObject(cx, argv[0], &obj)) + return JS_FALSE; + JS_ClearScope(cx, obj); + return JS_TRUE; +} + +static JSBool +Intern(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + JSString *str; + + str = JS_ValueToString(cx, argv[0]); + if (!str) + return JS_FALSE; + if (!JS_InternUCStringN(cx, JS_GetStringChars(str), + JS_GetStringLength(str))) { + return JS_FALSE; + } + return JS_TRUE; +} + +static JSBool +Clone(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + JSFunction *fun; + JSObject *funobj, *parent, *clone; + + fun = JS_ValueToFunction(cx, argv[0]); + if (!fun) + return JS_FALSE; + funobj = JS_GetFunctionObject(fun); + if (argc > 1) { + if (!JS_ValueToObject(cx, argv[1], &parent)) + return JS_FALSE; + } else { + parent = JS_GetParent(cx, funobj); + } + clone = JS_CloneFunctionObject(cx, funobj, parent); + if (!clone) + return JS_FALSE; + *rval = OBJECT_TO_JSVAL(clone); + return JS_TRUE; +} + +static JSBool +Seal(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + JSObject *target; + JSBool deep = JS_FALSE; + + if (!JS_ConvertArguments(cx, argc, argv, "o/b", &target, &deep)) + return JS_FALSE; + if (!target) + return JS_TRUE; + return JS_SealObject(cx, target, deep); +} + +static JSFunctionSpec shell_functions[] = { + {"version", Version, 0}, + {"options", Options, 0}, + {"load", Load, 1}, + {"print", Print, 0}, + {"help", Help, 0}, + {"quit", Quit, 0}, + {"gc", GC, 0}, + {"trap", Trap, 3}, + {"untrap", Untrap, 2}, + {"line2pc", LineToPC, 0}, + {"pc2line", PCToLine, 0}, +#ifdef DEBUG + {"dis", Disassemble, 1}, + {"dissrc", DisassWithSrc, 1}, + {"notes", Notes, 1}, + {"tracing", Tracing, 0}, + {"stats", DumpStats, 1}, +#endif +#ifdef TEST_EXPORT + {"xport", DoExport, 2}, +#endif +#ifdef TEST_CVTARGS + {"cvtargs", ConvertArgs, 0, 0, 12}, +#endif + {"build", BuildDate, 0}, + {"clear", Clear, 0}, + {"intern", Intern, 1}, + {"clone", Clone, 1}, + {"seal", Seal, 1, 0, 1}, + {0} +}; + +/* NOTE: These must be kept in sync with the above. */ + +static char *shell_help_messages[] = { + "version([number]) Get or set JavaScript version number", + "options([option ...]) Get or toggle JavaScript options", + "load(['foo.js' ...]) Load files named by string arguments", + "print([exp ...]) Evaluate and print expressions", + "help([name ...]) Display usage and help messages", + "quit() Quit the shell", + "gc() Run the garbage collector", + "trap([fun, [pc,]] exp) Trap bytecode execution", + "untrap(fun[, pc]) Remove a trap", + "line2pc([fun,] line) Map line number to PC", + "pc2line(fun[, pc]) Map PC to line number", +#ifdef DEBUG + "dis([fun]) Disassemble functions into bytecodes", + "dissrc([fun]) Disassemble functions with source lines", + "notes([fun]) Show source notes for functions", + "tracing([toggle]) Turn tracing on or off", + "stats([string ...]) Dump 'arena', 'atom', 'global' stats", +#endif +#ifdef TEST_EXPORT + "xport(obj, id) Export identified property from object", +#endif +#ifdef TEST_CVTARGS + "cvtargs(b, c, ...) Test JS_ConvertArguments", +#endif + "build() Show build date and time", + "clear([obj]) Clear properties of object", + "intern(str) Internalize str in the atom table", + "clone(fun[, scope]) Clone function object", + "seal(obj[, deep]) Seal object, or object graph if deep", + 0 +}; + +static void +ShowHelpHeader(void) +{ + fprintf(gOutFile, "%-9s %-22s %s\n", "Command", "Usage", "Description"); + fprintf(gOutFile, "%-9s %-22s %s\n", "=======", "=====", "==========="); +} + +static void +ShowHelpForCommand(uintN n) +{ + fprintf(gOutFile, "%-9.9s %s\n", shell_functions[n].name, shell_help_messages[n]); +} + +static JSBool +Help(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + uintN i, j; + int did_header, did_something; + JSType type; + JSFunction *fun; + JSString *str; + const char *bytes; + + fprintf(gOutFile, "%s\n", JS_GetImplementationVersion()); + if (argc == 0) { + ShowHelpHeader(); + for (i = 0; shell_functions[i].name; i++) + ShowHelpForCommand(i); + } else { + did_header = 0; + for (i = 0; i < argc; i++) { + did_something = 0; + type = JS_TypeOfValue(cx, argv[i]); + if (type == JSTYPE_FUNCTION) { + fun = JS_ValueToFunction(cx, argv[i]); + str = fun->atom ? ATOM_TO_STRING(fun->atom) : NULL; + } else if (type == JSTYPE_STRING) { + str = JSVAL_TO_STRING(argv[i]); + } else { + str = NULL; + } + if (str) { + bytes = JS_GetStringBytes(str); + for (j = 0; shell_functions[j].name; j++) { + if (!strcmp(bytes, shell_functions[j].name)) { + if (!did_header) { + did_header = 1; + ShowHelpHeader(); + } + did_something = 1; + ShowHelpForCommand(j); + break; + } + } + } + if (!did_something) { + str = JS_ValueToString(cx, argv[i]); + if (!str) + return JS_FALSE; + fprintf(gErrFile, "Sorry, no help for %s\n", + JS_GetStringBytes(str)); + } + } + } + return JS_TRUE; +} + +/* + * Define a JS object called "it". Give it class operations that printf why + * they're being called for tutorial purposes. + */ +enum its_tinyid { + ITS_COLOR, ITS_HEIGHT, ITS_WIDTH, ITS_FUNNY, ITS_ARRAY, ITS_RDONLY +}; + +static JSPropertySpec its_props[] = { + {"color", ITS_COLOR, JSPROP_ENUMERATE}, + {"height", ITS_HEIGHT, JSPROP_ENUMERATE}, + {"width", ITS_WIDTH, JSPROP_ENUMERATE}, + {"funny", ITS_FUNNY, JSPROP_ENUMERATE}, + {"array", ITS_ARRAY, JSPROP_ENUMERATE}, + {"rdonly", ITS_RDONLY, JSPROP_READONLY}, + {0} +}; + +static JSBool +its_item(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + *rval = OBJECT_TO_JSVAL(obj); + if (argc != 0) + JS_SetCallReturnValue2(cx, argv[0]); + return JS_TRUE; +} + +static JSFunctionSpec its_methods[] = { + {"item", its_item, 0}, + {0} +}; + +#ifdef JSD_LOWLEVEL_SOURCE +/* + * This facilitates sending source to JSD (the debugger system) in the shell + * where the source is loaded using the JSFILE hack in jsscan. The function + * below is used as a callback for the jsdbgapi JS_SetSourceHandler hook. + * A more normal embedding (e.g. mozilla) loads source itself and can send + * source directly to JSD without using this hook scheme. + */ +static void +SendSourceToJSDebugger(const char *filename, uintN lineno, + jschar *str, size_t length, + void **listenerTSData, JSDContext* jsdc) +{ + JSDSourceText *jsdsrc = (JSDSourceText *) *listenerTSData; + + if (!jsdsrc) { + if (!filename) + filename = "typein"; + if (1 == lineno) { + jsdsrc = JSD_NewSourceText(jsdc, filename); + } else { + jsdsrc = JSD_FindSourceForURL(jsdc, filename); + if (jsdsrc && JSD_SOURCE_PARTIAL != + JSD_GetSourceStatus(jsdc, jsdsrc)) { + jsdsrc = NULL; + } + } + } + if (jsdsrc) { + jsdsrc = JSD_AppendUCSourceText(jsdc,jsdsrc, str, length, + JSD_SOURCE_PARTIAL); + } + *listenerTSData = jsdsrc; +} +#endif /* JSD_LOWLEVEL_SOURCE */ + +static JSBool its_noisy; /* whether to be noisy when finalizing it */ + +static JSBool +its_addProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp) +{ + if (its_noisy) { + fprintf(gOutFile, "adding its property %s,", + JS_GetStringBytes(JS_ValueToString(cx, id))); + fprintf(gOutFile, " initial value %s\n", + JS_GetStringBytes(JS_ValueToString(cx, *vp))); + } + return JS_TRUE; +} + +static JSBool +its_delProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp) +{ + if (its_noisy) { + fprintf(gOutFile, "deleting its property %s,", + JS_GetStringBytes(JS_ValueToString(cx, id))); + fprintf(gOutFile, " current value %s\n", + JS_GetStringBytes(JS_ValueToString(cx, *vp))); + } + return JS_TRUE; +} + +static JSBool +its_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp) +{ + if (its_noisy) { + fprintf(gOutFile, "getting its property %s,", + JS_GetStringBytes(JS_ValueToString(cx, id))); + fprintf(gOutFile, " current value %s\n", + JS_GetStringBytes(JS_ValueToString(cx, *vp))); + } + return JS_TRUE; +} + +static JSBool +its_setProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp) +{ + if (its_noisy) { + fprintf(gOutFile, "setting its property %s,", + JS_GetStringBytes(JS_ValueToString(cx, id))); + fprintf(gOutFile, " new value %s\n", + JS_GetStringBytes(JS_ValueToString(cx, *vp))); + } + if (JSVAL_IS_STRING(id) && + !strcmp(JS_GetStringBytes(JSVAL_TO_STRING(id)), "noisy")) { + return JS_ValueToBoolean(cx, *vp, &its_noisy); + } + return JS_TRUE; +} + +static JSBool +its_enumerate(JSContext *cx, JSObject *obj) +{ + if (its_noisy) + fprintf(gOutFile, "enumerate its properties\n"); + return JS_TRUE; +} + +static JSBool +its_resolve(JSContext *cx, JSObject *obj, jsval id) +{ + if (its_noisy) { + fprintf(gOutFile, "resolving its property %s\n", + JS_GetStringBytes(JS_ValueToString(cx, id))); + } + return JS_TRUE; +} + +static JSBool +its_convert(JSContext *cx, JSObject *obj, JSType type, jsval *vp) +{ + if (its_noisy) + fprintf(gOutFile, "converting it to %s type\n", JS_GetTypeName(cx, type)); + return JS_TRUE; +} + +static void +its_finalize(JSContext *cx, JSObject *obj) +{ + if (its_noisy) + fprintf(gOutFile, "finalizing it\n"); +} + +static JSClass its_class = { + "It", 0, + its_addProperty, its_delProperty, its_getProperty, its_setProperty, + its_enumerate, its_resolve, its_convert, its_finalize +}; + +JSErrorFormatString jsShell_ErrorFormatString[JSErr_Limit] = { +#if JS_HAS_DFLT_MSG_STRINGS +#define MSG_DEF(name, number, count, exception, format) \ + { format, count } , +#else +#define MSG_DEF(name, number, count, exception, format) \ + { NULL, count } , +#endif +#include "jsshell.msg" +#undef MSG_DEF +}; + +static const JSErrorFormatString * +my_GetErrorMessage(void *userRef, const char *locale, const uintN errorNumber) +{ + if ((errorNumber > 0) && (errorNumber < JSShellErr_Limit)) + return &jsShell_ErrorFormatString[errorNumber]; + return NULL; +} + +static void +my_LoadErrorReporter(JSContext *cx, const char *message, JSErrorReport *report) +{ + if (!report) { + fprintf(gErrFile, "%s\n", message); + return; + } + + /* Ignore any exceptions */ + if (JSREPORT_IS_EXCEPTION(report->flags)) + return; + + /* Otherwise, fall back to the ordinary error reporter. */ + my_ErrorReporter(cx, message, report); +} + +static void +my_ErrorReporter(JSContext *cx, const char *message, JSErrorReport *report) +{ + int i, j, k, n; + char *prefix, *tmp; + const char *ctmp; + + if (!report) { + fprintf(gErrFile, "%s\n", message); + return; + } + + /* Conditionally ignore reported warnings. */ + if (JSREPORT_IS_WARNING(report->flags) && !reportWarnings) + return; + + prefix = NULL; + if (report->filename) + prefix = JS_smprintf("%s:", report->filename); + if (report->lineno) { + tmp = prefix; + prefix = JS_smprintf("%s%u: ", tmp ? tmp : "", report->lineno); + JS_free(cx, tmp); + } + if (JSREPORT_IS_WARNING(report->flags)) { + tmp = prefix; + prefix = JS_smprintf("%s%swarning: ", + tmp ? tmp : "", + JSREPORT_IS_STRICT(report->flags) ? "strict " : ""); + JS_free(cx, tmp); + } + + /* embedded newlines -- argh! */ + while ((ctmp = strchr(message, '\n')) != 0) { + ctmp++; + if (prefix) + fputs(prefix, gErrFile); + fwrite(message, 1, ctmp - message, gErrFile); + message = ctmp; + } + + /* If there were no filename or lineno, the prefix might be empty */ + if (prefix) + fputs(prefix, gErrFile); + fputs(message, gErrFile); + + if (!report->linebuf) { + fputc('\n', gErrFile); + goto out; + } + + /* report->linebuf usually ends with a newline. */ + n = strlen(report->linebuf); + fprintf(gErrFile, ":\n%s%s%s%s", + prefix, + report->linebuf, + (n > 0 && report->linebuf[n-1] == '\n') ? "" : "\n", + prefix); + n = PTRDIFF(report->tokenptr, report->linebuf, char); + for (i = j = 0; i < n; i++) { + if (report->linebuf[i] == '\t') { + for (k = (j + 8) & ~7; j < k; j++) { + fputc('.', gErrFile); + } + continue; + } + fputc('.', gErrFile); + j++; + } + fputs("^\n", gErrFile); + out: + if (!JSREPORT_IS_WARNING(report->flags)) + gExitCode = EXITCODE_RUNTIME_ERROR; + JS_free(cx, prefix); +} + +#if defined(SHELL_HACK) && defined(DEBUG) && defined(XP_UNIX) +static JSBool +Exec(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + JSFunction *fun; + const char *name, **nargv; + uintN i, nargc; + JSString *str; + pid_t pid; + int status; + + fun = JS_ValueToFunction(cx, argv[-2]); + if (!fun) + return JS_FALSE; + if (!fun->atom) + return JS_TRUE; + name = JS_GetStringBytes(ATOM_TO_STRING(fun->atom)); + nargc = 1 + argc; + nargv = JS_malloc(cx, (nargc + 1) * sizeof(char *)); + if (!nargv) + return JS_FALSE; + nargv[0] = name; + for (i = 1; i < nargc; i++) { + str = JS_ValueToString(cx, argv[i-1]); + if (!str) { + JS_free(cx, nargv); + return JS_FALSE; + } + nargv[i] = JS_GetStringBytes(str); + } + nargv[nargc] = 0; + pid = fork(); + switch (pid) { + case -1: + perror("js"); + break; + case 0: + (void) execvp(name, (char **)nargv); + perror("js"); + exit(127); + default: + while (waitpid(pid, &status, 0) < 0 && errno == EINTR) + continue; + break; + } + JS_free(cx, nargv); + return JS_TRUE; +} +#endif + +#define LAZY_STANDARD_CLASSES + +static JSBool +global_enumerate(JSContext *cx, JSObject *obj) +{ +#ifdef LAZY_STANDARD_CLASSES + return JS_EnumerateStandardClasses(cx, obj); +#else + return JS_TRUE; +#endif +} + +static JSBool +global_resolve(JSContext *cx, JSObject *obj, jsval id, uintN flags, + JSObject **objp) +{ +#ifdef LAZY_STANDARD_CLASSES + if ((flags & JSRESOLVE_ASSIGNING) == 0) { + JSBool resolved; + + if (!JS_ResolveStandardClass(cx, obj, id, &resolved)) + return JS_FALSE; + if (resolved) { + *objp = obj; + return JS_TRUE; + } + } +#endif + +#if defined(SHELL_HACK) && defined(DEBUG) && defined(XP_UNIX) + if ((flags & (JSRESOLVE_QUALIFIED | JSRESOLVE_ASSIGNING)) == 0) { + /* + * Do this expensive hack only for unoptimized Unix builds, which are + * not used for benchmarking. + */ + char *path, *comp, *full; + const char *name; + JSBool ok, found; + JSFunction *fun; + + if (!JSVAL_IS_STRING(id)) + return JS_TRUE; + path = getenv("PATH"); + if (!path) + return JS_TRUE; + path = JS_strdup(cx, path); + if (!path) + return JS_FALSE; + name = JS_GetStringBytes(JSVAL_TO_STRING(id)); + ok = JS_TRUE; + for (comp = strtok(path, ":"); comp; comp = strtok(NULL, ":")) { + if (*comp != '\0') { + full = JS_smprintf("%s/%s", comp, name); + if (!full) { + JS_ReportOutOfMemory(cx); + ok = JS_FALSE; + break; + } + } else { + full = (char *)name; + } + found = (access(full, X_OK) == 0); + if (*comp != '\0') + free(full); + if (found) { + fun = JS_DefineFunction(cx, obj, name, Exec, 0, + JSPROP_ENUMERATE); + ok = (fun != NULL); + if (ok) + *objp = obj; + break; + } + } + JS_free(cx, path); + return ok; + } +#else + return JS_TRUE; +#endif +} + +JSClass global_class = { + "global", JSCLASS_NEW_RESOLVE, + JS_PropertyStub, JS_PropertyStub, + JS_PropertyStub, JS_PropertyStub, + global_enumerate, (JSResolveOp) global_resolve, + JS_ConvertStub, JS_FinalizeStub +}; + +static JSBool +env_setProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp) +{ +/* XXX porting may be easy, but these don't seem to supply setenv by default */ +#if !defined XP_BEOS && !defined XP_OS2 && !defined SOLARIS + JSString *idstr, *valstr; + const char *name, *value; + int rv; + + idstr = JS_ValueToString(cx, id); + valstr = JS_ValueToString(cx, *vp); + if (!idstr || !valstr) + return JS_FALSE; + name = JS_GetStringBytes(idstr); + value = JS_GetStringBytes(valstr); +#if defined XP_WIN || defined HPUX || defined OSF1 || defined IRIX + { + char *waste = JS_smprintf("%s=%s", name, value); + if (!waste) { + JS_ReportOutOfMemory(cx); + return JS_FALSE; + } + rv = putenv(waste); +#ifdef XP_WIN + /* + * HPUX9 at least still has the bad old non-copying putenv. + * + * Per mail from , OSF1 also has a putenv + * that will crash if you pass it an auto char array (so it must place + * its argument directly in the char *environ[] array). + */ + free(waste); +#endif + } +#else + rv = setenv(name, value, 1); +#endif + if (rv < 0) { + JS_ReportError(cx, "can't set envariable %s to %s", name, value); + return JS_FALSE; + } + *vp = STRING_TO_JSVAL(valstr); +#endif /* !defined XP_BEOS && !defined XP_OS2 && !defined SOLARIS */ + return JS_TRUE; +} + +static JSBool +env_enumerate(JSContext *cx, JSObject *obj) +{ + static JSBool reflected; + char **evp, *name, *value; + JSString *valstr; + JSBool ok; + + if (reflected) + return JS_TRUE; + + for (evp = (char **)JS_GetPrivate(cx, obj); (name = *evp) != NULL; evp++) { + value = strchr(name, '='); + if (!value) + continue; + *value++ = '\0'; + valstr = JS_NewStringCopyZ(cx, value); + if (!valstr) { + ok = JS_FALSE; + } else { + ok = JS_DefineProperty(cx, obj, name, STRING_TO_JSVAL(valstr), + NULL, NULL, JSPROP_ENUMERATE); + } + value[-1] = '='; + if (!ok) + return JS_FALSE; + } + + reflected = JS_TRUE; + return JS_TRUE; +} + +static JSBool +env_resolve(JSContext *cx, JSObject *obj, jsval id, uintN flags, + JSObject **objp) +{ + JSString *idstr, *valstr; + const char *name, *value; + + if (flags & JSRESOLVE_ASSIGNING) + return JS_TRUE; + + idstr = JS_ValueToString(cx, id); + if (!idstr) + return JS_FALSE; + name = JS_GetStringBytes(idstr); + value = getenv(name); + if (value) { + valstr = JS_NewStringCopyZ(cx, value); + if (!valstr) + return JS_FALSE; + if (!JS_DefineProperty(cx, obj, name, STRING_TO_JSVAL(valstr), + NULL, NULL, JSPROP_ENUMERATE)) { + return JS_FALSE; + } + *objp = obj; + } + return JS_TRUE; +} + +static JSClass env_class = { + "environment", JSCLASS_HAS_PRIVATE | JSCLASS_NEW_RESOLVE, + JS_PropertyStub, JS_PropertyStub, + JS_PropertyStub, env_setProperty, + env_enumerate, (JSResolveOp) env_resolve, + JS_ConvertStub, JS_FinalizeStub +}; + +int +main(int argc, char **argv, char **envp) +{ + int stackDummy; + JSVersion version; + JSRuntime *rt; + JSContext *cx; + JSObject *glob, *it, *envobj; + int result; +#ifdef LIVECONNECT + JavaVM *java_vm = NULL; +#endif +#ifdef JSDEBUGGER_JAVA_UI + JNIEnv *java_env; +#endif + + gStackBase = (jsuword)&stackDummy; + +#ifdef XP_OS2 + /* these streams are normally line buffered on OS/2 and need a \n, * + * so we need to unbuffer then to get a reasonable prompt */ + setbuf(stdout,0); + setbuf(stderr,0); +#endif + + gErrFile = stderr; + gOutFile = stdout; + +#ifdef XP_MAC +#ifndef XP_MAC_MPW + initConsole("\pJavaScript Shell", "Welcome to js shell.", &argc, &argv); +#endif +#endif + +#ifdef MAC_TEST_HACK +/* + Open a file "testArgs.txt" and read each line into argc/argv. + Re-direct all output to "results.txt" +*/ + { + char argText[256]; + FILE *f = fopen("testargs.txt", "r"); + if (f) { + int maxArgs = 32; /* arbitrary max !!! */ + int argText_strlen; + argc = 1; + argv = malloc(sizeof(char *) * maxArgs); + argv[0] = NULL; + while (fgets(argText, 255, f)) { + /* argText includes '\n' */ + argText_strlen = strlen(argText); + argv[argc] = malloc(argText_strlen); + strncpy(argv[argc], argText, argText_strlen - 1); + argv[argc][argText_strlen - 1] = '\0'; + argc++; + if (argc >= maxArgs) + break; + } + fclose(f); + } + gTestResultFile = fopen("results.txt", "w"); + } + + gErrFile = gTestResultFile; + gOutFile = gTestResultFile; +#endif + + version = JSVERSION_DEFAULT; + + argc--; + argv++; + + rt = JS_NewRuntime(8L * 1024L * 1024L); + if (!rt) + return 1; + + cx = JS_NewContext(rt, gStackChunkSize); + if (!cx) + return 1; + JS_SetErrorReporter(cx, my_ErrorReporter); + + glob = JS_NewObject(cx, &global_class, NULL, NULL); + if (!glob) + return 1; +#ifdef LAZY_STANDARD_CLASSES + JS_SetGlobalObject(cx, glob); +#else + if (!JS_InitStandardClasses(cx, glob)) + return 1; +#endif + if (!JS_DefineFunctions(cx, glob, shell_functions)) + return 1; + + /* Set version only after there is a global object. */ + if (version != JSVERSION_DEFAULT) + JS_SetVersion(cx, version); + + it = JS_DefineObject(cx, glob, "it", &its_class, NULL, 0); + if (!it) + return 1; + if (!JS_DefineProperties(cx, it, its_props)) + return 1; + if (!JS_DefineFunctions(cx, it, its_methods)) + return 1; + +#ifdef PERLCONNECT + if (!JS_InitPerlClass(cx, glob)) + return 1; +#endif + +#ifdef JSDEBUGGER + /* + * XXX A command line option to enable debugging (or not) would be good + */ + _jsdc = JSD_DebuggerOnForUser(rt, NULL, NULL); + if (!_jsdc) + return 1; + JSD_JSContextInUse(_jsdc, cx); +#ifdef JSD_LOWLEVEL_SOURCE + JS_SetSourceHandler(rt, SendSourceToJSDebugger, _jsdc); +#endif /* JSD_LOWLEVEL_SOURCE */ +#ifdef JSDEBUGGER_JAVA_UI + _jsdjc = JSDJ_CreateContext(); + if (! _jsdjc) + return 1; + JSDJ_SetJSDContext(_jsdjc, _jsdc); + java_env = JSDJ_CreateJavaVMAndStartDebugger(_jsdjc); +#ifdef LIVECONNECT + if (java_env) + (*java_env)->GetJavaVM(java_env, &java_vm); +#endif + /* + * XXX This would be the place to wait for the debugger to start. + * Waiting would be nice in general, but especially when a js file + * is passed on the cmd line. + */ +#endif /* JSDEBUGGER_JAVA_UI */ +#ifdef JSDEBUGGER_C_UI + JSDB_InitDebugger(rt, _jsdc, 0); +#endif /* JSDEBUGGER_C_UI */ +#endif /* JSDEBUGGER */ + +#ifdef LIVECONNECT + if (!JSJ_SimpleInit(cx, glob, java_vm, getenv("CLASSPATH"))) + return 1; +#endif + + envobj = JS_DefineObject(cx, glob, "environment", &env_class, NULL, 0); + if (!envobj || !JS_SetPrivate(cx, envobj, envp)) + return 1; + + result = ProcessArgs(cx, glob, argv, argc); + +#ifdef JSDEBUGGER + if (_jsdc) + JSD_DebuggerOff(_jsdc); +#endif /* JSDEBUGGER */ + +#ifdef MAC_TEST_HACK + fclose(gTestResultFile); +#endif + + JS_DestroyContext(cx); + JS_DestroyRuntime(rt); + JS_ShutDown(); + return result; +} diff --git a/src/dom/js/js.mak b/src/dom/js/js.mak new file mode 100644 index 000000000..0f8b8f53c --- /dev/null +++ b/src/dom/js/js.mak @@ -0,0 +1,4025 @@ +# Microsoft Developer Studio Generated NMAKE File, Format Version 4.20 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 +# TARGTYPE "Win32 (x86) Static Library" 0x0104 + +!IF "$(CFG)" == "" +CFG=jsshell - Win32 Debug +!MESSAGE No configuration specified. Defaulting to jsshell - Win32 Debug. +!ENDIF + +!IF "$(CFG)" != "js - Win32 Release" && "$(CFG)" != "js - Win32 Debug" &&\ + "$(CFG)" != "jsshell - Win32 Release" && "$(CFG)" != "jsshell - Win32 Debug" &&\ + "$(CFG)" != "fdlibm - Win32 Release" && "$(CFG)" != "fdlibm - Win32 Debug" +!MESSAGE Invalid configuration "$(CFG)" specified. +!MESSAGE You can specify a configuration when running NMAKE on this makefile +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "js.mak" CFG="jsshell - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "js - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "js - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "jsshell - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "jsshell - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE "fdlibm - Win32 Release" (based on "Win32 (x86) Static Library") +!MESSAGE "fdlibm - Win32 Debug" (based on "Win32 (x86) Static Library") +!MESSAGE +!ERROR An invalid configuration is specified. +!ENDIF + +!IF "$(OS)" == "Windows_NT" +NULL= +!ELSE +NULL=nul +!ENDIF +################################################################################ +# Begin Project +# PROP Target_Last_Scanned "jsshell - Win32 Debug" + +!IF "$(CFG)" == "js - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "js___Wi1" +# PROP BASE Intermediate_Dir "js___Wi1" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +OUTDIR=.\Release +INTDIR=.\Release + +ALL : "fdlibm - Win32 Release" "$(OUTDIR)\js32.dll" + +CLEAN : + -@erase "$(INTDIR)\jsapi.obj" + -@erase "$(INTDIR)\jsarena.obj" + -@erase "$(INTDIR)\jsarray.obj" + -@erase "$(INTDIR)\jsatom.obj" + -@erase "$(INTDIR)\jsbool.obj" + -@erase "$(INTDIR)\jscntxt.obj" + -@erase "$(INTDIR)\jsdate.obj" + -@erase "$(INTDIR)\jsdbgapi.obj" + -@erase "$(INTDIR)\jsdhash.obj" + -@erase "$(INTDIR)\jsdtoa.obj" + -@erase "$(INTDIR)\jsemit.obj" + -@erase "$(INTDIR)\jsexn.obj" + -@erase "$(INTDIR)\jsfun.obj" + -@erase "$(INTDIR)\jsgc.obj" + -@erase "$(INTDIR)\jshash.obj" + -@erase "$(INTDIR)\jsinterp.obj" + -@erase "$(INTDIR)\jslock.obj" + -@erase "$(INTDIR)\jslog2.obj" + -@erase "$(INTDIR)\jslong.obj" + -@erase "$(INTDIR)\jsmath.obj" + -@erase "$(INTDIR)\jsnum.obj" + -@erase "$(INTDIR)\jsobj.obj" + -@erase "$(INTDIR)\jsopcode.obj" + -@erase "$(INTDIR)\jsparse.obj" + -@erase "$(INTDIR)\jsprf.obj" + -@erase "$(INTDIR)\jsregexp.obj" + -@erase "$(INTDIR)\jsscan.obj" + -@erase "$(INTDIR)\jsscope.obj" + -@erase "$(INTDIR)\jsscript.obj" + -@erase "$(INTDIR)\jsstr.obj" + -@erase "$(INTDIR)\jsutil.obj" + -@erase "$(INTDIR)\jsxdrapi.obj" + -@erase "$(INTDIR)\prmjtime.obj" + -@erase "$(OUTDIR)\js32.dll" + -@erase "$(OUTDIR)\js32.exp" + -@erase "$(OUTDIR)\js32.lib" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +CPP=cl.exe +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D _X86_=1 /D "_WINDOWS" /YX /c +# ADD CPP /nologo /MD /W3 /GX /O2 /D "NDEBUG" /D _X86_=1 /D "_WINDOWS" /D "WIN32" /D "XP_WIN" /D "JSFILE" /D "EXPORT_JS_API" /YX /c +CPP_PROJ=/nologo /MD /W3 /GX /O2 /D "NDEBUG" /D _X86_=1 /D "_WINDOWS" /D "WIN32" /D\ + "XP_WIN" /D "JSFILE" /D "EXPORT_JS_API" /Fp"$(INTDIR)/js.pch" /YX\ + /Fo"$(INTDIR)/" /c +CPP_OBJS=.\Release/ +CPP_SBRS=.\. + +.c{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.c{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +MTL=mktyplib.exe +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /win32 +MTL_PROJ=/nologo /D "NDEBUG" /win32 +RSC=rc.exe +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/js.bsc" +BSC32_SBRS= \ + +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386 /out:"Release/js32.dll" +# SUBTRACT LINK32 /nodefaultlib +LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\ + advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib\ + odbccp32.lib /nologo /subsystem:windows /dll /incremental:no\ + /pdb:"$(OUTDIR)/js32.pdb" /machine:I386 /out:"$(OUTDIR)/js32.dll"\ + /implib:"$(OUTDIR)/js32.lib" /opt:ref /opt:noicf +LINK32_OBJS= \ + "$(INTDIR)\jsapi.obj" \ + "$(INTDIR)\jsarena.obj" \ + "$(INTDIR)\jsarray.obj" \ + "$(INTDIR)\jsatom.obj" \ + "$(INTDIR)\jsbool.obj" \ + "$(INTDIR)\jscntxt.obj" \ + "$(INTDIR)\jsdate.obj" \ + "$(INTDIR)\jsdbgapi.obj" \ + "$(INTDIR)\jsdhash.obj" \ + "$(INTDIR)\jsdtoa.obj" \ + "$(INTDIR)\jsemit.obj" \ + "$(INTDIR)\jsexn.obj" \ + "$(INTDIR)\jsfun.obj" \ + "$(INTDIR)\jsgc.obj" \ + "$(INTDIR)\jshash.obj" \ + "$(INTDIR)\jsinterp.obj" \ + "$(INTDIR)\jslock.obj" \ + "$(INTDIR)\jslog2.obj" \ + "$(INTDIR)\jslong.obj" \ + "$(INTDIR)\jsmath.obj" \ + "$(INTDIR)\jsnum.obj" \ + "$(INTDIR)\jsobj.obj" \ + "$(INTDIR)\jsopcode.obj" \ + "$(INTDIR)\jsparse.obj" \ + "$(INTDIR)\jsprf.obj" \ + "$(INTDIR)\jsregexp.obj" \ + "$(INTDIR)\jsscan.obj" \ + "$(INTDIR)\jsscope.obj" \ + "$(INTDIR)\jsscript.obj" \ + "$(INTDIR)\jsstr.obj" \ + "$(INTDIR)\jsutil.obj" \ + "$(INTDIR)\jsxdrapi.obj" \ + "$(INTDIR)\prmjtime.obj" \ + "$(OUTDIR)\fdlibm.lib" + +"$(OUTDIR)\js32.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "js - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "js___Wi2" +# PROP BASE Intermediate_Dir "js___Wi2" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +OUTDIR=.\Debug +INTDIR=.\Debug + +ALL : "fdlibm - Win32 Debug" "$(OUTDIR)\js32.dll" + +CLEAN : + -@erase "$(INTDIR)\jsapi.obj" + -@erase "$(INTDIR)\jsarena.obj" + -@erase "$(INTDIR)\jsarray.obj" + -@erase "$(INTDIR)\jsatom.obj" + -@erase "$(INTDIR)\jsbool.obj" + -@erase "$(INTDIR)\jscntxt.obj" + -@erase "$(INTDIR)\jsdate.obj" + -@erase "$(INTDIR)\jsdbgapi.obj" + -@erase "$(INTDIR)\jsdhash.obj" + -@erase "$(INTDIR)\jsdtoa.obj" + -@erase "$(INTDIR)\jsemit.obj" + -@erase "$(INTDIR)\jsexn.obj" + -@erase "$(INTDIR)\jsfun.obj" + -@erase "$(INTDIR)\jsgc.obj" + -@erase "$(INTDIR)\jshash.obj" + -@erase "$(INTDIR)\jsinterp.obj" + -@erase "$(INTDIR)\jslock.obj" + -@erase "$(INTDIR)\jslog2.obj" + -@erase "$(INTDIR)\jslong.obj" + -@erase "$(INTDIR)\jsmath.obj" + -@erase "$(INTDIR)\jsnum.obj" + -@erase "$(INTDIR)\jsobj.obj" + -@erase "$(INTDIR)\jsopcode.obj" + -@erase "$(INTDIR)\jsparse.obj" + -@erase "$(INTDIR)\jsprf.obj" + -@erase "$(INTDIR)\jsregexp.obj" + -@erase "$(INTDIR)\jsscan.obj" + -@erase "$(INTDIR)\jsscope.obj" + -@erase "$(INTDIR)\jsscript.obj" + -@erase "$(INTDIR)\jsstr.obj" + -@erase "$(INTDIR)\jsutil.obj" + -@erase "$(INTDIR)\jsxdrapi.obj" + -@erase "$(INTDIR)\prmjtime.obj" + -@erase "$(INTDIR)\vc40.idb" + -@erase "$(INTDIR)\vc40.pdb" + -@erase "$(OUTDIR)\js32.dll" + -@erase "$(OUTDIR)\js32.exp" + -@erase "$(OUTDIR)\js32.ilk" + -@erase "$(OUTDIR)\js32.lib" + -@erase "$(OUTDIR)\js32.pdb" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +CPP=cl.exe +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D _X86_=1 /D "_WINDOWS" /YX /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /D "_DEBUG" /D "DEBUG" /D _X86_=1 /D "_WINDOWS" /D "WIN32" /D "XP_WIN" /D "JSFILE" /D "EXPORT_JS_API" /YX /c +CPP_PROJ=/nologo /MDd /W3 /Gm /GX /Zi /Od /D "_DEBUG" /D "DEBUG" /D _X86_=1 /D "_WINDOWS"\ + /D "WIN32" /D "XP_WIN" /D "JSFILE" /D "EXPORT_JS_API" /Fp"$(INTDIR)/js.pch" /YX\ + /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c +CPP_OBJS=.\Debug/ +CPP_SBRS=.\. + +.c{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.c{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +MTL=mktyplib.exe +# ADD BASE MTL /nologo /D "_DEBUG" /win32 +# ADD MTL /nologo /D "_DEBUG" /win32 +MTL_PROJ=/nologo /D "_DEBUG" /win32 +RSC=rc.exe +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/js.bsc" +BSC32_SBRS= \ + +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /out:"Debug/js32.dll" +# SUBTRACT LINK32 /nodefaultlib +LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\ + advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib\ + odbccp32.lib /nologo /subsystem:windows /dll /incremental:yes\ + /pdb:"$(OUTDIR)/js32.pdb" /debug /machine:I386 /out:"$(OUTDIR)/js32.dll"\ + /implib:"$(OUTDIR)/js32.lib" +LINK32_OBJS= \ + "$(INTDIR)\jsapi.obj" \ + "$(INTDIR)\jsarena.obj" \ + "$(INTDIR)\jsarray.obj" \ + "$(INTDIR)\jsatom.obj" \ + "$(INTDIR)\jsbool.obj" \ + "$(INTDIR)\jscntxt.obj" \ + "$(INTDIR)\jsdate.obj" \ + "$(INTDIR)\jsdbgapi.obj" \ + "$(INTDIR)\jsdhash.obj" \ + "$(INTDIR)\jsdtoa.obj" \ + "$(INTDIR)\jsemit.obj" \ + "$(INTDIR)\jsexn.obj" \ + "$(INTDIR)\jsfun.obj" \ + "$(INTDIR)\jsgc.obj" \ + "$(INTDIR)\jshash.obj" \ + "$(INTDIR)\jsinterp.obj" \ + "$(INTDIR)\jslock.obj" \ + "$(INTDIR)\jslog2.obj" \ + "$(INTDIR)\jslong.obj" \ + "$(INTDIR)\jsmath.obj" \ + "$(INTDIR)\jsnum.obj" \ + "$(INTDIR)\jsobj.obj" \ + "$(INTDIR)\jsopcode.obj" \ + "$(INTDIR)\jsparse.obj" \ + "$(INTDIR)\jsprf.obj" \ + "$(INTDIR)\jsregexp.obj" \ + "$(INTDIR)\jsscan.obj" \ + "$(INTDIR)\jsscope.obj" \ + "$(INTDIR)\jsscript.obj" \ + "$(INTDIR)\jsstr.obj" \ + "$(INTDIR)\jsutil.obj" \ + "$(INTDIR)\jsxdrapi.obj" \ + "$(INTDIR)\prmjtime.obj" \ + "$(OUTDIR)\fdlibm.lib" + +"$(OUTDIR)\js32.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "jsshell - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "jsshell\Release" +# PROP BASE Intermediate_Dir "jsshell\Release" +# PROP BASE Target_Dir "jsshell" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "jsshell" +OUTDIR=.\Release +INTDIR=.\Release + +ALL : "js - Win32 Release" "$(OUTDIR)\jsshell.exe" + +CLEAN : + -@erase "$(INTDIR)\js.obj" + -@erase "$(OUTDIR)\jsshell.exe" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +CPP=cl.exe +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /c +# ADD CPP /nologo /MD /W3 /GX /O2 /D "NDEBUG" /D "_CONSOLE" /D "WIN32" /D "XP_WIN" /D "JSFILE" /YX /c +CPP_PROJ=/nologo /MD /W3 /GX /O2 /D "NDEBUG" /D "_CONSOLE" /D "WIN32" /D\ + "XP_WIN" /D "JSFILE" /Fp"$(INTDIR)/jsshell.pch" /YX /Fo"$(INTDIR)/" /c +CPP_OBJS=.\Release/ +CPP_SBRS=.\. + +.c{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.c{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +RSC=rc.exe +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/jsshell.bsc" +BSC32_SBRS= \ + +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\ + advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib\ + odbccp32.lib /nologo /subsystem:console /incremental:no\ + /pdb:"$(OUTDIR)/jsshell.pdb" /machine:I386 /out:"$(OUTDIR)/jsshell.exe" +LINK32_OBJS= \ + "$(INTDIR)\js.obj" \ + "$(OUTDIR)\js32.lib" + +"$(OUTDIR)\jsshell.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "jsshell - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "jsshell\jsshell_" +# PROP BASE Intermediate_Dir "jsshell\jsshell_" +# PROP BASE Target_Dir "jsshell" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "jsshell" +OUTDIR=.\Debug +INTDIR=.\Debug + +ALL : "js - Win32 Debug" "$(OUTDIR)\jsshell.exe" + +CLEAN : + -@erase "$(INTDIR)\js.obj" + -@erase "$(INTDIR)\vc40.idb" + -@erase "$(INTDIR)\vc40.pdb" + -@erase "$(OUTDIR)\jsshell.exe" + -@erase "$(OUTDIR)\jsshell.ilk" + -@erase "$(OUTDIR)\jsshell.pdb" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +CPP=cl.exe +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /D "_CONSOLE" /D "_DEBUG" /D "WIN32" /D "XP_WIN" /D "JSFILE" /D "DEBUG" /YX /c +CPP_PROJ=/nologo /MDd /W3 /Gm /GX /Zi /Od /D "_CONSOLE" /D "_DEBUG" /D "WIN32"\ + /D "XP_WIN" /D "JSFILE" /D "DEBUG" /Fp"$(INTDIR)/jsshell.pch" /YX\ + /Fo"$(INTDIR)/" /Fd"$(INTDIR)/" /c +CPP_OBJS=.\Debug/ +CPP_SBRS=.\. + +.c{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.c{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +RSC=rc.exe +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/jsshell.bsc" +BSC32_SBRS= \ + +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 +LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib\ + advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib\ + odbccp32.lib /nologo /subsystem:console /incremental:yes\ + /pdb:"$(OUTDIR)/jsshell.pdb" /debug /machine:I386 /out:"$(OUTDIR)/jsshell.exe" +LINK32_OBJS= \ + "$(INTDIR)\js.obj" \ + "$(OUTDIR)\js32.lib" + +"$(OUTDIR)\jsshell.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "fdlibm - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "fdlibm\Release" +# PROP BASE Intermediate_Dir "fdlibm\Release" +# PROP BASE Target_Dir "fdlibm" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "fdlibm" +OUTDIR=.\Release +INTDIR=.\Release + +ALL : "$(OUTDIR)\fdlibm.lib" + +CLEAN : + -@erase "$(INTDIR)\e_atan2.obj" + -@erase "$(INTDIR)\e_pow.obj" + -@erase "$(INTDIR)\e_sqrt.obj" + -@erase "$(INTDIR)\k_standard.obj" + -@erase "$(INTDIR)\s_atan.obj" + -@erase "$(INTDIR)\s_copysign.obj" + -@erase "$(INTDIR)\s_fabs.obj" + -@erase "$(INTDIR)\s_finite.obj" + -@erase "$(INTDIR)\s_isnan.obj" + -@erase "$(INTDIR)\s_matherr.obj" + -@erase "$(INTDIR)\s_rint.obj" + -@erase "$(INTDIR)\s_scalbn.obj" + -@erase "$(INTDIR)\w_atan2.obj" + -@erase "$(INTDIR)\w_pow.obj" + -@erase "$(INTDIR)\w_sqrt.obj" + -@erase "$(OUTDIR)\fdlibm.lib" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +CPP=cl.exe +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D _X86_=1 /D "_WINDOWS" /YX /c +# ADD CPP /nologo /MD /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D _X86_=1 /D "_WINDOWS" /D "_IEEE_LIBM" /YX /c +CPP_PROJ=/nologo /MD /W3 /GX /O2 /D "NDEBUG" /D "WIN32" /D _X86_=1 /D "_WINDOWS" /D\ + "_IEEE_LIBM" /D "XP_WIN" /I .\ /Fp"$(INTDIR)/fdlibm.pch" /YX /Fo"$(INTDIR)/" /c +CPP_OBJS=.\Release/ +CPP_SBRS=.\. + +.c{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.c{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/fdlibm.bsc" +BSC32_SBRS= \ + +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo +LIB32_FLAGS=/nologo /out:"$(OUTDIR)/fdlibm.lib" +LIB32_OBJS= \ + "$(INTDIR)\e_atan2.obj" \ + "$(INTDIR)\e_pow.obj" \ + "$(INTDIR)\e_sqrt.obj" \ + "$(INTDIR)\k_standard.obj" \ + "$(INTDIR)\s_atan.obj" \ + "$(INTDIR)\s_copysign.obj" \ + "$(INTDIR)\s_fabs.obj" \ + "$(INTDIR)\s_finite.obj" \ + "$(INTDIR)\s_isnan.obj" \ + "$(INTDIR)\s_matherr.obj" \ + "$(INTDIR)\s_rint.obj" \ + "$(INTDIR)\s_scalbn.obj" \ + "$(INTDIR)\w_atan2.obj" \ + "$(INTDIR)\w_pow.obj" \ + "$(INTDIR)\w_sqrt.obj" + +"$(OUTDIR)\fdlibm.lib" : "$(OUTDIR)" $(DEF_FILE) $(LIB32_OBJS) + $(LIB32) @<< + $(LIB32_FLAGS) $(DEF_FLAGS) $(LIB32_OBJS) +<< + +!ELSEIF "$(CFG)" == "fdlibm - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "fdlibm\Debug" +# PROP BASE Intermediate_Dir "fdlibm\Debug" +# PROP BASE Target_Dir "fdlibm" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "fdlibm" +OUTDIR=.\Debug +INTDIR=.\Debug + +ALL : "$(OUTDIR)\fdlibm.lib" + +CLEAN : + -@erase "$(INTDIR)\e_atan2.obj" + -@erase "$(INTDIR)\e_pow.obj" + -@erase "$(INTDIR)\e_sqrt.obj" + -@erase "$(INTDIR)\k_standard.obj" + -@erase "$(INTDIR)\s_atan.obj" + -@erase "$(INTDIR)\s_copysign.obj" + -@erase "$(INTDIR)\s_fabs.obj" + -@erase "$(INTDIR)\s_finite.obj" + -@erase "$(INTDIR)\s_isnan.obj" + -@erase "$(INTDIR)\s_matherr.obj" + -@erase "$(INTDIR)\s_rint.obj" + -@erase "$(INTDIR)\s_scalbn.obj" + -@erase "$(INTDIR)\w_atan2.obj" + -@erase "$(INTDIR)\w_pow.obj" + -@erase "$(INTDIR)\w_sqrt.obj" + -@erase "$(OUTDIR)\fdlibm.lib" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +CPP=cl.exe +# ADD BASE CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D _X86_=1 /D "_WINDOWS" /YX /c +# ADD CPP /nologo /MDd /W3 /GX /Z7 /Od /D "_DEBUG" /D "WIN32" /D _X86_=1 /D "_WINDOWS" /D "_IEEE_LIBM" /YX /c +CPP_PROJ=/nologo /MDd /W3 /GX /Z7 /Od /D "_DEBUG" /D "WIN32" /D _X86_=1 /D "_WINDOWS" /D\ + "_IEEE_LIBM" /D "XP_WIN" -I .\ /Fp"$(INTDIR)/fdlibm.pch" /YX /Fo"$(INTDIR)/" /c +CPP_OBJS=.\Debug/ +CPP_SBRS=.\. + +.c{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_OBJS)}.obj: + $(CPP) $(CPP_PROJ) $< + +.c{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +.cpp{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +.cxx{$(CPP_SBRS)}.sbr: + $(CPP) $(CPP_PROJ) $< + +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +BSC32_FLAGS=/nologo /o"$(OUTDIR)/fdlibm.bsc" +BSC32_SBRS= \ + +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo +LIB32_FLAGS=/nologo /out:"$(OUTDIR)/fdlibm.lib" +LIB32_OBJS= \ + "$(INTDIR)\e_atan2.obj" \ + "$(INTDIR)\e_pow.obj" \ + "$(INTDIR)\e_sqrt.obj" \ + "$(INTDIR)\k_standard.obj" \ + "$(INTDIR)\s_atan.obj" \ + "$(INTDIR)\s_copysign.obj" \ + "$(INTDIR)\s_fabs.obj" \ + "$(INTDIR)\s_finite.obj" \ + "$(INTDIR)\s_isnan.obj" \ + "$(INTDIR)\s_matherr.obj" \ + "$(INTDIR)\s_rint.obj" \ + "$(INTDIR)\s_scalbn.obj" \ + "$(INTDIR)\w_atan2.obj" \ + "$(INTDIR)\w_pow.obj" \ + "$(INTDIR)\w_sqrt.obj" + +"$(OUTDIR)\fdlibm.lib" : "$(OUTDIR)" $(DEF_FILE) $(LIB32_OBJS) + $(LIB32) @<< + $(LIB32_FLAGS) $(DEF_FLAGS) $(LIB32_OBJS) +<< + +!ENDIF + +################################################################################ +# Begin Target + +# Name "js - Win32 Release" +# Name "js - Win32 Debug" + +!IF "$(CFG)" == "js - Win32 Release" + +!ELSEIF "$(CFG)" == "js - Win32 Debug" + +!ENDIF + +################################################################################ +# Begin Source File + +SOURCE=.\jsapi.c + +!IF "$(CFG)" == "js - Win32 Release" + +DEP_CPP_JSAPI=\ + ".\js.msg"\ + ".\jsapi.h"\ + ".\jsarena.h"\ + ".\jsarray.h"\ + ".\jsatom.h"\ + ".\jsbool.h"\ + ".\jsclist.h"\ + ".\jscntxt.h"\ + ".\jscompat.h"\ + ".\jsconfig.h"\ + ".\jscpucfg.h"\ + ".\jsdate.h"\ + ".\jsemit.h"\ + ".\jsexn.h"\ + ".\jsfile.h"\ + ".\jsfun.h"\ + ".\jsgc.h"\ + ".\jshash.h"\ + ".\jsinterp.h"\ + ".\jslock.h"\ + ".\jslong.h"\ + ".\jsmath.h"\ + ".\jsnum.h"\ + ".\jsobj.h"\ + ".\jsopcode.h"\ + ".\jsopcode.tbl"\ + ".\jsosdep.h"\ + ".\jsotypes.h"\ + ".\jsparse.h"\ + ".\jsprf.h"\ + ".\jsprvtd.h"\ + ".\jspubtd.h"\ + ".\jsregexp.h"\ + ".\jsscan.h"\ + ".\jsscope.h"\ + ".\jsscript.h"\ + ".\jsstddef.h"\ + ".\jsstr.h"\ + ".\jstypes.h"\ + ".\jsutil.h"\ + {$(INCLUDE)}"\sys\types.h"\ + +NODEP_CPP_JSAPI=\ + ".\jsautocfg.h"\ + ".\prcvar.h"\ + ".\prlock.h"\ + + +"$(INTDIR)\jsapi.obj" : $(SOURCE) $(DEP_CPP_JSAPI) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "js - Win32 Debug" + +DEP_CPP_JSAPI=\ + ".\js.msg"\ + ".\jsapi.h"\ + ".\jsarena.h"\ + ".\jsarray.h"\ + ".\jsatom.h"\ + ".\jsbool.h"\ + ".\jsclist.h"\ + ".\jscntxt.h"\ + ".\jscompat.h"\ + ".\jsconfig.h"\ + ".\jscpucfg.h"\ + ".\jsdate.h"\ + ".\jsemit.h"\ + ".\jsexn.h"\ + ".\jsfile.h"\ + ".\jsfun.h"\ + ".\jsgc.h"\ + ".\jshash.h"\ + ".\jsinterp.h"\ + ".\jslock.h"\ + ".\jslong.h"\ + ".\jsmath.h"\ + ".\jsnum.h"\ + ".\jsobj.h"\ + ".\jsopcode.h"\ + ".\jsopcode.tbl"\ + ".\jsosdep.h"\ + ".\jsotypes.h"\ + ".\jsparse.h"\ + ".\jsprf.h"\ + ".\jsprvtd.h"\ + ".\jspubtd.h"\ + ".\jsregexp.h"\ + ".\jsscan.h"\ + ".\jsscope.h"\ + ".\jsscript.h"\ + ".\jsstddef.h"\ + ".\jsstr.h"\ + ".\jstypes.h"\ + ".\jsutil.h"\ + {$(INCLUDE)}"\sys\types.h"\ + +NODEP_CPP_JSAPI=\ + ".\jsautocfg.h"\ + ".\prcvar.h"\ + ".\prlock.h"\ + + +"$(INTDIR)\jsapi.obj" : $(SOURCE) $(DEP_CPP_JSAPI) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\jsarena.c + +!IF "$(CFG)" == "js - Win32 Release" + +DEP_CPP_JSARE=\ + ".\jsarena.h"\ + ".\jsbit.h"\ + ".\jscompat.h"\ + ".\jscpucfg.h"\ + ".\jslong.h"\ + ".\jsosdep.h"\ + ".\jsotypes.h"\ + ".\jsstddef.h"\ + ".\jstypes.h"\ + ".\jsutil.h"\ + {$(INCLUDE)}"\sys\types.h"\ + +NODEP_CPP_JSARE=\ + ".\jsautocfg.h"\ + + +"$(INTDIR)\jsarena.obj" : $(SOURCE) $(DEP_CPP_JSARE) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "js - Win32 Debug" + +DEP_CPP_JSARE=\ + ".\jsarena.h"\ + ".\jsbit.h"\ + ".\jscompat.h"\ + ".\jscpucfg.h"\ + ".\jslong.h"\ + ".\jsosdep.h"\ + ".\jsotypes.h"\ + ".\jsstddef.h"\ + ".\jstypes.h"\ + ".\jsutil.h"\ + {$(INCLUDE)}"\sys\types.h"\ + +NODEP_CPP_JSARE=\ + ".\jsautocfg.h"\ + + +"$(INTDIR)\jsarena.obj" : $(SOURCE) $(DEP_CPP_JSARE) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\jsarray.c + +!IF "$(CFG)" == "js - Win32 Release" + +DEP_CPP_JSARR=\ + ".\js.msg"\ + ".\jsapi.h"\ + ".\jsarena.h"\ + ".\jsarray.h"\ + ".\jsatom.h"\ + ".\jsclist.h"\ + ".\jscntxt.h"\ + ".\jscompat.h"\ + ".\jsconfig.h"\ + ".\jscpucfg.h"\ + ".\jsfun.h"\ + ".\jsgc.h"\ + ".\jshash.h"\ + ".\jsinterp.h"\ + ".\jslock.h"\ + ".\jslong.h"\ + ".\jsnum.h"\ + ".\jsobj.h"\ + ".\jsosdep.h"\ + ".\jsotypes.h"\ + ".\jsprvtd.h"\ + ".\jspubtd.h"\ + ".\jsregexp.h"\ + ".\jsscope.h"\ + ".\jsstddef.h"\ + ".\jsstr.h"\ + ".\jstypes.h"\ + ".\jsutil.h"\ + {$(INCLUDE)}"\sys\types.h"\ + +NODEP_CPP_JSARR=\ + ".\jsautocfg.h"\ + ".\prcvar.h"\ + ".\prlock.h"\ + + +"$(INTDIR)\jsarray.obj" : $(SOURCE) $(DEP_CPP_JSARR) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "js - Win32 Debug" + +DEP_CPP_JSARR=\ + ".\js.msg"\ + ".\jsapi.h"\ + ".\jsarena.h"\ + ".\jsarray.h"\ + ".\jsatom.h"\ + ".\jsclist.h"\ + ".\jscntxt.h"\ + ".\jscompat.h"\ + ".\jsconfig.h"\ + ".\jscpucfg.h"\ + ".\jsfun.h"\ + ".\jsgc.h"\ + ".\jshash.h"\ + ".\jsinterp.h"\ + ".\jslock.h"\ + ".\jslong.h"\ + ".\jsnum.h"\ + ".\jsobj.h"\ + ".\jsosdep.h"\ + ".\jsotypes.h"\ + ".\jsprvtd.h"\ + ".\jspubtd.h"\ + ".\jsregexp.h"\ + ".\jsscope.h"\ + ".\jsstddef.h"\ + ".\jsstr.h"\ + ".\jstypes.h"\ + ".\jsutil.h"\ + {$(INCLUDE)}"\sys\types.h"\ + +NODEP_CPP_JSARR=\ + ".\jsautocfg.h"\ + ".\prcvar.h"\ + ".\prlock.h"\ + + +"$(INTDIR)\jsarray.obj" : $(SOURCE) $(DEP_CPP_JSARR) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\jsatom.c + +!IF "$(CFG)" == "js - Win32 Release" + +DEP_CPP_JSATO=\ + ".\js.msg"\ + ".\jsapi.h"\ + ".\jsarena.h"\ + ".\jsatom.h"\ + ".\jsclist.h"\ + ".\jscntxt.h"\ + ".\jscompat.h"\ + ".\jsconfig.h"\ + ".\jscpucfg.h"\ + ".\jsgc.h"\ + ".\jshash.h"\ + ".\jsinterp.h"\ + ".\jslock.h"\ + ".\jslong.h"\ + ".\jsnum.h"\ + ".\jsobj.h"\ + ".\jsopcode.h"\ + ".\jsopcode.tbl"\ + ".\jsosdep.h"\ + ".\jsotypes.h"\ + ".\jsprf.h"\ + ".\jsprvtd.h"\ + ".\jspubtd.h"\ + ".\jsregexp.h"\ + ".\jsscope.h"\ + ".\jsstddef.h"\ + ".\jsstr.h"\ + ".\jstypes.h"\ + ".\jsutil.h"\ + {$(INCLUDE)}"\sys\types.h"\ + +NODEP_CPP_JSATO=\ + ".\jsautocfg.h"\ + ".\prcvar.h"\ + ".\prlock.h"\ + + +"$(INTDIR)\jsatom.obj" : $(SOURCE) $(DEP_CPP_JSATO) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "js - Win32 Debug" + +DEP_CPP_JSATO=\ + ".\js.msg"\ + ".\jsapi.h"\ + ".\jsarena.h"\ + ".\jsatom.h"\ + ".\jsclist.h"\ + ".\jscntxt.h"\ + ".\jscompat.h"\ + ".\jsconfig.h"\ + ".\jscpucfg.h"\ + ".\jsgc.h"\ + ".\jshash.h"\ + ".\jsinterp.h"\ + ".\jslock.h"\ + ".\jslong.h"\ + ".\jsnum.h"\ + ".\jsobj.h"\ + ".\jsopcode.h"\ + ".\jsopcode.tbl"\ + ".\jsosdep.h"\ + ".\jsotypes.h"\ + ".\jsprf.h"\ + ".\jsprvtd.h"\ + ".\jspubtd.h"\ + ".\jsregexp.h"\ + ".\jsscope.h"\ + ".\jsstddef.h"\ + ".\jsstr.h"\ + ".\jstypes.h"\ + ".\jsutil.h"\ + {$(INCLUDE)}"\sys\types.h"\ + +NODEP_CPP_JSATO=\ + ".\jsautocfg.h"\ + ".\prcvar.h"\ + ".\prlock.h"\ + + +"$(INTDIR)\jsatom.obj" : $(SOURCE) $(DEP_CPP_JSATO) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\jsbool.c + +!IF "$(CFG)" == "js - Win32 Release" + +DEP_CPP_JSBOO=\ + ".\js.msg"\ + ".\jsapi.h"\ + ".\jsarena.h"\ + ".\jsatom.h"\ + ".\jsbool.h"\ + ".\jsclist.h"\ + ".\jscntxt.h"\ + ".\jscompat.h"\ + ".\jsconfig.h"\ + ".\jscpucfg.h"\ + ".\jsgc.h"\ + ".\jshash.h"\ + ".\jsinterp.h"\ + ".\jslock.h"\ + ".\jslong.h"\ + ".\jsnum.h"\ + ".\jsobj.h"\ + ".\jsosdep.h"\ + ".\jsotypes.h"\ + ".\jsprf.h"\ + ".\jsprvtd.h"\ + ".\jspubtd.h"\ + ".\jsregexp.h"\ + ".\jsscope.h"\ + ".\jsstddef.h"\ + ".\jsstr.h"\ + ".\jstypes.h"\ + ".\jsutil.h"\ + {$(INCLUDE)}"\sys\types.h"\ + +NODEP_CPP_JSBOO=\ + ".\jsautocfg.h"\ + ".\prcvar.h"\ + ".\prlock.h"\ + + +"$(INTDIR)\jsbool.obj" : $(SOURCE) $(DEP_CPP_JSBOO) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "js - Win32 Debug" + +DEP_CPP_JSBOO=\ + ".\js.msg"\ + ".\jsapi.h"\ + ".\jsarena.h"\ + ".\jsatom.h"\ + ".\jsbool.h"\ + ".\jsclist.h"\ + ".\jscntxt.h"\ + ".\jscompat.h"\ + ".\jsconfig.h"\ + ".\jscpucfg.h"\ + ".\jsgc.h"\ + ".\jshash.h"\ + ".\jsinterp.h"\ + ".\jslock.h"\ + ".\jslong.h"\ + ".\jsnum.h"\ + ".\jsobj.h"\ + ".\jsosdep.h"\ + ".\jsotypes.h"\ + ".\jsprf.h"\ + ".\jsprvtd.h"\ + ".\jspubtd.h"\ + ".\jsregexp.h"\ + ".\jsscope.h"\ + ".\jsstddef.h"\ + ".\jsstr.h"\ + ".\jstypes.h"\ + ".\jsutil.h"\ + {$(INCLUDE)}"\sys\types.h"\ + +NODEP_CPP_JSBOO=\ + ".\jsautocfg.h"\ + ".\prcvar.h"\ + ".\prlock.h"\ + + +"$(INTDIR)\jsbool.obj" : $(SOURCE) $(DEP_CPP_JSBOO) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\jscntxt.c + +!IF "$(CFG)" == "js - Win32 Release" + +DEP_CPP_JSCNT=\ + ".\js.msg"\ + ".\jsapi.h"\ + ".\jsarena.h"\ + ".\jsatom.h"\ + ".\jsclist.h"\ + ".\jscntxt.h"\ + ".\jscompat.h"\ + ".\jsconfig.h"\ + ".\jscpucfg.h"\ + ".\jsdbgapi.h"\ + ".\jsexn.h"\ + ".\jsgc.h"\ + ".\jshash.h"\ + ".\jsinterp.h"\ + ".\jslock.h"\ + ".\jslong.h"\ + ".\jsobj.h"\ + ".\jsopcode.h"\ + ".\jsopcode.tbl"\ + ".\jsosdep.h"\ + ".\jsotypes.h"\ + ".\jsprf.h"\ + ".\jsprvtd.h"\ + ".\jspubtd.h"\ + ".\jsregexp.h"\ + ".\jsscan.h"\ + ".\jsscope.h"\ + ".\jsscript.h"\ + ".\jsstddef.h"\ + ".\jsstr.h"\ + ".\jstypes.h"\ + ".\jsutil.h"\ + {$(INCLUDE)}"\sys\types.h"\ + +NODEP_CPP_JSCNT=\ + ".\jsautocfg.h"\ + ".\prcvar.h"\ + ".\prlock.h"\ + + +"$(INTDIR)\jscntxt.obj" : $(SOURCE) $(DEP_CPP_JSCNT) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "js - Win32 Debug" + +DEP_CPP_JSCNT=\ + ".\js.msg"\ + ".\jsapi.h"\ + ".\jsarena.h"\ + ".\jsatom.h"\ + ".\jsclist.h"\ + ".\jscntxt.h"\ + ".\jscompat.h"\ + ".\jsconfig.h"\ + ".\jscpucfg.h"\ + ".\jsdbgapi.h"\ + ".\jsexn.h"\ + ".\jsgc.h"\ + ".\jshash.h"\ + ".\jsinterp.h"\ + ".\jslock.h"\ + ".\jslong.h"\ + ".\jsobj.h"\ + ".\jsopcode.h"\ + ".\jsopcode.tbl"\ + ".\jsosdep.h"\ + ".\jsotypes.h"\ + ".\jsprf.h"\ + ".\jsprvtd.h"\ + ".\jspubtd.h"\ + ".\jsregexp.h"\ + ".\jsscan.h"\ + ".\jsscope.h"\ + ".\jsscript.h"\ + ".\jsstddef.h"\ + ".\jsstr.h"\ + ".\jstypes.h"\ + ".\jsutil.h"\ + {$(INCLUDE)}"\sys\types.h"\ + +NODEP_CPP_JSCNT=\ + ".\jsautocfg.h"\ + ".\prcvar.h"\ + ".\prlock.h"\ + + +"$(INTDIR)\jscntxt.obj" : $(SOURCE) $(DEP_CPP_JSCNT) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\jsdate.c + +!IF "$(CFG)" == "js - Win32 Release" + +DEP_CPP_JSDAT=\ + ".\js.msg"\ + ".\jsapi.h"\ + ".\jsarena.h"\ + ".\jsatom.h"\ + ".\jsclist.h"\ + ".\jscntxt.h"\ + ".\jscompat.h"\ + ".\jsconfig.h"\ + ".\jscpucfg.h"\ + ".\jsdate.h"\ + ".\jsdtoa.h"\ + ".\jsgc.h"\ + ".\jshash.h"\ + ".\jsinterp.h"\ + ".\jslock.h"\ + ".\jslong.h"\ + ".\jsnum.h"\ + ".\jsobj.h"\ + ".\jsosdep.h"\ + ".\jsotypes.h"\ + ".\jsprf.h"\ + ".\jsprvtd.h"\ + ".\jspubtd.h"\ + ".\jsregexp.h"\ + ".\jsscope.h"\ + ".\jsstddef.h"\ + ".\jsstr.h"\ + ".\jstypes.h"\ + ".\jsutil.h"\ + ".\prmjtime.h"\ + {$(INCLUDE)}"\sys\types.h"\ + +NODEP_CPP_JSDAT=\ + ".\jsautocfg.h"\ + ".\prcvar.h"\ + ".\prlock.h"\ + + +"$(INTDIR)\jsdate.obj" : $(SOURCE) $(DEP_CPP_JSDAT) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "js - Win32 Debug" + +DEP_CPP_JSDAT=\ + ".\js.msg"\ + ".\jsapi.h"\ + ".\jsarena.h"\ + ".\jsatom.h"\ + ".\jsclist.h"\ + ".\jscntxt.h"\ + ".\jscompat.h"\ + ".\jsconfig.h"\ + ".\jscpucfg.h"\ + ".\jsdate.h"\ + ".\jsdtoa.h"\ + ".\jsgc.h"\ + ".\jshash.h"\ + ".\jsinterp.h"\ + ".\jslock.h"\ + ".\jslong.h"\ + ".\jsnum.h"\ + ".\jsobj.h"\ + ".\jsosdep.h"\ + ".\jsotypes.h"\ + ".\jsprf.h"\ + ".\jsprvtd.h"\ + ".\jspubtd.h"\ + ".\jsregexp.h"\ + ".\jsscope.h"\ + ".\jsstddef.h"\ + ".\jsstr.h"\ + ".\jstypes.h"\ + ".\jsutil.h"\ + ".\prmjtime.h"\ + {$(INCLUDE)}"\sys\types.h"\ + +NODEP_CPP_JSDAT=\ + ".\jsautocfg.h"\ + ".\prcvar.h"\ + ".\prlock.h"\ + + +"$(INTDIR)\jsdate.obj" : $(SOURCE) $(DEP_CPP_JSDAT) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\jsdbgapi.c + +!IF "$(CFG)" == "js - Win32 Release" + +DEP_CPP_JSDBG=\ + ".\js.msg"\ + ".\jsapi.h"\ + ".\jsarena.h"\ + ".\jsatom.h"\ + ".\jsclist.h"\ + ".\jscntxt.h"\ + ".\jscompat.h"\ + ".\jsconfig.h"\ + ".\jscpucfg.h"\ + ".\jsdbgapi.h"\ + ".\jsfun.h"\ + ".\jsgc.h"\ + ".\jshash.h"\ + ".\jsinterp.h"\ + ".\jslock.h"\ + ".\jslong.h"\ + ".\jsobj.h"\ + ".\jsopcode.h"\ + ".\jsopcode.tbl"\ + ".\jsosdep.h"\ + ".\jsotypes.h"\ + ".\jsprvtd.h"\ + ".\jspubtd.h"\ + ".\jsregexp.h"\ + ".\jsscope.h"\ + ".\jsscript.h"\ + ".\jsstddef.h"\ + ".\jsstr.h"\ + ".\jstypes.h"\ + ".\jsutil.h"\ + {$(INCLUDE)}"\sys\types.h"\ + +NODEP_CPP_JSDBG=\ + ".\jsautocfg.h"\ + ".\prcvar.h"\ + ".\prlock.h"\ + + +"$(INTDIR)\jsdbgapi.obj" : $(SOURCE) $(DEP_CPP_JSDBG) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "js - Win32 Debug" + +DEP_CPP_JSDBG=\ + ".\js.msg"\ + ".\jsapi.h"\ + ".\jsarena.h"\ + ".\jsatom.h"\ + ".\jsclist.h"\ + ".\jscntxt.h"\ + ".\jscompat.h"\ + ".\jsconfig.h"\ + ".\jscpucfg.h"\ + ".\jsdbgapi.h"\ + ".\jsfun.h"\ + ".\jsgc.h"\ + ".\jshash.h"\ + ".\jsinterp.h"\ + ".\jslock.h"\ + ".\jslong.h"\ + ".\jsobj.h"\ + ".\jsopcode.h"\ + ".\jsopcode.tbl"\ + ".\jsosdep.h"\ + ".\jsotypes.h"\ + ".\jsprvtd.h"\ + ".\jspubtd.h"\ + ".\jsregexp.h"\ + ".\jsscope.h"\ + ".\jsscript.h"\ + ".\jsstddef.h"\ + ".\jsstr.h"\ + ".\jstypes.h"\ + ".\jsutil.h"\ + {$(INCLUDE)}"\sys\types.h"\ + +NODEP_CPP_JSDBG=\ + ".\jsautocfg.h"\ + ".\prcvar.h"\ + ".\prlock.h"\ + + +"$(INTDIR)\jsdbgapi.obj" : $(SOURCE) $(DEP_CPP_JSDBG) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\jsdhash.c + +!IF "$(CFG)" == "js - Win32 Release" + +DEP_CPP_JSDHA=\ + ".\jsbit.h"\ + ".\jscompat.h"\ + ".\jscpucfg.h"\ + ".\jsdhash.h"\ + ".\jslong.h"\ + ".\jsosdep.h"\ + ".\jsotypes.h"\ + ".\jstypes.h"\ + ".\jsutil.h"\ + {$(INCLUDE)}"\sys\types.h"\ + +NODEP_CPP_JSDHA=\ + ".\jsautocfg.h"\ + + +"$(INTDIR)\jsdhash.obj" : $(SOURCE) $(DEP_CPP_JSDHA) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "js - Win32 Debug" + +DEP_CPP_JSDHA=\ + ".\jsbit.h"\ + ".\jscompat.h"\ + ".\jscpucfg.h"\ + ".\jsdhash.h"\ + ".\jslong.h"\ + ".\jsosdep.h"\ + ".\jsotypes.h"\ + ".\jstypes.h"\ + ".\jsutil.h"\ + {$(INCLUDE)}"\sys\types.h"\ + +NODEP_CPP_JSDHA=\ + ".\jsautocfg.h"\ + + +"$(INTDIR)\jsdhash.obj" : $(SOURCE) $(DEP_CPP_JSDHA) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\jsdtoa.c + +!IF "$(CFG)" == "js - Win32 Release" + +DEP_CPP_JSDTO=\ + ".\jscompat.h"\ + ".\jscpucfg.h"\ + ".\jsdtoa.h"\ + ".\jslong.h"\ + ".\jsosdep.h"\ + ".\jsotypes.h"\ + ".\jsprf.h"\ + ".\jsstddef.h"\ + ".\jstypes.h"\ + ".\jsutil.h"\ + {$(INCLUDE)}"\sys\types.h"\ + +NODEP_CPP_JSDTO=\ + ".\jsautocfg.h"\ + ".\prlock.h"\ + + +"$(INTDIR)\jsdtoa.obj" : $(SOURCE) $(DEP_CPP_JSDTO) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "js - Win32 Debug" + +DEP_CPP_JSDTO=\ + ".\jscompat.h"\ + ".\jscpucfg.h"\ + ".\jsdtoa.h"\ + ".\jslong.h"\ + ".\jsosdep.h"\ + ".\jsotypes.h"\ + ".\jsprf.h"\ + ".\jsstddef.h"\ + ".\jstypes.h"\ + ".\jsutil.h"\ + {$(INCLUDE)}"\sys\types.h"\ + +NODEP_CPP_JSDTO=\ + ".\jsautocfg.h"\ + ".\prlock.h"\ + + +"$(INTDIR)\jsdtoa.obj" : $(SOURCE) $(DEP_CPP_JSDTO) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\jsemit.c + +!IF "$(CFG)" == "js - Win32 Release" + +DEP_CPP_JSEMI=\ + ".\js.msg"\ + ".\jsapi.h"\ + ".\jsarena.h"\ + ".\jsatom.h"\ + ".\jsclist.h"\ + ".\jscntxt.h"\ + ".\jscompat.h"\ + ".\jsconfig.h"\ + ".\jscpucfg.h"\ + ".\jsemit.h"\ + ".\jsfun.h"\ + ".\jsgc.h"\ + ".\jshash.h"\ + ".\jsinterp.h"\ + ".\jslock.h"\ + ".\jslong.h"\ + ".\jsnum.h"\ + ".\jsobj.h"\ + ".\jsopcode.h"\ + ".\jsopcode.tbl"\ + ".\jsosdep.h"\ + ".\jsotypes.h"\ + ".\jsparse.h"\ + ".\jsprf.h"\ + ".\jsprvtd.h"\ + ".\jspubtd.h"\ + ".\jsregexp.h"\ + ".\jsscan.h"\ + ".\jsscope.h"\ + ".\jsscript.h"\ + ".\jsstddef.h"\ + ".\jsstr.h"\ + ".\jstypes.h"\ + ".\jsutil.h"\ + {$(INCLUDE)}"\sys\types.h"\ + +NODEP_CPP_JSEMI=\ + ".\jsautocfg.h"\ + ".\prcvar.h"\ + ".\prlock.h"\ + + +"$(INTDIR)\jsemit.obj" : $(SOURCE) $(DEP_CPP_JSEMI) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "js - Win32 Debug" + +DEP_CPP_JSEMI=\ + ".\js.msg"\ + ".\jsapi.h"\ + ".\jsarena.h"\ + ".\jsatom.h"\ + ".\jsclist.h"\ + ".\jscntxt.h"\ + ".\jscompat.h"\ + ".\jsconfig.h"\ + ".\jscpucfg.h"\ + ".\jsemit.h"\ + ".\jsfun.h"\ + ".\jsgc.h"\ + ".\jshash.h"\ + ".\jsinterp.h"\ + ".\jslock.h"\ + ".\jslong.h"\ + ".\jsnum.h"\ + ".\jsobj.h"\ + ".\jsopcode.h"\ + ".\jsopcode.tbl"\ + ".\jsosdep.h"\ + ".\jsotypes.h"\ + ".\jsparse.h"\ + ".\jsprf.h"\ + ".\jsprvtd.h"\ + ".\jspubtd.h"\ + ".\jsregexp.h"\ + ".\jsscan.h"\ + ".\jsscope.h"\ + ".\jsscript.h"\ + ".\jsstddef.h"\ + ".\jsstr.h"\ + ".\jstypes.h"\ + ".\jsutil.h"\ + {$(INCLUDE)}"\sys\types.h"\ + +NODEP_CPP_JSEMI=\ + ".\jsautocfg.h"\ + ".\prcvar.h"\ + ".\prlock.h"\ + + +"$(INTDIR)\jsemit.obj" : $(SOURCE) $(DEP_CPP_JSEMI) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\jsexn.c + +!IF "$(CFG)" == "js - Win32 Release" + +DEP_CPP_JSEXN=\ + ".\js.msg"\ + ".\jsapi.h"\ + ".\jsarena.h"\ + ".\jsatom.h"\ + ".\jsclist.h"\ + ".\jscntxt.h"\ + ".\jscompat.h"\ + ".\jsconfig.h"\ + ".\jscpucfg.h"\ + ".\jsexn.h"\ + ".\jsfun.h"\ + ".\jsgc.h"\ + ".\jshash.h"\ + ".\jsinterp.h"\ + ".\jslock.h"\ + ".\jslong.h"\ + ".\jsobj.h"\ + ".\jsosdep.h"\ + ".\jsotypes.h"\ + ".\jsprf.h"\ + ".\jsprvtd.h"\ + ".\jspubtd.h"\ + ".\jsregexp.h"\ + ".\jsscope.h"\ + ".\jsstddef.h"\ + ".\jsstr.h"\ + ".\jstypes.h"\ + ".\jsutil.h"\ + {$(INCLUDE)}"\sys\types.h"\ + +NODEP_CPP_JSEXN=\ + ".\jsautocfg.h"\ + ".\prcvar.h"\ + ".\prlock.h"\ + + +"$(INTDIR)\jsexn.obj" : $(SOURCE) $(DEP_CPP_JSEXN) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "js - Win32 Debug" + +DEP_CPP_JSEXN=\ + ".\js.msg"\ + ".\jsapi.h"\ + ".\jsarena.h"\ + ".\jsatom.h"\ + ".\jsclist.h"\ + ".\jscntxt.h"\ + ".\jscompat.h"\ + ".\jsconfig.h"\ + ".\jscpucfg.h"\ + ".\jsexn.h"\ + ".\jsfun.h"\ + ".\jsgc.h"\ + ".\jshash.h"\ + ".\jsinterp.h"\ + ".\jslock.h"\ + ".\jslong.h"\ + ".\jsobj.h"\ + ".\jsosdep.h"\ + ".\jsotypes.h"\ + ".\jsprf.h"\ + ".\jsprvtd.h"\ + ".\jspubtd.h"\ + ".\jsregexp.h"\ + ".\jsscope.h"\ + ".\jsstddef.h"\ + ".\jsstr.h"\ + ".\jstypes.h"\ + ".\jsutil.h"\ + {$(INCLUDE)}"\sys\types.h"\ + +NODEP_CPP_JSEXN=\ + ".\jsautocfg.h"\ + ".\prcvar.h"\ + ".\prlock.h"\ + + +"$(INTDIR)\jsexn.obj" : $(SOURCE) $(DEP_CPP_JSEXN) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\jsfun.c + +!IF "$(CFG)" == "js - Win32 Release" + +DEP_CPP_JSFUN=\ + ".\js.msg"\ + ".\jsapi.h"\ + ".\jsarena.h"\ + ".\jsarray.h"\ + ".\jsatom.h"\ + ".\jsclist.h"\ + ".\jscntxt.h"\ + ".\jscompat.h"\ + ".\jsconfig.h"\ + ".\jscpucfg.h"\ + ".\jsfun.h"\ + ".\jsgc.h"\ + ".\jshash.h"\ + ".\jsinterp.h"\ + ".\jslock.h"\ + ".\jslong.h"\ + ".\jsnum.h"\ + ".\jsobj.h"\ + ".\jsopcode.h"\ + ".\jsopcode.tbl"\ + ".\jsosdep.h"\ + ".\jsotypes.h"\ + ".\jsparse.h"\ + ".\jsprvtd.h"\ + ".\jspubtd.h"\ + ".\jsregexp.h"\ + ".\jsscan.h"\ + ".\jsscope.h"\ + ".\jsscript.h"\ + ".\jsstddef.h"\ + ".\jsstr.h"\ + ".\jstypes.h"\ + ".\jsutil.h"\ + ".\jsxdrapi.h"\ + {$(INCLUDE)}"\sys\types.h"\ + +NODEP_CPP_JSFUN=\ + ".\jsautocfg.h"\ + ".\prcvar.h"\ + ".\prlock.h"\ + + +"$(INTDIR)\jsfun.obj" : $(SOURCE) $(DEP_CPP_JSFUN) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "js - Win32 Debug" + +DEP_CPP_JSFUN=\ + ".\js.msg"\ + ".\jsapi.h"\ + ".\jsarena.h"\ + ".\jsarray.h"\ + ".\jsatom.h"\ + ".\jsclist.h"\ + ".\jscntxt.h"\ + ".\jscompat.h"\ + ".\jsconfig.h"\ + ".\jscpucfg.h"\ + ".\jsfun.h"\ + ".\jsgc.h"\ + ".\jshash.h"\ + ".\jsinterp.h"\ + ".\jslock.h"\ + ".\jslong.h"\ + ".\jsnum.h"\ + ".\jsobj.h"\ + ".\jsopcode.h"\ + ".\jsopcode.tbl"\ + ".\jsosdep.h"\ + ".\jsotypes.h"\ + ".\jsparse.h"\ + ".\jsprvtd.h"\ + ".\jspubtd.h"\ + ".\jsregexp.h"\ + ".\jsscan.h"\ + ".\jsscope.h"\ + ".\jsscript.h"\ + ".\jsstddef.h"\ + ".\jsstr.h"\ + ".\jstypes.h"\ + ".\jsutil.h"\ + ".\jsxdrapi.h"\ + {$(INCLUDE)}"\sys\types.h"\ + +NODEP_CPP_JSFUN=\ + ".\jsautocfg.h"\ + ".\prcvar.h"\ + ".\prlock.h"\ + + +"$(INTDIR)\jsfun.obj" : $(SOURCE) $(DEP_CPP_JSFUN) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\jsgc.c + +!IF "$(CFG)" == "js - Win32 Release" + +DEP_CPP_JSGC_=\ + ".\js.msg"\ + ".\jsapi.h"\ + ".\jsarena.h"\ + ".\jsatom.h"\ + ".\jsclist.h"\ + ".\jscntxt.h"\ + ".\jscompat.h"\ + ".\jsconfig.h"\ + ".\jscpucfg.h"\ + ".\jsfun.h"\ + ".\jsgc.h"\ + ".\jshash.h"\ + ".\jsinterp.h"\ + ".\jslock.h"\ + ".\jslong.h"\ + ".\jsnum.h"\ + ".\jsobj.h"\ + ".\jsosdep.h"\ + ".\jsotypes.h"\ + ".\jsprf.h"\ + ".\jsprvtd.h"\ + ".\jspubtd.h"\ + ".\jsregexp.h"\ + ".\jsscope.h"\ + ".\jsscript.h"\ + ".\jsstddef.h"\ + ".\jsstr.h"\ + ".\jstypes.h"\ + ".\jsutil.h"\ + {$(INCLUDE)}"\sys\types.h"\ + +NODEP_CPP_JSGC_=\ + ".\jsautocfg.h"\ + ".\prcvar.h"\ + ".\prlock.h"\ + + +"$(INTDIR)\jsgc.obj" : $(SOURCE) $(DEP_CPP_JSGC_) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "js - Win32 Debug" + +DEP_CPP_JSGC_=\ + ".\js.msg"\ + ".\jsapi.h"\ + ".\jsarena.h"\ + ".\jsatom.h"\ + ".\jsclist.h"\ + ".\jscntxt.h"\ + ".\jscompat.h"\ + ".\jsconfig.h"\ + ".\jscpucfg.h"\ + ".\jsfun.h"\ + ".\jsgc.h"\ + ".\jshash.h"\ + ".\jsinterp.h"\ + ".\jslock.h"\ + ".\jslong.h"\ + ".\jsnum.h"\ + ".\jsobj.h"\ + ".\jsosdep.h"\ + ".\jsotypes.h"\ + ".\jsprf.h"\ + ".\jsprvtd.h"\ + ".\jspubtd.h"\ + ".\jsregexp.h"\ + ".\jsscope.h"\ + ".\jsscript.h"\ + ".\jsstddef.h"\ + ".\jsstr.h"\ + ".\jstypes.h"\ + ".\jsutil.h"\ + {$(INCLUDE)}"\sys\types.h"\ + +NODEP_CPP_JSGC_=\ + ".\jsautocfg.h"\ + ".\prcvar.h"\ + ".\prlock.h"\ + + +"$(INTDIR)\jsgc.obj" : $(SOURCE) $(DEP_CPP_JSGC_) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\jshash.c + +!IF "$(CFG)" == "js - Win32 Release" + +DEP_CPP_JSHAS=\ + ".\jsbit.h"\ + ".\jscompat.h"\ + ".\jscpucfg.h"\ + ".\jshash.h"\ + ".\jslong.h"\ + ".\jsosdep.h"\ + ".\jsotypes.h"\ + ".\jstypes.h"\ + ".\jsutil.h"\ + {$(INCLUDE)}"\sys\types.h"\ + +NODEP_CPP_JSHAS=\ + ".\jsautocfg.h"\ + + +"$(INTDIR)\jshash.obj" : $(SOURCE) $(DEP_CPP_JSHAS) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "js - Win32 Debug" + +DEP_CPP_JSHAS=\ + ".\jsbit.h"\ + ".\jscompat.h"\ + ".\jscpucfg.h"\ + ".\jshash.h"\ + ".\jslong.h"\ + ".\jsosdep.h"\ + ".\jsotypes.h"\ + ".\jstypes.h"\ + ".\jsutil.h"\ + {$(INCLUDE)}"\sys\types.h"\ + +NODEP_CPP_JSHAS=\ + ".\jsautocfg.h"\ + + +"$(INTDIR)\jshash.obj" : $(SOURCE) $(DEP_CPP_JSHAS) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\jsinterp.c + +!IF "$(CFG)" == "js - Win32 Release" + +DEP_CPP_JSINT=\ + ".\js.msg"\ + ".\jsapi.h"\ + ".\jsarena.h"\ + ".\jsarray.h"\ + ".\jsatom.h"\ + ".\jsbool.h"\ + ".\jsclist.h"\ + ".\jscntxt.h"\ + ".\jscompat.h"\ + ".\jsconfig.h"\ + ".\jscpucfg.h"\ + ".\jsdbgapi.h"\ + ".\jsfun.h"\ + ".\jsgc.h"\ + ".\jshash.h"\ + ".\jsinterp.h"\ + ".\jslock.h"\ + ".\jslong.h"\ + ".\jsnum.h"\ + ".\jsobj.h"\ + ".\jsopcode.h"\ + ".\jsopcode.tbl"\ + ".\jsosdep.h"\ + ".\jsotypes.h"\ + ".\jsprf.h"\ + ".\jsprvtd.h"\ + ".\jspubtd.h"\ + ".\jsregexp.h"\ + ".\jsscope.h"\ + ".\jsscript.h"\ + ".\jsstddef.h"\ + ".\jsstr.h"\ + ".\jstypes.h"\ + ".\jsutil.h"\ + {$(INCLUDE)}"\sys\types.h"\ + +NODEP_CPP_JSINT=\ + ".\jsautocfg.h"\ + ".\prcvar.h"\ + ".\prlock.h"\ + + +"$(INTDIR)\jsinterp.obj" : $(SOURCE) $(DEP_CPP_JSINT) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "js - Win32 Debug" + +DEP_CPP_JSINT=\ + ".\js.msg"\ + ".\jsapi.h"\ + ".\jsarena.h"\ + ".\jsarray.h"\ + ".\jsatom.h"\ + ".\jsbool.h"\ + ".\jsclist.h"\ + ".\jscntxt.h"\ + ".\jscompat.h"\ + ".\jsconfig.h"\ + ".\jscpucfg.h"\ + ".\jsdbgapi.h"\ + ".\jsfun.h"\ + ".\jsgc.h"\ + ".\jshash.h"\ + ".\jsinterp.h"\ + ".\jslock.h"\ + ".\jslong.h"\ + ".\jsnum.h"\ + ".\jsobj.h"\ + ".\jsopcode.h"\ + ".\jsopcode.tbl"\ + ".\jsosdep.h"\ + ".\jsotypes.h"\ + ".\jsprf.h"\ + ".\jsprvtd.h"\ + ".\jspubtd.h"\ + ".\jsregexp.h"\ + ".\jsscope.h"\ + ".\jsscript.h"\ + ".\jsstddef.h"\ + ".\jsstr.h"\ + ".\jstypes.h"\ + ".\jsutil.h"\ + {$(INCLUDE)}"\sys\types.h"\ + +NODEP_CPP_JSINT=\ + ".\jsautocfg.h"\ + ".\prcvar.h"\ + ".\prlock.h"\ + + +"$(INTDIR)\jsinterp.obj" : $(SOURCE) $(DEP_CPP_JSINT) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\jslock.c + +!IF "$(CFG)" == "js - Win32 Release" + +DEP_CPP_JSLOC=\ + ".\js.msg"\ + ".\jsapi.h"\ + ".\jsarena.h"\ + ".\jsatom.h"\ + ".\jsclist.h"\ + ".\jscntxt.h"\ + ".\jscompat.h"\ + ".\jsconfig.h"\ + ".\jscpucfg.h"\ + ".\jsgc.h"\ + ".\jshash.h"\ + ".\jsinterp.h"\ + ".\jslock.h"\ + ".\jslong.h"\ + ".\jsobj.h"\ + ".\jsosdep.h"\ + ".\jsotypes.h"\ + ".\jsprvtd.h"\ + ".\jspubtd.h"\ + ".\jsregexp.h"\ + ".\jsscope.h"\ + ".\jsstddef.h"\ + ".\jsstr.h"\ + ".\jstypes.h"\ + ".\jsutil.h"\ + {$(INCLUDE)}"\sys\types.h"\ + +NODEP_CPP_JSLOC=\ + ".\jsautocfg.h"\ + ".\pratom.h"\ + ".\prcvar.h"\ + ".\prlock.h"\ + ".\prthread.h"\ + + +"$(INTDIR)\jslock.obj" : $(SOURCE) $(DEP_CPP_JSLOC) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "js - Win32 Debug" + +DEP_CPP_JSLOC=\ + ".\js.msg"\ + ".\jsapi.h"\ + ".\jsarena.h"\ + ".\jsatom.h"\ + ".\jsclist.h"\ + ".\jscntxt.h"\ + ".\jscompat.h"\ + ".\jsconfig.h"\ + ".\jscpucfg.h"\ + ".\jsgc.h"\ + ".\jshash.h"\ + ".\jsinterp.h"\ + ".\jslock.h"\ + ".\jslong.h"\ + ".\jsobj.h"\ + ".\jsosdep.h"\ + ".\jsotypes.h"\ + ".\jsprvtd.h"\ + ".\jspubtd.h"\ + ".\jsregexp.h"\ + ".\jsscope.h"\ + ".\jsstddef.h"\ + ".\jsstr.h"\ + ".\jstypes.h"\ + ".\jsutil.h"\ + {$(INCLUDE)}"\sys\types.h"\ + +NODEP_CPP_JSLOC=\ + ".\jsautocfg.h"\ + ".\pratom.h"\ + ".\prcvar.h"\ + ".\prlock.h"\ + ".\prthread.h"\ + + +"$(INTDIR)\jslock.obj" : $(SOURCE) $(DEP_CPP_JSLOC) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\jslog2.c + +!IF "$(CFG)" == "js - Win32 Release" + +DEP_CPP_JSLOG=\ + ".\jsbit.h"\ + ".\jscpucfg.h"\ + ".\jsosdep.h"\ + ".\jsotypes.h"\ + ".\jstypes.h"\ + {$(INCLUDE)}"\sys\types.h"\ + +NODEP_CPP_JSLOG=\ + ".\jsautocfg.h"\ + + +"$(INTDIR)\jslog2.obj" : $(SOURCE) $(DEP_CPP_JSLOG) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "js - Win32 Debug" + +DEP_CPP_JSLOG=\ + ".\jsbit.h"\ + ".\jscpucfg.h"\ + ".\jsosdep.h"\ + ".\jsotypes.h"\ + ".\jstypes.h"\ + {$(INCLUDE)}"\sys\types.h"\ + +NODEP_CPP_JSLOG=\ + ".\jsautocfg.h"\ + + +"$(INTDIR)\jslog2.obj" : $(SOURCE) $(DEP_CPP_JSLOG) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\jslong.c + +!IF "$(CFG)" == "js - Win32 Release" + +DEP_CPP_JSLON=\ + ".\jscpucfg.h"\ + ".\jslong.h"\ + ".\jsosdep.h"\ + ".\jsotypes.h"\ + ".\jstypes.h"\ + {$(INCLUDE)}"\sys\types.h"\ + +NODEP_CPP_JSLON=\ + ".\jsautocfg.h"\ + + +"$(INTDIR)\jslong.obj" : $(SOURCE) $(DEP_CPP_JSLON) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "js - Win32 Debug" + +DEP_CPP_JSLON=\ + ".\jscpucfg.h"\ + ".\jslong.h"\ + ".\jsosdep.h"\ + ".\jsotypes.h"\ + ".\jstypes.h"\ + {$(INCLUDE)}"\sys\types.h"\ + +NODEP_CPP_JSLON=\ + ".\jsautocfg.h"\ + + +"$(INTDIR)\jslong.obj" : $(SOURCE) $(DEP_CPP_JSLON) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\jsmath.c + +!IF "$(CFG)" == "js - Win32 Release" + +DEP_CPP_JSMAT=\ + ".\js.msg"\ + ".\jsapi.h"\ + ".\jsarena.h"\ + ".\jsatom.h"\ + ".\jsclist.h"\ + ".\jscntxt.h"\ + ".\jscompat.h"\ + ".\jsconfig.h"\ + ".\jscpucfg.h"\ + ".\jsgc.h"\ + ".\jshash.h"\ + ".\jsinterp.h"\ + ".\jslibmath.h"\ + ".\jslock.h"\ + ".\jslong.h"\ + ".\jsmath.h"\ + ".\jsnum.h"\ + ".\jsobj.h"\ + ".\jsosdep.h"\ + ".\jsotypes.h"\ + ".\jsprvtd.h"\ + ".\jspubtd.h"\ + ".\jsregexp.h"\ + ".\jsscope.h"\ + ".\jsstddef.h"\ + ".\jsstr.h"\ + ".\jstypes.h"\ + ".\prmjtime.h"\ + {$(INCLUDE)}"\sys\types.h"\ + +NODEP_CPP_JSMAT=\ + ".\jsautocfg.h"\ + ".\prcvar.h"\ + ".\prlock.h"\ + + +"$(INTDIR)\jsmath.obj" : $(SOURCE) $(DEP_CPP_JSMAT) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "js - Win32 Debug" + +DEP_CPP_JSMAT=\ + ".\js.msg"\ + ".\jsapi.h"\ + ".\jsarena.h"\ + ".\jsatom.h"\ + ".\jsclist.h"\ + ".\jscntxt.h"\ + ".\jscompat.h"\ + ".\jsconfig.h"\ + ".\jscpucfg.h"\ + ".\jsgc.h"\ + ".\jshash.h"\ + ".\jsinterp.h"\ + ".\jslibmath.h"\ + ".\jslock.h"\ + ".\jslong.h"\ + ".\jsmath.h"\ + ".\jsnum.h"\ + ".\jsobj.h"\ + ".\jsosdep.h"\ + ".\jsotypes.h"\ + ".\jsprvtd.h"\ + ".\jspubtd.h"\ + ".\jsregexp.h"\ + ".\jsscope.h"\ + ".\jsstddef.h"\ + ".\jsstr.h"\ + ".\jstypes.h"\ + ".\prmjtime.h"\ + {$(INCLUDE)}"\sys\types.h"\ + +NODEP_CPP_JSMAT=\ + ".\jsautocfg.h"\ + ".\prcvar.h"\ + ".\prlock.h"\ + + +"$(INTDIR)\jsmath.obj" : $(SOURCE) $(DEP_CPP_JSMAT) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\jsnum.c + +!IF "$(CFG)" == "js - Win32 Release" + +DEP_CPP_JSNUM=\ + ".\js.msg"\ + ".\jsapi.h"\ + ".\jsarena.h"\ + ".\jsatom.h"\ + ".\jsclist.h"\ + ".\jscntxt.h"\ + ".\jscompat.h"\ + ".\jsconfig.h"\ + ".\jscpucfg.h"\ + ".\jsdtoa.h"\ + ".\jsgc.h"\ + ".\jshash.h"\ + ".\jsinterp.h"\ + ".\jslock.h"\ + ".\jslong.h"\ + ".\jsnum.h"\ + ".\jsobj.h"\ + ".\jsopcode.h"\ + ".\jsopcode.tbl"\ + ".\jsosdep.h"\ + ".\jsotypes.h"\ + ".\jsprf.h"\ + ".\jsprvtd.h"\ + ".\jspubtd.h"\ + ".\jsregexp.h"\ + ".\jsscope.h"\ + ".\jsstddef.h"\ + ".\jsstr.h"\ + ".\jstypes.h"\ + ".\jsutil.h"\ + {$(INCLUDE)}"\sys\types.h"\ + +NODEP_CPP_JSNUM=\ + ".\jsautocfg.h"\ + ".\prcvar.h"\ + ".\prlock.h"\ + + +"$(INTDIR)\jsnum.obj" : $(SOURCE) $(DEP_CPP_JSNUM) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "js - Win32 Debug" + +DEP_CPP_JSNUM=\ + ".\js.msg"\ + ".\jsapi.h"\ + ".\jsarena.h"\ + ".\jsatom.h"\ + ".\jsclist.h"\ + ".\jscntxt.h"\ + ".\jscompat.h"\ + ".\jsconfig.h"\ + ".\jscpucfg.h"\ + ".\jsdtoa.h"\ + ".\jsgc.h"\ + ".\jshash.h"\ + ".\jsinterp.h"\ + ".\jslock.h"\ + ".\jslong.h"\ + ".\jsnum.h"\ + ".\jsobj.h"\ + ".\jsopcode.h"\ + ".\jsopcode.tbl"\ + ".\jsosdep.h"\ + ".\jsotypes.h"\ + ".\jsprf.h"\ + ".\jsprvtd.h"\ + ".\jspubtd.h"\ + ".\jsregexp.h"\ + ".\jsscope.h"\ + ".\jsstddef.h"\ + ".\jsstr.h"\ + ".\jstypes.h"\ + ".\jsutil.h"\ + {$(INCLUDE)}"\sys\types.h"\ + +NODEP_CPP_JSNUM=\ + ".\jsautocfg.h"\ + ".\prcvar.h"\ + ".\prlock.h"\ + + +"$(INTDIR)\jsnum.obj" : $(SOURCE) $(DEP_CPP_JSNUM) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\jsobj.c + +!IF "$(CFG)" == "js - Win32 Release" + +DEP_CPP_JSOBJ=\ + ".\js.msg"\ + ".\jsapi.h"\ + ".\jsarena.h"\ + ".\jsatom.h"\ + ".\jsbool.h"\ + ".\jsclist.h"\ + ".\jscntxt.h"\ + ".\jscompat.h"\ + ".\jsconfig.h"\ + ".\jscpucfg.h"\ + ".\jsdbgapi.h"\ + ".\jsfun.h"\ + ".\jsgc.h"\ + ".\jshash.h"\ + ".\jsinterp.h"\ + ".\jslock.h"\ + ".\jslong.h"\ + ".\jsnum.h"\ + ".\jsobj.h"\ + ".\jsopcode.h"\ + ".\jsopcode.tbl"\ + ".\jsosdep.h"\ + ".\jsotypes.h"\ + ".\jsprf.h"\ + ".\jsprvtd.h"\ + ".\jspubtd.h"\ + ".\jsregexp.h"\ + ".\jsscope.h"\ + ".\jsscript.h"\ + ".\jsstddef.h"\ + ".\jsstr.h"\ + ".\jstypes.h"\ + ".\jsutil.h"\ + ".\jsxdrapi.h"\ + {$(INCLUDE)}"\sys\types.h"\ + +NODEP_CPP_JSOBJ=\ + ".\jsautocfg.h"\ + ".\prcvar.h"\ + ".\prlock.h"\ + + +"$(INTDIR)\jsobj.obj" : $(SOURCE) $(DEP_CPP_JSOBJ) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "js - Win32 Debug" + +DEP_CPP_JSOBJ=\ + ".\js.msg"\ + ".\jsapi.h"\ + ".\jsarena.h"\ + ".\jsatom.h"\ + ".\jsbool.h"\ + ".\jsclist.h"\ + ".\jscntxt.h"\ + ".\jscompat.h"\ + ".\jsconfig.h"\ + ".\jscpucfg.h"\ + ".\jsdbgapi.h"\ + ".\jsfun.h"\ + ".\jsgc.h"\ + ".\jshash.h"\ + ".\jsinterp.h"\ + ".\jslock.h"\ + ".\jslong.h"\ + ".\jsnum.h"\ + ".\jsobj.h"\ + ".\jsopcode.h"\ + ".\jsopcode.tbl"\ + ".\jsosdep.h"\ + ".\jsotypes.h"\ + ".\jsprf.h"\ + ".\jsprvtd.h"\ + ".\jspubtd.h"\ + ".\jsregexp.h"\ + ".\jsscope.h"\ + ".\jsscript.h"\ + ".\jsstddef.h"\ + ".\jsstr.h"\ + ".\jstypes.h"\ + ".\jsutil.h"\ + ".\jsxdrapi.h"\ + {$(INCLUDE)}"\sys\types.h"\ + +NODEP_CPP_JSOBJ=\ + ".\jsautocfg.h"\ + ".\prcvar.h"\ + ".\prlock.h"\ + + +"$(INTDIR)\jsobj.obj" : $(SOURCE) $(DEP_CPP_JSOBJ) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\jsopcode.c + +!IF "$(CFG)" == "js - Win32 Release" + +DEP_CPP_JSOPC=\ + ".\js.msg"\ + ".\jsapi.h"\ + ".\jsarena.h"\ + ".\jsarray.h"\ + ".\jsatom.h"\ + ".\jsclist.h"\ + ".\jscntxt.h"\ + ".\jscompat.h"\ + ".\jsconfig.h"\ + ".\jscpucfg.h"\ + ".\jsdbgapi.h"\ + ".\jsdtoa.h"\ + ".\jsemit.h"\ + ".\jsfun.h"\ + ".\jsgc.h"\ + ".\jshash.h"\ + ".\jsinterp.h"\ + ".\jslock.h"\ + ".\jslong.h"\ + ".\jsobj.h"\ + ".\jsopcode.h"\ + ".\jsopcode.tbl"\ + ".\jsosdep.h"\ + ".\jsotypes.h"\ + ".\jsprf.h"\ + ".\jsprvtd.h"\ + ".\jspubtd.h"\ + ".\jsregexp.h"\ + ".\jsscope.h"\ + ".\jsscript.h"\ + ".\jsstddef.h"\ + ".\jsstr.h"\ + ".\jstypes.h"\ + ".\jsutil.h"\ + {$(INCLUDE)}"\sys\types.h"\ + +NODEP_CPP_JSOPC=\ + ".\jsautocfg.h"\ + ".\prcvar.h"\ + ".\prlock.h"\ + + +"$(INTDIR)\jsopcode.obj" : $(SOURCE) $(DEP_CPP_JSOPC) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "js - Win32 Debug" + +DEP_CPP_JSOPC=\ + ".\js.msg"\ + ".\jsapi.h"\ + ".\jsarena.h"\ + ".\jsarray.h"\ + ".\jsatom.h"\ + ".\jsclist.h"\ + ".\jscntxt.h"\ + ".\jscompat.h"\ + ".\jsconfig.h"\ + ".\jscpucfg.h"\ + ".\jsdbgapi.h"\ + ".\jsdtoa.h"\ + ".\jsemit.h"\ + ".\jsfun.h"\ + ".\jsgc.h"\ + ".\jshash.h"\ + ".\jsinterp.h"\ + ".\jslock.h"\ + ".\jslong.h"\ + ".\jsobj.h"\ + ".\jsopcode.h"\ + ".\jsopcode.tbl"\ + ".\jsosdep.h"\ + ".\jsotypes.h"\ + ".\jsprf.h"\ + ".\jsprvtd.h"\ + ".\jspubtd.h"\ + ".\jsregexp.h"\ + ".\jsscope.h"\ + ".\jsscript.h"\ + ".\jsstddef.h"\ + ".\jsstr.h"\ + ".\jstypes.h"\ + ".\jsutil.h"\ + {$(INCLUDE)}"\sys\types.h"\ + +NODEP_CPP_JSOPC=\ + ".\jsautocfg.h"\ + ".\prcvar.h"\ + ".\prlock.h"\ + + +"$(INTDIR)\jsopcode.obj" : $(SOURCE) $(DEP_CPP_JSOPC) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\jsparse.c + +!IF "$(CFG)" == "js - Win32 Release" + +DEP_CPP_JSPAR=\ + ".\js.msg"\ + ".\jsapi.h"\ + ".\jsarena.h"\ + ".\jsatom.h"\ + ".\jsclist.h"\ + ".\jscntxt.h"\ + ".\jscompat.h"\ + ".\jsconfig.h"\ + ".\jscpucfg.h"\ + ".\jsemit.h"\ + ".\jsfun.h"\ + ".\jsgc.h"\ + ".\jshash.h"\ + ".\jsinterp.h"\ + ".\jslock.h"\ + ".\jslong.h"\ + ".\jsnum.h"\ + ".\jsobj.h"\ + ".\jsopcode.h"\ + ".\jsopcode.tbl"\ + ".\jsosdep.h"\ + ".\jsotypes.h"\ + ".\jsparse.h"\ + ".\jsprvtd.h"\ + ".\jspubtd.h"\ + ".\jsregexp.h"\ + ".\jsscan.h"\ + ".\jsscope.h"\ + ".\jsscript.h"\ + ".\jsstddef.h"\ + ".\jsstr.h"\ + ".\jstypes.h"\ + ".\jsutil.h"\ + {$(INCLUDE)}"\sys\types.h"\ + +NODEP_CPP_JSPAR=\ + ".\jsautocfg.h"\ + ".\prcvar.h"\ + ".\prlock.h"\ + + +"$(INTDIR)\jsparse.obj" : $(SOURCE) $(DEP_CPP_JSPAR) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "js - Win32 Debug" + +DEP_CPP_JSPAR=\ + ".\js.msg"\ + ".\jsapi.h"\ + ".\jsarena.h"\ + ".\jsatom.h"\ + ".\jsclist.h"\ + ".\jscntxt.h"\ + ".\jscompat.h"\ + ".\jsconfig.h"\ + ".\jscpucfg.h"\ + ".\jsemit.h"\ + ".\jsfun.h"\ + ".\jsgc.h"\ + ".\jshash.h"\ + ".\jsinterp.h"\ + ".\jslock.h"\ + ".\jslong.h"\ + ".\jsnum.h"\ + ".\jsobj.h"\ + ".\jsopcode.h"\ + ".\jsopcode.tbl"\ + ".\jsosdep.h"\ + ".\jsotypes.h"\ + ".\jsparse.h"\ + ".\jsprvtd.h"\ + ".\jspubtd.h"\ + ".\jsregexp.h"\ + ".\jsscan.h"\ + ".\jsscope.h"\ + ".\jsscript.h"\ + ".\jsstddef.h"\ + ".\jsstr.h"\ + ".\jstypes.h"\ + ".\jsutil.h"\ + {$(INCLUDE)}"\sys\types.h"\ + +NODEP_CPP_JSPAR=\ + ".\jsautocfg.h"\ + ".\prcvar.h"\ + ".\prlock.h"\ + + +"$(INTDIR)\jsparse.obj" : $(SOURCE) $(DEP_CPP_JSPAR) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\jsprf.c + +!IF "$(CFG)" == "js - Win32 Release" + +DEP_CPP_JSPRF=\ + ".\jscpucfg.h"\ + ".\jslong.h"\ + ".\jsosdep.h"\ + ".\jsotypes.h"\ + ".\jsprf.h"\ + ".\jstypes.h"\ + ".\jsutil.h"\ + {$(INCLUDE)}"\sys\types.h"\ + +NODEP_CPP_JSPRF=\ + ".\jsautocfg.h"\ + + +"$(INTDIR)\jsprf.obj" : $(SOURCE) $(DEP_CPP_JSPRF) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "js - Win32 Debug" + +DEP_CPP_JSPRF=\ + ".\jscpucfg.h"\ + ".\jslong.h"\ + ".\jsosdep.h"\ + ".\jsotypes.h"\ + ".\jsprf.h"\ + ".\jstypes.h"\ + ".\jsutil.h"\ + {$(INCLUDE)}"\sys\types.h"\ + +NODEP_CPP_JSPRF=\ + ".\jsautocfg.h"\ + + +"$(INTDIR)\jsprf.obj" : $(SOURCE) $(DEP_CPP_JSPRF) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\jsregexp.c + +!IF "$(CFG)" == "js - Win32 Release" + +DEP_CPP_JSREG=\ + ".\js.msg"\ + ".\jsapi.h"\ + ".\jsarena.h"\ + ".\jsarray.h"\ + ".\jsatom.h"\ + ".\jsclist.h"\ + ".\jscntxt.h"\ + ".\jscompat.h"\ + ".\jsconfig.h"\ + ".\jscpucfg.h"\ + ".\jsfun.h"\ + ".\jsgc.h"\ + ".\jshash.h"\ + ".\jsinterp.h"\ + ".\jslock.h"\ + ".\jslong.h"\ + ".\jsnum.h"\ + ".\jsobj.h"\ + ".\jsopcode.h"\ + ".\jsopcode.tbl"\ + ".\jsosdep.h"\ + ".\jsotypes.h"\ + ".\jsprvtd.h"\ + ".\jspubtd.h"\ + ".\jsregexp.h"\ + ".\jsscope.h"\ + ".\jsstddef.h"\ + ".\jsstr.h"\ + ".\jstypes.h"\ + ".\jsutil.h"\ + ".\jsxdrapi.h"\ + {$(INCLUDE)}"\sys\types.h"\ + +NODEP_CPP_JSREG=\ + ".\jsautocfg.h"\ + ".\prcvar.h"\ + ".\prlock.h"\ + + +"$(INTDIR)\jsregexp.obj" : $(SOURCE) $(DEP_CPP_JSREG) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "js - Win32 Debug" + +DEP_CPP_JSREG=\ + ".\js.msg"\ + ".\jsapi.h"\ + ".\jsarena.h"\ + ".\jsarray.h"\ + ".\jsatom.h"\ + ".\jsclist.h"\ + ".\jscntxt.h"\ + ".\jscompat.h"\ + ".\jsconfig.h"\ + ".\jscpucfg.h"\ + ".\jsfun.h"\ + ".\jsgc.h"\ + ".\jshash.h"\ + ".\jsinterp.h"\ + ".\jslock.h"\ + ".\jslong.h"\ + ".\jsnum.h"\ + ".\jsobj.h"\ + ".\jsopcode.h"\ + ".\jsopcode.tbl"\ + ".\jsosdep.h"\ + ".\jsotypes.h"\ + ".\jsprvtd.h"\ + ".\jspubtd.h"\ + ".\jsregexp.h"\ + ".\jsscope.h"\ + ".\jsstddef.h"\ + ".\jsstr.h"\ + ".\jstypes.h"\ + ".\jsutil.h"\ + ".\jsxdrapi.h"\ + {$(INCLUDE)}"\sys\types.h"\ + +NODEP_CPP_JSREG=\ + ".\jsautocfg.h"\ + ".\prcvar.h"\ + ".\prlock.h"\ + + +"$(INTDIR)\jsregexp.obj" : $(SOURCE) $(DEP_CPP_JSREG) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\jsscan.c + +!IF "$(CFG)" == "js - Win32 Release" + +DEP_CPP_JSSCA=\ + ".\js.msg"\ + ".\jsapi.h"\ + ".\jsarena.h"\ + ".\jsatom.h"\ + ".\jsclist.h"\ + ".\jscntxt.h"\ + ".\jscompat.h"\ + ".\jsconfig.h"\ + ".\jscpucfg.h"\ + ".\jsdtoa.h"\ + ".\jsexn.h"\ + ".\jsgc.h"\ + ".\jshash.h"\ + ".\jsinterp.h"\ + ".\jslock.h"\ + ".\jslong.h"\ + ".\jsnum.h"\ + ".\jsobj.h"\ + ".\jsopcode.h"\ + ".\jsopcode.tbl"\ + ".\jsosdep.h"\ + ".\jsotypes.h"\ + ".\jsprf.h"\ + ".\jsprvtd.h"\ + ".\jspubtd.h"\ + ".\jsregexp.h"\ + ".\jsscan.h"\ + ".\jsscope.h"\ + ".\jsstddef.h"\ + ".\jsstr.h"\ + ".\jstypes.h"\ + ".\jsutil.h"\ + {$(INCLUDE)}"\sys\types.h"\ + +NODEP_CPP_JSSCA=\ + ".\jsautocfg.h"\ + ".\prcvar.h"\ + ".\prlock.h"\ + + +"$(INTDIR)\jsscan.obj" : $(SOURCE) $(DEP_CPP_JSSCA) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "js - Win32 Debug" + +DEP_CPP_JSSCA=\ + ".\js.msg"\ + ".\jsapi.h"\ + ".\jsarena.h"\ + ".\jsatom.h"\ + ".\jsclist.h"\ + ".\jscntxt.h"\ + ".\jscompat.h"\ + ".\jsconfig.h"\ + ".\jscpucfg.h"\ + ".\jsdtoa.h"\ + ".\jsexn.h"\ + ".\jsgc.h"\ + ".\jshash.h"\ + ".\jsinterp.h"\ + ".\jslock.h"\ + ".\jslong.h"\ + ".\jsnum.h"\ + ".\jsobj.h"\ + ".\jsopcode.h"\ + ".\jsopcode.tbl"\ + ".\jsosdep.h"\ + ".\jsotypes.h"\ + ".\jsprf.h"\ + ".\jsprvtd.h"\ + ".\jspubtd.h"\ + ".\jsregexp.h"\ + ".\jsscan.h"\ + ".\jsscope.h"\ + ".\jsstddef.h"\ + ".\jsstr.h"\ + ".\jstypes.h"\ + ".\jsutil.h"\ + {$(INCLUDE)}"\sys\types.h"\ + +NODEP_CPP_JSSCA=\ + ".\jsautocfg.h"\ + ".\prcvar.h"\ + ".\prlock.h"\ + + +"$(INTDIR)\jsscan.obj" : $(SOURCE) $(DEP_CPP_JSSCA) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\jsscope.c + +!IF "$(CFG)" == "js - Win32 Release" + +DEP_CPP_JSSCO=\ + ".\js.msg"\ + ".\jsapi.h"\ + ".\jsarena.h"\ + ".\jsatom.h"\ + ".\jsclist.h"\ + ".\jscntxt.h"\ + ".\jscompat.h"\ + ".\jsconfig.h"\ + ".\jscpucfg.h"\ + ".\jsgc.h"\ + ".\jshash.h"\ + ".\jsinterp.h"\ + ".\jslock.h"\ + ".\jslong.h"\ + ".\jsnum.h"\ + ".\jsobj.h"\ + ".\jsosdep.h"\ + ".\jsotypes.h"\ + ".\jsprvtd.h"\ + ".\jspubtd.h"\ + ".\jsregexp.h"\ + ".\jsscope.h"\ + ".\jsstddef.h"\ + ".\jsstr.h"\ + ".\jstypes.h"\ + ".\jsutil.h"\ + {$(INCLUDE)}"\sys\types.h"\ + +NODEP_CPP_JSSCO=\ + ".\jsautocfg.h"\ + ".\prcvar.h"\ + ".\prlock.h"\ + + +"$(INTDIR)\jsscope.obj" : $(SOURCE) $(DEP_CPP_JSSCO) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "js - Win32 Debug" + +DEP_CPP_JSSCO=\ + ".\js.msg"\ + ".\jsapi.h"\ + ".\jsarena.h"\ + ".\jsatom.h"\ + ".\jsclist.h"\ + ".\jscntxt.h"\ + ".\jscompat.h"\ + ".\jsconfig.h"\ + ".\jscpucfg.h"\ + ".\jsgc.h"\ + ".\jshash.h"\ + ".\jsinterp.h"\ + ".\jslock.h"\ + ".\jslong.h"\ + ".\jsnum.h"\ + ".\jsobj.h"\ + ".\jsosdep.h"\ + ".\jsotypes.h"\ + ".\jsprvtd.h"\ + ".\jspubtd.h"\ + ".\jsregexp.h"\ + ".\jsscope.h"\ + ".\jsstddef.h"\ + ".\jsstr.h"\ + ".\jstypes.h"\ + ".\jsutil.h"\ + {$(INCLUDE)}"\sys\types.h"\ + +NODEP_CPP_JSSCO=\ + ".\jsautocfg.h"\ + ".\prcvar.h"\ + ".\prlock.h"\ + + +"$(INTDIR)\jsscope.obj" : $(SOURCE) $(DEP_CPP_JSSCO) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\jsscript.c + +!IF "$(CFG)" == "js - Win32 Release" + +DEP_CPP_JSSCR=\ + ".\js.msg"\ + ".\jsapi.h"\ + ".\jsarena.h"\ + ".\jsatom.h"\ + ".\jsclist.h"\ + ".\jscntxt.h"\ + ".\jscompat.h"\ + ".\jsconfig.h"\ + ".\jscpucfg.h"\ + ".\jsdbgapi.h"\ + ".\jsemit.h"\ + ".\jsfun.h"\ + ".\jsgc.h"\ + ".\jshash.h"\ + ".\jsinterp.h"\ + ".\jslock.h"\ + ".\jslong.h"\ + ".\jsnum.h"\ + ".\jsobj.h"\ + ".\jsopcode.h"\ + ".\jsopcode.tbl"\ + ".\jsosdep.h"\ + ".\jsotypes.h"\ + ".\jsprf.h"\ + ".\jsprvtd.h"\ + ".\jspubtd.h"\ + ".\jsregexp.h"\ + ".\jsscope.h"\ + ".\jsscript.h"\ + ".\jsstddef.h"\ + ".\jsstr.h"\ + ".\jstypes.h"\ + ".\jsutil.h"\ + ".\jsxdrapi.h"\ + {$(INCLUDE)}"\sys\types.h"\ + +NODEP_CPP_JSSCR=\ + ".\jsautocfg.h"\ + ".\prcvar.h"\ + ".\prlock.h"\ + + +"$(INTDIR)\jsscript.obj" : $(SOURCE) $(DEP_CPP_JSSCR) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "js - Win32 Debug" + +DEP_CPP_JSSCR=\ + ".\js.msg"\ + ".\jsapi.h"\ + ".\jsarena.h"\ + ".\jsatom.h"\ + ".\jsclist.h"\ + ".\jscntxt.h"\ + ".\jscompat.h"\ + ".\jsconfig.h"\ + ".\jscpucfg.h"\ + ".\jsdbgapi.h"\ + ".\jsemit.h"\ + ".\jsfun.h"\ + ".\jsgc.h"\ + ".\jshash.h"\ + ".\jsinterp.h"\ + ".\jslock.h"\ + ".\jslong.h"\ + ".\jsnum.h"\ + ".\jsobj.h"\ + ".\jsopcode.h"\ + ".\jsopcode.tbl"\ + ".\jsosdep.h"\ + ".\jsotypes.h"\ + ".\jsprf.h"\ + ".\jsprvtd.h"\ + ".\jspubtd.h"\ + ".\jsregexp.h"\ + ".\jsscope.h"\ + ".\jsscript.h"\ + ".\jsstddef.h"\ + ".\jsstr.h"\ + ".\jstypes.h"\ + ".\jsutil.h"\ + ".\jsxdrapi.h"\ + {$(INCLUDE)}"\sys\types.h"\ + +NODEP_CPP_JSSCR=\ + ".\jsautocfg.h"\ + ".\prcvar.h"\ + ".\prlock.h"\ + + +"$(INTDIR)\jsscript.obj" : $(SOURCE) $(DEP_CPP_JSSCR) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\jsstr.c + +!IF "$(CFG)" == "js - Win32 Release" + +DEP_CPP_JSSTR=\ + ".\js.msg"\ + ".\jsapi.h"\ + ".\jsarena.h"\ + ".\jsarray.h"\ + ".\jsatom.h"\ + ".\jsbool.h"\ + ".\jsclist.h"\ + ".\jscntxt.h"\ + ".\jscompat.h"\ + ".\jsconfig.h"\ + ".\jscpucfg.h"\ + ".\jsgc.h"\ + ".\jshash.h"\ + ".\jsinterp.h"\ + ".\jslock.h"\ + ".\jslong.h"\ + ".\jsnum.h"\ + ".\jsobj.h"\ + ".\jsopcode.h"\ + ".\jsopcode.tbl"\ + ".\jsosdep.h"\ + ".\jsotypes.h"\ + ".\jsprf.h"\ + ".\jsprvtd.h"\ + ".\jspubtd.h"\ + ".\jsregexp.h"\ + ".\jsscope.h"\ + ".\jsstddef.h"\ + ".\jsstr.h"\ + ".\jstypes.h"\ + ".\jsutil.h"\ + {$(INCLUDE)}"\sys\types.h"\ + +NODEP_CPP_JSSTR=\ + ".\jsautocfg.h"\ + ".\prcvar.h"\ + ".\prlock.h"\ + + +"$(INTDIR)\jsstr.obj" : $(SOURCE) $(DEP_CPP_JSSTR) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "js - Win32 Debug" + +DEP_CPP_JSSTR=\ + ".\js.msg"\ + ".\jsapi.h"\ + ".\jsarena.h"\ + ".\jsarray.h"\ + ".\jsatom.h"\ + ".\jsbool.h"\ + ".\jsclist.h"\ + ".\jscntxt.h"\ + ".\jscompat.h"\ + ".\jsconfig.h"\ + ".\jscpucfg.h"\ + ".\jsgc.h"\ + ".\jshash.h"\ + ".\jsinterp.h"\ + ".\jslock.h"\ + ".\jslong.h"\ + ".\jsnum.h"\ + ".\jsobj.h"\ + ".\jsopcode.h"\ + ".\jsopcode.tbl"\ + ".\jsosdep.h"\ + ".\jsotypes.h"\ + ".\jsprf.h"\ + ".\jsprvtd.h"\ + ".\jspubtd.h"\ + ".\jsregexp.h"\ + ".\jsscope.h"\ + ".\jsstddef.h"\ + ".\jsstr.h"\ + ".\jstypes.h"\ + ".\jsutil.h"\ + {$(INCLUDE)}"\sys\types.h"\ + +NODEP_CPP_JSSTR=\ + ".\jsautocfg.h"\ + ".\prcvar.h"\ + ".\prlock.h"\ + + +"$(INTDIR)\jsstr.obj" : $(SOURCE) $(DEP_CPP_JSSTR) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\jsutil.c + +!IF "$(CFG)" == "js - Win32 Release" + +DEP_CPP_JSUTI=\ + ".\jscpucfg.h"\ + ".\jsosdep.h"\ + ".\jsotypes.h"\ + ".\jsprf.h"\ + ".\jstypes.h"\ + ".\jsutil.h"\ + {$(INCLUDE)}"\sys\types.h"\ + +NODEP_CPP_JSUTI=\ + ".\jsautocfg.h"\ + + +"$(INTDIR)\jsutil.obj" : $(SOURCE) $(DEP_CPP_JSUTI) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "js - Win32 Debug" + +DEP_CPP_JSUTI=\ + ".\jscpucfg.h"\ + ".\jsosdep.h"\ + ".\jsotypes.h"\ + ".\jsprf.h"\ + ".\jstypes.h"\ + ".\jsutil.h"\ + {$(INCLUDE)}"\sys\types.h"\ + +NODEP_CPP_JSUTI=\ + ".\jsautocfg.h"\ + + +"$(INTDIR)\jsutil.obj" : $(SOURCE) $(DEP_CPP_JSUTI) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\jsxdrapi.c + +!IF "$(CFG)" == "js - Win32 Release" + +DEP_CPP_JSXDR=\ + ".\js.msg"\ + ".\jsapi.h"\ + ".\jsarena.h"\ + ".\jsatom.h"\ + ".\jsclist.h"\ + ".\jscntxt.h"\ + ".\jscompat.h"\ + ".\jsconfig.h"\ + ".\jscpucfg.h"\ + ".\jsgc.h"\ + ".\jshash.h"\ + ".\jsinterp.h"\ + ".\jslock.h"\ + ".\jslong.h"\ + ".\jsobj.h"\ + ".\jsosdep.h"\ + ".\jsotypes.h"\ + ".\jsprf.h"\ + ".\jsprvtd.h"\ + ".\jspubtd.h"\ + ".\jsregexp.h"\ + ".\jsscope.h"\ + ".\jsstddef.h"\ + ".\jsstr.h"\ + ".\jstypes.h"\ + ".\jsutil.h"\ + ".\jsxdrapi.h"\ + {$(INCLUDE)}"\sys\types.h"\ + +NODEP_CPP_JSXDR=\ + ".\jsautocfg.h"\ + ".\prcvar.h"\ + ".\prlock.h"\ + + +"$(INTDIR)\jsxdrapi.obj" : $(SOURCE) $(DEP_CPP_JSXDR) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "js - Win32 Debug" + +DEP_CPP_JSXDR=\ + ".\js.msg"\ + ".\jsapi.h"\ + ".\jsarena.h"\ + ".\jsatom.h"\ + ".\jsclist.h"\ + ".\jscntxt.h"\ + ".\jscompat.h"\ + ".\jsconfig.h"\ + ".\jscpucfg.h"\ + ".\jsgc.h"\ + ".\jshash.h"\ + ".\jsinterp.h"\ + ".\jslock.h"\ + ".\jslong.h"\ + ".\jsobj.h"\ + ".\jsosdep.h"\ + ".\jsotypes.h"\ + ".\jsprf.h"\ + ".\jsprvtd.h"\ + ".\jspubtd.h"\ + ".\jsregexp.h"\ + ".\jsscope.h"\ + ".\jsstddef.h"\ + ".\jsstr.h"\ + ".\jstypes.h"\ + ".\jsutil.h"\ + ".\jsxdrapi.h"\ + {$(INCLUDE)}"\sys\types.h"\ + +NODEP_CPP_JSXDR=\ + ".\jsautocfg.h"\ + ".\prcvar.h"\ + ".\prlock.h"\ + + +"$(INTDIR)\jsxdrapi.obj" : $(SOURCE) $(DEP_CPP_JSXDR) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\prmjtime.c + +!IF "$(CFG)" == "js - Win32 Release" + +DEP_CPP_PRMJT=\ + ".\jscompat.h"\ + ".\jscpucfg.h"\ + ".\jslong.h"\ + ".\jsosdep.h"\ + ".\jsotypes.h"\ + ".\jsprf.h"\ + ".\jstypes.h"\ + ".\prmjtime.h"\ + {$(INCLUDE)}"\sys\TIMEB.H"\ + {$(INCLUDE)}"\sys\types.h"\ + +NODEP_CPP_PRMJT=\ + ".\jsautocfg.h"\ + + +"$(INTDIR)\prmjtime.obj" : $(SOURCE) $(DEP_CPP_PRMJT) "$(INTDIR)" + + +!ELSEIF "$(CFG)" == "js - Win32 Debug" + +DEP_CPP_PRMJT=\ + ".\jscompat.h"\ + ".\jscpucfg.h"\ + ".\jslong.h"\ + ".\jsosdep.h"\ + ".\jsotypes.h"\ + ".\jsprf.h"\ + ".\jstypes.h"\ + ".\prmjtime.h"\ + {$(INCLUDE)}"\sys\TIMEB.H"\ + {$(INCLUDE)}"\sys\types.h"\ + +NODEP_CPP_PRMJT=\ + ".\jsautocfg.h"\ + + +"$(INTDIR)\prmjtime.obj" : $(SOURCE) $(DEP_CPP_PRMJT) "$(INTDIR)" + + +!ENDIF + +# End Source File +################################################################################ +# Begin Project Dependency + +# Project_Dep_Name "fdlibm" + +!IF "$(CFG)" == "js - Win32 Debug" + +"fdlibm - Win32 Debug" : + $(MAKE) /$(MAKEFLAGS) /F ".\js.mak" CFG="fdlibm - Win32 Debug" + +!ELSEIF "$(CFG)" == "js - Win32 Release" + +"fdlibm - Win32 Release" : + $(MAKE) /$(MAKEFLAGS) /F ".\js.mak" CFG="fdlibm - Win32 Release" + +!ENDIF + +# End Project Dependency +# End Target +################################################################################ +# Begin Target + +# Name "jsshell - Win32 Release" +# Name "jsshell - Win32 Debug" + +!IF "$(CFG)" == "jsshell - Win32 Release" + +!ELSEIF "$(CFG)" == "jsshell - Win32 Debug" + +!ENDIF + +################################################################################ +# Begin Source File + +SOURCE=.\js.c +DEP_CPP_JS_C42=\ + ".\js.msg"\ + ".\jsapi.h"\ + ".\jsarena.h"\ + ".\jsatom.h"\ + ".\jsclist.h"\ + ".\jscntxt.h"\ + ".\jscompat.h"\ + ".\jsconfig.h"\ + ".\jscpucfg.h"\ + ".\jsdbgapi.h"\ + ".\jsemit.h"\ + ".\jsfun.h"\ + ".\jsgc.h"\ + ".\jshash.h"\ + ".\jsinterp.h"\ + ".\jslock.h"\ + ".\jslong.h"\ + ".\jsobj.h"\ + ".\jsopcode.h"\ + ".\jsopcode.tbl"\ + ".\jsosdep.h"\ + ".\jsotypes.h"\ + ".\jsparse.h"\ + ".\jsprf.h"\ + ".\jsprvtd.h"\ + ".\jspubtd.h"\ + ".\jsregexp.h"\ + ".\jsscan.h"\ + ".\jsscope.h"\ + ".\jsscript.h"\ + ".\jsshell.msg"\ + ".\jsstddef.h"\ + ".\jsstr.h"\ + ".\jstypes.h"\ + ".\jsutil.h"\ + {$(INCLUDE)}"\sys\types.h"\ + +NODEP_CPP_JS_C42=\ + ".\jsautocfg.h"\ + ".\jsdb.h"\ + ".\jsdebug.h"\ + ".\jsdjava.h"\ + ".\jsjava.h"\ + ".\jsperl.h"\ + ".\prcvar.h"\ + ".\prlock.h"\ + + +"$(INTDIR)\js.obj" : $(SOURCE) $(DEP_CPP_JS_C42) "$(INTDIR)" + + +# End Source File +################################################################################ +# Begin Project Dependency + +# Project_Dep_Name "js" + +!IF "$(CFG)" == "jsshell - Win32 Release" + +"js - Win32 Release" : + $(MAKE) /$(MAKEFLAGS) /F ".\js.mak" CFG="js - Win32 Release" + +!ELSEIF "$(CFG)" == "jsshell - Win32 Debug" + +"js - Win32 Debug" : + $(MAKE) /$(MAKEFLAGS) /F ".\js.mak" CFG="js - Win32 Debug" + +!ENDIF + +# End Project Dependency +# End Target +################################################################################ +# Begin Target + +# Name "fdlibm - Win32 Release" +# Name "fdlibm - Win32 Debug" + +!IF "$(CFG)" == "fdlibm - Win32 Release" + +!ELSEIF "$(CFG)" == "fdlibm - Win32 Debug" + +!ENDIF + +################################################################################ +# Begin Source File + +SOURCE=.\fdlibm\w_atan2.c + +!IF "$(CFG)" == "fdlibm - Win32 Release" + +DEP_CPP_W_ATA=\ + ".\fdlibm\fdlibm.h"\ + + +"$(INTDIR)\w_atan2.obj" : $(SOURCE) $(DEP_CPP_W_ATA) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "fdlibm - Win32 Debug" + +DEP_CPP_W_ATA=\ + ".\fdlibm\fdlibm.h"\ + + +"$(INTDIR)\w_atan2.obj" : $(SOURCE) $(DEP_CPP_W_ATA) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\fdlibm\s_copysign.c + +!IF "$(CFG)" == "fdlibm - Win32 Release" + +DEP_CPP_S_COP=\ + ".\fdlibm\fdlibm.h"\ + + +"$(INTDIR)\s_copysign.obj" : $(SOURCE) $(DEP_CPP_S_COP) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "fdlibm - Win32 Debug" + +DEP_CPP_S_COP=\ + ".\fdlibm\fdlibm.h"\ + + +"$(INTDIR)\s_copysign.obj" : $(SOURCE) $(DEP_CPP_S_COP) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\fdlibm\w_pow.c + +!IF "$(CFG)" == "fdlibm - Win32 Release" + +DEP_CPP_W_POW=\ + ".\fdlibm\fdlibm.h"\ + + +"$(INTDIR)\w_pow.obj" : $(SOURCE) $(DEP_CPP_W_POW) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "fdlibm - Win32 Debug" + +DEP_CPP_W_POW=\ + ".\fdlibm\fdlibm.h"\ + + +"$(INTDIR)\w_pow.obj" : $(SOURCE) $(DEP_CPP_W_POW) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\fdlibm\e_pow.c + +!IF "$(CFG)" == "fdlibm - Win32 Release" + +DEP_CPP_E_POW=\ + ".\fdlibm\fdlibm.h"\ + + +"$(INTDIR)\e_pow.obj" : $(SOURCE) $(DEP_CPP_E_POW) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "fdlibm - Win32 Debug" + +DEP_CPP_E_POW=\ + ".\fdlibm\fdlibm.h"\ + + +"$(INTDIR)\e_pow.obj" : $(SOURCE) $(DEP_CPP_E_POW) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\fdlibm\k_standard.c + +!IF "$(CFG)" == "fdlibm - Win32 Release" + +DEP_CPP_K_STA=\ + ".\fdlibm\fdlibm.h"\ + + +"$(INTDIR)\k_standard.obj" : $(SOURCE) $(DEP_CPP_K_STA) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "fdlibm - Win32 Debug" + +DEP_CPP_K_STA=\ + ".\fdlibm\fdlibm.h"\ + + +"$(INTDIR)\k_standard.obj" : $(SOURCE) $(DEP_CPP_K_STA) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\fdlibm\e_atan2.c + +!IF "$(CFG)" == "fdlibm - Win32 Release" + +DEP_CPP_E_ATA=\ + ".\fdlibm\fdlibm.h"\ + + +"$(INTDIR)\e_atan2.obj" : $(SOURCE) $(DEP_CPP_E_ATA) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "fdlibm - Win32 Debug" + +DEP_CPP_E_ATA=\ + ".\fdlibm\fdlibm.h"\ + + +"$(INTDIR)\e_atan2.obj" : $(SOURCE) $(DEP_CPP_E_ATA) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\fdlibm\s_isnan.c + +!IF "$(CFG)" == "fdlibm - Win32 Release" + +DEP_CPP_S_ISN=\ + ".\fdlibm\fdlibm.h"\ + + +"$(INTDIR)\s_isnan.obj" : $(SOURCE) $(DEP_CPP_S_ISN) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "fdlibm - Win32 Debug" + +DEP_CPP_S_ISN=\ + ".\fdlibm\fdlibm.h"\ + + +"$(INTDIR)\s_isnan.obj" : $(SOURCE) $(DEP_CPP_S_ISN) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\fdlibm\s_fabs.c + +!IF "$(CFG)" == "fdlibm - Win32 Release" + +DEP_CPP_S_FAB=\ + ".\fdlibm\fdlibm.h"\ + + +"$(INTDIR)\s_fabs.obj" : $(SOURCE) $(DEP_CPP_S_FAB) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "fdlibm - Win32 Debug" + +DEP_CPP_S_FAB=\ + ".\fdlibm\fdlibm.h"\ + + +"$(INTDIR)\s_fabs.obj" : $(SOURCE) $(DEP_CPP_S_FAB) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\fdlibm\w_sqrt.c + +!IF "$(CFG)" == "fdlibm - Win32 Release" + +DEP_CPP_W_SQR=\ + ".\fdlibm\fdlibm.h"\ + + +"$(INTDIR)\w_sqrt.obj" : $(SOURCE) $(DEP_CPP_W_SQR) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "fdlibm - Win32 Debug" + +DEP_CPP_W_SQR=\ + ".\fdlibm\fdlibm.h"\ + + +"$(INTDIR)\w_sqrt.obj" : $(SOURCE) $(DEP_CPP_W_SQR) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\fdlibm\s_scalbn.c + +!IF "$(CFG)" == "fdlibm - Win32 Release" + +DEP_CPP_S_SCA=\ + ".\fdlibm\fdlibm.h"\ + + +"$(INTDIR)\s_scalbn.obj" : $(SOURCE) $(DEP_CPP_S_SCA) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "fdlibm - Win32 Debug" + +DEP_CPP_S_SCA=\ + ".\fdlibm\fdlibm.h"\ + + +"$(INTDIR)\s_scalbn.obj" : $(SOURCE) $(DEP_CPP_S_SCA) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\fdlibm\e_sqrt.c + +!IF "$(CFG)" == "fdlibm - Win32 Release" + +DEP_CPP_E_SQR=\ + ".\fdlibm\fdlibm.h"\ + + +"$(INTDIR)\e_sqrt.obj" : $(SOURCE) $(DEP_CPP_E_SQR) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "fdlibm - Win32 Debug" + +DEP_CPP_E_SQR=\ + ".\fdlibm\fdlibm.h"\ + + +"$(INTDIR)\e_sqrt.obj" : $(SOURCE) $(DEP_CPP_E_SQR) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\fdlibm\s_rint.c + +!IF "$(CFG)" == "fdlibm - Win32 Release" + +DEP_CPP_S_RIN=\ + ".\fdlibm\fdlibm.h"\ + + +"$(INTDIR)\s_rint.obj" : $(SOURCE) $(DEP_CPP_S_RIN) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "fdlibm - Win32 Debug" + +DEP_CPP_S_RIN=\ + ".\fdlibm\fdlibm.h"\ + + +"$(INTDIR)\s_rint.obj" : $(SOURCE) $(DEP_CPP_S_RIN) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\fdlibm\s_atan.c + +!IF "$(CFG)" == "fdlibm - Win32 Release" + +DEP_CPP_S_ATA=\ + ".\fdlibm\fdlibm.h"\ + + +"$(INTDIR)\s_atan.obj" : $(SOURCE) $(DEP_CPP_S_ATA) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "fdlibm - Win32 Debug" + +DEP_CPP_S_ATA=\ + ".\fdlibm\fdlibm.h"\ + + +"$(INTDIR)\s_atan.obj" : $(SOURCE) $(DEP_CPP_S_ATA) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\fdlibm\s_finite.c + +!IF "$(CFG)" == "fdlibm - Win32 Release" + +DEP_CPP_S_FIN=\ + ".\fdlibm\fdlibm.h"\ + + +"$(INTDIR)\s_finite.obj" : $(SOURCE) $(DEP_CPP_S_FIN) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "fdlibm - Win32 Debug" + +DEP_CPP_S_FIN=\ + ".\fdlibm\fdlibm.h"\ + + +"$(INTDIR)\s_finite.obj" : $(SOURCE) $(DEP_CPP_S_FIN) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +# End Source File +################################################################################ +# Begin Source File + +SOURCE=.\fdlibm\s_matherr.c + +!IF "$(CFG)" == "fdlibm - Win32 Release" + +DEP_CPP_S_MAT=\ + ".\fdlibm\fdlibm.h"\ + + +"$(INTDIR)\s_matherr.obj" : $(SOURCE) $(DEP_CPP_S_MAT) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ELSEIF "$(CFG)" == "fdlibm - Win32 Debug" + +DEP_CPP_S_MAT=\ + ".\fdlibm\fdlibm.h"\ + + +"$(INTDIR)\s_matherr.obj" : $(SOURCE) $(DEP_CPP_S_MAT) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +!ENDIF + +# End Source File +# End Target +# End Project +################################################################################ diff --git a/src/dom/js/js.msg b/src/dom/js/js.msg new file mode 100644 index 000000000..dbc571fdf --- /dev/null +++ b/src/dom/js/js.msg @@ -0,0 +1,251 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* + * This is the JavaScript error message file. + * + * The format for each JS error message is: + * + * MSG_DEF(, , , , + * ) + * + * where ; + * is a legal C identifer that will be used in the + * JS engine source. + * + * is an unique integral value identifying this error. + * + * is an integer literal specifying the total number of + * replaceable arguments in the following format string. + * + * is an exception index from the enum in jsexn.c; + * JSEXN_NONE for none. The given exception index will be raised by the + * engine when the corresponding error occurs. + * + * is a string literal, optionally containing sequences + * {X} where X is an integer representing the argument number that will + * be replaced with a string value when the error is reported. + * + * e.g. + * + * MSG_DEF(JSMSG_NOT_A_SUBSPECIES, 73, JSEXN_NONE, 2, + * "{0} is not a member of the {1} family") + * + * can be used: + * + * JS_ReportErrorNumber(JSMSG_NOT_A_SUBSPECIES, "Rhino", "Monkey"); + * + * to report: + * + * "Rhino is not a member of the Monkey family" + * + * Before adding a new MSG_DEF at the end, look for JSMSG_UNUSED free + * index placeholders in the middle of the list. + */ + +MSG_DEF(JSMSG_NOT_AN_ERROR, 0, 0, JSEXN_NONE, "") +MSG_DEF(JSMSG_NOT_DEFINED, 1, 1, JSEXN_REFERENCEERR, "{0} is not defined") +MSG_DEF(JSMSG_NO_REG_EXPS, 2, 1, JSEXN_INTERNALERR, "sorry, regular expression are not supported") +MSG_DEF(JSMSG_MORE_ARGS_NEEDED, 3, 3, JSEXN_NONE, "{0} requires more than {1} argument{2}") +MSG_DEF(JSMSG_BAD_CHAR, 4, 1, JSEXN_NONE, "invalid format character {0}") +MSG_DEF(JSMSG_BAD_TYPE, 5, 1, JSEXN_NONE, "unknown type {0}") +MSG_DEF(JSMSG_CANT_LOCK, 6, 0, JSEXN_NONE, "can't lock memory") +MSG_DEF(JSMSG_CANT_UNLOCK, 7, 0, JSEXN_NONE, "can't unlock memory") +MSG_DEF(JSMSG_INCOMPATIBLE_PROTO, 8, 3, JSEXN_TYPEERR, "{0}.prototype.{1} called on incompatible {2}") +MSG_DEF(JSMSG_NO_CONSTRUCTOR, 9, 1, JSEXN_NONE, "{0} has no constructor") +MSG_DEF(JSMSG_CANT_ALIAS, 10, 3, JSEXN_NONE, "can't alias {0} to {1} in class {2}") +MSG_DEF(JSMSG_UNUSED11, 11, 0, JSEXN_NONE, "") +MSG_DEF(JSMSG_BAD_SORT_ARG, 12, 0, JSEXN_TYPEERR, "invalid Array.prototype.sort argument") +MSG_DEF(JSMSG_BAD_ATOMIC_NUMBER, 13, 1, JSEXN_INTERNALERR, "internal error: no index for atom {0}") +MSG_DEF(JSMSG_TOO_MANY_LITERALS, 14, 0, JSEXN_INTERNALERR, "too many literals") +MSG_DEF(JSMSG_CANT_WATCH, 15, 1, JSEXN_NONE, "can't watch non-native objects of class {0}") +MSG_DEF(JSMSG_STACK_UNDERFLOW, 16, 2, JSEXN_INTERNALERR, "internal error compiling {0}: stack underflow at pc {1}") +MSG_DEF(JSMSG_NEED_DIET, 17, 1, JSEXN_INTERNALERR, "{0} too large") +MSG_DEF(JSMSG_UNUSED18, 18, 0, JSEXN_NONE, "") +MSG_DEF(JSMSG_READ_ONLY, 19, 1, JSEXN_ERR, "{0} is read-only") +MSG_DEF(JSMSG_BAD_FORMAL, 20, 0, JSEXN_SYNTAXERR, "malformed formal parameter") +MSG_DEF(JSMSG_SAME_FORMAL, 21, 1, JSEXN_NONE, "duplicate formal argument {0}") +MSG_DEF(JSMSG_NOT_FUNCTION, 22, 1, JSEXN_TYPEERR, "{0} is not a function") +MSG_DEF(JSMSG_NOT_CONSTRUCTOR, 23, 1, JSEXN_TYPEERR, "{0} is not a constructor") +MSG_DEF(JSMSG_STACK_OVERFLOW, 24, 1, JSEXN_INTERNALERR, "stack overflow in {0}") +MSG_DEF(JSMSG_NOT_EXPORTED, 25, 1, JSEXN_NONE, "{0} is not exported") +MSG_DEF(JSMSG_OVER_RECURSED, 26, 0, JSEXN_INTERNALERR, "too much recursion") +MSG_DEF(JSMSG_IN_NOT_OBJECT, 27, 1, JSEXN_TYPEERR, "invalid 'in' operand {0}") +MSG_DEF(JSMSG_BAD_NEW_RESULT, 28, 1, JSEXN_NONE, "invalid new expression result {0}") +MSG_DEF(JSMSG_BAD_SHARP_DEF, 29, 1, JSEXN_ERR, "invalid sharp variable definition #{0}=") +MSG_DEF(JSMSG_BAD_SHARP_USE, 30, 1, JSEXN_ERR, "invalid sharp variable use #{0}#") +MSG_DEF(JSMSG_BAD_INSTANCEOF_RHS, 31, 1, JSEXN_TYPEERR, "invalid 'instanceof' operand {0}") +MSG_DEF(JSMSG_BAD_BYTECODE, 32, 1, JSEXN_INTERNALERR, "unimplemented JavaScript bytecode {0}") +MSG_DEF(JSMSG_BAD_RADIX, 33, 1, JSEXN_ERR, "illegal radix {0}") +MSG_DEF(JSMSG_NAN, 34, 1, JSEXN_ERR, "{0} is not a number") +MSG_DEF(JSMSG_CANT_CONVERT, 35, 1, JSEXN_NONE, "can't convert {0} to an integer") +MSG_DEF(JSMSG_CYCLIC_VALUE, 36, 1, JSEXN_ERR, "cyclic {0} value") +MSG_DEF(JSMSG_PERMANENT, 37, 1, JSEXN_ERR, "{0} is permanent") +MSG_DEF(JSMSG_CANT_CONVERT_TO, 38, 2, JSEXN_TYPEERR, "can't convert {0} to {1}") +MSG_DEF(JSMSG_NO_PROPERTIES, 39, 1, JSEXN_TYPEERR, "{0} has no properties") +MSG_DEF(JSMSG_CANT_FIND_CLASS, 40, 1, JSEXN_NONE, "can't find class id {0}") +MSG_DEF(JSMSG_CANT_XDR_CLASS, 41, 1, JSEXN_NONE, "can't XDR class {0}") +MSG_DEF(JSMSG_BYTECODE_TOO_BIG, 42, 2, JSEXN_INTERNALERR, "bytecode {0} too large (limit {1})") +MSG_DEF(JSMSG_UNKNOWN_FORMAT, 43, 1, JSEXN_INTERNALERR, "unknown bytecode format {0}") +MSG_DEF(JSMSG_TOO_MANY_CON_ARGS, 44, 0, JSEXN_SYNTAXERR, "too many constructor arguments") +MSG_DEF(JSMSG_TOO_MANY_FUN_ARGS, 45, 0, JSEXN_SYNTAXERR, "too many function arguments") +MSG_DEF(JSMSG_BAD_QUANTIFIER, 46, 1, JSEXN_SYNTAXERR, "invalid quantifier {0}") +MSG_DEF(JSMSG_MIN_TOO_BIG, 47, 1, JSEXN_SYNTAXERR, "overlarge minimum {0}") +MSG_DEF(JSMSG_MAX_TOO_BIG, 48, 1, JSEXN_SYNTAXERR, "overlarge maximum {0}") +MSG_DEF(JSMSG_OUT_OF_ORDER, 49, 1, JSEXN_SYNTAXERR, "maximum {0} less than minimum") +MSG_DEF(JSMSG_ZERO_QUANTIFIER, 50, 1, JSEXN_SYNTAXERR, "zero quantifier {0}") +MSG_DEF(JSMSG_UNTERM_QUANTIFIER, 51, 1, JSEXN_SYNTAXERR, "unterminated quantifier {0}") +MSG_DEF(JSMSG_EMPTY_BEFORE_STAR, 52, 0, JSEXN_SYNTAXERR, "regular expression before * could be empty") +MSG_DEF(JSMSG_EMPTY_BEFORE_PLUS, 53, 0, JSEXN_SYNTAXERR, "regular expression before + could be empty") +MSG_DEF(JSMSG_MISSING_PAREN, 54, 0, JSEXN_SYNTAXERR, "unterminated parenthetical") +MSG_DEF(JSMSG_UNTERM_CLASS, 55, 1, JSEXN_SYNTAXERR, "unterminated character class {0}") +MSG_DEF(JSMSG_TRAILING_SLASH, 56, 0, JSEXN_SYNTAXERR, "trailing \\ in regular expression") +MSG_DEF(JSMSG_BAD_CLASS_RANGE, 57, 0, JSEXN_SYNTAXERR, "invalid range in character class") +MSG_DEF(JSMSG_BAD_FLAG, 58, 1, JSEXN_SYNTAXERR, "invalid regular expression flag {0}") +MSG_DEF(JSMSG_NO_INPUT, 59, 3, JSEXN_SYNTAXERR, "no input for /{0}/{1}{2}") +MSG_DEF(JSMSG_CANT_OPEN, 60, 2, JSEXN_NONE, "can't open {0}: {1}") +MSG_DEF(JSMSG_BAD_STRING_MASK, 61, 1, JSEXN_ERR, "invalid string escape mask {0}") +MSG_DEF(JSMSG_UNMATCHED_RIGHT_PAREN, 62, 0, JSEXN_SYNTAXERR, "unmatched ) in regular expression") +MSG_DEF(JSMSG_END_OF_DATA, 63, 0, JSEXN_NONE, "unexpected end of data") +MSG_DEF(JSMSG_SEEK_BEYOND_START, 64, 0, JSEXN_NONE, "illegal seek beyond start") +MSG_DEF(JSMSG_SEEK_BEYOND_END, 65, 0, JSEXN_NONE, "illegal seek beyond end") +MSG_DEF(JSMSG_END_SEEK, 66, 0, JSEXN_NONE, "illegal end-based seek") +MSG_DEF(JSMSG_WHITHER_WHENCE, 67, 1, JSEXN_NONE, "unknown seek whence: {0}") +MSG_DEF(JSMSG_BAD_SCRIPT_MAGIC, 68, 0, JSEXN_NONE, "bad script XDR magic number") +MSG_DEF(JSMSG_PAREN_BEFORE_FORMAL, 69, 0, JSEXN_SYNTAXERR, "missing ( before formal parameters") +MSG_DEF(JSMSG_MISSING_FORMAL, 70, 0, JSEXN_SYNTAXERR, "missing formal parameter") +MSG_DEF(JSMSG_PAREN_AFTER_FORMAL, 71, 0, JSEXN_SYNTAXERR, "missing ) after formal parameters") +MSG_DEF(JSMSG_CURLY_BEFORE_BODY, 72, 0, JSEXN_SYNTAXERR, "missing { before function body") +MSG_DEF(JSMSG_CURLY_AFTER_BODY, 73, 0, JSEXN_SYNTAXERR, "missing } after function body") +MSG_DEF(JSMSG_PAREN_BEFORE_COND, 74, 0, JSEXN_SYNTAXERR, "missing ( before condition") +MSG_DEF(JSMSG_PAREN_AFTER_COND, 75, 0, JSEXN_SYNTAXERR, "missing ) after condition") +MSG_DEF(JSMSG_NO_IMPORT_NAME, 76, 0, JSEXN_SYNTAXERR, "missing name in import statement") +MSG_DEF(JSMSG_NAME_AFTER_DOT, 77, 0, JSEXN_SYNTAXERR, "missing name after . operator") +MSG_DEF(JSMSG_BRACKET_IN_INDEX, 78, 0, JSEXN_SYNTAXERR, "missing ] in index expression") +MSG_DEF(JSMSG_NO_EXPORT_NAME, 79, 0, JSEXN_SYNTAXERR, "missing name in export statement") +MSG_DEF(JSMSG_PAREN_BEFORE_SWITCH, 80, 0, JSEXN_SYNTAXERR, "missing ( before switch expression") +MSG_DEF(JSMSG_PAREN_AFTER_SWITCH, 81, 0, JSEXN_SYNTAXERR, "missing ) after switch expression") +MSG_DEF(JSMSG_CURLY_BEFORE_SWITCH, 82, 0, JSEXN_SYNTAXERR, "missing { before switch body") +MSG_DEF(JSMSG_COLON_AFTER_CASE, 83, 0, JSEXN_SYNTAXERR, "missing : after case label") +MSG_DEF(JSMSG_WHILE_AFTER_DO, 84, 0, JSEXN_SYNTAXERR, "missing while after do-loop body") +MSG_DEF(JSMSG_PAREN_AFTER_FOR, 85, 0, JSEXN_SYNTAXERR, "missing ( after for") +MSG_DEF(JSMSG_SEMI_AFTER_FOR_INIT, 86, 0, JSEXN_SYNTAXERR, "missing ; after for-loop initializer") +MSG_DEF(JSMSG_SEMI_AFTER_FOR_COND, 87, 0, JSEXN_SYNTAXERR, "missing ; after for-loop condition") +MSG_DEF(JSMSG_PAREN_AFTER_FOR_CTRL, 88, 0, JSEXN_SYNTAXERR, "missing ) after for-loop control") +MSG_DEF(JSMSG_CURLY_BEFORE_TRY, 89, 0, JSEXN_SYNTAXERR, "missing { before try block") +MSG_DEF(JSMSG_CURLY_AFTER_TRY, 90, 0, JSEXN_SYNTAXERR, "missing } after try block") +MSG_DEF(JSMSG_PAREN_BEFORE_CATCH, 91, 0, JSEXN_SYNTAXERR, "missing ( before catch") +MSG_DEF(JSMSG_CATCH_IDENTIFIER, 92, 0, JSEXN_SYNTAXERR, "missing identifier in catch") +MSG_DEF(JSMSG_PAREN_AFTER_CATCH, 93, 0, JSEXN_SYNTAXERR, "missing ) after catch") +MSG_DEF(JSMSG_CURLY_BEFORE_CATCH, 94, 0, JSEXN_SYNTAXERR, "missing { before catch block") +MSG_DEF(JSMSG_CURLY_AFTER_CATCH, 95, 0, JSEXN_SYNTAXERR, "missing } after catch block") +MSG_DEF(JSMSG_CURLY_BEFORE_FINALLY, 96, 0, JSEXN_SYNTAXERR, "missing { before finally block") +MSG_DEF(JSMSG_CURLY_AFTER_FINALLY, 97, 0, JSEXN_SYNTAXERR, "missing } after finally block") +MSG_DEF(JSMSG_CATCH_OR_FINALLY, 98, 0, JSEXN_SYNTAXERR, "missing catch or finally after try") +MSG_DEF(JSMSG_PAREN_BEFORE_WITH, 99, 0, JSEXN_SYNTAXERR, "missing ( before with-statement object") +MSG_DEF(JSMSG_PAREN_AFTER_WITH, 100, 0, JSEXN_SYNTAXERR, "missing ) after with-statement object") +MSG_DEF(JSMSG_CURLY_IN_COMPOUND, 101, 0, JSEXN_SYNTAXERR, "missing } in compound statement") +MSG_DEF(JSMSG_NO_VARIABLE_NAME, 102, 0, JSEXN_SYNTAXERR, "missing variable name") +MSG_DEF(JSMSG_COLON_IN_COND, 103, 0, JSEXN_SYNTAXERR, "missing : in conditional expression") +MSG_DEF(JSMSG_PAREN_AFTER_ARGS, 104, 0, JSEXN_SYNTAXERR, "missing ) after argument list") +MSG_DEF(JSMSG_BRACKET_AFTER_LIST, 105, 0, JSEXN_SYNTAXERR, "missing ] after element list") +MSG_DEF(JSMSG_COLON_AFTER_ID, 106, 0, JSEXN_SYNTAXERR, "missing : after property id") +MSG_DEF(JSMSG_CURLY_AFTER_LIST, 107, 0, JSEXN_SYNTAXERR, "missing } after property list") +MSG_DEF(JSMSG_PAREN_IN_PAREN, 108, 0, JSEXN_SYNTAXERR, "missing ) in parenthetical") +MSG_DEF(JSMSG_SEMI_BEFORE_STMNT, 109, 0, JSEXN_SYNTAXERR, "missing ; before statement") +MSG_DEF(JSMSG_NO_RETURN_VALUE, 110, 1, JSEXN_TYPEERR, "function {0} does not always return a value") +MSG_DEF(JSMSG_DUPLICATE_FORMAL, 111, 1, JSEXN_TYPEERR, "duplicate formal argument {0}") +MSG_DEF(JSMSG_EQUAL_AS_ASSIGN, 112, 1, JSEXN_NONE, "test for equality (==) mistyped as assignment (=)?{0}") +MSG_DEF(JSMSG_BAD_IMPORT, 113, 0, JSEXN_SYNTAXERR, "invalid import expression") +MSG_DEF(JSMSG_TOO_MANY_DEFAULTS, 114, 0, JSEXN_SYNTAXERR, "more than one switch default") +MSG_DEF(JSMSG_TOO_MANY_CASES, 115, 0, JSEXN_INTERNALERR, "too many switch cases") +MSG_DEF(JSMSG_BAD_SWITCH, 116, 0, JSEXN_SYNTAXERR, "invalid switch statement") +MSG_DEF(JSMSG_BAD_FOR_LEFTSIDE, 117, 0, JSEXN_SYNTAXERR, "invalid for/in left-hand side") +MSG_DEF(JSMSG_CATCH_AFTER_GENERAL, 118, 0, JSEXN_SYNTAXERR, "catch after unconditional catch") +MSG_DEF(JSMSG_CATCH_WITHOUT_TRY, 119, 0, JSEXN_SYNTAXERR, "catch without try") +MSG_DEF(JSMSG_FINALLY_WITHOUT_TRY, 120, 0, JSEXN_SYNTAXERR, "finally without try") +MSG_DEF(JSMSG_LABEL_NOT_FOUND, 121, 0, JSEXN_SYNTAXERR, "label not found") +MSG_DEF(JSMSG_TOUGH_BREAK, 122, 0, JSEXN_SYNTAXERR, "invalid break") +MSG_DEF(JSMSG_BAD_CONTINUE, 123, 0, JSEXN_SYNTAXERR, "invalid continue") +MSG_DEF(JSMSG_BAD_RETURN, 124, 0, JSEXN_SYNTAXERR, "invalid return") +MSG_DEF(JSMSG_BAD_LABEL, 125, 0, JSEXN_SYNTAXERR, "invalid label") +MSG_DEF(JSMSG_DUPLICATE_LABEL, 126, 0, JSEXN_SYNTAXERR, "duplicate label") +MSG_DEF(JSMSG_VAR_HIDES_ARG, 127, 1, JSEXN_TYPEERR, "variable {0} hides argument") +MSG_DEF(JSMSG_BAD_VAR_INIT, 128, 0, JSEXN_SYNTAXERR, "invalid variable initialization") +MSG_DEF(JSMSG_BAD_LEFTSIDE_OF_ASS, 129, 0, JSEXN_SYNTAXERR, "invalid assignment left-hand side") +MSG_DEF(JSMSG_BAD_OPERAND, 130, 1, JSEXN_SYNTAXERR, "invalid {0} operand") +MSG_DEF(JSMSG_BAD_PROP_ID, 131, 0, JSEXN_SYNTAXERR, "invalid property id") +MSG_DEF(JSMSG_RESERVED_ID, 132, 1, JSEXN_SYNTAXERR, "{0} is a reserved identifier") +MSG_DEF(JSMSG_SYNTAX_ERROR, 133, 0, JSEXN_SYNTAXERR, "syntax error") +MSG_DEF(JSMSG_BAD_SHARP_VAR_DEF, 134, 0, JSEXN_SYNTAXERR, "invalid sharp variable definition") +MSG_DEF(JSMSG_BAD_PROTOTYPE, 135, 1, JSEXN_TYPEERR, "'prototype' property of {0} is not an object") +MSG_DEF(JSMSG_MISSING_EXPONENT, 136, 0, JSEXN_SYNTAXERR, "missing exponent") +MSG_DEF(JSMSG_OUT_OF_MEMORY, 137, 0, JSEXN_ERR, "out of memory") +MSG_DEF(JSMSG_UNTERMINATED_STRING, 138, 0, JSEXN_SYNTAXERR, "unterminated string literal") +MSG_DEF(JSMSG_TOO_MANY_PARENS, 139, 0, JSEXN_INTERNALERR, "too many parentheses in regular expression") +MSG_DEF(JSMSG_UNTERMINATED_COMMENT, 140, 0, JSEXN_SYNTAXERR, "unterminated comment") +MSG_DEF(JSMSG_UNTERMINATED_REGEXP, 141, 0, JSEXN_SYNTAXERR, "unterminated regular expression literal") +MSG_DEF(JSMSG_BAD_REGEXP_FLAG, 142, 0, JSEXN_SYNTAXERR, "invalid flag after regular expression") +MSG_DEF(JSMSG_SHARPVAR_TOO_BIG, 143, 0, JSEXN_SYNTAXERR, "overlarge sharp variable number") +MSG_DEF(JSMSG_ILLEGAL_CHARACTER, 144, 0, JSEXN_SYNTAXERR, "illegal character") +MSG_DEF(JSMSG_BAD_OCTAL, 145, 1, JSEXN_NONE, "{0} is not a legal ECMA-262 octal constant") +MSG_DEF(JSMSG_BAD_INDIRECT_CALL, 146, 1, JSEXN_EVALERR, "function {0} must be called directly, and not by way of a function of another name.") +MSG_DEF(JSMSG_UNCAUGHT_EXCEPTION, 147, 1, JSEXN_NONE, "uncaught exception: {0}") +MSG_DEF(JSMSG_INVALID_BACKREF, 148, 0, JSEXN_SYNTAXERR, "non-octal digit in an escape sequence that doesn't match a back-reference") +MSG_DEF(JSMSG_BAD_BACKREF, 149, 0, JSEXN_SYNTAXERR, "back-reference exceeds number of capturing parentheses") +MSG_DEF(JSMSG_PRECISION_RANGE, 150, 1, JSEXN_RANGEERR, "precision {0} out of range") +MSG_DEF(JSMSG_BAD_GETTER_OR_SETTER, 151, 1, JSEXN_SYNTAXERR, "invalid {0} usage") +MSG_DEF(JSMSG_BAD_ARRAY_LENGTH, 152, 0, JSEXN_RANGEERR, "invalid array length") +MSG_DEF(JSMSG_CANT_DESCRIBE_PROPS, 153, 1, JSEXN_NONE, "can't describe non-native properties of class {0}") +MSG_DEF(JSMSG_BAD_APPLY_ARGS, 154, 0, JSEXN_TYPEERR, "second argument to Function.prototype.apply must be an array") +MSG_DEF(JSMSG_REDECLARED_VAR, 155, 2, JSEXN_TYPEERR, "redeclaration of {0} {1}") +MSG_DEF(JSMSG_UNDECLARED_VAR, 156, 1, JSEXN_TYPEERR, "assignment to undeclared variable {0}") +MSG_DEF(JSMSG_ANON_NO_RETURN_VALUE, 157, 0, JSEXN_TYPEERR, "anonymous function does not always return a value") +MSG_DEF(JSMSG_DEPRECATED_USAGE, 158, 1, JSEXN_REFERENCEERR, "deprecated {0} usage") +MSG_DEF(JSMSG_BAD_URI, 159, 0, JSEXN_URIERR, "malformed URI sequence") +MSG_DEF(JSMSG_GETTER_ONLY, 160, 0, JSEXN_TYPEERR, "setting a property that has only a getter") +MSG_DEF(JSMSG_TRAILING_COMMA, 161, 0, JSEXN_SYNTAXERR, "trailing comma is not legal in ECMA-262 object initializers") +MSG_DEF(JSMSG_UNDEFINED_PROP, 162, 1, JSEXN_TYPEERR, "reference to undefined property {0}") +MSG_DEF(JSMSG_USELESS_EXPR, 163, 0, JSEXN_TYPEERR, "useless expression") +MSG_DEF(JSMSG_REDECLARED_PARAM, 164, 1, JSEXN_TYPEERR, "redeclaration of formal parameter {0}") +MSG_DEF(JSMSG_NEWREGEXP_FLAGGED, 165, 0, JSEXN_TYPEERR, "can't supply flags when constructing one RegExp from another") +MSG_DEF(JSMSG_RESERVED_SLOT_RANGE, 166, 0, JSEXN_RANGEERR, "reserved slot index out of range") +MSG_DEF(JSMSG_CANT_DECODE_PRINCIPALS, 167, 0, JSEXN_INTERNALERR, "can't decode JSPrincipals") +MSG_DEF(JSMSG_CANT_SEAL_OBJECT, 168, 1, JSEXN_ERR, "can't seal {0} objects") +MSG_DEF(JSMSG_CANT_UNSEAL_OBJECT, 169, 1, JSEXN_ERR, "can't unseal {0} objects") diff --git a/src/dom/js/jsapi.c b/src/dom/js/jsapi.c new file mode 100644 index 000000000..faf02d983 --- /dev/null +++ b/src/dom/js/jsapi.c @@ -0,0 +1,4187 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* + * JavaScript API. + */ +#include "jsstddef.h" +#include +#include +#include +#include +#include "jstypes.h" +#include "jsarena.h" /* Added by JSIFY */ +#include "jsutil.h" /* Added by JSIFY */ +#include "jsclist.h" +#include "jsdhash.h" +#include "jsprf.h" +#include "jsapi.h" +#include "jsarray.h" +#include "jsatom.h" +#include "jsbool.h" +#include "jscntxt.h" +#include "jsconfig.h" +#include "jsdate.h" +#include "jsdtoa.h" +#include "jsemit.h" +#include "jsexn.h" +#include "jsfun.h" +#include "jsgc.h" +#include "jsinterp.h" +#include "jslock.h" +#include "jsmath.h" +#include "jsnum.h" +#include "jsobj.h" +#include "jsopcode.h" +#include "jsparse.h" +#include "jsregexp.h" +#include "jsscan.h" +#include "jsscope.h" +#include "jsscript.h" +#include "jsstr.h" +#include "prmjtime.h" + +#if JS_HAS_FILE_OBJECT +#include "jsfile.h" +#endif + +#ifdef HAVE_VA_LIST_AS_ARRAY +#define JS_ADDRESSOF_VA_LIST(ap) (ap) +#else +#define JS_ADDRESSOF_VA_LIST(ap) (&(ap)) +#endif + +#if defined(JS_PARANOID_REQUEST) && defined(JS_THREADSAFE) +#define CHECK_REQUEST(cx) JS_ASSERT(cx->requestDepth) +#else +#define CHECK_REQUEST(cx) ((void)0) +#endif + +JS_PUBLIC_API(int64) +JS_Now() +{ + return PRMJ_Now(); +} + +JS_PUBLIC_API(jsval) +JS_GetNaNValue(JSContext *cx) +{ + return DOUBLE_TO_JSVAL(cx->runtime->jsNaN); +} + +JS_PUBLIC_API(jsval) +JS_GetNegativeInfinityValue(JSContext *cx) +{ + return DOUBLE_TO_JSVAL(cx->runtime->jsNegativeInfinity); +} + +JS_PUBLIC_API(jsval) +JS_GetPositiveInfinityValue(JSContext *cx) +{ + return DOUBLE_TO_JSVAL(cx->runtime->jsPositiveInfinity); +} + +JS_PUBLIC_API(jsval) +JS_GetEmptyStringValue(JSContext *cx) +{ + return STRING_TO_JSVAL(cx->runtime->emptyString); +} + +static JSBool +TryArgumentFormatter(JSContext *cx, const char **formatp, JSBool fromJS, + jsval **vpp, va_list *app) +{ + const char *format; + JSArgumentFormatMap *map; + + format = *formatp; + for (map = cx->argumentFormatMap; map; map = map->next) { + if (!strncmp(format, map->format, map->length)) { + *formatp = format + map->length; + return map->formatter(cx, format, fromJS, vpp, app); + } + } + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BAD_CHAR, format); + return JS_FALSE; +} + +JS_PUBLIC_API(JSBool) +JS_ConvertArguments(JSContext *cx, uintN argc, jsval *argv, const char *format, + ...) +{ + va_list ap; + JSBool ok; + + va_start(ap, format); + ok = JS_ConvertArgumentsVA(cx, argc, argv, format, ap); + va_end(ap); + return ok; +} + +JS_PUBLIC_API(JSBool) +JS_ConvertArgumentsVA(JSContext *cx, uintN argc, jsval *argv, + const char *format, va_list ap) +{ + jsval *sp; + JSBool required; + char c; + JSFunction *fun; + jsdouble d; + JSString *str; + JSObject *obj; + + CHECK_REQUEST(cx); + sp = argv; + required = JS_TRUE; + while ((c = *format++) != '\0') { + if (isspace(c)) + continue; + if (c == '/') { + required = JS_FALSE; + continue; + } + if (sp == argv + argc) { + if (required) { + fun = js_ValueToFunction(cx, &argv[-2], 0); + if (fun) { + char numBuf[12]; + JS_snprintf(numBuf, sizeof numBuf, "%u", argc); + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, + JSMSG_MORE_ARGS_NEEDED, + JS_GetFunctionName(fun), numBuf, + (argc == 1) ? "" : "s"); + } + return JS_FALSE; + } + break; + } + switch (c) { + case 'b': + if (!js_ValueToBoolean(cx, *sp, va_arg(ap, JSBool *))) + return JS_FALSE; + break; + case 'c': + if (!js_ValueToUint16(cx, *sp, va_arg(ap, uint16 *))) + return JS_FALSE; + break; + case 'i': + if (!js_ValueToECMAInt32(cx, *sp, va_arg(ap, int32 *))) + return JS_FALSE; + break; + case 'u': + if (!js_ValueToECMAUint32(cx, *sp, va_arg(ap, uint32 *))) + return JS_FALSE; + break; + case 'j': + if (!js_ValueToInt32(cx, *sp, va_arg(ap, int32 *))) + return JS_FALSE; + break; + case 'd': + if (!js_ValueToNumber(cx, *sp, va_arg(ap, jsdouble *))) + return JS_FALSE; + break; + case 'I': + if (!js_ValueToNumber(cx, *sp, &d)) + return JS_FALSE; + *va_arg(ap, jsdouble *) = js_DoubleToInteger(d); + break; + case 's': + case 'S': + case 'W': + str = js_ValueToString(cx, *sp); + if (!str) + return JS_FALSE; + *sp = STRING_TO_JSVAL(str); + if (c == 's') + *va_arg(ap, char **) = JS_GetStringBytes(str); + else if (c == 'W') + *va_arg(ap, jschar **) = JS_GetStringChars(str); + else + *va_arg(ap, JSString **) = str; + break; + case 'o': + if (!js_ValueToObject(cx, *sp, &obj)) + return JS_FALSE; + *sp = OBJECT_TO_JSVAL(obj); + *va_arg(ap, JSObject **) = obj; + break; + case 'f': + fun = js_ValueToFunction(cx, sp, 0); + if (!fun) + return JS_FALSE; + *sp = OBJECT_TO_JSVAL(fun->object); + *va_arg(ap, JSFunction **) = fun; + break; + case 'v': + *va_arg(ap, jsval *) = *sp; + break; + case '*': + break; + default: + format--; + if (!TryArgumentFormatter(cx, &format, JS_TRUE, &sp, + JS_ADDRESSOF_VA_LIST(ap))) { + return JS_FALSE; + } + /* NB: the formatter already updated sp, so we continue here. */ + continue; + } + sp++; + } + return JS_TRUE; +} + +JS_PUBLIC_API(jsval *) +JS_PushArguments(JSContext *cx, void **markp, const char *format, ...) +{ + va_list ap; + jsval *argv; + + va_start(ap, format); + argv = JS_PushArgumentsVA(cx, markp, format, ap); + va_end(ap); + return argv; +} + +JS_PUBLIC_API(jsval *) +JS_PushArgumentsVA(JSContext *cx, void **markp, const char *format, va_list ap) +{ + uintN argc; + jsval *argv, *sp; + char c; + const char *cp; + JSString *str; + JSFunction *fun; + JSStackHeader *sh; + + CHECK_REQUEST(cx); + *markp = NULL; + argc = 0; + for (cp = format; (c = *cp) != '\0'; cp++) { + /* + * Count non-space non-star characters as individual jsval arguments. + * This may over-allocate stack, but we'll fix below. + */ + if (isspace(c) || c == '*') + continue; + argc++; + } + sp = js_AllocStack(cx, argc, markp); + if (!sp) + return NULL; + argv = sp; + while ((c = *format++) != '\0') { + if (isspace(c) || c == '*') + continue; + switch (c) { + case 'b': + *sp = BOOLEAN_TO_JSVAL((JSBool) va_arg(ap, int)); + break; + case 'c': + *sp = INT_TO_JSVAL((uint16) va_arg(ap, unsigned int)); + break; + case 'i': + case 'j': + if (!js_NewNumberValue(cx, (jsdouble) va_arg(ap, int32), sp)) + goto bad; + break; + case 'u': + if (!js_NewNumberValue(cx, (jsdouble) va_arg(ap, uint32), sp)) + goto bad; + break; + case 'd': + case 'I': + if (!js_NewDoubleValue(cx, va_arg(ap, jsdouble), sp)) + goto bad; + break; + case 's': + str = JS_NewStringCopyZ(cx, va_arg(ap, char *)); + if (!str) + goto bad; + *sp = STRING_TO_JSVAL(str); + break; + case 'W': + str = JS_NewUCStringCopyZ(cx, va_arg(ap, jschar *)); + if (!str) + goto bad; + *sp = STRING_TO_JSVAL(str); + break; + case 'S': + str = va_arg(ap, JSString *); + *sp = STRING_TO_JSVAL(str); + break; + case 'o': + *sp = OBJECT_TO_JSVAL(va_arg(ap, JSObject *)); + break; + case 'f': + fun = va_arg(ap, JSFunction *); + *sp = fun ? OBJECT_TO_JSVAL(fun->object) : JSVAL_NULL; + break; + case 'v': + *sp = va_arg(ap, jsval); + break; + default: + format--; + if (!TryArgumentFormatter(cx, &format, JS_FALSE, &sp, + JS_ADDRESSOF_VA_LIST(ap))) { + goto bad; + } + /* NB: the formatter already updated sp, so we continue here. */ + continue; + } + sp++; + } + + /* + * We may have overallocated stack due to a multi-character format code + * handled by a JSArgumentFormatter. Give back that stack space! + */ + JS_ASSERT(sp <= argv + argc); + if (sp < argv + argc) { + /* Return slots not pushed to the current stack arena. */ + cx->stackPool.current->avail = (jsuword)sp; + + /* Reduce the count of slots the GC will scan in this stack segment. */ + sh = cx->stackHeaders; + JS_ASSERT(JS_STACK_SEGMENT(sh) + sh->nslots == argv + argc); + sh->nslots -= argc - (sp - argv); + } + return argv; + +bad: + js_FreeStack(cx, *markp); + return NULL; +} + +JS_PUBLIC_API(void) +JS_PopArguments(JSContext *cx, void *mark) +{ + CHECK_REQUEST(cx); + js_FreeStack(cx, mark); +} + +JS_PUBLIC_API(JSBool) +JS_AddArgumentFormatter(JSContext *cx, const char *format, + JSArgumentFormatter formatter) +{ + size_t length; + JSArgumentFormatMap **mpp, *map; + + length = strlen(format); + mpp = &cx->argumentFormatMap; + while ((map = *mpp) != NULL) { + /* Insert before any shorter string to match before prefixes. */ + if (map->length < length) + break; + if (map->length == length && !strcmp(map->format, format)) + goto out; + mpp = &map->next; + } + map = (JSArgumentFormatMap *) JS_malloc(cx, sizeof *map); + if (!map) + return JS_FALSE; + map->format = format; + map->length = length; + map->next = *mpp; + *mpp = map; +out: + map->formatter = formatter; + return JS_TRUE; +} + +JS_PUBLIC_API(void) +JS_RemoveArgumentFormatter(JSContext *cx, const char *format) +{ + size_t length; + JSArgumentFormatMap **mpp, *map; + + length = strlen(format); + mpp = &cx->argumentFormatMap; + while ((map = *mpp) != NULL) { + if (map->length == length && !strcmp(map->format, format)) { + *mpp = map->next; + JS_free(cx, map); + return; + } + mpp = &map->next; + } +} + +JS_PUBLIC_API(JSBool) +JS_ConvertValue(JSContext *cx, jsval v, JSType type, jsval *vp) +{ + JSBool ok, b; + JSObject *obj; + JSFunction *fun; + JSString *str; + jsdouble d, *dp; + + CHECK_REQUEST(cx); + switch (type) { + case JSTYPE_VOID: + *vp = JSVAL_VOID; + ok = JS_TRUE; + break; + case JSTYPE_OBJECT: + ok = js_ValueToObject(cx, v, &obj); + if (ok) + *vp = OBJECT_TO_JSVAL(obj); + break; + case JSTYPE_FUNCTION: + fun = js_ValueToFunction(cx, &v, JSV2F_SEARCH_STACK); + ok = (fun != NULL); + if (ok) + *vp = OBJECT_TO_JSVAL(fun->object); + break; + case JSTYPE_STRING: + str = js_ValueToString(cx, v); + ok = (str != NULL); + if (ok) + *vp = STRING_TO_JSVAL(str); + break; + case JSTYPE_NUMBER: + ok = js_ValueToNumber(cx, v, &d); + if (ok) { + dp = js_NewDouble(cx, d); + ok = (dp != NULL); + if (ok) + *vp = DOUBLE_TO_JSVAL(dp); + } + break; + case JSTYPE_BOOLEAN: + ok = js_ValueToBoolean(cx, v, &b); + if (ok) + *vp = BOOLEAN_TO_JSVAL(b); + break; + default: { + char numBuf[12]; + JS_snprintf(numBuf, sizeof numBuf, "%d", (int)type); + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BAD_TYPE, + numBuf); + ok = JS_FALSE; + break; + } + } + return ok; +} + +JS_PUBLIC_API(JSBool) +JS_ValueToObject(JSContext *cx, jsval v, JSObject **objp) +{ + CHECK_REQUEST(cx); + return js_ValueToObject(cx, v, objp); +} + +JS_PUBLIC_API(JSFunction *) +JS_ValueToFunction(JSContext *cx, jsval v) +{ + CHECK_REQUEST(cx); + return js_ValueToFunction(cx, &v, JSV2F_SEARCH_STACK); +} + +JS_PUBLIC_API(JSFunction *) +JS_ValueToConstructor(JSContext *cx, jsval v) +{ + CHECK_REQUEST(cx); + return js_ValueToFunction(cx, &v, JSV2F_SEARCH_STACK); +} + +JS_PUBLIC_API(JSString *) +JS_ValueToString(JSContext *cx, jsval v) +{ + CHECK_REQUEST(cx); + return js_ValueToString(cx, v); +} + +JS_PUBLIC_API(JSBool) +JS_ValueToNumber(JSContext *cx, jsval v, jsdouble *dp) +{ + CHECK_REQUEST(cx); + return js_ValueToNumber(cx, v, dp); +} + +JS_PUBLIC_API(JSBool) +JS_ValueToECMAInt32(JSContext *cx, jsval v, int32 *ip) +{ + CHECK_REQUEST(cx); + return js_ValueToECMAInt32(cx, v, ip); +} + +JS_PUBLIC_API(JSBool) +JS_ValueToECMAUint32(JSContext *cx, jsval v, uint32 *ip) +{ + CHECK_REQUEST(cx); + return js_ValueToECMAUint32(cx, v, ip); +} + +JS_PUBLIC_API(JSBool) +JS_ValueToInt32(JSContext *cx, jsval v, int32 *ip) +{ + CHECK_REQUEST(cx); + return js_ValueToInt32(cx, v, ip); +} + +JS_PUBLIC_API(JSBool) +JS_ValueToUint16(JSContext *cx, jsval v, uint16 *ip) +{ + CHECK_REQUEST(cx); + return js_ValueToUint16(cx, v, ip); +} + +JS_PUBLIC_API(JSBool) +JS_ValueToBoolean(JSContext *cx, jsval v, JSBool *bp) +{ + CHECK_REQUEST(cx); + return js_ValueToBoolean(cx, v, bp); +} + +JS_PUBLIC_API(JSType) +JS_TypeOfValue(JSContext *cx, jsval v) +{ + JSType type; + JSObject *obj; + JSObjectOps *ops; + JSClass *clasp; + + CHECK_REQUEST(cx); + if (JSVAL_IS_OBJECT(v)) { + /* XXX JSVAL_IS_OBJECT(v) is true for null too! Can we change ECMA? */ + obj = JSVAL_TO_OBJECT(v); + if (obj && + (ops = obj->map->ops, + ops == &js_ObjectOps + ? (clasp = OBJ_GET_CLASS(cx, obj), + clasp->call || clasp == &js_FunctionClass) + : ops->call != 0)) { + type = JSTYPE_FUNCTION; + } else { + type = JSTYPE_OBJECT; + } + } else if (JSVAL_IS_NUMBER(v)) { + type = JSTYPE_NUMBER; + } else if (JSVAL_IS_STRING(v)) { + type = JSTYPE_STRING; + } else if (JSVAL_IS_BOOLEAN(v)) { + type = JSTYPE_BOOLEAN; + } else { + type = JSTYPE_VOID; + } + return type; +} + +JS_PUBLIC_API(const char *) +JS_GetTypeName(JSContext *cx, JSType type) +{ + if ((uintN)type >= (uintN)JSTYPE_LIMIT) + return NULL; + return js_type_str[type]; +} + +/************************************************************************/ + +JS_PUBLIC_API(JSRuntime *) +JS_NewRuntime(uint32 maxbytes) +{ + JSRuntime *rt; + +#ifdef DEBUG + JS_BEGIN_MACRO + /* + * This code asserts that the numbers associated with the error names in + * jsmsg.def are monotonically increasing. It uses values for the error + * names enumerated in jscntxt.c. It's not a compiletime check, but it's + * better than nothing. + */ + int errorNumber = 0; +#define MSG_DEF(name, number, count, exception, format) \ + JS_ASSERT(name == errorNumber++); +#include "js.msg" +#undef MSG_DEF + JS_END_MACRO; +#endif /* DEBUG */ + + if (!js_InitScriptGlobals()) + return NULL; + if (!js_InitStringGlobals()) + return NULL; + rt = (JSRuntime *) malloc(sizeof(JSRuntime)); + if (!rt) + return NULL; + + /* Initialize infallibly first, so we can goto bad and JS_DestroyRuntime. */ + memset(rt, 0, sizeof(JSRuntime)); + JS_INIT_CLIST(&rt->contextList); + JS_INIT_CLIST(&rt->trapList); + JS_INIT_CLIST(&rt->watchPointList); + + if (!js_InitGC(rt, maxbytes)) + goto bad; +#ifdef JS_THREADSAFE + rt->gcLock = JS_NEW_LOCK(); + if (!rt->gcLock) + goto bad; + rt->gcDone = JS_NEW_CONDVAR(rt->gcLock); + if (!rt->gcDone) + goto bad; + rt->requestDone = JS_NEW_CONDVAR(rt->gcLock); + if (!rt->requestDone) + goto bad; + js_SetupLocks(8, 16); /* this is asymmetric with JS_ShutDown. */ + rt->rtLock = JS_NEW_LOCK(); + if (!rt->rtLock) + goto bad; + rt->stateChange = JS_NEW_CONDVAR(rt->gcLock); + if (!rt->stateChange) + goto bad; + rt->setSlotLock = JS_NEW_LOCK(); + if (!rt->setSlotLock) + goto bad; + rt->setSlotDone = JS_NEW_CONDVAR(rt->setSlotLock); + if (!rt->setSlotDone) + goto bad; + rt->scopeSharingDone = JS_NEW_CONDVAR(rt->gcLock); + if (!rt->scopeSharingDone) + goto bad; + rt->scopeSharingTodo = NO_SCOPE_SHARING_TODO; +#endif + rt->propertyCache.empty = JS_TRUE; + if (!js_InitPropertyTree(rt)) + goto bad; + return rt; + +bad: + JS_DestroyRuntime(rt); + return NULL; +} + +JS_PUBLIC_API(void) +JS_DestroyRuntime(JSRuntime *rt) +{ +#ifdef DEBUG + /* Don't hurt everyone in leaky ol' Mozilla with a fatal JS_ASSERT! */ + if (!JS_CLIST_IS_EMPTY(&rt->contextList)) { + JSContext *cx, *iter = NULL; + uintN cxcount = 0; + while ((cx = js_ContextIterator(rt, JS_TRUE, &iter)) != NULL) + cxcount++; + fprintf(stderr, +"JS API usage error: %u contexts left in runtime upon JS_DestroyRuntime.\n", + cxcount); + } +#endif + + js_FinishAtomState(&rt->atomState); + js_FinishGC(rt); +#ifdef JS_THREADSAFE + if (rt->gcLock) + JS_DESTROY_LOCK(rt->gcLock); + if (rt->gcDone) + JS_DESTROY_CONDVAR(rt->gcDone); + if (rt->requestDone) + JS_DESTROY_CONDVAR(rt->requestDone); + if (rt->rtLock) + JS_DESTROY_LOCK(rt->rtLock); + if (rt->stateChange) + JS_DESTROY_CONDVAR(rt->stateChange); + if (rt->setSlotLock) + JS_DESTROY_LOCK(rt->setSlotLock); + if (rt->setSlotDone) + JS_DESTROY_CONDVAR(rt->setSlotDone); + if (rt->scopeSharingDone) + JS_DESTROY_CONDVAR(rt->scopeSharingDone); +#endif + js_FinishPropertyTree(rt); + free(rt); +} + +JS_PUBLIC_API(void) +JS_ShutDown(void) +{ + JS_ArenaShutDown(); + js_FinishDtoa(); + js_FreeScriptGlobals(); + js_FreeStringGlobals(); +#ifdef JS_THREADSAFE + js_CleanupLocks(); +#endif +} + +JS_PUBLIC_API(void *) +JS_GetRuntimePrivate(JSRuntime *rt) +{ + return rt->data; +} + +JS_PUBLIC_API(void) +JS_SetRuntimePrivate(JSRuntime *rt, void *data) +{ + rt->data = data; +} + +#ifdef JS_THREADSAFE + +JS_PUBLIC_API(void) +JS_BeginRequest(JSContext *cx) +{ + JSRuntime *rt; + + JS_ASSERT(cx->thread); + if (!cx->requestDepth) { + /* Wait until the GC is finished. */ + rt = cx->runtime; + JS_LOCK_GC(rt); + + /* NB: we use cx->thread here, not js_CurrentThreadId(). */ + if (rt->gcThread != cx->thread) { + while (rt->gcLevel > 0) + JS_AWAIT_GC_DONE(rt); + } + + /* Indicate that a request is running. */ + rt->requestCount++; + cx->requestDepth = 1; + JS_UNLOCK_GC(rt); + return; + } + cx->requestDepth++; +} + +JS_PUBLIC_API(void) +JS_EndRequest(JSContext *cx) +{ + JSRuntime *rt; + JSScope *scope, **todop; + uintN nshares; + + CHECK_REQUEST(cx); + JS_ASSERT(cx->requestDepth > 0); + if (cx->requestDepth == 1) { + /* Lock before clearing to interlock with ClaimScope, in jslock.c. */ + rt = cx->runtime; + JS_LOCK_GC(rt); + cx->requestDepth = 0; + + /* See whether cx has any single-threaded scopes to start sharing. */ + todop = &rt->scopeSharingTodo; + nshares = 0; + while ((scope = *todop) != NO_SCOPE_SHARING_TODO) { + if (scope->ownercx != cx) { + todop = &scope->u.link; + continue; + } + *todop = scope->u.link; + scope->u.link = NULL; /* null u.link for sanity ASAP */ + + /* + * If js_DropObjectMap returns null, we held the last ref to scope. + * The waiting thread(s) must have been killed, after which the GC + * collected the object that held this scope. Unlikely, because it + * requires that the GC ran (e.g., from a branch callback) during + * this request, but possible. + */ + if (js_DropObjectMap(cx, &scope->map, NULL)) { + js_InitLock(&scope->lock); + scope->u.count = 0; /* NULL may not pun as 0 */ + js_FinishSharingScope(rt, scope); /* set ownercx = NULL */ + nshares++; + } + } + if (nshares) + JS_NOTIFY_ALL_CONDVAR(rt->scopeSharingDone); + + /* Give the GC a chance to run if this was the last request running. */ + JS_ASSERT(rt->requestCount > 0); + rt->requestCount--; + if (rt->requestCount == 0) + JS_NOTIFY_REQUEST_DONE(rt); + + JS_UNLOCK_GC(rt); + return; + } + + cx->requestDepth--; +} + +/* Yield to pending GC operations, regardless of request depth */ +JS_PUBLIC_API(void) +JS_YieldRequest(JSContext *cx) +{ + JSRuntime *rt; + + JS_ASSERT(cx->thread); + CHECK_REQUEST(cx); + + rt = cx->runtime; + JS_LOCK_GC(rt); + JS_ASSERT(rt->requestCount > 0); + rt->requestCount--; + if (rt->requestCount == 0) + JS_NOTIFY_REQUEST_DONE(rt); + JS_UNLOCK_GC(rt); + /* XXXbe give the GC or another request calling it a chance to run here? + Assumes FIFO scheduling */ + JS_LOCK_GC(rt); + rt->requestCount++; + JS_UNLOCK_GC(rt); +} + +JS_PUBLIC_API(jsrefcount) +JS_SuspendRequest(JSContext *cx) +{ + jsrefcount saveDepth = cx->requestDepth; + + while (cx->requestDepth) + JS_EndRequest(cx); + return saveDepth; +} + +JS_PUBLIC_API(void) +JS_ResumeRequest(JSContext *cx, jsrefcount saveDepth) +{ + JS_ASSERT(!cx->requestDepth); + while (--saveDepth >= 0) + JS_BeginRequest(cx); +} + +#endif /* JS_THREADSAFE */ + +JS_PUBLIC_API(void) +JS_Lock(JSRuntime *rt) +{ + JS_LOCK_RUNTIME(rt); +} + +JS_PUBLIC_API(void) +JS_Unlock(JSRuntime *rt) +{ + JS_UNLOCK_RUNTIME(rt); +} + +JS_PUBLIC_API(JSContext *) +JS_NewContext(JSRuntime *rt, size_t stackChunkSize) +{ + return js_NewContext(rt, stackChunkSize); +} + +JS_PUBLIC_API(void) +JS_DestroyContext(JSContext *cx) +{ + js_DestroyContext(cx, JS_FORCE_GC); +} + +JS_PUBLIC_API(void) +JS_DestroyContextNoGC(JSContext *cx) +{ + js_DestroyContext(cx, JS_NO_GC); +} + +JS_PUBLIC_API(void) +JS_DestroyContextMaybeGC(JSContext *cx) +{ + js_DestroyContext(cx, JS_MAYBE_GC); +} + +JS_PUBLIC_API(void *) +JS_GetContextPrivate(JSContext *cx) +{ + return cx->data; +} + +JS_PUBLIC_API(void) +JS_SetContextPrivate(JSContext *cx, void *data) +{ + cx->data = data; +} + +JS_PUBLIC_API(JSRuntime *) +JS_GetRuntime(JSContext *cx) +{ + return cx->runtime; +} + +JS_PUBLIC_API(JSContext *) +JS_ContextIterator(JSRuntime *rt, JSContext **iterp) +{ + return js_ContextIterator(rt, JS_TRUE, iterp); +} + +JS_PUBLIC_API(JSVersion) +JS_GetVersion(JSContext *cx) +{ + return cx->version; +} + +JS_PUBLIC_API(JSVersion) +JS_SetVersion(JSContext *cx, JSVersion version) +{ + JSVersion oldVersion; + + oldVersion = cx->version; + if (version == oldVersion) + return oldVersion; + + cx->version = version; + +#if !JS_BUG_FALLIBLE_EQOPS + if (cx->version == JSVERSION_1_2) { + cx->jsop_eq = JSOP_NEW_EQ; + cx->jsop_ne = JSOP_NEW_NE; + } else { + cx->jsop_eq = JSOP_EQ; + cx->jsop_ne = JSOP_NE; + } +#endif /* !JS_BUG_FALLIBLE_EQOPS */ + + return oldVersion; +} + +static struct v2smap { + JSVersion version; + const char *string; +} v2smap[] = { + {JSVERSION_1_0, "1.0"}, + {JSVERSION_1_1, "1.1"}, + {JSVERSION_1_2, "1.2"}, + {JSVERSION_1_3, "1.3"}, + {JSVERSION_1_4, "1.4"}, + {JSVERSION_ECMA_3, "ECMAv3"}, + {JSVERSION_1_5, "1.5"}, + {JSVERSION_DEFAULT, "default"}, + {JSVERSION_UNKNOWN, NULL}, /* must be last, NULL is sentinel */ +}; + +JS_PUBLIC_API(const char *) +JS_VersionToString(JSVersion version) +{ + int i; + + for (i = 0; v2smap[i].string; i++) + if (v2smap[i].version == version) + return v2smap[i].string; + return "unknown"; +} + +JS_PUBLIC_API(JSVersion) +JS_StringToVersion(const char *string) +{ + int i; + + for (i = 0; v2smap[i].string; i++) + if (strcmp(v2smap[i].string, string) == 0) + return v2smap[i].version; + return JSVERSION_UNKNOWN; +} + +JS_PUBLIC_API(uint32) +JS_GetOptions(JSContext *cx) +{ + return cx->options; +} + +JS_PUBLIC_API(uint32) +JS_SetOptions(JSContext *cx, uint32 options) +{ + uint32 oldopts = cx->options; + cx->options = options; + return oldopts; +} + +JS_PUBLIC_API(uint32) +JS_ToggleOptions(JSContext *cx, uint32 options) +{ + uint32 oldopts = cx->options; + cx->options ^= options; + return oldopts; +} + +JS_PUBLIC_API(const char *) +JS_GetImplementationVersion(void) +{ + return "JavaScript-C 1.5 pre-release 6 2004-01-27"; +} + + +JS_PUBLIC_API(JSObject *) +JS_GetGlobalObject(JSContext *cx) +{ + return cx->globalObject; +} + +JS_PUBLIC_API(void) +JS_SetGlobalObject(JSContext *cx, JSObject *obj) +{ + cx->globalObject = obj; +} + +static JSObject * +InitFunctionAndObjectClasses(JSContext *cx, JSObject *obj) +{ + JSDHashTable *table; + JSBool resolving; + JSRuntime *rt; + JSResolvingKey key; + JSResolvingEntry *entry; + JSObject *fun_proto, *obj_proto; + + /* If cx has no global object, use obj so prototypes can be found. */ + if (!cx->globalObject) + cx->globalObject = obj; + + /* Record Function and Object in cx->resolvingTable, if we are resolving. */ + table = cx->resolvingTable; + resolving = (table && table->entryCount); + if (resolving) { + rt = cx->runtime; + key.obj = obj; + key.id = (jsid) rt->atomState.FunctionAtom; + entry = (JSResolvingEntry *) + JS_DHashTableOperate(table, &key, JS_DHASH_ADD); + if (entry && entry->key.obj && (entry->flags & JSRESFLAG_LOOKUP)) { + /* Already resolving Function, record Object too. */ + JS_ASSERT(entry->key.obj == obj); + key.id = (jsid) rt->atomState.ObjectAtom; + entry = (JSResolvingEntry *) + JS_DHashTableOperate(table, &key, JS_DHASH_ADD); + } + if (!entry) { + JS_ReportOutOfMemory(cx); + return NULL; + } + JS_ASSERT(!entry->key.obj && entry->flags == 0); + entry->key = key; + entry->flags = JSRESFLAG_LOOKUP; + } + + /* Initialize the function class first so constructors can be made. */ + fun_proto = js_InitFunctionClass(cx, obj); + if (!fun_proto) + goto out; + + /* Initialize the object class next so Object.prototype works. */ + obj_proto = js_InitObjectClass(cx, obj); + if (!obj_proto) { + fun_proto = NULL; + goto out; + } + + /* Function.prototype and the global object delegate to Object.prototype. */ + OBJ_SET_PROTO(cx, fun_proto, obj_proto); + if (!OBJ_GET_PROTO(cx, obj)) + OBJ_SET_PROTO(cx, obj, obj_proto); + +out: + /* If resolving, remove the other entry (Object or Function) from table. */ + if (resolving) + JS_DHashTableOperate(table, &key, JS_DHASH_REMOVE); + return fun_proto; +} + +JS_PUBLIC_API(JSBool) +JS_InitStandardClasses(JSContext *cx, JSObject *obj) +{ + CHECK_REQUEST(cx); + +#if JS_HAS_UNDEFINED +{ + /* Define a top-level property 'undefined' with the undefined value. */ + JSAtom *atom = cx->runtime->atomState.typeAtoms[JSTYPE_VOID]; + if (!OBJ_DEFINE_PROPERTY(cx, obj, (jsid)atom, JSVAL_VOID, NULL, NULL, + JSPROP_PERMANENT, NULL)) { + return JS_FALSE; + } +} +#endif + + /* Function and Object require cooperative bootstrapping magic. */ + if (!InitFunctionAndObjectClasses(cx, obj)) + return JS_FALSE; + + /* Initialize the rest of the standard objects and functions. */ + return js_InitArrayClass(cx, obj) && + js_InitBooleanClass(cx, obj) && + js_InitMathClass(cx, obj) && + js_InitNumberClass(cx, obj) && + js_InitStringClass(cx, obj) && +#if JS_HAS_CALL_OBJECT + js_InitCallClass(cx, obj) && +#endif +#if JS_HAS_REGEXPS + js_InitRegExpClass(cx, obj) && +#endif +#if JS_HAS_SCRIPT_OBJECT + js_InitScriptClass(cx, obj) && +#endif +#if JS_HAS_ERROR_EXCEPTIONS + js_InitExceptionClasses(cx, obj) && +#endif +#if JS_HAS_FILE_OBJECT + js_InitFileClass(cx, obj, JS_TRUE) && +#endif + js_InitDateClass(cx, obj); +} + +#define ATOM_OFFSET(name) offsetof(JSAtomState, name##Atom) +#define OFFSET_TO_ATOM(rt,off) (*(JSAtom **)((char*)&(rt)->atomState + (off))) + +/* + * Table of class initializers and their atom offsets in rt->atomState. + * If you add a "standard" class, remember to update this table. + */ +static struct { + JSObjectOp init; + size_t atomOffset; +} standard_class_atoms[] = { + {InitFunctionAndObjectClasses, ATOM_OFFSET(Function)}, + {InitFunctionAndObjectClasses, ATOM_OFFSET(Object)}, + {js_InitArrayClass, ATOM_OFFSET(Array)}, + {js_InitBooleanClass, ATOM_OFFSET(Boolean)}, + {js_InitDateClass, ATOM_OFFSET(Date)}, + {js_InitMathClass, ATOM_OFFSET(Math)}, + {js_InitNumberClass, ATOM_OFFSET(Number)}, + {js_InitStringClass, ATOM_OFFSET(String)}, +#if JS_HAS_CALL_OBJECT + {js_InitCallClass, ATOM_OFFSET(Call)}, +#endif +#if JS_HAS_ERROR_EXCEPTIONS + {js_InitExceptionClasses, ATOM_OFFSET(Error)}, +#endif +#if JS_HAS_REGEXPS + {js_InitRegExpClass, ATOM_OFFSET(RegExp)}, +#endif +#if JS_HAS_SCRIPT_OBJECT + {js_InitScriptClass, ATOM_OFFSET(Script)}, +#endif + {NULL, 0} +}; + +/* + * Table of top-level function and constant names and their init functions. + * If you add a "standard" global function or property, remember to update + * this table. + */ +typedef struct JSStdName { + JSObjectOp init; + size_t atomOffset; /* offset of atom pointer in JSAtomState */ + const char *name; /* null if atom is pre-pinned, else name */ +} JSStdName; + +static JSAtom * +StdNameToAtom(JSContext *cx, JSStdName *stdn) +{ + size_t offset; + JSAtom *atom; + const char *name; + + offset = stdn->atomOffset; + atom = OFFSET_TO_ATOM(cx->runtime, offset); + if (!atom) { + name = stdn->name; + if (name) { + atom = js_Atomize(cx, name, strlen(name), ATOM_PINNED); + OFFSET_TO_ATOM(cx->runtime, offset) = atom; + } + } + return atom; +} + +#define EAGERLY_PINNED_ATOM(name) ATOM_OFFSET(name), NULL +#define LAZILY_PINNED_ATOM(name) ATOM_OFFSET(lazy.name), js_##name##_str + +static JSStdName standard_class_names[] = { + /* ECMA requires that eval be a direct property of the global object. */ + {js_InitObjectClass, EAGERLY_PINNED_ATOM(eval)}, + + /* Global properties and functions defined by the Number class. */ + {js_InitNumberClass, LAZILY_PINNED_ATOM(NaN)}, + {js_InitNumberClass, LAZILY_PINNED_ATOM(Infinity)}, + {js_InitNumberClass, LAZILY_PINNED_ATOM(isNaN)}, + {js_InitNumberClass, LAZILY_PINNED_ATOM(isFinite)}, + {js_InitNumberClass, LAZILY_PINNED_ATOM(parseFloat)}, + {js_InitNumberClass, LAZILY_PINNED_ATOM(parseInt)}, + + /* String global functions. */ + {js_InitStringClass, LAZILY_PINNED_ATOM(escape)}, + {js_InitStringClass, LAZILY_PINNED_ATOM(unescape)}, + {js_InitStringClass, LAZILY_PINNED_ATOM(decodeURI)}, + {js_InitStringClass, LAZILY_PINNED_ATOM(encodeURI)}, + {js_InitStringClass, LAZILY_PINNED_ATOM(decodeURIComponent)}, + {js_InitStringClass, LAZILY_PINNED_ATOM(encodeURIComponent)}, +#if JS_HAS_UNEVAL + {js_InitStringClass, LAZILY_PINNED_ATOM(uneval)}, +#endif + + /* Exception constructors. */ +#if JS_HAS_ERROR_EXCEPTIONS + {js_InitExceptionClasses, EAGERLY_PINNED_ATOM(Error)}, + {js_InitExceptionClasses, LAZILY_PINNED_ATOM(InternalError)}, + {js_InitExceptionClasses, LAZILY_PINNED_ATOM(EvalError)}, + {js_InitExceptionClasses, LAZILY_PINNED_ATOM(RangeError)}, + {js_InitExceptionClasses, LAZILY_PINNED_ATOM(ReferenceError)}, + {js_InitExceptionClasses, LAZILY_PINNED_ATOM(SyntaxError)}, + {js_InitExceptionClasses, LAZILY_PINNED_ATOM(TypeError)}, + {js_InitExceptionClasses, LAZILY_PINNED_ATOM(URIError)}, +#endif + + {NULL, 0, NULL} +}; + +static JSStdName object_prototype_names[] = { + /* Object.prototype properties (global delegates to Object.prototype). */ + {js_InitObjectClass, EAGERLY_PINNED_ATOM(proto)}, + {js_InitObjectClass, EAGERLY_PINNED_ATOM(parent)}, + {js_InitObjectClass, EAGERLY_PINNED_ATOM(count)}, +#if JS_HAS_TOSOURCE + {js_InitObjectClass, EAGERLY_PINNED_ATOM(toSource)}, +#endif + {js_InitObjectClass, EAGERLY_PINNED_ATOM(toString)}, + {js_InitObjectClass, EAGERLY_PINNED_ATOM(toLocaleString)}, + {js_InitObjectClass, EAGERLY_PINNED_ATOM(valueOf)}, +#if JS_HAS_OBJ_WATCHPOINT + {js_InitObjectClass, LAZILY_PINNED_ATOM(watch)}, + {js_InitObjectClass, LAZILY_PINNED_ATOM(unwatch)}, +#endif +#if JS_HAS_NEW_OBJ_METHODS + {js_InitObjectClass, LAZILY_PINNED_ATOM(hasOwnProperty)}, + {js_InitObjectClass, LAZILY_PINNED_ATOM(isPrototypeOf)}, + {js_InitObjectClass, LAZILY_PINNED_ATOM(propertyIsEnumerable)}, +#endif +#if JS_HAS_GETTER_SETTER + {js_InitObjectClass, LAZILY_PINNED_ATOM(defineGetter)}, + {js_InitObjectClass, LAZILY_PINNED_ATOM(defineSetter)}, + {js_InitObjectClass, LAZILY_PINNED_ATOM(lookupGetter)}, + {js_InitObjectClass, LAZILY_PINNED_ATOM(lookupSetter)}, +#endif + + {NULL, 0, NULL} +}; + +#undef EAGERLY_PINNED_ATOM +#undef LAZILY_PINNED_ATOM + +JS_PUBLIC_API(JSBool) +JS_ResolveStandardClass(JSContext *cx, JSObject *obj, jsval id, + JSBool *resolved) +{ + JSString *idstr; + JSRuntime *rt; + JSAtom *atom; + JSObjectOp init; + uintN i; + + CHECK_REQUEST(cx); + *resolved = JS_FALSE; + + if (!JSVAL_IS_STRING(id)) + return JS_TRUE; + idstr = JSVAL_TO_STRING(id); + rt = cx->runtime; + +#if JS_HAS_UNDEFINED + /* See if we're resolving 'undefined', and define it if so. */ + atom = rt->atomState.typeAtoms[JSTYPE_VOID]; + if (idstr == ATOM_TO_STRING(atom)) { + *resolved = JS_TRUE; + return OBJ_DEFINE_PROPERTY(cx, obj, (jsid)atom, JSVAL_VOID, NULL, NULL, + JSPROP_PERMANENT, NULL); + } +#endif + + /* Try for class constructors/prototypes named by well-known atoms. */ + init = NULL; + for (i = 0; standard_class_atoms[i].init; i++) { + atom = OFFSET_TO_ATOM(rt, standard_class_atoms[i].atomOffset); + if (idstr == ATOM_TO_STRING(atom)) { + init = standard_class_atoms[i].init; + break; + } + } + + if (!init) { + /* Try less frequently used top-level functions and constants. */ + for (i = 0; standard_class_names[i].init; i++) { + atom = StdNameToAtom(cx, &standard_class_names[i]); + if (!atom) + return JS_FALSE; + if (idstr == ATOM_TO_STRING(atom)) { + init = standard_class_names[i].init; + break; + } + } + + if (!init && !OBJ_GET_PROTO(cx, obj)) { + /* + * Try even less frequently used names delegated from the global + * object to Object.prototype, but only if the Object class hasn't + * yet been initialized. + */ + for (i = 0; object_prototype_names[i].init; i++) { + atom = StdNameToAtom(cx, &object_prototype_names[i]); + if (!atom) + return JS_FALSE; + if (idstr == ATOM_TO_STRING(atom)) { + init = standard_class_names[i].init; + break; + } + } + } + } + + if (init) { + if (!init(cx, obj)) + return JS_FALSE; + *resolved = JS_TRUE; + } + return JS_TRUE; +} + +static JSBool +HasOwnProperty(JSContext *cx, JSObject *obj, JSAtom *atom, JSBool *ownp) +{ + JSObject *pobj; + JSProperty *prop; + + if (!OBJ_LOOKUP_PROPERTY(cx, obj, (jsid)atom, &pobj, &prop)) + return JS_FALSE; + if (prop) + OBJ_DROP_PROPERTY(cx, pobj, prop); + *ownp = (pobj == obj && prop); + return JS_TRUE; +} + +JS_PUBLIC_API(JSBool) +JS_EnumerateStandardClasses(JSContext *cx, JSObject *obj) +{ + JSRuntime *rt; + JSAtom *atom; + JSBool found; + uintN i; + + CHECK_REQUEST(cx); + rt = cx->runtime; + +#if JS_HAS_UNDEFINED + /* See if we need to bind 'undefined' and define it if so. */ + atom = rt->atomState.typeAtoms[JSTYPE_VOID]; + if (!HasOwnProperty(cx, obj, atom, &found)) + return JS_FALSE; + if (!found && + !OBJ_DEFINE_PROPERTY(cx, obj, (jsid)atom, JSVAL_VOID, NULL, NULL, + JSPROP_PERMANENT, NULL)) { + return JS_FALSE; + } +#endif + + /* Initialize any classes that have not been resolved yet. */ + for (i = 0; standard_class_atoms[i].init; i++) { + atom = OFFSET_TO_ATOM(rt, standard_class_atoms[i].atomOffset); + if (!HasOwnProperty(cx, obj, atom, &found)) + return JS_FALSE; + if (!found && !standard_class_atoms[i].init(cx, obj)) + return JS_FALSE; + } + + return JS_TRUE; +} + +#undef ATOM_OFFSET +#undef OFFSET_TO_ATOM + +JS_PUBLIC_API(JSObject *) +JS_GetScopeChain(JSContext *cx) +{ + return cx->fp ? cx->fp->scopeChain : NULL; +} + +JS_PUBLIC_API(void *) +JS_malloc(JSContext *cx, size_t nbytes) +{ + void *p; + + JS_ASSERT(nbytes != 0); + if (nbytes == 0) + nbytes = 1; + cx->runtime->gcMallocBytes += nbytes; + p = malloc(nbytes); + if (!p) + JS_ReportOutOfMemory(cx); + return p; +} + +JS_PUBLIC_API(void *) +JS_realloc(JSContext *cx, void *p, size_t nbytes) +{ + p = realloc(p, nbytes); + if (!p) + JS_ReportOutOfMemory(cx); + return p; +} + +JS_PUBLIC_API(void) +JS_free(JSContext *cx, void *p) +{ + if (p) + free(p); +} + +JS_PUBLIC_API(char *) +JS_strdup(JSContext *cx, const char *s) +{ + size_t n; + void *p; + + n = strlen(s) + 1; + p = JS_malloc(cx, n); + if (!p) + return NULL; + return (char *)memcpy(p, s, n); +} + +JS_PUBLIC_API(jsdouble *) +JS_NewDouble(JSContext *cx, jsdouble d) +{ + CHECK_REQUEST(cx); + return js_NewDouble(cx, d); +} + +JS_PUBLIC_API(JSBool) +JS_NewDoubleValue(JSContext *cx, jsdouble d, jsval *rval) +{ + CHECK_REQUEST(cx); + return js_NewDoubleValue(cx, d, rval); +} + +JS_PUBLIC_API(JSBool) +JS_NewNumberValue(JSContext *cx, jsdouble d, jsval *rval) +{ + CHECK_REQUEST(cx); + return js_NewNumberValue(cx, d, rval); +} + +#undef JS_AddRoot +JS_PUBLIC_API(JSBool) +JS_AddRoot(JSContext *cx, void *rp) +{ + CHECK_REQUEST(cx); + return js_AddRoot(cx, rp, NULL); +} + +JS_PUBLIC_API(JSBool) +JS_AddNamedRootRT(JSRuntime *rt, void *rp, const char *name) +{ + return js_AddRootRT(rt, rp, name); +} + +JS_PUBLIC_API(JSBool) +JS_RemoveRoot(JSContext *cx, void *rp) +{ + CHECK_REQUEST(cx); + return js_RemoveRoot(cx->runtime, rp); +} + +JS_PUBLIC_API(JSBool) +JS_RemoveRootRT(JSRuntime *rt, void *rp) +{ + return js_RemoveRoot(rt, rp); +} + +JS_PUBLIC_API(JSBool) +JS_AddNamedRoot(JSContext *cx, void *rp, const char *name) +{ + CHECK_REQUEST(cx); + return js_AddRoot(cx, rp, name); +} + +JS_PUBLIC_API(void) +JS_ClearNewbornRoots(JSContext *cx) +{ + uintN i; + + for (i = 0; i < GCX_NTYPES; i++) + cx->newborn[i] = NULL; + cx->lastAtom = NULL; +} + +#include "jshash.h" /* Added by JSIFY */ + +#ifdef DEBUG + +typedef struct NamedRootDumpArgs { + void (*dump)(const char *name, void *rp, void *data); + void *data; +} NamedRootDumpArgs; + +JS_STATIC_DLL_CALLBACK(JSDHashOperator) +js_named_root_dumper(JSDHashTable *table, JSDHashEntryHdr *hdr, uint32 number, + void *arg) +{ + NamedRootDumpArgs *args = (NamedRootDumpArgs *) arg; + JSGCRootHashEntry *rhe = (JSGCRootHashEntry *)hdr; + + if (rhe->name) + args->dump(rhe->name, rhe->root, args->data); + return JS_DHASH_NEXT; +} + +JS_PUBLIC_API(void) +JS_DumpNamedRoots(JSRuntime *rt, + void (*dump)(const char *name, void *rp, void *data), + void *data) +{ + NamedRootDumpArgs args; + + args.dump = dump; + args.data = data; + JS_DHashTableEnumerate(&rt->gcRootsHash, js_named_root_dumper, &args); +} + +#endif /* DEBUG */ + +typedef struct GCRootMapArgs { + JSGCRootMapFun map; + void *data; +} GCRootMapArgs; + +JS_STATIC_DLL_CALLBACK(JSDHashOperator) +js_gcroot_mapper(JSDHashTable *table, JSDHashEntryHdr *hdr, uint32 number, + void *arg) +{ + GCRootMapArgs *args = (GCRootMapArgs *) arg; + JSGCRootHashEntry *rhe = (JSGCRootHashEntry *)hdr; + intN mapflags; + JSDHashOperator op; + + mapflags = args->map(rhe->root, rhe->name, args->data); + +#if JS_MAP_GCROOT_NEXT == JS_DHASH_NEXT && \ + JS_MAP_GCROOT_STOP == JS_DHASH_STOP && \ + JS_MAP_GCROOT_REMOVE == JS_DHASH_REMOVE + op = (JSDHashOperator)mapflags; +#else + op = JS_DHASH_NEXT; + if (mapflags & JS_MAP_GCROOT_STOP) + op |= JS_DHASH_STOP; + if (mapflags & JS_MAP_GCROOT_REMOVE) + op |= JS_DHASH_REMOVE; +#endif + + return op; +} + +JS_PUBLIC_API(uint32) +JS_MapGCRoots(JSRuntime *rt, JSGCRootMapFun map, void *data) +{ + GCRootMapArgs args; + uint32 rv; + + args.map = map; + args.data = data; + JS_LOCK_GC(rt); + rv = JS_DHashTableEnumerate(&rt->gcRootsHash, js_gcroot_mapper, &args); + JS_UNLOCK_GC(rt); + return rv; +} + +JS_PUBLIC_API(JSBool) +JS_LockGCThing(JSContext *cx, void *thing) +{ + JSBool ok; + + CHECK_REQUEST(cx); + ok = js_LockGCThing(cx, thing); + if (!ok) + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_LOCK); + return ok; +} + +JS_PUBLIC_API(JSBool) +JS_LockGCThingRT(JSRuntime *rt, void *thing) +{ + return js_LockGCThingRT(rt, thing); +} + +JS_PUBLIC_API(JSBool) +JS_UnlockGCThing(JSContext *cx, void *thing) +{ + JSBool ok; + + CHECK_REQUEST(cx); + ok = js_UnlockGCThingRT(cx->runtime, thing); + if (!ok) + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_UNLOCK); + return ok; +} + +JS_PUBLIC_API(JSBool) +JS_UnlockGCThingRT(JSRuntime *rt, void *thing) +{ + return js_UnlockGCThingRT(rt, thing); +} + +JS_PUBLIC_API(void) +JS_MarkGCThing(JSContext *cx, void *thing, const char *name, void *arg) +{ + JS_ASSERT(cx->runtime->gcLevel > 0); +#ifdef JS_THREADSAFE + JS_ASSERT(cx->runtime->gcThread == js_CurrentThreadId()); +#endif + + GC_MARK(cx, thing, name, arg); +} + +JS_PUBLIC_API(void) +JS_GC(JSContext *cx) +{ + /* Don't nuke active arenas if executing or compiling. */ + if (cx->stackPool.current == &cx->stackPool.first) + JS_FinishArenaPool(&cx->stackPool); + if (cx->tempPool.current == &cx->tempPool.first) + JS_FinishArenaPool(&cx->tempPool); + js_ForceGC(cx, 0); +} + +JS_PUBLIC_API(void) +JS_MaybeGC(JSContext *cx) +{ + JSRuntime *rt; + uint32 bytes, lastBytes; + + rt = cx->runtime; + bytes = rt->gcBytes; + lastBytes = rt->gcLastBytes; + if ((bytes > 8192 && bytes > lastBytes + lastBytes / 2) || + rt->gcMallocBytes > rt->gcMaxBytes) { + /* + * Run the GC if we have half again as many bytes of GC-things as + * the last time we GC'd, or if we have malloc'd more bytes through + * JS_malloc than we were told to allocate by JS_NewRuntime. + */ + JS_GC(cx); + } +} + +JS_PUBLIC_API(JSGCCallback) +JS_SetGCCallback(JSContext *cx, JSGCCallback cb) +{ + return JS_SetGCCallbackRT(cx->runtime, cb); +} + +JS_PUBLIC_API(JSGCCallback) +JS_SetGCCallbackRT(JSRuntime *rt, JSGCCallback cb) +{ + JSGCCallback oldcb; + + oldcb = rt->gcCallback; + rt->gcCallback = cb; + return oldcb; +} + +JS_PUBLIC_API(JSBool) +JS_IsAboutToBeFinalized(JSContext *cx, void *thing) +{ + JS_ASSERT(thing); + return js_IsAboutToBeFinalized(cx, thing); +} + +JS_PUBLIC_API(intN) +JS_AddExternalStringFinalizer(JSStringFinalizeOp finalizer) +{ + return js_ChangeExternalStringFinalizer(NULL, finalizer); +} + +JS_PUBLIC_API(intN) +JS_RemoveExternalStringFinalizer(JSStringFinalizeOp finalizer) +{ + return js_ChangeExternalStringFinalizer(finalizer, NULL); +} + +JS_PUBLIC_API(JSString *) +JS_NewExternalString(JSContext *cx, jschar *chars, size_t length, intN type) +{ + JSString *str; + + CHECK_REQUEST(cx); + JS_ASSERT(GCX_EXTERNAL_STRING <= type && type < (intN) GCX_NTYPES); + + str = (JSString *) js_AllocGCThing(cx, (uintN) type); + if (!str) + return NULL; + str->length = length; + str->chars = chars; + return str; +} + +JS_PUBLIC_API(intN) +JS_GetExternalStringGCType(JSRuntime *rt, JSString *str) +{ + uint8 type = (uint8) (*js_GetGCThingFlags(str) & GCF_TYPEMASK); + + if (type >= GCX_EXTERNAL_STRING) + return (intN)type; + JS_ASSERT(type == GCX_STRING || type == GCX_MUTABLE_STRING); + return -1; +} + +#ifdef DEBUG +static void +CheckStackGrowthDirection(int *dummy1addr, jsuword limitAddr) +{ + int dummy2; + +#if JS_STACK_GROWTH_DIRECTION > 0 + JS_ASSERT(dummy1addr < &dummy2); + JS_ASSERT((jsuword)&dummy2 < limitAddr); +#else + /* Stack grows downward, the common case on modern architectures. */ + JS_ASSERT(&dummy2 < dummy1addr); + JS_ASSERT(limitAddr < (jsuword)&dummy2); +#endif +} +#endif + +JS_PUBLIC_API(void) +JS_SetThreadStackLimit(JSContext *cx, jsuword limitAddr) +{ +#ifdef DEBUG + int dummy1; + + CheckStackGrowthDirection(&dummy1, limitAddr); +#endif + +#if JS_STACK_GROWTH_DIRECTION > 0 + if (limitAddr == 0) + limitAddr = (jsuword)-1; +#endif + cx->stackLimit = limitAddr; +} + +/************************************************************************/ + +JS_PUBLIC_API(void) +JS_DestroyIdArray(JSContext *cx, JSIdArray *ida) +{ + JS_free(cx, ida); +} + +JS_PUBLIC_API(JSBool) +JS_ValueToId(JSContext *cx, jsval v, jsid *idp) +{ + JSAtom *atom; + + CHECK_REQUEST(cx); + if (JSVAL_IS_INT(v)) { + *idp = v; + } else { + atom = js_ValueToStringAtom(cx, v); + if (!atom) + return JS_FALSE; + *idp = (jsid)atom; + } + return JS_TRUE; +} + +JS_PUBLIC_API(JSBool) +JS_IdToValue(JSContext *cx, jsid id, jsval *vp) +{ + CHECK_REQUEST(cx); + *vp = ID_TO_VALUE(id); + return JS_TRUE; +} + +JS_PUBLIC_API(JSBool) +JS_PropertyStub(JSContext *cx, JSObject *obj, jsval id, jsval *vp) +{ + return JS_TRUE; +} + +JS_PUBLIC_API(JSBool) +JS_EnumerateStub(JSContext *cx, JSObject *obj) +{ + return JS_TRUE; +} + +JS_PUBLIC_API(JSBool) +JS_ResolveStub(JSContext *cx, JSObject *obj, jsval id) +{ + return JS_TRUE; +} + +JS_PUBLIC_API(JSBool) +JS_ConvertStub(JSContext *cx, JSObject *obj, JSType type, jsval *vp) +{ +#if JS_BUG_EAGER_TOSTRING + if (type == JSTYPE_STRING) + return JS_TRUE; +#endif + return js_TryValueOf(cx, obj, type, vp); +} + +JS_PUBLIC_API(void) +JS_FinalizeStub(JSContext *cx, JSObject *obj) +{ +} + +JS_PUBLIC_API(JSObject *) +JS_InitClass(JSContext *cx, JSObject *obj, JSObject *parent_proto, + JSClass *clasp, JSNative constructor, uintN nargs, + JSPropertySpec *ps, JSFunctionSpec *fs, + JSPropertySpec *static_ps, JSFunctionSpec *static_fs) +{ + JSAtom *atom; + JSObject *proto, *ctor; + JSBool named; + JSFunction *fun; + jsval junk; + + CHECK_REQUEST(cx); + atom = js_Atomize(cx, clasp->name, strlen(clasp->name), 0); + if (!atom) + return NULL; + + /* Create a prototype object for this class. */ + proto = js_NewObject(cx, clasp, parent_proto, obj); + if (!proto) + return NULL; + + if (!constructor) { + /* Lacking a constructor, name the prototype (e.g., Math). */ + named = OBJ_DEFINE_PROPERTY(cx, obj, (jsid)atom, OBJECT_TO_JSVAL(proto), + NULL, NULL, 0, NULL); + if (!named) + goto bad; + ctor = proto; + } else { + /* Define the constructor function in obj's scope. */ + fun = js_DefineFunction(cx, obj, atom, constructor, nargs, 0); + named = (fun != NULL); + if (!fun) + goto bad; + + /* + * Remember the class this function is a constructor for so that + * we know to create an object of this class when we call the + * constructor. + */ + fun->clasp = clasp; + + /* Connect constructor and prototype by named properties. */ + ctor = fun->object; + if (!js_SetClassPrototype(cx, ctor, proto, + JSPROP_READONLY | JSPROP_PERMANENT)) { + goto bad; + } + + /* Bootstrap Function.prototype (see also JS_InitStandardClasses). */ + if (OBJ_GET_CLASS(cx, ctor) == clasp) { + /* XXXMLM - this fails in framesets that are writing over + * themselves! + * JS_ASSERT(!OBJ_GET_PROTO(cx, ctor)); + */ + OBJ_SET_PROTO(cx, ctor, proto); + } + } + + /* Add properties and methods to the prototype and the constructor. */ + if ((ps && !JS_DefineProperties(cx, proto, ps)) || + (fs && !JS_DefineFunctions(cx, proto, fs)) || + (static_ps && !JS_DefineProperties(cx, ctor, static_ps)) || + (static_fs && !JS_DefineFunctions(cx, ctor, static_fs))) { + goto bad; + } + return proto; + +bad: + if (named) + (void) OBJ_DELETE_PROPERTY(cx, obj, (jsid)atom, &junk); + cx->newborn[GCX_OBJECT] = NULL; + return NULL; +} + +#ifdef JS_THREADSAFE +JS_PUBLIC_API(JSClass *) +JS_GetClass(JSContext *cx, JSObject *obj) +{ + return (JSClass *) + JSVAL_TO_PRIVATE(GC_AWARE_GET_SLOT(cx, obj, JSSLOT_CLASS)); +} +#else +JS_PUBLIC_API(JSClass *) +JS_GetClass(JSObject *obj) +{ + return LOCKED_OBJ_GET_CLASS(obj); +} +#endif + +JS_PUBLIC_API(JSBool) +JS_InstanceOf(JSContext *cx, JSObject *obj, JSClass *clasp, jsval *argv) +{ + JSFunction *fun; + + CHECK_REQUEST(cx); + if (OBJ_GET_CLASS(cx, obj) == clasp) + return JS_TRUE; + if (argv) { + fun = js_ValueToFunction(cx, &argv[-2], 0); + if (fun) { + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, + JSMSG_INCOMPATIBLE_PROTO, + clasp->name, JS_GetFunctionName(fun), + OBJ_GET_CLASS(cx, obj)->name); + } + } + return JS_FALSE; +} + +JS_PUBLIC_API(void *) +JS_GetPrivate(JSContext *cx, JSObject *obj) +{ + jsval v; + + JS_ASSERT(OBJ_GET_CLASS(cx, obj)->flags & JSCLASS_HAS_PRIVATE); + v = GC_AWARE_GET_SLOT(cx, obj, JSSLOT_PRIVATE); + if (!JSVAL_IS_INT(v)) + return NULL; + return JSVAL_TO_PRIVATE(v); +} + +JS_PUBLIC_API(JSBool) +JS_SetPrivate(JSContext *cx, JSObject *obj, void *data) +{ + JS_ASSERT(OBJ_GET_CLASS(cx, obj)->flags & JSCLASS_HAS_PRIVATE); + OBJ_SET_SLOT(cx, obj, JSSLOT_PRIVATE, PRIVATE_TO_JSVAL(data)); + return JS_TRUE; +} + +JS_PUBLIC_API(void *) +JS_GetInstancePrivate(JSContext *cx, JSObject *obj, JSClass *clasp, + jsval *argv) +{ + if (!JS_InstanceOf(cx, obj, clasp, argv)) + return NULL; + return JS_GetPrivate(cx, obj); +} + +JS_PUBLIC_API(JSObject *) +JS_GetPrototype(JSContext *cx, JSObject *obj) +{ + JSObject *proto; + + CHECK_REQUEST(cx); + proto = JSVAL_TO_OBJECT(GC_AWARE_GET_SLOT(cx, obj, JSSLOT_PROTO)); + + /* Beware ref to dead object (we may be called from obj's finalizer). */ + return proto && proto->map ? proto : NULL; +} + +JS_PUBLIC_API(JSBool) +JS_SetPrototype(JSContext *cx, JSObject *obj, JSObject *proto) +{ + CHECK_REQUEST(cx); + if (obj->map->ops->setProto) + return obj->map->ops->setProto(cx, obj, JSSLOT_PROTO, proto); + OBJ_SET_SLOT(cx, obj, JSSLOT_PROTO, OBJECT_TO_JSVAL(proto)); + return JS_TRUE; +} + +JS_PUBLIC_API(JSObject *) +JS_GetParent(JSContext *cx, JSObject *obj) +{ + JSObject *parent; + + parent = JSVAL_TO_OBJECT(GC_AWARE_GET_SLOT(cx, obj, JSSLOT_PARENT)); + + /* Beware ref to dead object (we may be called from obj's finalizer). */ + return parent && parent->map ? parent : NULL; +} + +JS_PUBLIC_API(JSBool) +JS_SetParent(JSContext *cx, JSObject *obj, JSObject *parent) +{ + CHECK_REQUEST(cx); + if (obj->map->ops->setParent) + return obj->map->ops->setParent(cx, obj, JSSLOT_PARENT, parent); + OBJ_SET_SLOT(cx, obj, JSSLOT_PARENT, OBJECT_TO_JSVAL(parent)); + return JS_TRUE; +} + +JS_PUBLIC_API(JSObject *) +JS_GetConstructor(JSContext *cx, JSObject *proto) +{ + jsval cval; + + CHECK_REQUEST(cx); + if (!OBJ_GET_PROPERTY(cx, proto, + (jsid)cx->runtime->atomState.constructorAtom, + &cval)) { + return NULL; + } + if (!JSVAL_IS_FUNCTION(cx, cval)) { + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_NO_CONSTRUCTOR, + OBJ_GET_CLASS(cx, proto)->name); + return NULL; + } + return JSVAL_TO_OBJECT(cval); +} + +JS_PUBLIC_API(JSBool) +JS_GetObjectId(JSContext *cx, JSObject *obj, jsid *idp) +{ + *idp = (jsid) obj; + return JS_TRUE; +} + +JS_PUBLIC_API(JSObject *) +JS_NewObject(JSContext *cx, JSClass *clasp, JSObject *proto, JSObject *parent) +{ + CHECK_REQUEST(cx); + if (!clasp) + clasp = &js_ObjectClass; /* default class is Object */ + return js_NewObject(cx, clasp, proto, parent); +} + +JS_PUBLIC_API(JSBool) +JS_SealObject(JSContext *cx, JSObject *obj, JSBool deep) +{ + JSScope *scope; + JSIdArray *ida; + uint32 nslots; + jsval v, *vp, *end; + + if (!OBJ_IS_NATIVE(obj)) { + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, + JSMSG_CANT_SEAL_OBJECT, + OBJ_GET_CLASS(cx, obj)->name); + return JS_FALSE; + } + + scope = OBJ_SCOPE(obj); + +#if defined JS_THREADSAFE && defined DEBUG + /* Insist on scope being used exclusively by cx's thread. */ + if (scope->ownercx != cx) { + JS_LOCK_OBJ(cx, obj); + JS_ASSERT(OBJ_SCOPE(obj) == scope); + JS_ASSERT(scope->ownercx == cx); + JS_UNLOCK_SCOPE(cx, scope); + } +#endif + + /* Nothing to do if obj's scope is already sealed. */ + if (SCOPE_IS_SEALED(scope)) + return JS_TRUE; + + /* XXX Enumerate lazy properties now, as they can't be added later. */ + ida = JS_Enumerate(cx, obj); + if (!ida) + return JS_FALSE; + JS_DestroyIdArray(cx, ida); + + /* Ensure that obj has its own, mutable scope, and seal that scope. */ + JS_LOCK_OBJ(cx, obj); + scope = js_GetMutableScope(cx, obj); + if (scope) + SCOPE_SET_SEALED(scope); + JS_UNLOCK_SCOPE(cx, scope); + if (!scope) + return JS_FALSE; + + /* If we are not sealing an entire object graph, we're done. */ + if (!deep) + return JS_TRUE; + + /* Walk obj->slots and if any value is a non-null object, seal it. */ + nslots = JS_MIN(scope->map.freeslot, scope->map.nslots); + for (vp = obj->slots, end = vp + nslots; vp < end; vp++) { + v = *vp; + if (JSVAL_IS_PRIMITIVE(v)) + continue; + if (!JS_SealObject(cx, JSVAL_TO_OBJECT(v), deep)) + return JS_FALSE; + } + return JS_TRUE; +} + +JS_PUBLIC_API(JSObject *) +JS_ConstructObject(JSContext *cx, JSClass *clasp, JSObject *proto, + JSObject *parent) +{ + CHECK_REQUEST(cx); + if (!clasp) + clasp = &js_ObjectClass; /* default class is Object */ + return js_ConstructObject(cx, clasp, proto, parent, 0, NULL); +} + +JS_PUBLIC_API(JSObject *) +JS_ConstructObjectWithArguments(JSContext *cx, JSClass *clasp, JSObject *proto, + JSObject *parent, uintN argc, jsval *argv) +{ + CHECK_REQUEST(cx); + if (!clasp) + clasp = &js_ObjectClass; /* default class is Object */ + return js_ConstructObject(cx, clasp, proto, parent, argc, argv); +} + +static JSBool +DefineProperty(JSContext *cx, JSObject *obj, const char *name, jsval value, + JSPropertyOp getter, JSPropertyOp setter, uintN attrs, + uintN flags, intN tinyid) +{ + jsid id; + JSAtom *atom; + + if (attrs & JSPROP_INDEX) { + id = INT_TO_JSVAL((jsint)name); + atom = NULL; + attrs &= ~JSPROP_INDEX; + } else { + atom = js_Atomize(cx, name, strlen(name), 0); + if (!atom) + return JS_FALSE; + id = (jsid)atom; + } + if (flags != 0 && OBJ_IS_NATIVE(obj)) { + return js_DefineNativeProperty(cx, obj, id, value, getter, setter, + attrs, flags, tinyid, NULL); + } + return OBJ_DEFINE_PROPERTY(cx, obj, id, value, getter, setter, attrs, + NULL); +} + +#define AUTO_NAMELEN(s,n) (((n) == (size_t)-1) ? js_strlen(s) : (n)) + +static JSBool +DefineUCProperty(JSContext *cx, JSObject *obj, + const jschar *name, size_t namelen, jsval value, + JSPropertyOp getter, JSPropertyOp setter, uintN attrs, + uintN flags, intN tinyid) +{ + JSAtom *atom; + + atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name,namelen), 0); + if (!atom) + return JS_FALSE; + if (flags != 0 && OBJ_IS_NATIVE(obj)) { + return js_DefineNativeProperty(cx, obj, (jsid)atom, value, + getter, setter, attrs, flags, tinyid, + NULL); + } + return OBJ_DEFINE_PROPERTY(cx, obj, (jsid)atom, value, getter, setter, + attrs, NULL); +} + +JS_PUBLIC_API(JSObject *) +JS_DefineObject(JSContext *cx, JSObject *obj, const char *name, JSClass *clasp, + JSObject *proto, uintN attrs) +{ + JSObject *nobj; + + CHECK_REQUEST(cx); + if (!clasp) + clasp = &js_ObjectClass; /* default class is Object */ + nobj = js_NewObject(cx, clasp, proto, obj); + if (!nobj) + return NULL; + if (!DefineProperty(cx, obj, name, OBJECT_TO_JSVAL(nobj), NULL, NULL, attrs, + 0, 0)) { + cx->newborn[GCX_OBJECT] = NULL; + return NULL; + } + return nobj; +} + +JS_PUBLIC_API(JSBool) +JS_DefineConstDoubles(JSContext *cx, JSObject *obj, JSConstDoubleSpec *cds) +{ + JSBool ok; + jsval value; + uintN flags; + + CHECK_REQUEST(cx); + for (ok = JS_TRUE; cds->name; cds++) { + ok = js_NewNumberValue(cx, cds->dval, &value); + if (!ok) + break; + flags = cds->flags; + if (!flags) + flags = JSPROP_READONLY | JSPROP_PERMANENT; + ok = DefineProperty(cx, obj, cds->name, value, NULL, NULL, flags, 0, 0); + if (!ok) + break; + } + return ok; +} + +JS_PUBLIC_API(JSBool) +JS_DefineProperties(JSContext *cx, JSObject *obj, JSPropertySpec *ps) +{ + JSBool ok; + + CHECK_REQUEST(cx); + for (ok = JS_TRUE; ps->name; ps++) { + ok = DefineProperty(cx, obj, ps->name, JSVAL_VOID, + ps->getter, ps->setter, ps->flags, + SPROP_HAS_SHORTID, ps->tinyid); + if (!ok) + break; + } + return ok; +} + +JS_PUBLIC_API(JSBool) +JS_DefineProperty(JSContext *cx, JSObject *obj, const char *name, jsval value, + JSPropertyOp getter, JSPropertyOp setter, uintN attrs) +{ + CHECK_REQUEST(cx); + return DefineProperty(cx, obj, name, value, getter, setter, attrs, 0, 0); +} + +JS_PUBLIC_API(JSBool) +JS_DefinePropertyWithTinyId(JSContext *cx, JSObject *obj, const char *name, + int8 tinyid, jsval value, + JSPropertyOp getter, JSPropertyOp setter, + uintN attrs) +{ + CHECK_REQUEST(cx); + return DefineProperty(cx, obj, name, value, getter, setter, attrs, + SPROP_HAS_SHORTID, tinyid); +} + +static JSBool +LookupProperty(JSContext *cx, JSObject *obj, const char *name, JSObject **objp, + JSProperty **propp) +{ + JSAtom *atom; + + atom = js_Atomize(cx, name, strlen(name), 0); + if (!atom) + return JS_FALSE; + return OBJ_LOOKUP_PROPERTY(cx, obj, (jsid)atom, objp, propp); +} + +static JSBool +LookupUCProperty(JSContext *cx, JSObject *obj, + const jschar *name, size_t namelen, + JSObject **objp, JSProperty **propp) +{ + JSAtom *atom; + + atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name,namelen), 0); + if (!atom) + return JS_FALSE; + return OBJ_LOOKUP_PROPERTY(cx, obj, (jsid)atom, objp, propp); +} + +JS_PUBLIC_API(JSBool) +JS_AliasProperty(JSContext *cx, JSObject *obj, const char *name, + const char *alias) +{ + JSObject *obj2; + JSProperty *prop; + JSAtom *atom; + JSBool ok; + JSScopeProperty *sprop; + + CHECK_REQUEST(cx); + if (!LookupProperty(cx, obj, name, &obj2, &prop)) + return JS_FALSE; + if (!prop) { + js_ReportIsNotDefined(cx, name); + return JS_FALSE; + } + if (obj2 != obj || !OBJ_IS_NATIVE(obj)) { + OBJ_DROP_PROPERTY(cx, obj2, prop); + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_ALIAS, + alias, name, OBJ_GET_CLASS(cx, obj2)->name); + return JS_FALSE; + } + atom = js_Atomize(cx, alias, strlen(alias), 0); + if (!atom) { + ok = JS_FALSE; + } else { + sprop = (JSScopeProperty *)prop; + ok = (js_AddNativeProperty(cx, obj, (jsid)atom, + sprop->getter, sprop->setter, sprop->slot, + sprop->attrs, sprop->flags | SPROP_IS_ALIAS, + sprop->shortid) + != NULL); + } + OBJ_DROP_PROPERTY(cx, obj, prop); + return ok; +} + +static jsval +LookupResult(JSContext *cx, JSObject *obj, JSObject *obj2, JSProperty *prop) +{ + JSScopeProperty *sprop; + jsval rval; + + if (!prop) { + /* XXX bad API: no way to tell "not defined" from "void value" */ + return JSVAL_VOID; + } + if (OBJ_IS_NATIVE(obj2)) { + /* Peek at the native property's slot value, without doing a Get. */ + sprop = (JSScopeProperty *)prop; + rval = SPROP_HAS_VALID_SLOT(sprop, OBJ_SCOPE(obj2)) + ? LOCKED_OBJ_GET_SLOT(obj2, sprop->slot) + : JSVAL_TRUE; + } else { + /* XXX bad API: no way to return "defined but value unknown" */ + rval = JSVAL_TRUE; + } + OBJ_DROP_PROPERTY(cx, obj2, prop); + return rval; +} + +static JSBool +GetPropertyAttributes(JSContext *cx, JSObject *obj, JSAtom *atom, + uintN *attrsp, JSBool *foundp) +{ + JSObject *obj2; + JSProperty *prop; + JSBool ok; + + if (!atom) + return JS_FALSE; + if (!OBJ_LOOKUP_PROPERTY(cx, obj, (jsid)atom, &obj2, &prop)) + return JS_FALSE; + if (!prop || obj != obj2) { + *foundp = JS_FALSE; + if (prop) + OBJ_DROP_PROPERTY(cx, obj2, prop); + return JS_TRUE; + } + + *foundp = JS_TRUE; + ok = OBJ_GET_ATTRIBUTES(cx, obj, (jsid)atom, prop, attrsp); + OBJ_DROP_PROPERTY(cx, obj, prop); + return ok; +} + +static JSBool +SetPropertyAttributes(JSContext *cx, JSObject *obj, JSAtom *atom, + uintN attrs, JSBool *foundp) +{ + JSObject *obj2; + JSProperty *prop; + JSBool ok; + + if (!atom) + return JS_FALSE; + if (!OBJ_LOOKUP_PROPERTY(cx, obj, (jsid)atom, &obj2, &prop)) + return JS_FALSE; + if (!prop || obj != obj2) { + *foundp = JS_FALSE; + if (prop) + OBJ_DROP_PROPERTY(cx, obj2, prop); + return JS_TRUE; + } + + *foundp = JS_TRUE; + ok = OBJ_SET_ATTRIBUTES(cx, obj, (jsid)atom, prop, &attrs); + OBJ_DROP_PROPERTY(cx, obj, prop); + return ok; +} + + +JS_PUBLIC_API(JSBool) +JS_GetPropertyAttributes(JSContext *cx, JSObject *obj, const char *name, + uintN *attrsp, JSBool *foundp) +{ + CHECK_REQUEST(cx); + return GetPropertyAttributes(cx, obj, + js_Atomize(cx, name, strlen(name), 0), + attrsp, foundp); +} + +JS_PUBLIC_API(JSBool) +JS_SetPropertyAttributes(JSContext *cx, JSObject *obj, const char *name, + uintN attrs, JSBool *foundp) +{ + CHECK_REQUEST(cx); + return SetPropertyAttributes(cx, obj, + js_Atomize(cx, name, strlen(name), 0), + attrs, foundp); +} + +JS_PUBLIC_API(JSBool) +JS_LookupProperty(JSContext *cx, JSObject *obj, const char *name, jsval *vp) +{ + JSBool ok; + JSObject *obj2; + JSProperty *prop; + + CHECK_REQUEST(cx); + ok = LookupProperty(cx, obj, name, &obj2, &prop); + if (ok) + *vp = LookupResult(cx, obj, obj2, prop); + return ok; +} + +JS_PUBLIC_API(JSBool) +JS_GetProperty(JSContext *cx, JSObject *obj, const char *name, jsval *vp) +{ + JSAtom *atom; + + CHECK_REQUEST(cx); + atom = js_Atomize(cx, name, strlen(name), 0); + if (!atom) + return JS_FALSE; + return OBJ_GET_PROPERTY(cx, obj, (jsid)atom, vp); +} + +JS_PUBLIC_API(JSBool) +JS_SetProperty(JSContext *cx, JSObject *obj, const char *name, jsval *vp) +{ + JSAtom *atom; + + CHECK_REQUEST(cx); + atom = js_Atomize(cx, name, strlen(name), 0); + if (!atom) + return JS_FALSE; + return OBJ_SET_PROPERTY(cx, obj, (jsid)atom, vp); +} + +JS_PUBLIC_API(JSBool) +JS_DeleteProperty(JSContext *cx, JSObject *obj, const char *name) +{ + jsval junk; + + CHECK_REQUEST(cx); + return JS_DeleteProperty2(cx, obj, name, &junk); +} + +JS_PUBLIC_API(JSBool) +JS_DeleteProperty2(JSContext *cx, JSObject *obj, const char *name, + jsval *rval) +{ + JSAtom *atom; + + CHECK_REQUEST(cx); + atom = js_Atomize(cx, name, strlen(name), 0); + if (!atom) + return JS_FALSE; + return OBJ_DELETE_PROPERTY(cx, obj, (jsid)atom, rval); +} + +JS_PUBLIC_API(JSBool) +JS_DefineUCProperty(JSContext *cx, JSObject *obj, + const jschar *name, size_t namelen, jsval value, + JSPropertyOp getter, JSPropertyOp setter, + uintN attrs) +{ + CHECK_REQUEST(cx); + return DefineUCProperty(cx, obj, name, namelen, value, getter, setter, + attrs, 0, 0); +} + +JS_PUBLIC_API(JSBool) +JS_GetUCPropertyAttributes(JSContext *cx, JSObject *obj, + const jschar *name, size_t namelen, + uintN *attrsp, JSBool *foundp) +{ + CHECK_REQUEST(cx); + return GetPropertyAttributes(cx, obj, + js_AtomizeChars(cx, name, AUTO_NAMELEN(name,namelen), 0), + attrsp, foundp); +} + +JS_PUBLIC_API(JSBool) +JS_SetUCPropertyAttributes(JSContext *cx, JSObject *obj, + const jschar *name, size_t namelen, + uintN attrs, JSBool *foundp) +{ + CHECK_REQUEST(cx); + return SetPropertyAttributes(cx, obj, + js_AtomizeChars(cx, name, AUTO_NAMELEN(name,namelen), 0), + attrs, foundp); +} + +JS_PUBLIC_API(JSBool) +JS_DefineUCPropertyWithTinyId(JSContext *cx, JSObject *obj, + const jschar *name, size_t namelen, + int8 tinyid, jsval value, + JSPropertyOp getter, JSPropertyOp setter, + uintN attrs) +{ + CHECK_REQUEST(cx); + return DefineUCProperty(cx, obj, name, namelen, value, getter, setter, + attrs, SPROP_HAS_SHORTID, tinyid); +} + +JS_PUBLIC_API(JSBool) +JS_LookupUCProperty(JSContext *cx, JSObject *obj, + const jschar *name, size_t namelen, + jsval *vp) +{ + JSBool ok; + JSObject *obj2; + JSProperty *prop; + + CHECK_REQUEST(cx); + ok = LookupUCProperty(cx, obj, name, namelen, &obj2, &prop); + if (ok) + *vp = LookupResult(cx, obj, obj2, prop); + return ok; +} + +JS_PUBLIC_API(JSBool) +JS_GetUCProperty(JSContext *cx, JSObject *obj, + const jschar *name, size_t namelen, + jsval *vp) +{ + JSAtom *atom; + + CHECK_REQUEST(cx); + atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name,namelen), 0); + if (!atom) + return JS_FALSE; + return OBJ_GET_PROPERTY(cx, obj, (jsid)atom, vp); +} + +JS_PUBLIC_API(JSBool) +JS_SetUCProperty(JSContext *cx, JSObject *obj, + const jschar *name, size_t namelen, + jsval *vp) +{ + JSAtom *atom; + + CHECK_REQUEST(cx); + atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name,namelen), 0); + if (!atom) + return JS_FALSE; + return OBJ_SET_PROPERTY(cx, obj, (jsid)atom, vp); +} + +JS_PUBLIC_API(JSBool) +JS_DeleteUCProperty2(JSContext *cx, JSObject *obj, + const jschar *name, size_t namelen, + jsval *rval) +{ + JSAtom *atom; + + CHECK_REQUEST(cx); + atom = js_AtomizeChars(cx, name, AUTO_NAMELEN(name,namelen), 0); + if (!atom) + return JS_FALSE; + return OBJ_DELETE_PROPERTY(cx, obj, (jsid)atom, rval); +} + +JS_PUBLIC_API(JSObject *) +JS_NewArrayObject(JSContext *cx, jsint length, jsval *vector) +{ + CHECK_REQUEST(cx); + /* NB: jsuint cast does ToUint32. */ + return js_NewArrayObject(cx, (jsuint)length, vector); +} + +JS_PUBLIC_API(JSBool) +JS_IsArrayObject(JSContext *cx, JSObject *obj) +{ + return OBJ_GET_CLASS(cx, obj) == &js_ArrayClass; +} + +JS_PUBLIC_API(JSBool) +JS_GetArrayLength(JSContext *cx, JSObject *obj, jsuint *lengthp) +{ + CHECK_REQUEST(cx); + return js_GetLengthProperty(cx, obj, lengthp); +} + +JS_PUBLIC_API(JSBool) +JS_SetArrayLength(JSContext *cx, JSObject *obj, jsuint length) +{ + CHECK_REQUEST(cx); + return js_SetLengthProperty(cx, obj, length); +} + +JS_PUBLIC_API(JSBool) +JS_HasArrayLength(JSContext *cx, JSObject *obj, jsuint *lengthp) +{ + CHECK_REQUEST(cx); + return js_HasLengthProperty(cx, obj, lengthp); +} + +JS_PUBLIC_API(JSBool) +JS_DefineElement(JSContext *cx, JSObject *obj, jsint index, jsval value, + JSPropertyOp getter, JSPropertyOp setter, uintN attrs) +{ + CHECK_REQUEST(cx); + return OBJ_DEFINE_PROPERTY(cx, obj, INT_TO_JSVAL(index), value, + getter, setter, attrs, NULL); +} + +JS_PUBLIC_API(JSBool) +JS_AliasElement(JSContext *cx, JSObject *obj, const char *name, jsint alias) +{ + JSObject *obj2; + JSProperty *prop; + JSScopeProperty *sprop; + JSBool ok; + + CHECK_REQUEST(cx); + if (!LookupProperty(cx, obj, name, &obj2, &prop)) + return JS_FALSE; + if (!prop) { + js_ReportIsNotDefined(cx, name); + return JS_FALSE; + } + if (obj2 != obj || !OBJ_IS_NATIVE(obj)) { + char numBuf[12]; + OBJ_DROP_PROPERTY(cx, obj2, prop); + JS_snprintf(numBuf, sizeof numBuf, "%ld", (long)alias); + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_ALIAS, + numBuf, name, OBJ_GET_CLASS(cx, obj2)->name); + return JS_FALSE; + } + sprop = (JSScopeProperty *)prop; + ok = (js_AddNativeProperty(cx, obj, INT_TO_JSVAL(alias), + sprop->getter, sprop->setter, sprop->slot, + sprop->attrs, sprop->flags | SPROP_IS_ALIAS, + sprop->shortid) + != NULL); + OBJ_DROP_PROPERTY(cx, obj, prop); + return ok; +} + +JS_PUBLIC_API(JSBool) +JS_LookupElement(JSContext *cx, JSObject *obj, jsint index, jsval *vp) +{ + JSBool ok; + JSObject *obj2; + JSProperty *prop; + + CHECK_REQUEST(cx); + ok = OBJ_LOOKUP_PROPERTY(cx, obj, INT_TO_JSVAL(index), &obj2, &prop); + if (ok) + *vp = LookupResult(cx, obj, obj2, prop); + return ok; +} + +JS_PUBLIC_API(JSBool) +JS_GetElement(JSContext *cx, JSObject *obj, jsint index, jsval *vp) +{ + CHECK_REQUEST(cx); + return OBJ_GET_PROPERTY(cx, obj, INT_TO_JSVAL(index), vp); +} + +JS_PUBLIC_API(JSBool) +JS_SetElement(JSContext *cx, JSObject *obj, jsint index, jsval *vp) +{ + CHECK_REQUEST(cx); + return OBJ_SET_PROPERTY(cx, obj, INT_TO_JSVAL(index), vp); +} + +JS_PUBLIC_API(JSBool) +JS_DeleteElement(JSContext *cx, JSObject *obj, jsint index) +{ + jsval junk; + + CHECK_REQUEST(cx); + return JS_DeleteElement2(cx, obj, index, &junk); +} + +JS_PUBLIC_API(JSBool) +JS_DeleteElement2(JSContext *cx, JSObject *obj, jsint index, jsval *rval) +{ + CHECK_REQUEST(cx); + return OBJ_DELETE_PROPERTY(cx, obj, INT_TO_JSVAL(index), rval); +} + +JS_PUBLIC_API(void) +JS_ClearScope(JSContext *cx, JSObject *obj) +{ + CHECK_REQUEST(cx); + + if (obj->map->ops->clear) + obj->map->ops->clear(cx, obj); +} + +JS_PUBLIC_API(JSIdArray *) +JS_Enumerate(JSContext *cx, JSObject *obj) +{ + jsint i, n; + jsval iter_state, num_properties; + jsid id; + JSIdArray *ida; + jsval *vector; + + CHECK_REQUEST(cx); + + ida = NULL; + iter_state = JSVAL_NULL; + + /* Get the number of properties to enumerate. */ + if (!OBJ_ENUMERATE(cx, obj, JSENUMERATE_INIT, &iter_state, &num_properties)) + goto error; + if (!JSVAL_IS_INT(num_properties)) { + JS_ASSERT(0); + goto error; + } + + /* Grow as needed if we don't know the exact amount ahead of time. */ + n = JSVAL_TO_INT(num_properties); + if (n <= 0) + n = 8; + + /* Create an array of jsids large enough to hold all the properties */ + ida = js_NewIdArray(cx, n); + if (!ida) + goto error; + + i = 0; + vector = &ida->vector[0]; + for (;;) { + if (i == ida->length) { + /* Grow length by factor of 1.5 instead of doubling. */ + jsint newlen = ida->length + (((jsuint)ida->length + 1) >> 1); + ida = js_GrowIdArray(cx, ida, newlen); + if (!ida) + goto error; + vector = &ida->vector[0]; + } + + if (!OBJ_ENUMERATE(cx, obj, JSENUMERATE_NEXT, &iter_state, &id)) + goto error; + + /* No more jsid's to enumerate ? */ + if (iter_state == JSVAL_NULL) + break; + vector[i++] = id; + } + ida->length = i; + return ida; + +error: + if (iter_state != JSVAL_NULL) + OBJ_ENUMERATE(cx, obj, JSENUMERATE_DESTROY, &iter_state, 0); + if (ida) + JS_DestroyIdArray(cx, ida); + return NULL; +} + +JS_PUBLIC_API(JSBool) +JS_CheckAccess(JSContext *cx, JSObject *obj, jsid id, JSAccessMode mode, + jsval *vp, uintN *attrsp) +{ + CHECK_REQUEST(cx); + return OBJ_CHECK_ACCESS(cx, obj, id, mode, vp, attrsp); +} + +JS_PUBLIC_API(JSCheckAccessOp) +JS_SetCheckObjectAccessCallback(JSRuntime *rt, JSCheckAccessOp acb) +{ + JSCheckAccessOp oldacb; + + oldacb = rt->checkObjectAccess; + rt->checkObjectAccess = acb; + return oldacb; +} + +JS_PUBLIC_API(JSBool) +JS_GetReservedSlot(JSContext *cx, JSObject *obj, uint32 index, jsval *vp) +{ + JSClass *clasp; + uint32 slot; + + CHECK_REQUEST(cx); + clasp = OBJ_GET_CLASS(cx, obj); + if (index >= JSCLASS_RESERVED_SLOTS(clasp)) { + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, + JSMSG_RESERVED_SLOT_RANGE); + return JS_FALSE; + } + slot = JSSLOT_START(clasp) + index; + *vp = OBJ_GET_REQUIRED_SLOT(cx, obj, slot); + return JS_TRUE; +} + +JS_PUBLIC_API(JSBool) +JS_SetReservedSlot(JSContext *cx, JSObject *obj, uint32 index, jsval v) +{ + JSClass *clasp; + uint32 slot; + + CHECK_REQUEST(cx); + clasp = OBJ_GET_CLASS(cx, obj); + if (index >= JSCLASS_RESERVED_SLOTS(clasp)) { + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, + JSMSG_RESERVED_SLOT_RANGE); + return JS_FALSE; + } + slot = JSSLOT_START(clasp) + index; + OBJ_SET_REQUIRED_SLOT(cx, obj, slot, v); + return JS_TRUE; +} + +#ifdef JS_THREADSAFE +JS_PUBLIC_API(jsrefcount) +JS_HoldPrincipals(JSContext *cx, JSPrincipals *principals) +{ + return JS_ATOMIC_INCREMENT(&principals->refcount); +} + +JS_PUBLIC_API(jsrefcount) +JS_DropPrincipals(JSContext *cx, JSPrincipals *principals) +{ + jsrefcount rc = JS_ATOMIC_DECREMENT(&principals->refcount); + if (rc == 0) + principals->destroy(cx, principals); + return rc; +} +#endif + +JS_PUBLIC_API(JSPrincipalsTranscoder) +JS_SetPrincipalsTranscoder(JSRuntime *rt, JSPrincipalsTranscoder px) +{ + JSPrincipalsTranscoder oldpx; + + oldpx = rt->principalsTranscoder; + rt->principalsTranscoder = px; + return oldpx; +} + +JS_PUBLIC_API(JSObjectPrincipalsFinder) +JS_SetObjectPrincipalsFinder(JSContext *cx, JSObjectPrincipalsFinder fop) +{ + JSObjectPrincipalsFinder oldfop; + + oldfop = cx->findObjectPrincipals; + cx->findObjectPrincipals = fop; + return oldfop; +} + +JS_PUBLIC_API(JSFunction *) +JS_NewFunction(JSContext *cx, JSNative native, uintN nargs, uintN flags, + JSObject *parent, const char *name) +{ + JSAtom *atom; + + CHECK_REQUEST(cx); + + if (!name) { + atom = NULL; + } else { + atom = js_Atomize(cx, name, strlen(name), 0); + if (!atom) + return NULL; + } + return js_NewFunction(cx, NULL, native, nargs, flags, parent, atom); +} + +JS_PUBLIC_API(JSObject *) +JS_CloneFunctionObject(JSContext *cx, JSObject *funobj, JSObject *parent) +{ + CHECK_REQUEST(cx); + if (OBJ_GET_CLASS(cx, funobj) != &js_FunctionClass) { + /* Indicate we cannot clone this object. */ + return funobj; + } + return js_CloneFunctionObject(cx, funobj, parent); +} + +JS_PUBLIC_API(JSObject *) +JS_GetFunctionObject(JSFunction *fun) +{ + return fun->object; +} + +JS_PUBLIC_API(const char *) +JS_GetFunctionName(JSFunction *fun) +{ + return fun->atom + ? JS_GetStringBytes(ATOM_TO_STRING(fun->atom)) + : js_anonymous_str; +} + +JS_PUBLIC_API(JSString *) +JS_GetFunctionId(JSFunction *fun) +{ + return fun->atom ? ATOM_TO_STRING(fun->atom) : NULL; +} + +JS_PUBLIC_API(uintN) +JS_GetFunctionFlags(JSFunction *fun) +{ + return fun->flags; +} + +JS_PUBLIC_API(JSBool) +JS_ObjectIsFunction(JSContext *cx, JSObject *obj) +{ + return OBJ_GET_CLASS(cx, obj) == &js_FunctionClass; +} + +JS_PUBLIC_API(JSBool) +JS_DefineFunctions(JSContext *cx, JSObject *obj, JSFunctionSpec *fs) +{ + JSFunction *fun; + + CHECK_REQUEST(cx); + for (; fs->name; fs++) { + fun = JS_DefineFunction(cx, obj, fs->name, fs->call, fs->nargs, + fs->flags); + if (!fun) + return JS_FALSE; + fun->extra = fs->extra; + } + return JS_TRUE; +} + +JS_PUBLIC_API(JSFunction *) +JS_DefineFunction(JSContext *cx, JSObject *obj, const char *name, JSNative call, + uintN nargs, uintN attrs) +{ + JSAtom *atom; + + CHECK_REQUEST(cx); + atom = js_Atomize(cx, name, strlen(name), 0); + if (!atom) + return NULL; + return js_DefineFunction(cx, obj, atom, call, nargs, attrs); +} + +static JSScript * +CompileTokenStream(JSContext *cx, JSObject *obj, JSTokenStream *ts, + void *tempMark, JSBool *eofp) +{ + JSBool eof; + JSArenaPool codePool, notePool; + JSCodeGenerator cg; + JSScript *script; + + CHECK_REQUEST(cx); + eof = JS_FALSE; + JS_InitArenaPool(&codePool, "code", 1024, sizeof(jsbytecode)); + JS_InitArenaPool(¬ePool, "note", 1024, sizeof(jssrcnote)); + if (!js_InitCodeGenerator(cx, &cg, &codePool, ¬ePool, + ts->filename, ts->lineno, + ts->principals)) { + script = NULL; + } else if (!js_CompileTokenStream(cx, obj, ts, &cg)) { + script = NULL; + eof = (ts->flags & TSF_EOF) != 0; + } else { + script = js_NewScriptFromCG(cx, &cg, NULL); + } + if (eofp) + *eofp = eof; + if (!js_CloseTokenStream(cx, ts)) { + if (script) + js_DestroyScript(cx, script); + script = NULL; + } + cg.tempMark = tempMark; + js_FinishCodeGenerator(cx, &cg); + JS_FinishArenaPool(&codePool); + JS_FinishArenaPool(¬ePool); + return script; +} + +JS_PUBLIC_API(JSScript *) +JS_CompileScript(JSContext *cx, JSObject *obj, + const char *bytes, size_t length, + const char *filename, uintN lineno) +{ + jschar *chars; + JSScript *script; + + CHECK_REQUEST(cx); + chars = js_InflateString(cx, bytes, length); + if (!chars) + return NULL; + script = JS_CompileUCScript(cx, obj, chars, length, filename, lineno); + JS_free(cx, chars); + return script; +} + +JS_PUBLIC_API(JSScript *) +JS_CompileScriptForPrincipals(JSContext *cx, JSObject *obj, + JSPrincipals *principals, + const char *bytes, size_t length, + const char *filename, uintN lineno) +{ + jschar *chars; + JSScript *script; + + CHECK_REQUEST(cx); + chars = js_InflateString(cx, bytes, length); + if (!chars) + return NULL; + script = JS_CompileUCScriptForPrincipals(cx, obj, principals, + chars, length, filename, lineno); + JS_free(cx, chars); + return script; +} + +JS_PUBLIC_API(JSScript *) +JS_CompileUCScript(JSContext *cx, JSObject *obj, + const jschar *chars, size_t length, + const char *filename, uintN lineno) +{ + CHECK_REQUEST(cx); + return JS_CompileUCScriptForPrincipals(cx, obj, NULL, chars, length, + filename, lineno); +} + +JS_PUBLIC_API(JSScript *) +JS_CompileUCScriptForPrincipals(JSContext *cx, JSObject *obj, + JSPrincipals *principals, + const jschar *chars, size_t length, + const char *filename, uintN lineno) +{ + void *mark; + JSTokenStream *ts; + JSScript *script; + + CHECK_REQUEST(cx); + mark = JS_ARENA_MARK(&cx->tempPool); + ts = js_NewTokenStream(cx, chars, length, filename, lineno, principals); + if (!ts) + return NULL; + script = CompileTokenStream(cx, obj, ts, mark, NULL); +#if JS_HAS_EXCEPTIONS + if (!script && !cx->fp) + js_ReportUncaughtException(cx); +#endif + return script; +} + +JS_PUBLIC_API(JSBool) +JS_BufferIsCompilableUnit(JSContext *cx, JSObject *obj, + const char *bytes, size_t length) +{ + jschar *chars; + JSBool result; + JSExceptionState *exnState; + void *tempMark; + JSTokenStream *ts; + JSErrorReporter older; + + CHECK_REQUEST(cx); + chars = js_InflateString(cx, bytes, length); + if (!chars) + return JS_TRUE; + + /* + * Return true on any out-of-memory error, so our caller doesn't try to + * collect more buffered source. + */ + result = JS_TRUE; + exnState = JS_SaveExceptionState(cx); + tempMark = JS_ARENA_MARK(&cx->tempPool); + ts = js_NewTokenStream(cx, chars, length, NULL, 0, NULL); + if (ts) { + older = JS_SetErrorReporter(cx, NULL); + if (!js_ParseTokenStream(cx, obj, ts)) { + /* + * We ran into an error. If it was because we ran out of source, + * we return false, so our caller will know to try to collect more + * buffered source. + */ + result = (ts->flags & TSF_EOF) == 0; + } + + JS_SetErrorReporter(cx, older); + js_CloseTokenStream(cx, ts); + JS_ARENA_RELEASE(&cx->tempPool, tempMark); + } + + JS_free(cx, chars); + JS_RestoreExceptionState(cx, exnState); + return result; +} + +JS_PUBLIC_API(JSScript *) +JS_CompileFile(JSContext *cx, JSObject *obj, const char *filename) +{ + void *mark; + JSTokenStream *ts; + JSScript *script; + + CHECK_REQUEST(cx); + mark = JS_ARENA_MARK(&cx->tempPool); + ts = js_NewFileTokenStream(cx, filename, stdin); + if (!ts) + return NULL; + script = CompileTokenStream(cx, obj, ts, mark, NULL); +#if JS_HAS_EXCEPTIONS + if (!script && !cx->fp) + js_ReportUncaughtException(cx); +#endif + return script; +} + +JS_PUBLIC_API(JSScript *) +JS_CompileFileHandle(JSContext *cx, JSObject *obj, const char *filename, + FILE *file) +{ + return JS_CompileFileHandleForPrincipals(cx, obj, filename, file, NULL); +} + +JS_PUBLIC_API(JSScript *) +JS_CompileFileHandleForPrincipals(JSContext *cx, JSObject *obj, + const char *filename, FILE *file, + JSPrincipals *principals) +{ + void *mark; + JSTokenStream *ts; + JSScript *script; + + CHECK_REQUEST(cx); + mark = JS_ARENA_MARK(&cx->tempPool); + ts = js_NewFileTokenStream(cx, NULL, file); + if (!ts) + return NULL; + ts->filename = filename; + /* XXXshaver js_NewFileTokenStream should do this, because it drops */ + if (principals) { + ts->principals = principals; + JSPRINCIPALS_HOLD(cx, ts->principals); + } + script = CompileTokenStream(cx, obj, ts, mark, NULL); +#if JS_HAS_EXCEPTIONS + if (!script && !cx->fp) + js_ReportUncaughtException(cx); +#endif + return script; +} + +JS_PUBLIC_API(JSObject *) +JS_NewScriptObject(JSContext *cx, JSScript *script) +{ + JSObject *obj; + + /* + * We use a dummy stack frame to protect the script from a GC caused + * by debugger-hook execution. + * + * XXX We really need a way to manage local roots and such more + * XXX automatically, at which point we can remove this one-off hack + * XXX and others within the engine. See bug 40757 for discussion. + */ + JSStackFrame dummy; + + CHECK_REQUEST(cx); + + memset(&dummy, 0, sizeof dummy); + dummy.down = cx->fp; + dummy.script = script; + cx->fp = &dummy; + + obj = js_NewObject(cx, &js_ScriptClass, NULL, NULL); + + cx->fp = dummy.down; + if (!obj) + return NULL; + + if (script) { + if (!JS_SetPrivate(cx, obj, script)) + return NULL; + script->object = obj; + } + return obj; +} + +JS_PUBLIC_API(JSObject *) +JS_GetScriptObject(JSScript *script) +{ + return script->object; +} + +JS_PUBLIC_API(void) +JS_DestroyScript(JSContext *cx, JSScript *script) +{ + CHECK_REQUEST(cx); + js_DestroyScript(cx, script); +} + +JS_PUBLIC_API(JSFunction *) +JS_CompileFunction(JSContext *cx, JSObject *obj, const char *name, + uintN nargs, const char **argnames, + const char *bytes, size_t length, + const char *filename, uintN lineno) +{ + jschar *chars; + JSFunction *fun; + + CHECK_REQUEST(cx); + chars = js_InflateString(cx, bytes, length); + if (!chars) + return NULL; + fun = JS_CompileUCFunction(cx, obj, name, nargs, argnames, chars, length, + filename, lineno); + JS_free(cx, chars); + return fun; +} + +JS_PUBLIC_API(JSFunction *) +JS_CompileFunctionForPrincipals(JSContext *cx, JSObject *obj, + JSPrincipals *principals, const char *name, + uintN nargs, const char **argnames, + const char *bytes, size_t length, + const char *filename, uintN lineno) +{ + jschar *chars; + JSFunction *fun; + + CHECK_REQUEST(cx); + chars = js_InflateString(cx, bytes, length); + if (!chars) + return NULL; + fun = JS_CompileUCFunctionForPrincipals(cx, obj, principals, name, + nargs, argnames, chars, length, + filename, lineno); + JS_free(cx, chars); + return fun; +} + +JS_PUBLIC_API(JSFunction *) +JS_CompileUCFunction(JSContext *cx, JSObject *obj, const char *name, + uintN nargs, const char **argnames, + const jschar *chars, size_t length, + const char *filename, uintN lineno) +{ + CHECK_REQUEST(cx); + return JS_CompileUCFunctionForPrincipals(cx, obj, NULL, name, + nargs, argnames, + chars, length, + filename, lineno); +} + +JS_PUBLIC_API(JSFunction *) +JS_CompileUCFunctionForPrincipals(JSContext *cx, JSObject *obj, + JSPrincipals *principals, const char *name, + uintN nargs, const char **argnames, + const jschar *chars, size_t length, + const char *filename, uintN lineno) +{ + void *mark; + JSTokenStream *ts; + JSFunction *fun; + JSAtom *funAtom, *argAtom; + uintN i; + + CHECK_REQUEST(cx); + mark = JS_ARENA_MARK(&cx->tempPool); + ts = js_NewTokenStream(cx, chars, length, filename, lineno, principals); + if (!ts) { + fun = NULL; + goto out; + } + if (!name) { + funAtom = NULL; + } else { + funAtom = js_Atomize(cx, name, strlen(name), 0); + if (!funAtom) { + fun = NULL; + goto out; + } + } + fun = js_NewFunction(cx, NULL, NULL, nargs, 0, obj, funAtom); + if (!fun) + goto out; + if (nargs) { + for (i = 0; i < nargs; i++) { + argAtom = js_Atomize(cx, argnames[i], strlen(argnames[i]), 0); + if (!argAtom) + break; + if (!js_AddNativeProperty(cx, fun->object, (jsid)argAtom, + js_GetArgument, js_SetArgument, + SPROP_INVALID_SLOT, + JSPROP_ENUMERATE | JSPROP_PERMANENT | + JSPROP_SHARED, + SPROP_HAS_SHORTID, i)) { + break; + } + } + if (i < nargs) { + fun = NULL; + goto out; + } + } + if (!js_CompileFunctionBody(cx, ts, fun)) { + fun = NULL; + goto out; + } + if (obj && funAtom) { + if (!OBJ_DEFINE_PROPERTY(cx, obj, (jsid)funAtom, + OBJECT_TO_JSVAL(fun->object), + NULL, NULL, 0, NULL)) { + return NULL; + } + } +out: + if (ts) + js_CloseTokenStream(cx, ts); + JS_ARENA_RELEASE(&cx->tempPool, mark); +#if JS_HAS_EXCEPTIONS + if (!fun && !cx->fp) + js_ReportUncaughtException(cx); +#endif + return fun; +} + +JS_PUBLIC_API(JSString *) +JS_DecompileScript(JSContext *cx, JSScript *script, const char *name, + uintN indent) +{ + JSPrinter *jp; + JSString *str; + + CHECK_REQUEST(cx); + jp = js_NewPrinter(cx, name, + indent & ~JS_DONT_PRETTY_PRINT, + !(indent & JS_DONT_PRETTY_PRINT)); + if (!jp) + return NULL; + if (js_DecompileScript(jp, script)) + str = js_GetPrinterOutput(jp); + else + str = NULL; + js_DestroyPrinter(jp); + return str; +} + +JS_PUBLIC_API(JSString *) +JS_DecompileFunction(JSContext *cx, JSFunction *fun, uintN indent) +{ + JSPrinter *jp; + JSString *str; + + CHECK_REQUEST(cx); + jp = js_NewPrinter(cx, JS_GetFunctionName(fun), + indent & ~JS_DONT_PRETTY_PRINT, + !(indent & JS_DONT_PRETTY_PRINT)); + if (!jp) + return NULL; + if (js_DecompileFunction(jp, fun)) + str = js_GetPrinterOutput(jp); + else + str = NULL; + js_DestroyPrinter(jp); + return str; +} + +JS_PUBLIC_API(JSString *) +JS_DecompileFunctionBody(JSContext *cx, JSFunction *fun, uintN indent) +{ + JSPrinter *jp; + JSString *str; + + CHECK_REQUEST(cx); + jp = js_NewPrinter(cx, JS_GetFunctionName(fun), + indent & ~JS_DONT_PRETTY_PRINT, + !(indent & JS_DONT_PRETTY_PRINT)); + if (!jp) + return NULL; + if (js_DecompileFunctionBody(jp, fun)) + str = js_GetPrinterOutput(jp); + else + str = NULL; + js_DestroyPrinter(jp); + return str; +} + +JS_PUBLIC_API(JSBool) +JS_ExecuteScript(JSContext *cx, JSObject *obj, JSScript *script, jsval *rval) +{ + CHECK_REQUEST(cx); + if (!js_Execute(cx, obj, script, NULL, 0, rval)) { +#if JS_HAS_EXCEPTIONS + if (!cx->fp) + js_ReportUncaughtException(cx); +#endif + return JS_FALSE; + } + return JS_TRUE; +} + +JS_PUBLIC_API(JSBool) +JS_ExecuteScriptPart(JSContext *cx, JSObject *obj, JSScript *script, + JSExecPart part, jsval *rval) +{ + JSScript tmp; + JSRuntime *rt; + JSBool ok; + + /* Make a temporary copy of the JSScript structure and farble it a bit. */ + tmp = *script; + if (part == JSEXEC_PROLOG) { + tmp.length = PTRDIFF(tmp.main, tmp.code, jsbytecode); + } else { + tmp.length -= PTRDIFF(tmp.main, tmp.code, jsbytecode); + tmp.code = tmp.main; + } + + /* Tell the debugger about our temporary copy of the script structure. */ + rt = cx->runtime; + if (rt->newScriptHook) { + rt->newScriptHook(cx, tmp.filename, tmp.lineno, &tmp, NULL, + rt->newScriptHookData); + } + + /* Execute the farbled struct and tell the debugger to forget about it. */ + ok = JS_ExecuteScript(cx, obj, &tmp, rval); + if (rt->destroyScriptHook) + rt->destroyScriptHook(cx, &tmp, rt->destroyScriptHookData); + return ok; +} + +JS_PUBLIC_API(JSBool) +JS_EvaluateScript(JSContext *cx, JSObject *obj, + const char *bytes, uintN length, + const char *filename, uintN lineno, + jsval *rval) +{ + jschar *chars; + JSBool ok; + + CHECK_REQUEST(cx); + chars = js_InflateString(cx, bytes, length); + if (!chars) + return JS_FALSE; + ok = JS_EvaluateUCScript(cx, obj, chars, length, filename, lineno, rval); + JS_free(cx, chars); + return ok; +} + +JS_PUBLIC_API(JSBool) +JS_EvaluateScriptForPrincipals(JSContext *cx, JSObject *obj, + JSPrincipals *principals, + const char *bytes, uintN length, + const char *filename, uintN lineno, + jsval *rval) +{ + jschar *chars; + JSBool ok; + + CHECK_REQUEST(cx); + chars = js_InflateString(cx, bytes, length); + if (!chars) + return JS_FALSE; + ok = JS_EvaluateUCScriptForPrincipals(cx, obj, principals, chars, length, + filename, lineno, rval); + JS_free(cx, chars); + return ok; +} + +JS_PUBLIC_API(JSBool) +JS_EvaluateUCScript(JSContext *cx, JSObject *obj, + const jschar *chars, uintN length, + const char *filename, uintN lineno, + jsval *rval) +{ + CHECK_REQUEST(cx); + return JS_EvaluateUCScriptForPrincipals(cx, obj, NULL, chars, length, + filename, lineno, rval); +} + +JS_PUBLIC_API(JSBool) +JS_EvaluateUCScriptForPrincipals(JSContext *cx, JSObject *obj, + JSPrincipals *principals, + const jschar *chars, uintN length, + const char *filename, uintN lineno, + jsval *rval) +{ + JSScript *script; + JSBool ok; + + CHECK_REQUEST(cx); + script = JS_CompileUCScriptForPrincipals(cx, obj, principals, chars, length, + filename, lineno); + if (!script) + return JS_FALSE; + ok = js_Execute(cx, obj, script, NULL, 0, rval); +#if JS_HAS_EXCEPTIONS + if (!ok && !cx->fp) + js_ReportUncaughtException(cx); +#endif + JS_DestroyScript(cx, script); + return ok; +} + +JS_PUBLIC_API(JSBool) +JS_CallFunction(JSContext *cx, JSObject *obj, JSFunction *fun, uintN argc, + jsval *argv, jsval *rval) +{ + CHECK_REQUEST(cx); + if (!js_InternalCall(cx, obj, OBJECT_TO_JSVAL(fun->object), argc, argv, + rval)) { +#if JS_HAS_EXCEPTIONS + if (!cx->fp) + js_ReportUncaughtException(cx); +#endif + return JS_FALSE; + } + return JS_TRUE; +} + +JS_PUBLIC_API(JSBool) +JS_CallFunctionName(JSContext *cx, JSObject *obj, const char *name, uintN argc, + jsval *argv, jsval *rval) +{ + jsval fval; + + CHECK_REQUEST(cx); + if (!JS_GetProperty(cx, obj, name, &fval)) + return JS_FALSE; + if (!js_InternalCall(cx, obj, fval, argc, argv, rval)) { +#if JS_HAS_EXCEPTIONS + if (!cx->fp) + js_ReportUncaughtException(cx); +#endif + return JS_FALSE; + } + return JS_TRUE; +} + +JS_PUBLIC_API(JSBool) +JS_CallFunctionValue(JSContext *cx, JSObject *obj, jsval fval, uintN argc, + jsval *argv, jsval *rval) +{ + CHECK_REQUEST(cx); + if (!js_InternalCall(cx, obj, fval, argc, argv, rval)) { +#if JS_HAS_EXCEPTIONS + if (!cx->fp) + js_ReportUncaughtException(cx); +#endif + return JS_FALSE; + } + return JS_TRUE; +} + +JS_PUBLIC_API(JSBranchCallback) +JS_SetBranchCallback(JSContext *cx, JSBranchCallback cb) +{ + JSBranchCallback oldcb; + + oldcb = cx->branchCallback; + cx->branchCallback = cb; + return oldcb; +} + +JS_PUBLIC_API(JSBool) +JS_IsRunning(JSContext *cx) +{ + return cx->fp != NULL; +} + +JS_PUBLIC_API(JSBool) +JS_IsConstructing(JSContext *cx) +{ + return cx->fp && (cx->fp->flags & JSFRAME_CONSTRUCTING); +} + +JS_FRIEND_API(JSBool) +JS_IsAssigning(JSContext *cx) +{ + JSStackFrame *fp; + jsbytecode *pc; + + for (fp = cx->fp; fp && !fp->script; fp = fp->down) + continue; + if (!fp || !(pc = fp->pc)) + return JS_FALSE; + return (js_CodeSpec[*pc].format & JOF_ASSIGNING) != 0; +} + +JS_PUBLIC_API(void) +JS_SetCallReturnValue2(JSContext *cx, jsval v) +{ +#if JS_HAS_LVALUE_RETURN + cx->rval2 = v; + cx->rval2set = JS_TRUE; +#endif +} + +/************************************************************************/ + +JS_PUBLIC_API(JSString *) +JS_NewString(JSContext *cx, char *bytes, size_t length) +{ + jschar *chars; + JSString *str; + + CHECK_REQUEST(cx); + /* Make a Unicode vector from the 8-bit char codes in bytes. */ + chars = js_InflateString(cx, bytes, length); + if (!chars) + return NULL; + + /* Free chars (but not bytes, which caller frees on error) if we fail. */ + str = js_NewString(cx, chars, length, 0); + if (!str) { + JS_free(cx, chars); + return NULL; + } + + /* Hand off bytes to the deflated string cache, if possible. */ + if (!js_SetStringBytes(str, bytes, length)) + JS_free(cx, bytes); + return str; +} + +JS_PUBLIC_API(JSString *) +JS_NewStringCopyN(JSContext *cx, const char *s, size_t n) +{ + jschar *js; + JSString *str; + + CHECK_REQUEST(cx); + js = js_InflateString(cx, s, n); + if (!js) + return NULL; + str = js_NewString(cx, js, n, 0); + if (!str) + JS_free(cx, js); + return str; +} + +JS_PUBLIC_API(JSString *) +JS_NewStringCopyZ(JSContext *cx, const char *s) +{ + size_t n; + jschar *js; + JSString *str; + + CHECK_REQUEST(cx); + if (!s) + return cx->runtime->emptyString; + n = strlen(s); + js = js_InflateString(cx, s, n); + if (!js) + return NULL; + str = js_NewString(cx, js, n, 0); + if (!str) + JS_free(cx, js); + return str; +} + +JS_PUBLIC_API(JSString *) +JS_InternString(JSContext *cx, const char *s) +{ + JSAtom *atom; + + CHECK_REQUEST(cx); + atom = js_Atomize(cx, s, strlen(s), ATOM_INTERNED); + if (!atom) + return NULL; + return ATOM_TO_STRING(atom); +} + +JS_PUBLIC_API(JSString *) +JS_NewUCString(JSContext *cx, jschar *chars, size_t length) +{ + CHECK_REQUEST(cx); + return js_NewString(cx, chars, length, 0); +} + +JS_PUBLIC_API(JSString *) +JS_NewUCStringCopyN(JSContext *cx, const jschar *s, size_t n) +{ + CHECK_REQUEST(cx); + return js_NewStringCopyN(cx, s, n, 0); +} + +JS_PUBLIC_API(JSString *) +JS_NewUCStringCopyZ(JSContext *cx, const jschar *s) +{ + CHECK_REQUEST(cx); + if (!s) + return cx->runtime->emptyString; + return js_NewStringCopyZ(cx, s, 0); +} + +JS_PUBLIC_API(JSString *) +JS_InternUCStringN(JSContext *cx, const jschar *s, size_t length) +{ + JSAtom *atom; + + CHECK_REQUEST(cx); + atom = js_AtomizeChars(cx, s, length, ATOM_INTERNED); + if (!atom) + return NULL; + return ATOM_TO_STRING(atom); +} + +JS_PUBLIC_API(JSString *) +JS_InternUCString(JSContext *cx, const jschar *s) +{ + return JS_InternUCStringN(cx, s, js_strlen(s)); +} + +JS_PUBLIC_API(char *) +JS_GetStringBytes(JSString *str) +{ + char *bytes; + + bytes = js_GetStringBytes(str); + return bytes ? bytes : ""; +} + +JS_PUBLIC_API(jschar *) +JS_GetStringChars(JSString *str) +{ + /* + * API botch (again, shades of JS_GetStringBytes): we have no cx to pass + * to js_UndependString (called by js_GetStringChars) for out-of-memory + * error reports, so js_UndependString passes NULL and suppresses errors. + * If it fails to convert a dependent string into an independent one, our + * caller will not be guaranteed a \u0000 terminator as a backstop. This + * may break some clients who already misbehave on embedded NULs. + * + * The gain of dependent strings, which cure quadratic and cubic growth + * rate bugs in string concatenation, is worth this slight loss in API + * compatibility. + */ + jschar *chars; + + chars = js_GetStringChars(str); + return chars ? chars : JSSTRING_CHARS(str); +} + +JS_PUBLIC_API(size_t) +JS_GetStringLength(JSString *str) +{ + return JSSTRING_LENGTH(str); +} + +JS_PUBLIC_API(intN) +JS_CompareStrings(JSString *str1, JSString *str2) +{ + return js_CompareStrings(str1, str2); +} + +JS_PUBLIC_API(JSString *) +JS_NewGrowableString(JSContext *cx, jschar *chars, size_t length) +{ + CHECK_REQUEST(cx); + return js_NewString(cx, chars, length, GCF_MUTABLE); +} + +JS_PUBLIC_API(JSString *) +JS_NewDependentString(JSContext *cx, JSString *str, size_t start, + size_t length) +{ + CHECK_REQUEST(cx); + return js_NewDependentString(cx, str, start, length, 0); +} + +JS_PUBLIC_API(JSString *) +JS_ConcatStrings(JSContext *cx, JSString *left, JSString *right) +{ + CHECK_REQUEST(cx); + return js_ConcatStrings(cx, left, right); +} + +JS_PUBLIC_API(const jschar *) +JS_UndependString(JSContext *cx, JSString *str) +{ + CHECK_REQUEST(cx); + return js_UndependString(cx, str); +} + +JS_PUBLIC_API(JSBool) +JS_MakeStringImmutable(JSContext *cx, JSString *str) +{ + CHECK_REQUEST(cx); + if (!js_UndependString(cx, str)) + return JS_FALSE; + + *js_GetGCThingFlags(str) &= ~GCF_MUTABLE; + return JS_TRUE; +} + +/************************************************************************/ + +JS_PUBLIC_API(void) +JS_ReportError(JSContext *cx, const char *format, ...) +{ + va_list ap; + + va_start(ap, format); + js_ReportErrorVA(cx, JSREPORT_ERROR, format, ap); + va_end(ap); +} + +JS_PUBLIC_API(void) +JS_ReportErrorNumber(JSContext *cx, JSErrorCallback errorCallback, + void *userRef, const uintN errorNumber, ...) +{ + va_list ap; + + va_start(ap, errorNumber); + js_ReportErrorNumberVA(cx, JSREPORT_ERROR, errorCallback, userRef, + errorNumber, JS_TRUE, ap); + va_end(ap); +} + +JS_PUBLIC_API(void) +JS_ReportErrorNumberUC(JSContext *cx, JSErrorCallback errorCallback, + void *userRef, const uintN errorNumber, ...) +{ + va_list ap; + + va_start(ap, errorNumber); + js_ReportErrorNumberVA(cx, JSREPORT_ERROR, errorCallback, userRef, + errorNumber, JS_FALSE, ap); + va_end(ap); +} + +JS_PUBLIC_API(JSBool) +JS_ReportWarning(JSContext *cx, const char *format, ...) +{ + va_list ap; + JSBool ok; + + va_start(ap, format); + ok = js_ReportErrorVA(cx, JSREPORT_WARNING, format, ap); + va_end(ap); + return ok; +} + +JS_PUBLIC_API(JSBool) +JS_ReportErrorFlagsAndNumber(JSContext *cx, uintN flags, + JSErrorCallback errorCallback, void *userRef, + const uintN errorNumber, ...) +{ + va_list ap; + JSBool ok; + + va_start(ap, errorNumber); + ok = js_ReportErrorNumberVA(cx, flags, errorCallback, userRef, + errorNumber, JS_TRUE, ap); + va_end(ap); + return ok; +} + +JS_PUBLIC_API(JSBool) +JS_ReportErrorFlagsAndNumberUC(JSContext *cx, uintN flags, + JSErrorCallback errorCallback, void *userRef, + const uintN errorNumber, ...) +{ + va_list ap; + JSBool ok; + + va_start(ap, errorNumber); + ok = js_ReportErrorNumberVA(cx, flags, errorCallback, userRef, + errorNumber, JS_FALSE, ap); + va_end(ap); + return ok; +} + +JS_PUBLIC_API(void) +JS_ReportOutOfMemory(JSContext *cx) +{ + js_ReportOutOfMemory(cx, js_GetErrorMessage); +} + +JS_PUBLIC_API(JSErrorReporter) +JS_SetErrorReporter(JSContext *cx, JSErrorReporter er) +{ + JSErrorReporter older; + + older = cx->errorReporter; + cx->errorReporter = er; + return older; +} + +/************************************************************************/ + +/* + * Regular Expressions. + */ +JS_PUBLIC_API(JSObject *) +JS_NewRegExpObject(JSContext *cx, char *bytes, size_t length, uintN flags) +{ +#if JS_HAS_REGEXPS + jschar *chars; + JSObject *obj; + + CHECK_REQUEST(cx); + chars = js_InflateString(cx, bytes, length); + if (!chars) + return NULL; + obj = js_NewRegExpObject(cx, NULL, chars, length, flags); + JS_free(cx, chars); + return obj; +#else + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_NO_REG_EXPS); + return NULL; +#endif +} + +JS_PUBLIC_API(JSObject *) +JS_NewUCRegExpObject(JSContext *cx, jschar *chars, size_t length, uintN flags) +{ + CHECK_REQUEST(cx); +#if JS_HAS_REGEXPS + return js_NewRegExpObject(cx, NULL, chars, length, flags); +#else + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_NO_REG_EXPS); + return NULL; +#endif +} + +JS_PUBLIC_API(void) +JS_SetRegExpInput(JSContext *cx, JSString *input, JSBool multiline) +{ + JSRegExpStatics *res; + + CHECK_REQUEST(cx); + /* No locking required, cx is thread-private and input must be live. */ + res = &cx->regExpStatics; + res->input = input; + res->multiline = multiline; + cx->runtime->gcPoke = JS_TRUE; +} + +JS_PUBLIC_API(void) +JS_ClearRegExpStatics(JSContext *cx) +{ + JSRegExpStatics *res; + + /* No locking required, cx is thread-private and input must be live. */ + res = &cx->regExpStatics; + res->input = NULL; + res->multiline = JS_FALSE; + res->parenCount = 0; + res->lastMatch = res->lastParen = js_EmptySubString; + res->leftContext = res->rightContext = js_EmptySubString; + cx->runtime->gcPoke = JS_TRUE; +} + +JS_PUBLIC_API(void) +JS_ClearRegExpRoots(JSContext *cx) +{ + JSRegExpStatics *res; + + /* No locking required, cx is thread-private and input must be live. */ + res = &cx->regExpStatics; + res->input = NULL; + cx->runtime->gcPoke = JS_TRUE; +} + +/* TODO: compile, execute, get/set other statics... */ + +/************************************************************************/ + +JS_PUBLIC_API(void) +JS_SetLocaleCallbacks(JSContext *cx, JSLocaleCallbacks *callbacks) +{ + cx->localeCallbacks = callbacks; +} + +JS_PUBLIC_API(JSLocaleCallbacks *) +JS_GetLocaleCallbacks(JSContext *cx) +{ + return cx->localeCallbacks; +} + +/************************************************************************/ + +JS_PUBLIC_API(JSBool) +JS_IsExceptionPending(JSContext *cx) +{ +#if JS_HAS_EXCEPTIONS + return (JSBool) cx->throwing; +#else + return JS_FALSE; +#endif +} + +JS_PUBLIC_API(JSBool) +JS_GetPendingException(JSContext *cx, jsval *vp) +{ +#if JS_HAS_EXCEPTIONS + CHECK_REQUEST(cx); + if (!cx->throwing) + return JS_FALSE; + *vp = cx->exception; + return JS_TRUE; +#else + return JS_FALSE; +#endif +} + +JS_PUBLIC_API(void) +JS_SetPendingException(JSContext *cx, jsval v) +{ + CHECK_REQUEST(cx); +#if JS_HAS_EXCEPTIONS + cx->throwing = JS_TRUE; + cx->exception = v; +#endif +} + +JS_PUBLIC_API(void) +JS_ClearPendingException(JSContext *cx) +{ +#if JS_HAS_EXCEPTIONS + cx->throwing = JS_FALSE; + cx->exception = JSVAL_VOID; +#endif +} + +#if JS_HAS_EXCEPTIONS +struct JSExceptionState { + JSBool throwing; + jsval exception; +}; +#endif + +JS_PUBLIC_API(JSExceptionState *) +JS_SaveExceptionState(JSContext *cx) +{ +#if JS_HAS_EXCEPTIONS + JSExceptionState *state; + + CHECK_REQUEST(cx); + state = (JSExceptionState *) JS_malloc(cx, sizeof(JSExceptionState)); + if (state) { + state->throwing = JS_GetPendingException(cx, &state->exception); + if (state->throwing && JSVAL_IS_GCTHING(state->exception)) + js_AddRoot(cx, &state->exception, "JSExceptionState.exception"); + } + return state; +#else + return NULL; +#endif +} + +JS_PUBLIC_API(void) +JS_RestoreExceptionState(JSContext *cx, JSExceptionState *state) +{ +#if JS_HAS_EXCEPTIONS + CHECK_REQUEST(cx); + if (state) { + if (state->throwing) + JS_SetPendingException(cx, state->exception); + else + JS_ClearPendingException(cx); + JS_DropExceptionState(cx, state); + } +#endif +} + +JS_PUBLIC_API(void) +JS_DropExceptionState(JSContext *cx, JSExceptionState *state) +{ +#if JS_HAS_EXCEPTIONS + CHECK_REQUEST(cx); + if (state) { + if (state->throwing && JSVAL_IS_GCTHING(state->exception)) + JS_RemoveRoot(cx, &state->exception); + JS_free(cx, state); + } +#endif +} + +JS_PUBLIC_API(JSErrorReport *) +JS_ErrorFromException(JSContext *cx, jsval v) +{ +#if JS_HAS_EXCEPTIONS + CHECK_REQUEST(cx); + return js_ErrorFromException(cx, v); +#else + return NULL; +#endif +} + +#ifdef JS_THREADSAFE +JS_PUBLIC_API(jsword) +JS_GetContextThread(JSContext *cx) +{ + return cx->thread; +} + +JS_PUBLIC_API(jsword) +JS_SetContextThread(JSContext *cx) +{ + intN old = cx->thread; + cx->thread = js_CurrentThreadId(); + return old; +} + +JS_PUBLIC_API(intN) +JS_ClearContextThread(JSContext *cx) +{ + intN old = cx->thread; + cx->thread = 0; + return old; +} +#endif + +/************************************************************************/ + +#if defined(XP_WIN) +#include +/* + * Initialization routine for the JS DLL... + */ + +/* + * Global Instance handle... + * In Win32 this is the module handle of the DLL. + * + * In Win16 this is the instance handle of the application + * which loaded the DLL. + */ + +#ifdef _WIN32 +BOOL WINAPI DllMain (HINSTANCE hDLL, DWORD dwReason, LPVOID lpReserved) +{ + return TRUE; +} + +#else /* !_WIN32 */ + +int CALLBACK LibMain( HINSTANCE hInst, WORD wDataSeg, + WORD cbHeapSize, LPSTR lpszCmdLine ) +{ + return TRUE; +} + +BOOL CALLBACK __loadds WEP(BOOL fSystemExit) +{ + return TRUE; +} + +#endif /* !_WIN32 */ +#endif /* XP_WIN */ diff --git a/src/dom/js/jsapi.h b/src/dom/js/jsapi.h new file mode 100644 index 000000000..92b4e1d59 --- /dev/null +++ b/src/dom/js/jsapi.h @@ -0,0 +1,1752 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef jsapi_h___ +#define jsapi_h___ +/* + * JavaScript API. + */ +#include +#include +#include "jspubtd.h" + +JS_BEGIN_EXTERN_C + +/* + * Type tags stored in the low bits of a jsval. + */ +#define JSVAL_OBJECT 0x0 /* untagged reference to object */ +#define JSVAL_INT 0x1 /* tagged 31-bit integer value */ +#define JSVAL_DOUBLE 0x2 /* tagged reference to double */ +#define JSVAL_STRING 0x4 /* tagged reference to string */ +#define JSVAL_BOOLEAN 0x6 /* tagged boolean value */ + +/* Type tag bitfield length and derived macros. */ +#define JSVAL_TAGBITS 3 +#define JSVAL_TAGMASK JS_BITMASK(JSVAL_TAGBITS) +#define JSVAL_TAG(v) ((v) & JSVAL_TAGMASK) +#define JSVAL_SETTAG(v,t) ((v) | (t)) +#define JSVAL_CLRTAG(v) ((v) & ~(jsval)JSVAL_TAGMASK) +#define JSVAL_ALIGN JS_BIT(JSVAL_TAGBITS) + +/* Predicates for type testing. */ +#define JSVAL_IS_OBJECT(v) (JSVAL_TAG(v) == JSVAL_OBJECT) +#define JSVAL_IS_NUMBER(v) (JSVAL_IS_INT(v) || JSVAL_IS_DOUBLE(v)) +#define JSVAL_IS_INT(v) (((v) & JSVAL_INT) && (v) != JSVAL_VOID) +#define JSVAL_IS_DOUBLE(v) (JSVAL_TAG(v) == JSVAL_DOUBLE) +#define JSVAL_IS_STRING(v) (JSVAL_TAG(v) == JSVAL_STRING) +#define JSVAL_IS_BOOLEAN(v) (JSVAL_TAG(v) == JSVAL_BOOLEAN) +#define JSVAL_IS_NULL(v) ((v) == JSVAL_NULL) +#define JSVAL_IS_VOID(v) ((v) == JSVAL_VOID) +#define JSVAL_IS_PRIMITIVE(v) (!JSVAL_IS_OBJECT(v) || JSVAL_IS_NULL(v)) + +/* Objects, strings, and doubles are GC'ed. */ +#define JSVAL_IS_GCTHING(v) (!((v) & JSVAL_INT) && !JSVAL_IS_BOOLEAN(v)) +#define JSVAL_TO_GCTHING(v) ((void *)JSVAL_CLRTAG(v)) +#define JSVAL_TO_OBJECT(v) ((JSObject *)JSVAL_TO_GCTHING(v)) +#define JSVAL_TO_DOUBLE(v) ((jsdouble *)JSVAL_TO_GCTHING(v)) +#define JSVAL_TO_STRING(v) ((JSString *)JSVAL_TO_GCTHING(v)) +#define OBJECT_TO_JSVAL(obj) ((jsval)(obj)) +#define DOUBLE_TO_JSVAL(dp) JSVAL_SETTAG((jsval)(dp), JSVAL_DOUBLE) +#define STRING_TO_JSVAL(str) JSVAL_SETTAG((jsval)(str), JSVAL_STRING) + +/* Lock and unlock the GC thing held by a jsval. */ +#define JSVAL_LOCK(cx,v) (JSVAL_IS_GCTHING(v) \ + ? JS_LockGCThing(cx, JSVAL_TO_GCTHING(v)) \ + : JS_TRUE) +#define JSVAL_UNLOCK(cx,v) (JSVAL_IS_GCTHING(v) \ + ? JS_UnlockGCThing(cx, JSVAL_TO_GCTHING(v)) \ + : JS_TRUE) + +/* Domain limits for the jsval int type. */ +#define JSVAL_INT_BITS 31 +#define JSVAL_INT_POW2(n) ((jsval)1 << (n)) +#define JSVAL_INT_MIN ((jsval)1 - JSVAL_INT_POW2(30)) +#define JSVAL_INT_MAX (JSVAL_INT_POW2(30) - 1) +#define INT_FITS_IN_JSVAL(i) ((jsuint)((i)+JSVAL_INT_MAX) <= 2*JSVAL_INT_MAX) +#define JSVAL_TO_INT(v) ((jsint)(v) >> 1) +#define INT_TO_JSVAL(i) (((jsval)(i) << 1) | JSVAL_INT) + +/* Convert between boolean and jsval. */ +#define JSVAL_TO_BOOLEAN(v) ((JSBool)((v) >> JSVAL_TAGBITS)) +#define BOOLEAN_TO_JSVAL(b) JSVAL_SETTAG((jsval)(b) << JSVAL_TAGBITS, \ + JSVAL_BOOLEAN) + +/* A private data pointer (2-byte-aligned) can be stored as an int jsval. */ +#define JSVAL_TO_PRIVATE(v) ((void *)((v) & ~JSVAL_INT)) +#define PRIVATE_TO_JSVAL(p) ((jsval)(p) | JSVAL_INT) + +/* Property attributes, set in JSPropertySpec and passed to API functions. */ +#define JSPROP_ENUMERATE 0x01 /* property is visible to for/in loop */ +#define JSPROP_READONLY 0x02 /* not settable: assignment is no-op */ +#define JSPROP_PERMANENT 0x04 /* property cannot be deleted */ +#define JSPROP_EXPORTED 0x08 /* property is exported from object */ +#define JSPROP_GETTER 0x10 /* property holds getter function */ +#define JSPROP_SETTER 0x20 /* property holds setter function */ +#define JSPROP_SHARED 0x40 /* don't allocate a value slot for this + property; don't copy the property on + set of the same-named property in an + object that delegates to a prototype + containing this property */ +#define JSPROP_INDEX 0x80 /* name is actually (jsint) index */ + +/* Function flags, set in JSFunctionSpec and passed to JS_NewFunction etc. */ +#define JSFUN_LAMBDA 0x08 /* expressed, not declared, function */ +#define JSFUN_GETTER JSPROP_GETTER +#define JSFUN_SETTER JSPROP_SETTER +#define JSFUN_BOUND_METHOD 0x40 /* bind this to fun->object's parent */ +#define JSFUN_HEAVYWEIGHT 0x80 /* activation requires a Call object */ +#define JSFUN_FLAGS_MASK 0xf8 /* overlay JSFUN_* attributes */ + +/* + * Well-known JS values. The extern'd variables are initialized when the + * first JSContext is created by JS_NewContext (see below). + */ +#define JSVAL_VOID INT_TO_JSVAL(0 - JSVAL_INT_POW2(30)) +#define JSVAL_NULL OBJECT_TO_JSVAL(0) +#define JSVAL_ZERO INT_TO_JSVAL(0) +#define JSVAL_ONE INT_TO_JSVAL(1) +#define JSVAL_FALSE BOOLEAN_TO_JSVAL(JS_FALSE) +#define JSVAL_TRUE BOOLEAN_TO_JSVAL(JS_TRUE) + +/* + * Microseconds since the epoch, midnight, January 1, 1970 UTC. See the + * comment in jstypes.h regarding safe int64 usage. + */ +extern JS_PUBLIC_API(int64) +JS_Now(); + +/* Don't want to export data, so provide accessors for non-inline jsvals. */ +extern JS_PUBLIC_API(jsval) +JS_GetNaNValue(JSContext *cx); + +extern JS_PUBLIC_API(jsval) +JS_GetNegativeInfinityValue(JSContext *cx); + +extern JS_PUBLIC_API(jsval) +JS_GetPositiveInfinityValue(JSContext *cx); + +extern JS_PUBLIC_API(jsval) +JS_GetEmptyStringValue(JSContext *cx); + +/* + * Format is a string of the following characters (spaces are insignificant), + * specifying the tabulated type conversions: + * + * b JSBool Boolean + * c uint16/jschar ECMA uint16, Unicode char + * i int32 ECMA int32 + * u uint32 ECMA uint32 + * j int32 Rounded int32 (coordinate) + * d jsdouble IEEE double + * I jsdouble Integral IEEE double + * s char * C string + * S JSString * Unicode string, accessed by a JSString pointer + * W jschar * Unicode character vector, 0-terminated (W for wide) + * o JSObject * Object reference + * f JSFunction * Function private + * v jsval Argument value (no conversion) + * * N/A Skip this argument (no vararg) + * / N/A End of required arguments + * + * The variable argument list after format must consist of &b, &c, &s, e.g., + * where those variables have the types given above. For the pointer types + * char *, JSString *, and JSObject *, the pointed-at memory returned belongs + * to the JS runtime, not to the calling native code. The runtime promises + * to keep this memory valid so long as argv refers to allocated stack space + * (so long as the native function is active). + * + * Fewer arguments than format specifies may be passed only if there is a / + * in format after the last required argument specifier and argc is at least + * the number of required arguments. More arguments than format specifies + * may be passed without error; it is up to the caller to deal with trailing + * unconverted arguments. + */ +extern JS_PUBLIC_API(JSBool) +JS_ConvertArguments(JSContext *cx, uintN argc, jsval *argv, const char *format, + ...); + +#ifdef va_start +extern JS_PUBLIC_API(JSBool) +JS_ConvertArgumentsVA(JSContext *cx, uintN argc, jsval *argv, + const char *format, va_list ap); +#endif + +/* + * Inverse of JS_ConvertArguments: scan format and convert trailing arguments + * into jsvals, GC-rooted if necessary by the JS stack. Return null on error, + * and a pointer to the new argument vector on success. Also return a stack + * mark on success via *markp, in which case the caller must eventually clean + * up by calling JS_PopArguments. + * + * Note that the number of actual arguments supplied is specified exclusively + * by format, so there is no argc parameter. + */ +extern JS_PUBLIC_API(jsval *) +JS_PushArguments(JSContext *cx, void **markp, const char *format, ...); + +#ifdef va_start +extern JS_PUBLIC_API(jsval *) +JS_PushArgumentsVA(JSContext *cx, void **markp, const char *format, va_list ap); +#endif + +extern JS_PUBLIC_API(void) +JS_PopArguments(JSContext *cx, void *mark); + +#ifdef JS_ARGUMENT_FORMATTER_DEFINED + +/* + * Add and remove a format string handler for JS_{Convert,Push}Arguments{,VA}. + * The handler function has this signature (see jspubtd.h): + * + * JSBool MyArgumentFormatter(JSContext *cx, const char *format, + * JSBool fromJS, jsval **vpp, va_list *app); + * + * It should return true on success, and return false after reporting an error + * or detecting an already-reported error. + * + * For a given format string, for example "AA", the formatter is called from + * JS_ConvertArgumentsVA like so: + * + * formatter(cx, "AA...", JS_TRUE, &sp, &ap); + * + * sp points into the arguments array on the JS stack, while ap points into + * the stdarg.h va_list on the C stack. The JS_TRUE passed for fromJS tells + * the formatter to convert zero or more jsvals at sp to zero or more C values + * accessed via pointers-to-values at ap, updating both sp (via *vpp) and ap + * (via *app) to point past the converted arguments and their result pointers + * on the C stack. + * + * When called from JS_PushArgumentsVA, the formatter is invoked thus: + * + * formatter(cx, "AA...", JS_FALSE, &sp, &ap); + * + * where JS_FALSE for fromJS means to wrap the C values at ap according to the + * format specifier and store them at sp, updating ap and sp appropriately. + * + * The "..." after "AA" is the rest of the format string that was passed into + * JS_{Convert,Push}Arguments{,VA}. The actual format trailing substring used + * in each Convert or PushArguments call is passed to the formatter, so that + * one such function may implement several formats, in order to share code. + * + * Remove just forgets about any handler associated with format. Add does not + * copy format, it points at the string storage allocated by the caller, which + * is typically a string constant. If format is in dynamic storage, it is up + * to the caller to keep the string alive until Remove is called. + */ +extern JS_PUBLIC_API(JSBool) +JS_AddArgumentFormatter(JSContext *cx, const char *format, + JSArgumentFormatter formatter); + +extern JS_PUBLIC_API(void) +JS_RemoveArgumentFormatter(JSContext *cx, const char *format); + +#endif /* JS_ARGUMENT_FORMATTER_DEFINED */ + +extern JS_PUBLIC_API(JSBool) +JS_ConvertValue(JSContext *cx, jsval v, JSType type, jsval *vp); + +extern JS_PUBLIC_API(JSBool) +JS_ValueToObject(JSContext *cx, jsval v, JSObject **objp); + +extern JS_PUBLIC_API(JSFunction *) +JS_ValueToFunction(JSContext *cx, jsval v); + +extern JS_PUBLIC_API(JSFunction *) +JS_ValueToConstructor(JSContext *cx, jsval v); + +extern JS_PUBLIC_API(JSString *) +JS_ValueToString(JSContext *cx, jsval v); + +extern JS_PUBLIC_API(JSBool) +JS_ValueToNumber(JSContext *cx, jsval v, jsdouble *dp); + +/* + * Convert a value to a number, then to an int32, according to the ECMA rules + * for ToInt32. + */ +extern JS_PUBLIC_API(JSBool) +JS_ValueToECMAInt32(JSContext *cx, jsval v, int32 *ip); + +/* + * Convert a value to a number, then to a uint32, according to the ECMA rules + * for ToUint32. + */ +extern JS_PUBLIC_API(JSBool) +JS_ValueToECMAUint32(JSContext *cx, jsval v, uint32 *ip); + +/* + * Convert a value to a number, then to an int32 if it fits by rounding to + * nearest; but failing with an error report if the double is out of range + * or unordered. + */ +extern JS_PUBLIC_API(JSBool) +JS_ValueToInt32(JSContext *cx, jsval v, int32 *ip); + +/* + * ECMA ToUint16, for mapping a jsval to a Unicode point. + */ +extern JS_PUBLIC_API(JSBool) +JS_ValueToUint16(JSContext *cx, jsval v, uint16 *ip); + +extern JS_PUBLIC_API(JSBool) +JS_ValueToBoolean(JSContext *cx, jsval v, JSBool *bp); + +extern JS_PUBLIC_API(JSType) +JS_TypeOfValue(JSContext *cx, jsval v); + +extern JS_PUBLIC_API(const char *) +JS_GetTypeName(JSContext *cx, JSType type); + +/************************************************************************/ + +/* + * Initialization, locking, contexts, and memory allocation. + */ +#define JS_NewRuntime JS_Init +#define JS_DestroyRuntime JS_Finish +#define JS_LockRuntime JS_Lock +#define JS_UnlockRuntime JS_Unlock + +extern JS_PUBLIC_API(JSRuntime *) +JS_NewRuntime(uint32 maxbytes); + +extern JS_PUBLIC_API(void) +JS_DestroyRuntime(JSRuntime *rt); + +extern JS_PUBLIC_API(void) +JS_ShutDown(void); + +JS_PUBLIC_API(void *) +JS_GetRuntimePrivate(JSRuntime *rt); + +JS_PUBLIC_API(void) +JS_SetRuntimePrivate(JSRuntime *rt, void *data); + +#ifdef JS_THREADSAFE + +extern JS_PUBLIC_API(void) +JS_BeginRequest(JSContext *cx); + +extern JS_PUBLIC_API(void) +JS_EndRequest(JSContext *cx); + +/* Yield to pending GC operations, regardless of request depth */ +extern JS_PUBLIC_API(void) +JS_YieldRequest(JSContext *cx); + +extern JS_PUBLIC_API(jsrefcount) +JS_SuspendRequest(JSContext *cx); + +extern JS_PUBLIC_API(void) +JS_ResumeRequest(JSContext *cx, jsrefcount saveDepth); + +#endif /* JS_THREADSAFE */ + +extern JS_PUBLIC_API(void) +JS_Lock(JSRuntime *rt); + +extern JS_PUBLIC_API(void) +JS_Unlock(JSRuntime *rt); + +extern JS_PUBLIC_API(JSContext *) +JS_NewContext(JSRuntime *rt, size_t stackChunkSize); + +extern JS_PUBLIC_API(void) +JS_DestroyContext(JSContext *cx); + +extern JS_PUBLIC_API(void) +JS_DestroyContextNoGC(JSContext *cx); + +extern JS_PUBLIC_API(void) +JS_DestroyContextMaybeGC(JSContext *cx); + +extern JS_PUBLIC_API(void *) +JS_GetContextPrivate(JSContext *cx); + +extern JS_PUBLIC_API(void) +JS_SetContextPrivate(JSContext *cx, void *data); + +extern JS_PUBLIC_API(JSRuntime *) +JS_GetRuntime(JSContext *cx); + +extern JS_PUBLIC_API(JSContext *) +JS_ContextIterator(JSRuntime *rt, JSContext **iterp); + +extern JS_PUBLIC_API(JSVersion) +JS_GetVersion(JSContext *cx); + +extern JS_PUBLIC_API(JSVersion) +JS_SetVersion(JSContext *cx, JSVersion version); + +extern JS_PUBLIC_API(const char *) +JS_VersionToString(JSVersion version); + +extern JS_PUBLIC_API(JSVersion) +JS_StringToVersion(const char *string); + +/* + * JS options are orthogonal to version, and may be freely composed with one + * another as well as with version. + * + * JSOPTION_VAROBJFIX is recommended -- see the comments associated with the + * prototypes for JS_ExecuteScript, JS_EvaluateScript, etc. + */ +#define JSOPTION_STRICT JS_BIT(0) /* warn on dubious practice */ +#define JSOPTION_WERROR JS_BIT(1) /* convert warning to error */ +#define JSOPTION_VAROBJFIX JS_BIT(2) /* make JS_EvaluateScript use + the last object on its 'obj' + param's scope chain as the + ECMA 'variables object' */ +#define JSOPTION_PRIVATE_IS_NSISUPPORTS \ + JS_BIT(3) /* context private data points + to an nsISupports subclass */ + +extern JS_PUBLIC_API(uint32) +JS_GetOptions(JSContext *cx); + +extern JS_PUBLIC_API(uint32) +JS_SetOptions(JSContext *cx, uint32 options); + +extern JS_PUBLIC_API(uint32) +JS_ToggleOptions(JSContext *cx, uint32 options); + +extern JS_PUBLIC_API(const char *) +JS_GetImplementationVersion(void); + +extern JS_PUBLIC_API(JSObject *) +JS_GetGlobalObject(JSContext *cx); + +extern JS_PUBLIC_API(void) +JS_SetGlobalObject(JSContext *cx, JSObject *obj); + +/* + * Initialize standard JS class constructors, prototypes, and any top-level + * functions and constants associated with the standard classes (e.g. isNaN + * for Number). + * + * NB: This sets cx's global object to obj if it was null. + */ +extern JS_PUBLIC_API(JSBool) +JS_InitStandardClasses(JSContext *cx, JSObject *obj); + +/* + * Resolve id, which must contain either a string or an int, to a standard + * class name in obj if possible, defining the class's constructor and/or + * prototype and storing true in *resolved. If id does not name a standard + * class or a top-level property induced by initializing a standard class, + * store false in *resolved and just return true. Return false on error, + * as usual for JSBool result-typed API entry points. + * + * This API can be called directly from a global object class's resolve op, + * to define standard classes lazily. The class's enumerate op should call + * JS_EnumerateStandardClasses(cx, obj), to define eagerly during for..in + * loops any classes not yet resolved lazily. + */ +extern JS_PUBLIC_API(JSBool) +JS_ResolveStandardClass(JSContext *cx, JSObject *obj, jsval id, + JSBool *resolved); + +extern JS_PUBLIC_API(JSBool) +JS_EnumerateStandardClasses(JSContext *cx, JSObject *obj); + +extern JS_PUBLIC_API(JSObject *) +JS_GetScopeChain(JSContext *cx); + +extern JS_PUBLIC_API(void *) +JS_malloc(JSContext *cx, size_t nbytes); + +extern JS_PUBLIC_API(void *) +JS_realloc(JSContext *cx, void *p, size_t nbytes); + +extern JS_PUBLIC_API(void) +JS_free(JSContext *cx, void *p); + +extern JS_PUBLIC_API(char *) +JS_strdup(JSContext *cx, const char *s); + +extern JS_PUBLIC_API(jsdouble *) +JS_NewDouble(JSContext *cx, jsdouble d); + +extern JS_PUBLIC_API(JSBool) +JS_NewDoubleValue(JSContext *cx, jsdouble d, jsval *rval); + +extern JS_PUBLIC_API(JSBool) +JS_NewNumberValue(JSContext *cx, jsdouble d, jsval *rval); + +/* + * A JS GC root is a pointer to a JSObject *, JSString *, or jsdouble * that + * itself points into the GC heap (more recently, we support this extension: + * a root may be a pointer to a jsval v for which JSVAL_IS_GCTHING(v) is true). + * + * Therefore, you never pass JSObject *obj to JS_AddRoot(cx, obj). You always + * call JS_AddRoot(cx, &obj), passing obj by reference. And later, before obj + * or the structure it is embedded within goes out of scope or is freed, you + * must call JS_RemoveRoot(cx, &obj). + * + * Also, use JS_AddNamedRoot(cx, &structPtr->memberObj, "structPtr->memberObj") + * in preference to JS_AddRoot(cx, &structPtr->memberObj), in order to identify + * roots by their source callsites. This way, you can find the callsite while + * debugging if you should fail to do JS_RemoveRoot(cx, &structPtr->memberObj) + * before freeing structPtr's memory. + */ +extern JS_PUBLIC_API(JSBool) +JS_AddRoot(JSContext *cx, void *rp); + +#ifdef NAME_ALL_GC_ROOTS +#define JS_DEFINE_TO_TOKEN(def) #def +#define JS_DEFINE_TO_STRING(def) JS_DEFINE_TO_TOKEN(def) +#define JS_AddRoot(cx,rp) JS_AddNamedRoot((cx), (rp), (__FILE__ ":" JS_TOKEN_TO_STRING(__LINE__)) +#endif + +extern JS_PUBLIC_API(JSBool) +JS_AddNamedRoot(JSContext *cx, void *rp, const char *name); + +extern JS_PUBLIC_API(JSBool) +JS_AddNamedRootRT(JSRuntime *rt, void *rp, const char *name); + +extern JS_PUBLIC_API(JSBool) +JS_RemoveRoot(JSContext *cx, void *rp); + +extern JS_PUBLIC_API(JSBool) +JS_RemoveRootRT(JSRuntime *rt, void *rp); + +/* + * The last GC thing of each type (object, string, double, external string + * types) created on a given context is kept alive until another thing of the + * same type is created, using a newborn root in the context. These newborn + * roots help native code protect newly-created GC-things from GC invocations + * activated before those things can be rooted using local or global roots. + * + * However, the newborn roots can also entrain great gobs of garbage, so the + * JS_GC entry point clears them for the context on which GC is being forced. + * Embeddings may need to do likewise for all contexts. + * + * XXXbe See bug 40757 (http://bugzilla.mozilla.org/show_bug.cgi?id=40757), + * which proposes switching (with an #ifdef, alas, if we want to maintain API + * compatibility) to a JNI-like extensible local root frame stack model. + */ +extern JS_PUBLIC_API(void) +JS_ClearNewbornRoots(JSContext *cx); + +#ifdef DEBUG +extern JS_PUBLIC_API(void) +JS_DumpNamedRoots(JSRuntime *rt, + void (*dump)(const char *name, void *rp, void *data), + void *data); +#endif + +/* + * Call JS_MapGCRoots to map the GC's roots table using map(rp, name, data). + * The root is pointed at by rp; if the root is unnamed, name is null; data is + * supplied from the third parameter to JS_MapGCRoots. + * + * The map function should return JS_MAP_GCROOT_REMOVE to cause the currently + * enumerated root to be removed. To stop enumeration, set JS_MAP_GCROOT_STOP + * in the return value. To keep on mapping, return JS_MAP_GCROOT_NEXT. These + * constants are flags; you can OR them together. + * + * This function acquires and releases rt's GC lock around the mapping of the + * roots table, so the map function should run to completion in as few cycles + * as possible. Of course, map cannot call JS_GC, JS_MaybeGC, JS_BeginRequest, + * or any JS API entry point that acquires locks, without double-tripping or + * deadlocking on the GC lock. + * + * JS_MapGCRoots returns the count of roots that were successfully mapped. + */ +#define JS_MAP_GCROOT_NEXT 0 /* continue mapping entries */ +#define JS_MAP_GCROOT_STOP 1 /* stop mapping entries */ +#define JS_MAP_GCROOT_REMOVE 2 /* remove and free the current entry */ + +typedef intN +(* JS_DLL_CALLBACK JSGCRootMapFun)(void *rp, const char *name, void *data); + +extern JS_PUBLIC_API(uint32) +JS_MapGCRoots(JSRuntime *rt, JSGCRootMapFun map, void *data); + +extern JS_PUBLIC_API(JSBool) +JS_LockGCThing(JSContext *cx, void *thing); + +extern JS_PUBLIC_API(JSBool) +JS_LockGCThingRT(JSRuntime *rt, void *thing); + +extern JS_PUBLIC_API(JSBool) +JS_UnlockGCThing(JSContext *cx, void *thing); + +extern JS_PUBLIC_API(JSBool) +JS_UnlockGCThingRT(JSRuntime *rt, void *thing); + +/* + * For implementors of JSObjectOps.mark, to mark a GC-thing reachable via a + * property or other strong ref identified for debugging purposes by name. + * The name argument's storage needs to live only as long as the call to + * this routine. + * + * The final arg is used by GC_MARK_DEBUG code to build a ref path through + * the GC's live thing graph. Implementors of JSObjectOps.mark should pass + * its final arg through to this function when marking all GC-things that are + * directly reachable from the object being marked. + * + * See the JSMarkOp typedef in jspubtd.h, and the JSObjectOps struct below. + */ +extern JS_PUBLIC_API(void) +JS_MarkGCThing(JSContext *cx, void *thing, const char *name, void *arg); + +extern JS_PUBLIC_API(void) +JS_GC(JSContext *cx); + +extern JS_PUBLIC_API(void) +JS_MaybeGC(JSContext *cx); + +extern JS_PUBLIC_API(JSGCCallback) +JS_SetGCCallback(JSContext *cx, JSGCCallback cb); + +extern JS_PUBLIC_API(JSGCCallback) +JS_SetGCCallbackRT(JSRuntime *rt, JSGCCallback cb); + +extern JS_PUBLIC_API(JSBool) +JS_IsAboutToBeFinalized(JSContext *cx, void *thing); + +/* + * Add an external string finalizer, one created by JS_NewExternalString (see + * below) using a type-code returned from this function, and that understands + * how to free or release the memory pointed at by JS_GetStringChars(str). + * + * Return a nonnegative type index if there is room for finalizer in the + * global GC finalizers table, else return -1. If the engine is compiled + * JS_THREADSAFE and used in a multi-threaded environment, this function must + * be invoked on the primordial thread only, at startup -- or else the entire + * program must single-thread itself while loading a module that calls this + * function. + */ +extern JS_PUBLIC_API(intN) +JS_AddExternalStringFinalizer(JSStringFinalizeOp finalizer); + +/* + * Remove finalizer from the global GC finalizers table, returning its type + * code if found, -1 if not found. + * + * As with JS_AddExternalStringFinalizer, there is a threading restriction + * if you compile the engine JS_THREADSAFE: this function may be called for a + * given finalizer pointer on only one thread; different threads may call to + * remove distinct finalizers safely. + * + * You must ensure that all strings with finalizer's type have been collected + * before calling this function. Otherwise, string data will be leaked by the + * GC, for want of a finalizer to call. + */ +extern JS_PUBLIC_API(intN) +JS_RemoveExternalStringFinalizer(JSStringFinalizeOp finalizer); + +/* + * Create a new JSString whose chars member refers to external memory, i.e., + * memory requiring special, type-specific finalization. The type code must + * be a nonnegative return value from JS_AddExternalStringFinalizer. + */ +extern JS_PUBLIC_API(JSString *) +JS_NewExternalString(JSContext *cx, jschar *chars, size_t length, intN type); + +/* + * Returns the external-string finalizer index for this string, or -1 if it is + * an "internal" (native to JS engine) string. + */ +extern JS_PUBLIC_API(intN) +JS_GetExternalStringGCType(JSRuntime *rt, JSString *str); + +/* + * Sets maximum (if stack grows upward) or minimum (downward) legal stack byte + * address in limitAddr for the thread or process stack used by cx. To disable + * stack size checking, pass 0 for limitAddr. + */ +extern JS_PUBLIC_API(void) +JS_SetThreadStackLimit(JSContext *cx, jsuword limitAddr); + +/************************************************************************/ + +/* + * Classes, objects, and properties. + */ + +/* For detailed comments on the function pointer types, see jspubtd.h. */ +struct JSClass { + const char *name; + uint32 flags; + + /* Mandatory non-null function pointer members. */ + JSPropertyOp addProperty; + JSPropertyOp delProperty; + JSPropertyOp getProperty; + JSPropertyOp setProperty; + JSEnumerateOp enumerate; + JSResolveOp resolve; + JSConvertOp convert; + JSFinalizeOp finalize; + + /* Optionally non-null members start here. */ + JSGetObjectOps getObjectOps; + JSCheckAccessOp checkAccess; + JSNative call; + JSNative construct; + JSXDRObjectOp xdrObject; + JSHasInstanceOp hasInstance; + JSMarkOp mark; + jsword spare; +}; + +#define JSCLASS_HAS_PRIVATE (1<<0) /* objects have private slot */ +#define JSCLASS_NEW_ENUMERATE (1<<1) /* has JSNewEnumerateOp hook */ +#define JSCLASS_NEW_RESOLVE (1<<2) /* has JSNewResolveOp hook */ +#define JSCLASS_PRIVATE_IS_NSISUPPORTS (1<<3) /* private is (nsISupports *) */ +#define JSCLASS_SHARE_ALL_PROPERTIES (1<<4) /* all properties are SHARED */ +#define JSCLASS_NEW_RESOLVE_GETS_START (1<<5) /* JSNewResolveOp gets starting + object in prototype chain + passed in via *objp in/out + parameter */ + +/* + * To reserve slots fetched and stored via JS_Get/SetReservedSlot, bitwise-or + * JSCLASS_HAS_RESERVED_SLOTS(n) into the initializer for JSClass.flags, where + * n is a constant in [1, 255]. Reserved slots are indexed from 0 to n-1. + */ +#define JSCLASS_RESERVED_SLOTS_SHIFT 8 /* room for 8 flags below */ +#define JSCLASS_RESERVED_SLOTS_WIDTH 8 /* and 16 above this field */ +#define JSCLASS_RESERVED_SLOTS_MASK JS_BITMASK(JSCLASS_RESERVED_SLOTS_WIDTH) +#define JSCLASS_HAS_RESERVED_SLOTS(n) (((n) & JSCLASS_RESERVED_SLOTS_MASK) \ + << JSCLASS_RESERVED_SLOTS_SHIFT) +#define JSCLASS_RESERVED_SLOTS(clasp) (((clasp)->flags \ + >> JSCLASS_RESERVED_SLOTS_SHIFT) \ + & JSCLASS_RESERVED_SLOTS_MASK) + +/* Initializer for unused members of statically initialized JSClass structs. */ +#define JSCLASS_NO_OPTIONAL_MEMBERS 0,0,0,0,0,0,0,0 + +/* For detailed comments on these function pointer types, see jspubtd.h. */ +struct JSObjectOps { + /* Mandatory non-null function pointer members. */ + JSNewObjectMapOp newObjectMap; + JSObjectMapOp destroyObjectMap; + JSLookupPropOp lookupProperty; + JSDefinePropOp defineProperty; + JSPropertyIdOp getProperty; + JSPropertyIdOp setProperty; + JSAttributesOp getAttributes; + JSAttributesOp setAttributes; + JSPropertyIdOp deleteProperty; + JSConvertOp defaultValue; + JSNewEnumerateOp enumerate; + JSCheckAccessIdOp checkAccess; + + /* Optionally non-null members start here. */ + JSObjectOp thisObject; + JSPropertyRefOp dropProperty; + JSNative call; + JSNative construct; + JSXDRObjectOp xdrObject; + JSHasInstanceOp hasInstance; + JSSetObjectSlotOp setProto; + JSSetObjectSlotOp setParent; + JSMarkOp mark; + JSFinalizeOp clear; + JSGetRequiredSlotOp getRequiredSlot; + JSSetRequiredSlotOp setRequiredSlot; +}; + +/* + * Classes that expose JSObjectOps via a non-null getObjectOps class hook may + * derive a property structure from this struct, return a pointer to it from + * lookupProperty and defineProperty, and use the pointer to avoid rehashing + * in getAttributes and setAttributes. + * + * The jsid type contains either an int jsval (see JSVAL_IS_INT above), or an + * internal pointer that is opaque to users of this API, but which users may + * convert from and to a jsval using JS_ValueToId and JS_IdToValue. + */ +struct JSProperty { + jsid id; +}; + +struct JSIdArray { + jsint length; + jsid vector[1]; /* actually, length jsid words */ +}; + +extern JS_PUBLIC_API(void) +JS_DestroyIdArray(JSContext *cx, JSIdArray *ida); + +extern JS_PUBLIC_API(JSBool) +JS_ValueToId(JSContext *cx, jsval v, jsid *idp); + +extern JS_PUBLIC_API(JSBool) +JS_IdToValue(JSContext *cx, jsid id, jsval *vp); + +#define JSRESOLVE_QUALIFIED 0x01 /* resolve a qualified property id */ +#define JSRESOLVE_ASSIGNING 0x02 /* resolve on the left of assignment */ + +extern JS_PUBLIC_API(JSBool) +JS_PropertyStub(JSContext *cx, JSObject *obj, jsval id, jsval *vp); + +extern JS_PUBLIC_API(JSBool) +JS_EnumerateStub(JSContext *cx, JSObject *obj); + +extern JS_PUBLIC_API(JSBool) +JS_ResolveStub(JSContext *cx, JSObject *obj, jsval id); + +extern JS_PUBLIC_API(JSBool) +JS_ConvertStub(JSContext *cx, JSObject *obj, JSType type, jsval *vp); + +extern JS_PUBLIC_API(void) +JS_FinalizeStub(JSContext *cx, JSObject *obj); + +struct JSConstDoubleSpec { + jsdouble dval; + const char *name; + uint8 flags; + uint8 spare[3]; +}; + +/* + * To define an array element rather than a named property member, cast the + * element's index to (const char *) and initialize name with it, and set the + * JSPROP_INDEX bit in flags. + */ +struct JSPropertySpec { + const char *name; + int8 tinyid; + uint8 flags; + JSPropertyOp getter; + JSPropertyOp setter; +}; + +struct JSFunctionSpec { + const char *name; + JSNative call; + uint8 nargs; + uint8 flags; + uint16 extra; /* number of arg slots for local GC roots */ +}; + +extern JS_PUBLIC_API(JSObject *) +JS_InitClass(JSContext *cx, JSObject *obj, JSObject *parent_proto, + JSClass *clasp, JSNative constructor, uintN nargs, + JSPropertySpec *ps, JSFunctionSpec *fs, + JSPropertySpec *static_ps, JSFunctionSpec *static_fs); + +#ifdef JS_THREADSAFE +extern JS_PUBLIC_API(JSClass *) +JS_GetClass(JSContext *cx, JSObject *obj); + +#define JS_GET_CLASS(cx,obj) JS_GetClass(cx, obj) +#else +extern JS_PUBLIC_API(JSClass *) +JS_GetClass(JSObject *obj); + +#define JS_GET_CLASS(cx,obj) JS_GetClass(obj) +#endif + +extern JS_PUBLIC_API(JSBool) +JS_InstanceOf(JSContext *cx, JSObject *obj, JSClass *clasp, jsval *argv); + +extern JS_PUBLIC_API(void *) +JS_GetPrivate(JSContext *cx, JSObject *obj); + +extern JS_PUBLIC_API(JSBool) +JS_SetPrivate(JSContext *cx, JSObject *obj, void *data); + +extern JS_PUBLIC_API(void *) +JS_GetInstancePrivate(JSContext *cx, JSObject *obj, JSClass *clasp, + jsval *argv); + +extern JS_PUBLIC_API(JSObject *) +JS_GetPrototype(JSContext *cx, JSObject *obj); + +extern JS_PUBLIC_API(JSBool) +JS_SetPrototype(JSContext *cx, JSObject *obj, JSObject *proto); + +extern JS_PUBLIC_API(JSObject *) +JS_GetParent(JSContext *cx, JSObject *obj); + +extern JS_PUBLIC_API(JSBool) +JS_SetParent(JSContext *cx, JSObject *obj, JSObject *parent); + +extern JS_PUBLIC_API(JSObject *) +JS_GetConstructor(JSContext *cx, JSObject *proto); + +/* + * Get a unique identifier for obj, good for the lifetime of obj (even if it + * is moved by a copying GC). Return false on failure (likely out of memory), + * and true with *idp containing the unique id on success. + */ +extern JS_PUBLIC_API(JSBool) +JS_GetObjectId(JSContext *cx, JSObject *obj, jsid *idp); + +extern JS_PUBLIC_API(JSObject *) +JS_NewObject(JSContext *cx, JSClass *clasp, JSObject *proto, JSObject *parent); + +extern JS_PUBLIC_API(JSBool) +JS_SealObject(JSContext *cx, JSObject *obj, JSBool deep); + +extern JS_PUBLIC_API(JSObject *) +JS_ConstructObject(JSContext *cx, JSClass *clasp, JSObject *proto, + JSObject *parent); + +extern JS_PUBLIC_API(JSObject *) +JS_ConstructObjectWithArguments(JSContext *cx, JSClass *clasp, JSObject *proto, + JSObject *parent, uintN argc, jsval *argv); + +extern JS_PUBLIC_API(JSObject *) +JS_DefineObject(JSContext *cx, JSObject *obj, const char *name, JSClass *clasp, + JSObject *proto, uintN attrs); + +extern JS_PUBLIC_API(JSBool) +JS_DefineConstDoubles(JSContext *cx, JSObject *obj, JSConstDoubleSpec *cds); + +extern JS_PUBLIC_API(JSBool) +JS_DefineProperties(JSContext *cx, JSObject *obj, JSPropertySpec *ps); + +extern JS_PUBLIC_API(JSBool) +JS_DefineProperty(JSContext *cx, JSObject *obj, const char *name, jsval value, + JSPropertyOp getter, JSPropertyOp setter, uintN attrs); + +/* + * Determine the attributes (JSPROP_* flags) of a property on a given object. + * + * If the object does not have a property by that name, *foundp will be + * JS_FALSE and the value of *attrsp is undefined. + */ +extern JS_PUBLIC_API(JSBool) +JS_GetPropertyAttributes(JSContext *cx, JSObject *obj, const char *name, + uintN *attrsp, JSBool *foundp); + +/* + * Set the attributes of a property on a given object. + * + * If the object does not have a property by that name, *foundp will be + * JS_FALSE and nothing will be altered. + */ +extern JS_PUBLIC_API(JSBool) +JS_SetPropertyAttributes(JSContext *cx, JSObject *obj, const char *name, + uintN attrs, JSBool *foundp); + +extern JS_PUBLIC_API(JSBool) +JS_DefinePropertyWithTinyId(JSContext *cx, JSObject *obj, const char *name, + int8 tinyid, jsval value, + JSPropertyOp getter, JSPropertyOp setter, + uintN attrs); + +extern JS_PUBLIC_API(JSBool) +JS_AliasProperty(JSContext *cx, JSObject *obj, const char *name, + const char *alias); + +extern JS_PUBLIC_API(JSBool) +JS_LookupProperty(JSContext *cx, JSObject *obj, const char *name, jsval *vp); + +extern JS_PUBLIC_API(JSBool) +JS_GetProperty(JSContext *cx, JSObject *obj, const char *name, jsval *vp); + +extern JS_PUBLIC_API(JSBool) +JS_SetProperty(JSContext *cx, JSObject *obj, const char *name, jsval *vp); + +extern JS_PUBLIC_API(JSBool) +JS_DeleteProperty(JSContext *cx, JSObject *obj, const char *name); + +extern JS_PUBLIC_API(JSBool) +JS_DeleteProperty2(JSContext *cx, JSObject *obj, const char *name, + jsval *rval); + +extern JS_PUBLIC_API(JSBool) +JS_DefineUCProperty(JSContext *cx, JSObject *obj, + const jschar *name, size_t namelen, jsval value, + JSPropertyOp getter, JSPropertyOp setter, + uintN attrs); + +/* + * Determine the attributes (JSPROP_* flags) of a property on a given object. + * + * If the object does not have a property by that name, *foundp will be + * JS_FALSE and the value of *attrsp is undefined. + */ +extern JS_PUBLIC_API(JSBool) +JS_GetUCPropertyAttributes(JSContext *cx, JSObject *obj, + const jschar *name, size_t namelen, + uintN *attrsp, JSBool *foundp); + +/* + * Set the attributes of a property on a given object. + * + * If the object does not have a property by that name, *foundp will be + * JS_FALSE and nothing will be altered. + */ +extern JS_PUBLIC_API(JSBool) +JS_SetUCPropertyAttributes(JSContext *cx, JSObject *obj, + const jschar *name, size_t namelen, + uintN attrs, JSBool *foundp); + + +extern JS_PUBLIC_API(JSBool) +JS_DefineUCPropertyWithTinyId(JSContext *cx, JSObject *obj, + const jschar *name, size_t namelen, + int8 tinyid, jsval value, + JSPropertyOp getter, JSPropertyOp setter, + uintN attrs); + +extern JS_PUBLIC_API(JSBool) +JS_LookupUCProperty(JSContext *cx, JSObject *obj, + const jschar *name, size_t namelen, + jsval *vp); + +extern JS_PUBLIC_API(JSBool) +JS_GetUCProperty(JSContext *cx, JSObject *obj, + const jschar *name, size_t namelen, + jsval *vp); + +extern JS_PUBLIC_API(JSBool) +JS_SetUCProperty(JSContext *cx, JSObject *obj, + const jschar *name, size_t namelen, + jsval *vp); + +extern JS_PUBLIC_API(JSBool) +JS_DeleteUCProperty2(JSContext *cx, JSObject *obj, + const jschar *name, size_t namelen, + jsval *rval); + +extern JS_PUBLIC_API(JSObject *) +JS_NewArrayObject(JSContext *cx, jsint length, jsval *vector); + +extern JS_PUBLIC_API(JSBool) +JS_IsArrayObject(JSContext *cx, JSObject *obj); + +extern JS_PUBLIC_API(JSBool) +JS_GetArrayLength(JSContext *cx, JSObject *obj, jsuint *lengthp); + +extern JS_PUBLIC_API(JSBool) +JS_SetArrayLength(JSContext *cx, JSObject *obj, jsuint length); + +extern JS_PUBLIC_API(JSBool) +JS_HasArrayLength(JSContext *cx, JSObject *obj, jsuint *lengthp); + +extern JS_PUBLIC_API(JSBool) +JS_DefineElement(JSContext *cx, JSObject *obj, jsint index, jsval value, + JSPropertyOp getter, JSPropertyOp setter, uintN attrs); + +extern JS_PUBLIC_API(JSBool) +JS_AliasElement(JSContext *cx, JSObject *obj, const char *name, jsint alias); + +extern JS_PUBLIC_API(JSBool) +JS_LookupElement(JSContext *cx, JSObject *obj, jsint index, jsval *vp); + +extern JS_PUBLIC_API(JSBool) +JS_GetElement(JSContext *cx, JSObject *obj, jsint index, jsval *vp); + +extern JS_PUBLIC_API(JSBool) +JS_SetElement(JSContext *cx, JSObject *obj, jsint index, jsval *vp); + +extern JS_PUBLIC_API(JSBool) +JS_DeleteElement(JSContext *cx, JSObject *obj, jsint index); + +extern JS_PUBLIC_API(JSBool) +JS_DeleteElement2(JSContext *cx, JSObject *obj, jsint index, jsval *rval); + +extern JS_PUBLIC_API(void) +JS_ClearScope(JSContext *cx, JSObject *obj); + +extern JS_PUBLIC_API(JSIdArray *) +JS_Enumerate(JSContext *cx, JSObject *obj); + +extern JS_PUBLIC_API(JSBool) +JS_CheckAccess(JSContext *cx, JSObject *obj, jsid id, JSAccessMode mode, + jsval *vp, uintN *attrsp); + +extern JS_PUBLIC_API(JSCheckAccessOp) +JS_SetCheckObjectAccessCallback(JSRuntime *rt, JSCheckAccessOp acb); + +extern JS_PUBLIC_API(JSBool) +JS_GetReservedSlot(JSContext *cx, JSObject *obj, uint32 index, jsval *vp); + +extern JS_PUBLIC_API(JSBool) +JS_SetReservedSlot(JSContext *cx, JSObject *obj, uint32 index, jsval v); + +/************************************************************************/ + +/* + * Security protocol. + */ +struct JSPrincipals { + char *codebase; + void * (* JS_DLL_CALLBACK getPrincipalArray)(JSContext *cx, JSPrincipals *); + JSBool (* JS_DLL_CALLBACK globalPrivilegesEnabled)(JSContext *cx, JSPrincipals *); + + /* Don't call "destroy"; use reference counting macros below. */ + jsrefcount refcount; + void (* JS_DLL_CALLBACK destroy)(JSContext *cx, struct JSPrincipals *); +}; + +#ifdef JS_THREADSAFE +#define JSPRINCIPALS_HOLD(cx, principals) JS_HoldPrincipals(cx,principals) +#define JSPRINCIPALS_DROP(cx, principals) JS_DropPrincipals(cx,principals) + +extern JS_PUBLIC_API(jsrefcount) +JS_HoldPrincipals(JSContext *cx, JSPrincipals *principals); + +extern JS_PUBLIC_API(jsrefcount) +JS_DropPrincipals(JSContext *cx, JSPrincipals *principals); + +#else +#define JSPRINCIPALS_HOLD(cx, principals) (++(principals)->refcount) +#define JSPRINCIPALS_DROP(cx, principals) \ + ((--(principals)->refcount == 0) \ + ? ((*(principals)->destroy)((cx), (principals)), 0) \ + : (principals)->refcount) +#endif + +extern JS_PUBLIC_API(JSPrincipalsTranscoder) +JS_SetPrincipalsTranscoder(JSRuntime *rt, JSPrincipalsTranscoder px); + +extern JS_PUBLIC_API(JSObjectPrincipalsFinder) +JS_SetObjectPrincipalsFinder(JSContext *cx, JSObjectPrincipalsFinder fop); + +/************************************************************************/ + +/* + * Functions and scripts. + */ +extern JS_PUBLIC_API(JSFunction *) +JS_NewFunction(JSContext *cx, JSNative call, uintN nargs, uintN flags, + JSObject *parent, const char *name); + +extern JS_PUBLIC_API(JSObject *) +JS_GetFunctionObject(JSFunction *fun); + +/* + * Deprecated, useful only for diagnostics. Use JS_GetFunctionId instead for + * anonymous vs. "anonymous" disambiguation and Unicode fidelity. + */ +extern JS_PUBLIC_API(const char *) +JS_GetFunctionName(JSFunction *fun); + +/* + * Return the function's identifier as a JSString, or null if fun is unnamed. + * The returned string lives as long as fun, so you don't need to root a saved + * reference to it if fun is well-connected or rooted, and provided you bound + * the use of the saved reference by fun's lifetime. + * + * Prefer JS_GetFunctionId over JS_GetFunctionName because it returns null for + * truly anonymous functions, and because it doesn't chop to ISO-Latin-1 chars + * from UTF-16-ish jschars. + */ +extern JS_PUBLIC_API(JSString *) +JS_GetFunctionId(JSFunction *fun); + +/* + * Return JSFUN_* flags for fun. + */ +extern JS_PUBLIC_API(uintN) +JS_GetFunctionFlags(JSFunction *fun); + +/* + * Infallible predicate to test whether obj is a function object (faster than + * comparing obj's class name to "Function", but equivalent unless someone has + * overwritten the "Function" identifier with a different constructor and then + * created instances using that constructor that might be passed in as obj). + */ +extern JS_PUBLIC_API(JSBool) +JS_ObjectIsFunction(JSContext *cx, JSObject *obj); + +extern JS_PUBLIC_API(JSBool) +JS_DefineFunctions(JSContext *cx, JSObject *obj, JSFunctionSpec *fs); + +extern JS_PUBLIC_API(JSFunction *) +JS_DefineFunction(JSContext *cx, JSObject *obj, const char *name, JSNative call, + uintN nargs, uintN attrs); + +extern JS_PUBLIC_API(JSObject *) +JS_CloneFunctionObject(JSContext *cx, JSObject *funobj, JSObject *parent); + +/* + * Given a buffer, return JS_FALSE if the buffer might become a valid + * javascript statement with the addition of more lines. Otherwise return + * JS_TRUE. The intent is to support interactive compilation - accumulate + * lines in a buffer until JS_BufferIsCompilableUnit is true, then pass it to + * the compiler. + */ +extern JS_PUBLIC_API(JSBool) +JS_BufferIsCompilableUnit(JSContext *cx, JSObject *obj, + const char *bytes, size_t length); + +/* + * The JSScript objects returned by the following functions refer to string and + * other kinds of literals, including doubles and RegExp objects. These + * literals are vulnerable to garbage collection; to root script objects and + * prevent literals from being collected, create a rootable object using + * JS_NewScriptObject, and root the resulting object using JS_Add[Named]Root. + */ +extern JS_PUBLIC_API(JSScript *) +JS_CompileScript(JSContext *cx, JSObject *obj, + const char *bytes, size_t length, + const char *filename, uintN lineno); + +extern JS_PUBLIC_API(JSScript *) +JS_CompileScriptForPrincipals(JSContext *cx, JSObject *obj, + JSPrincipals *principals, + const char *bytes, size_t length, + const char *filename, uintN lineno); + +extern JS_PUBLIC_API(JSScript *) +JS_CompileUCScript(JSContext *cx, JSObject *obj, + const jschar *chars, size_t length, + const char *filename, uintN lineno); + +extern JS_PUBLIC_API(JSScript *) +JS_CompileUCScriptForPrincipals(JSContext *cx, JSObject *obj, + JSPrincipals *principals, + const jschar *chars, size_t length, + const char *filename, uintN lineno); + +extern JS_PUBLIC_API(JSScript *) +JS_CompileFile(JSContext *cx, JSObject *obj, const char *filename); + +extern JS_PUBLIC_API(JSScript *) +JS_CompileFileHandle(JSContext *cx, JSObject *obj, const char *filename, + FILE *fh); + +extern JS_PUBLIC_API(JSScript *) +JS_CompileFileHandleForPrincipals(JSContext *cx, JSObject *obj, + const char *filename, FILE *fh, + JSPrincipals *principals); + +/* + * NB: you must use JS_NewScriptObject and root a pointer to its return value + * in order to keep a JSScript and its atoms safe from garbage collection after + * creating the script via JS_Compile* and before a JS_ExecuteScript* call. + * E.g., and without error checks: + * + * JSScript *script = JS_CompileFile(cx, global, filename); + * JSObject *scrobj = JS_NewScriptObject(cx, script); + * JS_AddNamedRoot(cx, &scrobj, "scrobj"); + * do { + * jsval result; + * JS_ExecuteScript(cx, global, script, &result); + * JS_GC(); + * } while (!JSVAL_IS_BOOLEAN(result) || JSVAL_TO_BOOLEAN(result)); + * JS_RemoveRoot(cx, &scrobj); + */ +extern JS_PUBLIC_API(JSObject *) +JS_NewScriptObject(JSContext *cx, JSScript *script); + +/* + * Infallible getter for a script's object. If JS_NewScriptObject has not been + * called on script yet, the return value will be null. + */ +extern JS_PUBLIC_API(JSObject *) +JS_GetScriptObject(JSScript *script); + +extern JS_PUBLIC_API(void) +JS_DestroyScript(JSContext *cx, JSScript *script); + +extern JS_PUBLIC_API(JSFunction *) +JS_CompileFunction(JSContext *cx, JSObject *obj, const char *name, + uintN nargs, const char **argnames, + const char *bytes, size_t length, + const char *filename, uintN lineno); + +extern JS_PUBLIC_API(JSFunction *) +JS_CompileFunctionForPrincipals(JSContext *cx, JSObject *obj, + JSPrincipals *principals, const char *name, + uintN nargs, const char **argnames, + const char *bytes, size_t length, + const char *filename, uintN lineno); + +extern JS_PUBLIC_API(JSFunction *) +JS_CompileUCFunction(JSContext *cx, JSObject *obj, const char *name, + uintN nargs, const char **argnames, + const jschar *chars, size_t length, + const char *filename, uintN lineno); + +extern JS_PUBLIC_API(JSFunction *) +JS_CompileUCFunctionForPrincipals(JSContext *cx, JSObject *obj, + JSPrincipals *principals, const char *name, + uintN nargs, const char **argnames, + const jschar *chars, size_t length, + const char *filename, uintN lineno); + +extern JS_PUBLIC_API(JSString *) +JS_DecompileScript(JSContext *cx, JSScript *script, const char *name, + uintN indent); + +/* + * API extension: OR this into indent to avoid pretty-printing the decompiled + * source resulting from JS_DecompileFunction{,Body}. + */ +#define JS_DONT_PRETTY_PRINT ((uintN)0x8000) + +extern JS_PUBLIC_API(JSString *) +JS_DecompileFunction(JSContext *cx, JSFunction *fun, uintN indent); + +extern JS_PUBLIC_API(JSString *) +JS_DecompileFunctionBody(JSContext *cx, JSFunction *fun, uintN indent); + +/* + * NB: JS_ExecuteScript, JS_ExecuteScriptPart, and the JS_Evaluate*Script* + * quadruplets all use the obj parameter as the initial scope chain header, + * the 'this' keyword value, and the variables object (ECMA parlance for where + * 'var' and 'function' bind names) of the execution context for script. + * + * Using obj as the variables object is problematic if obj's parent (which is + * the scope chain link; see JS_SetParent and JS_NewObject) is not null: in + * this case, variables created by 'var x = 0', e.g., go in obj, but variables + * created by assignment to an unbound id, 'x = 0', go in the last object on + * the scope chain linked by parent. + * + * ECMA calls that last scoping object the "global object", but note that many + * embeddings have several such objects. ECMA requires that "global code" be + * executed with the variables object equal to this global object. But these + * JS API entry points provide freedom to execute code against a "sub-global", + * i.e., a parented or scoped object, in which case the variables object will + * differ from the last object on the scope chain, resulting in confusing and + * non-ECMA explicit vs. implicit variable creation. + * + * Caveat embedders: unless you already depend on this buggy variables object + * binding behavior, you should call JS_SetOptions(cx, JSOPTION_VAROBJFIX) or + * JS_SetOptions(cx, JS_GetOptions(cx) | JSOPTION_VAROBJFIX) -- the latter if + * someone may have set other options on cx already -- for each context in the + * application, if you pass parented objects as the obj parameter, or may ever + * pass such objects in the future. + * + * Why a runtime option? The alternative is to add six or so new API entry + * points with signatures matching the following six, and that doesn't seem + * worth the code bloat cost. Such new entry points would probably have less + * obvious names, too, so would not tend to be used. The JS_SetOption call, + * OTOH, can be more easily hacked into existing code that does not depend on + * the bug; such code can continue to use the familiar JS_EvaluateScript, + * etc., entry points. + */ +extern JS_PUBLIC_API(JSBool) +JS_ExecuteScript(JSContext *cx, JSObject *obj, JSScript *script, jsval *rval); + +/* + * Execute either the function-defining prolog of a script, or the script's + * main body, but not both. + */ +typedef enum JSExecPart { JSEXEC_PROLOG, JSEXEC_MAIN } JSExecPart; + +extern JS_PUBLIC_API(JSBool) +JS_ExecuteScriptPart(JSContext *cx, JSObject *obj, JSScript *script, + JSExecPart part, jsval *rval); + +extern JS_PUBLIC_API(JSBool) +JS_EvaluateScript(JSContext *cx, JSObject *obj, + const char *bytes, uintN length, + const char *filename, uintN lineno, + jsval *rval); + +extern JS_PUBLIC_API(JSBool) +JS_EvaluateScriptForPrincipals(JSContext *cx, JSObject *obj, + JSPrincipals *principals, + const char *bytes, uintN length, + const char *filename, uintN lineno, + jsval *rval); + +extern JS_PUBLIC_API(JSBool) +JS_EvaluateUCScript(JSContext *cx, JSObject *obj, + const jschar *chars, uintN length, + const char *filename, uintN lineno, + jsval *rval); + +extern JS_PUBLIC_API(JSBool) +JS_EvaluateUCScriptForPrincipals(JSContext *cx, JSObject *obj, + JSPrincipals *principals, + const jschar *chars, uintN length, + const char *filename, uintN lineno, + jsval *rval); + +extern JS_PUBLIC_API(JSBool) +JS_CallFunction(JSContext *cx, JSObject *obj, JSFunction *fun, uintN argc, + jsval *argv, jsval *rval); + +extern JS_PUBLIC_API(JSBool) +JS_CallFunctionName(JSContext *cx, JSObject *obj, const char *name, uintN argc, + jsval *argv, jsval *rval); + +extern JS_PUBLIC_API(JSBool) +JS_CallFunctionValue(JSContext *cx, JSObject *obj, jsval fval, uintN argc, + jsval *argv, jsval *rval); + +extern JS_PUBLIC_API(JSBranchCallback) +JS_SetBranchCallback(JSContext *cx, JSBranchCallback cb); + +extern JS_PUBLIC_API(JSBool) +JS_IsRunning(JSContext *cx); + +extern JS_PUBLIC_API(JSBool) +JS_IsConstructing(JSContext *cx); + +/* + * Returns true if a script is executing and its current bytecode is a set + * (assignment) operation, even if there are native (no script) stack frames + * between the script and the caller to JS_IsAssigning. + */ +extern JS_FRIEND_API(JSBool) +JS_IsAssigning(JSContext *cx); + +/* + * Set the second return value, which should be a string or int jsval that + * identifies a property in the returned object, to form an ECMA reference + * type value (obj, id). Only native methods can return reference types, + * and if the returned value is used on the left-hand side of an assignment + * op, the identified property will be set. If the return value is in an + * r-value, the interpreter just gets obj[id]'s value. + */ +extern JS_PUBLIC_API(void) +JS_SetCallReturnValue2(JSContext *cx, jsval v); + +/************************************************************************/ + +/* + * Strings. + * + * NB: JS_NewString takes ownership of bytes on success, avoiding a copy; but + * on error (signified by null return), it leaves bytes owned by the caller. + * So the caller must free bytes in the error case, if it has no use for them. + * In contrast, all the JS_New*StringCopy* functions do not take ownership of + * the character memory passed to them -- they copy it. + */ +extern JS_PUBLIC_API(JSString *) +JS_NewString(JSContext *cx, char *bytes, size_t length); + +extern JS_PUBLIC_API(JSString *) +JS_NewStringCopyN(JSContext *cx, const char *s, size_t n); + +extern JS_PUBLIC_API(JSString *) +JS_NewStringCopyZ(JSContext *cx, const char *s); + +extern JS_PUBLIC_API(JSString *) +JS_InternString(JSContext *cx, const char *s); + +extern JS_PUBLIC_API(JSString *) +JS_NewUCString(JSContext *cx, jschar *chars, size_t length); + +extern JS_PUBLIC_API(JSString *) +JS_NewUCStringCopyN(JSContext *cx, const jschar *s, size_t n); + +extern JS_PUBLIC_API(JSString *) +JS_NewUCStringCopyZ(JSContext *cx, const jschar *s); + +extern JS_PUBLIC_API(JSString *) +JS_InternUCStringN(JSContext *cx, const jschar *s, size_t length); + +extern JS_PUBLIC_API(JSString *) +JS_InternUCString(JSContext *cx, const jschar *s); + +extern JS_PUBLIC_API(char *) +JS_GetStringBytes(JSString *str); + +extern JS_PUBLIC_API(jschar *) +JS_GetStringChars(JSString *str); + +extern JS_PUBLIC_API(size_t) +JS_GetStringLength(JSString *str); + +extern JS_PUBLIC_API(intN) +JS_CompareStrings(JSString *str1, JSString *str2); + +/* + * Mutable string support. A string's characters are never mutable in this JS + * implementation, but a growable string has a buffer that can be reallocated, + * and a dependent string is a substring of another (growable, dependent, or + * immutable) string. The direct data members of the (opaque to API clients) + * JSString struct may be changed in a single-threaded way for growable and + * dependent strings. + * + * Therefore mutable strings cannot be used by more than one thread at a time. + * You may call JS_MakeStringImmutable to convert the string from a mutable + * (growable or dependent) string to an immutable (and therefore thread-safe) + * string. The engine takes care of converting growable and dependent strings + * to immutable for you if you store strings in multi-threaded objects using + * JS_SetProperty or kindred API entry points. + * + * If you store a JSString pointer in a native data structure that is (safely) + * accessible to multiple threads, you must call JS_MakeStringImmutable before + * retiring the store. + */ +extern JS_PUBLIC_API(JSString *) +JS_NewGrowableString(JSContext *cx, jschar *chars, size_t length); + +/* + * Create a dependent string, i.e., a string that owns no character storage, + * but that refers to a slice of another string's chars. Dependent strings + * are mutable by definition, so the thread safety comments above apply. + */ +extern JS_PUBLIC_API(JSString *) +JS_NewDependentString(JSContext *cx, JSString *str, size_t start, + size_t length); + +/* + * Concatenate two strings, resulting in a new growable string. If you create + * the left string and pass it to JS_ConcatStrings on a single thread, try to + * use JS_NewGrowableString to create the left string -- doing so helps Concat + * avoid allocating a new buffer for the result and copying left's chars into + * the new buffer. See above for thread safety comments. + */ +extern JS_PUBLIC_API(JSString *) +JS_ConcatStrings(JSContext *cx, JSString *left, JSString *right); + +/* + * Convert a dependent string into an independent one. This function does not + * change the string's mutability, so the thread safety comments above apply. + */ +extern JS_PUBLIC_API(const jschar *) +JS_UndependString(JSContext *cx, JSString *str); + +/* + * Convert a mutable string (either growable or dependent) into an immutable, + * thread-safe one. + */ +extern JS_PUBLIC_API(JSBool) +JS_MakeStringImmutable(JSContext *cx, JSString *str); + +/************************************************************************/ + +/* + * Locale specific string conversion callback. + */ +struct JSLocaleCallbacks { + JSLocaleToUpperCase localeToUpperCase; + JSLocaleToLowerCase localeToLowerCase; + JSLocaleCompare localeCompare; +}; + +/* + * Establish locale callbacks. The pointer must persist as long as the + * JSContext. Passing NULL restores the default behaviour. + */ +extern JS_PUBLIC_API(void) +JS_SetLocaleCallbacks(JSContext *cx, JSLocaleCallbacks *callbacks); + +/* + * Return the address of the current locale callbacks struct, which may + * be NULL. + */ +extern JS_PUBLIC_API(JSLocaleCallbacks *) +JS_GetLocaleCallbacks(JSContext *cx); + +/************************************************************************/ + +/* + * Error reporting. + */ + +/* + * Report an exception represented by the sprintf-like conversion of format + * and its arguments. This exception message string is passed to a pre-set + * JSErrorReporter function (set by JS_SetErrorReporter; see jspubtd.h for + * the JSErrorReporter typedef). + */ +extern JS_PUBLIC_API(void) +JS_ReportError(JSContext *cx, const char *format, ...); + +/* + * Use an errorNumber to retrieve the format string, args are char * + */ +extern JS_PUBLIC_API(void) +JS_ReportErrorNumber(JSContext *cx, JSErrorCallback errorCallback, + void *userRef, const uintN errorNumber, ...); + +/* + * Use an errorNumber to retrieve the format string, args are jschar * + */ +extern JS_PUBLIC_API(void) +JS_ReportErrorNumberUC(JSContext *cx, JSErrorCallback errorCallback, + void *userRef, const uintN errorNumber, ...); + +/* + * As above, but report a warning instead (JSREPORT_IS_WARNING(report.flags)). + * Return true if there was no error trying to issue the warning, and if the + * warning was not converted into an error due to the JSOPTION_WERROR option + * being set, false otherwise. + */ +extern JS_PUBLIC_API(JSBool) +JS_ReportWarning(JSContext *cx, const char *format, ...); + +extern JS_PUBLIC_API(JSBool) +JS_ReportErrorFlagsAndNumber(JSContext *cx, uintN flags, + JSErrorCallback errorCallback, void *userRef, + const uintN errorNumber, ...); + +extern JS_PUBLIC_API(JSBool) +JS_ReportErrorFlagsAndNumberUC(JSContext *cx, uintN flags, + JSErrorCallback errorCallback, void *userRef, + const uintN errorNumber, ...); + +/* + * Complain when out of memory. + */ +extern JS_PUBLIC_API(void) +JS_ReportOutOfMemory(JSContext *cx); + +struct JSErrorReport { + const char *filename; /* source file name, URL, etc., or null */ + uintN lineno; /* source line number */ + const char *linebuf; /* offending source line without final \n */ + const char *tokenptr; /* pointer to error token in linebuf */ + const jschar *uclinebuf; /* unicode (original) line buffer */ + const jschar *uctokenptr; /* unicode (original) token pointer */ + uintN flags; /* error/warning, etc. */ + uintN errorNumber; /* the error number, e.g. see js.msg */ + const jschar *ucmessage; /* the (default) error message */ + const jschar **messageArgs; /* arguments for the error message */ +}; + +/* + * JSErrorReport flag values. These may be freely composed. + */ +#define JSREPORT_ERROR 0x0 /* pseudo-flag for default case */ +#define JSREPORT_WARNING 0x1 /* reported via JS_ReportWarning */ +#define JSREPORT_EXCEPTION 0x2 /* exception was thrown */ +#define JSREPORT_STRICT 0x4 /* error or warning due to strict option */ + +/* + * If JSREPORT_EXCEPTION is set, then a JavaScript-catchable exception + * has been thrown for this runtime error, and the host should ignore it. + * Exception-aware hosts should also check for JS_IsExceptionPending if + * JS_ExecuteScript returns failure, and signal or propagate the exception, as + * appropriate. + */ +#define JSREPORT_IS_WARNING(flags) (((flags) & JSREPORT_WARNING) != 0) +#define JSREPORT_IS_EXCEPTION(flags) (((flags) & JSREPORT_EXCEPTION) != 0) +#define JSREPORT_IS_STRICT(flags) (((flags) & JSREPORT_STRICT) != 0) + +extern JS_PUBLIC_API(JSErrorReporter) +JS_SetErrorReporter(JSContext *cx, JSErrorReporter er); + +/************************************************************************/ + +/* + * Regular Expressions. + */ +#define JSREG_FOLD 0x01 /* fold uppercase to lowercase */ +#define JSREG_GLOB 0x02 /* global exec, creates array of matches */ +#define JSREG_MULTILINE 0x04 /* treat ^ and $ as begin and end of line */ + +extern JS_PUBLIC_API(JSObject *) +JS_NewRegExpObject(JSContext *cx, char *bytes, size_t length, uintN flags); + +extern JS_PUBLIC_API(JSObject *) +JS_NewUCRegExpObject(JSContext *cx, jschar *chars, size_t length, uintN flags); + +extern JS_PUBLIC_API(void) +JS_SetRegExpInput(JSContext *cx, JSString *input, JSBool multiline); + +extern JS_PUBLIC_API(void) +JS_ClearRegExpStatics(JSContext *cx); + +extern JS_PUBLIC_API(void) +JS_ClearRegExpRoots(JSContext *cx); + +/* TODO: compile, exec, get/set other statics... */ + +/************************************************************************/ + +extern JS_PUBLIC_API(JSBool) +JS_IsExceptionPending(JSContext *cx); + +extern JS_PUBLIC_API(JSBool) +JS_GetPendingException(JSContext *cx, jsval *vp); + +extern JS_PUBLIC_API(void) +JS_SetPendingException(JSContext *cx, jsval v); + +extern JS_PUBLIC_API(void) +JS_ClearPendingException(JSContext *cx); + +/* + * Save the current exception state. This takes a snapshot of cx's current + * exception state without making any change to that state. + * + * The returned state pointer MUST be passed later to JS_RestoreExceptionState + * (to restore that saved state, overriding any more recent state) or else to + * JS_DropExceptionState (to free the state struct in case it is not correct + * or desirable to restore it). Both Restore and Drop free the state struct, + * so callers must stop using the pointer returned from Save after calling the + * Release or Drop API. + */ +extern JS_PUBLIC_API(JSExceptionState *) +JS_SaveExceptionState(JSContext *cx); + +extern JS_PUBLIC_API(void) +JS_RestoreExceptionState(JSContext *cx, JSExceptionState *state); + +extern JS_PUBLIC_API(void) +JS_DropExceptionState(JSContext *cx, JSExceptionState *state); + +/* + * If the given value is an exception object that originated from an error, + * the exception will contain an error report struct, and this API will return + * the address of that struct. Otherwise, it returns NULL. The lifetime of + * the error report struct that might be returned is the same as the lifetime + * of the exception object. + */ +extern JS_PUBLIC_API(JSErrorReport *) +JS_ErrorFromException(JSContext *cx, jsval v); + +#ifdef JS_THREADSAFE + +/* + * Associate the current thread with the given context. This is done + * implicitly by JS_NewContext. + * + * Returns the old thread id for this context, which should be treated as + * an opaque value. This value is provided for comparison to 0, which + * indicates that ClearContextThread has been called on this context + * since the last SetContextThread, or non-0, which indicates the opposite. + */ +extern JS_PUBLIC_API(jsword) +JS_GetContextThread(JSContext *cx); + +extern JS_PUBLIC_API(jsword) +JS_SetContextThread(JSContext *cx); + +extern JS_PUBLIC_API(intN) +JS_ClearContextThread(JSContext *cx); + +#endif /* JS_THREADSAFE */ + +/************************************************************************/ + +JS_END_EXTERN_C + +#endif /* jsapi_h___ */ diff --git a/src/dom/js/jsarena.c b/src/dom/js/jsarena.c new file mode 100644 index 000000000..4cc2e7c53 --- /dev/null +++ b/src/dom/js/jsarena.c @@ -0,0 +1,565 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* + * Lifetime-based fast allocation, inspired by much prior art, including + * "Fast Allocation and Deallocation of Memory Based on Object Lifetimes" + * David R. Hanson, Software -- Practice and Experience, Vol. 20(1). + */ +#include "jsstddef.h" +#include +#include +#include "jstypes.h" +#include "jsbit.h" +#include "jsarena.h" /* Added by JSIFY */ +#include "jsutil.h" /* Added by JSIFY */ +#include "jslock.h" + +static JSArena *arena_freelist; + +#ifdef JS_THREADSAFE +static JSLock *arena_freelist_lock; +#endif + +#ifdef JS_ARENAMETER +static JSArenaStats *arena_stats_list; + +#define COUNT(pool,what) (pool)->stats.what++ +#else +#define COUNT(pool,what) /* nothing */ +#endif + +#define JS_ARENA_DEFAULT_ALIGN sizeof(double) + +JS_PUBLIC_API(void) +JS_InitArenaPool(JSArenaPool *pool, const char *name, size_t size, size_t align) +{ +#ifdef JS_THREADSAFE + /* Must come through here once in primordial thread to init safely! */ + if (!arena_freelist_lock) { + arena_freelist_lock = JS_NEW_LOCK(); + JS_ASSERT(arena_freelist_lock); + } +#endif + if (align == 0) + align = JS_ARENA_DEFAULT_ALIGN; + pool->mask = JS_BITMASK(JS_CeilingLog2(align)); + pool->first.next = NULL; + pool->first.base = pool->first.avail = pool->first.limit = + JS_ARENA_ALIGN(pool, &pool->first + 1); + pool->current = &pool->first; + pool->arenasize = size; +#ifdef JS_ARENAMETER + memset(&pool->stats, 0, sizeof pool->stats); + pool->stats.name = strdup(name); + pool->stats.next = arena_stats_list; + arena_stats_list = &pool->stats; +#endif +} + +/* + * An allocation that consumes more than pool->arenasize also has a header + * pointing back to its previous arena's next member. This header is not + * included in [a->base, a->limit), so its space can't be wrongly claimed. + * + * As the header is a pointer, it must be well-aligned. If pool->mask is + * greater than or equal to POINTER_MASK, the header just preceding a->base + * for an oversized arena a is well-aligned, because a->base is well-aligned. + * However, we may need to add more space to pad the JSArena ** back-pointer + * so that it lies just behind a->base, because a might not be aligned such + * that (jsuword)(a + 1) is on a pointer boundary. + * + * By how much must we pad? Let M be the alignment modulus for pool and P + * the modulus for a pointer. Given M >= P, the greatest distance between a + * pointer aligned on an M boundary and one aligned on a P boundary is M-P. + * If M and P are powers of two, then M-P = (pool->mask - POINTER_MASK). + * + * How much extra padding might spill over unused into the remainder of the + * allocation, in the worst case (where M > P)? + * + * If we add M-P to the nominal back-pointer address and then round down to + * align on a P boundary, we will use at most M-P bytes of padding, and at + * least P (M > P => M >= 2P; M == 2P gives the least padding, P). So if we + * use P bytes of padding, then we will overallocate a by P+M-1 bytes, as we + * also add M-1 to the estimated size in case malloc returns an odd pointer. + * a->limit must include this overestimation to satisfy a->avail in [a->base, + * a->limit]. + * + * Similarly, if pool->mask is less than POINTER_MASK, we must include enough + * space in the header size to align the back-pointer on a P boundary so that + * it can be found by subtracting P from a->base. This means a->base must be + * on a P boundary, even though subsequent allocations from a may be aligned + * on a lesser (M) boundary. Given powers of two M and P as above, the extra + * space needed when P > M is P-M or POINTER_MASK - pool->mask. + * + * The size of a header including padding is given by the HEADER_SIZE macro, + * below, for any pool (for any value of M). + * + * The mask to align a->base for any pool is (pool->mask | POINTER_MASK), or + * HEADER_BASE_MASK(pool). + * + * PTR_TO_HEADER computes the address of the back-pointer, given an oversized + * allocation at p. By definition, p must be a->base for the arena a that + * contains p. GET_HEADER and SET_HEADER operate on an oversized arena a, in + * the case of SET_HEADER with back-pointer ap. + */ +#define POINTER_MASK ((jsuword)(JS_ALIGN_OF_POINTER - 1)) +#define HEADER_SIZE(pool) (sizeof(JSArena **) \ + + (((pool)->mask < POINTER_MASK) \ + ? POINTER_MASK - (pool)->mask \ + : (pool)->mask - POINTER_MASK)) +#define HEADER_BASE_MASK(pool) ((pool)->mask | POINTER_MASK) +#define PTR_TO_HEADER(pool,p) (JS_ASSERT(((jsuword)(p) \ + & HEADER_BASE_MASK(pool)) \ + == 0), \ + (JSArena ***)(p) - 1) +#define GET_HEADER(pool,a) (*PTR_TO_HEADER(pool, (a)->base)) +#define SET_HEADER(pool,a,ap) (*PTR_TO_HEADER(pool, (a)->base) = (ap)) + +JS_PUBLIC_API(void *) +JS_ArenaAllocate(JSArenaPool *pool, size_t nb) +{ + JSArena **ap, **bp, *a, *b; + jsuword extra, hdrsz, gross, sz; + void *p; + + /* Search pool from current forward till we find or make enough space. */ + JS_ASSERT((nb & pool->mask) == 0); + for (a = pool->current; a->avail + nb > a->limit; pool->current = a) { + ap = &a->next; + if (!*ap) { + /* Not enough space in pool -- try to reclaim a free arena. */ + extra = (nb > pool->arenasize) ? HEADER_SIZE(pool) : 0; + hdrsz = sizeof *a + extra + pool->mask; + gross = hdrsz + JS_MAX(nb, pool->arenasize); + bp = &arena_freelist; + JS_ACQUIRE_LOCK(arena_freelist_lock); + while ((b = *bp) != NULL) { + /* + * Insist on exact arenasize match if nb is not greater than + * arenasize. Otherwise take any arena big enough, but not by + * more than gross + arenasize. + */ + sz = JS_UPTRDIFF(b->limit, b); + if (extra + ? sz >= gross && sz <= gross + pool->arenasize + : sz == gross) { + *bp = b->next; + JS_RELEASE_LOCK(arena_freelist_lock); + b->next = NULL; + COUNT(pool, nreclaims); + goto claim; + } + bp = &b->next; + } + + /* Nothing big enough on the freelist, so we must malloc. */ + JS_RELEASE_LOCK(arena_freelist_lock); + b = (JSArena *) malloc(gross); + if (!b) + return 0; + b->next = NULL; + b->limit = (jsuword)b + gross; + JS_COUNT_ARENA(pool,++); + COUNT(pool, nmallocs); + + claim: + /* If oversized, store ap in the header, just before a->base. */ + *ap = a = b; + JS_ASSERT(gross <= JS_UPTRDIFF(a->limit, a)); + if (extra) { + a->base = a->avail = + ((jsuword)a + hdrsz) & ~HEADER_BASE_MASK(pool); + SET_HEADER(pool, a, ap); + } else { + a->base = a->avail = JS_ARENA_ALIGN(pool, a + 1); + } + continue; + } + a = *ap; /* move to next arena */ + } + + p = (void *)a->avail; + a->avail += nb; + JS_ASSERT(a->base <= a->avail && a->avail <= a->limit); + return p; +} + +JS_PUBLIC_API(void *) +JS_ArenaRealloc(JSArenaPool *pool, void *p, size_t size, size_t incr) +{ + JSArena **ap, *a, *b; + jsuword boff, aoff, extra, hdrsz, gross; + + /* + * Use the oversized-single-allocation header to avoid searching for ap. + * See JS_ArenaAllocate, the SET_HEADER call. + */ + if (size > pool->arenasize) { + ap = *PTR_TO_HEADER(pool, p); + a = *ap; + } else { + ap = &pool->first.next; + while ((a = *ap) != pool->current) + ap = &a->next; + } + + JS_ASSERT(a->base == (jsuword)p); + boff = JS_UPTRDIFF(a->base, a); + aoff = size + incr; + JS_ASSERT(aoff > pool->arenasize); + extra = HEADER_SIZE(pool); /* oversized header holds ap */ + hdrsz = sizeof *a + extra + pool->mask; /* header and alignment slop */ + gross = hdrsz + aoff; + a = (JSArena *) realloc(a, gross); + if (!a) + return NULL; +#ifdef JS_ARENAMETER + pool->stats.nreallocs++; +#endif + + if (a != *ap) { + /* Oops, realloc moved the allocation: update other pointers to a. */ + if (pool->current == *ap) + pool->current = a; + b = a->next; + if (b && b->avail - b->base > pool->arenasize) { + JS_ASSERT(GET_HEADER(pool, b) == &(*ap)->next); + SET_HEADER(pool, b, &a->next); + } + + /* Now update *ap, the next link of the arena before a. */ + *ap = a; + } + + a->base = ((jsuword)a + hdrsz) & ~HEADER_BASE_MASK(pool); + a->limit = (jsuword)a + gross; + a->avail = JS_ARENA_ALIGN(pool, a->base + aoff); + JS_ASSERT(a->base <= a->avail && a->avail <= a->limit); + + /* Check whether realloc aligned differently, and copy if necessary. */ + if (boff != JS_UPTRDIFF(a->base, a)) + memmove((void *)a->base, (char *)a + boff, size); + + /* Store ap in the oversized-load arena header. */ + SET_HEADER(pool, a, ap); + return (void *)a->base; +} + +JS_PUBLIC_API(void *) +JS_ArenaGrow(JSArenaPool *pool, void *p, size_t size, size_t incr) +{ + void *newp; + + /* + * If p points to an oversized allocation, it owns an entire arena, so we + * can simply realloc the arena. + */ + if (size > pool->arenasize) + return JS_ArenaRealloc(pool, p, size, incr); + + JS_ARENA_ALLOCATE(newp, pool, size + incr); + if (newp) + memcpy(newp, p, size); + return newp; +} + +/* + * Free tail arenas linked after head, which may not be the true list head. + * Reset pool->current to point to head in case it pointed at a tail arena. + */ +static void +FreeArenaList(JSArenaPool *pool, JSArena *head, JSBool reallyFree) +{ + JSArena **ap, *a; + + ap = &head->next; + a = *ap; + if (!a) + return; + +#ifdef DEBUG + do { + JS_ASSERT(a->base <= a->avail && a->avail <= a->limit); + a->avail = a->base; + JS_CLEAR_UNUSED(a); + } while ((a = a->next) != NULL); + a = *ap; +#endif + + if (reallyFree) { + do { + *ap = a->next; + JS_CLEAR_ARENA(a); + JS_COUNT_ARENA(pool,--); + free(a); + } while ((a = *ap) != NULL); + } else { + /* Insert the whole arena chain at the front of the freelist. */ + do { + ap = &(*ap)->next; + } while (*ap); + JS_ACQUIRE_LOCK(arena_freelist_lock); + *ap = arena_freelist; + arena_freelist = a; + JS_RELEASE_LOCK(arena_freelist_lock); + head->next = NULL; + } + + pool->current = head; +} + +JS_PUBLIC_API(void) +JS_ArenaRelease(JSArenaPool *pool, char *mark) +{ + JSArena *a; + + for (a = &pool->first; a; a = a->next) { + JS_ASSERT(a->base <= a->avail && a->avail <= a->limit); + + if (JS_UPTRDIFF(mark, a->base) <= JS_UPTRDIFF(a->avail, a->base)) { + a->avail = JS_ARENA_ALIGN(pool, mark); + JS_ASSERT(a->avail <= a->limit); + FreeArenaList(pool, a, JS_TRUE); + return; + } + } +} + +JS_PUBLIC_API(void) +JS_ArenaFreeAllocation(JSArenaPool *pool, void *p, size_t size) +{ + JSArena **ap, *a, *b; + jsuword q; + + /* + * If the allocation is oversized, it consumes an entire arena, and it has + * a header just before the allocation pointing back to its predecessor's + * next member. Otherwise, we have to search pool for a. + */ + if (size > pool->arenasize) { + ap = *PTR_TO_HEADER(pool, p); + a = *ap; + } else { + q = (jsuword)p + size; + q = JS_ARENA_ALIGN(pool, q); + ap = &pool->first.next; + while ((a = *ap) != NULL) { + JS_ASSERT(a->base <= a->avail && a->avail <= a->limit); + + if (a->avail == q) { + /* + * If a is consumed by the allocation at p, we can free it to + * the malloc heap. + */ + if (a->base == (jsuword)p) + break; + + /* + * We can't free a, but we can "retract" its avail cursor -- + * whether there are others after it in pool. + */ + a->avail = (jsuword)p; + return; + } + ap = &a->next; + } + } + + /* + * At this point, a is doomed, so ensure that pool->current doesn't point + * at it. What's more, force future allocations to scavenge all arenas on + * pool, in case some have free space. + */ + if (pool->current == a) + pool->current = &pool->first; + + /* + * This is a non-LIFO deallocation, so take care to fix up a->next's back + * pointer in its header, if a->next is oversized. + */ + *ap = b = a->next; + if (b && b->avail - b->base > pool->arenasize) { + JS_ASSERT(GET_HEADER(pool, b) == &a->next); + SET_HEADER(pool, b, ap); + } + JS_CLEAR_ARENA(a); + JS_COUNT_ARENA(pool,--); + free(a); +} + +JS_PUBLIC_API(void) +JS_FreeArenaPool(JSArenaPool *pool) +{ + FreeArenaList(pool, &pool->first, JS_FALSE); + COUNT(pool, ndeallocs); +} + +JS_PUBLIC_API(void) +JS_FinishArenaPool(JSArenaPool *pool) +{ + FreeArenaList(pool, &pool->first, JS_TRUE); +#ifdef JS_ARENAMETER + { + JSArenaStats *stats, **statsp; + + if (pool->stats.name) + free(pool->stats.name); + for (statsp = &arena_stats_list; (stats = *statsp) != 0; + statsp = &stats->next) { + if (stats == &pool->stats) { + *statsp = stats->next; + return; + } + } + } +#endif +} + +JS_PUBLIC_API(void) +JS_ArenaFinish() +{ + JSArena *a, *next; + + JS_ACQUIRE_LOCK(arena_freelist_lock); + a = arena_freelist; + arena_freelist = NULL; + JS_RELEASE_LOCK(arena_freelist_lock); + for (; a; a = next) { + next = a->next; + free(a); + } +} + +JS_PUBLIC_API(void) +JS_ArenaShutDown(void) +{ +#ifdef JS_THREADSAFE + /* Must come through here once in the process's last thread! */ + if (arena_freelist_lock) { + JS_DESTROY_LOCK(arena_freelist_lock); + arena_freelist_lock = NULL; + } +#endif +} + +#ifdef JS_ARENAMETER +JS_PUBLIC_API(void) +JS_ArenaCountAllocation(JSArenaPool *pool, size_t nb) +{ + pool->stats.nallocs++; + pool->stats.nbytes += nb; + if (nb > pool->stats.maxalloc) + pool->stats.maxalloc = nb; + pool->stats.variance += nb * nb; +} + +JS_PUBLIC_API(void) +JS_ArenaCountInplaceGrowth(JSArenaPool *pool, size_t size, size_t incr) +{ + pool->stats.ninplace++; +} + +JS_PUBLIC_API(void) +JS_ArenaCountGrowth(JSArenaPool *pool, size_t size, size_t incr) +{ + pool->stats.ngrows++; + pool->stats.nbytes += incr; + pool->stats.variance -= size * size; + size += incr; + if (size > pool->stats.maxalloc) + pool->stats.maxalloc = size; + pool->stats.variance += size * size; +} + +JS_PUBLIC_API(void) +JS_ArenaCountRelease(JSArenaPool *pool, char *mark) +{ + pool->stats.nreleases++; +} + +JS_PUBLIC_API(void) +JS_ArenaCountRetract(JSArenaPool *pool, char *mark) +{ + pool->stats.nfastrels++; +} + +#include +#include + +JS_PUBLIC_API(void) +JS_DumpArenaStats(FILE *fp) +{ + JSArenaStats *stats; + uint32 nallocs, nbytes; + double mean, variance, sigma; + + for (stats = arena_stats_list; stats; stats = stats->next) { + nallocs = stats->nallocs; + if (nallocs != 0) { + nbytes = stats->nbytes; + mean = (double)nbytes / nallocs; + variance = stats->variance * nallocs - nbytes * nbytes; + if (variance < 0 || nallocs == 1) + variance = 0; + else + variance /= nallocs * (nallocs - 1); + sigma = sqrt(variance); + } else { + mean = variance = sigma = 0; + } + + fprintf(fp, "\n%s allocation statistics:\n", stats->name); + fprintf(fp, " number of arenas: %u\n", stats->narenas); + fprintf(fp, " number of allocations: %u\n", stats->nallocs); + fprintf(fp, " number of free arena reclaims: %u\n", stats->nreclaims); + fprintf(fp, " number of malloc calls: %u\n", stats->nmallocs); + fprintf(fp, " number of deallocations: %u\n", stats->ndeallocs); + fprintf(fp, " number of allocation growths: %u\n", stats->ngrows); + fprintf(fp, " number of in-place growths: %u\n", stats->ninplace); + fprintf(fp, " number of realloc'ing growths: %u\n", stats->nreallocs); + fprintf(fp, "number of released allocations: %u\n", stats->nreleases); + fprintf(fp, " number of fast releases: %u\n", stats->nfastrels); + fprintf(fp, " total bytes allocated: %u\n", stats->nbytes); + fprintf(fp, " mean allocation size: %g\n", mean); + fprintf(fp, " standard deviation: %g\n", sigma); + fprintf(fp, " maximum allocation size: %u\n", stats->maxalloc); + } +} +#endif /* JS_ARENAMETER */ diff --git a/src/dom/js/jsarena.h b/src/dom/js/jsarena.h new file mode 100644 index 000000000..e52398a1a --- /dev/null +++ b/src/dom/js/jsarena.h @@ -0,0 +1,302 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef jsarena_h___ +#define jsarena_h___ +/* + * Lifetime-based fast allocation, inspired by much prior art, including + * "Fast Allocation and Deallocation of Memory Based on Object Lifetimes" + * David R. Hanson, Software -- Practice and Experience, Vol. 20(1). + * + * Also supports LIFO allocation (JS_ARENA_MARK/JS_ARENA_RELEASE). + */ +#include +#include "jstypes.h" +#include "jscompat.h" + +JS_BEGIN_EXTERN_C + +typedef struct JSArena JSArena; +typedef struct JSArenaPool JSArenaPool; + +struct JSArena { + JSArena *next; /* next arena for this lifetime */ + jsuword base; /* aligned base address, follows this header */ + jsuword limit; /* one beyond last byte in arena */ + jsuword avail; /* points to next available byte */ +}; + +#ifdef JS_ARENAMETER +typedef struct JSArenaStats JSArenaStats; + +struct JSArenaStats { + JSArenaStats *next; /* next in arenaStats list */ + char *name; /* name for debugging */ + uint32 narenas; /* number of arenas in pool */ + uint32 nallocs; /* number of JS_ARENA_ALLOCATE() calls */ + uint32 nreclaims; /* number of reclaims from freeArenas */ + uint32 nmallocs; /* number of malloc() calls */ + uint32 ndeallocs; /* number of lifetime deallocations */ + uint32 ngrows; /* number of JS_ARENA_GROW() calls */ + uint32 ninplace; /* number of in-place growths */ + uint32 nreallocs; /* number of arena grow extending reallocs */ + uint32 nreleases; /* number of JS_ARENA_RELEASE() calls */ + uint32 nfastrels; /* number of "fast path" releases */ + size_t nbytes; /* total bytes allocated */ + size_t maxalloc; /* maximum allocation size in bytes */ + double variance; /* size variance accumulator */ +}; +#endif + +struct JSArenaPool { + JSArena first; /* first arena in pool list */ + JSArena *current; /* arena from which to allocate space */ + size_t arenasize; /* net exact size of a new arena */ + jsuword mask; /* alignment mask (power-of-2 - 1) */ +#ifdef JS_ARENAMETER + JSArenaStats stats; +#endif +}; + +/* + * If the including .c file uses only one power-of-2 alignment, it may define + * JS_ARENA_CONST_ALIGN_MASK to the alignment mask and save a few instructions + * per ALLOCATE and GROW. + */ +#ifdef JS_ARENA_CONST_ALIGN_MASK +#define JS_ARENA_ALIGN(pool, n) (((jsuword)(n) + JS_ARENA_CONST_ALIGN_MASK) \ + & ~(jsuword)JS_ARENA_CONST_ALIGN_MASK) + +#define JS_INIT_ARENA_POOL(pool, name, size) \ + JS_InitArenaPool(pool, name, size, JS_ARENA_CONST_ALIGN_MASK + 1) +#else +#define JS_ARENA_ALIGN(pool, n) (((jsuword)(n) + (pool)->mask) & ~(pool)->mask) +#endif + +#define JS_ARENA_ALLOCATE(p, pool, nb) \ + JS_ARENA_ALLOCATE_CAST(p, void *, pool, nb) + +#define JS_ARENA_ALLOCATE_TYPE(p, type, pool) \ + JS_ARENA_ALLOCATE_CAST(p, type *, pool, sizeof(type)) + +#define JS_ARENA_ALLOCATE_CAST(p, type, pool, nb) \ + JS_BEGIN_MACRO \ + JSArena *_a = (pool)->current; \ + size_t _nb = JS_ARENA_ALIGN(pool, nb); \ + jsuword _p = _a->avail; \ + jsuword _q = _p + _nb; \ + JS_ASSERT(_q >= _p); \ + if (_q > _a->limit) \ + _p = (jsuword)JS_ArenaAllocate(pool, _nb); \ + else \ + _a->avail = _q; \ + p = (type) _p; \ + JS_ArenaCountAllocation(pool, nb); \ + JS_END_MACRO + +#define JS_ARENA_GROW(p, pool, size, incr) \ + JS_ARENA_GROW_CAST(p, void *, pool, size, incr) + +#define JS_ARENA_GROW_CAST(p, type, pool, size, incr) \ + JS_BEGIN_MACRO \ + JSArena *_a = (pool)->current; \ + if (_a->avail == (jsuword)(p) + JS_ARENA_ALIGN(pool, size)) { \ + size_t _nb = (size) + (incr); \ + jsuword _q = (jsuword)(p) + JS_ARENA_ALIGN(pool, _nb); \ + if (_q <= _a->limit) { \ + _a->avail = _q; \ + JS_ArenaCountInplaceGrowth(pool, size, incr); \ + } else if ((jsuword)(p) == _a->base) { \ + p = (type) JS_ArenaRealloc(pool, p, size, incr); \ + } else { \ + p = (type) JS_ArenaGrow(pool, p, size, incr); \ + } \ + } else { \ + p = (type) JS_ArenaGrow(pool, p, size, incr); \ + } \ + JS_ArenaCountGrowth(pool, size, incr); \ + JS_END_MACRO + +#define JS_ARENA_MARK(pool) ((void *) (pool)->current->avail) +#define JS_UPTRDIFF(p,q) ((jsuword)(p) - (jsuword)(q)) + +#ifdef DEBUG +#define JS_FREE_PATTERN 0xDA +#define JS_CLEAR_UNUSED(a) (JS_ASSERT((a)->avail <= (a)->limit), \ + memset((void*)(a)->avail, JS_FREE_PATTERN, \ + (a)->limit - (a)->avail)) +#define JS_CLEAR_ARENA(a) memset((void*)(a), JS_FREE_PATTERN, \ + (a)->limit - (jsuword)(a)) +#else +#define JS_CLEAR_UNUSED(a) /* nothing */ +#define JS_CLEAR_ARENA(a) /* nothing */ +#endif + +#define JS_ARENA_RELEASE(pool, mark) \ + JS_BEGIN_MACRO \ + char *_m = (char *)(mark); \ + JSArena *_a = (pool)->current; \ + if (_a != &(pool)->first && \ + JS_UPTRDIFF(_m, _a->base) <= JS_UPTRDIFF(_a->avail, _a->base)) { \ + _a->avail = (jsuword)JS_ARENA_ALIGN(pool, _m); \ + JS_ASSERT(_a->avail <= _a->limit); \ + JS_CLEAR_UNUSED(_a); \ + JS_ArenaCountRetract(pool, _m); \ + } else { \ + JS_ArenaRelease(pool, _m); \ + } \ + JS_ArenaCountRelease(pool, _m); \ + JS_END_MACRO + +#ifdef JS_ARENAMETER +#define JS_COUNT_ARENA(pool,op) ((pool)->stats.narenas op) +#else +#define JS_COUNT_ARENA(pool,op) +#endif + +#define JS_ARENA_DESTROY(pool, a, pnext) \ + JS_BEGIN_MACRO \ + JS_COUNT_ARENA(pool,--); \ + if ((pool)->current == (a)) (pool)->current = &(pool)->first; \ + *(pnext) = (a)->next; \ + JS_CLEAR_ARENA(a); \ + free(a); \ + (a) = NULL; \ + JS_END_MACRO + +/* + * Initialize an arena pool with the given name for debugging and metering, + * with a minimum size per arena of size bytes. + */ +extern JS_PUBLIC_API(void) +JS_InitArenaPool(JSArenaPool *pool, const char *name, size_t size, + size_t align); + +/* + * Free the arenas in pool. The user may continue to allocate from pool + * after calling this function. There is no need to call JS_InitArenaPool() + * again unless JS_FinishArenaPool(pool) has been called. + */ +extern JS_PUBLIC_API(void) +JS_FreeArenaPool(JSArenaPool *pool); + +/* + * Free the arenas in pool and finish using it altogether. + */ +extern JS_PUBLIC_API(void) +JS_FinishArenaPool(JSArenaPool *pool); + +/* + * Finish using arenas, freeing all memory associated with them except for + * any locks needed for thread safety. + */ +extern JS_PUBLIC_API(void) +JS_ArenaFinish(void); + +/* + * Free any locks or other memory needed for thread safety, just before + * shutting down. At that point, we must be called by a single thread. + * + * After shutting down, the next thread to call JS_InitArenaPool must not + * race with any other thread. Once a pool has been initialized, threads + * may safely call jsarena.c functions on thread-local pools. The upshot + * is that pools are per-thread, but the underlying global freelist is + * thread-safe, provided that both the first pool initialization and the + * shut-down call are single-threaded. + */ +extern JS_PUBLIC_API(void) +JS_ArenaShutDown(void); + +/* + * Friend functions used by the JS_ARENA_*() macros. + */ +extern JS_PUBLIC_API(void *) +JS_ArenaAllocate(JSArenaPool *pool, size_t nb); + +extern JS_PUBLIC_API(void *) +JS_ArenaRealloc(JSArenaPool *pool, void *p, size_t size, size_t incr); + +extern JS_PUBLIC_API(void *) +JS_ArenaGrow(JSArenaPool *pool, void *p, size_t size, size_t incr); + +extern JS_PUBLIC_API(void) +JS_ArenaRelease(JSArenaPool *pool, char *mark); + +/* + * Function to be used directly when an allocation has likely grown to consume + * an entire JSArena, in which case the arena is returned to the malloc heap. + */ +extern JS_PUBLIC_API(void) +JS_ArenaFreeAllocation(JSArenaPool *pool, void *p, size_t size); + +#ifdef JS_ARENAMETER + +#include + +extern JS_PUBLIC_API(void) +JS_ArenaCountAllocation(JSArenaPool *pool, size_t nb); + +extern JS_PUBLIC_API(void) +JS_ArenaCountInplaceGrowth(JSArenaPool *pool, size_t size, size_t incr); + +extern JS_PUBLIC_API(void) +JS_ArenaCountGrowth(JSArenaPool *pool, size_t size, size_t incr); + +extern JS_PUBLIC_API(void) +JS_ArenaCountRelease(JSArenaPool *pool, char *mark); + +extern JS_PUBLIC_API(void) +JS_ArenaCountRetract(JSArenaPool *pool, char *mark); + +extern JS_PUBLIC_API(void) +JS_DumpArenaStats(FILE *fp); + +#else /* !JS_ARENAMETER */ + +#define JS_ArenaCountAllocation(ap, nb) /* nothing */ +#define JS_ArenaCountInplaceGrowth(ap, size, incr) /* nothing */ +#define JS_ArenaCountGrowth(ap, size, incr) /* nothing */ +#define JS_ArenaCountRelease(ap, mark) /* nothing */ +#define JS_ArenaCountRetract(ap, mark) /* nothing */ + +#endif /* !JS_ARENAMETER */ + +JS_END_EXTERN_C + +#endif /* jsarena_h___ */ diff --git a/src/dom/js/jsarray.c b/src/dom/js/jsarray.c new file mode 100644 index 000000000..250c67557 --- /dev/null +++ b/src/dom/js/jsarray.c @@ -0,0 +1,1429 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* + * JS array class. + */ +#include "jsstddef.h" +#include +#include +#include "jstypes.h" +#include "jsutil.h" /* Added by JSIFY */ +#include "jsapi.h" +#include "jsarray.h" +#include "jsatom.h" +#include "jscntxt.h" +#include "jsconfig.h" +#include "jsfun.h" +#include "jsgc.h" +#include "jsinterp.h" +#include "jslock.h" +#include "jsnum.h" +#include "jsobj.h" +#include "jsstr.h" + +/* 2^32 - 1 as a number and a string */ +#define MAXINDEX 4294967295u +#define MAXSTR "4294967295" + +/* + * Determine if the id represents an array index. + * + * An id is an array index according to ECMA by (15.4): + * + * "Array objects give special treatment to a certain class of property names. + * A property name P (in the form of a string value) is an array index if and + * only if ToString(ToUint32(P)) is equal to P and ToUint32(P) is not equal + * to 2^32-1." + * + * In our implementation, it would be sufficient to check for JSVAL_IS_INT(id) + * except that by using signed 32-bit integers we miss the top half of the + * valid range. This function checks the string representation itself; note + * that calling a standard conversion routine might allow strings such as + * "08" or "4.0" as array indices, which they are not. + */ +static JSBool +IdIsIndex(jsid id, jsuint *indexp) +{ + JSString *str; + jschar *cp; + + if (JSVAL_IS_INT(id)) { + jsint i; + i = JSVAL_TO_INT(id); + if (i < 0) + return JS_FALSE; + *indexp = (jsuint)i; + return JS_TRUE; + } + + /* It must be a string. */ + str = JSVAL_TO_STRING(id); + cp = JSSTRING_CHARS(str); + if (JS7_ISDEC(*cp) && JSSTRING_LENGTH(str) < sizeof(MAXSTR)) { + jsuint index = JS7_UNDEC(*cp++); + jsuint oldIndex = 0; + jsuint c = 0; + if (index != 0) { + while (JS7_ISDEC(*cp)) { + oldIndex = index; + c = JS7_UNDEC(*cp); + index = 10*index + c; + cp++; + } + } + /* Make sure all characters were consumed and that it couldn't + * have overflowed. + */ + if (*cp == 0 && + (oldIndex < (MAXINDEX / 10) || + (oldIndex == (MAXINDEX / 10) && c < (MAXINDEX % 10)))) + { + *indexp = index; + return JS_TRUE; + } + } + return JS_FALSE; +} + +static JSBool +ValueIsLength(JSContext *cx, jsval v, jsuint *lengthp) +{ + jsint i; + jsdouble d; + + if (JSVAL_IS_INT(v)) { + i = JSVAL_TO_INT(v); + if (i < 0) { + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, + JSMSG_BAD_ARRAY_LENGTH); + return JS_FALSE; + } + *lengthp = (jsuint) i; + return JS_TRUE; + } + + if (!js_ValueToNumber(cx, v, &d)) { + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, + JSMSG_BAD_ARRAY_LENGTH); + return JS_FALSE; + } + if (!js_DoubleToECMAUint32(cx, d, (uint32 *)lengthp)) { + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, + JSMSG_BAD_ARRAY_LENGTH); + return JS_FALSE; + } + if (JSDOUBLE_IS_NaN(d) || d != *lengthp) { + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, + JSMSG_BAD_ARRAY_LENGTH); + return JS_FALSE; + } + return JS_TRUE; +} + +JSBool +js_GetLengthProperty(JSContext *cx, JSObject *obj, jsuint *lengthp) +{ + jsid id; + jsint i; + jsval v; + + id = (jsid) cx->runtime->atomState.lengthAtom; + if (!OBJ_GET_PROPERTY(cx, obj, id, &v)) + return JS_FALSE; + + /* Short-circuit, because js_ValueToECMAUint32 fails when + * called during init time. + */ + if (JSVAL_IS_INT(v)) { + i = JSVAL_TO_INT(v); + /* jsuint cast does ToUint32. */ + *lengthp = (jsuint)i; + return JS_TRUE; + } + return js_ValueToECMAUint32(cx, v, (uint32 *)lengthp); +} + +static JSBool +IndexToValue(JSContext *cx, jsuint length, jsval *vp) +{ + if (length <= JSVAL_INT_MAX) { + *vp = INT_TO_JSVAL(length); + return JS_TRUE; + } + return js_NewDoubleValue(cx, (jsdouble)length, vp); +} + +static JSBool +IndexToId(JSContext *cx, jsuint length, jsid *idp) +{ + JSString *str; + JSAtom *atom; + + if (length <= JSVAL_INT_MAX) { + *idp = (jsid) INT_TO_JSVAL(length); + } else { + str = js_NumberToString(cx, (jsdouble)length); + if (!str) + return JS_FALSE; + atom = js_AtomizeString(cx, str, 0); + if (!atom) + return JS_FALSE; + *idp = (jsid)atom; + + } + return JS_TRUE; +} + +JSBool +js_SetLengthProperty(JSContext *cx, JSObject *obj, jsuint length) +{ + jsval v; + jsid id; + + if (!IndexToValue(cx, length, &v)) + return JS_FALSE; + id = (jsid) cx->runtime->atomState.lengthAtom; + return OBJ_SET_PROPERTY(cx, obj, id, &v); +} + +JSBool +js_HasLengthProperty(JSContext *cx, JSObject *obj, jsuint *lengthp) +{ + JSErrorReporter older; + jsid id; + JSBool ok; + jsval v; + + older = JS_SetErrorReporter(cx, NULL); + id = (jsid) cx->runtime->atomState.lengthAtom; + ok = OBJ_GET_PROPERTY(cx, obj, id, &v); + JS_SetErrorReporter(cx, older); + if (!ok) + return JS_FALSE; + return ValueIsLength(cx, v, lengthp); +} + +/* + * This get function is specific to Array.prototype.length and other array + * instance length properties. It calls back through the class get function + * in case some magic happens there (see call_getProperty in jsfun.c). + */ +static JSBool +array_length_getter(JSContext *cx, JSObject *obj, jsval id, jsval *vp) +{ + return OBJ_GET_CLASS(cx, obj)->getProperty(cx, obj, id, vp); +} + +static JSBool +array_length_setter(JSContext *cx, JSObject *obj, jsval id, jsval *vp) +{ + jsuint newlen, oldlen, slot; + jsid id2; + jsval junk; + + if (!ValueIsLength(cx, *vp, &newlen)) + return JS_FALSE; + if (!js_GetLengthProperty(cx, obj, &oldlen)) + return JS_FALSE; + slot = oldlen; + while (slot > newlen) { + --slot; + if (!IndexToId(cx, slot, &id2)) + return JS_FALSE; + if (!OBJ_DELETE_PROPERTY(cx, obj, id2, &junk)) + return JS_FALSE; + } + return IndexToValue(cx, newlen, vp); +} + +static JSBool +array_addProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp) +{ + jsuint index, length; + + if (!(IdIsIndex(id, &index))) + return JS_TRUE; + if (!js_GetLengthProperty(cx, obj, &length)) + return JS_FALSE; + if (index >= length) { + length = index + 1; + return js_SetLengthProperty(cx, obj, length); + } + return JS_TRUE; +} + +static JSBool +array_convert(JSContext *cx, JSObject *obj, JSType type, jsval *vp) +{ + jsuint length; + + if (cx->version == JSVERSION_1_2) { + if (!js_GetLengthProperty(cx, obj, &length)) + return JS_FALSE; + switch (type) { + case JSTYPE_NUMBER: + return IndexToValue(cx, length, vp); + case JSTYPE_BOOLEAN: + *vp = BOOLEAN_TO_JSVAL(length > 0); + return JS_TRUE; + default: + return JS_TRUE; + } + } + return js_TryValueOf(cx, obj, type, vp); +} + +JSClass js_ArrayClass = { + "Array", + 0, + array_addProperty, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, + JS_EnumerateStub, JS_ResolveStub, array_convert, JS_FinalizeStub, + JSCLASS_NO_OPTIONAL_MEMBERS +}; + +static JSBool +array_join_sub(JSContext *cx, JSObject *obj, JSString *sep, JSBool literalize, + jsval *rval, JSBool localeString) +{ + JSBool ok; + jsval v; + jsuint length, index; + jschar *chars, *ochars; + size_t nchars, growth, seplen, tmplen; + const jschar *sepstr; + JSString *str; + JSHashEntry *he; + JSObject *obj2; + + ok = js_GetLengthProperty(cx, obj, &length); + if (!ok) + return JS_FALSE; + ok = JS_TRUE; + + he = js_EnterSharpObject(cx, obj, NULL, &chars); + if (!he) + return JS_FALSE; + if (literalize) { + if (IS_SHARP(he)) { +#if JS_HAS_SHARP_VARS + nchars = js_strlen(chars); +#else + chars[0] = '['; + chars[1] = ']'; + chars[2] = 0; + nchars = 2; +#endif + goto make_string; + } + + /* + * Allocate 1 + 3 + 1 for "[", the worst-case closing ", ]", and the + * terminating 0. + */ + growth = (1 + 3 + 1) * sizeof(jschar); + if (!chars) { + nchars = 0; + chars = (jschar *) malloc(growth); + if (!chars) + goto done; + } else { + MAKE_SHARP(he); + nchars = js_strlen(chars); + chars = (jschar *) + realloc((ochars = chars), nchars * sizeof(jschar) + growth); + if (!chars) { + free(ochars); + goto done; + } + } + chars[nchars++] = '['; + } else { + /* + * Free any sharp variable definition in chars. Normally, we would + * MAKE_SHARP(he) so that only the first sharp variable annotation is + * a definition, and all the rest are references, but in the current + * case of (!literalize), we don't need chars at all. + */ + if (chars) + JS_free(cx, chars); + chars = NULL; + nchars = 0; + + /* Return the empty string on a cycle as well as on empty join. */ + if (IS_BUSY(he) || length == 0) { + js_LeaveSharpObject(cx, NULL); + *rval = JS_GetEmptyStringValue(cx); + return ok; + } + + /* Flag he as BUSY so we can distinguish a cycle from a join-point. */ + MAKE_BUSY(he); + } + sepstr = NULL; + seplen = JSSTRING_LENGTH(sep); + + v = JSVAL_NULL; + for (index = 0; index < length; index++) { + ok = JS_GetElement(cx, obj, index, &v); + if (!ok) + goto done; + + if (JSVAL_IS_VOID(v) || JSVAL_IS_NULL(v)) { + str = cx->runtime->emptyString; + } else { + if (localeString) { + if (!js_ValueToObject(cx, v, &obj2) || + !js_TryMethod(cx, obj2, + cx->runtime->atomState.toLocaleStringAtom, + 0, NULL, &v)) { + str = NULL; + } else { + str = js_ValueToString(cx, v); + } + } else { + str = (literalize ? js_ValueToSource : js_ValueToString)(cx, v); + } + if (!str) { + ok = JS_FALSE; + goto done; + } + } + + /* Allocate 3 + 1 at end for ", ", closing bracket, and zero. */ + growth = (nchars + (sepstr ? seplen : 0) + + JSSTRING_LENGTH(str) + + 3 + 1) * sizeof(jschar); + if (!chars) { + chars = (jschar *) malloc(growth); + if (!chars) + goto done; + } else { + chars = (jschar *) realloc((ochars = chars), growth); + if (!chars) { + free(ochars); + goto done; + } + } + + if (sepstr) { + js_strncpy(&chars[nchars], sepstr, seplen); + nchars += seplen; + } + sepstr = JSSTRING_CHARS(sep); + + tmplen = JSSTRING_LENGTH(str); + js_strncpy(&chars[nchars], JSSTRING_CHARS(str), tmplen); + nchars += tmplen; + } + + done: + if (literalize) { + if (chars) { + if (JSVAL_IS_VOID(v)) { + chars[nchars++] = ','; + chars[nchars++] = ' '; + } + chars[nchars++] = ']'; + } + } else { + CLEAR_BUSY(he); + } + js_LeaveSharpObject(cx, NULL); + if (!ok) { + if (chars) + free(chars); + return ok; + } + + make_string: + if (!chars) { + JS_ReportOutOfMemory(cx); + return JS_FALSE; + } + chars[nchars] = 0; + str = js_NewString(cx, chars, nchars, 0); + if (!str) { + free(chars); + return JS_FALSE; + } + *rval = STRING_TO_JSVAL(str); + return JS_TRUE; +} + +static jschar comma_space_ucstr[] = {',', ' ', 0}; +static jschar comma_ucstr[] = {',', 0}; +static JSString comma_space = {2, comma_space_ucstr}; +static JSString comma = {1, comma_ucstr}; + +#if JS_HAS_TOSOURCE +static JSBool +array_toSource(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval) +{ + return array_join_sub(cx, obj, &comma_space, JS_TRUE, rval, JS_FALSE); +} +#endif + +static JSBool +array_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval) +{ + JSBool literalize; + + /* + * JS1.2 arrays convert to array literals, with a comma followed by a space + * between each element. + */ + literalize = (cx->version == JSVERSION_1_2); + return array_join_sub(cx, obj, literalize ? &comma_space : &comma, + literalize, rval, JS_FALSE); +} + +static JSBool +array_toLocaleString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval) +{ + /* + * Passing comma here as the separator. Need a way to get a + * locale-specific version. + */ + return array_join_sub(cx, obj, &comma, JS_FALSE, rval, JS_TRUE); +} + +static JSBool +InitArrayElements(JSContext *cx, JSObject *obj, jsuint length, jsval *vector) +{ + jsuint index; + jsid id; + + for (index = 0; index < length; index++) { + if (!IndexToId(cx, index, &id)) + return JS_FALSE; + if (!OBJ_SET_PROPERTY(cx, obj, id, &vector[index])) + return JS_FALSE; + } + return JS_TRUE; +} + +static JSBool +InitArrayObject(JSContext *cx, JSObject *obj, jsuint length, jsval *vector) +{ + jsval v; + jsid id; + + if (!IndexToValue(cx, length, &v)) + return JS_FALSE; + id = (jsid) cx->runtime->atomState.lengthAtom; + if (!OBJ_DEFINE_PROPERTY(cx, obj, id, v, + array_length_getter, array_length_setter, + JSPROP_PERMANENT, + NULL)) { + return JS_FALSE; + } + if (!vector) + return JS_TRUE; + return InitArrayElements(cx, obj, length, vector); +} + +#if JS_HAS_SOME_PERL_FUN +/* + * Perl-inspired join, reverse, and sort. + */ +static JSBool +array_join(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + JSString *str; + + if (JSVAL_IS_VOID(argv[0])) + return array_join_sub(cx, obj, &comma, JS_FALSE, rval, JS_FALSE); + str = js_ValueToString(cx, argv[0]); + if (!str) + return JS_FALSE; + argv[0] = STRING_TO_JSVAL(str); + return array_join_sub(cx, obj, str, JS_FALSE, rval, JS_FALSE); +} + +static JSBool +array_reverse(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval) +{ + jsuint len, half, i; + jsid id, id2; + jsval v, v2; + + if (!js_GetLengthProperty(cx, obj, &len)) + return JS_FALSE; + + half = len / 2; + for (i = 0; i < half; i++) { + if (!IndexToId(cx, i, &id)) + return JS_FALSE; + if (!IndexToId(cx, len - i - 1, &id2)) + return JS_FALSE; + if (!OBJ_GET_PROPERTY(cx, obj, id, &v)) + return JS_FALSE; + if (!OBJ_GET_PROPERTY(cx, obj, id2, &v2)) + return JS_FALSE; + +#if JS_HAS_SPARSE_ARRAYS + /* This part isn't done yet. */ + + if (!OBJ_LOOKUP_PROPERTY(cx, obj, id, &obj2, &prop)) + return JS_FALSE; + if (!prop) { + OBJ_DELETE_PROPERTY(cx, obj, id2, &v); /* v is junk. */ + continue; + } + OBJ_DROP_PROPERTY(cx, obj2, prop); +#endif + + if (!OBJ_SET_PROPERTY(cx, obj, id, &v2)) + return JS_FALSE; + if (!OBJ_SET_PROPERTY(cx, obj, id2, &v)) + return JS_FALSE; + } + + *rval = OBJECT_TO_JSVAL(obj); + return JS_TRUE; +} + +typedef struct HSortArgs { + void *vec; + size_t elsize; + void *pivot; + JSComparator cmp; + void *arg; + JSBool fastcopy; +} HSortArgs; + +static int +sort_compare(const void *a, const void *b, void *arg); + +static int +sort_compare_strings(const void *a, const void *b, void *arg); + +static void +HeapSortHelper(JSBool building, HSortArgs *hsa, size_t lo, size_t hi) +{ + void *pivot, *vec, *vec2, *arg, *a, *b; + size_t elsize; + JSComparator cmp; + JSBool fastcopy; + size_t j, hiDiv2; + + pivot = hsa->pivot; + vec = hsa->vec; + elsize = hsa->elsize; + vec2 = (char *)vec - 2 * elsize; + cmp = hsa->cmp; + arg = hsa->arg; + + fastcopy = hsa->fastcopy; +#define MEMCPY(p,q,n) \ + (fastcopy ? (void)(*(jsval*)(p) = *(jsval*)(q)) : (void)memcpy(p, q, n)) + + if (lo == 1) { + j = 2; + b = (char *)vec + elsize; + if (j < hi && cmp(vec, b, arg) < 0) + j++; + a = (char *)vec + (hi - 1) * elsize; + b = (char *)vec2 + j * elsize; + + /* + * During sorting phase b points to a member of heap that cannot be + * bigger then biggest of vec[0] and vec[1], and cmp(a, b, arg) <= 0 + * always holds. + */ + if ((building || hi == 2) && cmp(a, b, arg) >= 0) + return; + + MEMCPY(pivot, a, elsize); + MEMCPY(a, b, elsize); + lo = j; + } else { + a = (char *)vec2 + lo * elsize; + MEMCPY(pivot, a, elsize); + } + + hiDiv2 = hi/2; + while (lo <= hiDiv2) { + j = lo + lo; + a = (char *)vec2 + j * elsize; + b = (char *)vec + (j - 1) * elsize; + if (j < hi && cmp(a, b, arg) < 0) + j++; + b = (char *)vec2 + j * elsize; + if (cmp(pivot, b, arg) >= 0) + break; + + a = (char *)vec2 + lo * elsize; + MEMCPY(a, b, elsize); + lo = j; + } + + a = (char *)vec2 + lo * elsize; + MEMCPY(a, pivot, elsize); +#undef MEMCPY +} + +JSBool +js_HeapSort(void *vec, size_t nel, size_t elsize, JSComparator cmp, void *arg) +{ + void *pivot; + HSortArgs hsa; + size_t i; + + pivot = malloc(elsize); + if (!pivot) + return JS_FALSE; + hsa.vec = vec; + hsa.elsize = elsize; + hsa.pivot = pivot; + hsa.cmp = cmp; + hsa.arg = arg; + hsa.fastcopy = (cmp == sort_compare || cmp == sort_compare_strings); + + for (i = nel/2; i != 0; i--) + HeapSortHelper(JS_TRUE, &hsa, i, nel); + while (nel > 2) + HeapSortHelper(JS_FALSE, &hsa, 1, --nel); + + free(pivot); + return JS_TRUE; +} + +typedef struct CompareArgs { + JSContext *context; + jsval fval; + JSBool status; +} CompareArgs; + +static int +sort_compare(const void *a, const void *b, void *arg) +{ + jsval av = *(const jsval *)a, bv = *(const jsval *)b; + CompareArgs *ca = (CompareArgs *) arg; + JSContext *cx = ca->context; + jsdouble cmp = -1; + jsval fval, argv[2], rval; + JSBool ok; + + fval = ca->fval; + if (fval == JSVAL_NULL) { + JSString *astr, *bstr; + + if (av == bv) { + cmp = 0; + } else if (av == JSVAL_VOID || bv == JSVAL_VOID) { + /* Put undefined properties at the end. */ + cmp = (av == JSVAL_VOID) ? 1 : -1; + } else if ((astr = js_ValueToString(cx, av)) != NULL && + (bstr = js_ValueToString(cx, bv)) != NULL) { + cmp = js_CompareStrings(astr, bstr); + } else { + ca->status = JS_FALSE; + } + } else { + argv[0] = av; + argv[1] = bv; + ok = js_InternalCall(cx, + OBJ_GET_PARENT(cx, JSVAL_TO_OBJECT(fval)), + fval, 2, argv, &rval); + if (ok) { + ok = js_ValueToNumber(cx, rval, &cmp); + /* Clamp cmp to -1, 0, 1. */ + if (JSDOUBLE_IS_NaN(cmp)) { + /* XXX report some kind of error here? ECMA talks about + * 'consistent compare functions' that don't return NaN, but is + * silent about what the result should be. So we currently + * ignore it. + */ + cmp = 0; + } else if (cmp != 0) { + cmp = cmp > 0 ? 1 : -1; + } + } else { + ca->status = ok; + } + } + return (int)cmp; +} + +static int +sort_compare_strings(const void *a, const void *b, void *arg) +{ + jsval av = *(const jsval *)a, bv = *(const jsval *)b; + + return (int) js_CompareStrings(JSVAL_TO_STRING(av), JSVAL_TO_STRING(bv)); +} + +/* XXXmccabe do the sort helper functions need to take int? (Or can we claim + * that 2^32 * 32 is too large to worry about?) Something dumps when I change + * to unsigned int; is qsort using -1 as a fencepost? + */ +static JSBool +array_sort(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + jsval fval; + CompareArgs ca; + jsuint len, newlen, i; + jsval *vec; + jsid id; + size_t nbytes; + + /* + * Optimize the default compare function case if all of obj's elements + * have values of type string. + */ + JSBool all_strings; + + if (argc > 0) { + if (JSVAL_IS_PRIMITIVE(argv[0])) { + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, + JSMSG_BAD_SORT_ARG); + return JS_FALSE; + } + fval = argv[0]; + all_strings = JS_FALSE; /* non-default compare function */ + } else { + fval = JSVAL_NULL; + all_strings = JS_TRUE; /* check for all string values */ + } + + if (!js_GetLengthProperty(cx, obj, &len)) + return JS_FALSE; + if (len == 0) { + *rval = OBJECT_TO_JSVAL(obj); + return JS_TRUE; + } + + /* + * Test for size_t overflow, which could lead to indexing beyond the end + * of the malloc'd vector. + */ + nbytes = len * sizeof(jsval); + if (nbytes != (double) len * sizeof(jsval)) { + JS_ReportOutOfMemory(cx); + return JS_FALSE; + } + vec = (jsval *) JS_malloc(cx, nbytes); + if (!vec) + return JS_FALSE; + +#if JS_HAS_SPARSE_ARRAYS + newlen = 0; +#else + newlen = len; +#endif + + for (i = 0; i < len; i++) { + ca.status = IndexToId(cx, i, &id); + if (!ca.status) + goto out; +#if JS_HAS_SPARSE_ARRAYS + { + JSObject *obj2; + JSProperty *prop; + ca.status = OBJ_LOOKUP_PROPERTY(cx, obj, id, &obj2, &prop); + if (!ca.status) + goto out; + if (!prop) { + vec[i] = JSVAL_VOID; + continue; + } + OBJ_DROP_PROPERTY(cx, obj2, prop); + newlen++; + } +#endif + ca.status = OBJ_GET_PROPERTY(cx, obj, id, &vec[i]); + if (!ca.status) + goto out; + + /* We know JSVAL_IS_STRING yields 0 or 1, so avoid a branch via &=. */ + all_strings &= JSVAL_IS_STRING(vec[i]); + } + + ca.context = cx; + ca.fval = fval; + ca.status = JS_TRUE; + if (!js_HeapSort(vec, (size_t) len, sizeof(jsval), + all_strings ? sort_compare_strings : sort_compare, + &ca)) { + JS_ReportOutOfMemory(cx); + ca.status = JS_FALSE; + } + + if (ca.status) { + ca.status = InitArrayElements(cx, obj, newlen, vec); + if (ca.status) + *rval = OBJECT_TO_JSVAL(obj); +#if JS_HAS_SPARSE_ARRAYS + /* set length of newly-created array object to old length. */ + if (ca.status && newlen < len) { + ca.status = js_SetLengthProperty(cx, obj, len); + + /* Delete any leftover properties greater than newlen. */ + while (ca.status && newlen < len) { + jsval junk; + + ca.status = !IndexToId(cx, newlen, &id) || + !OBJ_DELETE_PROPERTY(cx, obj, id, &junk); + newlen++; + } + } +#endif + } + +out: + if (vec) + JS_free(cx, vec); + return ca.status; +} +#endif /* JS_HAS_SOME_PERL_FUN */ + +#if JS_HAS_MORE_PERL_FUN +/* + * Perl-inspired push, pop, shift, unshift, and splice methods. + */ +static JSBool +array_push(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + jsuint length; + uintN i; + jsid id; + + if (!js_GetLengthProperty(cx, obj, &length)) + return JS_FALSE; + for (i = 0; i < argc; i++) { + if (!IndexToId(cx, length + i, &id)) + return JS_FALSE; + if (!OBJ_SET_PROPERTY(cx, obj, id, &argv[i])) + return JS_FALSE; + } + + /* + * If JS1.2, follow Perl4 by returning the last thing pushed. Otherwise, + * return the new array length. + */ + length += argc; + if (cx->version == JSVERSION_1_2) { + *rval = argc ? argv[argc-1] : JSVAL_VOID; + } else { + if (!IndexToValue(cx, length, rval)) + return JS_FALSE; + } + return js_SetLengthProperty(cx, obj, length); +} + +static JSBool +array_pop(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + jsuint index; + jsid id; + jsval junk; + + if (!js_GetLengthProperty(cx, obj, &index)) + return JS_FALSE; + if (index > 0) { + index--; + if (!IndexToId(cx, index, &id)) + return JS_FALSE; + + /* Get the to-be-deleted property's value into rval. */ + if (!OBJ_GET_PROPERTY(cx, obj, id, rval)) + return JS_FALSE; + + if (!OBJ_DELETE_PROPERTY(cx, obj, id, &junk)) + return JS_FALSE; + } + return js_SetLengthProperty(cx, obj, index); +} + +static JSBool +array_shift(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + jsuint length, i; + jsid id, id2; + jsval v, junk; + + if (!js_GetLengthProperty(cx, obj, &length)) + return JS_FALSE; + if (length > 0) { + length--; + id = JSVAL_ZERO; + + /* Get the to-be-deleted property's value into rval ASAP. */ + if (!OBJ_GET_PROPERTY(cx, obj, id, rval)) + return JS_FALSE; + + /* + * Slide down the array above the first element. + */ + if (length > 0) { + for (i = 1; i <= length; i++) { + if (!IndexToId(cx, i, &id)) + return JS_FALSE; + if (!IndexToId(cx, i - 1, &id2)) + return JS_FALSE; + if (!OBJ_GET_PROPERTY(cx, obj, id, &v)) + return JS_FALSE; + if (!OBJ_SET_PROPERTY(cx, obj, id2, &v)) + return JS_FALSE; + } + } + + /* Delete the only or last element. */ + if (!OBJ_DELETE_PROPERTY(cx, obj, id, &junk)) + return JS_FALSE; + } + return js_SetLengthProperty(cx, obj, length); +} + +static JSBool +array_unshift(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval) +{ + jsuint length, last; + uintN i; + jsid id, id2; + jsval v; +#if JS_HAS_SPARSE_ARRAYS + JSObject *obj2; + JSProperty *prop; +#endif + + if (!js_GetLengthProperty(cx, obj, &length)) + return JS_FALSE; + if (argc > 0) { + /* Slide up the array to make room for argc at the bottom. */ + if (length > 0) { + last = length; + while (last--) { + if (!IndexToId(cx, last, &id)) + return JS_FALSE; + if (!IndexToId(cx, last + argc, &id2)) + return JS_FALSE; +#if JS_HAS_SPARSE_ARRAYS + if (!OBJ_LOOKUP_PROPERTY(cx, obj, id, &obj2, &prop)) + return JS_FALSE; + if (!prop) { + OBJ_DELETE_PROPERTY(cx, obj, id2, &v); /* v is junk. */ + continue; + } + OBJ_DROP_PROPERTY(cx, obj2, prop); +#endif + if (!OBJ_GET_PROPERTY(cx, obj, id, &v)) + return JS_FALSE; + if (!OBJ_SET_PROPERTY(cx, obj, id2, &v)) + return JS_FALSE; + } + } + + /* Copy from argv to the bottom of the array. */ + for (i = 0; i < argc; i++) { + if (!IndexToId(cx, i, &id)) + return JS_FALSE; + if (!OBJ_SET_PROPERTY(cx, obj, id, &argv[i])) + return JS_FALSE; + } + + /* Follow Perl by returning the new array length. */ + length += argc; + if (!js_SetLengthProperty(cx, obj, length)) + return JS_FALSE; + } + return IndexToValue(cx, length, rval); +} + +static JSBool +array_splice(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + jsuint length, begin, end, count, delta, last; + uintN i; + jsdouble d; + jsid id, id2; + jsval v; + JSObject *obj2; + + /* Nothing to do if no args. Otherwise lock and load length. */ + if (argc == 0) + return JS_TRUE; + if (!js_GetLengthProperty(cx, obj, &length)) + return JS_FALSE; + + /* Convert the first argument into a starting index. */ + if (!js_ValueToNumber(cx, *argv, &d)) + return JS_FALSE; + d = js_DoubleToInteger(d); + if (d < 0) { + d += length; + if (d < 0) + d = 0; + } else if (d > length) { + d = length; + } + begin = (jsuint)d; /* d has been clamped to uint32 */ + argc--; + argv++; + + /* Convert the second argument from a count into a fencepost index. */ + delta = length - begin; + if (argc == 0) { + count = delta; + end = length; + } else { + if (!js_ValueToNumber(cx, *argv, &d)) + return JS_FALSE; + d = js_DoubleToInteger(d); + if (d < 0) + d = 0; + else if (d > delta) + d = delta; + count = (jsuint)d; + end = begin + count; + argc--; + argv++; + } + + if (count == 1 && cx->version == JSVERSION_1_2) { + /* + * JS lacks "list context", whereby in Perl one turns the single + * scalar that's spliced out into an array just by assigning it to + * @single instead of $single, or by using it as Perl push's first + * argument, for instance. + * + * JS1.2 emulated Perl too closely and returned a non-Array for + * the single-splice-out case, requiring callers to test and wrap + * in [] if necessary. So JS1.3, default, and other versions all + * return an array of length 1 for uniformity. + */ + if (!IndexToId(cx, begin, &id)) + return JS_FALSE; + if (!OBJ_GET_PROPERTY(cx, obj, id, rval)) + return JS_FALSE; + } else { + if (cx->version != JSVERSION_1_2 || count > 0) { + /* + * Create a new array value to return. Our ECMA v2 proposal specs + * that splice always returns an array value, even when given no + * arguments. We think this is best because it eliminates the need + * for callers to do an extra test to handle the empty splice case. + */ + obj2 = js_NewArrayObject(cx, 0, NULL); + if (!obj2) + return JS_FALSE; + *rval = OBJECT_TO_JSVAL(obj2); + + /* If there are elements to remove, put them into the return value. */ + if (count > 0) { + for (last = begin; last < end; last++) { + if (!IndexToId(cx, last, &id)) + return JS_FALSE; + if (!IndexToId(cx, last - begin, &id2)) + return JS_FALSE; + if (!OBJ_GET_PROPERTY(cx, obj, id, &v)) + return JS_FALSE; + if (!OBJ_SET_PROPERTY(cx, obj2, id2, &v)) + return JS_FALSE; + } + } + } + } + + /* Find the direction (up or down) to copy and make way for argv. */ + if (argc > count) { + delta = (jsuint)argc - count; + last = length; + /* (uint) end could be 0, so can't use vanilla >= test */ + while (last-- > end) { + if (!IndexToId(cx, last, &id)) + return JS_FALSE; + if (!IndexToId(cx, last + delta, &id2)) + return JS_FALSE; + if (!OBJ_GET_PROPERTY(cx, obj, id, &v)) + return JS_FALSE; + if (!OBJ_SET_PROPERTY(cx, obj, id2, &v)) + return JS_FALSE; + } + length += delta; + } else if (argc < count) { + delta = count - (jsuint)argc; + for (last = end; last < length; last++) { + if (!IndexToId(cx, last, &id)) + return JS_FALSE; + if (!IndexToId(cx, last - delta, &id2)) + return JS_FALSE; + if (!OBJ_GET_PROPERTY(cx, obj, id, &v)) + return JS_FALSE; + if (!OBJ_SET_PROPERTY(cx, obj, id2, &v)) + return JS_FALSE; + } + length -= delta; + } + + /* Copy from argv into the hole to complete the splice. */ + for (i = 0; i < argc; i++) { + if (!IndexToId(cx, begin + i, &id)) + return JS_FALSE; + if (!OBJ_SET_PROPERTY(cx, obj, id, &argv[i])) + return JS_FALSE; + } + + /* Update length in case we deleted elements from the end. */ + return js_SetLengthProperty(cx, obj, length); +} +#endif /* JS_HAS_MORE_PERL_FUN */ + +#if JS_HAS_SEQUENCE_OPS +/* + * Python-esque sequence operations. + */ +static JSBool +array_concat(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + JSObject *nobj, *aobj; + jsuint length, alength, slot; + uintN i; + jsval v; + jsid id, id2; + + /* Treat obj as the first argument; see ECMA 15.4.4.4. */ + --argv; + JS_ASSERT(obj == JSVAL_TO_OBJECT(argv[0])); + + /* Create a new Array object and store it in the rval local root. */ + nobj = js_NewArrayObject(cx, 0, NULL); + if (!nobj) + return JS_FALSE; + *rval = OBJECT_TO_JSVAL(nobj); + + /* Loop over [0, argc] to concat args into nobj, expanding all Arrays. */ + length = 0; + for (i = 0; i <= argc; i++) { + v = argv[i]; + if (JSVAL_IS_OBJECT(v)) { + aobj = JSVAL_TO_OBJECT(v); + if (aobj && OBJ_GET_CLASS(cx, aobj) == &js_ArrayClass) { + if (!OBJ_GET_PROPERTY(cx, aobj, + (jsid)cx->runtime->atomState.lengthAtom, + &v)) { + return JS_FALSE; + } + if (!ValueIsLength(cx, v, &alength)) + return JS_FALSE; + for (slot = 0; slot < alength; slot++) { + if (!IndexToId(cx, slot, &id)) + return JS_FALSE; + if (!IndexToId(cx, length + slot, &id2)) + return JS_FALSE; + if (!OBJ_GET_PROPERTY(cx, aobj, id, &v)) + return JS_FALSE; + if (!OBJ_SET_PROPERTY(cx, nobj, id2, &v)) + return JS_FALSE; + } + length += alength; + continue; + } + } + + if (!IndexToId(cx, length, &id)) + return JS_FALSE; + if (!OBJ_SET_PROPERTY(cx, nobj, id, &v)) + return JS_FALSE; + length++; + } + + return JS_TRUE; +} + +static JSBool +array_slice(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + JSObject *nobj; + jsuint length, begin, end, slot; + jsdouble d; + jsid id, id2; + jsval v; + + nobj = js_NewArrayObject(cx, 0, NULL); + if (!nobj) + return JS_FALSE; + + if (!js_GetLengthProperty(cx, obj, &length)) + return JS_FALSE; + begin = 0; + end = length; + + if (argc > 0) { + if (!js_ValueToNumber(cx, argv[0], &d)) + return JS_FALSE; + d = js_DoubleToInteger(d); + if (d < 0) { + d += length; + if (d < 0) + d = 0; + } else if (d > length) { + d = length; + } + begin = (jsuint)d; + + if (argc > 1) { + if (!js_ValueToNumber(cx, argv[1], &d)) + return JS_FALSE; + d = js_DoubleToInteger(d); + if (d < 0) { + d += length; + if (d < 0) + d = 0; + } else if (d > length) { + d = length; + } + end = (jsuint)d; + } + } + + for (slot = begin; slot < end; slot++) { + if (!IndexToId(cx, slot, &id)) + return JS_FALSE; + if (!IndexToId(cx, slot - begin, &id2)) + return JS_FALSE; + if (!OBJ_GET_PROPERTY(cx, obj, id, &v)) + return JS_FALSE; + if (!OBJ_SET_PROPERTY(cx, nobj, id2, &v)) + return JS_FALSE; + } + *rval = OBJECT_TO_JSVAL(nobj); + return JS_TRUE; +} +#endif /* JS_HAS_SEQUENCE_OPS */ + +static JSFunctionSpec array_methods[] = { +#if JS_HAS_TOSOURCE + {js_toSource_str, array_toSource, 0,0,0}, +#endif + {js_toString_str, array_toString, 0,0,0}, + {js_toLocaleString_str, array_toLocaleString, 0,0,0}, + + /* Perl-ish methods. */ +#if JS_HAS_SOME_PERL_FUN + {"join", array_join, 1,0,0}, + {"reverse", array_reverse, 0,0,0}, + {"sort", array_sort, 1,0,0}, +#endif +#if JS_HAS_MORE_PERL_FUN + {"push", array_push, 1,0,0}, + {"pop", array_pop, 0,0,0}, + {"shift", array_shift, 0,0,0}, + {"unshift", array_unshift, 1,0,0}, + {"splice", array_splice, 1,0,0}, +#endif + + /* Python-esque sequence methods. */ +#if JS_HAS_SEQUENCE_OPS + {"concat", array_concat, 0,0,0}, + {"slice", array_slice, 0,0,0}, +#endif + + {0,0,0,0,0} +}; + +static JSBool +Array(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + jsuint length; + jsval *vector; + + /* If called without new, replace obj with a new Array object. */ + if (!(cx->fp->flags & JSFRAME_CONSTRUCTING)) { + obj = js_NewObject(cx, &js_ArrayClass, NULL, NULL); + if (!obj) + return JS_FALSE; + *rval = OBJECT_TO_JSVAL(obj); + } + + if (argc == 0) { + length = 0; + vector = NULL; + } else if (cx->version == JSVERSION_1_2) { + length = (jsuint) argc; + vector = argv; + } else if (argc > 1) { + length = (jsuint) argc; + vector = argv; + } else if (!JSVAL_IS_NUMBER(argv[0])) { + length = 1; + vector = argv; + } else { + if (!ValueIsLength(cx, argv[0], &length)) + return JS_FALSE; + vector = NULL; + } + return InitArrayObject(cx, obj, length, vector); +} + +JSObject * +js_InitArrayClass(JSContext *cx, JSObject *obj) +{ + JSObject *proto; + + proto = JS_InitClass(cx, obj, NULL, &js_ArrayClass, Array, 1, + NULL, array_methods, NULL, NULL); + + /* Initialize the Array prototype object so it gets a length property. */ + if (!proto || !InitArrayObject(cx, proto, 0, NULL)) + return NULL; + return proto; +} + +JSObject * +js_NewArrayObject(JSContext *cx, jsuint length, jsval *vector) +{ + JSObject *obj; + + obj = js_NewObject(cx, &js_ArrayClass, NULL, NULL); + if (!obj) + return NULL; + if (!InitArrayObject(cx, obj, length, vector)) { + cx->newborn[GCX_OBJECT] = NULL; + return NULL; + } + return obj; +} diff --git a/src/dom/js/jsarray.h b/src/dom/js/jsarray.h new file mode 100644 index 000000000..cbb2aedf1 --- /dev/null +++ b/src/dom/js/jsarray.h @@ -0,0 +1,77 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef jsarray_h___ +#define jsarray_h___ +/* + * JS Array interface. + */ +#include "jsprvtd.h" +#include "jspubtd.h" + +JS_BEGIN_EXTERN_C + +extern JSClass js_ArrayClass; + +extern JSObject * +js_InitArrayClass(JSContext *cx, JSObject *obj); + +extern JSObject * +js_NewArrayObject(JSContext *cx, jsuint length, jsval *vector); + +extern JSBool +js_GetLengthProperty(JSContext *cx, JSObject *obj, jsuint *lengthp); + +extern JSBool +js_SetLengthProperty(JSContext *cx, JSObject *obj, jsuint length); + +extern JSBool +js_HasLengthProperty(JSContext *cx, JSObject *obj, jsuint *lengthp); + +/* + * JS-specific heap sort function. + */ +typedef int (*JSComparator)(const void *a, const void *b, void *arg); + +extern JSBool +js_HeapSort(void *vec, size_t nel, size_t elsize, JSComparator cmp, void *arg); + +JS_END_EXTERN_C + +#endif /* jsarray_h___ */ diff --git a/src/dom/js/jsatom.c b/src/dom/js/jsatom.c new file mode 100644 index 000000000..59cb4b801 --- /dev/null +++ b/src/dom/js/jsatom.c @@ -0,0 +1,911 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* + * JS atom table. + */ +#include "jsstddef.h" +#include +#include +#include "jstypes.h" +#include "jsutil.h" /* Added by JSIFY */ +#include "jshash.h" /* Added by JSIFY */ +#include "jsprf.h" +#include "jsapi.h" +#include "jsatom.h" +#include "jscntxt.h" +#include "jsgc.h" +#include "jslock.h" +#include "jsnum.h" +#include "jsopcode.h" +#include "jsstr.h" + +JS_FRIEND_API(const char *) +js_AtomToPrintableString(JSContext *cx, JSAtom *atom) +{ + JSString *str; + const char *bytes; + + str = js_QuoteString(cx, ATOM_TO_STRING(atom), 0); + if (!str) + return NULL; + bytes = js_GetStringBytes(str); + if (!bytes) + JS_ReportOutOfMemory(cx); + return bytes; +} + +extern const char js_Error_str[]; /* trivial, from jsexn.h */ + +/* + * Keep this in sync with jspubtd.h -- an assertion below will insist that + * its length match the JSType enum's JSTYPE_LIMIT limit value. + */ +const char *js_type_str[] = { + "undefined", + "object", + "function", + "string", + "number", + "boolean", +}; + +const char *js_boolean_str[] = { + js_false_str, + js_true_str +}; + +const char js_Arguments_str[] = "Arguments"; +const char js_Array_str[] = "Array"; +const char js_Boolean_str[] = "Boolean"; +const char js_Call_str[] = "Call"; +const char js_Date_str[] = "Date"; +const char js_Function_str[] = "Function"; +const char js_Math_str[] = "Math"; +const char js_Number_str[] = "Number"; +const char js_Object_str[] = "Object"; +const char js_RegExp_str[] = "RegExp"; +const char js_Script_str[] = "Script"; +const char js_String_str[] = "String"; +const char js_anonymous_str[] = "anonymous"; +const char js_arguments_str[] = "arguments"; +const char js_arity_str[] = "arity"; +const char js_callee_str[] = "callee"; +const char js_caller_str[] = "caller"; +const char js_class_prototype_str[] = "prototype"; +const char js_constructor_str[] = "constructor"; +const char js_count_str[] = "__count__"; +const char js_eval_str[] = "eval"; +const char js_getter_str[] = "getter"; +const char js_get_str[] = "get"; +const char js_index_str[] = "index"; +const char js_input_str[] = "input"; +const char js_length_str[] = "length"; +const char js_name_str[] = "name"; +const char js_noSuchMethod_str[] = "__noSuchMethod__"; +const char js_parent_str[] = "__parent__"; +const char js_proto_str[] = "__proto__"; +const char js_setter_str[] = "setter"; +const char js_set_str[] = "set"; +const char js_toSource_str[] = "toSource"; +const char js_toString_str[] = "toString"; +const char js_toLocaleString_str[] = "toLocaleString"; +const char js_valueOf_str[] = "valueOf"; + +#define HASH_OBJECT(o) ((JSHashNumber)(o) >> JSVAL_TAGBITS) +#define HASH_INT(i) ((JSHashNumber)(i)) +#define HASH_DOUBLE(dp) ((JSHashNumber)(((uint32*)(dp))[0] ^ ((uint32*)(dp))[1])) +#define HASH_BOOLEAN(b) ((JSHashNumber)(b)) + +JS_STATIC_DLL_CALLBACK(JSHashNumber) +js_hash_atom_key(const void *key) +{ + jsval v; + jsdouble *dp; + + /* Order JSVAL_IS_* tests by likelihood of success. */ + v = (jsval)key; + if (JSVAL_IS_STRING(v)) + return js_HashString(JSVAL_TO_STRING(v)); + if (JSVAL_IS_INT(v)) + return HASH_INT(JSVAL_TO_INT(v)); + if (JSVAL_IS_DOUBLE(v)) { + dp = JSVAL_TO_DOUBLE(v); + return HASH_DOUBLE(dp); + } + if (JSVAL_IS_OBJECT(v)) + return HASH_OBJECT(JSVAL_TO_OBJECT(v)); + if (JSVAL_IS_BOOLEAN(v)) + return HASH_BOOLEAN(JSVAL_TO_BOOLEAN(v)); + return (JSHashNumber)v; +} + +JS_STATIC_DLL_CALLBACK(intN) +js_compare_atom_keys(const void *k1, const void *k2) +{ + jsval v1, v2; + + v1 = (jsval)k1, v2 = (jsval)k2; + if (JSVAL_IS_STRING(v1) && JSVAL_IS_STRING(v2)) + return !js_CompareStrings(JSVAL_TO_STRING(v1), JSVAL_TO_STRING(v2)); + if (JSVAL_IS_DOUBLE(v1) && JSVAL_IS_DOUBLE(v2)) { + double d1 = *JSVAL_TO_DOUBLE(v1); + double d2 = *JSVAL_TO_DOUBLE(v2); + if (JSDOUBLE_IS_NaN(d1)) + return JSDOUBLE_IS_NaN(d2); +#if defined(XP_WIN) + /* XXX MSVC miscompiles such that (NaN == 0) */ + if (JSDOUBLE_IS_NaN(d2)) + return JS_FALSE; +#endif + return d1 == d2; + } + return v1 == v2; +} + +JS_STATIC_DLL_CALLBACK(int) +js_compare_stub(const void *v1, const void *v2) +{ + return 1; +} + +/* These next two are exported to jsscript.c and used similarly there. */ +void * JS_DLL_CALLBACK +js_alloc_table_space(void *priv, size_t size) +{ + return malloc(size); +} + +void JS_DLL_CALLBACK +js_free_table_space(void *priv, void *item) +{ + free(item); +} + +JS_STATIC_DLL_CALLBACK(JSHashEntry *) +js_alloc_atom(void *priv, const void *key) +{ + JSAtomState *state = (JSAtomState *) priv; + JSAtom *atom; + + atom = (JSAtom *) malloc(sizeof(JSAtom)); + if (!atom) + return NULL; +#ifdef JS_THREADSAFE + state->tablegen++; +#endif + atom->entry.key = key; + atom->entry.value = NULL; + atom->flags = 0; + atom->number = state->number++; + return &atom->entry; +} + +JS_STATIC_DLL_CALLBACK(void) +js_free_atom(void *priv, JSHashEntry *he, uintN flag) +{ + if (flag != HT_FREE_ENTRY) + return; +#ifdef JS_THREADSAFE + ((JSAtomState *)priv)->tablegen++; +#endif + free(he); +} + +static JSHashAllocOps atom_alloc_ops = { + js_alloc_table_space, js_free_table_space, + js_alloc_atom, js_free_atom +}; + +#define JS_ATOM_HASH_SIZE 1024 + +JSBool +js_InitAtomState(JSContext *cx, JSAtomState *state) +{ + state->table = JS_NewHashTable(JS_ATOM_HASH_SIZE, js_hash_atom_key, + js_compare_atom_keys, js_compare_stub, + &atom_alloc_ops, state); + if (!state->table) { + JS_ReportOutOfMemory(cx); + return JS_FALSE; + } + + state->runtime = cx->runtime; +#ifdef JS_THREADSAFE + js_InitLock(&state->lock); + state->tablegen = 0; +#endif + + if (!js_InitPinnedAtoms(cx, state)) { + js_FreeAtomState(cx, state); + return JS_FALSE; + } + return JS_TRUE; +} + +JSBool +js_InitPinnedAtoms(JSContext *cx, JSAtomState *state) +{ + uintN i; + +#define FROB(lval,str) \ + JS_BEGIN_MACRO \ + if (!(state->lval = js_Atomize(cx, str, strlen(str), ATOM_PINNED))) \ + return JS_FALSE; \ + JS_END_MACRO + + JS_ASSERT(sizeof js_type_str / sizeof js_type_str[0] == JSTYPE_LIMIT); + for (i = 0; i < JSTYPE_LIMIT; i++) + FROB(typeAtoms[i], js_type_str[i]); + + FROB(booleanAtoms[0], js_false_str); + FROB(booleanAtoms[1], js_true_str); + FROB(nullAtom, js_null_str); + + FROB(ArgumentsAtom, js_Arguments_str); + FROB(ArrayAtom, js_Array_str); + FROB(BooleanAtom, js_Boolean_str); + FROB(CallAtom, js_Call_str); + FROB(DateAtom, js_Date_str); + FROB(ErrorAtom, js_Error_str); + FROB(FunctionAtom, js_Function_str); + FROB(MathAtom, js_Math_str); + FROB(NumberAtom, js_Number_str); + FROB(ObjectAtom, js_Object_str); + FROB(RegExpAtom, js_RegExp_str); + FROB(ScriptAtom, js_Script_str); + FROB(StringAtom, js_String_str); + FROB(anonymousAtom, js_anonymous_str); + FROB(argumentsAtom, js_arguments_str); + FROB(arityAtom, js_arity_str); + FROB(calleeAtom, js_callee_str); + FROB(callerAtom, js_caller_str); + FROB(classPrototypeAtom, js_class_prototype_str); + FROB(constructorAtom, js_constructor_str); + FROB(countAtom, js_count_str); + FROB(evalAtom, js_eval_str); + FROB(getAtom, js_get_str); + FROB(getterAtom, js_getter_str); + FROB(indexAtom, js_index_str); + FROB(inputAtom, js_input_str); + FROB(lengthAtom, js_length_str); + FROB(nameAtom, js_name_str); + FROB(noSuchMethodAtom, js_noSuchMethod_str); + FROB(parentAtom, js_parent_str); + FROB(protoAtom, js_proto_str); + FROB(setAtom, js_set_str); + FROB(setterAtom, js_setter_str); + FROB(toSourceAtom, js_toSource_str); + FROB(toStringAtom, js_toString_str); + FROB(toLocaleStringAtom, js_toLocaleString_str); + FROB(valueOfAtom, js_valueOf_str); + +#undef FROB + + memset(&state->lazy, 0, sizeof state->lazy); + return JS_TRUE; +} + +/* NB: cx unused; js_FinishAtomState calls us with null cx. */ +void +js_FreeAtomState(JSContext *cx, JSAtomState *state) +{ + if (state->table) + JS_HashTableDestroy(state->table); +#ifdef JS_THREADSAFE + js_FinishLock(&state->lock); +#endif + memset(state, 0, sizeof *state); +} + +typedef struct UninternArgs { + JSRuntime *rt; + jsatomid leaks; +} UninternArgs; + +JS_STATIC_DLL_CALLBACK(intN) +js_atom_uninterner(JSHashEntry *he, intN i, void *arg) +{ + JSAtom *atom; + UninternArgs *args; + + atom = (JSAtom *)he; + args = (UninternArgs *)arg; + if (ATOM_IS_STRING(atom)) + js_FinalizeStringRT(args->rt, ATOM_TO_STRING(atom)); + else if (ATOM_IS_OBJECT(atom)) + args->leaks++; + return HT_ENUMERATE_NEXT; +} + +void +js_FinishAtomState(JSAtomState *state) +{ + UninternArgs args; + + if (!state->table) + return; + args.rt = state->runtime; + args.leaks = 0; + JS_HashTableEnumerateEntries(state->table, js_atom_uninterner, &args); +#ifdef DEBUG + if (args.leaks != 0) { + fprintf(stderr, +"JS engine warning: %lu atoms remain after destroying the JSRuntime.\n" +" These atoms may point to freed memory. Things reachable\n" +" through them have not been finalized.\n", + (unsigned long) args.leaks); + } +#endif + js_FreeAtomState(NULL, state); +} + +typedef struct MarkArgs { + uintN gcflags; + JSGCThingMarker mark; + void *data; +} MarkArgs; + +JS_STATIC_DLL_CALLBACK(intN) +js_atom_marker(JSHashEntry *he, intN i, void *arg) +{ + JSAtom *atom; + MarkArgs *args; + jsval key; + + atom = (JSAtom *)he; + args = (MarkArgs *)arg; + if ((atom->flags & (ATOM_PINNED | ATOM_INTERNED)) || + (args->gcflags & GC_KEEP_ATOMS)) { + atom->flags |= ATOM_MARK; + key = ATOM_KEY(atom); + if (JSVAL_IS_GCTHING(key)) + args->mark(JSVAL_TO_GCTHING(key), args->data); + } + return HT_ENUMERATE_NEXT; +} + +void +js_MarkAtomState(JSAtomState *state, uintN gcflags, JSGCThingMarker mark, + void *data) +{ + MarkArgs args; + + if (!state->table) + return; + args.gcflags = gcflags; + args.mark = mark; + args.data = data; + JS_HashTableEnumerateEntries(state->table, js_atom_marker, &args); +} + +JS_STATIC_DLL_CALLBACK(intN) +js_atom_sweeper(JSHashEntry *he, intN i, void *arg) +{ + JSAtom *atom; + JSAtomState *state; + + atom = (JSAtom *)he; + if (atom->flags & ATOM_MARK) { + atom->flags &= ~ATOM_MARK; + state = (JSAtomState *)arg; + state->liveAtoms++; + return HT_ENUMERATE_NEXT; + } + JS_ASSERT((atom->flags & (ATOM_PINNED | ATOM_INTERNED)) == 0); + atom->entry.key = NULL; + atom->flags = 0; + return HT_ENUMERATE_REMOVE; +} + +void +js_SweepAtomState(JSAtomState *state) +{ + state->liveAtoms = 0; + if (state->table) + JS_HashTableEnumerateEntries(state->table, js_atom_sweeper, state); +} + +JS_STATIC_DLL_CALLBACK(intN) +js_atom_unpinner(JSHashEntry *he, intN i, void *arg) +{ + JSAtom *atom; + + atom = (JSAtom *)he; + atom->flags &= ~ATOM_PINNED; + return HT_ENUMERATE_NEXT; +} + +void +js_UnpinPinnedAtoms(JSAtomState *state) +{ + if (state->table) + JS_HashTableEnumerateEntries(state->table, js_atom_unpinner, NULL); +} + +static JSAtom * +js_AtomizeHashedKey(JSContext *cx, jsval key, JSHashNumber keyHash, uintN flags) +{ + JSAtomState *state; + JSHashTable *table; + JSHashEntry *he, **hep; + JSAtom *atom; + + state = &cx->runtime->atomState; + JS_LOCK(&state->lock, cx); + table = state->table; + hep = JS_HashTableRawLookup(table, keyHash, (void *)key); + if ((he = *hep) == NULL) { + he = JS_HashTableRawAdd(table, hep, keyHash, (void *)key, NULL); + if (!he) { + JS_ReportOutOfMemory(cx); + atom = NULL; + goto out; + } + } + + atom = (JSAtom *)he; + atom->flags |= flags; + cx->lastAtom = atom; +out: + JS_UNLOCK(&state->lock,cx); + return atom; +} + +JSAtom * +js_AtomizeObject(JSContext *cx, JSObject *obj, uintN flags) +{ + jsval key; + JSHashNumber keyHash; + + /* XXX must be set in the following order or MSVC1.52 will crash */ + keyHash = HASH_OBJECT(obj); + key = OBJECT_TO_JSVAL(obj); + return js_AtomizeHashedKey(cx, key, keyHash, flags); +} + +JSAtom * +js_AtomizeBoolean(JSContext *cx, JSBool b, uintN flags) +{ + jsval key; + JSHashNumber keyHash; + + key = BOOLEAN_TO_JSVAL(b); + keyHash = HASH_BOOLEAN(b); + return js_AtomizeHashedKey(cx, key, keyHash, flags); +} + +JSAtom * +js_AtomizeInt(JSContext *cx, jsint i, uintN flags) +{ + jsval key; + JSHashNumber keyHash; + + key = INT_TO_JSVAL(i); + keyHash = HASH_INT(i); + return js_AtomizeHashedKey(cx, key, keyHash, flags); +} + +/* Worst-case alignment grain and aligning macro for 2x-sized buffer. */ +#define ALIGNMENT(t) JS_MAX(JSVAL_ALIGN, sizeof(t)) +#define ALIGN(b,t) ((t*) &(b)[ALIGNMENT(t) - (jsuword)(b) % ALIGNMENT(t)]) + +JSAtom * +js_AtomizeDouble(JSContext *cx, jsdouble d, uintN flags) +{ + jsdouble *dp; + JSHashNumber keyHash; + jsval key; + JSAtomState *state; + JSHashTable *table; + JSHashEntry *he, **hep; + JSAtom *atom; + char buf[2 * ALIGNMENT(double)]; + + dp = ALIGN(buf, double); + *dp = d; + keyHash = HASH_DOUBLE(dp); + key = DOUBLE_TO_JSVAL(dp); + state = &cx->runtime->atomState; + JS_LOCK(&state->lock, cx); + table = state->table; + hep = JS_HashTableRawLookup(table, keyHash, (void *)key); + if ((he = *hep) == NULL) { +#ifdef JS_THREADSAFE + uint32 gen = state->tablegen; +#endif + JS_UNLOCK(&state->lock,cx); + if (!js_NewDoubleValue(cx, d, &key)) + return NULL; + JS_LOCK(&state->lock, cx); +#ifdef JS_THREADSAFE + if (state->tablegen != gen) { + hep = JS_HashTableRawLookup(table, keyHash, (void *)key); + if ((he = *hep) != NULL) { + atom = (JSAtom *)he; + goto out; + } + } +#endif + he = JS_HashTableRawAdd(table, hep, keyHash, (void *)key, NULL); + if (!he) { + JS_ReportOutOfMemory(cx); + atom = NULL; + goto out; + } + } + + atom = (JSAtom *)he; + atom->flags |= flags; + cx->lastAtom = atom; +out: + JS_UNLOCK(&state->lock,cx); + return atom; +} + +JSAtom * +js_AtomizeString(JSContext *cx, JSString *str, uintN flags) +{ + JSHashNumber keyHash; + jsval key; + JSAtomState *state; + JSHashTable *table; + JSHashEntry *he, **hep; + JSAtom *atom; + + keyHash = js_HashString(str); + key = STRING_TO_JSVAL(str); + state = &cx->runtime->atomState; + JS_LOCK(&state->lock, cx); + table = state->table; + hep = JS_HashTableRawLookup(table, keyHash, (void *)key); + if ((he = *hep) == NULL) { +#ifdef JS_THREADSAFE + uint32 gen = state->tablegen; + JS_UNLOCK(&state->lock, cx); +#endif + + if (flags & ATOM_TMPSTR) { + str = (flags & ATOM_NOCOPY) + ? js_NewString(cx, str->chars, str->length, 0) + : js_NewStringCopyN(cx, str->chars, str->length, 0); + if (!str) + return NULL; + key = STRING_TO_JSVAL(str); + } else { + if (!JS_MakeStringImmutable(cx, str)) + return NULL; + } + +#ifdef JS_THREADSAFE + JS_LOCK(&state->lock, cx); + if (state->tablegen != gen) { + hep = JS_HashTableRawLookup(table, keyHash, (void *)key); + if ((he = *hep) != NULL) { + atom = (JSAtom *)he; + if (flags & ATOM_NOCOPY) + str->chars = NULL; + goto out; + } + } +#endif + + he = JS_HashTableRawAdd(table, hep, keyHash, (void *)key, NULL); + if (!he) { + JS_ReportOutOfMemory(cx); + atom = NULL; + goto out; + } + } + + atom = (JSAtom *)he; + atom->flags |= flags & (ATOM_PINNED | ATOM_INTERNED); + cx->lastAtom = atom; +out: + JS_UNLOCK(&state->lock,cx); + return atom; +} + +JS_FRIEND_API(JSAtom *) +js_Atomize(JSContext *cx, const char *bytes, size_t length, uintN flags) +{ + jschar *chars; + JSString *str; + JSAtom *atom; + char buf[2 * ALIGNMENT(JSString)]; + + /* + * Avoiding the malloc in js_InflateString on shorter strings saves us + * over 20,000 malloc calls on mozilla browser startup. This compares to + * only 131 calls where the string is longer than a 31 char (net) buffer. + * The vast majority of atomized strings are already in the hashtable. So + * js_AtomizeString rarely has to copy the temp string we make. + */ +#define ATOMIZE_BUF_MAX 32 + jschar inflated[ATOMIZE_BUF_MAX]; + + if (length < ATOMIZE_BUF_MAX) { + js_InflateStringToBuffer(inflated, bytes, length); + chars = inflated; + } else { + chars = js_InflateString(cx, bytes, length); + if (!chars) + return NULL; + flags |= ATOM_NOCOPY; + } + + str = ALIGN(buf, JSString); + + str->chars = chars; + str->length = length; + atom = js_AtomizeString(cx, str, ATOM_TMPSTR | flags); + if (chars != inflated && (!atom || ATOM_TO_STRING(atom)->chars != chars)) + JS_free(cx, chars); + return atom; +} + +JS_FRIEND_API(JSAtom *) +js_AtomizeChars(JSContext *cx, const jschar *chars, size_t length, uintN flags) +{ + JSString *str; + char buf[2 * ALIGNMENT(JSString)]; + + str = ALIGN(buf, JSString); + str->chars = (jschar *)chars; + str->length = length; + return js_AtomizeString(cx, str, ATOM_TMPSTR | flags); +} + +JSAtom * +js_AtomizeValue(JSContext *cx, jsval value, uintN flags) +{ + if (JSVAL_IS_STRING(value)) + return js_AtomizeString(cx, JSVAL_TO_STRING(value), flags); + if (JSVAL_IS_INT(value)) + return js_AtomizeInt(cx, JSVAL_TO_INT(value), flags); + if (JSVAL_IS_DOUBLE(value)) + return js_AtomizeDouble(cx, *JSVAL_TO_DOUBLE(value), flags); + if (JSVAL_IS_OBJECT(value)) + return js_AtomizeObject(cx, JSVAL_TO_OBJECT(value), flags); + if (JSVAL_IS_BOOLEAN(value)) + return js_AtomizeBoolean(cx, JSVAL_TO_BOOLEAN(value), flags); + return js_AtomizeHashedKey(cx, value, (JSHashNumber)value, flags); +} + +JSAtom * +js_ValueToStringAtom(JSContext *cx, jsval v) +{ + JSString *str; + + str = js_ValueToString(cx, v); + if (!str) + return NULL; + return js_AtomizeString(cx, str, 0); +} + +JS_STATIC_DLL_CALLBACK(JSHashNumber) +js_hash_atom_ptr(const void *key) +{ + const JSAtom *atom = key; + return atom->number; +} + +JS_STATIC_DLL_CALLBACK(void *) +js_alloc_temp_space(void *priv, size_t size) +{ + JSContext *cx = priv; + void *space; + + JS_ARENA_ALLOCATE(space, &cx->tempPool, size); + if (!space) + JS_ReportOutOfMemory(cx); + return space; +} + +JS_STATIC_DLL_CALLBACK(void) +js_free_temp_space(void *priv, void *item) +{ +} + +JS_STATIC_DLL_CALLBACK(JSHashEntry *) +js_alloc_temp_entry(void *priv, const void *key) +{ + JSContext *cx = priv; + JSAtomListElement *ale; + + JS_ARENA_ALLOCATE_TYPE(ale, JSAtomListElement, &cx->tempPool); + if (!ale) { + JS_ReportOutOfMemory(cx); + return NULL; + } + return &ale->entry; +} + +JS_STATIC_DLL_CALLBACK(void) +js_free_temp_entry(void *priv, JSHashEntry *he, uintN flag) +{ +} + +static JSHashAllocOps temp_alloc_ops = { + js_alloc_temp_space, js_free_temp_space, + js_alloc_temp_entry, js_free_temp_entry +}; + +JSAtomListElement * +js_IndexAtom(JSContext *cx, JSAtom *atom, JSAtomList *al) +{ + JSAtomListElement *ale, *ale2, *next; + JSHashEntry **hep; + + ATOM_LIST_LOOKUP(ale, hep, al, atom); + if (!ale) { + if (al->count <= 5) { + /* Few enough for linear search, no hash table needed. */ + JS_ASSERT(!al->table); + ale = (JSAtomListElement *)js_alloc_temp_entry(cx, atom); + if (!ale) + return NULL; + ALE_SET_ATOM(ale, atom); + ALE_SET_NEXT(ale, al->list); + al->list = ale; + } else { + /* We want to hash. Have we already made a hash table? */ + if (!al->table) { + /* No hash table yet, so hep had better be null! */ + JS_ASSERT(!hep); + al->table = JS_NewHashTable(8, js_hash_atom_ptr, + JS_CompareValues, JS_CompareValues, + &temp_alloc_ops, cx); + if (!al->table) + return NULL; + + /* Insert each ale on al->list into the new hash table. */ + for (ale2 = al->list; ale2; ale2 = next) { + next = ALE_NEXT(ale2); + ale2->entry.keyHash = ALE_ATOM(ale2)->number; + hep = JS_HashTableRawLookup(al->table, ale2->entry.keyHash, + ale2->entry.key); + ALE_SET_NEXT(ale2, *hep); + *hep = &ale2->entry; + } + al->list = NULL; + + /* Set hep for insertion of atom's ale, immediately below. */ + hep = JS_HashTableRawLookup(al->table, atom->number, atom); + } + + /* Finally, add an entry for atom into the hash bucket at hep. */ + ale = (JSAtomListElement *) + JS_HashTableRawAdd(al->table, hep, atom->number, atom, NULL); + if (!ale) + return NULL; + } + + ALE_SET_INDEX(ale, al->count++); + } + return ale; +} + +JS_FRIEND_API(JSAtom *) +js_GetAtom(JSContext *cx, JSAtomMap *map, jsatomid i) +{ + JSAtom *atom; + static JSAtom dummy; + + JS_ASSERT(map->vector && i < map->length); + if (!map->vector || i >= map->length) { + char numBuf[12]; + JS_snprintf(numBuf, sizeof numBuf, "%lu", (unsigned long)i); + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, + JSMSG_BAD_ATOMIC_NUMBER, numBuf); + return &dummy; + } + atom = map->vector[i]; + JS_ASSERT(atom); + return atom; +} + +JS_STATIC_DLL_CALLBACK(intN) +js_map_atom(JSHashEntry *he, intN i, void *arg) +{ + JSAtomListElement *ale = (JSAtomListElement *)he; + JSAtom **vector = arg; + + vector[ALE_INDEX(ale)] = ALE_ATOM(ale); + return HT_ENUMERATE_NEXT; +} + +#ifdef DEBUG +jsrefcount js_atom_map_count; +jsrefcount js_atom_map_hash_table_count; +#endif + +JS_FRIEND_API(JSBool) +js_InitAtomMap(JSContext *cx, JSAtomMap *map, JSAtomList *al) +{ + JSAtom **vector; + JSAtomListElement *ale; + uint32 count; + +#ifdef DEBUG + JS_ATOMIC_INCREMENT(&js_atom_map_count); +#endif + ale = al->list; + if (!ale && !al->table) { + map->vector = NULL; + map->length = 0; + return JS_TRUE; + } + + count = al->count; + if (count >= ATOM_INDEX_LIMIT) { + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, + JSMSG_TOO_MANY_LITERALS); + return JS_FALSE; + } + vector = (JSAtom **) JS_malloc(cx, (size_t) count * sizeof *vector); + if (!vector) + return JS_FALSE; + + if (al->table) { +#ifdef DEBUG + JS_ATOMIC_INCREMENT(&js_atom_map_hash_table_count); +#endif + JS_HashTableEnumerateEntries(al->table, js_map_atom, vector); + } else { + do { + vector[ALE_INDEX(ale)] = ALE_ATOM(ale); + } while ((ale = ALE_NEXT(ale)) != NULL); + } + ATOM_LIST_INIT(al); + + map->vector = vector; + map->length = (jsatomid)count; + return JS_TRUE; +} + +JS_FRIEND_API(void) +js_FreeAtomMap(JSContext *cx, JSAtomMap *map) +{ + if (map->vector) { + JS_free(cx, map->vector); + map->vector = NULL; + } + map->length = 0; +} diff --git a/src/dom/js/jsatom.h b/src/dom/js/jsatom.h new file mode 100644 index 000000000..ec9b52f80 --- /dev/null +++ b/src/dom/js/jsatom.h @@ -0,0 +1,409 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef jsatom_h___ +#define jsatom_h___ +/* + * JS atom table. + */ +#include +#include "jstypes.h" +#include "jshash.h" /* Added by JSIFY */ +#include "jsapi.h" +#include "jsprvtd.h" +#include "jspubtd.h" + +#ifdef JS_THREADSAFE +#include "jslock.h" +#endif + +JS_BEGIN_EXTERN_C + +#define ATOM_PINNED 0x01 /* atom is pinned against GC */ +#define ATOM_INTERNED 0x02 /* pinned variant for JS_Intern* API */ +#define ATOM_MARK 0x04 /* atom is reachable via GC */ +#define ATOM_NOCOPY 0x40 /* don't copy atom string bytes */ +#define ATOM_TMPSTR 0x80 /* internal, to avoid extra string */ + +struct JSAtom { + JSHashEntry entry; /* key is jsval, value keyword info */ + uint32 flags; /* pinned, interned, and mark flags */ + jsatomid number; /* atom serial number and hash code */ +}; + +#define ATOM_KEY(atom) ((jsval)(atom)->entry.key) +#define ATOM_IS_OBJECT(atom) JSVAL_IS_OBJECT(ATOM_KEY(atom)) +#define ATOM_TO_OBJECT(atom) JSVAL_TO_OBJECT(ATOM_KEY(atom)) +#define ATOM_IS_INT(atom) JSVAL_IS_INT(ATOM_KEY(atom)) +#define ATOM_TO_INT(atom) JSVAL_TO_INT(ATOM_KEY(atom)) +#define ATOM_IS_DOUBLE(atom) JSVAL_IS_DOUBLE(ATOM_KEY(atom)) +#define ATOM_TO_DOUBLE(atom) JSVAL_TO_DOUBLE(ATOM_KEY(atom)) +#define ATOM_IS_STRING(atom) JSVAL_IS_STRING(ATOM_KEY(atom)) +#define ATOM_TO_STRING(atom) JSVAL_TO_STRING(ATOM_KEY(atom)) +#define ATOM_IS_BOOLEAN(atom) JSVAL_IS_BOOLEAN(ATOM_KEY(atom)) +#define ATOM_TO_BOOLEAN(atom) JSVAL_TO_BOOLEAN(ATOM_KEY(atom)) + +/* + * Return a printable, lossless char[] representation of a string-type atom. + * The lifetime of the result extends at least until the next GC activation, + * longer if cx's string newborn root is not overwritten. + */ +extern JS_FRIEND_API(const char *) +js_AtomToPrintableString(JSContext *cx, JSAtom *atom); + +#define ATOM_KEYWORD(atom) ((struct keyword *)(atom)->entry.value) +#define ATOM_SET_KEYWORD(atom,kw) ((atom)->entry.value = (kw)) + +struct JSAtomListElement { + JSHashEntry entry; +}; + +#define ALE_ATOM(ale) ((JSAtom *) (ale)->entry.key) +#define ALE_INDEX(ale) ((jsatomid) (ale)->entry.value) +#define ALE_JSOP(ale) ((JSOp) (ale)->entry.value) +#define ALE_NEXT(ale) ((JSAtomListElement *) (ale)->entry.next) + +#define ALE_SET_ATOM(ale,atom) ((ale)->entry.key = (const void *)(atom)) +#define ALE_SET_INDEX(ale,index)((ale)->entry.value = (void *)(index)) +#define ALE_SET_JSOP(ale,op) ((ale)->entry.value = (void *)(op)) +#define ALE_SET_NEXT(ale,link) ((ale)->entry.next = (JSHashEntry *)(link)) + +struct JSAtomList { + JSAtomListElement *list; /* literals indexed for mapping */ + JSHashTable *table; /* hash table if list gets too long */ + jsuint count; /* count of indexed literals */ +}; + +#define ATOM_LIST_INIT(al) ((al)->list = NULL, (al)->table = NULL, \ + (al)->count = 0) + +#define ATOM_LIST_SEARCH(_ale,_al,_atom) \ + JS_BEGIN_MACRO \ + JSHashEntry **_hep; \ + ATOM_LIST_LOOKUP(_ale, _hep, _al, _atom); \ + JS_END_MACRO + +#define ATOM_LIST_LOOKUP(_ale,_hep,_al,_atom) \ + JS_BEGIN_MACRO \ + if ((_al)->table) { \ + _hep = JS_HashTableRawLookup((_al)->table, _atom->number, _atom); \ + _ale = *_hep ? (JSAtomListElement *) *_hep : NULL; \ + } else { \ + JSAtomListElement **_alep = &(_al)->list; \ + _hep = NULL; \ + while ((_ale = *_alep) != NULL) { \ + if (ALE_ATOM(_ale) == (_atom)) { \ + /* Hit, move atom's element to the front of the list. */ \ + *_alep = ALE_NEXT(_ale); \ + ALE_SET_NEXT(_ale, (_al)->list); \ + (_al)->list = _ale; \ + break; \ + } \ + _alep = (JSAtomListElement **)&_ale->entry.next; \ + } \ + } \ + JS_END_MACRO + +struct JSAtomMap { + JSAtom **vector; /* array of ptrs to indexed atoms */ + jsatomid length; /* count of (to-be-)indexed atoms */ +}; + +struct JSAtomState { + JSRuntime *runtime; /* runtime that owns us */ + JSHashTable *table; /* hash table containing all atoms */ + jsatomid number; /* one beyond greatest atom number */ + jsatomid liveAtoms; /* number of live atoms after last GC */ + + /* Type names and value literals. */ + JSAtom *typeAtoms[JSTYPE_LIMIT]; + JSAtom *booleanAtoms[2]; + JSAtom *nullAtom; + + /* Various built-in or commonly-used atoms, pinned on first context. */ + JSAtom *ArgumentsAtom; + JSAtom *ArrayAtom; + JSAtom *BooleanAtom; + JSAtom *CallAtom; + JSAtom *DateAtom; + JSAtom *ErrorAtom; + JSAtom *FunctionAtom; + JSAtom *MathAtom; + JSAtom *NumberAtom; + JSAtom *ObjectAtom; + JSAtom *RegExpAtom; + JSAtom *ScriptAtom; + JSAtom *StringAtom; + JSAtom *anonymousAtom; + JSAtom *argumentsAtom; + JSAtom *arityAtom; + JSAtom *calleeAtom; + JSAtom *callerAtom; + JSAtom *classPrototypeAtom; + JSAtom *constructorAtom; + JSAtom *countAtom; + JSAtom *evalAtom; + JSAtom *getAtom; + JSAtom *getterAtom; + JSAtom *indexAtom; + JSAtom *inputAtom; + JSAtom *lengthAtom; + JSAtom *nameAtom; + JSAtom *noSuchMethodAtom; + JSAtom *parentAtom; + JSAtom *protoAtom; + JSAtom *setAtom; + JSAtom *setterAtom; + JSAtom *toLocaleStringAtom; + JSAtom *toSourceAtom; + JSAtom *toStringAtom; + JSAtom *valueOfAtom; + + /* Less frequently used atoms, pinned lazily by JS_ResolveStandardClass. */ + struct { + JSAtom *EvalErrorAtom; + JSAtom *InfinityAtom; + JSAtom *InternalErrorAtom; + JSAtom *NaNAtom; + JSAtom *RangeErrorAtom; + JSAtom *ReferenceErrorAtom; + JSAtom *SyntaxErrorAtom; + JSAtom *TypeErrorAtom; + JSAtom *URIErrorAtom; + JSAtom *decodeURIAtom; + JSAtom *decodeURIComponentAtom; + JSAtom *defineGetterAtom; + JSAtom *defineSetterAtom; + JSAtom *encodeURIAtom; + JSAtom *encodeURIComponentAtom; + JSAtom *escapeAtom; + JSAtom *hasOwnPropertyAtom; + JSAtom *isFiniteAtom; + JSAtom *isNaNAtom; + JSAtom *isPrototypeOfAtom; + JSAtom *lookupGetterAtom; + JSAtom *lookupSetterAtom; + JSAtom *parseFloatAtom; + JSAtom *parseIntAtom; + JSAtom *propertyIsEnumerableAtom; + JSAtom *unescapeAtom; + JSAtom *unevalAtom; + JSAtom *unwatchAtom; + JSAtom *watchAtom; + } lazy; + +#ifdef JS_THREADSAFE + JSThinLock lock; + volatile uint32 tablegen; +#endif +}; + +/* Well-known predefined strings and their atoms. */ +extern const char *js_type_str[]; +extern const char *js_boolean_str[]; + +extern const char js_Arguments_str[]; +extern const char js_Array_str[]; +extern const char js_Boolean_str[]; +extern const char js_Call_str[]; +extern const char js_Date_str[]; +extern const char js_Function_str[]; +extern const char js_Math_str[]; +extern const char js_Number_str[]; +extern const char js_Object_str[]; +extern const char js_RegExp_str[]; +extern const char js_Script_str[]; +extern const char js_String_str[]; +extern const char js_anonymous_str[]; +extern const char js_arguments_str[]; +extern const char js_arity_str[]; +extern const char js_callee_str[]; +extern const char js_caller_str[]; +extern const char js_class_prototype_str[]; +extern const char js_constructor_str[]; +extern const char js_count_str[]; +extern const char js_eval_str[]; +extern const char js_getter_str[]; +extern const char js_get_str[]; +extern const char js_index_str[]; +extern const char js_input_str[]; +extern const char js_length_str[]; +extern const char js_name_str[]; +extern const char js_noSuchMethod_str[]; +extern const char js_parent_str[]; +extern const char js_proto_str[]; +extern const char js_setter_str[]; +extern const char js_set_str[]; +extern const char js_toSource_str[]; +extern const char js_toString_str[]; +extern const char js_toLocaleString_str[]; +extern const char js_valueOf_str[]; + +/* + * Initialize atom state. Return true on success, false with an out of + * memory error report on failure. + */ +extern JSBool +js_InitAtomState(JSContext *cx, JSAtomState *state); + +/* + * Free and clear atom state (except for any interned string atoms). + */ +extern void +js_FreeAtomState(JSContext *cx, JSAtomState *state); + +/* + * Interned strings are atoms that live until state's runtime is destroyed. + * This function frees all interned string atoms, and then frees and clears + * state's members (just as js_FreeAtomState does), unless there aren't any + * interned strings in state -- in which case state must be "free" already. + * + * NB: js_FreeAtomState is called for each "last" context being destroyed in + * a runtime, where there may yet be another context created in the runtime; + * whereas js_FinishAtomState is called from JS_DestroyRuntime, when we know + * that no more contexts will be created. Thus we minimize garbage during + * context-free episodes on a runtime, while preserving atoms created by the + * JS_Intern*String APIs for the life of the runtime. + */ +extern void +js_FinishAtomState(JSAtomState *state); + +/* + * Atom garbage collection hooks. + */ +typedef void +(*JSGCThingMarker)(void *thing, void *data); + +extern void +js_MarkAtomState(JSAtomState *state, uintN gcflags, JSGCThingMarker mark, + void *data); + +extern void +js_SweepAtomState(JSAtomState *state); + +extern JSBool +js_InitPinnedAtoms(JSContext *cx, JSAtomState *state); + +extern void +js_UnpinPinnedAtoms(JSAtomState *state); + +/* + * Find or create the atom for an object. If we create a new atom, give it the + * type indicated in flags. Return 0 on failure to allocate memory. + */ +extern JSAtom * +js_AtomizeObject(JSContext *cx, JSObject *obj, uintN flags); + +/* + * Find or create the atom for a Boolean value. If we create a new atom, give + * it the type indicated in flags. Return 0 on failure to allocate memory. + */ +extern JSAtom * +js_AtomizeBoolean(JSContext *cx, JSBool b, uintN flags); + +/* + * Find or create the atom for an integer value. If we create a new atom, give + * it the type indicated in flags. Return 0 on failure to allocate memory. + */ +extern JSAtom * +js_AtomizeInt(JSContext *cx, jsint i, uintN flags); + +/* + * Find or create the atom for a double value. If we create a new atom, give + * it the type indicated in flags. Return 0 on failure to allocate memory. + */ +extern JSAtom * +js_AtomizeDouble(JSContext *cx, jsdouble d, uintN flags); + +/* + * Find or create the atom for a string. If we create a new atom, give it the + * type indicated in flags. Return 0 on failure to allocate memory. + */ +extern JSAtom * +js_AtomizeString(JSContext *cx, JSString *str, uintN flags); + +extern JS_FRIEND_API(JSAtom *) +js_Atomize(JSContext *cx, const char *bytes, size_t length, uintN flags); + +extern JS_FRIEND_API(JSAtom *) +js_AtomizeChars(JSContext *cx, const jschar *chars, size_t length, uintN flags); + +/* + * This variant handles all value tag types. + */ +extern JSAtom * +js_AtomizeValue(JSContext *cx, jsval value, uintN flags); + +/* + * Convert v to an atomized string. + */ +extern JSAtom * +js_ValueToStringAtom(JSContext *cx, jsval v); + +/* + * Assign atom an index and insert it on al. + */ +extern JSAtomListElement * +js_IndexAtom(JSContext *cx, JSAtom *atom, JSAtomList *al); + +/* + * Get the atom with index i from map. + */ +extern JS_FRIEND_API(JSAtom *) +js_GetAtom(JSContext *cx, JSAtomMap *map, jsatomid i); + +/* + * For all unmapped atoms recorded in al, add a mapping from the atom's index + * to its address. The GC must not run until all indexed atoms in atomLists + * have been mapped by scripts connected to live objects (Function and Script + * class objects have scripts as/in their private data -- the GC knows about + * these two classes). + */ +extern JS_FRIEND_API(JSBool) +js_InitAtomMap(JSContext *cx, JSAtomMap *map, JSAtomList *al); + +/* + * Free map->vector and clear map. + */ +extern JS_FRIEND_API(void) +js_FreeAtomMap(JSContext *cx, JSAtomMap *map); + +JS_END_EXTERN_C + +#endif /* jsatom_h___ */ diff --git a/src/dom/js/jsautocfg.h b/src/dom/js/jsautocfg.h new file mode 100644 index 000000000..a7f5d6bc8 --- /dev/null +++ b/src/dom/js/jsautocfg.h @@ -0,0 +1,50 @@ +#ifndef js_cpucfg___ +#define js_cpucfg___ + +/* AUTOMATICALLY GENERATED - DO NOT EDIT */ + +#define IS_LITTLE_ENDIAN 1 +#undef IS_BIG_ENDIAN + +#define JS_BYTES_PER_BYTE 1L +#define JS_BYTES_PER_SHORT 2L +#define JS_BYTES_PER_INT 4L +#define JS_BYTES_PER_INT64 8L +#define JS_BYTES_PER_LONG 4L +#define JS_BYTES_PER_FLOAT 4L +#define JS_BYTES_PER_DOUBLE 8L +#define JS_BYTES_PER_WORD 4L +#define JS_BYTES_PER_DWORD 8L + +#define JS_BITS_PER_BYTE 8L +#define JS_BITS_PER_SHORT 16L +#define JS_BITS_PER_INT 32L +#define JS_BITS_PER_INT64 64L +#define JS_BITS_PER_LONG 32L +#define JS_BITS_PER_FLOAT 32L +#define JS_BITS_PER_DOUBLE 64L +#define JS_BITS_PER_WORD 32L + +#define JS_BITS_PER_BYTE_LOG2 3L +#define JS_BITS_PER_SHORT_LOG2 4L +#define JS_BITS_PER_INT_LOG2 5L +#define JS_BITS_PER_INT64_LOG2 6L +#define JS_BITS_PER_LONG_LOG2 5L +#define JS_BITS_PER_FLOAT_LOG2 5L +#define JS_BITS_PER_DOUBLE_LOG2 6L +#define JS_BITS_PER_WORD_LOG2 5L + +#define JS_ALIGN_OF_SHORT 2L +#define JS_ALIGN_OF_INT 4L +#define JS_ALIGN_OF_LONG 4L +#define JS_ALIGN_OF_INT64 4L +#define JS_ALIGN_OF_FLOAT 4L +#define JS_ALIGN_OF_DOUBLE 4L +#define JS_ALIGN_OF_POINTER 4L +#define JS_ALIGN_OF_WORD 4L + +#define JS_BYTES_PER_WORD_LOG2 2L +#define JS_BYTES_PER_DWORD_LOG2 3L +#define JS_WORDS_PER_DWORD_LOG2 1L + +#endif /* js_cpucfg___ */ diff --git a/src/dom/js/jsbit.h b/src/dom/js/jsbit.h new file mode 100644 index 000000000..db41acf9f --- /dev/null +++ b/src/dom/js/jsbit.h @@ -0,0 +1,113 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef jsbit_h___ +#define jsbit_h___ + +#include "jstypes.h" +JS_BEGIN_EXTERN_C + +/* +** A jsbitmap_t is a long integer that can be used for bitmaps +*/ +typedef JSUword jsbitmap_t; /* NSPR name, a la Unix system types */ +typedef jsbitmap_t jsbitmap; /* JS-style scalar typedef name */ + +#define JS_TEST_BIT(_map,_bit) \ + ((_map)[(_bit)>>JS_BITS_PER_WORD_LOG2] & (1L << ((_bit) & (JS_BITS_PER_WORD-1)))) +#define JS_SET_BIT(_map,_bit) \ + ((_map)[(_bit)>>JS_BITS_PER_WORD_LOG2] |= (1L << ((_bit) & (JS_BITS_PER_WORD-1)))) +#define JS_CLEAR_BIT(_map,_bit) \ + ((_map)[(_bit)>>JS_BITS_PER_WORD_LOG2] &= ~(1L << ((_bit) & (JS_BITS_PER_WORD-1)))) + +/* +** Compute the log of the least power of 2 greater than or equal to n +*/ +extern JS_PUBLIC_API(JSIntn) JS_CeilingLog2(JSUint32 i); + +/* +** Compute the log of the greatest power of 2 less than or equal to n +*/ +extern JS_PUBLIC_API(JSIntn) JS_FloorLog2(JSUint32 i); + +/* +** Macro version of JS_CeilingLog2: Compute the log of the least power of +** 2 greater than or equal to _n. The result is returned in _log2. +*/ +#define JS_CEILING_LOG2(_log2,_n) \ + JS_BEGIN_MACRO \ + JSUint32 j_ = (JSUint32)(_n); \ + (_log2) = 0; \ + if ((j_) & ((j_)-1)) \ + (_log2) += 1; \ + if ((j_) >> 16) \ + (_log2) += 16, (j_) >>= 16; \ + if ((j_) >> 8) \ + (_log2) += 8, (j_) >>= 8; \ + if ((j_) >> 4) \ + (_log2) += 4, (j_) >>= 4; \ + if ((j_) >> 2) \ + (_log2) += 2, (j_) >>= 2; \ + if ((j_) >> 1) \ + (_log2) += 1; \ + JS_END_MACRO + +/* +** Macro version of JS_FloorLog2: Compute the log of the greatest power of +** 2 less than or equal to _n. The result is returned in _log2. +** +** This is equivalent to finding the highest set bit in the word. +*/ +#define JS_FLOOR_LOG2(_log2,_n) \ + JS_BEGIN_MACRO \ + JSUint32 j_ = (JSUint32)(_n); \ + (_log2) = 0; \ + if ((j_) >> 16) \ + (_log2) += 16, (j_) >>= 16; \ + if ((j_) >> 8) \ + (_log2) += 8, (j_) >>= 8; \ + if ((j_) >> 4) \ + (_log2) += 4, (j_) >>= 4; \ + if ((j_) >> 2) \ + (_log2) += 2, (j_) >>= 2; \ + if ((j_) >> 1) \ + (_log2) += 1; \ + JS_END_MACRO + +JS_END_EXTERN_C +#endif /* jsbit_h___ */ diff --git a/src/dom/js/jsbool.c b/src/dom/js/jsbool.c new file mode 100644 index 000000000..05f596556 --- /dev/null +++ b/src/dom/js/jsbool.c @@ -0,0 +1,244 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* + * JS boolean implementation. + */ +#include "jsstddef.h" +#include "jstypes.h" +#include "jsutil.h" /* Added by JSIFY */ +#include "jsapi.h" +#include "jsatom.h" +#include "jsbool.h" +#include "jscntxt.h" +#include "jsconfig.h" +#include "jsinterp.h" +#include "jslock.h" +#include "jsnum.h" +#include "jsobj.h" +#include "jsstr.h" + +static JSClass boolean_class = { + "Boolean", + JSCLASS_HAS_PRIVATE, + JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, + JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub, + JSCLASS_NO_OPTIONAL_MEMBERS +}; + +#if JS_HAS_TOSOURCE +#include "jsprf.h" + +static JSBool +bool_toSource(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval) +{ + jsval v; + char buf[32]; + JSString *str; + + if (!JS_InstanceOf(cx, obj, &boolean_class, argv)) + return JS_FALSE; + v = OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE); + if (!JSVAL_IS_BOOLEAN(v)) + return js_obj_toSource(cx, obj, argc, argv, rval); + JS_snprintf(buf, sizeof buf, "(new %s(%s))", + boolean_class.name, + js_boolean_str[JSVAL_TO_BOOLEAN(v) ? 1 : 0]); + str = JS_NewStringCopyZ(cx, buf); + if (!str) + return JS_FALSE; + *rval = STRING_TO_JSVAL(str); + return JS_TRUE; +} +#endif + +static JSBool +bool_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval) +{ + jsval v; + JSAtom *atom; + JSString *str; + + if (!JS_InstanceOf(cx, obj, &boolean_class, argv)) + return JS_FALSE; + v = OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE); + if (!JSVAL_IS_BOOLEAN(v)) + return js_obj_toString(cx, obj, argc, argv, rval); + atom = cx->runtime->atomState.booleanAtoms[JSVAL_TO_BOOLEAN(v) ? 1 : 0]; + str = ATOM_TO_STRING(atom); + if (!str) + return JS_FALSE; + *rval = STRING_TO_JSVAL(str); + return JS_TRUE; +} + +static JSBool +bool_valueOf(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + if (!JS_InstanceOf(cx, obj, &boolean_class, argv)) + return JS_FALSE; + *rval = OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE); + return JS_TRUE; +} + +static JSFunctionSpec boolean_methods[] = { +#if JS_HAS_TOSOURCE + {js_toSource_str, bool_toSource, 0,0,0}, +#endif + {js_toString_str, bool_toString, 0,0,0}, + {js_valueOf_str, bool_valueOf, 0,0,0}, + {0,0,0,0,0} +}; + +#ifdef XP_MAC +#undef Boolean +#define Boolean js_Boolean +#endif + +static JSBool +Boolean(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + JSBool b; + jsval bval; + + if (argc != 0) { + if (!js_ValueToBoolean(cx, argv[0], &b)) + return JS_FALSE; + bval = BOOLEAN_TO_JSVAL(b); + } else { + bval = JSVAL_FALSE; + } + if (!(cx->fp->flags & JSFRAME_CONSTRUCTING)) { + *rval = bval; + return JS_TRUE; + } + OBJ_SET_SLOT(cx, obj, JSSLOT_PRIVATE, bval); + return JS_TRUE; +} + +JSObject * +js_InitBooleanClass(JSContext *cx, JSObject *obj) +{ + JSObject *proto; + + proto = JS_InitClass(cx, obj, NULL, &boolean_class, Boolean, 1, + NULL, boolean_methods, NULL, NULL); + if (!proto) + return NULL; + OBJ_SET_SLOT(cx, proto, JSSLOT_PRIVATE, JSVAL_FALSE); + return proto; +} + +JSObject * +js_BooleanToObject(JSContext *cx, JSBool b) +{ + JSObject *obj; + + obj = js_NewObject(cx, &boolean_class, NULL, NULL); + if (!obj) + return NULL; + OBJ_SET_SLOT(cx, obj, JSSLOT_PRIVATE, BOOLEAN_TO_JSVAL(b)); + return obj; +} + +JSString * +js_BooleanToString(JSContext *cx, JSBool b) +{ + return ATOM_TO_STRING(cx->runtime->atomState.booleanAtoms[b ? 1 : 0]); +} + +JSBool +js_ValueToBoolean(JSContext *cx, jsval v, JSBool *bp) +{ + JSBool b; + jsdouble d; + +#if defined _MSC_VER && _MSC_VER <= 800 + /* MSVC1.5 coredumps */ + if (!bp) + return JS_TRUE; + /* This should be an if-else chain, but MSVC1.5 crashes if it is. */ +#define ELSE +#else +#define ELSE else +#endif + + if (JSVAL_IS_NULL(v) || JSVAL_IS_VOID(v)) { + /* Must return early to avoid falling thru to JSVAL_IS_OBJECT case. */ + *bp = JS_FALSE; + return JS_TRUE; + } + if (JSVAL_IS_OBJECT(v)) { + if (!JSVERSION_IS_ECMA(cx->version)) { + if (!OBJ_DEFAULT_VALUE(cx, JSVAL_TO_OBJECT(v), JSTYPE_BOOLEAN, &v)) + return JS_FALSE; + if (!JSVAL_IS_BOOLEAN(v)) + v = JSVAL_TRUE; /* non-null object is true */ + b = JSVAL_TO_BOOLEAN(v); + } else { + b = JS_TRUE; + } + } ELSE + if (JSVAL_IS_STRING(v)) { + b = JSSTRING_LENGTH(JSVAL_TO_STRING(v)) ? JS_TRUE : JS_FALSE; + } ELSE + if (JSVAL_IS_INT(v)) { + b = JSVAL_TO_INT(v) ? JS_TRUE : JS_FALSE; + } ELSE + if (JSVAL_IS_DOUBLE(v)) { + d = *JSVAL_TO_DOUBLE(v); + b = (!JSDOUBLE_IS_NaN(d) && d != 0) ? JS_TRUE : JS_FALSE; + } ELSE +#if defined _MSC_VER && _MSC_VER <= 800 + if (JSVAL_IS_BOOLEAN(v)) { + b = JSVAL_TO_BOOLEAN(v); + } +#else + { + JS_ASSERT(JSVAL_IS_BOOLEAN(v)); + b = JSVAL_TO_BOOLEAN(v); + } +#endif + +#undef ELSE + *bp = b; + return JS_TRUE; +} diff --git a/src/dom/js/jsbool.h b/src/dom/js/jsbool.h new file mode 100644 index 000000000..c07910f59 --- /dev/null +++ b/src/dom/js/jsbool.h @@ -0,0 +1,62 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef jsbool_h___ +#define jsbool_h___ +/* + * JS boolean interface. + */ + +JS_BEGIN_EXTERN_C + +extern JSObject * +js_InitBooleanClass(JSContext *cx, JSObject *obj); + +extern JSObject * +js_BooleanToObject(JSContext *cx, JSBool b); + +extern JSString * +js_BooleanToString(JSContext *cx, JSBool b); + +extern JSBool +js_ValueToBoolean(JSContext *cx, jsval v, JSBool *bp); + +JS_END_EXTERN_C + +#endif /* jsbool_h___ */ diff --git a/src/dom/js/jsclist.h b/src/dom/js/jsclist.h new file mode 100644 index 000000000..2eafe8e40 --- /dev/null +++ b/src/dom/js/jsclist.h @@ -0,0 +1,139 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef jsclist_h___ +#define jsclist_h___ + +#include "jstypes.h" + +/* +** Circular linked list +*/ +typedef struct JSCListStr { + struct JSCListStr *next; + struct JSCListStr *prev; +} JSCList; + +/* +** Insert element "_e" into the list, before "_l". +*/ +#define JS_INSERT_BEFORE(_e,_l) \ + JS_BEGIN_MACRO \ + (_e)->next = (_l); \ + (_e)->prev = (_l)->prev; \ + (_l)->prev->next = (_e); \ + (_l)->prev = (_e); \ + JS_END_MACRO + +/* +** Insert element "_e" into the list, after "_l". +*/ +#define JS_INSERT_AFTER(_e,_l) \ + JS_BEGIN_MACRO \ + (_e)->next = (_l)->next; \ + (_e)->prev = (_l); \ + (_l)->next->prev = (_e); \ + (_l)->next = (_e); \ + JS_END_MACRO + +/* +** Return the element following element "_e" +*/ +#define JS_NEXT_LINK(_e) \ + ((_e)->next) +/* +** Return the element preceding element "_e" +*/ +#define JS_PREV_LINK(_e) \ + ((_e)->prev) + +/* +** Append an element "_e" to the end of the list "_l" +*/ +#define JS_APPEND_LINK(_e,_l) JS_INSERT_BEFORE(_e,_l) + +/* +** Insert an element "_e" at the head of the list "_l" +*/ +#define JS_INSERT_LINK(_e,_l) JS_INSERT_AFTER(_e,_l) + +/* Return the head/tail of the list */ +#define JS_LIST_HEAD(_l) (_l)->next +#define JS_LIST_TAIL(_l) (_l)->prev + +/* +** Remove the element "_e" from it's circular list. +*/ +#define JS_REMOVE_LINK(_e) \ + JS_BEGIN_MACRO \ + (_e)->prev->next = (_e)->next; \ + (_e)->next->prev = (_e)->prev; \ + JS_END_MACRO + +/* +** Remove the element "_e" from it's circular list. Also initializes the +** linkage. +*/ +#define JS_REMOVE_AND_INIT_LINK(_e) \ + JS_BEGIN_MACRO \ + (_e)->prev->next = (_e)->next; \ + (_e)->next->prev = (_e)->prev; \ + (_e)->next = (_e); \ + (_e)->prev = (_e); \ + JS_END_MACRO + +/* +** Return non-zero if the given circular list "_l" is empty, zero if the +** circular list is not empty +*/ +#define JS_CLIST_IS_EMPTY(_l) \ + ((_l)->next == (_l)) + +/* +** Initialize a circular list +*/ +#define JS_INIT_CLIST(_l) \ + JS_BEGIN_MACRO \ + (_l)->next = (_l); \ + (_l)->prev = (_l); \ + JS_END_MACRO + +#define JS_INIT_STATIC_CLIST(_l) \ + {(_l), (_l)} + +#endif /* jsclist_h___ */ diff --git a/src/dom/js/jscntxt.c b/src/dom/js/jscntxt.c new file mode 100644 index 000000000..85496b89b --- /dev/null +++ b/src/dom/js/jscntxt.c @@ -0,0 +1,702 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* + * JS execution context. + */ +#include "jsstddef.h" +#include +#include +#include +#include "jstypes.h" +#include "jsarena.h" /* Added by JSIFY */ +#include "jsutil.h" /* Added by JSIFY */ +#include "jsclist.h" +#include "jsprf.h" +#include "jsatom.h" +#include "jscntxt.h" +#include "jsconfig.h" +#include "jsdbgapi.h" +#include "jsexn.h" +#include "jsgc.h" +#include "jslock.h" +#include "jsnum.h" +#include "jsobj.h" +#include "jsopcode.h" +#include "jsscan.h" +#include "jsscript.h" +#include "jsstr.h" + +JSContext * +js_NewContext(JSRuntime *rt, size_t stackChunkSize) +{ + JSContext *cx; + JSBool ok, first; + + cx = (JSContext *) malloc(sizeof *cx); + if (!cx) + return NULL; + memset(cx, 0, sizeof *cx); + + cx->runtime = rt; +#if JS_STACK_GROWTH_DIRECTION > 0 + cx->stackLimit = (jsuword)-1; +#endif +#ifdef JS_THREADSAFE + js_InitContextForLocking(cx); +#endif + + JS_LOCK_GC(rt); + for (;;) { + first = (rt->contextList.next == &rt->contextList); + if (rt->state == JSRTS_UP) { + JS_ASSERT(!first); + break; + } + if (rt->state == JSRTS_DOWN) { + JS_ASSERT(first); + rt->state = JSRTS_LAUNCHING; + break; + } + JS_WAIT_CONDVAR(rt->stateChange, JS_NO_TIMEOUT); + } + JS_APPEND_LINK(&cx->links, &rt->contextList); + JS_UNLOCK_GC(rt); + + /* + * First we do the infallible, every-time per-context initializations. + * Should a later, fallible initialization (js_InitRegExpStatics, e.g., + * or the stuff under 'if (first)' below) fail, at least the version + * and arena-pools will be valid and safe to use (say, from the last GC + * done by js_DestroyContext). + */ + cx->version = JSVERSION_DEFAULT; + cx->jsop_eq = JSOP_EQ; + cx->jsop_ne = JSOP_NE; + JS_InitArenaPool(&cx->stackPool, "stack", stackChunkSize, sizeof(jsval)); + JS_InitArenaPool(&cx->tempPool, "temp", 1024, sizeof(jsdouble)); + +#if JS_HAS_REGEXPS + if (!js_InitRegExpStatics(cx, &cx->regExpStatics)) { + js_DestroyContext(cx, JS_NO_GC); + return NULL; + } +#endif +#if JS_HAS_EXCEPTIONS + cx->throwing = JS_FALSE; +#endif + + /* + * If cx is the first context on this runtime, initialize well-known atoms, + * keywords, numbers, and strings. If one of these steps should fail, the + * runtime will be left in a partially initialized state, with zeroes and + * nulls stored in the default-initialized remainder of the struct. We'll + * clean the runtime up under js_DestroyContext, because cx will be "last" + * as well as "first". + */ + if (first) { + ok = (rt->atomState.liveAtoms == 0) + ? js_InitAtomState(cx, &rt->atomState) + : js_InitPinnedAtoms(cx, &rt->atomState); + if (ok) + ok = js_InitScanner(cx); + if (ok) + ok = js_InitRuntimeNumberState(cx); + if (ok) + ok = js_InitRuntimeStringState(cx); + if (!ok) { + js_DestroyContext(cx, JS_NO_GC); + return NULL; + } + + JS_LOCK_GC(rt); + rt->state = JSRTS_UP; + JS_NOTIFY_ALL_CONDVAR(rt->stateChange); + JS_UNLOCK_GC(rt); + } + + return cx; +} + +void +js_DestroyContext(JSContext *cx, JSGCMode gcmode) +{ + JSRuntime *rt; + JSBool last; + JSArgumentFormatMap *map; + + rt = cx->runtime; + + /* Remove cx from context list first. */ + JS_LOCK_GC(rt); + JS_ASSERT(rt->state == JSRTS_UP || rt->state == JSRTS_LAUNCHING); + JS_REMOVE_LINK(&cx->links); + last = (rt->contextList.next == &rt->contextList); + if (last) + rt->state = JSRTS_LANDING; + JS_UNLOCK_GC(rt); + + if (last) { +#ifdef JS_THREADSAFE + /* + * If cx is not in a request already, begin one now so that we wait + * for any racing GC started on a not-last context to finish, before + * we plow ahead and unpin atoms. Note that even though we begin a + * request here if necessary, we end all requests on cx below before + * forcing a final GC. This lets any not-last context destruction + * racing in another thread try to force or maybe run the GC, but by + * that point, rt->state will not be JSRTS_UP, and that GC attempt + * will return early. + */ + if (cx->requestDepth == 0) + JS_BeginRequest(cx); +#endif + + /* Unpin all pinned atoms before final GC. */ + js_UnpinPinnedAtoms(&rt->atomState); + + /* Unlock and clear GC things held by runtime pointers. */ + js_FinishRuntimeNumberState(cx); + js_FinishRuntimeStringState(cx); + + /* Clear debugging state to remove GC roots. */ + JS_ClearAllTraps(cx); + JS_ClearAllWatchPoints(cx); + } + +#if JS_HAS_REGEXPS + /* + * Remove more GC roots in regExpStatics, then collect garbage. + * XXX anti-modularity alert: we rely on the call to js_RemoveRoot within + * XXX this function call to wait for any racing GC to complete, in the + * XXX case where JS_DestroyContext is called outside of a request on cx + */ + js_FreeRegExpStatics(cx, &cx->regExpStatics); +#endif + +#ifdef JS_THREADSAFE + /* + * Destroying a context implicitly calls JS_EndRequest(). Also, we must + * end our request here in case we are "last" -- in that event, another + * js_DestroyContext that was not last might be waiting in the GC for our + * request to end. We'll let it run below, just before we do the truly + * final GC and then free atom state. + * + * At this point, cx must be inaccessible to other threads. It's off the + * rt->contextList, and it should not be reachable via any object private + * data structure. + */ + while (cx->requestDepth != 0) + JS_EndRequest(cx); +#endif + + if (last) { + /* Always force, so we wait for any racing GC to finish. */ + js_ForceGC(cx, GC_LAST_CONTEXT); + + /* Iterate until no finalizer removes a GC root or lock. */ + while (rt->gcPoke) + js_GC(cx, GC_LAST_CONTEXT); + + /* Try to free atom state, now that no unrooted scripts survive. */ + if (rt->atomState.liveAtoms == 0) + js_FreeAtomState(cx, &rt->atomState); + + /* Take the runtime down, now that it has no contexts or atoms. */ + JS_LOCK_GC(rt); + rt->state = JSRTS_DOWN; + JS_NOTIFY_ALL_CONDVAR(rt->stateChange); + JS_UNLOCK_GC(rt); + } else { + if (gcmode == JS_FORCE_GC) + js_ForceGC(cx, 0); + else if (gcmode == JS_MAYBE_GC) + JS_MaybeGC(cx); + } + + /* Free the stuff hanging off of cx. */ + JS_FinishArenaPool(&cx->stackPool); + JS_FinishArenaPool(&cx->tempPool); + if (cx->lastMessage) + free(cx->lastMessage); + + /* Remove any argument formatters. */ + map = cx->argumentFormatMap; + while (map) { + JSArgumentFormatMap *temp = map; + map = map->next; + JS_free(cx, temp); + } + + /* Destroy the resolve recursion damper. */ + if (cx->resolvingTable) { + JS_DHashTableDestroy(cx->resolvingTable); + cx->resolvingTable = NULL; + } + + /* Finally, free cx itself. */ + free(cx); +} + +JSBool +js_ValidContextPointer(JSRuntime *rt, JSContext *cx) +{ + JSCList *cl; + + for (cl = rt->contextList.next; cl != &rt->contextList; cl = cl->next) { + if (cl == &cx->links) + return JS_TRUE; + } + JS_RUNTIME_METER(rt, deadContexts); + return JS_FALSE; +} + +JSContext * +js_ContextIterator(JSRuntime *rt, JSBool unlocked, JSContext **iterp) +{ + JSContext *cx = *iterp; + + if (unlocked) + JS_LOCK_GC(rt); + if (!cx) + cx = (JSContext *)&rt->contextList; + cx = (JSContext *)cx->links.next; + if (&cx->links == &rt->contextList) + cx = NULL; + *iterp = cx; + if (unlocked) + JS_UNLOCK_GC(rt); + return cx; +} + +static void +ReportError(JSContext *cx, const char *message, JSErrorReport *reportp) +{ + /* + * Check the error report, and set a JavaScript-catchable exception + * if the error is defined to have an associated exception. If an + * exception is thrown, then the JSREPORT_EXCEPTION flag will be set + * on the error report, and exception-aware hosts should ignore it. + */ + if (reportp && reportp->errorNumber == JSMSG_UNCAUGHT_EXCEPTION) + reportp->flags |= JSREPORT_EXCEPTION; + +#if JS_HAS_ERROR_EXCEPTIONS + /* + * Call the error reporter only if an exception wasn't raised. + * + * If an exception was raised, then we call the debugErrorHook + * (if present) to give it a chance to see the error before it + * propagates out of scope. This is needed for compatability + * with the old scheme. + */ + if (!js_ErrorToException(cx, message, reportp)) { + js_ReportErrorAgain(cx, message, reportp); + } else if (cx->runtime->debugErrorHook && cx->errorReporter) { + JSDebugErrorHook hook = cx->runtime->debugErrorHook; + /* test local in case debugErrorHook changed on another thread */ + if (hook) + hook(cx, message, reportp, cx->runtime->debugErrorHookData); + } +#else + js_ReportErrorAgain(cx, message, reportp); +#endif +} + +/* + * We don't post an exception in this case, since doing so runs into + * complications of pre-allocating an exception object which required + * running the Exception class initializer early etc. + * Instead we just invoke the errorReporter with an "Out Of Memory" + * type message, and then hope the process ends swiftly. + */ +void +js_ReportOutOfMemory(JSContext *cx, JSErrorCallback callback) +{ + JSStackFrame *fp; + JSErrorReport report; + JSErrorReporter onError = cx->errorReporter; + + /* Get the message for this error, but we won't expand any arguments. */ + const JSErrorFormatString *efs = callback(NULL, NULL, JSMSG_OUT_OF_MEMORY); + const char *msg = efs ? efs->format : "Out of memory"; + + /* Fill out the report, but don't do anything that requires allocation. */ + memset(&report, 0, sizeof (struct JSErrorReport)); + report.flags = JSREPORT_ERROR; + report.errorNumber = JSMSG_OUT_OF_MEMORY; + + /* + * Walk stack until we find a frame that is associated with some script + * rather than a native frame. + */ + for (fp = cx->fp; fp; fp = fp->down) { + if (fp->script && fp->pc) { + report.filename = fp->script->filename; + report.lineno = js_PCToLineNumber(cx, fp->script, fp->pc); + break; + } + } + + /* + * If debugErrorHook is present then we give it a chance to veto + * sending the error on to the regular ErrorReporter. + */ + if (onError) { + JSDebugErrorHook hook = cx->runtime->debugErrorHook; + if (hook && + !hook(cx, msg, &report, cx->runtime->debugErrorHookData)) { + onError = NULL; + } + } + + if (onError) + onError(cx, msg, &report); +} + +JSBool +js_ReportErrorVA(JSContext *cx, uintN flags, const char *format, va_list ap) +{ + char *last; + JSStackFrame *fp; + JSErrorReport report; + JSBool warning; + + if ((flags & JSREPORT_STRICT) && !JS_HAS_STRICT_OPTION(cx)) + return JS_TRUE; + + last = JS_vsmprintf(format, ap); + if (!last) + return JS_FALSE; + + memset(&report, 0, sizeof (struct JSErrorReport)); + report.flags = flags; + + /* Find the top-most active script frame, for best line number blame. */ + for (fp = cx->fp; fp; fp = fp->down) { + if (fp->script && fp->pc) { + report.filename = fp->script->filename; + report.lineno = js_PCToLineNumber(cx, fp->script, fp->pc); + break; + } + } + + warning = JSREPORT_IS_WARNING(report.flags); + if (warning && JS_HAS_WERROR_OPTION(cx)) { + report.flags &= ~JSREPORT_WARNING; + warning = JS_FALSE; + } + + ReportError(cx, last, &report); + free(last); + return warning; +} + +/* + * The arguments from ap need to be packaged up into an array and stored + * into the report struct. + * + * The format string addressed by the error number may contain operands + * identified by the format {N}, where N is a decimal digit. Each of these + * is to be replaced by the Nth argument from the va_list. The complete + * message is placed into reportp->ucmessage converted to a JSString. + * + * Returns true if the expansion succeeds (can fail if out of memory). + */ +JSBool +js_ExpandErrorArguments(JSContext *cx, JSErrorCallback callback, + void *userRef, const uintN errorNumber, + char **messagep, JSErrorReport *reportp, + JSBool *warningp, JSBool charArgs, va_list ap) +{ + const JSErrorFormatString *efs; + int i; + int argCount; + + *warningp = JSREPORT_IS_WARNING(reportp->flags); + if (*warningp && JS_HAS_WERROR_OPTION(cx)) { + reportp->flags &= ~JSREPORT_WARNING; + *warningp = JS_FALSE; + } + + *messagep = NULL; + if (callback) { + efs = callback(userRef, NULL, errorNumber); + if (efs) { + size_t totalArgsLength = 0; + size_t argLengths[10]; /* only {0} thru {9} supported */ + argCount = efs->argCount; + JS_ASSERT(argCount <= 10); + if (argCount > 0) { + /* + * Gather the arguments into an array, and accumulate + * their sizes. We allocate 1 more than necessary and + * null it out to act as the caboose when we free the + * pointers later. + */ + reportp->messageArgs = (const jschar **) + JS_malloc(cx, sizeof(jschar *) * (argCount + 1)); + if (!reportp->messageArgs) + return JS_FALSE; + reportp->messageArgs[argCount] = NULL; + for (i = 0; i < argCount; i++) { + if (charArgs) { + char *charArg = va_arg(ap, char *); + reportp->messageArgs[i] + = js_InflateString(cx, charArg, strlen(charArg)); + if (!reportp->messageArgs[i]) + goto error; + } + else + reportp->messageArgs[i] = va_arg(ap, jschar *); + argLengths[i] = js_strlen(reportp->messageArgs[i]); + totalArgsLength += argLengths[i]; + } + /* NULL-terminate for easy copying. */ + reportp->messageArgs[i] = NULL; + } + /* + * Parse the error format, substituting the argument X + * for {X} in the format. + */ + if (argCount > 0) { + if (efs->format) { + const char *fmt; + const jschar *arg; + jschar *out; + int expandedArgs = 0; + size_t expandedLength + = strlen(efs->format) + - (3 * argCount) /* exclude the {n} */ + + totalArgsLength; + /* + * Note - the above calculation assumes that each argument + * is used once and only once in the expansion !!! + */ + reportp->ucmessage = out = (jschar *) + JS_malloc(cx, (expandedLength + 1) * sizeof(jschar)); + if (!out) + goto error; + fmt = efs->format; + while (*fmt) { + if (*fmt == '{') { + if (isdigit(fmt[1])) { + int d = JS7_UNDEC(fmt[1]); + JS_ASSERT(expandedArgs < argCount); + arg = reportp->messageArgs[d]; + js_strncpy(out, arg, argLengths[d]); + out += argLengths[d]; + fmt += 3; + expandedArgs++; + continue; + } + } + /* + * is this kosher? + */ + *out++ = (unsigned char)(*fmt++); + } + JS_ASSERT(expandedArgs == argCount); + *out = 0; + *messagep = + js_DeflateString(cx, reportp->ucmessage, + (size_t)(out - reportp->ucmessage)); + if (!*messagep) + goto error; + } + } else { + /* + * Zero arguments: the format string (if it exists) is the + * entire message. + */ + if (efs->format) { + *messagep = JS_strdup(cx, efs->format); + if (!*messagep) + goto error; + reportp->ucmessage + = js_InflateString(cx, *messagep, strlen(*messagep)); + if (!reportp->ucmessage) + goto error; + } + } + } + } + if (*messagep == NULL) { + /* where's the right place for this ??? */ + const char *defaultErrorMessage + = "No error message available for error number %d"; + size_t nbytes = strlen(defaultErrorMessage) + 16; + *messagep = (char *)JS_malloc(cx, nbytes); + if (!*messagep) + goto error; + JS_snprintf(*messagep, nbytes, defaultErrorMessage, errorNumber); + } + return JS_TRUE; + +error: + if (reportp->messageArgs) { + i = 0; + while (reportp->messageArgs[i]) + JS_free(cx, (void *)reportp->messageArgs[i++]); + JS_free(cx, (void *)reportp->messageArgs); + reportp->messageArgs = NULL; + } + if (reportp->ucmessage) { + JS_free(cx, (void *)reportp->ucmessage); + reportp->ucmessage = NULL; + } + if (*messagep) { + JS_free(cx, (void *)*messagep); + *messagep = NULL; + } + return JS_FALSE; +} + +JSBool +js_ReportErrorNumberVA(JSContext *cx, uintN flags, JSErrorCallback callback, + void *userRef, const uintN errorNumber, + JSBool charArgs, va_list ap) +{ + JSStackFrame *fp; + JSErrorReport report; + char *message; + JSBool warning; + + if ((flags & JSREPORT_STRICT) && !JS_HAS_STRICT_OPTION(cx)) + return JS_TRUE; + + memset(&report, 0, sizeof (struct JSErrorReport)); + report.flags = flags; + report.errorNumber = errorNumber; + + /* + * If we can't find out where the error was based on the current frame, + * see if the next frame has a script/pc combo we can use. + */ + for (fp = cx->fp; fp; fp = fp->down) { + if (fp->script && fp->pc) { + report.filename = fp->script->filename; + report.lineno = js_PCToLineNumber(cx, fp->script, fp->pc); + break; + } + } + + if (!js_ExpandErrorArguments(cx, callback, userRef, errorNumber, + &message, &report, &warning, charArgs, ap)) { + return JS_FALSE; + } + + ReportError(cx, message, &report); + + if (message) + JS_free(cx, message); + if (report.messageArgs) { + int i = 0; + while (report.messageArgs[i]) + JS_free(cx, (void *)report.messageArgs[i++]); + JS_free(cx, (void *)report.messageArgs); + } + if (report.ucmessage) + JS_free(cx, (void *)report.ucmessage); + + return warning; +} + +JS_FRIEND_API(void) +js_ReportErrorAgain(JSContext *cx, const char *message, JSErrorReport *reportp) +{ + JSErrorReporter onError; + + if (!message) + return; + + if (cx->lastMessage) + free(cx->lastMessage); + cx->lastMessage = JS_strdup(cx, message); + if (!cx->lastMessage) + return; + onError = cx->errorReporter; + + /* + * If debugErrorHook is present then we give it a chance to veto + * sending the error on to the regular ErrorReporter. + */ + if (onError) { + JSDebugErrorHook hook = cx->runtime->debugErrorHook; + if (hook && + !hook(cx, cx->lastMessage, reportp, + cx->runtime->debugErrorHookData)) { + onError = NULL; + } + } + if (onError) + onError(cx, cx->lastMessage, reportp); +} + +void +js_ReportIsNotDefined(JSContext *cx, const char *name) +{ + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_NOT_DEFINED, name); +} + +#if defined DEBUG && defined XP_UNIX +/* For gdb usage. */ +void js_traceon(JSContext *cx) { cx->tracefp = stderr; } +void js_traceoff(JSContext *cx) { cx->tracefp = NULL; } +#endif + +JSErrorFormatString js_ErrorFormatString[JSErr_Limit] = { +#if JS_HAS_DFLT_MSG_STRINGS +#define MSG_DEF(name, number, count, exception, format) \ + { format, count } , +#else +#define MSG_DEF(name, number, count, exception, format) \ + { NULL, count } , +#endif +#include "js.msg" +#undef MSG_DEF +}; + +const JSErrorFormatString * +js_GetErrorMessage(void *userRef, const char *locale, const uintN errorNumber) +{ + if ((errorNumber > 0) && (errorNumber < JSErr_Limit)) + return &js_ErrorFormatString[errorNumber]; + return NULL; +} diff --git a/src/dom/js/jscntxt.h b/src/dom/js/jscntxt.h new file mode 100644 index 000000000..f9aab41a8 --- /dev/null +++ b/src/dom/js/jscntxt.h @@ -0,0 +1,496 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef jscntxt_h___ +#define jscntxt_h___ +/* + * JS execution context. + */ +#include "jsarena.h" /* Added by JSIFY */ +#include "jsclist.h" +#include "jslong.h" +#include "jsatom.h" +#include "jsconfig.h" +#include "jsdhash.h" +#include "jsgc.h" +#include "jsinterp.h" +#include "jsobj.h" +#include "jsprvtd.h" +#include "jspubtd.h" +#include "jsregexp.h" + +JS_BEGIN_EXTERN_C + +typedef enum JSGCMode { JS_NO_GC, JS_MAYBE_GC, JS_FORCE_GC } JSGCMode; + +typedef enum JSRuntimeState { + JSRTS_DOWN, + JSRTS_LAUNCHING, + JSRTS_UP, + JSRTS_LANDING +} JSRuntimeState; + +typedef struct JSPropertyTreeEntry { + JSDHashEntryHdr hdr; + JSScopeProperty *child; +} JSPropertyTreeEntry; + +struct JSRuntime { + /* Runtime state, synchronized by the stateChange/gcLock condvar/lock. */ + JSRuntimeState state; + + /* Garbage collector state, used by jsgc.c. */ + JSArenaPool gcArenaPool; + JSDHashTable gcRootsHash; + JSDHashTable *gcLocksHash; + JSGCThing *gcFreeList; + jsrefcount gcKeepAtoms; + uint32 gcBytes; + uint32 gcLastBytes; + uint32 gcMaxBytes; + uint32 gcLevel; + uint32 gcNumber; + JSPackedBool gcPoke; + JSPackedBool gcRunning; + JSGCCallback gcCallback; + uint32 gcMallocBytes; +#ifdef JS_GCMETER + JSGCStats gcStats; +#endif + + /* Literal table maintained by jsatom.c functions. */ + JSAtomState atomState; + + /* Random number generator state, used by jsmath.c. */ + JSBool rngInitialized; + int64 rngMultiplier; + int64 rngAddend; + int64 rngMask; + int64 rngSeed; + jsdouble rngDscale; + + /* Well-known numbers held for use by this runtime's contexts. */ + jsdouble *jsNaN; + jsdouble *jsNegativeInfinity; + jsdouble *jsPositiveInfinity; + + /* Empty string held for use by this runtime's contexts. */ + JSString *emptyString; + + /* List of active contexts sharing this runtime; protected by gcLock. */ + JSCList contextList; + + /* These are used for debugging -- see jsprvtd.h and jsdbgapi.h. */ + JSTrapHandler interruptHandler; + void *interruptHandlerData; + JSNewScriptHook newScriptHook; + void *newScriptHookData; + JSDestroyScriptHook destroyScriptHook; + void *destroyScriptHookData; + JSTrapHandler debuggerHandler; + void *debuggerHandlerData; + JSSourceHandler sourceHandler; + void *sourceHandlerData; + JSInterpreterHook executeHook; + void *executeHookData; + JSInterpreterHook callHook; + void *callHookData; + JSObjectHook objectHook; + void *objectHookData; + JSTrapHandler throwHook; + void *throwHookData; + JSDebugErrorHook debugErrorHook; + void *debugErrorHookData; + + /* More debugging state, see jsdbgapi.c. */ + JSCList trapList; + JSCList watchPointList; + + /* Weak links to properties, indexed by quickened get/set opcodes. */ + /* XXX must come after JSCLists or MSVC alignment bug bites empty lists */ + JSPropertyCache propertyCache; + + /* Client opaque pointer */ + void *data; + +#ifdef JS_THREADSAFE + /* These combine to interlock the GC and new requests. */ + PRLock *gcLock; + PRCondVar *gcDone; + PRCondVar *requestDone; + uint32 requestCount; + jsword gcThread; + + /* Lock and owning thread pointer for JS_LOCK_RUNTIME. */ + PRLock *rtLock; +#ifdef DEBUG + jsword rtLockOwner; +#endif + + /* Used to synchronize down/up state change; protected by gcLock. */ + PRCondVar *stateChange; + + /* Used to serialize cycle checks when setting __proto__ or __parent__. */ + PRLock *setSlotLock; + PRCondVar *setSlotDone; + JSBool setSlotBusy; + JSScope *setSlotScope; /* deadlock avoidance, see jslock.c */ + + /* + * State for sharing single-threaded scopes, once a second thread tries to + * lock a scope. The scopeSharingDone condvar is protected by rt->gcLock, + * to minimize number of locks taken in JS_EndRequest. + * + * The scopeSharingTodo linked list is likewise "global" per runtime, not + * one-list-per-context, to conserve space over all contexts, optimizing + * for the likely case that scopes become shared rarely, and among a very + * small set of threads (contexts). + */ + PRCondVar *scopeSharingDone; + JSScope *scopeSharingTodo; + +/* + * Magic terminator for the rt->scopeSharingTodo linked list, threaded through + * scope->u.link. This hack allows us to test whether a scope is on the list + * by asking whether scope->u.link is non-null. We use a large, likely bogus + * pointer here to distinguish this value from any valid u.count (small int) + * value. + */ +#define NO_SCOPE_SHARING_TODO ((JSScope *) 0xfeedbeef) +#endif /* JS_THREADSAFE */ + + /* + * Check property accessibility for objects of arbitrary class. Used at + * present to check f.caller accessibility for any function object f. + */ + JSCheckAccessOp checkObjectAccess; + + /* Security principals serialization support. */ + JSPrincipalsTranscoder principalsTranscoder; + + /* Shared scope property tree, and allocator for its nodes. */ + JSDHashTable propertyTreeHash; + JSScopeProperty *propertyFreeList; + JSArenaPool propertyArenaPool; + +#ifdef DEBUG + /* Function invocation metering. */ + jsrefcount inlineCalls; + jsrefcount nativeCalls; + jsrefcount nonInlineCalls; + jsrefcount constructs; + + /* Scope lock and property metering. */ + jsrefcount claimAttempts; + jsrefcount claimedScopes; + jsrefcount deadContexts; + jsrefcount deadlocksAvoided; + jsrefcount liveScopes; + jsrefcount sharedScopes; + jsrefcount totalScopes; + jsrefcount badUndependStrings; + jsrefcount liveScopeProps; + jsrefcount totalScopeProps; + jsrefcount livePropTreeNodes; + jsrefcount duplicatePropTreeNodes; + jsrefcount totalPropTreeNodes; + jsrefcount propTreeKidsChunks; + jsrefcount middleDeleteFixups; + + /* String instrumentation. */ + jsrefcount liveStrings; + jsrefcount totalStrings; + jsrefcount liveDependentStrings; + jsrefcount totalDependentStrings; + double lengthSum; + double lengthSquaredSum; + double strdepLengthSum; + double strdepLengthSquaredSum; +#endif +}; + +#ifdef DEBUG +# define JS_RUNTIME_METER(rt, which) JS_ATOMIC_INCREMENT(&(rt)->which) +# define JS_RUNTIME_UNMETER(rt, which) JS_ATOMIC_DECREMENT(&(rt)->which) +#else +# define JS_RUNTIME_METER(rt, which) /* nothing */ +# define JS_RUNTIME_UNMETER(rt, which) /* nothing */ +#endif + +#define JS_KEEP_ATOMS(rt) JS_ATOMIC_INCREMENT(&(rt)->gcKeepAtoms); +#define JS_UNKEEP_ATOMS(rt) JS_ATOMIC_DECREMENT(&(rt)->gcKeepAtoms); + +#ifdef JS_ARGUMENT_FORMATTER_DEFINED +/* + * Linked list mapping format strings for JS_{Convert,Push}Arguments{,VA} to + * formatter functions. Elements are sorted in non-increasing format string + * length order. + */ +struct JSArgumentFormatMap { + const char *format; + size_t length; + JSArgumentFormatter formatter; + JSArgumentFormatMap *next; +}; +#endif + +struct JSStackHeader { + uintN nslots; + JSStackHeader *down; +}; + +#define JS_STACK_SEGMENT(sh) ((jsval *)(sh) + 2) + +/* + * Key and entry types for the JSContext.resolvingTable hash table, typedef'd + * here because all consumers need to see these declarations (and not just the + * typedef names, as would be the case for an opaque pointer-to-typedef'd-type + * declaration), along with cx->resolvingTable. + */ +typedef struct JSResolvingKey { + JSObject *obj; + jsid id; +} JSResolvingKey; + +typedef struct JSResolvingEntry { + JSDHashEntryHdr hdr; + JSResolvingKey key; + uint32 flags; +} JSResolvingEntry; + +#define JSRESFLAG_LOOKUP 0x1 /* resolving id from lookup */ +#define JSRESFLAG_WATCH 0x2 /* resolving id from watch */ + +struct JSContext { + JSCList links; + + /* Interpreter activation count. */ + uintN interpLevel; + + /* Limit pointer for checking stack consumption during recursion. */ + jsuword stackLimit; + + /* Runtime version control identifier and equality operators. */ + JSVersion version; + jsbytecode jsop_eq; + jsbytecode jsop_ne; + + /* Data shared by threads in an address space. */ + JSRuntime *runtime; + + /* Stack arena pool and frame pointer register. */ + JSArenaPool stackPool; + JSStackFrame *fp; + + /* Temporary arena pool used while compiling and decompiling. */ + JSArenaPool tempPool; + + /* Top-level object and pointer to top stack frame's scope chain. */ + JSObject *globalObject; + + /* Most recently created things by type, members of the GC's root set. */ + JSGCThing *newborn[GCX_NTYPES]; + + /* Atom root for the last-looked-up atom on this context. */ + JSAtom *lastAtom; + + /* Regular expression class statics (XXX not shared globally). */ + JSRegExpStatics regExpStatics; + + /* State for object and array toSource conversion. */ + JSSharpObjectMap sharpObjectMap; + + /* Argument formatter support for JS_{Convert,Push}Arguments{,VA}. */ + JSArgumentFormatMap *argumentFormatMap; + + /* Last message string and trace file for debugging. */ + char *lastMessage; +#ifdef DEBUG + void *tracefp; +#endif + + /* Per-context optional user callbacks. */ + JSBranchCallback branchCallback; + JSErrorReporter errorReporter; + + /* Client opaque pointer */ + void *data; + + /* GC and thread-safe state. */ + JSStackFrame *dormantFrameChain; /* dormant stack frame to scan */ +#ifdef JS_THREADSAFE + jsword thread; + jsrefcount requestDepth; + JSScope *scopeToShare; /* weak reference, see jslock.c */ + JSScope *lockedSealedScope; /* weak ref, for low-cost sealed + scope locking */ +#endif + +#if JS_HAS_LVALUE_RETURN + /* + * Secondary return value from native method called on the left-hand side + * of an assignment operator. The native should store the object in which + * to set a property in *rval, and return the property's id expressed as a + * jsval by calling JS_SetCallReturnValue2(cx, idval). + */ + jsval rval2; + JSPackedBool rval2set; +#endif + + /* + * True if creating an exception object, to prevent runaway recursion. + * NB: creatingException packs with rval2set, #if JS_HAS_LVALUE_RETURN, + * and with throwing, below. + */ + JSPackedBool creatingException; + + /* + * Exception state -- the exception member is a GC root by definition. + * NB: throwing packs with creatingException and rval2set, above. + */ + JSPackedBool throwing; /* is there a pending exception? */ + jsval exception; /* most-recently-thrown exception */ + + /* Per-context options. */ + uint32 options; /* see jsapi.h for JSOPTION_* */ + + /* Locale specific callbacks for string conversion. */ + JSLocaleCallbacks *localeCallbacks; + + /* + * cx->resolvingTable is non-null and non-empty if we are initializing + * standard classes lazily, or if we are otherwise recursing indirectly + * from js_LookupProperty through a JSClass.resolve hook. It is used to + * limit runaway recursion (see jsapi.c and jsobj.c). + */ + JSDHashTable *resolvingTable; + + /* PDL of stack headers describing stack slots not rooted by argv, etc. */ + JSStackHeader *stackHeaders; + + /* Optional hook to find principals for an object being accessed on cx. */ + JSObjectPrincipalsFinder findObjectPrincipals; +}; + +/* Slightly more readable macros, also to hide bitset implementation detail. */ +#define JS_HAS_STRICT_OPTION(cx) ((cx)->options & JSOPTION_STRICT) +#define JS_HAS_WERROR_OPTION(cx) ((cx)->options & JSOPTION_WERROR) + +extern JSContext * +js_NewContext(JSRuntime *rt, size_t stackChunkSize); + +extern void +js_DestroyContext(JSContext *cx, JSGCMode gcmode); + +/* + * Return true if cx points to a context in rt->contextList, else return false. + * NB: the caller (see jslock.c:ClaimScope) must hold rt->gcLock. + */ +extern JSBool +js_ValidContextPointer(JSRuntime *rt, JSContext *cx); + +/* + * If unlocked, acquire and release rt->gcLock around *iterp update; otherwise + * the caller must be holding rt->gcLock. + */ +extern JSContext * +js_ContextIterator(JSRuntime *rt, JSBool unlocked, JSContext **iterp); + +/* + * Report an exception, which is currently realized as a printf-style format + * string and its arguments. + */ +typedef enum JSErrNum { +#define MSG_DEF(name, number, count, exception, format) \ + name = number, +#include "js.msg" +#undef MSG_DEF + JSErr_Limit +} JSErrNum; + +extern const JSErrorFormatString * +js_GetErrorMessage(void *userRef, const char *locale, const uintN errorNumber); + +#ifdef va_start +extern JSBool +js_ReportErrorVA(JSContext *cx, uintN flags, const char *format, va_list ap); + +extern JSBool +js_ReportErrorNumberVA(JSContext *cx, uintN flags, JSErrorCallback callback, + void *userRef, const uintN errorNumber, + JSBool charArgs, va_list ap); + +extern JSBool +js_ExpandErrorArguments(JSContext *cx, JSErrorCallback callback, + void *userRef, const uintN errorNumber, + char **message, JSErrorReport *reportp, + JSBool *warningp, JSBool charArgs, va_list ap); +#endif + +extern void +js_ReportOutOfMemory(JSContext *cx, JSErrorCallback errorCallback); + +/* + * Report an exception using a previously composed JSErrorReport. + * XXXbe remove from "friend" API + */ +extern JS_FRIEND_API(void) +js_ReportErrorAgain(JSContext *cx, const char *message, JSErrorReport *report); + +extern void +js_ReportIsNotDefined(JSContext *cx, const char *name); + +extern JSErrorFormatString js_ErrorFormatString[JSErr_Limit]; + +/* + * See JS_SetThreadStackLimit in jsapi.c, where we check that the stack grows + * in the expected direction. On Unix-y systems, JS_STACK_GROWTH_DIRECTION is + * computed on the build host by jscpucfg.c and written into jsautocfg.h. The + * macro is hardcoded in jscpucfg.h on Windows and Mac systems (for historical + * reasons pre-dating autoconf usage). + */ +#if JS_STACK_GROWTH_DIRECTION > 0 +# define JS_CHECK_STACK_SIZE(cx, lval) ((jsuword)&(lval) < (cx)->stackLimit) +#else +# define JS_CHECK_STACK_SIZE(cx, lval) ((jsuword)&(lval) > (cx)->stackLimit) +#endif + +JS_END_EXTERN_C + +#endif /* jscntxt_h___ */ diff --git a/src/dom/js/jscompat.h b/src/dom/js/jscompat.h new file mode 100644 index 000000000..6ba036a5e --- /dev/null +++ b/src/dom/js/jscompat.h @@ -0,0 +1,57 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998-1999 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* -*- Mode: C; tab-width: 8 -*- + * Copyright © 1996-1999 Netscape Communications Corporation, All Rights Reserved. + */ +#ifndef jscompat_h___ +#define jscompat_h___ +/* + * Compatibility glue for various NSPR versions. We must always define int8, + * int16, jsword, and so on to minimize differences with js/ref, no matter what + * the NSPR typedef names may be. + */ +#include "jstypes.h" +#include "jslong.h" + +typedef JSIntn intN; +typedef JSUintn uintN; +typedef JSUword jsuword; +typedef JSWord jsword; +typedef float float32; +#define allocPriv allocPool +#endif /* jscompat_h___ */ diff --git a/src/dom/js/jsconfig.h b/src/dom/js/jsconfig.h new file mode 100644 index 000000000..fae86d3a7 --- /dev/null +++ b/src/dom/js/jsconfig.h @@ -0,0 +1,489 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* + * JS configuration macros. + */ +#ifndef JS_VERSION +#define JS_VERSION 150 +#endif + +/* + * Compile-time JS version configuration. The JS version numbers lie on the + * number line like so: + * + * 1.0 1.1 1.2 1.3 1.4 ECMAv3 1.5 + * ^ ^ + * | | + * basis for ECMAv1 close to ECMAv2 + * + * where ECMAv3 stands for ECMA-262 Edition 3. See the runtime version enum + * JSVersion in jspubtd.h. Code in the engine can therefore count on version + * <= JSVERSION_1_4 to mean "before the Third Edition of ECMA-262" and version + * > JSVERSION_1_4 to mean "at or after the Third Edition". + * + * In the unlikely event that SpiderMonkey ever implements JavaScript 2.0, or + * ECMA-262 Edition 4 (JS2 without certain extensions), the version number to + * use would be near 200, or greater. + * + * The JS_VERSION_ECMA_3 version is the minimal configuration conforming to + * the ECMA-262 Edition 3 specification. Use it for minimal embeddings, where + * you're sure you don't need any of the extensions disabled in this version. + * In order to facilitate testing, JS_HAS_OBJ_PROTO_PROP is defined as part of + * the JS_VERSION_ECMA_3_TEST version. + */ +#define JS_VERSION_ECMA_3 148 +#define JS_VERSION_ECMA_3_TEST 149 + +#if JS_VERSION == JS_VERSION_ECMA_3 || \ + JS_VERSION == JS_VERSION_ECMA_3_TEST + +#define JS_BUG_NULL_INDEX_PROPS 0 /* o[0] defaults to null, not void */ +#define JS_BUG_EMPTY_INDEX_ZERO 0 /* o[""] is equivalent to o[0] */ +#define JS_BUG_EAGER_TOSTRING 0 /* o.toString() trumps o.valueOf() */ +#define JS_BUG_VOID_TOSTRING 0 /* void 0 + 0 == "undefined0" */ +#define JS_BUG_EVAL_THIS_FUN 0 /* eval('this') in function f is f */ +#define JS_BUG_EVAL_THIS_SCOPE 0 /* Math.eval('sin(x)') vs. local x */ +#define JS_BUG_FALLIBLE_EQOPS 0 /* fallible/intransitive equality ops */ +#define JS_BUG_FALLIBLE_TONUM 0 /* fallible ValueToNumber primitive */ +#define JS_BUG_WITH_CLOSURE 0 /* with(o)function f(){} sets o.f */ + +#define JS_HAS_PROP_DELETE 1 /* delete o.p removes p from o */ +#define JS_HAS_CALL_OBJECT 1 /* fun.caller is stack frame obj */ +#define JS_HAS_LABEL_STATEMENT 1 /* has break/continue to label: */ +#define JS_HAS_DO_WHILE_LOOP 1 /* has do {...} while (b) */ +#define JS_HAS_SWITCH_STATEMENT 1 /* has switch (v) {case c: ...} */ +#define JS_HAS_SOME_PERL_FUN 1 /* has array.join/reverse/sort */ +#define JS_HAS_MORE_PERL_FUN 1 /* has array.push, array.pop, etc */ +#define JS_HAS_STR_HTML_HELPERS 0 /* has str.anchor, str.bold, etc. */ +#define JS_HAS_PERL_SUBSTR 0 /* has str.substr */ +#define JS_HAS_VALUEOF_HINT 1 /* valueOf(hint) where hint is typeof */ +#define JS_HAS_LEXICAL_CLOSURE 1 /* nested functions, lexically closed */ +#define JS_HAS_APPLY_FUNCTION 1 /* has fun.apply(obj, argArray) */ +#define JS_HAS_CALL_FUNCTION 1 /* has fun.call(obj, arg1, ... argN) */ +#if JS_VERSION == JS_VERSION_ECMA_3_TEST +#define JS_HAS_OBJ_PROTO_PROP 1 /* has o.__proto__ etc. */ +#else +#define JS_HAS_OBJ_PROTO_PROP 0 /* has o.__proto__ etc. */ +#endif +#define JS_HAS_REGEXPS 1 /* has perl r.e.s via RegExp, /pat/ */ +#define JS_HAS_SEQUENCE_OPS 1 /* has array.slice, string.concat */ +#define JS_HAS_INITIALIZERS 1 /* has var o = {'foo': 42, 'bar':3} */ +#define JS_HAS_OBJ_WATCHPOINT 0 /* has o.watch and o.unwatch */ +#define JS_HAS_EXPORT_IMPORT 0 /* has export fun; import obj.fun */ +#define JS_HAS_EVAL_THIS_SCOPE 0 /* Math.eval is same as with (Math) */ +#define JS_HAS_TRIPLE_EQOPS 1 /* has === and !== identity eqops */ +#define JS_HAS_SHARP_VARS 0 /* has #n=, #n# for object literals */ +#define JS_HAS_REPLACE_LAMBDA 1 /* has string.replace(re, lambda) */ +#define JS_HAS_SCRIPT_OBJECT 0 /* has (new Script("x++")).exec() */ +#define JS_HAS_XDR 0 /* has XDR API and internal support */ +#define JS_HAS_XDR_FREEZE_THAW 0 /* has XDR freeze/thaw script methods */ +#define JS_HAS_EXCEPTIONS 1 /* has exception handling */ +#define JS_HAS_UNDEFINED 1 /* has global "undefined" property */ +#define JS_HAS_TOSOURCE 0 /* has Object/Array toSource method */ +#define JS_HAS_IN_OPERATOR 1 /* has in operator ('p' in {p:1}) */ +#define JS_HAS_INSTANCEOF 1 /* has {p:1} instanceof Object */ +#define JS_HAS_ARGS_OBJECT 1 /* has minimal ECMA arguments object */ +#define JS_HAS_DEBUGGER_KEYWORD 0 /* has hook for debugger keyword */ +#define JS_HAS_ERROR_EXCEPTIONS 1 /* has error object hierarchy */ +#define JS_HAS_CATCH_GUARD 0 /* has exception handling catch guard */ +#define JS_HAS_NEW_OBJ_METHODS 1 /* has Object.prototype query methods */ +#define JS_HAS_SPARSE_ARRAYS 0 /* array methods preserve empty elems */ +#define JS_HAS_DFLT_MSG_STRINGS 1 /* provides English error messages */ +#define JS_HAS_NUMBER_FORMATS 1 /* numbers have formatting methods */ +#define JS_HAS_GETTER_SETTER 0 /* has JS2 getter/setter functions */ +#define JS_HAS_UNEVAL 0 /* has uneval() top-level function */ +#define JS_HAS_CONST 0 /* has JS2 const as alternative var */ +#define JS_HAS_FUN_EXPR_STMT 0 /* has function expression statement */ +#define JS_HAS_LVALUE_RETURN 1 /* has o.item(i) = j; for native item */ +#define JS_HAS_NO_SUCH_METHOD 0 /* has o.__noSuchMethod__ handler */ + +#elif JS_VERSION == 100 + +#define JS_BUG_NULL_INDEX_PROPS 1 /* o[0] defaults to null, not void */ +#define JS_BUG_EMPTY_INDEX_ZERO 1 /* o[""] is equivalent to o[0] */ +#define JS_BUG_EAGER_TOSTRING 1 /* o.toString() trumps o.valueOf() */ +#define JS_BUG_VOID_TOSTRING 0 /* void 0 + 0 == "undefined0" */ +#define JS_BUG_EVAL_THIS_FUN 0 /* eval('this') in function f is f */ +#define JS_BUG_EVAL_THIS_SCOPE 0 /* Math.eval('sin(x)') vs. local x */ +#define JS_BUG_FALLIBLE_EQOPS 1 /* fallible/intransitive equality ops */ +#define JS_BUG_FALLIBLE_TONUM 1 /* fallible ValueToNumber primitive */ +#define JS_BUG_WITH_CLOSURE 0 /* with(o)function f(){} sets o.f */ + +#define JS_HAS_PROP_DELETE 0 /* delete o.p removes p from o */ +#define JS_HAS_CALL_OBJECT 0 /* fun.caller is stack frame obj */ +#define JS_HAS_LABEL_STATEMENT 0 /* has break/continue to label: */ +#define JS_HAS_DO_WHILE_LOOP 0 /* has do {...} while (b) */ +#define JS_HAS_SWITCH_STATEMENT 0 /* has switch (v) {case c: ...} */ +#define JS_HAS_SOME_PERL_FUN 0 /* has array.join/reverse/sort */ +#define JS_HAS_MORE_PERL_FUN 0 /* has array.push, str.substr, etc */ +#define JS_HAS_STR_HTML_HELPERS 1 /* has str.anchor, str.bold, etc. */ +#define JS_HAS_PERL_SUBSTR 0 /* has str.substr */ +#define JS_HAS_VALUEOF_HINT 0 /* valueOf(hint) where hint is typeof */ +#define JS_HAS_LEXICAL_CLOSURE 0 /* nested functions, lexically closed */ +#define JS_HAS_APPLY_FUNCTION 0 /* has fun.apply(obj, argArray) */ +#define JS_HAS_CALL_FUNCTION 0 /* has fun.call(obj, arg1, ... argN) */ +#define JS_HAS_OBJ_PROTO_PROP 0 /* has o.__proto__ etc. */ +#define JS_HAS_REGEXPS 0 /* has perl r.e.s via RegExp, /pat/ */ +#define JS_HAS_SEQUENCE_OPS 0 /* has array.slice, string.concat */ +#define JS_HAS_INITIALIZERS 0 /* has var o = {'foo': 42, 'bar':3} */ +#define JS_HAS_OBJ_WATCHPOINT 0 /* has o.watch and o.unwatch */ +#define JS_HAS_EXPORT_IMPORT 0 /* has export fun; import obj.fun */ +#define JS_HAS_EVAL_THIS_SCOPE 0 /* Math.eval is same as with (Math) */ +#define JS_HAS_TRIPLE_EQOPS 0 /* has === and !== identity eqops */ +#define JS_HAS_SHARP_VARS 0 /* has #n=, #n# for object literals */ +#define JS_HAS_REPLACE_LAMBDA 0 /* has string.replace(re, lambda) */ +#define JS_HAS_SCRIPT_OBJECT 0 /* has (new Script("x++")).exec() */ +#define JS_HAS_XDR 0 /* has XDR API and internal support */ +#define JS_HAS_XDR_FREEZE_THAW 0 /* has XDR freeze/thaw script methods */ +#define JS_HAS_EXCEPTIONS 0 /* has exception handling */ +#define JS_HAS_UNDEFINED 0 /* has global "undefined" property */ +#define JS_HAS_TOSOURCE 0 /* has Object/Array toSource method */ +#define JS_HAS_IN_OPERATOR 0 /* has in operator ('p' in {p:1}) */ +#define JS_HAS_INSTANCEOF 0 /* has {p:1} instanceof Object */ +#define JS_HAS_ARGS_OBJECT 0 /* has minimal ECMA arguments object */ +#define JS_HAS_DEBUGGER_KEYWORD 0 /* has hook for debugger keyword */ +#define JS_HAS_ERROR_EXCEPTIONS 0 /* has error object hierarchy */ +#define JS_HAS_CATCH_GUARD 0 /* has exception handling catch guard */ +#define JS_HAS_NEW_OBJ_METHODS 0 /* has Object.prototype query methods */ +#define JS_HAS_SPARSE_ARRAYS 0 /* array methods preserve empty elems */ +#define JS_HAS_DFLT_MSG_STRINGS 1 /* provides English error messages */ +#define JS_HAS_NUMBER_FORMATS 0 /* numbers have formatting methods */ +#define JS_HAS_GETTER_SETTER 0 /* has JS2 getter/setter functions */ +#define JS_HAS_UNEVAL 0 /* has uneval() top-level function */ +#define JS_HAS_CONST 0 /* has JS2 const as alternative var */ +#define JS_HAS_FUN_EXPR_STMT 0 /* has function expression statement */ +#define JS_HAS_LVALUE_RETURN 0 /* has o.item(i) = j; for native item */ +#define JS_HAS_NO_SUCH_METHOD 0 /* has o.__noSuchMethod__ handler */ + +#elif JS_VERSION == 110 + +#define JS_BUG_NULL_INDEX_PROPS 1 /* o[0] defaults to null, not void */ +#define JS_BUG_EMPTY_INDEX_ZERO 1 /* o[""] is equivalent to o[0] */ +#define JS_BUG_EAGER_TOSTRING 1 /* o.toString() trumps o.valueOf() */ +#define JS_BUG_VOID_TOSTRING 0 /* void 0 + 0 == "undefined0" */ +#define JS_BUG_EVAL_THIS_FUN 1 /* eval('this') in function f is f */ +#define JS_BUG_EVAL_THIS_SCOPE 1 /* Math.eval('sin(x)') vs. local x */ +#define JS_BUG_FALLIBLE_EQOPS 1 /* fallible/intransitive equality ops */ +#define JS_BUG_FALLIBLE_TONUM 1 /* fallible ValueToNumber primitive */ +#define JS_BUG_WITH_CLOSURE 0 /* with(o)function f(){} sets o.f */ + +#define JS_HAS_PROP_DELETE 0 /* delete o.p removes p from o */ +#define JS_HAS_CALL_OBJECT 0 /* fun.caller is stack frame obj */ +#define JS_HAS_LABEL_STATEMENT 0 /* has break/continue to label: */ +#define JS_HAS_DO_WHILE_LOOP 0 /* has do {...} while (b) */ +#define JS_HAS_SWITCH_STATEMENT 0 /* has switch (v) {case c: ...} */ +#define JS_HAS_SOME_PERL_FUN 1 /* has array.join/reverse/sort */ +#define JS_HAS_MORE_PERL_FUN 0 /* has array.push, str.substr, etc */ +#define JS_HAS_STR_HTML_HELPERS 1 /* has str.anchor, str.bold, etc. */ +#define JS_HAS_PERL_SUBSTR 0 /* has str.substr */ +#define JS_HAS_VALUEOF_HINT 0 /* valueOf(hint) where hint is typeof */ +#define JS_HAS_LEXICAL_CLOSURE 0 /* nested functions, lexically closed */ +#define JS_HAS_APPLY_FUNCTION 0 /* has apply(fun, arg1, ... argN) */ +#define JS_HAS_CALL_FUNCTION 0 /* has fun.call(obj, arg1, ... argN) */ +#define JS_HAS_OBJ_PROTO_PROP 0 /* has o.__proto__ etc. */ +#define JS_HAS_REGEXPS 0 /* has perl r.e.s via RegExp, /pat/ */ +#define JS_HAS_SEQUENCE_OPS 0 /* has array.slice, string.concat */ +#define JS_HAS_INITIALIZERS 0 /* has var o = {'foo': 42, 'bar':3} */ +#define JS_HAS_OBJ_WATCHPOINT 0 /* has o.watch and o.unwatch */ +#define JS_HAS_EXPORT_IMPORT 0 /* has export fun; import obj.fun */ +#define JS_HAS_EVAL_THIS_SCOPE 0 /* Math.eval is same as with (Math) */ +#define JS_HAS_TRIPLE_EQOPS 0 /* has === and !== identity eqops */ +#define JS_HAS_SHARP_VARS 0 /* has #n=, #n# for object literals */ +#define JS_HAS_REPLACE_LAMBDA 0 /* has string.replace(re, lambda) */ +#define JS_HAS_SCRIPT_OBJECT 0 /* has (new Script("x++")).exec() */ +#define JS_HAS_XDR 0 /* has XDR API and internal support */ +#define JS_HAS_XDR_FREEZE_THAW 0 /* has XDR freeze/thaw script methods */ +#define JS_HAS_EXCEPTIONS 0 /* has exception handling */ +#define JS_HAS_UNDEFINED 0 /* has global "undefined" property */ +#define JS_HAS_TOSOURCE 0 /* has Object/Array toSource method */ +#define JS_HAS_IN_OPERATOR 0 /* has in operator ('p' in {p:1}) */ +#define JS_HAS_INSTANCEOF 0 /* has {p:1} instanceof Object */ +#define JS_HAS_ARGS_OBJECT 0 /* has minimal ECMA arguments object */ +#define JS_HAS_DEBUGGER_KEYWORD 0 /* has hook for debugger keyword */ +#define JS_HAS_ERROR_EXCEPTIONS 0 /* has error object hierarchy */ +#define JS_HAS_CATCH_GUARD 0 /* has exception handling catch guard */ +#define JS_HAS_NEW_OBJ_METHODS 0 /* has Object.prototype query methods */ +#define JS_HAS_SPARSE_ARRAYS 0 /* array methods preserve empty elems */ +#define JS_HAS_DFLT_MSG_STRINGS 1 /* provides English error messages */ +#define JS_HAS_NUMBER_FORMATS 0 /* numbers have formatting methods */ +#define JS_HAS_GETTER_SETTER 0 /* has JS2 getter/setter functions */ +#define JS_HAS_UNEVAL 0 /* has uneval() top-level function */ +#define JS_HAS_CONST 0 /* has JS2 const as alternative var */ +#define JS_HAS_FUN_EXPR_STMT 0 /* has function expression statement */ +#define JS_HAS_LVALUE_RETURN 0 /* has o.item(i) = j; for native item */ +#define JS_HAS_NO_SUCH_METHOD 0 /* has o.__noSuchMethod__ handler */ + +#elif JS_VERSION == 120 + +#define JS_BUG_NULL_INDEX_PROPS 0 /* o[0] defaults to null, not void */ +#define JS_BUG_EMPTY_INDEX_ZERO 0 /* o[""] is equivalent to o[0] */ +#define JS_BUG_EAGER_TOSTRING 0 /* o.toString() trumps o.valueOf() */ +#define JS_BUG_VOID_TOSTRING 1 /* void 0 + 0 == "undefined0" */ +#define JS_BUG_EVAL_THIS_FUN 0 /* eval('this') in function f is f */ +#define JS_BUG_EVAL_THIS_SCOPE 0 /* Math.eval('sin(x)') vs. local x */ +#define JS_BUG_FALLIBLE_EQOPS 0 /* fallible/intransitive equality ops */ +#define JS_BUG_FALLIBLE_TONUM 0 /* fallible ValueToNumber primitive */ +#define JS_BUG_WITH_CLOSURE 1 /* with(o)function f(){} sets o.f */ + +#define JS_HAS_PROP_DELETE 1 /* delete o.p removes p from o */ +#define JS_HAS_CALL_OBJECT 1 /* fun.caller is stack frame obj */ +#define JS_HAS_LABEL_STATEMENT 1 /* has break/continue to label: */ +#define JS_HAS_DO_WHILE_LOOP 1 /* has do {...} while (b) */ +#define JS_HAS_SWITCH_STATEMENT 1 /* has switch (v) {case c: ...} */ +#define JS_HAS_SOME_PERL_FUN 1 /* has array.join/reverse/sort */ +#define JS_HAS_MORE_PERL_FUN 1 /* has array.push, str.substr, etc */ +#define JS_HAS_STR_HTML_HELPERS 1 /* has str.anchor, str.bold, etc. */ +#define JS_HAS_PERL_SUBSTR 1 /* has str.substr */ +#define JS_HAS_VALUEOF_HINT 1 /* valueOf(hint) where hint is typeof */ +#define JS_HAS_LEXICAL_CLOSURE 1 /* nested functions, lexically closed */ +#define JS_HAS_APPLY_FUNCTION 1 /* has apply(fun, arg1, ... argN) */ +#define JS_HAS_CALL_FUNCTION 0 /* has fun.call(obj, arg1, ... argN) */ +#define JS_HAS_OBJ_PROTO_PROP 1 /* has o.__proto__ etc. */ +#define JS_HAS_REGEXPS 1 /* has perl r.e.s via RegExp, /pat/ */ +#define JS_HAS_SEQUENCE_OPS 1 /* has array.slice, string.concat */ +#define JS_HAS_INITIALIZERS 1 /* has var o = {'foo': 42, 'bar':3} */ +#define JS_HAS_OBJ_WATCHPOINT 1 /* has o.watch and o.unwatch */ +#define JS_HAS_EXPORT_IMPORT 1 /* has export fun; import obj.fun */ +#define JS_HAS_EVAL_THIS_SCOPE 1 /* Math.eval is same as with (Math) */ +#define JS_HAS_TRIPLE_EQOPS 0 /* has === and !== identity eqops */ +#define JS_HAS_SHARP_VARS 0 /* has #n=, #n# for object literals */ +#define JS_HAS_REPLACE_LAMBDA 0 /* has string.replace(re, lambda) */ +#define JS_HAS_SCRIPT_OBJECT 0 /* has (new Script("x++")).exec() */ +#define JS_HAS_XDR 0 /* has XDR API and internal support */ +#define JS_HAS_XDR_FREEZE_THAW 0 /* has XDR freeze/thaw script methods */ +#define JS_HAS_EXCEPTIONS 0 /* has exception handling */ +#define JS_HAS_UNDEFINED 0 /* has global "undefined" property */ +#define JS_HAS_TOSOURCE 0 /* has Object/Array toSource method */ +#define JS_HAS_IN_OPERATOR 0 /* has in operator ('p' in {p:1}) */ +#define JS_HAS_INSTANCEOF 0 /* has {p:1} instanceof Object */ +#define JS_HAS_ARGS_OBJECT 0 /* has minimal ECMA arguments object */ +#define JS_HAS_DEBUGGER_KEYWORD 0 /* has hook for debugger keyword */ +#define JS_HAS_ERROR_EXCEPTIONS 0 /* has error object hierarchy */ +#define JS_HAS_CATCH_GUARD 0 /* has exception handling catch guard */ +#define JS_HAS_NEW_OBJ_METHODS 0 /* has Object.prototype query methods */ +#define JS_HAS_SPARSE_ARRAYS 0 /* array methods preserve empty elems */ +#define JS_HAS_DFLT_MSG_STRINGS 1 /* provides English error messages */ +#define JS_HAS_NUMBER_FORMATS 0 /* numbers have formatting methods */ +#define JS_HAS_GETTER_SETTER 0 /* has JS2 getter/setter functions */ +#define JS_HAS_UNEVAL 0 /* has uneval() top-level function */ +#define JS_HAS_CONST 0 /* has JS2 const as alternative var */ +#define JS_HAS_FUN_EXPR_STMT 0 /* has function expression statement */ +#define JS_HAS_LVALUE_RETURN 0 /* has o.item(i) = j; for native item */ +#define JS_HAS_NO_SUCH_METHOD 0 /* has o.__noSuchMethod__ handler */ + +#elif JS_VERSION == 130 + +#define JS_BUG_NULL_INDEX_PROPS 0 /* o[0] defaults to null, not void */ +#define JS_BUG_EMPTY_INDEX_ZERO 0 /* o[""] is equivalent to o[0] */ +#define JS_BUG_EAGER_TOSTRING 0 /* o.toString() trumps o.valueOf() */ +#define JS_BUG_VOID_TOSTRING 0 /* void 0 + 0 == "undefined0" */ +#define JS_BUG_EVAL_THIS_FUN 0 /* eval('this') in function f is f */ +#define JS_BUG_EVAL_THIS_SCOPE 0 /* Math.eval('sin(x)') vs. local x */ +#define JS_BUG_FALLIBLE_EQOPS 0 /* fallible/intransitive equality ops */ +#define JS_BUG_FALLIBLE_TONUM 0 /* fallible ValueToNumber primitive */ +#define JS_BUG_WITH_CLOSURE 1 /* with(o)function f(){} sets o.f */ + +#define JS_HAS_PROP_DELETE 1 /* delete o.p removes p from o */ +#define JS_HAS_CALL_OBJECT 1 /* fun.caller is stack frame obj */ +#define JS_HAS_LABEL_STATEMENT 1 /* has break/continue to label: */ +#define JS_HAS_DO_WHILE_LOOP 1 /* has do {...} while (b) */ +#define JS_HAS_SWITCH_STATEMENT 1 /* has switch (v) {case c: ...} */ +#define JS_HAS_SOME_PERL_FUN 1 /* has array.join/reverse/sort */ +#define JS_HAS_MORE_PERL_FUN 1 /* has array.push, str.substr, etc */ +#define JS_HAS_STR_HTML_HELPERS 1 /* has str.anchor, str.bold, etc. */ +#define JS_HAS_PERL_SUBSTR 1 /* has str.substr */ +#define JS_HAS_VALUEOF_HINT 1 /* valueOf(hint) where hint is typeof */ +#define JS_HAS_LEXICAL_CLOSURE 1 /* nested functions, lexically closed */ +#define JS_HAS_APPLY_FUNCTION 1 /* has apply(fun, arg1, ... argN) */ +#define JS_HAS_CALL_FUNCTION 1 /* has fun.call(obj, arg1, ... argN) */ +#define JS_HAS_OBJ_PROTO_PROP 1 /* has o.__proto__ etc. */ +#define JS_HAS_REGEXPS 1 /* has perl r.e.s via RegExp, /pat/ */ +#define JS_HAS_SEQUENCE_OPS 1 /* has array.slice, string.concat */ +#define JS_HAS_INITIALIZERS 1 /* has var o = {'foo': 42, 'bar':3} */ +#define JS_HAS_OBJ_WATCHPOINT 1 /* has o.watch and o.unwatch */ +#define JS_HAS_EXPORT_IMPORT 1 /* has export fun; import obj.fun */ +#define JS_HAS_EVAL_THIS_SCOPE 1 /* Math.eval is same as with (Math) */ +#define JS_HAS_TRIPLE_EQOPS 1 /* has === and !== identity eqops */ +#define JS_HAS_SHARP_VARS 1 /* has #n=, #n# for object literals */ +#define JS_HAS_REPLACE_LAMBDA 1 /* has string.replace(re, lambda) */ +#define JS_HAS_SCRIPT_OBJECT 1 /* has (new Script("x++")).exec() */ +#define JS_HAS_XDR 1 /* has XDR API and internal support */ +#define JS_HAS_XDR_FREEZE_THAW 0 /* has XDR freeze/thaw script methods */ +#define JS_HAS_EXCEPTIONS 0 /* has exception handling */ +#define JS_HAS_UNDEFINED 1 /* has global "undefined" property */ +#define JS_HAS_TOSOURCE 1 /* has Object/Array toSource method */ +#define JS_HAS_IN_OPERATOR 0 /* has in operator ('p' in {p:1}) */ +#define JS_HAS_INSTANCEOF 0 /* has {p:1} instanceof Object */ +#define JS_HAS_ARGS_OBJECT 1 /* has minimal ECMA arguments object */ +#define JS_HAS_DEBUGGER_KEYWORD 1 /* has hook for debugger keyword */ +#define JS_HAS_ERROR_EXCEPTIONS 0 /* has error object hierarchy */ +#define JS_HAS_CATCH_GUARD 0 /* has exception handling catch guard */ +#define JS_HAS_NEW_OBJ_METHODS 0 /* has Object.prototype query methods */ +#define JS_HAS_SPARSE_ARRAYS 0 /* array methods preserve empty elems */ +#define JS_HAS_DFLT_MSG_STRINGS 1 /* provides English error messages */ +#define JS_HAS_NUMBER_FORMATS 0 /* numbers have formatting methods */ +#define JS_HAS_GETTER_SETTER 0 /* has JS2 getter/setter functions */ +#define JS_HAS_UNEVAL 0 /* has uneval() top-level function */ +#define JS_HAS_CONST 0 /* has JS2 const as alternative var */ +#define JS_HAS_FUN_EXPR_STMT 0 /* has function expression statement */ +#define JS_HAS_LVALUE_RETURN 0 /* has o.item(i) = j; for native item */ +#define JS_HAS_NO_SUCH_METHOD 0 /* has o.__noSuchMethod__ handler */ + +#elif JS_VERSION == 140 + +#define JS_BUG_NULL_INDEX_PROPS 0 /* o[0] defaults to null, not void */ +#define JS_BUG_EMPTY_INDEX_ZERO 0 /* o[""] is equivalent to o[0] */ +#define JS_BUG_EAGER_TOSTRING 0 /* o.toString() trumps o.valueOf() */ +#define JS_BUG_VOID_TOSTRING 0 /* void 0 + 0 == "undefined0" */ +#define JS_BUG_EVAL_THIS_FUN 0 /* eval('this') in function f is f */ +#define JS_BUG_EVAL_THIS_SCOPE 0 /* Math.eval('sin(x)') vs. local x */ +#define JS_BUG_FALLIBLE_EQOPS 0 /* fallible/intransitive equality ops */ +#define JS_BUG_FALLIBLE_TONUM 0 /* fallible ValueToNumber primitive */ +#define JS_BUG_WITH_CLOSURE 1 /* with(o)function f(){} sets o.f */ + +#define JS_HAS_PROP_DELETE 1 /* delete o.p removes p from o */ +#define JS_HAS_CALL_OBJECT 1 /* fun.caller is stack frame obj */ +#define JS_HAS_LABEL_STATEMENT 1 /* has break/continue to label: */ +#define JS_HAS_DO_WHILE_LOOP 1 /* has do {...} while (b) */ +#define JS_HAS_SWITCH_STATEMENT 1 /* has switch (v) {case c: ...} */ +#define JS_HAS_SOME_PERL_FUN 1 /* has array.join/reverse/sort */ +#define JS_HAS_MORE_PERL_FUN 1 /* has array.push, str.substr, etc */ +#define JS_HAS_STR_HTML_HELPERS 1 /* has str.anchor, str.bold, etc. */ +#define JS_HAS_PERL_SUBSTR 1 /* has str.substr */ +#define JS_HAS_VALUEOF_HINT 1 /* valueOf(hint) where hint is typeof */ +#define JS_HAS_LEXICAL_CLOSURE 1 /* nested functions, lexically closed */ +#define JS_HAS_APPLY_FUNCTION 1 /* has apply(fun, arg1, ... argN) */ +#define JS_HAS_CALL_FUNCTION 1 /* has fun.call(obj, arg1, ... argN) */ +#define JS_HAS_OBJ_PROTO_PROP 1 /* has o.__proto__ etc. */ +#define JS_HAS_REGEXPS 1 /* has perl r.e.s via RegExp, /pat/ */ +#define JS_HAS_SEQUENCE_OPS 1 /* has array.slice, string.concat */ +#define JS_HAS_INITIALIZERS 1 /* has var o = {'foo': 42, 'bar':3} */ +#define JS_HAS_OBJ_WATCHPOINT 1 /* has o.watch and o.unwatch */ +#define JS_HAS_EXPORT_IMPORT 1 /* has export fun; import obj.fun */ +#define JS_HAS_EVAL_THIS_SCOPE 1 /* Math.eval is same as with (Math) */ +#define JS_HAS_TRIPLE_EQOPS 1 /* has === and !== identity eqops */ +#define JS_HAS_SHARP_VARS 1 /* has #n=, #n# for object literals */ +#define JS_HAS_REPLACE_LAMBDA 1 /* has string.replace(re, lambda) */ +#define JS_HAS_SCRIPT_OBJECT 1 /* has (new Script("x++")).exec() */ +#define JS_HAS_XDR 1 /* has XDR API and internal support */ +#define JS_HAS_XDR_FREEZE_THAW 0 /* has XDR freeze/thaw script methods */ +#define JS_HAS_EXCEPTIONS 1 /* has exception handling */ +#define JS_HAS_UNDEFINED 1 /* has global "undefined" property */ +#define JS_HAS_TOSOURCE 1 /* has Object/Array toSource method */ +#define JS_HAS_IN_OPERATOR 1 /* has in operator ('p' in {p:1}) */ +#define JS_HAS_INSTANCEOF 1 /* has {p:1} instanceof Object */ +#define JS_HAS_ARGS_OBJECT 1 /* has minimal ECMA arguments object */ +#define JS_HAS_DEBUGGER_KEYWORD 1 /* has hook for debugger keyword */ +#define JS_HAS_ERROR_EXCEPTIONS 0 /* rt errors reflected as exceptions */ +#define JS_HAS_CATCH_GUARD 0 /* has exception handling catch guard */ +#define JS_HAS_NEW_OBJ_METHODS 0 /* has Object.prototype query methods */ +#define JS_HAS_SPARSE_ARRAYS 0 /* array methods preserve empty elems */ +#define JS_HAS_DFLT_MSG_STRINGS 1 /* provides English error messages */ +#define JS_HAS_NUMBER_FORMATS 0 /* numbers have formatting methods */ +#define JS_HAS_GETTER_SETTER 0 /* has JS2 getter/setter functions */ +#define JS_HAS_UNEVAL 0 /* has uneval() top-level function */ +#define JS_HAS_CONST 0 /* has JS2 const as alternative var */ +#define JS_HAS_FUN_EXPR_STMT 0 /* has function expression statement */ +#define JS_HAS_LVALUE_RETURN 0 /* has o.item(i) = j; for native item */ +#define JS_HAS_NO_SUCH_METHOD 0 /* has o.__noSuchMethod__ handler */ + +#elif JS_VERSION == 150 + +#define JS_BUG_NULL_INDEX_PROPS 0 /* o[0] defaults to null, not void */ +#define JS_BUG_EMPTY_INDEX_ZERO 0 /* o[""] is equivalent to o[0] */ +#define JS_BUG_EAGER_TOSTRING 0 /* o.toString() trumps o.valueOf() */ +#define JS_BUG_VOID_TOSTRING 0 /* void 0 + 0 == "undefined0" */ +#define JS_BUG_EVAL_THIS_FUN 0 /* eval('this') in function f is f */ +#define JS_BUG_EVAL_THIS_SCOPE 0 /* Math.eval('sin(x)') vs. local x */ +#define JS_BUG_FALLIBLE_EQOPS 0 /* fallible/intransitive equality ops */ +#define JS_BUG_FALLIBLE_TONUM 0 /* fallible ValueToNumber primitive */ +#define JS_BUG_WITH_CLOSURE 0 /* with(o)function f(){} sets o.f */ + +#define JS_HAS_PROP_DELETE 1 /* delete o.p removes p from o */ +#define JS_HAS_CALL_OBJECT 1 /* fun.caller is stack frame obj */ +#define JS_HAS_LABEL_STATEMENT 1 /* has break/continue to label: */ +#define JS_HAS_DO_WHILE_LOOP 1 /* has do {...} while (b) */ +#define JS_HAS_SWITCH_STATEMENT 1 /* has switch (v) {case c: ...} */ +#define JS_HAS_SOME_PERL_FUN 1 /* has array.join/reverse/sort */ +#define JS_HAS_MORE_PERL_FUN 1 /* has array.push, str.substr, etc */ +#define JS_HAS_STR_HTML_HELPERS 1 /* has str.anchor, str.bold, etc. */ +#define JS_HAS_PERL_SUBSTR 1 /* has str.substr */ +#define JS_HAS_VALUEOF_HINT 1 /* valueOf(hint) where hint is typeof */ +#define JS_HAS_LEXICAL_CLOSURE 1 /* nested functions, lexically closed */ +#define JS_HAS_APPLY_FUNCTION 1 /* has apply(fun, arg1, ... argN) */ +#define JS_HAS_CALL_FUNCTION 1 /* has fun.call(obj, arg1, ... argN) */ +#define JS_HAS_OBJ_PROTO_PROP 1 /* has o.__proto__ etc. */ +#define JS_HAS_REGEXPS 1 /* has perl r.e.s via RegExp, /pat/ */ +#define JS_HAS_SEQUENCE_OPS 1 /* has array.slice, string.concat */ +#define JS_HAS_INITIALIZERS 1 /* has var o = {'foo': 42, 'bar':3} */ +#define JS_HAS_OBJ_WATCHPOINT 1 /* has o.watch and o.unwatch */ +#define JS_HAS_EXPORT_IMPORT 0 /* has export fun; import obj.fun */ +#define JS_HAS_EVAL_THIS_SCOPE 1 /* Math.eval is same as with (Math) */ +#define JS_HAS_TRIPLE_EQOPS 1 /* has === and !== identity eqops */ +#define JS_HAS_SHARP_VARS 1 /* has #n=, #n# for object literals */ +#define JS_HAS_REPLACE_LAMBDA 1 /* has string.replace(re, lambda) */ +#define JS_HAS_SCRIPT_OBJECT 1 /* has (new Script("x++")).exec() */ +#define JS_HAS_XDR 1 /* has XDR API and internal support */ +#define JS_HAS_XDR_FREEZE_THAW 0 /* has XDR freeze/thaw script methods */ +#define JS_HAS_EXCEPTIONS 1 /* has exception handling */ +#define JS_HAS_UNDEFINED 1 /* has global "undefined" property */ +#define JS_HAS_TOSOURCE 1 /* has Object/Array toSource method */ +#define JS_HAS_IN_OPERATOR 1 /* has in operator ('p' in {p:1}) */ +#define JS_HAS_INSTANCEOF 1 /* has {p:1} instanceof Object */ +#define JS_HAS_ARGS_OBJECT 1 /* has minimal ECMA arguments object */ +#define JS_HAS_DEBUGGER_KEYWORD 1 /* has hook for debugger keyword */ +#define JS_HAS_ERROR_EXCEPTIONS 1 /* rt errors reflected as exceptions */ +#define JS_HAS_CATCH_GUARD 1 /* has exception handling catch guard */ +#define JS_HAS_NEW_OBJ_METHODS 1 /* has Object.prototype query methods */ +#define JS_HAS_SPARSE_ARRAYS 0 /* array methods preserve empty elems */ +#define JS_HAS_DFLT_MSG_STRINGS 1 /* provides English error messages */ +#define JS_HAS_NUMBER_FORMATS 1 /* numbers have formatting methods */ +#define JS_HAS_GETTER_SETTER 1 /* has JS2 getter/setter functions */ +#define JS_HAS_UNEVAL 1 /* has uneval() top-level function */ +#define JS_HAS_CONST 1 /* has JS2 const as alternative var */ +#define JS_HAS_FUN_EXPR_STMT 1 /* has function expression statement */ +#define JS_HAS_LVALUE_RETURN 1 /* has o.item(i) = j; for native item */ +#define JS_HAS_NO_SUCH_METHOD 1 /* has o.__noSuchMethod__ handler */ + +#else + +#error "unknown JS_VERSION" + +#endif diff --git a/src/dom/js/jscpucfg.c b/src/dom/js/jscpucfg.c new file mode 100644 index 000000000..aa6c04c4d --- /dev/null +++ b/src/dom/js/jscpucfg.c @@ -0,0 +1,377 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Roland Mainz + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* + * Generate CPU-specific bit-size and similar #defines. + */ +#include +#include + +#ifdef CROSS_COMPILE +#include +#define INT64 PRInt64 +#else + +#ifdef __MWERKS__ +#define XP_MAC 1 +#endif + +/************************************************************************/ + +/* Generate cpucfg.h */ +#ifdef XP_MAC +#include +#define INT64 UnsignedWide +#else +#if defined(XP_WIN) || defined(XP_OS2) +#ifdef WIN32 +#if defined(__GNUC__) +#define INT64 long long +#else +#define INT64 _int64 +#endif /* __GNUC__ */ +#else +#define INT64 long +#endif +#else +#if defined(HPUX) || defined(__QNX__) || defined(_SCO_DS) || defined(UNIXWARE) +#define INT64 long +#else +#define INT64 long long +#endif +#endif +#endif + +#endif /* CROSS_COMPILE */ + +typedef void *prword; + +struct align_short { + char c; + short a; +}; +struct align_int { + char c; + int a; +}; +struct align_long { + char c; + long a; +}; +struct align_int64 { + char c; + INT64 a; +}; +struct align_fakelonglong { + char c; + struct { + long hi, lo; + } a; +}; +struct align_float { + char c; + float a; +}; +struct align_double { + char c; + double a; +}; +struct align_pointer { + char c; + void *a; +}; +struct align_prword { + char c; + prword a; +}; + +#define ALIGN_OF(type) \ + (((char*)&(((struct align_##type *)0)->a)) - ((char*)0)) + +unsigned int bpb; + +static int Log2(unsigned int n) +{ + int log2 = 0; + + if (n & (n-1)) + log2++; + if (n >> 16) + log2 += 16, n >>= 16; + if (n >> 8) + log2 += 8, n >>= 8; + if (n >> 4) + log2 += 4, n >>= 4; + if (n >> 2) + log2 += 2, n >>= 2; + if (n >> 1) + log2++; + return log2; +} + +/* + * Conceivably this could actually be used, but there is lots of code out + * there with ands and shifts in it that assumes a byte is exactly 8 bits, + * so forget about porting THIS code to all those non 8 bit byte machines. + */ +static void BitsPerByte(void) +{ + bpb = 8; +} + +static int StackGrowthDirection(int *dummy1addr) +{ + int dummy2; + + return (&dummy2 < dummy1addr) ? -1 : 1; +} + +int main(int argc, char **argv) +{ + int sizeof_char, sizeof_short, sizeof_int, sizeof_int64, sizeof_long, + sizeof_float, sizeof_double, sizeof_word, sizeof_dword; + int bits_per_int64_log2, align_of_short, align_of_int, align_of_long, + align_of_int64, align_of_float, align_of_double, align_of_pointer, + align_of_word; + int dummy1; + + BitsPerByte(); + + printf("#ifndef js_cpucfg___\n"); + printf("#define js_cpucfg___\n\n"); + + printf("/* AUTOMATICALLY GENERATED - DO NOT EDIT */\n\n"); + +#ifdef CROSS_COMPILE +#if defined(IS_LITTLE_ENDIAN) + printf("#define IS_LITTLE_ENDIAN 1\n"); + printf("#undef IS_BIG_ENDIAN\n\n"); +#elif defined(IS_BIG_ENDIAN) + printf("#undef IS_LITTLE_ENDIAN\n"); + printf("#define IS_BIG_ENDIAN 1\n\n"); +#else +#error "Endianess not defined." +#endif + + sizeof_char = PR_BYTES_PER_BYTE; + sizeof_short = PR_BYTES_PER_SHORT; + sizeof_int = PR_BYTES_PER_INT; + sizeof_int64 = PR_BYTES_PER_INT64; + sizeof_long = PR_BYTES_PER_LONG; + sizeof_float = PR_BYTES_PER_FLOAT; + sizeof_double = PR_BYTES_PER_DOUBLE; + sizeof_word = PR_BYTES_PER_WORD; + sizeof_dword = PR_BYTES_PER_DWORD; + + bits_per_int64_log2 = PR_BITS_PER_INT64_LOG2; + + align_of_short = PR_ALIGN_OF_SHORT; + align_of_int = PR_ALIGN_OF_INT; + align_of_long = PR_ALIGN_OF_LONG; + align_of_int64 = PR_ALIGN_OF_INT64; + align_of_float = PR_ALIGN_OF_FLOAT; + align_of_double = PR_ALIGN_OF_DOUBLE; + align_of_pointer = PR_ALIGN_OF_POINTER; + align_of_word = PR_ALIGN_OF_WORD; + +#else /* !CROSS_COMPILE */ + + /* + * We don't handle PDP-endian or similar orders: if a short is big-endian, + * so must int and long be big-endian for us to generate the IS_BIG_ENDIAN + * #define and the IS_LITTLE_ENDIAN #undef. + */ + { + int big_endian = 0, little_endian = 0, ntests = 0; + + if (sizeof(short) == 2) { + /* force |volatile| here to get rid of any compiler optimisations + * (var in register etc.) which may be appiled to |auto| vars - + * even those in |union|s... + * (|static| is used to get the same functionality for compilers + * which do not honor |volatile|...). + */ + volatile static union { + short i; + char c[2]; + } u; + + u.i = 0x0102; + big_endian += (u.c[0] == 0x01 && u.c[1] == 0x02); + little_endian += (u.c[0] == 0x02 && u.c[1] == 0x01); + ntests++; + } + + if (sizeof(int) == 4) { + /* force |volatile| here ... */ + volatile static union { + int i; + char c[4]; + } u; + + u.i = 0x01020304; + big_endian += (u.c[0] == 0x01 && u.c[1] == 0x02 && + u.c[2] == 0x03 && u.c[3] == 0x04); + little_endian += (u.c[0] == 0x04 && u.c[1] == 0x03 && + u.c[2] == 0x02 && u.c[3] == 0x01); + ntests++; + } + + if (sizeof(long) == 8) { + /* force |volatile| here ... */ + volatile static union { + long i; + char c[8]; + } u; + + /* + * Write this as portably as possible: avoid 0x0102030405060708L + * and <<= 32. + */ + u.i = 0x01020304; + u.i <<= 16, u.i <<= 16; + u.i |= 0x05060708; + big_endian += (u.c[0] == 0x01 && u.c[1] == 0x02 && + u.c[2] == 0x03 && u.c[3] == 0x04 && + u.c[4] == 0x05 && u.c[5] == 0x06 && + u.c[6] == 0x07 && u.c[7] == 0x08); + little_endian += (u.c[0] == 0x08 && u.c[1] == 0x07 && + u.c[2] == 0x06 && u.c[3] == 0x05 && + u.c[4] == 0x04 && u.c[5] == 0x03 && + u.c[6] == 0x02 && u.c[7] == 0x01); + ntests++; + } + + if (big_endian && big_endian == ntests) { + printf("#undef IS_LITTLE_ENDIAN\n"); + printf("#define IS_BIG_ENDIAN 1\n\n"); + } else if (little_endian && little_endian == ntests) { + printf("#define IS_LITTLE_ENDIAN 1\n"); + printf("#undef IS_BIG_ENDIAN\n\n"); + } else { + fprintf(stderr, "%s: unknown byte order" + "(big_endian=%d, little_endian=%d, ntests=%d)!\n", + argv[0], big_endian, little_endian, ntests); + return EXIT_FAILURE; + } + } + + sizeof_char = sizeof(char); + sizeof_short = sizeof(short); + sizeof_int = sizeof(int); + sizeof_int64 = 8; + sizeof_long = sizeof(long); + sizeof_float = sizeof(float); + sizeof_double = sizeof(double); + sizeof_word = sizeof(prword); + sizeof_dword = 8; + + bits_per_int64_log2 = 6; + + align_of_short = ALIGN_OF(short); + align_of_int = ALIGN_OF(int); + align_of_long = ALIGN_OF(long); + if (sizeof(INT64) < 8) { + /* this machine doesn't actually support int64's */ + align_of_int64 = ALIGN_OF(fakelonglong); + } else { + align_of_int64 = ALIGN_OF(int64); + } + align_of_float = ALIGN_OF(float); + align_of_double = ALIGN_OF(double); + align_of_pointer = ALIGN_OF(pointer); + align_of_word = ALIGN_OF(prword); + +#endif /* CROSS_COMPILE */ + + printf("#define JS_BYTES_PER_BYTE %dL\n", sizeof_char); + printf("#define JS_BYTES_PER_SHORT %dL\n", sizeof_short); + printf("#define JS_BYTES_PER_INT %dL\n", sizeof_int); + printf("#define JS_BYTES_PER_INT64 %dL\n", sizeof_int64); + printf("#define JS_BYTES_PER_LONG %dL\n", sizeof_long); + printf("#define JS_BYTES_PER_FLOAT %dL\n", sizeof_float); + printf("#define JS_BYTES_PER_DOUBLE %dL\n", sizeof_double); + printf("#define JS_BYTES_PER_WORD %dL\n", sizeof_word); + printf("#define JS_BYTES_PER_DWORD %dL\n", sizeof_dword); + printf("\n"); + + printf("#define JS_BITS_PER_BYTE %dL\n", bpb); + printf("#define JS_BITS_PER_SHORT %dL\n", bpb * sizeof_short); + printf("#define JS_BITS_PER_INT %dL\n", bpb * sizeof_int); + printf("#define JS_BITS_PER_INT64 %dL\n", bpb * sizeof_int64); + printf("#define JS_BITS_PER_LONG %dL\n", bpb * sizeof_long); + printf("#define JS_BITS_PER_FLOAT %dL\n", bpb * sizeof_float); + printf("#define JS_BITS_PER_DOUBLE %dL\n", bpb * sizeof_double); + printf("#define JS_BITS_PER_WORD %dL\n", bpb * sizeof_word); + printf("\n"); + + printf("#define JS_BITS_PER_BYTE_LOG2 %dL\n", Log2(bpb)); + printf("#define JS_BITS_PER_SHORT_LOG2 %dL\n", Log2(bpb * sizeof_short)); + printf("#define JS_BITS_PER_INT_LOG2 %dL\n", Log2(bpb * sizeof_int)); + printf("#define JS_BITS_PER_INT64_LOG2 %dL\n", bits_per_int64_log2); + printf("#define JS_BITS_PER_LONG_LOG2 %dL\n", Log2(bpb * sizeof_long)); + printf("#define JS_BITS_PER_FLOAT_LOG2 %dL\n", Log2(bpb * sizeof_float)); + printf("#define JS_BITS_PER_DOUBLE_LOG2 %dL\n", Log2(bpb * sizeof_double)); + printf("#define JS_BITS_PER_WORD_LOG2 %dL\n", Log2(bpb * sizeof_word)); + printf("\n"); + + printf("#define JS_ALIGN_OF_SHORT %dL\n", align_of_short); + printf("#define JS_ALIGN_OF_INT %dL\n", align_of_int); + printf("#define JS_ALIGN_OF_LONG %dL\n", align_of_long); + printf("#define JS_ALIGN_OF_INT64 %dL\n", align_of_int64); + printf("#define JS_ALIGN_OF_FLOAT %dL\n", align_of_float); + printf("#define JS_ALIGN_OF_DOUBLE %dL\n", align_of_double); + printf("#define JS_ALIGN_OF_POINTER %dL\n", align_of_pointer); + printf("#define JS_ALIGN_OF_WORD %dL\n", align_of_word); + printf("\n"); + + printf("#define JS_BYTES_PER_WORD_LOG2 %dL\n", Log2(sizeof_word)); + printf("#define JS_BYTES_PER_DWORD_LOG2 %dL\n", Log2(sizeof_dword)); + printf("#define JS_WORDS_PER_DWORD_LOG2 %dL\n", Log2(sizeof_dword/sizeof_word)); + printf("\n"); + + printf("#define JS_STACK_GROWTH_DIRECTION (%d)\n", StackGrowthDirection(&dummy1)); + printf("\n"); + + printf("#endif /* js_cpucfg___ */\n"); + + return EXIT_SUCCESS; +} + diff --git a/src/dom/js/jscpucfg.h b/src/dom/js/jscpucfg.h new file mode 100644 index 000000000..e93f5531d --- /dev/null +++ b/src/dom/js/jscpucfg.h @@ -0,0 +1,200 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef js_cpucfg___ +#define js_cpucfg___ + +#include "jsosdep.h" + +#ifdef XP_MAC +#undef IS_LITTLE_ENDIAN +#define IS_BIG_ENDIAN 1 + +#define JS_BYTES_PER_BYTE 1L +#define JS_BYTES_PER_SHORT 2L +#define JS_BYTES_PER_INT 4L +#define JS_BYTES_PER_INT64 8L +#define JS_BYTES_PER_LONG 4L +#define JS_BYTES_PER_FLOAT 4L +#define JS_BYTES_PER_DOUBLE 8L +#define JS_BYTES_PER_WORD 4L +#define JS_BYTES_PER_DWORD 8L + +#define JS_BITS_PER_BYTE 8L +#define JS_BITS_PER_SHORT 16L +#define JS_BITS_PER_INT 32L +#define JS_BITS_PER_INT64 64L +#define JS_BITS_PER_LONG 32L +#define JS_BITS_PER_FLOAT 32L +#define JS_BITS_PER_DOUBLE 64L +#define JS_BITS_PER_WORD 32L + +#define JS_BITS_PER_BYTE_LOG2 3L +#define JS_BITS_PER_SHORT_LOG2 4L +#define JS_BITS_PER_INT_LOG2 5L +#define JS_BITS_PER_INT64_LOG2 6L +#define JS_BITS_PER_LONG_LOG2 5L +#define JS_BITS_PER_FLOAT_LOG2 5L +#define JS_BITS_PER_DOUBLE_LOG2 6L +#define JS_BITS_PER_WORD_LOG2 5L + +#define JS_ALIGN_OF_SHORT 2L +#define JS_ALIGN_OF_INT 4L +#define JS_ALIGN_OF_LONG 4L +#define JS_ALIGN_OF_INT64 2L +#define JS_ALIGN_OF_FLOAT 4L +#define JS_ALIGN_OF_DOUBLE 4L +#define JS_ALIGN_OF_POINTER 4L +#define JS_ALIGN_OF_WORD 4L + +#define JS_BYTES_PER_WORD_LOG2 2L +#define JS_BYTES_PER_DWORD_LOG2 3L +#define PR_WORDS_PER_DWORD_LOG2 1L + +#elif defined(XP_WIN) || defined(XP_OS2) + +#if defined( _WIN32) || defined(XP_OS2) +#define IS_LITTLE_ENDIAN 1 +#undef IS_BIG_ENDIAN + +#define JS_BYTES_PER_BYTE 1L +#define JS_BYTES_PER_SHORT 2L +#define JS_BYTES_PER_INT 4L +#define JS_BYTES_PER_INT64 8L +#define JS_BYTES_PER_LONG 4L +#define JS_BYTES_PER_FLOAT 4L +#define JS_BYTES_PER_DOUBLE 8L +#define JS_BYTES_PER_WORD 4L +#define JS_BYTES_PER_DWORD 8L + +#define JS_BITS_PER_BYTE 8L +#define JS_BITS_PER_SHORT 16L +#define JS_BITS_PER_INT 32L +#define JS_BITS_PER_INT64 64L +#define JS_BITS_PER_LONG 32L +#define JS_BITS_PER_FLOAT 32L +#define JS_BITS_PER_DOUBLE 64L +#define JS_BITS_PER_WORD 32L + +#define JS_BITS_PER_BYTE_LOG2 3L +#define JS_BITS_PER_SHORT_LOG2 4L +#define JS_BITS_PER_INT_LOG2 5L +#define JS_BITS_PER_INT64_LOG2 6L +#define JS_BITS_PER_LONG_LOG2 5L +#define JS_BITS_PER_FLOAT_LOG2 5L +#define JS_BITS_PER_DOUBLE_LOG2 6L +#define JS_BITS_PER_WORD_LOG2 5L + +#define JS_ALIGN_OF_SHORT 2L +#define JS_ALIGN_OF_INT 4L +#define JS_ALIGN_OF_LONG 4L +#define JS_ALIGN_OF_INT64 8L +#define JS_ALIGN_OF_FLOAT 4L +#define JS_ALIGN_OF_DOUBLE 4L +#define JS_ALIGN_OF_POINTER 4L +#define JS_ALIGN_OF_WORD 4L + +#define JS_BYTES_PER_WORD_LOG2 2L +#define JS_BYTES_PER_DWORD_LOG2 3L +#define PR_WORDS_PER_DWORD_LOG2 1L +#endif /* _WIN32 || XP_OS2 */ + +#if defined(_WINDOWS) && !defined(_WIN32) /* WIN16 */ +#define IS_LITTLE_ENDIAN 1 +#undef IS_BIG_ENDIAN + +#define JS_BYTES_PER_BYTE 1L +#define JS_BYTES_PER_SHORT 2L +#define JS_BYTES_PER_INT 2L +#define JS_BYTES_PER_INT64 8L +#define JS_BYTES_PER_LONG 4L +#define JS_BYTES_PER_FLOAT 4L +#define JS_BYTES_PER_DOUBLE 8L +#define JS_BYTES_PER_WORD 4L +#define JS_BYTES_PER_DWORD 8L + +#define JS_BITS_PER_BYTE 8L +#define JS_BITS_PER_SHORT 16L +#define JS_BITS_PER_INT 16L +#define JS_BITS_PER_INT64 64L +#define JS_BITS_PER_LONG 32L +#define JS_BITS_PER_FLOAT 32L +#define JS_BITS_PER_DOUBLE 64L +#define JS_BITS_PER_WORD 32L + +#define JS_BITS_PER_BYTE_LOG2 3L +#define JS_BITS_PER_SHORT_LOG2 4L +#define JS_BITS_PER_INT_LOG2 4L +#define JS_BITS_PER_INT64_LOG2 6L +#define JS_BITS_PER_LONG_LOG2 5L +#define JS_BITS_PER_FLOAT_LOG2 5L +#define JS_BITS_PER_DOUBLE_LOG2 6L +#define JS_BITS_PER_WORD_LOG2 5L + +#define JS_ALIGN_OF_SHORT 2L +#define JS_ALIGN_OF_INT 2L +#define JS_ALIGN_OF_LONG 2L +#define JS_ALIGN_OF_INT64 2L +#define JS_ALIGN_OF_FLOAT 2L +#define JS_ALIGN_OF_DOUBLE 2L +#define JS_ALIGN_OF_POINTER 2L +#define JS_ALIGN_OF_WORD 2L + +#define JS_BYTES_PER_WORD_LOG2 2L +#define JS_BYTES_PER_DWORD_LOG2 3L +#define PR_WORDS_PER_DWORD_LOG2 1L +#endif /* defined(_WINDOWS) && !defined(_WIN32) */ + +#elif defined(XP_UNIX) || defined(XP_BEOS) + +#error "This file is supposed to be auto-generated on UNIX platforms, but the" +#error "static version for Mac and Windows platforms is being used." +#error "Something's probably wrong with paths/headers/dependencies/Makefiles." + +#else + +#error "Must define one of XP_BEOS, XP_MAC, XP_OS2, XP_WIN, or XP_UNIX" + +#endif + +#ifndef JS_STACK_GROWTH_DIRECTION +#define JS_STACK_GROWTH_DIRECTION (-1) +#endif + +#endif /* js_cpucfg___ */ diff --git a/src/dom/js/jsdate.c b/src/dom/js/jsdate.c new file mode 100644 index 000000000..a88df1830 --- /dev/null +++ b/src/dom/js/jsdate.c @@ -0,0 +1,2234 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* + * JS date methods. + */ + +/* + * "For example, OS/360 devotes 26 bytes of the permanently + * resident date-turnover routine to the proper handling of + * December 31 on leap years (when it is Day 366). That + * might have been left to the operator." + * + * Frederick Brooks, 'The Second-System Effect'. + */ + +#include "jsstddef.h" +#include +#include +#include +#include +#include "jstypes.h" +#include "jsprf.h" +#include "prmjtime.h" +#include "jsutil.h" /* Added by JSIFY */ +#include "jsapi.h" +#include "jsconfig.h" +#include "jscntxt.h" +#include "jsdate.h" +#include "jsinterp.h" +#include "jsnum.h" +#include "jsobj.h" +#include "jsstr.h" + +/* + * The JS 'Date' object is patterned after the Java 'Date' object. + * Here is an script: + * + * today = new Date(); + * + * print(today.toLocaleString()); + * + * weekDay = today.getDay(); + * + * + * These Java (and ECMA-262) methods are supported: + * + * UTC + * getDate (getUTCDate) + * getDay (getUTCDay) + * getHours (getUTCHours) + * getMinutes (getUTCMinutes) + * getMonth (getUTCMonth) + * getSeconds (getUTCSeconds) + * getMilliseconds (getUTCMilliseconds) + * getTime + * getTimezoneOffset + * getYear + * getFullYear (getUTCFullYear) + * parse + * setDate (setUTCDate) + * setHours (setUTCHours) + * setMinutes (setUTCMinutes) + * setMonth (setUTCMonth) + * setSeconds (setUTCSeconds) + * setMilliseconds (setUTCMilliseconds) + * setTime + * setYear (setFullYear, setUTCFullYear) + * toGMTString (toUTCString) + * toLocaleString + * toString + * + * + * These Java methods are not supported + * + * setDay + * before + * after + * equals + * hashCode + */ + +/* + * 11/97 - jsdate.c has been rewritten to conform to the ECMA-262 language + * definition and reduce dependence on NSPR. NSPR is used to get the current + * time in milliseconds, the time zone offset, and the daylight savings time + * offset for a given time. NSPR is also used for Date.toLocaleString(), for + * locale-specific formatting, and to get a string representing the timezone. + * (Which turns out to be platform-dependent.) + * + * To do: + * (I did some performance tests by timing how long it took to run what + * I had of the js ECMA conformance tests.) + * + * - look at saving results across multiple calls to supporting + * functions; the toString functions compute some of the same values + * multiple times. Although - I took a quick stab at this, and I lost + * rather than gained. (Fractionally.) Hard to tell what compilers/processors + * are doing these days. + * + * - look at tweaking function return types to return double instead + * of int; this seems to make things run slightly faster sometimes. + * (though it could be architecture-dependent.) It'd be good to see + * how this does on win32. (Tried it on irix.) Types could use a + * general going-over. + */ + +/* + * Supporting functions - ECMA 15.9.1.* + */ + +#define HalfTimeDomain 8.64e15 +#define HoursPerDay 24.0 +#define MinutesPerDay (HoursPerDay * MinutesPerHour) +#define MinutesPerHour 60.0 +#define SecondsPerDay (MinutesPerDay * SecondsPerMinute) +#define SecondsPerHour (MinutesPerHour * SecondsPerMinute) +#define SecondsPerMinute 60.0 + +#if defined(XP_WIN) || defined(XP_OS2) +/* Work around msvc double optimization bug by making these runtime values; if + * they're available at compile time, msvc optimizes division by them by + * computing the reciprocal and multiplying instead of dividing - this loses + * when the reciprocal isn't representable in a double. + */ +static jsdouble msPerSecond = 1000.0; +static jsdouble msPerDay = SecondsPerDay * 1000.0; +static jsdouble msPerHour = SecondsPerHour * 1000.0; +static jsdouble msPerMinute = SecondsPerMinute * 1000.0; +#else +#define msPerDay (SecondsPerDay * msPerSecond) +#define msPerHour (SecondsPerHour * msPerSecond) +#define msPerMinute (SecondsPerMinute * msPerSecond) +#define msPerSecond 1000.0 +#endif + +#define Day(t) floor((t) / msPerDay) + +static jsdouble +TimeWithinDay(jsdouble t) +{ + jsdouble result; + result = fmod(t, msPerDay); + if (result < 0) + result += msPerDay; + return result; +} + +#define DaysInYear(y) ((y) % 4 == 0 && ((y) % 100 || ((y) % 400 == 0)) \ + ? 366 : 365) + +/* math here has to be f.p, because we need + * floor((1968 - 1969) / 4) == -1 + */ +#define DayFromYear(y) (365 * ((y)-1970) + floor(((y)-1969)/4.0) \ + - floor(((y)-1901)/100.0) + floor(((y)-1601)/400.0)) +#define TimeFromYear(y) (DayFromYear(y) * msPerDay) + +static jsint +YearFromTime(jsdouble t) +{ + jsint y = (jsint) floor(t /(msPerDay*365.2425)) + 1970; + jsdouble t2 = (jsdouble) TimeFromYear(y); + + if (t2 > t) { + y--; + } else { + if (t2 + msPerDay * DaysInYear(y) <= t) + y++; + } + return y; +} + +#define InLeapYear(t) (JSBool) (DaysInYear(YearFromTime(t)) == 366) + +#define DayWithinYear(t, year) ((intN) (Day(t) - DayFromYear(year))) + +/* + * The following array contains the day of year for the first day of + * each month, where index 0 is January, and day 0 is January 1. + */ +static jsdouble firstDayOfMonth[2][12] = { + {0.0, 31.0, 59.0, 90.0, 120.0, 151.0, 181.0, 212.0, 243.0, 273.0, 304.0, 334.0}, + {0.0, 31.0, 60.0, 91.0, 121.0, 152.0, 182.0, 213.0, 244.0, 274.0, 305.0, 335.0} +}; + +#define DayFromMonth(m, leap) firstDayOfMonth[leap][(intN)m]; + +static intN +MonthFromTime(jsdouble t) +{ + intN d, step; + jsint year = YearFromTime(t); + d = DayWithinYear(t, year); + + if (d < (step = 31)) + return 0; + step += (InLeapYear(t) ? 29 : 28); + if (d < step) + return 1; + if (d < (step += 31)) + return 2; + if (d < (step += 30)) + return 3; + if (d < (step += 31)) + return 4; + if (d < (step += 30)) + return 5; + if (d < (step += 31)) + return 6; + if (d < (step += 31)) + return 7; + if (d < (step += 30)) + return 8; + if (d < (step += 31)) + return 9; + if (d < (step += 30)) + return 10; + return 11; +} + +static intN +DateFromTime(jsdouble t) +{ + intN d, step, next; + jsint year = YearFromTime(t); + d = DayWithinYear(t, year); + + if (d <= (next = 30)) + return d + 1; + step = next; + next += (InLeapYear(t) ? 29 : 28); + if (d <= next) + return d - step; + step = next; + if (d <= (next += 31)) + return d - step; + step = next; + if (d <= (next += 30)) + return d - step; + step = next; + if (d <= (next += 31)) + return d - step; + step = next; + if (d <= (next += 30)) + return d - step; + step = next; + if (d <= (next += 31)) + return d - step; + step = next; + if (d <= (next += 31)) + return d - step; + step = next; + if (d <= (next += 30)) + return d - step; + step = next; + if (d <= (next += 31)) + return d - step; + step = next; + if (d <= (next += 30)) + return d - step; + step = next; + return d - step; +} + +static intN +WeekDay(jsdouble t) +{ + jsint result; + result = (jsint) Day(t) + 4; + result = result % 7; + if (result < 0) + result += 7; + return (intN) result; +} + +/* LocalTZA gets set by js_InitDateClass() */ +static jsdouble LocalTZA; + +static jsdouble +DaylightSavingTA(jsdouble t) +{ + volatile int64 PR_t; + int64 ms2us; + int64 offset; + jsdouble result; + + /* abort if NaN */ + if (JSDOUBLE_IS_NaN(t)) + return t; + + /* put our t in an LL, and map it to usec for prtime */ + JSLL_D2L(PR_t, t); + JSLL_I2L(ms2us, PRMJ_USEC_PER_MSEC); + JSLL_MUL(PR_t, PR_t, ms2us); + + offset = PRMJ_DSTOffset(PR_t); + + JSLL_DIV(offset, offset, ms2us); + JSLL_L2D(result, offset); + return result; +} + + +#define AdjustTime(t) fmod(LocalTZA + DaylightSavingTA(t), msPerDay) + +#define LocalTime(t) ((t) + AdjustTime(t)) + +static jsdouble +UTC(jsdouble t) +{ + return t - AdjustTime(t - LocalTZA); +} + +static intN +HourFromTime(jsdouble t) +{ + intN result = (intN) fmod(floor(t/msPerHour), HoursPerDay); + if (result < 0) + result += (intN)HoursPerDay; + return result; +} + +static intN +MinFromTime(jsdouble t) +{ + intN result = (intN) fmod(floor(t / msPerMinute), MinutesPerHour); + if (result < 0) + result += (intN)MinutesPerHour; + return result; +} + +static intN +SecFromTime(jsdouble t) +{ + intN result = (intN) fmod(floor(t / msPerSecond), SecondsPerMinute); + if (result < 0) + result += (intN)SecondsPerMinute; + return result; +} + +static intN +msFromTime(jsdouble t) +{ + intN result = (intN) fmod(t, msPerSecond); + if (result < 0) + result += (intN)msPerSecond; + return result; +} + +#define MakeTime(hour, min, sec, ms) \ +(((hour * MinutesPerHour + min) * SecondsPerMinute + sec) * msPerSecond + ms) + +static jsdouble +MakeDay(jsdouble year, jsdouble month, jsdouble date) +{ + jsdouble result; + JSBool leap; + jsdouble yearday; + jsdouble monthday; + + year += floor(month / 12); + + month = fmod(month, 12.0); + if (month < 0) + month += 12; + + leap = (DaysInYear((jsint) year) == 366); + + yearday = floor(TimeFromYear(year) / msPerDay); + monthday = DayFromMonth(month, leap); + + result = yearday + + monthday + + date - 1; + return result; +} + +#define MakeDate(day, time) (day * msPerDay + time) + +#define TIMECLIP(d) ((JSDOUBLE_IS_FINITE(d) \ + && !((d < 0 ? -d : d) > HalfTimeDomain)) \ + ? js_DoubleToInteger(d + (+0.)) : *cx->runtime->jsNaN) + +/** + * end of ECMA 'support' functions + */ + +/* + * Other Support routines and definitions + */ + +static JSClass date_class = { + js_Date_str, + JSCLASS_HAS_PRIVATE, + JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, + JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub, + JSCLASS_NO_OPTIONAL_MEMBERS +}; + +/* for use by date_parse */ + +static const char* wtb[] = { + "am", "pm", + "monday", "tuesday", "wednesday", "thursday", "friday", + "saturday", "sunday", + "january", "february", "march", "april", "may", "june", + "july", "august", "september", "october", "november", "december", + "gmt", "ut", "utc", + "est", "edt", + "cst", "cdt", + "mst", "mdt", + "pst", "pdt" + /* time zone table needs to be expanded */ +}; + +static int ttb[] = { + -1, -2, 0, 0, 0, 0, 0, 0, 0, /* AM/PM */ + 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, + 10000 + 0, 10000 + 0, 10000 + 0, /* GMT/UT/UTC */ + 10000 + 5 * 60, 10000 + 4 * 60, /* EST/EDT */ + 10000 + 6 * 60, 10000 + 5 * 60, /* CST/CDT */ + 10000 + 7 * 60, 10000 + 6 * 60, /* MST/MDT */ + 10000 + 8 * 60, 10000 + 7 * 60 /* PST/PDT */ +}; + +/* helper for date_parse */ +static JSBool +date_regionMatches(const char* s1, int s1off, const jschar* s2, int s2off, + int count, int ignoreCase) +{ + JSBool result = JS_FALSE; + /* return true if matches, otherwise, false */ + + while (count > 0 && s1[s1off] && s2[s2off]) { + if (ignoreCase) { + if (JS_TOLOWER((jschar)s1[s1off]) != JS_TOLOWER(s2[s2off])) { + break; + } + } else { + if ((jschar)s1[s1off] != s2[s2off]) { + break; + } + } + s1off++; + s2off++; + count--; + } + + if (count == 0) { + result = JS_TRUE; + } + + return result; +} + +/* find UTC time from given date... no 1900 correction! */ +static jsdouble +date_msecFromDate(jsdouble year, jsdouble mon, jsdouble mday, jsdouble hour, + jsdouble min, jsdouble sec, jsdouble msec) +{ + jsdouble day; + jsdouble msec_time; + jsdouble result; + + day = MakeDay(year, mon, mday); + msec_time = MakeTime(hour, min, sec, msec); + result = MakeDate(day, msec_time); + return result; +} + +/* + * See ECMA 15.9.4.[3-10]; + */ +/* XXX this function must be above date_parseString to avoid a + horrid bug in the Win16 1.52 compiler */ +#define MAXARGS 7 +static JSBool +date_UTC(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + jsdouble array[MAXARGS]; + uintN loop; + jsdouble d; + + for (loop = 0; loop < MAXARGS; loop++) { + if (loop < argc) { + if (!js_ValueToNumber(cx, argv[loop], &d)) + return JS_FALSE; + /* return NaN if any arg is NaN */ + if (!JSDOUBLE_IS_FINITE(d)) { + return js_NewNumberValue(cx, d, rval); + } + array[loop] = floor(d); + } else { + array[loop] = 0; + } + } + + /* adjust 2-digit years into the 20th century */ + if (array[0] >= 0 && array[0] <= 99) + array[0] += 1900; + + /* if we got a 0 for 'date' (which is out of range) + * pretend it's a 1. (So Date.UTC(1972, 5) works) */ + if (array[2] < 1) + array[2] = 1; + + d = date_msecFromDate(array[0], array[1], array[2], + array[3], array[4], array[5], array[6]); + d = TIMECLIP(d); + + return js_NewNumberValue(cx, d, rval); +} + +static JSBool +date_parseString(JSString *str, jsdouble *result) +{ + jsdouble msec; + + const jschar *s = JSSTRING_CHARS(str); + size_t limit = JSSTRING_LENGTH(str); + size_t i = 0; + int year = -1; + int mon = -1; + int mday = -1; + int hour = -1; + int min = -1; + int sec = -1; + int c = -1; + int n = -1; + jsdouble tzoffset = -1; /* was an int, overflowed on win16!!! */ + int prevc = 0; + JSBool seenplusminus = JS_FALSE; + + if (limit == 0) + goto syntax; + while (i < limit) { + c = s[i]; + i++; + if (c <= ' ' || c == ',' || c == '-') { + if (c == '-' && '0' <= s[i] && s[i] <= '9') { + prevc = c; + } + continue; + } + if (c == '(') { /* comments) */ + int depth = 1; + while (i < limit) { + c = s[i]; + i++; + if (c == '(') depth++; + else if (c == ')') + if (--depth <= 0) + break; + } + continue; + } + if ('0' <= c && c <= '9') { + n = c - '0'; + while (i < limit && '0' <= (c = s[i]) && c <= '9') { + n = n * 10 + c - '0'; + i++; + } + + /* allow TZA before the year, so + * 'Wed Nov 05 21:49:11 GMT-0800 1997' + * works */ + + /* uses of seenplusminus allow : in TZA, so Java + * no-timezone style of GMT+4:30 works + */ + + if ((prevc == '+' || prevc == '-')/* && year>=0 */) { + /* make ':' case below change tzoffset */ + seenplusminus = JS_TRUE; + + /* offset */ + if (n < 24) + n = n * 60; /* EG. "GMT-3" */ + else + n = n % 100 + n / 100 * 60; /* eg "GMT-0430" */ + if (prevc == '+') /* plus means east of GMT */ + n = -n; + if (tzoffset != 0 && tzoffset != -1) + goto syntax; + tzoffset = n; + } else if (n >= 70 || + (prevc == '/' && mon >= 0 && mday >= 0 && year < 0)) { + if (year >= 0) + goto syntax; + else if (c <= ' ' || c == ',' || c == '/' || i >= limit) + year = n < 100 ? n + 1900 : n; + else + goto syntax; + } else if (c == ':') { + if (hour < 0) + hour = /*byte*/ n; + else if (min < 0) + min = /*byte*/ n; + else + goto syntax; + } else if (c == '/') { + if (mon < 0) + mon = /*byte*/ n-1; + else if (mday < 0) + mday = /*byte*/ n; + else + goto syntax; + } else if (i < limit && c != ',' && c > ' ' && c != '-') { + goto syntax; + } else if (seenplusminus && n < 60) { /* handle GMT-3:30 */ + if (tzoffset < 0) + tzoffset -= n; + else + tzoffset += n; + } else if (hour >= 0 && min < 0) { + min = /*byte*/ n; + } else if (min >= 0 && sec < 0) { + sec = /*byte*/ n; + } else if (mday < 0) { + mday = /*byte*/ n; + } else { + goto syntax; + } + prevc = 0; + } else if (c == '/' || c == ':' || c == '+' || c == '-') { + prevc = c; + } else { + size_t st = i - 1; + int k; + while (i < limit) { + c = s[i]; + if (!(('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z'))) + break; + i++; + } + if (i <= st + 1) + goto syntax; + for (k = (sizeof(wtb)/sizeof(char*)); --k >= 0;) + if (date_regionMatches(wtb[k], 0, s, st, i-st, 1)) { + int action = ttb[k]; + if (action != 0) { + if (action < 0) { + /* + * AM/PM. Count 12:30 AM as 00:30, 12:30 PM as + * 12:30, instead of blindly adding 12 if PM. + */ + JS_ASSERT(action == -1 || action == -2); + if (hour > 12 || hour < 0) { + goto syntax; + } else { + if (action == -1 && hour == 12) { /* am */ + hour = 0; + } else if (action == -2 && hour != 12) { /* pm */ + hour += 12; + } + } + } else if (action <= 13) { /* month! */ + if (mon < 0) { + mon = /*byte*/ (action - 2); + } else { + goto syntax; + } + } else { + tzoffset = action - 10000; + } + } + break; + } + if (k < 0) + goto syntax; + prevc = 0; + } + } + if (year < 0 || mon < 0 || mday < 0) + goto syntax; + if (sec < 0) + sec = 0; + if (min < 0) + min = 0; + if (hour < 0) + hour = 0; + if (tzoffset == -1) { /* no time zone specified, have to use local */ + jsdouble msec_time; + msec_time = date_msecFromDate(year, mon, mday, hour, min, sec, 0); + + *result = UTC(msec_time); + return JS_TRUE; + } + + msec = date_msecFromDate(year, mon, mday, hour, min, sec, 0); + msec += tzoffset * msPerMinute; + *result = msec; + return JS_TRUE; + +syntax: + /* syntax error */ + *result = 0; + return JS_FALSE; +} + +static JSBool +date_parse(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + JSString *str; + jsdouble result; + + str = js_ValueToString(cx, argv[0]); + if (!str) + return JS_FALSE; + if (!date_parseString(str, &result)) { + *rval = DOUBLE_TO_JSVAL(cx->runtime->jsNaN); + return JS_TRUE; + } + + result = TIMECLIP(result); + return js_NewNumberValue(cx, result, rval); +} + +static JSBool +date_now(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + int64 us, ms, us2ms; + jsdouble msec_time; + + us = PRMJ_Now(); + JSLL_UI2L(us2ms, PRMJ_USEC_PER_MSEC); + JSLL_DIV(ms, us, us2ms); + JSLL_L2D(msec_time, ms); + + return js_NewDoubleValue(cx, msec_time, rval); +} + +/* + * Check that obj is an object of class Date, and get the date value. + * Return NULL on failure. + */ +static jsdouble * +date_getProlog(JSContext *cx, JSObject *obj, jsval *argv) +{ + if (!JS_InstanceOf(cx, obj, &date_class, argv)) + return NULL; + return JSVAL_TO_DOUBLE(OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE)); +} + +/* + * See ECMA 15.9.5.4 thru 15.9.5.23 + */ +static JSBool +date_getTime(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + jsdouble *date = date_getProlog(cx, obj, argv); + if (!date) + return JS_FALSE; + + return js_NewNumberValue(cx, *date, rval); +} + +static JSBool +date_getYear(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + jsdouble result; + jsdouble *date = date_getProlog(cx, obj, argv); + if (!date) + return JS_FALSE; + result = *date; + + if (!JSDOUBLE_IS_FINITE(result)) + return js_NewNumberValue(cx, result, rval); + + result = YearFromTime(LocalTime(result)); + + /* + * During the great date rewrite of 1.3, we tried to track the evolving ECMA + * standard, which then had a definition of getYear which always subtracted + * 1900. Which we implemented, not realizing that it was incompatible with + * the old behavior... now, rather than thrash the behavior yet again, + * we've decided to leave it with the - 1900 behavior and point people to + * the getFullYear method. But we try to protect existing scripts that + * have specified a version... + */ + if (cx->version == JSVERSION_1_0 || + cx->version == JSVERSION_1_1 || + cx->version == JSVERSION_1_2) + { + if (result >= 1900 && result < 2000) + result -= 1900; + } else { + result -= 1900; + } + return js_NewNumberValue(cx, result, rval); +} + +static JSBool +date_getFullYear(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval) +{ + jsdouble result; + jsdouble *date = date_getProlog(cx, obj, argv); + if (!date) + return JS_FALSE; + result = *date; + + if (!JSDOUBLE_IS_FINITE(result)) + return js_NewNumberValue(cx, result, rval); + + result = YearFromTime(LocalTime(result)); + return js_NewNumberValue(cx, result, rval); +} + +static JSBool +date_getUTCFullYear(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval) +{ + jsdouble result; + jsdouble *date = date_getProlog(cx, obj, argv); + if (!date) + return JS_FALSE; + result = *date; + + if (!JSDOUBLE_IS_FINITE(result)) + return js_NewNumberValue(cx, result, rval); + + result = YearFromTime(result); + return js_NewNumberValue(cx, result, rval); +} + +static JSBool +date_getMonth(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval) +{ + jsdouble result; + jsdouble *date = date_getProlog(cx, obj, argv); + if (!date) + return JS_FALSE; + result = *date; + + if (!JSDOUBLE_IS_FINITE(result)) + return js_NewNumberValue(cx, result, rval); + + result = MonthFromTime(LocalTime(result)); + return js_NewNumberValue(cx, result, rval); +} + +static JSBool +date_getUTCMonth(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval) +{ + jsdouble result; + jsdouble *date = date_getProlog(cx, obj, argv); + if (!date) + return JS_FALSE; + result = *date; + + if (!JSDOUBLE_IS_FINITE(result)) + return js_NewNumberValue(cx, result, rval); + + result = MonthFromTime(result); + return js_NewNumberValue(cx, result, rval); +} + +static JSBool +date_getDate(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + jsdouble result; + jsdouble *date = date_getProlog(cx, obj, argv); + if (!date) + return JS_FALSE; + result = *date; + + if (!JSDOUBLE_IS_FINITE(result)) + return js_NewNumberValue(cx, result, rval); + + result = LocalTime(result); + result = DateFromTime(result); + return js_NewNumberValue(cx, result, rval); +} + +static JSBool +date_getUTCDate(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval) +{ + jsdouble result; + jsdouble *date = date_getProlog(cx, obj, argv); + if (!date) + return JS_FALSE; + result = *date; + + if (!JSDOUBLE_IS_FINITE(result)) + return js_NewNumberValue(cx, result, rval); + + result = DateFromTime(result); + return js_NewNumberValue(cx, result, rval); +} + +static JSBool +date_getDay(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + jsdouble result; + jsdouble *date = date_getProlog(cx, obj, argv); + if (!date) + return JS_FALSE; + result = *date; + + if (!JSDOUBLE_IS_FINITE(result)) + return js_NewNumberValue(cx, result, rval); + + result = LocalTime(result); + result = WeekDay(result); + return js_NewNumberValue(cx, result, rval); +} + +static JSBool +date_getUTCDay(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval) +{ + jsdouble result; + jsdouble *date = date_getProlog(cx, obj, argv); + if (!date) + return JS_FALSE; + result = *date; + + if (!JSDOUBLE_IS_FINITE(result)) + return js_NewNumberValue(cx, result, rval); + + result = WeekDay(result); + return js_NewNumberValue(cx, result, rval); +} + +static JSBool +date_getHours(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval) +{ + jsdouble result; + jsdouble *date = date_getProlog(cx, obj, argv); + if (!date) + return JS_FALSE; + result = *date; + + if (!JSDOUBLE_IS_FINITE(result)) + return js_NewNumberValue(cx, result, rval); + + result = HourFromTime(LocalTime(result)); + return js_NewNumberValue(cx, result, rval); +} + +static JSBool +date_getUTCHours(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval) +{ + jsdouble result; + jsdouble *date = date_getProlog(cx, obj, argv); + if (!date) + return JS_FALSE; + result = *date; + + if (!JSDOUBLE_IS_FINITE(result)) + return js_NewNumberValue(cx, result, rval); + + result = HourFromTime(result); + return js_NewNumberValue(cx, result, rval); +} + +static JSBool +date_getMinutes(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval) +{ + jsdouble result; + jsdouble *date = date_getProlog(cx, obj, argv); + if (!date) + return JS_FALSE; + result = *date; + + if (!JSDOUBLE_IS_FINITE(result)) + return js_NewNumberValue(cx, result, rval); + + result = MinFromTime(LocalTime(result)); + return js_NewNumberValue(cx, result, rval); +} + +static JSBool +date_getUTCMinutes(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval) +{ + jsdouble result; + jsdouble *date = date_getProlog(cx, obj, argv); + if (!date) + return JS_FALSE; + result = *date; + + if (!JSDOUBLE_IS_FINITE(result)) + return js_NewNumberValue(cx, result, rval); + + result = MinFromTime(result); + return js_NewNumberValue(cx, result, rval); +} + +/* Date.getSeconds is mapped to getUTCSeconds */ + +static JSBool +date_getUTCSeconds(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval) +{ + jsdouble result; + jsdouble *date = date_getProlog(cx, obj, argv); + if (!date) + return JS_FALSE; + result = *date; + + if (!JSDOUBLE_IS_FINITE(result)) + return js_NewNumberValue(cx, result, rval); + + result = SecFromTime(result); + return js_NewNumberValue(cx, result, rval); +} + +/* Date.getMilliseconds is mapped to getUTCMilliseconds */ + +static JSBool +date_getUTCMilliseconds(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval) +{ + jsdouble result; + jsdouble *date = date_getProlog(cx, obj, argv); + if (!date) + return JS_FALSE; + result = *date; + + if (!JSDOUBLE_IS_FINITE(result)) + return js_NewNumberValue(cx, result, rval); + + result = msFromTime(result); + return js_NewNumberValue(cx, result, rval); +} + +static JSBool +date_getTimezoneOffset(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval) +{ + jsdouble result; + jsdouble *date = date_getProlog(cx, obj, argv); + if (!date) + return JS_FALSE; + result = *date; + + /* + * Return the time zone offset in minutes for the current locale + * that is appropriate for this time. This value would be a + * constant except for daylight savings time. + */ + result = (result - LocalTime(result)) / msPerMinute; + return js_NewNumberValue(cx, result, rval); +} + +static JSBool +date_setTime(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + jsdouble result; + jsdouble *date = date_getProlog(cx, obj, argv); + if (!date) + return JS_FALSE; + + if (!js_ValueToNumber(cx, argv[0], &result)) + return JS_FALSE; + + result = TIMECLIP(result); + + *date = result; + return js_NewNumberValue(cx, result, rval); +} + +static JSBool +date_makeTime(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + uintN maxargs, JSBool local, jsval *rval) +{ + uintN i; + jsdouble args[4], *argp, *stop; + jsdouble hour, min, sec, msec; + jsdouble lorutime; /* Local or UTC version of *date */ + + jsdouble msec_time; + jsdouble result; + + jsdouble *date = date_getProlog(cx, obj, argv); + if (!date) + return JS_FALSE; + + result = *date; + + /* just return NaN if the date is already NaN */ + if (!JSDOUBLE_IS_FINITE(result)) + return js_NewNumberValue(cx, result, rval); + + /* Satisfy the ECMA rule that if a function is called with + * fewer arguments than the specified formal arguments, the + * remaining arguments are set to undefined. Seems like all + * the Date.setWhatever functions in ECMA are only varargs + * beyond the first argument; this should be set to undefined + * if it's not given. This means that "d = new Date(); + * d.setMilliseconds()" returns NaN. Blech. + */ + if (argc == 0) + argc = 1; /* should be safe, because length of all setters is 1 */ + else if (argc > maxargs) + argc = maxargs; /* clamp argc */ + + for (i = 0; i < argc; i++) { + if (!js_ValueToNumber(cx, argv[i], &args[i])) + return JS_FALSE; + if (!JSDOUBLE_IS_FINITE(args[i])) { + *date = *cx->runtime->jsNaN; + return js_NewNumberValue(cx, *date, rval); + } + args[i] = js_DoubleToInteger(args[i]); + } + + if (local) + lorutime = LocalTime(result); + else + lorutime = result; + + argp = args; + stop = argp + argc; + if (maxargs >= 4 && argp < stop) + hour = *argp++; + else + hour = HourFromTime(lorutime); + + if (maxargs >= 3 && argp < stop) + min = *argp++; + else + min = MinFromTime(lorutime); + + if (maxargs >= 2 && argp < stop) + sec = *argp++; + else + sec = SecFromTime(lorutime); + + if (maxargs >= 1 && argp < stop) + msec = *argp; + else + msec = msFromTime(lorutime); + + msec_time = MakeTime(hour, min, sec, msec); + result = MakeDate(Day(lorutime), msec_time); + +/* fprintf(stderr, "%f\n", result); */ + + if (local) + result = UTC(result); + +/* fprintf(stderr, "%f\n", result); */ + + *date = TIMECLIP(result); + return js_NewNumberValue(cx, *date, rval); +} + +static JSBool +date_setMilliseconds(JSContext *cx, JSObject *obj, uintN argc, + jsval *argv, jsval *rval) +{ + return date_makeTime(cx, obj, argc, argv, 1, JS_TRUE, rval); +} + +static JSBool +date_setUTCMilliseconds(JSContext *cx, JSObject *obj, uintN argc, + jsval *argv, jsval *rval) +{ + return date_makeTime(cx, obj, argc, argv, 1, JS_FALSE, rval); +} + +static JSBool +date_setSeconds(JSContext *cx, JSObject *obj, uintN argc, + jsval *argv, jsval *rval) +{ + return date_makeTime(cx, obj, argc, argv, 2, JS_TRUE, rval); +} + +static JSBool +date_setUTCSeconds(JSContext *cx, JSObject *obj, uintN argc, + jsval *argv, jsval *rval) +{ + return date_makeTime(cx, obj, argc, argv, 2, JS_FALSE, rval); +} + +static JSBool +date_setMinutes(JSContext *cx, JSObject *obj, uintN argc, + jsval *argv, jsval *rval) +{ + return date_makeTime(cx, obj, argc, argv, 3, JS_TRUE, rval); +} + +static JSBool +date_setUTCMinutes(JSContext *cx, JSObject *obj, uintN argc, + jsval *argv, jsval *rval) +{ + return date_makeTime(cx, obj, argc, argv, 3, JS_FALSE, rval); +} + +static JSBool +date_setHours(JSContext *cx, JSObject *obj, uintN argc, + jsval *argv, jsval *rval) +{ + return date_makeTime(cx, obj, argc, argv, 4, JS_TRUE, rval); +} + +static JSBool +date_setUTCHours(JSContext *cx, JSObject *obj, uintN argc, + jsval *argv, jsval *rval) +{ + return date_makeTime(cx, obj, argc, argv, 4, JS_FALSE, rval); +} + +static JSBool +date_makeDate(JSContext *cx, JSObject *obj, uintN argc, + jsval *argv, uintN maxargs, JSBool local, jsval *rval) +{ + uintN i; + jsdouble lorutime; /* local or UTC version of *date */ + jsdouble args[3], *argp, *stop; + jsdouble year, month, day; + jsdouble result; + + jsdouble *date = date_getProlog(cx, obj, argv); + if (!date) + return JS_FALSE; + + result = *date; + + /* see complaint about ECMA in date_MakeTime */ + if (argc == 0) + argc = 1; /* should be safe, because length of all setters is 1 */ + else if (argc > maxargs) + argc = maxargs; /* clamp argc */ + + for (i = 0; i < argc; i++) { + if (!js_ValueToNumber(cx, argv[i], &args[i])) + return JS_FALSE; + if (!JSDOUBLE_IS_FINITE(args[i])) { + *date = *cx->runtime->jsNaN; + return js_NewNumberValue(cx, *date, rval); + } + args[i] = js_DoubleToInteger(args[i]); + } + + /* return NaN if date is NaN and we're not setting the year, + * If we are, use 0 as the time. */ + if (!(JSDOUBLE_IS_FINITE(result))) { + if (argc < 3) + return js_NewNumberValue(cx, result, rval); + else + lorutime = +0.; + } else { + if (local) + lorutime = LocalTime(result); + else + lorutime = result; + } + + argp = args; + stop = argp + argc; + if (maxargs >= 3 && argp < stop) + year = *argp++; + else + year = YearFromTime(lorutime); + + if (maxargs >= 2 && argp < stop) + month = *argp++; + else + month = MonthFromTime(lorutime); + + if (maxargs >= 1 && argp < stop) + day = *argp++; + else + day = DateFromTime(lorutime); + + day = MakeDay(year, month, day); /* day within year */ + result = MakeDate(day, TimeWithinDay(lorutime)); + + if (local) + result = UTC(result); + + *date = TIMECLIP(result); + return js_NewNumberValue(cx, *date, rval); +} + +static JSBool +date_setDate(JSContext *cx, JSObject *obj, uintN argc, + jsval *argv, jsval *rval) +{ + return date_makeDate(cx, obj, argc, argv, 1, JS_TRUE, rval); +} + +static JSBool +date_setUTCDate(JSContext *cx, JSObject *obj, uintN argc, + jsval *argv, jsval *rval) +{ + return date_makeDate(cx, obj, argc, argv, 1, JS_FALSE, rval); +} + +static JSBool +date_setMonth(JSContext *cx, JSObject *obj, uintN argc, + jsval *argv, jsval *rval) +{ + return date_makeDate(cx, obj, argc, argv, 2, JS_TRUE, rval); +} + +static JSBool +date_setUTCMonth(JSContext *cx, JSObject *obj, uintN argc, + jsval *argv, jsval *rval) +{ + return date_makeDate(cx, obj, argc, argv, 2, JS_FALSE, rval); +} + +static JSBool +date_setFullYear(JSContext *cx, JSObject *obj, uintN argc, + jsval *argv, jsval *rval) +{ + return date_makeDate(cx, obj, argc, argv, 3, JS_TRUE, rval); +} + +static JSBool +date_setUTCFullYear(JSContext *cx, JSObject *obj, uintN argc, + jsval *argv, jsval *rval) +{ + return date_makeDate(cx, obj, argc, argv, 3, JS_FALSE, rval); +} + +static JSBool +date_setYear(JSContext *cx, JSObject *obj, uintN argc, + jsval *argv, jsval *rval) +{ + jsdouble t; + jsdouble year; + jsdouble day; + jsdouble result; + + jsdouble *date = date_getProlog(cx, obj, argv); + if (!date) + return JS_FALSE; + + result = *date; + + if (!js_ValueToNumber(cx, argv[0], &year)) + return JS_FALSE; + if (!JSDOUBLE_IS_FINITE(year)) { + *date = *cx->runtime->jsNaN; + return js_NewNumberValue(cx, *date, rval); + } + + year = js_DoubleToInteger(year); + + if (!JSDOUBLE_IS_FINITE(result)) { + t = +0.0; + } else { + t = LocalTime(result); + } + + if (year >= 0 && year <= 99) + year += 1900; + + day = MakeDay(year, MonthFromTime(t), DateFromTime(t)); + result = MakeDate(day, TimeWithinDay(t)); + result = UTC(result); + + *date = TIMECLIP(result); + return js_NewNumberValue(cx, *date, rval); +} + +/* constants for toString, toUTCString */ +static char js_NaN_date_str[] = "Invalid Date"; +static const char* days[] = +{ + "Sun","Mon","Tue","Wed","Thu","Fri","Sat" +}; +static const char* months[] = +{ + "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" +}; + +static JSBool +date_toGMTString(JSContext *cx, JSObject *obj, uintN argc, + jsval *argv, jsval *rval) +{ + char buf[100]; + JSString *str; + jsdouble *date = date_getProlog(cx, obj, argv); + if (!date) + return JS_FALSE; + + if (!JSDOUBLE_IS_FINITE(*date)) { + JS_snprintf(buf, sizeof buf, js_NaN_date_str); + } else { + jsdouble temp = *date; + + /* Avoid dependence on PRMJ_FormatTimeUSEnglish, because it + * requires a PRMJTime... which only has 16-bit years. Sub-ECMA. + */ + JS_snprintf(buf, sizeof buf, "%s, %.2d %s %.4d %.2d:%.2d:%.2d GMT", + days[WeekDay(temp)], + DateFromTime(temp), + months[MonthFromTime(temp)], + YearFromTime(temp), + HourFromTime(temp), + MinFromTime(temp), + SecFromTime(temp)); + } + str = JS_NewStringCopyZ(cx, buf); + if (!str) + return JS_FALSE; + *rval = STRING_TO_JSVAL(str); + return JS_TRUE; +} + +/* for Date.toLocaleString; interface to PRMJTime date struct. + * If findEquivalent is true, then try to map the year to an equivalent year + * that's in range. + */ +static void +new_explode(jsdouble timeval, PRMJTime *split, JSBool findEquivalent) +{ + jsint year = YearFromTime(timeval); + int16 adjustedYear; + + /* If the year doesn't fit in a PRMJTime, find something to do about it. */ + if (year > 32767 || year < -32768) { + if (findEquivalent) { + /* We're really just trying to get a timezone string; map the year + * to some equivalent year in the range 0 to 2800. Borrowed from + * A. D. Olsen. + */ + jsint cycles; +#define CYCLE_YEARS 2800L + cycles = (year >= 0) ? year / CYCLE_YEARS + : -1 - (-1 - year) / CYCLE_YEARS; + adjustedYear = (int16)(year - cycles * CYCLE_YEARS); + } else { + /* Clamp it to the nearest representable year. */ + adjustedYear = (int16)((year > 0) ? 32767 : - 32768); + } + } else { + adjustedYear = (int16)year; + } + + split->tm_usec = (int32) msFromTime(timeval) * 1000; + split->tm_sec = (int8) SecFromTime(timeval); + split->tm_min = (int8) MinFromTime(timeval); + split->tm_hour = (int8) HourFromTime(timeval); + split->tm_mday = (int8) DateFromTime(timeval); + split->tm_mon = (int8) MonthFromTime(timeval); + split->tm_wday = (int8) WeekDay(timeval); + split->tm_year = (int16) adjustedYear; + split->tm_yday = (int16) DayWithinYear(timeval, year); + + /* not sure how this affects things, but it doesn't seem + to matter. */ + split->tm_isdst = (DaylightSavingTA(timeval) != 0); +} + +typedef enum formatspec { + FORMATSPEC_FULL, FORMATSPEC_DATE, FORMATSPEC_TIME +} formatspec; + +/* helper function */ +static JSBool +date_format(JSContext *cx, jsdouble date, formatspec format, jsval *rval) +{ + char buf[100]; + JSString *str; + char tzbuf[100]; + JSBool usetz; + size_t i, tzlen; + PRMJTime split; + + if (!JSDOUBLE_IS_FINITE(date)) { + JS_snprintf(buf, sizeof buf, js_NaN_date_str); + } else { + jsdouble local = LocalTime(date); + + /* offset from GMT in minutes. The offset includes daylight savings, + if it applies. */ + jsint minutes = (jsint) floor(AdjustTime(date) / msPerMinute); + + /* map 510 minutes to 0830 hours */ + intN offset = (minutes / 60) * 100 + minutes % 60; + + /* print as "Wed Nov 05 19:38:03 GMT-0800 (PST) 1997" The TZA is + * printed as 'GMT-0800' rather than as 'PST' to avoid + * operating-system dependence on strftime (which + * PRMJ_FormatTimeUSEnglish calls, for %Z only.) win32 prints + * PST as 'Pacific Standard Time.' This way we always know + * what we're getting, and can parse it if we produce it. + * The OS TZA string is included as a comment. + */ + + /* get a timezone string from the OS to include as a + comment. */ + new_explode(date, &split, JS_TRUE); + if (PRMJ_FormatTime(tzbuf, sizeof tzbuf, "(%Z)", &split) != 0) { + + /* Decide whether to use the resulting timezone string. + * + * Reject it if it contains any non-ASCII, non-alphanumeric + * characters. It's then likely in some other character + * encoding, and we probably won't display it correctly. + */ + usetz = JS_TRUE; + tzlen = strlen(tzbuf); + if (tzlen > 100) { + usetz = JS_FALSE; + } else { + for (i = 0; i < tzlen; i++) { + jschar c = tzbuf[i]; + if (c > 127 || + !(isalpha(c) || isdigit(c) || + c == ' ' || c == '(' || c == ')')) { + usetz = JS_FALSE; + } + } + } + + /* Also reject it if it's not parenthesized or if it's '()'. */ + if (tzbuf[0] != '(' || tzbuf[1] == ')') + usetz = JS_FALSE; + } else + usetz = JS_FALSE; + + switch (format) { + case FORMATSPEC_FULL: + /* + * Avoid dependence on PRMJ_FormatTimeUSEnglish, because it + * requires a PRMJTime... which only has 16-bit years. Sub-ECMA. + */ + /* Tue Oct 31 2000 09:41:40 GMT-0800 (PST) */ + JS_snprintf(buf, sizeof buf, + "%s %s %.2d %.4d %.2d:%.2d:%.2d GMT%+.4d%s%s", + days[WeekDay(local)], + months[MonthFromTime(local)], + DateFromTime(local), + YearFromTime(local), + HourFromTime(local), + MinFromTime(local), + SecFromTime(local), + offset, + usetz ? " " : "", + usetz ? tzbuf : ""); + break; + case FORMATSPEC_DATE: + /* Tue Oct 31 2000 */ + JS_snprintf(buf, sizeof buf, + "%s %s %.2d %.4d", + days[WeekDay(local)], + months[MonthFromTime(local)], + DateFromTime(local), + YearFromTime(local)); + break; + case FORMATSPEC_TIME: + /* 09:41:40 GMT-0800 (PST) */ + JS_snprintf(buf, sizeof buf, + "%.2d:%.2d:%.2d GMT%+.4d%s%s", + HourFromTime(local), + MinFromTime(local), + SecFromTime(local), + offset, + usetz ? " " : "", + usetz ? tzbuf : ""); + break; + } + } + + str = JS_NewStringCopyZ(cx, buf); + if (!str) + return JS_FALSE; + *rval = STRING_TO_JSVAL(str); + return JS_TRUE; +} + +static JSBool +date_toLocaleHelper(JSContext *cx, JSObject *obj, uintN argc, + jsval *argv, jsval *rval, char *format) +{ + char buf[100]; + JSString *str; + PRMJTime split; + jsdouble *date = date_getProlog(cx, obj, argv); + if (!date) + return JS_FALSE; + + if (!JSDOUBLE_IS_FINITE(*date)) { + JS_snprintf(buf, sizeof buf, js_NaN_date_str); + } else { + intN result_len; + jsdouble local = LocalTime(*date); + new_explode(local, &split, JS_FALSE); + + /* let PRMJTime format it. */ + result_len = PRMJ_FormatTime(buf, sizeof buf, format, &split); + + /* If it failed, default to toString. */ + if (result_len == 0) + return date_format(cx, *date, FORMATSPEC_FULL, rval); + + /* Hacked check against undesired 2-digit year 00/00/00 form. */ + if (buf[result_len - 3] == '/' && + isdigit(buf[result_len - 2]) && isdigit(buf[result_len - 1])) { + JS_snprintf(buf + (result_len - 2), (sizeof buf) - (result_len - 2), + "%d", js_DateGetYear(cx, obj)); + } + + } + + str = JS_NewStringCopyZ(cx, buf); + if (!str) + return JS_FALSE; + *rval = STRING_TO_JSVAL(str); + return JS_TRUE; +} + +static JSBool +date_toLocaleString(JSContext *cx, JSObject *obj, uintN argc, + jsval *argv, jsval *rval) +{ + /* Use '%#c' for windows, because '%c' is + * backward-compatible and non-y2k with msvc; '%#c' requests that a + * full year be used in the result string. + */ + return date_toLocaleHelper(cx, obj, argc, argv, rval, +#if defined(_WIN32) && !defined(__MWERKS__) + "%#c" +#else + "%c" +#endif + ); +} + +static JSBool +date_toLocaleDateString(JSContext *cx, JSObject *obj, uintN argc, + jsval *argv, jsval *rval) +{ + /* Use '%#x' for windows, because '%x' is + * backward-compatible and non-y2k with msvc; '%#x' requests that a + * full year be used in the result string. + */ + return date_toLocaleHelper(cx, obj, argc, argv, rval, +#if defined(_WIN32) && !defined(__MWERKS__) + "%#x" +#else + "%x" +#endif + ); +} + +static JSBool +date_toLocaleTimeString(JSContext *cx, JSObject *obj, uintN argc, + jsval *argv, jsval *rval) +{ + return date_toLocaleHelper(cx, obj, argc, argv, rval, "%X"); +} + +static JSBool +date_toTimeString(JSContext *cx, JSObject *obj, uintN argc, + jsval *argv, jsval *rval) +{ + jsdouble *date = date_getProlog(cx, obj, argv); + if (!date) + return JS_FALSE; + return date_format(cx, *date, FORMATSPEC_TIME, rval); +} + +static JSBool +date_toDateString(JSContext *cx, JSObject *obj, uintN argc, + jsval *argv, jsval *rval) +{ + jsdouble *date = date_getProlog(cx, obj, argv); + if (!date) + return JS_FALSE; + return date_format(cx, *date, FORMATSPEC_DATE, rval); +} + +#if JS_HAS_TOSOURCE +#include +#include "jsdtoa.h" + +static JSBool +date_toSource(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval) +{ + jsdouble *date; + char buf[DTOSTR_STANDARD_BUFFER_SIZE], *numStr, *bytes; + JSString *str; + + date = date_getProlog(cx, obj, argv); + if (!date) + return JS_FALSE; + + numStr = JS_dtostr(buf, sizeof buf, DTOSTR_STANDARD, 0, *date); + if (!numStr) { + JS_ReportOutOfMemory(cx); + return JS_FALSE; + } + + bytes = JS_smprintf("(new %s(%s))", date_class.name, numStr); + if (!bytes) { + JS_ReportOutOfMemory(cx); + return JS_FALSE; + } + + str = JS_NewString(cx, bytes, strlen(bytes)); + if (!str) { + free(bytes); + return JS_FALSE; + } + *rval = STRING_TO_JSVAL(str); + return JS_TRUE; +} +#endif + +static JSBool +date_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval) +{ + jsdouble *date = date_getProlog(cx, obj, argv); + if (!date) + return JS_FALSE; + return date_format(cx, *date, FORMATSPEC_FULL, rval); +} + +#if JS_HAS_VALUEOF_HINT +static JSBool +date_valueOf(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval) +{ + /* It is an error to call date_valueOf on a non-date object, but we don't + * need to check for that explicitly here because every path calls + * date_getProlog, which does the check. + */ + + /* If called directly with no arguments, convert to a time number. */ + if (argc == 0) + return date_getTime(cx, obj, argc, argv, rval); + + /* Convert to number only if the hint was given, otherwise favor string. */ + if (argc == 1) { + JSString *str, *str2; + + str = js_ValueToString(cx, argv[0]); + if (!str) + return JS_FALSE; + str2 = ATOM_TO_STRING(cx->runtime->atomState.typeAtoms[JSTYPE_NUMBER]); + if (!js_CompareStrings(str, str2)) + return date_getTime(cx, obj, argc, argv, rval); + } + return date_toString(cx, obj, argc, argv, rval); +} +#else +#define date_valueOf date_getTime +#endif + + +/* + * creation and destruction + */ + +static JSFunctionSpec date_static_methods[] = { + {"UTC", date_UTC, MAXARGS,0,0 }, + {"parse", date_parse, 1,0,0 }, + {"now", date_now, 0,0,0 }, + {0,0,0,0,0} +}; + +static JSFunctionSpec date_methods[] = { + {"getTime", date_getTime, 0,0,0 }, + {"getTimezoneOffset", date_getTimezoneOffset, 0,0,0 }, + {"getYear", date_getYear, 0,0,0 }, + {"getFullYear", date_getFullYear, 0,0,0 }, + {"getUTCFullYear", date_getUTCFullYear, 0,0,0 }, + {"getMonth", date_getMonth, 0,0,0 }, + {"getUTCMonth", date_getUTCMonth, 0,0,0 }, + {"getDate", date_getDate, 0,0,0 }, + {"getUTCDate", date_getUTCDate, 0,0,0 }, + {"getDay", date_getDay, 0,0,0 }, + {"getUTCDay", date_getUTCDay, 0,0,0 }, + {"getHours", date_getHours, 0,0,0 }, + {"getUTCHours", date_getUTCHours, 0,0,0 }, + {"getMinutes", date_getMinutes, 0,0,0 }, + {"getUTCMinutes", date_getUTCMinutes, 0,0,0 }, + {"getSeconds", date_getUTCSeconds, 0,0,0 }, + {"getUTCSeconds", date_getUTCSeconds, 0,0,0 }, + {"getMilliseconds", date_getUTCMilliseconds,0,0,0 }, + {"getUTCMilliseconds", date_getUTCMilliseconds,0,0,0 }, + {"setTime", date_setTime, 1,0,0 }, + {"setYear", date_setYear, 1,0,0 }, + {"setFullYear", date_setFullYear, 3,0,0 }, + {"setUTCFullYear", date_setUTCFullYear, 3,0,0 }, + {"setMonth", date_setMonth, 2,0,0 }, + {"setUTCMonth", date_setUTCMonth, 2,0,0 }, + {"setDate", date_setDate, 1,0,0 }, + {"setUTCDate", date_setUTCDate, 1,0,0 }, + {"setHours", date_setHours, 4,0,0 }, + {"setUTCHours", date_setUTCHours, 4,0,0 }, + {"setMinutes", date_setMinutes, 3,0,0 }, + {"setUTCMinutes", date_setUTCMinutes, 3,0,0 }, + {"setSeconds", date_setSeconds, 2,0,0 }, + {"setUTCSeconds", date_setUTCSeconds, 2,0,0 }, + {"setMilliseconds", date_setMilliseconds, 1,0,0 }, + {"setUTCMilliseconds", date_setUTCMilliseconds,1,0,0 }, + {"toUTCString", date_toGMTString, 0,0,0 }, + {js_toLocaleString_str, date_toLocaleString, 0,0,0 }, + {"toLocaleDateString", date_toLocaleDateString,0,0,0 }, + {"toLocaleTimeString", date_toLocaleTimeString,0,0,0 }, + {"toDateString", date_toDateString, 0,0,0 }, + {"toTimeString", date_toTimeString, 0,0,0 }, +#if JS_HAS_TOSOURCE + {js_toSource_str, date_toSource, 0,0,0 }, +#endif + {js_toString_str, date_toString, 0,0,0 }, + {js_valueOf_str, date_valueOf, 0,0,0 }, + {0,0,0,0,0} +}; + +static jsdouble * +date_constructor(JSContext *cx, JSObject* obj) +{ + jsdouble *date; + + date = js_NewDouble(cx, 0.0); + if (!date) + return NULL; + OBJ_SET_SLOT(cx, obj, JSSLOT_PRIVATE, DOUBLE_TO_JSVAL(date)); + return date; +} + +static JSBool +Date(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + jsdouble *date; + JSString *str; + jsdouble d; + + /* Date called as function */ + if (!(cx->fp->flags & JSFRAME_CONSTRUCTING)) { + int64 us, ms, us2ms; + jsdouble msec_time; + + /* NSPR 2.0 docs say 'We do not support PRMJ_NowMS and PRMJ_NowS', + * so compute ms from PRMJ_Now. + */ + us = PRMJ_Now(); + JSLL_UI2L(us2ms, PRMJ_USEC_PER_MSEC); + JSLL_DIV(ms, us, us2ms); + JSLL_L2D(msec_time, ms); + + return date_format(cx, msec_time, FORMATSPEC_FULL, rval); + } + + /* Date called as constructor */ + if (argc == 0) { + int64 us, ms, us2ms; + jsdouble msec_time; + + date = date_constructor(cx, obj); + if (!date) + return JS_FALSE; + + us = PRMJ_Now(); + JSLL_UI2L(us2ms, PRMJ_USEC_PER_MSEC); + JSLL_DIV(ms, us, us2ms); + JSLL_L2D(msec_time, ms); + + *date = msec_time; + } else if (argc == 1) { + if (!JSVAL_IS_STRING(argv[0])) { + /* the argument is a millisecond number */ + if (!js_ValueToNumber(cx, argv[0], &d)) + return JS_FALSE; + date = date_constructor(cx, obj); + if (!date) + return JS_FALSE; + *date = TIMECLIP(d); + } else { + /* the argument is a string; parse it. */ + date = date_constructor(cx, obj); + if (!date) + return JS_FALSE; + + str = js_ValueToString(cx, argv[0]); + if (!str) + return JS_FALSE; + + if (!date_parseString(str, date)) + *date = *cx->runtime->jsNaN; + *date = TIMECLIP(*date); + } + } else { + jsdouble array[MAXARGS]; + uintN loop; + jsdouble double_arg; + jsdouble day; + jsdouble msec_time; + + for (loop = 0; loop < MAXARGS; loop++) { + if (loop < argc) { + if (!js_ValueToNumber(cx, argv[loop], &double_arg)) + return JS_FALSE; + /* if any arg is NaN, make a NaN date object + and return */ + if (!JSDOUBLE_IS_FINITE(double_arg)) { + date = date_constructor(cx, obj); + if (!date) + return JS_FALSE; + *date = *cx->runtime->jsNaN; + return JS_TRUE; + } + array[loop] = js_DoubleToInteger(double_arg); + } else { + if (loop == 2) { + array[loop] = 1; /* Default the date argument to 1. */ + } else { + array[loop] = 0; + } + } + } + + date = date_constructor(cx, obj); + if (!date) + return JS_FALSE; + + /* adjust 2-digit years into the 20th century */ + if (array[0] >= 0 && array[0] <= 99) + array[0] += 1900; + + day = MakeDay(array[0], array[1], array[2]); + msec_time = MakeTime(array[3], array[4], array[5], array[6]); + msec_time = MakeDate(day, msec_time); + msec_time = UTC(msec_time); + *date = TIMECLIP(msec_time); + } + return JS_TRUE; +} + +JSObject * +js_InitDateClass(JSContext *cx, JSObject *obj) +{ + JSObject *proto; + jsdouble *proto_date; + + /* set static LocalTZA */ + LocalTZA = -(PRMJ_LocalGMTDifference() * msPerSecond); + proto = JS_InitClass(cx, obj, NULL, &date_class, Date, MAXARGS, + NULL, date_methods, NULL, date_static_methods); + if (!proto) + return NULL; + + /* Alias toUTCString with toGMTString. (ECMA B.2.6) */ + if (!JS_AliasProperty(cx, proto, "toUTCString", "toGMTString")) + return NULL; + + /* Set the value of the Date.prototype date to NaN */ + proto_date = date_constructor(cx, proto); + if (!proto_date) + return NULL; + *proto_date = *cx->runtime->jsNaN; + + return proto; +} + +JS_FRIEND_API(JSObject *) +js_NewDateObjectMsec(JSContext *cx, jsdouble msec_time) +{ + JSObject *obj; + jsdouble *date; + + obj = js_NewObject(cx, &date_class, NULL, NULL); + if (!obj) + return NULL; + + date = date_constructor(cx, obj); + if (!date) + return NULL; + + *date = msec_time; + return obj; +} + +JS_FRIEND_API(JSObject *) +js_NewDateObject(JSContext* cx, int year, int mon, int mday, + int hour, int min, int sec) +{ + JSObject *obj; + jsdouble msec_time; + + msec_time = date_msecFromDate(year, mon, mday, hour, min, sec, 0); + obj = js_NewDateObjectMsec(cx, UTC(msec_time)); + return obj; +} + +JS_FRIEND_API(JSBool) +js_DateIsValid(JSContext *cx, JSObject* obj) +{ + jsdouble *date = date_getProlog(cx, obj, NULL); + + if (!date || JSDOUBLE_IS_NaN(*date)) + return JS_FALSE; + else + return JS_TRUE; +} + +JS_FRIEND_API(int) +js_DateGetYear(JSContext *cx, JSObject* obj) +{ + jsdouble *date = date_getProlog(cx, obj, NULL); + + /* Preserve legacy API behavior of returning 0 for invalid dates. */ + if (!date || JSDOUBLE_IS_NaN(*date)) + return 0; + return (int) YearFromTime(LocalTime(*date)); +} + +JS_FRIEND_API(int) +js_DateGetMonth(JSContext *cx, JSObject* obj) +{ + jsdouble *date = date_getProlog(cx, obj, NULL); + + if (!date || JSDOUBLE_IS_NaN(*date)) + return 0; + return (int) MonthFromTime(LocalTime(*date)); +} + +JS_FRIEND_API(int) +js_DateGetDate(JSContext *cx, JSObject* obj) +{ + jsdouble *date = date_getProlog(cx, obj, NULL); + + if (!date || JSDOUBLE_IS_NaN(*date)) + return 0; + return (int) DateFromTime(LocalTime(*date)); +} + +JS_FRIEND_API(int) +js_DateGetHours(JSContext *cx, JSObject* obj) +{ + jsdouble *date = date_getProlog(cx, obj, NULL); + + if (!date || JSDOUBLE_IS_NaN(*date)) + return 0; + return (int) HourFromTime(LocalTime(*date)); +} + +JS_FRIEND_API(int) +js_DateGetMinutes(JSContext *cx, JSObject* obj) +{ + jsdouble *date = date_getProlog(cx, obj, NULL); + + if (!date || JSDOUBLE_IS_NaN(*date)) + return 0; + return (int) MinFromTime(LocalTime(*date)); +} + +JS_FRIEND_API(int) +js_DateGetSeconds(JSContext *cx, JSObject* obj) +{ + jsdouble *date = date_getProlog(cx, obj, NULL); + + if (!date || JSDOUBLE_IS_NaN(*date)) + return 0; + return (int) SecFromTime(*date); +} + +JS_FRIEND_API(void) +js_DateSetYear(JSContext *cx, JSObject *obj, int year) +{ + jsdouble local; + jsdouble *date = date_getProlog(cx, obj, NULL); + if (!date) + return; + local = LocalTime(*date); + /* reset date if it was NaN */ + if (JSDOUBLE_IS_NaN(local)) + local = 0; + local = date_msecFromDate(year, + MonthFromTime(local), + DateFromTime(local), + HourFromTime(local), + MinFromTime(local), + SecFromTime(local), + msFromTime(local)); + *date = UTC(local); +} + +JS_FRIEND_API(void) +js_DateSetMonth(JSContext *cx, JSObject *obj, int month) +{ + jsdouble local; + jsdouble *date = date_getProlog(cx, obj, NULL); + if (!date) + return; + local = LocalTime(*date); + /* bail if date was NaN */ + if (JSDOUBLE_IS_NaN(local)) + return; + local = date_msecFromDate(YearFromTime(local), + month, + DateFromTime(local), + HourFromTime(local), + MinFromTime(local), + SecFromTime(local), + msFromTime(local)); + *date = UTC(local); +} + +JS_FRIEND_API(void) +js_DateSetDate(JSContext *cx, JSObject *obj, int date) +{ + jsdouble local; + jsdouble *datep = date_getProlog(cx, obj, NULL); + if (!datep) + return; + local = LocalTime(*datep); + if (JSDOUBLE_IS_NaN(local)) + return; + local = date_msecFromDate(YearFromTime(local), + MonthFromTime(local), + date, + HourFromTime(local), + MinFromTime(local), + SecFromTime(local), + msFromTime(local)); + *datep = UTC(local); +} + +JS_FRIEND_API(void) +js_DateSetHours(JSContext *cx, JSObject *obj, int hours) +{ + jsdouble local; + jsdouble *date = date_getProlog(cx, obj, NULL); + if (!date) + return; + local = LocalTime(*date); + if (JSDOUBLE_IS_NaN(local)) + return; + local = date_msecFromDate(YearFromTime(local), + MonthFromTime(local), + DateFromTime(local), + hours, + MinFromTime(local), + SecFromTime(local), + msFromTime(local)); + *date = UTC(local); +} + +JS_FRIEND_API(void) +js_DateSetMinutes(JSContext *cx, JSObject *obj, int minutes) +{ + jsdouble local; + jsdouble *date = date_getProlog(cx, obj, NULL); + if (!date) + return; + local = LocalTime(*date); + if (JSDOUBLE_IS_NaN(local)) + return; + local = date_msecFromDate(YearFromTime(local), + MonthFromTime(local), + DateFromTime(local), + HourFromTime(local), + minutes, + SecFromTime(local), + msFromTime(local)); + *date = UTC(local); +} + +JS_FRIEND_API(void) +js_DateSetSeconds(JSContext *cx, JSObject *obj, int seconds) +{ + jsdouble local; + jsdouble *date = date_getProlog(cx, obj, NULL); + if (!date) + return; + local = LocalTime(*date); + if (JSDOUBLE_IS_NaN(local)) + return; + local = date_msecFromDate(YearFromTime(local), + MonthFromTime(local), + DateFromTime(local), + HourFromTime(local), + MinFromTime(local), + seconds, + msFromTime(local)); + *date = UTC(local); +} + +JS_FRIEND_API(jsdouble) +js_DateGetMsecSinceEpoch(JSContext *cx, JSObject *obj) +{ + jsdouble *date = date_getProlog(cx, obj, NULL); + if (!date || JSDOUBLE_IS_NaN(*date)) + return 0; + return (*date); +} diff --git a/src/dom/js/jsdate.h b/src/dom/js/jsdate.h new file mode 100644 index 000000000..790b4daf6 --- /dev/null +++ b/src/dom/js/jsdate.h @@ -0,0 +1,118 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* + * JS Date class interface. + */ + +#ifndef jsdate_h___ +#define jsdate_h___ + +JS_BEGIN_EXTERN_C + +extern JSObject * +js_InitDateClass(JSContext *cx, JSObject *obj); + +/* + * These functions provide a C interface to the date/time object + */ + +/* + * Construct a new Date Object from a time value given in milliseconds UTC + * since the epoch. + */ +extern JS_FRIEND_API(JSObject*) +js_NewDateObjectMsec(JSContext* cx, jsdouble msec_time); + +/* + * Construct a new Date Object from an exploded local time value. + */ +extern JS_FRIEND_API(JSObject*) +js_NewDateObject(JSContext* cx, int year, int mon, int mday, + int hour, int min, int sec); + +/* + * Detect whether the internal date value is NaN. (Because failure is + * out-of-band for js_DateGet*) + */ +extern JS_FRIEND_API(JSBool) +js_DateIsValid(JSContext *cx, JSObject* obj); + +extern JS_FRIEND_API(int) +js_DateGetYear(JSContext *cx, JSObject* obj); + +extern JS_FRIEND_API(int) +js_DateGetMonth(JSContext *cx, JSObject* obj); + +extern JS_FRIEND_API(int) +js_DateGetDate(JSContext *cx, JSObject* obj); + +extern JS_FRIEND_API(int) +js_DateGetHours(JSContext *cx, JSObject* obj); + +extern JS_FRIEND_API(int) +js_DateGetMinutes(JSContext *cx, JSObject* obj); + +extern JS_FRIEND_API(int) +js_DateGetSeconds(JSContext *cx, JSObject* obj); + +extern JS_FRIEND_API(void) +js_DateSetYear(JSContext *cx, JSObject *obj, int year); + +extern JS_FRIEND_API(void) +js_DateSetMonth(JSContext *cx, JSObject *obj, int year); + +extern JS_FRIEND_API(void) +js_DateSetDate(JSContext *cx, JSObject *obj, int date); + +extern JS_FRIEND_API(void) +js_DateSetHours(JSContext *cx, JSObject *obj, int hours); + +extern JS_FRIEND_API(void) +js_DateSetMinutes(JSContext *cx, JSObject *obj, int minutes); + +extern JS_FRIEND_API(void) +js_DateSetSeconds(JSContext *cx, JSObject *obj, int seconds); + +extern JS_FRIEND_API(jsdouble) +js_DateGetMsecSinceEpoch(JSContext *cx, JSObject *obj); + +JS_END_EXTERN_C + +#endif /* jsdate_h___ */ diff --git a/src/dom/js/jsdbgapi.c b/src/dom/js/jsdbgapi.c new file mode 100644 index 000000000..2aa684941 --- /dev/null +++ b/src/dom/js/jsdbgapi.c @@ -0,0 +1,1240 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* + * JS debugging API. + */ +#include "jsstddef.h" +#include +#include "jstypes.h" +#include "jsutil.h" /* Added by JSIFY */ +#include "jsclist.h" +#include "jsapi.h" +#include "jscntxt.h" +#include "jsconfig.h" +#include "jsdbgapi.h" +#include "jsfun.h" +#include "jsgc.h" +#include "jsinterp.h" +#include "jslock.h" +#include "jsobj.h" +#include "jsopcode.h" +#include "jsscope.h" +#include "jsscript.h" +#include "jsstr.h" + +typedef struct JSTrap { + JSCList links; + JSScript *script; + jsbytecode *pc; + JSOp op; + JSTrapHandler handler; + void *closure; +} JSTrap; + +static JSTrap * +FindTrap(JSRuntime *rt, JSScript *script, jsbytecode *pc) +{ + JSTrap *trap; + + for (trap = (JSTrap *)rt->trapList.next; + trap != (JSTrap *)&rt->trapList; + trap = (JSTrap *)trap->links.next) { + if (trap->script == script && trap->pc == pc) + return trap; + } + return NULL; +} + +void +js_PatchOpcode(JSContext *cx, JSScript *script, jsbytecode *pc, JSOp op) +{ + JSTrap *trap; + + trap = FindTrap(cx->runtime, script, pc); + if (trap) + trap->op = op; + else + *pc = (jsbytecode)op; +} + +JS_PUBLIC_API(JSBool) +JS_SetTrap(JSContext *cx, JSScript *script, jsbytecode *pc, + JSTrapHandler handler, void *closure) +{ + JSRuntime *rt; + JSTrap *trap; + + rt = cx->runtime; + trap = FindTrap(rt, script, pc); + if (trap) { + JS_ASSERT(trap->script == script && trap->pc == pc); + JS_ASSERT(*pc == JSOP_TRAP); + } else { + trap = (JSTrap *) JS_malloc(cx, sizeof *trap); + if (!trap || !js_AddRoot(cx, &trap->closure, "trap->closure")) { + if (trap) + JS_free(cx, trap); + return JS_FALSE; + } + JS_APPEND_LINK(&trap->links, &rt->trapList); + trap->script = script; + trap->pc = pc; + trap->op = (JSOp)*pc; + *pc = JSOP_TRAP; + } + trap->handler = handler; + trap->closure = closure; + return JS_TRUE; +} + +JS_PUBLIC_API(JSOp) +JS_GetTrapOpcode(JSContext *cx, JSScript *script, jsbytecode *pc) +{ + JSTrap *trap; + + trap = FindTrap(cx->runtime, script, pc); + if (!trap) { + JS_ASSERT(0); /* XXX can't happen */ + return JSOP_LIMIT; + } + return trap->op; +} + +static void +DestroyTrap(JSContext *cx, JSTrap *trap) +{ + JS_REMOVE_LINK(&trap->links); + *trap->pc = (jsbytecode)trap->op; + js_RemoveRoot(cx->runtime, &trap->closure); + JS_free(cx, trap); +} + +JS_PUBLIC_API(void) +JS_ClearTrap(JSContext *cx, JSScript *script, jsbytecode *pc, + JSTrapHandler *handlerp, void **closurep) +{ + JSTrap *trap; + + trap = FindTrap(cx->runtime, script, pc); + if (handlerp) + *handlerp = trap ? trap->handler : NULL; + if (closurep) + *closurep = trap ? trap->closure : NULL; + if (trap) + DestroyTrap(cx, trap); +} + +JS_PUBLIC_API(void) +JS_ClearScriptTraps(JSContext *cx, JSScript *script) +{ + JSRuntime *rt; + JSTrap *trap, *next; + + rt = cx->runtime; + for (trap = (JSTrap *)rt->trapList.next; + trap != (JSTrap *)&rt->trapList; + trap = next) { + next = (JSTrap *)trap->links.next; + if (trap->script == script) + DestroyTrap(cx, trap); + } +} + +JS_PUBLIC_API(void) +JS_ClearAllTraps(JSContext *cx) +{ + JSRuntime *rt; + JSTrap *trap, *next; + + rt = cx->runtime; + for (trap = (JSTrap *)rt->trapList.next; + trap != (JSTrap *)&rt->trapList; + trap = next) { + next = (JSTrap *)trap->links.next; + DestroyTrap(cx, trap); + } +} + +JS_PUBLIC_API(JSTrapStatus) +JS_HandleTrap(JSContext *cx, JSScript *script, jsbytecode *pc, jsval *rval) +{ + JSTrap *trap; + JSTrapStatus status; + jsint op; + + trap = FindTrap(cx->runtime, script, pc); + if (!trap) { + JS_ASSERT(0); /* XXX can't happen */ + return JSTRAP_ERROR; + } + /* + * It's important that we not use 'trap->' after calling the callback -- + * the callback might remove the trap! + */ + op = (jsint)trap->op; + status = trap->handler(cx, script, pc, rval, trap->closure); + if (status == JSTRAP_CONTINUE) { + /* By convention, return the true op to the interpreter in rval. */ + *rval = INT_TO_JSVAL(op); + } + return status; +} + +JS_PUBLIC_API(JSBool) +JS_SetInterrupt(JSRuntime *rt, JSTrapHandler handler, void *closure) +{ + rt->interruptHandler = handler; + rt->interruptHandlerData = closure; + return JS_TRUE; +} + +JS_PUBLIC_API(JSBool) +JS_ClearInterrupt(JSRuntime *rt, JSTrapHandler *handlerp, void **closurep) +{ + if (handlerp) + *handlerp = (JSTrapHandler)rt->interruptHandler; + if (closurep) + *closurep = rt->interruptHandlerData; + rt->interruptHandler = 0; + rt->interruptHandlerData = 0; + return JS_TRUE; +} + +/************************************************************************/ + +typedef struct JSWatchPoint { + JSCList links; + JSObject *object; /* weak link, see js_FinalizeObject */ + JSScopeProperty *sprop; + JSPropertyOp setter; + JSWatchPointHandler handler; + void *closure; + jsrefcount nrefs; +} JSWatchPoint; + +#define HoldWatchPoint(wp) ((wp)->nrefs++) + +static JSBool +DropWatchPoint(JSContext *cx, JSWatchPoint *wp) +{ + JSScopeProperty *sprop; + + if (--wp->nrefs != 0) + return JS_TRUE; + + /* + * Remove wp from the list, then if there are no other watchpoints for + * wp->sprop in any scope, restore wp->sprop->setter from wp. + */ + JS_REMOVE_LINK(&wp->links); + sprop = wp->sprop; + if (!js_GetWatchedSetter(cx->runtime, NULL, sprop)) { + sprop = js_ChangeNativePropertyAttrs(cx, wp->object, sprop, + 0, sprop->attrs, + sprop->getter, wp->setter); + if (!sprop) + return JS_FALSE; + } + js_RemoveRoot(cx->runtime, &wp->closure); + JS_free(cx, wp); + return JS_TRUE; +} + +void +js_MarkWatchPoints(JSRuntime *rt) +{ + JSWatchPoint *wp; + + for (wp = (JSWatchPoint *)rt->watchPointList.next; + wp != (JSWatchPoint *)&rt->watchPointList; + wp = (JSWatchPoint *)wp->links.next) { + MARK_SCOPE_PROPERTY(wp->sprop); + } +} + +static JSWatchPoint * +FindWatchPoint(JSRuntime *rt, JSScope *scope, jsid id) +{ + JSWatchPoint *wp; + + for (wp = (JSWatchPoint *)rt->watchPointList.next; + wp != (JSWatchPoint *)&rt->watchPointList; + wp = (JSWatchPoint *)wp->links.next) { + if (wp->object == scope->object && wp->sprop->id == id) + return wp; + } + return NULL; +} + +JSScopeProperty * +js_FindWatchPoint(JSRuntime *rt, JSScope *scope, jsid id) +{ + JSWatchPoint *wp; + + wp = FindWatchPoint(rt, scope, id); + if (!wp) + return NULL; + return wp->sprop; +} + +JSPropertyOp +js_GetWatchedSetter(JSRuntime *rt, JSScope *scope, + const JSScopeProperty *sprop) +{ + JSWatchPoint *wp; + + for (wp = (JSWatchPoint *)rt->watchPointList.next; + wp != (JSWatchPoint *)&rt->watchPointList; + wp = (JSWatchPoint *)wp->links.next) { + if ((!scope || wp->object == scope->object) && wp->sprop == sprop) + return wp->setter; + } + return NULL; +} + +JSBool JS_DLL_CALLBACK +js_watch_set(JSContext *cx, JSObject *obj, jsval id, jsval *vp) +{ + JSRuntime *rt; + JSWatchPoint *wp; + JSScopeProperty *sprop; + jsval userid; + JSScope *scope; + JSBool ok; + + rt = cx->runtime; + for (wp = (JSWatchPoint *)rt->watchPointList.next; + wp != (JSWatchPoint *)&rt->watchPointList; + wp = (JSWatchPoint *)wp->links.next) { + sprop = wp->sprop; + if (wp->object == obj && SPROP_USERID(sprop) == id) { + JS_LOCK_OBJ(cx, obj); + userid = SPROP_USERID(sprop); + scope = OBJ_SCOPE(obj); + JS_UNLOCK_OBJ(cx, obj); + HoldWatchPoint(wp); + ok = wp->handler(cx, obj, userid, + SPROP_HAS_VALID_SLOT(sprop, scope) + ? OBJ_GET_SLOT(cx, obj, wp->sprop->slot) + : JSVAL_VOID, + vp, wp->closure); + if (ok) { + /* + * Create pseudo-frame for call to setter so that any + * stack-walking security code in the setter will correctly + * identify the guilty party. + */ + JSObject *funobj = (JSObject *) wp->closure; + JSFunction *fun = (JSFunction *) JS_GetPrivate(cx, funobj); + JSStackFrame frame; + + memset(&frame, 0, sizeof(frame)); + frame.script = fun->script; + frame.fun = fun; + frame.down = cx->fp; + cx->fp = &frame; + ok = !wp->setter || + ((sprop->attrs & JSPROP_SETTER) + ? js_InternalCall(cx, obj, OBJECT_TO_JSVAL(wp->setter), + 1, vp, vp) + : wp->setter(cx, OBJ_THIS_OBJECT(cx, obj), userid, vp)); + cx->fp = frame.down; + } + return DropWatchPoint(cx, wp); + } + } + JS_ASSERT(0); /* XXX can't happen */ + return JS_FALSE; +} + +JSBool JS_DLL_CALLBACK +js_watch_set_wrapper(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval) +{ + JSObject *funobj; + JSFunction *wrapper; + jsval userid; + + funobj = JSVAL_TO_OBJECT(argv[-2]); + wrapper = (JSFunction *) JS_GetPrivate(cx, funobj); + userid = ATOM_KEY(wrapper->atom); + *rval = argv[0]; + return js_watch_set(cx, obj, userid, rval); +} + +JSPropertyOp +js_WrapWatchedSetter(JSContext *cx, jsid id, uintN attrs, JSPropertyOp setter) +{ + JSAtom *atom; + JSFunction *wrapper; + + if (!(attrs & JSPROP_SETTER)) + return &js_watch_set; /* & to silence schoolmarmish MSVC */ + + if (!JSVAL_IS_INT(id)) { + atom = (JSAtom *)id; + } else { + atom = js_AtomizeInt(cx, JSVAL_TO_INT(id), 0); + if (!atom) + return NULL; + } + wrapper = js_NewFunction(cx, NULL, js_watch_set_wrapper, 1, 0, + OBJ_GET_PARENT(cx, (JSObject *)setter), + atom); + if (!wrapper) + return NULL; + return (JSPropertyOp) wrapper->object; +} + +JS_PUBLIC_API(JSBool) +JS_SetWatchPoint(JSContext *cx, JSObject *obj, jsval id, + JSWatchPointHandler handler, void *closure) +{ + JSAtom *atom; + jsid propid; + JSObject *pobj; + JSScopeProperty *sprop; + JSRuntime *rt; + JSWatchPoint *wp; + JSPropertyOp watcher; + + if (!OBJ_IS_NATIVE(obj)) { + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_WATCH, + OBJ_GET_CLASS(cx, obj)->name); + return JS_FALSE; + } + + if (JSVAL_IS_INT(id)) { + propid = (jsid)id; + atom = NULL; + } else { + atom = js_ValueToStringAtom(cx, id); + if (!atom) + return JS_FALSE; + propid = (jsid)atom; + } + + if (!js_LookupProperty(cx, obj, propid, &pobj, (JSProperty **)&sprop)) + return JS_FALSE; + rt = cx->runtime; + if (!sprop) { + /* Check for a deleted symbol watchpoint, which holds its property. */ + sprop = js_FindWatchPoint(rt, OBJ_SCOPE(obj), propid); + if (!sprop) { + /* Make a new property in obj so we can watch for the first set. */ + if (!js_DefineProperty(cx, obj, propid, JSVAL_VOID, + NULL, NULL, JSPROP_ENUMERATE, + (JSProperty **)&sprop)) { + sprop = NULL; + } + } + } else if (pobj != obj) { + /* Clone the prototype property so we can watch the right object. */ + jsval value; + JSPropertyOp getter, setter; + uintN attrs; + + if (OBJ_IS_NATIVE(pobj)) { + value = SPROP_HAS_VALID_SLOT(sprop, OBJ_SCOPE(pobj)) + ? LOCKED_OBJ_GET_SLOT(pobj, sprop->slot) + : JSVAL_VOID; + getter = sprop->getter; + setter = sprop->setter; + attrs = sprop->attrs; + } else { + if (!OBJ_GET_PROPERTY(cx, pobj, id, &value)) { + OBJ_DROP_PROPERTY(cx, pobj, (JSProperty *)sprop); + return JS_FALSE; + } + getter = setter = JS_PropertyStub; + attrs = JSPROP_ENUMERATE; + } + OBJ_DROP_PROPERTY(cx, pobj, (JSProperty *)sprop); + + if (!js_DefineProperty(cx, obj, propid, value, getter, setter, attrs, + (JSProperty **)&sprop)) { + sprop = NULL; + } + } + if (!sprop) + return JS_FALSE; + + wp = FindWatchPoint(rt, OBJ_SCOPE(obj), propid); + if (!wp) { + watcher = js_WrapWatchedSetter(cx, propid, sprop->attrs, sprop->setter); + if (!watcher) + return JS_FALSE; + + wp = (JSWatchPoint *) JS_malloc(cx, sizeof *wp); + if (!wp) + return JS_FALSE; + wp->handler = NULL; + wp->closure = NULL; + if (!js_AddRoot(cx, &wp->closure, "wp->closure")) { + JS_free(cx, wp); + return JS_FALSE; + } + JS_APPEND_LINK(&wp->links, &rt->watchPointList); + wp->object = obj; + wp->sprop = sprop; + JS_ASSERT(sprop->setter != js_watch_set); + wp->setter = sprop->setter; + wp->nrefs = 1; + sprop = js_ChangeNativePropertyAttrs(cx, obj, sprop, 0, sprop->attrs, + sprop->getter, watcher); + if (!sprop) + return DropWatchPoint(cx, wp); + } + wp->handler = handler; + wp->closure = closure; + OBJ_DROP_PROPERTY(cx, obj, (JSProperty *)sprop); + return JS_TRUE; +} + +JS_PUBLIC_API(JSBool) +JS_ClearWatchPoint(JSContext *cx, JSObject *obj, jsval id, + JSWatchPointHandler *handlerp, void **closurep) +{ + JSRuntime *rt; + JSWatchPoint *wp; + + rt = cx->runtime; + for (wp = (JSWatchPoint *)rt->watchPointList.next; + wp != (JSWatchPoint *)&rt->watchPointList; + wp = (JSWatchPoint *)wp->links.next) { + if (wp->object == obj && SPROP_USERID(wp->sprop) == id) { + if (handlerp) + *handlerp = wp->handler; + if (closurep) + *closurep = wp->closure; + return DropWatchPoint(cx, wp); + } + } + if (handlerp) + *handlerp = NULL; + if (closurep) + *closurep = NULL; + return JS_TRUE; +} + +JS_PUBLIC_API(JSBool) +JS_ClearWatchPointsForObject(JSContext *cx, JSObject *obj) +{ + JSRuntime *rt; + JSWatchPoint *wp, *next; + + rt = cx->runtime; + for (wp = (JSWatchPoint *)rt->watchPointList.next; + wp != (JSWatchPoint *)&rt->watchPointList; + wp = next) { + next = (JSWatchPoint *)wp->links.next; + if (wp->object == obj && !DropWatchPoint(cx, wp)) + return JS_FALSE; + } + return JS_TRUE; +} + +JS_PUBLIC_API(JSBool) +JS_ClearAllWatchPoints(JSContext *cx) +{ + JSRuntime *rt; + JSWatchPoint *wp, *next; + + rt = cx->runtime; + for (wp = (JSWatchPoint *)rt->watchPointList.next; + wp != (JSWatchPoint *)&rt->watchPointList; + wp = next) { + next = (JSWatchPoint *)wp->links.next; + if (!DropWatchPoint(cx, wp)) + return JS_FALSE; + } + return JS_TRUE; +} + +/************************************************************************/ + +JS_PUBLIC_API(uintN) +JS_PCToLineNumber(JSContext *cx, JSScript *script, jsbytecode *pc) +{ + return js_PCToLineNumber(cx, script, pc); +} + +JS_PUBLIC_API(jsbytecode *) +JS_LineNumberToPC(JSContext *cx, JSScript *script, uintN lineno) +{ + return js_LineNumberToPC(script, lineno); +} + +JS_PUBLIC_API(JSScript *) +JS_GetFunctionScript(JSContext *cx, JSFunction *fun) +{ + return fun->script; +} + +JS_PUBLIC_API(JSPrincipals *) +JS_GetScriptPrincipals(JSContext *cx, JSScript *script) +{ + return script->principals; +} + +/************************************************************************/ + +/* + * Stack Frame Iterator + */ +JS_PUBLIC_API(JSStackFrame *) +JS_FrameIterator(JSContext *cx, JSStackFrame **iteratorp) +{ + *iteratorp = (*iteratorp == NULL) ? cx->fp : (*iteratorp)->down; + return *iteratorp; +} + +JS_PUBLIC_API(JSScript *) +JS_GetFrameScript(JSContext *cx, JSStackFrame *fp) +{ + return fp->script; +} + +JS_PUBLIC_API(jsbytecode *) +JS_GetFramePC(JSContext *cx, JSStackFrame *fp) +{ + return fp->pc; +} + +JS_PUBLIC_API(JSStackFrame *) +JS_GetScriptedCaller(JSContext *cx, JSStackFrame *fp) +{ + if (!fp) + fp = cx->fp; + while ((fp = fp->down) != NULL) { + if (fp->script) + return fp; + } + return NULL; +} + +JS_PUBLIC_API(JSPrincipals *) +JS_StackFramePrincipals(JSContext *cx, JSStackFrame *fp) +{ + if (fp->fun && cx->findObjectPrincipals) { + JSObject *callee = JSVAL_TO_OBJECT(fp->argv[-2]); + + if (fp->fun->object != callee) + return cx->findObjectPrincipals(cx, callee); + /* FALL THROUGH */ + } + if (fp->script) + return fp->script->principals; + return NULL; +} + +JS_PUBLIC_API(JSPrincipals *) +JS_EvalFramePrincipals(JSContext *cx, JSStackFrame *fp, JSStackFrame *caller) +{ + if (cx->findObjectPrincipals) + return cx->findObjectPrincipals(cx, JSVAL_TO_OBJECT(fp->argv[-2])); + if (!caller) + return NULL; + return JS_StackFramePrincipals(cx, caller); +} + +JS_PUBLIC_API(void *) +JS_GetFrameAnnotation(JSContext *cx, JSStackFrame *fp) +{ + if (fp->annotation && fp->script) { + JSPrincipals *principals = JS_StackFramePrincipals(cx, fp); + + if (principals && principals->globalPrivilegesEnabled(cx, principals)) { + /* + * Give out an annotation only if privileges have not been revoked + * or disabled globally. + */ + return fp->annotation; + } + } + + return NULL; +} + +JS_PUBLIC_API(void) +JS_SetFrameAnnotation(JSContext *cx, JSStackFrame *fp, void *annotation) +{ + fp->annotation = annotation; +} + +JS_PUBLIC_API(void *) +JS_GetFramePrincipalArray(JSContext *cx, JSStackFrame *fp) +{ + JSPrincipals *principals; + + principals = JS_StackFramePrincipals(cx, fp); + if (!principals) + return NULL; + return principals->getPrincipalArray(cx, principals); +} + +JS_PUBLIC_API(JSBool) +JS_IsNativeFrame(JSContext *cx, JSStackFrame *fp) +{ + return !fp->script; +} + +/* this is deprecated, use JS_GetFrameScopeChain instead */ +JS_PUBLIC_API(JSObject *) +JS_GetFrameObject(JSContext *cx, JSStackFrame *fp) +{ + return fp->scopeChain; +} + +JS_PUBLIC_API(JSObject *) +JS_GetFrameScopeChain(JSContext *cx, JSStackFrame *fp) +{ + /* Force creation of argument and call objects if not yet created */ + (void) JS_GetFrameCallObject(cx, fp); + return fp->scopeChain; +} + +JS_PUBLIC_API(JSObject *) +JS_GetFrameCallObject(JSContext *cx, JSStackFrame *fp) +{ + if (! fp->fun) + return NULL; +#if JS_HAS_ARGS_OBJECT + /* Force creation of argument object if not yet created */ + (void) js_GetArgsObject(cx, fp); +#endif +#if JS_HAS_CALL_OBJECT + /* + * XXX ill-defined: null return here means error was reported, unlike a + * null returned above or in the #else + */ + return js_GetCallObject(cx, fp, NULL); +#else + return NULL; +#endif /* JS_HAS_CALL_OBJECT */ +} + + +JS_PUBLIC_API(JSObject *) +JS_GetFrameThis(JSContext *cx, JSStackFrame *fp) +{ + return fp->thisp; +} + +JS_PUBLIC_API(JSFunction *) +JS_GetFrameFunction(JSContext *cx, JSStackFrame *fp) +{ + return fp->fun; +} + +JS_PUBLIC_API(JSObject *) +JS_GetFrameFunctionObject(JSContext *cx, JSStackFrame *fp) +{ + return fp->argv && fp->fun ? JSVAL_TO_OBJECT(fp->argv[-2]) : NULL; +} + +JS_PUBLIC_API(JSBool) +JS_IsConstructorFrame(JSContext *cx, JSStackFrame *fp) +{ + return (fp->flags & JSFRAME_CONSTRUCTING) != 0; +} + +JS_PUBLIC_API(JSBool) +JS_IsDebuggerFrame(JSContext *cx, JSStackFrame *fp) +{ + return (fp->flags & JSFRAME_DEBUGGER) != 0; +} + +JS_PUBLIC_API(jsval) +JS_GetFrameReturnValue(JSContext *cx, JSStackFrame *fp) +{ + return fp->rval; +} + +JS_PUBLIC_API(void) +JS_SetFrameReturnValue(JSContext *cx, JSStackFrame *fp, jsval rval) +{ + fp->rval = rval; +} + +/************************************************************************/ + +JS_PUBLIC_API(const char *) +JS_GetScriptFilename(JSContext *cx, JSScript *script) +{ + return script->filename; +} + +JS_PUBLIC_API(uintN) +JS_GetScriptBaseLineNumber(JSContext *cx, JSScript *script) +{ + return script->lineno; +} + +JS_PUBLIC_API(uintN) +JS_GetScriptLineExtent(JSContext *cx, JSScript *script) +{ + return js_GetScriptLineExtent(script); +} + +JS_PUBLIC_API(JSVersion) +JS_GetScriptVersion(JSContext *cx, JSScript *script) +{ + return script->version; +} + +/***************************************************************************/ + +JS_PUBLIC_API(void) +JS_SetNewScriptHook(JSRuntime *rt, JSNewScriptHook hook, void *callerdata) +{ + rt->newScriptHook = hook; + rt->newScriptHookData = callerdata; +} + +JS_PUBLIC_API(void) +JS_SetDestroyScriptHook(JSRuntime *rt, JSDestroyScriptHook hook, + void *callerdata) +{ + rt->destroyScriptHook = hook; + rt->destroyScriptHookData = callerdata; +} + +/***************************************************************************/ + +JS_PUBLIC_API(JSBool) +JS_EvaluateUCInStackFrame(JSContext *cx, JSStackFrame *fp, + const jschar *bytes, uintN length, + const char *filename, uintN lineno, + jsval *rval) +{ + uint32 flags; + JSScript *script; + JSBool ok; + + /* + * XXX Hack around ancient compiler API to propagate the JSFRAME_SPECIAL + * flags to the code generator (see js_EmitTree's TOK_SEMI case). + */ + flags = fp->flags; + fp->flags |= JSFRAME_DEBUGGER | JSFRAME_EVAL; + script = JS_CompileUCScriptForPrincipals(cx, fp->scopeChain, + JS_StackFramePrincipals(cx, fp), + bytes, length, filename, lineno); + fp->flags = flags; + if (!script) + return JS_FALSE; + + ok = js_Execute(cx, fp->scopeChain, script, fp, + JSFRAME_DEBUGGER | JSFRAME_EVAL, rval); + js_DestroyScript(cx, script); + return ok; +} + +JS_PUBLIC_API(JSBool) +JS_EvaluateInStackFrame(JSContext *cx, JSStackFrame *fp, + const char *bytes, uintN length, + const char *filename, uintN lineno, + jsval *rval) +{ + jschar *chars; + JSBool ok; + + chars = js_InflateString(cx, bytes, length); + if (!chars) + return JS_FALSE; + ok = JS_EvaluateUCInStackFrame(cx, fp, chars, length, filename, lineno, + rval); + JS_free(cx, chars); + + return ok; +} + +/************************************************************************/ + +/* XXXbe this all needs to be reworked to avoid requiring JSScope types. */ + +JS_PUBLIC_API(JSScopeProperty *) +JS_PropertyIterator(JSObject *obj, JSScopeProperty **iteratorp) +{ + JSScopeProperty *sprop; + JSScope *scope; + + sprop = *iteratorp; + scope = OBJ_SCOPE(obj); + + /* XXXbe minor(?) incompatibility: iterate in reverse definition order */ + if (!sprop) { + sprop = SCOPE_LAST_PROP(scope); + } else { + while ((sprop = sprop->parent) != NULL) { + if (!SCOPE_HAD_MIDDLE_DELETE(scope)) + break; + if (SCOPE_HAS_PROPERTY(scope, sprop)) + break; + } + } + *iteratorp = sprop; + return sprop; +} + +JS_PUBLIC_API(JSBool) +JS_GetPropertyDesc(JSContext *cx, JSObject *obj, JSScopeProperty *sprop, + JSPropertyDesc *pd) +{ + JSPropertyOp getter; + JSScope *scope; + JSScopeProperty *aprop; + jsval lastException; + JSBool wasThrowing; + + pd->id = ID_TO_VALUE(sprop->id); + + wasThrowing = cx->throwing; + if (wasThrowing) { + lastException = cx->exception; + if (JSVAL_IS_GCTHING(lastException) && + !js_AddRoot(cx, &lastException, "lastException")) { + return JS_FALSE; + } + cx->throwing = JS_FALSE; + } + + if (!js_GetProperty(cx, obj, sprop->id, &pd->value)) { + if (!cx->throwing) { + pd->flags = JSPD_ERROR; + pd->value = JSVAL_VOID; + } else { + pd->flags = JSPD_EXCEPTION; + pd->value = cx->exception; + } + } else { + pd->flags = 0; + } + + cx->throwing = wasThrowing; + if (wasThrowing) { + cx->exception = lastException; + if (JSVAL_IS_GCTHING(lastException)) + js_RemoveRoot(cx->runtime, &lastException); + } + + getter = sprop->getter; + pd->flags |= ((sprop->attrs & JSPROP_ENUMERATE) ? JSPD_ENUMERATE : 0) + | ((sprop->attrs & JSPROP_READONLY) ? JSPD_READONLY : 0) + | ((sprop->attrs & JSPROP_PERMANENT) ? JSPD_PERMANENT : 0) +#if JS_HAS_CALL_OBJECT + | ((getter == js_GetCallVariable) ? JSPD_VARIABLE : 0) +#endif /* JS_HAS_CALL_OBJECT */ + | ((getter == js_GetArgument) ? JSPD_ARGUMENT : 0) + | ((getter == js_GetLocalVariable) ? JSPD_VARIABLE : 0); +#if JS_HAS_CALL_OBJECT + /* for Call Object 'real' getter isn't passed in to us */ + if (OBJ_GET_CLASS(cx, obj) == &js_CallClass && + getter == js_CallClass.getProperty) { + /* + * Property of a heavyweight function's variable object having the + * class-default getter. It's either an argument if permanent, or a + * nested function if impermanent. Local variables have a special + * getter (js_GetCallVariable, tested above) and setter, and not the + * class default. + */ + pd->flags |= (sprop->attrs & JSPROP_PERMANENT) + ? JSPD_ARGUMENT + : JSPD_VARIABLE; + } +#endif /* JS_HAS_CALL_OBJECT */ + pd->spare = 0; + pd->slot = (pd->flags & (JSPD_ARGUMENT | JSPD_VARIABLE)) + ? sprop->shortid + : 0; + pd->alias = JSVAL_VOID; + scope = OBJ_SCOPE(obj); + if (SPROP_HAS_VALID_SLOT(sprop, scope)) { + for (aprop = SCOPE_LAST_PROP(scope); aprop; aprop = aprop->parent) { + if (aprop != sprop && aprop->slot == sprop->slot) { + pd->alias = ID_TO_VALUE(aprop->id); + break; + } + } + } + return JS_TRUE; +} + +JS_PUBLIC_API(JSBool) +JS_GetPropertyDescArray(JSContext *cx, JSObject *obj, JSPropertyDescArray *pda) +{ + JSClass *clasp; + JSScope *scope; + uint32 i, n; + JSPropertyDesc *pd; + JSScopeProperty *sprop; + + clasp = OBJ_GET_CLASS(cx, obj); + if (!OBJ_IS_NATIVE(obj) || (clasp->flags & JSCLASS_NEW_ENUMERATE)) { + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, + JSMSG_CANT_DESCRIBE_PROPS, clasp->name); + return JS_FALSE; + } + if (!clasp->enumerate(cx, obj)) + return JS_FALSE; + + /* have no props, or object's scope has not mutated from that of proto */ + scope = OBJ_SCOPE(obj); + if (scope->object != obj || scope->entryCount == 0) { + pda->length = 0; + pda->array = NULL; + return JS_TRUE; + } + + n = scope->entryCount; + if (n > scope->map.nslots) + n = scope->map.nslots; + pd = (JSPropertyDesc *) JS_malloc(cx, (size_t)n * sizeof(JSPropertyDesc)); + if (!pd) + return JS_FALSE; + i = 0; + for (sprop = SCOPE_LAST_PROP(scope); sprop; sprop = sprop->parent) { + if (SCOPE_HAD_MIDDLE_DELETE(scope) && !SCOPE_HAS_PROPERTY(scope, sprop)) + continue; + if (!js_AddRoot(cx, &pd[i].id, NULL)) + goto bad; + if (!js_AddRoot(cx, &pd[i].value, NULL)) + goto bad; + if (!JS_GetPropertyDesc(cx, obj, sprop, &pd[i])) + goto bad; + if ((pd[i].flags & JSPD_ALIAS) && !js_AddRoot(cx, &pd[i].alias, NULL)) + goto bad; + if (++i == n) + break; + } + pda->length = i; + pda->array = pd; + return JS_TRUE; + +bad: + pda->length = i + 1; + pda->array = pd; + JS_PutPropertyDescArray(cx, pda); + return JS_FALSE; +} + +JS_PUBLIC_API(void) +JS_PutPropertyDescArray(JSContext *cx, JSPropertyDescArray *pda) +{ + JSPropertyDesc *pd; + uint32 i; + + pd = pda->array; + for (i = 0; i < pda->length; i++) { + js_RemoveRoot(cx->runtime, &pd[i].id); + js_RemoveRoot(cx->runtime, &pd[i].value); + if (pd[i].flags & JSPD_ALIAS) + js_RemoveRoot(cx->runtime, &pd[i].alias); + } + JS_free(cx, pd); +} + +/************************************************************************/ + +JS_PUBLIC_API(JSBool) +JS_SetDebuggerHandler(JSRuntime *rt, JSTrapHandler handler, void *closure) +{ + rt->debuggerHandler = handler; + rt->debuggerHandlerData = closure; + return JS_TRUE; +} + +JS_PUBLIC_API(JSBool) +JS_SetSourceHandler(JSRuntime *rt, JSSourceHandler handler, void *closure) +{ + rt->sourceHandler = handler; + rt->sourceHandlerData = closure; + return JS_TRUE; +} + +JS_PUBLIC_API(JSBool) +JS_SetExecuteHook(JSRuntime *rt, JSInterpreterHook hook, void *closure) +{ + rt->executeHook = hook; + rt->executeHookData = closure; + return JS_TRUE; +} + +JS_PUBLIC_API(JSBool) +JS_SetCallHook(JSRuntime *rt, JSInterpreterHook hook, void *closure) +{ + rt->callHook = hook; + rt->callHookData = closure; + return JS_TRUE; +} + +JS_PUBLIC_API(JSBool) +JS_SetObjectHook(JSRuntime *rt, JSObjectHook hook, void *closure) +{ + rt->objectHook = hook; + rt->objectHookData = closure; + return JS_TRUE; +} + +JS_PUBLIC_API(JSBool) +JS_SetThrowHook(JSRuntime *rt, JSTrapHandler hook, void *closure) +{ + rt->throwHook = hook; + rt->throwHookData = closure; + return JS_TRUE; +} + +JS_PUBLIC_API(JSBool) +JS_SetDebugErrorHook(JSRuntime *rt, JSDebugErrorHook hook, void *closure) +{ + rt->debugErrorHook = hook; + rt->debugErrorHookData = closure; + return JS_TRUE; +} + +/************************************************************************/ + +JS_PUBLIC_API(size_t) +JS_GetObjectTotalSize(JSContext *cx, JSObject *obj) +{ + size_t nbytes; + JSScope *scope; + + nbytes = sizeof *obj + obj->map->nslots * sizeof obj->slots[0]; + if (OBJ_IS_NATIVE(obj)) { + scope = OBJ_SCOPE(obj); + if (scope->object == obj) { + nbytes += sizeof *scope; + nbytes += SCOPE_CAPACITY(scope) * sizeof(JSScopeProperty *); + } + } + return nbytes; +} + +static size_t +GetAtomTotalSize(JSContext *cx, JSAtom *atom) +{ + size_t nbytes; + + nbytes = sizeof *atom; + if (ATOM_IS_STRING(atom)) { + nbytes += sizeof(JSString); + nbytes += (ATOM_TO_STRING(atom)->length + 1) * sizeof(jschar); + } else if (ATOM_IS_DOUBLE(atom)) { + nbytes += sizeof(jsdouble); + } else if (ATOM_IS_OBJECT(atom)) { + nbytes += JS_GetObjectTotalSize(cx, ATOM_TO_OBJECT(atom)); + } + return nbytes; +} + +JS_PUBLIC_API(size_t) +JS_GetFunctionTotalSize(JSContext *cx, JSFunction *fun) +{ + size_t nbytes, obytes; + JSObject *obj; + JSAtom *atom; + + nbytes = sizeof *fun; + JS_ASSERT(fun->nrefs); + obj = fun->object; + if (obj) { + obytes = JS_GetObjectTotalSize(cx, obj); + if (fun->nrefs > 1) + obytes = JS_HOWMANY(obytes, fun->nrefs); + nbytes += obytes; + } + if (fun->script) + nbytes += JS_GetScriptTotalSize(cx, fun->script); + atom = fun->atom; + if (atom) + nbytes += GetAtomTotalSize(cx, atom); + return nbytes; +} + +#include "jsemit.h" + +JS_PUBLIC_API(size_t) +JS_GetScriptTotalSize(JSContext *cx, JSScript *script) +{ + size_t nbytes, pbytes; + JSObject *obj; + jsatomid i; + jssrcnote *sn, *notes; + JSTryNote *tn, *tnotes; + JSPrincipals *principals; + + nbytes = sizeof *script; + obj = script->object; + if (obj) + nbytes += JS_GetObjectTotalSize(cx, obj); + + nbytes += script->length * sizeof script->code[0]; + nbytes += script->atomMap.length * sizeof script->atomMap.vector[0]; + for (i = 0; i < script->atomMap.length; i++) + nbytes += GetAtomTotalSize(cx, script->atomMap.vector[i]); + + if (script->filename) + nbytes += strlen(script->filename) + 1; + + notes = SCRIPT_NOTES(script); + for (sn = notes; !SN_IS_TERMINATOR(sn); sn = SN_NEXT(sn)) + continue; + nbytes += (sn - notes + 1) * sizeof *sn; + + tnotes = script->trynotes; + if (tnotes) { + for (tn = tnotes; tn->catchStart; tn++) + continue; + nbytes += (tn - tnotes + 1) * sizeof *tn; + } + + principals = script->principals; + if (principals) { + JS_ASSERT(principals->refcount); + pbytes = sizeof *principals; + if (principals->refcount > 1) + pbytes = JS_HOWMANY(pbytes, principals->refcount); + nbytes += pbytes; + } + + return nbytes; +} diff --git a/src/dom/js/jsdbgapi.h b/src/dom/js/jsdbgapi.h new file mode 100644 index 000000000..90215a275 --- /dev/null +++ b/src/dom/js/jsdbgapi.h @@ -0,0 +1,345 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef jsdbgapi_h___ +#define jsdbgapi_h___ +/* + * JS debugger API. + */ +#include "jsapi.h" +#include "jsopcode.h" +#include "jsprvtd.h" + +JS_BEGIN_EXTERN_C + +extern void +js_PatchOpcode(JSContext *cx, JSScript *script, jsbytecode *pc, JSOp op); + +extern JS_PUBLIC_API(JSBool) +JS_SetTrap(JSContext *cx, JSScript *script, jsbytecode *pc, + JSTrapHandler handler, void *closure); + +extern JS_PUBLIC_API(JSOp) +JS_GetTrapOpcode(JSContext *cx, JSScript *script, jsbytecode *pc); + +extern JS_PUBLIC_API(void) +JS_ClearTrap(JSContext *cx, JSScript *script, jsbytecode *pc, + JSTrapHandler *handlerp, void **closurep); + +extern JS_PUBLIC_API(void) +JS_ClearScriptTraps(JSContext *cx, JSScript *script); + +extern JS_PUBLIC_API(void) +JS_ClearAllTraps(JSContext *cx); + +extern JS_PUBLIC_API(JSTrapStatus) +JS_HandleTrap(JSContext *cx, JSScript *script, jsbytecode *pc, jsval *rval); + +extern JS_PUBLIC_API(JSBool) +JS_SetInterrupt(JSRuntime *rt, JSTrapHandler handler, void *closure); + +extern JS_PUBLIC_API(JSBool) +JS_ClearInterrupt(JSRuntime *rt, JSTrapHandler *handlerp, void **closurep); + +/************************************************************************/ + +extern JS_PUBLIC_API(JSBool) +JS_SetWatchPoint(JSContext *cx, JSObject *obj, jsval id, + JSWatchPointHandler handler, void *closure); + +extern JS_PUBLIC_API(JSBool) +JS_ClearWatchPoint(JSContext *cx, JSObject *obj, jsval id, + JSWatchPointHandler *handlerp, void **closurep); + +extern JS_PUBLIC_API(JSBool) +JS_ClearWatchPointsForObject(JSContext *cx, JSObject *obj); + +extern JS_PUBLIC_API(JSBool) +JS_ClearAllWatchPoints(JSContext *cx); + +#ifdef JS_HAS_OBJ_WATCHPOINT +/* + * Hide these non-API function prototypes by testing whether the internal + * header file "jsconfig.h" has been included. + */ +extern void +js_MarkWatchPoints(JSRuntime *rt); + +extern JSScopeProperty * +js_FindWatchPoint(JSRuntime *rt, JSScope *scope, jsid id); + +extern JSPropertyOp +js_GetWatchedSetter(JSRuntime *rt, JSScope *scope, + const JSScopeProperty *sprop); + +extern JSBool JS_DLL_CALLBACK +js_watch_set(JSContext *cx, JSObject *obj, jsval id, jsval *vp); + +extern JSBool JS_DLL_CALLBACK +js_watch_set_wrapper(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval); + +extern JSPropertyOp +js_WrapWatchedSetter(JSContext *cx, jsid id, uintN attrs, JSPropertyOp setter); + +#endif /* JS_HAS_OBJ_WATCHPOINT */ + +/************************************************************************/ + +extern JS_PUBLIC_API(uintN) +JS_PCToLineNumber(JSContext *cx, JSScript *script, jsbytecode *pc); + +extern JS_PUBLIC_API(jsbytecode *) +JS_LineNumberToPC(JSContext *cx, JSScript *script, uintN lineno); + +extern JS_PUBLIC_API(JSScript *) +JS_GetFunctionScript(JSContext *cx, JSFunction *fun); + +extern JS_PUBLIC_API(JSPrincipals *) +JS_GetScriptPrincipals(JSContext *cx, JSScript *script); + +/* + * Stack Frame Iterator + * + * Used to iterate through the JS stack frames to extract + * information from the frames. + */ + +extern JS_PUBLIC_API(JSStackFrame *) +JS_FrameIterator(JSContext *cx, JSStackFrame **iteratorp); + +extern JS_PUBLIC_API(JSScript *) +JS_GetFrameScript(JSContext *cx, JSStackFrame *fp); + +extern JS_PUBLIC_API(jsbytecode *) +JS_GetFramePC(JSContext *cx, JSStackFrame *fp); + +/* + * Get the closest scripted frame below fp. If fp is null, start from cx->fp. + */ +extern JS_PUBLIC_API(JSStackFrame *) +JS_GetScriptedCaller(JSContext *cx, JSStackFrame *fp); + +/* + * Return a weak reference to fp's principals. A null return does not denote + * an error, it means there are no principals. + */ +extern JS_PUBLIC_API(JSPrincipals *) +JS_StackFramePrincipals(JSContext *cx, JSStackFrame *fp); + +/* + * Like JS_StackFramePrincipals(cx, caller), but if cx->findObjectPrincipals + * is non-null, return the object principals for fp's callee function object + * (fp->argv[-2]), which is eval, Function, or a similar eval-like method. + * The caller parameter should be the result of JS_GetScriptedCaller(cx, fp). + * + * All eval-like methods must use JS_EvalFramePrincipals to acquire a weak + * reference to the correct principals for the eval call to be secure, given + * an embedding that calls JS_SetObjectPrincipalsFinder (see jsapi.h). + */ +extern JS_PUBLIC_API(JSPrincipals *) +JS_EvalFramePrincipals(JSContext *cx, JSStackFrame *fp, JSStackFrame *caller); + +extern JS_PUBLIC_API(void *) +JS_GetFrameAnnotation(JSContext *cx, JSStackFrame *fp); + +extern JS_PUBLIC_API(void) +JS_SetFrameAnnotation(JSContext *cx, JSStackFrame *fp, void *annotation); + +extern JS_PUBLIC_API(void *) +JS_GetFramePrincipalArray(JSContext *cx, JSStackFrame *fp); + +extern JS_PUBLIC_API(JSBool) +JS_IsNativeFrame(JSContext *cx, JSStackFrame *fp); + +/* this is deprecated, use JS_GetFrameScopeChain instead */ +extern JS_PUBLIC_API(JSObject *) +JS_GetFrameObject(JSContext *cx, JSStackFrame *fp); + +extern JS_PUBLIC_API(JSObject *) +JS_GetFrameScopeChain(JSContext *cx, JSStackFrame *fp); + +extern JS_PUBLIC_API(JSObject *) +JS_GetFrameCallObject(JSContext *cx, JSStackFrame *fp); + +extern JS_PUBLIC_API(JSObject *) +JS_GetFrameThis(JSContext *cx, JSStackFrame *fp); + +extern JS_PUBLIC_API(JSFunction *) +JS_GetFrameFunction(JSContext *cx, JSStackFrame *fp); + +extern JS_PUBLIC_API(JSObject *) +JS_GetFrameFunctionObject(JSContext *cx, JSStackFrame *fp); + +/* XXXrginda Initially published with typo */ +#define JS_IsContructorFrame JS_IsConstructorFrame +extern JS_PUBLIC_API(JSBool) +JS_IsConstructorFrame(JSContext *cx, JSStackFrame *fp); + +extern JS_PUBLIC_API(JSBool) +JS_IsDebuggerFrame(JSContext *cx, JSStackFrame *fp); + +extern JS_PUBLIC_API(jsval) +JS_GetFrameReturnValue(JSContext *cx, JSStackFrame *fp); + +extern JS_PUBLIC_API(void) +JS_SetFrameReturnValue(JSContext *cx, JSStackFrame *fp, jsval rval); + +/************************************************************************/ + +extern JS_PUBLIC_API(const char *) +JS_GetScriptFilename(JSContext *cx, JSScript *script); + +extern JS_PUBLIC_API(uintN) +JS_GetScriptBaseLineNumber(JSContext *cx, JSScript *script); + +extern JS_PUBLIC_API(uintN) +JS_GetScriptLineExtent(JSContext *cx, JSScript *script); + +extern JS_PUBLIC_API(JSVersion) +JS_GetScriptVersion(JSContext *cx, JSScript *script); + +/************************************************************************/ + +/* + * Hook setters for script creation and destruction, see jsprvtd.h for the + * typedefs. These macros provide binary compatibility and newer, shorter + * synonyms. + */ +#define JS_SetNewScriptHook JS_SetNewScriptHookProc +#define JS_SetDestroyScriptHook JS_SetDestroyScriptHookProc + +extern JS_PUBLIC_API(void) +JS_SetNewScriptHook(JSRuntime *rt, JSNewScriptHook hook, void *callerdata); + +extern JS_PUBLIC_API(void) +JS_SetDestroyScriptHook(JSRuntime *rt, JSDestroyScriptHook hook, + void *callerdata); + +/************************************************************************/ + +extern JS_PUBLIC_API(JSBool) +JS_EvaluateUCInStackFrame(JSContext *cx, JSStackFrame *fp, + const jschar *bytes, uintN length, + const char *filename, uintN lineno, + jsval *rval); + +extern JS_PUBLIC_API(JSBool) +JS_EvaluateInStackFrame(JSContext *cx, JSStackFrame *fp, + const char *bytes, uintN length, + const char *filename, uintN lineno, + jsval *rval); + +/************************************************************************/ + +typedef struct JSPropertyDesc { + jsval id; /* primary id, a string or int */ + jsval value; /* property value */ + uint8 flags; /* flags, see below */ + uint8 spare; /* unused */ + uint16 slot; /* argument/variable slot */ + jsval alias; /* alias id if JSPD_ALIAS flag */ +} JSPropertyDesc; + +#define JSPD_ENUMERATE 0x01 /* visible to for/in loop */ +#define JSPD_READONLY 0x02 /* assignment is error */ +#define JSPD_PERMANENT 0x04 /* property cannot be deleted */ +#define JSPD_ALIAS 0x08 /* property has an alias id */ +#define JSPD_ARGUMENT 0x10 /* argument to function */ +#define JSPD_VARIABLE 0x20 /* local variable in function */ +#define JSPD_EXCEPTION 0x40 /* exception occurred fetching the property, */ + /* value is exception */ +#define JSPD_ERROR 0x80 /* native getter returned JS_FALSE without */ + /* throwing an exception */ + +typedef struct JSPropertyDescArray { + uint32 length; /* number of elements in array */ + JSPropertyDesc *array; /* alloc'd by Get, freed by Put */ +} JSPropertyDescArray; + +extern JS_PUBLIC_API(JSScopeProperty *) +JS_PropertyIterator(JSObject *obj, JSScopeProperty **iteratorp); + +extern JS_PUBLIC_API(JSBool) +JS_GetPropertyDesc(JSContext *cx, JSObject *obj, JSScopeProperty *sprop, + JSPropertyDesc *pd); + +extern JS_PUBLIC_API(JSBool) +JS_GetPropertyDescArray(JSContext *cx, JSObject *obj, JSPropertyDescArray *pda); + +extern JS_PUBLIC_API(void) +JS_PutPropertyDescArray(JSContext *cx, JSPropertyDescArray *pda); + +/************************************************************************/ + +extern JS_PUBLIC_API(JSBool) +JS_SetDebuggerHandler(JSRuntime *rt, JSTrapHandler handler, void *closure); + +extern JS_PUBLIC_API(JSBool) +JS_SetSourceHandler(JSRuntime *rt, JSSourceHandler handler, void *closure); + +extern JS_PUBLIC_API(JSBool) +JS_SetExecuteHook(JSRuntime *rt, JSInterpreterHook hook, void *closure); + +extern JS_PUBLIC_API(JSBool) +JS_SetCallHook(JSRuntime *rt, JSInterpreterHook hook, void *closure); + +extern JS_PUBLIC_API(JSBool) +JS_SetObjectHook(JSRuntime *rt, JSObjectHook hook, void *closure); + +extern JS_PUBLIC_API(JSBool) +JS_SetThrowHook(JSRuntime *rt, JSTrapHandler hook, void *closure); + +extern JS_PUBLIC_API(JSBool) +JS_SetDebugErrorHook(JSRuntime *rt, JSDebugErrorHook hook, void *closure); + +/************************************************************************/ + +extern JS_PUBLIC_API(size_t) +JS_GetObjectTotalSize(JSContext *cx, JSObject *obj); + +extern JS_PUBLIC_API(size_t) +JS_GetFunctionTotalSize(JSContext *cx, JSFunction *fun); + +extern JS_PUBLIC_API(size_t) +JS_GetScriptTotalSize(JSContext *cx, JSScript *script); + +JS_END_EXTERN_C + +#endif /* jsdbgapi_h___ */ diff --git a/src/dom/js/jsdhash.c b/src/dom/js/jsdhash.c new file mode 100644 index 000000000..736de04ad --- /dev/null +++ b/src/dom/js/jsdhash.c @@ -0,0 +1,763 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla JavaScript code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1999-2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Brendan Eich (Original Author) + * Chris Waterson + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* + * Double hashing implementation. + */ +#include +#include +#include +#include "jsbit.h" +#include "jsdhash.h" +#include "jsutil.h" /* for JS_ASSERT */ + +#ifdef JS_DHASHMETER +# if defined MOZILLA_CLIENT && defined DEBUG_XXXbrendan +# include "nsTraceMalloc.h" +# endif +# define METER(x) x +#else +# define METER(x) /* nothing */ +#endif + +JS_PUBLIC_API(void *) +JS_DHashAllocTable(JSDHashTable *table, uint32 nbytes) +{ + return malloc(nbytes); +} + +JS_PUBLIC_API(void) +JS_DHashFreeTable(JSDHashTable *table, void *ptr) +{ + free(ptr); +} + +JS_PUBLIC_API(JSDHashNumber) +JS_DHashStringKey(JSDHashTable *table, const void *key) +{ + JSDHashNumber h; + const unsigned char *s; + + h = 0; + for (s = key; *s != '\0'; s++) + h = (h >> (JS_DHASH_BITS - 4)) ^ (h << 4) ^ *s; + return h; +} + +JS_PUBLIC_API(const void *) +JS_DHashGetKeyStub(JSDHashTable *table, JSDHashEntryHdr *entry) +{ + JSDHashEntryStub *stub = (JSDHashEntryStub *)entry; + + return stub->key; +} + +JS_PUBLIC_API(JSDHashNumber) +JS_DHashVoidPtrKeyStub(JSDHashTable *table, const void *key) +{ + return (JSDHashNumber)key >> 2; +} + +JS_PUBLIC_API(JSBool) +JS_DHashMatchEntryStub(JSDHashTable *table, + const JSDHashEntryHdr *entry, + const void *key) +{ + const JSDHashEntryStub *stub = (const JSDHashEntryStub *)entry; + + return stub->key == key; +} + +JS_PUBLIC_API(JSBool) +JS_DHashMatchStringKey(JSDHashTable *table, + const JSDHashEntryHdr *entry, + const void *key) +{ + const JSDHashEntryStub *stub = (const JSDHashEntryStub *)entry; + + /* XXX tolerate null keys on account of sloppy Mozilla callers. */ + return stub->key == key || + (stub->key && key && strcmp(stub->key, key) == 0); +} + +JS_PUBLIC_API(void) +JS_DHashMoveEntryStub(JSDHashTable *table, + const JSDHashEntryHdr *from, + JSDHashEntryHdr *to) +{ + memcpy(to, from, table->entrySize); +} + +JS_PUBLIC_API(void) +JS_DHashClearEntryStub(JSDHashTable *table, JSDHashEntryHdr *entry) +{ + memset(entry, 0, table->entrySize); +} + +JS_PUBLIC_API(void) +JS_DHashFreeStringKey(JSDHashTable *table, JSDHashEntryHdr *entry) +{ + const JSDHashEntryStub *stub = (const JSDHashEntryStub *)entry; + + free((void *) stub->key); + memset(entry, 0, table->entrySize); +} + +JS_PUBLIC_API(void) +JS_DHashFinalizeStub(JSDHashTable *table) +{ +} + +static const JSDHashTableOps stub_ops = { + JS_DHashAllocTable, + JS_DHashFreeTable, + JS_DHashGetKeyStub, + JS_DHashVoidPtrKeyStub, + JS_DHashMatchEntryStub, + JS_DHashMoveEntryStub, + JS_DHashClearEntryStub, + JS_DHashFinalizeStub, + NULL +}; + +JS_PUBLIC_API(const JSDHashTableOps *) +JS_DHashGetStubOps(void) +{ + return &stub_ops; +} + +JS_PUBLIC_API(JSDHashTable *) +JS_NewDHashTable(const JSDHashTableOps *ops, void *data, uint32 entrySize, + uint32 capacity) +{ + JSDHashTable *table; + + table = (JSDHashTable *) malloc(sizeof *table); + if (!table) + return NULL; + if (!JS_DHashTableInit(table, ops, data, entrySize, capacity)) { + free(table); + return NULL; + } + return table; +} + +JS_PUBLIC_API(void) +JS_DHashTableDestroy(JSDHashTable *table) +{ + JS_DHashTableFinish(table); + free(table); +} + +JS_PUBLIC_API(JSBool) +JS_DHashTableInit(JSDHashTable *table, const JSDHashTableOps *ops, void *data, + uint32 entrySize, uint32 capacity) +{ + int log2; + uint32 nbytes; + +#ifdef DEBUG + if (entrySize > 10 * sizeof(void *)) { + fprintf(stderr, + "jsdhash: for the table at address %p, the given entrySize" + " of %lu %s favors chaining over double hashing.\n", + (void *)table, + (unsigned long) entrySize, + (entrySize > 16 * sizeof(void*)) ? "definitely" : "probably"); + } +#endif + + table->ops = ops; + table->data = data; + if (capacity < JS_DHASH_MIN_SIZE) + capacity = JS_DHASH_MIN_SIZE; + log2 = JS_CeilingLog2(capacity); + capacity = JS_BIT(log2); + if (capacity >= JS_DHASH_SIZE_LIMIT) + return JS_FALSE; + table->hashShift = JS_DHASH_BITS - log2; + table->maxAlphaFrac = 0xC0; /* .75 */ + table->minAlphaFrac = 0x40; /* .25 */ + table->entrySize = entrySize; + table->entryCount = table->removedCount = 0; + table->generation = 0; + nbytes = capacity * entrySize; + + table->entryStore = ops->allocTable(table, nbytes); + if (!table->entryStore) + return JS_FALSE; + memset(table->entryStore, 0, nbytes); + METER(memset(&table->stats, 0, sizeof table->stats)); + return JS_TRUE; +} + +/* + * Compute max and min load numbers (entry counts) from table params. + */ +#define MAX_LOAD(table, size) (((table)->maxAlphaFrac * (size)) >> 8) +#define MIN_LOAD(table, size) (((table)->minAlphaFrac * (size)) >> 8) + +JS_PUBLIC_API(void) +JS_DHashTableSetAlphaBounds(JSDHashTable *table, + float maxAlpha, + float minAlpha) +{ + uint32 size; + + /* + * Reject obviously insane bounds, rather than trying to guess what the + * buggy caller intended. + */ + JS_ASSERT(0.5 <= maxAlpha && maxAlpha < 1 && 0 <= minAlpha); + if (maxAlpha < 0.5 || 1 <= maxAlpha || minAlpha < 0) + return; + + /* + * Ensure that at least one entry will always be free. If maxAlpha at + * minimum size leaves no entries free, reduce maxAlpha based on minimum + * size and the precision limit of maxAlphaFrac's fixed point format. + */ + JS_ASSERT(JS_DHASH_MIN_SIZE - (maxAlpha * JS_DHASH_MIN_SIZE) >= 1); + if (JS_DHASH_MIN_SIZE - (maxAlpha * JS_DHASH_MIN_SIZE) < 1) { + maxAlpha = (float) + (JS_DHASH_MIN_SIZE - JS_MAX(JS_DHASH_MIN_SIZE / 256, 1)) + / JS_DHASH_MIN_SIZE; + } + + /* + * Ensure that minAlpha is strictly less than half maxAlpha. Take care + * not to truncate an entry's worth of alpha when storing in minAlphaFrac + * (8-bit fixed point format). + */ + JS_ASSERT(minAlpha < maxAlpha / 2); + if (minAlpha >= maxAlpha / 2) { + size = JS_DHASH_TABLE_SIZE(table); + minAlpha = (size * maxAlpha - JS_MAX(size / 256, 1)) / (2 * size); + } + + table->maxAlphaFrac = (uint8)(maxAlpha * 256); + table->minAlphaFrac = (uint8)(minAlpha * 256); +} + +/* + * Double hashing needs the second hash code to be relatively prime to table + * size, so we simply make hash2 odd. + */ +#define HASH1(hash0, shift) ((hash0) >> (shift)) +#define HASH2(hash0,log2,shift) ((((hash0) << (log2)) >> (shift)) | 1) + +/* + * Reserve keyHash 0 for free entries and 1 for removed-entry sentinels. Note + * that a removed-entry sentinel need be stored only if the removed entry had + * a colliding entry added after it. Therefore we can use 1 as the collision + * flag in addition to the removed-entry sentinel value. Multiplicative hash + * uses the high order bits of keyHash, so this least-significant reservation + * should not hurt the hash function's effectiveness much. + * + * If you change any of these magic numbers, also update JS_DHASH_ENTRY_IS_LIVE + * in jsdhash.h. It used to be private to jsdhash.c, but then became public to + * assist iterator writers who inspect table->entryStore directly. + */ +#define COLLISION_FLAG ((JSDHashNumber) 1) +#define MARK_ENTRY_FREE(entry) ((entry)->keyHash = 0) +#define MARK_ENTRY_REMOVED(entry) ((entry)->keyHash = 1) +#define ENTRY_IS_REMOVED(entry) ((entry)->keyHash == 1) +#define ENTRY_IS_LIVE(entry) JS_DHASH_ENTRY_IS_LIVE(entry) +#define ENSURE_LIVE_KEYHASH(hash0) if (hash0 < 2) hash0 -= 2; else (void)0 + +/* Match an entry's keyHash against an unstored one computed from a key. */ +#define MATCH_ENTRY_KEYHASH(entry,hash0) \ + (((entry)->keyHash & ~COLLISION_FLAG) == (hash0)) + +/* Compute the address of the indexed entry in table. */ +#define ADDRESS_ENTRY(table, index) \ + ((JSDHashEntryHdr *)((table)->entryStore + (index) * (table)->entrySize)) + +JS_PUBLIC_API(void) +JS_DHashTableFinish(JSDHashTable *table) +{ + char *entryAddr, *entryLimit; + uint32 entrySize; + JSDHashEntryHdr *entry; + +#ifdef DEBUG_XXXbrendan + static FILE *dumpfp = NULL; + if (!dumpfp) dumpfp = fopen("/tmp/jsdhash.bigdump", "w"); + if (dumpfp) { +#ifdef MOZILLA_CLIENT + NS_TraceStack(1, dumpfp); +#endif + JS_DHashTableDumpMeter(table, NULL, dumpfp); + fputc('\n', dumpfp); + } +#endif + + /* Call finalize before clearing entries, so it can enumerate them. */ + table->ops->finalize(table); + + /* Clear any remaining live entries. */ + entryAddr = table->entryStore; + entrySize = table->entrySize; + entryLimit = entryAddr + JS_DHASH_TABLE_SIZE(table) * entrySize; + while (entryAddr < entryLimit) { + entry = (JSDHashEntryHdr *)entryAddr; + if (ENTRY_IS_LIVE(entry)) { + METER(table->stats.removeEnums++); + table->ops->clearEntry(table, entry); + } + entryAddr += entrySize; + } + + /* Free entry storage last. */ + table->ops->freeTable(table, table->entryStore); +} + +static JSDHashEntryHdr * +SearchTable(JSDHashTable *table, const void *key, JSDHashNumber keyHash, + JSDHashOperator op) +{ + JSDHashNumber hash1, hash2; + int hashShift, sizeLog2; + JSDHashEntryHdr *entry, *firstRemoved; + JSDHashMatchEntry matchEntry; + uint32 sizeMask; + + METER(table->stats.searches++); + JS_ASSERT(!(keyHash & COLLISION_FLAG)); + + /* Compute the primary hash address. */ + hashShift = table->hashShift; + hash1 = HASH1(keyHash, hashShift); + entry = ADDRESS_ENTRY(table, hash1); + + /* Miss: return space for a new entry. */ + if (JS_DHASH_ENTRY_IS_FREE(entry)) { + METER(table->stats.misses++); + return entry; + } + + /* Hit: return entry. */ + matchEntry = table->ops->matchEntry; + if (MATCH_ENTRY_KEYHASH(entry, keyHash) && matchEntry(table, entry, key)) { + METER(table->stats.hits++); + return entry; + } + + /* Collision: double hash. */ + sizeLog2 = JS_DHASH_BITS - table->hashShift; + hash2 = HASH2(keyHash, sizeLog2, hashShift); + sizeMask = JS_BITMASK(sizeLog2); + + /* Save the first removed entry pointer so JS_DHASH_ADD can recycle it. */ + if (ENTRY_IS_REMOVED(entry)) { + firstRemoved = entry; + } else { + firstRemoved = NULL; + if (op == JS_DHASH_ADD) + entry->keyHash |= COLLISION_FLAG; + } + + for (;;) { + METER(table->stats.steps++); + hash1 -= hash2; + hash1 &= sizeMask; + + entry = ADDRESS_ENTRY(table, hash1); + if (JS_DHASH_ENTRY_IS_FREE(entry)) { + METER(table->stats.misses++); + return (firstRemoved && op == JS_DHASH_ADD) ? firstRemoved : entry; + } + + if (MATCH_ENTRY_KEYHASH(entry, keyHash) && + matchEntry(table, entry, key)) { + METER(table->stats.hits++); + return entry; + } + + if (ENTRY_IS_REMOVED(entry)) { + if (!firstRemoved) + firstRemoved = entry; + } else { + if (op == JS_DHASH_ADD) + entry->keyHash |= COLLISION_FLAG; + } + } + + /* NOTREACHED */ + return NULL; +} + +static JSBool +ChangeTable(JSDHashTable *table, int deltaLog2) +{ + int oldLog2, newLog2; + uint32 oldCapacity, newCapacity; + char *newEntryStore, *oldEntryStore, *oldEntryAddr; + uint32 entrySize, i, nbytes; + JSDHashEntryHdr *oldEntry, *newEntry; + JSDHashGetKey getKey; + JSDHashMoveEntry moveEntry; + + /* Look, but don't touch, until we succeed in getting new entry store. */ + oldLog2 = JS_DHASH_BITS - table->hashShift; + newLog2 = oldLog2 + deltaLog2; + oldCapacity = JS_BIT(oldLog2); + newCapacity = JS_BIT(newLog2); + if (newCapacity >= JS_DHASH_SIZE_LIMIT) + return JS_FALSE; + entrySize = table->entrySize; + nbytes = newCapacity * entrySize; + + newEntryStore = table->ops->allocTable(table, nbytes); + if (!newEntryStore) + return JS_FALSE; + + /* We can't fail from here on, so update table parameters. */ + table->hashShift = JS_DHASH_BITS - newLog2; + table->removedCount = 0; + table->generation++; + + /* Assign the new entry store to table. */ + memset(newEntryStore, 0, nbytes); + oldEntryAddr = oldEntryStore = table->entryStore; + table->entryStore = newEntryStore; + getKey = table->ops->getKey; + moveEntry = table->ops->moveEntry; + + /* Copy only live entries, leaving removed ones behind. */ + for (i = 0; i < oldCapacity; i++) { + oldEntry = (JSDHashEntryHdr *)oldEntryAddr; + if (ENTRY_IS_LIVE(oldEntry)) { + oldEntry->keyHash &= ~COLLISION_FLAG; + newEntry = SearchTable(table, getKey(table, oldEntry), + oldEntry->keyHash, JS_DHASH_ADD); + JS_ASSERT(JS_DHASH_ENTRY_IS_FREE(newEntry)); + moveEntry(table, oldEntry, newEntry); + newEntry->keyHash = oldEntry->keyHash; + } + oldEntryAddr += entrySize; + } + + table->ops->freeTable(table, oldEntryStore); + return JS_TRUE; +} + +JS_PUBLIC_API(JSDHashEntryHdr *) +JS_DHashTableOperate(JSDHashTable *table, const void *key, JSDHashOperator op) +{ + JSDHashNumber keyHash; + JSDHashEntryHdr *entry; + uint32 size; + int deltaLog2; + + keyHash = table->ops->hashKey(table, key); + keyHash *= JS_DHASH_GOLDEN_RATIO; + + /* Avoid 0 and 1 hash codes, they indicate free and removed entries. */ + ENSURE_LIVE_KEYHASH(keyHash); + keyHash &= ~COLLISION_FLAG; + + switch (op) { + case JS_DHASH_LOOKUP: + METER(table->stats.lookups++); + entry = SearchTable(table, key, keyHash, op); + break; + + case JS_DHASH_ADD: + /* + * If alpha is >= .75, grow or compress the table. If key is already + * in the table, we may grow once more than necessary, but only if we + * are on the edge of being overloaded. + */ + size = JS_DHASH_TABLE_SIZE(table); + if (table->entryCount + table->removedCount >= MAX_LOAD(table, size)) { + /* Compress if a quarter or more of all entries are removed. */ + if (table->removedCount >= size >> 2) { + METER(table->stats.compresses++); + deltaLog2 = 0; + } else { + METER(table->stats.grows++); + deltaLog2 = 1; + } + + /* + * Grow or compress table, returning null if ChangeTable fails and + * falling through might claim the last free entry. + */ + if (!ChangeTable(table, deltaLog2) && + table->entryCount + table->removedCount == size - 1) { + METER(table->stats.addFailures++); + return NULL; + } + } + + /* + * Look for entry after possibly growing, so we don't have to add it, + * then skip it while growing the table and re-add it after. + */ + entry = SearchTable(table, key, keyHash, op); + if (!ENTRY_IS_LIVE(entry)) { + /* Initialize the entry, indicating that it's no longer free. */ + METER(table->stats.addMisses++); + if (ENTRY_IS_REMOVED(entry)) { + METER(table->stats.addOverRemoved++); + table->removedCount--; + keyHash |= COLLISION_FLAG; + } + if (table->ops->initEntry && + !table->ops->initEntry(table, entry, key)) { + /* We haven't claimed entry yet; fail with null return. */ + memset(entry + 1, 0, table->entrySize - sizeof *entry); + return NULL; + } + entry->keyHash = keyHash; + table->entryCount++; + } + METER(else table->stats.addHits++); + break; + + case JS_DHASH_REMOVE: + entry = SearchTable(table, key, keyHash, op); + if (ENTRY_IS_LIVE(entry)) { + /* Clear this entry and mark it as "removed". */ + METER(table->stats.removeHits++); + JS_DHashTableRawRemove(table, entry); + + /* Shrink if alpha is <= .25 and table isn't too small already. */ + size = JS_DHASH_TABLE_SIZE(table); + if (size > JS_DHASH_MIN_SIZE && + table->entryCount <= MIN_LOAD(table, size)) { + METER(table->stats.shrinks++); + (void) ChangeTable(table, -1); + } + } + METER(else table->stats.removeMisses++); + entry = NULL; + break; + + default: + JS_ASSERT(0); + entry = NULL; + } + + return entry; +} + +JS_PUBLIC_API(void) +JS_DHashTableRawRemove(JSDHashTable *table, JSDHashEntryHdr *entry) +{ + JSDHashNumber keyHash; /* load first in case clearEntry goofs it */ + + JS_ASSERT(JS_DHASH_ENTRY_IS_LIVE(entry)); + keyHash = entry->keyHash; + table->ops->clearEntry(table, entry); + if (keyHash & COLLISION_FLAG) { + MARK_ENTRY_REMOVED(entry); + table->removedCount++; + } else { + METER(table->stats.removeFrees++); + MARK_ENTRY_FREE(entry); + } + table->entryCount--; +} + +JS_PUBLIC_API(uint32) +JS_DHashTableEnumerate(JSDHashTable *table, JSDHashEnumerator etor, void *arg) +{ + char *entryAddr, *entryLimit; + uint32 i, capacity, entrySize; + JSBool didRemove; + JSDHashEntryHdr *entry; + JSDHashOperator op; + + entryAddr = table->entryStore; + entrySize = table->entrySize; + capacity = JS_DHASH_TABLE_SIZE(table); + entryLimit = entryAddr + capacity * entrySize; + i = 0; + didRemove = JS_FALSE; + while (entryAddr < entryLimit) { + entry = (JSDHashEntryHdr *)entryAddr; + if (ENTRY_IS_LIVE(entry)) { + op = etor(table, entry, i++, arg); + if (op & JS_DHASH_REMOVE) { + METER(table->stats.removeEnums++); + JS_DHashTableRawRemove(table, entry); + didRemove = JS_TRUE; + } + if (op & JS_DHASH_STOP) + break; + } + entryAddr += entrySize; + } + + /* + * Shrink or compress if a quarter or more of all entries are removed, or + * if the table is underloaded according to the configured minimum alpha, + * and is not minimal-size already. Do this only if we removed above, so + * non-removing enumerations can count on stable table->entryStore until + * the next non-lookup-Operate or removing-Enumerate. + */ + if (didRemove && + (table->removedCount >= capacity >> 2 || + (capacity > JS_DHASH_MIN_SIZE && + table->entryCount <= MIN_LOAD(table, capacity)))) { + METER(table->stats.enumShrinks++); + capacity = table->entryCount; + capacity += capacity >> 1; + if (capacity < JS_DHASH_MIN_SIZE) + capacity = JS_DHASH_MIN_SIZE; + (void) ChangeTable(table, + JS_CeilingLog2(capacity) + - (JS_DHASH_BITS - table->hashShift)); + } + return i; +} + +#ifdef JS_DHASHMETER +#include + +JS_PUBLIC_API(void) +JS_DHashTableDumpMeter(JSDHashTable *table, JSDHashEnumerator dump, FILE *fp) +{ + char *entryAddr; + uint32 entrySize, entryCount; + int hashShift, sizeLog2; + uint32 i, tableSize, sizeMask, chainLen, maxChainLen, chainCount; + JSDHashNumber hash1, hash2, saveHash1, maxChainHash1, maxChainHash2; + double sqsum, mean, variance, sigma; + JSDHashEntryHdr *entry, *probe; + + entryAddr = table->entryStore; + entrySize = table->entrySize; + hashShift = table->hashShift; + sizeLog2 = JS_DHASH_BITS - hashShift; + tableSize = JS_DHASH_TABLE_SIZE(table); + sizeMask = JS_BITMASK(sizeLog2); + chainCount = maxChainLen = 0; + hash2 = 0; + sqsum = 0; + + for (i = 0; i < tableSize; i++) { + entry = (JSDHashEntryHdr *)entryAddr; + entryAddr += entrySize; + if (!ENTRY_IS_LIVE(entry)) + continue; + hash1 = HASH1(entry->keyHash & ~COLLISION_FLAG, hashShift); + saveHash1 = hash1; + probe = ADDRESS_ENTRY(table, hash1); + chainLen = 1; + if (probe == entry) { + /* Start of a (possibly unit-length) chain. */ + chainCount++; + } else { + hash2 = HASH2(entry->keyHash & ~COLLISION_FLAG, sizeLog2, + hashShift); + do { + chainLen++; + hash1 -= hash2; + hash1 &= sizeMask; + probe = ADDRESS_ENTRY(table, hash1); + } while (probe != entry); + } + sqsum += chainLen * chainLen; + if (chainLen > maxChainLen) { + maxChainLen = chainLen; + maxChainHash1 = saveHash1; + maxChainHash2 = hash2; + } + } + + entryCount = table->entryCount; + if (entryCount && chainCount) { + mean = (double)entryCount / chainCount; + variance = chainCount * sqsum - entryCount * entryCount; + if (variance < 0 || chainCount == 1) + variance = 0; + else + variance /= chainCount * (chainCount - 1); + sigma = sqrt(variance); + } else { + mean = sigma = 0; + } + + fprintf(fp, "Double hashing statistics:\n"); + fprintf(fp, " table size (in entries): %u\n", tableSize); + fprintf(fp, " number of entries: %u\n", table->entryCount); + fprintf(fp, " number of removed entries: %u\n", table->removedCount); + fprintf(fp, " number of searches: %u\n", table->stats.searches); + fprintf(fp, " number of hits: %u\n", table->stats.hits); + fprintf(fp, " number of misses: %u\n", table->stats.misses); + fprintf(fp, " mean steps per search: %g\n", table->stats.searches ? + (double)table->stats.steps + / table->stats.searches : + 0.); + fprintf(fp, " mean hash chain length: %g\n", mean); + fprintf(fp, " standard deviation: %g\n", sigma); + fprintf(fp, " maximum hash chain length: %u\n", maxChainLen); + fprintf(fp, " number of lookups: %u\n", table->stats.lookups); + fprintf(fp, " adds that made a new entry: %u\n", table->stats.addMisses); + fprintf(fp, "adds that recycled removeds: %u\n", table->stats.addOverRemoved); + fprintf(fp, " adds that found an entry: %u\n", table->stats.addHits); + fprintf(fp, " add failures: %u\n", table->stats.addFailures); + fprintf(fp, " useful removes: %u\n", table->stats.removeHits); + fprintf(fp, " useless removes: %u\n", table->stats.removeMisses); + fprintf(fp, "removes that freed an entry: %u\n", table->stats.removeFrees); + fprintf(fp, " removes while enumerating: %u\n", table->stats.removeEnums); + fprintf(fp, " number of grows: %u\n", table->stats.grows); + fprintf(fp, " number of shrinks: %u\n", table->stats.shrinks); + fprintf(fp, " number of compresses: %u\n", table->stats.compresses); + fprintf(fp, "number of enumerate shrinks: %u\n", table->stats.enumShrinks); + + if (dump && maxChainLen && hash2) { + fputs("Maximum hash chain:\n", fp); + hash1 = maxChainHash1; + hash2 = maxChainHash2; + entry = ADDRESS_ENTRY(table, hash1); + i = 0; + do { + if (dump(table, entry, i++, fp) != JS_DHASH_NEXT) + break; + hash1 -= hash2; + hash1 &= sizeMask; + entry = ADDRESS_ENTRY(table, hash1); + } while (JS_DHASH_ENTRY_IS_BUSY(entry)); + } +} +#endif /* JS_DHASHMETER */ diff --git a/src/dom/js/jsdhash.h b/src/dom/js/jsdhash.h new file mode 100644 index 000000000..39982ce05 --- /dev/null +++ b/src/dom/js/jsdhash.h @@ -0,0 +1,573 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla JavaScript code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1999-2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Brendan Eich (Original Author) + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef jsdhash_h___ +#define jsdhash_h___ +/* + * Double hashing, a la Knuth 6. + */ +#include "jstypes.h" + +JS_BEGIN_EXTERN_C + +#ifdef DEBUG_XXXbrendan +#define JS_DHASHMETER 1 +#endif + +/* Table size limit, do not equal or exceed (see min&maxAlphaFrac, below). */ +#undef JS_DHASH_SIZE_LIMIT +#define JS_DHASH_SIZE_LIMIT JS_BIT(24) + +/* Minimum table size, or gross entry count (net is at most .75 loaded). */ +#ifndef JS_DHASH_MIN_SIZE +#define JS_DHASH_MIN_SIZE 16 +#elif (JS_DHASH_MIN_SIZE & (JS_DHASH_MIN_SIZE - 1)) != 0 +#error "JS_DHASH_MIN_SIZE must be a power of two!" +#endif + +/* + * Multiplicative hash uses an unsigned 32 bit integer and the golden ratio, + * expressed as a fixed-point 32-bit fraction. + */ +#define JS_DHASH_BITS 32 +#define JS_DHASH_GOLDEN_RATIO 0x9E3779B9U + +/* Primitive and forward-struct typedefs. */ +typedef uint32 JSDHashNumber; +typedef struct JSDHashEntryHdr JSDHashEntryHdr; +typedef struct JSDHashEntryStub JSDHashEntryStub; +typedef struct JSDHashTable JSDHashTable; +typedef struct JSDHashTableOps JSDHashTableOps; + +/* + * Table entry header structure. + * + * In order to allow in-line allocation of key and value, we do not declare + * either here. Instead, the API uses const void *key as a formal parameter, + * and asks each entry for its key when necessary via a getKey callback, used + * when growing or shrinking the table. Other callback types are defined + * below and grouped into the JSDHashTableOps structure, for single static + * initialization per hash table sub-type. + * + * Each hash table sub-type should nest the JSDHashEntryHdr structure at the + * front of its particular entry type. The keyHash member contains the result + * of multiplying the hash code returned from the hashKey callback (see below) + * by JS_DHASH_GOLDEN_RATIO, then constraining the result to avoid the magic 0 + * and 1 values. The stored keyHash value is table size invariant, and it is + * maintained automatically by JS_DHashTableOperate -- users should never set + * it, and its only uses should be via the entry macros below. + * + * The JS_DHASH_ENTRY_IS_LIVE macro tests whether entry is neither free nor + * removed. An entry may be either busy or free; if busy, it may be live or + * removed. Consumers of this API should not access members of entries that + * are not live. + * + * However, use JS_DHASH_ENTRY_IS_BUSY for faster liveness testing of entries + * returned by JS_DHashTableOperate, as JS_DHashTableOperate never returns a + * non-live, busy (i.e., removed) entry pointer to its caller. See below for + * more details on JS_DHashTableOperate's calling rules. + */ +struct JSDHashEntryHdr { + JSDHashNumber keyHash; /* every entry must begin like this */ +}; + +#define JS_DHASH_ENTRY_IS_FREE(entry) ((entry)->keyHash == 0) +#define JS_DHASH_ENTRY_IS_BUSY(entry) (!JS_DHASH_ENTRY_IS_FREE(entry)) +#define JS_DHASH_ENTRY_IS_LIVE(entry) ((entry)->keyHash >= 2) + +/* + * A JSDHashTable is currently 8 words (without the JS_DHASHMETER overhead) + * on most architectures, and may be allocated on the stack or within another + * structure or class (see below for the Init and Finish functions to use). + * + * To decide whether to use double hashing vs. chaining, we need to develop a + * trade-off relation, as follows: + * + * Let alpha be the load factor, esize the entry size in words, count the + * entry count, and pow2 the power-of-two table size in entries. + * + * (JSDHashTable overhead) > (JSHashTable overhead) + * (unused table entry space) > (malloc and .next overhead per entry) + + * (buckets overhead) + * (1 - alpha) * esize * pow2 > 2 * count + pow2 + * + * Notice that alpha is by definition (count / pow2): + * + * (1 - alpha) * esize * pow2 > 2 * alpha * pow2 + pow2 + * (1 - alpha) * esize > 2 * alpha + 1 + * + * esize > (1 + 2 * alpha) / (1 - alpha) + * + * This assumes both tables must keep keyHash, key, and value for each entry, + * where key and value point to separately allocated strings or structures. + * If key and value can be combined into one pointer, then the trade-off is: + * + * esize > (1 + 3 * alpha) / (1 - alpha) + * + * If the entry value can be a subtype of JSDHashEntryHdr, rather than a type + * that must be allocated separately and referenced by an entry.value pointer + * member, and provided key's allocation can be fused with its entry's, then + * k (the words wasted per entry with chaining) is 4. + * + * To see these curves, feed gnuplot input like so: + * + * gnuplot> f(x,k) = (1 + k * x) / (1 - x) + * gnuplot> plot [0:.75] f(x,2), f(x,3), f(x,4) + * + * For k of 2 and a well-loaded table (alpha > .5), esize must be more than 4 + * words for chaining to be more space-efficient than double hashing. + * + * Solving for alpha helps us decide when to shrink an underloaded table: + * + * esize > (1 + k * alpha) / (1 - alpha) + * esize - alpha * esize > 1 + k * alpha + * esize - 1 > (k + esize) * alpha + * (esize - 1) / (k + esize) > alpha + * + * alpha < (esize - 1) / (esize + k) + * + * Therefore double hashing should keep alpha >= (esize - 1) / (esize + k), + * assuming esize is not too large (in which case, chaining should probably be + * used for any alpha). For esize=2 and k=3, we want alpha >= .2; for esize=3 + * and k=2, we want alpha >= .4. For k=4, esize could be 6, and alpha >= .5 + * would still obtain. See the JS_DHASH_MIN_ALPHA macro further below. + * + * The current implementation uses a configurable lower bound on alpha, which + * defaults to .25, when deciding to shrink the table (while still respecting + * JS_DHASH_MIN_SIZE). + * + * Note a qualitative difference between chaining and double hashing: under + * chaining, entry addresses are stable across table shrinks and grows. With + * double hashing, you can't safely hold an entry pointer and use it after an + * ADD or REMOVE operation, unless you sample table->generation before adding + * or removing, and compare the sample after, dereferencing the entry pointer + * only if table->generation has not changed. + * + * The moral of this story: there is no one-size-fits-all hash table scheme, + * but for small table entry size, and assuming entry address stability is not + * required, double hashing wins. + */ +struct JSDHashTable { + const JSDHashTableOps *ops; /* virtual operations, see below */ + void *data; /* ops- and instance-specific data */ + int16 hashShift; /* multiplicative hash shift */ + uint8 maxAlphaFrac; /* 8-bit fixed point max alpha */ + uint8 minAlphaFrac; /* 8-bit fixed point min alpha */ + uint32 entrySize; /* number of bytes in an entry */ + uint32 entryCount; /* number of entries in table */ + uint32 removedCount; /* removed entry sentinels in table */ + uint32 generation; /* entry storage generation number */ + char *entryStore; /* entry storage */ +#ifdef JS_DHASHMETER + struct JSDHashStats { + uint32 searches; /* total number of table searches */ + uint32 steps; /* hash chain links traversed */ + uint32 hits; /* searches that found key */ + uint32 misses; /* searches that didn't find key */ + uint32 lookups; /* number of JS_DHASH_LOOKUPs */ + uint32 addMisses; /* adds that miss, and do work */ + uint32 addOverRemoved; /* adds that recycled a removed entry */ + uint32 addHits; /* adds that hit an existing entry */ + uint32 addFailures; /* out-of-memory during add growth */ + uint32 removeHits; /* removes that hit, and do work */ + uint32 removeMisses; /* useless removes that miss */ + uint32 removeFrees; /* removes that freed entry directly */ + uint32 removeEnums; /* removes done by Enumerate */ + uint32 grows; /* table expansions */ + uint32 shrinks; /* table contractions */ + uint32 compresses; /* table compressions */ + uint32 enumShrinks; /* contractions after Enumerate */ + } stats; +#endif +}; + +/* + * Size in entries (gross, not net of free and removed sentinels) for table. + * We store hashShift rather than sizeLog2 to optimize the collision-free case + * in SearchTable. + */ +#define JS_DHASH_TABLE_SIZE(table) JS_BIT(JS_DHASH_BITS - (table)->hashShift) + +/* + * Table space at entryStore is allocated and freed using these callbacks. + * The allocator should return null on error only (not if called with nbytes + * equal to 0; but note that jsdhash.c code will never call with 0 nbytes). + */ +typedef void * +(* JS_DLL_CALLBACK JSDHashAllocTable)(JSDHashTable *table, uint32 nbytes); + +typedef void +(* JS_DLL_CALLBACK JSDHashFreeTable) (JSDHashTable *table, void *ptr); + +/* + * When a table grows or shrinks, each entry is queried for its key using this + * callback. NB: in that event, entry is not in table any longer; it's in the + * old entryStore vector, which is due to be freed once all entries have been + * moved via moveEntry callbacks. + */ +typedef const void * +(* JS_DLL_CALLBACK JSDHashGetKey) (JSDHashTable *table, + JSDHashEntryHdr *entry); + +/* + * Compute the hash code for a given key to be looked up, added, or removed + * from table. A hash code may have any JSDHashNumber value. + */ +typedef JSDHashNumber +(* JS_DLL_CALLBACK JSDHashHashKey) (JSDHashTable *table, const void *key); + +/* + * Compare the key identifying entry in table with the provided key parameter. + * Return JS_TRUE if keys match, JS_FALSE otherwise. + */ +typedef JSBool +(* JS_DLL_CALLBACK JSDHashMatchEntry)(JSDHashTable *table, + const JSDHashEntryHdr *entry, + const void *key); + +/* + * Copy the data starting at from to the new entry storage at to. Do not add + * reference counts for any strong references in the entry, however, as this + * is a "move" operation: the old entry storage at from will be freed without + * any reference-decrementing callback shortly. + */ +typedef void +(* JS_DLL_CALLBACK JSDHashMoveEntry)(JSDHashTable *table, + const JSDHashEntryHdr *from, + JSDHashEntryHdr *to); + +/* + * Clear the entry and drop any strong references it holds. This callback is + * invoked during a JS_DHASH_REMOVE operation (see below for operation codes), + * but only if the given key is found in the table. + */ +typedef void +(* JS_DLL_CALLBACK JSDHashClearEntry)(JSDHashTable *table, + JSDHashEntryHdr *entry); + +/* + * Called when a table (whether allocated dynamically by itself, or nested in + * a larger structure, or allocated on the stack) is finished. This callback + * allows table->ops-specific code to finalize table->data. + */ +typedef void +(* JS_DLL_CALLBACK JSDHashFinalize) (JSDHashTable *table); + +/* + * Initialize a new entry, apart from keyHash. This function is called when + * JS_DHashTableOperate's JS_DHASH_ADD case finds no existing entry for the + * given key, and must add a new one. At that point, entry->keyHash is not + * set yet, to avoid claiming the last free entry in a severely overloaded + * table. + */ +typedef JSBool +(* JS_DLL_CALLBACK JSDHashInitEntry)(JSDHashTable *table, + JSDHashEntryHdr *entry, + const void *key); + +/* + * Finally, the "vtable" structure for JSDHashTable. The first eight hooks + * must be provided by implementations; they're called unconditionally by the + * generic jsdhash.c code. Hooks after these may be null. + * + * Summary of allocation-related hook usage with C++ placement new emphasis: + * allocTable Allocate raw bytes with malloc, no ctors run. + * freeTable Free raw bytes with free, no dtors run. + * initEntry Call placement new using default key-based ctor. + * Return JS_TRUE on success, JS_FALSE on error. + * moveEntry Call placement new using copy ctor, run dtor on old + * entry storage. + * clearEntry Run dtor on entry. + * finalize Stub unless table->data was initialized and needs to + * be finalized. + * + * Note the reason why initEntry is optional: the default hooks (stubs) clear + * entry storage: On successful JS_DHashTableOperate(tbl, key, JS_DHASH_ADD), + * the returned entry pointer addresses an entry struct whose keyHash member + * has been set non-zero, but all other entry members are still clear (null). + * JS_DHASH_ADD callers can test such members to see whether the entry was + * newly created by the JS_DHASH_ADD call that just succeeded. If placement + * new or similar initialization is required, define an initEntry hook. Of + * course, the clearEntry hook must zero or null appropriately. + * + * XXX assumes 0 is null for pointer types. + */ +struct JSDHashTableOps { + /* Mandatory hooks. All implementations must provide these. */ + JSDHashAllocTable allocTable; + JSDHashFreeTable freeTable; + JSDHashGetKey getKey; + JSDHashHashKey hashKey; + JSDHashMatchEntry matchEntry; + JSDHashMoveEntry moveEntry; + JSDHashClearEntry clearEntry; + JSDHashFinalize finalize; + + /* Optional hooks start here. If null, these are not called. */ + JSDHashInitEntry initEntry; +}; + +/* + * Default implementations for the above ops. + */ +extern JS_PUBLIC_API(void *) +JS_DHashAllocTable(JSDHashTable *table, uint32 nbytes); + +extern JS_PUBLIC_API(void) +JS_DHashFreeTable(JSDHashTable *table, void *ptr); + +extern JS_PUBLIC_API(JSDHashNumber) +JS_DHashStringKey(JSDHashTable *table, const void *key); + +/* A minimal entry contains a keyHash header and a void key pointer. */ +struct JSDHashEntryStub { + JSDHashEntryHdr hdr; + const void *key; +}; + +extern JS_PUBLIC_API(const void *) +JS_DHashGetKeyStub(JSDHashTable *table, JSDHashEntryHdr *entry); + +extern JS_PUBLIC_API(JSDHashNumber) +JS_DHashVoidPtrKeyStub(JSDHashTable *table, const void *key); + +extern JS_PUBLIC_API(JSBool) +JS_DHashMatchEntryStub(JSDHashTable *table, + const JSDHashEntryHdr *entry, + const void *key); + +extern JS_PUBLIC_API(JSBool) +JS_DHashMatchStringKey(JSDHashTable *table, + const JSDHashEntryHdr *entry, + const void *key); + +extern JS_PUBLIC_API(void) +JS_DHashMoveEntryStub(JSDHashTable *table, + const JSDHashEntryHdr *from, + JSDHashEntryHdr *to); + +extern JS_PUBLIC_API(void) +JS_DHashClearEntryStub(JSDHashTable *table, JSDHashEntryHdr *entry); + +extern JS_PUBLIC_API(void) +JS_DHashFreeStringKey(JSDHashTable *table, JSDHashEntryHdr *entry); + +extern JS_PUBLIC_API(void) +JS_DHashFinalizeStub(JSDHashTable *table); + +/* + * If you use JSDHashEntryStub or a subclass of it as your entry struct, and + * if your entries move via memcpy and clear via memset(0), you can use these + * stub operations. + */ +extern JS_PUBLIC_API(const JSDHashTableOps *) +JS_DHashGetStubOps(void); + +/* + * Dynamically allocate a new JSDHashTable using malloc, initialize it using + * JS_DHashTableInit, and return its address. Return null on malloc failure. + * Note that the entry storage at table->entryStore will be allocated using + * the ops->allocTable callback. + */ +extern JS_PUBLIC_API(JSDHashTable *) +JS_NewDHashTable(const JSDHashTableOps *ops, void *data, uint32 entrySize, + uint32 capacity); + +/* + * Finalize table's data, free its entry storage (via table->ops->freeTable), + * and return the memory starting at table to the malloc heap. + */ +extern JS_PUBLIC_API(void) +JS_DHashTableDestroy(JSDHashTable *table); + +/* + * Initialize table with ops, data, entrySize, and capacity. Capacity is a + * guess for the smallest table size at which the table will usually be less + * than 75% loaded (the table will grow or shrink as needed; capacity serves + * only to avoid inevitable early growth from JS_DHASH_MIN_SIZE). + */ +extern JS_PUBLIC_API(JSBool) +JS_DHashTableInit(JSDHashTable *table, const JSDHashTableOps *ops, void *data, + uint32 entrySize, uint32 capacity); + +/* + * Set maximum and minimum alpha for table. The defaults are 0.75 and .25. + * maxAlpha must be in [0.5, 0.9375] for the default JS_DHASH_MIN_SIZE; or if + * MinSize=JS_DHASH_MIN_SIZE <= 256, in [0.5, (float)(MinSize-1)/MinSize]; or + * else in [0.5, 255.0/256]. minAlpha must be in [0, maxAlpha / 2), so that + * we don't shrink on the very next remove after growing a table upon adding + * an entry that brings entryCount past maxAlpha * tableSize. + */ +JS_PUBLIC_API(void) +JS_DHashTableSetAlphaBounds(JSDHashTable *table, + float maxAlpha, + float minAlpha); + +/* + * Call this macro with k, the number of pointer-sized words wasted per entry + * under chaining, to compute the minimum alpha at which double hashing still + * beats chaining. + */ +#define JS_DHASH_MIN_ALPHA(table, k) \ + ((float)((table)->entrySize / sizeof(void *) - 1) \ + / ((table)->entrySize / sizeof(void *) + (k))) + +/* + * Finalize table's data, free its entry storage using table->ops->freeTable, + * and leave its members unchanged from their last live values (which leaves + * pointers dangling). If you want to burn cycles clearing table, it's up to + * your code to call memset. + */ +extern JS_PUBLIC_API(void) +JS_DHashTableFinish(JSDHashTable *table); + +/* + * To consolidate keyHash computation and table grow/shrink code, we use a + * single entry point for lookup, add, and remove operations. The operation + * codes are declared here, along with codes returned by JSDHashEnumerator + * functions, which control JS_DHashTableEnumerate's behavior. + */ +typedef enum JSDHashOperator { + JS_DHASH_LOOKUP = 0, /* lookup entry */ + JS_DHASH_ADD = 1, /* add entry */ + JS_DHASH_REMOVE = 2, /* remove entry, or enumerator says remove */ + JS_DHASH_NEXT = 0, /* enumerator says continue */ + JS_DHASH_STOP = 1 /* enumerator says stop */ +} JSDHashOperator; + +/* + * To lookup a key in table, call: + * + * entry = JS_DHashTableOperate(table, key, JS_DHASH_LOOKUP); + * + * If JS_DHASH_ENTRY_IS_BUSY(entry) is true, key was found and it identifies + * entry. If JS_DHASH_ENTRY_IS_FREE(entry) is true, key was not found. + * + * To add an entry identified by key to table, call: + * + * entry = JS_DHashTableOperate(table, key, JS_DHASH_ADD); + * + * If entry is null upon return, then either the table is severely overloaded, + * and memory can't be allocated for entry storage via table->ops->allocTable; + * Or if table->ops->initEntry is non-null, the table->ops->initEntry op may + * have returned false. + * + * Otherwise, entry->keyHash has been set so that JS_DHASH_ENTRY_IS_BUSY(entry) + * is true, and it is up to the caller to initialize the key and value parts + * of the entry sub-type, if they have not been set already (i.e. if entry was + * not already in the table, and if the optional initEntry hook was not used). + * + * To remove an entry identified by key from table, call: + * + * (void) JS_DHashTableOperate(table, key, JS_DHASH_REMOVE); + * + * If key's entry is found, it is cleared (via table->ops->clearEntry) and + * the entry is marked so that JS_DHASH_ENTRY_IS_FREE(entry). This operation + * returns null unconditionally; you should ignore its return value. + */ +extern JS_PUBLIC_API(JSDHashEntryHdr *) +JS_DHashTableOperate(JSDHashTable *table, const void *key, JSDHashOperator op); + +/* + * Remove an entry already accessed via LOOKUP or ADD. + * + * NB: this is a "raw" or low-level routine, intended to be used only where + * the inefficiency of a full JS_DHashTableOperate (which rehashes in order + * to find the entry given its key) is not tolerable. This function does not + * shrink the table if it is underloaded. It does not update stats #ifdef + * JS_DHASHMETER, either. + */ +extern JS_PUBLIC_API(void) +JS_DHashTableRawRemove(JSDHashTable *table, JSDHashEntryHdr *entry); + +/* + * Enumerate entries in table using etor: + * + * count = JS_DHashTableEnumerate(table, etor, arg); + * + * JS_DHashTableEnumerate calls etor like so: + * + * op = etor(table, entry, number, arg); + * + * where number is a zero-based ordinal assigned to live entries according to + * their order in table->entryStore. + * + * The return value, op, is treated as a set of flags. If op is JS_DHASH_NEXT, + * then continue enumerating. If op contains JS_DHASH_REMOVE, then clear (via + * table->ops->clearEntry) and free entry. Then we check whether op contains + * JS_DHASH_STOP; if so, stop enumerating and return the number of live entries + * that were enumerated so far. Return the total number of live entries when + * enumeration completes normally. + * + * If etor calls JS_DHashTableOperate on table with op != JS_DHASH_LOOKUP, it + * must return JS_DHASH_STOP; otherwise undefined behavior results. + * + * If any enumerator returns JS_DHASH_REMOVE, table->entryStore may be shrunk + * or compressed after enumeration, but before JS_DHashTableEnumerate returns. + * Such an enumerator therefore can't safely set aside entry pointers, but an + * enumerator that never returns JS_DHASH_REMOVE can set pointers to entries + * aside, e.g., to avoid copying live entries into an array of the entry type. + * Copying entry pointers is cheaper, and safe so long as the caller of such a + * "stable" Enumerate doesn't use the set-aside pointers after any call either + * to PL_DHashTableOperate, or to an "unstable" form of Enumerate, which might + * grow or shrink entryStore. + * + * If your enumerator wants to remove certain entries, but set aside pointers + * to other entries that it retains, it can use JS_DHashTableRawRemove on the + * entries to be removed, returning JS_DHASH_NEXT to skip them. Likewise, if + * you want to remove entries, but for some reason you do not want entryStore + * to be shrunk or compressed, you can call JS_DHashTableRawRemove safely on + * the entry being enumerated, rather than returning JS_DHASH_REMOVE. + */ +typedef JSDHashOperator +(* JS_DLL_CALLBACK JSDHashEnumerator)(JSDHashTable *table, JSDHashEntryHdr *hdr, + uint32 number, void *arg); + +extern JS_PUBLIC_API(uint32) +JS_DHashTableEnumerate(JSDHashTable *table, JSDHashEnumerator etor, void *arg); + +#ifdef JS_DHASHMETER +#include + +extern JS_PUBLIC_API(void) +JS_DHashTableDumpMeter(JSDHashTable *table, JSDHashEnumerator dump, FILE *fp); +#endif + +JS_END_EXTERN_C + +#endif /* jsdhash_h___ */ diff --git a/src/dom/js/jsdtoa.c b/src/dom/js/jsdtoa.c new file mode 100644 index 000000000..2bd163d75 --- /dev/null +++ b/src/dom/js/jsdtoa.c @@ -0,0 +1,3155 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* + * Portable double to alphanumeric string and back converters. + */ +#include "jsstddef.h" +#include "jslibmath.h" +#include "jstypes.h" +#include "jsdtoa.h" +#include "jsprf.h" +#include "jsutil.h" /* Added by JSIFY */ +#include "jspubtd.h" +#include "jsnum.h" + +#ifdef JS_THREADSAFE +#include "prlock.h" +#endif + +/**************************************************************** + * + * The author of this software is David M. Gay. + * + * Copyright (c) 1991 by Lucent Technologies. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose without fee is hereby granted, provided that this entire notice + * is included in all copies of any software which is or includes a copy + * or modification of this software and in all copies of the supporting + * documentation for such software. + * + * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR LUCENT MAKES ANY + * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY + * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. + * + ***************************************************************/ + +/* Please send bug reports to + David M. Gay + Bell Laboratories, Room 2C-463 + 600 Mountain Avenue + Murray Hill, NJ 07974-0636 + U.S.A. + dmg@bell-labs.com + */ + +/* On a machine with IEEE extended-precision registers, it is + * necessary to specify double-precision (53-bit) rounding precision + * before invoking strtod or dtoa. If the machine uses (the equivalent + * of) Intel 80x87 arithmetic, the call + * _control87(PC_53, MCW_PC); + * does this with many compilers. Whether this or another call is + * appropriate depends on the compiler; for this to work, it may be + * necessary to #include "float.h" or another system-dependent header + * file. + */ + +/* strtod for IEEE-arithmetic machines. + * + * This strtod returns a nearest machine number to the input decimal + * string (or sets err to JS_DTOA_ERANGE or JS_DTOA_ENOMEM). With IEEE + * arithmetic, ties are broken by the IEEE round-even rule. Otherwise + * ties are broken by biased rounding (add half and chop). + * + * Inspired loosely by William D. Clinger's paper "How to Read Floating + * Point Numbers Accurately" [Proc. ACM SIGPLAN '90, pp. 92-101]. + * + * Modifications: + * + * 1. We only require IEEE double-precision + * arithmetic (not IEEE double-extended). + * 2. We get by with floating-point arithmetic in a case that + * Clinger missed -- when we're computing d * 10^n + * for a small integer d and the integer n is not too + * much larger than 22 (the maximum integer k for which + * we can represent 10^k exactly), we may be able to + * compute (d*10^k) * 10^(e-k) with just one roundoff. + * 3. Rather than a bit-at-a-time adjustment of the binary + * result in the hard case, we use floating-point + * arithmetic to determine the adjustment to within + * one bit; only in really hard cases do we need to + * compute a second residual. + * 4. Because of 3., we don't need a large table of powers of 10 + * for ten-to-e (just some small tables, e.g. of 10^k + * for 0 <= k <= 22). + */ + +/* + * #define IEEE_8087 for IEEE-arithmetic machines where the least + * significant byte has the lowest address. + * #define IEEE_MC68k for IEEE-arithmetic machines where the most + * significant byte has the lowest address. + * #define Long int on machines with 32-bit ints and 64-bit longs. + * #define Sudden_Underflow for IEEE-format machines without gradual + * underflow (i.e., that flush to zero on underflow). + * #define No_leftright to omit left-right logic in fast floating-point + * computation of js_dtoa. + * #define Check_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3. + * #define RND_PRODQUOT to use rnd_prod and rnd_quot (assembly routines + * that use extended-precision instructions to compute rounded + * products and quotients) with IBM. + * #define ROUND_BIASED for IEEE-format with biased rounding. + * #define Inaccurate_Divide for IEEE-format with correctly rounded + * products but inaccurate quotients, e.g., for Intel i860. + * #define JS_HAVE_LONG_LONG on machines that have a "long long" + * integer type (of >= 64 bits). If long long is available and the name is + * something other than "long long", #define Llong to be the name, + * and if "unsigned Llong" does not work as an unsigned version of + * Llong, #define #ULLong to be the corresponding unsigned type. + * #define Bad_float_h if your system lacks a float.h or if it does not + * define some or all of DBL_DIG, DBL_MAX_10_EXP, DBL_MAX_EXP, + * FLT_RADIX, FLT_ROUNDS, and DBL_MAX. + * #define MALLOC your_malloc, where your_malloc(n) acts like malloc(n) + * if memory is available and otherwise does something you deem + * appropriate. If MALLOC is undefined, malloc will be invoked + * directly -- and assumed always to succeed. + * #define Omit_Private_Memory to omit logic (added Jan. 1998) for making + * memory allocations from a private pool of memory when possible. + * When used, the private pool is PRIVATE_MEM bytes long: 2000 bytes, + * unless #defined to be a different length. This default length + * suffices to get rid of MALLOC calls except for unusual cases, + * such as decimal-to-binary conversion of a very long string of + * digits. + * #define INFNAN_CHECK on IEEE systems to cause strtod to check for + * Infinity and NaN (case insensitively). On some systems (e.g., + * some HP systems), it may be necessary to #define NAN_WORD0 + * appropriately -- to the most significant word of a quiet NaN. + * (On HP Series 700/800 machines, -DNAN_WORD0=0x7ff40000 works.) + * #define MULTIPLE_THREADS if the system offers preemptively scheduled + * multiple threads. In this case, you must provide (or suitably + * #define) two locks, acquired by ACQUIRE_DTOA_LOCK() and released + * by RELEASE_DTOA_LOCK(). (The second lock, accessed + * in pow5mult, ensures lazy evaluation of only one copy of high + * powers of 5; omitting this lock would introduce a small + * probability of wasting memory, but would otherwise be harmless.) + * You must also invoke freedtoa(s) to free the value s returned by + * dtoa. You may do so whether or not MULTIPLE_THREADS is #defined. + * #define NO_IEEE_Scale to disable new (Feb. 1997) logic in strtod that + * avoids underflows on inputs whose result does not underflow. + */ +#ifdef IS_LITTLE_ENDIAN +#define IEEE_8087 +#else +#define IEEE_MC68k +#endif + +#ifndef Long +#define Long int32 +#endif + +#ifndef ULong +#define ULong uint32 +#endif + +#define Bug(errorMessageString) JS_ASSERT(!errorMessageString) + +#include "stdlib.h" +#include "string.h" + +#ifdef MALLOC +extern void *MALLOC(size_t); +#else +#define MALLOC malloc +#endif + +#define Omit_Private_Memory +/* Private memory currently doesn't work with JS_THREADSAFE */ +#ifndef Omit_Private_Memory +#ifndef PRIVATE_MEM +#define PRIVATE_MEM 2000 +#endif +#define PRIVATE_mem ((PRIVATE_MEM+sizeof(double)-1)/sizeof(double)) +static double private_mem[PRIVATE_mem], *pmem_next = private_mem; +#endif + +#ifdef Bad_float_h +#undef __STDC__ + +#define DBL_DIG 15 +#define DBL_MAX_10_EXP 308 +#define DBL_MAX_EXP 1024 +#define FLT_RADIX 2 +#define FLT_ROUNDS 1 +#define DBL_MAX 1.7976931348623157e+308 + + + +#ifndef LONG_MAX +#define LONG_MAX 2147483647 +#endif + +#else /* ifndef Bad_float_h */ +#include "float.h" +/* + * MacOS 10.2 defines the macro FLT_ROUNDS to an internal function + * which does not exist on 10.1. We can safely #define it to 1 here + * to allow 10.2 builds to run on 10.1, since we can't use fesetround() + * (which does not exist on 10.1 either). + */ +#if defined(MACOS_DEPLOYMENT_TARGET) && (MACOS_DEPLOYMENT_TARGET < 100200) +#undef FLT_ROUNDS +#define FLT_ROUNDS 1 +#endif +#endif /* Bad_float_h */ + +#ifndef __MATH_H__ +#include "math.h" +#endif + +#ifndef CONST +#define CONST const +#endif + +#if defined(IEEE_8087) + defined(IEEE_MC68k) != 1 +Exactly one of IEEE_8087 or IEEE_MC68k should be defined. +#endif + +#define word0(x) JSDOUBLE_HI32(x) +#define set_word0(x, y) JSDOUBLE_SET_HI32(x, y) +#define word1(x) JSDOUBLE_LO32(x) +#define set_word1(x, y) JSDOUBLE_SET_LO32(x, y) + +#define Storeinc(a,b,c) (*(a)++ = (b) << 16 | (c) & 0xffff) + +/* #define P DBL_MANT_DIG */ +/* Ten_pmax = floor(P*log(2)/log(5)) */ +/* Bletch = (highest power of 2 < DBL_MAX_10_EXP) / 16 */ +/* Quick_max = floor((P-1)*log(FLT_RADIX)/log(10) - 1) */ +/* Int_max = floor(P*log(FLT_RADIX)/log(10) - 1) */ + +#define Exp_shift 20 +#define Exp_shift1 20 +#define Exp_msk1 0x100000 +#define Exp_msk11 0x100000 +#define Exp_mask 0x7ff00000 +#define P 53 +#define Bias 1023 +#define Emin (-1022) +#define Exp_1 0x3ff00000 +#define Exp_11 0x3ff00000 +#define Ebits 11 +#define Frac_mask 0xfffff +#define Frac_mask1 0xfffff +#define Ten_pmax 22 +#define Bletch 0x10 +#define Bndry_mask 0xfffff +#define Bndry_mask1 0xfffff +#define LSB 1 +#define Sign_bit 0x80000000 +#define Log2P 1 +#define Tiny0 0 +#define Tiny1 1 +#define Quick_max 14 +#define Int_max 14 +#define Infinite(x) (word0(x) == 0x7ff00000) /* sufficient test for here */ +#ifndef NO_IEEE_Scale +#define Avoid_Underflow +#endif + + + +#ifdef RND_PRODQUOT +#define rounded_product(a,b) a = rnd_prod(a, b) +#define rounded_quotient(a,b) a = rnd_quot(a, b) +extern double rnd_prod(double, double), rnd_quot(double, double); +#else +#define rounded_product(a,b) a *= b +#define rounded_quotient(a,b) a /= b +#endif + +#define Big0 (Frac_mask1 | Exp_msk1*(DBL_MAX_EXP+Bias-1)) +#define Big1 0xffffffff + +#ifndef JS_HAVE_LONG_LONG +#undef ULLong +#else /* long long available */ +#ifndef Llong +#define Llong JSInt64 +#endif +#ifndef ULLong +#define ULLong JSUint64 +#endif +#endif /* JS_HAVE_LONG_LONG */ + +#ifdef JS_THREADSAFE +#define MULTIPLE_THREADS +static PRLock *freelist_lock; +#define ACQUIRE_DTOA_LOCK() \ + JS_BEGIN_MACRO \ + if (!initialized) \ + InitDtoa(); \ + PR_Lock(freelist_lock); \ + JS_END_MACRO +#define RELEASE_DTOA_LOCK() PR_Unlock(freelist_lock) +#else +#undef MULTIPLE_THREADS +#define ACQUIRE_DTOA_LOCK() /*nothing*/ +#define RELEASE_DTOA_LOCK() /*nothing*/ +#endif + +#define Kmax 15 + +struct Bigint { + struct Bigint *next; /* Free list link */ + int32 k; /* lg2(maxwds) */ + int32 maxwds; /* Number of words allocated for x */ + int32 sign; /* Zero if positive, 1 if negative. Ignored by most Bigint routines! */ + int32 wds; /* Actual number of words. If value is nonzero, the most significant word must be nonzero. */ + ULong x[1]; /* wds words of number in little endian order */ +}; + +#ifdef ENABLE_OOM_TESTING +/* Out-of-memory testing. Use a good testcase (over and over) and then use + * these routines to cause a memory failure on every possible Balloc allocation, + * to make sure that all out-of-memory paths can be followed. See bug 14044. + */ + +static int allocationNum; /* which allocation is next? */ +static int desiredFailure; /* which allocation should fail? */ + +/** + * js_BigintTestingReset + * + * Call at the beginning of a test run to set the allocation failure position. + * (Set to 0 to just have the engine count allocations without failing.) + */ +JS_PUBLIC_API(void) +js_BigintTestingReset(int newFailure) +{ + allocationNum = 0; + desiredFailure = newFailure; +} + +/** + * js_BigintTestingWhere + * + * Report the current allocation position. This is really only useful when you + * want to learn how many allocations a test run has. + */ +JS_PUBLIC_API(int) +js_BigintTestingWhere() +{ + return allocationNum; +} + + +/* + * So here's what you do: Set up a fantastic test case that exercises the + * elements of the code you wish. Set the failure point at 0 and run the test, + * then get the allocation position. This number is the number of allocations + * your test makes. Now loop from 1 to that number, setting the failure point + * at each loop count, and run the test over and over, causing failures at each + * step. Any memory failure *should* cause a Out-Of-Memory exception; if it + * doesn't, then there's still an error here. + */ +#endif + +typedef struct Bigint Bigint; + +static Bigint *freelist[Kmax+1]; + +/* + * Allocate a Bigint with 2^k words. + * This is not threadsafe. The caller must use thread locks + */ +static Bigint *Balloc(int32 k) +{ + int32 x; + Bigint *rv; +#ifndef Omit_Private_Memory + uint32 len; +#endif + +#ifdef ENABLE_OOM_TESTING + if (++allocationNum == desiredFailure) { + printf("Forced Failing Allocation number %d\n", allocationNum); + return NULL; + } +#endif + + if ((rv = freelist[k]) != NULL) + freelist[k] = rv->next; + if (rv == NULL) { + x = 1 << k; +#ifdef Omit_Private_Memory + rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(ULong)); +#else + len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1) + /sizeof(double); + if (pmem_next - private_mem + len <= PRIVATE_mem) { + rv = (Bigint*)pmem_next; + pmem_next += len; + } + else + rv = (Bigint*)MALLOC(len*sizeof(double)); +#endif + if (!rv) + return NULL; + rv->k = k; + rv->maxwds = x; + } + rv->sign = rv->wds = 0; + return rv; +} + +static void Bfree(Bigint *v) +{ + if (v) { + v->next = freelist[v->k]; + freelist[v->k] = v; + } +} + +#define Bcopy(x,y) memcpy((char *)&x->sign, (char *)&y->sign, \ + y->wds*sizeof(Long) + 2*sizeof(int32)) + +/* Return b*m + a. Deallocate the old b. Both a and m must be between 0 and + * 65535 inclusive. NOTE: old b is deallocated on memory failure. + */ +static Bigint *multadd(Bigint *b, int32 m, int32 a) +{ + int32 i, wds; +#ifdef ULLong + ULong *x; + ULLong carry, y; +#else + ULong carry, *x, y; + ULong xi, z; +#endif + Bigint *b1; + +#ifdef ENABLE_OOM_TESTING + if (++allocationNum == desiredFailure) { + /* Faux allocation, because I'm not getting all of the failure paths + * without it. + */ + printf("Forced Failing Allocation number %d\n", allocationNum); + Bfree(b); + return NULL; + } +#endif + + wds = b->wds; + x = b->x; + i = 0; + carry = a; + do { +#ifdef ULLong + y = *x * (ULLong)m + carry; + carry = y >> 32; + *x++ = (ULong)(y & 0xffffffffUL); +#else + xi = *x; + y = (xi & 0xffff) * m + carry; + z = (xi >> 16) * m + (y >> 16); + carry = z >> 16; + *x++ = (z << 16) + (y & 0xffff); +#endif + } + while(++i < wds); + if (carry) { + if (wds >= b->maxwds) { + b1 = Balloc(b->k+1); + if (!b1) { + Bfree(b); + return NULL; + } + Bcopy(b1, b); + Bfree(b); + b = b1; + } + b->x[wds++] = (ULong)carry; + b->wds = wds; + } + return b; +} + +static Bigint *s2b(CONST char *s, int32 nd0, int32 nd, ULong y9) +{ + Bigint *b; + int32 i, k; + Long x, y; + + x = (nd + 8) / 9; + for(k = 0, y = 1; x > y; y <<= 1, k++) ; + b = Balloc(k); + if (!b) + return NULL; + b->x[0] = y9; + b->wds = 1; + + i = 9; + if (9 < nd0) { + s += 9; + do { + b = multadd(b, 10, *s++ - '0'); + if (!b) + return NULL; + } while(++i < nd0); + s++; + } + else + s += 10; + for(; i < nd; i++) { + b = multadd(b, 10, *s++ - '0'); + if (!b) + return NULL; + } + return b; +} + + +/* Return the number (0 through 32) of most significant zero bits in x. */ +static int32 hi0bits(register ULong x) +{ + register int32 k = 0; + + if (!(x & 0xffff0000)) { + k = 16; + x <<= 16; + } + if (!(x & 0xff000000)) { + k += 8; + x <<= 8; + } + if (!(x & 0xf0000000)) { + k += 4; + x <<= 4; + } + if (!(x & 0xc0000000)) { + k += 2; + x <<= 2; + } + if (!(x & 0x80000000)) { + k++; + if (!(x & 0x40000000)) + return 32; + } + return k; +} + + +/* Return the number (0 through 32) of least significant zero bits in y. + * Also shift y to the right past these 0 through 32 zeros so that y's + * least significant bit will be set unless y was originally zero. */ +static int32 lo0bits(ULong *y) +{ + register int32 k; + register ULong x = *y; + + if (x & 7) { + if (x & 1) + return 0; + if (x & 2) { + *y = x >> 1; + return 1; + } + *y = x >> 2; + return 2; + } + k = 0; + if (!(x & 0xffff)) { + k = 16; + x >>= 16; + } + if (!(x & 0xff)) { + k += 8; + x >>= 8; + } + if (!(x & 0xf)) { + k += 4; + x >>= 4; + } + if (!(x & 0x3)) { + k += 2; + x >>= 2; + } + if (!(x & 1)) { + k++; + x >>= 1; + if (!x & 1) + return 32; + } + *y = x; + return k; +} + +/* Return a new Bigint with the given integer value, which must be nonnegative. */ +static Bigint *i2b(int32 i) +{ + Bigint *b; + + b = Balloc(1); + if (!b) + return NULL; + b->x[0] = i; + b->wds = 1; + return b; +} + +/* Return a newly allocated product of a and b. */ +static Bigint *mult(CONST Bigint *a, CONST Bigint *b) +{ + CONST Bigint *t; + Bigint *c; + int32 k, wa, wb, wc; + ULong y; + ULong *xc, *xc0, *xce; + CONST ULong *x, *xa, *xae, *xb, *xbe; +#ifdef ULLong + ULLong carry, z; +#else + ULong carry, z; + ULong z2; +#endif + + if (a->wds < b->wds) { + t = a; + a = b; + b = t; + } + k = a->k; + wa = a->wds; + wb = b->wds; + wc = wa + wb; + if (wc > a->maxwds) + k++; + c = Balloc(k); + if (!c) + return NULL; + for(xc = c->x, xce = xc + wc; xc < xce; xc++) + *xc = 0; + xa = a->x; + xae = xa + wa; + xb = b->x; + xbe = xb + wb; + xc0 = c->x; +#ifdef ULLong + for(; xb < xbe; xc0++) { + if ((y = *xb++) != 0) { + x = xa; + xc = xc0; + carry = 0; + do { + z = *x++ * (ULLong)y + *xc + carry; + carry = z >> 32; + *xc++ = (ULong)(z & 0xffffffffUL); + } + while(x < xae); + *xc = (ULong)carry; + } + } +#else + for(; xb < xbe; xb++, xc0++) { + if ((y = *xb & 0xffff) != 0) { + x = xa; + xc = xc0; + carry = 0; + do { + z = (*x & 0xffff) * y + (*xc & 0xffff) + carry; + carry = z >> 16; + z2 = (*x++ >> 16) * y + (*xc >> 16) + carry; + carry = z2 >> 16; + Storeinc(xc, z2, z); + } + while(x < xae); + *xc = carry; + } + if ((y = *xb >> 16) != 0) { + x = xa; + xc = xc0; + carry = 0; + z2 = *xc; + do { + z = (*x & 0xffff) * y + (*xc >> 16) + carry; + carry = z >> 16; + Storeinc(xc, z, z2); + z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry; + carry = z2 >> 16; + } + while(x < xae); + *xc = z2; + } + } +#endif + for(xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ; + c->wds = wc; + return c; +} + +/* + * 'p5s' points to a linked list of Bigints that are powers of 5. + * This list grows on demand, and it can only grow: it won't change + * in any other way. So if we read 'p5s' or the 'next' field of + * some Bigint on the list, and it is not NULL, we know it won't + * change to NULL or some other value. Only when the value of + * 'p5s' or 'next' is NULL do we need to acquire the lock and add + * a new Bigint to the list. + */ + +static Bigint *p5s; + +#ifdef JS_THREADSAFE +static PRLock *p5s_lock; +#endif + +/* Return b * 5^k. Deallocate the old b. k must be nonnegative. */ +/* NOTE: old b is deallocated on memory failure. */ +static Bigint *pow5mult(Bigint *b, int32 k) +{ + Bigint *b1, *p5, *p51; + int32 i; + static CONST int32 p05[3] = { 5, 25, 125 }; + + if ((i = k & 3) != 0) { + b = multadd(b, p05[i-1], 0); + if (!b) + return NULL; + } + + if (!(k >>= 2)) + return b; + if (!(p5 = p5s)) { +#ifdef JS_THREADSAFE + /* + * We take great care to not call i2b() and Bfree() + * while holding the lock. + */ + Bigint *wasted_effort = NULL; + p5 = i2b(625); + if (!p5) { + Bfree(b); + return NULL; + } + /* lock and check again */ + PR_Lock(p5s_lock); + if (!p5s) { + /* first time */ + p5s = p5; + p5->next = 0; + } else { + /* some other thread just beat us */ + wasted_effort = p5; + p5 = p5s; + } + PR_Unlock(p5s_lock); + if (wasted_effort) { + Bfree(wasted_effort); + } +#else + /* first time */ + p5 = p5s = i2b(625); + if (!p5) { + Bfree(b); + return NULL; + } + p5->next = 0; +#endif + } + for(;;) { + if (k & 1) { + b1 = mult(b, p5); + Bfree(b); + if (!b1) + return NULL; + b = b1; + } + if (!(k >>= 1)) + break; + if (!(p51 = p5->next)) { +#ifdef JS_THREADSAFE + Bigint *wasted_effort = NULL; + p51 = mult(p5, p5); + if (!p51) { + Bfree(b); + return NULL; + } + PR_Lock(p5s_lock); + if (!p5->next) { + p5->next = p51; + p51->next = 0; + } else { + wasted_effort = p51; + p51 = p5->next; + } + PR_Unlock(p5s_lock); + if (wasted_effort) { + Bfree(wasted_effort); + } +#else + p51 = mult(p5,p5); + if (!p51) { + Bfree(b); + return NULL; + } + p51->next = 0; + p5->next = p51; +#endif + } + p5 = p51; + } + return b; +} + +/* Return b * 2^k. Deallocate the old b. k must be nonnegative. + * NOTE: on memory failure, old b is deallocated. */ +static Bigint *lshift(Bigint *b, int32 k) +{ + int32 i, k1, n, n1; + Bigint *b1; + ULong *x, *x1, *xe, z; + + n = k >> 5; + k1 = b->k; + n1 = n + b->wds + 1; + for(i = b->maxwds; n1 > i; i <<= 1) + k1++; + b1 = Balloc(k1); + if (!b1) + goto done; + x1 = b1->x; + for(i = 0; i < n; i++) + *x1++ = 0; + x = b->x; + xe = x + b->wds; + if (k &= 0x1f) { + k1 = 32 - k; + z = 0; + do { + *x1++ = *x << k | z; + z = *x++ >> k1; + } + while(x < xe); + if ((*x1 = z) != 0) + ++n1; + } + else do + *x1++ = *x++; + while(x < xe); + b1->wds = n1 - 1; +done: + Bfree(b); + return b1; +} + +/* Return -1, 0, or 1 depending on whether ab, respectively. */ +static int32 cmp(Bigint *a, Bigint *b) +{ + ULong *xa, *xa0, *xb, *xb0; + int32 i, j; + + i = a->wds; + j = b->wds; +#ifdef DEBUG + if (i > 1 && !a->x[i-1]) + Bug("cmp called with a->x[a->wds-1] == 0"); + if (j > 1 && !b->x[j-1]) + Bug("cmp called with b->x[b->wds-1] == 0"); +#endif + if (i -= j) + return i; + xa0 = a->x; + xa = xa0 + j; + xb0 = b->x; + xb = xb0 + j; + for(;;) { + if (*--xa != *--xb) + return *xa < *xb ? -1 : 1; + if (xa <= xa0) + break; + } + return 0; +} + +static Bigint *diff(Bigint *a, Bigint *b) +{ + Bigint *c; + int32 i, wa, wb; + ULong *xa, *xae, *xb, *xbe, *xc; +#ifdef ULLong + ULLong borrow, y; +#else + ULong borrow, y; + ULong z; +#endif + + i = cmp(a,b); + if (!i) { + c = Balloc(0); + if (!c) + return NULL; + c->wds = 1; + c->x[0] = 0; + return c; + } + if (i < 0) { + c = a; + a = b; + b = c; + i = 1; + } + else + i = 0; + c = Balloc(a->k); + if (!c) + return NULL; + c->sign = i; + wa = a->wds; + xa = a->x; + xae = xa + wa; + wb = b->wds; + xb = b->x; + xbe = xb + wb; + xc = c->x; + borrow = 0; +#ifdef ULLong + do { + y = (ULLong)*xa++ - *xb++ - borrow; + borrow = y >> 32 & 1UL; + *xc++ = (ULong)(y & 0xffffffffUL); + } + while(xb < xbe); + while(xa < xae) { + y = *xa++ - borrow; + borrow = y >> 32 & 1UL; + *xc++ = (ULong)(y & 0xffffffffUL); + } +#else + do { + y = (*xa & 0xffff) - (*xb & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + z = (*xa++ >> 16) - (*xb++ >> 16) - borrow; + borrow = (z & 0x10000) >> 16; + Storeinc(xc, z, y); + } + while(xb < xbe); + while(xa < xae) { + y = (*xa & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + z = (*xa++ >> 16) - borrow; + borrow = (z & 0x10000) >> 16; + Storeinc(xc, z, y); + } +#endif + while(!*--xc) + wa--; + c->wds = wa; + return c; +} + +/* Return the absolute difference between x and the adjacent greater-magnitude double number (ignoring exponent overflows). */ +static double ulp(double x) +{ + register Long L; + double a; + + L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1; +#ifndef Sudden_Underflow + if (L > 0) { +#endif + set_word0(a, L); + set_word1(a, 0); +#ifndef Sudden_Underflow + } + else { + L = -L >> Exp_shift; + if (L < Exp_shift) { + set_word0(a, 0x80000 >> L); + set_word1(a, 0); + } + else { + set_word0(a, 0); + L -= Exp_shift; + set_word1(a, L >= 31 ? 1 : 1 << (31 - L)); + } + } +#endif + return a; +} + + +static double b2d(Bigint *a, int32 *e) +{ + ULong *xa, *xa0, w, y, z; + int32 k; + double d; +#define d0 word0(d) +#define d1 word1(d) +#define set_d0(x) set_word0(d, x) +#define set_d1(x) set_word1(d, x) + + xa0 = a->x; + xa = xa0 + a->wds; + y = *--xa; +#ifdef DEBUG + if (!y) Bug("zero y in b2d"); +#endif + k = hi0bits(y); + *e = 32 - k; + if (k < Ebits) { + set_d0(Exp_1 | y >> (Ebits - k)); + w = xa > xa0 ? *--xa : 0; + set_d1(y << (32-Ebits + k) | w >> (Ebits - k)); + goto ret_d; + } + z = xa > xa0 ? *--xa : 0; + if (k -= Ebits) { + set_d0(Exp_1 | y << k | z >> (32 - k)); + y = xa > xa0 ? *--xa : 0; + set_d1(z << k | y >> (32 - k)); + } + else { + set_d0(Exp_1 | y); + set_d1(z); + } + ret_d: +#undef d0 +#undef d1 +#undef set_d0 +#undef set_d1 + return d; +} + + +/* Convert d into the form b*2^e, where b is an odd integer. b is the returned + * Bigint and e is the returned binary exponent. Return the number of significant + * bits in b in bits. d must be finite and nonzero. */ +static Bigint *d2b(double d, int32 *e, int32 *bits) +{ + Bigint *b; + int32 de, i, k; + ULong *x, y, z; +#define d0 word0(d) +#define d1 word1(d) +#define set_d0(x) set_word0(d, x) +#define set_d1(x) set_word1(d, x) + + b = Balloc(1); + if (!b) + return NULL; + x = b->x; + + z = d0 & Frac_mask; + set_d0(d0 & 0x7fffffff); /* clear sign bit, which we ignore */ +#ifdef Sudden_Underflow + de = (int32)(d0 >> Exp_shift); + z |= Exp_msk11; +#else + if ((de = (int32)(d0 >> Exp_shift)) != 0) + z |= Exp_msk1; +#endif + if ((y = d1) != 0) { + if ((k = lo0bits(&y)) != 0) { + x[0] = y | z << (32 - k); + z >>= k; + } + else + x[0] = y; + i = b->wds = (x[1] = z) ? 2 : 1; + } + else { + JS_ASSERT(z); + k = lo0bits(&z); + x[0] = z; + i = b->wds = 1; + k += 32; + } +#ifndef Sudden_Underflow + if (de) { +#endif + *e = de - Bias - (P-1) + k; + *bits = P - k; +#ifndef Sudden_Underflow + } + else { + *e = de - Bias - (P-1) + 1 + k; + *bits = 32*i - hi0bits(x[i-1]); + } +#endif + return b; +} +#undef d0 +#undef d1 +#undef set_d0 +#undef set_d1 + + +static double ratio(Bigint *a, Bigint *b) +{ + double da, db; + int32 k, ka, kb; + + da = b2d(a, &ka); + db = b2d(b, &kb); + k = ka - kb + 32*(a->wds - b->wds); + if (k > 0) + set_word0(da, word0(da) + k*Exp_msk1); + else { + k = -k; + set_word0(db, word0(db) + k*Exp_msk1); + } + return da / db; +} + +static CONST double +tens[] = { + 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, + 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, + 1e20, 1e21, 1e22 +}; + +static CONST double bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 }; +static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, +#ifdef Avoid_Underflow + 9007199254740992.e-256 +#else + 1e-256 +#endif + }; +/* The factor of 2^53 in tinytens[4] helps us avoid setting the underflow */ +/* flag unnecessarily. It leads to a song and dance at the end of strtod. */ +#define Scale_Bit 0x10 +#define n_bigtens 5 + + +#ifdef INFNAN_CHECK + +#ifndef NAN_WORD0 +#define NAN_WORD0 0x7ff80000 +#endif + +#ifndef NAN_WORD1 +#define NAN_WORD1 0 +#endif + +static int match(CONST char **sp, char *t) +{ + int c, d; + CONST char *s = *sp; + + while(d = *t++) { + if ((c = *++s) >= 'A' && c <= 'Z') + c += 'a' - 'A'; + if (c != d) + return 0; + } + *sp = s + 1; + return 1; + } +#endif /* INFNAN_CHECK */ + + +#ifdef JS_THREADSAFE +static JSBool initialized = JS_FALSE; + +/* hacked replica of nspr _PR_InitDtoa */ +static void InitDtoa(void) +{ + freelist_lock = PR_NewLock(); + p5s_lock = PR_NewLock(); + initialized = JS_TRUE; +} +#endif + +void js_FinishDtoa(void) +{ + int count; + Bigint *temp; + +#ifdef JS_THREADSAFE + if (initialized == JS_TRUE) { + PR_DestroyLock(freelist_lock); + PR_DestroyLock(p5s_lock); + initialized = JS_FALSE; + } +#endif + + /* clear down the freelist array and p5s */ + + /* static Bigint *freelist[Kmax+1]; */ + for (count = 0; count <= Kmax; count++) { + Bigint **listp = &freelist[count]; + while ((temp = *listp) != NULL) { + *listp = temp->next; + free(temp); + } + freelist[count] = NULL; + } + + /* static Bigint *p5s; */ + while (p5s) { + temp = p5s; + p5s = p5s->next; + free(temp); + } +} + +/* nspr2 watcom bug ifdef omitted */ + +JS_FRIEND_API(double) +JS_strtod(CONST char *s00, char **se, int *err) +{ + int32 scale; + int32 bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dsign, + e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign; + CONST char *s, *s0, *s1; + double aadj, aadj1, adj, rv, rv0; + Long L; + ULong y, z; + Bigint *bb, *bb1, *bd, *bd0, *bs, *delta; + + SET_FPU(); + + *err = 0; + + bb = bd = bs = delta = NULL; + sign = nz0 = nz = 0; + rv = 0.; + + /* Locking for Balloc's shared buffers that will be used in this block */ + ACQUIRE_DTOA_LOCK(); + + for(s = s00;;s++) switch(*s) { + case '-': + sign = 1; + /* no break */ + case '+': + if (*++s) + goto break2; + /* no break */ + case 0: + s = s00; + goto ret; + case '\t': + case '\n': + case '\v': + case '\f': + case '\r': + case ' ': + continue; + default: + goto break2; + } +break2: + + if (*s == '0') { + nz0 = 1; + while(*++s == '0') ; + if (!*s) + goto ret; + } + s0 = s; + y = z = 0; + for(nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++) + if (nd < 9) + y = 10*y + c - '0'; + else if (nd < 16) + z = 10*z + c - '0'; + nd0 = nd; + if (c == '.') { + c = *++s; + if (!nd) { + for(; c == '0'; c = *++s) + nz++; + if (c > '0' && c <= '9') { + s0 = s; + nf += nz; + nz = 0; + goto have_dig; + } + goto dig_done; + } + for(; c >= '0' && c <= '9'; c = *++s) { + have_dig: + nz++; + if (c -= '0') { + nf += nz; + for(i = 1; i < nz; i++) + if (nd++ < 9) + y *= 10; + else if (nd <= DBL_DIG + 1) + z *= 10; + if (nd++ < 9) + y = 10*y + c; + else if (nd <= DBL_DIG + 1) + z = 10*z + c; + nz = 0; + } + } + } +dig_done: + e = 0; + if (c == 'e' || c == 'E') { + if (!nd && !nz && !nz0) { + s = s00; + goto ret; + } + s00 = s; + esign = 0; + switch(c = *++s) { + case '-': + esign = 1; + case '+': + c = *++s; + } + if (c >= '0' && c <= '9') { + while(c == '0') + c = *++s; + if (c > '0' && c <= '9') { + L = c - '0'; + s1 = s; + while((c = *++s) >= '0' && c <= '9') + L = 10*L + c - '0'; + if (s - s1 > 8 || L > 19999) + /* Avoid confusion from exponents + * so large that e might overflow. + */ + e = 19999; /* safe for 16 bit ints */ + else + e = (int32)L; + if (esign) + e = -e; + } + else + e = 0; + } + else + s = s00; + } + if (!nd) { + if (!nz && !nz0) { +#ifdef INFNAN_CHECK + /* Check for Nan and Infinity */ + switch(c) { + case 'i': + case 'I': + if (match(&s,"nfinity")) { + word0(rv) = 0x7ff00000; + word1(rv) = 0; + goto ret; + } + break; + case 'n': + case 'N': + if (match(&s, "an")) { + word0(rv) = NAN_WORD0; + word1(rv) = NAN_WORD1; + goto ret; + } + } +#endif /* INFNAN_CHECK */ + s = s00; + } + goto ret; + } + e1 = e -= nf; + + /* Now we have nd0 digits, starting at s0, followed by a + * decimal point, followed by nd-nd0 digits. The number we're + * after is the integer represented by those digits times + * 10**e */ + + if (!nd0) + nd0 = nd; + k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1; + rv = y; + if (k > 9) + rv = tens[k - 9] * rv + z; + bd0 = 0; + if (nd <= DBL_DIG +#ifndef RND_PRODQUOT + && FLT_ROUNDS == 1 +#endif + ) { + if (!e) + goto ret; + if (e > 0) { + if (e <= Ten_pmax) { + /* rv = */ rounded_product(rv, tens[e]); + goto ret; + } + i = DBL_DIG - nd; + if (e <= Ten_pmax + i) { + /* A fancier test would sometimes let us do + * this for larger i values. + */ + e -= i; + rv *= tens[i]; + /* rv = */ rounded_product(rv, tens[e]); + goto ret; + } + } +#ifndef Inaccurate_Divide + else if (e >= -Ten_pmax) { + /* rv = */ rounded_quotient(rv, tens[-e]); + goto ret; + } +#endif + } + e1 += nd - k; + + scale = 0; + + /* Get starting approximation = rv * 10**e1 */ + + if (e1 > 0) { + if ((i = e1 & 15) != 0) + rv *= tens[i]; + if (e1 &= ~15) { + if (e1 > DBL_MAX_10_EXP) { + ovfl: + *err = JS_DTOA_ERANGE; +#ifdef __STDC__ + rv = HUGE_VAL; +#else + /* Can't trust HUGE_VAL */ + word0(rv) = Exp_mask; + word1(rv) = 0; +#endif + if (bd0) + goto retfree; + goto ret; + } + e1 >>= 4; + for(j = 0; e1 > 1; j++, e1 >>= 1) + if (e1 & 1) + rv *= bigtens[j]; + /* The last multiplication could overflow. */ + set_word0(rv, word0(rv) - P*Exp_msk1); + rv *= bigtens[j]; + if ((z = word0(rv) & Exp_mask) > Exp_msk1*(DBL_MAX_EXP+Bias-P)) + goto ovfl; + if (z > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) { + /* set to largest number */ + /* (Can't trust DBL_MAX) */ + set_word0(rv, Big0); + set_word1(rv, Big1); + } + else + set_word0(rv, word0(rv) + P*Exp_msk1); + } + } + else if (e1 < 0) { + e1 = -e1; + if ((i = e1 & 15) != 0) + rv /= tens[i]; + if (e1 &= ~15) { + e1 >>= 4; + if (e1 >= 1 << n_bigtens) + goto undfl; +#ifdef Avoid_Underflow + if (e1 & Scale_Bit) + scale = P; + for(j = 0; e1 > 0; j++, e1 >>= 1) + if (e1 & 1) + rv *= tinytens[j]; + if (scale && (j = P + 1 - ((word0(rv) & Exp_mask) + >> Exp_shift)) > 0) { + /* scaled rv is denormal; zap j low bits */ + if (j >= 32) { + set_word1(rv, 0); + set_word0(rv, word0(rv) & (0xffffffff << (j-32))); + if (!word0(rv)) + set_word0(rv, 1); + } + else + set_word1(rv, word1(rv) & (0xffffffff << j)); + } +#else + for(j = 0; e1 > 1; j++, e1 >>= 1) + if (e1 & 1) + rv *= tinytens[j]; + /* The last multiplication could underflow. */ + rv0 = rv; + rv *= tinytens[j]; + if (!rv) { + rv = 2.*rv0; + rv *= tinytens[j]; +#endif + if (!rv) { + undfl: + rv = 0.; + *err = JS_DTOA_ERANGE; + if (bd0) + goto retfree; + goto ret; + } +#ifndef Avoid_Underflow + set_word0(rv, Tiny0); + set_word1(rv, Tiny1); + /* The refinement below will clean + * this approximation up. + */ + } +#endif + } + } + + /* Now the hard part -- adjusting rv to the correct value.*/ + + /* Put digits into bd: true value = bd * 10^e */ + + bd0 = s2b(s0, nd0, nd, y); + if (!bd0) + goto nomem; + + for(;;) { + bd = Balloc(bd0->k); + if (!bd) + goto nomem; + Bcopy(bd, bd0); + bb = d2b(rv, &bbe, &bbbits); /* rv = bb * 2^bbe */ + if (!bb) + goto nomem; + bs = i2b(1); + if (!bs) + goto nomem; + + if (e >= 0) { + bb2 = bb5 = 0; + bd2 = bd5 = e; + } + else { + bb2 = bb5 = -e; + bd2 = bd5 = 0; + } + if (bbe >= 0) + bb2 += bbe; + else + bd2 -= bbe; + bs2 = bb2; +#ifdef Sudden_Underflow + j = P + 1 - bbbits; +#else +#ifdef Avoid_Underflow + j = bbe - scale; +#else + j = bbe; +#endif + i = j + bbbits - 1; /* logb(rv) */ + if (i < Emin) /* denormal */ + j += P - Emin; + else + j = P + 1 - bbbits; +#endif + bb2 += j; + bd2 += j; +#ifdef Avoid_Underflow + bd2 += scale; +#endif + i = bb2 < bd2 ? bb2 : bd2; + if (i > bs2) + i = bs2; + if (i > 0) { + bb2 -= i; + bd2 -= i; + bs2 -= i; + } + if (bb5 > 0) { + bs = pow5mult(bs, bb5); + if (!bs) + goto nomem; + bb1 = mult(bs, bb); + if (!bb1) + goto nomem; + Bfree(bb); + bb = bb1; + } + if (bb2 > 0) { + bb = lshift(bb, bb2); + if (!bb) + goto nomem; + } + if (bd5 > 0) { + bd = pow5mult(bd, bd5); + if (!bd) + goto nomem; + } + if (bd2 > 0) { + bd = lshift(bd, bd2); + if (!bd) + goto nomem; + } + if (bs2 > 0) { + bs = lshift(bs, bs2); + if (!bs) + goto nomem; + } + delta = diff(bb, bd); + if (!delta) + goto nomem; + dsign = delta->sign; + delta->sign = 0; + i = cmp(delta, bs); + if (i < 0) { + /* Error is less than half an ulp -- check for + * special case of mantissa a power of two. + */ + if (dsign || word1(rv) || word0(rv) & Bndry_mask +#ifdef Avoid_Underflow + || (word0(rv) & Exp_mask) <= Exp_msk1 + P*Exp_msk1 +#else + || (word0(rv) & Exp_mask) <= Exp_msk1 +#endif + ) { +#ifdef Avoid_Underflow + if (!delta->x[0] && delta->wds == 1) + dsign = 2; +#endif + break; + } + delta = lshift(delta,Log2P); + if (!delta) + goto nomem; + if (cmp(delta, bs) > 0) + goto drop_down; + break; + } + if (i == 0) { + /* exactly half-way between */ + if (dsign) { + if ((word0(rv) & Bndry_mask1) == Bndry_mask1 + && word1(rv) == 0xffffffff) { + /*boundary case -- increment exponent*/ + set_word0(rv, (word0(rv) & Exp_mask) + Exp_msk1); + set_word1(rv, 0); +#ifdef Avoid_Underflow + dsign = 0; +#endif + break; + } + } + else if (!(word0(rv) & Bndry_mask) && !word1(rv)) { +#ifdef Avoid_Underflow + dsign = 2; +#endif + drop_down: + /* boundary case -- decrement exponent */ +#ifdef Sudden_Underflow + L = word0(rv) & Exp_mask; + if (L <= Exp_msk1) + goto undfl; + L -= Exp_msk1; +#else + L = (word0(rv) & Exp_mask) - Exp_msk1; +#endif + set_word0(rv, L | Bndry_mask1); + set_word1(rv, 0xffffffff); + break; + } +#ifndef ROUND_BIASED + if (!(word1(rv) & LSB)) + break; +#endif + if (dsign) + rv += ulp(rv); +#ifndef ROUND_BIASED + else { + rv -= ulp(rv); +#ifndef Sudden_Underflow + if (!rv) + goto undfl; +#endif + } +#ifdef Avoid_Underflow + dsign = 1 - dsign; +#endif +#endif + break; + } + if ((aadj = ratio(delta, bs)) <= 2.) { + if (dsign) + aadj = aadj1 = 1.; + else if (word1(rv) || word0(rv) & Bndry_mask) { +#ifndef Sudden_Underflow + if (word1(rv) == Tiny1 && !word0(rv)) + goto undfl; +#endif + aadj = 1.; + aadj1 = -1.; + } + else { + /* special case -- power of FLT_RADIX to be */ + /* rounded down... */ + + if (aadj < 2./FLT_RADIX) + aadj = 1./FLT_RADIX; + else + aadj *= 0.5; + aadj1 = -aadj; + } + } + else { + aadj *= 0.5; + aadj1 = dsign ? aadj : -aadj; +#ifdef Check_FLT_ROUNDS + switch(FLT_ROUNDS) { + case 2: /* towards +infinity */ + aadj1 -= 0.5; + break; + case 0: /* towards 0 */ + case 3: /* towards -infinity */ + aadj1 += 0.5; + } +#else + if (FLT_ROUNDS == 0) + aadj1 += 0.5; +#endif + } + y = word0(rv) & Exp_mask; + + /* Check for overflow */ + + if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) { + rv0 = rv; + set_word0(rv, word0(rv) - P*Exp_msk1); + adj = aadj1 * ulp(rv); + rv += adj; + if ((word0(rv) & Exp_mask) >= + Exp_msk1*(DBL_MAX_EXP+Bias-P)) { + if (word0(rv0) == Big0 && word1(rv0) == Big1) + goto ovfl; + set_word0(rv, Big0); + set_word1(rv, Big1); + goto cont; + } + else + set_word0(rv, word0(rv) + P*Exp_msk1); + } + else { +#ifdef Sudden_Underflow + if ((word0(rv) & Exp_mask) <= P*Exp_msk1) { + rv0 = rv; + set_word0(rv, word0(rv) + P*Exp_msk1); + adj = aadj1 * ulp(rv); + rv += adj; + if ((word0(rv) & Exp_mask) <= P*Exp_msk1) + { + if (word0(rv0) == Tiny0 + && word1(rv0) == Tiny1) + goto undfl; + set_word0(rv, Tiny0); + set_word1(rv, Tiny1); + goto cont; + } + else + set_word0(rv, word0(rv) - P*Exp_msk1); + } + else { + adj = aadj1 * ulp(rv); + rv += adj; + } +#else + /* Compute adj so that the IEEE rounding rules will + * correctly round rv + adj in some half-way cases. + * If rv * ulp(rv) is denormalized (i.e., + * y <= (P-1)*Exp_msk1), we must adjust aadj to avoid + * trouble from bits lost to denormalization; + * example: 1.2e-307 . + */ +#ifdef Avoid_Underflow + if (y <= P*Exp_msk1 && aadj > 1.) +#else + if (y <= (P-1)*Exp_msk1 && aadj > 1.) +#endif + { + aadj1 = (double)(int32)(aadj + 0.5); + if (!dsign) + aadj1 = -aadj1; + } +#ifdef Avoid_Underflow + if (scale && y <= P*Exp_msk1) + set_word0(aadj1, word0(aadj1) + (P+1)*Exp_msk1 - y); +#endif + adj = aadj1 * ulp(rv); + rv += adj; +#endif + } + z = word0(rv) & Exp_mask; +#ifdef Avoid_Underflow + if (!scale) +#endif + if (y == z) { + /* Can we stop now? */ + L = (Long)aadj; + aadj -= L; + /* The tolerances below are conservative. */ + if (dsign || word1(rv) || word0(rv) & Bndry_mask) { + if (aadj < .4999999 || aadj > .5000001) + break; + } + else if (aadj < .4999999/FLT_RADIX) + break; + } + cont: + Bfree(bb); + Bfree(bd); + Bfree(bs); + Bfree(delta); + bb = bd = bs = delta = NULL; + } +#ifdef Avoid_Underflow + if (scale) { + set_word0(rv0, Exp_1 - P*Exp_msk1); + set_word1(rv0, 0); + if ((word0(rv) & Exp_mask) <= P*Exp_msk1 + && word1(rv) & 1 + && dsign != 2) { + if (dsign) { +#ifdef Sudden_Underflow + /* rv will be 0, but this would give the */ + /* right result if only rv *= rv0 worked. */ + set_word0(rv, word0(rv) + P*Exp_msk1); + set_word0(rv0, Exp_1 - 2*P*Exp_msk1); +#endif + rv += ulp(rv); + } + else + set_word1(rv, word1(rv) & ~1); + } + rv *= rv0; + } +#endif /* Avoid_Underflow */ +retfree: + Bfree(bb); + Bfree(bd); + Bfree(bs); + Bfree(bd0); + Bfree(delta); +ret: + RELEASE_DTOA_LOCK(); + if (se) + *se = (char *)s; + rv0 = sign ? -rv : rv; + goto ret1; + +nomem: + Bfree(bb); + Bfree(bd); + Bfree(bs); + Bfree(bd0); + Bfree(delta); + *err = JS_DTOA_ENOMEM; + rv0 = 0; + +ret1: + RESTORE_FPU(); + return rv0; +} + + +/* Return floor(b/2^k) and set b to be the remainder. The returned quotient must be less than 2^32. */ +static uint32 quorem2(Bigint *b, int32 k) +{ + ULong mask; + ULong result; + ULong *bx, *bxe; + int32 w; + int32 n = k >> 5; + k &= 0x1F; + mask = (1<wds - n; + if (w <= 0) + return 0; + JS_ASSERT(w <= 2); + bx = b->x; + bxe = bx + n; + result = *bxe >> k; + *bxe &= mask; + if (w == 2) { + JS_ASSERT(!(bxe[1] & ~mask)); + if (k) + result |= bxe[1] << (32 - k); + } + n++; + while (!*bxe && bxe != bx) { + n--; + bxe--; + } + b->wds = n; + return result; +} + +/* Return floor(b/S) and set b to be the remainder. As added restrictions, b must not have + * more words than S, the most significant word of S must not start with a 1 bit, and the + * returned quotient must be less than 36. */ +static int32 quorem(Bigint *b, Bigint *S) +{ + int32 n; + ULong *bx, *bxe, q, *sx, *sxe; +#ifdef ULLong + ULLong borrow, carry, y, ys; +#else + ULong borrow, carry, y, ys; + ULong si, z, zs; +#endif + + n = S->wds; + JS_ASSERT(b->wds <= n); + if (b->wds < n) + return 0; + sx = S->x; + sxe = sx + --n; + bx = b->x; + bxe = bx + n; + JS_ASSERT(*sxe <= 0x7FFFFFFF); + q = *bxe / (*sxe + 1); /* ensure q <= true quotient */ + JS_ASSERT(q < 36); + if (q) { + borrow = 0; + carry = 0; + do { +#ifdef ULLong + ys = *sx++ * (ULLong)q + carry; + carry = ys >> 32; + y = *bx - (ys & 0xffffffffUL) - borrow; + borrow = y >> 32 & 1UL; + *bx++ = (ULong)(y & 0xffffffffUL); +#else + si = *sx++; + ys = (si & 0xffff) * q + carry; + zs = (si >> 16) * q + (ys >> 16); + carry = zs >> 16; + y = (*bx & 0xffff) - (ys & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + z = (*bx >> 16) - (zs & 0xffff) - borrow; + borrow = (z & 0x10000) >> 16; + Storeinc(bx, z, y); +#endif + } + while(sx <= sxe); + if (!*bxe) { + bx = b->x; + while(--bxe > bx && !*bxe) + --n; + b->wds = n; + } + } + if (cmp(b, S) >= 0) { + q++; + borrow = 0; + carry = 0; + bx = b->x; + sx = S->x; + do { +#ifdef ULLong + ys = *sx++ + carry; + carry = ys >> 32; + y = *bx - (ys & 0xffffffffUL) - borrow; + borrow = y >> 32 & 1UL; + *bx++ = (ULong)(y & 0xffffffffUL); +#else + si = *sx++; + ys = (si & 0xffff) + carry; + zs = (si >> 16) + (ys >> 16); + carry = zs >> 16; + y = (*bx & 0xffff) - (ys & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + z = (*bx >> 16) - (zs & 0xffff) - borrow; + borrow = (z & 0x10000) >> 16; + Storeinc(bx, z, y); +#endif + } while(sx <= sxe); + bx = b->x; + bxe = bx + n; + if (!*bxe) { + while(--bxe > bx && !*bxe) + --n; + b->wds = n; + } + } + return (int32)q; +} + +/* dtoa for IEEE arithmetic (dmg): convert double to ASCII string. + * + * Inspired by "How to Print Floating-Point Numbers Accurately" by + * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 92-101]. + * + * Modifications: + * 1. Rather than iterating, we use a simple numeric overestimate + * to determine k = floor(log10(d)). We scale relevant + * quantities using O(log2(k)) rather than O(k) multiplications. + * 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't + * try to generate digits strictly left to right. Instead, we + * compute with fewer bits and propagate the carry if necessary + * when rounding the final digit up. This is often faster. + * 3. Under the assumption that input will be rounded nearest, + * mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22. + * That is, we allow equality in stopping tests when the + * round-nearest rule will give the same floating-point value + * as would satisfaction of the stopping test with strict + * inequality. + * 4. We remove common factors of powers of 2 from relevant + * quantities. + * 5. When converting floating-point integers less than 1e16, + * we use floating-point arithmetic rather than resorting + * to multiple-precision integers. + * 6. When asked to produce fewer than 15 digits, we first try + * to get by with floating-point arithmetic; we resort to + * multiple-precision integer arithmetic only if we cannot + * guarantee that the floating-point calculation has given + * the correctly rounded result. For k requested digits and + * "uniformly" distributed input, the probability is + * something like 10^(k-15) that we must resort to the Long + * calculation. + */ + +/* Always emits at least one digit. */ +/* If biasUp is set, then rounding in modes 2 and 3 will round away from zero + * when the number is exactly halfway between two representable values. For example, + * rounding 2.5 to zero digits after the decimal point will return 3 and not 2. + * 2.49 will still round to 2, and 2.51 will still round to 3. */ +/* bufsize should be at least 20 for modes 0 and 1. For the other modes, + * bufsize should be two greater than the maximum number of output characters expected. */ +static JSBool +js_dtoa(double d, int mode, JSBool biasUp, int ndigits, + int *decpt, int *sign, char **rve, char *buf, size_t bufsize) +{ + /* Arguments ndigits, decpt, sign are similar to those + of ecvt and fcvt; trailing zeros are suppressed from + the returned string. If not null, *rve is set to point + to the end of the return value. If d is +-Infinity or NaN, + then *decpt is set to 9999. + + mode: + 0 ==> shortest string that yields d when read in + and rounded to nearest. + 1 ==> like 0, but with Steele & White stopping rule; + e.g. with IEEE P754 arithmetic , mode 0 gives + 1e23 whereas mode 1 gives 9.999999999999999e22. + 2 ==> max(1,ndigits) significant digits. This gives a + return value similar to that of ecvt, except + that trailing zeros are suppressed. + 3 ==> through ndigits past the decimal point. This + gives a return value similar to that from fcvt, + except that trailing zeros are suppressed, and + ndigits can be negative. + 4-9 should give the same return values as 2-3, i.e., + 4 <= mode <= 9 ==> same return as mode + 2 + (mode & 1). These modes are mainly for + debugging; often they run slower but sometimes + faster than modes 2-3. + 4,5,8,9 ==> left-to-right digit generation. + 6-9 ==> don't try fast floating-point estimate + (if applicable). + + Values of mode other than 0-9 are treated as mode 0. + + Sufficient space is allocated to the return value + to hold the suppressed trailing zeros. + */ + + int32 bbits, b2, b5, be, dig, i, ieps, ilim, ilim0, ilim1, + j, j1, k, k0, k_check, leftright, m2, m5, s2, s5, + spec_case, try_quick; + Long L; +#ifndef Sudden_Underflow + int32 denorm; + ULong x; +#endif + Bigint *b, *b1, *delta, *mlo, *mhi, *S; + double d2, ds, eps; + char *s; + JSBool ok; + + SET_FPU(); + + if (word0(d) & Sign_bit) { + /* set sign for everything, including 0's and NaNs */ + *sign = 1; + set_word0(d, word0(d) & ~Sign_bit); /* clear sign bit */ + } + else + *sign = 0; + + if ((word0(d) & Exp_mask) == Exp_mask) { + /* Infinity or NaN */ + *decpt = 9999; + s = !word1(d) && !(word0(d) & Frac_mask) ? "Infinity" : "NaN"; + if ((s[0] == 'I' && bufsize < 9) || (s[0] == 'N' && bufsize < 4)) { + JS_ASSERT(JS_FALSE); +/* JS_SetError(JS_BUFFER_OVERFLOW_ERROR, 0); */ + ok = JS_FALSE; + goto ret2; + } + strcpy(buf, s); + if (rve) { + *rve = buf[3] ? buf + 8 : buf + 3; + JS_ASSERT(**rve == '\0'); + } + ok = JS_TRUE; + goto ret2; + } + + b = NULL; /* initialize for abort protection */ + S = NULL; + mlo = mhi = NULL; + + if (!d) { + no_digits: + *decpt = 1; + if (bufsize < 2) { + JS_ASSERT(JS_FALSE); +/* JS_SetError(JS_BUFFER_OVERFLOW_ERROR, 0); */ + ok = JS_FALSE; + goto ret2; + } + buf[0] = '0'; buf[1] = '\0'; /* copy "0" to buffer */ + if (rve) + *rve = buf + 1; + /* We might have jumped to "no_digits" from below, so we need + * to be sure to free the potentially allocated Bigints to avoid + * memory leaks. */ + Bfree(b); + Bfree(S); + if (mlo != mhi) + Bfree(mlo); + Bfree(mhi); + ok = JS_TRUE; + goto ret2; + } + + b = d2b(d, &be, &bbits); + if (!b) + goto nomem; +#ifdef Sudden_Underflow + i = (int32)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1)); +#else + if ((i = (int32)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1))) != 0) { +#endif + d2 = d; + set_word0(d2, word0(d2) & Frac_mask1); + set_word0(d2, word0(d2) | Exp_11); + + /* log(x) ~=~ log(1.5) + (x-1.5)/1.5 + * log10(x) = log(x) / log(10) + * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10)) + * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2) + * + * This suggests computing an approximation k to log10(d) by + * + * k = (i - Bias)*0.301029995663981 + * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 ); + * + * We want k to be too large rather than too small. + * The error in the first-order Taylor series approximation + * is in our favor, so we just round up the constant enough + * to compensate for any error in the multiplication of + * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077, + * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14, + * adding 1e-13 to the constant term more than suffices. + * Hence we adjust the constant term to 0.1760912590558. + * (We could get a more accurate k by invoking log10, + * but this is probably not worthwhile.) + */ + + i -= Bias; +#ifndef Sudden_Underflow + denorm = 0; + } + else { + /* d is denormalized */ + + i = bbits + be + (Bias + (P-1) - 1); + x = i > 32 ? word0(d) << (64 - i) | word1(d) >> (i - 32) : word1(d) << (32 - i); + d2 = x; + set_word0(d2, word0(d2) - 31*Exp_msk1); /* adjust exponent */ + i -= (Bias + (P-1) - 1) + 1; + denorm = 1; + } +#endif + /* At this point d = f*2^i, where 1 <= f < 2. d2 is an approximation of f. */ + ds = (d2-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981; + k = (int32)ds; + if (ds < 0. && ds != k) + k--; /* want k = floor(ds) */ + k_check = 1; + if (k >= 0 && k <= Ten_pmax) { + if (d < tens[k]) + k--; + k_check = 0; + } + /* At this point floor(log10(d)) <= k <= floor(log10(d))+1. + If k_check is zero, we're guaranteed that k = floor(log10(d)). */ + j = bbits - i - 1; + /* At this point d = b/2^j, where b is an odd integer. */ + if (j >= 0) { + b2 = 0; + s2 = j; + } + else { + b2 = -j; + s2 = 0; + } + if (k >= 0) { + b5 = 0; + s5 = k; + s2 += k; + } + else { + b2 -= k; + b5 = -k; + s5 = 0; + } + /* At this point d/10^k = (b * 2^b2 * 5^b5) / (2^s2 * 5^s5), where b is an odd integer, + b2 >= 0, b5 >= 0, s2 >= 0, and s5 >= 0. */ + if (mode < 0 || mode > 9) + mode = 0; + try_quick = 1; + if (mode > 5) { + mode -= 4; + try_quick = 0; + } + leftright = 1; + ilim = ilim1 = 0; + switch(mode) { + case 0: + case 1: + ilim = ilim1 = -1; + i = 18; + ndigits = 0; + break; + case 2: + leftright = 0; + /* no break */ + case 4: + if (ndigits <= 0) + ndigits = 1; + ilim = ilim1 = i = ndigits; + break; + case 3: + leftright = 0; + /* no break */ + case 5: + i = ndigits + k + 1; + ilim = i; + ilim1 = i - 1; + if (i <= 0) + i = 1; + } + /* ilim is the maximum number of significant digits we want, based on k and ndigits. */ + /* ilim1 is the maximum number of significant digits we want, based on k and ndigits, + when it turns out that k was computed too high by one. */ + + /* Ensure space for at least i+1 characters, including trailing null. */ + if (bufsize <= (size_t)i) { + Bfree(b); + JS_ASSERT(JS_FALSE); + ok = JS_FALSE; + goto ret2; + } + s = buf; + + if (ilim >= 0 && ilim <= Quick_max && try_quick) { + + /* Try to get by with floating-point arithmetic. */ + + i = 0; + d2 = d; + k0 = k; + ilim0 = ilim; + ieps = 2; /* conservative */ + /* Divide d by 10^k, keeping track of the roundoff error and avoiding overflows. */ + if (k > 0) { + ds = tens[k&0xf]; + j = k >> 4; + if (j & Bletch) { + /* prevent overflows */ + j &= Bletch - 1; + d /= bigtens[n_bigtens-1]; + ieps++; + } + for(; j; j >>= 1, i++) + if (j & 1) { + ieps++; + ds *= bigtens[i]; + } + d /= ds; + } + else if ((j1 = -k) != 0) { + d *= tens[j1 & 0xf]; + for(j = j1 >> 4; j; j >>= 1, i++) + if (j & 1) { + ieps++; + d *= bigtens[i]; + } + } + /* Check that k was computed correctly. */ + if (k_check && d < 1. && ilim > 0) { + if (ilim1 <= 0) + goto fast_failed; + ilim = ilim1; + k--; + d *= 10.; + ieps++; + } + /* eps bounds the cumulative error. */ + eps = ieps*d + 7.; + set_word0(eps, word0(eps) - (P-1)*Exp_msk1); + if (ilim == 0) { + S = mhi = 0; + d -= 5.; + if (d > eps) + goto one_digit; + if (d < -eps) + goto no_digits; + goto fast_failed; + } +#ifndef No_leftright + if (leftright) { + /* Use Steele & White method of only + * generating digits needed. + */ + eps = 0.5/tens[ilim-1] - eps; + for(i = 0;;) { + L = (Long)d; + d -= L; + *s++ = '0' + (char)L; + if (d < eps) + goto ret1; + if (1. - d < eps) + goto bump_up; + if (++i >= ilim) + break; + eps *= 10.; + d *= 10.; + } + } + else { +#endif + /* Generate ilim digits, then fix them up. */ + eps *= tens[ilim-1]; + for(i = 1;; i++, d *= 10.) { + L = (Long)d; + d -= L; + *s++ = '0' + (char)L; + if (i == ilim) { + if (d > 0.5 + eps) + goto bump_up; + else if (d < 0.5 - eps) { + while(*--s == '0') ; + s++; + goto ret1; + } + break; + } + } +#ifndef No_leftright + } +#endif + fast_failed: + s = buf; + d = d2; + k = k0; + ilim = ilim0; + } + + /* Do we have a "small" integer? */ + + if (be >= 0 && k <= Int_max) { + /* Yes. */ + ds = tens[k]; + if (ndigits < 0 && ilim <= 0) { + S = mhi = 0; + if (ilim < 0 || d < 5*ds || (!biasUp && d == 5*ds)) + goto no_digits; + goto one_digit; + } + for(i = 1;; i++) { + L = (Long) (d / ds); + d -= L*ds; +#ifdef Check_FLT_ROUNDS + /* If FLT_ROUNDS == 2, L will usually be high by 1 */ + if (d < 0) { + L--; + d += ds; + } +#endif + *s++ = '0' + (char)L; + if (i == ilim) { + d += d; + if ((d > ds) || (d == ds && (L & 1 || biasUp))) { + bump_up: + while(*--s == '9') + if (s == buf) { + k++; + *s = '0'; + break; + } + ++*s++; + } + break; + } + if (!(d *= 10.)) + break; + } + goto ret1; + } + + m2 = b2; + m5 = b5; + if (leftright) { + if (mode < 2) { + i = +#ifndef Sudden_Underflow + denorm ? be + (Bias + (P-1) - 1 + 1) : +#endif + 1 + P - bbits; + /* i is 1 plus the number of trailing zero bits in d's significand. Thus, + (2^m2 * 5^m5) / (2^(s2+i) * 5^s5) = (1/2 lsb of d)/10^k. */ + } + else { + j = ilim - 1; + if (m5 >= j) + m5 -= j; + else { + s5 += j -= m5; + b5 += j; + m5 = 0; + } + if ((i = ilim) < 0) { + m2 -= i; + i = 0; + } + /* (2^m2 * 5^m5) / (2^(s2+i) * 5^s5) = (1/2 * 10^(1-ilim))/10^k. */ + } + b2 += i; + s2 += i; + mhi = i2b(1); + if (!mhi) + goto nomem; + /* (mhi * 2^m2 * 5^m5) / (2^s2 * 5^s5) = one-half of last printed (when mode >= 2) or + input (when mode < 2) significant digit, divided by 10^k. */ + } + /* We still have d/10^k = (b * 2^b2 * 5^b5) / (2^s2 * 5^s5). Reduce common factors in + b2, m2, and s2 without changing the equalities. */ + if (m2 > 0 && s2 > 0) { + i = m2 < s2 ? m2 : s2; + b2 -= i; + m2 -= i; + s2 -= i; + } + + /* Fold b5 into b and m5 into mhi. */ + if (b5 > 0) { + if (leftright) { + if (m5 > 0) { + mhi = pow5mult(mhi, m5); + if (!mhi) + goto nomem; + b1 = mult(mhi, b); + if (!b1) + goto nomem; + Bfree(b); + b = b1; + } + if ((j = b5 - m5) != 0) { + b = pow5mult(b, j); + if (!b) + goto nomem; + } + } + else { + b = pow5mult(b, b5); + if (!b) + goto nomem; + } + } + /* Now we have d/10^k = (b * 2^b2) / (2^s2 * 5^s5) and + (mhi * 2^m2) / (2^s2 * 5^s5) = one-half of last printed or input significant digit, divided by 10^k. */ + + S = i2b(1); + if (!S) + goto nomem; + if (s5 > 0) { + S = pow5mult(S, s5); + if (!S) + goto nomem; + } + /* Now we have d/10^k = (b * 2^b2) / (S * 2^s2) and + (mhi * 2^m2) / (S * 2^s2) = one-half of last printed or input significant digit, divided by 10^k. */ + + /* Check for special case that d is a normalized power of 2. */ + spec_case = 0; + if (mode < 2) { + if (!word1(d) && !(word0(d) & Bndry_mask) +#ifndef Sudden_Underflow + && word0(d) & (Exp_mask & Exp_mask << 1) +#endif + ) { + /* The special case. Here we want to be within a quarter of the last input + significant digit instead of one half of it when the decimal output string's value is less than d. */ + b2 += Log2P; + s2 += Log2P; + spec_case = 1; + } + } + + /* Arrange for convenient computation of quotients: + * shift left if necessary so divisor has 4 leading 0 bits. + * + * Perhaps we should just compute leading 28 bits of S once + * and for all and pass them and a shift to quorem, so it + * can do shifts and ors to compute the numerator for q. + */ + if ((i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f) != 0) + i = 32 - i; + /* i is the number of leading zero bits in the most significant word of S*2^s2. */ + if (i > 4) { + i -= 4; + b2 += i; + m2 += i; + s2 += i; + } + else if (i < 4) { + i += 28; + b2 += i; + m2 += i; + s2 += i; + } + /* Now S*2^s2 has exactly four leading zero bits in its most significant word. */ + if (b2 > 0) { + b = lshift(b, b2); + if (!b) + goto nomem; + } + if (s2 > 0) { + S = lshift(S, s2); + if (!S) + goto nomem; + } + /* Now we have d/10^k = b/S and + (mhi * 2^m2) / S = maximum acceptable error, divided by 10^k. */ + if (k_check) { + if (cmp(b,S) < 0) { + k--; + b = multadd(b, 10, 0); /* we botched the k estimate */ + if (!b) + goto nomem; + if (leftright) { + mhi = multadd(mhi, 10, 0); + if (!mhi) + goto nomem; + } + ilim = ilim1; + } + } + /* At this point 1 <= d/10^k = b/S < 10. */ + + if (ilim <= 0 && mode > 2) { + /* We're doing fixed-mode output and d is less than the minimum nonzero output in this mode. + Output either zero or the minimum nonzero output depending on which is closer to d. */ + if (ilim < 0) + goto no_digits; + S = multadd(S,5,0); + if (!S) + goto nomem; + i = cmp(b,S); + if (i < 0 || (i == 0 && !biasUp)) { + /* Always emit at least one digit. If the number appears to be zero + using the current mode, then emit one '0' digit and set decpt to 1. */ + /*no_digits: + k = -1 - ndigits; + goto ret; */ + goto no_digits; + } + one_digit: + *s++ = '1'; + k++; + goto ret; + } + if (leftright) { + if (m2 > 0) { + mhi = lshift(mhi, m2); + if (!mhi) + goto nomem; + } + + /* Compute mlo -- check for special case + * that d is a normalized power of 2. + */ + + mlo = mhi; + if (spec_case) { + mhi = Balloc(mhi->k); + if (!mhi) + goto nomem; + Bcopy(mhi, mlo); + mhi = lshift(mhi, Log2P); + if (!mhi) + goto nomem; + } + /* mlo/S = maximum acceptable error, divided by 10^k, if the output is less than d. */ + /* mhi/S = maximum acceptable error, divided by 10^k, if the output is greater than d. */ + + for(i = 1;;i++) { + dig = quorem(b,S) + '0'; + /* Do we yet have the shortest decimal string + * that will round to d? + */ + j = cmp(b, mlo); + /* j is b/S compared with mlo/S. */ + delta = diff(S, mhi); + if (!delta) + goto nomem; + j1 = delta->sign ? 1 : cmp(b, delta); + Bfree(delta); + /* j1 is b/S compared with 1 - mhi/S. */ +#ifndef ROUND_BIASED + if (j1 == 0 && !mode && !(word1(d) & 1)) { + if (dig == '9') + goto round_9_up; + if (j > 0) + dig++; + *s++ = (char)dig; + goto ret; + } +#endif + if ((j < 0) || (j == 0 && !mode +#ifndef ROUND_BIASED + && !(word1(d) & 1) +#endif + )) { + if (j1 > 0) { + /* Either dig or dig+1 would work here as the least significant decimal digit. + Use whichever would produce a decimal value closer to d. */ + b = lshift(b, 1); + if (!b) + goto nomem; + j1 = cmp(b, S); + if (((j1 > 0) || (j1 == 0 && (dig & 1 || biasUp))) + && (dig++ == '9')) + goto round_9_up; + } + *s++ = (char)dig; + goto ret; + } + if (j1 > 0) { + if (dig == '9') { /* possible if i == 1 */ + round_9_up: + *s++ = '9'; + goto roundoff; + } + *s++ = dig + 1; + goto ret; + } + *s++ = (char)dig; + if (i == ilim) + break; + b = multadd(b, 10, 0); + if (!b) + goto nomem; + if (mlo == mhi) { + mlo = mhi = multadd(mhi, 10, 0); + if (!mhi) + goto nomem; + } + else { + mlo = multadd(mlo, 10, 0); + if (!mlo) + goto nomem; + mhi = multadd(mhi, 10, 0); + if (!mhi) + goto nomem; + } + } + } + else + for(i = 1;; i++) { + *s++ = (char)(dig = quorem(b,S) + '0'); + if (i >= ilim) + break; + b = multadd(b, 10, 0); + if (!b) + goto nomem; + } + + /* Round off last digit */ + + b = lshift(b, 1); + if (!b) + goto nomem; + j = cmp(b, S); + if ((j > 0) || (j == 0 && (dig & 1 || biasUp))) { + roundoff: + while(*--s == '9') + if (s == buf) { + k++; + *s++ = '1'; + goto ret; + } + ++*s++; + } + else { + /* Strip trailing zeros */ + while(*--s == '0') ; + s++; + } + ret: + Bfree(S); + if (mhi) { + if (mlo && mlo != mhi) + Bfree(mlo); + Bfree(mhi); + } + ret1: + Bfree(b); + JS_ASSERT(s < buf + bufsize); + *s = '\0'; + if (rve) + *rve = s; + *decpt = k + 1; + ok = JS_TRUE; + goto ret2; + +nomem: + Bfree(S); + if (mhi) { + if (mlo && mlo != mhi) + Bfree(mlo); + Bfree(mhi); + } + Bfree(b); + ok = JS_FALSE; + +ret2: + RESTORE_FPU(); + return ok; +} + + +/* Mapping of JSDToStrMode -> js_dtoa mode */ +static const int dtoaModes[] = { + 0, /* DTOSTR_STANDARD */ + 0, /* DTOSTR_STANDARD_EXPONENTIAL, */ + 3, /* DTOSTR_FIXED, */ + 2, /* DTOSTR_EXPONENTIAL, */ + 2}; /* DTOSTR_PRECISION */ + +JS_FRIEND_API(char *) +JS_dtostr(char *buffer, size_t bufferSize, JSDToStrMode mode, int precision, double d) +{ + int decPt; /* Position of decimal point relative to first digit returned by js_dtoa */ + int sign; /* Nonzero if the sign bit was set in d */ + int nDigits; /* Number of significand digits returned by js_dtoa */ + char *numBegin = buffer+2; /* Pointer to the digits returned by js_dtoa; the +2 leaves space for */ + /* the sign and/or decimal point */ + char *numEnd; /* Pointer past the digits returned by js_dtoa */ + JSBool dtoaRet; + + JS_ASSERT(bufferSize >= (size_t)(mode <= DTOSTR_STANDARD_EXPONENTIAL ? DTOSTR_STANDARD_BUFFER_SIZE : + DTOSTR_VARIABLE_BUFFER_SIZE(precision))); + + if (mode == DTOSTR_FIXED && (d >= 1e21 || d <= -1e21)) + mode = DTOSTR_STANDARD; /* Change mode here rather than below because the buffer may not be large enough to hold a large integer. */ + + /* Locking for Balloc's shared buffers */ + ACQUIRE_DTOA_LOCK(); + dtoaRet = js_dtoa(d, dtoaModes[mode], mode >= DTOSTR_FIXED, precision, &decPt, &sign, &numEnd, numBegin, bufferSize-2); + RELEASE_DTOA_LOCK(); + if (!dtoaRet) + return 0; + + nDigits = numEnd - numBegin; + + /* If Infinity, -Infinity, or NaN, return the string regardless of the mode. */ + if (decPt != 9999) { + JSBool exponentialNotation = JS_FALSE; + int minNDigits = 0; /* Minimum number of significand digits required by mode and precision */ + char *p; + char *q; + + switch (mode) { + case DTOSTR_STANDARD: + if (decPt < -5 || decPt > 21) + exponentialNotation = JS_TRUE; + else + minNDigits = decPt; + break; + + case DTOSTR_FIXED: + if (precision >= 0) + minNDigits = decPt + precision; + else + minNDigits = decPt; + break; + + case DTOSTR_EXPONENTIAL: + JS_ASSERT(precision > 0); + minNDigits = precision; + /* Fall through */ + case DTOSTR_STANDARD_EXPONENTIAL: + exponentialNotation = JS_TRUE; + break; + + case DTOSTR_PRECISION: + JS_ASSERT(precision > 0); + minNDigits = precision; + if (decPt < -5 || decPt > precision) + exponentialNotation = JS_TRUE; + break; + } + + /* If the number has fewer than minNDigits, pad it with zeros at the end */ + if (nDigits < minNDigits) { + p = numBegin + minNDigits; + nDigits = minNDigits; + do { + *numEnd++ = '0'; + } while (numEnd != p); + *numEnd = '\0'; + } + + if (exponentialNotation) { + /* Insert a decimal point if more than one significand digit */ + if (nDigits != 1) { + numBegin--; + numBegin[0] = numBegin[1]; + numBegin[1] = '.'; + } + JS_snprintf(numEnd, bufferSize - (numEnd - buffer), "e%+d", decPt-1); + } else if (decPt != nDigits) { + /* Some kind of a fraction in fixed notation */ + JS_ASSERT(decPt <= nDigits); + if (decPt > 0) { + /* dd...dd . dd...dd */ + p = --numBegin; + do { + *p = p[1]; + p++; + } while (--decPt); + *p = '.'; + } else { + /* 0 . 00...00dd...dd */ + p = numEnd; + numEnd += 1 - decPt; + q = numEnd; + JS_ASSERT(numEnd < buffer + bufferSize); + *numEnd = '\0'; + while (p != numBegin) + *--q = *--p; + for (p = numBegin + 1; p != q; p++) + *p = '0'; + *numBegin = '.'; + *--numBegin = '0'; + } + } + } + + /* If negative and neither -0.0 nor NaN, output a leading '-'. */ + if (sign && + !(word0(d) == Sign_bit && word1(d) == 0) && + !((word0(d) & Exp_mask) == Exp_mask && + (word1(d) || (word0(d) & Frac_mask)))) { + *--numBegin = '-'; + } + return numBegin; +} + + +/* Let b = floor(b / divisor), and return the remainder. b must be nonnegative. + * divisor must be between 1 and 65536. + * This function cannot run out of memory. */ +static uint32 +divrem(Bigint *b, uint32 divisor) +{ + int32 n = b->wds; + uint32 remainder = 0; + ULong *bx; + ULong *bp; + + JS_ASSERT(divisor > 0 && divisor <= 65536); + + if (!n) + return 0; /* b is zero */ + bx = b->x; + bp = bx + n; + do { + ULong a = *--bp; + ULong dividend = remainder << 16 | a >> 16; + ULong quotientHi = dividend / divisor; + ULong quotientLo; + + remainder = dividend - quotientHi*divisor; + JS_ASSERT(quotientHi <= 0xFFFF && remainder < divisor); + dividend = remainder << 16 | (a & 0xFFFF); + quotientLo = dividend / divisor; + remainder = dividend - quotientLo*divisor; + JS_ASSERT(quotientLo <= 0xFFFF && remainder < divisor); + *bp = quotientHi << 16 | quotientLo; + } while (bp != bx); + /* Decrease the size of the number if its most significant word is now zero. */ + if (bx[n-1] == 0) + b->wds--; + return remainder; +} + + +/* "-0.0000...(1073 zeros after decimal point)...0001\0" is the longest string that we could produce, + * which occurs when printing -5e-324 in binary. We could compute a better estimate of the size of + * the output string and malloc fewer bytes depending on d and base, but why bother? */ +#define DTOBASESTR_BUFFER_SIZE 1078 +#define BASEDIGIT(digit) ((char)(((digit) >= 10) ? 'a' - 10 + (digit) : '0' + (digit))) + +JS_FRIEND_API(char *) +JS_dtobasestr(int base, double d) +{ + char *buffer; /* The output string */ + char *p; /* Pointer to current position in the buffer */ + char *pInt; /* Pointer to the beginning of the integer part of the string */ + char *q; + uint32 digit; + double di; /* d truncated to an integer */ + double df; /* The fractional part of d */ + + JS_ASSERT(base >= 2 && base <= 36); + + buffer = (char*) malloc(DTOBASESTR_BUFFER_SIZE); + if (buffer) { + p = buffer; + if (d < 0.0 +#if defined(XP_WIN) || defined(XP_OS2) + && !((word0(d) & Exp_mask) == Exp_mask && ((word0(d) & Frac_mask) || word1(d))) /* Visual C++ doesn't know how to compare against NaN */ +#endif + ) { + *p++ = '-'; + d = -d; + } + + /* Check for Infinity and NaN */ + if ((word0(d) & Exp_mask) == Exp_mask) { + strcpy(p, !word1(d) && !(word0(d) & Frac_mask) ? "Infinity" : "NaN"); + return buffer; + } + + /* Locking for Balloc's shared buffers */ + ACQUIRE_DTOA_LOCK(); + + /* Output the integer part of d with the digits in reverse order. */ + pInt = p; + di = fd_floor(d); + if (di <= 4294967295.0) { + uint32 n = (uint32)di; + if (n) + do { + uint32 m = n / base; + digit = n - m*base; + n = m; + JS_ASSERT(digit < (uint32)base); + *p++ = BASEDIGIT(digit); + } while (n); + else *p++ = '0'; + } else { + int32 e; + int32 bits; /* Number of significant bits in di; not used. */ + Bigint *b = d2b(di, &e, &bits); + if (!b) + goto nomem1; + b = lshift(b, e); + if (!b) { + nomem1: + Bfree(b); + return NULL; + } + do { + digit = divrem(b, base); + JS_ASSERT(digit < (uint32)base); + *p++ = BASEDIGIT(digit); + } while (b->wds); + Bfree(b); + } + /* Reverse the digits of the integer part of d. */ + q = p-1; + while (q > pInt) { + char ch = *pInt; + *pInt++ = *q; + *q-- = ch; + } + + df = d - di; + if (df != 0.0) { + /* We have a fraction. */ + int32 e, bbits, s2, done; + Bigint *b, *s, *mlo, *mhi; + + b = s = mlo = mhi = NULL; + + *p++ = '.'; + b = d2b(df, &e, &bbits); + if (!b) { + nomem2: + Bfree(b); + Bfree(s); + if (mlo != mhi) + Bfree(mlo); + Bfree(mhi); + return NULL; + } + JS_ASSERT(e < 0); + /* At this point df = b * 2^e. e must be less than zero because 0 < df < 1. */ + + s2 = -(int32)(word0(d) >> Exp_shift1 & Exp_mask>>Exp_shift1); +#ifndef Sudden_Underflow + if (!s2) + s2 = -1; +#endif + s2 += Bias + P; + /* 1/2^s2 = (nextDouble(d) - d)/2 */ + JS_ASSERT(-s2 < e); + mlo = i2b(1); + if (!mlo) + goto nomem2; + mhi = mlo; + if (!word1(d) && !(word0(d) & Bndry_mask) +#ifndef Sudden_Underflow + && word0(d) & (Exp_mask & Exp_mask << 1) +#endif + ) { + /* The special case. Here we want to be within a quarter of the last input + significant digit instead of one half of it when the output string's value is less than d. */ + s2 += Log2P; + mhi = i2b(1< df = b/2^s2 > 0; + * (d - prevDouble(d))/2 = mlo/2^s2; + * (nextDouble(d) - d)/2 = mhi/2^s2. */ + + done = JS_FALSE; + do { + int32 j, j1; + Bigint *delta; + + b = multadd(b, base, 0); + if (!b) + goto nomem2; + digit = quorem2(b, s2); + if (mlo == mhi) { + mlo = mhi = multadd(mlo, base, 0); + if (!mhi) + goto nomem2; + } + else { + mlo = multadd(mlo, base, 0); + if (!mlo) + goto nomem2; + mhi = multadd(mhi, base, 0); + if (!mhi) + goto nomem2; + } + + /* Do we yet have the shortest string that will round to d? */ + j = cmp(b, mlo); + /* j is b/2^s2 compared with mlo/2^s2. */ + delta = diff(s, mhi); + if (!delta) + goto nomem2; + j1 = delta->sign ? 1 : cmp(b, delta); + Bfree(delta); + /* j1 is b/2^s2 compared with 1 - mhi/2^s2. */ + +#ifndef ROUND_BIASED + if (j1 == 0 && !(word1(d) & 1)) { + if (j > 0) + digit++; + done = JS_TRUE; + } else +#endif + if (j < 0 || (j == 0 +#ifndef ROUND_BIASED + && !(word1(d) & 1) +#endif + )) { + if (j1 > 0) { + /* Either dig or dig+1 would work here as the least significant digit. + Use whichever would produce an output value closer to d. */ + b = lshift(b, 1); + if (!b) + goto nomem2; + j1 = cmp(b, s); + if (j1 > 0) /* The even test (|| (j1 == 0 && (digit & 1))) is not here because it messes up odd base output + * such as 3.5 in base 3. */ + digit++; + } + done = JS_TRUE; + } else if (j1 > 0) { + digit++; + done = JS_TRUE; + } + JS_ASSERT(digit < (uint32)base); + *p++ = BASEDIGIT(digit); + } while (!done); + Bfree(b); + Bfree(s); + if (mlo != mhi) + Bfree(mlo); + Bfree(mhi); + } + JS_ASSERT(p < buffer + DTOBASESTR_BUFFER_SIZE); + *p = '\0'; + RELEASE_DTOA_LOCK(); + } + return buffer; +} diff --git a/src/dom/js/jsdtoa.h b/src/dom/js/jsdtoa.h new file mode 100644 index 000000000..409f45454 --- /dev/null +++ b/src/dom/js/jsdtoa.h @@ -0,0 +1,130 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef jsdtoa_h___ +#define jsdtoa_h___ +/* + * Public interface to portable double-precision floating point to string + * and back conversion package. + */ + +#include "jscompat.h" + +JS_BEGIN_EXTERN_C + +/* + * JS_strtod() returns as a double-precision floating-point number + * the value represented by the character string pointed to by + * s00. The string is scanned up to the first unrecognized + * character. + * If the value of se is not (char **)NULL, a pointer to + * the character terminating the scan is returned in the location pointed + * to by se. If no number can be formed, se is set to s00r, and + * zero is returned. + * + * *err is set to zero on success; it's set to JS_DTOA_ERANGE on range + * errors and JS_DTOA_ENOMEM on memory failure. + */ +#define JS_DTOA_ERANGE 1 +#define JS_DTOA_ENOMEM 2 +JS_FRIEND_API(double) +JS_strtod(const char *s00, char **se, int *err); + +/* + * Modes for converting floating-point numbers to strings. + * + * Some of the modes can round-trip; this means that if the number is converted to + * a string using one of these mode and then converted back to a number, the result + * will be identical to the original number (except that, due to ECMA, -0 will get converted + * to +0). These round-trip modes return the minimum number of significand digits that + * permit the round trip. + * + * Some of the modes take an integer parameter . + */ +/* NB: Keep this in sync with number_constants[]. */ +typedef enum JSDToStrMode { + DTOSTR_STANDARD, /* Either fixed or exponential format; round-trip */ + DTOSTR_STANDARD_EXPONENTIAL, /* Always exponential format; round-trip */ + DTOSTR_FIXED, /* Round to digits after the decimal point; exponential if number is large */ + DTOSTR_EXPONENTIAL, /* Always exponential format; significant digits */ + DTOSTR_PRECISION /* Either fixed or exponential format; significant digits */ +} JSDToStrMode; + + +/* Maximum number of characters (including trailing null) that a DTOSTR_STANDARD or DTOSTR_STANDARD_EXPONENTIAL + * conversion can produce. This maximum is reached for a number like -0.0000012345678901234567. */ +#define DTOSTR_STANDARD_BUFFER_SIZE 26 + +/* Maximum number of characters (including trailing null) that one of the other conversions + * can produce. This maximum is reached for TO_FIXED, which can generate up to 21 digits before the decimal point. */ +#define DTOSTR_VARIABLE_BUFFER_SIZE(precision) ((precision)+24 > DTOSTR_STANDARD_BUFFER_SIZE ? (precision)+24 : DTOSTR_STANDARD_BUFFER_SIZE) + +/* + * Convert dval according to the given mode and return a pointer to the resulting ASCII string. + * The result is held somewhere in buffer, but not necessarily at the beginning. The size of + * buffer is given in bufferSize, and must be at least as large as given by the above macros. + * + * Return NULL if out of memory. + */ +JS_FRIEND_API(char *) +JS_dtostr(char *buffer, size_t bufferSize, JSDToStrMode mode, int precision, double dval); + +/* + * Convert d to a string in the given base. The integral part of d will be printed exactly + * in that base, regardless of how large it is, because there is no exponential notation for non-base-ten + * numbers. The fractional part will be rounded to as few digits as possible while still preserving + * the round-trip property (analogous to that of printing decimal numbers). In other words, if one were + * to read the resulting string in via a hypothetical base-number-reading routine that rounds to the nearest + * IEEE double (and to an even significand if there are two equally near doubles), then the result would + * equal d (except for -0.0, which converts to "0", and NaN, which is not equal to itself). + * + * Return NULL if out of memory. If the result is not NULL, it must be released via free(). + */ +JS_FRIEND_API(char *) +JS_dtobasestr(int base, double d); + +/* + * Clean up any persistent RAM allocated during the execution of DtoA + * routines, and remove any locks that might have been created. + */ +extern void js_FinishDtoa(void); + +JS_END_EXTERN_C + +#endif /* jsdtoa_h___ */ diff --git a/src/dom/js/jsemit.c b/src/dom/js/jsemit.c new file mode 100644 index 000000000..13e105c07 --- /dev/null +++ b/src/dom/js/jsemit.c @@ -0,0 +1,4471 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* + * JS bytecode generation. + */ +#include "jsstddef.h" +#ifdef HAVE_MEMORY_H +#include +#endif +#include +#include "jstypes.h" +#include "jsarena.h" /* Added by JSIFY */ +#include "jsutil.h" /* Added by JSIFY */ +#include "jsbit.h" +#include "jsprf.h" +#include "jsapi.h" +#include "jsatom.h" +#include "jscntxt.h" +#include "jsconfig.h" +#include "jsemit.h" +#include "jsfun.h" +#include "jsnum.h" +#include "jsopcode.h" +#include "jsparse.h" +#include "jsscan.h" +#include "jsscope.h" +#include "jsscript.h" + +/* Allocation chunk counts, must be powers of two in general. */ +#define BYTECODE_CHUNK 256 /* code allocation increment */ +#define SRCNOTE_CHUNK 64 /* initial srcnote allocation increment */ +#define TRYNOTE_CHUNK 64 /* trynote allocation increment */ + +/* Macros to compute byte sizes from typed element counts. */ +#define BYTECODE_SIZE(n) ((n) * sizeof(jsbytecode)) +#define SRCNOTE_SIZE(n) ((n) * sizeof(jssrcnote)) +#define TRYNOTE_SIZE(n) ((n) * sizeof(JSTryNote)) + +JS_FRIEND_API(JSBool) +js_InitCodeGenerator(JSContext *cx, JSCodeGenerator *cg, + JSArenaPool *codePool, JSArenaPool *notePool, + const char *filename, uintN lineno, + JSPrincipals *principals) +{ + memset(cg, 0, sizeof *cg); + TREE_CONTEXT_INIT(&cg->treeContext); + cg->treeContext.flags |= TCF_COMPILING; + cg->codePool = codePool; + cg->notePool = notePool; + cg->codeMark = JS_ARENA_MARK(codePool); + cg->noteMark = JS_ARENA_MARK(notePool); + cg->tempMark = JS_ARENA_MARK(&cx->tempPool); + cg->current = &cg->main; + cg->filename = filename; + cg->firstLine = cg->prolog.currentLine = cg->main.currentLine = lineno; + cg->principals = principals; + ATOM_LIST_INIT(&cg->atomList); + cg->prolog.noteMask = cg->main.noteMask = SRCNOTE_CHUNK - 1; + return JS_TRUE; +} + +JS_FRIEND_API(void) +js_FinishCodeGenerator(JSContext *cx, JSCodeGenerator *cg) +{ + TREE_CONTEXT_FINISH(&cg->treeContext); + JS_ARENA_RELEASE(cg->codePool, cg->codeMark); + JS_ARENA_RELEASE(cg->notePool, cg->noteMark); + JS_ARENA_RELEASE(&cx->tempPool, cg->tempMark); +} + +static ptrdiff_t +EmitCheck(JSContext *cx, JSCodeGenerator *cg, JSOp op, ptrdiff_t delta) +{ + jsbytecode *base, *limit, *next; + ptrdiff_t offset, length; + size_t incr, size; + + base = CG_BASE(cg); + next = CG_NEXT(cg); + limit = CG_LIMIT(cg); + offset = PTRDIFF(next, base, jsbytecode); + if (next + delta > limit) { + length = offset + delta; + length = (length <= BYTECODE_CHUNK) + ? BYTECODE_CHUNK + : JS_BIT(JS_CeilingLog2(length)); + incr = BYTECODE_SIZE(length); + if (!base) { + JS_ARENA_ALLOCATE_CAST(base, jsbytecode *, cg->codePool, incr); + } else { + size = BYTECODE_SIZE(PTRDIFF(limit, base, jsbytecode)); + incr -= size; + JS_ARENA_GROW_CAST(base, jsbytecode *, cg->codePool, size, incr); + } + if (!base) { + JS_ReportOutOfMemory(cx); + return -1; + } + CG_BASE(cg) = base; + CG_LIMIT(cg) = base + length; + CG_NEXT(cg) = base + offset; + } + return offset; +} + +static void +UpdateDepth(JSContext *cx, JSCodeGenerator *cg, ptrdiff_t target) +{ + jsbytecode *pc; + const JSCodeSpec *cs; + intN nuses; + + pc = CG_CODE(cg, target); + cs = &js_CodeSpec[pc[0]]; + nuses = cs->nuses; + if (nuses < 0) + nuses = 2 + GET_ARGC(pc); /* stack: fun, this, [argc arguments] */ + cg->stackDepth -= nuses; + if (cg->stackDepth < 0) { + char numBuf[12]; + JS_snprintf(numBuf, sizeof numBuf, "%d", target); + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, + JSMSG_STACK_UNDERFLOW, + cg->filename ? cg->filename : "stdin", numBuf); + } + cg->stackDepth += cs->ndefs; + if ((uintN)cg->stackDepth > cg->maxStackDepth) + cg->maxStackDepth = cg->stackDepth; +} + +ptrdiff_t +js_Emit1(JSContext *cx, JSCodeGenerator *cg, JSOp op) +{ + ptrdiff_t offset = EmitCheck(cx, cg, op, 1); + + if (offset >= 0) { + *CG_NEXT(cg)++ = (jsbytecode)op; + UpdateDepth(cx, cg, offset); + } + return offset; +} + +ptrdiff_t +js_Emit2(JSContext *cx, JSCodeGenerator *cg, JSOp op, jsbytecode op1) +{ + ptrdiff_t offset = EmitCheck(cx, cg, op, 2); + + if (offset >= 0) { + jsbytecode *next = CG_NEXT(cg); + next[0] = (jsbytecode)op; + next[1] = op1; + CG_NEXT(cg) = next + 2; + UpdateDepth(cx, cg, offset); + } + return offset; +} + +ptrdiff_t +js_Emit3(JSContext *cx, JSCodeGenerator *cg, JSOp op, jsbytecode op1, + jsbytecode op2) +{ + ptrdiff_t offset = EmitCheck(cx, cg, op, 3); + + if (offset >= 0) { + jsbytecode *next = CG_NEXT(cg); + next[0] = (jsbytecode)op; + next[1] = op1; + next[2] = op2; + CG_NEXT(cg) = next + 3; + UpdateDepth(cx, cg, offset); + } + return offset; +} + +ptrdiff_t +js_EmitN(JSContext *cx, JSCodeGenerator *cg, JSOp op, size_t extra) +{ + ptrdiff_t length = 1 + (ptrdiff_t)extra; + ptrdiff_t offset = EmitCheck(cx, cg, op, length); + + if (offset >= 0) { + jsbytecode *next = CG_NEXT(cg); + *next = (jsbytecode)op; + memset(next + 1, 0, BYTECODE_SIZE(extra)); + CG_NEXT(cg) = next + length; + UpdateDepth(cx, cg, offset); + } + return offset; +} + +/* XXX too many "... statement" L10N gaffes below -- fix via js.msg! */ +const char js_with_statement_str[] = "with statement"; + +static const char *statementName[] = { + "block", /* BLOCK */ + "label statement", /* LABEL */ + "if statement", /* IF */ + "else statement", /* ELSE */ + "switch statement", /* SWITCH */ + js_with_statement_str, /* WITH */ + "try statement", /* TRY */ + "catch block", /* CATCH */ + "finally statement", /* FINALLY */ + "do loop", /* DO_LOOP */ + "for loop", /* FOR_LOOP */ + "for/in loop", /* FOR_IN_LOOP */ + "while loop", /* WHILE_LOOP */ +}; + +static const char * +StatementName(JSCodeGenerator *cg) +{ + if (!cg->treeContext.topStmt) + return "script"; + return statementName[cg->treeContext.topStmt->type]; +} + +static void +ReportStatementTooLarge(JSContext *cx, JSCodeGenerator *cg) +{ + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_NEED_DIET, + StatementName(cg)); +} + +/** + Span-dependent instructions in JS bytecode consist of the jump (JOF_JUMP) + and switch (JOF_LOOKUPSWITCH, JOF_TABLESWITCH) format opcodes, subdivided + into unconditional (gotos and gosubs), and conditional jumps or branches + (which pop a value, test it, and jump depending on its value). Most jumps + have just one immediate operand, a signed offset from the jump opcode's pc + to the target bytecode. The lookup and table switch opcodes may contain + many jump offsets. + + Mozilla bug #80981 (http://bugzilla.mozilla.org/show_bug.cgi?id=80981) was + fixed by adding extended "X" counterparts to the opcodes/formats (NB: X is + suffixed to prefer JSOP_ORX thereby avoiding a JSOP_XOR name collision for + the extended form of the JSOP_OR branch opcode). The unextended or short + formats have 16-bit signed immediate offset operands, the extended or long + formats have 32-bit signed immediates. The span-dependency problem consists + of selecting as few long instructions as possible, or about as few -- since + jumps can span other jumps, extending one jump may cause another to need to + be extended. + + Most JS scripts are short, so need no extended jumps. We optimize for this + case by generating short jumps until we know a long jump is needed. After + that point, we keep generating short jumps, but each jump's 16-bit immediate + offset operand is actually an unsigned index into cg->spanDeps, an array of + JSSpanDep structs. Each struct tells the top offset in the script of the + opcode, the "before" offset of the jump (which will be the same as top for + simplex jumps, but which will index further into the bytecode array for a + non-initial jump offset in a lookup or table switch), the after "offset" + adjusted during span-dependent instruction selection (initially the same + value as the "before" offset), and the jump target (more below). + + Since we generate cg->spanDeps lazily, from within js_SetJumpOffset, we must + ensure that all bytecode generated so far can be inspected to discover where + the jump offset immediate operands lie within CG_CODE(cg). But the bonus is + that we generate span-dependency records sorted by their offsets, so we can + binary-search when trying to find a JSSpanDep for a given bytecode offset, + or the nearest JSSpanDep at or above a given pc. + + To avoid limiting scripts to 64K jumps, if the cg->spanDeps index overflows + 65534, we store SPANDEP_INDEX_HUGE in the jump's immediate operand. This + tells us that we need to binary-search for the cg->spanDeps entry by the + jump opcode's bytecode offset (sd->before). + + Jump targets need to be maintained in a data structure that lets us look + up an already-known target by its address (jumps may have a common target), + and that also lets us update the addresses (script-relative, a.k.a. absolute + offsets) of targets that come after a jump target (for when a jump below + that target needs to be extended). We use an AVL tree, implemented using + recursion, but with some tricky optimizations to its height-balancing code + (see http://www.enteract.com/~bradapp/ftp/src/libs/C++/AvlTrees.html). + + A final wrinkle: backpatch chains are linked by jump-to-jump offsets with + positive sign, even though they link "backward" (i.e., toward lower bytecode + address). We don't want to waste space and search time in the AVL tree for + such temporary backpatch deltas, so we use a single-bit wildcard scheme to + tag true JSJumpTarget pointers and encode untagged, signed (positive) deltas + in JSSpanDep.target pointers, depending on whether the JSSpanDep has a known + target, or is still awaiting backpatching. + + Note that backpatch chains would present a problem for BuildSpanDepTable, + which inspects bytecode to build cg->spanDeps on demand, when the first + short jump offset overflows. To solve this temporary problem, we emit a + proxy bytecode (JSOP_BACKPATCH; JSOP_BACKPATCH_PUSH for jumps that push a + result on the interpreter's stack, namely JSOP_GOSUB; or JSOP_BACKPATCH_POP + for branch ops) whose nuses/ndefs counts help keep the stack balanced, but + whose opcode format distinguishes its backpatch delta immediate operand from + a normal jump offset. + */ +static int +BalanceJumpTargets(JSJumpTarget **jtp) +{ + JSJumpTarget *jt, *jt2, *root; + int dir, otherDir, heightChanged; + JSBool doubleRotate; + + jt = *jtp; + JS_ASSERT(jt->balance != 0); + + if (jt->balance < -1) { + dir = JT_RIGHT; + doubleRotate = (jt->kids[JT_LEFT]->balance > 0); + } else if (jt->balance > 1) { + dir = JT_LEFT; + doubleRotate = (jt->kids[JT_RIGHT]->balance < 0); + } else { + return 0; + } + + otherDir = JT_OTHER_DIR(dir); + if (doubleRotate) { + jt2 = jt->kids[otherDir]; + *jtp = root = jt2->kids[dir]; + + jt->kids[otherDir] = root->kids[dir]; + root->kids[dir] = jt; + + jt2->kids[dir] = root->kids[otherDir]; + root->kids[otherDir] = jt2; + + heightChanged = 1; + root->kids[JT_LEFT]->balance = -JS_MAX(root->balance, 0); + root->kids[JT_RIGHT]->balance = -JS_MIN(root->balance, 0); + root->balance = 0; + } else { + *jtp = root = jt->kids[otherDir]; + jt->kids[otherDir] = root->kids[dir]; + root->kids[dir] = jt; + + heightChanged = (root->balance != 0); + jt->balance = -((dir == JT_LEFT) ? --root->balance : ++root->balance); + } + + return heightChanged; +} + +typedef struct AddJumpTargetArgs { + JSContext *cx; + JSCodeGenerator *cg; + ptrdiff_t offset; + JSJumpTarget *node; +} AddJumpTargetArgs; + +static int +AddJumpTarget(AddJumpTargetArgs *args, JSJumpTarget **jtp) +{ + JSJumpTarget *jt; + int balanceDelta; + + jt = *jtp; + if (!jt) { + JSCodeGenerator *cg = args->cg; + + jt = cg->jtFreeList; + if (jt) { + cg->jtFreeList = jt->kids[JT_LEFT]; + } else { + JS_ARENA_ALLOCATE_CAST(jt, JSJumpTarget *, &args->cx->tempPool, + sizeof *jt); + if (!jt) { + JS_ReportOutOfMemory(args->cx); + return 0; + } + } + jt->offset = args->offset; + jt->balance = 0; + jt->kids[JT_LEFT] = jt->kids[JT_RIGHT] = NULL; + cg->numJumpTargets++; + args->node = jt; + *jtp = jt; + return 1; + } + + if (jt->offset == args->offset) { + args->node = jt; + return 0; + } + + if (args->offset < jt->offset) + balanceDelta = -AddJumpTarget(args, &jt->kids[JT_LEFT]); + else + balanceDelta = AddJumpTarget(args, &jt->kids[JT_RIGHT]); + if (!args->node) + return 0; + + jt->balance += balanceDelta; + return (balanceDelta && jt->balance) + ? 1 - BalanceJumpTargets(jtp) + : 0; +} + +#ifdef DEBUG_brendan +static int AVLCheck(JSJumpTarget *jt) +{ + int lh, rh; + + if (!jt) return 0; + JS_ASSERT(-1 <= jt->balance && jt->balance <= 1); + lh = AVLCheck(jt->kids[JT_LEFT]); + rh = AVLCheck(jt->kids[JT_RIGHT]); + JS_ASSERT(jt->balance == rh - lh); + return 1 + JS_MAX(lh, rh); +} +#endif + +static JSBool +SetSpanDepTarget(JSContext *cx, JSCodeGenerator *cg, JSSpanDep *sd, + ptrdiff_t off) +{ + AddJumpTargetArgs args; + + if (off < JUMPX_OFFSET_MIN || JUMPX_OFFSET_MAX < off) { + ReportStatementTooLarge(cx, cg); + return JS_FALSE; + } + + args.cx = cx; + args.cg = cg; + args.offset = sd->top + off; + args.node = NULL; + AddJumpTarget(&args, &cg->jumpTargets); + if (!args.node) + return JS_FALSE; + +#ifdef DEBUG_brendan + AVLCheck(cg->jumpTargets); +#endif + + SD_SET_TARGET(sd, args.node); + return JS_TRUE; +} + +#define SPANDEPS_MIN 256 +#define SPANDEPS_SIZE(n) ((n) * sizeof(JSSpanDep)) +#define SPANDEPS_SIZE_MIN SPANDEPS_SIZE(SPANDEPS_MIN) + +static JSBool +AddSpanDep(JSContext *cx, JSCodeGenerator *cg, jsbytecode *pc, jsbytecode *pc2, + ptrdiff_t off) +{ + uintN index; + JSSpanDep *sdbase, *sd; + size_t size; + + index = cg->numSpanDeps; + if (index + 1 == 0) { + ReportStatementTooLarge(cx, cg); + return JS_FALSE; + } + + if ((index & (index - 1)) == 0 && + (!(sdbase = cg->spanDeps) || index >= SPANDEPS_MIN)) { + if (!sdbase) { + size = SPANDEPS_SIZE_MIN; + JS_ARENA_ALLOCATE_CAST(sdbase, JSSpanDep *, &cx->tempPool, size); + } else { + size = SPANDEPS_SIZE(index); + JS_ARENA_GROW_CAST(sdbase, JSSpanDep *, &cx->tempPool, size, size); + } + if (!sdbase) + return JS_FALSE; + cg->spanDeps = sdbase; + } + + cg->numSpanDeps = index + 1; + sd = cg->spanDeps + index; + sd->top = PTRDIFF(pc, CG_BASE(cg), jsbytecode); + sd->offset = sd->before = PTRDIFF(pc2, CG_BASE(cg), jsbytecode); + + if (js_CodeSpec[*pc].format & JOF_BACKPATCH) { + /* Jump offset will be backpatched if off is a non-zero "bpdelta". */ + if (off != 0) { + JS_ASSERT(off >= 1 + JUMP_OFFSET_LEN); + if (off > BPDELTA_MAX) { + ReportStatementTooLarge(cx, cg); + return JS_FALSE; + } + } + SD_SET_BPDELTA(sd, off); + } else if (off == 0) { + /* Jump offset will be patched directly, without backpatch chaining. */ + SD_SET_TARGET(sd, NULL); + } else { + /* The jump offset in off is non-zero, therefore it's already known. */ + if (!SetSpanDepTarget(cx, cg, sd, off)) + return JS_FALSE; + } + + if (index > SPANDEP_INDEX_MAX) + index = SPANDEP_INDEX_HUGE; + SET_SPANDEP_INDEX(pc2, index); + return JS_TRUE; +} + +static JSBool +BuildSpanDepTable(JSContext *cx, JSCodeGenerator *cg) +{ + jsbytecode *pc, *end; + JSOp op; + const JSCodeSpec *cs; + ptrdiff_t len, off; + + pc = CG_BASE(cg); + end = CG_NEXT(cg); + while (pc < end) { + op = (JSOp)*pc; + cs = &js_CodeSpec[op]; + len = (ptrdiff_t)cs->length; + + switch (cs->format & JOF_TYPEMASK) { + case JOF_JUMP: + off = GET_JUMP_OFFSET(pc); + if (!AddSpanDep(cx, cg, pc, pc, off)) + return JS_FALSE; + break; + +#if JS_HAS_SWITCH_STATEMENT + case JOF_TABLESWITCH: + { + jsbytecode *pc2; + jsint i, low, high; + + pc2 = pc; + off = GET_JUMP_OFFSET(pc2); + if (!AddSpanDep(cx, cg, pc, pc2, off)) + return JS_FALSE; + pc2 += JUMP_OFFSET_LEN; + low = GET_JUMP_OFFSET(pc2); + pc2 += JUMP_OFFSET_LEN; + high = GET_JUMP_OFFSET(pc2); + pc2 += JUMP_OFFSET_LEN; + for (i = low; i <= high; i++) { + off = GET_JUMP_OFFSET(pc2); + if (!AddSpanDep(cx, cg, pc, pc2, off)) + return JS_FALSE; + pc2 += JUMP_OFFSET_LEN; + } + len = 1 + pc2 - pc; + break; + } + + case JOF_LOOKUPSWITCH: + { + jsbytecode *pc2; + jsint npairs; + + pc2 = pc; + off = GET_JUMP_OFFSET(pc2); + if (!AddSpanDep(cx, cg, pc, pc2, off)) + return JS_FALSE; + pc2 += JUMP_OFFSET_LEN; + npairs = (jsint) GET_ATOM_INDEX(pc2); + pc2 += ATOM_INDEX_LEN; + while (npairs) { + pc2 += ATOM_INDEX_LEN; + off = GET_JUMP_OFFSET(pc2); + if (!AddSpanDep(cx, cg, pc, pc2, off)) + return JS_FALSE; + pc2 += JUMP_OFFSET_LEN; + npairs--; + } + len = 1 + pc2 - pc; + break; + } +#endif /* JS_HAS_SWITCH_STATEMENT */ + } + + pc += len; + } + + return JS_TRUE; +} + +static JSSpanDep * +GetSpanDep(JSCodeGenerator *cg, jsbytecode *pc) +{ + uintN index; + ptrdiff_t offset; + int lo, hi, mid; + JSSpanDep *sd; + + index = GET_SPANDEP_INDEX(pc); + if (index != SPANDEP_INDEX_HUGE) + return cg->spanDeps + index; + + offset = PTRDIFF(pc, CG_BASE(cg), jsbytecode); + lo = 0; + hi = cg->numSpanDeps - 1; + while (lo <= hi) { + mid = (lo + hi) / 2; + sd = cg->spanDeps + mid; + if (sd->before == offset) + return sd; + if (sd->before < offset) + lo = mid + 1; + else + hi = mid - 1; + } + + JS_ASSERT(0); + return NULL; +} + +static JSBool +SetBackPatchDelta(JSContext *cx, JSCodeGenerator *cg, jsbytecode *pc, + ptrdiff_t delta) +{ + JSSpanDep *sd; + + JS_ASSERT(delta >= 1 + JUMP_OFFSET_LEN); + if (!cg->spanDeps && delta < JUMP_OFFSET_MAX) { + SET_JUMP_OFFSET(pc, delta); + return JS_TRUE; + } + + if (delta > BPDELTA_MAX) { + ReportStatementTooLarge(cx, cg); + return JS_FALSE; + } + + if (!cg->spanDeps && !BuildSpanDepTable(cx, cg)) + return JS_FALSE; + + sd = GetSpanDep(cg, pc); + JS_ASSERT(SD_GET_BPDELTA(sd) == 0); + SD_SET_BPDELTA(sd, delta); + return JS_TRUE; +} + +static void +UpdateJumpTargets(JSJumpTarget *jt, ptrdiff_t pivot, ptrdiff_t delta) +{ + if (jt->offset > pivot) { + jt->offset += delta; + if (jt->kids[JT_LEFT]) + UpdateJumpTargets(jt->kids[JT_LEFT], pivot, delta); + } + if (jt->kids[JT_RIGHT]) + UpdateJumpTargets(jt->kids[JT_RIGHT], pivot, delta); +} + +static JSSpanDep * +FindNearestSpanDep(JSCodeGenerator *cg, ptrdiff_t offset, int lo, + JSSpanDep *guard) +{ + int num, hi, mid; + JSSpanDep *sdbase, *sd; + + num = cg->numSpanDeps; + JS_ASSERT(num > 0); + hi = num - 1; + sdbase = cg->spanDeps; + while (lo <= hi) { + mid = (lo + hi) / 2; + sd = sdbase + mid; + if (sd->before == offset) + return sd; + if (sd->before < offset) + lo = mid + 1; + else + hi = mid - 1; + } + if (lo == num) + return guard; + sd = sdbase + lo; + JS_ASSERT(sd->before >= offset && (lo == 0 || sd[-1].before < offset)); + return sd; +} + +static void +FreeJumpTargets(JSCodeGenerator *cg, JSJumpTarget *jt) +{ + if (jt->kids[JT_LEFT]) + FreeJumpTargets(cg, jt->kids[JT_LEFT]); + if (jt->kids[JT_RIGHT]) + FreeJumpTargets(cg, jt->kids[JT_RIGHT]); + jt->kids[JT_LEFT] = cg->jtFreeList; + cg->jtFreeList = jt; +} + +static JSBool +OptimizeSpanDeps(JSContext *cx, JSCodeGenerator *cg) +{ + jsbytecode *pc, *oldpc, *base, *limit, *next; + JSSpanDep *sd, *sd2, *sdbase, *sdlimit, *sdtop, guard; + ptrdiff_t offset, growth, delta, top, pivot, span, length, target; + JSBool done; + JSOp op; + uint32 type; + size_t size, incr; + jssrcnote *sn, *snlimit; + JSSrcNoteSpec *spec; + uintN i, n, noteIndex; + JSTryNote *tn, *tnlimit; +#ifdef DEBUG_brendan + int passes = 0; +#endif + + base = CG_BASE(cg); + sdbase = cg->spanDeps; + sdlimit = sdbase + cg->numSpanDeps; + offset = CG_OFFSET(cg); + growth = 0; + + do { + done = JS_TRUE; + delta = 0; + top = pivot = -1; + sdtop = NULL; + pc = NULL; + op = JSOP_NOP; + type = 0; +#ifdef DEBUG_brendan + passes++; +#endif + + for (sd = sdbase; sd < sdlimit; sd++) { + JS_ASSERT(JT_HAS_TAG(sd->target)); + sd->offset += delta; + + if (sd->top != top) { + sdtop = sd; + top = sd->top; + JS_ASSERT(top == sd->before); + pivot = sd->offset; + pc = base + top; + op = (JSOp) *pc; + type = (js_CodeSpec[op].format & JOF_TYPEMASK); + if (JOF_TYPE_IS_EXTENDED_JUMP(type)) { + /* + * We already extended all the jump offset operands for + * the opcode at sd->top. Jumps and branches have only + * one jump offset operand, but switches have many, all + * of which are adjacent in cg->spanDeps. + */ + continue; + } + + JS_ASSERT(type == JOF_JUMP || + type == JOF_TABLESWITCH || + type == JOF_LOOKUPSWITCH); + } + + if (!JOF_TYPE_IS_EXTENDED_JUMP(type)) { + span = SD_TARGET_OFFSET(sd) - pivot; + if (span < JUMP_OFFSET_MIN || JUMP_OFFSET_MAX < span) { + ptrdiff_t deltaFromTop = 0; + + done = JS_FALSE; + + switch (op) { + case JSOP_GOTO: op = JSOP_GOTOX; break; + case JSOP_IFEQ: op = JSOP_IFEQX; break; + case JSOP_IFNE: op = JSOP_IFNEX; break; + case JSOP_OR: op = JSOP_ORX; break; + case JSOP_AND: op = JSOP_ANDX; break; + case JSOP_GOSUB: op = JSOP_GOSUBX; break; + case JSOP_CASE: op = JSOP_CASEX; break; + case JSOP_DEFAULT: op = JSOP_DEFAULTX; break; + case JSOP_TABLESWITCH: op = JSOP_TABLESWITCHX; break; + case JSOP_LOOKUPSWITCH: op = JSOP_LOOKUPSWITCHX; break; + default: JS_ASSERT(0); + } + *pc = (jsbytecode) op; + + for (sd2 = sdtop; sd2 < sdlimit && sd2->top == top; sd2++) { + if (sd2 <= sd) { + /* + * sd2->offset already includes delta as it stood + * before we entered this loop, but it must also + * include the delta relative to top due to all the + * extended jump offset immediates for the opcode + * starting at top, which we extend in this loop. + * + * If there is only one extended jump offset, then + * sd2->offset won't change and this for loop will + * iterate once only. + */ + sd2->offset += deltaFromTop; + deltaFromTop += JUMPX_OFFSET_LEN - JUMP_OFFSET_LEN; + } else { + /* + * sd2 comes after sd, and won't be revisited by + * the outer for loop, so we have to increase its + * offset by delta, not merely by deltaFromTop. + */ + sd2->offset += delta; + } + + delta += JUMPX_OFFSET_LEN - JUMP_OFFSET_LEN; + UpdateJumpTargets(cg->jumpTargets, sd2->offset, + JUMPX_OFFSET_LEN - JUMP_OFFSET_LEN); + } + sd = sd2 - 1; + } + } + } + + growth += delta; + } while (!done); + + if (growth) { +#ifdef DEBUG_brendan + printf("%s:%u: %u/%u jumps extended in %d passes (%d=%d+%d)\n", + cg->filename ? cg->filename : "stdin", cg->firstLine, + growth / (JUMPX_OFFSET_LEN - JUMP_OFFSET_LEN), cg->numSpanDeps, + passes, offset + growth, offset, growth); +#endif + + /* + * Ensure that we have room for the extended jumps, but don't round up + * to a power of two -- we're done generating code, so we cut to fit. + */ + limit = CG_LIMIT(cg); + length = offset + growth; + next = base + length; + if (next > limit) { + JS_ASSERT(length > BYTECODE_CHUNK); + size = BYTECODE_SIZE(PTRDIFF(limit, base, jsbytecode)); + incr = BYTECODE_SIZE(length) - size; + JS_ARENA_GROW_CAST(base, jsbytecode *, cg->codePool, size, incr); + if (!base) { + JS_ReportOutOfMemory(cx); + return JS_FALSE; + } + CG_BASE(cg) = base; + CG_LIMIT(cg) = next = base + length; + } + CG_NEXT(cg) = next; + + /* + * Set up a fake span dependency record to guard the end of the code + * being generated. This guard record is returned as a fencepost by + * FindNearestSpanDep if there is no real spandep at or above a given + * unextended code offset. + */ + guard.top = -1; + guard.offset = offset + growth; + guard.before = offset; + guard.target = NULL; + } + + /* + * Now work backwards through the span dependencies, copying chunks of + * bytecode between each extended jump toward the end of the grown code + * space, and restoring immediate offset operands for all jump bytecodes. + * The first chunk of bytecodes, starting at base and ending at the first + * extended jump offset (NB: this chunk includes the operation bytecode + * just before that immediate jump offset), doesn't need to be copied. + */ + JS_ASSERT(sd == sdlimit); + top = -1; + while (--sd >= sdbase) { + if (sd->top != top) { + top = sd->top; + op = (JSOp) base[top]; + type = (js_CodeSpec[op].format & JOF_TYPEMASK); + + for (sd2 = sd - 1; sd2 >= sdbase && sd2->top == top; sd2--) + continue; + sd2++; + pivot = sd2->offset; + JS_ASSERT(top == sd2->before); + } + + oldpc = base + sd->before; + span = SD_TARGET_OFFSET(sd) - pivot; + + /* + * If this jump didn't need to be extended, restore its span immediate + * offset operand now, overwriting the index of sd within cg->spanDeps + * that was stored temporarily after *pc when BuildSpanDepTable ran. + * + * Note that span might fit in 16 bits even for an extended jump op, + * if the op has multiple span operands, not all of which overflowed + * (e.g. JSOP_LOOKUPSWITCH or JSOP_TABLESWITCH where some cases are in + * range for a short jump, but others are not). + */ + if (!JOF_TYPE_IS_EXTENDED_JUMP(type)) { + JS_ASSERT(JUMP_OFFSET_MIN <= span && span <= JUMP_OFFSET_MAX); + SET_JUMP_OFFSET(oldpc, span); + continue; + } + + /* + * Set up parameters needed to copy the next run of bytecode starting + * at offset (which is a cursor into the unextended, original bytecode + * vector), down to sd->before (a cursor of the same scale as offset, + * it's the index of the original jump pc). Reuse delta to count the + * nominal number of bytes to copy. + */ + pc = base + sd->offset; + delta = offset - sd->before; + JS_ASSERT(delta >= 1 + JUMP_OFFSET_LEN); + + /* + * Don't bother copying the jump offset we're about to reset, but do + * copy the bytecode at oldpc (which comes just before its immediate + * jump offset operand), on the next iteration through the loop, by + * including it in offset's new value. + */ + offset = sd->before + 1; + size = BYTECODE_SIZE(delta - (1 + JUMP_OFFSET_LEN)); + if (size) { + memmove(pc + 1 + JUMPX_OFFSET_LEN, + oldpc + 1 + JUMP_OFFSET_LEN, + size); + } + + SET_JUMPX_OFFSET(pc, span); + } + + if (growth) { + /* + * Fix source note deltas. Don't hardwire the delta fixup adjustment, + * even though currently it must be JUMPX_OFFSET_LEN - JUMP_OFFSET_LEN + * at each sd that moved. The future may bring different offset sizes + * for span-dependent instruction operands. However, we fix only main + * notes here, not prolog notes -- we know that prolog opcodes are not + * span-dependent, and aren't likely ever to be. + */ + offset = growth = 0; + sd = sdbase; + for (sn = cg->main.notes, snlimit = sn + cg->main.noteCount; + sn < snlimit; + sn = SN_NEXT(sn)) { + /* + * Recall that the offset of a given note includes its delta, and + * tells the offset of the annotated bytecode from the main entry + * point of the script. + */ + offset += SN_DELTA(sn); + while (sd < sdlimit && sd->before < offset) { + /* + * To compute the delta to add to sn, we need to look at the + * spandep after sd, whose offset - (before + growth) tells by + * how many bytes sd's instruction grew. + */ + sd2 = sd + 1; + if (sd2 == sdlimit) + sd2 = &guard; + delta = sd2->offset - (sd2->before + growth); + if (delta > 0) { + JS_ASSERT(delta == JUMPX_OFFSET_LEN - JUMP_OFFSET_LEN); + sn = js_AddToSrcNoteDelta(cx, cg, sn, delta); + if (!sn) + return JS_FALSE; + snlimit = cg->main.notes + cg->main.noteCount; + growth += delta; + } + sd++; + } + + /* + * If sn has span-dependent offset operands, check whether each + * covers further span-dependencies, and increase those operands + * accordingly. Some source notes measure offset not from the + * annotated pc, but from that pc plus some small bias. NB: we + * assume that spec->offsetBias can't itself span span-dependent + * instructions! + */ + spec = &js_SrcNoteSpec[SN_TYPE(sn)]; + if (spec->isSpanDep) { + pivot = offset + spec->offsetBias; + n = spec->arity; + for (i = 0; i < n; i++) { + span = js_GetSrcNoteOffset(sn, i); + if (span == 0) + continue; + target = pivot + span * spec->isSpanDep; + sd2 = FindNearestSpanDep(cg, target, + (target >= pivot) + ? sd - sdbase + : 0, + &guard); + + /* + * Increase target by sd2's before-vs-after offset delta, + * which is absolute (i.e., relative to start of script, + * as is target). Recompute the span by subtracting its + * adjusted pivot from target. + */ + target += sd2->offset - sd2->before; + span = target - (pivot + growth); + span *= spec->isSpanDep; + noteIndex = sn - cg->main.notes; + if (!js_SetSrcNoteOffset(cx, cg, noteIndex, i, span)) + return JS_FALSE; + sn = cg->main.notes + noteIndex; + snlimit = cg->main.notes + cg->main.noteCount; + } + } + } + + /* + * Fix try/catch notes (O(numTryNotes * log2(numSpanDeps)), but it's + * not clear how we can beat that). + */ + for (tn = cg->tryBase, tnlimit = cg->tryNext; tn < tnlimit; tn++) { + /* + * First, look for the nearest span dependency at/above tn->start. + * There may not be any such spandep, in which case the guard will + * be returned. + */ + offset = tn->start; + sd = FindNearestSpanDep(cg, offset, 0, &guard); + delta = sd->offset - sd->before; + tn->start = offset + delta; + + /* + * Next, find the nearest spandep at/above tn->start + tn->length. + * Use its delta minus tn->start's delta to increase tn->length. + */ + length = tn->length; + sd2 = FindNearestSpanDep(cg, offset + length, sd - sdbase, &guard); + if (sd2 != sd) + tn->length = length + sd2->offset - sd2->before - delta; + + /* + * Finally, adjust tn->catchStart upward only if it is non-zero, + * and provided there are spandeps below it that grew. + */ + offset = tn->catchStart; + if (offset != 0) { + sd = FindNearestSpanDep(cg, offset, sd2 - sdbase, &guard); + tn->catchStart = offset + sd->offset - sd->before; + } + } + } + +#ifdef DEBUG_brendan + { + uintN bigspans = 0; + top = -1; + for (sd = sdbase; sd < sdlimit; sd++) { + offset = sd->offset; + + /* NB: sd->top cursors into the original, unextended bytecode vector. */ + if (sd->top != top) { + JS_ASSERT(top == -1 || + !JOF_TYPE_IS_EXTENDED_JUMP(type) || + bigspans != 0); + bigspans = 0; + top = sd->top; + JS_ASSERT(top == sd->before); + op = (JSOp) base[offset]; + type = (js_CodeSpec[op].format & JOF_TYPEMASK); + JS_ASSERT(type == JOF_JUMP || + type == JOF_JUMPX || + type == JOF_TABLESWITCH || + type == JOF_TABLESWITCHX || + type == JOF_LOOKUPSWITCH || + type == JOF_LOOKUPSWITCHX); + pivot = offset; + } + + pc = base + offset; + if (JOF_TYPE_IS_EXTENDED_JUMP(type)) { + span = GET_JUMPX_OFFSET(pc); + if (span < JUMP_OFFSET_MIN || JUMP_OFFSET_MAX < span) { + bigspans++; + } else { + JS_ASSERT(type == JOF_TABLESWITCHX || + type == JOF_LOOKUPSWITCHX); + } + } else { + span = GET_JUMP_OFFSET(pc); + } + JS_ASSERT(SD_TARGET_OFFSET(sd) == pivot + span); + } + JS_ASSERT(!JOF_TYPE_IS_EXTENDED_JUMP(type) || bigspans != 0); + } +#endif + + /* + * Reset so we optimize at most once -- cg may be used for further code + * generation of successive, independent, top-level statements. No jump + * can span top-level statements, because JS lacks goto. + */ + size = SPANDEPS_SIZE(JS_BIT(JS_CeilingLog2(cg->numSpanDeps))); + JS_ArenaFreeAllocation(&cx->tempPool, cg->spanDeps, + JS_MAX(size, SPANDEPS_SIZE_MIN)); + cg->spanDeps = NULL; + FreeJumpTargets(cg, cg->jumpTargets); + cg->jumpTargets = NULL; + cg->numSpanDeps = cg->numJumpTargets = 0; + return JS_TRUE; +} + +static JSBool +EmitJump(JSContext *cx, JSCodeGenerator *cg, JSOp op, ptrdiff_t off) +{ + ptrdiff_t jmp; + jsbytecode *pc; + + if (off < JUMP_OFFSET_MIN || JUMP_OFFSET_MAX < off) { + if (!cg->spanDeps && !BuildSpanDepTable(cx, cg)) + return JS_FALSE; + } + + jmp = js_Emit3(cx, cg, op, JUMP_OFFSET_HI(off), JUMP_OFFSET_LO(off)); + if (jmp >= 0 && cg->spanDeps) { + pc = CG_CODE(cg, jmp); + if (!AddSpanDep(cx, cg, pc, pc, off)) + return JS_FALSE; + } + return jmp; +} + +static ptrdiff_t +GetJumpOffset(JSCodeGenerator *cg, jsbytecode *pc) +{ + JSSpanDep *sd; + JSJumpTarget *jt; + ptrdiff_t top; + + if (!cg->spanDeps) + return GET_JUMP_OFFSET(pc); + + sd = GetSpanDep(cg, pc); + jt = sd->target; + if (!JT_HAS_TAG(jt)) + return JT_TO_BPDELTA(jt); + + top = sd->top; + while (--sd >= cg->spanDeps && sd->top == top) + continue; + sd++; + return JT_CLR_TAG(jt)->offset - sd->offset; +} + +JSBool +js_SetJumpOffset(JSContext *cx, JSCodeGenerator *cg, jsbytecode *pc, + ptrdiff_t off) +{ + if (!cg->spanDeps) { + if (JUMP_OFFSET_MIN <= off && off <= JUMP_OFFSET_MAX) { + SET_JUMP_OFFSET(pc, off); + return JS_TRUE; + } + + if (!BuildSpanDepTable(cx, cg)) + return JS_FALSE; + } + + return SetSpanDepTarget(cx, cg, GetSpanDep(cg, pc), off); +} + +JSBool +js_InWithStatement(JSTreeContext *tc) +{ + JSStmtInfo *stmt; + + for (stmt = tc->topStmt; stmt; stmt = stmt->down) { + if (stmt->type == STMT_WITH) + return JS_TRUE; + } + return JS_FALSE; +} + +JSBool +js_InCatchBlock(JSTreeContext *tc, JSAtom *atom) +{ + JSStmtInfo *stmt; + + for (stmt = tc->topStmt; stmt; stmt = stmt->down) { + if (stmt->type == STMT_CATCH && stmt->label == atom) + return JS_TRUE; + } + return JS_FALSE; +} + +void +js_PushStatement(JSTreeContext *tc, JSStmtInfo *stmt, JSStmtType type, + ptrdiff_t top) +{ + stmt->type = type; + SET_STATEMENT_TOP(stmt, top); + stmt->label = NULL; + stmt->down = tc->topStmt; + tc->topStmt = stmt; +} + +/* + * Emit a backpatch op with offset pointing to the previous jump of this type, + * so that we can walk back up the chain fixing up the op and jump offset. + */ +#define EMIT_BACKPATCH_OP(cx, cg, last, op, jmp) \ + JS_BEGIN_MACRO \ + ptrdiff_t offset, delta; \ + offset = CG_OFFSET(cg); \ + delta = offset - (last); \ + last = offset; \ + JS_ASSERT(delta > 0); \ + jmp = EmitJump((cx), (cg), (op), (delta)); \ + JS_END_MACRO + +/* Emit additional bytecode(s) for non-local jumps. */ +static JSBool +EmitNonLocalJumpFixup(JSContext *cx, JSCodeGenerator *cg, JSStmtInfo *toStmt, + JSOp *returnop) +{ + intN depth; + JSStmtInfo *stmt; + ptrdiff_t jmp; + + /* + * Return from within a try block that has a finally clause must be split + * into two ops: JSOP_SETRVAL, to pop the r.v. and store it in fp->rval; + * and JSOP_RETRVAL, which makes control flow go back to the caller, who + * picks up fp->rval as usual. Otherwise, the stack will be unbalanced + * when executing the finally clause. + * + * We mutate *returnop once only if we find an enclosing try-block (viz, + * STMT_FINALLY) to ensure that we emit just one JSOP_SETRVAL before one + * or more JSOP_GOSUBs and other fixup opcodes emitted by this function. + * Our caller (the TOK_RETURN case of js_EmitTree) then emits *returnop. + * The fixup opcodes and gosubs must interleave in the proper order, from + * inner statement to outer, so that finally clauses run at the correct + * stack depth. + */ + if (returnop) { + JS_ASSERT(*returnop == JSOP_RETURN); + for (stmt = cg->treeContext.topStmt; stmt != toStmt; + stmt = stmt->down) { + if (stmt->type == STMT_FINALLY) { + if (js_Emit1(cx, cg, JSOP_SETRVAL) < 0) + return JS_FALSE; + *returnop = JSOP_RETRVAL; + break; + } + } + + /* + * If there are no try-with-finally blocks open around this return + * statement, we can generate a return forthwith and skip generating + * any fixup code. + */ + if (*returnop == JSOP_RETURN) + return JS_TRUE; + } + + /* + * The non-local jump fixup we emit will unbalance cg->stackDepth, because + * the fixup replicates balanced code such as JSOP_LEAVEWITH emitted at the + * end of a with statement, so we save cg->stackDepth here and restore it + * just before a successful return. + */ + depth = cg->stackDepth; + for (stmt = cg->treeContext.topStmt; stmt != toStmt; stmt = stmt->down) { + switch (stmt->type) { + case STMT_FINALLY: + if (js_NewSrcNote(cx, cg, SRC_HIDDEN) < 0) + return JS_FALSE; + EMIT_BACKPATCH_OP(cx, cg, stmt->gosub, JSOP_BACKPATCH_PUSH, jmp); + if (jmp < 0) + return JS_FALSE; + break; + + case STMT_WITH: + case STMT_CATCH: + /* There's a With object on the stack that we need to pop. */ + if (js_NewSrcNote(cx, cg, SRC_HIDDEN) < 0) + return JS_FALSE; + if (js_Emit1(cx, cg, JSOP_LEAVEWITH) < 0) + return JS_FALSE; + break; + + case STMT_FOR_IN_LOOP: + /* + * The iterator and the object being iterated need to be popped. + * JSOP_POP2 isn't decompiled, so it doesn't need to be HIDDEN. + */ + if (js_Emit1(cx, cg, JSOP_POP2) < 0) + return JS_FALSE; + break; + + case STMT_SUBROUTINE: + /* There's a retsub pc-offset on the stack that we need to pop. */ + if (js_NewSrcNote(cx, cg, SRC_HIDDEN) < 0) + return JS_FALSE; + if (js_Emit1(cx, cg, JSOP_POP) < 0) + return JS_FALSE; + break; + + default:; + } + } + + cg->stackDepth = depth; + return JS_TRUE; +} + +static ptrdiff_t +EmitGoto(JSContext *cx, JSCodeGenerator *cg, JSStmtInfo *toStmt, + ptrdiff_t *last, JSAtomListElement *label, JSSrcNoteType noteType) +{ + intN index; + ptrdiff_t jmp; + + if (!EmitNonLocalJumpFixup(cx, cg, toStmt, NULL)) + return -1; + + if (label) { + index = js_NewSrcNote(cx, cg, noteType); + if (index < 0) + return -1; + if (!js_SetSrcNoteOffset(cx, cg, (uintN)index, 0, + (ptrdiff_t) ALE_INDEX(label))) { + return -1; + } + } else if (noteType != SRC_NULL) { + if (js_NewSrcNote(cx, cg, noteType) < 0) + return -1; + } + + EMIT_BACKPATCH_OP(cx, cg, *last, JSOP_BACKPATCH, jmp); + return jmp; +} + +static JSBool +BackPatch(JSContext *cx, JSCodeGenerator *cg, ptrdiff_t last, + jsbytecode *target, jsbytecode op) +{ + jsbytecode *pc, *stop; + ptrdiff_t delta, span; + + pc = CG_CODE(cg, last); + stop = CG_CODE(cg, -1); + while (pc != stop) { + delta = GetJumpOffset(cg, pc); + span = PTRDIFF(target, pc, jsbytecode); + CHECK_AND_SET_JUMP_OFFSET(cx, cg, pc, span); + + /* + * Set *pc after jump offset in case bpdelta didn't overflow, but span + * does (if so, CHECK_AND_SET_JUMP_OFFSET might call BuildSpanDepTable + * and need to see the JSOP_BACKPATCH* op at *pc). + */ + *pc = op; + pc -= delta; + } + return JS_TRUE; +} + +void +js_PopStatement(JSTreeContext *tc) +{ + tc->topStmt = tc->topStmt->down; +} + +JSBool +js_PopStatementCG(JSContext *cx, JSCodeGenerator *cg) +{ + JSStmtInfo *stmt; + + stmt = cg->treeContext.topStmt; + if (!BackPatch(cx, cg, stmt->breaks, CG_NEXT(cg), JSOP_GOTO) || + !BackPatch(cx, cg, stmt->continues, CG_CODE(cg, stmt->update), + JSOP_GOTO)) { + return JS_FALSE; + } + js_PopStatement(&cg->treeContext); + return JS_TRUE; +} + +/* + * Emit a bytecode and its 2-byte constant (atom) index immediate operand. + * NB: We use cx and cg from our caller's lexical environment, and return + * false on error. + */ +#define EMIT_ATOM_INDEX_OP(op, atomIndex) \ + JS_BEGIN_MACRO \ + if (js_Emit3(cx, cg, op, ATOM_INDEX_HI(atomIndex), \ + ATOM_INDEX_LO(atomIndex)) < 0) { \ + return JS_FALSE; \ + } \ + JS_END_MACRO + +static JSBool +EmitAtomOp(JSContext *cx, JSParseNode *pn, JSOp op, JSCodeGenerator *cg) +{ + JSAtomListElement *ale; + + ale = js_IndexAtom(cx, pn->pn_atom, &cg->atomList); + if (!ale) + return JS_FALSE; + EMIT_ATOM_INDEX_OP(op, ALE_INDEX(ale)); + return JS_TRUE; +} + +/* + * This routine tries to optimize name gets and sets to stack slot loads and + * stores, given the variables object and scope chain in cx's top frame, the + * compile-time context in tc, and a TOK_NAME node pn. It returns false on + * error, true on success. + * + * The caller can inspect pn->pn_slot for a non-negative slot number to tell + * whether optimization occurred, in which case LookupArgOrVar also updated + * pn->pn_op. If pn->pn_slot is still -1 on return, pn->pn_op nevertheless + * may have been optimized, e.g., from JSOP_NAME to JSOP_ARGUMENTS. Whether + * or not pn->pn_op was modified, if this function finds an argument or local + * variable name, pn->pn_attrs will contain the property's attributes after a + * successful return. + */ +static JSBool +LookupArgOrVar(JSContext *cx, JSTreeContext *tc, JSParseNode *pn) +{ + JSObject *obj, *pobj; + JSClass *clasp; + JSAtom *atom; + JSScopeProperty *sprop; + JSOp op; + + JS_ASSERT(pn->pn_type == TOK_NAME); + if (pn->pn_slot >= 0 || pn->pn_op == JSOP_ARGUMENTS) + return JS_TRUE; + + /* + * We can't optimize if var and closure (a local function not in a larger + * expression and not at top-level within another's body) collide. + * XXX suboptimal: keep track of colliding names and deoptimize only those + */ + if (tc->flags & TCF_FUN_CLOSURE_VS_VAR) + return JS_TRUE; + + /* + * We can't optimize if we're not compiling a function body, whether via + * eval, or directly when compiling a function statement or expression. + */ + obj = cx->fp->varobj; + clasp = OBJ_GET_CLASS(cx, obj); + if (clasp != &js_FunctionClass && clasp != &js_CallClass) + return JS_TRUE; + + /* + * We can't optimize if we're in an eval called inside a with statement, + * or we're compiling a with statement and its body, or we're in a catch + * block whose exception variable has the same name as pn. + */ + atom = pn->pn_atom; + if (cx->fp->scopeChain != obj || + js_InWithStatement(tc) || + js_InCatchBlock(tc, atom)) { + return JS_TRUE; + } + + /* + * Ok, we may be able to optimize name to stack slot. Look for an argument + * or variable property in the function, or its call object, not found in + * any prototype object. Rewrite pn_op and update pn accordingly. NB: We + * know that JSOP_DELNAME on an argument or variable must evaluate to + * false, due to JSPROP_PERMANENT. + */ + if (!js_LookupProperty(cx, obj, (jsid)atom, &pobj, (JSProperty **)&sprop)) + return JS_FALSE; + op = pn->pn_op; + if (sprop) { + if (pobj == obj) { + JSPropertyOp getter = sprop->getter; + + if (getter == js_GetArgument) { + switch (op) { + case JSOP_NAME: op = JSOP_GETARG; break; + case JSOP_SETNAME: op = JSOP_SETARG; break; + case JSOP_INCNAME: op = JSOP_INCARG; break; + case JSOP_NAMEINC: op = JSOP_ARGINC; break; + case JSOP_DECNAME: op = JSOP_DECARG; break; + case JSOP_NAMEDEC: op = JSOP_ARGDEC; break; + case JSOP_FORNAME: op = JSOP_FORARG; break; + case JSOP_DELNAME: op = JSOP_FALSE; break; + default: JS_ASSERT(0); + } + } else if (getter == js_GetLocalVariable || + getter == js_GetCallVariable) + { + switch (op) { + case JSOP_NAME: op = JSOP_GETVAR; break; + case JSOP_SETNAME: op = JSOP_SETVAR; break; + case JSOP_SETCONST: op = JSOP_SETVAR; break; + case JSOP_INCNAME: op = JSOP_INCVAR; break; + case JSOP_NAMEINC: op = JSOP_VARINC; break; + case JSOP_DECNAME: op = JSOP_DECVAR; break; + case JSOP_NAMEDEC: op = JSOP_VARDEC; break; + case JSOP_FORNAME: op = JSOP_FORVAR; break; + case JSOP_DELNAME: op = JSOP_FALSE; break; + default: JS_ASSERT(0); + } + } + if (op != pn->pn_op) { + pn->pn_op = op; + pn->pn_slot = sprop->shortid; + } + pn->pn_attrs = sprop->attrs; + } + OBJ_DROP_PROPERTY(cx, pobj, (JSProperty *)sprop); + } + + if (pn->pn_slot < 0) { + /* + * We couldn't optimize it, so it's not an arg or local var name. Now + * we must check for the predefined arguments variable. It may be + * overridden by assignment, in which case the function is heavyweight + * and the interpreter will look up 'arguments' in the function's call + * object. + */ + if (pn->pn_op == JSOP_NAME && + atom == cx->runtime->atomState.argumentsAtom) { + pn->pn_op = JSOP_ARGUMENTS; + return JS_TRUE; + } + + tc->flags |= TCF_FUN_USES_NONLOCALS; + } + return JS_TRUE; +} + +/* + * If pn contains a useful expression, return true with *answer set to true. + * If pn contains a useless expression, return true with *answer set to false. + * Return false on error. + * + * The caller should initialize *answer to false and invoke this function on + * an expression statement or similar subtree to decide whether the tree could + * produce code that has any side effects. For an expression statement, we + * define useless code as code with no side effects, because the main effect, + * the value left on the stack after the code executes, will be discarded by a + * pop bytecode. + */ +static JSBool +CheckSideEffects(JSContext *cx, JSTreeContext *tc, JSParseNode *pn, + JSBool *answer) +{ + JSBool ok; + JSFunction *fun; + JSParseNode *pn2; + + ok = JS_TRUE; + if (!pn || *answer) + return ok; + + switch (pn->pn_arity) { + case PN_FUNC: + /* + * A named function is presumed useful: we can't yet know that it is + * not called. The side effects are the creation of a scope object + * to parent this function object, and the binding of the function's + * name in that scope object. See comments at case JSOP_NAMEDFUNOBJ: + * in jsinterp.c. + */ + fun = (JSFunction *) JS_GetPrivate(cx, ATOM_TO_OBJECT(pn->pn_funAtom)); + if (fun->atom) + *answer = JS_TRUE; + break; + + case PN_LIST: + if (pn->pn_type == TOK_NEW || + pn->pn_type == TOK_LP || + pn->pn_type == TOK_LB) { + /* + * All invocation operations (construct: TOK_NEW, call: TOK_LP) + * are presumed to be useful, because they may have side effects + * even if their main effect (their return value) is discarded. + * + * TOK_LB binary trees of 3 or more nodes are flattened into lists + * to avoid too much recursion. All such lists must be presumed + * to be useful because each index operation could invoke a getter + * (the JSOP_ARGUMENTS special case below, in the PN_BINARY case, + * does not apply here: arguments[i][j] might invoke a getter). + */ + *answer = JS_TRUE; + } else { + for (pn2 = pn->pn_head; pn2; pn2 = pn2->pn_next) + ok &= CheckSideEffects(cx, tc, pn2, answer); + } + break; + + case PN_TERNARY: + ok = CheckSideEffects(cx, tc, pn->pn_kid1, answer) && + CheckSideEffects(cx, tc, pn->pn_kid2, answer) && + CheckSideEffects(cx, tc, pn->pn_kid3, answer); + break; + + case PN_BINARY: + if (pn->pn_type == TOK_ASSIGN) { + /* + * Assignment is presumed to be useful, even if the next operation + * is another assignment overwriting this one's ostensible effect, + * because the left operand may be a property with a setter that + * has side effects. + */ + *answer = JS_TRUE; + } else { + if (pn->pn_type == TOK_LB) { + pn2 = pn->pn_left; + if (pn2->pn_type == TOK_NAME && !LookupArgOrVar(cx, tc, pn2)) + return JS_FALSE; + if (pn2->pn_op != JSOP_ARGUMENTS) { + /* + * Any indexed property reference could call a getter with + * side effects, except for arguments[i] where arguments is + * unambiguous. + */ + *answer = JS_TRUE; + } + } + ok = CheckSideEffects(cx, tc, pn->pn_left, answer) && + CheckSideEffects(cx, tc, pn->pn_right, answer); + } + break; + + case PN_UNARY: + if (pn->pn_type == TOK_INC || pn->pn_type == TOK_DEC || + pn->pn_type == TOK_DELETE || + pn->pn_type == TOK_THROW || + pn->pn_type == TOK_DEFSHARP) { + /* All these operations have effects that we must commit. */ + *answer = JS_TRUE; + } else { + ok = CheckSideEffects(cx, tc, pn->pn_kid, answer); + } + break; + + case PN_NAME: + if (pn->pn_type == TOK_NAME) { + if (!LookupArgOrVar(cx, tc, pn)) + return JS_FALSE; + if (pn->pn_slot < 0 && pn->pn_op != JSOP_ARGUMENTS) { + /* + * Not an argument or local variable use, so this expression + * could invoke a getter that has side effects. + */ + *answer = JS_TRUE; + } + } + pn2 = pn->pn_expr; + if (pn->pn_type == TOK_DOT && pn2->pn_type == TOK_NAME) { + if (!LookupArgOrVar(cx, tc, pn2)) + return JS_FALSE; + if (!(pn2->pn_op == JSOP_ARGUMENTS && + pn->pn_atom == cx->runtime->atomState.lengthAtom)) { + /* + * Any dotted property reference could call a getter, except + * for arguments.length where arguments is unambiguous. + */ + *answer = JS_TRUE; + } + } + ok = CheckSideEffects(cx, tc, pn2, answer); + break; + + case PN_NULLARY: + if (pn->pn_type == TOK_DEBUGGER) + *answer = JS_TRUE; + break; + } + return ok; +} + +static JSBool +EmitPropOp(JSContext *cx, JSParseNode *pn, JSOp op, JSCodeGenerator *cg) +{ + JSParseNode *pn2, *pndot, *pnup, *pndown; + ptrdiff_t top; + JSAtomListElement *ale; + + pn2 = pn->pn_expr; + if (op == JSOP_GETPROP && + pn->pn_type == TOK_DOT && + pn2->pn_type == TOK_NAME) { + /* Try to optimize arguments.length into JSOP_ARGCNT. */ + if (!LookupArgOrVar(cx, &cg->treeContext, pn2)) + return JS_FALSE; + if (pn2->pn_op == JSOP_ARGUMENTS && + pn->pn_atom == cx->runtime->atomState.lengthAtom) { + return js_Emit1(cx, cg, JSOP_ARGCNT) >= 0; + } + } + + /* + * If the object operand is also a dotted property reference, reverse the + * list linked via pn_expr temporarily so we can iterate over it from the + * bottom up (reversing again as we go), to avoid excessive recursion. + */ + if (pn2->pn_type == TOK_DOT) { + pndot = pn2; + pnup = NULL; + top = CG_OFFSET(cg); + for (;;) { + /* Reverse pndot->pn_expr to point up, not down. */ + pndot->pn_offset = top; + pndown = pndot->pn_expr; + pndot->pn_expr = pnup; + if (pndown->pn_type != TOK_DOT) + break; + pnup = pndot; + pndot = pndown; + } + + /* pndown is a primary expression, not a dotted property reference. */ + if (!js_EmitTree(cx, cg, pndown)) + return JS_FALSE; + + do { + /* Walk back up the list, emitting annotated name ops. */ + if (js_NewSrcNote2(cx, cg, SRC_PCBASE, + CG_OFFSET(cg) - pndown->pn_offset) < 0) { + return JS_FALSE; + } + ale = js_IndexAtom(cx, pndot->pn_atom, &cg->atomList); + if (!ale) + return JS_FALSE; + EMIT_ATOM_INDEX_OP(pndot->pn_op, ALE_INDEX(ale)); + + /* Reverse the pn_expr link again. */ + pnup = pndot->pn_expr; + pndot->pn_expr = pndown; + pndown = pndot; + } while ((pndot = pnup) != NULL); + } else { + if (!js_EmitTree(cx, cg, pn2)) + return JS_FALSE; + } + + if (js_NewSrcNote2(cx, cg, SRC_PCBASE, CG_OFFSET(cg) - pn2->pn_offset) < 0) + return JS_FALSE; + if (!pn->pn_atom) { + JS_ASSERT(op == JSOP_IMPORTALL); + if (js_Emit1(cx, cg, op) < 0) + return JS_FALSE; + } else { + ale = js_IndexAtom(cx, pn->pn_atom, &cg->atomList); + if (!ale) + return JS_FALSE; + EMIT_ATOM_INDEX_OP(op, ALE_INDEX(ale)); + } + return JS_TRUE; +} + +static JSBool +EmitElemOp(JSContext *cx, JSParseNode *pn, JSOp op, JSCodeGenerator *cg) +{ + ptrdiff_t top; + JSParseNode *left, *right, *next; + jsint slot; + + top = CG_OFFSET(cg); + if (pn->pn_arity == PN_LIST) { + /* Left-associative operator chain to avoid too much recursion. */ + JS_ASSERT(pn->pn_op == JSOP_GETELEM); + JS_ASSERT(pn->pn_count >= 3); + left = pn->pn_head; + right = PN_LAST(pn); + next = left->pn_next; + JS_ASSERT(next != right); + + /* + * Try to optimize arguments[0][j]... into JSOP_ARGSUB<0> followed by + * one or more index expression and JSOP_GETELEM op pairs. + */ + if (left->pn_type == TOK_NAME && next->pn_type == TOK_NUMBER) { + if (!LookupArgOrVar(cx, &cg->treeContext, left)) + return JS_FALSE; + if (left->pn_op == JSOP_ARGUMENTS && + JSDOUBLE_IS_INT(next->pn_dval, slot) && + (jsuint)slot < ATOM_INDEX_LIMIT) { + left->pn_offset = next->pn_offset = top; + EMIT_ATOM_INDEX_OP(JSOP_ARGSUB, (jsatomid)slot); + left = next; + next = left->pn_next; + } + } + + /* + * Check whether we generated JSOP_ARGSUB, just above, and have only + * one more index expression to emit. Given arguments[0][j], we must + * skip the while loop altogether, falling through to emit code for j + * (in the subtree referenced by right), followed by the annotated op, + * at the bottom of this function. + */ + JS_ASSERT(next != right || pn->pn_count == 3); + if (left == pn->pn_head) { + if (!js_EmitTree(cx, cg, left)) + return JS_FALSE; + } + while (next != right) { + if (!js_EmitTree(cx, cg, next)) + return JS_FALSE; + if (js_NewSrcNote2(cx, cg, SRC_PCBASE, CG_OFFSET(cg) - top) < 0) + return JS_FALSE; + if (js_Emit1(cx, cg, JSOP_GETELEM) < 0) + return JS_FALSE; + next = next->pn_next; + } + } else { + JS_ASSERT(pn->pn_arity == PN_BINARY); + left = pn->pn_left; + right = pn->pn_right; + + /* Try to optimize arguments[0] (e.g.) into JSOP_ARGSUB<0>. */ + if (op == JSOP_GETELEM && + left->pn_type == TOK_NAME && + right->pn_type == TOK_NUMBER) { + if (!LookupArgOrVar(cx, &cg->treeContext, left)) + return JS_FALSE; + if (left->pn_op == JSOP_ARGUMENTS && + JSDOUBLE_IS_INT(right->pn_dval, slot) && + (jsuint)slot < ATOM_INDEX_LIMIT) { + left->pn_offset = right->pn_offset = top; + EMIT_ATOM_INDEX_OP(JSOP_ARGSUB, (jsatomid)slot); + return JS_TRUE; + } + } + + if (!js_EmitTree(cx, cg, left)) + return JS_FALSE; + } + if (!js_EmitTree(cx, cg, right)) + return JS_FALSE; + if (js_NewSrcNote2(cx, cg, SRC_PCBASE, CG_OFFSET(cg) - top) < 0) + return JS_FALSE; + return js_Emit1(cx, cg, op) >= 0; +} + +static JSBool +EmitNumberOp(JSContext *cx, jsdouble dval, JSCodeGenerator *cg) +{ + jsint ival; + jsatomid atomIndex; + JSAtom *atom; + JSAtomListElement *ale; + + if (JSDOUBLE_IS_INT(dval, ival) && INT_FITS_IN_JSVAL(ival)) { + if (ival == 0) + return js_Emit1(cx, cg, JSOP_ZERO) >= 0; + if (ival == 1) + return js_Emit1(cx, cg, JSOP_ONE) >= 0; + if ((jsuint)ival < (jsuint)ATOM_INDEX_LIMIT) { + atomIndex = (jsatomid)ival; + EMIT_ATOM_INDEX_OP(JSOP_UINT16, atomIndex); + return JS_TRUE; + } + atom = js_AtomizeInt(cx, ival, 0); + } else { + atom = js_AtomizeDouble(cx, dval, 0); + } + if (!atom) + return JS_FALSE; + ale = js_IndexAtom(cx, atom, &cg->atomList); + if (!ale) + return JS_FALSE; + EMIT_ATOM_INDEX_OP(JSOP_NUMBER, ALE_INDEX(ale)); + return JS_TRUE; +} + +#if JS_HAS_SWITCH_STATEMENT +static JSBool +EmitSwitch(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn, + JSStmtInfo *stmtInfo) +{ + JSOp switchop; + JSBool ok, hasDefault; + ptrdiff_t top, off, defaultOffset; + JSParseNode *pn2, *pn3, *pn4; + uint32 ncases, tablen; + jsdouble d; + jsint i, low, high; + JSAtom *atom; + JSAtomListElement *ale; + intN noteIndex; + size_t switchsize, tablesize; + JSParseNode **table; + jsbytecode *pc; + + /* Try for most optimal, fall back if not dense ints, and per ECMAv2. */ + switchop = JSOP_TABLESWITCH; + ok = JS_TRUE; + hasDefault = JS_FALSE; + defaultOffset = -1; + + /* Emit code for the discriminant first. */ + if (!js_EmitTree(cx, cg, pn->pn_kid1)) + return JS_FALSE; + + /* Switch bytecodes run from here till end of final case. */ + top = CG_OFFSET(cg); + js_PushStatement(&cg->treeContext, stmtInfo, STMT_SWITCH, top); + + pn2 = pn->pn_kid2; + ncases = pn2->pn_count; + tablen = 0; + + if (ncases == 0 || + (ncases == 1 && + (hasDefault = (pn2->pn_head->pn_type == TOK_DEFAULT)))) { + ncases = 0; + low = 0; + high = -1; + } else { +#define INTMAP_LENGTH 256 + jsbitmap intmap_space[INTMAP_LENGTH]; + jsbitmap *intmap = NULL; + int32 intmap_bitlen = 0; + + low = JSVAL_INT_MAX; + high = JSVAL_INT_MIN; + + for (pn3 = pn2->pn_head; pn3; pn3 = pn3->pn_next) { + if (pn3->pn_type == TOK_DEFAULT) { + hasDefault = JS_TRUE; + ncases--; /* one of the "cases" was the default */ + continue; + } + + JS_ASSERT(pn3->pn_type == TOK_CASE); + if (switchop == JSOP_CONDSWITCH) + continue; + + pn4 = pn3->pn_left; + switch (pn4->pn_type) { + case TOK_NUMBER: + d = pn4->pn_dval; + if (JSDOUBLE_IS_INT(d, i) && INT_FITS_IN_JSVAL(i)) { + pn3->pn_val = INT_TO_JSVAL(i); + } else { + atom = js_AtomizeDouble(cx, d, 0); + if (!atom) { + ok = JS_FALSE; + goto release; + } + pn3->pn_val = ATOM_KEY(atom); + } + break; + case TOK_STRING: + pn3->pn_val = ATOM_KEY(pn4->pn_atom); + break; + case TOK_PRIMARY: + if (pn4->pn_op == JSOP_TRUE) { + pn3->pn_val = JSVAL_TRUE; + break; + } + if (pn4->pn_op == JSOP_FALSE) { + pn3->pn_val = JSVAL_FALSE; + break; + } + /* FALL THROUGH */ + default: + switchop = JSOP_CONDSWITCH; + continue; + } + + JS_ASSERT(JSVAL_IS_NUMBER(pn3->pn_val) || + JSVAL_IS_STRING(pn3->pn_val) || + JSVAL_IS_BOOLEAN(pn3->pn_val)); + + if (switchop != JSOP_TABLESWITCH) + continue; + if (!JSVAL_IS_INT(pn3->pn_val)) { + switchop = JSOP_LOOKUPSWITCH; + continue; + } + i = JSVAL_TO_INT(pn3->pn_val); + if ((jsuint)(i + (jsint)JS_BIT(15)) >= (jsuint)JS_BIT(16)) { + switchop = JSOP_LOOKUPSWITCH; + continue; + } + if (i < low) + low = i; + if (high < i) + high = i; + + /* + * Check for duplicates, which require a JSOP_LOOKUPSWITCH. + * We bias i by 65536 if it's negative, and hope that's a rare + * case (because it requires a malloc'd bitmap). + */ + if (i < 0) + i += JS_BIT(16); + if (i >= intmap_bitlen) { + if (!intmap && + i < (INTMAP_LENGTH << JS_BITS_PER_WORD_LOG2)) { + intmap = intmap_space; + intmap_bitlen = INTMAP_LENGTH << JS_BITS_PER_WORD_LOG2; + } else { + /* Just grab 8K for the worst-case bitmap. */ + intmap_bitlen = JS_BIT(16); + intmap = (jsbitmap *) + JS_malloc(cx, + (JS_BIT(16) >> JS_BITS_PER_WORD_LOG2) + * sizeof(jsbitmap)); + if (!intmap) { + JS_ReportOutOfMemory(cx); + return JS_FALSE; + } + } + memset(intmap, 0, intmap_bitlen >> JS_BITS_PER_BYTE_LOG2); + } + if (JS_TEST_BIT(intmap, i)) { + switchop = JSOP_LOOKUPSWITCH; + continue; + } + JS_SET_BIT(intmap, i); + } + + release: + if (intmap && intmap != intmap_space) + JS_free(cx, intmap); + if (!ok) + return JS_FALSE; + + /* + * Compute table length and select lookup instead if overlarge or + * more than half-sparse. + */ + if (switchop == JSOP_TABLESWITCH) { + tablen = (uint32)(high - low + 1); + if (tablen >= JS_BIT(16) || tablen > 2 * ncases) + switchop = JSOP_LOOKUPSWITCH; + } + } + + /* + * Emit a note with two offsets: first tells total switch code length, + * second tells offset to first JSOP_CASE if condswitch. + */ + noteIndex = js_NewSrcNote3(cx, cg, SRC_SWITCH, 0, 0); + if (noteIndex < 0) + return JS_FALSE; + + if (switchop == JSOP_CONDSWITCH) { + /* + * 0 bytes of immediate for unoptimized ECMAv2 switch. + */ + switchsize = 0; + } else if (switchop == JSOP_TABLESWITCH) { + /* + * 3 offsets (len, low, high) before the table, 1 per entry. + */ + switchsize = (size_t)(JUMP_OFFSET_LEN * (3 + tablen)); + } else { + /* + * JSOP_LOOKUPSWITCH: + * 1 offset (len) and 1 atom index (npairs) before the table, + * 1 atom index and 1 jump offset per entry. + */ + switchsize = (size_t)(JUMP_OFFSET_LEN + ATOM_INDEX_LEN + + (ATOM_INDEX_LEN + JUMP_OFFSET_LEN) * ncases); + } + + /* + * Emit switchop followed by switchsize bytes of jump or lookup table. + * + * If switchop is JSOP_LOOKUPSWITCH or JSOP_TABLESWITCH, it is crucial + * to emit the immediate operand(s) by which bytecode readers such as + * BuildSpanDepTable discover the length of the switch opcode *before* + * calling js_SetJumpOffset (which may call BuildSpanDepTable). It's + * also important to zero all unknown jump offset immediate operands, + * so they can be converted to span dependencies with null targets to + * be computed later (js_EmitN zeros switchsize bytes after switchop). + */ + if (js_EmitN(cx, cg, switchop, switchsize) < 0) + return JS_FALSE; + + off = -1; + if (switchop == JSOP_CONDSWITCH) { + intN caseNoteIndex = -1; + + /* Emit code for evaluating cases and jumping to case statements. */ + for (pn3 = pn2->pn_head; pn3; pn3 = pn3->pn_next) { + pn4 = pn3->pn_left; + if (pn4 && !js_EmitTree(cx, cg, pn4)) + return JS_FALSE; + if (caseNoteIndex >= 0) { + /* off is the previous JSOP_CASE's bytecode offset. */ + if (!js_SetSrcNoteOffset(cx, cg, (uintN)caseNoteIndex, 0, + CG_OFFSET(cg) - off)) { + return JS_FALSE; + } + } + if (pn3->pn_type == TOK_DEFAULT) + continue; + caseNoteIndex = js_NewSrcNote2(cx, cg, SRC_PCDELTA, 0); + if (caseNoteIndex < 0) + return JS_FALSE; + off = EmitJump(cx, cg, JSOP_CASE, 0); + if (off < 0) + return JS_FALSE; + pn3->pn_offset = off; + if (pn3 == pn2->pn_head) { + /* Switch note's second offset is to first JSOP_CASE. */ + if (!js_SetSrcNoteOffset(cx, cg, (uintN)noteIndex, 1, + off - top)) { + return JS_FALSE; + } + } + } + + /* Emit default even if no explicit default statement. */ + defaultOffset = EmitJump(cx, cg, JSOP_DEFAULT, 0); + if (defaultOffset < 0) + return JS_FALSE; + } else if (switchop == JSOP_TABLESWITCH) { + /* Fill in switch bounds, which we know fit in 16-bit offsets. */ + pc = CG_CODE(cg, top + JUMP_OFFSET_LEN); + SET_JUMP_OFFSET(pc, low); + pc += JUMP_OFFSET_LEN; + SET_JUMP_OFFSET(pc, high); + pc += JUMP_OFFSET_LEN; + } else { + JS_ASSERT(switchop == JSOP_LOOKUPSWITCH); + + /* Fill in the number of cases. */ + pc = CG_CODE(cg, top + JUMP_OFFSET_LEN); + SET_ATOM_INDEX(pc, ncases); + } + + /* Emit code for each case's statements, copying pn_offset up to pn3. */ + for (pn3 = pn2->pn_head; pn3; pn3 = pn3->pn_next) { + if (switchop == JSOP_CONDSWITCH && pn3->pn_type != TOK_DEFAULT) + CHECK_AND_SET_JUMP_OFFSET_AT(cx, cg, pn3->pn_offset); + pn4 = pn3->pn_right; + if (!js_EmitTree(cx, cg, pn4)) + return JS_FALSE; + pn3->pn_offset = pn4->pn_offset; + if (pn3->pn_type == TOK_DEFAULT) + off = pn3->pn_offset - top; + } + + if (!hasDefault) { + /* If no default case, offset for default is to end of switch. */ + off = CG_OFFSET(cg) - top; + } + + /* We better have set "off" by now. */ + JS_ASSERT(off != -1); + + /* Set the default offset (to end of switch if no default). */ + pc = NULL; + if (switchop == JSOP_CONDSWITCH) { + JS_ASSERT(defaultOffset != -1); + if (!js_SetJumpOffset(cx, cg, CG_CODE(cg, defaultOffset), + off - (defaultOffset - top))) { + return JS_FALSE; + } + } else { + pc = CG_CODE(cg, top); + if (!js_SetJumpOffset(cx, cg, pc, off)) + return JS_FALSE; + pc += JUMP_OFFSET_LEN; + } + + /* Set the SRC_SWITCH note's offset operand to tell end of switch. */ + off = CG_OFFSET(cg) - top; + if (!js_SetSrcNoteOffset(cx, cg, (uintN)noteIndex, 0, off)) + return JS_FALSE; + + if (switchop == JSOP_TABLESWITCH) { + /* Skip over the already-initialized switch bounds. */ + pc += 2 * JUMP_OFFSET_LEN; + + /* Fill in the jump table, if there is one. */ + if (tablen) { + /* Avoid bloat for a compilation unit with many switches. */ + tablesize = (size_t)tablen * sizeof *table; + table = (JSParseNode **) JS_malloc(cx, tablesize); + if (!table) + return JS_FALSE; + memset(table, 0, tablesize); + for (pn3 = pn2->pn_head; pn3; pn3 = pn3->pn_next) { + if (pn3->pn_type == TOK_DEFAULT) + continue; + i = JSVAL_TO_INT(pn3->pn_val); + i -= low; + JS_ASSERT((uint32)i < tablen); + table[i] = pn3; + } + for (i = 0; i < (jsint)tablen; i++) { + pn3 = table[i]; + off = pn3 ? pn3->pn_offset - top : 0; + ok = js_SetJumpOffset(cx, cg, pc, off); + if (!ok) + break; + pc += JUMP_OFFSET_LEN; + } + JS_free(cx, table); + if (!ok) + return JS_FALSE; + } + } else if (switchop == JSOP_LOOKUPSWITCH) { + /* Skip over the already-initialized number of cases. */ + pc += ATOM_INDEX_LEN; + + for (pn3 = pn2->pn_head; pn3; pn3 = pn3->pn_next) { + if (pn3->pn_type == TOK_DEFAULT) + continue; + atom = js_AtomizeValue(cx, pn3->pn_val, 0); + if (!atom) + return JS_FALSE; + ale = js_IndexAtom(cx, atom, &cg->atomList); + if (!ale) + return JS_FALSE; + SET_ATOM_INDEX(pc, ALE_INDEX(ale)); + pc += ATOM_INDEX_LEN; + + off = pn3->pn_offset - top; + if (!js_SetJumpOffset(cx, cg, pc, off)) + return JS_FALSE; + pc += JUMP_OFFSET_LEN; + } + } + + return js_PopStatementCG(cx, cg); +} +#endif /* JS_HAS_SWITCH_STATEMENT */ + +JSBool +js_EmitFunctionBody(JSContext *cx, JSCodeGenerator *cg, JSParseNode *body, + JSFunction *fun) +{ + JSStackFrame *fp, frame; + JSObject *funobj; + JSBool ok; + + if (!js_AllocTryNotes(cx, cg)) + return JS_FALSE; + + fp = cx->fp; + funobj = fun->object; + if (!fp || fp->fun != fun || fp->varobj != funobj || + fp->scopeChain != funobj) { + memset(&frame, 0, sizeof frame); + frame.fun = fun; + frame.varobj = frame.scopeChain = funobj; + frame.down = fp; + cx->fp = &frame; + } + ok = js_EmitTree(cx, cg, body); + cx->fp = fp; + if (!ok) + return JS_FALSE; + + fun->script = js_NewScriptFromCG(cx, cg, fun); + if (!fun->script) + return JS_FALSE; + if (cg->treeContext.flags & TCF_FUN_HEAVYWEIGHT) + fun->flags |= JSFUN_HEAVYWEIGHT; + return JS_TRUE; +} + +/* A macro for inlining at the top of js_EmitTree (whence it came). */ +#define UPDATE_LINE_NUMBER_NOTES(cx, cg, pn) \ + JS_BEGIN_MACRO \ + uintN line_ = (pn)->pn_pos.begin.lineno; \ + uintN delta_ = line_ - CG_CURRENT_LINE(cg); \ + if (delta_ != 0) { \ + /* \ + * Encode any change in the current source line number by using \ + * either several SRC_NEWLINE notes or just one SRC_SETLINE note, \ + * whichever consumes less space. \ + * \ + * NB: We handle backward line number deltas (possible with for \ + * loops where the update part is emitted after the body, but its \ + * line number is <= any line number in the body) here by letting \ + * unsigned delta_ wrap to a very large number, which triggers a \ + * SRC_SETLINE. \ + */ \ + CG_CURRENT_LINE(cg) = line_; \ + if (delta_ >= (uintN)(2 + ((line_ > SN_3BYTE_OFFSET_MASK)<<1))) { \ + if (js_NewSrcNote2(cx, cg, SRC_SETLINE, (ptrdiff_t)line_) < 0)\ + return JS_FALSE; \ + } else { \ + do { \ + if (js_NewSrcNote(cx, cg, SRC_NEWLINE) < 0) \ + return JS_FALSE; \ + } while (--delta_ != 0); \ + } \ + } \ + JS_END_MACRO + +/* A function, so that we avoid macro-bloating all the other callsites. */ +static JSBool +UpdateLineNumberNotes(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn) +{ + UPDATE_LINE_NUMBER_NOTES(cx, cg, pn); + return JS_TRUE; +} + +JSBool +js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn) +{ + JSBool ok, useful, wantval; + JSStmtInfo *stmt, stmtInfo; + ptrdiff_t top, off, tmp, beq, jmp; + JSParseNode *pn2, *pn3; + JSAtom *atom; + JSAtomListElement *ale; + jsatomid atomIndex; + intN noteIndex; + JSSrcNoteType noteType; + jsbytecode *pc; + JSOp op; + uint32 argc; + int stackDummy; + + if (!JS_CHECK_STACK_SIZE(cx, stackDummy)) { + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_OVER_RECURSED); + return JS_FALSE; + } + + ok = JS_TRUE; + cg->emitLevel++; + pn->pn_offset = top = CG_OFFSET(cg); + + /* Emit notes to tell the current bytecode's source line number. */ + UPDATE_LINE_NUMBER_NOTES(cx, cg, pn); + + switch (pn->pn_type) { + case TOK_FUNCTION: + { + void *cg2mark; + JSCodeGenerator *cg2; + JSFunction *fun; + + /* Generate code for the function's body. */ + cg2mark = JS_ARENA_MARK(&cx->tempPool); + JS_ARENA_ALLOCATE_TYPE(cg2, JSCodeGenerator, &cx->tempPool); + if (!cg2) { + JS_ReportOutOfMemory(cx); + return JS_FALSE; + } + if (!js_InitCodeGenerator(cx, cg2, cg->codePool, cg->notePool, + cg->filename, pn->pn_pos.begin.lineno, + cg->principals)) { + return JS_FALSE; + } + cg2->treeContext.flags = pn->pn_flags | TCF_IN_FUNCTION; + cg2->treeContext.tryCount = pn->pn_tryCount; + fun = (JSFunction *) JS_GetPrivate(cx, ATOM_TO_OBJECT(pn->pn_funAtom)); + if (!js_EmitFunctionBody(cx, cg2, pn->pn_body, fun)) + return JS_FALSE; + + /* + * We need an activation object if an inner peeks out, or if such + * inner-peeking caused one of our inners to become heavyweight. + */ + if (cg2->treeContext.flags & + (TCF_FUN_USES_NONLOCALS | TCF_FUN_HEAVYWEIGHT)) { + cg->treeContext.flags |= TCF_FUN_HEAVYWEIGHT; + } + js_FinishCodeGenerator(cx, cg2); + JS_ARENA_RELEASE(&cx->tempPool, cg2mark); + + /* Make the function object a literal in the outer script's pool. */ + ale = js_IndexAtom(cx, pn->pn_funAtom, &cg->atomList); + if (!ale) + return JS_FALSE; + atomIndex = ALE_INDEX(ale); + +#if JS_HAS_LEXICAL_CLOSURE + /* Emit a bytecode pointing to the closure object in its immediate. */ + if (pn->pn_op != JSOP_NOP) { + EMIT_ATOM_INDEX_OP(pn->pn_op, atomIndex); + break; + } +#endif + + /* Top-level named functions need a nop for decompilation. */ + noteIndex = js_NewSrcNote2(cx, cg, SRC_FUNCDEF, (ptrdiff_t)atomIndex); + if (noteIndex < 0 || + js_Emit1(cx, cg, JSOP_NOP) < 0) { + return JS_FALSE; + } + + /* + * Top-levels also need a prolog op to predefine their names in the + * variable object, or if local, to fill their stack slots. + */ + CG_SWITCH_TO_PROLOG(cg); + +#if JS_HAS_LEXICAL_CLOSURE + if (cg->treeContext.flags & TCF_IN_FUNCTION) { + JSObject *obj, *pobj; + JSScopeProperty *sprop; + uintN slot; + + obj = OBJ_GET_PARENT(cx, fun->object); + if (!js_LookupProperty(cx, obj, (jsid)fun->atom, &pobj, + (JSProperty **)&sprop)) { + return JS_FALSE; + } + JS_ASSERT(sprop && pobj == obj); + slot = sprop->shortid; + OBJ_DROP_PROPERTY(cx, pobj, (JSProperty *)sprop); + + /* Emit [JSOP_DEFLOCALFUN, local variable slot, atomIndex]. */ + off = js_EmitN(cx, cg, JSOP_DEFLOCALFUN, VARNO_LEN+ATOM_INDEX_LEN); + if (off < 0) + return JS_FALSE; + pc = CG_CODE(cg, off); + SET_VARNO(pc, slot); + pc += VARNO_LEN; + SET_ATOM_INDEX(pc, atomIndex); + } else +#endif + EMIT_ATOM_INDEX_OP(JSOP_DEFFUN, atomIndex); + + CG_SWITCH_TO_MAIN(cg); + break; + } + +#if JS_HAS_EXPORT_IMPORT + case TOK_EXPORT: + pn2 = pn->pn_head; + if (pn2->pn_type == TOK_STAR) { + /* + * 'export *' must have no other elements in the list (what would + * be the point?). + */ + if (js_Emit1(cx, cg, JSOP_EXPORTALL) < 0) + return JS_FALSE; + } else { + /* + * If not 'export *', the list consists of NAME nodes identifying + * properties of the variables object to flag as exported. + */ + do { + ale = js_IndexAtom(cx, pn2->pn_atom, &cg->atomList); + if (!ale) + return JS_FALSE; + EMIT_ATOM_INDEX_OP(JSOP_EXPORTNAME, ALE_INDEX(ale)); + } while ((pn2 = pn2->pn_next) != NULL); + } + break; + + case TOK_IMPORT: + for (pn2 = pn->pn_head; pn2; pn2 = pn2->pn_next) { + /* + * Each subtree on an import list is rooted by a DOT or LB node. + * A DOT may have a null pn_atom member, in which case pn_op must + * be JSOP_IMPORTALL -- see EmitPropOp above. + */ + if (!js_EmitTree(cx, cg, pn2)) + return JS_FALSE; + } + break; +#endif /* JS_HAS_EXPORT_IMPORT */ + + case TOK_IF: + /* Initialize so we can detect else-if chains and avoid recursion. */ + stmtInfo.type = STMT_IF; + beq = jmp = -1; + noteIndex = -1; + + if_again: + /* Emit code for the condition before pushing stmtInfo. */ + if (!js_EmitTree(cx, cg, pn->pn_kid1)) + return JS_FALSE; + if (stmtInfo.type == STMT_IF) { + js_PushStatement(&cg->treeContext, &stmtInfo, STMT_IF, + CG_OFFSET(cg)); + } else { + /* + * We came here from the goto further below that detects else-if + * chains, so we must mutate stmtInfo back into a STMT_IF record. + * Also (see below for why) we need a note offset for SRC_IF_ELSE + * to help the decompiler. + */ + JS_ASSERT(stmtInfo.type == STMT_ELSE); + stmtInfo.type = STMT_IF; + if (!js_SetSrcNoteOffset(cx, cg, noteIndex, 0, jmp - beq)) + return JS_FALSE; + } + + /* Emit an annotated branch-if-false around the then part. */ + pn3 = pn->pn_kid3; + noteIndex = js_NewSrcNote(cx, cg, pn3 ? SRC_IF_ELSE : SRC_IF); + if (noteIndex < 0) + return JS_FALSE; + beq = EmitJump(cx, cg, JSOP_IFEQ, 0); + if (beq < 0) + return JS_FALSE; + + /* Emit code for the then and optional else parts. */ + if (!js_EmitTree(cx, cg, pn->pn_kid2)) + return JS_FALSE; + if (pn3) { + /* Modify stmtInfo so we know we're in the else part. */ + stmtInfo.type = STMT_ELSE; + + /* + * Emit a JSOP_BACKPATCH op to jump from the end of our then part + * around the else part. The js_PopStatementCG call at the bottom + * of this switch case will fix up the backpatch chain linked from + * stmtInfo.breaks. + */ + jmp = EmitGoto(cx, cg, &stmtInfo, &stmtInfo.breaks, NULL, SRC_NULL); + if (jmp < 0) + return JS_FALSE; + + /* Ensure the branch-if-false comes here, then emit the else. */ + CHECK_AND_SET_JUMP_OFFSET_AT(cx, cg, beq); + if (pn3->pn_type == TOK_IF) { + pn = pn3; + goto if_again; + } + + if (!js_EmitTree(cx, cg, pn3)) + return JS_FALSE; + + /* + * Annotate SRC_IF_ELSE with the offset from branch to jump, for + * the decompiler's benefit. We can't just "back up" from the pc + * of the else clause, because we don't know whether an extended + * jump was required to leap from the end of the then clause over + * the else clause. + */ + if (!js_SetSrcNoteOffset(cx, cg, noteIndex, 0, jmp - beq)) + return JS_FALSE; + } else { + /* No else part, fixup the branch-if-false to come here. */ + CHECK_AND_SET_JUMP_OFFSET_AT(cx, cg, beq); + } + ok = js_PopStatementCG(cx, cg); + break; + +#if JS_HAS_SWITCH_STATEMENT + case TOK_SWITCH: + /* Out of line to avoid bloating js_EmitTree's stack frame size. */ + ok = EmitSwitch(cx, cg, pn, &stmtInfo); + break; +#endif /* JS_HAS_SWITCH_STATEMENT */ + + case TOK_WHILE: + js_PushStatement(&cg->treeContext, &stmtInfo, STMT_WHILE_LOOP, top); + if (!js_EmitTree(cx, cg, pn->pn_left)) + return JS_FALSE; + noteIndex = js_NewSrcNote(cx, cg, SRC_WHILE); + if (noteIndex < 0) + return JS_FALSE; + beq = EmitJump(cx, cg, JSOP_IFEQ, 0); + if (beq < 0) + return JS_FALSE; + if (!js_EmitTree(cx, cg, pn->pn_right)) + return JS_FALSE; + jmp = EmitJump(cx, cg, JSOP_GOTO, top - CG_OFFSET(cg)); + if (jmp < 0) + return JS_FALSE; + CHECK_AND_SET_JUMP_OFFSET_AT(cx, cg, beq); + if (!js_SetSrcNoteOffset(cx, cg, noteIndex, 0, jmp - beq)) + return JS_FALSE; + ok = js_PopStatementCG(cx, cg); + break; + +#if JS_HAS_DO_WHILE_LOOP + case TOK_DO: + /* Emit an annotated nop so we know to decompile a 'do' keyword. */ + if (js_NewSrcNote(cx, cg, SRC_WHILE) < 0 || + js_Emit1(cx, cg, JSOP_NOP) < 0) { + return JS_FALSE; + } + + /* Compile the loop body. */ + top = CG_OFFSET(cg); + js_PushStatement(&cg->treeContext, &stmtInfo, STMT_DO_LOOP, top); + if (!js_EmitTree(cx, cg, pn->pn_left)) + return JS_FALSE; + + /* Set loop and enclosing label update offsets, for continue. */ + stmt = &stmtInfo; + do { + stmt->update = CG_OFFSET(cg); + } while ((stmt = stmt->down) != NULL && stmt->type == STMT_LABEL); + + /* Compile the loop condition, now that continues know where to go. */ + if (!js_EmitTree(cx, cg, pn->pn_right)) + return JS_FALSE; + + /* + * No source note needed, because JSOP_IFNE is used only for do-while. + * If we ever use JSOP_IFNE for other purposes, we can still avoid yet + * another note here, by storing (jmp - top) in the SRC_WHILE note's + * offset, and fetching that delta in order to decompile recursively. + */ + if (EmitJump(cx, cg, JSOP_IFNE, top - CG_OFFSET(cg)) < 0) + return JS_FALSE; + ok = js_PopStatementCG(cx, cg); + break; +#endif /* JS_HAS_DO_WHILE_LOOP */ + + case TOK_FOR: + beq = 0; /* suppress gcc warnings */ + pn2 = pn->pn_left; + js_PushStatement(&cg->treeContext, &stmtInfo, STMT_FOR_LOOP, top); + + if (pn2->pn_type == TOK_IN) { + /* Set stmtInfo type for later testing. */ + stmtInfo.type = STMT_FOR_IN_LOOP; + noteIndex = -1; + + /* If the left part is var x = i, bind x, evaluate i, and pop. */ + pn3 = pn2->pn_left; + if (pn3->pn_type == TOK_VAR && pn3->pn_head->pn_expr) { + if (!js_EmitTree(cx, cg, pn3)) + return JS_FALSE; + /* Set pn3 to the variable name, to avoid another var note. */ + pn3 = pn3->pn_head; + JS_ASSERT(pn3->pn_type == TOK_NAME); + } + + /* Emit a push to allocate the iterator. */ + if (js_Emit1(cx, cg, JSOP_PUSH) < 0) + return JS_FALSE; + + /* Compile the object expression to the right of 'in'. */ + if (!js_EmitTree(cx, cg, pn2->pn_right)) + return JS_FALSE; + if (js_Emit1(cx, cg, JSOP_TOOBJECT) < 0) + return JS_FALSE; + + top = CG_OFFSET(cg); + SET_STATEMENT_TOP(&stmtInfo, top); + + /* Compile a JSOP_FOR* bytecode based on the left hand side. */ + switch (pn3->pn_type) { + case TOK_VAR: + pn3 = pn3->pn_head; + if (js_NewSrcNote(cx, cg, SRC_VAR) < 0) + return JS_FALSE; + /* FALL THROUGH */ + case TOK_NAME: + pn3->pn_op = JSOP_FORNAME; + if (!LookupArgOrVar(cx, &cg->treeContext, pn3)) + return JS_FALSE; + op = pn3->pn_op; + if (pn3->pn_slot >= 0) { + if (pn3->pn_attrs & JSPROP_READONLY) + op = JSOP_GETVAR; + atomIndex = (jsatomid) pn3->pn_slot; + EMIT_ATOM_INDEX_OP(op, atomIndex); + } else { + if (!EmitAtomOp(cx, pn3, op, cg)) + return JS_FALSE; + } + break; + + case TOK_DOT: + if (!EmitPropOp(cx, pn3, JSOP_FORPROP, cg)) + return JS_FALSE; + break; + + case TOK_LB: + /* + * We separate the first/next bytecode from the enumerator + * variable binding to avoid any side-effects in the index + * expression (e.g., for (x[i++] in {}) should not bind x[i] + * or increment i at all). + */ + if (!js_Emit1(cx, cg, JSOP_FORELEM)) + return JS_FALSE; + + /* + * Emit a SRC_WHILE note with offset telling the distance to + * the loop-closing jump (we can't reckon from the branch at + * the top of the loop, because the loop-closing jump might + * need to be an extended jump, independent of whether the + * branch is short or long). + */ + noteIndex = js_NewSrcNote(cx, cg, SRC_WHILE); + if (noteIndex < 0) + return JS_FALSE; + beq = EmitJump(cx, cg, JSOP_IFEQ, 0); + if (beq < 0) + return JS_FALSE; + + /* Now that we're safely past the IFEQ, commit side effects. */ + if (!EmitElemOp(cx, pn3, JSOP_ENUMELEM, cg)) + return JS_FALSE; + break; + + default: + JS_ASSERT(0); + } + if (pn3->pn_type != TOK_LB) { + /* Annotate so the decompiler can find the loop-closing jump. */ + noteIndex = js_NewSrcNote(cx, cg, SRC_WHILE); + if (noteIndex < 0) + return JS_FALSE; + + /* Pop and test the loop condition generated by JSOP_FOR*. */ + beq = EmitJump(cx, cg, JSOP_IFEQ, 0); + if (beq < 0) + return JS_FALSE; + } + } else { + if (!pn2->pn_kid1) { + /* No initializer: emit an annotated nop for the decompiler. */ + op = JSOP_NOP; + } else { + if (!js_EmitTree(cx, cg, pn2->pn_kid1)) + return JS_FALSE; + op = JSOP_POP; + } + noteIndex = js_NewSrcNote(cx, cg, SRC_FOR); + if (noteIndex < 0 || + js_Emit1(cx, cg, op) < 0) { + return JS_FALSE; + } + + top = CG_OFFSET(cg); + SET_STATEMENT_TOP(&stmtInfo, top); + if (!pn2->pn_kid2) { + /* No loop condition: flag this fact in the source notes. */ + if (!js_SetSrcNoteOffset(cx, cg, (uintN)noteIndex, 0, 0)) + return JS_FALSE; + } else { + if (!js_EmitTree(cx, cg, pn2->pn_kid2)) + return JS_FALSE; + if (!js_SetSrcNoteOffset(cx, cg, (uintN)noteIndex, 0, + CG_OFFSET(cg) - top)) { + return JS_FALSE; + } + beq = EmitJump(cx, cg, JSOP_IFEQ, 0); + if (beq < 0) + return JS_FALSE; + } + + /* Set pn3 (used below) here to avoid spurious gcc warnings. */ + pn3 = pn2->pn_kid3; + } + + /* Emit code for the loop body. */ + if (!js_EmitTree(cx, cg, pn->pn_right)) + return JS_FALSE; + + if (pn2->pn_type != TOK_IN) { + /* Set the second note offset so we can find the update part. */ + JS_ASSERT(noteIndex != -1); + if (!js_SetSrcNoteOffset(cx, cg, (uintN)noteIndex, 1, + CG_OFFSET(cg) - top)) { + return JS_FALSE; + } + + if (pn3) { + /* Set loop and enclosing "update" offsets, for continue. */ + stmt = &stmtInfo; + do { + stmt->update = CG_OFFSET(cg); + } while ((stmt = stmt->down) != NULL && + stmt->type == STMT_LABEL); + + if (!js_EmitTree(cx, cg, pn3)) + return JS_FALSE; + if (js_Emit1(cx, cg, JSOP_POP) < 0) + return JS_FALSE; + + /* Restore the absolute line number for source note readers. */ + off = (ptrdiff_t) pn->pn_pos.end.lineno; + if (CG_CURRENT_LINE(cg) != (uintN) off) { + if (js_NewSrcNote2(cx, cg, SRC_SETLINE, off) < 0) + return JS_FALSE; + CG_CURRENT_LINE(cg) = (uintN) off; + } + } + + /* The third note offset helps us find the loop-closing jump. */ + if (!js_SetSrcNoteOffset(cx, cg, (uintN)noteIndex, 2, + CG_OFFSET(cg) - top)) { + return JS_FALSE; + } + } + + /* Emit the loop-closing jump and fixup all jump offsets. */ + jmp = EmitJump(cx, cg, JSOP_GOTO, top - CG_OFFSET(cg)); + if (jmp < 0) + return JS_FALSE; + if (beq > 0) + CHECK_AND_SET_JUMP_OFFSET_AT(cx, cg, beq); + if (pn2->pn_type == TOK_IN) { + /* Set the SRC_WHILE note offset so we can find the closing jump. */ + JS_ASSERT(noteIndex != -1); + if (!js_SetSrcNoteOffset(cx, cg, (uintN)noteIndex, 0, jmp - beq)) + return JS_FALSE; + } + + /* Now fixup all breaks and continues (before for/in's final POP2). */ + if (!js_PopStatementCG(cx, cg)) + return JS_FALSE; + + if (pn2->pn_type == TOK_IN) { + /* + * Generate the object and iterator pop opcodes after popping the + * stmtInfo stack, so breaks will go to this pop bytecode. + */ + if (pn3->pn_type != TOK_LB) { + if (js_Emit1(cx, cg, JSOP_POP2) < 0) + return JS_FALSE; + } else { + /* + * With 'for(x[i]...)', there's only the object on the stack, + * so we need to hide the pop. + */ + if (js_NewSrcNote(cx, cg, SRC_HIDDEN) < 0) + return JS_FALSE; + if (js_Emit1(cx, cg, JSOP_POP) < 0) + return JS_FALSE; + } + } + break; + + case TOK_BREAK: + stmt = cg->treeContext.topStmt; + atom = pn->pn_atom; + if (atom) { + ale = js_IndexAtom(cx, atom, &cg->atomList); + if (!ale) + return JS_FALSE; + while (stmt->type != STMT_LABEL || stmt->label != atom) + stmt = stmt->down; + noteType = SRC_BREAK2LABEL; + } else { + ale = NULL; + while (!STMT_IS_LOOP(stmt) && stmt->type != STMT_SWITCH) + stmt = stmt->down; + noteType = SRC_NULL; + } + + if (EmitGoto(cx, cg, stmt, &stmt->breaks, ale, noteType) < 0) + return JS_FALSE; + break; + + case TOK_CONTINUE: + stmt = cg->treeContext.topStmt; + atom = pn->pn_atom; + if (atom) { + /* Find the loop statement enclosed by the matching label. */ + JSStmtInfo *loop = NULL; + ale = js_IndexAtom(cx, atom, &cg->atomList); + if (!ale) + return JS_FALSE; + while (stmt->type != STMT_LABEL || stmt->label != atom) { + if (STMT_IS_LOOP(stmt)) + loop = stmt; + stmt = stmt->down; + } + stmt = loop; + noteType = SRC_CONT2LABEL; + } else { + ale = NULL; + while (!STMT_IS_LOOP(stmt)) + stmt = stmt->down; + noteType = SRC_CONTINUE; + } + + if (EmitGoto(cx, cg, stmt, &stmt->continues, ale, noteType) < 0) + return JS_FALSE; + break; + + case TOK_WITH: + if (!js_EmitTree(cx, cg, pn->pn_left)) + return JS_FALSE; + js_PushStatement(&cg->treeContext, &stmtInfo, STMT_WITH, CG_OFFSET(cg)); + if (js_Emit1(cx, cg, JSOP_ENTERWITH) < 0) + return JS_FALSE; + if (!js_EmitTree(cx, cg, pn->pn_right)) + return JS_FALSE; + if (js_Emit1(cx, cg, JSOP_LEAVEWITH) < 0) + return JS_FALSE; + ok = js_PopStatementCG(cx, cg); + break; + +#if JS_HAS_EXCEPTIONS + + case TOK_TRY: + { + ptrdiff_t start, end, catchStart, finallyCatch, catchJump; + JSParseNode *iter; + intN depth; + + /* Quell GCC overwarnings. */ + end = catchStart = finallyCatch = catchJump = -1; + +/* Emit JSOP_GOTO that points to the first op after the catch/finally blocks */ +#define EMIT_CATCH_GOTO(cx, cg, jmp) \ + EMIT_BACKPATCH_OP(cx, cg, stmtInfo.catchJump, JSOP_BACKPATCH, jmp) + +/* Emit JSOP_GOSUB that points to the finally block. */ +#define EMIT_FINALLY_GOSUB(cx, cg, jmp) \ + EMIT_BACKPATCH_OP(cx, cg, stmtInfo.gosub, JSOP_BACKPATCH_PUSH, jmp) + + /* + * Push stmtInfo to track jumps-over-catches and gosubs-to-finally + * for later fixup. + * + * When a finally block is `active' (STMT_FINALLY on the treeContext), + * non-local jumps (including jumps-over-catches) result in a GOSUB + * being written into the bytecode stream and fixed-up later (c.f. + * EMIT_BACKPATCH_OP and BackPatch). + */ + js_PushStatement(&cg->treeContext, &stmtInfo, + pn->pn_kid3 ? STMT_FINALLY : STMT_BLOCK, + CG_OFFSET(cg)); + + /* + * About JSOP_SETSP: an exception can be thrown while the stack is in + * an unbalanced state, and this imbalance causes problems with things + * like function invocation later on. + * + * To fix this, we compute the `balanced' stack depth upon try entry, + * and then restore the stack to this depth when we hit the first catch + * or finally block. We can't just zero the stack, because things like + * for/in and with that are active upon entry to the block keep state + * variables on the stack. + */ + depth = cg->stackDepth; + + /* Mark try location for decompilation, then emit try block. */ + if (js_Emit1(cx, cg, JSOP_TRY) < 0) + return JS_FALSE; + start = CG_OFFSET(cg); + if (!js_EmitTree(cx, cg, pn->pn_kid1)) + return JS_FALSE; + + /* GOSUB to finally, if present. */ + if (pn->pn_kid3) { + if (js_NewSrcNote(cx, cg, SRC_HIDDEN) < 0) + return JS_FALSE; + EMIT_FINALLY_GOSUB(cx, cg, jmp); + if (jmp < 0) + return JS_FALSE; + } + + /* Emit (hidden) jump over catch and/or finally. */ + if (js_NewSrcNote(cx, cg, SRC_HIDDEN) < 0) + return JS_FALSE; + EMIT_CATCH_GOTO(cx, cg, jmp); + if (jmp < 0) + return JS_FALSE; + + end = CG_OFFSET(cg); + + /* If this try has a catch block, emit it. */ + iter = pn->pn_kid2; + if (iter) { + catchStart = end; + + /* + * The emitted code for a catch block looks like: + * + * [ popscope ] only if 2nd+ catch block + * name Object + * pushobj + * newinit + * exception + * initcatchvar + * enterwith + * [< catchguard code >] if there's a catchguard + * [ifeq ] " " + * < catch block contents > + * leavewith + * goto non-local; finally applies + * + * If there's no catch block without a catchguard, the last + * points to rethrow code. This + * code will GOSUB to the finally code if appropriate, and is + * also used for the catch-all trynote for capturing exceptions + * thrown from catch{} blocks. + */ + for (;;) { + JSStmtInfo stmtInfo2; + JSParseNode *disc; + ptrdiff_t guardnote; + + if (!UpdateLineNumberNotes(cx, cg, iter)) + return JS_FALSE; + + if (catchJump != -1) { + /* Fix up and clean up previous catch block. */ + CHECK_AND_SET_JUMP_OFFSET_AT(cx, cg, catchJump); + + /* Compensate for the [leavewith]. */ + cg->stackDepth++; + JS_ASSERT((uintN) cg->stackDepth <= cg->maxStackDepth); + + if (js_NewSrcNote(cx, cg, SRC_HIDDEN) < 0 || + js_Emit1(cx, cg, JSOP_LEAVEWITH) < 0) { + return JS_FALSE; + } + } else { + /* Set stack to original depth (see SETSP comment above). */ + EMIT_ATOM_INDEX_OP(JSOP_SETSP, (jsatomid)depth); + cg->stackDepth = depth; + } + + /* Non-negative guardnote offset is length of catchguard. */ + guardnote = js_NewSrcNote2(cx, cg, SRC_CATCH, 0); + if (guardnote < 0 || + js_Emit1(cx, cg, JSOP_NOP) < 0) { + return JS_FALSE; + } + + /* Construct the scope holder and push it on. */ + ale = js_IndexAtom(cx, cx->runtime->atomState.ObjectAtom, + &cg->atomList); + if (!ale) + return JS_FALSE; + EMIT_ATOM_INDEX_OP(JSOP_NAME, ALE_INDEX(ale)); + + if (js_Emit1(cx, cg, JSOP_PUSHOBJ) < 0 || + js_Emit1(cx, cg, JSOP_NEWINIT) < 0 || + js_Emit1(cx, cg, JSOP_EXCEPTION) < 0) { + return JS_FALSE; + } + + /* initcatchvar */ + disc = iter->pn_kid1; + ale = js_IndexAtom(cx, disc->pn_atom, &cg->atomList); + if (!ale) + return JS_FALSE; + + EMIT_ATOM_INDEX_OP(JSOP_INITCATCHVAR, ALE_INDEX(ale)); + if (js_NewSrcNote(cx, cg, SRC_HIDDEN) < 0 || + js_Emit1(cx, cg, JSOP_ENTERWITH) < 0) { + return JS_FALSE; + } + + /* boolean_expr */ + if (disc->pn_expr) { + ptrdiff_t guardstart = CG_OFFSET(cg); + if (!js_EmitTree(cx, cg, disc->pn_expr)) + return JS_FALSE; + if (!js_SetSrcNoteOffset(cx, cg, guardnote, 0, + CG_OFFSET(cg) - guardstart)) { + return JS_FALSE; + } + /* ifeq */ + catchJump = EmitJump(cx, cg, JSOP_IFEQ, 0); + if (catchJump < 0) + return JS_FALSE; + } + + /* Emit catch block. */ + js_PushStatement(&cg->treeContext, &stmtInfo2, STMT_CATCH, + CG_OFFSET(cg)); + stmtInfo2.label = disc->pn_atom; + if (!js_EmitTree(cx, cg, iter->pn_kid3)) + return JS_FALSE; + js_PopStatementCG(cx, cg); + + /* + * Jump over the remaining catch blocks. + * This counts as a non-local jump, so do the finally thing. + */ + + /* popscope */ + if (js_NewSrcNote(cx, cg, SRC_HIDDEN) < 0 || + js_Emit1(cx, cg, JSOP_LEAVEWITH) < 0) { + return JS_FALSE; + } + + /* gosub , if required */ + if (pn->pn_kid3) { + EMIT_FINALLY_GOSUB(cx, cg, jmp); + if (jmp < 0) + return JS_FALSE; + } + + /* This will get fixed up to jump to after catch/finally. */ + if (js_NewSrcNote(cx, cg, SRC_HIDDEN) < 0) + return JS_FALSE; + EMIT_CATCH_GOTO(cx, cg, jmp); + if (jmp < 0) + return JS_FALSE; + if (!iter->pn_kid2) /* leave iter at last catch */ + break; + iter = iter->pn_kid2; + } + } + + /* + * We use a [leavewith],[gosub],rethrow block for rethrowing + * when there's no unguarded catch, and also for running finally + * code while letting an uncaught exception pass through. + */ + if (pn->pn_kid3 || + (catchJump != -1 && iter->pn_kid1->pn_expr)) { + /* + * Emit another stack fixup, because the catch could itself + * throw an exception in an unbalanced state, and the finally + * may need to call functions. If there is no finally, only + * guarded catches, the rethrow code below nevertheless needs + * stack fixup. + */ + finallyCatch = CG_OFFSET(cg); + EMIT_ATOM_INDEX_OP(JSOP_SETSP, (jsatomid)depth); + cg->stackDepth = depth; + + /* Last discriminant jumps to rethrow if none match. */ + if (catchJump != -1 && iter->pn_kid1->pn_expr) { + CHECK_AND_SET_JUMP_OFFSET_AT(cx, cg, catchJump); + + /* Compensate for the [leavewith]. */ + cg->stackDepth++; + JS_ASSERT((uintN) cg->stackDepth <= cg->maxStackDepth); + + if (js_NewSrcNote(cx, cg, SRC_HIDDEN) < 0 || + js_Emit1(cx, cg, JSOP_LEAVEWITH) < 0) { + return JS_FALSE; + } + } + + if (pn->pn_kid3) { + EMIT_FINALLY_GOSUB(cx, cg, jmp); + if (jmp < 0) + return JS_FALSE; + cg->stackDepth = depth; + } + + if (js_NewSrcNote(cx, cg, SRC_HIDDEN) < 0 || + js_Emit1(cx, cg, JSOP_EXCEPTION) < 0 || + js_NewSrcNote(cx, cg, SRC_HIDDEN) < 0 || + js_Emit1(cx, cg, JSOP_THROW) < 0) { + return JS_FALSE; + } + JS_ASSERT(cg->stackDepth == depth); + } + + /* + * If we have a finally, it belongs here, and we have to fix up the + * gosubs that might have been emitted before non-local jumps. + */ + if (pn->pn_kid3) { + if (!BackPatch(cx, cg, stmtInfo.gosub, CG_NEXT(cg), JSOP_GOSUB)) + return JS_FALSE; + + /* + * The stack budget must be balanced at this point, and we need + * one more slot for the JSOP_RETSUB return address pushed by a + * JSOP_GOSUB opcode that calls this finally clause. + */ + JS_ASSERT(cg->stackDepth == depth); + if ((uintN)++cg->stackDepth > cg->maxStackDepth) + cg->maxStackDepth = cg->stackDepth; + + /* Now indicate that we're emitting a subroutine body. */ + stmtInfo.type = STMT_SUBROUTINE; + if (!UpdateLineNumberNotes(cx, cg, pn->pn_kid3)) + return JS_FALSE; + if (js_Emit1(cx, cg, JSOP_FINALLY) < 0 || + !js_EmitTree(cx, cg, pn->pn_kid3) || + js_Emit1(cx, cg, JSOP_RETSUB) < 0) { + return JS_FALSE; + } + } + js_PopStatementCG(cx, cg); + + if (js_NewSrcNote(cx, cg, SRC_ENDBRACE) < 0 || + js_Emit1(cx, cg, JSOP_NOP) < 0) { + return JS_FALSE; + } + + /* Fix up the end-of-try/catch jumps to come here. */ + if (!BackPatch(cx, cg, stmtInfo.catchJump, CG_NEXT(cg), JSOP_GOTO)) + return JS_FALSE; + + /* + * Add the try note last, to let post-order give us the right ordering + * (first to last for a given nesting level, inner to outer by level). + */ + if (pn->pn_kid2) { + JS_ASSERT(end != -1 && catchStart != -1); + if (!js_NewTryNote(cx, cg, start, end, catchStart)) + return JS_FALSE; + } + + /* + * If we've got a finally, mark try+catch region with additional + * trynote to catch exceptions (re)thrown from a catch block or + * for the try{}finally{} case. + */ + if (pn->pn_kid3) { + JS_ASSERT(finallyCatch != -1); + if (!js_NewTryNote(cx, cg, start, finallyCatch, finallyCatch)) + return JS_FALSE; + } + break; + } + +#endif /* JS_HAS_EXCEPTIONS */ + + case TOK_VAR: + off = noteIndex = -1; + for (pn2 = pn->pn_head; ; pn2 = pn2->pn_next) { + JS_ASSERT(pn2->pn_type == TOK_NAME); + if (!LookupArgOrVar(cx, &cg->treeContext, pn2)) + return JS_FALSE; + op = pn2->pn_op; + if (op == JSOP_ARGUMENTS) { + JS_ASSERT(!pn2->pn_expr); /* JSOP_ARGUMENTS => no initializer */ +#ifdef __GNUC__ + atomIndex = 0; /* quell GCC overwarning */ +#endif + } else { + if (pn2->pn_slot >= 0) { + atomIndex = (jsatomid) pn2->pn_slot; + } else { + ale = js_IndexAtom(cx, pn2->pn_atom, &cg->atomList); + if (!ale) + return JS_FALSE; + atomIndex = ALE_INDEX(ale); + + if (!(cg->treeContext.flags & TCF_IN_FUNCTION) || + (cg->treeContext.flags & TCF_FUN_HEAVYWEIGHT)) { + /* Emit a prolog bytecode to predefine the variable. */ + CG_SWITCH_TO_PROLOG(cg); + if (!UpdateLineNumberNotes(cx, cg, pn2)) + return JS_FALSE; + EMIT_ATOM_INDEX_OP(pn->pn_op, atomIndex); + CG_SWITCH_TO_MAIN(cg); + } + } + if (pn2->pn_expr) { + if (op == JSOP_SETNAME) + EMIT_ATOM_INDEX_OP(JSOP_BINDNAME, atomIndex); + if (!js_EmitTree(cx, cg, pn2->pn_expr)) + return JS_FALSE; + } + } + if (pn2 == pn->pn_head && + js_NewSrcNote(cx, cg, + (pn->pn_op == JSOP_DEFCONST) + ? SRC_CONST + : SRC_VAR) < 0) { + return JS_FALSE; + } + if (op == JSOP_ARGUMENTS) { + if (js_Emit1(cx, cg, op) < 0) + return JS_FALSE; + } else { + EMIT_ATOM_INDEX_OP(op, atomIndex); + } + tmp = CG_OFFSET(cg); + if (noteIndex >= 0) { + if (!js_SetSrcNoteOffset(cx, cg, (uintN)noteIndex, 0, tmp-off)) + return JS_FALSE; + } + if (!pn2->pn_next) + break; + off = tmp; + noteIndex = js_NewSrcNote2(cx, cg, SRC_PCDELTA, 0); + if (noteIndex < 0 || + js_Emit1(cx, cg, JSOP_POP) < 0) { + return JS_FALSE; + } + } + if (pn->pn_extra) { + if (js_Emit1(cx, cg, JSOP_POP) < 0) + return JS_FALSE; + } + break; + + case TOK_RETURN: + /* Push a return value */ + pn2 = pn->pn_kid; + if (pn2) { + if (!js_EmitTree(cx, cg, pn2)) + return JS_FALSE; + } else { + if (js_Emit1(cx, cg, JSOP_PUSH) < 0) + return JS_FALSE; + } + + /* + * EmitNonLocalJumpFixup mutates op to JSOP_RETRVAL after emitting a + * JSOP_SETRVAL if there are open try blocks having finally clauses. + * We can't simply transfer control flow to our caller in that case, + * because we must gosub to those clauses from inner to outer, with + * the correct stack pointer (i.e., after popping any with, for/in, + * etc., slots nested inside the finally's try). + */ + op = JSOP_RETURN; + if (!EmitNonLocalJumpFixup(cx, cg, NULL, &op)) + return JS_FALSE; + if (js_Emit1(cx, cg, op) < 0) + return JS_FALSE; + break; + + case TOK_LC: + js_PushStatement(&cg->treeContext, &stmtInfo, STMT_BLOCK, top); + for (pn2 = pn->pn_head; pn2; pn2 = pn2->pn_next) { + if (!js_EmitTree(cx, cg, pn2)) + return JS_FALSE; + } + ok = js_PopStatementCG(cx, cg); + break; + + case TOK_SEMI: + pn2 = pn->pn_kid; + if (pn2) { + /* + * Top-level or called-from-a-native JS_Execute/EvaluateScript, + * debugger, and eval frames may need the value of the ultimate + * expression statement as the script's result, despite the fact + * that it appears useless to the compiler. + */ + useful = wantval = !cx->fp->fun || + cx->fp->fun->native || + (cx->fp->flags & JSFRAME_SPECIAL); + if (!useful) { + if (!CheckSideEffects(cx, &cg->treeContext, pn2, &useful)) + return JS_FALSE; + } + if (!useful) { + CG_CURRENT_LINE(cg) = pn2->pn_pos.begin.lineno; + if (!js_ReportCompileErrorNumber(cx, NULL, cg, + JSREPORT_WARNING | + JSREPORT_STRICT, + JSMSG_USELESS_EXPR)) { + return JS_FALSE; + } + } else { + if (!js_EmitTree(cx, cg, pn2)) + return JS_FALSE; + if (js_Emit1(cx, cg, wantval ? JSOP_POPV : JSOP_POP) < 0) + return JS_FALSE; + } + } + break; + + case TOK_COLON: + /* Emit an annotated nop so we know to decompile a label. */ + atom = pn->pn_atom; + ale = js_IndexAtom(cx, atom, &cg->atomList); + if (!ale) + return JS_FALSE; + pn2 = pn->pn_expr; + noteIndex = js_NewSrcNote2(cx, cg, + (pn2->pn_type == TOK_LC) + ? SRC_LABELBRACE + : SRC_LABEL, + (ptrdiff_t) ALE_INDEX(ale)); + if (noteIndex < 0 || + js_Emit1(cx, cg, JSOP_NOP) < 0) { + return JS_FALSE; + } + + /* Emit code for the labeled statement. */ + js_PushStatement(&cg->treeContext, &stmtInfo, STMT_LABEL, + CG_OFFSET(cg)); + stmtInfo.label = atom; + if (!js_EmitTree(cx, cg, pn2)) + return JS_FALSE; + if (!js_PopStatementCG(cx, cg)) + return JS_FALSE; + + /* If the statement was compound, emit a note for the end brace. */ + if (pn2->pn_type == TOK_LC) { + if (js_NewSrcNote(cx, cg, SRC_ENDBRACE) < 0 || + js_Emit1(cx, cg, JSOP_NOP) < 0) { + return JS_FALSE; + } + } + break; + + case TOK_COMMA: + /* + * Emit SRC_PCDELTA notes on each JSOP_POP between comma operands. + * These notes help the decompiler bracket the bytecodes generated + * from each sub-expression that follows a comma. + */ + off = noteIndex = -1; + for (pn2 = pn->pn_head; ; pn2 = pn2->pn_next) { + if (!js_EmitTree(cx, cg, pn2)) + return JS_FALSE; + tmp = CG_OFFSET(cg); + if (noteIndex >= 0) { + if (!js_SetSrcNoteOffset(cx, cg, (uintN)noteIndex, 0, tmp-off)) + return JS_FALSE; + } + if (!pn2->pn_next) + break; + off = tmp; + noteIndex = js_NewSrcNote2(cx, cg, SRC_PCDELTA, 0); + if (noteIndex < 0 || + js_Emit1(cx, cg, JSOP_POP) < 0) { + return JS_FALSE; + } + } + break; + + case TOK_ASSIGN: + /* + * Check left operand type and generate specialized code for it. + * Specialize to avoid ECMA "reference type" values on the operand + * stack, which impose pervasive runtime "GetValue" costs. + */ + pn2 = pn->pn_left; + JS_ASSERT(pn2->pn_type != TOK_RP); + atomIndex = (jsatomid) -1; /* Suppress warning. */ + switch (pn2->pn_type) { + case TOK_NAME: + if (!LookupArgOrVar(cx, &cg->treeContext, pn2)) + return JS_FALSE; + if (pn2->pn_slot >= 0) { + atomIndex = (jsatomid) pn2->pn_slot; + } else { + ale = js_IndexAtom(cx, pn2->pn_atom, &cg->atomList); + if (!ale) + return JS_FALSE; + atomIndex = ALE_INDEX(ale); + EMIT_ATOM_INDEX_OP(JSOP_BINDNAME, atomIndex); + } + break; + case TOK_DOT: + if (!js_EmitTree(cx, cg, pn2->pn_expr)) + return JS_FALSE; + ale = js_IndexAtom(cx, pn2->pn_atom, &cg->atomList); + if (!ale) + return JS_FALSE; + atomIndex = ALE_INDEX(ale); + break; + case TOK_LB: + JS_ASSERT(pn->pn_arity == PN_BINARY); + if (!js_EmitTree(cx, cg, pn2->pn_left)) + return JS_FALSE; + if (!js_EmitTree(cx, cg, pn2->pn_right)) + return JS_FALSE; + break; +#if JS_HAS_LVALUE_RETURN + case TOK_LP: + if (!js_EmitTree(cx, cg, pn2)) + return JS_FALSE; + break; +#endif + default: + JS_ASSERT(0); + } + + op = pn->pn_op; +#if JS_HAS_GETTER_SETTER + if (op == JSOP_GETTER || op == JSOP_SETTER) { + /* We'll emit these prefix bytecodes after emitting the r.h.s. */ + } else +#endif + /* If += or similar, dup the left operand and get its value. */ + if (op != JSOP_NOP) { + switch (pn2->pn_type) { + case TOK_NAME: + if (pn2->pn_op != JSOP_SETNAME) { + EMIT_ATOM_INDEX_OP((pn2->pn_op == JSOP_SETARG) + ? JSOP_GETARG + : JSOP_GETVAR, + atomIndex); + break; + } + /* FALL THROUGH */ + case TOK_DOT: + if (js_Emit1(cx, cg, JSOP_DUP) < 0) + return JS_FALSE; + EMIT_ATOM_INDEX_OP(JSOP_GETPROP, atomIndex); + break; + case TOK_LB: +#if JS_HAS_LVALUE_RETURN + case TOK_LP: +#endif + if (js_Emit1(cx, cg, JSOP_DUP2) < 0) + return JS_FALSE; + if (js_Emit1(cx, cg, JSOP_GETELEM) < 0) + return JS_FALSE; + break; + default:; + } + } + + /* Now emit the right operand (it may affect the namespace). */ + if (!js_EmitTree(cx, cg, pn->pn_right)) + return JS_FALSE; + + /* If += etc., emit the binary operator with a decompiler note. */ + if (op != JSOP_NOP) { + if (js_NewSrcNote(cx, cg, SRC_ASSIGNOP) < 0 || + js_Emit1(cx, cg, op) < 0) { + return JS_FALSE; + } + } + + /* Left parts such as a.b.c and a[b].c need a decompiler note. */ + if (pn2->pn_type != TOK_NAME) { + if (js_NewSrcNote2(cx, cg, SRC_PCBASE, CG_OFFSET(cg) - top) < 0) + return JS_FALSE; + } + + /* Finally, emit the specialized assignment bytecode. */ + switch (pn2->pn_type) { + case TOK_NAME: + if (pn2->pn_slot < 0 || !(pn2->pn_attrs & JSPROP_READONLY)) { + case TOK_DOT: + EMIT_ATOM_INDEX_OP(pn2->pn_op, atomIndex); + } + break; + case TOK_LB: +#if JS_HAS_LVALUE_RETURN + case TOK_LP: +#endif + if (js_Emit1(cx, cg, JSOP_SETELEM) < 0) + return JS_FALSE; + break; + default:; + } + break; + + case TOK_HOOK: + /* Emit the condition, then branch if false to the else part. */ + if (!js_EmitTree(cx, cg, pn->pn_kid1)) + return JS_FALSE; + noteIndex = js_NewSrcNote(cx, cg, SRC_COND); + if (noteIndex < 0) + return JS_FALSE; + beq = EmitJump(cx, cg, JSOP_IFEQ, 0); + if (beq < 0 || !js_EmitTree(cx, cg, pn->pn_kid2)) + return JS_FALSE; + + /* Jump around else, fixup the branch, emit else, fixup jump. */ + jmp = EmitJump(cx, cg, JSOP_GOTO, 0); + if (jmp < 0) + return JS_FALSE; + CHECK_AND_SET_JUMP_OFFSET_AT(cx, cg, beq); + if (!js_EmitTree(cx, cg, pn->pn_kid3)) + return JS_FALSE; + CHECK_AND_SET_JUMP_OFFSET_AT(cx, cg, jmp); + if (!js_SetSrcNoteOffset(cx, cg, noteIndex, 0, jmp - beq)) + return JS_FALSE; + + /* + * Because each branch pushes a single value, but our stack budgeting + * analysis ignores branches, we now have two values accounted for in + * cg->stackDepth. Execution will follow only one path, so we must + * decrement cg->stackDepth here. Failing to do this will foil code, + * such as the try/catch/finally exception handling code generator, + * that samples cg->stackDepth for use at runtime (JSOP_SETSP). + */ + JS_ASSERT(cg->stackDepth > 1); + cg->stackDepth--; + break; + + case TOK_OR: + case TOK_AND: + /* + * JSOP_OR converts the operand on the stack to boolean, and if true, + * leaves the original operand value on the stack and jumps; otherwise + * it pops and falls into the next bytecode, which evaluates the right + * operand. The jump goes around the right operand evaluation. + * + * JSOP_AND converts the operand on the stack to boolean, and if false, + * leaves the original operand value on the stack and jumps; otherwise + * it pops and falls into the right operand's bytecode. + * + * Avoid tail recursion for long ||...|| expressions and long &&...&& + * expressions or long mixtures of ||'s and &&'s that can easily blow + * the stack, by forward-linking and then backpatching all the JSOP_OR + * and JSOP_AND bytecodes' immediate jump-offset operands. + */ + pn3 = pn; + if (!js_EmitTree(cx, cg, pn->pn_left)) + return JS_FALSE; + top = EmitJump(cx, cg, JSOP_BACKPATCH_POP, 0); + if (top < 0) + return JS_FALSE; + jmp = top; + pn2 = pn->pn_right; + while (pn2->pn_type == TOK_OR || pn2->pn_type == TOK_AND) { + pn = pn2; + if (!js_EmitTree(cx, cg, pn->pn_left)) + return JS_FALSE; + off = EmitJump(cx, cg, JSOP_BACKPATCH_POP, 0); + if (off < 0) + return JS_FALSE; + if (!SetBackPatchDelta(cx, cg, CG_CODE(cg, jmp), off - jmp)) + return JS_FALSE; + jmp = off; + pn2 = pn->pn_right; + } + if (!js_EmitTree(cx, cg, pn2)) + return JS_FALSE; + off = CG_OFFSET(cg); + do { + pc = CG_CODE(cg, top); + tmp = GetJumpOffset(cg, pc); + CHECK_AND_SET_JUMP_OFFSET(cx, cg, pc, off - top); + *pc = pn3->pn_op; + top += tmp; + } while ((pn3 = pn3->pn_right) != pn2); + break; + + case TOK_BITOR: + case TOK_BITXOR: + case TOK_BITAND: + case TOK_EQOP: + case TOK_RELOP: +#if JS_HAS_IN_OPERATOR + case TOK_IN: +#endif +#if JS_HAS_INSTANCEOF + case TOK_INSTANCEOF: +#endif + case TOK_SHOP: + case TOK_PLUS: + case TOK_MINUS: + case TOK_STAR: + case TOK_DIVOP: + if (pn->pn_arity == PN_LIST) { + /* Left-associative operator chain: avoid too much recursion. */ + pn2 = pn->pn_head; + if (!js_EmitTree(cx, cg, pn2)) + return JS_FALSE; + op = pn->pn_op; + while ((pn2 = pn2->pn_next) != NULL) { + if (!js_EmitTree(cx, cg, pn2)) + return JS_FALSE; + if (js_Emit1(cx, cg, op) < 0) + return JS_FALSE; + } + } else { + /* Binary operators that evaluate both operands unconditionally. */ + if (!js_EmitTree(cx, cg, pn->pn_left)) + return JS_FALSE; + if (!js_EmitTree(cx, cg, pn->pn_right)) + return JS_FALSE; + if (js_Emit1(cx, cg, pn->pn_op) < 0) + return JS_FALSE; + } + break; + +#if JS_HAS_EXCEPTIONS + case TOK_THROW: +#endif + case TOK_UNARYOP: + /* Unary op, including unary +/-. */ + if (!js_EmitTree(cx, cg, pn->pn_kid)) + return JS_FALSE; + if (js_Emit1(cx, cg, pn->pn_op) < 0) + return JS_FALSE; + break; + + case TOK_INC: + case TOK_DEC: + /* Emit lvalue-specialized code for ++/-- operators. */ + pn2 = pn->pn_kid; + JS_ASSERT(pn2->pn_type != TOK_RP); + op = pn->pn_op; + switch (pn2->pn_type) { + case TOK_NAME: + pn2->pn_op = op; + if (!LookupArgOrVar(cx, &cg->treeContext, pn2)) + return JS_FALSE; + op = pn2->pn_op; + if (pn2->pn_slot >= 0) { + if (pn2->pn_attrs & JSPROP_READONLY) + op = JSOP_GETVAR; + atomIndex = (jsatomid) pn2->pn_slot; + EMIT_ATOM_INDEX_OP(op, atomIndex); + } else { + if (!EmitAtomOp(cx, pn2, op, cg)) + return JS_FALSE; + } + break; + case TOK_DOT: + if (!EmitPropOp(cx, pn2, op, cg)) + return JS_FALSE; + break; + case TOK_LB: + if (!EmitElemOp(cx, pn2, op, cg)) + return JS_FALSE; + break; +#if JS_HAS_LVALUE_RETURN + case TOK_LP: + if (!js_EmitTree(cx, cg, pn2)) + return JS_FALSE; + if (js_NewSrcNote2(cx, cg, SRC_PCBASE, + CG_OFFSET(cg) - pn2->pn_offset) < 0) { + return JS_FALSE; + } + if (js_Emit1(cx, cg, op) < 0) + return JS_FALSE; + break; +#endif + default: + JS_ASSERT(0); + } + break; + + case TOK_DELETE: + /* Under ECMA 3, deleting a non-reference returns true. */ + pn2 = pn->pn_kid; + switch (pn2->pn_type) { + case TOK_NAME: + pn2->pn_op = JSOP_DELNAME; + if (!LookupArgOrVar(cx, &cg->treeContext, pn2)) + return JS_FALSE; + op = pn2->pn_op; + if (op == JSOP_FALSE) { + if (js_Emit1(cx, cg, op) < 0) + return JS_FALSE; + } else { + if (!EmitAtomOp(cx, pn2, op, cg)) + return JS_FALSE; + } + break; + case TOK_DOT: + if (!EmitPropOp(cx, pn2, JSOP_DELPROP, cg)) + return JS_FALSE; + break; + case TOK_LB: + if (!EmitElemOp(cx, pn2, JSOP_DELELEM, cg)) + return JS_FALSE; + break; + default: + if (js_Emit1(cx, cg, JSOP_TRUE) < 0) + return JS_FALSE; + } + break; + + case TOK_DOT: + /* + * Pop a stack operand, convert it to object, get a property named by + * this bytecode's immediate-indexed atom operand, and push its value + * (not a reference to it). This bytecode sets the virtual machine's + * "obj" register to the left operand's ToObject conversion result, + * for use by JSOP_PUSHOBJ. + */ + ok = EmitPropOp(cx, pn, pn->pn_op, cg); + break; + + case TOK_LB: + /* + * Pop two operands, convert the left one to object and the right one + * to property name (atom or tagged int), get the named property, and + * push its value. Set the "obj" register to the result of ToObject + * on the left operand. + */ + ok = EmitElemOp(cx, pn, pn->pn_op, cg); + break; + + case TOK_NEW: + case TOK_LP: + /* + * Emit function call or operator new (constructor call) code. + * First, emit code for the left operand to evaluate the callable or + * constructable object expression. + */ + pn2 = pn->pn_head; + if (!js_EmitTree(cx, cg, pn2)) + return JS_FALSE; + + /* Remember start of callable-object bytecode for decompilation hint. */ + off = pn2->pn_offset; + + /* + * Push the virtual machine's "obj" register, which was set by a name, + * property, or element get (or set) bytecode. + */ + if (js_Emit1(cx, cg, JSOP_PUSHOBJ) < 0) + return JS_FALSE; + + /* + * Emit code for each argument in order, then emit the JSOP_*CALL or + * JSOP_NEW bytecode with a two-byte immediate telling how many args + * were pushed on the operand stack. + */ + for (pn2 = pn2->pn_next; pn2; pn2 = pn2->pn_next) { + if (!js_EmitTree(cx, cg, pn2)) + return JS_FALSE; + } + if (js_NewSrcNote2(cx, cg, SRC_PCBASE, CG_OFFSET(cg) - off) < 0) + return JS_FALSE; + argc = pn->pn_count - 1; + if (js_Emit3(cx, cg, pn->pn_op, ARGC_HI(argc), ARGC_LO(argc)) < 0) + return JS_FALSE; + break; + +#if JS_HAS_INITIALIZERS + case TOK_RB: + /* + * Emit code for [a, b, c] of the form: + * t = new Array; t[0] = a; t[1] = b; t[2] = c; t; + * but use a stack slot for t and avoid dup'ing and popping it via + * the JSOP_NEWINIT and JSOP_INITELEM bytecodes. + */ + ale = js_IndexAtom(cx, cx->runtime->atomState.ArrayAtom, + &cg->atomList); + if (!ale) + return JS_FALSE; + EMIT_ATOM_INDEX_OP(JSOP_NAME, ALE_INDEX(ale)); + if (js_Emit1(cx, cg, JSOP_PUSHOBJ) < 0) + return JS_FALSE; + if (js_Emit1(cx, cg, JSOP_NEWINIT) < 0) + return JS_FALSE; + + pn2 = pn->pn_head; +#if JS_HAS_SHARP_VARS + if (pn2 && pn2->pn_type == TOK_DEFSHARP) { + EMIT_ATOM_INDEX_OP(JSOP_DEFSHARP, (jsatomid)pn2->pn_num); + pn2 = pn2->pn_next; + } +#endif + + for (atomIndex = 0; pn2; pn2 = pn2->pn_next) { + /* PrimaryExpr enforced ATOM_INDEX_LIMIT, so in-line optimize. */ + JS_ASSERT(atomIndex < ATOM_INDEX_LIMIT); + if (atomIndex == 0) { + if (js_Emit1(cx, cg, JSOP_ZERO) < 0) + return JS_FALSE; + } else if (atomIndex == 1) { + if (js_Emit1(cx, cg, JSOP_ONE) < 0) + return JS_FALSE; + } else { + EMIT_ATOM_INDEX_OP(JSOP_UINT16, (jsatomid)atomIndex); + } + + /* Sub-optimal: holes in a sparse initializer are void-filled. */ + if (pn2->pn_type == TOK_COMMA) { + if (js_Emit1(cx, cg, JSOP_PUSH) < 0) + return JS_FALSE; + } else { + if (!js_EmitTree(cx, cg, pn2)) + return JS_FALSE; + } + if (js_Emit1(cx, cg, JSOP_INITELEM) < 0) + return JS_FALSE; + + atomIndex++; + } + + if (pn->pn_extra) { + /* Emit a source note so we know to decompile an extra comma. */ + if (js_NewSrcNote(cx, cg, SRC_CONTINUE) < 0) + return JS_FALSE; + } + + /* Emit an op for sharp array cleanup and decompilation. */ + if (js_Emit1(cx, cg, JSOP_ENDINIT) < 0) + return JS_FALSE; + break; + + case TOK_RC: + /* + * Emit code for {p:a, '%q':b, 2:c} of the form: + * t = new Object; t.p = a; t['%q'] = b; t[2] = c; t; + * but use a stack slot for t and avoid dup'ing and popping it via + * the JSOP_NEWINIT and JSOP_INITELEM bytecodes. + */ + ale = js_IndexAtom(cx, cx->runtime->atomState.ObjectAtom, + &cg->atomList); + if (!ale) + return JS_FALSE; + EMIT_ATOM_INDEX_OP(JSOP_NAME, ALE_INDEX(ale)); + + if (js_Emit1(cx, cg, JSOP_PUSHOBJ) < 0) + return JS_FALSE; + if (js_Emit1(cx, cg, JSOP_NEWINIT) < 0) + return JS_FALSE; + + pn2 = pn->pn_head; +#if JS_HAS_SHARP_VARS + if (pn2 && pn2->pn_type == TOK_DEFSHARP) { + EMIT_ATOM_INDEX_OP(JSOP_DEFSHARP, (jsatomid)pn2->pn_num); + pn2 = pn2->pn_next; + } +#endif + + for (; pn2; pn2 = pn2->pn_next) { + /* Emit an index for t[2], else map an atom for t.p or t['%q']. */ + pn3 = pn2->pn_left; + switch (pn3->pn_type) { + case TOK_NUMBER: + if (!EmitNumberOp(cx, pn3->pn_dval, cg)) + return JS_FALSE; + break; + case TOK_NAME: + case TOK_STRING: + ale = js_IndexAtom(cx, pn3->pn_atom, &cg->atomList); + if (!ale) + return JS_FALSE; + break; + default: + JS_ASSERT(0); + } + + /* Emit code for the property initializer. */ + if (!js_EmitTree(cx, cg, pn2->pn_right)) + return JS_FALSE; + +#if JS_HAS_GETTER_SETTER + op = pn2->pn_op; + if (op == JSOP_GETTER || op == JSOP_SETTER) { + if (js_Emit1(cx, cg, op) < 0) + return JS_FALSE; + } +#endif + /* Annotate JSOP_INITELEM so we decompile 2:c and not just c. */ + if (pn3->pn_type == TOK_NUMBER) { + if (js_NewSrcNote(cx, cg, SRC_LABEL) < 0) + return JS_FALSE; + if (js_Emit1(cx, cg, JSOP_INITELEM) < 0) + return JS_FALSE; + } else { + EMIT_ATOM_INDEX_OP(JSOP_INITPROP, ALE_INDEX(ale)); + } + } + + /* Emit an op for sharpArray cleanup and decompilation. */ + if (js_Emit1(cx, cg, JSOP_ENDINIT) < 0) + return JS_FALSE; + break; + +#if JS_HAS_SHARP_VARS + case TOK_DEFSHARP: + if (!js_EmitTree(cx, cg, pn->pn_kid)) + return JS_FALSE; + EMIT_ATOM_INDEX_OP(JSOP_DEFSHARP, (jsatomid) pn->pn_num); + break; + + case TOK_USESHARP: + EMIT_ATOM_INDEX_OP(JSOP_USESHARP, (jsatomid) pn->pn_num); + break; +#endif /* JS_HAS_SHARP_VARS */ +#endif /* JS_HAS_INITIALIZERS */ + + case TOK_RP: + /* + * The node for (e) has e as its kid, enabling users who want to nest + * assignment expressions in conditions to avoid the error correction + * done by Condition (from x = y to x == y) by double-parenthesizing. + */ + if (!js_EmitTree(cx, cg, pn->pn_kid)) + return JS_FALSE; + if (js_Emit1(cx, cg, JSOP_GROUP) < 0) + return JS_FALSE; + break; + + case TOK_NAME: + if (!LookupArgOrVar(cx, &cg->treeContext, pn)) + return JS_FALSE; + op = pn->pn_op; + if (op == JSOP_ARGUMENTS) { + if (js_Emit1(cx, cg, op) < 0) + return JS_FALSE; + break; + } + if (pn->pn_slot >= 0) { + atomIndex = (jsatomid) pn->pn_slot; + EMIT_ATOM_INDEX_OP(op, atomIndex); + break; + } + /* FALL THROUGH */ + case TOK_STRING: + case TOK_OBJECT: + /* + * The scanner and parser associate JSOP_NAME with TOK_NAME, although + * other bytecodes may result instead (JSOP_BINDNAME/JSOP_SETNAME, + * JSOP_FORNAME, etc.). Among JSOP_*NAME* variants, only JSOP_NAME + * may generate the first operand of a call or new expression, so only + * it sets the "obj" virtual machine register to the object along the + * scope chain in which the name was found. + * + * Token types for STRING and OBJECT have corresponding bytecode ops + * in pn_op and emit the same format as NAME, so they share this code. + */ + ok = EmitAtomOp(cx, pn, pn->pn_op, cg); + break; + + case TOK_NUMBER: + ok = EmitNumberOp(cx, pn->pn_dval, cg); + break; + + case TOK_PRIMARY: + if (js_Emit1(cx, cg, pn->pn_op) < 0) + return JS_FALSE; + break; + +#if JS_HAS_DEBUGGER_KEYWORD + case TOK_DEBUGGER: + if (js_Emit1(cx, cg, JSOP_DEBUGGER) < 0) + return JS_FALSE; + break; +#endif /* JS_HAS_DEBUGGER_KEYWORD */ + + default: + JS_ASSERT(0); + } + + if (ok && --cg->emitLevel == 0 && cg->spanDeps) + ok = OptimizeSpanDeps(cx, cg); + + return ok; +} + +JS_FRIEND_DATA(JSSrcNoteSpec) js_SrcNoteSpec[] = { + {"null", 0, 0, 0}, + {"if", 0, 0, 0}, + {"if-else", 1, 0, 1}, + {"while", 1, 0, 1}, + {"for", 3, 1, 1}, + {"continue", 0, 0, 0}, + {"var", 0, 0, 0}, + {"pcdelta", 1, 0, 1}, + {"assignop", 0, 0, 0}, + {"cond", 1, 0, 1}, + {"reserved0", 0, 0, 0}, + {"hidden", 0, 0, 0}, + {"pcbase", 1, 0, -1}, + {"label", 1, 0, 0}, + {"labelbrace", 1, 0, 0}, + {"endbrace", 0, 0, 0}, + {"break2label", 1, 0, 0}, + {"cont2label", 1, 0, 0}, + {"switch", 2, 0, 1}, + {"funcdef", 1, 0, 0}, + {"catch", 1, 11, 1}, + {"const", 0, 0, 0}, + {"newline", 0, 0, 0}, + {"setline", 1, 0, 0}, + {"xdelta", 0, 0, 0}, +}; + +static intN +AllocSrcNote(JSContext *cx, JSCodeGenerator *cg) +{ + intN index; + JSArenaPool *pool; + size_t size; + + index = CG_NOTE_COUNT(cg); + if (((uintN)index & CG_NOTE_MASK(cg)) == 0) { + pool = cg->notePool; + size = SRCNOTE_SIZE(CG_NOTE_MASK(cg) + 1); + if (!CG_NOTES(cg)) { + /* Allocate the first note array lazily; leave noteMask alone. */ + JS_ARENA_ALLOCATE_CAST(CG_NOTES(cg), jssrcnote *, pool, size); + } else { + /* Grow by doubling note array size; update noteMask on success. */ + JS_ARENA_GROW_CAST(CG_NOTES(cg), jssrcnote *, pool, size, size); + if (CG_NOTES(cg)) + CG_NOTE_MASK(cg) = (CG_NOTE_MASK(cg) << 1) | 1; + } + if (!CG_NOTES(cg)) { + JS_ReportOutOfMemory(cx); + return -1; + } + } + + CG_NOTE_COUNT(cg) = index + 1; + return index; +} + +intN +js_NewSrcNote(JSContext *cx, JSCodeGenerator *cg, JSSrcNoteType type) +{ + intN index, n; + jssrcnote *sn; + ptrdiff_t offset, delta, xdelta; + + /* + * Claim a note slot in CG_NOTES(cg) by growing it if necessary and then + * incrementing CG_NOTE_COUNT(cg). + */ + index = AllocSrcNote(cx, cg); + if (index < 0) + return -1; + sn = &CG_NOTES(cg)[index]; + + /* + * Compute delta from the last annotated bytecode's offset. If it's too + * big to fit in sn, allocate one or more xdelta notes and reset sn. + */ + offset = CG_OFFSET(cg); + delta = offset - CG_LAST_NOTE_OFFSET(cg); + CG_LAST_NOTE_OFFSET(cg) = offset; + if (delta >= SN_DELTA_LIMIT) { + do { + xdelta = JS_MIN(delta, SN_XDELTA_MASK); + SN_MAKE_XDELTA(sn, xdelta); + delta -= xdelta; + index = AllocSrcNote(cx, cg); + if (index < 0) + return -1; + sn = &CG_NOTES(cg)[index]; + } while (delta >= SN_DELTA_LIMIT); + } + + /* + * Initialize type and delta, then allocate the minimum number of notes + * needed for type's arity. Usually, we won't need more, but if an offset + * does take two bytes, js_SetSrcNoteOffset will grow CG_NOTES(cg). + */ + SN_MAKE_NOTE(sn, type, delta); + for (n = (intN)js_SrcNoteSpec[type].arity; n > 0; n--) { + if (js_NewSrcNote(cx, cg, SRC_NULL) < 0) + return -1; + } + return index; +} + +intN +js_NewSrcNote2(JSContext *cx, JSCodeGenerator *cg, JSSrcNoteType type, + ptrdiff_t offset) +{ + intN index; + + index = js_NewSrcNote(cx, cg, type); + if (index >= 0) { + if (!js_SetSrcNoteOffset(cx, cg, index, 0, offset)) + return -1; + } + return index; +} + +intN +js_NewSrcNote3(JSContext *cx, JSCodeGenerator *cg, JSSrcNoteType type, + ptrdiff_t offset1, ptrdiff_t offset2) +{ + intN index; + + index = js_NewSrcNote(cx, cg, type); + if (index >= 0) { + if (!js_SetSrcNoteOffset(cx, cg, index, 0, offset1)) + return -1; + if (!js_SetSrcNoteOffset(cx, cg, index, 1, offset2)) + return -1; + } + return index; +} + +static JSBool +GrowSrcNotes(JSContext *cx, JSCodeGenerator *cg) +{ + JSArenaPool *pool; + size_t size; + + /* Grow by doubling note array size; update noteMask on success. */ + pool = cg->notePool; + size = SRCNOTE_SIZE(CG_NOTE_MASK(cg) + 1); + JS_ARENA_GROW_CAST(CG_NOTES(cg), jssrcnote *, pool, size, size); + if (!CG_NOTES(cg)) { + JS_ReportOutOfMemory(cx); + return JS_FALSE; + } + CG_NOTE_MASK(cg) = (CG_NOTE_MASK(cg) << 1) | 1; + return JS_TRUE; +} + +jssrcnote * +js_AddToSrcNoteDelta(JSContext *cx, JSCodeGenerator *cg, jssrcnote *sn, + ptrdiff_t delta) +{ + ptrdiff_t base, limit, newdelta, diff; + intN index; + + /* + * Called only from OptimizeSpanDeps and js_FinishTakingSrcNotes to add to + * main script note deltas, and only by a small positive amount. + */ + JS_ASSERT(cg->current == &cg->main); + JS_ASSERT((unsigned) delta < (unsigned) SN_XDELTA_LIMIT); + + base = SN_DELTA(sn); + limit = SN_IS_XDELTA(sn) ? SN_XDELTA_LIMIT : SN_DELTA_LIMIT; + newdelta = base + delta; + if (newdelta < limit) { + SN_SET_DELTA(sn, newdelta); + } else { + index = sn - cg->main.notes; + if ((cg->main.noteCount & cg->main.noteMask) == 0) { + if (!GrowSrcNotes(cx, cg)) + return NULL; + sn = cg->main.notes + index; + } + diff = cg->main.noteCount - index; + cg->main.noteCount++; + memmove(sn + 1, sn, SRCNOTE_SIZE(diff)); + SN_MAKE_XDELTA(sn, delta); + sn++; + } + return sn; +} + +uintN +js_SrcNoteLength(jssrcnote *sn) +{ + uintN arity; + jssrcnote *base; + + arity = (intN)js_SrcNoteSpec[SN_TYPE(sn)].arity; + for (base = sn++; arity; sn++, arity--) { + if (*sn & SN_3BYTE_OFFSET_FLAG) + sn += 2; + } + return sn - base; +} + +JS_FRIEND_API(ptrdiff_t) +js_GetSrcNoteOffset(jssrcnote *sn, uintN which) +{ + /* Find the offset numbered which (i.e., skip exactly which offsets). */ + JS_ASSERT(SN_TYPE(sn) != SRC_XDELTA); + JS_ASSERT(which < js_SrcNoteSpec[SN_TYPE(sn)].arity); + for (sn++; which; sn++, which--) { + if (*sn & SN_3BYTE_OFFSET_FLAG) + sn += 2; + } + if (*sn & SN_3BYTE_OFFSET_FLAG) { + return (ptrdiff_t)(((uint32)(sn[0] & SN_3BYTE_OFFSET_MASK) << 16) + | (sn[1] << 8) + | sn[2]); + } + return (ptrdiff_t)*sn; +} + +JSBool +js_SetSrcNoteOffset(JSContext *cx, JSCodeGenerator *cg, uintN index, + uintN which, ptrdiff_t offset) +{ + jssrcnote *sn; + ptrdiff_t diff; + + if ((jsuword)offset >= (jsuword)((ptrdiff_t)SN_3BYTE_OFFSET_FLAG << 16)) { + ReportStatementTooLarge(cx, cg); + return JS_FALSE; + } + + /* Find the offset numbered which (i.e., skip exactly which offsets). */ + sn = &CG_NOTES(cg)[index]; + JS_ASSERT(SN_TYPE(sn) != SRC_XDELTA); + JS_ASSERT(which < js_SrcNoteSpec[SN_TYPE(sn)].arity); + for (sn++; which; sn++, which--) { + if (*sn & SN_3BYTE_OFFSET_FLAG) + sn += 2; + } + + /* See if the new offset requires three bytes. */ + if (offset > (ptrdiff_t)SN_3BYTE_OFFSET_MASK) { + /* Maybe this offset was already set to a three-byte value. */ + if (!(*sn & SN_3BYTE_OFFSET_FLAG)) { + /* Losing, need to insert another two bytes for this offset. */ + index = PTRDIFF(sn, CG_NOTES(cg), jssrcnote); + + /* + * Simultaneously test to see if the source note array must grow to + * accomodate either the first or second byte of additional storage + * required by this 3-byte offset. + */ + if (((CG_NOTE_COUNT(cg) + 1) & CG_NOTE_MASK(cg)) <= 1) { + if (!GrowSrcNotes(cx, cg)) + return JS_FALSE; + sn = CG_NOTES(cg) + index; + } + CG_NOTE_COUNT(cg) += 2; + + diff = CG_NOTE_COUNT(cg) - (index + 3); + JS_ASSERT(diff >= 0); + if (diff > 0) + memmove(sn + 3, sn + 1, SRCNOTE_SIZE(diff)); + } + *sn++ = (jssrcnote)(SN_3BYTE_OFFSET_FLAG | (offset >> 16)); + *sn++ = (jssrcnote)(offset >> 8); + } + *sn = (jssrcnote)offset; + return JS_TRUE; +} + +#ifdef DEBUG_brendan +#define NBINS 10 +static uint32 hist[NBINS]; + +void DumpSrcNoteSizeHist() +{ + static FILE *fp; + int i, n; + + if (!fp) { + fp = fopen("/tmp/srcnotes.hist", "w"); + if (!fp) + return; + setlinebuf(fp); + } + fprintf(fp, "SrcNote size histogram:\n"); + for (i = 0; i < NBINS; i++) { + fprintf(fp, "%4u %4u ", JS_BIT(i), hist[i]); + for (n = (int) JS_HOWMANY(hist[i], 10); n > 0; --n) + fputc('*', fp); + fputc('\n', fp); + } + fputc('\n', fp); +} +#endif + +/* + * Fill in the storage at notes with prolog and main srcnotes; the space at + * notes was allocated using the CG_COUNT_FINAL_SRCNOTES macro from jsemit.h. + * SO DON'T CHANGE THIS FUNCTION WITHOUT AT LEAST CHECKING WHETHER jsemit.h's + * CG_COUNT_FINAL_SRCNOTES MACRO NEEDS CORRESPONDING CHANGES! + */ +JSBool +js_FinishTakingSrcNotes(JSContext *cx, JSCodeGenerator *cg, jssrcnote *notes) +{ + uintN prologCount, mainCount, totalCount; + ptrdiff_t offset, delta; + jssrcnote *sn; + + JS_ASSERT(cg->current == &cg->main); + + prologCount = cg->prolog.noteCount; + if (prologCount && cg->prolog.currentLine != cg->firstLine) { + CG_SWITCH_TO_PROLOG(cg); + if (js_NewSrcNote2(cx, cg, SRC_SETLINE, (ptrdiff_t)cg->firstLine) < 0) + return JS_FALSE; + prologCount = cg->prolog.noteCount; + CG_SWITCH_TO_MAIN(cg); + } else { + /* + * Either no prolog srcnotes, or no line number change over prolog. + * We don't need a SRC_SETLINE, but we may need to adjust the offset + * of the first main note, by adding to its delta and possibly even + * prepending SRC_XDELTA notes to it to account for prolog bytecodes + * that came at and after the last annotated bytecode. + */ + offset = CG_PROLOG_OFFSET(cg) - cg->prolog.lastNoteOffset; + JS_ASSERT(offset >= 0); + if (offset > 0) { + /* NB: Use as much of the first main note's delta as we can. */ + sn = cg->main.notes; + delta = SN_IS_XDELTA(sn) + ? SN_XDELTA_MASK - (*sn & SN_XDELTA_MASK) + : SN_DELTA_MASK - (*sn & SN_DELTA_MASK); + if (offset < delta) + delta = offset; + for (;;) { + if (!js_AddToSrcNoteDelta(cx, cg, sn, delta)) + return JS_FALSE; + offset -= delta; + if (offset == 0) + break; + delta = JS_MIN(offset, SN_XDELTA_MASK); + sn = cg->main.notes; + } + } + } + + mainCount = cg->main.noteCount; + totalCount = prologCount + mainCount; + if (prologCount) + memcpy(notes, cg->prolog.notes, SRCNOTE_SIZE(prologCount)); + memcpy(notes + prologCount, cg->main.notes, SRCNOTE_SIZE(mainCount)); + SN_MAKE_TERMINATOR(¬es[totalCount]); + +#ifdef DEBUG_brendan + { int bin = JS_CeilingLog2(totalCount); + if (bin >= NBINS) + bin = NBINS - 1; + ++hist[bin]; + } +#endif + return JS_TRUE; +} + +JSBool +js_AllocTryNotes(JSContext *cx, JSCodeGenerator *cg) +{ + size_t size, incr; + ptrdiff_t delta; + + size = TRYNOTE_SIZE(cg->treeContext.tryCount); + if (size <= cg->tryNoteSpace) + return JS_TRUE; + + /* + * Allocate trynotes from cx->tempPool. + * XXX Too much growing and we bloat, as other tempPool allocators block + * in-place growth, and we never recycle old free space in an arena. + * YYY But once we consume an entire arena, we'll realloc it, letting the + * malloc heap recycle old space, while still freeing _en masse_ via the + * arena pool. + */ + if (!cg->tryBase) { + size = JS_ROUNDUP(size, TRYNOTE_SIZE(TRYNOTE_CHUNK)); + JS_ARENA_ALLOCATE_CAST(cg->tryBase, JSTryNote *, &cx->tempPool, size); + if (!cg->tryBase) + return JS_FALSE; + cg->tryNoteSpace = size; + cg->tryNext = cg->tryBase; + } else { + delta = PTRDIFF((char *)cg->tryNext, (char *)cg->tryBase, char); + incr = size - cg->tryNoteSpace; + incr = JS_ROUNDUP(incr, TRYNOTE_SIZE(TRYNOTE_CHUNK)); + size = cg->tryNoteSpace; + JS_ARENA_GROW_CAST(cg->tryBase, JSTryNote *, &cx->tempPool, size, incr); + if (!cg->tryBase) + return JS_FALSE; + cg->tryNoteSpace = size + incr; + cg->tryNext = (JSTryNote *)((char *)cg->tryBase + delta); + } + return JS_TRUE; +} + +JSTryNote * +js_NewTryNote(JSContext *cx, JSCodeGenerator *cg, ptrdiff_t start, + ptrdiff_t end, ptrdiff_t catchStart) +{ + JSTryNote *tn; + + JS_ASSERT(cg->tryBase <= cg->tryNext); + JS_ASSERT(catchStart >= 0); + tn = cg->tryNext++; + tn->start = start; + tn->length = end - start; + tn->catchStart = catchStart; + return tn; +} + +void +js_FinishTakingTryNotes(JSContext *cx, JSCodeGenerator *cg, JSTryNote *notes) +{ + uintN count; + + count = PTRDIFF(cg->tryNext, cg->tryBase, JSTryNote); + if (!count) + return; + + memcpy(notes, cg->tryBase, TRYNOTE_SIZE(count)); + notes[count].start = 0; + notes[count].length = CG_OFFSET(cg); + notes[count].catchStart = 0; +} diff --git a/src/dom/js/jsemit.h b/src/dom/js/jsemit.h new file mode 100644 index 000000000..43b520c6e --- /dev/null +++ b/src/dom/js/jsemit.h @@ -0,0 +1,547 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef jsemit_h___ +#define jsemit_h___ +/* + * JS bytecode generation. + */ + +#include "jsstddef.h" +#include "jstypes.h" +#include "jsatom.h" +#include "jsopcode.h" +#include "jsprvtd.h" +#include "jspubtd.h" + +JS_BEGIN_EXTERN_C + +/* + * NB: If you add non-loop STMT_* enumerators, do so before STMT_DO_LOOP or + * you will break the STMT_IS_LOOP macro, just below this enum. + */ +typedef enum JSStmtType { + STMT_BLOCK = 0, /* compound statement: { s1[;... sN] } */ + STMT_LABEL = 1, /* labeled statement: L: s */ + STMT_IF = 2, /* if (then) statement */ + STMT_ELSE = 3, /* else clause of if statement */ + STMT_SWITCH = 4, /* switch statement */ + STMT_WITH = 5, /* with statement */ + STMT_TRY = 6, /* try statement */ + STMT_CATCH = 7, /* catch block */ + STMT_FINALLY = 8, /* finally statement */ + STMT_SUBROUTINE = 9, /* gosub-target subroutine body */ + STMT_DO_LOOP = 10, /* do/while loop statement */ + STMT_FOR_LOOP = 11, /* for loop statement */ + STMT_FOR_IN_LOOP = 12, /* for/in loop statement */ + STMT_WHILE_LOOP = 13 /* while loop statement */ +} JSStmtType; + +#define STMT_IS_LOOP(stmt) ((stmt)->type >= STMT_DO_LOOP) + +typedef struct JSStmtInfo JSStmtInfo; + +struct JSStmtInfo { + JSStmtType type; /* statement type */ + ptrdiff_t update; /* loop update offset (top if none) */ + ptrdiff_t breaks; /* offset of last break in loop */ + ptrdiff_t continues; /* offset of last continue in loop */ + ptrdiff_t gosub; /* offset of last GOSUB for this finally */ + ptrdiff_t catchJump; /* offset of last end-of-catch jump */ + JSAtom *label; /* name of LABEL or CATCH var */ + JSStmtInfo *down; /* info for enclosing statement */ +}; + +#define SET_STATEMENT_TOP(stmt, top) \ + ((stmt)->update = (top), (stmt)->breaks = \ + (stmt)->continues = (stmt)->catchJump = (stmt)->gosub = (-1)) + +struct JSTreeContext { /* tree context for semantic checks */ + uint32 flags; /* statement state flags, see below */ + uint32 tryCount; /* total count of try statements parsed */ + JSStmtInfo *topStmt; /* top of statement info stack */ + JSAtomList decls; /* function, const, and var declarations */ + JSParseNode *nodeList; /* list of recyclable parse-node structs */ +}; + +#define TCF_COMPILING 0x01 /* generating bytecode; this tc is a cg */ +#define TCF_IN_FUNCTION 0x02 /* parsing inside function body */ +#define TCF_RETURN_EXPR 0x04 /* function has 'return expr;' */ +#define TCF_RETURN_VOID 0x08 /* function has 'return;' */ +#define TCF_IN_FOR_INIT 0x10 /* parsing init expr of for; exclude 'in' */ +#define TCF_FUN_CLOSURE_VS_VAR 0x20 /* function and var with same name */ +#define TCF_FUN_USES_NONLOCALS 0x40 /* function refers to non-local names */ +#define TCF_FUN_HEAVYWEIGHT 0x80 /* function needs Call object per call */ +#define TCF_FUN_FLAGS 0xE0 /* flags to propagate from FunctionBody */ + +#define TREE_CONTEXT_INIT(tc) \ + ((tc)->flags = 0, (tc)->tryCount = 0, (tc)->topStmt = NULL, \ + ATOM_LIST_INIT(&(tc)->decls), (tc)->nodeList = NULL) + +#define TREE_CONTEXT_FINISH(tc) \ + ((void)0) + +/* + * Span-dependent instructions are jumps whose span (from the jump bytecode to + * the jump target) may require 2 or 4 bytes of immediate operand. + */ +typedef struct JSSpanDep JSSpanDep; +typedef struct JSJumpTarget JSJumpTarget; + +struct JSSpanDep { + ptrdiff_t top; /* offset of first bytecode in an opcode */ + ptrdiff_t offset; /* offset - 1 within opcode of jump operand */ + ptrdiff_t before; /* original offset - 1 of jump operand */ + JSJumpTarget *target; /* tagged target pointer or backpatch delta */ +}; + +/* + * Jump targets are stored in an AVL tree, for O(log(n)) lookup with targets + * sorted by offset from left to right, so that targets after a span-dependent + * instruction whose jump offset operand must be extended can be found quickly + * and adjusted upward (toward higher offsets). + */ +struct JSJumpTarget { + ptrdiff_t offset; /* offset of span-dependent jump target */ + int balance; /* AVL tree balance number */ + JSJumpTarget *kids[2]; /* left and right AVL tree child pointers */ +}; + +#define JT_LEFT 0 +#define JT_RIGHT 1 +#define JT_OTHER_DIR(dir) (1 - (dir)) +#define JT_IMBALANCE(dir) (((dir) << 1) - 1) +#define JT_DIR(imbalance) (((imbalance) + 1) >> 1) + +/* + * Backpatch deltas are encoded in JSSpanDep.target if JT_TAG_BIT is clear, + * so we can maintain backpatch chains when using span dependency records to + * hold jump offsets that overflow 16 bits. + */ +#define JT_TAG_BIT ((jsword) 1) +#define JT_UNTAG_SHIFT 1 +#define JT_SET_TAG(jt) ((JSJumpTarget *)((jsword)(jt) | JT_TAG_BIT)) +#define JT_CLR_TAG(jt) ((JSJumpTarget *)((jsword)(jt) & ~JT_TAG_BIT)) +#define JT_HAS_TAG(jt) ((jsword)(jt) & JT_TAG_BIT) + +#define BITS_PER_PTRDIFF (sizeof(ptrdiff_t) * JS_BITS_PER_BYTE) +#define BITS_PER_BPDELTA (BITS_PER_PTRDIFF - 1 - JT_UNTAG_SHIFT) +#define BPDELTA_MAX (((ptrdiff_t)1 << BITS_PER_BPDELTA) - 1) +#define BPDELTA_TO_JT(bp) ((JSJumpTarget *)((bp) << JT_UNTAG_SHIFT)) +#define JT_TO_BPDELTA(jt) ((ptrdiff_t)((jsword)(jt) >> JT_UNTAG_SHIFT)) + +#define SD_SET_TARGET(sd,jt) ((sd)->target = JT_SET_TAG(jt)) +#define SD_SET_BPDELTA(sd,bp) ((sd)->target = BPDELTA_TO_JT(bp)) +#define SD_GET_BPDELTA(sd) (JS_ASSERT(!JT_HAS_TAG((sd)->target)), \ + JT_TO_BPDELTA((sd)->target)) +#define SD_TARGET_OFFSET(sd) (JS_ASSERT(JT_HAS_TAG((sd)->target)), \ + JT_CLR_TAG((sd)->target)->offset) + +struct JSCodeGenerator { + JSTreeContext treeContext; /* base state: statement info stack, etc. */ + JSArenaPool *codePool; /* pointer to thread code arena pool */ + JSArenaPool *notePool; /* pointer to thread srcnote arena pool */ + void *codeMark; /* low watermark in cg->codePool */ + void *noteMark; /* low watermark in cg->notePool */ + void *tempMark; /* low watermark in cx->tempPool */ + struct { + jsbytecode *base; /* base of JS bytecode vector */ + jsbytecode *limit; /* one byte beyond end of bytecode */ + jsbytecode *next; /* pointer to next free bytecode */ + jssrcnote *notes; /* source notes, see below */ + uintN noteCount; /* number of source notes so far */ + uintN noteMask; /* growth increment for notes */ + ptrdiff_t lastNoteOffset; /* code offset for last source note */ + uintN currentLine; /* line number for tree-based srcnote gen */ + } prolog, main, *current; + const char *filename; /* null or weak link to source filename */ + uintN firstLine; /* first line, for js_NewScriptFromCG */ + JSPrincipals *principals; /* principals for constant folding eval */ + JSAtomList atomList; /* literals indexed for mapping */ + intN stackDepth; /* current stack depth in script frame */ + uintN maxStackDepth; /* maximum stack depth so far */ + JSTryNote *tryBase; /* first exception handling note */ + JSTryNote *tryNext; /* next available note */ + size_t tryNoteSpace; /* # of bytes allocated at tryBase */ + JSSpanDep *spanDeps; /* span dependent instruction records */ + JSJumpTarget *jumpTargets; /* AVL tree of jump target offsets */ + JSJumpTarget *jtFreeList; /* JT_LEFT-linked list of free structs */ + uintN numSpanDeps; /* number of span dependencies */ + uintN numJumpTargets; /* number of jump targets */ + uintN emitLevel; /* js_EmitTree recursion level */ +}; + +#define CG_BASE(cg) ((cg)->current->base) +#define CG_LIMIT(cg) ((cg)->current->limit) +#define CG_NEXT(cg) ((cg)->current->next) +#define CG_CODE(cg,offset) (CG_BASE(cg) + (offset)) +#define CG_OFFSET(cg) PTRDIFF(CG_NEXT(cg), CG_BASE(cg), jsbytecode) + +#define CG_NOTES(cg) ((cg)->current->notes) +#define CG_NOTE_COUNT(cg) ((cg)->current->noteCount) +#define CG_NOTE_MASK(cg) ((cg)->current->noteMask) +#define CG_LAST_NOTE_OFFSET(cg) ((cg)->current->lastNoteOffset) +#define CG_CURRENT_LINE(cg) ((cg)->current->currentLine) + +#define CG_PROLOG_BASE(cg) ((cg)->prolog.base) +#define CG_PROLOG_LIMIT(cg) ((cg)->prolog.limit) +#define CG_PROLOG_NEXT(cg) ((cg)->prolog.next) +#define CG_PROLOG_CODE(cg,poff) (CG_PROLOG_BASE(cg) + (poff)) +#define CG_PROLOG_OFFSET(cg) PTRDIFF(CG_PROLOG_NEXT(cg), CG_PROLOG_BASE(cg),\ + jsbytecode) + +#define CG_SWITCH_TO_MAIN(cg) ((cg)->current = &(cg)->main) +#define CG_SWITCH_TO_PROLOG(cg) ((cg)->current = &(cg)->prolog) + +/* + * Initialize cg to allocate bytecode space from codePool, source note space + * from notePool, and all other arena-allocated temporaries from cx->tempPool. + * Return true on success. Report an error and return false if the initial + * code segment can't be allocated. + */ +extern JS_FRIEND_API(JSBool) +js_InitCodeGenerator(JSContext *cx, JSCodeGenerator *cg, + JSArenaPool *codePool, JSArenaPool *notePool, + const char *filename, uintN lineno, + JSPrincipals *principals); + +/* + * Release cg->codePool, cg->notePool, and cx->tempPool to marks set by + * js_InitCodeGenerator. Note that cgs are magic: they own the arena pool + * "tops-of-stack" space above their codeMark, noteMark, and tempMark points. + * This means you cannot alloc from tempPool and save the pointer beyond the + * next JS_FinishCodeGenerator. + */ +extern JS_FRIEND_API(void) +js_FinishCodeGenerator(JSContext *cx, JSCodeGenerator *cg); + +/* + * Emit one bytecode. + */ +extern ptrdiff_t +js_Emit1(JSContext *cx, JSCodeGenerator *cg, JSOp op); + +/* + * Emit two bytecodes, an opcode (op) with a byte of immediate operand (op1). + */ +extern ptrdiff_t +js_Emit2(JSContext *cx, JSCodeGenerator *cg, JSOp op, jsbytecode op1); + +/* + * Emit three bytecodes, an opcode with two bytes of immediate operands. + */ +extern ptrdiff_t +js_Emit3(JSContext *cx, JSCodeGenerator *cg, JSOp op, jsbytecode op1, + jsbytecode op2); + +/* + * Emit (1 + extra) bytecodes, for N bytes of op and its immediate operand. + */ +extern ptrdiff_t +js_EmitN(JSContext *cx, JSCodeGenerator *cg, JSOp op, size_t extra); + +/* + * Unsafe macro to call js_SetJumpOffset and return false if it does. + */ +#define CHECK_AND_SET_JUMP_OFFSET(cx,cg,pc,off) \ + JS_BEGIN_MACRO \ + if (!js_SetJumpOffset(cx, cg, pc, off)) \ + return JS_FALSE; \ + JS_END_MACRO + +#define CHECK_AND_SET_JUMP_OFFSET_AT(cx,cg,off) \ + CHECK_AND_SET_JUMP_OFFSET(cx, cg, CG_CODE(cg,off), CG_OFFSET(cg) - (off)) + +extern JSBool +js_SetJumpOffset(JSContext *cx, JSCodeGenerator *cg, jsbytecode *pc, + ptrdiff_t off); + +/* Test whether we're in a with statement. */ +extern JSBool +js_InWithStatement(JSTreeContext *tc); + +/* Test whether we're in a catch block with exception named by atom. */ +extern JSBool +js_InCatchBlock(JSTreeContext *tc, JSAtom *atom); + +/* + * Push the C-stack-allocated struct at stmt onto the stmtInfo stack. + */ +extern void +js_PushStatement(JSTreeContext *tc, JSStmtInfo *stmt, JSStmtType type, + ptrdiff_t top); + +/* + * Pop tc->topStmt. If the top JSStmtInfo struct is not stack-allocated, it + * is up to the caller to free it. + */ +extern void +js_PopStatement(JSTreeContext *tc); + +/* + * Like js_PopStatement(&cg->treeContext), also patch breaks and continues. + * May fail if a jump offset overflows. + */ +extern JSBool +js_PopStatementCG(JSContext *cx, JSCodeGenerator *cg); + +/* + * Emit code into cg for the tree rooted at pn. + */ +extern JSBool +js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn); + +/* + * Emit code into cg for the tree rooted at body, then create a persistent + * script for fun from cg. + */ +extern JSBool +js_EmitFunctionBody(JSContext *cx, JSCodeGenerator *cg, JSParseNode *body, + JSFunction *fun); + +/* + * Source notes generated along with bytecode for decompiling and debugging. + * A source note is a uint8 with 5 bits of type and 3 of offset from the pc of + * the previous note. If 3 bits of offset aren't enough, extended delta notes + * (SRC_XDELTA) consisting of 2 set high order bits followed by 6 offset bits + * are emitted before the next note. Some notes have operand offsets encoded + * immediately after them, in note bytes or byte-triples. + * + * Source Note Extended Delta + * +7-6-5-4-3+2-1-0+ +7-6-5+4-3-2-1-0+ + * |note-type|delta| |1 1| ext-delta | + * +---------+-----+ +---+-----------+ + * + * At most one "gettable" note (i.e., a note of type other than SRC_NEWLINE, + * SRC_SETLINE, and SRC_XDELTA) applies to a given bytecode. + * + * NB: the js_SrcNoteSpec array in jsemit.c is indexed by this enum, so its + * initializers need to match the order here. + */ +typedef enum JSSrcNoteType { + SRC_NULL = 0, /* terminates a note vector */ + SRC_IF = 1, /* JSOP_IFEQ bytecode is from an if-then */ + SRC_IF_ELSE = 2, /* JSOP_IFEQ bytecode is from an if-then-else */ + SRC_WHILE = 3, /* JSOP_IFEQ is from a while loop */ + SRC_FOR = 4, /* JSOP_NOP or JSOP_POP in for loop head */ + SRC_CONTINUE = 5, /* JSOP_GOTO is a continue, not a break; + also used on JSOP_ENDINIT if extra comma + at end of array literal: [1,2,,] */ + SRC_VAR = 6, /* JSOP_NAME/SETNAME/FORNAME in a var decl */ + SRC_PCDELTA = 7, /* offset from comma-operator to next POP, + or from CONDSWITCH to first CASE opcode */ + SRC_ASSIGNOP = 8, /* += or another assign-op follows */ + SRC_COND = 9, /* JSOP_IFEQ is from conditional ?: operator */ + SRC_RESERVED0 = 10, /* reserved for future use */ + SRC_HIDDEN = 11, /* opcode shouldn't be decompiled */ + SRC_PCBASE = 12, /* offset of first obj.prop.subprop bytecode */ + SRC_LABEL = 13, /* JSOP_NOP for label: with atomid immediate */ + SRC_LABELBRACE = 14, /* JSOP_NOP for label: {...} begin brace */ + SRC_ENDBRACE = 15, /* JSOP_NOP for label: {...} end brace */ + SRC_BREAK2LABEL = 16, /* JSOP_GOTO for 'break label' with atomid */ + SRC_CONT2LABEL = 17, /* JSOP_GOTO for 'continue label' with atomid */ + SRC_SWITCH = 18, /* JSOP_*SWITCH with offset to end of switch, + 2nd off to first JSOP_CASE if condswitch */ + SRC_FUNCDEF = 19, /* JSOP_NOP for function f() with atomid */ + SRC_CATCH = 20, /* catch block has guard */ + SRC_CONST = 21, /* JSOP_SETCONST in a const decl */ + SRC_NEWLINE = 22, /* bytecode follows a source newline */ + SRC_SETLINE = 23, /* a file-absolute source line number note */ + SRC_XDELTA = 24 /* 24-31 are for extended delta notes */ +} JSSrcNoteType; + +#define SN_TYPE_BITS 5 +#define SN_DELTA_BITS 3 +#define SN_XDELTA_BITS 6 +#define SN_TYPE_MASK (JS_BITMASK(SN_TYPE_BITS) << SN_DELTA_BITS) +#define SN_DELTA_MASK ((ptrdiff_t)JS_BITMASK(SN_DELTA_BITS)) +#define SN_XDELTA_MASK ((ptrdiff_t)JS_BITMASK(SN_XDELTA_BITS)) + +#define SN_MAKE_NOTE(sn,t,d) (*(sn) = (jssrcnote) \ + (((t) << SN_DELTA_BITS) \ + | ((d) & SN_DELTA_MASK))) +#define SN_MAKE_XDELTA(sn,d) (*(sn) = (jssrcnote) \ + ((SRC_XDELTA << SN_DELTA_BITS) \ + | ((d) & SN_XDELTA_MASK))) + +#define SN_IS_XDELTA(sn) ((*(sn) >> SN_DELTA_BITS) >= SRC_XDELTA) +#define SN_TYPE(sn) (SN_IS_XDELTA(sn) ? SRC_XDELTA \ + : *(sn) >> SN_DELTA_BITS) +#define SN_SET_TYPE(sn,type) SN_MAKE_NOTE(sn, type, SN_DELTA(sn)) +#define SN_IS_GETTABLE(sn) (SN_TYPE(sn) < SRC_NEWLINE) + +#define SN_DELTA(sn) ((ptrdiff_t)(SN_IS_XDELTA(sn) \ + ? *(sn) & SN_XDELTA_MASK \ + : *(sn) & SN_DELTA_MASK)) +#define SN_SET_DELTA(sn,delta) (SN_IS_XDELTA(sn) \ + ? SN_MAKE_XDELTA(sn, delta) \ + : SN_MAKE_NOTE(sn, SN_TYPE(sn), delta)) + +#define SN_DELTA_LIMIT ((ptrdiff_t)JS_BIT(SN_DELTA_BITS)) +#define SN_XDELTA_LIMIT ((ptrdiff_t)JS_BIT(SN_XDELTA_BITS)) + +/* + * Offset fields follow certain notes and are frequency-encoded: an offset in + * [0,0x7f] consumes one byte, an offset in [0x80,0x7fffff] takes three, and + * the high bit of the first byte is set. + */ +#define SN_3BYTE_OFFSET_FLAG 0x80 +#define SN_3BYTE_OFFSET_MASK 0x7f + +typedef struct JSSrcNoteSpec { + const char *name; /* name for disassembly/debugging output */ + uint8 arity; /* number of offset operands */ + uint8 offsetBias; /* bias of offset(s) from annotated pc */ + int8 isSpanDep; /* 1 or -1 if offsets could span extended ops, + 0 otherwise; sign tells span direction */ +} JSSrcNoteSpec; + +extern JS_FRIEND_DATA(JSSrcNoteSpec) js_SrcNoteSpec[]; +extern JS_FRIEND_API(uintN) js_SrcNoteLength(jssrcnote *sn); + +#define SN_LENGTH(sn) ((js_SrcNoteSpec[SN_TYPE(sn)].arity == 0) ? 1 \ + : js_SrcNoteLength(sn)) +#define SN_NEXT(sn) ((sn) + SN_LENGTH(sn)) + +/* A source note array is terminated by an all-zero element. */ +#define SN_MAKE_TERMINATOR(sn) (*(sn) = SRC_NULL) +#define SN_IS_TERMINATOR(sn) (*(sn) == SRC_NULL) + +/* + * Append a new source note of the given type (and therefore size) to cg's + * notes dynamic array, updating cg->noteCount. Return the new note's index + * within the array pointed at by cg->current->notes. Return -1 if out of + * memory. + */ +extern intN +js_NewSrcNote(JSContext *cx, JSCodeGenerator *cg, JSSrcNoteType type); + +extern intN +js_NewSrcNote2(JSContext *cx, JSCodeGenerator *cg, JSSrcNoteType type, + ptrdiff_t offset); + +extern intN +js_NewSrcNote3(JSContext *cx, JSCodeGenerator *cg, JSSrcNoteType type, + ptrdiff_t offset1, ptrdiff_t offset2); + +/* + * NB: this function can add at most one extra extended delta note. + */ +extern jssrcnote * +js_AddToSrcNoteDelta(JSContext *cx, JSCodeGenerator *cg, jssrcnote *sn, + ptrdiff_t delta); + +/* + * Get and set the offset operand identified by which (0 for the first, etc.). + */ +extern JS_FRIEND_API(ptrdiff_t) +js_GetSrcNoteOffset(jssrcnote *sn, uintN which); + +extern JSBool +js_SetSrcNoteOffset(JSContext *cx, JSCodeGenerator *cg, uintN index, + uintN which, ptrdiff_t offset); + +/* + * Finish taking source notes in cx's notePool, copying final notes to the new + * stable store allocated by the caller and passed in via notes. Return false + * on malloc failure, which means this function reported an error. + * + * To compute the number of jssrcnotes to allocate and pass in via notes, use + * the CG_COUNT_FINAL_SRCNOTES macro. This macro knows a lot about details of + * js_FinishTakingSrcNotes, SO DON'T CHANGE jsemit.c's js_FinishTakingSrcNotes + * FUNCTION WITHOUT CHECKING WHETHER THIS MACRO NEEDS CORRESPONDING CHANGES! + */ +#define CG_COUNT_FINAL_SRCNOTES(cg, cnt) \ + JS_BEGIN_MACRO \ + ptrdiff_t diff_ = CG_PROLOG_OFFSET(cg) - (cg)->prolog.lastNoteOffset; \ + cnt = (cg)->prolog.noteCount + (cg)->main.noteCount + 1; \ + if ((cg)->prolog.noteCount && \ + (cg)->prolog.currentLine != (cg)->firstLine) { \ + if (diff_ > SN_DELTA_MASK) \ + cnt += JS_HOWMANY(diff_ - SN_DELTA_MASK, SN_XDELTA_MASK); \ + cnt += 2 + (((cg)->firstLine > SN_3BYTE_OFFSET_MASK) << 1); \ + } else if (diff_ > 0) { \ + if (cg->main.noteCount) { \ + jssrcnote *sn_ = (cg)->main.notes; \ + diff_ -= SN_IS_XDELTA(sn_) \ + ? SN_XDELTA_MASK - (*sn_ & SN_XDELTA_MASK) \ + : SN_DELTA_MASK - (*sn_ & SN_DELTA_MASK); \ + } \ + if (diff_ > 0) \ + cnt += JS_HOWMANY(diff_, SN_XDELTA_MASK); \ + } \ + JS_END_MACRO + +extern JSBool +js_FinishTakingSrcNotes(JSContext *cx, JSCodeGenerator *cg, jssrcnote *notes); + +/* + * Allocate cg->treeContext.tryCount notes (plus one for the end sentinel) + * from cx->tempPool and set up cg->tryBase/tryNext for exactly tryCount + * js_NewTryNote calls. The storage is freed by js_FinishCodeGenerator. + */ +extern JSBool +js_AllocTryNotes(JSContext *cx, JSCodeGenerator *cg); + +/* + * Grab the next trynote slot in cg, filling it in appropriately. + */ +extern JSTryNote * +js_NewTryNote(JSContext *cx, JSCodeGenerator *cg, ptrdiff_t start, + ptrdiff_t end, ptrdiff_t catchStart); + +/* + * Finish generating exception information into the space at notes. As with + * js_FinishTakingSrcNotes, the caller must use CG_COUNT_FINAL_TRYNOTES(cg) to + * preallocate enough space in a JSTryNote[] to pass as the notes parameter of + * js_FinishTakingTryNotes. + */ +#define CG_COUNT_FINAL_TRYNOTES(cg, cnt) \ + JS_BEGIN_MACRO \ + cnt = ((cg)->tryNext > (cg)->tryBase) \ + ? PTRDIFF(cg->tryNext, cg->tryBase, JSTryNote) + 1 \ + : 0; \ + JS_END_MACRO + +extern void +js_FinishTakingTryNotes(JSContext *cx, JSCodeGenerator *cg, JSTryNote *notes); + +JS_END_EXTERN_C + +#endif /* jsemit_h___ */ diff --git a/src/dom/js/jsexn.c b/src/dom/js/jsexn.c new file mode 100644 index 000000000..c407c1628 --- /dev/null +++ b/src/dom/js/jsexn.c @@ -0,0 +1,1081 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* + * JS standard exception implementation. + */ + +#include "jsstddef.h" +#include +#include +#include "jstypes.h" +#include "jsbit.h" +#include "jsutil.h" /* Added by JSIFY */ +#include "jsprf.h" +#include "jsapi.h" +#include "jscntxt.h" +#include "jsconfig.h" +#include "jsexn.h" +#include "jsfun.h" +#include "jsinterp.h" +#include "jsopcode.h" +#include "jsnum.h" +#include "jsscript.h" + +#if JS_HAS_ERROR_EXCEPTIONS +#if !JS_HAS_EXCEPTIONS +# error "JS_HAS_EXCEPTIONS must be defined to use JS_HAS_ERROR_EXCEPTIONS" +#endif + +/* XXX consider adding rt->atomState.messageAtom */ +static char js_message_str[] = "message"; +static char js_filename_str[] = "fileName"; +static char js_lineno_str[] = "lineNumber"; +static char js_stack_str[] = "stack"; + +/* Forward declarations for ExceptionClass's initializer. */ +static JSBool +Exception(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval); + +static void +exn_finalize(JSContext *cx, JSObject *obj); + +static JSClass ExceptionClass = { + "Error", + JSCLASS_HAS_PRIVATE, + JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, + JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, exn_finalize, + NULL, NULL, NULL, Exception, + NULL, NULL, NULL, 0 +}; + +/* + * A copy of the JSErrorReport originally generated. + */ +typedef struct JSExnPrivate { + JSErrorReport *errorReport; +} JSExnPrivate; + +/* + * Undo all the damage done by exn_newPrivate. + */ +static void +exn_destroyPrivate(JSContext *cx, JSExnPrivate *privateData) +{ + JSErrorReport *report; + const jschar **args; + + if (!privateData) + return; + report = privateData->errorReport; + if (report) { + if (report->uclinebuf) + JS_free(cx, (void *)report->uclinebuf); + if (report->filename) + JS_free(cx, (void *)report->filename); + if (report->ucmessage) + JS_free(cx, (void *)report->ucmessage); + if (report->messageArgs) { + args = report->messageArgs; + while (*args != NULL) + JS_free(cx, (void *)*args++); + JS_free(cx, (void *)report->messageArgs); + } + JS_free(cx, report); + } + JS_free(cx, privateData); +} + +/* + * Copy everything interesting about an error into allocated memory. + */ +static JSExnPrivate * +exn_newPrivate(JSContext *cx, JSErrorReport *report) +{ + intN i; + JSExnPrivate *newPrivate; + JSErrorReport *newReport; + size_t capacity; + + newPrivate = (JSExnPrivate *)JS_malloc(cx, sizeof (JSExnPrivate)); + if (!newPrivate) + return NULL; + memset(newPrivate, 0, sizeof (JSExnPrivate)); + + /* Copy the error report */ + newReport = (JSErrorReport *)JS_malloc(cx, sizeof (JSErrorReport)); + if (!newReport) + goto error; + memset(newReport, 0, sizeof (JSErrorReport)); + newPrivate->errorReport = newReport; + + if (report->filename != NULL) { + newReport->filename = JS_strdup(cx, report->filename); + if (!newReport->filename) + goto error; + } else { + newReport->filename = NULL; + } + + newReport->lineno = report->lineno; + + /* + * We don't need to copy linebuf and tokenptr, because they + * point into the deflated string cache. (currently?) + */ + newReport->linebuf = report->linebuf; + newReport->tokenptr = report->tokenptr; + + /* + * But we do need to copy uclinebuf, uctokenptr, because they're + * pointers into internal tokenstream structs, and may go away. + */ + if (report->uclinebuf != NULL) { + capacity = js_strlen(report->uclinebuf) + 1; + newReport->uclinebuf = + (const jschar *)JS_malloc(cx, capacity * sizeof(jschar)); + if (!newReport->uclinebuf) + goto error; + js_strncpy((jschar *)newReport->uclinebuf, report->uclinebuf, capacity); + newReport->uctokenptr = newReport->uclinebuf + (report->uctokenptr - + report->uclinebuf); + } else { + newReport->uclinebuf = newReport->uctokenptr = NULL; + } + + if (report->ucmessage != NULL) { + capacity = js_strlen(report->ucmessage) + 1; + newReport->ucmessage = (const jschar *) + JS_malloc(cx, capacity * sizeof(jschar)); + if (!newReport->ucmessage) + goto error; + js_strncpy((jschar *)newReport->ucmessage, report->ucmessage, capacity); + + if (report->messageArgs) { + for (i = 0; report->messageArgs[i] != NULL; i++) + continue; + JS_ASSERT(i); + newReport->messageArgs = + (const jschar **)JS_malloc(cx, (i + 1) * sizeof(jschar *)); + if (!newReport->messageArgs) + goto error; + for (i = 0; report->messageArgs[i] != NULL; i++) { + capacity = js_strlen(report->messageArgs[i]) + 1; + newReport->messageArgs[i] = + (const jschar *)JS_malloc(cx, capacity * sizeof(jschar)); + if (!newReport->messageArgs[i]) + goto error; + js_strncpy((jschar *)(newReport->messageArgs[i]), + report->messageArgs[i], capacity); + } + newReport->messageArgs[i] = NULL; + } else { + newReport->messageArgs = NULL; + } + } else { + newReport->ucmessage = NULL; + newReport->messageArgs = NULL; + } + newReport->errorNumber = report->errorNumber; + + /* Note that this is before it gets flagged with JSREPORT_EXCEPTION */ + newReport->flags = report->flags; + + return newPrivate; +error: + exn_destroyPrivate(cx, newPrivate); + return NULL; +} + +static void +exn_finalize(JSContext *cx, JSObject *obj) +{ + JSExnPrivate *privateData; + jsval privateValue; + + privateValue = OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE); + + if (!JSVAL_IS_VOID(privateValue)) { + privateData = (JSExnPrivate*) JSVAL_TO_PRIVATE(privateValue); + if (privateData) + exn_destroyPrivate(cx, privateData); + } +} + +JSErrorReport * +js_ErrorFromException(JSContext *cx, jsval exn) +{ + JSObject *obj; + JSExnPrivate *privateData; + jsval privateValue; + + if (JSVAL_IS_PRIMITIVE(exn)) + return NULL; + obj = JSVAL_TO_OBJECT(exn); + if (OBJ_GET_CLASS(cx, obj) != &ExceptionClass) + return NULL; + privateValue = OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE); + if (JSVAL_IS_VOID(privateValue)) + return NULL; + privateData = (JSExnPrivate*) JSVAL_TO_PRIVATE(privateValue); + if (!privateData) + return NULL; + + JS_ASSERT(privateData->errorReport); + return privateData->errorReport; +} + +/* + * This must be kept in synch with the exceptions array below. + * XXX use a jsexn.tbl file a la jsopcode.tbl + */ +typedef enum JSExnType { + JSEXN_NONE = -1, + JSEXN_ERR, + JSEXN_INTERNALERR, + JSEXN_EVALERR, + JSEXN_RANGEERR, + JSEXN_REFERENCEERR, + JSEXN_SYNTAXERR, + JSEXN_TYPEERR, + JSEXN_URIERR, + JSEXN_LIMIT +} JSExnType; + +struct JSExnSpec { + int protoIndex; + const char *name; + JSNative native; +}; + +/* + * All *Error constructors share the same JSClass, ExceptionClass. But each + * constructor function for an *Error class must have a distinct native 'call' + * function pointer, in order for instanceof to work properly across multiple + * standard class sets. See jsfun.c:fun_hasInstance. + */ +#define MAKE_EXCEPTION_CTOR(name) \ +const char js_##name##_str[] = #name; \ +static JSBool \ +name(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) \ +{ \ + return Exception(cx, obj, argc, argv, rval); \ +} + +MAKE_EXCEPTION_CTOR(Error) +MAKE_EXCEPTION_CTOR(InternalError) +MAKE_EXCEPTION_CTOR(EvalError) +MAKE_EXCEPTION_CTOR(RangeError) +MAKE_EXCEPTION_CTOR(ReferenceError) +MAKE_EXCEPTION_CTOR(SyntaxError) +MAKE_EXCEPTION_CTOR(TypeError) +MAKE_EXCEPTION_CTOR(URIError) + +#undef MAKE_EXCEPTION_CTOR + +static struct JSExnSpec exceptions[] = { + { JSEXN_NONE, js_Error_str, Error }, + { JSEXN_ERR, js_InternalError_str, InternalError }, + { JSEXN_ERR, js_EvalError_str, EvalError }, + { JSEXN_ERR, js_RangeError_str, RangeError }, + { JSEXN_ERR, js_ReferenceError_str, ReferenceError }, + { JSEXN_ERR, js_SyntaxError_str, SyntaxError }, + { JSEXN_ERR, js_TypeError_str, TypeError }, + { JSEXN_ERR, js_URIError_str, URIError }, + {0,NULL,NULL} +}; + +static JSBool +InitExceptionObject(JSContext *cx, JSObject *obj, JSString *message, + JSString *filename, uintN lineno) +{ + JSCheckAccessOp checkAccess; + JSErrorReporter older; + JSExceptionState *state; + jschar *stackbuf; + size_t stacklen, stackmax; + JSStackFrame *fp; + jsval callerid, v; + JSBool ok; + JSString *argsrc, *stack; + uintN i, ulineno; + const char *cp; + char ulnbuf[11]; + + if (!JS_DefineProperty(cx, obj, js_message_str, STRING_TO_JSVAL(message), + NULL, NULL, JSPROP_ENUMERATE)) { + return JS_FALSE; + } + + if (!JS_DefineProperty(cx, obj, js_filename_str, + STRING_TO_JSVAL(filename), + NULL, NULL, JSPROP_ENUMERATE)) { + return JS_FALSE; + } + + if (!JS_DefineProperty(cx, obj, js_lineno_str, + INT_TO_JSVAL(lineno), + NULL, NULL, JSPROP_ENUMERATE)) { + return JS_FALSE; + } + + /* + * Set the 'stack' property. + * + * First, set aside any error reporter for cx and save its exception state + * so we can suppress any checkAccess failures. Such failures should stop + * the backtrace procedure, not result in a failure of this constructor. + */ + checkAccess = cx->runtime->checkObjectAccess; + if (checkAccess) { + older = JS_SetErrorReporter(cx, NULL); + state = JS_SaveExceptionState(cx); + } +#ifdef __GNUC__ /* suppress bogus gcc warnings */ + else { + older = NULL; + state = NULL; + } +#endif + callerid = ATOM_KEY(cx->runtime->atomState.callerAtom); + + /* + * Prepare to allocate a jschar buffer at stackbuf, where stacklen indexes + * the next free jschar slot, and with room for at most stackmax non-null + * jschars. If stackbuf is non-null, it always contains an extra slot for + * the null terminator we'll store at the end, as a backstop. + * + * All early returns must goto done after this point, till the after-loop + * cleanup code has run! + */ + stackbuf = NULL; + stacklen = stackmax = 0; + ok = JS_TRUE; + +#define APPEND_CHAR_TO_STACK(c) \ + JS_BEGIN_MACRO \ + if (stacklen == stackmax) { \ + void *ptr_; \ + stackmax = stackmax ? 2 * stackmax : 64; \ + ptr_ = JS_realloc(cx, stackbuf, (stackmax+1) * sizeof(jschar)); \ + if (!ptr_) { \ + ok = JS_FALSE; \ + goto done; \ + } \ + stackbuf = ptr_; \ + } \ + stackbuf[stacklen++] = (c); \ + JS_END_MACRO + +#define APPEND_STRING_TO_STACK(str) \ + JS_BEGIN_MACRO \ + JSString *str_ = str; \ + size_t length_ = JSSTRING_LENGTH(str_); \ + if (stacklen + length_ > stackmax) { \ + void *ptr_; \ + stackmax = JS_BIT(JS_CeilingLog2(stacklen + length_)); \ + ptr_ = JS_realloc(cx, stackbuf, (stackmax+1) * sizeof(jschar)); \ + if (!ptr_) { \ + ok = JS_FALSE; \ + goto done; \ + } \ + stackbuf = ptr_; \ + } \ + js_strncpy(stackbuf + stacklen, JSSTRING_CHARS(str_), length_); \ + stacklen += length_; \ + JS_END_MACRO + + for (fp = cx->fp; fp; fp = fp->down) { + if (checkAccess) { + v = (fp->fun && fp->argv) ? fp->argv[-2] : JSVAL_NULL; + if (!JSVAL_IS_PRIMITIVE(v)) { + ok = checkAccess(cx, fp->fun->object, callerid, JSACC_READ, &v); + if (!ok) { + ok = JS_TRUE; + break; + } + } + } + + if (fp->fun) { + if (fp->fun->atom) + APPEND_STRING_TO_STACK(ATOM_TO_STRING(fp->fun->atom)); + + APPEND_CHAR_TO_STACK('('); + for (i = 0; i < fp->argc; i++) { + /* Avoid toSource bloat and fallibility for object types. */ + v = fp->argv[i]; + if (JSVAL_IS_PRIMITIVE(v)) { + argsrc = js_ValueToSource(cx, v); + } else if (JSVAL_IS_FUNCTION(cx, v)) { + /* XXX Avoid function decompilation bloat for now. */ + argsrc = JS_GetFunctionId(JS_ValueToFunction(cx, v)); + if (!argsrc) + argsrc = js_ValueToSource(cx, v); + } else { + /* XXX Avoid toString on objects, it takes too long and + uses too much memory, for too many classes (see + Mozilla bug 166743). */ + char buf[100]; + JS_snprintf(buf, sizeof buf, "[object %s]", + OBJ_GET_CLASS(cx, JSVAL_TO_OBJECT(v))->name); + argsrc = JS_NewStringCopyZ(cx, buf); + } + if (!argsrc) { + ok = JS_FALSE; + goto done; + } + if (i > 0) + APPEND_CHAR_TO_STACK(','); + APPEND_STRING_TO_STACK(argsrc); + } + APPEND_CHAR_TO_STACK(')'); + } + + APPEND_CHAR_TO_STACK('@'); + if (fp->script && fp->script->filename) { + for (cp = fp->script->filename; *cp; cp++) + APPEND_CHAR_TO_STACK(*cp); + } + APPEND_CHAR_TO_STACK(':'); + if (fp->script && fp->pc) { + ulineno = js_PCToLineNumber(cx, fp->script, fp->pc); + JS_snprintf(ulnbuf, sizeof ulnbuf, "%u", ulineno); + for (cp = ulnbuf; *cp; cp++) + APPEND_CHAR_TO_STACK(*cp); + } else { + APPEND_CHAR_TO_STACK('0'); + } + APPEND_CHAR_TO_STACK('\n'); + } + +#undef APPEND_CHAR_TO_STACK +#undef APPEND_STRING_TO_STACK + +done: + if (checkAccess) { + if (ok) + JS_RestoreExceptionState(cx, state); + else + JS_DropExceptionState(cx, state); + JS_SetErrorReporter(cx, older); + } + if (!ok) { + JS_free(cx, stackbuf); + return JS_FALSE; + } + + if (!stackbuf) { + stack = cx->runtime->emptyString; + } else { + /* NB: if stackbuf was allocated, it has room for the terminator. */ + JS_ASSERT(stacklen <= stackmax); + if (stacklen < stackmax) { + /* + * Realloc can fail when shrinking on some FreeBSD versions, so + * don't use JS_realloc here; simply let the oversized allocation + * be owned by the string in that rare case. + */ + void *shrunk = realloc(stackbuf, (stacklen+1) * sizeof(jschar)); + if (shrunk) + stackbuf = shrunk; + } + stackbuf[stacklen] = 0; + stack = js_NewString(cx, stackbuf, stacklen, 0); + if (!stack) { + JS_free(cx, stackbuf); + return JS_FALSE; + } + } + return JS_DefineProperty(cx, obj, js_stack_str, + STRING_TO_JSVAL(stack), + NULL, NULL, JSPROP_ENUMERATE); +} + +static JSBool +Exception(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + JSBool ok; + jsval pval; + int32 lineno; + JSString *message, *filename; + + if (cx->creatingException) + return JS_FALSE; + cx->creatingException = JS_TRUE; + + if (!(cx->fp->flags & JSFRAME_CONSTRUCTING)) { + /* + * ECMA ed. 3, 15.11.1 requires Error, etc., to construct even when + * called as functions, without operator new. But as we do not give + * each constructor a distinct JSClass, whose .name member is used by + * js_NewObject to find the class prototype, we must get the class + * prototype ourselves. + */ + ok = OBJ_GET_PROPERTY(cx, JSVAL_TO_OBJECT(argv[-2]), + (jsid)cx->runtime->atomState.classPrototypeAtom, + &pval); + if (!ok) + goto out; + obj = js_NewObject(cx, &ExceptionClass, JSVAL_TO_OBJECT(pval), NULL); + if (!obj) { + ok = JS_FALSE; + goto out; + } + *rval = OBJECT_TO_JSVAL(obj); + } + + /* + * If it's a new object of class Exception, then null out the private + * data so that the finalizer doesn't attempt to free it. + */ + if (OBJ_GET_CLASS(cx, obj) == &ExceptionClass) + OBJ_SET_SLOT(cx, obj, JSSLOT_PRIVATE, JSVAL_VOID); + + /* Set the 'message' property. */ + if (argc != 0) { + message = js_ValueToString(cx, argv[0]); + if (!message) { + ok = JS_FALSE; + goto out; + } + } else { + message = cx->runtime->emptyString; + } + + /* Set the 'fileName' property. */ + if (argc > 1) { + filename = js_ValueToString(cx, argv[1]); + if (!filename) { + ok = JS_FALSE; + goto out; + } + } else { + filename = cx->runtime->emptyString; + } + + /* Set the 'lineNumber' property. */ + if (argc > 2) { + ok = js_ValueToInt32(cx, argv[2], &lineno); + if (!ok) + goto out; + } else { + lineno = 0; + } + + ok = InitExceptionObject(cx, obj, message, filename, lineno); + +out: + cx->creatingException = JS_FALSE; + return ok; +} + +/* + * Convert to string. + * + * This method only uses JavaScript-modifiable properties name, message. It + * is left to the host to check for private data and report filename and line + * number information along with this message. + */ +static JSBool +exn_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + jsval v; + JSString *name, *message, *result; + jschar *chars, *cp; + size_t name_length, message_length, length; + + if (!OBJ_GET_PROPERTY(cx, obj, (jsid)cx->runtime->atomState.nameAtom, &v)) + return JS_FALSE; + name = js_ValueToString(cx, v); + if (!name) + return JS_FALSE; + + if (!JS_GetProperty(cx, obj, js_message_str, &v) || + !(message = js_ValueToString(cx, v))) { + return JS_FALSE; + } + + if (JSSTRING_LENGTH(message) != 0) { + name_length = JSSTRING_LENGTH(name); + message_length = JSSTRING_LENGTH(message); + length = name_length + message_length + 2; + cp = chars = (jschar*) JS_malloc(cx, (length + 1) * sizeof(jschar)); + if (!chars) + return JS_FALSE; + + js_strncpy(cp, JSSTRING_CHARS(name), name_length); + cp += name_length; + *cp++ = ':'; *cp++ = ' '; + js_strncpy(cp, JSSTRING_CHARS(message), message_length); + cp += message_length; + *cp = 0; + + result = js_NewString(cx, chars, length, 0); + if (!result) { + JS_free(cx, chars); + return JS_FALSE; + } + } else { + result = name; + } + + *rval = STRING_TO_JSVAL(result); + return JS_TRUE; +} + +#if JS_HAS_TOSOURCE +/* + * Return a string that may eval to something similar to the original object. + */ +static JSBool +exn_toSource(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + jsval v; + JSString *name, *message, *filename, *lineno_as_str, *result; + int32 lineno; + size_t lineno_length, name_length, message_length, filename_length, length; + jschar *chars, *cp; + + if (!OBJ_GET_PROPERTY(cx, obj, (jsid)cx->runtime->atomState.nameAtom, &v)) + return JS_FALSE; + name = js_ValueToString(cx, v); + if (!name) + return JS_FALSE; + + if (!JS_GetProperty(cx, obj, js_message_str, &v) || + !(message = js_ValueToSource(cx, v))) { + return JS_FALSE; + } + + if (!JS_GetProperty(cx, obj, js_filename_str, &v) || + !(filename = js_ValueToSource(cx, v))) { + return JS_FALSE; + } + + if (!JS_GetProperty(cx, obj, js_lineno_str, &v) || + !js_ValueToInt32 (cx, v, &lineno)) { + return JS_FALSE; + } + + if (lineno != 0) { + if (!(lineno_as_str = js_ValueToString(cx, v))) { + return JS_FALSE; + } + lineno_length = JSSTRING_LENGTH(lineno_as_str); + } else { + lineno_as_str = NULL; + lineno_length = 0; + } + + /* Magic 8, for the characters in ``(new ())''. */ + name_length = JSSTRING_LENGTH(name); + message_length = JSSTRING_LENGTH(message); + length = 8 + name_length + message_length; + + filename_length = JSSTRING_LENGTH(filename); + if (filename_length != 0) { + /* append filename as ``, {filename}'' */ + length += 2 + filename_length; + if (lineno_as_str) { + /* append lineno as ``, {lineno_as_str}'' */ + length += 2 + lineno_length; + } + } else { + if (lineno_as_str) { + /* + * no filename, but have line number, + * need to append ``, "", {lineno_as_str}'' + */ + length += 6 + lineno_length; + } + } + + cp = chars = (jschar*) JS_malloc(cx, (length + 1) * sizeof(jschar)); + if (!chars) + return JS_FALSE; + + *cp++ = '('; *cp++ = 'n'; *cp++ = 'e'; *cp++ = 'w'; *cp++ = ' '; + js_strncpy(cp, JSSTRING_CHARS(name), name_length); + cp += name_length; + *cp++ = '('; + if (message_length != 0) { + js_strncpy(cp, JSSTRING_CHARS(message), message_length); + cp += message_length; + } + + if (filename_length != 0) { + /* append filename as ``, {filename}'' */ + *cp++ = ','; *cp++ = ' '; + js_strncpy(cp, JSSTRING_CHARS(filename), filename_length); + cp += filename_length; + } else { + if (lineno_as_str) { + /* + * no filename, but have line number, + * need to append ``, "", {lineno_as_str}'' + */ + *cp++ = ','; *cp++ = ' '; *cp++ = '"'; *cp++ = '"'; + } + } + if (lineno_as_str) { + /* append lineno as ``, {lineno_as_str}'' */ + *cp++ = ','; *cp++ = ' '; + js_strncpy(cp, JSSTRING_CHARS(lineno_as_str), lineno_length); + cp += lineno_length; + } + + *cp++ = ')'; *cp++ = ')'; *cp = 0; + + result = js_NewString(cx, chars, length, 0); + if (!result) { + JS_free(cx, chars); + return JS_FALSE; + } + *rval = STRING_TO_JSVAL(result); + return JS_TRUE; +} +#endif + +static JSFunctionSpec exception_methods[] = { +#if JS_HAS_TOSOURCE + {js_toSource_str, exn_toSource, 0,0,0}, +#endif + {js_toString_str, exn_toString, 0,0,0}, + {0,0,0,0,0} +}; + +JSObject * +js_InitExceptionClasses(JSContext *cx, JSObject *obj) +{ + int i; + JSObject *protos[JSEXN_LIMIT]; + + /* Initialize the prototypes first. */ + for (i = 0; exceptions[i].name != 0; i++) { + JSAtom *atom; + JSFunction *fun; + JSString *nameString; + int protoIndex = exceptions[i].protoIndex; + + /* Make the prototype for the current constructor name. */ + protos[i] = js_NewObject(cx, &ExceptionClass, + (protoIndex != JSEXN_NONE) + ? protos[protoIndex] + : NULL, + obj); + if (!protos[i]) + return NULL; + + /* So exn_finalize knows whether to destroy private data. */ + OBJ_SET_SLOT(cx, protos[i], JSSLOT_PRIVATE, JSVAL_VOID); + + atom = js_Atomize(cx, exceptions[i].name, strlen(exceptions[i].name), 0); + if (!atom) + return NULL; + + /* Make a constructor function for the current name. */ + fun = js_DefineFunction(cx, obj, atom, exceptions[i].native, 3, 0); + if (!fun) + return NULL; + + /* Make this constructor make objects of class Exception. */ + fun->clasp = &ExceptionClass; + + /* Make the prototype and constructor links. */ + if (!js_SetClassPrototype(cx, fun->object, protos[i], + JSPROP_READONLY | JSPROP_PERMANENT)) { + return NULL; + } + + /* proto bootstrap bit from JS_InitClass omitted. */ + nameString = JS_NewStringCopyZ(cx, exceptions[i].name); + if (!nameString) + return NULL; + + /* Add the name property to the prototype. */ + if (!JS_DefineProperty(cx, protos[i], js_name_str, + STRING_TO_JSVAL(nameString), + NULL, NULL, + JSPROP_ENUMERATE)) { + return NULL; + } + } + + /* + * Add an empty message property. (To Exception.prototype only, + * because this property will be the same for all the exception + * protos.) + */ + if (!JS_DefineProperty(cx, protos[0], js_message_str, + STRING_TO_JSVAL(cx->runtime->emptyString), + NULL, NULL, JSPROP_ENUMERATE)) { + return NULL; + } + if (!JS_DefineProperty(cx, protos[0], js_filename_str, + STRING_TO_JSVAL(cx->runtime->emptyString), + NULL, NULL, JSPROP_ENUMERATE)) { + return NULL; + } + if (!JS_DefineProperty(cx, protos[0], js_lineno_str, + INT_TO_JSVAL(0), + NULL, NULL, JSPROP_ENUMERATE)) { + return NULL; + } + + /* + * Add methods only to Exception.prototype, because ostensibly all + * exception types delegate to that. + */ + if (!JS_DefineFunctions(cx, protos[0], exception_methods)) + return NULL; + + return protos[0]; +} + +static JSExnType errorToExceptionNum[] = { +#define MSG_DEF(name, number, count, exception, format) \ + exception, +#include "js.msg" +#undef MSG_DEF +}; + +#if defined ( DEBUG_mccabe ) && defined ( PRINTNAMES ) +/* For use below... get character strings for error name and exception name */ +static struct exnname { char *name; char *exception; } errortoexnname[] = { +#define MSG_DEF(name, number, count, exception, format) \ + {#name, #exception}, +#include "js.msg" +#undef MSG_DEF +}; +#endif /* DEBUG */ + +JSBool +js_ErrorToException(JSContext *cx, const char *message, JSErrorReport *reportp) +{ + JSErrNum errorNumber; + JSExnType exn; + JSBool ok; + JSObject *errProto, *errObject; + JSString *messageStr, *filenameStr; + uintN lineno; + JSExnPrivate *privateData; + + /* + * Tell our caller to report immediately if cx has no active frames, or if + * this report is just a warning. + */ + JS_ASSERT(reportp); + if (!cx->fp || JSREPORT_IS_WARNING(reportp->flags)) + return JS_FALSE; + + /* Find the exception index associated with this error. */ + errorNumber = (JSErrNum) reportp->errorNumber; + exn = errorToExceptionNum[errorNumber]; + JS_ASSERT(exn < JSEXN_LIMIT); + +#if defined( DEBUG_mccabe ) && defined ( PRINTNAMES ) + /* Print the error name and the associated exception name to stderr */ + fprintf(stderr, "%s\t%s\n", + errortoexnname[errorNumber].name, + errortoexnname[errorNumber].exception); +#endif + + /* + * Return false (no exception raised) if no exception is associated + * with the given error number. + */ + if (exn == JSEXN_NONE) + return JS_FALSE; + + /* + * Prevent runaway recursion, just as the Exception native constructor + * must do, via cx->creatingException. If an out-of-memory error occurs, + * no exception object will be created, but we don't assume that OOM is + * the only kind of error that subroutines of this function called below + * might raise. + */ + if (cx->creatingException) + return JS_FALSE; + cx->creatingException = JS_TRUE; + + /* + * Try to get an appropriate prototype by looking up the corresponding + * exception constructor name in the scope chain of the current context's + * top stack frame, or in the global object if no frame is active. + * + * XXXbe hack around JSCLASS_NEW_RESOLVE code in js_LookupProperty that + * checks cx->fp, cx->fp->pc, and js_CodeSpec[*cx->fp->pc] in order + * to compute resolve flags such as JSRESOLVE_ASSIGNING. The bug + * is that this "internal" js_GetClassPrototype call may trigger a + * resolve of exceptions[exn].name if the global object uses a lazy + * standard class resolver (see JS_ResolveStandardClass), but the + * current frame and bytecode end up affecting the resolve flags. + */ + { + JSStackFrame *fp = cx->fp; + jsbytecode *pc = NULL; + + if (fp) { + pc = fp->pc; + fp->pc = NULL; + } + ok = js_GetClassPrototype(cx, exceptions[exn].name, &errProto); + if (pc) + fp->pc = pc; + if (!ok) + goto out; + } + + errObject = js_NewObject(cx, &ExceptionClass, errProto, NULL); + if (!errObject) { + ok = JS_FALSE; + goto out; + } + + /* + * Set the generated Exception object early, so it won't be GC'd by a last + * ditch attempt to collect garbage, or a GC that otherwise nests or races + * under any of the following calls. If one of the following calls fails, + * it will overwrite this exception object with one of its own (except in + * case of OOM errors, of course). + */ + JS_SetPendingException(cx, OBJECT_TO_JSVAL(errObject)); + + messageStr = JS_NewStringCopyZ(cx, message); + if (!messageStr) { + ok = JS_FALSE; + goto out; + } + + if (reportp) { + filenameStr = JS_NewStringCopyZ(cx, reportp->filename); + if (!filenameStr) { + ok = JS_FALSE; + goto out; + } + lineno = reportp->lineno; + } else { + filenameStr = cx->runtime->emptyString; + lineno = 0; + } + ok = InitExceptionObject(cx, errObject, messageStr, filenameStr, lineno); + if (!ok) + goto out; + + /* + * Construct a new copy of the error report struct, and store it in the + * exception object's private data. We can't use the error report struct + * that was passed in, because it's stack-allocated, and also because it + * may point to transient data in the JSTokenStream. + */ + privateData = exn_newPrivate(cx, reportp); + if (!privateData) { + ok = JS_FALSE; + goto out; + } + OBJ_SET_SLOT(cx, errObject, JSSLOT_PRIVATE, PRIVATE_TO_JSVAL(privateData)); + + /* Flag the error report passed in to indicate an exception was raised. */ + reportp->flags |= JSREPORT_EXCEPTION; + +out: + cx->creatingException = JS_FALSE; + return ok; +} +#endif /* JS_HAS_ERROR_EXCEPTIONS */ + +#if JS_HAS_EXCEPTIONS + +JSBool +js_ReportUncaughtException(JSContext *cx) +{ + JSObject *exnObject; + JSString *str; + jsval exn; + JSErrorReport *reportp; + const char *bytes; + + if (!JS_IsExceptionPending(cx)) + return JS_FALSE; + + if (!JS_GetPendingException(cx, &exn)) + return JS_FALSE; + + /* + * Because js_ValueToString below could error and an exception object + * could become unrooted, we root it here. + */ + if (JSVAL_IS_OBJECT(exn) && exn != JSVAL_NULL) { + exnObject = JSVAL_TO_OBJECT(exn); + if (!js_AddRoot(cx, &exnObject, "exn.report.root")) + return JS_FALSE; + } else { + exnObject = NULL; + } + +#if JS_HAS_ERROR_EXCEPTIONS + reportp = js_ErrorFromException(cx, exn); +#else + reportp = NULL; +#endif + + str = js_ValueToString(cx, exn); + bytes = str ? js_GetStringBytes(str) : "null"; + + if (reportp == NULL) { + /* + * XXXmccabe todo: Instead of doing this, synthesize an error report + * struct that includes the filename, lineno where the exception was + * originally thrown. + */ + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, + JSMSG_UNCAUGHT_EXCEPTION, bytes); + } else { + /* Flag the error as an exception. */ + reportp->flags |= JSREPORT_EXCEPTION; + js_ReportErrorAgain(cx, bytes, reportp); + } + + if (exnObject != NULL) + js_RemoveRoot(cx->runtime, &exnObject); + return JS_TRUE; +} + +#endif /* JS_HAS_EXCEPTIONS */ diff --git a/src/dom/js/jsexn.h b/src/dom/js/jsexn.h new file mode 100644 index 000000000..aeaab0a58 --- /dev/null +++ b/src/dom/js/jsexn.h @@ -0,0 +1,102 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* + * JS runtime exception classes. + */ + +#ifndef jsexn_h___ +#define jsexn_h___ + +JS_BEGIN_EXTERN_C + +/* + * Initialize the exception constructor/prototype hierarchy. + */ +extern JSObject * +js_InitExceptionClasses(JSContext *cx, JSObject *obj); + +/* + * String constants naming the exception classes. + */ +extern const char js_Error_str[]; +extern const char js_InternalError_str[]; +extern const char js_EvalError_str[]; +extern const char js_RangeError_str[]; +extern const char js_ReferenceError_str[]; +extern const char js_SyntaxError_str[]; +extern const char js_TypeError_str[]; +extern const char js_URIError_str[]; + +/* + * Given a JSErrorReport, check to see if there is an exception associated with + * the error number. If there is, then create an appropriate exception object, + * set it as the pending exception, and set the JSREPORT_EXCEPTION flag on the + * error report. Exception-aware host error reporters should probably ignore + * error reports so flagged. Returns JS_TRUE if an associated exception is + * found and set, JS_FALSE otherwise.. + */ +extern JSBool +js_ErrorToException(JSContext *cx, const char *message, JSErrorReport *reportp); + +/* + * Called if a JS API call to js_Execute or js_InternalCall fails; calls the + * error reporter with the error report associated with any uncaught exception + * that has been raised. Returns true if there was an exception pending, and + * the error reporter was actually called. + * + * The JSErrorReport * that the error reporter is called with is currently + * associated with a JavaScript object, and is not guaranteed to persist after + * the object is collected. Any persistent uses of the JSErrorReport contents + * should make their own copy. + * + * The flags field of the JSErrorReport will have the JSREPORT_EXCEPTION flag + * set; embeddings that want to silently propagate JavaScript exceptions to + * other contexts may want to use an error reporter that ignores errors with + * this flag. + */ +extern JSBool +js_ReportUncaughtException(JSContext *cx); + +extern JSErrorReport * +js_ErrorFromException(JSContext *cx, jsval exn); + +JS_END_EXTERN_C + +#endif /* jsexn_h___ */ diff --git a/src/dom/js/jsfile.c b/src/dom/js/jsfile.c new file mode 100644 index 000000000..ef5e93b29 --- /dev/null +++ b/src/dom/js/jsfile.c @@ -0,0 +1,2610 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* + * JS File object + */ +#if JS_HAS_FILE_OBJECT + +#include "jsstddef.h" + +/* ----------------- Platform-specific includes and defines ----------------- */ +#ifdef XP_MAC +# define FILESEPARATOR ':' +# define FILESEPARATOR2 '\0' +# define CURRENT_DIR "HARD DISK:Desktop Folder" +/* TODO: #include */ +#elif defined(XP_WIN) || defined(XP_OS2) +# include +# include +# include +# include +# define FILESEPARATOR '\\' +# define FILESEPARATOR2 '/' +# define CURRENT_DIR "c:\\" +# define POPEN _popen +# define PCLOSE _pclose +#elif defined(XP_UNIX) || defined(XP_BEOS) +# include +# include +# include +# include +# define FILESEPARATOR '/' +# define FILESEPARATOR2 '\0' +# define CURRENT_DIR "/" +# define POPEN popen +# define PCLOSE pclose +#endif + +/* --------------- Platform-independent includes and defines ---------------- */ +#include "jsapi.h" +#include "jsatom.h" +#include "jscntxt.h" +#include "jsdate.h" +#include "jsdbgapi.h" +#include "jsemit.h" +#include "jsfun.h" +#include "jslock.h" +#include "jsobj.h" +#include "jsparse.h" +#include "jsscan.h" +#include "jsscope.h" +#include "jsscript.h" +#include "jsstr.h" +#include "jsutil.h" /* Added by JSIFY */ +#include + +/* NSPR dependencies */ +#include "prio.h" +#include "prerror.h" + +#define SPECIAL_FILE_STRING "Special File" +#define CURRENTDIR_PROPERTY "currentDir" +#define SEPARATOR_PROPERTY "separator" +#define FILE_CONSTRUCTOR "File" +#define PIPE_SYMBOL '|' + +#define ASCII 0 +#define UTF8 1 +#define UCS2 2 + +#define asciistring "text" +#define utfstring "binary" +#define unicodestring "unicode" + +#define MAX_PATH_LENGTH 1024 +#define MODE_SIZE 256 +#define NUMBER_SIZE 32 +#define MAX_LINE_LENGTH 256 +#define URL_PREFIX "file://" + +#define STDINPUT_NAME "Standard input stream" +#define STDOUTPUT_NAME "Standard output stream" +#define STDERROR_NAME "Standard error stream" + +#define RESOLVE_PATH js_canonicalPath /* js_absolutePath */ + +/* Error handling */ +typedef enum JSFileErrNum { +#define MSG_DEF(name, number, count, exception, format) \ + name = number, +#include "jsfile.msg" +#undef MSG_DEF + JSFileErr_Limit +#undef MSGDEF +} JSFileErrNum; + +#define JSFILE_HAS_DFLT_MSG_STRINGS 1 + +JSErrorFormatString JSFile_ErrorFormatString[JSFileErr_Limit] = { +#if JSFILE_HAS_DFLT_MSG_STRINGS +#define MSG_DEF(name, number, count, exception, format) \ + { format, count } , +#else +#define MSG_DEF(name, number, count, exception, format) \ + { NULL, count } , +#endif +#include "jsfile.msg" +#undef MSG_DEF +}; + +const JSErrorFormatString * +JSFile_GetErrorMessage(void *userRef, const char *locale, + const uintN errorNumber) +{ + if ((errorNumber > 0) && (errorNumber < JSFileErr_Limit)) + return &JSFile_ErrorFormatString[errorNumber]; + else + return NULL; +} + +#define JSFILE_CHECK_NATIVE(op) \ + if(file->isNative){ \ + JS_ReportWarning(cx, "Cannot call or access \"%s\" on native file %s", \ + op, file->path); \ + goto out; \ + } + +#define JSFILE_CHECK_WRITE \ + if (!file->isOpen){ \ + JS_ReportWarning(cx, \ + "File %s is closed, will open it for writing, proceeding", \ + file->path); \ + js_FileOpen(cx, obj, file, "write,append,create"); \ + }else \ + if(!js_canWrite(cx, file)){ \ + JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL, \ + JSFILEMSG_CANNOT_WRITE, file->path); \ + goto out; \ + } + +#define JSFILE_CHECK_READ \ + if (!file->isOpen){ \ + JS_ReportWarning(cx, \ + "File %s is closed, will open it for reading, proceeding", \ + file->path); \ + js_FileOpen(cx, obj, file, "read"); \ + }else \ + if(!js_canRead(cx, file)){ \ + JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL, \ + JSFILEMSG_CANNOT_READ, file->path); \ + goto out; \ + } + +#define JSFILE_CHECK_OPEN(op) \ + if(!file->isOpen){ \ + JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL, \ + JSFILEMSG_FILE_MUST_BE_CLOSED, op); \ + goto out; \ + } + +#define JSFILE_CHECK_CLOSED(op) \ + if(file->isOpen){ \ + JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL, \ + JSFILEMSG_FILE_MUST_BE_OPEN, op); \ + goto out; \ + } + +#define JSFILE_CHECK_ONE_ARG(op) \ + if (argc!=1){ \ + char str[NUMBER_SIZE]; \ + \ + sprintf(str, "%d", argc); \ + JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL, \ + JSFILEMSG_EXPECTS_ONE_ARG_ERROR, op, str); \ + goto out; \ + } + + +/* + Security mechanism, should define a callback for this. + The parameters are as follows: + SECURITY_CHECK(JSContext *cx, JSPrincipals *ps, char *op_name, JSFile *file) +*/ +#define SECURITY_CHECK(cx, ps, op, file) \ + /* Define a callback here... */ + + +/* Structure representing the file internally */ +typedef struct JSFile { + char *path; /* the path to the file. */ + JSBool isOpen; + JSString *linebuffer; /* temp buffer used by readln. */ + int32 mode; /* mode used to open the file: read, write, append, create, etc.. */ + int32 type; /* Asciiz, utf, unicode */ + char byteBuffer[3]; /* bytes read in advance by js_FileRead ( UTF8 encoding ) */ + jsint nbBytesInBuf; /* number of bytes stored in the buffer above */ + jschar charBuffer; /* character read in advance by readln ( mac files only ) */ + JSBool charBufferUsed; /* flag indicating if the buffer above is being used */ + JSBool hasRandomAccess; /* can the file be randomly accessed? false for stdin, and + UTF-encoded files. */ + JSBool hasAutoflush; /* should we force a flush for each line break? */ + JSBool isNative; /* if the file is using OS-specific file FILE type */ + /* We can actually put the following two in a union since they should never be used at the same time */ + PRFileDesc *handle; /* the handle for the file, if open. */ + FILE *nativehandle; /* native handle, for stuff NSPR doesn't do. */ + JSBool isPipe; /* if the file is really an OS pipe */ +} JSFile; + +/* a few forward declarations... */ +static JSClass file_class; +JS_PUBLIC_API(JSObject*) js_NewFileObject(JSContext *cx, char *filename); +static JSBool file_open(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval); +static JSBool file_close(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval); + +/* --------------------------- New filename manipulation procesures -------------------------- */ +/* assumes we don't have leading/trailing spaces */ +static JSBool +js_filenameHasAPipe(const char *filename) +{ +#ifdef XP_MAC + /* pipes are not supported on the MAC */ + return JS_FALSE; +#else + if(!filename) return JS_FALSE; + return filename[0]==PIPE_SYMBOL || + filename[strlen(filename)-1]==PIPE_SYMBOL; +#endif +} + +static JSBool +js_isAbsolute(const char *name) +{ +#if defined(XP_WIN) || defined(XP_OS2) + return (strlen(name)>1)?((name[1]==':')?JS_TRUE:JS_FALSE):JS_FALSE; +#else + return (name[0] +# if defined(XP_UNIX) || defined(XP_BEOS) + == +# else + != +# endif + FILESEPARATOR)?JS_TRUE:JS_FALSE; +#endif +} + +/* + Concatinates base and name to produce a valid filename. + Returned string must be freed. +*/ +static char* +js_combinePath(JSContext *cx, const char *base, const char *name) +{ + int len = strlen(base); + char* result = (char*)JS_malloc(cx, len+strlen(name)+2); + + if (!result) return NULL; + + strcpy(result, base); + + if (base[len-1]!=FILESEPARATOR +#if defined(XP_WIN) || defined(XP_OS2) + && base[len-1]!=FILESEPARATOR2 +#endif + ) { + result[len] = FILESEPARATOR; + result[len+1] = '\0'; + } + strcat(result, name); + return result; +} + +/* Extract the last component from a path name. Returned string must be freed */ +static char * +js_fileBaseName(JSContext *cx, const char *pathname) +{ + jsint index, aux; + char *result; + +#if defined(XP_WIN) || defined(XP_OS2) + /* First, get rid of the drive selector */ + if ((strlen(pathname)>=2)&&(pathname[1]==':')) { + pathname = &pathname[2]; + } +#endif + index = strlen(pathname)-1; + /* + remove trailing separators -- don't necessarily need to check for + FILESEPARATOR2, but that's fine + */ + while ((index>0)&&((pathname[index]==FILESEPARATOR)|| + (pathname[index]==FILESEPARATOR2))) index--; + aux = index; + /* now find the next separator */ + while ((index>=0)&&(pathname[index]!=FILESEPARATOR)&& + (pathname[index]!=FILESEPARATOR2)) index--; + /* allocate and copy */ + result = (char*)JS_malloc(cx, aux-index+1); + if (!result) return NULL; + strncpy(result, &pathname[index+1], aux-index); + result[aux-index] = '\0'; + return result; +} + +/* + Returns everytynig but the last component from a path name. + Returned string must be freed. Returned string must be freed. +*/ +static char * +js_fileDirectoryName(JSContext *cx, const char *pathname) +{ + jsint index; + char *result; + +#if defined(XP_WIN) || defined(XP_OS2) + char drive = '\0'; + const char *oldpathname = pathname; + + /* First, get rid of the drive selector */ + if ((strlen(pathname)>=2)&&(pathname[1]==':')) { + drive = pathname[0]; + pathname = &pathname[2]; + } +#endif + index = strlen(pathname)-1; + while ((index>0)&&((pathname[index]==FILESEPARATOR)|| + (pathname[index]==FILESEPARATOR2))) index--; + while ((index>0)&&(pathname[index]!=FILESEPARATOR)&& + (pathname[index]!=FILESEPARATOR2)) index--; + + if (index>=0){ + result = (char*)JS_malloc(cx, index+4); + if (!result) return NULL; +#if defined(XP_WIN) || defined(XP_OS2) + if (drive!='\0') { + result[0] = toupper(drive); + result[1] = ':'; + strncpy(&result[2], pathname, index); + result[index+3] = '\0'; + }else +#endif + { + strncpy(result, pathname, index); + result[index] = '\0'; + } + + /* add terminating separator */ + index = strlen(result)-1; + result[index] = FILESEPARATOR; + result[index+1] = '\0'; + } else{ +#if defined(XP_WIN) || defined(XP_OS2) + result = JS_strdup(cx, oldpathname); /* may include drive selector */ +#else + result = JS_strdup(cx, pathname); +#endif + } + + return result; +} + +static char * +js_absolutePath(JSContext *cx, const char * path) +{ + JSObject *obj; + JSString *str; + jsval prop; + + if (js_isAbsolute(path)){ + return JS_strdup(cx, path); + }else{ + obj = JS_GetGlobalObject(cx); + if (!JS_GetProperty(cx, obj, FILE_CONSTRUCTOR, &prop)) { + JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL, + JSFILEMSG_FILE_CONSTRUCTOR_UNDEFINED_ERROR); + return JS_strdup(cx, path); + } + obj = JSVAL_TO_OBJECT(prop); + if (!JS_GetProperty(cx, obj, CURRENTDIR_PROPERTY, &prop)) { + JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL, + JSFILEMSG_FILE_CURRENTDIR_UNDEFINED_ERROR); + return JS_strdup(cx, path); + } + str = JS_ValueToString(cx, prop); + if (!str ) { + return JS_strdup(cx, path); + } + /* should we have an array of curr dirs indexed by drive for windows? */ + return js_combinePath(cx, JS_GetStringBytes(str), path); + } +} + +/* Side effect: will remove spaces in the beginning/end of the filename */ +static char * +js_canonicalPath(JSContext *cx, char *oldpath) +{ + char *tmp; + char *path = oldpath; + char *base, *dir, *current, *result; + jsint c; + jsint back = 0; + unsigned int i = 0, j = strlen(path)-1; + + /* This is probably optional */ + /* Remove possible spaces in the beginning and end */ + while(i=0 && path[j]==' ') j--; + + tmp = JS_malloc(cx, j-i+2); + strncpy(tmp, &path[i], j-i+1); + tmp[j-i+1] = '\0'; + + path = tmp; + + /* pipe support */ + if(js_filenameHasAPipe(path)) + return JS_strdup(cx, path); + /* file:// support */ + if(!strncmp(path, URL_PREFIX, strlen(URL_PREFIX))) + return js_canonicalPath(cx, &path[strlen(URL_PREFIX)-1]); + + if (!js_isAbsolute(path)) + path = js_absolutePath(cx, path); + else + path = JS_strdup(cx, path); + + result = JS_strdup(cx, ""); + + current = path; + + base = js_fileBaseName(cx, current); + dir = js_fileDirectoryName(cx, current); + + /* TODO: MAC -- not going to work??? */ + while (strcmp(dir, current)) { + if (!strcmp(base, "..")) { + back++; + } else + if(!strcmp(base, ".")){ + /* ??? */ + } else { + if (back>0) + back--; + else { + tmp = result; + result = JS_malloc(cx, strlen(base)+1+strlen(tmp)+1); + if (!result) { + JS_free(cx, dir); + JS_free(cx, base); + JS_free(cx, current); + return NULL; + } + strcpy(result, base); + c = strlen(result); + if (*tmp) { + result[c] = FILESEPARATOR; + result[c+1] = '\0'; + strcat(result, tmp); + } + JS_free(cx, tmp); + } + } + JS_free(cx, current); + JS_free(cx, base); + current = dir; + base = js_fileBaseName(cx, current); + dir = js_fileDirectoryName(cx, current); + } + + tmp = result; + result = JS_malloc(cx, strlen(dir)+1+strlen(tmp)+1); + if (!result) { + JS_free(cx, dir); + JS_free(cx, base); + JS_free(cx, current); + return NULL; + } + strcpy(result, dir); + c = strlen(result); + if (tmp[0]!='\0') { + if ((result[c-1]!=FILESEPARATOR)&&(result[c-1]!=FILESEPARATOR2)) { + result[c] = FILESEPARATOR; + result[c+1] = '\0'; + } + strcat(result, tmp); + } + JS_free(cx, tmp); + JS_free(cx, dir); + JS_free(cx, base); + JS_free(cx, current); + + return result; +} + +/* -------------------------- Text conversion ------------------------------- */ +/* The following is ripped from libi18n/unicvt.c and include files.. */ + +/* + * UTF8 defines and macros + */ +#define ONE_OCTET_BASE 0x00 /* 0xxxxxxx */ +#define ONE_OCTET_MASK 0x7F /* x1111111 */ +#define CONTINUING_OCTET_BASE 0x80 /* 10xxxxxx */ +#define CONTINUING_OCTET_MASK 0x3F /* 00111111 */ +#define TWO_OCTET_BASE 0xC0 /* 110xxxxx */ +#define TWO_OCTET_MASK 0x1F /* 00011111 */ +#define THREE_OCTET_BASE 0xE0 /* 1110xxxx */ +#define THREE_OCTET_MASK 0x0F /* 00001111 */ +#define FOUR_OCTET_BASE 0xF0 /* 11110xxx */ +#define FOUR_OCTET_MASK 0x07 /* 00000111 */ +#define FIVE_OCTET_BASE 0xF8 /* 111110xx */ +#define FIVE_OCTET_MASK 0x03 /* 00000011 */ +#define SIX_OCTET_BASE 0xFC /* 1111110x */ +#define SIX_OCTET_MASK 0x01 /* 00000001 */ + +#define IS_UTF8_1ST_OF_1(x) (( (x)&~ONE_OCTET_MASK ) == ONE_OCTET_BASE) +#define IS_UTF8_1ST_OF_2(x) (( (x)&~TWO_OCTET_MASK ) == TWO_OCTET_BASE) +#define IS_UTF8_1ST_OF_3(x) (( (x)&~THREE_OCTET_MASK) == THREE_OCTET_BASE) +#define IS_UTF8_1ST_OF_4(x) (( (x)&~FOUR_OCTET_MASK ) == FOUR_OCTET_BASE) +#define IS_UTF8_1ST_OF_5(x) (( (x)&~FIVE_OCTET_MASK ) == FIVE_OCTET_BASE) +#define IS_UTF8_1ST_OF_6(x) (( (x)&~SIX_OCTET_MASK ) == SIX_OCTET_BASE) +#define IS_UTF8_2ND_THRU_6TH(x) \ + (( (x)&~CONTINUING_OCTET_MASK ) == CONTINUING_OCTET_BASE) +#define IS_UTF8_1ST_OF_UCS2(x) \ + IS_UTF8_1ST_OF_1(x) \ + || IS_UTF8_1ST_OF_2(x) \ + || IS_UTF8_1ST_OF_3(x) + + +#define MAX_UCS2 0xFFFF +#define DEFAULT_CHAR 0x003F /* Default char is "?" */ +#define BYTE_MASK 0xBF +#define BYTE_MARK 0x80 + + +/* Function: one_ucs2_to_utf8_char + * + * Function takes one UCS-2 char and writes it to a UTF-8 buffer. + * We need a UTF-8 buffer because we don't know before this + * function how many bytes of utf-8 data will be written. It also + * takes a pointer to the end of the UTF-8 buffer so that we don't + * overwrite data. This function returns the number of UTF-8 bytes + * of data written, or -1 if the buffer would have been overrun. + */ + +#define LINE_SEPARATOR 0x2028 +#define PARAGRAPH_SEPARATOR 0x2029 +static int16 one_ucs2_to_utf8_char(unsigned char *tobufp, + unsigned char *tobufendp, uint16 onechar) +{ + + int16 numUTF8bytes = 0; + + if((onechar == LINE_SEPARATOR)||(onechar == PARAGRAPH_SEPARATOR)) + { + strcpy((char*)tobufp, "\n"); + return strlen((char*)tobufp);; + } + + if (onechar < 0x80) { numUTF8bytes = 1; + } else if (onechar < 0x800) { numUTF8bytes = 2; + } else if (onechar <= MAX_UCS2) { numUTF8bytes = 3; + } else { numUTF8bytes = 2; + onechar = DEFAULT_CHAR; + } + + tobufp += numUTF8bytes; + + /* return error if we don't have space for the whole character */ + if (tobufp > tobufendp) { + return(-1); + } + + + switch(numUTF8bytes) { + + case 3: *--tobufp = (onechar | BYTE_MARK) & BYTE_MASK; onechar >>=6; + *--tobufp = (onechar | BYTE_MARK) & BYTE_MASK; onechar >>=6; + *--tobufp = onechar | THREE_OCTET_BASE; + break; + + case 2: *--tobufp = (onechar | BYTE_MARK) & BYTE_MASK; onechar >>=6; + *--tobufp = onechar | TWO_OCTET_BASE; + break; + case 1: *--tobufp = (unsigned char)onechar; break; + } + + return(numUTF8bytes); +} + +/* + * utf8_to_ucs2_char + * + * Convert a utf8 multibyte character to ucs2 + * + * inputs: pointer to utf8 character(s) + * length of utf8 buffer ("read" length limit) + * pointer to return ucs2 character + * + * outputs: number of bytes in the utf8 character + * -1 if not a valid utf8 character sequence + * -2 if the buffer is too short + */ +static int16 +utf8_to_ucs2_char(const unsigned char *utf8p, int16 buflen, uint16 *ucs2p) +{ + uint16 lead, cont1, cont2; + + /* + * Check for minimum buffer length + */ + if ((buflen < 1) || (utf8p == NULL)) { + return -2; + } + lead = (uint16) (*utf8p); + + /* + * Check for a one octet sequence + */ + if (IS_UTF8_1ST_OF_1(lead)) { + *ucs2p = lead & ONE_OCTET_MASK; + return 1; + } + + /* + * Check for a two octet sequence + */ + if (IS_UTF8_1ST_OF_2(*utf8p)) { + if (buflen < 2) + return -2; + cont1 = (uint16) *(utf8p+1); + if (!IS_UTF8_2ND_THRU_6TH(cont1)) + return -1; + *ucs2p = (lead & TWO_OCTET_MASK) << 6; + *ucs2p |= cont1 & CONTINUING_OCTET_MASK; + return 2; + } + + /* + * Check for a three octet sequence + */ + else if (IS_UTF8_1ST_OF_3(lead)) { + if (buflen < 3) + return -2; + cont1 = (uint16) *(utf8p+1); + cont2 = (uint16) *(utf8p+2); + if ( (!IS_UTF8_2ND_THRU_6TH(cont1)) + || (!IS_UTF8_2ND_THRU_6TH(cont2))) + return -1; + *ucs2p = (lead & THREE_OCTET_MASK) << 12; + *ucs2p |= (cont1 & CONTINUING_OCTET_MASK) << 6; + *ucs2p |= cont2 & CONTINUING_OCTET_MASK; + return 3; + } + else { /* not a valid utf8/ucs2 character */ + return -1; + } +} + +/* ----------------------------- Helper functions --------------------------- */ +/* Ripped off from lm_win.c .. */ +/* where is strcasecmp?.. for now, it's case sensitive.. + * + * strcasecmp is in strings.h, but on windows it's called _stricmp... + * will need to #ifdef this +*/ + +static int32 +js_FileHasOption(JSContext *cx, const char *oldoptions, const char *name) +{ + char *comma, *equal, *current; + char *options = JS_strdup(cx, oldoptions); + int32 found = 0; + + current = options; + for (;;) { + comma = strchr(current, ','); + if (comma) *comma = '\0'; + equal = strchr(current, '='); + if (equal) *equal = '\0'; + if (strcmp(current, name) == 0) { + if (!equal || strcmp(equal + 1, "yes") == 0) + found = 1; + else + found = atoi(equal + 1); + } + if (equal) *equal = '='; + if (comma) *comma = ','; + if (found || !comma) + break; + current = comma + 1; + } + JS_free(cx, options); + return found; +} + +/* empty the buffer */ +static void +js_ResetBuffers(JSFile * file) +{ + file->charBufferUsed = JS_FALSE; + file->nbBytesInBuf = 0; + file->linebuffer = NULL; /* TODO: check for mem. leak? */ +} + +/* Reset file attributes */ +static void +js_ResetAttributes(JSFile * file){ + file->mode = file->type = 0; + file->isOpen = JS_FALSE; + file->handle = NULL; + file->nativehandle = NULL; + file->hasRandomAccess = JS_TRUE; /* innocent until proven guilty */ + file->hasAutoflush = JS_FALSE; + file->isNative = JS_FALSE; + file->isPipe = JS_FALSE; + + js_ResetBuffers(file); +} + +static JSBool +js_FileOpen(JSContext *cx, JSObject *obj, JSFile *file, char *mode){ + JSString *type, *mask; + jsval v[2]; + jsval rval; + + type = JS_InternString(cx, asciistring); + mask = JS_NewStringCopyZ(cx, mode); + v[0] = STRING_TO_JSVAL(mask); + v[1] = STRING_TO_JSVAL(type); + + if (!file_open(cx, obj, 2, v, &rval)) { + return JS_FALSE; + } + return JS_TRUE; +} + +/* Buffered version of PR_Read. Used by js_FileRead */ +static int32 +js_BufferedRead(JSFile * f, char *buf, int32 len) +{ + int32 count = 0; + + while (f->nbBytesInBuf>0&&len>0) { + buf[0] = f->byteBuffer[0]; + f->byteBuffer[0] = f->byteBuffer[1]; + f->byteBuffer[1] = f->byteBuffer[2]; + f->nbBytesInBuf--; + len--; + buf+=1; + count++; + } + + if (len>0) { + count+= (!f->isNative)? + PR_Read(f->handle, buf, len): + fread(buf, 1, len, f->nativehandle); + } + return count; +} + +static int32 +js_FileRead(JSContext *cx, JSFile * file, jschar*buf, int32 len, int32 mode) +{ + unsigned char*aux; + int32 count, i; + jsint remainder; + unsigned char utfbuf[3]; + + if (file->charBufferUsed) { + buf[0] = file->charBuffer; + buf++; + len--; + file->charBufferUsed = JS_FALSE; + } + + switch (mode) { + case ASCII: + aux = (unsigned char*)JS_malloc(cx, len); + if (!aux) { + return 0; + } + count = js_BufferedRead(file, aux, len); + if (count==-1) { + JS_free(cx, aux); + return 0; + } + for (i = 0;i0) { + file->byteBuffer[file->nbBytesInBuf] = utfbuf[0]; + file->nbBytesInBuf++; + utfbuf[0] = utfbuf[1]; + utfbuf[1] = utfbuf[2]; + remainder--; + } + break; + case UCS2: + count = js_BufferedRead(file, (char*)buf, len*2)>>1; + if (count==-1) { + return 0; + } + break; + } + + if(count==-1){ + JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL, + JSFILEMSG_OP_FAILED, "read", file->path); + } + + return count; +} + +static int32 +js_FileSeek(JSContext *cx, JSFile *file, int32 len, int32 mode) +{ + int32 count, i; + jsint remainder; + unsigned char utfbuf[3]; + jschar tmp; + + switch (mode) { + case ASCII: + count = PR_Seek(file->handle, len, PR_SEEK_CUR); + break; + case UTF8: + remainder = 0; + for (count = 0;count0) { + file->byteBuffer[file->nbBytesInBuf] = utfbuf[0]; + file->nbBytesInBuf++; + utfbuf[0] = utfbuf[1]; + utfbuf[1] = utfbuf[2]; + remainder--; + } + break; + case UCS2: + count = PR_Seek(file->handle, len*2, PR_SEEK_CUR)/2; + break; + } + + if(count==-1){ + JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL, + JSFILEMSG_OP_FAILED, "seek", file->path); + } + + return count; +} + +static int32 +js_FileWrite(JSContext *cx, JSFile *file, jschar *buf, int32 len, int32 mode) +{ + unsigned char *aux; + int32 count, i, j; + unsigned char *utfbuf; + + switch (mode) { + case ASCII: + aux = (unsigned char*)JS_malloc(cx, len); + if (!aux) return 0; + + for (i = 0; iisNative)? + PR_Write(file->handle, aux, len): + fwrite(aux, 1, len, file->nativehandle); + + if (count==-1) { + JS_free(cx, aux); + return 0; + } + JS_free(cx, aux); + break; + case UTF8: + utfbuf = (unsigned char*)JS_malloc(cx, len*3); + if (!utfbuf) return 0; + i = 0; + for (count = 0;countisNative)? + PR_Write(file->handle, utfbuf, i): + fwrite(utfbuf, 1, i, file->nativehandle); + + if (jisNative)? + PR_Write(file->handle, buf, len*2)>>1: + fwrite(buf, 1, len*2, file->nativehandle)>>1; + + if (count==-1) { + return 0; + } + break; + } + if(count==-1){ + JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL, + JSFILEMSG_OP_FAILED, "write", file->path); + } + return count; +} + +/* ----------------------------- Property checkers -------------------------- */ +static JSBool +js_exists(JSContext *cx, JSFile *file) +{ + if(!file->isNative){ + return (PR_Access(file->path, PR_ACCESS_EXISTS)==PR_SUCCESS); + }else{ + /* doesn't make sense for a pipe of stdstream */ + return JS_FALSE; + } +} + +static JSBool +js_canRead(JSContext *cx, JSFile *file) +{ + if(!file->isNative){ + if(file->isOpen&&!(file->mode&PR_RDONLY)) return JS_FALSE; + return (PR_Access(file->path, PR_ACCESS_READ_OK)==PR_SUCCESS); + }else{ + if(file->isPipe){ + /* pipe open for reading */ + return file->path[0]==PIPE_SYMBOL; + }else{ + return !strcmp(file->path, STDINPUT_NAME); + } + } +} + +static JSBool +js_canWrite(JSContext *cx, JSFile *file) +{ + if(!file->isNative){ + if(file->isOpen&&!(file->mode&PR_WRONLY)) return JS_FALSE; + return (PR_Access(file->path, PR_ACCESS_WRITE_OK)==PR_SUCCESS); + }else{ + if(file->isPipe){ + /* pipe open for writing */ + return file->path[strlen(file->path)-1]==PIPE_SYMBOL; + }else{ + return !strcmp(file->path, STDOUTPUT_NAME) || + !strcmp(file->path, STDERROR_NAME); + } + } +} + +static JSBool +js_isFile(JSContext *cx, JSFile *file) +{ + if(!file->isNative){ + PRFileInfo info; + + if ((file->isOpen)? + PR_GetOpenFileInfo(file->handle, &info): + PR_GetFileInfo(file->path, &info)!=PR_SUCCESS){ + JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL, + JSFILEMSG_CANNOT_ACCESS_FILE_STATUS, file->path); + return JS_FALSE; + }else + return (info.type==PR_FILE_FILE); + }else{ + /* doesn't make sense for a pipe of stdstream */ + return JS_FALSE; + } +} + +static JSBool +js_isDirectory(JSContext *cx, JSFile *file) +{ + if(!file->isNative){ + PRFileInfo info; + + /* hack needed to get get_property to work */ + if(!js_exists(cx, file)) return JS_FALSE; + + if ((file->isOpen)? + PR_GetOpenFileInfo(file->handle, &info): + PR_GetFileInfo(file->path, &info)!=PR_SUCCESS){ + JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL, + JSFILEMSG_CANNOT_ACCESS_FILE_STATUS, file->path); + return JS_FALSE; + }else + return (info.type==PR_FILE_DIRECTORY); + }else{ + /* doesn't make sense for a pipe of stdstream */ + return JS_FALSE; + } +} + +static jsval +js_size(JSContext *cx, JSFile *file) +{ + PRFileInfo info; + + JSFILE_CHECK_NATIVE("size"); + + if ((file->isOpen)? + PR_GetOpenFileInfo(file->handle, &info): + PR_GetFileInfo(file->path, &info)!=PR_SUCCESS){ + JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL, + JSFILEMSG_CANNOT_ACCESS_FILE_STATUS, file->path); + goto out; + }else + return INT_TO_JSVAL(info.size); +out: + return JSVAL_VOID; +} + +/* Return the parent object */ +static jsval +js_parent(JSContext *cx, JSFile *file) +{ + char *str; + + /* since we only care about pipes and native files, return NULL */ + if(file->isNative) return JSVAL_VOID; + + str = js_fileDirectoryName(cx, file->path); + /* root.parent = null ??? */ + if(!strcmp(file->path, str) || + (!strncmp(str, file->path, strlen(str)-1)&& + file->path[strlen(file->path)]-1)==FILESEPARATOR){ + return JSVAL_NULL; + }else{ + return OBJECT_TO_JSVAL(js_NewFileObject(cx, str)); + JS_free(cx, str); + } +} + +static jsval +js_name(JSContext *cx, JSFile *file){ + return file->isPipe? + JSVAL_VOID: + STRING_TO_JSVAL(JS_NewStringCopyZ(cx, js_fileBaseName(cx, file->path))); +} + +/* ------------------------------ File object methods ---------------------------- */ +static JSBool +file_open(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + JSFile *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL); + JSString *strmode, *strtype; + char *ctype, *mode; + int32 mask, type; + int len; + + SECURITY_CHECK(cx, NULL, "open", file); + + /* A native file that is already open */ + if(file->isOpen && file->isNative){ + JS_ReportWarning(cx, "Native file %s is already open, proceeding", + file->path); + goto good; + } + + /* Close before proceeding */ + if (file->isOpen) { + JS_ReportWarning(cx, + "File %s is already open, we will close it and reopen, proceeding", + file->path); + if(!file_close(cx, obj, 0, NULL, rval)) goto out; + } + + if(js_isDirectory(cx, file)){ + JS_ReportWarning(cx, "%s seems to be a directory, there is no point in " + "trying to open it, proceeding", file->path); + goto good; + } + + /* Path must be defined at this point */ + len = strlen(file->path); + + /* Mode */ + if (argc>=1){ + strmode = JS_ValueToString(cx, argv[0]); + if (!strmode){ + JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL, + JSFILEMSG_FIRST_ARGUMENT_OPEN_NOT_STRING_ERROR, argv[0]); + goto out; + } + mode = JS_strdup(cx, JS_GetStringBytes(strmode)); + }else{ + if(file->path[0]==PIPE_SYMBOL){ + /* pipe default mode */ + mode = JS_strdup(cx, "read"); + }else + if(file->path[len-1]==PIPE_SYMBOL){ + /* pipe default mode */ + mode = JS_strdup(cx, "write"); + }else{ + /* non-destructive, permissive defaults. */ + mode = JS_strdup(cx, "readWrite,append,create"); + } + } + + /* Process the mode */ + mask = 0; + /* TODO: this is pretty ugly, BTW, we walk thru the string too many times */ + mask|=(js_FileHasOption(cx, mode, "read"))? PR_RDONLY : 0; + mask|=(js_FileHasOption(cx, mode, "write"))? PR_WRONLY : 0; + mask|=(js_FileHasOption(cx, mode, "readWrite"))? PR_RDWR : 0; + mask|=(js_FileHasOption(cx, mode, "append"))? PR_APPEND : 0; + mask|=(js_FileHasOption(cx, mode, "create"))? PR_CREATE_FILE : 0; + mask|=(js_FileHasOption(cx, mode, "replace"))? PR_TRUNCATE : 0; + + if((mask&PR_RDWR)) mask|=(PR_RDONLY|PR_WRONLY); + if((mask&PR_RDONLY)&&(mask&PR_WRONLY)) mask|=PR_RDWR; + + file->hasAutoflush|=(js_FileHasOption(cx, mode, "autoflush")); + + /* Type */ + if (argc>1) { + strtype = JS_ValueToString(cx, argv[1]); + if (!strtype) { + JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL, + JSFILEMSG_SECOND_ARGUMENT_OPEN_NOT_STRING_ERROR, argv[1]); + goto out; + } + ctype = JS_GetStringBytes(strtype); + + if(!strcmp(ctype, utfstring)) + type = UTF8; + else + if (!strcmp(ctype, unicodestring)) + type = UCS2; + else{ + if(strcmp(ctype, asciistring)){ + JS_ReportWarning(cx, "File type %s is not supported, using " + "'text' instead, proceeding", ctype); + } + type = ASCII; + } + }else{ + type = ASCII; + } + + /* Save the relevant fields */ + file->type = type; + file->mode = mask; + file->nativehandle = NULL; + file->hasRandomAccess = (type!=UTF8); + + /* + Deal with pipes here. We can't use NSPR for pipes, + so we have to use POPEN. + */ + if(file->path[0]==PIPE_SYMBOL || file->path[len-1]==PIPE_SYMBOL){ + if(file->path[0]==PIPE_SYMBOL && file->path[len-1]==PIPE_SYMBOL){ + JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL, + JSFILEMSG_BIDIRECTIONAL_PIPE_NOT_SUPPORTED); + goto out; + }else{ + char pipemode[3]; + SECURITY_CHECK(cx, NULL, "pipe_open", file); + + if(file->path[0] == PIPE_SYMBOL){ + if(mask & (PR_WRONLY | PR_APPEND | PR_CREATE_FILE | PR_TRUNCATE)){ + JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL, + JSFILEMSG_OPEN_MODE_NOT_SUPPORTED_WITH_PIPES, + mode, file->path); + goto out; + } + /* open(SPOOLER, "| cat -v | lpr -h 2>/dev/null") -- pipe for writing */ + pipemode[0] = 'r'; + pipemode[1] = file->type==UTF8?'b':'t'; + pipemode[2] = '\0'; + file->nativehandle = POPEN(&file->path[1], pipemode); + }else + if(file->path[len-1] == PIPE_SYMBOL){ + char *command = JS_malloc(cx, len); + + strncpy(command, file->path, len-1); + command[len-1] = '\0'; + /* open(STATUS, "netstat -an 2>&1 |") */ + pipemode[0] = 'w'; + pipemode[1] = file->type==UTF8?'b':'t'; + pipemode[2] = '\0'; + file->nativehandle = POPEN(command, pipemode); + JS_free(cx, command); + } + /* set the flags */ + file->isNative = JS_TRUE; + file->isPipe = JS_TRUE; + file->hasRandomAccess = JS_FALSE; + } + }else{ + /* TODO: what about the permissions?? Java ignores the problem... */ + file->handle = PR_Open(file->path, mask, 0644); + } + + js_ResetBuffers(file); + JS_free(cx, mode); + mode = NULL; + + /* Set the open flag and return result */ + if (file->handle==NULL && file->nativehandle==NULL){ + file->isOpen = JS_FALSE; + + JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL, + JSFILEMSG_OP_FAILED, "open", file->path); + goto out; + }else + goto good; +good: + file->isOpen = JS_TRUE; + *rval = JSVAL_TRUE; + return JS_TRUE; +out: + if(mode) JS_free(cx, mode); + *rval = JSVAL_VOID; + return JS_FALSE; +} + +static JSBool +file_close(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + JSFile *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL); + + SECURITY_CHECK(cx, NULL, "close", file); + + if(!file->isOpen){ + JS_ReportWarning(cx, "File %s is not open, can't close it, proceeding", + file->path); + goto out; + } + + if(!file->isPipe){ + if(file->isNative){ + JS_ReportWarning(cx, "Unable to close a native file, proceeding", file->path); + goto out; + }else{ + if(file->handle && PR_Close(file->handle)){ + JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL, + JSFILEMSG_OP_FAILED, "close", file->path); + + goto out; + } + } + }else{ + if(PCLOSE(file->nativehandle)==-1){ + JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL, + JSFILEMSG_OP_FAILED, "pclose", file->path); + goto out; + } + } + + js_ResetAttributes(file); + *rval = JSVAL_TRUE; + return JS_TRUE; +out: + *rval = JSVAL_FALSE; + return JS_FALSE; +} + + +static JSBool +file_remove(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + JSFile *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL); + + SECURITY_CHECK(cx, NULL, "remove", file); + JSFILE_CHECK_NATIVE("remove"); + JSFILE_CHECK_CLOSED("remove"); + + if ((js_isDirectory(cx, file) ? + PR_RmDir(file->path) : PR_Delete(file->path))==PR_SUCCESS) { + js_ResetAttributes(file); + *rval = JSVAL_TRUE; + return JS_TRUE; + } else { + JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL, + JSFILEMSG_OP_FAILED, "remove", file->path); + goto out; + } +out: + *rval = JSVAL_FALSE; + return JS_FALSE; +} + +/* Raw PR-based function. No text processing. Just raw data copying. */ +static JSBool +file_copyTo(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + JSFile *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL); + char *dest = NULL; + PRFileDesc *handle = NULL; + char *buffer; + jsval count, size; + JSBool fileInitiallyOpen=JS_FALSE; + + SECURITY_CHECK(cx, NULL, "copyTo", file); /* may need a second argument!*/ + JSFILE_CHECK_ONE_ARG("copyTo"); + JSFILE_CHECK_NATIVE("copyTo"); + /* remeber the state */ + fileInitiallyOpen = file->isOpen; + JSFILE_CHECK_READ; + + dest = JS_GetStringBytes(JS_ValueToString(cx, argv[0])); + + /* make sure we are not reading a file open for writing */ + if (file->isOpen && !js_canRead(cx, file)) { + JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL, + JSFILEMSG_CANNOT_COPY_FILE_OPEN_FOR_WRITING_ERROR, file->path); + goto out; + } + + if (file->handle==NULL){ + JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL, + JSFILEMSG_OP_FAILED, "open", file->path); + goto out; + } + + handle = PR_Open(dest, PR_WRONLY|PR_CREATE_FILE|PR_TRUNCATE, 0644); + + if(!handle){ + JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL, + JSFILEMSG_OP_FAILED, "open", dest); + goto out; + } + + if ((size=js_size(cx, file))==JSVAL_VOID) { + goto out; + } + + buffer = JS_malloc(cx, size); + + count = INT_TO_JSVAL(PR_Read(file->handle, buffer, size)); + + /* reading panic */ + if (count!=size) { + JS_free(cx, buffer); + JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL, + JSFILEMSG_COPY_READ_ERROR, file->path); + goto out; + } + + count = INT_TO_JSVAL(PR_Write(handle, buffer, JSVAL_TO_INT(size))); + + /* writing panic */ + if (count!=size) { + JS_free(cx, buffer); + JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL, + JSFILEMSG_COPY_WRITE_ERROR, file->path); + goto out; + } + + JS_free(cx, buffer); + + if(!fileInitiallyOpen){ + if(!file_close(cx, obj, 0, NULL, rval)) goto out; + } + + if(PR_Close(handle)!=PR_SUCCESS){ + JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL, + JSFILEMSG_OP_FAILED, "close", dest); + goto out; + } + + *rval = JSVAL_TRUE; + return JS_TRUE; +out: + if(file->isOpen && !fileInitiallyOpen){ + if(PR_Close(file->handle)!=PR_SUCCESS){ + JS_ReportWarning(cx, "Can't close %s, proceeding", file->path); + } + } + + if(handle && PR_Close(handle)!=PR_SUCCESS){ + JS_ReportWarning(cx, "Can't close %s, proceeding", dest); + } + + *rval = JSVAL_FALSE; + return JS_FALSE; +} + +static JSBool +file_renameTo(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + JSFile *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL); + char *dest; + + SECURITY_CHECK(cx, NULL, "renameTo", file); /* may need a second argument!*/ + JSFILE_CHECK_ONE_ARG("renameTo"); + JSFILE_CHECK_NATIVE("renameTo"); + JSFILE_CHECK_CLOSED("renameTo"); + + dest = RESOLVE_PATH(cx, JS_GetStringBytes(JS_ValueToString(cx, argv[0]))); + + if (PR_Rename(file->path, dest)==PR_SUCCESS){ + /* copy the new filename */ + JS_free(cx, file->path); + file->path = dest; + *rval = JSVAL_TRUE; + return JS_TRUE; + }else{ + JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL, + JSFILEMSG_RENAME_FAILED, file->path, dest); + goto out; + } +out: + *rval = JSVAL_FALSE; + return JS_FALSE; +} + +static JSBool +file_flush(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + JSFile *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL); + + SECURITY_CHECK(cx, NULL, "flush", file); + JSFILE_CHECK_NATIVE("flush"); + JSFILE_CHECK_OPEN("flush"); + + if (PR_Sync(file->handle)==PR_SUCCESS){ + *rval = JSVAL_TRUE; + return JS_TRUE; + }else{ + JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL, + JSFILEMSG_OP_FAILED, "flush", file->path); + goto out; + } +out: + *rval = JSVAL_FALSE; + return JS_FALSE; +} + +static JSBool +file_write(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + JSFile *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL); + JSString *str; + int32 count; + uintN i; + + SECURITY_CHECK(cx, NULL, "write", file); + JSFILE_CHECK_WRITE; + + for (i = 0; itype); + if (count==-1){ + *rval = JSVAL_FALSE; + return JS_FALSE; + } + } + + *rval = JSVAL_TRUE; + return JS_TRUE; +out: + *rval = JSVAL_FALSE; + return JS_FALSE; +} + +static JSBool +file_writeln(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + JSFile *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL); + JSString *str; + + SECURITY_CHECK(cx, NULL, "writeln", file); + JSFILE_CHECK_WRITE; + + /* don't report an error here */ + if(!file_write(cx, obj, argc, argv, rval)) return JS_FALSE; + /* don't do security here -- we passed the check in file_write */ + str = JS_NewStringCopyZ(cx, "\n"); + + if (js_FileWrite(cx, file, JS_GetStringChars(str), JS_GetStringLength(str), + file->type)==-1){ + *rval = JSVAL_FALSE; + return JS_FALSE; + } + + /* eol causes flush if hasAutoflush is turned on */ + if (file->hasAutoflush) + file_flush(cx, obj, 0, NULL, rval); + + *rval = JSVAL_TRUE; + return JS_TRUE; +out: + *rval = JSVAL_FALSE; + return JS_FALSE; +} + +static JSBool +file_writeAll(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + JSFile *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL); + jsuint i; + jsuint limit; + JSObject *array; + JSObject *elem; + jsval elemval; + + SECURITY_CHECK(cx, NULL, "writeAll", file); + JSFILE_CHECK_ONE_ARG("writeAll"); + JSFILE_CHECK_WRITE; + + if (!JS_IsArrayObject(cx, JSVAL_TO_OBJECT(argv[0]))) { + JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL, + JSFILEMSG_FIRST_ARGUMENT_WRITEALL_NOT_ARRAY_ERROR); + goto out; + } + + array = JSVAL_TO_OBJECT(argv[0]); + + JS_GetArrayLength(cx, array, &limit); + + for (i = 0; i262144)?262144:want; * arbitrary size limitation */ + + buf = JS_malloc(cx, want*sizeof buf[0]); + if (!buf) goto out; + + count = js_FileRead(cx, file, buf, want, file->type); + if (count>0) { + str = JS_NewUCStringCopyN(cx, buf, count); + *rval = STRING_TO_JSVAL(str); + JS_free(cx, buf); + return JS_TRUE; + } else { + JS_free(cx, buf); + goto out; + } +out: + *rval = JSVAL_FALSE; + return JS_FALSE; +} + +static JSBool +file_readln(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + JSFile *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL); + JSString *str; + jschar *buf; + int32 offset; + intN room; + jschar data, data2; + JSBool endofline; + + SECURITY_CHECK(cx, NULL, "readln", file); + JSFILE_CHECK_READ; + + if (!file->linebuffer) { + buf = JS_malloc(cx, MAX_LINE_LENGTH*(sizeof data)); + if (!buf) goto out; + file->linebuffer = JS_NewUCString(cx, buf, MAX_LINE_LENGTH); + } + room = JS_GetStringLength(file->linebuffer); + offset = 0; + + /* XXX TEST ME!! TODO: yes, please do */ + for(;;) { + if (!js_FileRead(cx, file, &data, 1, file->type)) { + endofline = JS_FALSE; + goto loop; + } + switch (data) { + case '\n' : + endofline = JS_TRUE; + goto loop; + case '\r' : + if (!js_FileRead(cx, file, &data2, 1, file->type)) { + endofline = JS_TRUE; + goto loop; + } + if (data2!='\n') { /* We read one char too far. Buffer it. */ + file->charBuffer = data2; + file->charBufferUsed = JS_TRUE; + } + endofline = JS_TRUE; + goto loop; + default: + if (--room < 0) { + buf = JS_malloc(cx, (offset+MAX_LINE_LENGTH)*sizeof data); + if (!buf) return JS_FALSE; + room = MAX_LINE_LENGTH-1; + memcpy(buf, JS_GetStringChars(file->linebuffer), + JS_GetStringLength(file->linebuffer)); + /* what follows may not be the cleanest way. */ + file->linebuffer->chars = buf; + file->linebuffer->length = offset+MAX_LINE_LENGTH; + } + file->linebuffer->chars[offset++] = data; + break; + } + } +loop: + file->linebuffer->chars[offset] = 0; + if ((endofline==JS_TRUE)) { + str = JS_NewUCStringCopyN(cx, JS_GetStringChars(file->linebuffer), + offset); + *rval = STRING_TO_JSVAL(str); + return JS_TRUE; + }else{ + goto out; + } +out: + *rval = JSVAL_NULL; + return JS_FALSE; +} + +static JSBool +file_readAll(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + JSFile *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL); + JSObject *array; + jsint len; + jsval line; + + SECURITY_CHECK(cx, NULL, "readAll", file); + JSFILE_CHECK_READ; + + array = JS_NewArrayObject(cx, 0, NULL); + len = 0; + + while(file_readln(cx, obj, 0, NULL, &line)){ + JS_SetElement(cx, array, len, &line); + len++; + } + + *rval = OBJECT_TO_JSVAL(array); + return JS_TRUE; +out: + *rval = JSVAL_FALSE; + return JS_FALSE; +} + +static JSBool +file_seek(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + JSFile *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL); + int32 toskip; + int32 pos; + + SECURITY_CHECK(cx, NULL, "seek", file); + JSFILE_CHECK_ONE_ARG("seek"); + JSFILE_CHECK_NATIVE("seek"); + JSFILE_CHECK_READ; + + if (!JS_ValueToInt32(cx, argv[0], &toskip)){ + JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL, + JSFILEMSG_FIRST_ARGUMENT_MUST_BE_A_NUMBER, "seek", argv[0]); + goto out; + } + + if(!file->hasRandomAccess){ + JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL, + JSFILEMSG_NO_RANDOM_ACCESS, file->path); + goto out; + } + + if(js_isDirectory(cx, file)){ + JS_ReportWarning(cx,"Seek on directories is not supported, proceeding"); + goto out; + } + + pos = js_FileSeek(cx, file, toskip, file->type); + + if (pos!=-1) { + *rval = INT_TO_JSVAL(pos); + return JS_TRUE; + } +out: + *rval = JSVAL_VOID; + return JS_FALSE; +} + +static JSBool +file_list(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + PRDir *dir; + PRDirEntry *entry; + JSFile *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL); + JSObject *array; + JSObject *eachFile; + jsint len; + jsval v; + JSRegExp *re = NULL; + JSFunction *func = NULL; + JSString *str; + jsval args[1]; + char *filePath; + + SECURITY_CHECK(cx, NULL, "list", file); + JSFILE_CHECK_NATIVE("list"); + + if (argc==1) { + if (JSVAL_IS_REGEXP(cx, argv[0])) { + re = JS_GetPrivate(cx, JSVAL_TO_OBJECT(argv[0])); + }else + if (JSVAL_IS_FUNCTION(cx, argv[0])) { + func = JS_GetPrivate(cx, JSVAL_TO_OBJECT(argv[0])); + }else{ + JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL, + JSFILEMSG_FIRST_ARGUMENT_MUST_BE_A_FUNCTION_OR_REGEX, argv[0]); + goto out; + } + } + + if (!js_isDirectory(cx, file)) { + JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL, + JSFILEMSG_CANNOT_DO_LIST_ON_A_FILE, file->path); + goto out; + } + + dir = PR_OpenDir(file->path); + if(!dir){ + JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL, + JSFILEMSG_OP_FAILED, "open", file->path); + goto out; + } + + /* create JSArray here... */ + array = JS_NewArrayObject(cx, 0, NULL); + len = 0; + + while ((entry = PR_ReadDir(dir, PR_SKIP_BOTH))!=NULL) { + /* first, check if we have a regexp */ + if (re!=NULL) { + size_t index = 0; + + str = JS_NewStringCopyZ(cx, entry->name); + if(!js_ExecuteRegExp(cx, re, str, &index, JS_TRUE, &v)){ + /* don't report anything here */ + goto out; + } + /* not matched! */ + if (JSVAL_IS_NULL(v)) { + continue; + } + }else + if (func!=NULL) { + str = JS_NewStringCopyZ(cx, entry->name); + args[0] = STRING_TO_JSVAL(str); + if(!JS_CallFunction(cx, obj, func, 1, args, &v)){ + goto out; + } + + if (v==JSVAL_FALSE) { + continue; + } + } + + filePath = js_combinePath(cx, file->path, (char*)entry->name); + + eachFile = js_NewFileObject(cx, filePath); + JS_free(cx, filePath); + if (!eachFile){ + JS_ReportWarning(cx, "File %s cannot be retrieved", filePath); + continue; + } + v = OBJECT_TO_JSVAL(eachFile); + JS_SetElement(cx, array, len, &v); + JS_SetProperty(cx, array, entry->name, &v); + len++; + } + + if(PR_CloseDir(dir)!=PR_SUCCESS){ + JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL, + JSFILEMSG_OP_FAILED, "close", file->path); + goto out; + } + *rval = OBJECT_TO_JSVAL(array); + return JS_TRUE; +out: + *rval = JSVAL_NULL; + return JS_FALSE; +} + +static JSBool +file_mkdir(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + JSFile *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL); + + SECURITY_CHECK(cx, NULL, "mkdir", file); + JSFILE_CHECK_ONE_ARG("mkdir"); + JSFILE_CHECK_NATIVE("mkdir"); + + /* if the current file is not a directory, find out the directory name */ + if (!js_isDirectory(cx, file)) { + char *dir = js_fileDirectoryName(cx, file->path); + JSObject *dirObj = js_NewFileObject(cx, dir); + + JS_free(cx, dir); + + /* call file_mkdir with the right set of parameters if needed */ + if (file_mkdir(cx, dirObj, argc, argv, rval)) + return JS_TRUE; + else + goto out; + }else{ + char *dirName = JS_GetStringBytes(JS_ValueToString(cx, argv[0])); + char *fullName; + + fullName = js_combinePath(cx, file->path, dirName); + if (PR_MkDir(fullName, 0755)==PR_SUCCESS){ + *rval = JSVAL_TRUE; + JS_free(cx, fullName); + return JS_TRUE; + }else{ + JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL, + JSFILEMSG_OP_FAILED, "mkdir", fullName); + JS_free(cx, fullName); + goto out; + } + } +out: + *rval = JSVAL_FALSE; + return JS_FALSE; +} + +static JSBool +file_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval*rval) +{ + JSFile *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL); + + *rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, file->path)); + return JS_TRUE; +} + +static JSBool +file_toURL(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + JSFile *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL); + char url[MAX_PATH_LENGTH]; + jschar *urlChars; + + JSFILE_CHECK_NATIVE("toURL"); + + sprintf(url, "file://%s", file->path); + /* TODO: js_escape in jsstr.h may go away at some point */ + + urlChars = js_InflateString(cx, url, strlen(url)); + if (urlChars == NULL) return JS_FALSE; + *rval = STRING_TO_JSVAL(js_NewString(cx, urlChars, strlen(url), 0)); + if (!js_str_escape(cx, obj, 0, rval, rval)) return JS_FALSE; + + return JS_TRUE; +out: + *rval = JSVAL_VOID; + return JS_FALSE; +} + + +static void +file_finalize(JSContext *cx, JSObject *obj) +{ + JSFile *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL); + + if(file){ + /* close the file before exiting */ + if(file->isOpen && !file->isNative){ + jsval vp; + file_close(cx, obj, 0, NULL, &vp); + } + + if (file->path) + JS_free(cx, file->path); + + JS_free(cx, file); + } +} + +/* + Allocates memory for the file object, sets fields to defaults. +*/ +static JSFile* +file_init(JSContext *cx, JSObject *obj, char *bytes) +{ + JSFile *file; + + file = JS_malloc(cx, sizeof *file); + if (!file) return NULL; + memset(file, 0 , sizeof *file); + + js_ResetAttributes(file); + + file->path = RESOLVE_PATH(cx, bytes); + + if (!JS_SetPrivate(cx, obj, file)) { + JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL, + JSFILEMSG_CANNOT_SET_PRIVATE_FILE, file->path); + JS_free(cx, file); + return NULL; + }else + return file; +} + +/* Returns a JSObject. This function is globally visible */ +JS_PUBLIC_API(JSObject*) +js_NewFileObject(JSContext *cx, char *filename) +{ + JSObject *obj; + JSFile *file; + + obj = JS_NewObject(cx, &file_class, NULL, NULL); + if (!obj){ + JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL, + JSFILEMSG_OBJECT_CREATION_FAILED, "js_NewFileObject"); + return NULL; + } + file = file_init(cx, obj, filename); + if(!file) return NULL; + return obj; +} + +/* Internal function, used for cases which NSPR file support doesn't cover */ +JSObject* +js_NewFileObjectFromFILE(JSContext *cx, FILE *nativehandle, char *filename, + int32 mode, JSBool open, JSBool randomAccess) +{ + JSObject *obj; + JSFile *file; +#ifdef XP_MAC + JS_ReportWarning(cx, "Native files are not fully supported on the MAC"); +#endif + + obj = JS_NewObject(cx, &file_class, NULL, NULL); + if (!obj){ + JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL, + JSFILEMSG_OBJECT_CREATION_FAILED, "js_NewFileObjectFromFILE"); + return NULL; + } + file = file_init(cx, obj, filename); + if(!file) return NULL; + + file->nativehandle = nativehandle; + + /* free result of RESOLVE_PATH from file_init. */ + JS_ASSERT(file->path != NULL); + JS_free(cx, file->path); + + file->path = strdup(filename); + file->isOpen = open; + file->mode = mode; + file->hasRandomAccess = randomAccess; + file->isNative = JS_TRUE; + return obj; +} + +/* + Real file constructor that is called from JavaScript. + Basically, does error processing and calls file_init. +*/ +static JSBool +file_constructor(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval) +{ + JSString *str; + JSFile *file; + + str = (argc==0)?JS_InternString(cx, ""):JS_ValueToString(cx, argv[0]); + + if (!str){ + JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL, + JSFILEMSG_FIRST_ARGUMENT_CONSTRUCTOR_NOT_STRING_ERROR, argv[0]); + goto out; + } + + file = file_init(cx, obj, JS_GetStringBytes(str)); + if (!file) goto out; + + SECURITY_CHECK(cx, NULL, "constructor", file); + + return JS_TRUE; +out: + *rval = JSVAL_VOID; + return JS_FALSE; +} + +/* -------------------- File methods and properties ------------------------- */ +static JSFunctionSpec file_functions[] = { + { "open", file_open, 0}, + { "close", file_close, 0}, + { "remove", file_remove, 0}, + { "copyTo", file_copyTo, 0}, + { "renameTo", file_renameTo, 0}, + { "flush", file_flush, 0}, + { "seek", file_seek, 0}, + { "read", file_read, 0}, + { "readln", file_readln, 0}, + { "readAll", file_readAll, 0}, + { "write", file_write, 0}, + { "writeln", file_writeln, 0}, + { "writeAll", file_writeAll, 0}, + { "list", file_list, 0}, + { "mkdir", file_mkdir, 0}, + { "toString", file_toString, 0}, + { "toURL", file_toURL, 0}, + {0} +}; + +enum file_tinyid { + FILE_LENGTH = -2, + FILE_PARENT = -3, + FILE_PATH = -4, + FILE_NAME = -5, + FILE_ISDIR = -6, + FILE_ISFILE = -7, + FILE_EXISTS = -8, + FILE_CANREAD = -9, + FILE_CANWRITE = -10, + FILE_OPEN = -11, + FILE_TYPE = -12, + FILE_MODE = -13, + FILE_CREATED = -14, + FILE_MODIFIED = -15, + FILE_SIZE = -16, + FILE_RANDOMACCESS = -17, + FILE_POSITION = -18, + FILE_APPEND = -19, + FILE_REPLACE = -20, + FILE_AUTOFLUSH = -21, + FILE_ISNATIVE = -22, +}; + +static JSPropertySpec file_props[] = { + {"length", FILE_LENGTH, JSPROP_ENUMERATE | JSPROP_READONLY }, + {"parent", FILE_PARENT, JSPROP_ENUMERATE | JSPROP_READONLY }, + {"path", FILE_PATH, JSPROP_ENUMERATE | JSPROP_READONLY }, + {"name", FILE_NAME, JSPROP_ENUMERATE | JSPROP_READONLY }, + {"isDirectory", FILE_ISDIR, JSPROP_ENUMERATE | JSPROP_READONLY }, + {"isFile", FILE_ISFILE, JSPROP_ENUMERATE | JSPROP_READONLY }, + {"exists", FILE_EXISTS, JSPROP_ENUMERATE | JSPROP_READONLY }, + {"canRead", FILE_CANREAD, JSPROP_ENUMERATE | JSPROP_READONLY }, + {"canWrite", FILE_CANWRITE, JSPROP_ENUMERATE | JSPROP_READONLY }, + {"canAppend", FILE_APPEND, JSPROP_ENUMERATE | JSPROP_READONLY }, + {"canReplace", FILE_REPLACE, JSPROP_ENUMERATE | JSPROP_READONLY }, + {"isOpen", FILE_OPEN, JSPROP_ENUMERATE | JSPROP_READONLY }, + {"type", FILE_TYPE, JSPROP_ENUMERATE | JSPROP_READONLY }, + {"mode", FILE_MODE, JSPROP_ENUMERATE | JSPROP_READONLY }, + {"creationTime", FILE_CREATED, JSPROP_ENUMERATE | JSPROP_READONLY }, + {"lastModified", FILE_MODIFIED, JSPROP_ENUMERATE | JSPROP_READONLY }, + {"size", FILE_SIZE, JSPROP_ENUMERATE | JSPROP_READONLY }, + {"hasRandomAccess", FILE_RANDOMACCESS, JSPROP_ENUMERATE | JSPROP_READONLY }, + {"hasAutoFlush", FILE_AUTOFLUSH, JSPROP_ENUMERATE | JSPROP_READONLY }, + {"position", FILE_POSITION, JSPROP_ENUMERATE }, + {"isNative", FILE_ISNATIVE, JSPROP_ENUMERATE | JSPROP_READONLY }, + {0} +}; + +/* ------------------------- Property getter/setter ------------------------- */ +static JSBool +file_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp) +{ + JSFile *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL); + char *str; + jsint tiny; + PRFileInfo info; + JSBool flag; + PRExplodedTime + expandedTime; + + tiny = JSVAL_TO_INT(id); + if(!file) return JS_TRUE; + + switch (tiny) { + case FILE_PARENT: + SECURITY_CHECK(cx, NULL, "parent", file); + *vp = js_parent(cx, file); + break; + case FILE_PATH: + *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, file->path)); + break; + case FILE_NAME: + *vp = js_name(cx, file); + break; + case FILE_ISDIR: + SECURITY_CHECK(cx, NULL, "isDirectory", file); + *vp = BOOLEAN_TO_JSVAL(js_isDirectory(cx, file)); + break; + case FILE_ISFILE: + SECURITY_CHECK(cx, NULL, "isFile", file); + *vp = BOOLEAN_TO_JSVAL(js_isFile(cx, file)); + break; + case FILE_EXISTS: + SECURITY_CHECK(cx, NULL, "exists", file); + *vp = BOOLEAN_TO_JSVAL(js_exists(cx, file)); + break; + case FILE_ISNATIVE: + SECURITY_CHECK(cx, NULL, "isNative", file); + *vp = BOOLEAN_TO_JSVAL(file->isNative); + break; + case FILE_CANREAD: + SECURITY_CHECK(cx, NULL, "canRead", file); + *vp = BOOLEAN_TO_JSVAL(js_canRead(cx, file)); + break; + case FILE_CANWRITE: + SECURITY_CHECK(cx, NULL, "canWrite", file); + *vp = BOOLEAN_TO_JSVAL(js_canWrite(cx, file)); + break; + case FILE_OPEN: + SECURITY_CHECK(cx, NULL, "isOpen", file); + *vp = BOOLEAN_TO_JSVAL(file->isOpen); + break; + case FILE_APPEND : + SECURITY_CHECK(cx, NULL, "canAppend", file); + JSFILE_CHECK_OPEN("canAppend"); + *vp = BOOLEAN_TO_JSVAL(!file->isNative && + (file->mode&PR_APPEND)==PR_APPEND); + break; + case FILE_REPLACE : + SECURITY_CHECK(cx, NULL, "canReplace", file); + JSFILE_CHECK_OPEN("canReplace"); + *vp = BOOLEAN_TO_JSVAL(!file->isNative && + (file->mode&PR_TRUNCATE)==PR_TRUNCATE); + break; + case FILE_AUTOFLUSH : + SECURITY_CHECK(cx, NULL, "hasAutoFlush", file); + JSFILE_CHECK_OPEN("hasAutoFlush"); + *vp = BOOLEAN_TO_JSVAL(!file->isNative && file->hasAutoflush); + break; + case FILE_TYPE: + SECURITY_CHECK(cx, NULL, "type", file); + JSFILE_CHECK_OPEN("type"); + if(js_isDirectory(cx, file)){ + *vp = JSVAL_VOID; + break; + } + + switch (file->type) { + case ASCII: + *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, asciistring)); + break; + case UTF8: + *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, utfstring)); + break; + case UCS2: + *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, unicodestring)); + break; + default: + JS_ReportWarning(cx, "Unsupported file type %d, proceeding", + file->type); + } + break; + case FILE_MODE: + SECURITY_CHECK(cx, NULL, "mode", file); + JSFILE_CHECK_OPEN("mode"); + str = (char*)JS_malloc(cx, MODE_SIZE); + str[0] = '\0'; + flag = JS_FALSE; + + if ((file->mode&PR_RDONLY)==PR_RDONLY) { + if (flag) strcat(str, ","); + strcat(str, "read"); + flag = JS_TRUE; + } + if ((file->mode&PR_WRONLY)==PR_WRONLY) { + if (flag) strcat(str, ","); + strcat(str, "write"); + flag = JS_TRUE; + } + if ((file->mode&PR_RDWR)==PR_RDWR) { + if (flag) strcat(str, ","); + strcat(str, "readWrite"); + flag = JS_TRUE; + } + if ((file->mode&PR_APPEND)==PR_APPEND) { + if (flag) strcat(str, ","); + strcat(str, "append"); + flag = JS_TRUE; + } + if ((file->mode&PR_CREATE_FILE)==PR_CREATE_FILE) { + if (flag) strcat(str, ","); + strcat(str, "create"); + flag = JS_TRUE; + } + if ((file->mode&PR_TRUNCATE)==PR_TRUNCATE) { + if (flag) strcat(str, ","); + strcat(str, "replace"); + flag = JS_TRUE; + } + if (file->hasAutoflush) { + if (flag) strcat(str, ","); + strcat(str, "hasAutoFlush"); + flag = JS_TRUE; + } + *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, str)); + JS_free(cx, str); + break; + case FILE_CREATED: + SECURITY_CHECK(cx, NULL, "creationTime", file); + JSFILE_CHECK_NATIVE("creationTime"); + if(((file->isOpen)? + PR_GetOpenFileInfo(file->handle, &info): + PR_GetFileInfo(file->path, &info))!=PR_SUCCESS){ + JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL, + JSFILEMSG_CANNOT_ACCESS_FILE_STATUS, file->path); + goto out; + } + + PR_ExplodeTime(info.creationTime, PR_LocalTimeParameters,&expandedTime); + *vp = OBJECT_TO_JSVAL(js_NewDateObject(cx, expandedTime.tm_year, + expandedTime.tm_month, + expandedTime.tm_mday, + expandedTime.tm_hour, + expandedTime.tm_min, + expandedTime.tm_sec)); + break; + case FILE_MODIFIED: + SECURITY_CHECK(cx, NULL, "lastModified", file); + JSFILE_CHECK_NATIVE("lastModified"); + if(((file->isOpen)? + PR_GetOpenFileInfo(file->handle, &info): + PR_GetFileInfo(file->path, &info))!=PR_SUCCESS){ + JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL, + JSFILEMSG_CANNOT_ACCESS_FILE_STATUS, file->path); + goto out; + } + + PR_ExplodeTime(info.modifyTime, PR_LocalTimeParameters, &expandedTime); + *vp = OBJECT_TO_JSVAL(js_NewDateObject(cx, expandedTime.tm_year, + expandedTime.tm_month, + expandedTime.tm_mday, + expandedTime.tm_hour, + expandedTime.tm_min, + expandedTime.tm_sec)); + break; + case FILE_SIZE: + SECURITY_CHECK(cx, NULL, "size", file); + *vp = js_size(cx, file); + break; + case FILE_LENGTH: + SECURITY_CHECK(cx, NULL, "length", file); + JSFILE_CHECK_NATIVE("length"); + + if (js_isDirectory(cx, file)) { /* XXX debug me */ + PRDir *dir; + PRDirEntry *entry; + jsint count = 0; + + if(!(dir = PR_OpenDir(file->path))){ + JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL, + JSFILEMSG_CANNOT_OPEN_DIR, file->path); + goto out; + } + + while ((entry = PR_ReadDir(dir, PR_SKIP_BOTH))) { + count++; + } + + if(!PR_CloseDir(dir)){ + JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL, + JSFILEMSG_OP_FAILED, "close", file->path); + + goto out; + } + + *vp = INT_TO_JSVAL(count); + break; + }else{ + /* return file size */ + *vp = js_size(cx, file); + } + break; + case FILE_RANDOMACCESS: + SECURITY_CHECK(cx, NULL, "hasRandomAccess", file); + JSFILE_CHECK_OPEN("hasRandomAccess"); + *vp = BOOLEAN_TO_JSVAL(file->hasRandomAccess); + break; + case FILE_POSITION: + SECURITY_CHECK(cx, NULL, "position", file); + JSFILE_CHECK_NATIVE("position"); + JSFILE_CHECK_OPEN("position"); + + if(!file->hasRandomAccess){ + JS_ReportWarning(cx, "File %s doesn't support random access, can't report the position, proceeding"); + *vp = JSVAL_VOID; + break; + } + + if (file->isOpen && js_isFile(cx, file)) { + int pos = PR_Seek(file->handle, 0, PR_SEEK_CUR); + if(pos!=-1){ + *vp = INT_TO_JSVAL(pos); + }else{ + JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL, + JSFILEMSG_CANNOT_REPORT_POSITION, file->path); + goto out; + } + }else { + JS_ReportWarning(cx, "File %s is closed or not a plain file," + " can't report position, proceeding"); + goto out; + } + break; + default: + SECURITY_CHECK(cx, NULL, "file_access", file); + /* this is some other property -- try to use the dir["file"] syntax */ + if(js_isDirectory(cx, file)){ + PRDir *dir = NULL; + PRDirEntry *entry = NULL; + char *prop_name = JS_GetStringBytes(JS_ValueToString(cx, id)); + + /* no native files past this point */ + dir = PR_OpenDir(file->path); + if(!dir) { + /* This is probably not a directory */ + JS_ReportWarning(cx, "Can't open directory %s", file->path); + return JS_FALSE; + } + + while((entry = PR_ReadDir(dir, PR_SKIP_NONE))!=NULL){ + if(!strcmp(entry->name, prop_name)){ + str = js_combinePath(cx, file->path, prop_name); + *vp = OBJECT_TO_JSVAL(js_NewFileObject(cx, str)); + JS_free(cx, str); + return JS_TRUE; + } + } + } + } + return JS_TRUE; +out: + *vp = JSVAL_VOID; + return JS_FALSE; +} + +static JSBool +file_setProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp) +{ + JSFile *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL); + jsint slot; + + if (JSVAL_IS_STRING(id)){ + return JS_TRUE; + } + + slot = JSVAL_TO_INT(id); + + switch (slot) { + /* File.position = 10 */ + case FILE_POSITION: + SECURITY_CHECK(cx, NULL, "set_position", file); + JSFILE_CHECK_NATIVE("set_position"); + + if(!file->hasRandomAccess){ + JS_ReportWarning(cx, "File %s doesn't support random access, can't " + "report the position, proceeding"); + goto out; + } + + if (file->isOpen && js_isFile(cx, file)) { + int32 pos; + int32 offset; + + if (!JS_ValueToInt32(cx, *vp, &offset)){ + JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL, + JSFILEMSG_FIRST_ARGUMENT_MUST_BE_A_NUMBER, "position", *vp); + goto out; + } + + pos = PR_Seek(file->handle, offset, PR_SEEK_SET); + + if(pos!=-1){ + *vp = INT_TO_JSVAL(pos); + }else{ + JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL, + JSFILEMSG_CANNOT_SET_POSITION, file->path); + goto out; + } + } else { + JS_ReportWarning(cx, "File %s is closed or not a file, can't set " + "position, proceeding", file->path); + goto out; + } + } + + return JS_TRUE; +out: + *vp = JSVAL_VOID; + return JS_FALSE; +} + +/* + File.currentDir = new File("D:\") or File.currentDir = "D:\" +*/ +static JSBool +file_currentDirSetter(JSContext *cx, JSObject *obj, jsval id, jsval *vp) +{ + JSObject *rhsObject; + char *path; + JSFile *file = JS_GetInstancePrivate(cx, rhsObject, &file_class, NULL); + + /* Look at the rhs and extract a file object from it */ + if (JSVAL_IS_OBJECT(*vp)){ + if (JS_InstanceOf(cx, rhsObject, &file_class, NULL)){ + /* Braindamaged rhs -- just return the old value */ + if (file && (!js_exists(cx, file) || !js_isDirectory(cx, file))){ + JS_GetProperty(cx, obj, CURRENTDIR_PROPERTY, vp); + goto out; + }else{ + rhsObject = JSVAL_TO_OBJECT(*vp); + chdir(file->path); + return JS_TRUE; + } + }else + goto out; + }else{ + path = JS_GetStringBytes(JS_ValueToString(cx, *vp)); + rhsObject = js_NewFileObject(cx, path); + if (!rhsObject) goto out; + + if (!file || !js_exists(cx, file) || !js_isDirectory(cx, file)){ + JS_GetProperty(cx, obj, CURRENTDIR_PROPERTY, vp); + }else{ + *vp = OBJECT_TO_JSVAL(rhsObject); + chdir(path); + } + } + return JS_TRUE; +out: + *vp = JSVAL_VOID; + return JS_FALSE; +} + +/* Declare class */ +static JSClass file_class = { + FILE_CONSTRUCTOR, JSCLASS_HAS_PRIVATE, + JS_PropertyStub, JS_PropertyStub, file_getProperty, file_setProperty, + JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, file_finalize +}; + +/* -------------------- Functions exposed to the outside -------------------- */ +JS_PUBLIC_API(JSObject*) +js_InitFileClass(JSContext *cx, JSObject* obj, JSBool initStandardStreams) +{ + JSObject *file, *ctor, *afile; + jsval vp; + char *currentdir; + char separator[2]; + + file = JS_InitClass(cx, obj, NULL, &file_class, file_constructor, 1, + file_props, file_functions, NULL, NULL); + if (!file) { + JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL, + JSFILEMSG_INIT_FAILED); + return NULL; + } + + ctor = JS_GetConstructor(cx, file); + if (!ctor) return NULL; + + /* Define CURRENTDIR property. We are doing this to get a + slash at the end of the current dir */ + afile = js_NewFileObject(cx, CURRENT_DIR); + currentdir = JS_malloc(cx, MAX_PATH_LENGTH); + currentdir = getcwd(currentdir, MAX_PATH_LENGTH); + afile = js_NewFileObject(cx, currentdir); + JS_free(cx, currentdir); + vp = OBJECT_TO_JSVAL(afile); + JS_DefinePropertyWithTinyId(cx, ctor, CURRENTDIR_PROPERTY, 0, vp, + JS_PropertyStub, file_currentDirSetter, + JSPROP_ENUMERATE | JSPROP_READONLY ); + + if(initStandardStreams){ + /* Code to create stdin, stdout, and stderr. Insert in the appropriate place. */ + /* Define input */ + vp = OBJECT_TO_JSVAL(js_NewFileObjectFromFILE(cx, stdin, + STDINPUT_NAME, PR_RDONLY, JS_TRUE, JS_FALSE)); + JS_SetProperty(cx, ctor, "input", &vp); + + /* Define output */ + vp = OBJECT_TO_JSVAL(js_NewFileObjectFromFILE(cx, stdout, + STDOUTPUT_NAME, PR_WRONLY, JS_TRUE, JS_FALSE)); + JS_SetProperty(cx, ctor, "output", &vp); + + /* Define error */ + vp = OBJECT_TO_JSVAL(js_NewFileObjectFromFILE(cx, stderr, + STDERROR_NAME, PR_WRONLY, JS_TRUE, JS_FALSE)); + JS_SetProperty(cx, ctor, "error", &vp); + } + separator[0] = FILESEPARATOR; + separator[1] = '\0'; + vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, separator)); + JS_DefinePropertyWithTinyId(cx, ctor, SEPARATOR_PROPERTY, 0, vp, + JS_PropertyStub, JS_PropertyStub, + JSPROP_ENUMERATE | JSPROP_READONLY ); + return file; +} +#endif /* JS_HAS_FILE_OBJECT */ diff --git a/src/dom/js/jsfile.h b/src/dom/js/jsfile.h new file mode 100644 index 000000000..47a8692d8 --- /dev/null +++ b/src/dom/js/jsfile.h @@ -0,0 +1,50 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef _jsfile_h__ +#define _jsfile_h__ + +#if JS_HAS_FILE_OBJECT +extern JS_PUBLIC_API(JSObject*) +js_InitFileClass(JSContext *cx, JSObject* obj, JSBool initStandardStreams); + +extern JS_PUBLIC_API(JSObject*) +js_NewFileObject(JSContext *cx, char *bytes); +#endif /* JS_HAS_FILE_OBJECT */ +#endif /* _jsfile_h__ */ diff --git a/src/dom/js/jsfun.c b/src/dom/js/jsfun.c new file mode 100644 index 000000000..93cd4009d --- /dev/null +++ b/src/dom/js/jsfun.c @@ -0,0 +1,2059 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* + * JS function support. + */ +#include "jsstddef.h" +#include +#include "jstypes.h" +#include "jsbit.h" +#include "jsutil.h" /* Added by JSIFY */ +#include "jsapi.h" +#include "jsarray.h" +#include "jsatom.h" +#include "jscntxt.h" +#include "jsconfig.h" +#include "jsdbgapi.h" +#include "jsfun.h" +#include "jsgc.h" +#include "jsinterp.h" +#include "jslock.h" +#include "jsnum.h" +#include "jsobj.h" +#include "jsopcode.h" +#include "jsparse.h" +#include "jsscan.h" +#include "jsscope.h" +#include "jsscript.h" +#include "jsstr.h" +#include "jsexn.h" + +/* Generic function/call/arguments tinyids -- also reflected bit numbers. */ +enum { + CALL_ARGUMENTS = -1, /* predefined arguments local variable */ + CALL_CALLEE = -2, /* reference to active function's object */ + ARGS_LENGTH = -3, /* number of actual args, arity if inactive */ + ARGS_CALLEE = -4, /* reference from arguments to active funobj */ + FUN_ARITY = -5, /* number of formal parameters; desired argc */ + FUN_NAME = -6, /* function name, "" if anonymous */ + FUN_CALLER = -7 /* Function.prototype.caller, backward compat */ +}; + +#if JSFRAME_OVERRIDE_BITS < 8 +# error "not enough override bits in JSStackFrame.flags!" +#endif + +#define TEST_OVERRIDE_BIT(fp, tinyid) \ + ((fp)->flags & JS_BIT(JSFRAME_OVERRIDE_SHIFT - ((tinyid) + 1))) + +#define SET_OVERRIDE_BIT(fp, tinyid) \ + ((fp)->flags |= JS_BIT(JSFRAME_OVERRIDE_SHIFT - ((tinyid) + 1))) + +#if JS_HAS_ARGS_OBJECT + +JSBool +js_GetArgsValue(JSContext *cx, JSStackFrame *fp, jsval *vp) +{ + JSObject *argsobj; + + if (TEST_OVERRIDE_BIT(fp, CALL_ARGUMENTS)) { + JS_ASSERT(fp->callobj); + return OBJ_GET_PROPERTY(cx, fp->callobj, + (jsid) cx->runtime->atomState.argumentsAtom, + vp); + } + argsobj = js_GetArgsObject(cx, fp); + if (!argsobj) + return JS_FALSE; + *vp = OBJECT_TO_JSVAL(argsobj); + return JS_TRUE; +} + +static JSBool +MarkArgDeleted(JSContext *cx, JSStackFrame *fp, uintN slot) +{ + JSObject *argsobj; + jsval bmapval, bmapint; + size_t nbits, nbytes; + jsbitmap *bitmap; + + argsobj = fp->argsobj; + (void) JS_GetReservedSlot(cx, argsobj, 0, &bmapval); + nbits = JS_MAX(fp->argc, fp->fun->nargs); + JS_ASSERT(slot < nbits); + if (JSVAL_IS_VOID(bmapval)) { + if (nbits <= JSVAL_INT_BITS) { + bmapint = 0; + bitmap = (jsbitmap *) &bmapint; + } else { + nbytes = JS_HOWMANY(nbits, JS_BITS_PER_WORD) * sizeof(jsbitmap); + bitmap = (jsbitmap *) JS_malloc(cx, nbytes); + if (!bitmap) + return JS_FALSE; + memset(bitmap, 0, nbytes); + bmapval = PRIVATE_TO_JSVAL(bitmap); + JS_SetReservedSlot(cx, argsobj, 0, bmapval); + } + } else { + if (nbits <= JSVAL_INT_BITS) { + bmapint = JSVAL_TO_INT(bmapval); + bitmap = (jsbitmap *) &bmapint; + } else { + bitmap = (jsbitmap *) JSVAL_TO_PRIVATE(bmapval); + } + } + JS_SET_BIT(bitmap, slot); + if (bitmap == (jsbitmap *) &bmapint) { + bmapval = INT_TO_JSVAL(bmapint); + JS_SetReservedSlot(cx, argsobj, 0, bmapval); + } + return JS_TRUE; +} + +/* NB: Infallible predicate, false does not mean error/exception. */ +static JSBool +ArgWasDeleted(JSContext *cx, JSStackFrame *fp, uintN slot) +{ + JSObject *argsobj; + jsval bmapval, bmapint; + jsbitmap *bitmap; + + argsobj = fp->argsobj; + (void) JS_GetReservedSlot(cx, argsobj, 0, &bmapval); + if (JSVAL_IS_VOID(bmapval)) + return JS_FALSE; + if (JS_MAX(fp->argc, fp->fun->nargs) <= JSVAL_INT_BITS) { + bmapint = JSVAL_TO_INT(bmapval); + bitmap = (jsbitmap *) &bmapint; + } else { + bitmap = (jsbitmap *) JSVAL_TO_PRIVATE(bmapval); + } + return JS_TEST_BIT(bitmap, slot) != 0; +} + +JSBool +js_GetArgsProperty(JSContext *cx, JSStackFrame *fp, jsid id, + JSObject **objp, jsval *vp) +{ + jsval val; + JSObject *obj; + uintN slot; + + if (TEST_OVERRIDE_BIT(fp, CALL_ARGUMENTS)) { + JS_ASSERT(fp->callobj); + if (!OBJ_GET_PROPERTY(cx, fp->callobj, + (jsid) cx->runtime->atomState.argumentsAtom, + &val)) { + return JS_FALSE; + } + if (JSVAL_IS_PRIMITIVE(val)) { + obj = js_ValueToNonNullObject(cx, val); + if (!obj) + return JS_FALSE; + } else { + obj = JSVAL_TO_OBJECT(val); + } + *objp = obj; + return OBJ_GET_PROPERTY(cx, obj, id, vp); + } + + *objp = NULL; + *vp = JSVAL_VOID; + if (JSVAL_IS_INT(id)) { + slot = (uintN) JSVAL_TO_INT(id); + if (slot < JS_MAX(fp->argc, fp->fun->nargs)) { + if (fp->argsobj && ArgWasDeleted(cx, fp, slot)) + return OBJ_GET_PROPERTY(cx, fp->argsobj, id, vp); + *vp = fp->argv[slot]; + } + } else { + if (id == (jsid) cx->runtime->atomState.lengthAtom) { + if (fp->argsobj && TEST_OVERRIDE_BIT(fp, ARGS_LENGTH)) + return OBJ_GET_PROPERTY(cx, fp->argsobj, id, vp); + *vp = INT_TO_JSVAL((jsint) fp->argc); + } + } + return JS_TRUE; +} + +JSObject * +js_GetArgsObject(JSContext *cx, JSStackFrame *fp) +{ + JSObject *argsobj; + + /* Create an arguments object for fp only if it lacks one. */ + JS_ASSERT(fp->fun); + argsobj = fp->argsobj; + if (argsobj) + return argsobj; + + /* Link the new object to fp so it can get actual argument values. */ + argsobj = js_NewObject(cx, &js_ArgumentsClass, NULL, NULL); + if (!argsobj || !JS_SetPrivate(cx, argsobj, fp)) { + cx->newborn[GCX_OBJECT] = NULL; + return NULL; + } + fp->argsobj = argsobj; + return argsobj; +} + +static JSBool +args_enumerate(JSContext *cx, JSObject *obj); + +JSBool +js_PutArgsObject(JSContext *cx, JSStackFrame *fp) +{ + JSObject *argsobj; + jsval bmapval, rval; + JSBool ok; + JSRuntime *rt; + + /* + * Reuse args_enumerate here to reflect fp's actual arguments as indexed + * elements of argsobj. Do this first, before clearing and freeing the + * deleted argument slot bitmap, because args_enumerate depends on that. + */ + argsobj = fp->argsobj; + ok = args_enumerate(cx, argsobj); + + /* + * Now clear the deleted argument number bitmap slot and free the bitmap, + * if one was actually created due to 'delete arguments[0]' or similar. + */ + (void) JS_GetReservedSlot(cx, argsobj, 0, &bmapval); + if (!JSVAL_IS_VOID(bmapval)) { + JS_SetReservedSlot(cx, argsobj, 0, JSVAL_VOID); + if (JS_MAX(fp->argc, fp->fun->nargs) > JSVAL_INT_BITS) + JS_free(cx, JSVAL_TO_PRIVATE(bmapval)); + } + + /* + * Now get the prototype properties so we snapshot fp->fun and fp->argc + * before fp goes away. + */ + rt = cx->runtime; + ok &= js_GetProperty(cx, argsobj, (jsid)rt->atomState.calleeAtom, &rval); + ok &= js_SetProperty(cx, argsobj, (jsid)rt->atomState.calleeAtom, &rval); + ok &= js_GetProperty(cx, argsobj, (jsid)rt->atomState.lengthAtom, &rval); + ok &= js_SetProperty(cx, argsobj, (jsid)rt->atomState.lengthAtom, &rval); + + /* + * Clear the private pointer to fp, which is about to go away (js_Invoke). + * Do this last because the args_enumerate and js_GetProperty calls above + * need to follow the private slot to find fp. + */ + ok &= JS_SetPrivate(cx, argsobj, NULL); + fp->argsobj = NULL; + return ok; +} + +static JSBool +args_delProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp) +{ + jsint slot; + JSStackFrame *fp; + + if (!JSVAL_IS_INT(id)) + return JS_TRUE; + fp = (JSStackFrame *) + JS_GetInstancePrivate(cx, obj, &js_ArgumentsClass, NULL); + if (!fp) + return JS_TRUE; + JS_ASSERT(fp->argsobj); + JS_ASSERT(fp->fun); + + slot = JSVAL_TO_INT(id); + switch (slot) { + case ARGS_CALLEE: + case ARGS_LENGTH: + SET_OVERRIDE_BIT(fp, slot); + break; + + default: + if ((uintN)slot < JS_MAX(fp->argc, fp->fun->nargs) && + !MarkArgDeleted(cx, fp, slot)) { + return JS_FALSE; + } + break; + } + return JS_TRUE; +} + +static JSBool +args_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp) +{ + jsint slot; + JSStackFrame *fp; + + if (!JSVAL_IS_INT(id)) + return JS_TRUE; + fp = (JSStackFrame *) + JS_GetInstancePrivate(cx, obj, &js_ArgumentsClass, NULL); + if (!fp) + return JS_TRUE; + JS_ASSERT(fp->argsobj); + JS_ASSERT(fp->fun); + + slot = JSVAL_TO_INT(id); + switch (slot) { + case ARGS_CALLEE: + if (!TEST_OVERRIDE_BIT(fp, slot)) + *vp = fp->argv ? fp->argv[-2] : OBJECT_TO_JSVAL(fp->fun->object); + break; + + case ARGS_LENGTH: + if (!TEST_OVERRIDE_BIT(fp, slot)) + *vp = INT_TO_JSVAL((jsint)fp->argc); + break; + + default: + if ((uintN)slot < JS_MAX(fp->argc, fp->fun->nargs) && + !ArgWasDeleted(cx, fp, slot)) { + *vp = fp->argv[slot]; + } + break; + } + return JS_TRUE; +} + +static JSBool +args_setProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp) +{ + JSStackFrame *fp; + jsint slot; + + if (!JSVAL_IS_INT(id)) + return JS_TRUE; + fp = (JSStackFrame *) + JS_GetInstancePrivate(cx, obj, &js_ArgumentsClass, NULL); + if (!fp) + return JS_TRUE; + JS_ASSERT(fp->argsobj); + JS_ASSERT(fp->fun); + + slot = JSVAL_TO_INT(id); + switch (slot) { + case ARGS_CALLEE: + case ARGS_LENGTH: + SET_OVERRIDE_BIT(fp, slot); + break; + + default: + if ((uintN)slot < JS_MAX(fp->argc, fp->fun->nargs) && + !ArgWasDeleted(cx, fp, slot)) { + fp->argv[slot] = *vp; + } + break; + } + return JS_TRUE; +} + +static JSBool +args_resolve(JSContext *cx, JSObject *obj, jsval id, uintN flags, + JSObject **objp) +{ + JSStackFrame *fp; + uintN slot; + JSString *str; + JSAtom *atom; + intN tinyid; + jsval value; + + *objp = NULL; + fp = (JSStackFrame *) + JS_GetInstancePrivate(cx, obj, &js_ArgumentsClass, NULL); + if (!fp) + return JS_TRUE; + JS_ASSERT(fp->argsobj); + JS_ASSERT(fp->fun); + + if (JSVAL_IS_INT(id)) { + slot = JSVAL_TO_INT(id); + if (slot < JS_MAX(fp->argc, fp->fun->nargs) && + !ArgWasDeleted(cx, fp, slot)) { + /* XXX ECMA specs DontEnum, contrary to other array-like objects */ + if (!js_DefineProperty(cx, obj, (jsid) id, fp->argv[slot], + args_getProperty, args_setProperty, + JSVERSION_IS_ECMA(cx->version) + ? 0 + : JSPROP_ENUMERATE, + NULL)) { + return JS_FALSE; + } + *objp = obj; + } + } else { + str = JSVAL_TO_STRING(id); + atom = cx->runtime->atomState.lengthAtom; + if (str == ATOM_TO_STRING(atom)) { + tinyid = ARGS_LENGTH; + value = INT_TO_JSVAL(fp->argc); + } else { + atom = cx->runtime->atomState.calleeAtom; + if (str == ATOM_TO_STRING(atom)) { + tinyid = ARGS_CALLEE; + value = fp->argv ? fp->argv[-2] + : OBJECT_TO_JSVAL(fp->fun->object); + } else { + atom = NULL; + + /* Quell GCC overwarnings. */ + tinyid = 0; + value = JSVAL_NULL; + } + } + + if (atom && !TEST_OVERRIDE_BIT(fp, tinyid)) { + if (!js_DefineNativeProperty(cx, obj, (jsid) atom, value, + args_getProperty, args_setProperty, 0, + SPROP_HAS_SHORTID, tinyid, NULL)) { + return JS_FALSE; + } + *objp = obj; + } + } + + return JS_TRUE; +} + +static JSBool +args_enumerate(JSContext *cx, JSObject *obj) +{ + JSStackFrame *fp; + JSObject *pobj; + JSProperty *prop; + uintN slot, nargs; + + fp = (JSStackFrame *) + JS_GetInstancePrivate(cx, obj, &js_ArgumentsClass, NULL); + if (!fp) + return JS_TRUE; + JS_ASSERT(fp->argsobj); + JS_ASSERT(fp->fun); + + /* + * Trigger reflection with value snapshot in args_resolve using a series + * of js_LookupProperty calls. We handle length, callee, and the indexed + * argument properties. We know that args_resolve covers all these cases + * and creates direct properties of obj, but that it may fail to resolve + * length or callee if overridden. + */ + if (!js_LookupProperty(cx, obj, (jsid) cx->runtime->atomState.lengthAtom, + &pobj, &prop)) { + return JS_FALSE; + } + if (prop) + OBJ_DROP_PROPERTY(cx, pobj, prop); + + if (!js_LookupProperty(cx, obj, (jsid) cx->runtime->atomState.calleeAtom, + &pobj, &prop)) { + return JS_FALSE; + } + if (prop) + OBJ_DROP_PROPERTY(cx, pobj, prop); + + nargs = JS_MAX(fp->argc, fp->fun->nargs); + for (slot = 0; slot < nargs; slot++) { + if (!js_LookupProperty(cx, obj, (jsid) INT_TO_JSVAL((jsint)slot), + &pobj, &prop)) { + return JS_FALSE; + } + if (prop) + OBJ_DROP_PROPERTY(cx, pobj, prop); + } + return JS_TRUE; +} + +/* + * The Arguments class is not initialized via JS_InitClass, and must not be, + * because its name is "Object". Per ECMA, that causes instances of it to + * delegate to the object named by Object.prototype. It also ensures that + * arguments.toString() returns "[object Object]". + * + * The JSClass functions below collaborate to lazily reflect and synchronize + * actual argument values, argument count, and callee function object stored + * in a JSStackFrame with their corresponding property values in the frame's + * arguments object. + */ +JSClass js_ArgumentsClass = { + js_Object_str, + JSCLASS_HAS_PRIVATE | JSCLASS_NEW_RESOLVE | JSCLASS_HAS_RESERVED_SLOTS(1), + JS_PropertyStub, args_delProperty, + args_getProperty, args_setProperty, + args_enumerate, (JSResolveOp) args_resolve, + JS_ConvertStub, JS_FinalizeStub, + JSCLASS_NO_OPTIONAL_MEMBERS +}; + +#endif /* JS_HAS_ARGS_OBJECT */ + +#if JS_HAS_CALL_OBJECT + +JSObject * +js_GetCallObject(JSContext *cx, JSStackFrame *fp, JSObject *parent) +{ + JSObject *callobj, *funobj; + + /* Create a call object for fp only if it lacks one. */ + JS_ASSERT(fp->fun); + callobj = fp->callobj; + if (callobj) + return callobj; + JS_ASSERT(fp->fun); + + /* The default call parent is its function's parent (static link). */ + if (!parent) { + funobj = fp->argv ? JSVAL_TO_OBJECT(fp->argv[-2]) : fp->fun->object; + if (funobj) + parent = OBJ_GET_PARENT(cx, funobj); + } + + /* Create the call object and link it to its stack frame. */ + callobj = js_NewObject(cx, &js_CallClass, NULL, parent); + if (!callobj || !JS_SetPrivate(cx, callobj, fp)) { + cx->newborn[GCX_OBJECT] = NULL; + return NULL; + } + fp->callobj = callobj; + + /* Make callobj be the scope chain and the variables object. */ + fp->scopeChain = callobj; + fp->varobj = callobj; + return callobj; +} + +static JSBool +call_enumerate(JSContext *cx, JSObject *obj); + +JSBool +js_PutCallObject(JSContext *cx, JSStackFrame *fp) +{ + JSObject *callobj; + JSBool ok; + jsid argsid; + jsval aval; + + /* + * Reuse call_enumerate here to reflect all actual args and vars into the + * call object from fp. + */ + callobj = fp->callobj; + if (!callobj) + return JS_TRUE; + ok = call_enumerate(cx, callobj); + + /* + * Get the arguments object to snapshot fp's actual argument values. + */ + if (fp->argsobj) { + argsid = (jsid) cx->runtime->atomState.argumentsAtom; + ok &= js_GetProperty(cx, callobj, argsid, &aval); + ok &= js_SetProperty(cx, callobj, argsid, &aval); + ok &= js_PutArgsObject(cx, fp); + } + + /* + * Clear the private pointer to fp, which is about to go away (js_Invoke). + * Do this last because the call_enumerate and js_GetProperty calls above + * need to follow the private slot to find fp. + */ + ok &= JS_SetPrivate(cx, callobj, NULL); + fp->callobj = NULL; + return ok; +} + +static JSPropertySpec call_props[] = { + {js_arguments_str, CALL_ARGUMENTS, JSPROP_PERMANENT,0,0}, + {"__callee__", CALL_CALLEE, 0,0,0}, + {0,0,0,0,0} +}; + +static JSBool +call_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp) +{ + JSStackFrame *fp; + jsint slot; + + if (!JSVAL_IS_INT(id)) + return JS_TRUE; + fp = (JSStackFrame *) JS_GetPrivate(cx, obj); + if (!fp) + return JS_TRUE; + JS_ASSERT(fp->fun); + + slot = JSVAL_TO_INT(id); + switch (slot) { + case CALL_ARGUMENTS: + if (!TEST_OVERRIDE_BIT(fp, slot)) { + JSObject *argsobj = js_GetArgsObject(cx, fp); + if (!argsobj) + return JS_FALSE; + *vp = OBJECT_TO_JSVAL(argsobj); + } + break; + + case CALL_CALLEE: + if (!TEST_OVERRIDE_BIT(fp, slot)) + *vp = fp->argv ? fp->argv[-2] : OBJECT_TO_JSVAL(fp->fun->object); + break; + + default: + if ((uintN)slot < JS_MAX(fp->argc, fp->fun->nargs)) + *vp = fp->argv[slot]; + break; + } + return JS_TRUE; +} + +static JSBool +call_setProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp) +{ + JSStackFrame *fp; + jsint slot; + + if (!JSVAL_IS_INT(id)) + return JS_TRUE; + fp = (JSStackFrame *) JS_GetPrivate(cx, obj); + if (!fp) + return JS_TRUE; + JS_ASSERT(fp->fun); + + slot = JSVAL_TO_INT(id); + switch (slot) { + case CALL_ARGUMENTS: + case CALL_CALLEE: + SET_OVERRIDE_BIT(fp, slot); + break; + + default: + if ((uintN)slot < JS_MAX(fp->argc, fp->fun->nargs)) + fp->argv[slot] = *vp; + break; + } + return JS_TRUE; +} + +JSBool +js_GetCallVariable(JSContext *cx, JSObject *obj, jsval id, jsval *vp) +{ + JSStackFrame *fp; + + JS_ASSERT(JSVAL_IS_INT(id)); + fp = (JSStackFrame *) JS_GetPrivate(cx, obj); + if (fp) { + /* XXX no jsint slot commoning here to avoid MSVC1.52 crashes */ + if ((uintN)JSVAL_TO_INT(id) < fp->nvars) + *vp = fp->vars[JSVAL_TO_INT(id)]; + } + return JS_TRUE; +} + +JSBool +js_SetCallVariable(JSContext *cx, JSObject *obj, jsval id, jsval *vp) +{ + JSStackFrame *fp; + + JS_ASSERT(JSVAL_IS_INT(id)); + fp = (JSStackFrame *) JS_GetPrivate(cx, obj); + if (fp) { + /* XXX jsint slot is block-local here to avoid MSVC1.52 crashes */ + jsint slot = JSVAL_TO_INT(id); + if ((uintN)slot < fp->nvars) + fp->vars[slot] = *vp; + } + return JS_TRUE; +} + +static JSBool +call_enumerate(JSContext *cx, JSObject *obj) +{ + JSStackFrame *fp; + JSObject *funobj; + JSScope *scope; + JSScopeProperty *sprop, *cprop; + JSPropertyOp getter; + jsval *vec; + JSProperty *prop; + + fp = (JSStackFrame *) JS_GetPrivate(cx, obj); + if (!fp) + return JS_TRUE; + + /* + * Do not enumerate a cloned function object at fp->argv[-2], it may have + * gained its own (mutable) scope (e.g., a brutally-shared XUL script sets + * the clone's prototype property). We must enumerate the function object + * that was decorated with parameter and local variable properties by the + * compiler when the compiler created fp->fun, namely fp->fun->object. + * + * Contrast with call_resolve, where we prefer fp->argv[-2], because we'll + * use js_LookupProperty to find any overridden properties in that object, + * if it was a mutated clone; and if not, we will search its prototype, + * fp->fun->object, to find compiler-created params and locals. + */ + funobj = fp->fun->object; + if (!funobj) + return JS_TRUE; + + /* + * Reflect actual args from fp->argv for formal parameters, and local vars + * and functions in fp->vars for declared variables and nested-at-top-level + * local functions. + */ + scope = OBJ_SCOPE(funobj); + for (sprop = SCOPE_LAST_PROP(scope); sprop; sprop = sprop->parent) { + getter = sprop->getter; + if (getter == js_GetArgument) + vec = fp->argv; + else if (getter == js_GetLocalVariable) + vec = fp->vars; + else + continue; + + /* Trigger reflection in call_resolve by doing a lookup. */ + if (!js_LookupProperty(cx, obj, sprop->id, &obj, &prop)) + return JS_FALSE; + JS_ASSERT(obj && prop); + cprop = (JSScopeProperty *)prop; + LOCKED_OBJ_SET_SLOT(obj, cprop->slot, vec[sprop->shortid]); + OBJ_DROP_PROPERTY(cx, obj, prop); + } + + return JS_TRUE; +} + +static JSBool +call_resolve(JSContext *cx, JSObject *obj, jsval id, uintN flags, + JSObject **objp) +{ + JSStackFrame *fp; + JSObject *funobj; + JSString *str; + JSAtom *atom; + JSObject *obj2; + JSScopeProperty *sprop; + jsid propid; + JSPropertyOp getter, setter; + uintN attrs, slot, nslots, spflags; + jsval *vp, value; + intN shortid; + + fp = (JSStackFrame *) JS_GetPrivate(cx, obj); + if (!fp) + return JS_TRUE; + JS_ASSERT(fp->fun); + + if (!JSVAL_IS_STRING(id)) + return JS_TRUE; + + funobj = fp->argv ? JSVAL_TO_OBJECT(fp->argv[-2]) : fp->fun->object; + if (!funobj) + return JS_TRUE; + + str = JSVAL_TO_STRING(id); + atom = js_AtomizeString(cx, str, 0); + if (!atom) + return JS_FALSE; + if (!js_LookupProperty(cx, funobj, (jsid)atom, &obj2, + (JSProperty **)&sprop)) { + return JS_FALSE; + } + + if (sprop && OBJ_IS_NATIVE(obj2)) { + propid = sprop->id; + getter = sprop->getter; + attrs = sprop->attrs & ~JSPROP_SHARED; + slot = (uintN) sprop->shortid; + OBJ_DROP_PROPERTY(cx, obj2, (JSProperty *)sprop); + if (getter == js_GetArgument || getter == js_GetLocalVariable) { + if (getter == js_GetArgument) { + vp = fp->argv; + nslots = JS_MAX(fp->argc, fp->fun->nargs); + getter = setter = NULL; + } else { + vp = fp->vars; + nslots = fp->nvars; + getter = js_GetCallVariable; + setter = js_SetCallVariable; + } + if (slot < nslots) { + value = vp[slot]; + spflags = SPROP_HAS_SHORTID; + shortid = (intN) slot; + } else { + value = JSVAL_VOID; + spflags = 0; + shortid = 0; + } + if (!js_DefineNativeProperty(cx, obj, propid, value, + getter, setter, attrs, + spflags, shortid, NULL)) { + return JS_FALSE; + } + *objp = obj; + } + } + return JS_TRUE; +} + +static JSBool +call_convert(JSContext *cx, JSObject *obj, JSType type, jsval *vp) +{ + JSStackFrame *fp; + + if (type == JSTYPE_FUNCTION) { + fp = (JSStackFrame *) JS_GetPrivate(cx, obj); + if (fp) { + JS_ASSERT(fp->fun); + *vp = fp->argv ? fp->argv[-2] : OBJECT_TO_JSVAL(fp->fun->object); + } + } + return JS_TRUE; +} + +JSClass js_CallClass = { + js_Call_str, + JSCLASS_HAS_PRIVATE | JSCLASS_NEW_RESOLVE, + JS_PropertyStub, JS_PropertyStub, + call_getProperty, call_setProperty, + call_enumerate, (JSResolveOp)call_resolve, + call_convert, JS_FinalizeStub, + JSCLASS_NO_OPTIONAL_MEMBERS +}; + +#endif /* JS_HAS_CALL_OBJECT */ + +/* SHARED because fun_getProperty always computes a new value. */ +#define FUNCTION_PROP_ATTRS (JSPROP_READONLY|JSPROP_PERMANENT|JSPROP_SHARED) + +static JSPropertySpec function_props[] = { + {js_arguments_str, CALL_ARGUMENTS, FUNCTION_PROP_ATTRS,0,0}, + {js_arity_str, FUN_ARITY, FUNCTION_PROP_ATTRS,0,0}, + {js_length_str, ARGS_LENGTH, FUNCTION_PROP_ATTRS,0,0}, + {js_name_str, FUN_NAME, FUNCTION_PROP_ATTRS,0,0}, + {js_caller_str, FUN_CALLER, FUNCTION_PROP_ATTRS,0,0}, + {0,0,0,0,0} +}; + +static JSBool +fun_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp) +{ + jsint slot; + JSFunction *fun; + JSStackFrame *fp; +#if defined _MSC_VER &&_MSC_VER <= 800 + /* MSVC1.5 coredumps */ + jsval bogus = *vp; +#endif + + if (!JSVAL_IS_INT(id)) + return JS_TRUE; + slot = JSVAL_TO_INT(id); + + /* No valid function object should lack private data, but check anyway. */ + fun = (JSFunction *)JS_GetInstancePrivate(cx, obj, &js_FunctionClass, NULL); + if (!fun) + return JS_TRUE; + + /* Find fun's top-most activation record. */ + for (fp = cx->fp; fp && (fp->fun != fun || (fp->flags & JSFRAME_SPECIAL)); + fp = fp->down) { + continue; + } + + switch (slot) { + case CALL_ARGUMENTS: +#if JS_HAS_ARGS_OBJECT + /* Warn if strict about f.arguments or equivalent unqualified uses. */ + if (!JS_ReportErrorFlagsAndNumber(cx, + JSREPORT_WARNING | JSREPORT_STRICT, + js_GetErrorMessage, NULL, + JSMSG_DEPRECATED_USAGE, + js_arguments_str)) { + return JS_FALSE; + } + if (fp) { + if (!js_GetArgsValue(cx, fp, vp)) + return JS_FALSE; + } else { + *vp = JSVAL_NULL; + } + break; +#else /* !JS_HAS_ARGS_OBJECT */ + *vp = OBJECT_TO_JSVAL(fp ? obj : NULL); + break; +#endif /* !JS_HAS_ARGS_OBJECT */ + + case ARGS_LENGTH: + if (!JSVERSION_IS_ECMA(cx->version)) + *vp = INT_TO_JSVAL((jsint)(fp && fp->fun ? fp->argc : fun->nargs)); + else + case FUN_ARITY: + *vp = INT_TO_JSVAL((jsint)fun->nargs); + break; + + case FUN_NAME: + *vp = fun->atom + ? ATOM_KEY(fun->atom) + : STRING_TO_JSVAL(cx->runtime->emptyString); + break; + + case FUN_CALLER: + while (fp && (fp->flags & JSFRAME_SKIP_CALLER) && fp->down) + fp = fp->down; + if (fp && fp->down && fp->down->fun && fp->down->argv) + *vp = fp->down->argv[-2]; + else + *vp = JSVAL_NULL; + if (!JSVAL_IS_PRIMITIVE(*vp) && cx->runtime->checkObjectAccess) { + id = ATOM_KEY(cx->runtime->atomState.callerAtom); + if (!cx->runtime->checkObjectAccess(cx, obj, id, JSACC_READ, vp)) + return JS_FALSE; + } + break; + + default: + /* XXX fun[0] and fun.arguments[0] are equivalent. */ + if (fp && fp->fun && (uintN)slot < fp->fun->nargs) +#if defined _MSC_VER &&_MSC_VER <= 800 + /* MSVC1.5 coredumps */ + if (bogus == *vp) +#endif + *vp = fp->argv[slot]; + break; + } + + return JS_TRUE; +} + +static JSBool +fun_resolve(JSContext *cx, JSObject *obj, jsval id, uintN flags, + JSObject **objp) +{ + JSFunction *fun; + JSString *str; + JSAtom *prototypeAtom; + + if (!JSVAL_IS_STRING(id)) + return JS_TRUE; + + /* No valid function object should lack private data, but check anyway. */ + fun = (JSFunction *)JS_GetInstancePrivate(cx, obj, &js_FunctionClass, NULL); + if (!fun || !fun->object) + return JS_TRUE; + + /* No need to reflect fun.prototype in 'fun.prototype = ...'. */ + if (flags & JSRESOLVE_ASSIGNING) + return JS_TRUE; + + /* + * Ok, check whether id is 'prototype' and bootstrap the function object's + * prototype property. + */ + str = JSVAL_TO_STRING(id); + prototypeAtom = cx->runtime->atomState.classPrototypeAtom; + if (str == ATOM_TO_STRING(prototypeAtom)) { + JSObject *proto, *parentProto; + jsval pval; + + proto = parentProto = NULL; + if (fun->object != obj && fun->object) { + /* + * Clone of a function: make its prototype property value have the + * same class as the clone-parent's prototype. + */ + if (!OBJ_GET_PROPERTY(cx, fun->object, (jsid)prototypeAtom, &pval)) + return JS_FALSE; + if (JSVAL_IS_OBJECT(pval)) + parentProto = JSVAL_TO_OBJECT(pval); + } + + /* + * Beware of the wacky case of a user function named Object -- trying + * to find a prototype for that will recur back here ad perniciem. + */ + if (!parentProto && fun->atom == cx->runtime->atomState.ObjectAtom) + return JS_TRUE; + + /* + * If resolving "prototype" in a clone, clone the parent's prototype. + * Pass the constructor's (obj's) parent as the prototype parent, to + * avoid defaulting to parentProto.constructor.__parent__. + */ + proto = js_NewObject(cx, &js_ObjectClass, parentProto, + OBJ_GET_PARENT(cx, obj)); + if (!proto) + return JS_FALSE; + + /* + * ECMA says that constructor.prototype is DontEnum | DontDelete for + * user-defined functions, but DontEnum | ReadOnly | DontDelete for + * native "system" constructors such as Object or Function. So lazily + * set the former here in fun_resolve, but eagerly define the latter + * in JS_InitClass, with the right attributes. + */ + if (!js_SetClassPrototype(cx, obj, proto, JSPROP_PERMANENT)) { + cx->newborn[GCX_OBJECT] = NULL; + return JS_FALSE; + } + *objp = obj; + } + + return JS_TRUE; +} + +static JSBool +fun_convert(JSContext *cx, JSObject *obj, JSType type, jsval *vp) +{ + switch (type) { + case JSTYPE_FUNCTION: + *vp = OBJECT_TO_JSVAL(obj); + return JS_TRUE; + default: + return js_TryValueOf(cx, obj, type, vp); + } +} + +static void +fun_finalize(JSContext *cx, JSObject *obj) +{ + JSFunction *fun; + + /* No valid function object should lack private data, but check anyway. */ + fun = (JSFunction *) JS_GetPrivate(cx, obj); + if (!fun) + return; + if (fun->object == obj) + fun->object = NULL; + JS_ATOMIC_DECREMENT(&fun->nrefs); + if (fun->nrefs) + return; + if (fun->script) + js_DestroyScript(cx, fun->script); + JS_free(cx, fun); +} + +#if JS_HAS_XDR + +#include "jsxdrapi.h" + +enum { + JSXDR_FUNARG = 1, + JSXDR_FUNVAR = 2, + JSXDR_FUNCONST = 3 +}; + +/* XXX store parent and proto, if defined */ +static JSBool +fun_xdrObject(JSXDRState *xdr, JSObject **objp) +{ + JSContext *cx; + JSFunction *fun; + JSString *atomstr; + char *propname; + JSScopeProperty *sprop; + uint32 userid; /* NB: holds a signed int-tagged jsval */ + JSAtom *atom; + uintN i, n, dupflag; + uint32 type; +#ifdef DEBUG + uintN nvars = 0, nargs = 0; +#endif + + cx = xdr->cx; + if (xdr->mode == JSXDR_ENCODE) { + /* + * No valid function object should lack private data, but fail soft + * (return true, no error report) in case one does due to API pilot + * or internal error. + */ + fun = (JSFunction *) JS_GetPrivate(cx, *objp); + if (!fun) + return JS_TRUE; + atomstr = fun->atom ? ATOM_TO_STRING(fun->atom) : NULL; + } else { + fun = js_NewFunction(cx, NULL, NULL, 0, 0, NULL, NULL); + if (!fun) + return JS_FALSE; + atomstr = NULL; + } + + if (!JS_XDRStringOrNull(xdr, &atomstr) || + !JS_XDRUint16(xdr, &fun->nargs) || + !JS_XDRUint16(xdr, &fun->extra) || + !JS_XDRUint16(xdr, &fun->nvars) || + !JS_XDRUint8(xdr, &fun->flags)) { + return JS_FALSE; + } + + /* do arguments and local vars */ + if (fun->object) { + n = fun->nargs + fun->nvars; + if (xdr->mode == JSXDR_ENCODE) { + JSScope *scope; + JSScopeProperty **spvec, *auto_spvec[8]; + void *mark; + + if (n <= sizeof auto_spvec / sizeof auto_spvec[0]) { + spvec = auto_spvec; + mark = NULL; + } else { + mark = JS_ARENA_MARK(&cx->tempPool); + JS_ARENA_ALLOCATE_CAST(spvec, JSScopeProperty **, &cx->tempPool, + n * sizeof(JSScopeProperty *)); + if (!spvec) { + JS_ReportOutOfMemory(cx); + return JS_FALSE; + } + } + scope = OBJ_SCOPE(fun->object); + for (sprop = SCOPE_LAST_PROP(scope); sprop; + sprop = sprop->parent) { + if (sprop->getter == js_GetArgument) { + JS_ASSERT(nargs++ <= fun->nargs); + spvec[sprop->shortid] = sprop; + } else if (sprop->getter == js_GetLocalVariable) { + JS_ASSERT(nvars++ <= fun->nvars); + spvec[fun->nargs + sprop->shortid] = sprop; + } + } + for (i = 0; i < n; i++) { + sprop = spvec[i]; + JS_ASSERT(sprop->flags & SPROP_HAS_SHORTID); + type = (i < fun->nargs) + ? JSXDR_FUNARG + : (sprop->attrs & JSPROP_READONLY) + ? JSXDR_FUNCONST + : JSXDR_FUNVAR; + userid = INT_TO_JSVAL(sprop->shortid); + /* XXX lossy conversion, need new XDR version for ECMAv3 */ + propname = JS_GetStringBytes(ATOM_TO_STRING((JSAtom *)sprop->id)); + if (!propname || + !JS_XDRUint32(xdr, &type) || + !JS_XDRUint32(xdr, &userid) || + !JS_XDRCString(xdr, &propname)) { + if (mark) + JS_ARENA_RELEASE(&cx->tempPool, mark); + return JS_FALSE; + } + } + if (mark) + JS_ARENA_RELEASE(&cx->tempPool, mark); + } else { + JSPropertyOp getter, setter; + + for (i = n; i != 0; i--) { + uintN attrs = JSPROP_ENUMERATE | JSPROP_PERMANENT; + + if (!JS_XDRUint32(xdr, &type) || + !JS_XDRUint32(xdr, &userid) || + !JS_XDRCString(xdr, &propname)) { + return JS_FALSE; + } + JS_ASSERT(type == JSXDR_FUNARG || type == JSXDR_FUNVAR || + type == JSXDR_FUNCONST); + if (type == JSXDR_FUNARG) { + getter = js_GetArgument; + setter = js_SetArgument; + JS_ASSERT(nargs++ <= fun->nargs); + } else if (type == JSXDR_FUNVAR || type == JSXDR_FUNCONST) { + getter = js_GetLocalVariable; + setter = js_SetLocalVariable; + if (type == JSXDR_FUNCONST) + attrs |= JSPROP_READONLY; + JS_ASSERT(nvars++ <= fun->nvars); + } else { + getter = NULL; + setter = NULL; + } + atom = js_Atomize(cx, propname, strlen(propname), 0); + JS_free(cx, propname); + if (!atom) + return JS_FALSE; + + /* Flag duplicate argument if atom is bound in fun->object. */ + dupflag = SCOPE_GET_PROPERTY(OBJ_SCOPE(fun->object), (jsid)atom) + ? SPROP_IS_DUPLICATE + : 0; + + if (!js_AddNativeProperty(cx, fun->object, (jsid)atom, + getter, setter, SPROP_INVALID_SLOT, + attrs | JSPROP_SHARED, + SPROP_HAS_SHORTID | dupflag, + JSVAL_TO_INT(userid))) { + return JS_FALSE; + } + } + } + } + + if (!js_XDRScript(xdr, &fun->script, NULL)) + return JS_FALSE; + + if (xdr->mode == JSXDR_DECODE) { + *objp = fun->object; + if (atomstr) { + fun->atom = js_AtomizeString(cx, atomstr, 0); + if (!fun->atom) + return JS_FALSE; + + if (!OBJ_DEFINE_PROPERTY(cx, cx->globalObject, + (jsid)fun->atom, OBJECT_TO_JSVAL(*objp), + NULL, NULL, JSPROP_ENUMERATE, + NULL)) { + return JS_FALSE; + } + } + + js_CallNewScriptHook(cx, fun->script, fun); + } + + return JS_TRUE; +} + +#else /* !JS_HAS_XDR */ + +#define fun_xdrObject NULL + +#endif /* !JS_HAS_XDR */ + +#if JS_HAS_INSTANCEOF + +/* + * [[HasInstance]] internal method for Function objects: fetch the .prototype + * property of its 'this' parameter, and walks the prototype chain of v (only + * if v is an object) returning true if .prototype is found. + */ +static JSBool +fun_hasInstance(JSContext *cx, JSObject *obj, jsval v, JSBool *bp) +{ + jsval pval, cval; + JSString *str; + JSObject *proto, *obj2; + JSFunction *cfun, *ofun; + + if (!OBJ_GET_PROPERTY(cx, obj, + (jsid)cx->runtime->atomState.classPrototypeAtom, + &pval)) { + return JS_FALSE; + } + + if (JSVAL_IS_PRIMITIVE(pval)) { + /* + * Throw a runtime error if instanceof is called on a function that + * has a non-object as its .prototype value. + */ + str = js_DecompileValueGenerator(cx, -1, OBJECT_TO_JSVAL(obj), NULL); + if (str) { + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, + JSMSG_BAD_PROTOTYPE, JS_GetStringBytes(str)); + } + return JS_FALSE; + } + + proto = JSVAL_TO_OBJECT(pval); + if (!js_IsDelegate(cx, proto, v, bp)) + return JS_FALSE; + + if (!*bp && !JSVAL_IS_PRIMITIVE(v)) { + /* + * Extension for "brutal sharing" of standard class constructors: if + * a script is compiled using a single, shared set of constructors, in + * particular Function and RegExp, but executed many times using other + * sets of standard constructors, then (/re/ instanceof RegExp), e.g., + * will be false. + * + * We extend instanceof in this case to look for a matching native or + * script underlying the function object found in the 'constructor' + * property of the object in question (which is JSVAL_TO_OBJECT(v)), + * or found in the 'constructor' property of one of its prototypes. + * + * See also jsexn.c, where the *Error constructors are defined, each + * with its own native function, to satisfy (e instanceof Error) even + * when exceptions cross standard-class sharing boundaries. Note that + * Error.prototype may not lie on e's __proto__ chain in that case. + */ + obj2 = JSVAL_TO_OBJECT(v); + do { + if (!OBJ_GET_PROPERTY(cx, obj2, + (jsid)cx->runtime->atomState.constructorAtom, + &cval)) { + return JS_FALSE; + } + + if (JSVAL_IS_FUNCTION(cx, cval)) { + cfun = (JSFunction *) JS_GetPrivate(cx, JSVAL_TO_OBJECT(cval)); + ofun = (JSFunction *) JS_GetPrivate(cx, obj); + if (cfun->native == ofun->native && + cfun->script == ofun->script) { + *bp = JS_TRUE; + break; + } + } + } while ((obj2 = OBJ_GET_PROTO(cx, obj2)) != NULL); + } + + return JS_TRUE; +} + +#else /* !JS_HAS_INSTANCEOF */ + +#define fun_hasInstance NULL + +#endif /* !JS_HAS_INSTANCEOF */ + +static uint32 +fun_mark(JSContext *cx, JSObject *obj, void *arg) +{ + JSFunction *fun; + + fun = (JSFunction *) JS_GetPrivate(cx, obj); + if (fun) { + if (fun->atom) + GC_MARK_ATOM(cx, fun->atom, arg); + if (fun->script) + js_MarkScript(cx, fun->script, arg); + } + return 0; +} + +/* + * Reserve two slots in all function objects for XPConnect. Note that this + * does not bloat every instance, only those on which reserved slots are set, + * and those on which ad-hoc properties are defined. + */ +JSClass js_FunctionClass = { + js_Function_str, + JSCLASS_HAS_PRIVATE | JSCLASS_NEW_RESOLVE | JSCLASS_HAS_RESERVED_SLOTS(2), + JS_PropertyStub, JS_PropertyStub, + fun_getProperty, JS_PropertyStub, + JS_EnumerateStub, (JSResolveOp)fun_resolve, + fun_convert, fun_finalize, + NULL, NULL, + NULL, NULL, + fun_xdrObject, fun_hasInstance, + fun_mark, 0 +}; + +JSBool +js_fun_toString(JSContext *cx, JSObject *obj, uint32 indent, + uintN argc, jsval *argv, jsval *rval) +{ + jsval fval; + JSFunction *fun; + JSString *str; + + if (!argv) { + JS_ASSERT(JS_ObjectIsFunction(cx, obj)); + } else { + fval = argv[-1]; + if (!JSVAL_IS_FUNCTION(cx, fval)) { + /* + * If we don't have a function to start off with, try converting + * the object to a function. If that doesn't work, complain. + */ + if (JSVAL_IS_OBJECT(fval)) { + obj = JSVAL_TO_OBJECT(fval); + if (!OBJ_GET_CLASS(cx, obj)->convert(cx, obj, JSTYPE_FUNCTION, + &fval)) { + return JS_FALSE; + } + } + if (!JSVAL_IS_FUNCTION(cx, fval)) { + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, + JSMSG_INCOMPATIBLE_PROTO, + js_Function_str, js_toString_str, + JS_GetTypeName(cx, + JS_TypeOfValue(cx, fval))); + return JS_FALSE; + } + } + + obj = JSVAL_TO_OBJECT(fval); + } + + fun = (JSFunction *) JS_GetPrivate(cx, obj); + if (!fun) + return JS_TRUE; + if (argc && !js_ValueToECMAUint32(cx, argv[0], &indent)) + return JS_FALSE; + str = JS_DecompileFunction(cx, fun, (uintN)indent); + if (!str) + return JS_FALSE; + *rval = STRING_TO_JSVAL(str); + return JS_TRUE; +} + +static JSBool +fun_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + return js_fun_toString(cx, obj, 0, argc, argv, rval); +} + +#if JS_HAS_TOSOURCE +static JSBool +fun_toSource(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + return js_fun_toString(cx, obj, JS_DONT_PRETTY_PRINT, argc, argv, rval); +} +#endif + +static const char js_call_str[] = "call"; + +#if JS_HAS_CALL_FUNCTION +static JSBool +fun_call(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + jsval fval, *sp, *oldsp; + void *mark; + uintN i; + JSStackFrame *fp; + JSBool ok; + + if (!OBJ_DEFAULT_VALUE(cx, obj, JSTYPE_FUNCTION, &argv[-1])) + return JS_FALSE; + fval = argv[-1]; + + if (!JSVAL_IS_FUNCTION(cx, fval)) { + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, + JSMSG_INCOMPATIBLE_PROTO, + js_Function_str, js_call_str, + JS_GetStringBytes(JS_ValueToString(cx, fval))); + return JS_FALSE; + } + + if (argc == 0) { + /* Call fun with its parent as the 'this' parameter if no args. */ + obj = OBJ_GET_PARENT(cx, obj); + } else { + /* Otherwise convert the first arg to 'this' and skip over it. */ + if (!js_ValueToObject(cx, argv[0], &obj)) + return JS_FALSE; + argc--; + argv++; + } + + /* Allocate stack space for fval, obj, and the args. */ + sp = js_AllocStack(cx, 2 + argc, &mark); + if (!sp) + return JS_FALSE; + + /* Push fval, obj, and the args. */ + *sp++ = fval; + *sp++ = OBJECT_TO_JSVAL(obj); + for (i = 0; i < argc; i++) + *sp++ = argv[i]; + + /* Lift current frame to include the args and do the call. */ + fp = cx->fp; + oldsp = fp->sp; + fp->sp = sp; + ok = js_Invoke(cx, argc, JSINVOKE_INTERNAL | JSINVOKE_SKIP_CALLER); + + /* Store rval and pop stack back to our frame's sp. */ + *rval = fp->sp[-1]; + fp->sp = oldsp; + js_FreeStack(cx, mark); + return ok; +} +#endif /* JS_HAS_CALL_FUNCTION */ + +#if JS_HAS_APPLY_FUNCTION +static JSBool +fun_apply(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + jsval fval, *sp, *oldsp; + JSObject *aobj; + jsuint length; + void *mark; + uintN i; + JSBool ok; + JSStackFrame *fp; + + if (argc == 0) { + /* Will get globalObject as 'this' and no other agurments. */ + return fun_call(cx, obj, argc, argv, rval); + } + + if (!OBJ_DEFAULT_VALUE(cx, obj, JSTYPE_FUNCTION, &argv[-1])) + return JS_FALSE; + fval = argv[-1]; + + if (!JSVAL_IS_FUNCTION(cx, fval)) { + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, + JSMSG_INCOMPATIBLE_PROTO, + js_Function_str, "apply", + JS_GetStringBytes(JS_ValueToString(cx, fval))); + return JS_FALSE; + } + + /* Quell GCC overwarnings. */ + aobj = NULL; + length = 0; + + if (argc >= 2) { + /* If the 2nd arg is null or void, call the function with 0 args. */ + if (JSVAL_IS_NULL(argv[1]) || JSVAL_IS_VOID(argv[1])) { + argc = 0; + } else { + /* The second arg must be an array (or arguments object). */ + if (JSVAL_IS_PRIMITIVE(argv[1]) || + (aobj = JSVAL_TO_OBJECT(argv[1]), + OBJ_GET_CLASS(cx, aobj) != &js_ArgumentsClass && + OBJ_GET_CLASS(cx, aobj) != &js_ArrayClass)) + { + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, + JSMSG_BAD_APPLY_ARGS); + return JS_FALSE; + } + if (!js_GetLengthProperty(cx, aobj, &length)) + return JS_FALSE; + } + } + + /* Convert the first arg to 'this' and skip over it. */ + if (!js_ValueToObject(cx, argv[0], &obj)) + return JS_FALSE; + + /* Allocate stack space for fval, obj, and the args. */ + argc = (uintN)JS_MIN(length, ARGC_LIMIT - 1); + sp = js_AllocStack(cx, 2 + argc, &mark); + if (!sp) + return JS_FALSE; + + /* Push fval, obj, and aobj's elements as args. */ + *sp++ = fval; + *sp++ = OBJECT_TO_JSVAL(obj); + for (i = 0; i < argc; i++) { + ok = JS_GetElement(cx, aobj, (jsint)i, sp); + if (!ok) + goto out; + sp++; + } + + /* Lift current frame to include the args and do the call. */ + fp = cx->fp; + oldsp = fp->sp; + fp->sp = sp; + ok = js_Invoke(cx, argc, JSINVOKE_INTERNAL | JSINVOKE_SKIP_CALLER); + + /* Store rval and pop stack back to our frame's sp. */ + *rval = fp->sp[-1]; + fp->sp = oldsp; +out: + js_FreeStack(cx, mark); + return ok; +} +#endif /* JS_HAS_APPLY_FUNCTION */ + +static JSFunctionSpec function_methods[] = { +#if JS_HAS_TOSOURCE + {js_toSource_str, fun_toSource, 0,0,0}, +#endif + {js_toString_str, fun_toString, 1,0,0}, +#if JS_HAS_APPLY_FUNCTION + {"apply", fun_apply, 2,0,0}, +#endif +#if JS_HAS_CALL_FUNCTION + {js_call_str, fun_call, 1,0,0}, +#endif + {0,0,0,0,0} +}; + +JSBool +js_IsIdentifier(JSString *str) +{ + size_t n; + jschar *s, c; + + n = JSSTRING_LENGTH(str); + if (n == 0) + return JS_FALSE; + s = JSSTRING_CHARS(str); + c = *s; + if (!JS_ISIDENT_START(c)) + return JS_FALSE; + for (n--; n != 0; n--) { + c = *++s; + if (!JS_ISIDENT(c)) + return JS_FALSE; + } + return JS_TRUE; +} + +static JSBool +Function(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + JSStackFrame *fp, *caller; + JSFunction *fun; + JSObject *parent; + uintN i, n, lineno, dupflag; + JSAtom *atom; + const char *filename; + JSObject *obj2; + JSScopeProperty *sprop; + JSString *str, *arg; + void *mark; + JSTokenStream *ts; + JSPrincipals *principals; + jschar *collected_args, *cp; + size_t arg_length, args_length; + JSTokenType tt; + JSBool ok; + + fp = cx->fp; + if (fp && !(fp->flags & JSFRAME_CONSTRUCTING)) { + obj = js_NewObject(cx, &js_FunctionClass, NULL, NULL); + if (!obj) + return JS_FALSE; + *rval = OBJECT_TO_JSVAL(obj); + } + fun = (JSFunction *) JS_GetPrivate(cx, obj); + if (fun) + return JS_TRUE; + +#if JS_HAS_CALL_OBJECT + /* + * NB: (new Function) is not lexically closed by its caller, it's just an + * anonymous function in the top-level scope that its constructor inhabits. + * Thus 'var x = 42; f = new Function("return x"); print(f())' prints 42, + * and so would a call to f from another top-level's script or function. + * + * In older versions, before call objects, a new Function was adopted by + * its running context's globalObject, which might be different from the + * top-level reachable from scopeChain (in HTML frames, e.g.). + */ + parent = OBJ_GET_PARENT(cx, JSVAL_TO_OBJECT(argv[-2])); +#else + /* Set up for dynamic parenting (see js_Invoke in jsinterp.c). */ + parent = NULL; +#endif + + fun = js_NewFunction(cx, obj, NULL, 0, JSFUN_LAMBDA, parent, + JSVERSION_IS_ECMA(cx->version) + ? cx->runtime->atomState.anonymousAtom + : NULL); + + if (!fun) + return JS_FALSE; + + /* + * Function is static and not called directly by other functions in this + * file, therefore it is callable only as a native function by js_Invoke. + * Find the scripted caller, possibly skipping other native frames such as + * are built for Function.prototype.call or .apply activations that invoke + * Function indirectly from a script. + */ + JS_ASSERT(!fp->script && fp->fun && fp->fun->native == Function); + caller = JS_GetScriptedCaller(cx, fp); + if (caller) { + filename = caller->script->filename; + lineno = js_PCToLineNumber(cx, caller->script, caller->pc); + principals = JS_EvalFramePrincipals(cx, fp, caller); + } else { + filename = NULL; + lineno = 0; + principals = NULL; + } + + n = argc ? argc - 1 : 0; + if (n > 0) { + /* + * Collect the function-argument arguments into one string, separated + * by commas, then make a tokenstream from that string, and scan it to + * get the arguments. We need to throw the full scanner at the + * problem, because the argument string can legitimately contain + * comments and linefeeds. XXX It might be better to concatenate + * everything up into a function definition and pass it to the + * compiler, but doing it this way is less of a delta from the old + * code. See ECMA 15.3.2.1. + */ + args_length = 0; + for (i = 0; i < n; i++) { + /* Collect the lengths for all the function-argument arguments. */ + arg = js_ValueToString(cx, argv[i]); + if (!arg) + return JS_FALSE; + argv[i] = STRING_TO_JSVAL(arg); + args_length += JSSTRING_LENGTH(arg); + } + /* Add 1 for each joining comma. */ + args_length += n - 1; + + /* + * Allocate a string to hold the concatenated arguments, including room + * for a terminating 0. Mark cx->tempPool for later release, to free + * collected_args and its tokenstream in one swoop. + */ + mark = JS_ARENA_MARK(&cx->tempPool); + JS_ARENA_ALLOCATE_CAST(cp, jschar *, &cx->tempPool, + (args_length+1) * sizeof(jschar)); + if (!cp) + return JS_FALSE; + collected_args = cp; + + /* + * Concatenate the arguments into the new string, separated by commas. + */ + for (i = 0; i < n; i++) { + arg = JSVAL_TO_STRING(argv[i]); + arg_length = JSSTRING_LENGTH(arg); + (void) js_strncpy(cp, JSSTRING_CHARS(arg), arg_length); + cp += arg_length; + + /* Add separating comma or terminating 0. */ + *cp++ = (i + 1 < n) ? ',' : 0; + } + + /* + * Make a tokenstream (allocated from cx->tempPool) that reads from + * the given string. + */ + ts = js_NewTokenStream(cx, collected_args, args_length, filename, + lineno, principals); + if (!ts) { + JS_ARENA_RELEASE(&cx->tempPool, mark); + return JS_FALSE; + } + + /* The argument string may be empty or contain no tokens. */ + tt = js_GetToken(cx, ts); + if (tt != TOK_EOF) { + for (;;) { + /* + * Check that it's a name. This also implicitly guards against + * TOK_ERROR, which was already reported. + */ + if (tt != TOK_NAME) + goto bad_formal; + + /* + * Get the atom corresponding to the name from the tokenstream; + * we're assured at this point that it's a valid identifier. + */ + atom = CURRENT_TOKEN(ts).t_atom; + if (!js_LookupProperty(cx, obj, (jsid)atom, &obj2, + (JSProperty **)&sprop)) { + goto bad_formal; + } + dupflag = 0; + if (sprop) { + ok = JS_TRUE; + if (obj2 == obj) { + const char *name = js_AtomToPrintableString(cx, atom); + + /* + * A duplicate parameter name. We force a duplicate + * node on the SCOPE_LAST_PROP(scope) list with the + * same id, distinguished by the SPROP_IS_DUPLICATE + * flag, and not mapped by an entry in scope. + */ + JS_ASSERT(sprop->getter == js_GetArgument); + ok = name && + js_ReportCompileErrorNumber(cx, ts, NULL, + JSREPORT_WARNING | + JSREPORT_STRICT, + JSMSG_DUPLICATE_FORMAL, + name); + + dupflag = SPROP_IS_DUPLICATE; + } + OBJ_DROP_PROPERTY(cx, obj2, (JSProperty *)sprop); + if (!ok) + goto bad_formal; + sprop = NULL; + } + if (!js_AddNativeProperty(cx, fun->object, (jsid)atom, + js_GetArgument, js_SetArgument, + SPROP_INVALID_SLOT, + JSPROP_ENUMERATE | JSPROP_PERMANENT | + JSPROP_SHARED, + SPROP_HAS_SHORTID | dupflag, + fun->nargs)) { + goto bad_formal; + } + fun->nargs++; + + /* + * Get the next token. Stop on end of stream. Otherwise + * insist on a comma, get another name, and iterate. + */ + tt = js_GetToken(cx, ts); + if (tt == TOK_EOF) + break; + if (tt != TOK_COMMA) + goto bad_formal; + tt = js_GetToken(cx, ts); + } + } + + /* Clean up. */ + ok = js_CloseTokenStream(cx, ts); + JS_ARENA_RELEASE(&cx->tempPool, mark); + if (!ok) + return JS_FALSE; + } + + if (argc) { + str = js_ValueToString(cx, argv[argc-1]); + } else { + /* Can't use cx->runtime->emptyString because we're called too early. */ + str = js_NewStringCopyZ(cx, js_empty_ucstr, 0); + } + if (!str) + return JS_FALSE; + if (argv) { + /* Use the last arg (or this if argc == 0) as a local GC root. */ + argv[(intN)(argc-1)] = STRING_TO_JSVAL(str); + } + + mark = JS_ARENA_MARK(&cx->tempPool); + ts = js_NewTokenStream(cx, JSSTRING_CHARS(str), JSSTRING_LENGTH(str), + filename, lineno, principals); + if (!ts) { + ok = JS_FALSE; + } else { + ok = js_CompileFunctionBody(cx, ts, fun) && + js_CloseTokenStream(cx, ts); + } + JS_ARENA_RELEASE(&cx->tempPool, mark); + return ok; + +bad_formal: + /* + * Report "malformed formal parameter" iff no illegal char or similar + * scanner error was already reported. + */ + if (!(ts->flags & TSF_ERROR)) + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BAD_FORMAL); + + /* + * Clean up the arguments string and tokenstream if we failed to parse + * the arguments. + */ + (void)js_CloseTokenStream(cx, ts); + JS_ARENA_RELEASE(&cx->tempPool, mark); + return JS_FALSE; +} + +JSObject * +js_InitFunctionClass(JSContext *cx, JSObject *obj) +{ + JSObject *proto; + JSAtom *atom; + JSFunction *fun; + + proto = JS_InitClass(cx, obj, NULL, &js_FunctionClass, Function, 1, + function_props, function_methods, NULL, NULL); + if (!proto) + return NULL; + atom = js_Atomize(cx, js_FunctionClass.name, strlen(js_FunctionClass.name), + 0); + if (!atom) + goto bad; + fun = js_NewFunction(cx, proto, NULL, 0, 0, obj, NULL); + if (!fun) + goto bad; + fun->script = js_NewScript(cx, 0, 0, 0); + if (!fun->script) + goto bad; + return proto; + +bad: + cx->newborn[GCX_OBJECT] = NULL; + return NULL; +} + +#if JS_HAS_CALL_OBJECT +JSObject * +js_InitCallClass(JSContext *cx, JSObject *obj) +{ + return JS_InitClass(cx, obj, NULL, &js_CallClass, NULL, 0, + call_props, NULL, NULL, NULL); +} +#endif + +JSFunction * +js_NewFunction(JSContext *cx, JSObject *funobj, JSNative native, uintN nargs, + uintN flags, JSObject *parent, JSAtom *atom) +{ + JSFunction *fun; + + /* Allocate a function struct. */ + fun = (JSFunction *) JS_malloc(cx, sizeof *fun); + if (!fun) + return NULL; + + /* If funobj is null, allocate an object for it. */ + if (funobj) { + OBJ_SET_PARENT(cx, funobj, parent); + } else { + funobj = js_NewObject(cx, &js_FunctionClass, NULL, parent); + if (!funobj) { + JS_free(cx, fun); + return NULL; + } + } + + /* Initialize all function members. */ + fun->nrefs = 0; + fun->object = NULL; + fun->native = native; + fun->script = NULL; + fun->nargs = nargs; + fun->extra = 0; + fun->nvars = 0; + fun->flags = flags & JSFUN_FLAGS_MASK; + fun->spare = 0; + fun->atom = atom; + fun->clasp = NULL; + + /* Link fun to funobj and vice versa. */ + if (!js_LinkFunctionObject(cx, fun, funobj)) { + cx->newborn[GCX_OBJECT] = NULL; + JS_free(cx, fun); + return NULL; + } + return fun; +} + +JSObject * +js_CloneFunctionObject(JSContext *cx, JSObject *funobj, JSObject *parent) +{ + JSObject *newfunobj; + JSFunction *fun; + + JS_ASSERT(OBJ_GET_CLASS(cx, funobj) == &js_FunctionClass); + newfunobj = js_NewObject(cx, &js_FunctionClass, funobj, parent); + if (!newfunobj) + return NULL; + fun = (JSFunction *) JS_GetPrivate(cx, funobj); + if (!js_LinkFunctionObject(cx, fun, newfunobj)) { + cx->newborn[GCX_OBJECT] = NULL; + return NULL; + } + return newfunobj; +} + +JSBool +js_LinkFunctionObject(JSContext *cx, JSFunction *fun, JSObject *funobj) +{ + if (!fun->object) + fun->object = funobj; + if (!JS_SetPrivate(cx, funobj, fun)) + return JS_FALSE; + JS_ATOMIC_INCREMENT(&fun->nrefs); + return JS_TRUE; +} + +JSFunction * +js_DefineFunction(JSContext *cx, JSObject *obj, JSAtom *atom, JSNative native, + uintN nargs, uintN attrs) +{ + JSFunction *fun; + + fun = js_NewFunction(cx, NULL, native, nargs, attrs, obj, atom); + if (!fun) + return NULL; + if (!OBJ_DEFINE_PROPERTY(cx, obj, (jsid)atom, OBJECT_TO_JSVAL(fun->object), + NULL, NULL, attrs & ~JSFUN_FLAGS_MASK, NULL)) { + return NULL; + } + return fun; +} + +#if (JSV2F_CONSTRUCT & JSV2F_SEARCH_STACK) +# error "JSINVOKE_CONSTRUCT and JSV2F_SEARCH_STACK are not disjoint!" +#endif + +JSFunction * +js_ValueToFunction(JSContext *cx, jsval *vp, uintN flags) +{ + jsval v; + JSObject *obj; + + v = *vp; + obj = NULL; + if (JSVAL_IS_OBJECT(v)) { + obj = JSVAL_TO_OBJECT(v); + if (obj && OBJ_GET_CLASS(cx, obj) != &js_FunctionClass) { + if (!OBJ_DEFAULT_VALUE(cx, obj, JSTYPE_FUNCTION, &v)) + return NULL; + obj = JSVAL_IS_FUNCTION(cx, v) ? JSVAL_TO_OBJECT(v) : NULL; + } + } + if (!obj) { + js_ReportIsNotFunction(cx, vp, flags); + return NULL; + } + return (JSFunction *) JS_GetPrivate(cx, obj); +} + +void +js_ReportIsNotFunction(JSContext *cx, jsval *vp, uintN flags) +{ + JSType type; + JSString *fallback; + JSString *str; + + /* + * We provide the typename as the fallback to handle the case when + * valueOf is not a function, which prevents ValueToString from being + * called as the default case inside js_DecompileValueGenerator (and + * so recursing back to here). + */ + type = JS_TypeOfValue(cx, *vp); + fallback = ATOM_TO_STRING(cx->runtime->atomState.typeAtoms[type]); + str = js_DecompileValueGenerator(cx, + (flags & JSV2F_SEARCH_STACK) + ? JSDVG_SEARCH_STACK + : cx->fp + ? vp - cx->fp->sp + : JSDVG_IGNORE_STACK, + *vp, + fallback); + if (str) { + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, + (uintN)((flags & JSV2F_CONSTRUCT) + ? JSMSG_NOT_CONSTRUCTOR + : JSMSG_NOT_FUNCTION), + JS_GetStringBytes(str)); + } +} diff --git a/src/dom/js/jsfun.h b/src/dom/js/jsfun.h new file mode 100644 index 000000000..0a3237921 --- /dev/null +++ b/src/dom/js/jsfun.h @@ -0,0 +1,151 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef jsfun_h___ +#define jsfun_h___ +/* + * JS function definitions. + */ +#include "jsprvtd.h" +#include "jspubtd.h" + +JS_BEGIN_EXTERN_C + +struct JSFunction { + jsrefcount nrefs; /* number of referencing objects */ + JSObject *object; /* back-pointer to GC'ed object header */ + JSNative native; /* native method pointer or null */ + JSScript *script; /* interpreted bytecode descriptor or null */ + uint16 nargs; /* minimum number of actual arguments */ + uint16 extra; /* number of arg slots for local GC roots */ + uint16 nvars; /* number of local variables */ + uint8 flags; /* bound method and other flags, see jsapi.h */ + uint8 spare; /* reserved for future use */ + JSAtom *atom; /* name for diagnostics and decompiling */ + JSClass *clasp; /* if non-null, constructor for this class */ +}; + +extern JSClass js_ArgumentsClass; +extern JSClass js_CallClass; + +/* JS_FRIEND_DATA so that JSVAL_IS_FUNCTION is callable from outside */ +extern JS_FRIEND_DATA(JSClass) js_FunctionClass; + +/* + * NB: jsapi.h and jsobj.h must be included before any call to this macro. + */ +#define JSVAL_IS_FUNCTION(cx, v) \ + (JSVAL_IS_OBJECT(v) && JSVAL_TO_OBJECT(v) && \ + OBJ_GET_CLASS(cx, JSVAL_TO_OBJECT(v)) == &js_FunctionClass) + +extern JSBool +js_fun_toString(JSContext *cx, JSObject *obj, uint32 indent, + uintN argc, jsval *argv, jsval *rval); + +extern JSBool +js_IsIdentifier(JSString *str); + +extern JSObject * +js_InitFunctionClass(JSContext *cx, JSObject *obj); + +extern JSObject * +js_InitArgumentsClass(JSContext *cx, JSObject *obj); + +extern JSObject * +js_InitCallClass(JSContext *cx, JSObject *obj); + +extern JSFunction * +js_NewFunction(JSContext *cx, JSObject *funobj, JSNative native, uintN nargs, + uintN flags, JSObject *parent, JSAtom *atom); + +extern JSObject * +js_CloneFunctionObject(JSContext *cx, JSObject *funobj, JSObject *parent); + +extern JSBool +js_LinkFunctionObject(JSContext *cx, JSFunction *fun, JSObject *object); + +extern JSFunction * +js_DefineFunction(JSContext *cx, JSObject *obj, JSAtom *atom, JSNative native, + uintN nargs, uintN flags); + +/* + * Flags for js_ValueToFunction and js_ReportIsNotFunction. We depend on the + * fact that JSINVOKE_CONSTRUCT (aka JSFRAME_CONSTRUCTING) is 1, and test that + * with #if/#error in jsfun.c. + */ +#define JSV2F_CONSTRUCT JSINVOKE_CONSTRUCT +#define JSV2F_SEARCH_STACK 2 + +extern JSFunction * +js_ValueToFunction(JSContext *cx, jsval *vp, uintN flags); + +extern void +js_ReportIsNotFunction(JSContext *cx, jsval *vp, uintN flags); + +extern JSObject * +js_GetCallObject(JSContext *cx, JSStackFrame *fp, JSObject *parent); + +extern JSBool +js_PutCallObject(JSContext *cx, JSStackFrame *fp); + +extern JSBool +js_GetCallVariable(JSContext *cx, JSObject *obj, jsval id, jsval *vp); + +extern JSBool +js_SetCallVariable(JSContext *cx, JSObject *obj, jsval id, jsval *vp); + +extern JSBool +js_GetArgsValue(JSContext *cx, JSStackFrame *fp, jsval *vp); + +extern JSBool +js_GetArgsProperty(JSContext *cx, JSStackFrame *fp, jsid id, + JSObject **objp, jsval *vp); + +extern JSObject * +js_GetArgsObject(JSContext *cx, JSStackFrame *fp); + +extern JSBool +js_PutArgsObject(JSContext *cx, JSStackFrame *fp); + +extern JSBool +js_XDRFunction(JSXDRState *xdr, JSObject **objp); + +JS_END_EXTERN_C + +#endif /* jsfun_h___ */ diff --git a/src/dom/js/jsgc.c b/src/dom/js/jsgc.c new file mode 100644 index 000000000..a0efec4d7 --- /dev/null +++ b/src/dom/js/jsgc.c @@ -0,0 +1,1423 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* + * JS Mark-and-Sweep Garbage Collector. + * + * This GC allocates only fixed-sized things big enough to contain two words + * (pointers) on any host architecture. It allocates from an arena pool (see + * jsarena.h). It uses an ideally parallel array of flag bytes to hold the + * mark bit, finalizer type index, etc. + * + * XXX swizzle page to freelist for better locality of reference + */ +#include "jsstddef.h" +#include /* for free, called by JS_ARENA_DESTROY */ +#include /* for memset, called by jsarena.h macros if DEBUG */ +#include "jstypes.h" +#include "jsarena.h" /* Added by JSIFY */ +#include "jsutil.h" /* Added by JSIFY */ +#include "jshash.h" /* Added by JSIFY */ +#include "jsapi.h" +#include "jsatom.h" +#include "jscntxt.h" +#include "jsconfig.h" +#include "jsdbgapi.h" +#include "jsfun.h" +#include "jsgc.h" +#include "jsinterp.h" +#include "jslock.h" +#include "jsnum.h" +#include "jsobj.h" +#include "jsscope.h" +#include "jsscript.h" +#include "jsstr.h" + +/* + * GC arena sizing depends on amortizing arena overhead using a large number + * of things per arena, and on the thing/flags ratio of 8:1 on most platforms. + * + * On 64-bit platforms, we would have half as many things per arena because + * pointers are twice as big, so we double the bytes for things per arena. + * This preserves the 1024 byte flags sub-arena size, which relates to the + * GC_PAGE_SIZE (see below for why). + */ +#if JS_BYTES_PER_WORD == 8 +# define GC_THINGS_SHIFT 14 /* 16KB for things on Alpha, etc. */ +#else +# define GC_THINGS_SHIFT 13 /* 8KB for things on most platforms */ +#endif +#define GC_THINGS_SIZE JS_BIT(GC_THINGS_SHIFT) +#define GC_FLAGS_SIZE (GC_THINGS_SIZE / sizeof(JSGCThing)) +#define GC_ARENA_SIZE (GC_THINGS_SIZE + GC_FLAGS_SIZE) + +/* + * The private JSGCThing struct, which describes a gcFreeList element. + */ +struct JSGCThing { + JSGCThing *next; + uint8 *flagp; +}; + +/* + * A GC arena contains one flag byte for each thing in its heap, and supports + * O(1) lookup of a flag given its thing's address. + * + * To implement this, we take advantage of the thing/flags numerology: given + * the 8K bytes worth of GC-things, there are 1K flag bytes. We mask a thing's + * address with ~1023 to find a JSGCPageInfo record at the front of a mythical + * "GC page" within the larger 8K thing arena. That JSGCPageInfo contains a + * pointer to the 128 flag bytes corresponding to the things in the page, so we + * index into this flags array using the thing's index within its page. + * + * To align thing pages on 1024-byte boundaries, we must allocate the 9KB of + * flags+things arena payload, then find the first 0 mod 1024 boundary after + * the first payload address. That's where things start, with a JSGCPageInfo + * taking up the first thing-slot, as usual for 0 mod 1024 byte boundaries. + * The effect of this alignment trick is to split the flags into at most 2 + * discontiguous spans, one before the things and one after (if we're really + * lucky, and the arena payload starts on a 0 mod 1024 byte boundary, no need + * to split). + * + * The overhead of this scheme for most platforms is (16+8*(8+1))/(16+9K) or + * .95% (assuming 16 byte JSArena header size, and 8 byte JSGCThing size). + * + * Here's some ASCII art showing an arena: + * + * split + * | + * V + * +--+-------+-------+-------+-------+-------+-------+-------+-------+-----+ + * |fB| tp0 | tp1 | tp2 | tp3 | tp4 | tp5 | tp6 | tp7 | fA | + * +--+-------+-------+-------+-------+-------+-------+-------+-------+-----+ + * ^ ^ + * tI ---------+ | + * tJ -------------------------------------------+ + * + * - fB are the "before split" flags, fA are the "after split" flags + * - tp0-tp7 are the 8 thing pages + * - thing tI points into tp1, whose flags are below the split, in fB + * - thing tJ points into tp5, clearly above the split + * + * In general, one of the thing pages will have some of its things' flags on + * the low side of the split, and the rest of its things' flags on the high + * side. All the other pages have flags only below or only above. Therefore + * we'll have to test something to decide whether the split divides flags in + * a given thing's page. So we store the split pointer (the pointer to tp0) + * in each JSGCPageInfo, along with the flags pointer for the 128 flag bytes + * ideally starting, for tp0 things, at the beginning of the arena's payload + * (at the start of fB). + * + * That is, each JSGCPageInfo's flags pointer is 128 bytes from the previous, + * or at the start of the arena if there is no previous page in this arena. + * Thus these ideal 128-byte flag pages run contiguously from the start of the + * arena (right over the split!), and the JSGCPageInfo flags pointers contain + * no discontinuities over the split created by the thing pages. So if, for a + * given JSGCPageInfo *pi, we find that + * + * pi->flags + ((jsuword)thing % 1024) / sizeof(JSGCThing) >= pi->split + * + * then we must add GC_THINGS_SIZE to the nominal flags pointer to jump over + * all the thing pages that split the flags into two discontiguous spans. + * + * (If we need to implement card-marking for an incremental GC write barrier, + * we can use the low byte of the pi->split pointer as the card-mark, for an + * extremely efficient write barrier: when mutating an object obj, just store + * a 1 byte at (uint8 *) ((jsuword)obj & ~1023) for little-endian platforms. + * When finding flags, we'll of course have to mask split with ~255, but it is + * guaranteed to be 1024-byte aligned, so no information is lost by overlaying + * the card-mark byte on split's low byte.) + */ +#define GC_PAGE_SHIFT 10 +#define GC_PAGE_MASK ((jsuword) JS_BITMASK(GC_PAGE_SHIFT)) +#define GC_PAGE_SIZE JS_BIT(GC_PAGE_SHIFT) + +typedef struct JSGCPageInfo { + uint8 *split; + uint8 *flags; +} JSGCPageInfo; + +#define FIRST_THING_PAGE(a) (((a)->base + GC_FLAGS_SIZE) & ~GC_PAGE_MASK) + +static JSGCThing * +gc_new_arena(JSArenaPool *pool) +{ + uint8 *flagp, *split, *pagep, *limit; + JSArena *a; + JSGCThing *thing; + JSGCPageInfo *pi; + + /* Use JS_ArenaAllocate to grab another 9K-net-size hunk of space. */ + flagp = (uint8 *) JS_ArenaAllocate(pool, GC_ARENA_SIZE); + if (!flagp) + return NULL; + a = pool->current; + + /* Reset a->avail to start at the flags split, aka the first thing page. */ + a->avail = FIRST_THING_PAGE(a); + split = pagep = (uint8 *) a->avail; + a->avail += sizeof(JSGCPageInfo); + thing = (JSGCThing *) a->avail; + a->avail += sizeof(JSGCThing); + + /* Initialize the JSGCPageInfo records at the start of every thing page. */ + limit = pagep + GC_THINGS_SIZE; + do { + pi = (JSGCPageInfo *) pagep; + pi->split = split; + pi->flags = flagp; + flagp += GC_PAGE_SIZE >> (GC_THINGS_SHIFT - GC_PAGE_SHIFT); + pagep += GC_PAGE_SIZE; + } while (pagep < limit); + return thing; +} + +uint8 * +js_GetGCThingFlags(void *thing) +{ + JSGCPageInfo *pi; + uint8 *flagp; + + pi = (JSGCPageInfo *) ((jsuword)thing & ~GC_PAGE_MASK); + flagp = pi->flags + ((jsuword)thing & GC_PAGE_MASK) / sizeof(JSGCThing); + if (flagp >= pi->split) + flagp += GC_THINGS_SIZE; + return flagp; +} + +JSBool +js_IsAboutToBeFinalized(JSContext *cx, void *thing) +{ + uint8 flags = *js_GetGCThingFlags(thing); + + return !(flags & (GCF_MARK | GCF_LOCKMASK | GCF_FINAL)); +} + +typedef void (*GCFinalizeOp)(JSContext *cx, JSGCThing *thing); + +static GCFinalizeOp gc_finalizers[GCX_NTYPES]; + +intN +js_ChangeExternalStringFinalizer(JSStringFinalizeOp oldop, + JSStringFinalizeOp newop) +{ + uintN i; + + for (i = GCX_EXTERNAL_STRING; i < GCX_NTYPES; i++) { + if (gc_finalizers[i] == (GCFinalizeOp) oldop) { + gc_finalizers[i] = (GCFinalizeOp) newop; + return (intN) i; + } + } + return -1; +} + +#ifdef JS_GCMETER +#define METER(x) x +#else +#define METER(x) /* nothing */ +#endif + +/* Initial size of the gcRootsHash table (SWAG, small enough to amortize). */ +#define GC_ROOTS_SIZE 256 +#define GC_FINALIZE_LEN 1024 + +JSBool +js_InitGC(JSRuntime *rt, uint32 maxbytes) +{ + JS_ASSERT(sizeof(JSGCThing) == sizeof(JSGCPageInfo)); + JS_ASSERT(sizeof(JSGCThing) >= sizeof(JSObject)); + JS_ASSERT(sizeof(JSGCThing) >= sizeof(JSString)); + JS_ASSERT(sizeof(JSGCThing) >= sizeof(jsdouble)); + JS_ASSERT(GC_FLAGS_SIZE >= GC_PAGE_SIZE); + JS_ASSERT(sizeof(JSStackHeader) >= 2 * sizeof(jsval)); + + if (!gc_finalizers[GCX_OBJECT]) { + gc_finalizers[GCX_OBJECT] = (GCFinalizeOp)js_FinalizeObject; + gc_finalizers[GCX_STRING] = (GCFinalizeOp)js_FinalizeString; +#ifdef DEBUG + gc_finalizers[GCX_DOUBLE] = (GCFinalizeOp)js_FinalizeDouble; +#endif + gc_finalizers[GCX_MUTABLE_STRING] = (GCFinalizeOp)js_FinalizeString; + } + + JS_InitArenaPool(&rt->gcArenaPool, "gc-arena", GC_ARENA_SIZE, + sizeof(JSGCThing)); + if (!JS_DHashTableInit(&rt->gcRootsHash, JS_DHashGetStubOps(), NULL, + sizeof(JSGCRootHashEntry), GC_ROOTS_SIZE)) { + rt->gcRootsHash.ops = NULL; + return JS_FALSE; + } + rt->gcLocksHash = NULL; /* create lazily */ + rt->gcMaxBytes = maxbytes; + return JS_TRUE; +} + +#ifdef JS_GCMETER +void +js_DumpGCStats(JSRuntime *rt, FILE *fp) +{ + fprintf(fp, "\nGC allocation statistics:\n"); + fprintf(fp, " bytes currently allocated: %lu\n", rt->gcBytes); + fprintf(fp, " alloc attempts: %lu\n", rt->gcStats.alloc); + fprintf(fp, " GC freelist length: %lu\n", rt->gcStats.freelen); + fprintf(fp, " recycles through GC freelist: %lu\n", rt->gcStats.recycle); + fprintf(fp, "alloc retries after running GC: %lu\n", rt->gcStats.retry); + fprintf(fp, " allocation failures: %lu\n", rt->gcStats.fail); + fprintf(fp, " valid lock calls: %lu\n", rt->gcStats.lock); + fprintf(fp, " valid unlock calls: %lu\n", rt->gcStats.unlock); + fprintf(fp, " locks that hit stuck counts: %lu\n", rt->gcStats.stuck); + fprintf(fp, " unlocks that saw stuck counts: %lu\n", rt->gcStats.unstuck); + fprintf(fp, " mark recursion depth: %lu\n", rt->gcStats.depth); + fprintf(fp, " maximum mark recursion depth: %lu\n", rt->gcStats.maxdepth); + fprintf(fp, " maximum GC nesting level: %lu\n", rt->gcStats.maxlevel); + fprintf(fp, " potentially useful GC calls: %lu\n", rt->gcStats.poke); + fprintf(fp, " useless GC calls: %lu\n", rt->gcStats.nopoke); + fprintf(fp, " thing arenas freed so far: %lu\n", rt->gcStats.afree); + fprintf(fp, " extra stack segments scanned: %lu\n", rt->gcStats.stackseg); + fprintf(fp, " stack segment slots scanned: %lu\n", rt->gcStats.segslots); +#ifdef JS_ARENAMETER + JS_DumpArenaStats(fp); +#endif +} +#endif + +#ifdef DEBUG +JS_STATIC_DLL_CALLBACK(JSDHashOperator) +js_root_printer(JSDHashTable *table, JSDHashEntryHdr *hdr, uint32 i, void *arg) +{ + uint32 *leakedroots = (uint32 *)arg; + JSGCRootHashEntry *rhe = (JSGCRootHashEntry *)hdr; + + (*leakedroots)++; + fprintf(stderr, + "JS engine warning: leaking GC root \'%s\' at %p\n", + rhe->name ? (char *)rhe->name : "", rhe->root); + + return JS_DHASH_NEXT; +} +#endif + +void +js_FinishGC(JSRuntime *rt) +{ +#ifdef JS_ARENAMETER + JS_DumpArenaStats(stdout); +#endif +#ifdef JS_GCMETER + js_DumpGCStats(rt, stdout); +#endif + JS_FinishArenaPool(&rt->gcArenaPool); + JS_ArenaFinish(); + + if (rt->gcRootsHash.ops) { +#ifdef DEBUG + uint32 leakedroots = 0; + + /* Warn (but don't assert) debug builds of any remaining roots. */ + JS_DHashTableEnumerate(&rt->gcRootsHash, js_root_printer, + &leakedroots); + if (leakedroots > 0) { + if (leakedroots == 1) { + fprintf(stderr, +"JS engine warning: 1 GC root remains after destroying the JSRuntime.\n" +" This root may point to freed memory. Objects reachable\n" +" through it have not been finalized.\n"); + } else { + fprintf(stderr, +"JS engine warning: %lu GC roots remain after destroying the JSRuntime.\n" +" These roots may point to freed memory. Objects reachable\n" +" through them have not been finalized.\n", + (unsigned long) leakedroots); + } + } +#endif + + JS_DHashTableFinish(&rt->gcRootsHash); + rt->gcRootsHash.ops = NULL; + } + if (rt->gcLocksHash) { + JS_DHashTableDestroy(rt->gcLocksHash); + rt->gcLocksHash = NULL; + } + rt->gcFreeList = NULL; +} + +JSBool +js_AddRoot(JSContext *cx, void *rp, const char *name) +{ + JSBool ok = js_AddRootRT(cx->runtime, rp, name); + if (!ok) + JS_ReportOutOfMemory(cx); + return ok; +} + +JSBool +js_AddRootRT(JSRuntime *rt, void *rp, const char *name) +{ + JSBool ok; + JSGCRootHashEntry *rhe; + + /* + * Due to the long-standing, but now removed, use of rt->gcLock across the + * bulk of js_GC, API users have come to depend on JS_AddRoot etc. locking + * properly with a racing GC, without calling JS_AddRoot from a request. + * We have to preserve API compatibility here, now that we avoid holding + * rt->gcLock across the mark phase (including the root hashtable mark). + * + * If the GC is running and we're called on another thread, wait for this + * GC activation to finish. We can safely wait here (in the case where we + * are called within a request on another thread's context) without fear + * of deadlock because the GC doesn't set rt->gcRunning until after it has + * waited for all active requests to end. + */ + JS_LOCK_GC(rt); +#ifdef JS_THREADSAFE + JS_ASSERT(!rt->gcRunning || rt->gcLevel > 0); + if (rt->gcRunning && rt->gcThread != js_CurrentThreadId()) { + do { + JS_AWAIT_GC_DONE(rt); + } while (rt->gcLevel > 0); + } +#endif + rhe = (JSGCRootHashEntry *) JS_DHashTableOperate(&rt->gcRootsHash, rp, + JS_DHASH_ADD); + if (rhe) { + rhe->root = rp; + rhe->name = name; + ok = JS_TRUE; + } else { + ok = JS_FALSE; + } + JS_UNLOCK_GC(rt); + return ok; +} + +JSBool +js_RemoveRoot(JSRuntime *rt, void *rp) +{ + /* + * Due to the JS_RemoveRootRT API, we may be called outside of a request. + * Same synchronization drill as above in js_AddRoot. + */ + JS_LOCK_GC(rt); +#ifdef JS_THREADSAFE + JS_ASSERT(!rt->gcRunning || rt->gcLevel > 0); + if (rt->gcRunning && rt->gcThread != js_CurrentThreadId()) { + do { + JS_AWAIT_GC_DONE(rt); + } while (rt->gcLevel > 0); + } +#endif + (void) JS_DHashTableOperate(&rt->gcRootsHash, rp, JS_DHASH_REMOVE); + rt->gcPoke = JS_TRUE; + JS_UNLOCK_GC(rt); + return JS_TRUE; +} + +void * +js_AllocGCThing(JSContext *cx, uintN flags) +{ + JSBool tried_gc; + JSRuntime *rt; + JSGCThing *thing; + uint8 *flagp; + +#ifdef TOO_MUCH_GC + js_GC(cx, GC_KEEP_ATOMS); + tried_gc = JS_TRUE; +#else + tried_gc = JS_FALSE; +#endif + + rt = cx->runtime; + JS_LOCK_GC(rt); + JS_ASSERT(!rt->gcRunning); + if (rt->gcRunning) { + METER(rt->gcStats.finalfail++); + JS_UNLOCK_GC(rt); + return NULL; + } + METER(rt->gcStats.alloc++); +retry: + thing = rt->gcFreeList; + if (thing) { + rt->gcFreeList = thing->next; + flagp = thing->flagp; + METER(rt->gcStats.freelen--); + METER(rt->gcStats.recycle++); + } else { + if (rt->gcBytes < rt->gcMaxBytes && + (tried_gc || rt->gcMallocBytes < rt->gcMaxBytes)) + { + /* + * Inline form of JS_ARENA_ALLOCATE adapted to truncate the current + * arena's limit to a GC_PAGE_SIZE boundary, and to skip over every + * GC_PAGE_SIZE-byte-aligned thing (which is actually not a thing, + * it's a JSGCPageInfo record). + */ + JSArenaPool *pool = &rt->gcArenaPool; + JSArena *a = pool->current; + size_t nb = sizeof(JSGCThing); + jsuword p = a->avail; + jsuword q = p + nb; + + if (q > (a->limit & ~GC_PAGE_MASK)) { + thing = gc_new_arena(pool); + } else { + if ((p & GC_PAGE_MASK) == 0) { + /* Beware, p points to a JSGCPageInfo record! */ + p = q; + q += nb; + JS_ArenaCountAllocation(pool, nb); + } + a->avail = q; + thing = (JSGCThing *)p; + } + JS_ArenaCountAllocation(pool, nb); + } + + /* + * Consider doing a "last ditch" GC if thing couldn't be allocated. + * + * Keep rt->gcLock across the call into js_GC so we don't starve and + * lose to racing threads who deplete the heap just after js_GC has + * replenished it (or has synchronized with a racing GC that collected + * a bunch of garbage). This unfair scheduling can happen on certain + * operating systems. For the gory details, see Mozilla bug 162779 + * (http://bugzilla.mozilla.org/show_bug.cgi?id=162779). + */ + if (!thing) { + if (!tried_gc) { + rt->gcPoke = JS_TRUE; + js_GC(cx, GC_KEEP_ATOMS | GC_ALREADY_LOCKED); + tried_gc = JS_TRUE; + METER(rt->gcStats.retry++); + goto retry; + } + METER(rt->gcStats.fail++); + JS_UNLOCK_GC(rt); + JS_ReportOutOfMemory(cx); + return NULL; + } + + /* Find the flags pointer given thing's address. */ + flagp = js_GetGCThingFlags(thing); + } + *flagp = (uint8)flags; + rt->gcBytes += sizeof(JSGCThing) + sizeof(uint8); + cx->newborn[flags & GCF_TYPEMASK] = thing; + + /* + * Clear thing before unlocking in case a GC run is about to scan it, + * finding it via cx->newborn[]. + */ + thing->next = NULL; + thing->flagp = NULL; + JS_UNLOCK_GC(rt); + return thing; +} + +JSBool +js_LockGCThing(JSContext *cx, void *thing) +{ + JSBool ok = js_LockGCThingRT(cx->runtime, thing); + if (!ok) + JS_ReportOutOfMemory(cx); + return ok; +} + +JSBool +js_LockGCThingRT(JSRuntime *rt, void *thing) +{ + uint8 *flagp, flags, lockbits; + JSBool ok; + JSGCLockHashEntry *lhe; + + if (!thing) + return JS_TRUE; + flagp = js_GetGCThingFlags(thing); + flags = *flagp; + + ok = JS_FALSE; + JS_LOCK_GC(rt); + lockbits = (flags & GCF_LOCKMASK); + + if (lockbits != GCF_LOCKMASK) { + if ((flags & GCF_TYPEMASK) == GCX_OBJECT) { + /* Objects may require "deep locking", i.e., rooting by value. */ + if (lockbits == 0) { + if (!rt->gcLocksHash) { + rt->gcLocksHash = + JS_NewDHashTable(JS_DHashGetStubOps(), NULL, + sizeof(JSGCLockHashEntry), + GC_ROOTS_SIZE); + if (!rt->gcLocksHash) + goto error; + } else { +#ifdef DEBUG + JSDHashEntryHdr *hdr = + JS_DHashTableOperate(rt->gcLocksHash, thing, + JS_DHASH_LOOKUP); + JS_ASSERT(JS_DHASH_ENTRY_IS_FREE(hdr)); +#endif + } + lhe = (JSGCLockHashEntry *) + JS_DHashTableOperate(rt->gcLocksHash, thing, JS_DHASH_ADD); + if (!lhe) + goto error; + lhe->thing = thing; + lhe->count = 1; + *flagp = (uint8)(flags + GCF_LOCK); + } else { + JS_ASSERT(lockbits == GCF_LOCK); + lhe = (JSGCLockHashEntry *) + JS_DHashTableOperate(rt->gcLocksHash, thing, + JS_DHASH_LOOKUP); + JS_ASSERT(JS_DHASH_ENTRY_IS_BUSY(&lhe->hdr)); + if (JS_DHASH_ENTRY_IS_BUSY(&lhe->hdr)) { + JS_ASSERT(lhe->count >= 1); + lhe->count++; + } + } + } else { + *flagp = (uint8)(flags + GCF_LOCK); + } + } else { + METER(rt->gcStats.stuck++); + } + + METER(rt->gcStats.lock++); + ok = JS_TRUE; +error: + JS_UNLOCK_GC(rt); + return ok; +} + +JSBool +js_UnlockGCThingRT(JSRuntime *rt, void *thing) +{ + uint8 *flagp, flags, lockbits; + JSGCLockHashEntry *lhe; + + if (!thing) + return JS_TRUE; + flagp = js_GetGCThingFlags(thing); + flags = *flagp; + + JS_LOCK_GC(rt); + lockbits = (flags & GCF_LOCKMASK); + + if (lockbits != GCF_LOCKMASK) { + if ((flags & GCF_TYPEMASK) == GCX_OBJECT) { + /* Defend against a call on an unlocked object. */ + if (lockbits != 0) { + JS_ASSERT(lockbits == GCF_LOCK); + lhe = (JSGCLockHashEntry *) + JS_DHashTableOperate(rt->gcLocksHash, thing, + JS_DHASH_LOOKUP); + JS_ASSERT(JS_DHASH_ENTRY_IS_BUSY(&lhe->hdr)); + if (JS_DHASH_ENTRY_IS_BUSY(&lhe->hdr) && + --lhe->count == 0) { + (void) JS_DHashTableOperate(rt->gcLocksHash, thing, + JS_DHASH_REMOVE); + *flagp = (uint8)(flags & ~GCF_LOCKMASK); + } + } + } else { + *flagp = (uint8)(flags - GCF_LOCK); + } + } else { + METER(rt->gcStats.unstuck++); + } + + rt->gcPoke = JS_TRUE; + METER(rt->gcStats.unlock++); + JS_UNLOCK_GC(rt); + return JS_TRUE; +} + +#ifdef GC_MARK_DEBUG + +#include +#include +#include "jsprf.h" + +JS_FRIEND_DATA(FILE *) js_DumpGCHeap; +JS_EXPORT_DATA(void *) js_LiveThingToFind; + +#ifdef HAVE_XPCONNECT +#include "dump_xpc.h" +#endif + +static const char * +gc_object_class_name(void* thing) +{ + uint8 *flagp = js_GetGCThingFlags(thing); + const char *className = ""; + static char depbuf[32]; + + switch (*flagp & GCF_TYPEMASK) { + case GCX_OBJECT: { + JSObject *obj = (JSObject *)thing; + JSClass *clasp = JSVAL_TO_PRIVATE(obj->slots[JSSLOT_CLASS]); + className = clasp->name; +#ifdef HAVE_XPCONNECT + if (clasp->flags & JSCLASS_PRIVATE_IS_NSISUPPORTS) { + jsval privateValue = obj->slots[JSSLOT_PRIVATE]; + + JS_ASSERT(clasp->flags & JSCLASS_HAS_PRIVATE); + if (!JSVAL_IS_VOID(privateValue)) { + void *privateThing = JSVAL_TO_PRIVATE(privateValue); + const char *xpcClassName = GetXPCObjectClassName(privateThing); + + if (xpcClassName) + className = xpcClassName; + } + } +#endif + break; + } + + case GCX_STRING: + case GCX_MUTABLE_STRING: { + JSString *str = (JSString *)thing; + if (JSSTRING_IS_DEPENDENT(str)) { + JS_snprintf(depbuf, sizeof depbuf, "start:%u, length:%u", + JSSTRDEP_START(str), JSSTRDEP_LENGTH(str)); + className = depbuf; + } else { + className = "string"; + } + break; + } + + case GCX_DOUBLE: + className = "double"; + break; + } + + return className; +} + +static void +gc_dump_thing(JSGCThing *thing, uint8 flags, GCMarkNode *prev, FILE *fp) +{ + GCMarkNode *next = NULL; + char *path = NULL; + + while (prev) { + next = prev; + prev = prev->prev; + } + while (next) { + path = JS_sprintf_append(path, "%s(%s).", + next->name, + gc_object_class_name(next->thing)); + next = next->next; + } + if (!path) + return; + + fprintf(fp, "%08lx ", (long)thing); + switch (flags & GCF_TYPEMASK) { + case GCX_OBJECT: + { + JSObject *obj = (JSObject *)thing; + jsval privateValue = obj->slots[JSSLOT_PRIVATE]; + void *privateThing = JSVAL_IS_VOID(privateValue) + ? NULL + : JSVAL_TO_PRIVATE(privateValue); + const char *className = gc_object_class_name(thing); + fprintf(fp, "object %8p %s", privateThing, className); + break; + } + case GCX_DOUBLE: + fprintf(fp, "double %g", *(jsdouble *)thing); + break; + default: + fprintf(fp, "string %s", JS_GetStringBytes((JSString *)thing)); + break; + } + fprintf(fp, " via %s\n", path); + free(path); +} + +#endif /* !GC_MARK_DEBUG */ + +static void +gc_mark_atom_key_thing(void *thing, void *arg) +{ + JSContext *cx = (JSContext *) arg; + + GC_MARK(cx, thing, "atom", NULL); +} + +void +js_MarkAtom(JSContext *cx, JSAtom *atom, void *arg) +{ + jsval key; + + if (atom->flags & ATOM_MARK) + return; + atom->flags |= ATOM_MARK; + key = ATOM_KEY(atom); + if (JSVAL_IS_GCTHING(key)) { +#ifdef GC_MARK_DEBUG + char name[32]; + + if (JSVAL_IS_STRING(key)) { + JS_snprintf(name, sizeof name, "'%s'", + JS_GetStringBytes(JSVAL_TO_STRING(key))); + } else { + JS_snprintf(name, sizeof name, "<%x>", key); + } +#endif + GC_MARK(cx, JSVAL_TO_GCTHING(key), name, arg); + } +} + +void +js_MarkGCThing(JSContext *cx, void *thing, void *arg) +{ + uint8 flags, *flagp; + JSRuntime *rt; + JSObject *obj; + uint32 nslots; + jsval v, *vp, *end; + JSString *str; +#ifdef GC_MARK_DEBUG + JSScope *scope; + JSScopeProperty *sprop; +#endif + + if (!thing) + return; + + flagp = js_GetGCThingFlags(thing); + flags = *flagp; + JS_ASSERT(flags != GCF_FINAL); +#ifdef GC_MARK_DEBUG + if (js_LiveThingToFind == thing) + gc_dump_thing(thing, flags, arg, stderr); +#endif + + if (flags & GCF_MARK) + return; + + *flagp |= GCF_MARK; + rt = cx->runtime; + METER(if (++rt->gcStats.depth > rt->gcStats.maxdepth) + rt->gcStats.maxdepth = rt->gcStats.depth); + +#ifdef GC_MARK_DEBUG + if (js_DumpGCHeap) + gc_dump_thing(thing, flags, arg, js_DumpGCHeap); +#endif + + switch (flags & GCF_TYPEMASK) { + case GCX_OBJECT: + obj = (JSObject *) thing; + vp = obj->slots; + if (!vp) { + /* If obj->slots is null, obj must be a newborn. */ + JS_ASSERT(!obj->map); + goto out; + } + nslots = (obj->map->ops->mark) + ? obj->map->ops->mark(cx, obj, arg) + : JS_MIN(obj->map->freeslot, obj->map->nslots); +#ifdef GC_MARK_DEBUG + scope = OBJ_IS_NATIVE(obj) ? OBJ_SCOPE(obj) : NULL; +#endif + for (end = vp + nslots; vp < end; vp++) { + v = *vp; + if (JSVAL_IS_GCTHING(v)) { +#ifdef GC_MARK_DEBUG + char name[32]; + + if (scope) { + uint32 slot; + jsval nval; + + slot = vp - obj->slots; + for (sprop = SCOPE_LAST_PROP(scope); ; + sprop = sprop->parent) { + if (!sprop) { + switch (slot) { + case JSSLOT_PROTO: + strcpy(name, "__proto__"); + break; + case JSSLOT_PARENT: + strcpy(name, "__parent__"); + break; + case JSSLOT_PRIVATE: + strcpy(name, "__private__"); + break; + default: + JS_snprintf(name, sizeof name, + "**UNKNOWN SLOT %ld**", + (long)slot); + break; + } + break; + } + if (sprop->slot == slot) { + nval = ID_TO_VALUE(sprop->id); + if (JSVAL_IS_INT(nval)) { + JS_snprintf(name, sizeof name, "%ld", + (long)JSVAL_TO_INT(nval)); + } else if (JSVAL_IS_STRING(nval)) { + JS_snprintf(name, sizeof name, "%s", + JS_GetStringBytes(JSVAL_TO_STRING(nval))); + } else { + strcpy(name, "**FINALIZED ATOM KEY**"); + } + break; + } + } + } else { + strcpy(name, "**UNKNOWN OBJECT MAP ENTRY**"); + } +#endif + GC_MARK(cx, JSVAL_TO_GCTHING(v), name, arg); + } + } + break; + +#ifdef DEBUG + case GCX_STRING: + str = (JSString *)thing; + JS_ASSERT(!JSSTRING_IS_DEPENDENT(str)); + break; +#endif + + case GCX_MUTABLE_STRING: + str = (JSString *)thing; + if (JSSTRING_IS_DEPENDENT(str)) + GC_MARK(cx, JSSTRDEP_BASE(str), "base", arg); + break; + } + +out: + METER(rt->gcStats.depth--); +} + +JS_STATIC_DLL_CALLBACK(JSDHashOperator) +gc_root_marker(JSDHashTable *table, JSDHashEntryHdr *hdr, uint32 num, void *arg) +{ + JSGCRootHashEntry *rhe = (JSGCRootHashEntry *)hdr; + jsval *rp = (jsval *)rhe->root; + jsval v = *rp; + + /* Ignore null object and scalar values. */ + if (!JSVAL_IS_NULL(v) && JSVAL_IS_GCTHING(v)) { + JSContext *cx = (JSContext *)arg; +#ifdef DEBUG + JSArena *a; + jsuword firstpage; + JSBool root_points_to_gcArenaPool = JS_FALSE; + void *thing = JSVAL_TO_GCTHING(v); + + for (a = cx->runtime->gcArenaPool.first.next; a; a = a->next) { + firstpage = FIRST_THING_PAGE(a); + if (JS_UPTRDIFF(thing, firstpage) < a->avail - firstpage) { + root_points_to_gcArenaPool = JS_TRUE; + break; + } + } + if (!root_points_to_gcArenaPool && rhe->name) { + fprintf(stderr, +"JS API usage error: the address passed to JS_AddNamedRoot currently holds an\n" +"invalid jsval. This is usually caused by a missing call to JS_RemoveRoot.\n" +"The root's name is \"%s\".\n", + rhe->name); + } + JS_ASSERT(root_points_to_gcArenaPool); +#endif + + GC_MARK(cx, JSVAL_TO_GCTHING(v), rhe->name ? rhe->name : "root", NULL); + } + return JS_DHASH_NEXT; +} + +JS_STATIC_DLL_CALLBACK(JSDHashOperator) +gc_lock_marker(JSDHashTable *table, JSDHashEntryHdr *hdr, uint32 num, void *arg) +{ + JSGCLockHashEntry *lhe = (JSGCLockHashEntry *)hdr; + void *thing = (void *)lhe->thing; + JSContext *cx = (JSContext *)arg; + + GC_MARK(cx, thing, "locked object", NULL); + return JS_DHASH_NEXT; +} + +void +js_ForceGC(JSContext *cx, uintN gcflags) +{ + uintN i; + + for (i = 0; i < GCX_NTYPES; i++) + cx->newborn[i] = NULL; + cx->lastAtom = NULL; + cx->runtime->gcPoke = JS_TRUE; + js_GC(cx, gcflags); + JS_ArenaFinish(); +} + +#define GC_MARK_JSVALS(cx, len, vec, name) \ + JS_BEGIN_MACRO \ + jsval _v, *_vp, *_end; \ + \ + for (_vp = vec, _end = _vp + len; _vp < _end; _vp++) { \ + _v = *_vp; \ + if (JSVAL_IS_GCTHING(_v)) \ + GC_MARK(cx, JSVAL_TO_GCTHING(_v), name, NULL); \ + } \ + JS_END_MACRO + +void +js_GC(JSContext *cx, uintN gcflags) +{ + JSRuntime *rt; + JSContext *iter, *acx; + JSStackFrame *fp, *chain; + uintN i, depth, nslots, type; + JSStackHeader *sh; + JSArena *a, **ap; + uint8 flags, *flagp, *split; + JSGCThing *thing, *limit, **flp, **oflp; + GCFinalizeOp finalizer; + JSBool all_clear; +#ifdef JS_THREADSAFE + jsword currentThread; + uint32 requestDebit; +#endif + + rt = cx->runtime; +#ifdef JS_THREADSAFE + /* Avoid deadlock. */ + JS_ASSERT(!JS_IS_RUNTIME_LOCKED(rt)); +#endif + + /* + * Don't collect garbage if the runtime isn't up, and cx is not the last + * context in the runtime. The last context must force a GC, and nothing + * should suppress that final collection or there may be shutdown leaks, + * or runtime bloat until the next context is created. + */ + if (rt->state != JSRTS_UP && !(gcflags & GC_LAST_CONTEXT)) + return; + + /* + * Let the API user decide to defer a GC if it wants to (unless this + * is the last context). Invoke the callback regardless. + */ + if (rt->gcCallback) { + if (!rt->gcCallback(cx, JSGC_BEGIN) && !(gcflags & GC_LAST_CONTEXT)) + return; + } + + /* Lock out other GC allocator and collector invocations. */ + if (!(gcflags & GC_ALREADY_LOCKED)) + JS_LOCK_GC(rt); + + /* Do nothing if no assignment has executed since the last GC. */ + if (!rt->gcPoke) { + METER(rt->gcStats.nopoke++); + if (!(gcflags & GC_ALREADY_LOCKED)) + JS_UNLOCK_GC(rt); + return; + } + METER(rt->gcStats.poke++); + +#ifdef JS_THREADSAFE + /* Bump gcLevel and return rather than nest on this thread. */ + currentThread = js_CurrentThreadId(); + if (rt->gcThread == currentThread) { + JS_ASSERT(rt->gcLevel > 0); + rt->gcLevel++; + METER(if (rt->gcLevel > rt->gcStats.maxlevel) + rt->gcStats.maxlevel = rt->gcLevel); + if (!(gcflags & GC_ALREADY_LOCKED)) + JS_UNLOCK_GC(rt); + return; + } + + /* + * If we're in one or more requests (possibly on more than one context) + * running on the current thread, indicate, temporarily, that all these + * requests are inactive. NB: if cx->thread is 0, then cx is not using + * the request model, and does not contribute to rt->requestCount. + */ + requestDebit = 0; + if (cx->thread) { + /* + * Check all contexts for any with the same thread-id. XXX should we + * keep a sub-list of contexts having the same id? + */ + iter = NULL; + while ((acx = js_ContextIterator(rt, JS_FALSE, &iter)) != NULL) { + if (acx->thread == cx->thread && acx->requestDepth) + requestDebit++; + } + } else { + /* + * We assert, but check anyway, in case someone is misusing the API. + * Avoiding the loop over all of rt's contexts is a win in the event + * that the GC runs only on request-less contexts with 0 thread-ids, + * in a special thread such as might be used by the UI/DOM/Layout + * "mozilla" or "main" thread in Mozilla-the-browser. + */ + JS_ASSERT(cx->requestDepth == 0); + if (cx->requestDepth) + requestDebit = 1; + } + if (requestDebit) { + JS_ASSERT(requestDebit <= rt->requestCount); + rt->requestCount -= requestDebit; + if (rt->requestCount == 0) + JS_NOTIFY_REQUEST_DONE(rt); + } + + /* If another thread is already in GC, don't attempt GC; wait instead. */ + if (rt->gcLevel > 0) { + /* Bump gcLevel to restart the current GC, so it finds new garbage. */ + rt->gcLevel++; + METER(if (rt->gcLevel > rt->gcStats.maxlevel) + rt->gcStats.maxlevel = rt->gcLevel); + + /* Wait for the other thread to finish, then resume our request. */ + while (rt->gcLevel > 0) + JS_AWAIT_GC_DONE(rt); + if (requestDebit) + rt->requestCount += requestDebit; + if (!(gcflags & GC_ALREADY_LOCKED)) + JS_UNLOCK_GC(rt); + return; + } + + /* No other thread is in GC, so indicate that we're now in GC. */ + rt->gcLevel = 1; + rt->gcThread = currentThread; + + /* Wait for all other requests to finish. */ + while (rt->requestCount > 0) + JS_AWAIT_REQUEST_DONE(rt); + +#else /* !JS_THREADSAFE */ + + /* Bump gcLevel and return rather than nest; the outer gc will restart. */ + rt->gcLevel++; + METER(if (rt->gcLevel > rt->gcStats.maxlevel) + rt->gcStats.maxlevel = rt->gcLevel); + if (rt->gcLevel > 1) + return; + +#endif /* !JS_THREADSAFE */ + + /* + * Set rt->gcRunning here within the GC lock, and after waiting for any + * active requests to end, so that new requests that try to JS_AddRoot, + * JS_RemoveRoot, or JS_RemoveRootRT block in JS_BeginRequest waiting for + * rt->gcLevel to drop to zero, while request-less calls to the *Root* + * APIs block in js_AddRoot or js_RemoveRoot (see above in this file), + * waiting for GC to finish. + */ + rt->gcRunning = JS_TRUE; + JS_UNLOCK_GC(rt); + + /* If a suspended compile is running on another context, keep atoms. */ + if (rt->gcKeepAtoms) + gcflags |= GC_KEEP_ATOMS; + + /* Reset malloc counter. */ + rt->gcMallocBytes = 0; + + /* Drop atoms held by the property cache, and clear property weak links. */ + js_DisablePropertyCache(cx); + js_FlushPropertyCache(cx); +#ifdef DEBUG_brendan + { extern void js_DumpScopeMeters(JSRuntime *rt); + js_DumpScopeMeters(rt); + } +#endif + +restart: + rt->gcNumber++; + + /* + * Mark phase. + */ + JS_DHashTableEnumerate(&rt->gcRootsHash, gc_root_marker, cx); + if (rt->gcLocksHash) + JS_DHashTableEnumerate(rt->gcLocksHash, gc_lock_marker, cx); + js_MarkAtomState(&rt->atomState, gcflags, gc_mark_atom_key_thing, cx); + js_MarkWatchPoints(rt); + iter = NULL; + while ((acx = js_ContextIterator(rt, JS_TRUE, &iter)) != NULL) { + /* + * Iterate frame chain and dormant chains. Temporarily tack current + * frame onto the head of the dormant list to ease iteration. + * + * (NB: see comment on this whole "dormant" thing in js_Execute.) + */ + chain = acx->fp; + if (chain) { + JS_ASSERT(!chain->dormantNext); + chain->dormantNext = acx->dormantFrameChain; + } else { + chain = acx->dormantFrameChain; + } + + for (fp = chain; fp; fp = chain = chain->dormantNext) { + do { + if (fp->callobj) + GC_MARK(cx, fp->callobj, "call object", NULL); + if (fp->argsobj) + GC_MARK(cx, fp->argsobj, "arguments object", NULL); + if (fp->varobj) + GC_MARK(cx, fp->varobj, "variables object", NULL); + if (fp->script) { + js_MarkScript(cx, fp->script, NULL); + if (fp->spbase) { + /* + * Don't mark what has not been pushed yet, or what + * has been popped already. + */ + depth = fp->script->depth; + nslots = (JS_UPTRDIFF(fp->sp, fp->spbase) + < depth * sizeof(jsval)) + ? (uintN)(fp->sp - fp->spbase) + : depth; + GC_MARK_JSVALS(cx, nslots, fp->spbase, "operand"); + } + } + GC_MARK(cx, fp->thisp, "this", NULL); + if (fp->argv) { + nslots = fp->argc; + if (fp->fun && fp->fun->nargs > nslots) + nslots = fp->fun->nargs; + GC_MARK_JSVALS(cx, nslots, fp->argv, "arg"); + } + if (JSVAL_IS_GCTHING(fp->rval)) + GC_MARK(cx, JSVAL_TO_GCTHING(fp->rval), "rval", NULL); + if (fp->vars) + GC_MARK_JSVALS(cx, fp->nvars, fp->vars, "var"); + GC_MARK(cx, fp->scopeChain, "scope chain", NULL); + if (fp->sharpArray) + GC_MARK(cx, fp->sharpArray, "sharp array", NULL); + + if (fp->objAtomMap) { + JSAtom **vector, *atom; + + nslots = fp->objAtomMap->length; + vector = fp->objAtomMap->vector; + for (i = 0; i < nslots; i++) { + atom = vector[i]; + if (atom) + GC_MARK_ATOM(cx, atom, NULL); + } + } + } while ((fp = fp->down) != NULL); + } + + /* Cleanup temporary "dormant" linkage. */ + if (acx->fp) + acx->fp->dormantNext = NULL; + + /* Mark other roots-by-definition in acx. */ + GC_MARK(cx, acx->globalObject, "global object", NULL); + GC_MARK(cx, acx->newborn[GCX_OBJECT], "newborn object", NULL); + GC_MARK(cx, acx->newborn[GCX_STRING], "newborn string", NULL); + GC_MARK(cx, acx->newborn[GCX_DOUBLE], "newborn double", NULL); + GC_MARK(cx, acx->newborn[GCX_MUTABLE_STRING], "newborn mutable string", + NULL); + for (i = GCX_EXTERNAL_STRING; i < GCX_NTYPES; i++) + GC_MARK(cx, acx->newborn[i], "newborn external string", NULL); + if (acx->lastAtom) + GC_MARK_ATOM(cx, acx->lastAtom, NULL); +#if JS_HAS_EXCEPTIONS + if (acx->throwing && JSVAL_IS_GCTHING(acx->exception)) + GC_MARK(cx, JSVAL_TO_GCTHING(acx->exception), "exception", NULL); +#endif +#if JS_HAS_LVALUE_RETURN + if (acx->rval2set && JSVAL_IS_GCTHING(acx->rval2)) + GC_MARK(cx, JSVAL_TO_GCTHING(acx->rval2), "rval2", NULL); +#endif + + for (sh = acx->stackHeaders; sh; sh = sh->down) { + METER(rt->gcStats.stackseg++); + METER(rt->gcStats.segslots += sh->nslots); + GC_MARK_JSVALS(cx, sh->nslots, JS_STACK_SEGMENT(sh), "stack"); + } + } + + if (rt->gcCallback) + (void) rt->gcCallback(cx, JSGC_MARK_END); + + /* + * Sweep phase. + * Finalize as we sweep, outside of rt->gcLock, but with rt->gcRunning set + * so that any attempt to allocate a GC-thing from a finalizer will fail, + * rather than nest badly and leave the unmarked newborn to be swept. + */ + js_SweepAtomState(&rt->atomState); + js_SweepScopeProperties(rt); + js_SweepScriptFilenames(rt); + for (a = rt->gcArenaPool.first.next; a; a = a->next) { + flagp = (uint8 *) a->base; + split = (uint8 *) FIRST_THING_PAGE(a); + limit = (JSGCThing *) a->avail; + for (thing = (JSGCThing *) split; thing < limit; thing++) { + if (((jsuword)thing & GC_PAGE_MASK) == 0) { + flagp++; + thing++; + } + flags = *flagp; + if (flags & GCF_MARK) { + *flagp &= ~GCF_MARK; + } else if (!(flags & (GCF_LOCKMASK | GCF_FINAL))) { + /* Call the finalizer with GCF_FINAL ORed into flags. */ + type = flags & GCF_TYPEMASK; + finalizer = gc_finalizers[type]; + if (finalizer) { + *flagp = (uint8)(flags | GCF_FINAL); + if (type >= GCX_EXTERNAL_STRING) + js_PurgeDeflatedStringCache((JSString *)thing); + finalizer(cx, thing); + } + + /* Set flags to GCF_FINAL, signifying that thing is free. */ + *flagp = GCF_FINAL; + + JS_ASSERT(rt->gcBytes >= sizeof(JSGCThing) + sizeof(uint8)); + rt->gcBytes -= sizeof(JSGCThing) + sizeof(uint8); + } + if (++flagp == split) + flagp += GC_THINGS_SIZE; + } + } + + /* + * Free phase. + * Free any unused arenas and rebuild the JSGCThing freelist. + */ + ap = &rt->gcArenaPool.first.next; + a = *ap; + if (!a) + goto out; + all_clear = JS_TRUE; + flp = oflp = &rt->gcFreeList; + *flp = NULL; + METER(rt->gcStats.freelen = 0); + + do { + flagp = (uint8 *) a->base; + split = (uint8 *) FIRST_THING_PAGE(a); + limit = (JSGCThing *) a->avail; + for (thing = (JSGCThing *) split; thing < limit; thing++) { + if (((jsuword)thing & GC_PAGE_MASK) == 0) { + flagp++; + thing++; + } + if (*flagp != GCF_FINAL) { + all_clear = JS_FALSE; + } else { + thing->flagp = flagp; + *flp = thing; + flp = &thing->next; + METER(rt->gcStats.freelen++); + } + if (++flagp == split) + flagp += GC_THINGS_SIZE; + } + + if (all_clear) { + JS_ARENA_DESTROY(&rt->gcArenaPool, a, ap); + flp = oflp; + METER(rt->gcStats.afree++); + } else { + ap = &a->next; + all_clear = JS_TRUE; + oflp = flp; + } + } while ((a = *ap) != NULL); + + /* Terminate the new freelist. */ + *flp = NULL; + + if (rt->gcCallback) + (void) rt->gcCallback(cx, JSGC_FINALIZE_END); +#ifdef DEBUG_brendan + { extern void DumpSrcNoteSizeHist(); + DumpSrcNoteSizeHist(); + } +#endif + +out: + JS_LOCK_GC(rt); + if (rt->gcLevel > 1) { + rt->gcLevel = 1; + JS_UNLOCK_GC(rt); + goto restart; + } + js_EnablePropertyCache(cx); + rt->gcLevel = 0; + rt->gcLastBytes = rt->gcBytes; + rt->gcPoke = rt->gcRunning = JS_FALSE; + +#ifdef JS_THREADSAFE + /* If we were invoked during a request, pay back the temporary debit. */ + if (requestDebit) + rt->requestCount += requestDebit; + rt->gcThread = 0; + JS_NOTIFY_GC_DONE(rt); + if (!(gcflags & GC_ALREADY_LOCKED)) + JS_UNLOCK_GC(rt); +#endif + + if (rt->gcCallback) { + if (gcflags & GC_ALREADY_LOCKED) + JS_UNLOCK_GC(rt); + (void) rt->gcCallback(cx, JSGC_END); + if (gcflags & GC_ALREADY_LOCKED) + JS_LOCK_GC(rt); + } +} diff --git a/src/dom/js/jsgc.h b/src/dom/js/jsgc.h new file mode 100644 index 000000000..f501aca23 --- /dev/null +++ b/src/dom/js/jsgc.h @@ -0,0 +1,230 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef jsgc_h___ +#define jsgc_h___ +/* + * JS Garbage Collector. + */ +#include "jsprvtd.h" +#include "jspubtd.h" +#include "jsdhash.h" + +JS_BEGIN_EXTERN_C + +/* GC thing type indexes. */ +#define GCX_OBJECT 0 /* JSObject */ +#define GCX_STRING 1 /* JSString */ +#define GCX_DOUBLE 2 /* jsdouble */ +#define GCX_MUTABLE_STRING 3 /* JSString that's mutable -- + single-threaded only! */ +#define GCX_EXTERNAL_STRING 4 /* JSString w/ external chars */ +#define GCX_NTYPES_LOG2 3 /* type index bits */ +#define GCX_NTYPES JS_BIT(GCX_NTYPES_LOG2) + +/* GC flag definitions, must fit in 8 bits (type index goes in the low bits). */ +#define GCF_TYPEMASK JS_BITMASK(GCX_NTYPES_LOG2) +#define GCF_MARK JS_BIT(GCX_NTYPES_LOG2) +#define GCF_FINAL JS_BIT(GCX_NTYPES_LOG2 + 1) +#define GCF_LOCKSHIFT (GCX_NTYPES_LOG2 + 2) /* lock bit shift and mask */ +#define GCF_LOCKMASK (JS_BITMASK(8 - GCF_LOCKSHIFT) << GCF_LOCKSHIFT) +#define GCF_LOCK JS_BIT(GCF_LOCKSHIFT) /* lock request bit in API */ + +/* Pseudo-flag that modifies GCX_STRING to make GCX_MUTABLE_STRING. */ +#define GCF_MUTABLE 2 + +#if (GCX_STRING | GCF_MUTABLE) != GCX_MUTABLE_STRING +# error "mutable string type index botch!" +#endif + +extern uint8 * +js_GetGCThingFlags(void *thing); + +/* These are compatible with JSDHashEntryStub. */ +struct JSGCRootHashEntry { + JSDHashEntryHdr hdr; + void *root; + const char *name; +}; + +struct JSGCLockHashEntry { + JSDHashEntryHdr hdr; + const JSGCThing *thing; + uint32 count; +}; + +#if 1 +/* + * Since we're forcing a GC from JS_GC anyway, don't bother wasting cycles + * loading oldval. XXX remove implied force, fix jsinterp.c's "second arg + * ignored", etc. + */ +#define GC_POKE(cx, oldval) ((cx)->runtime->gcPoke = JS_TRUE) +#else +#define GC_POKE(cx, oldval) ((cx)->runtime->gcPoke = JSVAL_IS_GCTHING(oldval)) +#endif + +extern intN +js_ChangeExternalStringFinalizer(JSStringFinalizeOp oldop, + JSStringFinalizeOp newop); + +extern JSBool +js_InitGC(JSRuntime *rt, uint32 maxbytes); + +extern void +js_FinishGC(JSRuntime *rt); + +extern JSBool +js_AddRoot(JSContext *cx, void *rp, const char *name); + +extern JSBool +js_AddRootRT(JSRuntime *rt, void *rp, const char *name); + +extern JSBool +js_RemoveRoot(JSRuntime *rt, void *rp); + +extern void * +js_AllocGCThing(JSContext *cx, uintN flags); + +extern JSBool +js_LockGCThing(JSContext *cx, void *thing); + +extern JSBool +js_LockGCThingRT(JSRuntime *rt, void *thing); + +extern JSBool +js_UnlockGCThingRT(JSRuntime *rt, void *thing); + +extern JSBool +js_IsAboutToBeFinalized(JSContext *cx, void *thing); + +extern void +js_MarkAtom(JSContext *cx, JSAtom *atom, void *arg); + +/* We avoid a large number of unnecessary calls by doing the flag check first */ +#define GC_MARK_ATOM(cx, atom, arg) \ + JS_BEGIN_MACRO \ + if (!((atom)->flags & ATOM_MARK)) \ + js_MarkAtom(cx, atom, arg); \ + JS_END_MACRO + +extern void +js_MarkGCThing(JSContext *cx, void *thing, void *arg); + +#ifdef GC_MARK_DEBUG + +typedef struct GCMarkNode GCMarkNode; + +struct GCMarkNode { + void *thing; + const char *name; + GCMarkNode *next; + GCMarkNode *prev; +}; + +#define GC_MARK(_cx, _thing, _name, _prev) \ + JS_BEGIN_MACRO \ + GCMarkNode _node; \ + _node.thing = _thing; \ + _node.name = _name; \ + _node.next = NULL; \ + _node.prev = _prev; \ + if (_prev) ((GCMarkNode *)(_prev))->next = &_node; \ + js_MarkGCThing(_cx, _thing, &_node); \ + JS_END_MACRO + +#else /* !GC_MARK_DEBUG */ + +#define GC_MARK(cx, thing, name, prev) js_MarkGCThing(cx, thing, NULL) + +#endif /* !GC_MARK_DEBUG */ + +/* + * Flags to modify how a GC marks and sweeps: + * GC_KEEP_ATOMS Don't sweep unmarked atoms, they may be in use by the + * compiler, or by an API function that calls js_Atomize, + * when the GC is called from js_AllocGCThing, due to a + * malloc failure or runtime GC-thing limit. + * GC_LAST_CONTEXT Called from js_DestroyContext for last JSContext in a + * JSRuntime, when it is imperative that rt->gcPoke gets + * cleared early in js_GC, if it is set. + * GC_ALREADY_LOCKED rt->gcLock is already held on entry to js_GC, and kept + * on return to its caller. + */ +#define GC_KEEP_ATOMS 0x1 +#define GC_LAST_CONTEXT 0x2 +#define GC_ALREADY_LOCKED 0x4 + +extern void +js_ForceGC(JSContext *cx, uintN gcflags); + +extern void +js_GC(JSContext *cx, uintN gcflags); + +#ifdef JS_GCMETER + +typedef struct JSGCStats { + uint32 alloc; /* number of allocation attempts */ + uint32 freelen; /* gcFreeList length */ + uint32 recycle; /* number of things recycled through gcFreeList */ + uint32 retry; /* allocation attempt retries after running the GC */ + uint32 fail; /* allocation failures */ + uint32 finalfail; /* finalizer calls allocator failures */ + uint32 lock; /* valid lock calls */ + uint32 unlock; /* valid unlock calls */ + uint32 stuck; /* stuck reference counts seen by lock calls */ + uint32 unstuck; /* unlock calls that saw a stuck lock count */ + uint32 depth; /* mark recursion depth */ + uint32 maxdepth; /* maximum mark recursion depth */ + uint32 maxlevel; /* maximum GC nesting (indirect recursion) level */ + uint32 poke; /* number of potentially useful GC calls */ + uint32 nopoke; /* useless GC calls where js_PokeGC was not set */ + uint32 afree; /* thing arenas freed so far */ + uint32 stackseg; /* total extraordinary stack segments scanned */ + uint32 segslots; /* total stack segment jsval slots scanned */ +} JSGCStats; + +extern void +js_DumpGCStats(JSRuntime *rt, FILE *fp); + +#endif /* JS_GCMETER */ + +JS_END_EXTERN_C + +#endif /* jsgc_h___ */ diff --git a/src/dom/js/jshash.c b/src/dom/js/jshash.c new file mode 100644 index 000000000..3382daadb --- /dev/null +++ b/src/dom/js/jshash.c @@ -0,0 +1,479 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* + * PR hash table package. + */ +#include "jsstddef.h" +#include +#include +#include "jstypes.h" +#include "jsbit.h" +#include "jsutil.h" /* Added by JSIFY */ +#include "jshash.h" /* Added by JSIFY */ + +/* Compute the number of buckets in ht */ +#define NBUCKETS(ht) JS_BIT(JS_HASH_BITS - (ht)->shift) + +/* The smallest table has 16 buckets */ +#define MINBUCKETSLOG2 4 +#define MINBUCKETS JS_BIT(MINBUCKETSLOG2) + +/* Compute the maximum entries given n buckets that we will tolerate, ~90% */ +#define OVERLOADED(n) ((n) - ((n) >> 3)) + +/* Compute the number of entries below which we shrink the table by half */ +#define UNDERLOADED(n) (((n) > MINBUCKETS) ? ((n) >> 2) : 0) + +/* +** Stubs for default hash allocator ops. +*/ +static void * +DefaultAllocTable(void *pool, size_t size) +{ + return malloc(size); +} + +static void +DefaultFreeTable(void *pool, void *item) +{ + free(item); +} + +static JSHashEntry * +DefaultAllocEntry(void *pool, const void *key) +{ + return (JSHashEntry*) malloc(sizeof(JSHashEntry)); +} + +static void +DefaultFreeEntry(void *pool, JSHashEntry *he, uintN flag) +{ + if (flag == HT_FREE_ENTRY) + free(he); +} + +static JSHashAllocOps defaultHashAllocOps = { + DefaultAllocTable, DefaultFreeTable, + DefaultAllocEntry, DefaultFreeEntry +}; + +JS_PUBLIC_API(JSHashTable *) +JS_NewHashTable(uint32 n, JSHashFunction keyHash, + JSHashComparator keyCompare, JSHashComparator valueCompare, + JSHashAllocOps *allocOps, void *allocPriv) +{ + JSHashTable *ht; + size_t nb; + + if (n <= MINBUCKETS) { + n = MINBUCKETSLOG2; + } else { + n = JS_CeilingLog2(n); + if ((int32)n < 0) + return NULL; + } + + if (!allocOps) allocOps = &defaultHashAllocOps; + + ht = (JSHashTable*) (*allocOps->allocTable)(allocPriv, sizeof *ht); + if (!ht) + return NULL; + memset(ht, 0, sizeof *ht); + ht->shift = JS_HASH_BITS - n; + n = JS_BIT(n); +#if defined _MSC_VER && _MSC_VER <= 800 + if (n > 16000) { + (*allocOps->freeTable)(allocPriv, ht); + return NULL; + } +#endif /* WIN16 */ + nb = n * sizeof(JSHashEntry *); + ht->buckets = (JSHashEntry**) (*allocOps->allocTable)(allocPriv, nb); + if (!ht->buckets) { + (*allocOps->freeTable)(allocPriv, ht); + return NULL; + } + memset(ht->buckets, 0, nb); + + ht->keyHash = keyHash; + ht->keyCompare = keyCompare; + ht->valueCompare = valueCompare; + ht->allocOps = allocOps; + ht->allocPriv = allocPriv; + return ht; +} + +JS_PUBLIC_API(void) +JS_HashTableDestroy(JSHashTable *ht) +{ + uint32 i, n; + JSHashEntry *he, **hep; + JSHashAllocOps *allocOps = ht->allocOps; + void *allocPriv = ht->allocPriv; + + n = NBUCKETS(ht); + for (i = 0; i < n; i++) { + hep = &ht->buckets[i]; + while ((he = *hep) != NULL) { + *hep = he->next; + (*allocOps->freeEntry)(allocPriv, he, HT_FREE_ENTRY); + } + } +#ifdef DEBUG + memset(ht->buckets, 0xDB, n * sizeof ht->buckets[0]); +#endif + (*allocOps->freeTable)(allocPriv, ht->buckets); +#ifdef DEBUG + memset(ht, 0xDB, sizeof *ht); +#endif + (*allocOps->freeTable)(allocPriv, ht); +} + +/* +** Multiplicative hash, from Knuth 6.4. +*/ +JS_PUBLIC_API(JSHashEntry **) +JS_HashTableRawLookup(JSHashTable *ht, JSHashNumber keyHash, const void *key) +{ + JSHashEntry *he, **hep, **hep0; + JSHashNumber h; + +#ifdef HASHMETER + ht->nlookups++; +#endif + h = keyHash * JS_GOLDEN_RATIO; + h >>= ht->shift; + hep = hep0 = &ht->buckets[h]; + while ((he = *hep) != NULL) { + if (he->keyHash == keyHash && (*ht->keyCompare)(key, he->key)) { + /* Move to front of chain if not already there */ + if (hep != hep0) { + *hep = he->next; + he->next = *hep0; + *hep0 = he; + } + return hep0; + } + hep = &he->next; +#ifdef HASHMETER + ht->nsteps++; +#endif + } + return hep; +} + +JS_PUBLIC_API(JSHashEntry *) +JS_HashTableRawAdd(JSHashTable *ht, JSHashEntry **hep, + JSHashNumber keyHash, const void *key, void *value) +{ + uint32 i, n; + JSHashEntry *he, *next, **oldbuckets; + size_t nb; + + /* Grow the table if it is overloaded */ + n = NBUCKETS(ht); + if (ht->nentries >= OVERLOADED(n)) { + oldbuckets = ht->buckets; +#if defined _MSC_VER && _MSC_VER <= 800 + if (2 * n > 16000) + return NULL; +#endif /* WIN16 */ + nb = 2 * n * sizeof(JSHashEntry *); + ht->buckets = (JSHashEntry**) (*ht->allocOps->allocTable)(ht->allocPriv, nb); + if (!ht->buckets) { + ht->buckets = oldbuckets; + return NULL; + } + memset(ht->buckets, 0, nb); +#ifdef HASHMETER + ht->ngrows++; +#endif + ht->shift--; + + for (i = 0; i < n; i++) { + for (he = oldbuckets[i]; he; he = next) { + next = he->next; + hep = JS_HashTableRawLookup(ht, he->keyHash, he->key); + JS_ASSERT(*hep == NULL); + he->next = NULL; + *hep = he; + } + } +#ifdef DEBUG + memset(oldbuckets, 0xDB, n * sizeof oldbuckets[0]); +#endif + (*ht->allocOps->freeTable)(ht->allocPriv, oldbuckets); + hep = JS_HashTableRawLookup(ht, keyHash, key); + } + + /* Make a new key value entry */ + he = (*ht->allocOps->allocEntry)(ht->allocPriv, key); + if (!he) + return NULL; + he->keyHash = keyHash; + he->key = key; + he->value = value; + he->next = *hep; + *hep = he; + ht->nentries++; + return he; +} + +JS_PUBLIC_API(JSHashEntry *) +JS_HashTableAdd(JSHashTable *ht, const void *key, void *value) +{ + JSHashNumber keyHash; + JSHashEntry *he, **hep; + + keyHash = (*ht->keyHash)(key); + hep = JS_HashTableRawLookup(ht, keyHash, key); + if ((he = *hep) != NULL) { + /* Hit; see if values match */ + if ((*ht->valueCompare)(he->value, value)) { + /* key,value pair is already present in table */ + return he; + } + if (he->value) + (*ht->allocOps->freeEntry)(ht->allocPriv, he, HT_FREE_VALUE); + he->value = value; + return he; + } + return JS_HashTableRawAdd(ht, hep, keyHash, key, value); +} + +JS_PUBLIC_API(void) +JS_HashTableRawRemove(JSHashTable *ht, JSHashEntry **hep, JSHashEntry *he) +{ + uint32 i, n; + JSHashEntry *next, **oldbuckets; + size_t nb; + + *hep = he->next; + (*ht->allocOps->freeEntry)(ht->allocPriv, he, HT_FREE_ENTRY); + + /* Shrink table if it's underloaded */ + n = NBUCKETS(ht); + if (--ht->nentries < UNDERLOADED(n)) { + oldbuckets = ht->buckets; + nb = n * sizeof(JSHashEntry*) / 2; + ht->buckets = (JSHashEntry**) (*ht->allocOps->allocTable)(ht->allocPriv, nb); + if (!ht->buckets) { + ht->buckets = oldbuckets; + return; + } + memset(ht->buckets, 0, nb); +#ifdef HASHMETER + ht->nshrinks++; +#endif + ht->shift++; + + for (i = 0; i < n; i++) { + for (he = oldbuckets[i]; he; he = next) { + next = he->next; + hep = JS_HashTableRawLookup(ht, he->keyHash, he->key); + JS_ASSERT(*hep == NULL); + he->next = NULL; + *hep = he; + } + } +#ifdef DEBUG + memset(oldbuckets, 0xDB, n * sizeof oldbuckets[0]); +#endif + (*ht->allocOps->freeTable)(ht->allocPriv, oldbuckets); + } +} + +JS_PUBLIC_API(JSBool) +JS_HashTableRemove(JSHashTable *ht, const void *key) +{ + JSHashNumber keyHash; + JSHashEntry *he, **hep; + + keyHash = (*ht->keyHash)(key); + hep = JS_HashTableRawLookup(ht, keyHash, key); + if ((he = *hep) == NULL) + return JS_FALSE; + + /* Hit; remove element */ + JS_HashTableRawRemove(ht, hep, he); + return JS_TRUE; +} + +JS_PUBLIC_API(void *) +JS_HashTableLookup(JSHashTable *ht, const void *key) +{ + JSHashNumber keyHash; + JSHashEntry *he, **hep; + + keyHash = (*ht->keyHash)(key); + hep = JS_HashTableRawLookup(ht, keyHash, key); + if ((he = *hep) != NULL) { + return he->value; + } + return NULL; +} + +/* +** Iterate over the entries in the hash table calling func for each +** entry found. Stop if "f" says to (return value & JS_ENUMERATE_STOP). +** Return a count of the number of elements scanned. +*/ +JS_PUBLIC_API(int) +JS_HashTableEnumerateEntries(JSHashTable *ht, JSHashEnumerator f, void *arg) +{ + JSHashEntry *he, **hep; + uint32 i, nbuckets; + int rv, n = 0; + JSHashEntry *todo = NULL; + + nbuckets = NBUCKETS(ht); + for (i = 0; i < nbuckets; i++) { + hep = &ht->buckets[i]; + while ((he = *hep) != NULL) { + rv = (*f)(he, n, arg); + n++; + if (rv & (HT_ENUMERATE_REMOVE | HT_ENUMERATE_UNHASH)) { + *hep = he->next; + if (rv & HT_ENUMERATE_REMOVE) { + he->next = todo; + todo = he; + } + } else { + hep = &he->next; + } + if (rv & HT_ENUMERATE_STOP) { + goto out; + } + } + } + +out: + hep = &todo; + while ((he = *hep) != NULL) { + JS_HashTableRawRemove(ht, hep, he); + } + return n; +} + +#ifdef HASHMETER +#include +#include + +JS_PUBLIC_API(void) +JS_HashTableDumpMeter(JSHashTable *ht, JSHashEnumerator dump, FILE *fp) +{ + double sqsum, mean, variance, sigma; + uint32 nchains, nbuckets, nentries; + uint32 i, n, maxChain, maxChainLen; + JSHashEntry *he; + + sqsum = 0; + nchains = 0; + maxChainLen = 0; + nbuckets = NBUCKETS(ht); + for (i = 0; i < nbuckets; i++) { + he = ht->buckets[i]; + if (!he) + continue; + nchains++; + for (n = 0; he; he = he->next) + n++; + sqsum += n * n; + if (n > maxChainLen) { + maxChainLen = n; + maxChain = i; + } + } + nentries = ht->nentries; + mean = (double)nentries / nchains; + variance = nchains * sqsum - nentries * nentries; + if (variance < 0 || nchains == 1) + variance = 0; + else + variance /= nchains * (nchains - 1); + sigma = sqrt(variance); + + fprintf(fp, "\nHash table statistics:\n"); + fprintf(fp, " number of lookups: %u\n", ht->nlookups); + fprintf(fp, " number of entries: %u\n", ht->nentries); + fprintf(fp, " number of grows: %u\n", ht->ngrows); + fprintf(fp, " number of shrinks: %u\n", ht->nshrinks); + fprintf(fp, " mean steps per hash: %g\n", (double)ht->nsteps + / ht->nlookups); + fprintf(fp, "mean hash chain length: %g\n", mean); + fprintf(fp, " standard deviation: %g\n", sigma); + fprintf(fp, " max hash chain length: %u\n", maxChainLen); + fprintf(fp, " max hash chain: [%u]\n", maxChain); + + for (he = ht->buckets[maxChain], i = 0; he; he = he->next, i++) + if ((*dump)(he, i, fp) != HT_ENUMERATE_NEXT) + break; +} +#endif /* HASHMETER */ + +JS_PUBLIC_API(int) +JS_HashTableDump(JSHashTable *ht, JSHashEnumerator dump, FILE *fp) +{ + int count; + + count = JS_HashTableEnumerateEntries(ht, dump, fp); +#ifdef HASHMETER + JS_HashTableDumpMeter(ht, dump, fp); +#endif + return count; +} + +JS_PUBLIC_API(JSHashNumber) +JS_HashString(const void *key) +{ + JSHashNumber h; + const unsigned char *s; + + h = 0; + for (s = (const unsigned char *)key; *s; s++) + h = (h >> (JS_HASH_BITS - 4)) ^ (h << 4) ^ *s; + return h; +} + +JS_PUBLIC_API(int) +JS_CompareValues(const void *v1, const void *v2) +{ + return v1 == v2; +} diff --git a/src/dom/js/jshash.h b/src/dom/js/jshash.h new file mode 100644 index 000000000..85e3cf811 --- /dev/null +++ b/src/dom/js/jshash.h @@ -0,0 +1,152 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef jshash_h___ +#define jshash_h___ +/* + * API to portable hash table code. + */ +#include +#include +#include "jstypes.h" +#include "jscompat.h" + +JS_BEGIN_EXTERN_C + +typedef uint32 JSHashNumber; +typedef struct JSHashEntry JSHashEntry; +typedef struct JSHashTable JSHashTable; + +#define JS_HASH_BITS 32 +#define JS_GOLDEN_RATIO 0x9E3779B9U + +typedef JSHashNumber (* JS_DLL_CALLBACK JSHashFunction)(const void *key); +typedef intN (* JS_DLL_CALLBACK JSHashComparator)(const void *v1, const void *v2); +typedef intN (* JS_DLL_CALLBACK JSHashEnumerator)(JSHashEntry *he, intN i, void *arg); + +/* Flag bits in JSHashEnumerator's return value */ +#define HT_ENUMERATE_NEXT 0 /* continue enumerating entries */ +#define HT_ENUMERATE_STOP 1 /* stop enumerating entries */ +#define HT_ENUMERATE_REMOVE 2 /* remove and free the current entry */ +#define HT_ENUMERATE_UNHASH 4 /* just unhash the current entry */ + +typedef struct JSHashAllocOps { + void * (*allocTable)(void *pool, size_t size); + void (*freeTable)(void *pool, void *item); + JSHashEntry * (*allocEntry)(void *pool, const void *key); + void (*freeEntry)(void *pool, JSHashEntry *he, uintN flag); +} JSHashAllocOps; + +#define HT_FREE_VALUE 0 /* just free the entry's value */ +#define HT_FREE_ENTRY 1 /* free value and entire entry */ + +struct JSHashEntry { + JSHashEntry *next; /* hash chain linkage */ + JSHashNumber keyHash; /* key hash function result */ + const void *key; /* ptr to opaque key */ + void *value; /* ptr to opaque value */ +}; + +struct JSHashTable { + JSHashEntry **buckets; /* vector of hash buckets */ + uint32 nentries; /* number of entries in table */ + uint32 shift; /* multiplicative hash shift */ + JSHashFunction keyHash; /* key hash function */ + JSHashComparator keyCompare; /* key comparison function */ + JSHashComparator valueCompare; /* value comparison function */ + JSHashAllocOps *allocOps; /* allocation operations */ + void *allocPriv; /* allocation private data */ +#ifdef HASHMETER + uint32 nlookups; /* total number of lookups */ + uint32 nsteps; /* number of hash chains traversed */ + uint32 ngrows; /* number of table expansions */ + uint32 nshrinks; /* number of table contractions */ +#endif +}; + +/* + * Create a new hash table. + * If allocOps is null, use default allocator ops built on top of malloc(). + */ +extern JS_PUBLIC_API(JSHashTable *) +JS_NewHashTable(uint32 n, JSHashFunction keyHash, + JSHashComparator keyCompare, JSHashComparator valueCompare, + JSHashAllocOps *allocOps, void *allocPriv); + +extern JS_PUBLIC_API(void) +JS_HashTableDestroy(JSHashTable *ht); + +/* Low level access methods */ +extern JS_PUBLIC_API(JSHashEntry **) +JS_HashTableRawLookup(JSHashTable *ht, JSHashNumber keyHash, const void *key); + +extern JS_PUBLIC_API(JSHashEntry *) +JS_HashTableRawAdd(JSHashTable *ht, JSHashEntry **hep, JSHashNumber keyHash, + const void *key, void *value); + +extern JS_PUBLIC_API(void) +JS_HashTableRawRemove(JSHashTable *ht, JSHashEntry **hep, JSHashEntry *he); + +/* Higher level access methods */ +extern JS_PUBLIC_API(JSHashEntry *) +JS_HashTableAdd(JSHashTable *ht, const void *key, void *value); + +extern JS_PUBLIC_API(JSBool) +JS_HashTableRemove(JSHashTable *ht, const void *key); + +extern JS_PUBLIC_API(intN) +JS_HashTableEnumerateEntries(JSHashTable *ht, JSHashEnumerator f, void *arg); + +extern JS_PUBLIC_API(void *) +JS_HashTableLookup(JSHashTable *ht, const void *key); + +extern JS_PUBLIC_API(intN) +JS_HashTableDump(JSHashTable *ht, JSHashEnumerator dump, FILE *fp); + +/* General-purpose C string hash function. */ +extern JS_PUBLIC_API(JSHashNumber) +JS_HashString(const void *key); + +/* Stub function just returns v1 == v2 */ +extern JS_PUBLIC_API(intN) +JS_CompareValues(const void *v1, const void *v2); + +JS_END_EXTERN_C + +#endif /* jshash_h___ */ diff --git a/src/dom/js/jsinterp.c b/src/dom/js/jsinterp.c new file mode 100644 index 000000000..60f39b3ce --- /dev/null +++ b/src/dom/js/jsinterp.c @@ -0,0 +1,4284 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* build on macs with low memory */ +#if defined(XP_MAC) && defined(MOZ_MAC_LOWMEM) +#pragma optimization_level 1 +#endif + +/* + * JavaScript bytecode interpreter. + */ +#include "jsstddef.h" +#include +#include +#include +#include "jstypes.h" +#include "jsarena.h" /* Added by JSIFY */ +#include "jsutil.h" /* Added by JSIFY */ +#include "jsprf.h" +#include "jsapi.h" +#include "jsarray.h" +#include "jsatom.h" +#include "jsbool.h" +#include "jscntxt.h" +#include "jsconfig.h" +#include "jsdbgapi.h" +#include "jsfun.h" +#include "jsgc.h" +#include "jsinterp.h" +#include "jslock.h" +#include "jsnum.h" +#include "jsobj.h" +#include "jsopcode.h" +#include "jsscope.h" +#include "jsscript.h" +#include "jsstr.h" + +#if JS_HAS_JIT +#include "jsjit.h" +#endif + +#ifdef DEBUG +#define ASSERT_CACHE_IS_EMPTY(cache) \ + JS_BEGIN_MACRO \ + JSPropertyCacheEntry *end_, *pce_, entry_; \ + JSPropertyCache *cache_ = (cache); \ + JS_ASSERT(cache_->empty); \ + end_ = &cache_->table[PROPERTY_CACHE_SIZE]; \ + for (pce_ = &cache_->table[0]; pce_ < end_; pce_++) { \ + PCE_LOAD(cache_, pce_, entry_); \ + JS_ASSERT(!PCE_OBJECT(entry_)); \ + JS_ASSERT(!PCE_PROPERTY(entry_)); \ + } \ + JS_END_MACRO +#else +#define ASSERT_CACHE_IS_EMPTY(cache) ((void)0) +#endif + +void +js_FlushPropertyCache(JSContext *cx) +{ + JSPropertyCache *cache; + + cache = &cx->runtime->propertyCache; + if (cache->empty) { + ASSERT_CACHE_IS_EMPTY(cache); + return; + } + memset(cache->table, 0, sizeof cache->table); + cache->empty = JS_TRUE; +#ifdef JS_PROPERTY_CACHE_METERING + cache->flushes++; +#endif +} + +void +js_DisablePropertyCache(JSContext *cx) +{ + JS_ASSERT(!cx->runtime->propertyCache.disabled); + cx->runtime->propertyCache.disabled = JS_TRUE; +} + +void +js_EnablePropertyCache(JSContext *cx) +{ + JS_ASSERT(cx->runtime->propertyCache.disabled); + ASSERT_CACHE_IS_EMPTY(&cx->runtime->propertyCache); + cx->runtime->propertyCache.disabled = JS_FALSE; +} + +/* + * Class for for/in loop property iterator objects. + */ +#define JSSLOT_ITER_STATE JSSLOT_PRIVATE + +static void +prop_iterator_finalize(JSContext *cx, JSObject *obj) +{ + jsval iter_state; + jsval iteratee; + + /* Protect against stillborn iterators. */ + iter_state = obj->slots[JSSLOT_ITER_STATE]; + iteratee = obj->slots[JSSLOT_PARENT]; + if (!JSVAL_IS_NULL(iter_state) && !JSVAL_IS_PRIMITIVE(iteratee)) { + OBJ_ENUMERATE(cx, JSVAL_TO_OBJECT(iteratee), JSENUMERATE_DESTROY, + &iter_state, NULL); + } + js_RemoveRoot(cx->runtime, &obj->slots[JSSLOT_PARENT]); + + /* XXX force the GC to restart so we can collect iteratee, if possible, + during the current collector activation */ + cx->runtime->gcLevel++; +} + +static JSClass prop_iterator_class = { + "PropertyIterator", + 0, + JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, + JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, prop_iterator_finalize, + JSCLASS_NO_OPTIONAL_MEMBERS +}; + +/* + * Stack macros and functions. These all use a local variable, jsval *sp, to + * point to the next free stack slot. SAVE_SP must be called before any call + * to a function that may invoke the interpreter. RESTORE_SP must be called + * only after return from js_Invoke, because only js_Invoke changes fp->sp. + */ +#define PUSH(v) (*sp++ = (v)) +#define POP() (*--sp) +#ifdef DEBUG +#define SAVE_SP(fp) \ + (JS_ASSERT((fp)->script || !(fp)->spbase || (sp) == (fp)->spbase), \ + (fp)->sp = sp) +#else +#define SAVE_SP(fp) ((fp)->sp = sp) +#endif +#define RESTORE_SP(fp) (sp = (fp)->sp) + +/* + * Push the generating bytecode's pc onto the parallel pc stack that runs + * depth slots below the operands. + * + * NB: PUSH_OPND uses sp, depth, and pc from its lexical environment. See + * js_Interpret for these local variables' declarations and uses. + */ +#define PUSH_OPND(v) (sp[-depth] = (jsval)pc, PUSH(v)) +#define STORE_OPND(n,v) (sp[(n)-depth] = (jsval)pc, sp[n] = (v)) +#define POP_OPND() POP() +#define FETCH_OPND(n) (sp[n]) + +/* + * Push the jsdouble d using sp, depth, and pc from the lexical environment. + * Try to convert d to a jsint that fits in a jsval, otherwise GC-alloc space + * for it and push a reference. + */ +#define STORE_NUMBER(cx, n, d) \ + JS_BEGIN_MACRO \ + jsint i_; \ + jsval v_; \ + \ + if (JSDOUBLE_IS_INT(d, i_) && INT_FITS_IN_JSVAL(i_)) { \ + v_ = INT_TO_JSVAL(i_); \ + } else { \ + ok = js_NewDoubleValue(cx, d, &v_); \ + if (!ok) \ + goto out; \ + } \ + STORE_OPND(n, v_); \ + JS_END_MACRO + +#define FETCH_NUMBER(cx, n, d) \ + JS_BEGIN_MACRO \ + jsval v_; \ + \ + v_ = FETCH_OPND(n); \ + VALUE_TO_NUMBER(cx, v_, d); \ + JS_END_MACRO + +#define FETCH_INT(cx, n, i) \ + JS_BEGIN_MACRO \ + jsval v_ = FETCH_OPND(n); \ + if (JSVAL_IS_INT(v_)) { \ + i = JSVAL_TO_INT(v_); \ + } else { \ + SAVE_SP(fp); \ + ok = js_ValueToECMAInt32(cx, v_, &i); \ + if (!ok) \ + goto out; \ + } \ + JS_END_MACRO + +#define FETCH_UINT(cx, n, ui) \ + JS_BEGIN_MACRO \ + jsval v_ = FETCH_OPND(n); \ + jsint i_; \ + if (JSVAL_IS_INT(v_) && (i_ = JSVAL_TO_INT(v_)) >= 0) { \ + ui = (uint32) i_; \ + } else { \ + SAVE_SP(fp); \ + ok = js_ValueToECMAUint32(cx, v_, &ui); \ + if (!ok) \ + goto out; \ + } \ + JS_END_MACRO + +/* + * Optimized conversion macros that test for the desired type in v before + * homing sp and calling a conversion function. + */ +#define VALUE_TO_NUMBER(cx, v, d) \ + JS_BEGIN_MACRO \ + if (JSVAL_IS_INT(v)) { \ + d = (jsdouble)JSVAL_TO_INT(v); \ + } else if (JSVAL_IS_DOUBLE(v)) { \ + d = *JSVAL_TO_DOUBLE(v); \ + } else { \ + SAVE_SP(fp); \ + ok = js_ValueToNumber(cx, v, &d); \ + if (!ok) \ + goto out; \ + } \ + JS_END_MACRO + +#define POP_BOOLEAN(cx, v, b) \ + JS_BEGIN_MACRO \ + v = FETCH_OPND(-1); \ + if (v == JSVAL_NULL) { \ + b = JS_FALSE; \ + } else if (JSVAL_IS_BOOLEAN(v)) { \ + b = JSVAL_TO_BOOLEAN(v); \ + } else { \ + SAVE_SP(fp); \ + ok = js_ValueToBoolean(cx, v, &b); \ + if (!ok) \ + goto out; \ + } \ + sp--; \ + JS_END_MACRO + +#define VALUE_TO_OBJECT(cx, v, obj) \ + JS_BEGIN_MACRO \ + if (JSVAL_IS_OBJECT(v) && v != JSVAL_NULL) { \ + obj = JSVAL_TO_OBJECT(v); \ + } else { \ + SAVE_SP(fp); \ + obj = js_ValueToNonNullObject(cx, v); \ + if (!obj) { \ + ok = JS_FALSE; \ + goto out; \ + } \ + } \ + JS_END_MACRO + +#if JS_BUG_VOID_TOSTRING +#define CHECK_VOID_TOSTRING(cx, v) \ + if (JSVAL_IS_VOID(v)) { \ + JSString *str_; \ + str_ = ATOM_TO_STRING(cx->runtime->atomState.typeAtoms[JSTYPE_VOID]); \ + v = STRING_TO_JSVAL(str_); \ + } +#else +#define CHECK_VOID_TOSTRING(cx, v) ((void)0) +#endif + +#if JS_BUG_EAGER_TOSTRING +#define CHECK_EAGER_TOSTRING(hint) (hint = JSTYPE_STRING) +#else +#define CHECK_EAGER_TOSTRING(hint) ((void)0) +#endif + +#define VALUE_TO_PRIMITIVE(cx, v, hint, vp) \ + JS_BEGIN_MACRO \ + if (JSVAL_IS_PRIMITIVE(v)) { \ + CHECK_VOID_TOSTRING(cx, v); \ + *vp = v; \ + } else { \ + SAVE_SP(fp); \ + CHECK_EAGER_TOSTRING(hint); \ + ok = OBJ_DEFAULT_VALUE(cx, JSVAL_TO_OBJECT(v), hint, vp); \ + if (!ok) \ + goto out; \ + } \ + JS_END_MACRO + +JS_FRIEND_API(jsval *) +js_AllocRawStack(JSContext *cx, uintN nslots, void **markp) +{ + jsval *sp; + + if (markp) + *markp = JS_ARENA_MARK(&cx->stackPool); + JS_ARENA_ALLOCATE_CAST(sp, jsval *, &cx->stackPool, nslots * sizeof(jsval)); + if (!sp) { + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_STACK_OVERFLOW, + (cx->fp && cx->fp->fun) + ? JS_GetFunctionName(cx->fp->fun) + : "script"); + } + return sp; +} + +JS_FRIEND_API(void) +js_FreeRawStack(JSContext *cx, void *mark) +{ + JS_ARENA_RELEASE(&cx->stackPool, mark); +} + +JS_FRIEND_API(jsval *) +js_AllocStack(JSContext *cx, uintN nslots, void **markp) +{ + jsval *sp, *vp, *end; + JSArena *a; + JSStackHeader *sh; + JSStackFrame *fp; + + /* Callers don't check for zero nslots: we do to avoid empty segments. */ + if (nslots == 0) { + *markp = NULL; + return JS_ARENA_MARK(&cx->stackPool); + } + + /* Allocate 2 extra slots for the stack segment header we'll likely need. */ + sp = js_AllocRawStack(cx, 2 + nslots, markp); + if (!sp) + return NULL; + + /* Try to avoid another header if we can piggyback on the last segment. */ + a = cx->stackPool.current; + sh = cx->stackHeaders; + if (sh && JS_STACK_SEGMENT(sh) + sh->nslots == sp) { + /* Extend the last stack segment, give back the 2 header slots. */ + sh->nslots += nslots; + a->avail -= 2 * sizeof(jsval); + } else { + /* + * Need a new stack segment, so we must initialize unused slots in the + * current frame. See js_GC, just before marking the "operand" jsvals, + * where we scan from fp->spbase to fp->sp or through fp->script->depth + * (whichever covers fewer slots). + */ + fp = cx->fp; + if (fp && fp->script && fp->spbase) { +#ifdef DEBUG + jsuword depthdiff = fp->script->depth * sizeof(jsval); + JS_ASSERT(JS_UPTRDIFF(fp->sp, fp->spbase) <= depthdiff); + JS_ASSERT(JS_UPTRDIFF(*markp, fp->spbase) >= depthdiff); +#endif + end = fp->spbase + fp->script->depth; + for (vp = fp->sp; vp < end; vp++) + *vp = JSVAL_VOID; + } + + /* Allocate and push a stack segment header from the 2 extra slots. */ + sh = (JSStackHeader *)sp; + sh->nslots = nslots; + sh->down = cx->stackHeaders; + cx->stackHeaders = sh; + sp += 2; + } + + return sp; +} + +JS_FRIEND_API(void) +js_FreeStack(JSContext *cx, void *mark) +{ + JSStackHeader *sh; + jsuword slotdiff; + + /* Check for zero nslots allocation special case. */ + if (!mark) + return; + + /* We can assert because js_FreeStack always balances js_AllocStack. */ + sh = cx->stackHeaders; + JS_ASSERT(sh); + + /* If mark is in the current segment, reduce sh->nslots, else pop sh. */ + slotdiff = JS_UPTRDIFF(mark, JS_STACK_SEGMENT(sh)) / sizeof(jsval); + if (slotdiff < (jsuword)sh->nslots) + sh->nslots = slotdiff; + else + cx->stackHeaders = sh->down; + + /* Release the stackPool space allocated since mark was set. */ + JS_ARENA_RELEASE(&cx->stackPool, mark); +} + +/* + * To economize on slots space in functions, the compiler records arguments and + * local variables as shared (JSPROP_SHARED) properties with well-known getters + * and setters: js_{Get,Set}Argument, js_{Get,Set}LocalVariable. Now, we could + * record args and vars in lists or hash tables in function-private data, but + * that means more duplication in code, and more data at runtime in the hash + * table case due to round-up to powers of two, just to recapitulate the scope + * machinery in the function object. + * + * What's more, for a long time (to the dawn of "Mocha" in 1995), these getters + * and setters knew how to search active stack frames in a context to find the + * top activation of the function f, in order to satisfy a get or set of f.a, + * for argument a, or f.x, for local variable x. You could use f.a instead of + * just a in function f(a) { return f.a }, for example, to return the actual + * parameter. + * + * ECMA requires that we give up on this ancient extension, because it is not + * compatible with the standard as used by real-world scripts. While Chapter + * 16 does allow for additional properties to be defined on native objects by + * a conforming implementation, these magic getters and setters cause f.a's + * meaning to vary unexpectedly. Real-world scripts set f.A = 42 to define + * "class static" (after Java) constants, for example, but if A also names an + * arg or var in f, the constant is not available while f is active, and any + * non-constant class-static can't be set while f is active. + * + * So, to label arg and var properties in functions without giving them magic + * abilities to affect active frame stack slots, while keeping the properties + * shared (slot-less) to save space in the common case (where no assignment + * sets a function property with the same name as an arg or var), the setters + * for args and vars must handle two special cases here. + * + * XXX functions tend to have few args and vars, so we risk O(n^2) growth here + * XXX ECMA *really* wants args and vars to be stored in function-private data, + * not as function object properties. + */ +static JSBool +SetFunctionSlot(JSContext *cx, JSObject *obj, JSPropertyOp setter, jsid id, + jsval v) +{ + uintN slot; + JSObject *origobj; + JSScope *scope; + JSScopeProperty *sprop; + JSString *str; + JSBool ok; + + slot = (uintN) JSVAL_TO_INT(id); + if (OBJ_GET_CLASS(cx, obj) != &js_FunctionClass) { + /* + * Given a non-function object obj that has a function object in its + * prototype chain, where an argument or local variable property named + * by (setter, slot) is being set, override the shared property in the + * prototype with an unshared property in obj. This situation arises + * in real-world JS due to .prototype setting and collisions among a + * function's "static property" names and arg or var names, believe it + * or not. + */ + origobj = obj; + do { + obj = OBJ_GET_PROTO(cx, obj); + if (!obj) + return JS_TRUE; + } while (OBJ_GET_CLASS(cx, obj) != &js_FunctionClass); + + JS_LOCK_OBJ(cx, obj); + scope = OBJ_SCOPE(obj); + for (sprop = SCOPE_LAST_PROP(scope); sprop; sprop = sprop->parent) { + if (sprop->setter == setter) { + JS_ASSERT(!JSVAL_IS_INT(sprop->id) && + ATOM_IS_STRING((JSAtom *)sprop->id) && + (sprop->flags & SPROP_HAS_SHORTID)); + + if ((uintN) sprop->shortid == slot) { + str = ATOM_TO_STRING((JSAtom *)sprop->id); + JS_UNLOCK_SCOPE(cx, scope); + + return JS_DefineUCProperty(cx, origobj, + JSSTRING_CHARS(str), + JSSTRING_LENGTH(str), + v, NULL, NULL, + JSPROP_ENUMERATE); + } + } + } + JS_UNLOCK_SCOPE(cx, scope); + return JS_TRUE; + } + + /* + * Argument and local variable properties of function objects are shared + * by default (JSPROP_SHARED), therefore slot-less. But if for function + * f(a) {}, f.a = 42 is evaluated, f.a should be 42 after the assignment, + * whether or not f is active. So js_SetArgument and js_SetLocalVariable + * must be prepared to change an arg or var from shared to unshared status, + * allocating a slot in obj to hold v. + */ + ok = JS_TRUE; + JS_LOCK_OBJ(cx, obj); + scope = OBJ_SCOPE(obj); + for (sprop = SCOPE_LAST_PROP(scope); sprop; sprop = sprop->parent) { + if (sprop->setter == setter && (uintN) sprop->shortid == slot) { + if (sprop->attrs & JSPROP_SHARED) { + sprop = js_ChangeScopePropertyAttrs(cx, scope, sprop, + 0, ~JSPROP_SHARED, + sprop->getter, setter); + if (!sprop) { + ok = JS_FALSE; + } else { + /* See js_SetProperty, near the bottom. */ + GC_POKE(cx, pval); + LOCKED_OBJ_SET_SLOT(obj, sprop->slot, v); + } + } + break; + } + } + JS_UNLOCK_SCOPE(cx, scope); + return ok; +} + +JSBool +js_GetArgument(JSContext *cx, JSObject *obj, jsval id, jsval *vp) +{ + return JS_TRUE; +} + +JSBool +js_SetArgument(JSContext *cx, JSObject *obj, jsval id, jsval *vp) +{ + return SetFunctionSlot(cx, obj, js_SetArgument, id, *vp); +} + +JSBool +js_GetLocalVariable(JSContext *cx, JSObject *obj, jsval id, jsval *vp) +{ + return JS_TRUE; +} + +JSBool +js_SetLocalVariable(JSContext *cx, JSObject *obj, jsval id, jsval *vp) +{ + return SetFunctionSlot(cx, obj, js_SetLocalVariable, id, *vp); +} + +/* + * Compute the 'this' parameter and store it in frame as frame.thisp. + * Activation objects ("Call" objects not created with "new Call()", i.e., + * "Call" objects that have private data) may not be referred to by 'this', + * as dictated by ECMA. + * + * N.B.: fp->argv must be set, fp->argv[-1] the nominal 'this' paramter as + * a jsval, and fp->argv[-2] must be the callee object reference, usually a + * function object. Also, fp->flags must contain JSFRAME_CONSTRUCTING if we + * are preparing for a constructor call. + */ +static JSBool +ComputeThis(JSContext *cx, JSObject *thisp, JSStackFrame *fp) +{ + JSObject *parent; + + if (thisp && OBJ_GET_CLASS(cx, thisp) != &js_CallClass) { + /* Some objects (e.g., With) delegate 'this' to another object. */ + thisp = OBJ_THIS_OBJECT(cx, thisp); + if (!thisp) + return JS_FALSE; + + /* Default return value for a constructor is the new object. */ + if (fp->flags & JSFRAME_CONSTRUCTING) + fp->rval = OBJECT_TO_JSVAL(thisp); + } else { + /* + * ECMA requires "the global object", but in the presence of multiple + * top-level objects (windows, frames, or certain layers in the client + * object model), we prefer fun's parent. An example that causes this + * code to run: + * + * // in window w1 + * function f() { return this } + * function g() { return f } + * + * // in window w2 + * var h = w1.g() + * alert(h() == w1) + * + * The alert should display "true". + */ + JS_ASSERT(!(fp->flags & JSFRAME_CONSTRUCTING)); + if (JSVAL_IS_PRIMITIVE(fp->argv[-2]) || + !(parent = OBJ_GET_PARENT(cx, JSVAL_TO_OBJECT(fp->argv[-2])))) { + thisp = cx->globalObject; + } else { + /* walk up to find the top-level object */ + thisp = parent; + while ((parent = OBJ_GET_PARENT(cx, thisp)) != NULL) + thisp = parent; + } + } + fp->thisp = thisp; + fp->argv[-1] = OBJECT_TO_JSVAL(thisp); + return JS_TRUE; +} + +/* + * Find a function reference and its 'this' object implicit first parameter + * under argc arguments on cx's stack, and call the function. Push missing + * required arguments, allocate declared local variables, and pop everything + * when done. Then push the return value. + */ +JS_FRIEND_API(JSBool) +js_Invoke(JSContext *cx, uintN argc, uintN flags) +{ + void *mark; + JSStackFrame *fp, frame; + jsval *sp, *newsp, *limit; + jsval *vp, v; + JSObject *funobj, *parent, *thisp; + JSBool ok; + JSClass *clasp; + JSObjectOps *ops; + JSNative native; + JSFunction *fun; + JSScript *script; + uintN minargs, nvars; + intN nslots, nalloc, surplus; + JSInterpreterHook hook; + void *hookData; + + /* Mark the top of stack and load frequently-used registers. */ + mark = JS_ARENA_MARK(&cx->stackPool); + fp = cx->fp; + sp = fp->sp; + + /* + * Set vp to the callee value's stack slot (it's where rval goes). + * Once vp is set, control should flow through label out2: to return. + * Set frame.rval early so native class and object ops can throw and + * return false, causing a goto out2 with ok set to false. Also set + * frame.flags to flags so that ComputeThis can test bits in it. + */ + vp = sp - (2 + argc); + v = *vp; + frame.rval = JSVAL_VOID; + frame.flags = flags; + thisp = JSVAL_TO_OBJECT(vp[1]); + + /* + * A callee must be an object reference, unless its |this| parameter + * implements the __noSuchMethod__ method, in which case that method will + * be called like so: + * + * thisp.__noSuchMethod__(id, args) + * + * where id is the name of the method that this invocation attempted to + * call by name, and args is an Array containing this invocation's actual + * parameters. + */ + if (JSVAL_IS_PRIMITIVE(v)) { +#if JS_HAS_NO_SUCH_METHOD + jsbytecode *pc; + jsatomid atomIndex; + JSAtom *atom; + JSObject *argsobj; + JSArena *a; + + if (!fp->script || (flags & JSINVOKE_INTERNAL)) + goto bad; + + /* + * We must ComputeThis here to censor Call objects; performance hit, + * but at least it's idempotent. + * + * Normally, we call ComputeThis after all frame members have been + * set, and in particular, after any revision of the callee value at + * *vp due to clasp->convert (see below). This matters because + * ComputeThis may access *vp via fp->argv[-2], to follow the parent + * chain to a global object to use as the |this| parameter. + * + * Obviously, here in the JSVAL_IS_PRIMITIVE(v) case, there can't be + * any such defaulting of |this| to callee (v, *vp) ancestor. + */ + frame.argv = vp + 2; + ok = ComputeThis(cx, thisp, &frame); + if (!ok) + goto out2; + thisp = frame.thisp; + + ok = OBJ_GET_PROPERTY(cx, thisp, + (jsid)cx->runtime->atomState.noSuchMethodAtom, + &v); + if (!ok) + goto out2; + if (JSVAL_IS_PRIMITIVE(v)) + goto bad; + + pc = (jsbytecode *) vp[-(intN)fp->script->depth]; + switch ((JSOp) *pc) { + case JSOP_NAME: + case JSOP_GETPROP: + atomIndex = GET_ATOM_INDEX(pc); + atom = js_GetAtom(cx, &fp->script->atomMap, atomIndex); + argsobj = js_NewArrayObject(cx, argc, vp + 2); + if (!argsobj) { + ok = JS_FALSE; + goto out2; + } + + sp = vp + 4; + if (argc < 2) { + a = cx->stackPool.current; + if ((jsuword)sp > a->limit) { + /* + * Arguments must be contiguous, and must include argv[-1] + * and argv[-2], so allocate more stack, advance sp, and + * set newsp[1] to thisp (vp[1]). The other argv elements + * will be set below, using negative indexing from sp. + */ + newsp = js_AllocRawStack(cx, 4, NULL); + if (!newsp) { + ok = JS_FALSE; + goto out2; + } + newsp[1] = OBJECT_TO_JSVAL(thisp); + sp = newsp + 4; + } else if ((jsuword)sp > a->avail) { + /* + * Inline, optimized version of JS_ARENA_ALLOCATE to claim + * the small number of words not already allocated as part + * of the caller's operand stack. + */ + JS_ArenaCountAllocation(pool, (jsuword)sp - a->avail); + a->avail = (jsuword)sp; + } + } + + sp[-4] = v; + JS_ASSERT(sp[-3] == OBJECT_TO_JSVAL(thisp)); + sp[-2] = ATOM_KEY(atom); + sp[-1] = OBJECT_TO_JSVAL(argsobj); + fp->sp = sp; + argc = 2; + break; + + default: + goto bad; + } +#else + goto bad; +#endif + } + + funobj = JSVAL_TO_OBJECT(v); + parent = OBJ_GET_PARENT(cx, funobj); + clasp = OBJ_GET_CLASS(cx, funobj); + if (clasp != &js_FunctionClass) { + /* Function is inlined, all other classes use object ops. */ + ops = funobj->map->ops; + + /* + * XXX + * Try converting to function, for closure and API compatibility. + * We attempt the conversion under all circumstances for 1.2, but + * only if there is a call op defined otherwise. + */ + if (cx->version == JSVERSION_1_2 || + ((ops == &js_ObjectOps) ? clasp->call : ops->call)) { + ok = clasp->convert(cx, funobj, JSTYPE_FUNCTION, &v); + if (!ok) + goto out2; + + if (JSVAL_IS_FUNCTION(cx, v)) { + /* Make vp refer to funobj to keep it available as argv[-2]. */ + *vp = v; + funobj = JSVAL_TO_OBJECT(v); + parent = OBJ_GET_PARENT(cx, funobj); + goto have_fun; + } + } + fun = NULL; + script = NULL; + minargs = nvars = 0; + + /* Try a call or construct native object op. */ + native = (flags & JSINVOKE_CONSTRUCT) ? ops->construct : ops->call; + if (!native) + goto bad; + } else { +have_fun: + /* Get private data and set derived locals from it. */ + fun = (JSFunction *) JS_GetPrivate(cx, funobj); + native = fun->native; + script = fun->script; + minargs = fun->nargs + fun->extra; + nvars = fun->nvars; + + /* Handle bound method special case. */ + if (fun->flags & JSFUN_BOUND_METHOD) + thisp = parent; + } + + /* Initialize the rest of frame, except for sp (set by SAVE_SP later). */ + frame.varobj = NULL; + frame.callobj = frame.argsobj = NULL; + frame.script = script; + frame.fun = fun; + frame.argc = argc; + frame.argv = sp - argc; + frame.nvars = nvars; + frame.vars = sp; + frame.down = fp; + frame.annotation = NULL; + frame.scopeChain = NULL; /* set below for real, after cx->fp is set */ + frame.pc = NULL; + frame.spbase = NULL; + frame.sharpDepth = 0; + frame.sharpArray = NULL; + frame.dormantNext = NULL; + frame.objAtomMap = NULL; + + /* Compute the 'this' parameter and store it in frame as frame.thisp. */ + ok = ComputeThis(cx, thisp, &frame); + if (!ok) + goto out2; + + /* From here on, control must flow through label out: to return. */ + cx->fp = &frame; + + /* Init these now in case we goto out before first hook call. */ + hook = cx->runtime->callHook; + hookData = NULL; + + /* Check for missing arguments expected by the function. */ + nslots = (intN)((argc < minargs) ? minargs - argc : 0); + if (nslots) { + /* All arguments must be contiguous, so we may have to copy actuals. */ + nalloc = nslots; + limit = (jsval *) cx->stackPool.current->limit; + if (sp + nslots > limit) { + /* Hit end of arena: we have to copy argv[-2..(argc+nslots-1)]. */ + nalloc += 2 + argc; + } else { + /* Take advantage of surplus slots in the caller's frame depth. */ + surplus = (jsval *)mark - sp; + JS_ASSERT(surplus >= 0); + nalloc -= surplus; + } + + /* Check whether we have enough space in the caller's frame. */ + if (nalloc > 0) { + /* Need space for actuals plus missing formals minus surplus. */ + newsp = js_AllocRawStack(cx, (uintN)nalloc, NULL); + if (!newsp) { + ok = JS_FALSE; + goto out; + } + + /* If we couldn't allocate contiguous args, copy actuals now. */ + if (newsp != mark) { + JS_ASSERT(sp + nslots > limit); + JS_ASSERT(2 + argc + nslots == (uintN)nalloc); + *newsp++ = vp[0]; + *newsp++ = vp[1]; + if (argc) + memcpy(newsp, frame.argv, argc * sizeof(jsval)); + frame.argv = newsp; + sp = frame.vars = newsp + argc; + } + } + + /* Advance frame.vars to make room for the missing args. */ + frame.vars += nslots; + + /* Push void to initialize missing args. */ + while (--nslots >= 0) + PUSH(JSVAL_VOID); + } + + /* Now allocate stack space for local variables. */ + nslots = (intN)frame.nvars; + if (nslots) { + surplus = (intN)((jsval *)cx->stackPool.current->avail - frame.vars); + if (surplus < nslots) { + newsp = js_AllocRawStack(cx, (uintN)nslots, NULL); + if (!newsp) { + ok = JS_FALSE; + goto out; + } + if (newsp != sp) { + /* NB: Discontinuity between argv and vars. */ + sp = frame.vars = newsp; + } + } + + /* Push void to initialize local variables. */ + while (--nslots >= 0) + PUSH(JSVAL_VOID); + } + + /* Store the current sp in frame before calling fun. */ + SAVE_SP(&frame); + + /* call the hook if present */ + if (hook && (native || script)) + hookData = hook(cx, &frame, JS_TRUE, 0, cx->runtime->callHookData); + + /* Call the function, either a native method or an interpreted script. */ + if (native) { +#if JS_HAS_LVALUE_RETURN + /* Set by JS_SetCallReturnValue2, used to return reference types. */ + cx->rval2set = JS_FALSE; +#endif + + /* If native, use caller varobj and scopeChain for eval. */ + frame.varobj = fp->varobj; + frame.scopeChain = fp->scopeChain; + ok = native(cx, frame.thisp, argc, frame.argv, &frame.rval); + JS_RUNTIME_METER(cx->runtime, nativeCalls); + } else if (script) { + /* Use parent scope so js_GetCallObject can find the right "Call". */ + frame.scopeChain = parent; + if (fun->flags & JSFUN_HEAVYWEIGHT) { +#if JS_HAS_CALL_OBJECT + /* Scope with a call object parented by the callee's parent. */ + if (!js_GetCallObject(cx, &frame, parent)) { + ok = JS_FALSE; + goto out; + } +#else + /* Bad old code used the function as a proxy for all calls to it. */ + frame.scopeChain = funobj; +#endif + } + ok = js_Interpret(cx, &v); + } else { + /* fun might be onerror trying to report a syntax error in itself. */ + frame.scopeChain = NULL; + ok = JS_TRUE; + } + +out: + if (hookData) { + hook = cx->runtime->callHook; + if (hook) + hook(cx, &frame, JS_FALSE, &ok, hookData); + } +#if JS_HAS_CALL_OBJECT + /* If frame has a call object, sync values and clear back-pointer. */ + if (frame.callobj) + ok &= js_PutCallObject(cx, &frame); +#endif +#if JS_HAS_ARGS_OBJECT + /* If frame has an arguments object, sync values and clear back-pointer. */ + if (frame.argsobj) + ok &= js_PutArgsObject(cx, &frame); +#endif + + /* Restore cx->fp now that we're done releasing frame objects. */ + cx->fp = fp; + +out2: + /* Pop everything we may have allocated off the stack. */ + JS_ARENA_RELEASE(&cx->stackPool, mark); + + /* Store the return value and restore sp just above it. */ + *vp = frame.rval; + fp->sp = vp + 1; + + /* + * Store the location of the JSOP_CALL or JSOP_EVAL that generated the + * return value, but only if this is an external (compiled from script + * source) call that has stack budget for the generating pc. + */ + if (fp->script && !(flags & JSINVOKE_INTERNAL)) + vp[-(intN)fp->script->depth] = (jsval)fp->pc; + return ok; + +bad: + js_ReportIsNotFunction(cx, vp, flags & JSINVOKE_CONSTRUCT); + ok = JS_FALSE; + goto out2; +} + +JSBool +js_InternalInvoke(JSContext *cx, JSObject *obj, jsval fval, uintN flags, + uintN argc, jsval *argv, jsval *rval) +{ + JSStackFrame *fp, *oldfp, frame; + jsval *oldsp, *sp; + void *mark; + uintN i; + JSBool ok; + + fp = oldfp = cx->fp; + if (!fp) { + memset(&frame, 0, sizeof frame); + cx->fp = fp = &frame; + } + oldsp = fp->sp; + sp = js_AllocStack(cx, 2 + argc, &mark); + if (!sp) { + ok = JS_FALSE; + goto out; + } + + PUSH(fval); + PUSH(OBJECT_TO_JSVAL(obj)); + for (i = 0; i < argc; i++) + PUSH(argv[i]); + fp->sp = sp; + ok = js_Invoke(cx, argc, flags | JSINVOKE_INTERNAL); + if (ok) { + RESTORE_SP(fp); + *rval = POP_OPND(); + } + + js_FreeStack(cx, mark); +out: + fp->sp = oldsp; + if (oldfp != fp) + cx->fp = oldfp; + + return ok; +} + +JSBool +js_InternalGetOrSet(JSContext *cx, JSObject *obj, jsid id, jsval fval, + JSAccessMode mode, uintN argc, jsval *argv, jsval *rval) +{ + /* + * Check general (not object-ops/class-specific) access from the running + * script to obj.id only if id has a scripted getter or setter that we're + * about to invoke. If we don't check this case, nothing else will -- no + * other native code has the chance to check. + * + * Contrast this non-native (scripted) case with native getter and setter + * accesses, where the native itself must do an access check, if security + * policies requires it. We make a checkAccess or checkObjectAccess call + * back to the embedding program only in those cases where we're not going + * to call an embedding-defined native function, getter, setter, or class + * hook anyway. Where we do call such a native, there's no need for the + * engine to impose a separate access check callback on all embeddings -- + * many embeddings have no security policy at all. + */ + JS_ASSERT(mode == JSACC_READ || mode == JSACC_WRITE); + if (cx->runtime->checkObjectAccess && + JSVAL_IS_FUNCTION(cx, fval) && + ((JSFunction *) JS_GetPrivate(cx, JSVAL_TO_OBJECT(fval)))->script && + !cx->runtime->checkObjectAccess(cx, obj, ID_TO_VALUE(id), mode, + &fval)) { + return JS_FALSE; + } + + return js_InternalCall(cx, obj, fval, argc, argv, rval); +} + +JSBool +js_Execute(JSContext *cx, JSObject *chain, JSScript *script, + JSStackFrame *down, uintN special, jsval *result) +{ + JSStackFrame *oldfp, frame; + JSObject *obj, *tmp; + JSBool ok; + JSInterpreterHook hook; + void *hookData; + + hook = cx->runtime->executeHook; + hookData = NULL; + oldfp = cx->fp; + frame.callobj = frame.argsobj = NULL; + frame.script = script; + if (down) { + /* Propagate arg/var state for eval and the debugger API. */ + frame.varobj = down->varobj; + frame.fun = down->fun; + frame.thisp = down->thisp; + frame.argc = down->argc; + frame.argv = down->argv; + frame.nvars = down->nvars; + frame.vars = down->vars; + frame.annotation = down->annotation; + frame.sharpArray = down->sharpArray; + } else { + obj = chain; + if (cx->options & JSOPTION_VAROBJFIX) { + while ((tmp = OBJ_GET_PARENT(cx, obj)) != NULL) + obj = tmp; + } + frame.varobj = obj; + frame.fun = NULL; + frame.thisp = chain; + frame.argc = frame.nvars = 0; + frame.argv = frame.vars = NULL; + frame.annotation = NULL; + frame.sharpArray = NULL; + } + frame.rval = JSVAL_VOID; + frame.down = down; + frame.scopeChain = chain; + frame.pc = NULL; + frame.sp = oldfp ? oldfp->sp : NULL; + frame.spbase = NULL; + frame.sharpDepth = 0; + frame.flags = special; + frame.dormantNext = NULL; + frame.objAtomMap = NULL; + + /* + * Here we wrap the call to js_Interpret with code to (conditionally) + * save and restore the old stack frame chain into a chain of 'dormant' + * frame chains. Since we are replacing cx->fp, we were running into + * the problem that if GC was called under this frame, some of the GC + * things associated with the old frame chain (available here only in + * the C variable 'oldfp') were not rooted and were being collected. + * + * So, now we preserve the links to these 'dormant' frame chains in cx + * before calling js_Interpret and cleanup afterwards. The GC walks + * these dormant chains and marks objects in the same way that it marks + * objects in the primary cx->fp chain. + */ + if (oldfp && oldfp != down) { + JS_ASSERT(!oldfp->dormantNext); + oldfp->dormantNext = cx->dormantFrameChain; + cx->dormantFrameChain = oldfp; + } + + cx->fp = &frame; + if (hook) + hookData = hook(cx, &frame, JS_TRUE, 0, cx->runtime->executeHookData); + + ok = js_Interpret(cx, result); + + if (hookData) { + hook = cx->runtime->executeHook; + if (hook) + hook(cx, &frame, JS_FALSE, &ok, hookData); + } + cx->fp = oldfp; + + if (oldfp && oldfp != down) { + JS_ASSERT(cx->dormantFrameChain == oldfp); + cx->dormantFrameChain = oldfp->dormantNext; + oldfp->dormantNext = NULL; + } + + return ok; +} + +#if JS_HAS_EXPORT_IMPORT +/* + * If id is JSVAL_VOID, import all exported properties from obj. + */ +static JSBool +ImportProperty(JSContext *cx, JSObject *obj, jsid id) +{ + JSBool ok; + JSIdArray *ida; + JSProperty *prop; + JSObject *obj2, *target, *funobj, *closure; + JSString *str; + uintN attrs; + jsint i; + jsval value; + + if (JSVAL_IS_VOID(id)) { + ida = JS_Enumerate(cx, obj); + if (!ida) + return JS_FALSE; + ok = JS_TRUE; + if (ida->length == 0) + goto out; + } else { + ida = NULL; + if (!OBJ_LOOKUP_PROPERTY(cx, obj, id, &obj2, &prop)) + return JS_FALSE; + if (!prop) { + str = js_DecompileValueGenerator(cx, JSDVG_IGNORE_STACK, + ID_TO_VALUE(id), NULL); + if (str) + js_ReportIsNotDefined(cx, JS_GetStringBytes(str)); + return JS_FALSE; + } + ok = OBJ_GET_ATTRIBUTES(cx, obj, id, prop, &attrs); + OBJ_DROP_PROPERTY(cx, obj2, prop); + if (!ok) + return JS_FALSE; + if (!(attrs & JSPROP_EXPORTED)) { + str = js_DecompileValueGenerator(cx, JSDVG_IGNORE_STACK, + ID_TO_VALUE(id), NULL); + if (str) { + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, + JSMSG_NOT_EXPORTED, + JS_GetStringBytes(str)); + } + return JS_FALSE; + } + } + + target = cx->fp->varobj; + i = 0; + do { + if (ida) { + id = ida->vector[i]; + ok = OBJ_GET_ATTRIBUTES(cx, obj, id, NULL, &attrs); + if (!ok) + goto out; + if (!(attrs & JSPROP_EXPORTED)) + continue; + } + ok = OBJ_CHECK_ACCESS(cx, obj, id, JSACC_IMPORT, &value, &attrs); + if (!ok) + goto out; + if (JSVAL_IS_FUNCTION(cx, value)) { + funobj = JSVAL_TO_OBJECT(value); + closure = js_CloneFunctionObject(cx, funobj, obj); + if (!closure) { + ok = JS_FALSE; + goto out; + } + value = OBJECT_TO_JSVAL(closure); + } + + /* + * Handle the case of importing a property that refers to a local + * variable or formal parameter of a function activation. These + * properties are accessed by opcodes using stack slot numbers + * generated by the compiler rather than runtime name-lookup. These + * local references, therefore, bypass the normal scope chain lookup. + * So, instead of defining a new property in the activation object, + * modify the existing value in the stack slot. + */ + if (OBJ_GET_CLASS(cx, target) == &js_CallClass) { + ok = OBJ_LOOKUP_PROPERTY(cx, target, id, &obj2, &prop); + if (!ok) + goto out; + } else { + prop = NULL; + } + if (prop && target == obj2) { + ok = OBJ_SET_PROPERTY(cx, target, id, &value); + } else { + ok = OBJ_DEFINE_PROPERTY(cx, target, id, value, NULL, NULL, + attrs & ~JSPROP_EXPORTED, + NULL); + } + if (prop) + OBJ_DROP_PROPERTY(cx, obj2, prop); + if (!ok) + goto out; + } while (ida && ++i < ida->length); + +out: + if (ida) + JS_DestroyIdArray(cx, ida); + return ok; +} +#endif /* JS_HAS_EXPORT_IMPORT */ + +JSBool +js_CheckRedeclaration(JSContext *cx, JSObject *obj, jsid id, uintN attrs, + JSBool *foundp) +{ + JSObject *obj2; + JSProperty *prop; + JSBool ok; + uintN oldAttrs, report; + JSBool isFunction; + jsval value; + const char *type, *name; + + if (!OBJ_LOOKUP_PROPERTY(cx, obj, id, &obj2, &prop)) + return JS_FALSE; + *foundp = (prop != NULL); + if (!prop) + return JS_TRUE; + ok = OBJ_GET_ATTRIBUTES(cx, obj2, id, prop, &oldAttrs); + OBJ_DROP_PROPERTY(cx, obj2, prop); + if (!ok) + return JS_FALSE; + + /* If either property is readonly, we have an error. */ + report = ((oldAttrs | attrs) & JSPROP_READONLY) + ? JSREPORT_ERROR + : JSREPORT_WARNING | JSREPORT_STRICT; + + if (report != JSREPORT_ERROR) { + /* + * Allow redeclaration of variables and functions, but insist that the + * new value is not a getter if the old value was, ditto for setters -- + * unless prop is impermanent (in which case anyone could delete it and + * redefine it, willy-nilly). + */ + if (!(attrs & (JSPROP_GETTER | JSPROP_SETTER))) + return JS_TRUE; + if ((~(oldAttrs ^ attrs) & (JSPROP_GETTER | JSPROP_SETTER)) == 0) + return JS_TRUE; + if (!(oldAttrs & JSPROP_PERMANENT)) + return JS_TRUE; + report = JSREPORT_ERROR; + } + + isFunction = (oldAttrs & (JSPROP_GETTER | JSPROP_SETTER)) != 0; + if (!isFunction) { + if (!OBJ_GET_PROPERTY(cx, obj, id, &value)) + return JS_FALSE; + isFunction = JSVAL_IS_FUNCTION(cx, value); + } + type = (oldAttrs & attrs & JSPROP_GETTER) + ? js_getter_str + : (oldAttrs & attrs & JSPROP_SETTER) + ? js_setter_str + : (oldAttrs & JSPROP_READONLY) + ? js_const_str + : isFunction + ? js_function_str + : js_var_str; + name = js_AtomToPrintableString(cx, (JSAtom *)id); + if (!name) + return JS_FALSE; + return JS_ReportErrorFlagsAndNumber(cx, report, + js_GetErrorMessage, NULL, + JSMSG_REDECLARED_VAR, + type, name); +} + +#ifndef MAX_INTERP_LEVEL +#if defined(XP_OS2) +#define MAX_INTERP_LEVEL 250 +#elif defined _MSC_VER && _MSC_VER <= 800 +#define MAX_INTERP_LEVEL 30 +#else +#define MAX_INTERP_LEVEL 1000 +#endif +#endif + +#define MAX_INLINE_CALL_COUNT 1000 + +JSBool +js_Interpret(JSContext *cx, jsval *result) +{ + JSRuntime *rt; + JSStackFrame *fp; + JSScript *script; + uintN inlineCallCount; + JSObject *obj, *obj2, *proto, *parent; + JSVersion currentVersion, originalVersion; + JSBranchCallback onbranch; + JSBool ok, cond; + JSTrapHandler interruptHandler; + jsint depth, len; + jsval *sp, *newsp; + void *mark; + jsbytecode *pc, *pc2, *endpc; + JSOp op, op2; + const JSCodeSpec *cs; + JSAtom *atom; + uintN argc, slot, attrs; + jsval *vp, lval, rval, ltmp, rtmp; + jsid id; + JSObject *withobj, *origobj, *propobj; + jsval iter_state; + JSProperty *prop; + JSScopeProperty *sprop; + JSString *str, *str2; + jsint i, j; + jsdouble d, d2; + JSClass *clasp, *funclasp; + JSFunction *fun; + JSType type; +#ifdef DEBUG + FILE *tracefp; +#endif +#if JS_HAS_EXPORT_IMPORT + JSIdArray *ida; +#endif +#if JS_HAS_SWITCH_STATEMENT + jsint low, high, off, npairs; + JSBool match; +#endif +#if JS_HAS_GETTER_SETTER + JSPropertyOp getter, setter; +#endif + int stackDummy; + + *result = JSVAL_VOID; + rt = cx->runtime; + + /* Set registerized frame pointer and derived script pointer. */ + fp = cx->fp; + script = fp->script; + + /* Count of JS function calls that nest in this C js_Interpret frame. */ + inlineCallCount = 0; + + /* + * Optimized Get and SetVersion for proper script language versioning. + * + * If any native method or JSClass/JSObjectOps hook calls JS_SetVersion + * and changes cx->version, the effect will "stick" and we will stop + * maintaining currentVersion. This is relied upon by testsuites, for + * the most part -- web browsers select version before compiling and not + * at run-time. + */ + currentVersion = script->version; + originalVersion = cx->version; + if (currentVersion != originalVersion) + JS_SetVersion(cx, currentVersion); + + /* + * Prepare to call a user-supplied branch handler, and abort the script + * if it returns false. + */ + onbranch = cx->branchCallback; + ok = JS_TRUE; +#define CHECK_BRANCH(len) \ + JS_BEGIN_MACRO \ + if (len <= 0 && onbranch) { \ + SAVE_SP(fp); \ + if (!(ok = (*onbranch)(cx, script))) \ + goto out; \ + } \ + JS_END_MACRO + + /* + * Load the debugger's interrupt hook here and after calling out to native + * functions (but not to getters, setters, or other native hooks), so we do + * not have to reload it each time through the interpreter loop -- we hope + * the compiler can keep it in a register. + * XXX if it spills, we still lose + */ +#define LOAD_INTERRUPT_HANDLER(rt) (interruptHandler = (rt)->interruptHandler) + + LOAD_INTERRUPT_HANDLER(rt); + + pc = script->code; + endpc = pc + script->length; + depth = (jsint) script->depth; + len = -1; + + /* Check for too much js_Interpret nesting, or too deep a C stack. */ + if (++cx->interpLevel == MAX_INTERP_LEVEL || + !JS_CHECK_STACK_SIZE(cx, stackDummy)) { + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_OVER_RECURSED); + ok = JS_FALSE; + goto out; + } + + /* + * Allocate operand and pc stack slots for the script's worst-case depth. + */ + newsp = js_AllocRawStack(cx, (uintN)(2 * depth), &mark); + if (!newsp) { + ok = JS_FALSE; + goto out; + } + sp = newsp + depth; + fp->spbase = sp; + SAVE_SP(fp); + + while (pc < endpc) { + fp->pc = pc; + op = (JSOp) *pc; + do_op: + cs = &js_CodeSpec[op]; + len = cs->length; + +#ifdef DEBUG + tracefp = (FILE *) cx->tracefp; + if (tracefp) { + intN nuses, n; + + fprintf(tracefp, "%4u: ", js_PCToLineNumber(cx, script, pc)); + js_Disassemble1(cx, script, pc, + PTRDIFF(pc, script->code, jsbytecode), JS_FALSE, + tracefp); + nuses = cs->nuses; + if (nuses) { + SAVE_SP(fp); + for (n = -nuses; n < 0; n++) { + str = js_DecompileValueGenerator(cx, n, sp[n], NULL); + if (str != NULL) { + fprintf(tracefp, "%s %s", + (n == -nuses) ? " inputs:" : ",", + JS_GetStringBytes(str)); + } + } + fprintf(tracefp, " @ %d\n", sp - fp->spbase); + } + } +#endif + + if (interruptHandler) { + SAVE_SP(fp); + switch (interruptHandler(cx, script, pc, &rval, + rt->interruptHandlerData)) { + case JSTRAP_ERROR: + ok = JS_FALSE; + goto out; + case JSTRAP_CONTINUE: + break; + case JSTRAP_RETURN: + fp->rval = rval; + goto out; +#if JS_HAS_EXCEPTIONS + case JSTRAP_THROW: + cx->throwing = JS_TRUE; + cx->exception = rval; + ok = JS_FALSE; + goto out; +#endif /* JS_HAS_EXCEPTIONS */ + default:; + } + LOAD_INTERRUPT_HANDLER(rt); + } + + switch (op) { + case JSOP_NOP: + break; + + case JSOP_GROUP: + obj = NULL; + break; + + case JSOP_PUSH: + PUSH_OPND(JSVAL_VOID); + break; + + case JSOP_POP: + sp--; + break; + + case JSOP_POP2: + sp -= 2; + break; + + case JSOP_SWAP: + /* + * N.B. JSOP_SWAP doesn't swap the corresponding generating pcs + * for the operands it swaps. + */ + ltmp = sp[-1]; + sp[-1] = sp[-2]; + sp[-2] = ltmp; + break; + + case JSOP_POPV: + *result = POP_OPND(); + break; + + case JSOP_ENTERWITH: + rval = FETCH_OPND(-1); + VALUE_TO_OBJECT(cx, rval, obj); + withobj = js_NewObject(cx, &js_WithClass, obj, fp->scopeChain); + if (!withobj) + goto out; + fp->scopeChain = withobj; + STORE_OPND(-1, OBJECT_TO_JSVAL(withobj)); + break; + + case JSOP_LEAVEWITH: + rval = POP_OPND(); + JS_ASSERT(JSVAL_IS_OBJECT(rval)); + withobj = JSVAL_TO_OBJECT(rval); + JS_ASSERT(OBJ_GET_CLASS(cx, withobj) == &js_WithClass); + + rval = OBJ_GET_SLOT(cx, withobj, JSSLOT_PARENT); + JS_ASSERT(JSVAL_IS_OBJECT(rval)); + fp->scopeChain = JSVAL_TO_OBJECT(rval); + break; + + case JSOP_SETRVAL: + fp->rval = POP_OPND(); + break; + + case JSOP_RETURN: + CHECK_BRANCH(-1); + fp->rval = POP_OPND(); + /* FALL THROUGH */ + + case JSOP_RETRVAL: /* fp->rval already set */ + if (inlineCallCount) + inline_return: + { + JSInlineFrame *ifp = (JSInlineFrame *) fp; + void *hookData = ifp->hookData; + + if (hookData) { + JSInterpreterHook hook = cx->runtime->callHook; + if (hook) { + hook(cx, fp, JS_FALSE, &ok, hookData); + LOAD_INTERRUPT_HANDLER(rt); + } + } +#if JS_HAS_ARGS_OBJECT + if (fp->argsobj) + ok &= js_PutArgsObject(cx, fp); +#endif + + /* Restore context version only if callee hasn't set version. */ + if (cx->version == currentVersion) { + currentVersion = ifp->callerVersion; + if (currentVersion != cx->version) + JS_SetVersion(cx, currentVersion); + } + + /* Store the return value in the caller's operand frame. */ + vp = fp->argv - 2; + *vp = fp->rval; + + /* Restore cx->fp and release the inline frame's space. */ + cx->fp = fp = fp->down; + JS_ARENA_RELEASE(&cx->stackPool, ifp->mark); + + /* Restore sp to point just above the return value. */ + fp->sp = vp + 1; + RESTORE_SP(fp); + + /* Restore the calling script's interpreter registers. */ + script = fp->script; + depth = (jsint) script->depth; + pc = fp->pc; + endpc = script->code + script->length; + + /* Store the generating pc for the return value. */ + vp[-depth] = (jsval)pc; + + /* Set remaining variables for 'goto advance_pc'. */ + op = (JSOp) *pc; + cs = &js_CodeSpec[op]; + len = cs->length; + + /* Resume execution in the calling frame. */ + inlineCallCount--; + if (ok) + goto advance_pc; + } + goto out; + +#if JS_HAS_SWITCH_STATEMENT + case JSOP_DEFAULT: + (void) POP(); + /* FALL THROUGH */ +#endif + case JSOP_GOTO: + len = GET_JUMP_OFFSET(pc); + CHECK_BRANCH(len); + break; + + case JSOP_IFEQ: + POP_BOOLEAN(cx, rval, cond); + if (cond == JS_FALSE) { + len = GET_JUMP_OFFSET(pc); + CHECK_BRANCH(len); + } + break; + + case JSOP_IFNE: + POP_BOOLEAN(cx, rval, cond); + if (cond != JS_FALSE) { + len = GET_JUMP_OFFSET(pc); + CHECK_BRANCH(len); + } + break; + + case JSOP_OR: + POP_BOOLEAN(cx, rval, cond); + if (cond == JS_TRUE) { + len = GET_JUMP_OFFSET(pc); + PUSH_OPND(rval); + } + break; + + case JSOP_AND: + POP_BOOLEAN(cx, rval, cond); + if (cond == JS_FALSE) { + len = GET_JUMP_OFFSET(pc); + PUSH_OPND(rval); + } + break; + + +#if JS_HAS_SWITCH_STATEMENT + case JSOP_DEFAULTX: + (void) POP(); + /* FALL THROUGH */ +#endif + case JSOP_GOTOX: + len = GET_JUMPX_OFFSET(pc); + CHECK_BRANCH(len); + break; + + case JSOP_IFEQX: + POP_BOOLEAN(cx, rval, cond); + if (cond == JS_FALSE) { + len = GET_JUMPX_OFFSET(pc); + CHECK_BRANCH(len); + } + break; + + case JSOP_IFNEX: + POP_BOOLEAN(cx, rval, cond); + if (cond != JS_FALSE) { + len = GET_JUMPX_OFFSET(pc); + CHECK_BRANCH(len); + } + break; + + case JSOP_ORX: + POP_BOOLEAN(cx, rval, cond); + if (cond == JS_TRUE) { + len = GET_JUMPX_OFFSET(pc); + PUSH_OPND(rval); + } + break; + + case JSOP_ANDX: + POP_BOOLEAN(cx, rval, cond); + if (cond == JS_FALSE) { + len = GET_JUMPX_OFFSET(pc); + PUSH_OPND(rval); + } + break; + + case JSOP_TOOBJECT: + SAVE_SP(fp); + ok = js_ValueToObject(cx, FETCH_OPND(-1), &obj); + if (!ok) + goto out; + STORE_OPND(-1, OBJECT_TO_JSVAL(obj)); + break; + +#define FETCH_ELEMENT_ID(n, id) \ + JS_BEGIN_MACRO \ + /* If the index is not a jsint, atomize it. */ \ + id = (jsid) FETCH_OPND(n); \ + if (JSVAL_IS_INT(id)) { \ + atom = NULL; \ + } else { \ + SAVE_SP(fp); \ + atom = js_ValueToStringAtom(cx, (jsval)id); \ + if (!atom) { \ + ok = JS_FALSE; \ + goto out; \ + } \ + id = (jsid)atom; \ + } \ + JS_END_MACRO + +#define POP_ELEMENT_ID(id) \ + JS_BEGIN_MACRO \ + FETCH_ELEMENT_ID(-1, id); \ + sp--; \ + JS_END_MACRO + +#if JS_HAS_IN_OPERATOR + case JSOP_IN: + rval = FETCH_OPND(-1); + if (JSVAL_IS_PRIMITIVE(rval)) { + str = js_DecompileValueGenerator(cx, -1, rval, NULL); + if (str) { + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, + JSMSG_IN_NOT_OBJECT, + JS_GetStringBytes(str)); + } + ok = JS_FALSE; + goto out; + } + sp--; + obj = JSVAL_TO_OBJECT(rval); + FETCH_ELEMENT_ID(-1, id); + ok = OBJ_LOOKUP_PROPERTY(cx, obj, id, &obj2, &prop); + if (!ok) + goto out; + STORE_OPND(-1, BOOLEAN_TO_JSVAL(prop != NULL)); + if (prop) + OBJ_DROP_PROPERTY(cx, obj2, prop); + break; +#endif /* JS_HAS_IN_OPERATOR */ + + case JSOP_FORPROP: + /* + * Handle JSOP_FORPROP first, so the cost of the goto do_forinloop + * is not paid for the more common cases. + */ + lval = FETCH_OPND(-1); + atom = GET_ATOM(cx, script, pc); + id = (jsid)atom; + i = -2; + goto do_forinloop; + + case JSOP_FORNAME: + atom = GET_ATOM(cx, script, pc); + id = (jsid)atom; + + /* + * ECMA 12.6.3 says to eval the LHS after looking for properties + * to enumerate, and bail without LHS eval if there are no props. + * We do Find here to share the most code at label do_forinloop. + * If looking for enumerable properties could have side effects, + * then we'd have to move this into the common code and condition + * it on op == JSOP_FORNAME. + */ + SAVE_SP(fp); + ok = js_FindProperty(cx, id, &obj, &obj2, &prop); + if (!ok) + goto out; + if (prop) + OBJ_DROP_PROPERTY(cx, obj2, prop); + lval = OBJECT_TO_JSVAL(obj); + /* FALL THROUGH */ + + case JSOP_FORARG: + case JSOP_FORVAR: + /* + * JSOP_FORARG and JSOP_FORVAR don't require any lval computation + * here, because they address slots on the stack (in fp->args and + * fp->vars, respectively). + */ + /* FALL THROUGH */ + + case JSOP_FORELEM: + /* + * JSOP_FORELEM simply initializes or updates the iteration state + * and leaves the index expression evaluation and assignment to the + * enumerator until after the next property has been acquired, via + * a JSOP_ENUMELEM bytecode. + */ + i = -1; + + do_forinloop: + /* + * ECMA-compatible for/in evals the object just once, before loop. + * Bad old bytecodes (since removed) did it on every iteration. + */ + obj = JSVAL_TO_OBJECT(sp[i]); + + /* If the thing to the right of 'in' has no properties, break. */ + if (!obj) { + rval = JSVAL_FALSE; + goto end_forinloop; + } + + /* + * Save the thing to the right of 'in' as origobj. Later on, we + * use this variable to suppress enumeration of shadowed prototype + * properties. + */ + origobj = obj; + + /* + * Reach under the top of stack to find our property iterator, a + * JSObject that contains the iteration state. (An object is used + * rather than a native struct so that the iteration state is + * cleaned up via GC if the for-in loop terminates abruptly.) + */ + vp = &sp[i - 1]; + rval = *vp; + + /* Is this the first iteration ? */ + if (JSVAL_IS_VOID(rval)) { + /* Yes, create a new JSObject to hold the iterator state */ + propobj = js_NewObject(cx, &prop_iterator_class, NULL, obj); + if (!propobj) { + ok = JS_FALSE; + goto out; + } + propobj->slots[JSSLOT_ITER_STATE] = JSVAL_NULL; + + /* + * Root the parent slot so we can get it even in our finalizer + * (otherwise, it would live as long as we do, but it might be + * finalized first). + */ + ok = js_AddRoot(cx, &propobj->slots[JSSLOT_PARENT], + "propobj->parent"); + if (!ok) + goto out; + + /* + * Rewrite the iterator so we know to do the next case. + * Do this before calling the enumerator, which could + * displace cx->newborn and cause GC. + */ + *vp = OBJECT_TO_JSVAL(propobj); + + ok = OBJ_ENUMERATE(cx, obj, JSENUMERATE_INIT, &iter_state, 0); + + /* + * Stash private iteration state into property iterator object. + * We do this before checking 'ok' to ensure that propobj is + * in a valid state even if OBJ_ENUMERATE returned JS_FALSE. + * NB: This code knows that the first slots are pre-allocated. + */ +#if JS_INITIAL_NSLOTS < 5 +#error JS_INITIAL_NSLOTS must be greater than or equal to 5. +#endif + propobj->slots[JSSLOT_ITER_STATE] = iter_state; + if (!ok) + goto out; + } else { + /* This is not the first iteration. Recover iterator state. */ + propobj = JSVAL_TO_OBJECT(rval); + obj = JSVAL_TO_OBJECT(propobj->slots[JSSLOT_PARENT]); + iter_state = propobj->slots[JSSLOT_ITER_STATE]; + } + + enum_next_property: + /* Get the next jsid to be enumerated and store it in rval. */ + OBJ_ENUMERATE(cx, obj, JSENUMERATE_NEXT, &iter_state, &rval); + propobj->slots[JSSLOT_ITER_STATE] = iter_state; + + /* No more jsids to iterate in obj? */ + if (iter_state == JSVAL_NULL) { + /* Enumerate the properties on obj's prototype chain. */ + obj = OBJ_GET_PROTO(cx, obj); + if (!obj) { + /* End of property list -- terminate loop. */ + rval = JSVAL_FALSE; + goto end_forinloop; + } + + ok = OBJ_ENUMERATE(cx, obj, JSENUMERATE_INIT, &iter_state, 0); + + /* + * Stash private iteration state into property iterator object. + * We do this before checking 'ok' to ensure that propobj is + * in a valid state even if OBJ_ENUMERATE returned JS_FALSE. + * NB: This code knows that the first slots are pre-allocated. + */ + propobj->slots[JSSLOT_ITER_STATE] = iter_state; + if (!ok) + goto out; + + /* + * Update the iterator JSObject's parent link to refer to the + * current object. This is used in the iterator JSObject's + * finalizer. + */ + propobj->slots[JSSLOT_PARENT] = OBJECT_TO_JSVAL(obj); + goto enum_next_property; + } + + /* Skip properties not owned by obj, and leave next id in rval. */ + ok = OBJ_LOOKUP_PROPERTY(cx, origobj, rval, &obj2, &prop); + if (!ok) + goto out; + if (prop) { + OBJ_DROP_PROPERTY(cx, obj2, prop); + + /* Yes, don't enumerate again. Go to the next property. */ + if (obj2 != obj) + goto enum_next_property; + } + + /* Make sure rval is a string for uniformity and compatibility. */ + if (!JSVAL_IS_INT(rval)) { + rval = ATOM_KEY((JSAtom *)rval); + } else if (cx->version != JSVERSION_1_2) { + str = js_NumberToString(cx, (jsdouble) JSVAL_TO_INT(rval)); + if (!str) { + ok = JS_FALSE; + goto out; + } + + rval = STRING_TO_JSVAL(str); + } + + switch (op) { + case JSOP_FORARG: + slot = GET_ARGNO(pc); + JS_ASSERT(slot < fp->fun->nargs); + fp->argv[slot] = rval; + break; + + case JSOP_FORVAR: + slot = GET_VARNO(pc); + JS_ASSERT(slot < fp->fun->nvars); + fp->vars[slot] = rval; + break; + + case JSOP_FORELEM: + /* FORELEM is not a SET operation, it's more like BINDNAME. */ + PUSH_OPND(rval); + break; + + default: + /* Convert lval to a non-null object containing id. */ + VALUE_TO_OBJECT(cx, lval, obj); + + /* Set the variable obj[id] to refer to rval. */ + fp->flags |= JSFRAME_ASSIGNING; + ok = OBJ_SET_PROPERTY(cx, obj, id, &rval); + fp->flags &= ~JSFRAME_ASSIGNING; + if (!ok) + goto out; + break; + } + + /* Push true to keep looping through properties. */ + rval = JSVAL_TRUE; + + end_forinloop: + sp += i + 1; + PUSH_OPND(rval); + break; + + case JSOP_DUP: + JS_ASSERT(sp > fp->spbase); + rval = sp[-1]; + PUSH_OPND(rval); + break; + + case JSOP_DUP2: + JS_ASSERT(sp - 1 > fp->spbase); + lval = FETCH_OPND(-2); + rval = FETCH_OPND(-1); + PUSH_OPND(lval); + PUSH_OPND(rval); + break; + +#define PROPERTY_OP(n, call) \ + JS_BEGIN_MACRO \ + /* Pop the left part and resolve it to a non-null object. */ \ + lval = FETCH_OPND(n); \ + VALUE_TO_OBJECT(cx, lval, obj); \ + \ + /* Get or set the property, set ok false if error, true if success. */\ + SAVE_SP(fp); \ + call; \ + if (!ok) \ + goto out; \ + JS_END_MACRO + +#define ELEMENT_OP(n, call) \ + JS_BEGIN_MACRO \ + FETCH_ELEMENT_ID(n, id); \ + PROPERTY_OP(n-1, call); \ + JS_END_MACRO + +/* + * Direct callers, i.e. those who do not wrap CACHED_GET and CACHED_SET calls + * in PROPERTY_OP or ELEMENT_OP macro calls must SAVE_SP(fp); beforehand, just + * in case a getter or setter function is invoked. + */ +#define CACHED_GET(call) \ + JS_BEGIN_MACRO \ + if (!OBJ_IS_NATIVE(obj)) { \ + ok = call; \ + } else { \ + JS_LOCK_OBJ(cx, obj); \ + PROPERTY_CACHE_TEST(&rt->propertyCache, obj, id, sprop); \ + if (sprop) { \ + JSScope *scope_ = OBJ_SCOPE(obj); \ + slot = (uintN)sprop->slot; \ + rval = (slot != SPROP_INVALID_SLOT) \ + ? LOCKED_OBJ_GET_SLOT(obj, slot) \ + : JSVAL_VOID; \ + JS_UNLOCK_SCOPE(cx, scope_); \ + ok = SPROP_GET(cx, sprop, obj, obj, &rval); \ + JS_LOCK_SCOPE(cx, scope_); \ + if (ok && SPROP_HAS_VALID_SLOT(sprop, scope_)) \ + LOCKED_OBJ_SET_SLOT(obj, slot, rval); \ + JS_UNLOCK_SCOPE(cx, scope_); \ + } else { \ + JS_UNLOCK_OBJ(cx, obj); \ + ok = call; \ + /* No fill here: js_GetProperty fills the cache. */ \ + } \ + } \ + JS_END_MACRO + +#define CACHED_SET(call) \ + JS_BEGIN_MACRO \ + if (!OBJ_IS_NATIVE(obj)) { \ + ok = call; \ + } else { \ + JSScope *scope_; \ + JS_LOCK_OBJ(cx, obj); \ + PROPERTY_CACHE_TEST(&rt->propertyCache, obj, id, sprop); \ + if (sprop && \ + !(sprop->attrs & JSPROP_READONLY) && \ + (scope_ = OBJ_SCOPE(obj), !SCOPE_IS_SEALED(scope_))) { \ + JS_UNLOCK_SCOPE(cx, scope_); \ + ok = SPROP_SET(cx, sprop, obj, obj, &rval); \ + JS_LOCK_SCOPE(cx, scope_); \ + if (ok && SPROP_HAS_VALID_SLOT(sprop, scope_)) { \ + LOCKED_OBJ_SET_SLOT(obj, sprop->slot, rval); \ + GC_POKE(cx, JSVAL_NULL); /* XXX second arg ignored */ \ + } \ + JS_UNLOCK_SCOPE(cx, scope_); \ + } else { \ + JS_UNLOCK_OBJ(cx, obj); \ + ok = call; \ + /* No fill here: js_SetProperty writes through the cache. */ \ + } \ + } \ + JS_END_MACRO + + case JSOP_SETCONST: + obj = fp->varobj; + atom = GET_ATOM(cx, script, pc); + rval = FETCH_OPND(-1); + ok = OBJ_DEFINE_PROPERTY(cx, obj, (jsid)atom, rval, NULL, NULL, + JSPROP_ENUMERATE | JSPROP_PERMANENT | + JSPROP_READONLY, + NULL); + if (!ok) + goto out; + STORE_OPND(-1, rval); + break; + + case JSOP_BINDNAME: + atom = GET_ATOM(cx, script, pc); + SAVE_SP(fp); + obj = js_FindIdentifierBase(cx, (jsid)atom); + if (!obj) { + ok = JS_FALSE; + goto out; + } + PUSH_OPND(OBJECT_TO_JSVAL(obj)); + break; + + case JSOP_SETNAME: + atom = GET_ATOM(cx, script, pc); + id = (jsid)atom; + rval = FETCH_OPND(-1); + lval = FETCH_OPND(-2); + JS_ASSERT(!JSVAL_IS_PRIMITIVE(lval)); + obj = JSVAL_TO_OBJECT(lval); + SAVE_SP(fp); + CACHED_SET(OBJ_SET_PROPERTY(cx, obj, id, &rval)); + if (!ok) + goto out; + sp--; + STORE_OPND(-1, rval); + break; + +#define INTEGER_OP(OP, EXTRA_CODE) \ + JS_BEGIN_MACRO \ + FETCH_INT(cx, -1, j); \ + FETCH_INT(cx, -2, i); \ + if (!ok) \ + goto out; \ + EXTRA_CODE \ + d = i OP j; \ + sp--; \ + STORE_NUMBER(cx, -1, d); \ + JS_END_MACRO + +#define BITWISE_OP(OP) INTEGER_OP(OP, (void) 0;) +#define SIGNED_SHIFT_OP(OP) INTEGER_OP(OP, j &= 31;) + + case JSOP_BITOR: + BITWISE_OP(|); + break; + + case JSOP_BITXOR: + BITWISE_OP(^); + break; + + case JSOP_BITAND: + BITWISE_OP(&); + break; + +#if defined(XP_WIN) +#define COMPARE_DOUBLES(LVAL, OP, RVAL, IFNAN) \ + ((JSDOUBLE_IS_NaN(LVAL) || JSDOUBLE_IS_NaN(RVAL)) \ + ? (IFNAN) \ + : (LVAL) OP (RVAL)) +#else +#define COMPARE_DOUBLES(LVAL, OP, RVAL, IFNAN) ((LVAL) OP (RVAL)) +#endif + +#define RELATIONAL_OP(OP) \ + JS_BEGIN_MACRO \ + rval = FETCH_OPND(-1); \ + lval = FETCH_OPND(-2); \ + /* Optimize for two int-tagged operands (typical loop control). */ \ + if ((lval & rval) & JSVAL_INT) { \ + ltmp = lval ^ JSVAL_VOID; \ + rtmp = rval ^ JSVAL_VOID; \ + if (ltmp && rtmp) { \ + cond = JSVAL_TO_INT(lval) OP JSVAL_TO_INT(rval); \ + } else { \ + d = ltmp ? JSVAL_TO_INT(lval) : *rt->jsNaN; \ + d2 = rtmp ? JSVAL_TO_INT(rval) : *rt->jsNaN; \ + cond = COMPARE_DOUBLES(d, OP, d2, JS_FALSE); \ + } \ + } else { \ + VALUE_TO_PRIMITIVE(cx, lval, JSTYPE_NUMBER, &lval); \ + VALUE_TO_PRIMITIVE(cx, rval, JSTYPE_NUMBER, &rval); \ + if (JSVAL_IS_STRING(lval) && JSVAL_IS_STRING(rval)) { \ + str = JSVAL_TO_STRING(lval); \ + str2 = JSVAL_TO_STRING(rval); \ + cond = js_CompareStrings(str, str2) OP 0; \ + } else { \ + VALUE_TO_NUMBER(cx, lval, d); \ + VALUE_TO_NUMBER(cx, rval, d2); \ + cond = COMPARE_DOUBLES(d, OP, d2, JS_FALSE); \ + } \ + } \ + sp--; \ + STORE_OPND(-1, BOOLEAN_TO_JSVAL(cond)); \ + JS_END_MACRO + +#define EQUALITY_OP(OP, IFNAN) \ + JS_BEGIN_MACRO \ + rval = FETCH_OPND(-1); \ + lval = FETCH_OPND(-2); \ + ltmp = JSVAL_TAG(lval); \ + rtmp = JSVAL_TAG(rval); \ + if (ltmp == rtmp) { \ + if (ltmp == JSVAL_STRING) { \ + str = JSVAL_TO_STRING(lval); \ + str2 = JSVAL_TO_STRING(rval); \ + cond = js_CompareStrings(str, str2) OP 0; \ + } else if (ltmp == JSVAL_DOUBLE) { \ + d = *JSVAL_TO_DOUBLE(lval); \ + d2 = *JSVAL_TO_DOUBLE(rval); \ + cond = COMPARE_DOUBLES(d, OP, d2, IFNAN); \ + } else { \ + /* Handle all undefined (=>NaN) and int combinations. */ \ + cond = lval OP rval; \ + } \ + } else { \ + if (JSVAL_IS_NULL(lval) || JSVAL_IS_VOID(lval)) { \ + cond = (JSVAL_IS_NULL(rval) || JSVAL_IS_VOID(rval)) OP 1; \ + } else if (JSVAL_IS_NULL(rval) || JSVAL_IS_VOID(rval)) { \ + cond = 1 OP 0; \ + } else { \ + if (ltmp == JSVAL_OBJECT) { \ + VALUE_TO_PRIMITIVE(cx, lval, JSTYPE_VOID, &lval); \ + ltmp = JSVAL_TAG(lval); \ + } else if (rtmp == JSVAL_OBJECT) { \ + VALUE_TO_PRIMITIVE(cx, rval, JSTYPE_VOID, &rval); \ + rtmp = JSVAL_TAG(rval); \ + } \ + if (ltmp == JSVAL_STRING && rtmp == JSVAL_STRING) { \ + str = JSVAL_TO_STRING(lval); \ + str2 = JSVAL_TO_STRING(rval); \ + cond = js_CompareStrings(str, str2) OP 0; \ + } else { \ + VALUE_TO_NUMBER(cx, lval, d); \ + VALUE_TO_NUMBER(cx, rval, d2); \ + cond = COMPARE_DOUBLES(d, OP, d2, IFNAN); \ + } \ + } \ + } \ + sp--; \ + STORE_OPND(-1, BOOLEAN_TO_JSVAL(cond)); \ + JS_END_MACRO + + case JSOP_EQ: + EQUALITY_OP(==, JS_FALSE); + break; + + case JSOP_NE: + EQUALITY_OP(!=, JS_TRUE); + break; + +#if !JS_BUG_FALLIBLE_EQOPS +#define NEW_EQUALITY_OP(OP, IFNAN) \ + JS_BEGIN_MACRO \ + rval = FETCH_OPND(-1); \ + lval = FETCH_OPND(-2); \ + ltmp = JSVAL_TAG(lval); \ + rtmp = JSVAL_TAG(rval); \ + if (ltmp == rtmp) { \ + if (ltmp == JSVAL_STRING) { \ + str = JSVAL_TO_STRING(lval); \ + str2 = JSVAL_TO_STRING(rval); \ + cond = js_CompareStrings(str, str2) OP 0; \ + } else if (ltmp == JSVAL_DOUBLE) { \ + d = *JSVAL_TO_DOUBLE(lval); \ + d2 = *JSVAL_TO_DOUBLE(rval); \ + cond = COMPARE_DOUBLES(d, OP, d2, IFNAN); \ + } else { \ + cond = lval OP rval; \ + } \ + } else { \ + if (ltmp == JSVAL_DOUBLE && JSVAL_IS_INT(rval)) { \ + d = *JSVAL_TO_DOUBLE(lval); \ + d2 = JSVAL_TO_INT(rval); \ + cond = COMPARE_DOUBLES(d, OP, d2, IFNAN); \ + } else if (JSVAL_IS_INT(lval) && rtmp == JSVAL_DOUBLE) { \ + d = JSVAL_TO_INT(lval); \ + d2 = *JSVAL_TO_DOUBLE(rval); \ + cond = COMPARE_DOUBLES(d, OP, d2, IFNAN); \ + } else { \ + cond = lval OP rval; \ + } \ + } \ + sp--; \ + STORE_OPND(-1, BOOLEAN_TO_JSVAL(cond)); \ + JS_END_MACRO + + case JSOP_NEW_EQ: + NEW_EQUALITY_OP(==, JS_FALSE); + break; + + case JSOP_NEW_NE: + NEW_EQUALITY_OP(!=, JS_TRUE); + break; + +#if JS_HAS_SWITCH_STATEMENT + case JSOP_CASE: + NEW_EQUALITY_OP(==, JS_FALSE); + (void) POP(); + if (cond) { + len = GET_JUMP_OFFSET(pc); + CHECK_BRANCH(len); + } else { + PUSH(lval); + } + break; + + case JSOP_CASEX: + NEW_EQUALITY_OP(==, JS_FALSE); + (void) POP(); + if (cond) { + len = GET_JUMPX_OFFSET(pc); + CHECK_BRANCH(len); + } else { + PUSH(lval); + } + break; +#endif + +#endif /* !JS_BUG_FALLIBLE_EQOPS */ + + case JSOP_LT: + RELATIONAL_OP(<); + break; + + case JSOP_LE: + RELATIONAL_OP(<=); + break; + + case JSOP_GT: + RELATIONAL_OP(>); + break; + + case JSOP_GE: + RELATIONAL_OP(>=); + break; + +#undef EQUALITY_OP +#undef RELATIONAL_OP + + case JSOP_LSH: + SIGNED_SHIFT_OP(<<); + break; + + case JSOP_RSH: + SIGNED_SHIFT_OP(>>); + break; + + case JSOP_URSH: + { + uint32 u; + + FETCH_INT(cx, -1, j); + FETCH_UINT(cx, -2, u); + j &= 31; + d = u >> j; + sp--; + STORE_NUMBER(cx, -1, d); + break; + } + +#undef INTEGER_OP +#undef BITWISE_OP +#undef SIGNED_SHIFT_OP + + case JSOP_ADD: + rval = FETCH_OPND(-1); + lval = FETCH_OPND(-2); + VALUE_TO_PRIMITIVE(cx, lval, JSTYPE_VOID, <mp); + VALUE_TO_PRIMITIVE(cx, rval, JSTYPE_VOID, &rtmp); + if ((cond = JSVAL_IS_STRING(ltmp)) || JSVAL_IS_STRING(rtmp)) { + if (cond) { + str = JSVAL_TO_STRING(ltmp); + SAVE_SP(fp); + ok = (str2 = js_ValueToString(cx, rtmp)) != NULL; + } else { + str2 = JSVAL_TO_STRING(rtmp); + SAVE_SP(fp); + ok = (str = js_ValueToString(cx, ltmp)) != NULL; + } + if (!ok) + goto out; + str = js_ConcatStrings(cx, str, str2); + if (!str) { + ok = JS_FALSE; + goto out; + } + sp--; + STORE_OPND(-1, STRING_TO_JSVAL(str)); + } else { + VALUE_TO_NUMBER(cx, lval, d); + VALUE_TO_NUMBER(cx, rval, d2); + d += d2; + sp--; + STORE_NUMBER(cx, -1, d); + } + break; + +#define BINARY_OP(OP) \ + JS_BEGIN_MACRO \ + FETCH_NUMBER(cx, -1, d2); \ + FETCH_NUMBER(cx, -2, d); \ + d = d OP d2; \ + sp--; \ + STORE_NUMBER(cx, -1, d); \ + JS_END_MACRO + + case JSOP_SUB: + BINARY_OP(-); + break; + + case JSOP_MUL: + BINARY_OP(*); + break; + + case JSOP_DIV: + FETCH_NUMBER(cx, -1, d2); + FETCH_NUMBER(cx, -2, d); + sp--; + if (d2 == 0) { +#if defined(XP_WIN) + /* XXX MSVC miscompiles such that (NaN == 0) */ + if (JSDOUBLE_IS_NaN(d2)) + rval = DOUBLE_TO_JSVAL(rt->jsNaN); + else +#endif + if (d == 0 || JSDOUBLE_IS_NaN(d)) + rval = DOUBLE_TO_JSVAL(rt->jsNaN); + else if ((JSDOUBLE_HI32(d) ^ JSDOUBLE_HI32(d2)) >> 31) + rval = DOUBLE_TO_JSVAL(rt->jsNegativeInfinity); + else + rval = DOUBLE_TO_JSVAL(rt->jsPositiveInfinity); + STORE_OPND(-1, rval); + } else { + d /= d2; + STORE_NUMBER(cx, -1, d); + } + break; + + case JSOP_MOD: + FETCH_NUMBER(cx, -1, d2); + FETCH_NUMBER(cx, -2, d); + sp--; + if (d2 == 0) { + STORE_OPND(-1, DOUBLE_TO_JSVAL(rt->jsNaN)); + } else { +#if defined(XP_WIN) + /* Workaround MS fmod bug where 42 % (1/0) => NaN, not 42. */ + if (!(JSDOUBLE_IS_FINITE(d) && JSDOUBLE_IS_INFINITE(d2))) +#endif + d = fmod(d, d2); + STORE_NUMBER(cx, -1, d); + } + break; + + case JSOP_NOT: + POP_BOOLEAN(cx, rval, cond); + PUSH_OPND(BOOLEAN_TO_JSVAL(!cond)); + break; + + case JSOP_BITNOT: + FETCH_INT(cx, -1, i); + d = (jsdouble) ~i; + STORE_NUMBER(cx, -1, d); + break; + + case JSOP_NEG: + FETCH_NUMBER(cx, -1, d); +#ifdef HPUX + /* + * Negation of a zero doesn't produce a negative + * zero on HPUX. Perform the operation by bit + * twiddling. + */ + JSDOUBLE_HI32(d) ^= JSDOUBLE_HI32_SIGNBIT; +#else + d = -d; +#endif + STORE_NUMBER(cx, -1, d); + break; + + case JSOP_POS: + FETCH_NUMBER(cx, -1, d); + STORE_NUMBER(cx, -1, d); + break; + + case JSOP_NEW: + /* Get immediate argc and find the constructor function. */ + argc = GET_ARGC(pc); + +#if JS_HAS_INITIALIZERS + do_new: +#endif + vp = sp - (2 + argc); + JS_ASSERT(vp >= fp->spbase); + + fun = NULL; + obj2 = NULL; + lval = *vp; + if (!JSVAL_IS_OBJECT(lval) || + (obj2 = JSVAL_TO_OBJECT(lval)) == NULL || + /* XXX clean up to avoid special cases above ObjectOps layer */ + OBJ_GET_CLASS(cx, obj2) == &js_FunctionClass || + !obj2->map->ops->construct) + { + SAVE_SP(fp); + fun = js_ValueToFunction(cx, vp, JSV2F_CONSTRUCT); + if (!fun) { + ok = JS_FALSE; + goto out; + } + } + + clasp = &js_ObjectClass; + if (!obj2) { + proto = parent = NULL; + fun = NULL; + } else { + /* Get the constructor prototype object for this function. */ + ok = OBJ_GET_PROPERTY(cx, obj2, + (jsid)rt->atomState.classPrototypeAtom, + &rval); + if (!ok) + goto out; + proto = JSVAL_IS_OBJECT(rval) ? JSVAL_TO_OBJECT(rval) : NULL; + parent = OBJ_GET_PARENT(cx, obj2); + + if (OBJ_GET_CLASS(cx, obj2) == &js_FunctionClass) { + funclasp = ((JSFunction *)JS_GetPrivate(cx, obj2))->clasp; + if (funclasp) + clasp = funclasp; + } + } + obj = js_NewObject(cx, clasp, proto, parent); + if (!obj) { + ok = JS_FALSE; + goto out; + } + + /* Now we have an object with a constructor method; call it. */ + vp[1] = OBJECT_TO_JSVAL(obj); + SAVE_SP(fp); + ok = js_Invoke(cx, argc, JSINVOKE_CONSTRUCT); + RESTORE_SP(fp); + LOAD_INTERRUPT_HANDLER(rt); + if (!ok) { + cx->newborn[GCX_OBJECT] = NULL; + goto out; + } + + /* Check the return value and update obj from it. */ + rval = *vp; + if (JSVAL_IS_PRIMITIVE(rval)) { + if (fun || !JSVERSION_IS_ECMA(cx->version)) { + *vp = OBJECT_TO_JSVAL(obj); + break; + } + /* native [[Construct]] returning primitive is error */ + str = js_ValueToString(cx, rval); + if (str) { + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, + JSMSG_BAD_NEW_RESULT, + JS_GetStringBytes(str)); + } + ok = JS_FALSE; + goto out; + } + obj = JSVAL_TO_OBJECT(rval); + JS_RUNTIME_METER(rt, constructs); + break; + + case JSOP_DELNAME: + atom = GET_ATOM(cx, script, pc); + id = (jsid)atom; + + SAVE_SP(fp); + ok = js_FindProperty(cx, id, &obj, &obj2, &prop); + if (!ok) + goto out; + + /* ECMA says to return true if name is undefined or inherited. */ + rval = JSVAL_TRUE; + if (prop) { + OBJ_DROP_PROPERTY(cx, obj2, prop); + ok = OBJ_DELETE_PROPERTY(cx, obj, id, &rval); + if (!ok) + goto out; + } + PUSH_OPND(rval); + break; + + case JSOP_DELPROP: + atom = GET_ATOM(cx, script, pc); + id = (jsid)atom; + PROPERTY_OP(-1, ok = OBJ_DELETE_PROPERTY(cx, obj, id, &rval)); + STORE_OPND(-1, rval); + break; + + case JSOP_DELELEM: + ELEMENT_OP(-1, ok = OBJ_DELETE_PROPERTY(cx, obj, id, &rval)); + sp--; + STORE_OPND(-1, rval); + break; + + case JSOP_TYPEOF: + rval = POP_OPND(); + type = JS_TypeOfValue(cx, rval); + atom = rt->atomState.typeAtoms[type]; + str = ATOM_TO_STRING(atom); + PUSH_OPND(STRING_TO_JSVAL(str)); + break; + + case JSOP_VOID: + (void) POP_OPND(); + PUSH_OPND(JSVAL_VOID); + break; + + case JSOP_INCNAME: + case JSOP_DECNAME: + case JSOP_NAMEINC: + case JSOP_NAMEDEC: + atom = GET_ATOM(cx, script, pc); + id = (jsid)atom; + + SAVE_SP(fp); + ok = js_FindProperty(cx, id, &obj, &obj2, &prop); + if (!ok) + goto out; + if (!prop) + goto atom_not_defined; + + OBJ_DROP_PROPERTY(cx, obj2, prop); + lval = OBJECT_TO_JSVAL(obj); + goto do_incop; + + case JSOP_INCPROP: + case JSOP_DECPROP: + case JSOP_PROPINC: + case JSOP_PROPDEC: + atom = GET_ATOM(cx, script, pc); + id = (jsid)atom; + lval = POP_OPND(); + goto do_incop; + + case JSOP_INCELEM: + case JSOP_DECELEM: + case JSOP_ELEMINC: + case JSOP_ELEMDEC: + POP_ELEMENT_ID(id); + lval = POP_OPND(); + + do_incop: + VALUE_TO_OBJECT(cx, lval, obj); + + /* The operand must contain a number. */ + SAVE_SP(fp); + CACHED_GET(OBJ_GET_PROPERTY(cx, obj, id, &rval)); + if (!ok) + goto out; + + /* The expression result goes in rtmp, the updated value in rval. */ + if (JSVAL_IS_INT(rval) && + rval != INT_TO_JSVAL(JSVAL_INT_MIN) && + rval != INT_TO_JSVAL(JSVAL_INT_MAX)) { + if (cs->format & JOF_POST) { + rtmp = rval; + (cs->format & JOF_INC) ? (rval += 2) : (rval -= 2); + } else { + (cs->format & JOF_INC) ? (rval += 2) : (rval -= 2); + rtmp = rval; + } + } else { + +/* + * Initially, rval contains the value to increment or decrement, which is not + * yet converted. As above, the expression result goes in rtmp, the updated + * value goes in rval. + */ +#define NONINT_INCREMENT_OP() \ + JS_BEGIN_MACRO \ + VALUE_TO_NUMBER(cx, rval, d); \ + if (cs->format & JOF_POST) { \ + rtmp = rval; \ + if (!JSVAL_IS_NUMBER(rtmp)) { \ + ok = js_NewNumberValue(cx, d, &rtmp); \ + if (!ok) \ + goto out; \ + } \ + (cs->format & JOF_INC) ? d++ : d--; \ + ok = js_NewNumberValue(cx, d, &rval); \ + } else { \ + (cs->format & JOF_INC) ? ++d : --d; \ + ok = js_NewNumberValue(cx, d, &rval); \ + rtmp = rval; \ + } \ + if (!ok) \ + goto out; \ + JS_END_MACRO + + NONINT_INCREMENT_OP(); + } + + CACHED_SET(OBJ_SET_PROPERTY(cx, obj, id, &rval)); + if (!ok) + goto out; + PUSH_OPND(rtmp); + break; + +/* + * NB: This macro can't use JS_BEGIN_MACRO/JS_END_MACRO around its body because + * it must break from the switch case that calls it, not from the do...while(0) + * loop created by the JS_BEGIN/END_MACRO brackets. + */ +#define FAST_INCREMENT_OP(SLOT,COUNT,BASE,PRE,OP,MINMAX) \ + slot = (uintN)SLOT; \ + JS_ASSERT(slot < fp->fun->COUNT); \ + vp = fp->BASE + slot; \ + rval = *vp; \ + if (JSVAL_IS_INT(rval) && \ + rval != INT_TO_JSVAL(JSVAL_INT_##MINMAX)) { \ + PRE = rval; \ + rval OP 2; \ + *vp = rval; \ + PUSH_OPND(PRE); \ + break; \ + } \ + goto do_nonint_fast_incop; + + case JSOP_INCARG: + FAST_INCREMENT_OP(GET_ARGNO(pc), nargs, argv, rval, +=, MAX); + case JSOP_DECARG: + FAST_INCREMENT_OP(GET_ARGNO(pc), nargs, argv, rval, -=, MIN); + case JSOP_ARGINC: + FAST_INCREMENT_OP(GET_ARGNO(pc), nargs, argv, rtmp, +=, MAX); + case JSOP_ARGDEC: + FAST_INCREMENT_OP(GET_ARGNO(pc), nargs, argv, rtmp, -=, MIN); + + case JSOP_INCVAR: + FAST_INCREMENT_OP(GET_VARNO(pc), nvars, vars, rval, +=, MAX); + case JSOP_DECVAR: + FAST_INCREMENT_OP(GET_VARNO(pc), nvars, vars, rval, -=, MIN); + case JSOP_VARINC: + FAST_INCREMENT_OP(GET_VARNO(pc), nvars, vars, rtmp, +=, MAX); + case JSOP_VARDEC: + FAST_INCREMENT_OP(GET_VARNO(pc), nvars, vars, rtmp, -=, MIN); + +#undef FAST_INCREMENT_OP + + do_nonint_fast_incop: + NONINT_INCREMENT_OP(); + *vp = rval; + PUSH_OPND(rtmp); + break; + + case JSOP_GETPROP: + /* Get an immediate atom naming the property. */ + atom = GET_ATOM(cx, script, pc); + id = (jsid)atom; + PROPERTY_OP(-1, CACHED_GET(OBJ_GET_PROPERTY(cx, obj, id, &rval))); + STORE_OPND(-1, rval); + break; + + case JSOP_SETPROP: + /* Pop the right-hand side into rval for OBJ_SET_PROPERTY. */ + rval = FETCH_OPND(-1); + + /* Get an immediate atom naming the property. */ + atom = GET_ATOM(cx, script, pc); + id = (jsid)atom; + PROPERTY_OP(-2, CACHED_SET(OBJ_SET_PROPERTY(cx, obj, id, &rval))); + sp--; + STORE_OPND(-1, rval); + break; + + case JSOP_GETELEM: + ELEMENT_OP(-1, CACHED_GET(OBJ_GET_PROPERTY(cx, obj, id, &rval))); + sp--; + STORE_OPND(-1, rval); + break; + + case JSOP_SETELEM: + rval = FETCH_OPND(-1); + ELEMENT_OP(-2, CACHED_SET(OBJ_SET_PROPERTY(cx, obj, id, &rval))); + sp -= 2; + STORE_OPND(-1, rval); + break; + + case JSOP_ENUMELEM: + /* Funky: the value to set is under the [obj, id] pair. */ + FETCH_ELEMENT_ID(-1, id); + lval = FETCH_OPND(-2); + VALUE_TO_OBJECT(cx, lval, obj); + rval = FETCH_OPND(-3); + SAVE_SP(fp); + ok = OBJ_SET_PROPERTY(cx, obj, id, &rval); + if (!ok) + goto out; + sp -= 3; + break; + +/* + * LAZY_ARGS_THISP allows the JSOP_ARGSUB bytecode to defer creation of the + * arguments object until it is truly needed. JSOP_ARGSUB optimizes away + * arguments objects when the only uses of the 'arguments' parameter are to + * fetch individual actual parameters. But if such a use were then invoked, + * e.g., arguments[i](), the 'this' parameter would and must bind to the + * caller's arguments object. So JSOP_ARGSUB sets obj to LAZY_ARGS_THISP. + */ +#define LAZY_ARGS_THISP ((JSObject *) 1) + + case JSOP_PUSHOBJ: + if (obj == LAZY_ARGS_THISP && !(obj = js_GetArgsObject(cx, fp))) { + ok = JS_FALSE; + goto out; + } + PUSH_OPND(OBJECT_TO_JSVAL(obj)); + break; + + case JSOP_CALL: + case JSOP_EVAL: + argc = GET_ARGC(pc); + vp = sp - (argc + 2); + lval = *vp; + SAVE_SP(fp); + + if (JSVAL_IS_FUNCTION(cx, lval) && + (obj = JSVAL_TO_OBJECT(lval), + fun = (JSFunction *) JS_GetPrivate(cx, obj), + !fun->native && + !(fun->flags & (JSFUN_HEAVYWEIGHT | JSFUN_BOUND_METHOD)) && + argc >= (uintN)(fun->nargs + fun->extra))) + /* inline_call: */ + { + uintN nframeslots, nvars; + void *newmark; + JSInlineFrame *newifp; + JSInterpreterHook hook; + + /* Restrict recursion of lightweight functions. */ + if (inlineCallCount == MAX_INLINE_CALL_COUNT) { + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, + JSMSG_OVER_RECURSED); + ok = JS_FALSE; + goto out; + } + +#if JS_HAS_JIT + /* ZZZbe should do this only if interpreted often enough. */ + ok = jsjit_Compile(cx, fun); + if (!ok) + goto out; +#endif + + /* Compute the number of stack slots needed for fun. */ + nframeslots = (sizeof(JSInlineFrame) + sizeof(jsval) - 1) + / sizeof(jsval); + nvars = fun->nvars; + script = fun->script; + depth = (jsint) script->depth; + + /* Allocate the frame and space for vars and operands. */ + newsp = js_AllocRawStack(cx, nframeslots + nvars + 2 * depth, + &newmark); + if (!newsp) { + ok = JS_FALSE; + goto bad_inline_call; + } + newifp = (JSInlineFrame *) newsp; + newsp += nframeslots; + + /* Initialize the stack frame. */ + memset(newifp, 0, sizeof(JSInlineFrame)); + newifp->frame.script = script; + newifp->frame.fun = fun; + newifp->frame.argc = argc; + newifp->frame.argv = vp + 2; + newifp->frame.rval = JSVAL_VOID; + newifp->frame.nvars = nvars; + newifp->frame.vars = newsp; + newifp->frame.down = fp; + newifp->frame.scopeChain = OBJ_GET_PARENT(cx, obj); + newifp->mark = newmark; + + /* Compute the 'this' parameter now that argv is set. */ + ok = ComputeThis(cx, JSVAL_TO_OBJECT(vp[1]), &newifp->frame); + if (!ok) { + js_FreeRawStack(cx, newmark); + goto bad_inline_call; + } + + /* Push void to initialize local variables. */ + sp = newsp; + while (nvars--) + PUSH(JSVAL_VOID); + sp += depth; + newifp->frame.spbase = sp; + SAVE_SP(&newifp->frame); + + /* Call the debugger hook if present. */ + hook = cx->runtime->callHook; + if (hook) { + newifp->hookData = hook(cx, &newifp->frame, JS_TRUE, 0, + cx->runtime->callHookData); + LOAD_INTERRUPT_HANDLER(rt); + } + + /* Switch to new version if currentVersion wasn't overridden. */ + newifp->callerVersion = cx->version; + if (cx->version == currentVersion) { + currentVersion = script->version; + if (currentVersion != cx->version) + JS_SetVersion(cx, currentVersion); + } + + /* Push the frame and set interpreter registers. */ + cx->fp = fp = &newifp->frame; + pc = script->code; + endpc = pc + script->length; + inlineCallCount++; + JS_RUNTIME_METER(rt, inlineCalls); + continue; + + bad_inline_call: + script = fp->script; + depth = (jsint) script->depth; + goto out; + } + + ok = js_Invoke(cx, argc, 0); + RESTORE_SP(fp); + LOAD_INTERRUPT_HANDLER(rt); + if (!ok) + goto out; + JS_RUNTIME_METER(rt, nonInlineCalls); +#if JS_HAS_LVALUE_RETURN + if (cx->rval2set) { + /* + * Sneaky: use the stack depth we didn't claim in our budget, + * but that we know is there on account of [fun, this] already + * having been pushed, at a minimum (if no args). Those two + * slots have been popped and [rval] has been pushed, which + * leaves one more slot for rval2 before we might overflow. + * + * NB: rval2 must be the property identifier, and rval the + * object from which to get the property. The pair form an + * ECMA "reference type", which can be used on the right- or + * left-hand side of assignment ops. Only native methods can + * return reference types. See JSOP_SETCALL just below for + * the left-hand-side case. + */ + PUSH_OPND(cx->rval2); + cx->rval2set = JS_FALSE; + ELEMENT_OP(-1, ok = OBJ_GET_PROPERTY(cx, obj, id, &rval)); + sp--; + STORE_OPND(-1, rval); + } +#endif + obj = NULL; + break; + +#if JS_HAS_LVALUE_RETURN + case JSOP_SETCALL: + argc = GET_ARGC(pc); + SAVE_SP(fp); + ok = js_Invoke(cx, argc, 0); + RESTORE_SP(fp); + LOAD_INTERRUPT_HANDLER(rt); + if (!ok) + goto out; + if (!cx->rval2set) { + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, + JSMSG_BAD_LEFTSIDE_OF_ASS); + ok = JS_FALSE; + goto out; + } + PUSH_OPND(cx->rval2); + cx->rval2set = JS_FALSE; + obj = NULL; + break; +#endif + + case JSOP_NAME: + atom = GET_ATOM(cx, script, pc); + id = (jsid)atom; + + SAVE_SP(fp); + ok = js_FindProperty(cx, id, &obj, &obj2, &prop); + if (!ok) + goto out; + if (!prop) { + /* Kludge to allow (typeof foo == "undefined") tests. */ + for (pc2 = pc + len; pc2 < endpc; pc2++) { + op2 = (JSOp)*pc2; + if (op2 == JSOP_TYPEOF) { + PUSH_OPND(JSVAL_VOID); + goto advance_pc; + } + if (op2 != JSOP_GROUP) + break; + } + goto atom_not_defined; + } + + /* Take the slow path if prop was not found in a native object. */ + if (!OBJ_IS_NATIVE(obj) || !OBJ_IS_NATIVE(obj2)) { + OBJ_DROP_PROPERTY(cx, obj2, prop); + ok = OBJ_GET_PROPERTY(cx, obj, id, &rval); + if (!ok) + goto out; + PUSH_OPND(rval); + break; + } + + /* Get and push the obj[id] property's value. */ + sprop = (JSScopeProperty *)prop; + slot = (uintN)sprop->slot; + rval = (slot != SPROP_INVALID_SLOT) + ? LOCKED_OBJ_GET_SLOT(obj2, slot) + : JSVAL_VOID; + JS_UNLOCK_OBJ(cx, obj2); + ok = SPROP_GET(cx, sprop, obj, obj2, &rval); + JS_LOCK_OBJ(cx, obj2); + if (!ok) { + OBJ_DROP_PROPERTY(cx, obj2, prop); + goto out; + } + if (SPROP_HAS_VALID_SLOT(sprop, OBJ_SCOPE(obj2))) + LOCKED_OBJ_SET_SLOT(obj2, slot, rval); + OBJ_DROP_PROPERTY(cx, obj2, prop); + PUSH_OPND(rval); + break; + + case JSOP_UINT16: + i = (jsint) GET_ATOM_INDEX(pc); + rval = INT_TO_JSVAL(i); + PUSH_OPND(rval); + obj = NULL; + break; + + case JSOP_NUMBER: + case JSOP_STRING: + atom = GET_ATOM(cx, script, pc); + PUSH_OPND(ATOM_KEY(atom)); + obj = NULL; + break; + + case JSOP_OBJECT: + { +#if 0 + jsatomid atomIndex; + JSAtomMap *atomMap; + + /* + * Get a suitable object from an atom mapped by the bytecode at pc. + * + * We must handle the case where a regexp object literal is used in + * a different global at execution time from the global with which + * it was scanned at compile time, in order to rewrap the JSRegExp + * struct with a new object having the right prototype and parent. + * + * Unlike JSOP_DEFFUN and other prolog bytecodes, we don't want to + * pay a script prolog execution price for all regexp literals in a + * script (many may not be used by a particular execution of that + * script, depending on control flow), so we do all fp->objAtomMap + * initialization lazily, here under JSOP_OBJECT. + * + * XXX This code is specific to regular expression objects. If we + * need JSOP_OBJECT for other kinds of object literals, we should + * push cloning down under JSObjectOps. Also, fp->objAtomMap is + * used only for object atoms, so it's sparse (wasting some stack + * space) and as its name implies, you can't get non-object atoms + * from it. + */ + atomIndex = GET_ATOM_INDEX(pc); + atomMap = fp->objAtomMap; + atom = atomMap ? atomMap->vector[atomIndex] : NULL; + if (!atom) { + /* Let atom and obj denote the regexp (object) mapped by pc. */ + atom = js_GetAtom(cx, &script->atomMap, atomIndex); + JS_ASSERT(ATOM_IS_OBJECT(atom)); + obj = ATOM_TO_OBJECT(atom); + JS_ASSERT(OBJ_GET_CLASS(cx, obj) == &js_RegExpClass); + + /* Compute the current global object in obj2. */ + obj2 = fp->scopeChain; + while ((parent = OBJ_GET_PARENT(cx, obj2)) != NULL) + obj2 = parent; + + /* + * If obj's parent is not obj2, we must clone obj so that it + * has the right parent, and therefore, the right prototype. + * + * Yes, this means we assume that the correct RegExp.prototype + * to which regexp instances (including literals) delegate can + * be distinguished solely by the instance's parent, which was + * set to the parent of the RegExp constructor function object + * when the instance was created. In other words, + * + * (/x/.__parent__ == RegExp.__parent__) implies + * (/x/.__proto__ == RegExp.prototype) + * + * (unless you assign a different object to RegExp.prototype + * at runtime, in which case, ECMA doesn't specify operation, + * and you get what you deserve). + * + * This same coupling between instance parent and constructor + * parent turns up elsewhere (see jsobj.c's FindConstructor, + * js_ConstructObject, and js_NewObject). It's fundamental. + */ + if (OBJ_GET_PARENT(cx, obj) != obj2) { + obj = js_CloneRegExpObject(cx, obj, obj2); + if (!obj) { + ok = JS_FALSE; + goto out; + } + + atom = js_AtomizeObject(cx, obj, 0); + if (!atom) { + ok = JS_FALSE; + goto out; + } + } + + /* + * If fp->objAtomMap is null, initialize it now so we can map + * atom (whether atom is newly created for a cloned object, or + * the original atom mapped by script) for faster performance + * next time through JSOP_OBJECT. + */ + if (!atomMap) { + jsatomid mapLength = script->atomMap.length; + size_t vectorBytes = mapLength * sizeof(JSAtom *); + + /* Allocate an override atom map from cx->stackPool. */ + JS_ARENA_ALLOCATE_CAST(atomMap, JSAtomMap *, + &cx->stackPool, + sizeof(JSAtomMap) + vectorBytes); + if (!atomMap) { + JS_ReportOutOfMemory(cx); + ok = JS_FALSE; + goto out; + } + + atomMap->length = mapLength; + atomMap->vector = (JSAtom **)(atomMap + 1); + memset(atomMap->vector, 0, vectorBytes); + fp->objAtomMap = atomMap; + } + atomMap->vector[atomIndex] = atom; + } +#else + atom = GET_ATOM(cx, script, pc); + JS_ASSERT(ATOM_IS_OBJECT(atom)); +#endif + rval = ATOM_KEY(atom); + PUSH_OPND(rval); + obj = NULL; + break; + } + + case JSOP_ZERO: + PUSH_OPND(JSVAL_ZERO); + obj = NULL; + break; + + case JSOP_ONE: + PUSH_OPND(JSVAL_ONE); + obj = NULL; + break; + + case JSOP_NULL: + PUSH_OPND(JSVAL_NULL); + obj = NULL; + break; + + case JSOP_THIS: + PUSH_OPND(OBJECT_TO_JSVAL(fp->thisp)); + obj = NULL; + break; + + case JSOP_FALSE: + PUSH_OPND(JSVAL_FALSE); + obj = NULL; + break; + + case JSOP_TRUE: + PUSH_OPND(JSVAL_TRUE); + obj = NULL; + break; + +#if JS_HAS_SWITCH_STATEMENT + case JSOP_TABLESWITCH: + pc2 = pc; + len = GET_JUMP_OFFSET(pc2); + + /* + * ECMAv2 forbids conversion of discriminant, so we will skip to + * the default case if the discriminant isn't already an int jsval. + * (This opcode is emitted only for dense jsint-domain switches.) + */ + if (cx->version == JSVERSION_DEFAULT || + cx->version >= JSVERSION_1_4) { + rval = POP_OPND(); + if (!JSVAL_IS_INT(rval)) + break; + i = JSVAL_TO_INT(rval); + } else { + FETCH_INT(cx, -1, i); + sp--; + } + + pc2 += JUMP_OFFSET_LEN; + low = GET_JUMP_OFFSET(pc2); + pc2 += JUMP_OFFSET_LEN; + high = GET_JUMP_OFFSET(pc2); + + i -= low; + if ((jsuint)i < (jsuint)(high - low + 1)) { + pc2 += JUMP_OFFSET_LEN + JUMP_OFFSET_LEN * i; + off = (jsint) GET_JUMP_OFFSET(pc2); + if (off) + len = off; + } + break; + + case JSOP_LOOKUPSWITCH: + lval = POP_OPND(); + pc2 = pc; + len = GET_JUMP_OFFSET(pc2); + + if (!JSVAL_IS_NUMBER(lval) && + !JSVAL_IS_STRING(lval) && + !JSVAL_IS_BOOLEAN(lval)) { + goto advance_pc; + } + + pc2 += JUMP_OFFSET_LEN; + npairs = (jsint) GET_ATOM_INDEX(pc2); + pc2 += ATOM_INDEX_LEN; + +#define SEARCH_PAIRS(MATCH_CODE) \ + while (npairs) { \ + atom = GET_ATOM(cx, script, pc2); \ + rval = ATOM_KEY(atom); \ + MATCH_CODE \ + if (match) { \ + pc2 += ATOM_INDEX_LEN; \ + len = GET_JUMP_OFFSET(pc2); \ + goto advance_pc; \ + } \ + pc2 += ATOM_INDEX_LEN + JUMP_OFFSET_LEN; \ + npairs--; \ + } + if (JSVAL_IS_STRING(lval)) { + str = JSVAL_TO_STRING(lval); + SEARCH_PAIRS( + match = (JSVAL_IS_STRING(rval) && + ((str2 = JSVAL_TO_STRING(rval)) == str || + !js_CompareStrings(str2, str))); + ) + } else if (JSVAL_IS_DOUBLE(lval)) { + d = *JSVAL_TO_DOUBLE(lval); + SEARCH_PAIRS( + match = (JSVAL_IS_DOUBLE(rval) && + *JSVAL_TO_DOUBLE(rval) == d); + ) + } else { + SEARCH_PAIRS( + match = (lval == rval); + ) + } +#undef SEARCH_PAIRS + break; + + case JSOP_TABLESWITCHX: + pc2 = pc; + len = GET_JUMPX_OFFSET(pc2); + + /* + * ECMAv2 forbids conversion of discriminant, so we will skip to + * the default case if the discriminant isn't already an int jsval. + * (This opcode is emitted only for dense jsint-domain switches.) + */ + if (cx->version == JSVERSION_DEFAULT || + cx->version >= JSVERSION_1_4) { + rval = POP_OPND(); + if (!JSVAL_IS_INT(rval)) + break; + i = JSVAL_TO_INT(rval); + } else { + FETCH_INT(cx, -1, i); + sp--; + } + + pc2 += JUMPX_OFFSET_LEN; + low = GET_JUMP_OFFSET(pc2); + pc2 += JUMP_OFFSET_LEN; + high = GET_JUMP_OFFSET(pc2); + + i -= low; + if ((jsuint)i < (jsuint)(high - low + 1)) { + pc2 += JUMP_OFFSET_LEN + JUMPX_OFFSET_LEN * i; + off = (jsint) GET_JUMPX_OFFSET(pc2); + if (off) + len = off; + } + break; + + case JSOP_LOOKUPSWITCHX: + lval = POP_OPND(); + pc2 = pc; + len = GET_JUMPX_OFFSET(pc2); + + if (!JSVAL_IS_NUMBER(lval) && + !JSVAL_IS_STRING(lval) && + !JSVAL_IS_BOOLEAN(lval)) { + goto advance_pc; + } + + pc2 += JUMPX_OFFSET_LEN; + npairs = (jsint) GET_ATOM_INDEX(pc2); + pc2 += ATOM_INDEX_LEN; + +#define SEARCH_EXTENDED_PAIRS(MATCH_CODE) \ + while (npairs) { \ + atom = GET_ATOM(cx, script, pc2); \ + rval = ATOM_KEY(atom); \ + MATCH_CODE \ + if (match) { \ + pc2 += ATOM_INDEX_LEN; \ + len = GET_JUMPX_OFFSET(pc2); \ + goto advance_pc; \ + } \ + pc2 += ATOM_INDEX_LEN + JUMPX_OFFSET_LEN; \ + npairs--; \ + } + if (JSVAL_IS_STRING(lval)) { + str = JSVAL_TO_STRING(lval); + SEARCH_EXTENDED_PAIRS( + match = (JSVAL_IS_STRING(rval) && + ((str2 = JSVAL_TO_STRING(rval)) == str || + !js_CompareStrings(str2, str))); + ) + } else if (JSVAL_IS_DOUBLE(lval)) { + d = *JSVAL_TO_DOUBLE(lval); + SEARCH_EXTENDED_PAIRS( + match = (JSVAL_IS_DOUBLE(rval) && + *JSVAL_TO_DOUBLE(rval) == d); + ) + } else { + SEARCH_EXTENDED_PAIRS( + match = (lval == rval); + ) + } +#undef SEARCH_EXTENDED_PAIRS + break; + + case JSOP_CONDSWITCH: + break; + +#endif /* JS_HAS_SWITCH_STATEMENT */ + +#if JS_HAS_EXPORT_IMPORT + case JSOP_EXPORTALL: + obj = fp->varobj; + ida = JS_Enumerate(cx, obj); + if (!ida) { + ok = JS_FALSE; + } else { + for (i = 0, j = ida->length; i < j; i++) { + id = ida->vector[i]; + ok = OBJ_LOOKUP_PROPERTY(cx, obj, id, &obj2, &prop); + if (!ok) + break; + if (!prop) + continue; + ok = OBJ_GET_ATTRIBUTES(cx, obj, id, prop, &attrs); + if (ok) { + attrs |= JSPROP_EXPORTED; + ok = OBJ_SET_ATTRIBUTES(cx, obj, id, prop, &attrs); + } + OBJ_DROP_PROPERTY(cx, obj2, prop); + if (!ok) + break; + } + JS_DestroyIdArray(cx, ida); + } + break; + + case JSOP_EXPORTNAME: + atom = GET_ATOM(cx, script, pc); + id = (jsid)atom; + obj = fp->varobj; + ok = OBJ_LOOKUP_PROPERTY(cx, obj, id, &obj2, &prop); + if (!ok) + goto out; + if (!prop) { + ok = OBJ_DEFINE_PROPERTY(cx, obj, id, JSVAL_VOID, NULL, NULL, + JSPROP_EXPORTED, NULL); + } else { + ok = OBJ_GET_ATTRIBUTES(cx, obj, id, prop, &attrs); + if (ok) { + attrs |= JSPROP_EXPORTED; + ok = OBJ_SET_ATTRIBUTES(cx, obj, id, prop, &attrs); + } + OBJ_DROP_PROPERTY(cx, obj2, prop); + } + if (!ok) + goto out; + break; + + case JSOP_IMPORTALL: + id = (jsid)JSVAL_VOID; + PROPERTY_OP(-1, ok = ImportProperty(cx, obj, id)); + sp--; + break; + + case JSOP_IMPORTPROP: + /* Get an immediate atom naming the property. */ + atom = GET_ATOM(cx, script, pc); + id = (jsid)atom; + PROPERTY_OP(-1, ok = ImportProperty(cx, obj, id)); + sp--; + break; + + case JSOP_IMPORTELEM: + ELEMENT_OP(-1, ok = ImportProperty(cx, obj, id)); + sp -= 2; + break; +#endif /* JS_HAS_EXPORT_IMPORT */ + + case JSOP_TRAP: + switch (JS_HandleTrap(cx, script, pc, &rval)) { + case JSTRAP_ERROR: + ok = JS_FALSE; + goto out; + case JSTRAP_CONTINUE: + JS_ASSERT(JSVAL_IS_INT(rval)); + op = (JSOp) JSVAL_TO_INT(rval); + JS_ASSERT((uintN)op < (uintN)JSOP_LIMIT); + LOAD_INTERRUPT_HANDLER(rt); + goto do_op; + case JSTRAP_RETURN: + fp->rval = rval; + goto out; +#if JS_HAS_EXCEPTIONS + case JSTRAP_THROW: + cx->throwing = JS_TRUE; + cx->exception = rval; + ok = JS_FALSE; + goto out; +#endif /* JS_HAS_EXCEPTIONS */ + default:; + } + LOAD_INTERRUPT_HANDLER(rt); + break; + + case JSOP_ARGUMENTS: + SAVE_SP(fp); + ok = js_GetArgsValue(cx, fp, &rval); + if (!ok) + goto out; + PUSH_OPND(rval); + break; + + case JSOP_ARGSUB: + id = (jsid) INT_TO_JSVAL(GET_ARGNO(pc)); + SAVE_SP(fp); + ok = js_GetArgsProperty(cx, fp, id, &obj, &rval); + if (!ok) + goto out; + if (!obj) { + /* + * If arguments was not overridden by eval('arguments = ...'), + * set obj to the magic cookie respected by JSOP_PUSHOBJ, just + * in case this bytecode is part of an 'arguments[i](j, k)' or + * similar such invocation sequence, where the function that + * is invoked expects its 'this' parameter to be the caller's + * arguments object. + */ + obj = LAZY_ARGS_THISP; + } + PUSH_OPND(rval); + break; + +#undef LAZY_ARGS_THISP + + case JSOP_ARGCNT: + id = (jsid) rt->atomState.lengthAtom; + SAVE_SP(fp); + ok = js_GetArgsProperty(cx, fp, id, &obj, &rval); + if (!ok) + goto out; + PUSH_OPND(rval); + break; + + case JSOP_GETARG: + slot = GET_ARGNO(pc); + JS_ASSERT(slot < fp->fun->nargs); + PUSH_OPND(fp->argv[slot]); + obj = NULL; + break; + + case JSOP_SETARG: + slot = GET_ARGNO(pc); + JS_ASSERT(slot < fp->fun->nargs); + vp = &fp->argv[slot]; + GC_POKE(cx, *vp); + *vp = FETCH_OPND(-1); + obj = NULL; + break; + + case JSOP_GETVAR: + slot = GET_VARNO(pc); + JS_ASSERT(slot < fp->fun->nvars); + PUSH_OPND(fp->vars[slot]); + obj = NULL; + break; + + case JSOP_SETVAR: + slot = GET_VARNO(pc); + JS_ASSERT(slot < fp->fun->nvars); + vp = &fp->vars[slot]; + GC_POKE(cx, *vp); + *vp = FETCH_OPND(-1); + obj = NULL; + break; + + case JSOP_DEFCONST: + case JSOP_DEFVAR: + { + JSBool defined; + + atom = GET_ATOM(cx, script, pc); + obj = fp->varobj; + attrs = JSPROP_ENUMERATE; + if (!(fp->flags & JSFRAME_EVAL)) + attrs |= JSPROP_PERMANENT; + if (op == JSOP_DEFCONST) + attrs |= JSPROP_READONLY; + + /* Lookup id in order to check for redeclaration problems. */ + id = (jsid)atom; + ok = js_CheckRedeclaration(cx, obj, id, attrs, &defined); + if (!ok) + goto out; + + /* Bind a variable only if it's not yet defined. */ + if (!defined) { + ok = OBJ_DEFINE_PROPERTY(cx, obj, id, JSVAL_VOID, NULL, NULL, + attrs, NULL); + if (!ok) + goto out; + } + break; + } + + case JSOP_DEFFUN: + { + uintN flags; + + atom = GET_ATOM(cx, script, pc); + obj = ATOM_TO_OBJECT(atom); + fun = (JSFunction *) JS_GetPrivate(cx, obj); + id = (jsid) fun->atom; + + /* + * We must be at top-level (either outermost block that forms a + * function's body, or a global) scope, not inside an expression + * (JSOP_{ANON,NAMED}FUNOBJ) or compound statement (JSOP_CLOSURE) + * in the same compilation unit (ECMA Program). + * + * However, we could be in a Program being eval'd from inside a + * with statement, so we need to distinguish variables object from + * scope chain head. Hence the two assignments to parent below. + * First we make sure the function object we're defining has the + * right scope chain. Then we define its name in fp->varobj. + * + * If static link is not current scope, clone fun's object to link + * to the current scope via parent. This clause exists to enable + * sharing of compiled functions among multiple equivalent scopes, + * splitting the cost of compilation evenly among the scopes and + * amortizing it over a number of executions. Examples include XUL + * scripts and event handlers shared among Mozilla chrome windows, + * and server-side JS user-defined functions shared among requests. + * + * NB: The Script object exposes compile and exec in the language, + * such that this clause introduces an incompatible change from old + * JS versions that supported Script. Such a JS version supported + * executing a script that defined and called functions scoped by + * the compile-time static link, not by the exec-time scope chain. + * + * We sacrifice compatibility, breaking such scripts, in order to + * promote compile-cost sharing and amortizing, and because Script + * is not and will not be standardized. + */ + parent = fp->scopeChain; + if (OBJ_GET_PARENT(cx, obj) != parent) { + obj = js_CloneFunctionObject(cx, obj, parent); + if (!obj) { + ok = JS_FALSE; + goto out; + } + } + + /* + * ECMA requires functions defined when entering Global code to be + * permanent, and functions defined when entering Eval code to be + * impermanent. + */ + attrs = JSPROP_ENUMERATE; + if (!(fp->flags & JSFRAME_EVAL)) + attrs |= JSPROP_PERMANENT; + + /* + * Load function flags that are also property attributes. Getters + * and setters do not need a slot, their value is stored elsewhere + * in the property itself, not in obj->slots. + */ + flags = fun->flags & (JSFUN_GETTER | JSFUN_SETTER); + if (flags) + attrs |= flags | JSPROP_SHARED; + + /* + * Check for a const property of the same name -- or any kind + * of property if executing with the strict option. We check + * here at runtime as well as at compile-time, to handle eval + * as well as multiple HTML script tags. + */ + parent = fp->varobj; + ok = js_CheckRedeclaration(cx, parent, id, attrs, &cond); + if (!ok) + goto out; + + ok = OBJ_DEFINE_PROPERTY(cx, parent, id, + flags ? JSVAL_VOID : OBJECT_TO_JSVAL(obj), + (flags & JSFUN_GETTER) + ? (JSPropertyOp) obj + : NULL, + (flags & JSFUN_SETTER) + ? (JSPropertyOp) obj + : NULL, + attrs, + NULL); + if (!ok) + goto out; + break; + } + +#if JS_HAS_LEXICAL_CLOSURE + case JSOP_DEFLOCALFUN: + /* + * Define a local function (i.e., one nested at the top level of + * another function), parented by the current scope chain, and + * stored in a local variable slot that the compiler allocated. + * This is an optimization over JSOP_DEFFUN that avoids requiring + * a call object for the outer function's activation. + */ + pc2 = pc; + slot = GET_VARNO(pc2); + pc2 += VARNO_LEN; + atom = GET_ATOM(cx, script, pc2); + obj = ATOM_TO_OBJECT(atom); + fun = (JSFunction *) JS_GetPrivate(cx, obj); + + parent = fp->scopeChain; + if (OBJ_GET_PARENT(cx, obj) != parent) { + obj = js_CloneFunctionObject(cx, obj, parent); + if (!obj) { + ok = JS_FALSE; + goto out; + } + } + fp->vars[slot] = OBJECT_TO_JSVAL(obj); + break; + + case JSOP_ANONFUNOBJ: + /* Push the specified function object literal. */ + atom = GET_ATOM(cx, script, pc); + obj = ATOM_TO_OBJECT(atom); + + /* If re-parenting, push a clone of the function object. */ + parent = fp->scopeChain; + if (OBJ_GET_PARENT(cx, obj) != parent) { + obj = js_CloneFunctionObject(cx, obj, parent); + if (!obj) { + ok = JS_FALSE; + goto out; + } + } + PUSH_OPND(OBJECT_TO_JSVAL(obj)); + break; + + case JSOP_NAMEDFUNOBJ: + /* ECMA ed. 3 FunctionExpression: function Identifier [etc.]. */ + atom = GET_ATOM(cx, script, pc); + rval = ATOM_KEY(atom); + JS_ASSERT(JSVAL_IS_FUNCTION(cx, rval)); + + /* + * 1. Create a new object as if by the expression new Object(). + * 2. Add Result(1) to the front of the scope chain. + * + * Step 2 is achieved by making the new object's parent be the + * current scope chain, and then making the new object the parent + * of the Function object clone. + */ + SAVE_SP(fp); + parent = js_ConstructObject(cx, &js_ObjectClass, NULL, + fp->scopeChain, 0, NULL); + if (!parent) { + ok = JS_FALSE; + goto out; + } + + /* + * 3. Create a new Function object as specified in section 13.2 + * with [parameters and body specified by the function expression + * that was parsed by the compiler into a Function object, and + * saved in the script's atom map]. + */ + obj = js_CloneFunctionObject(cx, JSVAL_TO_OBJECT(rval), parent); + if (!obj) { + ok = JS_FALSE; + goto out; + } + + /* + * 4. Create a property in the object Result(1). The property's + * name is [fun->atom, the identifier parsed by the compiler], + * value is Result(3), and attributes are { DontDelete, ReadOnly }. + */ + fun = (JSFunction *) JS_GetPrivate(cx, obj); + attrs = fun->flags & (JSFUN_GETTER | JSFUN_SETTER); + if (attrs) + attrs |= JSPROP_SHARED; + ok = OBJ_DEFINE_PROPERTY(cx, parent, (jsid)fun->atom, + attrs ? JSVAL_VOID : OBJECT_TO_JSVAL(obj), + (attrs & JSFUN_GETTER) + ? (JSPropertyOp) obj + : NULL, + (attrs & JSFUN_SETTER) + ? (JSPropertyOp) obj + : NULL, + attrs | + JSPROP_ENUMERATE | JSPROP_PERMANENT | + JSPROP_READONLY, + NULL); + if (!ok) { + cx->newborn[GCX_OBJECT] = NULL; + goto out; + } + + /* + * 5. Remove Result(1) from the front of the scope chain [no-op]. + * 6. Return Result(3). + */ + PUSH_OPND(OBJECT_TO_JSVAL(obj)); + break; + + case JSOP_CLOSURE: + /* + * ECMA ed. 3 extension: a named function expression in a compound + * statement (not at the top statement level of global code, or at + * the top level of a function body). + * + * Get immediate operand atom, which is a function object literal. + * From it, get the function to close. + */ + atom = GET_ATOM(cx, script, pc); + JS_ASSERT(JSVAL_IS_FUNCTION(cx, ATOM_KEY(atom))); + obj = ATOM_TO_OBJECT(atom); + + /* + * Clone the function object with the current scope chain as the + * clone's parent. The original function object is the prototype + * of the clone. Do this only if re-parenting; the compiler may + * have seen the right parent already and created a sufficiently + * well-scoped function object. + */ + parent = fp->scopeChain; + if (OBJ_GET_PARENT(cx, obj) != parent) { + obj = js_CloneFunctionObject(cx, obj, parent); + if (!obj) { + ok = JS_FALSE; + goto out; + } + } + + /* + * Make a property in fp->varobj with id fun->atom and value obj, + * unless fun is a getter or setter (in which case, obj is cast to + * a JSPropertyOp and passed accordingly). + */ + fun = (JSFunction *) JS_GetPrivate(cx, obj); + attrs = fun->flags & (JSFUN_GETTER | JSFUN_SETTER); + if (attrs) + attrs |= JSPROP_SHARED; + ok = OBJ_DEFINE_PROPERTY(cx, fp->varobj, (jsid)fun->atom, + attrs ? JSVAL_VOID : OBJECT_TO_JSVAL(obj), + (attrs & JSFUN_GETTER) + ? (JSPropertyOp) obj + : NULL, + (attrs & JSFUN_SETTER) + ? (JSPropertyOp) obj + : NULL, + attrs | JSPROP_ENUMERATE, + NULL); + if (!ok) { + cx->newborn[GCX_OBJECT] = NULL; + goto out; + } + break; +#endif /* JS_HAS_LEXICAL_CLOSURE */ + +#if JS_HAS_GETTER_SETTER + case JSOP_GETTER: + case JSOP_SETTER: + JS_ASSERT(len == 1); + op2 = (JSOp) *++pc; + cs = &js_CodeSpec[op2]; + len = cs->length; + switch (op2) { + case JSOP_SETNAME: + case JSOP_SETPROP: + atom = GET_ATOM(cx, script, pc); + id = (jsid)atom; + i = -1; + rval = FETCH_OPND(i); + goto gs_pop_lval; + + case JSOP_SETELEM: + rval = FETCH_OPND(-1); + i = -2; + FETCH_ELEMENT_ID(i, id); + gs_pop_lval: + lval = FETCH_OPND(i-1); + VALUE_TO_OBJECT(cx, lval, obj); + break; + +#if JS_HAS_INITIALIZERS + case JSOP_INITPROP: + JS_ASSERT(sp - fp->spbase >= 2); + i = -1; + rval = FETCH_OPND(i); + atom = GET_ATOM(cx, script, pc); + id = (jsid)atom; + goto gs_get_lval; + + case JSOP_INITELEM: + JS_ASSERT(sp - fp->spbase >= 3); + rval = FETCH_OPND(-1); + i = -2; + FETCH_ELEMENT_ID(i, id); + gs_get_lval: + lval = FETCH_OPND(i-1); + JS_ASSERT(JSVAL_IS_OBJECT(lval)); + obj = JSVAL_TO_OBJECT(lval); + break; +#endif /* JS_HAS_INITIALIZERS */ + + default: + JS_ASSERT(0); + } + + if (JS_TypeOfValue(cx, rval) != JSTYPE_FUNCTION) { + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, + JSMSG_BAD_GETTER_OR_SETTER, + (op == JSOP_GETTER) + ? js_getter_str + : js_setter_str); + ok = JS_FALSE; + goto out; + } + + /* + * Getters and setters are just like watchpoints from an access + * control point of view. + */ + ok = OBJ_CHECK_ACCESS(cx, obj, id, JSACC_WATCH, &rtmp, &attrs); + if (!ok) + goto out; + + if (op == JSOP_GETTER) { + getter = (JSPropertyOp) JSVAL_TO_OBJECT(rval); + setter = NULL; + attrs = JSPROP_GETTER; + } else { + getter = NULL; + setter = (JSPropertyOp) JSVAL_TO_OBJECT(rval); + attrs = JSPROP_SETTER; + } + attrs |= JSPROP_ENUMERATE | JSPROP_SHARED; + + /* Check for a readonly or permanent property of the same name. */ + ok = js_CheckRedeclaration(cx, obj, id, attrs, &cond); + if (!ok) + goto out; + + ok = OBJ_DEFINE_PROPERTY(cx, obj, id, JSVAL_VOID, getter, setter, + attrs, NULL); + if (!ok) + goto out; + + sp += i; + if (cs->ndefs) + STORE_OPND(-1, rval); + break; +#endif /* JS_HAS_GETTER_SETTER */ + +#if JS_HAS_INITIALIZERS + case JSOP_NEWINIT: + argc = 0; + fp->sharpDepth++; + goto do_new; + + case JSOP_ENDINIT: + if (--fp->sharpDepth == 0) + fp->sharpArray = NULL; + + /* Re-set the newborn root to the top of this object tree. */ + JS_ASSERT(sp - fp->spbase >= 1); + lval = FETCH_OPND(-1); + JS_ASSERT(JSVAL_IS_OBJECT(lval)); + cx->newborn[GCX_OBJECT] = JSVAL_TO_GCTHING(lval); + break; + + case JSOP_INITPROP: + /* Pop the property's value into rval. */ + JS_ASSERT(sp - fp->spbase >= 2); + rval = FETCH_OPND(-1); + + /* Get the immediate property name into id. */ + atom = GET_ATOM(cx, script, pc); + id = (jsid)atom; + i = -1; + goto do_init; + + case JSOP_INITELEM: + /* Pop the element's value into rval. */ + JS_ASSERT(sp - fp->spbase >= 3); + rval = FETCH_OPND(-1); + + /* Pop and conditionally atomize the element id. */ + FETCH_ELEMENT_ID(-2, id); + i = -2; + + do_init: + /* Find the object being initialized at top of stack. */ + lval = FETCH_OPND(i-1); + JS_ASSERT(JSVAL_IS_OBJECT(lval)); + obj = JSVAL_TO_OBJECT(lval); + + /* Set the property named by obj[id] to rval. */ + ok = OBJ_SET_PROPERTY(cx, obj, id, &rval); + if (!ok) + goto out; + sp += i; + break; + +#if JS_HAS_SHARP_VARS + case JSOP_DEFSHARP: + obj = fp->sharpArray; + if (!obj) { + obj = js_NewArrayObject(cx, 0, NULL); + if (!obj) { + ok = JS_FALSE; + goto out; + } + fp->sharpArray = obj; + } + i = (jsint) GET_ATOM_INDEX(pc); + id = (jsid) INT_TO_JSVAL(i); + rval = FETCH_OPND(-1); + if (JSVAL_IS_PRIMITIVE(rval)) { + char numBuf[12]; + JS_snprintf(numBuf, sizeof numBuf, "%u", (unsigned) i); + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, + JSMSG_BAD_SHARP_DEF, numBuf); + ok = JS_FALSE; + goto out; + } + ok = OBJ_SET_PROPERTY(cx, obj, id, &rval); + if (!ok) + goto out; + break; + + case JSOP_USESHARP: + i = (jsint) GET_ATOM_INDEX(pc); + id = (jsid) INT_TO_JSVAL(i); + obj = fp->sharpArray; + if (!obj) { + rval = JSVAL_VOID; + } else { + ok = OBJ_GET_PROPERTY(cx, obj, id, &rval); + if (!ok) + goto out; + } + if (!JSVAL_IS_OBJECT(rval)) { + char numBuf[12]; + JS_snprintf(numBuf, sizeof numBuf, "%u", (unsigned) i); + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, + JSMSG_BAD_SHARP_USE, numBuf); + ok = JS_FALSE; + goto out; + } + PUSH_OPND(rval); + break; +#endif /* JS_HAS_SHARP_VARS */ +#endif /* JS_HAS_INITIALIZERS */ + +#if JS_HAS_EXCEPTIONS + /* No-ops for ease of decompilation and jit'ing. */ + case JSOP_TRY: + case JSOP_FINALLY: + break; + + /* Reset the stack to the given depth. */ + case JSOP_SETSP: + i = (jsint) GET_ATOM_INDEX(pc); + JS_ASSERT(i >= 0); + sp = fp->spbase + i; + break; + + case JSOP_GOSUB: + i = PTRDIFF(pc, script->main, jsbytecode) + len; + len = GET_JUMP_OFFSET(pc); + PUSH(INT_TO_JSVAL(i)); + break; + + case JSOP_GOSUBX: + i = PTRDIFF(pc, script->main, jsbytecode) + len; + len = GET_JUMPX_OFFSET(pc); + PUSH(INT_TO_JSVAL(i)); + break; + + case JSOP_RETSUB: + rval = POP(); + JS_ASSERT(JSVAL_IS_INT(rval)); + i = JSVAL_TO_INT(rval); + pc = script->main + i; + len = 0; + break; + + case JSOP_EXCEPTION: + PUSH(cx->exception); + break; + + case JSOP_THROW: + cx->throwing = JS_TRUE; + cx->exception = POP_OPND(); + ok = JS_FALSE; + /* let the code at out try to catch the exception. */ + goto out; + + case JSOP_INITCATCHVAR: + /* Pop the property's value into rval. */ + JS_ASSERT(sp - fp->spbase >= 2); + rval = POP_OPND(); + + /* Get the immediate catch variable name into id. */ + atom = GET_ATOM(cx, script, pc); + id = (jsid)atom; + + /* Find the object being initialized at top of stack. */ + lval = FETCH_OPND(-1); + JS_ASSERT(JSVAL_IS_OBJECT(lval)); + obj = JSVAL_TO_OBJECT(lval); + + /* Define obj[id] to contain rval and to be permanent. */ + ok = OBJ_DEFINE_PROPERTY(cx, obj, id, rval, NULL, NULL, + JSPROP_PERMANENT, NULL); + if (!ok) + goto out; + break; +#endif /* JS_HAS_EXCEPTIONS */ + +#if JS_HAS_INSTANCEOF + case JSOP_INSTANCEOF: + rval = FETCH_OPND(-1); + if (JSVAL_IS_PRIMITIVE(rval)) { + SAVE_SP(fp); + str = js_DecompileValueGenerator(cx, -1, rval, NULL); + if (str) { + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, + JSMSG_BAD_INSTANCEOF_RHS, + JS_GetStringBytes(str)); + } + ok = JS_FALSE; + goto out; + } + obj = JSVAL_TO_OBJECT(rval); + lval = FETCH_OPND(-2); + cond = JS_FALSE; + if (obj->map->ops->hasInstance) { + SAVE_SP(fp); + ok = obj->map->ops->hasInstance(cx, obj, lval, &cond); + if (!ok) + goto out; + } + sp--; + STORE_OPND(-1, BOOLEAN_TO_JSVAL(cond)); + break; +#endif /* JS_HAS_INSTANCEOF */ + +#if JS_HAS_DEBUGGER_KEYWORD + case JSOP_DEBUGGER: + { + JSTrapHandler handler = rt->debuggerHandler; + if (handler) { + SAVE_SP(fp); + switch (handler(cx, script, pc, &rval, + rt->debuggerHandlerData)) { + case JSTRAP_ERROR: + ok = JS_FALSE; + goto out; + case JSTRAP_CONTINUE: + break; + case JSTRAP_RETURN: + fp->rval = rval; + goto out; +#if JS_HAS_EXCEPTIONS + case JSTRAP_THROW: + cx->throwing = JS_TRUE; + cx->exception = rval; + ok = JS_FALSE; + goto out; +#endif /* JS_HAS_EXCEPTIONS */ + default:; + } + LOAD_INTERRUPT_HANDLER(rt); + } + break; + } +#endif /* JS_HAS_DEBUGGER_KEYWORD */ + + default: { + char numBuf[12]; + JS_snprintf(numBuf, sizeof numBuf, "%d", op); + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, + JSMSG_BAD_BYTECODE, numBuf); + ok = JS_FALSE; + goto out; + } + } + + advance_pc: + pc += len; + +#ifdef DEBUG + if (tracefp) { + intN ndefs, n; + jsval *siter; + + ndefs = cs->ndefs; + if (ndefs) { + SAVE_SP(fp); + for (n = -ndefs; n < 0; n++) { + str = js_DecompileValueGenerator(cx, n, sp[n], NULL); + if (str) { + fprintf(tracefp, "%s %s", + (n == -ndefs) ? " output:" : ",", + JS_GetStringBytes(str)); + } + } + fprintf(tracefp, " @ %d\n", sp - fp->spbase); + } + fprintf(tracefp, " stack: "); + for (siter = fp->spbase; siter < sp; siter++) { + str = js_ValueToSource(cx, *siter); + fprintf(tracefp, "%s ", + str ? JS_GetStringBytes(str) : ""); + } + fputc('\n', tracefp); + } +#endif + } +out: + +#if JS_HAS_EXCEPTIONS + /* + * Has an exception been raised? + */ + if (!ok && cx->throwing) { + /* + * Call debugger throw hook if set (XXX thread safety?). + */ + JSTrapHandler handler = rt->throwHook; + if (handler) { + SAVE_SP(fp); + switch (handler(cx, script, pc, &rval, rt->throwHookData)) { + case JSTRAP_ERROR: + cx->throwing = JS_FALSE; + goto no_catch; + case JSTRAP_RETURN: + ok = JS_TRUE; + cx->throwing = JS_FALSE; + fp->rval = rval; + goto no_catch; + case JSTRAP_THROW: + cx->exception = rval; + case JSTRAP_CONTINUE: + default:; + } + LOAD_INTERRUPT_HANDLER(rt); + } + + /* + * Look for a try block within this frame that can catch the exception. + */ + SCRIPT_FIND_CATCH_START(script, pc, pc); + if (pc) { + len = 0; + cx->throwing = JS_FALSE; /* caught */ + ok = JS_TRUE; + goto advance_pc; + } + } +no_catch: +#endif + + /* + * Check whether control fell off the end of a lightweight function, or an + * exception thrown under such a function was not caught by it. If so, go + * to the inline code under JSOP_RETURN. + */ + if (inlineCallCount) + goto inline_return; + + /* + * Reset sp before freeing stack slots, because our caller may GC soon. + * Clear spbase to indicate that we've popped the 2 * depth operand slots. + * Restore the previous frame's execution state. + */ + fp->sp = fp->spbase; + fp->spbase = NULL; + js_FreeRawStack(cx, mark); + if (cx->version == currentVersion && currentVersion != originalVersion) + JS_SetVersion(cx, originalVersion); + cx->interpLevel--; + return ok; + +atom_not_defined: + { + const char *printable = js_AtomToPrintableString(cx, atom); + if (printable) + js_ReportIsNotDefined(cx, printable); + ok = JS_FALSE; + goto out; + } +} diff --git a/src/dom/js/jsinterp.h b/src/dom/js/jsinterp.h new file mode 100644 index 000000000..3e0634e4d --- /dev/null +++ b/src/dom/js/jsinterp.h @@ -0,0 +1,292 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef jsinterp_h___ +#define jsinterp_h___ +/* + * JS interpreter interface. + */ +#include "jsprvtd.h" +#include "jspubtd.h" + +JS_BEGIN_EXTERN_C + +/* + * JS stack frame, allocated on the C stack. + */ +struct JSStackFrame { + JSObject *callobj; /* lazily created Call object */ + JSObject *argsobj; /* lazily created arguments object */ + JSObject *varobj; /* variables object, where vars go */ + JSScript *script; /* script being interpreted */ + JSFunction *fun; /* function being called or null */ + JSObject *thisp; /* "this" pointer if in method */ + uintN argc; /* actual argument count */ + jsval *argv; /* base of argument stack slots */ + jsval rval; /* function return value */ + uintN nvars; /* local variable count */ + jsval *vars; /* base of variable stack slots */ + JSStackFrame *down; /* previous frame */ + void *annotation; /* used by Java security */ + JSObject *scopeChain; /* scope chain */ + jsbytecode *pc; /* program counter */ + jsval *sp; /* stack pointer */ + jsval *spbase; /* operand stack base */ + uintN sharpDepth; /* array/object initializer depth */ + JSObject *sharpArray; /* scope for #n= initializer vars */ + uint32 flags; /* frame flags -- see below */ + JSStackFrame *dormantNext; /* next dormant frame chain */ + JSAtomMap *objAtomMap; /* object atom map, non-null only if we + hit a regexp object literal */ +}; + +typedef struct JSInlineFrame { + JSStackFrame frame; /* base struct */ + void *mark; /* mark before inline frame */ + void *hookData; /* debugger call hook data */ + JSVersion callerVersion; /* dynamic version of calling script */ +} JSInlineFrame; + +/* JS stack frame flags. */ +#define JSFRAME_CONSTRUCTING 0x01 /* frame is for a constructor invocation */ +#define JSFRAME_INTERNAL 0x02 /* internal call, not invoked by a script */ +#define JSFRAME_SKIP_CALLER 0x04 /* skip one link when evaluating f.caller + for this invocation of f */ +#define JSFRAME_ASSIGNING 0x08 /* a complex (not simplex JOF_ASSIGNING) op + is currently assigning to a property */ +#define JSFRAME_DEBUGGER 0x10 /* frame for JS_EvaluateInStackFrame */ +#define JSFRAME_EVAL 0x20 /* frame for obj_eval */ +#define JSFRAME_SPECIAL 0x30 /* special evaluation frame flags */ + +#define JSFRAME_OVERRIDE_SHIFT 24 /* override bit-set params; see jsfun.c */ +#define JSFRAME_OVERRIDE_BITS 8 + +/* + * Property cache for quickened get/set property opcodes. + */ +#define PROPERTY_CACHE_LOG2 10 +#define PROPERTY_CACHE_SIZE JS_BIT(PROPERTY_CACHE_LOG2) +#define PROPERTY_CACHE_MASK JS_BITMASK(PROPERTY_CACHE_LOG2) + +#define PROPERTY_CACHE_HASH(obj, id) \ + ((((jsuword)(obj) >> JSVAL_TAGBITS) ^ (jsuword)(id)) & PROPERTY_CACHE_MASK) + +#ifdef JS_THREADSAFE + +#if HAVE_ATOMIC_DWORD_ACCESS + +#define PCE_LOAD(cache, pce, entry) JS_ATOMIC_DWORD_LOAD(pce, entry) +#define PCE_STORE(cache, pce, entry) JS_ATOMIC_DWORD_STORE(pce, entry) + +#else /* !HAVE_ATOMIC_DWORD_ACCESS */ + +#define JS_PROPERTY_CACHE_METERING 1 + +#define PCE_LOAD(cache, pce, entry) \ + JS_BEGIN_MACRO \ + uint32 prefills_; \ + uint32 fills_ = (cache)->fills; \ + do { \ + /* Load until cache->fills is stable (see FILL macro below). */ \ + prefills_ = fills_; \ + (entry) = *(pce); \ + } while ((fills_ = (cache)->fills) != prefills_); \ + JS_END_MACRO + +#define PCE_STORE(cache, pce, entry) \ + JS_BEGIN_MACRO \ + do { \ + /* Store until no racing collider stores half or all of pce. */ \ + *(pce) = (entry); \ + } while (PCE_OBJECT(*pce) != PCE_OBJECT(entry) || \ + PCE_PROPERTY(*pce) != PCE_PROPERTY(entry)); \ + JS_END_MACRO + +#endif /* !HAVE_ATOMIC_DWORD_ACCESS */ + +#else /* !JS_THREADSAFE */ + +#define PCE_LOAD(cache, pce, entry) ((entry) = *(pce)) +#define PCE_STORE(cache, pce, entry) (*(pce) = (entry)) + +#endif /* !JS_THREADSAFE */ + +typedef union JSPropertyCacheEntry { + struct { + JSObject *object; /* weak link to object */ + JSScopeProperty *property; /* weak link to property */ + } s; +#ifdef HAVE_ATOMIC_DWORD_ACCESS + prdword align; +#endif +} JSPropertyCacheEntry; + +/* These may be called in lvalue or rvalue position. */ +#define PCE_OBJECT(entry) ((entry).s.object) +#define PCE_PROPERTY(entry) ((entry).s.property) + +typedef struct JSPropertyCache { + JSPropertyCacheEntry table[PROPERTY_CACHE_SIZE]; + JSBool empty; + JSBool disabled; +#ifdef JS_PROPERTY_CACHE_METERING + uint32 fills; + uint32 recycles; + uint32 tests; + uint32 misses; + uint32 flushes; +# define PCMETER(x) x +#else +# define PCMETER(x) /* nothing */ +#endif +} JSPropertyCache; + +#define PROPERTY_CACHE_FILL(cache, obj, id, sprop) \ + JS_BEGIN_MACRO \ + JSPropertyCache *cache_ = (cache); \ + if (!cache_->disabled) { \ + uintN hashIndex_ = (uintN) PROPERTY_CACHE_HASH(obj, id); \ + JSPropertyCacheEntry *pce_ = &cache_->table[hashIndex_]; \ + JSPropertyCacheEntry entry_; \ + JSScopeProperty *pce_sprop_; \ + PCE_LOAD(cache_, pce_, entry_); \ + pce_sprop_ = PCE_PROPERTY(entry_); \ + PCMETER(if (pce_sprop_ && pce_sprop_ != sprop) \ + cache_->recycles++); \ + PCE_OBJECT(entry_) = obj; \ + PCE_PROPERTY(entry_) = sprop; \ + cache_->empty = JS_FALSE; \ + PCMETER(cache_->fills++); \ + PCE_STORE(cache_, pce_, entry_); \ + } \ + JS_END_MACRO + +#define PROPERTY_CACHE_TEST(cache, obj, id, sprop) \ + JS_BEGIN_MACRO \ + uintN hashIndex_ = (uintN) PROPERTY_CACHE_HASH(obj, id); \ + JSPropertyCache *cache_ = (cache); \ + JSPropertyCacheEntry *pce_ = &cache_->table[hashIndex_]; \ + JSPropertyCacheEntry entry_; \ + JSScopeProperty *pce_sprop_; \ + PCE_LOAD(cache_, pce_, entry_); \ + pce_sprop_ = PCE_PROPERTY(entry_); \ + PCMETER(cache_->tests++); \ + if (pce_sprop_ && \ + PCE_OBJECT(entry_) == obj && \ + pce_sprop_->id == id) { \ + sprop = pce_sprop_; \ + } else { \ + PCMETER(cache_->misses++); \ + sprop = NULL; \ + } \ + JS_END_MACRO + +extern void +js_FlushPropertyCache(JSContext *cx); + +extern void +js_DisablePropertyCache(JSContext *cx); + +extern void +js_EnablePropertyCache(JSContext *cx); + +extern JS_FRIEND_API(jsval *) +js_AllocStack(JSContext *cx, uintN nslots, void **markp); + +extern JS_FRIEND_API(void) +js_FreeStack(JSContext *cx, void *mark); + +extern JSBool +js_GetArgument(JSContext *cx, JSObject *obj, jsval id, jsval *vp); + +extern JSBool +js_SetArgument(JSContext *cx, JSObject *obj, jsval id, jsval *vp); + +extern JSBool +js_GetLocalVariable(JSContext *cx, JSObject *obj, jsval id, jsval *vp); + +extern JSBool +js_SetLocalVariable(JSContext *cx, JSObject *obj, jsval id, jsval *vp); + +/* + * NB: js_Invoke requires that cx is currently running JS (i.e., that cx->fp + * is non-null). + */ +extern JS_FRIEND_API(JSBool) +js_Invoke(JSContext *cx, uintN argc, uintN flags); + +/* + * Consolidated js_Invoke flags simply rename the low JSFRAME_* flags. + */ +#define JSINVOKE_CONSTRUCT JSFRAME_CONSTRUCTING +#define JSINVOKE_INTERNAL JSFRAME_INTERNAL +#define JSINVOKE_SKIP_CALLER JSFRAME_SKIP_CALLER + +/* + * "Internal" calls may come from C or C++ code using a JSContext on which no + * JS is running (!cx->fp), so they may need to push a dummy JSStackFrame. + */ +#define js_InternalCall(cx,obj,fval,argc,argv,rval) \ + js_InternalInvoke(cx, obj, fval, 0, argc, argv, rval) + +#define js_InternalConstruct(cx,obj,fval,argc,argv,rval) \ + js_InternalInvoke(cx, obj, fval, JSINVOKE_CONSTRUCT, argc, argv, rval) + +extern JSBool +js_InternalInvoke(JSContext *cx, JSObject *obj, jsval fval, uintN flags, + uintN argc, jsval *argv, jsval *rval); + +extern JSBool +js_InternalGetOrSet(JSContext *cx, JSObject *obj, jsid id, jsval fval, + JSAccessMode mode, uintN argc, jsval *argv, jsval *rval); + +extern JSBool +js_Execute(JSContext *cx, JSObject *chain, JSScript *script, + JSStackFrame *down, uintN flags, jsval *result); + +extern JSBool +js_CheckRedeclaration(JSContext *cx, JSObject *obj, jsid id, uintN attrs, + JSBool *foundp); + +extern JSBool +js_Interpret(JSContext *cx, jsval *result); + +JS_END_EXTERN_C + +#endif /* jsinterp_h___ */ diff --git a/src/dom/js/jslibmath.h b/src/dom/js/jslibmath.h new file mode 100644 index 000000000..7cbcf767a --- /dev/null +++ b/src/dom/js/jslibmath.h @@ -0,0 +1,290 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * IBM Corp. + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* + * By default all math calls go to fdlibm. The defines for each platform + * remap the math calls to native routines. + */ + +#ifndef _LIBMATH_H +#define _LIBMATH_H + +#include +#include "jsconfig.h" + +/* + * Define which platforms on which to use fdlibm. Not used + * by default since there can be problems with endian-ness and such. + */ + +#if defined(_WIN32) && !defined(__MWERKS__) +#define JS_USE_FDLIBM_MATH 1 + +#elif defined(SUNOS4) +#define JS_USE_FDLIBM_MATH 1 + +#elif defined(IRIX) +#define JS_USE_FDLIBM_MATH 1 + +#elif defined(SOLARIS) +#define JS_USE_FDLIBM_MATH 1 + +#elif defined(HPUX) +#define JS_USE_FDLIBM_MATH 1 + +#elif defined(linux) +#define JS_USE_FDLIBM_MATH 1 + +#elif defined(OSF1) +/* Want to use some fdlibm functions but fdlibm broken on OSF1/alpha. */ +#define JS_USE_FDLIBM_MATH 0 + +#elif defined(AIX) +#define JS_USE_FDLIBM_MATH 1 + +#else +#define JS_USE_FDLIBM_MATH 0 +#endif + +#if !JS_USE_FDLIBM_MATH + +/* + * Use system provided math routines. + */ + +#define fd_acos acos +#define fd_asin asin +#define fd_atan atan +#define fd_atan2 atan2 +#define fd_ceil ceil +#define fd_copysign copysign +#define fd_cos cos +#define fd_exp exp +#define fd_fabs fabs +#define fd_floor floor +#define fd_fmod fmod +#define fd_log log +#define fd_pow pow +#define fd_sin sin +#define fd_sqrt sqrt +#define fd_tan tan + +#else + +/* + * Use math routines in fdlibm. + */ + +#undef __P +#ifdef __STDC__ +#define __P(p) p +#else +#define __P(p) () +#endif + +#if defined _WIN32 || defined SUNOS4 + +#define fd_acos acos +#define fd_asin asin +#define fd_atan atan +#define fd_cos cos +#define fd_sin sin +#define fd_tan tan +#define fd_exp exp +#define fd_log log +#define fd_sqrt sqrt +#define fd_ceil ceil +#define fd_fabs fabs +#define fd_floor floor +#define fd_fmod fmod + +extern double fd_atan2 __P((double, double)); +extern double fd_copysign __P((double, double)); +extern double fd_pow __P((double, double)); + +#elif defined IRIX + +#define fd_acos acos +#define fd_asin asin +#define fd_atan atan +#define fd_exp exp +#define fd_log log +#define fd_log10 log10 +#define fd_sqrt sqrt +#define fd_fabs fabs +#define fd_floor floor +#define fd_fmod fmod + +extern double fd_cos __P((double)); +extern double fd_sin __P((double)); +extern double fd_tan __P((double)); +extern double fd_atan2 __P((double, double)); +extern double fd_pow __P((double, double)); +extern double fd_ceil __P((double)); +extern double fd_copysign __P((double, double)); + +#elif defined SOLARIS + +#define fd_atan atan +#define fd_cos cos +#define fd_sin sin +#define fd_tan tan +#define fd_exp exp +#define fd_sqrt sqrt +#define fd_ceil ceil +#define fd_fabs fabs +#define fd_floor floor +#define fd_fmod fmod + +extern double fd_acos __P((double)); +extern double fd_asin __P((double)); +extern double fd_log __P((double)); +extern double fd_atan2 __P((double, double)); +extern double fd_pow __P((double, double)); +extern double fd_copysign __P((double, double)); + +#elif defined HPUX + +#define fd_cos cos +#define fd_sin sin +#define fd_exp exp +#define fd_sqrt sqrt +#define fd_fabs fabs +#define fd_floor floor +#define fd_fmod fmod + +extern double fd_ceil __P((double)); +extern double fd_acos __P((double)); +extern double fd_log __P((double)); +extern double fd_atan2 __P((double, double)); +extern double fd_tan __P((double)); +extern double fd_pow __P((double, double)); +extern double fd_asin __P((double)); +extern double fd_atan __P((double)); +extern double fd_copysign __P((double, double)); + +#elif defined(linux) + +#define fd_atan atan +#define fd_atan2 atan2 +#define fd_ceil ceil +#define fd_cos cos +#define fd_fabs fabs +#define fd_floor floor +#define fd_fmod fmod +#define fd_sin sin +#define fd_sqrt sqrt +#define fd_tan tan +#define fd_copysign copysign + +extern double fd_asin __P((double)); +extern double fd_acos __P((double)); +extern double fd_exp __P((double)); +extern double fd_log __P((double)); +extern double fd_pow __P((double, double)); + +#elif defined(OSF1) + +#define fd_acos acos +#define fd_asin asin +#define fd_atan atan +#define fd_copysign copysign +#define fd_cos cos +#define fd_exp exp +#define fd_fabs fabs +#define fd_fmod fmod +#define fd_sin sin +#define fd_sqrt sqrt +#define fd_tan tan + +extern double fd_atan2 __P((double, double)); +extern double fd_ceil __P((double)); +extern double fd_floor __P((double)); +extern double fd_log __P((double)); +extern double fd_pow __P((double, double)); + +#elif defined(AIX) + +#define fd_acos acos +#define fd_asin asin +#define fd_atan2 atan2 +#define fd_copysign copysign +#define fd_cos cos +#define fd_exp exp +#define fd_fabs fabs +#define fd_floor floor +#define fd_fmod fmod +#define fd_log log +#define fd_sin sin +#define fd_sqrt sqrt + +extern double fd_atan __P((double)); +extern double fd_ceil __P((double)); +extern double fd_pow __P((double,double)); +extern double fd_tan __P((double)); + +#else /* other platform.. generic paranoid slow fdlibm */ + +extern double fd_acos __P((double)); +extern double fd_asin __P((double)); +extern double fd_atan __P((double)); +extern double fd_cos __P((double)); +extern double fd_sin __P((double)); +extern double fd_tan __P((double)); + +extern double fd_exp __P((double)); +extern double fd_log __P((double)); +extern double fd_sqrt __P((double)); + +extern double fd_ceil __P((double)); +extern double fd_fabs __P((double)); +extern double fd_floor __P((double)); +extern double fd_fmod __P((double, double)); + +extern double fd_atan2 __P((double, double)); +extern double fd_pow __P((double, double)); +extern double fd_copysign __P((double, double)); + +#endif + +#endif /* JS_USE_FDLIBM_MATH */ + +#endif /* _LIBMATH_H */ + diff --git a/src/dom/js/jslock.c b/src/dom/js/jslock.c new file mode 100644 index 000000000..9709c8cc0 --- /dev/null +++ b/src/dom/js/jslock.c @@ -0,0 +1,1241 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifdef JS_THREADSAFE + +/* + * JS locking stubs. + */ +#include "jsstddef.h" +#include +#include "jspubtd.h" +#include "prthread.h" +#include "jsutil.h" /* Added by JSIFY */ +#include "jstypes.h" +#include "jsbit.h" +#include "jscntxt.h" +#include "jsdtoa.h" +#include "jsgc.h" +#include "jslock.h" +#include "jsscope.h" +#include "jsstr.h" + +#define ReadWord(W) (W) + +#ifndef NSPR_LOCK + +#include + +static PRLock **global_locks; +static uint32 global_lock_count = 1; +static uint32 global_locks_log2 = 0; +static uint32 global_locks_mask = 0; + +#define GLOBAL_LOCK_INDEX(id) (((uint32)(id) >> 2) & global_locks_mask) + +static void +js_LockGlobal(void *id) +{ + uint32 i = GLOBAL_LOCK_INDEX(id); + PR_Lock(global_locks[i]); +} + +static void +js_UnlockGlobal(void *id) +{ + uint32 i = GLOBAL_LOCK_INDEX(id); + PR_Unlock(global_locks[i]); +} + +/* Exclude Alpha NT. */ +#if defined(_WIN32) && defined(_M_IX86) +#pragma warning( disable : 4035 ) + +static JS_INLINE int +js_CompareAndSwap(jsword *w, jsword ov, jsword nv) +{ + __asm { + mov eax, ov + mov ecx, nv + mov ebx, w + lock cmpxchg [ebx], ecx + sete al + and eax, 1h + } +} + +#elif defined(__GNUC__) && defined(__i386__) + +/* Note: This fails on 386 cpus, cmpxchgl is a >= 486 instruction */ +static JS_INLINE int +js_CompareAndSwap(jsword *w, jsword ov, jsword nv) +{ + unsigned int res; + + __asm__ __volatile__ ( + "lock\n" + "cmpxchgl %2, (%1)\n" + "sete %%al\n" + "andl $1, %%eax\n" + : "=a" (res) + : "r" (w), "r" (nv), "a" (ov) + : "cc", "memory"); + return (int)res; +} + +#elif defined(SOLARIS) && defined(sparc) && defined(ULTRA_SPARC) + +static JS_INLINE int +js_CompareAndSwap(jsword *w, jsword ov, jsword nv) +{ +#if defined(__GNUC__) + unsigned int res; + JS_ASSERT(ov != nv); + asm volatile ("\ +stbar\n\ +cas [%1],%2,%3\n\ +cmp %2,%3\n\ +be,a 1f\n\ +mov 1,%0\n\ +mov 0,%0\n\ +1:" + : "=r" (res) + : "r" (w), "r" (ov), "r" (nv)); + return (int)res; +#else /* !__GNUC__ */ + extern int compare_and_swap(jsword*, jsword, jsword); + JS_ASSERT(ov != nv); + return compare_and_swap(w, ov, nv); +#endif +} + +#elif defined(AIX) + +#include + +static JS_INLINE int +js_CompareAndSwap(jsword *w, jsword ov, jsword nv) +{ + return !_check_lock((atomic_p)w, ov, nv); +} + +#else + +#error "Define NSPR_LOCK if your platform lacks a compare-and-swap instruction." + +#endif /* arch-tests */ + +#endif /* !NSPR_LOCK */ + +jsword +js_CurrentThreadId() +{ + return CurrentThreadId(); +} + +void +js_InitLock(JSThinLock *tl) +{ +#ifdef NSPR_LOCK + tl->owner = 0; + tl->fat = (JSFatLock*)JS_NEW_LOCK(); +#else + memset(tl, 0, sizeof(JSThinLock)); +#endif +} + +void +js_FinishLock(JSThinLock *tl) +{ +#ifdef NSPR_LOCK + tl->owner = 0xdeadbeef; + if (tl->fat) + JS_DESTROY_LOCK(((JSLock*)tl->fat)); +#else + JS_ASSERT(tl->owner == 0); + JS_ASSERT(tl->fat == NULL); +#endif +} + +static void js_Dequeue(JSThinLock *); + +#ifdef DEBUG_SCOPE_COUNT + +#include +#include "jsdhash.h" + +static FILE *logfp; +static JSDHashTable logtbl; + +typedef struct logentry { + JSDHashEntryStub stub; + char op; + const char *file; + int line; +} logentry; + +static void +logit(JSScope *scope, char op, const char *file, int line) +{ + logentry *entry; + + if (!logfp) { + logfp = fopen("/tmp/scope.log", "w"); + if (!logfp) + return; + setvbuf(logfp, NULL, _IONBF, 0); + } + fprintf(logfp, "%p %c %s %d\n", scope, op, file, line); + + if (!logtbl.entryStore && + !JS_DHashTableInit(&logtbl, JS_DHashGetStubOps(), NULL, + sizeof(logentry), 100)) { + return; + } + entry = (logentry *) JS_DHashTableOperate(&logtbl, scope, JS_DHASH_ADD); + if (!entry) + return; + entry->stub.key = scope; + entry->op = op; + entry->file = file; + entry->line = line; +} + +void +js_unlog_scope(JSScope *scope) +{ + if (!logtbl.entryStore) + return; + (void) JS_DHashTableOperate(&logtbl, scope, JS_DHASH_REMOVE); +} + +# define LOGIT(scope,op) logit(scope, op, __FILE__, __LINE__) + +#else + +# define LOGIT(scope,op) /* nothing */ + +#endif /* DEBUG_SCOPE_COUNT */ + +/* + * Return true if scope's ownercx, or the ownercx of a single-threaded scope + * for which ownercx is waiting to become multi-threaded and shared, is cx. + * That condition implies deadlock in ClaimScope if cx's thread were to wait + * to share scope. + * + * (i) rt->gcLock held + */ +static JSBool +WillDeadlock(JSScope *scope, JSContext *cx) +{ + JSContext *ownercx; + + do { + ownercx = scope->ownercx; + if (ownercx == cx) { + JS_RUNTIME_METER(cx->runtime, deadlocksAvoided); + return JS_TRUE; + } + } while (ownercx && (scope = ownercx->scopeToShare) != NULL); + return JS_FALSE; +} + +/* + * Make scope multi-threaded, i.e. share its ownership among contexts in rt + * using a "thin" or (if necessary due to contention) "fat" lock. Called only + * from ClaimScope, immediately below, when we detect deadlock were we to wait + * for scope's lock, because its ownercx is waiting on a scope owned by the + * calling cx. + * + * (i) rt->gcLock held + */ +static void +ShareScope(JSRuntime *rt, JSScope *scope) +{ + JSScope **todop; + + if (scope->u.link) { + for (todop = &rt->scopeSharingTodo; *todop != scope; + todop = &(*todop)->u.link) { + JS_ASSERT(*todop != NO_SCOPE_SHARING_TODO); + } + *todop = scope->u.link; + scope->u.link = NULL; /* null u.link for sanity ASAP */ + JS_NOTIFY_ALL_CONDVAR(rt->scopeSharingDone); + } + js_InitLock(&scope->lock); + if (scope == rt->setSlotScope) { + /* + * Nesting locks on another thread that's using scope->ownercx: give + * the held lock a reentrancy count of 1 and set its lock.owner field + * directly (no compare-and-swap needed while scope->ownercx is still + * non-null). See below in ClaimScope, before the ShareScope call, + * for more on why this is necessary. + * + * If NSPR_LOCK is defined, we cannot deadlock holding rt->gcLock and + * acquiring scope->lock.fat here, against another thread holding that + * fat lock and trying to grab rt->gcLock. This is because no other + * thread can attempt to acquire scope->lock.fat until scope->ownercx + * is null *and* our thread has released rt->gcLock, which interlocks + * scope->ownercx's transition to null against tests of that member + * in ClaimScope. + */ + scope->lock.owner = scope->ownercx->thread; +#ifdef NSPR_LOCK + JS_ACQUIRE_LOCK((JSLock*)scope->lock.fat); +#endif + scope->u.count = 1; + } else { + scope->u.count = 0; + } + js_FinishSharingScope(rt, scope); +} + +/* + * js_FinishSharingScope is the tail part of ShareScope, split out to become a + * subroutine of JS_EndRequest too. The bulk of the work here involves making + * mutable strings in the scope's object's slots be immutable. We have to do + * this because such strings will soon be available to multiple threads, so + * their buffers can't be realloc'd any longer in js_ConcatStrings, and their + * members can't be modified by js_ConcatStrings, js_MinimizeDependentStrings, + * or js_UndependString. + * + * The last bit of work done by js_FinishSharingScope nulls scope->ownercx and + * updates rt->sharedScopes. + */ +#define MAKE_STRING_IMMUTABLE(rt, v, vp) \ + JS_BEGIN_MACRO \ + JSString *str_ = JSVAL_TO_STRING(v); \ + uint8 *flagp_ = js_GetGCThingFlags(str_); \ + if (*flagp_ & GCF_MUTABLE) { \ + if (JSSTRING_IS_DEPENDENT(str_) && \ + !js_UndependString(NULL, str_)) { \ + JS_RUNTIME_METER(rt, badUndependStrings); \ + *vp = JSVAL_VOID; \ + } else { \ + *flagp_ &= ~GCF_MUTABLE; \ + } \ + } \ + JS_END_MACRO + +void +js_FinishSharingScope(JSRuntime *rt, JSScope *scope) +{ + JSObject *obj; + uint32 nslots; + jsval v, *vp, *end; + + obj = scope->object; + nslots = JS_MIN(obj->map->freeslot, obj->map->nslots); + for (vp = obj->slots, end = vp + nslots; vp < end; vp++) { + v = *vp; + if (JSVAL_IS_STRING(v)) + MAKE_STRING_IMMUTABLE(rt, v, vp); + } + + scope->ownercx = NULL; /* NB: set last, after lock init */ + JS_RUNTIME_METER(rt, sharedScopes); +} + +/* + * Given a scope with apparently non-null ownercx different from cx, try to + * set ownercx to cx, claiming exclusive (single-threaded) ownership of scope. + * If we claim ownership, return true. Otherwise, we wait for ownercx to be + * set to null (indicating that scope is multi-threaded); or if waiting would + * deadlock, we set ownercx to null ourselves via ShareScope. In any case, + * once ownercx is null we return false. + */ +static JSBool +ClaimScope(JSScope *scope, JSContext *cx) +{ + JSRuntime *rt; + JSContext *ownercx; + jsrefcount saveDepth; + PRStatus stat; + + rt = cx->runtime; + JS_RUNTIME_METER(rt, claimAttempts); + JS_LOCK_GC(rt); + + /* Reload in case ownercx went away while we blocked on the lock. */ + while ((ownercx = scope->ownercx) != NULL) { + /* + * Avoid selflock if ownercx is dead, or is not running a request, or + * has the same thread as cx. Set scope->ownercx to cx so that the + * matching JS_UNLOCK_SCOPE or JS_UNLOCK_OBJ macro call will take the + * fast path around the corresponding js_UnlockScope or js_UnlockObj + * function call. + * + * If scope->u.link is non-null, scope has already been inserted on + * the rt->scopeSharingTodo list, because another thread's context + * already wanted to lock scope while ownercx was running a request. + * We can't claim any scope whose u.link is non-null at this point, + * even if ownercx->requestDepth is 0 (see below where we suspend our + * request before waiting on rt->scopeSharingDone). + */ + if (!scope->u.link && + (!js_ValidContextPointer(rt, ownercx) || + !ownercx->requestDepth || + ownercx->thread == cx->thread)) { + JS_ASSERT(scope->u.count == 0); + scope->ownercx = cx; + JS_UNLOCK_GC(rt); + JS_RUNTIME_METER(rt, claimedScopes); + return JS_TRUE; + } + + /* + * Avoid deadlock if scope's owner context is waiting on a scope that + * we own, by revoking scope's ownership. This approach to deadlock + * avoidance works because the engine never nests scope locks, except + * for the notable case of js_SetProtoOrParent (see jsobj.c). + * + * If cx could hold locks on ownercx->scopeToShare, or if ownercx + * could hold locks on scope, we would need to keep reentrancy counts + * for all such "flyweight" (ownercx != NULL) locks, so that control + * would unwind properly once these locks became "thin" or "fat". + * Apart from the js_SetProtoOrParent exception, the engine promotes + * a scope from exclusive to shared access only when locking, never + * when holding or unlocking. + * + * If ownercx's thread is calling js_SetProtoOrParent, trying to lock + * the inner scope (the scope of the object being set as the prototype + * of the outer object), ShareScope will find the outer object's scope + * at rt->setSlotScope. If it's the same as scope, we give it a lock + * held by ownercx's thread with reentrancy count of 1, then we return + * here and break. After that we unwind to js_[GS]etSlotThreadSafe or + * js_LockScope (our caller), where we wait on the newly-fattened lock + * until ownercx's thread unwinds from js_SetProtoOrParent. + * + * Avoid deadlock before any of this scope/context cycle detection if + * cx is on the active GC's thread, because in that case, no requests + * will run until the GC completes. Any scope wanted by the GC (from + * a finalizer) that can't be claimed must be slated for sharing. + */ + if (rt->gcThread == cx->thread || + (ownercx->scopeToShare && + WillDeadlock(ownercx->scopeToShare, cx))) { + ShareScope(rt, scope); + break; + } + + /* + * Thanks to the non-zero NO_SCOPE_SHARING_TODO link terminator, we + * can decide whether scope is on rt->scopeSharingTodo with a single + * non-null test, and avoid double-insertion bugs. + */ + if (!scope->u.link) { + scope->u.link = rt->scopeSharingTodo; + rt->scopeSharingTodo = scope; + js_HoldObjectMap(cx, &scope->map); + } + + /* + * Inline JS_SuspendRequest before we wait on rt->scopeSharingDone, + * saving and clearing cx->requestDepth so we don't deadlock if the + * GC needs to run on ownercx. + * + * Unlike JS_SuspendRequest and JS_EndRequest, we must take care not + * to decrement rt->requestCount if cx is active on the GC's thread, + * because the GC has already reduced rt->requestCount to exclude all + * such such contexts. + */ + saveDepth = cx->requestDepth; + if (saveDepth) { + cx->requestDepth = 0; + if (rt->gcThread != cx->thread) { + JS_ASSERT(rt->requestCount > 0); + rt->requestCount--; + if (rt->requestCount == 0) + JS_NOTIFY_REQUEST_DONE(rt); + } + } + + /* + * We know that some other thread's context owns scope, which is now + * linked onto rt->scopeSharingTodo, awaiting the end of that other + * thread's request. So it is safe to wait on rt->scopeSharingDone. + */ + cx->scopeToShare = scope; + stat = PR_WaitCondVar(rt->scopeSharingDone, PR_INTERVAL_NO_TIMEOUT); + JS_ASSERT(stat != PR_FAILURE); + + /* + * Inline JS_ResumeRequest after waiting on rt->scopeSharingDone, + * restoring cx->requestDepth. Same note as above for the inlined, + * specialized JS_SuspendRequest code: beware rt->gcThread. + */ + if (saveDepth) { + if (rt->gcThread != cx->thread) { + while (rt->gcLevel > 0) + JS_AWAIT_GC_DONE(rt); + rt->requestCount++; + } + cx->requestDepth = saveDepth; + } + + /* + * Don't clear cx->scopeToShare until after we're through waiting on + * all condition variables protected by rt->gcLock -- that includes + * rt->scopeSharingDone *and* rt->gcDone (hidden in JS_AWAIT_GC_DONE, + * in the inlined JS_ResumeRequest code immediately above). + * + * Otherwise, the GC could easily deadlock with another thread that + * owns a scope wanted by a finalizer. By keeping cx->scopeToShare + * set till here, we ensure that such deadlocks are detected, which + * results in the finalized object's scope being shared (it must, of + * course, have other, live objects sharing it). + */ + cx->scopeToShare = NULL; + } + + JS_UNLOCK_GC(rt); + return JS_FALSE; +} + +/* Exported to js.c, which calls it via OBJ_GET_* and JSVAL_IS_* macros. */ +JS_FRIEND_API(jsval) +js_GetSlotThreadSafe(JSContext *cx, JSObject *obj, uint32 slot) +{ + jsval v; + JSScope *scope; +#ifndef NSPR_LOCK + JSThinLock *tl; + jsword me; +#endif + + /* + * We handle non-native objects via JSObjectOps.getRequiredSlot, treating + * all slots starting from 0 as required slots. A property definition or + * some prior arrangement must have allocated slot. + * + * Note once again (see jspubtd.h, before JSGetRequiredSlotOp's typedef) + * the crucial distinction between a |required slot number| that's passed + * to the get/setRequiredSlot JSObjectOps, and a |reserved slot index| + * passed to the JS_Get/SetReservedSlot APIs. + */ + if (!OBJ_IS_NATIVE(obj)) + return OBJ_GET_REQUIRED_SLOT(cx, obj, slot); + + /* + * Native object locking is inlined here to optimize the single-threaded + * and contention-free multi-threaded cases. + */ + scope = OBJ_SCOPE(obj); + JS_ASSERT(scope->ownercx != cx); + JS_ASSERT(obj->slots && slot < obj->map->freeslot); + + /* + * Avoid locking if called from the GC (see GC_AWARE_GET_SLOT in jsobj.h). + * Also avoid locking an object owning a sealed scope. If neither of those + * special cases applies, try to claim scope's flyweight lock from whatever + * context may have had it in an earlier request. + */ + if (CX_THREAD_IS_RUNNING_GC(cx) || + (SCOPE_IS_SEALED(scope) && scope->object == obj) || + (scope->ownercx && ClaimScope(scope, cx))) { + return obj->slots[slot]; + } + +#ifndef NSPR_LOCK + tl = &scope->lock; + me = cx->thread; + JS_ASSERT(me == CurrentThreadId()); + if (js_CompareAndSwap(&tl->owner, 0, me)) { + /* + * Got the lock with one compare-and-swap. Even so, someone else may + * have mutated obj so it now has its own scope and lock, which would + * require either a restart from the top of this routine, or a thin + * lock release followed by fat lock acquisition. + */ + if (scope == OBJ_SCOPE(obj)) { + v = obj->slots[slot]; + if (!js_CompareAndSwap(&tl->owner, me, 0)) { + /* Assert that scope locks never revert to flyweight. */ + JS_ASSERT(scope->ownercx != cx); + LOGIT(scope, '1'); + scope->u.count = 1; + js_UnlockObj(cx, obj); + } + return v; + } + if (!js_CompareAndSwap(&tl->owner, me, 0)) + js_Dequeue(tl); + } + else if (Thin_RemoveWait(ReadWord(tl->owner)) == me) { + return obj->slots[slot]; + } +#endif + + js_LockObj(cx, obj); + v = obj->slots[slot]; + + /* + * Test whether cx took ownership of obj's scope during js_LockObj. + * + * This does not mean that a given scope reverted to flyweight from "thin" + * or "fat" -- it does mean that obj's map pointer changed due to another + * thread setting a property, requiring obj to cease sharing a prototype + * object's scope (whose lock was not flyweight, else we wouldn't be here + * in the first place!). + */ + scope = OBJ_SCOPE(obj); + if (scope->ownercx != cx) + js_UnlockScope(cx, scope); + return v; +} + +void +js_SetSlotThreadSafe(JSContext *cx, JSObject *obj, uint32 slot, jsval v) +{ + JSScope *scope; +#ifndef NSPR_LOCK + JSThinLock *tl; + jsword me; +#endif + + /* Any string stored in a thread-safe object must be immutable. */ + if (JSVAL_IS_STRING(v)) + MAKE_STRING_IMMUTABLE(cx->runtime, v, &v); + + /* + * We handle non-native objects via JSObjectOps.setRequiredSlot, as above + * for the Get case. + */ + if (!OBJ_IS_NATIVE(obj)) { + OBJ_SET_REQUIRED_SLOT(cx, obj, slot, v); + return; + } + + /* + * Native object locking is inlined here to optimize the single-threaded + * and contention-free multi-threaded cases. + */ + scope = OBJ_SCOPE(obj); + JS_ASSERT(scope->ownercx != cx); + JS_ASSERT(obj->slots && slot < obj->map->freeslot); + + /* + * Avoid locking if called from the GC (see GC_AWARE_GET_SLOT in jsobj.h). + * Also avoid locking an object owning a sealed scope. If neither of those + * special cases applies, try to claim scope's flyweight lock from whatever + * context may have had it in an earlier request. + */ + if (CX_THREAD_IS_RUNNING_GC(cx) || + (SCOPE_IS_SEALED(scope) && scope->object == obj) || + (scope->ownercx && ClaimScope(scope, cx))) { + obj->slots[slot] = v; + return; + } + +#ifndef NSPR_LOCK + tl = &scope->lock; + me = cx->thread; + JS_ASSERT(me == CurrentThreadId()); + if (js_CompareAndSwap(&tl->owner, 0, me)) { + if (scope == OBJ_SCOPE(obj)) { + obj->slots[slot] = v; + if (!js_CompareAndSwap(&tl->owner, me, 0)) { + /* Assert that scope locks never revert to flyweight. */ + JS_ASSERT(scope->ownercx != cx); + LOGIT(scope, '1'); + scope->u.count = 1; + js_UnlockObj(cx, obj); + } + return; + } + if (!js_CompareAndSwap(&tl->owner, me, 0)) + js_Dequeue(tl); + } + else if (Thin_RemoveWait(ReadWord(tl->owner)) == me) { + obj->slots[slot] = v; + return; + } +#endif + + js_LockObj(cx, obj); + obj->slots[slot] = v; + + /* + * Same drill as above, in js_GetSlotThreadSafe. Note that we cannot + * assume obj has its own mutable scope (where scope->object == obj) yet, + * because OBJ_SET_SLOT is called for the "universal", common slots such + * as JSSLOT_PROTO and JSSLOT_PARENT, without a prior js_GetMutableScope. + * See also the JSPROP_SHARED attribute and its usage. + */ + scope = OBJ_SCOPE(obj); + if (scope->ownercx != cx) + js_UnlockScope(cx, scope); +} + +#ifndef NSPR_LOCK + +static JSFatLock * +NewFatlock() +{ + JSFatLock *fl = (JSFatLock *)malloc(sizeof(JSFatLock)); /* for now */ + if (!fl) return NULL; + fl->susp = 0; + fl->next = NULL; + fl->prevp = NULL; + fl->slock = PR_NewLock(); + fl->svar = PR_NewCondVar(fl->slock); + return fl; +} + +static void +DestroyFatlock(JSFatLock *fl) +{ + PR_DestroyLock(fl->slock); + PR_DestroyCondVar(fl->svar); + free(fl); +} + +static JSFatLock * +ListOfFatlocks(int listc) +{ + JSFatLock *m; + JSFatLock *m0; + int i; + + JS_ASSERT(listc>0); + m0 = m = NewFatlock(); + for (i=1; inext = NewFatlock(); + m = m->next; + } + return m0; +} + +static void +DeleteListOfFatlocks(JSFatLock *m) +{ + JSFatLock *m0; + for (; m; m=m0) { + m0 = m->next; + DestroyFatlock(m); + } +} + +static JSFatLockTable *fl_list_table = NULL; +static uint32 fl_list_table_len = 0; +static uint32 fl_list_chunk_len = 0; + +static JSFatLock * +GetFatlock(void *id) +{ + JSFatLock *m; + + uint32 i = GLOBAL_LOCK_INDEX(id); + if (fl_list_table[i].free == NULL) { +#ifdef DEBUG + if (fl_list_table[i].taken) + printf("Ran out of fat locks!\n"); +#endif + fl_list_table[i].free = ListOfFatlocks(fl_list_chunk_len); + } + m = fl_list_table[i].free; + fl_list_table[i].free = m->next; + m->susp = 0; + m->next = fl_list_table[i].taken; + m->prevp = &fl_list_table[i].taken; + if (fl_list_table[i].taken) + fl_list_table[i].taken->prevp = &m->next; + fl_list_table[i].taken = m; + return m; +} + +static void +PutFatlock(JSFatLock *m, void *id) +{ + uint32 i; + if (m == NULL) + return; + + /* Unlink m from fl_list_table[i].taken. */ + *m->prevp = m->next; + if (m->next) + m->next->prevp = m->prevp; + + /* Insert m in fl_list_table[i].free. */ + i = GLOBAL_LOCK_INDEX(id); + m->next = fl_list_table[i].free; + fl_list_table[i].free = m; +} + +#endif /* !NSPR_LOCK */ + +JSBool +js_SetupLocks(int listc, int globc) +{ +#ifndef NSPR_LOCK + uint32 i; + + if (global_locks) + return JS_TRUE; +#ifdef DEBUG + if (listc > 10000 || listc < 0) /* listc == fat lock list chunk length */ + printf("Bad number %d in js_SetupLocks()!\n", listc); + if (globc > 100 || globc < 0) /* globc == number of global locks */ + printf("Bad number %d in js_SetupLocks()!\n", listc); +#endif + global_locks_log2 = JS_CeilingLog2(globc); + global_locks_mask = JS_BITMASK(global_locks_log2); + global_lock_count = JS_BIT(global_locks_log2); + global_locks = (PRLock **) malloc(global_lock_count * sizeof(PRLock*)); + if (!global_locks) + return JS_FALSE; + for (i = 0; i < global_lock_count; i++) { + global_locks[i] = PR_NewLock(); + if (!global_locks[i]) { + global_lock_count = i; + js_CleanupLocks(); + return JS_FALSE; + } + } + fl_list_table = (JSFatLockTable *) malloc(i * sizeof(JSFatLockTable)); + if (!fl_list_table) { + js_CleanupLocks(); + return JS_FALSE; + } + fl_list_table_len = global_lock_count; + for (i = 0; i < global_lock_count; i++) + fl_list_table[i].free = fl_list_table[i].taken = NULL; + fl_list_chunk_len = listc; +#endif /* !NSPR_LOCK */ + return JS_TRUE; +} + +void +js_CleanupLocks() +{ +#ifndef NSPR_LOCK + uint32 i; + + if (global_locks) { + for (i = 0; i < global_lock_count; i++) + PR_DestroyLock(global_locks[i]); + free(global_locks); + global_locks = NULL; + global_lock_count = 1; + global_locks_log2 = 0; + global_locks_mask = 0; + } + if (fl_list_table) { + for (i = 0; i < fl_list_table_len; i++) { + DeleteListOfFatlocks(fl_list_table[i].free); + fl_list_table[i].free = NULL; + DeleteListOfFatlocks(fl_list_table[i].taken); + fl_list_table[i].taken = NULL; + } + free(fl_list_table); + fl_list_table = NULL; + fl_list_table_len = 0; + } +#endif /* !NSPR_LOCK */ +} + +void +js_InitContextForLocking(JSContext *cx) +{ + cx->thread = CurrentThreadId(); + JS_ASSERT(Thin_GetWait(cx->thread) == 0); +} + +#ifndef NSPR_LOCK + +/* + * Fast locking and unlocking is implemented by delaying the allocation of a + * system lock (fat lock) until contention. As long as a locking thread A + * runs uncontended, the lock is represented solely by storing A's identity in + * the object being locked. + * + * If another thread B tries to lock the object currently locked by A, B is + * enqueued into a fat lock structure (which might have to be allocated and + * pointed to by the object), and suspended using NSPR conditional variables + * (wait). A wait bit (Bacon bit) is set in the lock word of the object, + * signalling to A that when releasing the lock, B must be dequeued and + * notified. + * + * The basic operation of the locking primitives (js_Lock, js_Unlock, + * js_Enqueue, and js_Dequeue) is compare-and-swap. Hence, when locking into + * the word pointed at by p, compare-and-swap(p, 0, A) success implies that p + * is unlocked. Similarly, when unlocking p, if compare-and-swap(p, A, 0) + * succeeds this implies that p is uncontended (no one is waiting because the + * wait bit is not set). + * + * When dequeueing, the lock is released, and one of the threads suspended on + * the lock is notified. If other threads still are waiting, the wait bit is + * kept (in js_Enqueue), and if not, the fat lock is deallocated. + * + * The functions js_Enqueue, js_Dequeue, js_SuspendThread, and js_ResumeThread + * are serialized using a global lock. For scalability, a hashtable of global + * locks is used, which is indexed modulo the thin lock pointer. + */ + +/* + * Invariants: + * (i) global lock is held + * (ii) fl->susp >= 0 + */ +static int +js_SuspendThread(JSThinLock *tl) +{ + JSFatLock *fl; + PRStatus stat; + + if (tl->fat == NULL) + fl = tl->fat = GetFatlock(tl); + else + fl = tl->fat; + JS_ASSERT(fl->susp >= 0); + fl->susp++; + PR_Lock(fl->slock); + js_UnlockGlobal(tl); + stat = PR_WaitCondVar(fl->svar, PR_INTERVAL_NO_TIMEOUT); + JS_ASSERT(stat != PR_FAILURE); + PR_Unlock(fl->slock); + js_LockGlobal(tl); + fl->susp--; + if (fl->susp == 0) { + PutFatlock(fl, tl); + tl->fat = NULL; + } + return tl->fat == NULL; +} + +/* + * (i) global lock is held + * (ii) fl->susp > 0 + */ +static void +js_ResumeThread(JSThinLock *tl) +{ + JSFatLock *fl = tl->fat; + PRStatus stat; + + JS_ASSERT(fl != NULL); + JS_ASSERT(fl->susp > 0); + PR_Lock(fl->slock); + js_UnlockGlobal(tl); + stat = PR_NotifyCondVar(fl->svar); + JS_ASSERT(stat != PR_FAILURE); + PR_Unlock(fl->slock); +} + +static void +js_Enqueue(JSThinLock *tl, jsword me) +{ + jsword o, n; + + js_LockGlobal(tl); + for (;;) { + o = ReadWord(tl->owner); + n = Thin_SetWait(o); + if (o != 0 && js_CompareAndSwap(&tl->owner, o, n)) { + if (js_SuspendThread(tl)) + me = Thin_RemoveWait(me); + else + me = Thin_SetWait(me); + } + else if (js_CompareAndSwap(&tl->owner, 0, me)) { + js_UnlockGlobal(tl); + return; + } + } +} + +static void +js_Dequeue(JSThinLock *tl) +{ + jsword o; + + js_LockGlobal(tl); + o = ReadWord(tl->owner); + JS_ASSERT(Thin_GetWait(o) != 0); + JS_ASSERT(tl->fat != NULL); + if (!js_CompareAndSwap(&tl->owner, o, 0)) /* release it */ + JS_ASSERT(0); + js_ResumeThread(tl); +} + +JS_INLINE void +js_Lock(JSThinLock *tl, jsword me) +{ + JS_ASSERT(me == CurrentThreadId()); + if (js_CompareAndSwap(&tl->owner, 0, me)) + return; + if (Thin_RemoveWait(ReadWord(tl->owner)) != me) + js_Enqueue(tl, me); +#ifdef DEBUG + else + JS_ASSERT(0); +#endif +} + +JS_INLINE void +js_Unlock(JSThinLock *tl, jsword me) +{ + JS_ASSERT(me == CurrentThreadId()); + if (js_CompareAndSwap(&tl->owner, me, 0)) + return; + if (Thin_RemoveWait(ReadWord(tl->owner)) == me) + js_Dequeue(tl); +#ifdef DEBUG + else + JS_ASSERT(0); +#endif +} + +#endif /* !NSPR_LOCK */ + +void +js_LockRuntime(JSRuntime *rt) +{ + PR_Lock(rt->rtLock); +#ifdef DEBUG + rt->rtLockOwner = CurrentThreadId(); +#endif +} + +void +js_UnlockRuntime(JSRuntime *rt) +{ +#ifdef DEBUG + rt->rtLockOwner = 0; +#endif + PR_Unlock(rt->rtLock); +} + +void +js_LockScope(JSContext *cx, JSScope *scope) +{ + jsword me = cx->thread; + + JS_ASSERT(me == CurrentThreadId()); + JS_ASSERT(scope->ownercx != cx); + if (CX_THREAD_IS_RUNNING_GC(cx)) + return; + if (scope->ownercx && ClaimScope(scope, cx)) + return; + + if (Thin_RemoveWait(ReadWord(scope->lock.owner)) == me) { + JS_ASSERT(scope->u.count > 0); + LOGIT(scope, '+'); + scope->u.count++; + } else { + JSThinLock *tl = &scope->lock; + JS_LOCK0(tl, me); + JS_ASSERT(scope->u.count == 0); + LOGIT(scope, '1'); + scope->u.count = 1; + } +} + +void +js_UnlockScope(JSContext *cx, JSScope *scope) +{ + jsword me = cx->thread; + + /* We hope compilers use me instead of reloading cx->thread in the macro. */ + if (CX_THREAD_IS_RUNNING_GC(cx)) + return; + if (cx->lockedSealedScope == scope) { + cx->lockedSealedScope = NULL; + return; + } + + JS_ASSERT(scope->ownercx == NULL); + JS_ASSERT(scope->u.count > 0); + if (Thin_RemoveWait(ReadWord(scope->lock.owner)) != me) { + JS_ASSERT(0); /* unbalanced unlock */ + return; + } + LOGIT(scope, '-'); + if (--scope->u.count == 0) { + JSThinLock *tl = &scope->lock; + JS_UNLOCK0(tl, me); + } +} + +/* + * NB: oldscope may be null if our caller is js_GetMutableScope and it just + * dropped the last reference to oldscope. + */ +void +js_TransferScopeLock(JSContext *cx, JSScope *oldscope, JSScope *newscope) +{ + jsword me; + JSThinLock *tl; + + JS_ASSERT(JS_IS_SCOPE_LOCKED(cx, newscope)); + + /* + * If the last reference to oldscope went away, newscope needs no lock + * state update. + */ + if (!oldscope) + return; + JS_ASSERT(JS_IS_SCOPE_LOCKED(cx, oldscope)); + + /* + * Special case in js_LockScope and js_UnlockScope for the GC calling + * code that locks, unlocks, or mutates. Nothing to do in these cases, + * because scope and newscope were "locked" by the GC thread, so neither + * was actually locked. + */ + if (CX_THREAD_IS_RUNNING_GC(cx)) + return; + + /* + * Special case in js_LockObj and js_UnlockScope for locking the sealed + * scope of an object that owns that scope (the prototype or mutated obj + * for which OBJ_SCOPE(obj)->object == obj), and unlocking it. + */ + JS_ASSERT(cx->lockedSealedScope != newscope); + if (cx->lockedSealedScope == oldscope) { + JS_ASSERT(newscope->ownercx == cx || + (!newscope->ownercx && newscope->u.count == 1)); + cx->lockedSealedScope = NULL; + return; + } + + /* + * If oldscope is single-threaded, there's nothing to do. + */ + if (oldscope->ownercx) { + JS_ASSERT(oldscope->ownercx == cx); + JS_ASSERT(newscope->ownercx == cx || + (!newscope->ownercx && newscope->u.count == 1)); + return; + } + + /* + * We transfer oldscope->u.count only if newscope is not single-threaded. + * Flow unwinds from here through some number of JS_UNLOCK_SCOPE and/or + * JS_UNLOCK_OBJ macro calls, which will decrement newscope->u.count only + * if they find newscope->ownercx != cx. + */ + if (newscope->ownercx != cx) { + JS_ASSERT(!newscope->ownercx); + newscope->u.count = oldscope->u.count; + } + + /* + * Reset oldscope's lock state so that it is completely unlocked. + */ + LOGIT(oldscope, '0'); + oldscope->u.count = 0; + tl = &oldscope->lock; + me = cx->thread; + JS_UNLOCK0(tl, me); +} + +void +js_LockObj(JSContext *cx, JSObject *obj) +{ + JSScope *scope; + + JS_ASSERT(OBJ_IS_NATIVE(obj)); + for (;;) { + scope = OBJ_SCOPE(obj); + if (SCOPE_IS_SEALED(scope) && scope->object == obj && + !cx->lockedSealedScope) { + cx->lockedSealedScope = scope; + return; + } + + js_LockScope(cx, scope); + + /* If obj still has this scope, we're done. */ + if (scope == OBJ_SCOPE(obj)) + return; + + /* Lost a race with a mutator; retry with obj's new scope. */ + js_UnlockScope(cx, scope); + } +} + +void +js_UnlockObj(JSContext *cx, JSObject *obj) +{ + JS_ASSERT(OBJ_IS_NATIVE(obj)); + js_UnlockScope(cx, OBJ_SCOPE(obj)); +} + +#ifdef DEBUG + +JSBool +js_IsRuntimeLocked(JSRuntime *rt) +{ + return CurrentThreadId() == rt->rtLockOwner; +} + +JSBool +js_IsObjLocked(JSContext *cx, JSObject *obj) +{ + JSScope *scope = OBJ_SCOPE(obj); + + return MAP_IS_NATIVE(&scope->map) && js_IsScopeLocked(cx, scope); +} + +JSBool +js_IsScopeLocked(JSContext *cx, JSScope *scope) +{ + /* Special case: the GC locking any object's scope, see js_LockScope. */ + if (CX_THREAD_IS_RUNNING_GC(cx)) + return JS_TRUE; + + /* Special case: locked object owning a sealed scope, see js_LockObj. */ + if (cx->lockedSealedScope == scope) + return JS_TRUE; + + /* + * General case: the scope is either exclusively owned (by cx), or it has + * a thin or fat lock to cope with shared (concurrent) ownership. + */ + if (scope->ownercx) { + JS_ASSERT(scope->ownercx == cx); + return JS_TRUE; + } + return CurrentThreadId() == Thin_RemoveWait(ReadWord(scope->lock.owner)); +} + +#endif /* DEBUG */ +#endif /* JS_THREADSAFE */ diff --git a/src/dom/js/jslock.h b/src/dom/js/jslock.h new file mode 100644 index 000000000..9ece59c9b --- /dev/null +++ b/src/dom/js/jslock.h @@ -0,0 +1,289 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ +#ifndef jslock_h__ +#define jslock_h__ + +#ifdef JS_THREADSAFE + +#include "jstypes.h" +#include "pratom.h" +#include "prlock.h" +#include "prcvar.h" + +#include "jsprvtd.h" /* for JSScope, etc. */ +#include "jspubtd.h" /* for JSRuntime, etc. */ + +#define Thin_GetWait(W) ((jsword)(W) & 0x1) +#define Thin_SetWait(W) ((jsword)(W) | 0x1) +#define Thin_RemoveWait(W) ((jsword)(W) & ~0x1) + +typedef struct JSFatLock JSFatLock; + +struct JSFatLock { + int susp; + PRLock *slock; + PRCondVar *svar; + JSFatLock *next; + JSFatLock **prevp; +}; + +typedef struct JSThinLock { + jsword owner; + JSFatLock *fat; +} JSThinLock; + +typedef PRLock JSLock; + +typedef struct JSFatLockTable { + JSFatLock *free; + JSFatLock *taken; +} JSFatLockTable; + +/* + * Atomic increment and decrement for a reference counter, given jsrefcount *p. + * NB: jsrefcount is int32, aka PRInt32, so that pratom.h functions work. + */ +#define JS_ATOMIC_INCREMENT(p) PR_AtomicIncrement((PRInt32 *)(p)) +#define JS_ATOMIC_DECREMENT(p) PR_AtomicDecrement((PRInt32 *)(p)) +#define JS_ATOMIC_ADD(p,v) PR_AtomicAdd((PRInt32 *)(p), (PRInt32)(v)) + +#define CurrentThreadId() (jsword)PR_GetCurrentThread() +#define JS_CurrentThreadId() js_CurrentThreadId() +#define JS_NEW_LOCK() PR_NewLock() +#define JS_DESTROY_LOCK(l) PR_DestroyLock(l) +#define JS_ACQUIRE_LOCK(l) PR_Lock(l) +#define JS_RELEASE_LOCK(l) PR_Unlock(l) +#define JS_LOCK0(P,M) js_Lock(P,M) +#define JS_UNLOCK0(P,M) js_Unlock(P,M) + +#define JS_NEW_CONDVAR(l) PR_NewCondVar(l) +#define JS_DESTROY_CONDVAR(cv) PR_DestroyCondVar(cv) +#define JS_WAIT_CONDVAR(cv,to) PR_WaitCondVar(cv,to) +#define JS_NO_TIMEOUT PR_INTERVAL_NO_TIMEOUT +#define JS_NOTIFY_CONDVAR(cv) PR_NotifyCondVar(cv) +#define JS_NOTIFY_ALL_CONDVAR(cv) PR_NotifyAllCondVar(cv) + +/* + * Include jsscope.h so JS_LOCK_OBJ macro callers don't have to include it. + * Since there is a JSThinLock member in JSScope, we can't nest this include + * much earlier (see JSThinLock's typedef, above). Yes, that means there is + * an #include cycle between jslock.h and jsscope.h: moderate-sized XXX here, + * to be fixed by moving JS_LOCK_SCOPE to jsscope.h, JS_LOCK_OBJ to jsobj.h, + * and so on. + * + * We also need jsscope.h #ifdef DEBUG for SET_OBJ_INFO and SET_SCOPE_INFO, + * but we do not want any nested includes that depend on DEBUG. Those lead + * to build bustage when someone makes a change that depends in a subtle way + * on jsscope.h being included directly or indirectly, but does not test by + * building optimized as well as DEBUG. + */ +#include "jsscope.h" + +#ifdef DEBUG + +#define SET_OBJ_INFO(obj_,file_,line_) \ + SET_SCOPE_INFO(OBJ_SCOPE(obj_),file_,line_) + +#define SET_SCOPE_INFO(scope_,file_,line_) \ + ((scope_)->ownercx ? (void)0 : \ + (JS_ASSERT((0 < (scope_)->u.count && (scope_)->u.count <= 4) || \ + SCOPE_IS_SEALED(scope_)), \ + (void)((scope_)->file[(scope_)->u.count-1] = (file_), \ + (scope_)->line[(scope_)->u.count-1] = (line_)))) +#endif /* DEBUG */ + +#define JS_LOCK_RUNTIME(rt) js_LockRuntime(rt) +#define JS_UNLOCK_RUNTIME(rt) js_UnlockRuntime(rt) + +/* + * NB: The JS_LOCK_OBJ and JS_UNLOCK_OBJ macros work *only* on native objects + * (objects for which OBJ_IS_NATIVE returns true). All uses of these macros in + * the engine are predicated on OBJ_IS_NATIVE or equivalent checks. These uses + * are for optimizations above the JSObjectOps layer, under which object locks + * normally hide. + */ +#define JS_LOCK_OBJ(cx,obj) ((OBJ_SCOPE(obj)->ownercx == (cx)) \ + ? (void)0 \ + : (js_LockObj(cx, obj), \ + SET_OBJ_INFO(obj,__FILE__,__LINE__))) +#define JS_UNLOCK_OBJ(cx,obj) ((OBJ_SCOPE(obj)->ownercx == (cx)) \ + ? (void)0 : js_UnlockObj(cx, obj)) + +#define JS_LOCK_SCOPE(cx,scope) ((scope)->ownercx == (cx) ? (void)0 : \ + (js_LockScope(cx, scope), \ + SET_SCOPE_INFO(scope,__FILE__,__LINE__))) +#define JS_UNLOCK_SCOPE(cx,scope) ((scope)->ownercx == (cx) ? (void)0 : \ + js_UnlockScope(cx, scope)) +#define JS_TRANSFER_SCOPE_LOCK(cx, scope, newscope) \ + js_TransferScopeLock(cx, scope, newscope) + +extern jsword js_CurrentThreadId(); +extern void js_LockRuntime(JSRuntime *rt); +extern void js_UnlockRuntime(JSRuntime *rt); +extern void js_LockObj(JSContext *cx, JSObject *obj); +extern void js_UnlockObj(JSContext *cx, JSObject *obj); +extern void js_LockScope(JSContext *cx, JSScope *scope); +extern void js_UnlockScope(JSContext *cx, JSScope *scope); +extern int js_SetupLocks(int,int); +extern void js_CleanupLocks(); +extern void js_InitContextForLocking(JSContext *); +extern void js_TransferScopeLock(JSContext *, JSScope *, JSScope *); +extern JS_FRIEND_API(jsval) +js_GetSlotThreadSafe(JSContext *, JSObject *, uint32); +extern void js_SetSlotThreadSafe(JSContext *, JSObject *, uint32, jsval); +extern void js_InitLock(JSThinLock *); +extern void js_FinishLock(JSThinLock *); +extern void js_FinishSharingScope(JSRuntime *rt, JSScope *scope); + +#ifdef DEBUG + +#define JS_IS_RUNTIME_LOCKED(rt) js_IsRuntimeLocked(rt) +#define JS_IS_OBJ_LOCKED(cx,obj) js_IsObjLocked(cx,obj) +#define JS_IS_SCOPE_LOCKED(cx,scope) js_IsScopeLocked(cx,scope) + +extern JSBool js_IsRuntimeLocked(JSRuntime *rt); +extern JSBool js_IsObjLocked(JSContext *cx, JSObject *obj); +extern JSBool js_IsScopeLocked(JSContext *cx, JSScope *scope); + +#else + +#define JS_IS_RUNTIME_LOCKED(rt) 0 +#define JS_IS_OBJ_LOCKED(cx,obj) 1 +#define JS_IS_SCOPE_LOCKED(cx,scope) 1 + +#endif /* DEBUG */ + +#define JS_LOCK_OBJ_VOID(cx, obj, e) \ + JS_BEGIN_MACRO \ + JS_LOCK_OBJ(cx, obj); \ + e; \ + JS_UNLOCK_OBJ(cx, obj); \ + JS_END_MACRO + +#define JS_LOCK_VOID(cx, e) \ + JS_BEGIN_MACRO \ + JSRuntime *_rt = (cx)->runtime; \ + JS_LOCK_RUNTIME_VOID(_rt, e); \ + JS_END_MACRO + +#if defined(JS_USE_ONLY_NSPR_LOCKS) || \ + !( (defined(_WIN32) && defined(_M_IX86)) || \ + (defined(__GNUC__) && defined(__i386__)) || \ + (defined(SOLARIS) && defined(sparc) && defined(ULTRA_SPARC)) || \ + defined(AIX) ) + +#define NSPR_LOCK 1 + +#undef JS_LOCK0 +#undef JS_UNLOCK0 +#define JS_LOCK0(P,M) (JS_ACQUIRE_LOCK(((JSLock*)(P)->fat)), (P)->owner = (M)) +#define JS_UNLOCK0(P,M) ((P)->owner = 0, JS_RELEASE_LOCK(((JSLock*)(P)->fat))) + +#else /* arch-tests */ + +#undef NSPR_LOCK + +extern JS_INLINE void js_Lock(JSThinLock *tl, jsword me); +extern JS_INLINE void js_Unlock(JSThinLock *tl, jsword me); + +#endif /* arch-tests */ + +#else /* !JS_THREADSAFE */ + +#define JS_ATOMIC_INCREMENT(p) (++*(p)) +#define JS_ATOMIC_DECREMENT(p) (--*(p)) +#define JS_ATOMIC_ADD(p,v) (*(p) += (v)) + +#define JS_CurrentThreadId() 0 +#define JS_NEW_LOCK() NULL +#define JS_DESTROY_LOCK(l) ((void)0) +#define JS_ACQUIRE_LOCK(l) ((void)0) +#define JS_RELEASE_LOCK(l) ((void)0) +#define JS_LOCK0(P,M) ((void)0) +#define JS_UNLOCK0(P,M) ((void)0) + +#define JS_NEW_CONDVAR(l) NULL +#define JS_DESTROY_CONDVAR(cv) ((void)0) +#define JS_WAIT_CONDVAR(cv,to) ((void)0) +#define JS_NOTIFY_CONDVAR(cv) ((void)0) +#define JS_NOTIFY_ALL_CONDVAR(cv) ((void)0) + +#define JS_LOCK_RUNTIME(rt) ((void)0) +#define JS_UNLOCK_RUNTIME(rt) ((void)0) +#define JS_LOCK_OBJ(cx,obj) ((void)0) +#define JS_UNLOCK_OBJ(cx,obj) ((void)0) +#define JS_LOCK_OBJ_VOID(cx,obj,e) (e) +#define JS_LOCK_SCOPE(cx,scope) ((void)0) +#define JS_UNLOCK_SCOPE(cx,scope) ((void)0) +#define JS_TRANSFER_SCOPE_LOCK(c,o,n) ((void)0) + +#define JS_IS_RUNTIME_LOCKED(rt) 1 +#define JS_IS_OBJ_LOCKED(cx,obj) 1 +#define JS_IS_SCOPE_LOCKED(cx,scope) 1 +#define JS_LOCK_VOID(cx, e) JS_LOCK_RUNTIME_VOID((cx)->runtime, e) + +#endif /* !JS_THREADSAFE */ + +#define JS_LOCK_RUNTIME_VOID(rt,e) \ + JS_BEGIN_MACRO \ + JS_LOCK_RUNTIME(rt); \ + e; \ + JS_UNLOCK_RUNTIME(rt); \ + JS_END_MACRO + +#define JS_LOCK_GC(rt) JS_ACQUIRE_LOCK((rt)->gcLock) +#define JS_UNLOCK_GC(rt) JS_RELEASE_LOCK((rt)->gcLock) +#define JS_LOCK_GC_VOID(rt,e) (JS_LOCK_GC(rt), (e), JS_UNLOCK_GC(rt)) +#define JS_AWAIT_GC_DONE(rt) JS_WAIT_CONDVAR((rt)->gcDone, JS_NO_TIMEOUT) +#define JS_NOTIFY_GC_DONE(rt) JS_NOTIFY_ALL_CONDVAR((rt)->gcDone) +#define JS_AWAIT_REQUEST_DONE(rt) JS_WAIT_CONDVAR((rt)->requestDone, \ + JS_NO_TIMEOUT) +#define JS_NOTIFY_REQUEST_DONE(rt) JS_NOTIFY_CONDVAR((rt)->requestDone) + +#define JS_LOCK(P,CX) JS_LOCK0(P,(CX)->thread) +#define JS_UNLOCK(P,CX) JS_UNLOCK0(P,(CX)->thread) + +#ifndef SET_OBJ_INFO +#define SET_OBJ_INFO(obj,f,l) ((void)0) +#endif +#ifndef SET_SCOPE_INFO +#define SET_SCOPE_INFO(scope,f,l) ((void)0) +#endif + +#endif /* jslock_h___ */ diff --git a/src/dom/js/jslocko.asm b/src/dom/js/jslocko.asm new file mode 100644 index 000000000..2589bb7f9 --- /dev/null +++ b/src/dom/js/jslocko.asm @@ -0,0 +1,59 @@ +COMMENT | -*- Mode: asm; tab-width: 8; c-basic-offset: 4 -*- +***** BEGIN LICENSE BLOCK ***** +Version: MPL 1.1/GPL 2.0/LGPL 2.1 + +The contents of this file are subject to the Mozilla Public License Version +1.1 (the "License"); you may not use this file except in compliance with +the License. You may obtain a copy of the License at +http://www.mozilla.org/MPL/ + +Software distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +for the specific language governing rights and limitations under the +License. + +The Original Code is an OS/2 implementation of js_CompareAndSwap in assembly + +The Initial Developer of the Original Code is IBM Corporation. +Portions created by the Initial Developer are Copyright (C) 2001 +the Initial Developer. All Rights Reserved. + +Contributor(s): + +Alternatively, the contents of this file may be used under the terms of +either the GNU General Public License Version 2 or later (the "GPL"), or +the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), +in which case the provisions of the GPL or the LGPL are applicable instead +of those above. If you wish to allow use of your version of this file only +under the terms of either the GPL or the LGPL, and not to allow others to +use your version of this file under the terms of the MPL, indicate your +decision by deleting the provisions above and replace them with the notice +and other provisions required by the GPL or the LGPL. If you do not delete +the provisions above, a recipient may use your version of this file under +the terms of any one of the MPL, the GPL or the LGPL. + +***** END LICENSE BLOCK ***** + | + + .486P + .MODEL FLAT, OPTLINK + .STACK + + .CODE + +;;;--------------------------------------------------------------------- +;;; int _Optlink js_CompareAndSwap(jsword *w, jsword ov, jsword nv) +;;;--------------------------------------------------------------------- +js_CompareAndSwap PROC OPTLINK EXPORT + push ebx + mov ebx, eax + mov eax, edx + mov edx, ebx + lock cmpxchg [ebx], ecx + sete al + and eax, 1h + pop ebx + ret +js_CompareAndSwap endp + + END diff --git a/src/dom/js/jslog2.c b/src/dom/js/jslog2.c new file mode 100644 index 000000000..113c276d0 --- /dev/null +++ b/src/dom/js/jslog2.c @@ -0,0 +1,83 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "jsstddef.h" +#include "jsbit.h" + +/* +** Compute the log of the least power of 2 greater than or equal to n +*/ +JS_PUBLIC_API(JSIntn) JS_CeilingLog2(JSUint32 n) +{ + JSIntn log2 = 0; + + if (n & (n-1)) + log2++; + if (n >> 16) + log2 += 16, n >>= 16; + if (n >> 8) + log2 += 8, n >>= 8; + if (n >> 4) + log2 += 4, n >>= 4; + if (n >> 2) + log2 += 2, n >>= 2; + if (n >> 1) + log2++; + return log2; +} + +/* +** Compute the log of the greatest power of 2 less than or equal to n. +** This really just finds the highest set bit in the word. +*/ +JS_PUBLIC_API(JSIntn) JS_FloorLog2(JSUint32 n) +{ + JSIntn log2 = 0; + + if (n >> 16) + log2 += 16, n >>= 16; + if (n >> 8) + log2 += 8, n >>= 8; + if (n >> 4) + log2 += 4, n >>= 4; + if (n >> 2) + log2 += 2, n >>= 2; + if (n >> 1) + log2++; + return log2; +} diff --git a/src/dom/js/jslong.c b/src/dom/js/jslong.c new file mode 100644 index 000000000..76259e502 --- /dev/null +++ b/src/dom/js/jslong.c @@ -0,0 +1,281 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "jsstddef.h" +#include "jstypes.h" +#include "jslong.h" + +static JSInt64 ll_zero = JSLL_INIT( 0x00000000,0x00000000 ); +static JSInt64 ll_maxint = JSLL_INIT( 0x7fffffff, 0xffffffff ); +static JSInt64 ll_minint = JSLL_INIT( 0x80000000, 0x00000000 ); + +#ifdef HAVE_WATCOM_BUG_2 +JSInt64 __pascal __loadds __export + JSLL_Zero(void) { return ll_zero; } +JSInt64 __pascal __loadds __export + JSLL_MaxInt(void) { return ll_maxint; } +JSInt64 __pascal __loadds __export + JSLL_MinInt(void) { return ll_minint; } +#else +JS_PUBLIC_API(JSInt64) JSLL_Zero(void) { return ll_zero; } +JS_PUBLIC_API(JSInt64) JSLL_MaxInt(void) { return ll_maxint; } +JS_PUBLIC_API(JSInt64) JSLL_MinInt(void) { return ll_minint; } +#endif + +#ifndef JS_HAVE_LONG_LONG +/* +** Divide 64-bit a by 32-bit b, which must be normalized so its high bit is 1. +*/ +static void norm_udivmod32(JSUint32 *qp, JSUint32 *rp, JSUint64 a, JSUint32 b) +{ + JSUint32 d1, d0, q1, q0; + JSUint32 r1, r0, m; + + d1 = jshi16(b); + d0 = jslo16(b); + r1 = a.hi % d1; + q1 = a.hi / d1; + m = q1 * d0; + r1 = (r1 << 16) | jshi16(a.lo); + if (r1 < m) { + q1--, r1 += b; + if (r1 >= b /* i.e., we didn't get a carry when adding to r1 */ + && r1 < m) { + q1--, r1 += b; + } + } + r1 -= m; + r0 = r1 % d1; + q0 = r1 / d1; + m = q0 * d0; + r0 = (r0 << 16) | jslo16(a.lo); + if (r0 < m) { + q0--, r0 += b; + if (r0 >= b + && r0 < m) { + q0--, r0 += b; + } + } + *qp = (q1 << 16) | q0; + *rp = r0 - m; +} + +static JSUint32 CountLeadingZeros(JSUint32 a) +{ + JSUint32 t; + JSUint32 r = 32; + + if ((t = a >> 16) != 0) + r -= 16, a = t; + if ((t = a >> 8) != 0) + r -= 8, a = t; + if ((t = a >> 4) != 0) + r -= 4, a = t; + if ((t = a >> 2) != 0) + r -= 2, a = t; + if ((t = a >> 1) != 0) + r -= 1, a = t; + if (a & 1) + r--; + return r; +} + +JS_PUBLIC_API(void) jsll_udivmod(JSUint64 *qp, JSUint64 *rp, JSUint64 a, JSUint64 b) +{ + JSUint32 n0, n1, n2; + JSUint32 q0, q1; + JSUint32 rsh, lsh; + + n0 = a.lo; + n1 = a.hi; + + if (b.hi == 0) { + if (b.lo > n1) { + /* (0 q0) = (n1 n0) / (0 D0) */ + + lsh = CountLeadingZeros(b.lo); + + if (lsh) { + /* + * Normalize, i.e. make the most significant bit of the + * denominator be set. + */ + b.lo = b.lo << lsh; + n1 = (n1 << lsh) | (n0 >> (32 - lsh)); + n0 = n0 << lsh; + } + + a.lo = n0, a.hi = n1; + norm_udivmod32(&q0, &n0, a, b.lo); + q1 = 0; + + /* remainder is in n0 >> lsh */ + } else { + /* (q1 q0) = (n1 n0) / (0 d0) */ + + if (b.lo == 0) /* user wants to divide by zero! */ + b.lo = 1 / b.lo; /* so go ahead and crash */ + + lsh = CountLeadingZeros(b.lo); + + if (lsh == 0) { + /* + * From (n1 >= b.lo) + * && (the most significant bit of b.lo is set), + * conclude that + * (the most significant bit of n1 is set) + * && (the leading quotient digit q1 = 1). + * + * This special case is necessary, not an optimization + * (Shifts counts of 32 are undefined). + */ + n1 -= b.lo; + q1 = 1; + } else { + /* + * Normalize. + */ + rsh = 32 - lsh; + + b.lo = b.lo << lsh; + n2 = n1 >> rsh; + n1 = (n1 << lsh) | (n0 >> rsh); + n0 = n0 << lsh; + + a.lo = n1, a.hi = n2; + norm_udivmod32(&q1, &n1, a, b.lo); + } + + /* n1 != b.lo... */ + + a.lo = n0, a.hi = n1; + norm_udivmod32(&q0, &n0, a, b.lo); + + /* remainder in n0 >> lsh */ + } + + if (rp) { + rp->lo = n0 >> lsh; + rp->hi = 0; + } + } else { + if (b.hi > n1) { + /* (0 0) = (n1 n0) / (D1 d0) */ + + q0 = 0; + q1 = 0; + + /* remainder in (n1 n0) */ + if (rp) { + rp->lo = n0; + rp->hi = n1; + } + } else { + /* (0 q0) = (n1 n0) / (d1 d0) */ + + lsh = CountLeadingZeros(b.hi); + if (lsh == 0) { + /* + * From (n1 >= b.hi) + * && (the most significant bit of b.hi is set), + * conclude that + * (the most significant bit of n1 is set) + * && (the quotient digit q0 = 0 or 1). + * + * This special case is necessary, not an optimization. + */ + + /* + * The condition on the next line takes advantage of that + * n1 >= b.hi (true due to control flow). + */ + if (n1 > b.hi || n0 >= b.lo) { + q0 = 1; + a.lo = n0, a.hi = n1; + JSLL_SUB(a, a, b); + } else { + q0 = 0; + } + q1 = 0; + + if (rp) { + rp->lo = n0; + rp->hi = n1; + } + } else { + JSInt64 m; + + /* + * Normalize. + */ + rsh = 32 - lsh; + + b.hi = (b.hi << lsh) | (b.lo >> rsh); + b.lo = b.lo << lsh; + n2 = n1 >> rsh; + n1 = (n1 << lsh) | (n0 >> rsh); + n0 = n0 << lsh; + + a.lo = n1, a.hi = n2; + norm_udivmod32(&q0, &n1, a, b.hi); + JSLL_MUL32(m, q0, b.lo); + + if ((m.hi > n1) || ((m.hi == n1) && (m.lo > n0))) { + q0--; + JSLL_SUB(m, m, b); + } + + q1 = 0; + + /* Remainder is ((n1 n0) - (m1 m0)) >> lsh */ + if (rp) { + a.lo = n0, a.hi = n1; + JSLL_SUB(a, a, m); + rp->lo = (a.hi << rsh) | (a.lo >> lsh); + rp->hi = a.hi >> lsh; + } + } + } + } + + if (qp) { + qp->lo = q0; + qp->hi = q1; + } +} +#endif /* !JS_HAVE_LONG_LONG */ diff --git a/src/dom/js/jslong.h b/src/dom/js/jslong.h new file mode 100644 index 000000000..bde8bfbbf --- /dev/null +++ b/src/dom/js/jslong.h @@ -0,0 +1,437 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* +** File: jslong.h +** Description: Portable access to 64 bit numerics +** +** Long-long (64-bit signed integer type) support. Some C compilers +** don't support 64 bit integers yet, so we use these macros to +** support both machines that do and don't. +**/ +#ifndef jslong_h___ +#define jslong_h___ + +#include "jstypes.h" + +JS_BEGIN_EXTERN_C + +/*********************************************************************** +** DEFINES: JSLL_MaxInt +** JSLL_MinInt +** JSLL_Zero +** DESCRIPTION: +** Various interesting constants and static variable +** initializer +***********************************************************************/ +#ifdef HAVE_WATCOM_BUG_2 +JSInt64 __pascal __loadds __export + JSLL_MaxInt(void); +JSInt64 __pascal __loadds __export + JSLL_MinInt(void); +JSInt64 __pascal __loadds __export + JSLL_Zero(void); +#else +extern JS_PUBLIC_API(JSInt64) JSLL_MaxInt(void); +extern JS_PUBLIC_API(JSInt64) JSLL_MinInt(void); +extern JS_PUBLIC_API(JSInt64) JSLL_Zero(void); +#endif + +#define JSLL_MAXINT JSLL_MaxInt() +#define JSLL_MININT JSLL_MinInt() +#define JSLL_ZERO JSLL_Zero() + +#ifdef JS_HAVE_LONG_LONG + +#if JS_BYTES_PER_LONG == 8 +#define JSLL_INIT(hi, lo) ((hi ## L << 32) + lo ## L) +#elif (defined(WIN32) || defined(WIN16)) && !defined(__GNUC__) +#define JSLL_INIT(hi, lo) ((hi ## i64 << 32) + lo ## i64) +#else +#define JSLL_INIT(hi, lo) ((hi ## LL << 32) + lo ## LL) +#endif + +/*********************************************************************** +** MACROS: JSLL_* +** DESCRIPTION: +** The following macros define portable access to the 64 bit +** math facilities. +** +***********************************************************************/ + +/*********************************************************************** +** MACROS: JSLL_ +** +** JSLL_IS_ZERO Test for zero +** JSLL_EQ Test for equality +** JSLL_NE Test for inequality +** JSLL_GE_ZERO Test for zero or positive +** JSLL_CMP Compare two values +***********************************************************************/ +#define JSLL_IS_ZERO(a) ((a) == 0) +#define JSLL_EQ(a, b) ((a) == (b)) +#define JSLL_NE(a, b) ((a) != (b)) +#define JSLL_GE_ZERO(a) ((a) >= 0) +#define JSLL_CMP(a, op, b) ((JSInt64)(a) op (JSInt64)(b)) +#define JSLL_UCMP(a, op, b) ((JSUint64)(a) op (JSUint64)(b)) + +/*********************************************************************** +** MACROS: JSLL_ +** +** JSLL_AND Logical and +** JSLL_OR Logical or +** JSLL_XOR Logical exclusion +** JSLL_OR2 A disgusting deviation +** JSLL_NOT Negation (one's compliment) +***********************************************************************/ +#define JSLL_AND(r, a, b) ((r) = (a) & (b)) +#define JSLL_OR(r, a, b) ((r) = (a) | (b)) +#define JSLL_XOR(r, a, b) ((r) = (a) ^ (b)) +#define JSLL_OR2(r, a) ((r) = (r) | (a)) +#define JSLL_NOT(r, a) ((r) = ~(a)) + +/*********************************************************************** +** MACROS: JSLL_ +** +** JSLL_NEG Negation (two's compliment) +** JSLL_ADD Summation (two's compliment) +** JSLL_SUB Difference (two's compliment) +***********************************************************************/ +#define JSLL_NEG(r, a) ((r) = -(a)) +#define JSLL_ADD(r, a, b) ((r) = (a) + (b)) +#define JSLL_SUB(r, a, b) ((r) = (a) - (b)) + +/*********************************************************************** +** MACROS: JSLL_ +** +** JSLL_MUL Product (two's compliment) +** JSLL_DIV Quotient (two's compliment) +** JSLL_MOD Modulus (two's compliment) +***********************************************************************/ +#define JSLL_MUL(r, a, b) ((r) = (a) * (b)) +#define JSLL_DIV(r, a, b) ((r) = (a) / (b)) +#define JSLL_MOD(r, a, b) ((r) = (a) % (b)) + +/*********************************************************************** +** MACROS: JSLL_ +** +** JSLL_SHL Shift left [0..64] bits +** JSLL_SHR Shift right [0..64] bits with sign extension +** JSLL_USHR Unsigned shift right [0..64] bits +** JSLL_ISHL Signed shift left [0..64] bits +***********************************************************************/ +#define JSLL_SHL(r, a, b) ((r) = (JSInt64)(a) << (b)) +#define JSLL_SHR(r, a, b) ((r) = (JSInt64)(a) >> (b)) +#define JSLL_USHR(r, a, b) ((r) = (JSUint64)(a) >> (b)) +#define JSLL_ISHL(r, a, b) ((r) = (JSInt64)(a) << (b)) + +/*********************************************************************** +** MACROS: JSLL_ +** +** JSLL_L2I Convert to signed 32 bit +** JSLL_L2UI Convert to unsigned 32 bit +** JSLL_L2F Convert to floating point +** JSLL_L2D Convert to floating point +** JSLL_I2L Convert signed to 64 bit +** JSLL_UI2L Convert unsigned to 64 bit +** JSLL_F2L Convert float to 64 bit +** JSLL_D2L Convert float to 64 bit +***********************************************************************/ +#define JSLL_L2I(i, l) ((i) = (JSInt32)(l)) +#define JSLL_L2UI(ui, l) ((ui) = (JSUint32)(l)) +#define JSLL_L2F(f, l) ((f) = (JSFloat64)(l)) +#define JSLL_L2D(d, l) ((d) = (JSFloat64)(l)) + +#define JSLL_I2L(l, i) ((l) = (JSInt64)(i)) +#define JSLL_UI2L(l, ui) ((l) = (JSInt64)(ui)) +#define JSLL_F2L(l, f) ((l) = (JSInt64)(f)) +#define JSLL_D2L(l, d) ((l) = (JSInt64)(d)) + +/*********************************************************************** +** MACROS: JSLL_UDIVMOD +** DESCRIPTION: +** Produce both a quotient and a remainder given an unsigned +** INPUTS: JSUint64 a: The dividend of the operation +** JSUint64 b: The quotient of the operation +** OUTPUTS: JSUint64 *qp: pointer to quotient +** JSUint64 *rp: pointer to remainder +***********************************************************************/ +#define JSLL_UDIVMOD(qp, rp, a, b) \ + (*(qp) = ((JSUint64)(a) / (b)), \ + *(rp) = ((JSUint64)(a) % (b))) + +#else /* !JS_HAVE_LONG_LONG */ + +#ifdef IS_LITTLE_ENDIAN +#define JSLL_INIT(hi, lo) {JS_INT32(lo), JS_INT32(hi)} +#else +#define JSLL_INIT(hi, lo) {JS_INT32(hi), JS_INT32(lo)} +#endif + +#define JSLL_IS_ZERO(a) (((a).hi == 0) && ((a).lo == 0)) +#define JSLL_EQ(a, b) (((a).hi == (b).hi) && ((a).lo == (b).lo)) +#define JSLL_NE(a, b) (((a).hi != (b).hi) || ((a).lo != (b).lo)) +#define JSLL_GE_ZERO(a) (((a).hi >> 31) == 0) + +#ifdef DEBUG +#define JSLL_CMP(a, op, b) (JS_ASSERT((#op)[1] != '='), JSLL_REAL_CMP(a, op, b)) +#define JSLL_UCMP(a, op, b) (JS_ASSERT((#op)[1] != '='), JSLL_REAL_UCMP(a, op, b)) +#else +#define JSLL_CMP(a, op, b) JSLL_REAL_CMP(a, op, b) +#define JSLL_UCMP(a, op, b) JSLL_REAL_UCMP(a, op, b) +#endif + +#define JSLL_REAL_CMP(a,op,b) (((JSInt32)(a).hi op (JSInt32)(b).hi) || \ + (((a).hi == (b).hi) && ((a).lo op (b).lo))) +#define JSLL_REAL_UCMP(a,op,b) (((a).hi op (b).hi) || \ + (((a).hi == (b).hi) && ((a).lo op (b).lo))) + +#define JSLL_AND(r, a, b) ((r).lo = (a).lo & (b).lo, \ + (r).hi = (a).hi & (b).hi) +#define JSLL_OR(r, a, b) ((r).lo = (a).lo | (b).lo, \ + (r).hi = (a).hi | (b).hi) +#define JSLL_XOR(r, a, b) ((r).lo = (a).lo ^ (b).lo, \ + (r).hi = (a).hi ^ (b).hi) +#define JSLL_OR2(r, a) ((r).lo = (r).lo | (a).lo, \ + (r).hi = (r).hi | (a).hi) +#define JSLL_NOT(r, a) ((r).lo = ~(a).lo, \ + (r).hi = ~(a).hi) + +#define JSLL_NEG(r, a) ((r).lo = -(JSInt32)(a).lo, \ + (r).hi = -(JSInt32)(a).hi - ((r).lo != 0)) +#define JSLL_ADD(r, a, b) { \ + JSInt64 _a, _b; \ + _a = a; _b = b; \ + (r).lo = _a.lo + _b.lo; \ + (r).hi = _a.hi + _b.hi + ((r).lo < _b.lo); \ +} + +#define JSLL_SUB(r, a, b) { \ + JSInt64 _a, _b; \ + _a = a; _b = b; \ + (r).lo = _a.lo - _b.lo; \ + (r).hi = _a.hi - _b.hi - (_a.lo < _b.lo); \ +} + +#define JSLL_MUL(r, a, b) { \ + JSInt64 _a, _b; \ + _a = a; _b = b; \ + JSLL_MUL32(r, _a.lo, _b.lo); \ + (r).hi += _a.hi * _b.lo + _a.lo * _b.hi; \ +} + +#define jslo16(a) ((a) & JS_BITMASK(16)) +#define jshi16(a) ((a) >> 16) + +#define JSLL_MUL32(r, a, b) { \ + JSUint32 _a1, _a0, _b1, _b0, _y0, _y1, _y2, _y3; \ + _a1 = jshi16(a), _a0 = jslo16(a); \ + _b1 = jshi16(b), _b0 = jslo16(b); \ + _y0 = _a0 * _b0; \ + _y1 = _a0 * _b1; \ + _y2 = _a1 * _b0; \ + _y3 = _a1 * _b1; \ + _y1 += jshi16(_y0); /* can't carry */ \ + _y1 += _y2; /* might carry */ \ + if (_y1 < _y2) \ + _y3 += (JSUint32)(JS_BIT(16)); /* propagate */ \ + (r).lo = (jslo16(_y1) << 16) + jslo16(_y0); \ + (r).hi = _y3 + jshi16(_y1); \ +} + +#define JSLL_UDIVMOD(qp, rp, a, b) jsll_udivmod(qp, rp, a, b) + +extern JS_PUBLIC_API(void) jsll_udivmod(JSUint64 *qp, JSUint64 *rp, JSUint64 a, JSUint64 b); + +#define JSLL_DIV(r, a, b) { \ + JSInt64 _a, _b; \ + JSUint32 _negative = (JSInt32)(a).hi < 0; \ + if (_negative) { \ + JSLL_NEG(_a, a); \ + } else { \ + _a = a; \ + } \ + if ((JSInt32)(b).hi < 0) { \ + _negative ^= 1; \ + JSLL_NEG(_b, b); \ + } else { \ + _b = b; \ + } \ + JSLL_UDIVMOD(&(r), 0, _a, _b); \ + if (_negative) \ + JSLL_NEG(r, r); \ +} + +#define JSLL_MOD(r, a, b) { \ + JSInt64 _a, _b; \ + JSUint32 _negative = (JSInt32)(a).hi < 0; \ + if (_negative) { \ + JSLL_NEG(_a, a); \ + } else { \ + _a = a; \ + } \ + if ((JSInt32)(b).hi < 0) { \ + JSLL_NEG(_b, b); \ + } else { \ + _b = b; \ + } \ + JSLL_UDIVMOD(0, &(r), _a, _b); \ + if (_negative) \ + JSLL_NEG(r, r); \ +} + +#define JSLL_SHL(r, a, b) { \ + if (b) { \ + JSInt64 _a; \ + _a = a; \ + if ((b) < 32) { \ + (r).lo = _a.lo << ((b) & 31); \ + (r).hi = (_a.hi << ((b) & 31)) | (_a.lo >> (32 - (b))); \ + } else { \ + (r).lo = 0; \ + (r).hi = _a.lo << ((b) & 31); \ + } \ + } else { \ + (r) = (a); \ + } \ +} + +/* a is an JSInt32, b is JSInt32, r is JSInt64 */ +#define JSLL_ISHL(r, a, b) { \ + if (b) { \ + JSInt64 _a; \ + _a.lo = (a); \ + _a.hi = 0; \ + if ((b) < 32) { \ + (r).lo = (a) << ((b) & 31); \ + (r).hi = ((a) >> (32 - (b))); \ + } else { \ + (r).lo = 0; \ + (r).hi = (a) << ((b) & 31); \ + } \ + } else { \ + (r).lo = (a); \ + (r).hi = 0; \ + } \ +} + +#define JSLL_SHR(r, a, b) { \ + if (b) { \ + JSInt64 _a; \ + _a = a; \ + if ((b) < 32) { \ + (r).lo = (_a.hi << (32 - (b))) | (_a.lo >> ((b) & 31)); \ + (r).hi = (JSInt32)_a.hi >> ((b) & 31); \ + } else { \ + (r).lo = (JSInt32)_a.hi >> ((b) & 31); \ + (r).hi = (JSInt32)_a.hi >> 31; \ + } \ + } else { \ + (r) = (a); \ + } \ +} + +#define JSLL_USHR(r, a, b) { \ + if (b) { \ + JSInt64 _a; \ + _a = a; \ + if ((b) < 32) { \ + (r).lo = (_a.hi << (32 - (b))) | (_a.lo >> ((b) & 31)); \ + (r).hi = _a.hi >> ((b) & 31); \ + } else { \ + (r).lo = _a.hi >> ((b) & 31); \ + (r).hi = 0; \ + } \ + } else { \ + (r) = (a); \ + } \ +} + +#define JSLL_L2I(i, l) ((i) = (l).lo) +#define JSLL_L2UI(ui, l) ((ui) = (l).lo) +#define JSLL_L2F(f, l) { double _d; JSLL_L2D(_d, l); (f) = (JSFloat64)_d; } + +#define JSLL_L2D(d, l) { \ + int _negative; \ + JSInt64 _absval; \ + \ + _negative = (l).hi >> 31; \ + if (_negative) { \ + JSLL_NEG(_absval, l); \ + } else { \ + _absval = l; \ + } \ + (d) = (double)_absval.hi * 4.294967296e9 + _absval.lo; \ + if (_negative) \ + (d) = -(d); \ +} + +#define JSLL_I2L(l, i) { JSInt32 _i = (i) >> 31; (l).lo = (i); (l).hi = _i; } +#define JSLL_UI2L(l, ui) ((l).lo = (ui), (l).hi = 0) +#define JSLL_F2L(l, f) { double _d = (double)f; JSLL_D2L(l, _d); } + +#define JSLL_D2L(l, d) { \ + int _negative; \ + double _absval, _d_hi; \ + JSInt64 _lo_d; \ + \ + _negative = ((d) < 0); \ + _absval = _negative ? -(d) : (d); \ + \ + (l).hi = _absval / 4.294967296e9; \ + (l).lo = 0; \ + JSLL_L2D(_d_hi, l); \ + _absval -= _d_hi; \ + _lo_d.hi = 0; \ + if (_absval < 0) { \ + _lo_d.lo = -_absval; \ + JSLL_SUB(l, l, _lo_d); \ + } else { \ + _lo_d.lo = _absval; \ + JSLL_ADD(l, l, _lo_d); \ + } \ + \ + if (_negative) \ + JSLL_NEG(l, l); \ +} + +#endif /* !JS_HAVE_LONG_LONG */ + +JS_END_EXTERN_C + +#endif /* jslong_h___ */ diff --git a/src/dom/js/jsmath.c b/src/dom/js/jsmath.c new file mode 100644 index 000000000..9c6fcec0e --- /dev/null +++ b/src/dom/js/jsmath.c @@ -0,0 +1,477 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* + * JS math package. + */ +#include "jsstddef.h" +#include "jslibmath.h" +#include +#include "jstypes.h" +#include "jslong.h" +#include "prmjtime.h" +#include "jsapi.h" +#include "jsatom.h" +#include "jscntxt.h" +#include "jsconfig.h" +#include "jslock.h" +#include "jsmath.h" +#include "jsnum.h" +#include "jsobj.h" + +#ifndef M_E +#define M_E 2.7182818284590452354 +#endif +#ifndef M_LOG2E +#define M_LOG2E 1.4426950408889634074 +#endif +#ifndef M_LOG10E +#define M_LOG10E 0.43429448190325182765 +#endif +#ifndef M_LN2 +#define M_LN2 0.69314718055994530942 +#endif +#ifndef M_LN10 +#define M_LN10 2.30258509299404568402 +#endif +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif +#ifndef M_SQRT2 +#define M_SQRT2 1.41421356237309504880 +#endif +#ifndef M_SQRT1_2 +#define M_SQRT1_2 0.70710678118654752440 +#endif + +static JSConstDoubleSpec math_constants[] = { + {M_E, "E", 0, {0,0,0}}, + {M_LOG2E, "LOG2E", 0, {0,0,0}}, + {M_LOG10E, "LOG10E", 0, {0,0,0}}, + {M_LN2, "LN2", 0, {0,0,0}}, + {M_LN10, "LN10", 0, {0,0,0}}, + {M_PI, "PI", 0, {0,0,0}}, + {M_SQRT2, "SQRT2", 0, {0,0,0}}, + {M_SQRT1_2, "SQRT1_2", 0, {0,0,0}}, + {0,0,0,{0,0,0}} +}; + +static JSClass math_class = { + "Math", + 0, + JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, + JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub, + JSCLASS_NO_OPTIONAL_MEMBERS +}; + +static JSBool +math_abs(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + jsdouble x, z; + + if (!js_ValueToNumber(cx, argv[0], &x)) + return JS_FALSE; + z = fd_fabs(x); + return js_NewNumberValue(cx, z, rval); +} + +static JSBool +math_acos(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + jsdouble x, z; + + if (!js_ValueToNumber(cx, argv[0], &x)) + return JS_FALSE; + z = fd_acos(x); + return js_NewNumberValue(cx, z, rval); +} + +static JSBool +math_asin(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + jsdouble x, z; + + if (!js_ValueToNumber(cx, argv[0], &x)) + return JS_FALSE; +#ifdef XP_MAC + if (x == 0) + return js_NewNumberValue(cx, x, rval); +#endif + z = fd_asin(x); + return js_NewNumberValue(cx, z, rval); +} + +static JSBool +math_atan(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + jsdouble x, z; + + if (!js_ValueToNumber(cx, argv[0], &x)) + return JS_FALSE; +#ifdef XP_MAC + if (x == 0) + return js_NewNumberValue(cx, x, rval); +#endif + z = fd_atan(x); + return js_NewNumberValue(cx, z, rval); +} + +static JSBool +math_atan2(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + jsdouble x, y, z; + + if (!js_ValueToNumber(cx, argv[0], &x)) + return JS_FALSE; + if (!js_ValueToNumber(cx, argv[1], &y)) + return JS_FALSE; + z = fd_atan2(x, y); + return js_NewNumberValue(cx, z, rval); +} + +static JSBool +math_ceil(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + jsdouble x, z; + + if (!js_ValueToNumber(cx, argv[0], &x)) + return JS_FALSE; + z = fd_ceil(x); + return js_NewNumberValue(cx, z, rval); +} + +static JSBool +math_cos(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + jsdouble x, z; + + if (!js_ValueToNumber(cx, argv[0], &x)) + return JS_FALSE; + z = fd_cos(x); + return js_NewNumberValue(cx, z, rval); +} + +static JSBool +math_exp(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + jsdouble x, z; + + if (!js_ValueToNumber(cx, argv[0], &x)) + return JS_FALSE; +#ifdef _WIN32 + if (!JSDOUBLE_IS_NaN(x)) { + if (x == *cx->runtime->jsPositiveInfinity) { + *rval = DOUBLE_TO_JSVAL(cx->runtime->jsPositiveInfinity); + return JS_TRUE; + } + if (x == *cx->runtime->jsNegativeInfinity) { + *rval = JSVAL_ZERO; + return JS_TRUE; + } + } +#endif + z = fd_exp(x); + return js_NewNumberValue(cx, z, rval); +} + +static JSBool +math_floor(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + jsdouble x, z; + + if (!js_ValueToNumber(cx, argv[0], &x)) + return JS_FALSE; + z = fd_floor(x); + return js_NewNumberValue(cx, z, rval); +} + +static JSBool +math_log(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + jsdouble x, z; + + if (!js_ValueToNumber(cx, argv[0], &x)) + return JS_FALSE; + z = fd_log(x); + return js_NewNumberValue(cx, z, rval); +} + +static JSBool +math_max(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + jsdouble x, z = *cx->runtime->jsNegativeInfinity; + uintN i; + + if (argc == 0) { + *rval = DOUBLE_TO_JSVAL(cx->runtime->jsNegativeInfinity); + return JS_TRUE; + } + for (i = 0; i < argc; i++) { + if (!js_ValueToNumber(cx, argv[i], &x)) + return JS_FALSE; + if (JSDOUBLE_IS_NaN(x)) { + *rval = DOUBLE_TO_JSVAL(cx->runtime->jsNaN); + return JS_TRUE; + } + if ((x==0)&&(x==z)&&(fd_copysign(1.0,z)==-1)) + z = x; + else + z = (x > z) ? x : z; + } + return js_NewNumberValue(cx, z, rval); +} + +static JSBool +math_min(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + jsdouble x, z = *cx->runtime->jsPositiveInfinity; + uintN i; + + if (argc == 0) { + *rval = DOUBLE_TO_JSVAL(cx->runtime->jsPositiveInfinity); + return JS_TRUE; + } + for (i = 0; i < argc; i++) { + if (!js_ValueToNumber(cx, argv[i], &x)) + return JS_FALSE; + if (JSDOUBLE_IS_NaN(x)) { + *rval = DOUBLE_TO_JSVAL(cx->runtime->jsNaN); + return JS_TRUE; + } + if ((x==0)&&(x==z)&&(fd_copysign(1.0,x)==-1)) + z = x; + else + z = (x < z) ? x : z; + } + return js_NewNumberValue(cx, z, rval); +} + +static JSBool +math_pow(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + jsdouble x, y, z; + + if (!js_ValueToNumber(cx, argv[0], &x)) + return JS_FALSE; + if (!js_ValueToNumber(cx, argv[1], &y)) + return JS_FALSE; + z = fd_pow(x, y); + return js_NewNumberValue(cx, z, rval); +} + +/* + * Math.random() support, lifted from java.util.Random.java. + */ +static void +random_setSeed(JSRuntime *rt, int64 seed) +{ + int64 tmp; + + JSLL_I2L(tmp, 1000); + JSLL_DIV(seed, seed, tmp); + JSLL_XOR(tmp, seed, rt->rngMultiplier); + JSLL_AND(rt->rngSeed, tmp, rt->rngMask); +} + +static void +random_init(JSRuntime *rt) +{ + int64 tmp, tmp2; + + /* Do at most once. */ + if (rt->rngInitialized) + return; + rt->rngInitialized = JS_TRUE; + + /* rt->rngMultiplier = 0x5DEECE66DL */ + JSLL_ISHL(tmp, 0x5, 32); + JSLL_UI2L(tmp2, 0xDEECE66DL); + JSLL_OR(rt->rngMultiplier, tmp, tmp2); + + /* rt->rngAddend = 0xBL */ + JSLL_I2L(rt->rngAddend, 0xBL); + + /* rt->rngMask = (1L << 48) - 1 */ + JSLL_I2L(tmp, 1); + JSLL_SHL(tmp2, tmp, 48); + JSLL_SUB(rt->rngMask, tmp2, tmp); + + /* rt->rngDscale = (jsdouble)(1L << 53) */ + JSLL_SHL(tmp2, tmp, 53); + JSLL_L2D(rt->rngDscale, tmp2); + + /* Finally, set the seed from current time. */ + random_setSeed(rt, PRMJ_Now()); +} + +static uint32 +random_next(JSRuntime *rt, int bits) +{ + int64 nextseed, tmp; + uint32 retval; + + JSLL_MUL(nextseed, rt->rngSeed, rt->rngMultiplier); + JSLL_ADD(nextseed, nextseed, rt->rngAddend); + JSLL_AND(nextseed, nextseed, rt->rngMask); + rt->rngSeed = nextseed; + JSLL_USHR(tmp, nextseed, 48 - bits); + JSLL_L2I(retval, tmp); + return retval; +} + +static jsdouble +random_nextDouble(JSRuntime *rt) +{ + int64 tmp, tmp2; + jsdouble d; + + JSLL_ISHL(tmp, random_next(rt, 26), 27); + JSLL_UI2L(tmp2, random_next(rt, 27)); + JSLL_ADD(tmp, tmp, tmp2); + JSLL_L2D(d, tmp); + return d / rt->rngDscale; +} + +static JSBool +math_random(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + JSRuntime *rt; + jsdouble z; + + rt = cx->runtime; + JS_LOCK_RUNTIME(rt); + random_init(rt); + z = random_nextDouble(rt); + JS_UNLOCK_RUNTIME(rt); + return js_NewNumberValue(cx, z, rval); +} + +static JSBool +math_round(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + jsdouble x, z; + + if (!js_ValueToNumber(cx, argv[0], &x)) + return JS_FALSE; + z = fd_copysign(fd_floor(x + 0.5), x); + return js_NewNumberValue(cx, z, rval); +} + +static JSBool +math_sin(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + jsdouble x, z; + + if (!js_ValueToNumber(cx, argv[0], &x)) + return JS_FALSE; + z = fd_sin(x); + return js_NewNumberValue(cx, z, rval); +} + +static JSBool +math_sqrt(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + jsdouble x, z; + + if (!js_ValueToNumber(cx, argv[0], &x)) + return JS_FALSE; + z = fd_sqrt(x); + return js_NewNumberValue(cx, z, rval); +} + +static JSBool +math_tan(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + jsdouble x, z; + + if (!js_ValueToNumber(cx, argv[0], &x)) + return JS_FALSE; + z = fd_tan(x); + return js_NewNumberValue(cx, z, rval); +} + +#if JS_HAS_TOSOURCE +static JSBool +math_toSource(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval) +{ + *rval = ATOM_KEY(cx->runtime->atomState.MathAtom); + return JS_TRUE; +} +#endif + +static JSFunctionSpec math_static_methods[] = { +#if JS_HAS_TOSOURCE + {js_toSource_str, math_toSource, 0, 0, 0}, +#endif + {"abs", math_abs, 1, 0, 0}, + {"acos", math_acos, 1, 0, 0}, + {"asin", math_asin, 1, 0, 0}, + {"atan", math_atan, 1, 0, 0}, + {"atan2", math_atan2, 2, 0, 0}, + {"ceil", math_ceil, 1, 0, 0}, + {"cos", math_cos, 1, 0, 0}, + {"exp", math_exp, 1, 0, 0}, + {"floor", math_floor, 1, 0, 0}, + {"log", math_log, 1, 0, 0}, + {"max", math_max, 2, 0, 0}, + {"min", math_min, 2, 0, 0}, + {"pow", math_pow, 2, 0, 0}, + {"random", math_random, 0, 0, 0}, + {"round", math_round, 1, 0, 0}, + {"sin", math_sin, 1, 0, 0}, + {"sqrt", math_sqrt, 1, 0, 0}, + {"tan", math_tan, 1, 0, 0}, + {0,0,0,0,0} +}; + +JSObject * +js_InitMathClass(JSContext *cx, JSObject *obj) +{ + JSObject *Math; + + Math = JS_DefineObject(cx, obj, "Math", &math_class, NULL, 0); + if (!Math) + return NULL; + if (!JS_DefineFunctions(cx, Math, math_static_methods)) + return NULL; + if (!JS_DefineConstDoubles(cx, Math, math_constants)) + return NULL; + return Math; +} diff --git a/src/dom/js/jsmath.h b/src/dom/js/jsmath.h new file mode 100644 index 000000000..7a6b21657 --- /dev/null +++ b/src/dom/js/jsmath.h @@ -0,0 +1,55 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998-1999 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* -*- Mode: C; tab-width: 8 -*- + * Copyright (C) 1998-1999 Netscape Communications Corporation, All Rights Reserved. + */ + +#ifndef jsmath_h___ +#define jsmath_h___ +/* + * JS math functions. + */ + +JS_BEGIN_EXTERN_C + +extern JSObject * +js_InitMathClass(JSContext *cx, JSObject *obj); + +JS_END_EXTERN_C + +#endif /* jsmath_h___ */ diff --git a/src/dom/js/jsnum.c b/src/dom/js/jsnum.c new file mode 100644 index 000000000..6f6963b69 --- /dev/null +++ b/src/dom/js/jsnum.c @@ -0,0 +1,1058 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * IBM Corp. + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* + * JS number type and wrapper class. + */ +#include "jsstddef.h" +#if defined(XP_WIN) || defined(XP_OS2) +#include +#endif +#include +#include +#include +#include "jstypes.h" +#include "jsutil.h" /* Added by JSIFY */ +#include "jsapi.h" +#include "jsatom.h" +#include "jscntxt.h" +#include "jsconfig.h" +#include "jsdtoa.h" +#include "jsgc.h" +#include "jsinterp.h" +#include "jsnum.h" +#include "jsobj.h" +#include "jsopcode.h" +#include "jsprf.h" +#include "jsstr.h" + +static JSBool +num_isNaN(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + jsdouble x; + + if (!js_ValueToNumber(cx, argv[0], &x)) + return JS_FALSE; + *rval = BOOLEAN_TO_JSVAL(JSDOUBLE_IS_NaN(x)); + return JS_TRUE; +} + +static JSBool +num_isFinite(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + jsdouble x; + + if (!js_ValueToNumber(cx, argv[0], &x)) + return JS_FALSE; + *rval = BOOLEAN_TO_JSVAL(JSDOUBLE_IS_FINITE(x)); + return JS_TRUE; +} + +static JSBool +num_parseFloat(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + JSString *str; + jsdouble d; + const jschar *bp, *ep; + + str = js_ValueToString(cx, argv[0]); + if (!str) + return JS_FALSE; + /* XXXbe js_strtod shouldn't require NUL termination */ + bp = js_UndependString(cx, str); + if (!bp) + return JS_FALSE; + if (!js_strtod(cx, bp, &ep, &d)) + return JS_FALSE; + if (ep == bp) { + *rval = DOUBLE_TO_JSVAL(cx->runtime->jsNaN); + return JS_TRUE; + } + return js_NewNumberValue(cx, d, rval); +} + +/* See ECMA 15.1.2.2. */ +static JSBool +num_parseInt(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + JSString *str; + jsint radix; + jsdouble d; + const jschar *bp, *ep; + + str = js_ValueToString(cx, argv[0]); + if (!str) + return JS_FALSE; + + if (argc > 1) { + if (!js_ValueToECMAInt32(cx, argv[1], &radix)) + return JS_FALSE; + } else + radix = 0; + + if (radix != 0 && (radix < 2 || radix > 36)) { + *rval = DOUBLE_TO_JSVAL(cx->runtime->jsNaN); + return JS_TRUE; + } + /* XXXbe js_strtointeger shouldn't require NUL termination */ + bp = js_UndependString(cx, str); + if (!bp) + return JS_FALSE; + if (!js_strtointeger(cx, bp, &ep, radix, &d)) + return JS_FALSE; + if (ep == bp) { + *rval = DOUBLE_TO_JSVAL(cx->runtime->jsNaN); + return JS_TRUE; + } + return js_NewNumberValue(cx, d, rval); +} + +const char js_Infinity_str[] = "Infinity"; +const char js_NaN_str[] = "NaN"; +const char js_isNaN_str[] = "isNaN"; +const char js_isFinite_str[] = "isFinite"; +const char js_parseFloat_str[] = "parseFloat"; +const char js_parseInt_str[] = "parseInt"; + +static JSFunctionSpec number_functions[] = { + {"isNaN", num_isNaN, 1,0,0}, + {"isFinite", num_isFinite, 1,0,0}, + {"parseFloat", num_parseFloat, 1,0,0}, + {"parseInt", num_parseInt, 2,0,0}, + {0,0,0,0,0} +}; + +static JSClass number_class = { + "Number", + JSCLASS_HAS_PRIVATE, + JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, + JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub, + JSCLASS_NO_OPTIONAL_MEMBERS +}; + +static JSBool +Number(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + jsdouble d; + jsval v; + + if (argc != 0) { + if (!js_ValueToNumber(cx, argv[0], &d)) + return JS_FALSE; + } else { + d = 0.0; + } + if (!js_NewNumberValue(cx, d, &v)) + return JS_FALSE; + if (!(cx->fp->flags & JSFRAME_CONSTRUCTING)) { + *rval = v; + return JS_TRUE; + } + OBJ_SET_SLOT(cx, obj, JSSLOT_PRIVATE, v); + return JS_TRUE; +} + +#if JS_HAS_TOSOURCE +static JSBool +num_toSource(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + jsval v; + jsdouble d; + char numBuf[DTOSTR_STANDARD_BUFFER_SIZE], *numStr; + char buf[64]; + JSString *str; + + if (!JS_InstanceOf(cx, obj, &number_class, argv)) + return JS_FALSE; + v = OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE); + JS_ASSERT(JSVAL_IS_NUMBER(v)); + d = JSVAL_IS_INT(v) ? (jsdouble)JSVAL_TO_INT(v) : *JSVAL_TO_DOUBLE(v); + numStr = JS_dtostr(numBuf, sizeof numBuf, DTOSTR_STANDARD, 0, d); + if (!numStr) { + JS_ReportOutOfMemory(cx); + return JS_FALSE; + } + JS_snprintf(buf, sizeof buf, "(new %s(%s))", number_class.name, numStr); + str = JS_NewStringCopyZ(cx, buf); + if (!str) + return JS_FALSE; + *rval = STRING_TO_JSVAL(str); + return JS_TRUE; +} +#endif + +/* The buf must be big enough for MIN_INT to fit including '-' and '\0'. */ +static char * +IntToString(jsint i, char *buf, size_t bufSize) +{ + char *cp; + jsuint u; + + u = (i < 0) ? -i : i; + + cp = buf + bufSize; /* one past last buffer cell */ + *--cp = '\0'; /* null terminate the string to be */ + + /* + * Build the string from behind. We use multiply and subtraction + * instead of modulus because that's much faster. + */ + do { + jsuint newu = u / 10; + *--cp = (char)(u - newu * 10) + '0'; + u = newu; + } while (u != 0); + + if (i < 0) + *--cp = '-'; + + return cp; +} + +static JSBool +num_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + jsval v; + jsdouble d; + jsint base; + JSString *str; + + if (!JS_InstanceOf(cx, obj, &number_class, argv)) + return JS_FALSE; + v = OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE); + JS_ASSERT(JSVAL_IS_NUMBER(v)); + d = JSVAL_IS_INT(v) ? (jsdouble)JSVAL_TO_INT(v) : *JSVAL_TO_DOUBLE(v); + base = 10; + if (argc != 0) { + if (!js_ValueToECMAInt32(cx, argv[0], &base)) + return JS_FALSE; + if (base < 2 || base > 36) { + char numBuf[12]; + char *numStr = IntToString(base, numBuf, sizeof numBuf); + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BAD_RADIX, + numStr); + return JS_FALSE; + } + } + if (base == 10) + str = js_NumberToString(cx, d); + else { + char *dStr = JS_dtobasestr(base, d); + if (!dStr) { + JS_ReportOutOfMemory(cx); + return JS_FALSE; + } + str = JS_NewStringCopyZ(cx, dStr); + free(dStr); + } + if (!str) + return JS_FALSE; + *rval = STRING_TO_JSVAL(str); + return JS_TRUE; +} + +static JSBool +num_toLocaleString(JSContext *cx, JSObject *obj, uintN argc, + jsval *argv, jsval *rval) +{ +/* + * For now, forcibly ignore the first (or any) argument and return toString(). + * ECMA allows this, although it doesn't 'encourage it'. + * [The first argument is being reserved by ECMA and we don't want it confused + * with a radix] + */ + return num_toString(cx, obj, 0, argv, rval); +} + +static JSBool +num_valueOf(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + if (!JS_InstanceOf(cx, obj, &number_class, argv)) + return JS_FALSE; + *rval = OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE); + return JS_TRUE; +} + + +#if JS_HAS_NUMBER_FORMATS +#define MAX_PRECISION 100 + +static JSBool +num_to(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval, JSDToStrMode zeroArgMode, + JSDToStrMode oneArgMode, jsint precisionMin, jsint precisionMax, jsint precisionOffset) +{ + jsval v; + jsdouble d, precision; + JSString *str; + char buf[DTOSTR_VARIABLE_BUFFER_SIZE(MAX_PRECISION+1)], *numStr; /* Use MAX_PRECISION+1 because precisionOffset can be 1 */ + + if (!JS_InstanceOf(cx, obj, &number_class, argv)) + return JS_FALSE; + v = OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE); + JS_ASSERT(JSVAL_IS_NUMBER(v)); + d = JSVAL_IS_INT(v) ? (jsdouble)JSVAL_TO_INT(v) : *JSVAL_TO_DOUBLE(v); + + if (JSVAL_IS_VOID(argv[0])) { + precision = 0.0; + oneArgMode = zeroArgMode; + } else { + if (!js_ValueToNumber(cx, argv[0], &precision)) + return JS_FALSE; + precision = js_DoubleToInteger(precision); + if (precision < precisionMin || precision > precisionMax) { + numStr = JS_dtostr(buf, sizeof buf, DTOSTR_STANDARD, 0, precision); + if (!numStr) + JS_ReportOutOfMemory(cx); + else + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_PRECISION_RANGE, numStr); + return JS_FALSE; + } + } + + numStr = JS_dtostr(buf, sizeof buf, oneArgMode, (jsint)precision + precisionOffset, d); + if (!numStr) { + JS_ReportOutOfMemory(cx); + return JS_FALSE; + } + str = JS_NewStringCopyZ(cx, numStr); + if (!str) + return JS_FALSE; + *rval = STRING_TO_JSVAL(str); + return JS_TRUE; +} + +static JSBool +num_toFixed(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + /* We allow a larger range of precision than ECMA requires; this is permitted by ECMA. */ + return num_to(cx, obj, argc, argv, rval, DTOSTR_FIXED, DTOSTR_FIXED, -20, MAX_PRECISION, 0); +} + +static JSBool +num_toExponential(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + /* We allow a larger range of precision than ECMA requires; this is permitted by ECMA. */ + return num_to(cx, obj, argc, argv, rval, DTOSTR_STANDARD_EXPONENTIAL, DTOSTR_EXPONENTIAL, 0, MAX_PRECISION, 1); +} + +static JSBool +num_toPrecision(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + /* We allow a larger range of precision than ECMA requires; this is permitted by ECMA. */ + return num_to(cx, obj, argc, argv, rval, DTOSTR_STANDARD, DTOSTR_PRECISION, 1, MAX_PRECISION, 0); +} +#endif /* JS_HAS_NUMBER_FORMATS */ + + +static JSFunctionSpec number_methods[] = { +#if JS_HAS_TOSOURCE + {js_toSource_str, num_toSource, 0,0,0}, +#endif + {js_toString_str, num_toString, 0,0,0}, + {js_toLocaleString_str, num_toLocaleString, 0,0,0}, + {js_valueOf_str, num_valueOf, 0,0,0}, +#if JS_HAS_NUMBER_FORMATS + {"toFixed", num_toFixed, 1,0,0}, + {"toExponential", num_toExponential, 1,0,0}, + {"toPrecision", num_toPrecision, 1,0,0}, +#endif + {0,0,0,0,0} +}; + +/* NB: Keep this in synch with number_constants[]. */ +enum nc_slot { + NC_NaN, + NC_POSITIVE_INFINITY, + NC_NEGATIVE_INFINITY, + NC_MAX_VALUE, + NC_MIN_VALUE, + NC_LIMIT +}; + +/* + * Some to most C compilers forbid spelling these at compile time, or barf + * if you try, so all but MAX_VALUE are set up by js_InitRuntimeNumberState + * using union jsdpun. + */ +static JSConstDoubleSpec number_constants[] = { + {0, js_NaN_str, 0,{0,0,0}}, + {0, "POSITIVE_INFINITY", 0,{0,0,0}}, + {0, "NEGATIVE_INFINITY", 0,{0,0,0}}, + {1.7976931348623157E+308, "MAX_VALUE", 0,{0,0,0}}, + {0, "MIN_VALUE", 0,{0,0,0}}, + {0,0,0,{0,0,0}} +}; + +static jsdouble NaN; + + +#if defined XP_WIN && \ + !defined __MWERKS__ && \ + (defined _M_IX86 || \ + (defined __GNUC__ && !defined __MINGW32__)) + +/* + * Set the exception mask to mask all exceptions and set the FPU precision + * to 53 bit mantissa. + * On Alpha platform this is handled via Compiler option. + */ +#define FIX_FPU() _control87(MCW_EM | PC_53, MCW_EM | MCW_PC) + +#else + +#define FIX_FPU() ((void)0) + +#endif + +JSBool +js_InitRuntimeNumberState(JSContext *cx) +{ + JSRuntime *rt; + jsdpun u; + + rt = cx->runtime; + JS_ASSERT(!rt->jsNaN); + + FIX_FPU(); + + u.s.hi = JSDOUBLE_HI32_EXPMASK | JSDOUBLE_HI32_MANTMASK; + u.s.lo = 0xffffffff; + number_constants[NC_NaN].dval = NaN = u.d; + rt->jsNaN = js_NewDouble(cx, NaN); + if (!rt->jsNaN || !js_LockGCThing(cx, rt->jsNaN)) + return JS_FALSE; + + u.s.hi = JSDOUBLE_HI32_EXPMASK; + u.s.lo = 0x00000000; + number_constants[NC_POSITIVE_INFINITY].dval = u.d; + rt->jsPositiveInfinity = js_NewDouble(cx, u.d); + if (!rt->jsPositiveInfinity || + !js_LockGCThing(cx, rt->jsPositiveInfinity)) { + return JS_FALSE; + } + + u.s.hi = JSDOUBLE_HI32_SIGNBIT | JSDOUBLE_HI32_EXPMASK; + u.s.lo = 0x00000000; + number_constants[NC_NEGATIVE_INFINITY].dval = u.d; + rt->jsNegativeInfinity = js_NewDouble(cx, u.d); + if (!rt->jsNegativeInfinity || + !js_LockGCThing(cx, rt->jsNegativeInfinity)) { + return JS_FALSE; + } + + u.s.hi = 0; + u.s.lo = 1; + number_constants[NC_MIN_VALUE].dval = u.d; + + return JS_TRUE; +} + +void +js_FinishRuntimeNumberState(JSContext *cx) +{ + JSRuntime *rt = cx->runtime; + + js_UnlockGCThingRT(rt, rt->jsNaN); + js_UnlockGCThingRT(rt, rt->jsNegativeInfinity); + js_UnlockGCThingRT(rt, rt->jsPositiveInfinity); + + rt->jsNaN = NULL; + rt->jsNegativeInfinity = NULL; + rt->jsPositiveInfinity = NULL; +} + +JSObject * +js_InitNumberClass(JSContext *cx, JSObject *obj) +{ + JSObject *proto, *ctor; + JSRuntime *rt; + + /* XXX must do at least once per new thread, so do it per JSContext... */ + FIX_FPU(); + + if (!JS_DefineFunctions(cx, obj, number_functions)) + return NULL; + + proto = JS_InitClass(cx, obj, NULL, &number_class, Number, 1, + NULL, number_methods, NULL, NULL); + if (!proto || !(ctor = JS_GetConstructor(cx, proto))) + return NULL; + OBJ_SET_SLOT(cx, proto, JSSLOT_PRIVATE, JSVAL_ZERO); + if (!JS_DefineConstDoubles(cx, ctor, number_constants)) + return NULL; + + /* ECMA 15.1.1.1 */ + rt = cx->runtime; + if (!JS_DefineProperty(cx, obj, js_NaN_str, DOUBLE_TO_JSVAL(rt->jsNaN), + NULL, NULL, JSPROP_PERMANENT)) { + return NULL; + } + + /* ECMA 15.1.1.2 */ + if (!JS_DefineProperty(cx, obj, js_Infinity_str, + DOUBLE_TO_JSVAL(rt->jsPositiveInfinity), + NULL, NULL, JSPROP_PERMANENT)) { + return NULL; + } + return proto; +} + +jsdouble * +js_NewDouble(JSContext *cx, jsdouble d) +{ + jsdouble *dp; + + dp = (jsdouble *) js_AllocGCThing(cx, GCX_DOUBLE); + if (!dp) + return NULL; + *dp = d; + return dp; +} + +void +js_FinalizeDouble(JSContext *cx, jsdouble *dp) +{ + *dp = NaN; +} + +JSBool +js_NewDoubleValue(JSContext *cx, jsdouble d, jsval *rval) +{ + jsdouble *dp; + + dp = js_NewDouble(cx, d); + if (!dp) + return JS_FALSE; + *rval = DOUBLE_TO_JSVAL(dp); + return JS_TRUE; +} + +JSBool +js_NewNumberValue(JSContext *cx, jsdouble d, jsval *rval) +{ + jsint i; + JSBool ok; + + SET_FPU(); + + if (JSDOUBLE_IS_INT(d, i) && INT_FITS_IN_JSVAL(i)) { + *rval = INT_TO_JSVAL(i); + ok = JS_TRUE; + } else { + ok = js_NewDoubleValue(cx, d, rval); + } + + RESTORE_FPU(); + return ok; +} + +JSObject * +js_NumberToObject(JSContext *cx, jsdouble d) +{ + JSObject *obj; + jsval v; + + obj = js_NewObject(cx, &number_class, NULL, NULL); + if (!obj) + return NULL; + if (!js_NewNumberValue(cx, d, &v)) { + cx->newborn[GCX_OBJECT] = NULL; + return NULL; + } + OBJ_SET_SLOT(cx, obj, JSSLOT_PRIVATE, v); + return obj; +} + +JSString * +js_NumberToString(JSContext *cx, jsdouble d) +{ + jsint i; + char buf[DTOSTR_STANDARD_BUFFER_SIZE]; + char *numStr; + + if (JSDOUBLE_IS_INT(d, i)) + numStr = IntToString(i, buf, sizeof buf); + else { + numStr = JS_dtostr(buf, sizeof buf, DTOSTR_STANDARD, 0, d); + if (!numStr) { + JS_ReportOutOfMemory(cx); + return NULL; + } + } + return JS_NewStringCopyZ(cx, numStr); +} + +JSBool +js_ValueToNumber(JSContext *cx, jsval v, jsdouble *dp) +{ + JSObject *obj; + JSString *str; + const jschar *bp, *ep; + + if (JSVAL_IS_OBJECT(v)) { + obj = JSVAL_TO_OBJECT(v); + if (!obj) { + *dp = 0; + return JS_TRUE; + } + if (!OBJ_DEFAULT_VALUE(cx, obj, JSTYPE_NUMBER, &v)) + return JS_FALSE; + } + if (JSVAL_IS_INT(v)) { + *dp = (jsdouble)JSVAL_TO_INT(v); + } else if (JSVAL_IS_DOUBLE(v)) { + *dp = *JSVAL_TO_DOUBLE(v); + } else if (JSVAL_IS_STRING(v)) { + str = JSVAL_TO_STRING(v); + /* + * Note that ECMA doesn't treat a string beginning with a '0' as an + * octal number here. This works because all such numbers will be + * interpreted as decimal by js_strtod and will never get passed to + * js_strtointeger (which would interpret them as octal). + */ + /* XXXbe js_strtod shouldn't require NUL termination */ + bp = js_UndependString(cx, str); + if (!bp) + return JS_FALSE; + if ((!js_strtod(cx, bp, &ep, dp) || + js_SkipWhiteSpace(ep) != bp + str->length) && + (!js_strtointeger(cx, bp, &ep, 0, dp) || + js_SkipWhiteSpace(ep) != bp + str->length)) { + goto badstr; + } + } else if (JSVAL_IS_BOOLEAN(v)) { + *dp = JSVAL_TO_BOOLEAN(v) ? 1 : 0; + } else { +#if JS_BUG_FALLIBLE_TONUM + str = js_DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, v, NULL); +badstr: + if (str) { + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_NAN, + JS_GetStringBytes(str)); + + } + return JS_FALSE; +#else +badstr: + *dp = *cx->runtime->jsNaN; +#endif + } + return JS_TRUE; +} + +JSBool +js_ValueToECMAInt32(JSContext *cx, jsval v, int32 *ip) +{ + jsdouble d; + + if (!js_ValueToNumber(cx, v, &d)) + return JS_FALSE; + return js_DoubleToECMAInt32(cx, d, ip); +} + +JSBool +js_DoubleToECMAInt32(JSContext *cx, jsdouble d, int32 *ip) +{ + jsdouble two32 = 4294967296.0; + jsdouble two31 = 2147483648.0; + + if (!JSDOUBLE_IS_FINITE(d) || d == 0) { + *ip = 0; + return JS_TRUE; + } + d = fmod(d, two32); + d = (d >= 0) ? floor(d) : ceil(d) + two32; + if (d >= two31) + *ip = (int32)(d - two32); + else + *ip = (int32)d; + return JS_TRUE; +} + +JSBool +js_ValueToECMAUint32(JSContext *cx, jsval v, uint32 *ip) +{ + jsdouble d; + + if (!js_ValueToNumber(cx, v, &d)) + return JS_FALSE; + return js_DoubleToECMAUint32(cx, d, ip); +} + +JSBool +js_DoubleToECMAUint32(JSContext *cx, jsdouble d, uint32 *ip) +{ + JSBool neg; + jsdouble two32 = 4294967296.0; + + if (!JSDOUBLE_IS_FINITE(d) || d == 0) { + *ip = 0; + return JS_TRUE; + } + + neg = (d < 0); + d = floor(neg ? -d : d); + d = neg ? -d : d; + + d = fmod(d, two32); + + d = (d >= 0) ? d : d + two32; + *ip = (uint32)d; + return JS_TRUE; +} + +JSBool +js_ValueToInt32(JSContext *cx, jsval v, int32 *ip) +{ + jsdouble d; + JSString *str; + + if (JSVAL_IS_INT(v)) { + *ip = JSVAL_TO_INT(v); + return JS_TRUE; + } + if (!js_ValueToNumber(cx, v, &d)) + return JS_FALSE; + if (JSDOUBLE_IS_NaN(d) || d <= -2147483649.0 || 2147483648.0 <= d) { + str = js_DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, v, NULL); + if (str) { + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, + JSMSG_CANT_CONVERT, JS_GetStringBytes(str)); + + } + return JS_FALSE; + } + *ip = (int32)floor(d + 0.5); /* Round to nearest */ + return JS_TRUE; +} + +JSBool +js_ValueToUint16(JSContext *cx, jsval v, uint16 *ip) +{ + jsdouble d; + jsuint i, m; + JSBool neg; + + if (!js_ValueToNumber(cx, v, &d)) + return JS_FALSE; + if (d == 0 || !JSDOUBLE_IS_FINITE(d)) { + *ip = 0; + return JS_TRUE; + } + i = (jsuint)d; + if ((jsdouble)i == d) { + *ip = (uint16)i; + return JS_TRUE; + } + neg = (d < 0); + d = floor(neg ? -d : d); + d = neg ? -d : d; + m = JS_BIT(16); + d = fmod(d, (double)m); + if (d < 0) + d += m; + *ip = (uint16) d; + return JS_TRUE; +} + +jsdouble +js_DoubleToInteger(jsdouble d) +{ + JSBool neg; + + if (d == 0) + return d; + if (!JSDOUBLE_IS_FINITE(d)) { + if (JSDOUBLE_IS_NaN(d)) + return 0; + return d; + } + neg = (d < 0); + d = floor(neg ? -d : d); + return neg ? -d : d; +} + + +JSBool +js_strtod(JSContext *cx, const jschar *s, const jschar **ep, jsdouble *dp) +{ + char cbuf[32]; + size_t i; + char *cstr, *istr, *estr; + JSBool negative; + jsdouble d; + const jschar *s1 = js_SkipWhiteSpace(s); + size_t length = js_strlen(s1); + + /* Use cbuf to avoid malloc */ + if (length >= sizeof cbuf) { + cstr = (char *) JS_malloc(cx, length + 1); + if (!cstr) + return JS_FALSE; + } else { + cstr = cbuf; + } + + for (i = 0; i <= length; i++) { + if (s1[i] >> 8) { + cstr[i] = 0; + break; + } + cstr[i] = (char)s1[i]; + } + + istr = cstr; + if ((negative = (*istr == '-')) != 0 || *istr == '+') + istr++; + if (!strncmp(istr, js_Infinity_str, sizeof js_Infinity_str - 1)) { + d = *(negative ? cx->runtime->jsNegativeInfinity : cx->runtime->jsPositiveInfinity); + estr = istr + 8; + } else { + int err; + d = JS_strtod(cstr, &estr, &err); + if (err == JS_DTOA_ENOMEM) { + JS_ReportOutOfMemory(cx); + if (cstr != cbuf) + JS_free(cx, cstr); + return JS_FALSE; + } + if (err == JS_DTOA_ERANGE) { + if (d == HUGE_VAL) + d = *cx->runtime->jsPositiveInfinity; + else if (d == -HUGE_VAL) + d = *cx->runtime->jsNegativeInfinity; + } +#ifdef HPUX + if (d == 0.0 && negative) { + /* + * "-0", "-1e-2000" come out as positive zero + * here on HPUX. Force a negative zero instead. + */ + JSDOUBLE_HI32(d) = JSDOUBLE_HI32_SIGNBIT; + JSDOUBLE_LO32(d) = 0; + } +#endif + } + + i = estr - cstr; + if (cstr != cbuf) + JS_free(cx, cstr); + *ep = i ? s1 + i : s; + *dp = d; + return JS_TRUE; +} + +struct BinaryDigitReader +{ + uintN base; /* Base of number; must be a power of 2 */ + uintN digit; /* Current digit value in radix given by base */ + uintN digitMask; /* Mask to extract the next bit from digit */ + const jschar *digits; /* Pointer to the remaining digits */ + const jschar *end; /* Pointer to first non-digit */ +}; + +/* Return the next binary digit from the number or -1 if done */ +static intN GetNextBinaryDigit(struct BinaryDigitReader *bdr) +{ + intN bit; + + if (bdr->digitMask == 0) { + uintN c; + + if (bdr->digits == bdr->end) + return -1; + + c = *bdr->digits++; + if ('0' <= c && c <= '9') + bdr->digit = c - '0'; + else if ('a' <= c && c <= 'z') + bdr->digit = c - 'a' + 10; + else bdr->digit = c - 'A' + 10; + bdr->digitMask = bdr->base >> 1; + } + bit = (bdr->digit & bdr->digitMask) != 0; + bdr->digitMask >>= 1; + return bit; +} + +JSBool +js_strtointeger(JSContext *cx, const jschar *s, const jschar **ep, jsint base, jsdouble *dp) +{ + JSBool negative; + jsdouble value; + const jschar *start; + const jschar *s1 = js_SkipWhiteSpace(s); + + if ((negative = (*s1 == '-')) != 0 || *s1 == '+') + s1++; + + if (base == 0) { + /* No base supplied, or some base that evaluated to 0. */ + if (*s1 == '0') { + /* It's either hex or octal; only increment char if str isn't '0' */ + if (s1[1] == 'X' || s1[1] == 'x') { /* Hex */ + s1 += 2; + base = 16; + } else { /* Octal */ + base = 8; + } + } else { + base = 10; /* Default to decimal. */ + } + } else if (base == 16 && *s1 == '0' && (s1[1] == 'X' || s1[1] == 'x')) { + /* If base is 16, ignore hex prefix. */ + s1 += 2; + } + + /* + * Done with the preliminaries; find some prefix of the string that's + * a number in the given base. + */ + start = s1; /* Mark - if string is empty, we return NaN. */ + value = 0.0; + for (;;) { + uintN digit; + jschar c = *s1; + if ('0' <= c && c <= '9') + digit = c - '0'; + else if ('a' <= c && c <= 'z') + digit = c - 'a' + 10; + else if ('A' <= c && c <= 'Z') + digit = c - 'A' + 10; + else + break; + if (digit >= (uintN)base) + break; + value = value * base + digit; + s1++; + } + + if (value >= 9007199254740992.0) { + if (base == 10) { + /* + * If we're accumulating a decimal number and the number is >= + * 2^53, then the result from the repeated multiply-add above may + * be inaccurate. Call JS_strtod to get the correct answer. + */ + size_t i; + size_t length = s1 - start; + char *cstr = (char *) JS_malloc(cx, length + 1); + char *estr; + int err=0; + + if (!cstr) + return JS_FALSE; + for (i = 0; i != length; i++) + cstr[i] = (char)start[i]; + cstr[length] = 0; + + value = JS_strtod(cstr, &estr, &err); + if (err == JS_DTOA_ENOMEM) { + JS_ReportOutOfMemory(cx); + JS_free(cx, cstr); + return JS_FALSE; + } + if (err == JS_DTOA_ERANGE && value == HUGE_VAL) + value = *cx->runtime->jsPositiveInfinity; + JS_free(cx, cstr); + } else if ((base & (base - 1)) == 0) { + /* + * The number may also be inaccurate for power-of-two bases. This + * happens if the addition in value * base + digit causes a round- + * down to an even least significant mantissa bit when the first + * dropped bit is a one. If any of the following digits in the + * number (which haven't been added in yet) are nonzero, then the + * correct action would have been to round up instead of down. An + * example occurs when reading the number 0x1000000000000081, which + * rounds to 0x1000000000000000 instead of 0x1000000000000100. + */ + struct BinaryDigitReader bdr; + intN bit, bit2; + intN j; + + bdr.base = base; + bdr.digitMask = 0; + bdr.digits = start; + bdr.end = s1; + value = 0.0; + + /* Skip leading zeros. */ + do { + bit = GetNextBinaryDigit(&bdr); + } while (bit == 0); + + if (bit == 1) { + /* Gather the 53 significant bits (including the leading 1) */ + value = 1.0; + for (j = 52; j; j--) { + bit = GetNextBinaryDigit(&bdr); + if (bit < 0) + goto done; + value = value*2 + bit; + } + /* bit2 is the 54th bit (the first dropped from the mantissa) */ + bit2 = GetNextBinaryDigit(&bdr); + if (bit2 >= 0) { + jsdouble factor = 2.0; + intN sticky = 0; /* sticky is 1 if any bit beyond the 54th is 1 */ + intN bit3; + + while ((bit3 = GetNextBinaryDigit(&bdr)) >= 0) { + sticky |= bit3; + factor *= 2; + } + value += bit2 & (bit | sticky); + value *= factor; + } + done:; + } + } + } + /* We don't worry about inaccurate numbers for any other base. */ + + if (s1 == start) { + *dp = 0.0; + *ep = s; + } else { + *dp = negative ? -value : value; + *ep = s1; + } + return JS_TRUE; +} diff --git a/src/dom/js/jsnum.h b/src/dom/js/jsnum.h new file mode 100644 index 000000000..46992e2b6 --- /dev/null +++ b/src/dom/js/jsnum.h @@ -0,0 +1,280 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef jsnum_h___ +#define jsnum_h___ +/* + * JS number (IEEE double) interface. + * + * JS numbers are optimistically stored in the top 31 bits of 32-bit integers, + * but floating point literals, results that overflow 31 bits, and division and + * modulus operands and results require a 64-bit IEEE double. These are GC'ed + * and pointed to by 32-bit jsvals on the stack and in object properties. + * + * When a JS number is treated as an object (followed by . or []), the runtime + * wraps it with a JSObject whose valueOf method returns the unwrapped number. + */ + +JS_BEGIN_EXTERN_C + +/* + * Stefan Hanske reports: + * ARM is a little endian architecture but 64 bit double words are stored + * differently: the 32 bit words are in little endian byte order, the two words + * are stored in big endian`s way. + */ + +#if defined(__arm) || defined(__arm32__) || defined(__arm26__) || defined(__arm__) +#define CPU_IS_ARM +#endif + +typedef union jsdpun { + struct { +#if defined(IS_LITTLE_ENDIAN) && !defined(CPU_IS_ARM) + uint32 lo, hi; +#else + uint32 hi, lo; +#endif + } s; + jsdouble d; +} jsdpun; + +#if (__GNUC__ == 2 && __GNUC_MINOR__ > 95) || __GNUC__ > 2 +/* + * This version of the macros is safe for the alias optimizations that gcc + * does, but uses gcc-specific extensions. + */ + +#define JSDOUBLE_HI32(x) (__extension__ ({ jsdpun u; u.d = (x); u.s.hi; })) +#define JSDOUBLE_LO32(x) (__extension__ ({ jsdpun u; u.d = (x); u.s.lo; })) +#define JSDOUBLE_SET_HI32(x, y) \ + (__extension__ ({ jsdpun u; u.d = (x); u.s.hi = (y); (x) = u.d; })) +#define JSDOUBLE_SET_LO32(x, y) \ + (__extension__ ({ jsdpun u; u.d = (x); u.s.lo = (y); (x) = u.d; })) + +#else /* not or old GNUC */ + +/* + * We don't know of any non-gcc compilers that perform alias optimization, + * so this code should work. + */ + +#if defined(IS_LITTLE_ENDIAN) && !defined(CPU_IS_ARM) +#define JSDOUBLE_HI32(x) (((uint32 *)&(x))[1]) +#define JSDOUBLE_LO32(x) (((uint32 *)&(x))[0]) +#else +#define JSDOUBLE_HI32(x) (((uint32 *)&(x))[0]) +#define JSDOUBLE_LO32(x) (((uint32 *)&(x))[1]) +#endif + +#define JSDOUBLE_SET_HI32(x, y) (JSDOUBLE_HI32(x)=(y)) +#define JSDOUBLE_SET_LO32(x, y) (JSDOUBLE_LO32(x)=(y)) + +#endif /* not or old GNUC */ + +#define JSDOUBLE_HI32_SIGNBIT 0x80000000 +#define JSDOUBLE_HI32_EXPMASK 0x7ff00000 +#define JSDOUBLE_HI32_MANTMASK 0x000fffff + +#define JSDOUBLE_IS_NaN(x) \ + ((JSDOUBLE_HI32(x) & JSDOUBLE_HI32_EXPMASK) == JSDOUBLE_HI32_EXPMASK && \ + (JSDOUBLE_LO32(x) || (JSDOUBLE_HI32(x) & JSDOUBLE_HI32_MANTMASK))) + +#define JSDOUBLE_IS_INFINITE(x) \ + ((JSDOUBLE_HI32(x) & ~JSDOUBLE_HI32_SIGNBIT) == JSDOUBLE_HI32_EXPMASK && \ + !JSDOUBLE_LO32(x)) + +#define JSDOUBLE_IS_FINITE(x) \ + ((JSDOUBLE_HI32(x) & JSDOUBLE_HI32_EXPMASK) != JSDOUBLE_HI32_EXPMASK) + +#define JSDOUBLE_IS_NEGZERO(d) (JSDOUBLE_HI32(d) == JSDOUBLE_HI32_SIGNBIT && \ + JSDOUBLE_LO32(d) == 0) + +/* + * JSDOUBLE_IS_INT first checks that d is neither NaN nor infinite, to avoid + * raising SIGFPE on platforms such as Alpha Linux, then (only if the cast is + * safe) leaves i as (jsint)d. This also avoid anomalous NaN floating point + * comparisons under MSVC. + */ +#define JSDOUBLE_IS_INT(d, i) (JSDOUBLE_IS_FINITE(d) \ + && !JSDOUBLE_IS_NEGZERO(d) \ + && ((d) == (i = (jsint)(d)))) + +/* Initialize number constants and runtime state for the first context. */ +extern JSBool +js_InitRuntimeNumberState(JSContext *cx); + +extern void +js_FinishRuntimeNumberState(JSContext *cx); + +/* Initialize the Number class, returning its prototype object. */ +extern JSObject * +js_InitNumberClass(JSContext *cx, JSObject *obj); + +/* + * String constants for global function names, used in jsapi.c and jsnum.c. + */ +extern const char js_Infinity_str[]; +extern const char js_NaN_str[]; +extern const char js_isNaN_str[]; +extern const char js_isFinite_str[]; +extern const char js_parseFloat_str[]; +extern const char js_parseInt_str[]; + +/* GC-allocate a new JS number. */ +extern jsdouble * +js_NewDouble(JSContext *cx, jsdouble d); + +extern void +js_FinalizeDouble(JSContext *cx, jsdouble *dp); + +extern JSBool +js_NewDoubleValue(JSContext *cx, jsdouble d, jsval *rval); + +extern JSBool +js_NewNumberValue(JSContext *cx, jsdouble d, jsval *rval); + +/* Construct a Number instance that wraps around d. */ +extern JSObject * +js_NumberToObject(JSContext *cx, jsdouble d); + +/* Convert a number to a GC'ed string. */ +extern JSString * +js_NumberToString(JSContext *cx, jsdouble d); + +/* + * Convert a value to a number, returning false after reporting any error, + * otherwise returning true with *dp set. + */ +extern JSBool +js_ValueToNumber(JSContext *cx, jsval v, jsdouble *dp); + +/* + * Convert a value or a double to an int32, according to the ECMA rules + * for ToInt32. + */ +extern JSBool +js_ValueToECMAInt32(JSContext *cx, jsval v, int32 *ip); + +extern JSBool +js_DoubleToECMAInt32(JSContext *cx, jsdouble d, int32 *ip); + +/* + * Convert a value or a double to a uint32, according to the ECMA rules + * for ToUint32. + */ +extern JSBool +js_ValueToECMAUint32(JSContext *cx, jsval v, uint32 *ip); + +extern JSBool +js_DoubleToECMAUint32(JSContext *cx, jsdouble d, uint32 *ip); + +/* + * Convert a value to a number, then to an int32 if it fits by rounding to + * nearest; but failing with an error report if the double is out of range + * or unordered. + */ +extern JSBool +js_ValueToInt32(JSContext *cx, jsval v, int32 *ip); + +/* + * Convert a value to a number, then to a uint16 according to the ECMA rules + * for ToUint16. + */ +extern JSBool +js_ValueToUint16(JSContext *cx, jsval v, uint16 *ip); + +/* + * Convert a jsdouble to an integral number, stored in a jsdouble. + * If d is NaN, return 0. If d is an infinity, return it without conversion. + */ +extern jsdouble +js_DoubleToInteger(jsdouble d); + +/* + * Similar to strtod except that it replaces overflows with infinities of the + * correct sign, and underflows with zeros of the correct sign. Guaranteed to + * return the closest double number to the given input in dp. + * + * Also allows inputs of the form [+|-]Infinity, which produce an infinity of + * the appropriate sign. The case of the "Infinity" string must match exactly. + * If the string does not contain a number, set *ep to s and return 0.0 in dp. + * Return false if out of memory. + */ +extern JSBool +js_strtod(JSContext *cx, const jschar *s, const jschar **ep, jsdouble *dp); + +/* + * Similar to strtol except that it handles integers of arbitrary size. + * Guaranteed to return the closest double number to the given input when radix + * is 10 or a power of 2. Callers may see round-off errors for very large + * numbers of a different radix than 10 or a power of 2. + * + * If the string does not contain a number, set *ep to s and return 0.0 in dp. + * Return false if out of memory. + */ +extern JSBool +js_strtointeger(JSContext *cx, const jschar *s, const jschar **ep, jsint radix, jsdouble *dp); + + +#ifdef XP_OS2 +/* XXX see bug 224487 + * On OS/2, some system function calls seem to change the FPU control word, + * such that we crash with a floating underflow exception. The FIX_FPU() call + * in jsnum.c does not always work, as sometimes FIX_FPU() is called BEFORE the + * OS/2 system call that horks the FPU control word. So, on OS/2, we need to do + * what the comment at the top of this file (around line 80) suggests: setting + * the FPU precision (& exceptions mask) before calling strtod or dtoa. Also, + * we play nice by reverting to the previous FPU control word at the end of + * those functions. + * + * Set the exception mask to mask all exceptions and set the FPU precision + * to 53 bit mantissa. + */ + #define SET_FPU() unsigned cw = _control87(0,0); \ + _control87((CW_DEFAULT & ~MCW_PC) | PC_53, 0xffff) + #define RESTORE_FPU() _control87(cw, MCW_EM | MCW_IC | MCW_RC | MCW_PC) +#else + #define SET_FPU() ((void)0) + #define RESTORE_FPU() ((void)0) +#endif + +JS_END_EXTERN_C + +#endif /* jsnum_h___ */ diff --git a/src/dom/js/jsobj.c b/src/dom/js/jsobj.c new file mode 100644 index 000000000..1da1f138b --- /dev/null +++ b/src/dom/js/jsobj.c @@ -0,0 +1,3900 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* + * JS object implementation. + */ +#include "jsstddef.h" +#include +#include +#include "jstypes.h" +#include "jsarena.h" /* Added by JSIFY */ +#include "jsutil.h" /* Added by JSIFY */ +#include "jshash.h" /* Added by JSIFY */ +#include "jsdhash.h" +#include "jsprf.h" +#include "jsapi.h" +#include "jsarray.h" +#include "jsatom.h" +#include "jsbool.h" +#include "jscntxt.h" +#include "jsconfig.h" +#include "jsfun.h" +#include "jsgc.h" +#include "jsinterp.h" +#include "jslock.h" +#include "jsnum.h" +#include "jsobj.h" +#include "jsscope.h" +#include "jsscript.h" +#include "jsstr.h" +#include "jsopcode.h" + +#include "jsdbgapi.h" /* whether or not JS_HAS_OBJ_WATCHPOINT */ + +#ifdef JS_THREADSAFE +#define NATIVE_DROP_PROPERTY js_DropProperty + +extern void +js_DropProperty(JSContext *cx, JSObject *obj, JSProperty *prop); +#else +#define NATIVE_DROP_PROPERTY NULL +#endif + +#ifdef XP_MAC +#pragma export on +#endif + +JS_FRIEND_DATA(JSObjectOps) js_ObjectOps = { + js_NewObjectMap, js_DestroyObjectMap, +#if defined JS_THREADSAFE && defined DEBUG + _js_LookupProperty, js_DefineProperty, +#else + js_LookupProperty, js_DefineProperty, +#endif + js_GetProperty, js_SetProperty, + js_GetAttributes, js_SetAttributes, + js_DeleteProperty, js_DefaultValue, + js_Enumerate, js_CheckAccess, + NULL, NATIVE_DROP_PROPERTY, + js_Call, js_Construct, + NULL, js_HasInstance, + js_SetProtoOrParent, js_SetProtoOrParent, + js_Mark, js_Clear, + js_GetRequiredSlot, js_SetRequiredSlot +}; + +#ifdef XP_MAC +#pragma export off +#endif + +JSClass js_ObjectClass = { + js_Object_str, + 0, + JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, + JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub, + JSCLASS_NO_OPTIONAL_MEMBERS +}; + +#if JS_HAS_OBJ_PROTO_PROP + +static JSBool +obj_getSlot(JSContext *cx, JSObject *obj, jsval id, jsval *vp); + +static JSBool +obj_setSlot(JSContext *cx, JSObject *obj, jsval id, jsval *vp); + +static JSBool +obj_getCount(JSContext *cx, JSObject *obj, jsval id, jsval *vp); + +static JSPropertySpec object_props[] = { + /* These two must come first; see object_props[slot].name usage below. */ + {js_proto_str, JSSLOT_PROTO, JSPROP_PERMANENT|JSPROP_SHARED, + obj_getSlot, obj_setSlot}, + {js_parent_str,JSSLOT_PARENT,JSPROP_READONLY|JSPROP_PERMANENT|JSPROP_SHARED, + obj_getSlot, obj_setSlot}, + {js_count_str, 0, JSPROP_PERMANENT,obj_getCount, obj_getCount}, + {0,0,0,0,0} +}; + +/* NB: JSSLOT_PROTO and JSSLOT_PARENT are already indexes into object_props. */ +#define JSSLOT_COUNT 2 + +static JSBool +ReportStrictSlot(JSContext *cx, uint32 slot) +{ + if (slot == JSSLOT_PROTO) + return JS_TRUE; + return JS_ReportErrorFlagsAndNumber(cx, + JSREPORT_WARNING | JSREPORT_STRICT, + js_GetErrorMessage, NULL, + JSMSG_DEPRECATED_USAGE, + object_props[slot].name); +} + +static JSBool +obj_getSlot(JSContext *cx, JSObject *obj, jsval id, jsval *vp) +{ + uint32 slot; + JSAccessMode mode; + uintN attrs; + + slot = (uint32) JSVAL_TO_INT(id); + if (JS_HAS_STRICT_OPTION(cx) && !ReportStrictSlot(cx, slot)) + return JS_FALSE; + if (id == INT_TO_JSVAL(JSSLOT_PROTO)) { + id = (jsid)cx->runtime->atomState.protoAtom; + mode = JSACC_PROTO; + } else { + id = (jsid)cx->runtime->atomState.parentAtom; + mode = JSACC_PARENT; + } + if (!OBJ_CHECK_ACCESS(cx, obj, id, mode, vp, &attrs)) + return JS_FALSE; + *vp = OBJ_GET_SLOT(cx, obj, slot); + return JS_TRUE; +} + +static JSBool +obj_setSlot(JSContext *cx, JSObject *obj, jsval id, jsval *vp) +{ + JSObject *pobj; + uint32 slot; + uintN attrs; + + if (!JSVAL_IS_OBJECT(*vp)) + return JS_TRUE; + pobj = JSVAL_TO_OBJECT(*vp); + slot = (uint32) JSVAL_TO_INT(id); + if (JS_HAS_STRICT_OPTION(cx) && !ReportStrictSlot(cx, slot)) + return JS_FALSE; + + /* __parent__ is readonly and permanent, only __proto__ may be set. */ + if (!OBJ_CHECK_ACCESS(cx, obj, id, JSACC_PROTO | JSACC_WRITE, vp, &attrs)) + return JS_FALSE; + + return js_SetProtoOrParent(cx, obj, slot, pobj); +} + +static JSBool +obj_getCount(JSContext *cx, JSObject *obj, jsval id, jsval *vp) +{ + jsval iter_state; + jsid num_properties; + JSBool ok; + + if (JS_HAS_STRICT_OPTION(cx) && !ReportStrictSlot(cx, JSSLOT_COUNT)) + return JS_FALSE; + + /* Get the number of properties to enumerate. */ + iter_state = JSVAL_NULL; + ok = OBJ_ENUMERATE(cx, obj, JSENUMERATE_INIT, &iter_state, &num_properties); + if (!ok) + goto out; + + if (!JSVAL_IS_INT(num_properties)) { + JS_ASSERT(0); + *vp = JSVAL_ZERO; + goto out; + } + *vp = num_properties; + +out: + if (iter_state != JSVAL_NULL) + ok = OBJ_ENUMERATE(cx, obj, JSENUMERATE_DESTROY, &iter_state, 0); + return ok; +} + +#else /* !JS_HAS_OBJ_PROTO_PROP */ + +#define object_props NULL + +#endif /* !JS_HAS_OBJ_PROTO_PROP */ + +JSBool +js_SetProtoOrParent(JSContext *cx, JSObject *obj, uint32 slot, JSObject *pobj) +{ + JSRuntime *rt; + JSObject *obj2, *oldproto; + JSScope *scope, *newscope; + + /* + * Serialize all proto and parent setting in order to detect cycles. + * We nest locks in this function, and only here, in the following orders: + * + * (1) rt->setSlotLock < pobj's scope lock; + * rt->setSlotLock < pobj's proto-or-parent's scope lock; + * rt->setSlotLock < pobj's grand-proto-or-parent's scope lock; + * etc... + * (2) rt->setSlotLock < obj's scope lock < pobj's scope lock. + * + * We avoid AB-BA deadlock by restricting obj from being on pobj's parent + * or proto chain (pobj may already be on obj's parent or proto chain; it + * could be moving up or down). We finally order obj with respect to pobj + * at the bottom of this routine (just before releasing rt->setSlotLock), + * by making pobj be obj's prototype or parent. + * + * After we have set the slot and released rt->setSlotLock, another call + * to js_SetProtoOrParent could nest locks according to the first order + * list above, but it cannot deadlock with any other thread. For there + * to be a deadlock, other parts of the engine would have to nest scope + * locks in the opposite order. XXXbe ensure they don't! + */ + rt = cx->runtime; +#ifdef JS_THREADSAFE + + JS_ACQUIRE_LOCK(rt->setSlotLock); + while (rt->setSlotBusy) { + jsrefcount saveDepth; + + /* Take pains to avoid nesting rt->gcLock inside rt->setSlotLock! */ + JS_RELEASE_LOCK(rt->setSlotLock); + saveDepth = JS_SuspendRequest(cx); + JS_ACQUIRE_LOCK(rt->setSlotLock); + if (rt->setSlotBusy) + JS_WAIT_CONDVAR(rt->setSlotDone, JS_NO_TIMEOUT); + JS_RELEASE_LOCK(rt->setSlotLock); + JS_ResumeRequest(cx, saveDepth); + JS_ACQUIRE_LOCK(rt->setSlotLock); + } + rt->setSlotBusy = JS_TRUE; + JS_RELEASE_LOCK(rt->setSlotLock); + +#define SET_SLOT_DONE(rt) \ + JS_BEGIN_MACRO \ + JS_ACQUIRE_LOCK((rt)->setSlotLock); \ + (rt)->setSlotBusy = JS_FALSE; \ + JS_NOTIFY_ALL_CONDVAR((rt)->setSlotDone); \ + JS_RELEASE_LOCK((rt)->setSlotLock); \ + JS_END_MACRO + +#else + +#define SET_SLOT_DONE(rt) /* nothing */ + +#endif + + obj2 = pobj; + while (obj2) { + if (obj2 == obj) { + SET_SLOT_DONE(rt); + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, + JSMSG_CYCLIC_VALUE, +#if JS_HAS_OBJ_PROTO_PROP + object_props[slot].name +#else + (slot == JSSLOT_PROTO) ? js_proto_str + : js_parent_str +#endif + ); + return JS_FALSE; + } + obj2 = JSVAL_TO_OBJECT(OBJ_GET_SLOT(cx, obj2, slot)); + } + + if (slot == JSSLOT_PROTO && OBJ_IS_NATIVE(obj)) { + /* Check to see whether obj shares its prototype's scope. */ + JS_LOCK_OBJ(cx, obj); + scope = OBJ_SCOPE(obj); + oldproto = JSVAL_TO_OBJECT(LOCKED_OBJ_GET_SLOT(obj, JSSLOT_PROTO)); + if (oldproto && OBJ_SCOPE(oldproto) == scope) { + /* Either obj needs a new empty scope, or it should share pobj's. */ + if (!pobj || + !OBJ_IS_NATIVE(pobj) || + OBJ_GET_CLASS(cx, pobj) != LOCKED_OBJ_GET_CLASS(oldproto)) { + /* + * With no proto and no scope of its own, obj is truly empty. + * + * If pobj is not native, obj needs its own empty scope -- it + * should not continue to share oldproto's scope once oldproto + * is not on obj's prototype chain. That would put properties + * from oldproto's scope ahead of properties defined by pobj, + * in lookup order. + * + * If pobj's class differs from oldproto's, we may need a new + * scope to handle differences in private and reserved slots, + * so we suboptimally but safely make one. + */ + scope = js_GetMutableScope(cx, obj); + if (!scope) { + JS_UNLOCK_OBJ(cx, obj); + SET_SLOT_DONE(rt); + return JS_FALSE; + } + } else if (OBJ_SCOPE(pobj) != scope) { +#ifdef JS_THREADSAFE + /* + * We are about to nest scope locks. Help jslock.c:ShareScope + * keep scope->u.count balanced for the JS_UNLOCK_SCOPE, while + * avoiding deadlock, by recording scope in rt->setSlotScope. + */ + if (scope->ownercx) { + JS_ASSERT(scope->ownercx == cx); + rt->setSlotScope = scope; + } +#endif + + /* We can't deadlock because we checked for cycles above (2). */ + JS_LOCK_OBJ(cx, pobj); + newscope = (JSScope *) js_HoldObjectMap(cx, pobj->map); + obj->map = &newscope->map; + js_DropObjectMap(cx, &scope->map, obj); + JS_TRANSFER_SCOPE_LOCK(cx, scope, newscope); + scope = newscope; +#ifdef JS_THREADSAFE + rt->setSlotScope = NULL; +#endif + } + } + LOCKED_OBJ_SET_SLOT(obj, JSSLOT_PROTO, OBJECT_TO_JSVAL(pobj)); + JS_UNLOCK_SCOPE(cx, scope); + } else { + OBJ_SET_SLOT(cx, obj, slot, OBJECT_TO_JSVAL(pobj)); + } + + SET_SLOT_DONE(rt); + return JS_TRUE; + +#undef SET_SLOT_DONE +} + +JS_STATIC_DLL_CALLBACK(JSHashNumber) +js_hash_object(const void *key) +{ + return (JSHashNumber)key >> JSVAL_TAGBITS; +} + +static JSHashEntry * +MarkSharpObjects(JSContext *cx, JSObject *obj, JSIdArray **idap) +{ + JSSharpObjectMap *map; + JSHashTable *table; + JSHashNumber hash; + JSHashEntry **hep, *he; + jsatomid sharpid; + JSIdArray *ida; + JSBool ok; + jsint i, length; + jsid id; +#if JS_HAS_GETTER_SETTER + JSObject *obj2; + JSProperty *prop; + uintN attrs; +#endif + jsval val; + + map = &cx->sharpObjectMap; + table = map->table; + hash = js_hash_object(obj); + hep = JS_HashTableRawLookup(table, hash, obj); + he = *hep; + if (!he) { + sharpid = 0; + he = JS_HashTableRawAdd(table, hep, hash, obj, (void *)sharpid); + if (!he) { + JS_ReportOutOfMemory(cx); + return NULL; + } + ida = JS_Enumerate(cx, obj); + if (!ida) + return NULL; + ok = JS_TRUE; + for (i = 0, length = ida->length; i < length; i++) { + id = ida->vector[i]; +#if JS_HAS_GETTER_SETTER + ok = OBJ_LOOKUP_PROPERTY(cx, obj, id, &obj2, &prop); + if (!ok) + break; + if (prop) { + ok = OBJ_GET_ATTRIBUTES(cx, obj2, id, prop, &attrs); + if (ok) { + if (OBJ_IS_NATIVE(obj2) && + (attrs & (JSPROP_GETTER | JSPROP_SETTER))) { + val = JSVAL_NULL; + if (attrs & JSPROP_GETTER) + val = (jsval) ((JSScopeProperty*)prop)->getter; + if (attrs & JSPROP_SETTER) { + if (val != JSVAL_NULL) { + /* Mark the getter, then set val to setter. */ + ok = (MarkSharpObjects(cx, JSVAL_TO_OBJECT(val), + NULL) + != NULL); + } + val = (jsval) ((JSScopeProperty*)prop)->setter; + } + } else { + ok = OBJ_GET_PROPERTY(cx, obj, id, &val); + } + } + OBJ_DROP_PROPERTY(cx, obj2, prop); + } +#else + ok = OBJ_GET_PROPERTY(cx, obj, id, &val); +#endif + if (!ok) + break; + if (!JSVAL_IS_PRIMITIVE(val) && + !MarkSharpObjects(cx, JSVAL_TO_OBJECT(val), NULL)) { + ok = JS_FALSE; + break; + } + } + if (!ok || !idap) + JS_DestroyIdArray(cx, ida); + if (!ok) + return NULL; + } else { + sharpid = (jsatomid) he->value; + if (sharpid == 0) { + sharpid = ++map->sharpgen << SHARP_ID_SHIFT; + he->value = (void *) sharpid; + } + ida = NULL; + } + if (idap) + *idap = ida; + return he; +} + +JSHashEntry * +js_EnterSharpObject(JSContext *cx, JSObject *obj, JSIdArray **idap, + jschar **sp) +{ + JSSharpObjectMap *map; + JSHashTable *table; + JSIdArray *ida; + JSHashNumber hash; + JSHashEntry *he, **hep; + jsatomid sharpid; + char buf[20]; + size_t len; + + /* Set to null in case we return an early error. */ + *sp = NULL; + map = &cx->sharpObjectMap; + table = map->table; + if (!table) { + table = JS_NewHashTable(8, js_hash_object, JS_CompareValues, + JS_CompareValues, NULL, NULL); + if (!table) { + JS_ReportOutOfMemory(cx); + return NULL; + } + map->table = table; + } + + ida = NULL; + if (map->depth == 0) { + he = MarkSharpObjects(cx, obj, &ida); + if (!he) + goto bad; + JS_ASSERT((((jsatomid) he->value) & SHARP_BIT) == 0); + if (!idap) { + JS_DestroyIdArray(cx, ida); + ida = NULL; + } + } else { + hash = js_hash_object(obj); + hep = JS_HashTableRawLookup(table, hash, obj); + he = *hep; + + /* + * It's possible that the value of a property has changed from the + * first time the object's properties are traversed (when the property + * ids are entered into the hash table) to the second (when they are + * converted to strings), i.e., the OBJ_GET_PROPERTY() call is not + * idempotent. + */ + if (!he) { + he = JS_HashTableRawAdd(table, hep, hash, obj, NULL); + if (!he) { + JS_ReportOutOfMemory(cx); + goto bad; + } + *sp = NULL; + sharpid = 0; + goto out; + } + } + + sharpid = (jsatomid) he->value; + if (sharpid == 0) { + *sp = NULL; + } else { + len = JS_snprintf(buf, sizeof buf, "#%u%c", + sharpid >> SHARP_ID_SHIFT, + (sharpid & SHARP_BIT) ? '#' : '='); + *sp = js_InflateString(cx, buf, len); + if (!*sp) { + if (ida) + JS_DestroyIdArray(cx, ida); + goto bad; + } + } + +out: + JS_ASSERT(he); + if ((sharpid & SHARP_BIT) == 0) { + if (idap && !ida) { + ida = JS_Enumerate(cx, obj); + if (!ida) { + if (*sp) { + JS_free(cx, *sp); + *sp = NULL; + } + goto bad; + } + } + map->depth++; + } + + if (idap) + *idap = ida; + return he; + +bad: + /* Clean up the sharpObjectMap table on outermost error. */ + if (map->depth == 0) { + map->sharpgen = 0; + JS_HashTableDestroy(map->table); + map->table = NULL; + } + return NULL; +} + +void +js_LeaveSharpObject(JSContext *cx, JSIdArray **idap) +{ + JSSharpObjectMap *map; + JSIdArray *ida; + + map = &cx->sharpObjectMap; + JS_ASSERT(map->depth > 0); + if (--map->depth == 0) { + map->sharpgen = 0; + JS_HashTableDestroy(map->table); + map->table = NULL; + } + if (idap) { + ida = *idap; + if (ida) { + JS_DestroyIdArray(cx, ida); + *idap = NULL; + } + } +} + +#define OBJ_TOSTRING_EXTRA 3 /* for 3 local GC roots */ + +#if JS_HAS_INITIALIZERS || JS_HAS_TOSOURCE +JSBool +js_obj_toSource(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval) +{ + JSBool ok, outermost; + JSHashEntry *he; + JSIdArray *ida; + jschar *chars, *ochars, *vsharp; + const jschar *idstrchars, *vchars; + size_t nchars, idstrlength, gsoplength, vlength, vsharplength; + char *comma; + jsint i, j, length, valcnt; + jsid id; +#if JS_HAS_GETTER_SETTER + JSObject *obj2; + JSProperty *prop; + uintN attrs; +#endif + jsval val[2]; + JSString *gsop[2]; + JSAtom *atom; + JSString *idstr, *valstr, *str; + int stackDummy; + + if (!JS_CHECK_STACK_SIZE(cx, stackDummy)) { + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_OVER_RECURSED); + return JS_FALSE; + } + + /* + * obj_toString for 1.2 calls toSource, and doesn't want the extra parens + * on the outside. + */ + outermost = (cx->version != JSVERSION_1_2 && cx->sharpObjectMap.depth == 0); + he = js_EnterSharpObject(cx, obj, &ida, &chars); + if (!he) + return JS_FALSE; + if (IS_SHARP(he)) { + /* + * We didn't enter -- obj is already "sharp", meaning we've visited it + * already in our depth first search, and therefore chars contains a + * string of the form "#n#". + */ + JS_ASSERT(!ida); +#if JS_HAS_SHARP_VARS + nchars = js_strlen(chars); +#else + chars[0] = '{'; + chars[1] = '}'; + chars[2] = 0; + nchars = 2; +#endif + goto make_string; + } + JS_ASSERT(ida); + ok = JS_TRUE; + + if (!chars) { + /* If outermost, allocate 4 + 1 for "({})" and the terminator. */ + chars = (jschar *) malloc(((outermost ? 4 : 2) + 1) * sizeof(jschar)); + nchars = 0; + if (!chars) + goto error; + if (outermost) + chars[nchars++] = '('; + } else { + /* js_EnterSharpObject returned a string of the form "#n=" in chars. */ + MAKE_SHARP(he); + nchars = js_strlen(chars); + chars = (jschar *) + realloc((ochars = chars), (nchars + 2 + 1) * sizeof(jschar)); + if (!chars) { + free(ochars); + goto error; + } + if (outermost) { + /* + * No need for parentheses around the whole shebang, because #n= + * unambiguously begins an object initializer, and never a block + * statement. + */ + outermost = JS_FALSE; + } + } + + chars[nchars++] = '{'; + + comma = NULL; + + for (i = 0, length = ida->length; i < length; i++) { + /* Get strings for id and value and GC-root them via argv. */ + id = ida->vector[i]; + +#if JS_HAS_GETTER_SETTER + + ok = OBJ_LOOKUP_PROPERTY(cx, obj, id, &obj2, &prop); + if (!ok) + goto error; + valcnt = 0; + if (prop) { + ok = OBJ_GET_ATTRIBUTES(cx, obj2, id, prop, &attrs); + if (!ok) { + OBJ_DROP_PROPERTY(cx, obj2, prop); + goto error; + } + if (OBJ_IS_NATIVE(obj2) && + (attrs & (JSPROP_GETTER | JSPROP_SETTER))) { + if (attrs & JSPROP_GETTER) { + val[valcnt] = (jsval) ((JSScopeProperty *)prop)->getter; +#ifdef OLD_GETTER_SETTER + gsop[valcnt] = + ATOM_TO_STRING(cx->runtime->atomState.getterAtom); +#else + gsop[valcnt] = + ATOM_TO_STRING(cx->runtime->atomState.getAtom); +#endif + valcnt++; + } + if (attrs & JSPROP_SETTER) { + val[valcnt] = (jsval) ((JSScopeProperty *)prop)->setter; +#ifdef OLD_GETTER_SETTER + gsop[valcnt] = + ATOM_TO_STRING(cx->runtime->atomState.setterAtom); +#else + gsop[valcnt] = + ATOM_TO_STRING(cx->runtime->atomState.setAtom); +#endif + valcnt++; + } + } else { + valcnt = 1; + gsop[0] = NULL; + ok = OBJ_GET_PROPERTY(cx, obj, id, &val[0]); + } + OBJ_DROP_PROPERTY(cx, obj2, prop); + } + +#else /* !JS_HAS_GETTER_SETTER */ + + valcnt = 1; + gsop[0] = NULL; + ok = OBJ_GET_PROPERTY(cx, obj, id, &val[0]); + +#endif /* !JS_HAS_GETTER_SETTER */ + + if (!ok) + goto error; + + /* Convert id to a jsval and then to a string. */ + atom = JSVAL_IS_INT(id) ? NULL : (JSAtom *)id; + id = ID_TO_VALUE(id); + idstr = js_ValueToString(cx, id); + if (!idstr) { + ok = JS_FALSE; + goto error; + } + argv[0] = STRING_TO_JSVAL(idstr); + + /* + * If id is a string that's a reserved identifier, or else id is not + * an identifier at all, then it needs to be quoted. + */ + if (atom && (ATOM_KEYWORD(atom) || !js_IsIdentifier(idstr))) { + idstr = js_QuoteString(cx, idstr, (jschar)'\''); + if (!idstr) { + ok = JS_FALSE; + goto error; + } + argv[0] = STRING_TO_JSVAL(idstr); + } + idstrchars = JSSTRING_CHARS(idstr); + idstrlength = JSSTRING_LENGTH(idstr); + + for (j = 0; j < valcnt; j++) { + /* Convert val[j] to its canonical source form. */ + valstr = js_ValueToSource(cx, val[j]); + if (!valstr) { + ok = JS_FALSE; + goto error; + } + argv[1+j] = STRING_TO_JSVAL(valstr); + vchars = JSSTRING_CHARS(valstr); + vlength = JSSTRING_LENGTH(valstr); + +#ifndef OLD_GETTER_SETTER + /* Remove 'function ' from beginning of valstr. */ + if (gsop[j]) { + int n = strlen(js_function_str) + 1; + vchars += n; + vlength -= n; + } +#endif + + /* If val[j] is a non-sharp object, consider sharpening it. */ + vsharp = NULL; + vsharplength = 0; +#if JS_HAS_SHARP_VARS + if (!JSVAL_IS_PRIMITIVE(val[j]) && vchars[0] != '#') { + he = js_EnterSharpObject(cx, JSVAL_TO_OBJECT(val[j]), NULL, + &vsharp); + if (!he) { + ok = JS_FALSE; + goto error; + } + if (IS_SHARP(he)) { + vchars = vsharp; + vlength = js_strlen(vchars); + } else { + if (vsharp) { + vsharplength = js_strlen(vsharp); + MAKE_SHARP(he); + } + js_LeaveSharpObject(cx, NULL); + } + } +#endif + + /* Allocate 1 + 1 at end for closing brace and terminating 0. */ + chars = (jschar *) + realloc((ochars = chars), + (nchars + (comma ? 2 : 0) + + idstrlength + 1 + + (gsop[j] ? 1 + JSSTRING_LENGTH(gsop[j]) : 0) + + vsharplength + vlength + + (outermost ? 2 : 1) + 1) * sizeof(jschar)); + if (!chars) { + /* Save code space on error: let JS_free ignore null vsharp. */ + JS_free(cx, vsharp); + free(ochars); + goto error; + } + + if (comma) { + chars[nchars++] = comma[0]; + chars[nchars++] = comma[1]; + } + comma = ", "; + +#ifdef OLD_GETTER_SETTER + js_strncpy(&chars[nchars], idstrchars, idstrlength); + nchars += idstrlength; + if (gsop[j]) { + chars[nchars++] = ' '; + gsoplength = JSSTRING_LENGTH(gsop[j]); + js_strncpy(&chars[nchars], JSSTRING_CHARS(gsop[j]), gsoplength); + nchars += gsoplength; + } + chars[nchars++] = ':'; +#else + if (gsop[j]) { + gsoplength = JSSTRING_LENGTH(gsop[j]); + js_strncpy(&chars[nchars], JSSTRING_CHARS(gsop[j]), gsoplength); + nchars += gsoplength; + chars[nchars++] = ' '; + } + js_strncpy(&chars[nchars], idstrchars, idstrlength); + nchars += idstrlength; + if (!gsop[j]) + chars[nchars++] = ':'; +#endif + if (vsharplength) { + js_strncpy(&chars[nchars], vsharp, vsharplength); + nchars += vsharplength; + } + js_strncpy(&chars[nchars], vchars, vlength); + nchars += vlength; + + if (vsharp) + JS_free(cx, vsharp); + } + } + + chars[nchars++] = '}'; + if (outermost) + chars[nchars++] = ')'; + chars[nchars] = 0; + + error: + js_LeaveSharpObject(cx, &ida); + + if (!ok) { + if (chars) + free(chars); + return ok; + } + + if (!chars) { + JS_ReportOutOfMemory(cx); + return JS_FALSE; + } + make_string: + str = js_NewString(cx, chars, nchars, 0); + if (!str) { + free(chars); + return JS_FALSE; + } + *rval = STRING_TO_JSVAL(str); + return JS_TRUE; +} +#endif /* JS_HAS_INITIALIZERS || JS_HAS_TOSOURCE */ + +JSBool +js_obj_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval) +{ + jschar *chars; + size_t nchars; + const char *clazz, *prefix; + JSString *str; + +#if JS_HAS_INITIALIZERS + if (cx->version == JSVERSION_1_2) + return js_obj_toSource(cx, obj, argc, argv, rval); +#endif + + clazz = OBJ_GET_CLASS(cx, obj)->name; + nchars = 9 + strlen(clazz); /* 9 for "[object ]" */ + chars = (jschar *) JS_malloc(cx, (nchars + 1) * sizeof(jschar)); + if (!chars) + return JS_FALSE; + + prefix = "[object "; + nchars = 0; + while ((chars[nchars] = (jschar)*prefix) != 0) + nchars++, prefix++; + while ((chars[nchars] = (jschar)*clazz) != 0) + nchars++, clazz++; + chars[nchars++] = ']'; + chars[nchars] = 0; + + str = js_NewString(cx, chars, nchars, 0); + if (!str) { + JS_free(cx, chars); + return JS_FALSE; + } + *rval = STRING_TO_JSVAL(str); + return JS_TRUE; +} + +static JSBool +obj_valueOf(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + *rval = OBJECT_TO_JSVAL(obj); + return JS_TRUE; +} + +static JSBool +obj_eval(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + JSStackFrame *fp, *caller; + JSBool indirectCall; + JSObject *scopeobj; + JSString *str; + const char *file; + uintN line; + JSPrincipals *principals; + JSScript *script; + JSBool ok; +#if JS_HAS_EVAL_THIS_SCOPE + JSObject *callerScopeChain = NULL, *callerVarObj = NULL; + JSBool setCallerScopeChain = JS_FALSE, setCallerVarObj = JS_FALSE; +#endif + + fp = cx->fp; + caller = JS_GetScriptedCaller(cx, fp); + indirectCall = (caller && caller->pc && *caller->pc != JSOP_EVAL); + + if (JSVERSION_IS_ECMA(cx->version) && + indirectCall && + !JS_ReportErrorFlagsAndNumber(cx, + JSREPORT_WARNING | JSREPORT_STRICT, + js_GetErrorMessage, NULL, + JSMSG_BAD_INDIRECT_CALL, + js_eval_str)) { + return JS_FALSE; + } + + if (!JSVAL_IS_STRING(argv[0])) { + *rval = argv[0]; + return JS_TRUE; + } + +#if JS_HAS_SCRIPT_OBJECT + /* + * Script.prototype.compile/exec and Object.prototype.eval all take an + * optional trailing argument that overrides the scope object. + */ + scopeobj = NULL; + if (argc >= 2) { + if (!js_ValueToObject(cx, argv[1], &scopeobj)) + return JS_FALSE; + argv[1] = OBJECT_TO_JSVAL(scopeobj); + } + if (!scopeobj) +#endif + { +#if JS_HAS_EVAL_THIS_SCOPE + /* If obj.eval(str), emulate 'with (obj) eval(str)' in the caller. */ + if (indirectCall) { + callerScopeChain = caller->scopeChain; + if (obj != callerScopeChain) { + scopeobj = js_NewObject(cx, &js_WithClass, obj, + callerScopeChain); + if (!scopeobj) + return JS_FALSE; + + /* Set fp->scopeChain too, for the compiler. */ + caller->scopeChain = fp->scopeChain = scopeobj; + setCallerScopeChain = JS_TRUE; + } + + callerVarObj = caller->varobj; + if (obj != callerVarObj) { + /* Set fp->varobj too, for the compiler. */ + caller->varobj = fp->varobj = obj; + setCallerVarObj = JS_TRUE; + } + } + /* From here on, control must exit through label out with ok set. */ +#endif + +#if JS_BUG_EVAL_THIS_SCOPE + /* An old version used the object in which eval was found for scope. */ + scopeobj = obj; +#else + /* Compile using caller's current scope object. */ + if (caller) + scopeobj = caller->scopeChain; +#endif + } + + str = JSVAL_TO_STRING(argv[0]); + if (caller) { + file = caller->script->filename; + line = js_PCToLineNumber(cx, caller->script, caller->pc); + principals = JS_EvalFramePrincipals(cx, fp, caller); + } else { + file = NULL; + line = 0; + principals = NULL; + } + + /* XXXbe set only for the compiler, which does not currently test it */ + fp->flags |= JSFRAME_EVAL; + script = JS_CompileUCScriptForPrincipals(cx, scopeobj, principals, + JSSTRING_CHARS(str), + JSSTRING_LENGTH(str), + file, line); + if (!script) { + ok = JS_FALSE; + goto out; + } + +#if !JS_BUG_EVAL_THIS_SCOPE +#if JS_HAS_SCRIPT_OBJECT + if (argc < 2) +#endif + { + /* Execute using caller's new scope object (might be a Call object). */ + if (caller) + scopeobj = caller->scopeChain; + } +#endif + ok = js_Execute(cx, scopeobj, script, caller, JSFRAME_EVAL, rval); + JS_DestroyScript(cx, script); + +out: +#if JS_HAS_EVAL_THIS_SCOPE + /* Restore OBJ_GET_PARENT(scopeobj) not callerScopeChain in case of Call. */ + if (setCallerScopeChain) + caller->scopeChain = callerScopeChain; + if (setCallerVarObj) + caller->varobj = callerVarObj; +#endif + return ok; +} + +JS_STATIC_DLL_CALLBACK(const void *) +resolving_GetKey(JSDHashTable *table, JSDHashEntryHdr *hdr) +{ + JSResolvingEntry *entry = (JSResolvingEntry *)hdr; + + return &entry->key; +} + +JS_STATIC_DLL_CALLBACK(JSDHashNumber) +resolving_HashKey(JSDHashTable *table, const void *ptr) +{ + const JSResolvingKey *key = (const JSResolvingKey *)ptr; + + return ((JSDHashNumber)key->obj >> JSVAL_TAGBITS) ^ key->id; +} + +JS_PUBLIC_API(JSBool) +resolving_MatchEntry(JSDHashTable *table, + const JSDHashEntryHdr *hdr, + const void *ptr) +{ + const JSResolvingEntry *entry = (const JSResolvingEntry *)hdr; + const JSResolvingKey *key = (const JSResolvingKey *)ptr; + + return entry->key.obj == key->obj && entry->key.id == key->id; +} + +static const JSDHashTableOps resolving_dhash_ops = { + JS_DHashAllocTable, + JS_DHashFreeTable, + resolving_GetKey, + resolving_HashKey, + resolving_MatchEntry, + JS_DHashMoveEntryStub, + JS_DHashClearEntryStub, + JS_DHashFinalizeStub, + NULL +}; + +static JSBool +StartResolving(JSContext *cx, JSResolvingKey *key, uint32 flag, + JSResolvingEntry **entryp) +{ + JSDHashTable *table; + JSResolvingEntry *entry; + + table = cx->resolvingTable; + if (!table) { + table = JS_NewDHashTable(&resolving_dhash_ops, NULL, + sizeof(JSResolvingEntry), + JS_DHASH_MIN_SIZE); + if (!table) + goto outofmem; + cx->resolvingTable = table; + } + + entry = (JSResolvingEntry *) + JS_DHashTableOperate(table, key, JS_DHASH_ADD); + if (!entry) + goto outofmem; + + if (entry->flags & flag) { + /* An entry for (key, flag) exists already -- dampen recursion. */ + entry = NULL; + } else { + /* Fill in key if we were the first to add entry, then set flag. */ + if (!entry->key.obj) + entry->key = *key; + entry->flags |= flag; + } + *entryp = entry; + return JS_TRUE; + +outofmem: + JS_ReportOutOfMemory(cx); + return JS_FALSE; +} + +static void +StopResolving(JSContext *cx, JSResolvingKey *key, uint32 flag, + JSResolvingEntry *entry, uint32 generation) +{ + JSDHashTable *table; + + /* + * Clear flag from entry->flags and return early if other flags remain. + * We must take care to re-lookup entry if the table has changed since + * it was found by StartResolving. + */ + table = cx->resolvingTable; + if (table->generation != generation) { + entry = (JSResolvingEntry *) + JS_DHashTableOperate(table, key, JS_DHASH_LOOKUP); + } + entry->flags &= ~flag; + if (entry->flags) + return; + + /* + * Do a raw remove only if fewer entries were removed than would cause + * alpha to be less than .5 (alpha is at most .75). Otherwise, we just + * call JS_DHashTableOperate to re-lookup the key and remove its entry, + * compressing or shrinking the table as needed. + */ + if (table->removedCount < JS_DHASH_TABLE_SIZE(table) >> 2) + JS_DHashTableRawRemove(table, &entry->hdr); + else + JS_DHashTableOperate(table, key, JS_DHASH_REMOVE); +} + +#if JS_HAS_OBJ_WATCHPOINT + +static JSBool +obj_watch_handler(JSContext *cx, JSObject *obj, jsval id, jsval old, jsval *nvp, + void *closure) +{ + JSResolvingKey key; + JSResolvingEntry *entry; + uint32 generation; + JSObject *funobj; + jsval argv[3]; + JSBool ok; + + /* Avoid recursion on (obj, id) already being watched on cx. */ + key.obj = obj; + key.id = id; + if (!StartResolving(cx, &key, JSRESFLAG_WATCH, &entry)) + return JS_FALSE; + if (!entry) + return JS_TRUE; + generation = cx->resolvingTable->generation; + + funobj = (JSObject *) closure; + argv[0] = id; + argv[1] = old; + argv[2] = *nvp; + ok = js_InternalCall(cx, obj, OBJECT_TO_JSVAL(funobj), 3, argv, nvp); + StopResolving(cx, &key, JSRESFLAG_WATCH, entry, generation); + return ok; +} + +static JSBool +obj_watch(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + JSFunction *fun; + jsval userid, value; + jsid propid; + uintN attrs; + + fun = js_ValueToFunction(cx, &argv[1], 0); + if (!fun) + return JS_FALSE; + argv[1] = OBJECT_TO_JSVAL(fun->object); + + /* Compute the unique int/atom symbol id needed by js_LookupProperty. */ + userid = argv[0]; + if (!JS_ValueToId(cx, userid, &propid)) + return JS_FALSE; + + if (!OBJ_CHECK_ACCESS(cx, obj, propid, JSACC_WATCH, &value, &attrs)) + return JS_FALSE; + if (attrs & JSPROP_READONLY) + return JS_TRUE; + return JS_SetWatchPoint(cx, obj, userid, obj_watch_handler, fun->object); +} + +static JSBool +obj_unwatch(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + return JS_ClearWatchPoint(cx, obj, argv[0], NULL, NULL); +} + +#endif /* JS_HAS_OBJ_WATCHPOINT */ + +#if JS_HAS_NEW_OBJ_METHODS +/* + * Prototype and property query methods, to complement the 'in' and + * 'instanceof' operators. + */ + +/* Proposed ECMA 15.2.4.5. */ +static JSBool +obj_hasOwnProperty(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval) +{ + jsid id; + JSObject *obj2; + JSProperty *prop; + JSScopeProperty *sprop; + + if (!JS_ValueToId(cx, argv[0], &id)) + return JS_FALSE; + if (!OBJ_LOOKUP_PROPERTY(cx, obj, id, &obj2, &prop)) + return JS_FALSE; + if (!prop) { + *rval = JSVAL_FALSE; + } else if (obj2 == obj) { + *rval = JSVAL_TRUE; + } else if (OBJ_IS_NATIVE(obj2)) { + sprop = (JSScopeProperty *)prop; + *rval = BOOLEAN_TO_JSVAL(SPROP_IS_SHARED_PERMANENT(sprop)); + } else { + *rval = JSVAL_FALSE; + } + if (prop) + OBJ_DROP_PROPERTY(cx, obj2, prop); + return JS_TRUE; +} + +/* Proposed ECMA 15.2.4.6. */ +static JSBool +obj_isPrototypeOf(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval) +{ + JSBool b; + + if (!js_IsDelegate(cx, obj, *argv, &b)) + return JS_FALSE; + *rval = BOOLEAN_TO_JSVAL(b); + return JS_TRUE; +} + +/* Proposed ECMA 15.2.4.7. */ +static JSBool +obj_propertyIsEnumerable(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval) +{ + jsid id; + uintN attrs; + JSObject *obj2; + JSProperty *prop; + JSBool ok; + + if (!JS_ValueToId(cx, argv[0], &id)) + return JS_FALSE; + + if (!OBJ_LOOKUP_PROPERTY(cx, obj, id, &obj2, &prop)) + return JS_FALSE; + + if (!prop) { + *rval = JSVAL_FALSE; + return JS_TRUE; + } + + /* + * XXX ECMA spec error compatible: return false unless hasOwnProperty. + * The ECMA spec really should be fixed so propertyIsEnumerable and the + * for..in loop agree on whether prototype properties are enumerable, + * obviously by fixing this method (not by breaking the for..in loop!). + * + * We check here for shared permanent prototype properties, which should + * be treated as if they are local to obj. They are an implementation + * technique used to satisfy ECMA requirements; users should not be able + * to distinguish a shared permanent proto-property from a local one. + */ + if (obj2 != obj && + !(OBJ_IS_NATIVE(obj2) && + SPROP_IS_SHARED_PERMANENT((JSScopeProperty *)prop))) { + OBJ_DROP_PROPERTY(cx, obj2, prop); + *rval = JSVAL_FALSE; + return JS_TRUE; + } + + ok = OBJ_GET_ATTRIBUTES(cx, obj2, id, prop, &attrs); + OBJ_DROP_PROPERTY(cx, obj2, prop); + if (ok) + *rval = BOOLEAN_TO_JSVAL((attrs & JSPROP_ENUMERATE) != 0); + return ok; +} +#endif /* JS_HAS_NEW_OBJ_METHODS */ + +#if JS_HAS_GETTER_SETTER +static JSBool +obj_defineGetter(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval) +{ + jsval fval, junk; + jsid id; + JSBool found; + uintN attrs; + + fval = argv[1]; + if (JS_TypeOfValue(cx, fval) != JSTYPE_FUNCTION) { + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, + JSMSG_BAD_GETTER_OR_SETTER, + js_getter_str); + return JS_FALSE; + } + + if (!JS_ValueToId(cx, argv[0], &id)) + return JS_FALSE; + if (!js_CheckRedeclaration(cx, obj, id, JSPROP_GETTER, &found)) + return JS_FALSE; + /* + * Getters and setters are just like watchpoints from an access + * control point of view. + */ + if (!OBJ_CHECK_ACCESS(cx, obj, id, JSACC_WATCH, &junk, &attrs)) + return JS_FALSE; + return OBJ_DEFINE_PROPERTY(cx, obj, id, JSVAL_VOID, + (JSPropertyOp) JSVAL_TO_OBJECT(fval), NULL, + JSPROP_GETTER | JSPROP_SHARED, NULL); +} + +static JSBool +obj_defineSetter(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval) +{ + jsval fval, junk; + jsid id; + JSBool found; + uintN attrs; + + fval = argv[1]; + if (JS_TypeOfValue(cx, fval) != JSTYPE_FUNCTION) { + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, + JSMSG_BAD_GETTER_OR_SETTER, + js_setter_str); + return JS_FALSE; + } + + if (!JS_ValueToId(cx, argv[0], &id)) + return JS_FALSE; + if (!js_CheckRedeclaration(cx, obj, id, JSPROP_SETTER, &found)) + return JS_FALSE; + /* + * Getters and setters are just like watchpoints from an access + * control point of view. + */ + if (!OBJ_CHECK_ACCESS(cx, obj, id, JSACC_WATCH, &junk, &attrs)) + return JS_FALSE; + return OBJ_DEFINE_PROPERTY(cx, obj, id, JSVAL_VOID, + NULL, (JSPropertyOp) JSVAL_TO_OBJECT(fval), + JSPROP_SETTER | JSPROP_SHARED, NULL); +} + +static JSBool +obj_lookupGetter(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval) +{ + jsid id; + JSObject *pobj; + JSScopeProperty *sprop; + + if (!JS_ValueToId(cx, argv[0], &id)) + return JS_FALSE; + if (!OBJ_LOOKUP_PROPERTY(cx, obj, id, &pobj, (JSProperty **) &sprop)) + return JS_FALSE; + if (sprop) { + if (sprop->attrs & JSPROP_GETTER) + *rval = OBJECT_TO_JSVAL(sprop->getter); + OBJ_DROP_PROPERTY(cx, pobj, (JSProperty *)sprop); + } + return JS_TRUE; +} + +static JSBool +obj_lookupSetter(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval) +{ + jsid id; + JSObject *pobj; + JSScopeProperty *sprop; + + if (!JS_ValueToId(cx, argv[0], &id)) + return JS_FALSE; + if (!OBJ_LOOKUP_PROPERTY(cx, obj, id, &pobj, (JSProperty **) &sprop)) + return JS_FALSE; + if (sprop) { + if (sprop->attrs & JSPROP_SETTER) + *rval = OBJECT_TO_JSVAL(sprop->setter); + OBJ_DROP_PROPERTY(cx, pobj, (JSProperty *)sprop); + } + return JS_TRUE; +} +#endif /* JS_HAS_GETTER_SETTER */ + +#if JS_HAS_OBJ_WATCHPOINT +const char js_watch_str[] = "watch"; +const char js_unwatch_str[] = "unwatch"; +#endif +#if JS_HAS_NEW_OBJ_METHODS +const char js_hasOwnProperty_str[] = "hasOwnProperty"; +const char js_isPrototypeOf_str[] = "isPrototypeOf"; +const char js_propertyIsEnumerable_str[] = "propertyIsEnumerable"; +#endif +#if JS_HAS_GETTER_SETTER +const char js_defineGetter_str[] = "__defineGetter__"; +const char js_defineSetter_str[] = "__defineSetter__"; +const char js_lookupGetter_str[] = "__lookupGetter__"; +const char js_lookupSetter_str[] = "__lookupSetter__"; +#endif + +static JSFunctionSpec object_methods[] = { +#if JS_HAS_TOSOURCE + {js_toSource_str, js_obj_toSource, 0, 0, OBJ_TOSTRING_EXTRA}, +#endif + {js_toString_str, js_obj_toString, 0, 0, OBJ_TOSTRING_EXTRA}, + {js_toLocaleString_str, js_obj_toString, 0, 0, OBJ_TOSTRING_EXTRA}, + {js_valueOf_str, obj_valueOf, 0,0,0}, + {js_eval_str, obj_eval, 1,0,0}, +#if JS_HAS_OBJ_WATCHPOINT + {js_watch_str, obj_watch, 2,0,0}, + {js_unwatch_str, obj_unwatch, 1,0,0}, +#endif +#if JS_HAS_NEW_OBJ_METHODS + {js_hasOwnProperty_str, obj_hasOwnProperty, 1,0,0}, + {js_isPrototypeOf_str, obj_isPrototypeOf, 1,0,0}, + {js_propertyIsEnumerable_str, obj_propertyIsEnumerable, 1,0,0}, +#endif +#if JS_HAS_GETTER_SETTER + {js_defineGetter_str, obj_defineGetter, 2,0,0}, + {js_defineSetter_str, obj_defineSetter, 2,0,0}, + {js_lookupGetter_str, obj_lookupGetter, 1,0,0}, + {js_lookupSetter_str, obj_lookupSetter, 1,0,0}, +#endif + {0,0,0,0,0} +}; + +static JSBool +Object(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + if (argc == 0) { + /* Trigger logic below to construct a blank object. */ + obj = NULL; + } else { + /* If argv[0] is null or undefined, obj comes back null. */ + if (!js_ValueToObject(cx, argv[0], &obj)) + return JS_FALSE; + } + if (!obj) { + JS_ASSERT(!argc || JSVAL_IS_NULL(argv[0]) || JSVAL_IS_VOID(argv[0])); + if (cx->fp->flags & JSFRAME_CONSTRUCTING) + return JS_TRUE; + obj = js_NewObject(cx, &js_ObjectClass, NULL, NULL); + if (!obj) + return JS_FALSE; + } + *rval = OBJECT_TO_JSVAL(obj); + return JS_TRUE; +} + +/* + * ObjectOps and Class for with-statement stack objects. + */ +static JSBool +with_LookupProperty(JSContext *cx, JSObject *obj, jsid id, JSObject **objp, + JSProperty **propp +#if defined JS_THREADSAFE && defined DEBUG + , const char *file, uintN line +#endif + ) +{ + JSObject *proto; + JSScopeProperty *sprop; + JSStackFrame *fp; + + proto = OBJ_GET_PROTO(cx, obj); + if (!proto) + return js_LookupProperty(cx, obj, id, objp, propp); + if (!OBJ_LOOKUP_PROPERTY(cx, proto, id, objp, propp)) + return JS_FALSE; + + /* + * Check whether id names an argument or local variable in an active + * function. If so, pretend we didn't find it, so that the real arg or + * var property can be found in the function's call object, later on in + * the scope chain. But skip unshared arg and var properties -- those + * result when a script explicitly sets a function "static" property of + * the same name. See jsinterp.c:SetFunctionSlot. + * + * XXX blame pre-ECMA reflection of function args and vars as properties + */ + if ((sprop = (JSScopeProperty *) *propp) && + (proto = *objp, OBJ_IS_NATIVE(proto)) && + (sprop->getter == js_GetArgument || + sprop->getter == js_GetLocalVariable) && + (sprop->attrs & JSPROP_SHARED)) { + JS_ASSERT(OBJ_GET_CLASS(cx, proto) == &js_FunctionClass); + for (fp = cx->fp; fp && (!fp->fun || fp->fun->native); fp = fp->down) + continue; + if (fp && fp->fun == (JSFunction *) JS_GetPrivate(cx, proto)) { + OBJ_DROP_PROPERTY(cx, proto, *propp); + *objp = NULL; + *propp = NULL; + } + } + return JS_TRUE; +} + +static JSBool +with_GetProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp) +{ + JSObject *proto = OBJ_GET_PROTO(cx, obj); + if (!proto) + return js_GetProperty(cx, obj, id, vp); + return OBJ_GET_PROPERTY(cx, proto, id, vp); +} + +static JSBool +with_SetProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp) +{ + JSObject *proto = OBJ_GET_PROTO(cx, obj); + if (!proto) + return js_SetProperty(cx, obj, id, vp); + return OBJ_SET_PROPERTY(cx, proto, id, vp); +} + +static JSBool +with_GetAttributes(JSContext *cx, JSObject *obj, jsid id, JSProperty *prop, + uintN *attrsp) +{ + JSObject *proto = OBJ_GET_PROTO(cx, obj); + if (!proto) + return js_GetAttributes(cx, obj, id, prop, attrsp); + return OBJ_GET_ATTRIBUTES(cx, proto, id, prop, attrsp); +} + +static JSBool +with_SetAttributes(JSContext *cx, JSObject *obj, jsid id, JSProperty *prop, + uintN *attrsp) +{ + JSObject *proto = OBJ_GET_PROTO(cx, obj); + if (!proto) + return js_SetAttributes(cx, obj, id, prop, attrsp); + return OBJ_SET_ATTRIBUTES(cx, proto, id, prop, attrsp); +} + +static JSBool +with_DeleteProperty(JSContext *cx, JSObject *obj, jsid id, jsval *rval) +{ + JSObject *proto = OBJ_GET_PROTO(cx, obj); + if (!proto) + return js_DeleteProperty(cx, obj, id, rval); + return OBJ_DELETE_PROPERTY(cx, proto, id, rval); +} + +static JSBool +with_DefaultValue(JSContext *cx, JSObject *obj, JSType hint, jsval *vp) +{ + JSObject *proto = OBJ_GET_PROTO(cx, obj); + if (!proto) + return js_DefaultValue(cx, obj, hint, vp); + return OBJ_DEFAULT_VALUE(cx, proto, hint, vp); +} + +static JSBool +with_Enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op, + jsval *statep, jsid *idp) +{ + JSObject *proto = OBJ_GET_PROTO(cx, obj); + if (!proto) + return js_Enumerate(cx, obj, enum_op, statep, idp); + return OBJ_ENUMERATE(cx, proto, enum_op, statep, idp); +} + +static JSBool +with_CheckAccess(JSContext *cx, JSObject *obj, jsid id, JSAccessMode mode, + jsval *vp, uintN *attrsp) +{ + JSObject *proto = OBJ_GET_PROTO(cx, obj); + if (!proto) + return js_CheckAccess(cx, obj, id, mode, vp, attrsp); + return OBJ_CHECK_ACCESS(cx, proto, id, mode, vp, attrsp); +} + +static JSObject * +with_ThisObject(JSContext *cx, JSObject *obj) +{ + JSObject *proto = OBJ_GET_PROTO(cx, obj); + if (!proto) + return obj; + return OBJ_THIS_OBJECT(cx, proto); +} + +JS_FRIEND_DATA(JSObjectOps) js_WithObjectOps = { + js_NewObjectMap, js_DestroyObjectMap, + with_LookupProperty, js_DefineProperty, + with_GetProperty, with_SetProperty, + with_GetAttributes, with_SetAttributes, + with_DeleteProperty, with_DefaultValue, + with_Enumerate, with_CheckAccess, + with_ThisObject, NATIVE_DROP_PROPERTY, + NULL, NULL, + NULL, NULL, + js_SetProtoOrParent, js_SetProtoOrParent, + js_Mark, js_Clear, + NULL, NULL +}; + +static JSObjectOps * +with_getObjectOps(JSContext *cx, JSClass *clasp) +{ + return &js_WithObjectOps; +} + +JSClass js_WithClass = { + "With", + 0, + JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, + JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub, + with_getObjectOps, + 0,0,0,0,0,0,0 +}; + +#if JS_HAS_OBJ_PROTO_PROP +static JSBool +With(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + JSObject *parent, *proto; + jsval v; + + if (!JS_ReportErrorFlagsAndNumber(cx, + JSREPORT_WARNING | JSREPORT_STRICT, + js_GetErrorMessage, NULL, + JSMSG_DEPRECATED_USAGE, + js_WithClass.name)) { + return JS_FALSE; + } + + if (!(cx->fp->flags & JSFRAME_CONSTRUCTING)) { + obj = js_NewObject(cx, &js_WithClass, NULL, NULL); + if (!obj) + return JS_FALSE; + *rval = OBJECT_TO_JSVAL(obj); + } + + parent = cx->fp->scopeChain; + if (argc > 0) { + if (!js_ValueToObject(cx, argv[0], &proto)) + return JS_FALSE; + v = OBJECT_TO_JSVAL(proto); + if (!obj_setSlot(cx, obj, INT_TO_JSVAL(JSSLOT_PROTO), &v)) + return JS_FALSE; + if (argc > 1) { + if (!js_ValueToObject(cx, argv[1], &parent)) + return JS_FALSE; + } + } + v = OBJECT_TO_JSVAL(parent); + return obj_setSlot(cx, obj, INT_TO_JSVAL(JSSLOT_PARENT), &v); +} +#endif + +JSObject * +js_InitObjectClass(JSContext *cx, JSObject *obj) +{ + JSObject *proto; + jsval eval; + +#if JS_HAS_SHARP_VARS + JS_ASSERT(sizeof(jsatomid) * JS_BITS_PER_BYTE >= ATOM_INDEX_LIMIT_LOG2 + 1); +#endif + + proto = JS_InitClass(cx, obj, NULL, &js_ObjectClass, Object, 1, + object_props, object_methods, NULL, NULL); + if (!proto) + return NULL; + +#if JS_HAS_OBJ_PROTO_PROP + if (!JS_InitClass(cx, obj, NULL, &js_WithClass, With, 0, + NULL, NULL, NULL, NULL)) { + return NULL; + } +#endif + + /* ECMA (15.1.2.1) says 'eval' is also a property of the global object. */ + if (!OBJ_GET_PROPERTY(cx, proto, (jsid)cx->runtime->atomState.evalAtom, + &eval)) { + return NULL; + } + if (!OBJ_DEFINE_PROPERTY(cx, obj, (jsid)cx->runtime->atomState.evalAtom, + eval, NULL, NULL, 0, NULL)) { + return NULL; + } + + return proto; +} + +void +js_InitObjectMap(JSObjectMap *map, jsrefcount nrefs, JSObjectOps *ops, + JSClass *clasp) +{ + map->nrefs = nrefs; + map->ops = ops; + map->nslots = JS_INITIAL_NSLOTS; + map->freeslot = JSSLOT_FREE(clasp); +} + +JSObjectMap * +js_NewObjectMap(JSContext *cx, jsrefcount nrefs, JSObjectOps *ops, + JSClass *clasp, JSObject *obj) +{ + return (JSObjectMap *) js_NewScope(cx, nrefs, ops, clasp, obj); +} + +void +js_DestroyObjectMap(JSContext *cx, JSObjectMap *map) +{ + js_DestroyScope(cx, (JSScope *)map); +} + +JSObjectMap * +js_HoldObjectMap(JSContext *cx, JSObjectMap *map) +{ + JS_ASSERT(map->nrefs >= 0); + JS_ATOMIC_INCREMENT(&map->nrefs); + return map; +} + +JSObjectMap * +js_DropObjectMap(JSContext *cx, JSObjectMap *map, JSObject *obj) +{ + JS_ASSERT(map->nrefs > 0); + JS_ATOMIC_DECREMENT(&map->nrefs); + if (map->nrefs == 0) { + map->ops->destroyObjectMap(cx, map); + return NULL; + } + if (MAP_IS_NATIVE(map) && ((JSScope *)map)->object == obj) + ((JSScope *)map)->object = NULL; + return map; +} + +static JSBool +GetClassPrototype(JSContext *cx, JSObject *scope, const char *name, + JSObject **protop); + +JSObject * +js_NewObject(JSContext *cx, JSClass *clasp, JSObject *proto, JSObject *parent) +{ + JSObject *obj, *ctor; + JSObjectOps *ops; + JSObjectMap *map; + jsval cval; + uint32 nslots, i; + jsval *newslots; + + /* Allocate an object from the GC heap and zero it. */ + obj = (JSObject *) js_AllocGCThing(cx, GCX_OBJECT); + if (!obj) + return NULL; + + /* Bootstrap the ur-object, and make it the default prototype object. */ + if (!proto) { + if (!GetClassPrototype(cx, parent, clasp->name, &proto)) + goto bad; + if (!proto && !GetClassPrototype(cx, parent, js_Object_str, &proto)) + goto bad; + } + + /* Always call the class's getObjectOps hook if it has one. */ + ops = clasp->getObjectOps + ? clasp->getObjectOps(cx, clasp) + : &js_ObjectOps; + + /* + * Share proto's map only if it has the same JSObjectOps, and only if + * proto's class has the same private and reserved slots, as obj's map + * and class have. + */ + if (proto && + (map = proto->map)->ops == ops && + ((clasp->flags ^ OBJ_GET_CLASS(cx, proto)->flags) & + (JSCLASS_HAS_PRIVATE | + (JSCLASS_RESERVED_SLOTS_MASK << JSCLASS_RESERVED_SLOTS_SHIFT))) + == 0) { + /* Default parent to the parent of the prototype's constructor. */ + if (!parent) { + if (!OBJ_GET_PROPERTY(cx, proto, + (jsid)cx->runtime->atomState.constructorAtom, + &cval)) { + goto bad; + } + if (JSVAL_IS_OBJECT(cval) && (ctor = JSVAL_TO_OBJECT(cval)) != NULL) + parent = OBJ_GET_PARENT(cx, ctor); + } + + /* Share the given prototype's map. */ + obj->map = js_HoldObjectMap(cx, map); + + /* Ensure that obj starts with the minimum slots for clasp. */ + nslots = JS_INITIAL_NSLOTS; + } else { + /* Leave parent alone. Allocate a new map for obj. */ + map = ops->newObjectMap(cx, 1, ops, clasp, obj); + if (!map) + goto bad; + obj->map = map; + + /* Let ops->newObjectMap set nslots so as to reserve slots. */ + nslots = map->nslots; + } + + /* Allocate a slots vector, with a -1'st element telling its length. */ + newslots = (jsval *) JS_malloc(cx, (nslots + 1) * sizeof(jsval)); + if (!newslots) { + js_DropObjectMap(cx, obj->map, obj); + obj->map = NULL; + goto bad; + } + newslots[0] = nslots; + newslots++; + + /* Set the proto, parent, and class properties. */ + newslots[JSSLOT_PROTO] = OBJECT_TO_JSVAL(proto); + newslots[JSSLOT_PARENT] = OBJECT_TO_JSVAL(parent); + newslots[JSSLOT_CLASS] = PRIVATE_TO_JSVAL(clasp); + + /* Clear above JSSLOT_CLASS so the GC doesn't load uninitialized memory. */ + for (i = JSSLOT_CLASS + 1; i < nslots; i++) + newslots[i] = JSVAL_VOID; + + /* Store newslots after initializing all of 'em, just in case. */ + obj->slots = newslots; + + if (cx->runtime->objectHook) + cx->runtime->objectHook(cx, obj, JS_TRUE, cx->runtime->objectHookData); + + return obj; + +bad: + cx->newborn[GCX_OBJECT] = NULL; + return NULL; +} + +static JSBool +FindConstructor(JSContext *cx, JSObject *scope, const char *name, jsval *vp) +{ + JSAtom *atom; + JSObject *obj; + JSObject *pobj; + JSScopeProperty *sprop; + + atom = js_Atomize(cx, name, strlen(name), 0); + if (!atom) + return JS_FALSE; + + if (scope || (cx->fp && (scope = cx->fp->scopeChain) != NULL)) { + /* Find the topmost object in the scope chain. */ + do { + obj = scope; + scope = OBJ_GET_PARENT(cx, obj); + } while (scope); + } else { + obj = cx->globalObject; + if (!obj) { + *vp = JSVAL_VOID; + return JS_TRUE; + } + } + + if (!OBJ_LOOKUP_PROPERTY(cx, obj, (jsid)atom, &pobj, (JSProperty**)&sprop)) + return JS_FALSE; + if (!sprop) { + *vp = JSVAL_VOID; + return JS_TRUE; + } + + JS_ASSERT(OBJ_IS_NATIVE(pobj)); + JS_ASSERT(SPROP_HAS_VALID_SLOT(sprop, OBJ_SCOPE(pobj))); + *vp = OBJ_GET_SLOT(cx, pobj, sprop->slot); + OBJ_DROP_PROPERTY(cx, pobj, (JSProperty *)sprop); + return JS_TRUE; +} + +JSObject * +js_ConstructObject(JSContext *cx, JSClass *clasp, JSObject *proto, + JSObject *parent, uintN argc, jsval *argv) +{ + jsval cval, rval; + JSObject *obj, *ctor; + + if (!FindConstructor(cx, parent, clasp->name, &cval)) + return NULL; + if (JSVAL_IS_PRIMITIVE(cval)) { + js_ReportIsNotFunction(cx, &cval, JSV2F_CONSTRUCT | JSV2F_SEARCH_STACK); + return NULL; + } + + /* + * If proto or parent are NULL, set them to Constructor.prototype and/or + * Constructor.__parent__, just like JSOP_NEW does. + */ + ctor = JSVAL_TO_OBJECT(cval); + if (!parent) + parent = OBJ_GET_PARENT(cx, ctor); + if (!proto) { + if (!OBJ_GET_PROPERTY(cx, ctor, + (jsid)cx->runtime->atomState.classPrototypeAtom, + &rval)) { + return NULL; + } + if (JSVAL_IS_OBJECT(rval)) + proto = JSVAL_TO_OBJECT(rval); + } + + obj = js_NewObject(cx, clasp, proto, parent); + if (!obj) + return NULL; + + if (!js_InternalConstruct(cx, obj, cval, argc, argv, &rval)) + goto bad; + return JSVAL_IS_OBJECT(rval) ? JSVAL_TO_OBJECT(rval) : obj; +bad: + cx->newborn[GCX_OBJECT] = NULL; + return NULL; +} + +void +js_FinalizeObject(JSContext *cx, JSObject *obj) +{ + JSObjectMap *map; + + /* Cope with stillborn objects that have no map. */ + map = obj->map; + if (!map) + return; + JS_ASSERT(obj->slots); + + if (cx->runtime->objectHook) + cx->runtime->objectHook(cx, obj, JS_FALSE, cx->runtime->objectHookData); + + /* Remove all watchpoints with weak links to obj. */ + JS_ClearWatchPointsForObject(cx, obj); + + /* + * Finalize obj first, in case it needs map and slots. Optimized to use + * LOCKED_OBJ_GET_CLASS instead of OBJ_GET_CLASS, so we avoid "promoting" + * obj's scope from lock-free to lock-full (see jslock.c:ClaimScope) when + * we're called from the GC. Only the GC should call js_FinalizeObject, + * and no other threads run JS (and possibly racing to update obj->slots) + * while the GC is running. + */ + LOCKED_OBJ_GET_CLASS(obj)->finalize(cx, obj); + + /* Drop map and free slots. */ + js_DropObjectMap(cx, map, obj); + obj->map = NULL; + JS_free(cx, obj->slots - 1); + obj->slots = NULL; +} + +/* XXXbe if one adds props, deletes earlier props, adds more, the last added + won't recycle the deleted props' slots. */ +JSBool +js_AllocSlot(JSContext *cx, JSObject *obj, uint32 *slotp) +{ + JSObjectMap *map; + uint32 nslots, i; + size_t nbytes; + jsval *newslots; + + map = obj->map; + JS_ASSERT(!MAP_IS_NATIVE(map) || ((JSScope *)map)->object == obj); + nslots = map->nslots; + if (map->freeslot >= nslots) { + nslots = map->freeslot; + JS_ASSERT(nslots >= JS_INITIAL_NSLOTS); + nslots += (nslots + 1) / 2; + + nbytes = (nslots + 1) * sizeof(jsval); +#if defined _MSC_VER && _MSC_VER <= 800 + if (nbytes > 60000U) { + JS_ReportOutOfMemory(cx); + return JS_FALSE; + } +#endif + + newslots = (jsval *) JS_realloc(cx, obj->slots - 1, nbytes); + if (!newslots) + return JS_FALSE; + for (i = 1 + newslots[0]; i <= nslots; i++) + newslots[i] = JSVAL_VOID; + newslots[0] = map->nslots = nslots; + obj->slots = newslots + 1; + } + +#ifdef TOO_MUCH_GC + obj->slots[map->freeslot] = JSVAL_VOID; +#endif + *slotp = map->freeslot++; + return JS_TRUE; +} + +void +js_FreeSlot(JSContext *cx, JSObject *obj, uint32 slot) +{ + JSObjectMap *map; + uint32 nslots; + size_t nbytes; + jsval *newslots; + + OBJ_CHECK_SLOT(obj, slot); + obj->slots[slot] = JSVAL_VOID; + map = obj->map; + JS_ASSERT(!MAP_IS_NATIVE(map) || ((JSScope *)map)->object == obj); + if (map->freeslot == slot + 1) + map->freeslot = slot; + nslots = map->nslots; + if (nslots > JS_INITIAL_NSLOTS && map->freeslot < nslots / 2) { + nslots = map->freeslot; + nslots += nslots / 2; + if (nslots < JS_INITIAL_NSLOTS) + nslots = JS_INITIAL_NSLOTS; + nbytes = (nslots + 1) * sizeof(jsval); + newslots = (jsval *) JS_realloc(cx, obj->slots - 1, nbytes); + if (!newslots) + return; + newslots[0] = map->nslots = nslots; + obj->slots = newslots + 1; + } +} + +#if JS_BUG_EMPTY_INDEX_ZERO +#define CHECK_FOR_EMPTY_INDEX(id) \ + JS_BEGIN_MACRO \ + if (JSSTRING_LENGTH(_str) == 0) \ + id = JSVAL_ZERO; \ + JS_END_MACRO +#else +#define CHECK_FOR_EMPTY_INDEX(id) /* nothing */ +#endif + +/* JSVAL_INT_MAX as a string */ +#define JSVAL_INT_MAX_STRING "1073741823" + +#define CHECK_FOR_FUNNY_INDEX(id) \ + JS_BEGIN_MACRO \ + if (!JSVAL_IS_INT(id)) { \ + JSAtom *atom_ = (JSAtom *)id; \ + JSString *str_ = ATOM_TO_STRING(atom_); \ + const jschar *cp_ = str_->chars; \ + JSBool negative_ = (*cp_ == '-'); \ + if (negative_) cp_++; \ + if (JS7_ISDEC(*cp_) && \ + str_->length - negative_ <= sizeof(JSVAL_INT_MAX_STRING)-1) { \ + id = CheckForFunnyIndex(id, cp_, negative_); \ + } else { \ + CHECK_FOR_EMPTY_INDEX(id); \ + } \ + } \ + JS_END_MACRO + +static jsid +CheckForFunnyIndex(jsid id, const jschar *cp, JSBool negative) +{ + jsuint index = JS7_UNDEC(*cp++); + jsuint oldIndex = 0; + jsuint c = 0; + + if (index != 0) { + while (JS7_ISDEC(*cp)) { + oldIndex = index; + c = JS7_UNDEC(*cp); + index = 10 * index + c; + cp++; + } + } + if (*cp == 0 && + (oldIndex < (JSVAL_INT_MAX / 10) || + (oldIndex == (JSVAL_INT_MAX / 10) && + c <= (JSVAL_INT_MAX % 10)))) { + if (negative) + index = 0 - index; + id = INT_TO_JSVAL((jsint)index); + } + return id; +} + +JSScopeProperty * +js_AddNativeProperty(JSContext *cx, JSObject *obj, jsid id, + JSPropertyOp getter, JSPropertyOp setter, uint32 slot, + uintN attrs, uintN flags, intN shortid) +{ + JSScope *scope; + JSScopeProperty *sprop; + + JS_LOCK_OBJ(cx, obj); + scope = js_GetMutableScope(cx, obj); + if (!scope) { + sprop = NULL; + } else { + /* + * Handle old bug that took empty string as zero index. Also convert + * string indices to integers if appropriate. + */ + CHECK_FOR_FUNNY_INDEX(id); + sprop = js_AddScopeProperty(cx, scope, id, getter, setter, slot, attrs, + flags, shortid); + } + JS_UNLOCK_OBJ(cx, obj); + return sprop; +} + +JSScopeProperty * +js_ChangeNativePropertyAttrs(JSContext *cx, JSObject *obj, + JSScopeProperty *sprop, uintN attrs, uintN mask, + JSPropertyOp getter, JSPropertyOp setter) +{ + JSScope *scope; + + JS_LOCK_OBJ(cx, obj); + scope = js_GetMutableScope(cx, obj); + if (!scope) { + sprop = NULL; + } else { + sprop = js_ChangeScopePropertyAttrs(cx, scope, sprop, attrs, mask, + getter, setter); + if (sprop) { + PROPERTY_CACHE_FILL(&cx->runtime->propertyCache, obj, sprop->id, + sprop); + } + } + JS_UNLOCK_OBJ(cx, obj); + return sprop; +} + +JSBool +js_DefineProperty(JSContext *cx, JSObject *obj, jsid id, jsval value, + JSPropertyOp getter, JSPropertyOp setter, uintN attrs, + JSProperty **propp) +{ + return js_DefineNativeProperty(cx, obj, id, value, getter, setter, attrs, + 0, 0, propp); +} + +JSBool +js_DefineNativeProperty(JSContext *cx, JSObject *obj, jsid id, jsval value, + JSPropertyOp getter, JSPropertyOp setter, uintN attrs, + uintN flags, intN shortid, JSProperty **propp) +{ + JSClass *clasp; + JSScope *scope; + JSScopeProperty *sprop; + + /* + * Handle old bug that took empty string as zero index. Also convert + * string indices to integers if appropriate. + */ + CHECK_FOR_FUNNY_INDEX(id); + +#if JS_HAS_GETTER_SETTER + /* + * If defining a getter or setter, we must check for its counterpart and + * update the attributes and property ops. A getter or setter is really + * only half of a property. + */ + if (attrs & (JSPROP_GETTER | JSPROP_SETTER)) { + JSObject *pobj; + + /* + * If JS_THREADSAFE and id is found, js_LookupProperty returns with + * sprop non-null and pobj locked. If pobj == obj, the property is + * already in obj and obj has its own (mutable) scope. So if we are + * defining a getter whose setter was already defined, or vice versa, + * finish the job via js_ChangeScopePropertyAttributes, and refresh + * the property cache line for (obj, id) to map sprop. + */ + if (!js_LookupProperty(cx, obj, id, &pobj, (JSProperty **)&sprop)) + return JS_FALSE; + if (sprop && + pobj == obj && + (sprop->attrs & (JSPROP_GETTER | JSPROP_SETTER))) { + sprop = js_ChangeScopePropertyAttrs(cx, OBJ_SCOPE(obj), sprop, + attrs, sprop->attrs, + (attrs & JSPROP_GETTER) + ? getter + : sprop->getter, + (attrs & JSPROP_SETTER) + ? setter + : sprop->setter); + + /* NB: obj == pobj, so we can share unlock code at the bottom. */ + if (!sprop) + goto bad; + goto out; + } + + if (sprop) { + /* NB: call OBJ_DROP_PROPERTY, as pobj might not be native. */ + OBJ_DROP_PROPERTY(cx, pobj, (JSProperty *)sprop); + sprop = NULL; + } + } +#endif /* JS_HAS_GETTER_SETTER */ + + /* Lock if object locking is required by this implementation. */ + JS_LOCK_OBJ(cx, obj); + + /* Use the object's class getter and setter by default. */ + clasp = LOCKED_OBJ_GET_CLASS(obj); + if (!getter) + getter = clasp->getProperty; + if (!setter) + setter = clasp->setProperty; + + /* Get obj's own scope if it has one, or create a new one for obj. */ + scope = js_GetMutableScope(cx, obj); + if (!scope) + goto bad; + + /* Add the property to scope, or replace an existing one of the same id. */ + if (clasp->flags & JSCLASS_SHARE_ALL_PROPERTIES) + attrs |= JSPROP_SHARED; + sprop = js_AddScopeProperty(cx, scope, id, getter, setter, + SPROP_INVALID_SLOT, attrs, flags, shortid); + if (!sprop) + goto bad; + + /* XXXbe called with lock held */ + if (!clasp->addProperty(cx, obj, SPROP_USERID(sprop), &value)) { + (void) js_RemoveScopeProperty(cx, scope, id); + goto bad; + } + + if (SPROP_HAS_VALID_SLOT(sprop, scope)) + LOCKED_OBJ_SET_SLOT(obj, sprop->slot, value); + +#if JS_HAS_GETTER_SETTER +out: +#endif + PROPERTY_CACHE_FILL(&cx->runtime->propertyCache, obj, id, sprop); + if (propp) + *propp = (JSProperty *) sprop; + else + JS_UNLOCK_OBJ(cx, obj); + return JS_TRUE; + +bad: + JS_UNLOCK_OBJ(cx, obj); + return JS_FALSE; +} + +#if defined JS_THREADSAFE && defined DEBUG +JS_FRIEND_API(JSBool) +_js_LookupProperty(JSContext *cx, JSObject *obj, jsid id, JSObject **objp, + JSProperty **propp, const char *file, uintN line) +#else +JS_FRIEND_API(JSBool) +js_LookupProperty(JSContext *cx, JSObject *obj, jsid id, JSObject **objp, + JSProperty **propp) +#endif +{ + JSObject *start, *obj2, *proto; + JSScope *scope; + JSScopeProperty *sprop; + JSClass *clasp; + JSResolveOp resolve; + JSResolvingKey key; + JSResolvingEntry *entry; + uint32 generation; + JSNewResolveOp newresolve; + uintN flags; + uint32 format; + JSBool ok; + + /* + * Handle old bug that took empty string as zero index. Also convert + * string indices to integers if appropriate. + */ + CHECK_FOR_FUNNY_INDEX(id); + + /* Search scopes starting with obj and following the prototype link. */ + start = obj; + for (;;) { + JS_LOCK_OBJ(cx, obj); + SET_OBJ_INFO(obj, file, line); + scope = OBJ_SCOPE(obj); + if (scope->object == obj) { + sprop = SCOPE_GET_PROPERTY(scope, id); + } else { + /* Shared prototype scope: try resolve before lookup. */ + sprop = NULL; + } + + /* Try obj's class resolve hook if id was not found in obj's scope. */ + if (!sprop) { + clasp = LOCKED_OBJ_GET_CLASS(obj); + resolve = clasp->resolve; + if (resolve != JS_ResolveStub) { + /* Avoid recursion on (obj, id) already being resolved on cx. */ + key.obj = obj; + key.id = id; + + /* + * Once we have successfully added an entry for (obj, key) to + * cx->resolvingTable, control must go through cleanup: before + * returning. But note that JS_DHASH_ADD may find an existing + * entry, in which case we bail to suppress runaway recursion. + */ + if (!StartResolving(cx, &key, JSRESFLAG_LOOKUP, &entry)) { + JS_UNLOCK_OBJ(cx, obj); + return JS_FALSE; + } + if (!entry) { + /* Already resolving id in obj -- dampen recursion. */ + JS_UNLOCK_OBJ(cx, obj); + goto out; + } + generation = cx->resolvingTable->generation; + + /* Null *propp here so we can test it at cleanup: safely. */ + *propp = NULL; + + if (clasp->flags & JSCLASS_NEW_RESOLVE) { + newresolve = (JSNewResolveOp)resolve; + flags = 0; + if (cx->fp && cx->fp->pc) { + format = js_CodeSpec[*cx->fp->pc].format; + if ((format & JOF_MODEMASK) != JOF_NAME) + flags |= JSRESOLVE_QUALIFIED; + if ((format & JOF_ASSIGNING) || + (cx->fp->flags & JSFRAME_ASSIGNING)) { + flags |= JSRESOLVE_ASSIGNING; + } + } + obj2 = (clasp->flags & JSCLASS_NEW_RESOLVE_GETS_START) + ? start + : NULL; + JS_UNLOCK_OBJ(cx, obj); + + /* Protect id and all atoms from a GC nested in resolve. */ + JS_KEEP_ATOMS(cx->runtime); + ok = newresolve(cx, obj, ID_TO_VALUE(id), flags, &obj2); + JS_UNKEEP_ATOMS(cx->runtime); + if (!ok) + goto cleanup; + + JS_LOCK_OBJ(cx, obj); + SET_OBJ_INFO(obj, file, line); + if (obj2) { + /* Resolved: juggle locks and lookup id again. */ + if (obj2 != obj) { + JS_UNLOCK_OBJ(cx, obj); + JS_LOCK_OBJ(cx, obj2); + } + scope = OBJ_SCOPE(obj2); + if (!MAP_IS_NATIVE(&scope->map)) { + /* Whoops, newresolve handed back a foreign obj2. */ + JS_ASSERT(obj2 != obj); + JS_UNLOCK_OBJ(cx, obj2); + ok = OBJ_LOOKUP_PROPERTY(cx, obj2, id, objp, propp); + if (!ok || *propp) + goto cleanup; + JS_LOCK_OBJ(cx, obj2); + } else { + /* + * Require that obj2 have its own scope now, as we + * do for old-style resolve. If it doesn't, then + * id was not truly resolved, and we'll find it in + * the proto chain, or miss it if obj2's proto is + * not on obj's proto chain. That last case is a + * "too bad!" case. + */ + if (scope->object == obj2) + sprop = SCOPE_GET_PROPERTY(scope, id); + } + if (obj2 != obj && !sprop) { + JS_UNLOCK_OBJ(cx, obj2); + JS_LOCK_OBJ(cx, obj); + } + } + } else { + /* + * Old resolve always requires id re-lookup if obj owns + * its scope after resolve returns. + */ + JS_UNLOCK_OBJ(cx, obj); + ok = resolve(cx, obj, ID_TO_VALUE(id)); + if (!ok) + goto cleanup; + JS_LOCK_OBJ(cx, obj); + SET_OBJ_INFO(obj, file, line); + scope = OBJ_SCOPE(obj); + JS_ASSERT(MAP_IS_NATIVE(&scope->map)); + if (scope->object == obj) + sprop = SCOPE_GET_PROPERTY(scope, id); + } + + cleanup: + StopResolving(cx, &key, JSRESFLAG_LOOKUP, entry, generation); + if (!ok || *propp) + return ok; + } + } + + if (sprop) { + JS_ASSERT(OBJ_SCOPE(obj) == scope); + *objp = scope->object; /* XXXbe hide in jsscope.[ch] */ + + *propp = (JSProperty *) sprop; + return JS_TRUE; + } + + proto = LOCKED_OBJ_GET_PROTO(obj); + JS_UNLOCK_OBJ(cx, obj); + if (!proto) + break; + if (!OBJ_IS_NATIVE(proto)) + return OBJ_LOOKUP_PROPERTY(cx, proto, id, objp, propp); + obj = proto; + } + +out: + *objp = NULL; + *propp = NULL; + return JS_TRUE; +} + +JS_FRIEND_API(JSBool) +js_FindProperty(JSContext *cx, jsid id, JSObject **objp, JSObject **pobjp, + JSProperty **propp) +{ + JSRuntime *rt; + JSObject *obj, *pobj, *lastobj; + JSScopeProperty *sprop; + JSProperty *prop; + + rt = cx->runtime; + obj = cx->fp->scopeChain; + do { + /* Try the property cache and return immediately on cache hit. */ + if (OBJ_IS_NATIVE(obj)) { + JS_LOCK_OBJ(cx, obj); + PROPERTY_CACHE_TEST(&rt->propertyCache, obj, id, sprop); + if (sprop) { + JS_ASSERT(OBJ_IS_NATIVE(obj)); + *objp = obj; + *pobjp = obj; + *propp = (JSProperty *) sprop; + return JS_TRUE; + } + JS_UNLOCK_OBJ(cx, obj); + } + + /* If cache miss, take the slow path. */ + if (!OBJ_LOOKUP_PROPERTY(cx, obj, id, &pobj, &prop)) + return JS_FALSE; + if (prop) { + if (OBJ_IS_NATIVE(pobj)) { + sprop = (JSScopeProperty *) prop; + PROPERTY_CACHE_FILL(&rt->propertyCache, pobj, id, sprop); + } + *objp = obj; + *pobjp = pobj; + *propp = prop; + return JS_TRUE; + } + lastobj = obj; + } while ((obj = OBJ_GET_PARENT(cx, obj)) != NULL); + + *objp = lastobj; + *pobjp = NULL; + *propp = NULL; + return JS_TRUE; +} + +JSObject * +js_FindIdentifierBase(JSContext *cx, jsid id) +{ + JSObject *obj, *pobj; + JSProperty *prop; + + /* + * Look for id's property along the "with" statement chain and the + * statically-linked scope chain. + */ + if (!js_FindProperty(cx, id, &obj, &pobj, &prop)) + return NULL; + if (prop) { + OBJ_DROP_PROPERTY(cx, pobj, prop); + return obj; + } + + /* + * Use the top-level scope from the scope chain, which won't end in the + * same scope as cx->globalObject for cross-context function calls. + */ + JS_ASSERT(obj); + + /* + * Property not found. Give a strict warning if binding an undeclared + * top-level variable. + */ + if (JS_HAS_STRICT_OPTION(cx)) { + JSString *str = JSVAL_TO_STRING(ID_TO_VALUE(id)); + if (!JS_ReportErrorFlagsAndNumber(cx, + JSREPORT_WARNING | JSREPORT_STRICT, + js_GetErrorMessage, NULL, + JSMSG_UNDECLARED_VAR, + JS_GetStringBytes(str))) { + return NULL; + } + } + return obj; +} + +JSBool +js_GetProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp) +{ + JSObject *obj2; + JSScopeProperty *sprop; + JSScope *scope; + uint32 slot; + + /* + * Handle old bug that took empty string as zero index. Also convert + * string indices to integers if appropriate. + */ + CHECK_FOR_FUNNY_INDEX(id); + + if (!js_LookupProperty(cx, obj, id, &obj2, (JSProperty **)&sprop)) + return JS_FALSE; + if (!sprop) { + jsval default_val; + +#if JS_BUG_NULL_INDEX_PROPS + /* Indexed properties defaulted to null in old versions. */ + default_val = (JSVAL_IS_INT(id) && JSVAL_TO_INT(id) >= 0) + ? JSVAL_NULL + : JSVAL_VOID; +#else + default_val = JSVAL_VOID; +#endif + *vp = default_val; + + if (!OBJ_GET_CLASS(cx, obj)->getProperty(cx, obj, ID_TO_VALUE(id), vp)) + return JS_FALSE; + + /* + * Give a strict warning if foo.bar is evaluated by a script for an + * object foo with no property named 'bar'. + */ + if (JS_HAS_STRICT_OPTION(cx) && + *vp == default_val && + cx->fp && cx->fp->pc && + (*cx->fp->pc == JSOP_GETPROP || *cx->fp->pc == JSOP_GETELEM)) + { + jsbytecode *pc, *endpc; + JSString *str; + + /* Kludge to allow (typeof foo == "undefined") tests. */ + JS_ASSERT(cx->fp->script); + pc = cx->fp->pc; + pc += js_CodeSpec[*pc].length; + endpc = cx->fp->script->code + cx->fp->script->length; + while (pc < endpc) { + if (*pc == JSOP_TYPEOF) + return JS_TRUE; + if (*pc != JSOP_GROUP) + break; + pc++; + } + + /* Ok, bad undefined property reference: whine about it. */ + str = js_DecompileValueGenerator(cx, JS_FALSE, ID_TO_VALUE(id), + NULL); + if (!str || + !JS_ReportErrorFlagsAndNumber(cx, + JSREPORT_WARNING|JSREPORT_STRICT, + js_GetErrorMessage, NULL, + JSMSG_UNDEFINED_PROP, + JS_GetStringBytes(str))) { + return JS_FALSE; + } + } + return JS_TRUE; + } + + if (!OBJ_IS_NATIVE(obj2)) { + OBJ_DROP_PROPERTY(cx, obj2, (JSProperty *)sprop); + return OBJ_GET_PROPERTY(cx, obj2, id, vp); + } + + /* Unlock obj2 before calling getter, relock after to avoid deadlock. */ + scope = OBJ_SCOPE(obj2); + slot = sprop->slot; + if (slot != SPROP_INVALID_SLOT) { + JS_ASSERT(slot < obj2->map->freeslot); + *vp = LOCKED_OBJ_GET_SLOT(obj2, slot); + + /* If sprop has a stub getter, we're done. */ + if (!sprop->getter) + goto out; + } else { + *vp = JSVAL_VOID; + } + + JS_UNLOCK_SCOPE(cx, scope); + if (!SPROP_GET(cx, sprop, obj, obj2, vp)) + return JS_FALSE; + JS_LOCK_SCOPE(cx, scope); + + if (SPROP_HAS_VALID_SLOT(sprop, scope)) { + LOCKED_OBJ_SET_SLOT(obj2, slot, *vp); + PROPERTY_CACHE_FILL(&cx->runtime->propertyCache, obj2, id, sprop); + } + +out: + JS_UNLOCK_SCOPE(cx, scope); + return JS_TRUE; +} + +JSBool +js_SetProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp) +{ + JSObject *pobj; + JSScopeProperty *sprop; + JSScope *scope; + uintN attrs, flags; + intN shortid; + JSClass *clasp; + JSPropertyOp getter, setter; + jsval pval; + uint32 slot; + + /* + * Handle old bug that took empty string as zero index. Also convert + * string indices to integers if appropriate. + */ + CHECK_FOR_FUNNY_INDEX(id); + + if (!js_LookupProperty(cx, obj, id, &pobj, (JSProperty **)&sprop)) + return JS_FALSE; + + if (sprop && !OBJ_IS_NATIVE(pobj)) { + OBJ_DROP_PROPERTY(cx, pobj, (JSProperty *)sprop); + sprop = NULL; + } + + /* + * Now either sprop is null, meaning id was not found in obj or one of its + * prototypes; or sprop is non-null, meaning id was found in pobj's scope. + * If JS_THREADSAFE and sprop is non-null, then scope is locked, and sprop + * is held: we must OBJ_DROP_PROPERTY or JS_UNLOCK_SCOPE before we return + * (the two are equivalent for native objects, but we use JS_UNLOCK_SCOPE + * because it is cheaper). + */ + attrs = JSPROP_ENUMERATE; + flags = 0; + shortid = 0; + clasp = OBJ_GET_CLASS(cx, obj); + getter = clasp->getProperty; + setter = clasp->setProperty; + + if (sprop) { + /* + * Set scope for use below. It was locked by js_LookupProperty, and + * we know pobj owns it (i.e., scope->object == pobj). Therefore we + * optimize JS_UNLOCK_OBJ(cx, pobj) into JS_UNLOCK_SCOPE(cx, scope). + */ + scope = OBJ_SCOPE(pobj); + + attrs = sprop->attrs; + if ((attrs & JSPROP_READONLY) || + (SCOPE_IS_SEALED(scope) && pobj == obj)) { + JS_UNLOCK_SCOPE(cx, scope); + if ((attrs & JSPROP_READONLY) && JSVERSION_IS_ECMA(cx->version)) + return JS_TRUE; + goto read_only_error; + } + + if (pobj != obj) { + /* + * We found id in a prototype object: prepare to share or shadow. + * NB: Thanks to the immutable, garbage-collected property tree + * maintained by jsscope.c in cx->runtime, we needn't worry about + * sprop going away behind our back after we've unlocked scope. + */ + JS_UNLOCK_SCOPE(cx, scope); + + /* Don't clone a shared prototype property. */ + if (attrs & JSPROP_SHARED) + return SPROP_SET(cx, sprop, obj, pobj, vp); + + /* Restore attrs to the ECMA default for new properties. */ + attrs = JSPROP_ENUMERATE; + + /* + * Preserve the shortid, getter, and setter when shadowing any + * property that has a shortid. An old API convention requires + * that the property's getter and setter functions receive the + * shortid, not id, when they are called on the shadow we are + * about to create in obj's scope. + */ + if (sprop->flags & SPROP_HAS_SHORTID) { + flags = SPROP_HAS_SHORTID; + shortid = sprop->shortid; + getter = sprop->getter; + setter = sprop->setter; + } + + /* + * Forget we found the proto-property now that we've copied any + * needed member values. + */ + sprop = NULL; + } +#ifdef __GNUC__ /* suppress bogus gcc warnings */ + } else { + scope = NULL; +#endif + } + + if (!sprop) { + if (SCOPE_IS_SEALED(OBJ_SCOPE(obj)) && OBJ_SCOPE(obj)->object == obj) + goto read_only_error; + + /* Find or make a property descriptor with the right heritage. */ + JS_LOCK_OBJ(cx, obj); + scope = js_GetMutableScope(cx, obj); + if (!scope) { + JS_UNLOCK_OBJ(cx, obj); + return JS_FALSE; + } + if (clasp->flags & JSCLASS_SHARE_ALL_PROPERTIES) + attrs |= JSPROP_SHARED; + sprop = js_AddScopeProperty(cx, scope, id, getter, setter, + SPROP_INVALID_SLOT, attrs, flags, shortid); + if (!sprop) { + JS_UNLOCK_SCOPE(cx, scope); + return JS_FALSE; + } + + /* XXXbe called with obj locked */ + if (!clasp->addProperty(cx, obj, SPROP_USERID(sprop), vp)) { + (void) js_RemoveScopeProperty(cx, scope, id); + JS_UNLOCK_SCOPE(cx, scope); + return JS_FALSE; + } + + /* Initialize new property value (passed to setter) to undefined. */ + if (SPROP_HAS_VALID_SLOT(sprop, scope)) + LOCKED_OBJ_SET_SLOT(obj, sprop->slot, JSVAL_VOID); + + PROPERTY_CACHE_FILL(&cx->runtime->propertyCache, obj, id, sprop); + } + + /* Get the current property value from its slot. */ + slot = sprop->slot; + if (slot != SPROP_INVALID_SLOT) { + JS_ASSERT(slot < obj->map->freeslot); + pval = LOCKED_OBJ_GET_SLOT(obj, slot); + + /* If sprop has a stub setter, keep scope locked and just store *vp. */ + if (!sprop->setter) + goto set_slot; + } + + /* Avoid deadlock by unlocking obj's scope while calling sprop's setter. */ + JS_UNLOCK_SCOPE(cx, scope); + + /* Let the setter modify vp before copying from it to obj->slots[slot]. */ + if (!SPROP_SET(cx, sprop, obj, obj, vp)) + return JS_FALSE; + + /* Relock obj's scope until we are done with sprop. */ + JS_LOCK_SCOPE(cx, scope); + + /* + * Check whether sprop is still around (was not deleted), and whether it + * has a slot (it may never have had one, or we may have lost a race with + * someone who cleared scope). + */ + if (SPROP_HAS_VALID_SLOT(sprop, scope)) { + set_slot: + GC_POKE(cx, pval); + LOCKED_OBJ_SET_SLOT(obj, slot, *vp); + } + JS_UNLOCK_SCOPE(cx, scope); + return JS_TRUE; + + read_only_error: { + JSString *str = js_DecompileValueGenerator(cx, + JSDVG_IGNORE_STACK, + ID_TO_VALUE(id), + NULL); + if (str) { + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, + JSMSG_READ_ONLY, + JS_GetStringBytes(str)); + } + return JS_FALSE; + } +} + +JSBool +js_GetAttributes(JSContext *cx, JSObject *obj, jsid id, JSProperty *prop, + uintN *attrsp) +{ + JSBool noprop, ok; + JSScopeProperty *sprop; + + noprop = !prop; + if (noprop) { + if (!js_LookupProperty(cx, obj, id, &obj, &prop)) + return JS_FALSE; + if (!prop) { + *attrsp = 0; + return JS_TRUE; + } + if (!OBJ_IS_NATIVE(obj)) { + ok = OBJ_GET_ATTRIBUTES(cx, obj, id, prop, attrsp); + OBJ_DROP_PROPERTY(cx, obj, prop); + return ok; + } + } + sprop = (JSScopeProperty *)prop; + *attrsp = sprop->attrs; + if (noprop) + OBJ_DROP_PROPERTY(cx, obj, prop); + return JS_TRUE; +} + +JSBool +js_SetAttributes(JSContext *cx, JSObject *obj, jsid id, JSProperty *prop, + uintN *attrsp) +{ + JSBool noprop, ok; + JSScopeProperty *sprop; + + noprop = !prop; + if (noprop) { + if (!js_LookupProperty(cx, obj, id, &obj, &prop)) + return JS_FALSE; + if (!prop) + return JS_TRUE; + if (!OBJ_IS_NATIVE(obj)) { + ok = OBJ_SET_ATTRIBUTES(cx, obj, id, prop, attrsp); + OBJ_DROP_PROPERTY(cx, obj, prop); + return ok; + } + } + sprop = (JSScopeProperty *)prop; + sprop = js_ChangeNativePropertyAttrs(cx, obj, sprop, + *attrsp & + ~(JSPROP_GETTER | JSPROP_SETTER), 0, + sprop->getter, sprop->setter); + if (noprop) + OBJ_DROP_PROPERTY(cx, obj, prop); + return (sprop != NULL); +} + +JSBool +js_DeleteProperty(JSContext *cx, JSObject *obj, jsid id, jsval *rval) +{ +#if JS_HAS_PROP_DELETE + + JSObject *proto; + JSProperty *prop; + JSScopeProperty *sprop; + JSString *str; + JSScope *scope; + JSBool ok; + + *rval = JSVERSION_IS_ECMA(cx->version) ? JSVAL_TRUE : JSVAL_VOID; + + /* + * Handle old bug that took empty string as zero index. Also convert + * string indices to integers if appropriate. + */ + CHECK_FOR_FUNNY_INDEX(id); + + if (!js_LookupProperty(cx, obj, id, &proto, &prop)) + return JS_FALSE; + if (!prop || proto != obj) { + /* + * If the property was found in a native prototype, check whether it's + * shared and permanent. Such a property stands for direct properties + * in all delegating objects, matching ECMA semantics without bloating + * each delegating object. + */ + if (prop) { + if (OBJ_IS_NATIVE(proto)) { + sprop = (JSScopeProperty *)prop; + if (SPROP_IS_SHARED_PERMANENT(sprop)) + *rval = JSVAL_FALSE; + } + OBJ_DROP_PROPERTY(cx, proto, prop); + if (*rval == JSVAL_FALSE) + return JS_TRUE; + } + + /* + * If no property, or the property comes unshared or impermanent from + * a prototype, call the class's delProperty hook, passing rval as the + * result parameter. + */ + return OBJ_GET_CLASS(cx, obj)->delProperty(cx, obj, ID_TO_VALUE(id), + rval); + } + + sprop = (JSScopeProperty *)prop; + if (sprop->attrs & JSPROP_PERMANENT) { + OBJ_DROP_PROPERTY(cx, obj, prop); + if (JSVERSION_IS_ECMA(cx->version)) { + *rval = JSVAL_FALSE; + return JS_TRUE; + } + str = js_DecompileValueGenerator(cx, JSDVG_IGNORE_STACK, + ID_TO_VALUE(id), NULL); + if (str) { + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, + JSMSG_PERMANENT, JS_GetStringBytes(str)); + } + return JS_FALSE; + } + + /* XXXbe called with obj locked */ + if (!LOCKED_OBJ_GET_CLASS(obj)->delProperty(cx, obj, SPROP_USERID(sprop), + rval)) { + OBJ_DROP_PROPERTY(cx, obj, prop); + return JS_FALSE; + } + + scope = OBJ_SCOPE(obj); + if (SPROP_HAS_VALID_SLOT(sprop, scope)) + GC_POKE(cx, LOCKED_OBJ_GET_SLOT(obj, sprop->slot)); + + PROPERTY_CACHE_FILL(&cx->runtime->propertyCache, obj, id, NULL); + ok = js_RemoveScopeProperty(cx, scope, id); + OBJ_DROP_PROPERTY(cx, obj, prop); + return ok; + +#else /* !JS_HAS_PROP_DELETE */ + + jsval null = JSVAL_NULL; + + *rval = JSVAL_VOID; + return js_SetProperty(cx, obj, id, &null); + +#endif /* !JS_HAS_PROP_DELETE */ +} + +JSBool +js_DefaultValue(JSContext *cx, JSObject *obj, JSType hint, jsval *vp) +{ + jsval v; + JSString *str; + + v = OBJECT_TO_JSVAL(obj); + switch (hint) { + case JSTYPE_STRING: + /* + * Propagate the exception if js_TryMethod finds an appropriate + * method, and calling that method returned failure. + */ + if (!js_TryMethod(cx, obj, cx->runtime->atomState.toStringAtom, 0, NULL, + &v)) + return JS_FALSE; + + if (!JSVAL_IS_PRIMITIVE(v)) { + if (!OBJ_GET_CLASS(cx, obj)->convert(cx, obj, hint, &v)) + return JS_FALSE; + + /* + * JS1.2 never failed (except for malloc failure) to convert an + * object to a string. ECMA requires an error if both toString + * and valueOf fail to produce a primitive value. + */ + if (!JSVAL_IS_PRIMITIVE(v) && cx->version == JSVERSION_1_2) { + char *bytes = JS_smprintf("[object %s]", + OBJ_GET_CLASS(cx, obj)->name); + if (!bytes) + return JS_FALSE; + str = JS_NewString(cx, bytes, strlen(bytes)); + if (!str) { + free(bytes); + return JS_FALSE; + } + v = STRING_TO_JSVAL(str); + goto out; + } + } + break; + + default: + if (!OBJ_GET_CLASS(cx, obj)->convert(cx, obj, hint, &v)) + return JS_FALSE; + if (!JSVAL_IS_PRIMITIVE(v)) { + JSType type = JS_TypeOfValue(cx, v); + if (type == hint || + (type == JSTYPE_FUNCTION && hint == JSTYPE_OBJECT)) { + goto out; + } + /* Don't convert to string (source object literal) for JS1.2. */ + if (cx->version == JSVERSION_1_2 && hint == JSTYPE_BOOLEAN) + goto out; + if (!js_TryMethod(cx, obj, cx->runtime->atomState.toStringAtom, 0, + NULL, &v)) + return JS_FALSE; + } + break; + } + if (!JSVAL_IS_PRIMITIVE(v)) { + /* Avoid recursive death through js_DecompileValueGenerator. */ + if (hint == JSTYPE_STRING) { + str = JS_InternString(cx, OBJ_GET_CLASS(cx, obj)->name); + if (!str) + return JS_FALSE; + } else { + str = NULL; + } + *vp = OBJECT_TO_JSVAL(obj); + str = js_DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, v, str); + if (str) { + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, + JSMSG_CANT_CONVERT_TO, + JS_GetStringBytes(str), + (hint == JSTYPE_VOID) + ? "primitive type" + : js_type_str[hint]); + } + return JS_FALSE; + } +out: + *vp = v; + return JS_TRUE; +} + +JSIdArray * +js_NewIdArray(JSContext *cx, jsint length) +{ + JSIdArray *ida; + + ida = (JSIdArray *) + JS_malloc(cx, sizeof(JSIdArray) + (length - 1) * sizeof(jsval)); + if (ida) + ida->length = length; + return ida; +} + +JSIdArray * +js_GrowIdArray(JSContext *cx, JSIdArray *ida, jsint length) +{ + ida = (JSIdArray *) + JS_realloc(cx, ida, sizeof(JSIdArray) + (length - 1) * sizeof(jsval)); + if (ida) + ida->length = length; + return ida; +} + +/* Private type used to iterate over all properties of a native JS object */ +typedef struct JSNativeIteratorState { + jsint next_index; /* index into jsid array */ + JSIdArray *ida; /* All property ids in enumeration */ +} JSNativeIteratorState; + +/* + * This function is used to enumerate the properties of native JSObjects + * and those host objects that do not define a JSNewEnumerateOp-style iterator + * function. + */ +JSBool +js_Enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op, + jsval *statep, jsid *idp) +{ + JSObject *proto_obj; + JSClass *clasp; + JSEnumerateOp enumerate; + JSScopeProperty *sprop, *lastProp; + jsint i, length; + JSScope *scope; + JSIdArray *ida; + JSNativeIteratorState *state; + + clasp = OBJ_GET_CLASS(cx, obj); + enumerate = clasp->enumerate; + if (clasp->flags & JSCLASS_NEW_ENUMERATE) + return ((JSNewEnumerateOp) enumerate)(cx, obj, enum_op, statep, idp); + + switch (enum_op) { + + case JSENUMERATE_INIT: + if (!enumerate(cx, obj)) + goto init_error; + length = 0; + + /* + * The set of all property ids is pre-computed when the iterator + * is initialized so as to avoid problems with properties being + * deleted during the iteration. + */ + JS_LOCK_OBJ(cx, obj); + scope = OBJ_SCOPE(obj); + + /* + * If this object shares a scope with its prototype, don't enumerate + * its properties. Otherwise they will be enumerated a second time + * when the prototype object is enumerated. + */ + proto_obj = OBJ_GET_PROTO(cx, obj); + if (proto_obj && scope == OBJ_SCOPE(proto_obj)) { + ida = js_NewIdArray(cx, 0); + if (!ida) { + JS_UNLOCK_OBJ(cx, obj); + goto init_error; + } + } else { + /* Object has a private scope; Enumerate all props in scope. */ + for (sprop = lastProp = SCOPE_LAST_PROP(scope); sprop; + sprop = sprop->parent) { + if ((sprop->attrs & JSPROP_ENUMERATE) && + !(sprop->flags & SPROP_IS_ALIAS) && + (!SCOPE_HAD_MIDDLE_DELETE(scope) || + SCOPE_HAS_PROPERTY(scope, sprop))) { + length++; + } + } + ida = js_NewIdArray(cx, length); + if (!ida) { + JS_UNLOCK_OBJ(cx, obj); + goto init_error; + } + i = length; + for (sprop = lastProp; sprop; sprop = sprop->parent) { + if ((sprop->attrs & JSPROP_ENUMERATE) && + !(sprop->flags & SPROP_IS_ALIAS) && + (!SCOPE_HAD_MIDDLE_DELETE(scope) || + SCOPE_HAS_PROPERTY(scope, sprop))) { + JS_ASSERT(i > 0); + ida->vector[--i] = sprop->id; + } + } + } + JS_UNLOCK_OBJ(cx, obj); + + state = (JSNativeIteratorState *) + JS_malloc(cx, sizeof(JSNativeIteratorState)); + if (!state) { + JS_DestroyIdArray(cx, ida); + goto init_error; + } + state->ida = ida; + state->next_index = 0; + *statep = PRIVATE_TO_JSVAL(state); + if (idp) + *idp = INT_TO_JSVAL(length); + return JS_TRUE; + + case JSENUMERATE_NEXT: + state = (JSNativeIteratorState *) JSVAL_TO_PRIVATE(*statep); + ida = state->ida; + length = ida->length; + if (state->next_index != length) { + *idp = ida->vector[state->next_index++]; + return JS_TRUE; + } + + /* Fall through ... */ + + case JSENUMERATE_DESTROY: + state = (JSNativeIteratorState *) JSVAL_TO_PRIVATE(*statep); + JS_DestroyIdArray(cx, state->ida); + JS_free(cx, state); + *statep = JSVAL_NULL; + return JS_TRUE; + + default: + JS_ASSERT(0); + return JS_FALSE; + } + +init_error: + *statep = JSVAL_NULL; + return JS_FALSE; +} + +JSBool +js_CheckAccess(JSContext *cx, JSObject *obj, jsid id, JSAccessMode mode, + jsval *vp, uintN *attrsp) +{ + JSObject *pobj; + JSProperty *prop; + JSScopeProperty *sprop; + JSClass *clasp; + JSBool ok; + + if (!js_LookupProperty(cx, obj, id, &pobj, &prop)) + return JS_FALSE; + if (!prop) { + *vp = JSVAL_VOID; + *attrsp = 0; + clasp = OBJ_GET_CLASS(cx, obj); + return !clasp->checkAccess || + clasp->checkAccess(cx, obj, ID_TO_VALUE(id), mode, vp); + } + if (!OBJ_IS_NATIVE(pobj)) { + OBJ_DROP_PROPERTY(cx, pobj, prop); + return OBJ_CHECK_ACCESS(cx, pobj, id, mode, vp, attrsp); + } + sprop = (JSScopeProperty *)prop; + *vp = (SPROP_HAS_VALID_SLOT(sprop, OBJ_SCOPE(pobj))) + ? LOCKED_OBJ_GET_SLOT(pobj, sprop->slot) + : JSVAL_VOID; + *attrsp = sprop->attrs; + clasp = LOCKED_OBJ_GET_CLASS(obj); + if (clasp->checkAccess) { + JS_UNLOCK_OBJ(cx, pobj); + ok = clasp->checkAccess(cx, obj, ID_TO_VALUE(id), mode, vp); + JS_LOCK_OBJ(cx, pobj); + } else { + ok = JS_TRUE; + } + OBJ_DROP_PROPERTY(cx, pobj, prop); + return ok; +} + +#ifdef JS_THREADSAFE +void +js_DropProperty(JSContext *cx, JSObject *obj, JSProperty *prop) +{ + JS_UNLOCK_OBJ(cx, obj); +} +#endif + +static void +ReportIsNotFunction(JSContext *cx, jsval *vp, uintN flags) +{ + /* + * The decompiler may need to access the args of the function in + * progress rather than the one we had hoped to call. + * So we switch the cx->fp to the frame below us. We stick the + * current frame in the dormantFrameChain to protect it from gc. + */ + + JSStackFrame *fp = cx->fp; + if (fp->down) { + JS_ASSERT(!fp->dormantNext); + fp->dormantNext = cx->dormantFrameChain; + cx->dormantFrameChain = fp; + cx->fp = fp->down; + } + + js_ReportIsNotFunction(cx, vp, flags); + + if (fp->down) { + JS_ASSERT(cx->dormantFrameChain == fp); + cx->dormantFrameChain = fp->dormantNext; + fp->dormantNext = NULL; + cx->fp = fp; + } +} + +JSBool +js_Call(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + JSClass *clasp; + + clasp = OBJ_GET_CLASS(cx, JSVAL_TO_OBJECT(argv[-2])); + if (!clasp->call) { + ReportIsNotFunction(cx, &argv[-2], 0); + return JS_FALSE; + } + return clasp->call(cx, obj, argc, argv, rval); +} + +JSBool +js_Construct(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval) +{ + JSClass *clasp; + + clasp = OBJ_GET_CLASS(cx, JSVAL_TO_OBJECT(argv[-2])); + if (!clasp->construct) { + ReportIsNotFunction(cx, &argv[-2], JSV2F_CONSTRUCT); + return JS_FALSE; + } + return clasp->construct(cx, obj, argc, argv, rval); +} + +JSBool +js_HasInstance(JSContext *cx, JSObject *obj, jsval v, JSBool *bp) +{ + JSClass *clasp; + + clasp = OBJ_GET_CLASS(cx, obj); + if (clasp->hasInstance) + return clasp->hasInstance(cx, obj, v, bp); + *bp = JS_FALSE; + return JS_TRUE; +} + +JSBool +js_IsDelegate(JSContext *cx, JSObject *obj, jsval v, JSBool *bp) +{ + JSObject *obj2; + + *bp = JS_FALSE; + if (JSVAL_IS_PRIMITIVE(v)) + return JS_TRUE; + obj2 = JSVAL_TO_OBJECT(v); + while ((obj2 = OBJ_GET_PROTO(cx, obj2)) != NULL) { + if (obj2 == obj) { + *bp = JS_TRUE; + break; + } + } + return JS_TRUE; +} + +JSBool +js_GetClassPrototype(JSContext *cx, const char *name, JSObject **protop) +{ + return GetClassPrototype(cx, NULL, name, protop); +} + +static JSBool +GetClassPrototype(JSContext *cx, JSObject *scope, const char *name, + JSObject **protop) +{ + jsval v; + JSObject *ctor; + + if (!FindConstructor(cx, scope, name, &v)) + return JS_FALSE; + if (JSVAL_IS_FUNCTION(cx, v)) { + ctor = JSVAL_TO_OBJECT(v); + if (!OBJ_GET_PROPERTY(cx, ctor, + (jsid)cx->runtime->atomState.classPrototypeAtom, + &v)) { + return JS_FALSE; + } + } + *protop = JSVAL_IS_OBJECT(v) ? JSVAL_TO_OBJECT(v) : NULL; + return JS_TRUE; +} + +JSBool +js_SetClassPrototype(JSContext *cx, JSObject *ctor, JSObject *proto, + uintN attrs) +{ + /* + * Use the given attributes for the prototype property of the constructor, + * as user-defined constructors have a DontEnum | DontDelete prototype (it + * may be reset), while native or "system" constructors require DontEnum | + * ReadOnly | DontDelete. + */ + if (!OBJ_DEFINE_PROPERTY(cx, ctor, + (jsid)cx->runtime->atomState.classPrototypeAtom, + OBJECT_TO_JSVAL(proto), NULL, NULL, + attrs, NULL)) { + return JS_FALSE; + } + + /* + * ECMA says that Object.prototype.constructor, or f.prototype.constructor + * for a user-defined function f, is DontEnum. + */ + return OBJ_DEFINE_PROPERTY(cx, proto, + (jsid)cx->runtime->atomState.constructorAtom, + OBJECT_TO_JSVAL(ctor), NULL, NULL, + 0, NULL); +} + +JSBool +js_ValueToObject(JSContext *cx, jsval v, JSObject **objp) +{ + JSObject *obj; + + if (JSVAL_IS_NULL(v) || JSVAL_IS_VOID(v)) { + obj = NULL; + } else if (JSVAL_IS_OBJECT(v)) { + obj = JSVAL_TO_OBJECT(v); + if (!OBJ_DEFAULT_VALUE(cx, obj, JSTYPE_OBJECT, &v)) + return JS_FALSE; + if (JSVAL_IS_OBJECT(v)) + obj = JSVAL_TO_OBJECT(v); + } else { + if (JSVAL_IS_STRING(v)) { + obj = js_StringToObject(cx, JSVAL_TO_STRING(v)); + } else if (JSVAL_IS_INT(v)) { + obj = js_NumberToObject(cx, (jsdouble)JSVAL_TO_INT(v)); + } else if (JSVAL_IS_DOUBLE(v)) { + obj = js_NumberToObject(cx, *JSVAL_TO_DOUBLE(v)); + } else { + JS_ASSERT(JSVAL_IS_BOOLEAN(v)); + obj = js_BooleanToObject(cx, JSVAL_TO_BOOLEAN(v)); + } + if (!obj) + return JS_FALSE; + } + *objp = obj; + return JS_TRUE; +} + +JSObject * +js_ValueToNonNullObject(JSContext *cx, jsval v) +{ + JSObject *obj; + JSString *str; + + if (!js_ValueToObject(cx, v, &obj)) + return NULL; + if (!obj) { + str = js_DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, v, NULL); + if (str) { + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, + JSMSG_NO_PROPERTIES, JS_GetStringBytes(str)); + } + } + return obj; +} + +JSBool +js_TryValueOf(JSContext *cx, JSObject *obj, JSType type, jsval *rval) +{ +#if JS_HAS_VALUEOF_HINT + jsval argv[1]; + + argv[0] = ATOM_KEY(cx->runtime->atomState.typeAtoms[type]); + return js_TryMethod(cx, obj, cx->runtime->atomState.valueOfAtom, 1, argv, + rval); +#else + return js_TryMethod(cx, obj, cx->runtime->atomState.valueOfAtom, 0, NULL, + rval); +#endif +} + +JSBool +js_TryMethod(JSContext *cx, JSObject *obj, JSAtom *atom, + uintN argc, jsval *argv, jsval *rval) +{ + JSErrorReporter older; + jsval fval; + JSBool ok; + + /* + * Report failure only if an appropriate method was found, and calling it + * returned failure. We propagate failure in this case to make exceptions + * behave properly. + */ + older = JS_SetErrorReporter(cx, NULL); + if (OBJ_GET_PROPERTY(cx, obj, (jsid)atom, &fval) && + !JSVAL_IS_PRIMITIVE(fval)) { + ok = js_InternalCall(cx, obj, fval, argc, argv, rval); + } else { + ok = JS_TRUE; + } + JS_SetErrorReporter(cx, older); + return ok; +} + +#if JS_HAS_XDR + +#include "jsxdrapi.h" + +JSBool +js_XDRObject(JSXDRState *xdr, JSObject **objp) +{ + JSContext *cx; + JSClass *clasp; + const char *className; + uint32 classId, classDef; + JSBool ok; + JSObject *proto; + + cx = xdr->cx; + if (xdr->mode == JSXDR_ENCODE) { + clasp = OBJ_GET_CLASS(cx, *objp); + className = clasp->name; + classId = JS_XDRFindClassIdByName(xdr, className); + classDef = !classId; + if (classDef && !JS_XDRRegisterClass(xdr, clasp, &classId)) + return JS_FALSE; + } else { + classDef = 0; + className = NULL; + clasp = NULL; /* quell GCC overwarning */ + } + + /* XDR a flag word followed (if true) by the class name. */ + if (!JS_XDRUint32(xdr, &classDef)) + return JS_FALSE; + if (classDef && !JS_XDRCString(xdr, (char **) &className)) + return JS_FALSE; + + /* From here on, return through out: to free className if it was set. */ + ok = JS_XDRUint32(xdr, &classId); + if (!ok) + goto out; + + if (xdr->mode != JSXDR_ENCODE) { + if (classDef) { + ok = js_GetClassPrototype(cx, className, &proto); + if (!ok) + goto out; + clasp = OBJ_GET_CLASS(cx, proto); + ok = JS_XDRRegisterClass(xdr, clasp, &classId); + if (!ok) + goto out; + } else { + clasp = JS_XDRFindClassById(xdr, classId); + if (!clasp) { + char numBuf[12]; + JS_snprintf(numBuf, sizeof numBuf, "%ld", (long)classId); + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, + JSMSG_CANT_FIND_CLASS, numBuf); + ok = JS_FALSE; + goto out; + } + } + } + + if (!clasp->xdrObject) { + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, + JSMSG_CANT_XDR_CLASS, clasp->name); + ok = JS_FALSE; + } else { + ok = clasp->xdrObject(xdr, objp); + } +out: + if (xdr->mode != JSXDR_ENCODE && className) + JS_free(cx, (void *)className); + return ok; +} + +#endif /* JS_HAS_XDR */ + +#ifdef DEBUG_brendan + +#include +#include + +uint32 js_entry_count_max; +uint32 js_entry_count_sum; +double js_entry_count_sqsum; +uint32 js_entry_count_hist[11]; + +static void +MeterEntryCount(uintN count) +{ + if (count) { + js_entry_count_sum += count; + js_entry_count_sqsum += (double)count * count; + if (count > js_entry_count_max) + js_entry_count_max = count; + } + js_entry_count_hist[JS_MIN(count, 10)]++; +} + +void +js_DumpScopeMeters(JSRuntime *rt) +{ + static FILE *logfp; + if (!logfp) + logfp = fopen("/tmp/scope.stats", "a"); + + { + double mean = 0., var = 0., sigma = 0.; + double nscopes = rt->liveScopes; + double nentrys = js_entry_count_sum; + if (nscopes > 0 && nentrys >= 0) { + mean = nentrys / nscopes; + var = nscopes * js_entry_count_sqsum - nentrys * nentrys; + if (var < 0.0 || nscopes <= 1) + var = 0.0; + else + var /= nscopes * (nscopes - 1); + + /* Windows says sqrt(0.0) is "-1.#J" (?!) so we must test. */ + sigma = (var != 0.) ? sqrt(var) : 0.; + } + + fprintf(logfp, + "scopes %g entries %g mean %g sigma %g max %u", + nscopes, nentrys, mean, sigma, js_entry_count_max); + } + + fprintf(logfp, " histogram %u %u %u %u %u %u %u %u %u %u %u\n", + js_entry_count_hist[0], js_entry_count_hist[1], + js_entry_count_hist[2], js_entry_count_hist[3], + js_entry_count_hist[4], js_entry_count_hist[5], + js_entry_count_hist[6], js_entry_count_hist[7], + js_entry_count_hist[8], js_entry_count_hist[9], + js_entry_count_hist[10]); + js_entry_count_sum = js_entry_count_max = 0; + js_entry_count_sqsum = 0; + memset(js_entry_count_hist, 0, sizeof js_entry_count_hist); + fflush(logfp); +} + +#endif /* DEBUG_brendan */ + +uint32 +js_Mark(JSContext *cx, JSObject *obj, void *arg) +{ + JSScope *scope; + JSScopeProperty *sprop; + JSClass *clasp; + + JS_ASSERT(OBJ_IS_NATIVE(obj)); + scope = OBJ_SCOPE(obj); +#ifdef DEBUG_brendan + if (scope->object == obj) + MeterEntryCount(scope->entryCount); +#endif + + JS_ASSERT(!SCOPE_LAST_PROP(scope) || + SCOPE_HAS_PROPERTY(scope, SCOPE_LAST_PROP(scope))); + + for (sprop = SCOPE_LAST_PROP(scope); sprop; sprop = sprop->parent) { + if (SCOPE_HAD_MIDDLE_DELETE(scope) && !SCOPE_HAS_PROPERTY(scope, sprop)) + continue; + MARK_SCOPE_PROPERTY(sprop); + if (!JSVAL_IS_INT(sprop->id)) + GC_MARK_ATOM(cx, (JSAtom *)sprop->id, arg); + +#if JS_HAS_GETTER_SETTER + if (sprop->attrs & (JSPROP_GETTER | JSPROP_SETTER)) { +#ifdef GC_MARK_DEBUG + char buf[64]; + JSAtom *atom = (JSAtom *)sprop->id; + const char *id = (atom && ATOM_IS_STRING(atom)) + ? JS_GetStringBytes(ATOM_TO_STRING(atom)) + : "unknown"; +#endif + + if (sprop->attrs & JSPROP_GETTER) { +#ifdef GC_MARK_DEBUG + JS_snprintf(buf, sizeof buf, "%s %s", + id, js_getter_str); +#endif + GC_MARK(cx, + JSVAL_TO_GCTHING((jsval) sprop->getter), + buf, + arg); + } + if (sprop->attrs & JSPROP_SETTER) { +#ifdef GC_MARK_DEBUG + JS_snprintf(buf, sizeof buf, "%s %s", + id, js_setter_str); +#endif + GC_MARK(cx, + JSVAL_TO_GCTHING((jsval) sprop->setter), + buf, + arg); + } + } +#endif /* JS_HAS_GETTER_SETTER */ + } + + /* No one runs while the GC is running, so we can use LOCKED_... here. */ + clasp = LOCKED_OBJ_GET_CLASS(obj); + if (clasp->mark) + (void) clasp->mark(cx, obj, arg); + + if (scope->object != obj) { + /* + * An unmutated object that shares a prototype's scope. We can't tell + * how many slots are allocated and in use at obj->slots by looking at + * scope, so we get obj->slots' length from its -1'st element. + */ + return (uint32) obj->slots[-1]; + } + return JS_MIN(obj->map->freeslot, obj->map->nslots); +} + +void +js_Clear(JSContext *cx, JSObject *obj) +{ + JSScope *scope; + JSRuntime *rt; + JSScopeProperty *sprop; + uint32 i, n; + + /* + * Clear our scope and the property cache of all obj's properties only if + * obj owns the scope (i.e., not if obj is unmutated and therefore sharing + * its prototype's scope). NB: we do not clear any reserved slots lying + * below JSSLOT_FREE(clasp). + */ + JS_LOCK_OBJ(cx, obj); + scope = OBJ_SCOPE(obj); + if (scope->object == obj) { + /* Clear the property cache before we clear the scope. */ + rt = cx->runtime; + for (sprop = SCOPE_LAST_PROP(scope); sprop; sprop = sprop->parent) { + if (!SCOPE_HAD_MIDDLE_DELETE(scope) || + SCOPE_HAS_PROPERTY(scope, sprop)) { + PROPERTY_CACHE_FILL(&rt->propertyCache, obj, sprop->id, NULL); + } + } + + /* Now that we're done using scope->lastProp/table, clear scope. */ + js_ClearScope(cx, scope); + + /* Clear slot values and reset freeslot so we're consistent. */ + i = scope->map.nslots; + n = JSSLOT_FREE(LOCKED_OBJ_GET_CLASS(obj)); + while (--i >= n) + obj->slots[i] = JSVAL_VOID; + scope->map.freeslot = n; + } + JS_UNLOCK_OBJ(cx, obj); +} + +jsval +js_GetRequiredSlot(JSContext *cx, JSObject *obj, uint32 slot) +{ + jsval v; + + JS_LOCK_OBJ(cx, obj); + v = (slot < (uint32) obj->slots[-1]) ? obj->slots[slot] : JSVAL_VOID; + JS_UNLOCK_OBJ(cx, obj); + return v; +} + +void +js_SetRequiredSlot(JSContext *cx, JSObject *obj, uint32 slot, jsval v) +{ + uint32 nslots, rlimit, i; + JSClass *clasp; + jsval *newslots; + + JS_LOCK_OBJ(cx, obj); + nslots = (uint32) obj->slots[-1]; + if (slot >= nslots) { + clasp = LOCKED_OBJ_GET_CLASS(obj); + rlimit = JSSLOT_START(clasp) + JSCLASS_RESERVED_SLOTS(clasp); + JS_ASSERT(slot < rlimit); + if (rlimit > nslots) + nslots = rlimit; + + newslots = (jsval *) + JS_realloc(cx, obj->slots - 1, (nslots + 1) * sizeof(jsval)); + if (!newslots) { + JS_UNLOCK_OBJ(cx, obj); + return; + } + for (i = 1 + newslots[0]; i <= rlimit; i++) + newslots[i] = JSVAL_VOID; + newslots[0] = nslots; + if (OBJ_SCOPE(obj)->object == obj) + obj->map->nslots = nslots; + obj->slots = newslots + 1; + } + + obj->slots[slot] = v; + JS_UNLOCK_OBJ(cx, obj); +} + +#ifdef DEBUG + +/* Routines to print out values during debugging. */ + +void printChar(jschar *cp) { + fprintf(stderr, "jschar* (0x%p) \"", (void *)cp); + while (*cp) + fputc(*cp++, stderr); + fputc('"', stderr); + fputc('\n', stderr); +} + +void printString(JSString *str) { + size_t i, n; + jschar *s; + fprintf(stderr, "string (0x%p) \"", (void *)str); + s = JSSTRING_CHARS(str); + for (i=0, n=JSSTRING_LENGTH(str); i < n; i++) + fputc(s[i], stderr); + fputc('"', stderr); + fputc('\n', stderr); +} + +void printVal(JSContext *cx, jsval val); + +void printObj(JSContext *cx, JSObject *jsobj) { + jsuint i; + jsval val; + JSClass *clasp; + + fprintf(stderr, "object 0x%p\n", (void *)jsobj); + clasp = OBJ_GET_CLASS(cx, jsobj); + fprintf(stderr, "class 0x%p %s\n", (void *)clasp, clasp->name); + for (i=0; i < jsobj->map->nslots; i++) { + fprintf(stderr, "slot %3d ", i); + val = jsobj->slots[i]; + if (JSVAL_IS_OBJECT(val)) + fprintf(stderr, "object 0x%p\n", (void *)JSVAL_TO_OBJECT(val)); + else + printVal(cx, val); + } +} + +void printVal(JSContext *cx, jsval val) { + fprintf(stderr, "val %d (0x%p) = ", (int)val, (void *)val); + if (JSVAL_IS_NULL(val)) { + fprintf(stderr, "null\n"); + } else if (JSVAL_IS_VOID(val)) { + fprintf(stderr, "undefined\n"); + } else if (JSVAL_IS_OBJECT(val)) { + printObj(cx, JSVAL_TO_OBJECT(val)); + } else if (JSVAL_IS_INT(val)) { + fprintf(stderr, "(int) %d\n", JSVAL_TO_INT(val)); + } else if (JSVAL_IS_STRING(val)) { + printString(JSVAL_TO_STRING(val)); + } else if (JSVAL_IS_DOUBLE(val)) { + fprintf(stderr, "(double) %g\n", *JSVAL_TO_DOUBLE(val)); + } else { + JS_ASSERT(JSVAL_IS_BOOLEAN(val)); + fprintf(stderr, "(boolean) %s\n", + JSVAL_TO_BOOLEAN(val) ? "true" : "false"); + } + fflush(stderr); +} + +void printId(JSContext *cx, jsid id) { + fprintf(stderr, "id %d (0x%p) is ", (int)id, (void *)id); + printVal(cx, ID_TO_VALUE(id)); +} + +void printAtom(JSAtom *atom) { + printString(ATOM_TO_STRING(atom)); +} + +#endif diff --git a/src/dom/js/jsobj.h b/src/dom/js/jsobj.h new file mode 100644 index 000000000..a523194db --- /dev/null +++ b/src/dom/js/jsobj.h @@ -0,0 +1,464 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef jsobj_h___ +#define jsobj_h___ +/* + * JS object definitions. + * + * A JS object consists of a possibly-shared object descriptor containing + * ordered property names, called the map; and a dense vector of property + * values, called slots. The map/slot pointer pair is GC'ed, while the map + * is reference counted and the slot vector is malloc'ed. + */ +#include "jshash.h" /* Added by JSIFY */ +#include "jsprvtd.h" +#include "jspubtd.h" + +JS_BEGIN_EXTERN_C + +struct JSObjectMap { + jsrefcount nrefs; /* count of all referencing objects */ + JSObjectOps *ops; /* high level object operation vtable */ + uint32 nslots; /* length of obj->slots vector */ + uint32 freeslot; /* index of next free obj->slots element */ +}; + +/* Shorthand macros for frequently-made calls. */ +#if defined JS_THREADSAFE && defined DEBUG +#define OBJ_LOOKUP_PROPERTY(cx,obj,id,objp,propp) \ + (obj)->map->ops->lookupProperty(cx,obj,id,objp,propp,__FILE__,__LINE__) +#else +#define OBJ_LOOKUP_PROPERTY(cx,obj,id,objp,propp) \ + (obj)->map->ops->lookupProperty(cx,obj,id,objp,propp) +#endif +#define OBJ_DEFINE_PROPERTY(cx,obj,id,value,getter,setter,attrs,propp) \ + (obj)->map->ops->defineProperty(cx,obj,id,value,getter,setter,attrs,propp) +#define OBJ_GET_PROPERTY(cx,obj,id,vp) \ + (obj)->map->ops->getProperty(cx,obj,id,vp) +#define OBJ_SET_PROPERTY(cx,obj,id,vp) \ + (obj)->map->ops->setProperty(cx,obj,id,vp) +#define OBJ_GET_ATTRIBUTES(cx,obj,id,prop,attrsp) \ + (obj)->map->ops->getAttributes(cx,obj,id,prop,attrsp) +#define OBJ_SET_ATTRIBUTES(cx,obj,id,prop,attrsp) \ + (obj)->map->ops->setAttributes(cx,obj,id,prop,attrsp) +#define OBJ_DELETE_PROPERTY(cx,obj,id,rval) \ + (obj)->map->ops->deleteProperty(cx,obj,id,rval) +#define OBJ_DEFAULT_VALUE(cx,obj,hint,vp) \ + (obj)->map->ops->defaultValue(cx,obj,hint,vp) +#define OBJ_ENUMERATE(cx,obj,enum_op,statep,idp) \ + (obj)->map->ops->enumerate(cx,obj,enum_op,statep,idp) +#define OBJ_CHECK_ACCESS(cx,obj,id,mode,vp,attrsp) \ + (obj)->map->ops->checkAccess(cx,obj,id,mode,vp,attrsp) + +/* These four are time-optimized to avoid stub calls. */ +#define OBJ_THIS_OBJECT(cx,obj) \ + ((obj)->map->ops->thisObject \ + ? (obj)->map->ops->thisObject(cx,obj) \ + : (obj)) +#define OBJ_DROP_PROPERTY(cx,obj,prop) \ + ((obj)->map->ops->dropProperty \ + ? (obj)->map->ops->dropProperty(cx,obj,prop) \ + : (void)0) +#define OBJ_GET_REQUIRED_SLOT(cx,obj,slot) \ + ((obj)->map->ops->getRequiredSlot \ + ? (obj)->map->ops->getRequiredSlot(cx, obj, slot) \ + : JSVAL_VOID) +#define OBJ_SET_REQUIRED_SLOT(cx,obj,slot,v) \ + ((obj)->map->ops->setRequiredSlot \ + ? (obj)->map->ops->setRequiredSlot(cx, obj, slot, v) \ + : (void)0) + +/* + * In the original JS engine design, obj->slots pointed to a vector of length + * JS_INITIAL_NSLOTS words if obj->map was shared with a prototype object, + * else of length obj->map->nslots. With the advent of JS_GetReservedSlot, + * JS_SetReservedSlot, and JSCLASS_HAS_RESERVED_SLOTS (see jsapi.h), the size + * of the minimum length slots vector in the case where map is shared cannot + * be constant. This length starts at JS_INITIAL_NSLOTS, but may advance to + * include all the reserved slots. + * + * Therefore slots must be self-describing. Rather than tag its low order bit + * (a bit is all we need) to distinguish initial length from reserved length, + * we do "the BSTR thing": over-allocate slots by one jsval, and store the + * *net* length (counting usable slots, which have non-negative obj->slots[] + * indices) in obj->slots[-1]. All code that sets obj->slots must be aware of + * this hack -- you have been warned, and jsobj.c has been updated! + */ +struct JSObject { + JSObjectMap *map; + jsval *slots; +}; + +#define JSSLOT_PROTO 0 +#define JSSLOT_PARENT 1 +#define JSSLOT_CLASS 2 +#define JSSLOT_PRIVATE 3 +#define JSSLOT_START(clasp) (((clasp)->flags & JSCLASS_HAS_PRIVATE) \ + ? JSSLOT_PRIVATE + 1 \ + : JSSLOT_CLASS + 1) + +#define JSSLOT_FREE(clasp) (JSSLOT_START(clasp) \ + + JSCLASS_RESERVED_SLOTS(clasp)) + +#define JS_INITIAL_NSLOTS 5 + +#ifdef DEBUG +#define MAP_CHECK_SLOT(map,slot) \ + JS_ASSERT((uint32)slot < JS_MIN((map)->freeslot, (map)->nslots)) +#define OBJ_CHECK_SLOT(obj,slot) \ + MAP_CHECK_SLOT((obj)->map, slot) +#else +#define OBJ_CHECK_SLOT(obj,slot) ((void)0) +#endif + +/* Fast macros for accessing obj->slots while obj is locked (if thread-safe). */ +#define LOCKED_OBJ_GET_SLOT(obj,slot) \ + (OBJ_CHECK_SLOT(obj, slot), (obj)->slots[slot]) +#define LOCKED_OBJ_SET_SLOT(obj,slot,value) \ + (OBJ_CHECK_SLOT(obj, slot), (obj)->slots[slot] = (value)) +#define LOCKED_OBJ_GET_PROTO(obj) \ + JSVAL_TO_OBJECT(LOCKED_OBJ_GET_SLOT(obj, JSSLOT_PROTO)) +#define LOCKED_OBJ_GET_CLASS(obj) \ + ((JSClass *)JSVAL_TO_PRIVATE(LOCKED_OBJ_GET_SLOT(obj, JSSLOT_CLASS))) + +#ifdef JS_THREADSAFE + +/* Thread-safe functions and wrapper macros for accessing obj->slots. */ +#define OBJ_GET_SLOT(cx,obj,slot) \ + (OBJ_CHECK_SLOT(obj, slot), \ + (OBJ_IS_NATIVE(obj) && OBJ_SCOPE(obj)->ownercx == cx) \ + ? LOCKED_OBJ_GET_SLOT(obj, slot) \ + : js_GetSlotThreadSafe(cx, obj, slot)) + +#define OBJ_SET_SLOT(cx,obj,slot,value) \ + (OBJ_CHECK_SLOT(obj, slot), \ + (OBJ_IS_NATIVE(obj) && OBJ_SCOPE(obj)->ownercx == cx) \ + ? (void) LOCKED_OBJ_SET_SLOT(obj, slot, value) \ + : js_SetSlotThreadSafe(cx, obj, slot, value)) + +/* + * If thread-safe, define an OBJ_GET_SLOT wrapper that bypasses, for a native + * object, the lock-free "fast path" test of (OBJ_SCOPE(obj)->ownercx == cx), + * to avoid needlessly switching from lock-free to lock-full scope when doing + * GC on a different context from the last one to own the scope. The caller + * in this case is probably a JSClass.mark function, e.g., fun_mark, or maybe + * a finalizer. + * + * The GC runs only when all threads except the one on which the GC is active + * are suspended at GC-safe points, so there is no hazard in directly accessing + * obj->slots[slot] from the GC's thread, once rt->gcRunning has been set. See + * jsgc.c for details. + */ +#define THREAD_IS_RUNNING_GC(rt, thread) \ + ((rt)->gcRunning && (rt)->gcThread == (thread)) + +#define CX_THREAD_IS_RUNNING_GC(cx) \ + THREAD_IS_RUNNING_GC((cx)->runtime, (cx)->thread) + +#define GC_AWARE_GET_SLOT(cx, obj, slot) \ + ((OBJ_IS_NATIVE(obj) && CX_THREAD_IS_RUNNING_GC(cx)) \ + ? (obj)->slots[slot] \ + : OBJ_GET_SLOT(cx, obj, slot)) + +#else /* !JS_THREADSAFE */ + +#define OBJ_GET_SLOT(cx,obj,slot) LOCKED_OBJ_GET_SLOT(obj,slot) +#define OBJ_SET_SLOT(cx,obj,slot,value) LOCKED_OBJ_SET_SLOT(obj,slot,value) +#define GC_AWARE_GET_SLOT(cx,obj,slot) LOCKED_OBJ_GET_SLOT(obj,slot) + +#endif /* !JS_THREADSAFE */ + +/* Thread-safe proto, parent, and class access macros. */ +#define OBJ_GET_PROTO(cx,obj) \ + JSVAL_TO_OBJECT(OBJ_GET_SLOT(cx, obj, JSSLOT_PROTO)) +#define OBJ_SET_PROTO(cx,obj,proto) \ + OBJ_SET_SLOT(cx, obj, JSSLOT_PROTO, OBJECT_TO_JSVAL(proto)) + +#define OBJ_GET_PARENT(cx,obj) \ + JSVAL_TO_OBJECT(OBJ_GET_SLOT(cx, obj, JSSLOT_PARENT)) +#define OBJ_SET_PARENT(cx,obj,parent) \ + OBJ_SET_SLOT(cx, obj, JSSLOT_PARENT, OBJECT_TO_JSVAL(parent)) + +#define OBJ_GET_CLASS(cx,obj) \ + ((JSClass *)JSVAL_TO_PRIVATE(OBJ_GET_SLOT(cx, obj, JSSLOT_CLASS))) + +/* Test whether a map or object is native. */ +#define MAP_IS_NATIVE(map) \ + ((map)->ops == &js_ObjectOps || \ + ((map)->ops && (map)->ops->newObjectMap == js_ObjectOps.newObjectMap)) + +#define OBJ_IS_NATIVE(obj) MAP_IS_NATIVE((obj)->map) + +extern JS_FRIEND_DATA(JSObjectOps) js_ObjectOps; +extern JS_FRIEND_DATA(JSObjectOps) js_WithObjectOps; +extern JSClass js_ObjectClass; +extern JSClass js_WithClass; + +struct JSSharpObjectMap { + jsrefcount depth; + jsatomid sharpgen; + JSHashTable *table; +}; + +#define SHARP_BIT ((jsatomid) 1) +#define BUSY_BIT ((jsatomid) 2) +#define SHARP_ID_SHIFT 2 +#define IS_SHARP(he) ((jsatomid)(he)->value & SHARP_BIT) +#define MAKE_SHARP(he) ((he)->value = (void*)((jsatomid)(he)->value|SHARP_BIT)) +#define IS_BUSY(he) ((jsatomid)(he)->value & BUSY_BIT) +#define MAKE_BUSY(he) ((he)->value = (void*)((jsatomid)(he)->value|BUSY_BIT)) +#define CLEAR_BUSY(he) ((he)->value = (void*)((jsatomid)(he)->value&~BUSY_BIT)) + +extern JSHashEntry * +js_EnterSharpObject(JSContext *cx, JSObject *obj, JSIdArray **idap, + jschar **sp); + +extern void +js_LeaveSharpObject(JSContext *cx, JSIdArray **idap); + +extern JSBool +js_obj_toSource(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval); + +extern JSBool +js_obj_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval); + +extern JSObject * +js_InitObjectClass(JSContext *cx, JSObject *obj); + +/* Select Object.prototype method names shared between jsapi.c and jsobj.c. */ +extern const char js_watch_str[]; +extern const char js_unwatch_str[]; +extern const char js_hasOwnProperty_str[]; +extern const char js_isPrototypeOf_str[]; +extern const char js_propertyIsEnumerable_str[]; +extern const char js_defineGetter_str[]; +extern const char js_defineSetter_str[]; +extern const char js_lookupGetter_str[]; +extern const char js_lookupSetter_str[]; + +extern void +js_InitObjectMap(JSObjectMap *map, jsrefcount nrefs, JSObjectOps *ops, + JSClass *clasp); + +extern JSObjectMap * +js_NewObjectMap(JSContext *cx, jsrefcount nrefs, JSObjectOps *ops, + JSClass *clasp, JSObject *obj); + +extern void +js_DestroyObjectMap(JSContext *cx, JSObjectMap *map); + +extern JSObjectMap * +js_HoldObjectMap(JSContext *cx, JSObjectMap *map); + +extern JSObjectMap * +js_DropObjectMap(JSContext *cx, JSObjectMap *map, JSObject *obj); + +extern JSObject * +js_NewObject(JSContext *cx, JSClass *clasp, JSObject *proto, JSObject *parent); + +extern JSObject * +js_ConstructObject(JSContext *cx, JSClass *clasp, JSObject *proto, + JSObject *parent, uintN argc, jsval *argv); + +extern void +js_FinalizeObject(JSContext *cx, JSObject *obj); + +extern JSBool +js_AllocSlot(JSContext *cx, JSObject *obj, uint32 *slotp); + +extern void +js_FreeSlot(JSContext *cx, JSObject *obj, uint32 slot); + +/* + * Find or create a property named by id in obj's scope, with the given getter + * and setter, slot, attributes, and other members. + */ +extern JSScopeProperty * +js_AddNativeProperty(JSContext *cx, JSObject *obj, jsid id, + JSPropertyOp getter, JSPropertyOp setter, uint32 slot, + uintN attrs, uintN flags, intN shortid); + +/* + * Change sprop to have the given attrs, getter, and setter in scope, morphing + * it into a potentially new JSScopeProperty. Return a pointer to the changed + * or identical property. + */ +extern JSScopeProperty * +js_ChangeNativePropertyAttrs(JSContext *cx, JSObject *obj, + JSScopeProperty *sprop, uintN attrs, uintN mask, + JSPropertyOp getter, JSPropertyOp setter); + +/* + * On error, return false. On success, if propp is non-null, return true with + * obj locked and with a held property in *propp; if propp is null, return true + * but release obj's lock first. Therefore all callers who pass non-null propp + * result parameters must later call OBJ_DROP_PROPERTY(cx, obj, *propp) both to + * drop the held property, and to release the lock on obj. + */ +extern JSBool +js_DefineProperty(JSContext *cx, JSObject *obj, jsid id, jsval value, + JSPropertyOp getter, JSPropertyOp setter, uintN attrs, + JSProperty **propp); + +extern JSBool +js_DefineNativeProperty(JSContext *cx, JSObject *obj, jsid id, jsval value, + JSPropertyOp getter, JSPropertyOp setter, uintN attrs, + uintN flags, intN shortid, JSProperty **propp); + +/* + * Unlike js_DefineProperty, propp must be non-null. On success, and if id was + * found, return true with *objp non-null and locked, and with a held property + * stored in *propp. If successful but id was not found, return true with both + * *objp and *propp null. Therefore all callers who receive a non-null *propp + * must later call OBJ_DROP_PROPERTY(cx, *objp, *propp). + */ +#if defined JS_THREADSAFE && defined DEBUG +extern JS_FRIEND_API(JSBool) +_js_LookupProperty(JSContext *cx, JSObject *obj, jsid id, JSObject **objp, + JSProperty **propp, const char *file, uintN line); + +#define js_LookupProperty(cx,obj,id,objp,propp) \ + _js_LookupProperty(cx,obj,id,objp,propp,__FILE__,__LINE__) +#else +extern JS_FRIEND_API(JSBool) +js_LookupProperty(JSContext *cx, JSObject *obj, jsid id, JSObject **objp, + JSProperty **propp); +#endif + +extern JS_FRIEND_API(JSBool) +js_FindProperty(JSContext *cx, jsid id, JSObject **objp, JSObject **pobjp, + JSProperty **propp); + +extern JSObject * +js_FindIdentifierBase(JSContext *cx, jsid id); + +extern JSObject * +js_FindVariableScope(JSContext *cx, JSFunction **funp); + +extern JSBool +js_GetProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp); + +extern JSBool +js_SetProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp); + +extern JSBool +js_GetAttributes(JSContext *cx, JSObject *obj, jsid id, JSProperty *prop, + uintN *attrsp); + +extern JSBool +js_SetAttributes(JSContext *cx, JSObject *obj, jsid id, JSProperty *prop, + uintN *attrsp); + +extern JSBool +js_DeleteProperty(JSContext *cx, JSObject *obj, jsid id, jsval *rval); + +extern JSBool +js_DefaultValue(JSContext *cx, JSObject *obj, JSType hint, jsval *vp); + +extern JSIdArray * +js_NewIdArray(JSContext *cx, jsint length); + +extern JSIdArray * +js_GrowIdArray(JSContext *cx, JSIdArray *ida, jsint length); + +extern JSBool +js_Enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op, + jsval *statep, jsid *idp); + +extern JSBool +js_CheckAccess(JSContext *cx, JSObject *obj, jsid id, JSAccessMode mode, + jsval *vp, uintN *attrsp); + +extern JSBool +js_Call(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval); + +extern JSBool +js_Construct(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval); + +extern JSBool +js_HasInstance(JSContext *cx, JSObject *obj, jsval v, JSBool *bp); + +extern JSBool +js_SetProtoOrParent(JSContext *cx, JSObject *obj, uint32 slot, JSObject *pobj); + +extern JSBool +js_IsDelegate(JSContext *cx, JSObject *obj, jsval v, JSBool *bp); + +extern JSBool +js_GetClassPrototype(JSContext *cx, const char *name, JSObject **protop); + +extern JSBool +js_SetClassPrototype(JSContext *cx, JSObject *ctor, JSObject *proto, + uintN attrs); + +extern JSBool +js_ValueToObject(JSContext *cx, jsval v, JSObject **objp); + +extern JSObject * +js_ValueToNonNullObject(JSContext *cx, jsval v); + +extern JSBool +js_TryValueOf(JSContext *cx, JSObject *obj, JSType type, jsval *rval); + +extern JSBool +js_TryMethod(JSContext *cx, JSObject *obj, JSAtom *atom, + uintN argc, jsval *argv, jsval *rval); + +extern JSBool +js_XDRObject(JSXDRState *xdr, JSObject **objp); + +extern uint32 +js_Mark(JSContext *cx, JSObject *obj, void *arg); + +extern void +js_Clear(JSContext *cx, JSObject *obj); + +extern jsval +js_GetRequiredSlot(JSContext *cx, JSObject *obj, uint32 slot); + +extern void +js_SetRequiredSlot(JSContext *cx, JSObject *obj, uint32 slot, jsval v); + +JS_END_EXTERN_C + +#endif /* jsobj_h___ */ diff --git a/src/dom/js/jsopcode.c b/src/dom/js/jsopcode.c new file mode 100644 index 000000000..166f602d5 --- /dev/null +++ b/src/dom/js/jsopcode.c @@ -0,0 +1,2660 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* + * JS bytecode descriptors, disassemblers, and decompilers. + */ +#include "jsstddef.h" +#ifdef HAVE_MEMORY_H +#include +#endif +#include +#include +#include +#include +#include "jstypes.h" +#include "jsarena.h" /* Added by JSIFY */ +#include "jsutil.h" /* Added by JSIFY */ +#include "jsdtoa.h" +#include "jsprf.h" +#include "jsapi.h" +#include "jsarray.h" +#include "jsatom.h" +#include "jscntxt.h" +#include "jsconfig.h" +#include "jsdbgapi.h" +#include "jsemit.h" +#include "jsfun.h" +#include "jslock.h" +#include "jsobj.h" +#include "jsopcode.h" +#include "jsscope.h" +#include "jsscript.h" +#include "jsstr.h" + +const char js_const_str[] = "const"; +const char js_var_str[] = "var"; +const char js_function_str[] = "function"; +const char js_in_str[] = "in"; +const char js_instanceof_str[] = "instanceof"; +const char js_new_str[] = "new"; +const char js_delete_str[] = "delete"; +const char js_typeof_str[] = "typeof"; +const char js_void_str[] = "void"; +const char js_null_str[] = "null"; +const char js_this_str[] = "this"; +const char js_false_str[] = "false"; +const char js_true_str[] = "true"; + +const char *js_incop_str[] = {"++", "--"}; + +/* Pollute the namespace locally for MSVC Win16, but not for WatCom. */ +#ifdef __WINDOWS_386__ + #ifdef FAR + #undef FAR + #endif +#else /* !__WINDOWS_386__ */ +#ifndef FAR +#define FAR +#endif +#endif /* !__WINDOWS_386__ */ + +const JSCodeSpec FAR js_CodeSpec[] = { +#define OPDEF(op,val,name,token,length,nuses,ndefs,prec,format) \ + {name,token,length,nuses,ndefs,prec,format}, +#include "jsopcode.tbl" +#undef OPDEF +}; + +uintN js_NumCodeSpecs = sizeof (js_CodeSpec) / sizeof js_CodeSpec[0]; + +/************************************************************************/ + +static ptrdiff_t +GetJumpOffset(jsbytecode *pc, jsbytecode *pc2) +{ + uint32 type; + + type = (js_CodeSpec[*pc].format & JOF_TYPEMASK); + if (JOF_TYPE_IS_EXTENDED_JUMP(type)) + return GET_JUMPX_OFFSET(pc2); + return GET_JUMP_OFFSET(pc2); +} + +#ifdef DEBUG + +JS_FRIEND_API(void) +js_Disassemble(JSContext *cx, JSScript *script, JSBool lines, FILE *fp) +{ + jsbytecode *pc, *end; + uintN len; + + pc = script->code; + end = pc + script->length; + while (pc < end) { + if (pc == script->main) + fputs("main:\n", fp); + len = js_Disassemble1(cx, script, pc, + PTRDIFF(pc, script->code, jsbytecode), + lines, fp); + if (!len) + return; + pc += len; + } +} + +JS_FRIEND_API(uintN) +js_Disassemble1(JSContext *cx, JSScript *script, jsbytecode *pc, uintN loc, + JSBool lines, FILE *fp) +{ + JSOp op; + const JSCodeSpec *cs; + intN len, off; + JSAtom *atom; + JSString *str; + char *cstr; + + op = (JSOp)*pc; + if (op >= JSOP_LIMIT) { + char numBuf1[12], numBuf2[12]; + JS_snprintf(numBuf1, sizeof numBuf1, "%d", op); + JS_snprintf(numBuf2, sizeof numBuf2, "%d", JSOP_LIMIT); + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, + JSMSG_BYTECODE_TOO_BIG, numBuf1, numBuf2); + return 0; + } + cs = &js_CodeSpec[op]; + len = (intN)cs->length; + fprintf(fp, "%05u:", loc); + if (lines) + fprintf(fp, "%4u", JS_PCToLineNumber(cx, script, pc)); + fprintf(fp, " %s", cs->name); + switch (cs->format & JOF_TYPEMASK) { + case JOF_BYTE: + if (op == JSOP_TRAP) { + op = JS_GetTrapOpcode(cx, script, pc); + if (op == JSOP_LIMIT) + return 0; + len = (intN)js_CodeSpec[op].length; + } + break; + + case JOF_JUMP: + case JOF_JUMPX: + off = GetJumpOffset(pc, pc); + fprintf(fp, " %u (%d)", loc + off, off); + break; + + case JOF_CONST: + atom = GET_ATOM(cx, script, pc); + str = js_ValueToSource(cx, ATOM_KEY(atom)); + if (!str) + return 0; + cstr = js_DeflateString(cx, JSSTRING_CHARS(str), JSSTRING_LENGTH(str)); + if (!cstr) + return 0; + fprintf(fp, " %s", cstr); + JS_free(cx, cstr); + break; + + case JOF_UINT16: + fprintf(fp, " %u", GET_ARGC(pc)); + break; + +#if JS_HAS_SWITCH_STATEMENT + case JOF_TABLESWITCH: + { + jsbytecode *pc2; + jsint i, low, high; + + pc2 = pc; + off = GetJumpOffset(pc, pc2); + pc2 += JUMP_OFFSET_LEN; + low = GetJumpOffset(pc, pc2); + pc2 += JUMP_OFFSET_LEN; + high = GetJumpOffset(pc, pc2); + pc2 += JUMP_OFFSET_LEN; + fprintf(fp, " defaultOffset %d low %d high %d", off, low, high); + for (i = low; i <= high; i++) { + off = GetJumpOffset(pc, pc2); + fprintf(fp, "\n\t%d: %d", i, off); + pc2 += JUMP_OFFSET_LEN; + } + len = 1 + pc2 - pc; + break; + } + + case JOF_LOOKUPSWITCH: + { + jsbytecode *pc2; + jsint npairs; + + pc2 = pc; + off = GetJumpOffset(pc, pc2); + pc2 += JUMP_OFFSET_LEN; + npairs = (jsint) GET_ATOM_INDEX(pc2); + pc2 += ATOM_INDEX_LEN; + fprintf(fp, " offset %d npairs %u", off, (uintN) npairs); + while (npairs) { + atom = GET_ATOM(cx, script, pc2); + pc2 += ATOM_INDEX_LEN; + off = GetJumpOffset(pc, pc2); + pc2 += JUMP_OFFSET_LEN; + + str = js_ValueToSource(cx, ATOM_KEY(atom)); + if (!str) + return 0; + cstr = js_DeflateString(cx, JSSTRING_CHARS(str), + JSSTRING_LENGTH(str)); + if (!cstr) + return 0; + fprintf(fp, "\n\t%s: %d", cstr, off); + JS_free(cx, cstr); + npairs--; + } + len = 1 + pc2 - pc; + break; + } +#endif /* JS_HAS_SWITCH_STATEMENT */ + + case JOF_QARG: + fprintf(fp, " %u", GET_ARGNO(pc)); + break; + + case JOF_QVAR: + fprintf(fp, " %u", GET_VARNO(pc)); + break; + +#if JS_HAS_LEXICAL_CLOSURE + case JOF_DEFLOCALVAR: + fprintf(fp, " %u", GET_VARNO(pc)); + pc += VARNO_LEN; + atom = GET_ATOM(cx, script, pc); + str = js_ValueToSource(cx, ATOM_KEY(atom)); + if (!str) + return 0; + cstr = js_DeflateString(cx, JSSTRING_CHARS(str), JSSTRING_LENGTH(str)); + if (!cstr) + return 0; + fprintf(fp, " %s", cstr); + JS_free(cx, cstr); + break; +#endif + + default: { + char numBuf[12]; + JS_snprintf(numBuf, sizeof numBuf, "%lx", (unsigned long) cs->format); + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, + JSMSG_UNKNOWN_FORMAT, numBuf); + return 0; + } + } + fputs("\n", fp); + return len; +} + +#endif /* DEBUG */ + +/************************************************************************/ + +/* + * Sprintf, but with unlimited and automatically allocated buffering. + */ +typedef struct Sprinter { + JSContext *context; /* context executing the decompiler */ + JSArenaPool *pool; /* string allocation pool */ + char *base; /* base address of buffer in pool */ + size_t size; /* size of buffer allocated at base */ + ptrdiff_t offset; /* offset of next free char in buffer */ +} Sprinter; + +#define INIT_SPRINTER(cx, sp, ap, off) \ + ((sp)->context = cx, (sp)->pool = ap, (sp)->base = NULL, (sp)->size = 0, \ + (sp)->offset = off) + +#define OFF2STR(sp,off) ((sp)->base + (off)) +#define STR2OFF(sp,str) ((str) - (sp)->base) +#define RETRACT(sp,str) ((sp)->offset = STR2OFF(sp, str)) + +static JSBool +SprintAlloc(Sprinter *sp, size_t nb) +{ + if (!sp->base) { + JS_ARENA_ALLOCATE_CAST(sp->base, char *, sp->pool, nb); + } else { + JS_ARENA_GROW_CAST(sp->base, char *, sp->pool, sp->size, nb); + } + if (!sp->base) { + JS_ReportOutOfMemory(sp->context); + return JS_FALSE; + } + sp->size += nb; + return JS_TRUE; +} + +static ptrdiff_t +SprintPut(Sprinter *sp, const char *s, size_t len) +{ + ptrdiff_t nb, offset; + char *bp; + + /* Allocate space for s, including the '\0' at the end. */ + nb = (sp->offset + len + 1) - sp->size; + if (nb > 0 && !SprintAlloc(sp, nb)) + return -1; + + /* Advance offset and copy s into sp's buffer. */ + offset = sp->offset; + sp->offset += len; + bp = sp->base + offset; + memmove(bp, s, len); + bp[len] = 0; + return offset; +} + +static ptrdiff_t +Sprint(Sprinter *sp, const char *format, ...) +{ + va_list ap; + char *bp; + ptrdiff_t offset; + + va_start(ap, format); + bp = JS_vsmprintf(format, ap); /* XXX vsaprintf */ + va_end(ap); + if (!bp) { + JS_ReportOutOfMemory(sp->context); + return -1; + } + offset = SprintPut(sp, bp, strlen(bp)); + free(bp); + return offset; +} + +const jschar js_EscapeMap[] = { + '\b', 'b', + '\f', 'f', + '\n', 'n', + '\r', 'r', + '\t', 't', + '\v', 'v', + '"', '"', + '\'', '\'', + '\\', '\\', + 0 +}; + +static char * +QuoteString(Sprinter *sp, JSString *str, jschar quote) +{ + ptrdiff_t off, len, nb; + const jschar *s, *t, *u, *z; + char *bp; + jschar c; + JSBool ok; + + /* Sample off first for later return value pointer computation. */ + off = sp->offset; + if (quote && Sprint(sp, "%c", (char)quote) < 0) + return NULL; + + /* Loop control variables: z points at end of string sentinel. */ + s = JSSTRING_CHARS(str); + z = s + JSSTRING_LENGTH(str); + for (t = s; t < z; s = ++t) { + /* Move t forward from s past un-quote-worthy characters. */ + c = *t; + while (JS_ISPRINT(c) && c != quote && c != '\\' && !(c >> 8)) { + c = *++t; + if (t == z) + break; + } + len = PTRDIFF(t, s, jschar); + + /* Allocate space for s, including the '\0' at the end. */ + nb = (sp->offset + len + 1) - sp->size; + if (nb > 0 && !SprintAlloc(sp, nb)) + return NULL; + + /* Advance sp->offset and copy s into sp's buffer. */ + bp = sp->base + sp->offset; + sp->offset += len; + while (--len >= 0) + *bp++ = (char) *s++; + *bp = '\0'; + + if (t == z) + break; + + /* Use js_EscapeMap, \u, or \x only if necessary. */ + if ((u = js_strchr(js_EscapeMap, c)) != NULL) + ok = Sprint(sp, "\\%c", (char)u[1]) >= 0; + else + ok = Sprint(sp, (c >> 8) ? "\\u%04X" : "\\x%02X", c) >= 0; + if (!ok) + return NULL; + } + + /* Sprint the closing quote and return the quoted string. */ + if (quote && Sprint(sp, "%c", (char)quote) < 0) + return NULL; + return OFF2STR(sp, off); +} + +JSString * +js_QuoteString(JSContext *cx, JSString *str, jschar quote) +{ + void *mark; + Sprinter sprinter; + char *bytes; + JSString *escstr; + + mark = JS_ARENA_MARK(&cx->tempPool); + INIT_SPRINTER(cx, &sprinter, &cx->tempPool, 0); + bytes = QuoteString(&sprinter, str, quote); + escstr = bytes ? JS_NewStringCopyZ(cx, bytes) : NULL; + JS_ARENA_RELEASE(&cx->tempPool, mark); + return escstr; +} + +/************************************************************************/ + +struct JSPrinter { + Sprinter sprinter; /* base class state */ + JSArenaPool pool; /* string allocation pool */ + uintN indent; /* indentation in spaces */ + JSBool pretty; /* pretty-print: indent, use newlines */ + JSScript *script; /* script being printed */ + JSScope *scope; /* script function scope */ +}; + +JSPrinter * +js_NewPrinter(JSContext *cx, const char *name, uintN indent, JSBool pretty) +{ + JSPrinter *jp; + JSStackFrame *fp; + JSObjectMap *map; + + jp = (JSPrinter *) JS_malloc(cx, sizeof(JSPrinter)); + if (!jp) + return NULL; + INIT_SPRINTER(cx, &jp->sprinter, &jp->pool, 0); + JS_InitArenaPool(&jp->pool, name, 256, 1); + jp->indent = indent; + jp->pretty = pretty; + jp->script = NULL; + jp->scope = NULL; + fp = cx->fp; + if (fp && fp->fun && fp->fun->object) { + map = fp->fun->object->map; + if (MAP_IS_NATIVE(map)) + jp->scope = (JSScope *)map; + } + return jp; +} + +void +js_DestroyPrinter(JSPrinter *jp) +{ + JS_FinishArenaPool(&jp->pool); + JS_free(jp->sprinter.context, jp); +} + +JSString * +js_GetPrinterOutput(JSPrinter *jp) +{ + JSContext *cx; + JSString *str; + + cx = jp->sprinter.context; + if (!jp->sprinter.base) + return cx->runtime->emptyString; + str = JS_NewStringCopyZ(cx, jp->sprinter.base); + if (!str) + return NULL; + JS_FreeArenaPool(&jp->pool); + INIT_SPRINTER(cx, &jp->sprinter, &jp->pool, 0); + return str; +} + +int +js_printf(JSPrinter *jp, const char *format, ...) +{ + va_list ap; + char *bp, *fp; + int cc; + + if (*format == '\0') + return 0; + + va_start(ap, format); + + /* If pretty-printing, expand magic tab into a run of jp->indent spaces. */ + if (*format == '\t') { + if (jp->pretty && Sprint(&jp->sprinter, "%*s", jp->indent, "") < 0) + return -1; + format++; + } + + /* Suppress newlines (must be once per format, at the end) if not pretty. */ + fp = NULL; + if (!jp->pretty && format[cc = strlen(format)-1] == '\n') { + fp = JS_strdup(jp->sprinter.context, format); + if (!fp) + return -1; + fp[cc] = '\0'; + format = fp; + } + + /* Allocate temp space, convert format, and put. */ + bp = JS_vsmprintf(format, ap); /* XXX vsaprintf */ + if (fp) { + JS_free(jp->sprinter.context, fp); + format = NULL; + } + if (!bp) { + JS_ReportOutOfMemory(jp->sprinter.context); + return -1; + } + + cc = strlen(bp); + if (SprintPut(&jp->sprinter, bp, (size_t)cc) < 0) + cc = -1; + free(bp); + + va_end(ap); + return cc; +} + +JSBool +js_puts(JSPrinter *jp, const char *s) +{ + return SprintPut(&jp->sprinter, s, strlen(s)) >= 0; +} + +/************************************************************************/ + +typedef struct SprintStack { + Sprinter sprinter; /* sprinter for postfix to infix buffering */ + ptrdiff_t *offsets; /* stack of postfix string offsets */ + jsbytecode *opcodes; /* parallel stack of JS opcodes */ + uintN top; /* top of stack index */ + JSPrinter *printer; /* permanent output goes here */ +} SprintStack; + +/* Gap between stacked strings to allow for insertion of parens and commas. */ +#define PAREN_SLOP (2 + 1) + +/* + * These pseudo-ops help js_DecompileValueGenerator decompile JSOP_SETNAME, + * JSOP_SETPROP, and JSOP_SETELEM, respectively. See the first assertion in + * PushOff. + */ +#define JSOP_GETPROP2 254 +#define JSOP_GETELEM2 255 + +static JSBool +PushOff(SprintStack *ss, ptrdiff_t off, JSOp op) +{ + uintN top; + +#if JSOP_LIMIT > JSOP_GETPROP2 +#error JSOP_LIMIT must be <= JSOP_GETPROP2 +#endif + if (!SprintAlloc(&ss->sprinter, PAREN_SLOP)) + return JS_FALSE; + + /* ss->top points to the next free slot; be paranoid about overflow. */ + top = ss->top; + JS_ASSERT(top < ss->printer->script->depth); + if (top >= ss->printer->script->depth) { + JS_ReportOutOfMemory(ss->sprinter.context); + return JS_FALSE; + } + + /* The opcodes stack must contain real bytecodes that index js_CodeSpec. */ + ss->offsets[top] = off; + ss->opcodes[top] = (op == JSOP_GETPROP2) ? JSOP_GETPROP + : (op == JSOP_GETELEM2) ? JSOP_GETELEM + : (jsbytecode) op; + ss->top = ++top; + ss->sprinter.offset += PAREN_SLOP; + return JS_TRUE; +} + +static ptrdiff_t +PopOff(SprintStack *ss, JSOp op) +{ + uintN top; + const JSCodeSpec *cs, *topcs; + ptrdiff_t off; + + /* ss->top points to the next free slot; be paranoid about underflow. */ + top = ss->top; + JS_ASSERT(top != 0); + if (top == 0) + return 0; + + ss->top = --top; + topcs = &js_CodeSpec[ss->opcodes[top]]; + cs = &js_CodeSpec[op]; + if (topcs->prec != 0 && topcs->prec < cs->prec) { + ss->offsets[top] -= 2; + ss->sprinter.offset = ss->offsets[top]; + off = Sprint(&ss->sprinter, "(%s)", + OFF2STR(&ss->sprinter, ss->sprinter.offset + 2)); + } else { + off = ss->sprinter.offset = ss->offsets[top]; + } + return off; +} + +#if JS_HAS_SWITCH_STATEMENT +typedef struct TableEntry { + jsval key; + ptrdiff_t offset; +} TableEntry; + +static int +CompareOffsets(const void *v1, const void *v2, void *arg) +{ + const TableEntry *te1 = (const TableEntry *) v1, + *te2 = (const TableEntry *) v2; + + return te1->offset - te2->offset; +} + +static JSBool +Decompile(SprintStack *ss, jsbytecode *pc, intN nb); + +static JSBool +DecompileSwitch(SprintStack *ss, TableEntry *table, uintN tableLength, + jsbytecode *pc, ptrdiff_t switchLength, + ptrdiff_t defaultOffset, JSBool isCondSwitch) +{ + JSContext *cx; + JSPrinter *jp; + char *lval, *rval; + uintN i; + ptrdiff_t diff, off, off2, caseExprOff; + jsval key; + JSString *str; + + cx = ss->sprinter.context; + jp = ss->printer; + + lval = OFF2STR(&ss->sprinter, PopOff(ss, JSOP_NOP)); + js_printf(jp, "\tswitch (%s) {\n", lval); + + if (tableLength) { + diff = table[0].offset - defaultOffset; + if (diff > 0) { + jp->indent += 2; + js_printf(jp, "\tdefault:\n"); + jp->indent += 2; + if (!Decompile(ss, pc + defaultOffset, diff)) + return JS_FALSE; + jp->indent -= 4; + } + + caseExprOff = isCondSwitch + ? (ptrdiff_t) js_CodeSpec[JSOP_CONDSWITCH].length + : 0; + + for (i = 0; i < tableLength; i++) { + off = table[i].offset; + if (i + 1 < tableLength) + off2 = table[i + 1].offset; + else + off2 = switchLength; + + key = table[i].key; + if (isCondSwitch) { + ptrdiff_t nextCaseExprOff; + + /* + * key encodes the JSOP_CASE bytecode's offset from switchtop. + * The next case expression follows immediately, unless we are + * at the last case. + */ + nextCaseExprOff = (ptrdiff_t)JSVAL_TO_INT(key); + nextCaseExprOff += js_CodeSpec[pc[nextCaseExprOff]].length; + jp->indent += 2; + if (!Decompile(ss, pc + caseExprOff, + nextCaseExprOff - caseExprOff)) { + return JS_FALSE; + } + caseExprOff = nextCaseExprOff; + } else { + /* + * key comes from an atom, not the decompiler, so we need to + * quote it if it's a string literal. + */ + str = js_ValueToString(cx, key); + if (!str) + return JS_FALSE; + jp->indent += 2; + if (JSVAL_IS_STRING(key)) { + rval = QuoteString(&ss->sprinter, str, (jschar)'"'); + if (!rval) + return JS_FALSE; + RETRACT(&ss->sprinter, rval); + } else { + rval = JS_GetStringBytes(str); + } + js_printf(jp, "\tcase %s:\n", rval); + } + + jp->indent += 2; + if (off <= defaultOffset && defaultOffset < off2) { + diff = defaultOffset - off; + if (diff != 0) { + if (!Decompile(ss, pc + off, diff)) + return JS_FALSE; + off = defaultOffset; + } + jp->indent -= 2; + js_printf(jp, "\tdefault:\n"); + jp->indent += 2; + } + if (!Decompile(ss, pc + off, off2 - off)) + return JS_FALSE; + jp->indent -= 4; + } + } + + if (defaultOffset == switchLength) { + jp->indent += 2; + js_printf(jp, "\tdefault:\n"); + jp->indent -= 2; + } + js_printf(jp, "\t}\n"); + return JS_TRUE; +} +#endif + +static JSAtom * +GetSlotAtom(JSPrinter *jp, JSPropertyOp getter, uintN slot) +{ + JSScope *scope; + JSScopeProperty *sprop; + JSObject *obj, *proto; + + scope = jp->scope; + while (scope) { + for (sprop = SCOPE_LAST_PROP(scope); sprop; sprop = sprop->parent) { + if (sprop->getter != getter) + continue; + JS_ASSERT(sprop->flags & SPROP_HAS_SHORTID); + JS_ASSERT(!JSVAL_IS_INT(sprop->id)); + if ((uintN) sprop->shortid == slot) + return (JSAtom *) sprop->id; + } + obj = scope->object; + if (!obj) + break; + proto = OBJ_GET_PROTO(jp->sprinter.context, obj); + if (!proto) + break; + scope = OBJ_SCOPE(proto); + } + return NULL; +} + +static const char * +VarPrefix(jssrcnote *sn) +{ + const char *kw; + static char buf[8]; + + kw = NULL; + if (sn) { + if (SN_TYPE(sn) == SRC_VAR) + kw = js_var_str; + else if (SN_TYPE(sn) == SRC_CONST) + kw = js_const_str; + } + if (!kw) + return ""; + JS_snprintf(buf, sizeof buf, "%s ", kw); + return buf; +} + +static JSBool +Decompile(SprintStack *ss, jsbytecode *pc, intN nb) +{ + JSContext *cx; + JSPrinter *jp, *jp2; + jsbytecode *endpc, *done, *forelem_tail, *forelem_done; + ptrdiff_t len, todo, oplen, cond, next, tail; + JSOp op, lastop, saveop; + const JSCodeSpec *cs, *topcs; + jssrcnote *sn, *sn2; + const char *lval, *rval, *xval, *fmt; + jsint i, argc; + char **argv; + JSAtom *atom; + JSObject *obj; + JSFunction *fun; + JSString *str; + JSBool ok; + jsval val; + +/* + * Local macros + */ +#define DECOMPILE_CODE(pc,nb) if (!Decompile(ss, pc, nb)) return JS_FALSE +#define POP_STR() OFF2STR(&ss->sprinter, PopOff(ss, op)) +#define LOCAL_ASSERT(expr) JS_ASSERT(expr); if (!(expr)) return JS_FALSE + +/* + * Get atom from script's atom map, quote/escape its string appropriately into + * rval, and select fmt from the quoted and unquoted alternatives. + */ +#define GET_ATOM_QUOTE_AND_FMT(qfmt, ufmt, rval) \ + JS_BEGIN_MACRO \ + jschar quote_; \ + atom = GET_ATOM(cx, jp->script, pc); \ + if (ATOM_KEYWORD(atom)) { \ + quote_ = '\''; \ + fmt = qfmt; \ + } else { \ + quote_ = 0; \ + fmt = ufmt; \ + } \ + rval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), quote_); \ + if (!rval) \ + return JS_FALSE; \ + JS_END_MACRO + + cx = ss->sprinter.context; + jp = ss->printer; + endpc = pc + nb; + forelem_tail = forelem_done = NULL; + todo = -2; /* NB: different from Sprint() error return. */ + tail = -1; + op = JSOP_NOP; + sn = NULL; + rval = NULL; + + while (pc < endpc) { + lastop = op; + op = saveop = (JSOp) *pc; + if (op >= JSOP_LIMIT) { + switch (op) { + case JSOP_GETPROP2: + saveop = JSOP_GETPROP; + break; + case JSOP_GETELEM2: + saveop = JSOP_GETELEM; + break; + default:; + } + } + cs = &js_CodeSpec[saveop]; + len = oplen = cs->length; + + if (cs->token) { + switch (cs->nuses) { + case 2: + rval = POP_STR(); + lval = POP_STR(); + sn = js_GetSrcNote(jp->script, pc); + if (sn && SN_TYPE(sn) == SRC_ASSIGNOP) { + /* Print only the right operand of the assignment-op. */ + todo = SprintPut(&ss->sprinter, rval, strlen(rval)); + } else { + todo = Sprint(&ss->sprinter, "%s %s %s", + lval, cs->token, rval); + } + break; + + case 1: + rval = POP_STR(); + todo = Sprint(&ss->sprinter, "%s%s", cs->token, rval); + break; + + case 0: +#if JS_HAS_GETTER_SETTER + if (op == JSOP_GETTER || op == JSOP_SETTER) { + todo = -2; + break; + } +#endif + todo = SprintPut(&ss->sprinter, cs->token, strlen(cs->token)); + break; + + default: + todo = -2; + break; + } + } else { + switch (op) { + case JSOP_NOP: + /* + * Check for a do-while loop, a for-loop with an empty + * initializer part, a labeled statement, a function + * definition, or try/finally. + */ + sn = js_GetSrcNote(jp->script, pc); + todo = -2; + switch (sn ? SN_TYPE(sn) : SRC_NULL) { +#if JS_HAS_DO_WHILE_LOOP + case SRC_WHILE: + js_printf(jp, "\tdo {\n"); + jp->indent += 4; + break; +#endif /* JS_HAS_DO_WHILE_LOOP */ + + case SRC_FOR: + rval = ""; + + do_forloop: + /* Skip the JSOP_NOP or JSOP_POP bytecode. */ + pc++; + + /* Get the cond, next, and loop-closing tail offsets. */ + cond = js_GetSrcNoteOffset(sn, 0); + next = js_GetSrcNoteOffset(sn, 1); + tail = js_GetSrcNoteOffset(sn, 2); + LOCAL_ASSERT(tail + GetJumpOffset(pc+tail, pc+tail) == 0); + + /* Print the keyword and the possibly empty init-part. */ + js_printf(jp, "\tfor (%s;", rval); + + if (pc[cond] == JSOP_IFEQ || pc[cond] == JSOP_IFEQX) { + /* Decompile the loop condition. */ + DECOMPILE_CODE(pc, cond); + js_printf(jp, " %s", POP_STR()); + } + + /* Need a semicolon whether or not there was a cond. */ + js_puts(jp, ";"); + + if (pc[next] != JSOP_GOTO && pc[next] != JSOP_GOTOX) { + /* Decompile the loop updater. */ + DECOMPILE_CODE(pc + next, tail - next - 1); + js_printf(jp, " %s", POP_STR()); + } + + /* Do the loop body. */ + js_puts(jp, ") {\n"); + jp->indent += 4; + oplen = (cond) ? js_CodeSpec[pc[cond]].length : 0; + DECOMPILE_CODE(pc + cond + oplen, next - cond - oplen); + jp->indent -= 4; + js_printf(jp, "\t}\n"); + + /* Set len so pc skips over the entire loop. */ + len = tail + js_CodeSpec[pc[tail]].length; + break; + + case SRC_LABEL: + atom = js_GetAtom(cx, &jp->script->atomMap, + (jsatomid) js_GetSrcNoteOffset(sn, 0)); + jp->indent -= 4; + rval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0); + if (!rval) + return JS_FALSE; + RETRACT(&ss->sprinter, rval); + js_printf(jp, "\t%s:\n", rval); + jp->indent += 4; + break; + + case SRC_LABELBRACE: + atom = js_GetAtom(cx, &jp->script->atomMap, + (jsatomid) js_GetSrcNoteOffset(sn, 0)); + rval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0); + if (!rval) + return JS_FALSE; + RETRACT(&ss->sprinter, rval); + js_printf(jp, "\t%s: {\n", rval); + jp->indent += 4; + break; + + case SRC_ENDBRACE: + jp->indent -= 4; + js_printf(jp, "\t}\n"); + break; + + case SRC_CATCH: + jp->indent -= 4; + sn = js_GetSrcNote(jp->script, pc); + pc += oplen; + js_printf(jp, "\t} catch ("); + + LOCAL_ASSERT(*pc == JSOP_NAME); + pc += js_CodeSpec[JSOP_NAME].length; + LOCAL_ASSERT(*pc == JSOP_PUSHOBJ); + pc += js_CodeSpec[JSOP_PUSHOBJ].length; + LOCAL_ASSERT(*pc == JSOP_NEWINIT); + pc += js_CodeSpec[JSOP_NEWINIT].length; + LOCAL_ASSERT(*pc == JSOP_EXCEPTION); + pc += js_CodeSpec[JSOP_EXCEPTION].length; + LOCAL_ASSERT(*pc == JSOP_INITCATCHVAR); + atom = GET_ATOM(cx, jp->script, pc); + rval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0); + if (!rval) + return JS_FALSE; + RETRACT(&ss->sprinter, rval); + js_printf(jp, "%s", rval); + pc += js_CodeSpec[JSOP_INITCATCHVAR].length; + LOCAL_ASSERT(*pc == JSOP_ENTERWITH); + pc += js_CodeSpec[JSOP_ENTERWITH].length; + + len = js_GetSrcNoteOffset(sn, 0); + if (len) { + js_printf(jp, " if "); + DECOMPILE_CODE(pc, len); + js_printf(jp, "%s", POP_STR()); + pc += len; + LOCAL_ASSERT(*pc == JSOP_IFEQ || *pc == JSOP_IFEQX); + pc += js_CodeSpec[*pc].length; + } + + js_printf(jp, ") {\n"); + jp->indent += 4; + len = 0; + break; + + case SRC_FUNCDEF: + atom = js_GetAtom(cx, &jp->script->atomMap, + (jsatomid) js_GetSrcNoteOffset(sn, 0)); + JS_ASSERT(ATOM_IS_OBJECT(atom)); + do_function: + obj = ATOM_TO_OBJECT(atom); + fun = (JSFunction *) JS_GetPrivate(cx, obj); + jp2 = js_NewPrinter(cx, JS_GetFunctionName(fun), + jp->indent, jp->pretty); + if (!jp2) + return JS_FALSE; + jp2->scope = jp->scope; + if (js_DecompileFunction(jp2, fun)) { + str = js_GetPrinterOutput(jp2); + if (str) + js_printf(jp, "%s\n", JS_GetStringBytes(str)); + } + js_DestroyPrinter(jp2); + break; + + default:; + } + case JSOP_RETRVAL: + break; + + case JSOP_GROUP: + /* Use last real op so PopOff adds parens if needed. */ + todo = PopOff(ss, lastop); + + /* Now add user-supplied parens only if PopOff did not. */ + cs = &js_CodeSpec[lastop]; + topcs = &js_CodeSpec[ss->opcodes[ss->top]]; + if (topcs->prec >= cs->prec) { + todo = Sprint(&ss->sprinter, "(%s)", + OFF2STR(&ss->sprinter, todo)); + } + break; + + case JSOP_PUSH: + case JSOP_PUSHOBJ: + case JSOP_BINDNAME: + todo = Sprint(&ss->sprinter, ""); + break; + +#if JS_HAS_EXCEPTIONS + case JSOP_TRY: + js_printf(jp, "\ttry {\n"); + jp->indent += 4; + todo = -2; + break; + + { + static const char finally_cookie[] = "finally-cookie"; + + case JSOP_FINALLY: + jp->indent -= 4; + js_printf(jp, "\t} finally {\n"); + jp->indent += 4; + + /* + * We must push an empty string placeholder for gosub's return + * address, popped by JSOP_RETSUB and counted by script->depth + * but not by ss->top (see JSOP_SETSP, below). + */ + todo = Sprint(&ss->sprinter, finally_cookie); + break; + + case JSOP_RETSUB: + rval = POP_STR(); + LOCAL_ASSERT(strcmp(rval, finally_cookie) == 0); + todo = -2; + break; + } + + case JSOP_SWAP: + /* + * We don't generate this opcode currently, and previously we + * did not need to decompile it. If old, serialized bytecode + * uses it still, we should fall through and set todo = -2. + */ + /* FALL THROUGH */ + + case JSOP_GOSUB: + case JSOP_GOSUBX: + /* + * JSOP_GOSUB and GOSUBX have no effect on the decompiler's + * string stack because the next op in bytecode order finds + * the stack balanced by a JSOP_RETSUB executed elsewhere. + */ + todo = -2; + break; + + case JSOP_SETSP: + /* + * The compiler models operand stack depth and fixes the stack + * pointer on entry to a catch clause based on its depth model. + * The decompiler must match the code generator's model, which + * is why JSOP_FINALLY pushes a cookie that JSOP_RETSUB pops. + */ + ss->top = (uintN) GET_ATOM_INDEX(pc); + break; + + case JSOP_EXCEPTION: + /* + * The only other JSOP_EXCEPTION case occurs as part of a code + * sequence that follows a SRC_CATCH-annotated JSOP_NOP. + */ + sn = js_GetSrcNote(jp->script, pc); + LOCAL_ASSERT(sn && SN_TYPE(sn) == SRC_HIDDEN); + todo = -2; + break; +#endif /* JS_HAS_EXCEPTIONS */ + + case JSOP_POP: + case JSOP_POPV: + sn = js_GetSrcNote(jp->script, pc); + switch (sn ? SN_TYPE(sn) : SRC_NULL) { + case SRC_FOR: + rval = POP_STR(); + todo = -2; + goto do_forloop; + + case SRC_PCDELTA: + /* Pop and save to avoid blowing stack depth budget. */ + lval = JS_strdup(cx, POP_STR()); + if (!lval) + return JS_FALSE; + + /* + * The offset tells distance to the end of the right-hand + * operand of the comma operator. + */ + done = pc + len; + pc += js_GetSrcNoteOffset(sn, 0); + len = 0; + + if (!Decompile(ss, done, pc - done)) { + JS_free(cx, (char *)lval); + return JS_FALSE; + } + + /* Pop Decompile result and print comma expression. */ + rval = POP_STR(); + todo = Sprint(&ss->sprinter, "%s, %s", lval, rval); + JS_free(cx, (char *)lval); + break; + + case SRC_HIDDEN: + /* Hide this pop, it's from a goto in a with or for/in. */ + todo = -2; + break; + + default: + rval = POP_STR(); + if (*rval != '\0') + js_printf(jp, "\t%s;\n", rval); + todo = -2; + break; + } + break; + + case JSOP_POP2: + (void) PopOff(ss, op); + (void) PopOff(ss, op); + todo = -2; + break; + + { + static const char with_cookie[] = "with-cookie"; + + case JSOP_ENTERWITH: + sn = js_GetSrcNote(jp->script, pc); + if (sn && SN_TYPE(sn) == SRC_HIDDEN) { + todo = -2; + break; + } + rval = POP_STR(); + js_printf(jp, "\twith (%s) {\n", rval); + jp->indent += 4; + todo = Sprint(&ss->sprinter, with_cookie); + break; + + case JSOP_LEAVEWITH: + sn = js_GetSrcNote(jp->script, pc); + todo = -2; + if (sn && SN_TYPE(sn) == SRC_HIDDEN) + break; + rval = POP_STR(); + LOCAL_ASSERT(strcmp(rval, with_cookie) == 0); + jp->indent -= 4; + js_printf(jp, "\t}\n"); + break; + } + + case JSOP_SETRVAL: + case JSOP_RETURN: + rval = POP_STR(); + if (*rval != '\0') + js_printf(jp, "\t%s %s;\n", cs->name, rval); + else + js_printf(jp, "\t%s;\n", cs->name); + todo = -2; + break; + +#if JS_HAS_EXCEPTIONS + case JSOP_THROW: + sn = js_GetSrcNote(jp->script, pc); + todo = -2; + if (sn && SN_TYPE(sn) == SRC_HIDDEN) + break; + rval = POP_STR(); + js_printf(jp, "\t%s %s;\n", cs->name, rval); + break; +#endif /* JS_HAS_EXCEPTIONS */ + + case JSOP_GOTO: + case JSOP_GOTOX: + sn = js_GetSrcNote(jp->script, pc); + switch (sn ? SN_TYPE(sn) : SRC_NULL) { + case SRC_CONT2LABEL: + atom = js_GetAtom(cx, &jp->script->atomMap, + (jsatomid) js_GetSrcNoteOffset(sn, 0)); + rval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0); + if (!rval) + return JS_FALSE; + RETRACT(&ss->sprinter, rval); + js_printf(jp, "\tcontinue %s;\n", rval); + break; + case SRC_CONTINUE: + js_printf(jp, "\tcontinue;\n"); + break; + case SRC_BREAK2LABEL: + atom = js_GetAtom(cx, &jp->script->atomMap, + (jsatomid) js_GetSrcNoteOffset(sn, 0)); + rval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0); + if (!rval) + return JS_FALSE; + RETRACT(&ss->sprinter, rval); + js_printf(jp, "\tbreak %s;\n", rval); + break; + case SRC_HIDDEN: + break; + default: + js_printf(jp, "\tbreak;\n"); + break; + } + todo = -2; + break; + + case JSOP_IFEQ: + case JSOP_IFEQX: + len = GetJumpOffset(pc, pc); + sn = js_GetSrcNote(jp->script, pc); + + switch (sn ? SN_TYPE(sn) : SRC_NULL) { + case SRC_IF: + case SRC_IF_ELSE: + rval = POP_STR(); + js_printf(jp, "\tif (%s) {\n", rval); + jp->indent += 4; + if (SN_TYPE(sn) == SRC_IF) { + DECOMPILE_CODE(pc + oplen, len - oplen); + } else { + len = js_GetSrcNoteOffset(sn, 0); + DECOMPILE_CODE(pc + oplen, len - oplen); + jp->indent -= 4; + pc += len; + LOCAL_ASSERT(*pc == JSOP_GOTO || *pc == JSOP_GOTOX); + oplen = js_CodeSpec[*pc].length; + len = GetJumpOffset(pc, pc); + js_printf(jp, "\t} else {\n"); + jp->indent += 4; + DECOMPILE_CODE(pc + oplen, len - oplen); + } + jp->indent -= 4; + js_printf(jp, "\t}\n"); + todo = -2; + break; + + case SRC_WHILE: + rval = POP_STR(); + js_printf(jp, "\twhile (%s) {\n", rval); + jp->indent += 4; + tail = js_GetSrcNoteOffset(sn, 0); + DECOMPILE_CODE(pc + oplen, tail - oplen); + jp->indent -= 4; + js_printf(jp, "\t}\n"); + todo = -2; + break; + + case SRC_COND: + xval = JS_strdup(cx, POP_STR()); + if (!xval) + return JS_FALSE; + len = js_GetSrcNoteOffset(sn, 0); + DECOMPILE_CODE(pc + oplen, len - oplen); + lval = JS_strdup(cx, POP_STR()); + if (!lval) { + JS_free(cx, (void *)xval); + return JS_FALSE; + } + pc += len; + LOCAL_ASSERT(*pc == JSOP_GOTO || *pc == JSOP_GOTOX); + oplen = js_CodeSpec[*pc].length; + len = GetJumpOffset(pc, pc); + DECOMPILE_CODE(pc + oplen, len - oplen); + rval = POP_STR(); + todo = Sprint(&ss->sprinter, "%s ? %s : %s", + xval, lval, rval); + JS_free(cx, (void *)xval); + JS_free(cx, (void *)lval); + break; + + default: + break; + } + break; + + case JSOP_IFNE: + case JSOP_IFNEX: +#if JS_HAS_DO_WHILE_LOOP + /* Currently, this must be a do-while loop's upward branch. */ + jp->indent -= 4; + js_printf(jp, "\t} while (%s);\n", POP_STR()); + todo = -2; +#else + JS_ASSERT(0); +#endif /* JS_HAS_DO_WHILE_LOOP */ + break; + + case JSOP_OR: + case JSOP_ORX: + xval = "||"; + + do_logical_connective: + /* Top of stack is the first clause in a disjunction (||). */ + lval = JS_strdup(cx, POP_STR()); + if (!lval) + return JS_FALSE; + done = pc + GetJumpOffset(pc, pc); + pc += len; + len = PTRDIFF(done, pc, jsbytecode); + DECOMPILE_CODE(pc, len); + rval = POP_STR(); + if (jp->pretty && + jp->indent + 4 + strlen(lval) + 4 + strlen(rval) > 75) { + rval = JS_strdup(cx, rval); + if (!rval) { + tail = -1; + } else { + todo = Sprint(&ss->sprinter, "%s %s\n", lval, xval); + tail = Sprint(&ss->sprinter, "%*s%s", + jp->indent + 4, "", rval); + JS_free(cx, (char *)rval); + } + if (tail < 0) + todo = -1; + } else { + todo = Sprint(&ss->sprinter, "%s %s %s", lval, xval, rval); + } + JS_free(cx, (char *)lval); + break; + + case JSOP_AND: + case JSOP_ANDX: + xval = "&&"; + goto do_logical_connective; + + case JSOP_FORARG: + atom = GetSlotAtom(jp, js_GetArgument, GET_ARGNO(pc)); + LOCAL_ASSERT(atom); + goto do_fornameinloop; + + case JSOP_FORVAR: + atom = GetSlotAtom(jp, js_GetLocalVariable, GET_VARNO(pc)); + LOCAL_ASSERT(atom); + goto do_fornameinloop; + + case JSOP_FORNAME: + atom = GET_ATOM(cx, jp->script, pc); + + do_fornameinloop: + sn = js_GetSrcNote(jp->script, pc); + xval = NULL; + lval = ""; + goto do_forinloop; + + case JSOP_FORPROP: + xval = NULL; + atom = GET_ATOM(cx, jp->script, pc); + if (ATOM_KEYWORD(atom)) { + xval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), + (jschar)'\''); + if (!xval) + return JS_FALSE; + atom = NULL; + } + lval = POP_STR(); + sn = NULL; + + do_forinloop: + pc += oplen; + LOCAL_ASSERT(*pc == JSOP_IFEQ || *pc == JSOP_IFEQX); + oplen = js_CodeSpec[*pc].length; + len = GetJumpOffset(pc, pc); + sn2 = js_GetSrcNote(jp->script, pc); + tail = js_GetSrcNoteOffset(sn2, 0); + + do_forinbody: + js_printf(jp, "\tfor (%s%s", VarPrefix(sn), lval); + if (atom) { + xval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0); + if (!xval) + return JS_FALSE; + RETRACT(&ss->sprinter, xval); + js_printf(jp, *lval ? ".%s" : "%s", xval); + } else if (xval) { + js_printf(jp, "[%s]", xval); + } + rval = OFF2STR(&ss->sprinter, ss->offsets[ss->top-1]); + js_printf(jp, " in %s) {\n", rval); + jp->indent += 4; + DECOMPILE_CODE(pc + oplen, tail - oplen); + jp->indent -= 4; + js_printf(jp, "\t}\n"); + todo = -2; + break; + + case JSOP_FORELEM: + pc++; + LOCAL_ASSERT(*pc == JSOP_IFEQ || *pc == JSOP_IFEQX); + len = js_CodeSpec[*pc].length; + + /* + * Arrange for the JSOP_ENUMELEM case to set tail for use by + * do_forinbody: code that uses on it to find the loop-closing + * jump (whatever its format, normal or extended), in order to + * bound the recursively decompiled loop body. + */ + sn = js_GetSrcNote(jp->script, pc); + JS_ASSERT(!forelem_tail); + forelem_tail = pc + js_GetSrcNoteOffset(sn, 0); + + /* + * This gets a little wacky. Only the length of the for loop + * body PLUS the element-indexing expression is known here, so + * we pass the after-loop pc to the JSOP_ENUMELEM case, which + * is immediately below, to decompile that helper bytecode via + * the 'forelem_done' local. + * + * Since a for..in loop can't nest in the head of another for + * loop, we can use forelem_{tail,done} singletons to remember + * state from JSOP_FORELEM to JSOP_ENUMELEM, thence (via goto) + * to label do_forinbody. + */ + JS_ASSERT(!forelem_done); + forelem_done = pc + GetJumpOffset(pc, pc); + break; + + case JSOP_ENUMELEM: + /* + * The stack has the object under the (top) index expression. + * The "rval" property id is underneath those two on the stack. + * The for loop body net and gross lengths can now be adjusted + * to account for the length of the indexing expression that + * came after JSOP_FORELEM and before JSOP_ENUMELEM. + */ + atom = NULL; + xval = POP_STR(); + lval = POP_STR(); + rval = OFF2STR(&ss->sprinter, ss->offsets[ss->top-1]); + JS_ASSERT(forelem_tail > pc); + tail = forelem_tail - pc; + forelem_tail = NULL; + JS_ASSERT(forelem_done > pc); + len = forelem_done - pc; + forelem_done = NULL; + goto do_forinbody; + + case JSOP_DUP2: + rval = OFF2STR(&ss->sprinter, ss->offsets[ss->top-2]); + todo = SprintPut(&ss->sprinter, rval, strlen(rval)); + if (todo < 0 || !PushOff(ss, todo, ss->opcodes[ss->top-2])) + return JS_FALSE; + /* FALL THROUGH */ + + case JSOP_DUP: + rval = OFF2STR(&ss->sprinter, ss->offsets[ss->top-1]); + op = ss->opcodes[ss->top-1]; + todo = SprintPut(&ss->sprinter, rval, strlen(rval)); + break; + + case JSOP_SETARG: + atom = GetSlotAtom(jp, js_GetArgument, GET_ARGNO(pc)); + LOCAL_ASSERT(atom); + goto do_setname; + + case JSOP_SETVAR: + atom = GetSlotAtom(jp, js_GetLocalVariable, GET_VARNO(pc)); + LOCAL_ASSERT(atom); + goto do_setname; + + case JSOP_SETCONST: + case JSOP_SETNAME: + atom = GET_ATOM(cx, jp->script, pc); + do_setname: + lval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0); + if (!lval) + return JS_FALSE; + rval = POP_STR(); + if (op == JSOP_SETNAME) + (void) PopOff(ss, op); + do_setlval: + sn = js_GetSrcNote(jp->script, pc - 1); + if (sn && SN_TYPE(sn) == SRC_ASSIGNOP) { + todo = Sprint(&ss->sprinter, "%s %s= %s", + lval, js_CodeSpec[lastop].token, rval); + } else { + sn = js_GetSrcNote(jp->script, pc); + todo = Sprint(&ss->sprinter, "%s%s = %s", + VarPrefix(sn), lval, rval); + } + break; + + case JSOP_NEW: + case JSOP_CALL: + case JSOP_EVAL: +#if JS_HAS_LVALUE_RETURN + case JSOP_SETCALL: +#endif + saveop = op; + op = JSOP_NOP; /* turn off parens */ + argc = GET_ARGC(pc); + argv = (char **) + JS_malloc(cx, (size_t)(argc + 1) * sizeof *argv); + if (!argv) + return JS_FALSE; + + ok = JS_TRUE; + for (i = argc; i > 0; i--) { + argv[i] = JS_strdup(cx, POP_STR()); + if (!argv[i]) { + ok = JS_FALSE; + break; + } + } + + /* Skip the JSOP_PUSHOBJ-created empty string. */ + LOCAL_ASSERT(ss->top >= 2); + (void) PopOff(ss, op); + + /* Get the callee's decompiled image in argv[0]. */ + argv[0] = JS_strdup(cx, POP_STR()); + if (!argv[i]) + ok = JS_FALSE; + + lval = "(", rval = ")"; + if (saveop == JSOP_NEW) { + todo = Sprint(&ss->sprinter, "%s %s%s", + js_new_str, argv[0], lval); + } else { + todo = Sprint(&ss->sprinter, "%s%s", + argv[0], lval); + } + if (todo < 0) + ok = JS_FALSE; + + for (i = 1; i <= argc; i++) { + if (!argv[i] || + Sprint(&ss->sprinter, "%s%s", + argv[i], (i < argc) ? ", " : "") < 0) { + ok = JS_FALSE; + break; + } + } + if (Sprint(&ss->sprinter, rval) < 0) + ok = JS_FALSE; + + for (i = 0; i <= argc; i++) { + if (argv[i]) + JS_free(cx, argv[i]); + } + JS_free(cx, argv); + if (!ok) + return JS_FALSE; + op = saveop; +#if JS_HAS_LVALUE_RETURN + if (op == JSOP_SETCALL) { + if (!PushOff(ss, todo, op)) + return JS_FALSE; + todo = Sprint(&ss->sprinter, ""); + } +#endif + break; + + case JSOP_DELNAME: + atom = GET_ATOM(cx, jp->script, pc); + lval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0); + if (!lval) + return JS_FALSE; + RETRACT(&ss->sprinter, lval); + todo = Sprint(&ss->sprinter, "%s %s", js_delete_str, lval); + break; + + case JSOP_DELPROP: + GET_ATOM_QUOTE_AND_FMT("%s %s[%s]", "%s %s.%s", rval); + lval = POP_STR(); + todo = Sprint(&ss->sprinter, fmt, js_delete_str, lval, rval); + break; + + case JSOP_DELELEM: + xval = POP_STR(); + lval = POP_STR(); + todo = Sprint(&ss->sprinter, "%s %s[%s]", + js_delete_str, lval, xval); + break; + + case JSOP_TYPEOF: + case JSOP_VOID: + rval = POP_STR(); + todo = Sprint(&ss->sprinter, "%s %s", cs->name, rval); + break; + + case JSOP_INCARG: + case JSOP_DECARG: + atom = GetSlotAtom(jp, js_GetArgument, GET_ARGNO(pc)); + LOCAL_ASSERT(atom); + goto do_incatom; + + case JSOP_INCVAR: + case JSOP_DECVAR: + atom = GetSlotAtom(jp, js_GetLocalVariable, GET_VARNO(pc)); + LOCAL_ASSERT(atom); + goto do_incatom; + + case JSOP_INCNAME: + case JSOP_DECNAME: + atom = GET_ATOM(cx, jp->script, pc); + do_incatom: + lval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0); + if (!lval) + return JS_FALSE; + RETRACT(&ss->sprinter, lval); + todo = Sprint(&ss->sprinter, "%s%s", + js_incop_str[!(cs->format & JOF_INC)], lval); + break; + + case JSOP_INCPROP: + case JSOP_DECPROP: + GET_ATOM_QUOTE_AND_FMT("%s%s[%s]", "%s%s.%s", rval); + lval = POP_STR(); + todo = Sprint(&ss->sprinter, fmt, + js_incop_str[!(cs->format & JOF_INC)], + lval, rval); + break; + + case JSOP_INCELEM: + case JSOP_DECELEM: + xval = POP_STR(); + lval = POP_STR(); + todo = Sprint(&ss->sprinter, "%s%s[%s]", + js_incop_str[!(cs->format & JOF_INC)], + lval, xval); + break; + + case JSOP_ARGINC: + case JSOP_ARGDEC: + atom = GetSlotAtom(jp, js_GetArgument, GET_ARGNO(pc)); + LOCAL_ASSERT(atom); + goto do_atominc; + + case JSOP_VARINC: + case JSOP_VARDEC: + atom = GetSlotAtom(jp, js_GetLocalVariable, GET_VARNO(pc)); + LOCAL_ASSERT(atom); + goto do_atominc; + + case JSOP_NAMEINC: + case JSOP_NAMEDEC: + atom = GET_ATOM(cx, jp->script, pc); + do_atominc: + lval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0); + if (!lval) + return JS_FALSE; + todo = STR2OFF(&ss->sprinter, lval); + SprintPut(&ss->sprinter, + js_incop_str[!(cs->format & JOF_INC)], + 2); + break; + + case JSOP_PROPINC: + case JSOP_PROPDEC: + GET_ATOM_QUOTE_AND_FMT("%s[%s]%s", "%s.%s%s", rval); + lval = POP_STR(); + todo = Sprint(&ss->sprinter, fmt, lval, rval, + js_incop_str[!(cs->format & JOF_INC)]); + break; + + case JSOP_ELEMINC: + case JSOP_ELEMDEC: + xval = POP_STR(); + lval = POP_STR(); + todo = Sprint(&ss->sprinter, "%s[%s]%s", + lval, xval, + js_incop_str[!(cs->format & JOF_INC)]); + break; + + case JSOP_GETPROP2: + op = JSOP_GETPROP; + (void) PopOff(ss, lastop); + /* FALL THROUGH */ + + case JSOP_GETPROP: + GET_ATOM_QUOTE_AND_FMT("%s[%s]", "%s.%s", rval); + lval = POP_STR(); + todo = Sprint(&ss->sprinter, fmt, lval, rval); + break; + + case JSOP_SETPROP: + GET_ATOM_QUOTE_AND_FMT("%s[%s] %s= %s", "%s.%s %s= %s", xval); + rval = POP_STR(); + lval = POP_STR(); + sn = js_GetSrcNote(jp->script, pc - 1); + todo = Sprint(&ss->sprinter, fmt, lval, xval, + (sn && SN_TYPE(sn) == SRC_ASSIGNOP) + ? js_CodeSpec[lastop].token + : "", + rval); + break; + + case JSOP_GETELEM2: + op = JSOP_GETELEM; + (void) PopOff(ss, lastop); + /* FALL THROUGH */ + + case JSOP_GETELEM: + op = JSOP_NOP; /* turn off parens */ + xval = POP_STR(); + op = JSOP_GETELEM; + lval = POP_STR(); + if (*xval == '\0') + todo = Sprint(&ss->sprinter, "%s", lval); + else + todo = Sprint(&ss->sprinter, "%s[%s]", lval, xval); + break; + + case JSOP_SETELEM: + op = JSOP_NOP; /* turn off parens */ + rval = POP_STR(); + xval = POP_STR(); + op = JSOP_SETELEM; + lval = POP_STR(); + if (*xval == '\0') + goto do_setlval; + sn = js_GetSrcNote(jp->script, pc - 1); + todo = Sprint(&ss->sprinter, "%s[%s] %s= %s", + lval, xval, + (sn && SN_TYPE(sn) == SRC_ASSIGNOP) + ? js_CodeSpec[lastop].token + : "", + rval); + break; + + case JSOP_ARGSUB: + i = (jsint) GET_ATOM_INDEX(pc); + todo = Sprint(&ss->sprinter, "%s[%d]", + js_arguments_str, (int) i); + break; + + case JSOP_ARGCNT: + todo = Sprint(&ss->sprinter, "%s.%s", + js_arguments_str, js_length_str); + break; + + case JSOP_GETARG: + atom = GetSlotAtom(jp, js_GetArgument, GET_ARGNO(pc)); + LOCAL_ASSERT(atom); + goto do_name; + + case JSOP_GETVAR: + atom = GetSlotAtom(jp, js_GetLocalVariable, GET_VARNO(pc)); + LOCAL_ASSERT(atom); + goto do_name; + + case JSOP_NAME: + atom = GET_ATOM(cx, jp->script, pc); + do_name: + sn = js_GetSrcNote(jp->script, pc); + rval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0); + if (!rval) + return JS_FALSE; + RETRACT(&ss->sprinter, rval); + todo = Sprint(&ss->sprinter, "%s%s", VarPrefix(sn), rval); + break; + + case JSOP_UINT16: + i = (jsint) GET_ATOM_INDEX(pc); + todo = Sprint(&ss->sprinter, "%u", (unsigned) i); + break; + + case JSOP_NUMBER: + atom = GET_ATOM(cx, jp->script, pc); + val = ATOM_KEY(atom); + if (JSVAL_IS_INT(val)) { + long ival = (long)JSVAL_TO_INT(val); + todo = Sprint(&ss->sprinter, "%ld", ival); + } else { + char buf[DTOSTR_STANDARD_BUFFER_SIZE]; + char *numStr = JS_dtostr(buf, sizeof buf, DTOSTR_STANDARD, + 0, *JSVAL_TO_DOUBLE(val)); + if (!numStr) { + JS_ReportOutOfMemory(cx); + return JS_FALSE; + } + todo = Sprint(&ss->sprinter, numStr); + } + break; + + case JSOP_STRING: + atom = GET_ATOM(cx, jp->script, pc); + rval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), + (jschar)'"'); + if (!rval) + return JS_FALSE; + todo = STR2OFF(&ss->sprinter, rval); + break; + + case JSOP_OBJECT: + case JSOP_ANONFUNOBJ: + case JSOP_NAMEDFUNOBJ: + atom = GET_ATOM(cx, jp->script, pc); + if (op == JSOP_OBJECT) { + str = js_ValueToSource(cx, ATOM_KEY(atom)); + if (!str) + return JS_FALSE; + } else { + if (!js_fun_toString(cx, ATOM_TO_OBJECT(atom), + JS_DONT_PRETTY_PRINT, 0, NULL, + &val)) { + return JS_FALSE; + } + str = JSVAL_TO_STRING(val); + } + todo = SprintPut(&ss->sprinter, JS_GetStringBytes(str), + JSSTRING_LENGTH(str)); + break; + +#if JS_HAS_SWITCH_STATEMENT + case JSOP_TABLESWITCH: + case JSOP_TABLESWITCHX: + { + jsbytecode *pc2; + ptrdiff_t off, off2; + jsint j, n, low, high; + TableEntry *table; + + sn = js_GetSrcNote(jp->script, pc); + JS_ASSERT(sn && SN_TYPE(sn) == SRC_SWITCH); + len = js_GetSrcNoteOffset(sn, 0); + pc2 = pc; + off = GetJumpOffset(pc, pc2); + pc2 += JUMP_OFFSET_LEN; + low = GetJumpOffset(pc, pc2); + pc2 += JUMP_OFFSET_LEN; + high = GetJumpOffset(pc, pc2); + + n = high - low + 1; + if (n == 0) { + table = NULL; + j = 0; + } else { + table = (TableEntry *) + JS_malloc(cx, (size_t)n * sizeof *table); + if (!table) + return JS_FALSE; + for (i = j = 0; i < n; i++) { + pc2 += JUMP_OFFSET_LEN; + off2 = GetJumpOffset(pc, pc2); + if (off2) { + table[j].key = INT_TO_JSVAL(low + i); + table[j++].offset = off2; + } + } + js_HeapSort(table, (size_t) j, sizeof *table, + CompareOffsets, NULL); + } + + ok = DecompileSwitch(ss, table, (uintN)j, pc, len, off, + JS_FALSE); + JS_free(cx, table); + if (!ok) + return ok; + todo = -2; + break; + } + + case JSOP_LOOKUPSWITCH: + case JSOP_LOOKUPSWITCHX: + { + jsbytecode *pc2; + ptrdiff_t off, off2; + jsint npairs; + TableEntry *table; + + sn = js_GetSrcNote(jp->script, pc); + JS_ASSERT(sn && SN_TYPE(sn) == SRC_SWITCH); + len = js_GetSrcNoteOffset(sn, 0); + pc2 = pc; + off = GetJumpOffset(pc, pc2); + pc2 += JUMP_OFFSET_LEN; + npairs = (jsint) GET_ATOM_INDEX(pc2); + pc2 += ATOM_INDEX_LEN; + + table = (TableEntry *) + JS_malloc(cx, (size_t)npairs * sizeof *table); + if (!table) + return JS_FALSE; + for (i = 0; i < npairs; i++) { + atom = GET_ATOM(cx, jp->script, pc2); + pc2 += ATOM_INDEX_LEN; + off2 = GetJumpOffset(pc, pc2); + pc2 += JUMP_OFFSET_LEN; + table[i].key = ATOM_KEY(atom); + table[i].offset = off2; + } + + ok = DecompileSwitch(ss, table, (uintN)npairs, pc, len, off, + JS_FALSE); + JS_free(cx, table); + if (!ok) + return ok; + todo = -2; + break; + } + + case JSOP_CONDSWITCH: + { + jsbytecode *pc2; + ptrdiff_t off, off2, caseOff; + jsint ncases; + TableEntry *table; + + sn = js_GetSrcNote(jp->script, pc); + JS_ASSERT(sn && SN_TYPE(sn) == SRC_SWITCH); + len = js_GetSrcNoteOffset(sn, 0); + off = js_GetSrcNoteOffset(sn, 1); + + /* + * Count the cases using offsets from switch to first case, + * and case to case, stored in srcnote immediates. + */ + pc2 = pc; + off2 = off; + for (ncases = 0; off2 != 0; ncases++) { + pc2 += off2; + JS_ASSERT(*pc2 == JSOP_CASE || *pc2 == JSOP_DEFAULT || + *pc2 == JSOP_CASEX || *pc2 == JSOP_DEFAULTX); + if (*pc2 == JSOP_DEFAULT || *pc2 == JSOP_DEFAULTX) { + /* End of cases, but count default as a case. */ + off2 = 0; + } else { + sn = js_GetSrcNote(jp->script, pc2); + JS_ASSERT(sn && SN_TYPE(sn) == SRC_PCDELTA); + off2 = js_GetSrcNoteOffset(sn, 0); + } + } + + /* + * Allocate table and rescan the cases using their srcnotes, + * stashing each case's delta from switch top in table[i].key, + * and the distance to its statements in table[i].offset. + */ + table = (TableEntry *) + JS_malloc(cx, (size_t)ncases * sizeof *table); + if (!table) + return JS_FALSE; + pc2 = pc; + off2 = off; + for (i = 0; i < ncases; i++) { + pc2 += off2; + JS_ASSERT(*pc2 == JSOP_CASE || *pc2 == JSOP_DEFAULT || + *pc2 == JSOP_CASEX || *pc2 == JSOP_DEFAULTX); + caseOff = pc2 - pc; + table[i].key = INT_TO_JSVAL((jsint) caseOff); + table[i].offset = caseOff + GetJumpOffset(pc2, pc2); + if (*pc2 == JSOP_CASE || *pc2 == JSOP_CASEX) { + sn = js_GetSrcNote(jp->script, pc2); + JS_ASSERT(sn && SN_TYPE(sn) == SRC_PCDELTA); + off2 = js_GetSrcNoteOffset(sn, 0); + } + } + + /* + * Find offset of default code by fetching the default offset + * from the end of table. JSOP_CONDSWITCH always has a default + * case at the end. + */ + off = JSVAL_TO_INT(table[ncases-1].key); + pc2 = pc + off; + off += GetJumpOffset(pc2, pc2); + + ok = DecompileSwitch(ss, table, (uintN)ncases, pc, len, off, + JS_TRUE); + JS_free(cx, table); + if (!ok) + return ok; + todo = -2; + break; + } + + case JSOP_CASE: + case JSOP_CASEX: + { + lval = POP_STR(); + if (!lval) + return JS_FALSE; + js_printf(jp, "\tcase %s:\n", lval); + todo = -2; + break; + } + +#endif /* JS_HAS_SWITCH_STATEMENT */ + +#if !JS_BUG_FALLIBLE_EQOPS + case JSOP_NEW_EQ: + case JSOP_NEW_NE: + rval = POP_STR(); + lval = POP_STR(); + todo = Sprint(&ss->sprinter, "%s %c%s %s", + lval, + (op == JSOP_NEW_EQ) ? '=' : '!', +#if JS_HAS_TRIPLE_EQOPS + JSVERSION_IS_ECMA(cx->version) ? "==" : +#endif + "=", + rval); + break; +#endif /* !JS_BUG_FALLIBLE_EQOPS */ + +#if JS_HAS_LEXICAL_CLOSURE + case JSOP_CLOSURE: + atom = GET_ATOM(cx, jp->script, pc); + JS_ASSERT(ATOM_IS_OBJECT(atom)); + goto do_function; +#endif /* JS_HAS_LEXICAL_CLOSURE */ + +#if JS_HAS_EXPORT_IMPORT + case JSOP_EXPORTALL: + js_printf(jp, "\texport *\n"); + todo = -2; + break; + + case JSOP_EXPORTNAME: + atom = GET_ATOM(cx, jp->script, pc); + rval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), 0); + if (!rval) + return JS_FALSE; + RETRACT(&ss->sprinter, rval); + js_printf(jp, "\texport %s\n", rval); + todo = -2; + break; + + case JSOP_IMPORTALL: + lval = POP_STR(); + js_printf(jp, "\timport %s.*\n", lval); + todo = -2; + break; + + case JSOP_IMPORTPROP: + GET_ATOM_QUOTE_AND_FMT("\timport %s[%s]\n", "\timport %s.%s\n", + rval); + lval = POP_STR(); + js_printf(jp, fmt, lval, rval); + todo = -2; + break; + + case JSOP_IMPORTELEM: + xval = POP_STR(); + op = JSOP_GETELEM; + lval = POP_STR(); + js_printf(jp, "\timport %s[%s]\n", lval, xval); + todo = -2; + break; +#endif /* JS_HAS_EXPORT_IMPORT */ + + case JSOP_TRAP: + op = JS_GetTrapOpcode(cx, jp->script, pc); + if (op == JSOP_LIMIT) + return JS_FALSE; + *pc = op; + cs = &js_CodeSpec[op]; + len = cs->length; + DECOMPILE_CODE(pc, len); + *pc = JSOP_TRAP; + todo = -2; + break; + +#if JS_HAS_INITIALIZERS + case JSOP_NEWINIT: + LOCAL_ASSERT(ss->top >= 2); + (void) PopOff(ss, op); + lval = POP_STR(); +#if JS_HAS_SHARP_VARS + op = (JSOp)pc[len]; + if (op == JSOP_DEFSHARP) { + pc += len; + cs = &js_CodeSpec[op]; + len = cs->length; + i = (jsint) GET_ATOM_INDEX(pc); + todo = Sprint(&ss->sprinter, "#%u=%c", + (unsigned) i, + (*lval == 'O') ? '{' : '['); + } else +#endif /* JS_HAS_SHARP_VARS */ + { + todo = Sprint(&ss->sprinter, (*lval == 'O') ? "{" : "["); + } + break; + + case JSOP_ENDINIT: + rval = POP_STR(); + sn = js_GetSrcNote(jp->script, pc); + todo = Sprint(&ss->sprinter, "%s%s%c", + rval, + (sn && SN_TYPE(sn) == SRC_CONTINUE) ? ", " : "", + (*rval == '{') ? '}' : ']'); + break; + + case JSOP_INITPROP: + case JSOP_INITCATCHVAR: + atom = GET_ATOM(cx, jp->script, pc); + xval = QuoteString(&ss->sprinter, ATOM_TO_STRING(atom), + ATOM_KEYWORD(atom) ? '\'' : 0); + if (!xval) + return JS_FALSE; + rval = POP_STR(); + lval = POP_STR(); + do_initprop: +#ifdef OLD_GETTER_SETTER + todo = Sprint(&ss->sprinter, "%s%s%s%s%s:%s", + lval, + (lval[1] != '\0') ? ", " : "", + xval, + (lastop == JSOP_GETTER || lastop == JSOP_SETTER) + ? " " : "", + (lastop == JSOP_GETTER) ? js_getter_str : + (lastop == JSOP_SETTER) ? js_setter_str : + "", + rval); +#else + if (lastop == JSOP_GETTER || lastop == JSOP_SETTER) { + todo = Sprint(&ss->sprinter, "%s%s%s %s%s", + lval, + (lval[1] != '\0') ? ", " : "", + (lastop == JSOP_GETTER) + ? js_get_str : js_set_str, + xval, + rval + strlen(js_function_str) + 1); + } else { + todo = Sprint(&ss->sprinter, "%s%s%s:%s", + lval, + (lval[1] != '\0') ? ", " : "", + xval, + rval); + } +#endif + break; + + case JSOP_INITELEM: + rval = POP_STR(); + xval = POP_STR(); + lval = POP_STR(); + sn = js_GetSrcNote(jp->script, pc); + if (sn && SN_TYPE(sn) == SRC_LABEL) + goto do_initprop; + todo = Sprint(&ss->sprinter, "%s%s%s", + lval, + (lval[1] != '\0' || *xval != '0') ? ", " : "", + rval); + break; + +#if JS_HAS_SHARP_VARS + case JSOP_DEFSHARP: + i = (jsint) GET_ATOM_INDEX(pc); + rval = POP_STR(); + todo = Sprint(&ss->sprinter, "#%u=%s", (unsigned) i, rval); + break; + + case JSOP_USESHARP: + i = (jsint) GET_ATOM_INDEX(pc); + todo = Sprint(&ss->sprinter, "#%u#", (unsigned) i); + break; +#endif /* JS_HAS_SHARP_VARS */ +#endif /* JS_HAS_INITIALIZERS */ + +#if JS_HAS_DEBUGGER_KEYWORD + case JSOP_DEBUGGER: + js_printf(jp, "\tdebugger;\n"); + todo = -2; + break; +#endif /* JS_HAS_DEBUGGER_KEYWORD */ + + default: + todo = -2; + break; + } + } + + if (todo < 0) { + /* -2 means "don't push", -1 means reported error. */ + if (todo == -1) + return JS_FALSE; + } else { + if (!PushOff(ss, todo, op)) + return JS_FALSE; + } + pc += len; + } + +/* + * Undefine local macros. + */ +#undef DECOMPILE_CODE +#undef POP_STR +#undef LOCAL_ASSERT +#undef GET_ATOM_QUOTE_AND_FMT + + return JS_TRUE; +} + + +JSBool +js_DecompileCode(JSPrinter *jp, JSScript *script, jsbytecode *pc, uintN len) +{ + SprintStack ss; + JSContext *cx; + void *mark, *space; + size_t offsetsz, opcodesz; + JSBool ok; + JSScript *oldscript; + char *last; + + /* Initialize a sprinter for use with the offset stack. */ + ss.printer = jp; + cx = jp->sprinter.context; + mark = JS_ARENA_MARK(&cx->tempPool); + INIT_SPRINTER(cx, &ss.sprinter, &cx->tempPool, PAREN_SLOP); + + /* Allocate the parallel (to avoid padding) offset and opcode stacks. */ + offsetsz = script->depth * sizeof(ptrdiff_t); + opcodesz = script->depth * sizeof(jsbytecode); + JS_ARENA_ALLOCATE(space, &cx->tempPool, offsetsz + opcodesz); + if (!space) { + ok = JS_FALSE; + goto out; + } + ss.offsets = (ptrdiff_t *) space; + ss.opcodes = (jsbytecode *) ((char *)space + offsetsz); + ss.top = 0; + + /* Call recursive subroutine to do the hard work. */ + oldscript = jp->script; + jp->script = script; + ok = Decompile(&ss, pc, len); + jp->script = oldscript; + + /* If the given code didn't empty the stack, do it now. */ + if (ss.top) { + do { + last = OFF2STR(&ss.sprinter, PopOff(&ss, JSOP_NOP)); + } while (ss.top); + js_printf(jp, "%s", last); + } + +out: + /* Free all temporary stuff allocated under this call. */ + JS_ARENA_RELEASE(&cx->tempPool, mark); + return ok; +} + +JSBool +js_DecompileScript(JSPrinter *jp, JSScript *script) +{ + return js_DecompileCode(jp, script, script->code, (uintN)script->length); +} + +static const char native_code_str[] = "\t[native code]\n"; + +JSBool +js_DecompileFunctionBody(JSPrinter *jp, JSFunction *fun) +{ + JSScript *script; + JSScope *scope, *save; + JSBool ok; + + script = fun->script; + if (!script) { + js_printf(jp, native_code_str); + return JS_TRUE; + } + scope = fun->object ? OBJ_SCOPE(fun->object) : NULL; + save = jp->scope; + jp->scope = scope; + ok = js_DecompileCode(jp, script, script->code, (uintN)script->length); + jp->scope = save; + return ok; +} + +JSBool +js_DecompileFunction(JSPrinter *jp, JSFunction *fun) +{ + JSContext *cx; + uintN i, nargs, indent; + void *mark; + JSAtom **params; + JSScope *scope, *oldscope; + JSScopeProperty *sprop; + JSBool ok; + + /* + * If pretty, conform to ECMA-262 Edition 3, 15.3.4.2, by decompiling a + * FunctionDeclaration. Otherwise, check the JSFUN_LAMBDA flag and force + * an expression by parenthesizing. + */ + if (jp->pretty) { + js_puts(jp, "\n"); + js_printf(jp, "\t"); + } else { + if (fun->flags & JSFUN_LAMBDA) + js_puts(jp, "("); + } + if (fun->flags & JSFUN_GETTER) + js_printf(jp, "%s ", js_getter_str); + else if (fun->flags & JSFUN_SETTER) + js_printf(jp, "%s ", js_setter_str); + + js_printf(jp, "%s ", js_function_str); + if (fun->atom && !QuoteString(&jp->sprinter, ATOM_TO_STRING(fun->atom), 0)) + return JS_FALSE; + js_puts(jp, "("); + + if (fun->script && fun->object) { + /* + * Print the parameters. + * + * This code is complicated by the need to handle duplicate parameter + * names, as required by ECMA (bah!). A duplicate parameter is stored + * as another node with the same id (the parameter name) but different + * shortid (the argument index) along the property tree ancestor line + * starting at SCOPE_LAST_PROP(scope). Only the last duplicate param + * is mapped by the scope's hash table. + */ + cx = jp->sprinter.context; + nargs = fun->nargs; + mark = JS_ARENA_MARK(&cx->tempPool); + JS_ARENA_ALLOCATE_CAST(params, JSAtom **, &cx->tempPool, + nargs * sizeof(JSAtom *)); + if (!params) { + JS_ReportOutOfMemory(cx); + return JS_FALSE; + } + scope = OBJ_SCOPE(fun->object); + for (sprop = SCOPE_LAST_PROP(scope); sprop; sprop = sprop->parent) { + if (sprop->getter != js_GetArgument) + continue; + JS_ASSERT(sprop->flags & SPROP_HAS_SHORTID); + JS_ASSERT((uintN) sprop->shortid < nargs); + JS_ASSERT(!JSVAL_IS_INT(sprop->id)); + params[(uintN) sprop->shortid] = (JSAtom *) sprop->id; + } + for (i = 0; i < nargs; i++) { + if (i > 0) + js_puts(jp, ", "); + if (!QuoteString(&jp->sprinter, ATOM_TO_STRING(params[i]), 0)) + return JS_FALSE; + } + JS_ARENA_RELEASE(&cx->tempPool, mark); +#ifdef __GNUC__ + } else { + scope = NULL; +#endif + } + + js_printf(jp, ") {\n"); + indent = jp->indent; + jp->indent += 4; + if (fun->script && fun->object) { + oldscope = jp->scope; + jp->scope = scope; + ok = js_DecompileScript(jp, fun->script); + jp->scope = oldscope; + if (!ok) { + jp->indent = indent; + return JS_FALSE; + } + } else { + js_printf(jp, native_code_str); + } + jp->indent -= 4; + js_printf(jp, "\t}"); + + if (jp->pretty) { + js_puts(jp, "\n"); + } else { + if (fun->flags & JSFUN_LAMBDA) + js_puts(jp, ")"); + } + return JS_TRUE; +} + +JSString * +js_DecompileValueGenerator(JSContext *cx, intN spindex, jsval v, + JSString *fallback) +{ + JSStackFrame *fp, *down; + jsbytecode *pc, *begin, *end, *tmp; + jsval *sp, *base, *limit; + JSScript *script; + JSOp op; + const JSCodeSpec *cs; + uint32 format, mode; + intN depth; + jssrcnote *sn; + uintN len, off; + JSPrinter *jp; + JSString *name; + + fp = cx->fp; + if (!fp) + goto do_fallback; + + /* Try to find sp's generating pc depth slots under it on the stack. */ + pc = fp->pc; + if (spindex == JSDVG_SEARCH_STACK) { + if (!pc) { + /* + * Current frame is native: look under it for a scripted call + * in which a decompilable bytecode string that generated the + * value as an actual argument might exist. + */ + JS_ASSERT(!fp->script && fp->fun && fp->fun->native); + down = fp->down; + if (!down) + goto do_fallback; + script = down->script; + base = fp->argv; + limit = base + fp->argc; + } else { + /* + * This should be a script activation, either a top-level + * script or a scripted function. But be paranoid about calls + * to js_DecompileValueGenerator from code that hasn't fully + * initialized a (default-all-zeroes) frame. + */ + script = fp->script; + base = fp->spbase; + limit = fp->sp; + } + + /* + * Pure paranoia about default-zeroed frames being active while + * js_DecompileValueGenerator is called. It can't hurt much now; + * error reporting performance is not an issue. + */ + if (!script || !base || !limit) + goto do_fallback; + + /* + * Try to find operand-generating pc depth slots below sp. + * + * In the native case, we know the arguments have generating pc's + * under them, on account of fp->down->script being non-null: all + * compiled scripts get depth slots for generating pc's allocated + * upon activation, at the top of js_Interpret. + * + * In the script or scripted function case, the same reasoning + * applies to fp rather than to fp->down. + */ + for (sp = base; sp < limit; sp++) { + if (*sp == v) { + depth = (intN)script->depth; + pc = (jsbytecode *) sp[-depth]; + break; + } + } + } else { + /* + * At this point, pc may or may not be null, i.e., we could be in + * a script activation, or we could be in a native frame that was + * called by another native function. Check pc and script. + */ + if (!pc) + goto do_fallback; + script = fp->script; + if (!script) + goto do_fallback; + + if (spindex != JSDVG_IGNORE_STACK) { + JS_ASSERT(spindex < 0); + depth = (intN)script->depth; +#if !JS_HAS_NO_SUCH_METHOD + JS_ASSERT(-depth <= spindex); +#endif + spindex -= depth; + + base = (jsval *) cx->stackPool.current->base; + limit = (jsval *) cx->stackPool.current->avail; + sp = fp->sp + spindex; + if (JS_UPTRDIFF(sp, base) < JS_UPTRDIFF(limit, base)) + pc = (jsbytecode *) *sp; + } + } + + /* + * Again, be paranoid, this time about possibly loading an invalid pc + * from sp[-(1+depth)]. + */ + if (JS_UPTRDIFF(pc, script->code) >= (jsuword)script->length) { + pc = fp->pc; + if (!pc) + goto do_fallback; + } + op = (JSOp) *pc; + if (op == JSOP_TRAP) + op = JS_GetTrapOpcode(cx, script, pc); + + /* XXX handle null as a special case, to avoid calling null "object" */ + if (op == JSOP_NULL) + return ATOM_TO_STRING(cx->runtime->atomState.nullAtom); + + cs = &js_CodeSpec[op]; + format = cs->format; + mode = (format & JOF_MODEMASK); + + /* NAME ops are self-contained, but others require left context. */ + if (mode == JOF_NAME) { + begin = pc; + } else { + sn = js_GetSrcNote(script, pc); + if (!sn || SN_TYPE(sn) != SRC_PCBASE) + goto do_fallback; + begin = pc - js_GetSrcNoteOffset(sn, 0); + } + end = pc + cs->length; + len = PTRDIFF(end, begin, jsbytecode); + + if (format & (JOF_SET | JOF_DEL | JOF_INCDEC | JOF_IMPORT | JOF_FOR)) { + tmp = (jsbytecode *) JS_malloc(cx, len * sizeof(jsbytecode)); + if (!tmp) + return NULL; + memcpy(tmp, begin, len * sizeof(jsbytecode)); + if (mode == JOF_NAME) { + tmp[0] = JSOP_NAME; + } else { + /* + * We must replace the faulting pc's bytecode with a corresponding + * JSOP_GET* code. For JSOP_SET{PROP,ELEM}, we must use the "2nd" + * form of JSOP_GET{PROP,ELEM}, to throw away the assignment op's + * right-hand operand and decompile it as if it were a GET of its + * left-hand operand. + */ + off = len - cs->length; + JS_ASSERT(off == (uintN) PTRDIFF(pc, begin, jsbytecode)); + if (mode == JOF_PROP) { + tmp[off] = (format & JOF_SET) ? JSOP_GETPROP2 : JSOP_GETPROP; + } else if (mode == JOF_ELEM) { + tmp[off] = (format & JOF_SET) ? JSOP_GETELEM2 : JSOP_GETELEM; + } else { + /* + * A zero mode means precisely that op is uncategorized for our + * purposes, so we must write per-op special case code here. + */ + switch (op) { + case JSOP_ENUMELEM: + tmp[off] = JSOP_GETELEM; + break; +#if JS_HAS_LVALUE_RETURN + case JSOP_SETCALL: + tmp[off] = JSOP_CALL; + break; +#endif + default: + JS_ASSERT(0); + } + } + } + begin = tmp; + } else { + /* No need to revise script bytecode. */ + tmp = NULL; + } + + jp = js_NewPrinter(cx, "js_DecompileValueGenerator", 0, JS_FALSE); + if (jp && js_DecompileCode(jp, script, begin, len)) + name = js_GetPrinterOutput(jp); + else + name = NULL; + js_DestroyPrinter(jp); + if (tmp) + JS_free(cx, tmp); + return name; + + do_fallback: + return fallback ? fallback : js_ValueToString(cx, v); +} diff --git a/src/dom/js/jsopcode.h b/src/dom/js/jsopcode.h new file mode 100644 index 000000000..e24fb2bf8 --- /dev/null +++ b/src/dom/js/jsopcode.h @@ -0,0 +1,273 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef jsopcode_h___ +#define jsopcode_h___ +/* + * JS bytecode definitions. + */ +#include +#include "jsprvtd.h" +#include "jspubtd.h" + +JS_BEGIN_EXTERN_C + +/* + * JS operation bytecodes. + */ +typedef enum JSOp { +#define OPDEF(op,val,name,token,length,nuses,ndefs,prec,format) \ + op = val, +#include "jsopcode.tbl" +#undef OPDEF + JSOP_LIMIT +} JSOp; + +/* + * JS bytecode formats. + */ +#define JOF_BYTE 0 /* single bytecode, no immediates */ +#define JOF_JUMP 1 /* signed 16-bit jump offset immediate */ +#define JOF_CONST 2 /* unsigned 16-bit constant pool index */ +#define JOF_UINT16 3 /* unsigned 16-bit immediate operand */ +#define JOF_TABLESWITCH 4 /* table switch */ +#define JOF_LOOKUPSWITCH 5 /* lookup switch */ +#define JOF_QARG 6 /* quickened get/set function argument ops */ +#define JOF_QVAR 7 /* quickened get/set local variable ops */ +#define JOF_DEFLOCALVAR 8 /* define local var with initial value */ +#define JOF_JUMPX 9 /* signed 32-bit jump offset immediate */ +#define JOF_TABLESWITCHX 10 /* extended (32-bit offset) table switch */ +#define JOF_LOOKUPSWITCHX 11 /* extended (32-bit offset) lookup switch */ +#define JOF_TYPEMASK 0x000f /* mask for above immediate types */ +#define JOF_NAME 0x0010 /* name operation */ +#define JOF_PROP 0x0020 /* obj.prop operation */ +#define JOF_ELEM 0x0030 /* obj[index] operation */ +#define JOF_MODEMASK 0x0030 /* mask for above addressing modes */ +#define JOF_SET 0x0040 /* set (i.e., assignment) operation */ +#define JOF_DEL 0x0080 /* delete operation */ +#define JOF_DEC 0x0100 /* decrement (--, not ++) opcode */ +#define JOF_INC 0x0200 /* increment (++, not --) opcode */ +#define JOF_INCDEC 0x0300 /* increment or decrement opcode */ +#define JOF_POST 0x0400 /* postorder increment or decrement */ +#define JOF_IMPORT 0x0800 /* import property op */ +#define JOF_FOR 0x1000 /* for-in property op */ +#define JOF_ASSIGNING JOF_SET /* hint for JSClass.resolve, used for ops + that do simplex assignment */ +#define JOF_BACKPATCH 0x4000 /* backpatch placeholder during codegen */ +#define JOF_LEFTASSOC 0x8000 /* left-associative operator */ + +#define JOF_TYPE_IS_EXTENDED_JUMP(t) \ + ((unsigned)((t) - JOF_JUMPX) <= (unsigned)(JOF_LOOKUPSWITCHX - JOF_JUMPX)) + +/* + * Immediate operand getters, setters, and bounds. + */ + +/* Short (2-byte signed offset) relative jump macros. */ +#define JUMP_OFFSET_LEN 2 +#define JUMP_OFFSET_HI(off) ((jsbytecode)((off) >> 8)) +#define JUMP_OFFSET_LO(off) ((jsbytecode)(off)) +#define GET_JUMP_OFFSET(pc) ((int16)(((pc)[1] << 8) | (pc)[2])) +#define SET_JUMP_OFFSET(pc,off) ((pc)[1] = JUMP_OFFSET_HI(off), \ + (pc)[2] = JUMP_OFFSET_LO(off)) +#define JUMP_OFFSET_MIN ((int16)0x8000) +#define JUMP_OFFSET_MAX ((int16)0x7fff) + +/* + * When a short jump won't hold a relative offset, its 2-byte immediate offset + * operand is an unsigned index of a span-dependency record, maintained until + * code generation finishes -- after which some (but we hope not nearly all) + * span-dependent jumps must be extended (see OptimizeSpanDeps in jsemit.c). + * + * If the span-dependency record index overflows SPANDEP_INDEX_MAX, the jump + * offset will contain SPANDEP_INDEX_HUGE, indicating that the record must be + * found (via binary search) by its "before span-dependency optimization" pc + * offset (from script main entry point). + */ +#define GET_SPANDEP_INDEX(pc) ((uint16)(((pc)[1] << 8) | (pc)[2])) +#define SET_SPANDEP_INDEX(pc,i) ((pc)[1] = JUMP_OFFSET_HI(i), \ + (pc)[2] = JUMP_OFFSET_LO(i)) +#define SPANDEP_INDEX_MAX ((uint16)0xfffe) +#define SPANDEP_INDEX_HUGE ((uint16)0xffff) + +/* Ultimately, if short jumps won't do, emit long (4-byte signed) offsets. */ +#define JUMPX_OFFSET_LEN 4 +#define JUMPX_OFFSET_B3(off) ((jsbytecode)((off) >> 24)) +#define JUMPX_OFFSET_B2(off) ((jsbytecode)((off) >> 16)) +#define JUMPX_OFFSET_B1(off) ((jsbytecode)((off) >> 8)) +#define JUMPX_OFFSET_B0(off) ((jsbytecode)(off)) +#define GET_JUMPX_OFFSET(pc) ((int32)(((pc)[1] << 24) | ((pc)[2] << 16) \ + | ((pc)[3] << 8) | (pc)[4])) +#define SET_JUMPX_OFFSET(pc,off)((pc)[1] = JUMPX_OFFSET_B3(off), \ + (pc)[2] = JUMPX_OFFSET_B2(off), \ + (pc)[3] = JUMPX_OFFSET_B1(off), \ + (pc)[4] = JUMPX_OFFSET_B0(off)) +#define JUMPX_OFFSET_MIN ((int32)0x80000000) +#define JUMPX_OFFSET_MAX ((int32)0x7fffffff) + +/* A literal is indexed by a per-script atom map. */ +#define ATOM_INDEX_LEN 2 +#define ATOM_INDEX_HI(index) ((jsbytecode)((index) >> 8)) +#define ATOM_INDEX_LO(index) ((jsbytecode)(index)) +#define GET_ATOM_INDEX(pc) ((jsatomid)(((pc)[1] << 8) | (pc)[2])) +#define SET_ATOM_INDEX(pc,index)((pc)[1] = ATOM_INDEX_HI(index), \ + (pc)[2] = ATOM_INDEX_LO(index)) +#define GET_ATOM(cx,script,pc) js_GetAtom((cx), &(script)->atomMap, \ + GET_ATOM_INDEX(pc)) +#define ATOM_INDEX_LIMIT_LOG2 16 +#define ATOM_INDEX_LIMIT ((uint32)1 << ATOM_INDEX_LIMIT_LOG2) + +/* Actual argument count operand format helpers. */ +#define ARGC_HI(argc) ((jsbytecode)((argc) >> 8)) +#define ARGC_LO(argc) ((jsbytecode)(argc)) +#define GET_ARGC(pc) ((uintN)(((pc)[1] << 8) | (pc)[2])) +#define ARGC_LIMIT ((uint32)1 << 16) + +/* Synonyms for quick JOF_QARG and JOF_QVAR bytecodes. */ +#define GET_ARGNO(pc) GET_ARGC(pc) +#define SET_ARGNO(pc,argno) SET_JUMP_OFFSET(pc,argno) +#define ARGNO_LEN JUMP_OFFSET_LEN +#define GET_VARNO(pc) GET_ARGC(pc) +#define SET_VARNO(pc,varno) SET_JUMP_OFFSET(pc,varno) +#define VARNO_LEN JUMP_OFFSET_LEN + +struct JSCodeSpec { + const char *name; /* JS bytecode name */ + const char *token; /* JS source literal or null */ + int8 length; /* length including opcode byte */ + int8 nuses; /* arity, -1 if variadic */ + int8 ndefs; /* number of stack results */ + uint8 prec; /* operator precedence */ + uint32 format; /* immediate operand format */ +}; + +extern const char js_const_str[]; +extern const char js_var_str[]; +extern const char js_function_str[]; +extern const char js_in_str[]; +extern const char js_instanceof_str[]; +extern const char js_new_str[]; +extern const char js_delete_str[]; +extern const char js_typeof_str[]; +extern const char js_void_str[]; +extern const char js_null_str[]; +extern const char js_this_str[]; +extern const char js_false_str[]; +extern const char js_true_str[]; +extern const JSCodeSpec js_CodeSpec[]; +extern uintN js_NumCodeSpecs; +extern const jschar js_EscapeMap[]; + +/* + * Return a GC'ed string containing the chars in str, with any non-printing + * chars or quotes (' or " as specified by the quote argument) escaped, and + * with the quote character at the beginning and end of the result string. + */ +extern JSString * +js_QuoteString(JSContext *cx, JSString *str, jschar quote); + +/* + * JSPrinter operations, for printf style message formatting. The return + * value from js_GetPrinterOutput() is the printer's cumulative output, in + * a GC'ed string. + */ +extern JSPrinter * +js_NewPrinter(JSContext *cx, const char *name, uintN indent, JSBool pretty); + +extern void +js_DestroyPrinter(JSPrinter *jp); + +extern JSString * +js_GetPrinterOutput(JSPrinter *jp); + +extern int +js_printf(JSPrinter *jp, const char *format, ...); + +extern JSBool +js_puts(JSPrinter *jp, const char *s); + +#ifdef DEBUG +/* + * Disassemblers, for debugging only. + */ +#include + +extern JS_FRIEND_API(void) +js_Disassemble(JSContext *cx, JSScript *script, JSBool lines, FILE *fp); + +extern JS_FRIEND_API(uintN) +js_Disassemble1(JSContext *cx, JSScript *script, jsbytecode *pc, uintN loc, + JSBool lines, FILE *fp); +#endif /* DEBUG */ + +/* + * Decompilers, for script, function, and expression pretty-printing. + */ +extern JSBool +js_DecompileCode(JSPrinter *jp, JSScript *script, jsbytecode *pc, uintN len); + +extern JSBool +js_DecompileScript(JSPrinter *jp, JSScript *script); + +extern JSBool +js_DecompileFunctionBody(JSPrinter *jp, JSFunction *fun); + +extern JSBool +js_DecompileFunction(JSPrinter *jp, JSFunction *fun); + +/* + * Find the source expression that resulted in v, and return a new string + * containing it. Fall back on v's string conversion (fallback) if we can't + * find the bytecode that generated and pushed v on the operand stack. + * + * Search the current stack frame if spindex is JSDVG_SEARCH_STACK. Don't + * look for v on the stack if spindex is JSDVG_IGNORE_STACK. Otherwise, + * spindex is the negative index of v, measured from cx->fp->sp, or from a + * lower frame's sp if cx->fp is native. + */ +extern JSString * +js_DecompileValueGenerator(JSContext *cx, intN spindex, jsval v, + JSString *fallback); + +#define JSDVG_IGNORE_STACK 0 +#define JSDVG_SEARCH_STACK 1 + +JS_END_EXTERN_C + +#endif /* jsopcode_h___ */ diff --git a/src/dom/js/jsopcode.tbl b/src/dom/js/jsopcode.tbl new file mode 100644 index 000000000..d4bad0fd9 --- /dev/null +++ b/src/dom/js/jsopcode.tbl @@ -0,0 +1,333 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* + * JavaScript operation bytecodes. If you need to allocate a bytecode, look + * for a name of the form JSOP_UNUSED* and claim it. Otherwise, always add at + * the end of the table. + * + * Includers must define an OPDEF macro of the following form: + * + * #define OPDEF(op,val,name,image,length,nuses,ndefs,prec,format) ... + * + * Selected arguments can be expanded in initializers. The op argument is + * expanded followed by comma in the JSOp enum (jsopcode.h), e.g. The value + * field must be dense for now, because jsopcode.c uses an OPDEF() expansion + * inside the js_CodeSpec[] initializer. + * + * Field Description + * op Bytecode name, which is the JSOp enumerator name + * value Bytecode value, which is the JSOp enumerator value + * name C string containing name for disassembler + * image C string containing "image" for pretty-printer, null if ugly + * length Number of bytes including any immediate operands + * nuses Number of stack slots consumed by bytecode, -1 if variadic + * ndefs Number of stack slots produced by bytecode + * prec Operator precedence, zero if not an operator + * format Bytecode plus immediate operand encoding format + * + * This file is best viewed with 116 columns: +01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345 + */ + +/* legend: op val name image len use def prec format */ + +/* Longstanding JavaScript bytecodes. */ +OPDEF(JSOP_NOP, 0, "nop", NULL, 1, 0, 0, 0, JOF_BYTE) +OPDEF(JSOP_PUSH, 1, "push", NULL, 1, 0, 1, 0, JOF_BYTE) +OPDEF(JSOP_POPV, 2, "popv", NULL, 1, 1, 0, 0, JOF_BYTE) +OPDEF(JSOP_ENTERWITH, 3, "enterwith", NULL, 1, 1, 1, 0, JOF_BYTE) +OPDEF(JSOP_LEAVEWITH, 4, "leavewith", NULL, 1, 1, 0, 0, JOF_BYTE) +OPDEF(JSOP_RETURN, 5, "return", NULL, 1, 1, 0, 0, JOF_BYTE) +OPDEF(JSOP_GOTO, 6, "goto", NULL, 3, 0, 0, 0, JOF_JUMP) +OPDEF(JSOP_IFEQ, 7, "ifeq", NULL, 3, 1, 0, 0, JOF_JUMP) +OPDEF(JSOP_IFNE, 8, "ifne", NULL, 3, 1, 0, 0, JOF_JUMP) + +/* Get the arguments object for the current, lightweight function activation. */ +OPDEF(JSOP_ARGUMENTS, 9, js_arguments_str, js_arguments_str, 1, 0, 1, 12, JOF_BYTE) + +/* ECMA-compliant for-in loop with argument or local variable loop control. */ +OPDEF(JSOP_FORARG, 10, "forarg", NULL, 3, 0, 1, 0, JOF_QARG|JOF_NAME|JOF_FOR) +OPDEF(JSOP_FORVAR, 11, "forvar", NULL, 3, 0, 1, 0, JOF_QVAR|JOF_NAME|JOF_FOR) + +/* More longstanding bytecodes. */ +OPDEF(JSOP_DUP, 12, "dup", NULL, 1, 1, 2, 0, JOF_BYTE) +OPDEF(JSOP_DUP2, 13, "dup2", NULL, 1, 2, 4, 0, JOF_BYTE) +OPDEF(JSOP_SETCONST, 14, "setconst", NULL, 3, 1, 1, 1, JOF_CONST|JOF_NAME|JOF_SET|JOF_ASSIGNING) +OPDEF(JSOP_BITOR, 15, "bitor", "|", 1, 2, 1, 2, JOF_BYTE|JOF_LEFTASSOC) +OPDEF(JSOP_BITXOR, 16, "bitxor", "^", 1, 2, 1, 3, JOF_BYTE|JOF_LEFTASSOC) +OPDEF(JSOP_BITAND, 17, "bitand", "&", 1, 2, 1, 4, JOF_BYTE|JOF_LEFTASSOC) +OPDEF(JSOP_EQ, 18, "eq", "==", 1, 2, 1, 5, JOF_BYTE|JOF_LEFTASSOC) +OPDEF(JSOP_NE, 19, "ne", "!=", 1, 2, 1, 5, JOF_BYTE|JOF_LEFTASSOC) +OPDEF(JSOP_LT, 20, "lt", "<", 1, 2, 1, 6, JOF_BYTE|JOF_LEFTASSOC) +OPDEF(JSOP_LE, 21, "le", "<=", 1, 2, 1, 6, JOF_BYTE|JOF_LEFTASSOC) +OPDEF(JSOP_GT, 22, "gt", ">", 1, 2, 1, 6, JOF_BYTE|JOF_LEFTASSOC) +OPDEF(JSOP_GE, 23, "ge", ">=", 1, 2, 1, 6, JOF_BYTE|JOF_LEFTASSOC) +OPDEF(JSOP_LSH, 24, "lsh", "<<", 1, 2, 1, 7, JOF_BYTE|JOF_LEFTASSOC) +OPDEF(JSOP_RSH, 25, "rsh", ">>", 1, 2, 1, 7, JOF_BYTE|JOF_LEFTASSOC) +OPDEF(JSOP_URSH, 26, "ursh", ">>>", 1, 2, 1, 7, JOF_BYTE|JOF_LEFTASSOC) +OPDEF(JSOP_ADD, 27, "add", "+", 1, 2, 1, 8, JOF_BYTE|JOF_LEFTASSOC) +OPDEF(JSOP_SUB, 28, "sub", "-", 1, 2, 1, 8, JOF_BYTE|JOF_LEFTASSOC) +OPDEF(JSOP_MUL, 29, "mul", "*", 1, 2, 1, 9, JOF_BYTE|JOF_LEFTASSOC) +OPDEF(JSOP_DIV, 30, "div", "/", 1, 2, 1, 9, JOF_BYTE|JOF_LEFTASSOC) +OPDEF(JSOP_MOD, 31, "mod", "%", 1, 2, 1, 9, JOF_BYTE|JOF_LEFTASSOC) +OPDEF(JSOP_NOT, 32, "not", "!", 1, 1, 1, 10, JOF_BYTE) +OPDEF(JSOP_BITNOT, 33, "bitnot", "~", 1, 1, 1, 10, JOF_BYTE) +OPDEF(JSOP_NEG, 34, "neg", "-", 1, 1, 1, 10, JOF_BYTE) +OPDEF(JSOP_NEW, 35, js_new_str, NULL, 3, -1, 1, 10, JOF_UINT16) +OPDEF(JSOP_DELNAME, 36, "delname", NULL, 3, 0, 1, 10, JOF_CONST|JOF_NAME|JOF_DEL) +OPDEF(JSOP_DELPROP, 37, "delprop", NULL, 3, 1, 1, 10, JOF_CONST|JOF_PROP|JOF_DEL) +OPDEF(JSOP_DELELEM, 38, "delelem", NULL, 1, 2, 1, 10, JOF_BYTE |JOF_ELEM|JOF_DEL) +OPDEF(JSOP_TYPEOF, 39, js_typeof_str,NULL, 1, 1, 1, 10, JOF_BYTE) +OPDEF(JSOP_VOID, 40, js_void_str, NULL, 1, 1, 1, 10, JOF_BYTE) +OPDEF(JSOP_INCNAME, 41, "incname", NULL, 3, 0, 1, 10, JOF_CONST|JOF_NAME|JOF_INC) +OPDEF(JSOP_INCPROP, 42, "incprop", NULL, 3, 1, 1, 10, JOF_CONST|JOF_PROP|JOF_INC) +OPDEF(JSOP_INCELEM, 43, "incelem", NULL, 1, 2, 1, 10, JOF_BYTE |JOF_ELEM|JOF_INC) +OPDEF(JSOP_DECNAME, 44, "decname", NULL, 3, 0, 1, 10, JOF_CONST|JOF_NAME|JOF_DEC) +OPDEF(JSOP_DECPROP, 45, "decprop", NULL, 3, 1, 1, 10, JOF_CONST|JOF_PROP|JOF_DEC) +OPDEF(JSOP_DECELEM, 46, "decelem", NULL, 1, 2, 1, 10, JOF_BYTE |JOF_ELEM|JOF_DEC) +OPDEF(JSOP_NAMEINC, 47, "nameinc", NULL, 3, 0, 1, 10, JOF_CONST|JOF_NAME|JOF_INC|JOF_POST) +OPDEF(JSOP_PROPINC, 48, "propinc", NULL, 3, 1, 1, 10, JOF_CONST|JOF_PROP|JOF_INC|JOF_POST) +OPDEF(JSOP_ELEMINC, 49, "eleminc", NULL, 1, 2, 1, 10, JOF_BYTE |JOF_ELEM|JOF_INC|JOF_POST) +OPDEF(JSOP_NAMEDEC, 50, "namedec", NULL, 3, 0, 1, 10, JOF_CONST|JOF_NAME|JOF_DEC|JOF_POST) +OPDEF(JSOP_PROPDEC, 51, "propdec", NULL, 3, 1, 1, 10, JOF_CONST|JOF_PROP|JOF_DEC|JOF_POST) +OPDEF(JSOP_ELEMDEC, 52, "elemdec", NULL, 1, 2, 1, 10, JOF_BYTE |JOF_ELEM|JOF_DEC|JOF_POST) +OPDEF(JSOP_GETPROP, 53, "getprop", NULL, 3, 1, 1, 11, JOF_CONST|JOF_PROP) +OPDEF(JSOP_SETPROP, 54, "setprop", NULL, 3, 2, 1, 1, JOF_CONST|JOF_PROP|JOF_SET|JOF_ASSIGNING) +OPDEF(JSOP_GETELEM, 55, "getelem", NULL, 1, 2, 1, 11, JOF_BYTE |JOF_ELEM|JOF_LEFTASSOC) +OPDEF(JSOP_SETELEM, 56, "setelem", NULL, 1, 3, 1, 1, JOF_BYTE |JOF_ELEM|JOF_SET|JOF_ASSIGNING) +OPDEF(JSOP_PUSHOBJ, 57, "pushobj", NULL, 1, 0, 1, 0, JOF_BYTE) +OPDEF(JSOP_CALL, 58, "call", NULL, 3, -1, 1, 11, JOF_UINT16) +OPDEF(JSOP_NAME, 59, "name", NULL, 3, 0, 1, 12, JOF_CONST|JOF_NAME) +OPDEF(JSOP_NUMBER, 60, "number", NULL, 3, 0, 1, 12, JOF_CONST) +OPDEF(JSOP_STRING, 61, "string", NULL, 3, 0, 1, 12, JOF_CONST) +OPDEF(JSOP_ZERO, 62, "zero", "0", 1, 0, 1, 12, JOF_BYTE) +OPDEF(JSOP_ONE, 63, "one", "1", 1, 0, 1, 12, JOF_BYTE) +OPDEF(JSOP_NULL, 64, js_null_str, js_null_str, 1, 0, 1, 12, JOF_BYTE) +OPDEF(JSOP_THIS, 65, js_this_str, js_this_str, 1, 0, 1, 12, JOF_BYTE) +OPDEF(JSOP_FALSE, 66, js_false_str, js_false_str, 1, 0, 1, 12, JOF_BYTE) +OPDEF(JSOP_TRUE, 67, js_true_str, js_true_str, 1, 0, 1, 12, JOF_BYTE) +OPDEF(JSOP_OR, 68, "or", NULL, 3, 1, 0, 0, JOF_JUMP) +OPDEF(JSOP_AND, 69, "and", NULL, 3, 1, 0, 0, JOF_JUMP) + +/* The switch bytecodes have variable length. */ +OPDEF(JSOP_TABLESWITCH, 70, "tableswitch", NULL, -1, 1, 0, 0, JOF_TABLESWITCH) +OPDEF(JSOP_LOOKUPSWITCH, 71, "lookupswitch", NULL, -1, 1, 0, 0, JOF_LOOKUPSWITCH) + +/* New, infallible/transitive identity ops. */ +OPDEF(JSOP_NEW_EQ, 72, "eq", NULL, 1, 2, 1, 5, JOF_BYTE) +OPDEF(JSOP_NEW_NE, 73, "ne", NULL, 1, 2, 1, 5, JOF_BYTE) + +/* Lexical closure constructor. */ +OPDEF(JSOP_CLOSURE, 74, "closure", NULL, 3, 0, 0, 0, JOF_CONST) + +/* Export and import ops. */ +OPDEF(JSOP_EXPORTALL, 75, "exportall", NULL, 1, 0, 0, 0, JOF_BYTE) +OPDEF(JSOP_EXPORTNAME,76, "exportname", NULL, 3, 0, 0, 0, JOF_CONST|JOF_NAME) +OPDEF(JSOP_IMPORTALL, 77, "importall", NULL, 1, 1, 0, 0, JOF_BYTE) +OPDEF(JSOP_IMPORTPROP,78, "importprop", NULL, 3, 1, 0, 0, JOF_CONST|JOF_PROP|JOF_IMPORT) +OPDEF(JSOP_IMPORTELEM,79, "importelem", NULL, 1, 2, 0, 0, JOF_BYTE |JOF_ELEM|JOF_IMPORT) + +/* Push object literal. */ +OPDEF(JSOP_OBJECT, 80, "object", NULL, 3, 0, 1, 12, JOF_CONST) + +/* Pop value and discard it. */ +OPDEF(JSOP_POP, 81, "pop", NULL, 1, 1, 0, 0, JOF_BYTE) + +/* Convert value to number, for unary +. */ +OPDEF(JSOP_POS, 82, "pos", "+", 1, 1, 1, 10, JOF_BYTE) + +/* Trap into debugger for breakpoint, etc. */ +OPDEF(JSOP_TRAP, 83, "trap", NULL, 1, 0, 0, 0, JOF_BYTE) + +/* Fast get/set ops for function arguments and local variables. */ +OPDEF(JSOP_GETARG, 84, "getarg", NULL, 3, 0, 1, 12, JOF_QARG |JOF_NAME) +OPDEF(JSOP_SETARG, 85, "setarg", NULL, 3, 1, 1, 1, JOF_QARG |JOF_NAME|JOF_SET|JOF_ASSIGNING) +OPDEF(JSOP_GETVAR, 86, "getvar", NULL, 3, 0, 1, 12, JOF_QVAR |JOF_NAME) +OPDEF(JSOP_SETVAR, 87, "setvar", NULL, 3, 1, 1, 1, JOF_QVAR |JOF_NAME|JOF_SET|JOF_ASSIGNING) + +/* Push unsigned 16-bit int constant. */ +OPDEF(JSOP_UINT16, 88, "uint16", NULL, 3, 0, 1, 12, JOF_UINT16) + +/* Object and array literal support. */ +OPDEF(JSOP_NEWINIT, 89, "newinit", NULL, 1, 2, 1, 10, JOF_BYTE) +OPDEF(JSOP_ENDINIT, 90, "endinit", NULL, 1, 0, 0, 0, JOF_BYTE) +OPDEF(JSOP_INITPROP, 91, "initprop", NULL, 3, 1, 0, 0, JOF_CONST|JOF_PROP) +OPDEF(JSOP_INITELEM, 92, "initelem", NULL, 1, 2, 0, 0, JOF_BYTE |JOF_ELEM) +OPDEF(JSOP_DEFSHARP, 93, "defsharp", NULL, 3, 0, 0, 0, JOF_UINT16) +OPDEF(JSOP_USESHARP, 94, "usesharp", NULL, 3, 0, 1, 0, JOF_UINT16) + +/* Fast inc/dec ops for args and local vars. */ +OPDEF(JSOP_INCARG, 95, "incarg", NULL, 3, 0, 1, 10, JOF_QARG |JOF_NAME|JOF_INC) +OPDEF(JSOP_INCVAR, 96, "incvar", NULL, 3, 0, 1, 10, JOF_QVAR |JOF_NAME|JOF_INC) +OPDEF(JSOP_DECARG, 97, "decarg", NULL, 3, 0, 1, 10, JOF_QARG |JOF_NAME|JOF_DEC) +OPDEF(JSOP_DECVAR, 98, "decvar", NULL, 3, 0, 1, 10, JOF_QVAR |JOF_NAME|JOF_DEC) +OPDEF(JSOP_ARGINC, 99, "arginc", NULL, 3, 0, 1, 10, JOF_QARG |JOF_NAME|JOF_INC|JOF_POST) +OPDEF(JSOP_VARINC, 100,"varinc", NULL, 3, 0, 1, 10, JOF_QVAR |JOF_NAME|JOF_INC|JOF_POST) +OPDEF(JSOP_ARGDEC, 101,"argdec", NULL, 3, 0, 1, 10, JOF_QARG |JOF_NAME|JOF_DEC|JOF_POST) +OPDEF(JSOP_VARDEC, 102,"vardec", NULL, 3, 0, 1, 10, JOF_QVAR |JOF_NAME|JOF_DEC|JOF_POST) + +/* ECMA-compliant for/in ops. */ +OPDEF(JSOP_TOOBJECT, 103,"toobject", NULL, 1, 1, 1, 0, JOF_BYTE) +OPDEF(JSOP_FORNAME, 104,"forname", NULL, 3, 0, 1, 0, JOF_CONST|JOF_NAME|JOF_FOR) +OPDEF(JSOP_FORPROP, 105,"forprop", NULL, 3, 1, 1, 0, JOF_CONST|JOF_PROP|JOF_FOR) +OPDEF(JSOP_FORELEM, 106,"forelem", NULL, 1, 2, 4, 0, JOF_BYTE |JOF_ELEM|JOF_FOR) +OPDEF(JSOP_POP2, 107,"pop2", NULL, 1, 2, 0, 0, JOF_BYTE) + +/* ECMA-compliant assignment ops. */ +OPDEF(JSOP_BINDNAME, 108,"bindname", NULL, 3, 0, 1, 0, JOF_CONST|JOF_NAME|JOF_SET|JOF_ASSIGNING) +OPDEF(JSOP_SETNAME, 109,"setname", NULL, 3, 2, 1, 1, JOF_CONST|JOF_NAME|JOF_SET|JOF_ASSIGNING) + +/* Exception handling ops. */ +OPDEF(JSOP_THROW, 110,"throw", NULL, 1, 1, 0, 0, JOF_BYTE) + +/* 'in' and 'instanceof' ops. */ +OPDEF(JSOP_IN, 111,js_in_str, js_in_str, 1, 2, 1, 6, JOF_BYTE|JOF_LEFTASSOC) +OPDEF(JSOP_INSTANCEOF,112,js_instanceof_str,js_instanceof_str,1,2,1,6,JOF_BYTE|JOF_LEFTASSOC) + +/* debugger op */ +OPDEF(JSOP_DEBUGGER, 113,"debugger", NULL, 1, 0, 0, 0, JOF_BYTE) + +/* gosub/retsub for finally handling */ +OPDEF(JSOP_GOSUB, 114,"gosub", NULL, 3, 0, 1, 0, JOF_JUMP) +OPDEF(JSOP_RETSUB, 115,"retsub", NULL, 1, 1, 0, 0, JOF_BYTE) + +/* More exception handling ops. */ +OPDEF(JSOP_EXCEPTION, 116,"exception", NULL, 1, 0, 1, 0, JOF_BYTE) +OPDEF(JSOP_SETSP, 117,"setsp", NULL, 3, 0, 0, 0, JOF_UINT16) + +/* + * ECMA-compliant switch statement ops. + * CONDSWITCH is a decompilable NOP; CASE is ===, POP, jump if true, re-push + * lval if false; and DEFAULT is POP lval and GOTO. + */ +OPDEF(JSOP_CONDSWITCH,118,"condswitch", NULL, 1, 0, 0, 0, JOF_BYTE) +OPDEF(JSOP_CASE, 119,"case", NULL, 3, 1, 0, 0, JOF_JUMP) +OPDEF(JSOP_DEFAULT, 120,"default", NULL, 3, 1, 0, 0, JOF_JUMP) + +/* + * ECMA-compliant call to eval op + */ +OPDEF(JSOP_EVAL, 121,"eval", NULL, 3, -1, 1, 11, JOF_UINT16) + +/* + * ECMA-compliant helper for 'for (x[i] in o)' loops. + */ +OPDEF(JSOP_ENUMELEM, 122,"enumelem", NULL, 1, 3, 0, 1, JOF_BYTE |JOF_SET|JOF_ASSIGNING) + +/* + * Getter and setter prefix bytecodes. These modify the next bytecode, either + * an assignment or a property initializer code, which then defines a property + * getter or setter. + */ +OPDEF(JSOP_GETTER, 123,js_getter_str,js_getter_str,1, 0, 0, 0, JOF_BYTE) +OPDEF(JSOP_SETTER, 124,js_setter_str,js_setter_str,1, 0, 0, 0, JOF_BYTE) + +/* + * Prolog bytecodes for defining function, var, and const names. + */ +OPDEF(JSOP_DEFFUN, 125,"deffun", NULL, 3, 0, 0, 0, JOF_CONST) +OPDEF(JSOP_DEFCONST, 126,"defconst", NULL, 3, 0, 0, 0, JOF_CONST|JOF_NAME) +OPDEF(JSOP_DEFVAR, 127,"defvar", NULL, 3, 0, 0, 0, JOF_CONST|JOF_NAME) + +/* Auto-clone (if needed due to re-parenting) and push an anonymous function. */ +OPDEF(JSOP_ANONFUNOBJ, 128, "anonfunobj", NULL, 3, 0, 1, 12, JOF_CONST) + +/* ECMA ed. 3 named function expression. */ +OPDEF(JSOP_NAMEDFUNOBJ, 129, "namedfunobj", NULL, 3, 0, 1, 12, JOF_CONST) + +/* Like JSOP_INITPROP, but specialized to make a DontDelete property for ECMA ed. 3 catch variables. */ +OPDEF(JSOP_INITCATCHVAR,130, "initcatchvar",NULL, 3, 1, 0, 0, JOF_CONST|JOF_PROP) + +/* ECMA-mandated parenthesization opcode, which nulls the reference base register, obj; see jsinterp.c. */ +OPDEF(JSOP_GROUP, 131, "group", NULL, 1, 0, 0, 0, JOF_BYTE) + +/* Host object extension: given 'o.item(i) = j', the left-hand side compiles JSOP_SETCALL, rather than JSOP_CALL. */ +OPDEF(JSOP_SETCALL, 132, "setcall", NULL, 3, -1, 2, 11, JOF_UINT16|JOF_SET|JOF_ASSIGNING) + +/* + * Exception handling no-ops, for more economical byte-coding than SRC_TRYFIN + * srcnote-annotated JSOP_NOPs. + */ +OPDEF(JSOP_TRY, 133,"try", NULL, 1, 0, 0, 0, JOF_BYTE) +OPDEF(JSOP_FINALLY, 134,"finally", NULL, 1, 0, 0, 0, JOF_BYTE) + +/* + * Swap the top two stack elements. + * N.B. JSOP_SWAP doesn't swap the corresponding pc stack generating pcs, as + * they're not needed for the current use of preserving the top-of-stack return + * value when popping scopes while returning from catch blocks. + */ +OPDEF(JSOP_SWAP, 135,"swap", NULL, 1, 2, 2, 0, JOF_BYTE) + +/* + * Bytecodes that avoid making an arguments object in most cases: + * JSOP_ARGSUB gets arguments[i] from fp->argv, iff i is in [0, fp->argc-1]. + * JSOP_ARGCNT returns fp->argc. + */ +OPDEF(JSOP_ARGSUB, 136,"argsub", NULL, 3, 0, 1, 12, JOF_QARG |JOF_NAME) +OPDEF(JSOP_ARGCNT, 137,"argcnt", NULL, 1, 0, 1, 12, JOF_BYTE) + +/* + * Define a local function object as a local variable. + * The local variable's slot number is the first immediate two-byte operand. + * The function object's atom index is the second immediate operand. + */ +OPDEF(JSOP_DEFLOCALFUN, 138,"deflocalfun",NULL, 5, 0, 0, 0, JOF_DEFLOCALVAR) + +/* Extended jumps. */ +OPDEF(JSOP_GOTOX, 139,"gotox", NULL, 5, 0, 0, 0, JOF_JUMPX) +OPDEF(JSOP_IFEQX, 140,"ifeqx", NULL, 5, 1, 0, 0, JOF_JUMPX) +OPDEF(JSOP_IFNEX, 141,"ifnex", NULL, 5, 1, 0, 0, JOF_JUMPX) +OPDEF(JSOP_ORX, 142,"orx", NULL, 5, 1, 0, 0, JOF_JUMPX) +OPDEF(JSOP_ANDX, 143,"andx", NULL, 5, 1, 0, 0, JOF_JUMPX) +OPDEF(JSOP_GOSUBX, 144,"gosubx", NULL, 5, 0, 1, 0, JOF_JUMPX) +OPDEF(JSOP_CASEX, 145,"casex", NULL, 5, 1, 0, 0, JOF_JUMPX) +OPDEF(JSOP_DEFAULTX, 146,"defaultx", NULL, 5, 1, 0, 0, JOF_JUMPX) +OPDEF(JSOP_TABLESWITCHX, 147,"tableswitchx",NULL, -1, 1, 0, 0, JOF_TABLESWITCHX) +OPDEF(JSOP_LOOKUPSWITCHX, 148,"lookupswitchx",NULL, -1, 1, 0, 0, JOF_LOOKUPSWITCHX) + +/* Placeholders for a real jump opcode set during backpatch chain fixup. */ +OPDEF(JSOP_BACKPATCH, 149,"backpatch",NULL, 3, 0, 0, 0, JOF_JUMP|JOF_BACKPATCH) +OPDEF(JSOP_BACKPATCH_POP, 150,"backpatch_pop",NULL, 3, 1, 0, 0, JOF_JUMP|JOF_BACKPATCH) +OPDEF(JSOP_BACKPATCH_PUSH,151,"backpatch_push",NULL, 3, 0, 1, 0, JOF_JUMP|JOF_BACKPATCH) + +/* Set and get return value pseudo-register in stack frame. */ +OPDEF(JSOP_SETRVAL, 152,"setrval", NULL, 1, 1, 0, 0, JOF_BYTE) +OPDEF(JSOP_RETRVAL, 153,"retrval", NULL, 1, 0, 0, 0, JOF_BYTE) diff --git a/src/dom/js/jsosdep.h b/src/dom/js/jsosdep.h new file mode 100644 index 000000000..c93eee2f1 --- /dev/null +++ b/src/dom/js/jsosdep.h @@ -0,0 +1,127 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef jsosdep_h___ +#define jsosdep_h___ +/* + * OS (and machine, and compiler XXX) dependent information. + */ + +#if defined(XP_WIN) || defined(XP_OS2) + +#if defined(_WIN32) || defined (XP_OS2) +#define JS_HAVE_LONG_LONG +#else +#undef JS_HAVE_LONG_LONG +#endif +#endif /* XP_WIN || XP_OS2 */ + +#ifdef XP_MAC +#define JS_HAVE_LONG_LONG + +JS_BEGIN_EXTERN_C + +#include + +extern void* reallocSmaller(void* block, size_t newSize); + +extern char* strdup(const char* str); + +JS_END_EXTERN_C + +#endif /* XP_MAC */ + +#ifdef XP_BEOS +#define JS_HAVE_LONG_LONG +#endif + + +#ifdef XP_UNIX + +/* + * Get OS specific header information. + */ +#if defined(AIXV3) || defined(AIX) +#define JS_HAVE_LONG_LONG + +#elif defined(BSDI) +#define JS_HAVE_LONG_LONG + +#elif defined(HPUX) +#define JS_HAVE_LONG_LONG + +#elif defined(IRIX) +#define JS_HAVE_LONG_LONG + +#elif defined(linux) +#define JS_HAVE_LONG_LONG + +#elif defined(OSF1) +#define JS_HAVE_LONG_LONG + +#elif defined(_SCO_DS) +#undef JS_HAVE_LONG_LONG + +#elif defined(SOLARIS) +#define JS_HAVE_LONG_LONG + +#elif defined(FREEBSD) +#define JS_HAVE_LONG_LONG + +#elif defined(SUNOS4) +#undef JS_HAVE_LONG_LONG + +/* +** Missing function prototypes +*/ + +extern void *sbrk(int); + +#elif defined(UNIXWARE) +#undef JS_HAVE_LONG_LONG + +#elif defined(VMS) && defined(__ALPHA) +#define JS_HAVE_LONG_LONG + +#endif + +#endif /* XP_UNIX */ + +#endif /* jsosdep_h___ */ + diff --git a/src/dom/js/jsotypes.h b/src/dom/js/jsotypes.h new file mode 100644 index 000000000..ad8b5203e --- /dev/null +++ b/src/dom/js/jsotypes.h @@ -0,0 +1,211 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* + * This section typedefs the old 'native' types to the new PRs. + * These definitions are scheduled to be eliminated at the earliest + * possible time. The NSPR API is implemented and documented using + * the new definitions. + */ + +/* + * Note that we test for PROTYPES_H, not JSOTYPES_H. This is to avoid + * double-definitions of scalar types such as uint32, if NSPR's + * protypes.h is also included. + */ +#ifndef PROTYPES_H +#define PROTYPES_H + +#ifdef XP_BEOS +/* BeOS defines most int types in SupportDefs.h (int8, uint8, int16, + * uint16, int32, uint32, int64, uint64), so in the interest of + * not conflicting with other definitions elsewhere we have to skip the + * #ifdef jungle below, duplicate some definitions, and do our stuff. + */ +#include + +typedef JSUintn uintn; +#ifndef _XP_Core_ +typedef JSIntn intn; +#endif + +#else + +/* SVR4 typedef of uint is commonly found on UNIX machines. */ +#ifdef XP_UNIX +#include +#else +typedef JSUintn uint; +#endif + +typedef JSUintn uintn; +typedef JSUint64 uint64; +#if !defined(XP_MAC) && !defined(_WIN32) && !defined(XP_OS2) +typedef JSUint32 uint32; +#else +typedef unsigned long uint32; +#endif +typedef JSUint16 uint16; +typedef JSUint8 uint8; + +#ifndef _XP_Core_ +typedef JSIntn intn; +#endif + +/* + * On AIX 4.3, sys/inttypes.h (which is included by sys/types.h, a very + * common header file) defines the types int8, int16, int32, and int64. + * So we don't define these four types here to avoid conflicts in case + * the code also includes sys/types.h. + */ +#if defined(AIX) && defined(HAVE_SYS_INTTYPES_H) +#include +#else +typedef JSInt64 int64; + +/* /usr/include/model.h on HP-UX defines int8, int16, and int32 */ +#ifdef HPUX +#include +#else +#if !defined(XP_MAC) && !defined(_WIN32) && !defined(XP_OS2) +typedef JSInt32 int32; +#else +typedef long int32; +#endif +typedef JSInt16 int16; +typedef JSInt8 int8; +#endif /* HPUX */ +#endif /* AIX && HAVE_SYS_INTTYPES_H */ + +#endif /* XP_BEOS */ + +typedef JSFloat64 float64; + +/* Re: jsbit.h */ +#define TEST_BIT JS_TEST_BIT +#define SET_BIT JS_SET_BIT +#define CLEAR_BIT JS_CLEAR_BIT + +/* Re: prarena.h->plarena.h */ +#define PRArena PLArena +#define PRArenaPool PLArenaPool +#define PRArenaStats PLArenaStats +#define PR_ARENA_ALIGN PL_ARENA_ALIGN +#define PR_INIT_ARENA_POOL PL_INIT_ARENA_POOL +#define PR_ARENA_ALLOCATE PL_ARENA_ALLOCATE +#define PR_ARENA_GROW PL_ARENA_GROW +#define PR_ARENA_MARK PL_ARENA_MARK +#define PR_CLEAR_UNUSED PL_CLEAR_UNUSED +#define PR_CLEAR_ARENA PL_CLEAR_ARENA +#define PR_ARENA_RELEASE PL_ARENA_RELEASE +#define PR_COUNT_ARENA PL_COUNT_ARENA +#define PR_ARENA_DESTROY PL_ARENA_DESTROY +#define PR_InitArenaPool PL_InitArenaPool +#define PR_FreeArenaPool PL_FreeArenaPool +#define PR_FinishArenaPool PL_FinishArenaPool +#define PR_CompactArenaPool PL_CompactArenaPool +#define PR_ArenaFinish PL_ArenaFinish +#define PR_ArenaAllocate PL_ArenaAllocate +#define PR_ArenaGrow PL_ArenaGrow +#define PR_ArenaRelease PL_ArenaRelease +#define PR_ArenaCountAllocation PL_ArenaCountAllocation +#define PR_ArenaCountInplaceGrowth PL_ArenaCountInplaceGrowth +#define PR_ArenaCountGrowth PL_ArenaCountGrowth +#define PR_ArenaCountRelease PL_ArenaCountRelease +#define PR_ArenaCountRetract PL_ArenaCountRetract + +/* Re: prevent.h->plevent.h */ +#define PREvent PLEvent +#define PREventQueue PLEventQueue +#define PR_CreateEventQueue PL_CreateEventQueue +#define PR_DestroyEventQueue PL_DestroyEventQueue +#define PR_GetEventQueueMonitor PL_GetEventQueueMonitor +#define PR_ENTER_EVENT_QUEUE_MONITOR PL_ENTER_EVENT_QUEUE_MONITOR +#define PR_EXIT_EVENT_QUEUE_MONITOR PL_EXIT_EVENT_QUEUE_MONITOR +#define PR_PostEvent PL_PostEvent +#define PR_PostSynchronousEvent PL_PostSynchronousEvent +#define PR_GetEvent PL_GetEvent +#define PR_EventAvailable PL_EventAvailable +#define PREventFunProc PLEventFunProc +#define PR_MapEvents PL_MapEvents +#define PR_RevokeEvents PL_RevokeEvents +#define PR_ProcessPendingEvents PL_ProcessPendingEvents +#define PR_WaitForEvent PL_WaitForEvent +#define PR_EventLoop PL_EventLoop +#define PR_GetEventQueueSelectFD PL_GetEventQueueSelectFD +#define PRHandleEventProc PLHandleEventProc +#define PRDestroyEventProc PLDestroyEventProc +#define PR_InitEvent PL_InitEvent +#define PR_GetEventOwner PL_GetEventOwner +#define PR_HandleEvent PL_HandleEvent +#define PR_DestroyEvent PL_DestroyEvent +#define PR_DequeueEvent PL_DequeueEvent +#define PR_GetMainEventQueue PL_GetMainEventQueue + +/* Re: prhash.h->plhash.h */ +#define PRHashEntry PLHashEntry +#define PRHashTable PLHashTable +#define PRHashNumber PLHashNumber +#define PRHashFunction PLHashFunction +#define PRHashComparator PLHashComparator +#define PRHashEnumerator PLHashEnumerator +#define PRHashAllocOps PLHashAllocOps +#define PR_NewHashTable PL_NewHashTable +#define PR_HashTableDestroy PL_HashTableDestroy +#define PR_HashTableRawLookup PL_HashTableRawLookup +#define PR_HashTableRawAdd PL_HashTableRawAdd +#define PR_HashTableRawRemove PL_HashTableRawRemove +#define PR_HashTableAdd PL_HashTableAdd +#define PR_HashTableRemove PL_HashTableRemove +#define PR_HashTableEnumerateEntries PL_HashTableEnumerateEntries +#define PR_HashTableLookup PL_HashTableLookup +#define PR_HashTableDump PL_HashTableDump +#define PR_HashString PL_HashString +#define PR_CompareStrings PL_CompareStrings +#define PR_CompareValues PL_CompareValues + +#ifdef XP_MAC +#ifndef TRUE /* Mac standard is lower case true */ + #define TRUE 1 +#endif +#ifndef FALSE /* Mac standard is lower case false */ + #define FALSE 0 +#endif +#endif + +#endif /* !defined(PROTYPES_H) */ diff --git a/src/dom/js/jsparse.c b/src/dom/js/jsparse.c new file mode 100644 index 000000000..7cf18d454 --- /dev/null +++ b/src/dom/js/jsparse.c @@ -0,0 +1,3547 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* + * JS parser. + * + * This is a recursive-descent parser for the JavaScript language specified by + * "The JavaScript 1.5 Language Specification". It uses lexical and semantic + * feedback to disambiguate non-LL(1) structures. It generates trees of nodes + * induced by the recursive parsing (not precise syntax trees, see jsparse.h). + * After tree construction, it rewrites trees to fold constants and evaluate + * compile-time expressions. Finally, it calls js_EmitTree (see jsemit.h) to + * generate bytecode. + * + * This parser attempts no error recovery. The dense JSTokenType enumeration + * was designed with error recovery built on 64-bit first and follow bitsets + * in mind, however. + */ +#include "jsstddef.h" +#include +#include +#include +#include "jstypes.h" +#include "jsarena.h" /* Added by JSIFY */ +#include "jsutil.h" /* Added by JSIFY */ +#include "jsapi.h" +#include "jsatom.h" +#include "jscntxt.h" +#include "jsconfig.h" +#include "jsemit.h" +#include "jsfun.h" +#include "jsinterp.h" +#include "jslock.h" +#include "jsnum.h" +#include "jsobj.h" +#include "jsopcode.h" +#include "jsparse.h" +#include "jsscan.h" +#include "jsscope.h" +#include "jsscript.h" +#include "jsstr.h" + +/* + * JS parsers, from lowest to highest precedence. + * + * Each parser takes a context and a token stream, and emits bytecode using + * a code generator. + */ + +typedef JSParseNode * +JSParser(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc); + +typedef JSParseNode * +JSMemberParser(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc, + JSBool allowCallSyntax); + +static JSParser FunctionStmt; +#if JS_HAS_LEXICAL_CLOSURE +static JSParser FunctionExpr; +#endif +static JSParser Statements; +static JSParser Statement; +static JSParser Variables; +static JSParser Expr; +static JSParser AssignExpr; +static JSParser CondExpr; +static JSParser OrExpr; +static JSParser AndExpr; +static JSParser BitOrExpr; +static JSParser BitXorExpr; +static JSParser BitAndExpr; +static JSParser EqExpr; +static JSParser RelExpr; +static JSParser ShiftExpr; +static JSParser AddExpr; +static JSParser MulExpr; +static JSParser UnaryExpr; +static JSMemberParser MemberExpr; +static JSParser PrimaryExpr; + +/* + * Insist that the next token be of type tt, or report errno and return null. + * NB: this macro uses cx and ts from its lexical environment. + */ +#define MUST_MATCH_TOKEN(tt, errno) \ + JS_BEGIN_MACRO \ + if (js_GetToken(cx, ts) != tt) { \ + js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR, errno); \ + return NULL; \ + } \ + JS_END_MACRO + +#define CHECK_RECURSION() \ + JS_BEGIN_MACRO \ + int stackDummy; \ + if (!JS_CHECK_STACK_SIZE(cx, stackDummy)) { \ + js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR, \ + JSMSG_OVER_RECURSED); \ + return NULL; \ + } \ + JS_END_MACRO + +#ifdef METER_PARSENODES +static uint32 parsenodes = 0; +static uint32 maxparsenodes = 0; +static uint32 recyclednodes = 0; +#endif + +static void +RecycleTree(JSParseNode *pn, JSTreeContext *tc) +{ + if (!pn) + return; + JS_ASSERT(pn != tc->nodeList); /* catch back-to-back dup recycles */ + pn->pn_next = tc->nodeList; + tc->nodeList = pn; +#ifdef METER_PARSENODES + recyclednodes++; +#endif +} + +static JSParseNode * +NewOrRecycledNode(JSContext *cx, JSTreeContext *tc) +{ + JSParseNode *pn; + + pn = tc->nodeList; + if (!pn) { + JS_ARENA_ALLOCATE_TYPE(pn, JSParseNode, &cx->tempPool); + if (!pn) + JS_ReportOutOfMemory(cx); + } else { + tc->nodeList = pn->pn_next; + + /* Recycle immediate descendents only, to save work and working set. */ + switch (pn->pn_arity) { + case PN_FUNC: + RecycleTree(pn->pn_body, tc); + break; + case PN_LIST: + if (pn->pn_head) { + /* XXX check for dup recycles in the list */ + *pn->pn_tail = tc->nodeList; + tc->nodeList = pn->pn_head; +#ifdef METER_PARSENODES + recyclednodes += pn->pn_count; +#endif + } + break; + case PN_TERNARY: + RecycleTree(pn->pn_kid1, tc); + RecycleTree(pn->pn_kid2, tc); + RecycleTree(pn->pn_kid3, tc); + break; + case PN_BINARY: + RecycleTree(pn->pn_left, tc); + RecycleTree(pn->pn_right, tc); + break; + case PN_UNARY: + RecycleTree(pn->pn_kid, tc); + break; + case PN_NAME: + RecycleTree(pn->pn_expr, tc); + break; + case PN_NULLARY: + break; + } + } + return pn; +} + +/* + * Allocate a JSParseNode from cx's temporary arena. + */ +static JSParseNode * +NewParseNode(JSContext *cx, JSToken *tok, JSParseNodeArity arity, + JSTreeContext *tc) +{ + JSParseNode *pn; + + pn = NewOrRecycledNode(cx, tc); + if (!pn) + return NULL; + pn->pn_type = tok->type; + pn->pn_pos = tok->pos; + pn->pn_op = JSOP_NOP; + pn->pn_arity = arity; + pn->pn_next = NULL; +#ifdef METER_PARSENODES + parsenodes++; + if (parsenodes - recyclednodes > maxparsenodes) + maxparsenodes = parsenodes - recyclednodes; +#endif + return pn; +} + +static JSParseNode * +NewBinary(JSContext *cx, JSTokenType tt, + JSOp op, JSParseNode *left, JSParseNode *right, + JSTreeContext *tc) +{ + JSParseNode *pn, *pn1, *pn2; + + if (!left || !right) + return NULL; + + /* + * Flatten a left-associative (left-heavy) tree of a given operator into + * a list, to reduce js_FoldConstants and js_EmitTree recursion. + */ + if (left->pn_type == tt && + left->pn_op == op && + (js_CodeSpec[op].format & JOF_LEFTASSOC)) { + if (left->pn_arity != PN_LIST) { + pn1 = left->pn_left, pn2 = left->pn_right; + left->pn_arity = PN_LIST; + PN_INIT_LIST_1(left, pn1); + PN_APPEND(left, pn2); + left->pn_extra = 0; + if (tt == TOK_PLUS) { + if (pn1->pn_type == TOK_STRING) + left->pn_extra |= PNX_STRCAT; + else if (pn1->pn_type != TOK_NUMBER) + left->pn_extra |= PNX_CANTFOLD; + if (pn2->pn_type == TOK_STRING) + left->pn_extra |= PNX_STRCAT; + else if (pn2->pn_type != TOK_NUMBER) + left->pn_extra |= PNX_CANTFOLD; + } + } + PN_APPEND(left, right); + left->pn_pos.end = right->pn_pos.end; + if (tt == TOK_PLUS) { + if (right->pn_type == TOK_STRING) + left->pn_extra |= PNX_STRCAT; + else if (right->pn_type != TOK_NUMBER) + left->pn_extra |= PNX_CANTFOLD; + } + return left; + } + + /* + * Fold constant addition immediately, to conserve node space and, what's + * more, so js_FoldConstants never sees mixed addition and concatenation + * operations with more than one leading non-string operand in a PN_LIST + * generated for expressions such as 1 + 2 + "pt" (which should evaluate + * to "3pt", not "12pt"). + */ + if (tt == TOK_PLUS && + left->pn_type == TOK_NUMBER && + right->pn_type == TOK_NUMBER) { + left->pn_dval += right->pn_dval; + RecycleTree(right, tc); + return left; + } + + pn = NewOrRecycledNode(cx, tc); + if (!pn) + return NULL; + pn->pn_type = tt; + pn->pn_pos.begin = left->pn_pos.begin; + pn->pn_pos.end = right->pn_pos.end; + pn->pn_op = op; + pn->pn_arity = PN_BINARY; + pn->pn_left = left; + pn->pn_right = right; + pn->pn_next = NULL; +#ifdef METER_PARSENODES + parsenodes++; + if (parsenodes - recyclednodes > maxparsenodes) + maxparsenodes = parsenodes - recyclednodes; +#endif + return pn; +} + +#if JS_HAS_GETTER_SETTER +static JSTokenType +CheckGetterOrSetter(JSContext *cx, JSTokenStream *ts, JSTokenType tt) +{ + JSAtom *atom; + JSRuntime *rt; + JSOp op; + const char *name; + + JS_ASSERT(CURRENT_TOKEN(ts).type == TOK_NAME); + atom = CURRENT_TOKEN(ts).t_atom; + rt = cx->runtime; + if (atom == rt->atomState.getterAtom) + op = JSOP_GETTER; + else if (atom == rt->atomState.setterAtom) + op = JSOP_SETTER; + else + return TOK_NAME; + if (js_PeekTokenSameLine(cx, ts) != tt) + return TOK_NAME; + (void) js_GetToken(cx, ts); + if (CURRENT_TOKEN(ts).t_op != JSOP_NOP) { + js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR, + JSMSG_BAD_GETTER_OR_SETTER, + (op == JSOP_GETTER) + ? js_getter_str + : js_setter_str); + return TOK_ERROR; + } + CURRENT_TOKEN(ts).t_op = op; + name = js_AtomToPrintableString(cx, atom); + if (!name || + !js_ReportCompileErrorNumber(cx, ts, NULL, + JSREPORT_WARNING | + JSREPORT_STRICT, + JSMSG_DEPRECATED_USAGE, + name)) { + return TOK_ERROR; + } + return tt; +} +#endif + +/* + * Parse a top-level JS script. + */ +JS_FRIEND_API(JSParseNode *) +js_ParseTokenStream(JSContext *cx, JSObject *chain, JSTokenStream *ts) +{ + JSStackFrame *fp, frame; + JSTreeContext tc; + JSParseNode *pn; + + /* + * Push a compiler frame if we have no frames, or if the top frame is a + * lightweight function activation, or if its scope chain doesn't match + * the one passed to us. + */ + fp = cx->fp; + if (!fp || !fp->varobj || fp->scopeChain != chain) { + memset(&frame, 0, sizeof frame); + frame.varobj = frame.scopeChain = chain; + if (cx->options & JSOPTION_VAROBJFIX) { + while ((chain = JS_GetParent(cx, chain)) != NULL) + frame.varobj = chain; + } + frame.down = fp; + cx->fp = &frame; + } + + /* + * Protect atoms from being collected by a GC activation, which might + * - nest on this thread due to out of memory (the so-called "last ditch" + * GC attempted within js_AllocGCThing), or + * - run for any reason on another thread if this thread is suspended on + * an object lock before it finishes generating bytecode into a script + * protected from the GC by a root or a stack frame reference. + */ + JS_KEEP_ATOMS(cx->runtime); + TREE_CONTEXT_INIT(&tc); + pn = Statements(cx, ts, &tc); + if (pn) { + if (!js_MatchToken(cx, ts, TOK_EOF)) { + js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR, + JSMSG_SYNTAX_ERROR); + pn = NULL; + } else { + pn->pn_type = TOK_LC; + if (!js_FoldConstants(cx, pn, &tc)) + pn = NULL; + } + } + + TREE_CONTEXT_FINISH(&tc); + JS_UNKEEP_ATOMS(cx->runtime); + cx->fp = fp; + return pn; +} + +/* + * Compile a top-level script. + */ +JS_FRIEND_API(JSBool) +js_CompileTokenStream(JSContext *cx, JSObject *chain, JSTokenStream *ts, + JSCodeGenerator *cg) +{ + JSStackFrame *fp, frame; + JSParseNode *pn; + JSBool ok; +#ifdef METER_PARSENODES + void *sbrk(ptrdiff_t), *before = sbrk(0); +#endif + + /* + * Push a compiler frame if we have no frames, or if the top frame is a + * lightweight function activation, or if its scope chain doesn't match + * the one passed to us. + */ + fp = cx->fp; + if (!fp || !fp->varobj || fp->scopeChain != chain) { + memset(&frame, 0, sizeof frame); + frame.varobj = frame.scopeChain = chain; + if (cx->options & JSOPTION_VAROBJFIX) { + while ((chain = JS_GetParent(cx, chain)) != NULL) + frame.varobj = chain; + } + frame.down = fp; + cx->fp = &frame; + } + + /* Prevent GC activation while compiling. */ + JS_KEEP_ATOMS(cx->runtime); + + pn = Statements(cx, ts, &cg->treeContext); + if (!pn) { + ok = JS_FALSE; + } else if (!js_MatchToken(cx, ts, TOK_EOF)) { + js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR, + JSMSG_SYNTAX_ERROR); + ok = JS_FALSE; + } else { +#ifdef METER_PARSENODES + printf("Parser growth: %d (%u nodes, %u max, %u unrecycled)\n", + (char *)sbrk(0) - (char *)before, + parsenodes, + maxparsenodes, + parsenodes - recyclednodes); + before = sbrk(0); +#endif + + /* + * No need to emit code here -- Statements already has, for each + * statement in turn. Search for TCF_COMPILING in Statements, below. + * That flag is set for every tc == &cg->treeContext, and it implies + * that the tc can be downcast to a cg and used to emit code during + * parsing, rather than at the end of the parse phase. + */ + JS_ASSERT(cg->treeContext.flags & TCF_COMPILING); + ok = JS_TRUE; + } + +#ifdef METER_PARSENODES + printf("Code-gen growth: %d (%u bytecodes, %u srcnotes)\n", + (char *)sbrk(0) - (char *)before, CG_OFFSET(cg), cg->noteCount); +#endif +#ifdef JS_ARENAMETER + JS_DumpArenaStats(stdout); +#endif + JS_UNKEEP_ATOMS(cx->runtime); + cx->fp = fp; + return ok; +} + +/* + * Insist on a final return before control flows out of pn, but don't be too + * smart about loops (do {...; return e2;} while(0) at the end of a function + * that contains an early return e1 will get a strict-option-only warning). + */ +static JSBool +HasFinalReturn(JSParseNode *pn) +{ + JSBool ok, hasDefault; + JSParseNode *pn2, *pn3; + + switch (pn->pn_type) { + case TOK_LC: + if (!pn->pn_head) + return JS_FALSE; + return HasFinalReturn(PN_LAST(pn)); + + case TOK_IF: + ok = HasFinalReturn(pn->pn_kid2); + ok &= pn->pn_kid3 && HasFinalReturn(pn->pn_kid3); + return ok; + +#if JS_HAS_SWITCH_STATEMENT + case TOK_SWITCH: + ok = JS_TRUE; + hasDefault = JS_FALSE; + for (pn2 = pn->pn_kid2->pn_head; ok && pn2; pn2 = pn2->pn_next) { + if (pn2->pn_type == TOK_DEFAULT) + hasDefault = JS_TRUE; + pn3 = pn2->pn_right; + JS_ASSERT(pn3->pn_type == TOK_LC); + if (pn3->pn_head) + ok &= HasFinalReturn(PN_LAST(pn3)); + } + /* If a final switch has no default case, we judge it harshly. */ + ok &= hasDefault; + return ok; +#endif /* JS_HAS_SWITCH_STATEMENT */ + + case TOK_WITH: + return HasFinalReturn(pn->pn_right); + + case TOK_RETURN: + return JS_TRUE; + +#if JS_HAS_EXCEPTIONS + case TOK_THROW: + return JS_TRUE; + + case TOK_TRY: + /* If we have a finally block that returns, we are done. */ + if (pn->pn_kid3 && HasFinalReturn(pn->pn_kid3)) + return JS_TRUE; + + /* Else check the try block and any and all catch statements. */ + ok = HasFinalReturn(pn->pn_kid1); + if (pn->pn_kid2) + ok &= HasFinalReturn(pn->pn_kid2); + return ok; + + case TOK_CATCH: + /* Check this block's code and iterate over further catch blocks. */ + ok = HasFinalReturn(pn->pn_kid3); + for (pn2 = pn->pn_kid2; pn2; pn2 = pn2->pn_kid2) + ok &= HasFinalReturn(pn2->pn_kid3); + return ok; +#endif + + default: + return JS_FALSE; + } +} + +static JSBool +ReportNoReturnValue(JSContext *cx, JSTokenStream *ts) +{ + JSFunction *fun; + JSBool ok; + + fun = cx->fp->fun; + if (fun->atom) { + char *name = js_GetStringBytes(ATOM_TO_STRING(fun->atom)); + ok = js_ReportCompileErrorNumber(cx, ts, NULL, + JSREPORT_WARNING | + JSREPORT_STRICT, + JSMSG_NO_RETURN_VALUE, name); + } else { + ok = js_ReportCompileErrorNumber(cx, ts, NULL, + JSREPORT_WARNING | + JSREPORT_STRICT, + JSMSG_ANON_NO_RETURN_VALUE); + } + return ok; +} + +static JSBool +CheckFinalReturn(JSContext *cx, JSTokenStream *ts, JSParseNode *pn) +{ + return HasFinalReturn(pn) || ReportNoReturnValue(cx, ts); +} + +static JSParseNode * +FunctionBody(JSContext *cx, JSTokenStream *ts, JSFunction *fun, + JSTreeContext *tc) +{ + JSStackFrame *fp, frame; + JSObject *funobj; + uintN oldflags; + JSParseNode *pn; + + fp = cx->fp; + funobj = fun->object; + if (!fp || fp->fun != fun || fp->varobj != funobj || + fp->scopeChain != funobj) { + memset(&frame, 0, sizeof frame); + frame.fun = fun; + frame.varobj = frame.scopeChain = funobj; + frame.down = fp; + cx->fp = &frame; + } + + oldflags = tc->flags; + tc->flags &= ~(TCF_RETURN_EXPR | TCF_RETURN_VOID); + tc->flags |= TCF_IN_FUNCTION; + pn = Statements(cx, ts, tc); + + /* Check for falling off the end of a function that returns a value. */ + if (pn && JS_HAS_STRICT_OPTION(cx) && (tc->flags & TCF_RETURN_EXPR)) { + if (!CheckFinalReturn(cx, ts, pn)) + pn = NULL; + } + + cx->fp = fp; + tc->flags = oldflags | (tc->flags & TCF_FUN_FLAGS); + return pn; +} + +/* + * Compile a JS function body, which might appear as the value of an event + * handler attribute in an HTML tag. + */ +JSBool +js_CompileFunctionBody(JSContext *cx, JSTokenStream *ts, JSFunction *fun) +{ + JSArenaPool codePool, notePool; + JSCodeGenerator funcg; + JSStackFrame *fp, frame; + JSObject *funobj; + JSParseNode *pn; + JSBool ok; + + JS_InitArenaPool(&codePool, "code", 1024, sizeof(jsbytecode)); + JS_InitArenaPool(¬ePool, "note", 1024, sizeof(jssrcnote)); + if (!js_InitCodeGenerator(cx, &funcg, &codePool, ¬ePool, + ts->filename, ts->lineno, + ts->principals)) { + return JS_FALSE; + } + + /* Prevent GC activation while compiling. */ + JS_KEEP_ATOMS(cx->runtime); + + /* Push a JSStackFrame for use by FunctionBody and js_EmitFunctionBody. */ + fp = cx->fp; + funobj = fun->object; + JS_ASSERT(!fp || fp->fun != fun || fp->varobj != funobj || + fp->scopeChain != funobj); + memset(&frame, 0, sizeof frame); + frame.fun = fun; + frame.varobj = frame.scopeChain = funobj; + frame.down = fp; + cx->fp = &frame; + + /* Ensure that the body looks like a block statement to js_EmitTree. */ + CURRENT_TOKEN(ts).type = TOK_LC; + pn = FunctionBody(cx, ts, fun, &funcg.treeContext); + if (!pn) { + ok = JS_FALSE; + } else { + /* + * No need to emit code here -- Statements (via FunctionBody) already + * has. See similar comment in js_CompileTokenStream, and bug 108257. + */ + fun->script = js_NewScriptFromCG(cx, &funcg, fun); + if (!fun->script) { + ok = JS_FALSE; + } else { + if (funcg.treeContext.flags & TCF_FUN_HEAVYWEIGHT) + fun->flags |= JSFUN_HEAVYWEIGHT; + ok = JS_TRUE; + } + } + + /* Restore saved state and release code generation arenas. */ + cx->fp = fp; + JS_UNKEEP_ATOMS(cx->runtime); + js_FinishCodeGenerator(cx, &funcg); + JS_FinishArenaPool(&codePool); + JS_FinishArenaPool(¬ePool); + return ok; +} + +static JSParseNode * +FunctionDef(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc, + JSBool lambda) +{ + JSParseNode *pn, *body; + JSOp op, prevop; + JSAtom *funAtom, *argAtom; + JSFunction *fun; + JSObject *parent; + JSObject *pobj; + JSScopeProperty *sprop; + uintN dupflag; + JSBool ok; + JSTreeContext funtc; + JSAtomListElement *ale; + + /* Make a TOK_FUNCTION node. */ + pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_FUNC, tc); + if (!pn) + return NULL; +#if JS_HAS_GETTER_SETTER + op = CURRENT_TOKEN(ts).t_op; +#endif + + /* Scan the optional function name into funAtom. */ + if (js_MatchToken(cx, ts, TOK_NAME)) + funAtom = CURRENT_TOKEN(ts).t_atom; + else + funAtom = NULL; + + /* Find the nearest variable-declaring scope and use it as our parent. */ + parent = cx->fp->varobj; + fun = js_NewFunction(cx, NULL, NULL, 0, lambda ? JSFUN_LAMBDA : 0, parent, + funAtom); + if (!fun) + return NULL; + +#if JS_HAS_GETTER_SETTER + if (op != JSOP_NOP) + fun->flags |= (op == JSOP_GETTER) ? JSPROP_GETTER : JSPROP_SETTER; +#endif + + /* Now parse formal argument list and compute fun->nargs. */ + MUST_MATCH_TOKEN(TOK_LP, JSMSG_PAREN_BEFORE_FORMAL); + if (!js_MatchToken(cx, ts, TOK_RP)) { + do { + MUST_MATCH_TOKEN(TOK_NAME, JSMSG_MISSING_FORMAL); + argAtom = CURRENT_TOKEN(ts).t_atom; + pobj = NULL; + if (!js_LookupProperty(cx, fun->object, (jsid)argAtom, &pobj, + (JSProperty **)&sprop)) { + return NULL; + } + dupflag = 0; + if (sprop) { + ok = JS_TRUE; + if (pobj == fun->object && + sprop->getter == js_GetArgument) { + const char *name = js_AtomToPrintableString(cx, argAtom); + + /* + * A duplicate parameter name. We force a duplicate node + * on the SCOPE_LAST_PROP(scope) list with the same id, + * distinguished by the SPROP_IS_DUPLICATE flag, and not + * mapped by an entry in scope. + */ + ok = name && + js_ReportCompileErrorNumber(cx, ts, NULL, + JSREPORT_WARNING | + JSREPORT_STRICT, + JSMSG_DUPLICATE_FORMAL, + name); + + dupflag = SPROP_IS_DUPLICATE; + } + OBJ_DROP_PROPERTY(cx, pobj, (JSProperty *)sprop); + if (!ok) + return NULL; + sprop = NULL; + } + if (!js_AddNativeProperty(cx, fun->object, (jsid)argAtom, + js_GetArgument, js_SetArgument, + SPROP_INVALID_SLOT, + JSPROP_ENUMERATE | JSPROP_PERMANENT | + JSPROP_SHARED, + SPROP_HAS_SHORTID | dupflag, + fun->nargs)) { + return NULL; + } + fun->nargs++; + } while (js_MatchToken(cx, ts, TOK_COMMA)); + + MUST_MATCH_TOKEN(TOK_RP, JSMSG_PAREN_AFTER_FORMAL); + } + + MUST_MATCH_TOKEN(TOK_LC, JSMSG_CURLY_BEFORE_BODY); + pn->pn_pos.begin = CURRENT_TOKEN(ts).pos.begin; + + TREE_CONTEXT_INIT(&funtc); + body = FunctionBody(cx, ts, fun, &funtc); + if (!body) + return NULL; + + MUST_MATCH_TOKEN(TOK_RC, JSMSG_CURLY_AFTER_BODY); + pn->pn_pos.end = CURRENT_TOKEN(ts).pos.end; + +#if JS_HAS_LEXICAL_CLOSURE + /* + * If we collected flags that indicate nested heavyweight functions, or + * this function contains heavyweight-making statements (references to + * __parent__ or __proto__; use of with, eval, import, or export; and + * assignment to arguments), flag the function as heavyweight (requiring + * a call object per invocation). + */ + if (funtc.flags & TCF_FUN_HEAVYWEIGHT) { + fun->flags |= JSFUN_HEAVYWEIGHT; + tc->flags |= TCF_FUN_HEAVYWEIGHT; + } else { + /* + * If this function is a named statement function not at top-level + * (i.e. a JSOP_CLOSURE), or if it refers to unqualified names that + * are not local args or vars (TCF_FUN_USES_NONLOCALS), then our + * enclosing function, if any, must be heavyweight. + */ + if ((!lambda && funAtom && tc->topStmt) || + (funtc.flags & TCF_FUN_USES_NONLOCALS)) { + tc->flags |= TCF_FUN_HEAVYWEIGHT; + } + } +#endif + + /* + * Record names for function statements in tc->decls so we know when to + * avoid optimizing variable references that might name a function. + */ + if (!lambda && funAtom) { + ATOM_LIST_SEARCH(ale, &tc->decls, funAtom); + if (ale) { + prevop = ALE_JSOP(ale); + if (JS_HAS_STRICT_OPTION(cx) || prevop == JSOP_DEFCONST) { + const char *name = js_AtomToPrintableString(cx, funAtom); + if (!name || + !js_ReportCompileErrorNumber(cx, ts, NULL, + (prevop != JSOP_DEFCONST) + ? JSREPORT_WARNING | + JSREPORT_STRICT + : JSREPORT_ERROR, + JSMSG_REDECLARED_VAR, + (prevop == JSOP_DEFFUN || + prevop == JSOP_CLOSURE) + ? js_function_str + : (prevop == JSOP_DEFCONST) + ? js_const_str + : js_var_str, + name)) { + return NULL; + } + } + if (tc->topStmt && prevop == JSOP_DEFVAR) + tc->flags |= TCF_FUN_CLOSURE_VS_VAR; + } else { + ale = js_IndexAtom(cx, funAtom, &tc->decls); + if (!ale) + return NULL; + } + ALE_SET_JSOP(ale, tc->topStmt ? JSOP_CLOSURE : JSOP_DEFFUN); + +#if JS_HAS_LEXICAL_CLOSURE + /* + * A function nested at top level inside another's body needs only a + * local variable to bind its name to its value, and not an activation + * object property (it might also need the activation property, if the + * outer function contains with statements, e.g., but the stack slot + * wins when jsemit.c's LookupArgOrVar can optimize a JSOP_NAME into a + * JSOP_GETVAR bytecode). + */ + if (!tc->topStmt && (tc->flags & TCF_IN_FUNCTION)) { + JSStackFrame *fp; + JSObject *varobj; + + /* + * Define a property on the outer function so that LookupArgOrVar + * can properly optimize accesses. + * + * XXX Here and in Variables, we use the function object's scope, + * XXX arguably polluting it, when we could use a compiler-private + * XXX scope structure. Tradition! + */ + fp = cx->fp; + varobj = fp->varobj; + JS_ASSERT(OBJ_GET_CLASS(cx, varobj) == &js_FunctionClass); + JS_ASSERT(fp->fun == (JSFunction *) JS_GetPrivate(cx, varobj)); + if (!js_DefineNativeProperty(cx, varobj, (jsid)funAtom, + OBJECT_TO_JSVAL(fun->object), + js_GetLocalVariable, + js_SetLocalVariable, + JSPROP_ENUMERATE, + SPROP_HAS_SHORTID, fp->fun->nvars, + NULL)) { + return NULL; + } + fp->fun->nvars++; + } +#endif + } + +#if JS_HAS_LEXICAL_CLOSURE + if (lambda || !funAtom) { + /* + * ECMA ed. 3 standard: function expression, possibly anonymous (even + * if at top-level, an unnamed function is an expression statement, not + * a function declaration). + */ + op = fun->atom ? JSOP_NAMEDFUNOBJ : JSOP_ANONFUNOBJ; + } else if (tc->topStmt) { + /* + * ECMA ed. 3 extension: a function expression statement not at the + * top level, e.g., in a compound statement such as the "then" part + * of an "if" statement, binds a closure only if control reaches that + * sub-statement. + */ + op = JSOP_CLOSURE; + } else +#endif + op = JSOP_NOP; + + /* + * Pending a better automatic GC root management scheme (see Mozilla bug + * 40757, http://bugzilla.mozilla.org/show_bug.cgi?id=40757), we need to + * atomize here to protect against a GC activation. + */ + pn->pn_funAtom = js_AtomizeObject(cx, fun->object, 0); + if (!pn->pn_funAtom) + return NULL; + + pn->pn_op = op; + pn->pn_body = body; + pn->pn_flags = funtc.flags & TCF_FUN_FLAGS; + pn->pn_tryCount = funtc.tryCount; + TREE_CONTEXT_FINISH(&funtc); + return pn; +} + +static JSParseNode * +FunctionStmt(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc) +{ + return FunctionDef(cx, ts, tc, JS_FALSE); +} + +#if JS_HAS_LEXICAL_CLOSURE +static JSParseNode * +FunctionExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc) +{ + return FunctionDef(cx, ts, tc, JS_TRUE); +} +#endif + +/* + * Parse the statements in a block, creating a TOK_LC node that lists the + * statements' trees. If called from block-parsing code, the caller must + * match { before and } after. + */ +static JSParseNode * +Statements(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc) +{ + JSParseNode *pn, *pn2; + JSTokenType tt; + + CHECK_RECURSION(); + + pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_LIST, tc); + if (!pn) + return NULL; + PN_INIT_LIST(pn); + + ts->flags |= TSF_REGEXP; + while ((tt = js_PeekToken(cx, ts)) > TOK_EOF && tt != TOK_RC) { + ts->flags &= ~TSF_REGEXP; + pn2 = Statement(cx, ts, tc); + if (!pn2) + return NULL; + ts->flags |= TSF_REGEXP; + + /* If compiling top-level statements, emit as we go to save space. */ + if (!tc->topStmt && (tc->flags & TCF_COMPILING)) { + if (cx->fp->fun && + JS_HAS_STRICT_OPTION(cx) && + (tc->flags & TCF_RETURN_EXPR)) { + /* + * Check pn2 for lack of a final return statement if it is the + * last statement in the block. + */ + tt = js_PeekToken(cx, ts); + if ((tt == TOK_EOF || tt == TOK_RC) && + !CheckFinalReturn(cx, ts, pn2)) { + tt = TOK_ERROR; + break; + } + + /* + * Clear TCF_RETURN_EXPR so FunctionBody doesn't try to + * CheckFinalReturn again. + */ + tc->flags &= ~TCF_RETURN_EXPR; + } + if (!js_FoldConstants(cx, pn2, tc) || + !js_AllocTryNotes(cx, (JSCodeGenerator *)tc) || + !js_EmitTree(cx, (JSCodeGenerator *)tc, pn2)) { + tt = TOK_ERROR; + break; + } + RecycleTree(pn2, tc); + } else { + PN_APPEND(pn, pn2); + } + } + ts->flags &= ~TSF_REGEXP; + if (tt == TOK_ERROR) + return NULL; + + pn->pn_pos.end = CURRENT_TOKEN(ts).pos.end; + return pn; +} + +static JSParseNode * +Condition(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc) +{ + JSParseNode *pn, *pn2; + + MUST_MATCH_TOKEN(TOK_LP, JSMSG_PAREN_BEFORE_COND); + pn = Expr(cx, ts, tc); + if (!pn) + return NULL; + MUST_MATCH_TOKEN(TOK_RP, JSMSG_PAREN_AFTER_COND); + + /* + * Check for (a = b) and "correct" it to (a == b) iff b's operator has + * greater precedence than ==. + * XXX not ECMA, but documented in several books -- now a strict warning. + */ + if (pn->pn_type == TOK_ASSIGN && + pn->pn_op == JSOP_NOP && + pn->pn_right->pn_type > TOK_EQOP) + { + JSBool rewrite = !JSVERSION_IS_ECMA(cx->version); + if (!js_ReportCompileErrorNumber(cx, ts, NULL, + JSREPORT_WARNING | JSREPORT_STRICT, + JSMSG_EQUAL_AS_ASSIGN, + rewrite + ? "\nAssuming equality test" + : "")) { + return NULL; + } + if (rewrite) { + pn->pn_type = TOK_EQOP; + pn->pn_op = (JSOp)cx->jsop_eq; + pn2 = pn->pn_left; + switch (pn2->pn_op) { + case JSOP_SETNAME: + pn2->pn_op = JSOP_NAME; + break; + case JSOP_SETPROP: + pn2->pn_op = JSOP_GETPROP; + break; + case JSOP_SETELEM: + pn2->pn_op = JSOP_GETELEM; + break; + default: + JS_ASSERT(0); + } + } + } + return pn; +} + +static JSBool +MatchLabel(JSContext *cx, JSTokenStream *ts, JSParseNode *pn) +{ + JSAtom *label; +#if JS_HAS_LABEL_STATEMENT + JSTokenType tt; + + tt = js_PeekTokenSameLine(cx, ts); + if (tt == TOK_ERROR) + return JS_FALSE; + if (tt == TOK_NAME) { + (void) js_GetToken(cx, ts); + label = CURRENT_TOKEN(ts).t_atom; + } else { + label = NULL; + } +#else + label = NULL; +#endif + pn->pn_atom = label; + return JS_TRUE; +} + +#if JS_HAS_EXPORT_IMPORT +static JSParseNode * +ImportExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc) +{ + JSParseNode *pn, *pn2, *pn3; + JSTokenType tt; + + MUST_MATCH_TOKEN(TOK_NAME, JSMSG_NO_IMPORT_NAME); + pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_NAME, tc); + if (!pn) + return NULL; + pn->pn_op = JSOP_NAME; + pn->pn_atom = CURRENT_TOKEN(ts).t_atom; + pn->pn_expr = NULL; + pn->pn_slot = -1; + pn->pn_attrs = 0; + + ts->flags |= TSF_REGEXP; + while ((tt = js_GetToken(cx, ts)) == TOK_DOT || tt == TOK_LB) { + ts->flags &= ~TSF_REGEXP; + if (pn->pn_op == JSOP_IMPORTALL) + goto bad_import; + + if (tt == TOK_DOT) { + pn2 = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_NAME, tc); + if (!pn2) + return NULL; + if (js_MatchToken(cx, ts, TOK_STAR)) { + pn2->pn_op = JSOP_IMPORTALL; + pn2->pn_atom = NULL; + } else { + MUST_MATCH_TOKEN(TOK_NAME, JSMSG_NAME_AFTER_DOT); + pn2->pn_op = JSOP_GETPROP; + pn2->pn_atom = CURRENT_TOKEN(ts).t_atom; + pn2->pn_slot = -1; + pn2->pn_attrs = 0; + } + pn2->pn_expr = pn; + pn2->pn_pos.begin = pn->pn_pos.begin; + pn2->pn_pos.end = CURRENT_TOKEN(ts).pos.end; + } else { + /* Make a TOK_LB node. */ + pn2 = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_BINARY, tc); + if (!pn2) + return NULL; + pn3 = Expr(cx, ts, tc); + if (!pn3) + return NULL; + + MUST_MATCH_TOKEN(TOK_RB, JSMSG_BRACKET_IN_INDEX); + pn2->pn_pos.begin = pn->pn_pos.begin; + pn2->pn_pos.end = CURRENT_TOKEN(ts).pos.end; + + pn2->pn_op = JSOP_GETELEM; + pn2->pn_left = pn; + pn2->pn_right = pn3; + } + + pn = pn2; + ts->flags |= TSF_REGEXP; + } + ts->flags &= ~TSF_REGEXP; + if (tt == TOK_ERROR) + return NULL; + js_UngetToken(ts); + + switch (pn->pn_op) { + case JSOP_GETPROP: + pn->pn_op = JSOP_IMPORTPROP; + break; + case JSOP_GETELEM: + pn->pn_op = JSOP_IMPORTELEM; + break; + case JSOP_IMPORTALL: + break; + default: + goto bad_import; + } + return pn; + + bad_import: + js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR, JSMSG_BAD_IMPORT); + return NULL; +} +#endif /* JS_HAS_EXPORT_IMPORT */ + +extern const char js_with_statement_str[]; + +static JSParseNode * +Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc) +{ + JSTokenType tt; + JSParseNode *pn, *pn1, *pn2, *pn3, *pn4; + JSStmtInfo stmtInfo, *stmt, *stmt2; + JSAtom *label; + + ts->flags |= TSF_REGEXP; + tt = js_GetToken(cx, ts); + ts->flags &= ~TSF_REGEXP; + +#if JS_HAS_GETTER_SETTER + if (tt == TOK_NAME) { + tt = CheckGetterOrSetter(cx, ts, TOK_FUNCTION); + if (tt == TOK_ERROR) + return NULL; + } +#endif + + switch (tt) { +#if JS_HAS_EXPORT_IMPORT + case TOK_EXPORT: + pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_LIST, tc); + if (!pn) + return NULL; + PN_INIT_LIST(pn); + if (js_MatchToken(cx, ts, TOK_STAR)) { + pn2 = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_NULLARY, tc); + if (!pn2) + return NULL; + PN_APPEND(pn, pn2); + } else { + do { + MUST_MATCH_TOKEN(TOK_NAME, JSMSG_NO_EXPORT_NAME); + pn2 = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_NAME, tc); + if (!pn2) + return NULL; + pn2->pn_op = JSOP_NAME; + pn2->pn_atom = CURRENT_TOKEN(ts).t_atom; + pn2->pn_expr = NULL; + pn2->pn_slot = -1; + pn2->pn_attrs = 0; + PN_APPEND(pn, pn2); + } while (js_MatchToken(cx, ts, TOK_COMMA)); + } + pn->pn_pos.end = PN_LAST(pn)->pn_pos.end; + tc->flags |= TCF_FUN_HEAVYWEIGHT; + break; + + case TOK_IMPORT: + pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_LIST, tc); + if (!pn) + return NULL; + PN_INIT_LIST(pn); + do { + pn2 = ImportExpr(cx, ts, tc); + if (!pn2) + return NULL; + PN_APPEND(pn, pn2); + } while (js_MatchToken(cx, ts, TOK_COMMA)); + pn->pn_pos.end = PN_LAST(pn)->pn_pos.end; + tc->flags |= TCF_FUN_HEAVYWEIGHT; + break; +#endif /* JS_HAS_EXPORT_IMPORT */ + + case TOK_FUNCTION: + return FunctionStmt(cx, ts, tc); + + case TOK_IF: + /* An IF node has three kids: condition, then, and optional else. */ + pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_TERNARY, tc); + if (!pn) + return NULL; + pn1 = Condition(cx, ts, tc); + if (!pn1) + return NULL; + js_PushStatement(tc, &stmtInfo, STMT_IF, -1); + pn2 = Statement(cx, ts, tc); + if (!pn2) + return NULL; + if (js_MatchToken(cx, ts, TOK_ELSE)) { + stmtInfo.type = STMT_ELSE; + pn3 = Statement(cx, ts, tc); + if (!pn3) + return NULL; + pn->pn_pos.end = pn3->pn_pos.end; + } else { + pn3 = NULL; + pn->pn_pos.end = pn2->pn_pos.end; + } + js_PopStatement(tc); + pn->pn_kid1 = pn1; + pn->pn_kid2 = pn2; + pn->pn_kid3 = pn3; + return pn; + +#if JS_HAS_SWITCH_STATEMENT + case TOK_SWITCH: + { + JSParseNode *pn5; + JSBool seenDefault = JS_FALSE; + + pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_BINARY, tc); + if (!pn) + return NULL; + MUST_MATCH_TOKEN(TOK_LP, JSMSG_PAREN_BEFORE_SWITCH); + + /* pn1 points to the switch's discriminant. */ + pn1 = Expr(cx, ts, tc); + if (!pn1) + return NULL; + + MUST_MATCH_TOKEN(TOK_RP, JSMSG_PAREN_AFTER_SWITCH); + MUST_MATCH_TOKEN(TOK_LC, JSMSG_CURLY_BEFORE_SWITCH); + + /* pn2 is a list of case nodes. The default case has pn_left == NULL */ + pn2 = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_LIST, tc); + if (!pn2) + return NULL; + PN_INIT_LIST(pn2); + + js_PushStatement(tc, &stmtInfo, STMT_SWITCH, -1); + + while ((tt = js_GetToken(cx, ts)) != TOK_RC) { + switch (tt) { + case TOK_DEFAULT: + if (seenDefault) { + js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR, + JSMSG_TOO_MANY_DEFAULTS); + return NULL; + } + seenDefault = JS_TRUE; + /* fall through */ + + case TOK_CASE: + pn3 = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_BINARY, tc); + if (!pn3) + return NULL; + if (tt == TOK_DEFAULT) { + pn3->pn_left = NULL; + } else { + pn3->pn_left = Expr(cx, ts, tc); + if (!pn3->pn_left) + return NULL; + } + PN_APPEND(pn2, pn3); + if (pn2->pn_count == JS_BIT(16)) { + js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR, + JSMSG_TOO_MANY_CASES); + return NULL; + } + break; + + case TOK_ERROR: + return NULL; + + default: + js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR, + JSMSG_BAD_SWITCH); + return NULL; + } + MUST_MATCH_TOKEN(TOK_COLON, JSMSG_COLON_AFTER_CASE); + + pn4 = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_LIST, tc); + if (!pn4) + return NULL; + pn4->pn_type = TOK_LC; + PN_INIT_LIST(pn4); + while ((tt = js_PeekToken(cx, ts)) != TOK_RC && + tt != TOK_CASE && tt != TOK_DEFAULT) { + if (tt == TOK_ERROR) + return NULL; + pn5 = Statement(cx, ts, tc); + if (!pn5) + return NULL; + pn4->pn_pos.end = pn5->pn_pos.end; + PN_APPEND(pn4, pn5); + } + + /* Fix the PN_LIST so it doesn't begin at the TOK_COLON. */ + if (pn4->pn_head) + pn4->pn_pos.begin = pn4->pn_head->pn_pos.begin; + pn3->pn_pos.end = pn4->pn_pos.end; + pn3->pn_right = pn4; + } + + js_PopStatement(tc); + + pn->pn_pos.end = pn2->pn_pos.end = CURRENT_TOKEN(ts).pos.end; + pn->pn_kid1 = pn1; + pn->pn_kid2 = pn2; + return pn; + } +#endif /* JS_HAS_SWITCH_STATEMENT */ + + case TOK_WHILE: + pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_BINARY, tc); + if (!pn) + return NULL; + js_PushStatement(tc, &stmtInfo, STMT_WHILE_LOOP, -1); + pn2 = Condition(cx, ts, tc); + if (!pn2) + return NULL; + pn->pn_left = pn2; + pn2 = Statement(cx, ts, tc); + if (!pn2) + return NULL; + js_PopStatement(tc); + pn->pn_pos.end = pn2->pn_pos.end; + pn->pn_right = pn2; + return pn; + +#if JS_HAS_DO_WHILE_LOOP + case TOK_DO: + pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_BINARY, tc); + if (!pn) + return NULL; + js_PushStatement(tc, &stmtInfo, STMT_DO_LOOP, -1); + pn2 = Statement(cx, ts, tc); + if (!pn2) + return NULL; + pn->pn_left = pn2; + MUST_MATCH_TOKEN(TOK_WHILE, JSMSG_WHILE_AFTER_DO); + pn2 = Condition(cx, ts, tc); + if (!pn2) + return NULL; + js_PopStatement(tc); + pn->pn_pos.end = pn2->pn_pos.end; + pn->pn_right = pn2; + break; +#endif /* JS_HAS_DO_WHILE_LOOP */ + + case TOK_FOR: + /* A FOR node is binary, left is loop control and right is the body. */ + pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_BINARY, tc); + if (!pn) + return NULL; + js_PushStatement(tc, &stmtInfo, STMT_FOR_LOOP, -1); + + MUST_MATCH_TOKEN(TOK_LP, JSMSG_PAREN_AFTER_FOR); + tt = js_PeekToken(cx, ts); + if (tt == TOK_SEMI) { + /* No initializer -- set first kid of left sub-node to null. */ + pn1 = NULL; + } else { + /* Set pn1 to a var list or an initializing expression. */ +#if JS_HAS_IN_OPERATOR + /* + * Set the TCF_IN_FOR_INIT flag during parsing of the first clause + * of the for statement. This flag will be used by the RelExpr + * production; if it is set, then the 'in' keyword will not be + * recognized as an operator, leaving it available to be parsed as + * part of a for/in loop. A side effect of this restriction is + * that (unparenthesized) expressions involving an 'in' operator + * are illegal in the init clause of an ordinary for loop. + */ + tc->flags |= TCF_IN_FOR_INIT; +#endif /* JS_HAS_IN_OPERATOR */ + if (tt == TOK_VAR) { + (void) js_GetToken(cx, ts); + pn1 = Variables(cx, ts, tc); + } else { + pn1 = Expr(cx, ts, tc); + } +#if JS_HAS_IN_OPERATOR + tc->flags &= ~TCF_IN_FOR_INIT; +#endif /* JS_HAS_IN_OPERATOR */ + if (!pn1) + return NULL; + } + + /* + * We can be sure that it's a for/in loop if there's still an 'in' + * keyword here, even if JavaScript recognizes 'in' as an operator, + * as we've excluded 'in' from being parsed in RelExpr by setting + * the TCF_IN_FOR_INIT flag in our JSTreeContext. + */ + if (pn1 && js_MatchToken(cx, ts, TOK_IN)) { + stmtInfo.type = STMT_FOR_IN_LOOP; + + /* Check that the left side of the 'in' is valid. */ + if ((pn1->pn_type == TOK_VAR) + ? (pn1->pn_count > 1 || pn1->pn_op == JSOP_DEFCONST) + : (pn1->pn_type != TOK_NAME && + pn1->pn_type != TOK_DOT && + pn1->pn_type != TOK_LB)) { + js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR, + JSMSG_BAD_FOR_LEFTSIDE); + return NULL; + } + + if (pn1->pn_type == TOK_VAR) { + /* Tell js_EmitTree(TOK_VAR) to generate a final POP. */ + pn1->pn_extra = JS_TRUE; + pn2 = pn1->pn_head; + } else { + pn2 = pn1; + } + + /* Beware 'for (arguments in ...)' with or without a 'var'. */ + if (pn2->pn_type == TOK_NAME && + pn2->pn_atom == cx->runtime->atomState.argumentsAtom) { + tc->flags |= TCF_FUN_HEAVYWEIGHT; + } + + /* Parse the object expression as the right operand of 'in'. */ + pn2 = NewBinary(cx, TOK_IN, JSOP_NOP, pn1, Expr(cx, ts, tc), tc); + if (!pn2) + return NULL; + pn->pn_left = pn2; + } else { + /* Parse the loop condition or null into pn2. */ + MUST_MATCH_TOKEN(TOK_SEMI, JSMSG_SEMI_AFTER_FOR_INIT); + if (js_PeekToken(cx, ts) == TOK_SEMI) { + pn2 = NULL; + } else { + pn2 = Expr(cx, ts, tc); + if (!pn2) + return NULL; + } + + /* Parse the update expression or null into pn3. */ + MUST_MATCH_TOKEN(TOK_SEMI, JSMSG_SEMI_AFTER_FOR_COND); + if (js_PeekToken(cx, ts) == TOK_RP) { + pn3 = NULL; + } else { + pn3 = Expr(cx, ts, tc); + if (!pn3) + return NULL; + } + + /* Build the RESERVED node to use as the left kid of pn. */ + pn4 = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_TERNARY, tc); + if (!pn4) + return NULL; + pn4->pn_type = TOK_RESERVED; + pn4->pn_op = JSOP_NOP; + pn4->pn_kid1 = pn1; + pn4->pn_kid2 = pn2; + pn4->pn_kid3 = pn3; + pn->pn_left = pn4; + } + + MUST_MATCH_TOKEN(TOK_RP, JSMSG_PAREN_AFTER_FOR_CTRL); + + /* Parse the loop body into pn->pn_right. */ + pn2 = Statement(cx, ts, tc); + if (!pn2) + return NULL; + pn->pn_right = pn2; + js_PopStatement(tc); + + /* Record the absolute line number for source note emission. */ + pn->pn_pos.end = pn2->pn_pos.end; + return pn; + +#if JS_HAS_EXCEPTIONS + case TOK_TRY: { + JSParseNode *catchtail = NULL; + /* + * try nodes are ternary. + * kid1 is the try Statement + * kid2 is the catch node + * kid3 is the finally Statement + * + * catch nodes are ternary. + * kid1 is the discriminant + * kid2 is the next catch node, or NULL + * kid3 is the catch block (on kid3 so that we can always append a + * new catch pn on catchtail->kid2) + * + * catch discriminant nodes are binary + * atom is the receptacle + * expr is the discriminant code + * + * finally nodes are unary (just the finally expression) + */ + pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_TERNARY, tc); + pn->pn_op = JSOP_NOP; + + MUST_MATCH_TOKEN(TOK_LC, JSMSG_CURLY_BEFORE_TRY); + js_PushStatement(tc, &stmtInfo, STMT_TRY, -1); + pn->pn_kid1 = Statements(cx, ts, tc); + if (!pn->pn_kid1) + return NULL; + MUST_MATCH_TOKEN(TOK_RC, JSMSG_CURLY_AFTER_TRY); + js_PopStatement(tc); + + catchtail = pn; + while (js_PeekToken(cx, ts) == TOK_CATCH) { + /* check for another catch after unconditional catch */ + if (catchtail != pn && !catchtail->pn_kid1->pn_expr) { + js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR, + JSMSG_CATCH_AFTER_GENERAL); + return NULL; + } + + /* + * legal catch forms are: + * catch (v) + * catch (v if ) + * (the latter is legal only #ifdef JS_HAS_CATCH_GUARD) + */ + (void) js_GetToken(cx, ts); /* eat `catch' */ + pn2 = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_TERNARY, tc); + if (!pn2) + return NULL; + + /* + * We use a PN_NAME for the discriminant (catchguard) node + * with the actual discriminant code in the initializer spot + */ + MUST_MATCH_TOKEN(TOK_LP, JSMSG_PAREN_BEFORE_CATCH); + MUST_MATCH_TOKEN(TOK_NAME, JSMSG_CATCH_IDENTIFIER); + pn3 = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_NAME, tc); + if (!pn3) + return NULL; + + pn3->pn_atom = CURRENT_TOKEN(ts).t_atom; + pn3->pn_expr = NULL; +#if JS_HAS_CATCH_GUARD + /* + * We use `catch (x if x === 5)' (not `catch (x : x === 5)') to + * avoid conflicting with the JS2/ECMA2 proposed catchguard syntax. + */ + if (js_PeekToken(cx, ts) == TOK_IF) { + (void)js_GetToken(cx, ts); /* eat `if' */ + pn3->pn_expr = Expr(cx, ts, tc); + if (!pn3->pn_expr) + return NULL; + } +#endif + pn2->pn_kid1 = pn3; + + MUST_MATCH_TOKEN(TOK_RP, JSMSG_PAREN_AFTER_CATCH); + + MUST_MATCH_TOKEN(TOK_LC, JSMSG_CURLY_BEFORE_CATCH); + js_PushStatement(tc, &stmtInfo, STMT_CATCH, -1); + stmtInfo.label = pn3->pn_atom; + pn2->pn_kid3 = Statements(cx, ts, tc); + if (!pn2->pn_kid3) + return NULL; + MUST_MATCH_TOKEN(TOK_RC, JSMSG_CURLY_AFTER_CATCH); + js_PopStatement(tc); + + catchtail = catchtail->pn_kid2 = pn2; + } + catchtail->pn_kid2 = NULL; + + if (js_MatchToken(cx, ts, TOK_FINALLY)) { + tc->tryCount++; + MUST_MATCH_TOKEN(TOK_LC, JSMSG_CURLY_BEFORE_FINALLY); + js_PushStatement(tc, &stmtInfo, STMT_FINALLY, -1); + pn->pn_kid3 = Statements(cx, ts, tc); + if (!pn->pn_kid3) + return NULL; + MUST_MATCH_TOKEN(TOK_RC, JSMSG_CURLY_AFTER_FINALLY); + js_PopStatement(tc); + } else { + pn->pn_kid3 = NULL; + } + if (!pn->pn_kid2 && !pn->pn_kid3) { + js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR, + JSMSG_CATCH_OR_FINALLY); + return NULL; + } + tc->tryCount++; + return pn; + } + + case TOK_THROW: + pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_UNARY, tc); + if (!pn) + return NULL; + pn2 = Expr(cx, ts, tc); + if (!pn2) + return NULL; + pn->pn_pos.end = pn2->pn_pos.end; + pn->pn_op = JSOP_THROW; + pn->pn_kid = pn2; + break; + + /* TOK_CATCH and TOK_FINALLY are both handled in the TOK_TRY case */ + case TOK_CATCH: + js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR, + JSMSG_CATCH_WITHOUT_TRY); + return NULL; + + case TOK_FINALLY: + js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR, + JSMSG_FINALLY_WITHOUT_TRY); + return NULL; + +#endif /* JS_HAS_EXCEPTIONS */ + + case TOK_BREAK: + pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_NULLARY, tc); + if (!pn) + return NULL; + if (!MatchLabel(cx, ts, pn)) + return NULL; + stmt = tc->topStmt; + label = pn->pn_atom; + if (label) { + for (; ; stmt = stmt->down) { + if (!stmt) { + js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR, + JSMSG_LABEL_NOT_FOUND); + return NULL; + } + if (stmt->type == STMT_LABEL && stmt->label == label) + break; + } + } else { + for (; ; stmt = stmt->down) { + if (!stmt) { + js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR, + JSMSG_TOUGH_BREAK); + return NULL; + } + if (STMT_IS_LOOP(stmt) || stmt->type == STMT_SWITCH) + break; + } + } + if (label) + pn->pn_pos.end = CURRENT_TOKEN(ts).pos.end; + break; + + case TOK_CONTINUE: + pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_NULLARY, tc); + if (!pn) + return NULL; + if (!MatchLabel(cx, ts, pn)) + return NULL; + stmt = tc->topStmt; + label = pn->pn_atom; + if (label) { + for (stmt2 = NULL; ; stmt = stmt->down) { + if (!stmt) { + js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR, + JSMSG_LABEL_NOT_FOUND); + return NULL; + } + if (stmt->type == STMT_LABEL) { + if (stmt->label == label) { + if (!stmt2 || !STMT_IS_LOOP(stmt2)) { + js_ReportCompileErrorNumber(cx, ts, NULL, + JSREPORT_ERROR, + JSMSG_BAD_CONTINUE); + return NULL; + } + break; + } + } else { + stmt2 = stmt; + } + } + } else { + for (; ; stmt = stmt->down) { + if (!stmt) { + js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR, + JSMSG_BAD_CONTINUE); + return NULL; + } + if (STMT_IS_LOOP(stmt)) + break; + } + } + if (label) + pn->pn_pos.end = CURRENT_TOKEN(ts).pos.end; + break; + + case TOK_WITH: + pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_BINARY, tc); + if (!pn) + return NULL; + MUST_MATCH_TOKEN(TOK_LP, JSMSG_PAREN_BEFORE_WITH); + pn2 = Expr(cx, ts, tc); + if (!pn2) + return NULL; + MUST_MATCH_TOKEN(TOK_RP, JSMSG_PAREN_AFTER_WITH); + pn->pn_left = pn2; + + js_PushStatement(tc, &stmtInfo, STMT_WITH, -1); + pn2 = Statement(cx, ts, tc); + if (!pn2) + return NULL; + js_PopStatement(tc); + + /* Deprecate after parsing, in case of WERROR option. */ + if (!js_ReportCompileErrorNumber(cx, ts, NULL, + JSREPORT_WARNING | JSREPORT_STRICT, + JSMSG_DEPRECATED_USAGE, + js_with_statement_str)) { + return NULL; + } + + pn->pn_pos.end = pn2->pn_pos.end; + pn->pn_right = pn2; + tc->flags |= TCF_FUN_HEAVYWEIGHT; + return pn; + + case TOK_VAR: + pn = Variables(cx, ts, tc); + if (!pn) + return NULL; + + /* Tell js_EmitTree to generate a final POP. */ + pn->pn_extra = JS_TRUE; + break; + + case TOK_RETURN: + if (!(tc->flags & TCF_IN_FUNCTION)) { + js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR, + JSMSG_BAD_RETURN); + return NULL; + } + pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_UNARY, tc); + if (!pn) + return NULL; + + /* This is ugly, but we don't want to require a semicolon. */ + ts->flags |= TSF_REGEXP; + tt = js_PeekTokenSameLine(cx, ts); + ts->flags &= ~TSF_REGEXP; + if (tt == TOK_ERROR) + return NULL; + + if (tt != TOK_EOF && tt != TOK_EOL && tt != TOK_SEMI && tt != TOK_RC) { + pn2 = Expr(cx, ts, tc); + if (!pn2) + return NULL; + tc->flags |= TCF_RETURN_EXPR; + pn->pn_pos.end = pn2->pn_pos.end; + pn->pn_kid = pn2; + } else { + tc->flags |= TCF_RETURN_VOID; + pn->pn_kid = NULL; + } + + if (JS_HAS_STRICT_OPTION(cx) && + (~tc->flags & (TCF_RETURN_EXPR | TCF_RETURN_VOID)) == 0) { + /* + * We must be in a frame with a non-native function, because + * we're compiling one. + */ + if (!ReportNoReturnValue(cx, ts)) + return NULL; + } + break; + + case TOK_LC: + js_PushStatement(tc, &stmtInfo, STMT_BLOCK, -1); + pn = Statements(cx, ts, tc); + if (!pn) + return NULL; + + MUST_MATCH_TOKEN(TOK_RC, JSMSG_CURLY_IN_COMPOUND); + js_PopStatement(tc); + return pn; + + case TOK_EOL: + case TOK_SEMI: + pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_UNARY, tc); + if (!pn) + return NULL; + pn->pn_type = TOK_SEMI; + pn->pn_kid = NULL; + return pn; + +#if JS_HAS_DEBUGGER_KEYWORD + case TOK_DEBUGGER: + pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_NULLARY, tc); + if (!pn) + return NULL; + pn->pn_type = TOK_DEBUGGER; + tc->flags |= TCF_FUN_HEAVYWEIGHT; + break; +#endif /* JS_HAS_DEBUGGER_KEYWORD */ + + case TOK_ERROR: + return NULL; + + default: + js_UngetToken(ts); + pn2 = Expr(cx, ts, tc); + if (!pn2) + return NULL; + + if (js_PeekToken(cx, ts) == TOK_COLON) { + if (pn2->pn_type != TOK_NAME) { + js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR, + JSMSG_BAD_LABEL); + return NULL; + } + label = pn2->pn_atom; + for (stmt = tc->topStmt; stmt; stmt = stmt->down) { + if (stmt->type == STMT_LABEL && stmt->label == label) { + js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR, + JSMSG_DUPLICATE_LABEL); + return NULL; + } + } + (void) js_GetToken(cx, ts); + + /* Push a label struct and parse the statement. */ + js_PushStatement(tc, &stmtInfo, STMT_LABEL, -1); + stmtInfo.label = label; + pn = Statement(cx, ts, tc); + if (!pn) + return NULL; + + /* Pop the label, set pn_expr, and return early. */ + js_PopStatement(tc); + pn2->pn_type = TOK_COLON; + pn2->pn_pos.end = pn->pn_pos.end; + pn2->pn_expr = pn; + return pn2; + } + + pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_UNARY, tc); + if (!pn) + return NULL; + pn->pn_type = TOK_SEMI; + pn->pn_pos = pn2->pn_pos; + pn->pn_kid = pn2; + break; + } + + /* Check termination of this primitive statement. */ + if (ON_CURRENT_LINE(ts, pn->pn_pos)) { + tt = js_PeekTokenSameLine(cx, ts); + if (tt == TOK_ERROR) + return NULL; + if (tt != TOK_EOF && tt != TOK_EOL && tt != TOK_SEMI && tt != TOK_RC) { + js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR, + JSMSG_SEMI_BEFORE_STMNT); + return NULL; + } + } + + (void) js_MatchToken(cx, ts, TOK_SEMI); + return pn; +} + +static JSParseNode * +Variables(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc) +{ + JSParseNode *pn, *pn2; + JSObject *obj, *pobj; + JSStackFrame *fp; + JSFunction *fun; + JSClass *clasp; + JSPropertyOp getter, setter, currentGetter, currentSetter; + JSAtom *atom; + JSAtomListElement *ale; + JSOp prevop; + JSProperty *prop; + JSScopeProperty *sprop; + JSBool ok; + + /* + * The tricky part of this code is to create special parsenode opcodes for + * getting and setting variables (which will be stored as special slots in + * the frame). The complex special case is an eval() inside a function. + * If the evaluated string references variables in the enclosing function, + * then we need to generate the special variable opcodes. We determine + * this by looking up the variable id in the current variable scope. + */ + JS_ASSERT(CURRENT_TOKEN(ts).type == TOK_VAR); + pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_LIST, tc); + if (!pn) + return NULL; + pn->pn_op = CURRENT_TOKEN(ts).t_op; + pn->pn_extra = JS_FALSE; /* assume no JSOP_POP needed */ + PN_INIT_LIST(pn); + + /* + * Skip eval and debugger frames when looking for the function whose code + * is being compiled. If we are called from FunctionBody, TCF_IN_FUNCTION + * will be set in tc->flags, and we can be sure fp->fun is the function to + * use. But if a function calls eval, the string argument is treated as a + * Program (per ECMA), so TCF_IN_FUNCTION won't be set. + * + * What's more, when the following code is reached from eval, cx->fp->fun + * is eval's JSFunction (a native function), so we need to skip its frame. + * We should find the scripted caller's function frame just below it, but + * we code a loop out of paranoia. + */ + for (fp = cx->fp; (fp->flags & JSFRAME_SPECIAL) && fp->down; fp = fp->down) + continue; + obj = fp->varobj; + fun = fp->fun; + clasp = OBJ_GET_CLASS(cx, obj); + if (fun && clasp == &js_FunctionClass) { + /* We are compiling code inside a function */ + getter = js_GetLocalVariable; + setter = js_SetLocalVariable; + } else if (fun && clasp == &js_CallClass) { + /* We are compiling code from an eval inside a function */ + getter = js_GetCallVariable; + setter = js_SetCallVariable; + } else { + getter = clasp->getProperty; + setter = clasp->setProperty; + } + + ok = JS_TRUE; + do { + currentGetter = getter; + currentSetter = setter; + MUST_MATCH_TOKEN(TOK_NAME, JSMSG_NO_VARIABLE_NAME); + atom = CURRENT_TOKEN(ts).t_atom; + + ATOM_LIST_SEARCH(ale, &tc->decls, atom); + if (ale) { + prevop = ALE_JSOP(ale); + if (JS_HAS_STRICT_OPTION(cx) || + pn->pn_op == JSOP_DEFCONST || + prevop == JSOP_DEFCONST) { + const char *name = js_AtomToPrintableString(cx, atom); + if (!name || + !js_ReportCompileErrorNumber(cx, ts, NULL, + (pn->pn_op != JSOP_DEFCONST && + prevop != JSOP_DEFCONST) + ? JSREPORT_WARNING | + JSREPORT_STRICT + : JSREPORT_ERROR, + JSMSG_REDECLARED_VAR, + (prevop == JSOP_DEFFUN || + prevop == JSOP_CLOSURE) + ? js_function_str + : (prevop == JSOP_DEFCONST) + ? js_const_str + : js_var_str, + name)) { + return NULL; + } + } + if (pn->pn_op == JSOP_DEFVAR && prevop == JSOP_CLOSURE) + tc->flags |= TCF_FUN_CLOSURE_VS_VAR; + } else { + ale = js_IndexAtom(cx, atom, &tc->decls); + if (!ale) + return NULL; + } + ALE_SET_JSOP(ale, pn->pn_op); + + pn2 = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_NAME, tc); + if (!pn2) + return NULL; + pn2->pn_op = JSOP_NAME; + pn2->pn_atom = atom; + pn2->pn_expr = NULL; + pn2->pn_slot = -1; + pn2->pn_attrs = (pn->pn_op == JSOP_DEFCONST) + ? JSPROP_ENUMERATE | JSPROP_PERMANENT | + JSPROP_READONLY + : JSPROP_ENUMERATE | JSPROP_PERMANENT; + PN_APPEND(pn, pn2); + + if (!OBJ_LOOKUP_PROPERTY(cx, obj, (jsid)atom, &pobj, &prop)) + return NULL; + if (pobj == obj && + OBJ_IS_NATIVE(pobj) && + (sprop = (JSScopeProperty *)prop) != NULL) { + if (sprop->getter == js_GetArgument) { + const char *name = js_AtomToPrintableString(cx, atom); + if (!name) { + ok = JS_FALSE; + } else if (pn->pn_op == JSOP_DEFCONST) { + js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR, + JSMSG_REDECLARED_PARAM, + name); + ok = JS_FALSE; + } else { + currentGetter = js_GetArgument; + currentSetter = js_SetArgument; + ok = js_ReportCompileErrorNumber(cx, ts, NULL, + JSREPORT_WARNING | + JSREPORT_STRICT, + JSMSG_VAR_HIDES_ARG, + name); + } + } else { + if (fun) { + /* Not an argument, must be a redeclared local var. */ + if (clasp == &js_FunctionClass) { + JS_ASSERT(sprop->getter == js_GetLocalVariable); + JS_ASSERT((sprop->flags & SPROP_HAS_SHORTID) && + sprop->shortid < fun->nvars); + } else if (clasp == &js_CallClass) { + if (sprop->getter == js_GetCallVariable) { + /* + * Referencing a variable introduced by a var + * statement in the enclosing function. Check + * that the slot number we have is in range. + */ + JS_ASSERT((sprop->flags & SPROP_HAS_SHORTID) && + sprop->shortid < fun->nvars); + } else { + /* + * A variable introduced through another eval: + * don't use the special getters and setters + * since we can't allocate a slot in the frame. + */ + currentGetter = sprop->getter; + currentSetter = sprop->setter; + } + } + + /* Override the old getter and setter, to handle eval. */ + sprop = js_ChangeNativePropertyAttrs(cx, obj, sprop, + 0, sprop->attrs, + currentGetter, + currentSetter); + if (!sprop) + ok = JS_FALSE; + } + } + } else { + /* + * Property not found in current variable scope: we have not seen + * this variable before. Define a new local variable by adding a + * property to the function's scope, allocating one slot in the + * function's frame. Global variables and any locals declared in + * with statement bodies are handled at runtime, by script prolog + * JSOP_DEFVAR bytecodes generated for slot-less vars. + */ + sprop = NULL; + if (prop) { + OBJ_DROP_PROPERTY(cx, pobj, prop); + prop = NULL; + } + if (currentGetter == js_GetCallVariable) { + /* Can't increase fun->nvars in an active frame! */ + currentGetter = clasp->getProperty; + currentSetter = clasp->setProperty; + } + if (currentGetter == js_GetLocalVariable && + atom != cx->runtime->atomState.argumentsAtom && + fp->scopeChain == obj && + !js_InWithStatement(tc)) { + if (!js_AddNativeProperty(cx, obj, (jsid)atom, + currentGetter, currentSetter, + SPROP_INVALID_SLOT, + pn2->pn_attrs | JSPROP_SHARED, + SPROP_HAS_SHORTID, fun->nvars)) { + ok = JS_FALSE; + } + fun->nvars++; + } + } + + if (js_MatchToken(cx, ts, TOK_ASSIGN)) { + if (CURRENT_TOKEN(ts).t_op != JSOP_NOP) { + js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR, + JSMSG_BAD_VAR_INIT); + ok = JS_FALSE; + } else { + pn2->pn_expr = AssignExpr(cx, ts, tc); + if (!pn2->pn_expr) { + ok = JS_FALSE; + } else { + pn2->pn_op = (pn->pn_op == JSOP_DEFCONST) + ? JSOP_SETCONST + : JSOP_SETNAME; + if (atom == cx->runtime->atomState.argumentsAtom) + tc->flags |= TCF_FUN_HEAVYWEIGHT; + } + } + } + + if (prop) + OBJ_DROP_PROPERTY(cx, pobj, prop); + if (!ok) + return NULL; + } while (js_MatchToken(cx, ts, TOK_COMMA)); + + pn->pn_pos.end = PN_LAST(pn)->pn_pos.end; + return pn; +} + +static JSParseNode * +Expr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc) +{ + JSParseNode *pn, *pn2; + + pn = AssignExpr(cx, ts, tc); + if (pn && js_MatchToken(cx, ts, TOK_COMMA)) { + pn2 = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_LIST, tc); + if (!pn2) + return NULL; + pn2->pn_pos.begin = pn->pn_pos.begin; + PN_INIT_LIST_1(pn2, pn); + pn = pn2; + do { + pn2 = AssignExpr(cx, ts, tc); + if (!pn2) + return NULL; + PN_APPEND(pn, pn2); + } while (js_MatchToken(cx, ts, TOK_COMMA)); + pn->pn_pos.end = PN_LAST(pn)->pn_pos.end; + } + return pn; +} + +static JSParseNode * +AssignExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc) +{ + JSParseNode *pn, *pn2; + JSTokenType tt; + JSOp op; + + CHECK_RECURSION(); + + pn = CondExpr(cx, ts, tc); + if (!pn) + return NULL; + + tt = js_GetToken(cx, ts); +#if JS_HAS_GETTER_SETTER + if (tt == TOK_NAME) { + tt = CheckGetterOrSetter(cx, ts, TOK_ASSIGN); + if (tt == TOK_ERROR) + return NULL; + } +#endif + if (tt != TOK_ASSIGN) { + js_UngetToken(ts); + return pn; + } + + op = CURRENT_TOKEN(ts).t_op; + for (pn2 = pn; pn2->pn_type == TOK_RP; pn2 = pn2->pn_kid) + continue; + switch (pn2->pn_type) { + case TOK_NAME: + pn2->pn_op = JSOP_SETNAME; + if (pn2->pn_atom == cx->runtime->atomState.argumentsAtom) + tc->flags |= TCF_FUN_HEAVYWEIGHT; + break; + case TOK_DOT: + pn2->pn_op = JSOP_SETPROP; + break; + case TOK_LB: + pn2->pn_op = JSOP_SETELEM; + break; +#if JS_HAS_LVALUE_RETURN + case TOK_LP: + pn2->pn_op = JSOP_SETCALL; + break; +#endif + default: + js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR, + JSMSG_BAD_LEFTSIDE_OF_ASS); + return NULL; + } + pn = NewBinary(cx, TOK_ASSIGN, op, pn2, AssignExpr(cx, ts, tc), tc); + return pn; +} + +static JSParseNode * +CondExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc) +{ + JSParseNode *pn, *pn1, *pn2, *pn3; +#if JS_HAS_IN_OPERATOR + uintN oldflags; +#endif /* JS_HAS_IN_OPERATOR */ + + pn = OrExpr(cx, ts, tc); + if (pn && js_MatchToken(cx, ts, TOK_HOOK)) { + pn1 = pn; + pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_TERNARY, tc); + if (!pn) + return NULL; +#if JS_HAS_IN_OPERATOR + /* + * Always accept the 'in' operator in the middle clause of a ternary, + * where it's unambiguous, even if we might be parsing the init of a + * for statement. + */ + oldflags = tc->flags; + tc->flags &= ~TCF_IN_FOR_INIT; +#endif /* JS_HAS_IN_OPERATOR */ + pn2 = AssignExpr(cx, ts, tc); +#if JS_HAS_IN_OPERATOR + tc->flags = oldflags | (tc->flags & TCF_FUN_FLAGS); +#endif /* JS_HAS_IN_OPERATOR */ + + if (!pn2) + return NULL; + MUST_MATCH_TOKEN(TOK_COLON, JSMSG_COLON_IN_COND); + pn3 = AssignExpr(cx, ts, tc); + if (!pn3) + return NULL; + pn->pn_pos.begin = pn1->pn_pos.begin; + pn->pn_pos.end = pn3->pn_pos.end; + pn->pn_kid1 = pn1; + pn->pn_kid2 = pn2; + pn->pn_kid3 = pn3; + } + return pn; +} + +static JSParseNode * +OrExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc) +{ + JSParseNode *pn; + + pn = AndExpr(cx, ts, tc); + if (pn && js_MatchToken(cx, ts, TOK_OR)) + pn = NewBinary(cx, TOK_OR, JSOP_OR, pn, OrExpr(cx, ts, tc), tc); + return pn; +} + +static JSParseNode * +AndExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc) +{ + JSParseNode *pn; + + pn = BitOrExpr(cx, ts, tc); + if (pn && js_MatchToken(cx, ts, TOK_AND)) + pn = NewBinary(cx, TOK_AND, JSOP_AND, pn, AndExpr(cx, ts, tc), tc); + return pn; +} + +static JSParseNode * +BitOrExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc) +{ + JSParseNode *pn; + + pn = BitXorExpr(cx, ts, tc); + while (pn && js_MatchToken(cx, ts, TOK_BITOR)) { + pn = NewBinary(cx, TOK_BITOR, JSOP_BITOR, pn, BitXorExpr(cx, ts, tc), + tc); + } + return pn; +} + +static JSParseNode * +BitXorExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc) +{ + JSParseNode *pn; + + pn = BitAndExpr(cx, ts, tc); + while (pn && js_MatchToken(cx, ts, TOK_BITXOR)) { + pn = NewBinary(cx, TOK_BITXOR, JSOP_BITXOR, pn, BitAndExpr(cx, ts, tc), + tc); + } + return pn; +} + +static JSParseNode * +BitAndExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc) +{ + JSParseNode *pn; + + pn = EqExpr(cx, ts, tc); + while (pn && js_MatchToken(cx, ts, TOK_BITAND)) + pn = NewBinary(cx, TOK_BITAND, JSOP_BITAND, pn, EqExpr(cx, ts, tc), tc); + return pn; +} + +static JSParseNode * +EqExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc) +{ + JSParseNode *pn; + JSOp op; + + pn = RelExpr(cx, ts, tc); + while (pn && js_MatchToken(cx, ts, TOK_EQOP)) { + op = CURRENT_TOKEN(ts).t_op; + pn = NewBinary(cx, TOK_EQOP, op, pn, RelExpr(cx, ts, tc), tc); + } + return pn; +} + +static JSParseNode * +RelExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc) +{ + JSParseNode *pn; + JSTokenType tt; + JSOp op; +#if JS_HAS_IN_OPERATOR + uintN inForInitFlag = tc->flags & TCF_IN_FOR_INIT; + + /* + * Uses of the in operator in ShiftExprs are always unambiguous, + * so unset the flag that prohibits recognizing it. + */ + tc->flags &= ~TCF_IN_FOR_INIT; +#endif /* JS_HAS_IN_OPERATOR */ + + pn = ShiftExpr(cx, ts, tc); + while (pn && + (js_MatchToken(cx, ts, TOK_RELOP) +#if JS_HAS_IN_OPERATOR + /* + * Recognize the 'in' token as an operator only if we're not + * currently in the init expr of a for loop. + */ + || (inForInitFlag == 0 && js_MatchToken(cx, ts, TOK_IN)) +#endif /* JS_HAS_IN_OPERATOR */ +#if JS_HAS_INSTANCEOF + || js_MatchToken(cx, ts, TOK_INSTANCEOF) +#endif /* JS_HAS_INSTANCEOF */ + )) { + tt = CURRENT_TOKEN(ts).type; + op = CURRENT_TOKEN(ts).t_op; + pn = NewBinary(cx, tt, op, pn, ShiftExpr(cx, ts, tc), tc); + } +#if JS_HAS_IN_OPERATOR + /* Restore previous state of inForInit flag. */ + tc->flags |= inForInitFlag; +#endif /* JS_HAS_IN_OPERATOR */ + + return pn; +} + +static JSParseNode * +ShiftExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc) +{ + JSParseNode *pn; + JSOp op; + + pn = AddExpr(cx, ts, tc); + while (pn && js_MatchToken(cx, ts, TOK_SHOP)) { + op = CURRENT_TOKEN(ts).t_op; + pn = NewBinary(cx, TOK_SHOP, op, pn, AddExpr(cx, ts, tc), tc); + } + return pn; +} + +static JSParseNode * +AddExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc) +{ + JSParseNode *pn; + JSTokenType tt; + JSOp op; + + pn = MulExpr(cx, ts, tc); + while (pn && + (js_MatchToken(cx, ts, TOK_PLUS) || + js_MatchToken(cx, ts, TOK_MINUS))) { + tt = CURRENT_TOKEN(ts).type; + op = (tt == TOK_PLUS) ? JSOP_ADD : JSOP_SUB; + pn = NewBinary(cx, tt, op, pn, MulExpr(cx, ts, tc), tc); + } + return pn; +} + +static JSParseNode * +MulExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc) +{ + JSParseNode *pn; + JSTokenType tt; + JSOp op; + + pn = UnaryExpr(cx, ts, tc); + while (pn && + (js_MatchToken(cx, ts, TOK_STAR) || + js_MatchToken(cx, ts, TOK_DIVOP))) { + tt = CURRENT_TOKEN(ts).type; + op = CURRENT_TOKEN(ts).t_op; + pn = NewBinary(cx, tt, op, pn, UnaryExpr(cx, ts, tc), tc); + } + return pn; +} + +static JSParseNode * +SetLvalKid(JSContext *cx, JSTokenStream *ts, JSParseNode *pn, JSParseNode *kid, + const char *name) +{ + while (kid->pn_type == TOK_RP) + kid = kid->pn_kid; + if (kid->pn_type != TOK_NAME && + kid->pn_type != TOK_DOT && +#if JS_HAS_LVALUE_RETURN + (kid->pn_type != TOK_LP || kid->pn_op != JSOP_CALL) && +#endif + kid->pn_type != TOK_LB) { + js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR, + JSMSG_BAD_OPERAND, name); + return NULL; + } + pn->pn_kid = kid; + return kid; +} + +static const char *incop_name_str[] = {"increment", "decrement"}; + +static JSBool +SetIncOpKid(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc, + JSParseNode *pn, JSParseNode *kid, + JSTokenType tt, JSBool preorder) +{ + JSOp op; + + kid = SetLvalKid(cx, ts, pn, kid, incop_name_str[tt == TOK_DEC]); + if (!kid) + return JS_FALSE; + switch (kid->pn_type) { + case TOK_NAME: + op = (tt == TOK_INC) + ? (preorder ? JSOP_INCNAME : JSOP_NAMEINC) + : (preorder ? JSOP_DECNAME : JSOP_NAMEDEC); + if (kid->pn_atom == cx->runtime->atomState.argumentsAtom) + tc->flags |= TCF_FUN_HEAVYWEIGHT; + break; + + case TOK_DOT: + op = (tt == TOK_INC) + ? (preorder ? JSOP_INCPROP : JSOP_PROPINC) + : (preorder ? JSOP_DECPROP : JSOP_PROPDEC); + break; + +#if JS_HAS_LVALUE_RETURN + case TOK_LP: + kid->pn_op = JSOP_SETCALL; +#endif + case TOK_LB: + op = (tt == TOK_INC) + ? (preorder ? JSOP_INCELEM : JSOP_ELEMINC) + : (preorder ? JSOP_DECELEM : JSOP_ELEMDEC); + break; + + default: + JS_ASSERT(0); + op = JSOP_NOP; + } + pn->pn_op = op; + return JS_TRUE; +} + +static JSParseNode * +UnaryExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc) +{ + JSTokenType tt; + JSParseNode *pn, *pn2; + + ts->flags |= TSF_REGEXP; + tt = js_GetToken(cx, ts); + ts->flags &= ~TSF_REGEXP; + + switch (tt) { + case TOK_UNARYOP: + case TOK_PLUS: + case TOK_MINUS: + pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_UNARY, tc); + if (!pn) + return NULL; + pn->pn_type = TOK_UNARYOP; /* PLUS and MINUS are binary */ + pn->pn_op = CURRENT_TOKEN(ts).t_op; + pn2 = UnaryExpr(cx, ts, tc); + if (!pn2) + return NULL; + pn->pn_pos.end = pn2->pn_pos.end; + pn->pn_kid = pn2; + break; + + case TOK_INC: + case TOK_DEC: + pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_UNARY, tc); + if (!pn) + return NULL; + pn2 = MemberExpr(cx, ts, tc, JS_TRUE); + if (!pn2) + return NULL; + if (!SetIncOpKid(cx, ts, tc, pn, pn2, tt, JS_TRUE)) + return NULL; + pn->pn_pos.end = pn2->pn_pos.end; + break; + + case TOK_DELETE: + pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_UNARY, tc); + if (!pn) + return NULL; + pn2 = UnaryExpr(cx, ts, tc); + if (!pn2) + return NULL; + pn->pn_pos.end = pn2->pn_pos.end; + + /* + * Under ECMA3, deleting any unary expression is valid -- it simply + * returns true. Here we strip off any parentheses. + */ + while (pn2->pn_type == TOK_RP) + pn2 = pn2->pn_kid; + pn->pn_kid = pn2; + break; + + case TOK_ERROR: + return NULL; + + default: + js_UngetToken(ts); + pn = MemberExpr(cx, ts, tc, JS_TRUE); + if (!pn) + return NULL; + + /* Don't look across a newline boundary for a postfix incop. */ + if (ON_CURRENT_LINE(ts, pn->pn_pos)) { + tt = js_PeekTokenSameLine(cx, ts); + if (tt == TOK_INC || tt == TOK_DEC) { + (void) js_GetToken(cx, ts); + pn2 = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_UNARY, tc); + if (!pn2) + return NULL; + if (!SetIncOpKid(cx, ts, tc, pn2, pn, tt, JS_FALSE)) + return NULL; + pn2->pn_pos.begin = pn->pn_pos.begin; + pn = pn2; + } + } + break; + } + return pn; +} + +static JSBool +ArgumentList(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc, + JSParseNode *listNode) +{ + JSBool matched; + + ts->flags |= TSF_REGEXP; + matched = js_MatchToken(cx, ts, TOK_RP); + ts->flags &= ~TSF_REGEXP; + if (!matched) { + do { + JSParseNode *argNode = AssignExpr(cx, ts, tc); + if (!argNode) + return JS_FALSE; + PN_APPEND(listNode, argNode); + } while (js_MatchToken(cx, ts, TOK_COMMA)); + + if (js_GetToken(cx, ts) != TOK_RP) { + js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR, + JSMSG_PAREN_AFTER_ARGS); + return JS_FALSE; + } + } + return JS_TRUE; +} + +static JSParseNode * +MemberExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc, + JSBool allowCallSyntax) +{ + JSParseNode *pn, *pn2, *pn3; + JSTokenType tt; + + CHECK_RECURSION(); + + /* Check for new expression first. */ + ts->flags |= TSF_REGEXP; + tt = js_PeekToken(cx, ts); + ts->flags &= ~TSF_REGEXP; + if (tt == TOK_NEW) { + (void) js_GetToken(cx, ts); + + pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_LIST, tc); + if (!pn) + return NULL; + pn2 = MemberExpr(cx, ts, tc, JS_FALSE); + if (!pn2) + return NULL; + pn->pn_op = JSOP_NEW; + PN_INIT_LIST_1(pn, pn2); + pn->pn_pos.begin = pn2->pn_pos.begin; + + if (js_MatchToken(cx, ts, TOK_LP) && !ArgumentList(cx, ts, tc, pn)) + return NULL; + if (pn->pn_count > ARGC_LIMIT) { + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, + JSMSG_TOO_MANY_CON_ARGS); + return NULL; + } + pn->pn_pos.end = PN_LAST(pn)->pn_pos.end; + } else { + pn = PrimaryExpr(cx, ts, tc); + if (!pn) + return NULL; + } + + while ((tt = js_GetToken(cx, ts)) > TOK_EOF) { + if (tt == TOK_DOT) { + pn2 = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_NAME, tc); + if (!pn2) + return NULL; + MUST_MATCH_TOKEN(TOK_NAME, JSMSG_NAME_AFTER_DOT); + pn2->pn_pos.begin = pn->pn_pos.begin; + pn2->pn_pos.end = CURRENT_TOKEN(ts).pos.end; + pn2->pn_op = JSOP_GETPROP; + pn2->pn_expr = pn; + pn2->pn_atom = CURRENT_TOKEN(ts).t_atom; + } else if (tt == TOK_LB) { + pn2 = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_BINARY, tc); + if (!pn2) + return NULL; + pn3 = Expr(cx, ts, tc); + if (!pn3) + return NULL; + + MUST_MATCH_TOKEN(TOK_RB, JSMSG_BRACKET_IN_INDEX); + pn2->pn_pos.begin = pn->pn_pos.begin; + pn2->pn_pos.end = CURRENT_TOKEN(ts).pos.end; + + /* Optimize o['p'] to o.p by rewriting pn2. */ + if (pn3->pn_type == TOK_STRING) { + pn2->pn_type = TOK_DOT; + pn2->pn_op = JSOP_GETPROP; + pn2->pn_arity = PN_NAME; + pn2->pn_expr = pn; + pn2->pn_atom = pn3->pn_atom; + } else { + pn2->pn_op = JSOP_GETELEM; + pn2->pn_left = pn; + pn2->pn_right = pn3; + } + } else if (allowCallSyntax && tt == TOK_LP) { + pn2 = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_LIST, tc); + if (!pn2) + return NULL; + + /* Pick JSOP_EVAL and flag tc as heavyweight if eval(...). */ + pn2->pn_op = JSOP_CALL; + if (pn->pn_op == JSOP_NAME && + pn->pn_atom == cx->runtime->atomState.evalAtom) { + pn2->pn_op = JSOP_EVAL; + tc->flags |= TCF_FUN_HEAVYWEIGHT; + } + + PN_INIT_LIST_1(pn2, pn); + pn2->pn_pos.begin = pn->pn_pos.begin; + + if (!ArgumentList(cx, ts, tc, pn2)) + return NULL; + if (pn2->pn_count > ARGC_LIMIT) { + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, + JSMSG_TOO_MANY_FUN_ARGS); + return NULL; + } + pn2->pn_pos.end = PN_LAST(pn2)->pn_pos.end; + } else { + js_UngetToken(ts); + return pn; + } + + pn = pn2; + } + if (tt == TOK_ERROR) + return NULL; + return pn; +} + +static JSParseNode * +PrimaryExpr(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc) +{ + JSTokenType tt; + JSParseNode *pn, *pn2, *pn3; + char *badWord; +#if JS_HAS_GETTER_SETTER + JSAtom *atom; + JSRuntime *rt; +#endif + +#if JS_HAS_SHARP_VARS + JSParseNode *defsharp; + JSBool notsharp; + + defsharp = NULL; + notsharp = JS_FALSE; + again: + /* + * Control flows here after #n= is scanned. If the following primary is + * not valid after such a "sharp variable" definition, the token type case + * should set notsharp. + */ +#endif + + CHECK_RECURSION(); + + ts->flags |= TSF_REGEXP; + tt = js_GetToken(cx, ts); + ts->flags &= ~TSF_REGEXP; + +#if JS_HAS_GETTER_SETTER + if (tt == TOK_NAME) { + tt = CheckGetterOrSetter(cx, ts, TOK_FUNCTION); + if (tt == TOK_ERROR) + return NULL; + } +#endif + + switch (tt) { +#if JS_HAS_LEXICAL_CLOSURE + case TOK_FUNCTION: + pn = FunctionExpr(cx, ts, tc); + if (!pn) + return NULL; + break; +#endif + +#if JS_HAS_INITIALIZERS + case TOK_LB: + { + JSBool matched; + jsuint atomIndex; + + pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_LIST, tc); + if (!pn) + return NULL; + pn->pn_type = TOK_RB; + pn->pn_extra = JS_FALSE; + +#if JS_HAS_SHARP_VARS + if (defsharp) { + PN_INIT_LIST_1(pn, defsharp); + defsharp = NULL; + } else +#endif + PN_INIT_LIST(pn); + + ts->flags |= TSF_REGEXP; + matched = js_MatchToken(cx, ts, TOK_RB); + ts->flags &= ~TSF_REGEXP; + if (!matched) { + for (atomIndex = 0; atomIndex < ATOM_INDEX_LIMIT; atomIndex++) { + ts->flags |= TSF_REGEXP; + tt = js_PeekToken(cx, ts); + ts->flags &= ~TSF_REGEXP; + if (tt == TOK_RB) { + pn->pn_extra = JS_TRUE; + break; + } + + if (tt == TOK_COMMA) { + /* So CURRENT_TOKEN gets TOK_COMMA and not TOK_LB. */ + js_MatchToken(cx, ts, TOK_COMMA); + pn2 = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_NULLARY, tc); + } else { + pn2 = AssignExpr(cx, ts, tc); + } + if (!pn2) + return NULL; + PN_APPEND(pn, pn2); + + if (tt != TOK_COMMA) { + /* If we didn't already match TOK_COMMA in above case. */ + if (!js_MatchToken(cx, ts, TOK_COMMA)) + break; + } + } + + MUST_MATCH_TOKEN(TOK_RB, JSMSG_BRACKET_AFTER_LIST); + } + pn->pn_pos.end = CURRENT_TOKEN(ts).pos.end; + return pn; + } + + case TOK_LC: + pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_LIST, tc); + if (!pn) + return NULL; + pn->pn_type = TOK_RC; + +#if JS_HAS_SHARP_VARS + if (defsharp) { + PN_INIT_LIST_1(pn, defsharp); + defsharp = NULL; + } else +#endif + PN_INIT_LIST(pn); + + if (!js_MatchToken(cx, ts, TOK_RC)) { + do { + JSOp op; + + tt = js_GetToken(cx, ts); + switch (tt) { + case TOK_NUMBER: + pn3 = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_NULLARY, tc); + if (pn3) + pn3->pn_dval = CURRENT_TOKEN(ts).t_dval; + break; + case TOK_NAME: +#if JS_HAS_GETTER_SETTER + atom = CURRENT_TOKEN(ts).t_atom; + rt = cx->runtime; + if (atom == rt->atomState.getAtom || + atom == rt->atomState.setAtom) { + op = (atom == rt->atomState.getAtom) + ? JSOP_GETTER + : JSOP_SETTER; + if (js_MatchToken(cx, ts, TOK_NAME)) { + pn3 = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_NAME, + tc); + if (!pn3) + return NULL; + pn3->pn_atom = CURRENT_TOKEN(ts).t_atom; + pn3->pn_expr = NULL; + + /* We have to fake a 'function' token here. */ + CURRENT_TOKEN(ts).t_op = JSOP_NOP; + CURRENT_TOKEN(ts).type = TOK_FUNCTION; + pn2 = FunctionExpr(cx, ts, tc); + pn2 = NewBinary(cx, TOK_COLON, op, pn3, pn2, tc); + goto skip; + } + } + /* else fall thru ... */ +#endif + case TOK_STRING: + pn3 = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_NULLARY, tc); + if (pn3) + pn3->pn_atom = CURRENT_TOKEN(ts).t_atom; + break; + case TOK_RC: + if (!js_ReportCompileErrorNumber(cx, ts, NULL, + JSREPORT_WARNING | + JSREPORT_STRICT, + JSMSG_TRAILING_COMMA)) { + return NULL; + } + goto end_obj_init; + default: + js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR, + JSMSG_BAD_PROP_ID); + return NULL; + } + + tt = js_GetToken(cx, ts); +#if JS_HAS_GETTER_SETTER + if (tt == TOK_NAME) { + tt = CheckGetterOrSetter(cx, ts, TOK_COLON); + if (tt == TOK_ERROR) + return NULL; + } +#endif + if (tt != TOK_COLON) { + js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR, + JSMSG_COLON_AFTER_ID); + return NULL; + } + op = CURRENT_TOKEN(ts).t_op; + pn2 = NewBinary(cx, TOK_COLON, op, pn3, AssignExpr(cx, ts, tc), + tc); +#if JS_HAS_GETTER_SETTER + skip: +#endif + if (!pn2) + return NULL; + PN_APPEND(pn, pn2); + } while (js_MatchToken(cx, ts, TOK_COMMA)); + + MUST_MATCH_TOKEN(TOK_RC, JSMSG_CURLY_AFTER_LIST); + } + end_obj_init: + pn->pn_pos.end = CURRENT_TOKEN(ts).pos.end; + return pn; + +#if JS_HAS_SHARP_VARS + case TOK_DEFSHARP: + if (defsharp) + goto badsharp; + defsharp = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_UNARY, tc); + if (!defsharp) + return NULL; + defsharp->pn_kid = NULL; + defsharp->pn_num = (jsint) CURRENT_TOKEN(ts).t_dval; + goto again; + + case TOK_USESHARP: + /* Check for forward/dangling references at runtime, to allow eval. */ + pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_NULLARY, tc); + if (!pn) + return NULL; + pn->pn_num = (jsint) CURRENT_TOKEN(ts).t_dval; + notsharp = JS_TRUE; + break; +#endif /* JS_HAS_SHARP_VARS */ +#endif /* JS_HAS_INITIALIZERS */ + + case TOK_LP: + { +#if JS_HAS_IN_OPERATOR + uintN oldflags; +#endif + pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_UNARY, tc); + if (!pn) + return NULL; +#if JS_HAS_IN_OPERATOR + /* + * Always accept the 'in' operator in a parenthesized expression, + * where it's unambiguous, even if we might be parsing the init of a + * for statement. + */ + oldflags = tc->flags; + tc->flags &= ~TCF_IN_FOR_INIT; +#endif + pn2 = Expr(cx, ts, tc); +#if JS_HAS_IN_OPERATOR + tc->flags = oldflags | (tc->flags & TCF_FUN_FLAGS); +#endif + if (!pn2) + return NULL; + + MUST_MATCH_TOKEN(TOK_RP, JSMSG_PAREN_IN_PAREN); + pn->pn_type = TOK_RP; + pn->pn_pos.end = CURRENT_TOKEN(ts).pos.end; + pn->pn_kid = pn2; + break; + } + + case TOK_STRING: +#if JS_HAS_SHARP_VARS + notsharp = JS_TRUE; +#endif + /* FALL THROUGH */ + case TOK_NAME: + case TOK_OBJECT: + pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_NULLARY, tc); + if (!pn) + return NULL; + pn->pn_op = CURRENT_TOKEN(ts).t_op; + pn->pn_atom = CURRENT_TOKEN(ts).t_atom; + if (tt == TOK_NAME) { + pn->pn_arity = PN_NAME; + pn->pn_expr = NULL; + pn->pn_slot = -1; + pn->pn_attrs = 0; + + /* Unqualified __parent__ and __proto__ uses require activations. */ + if (pn->pn_atom == cx->runtime->atomState.parentAtom || + pn->pn_atom == cx->runtime->atomState.protoAtom) { + tc->flags |= TCF_FUN_HEAVYWEIGHT; + } + } + break; + + case TOK_NUMBER: + pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_NULLARY, tc); + if (!pn) + return NULL; + pn->pn_dval = CURRENT_TOKEN(ts).t_dval; +#if JS_HAS_SHARP_VARS + notsharp = JS_TRUE; +#endif + break; + + case TOK_PRIMARY: + pn = NewParseNode(cx, &CURRENT_TOKEN(ts), PN_NULLARY, tc); + if (!pn) + return NULL; + pn->pn_op = CURRENT_TOKEN(ts).t_op; +#if JS_HAS_SHARP_VARS + notsharp = JS_TRUE; +#endif + break; + +#if !JS_HAS_EXPORT_IMPORT + case TOK_EXPORT: + case TOK_IMPORT: +#endif + case TOK_RESERVED: + badWord = js_DeflateString(cx, CURRENT_TOKEN(ts).ptr, + (size_t) CURRENT_TOKEN(ts).pos.end.index + - CURRENT_TOKEN(ts).pos.begin.index); + js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR, + JSMSG_RESERVED_ID, badWord); + JS_free(cx, badWord); + return NULL; + + case TOK_ERROR: + /* The scanner or one of its subroutines reported the error. */ + return NULL; + + default: + js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR, + JSMSG_SYNTAX_ERROR); + return NULL; + } + +#if JS_HAS_SHARP_VARS + if (defsharp) { + if (notsharp) { + badsharp: + js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR, + JSMSG_BAD_SHARP_VAR_DEF); + return NULL; + } + defsharp->pn_kid = pn; + return defsharp; + } +#endif + return pn; +} + +static JSBool +ContainsVarStmt(JSParseNode *pn) +{ + JSParseNode *pn2; + + if (!pn) + return JS_FALSE; + switch (pn->pn_arity) { + case PN_LIST: + if (pn->pn_type == TOK_VAR) + return JS_TRUE; + for (pn2 = pn->pn_head; pn2; pn2 = pn2->pn_next) { + if (ContainsVarStmt(pn2)) + return JS_TRUE; + } + break; + case PN_TERNARY: + return ContainsVarStmt(pn->pn_kid1) || + ContainsVarStmt(pn->pn_kid2) || + ContainsVarStmt(pn->pn_kid3); + case PN_BINARY: + /* + * Limit recursion if pn is a binary expression, which can't contain a + * var statement. + */ + if (pn->pn_op != JSOP_NOP) + return JS_FALSE; + return ContainsVarStmt(pn->pn_left) || ContainsVarStmt(pn->pn_right); + case PN_UNARY: + if (pn->pn_op != JSOP_NOP) + return JS_FALSE; + return ContainsVarStmt(pn->pn_kid); + default:; + } + return JS_FALSE; +} + +/* + * Fold from one constant type to another. + * XXX handles only strings and numbers for now + */ +static JSBool +FoldType(JSContext *cx, JSParseNode *pn, JSTokenType type) +{ + if (pn->pn_type != type) { + switch (type) { + case TOK_NUMBER: + if (pn->pn_type == TOK_STRING) { + jsdouble d; + if (!js_ValueToNumber(cx, ATOM_KEY(pn->pn_atom), &d)) + return JS_FALSE; + pn->pn_dval = d; + pn->pn_type = TOK_NUMBER; + pn->pn_op = JSOP_NUMBER; + } + break; + + case TOK_STRING: + if (pn->pn_type == TOK_NUMBER) { + JSString *str = js_NumberToString(cx, pn->pn_dval); + if (!str) + return JS_FALSE; + pn->pn_atom = js_AtomizeString(cx, str, 0); + if (!pn->pn_atom) + return JS_FALSE; + pn->pn_type = TOK_STRING; + pn->pn_op = JSOP_STRING; + } + break; + + default:; + } + } + return JS_TRUE; +} + +/* + * Fold two numeric constants. Beware that pn1 and pn2 are recycled, unless + * one of them aliases pn, so you can't safely fetch pn2->pn_next, e.g., after + * a successful call to this function. + */ +static JSBool +FoldBinaryNumeric(JSContext *cx, JSOp op, JSParseNode *pn1, JSParseNode *pn2, + JSParseNode *pn, JSTreeContext *tc) +{ + jsdouble d, d2; + int32 i, j; + uint32 u; + + JS_ASSERT(pn1->pn_type == TOK_NUMBER && pn2->pn_type == TOK_NUMBER); + d = pn1->pn_dval; + d2 = pn2->pn_dval; + switch (op) { + case JSOP_LSH: + case JSOP_RSH: + if (!js_DoubleToECMAInt32(cx, d, &i)) + return JS_FALSE; + if (!js_DoubleToECMAInt32(cx, d2, &j)) + return JS_FALSE; + j &= 31; + d = (op == JSOP_LSH) ? i << j : i >> j; + break; + + case JSOP_URSH: + if (!js_DoubleToECMAUint32(cx, d, &u)) + return JS_FALSE; + if (!js_DoubleToECMAInt32(cx, d2, &j)) + return JS_FALSE; + j &= 31; + d = u >> j; + break; + + case JSOP_ADD: + d += d2; + break; + + case JSOP_SUB: + d -= d2; + break; + + case JSOP_MUL: + d *= d2; + break; + + case JSOP_DIV: + if (d2 == 0) { +#if defined(XP_WIN) + /* XXX MSVC miscompiles such that (NaN == 0) */ + if (JSDOUBLE_IS_NaN(d2)) + d = *cx->runtime->jsNaN; + else +#endif + if (d == 0 || JSDOUBLE_IS_NaN(d)) + d = *cx->runtime->jsNaN; + else if ((JSDOUBLE_HI32(d) ^ JSDOUBLE_HI32(d2)) >> 31) + d = *cx->runtime->jsNegativeInfinity; + else + d = *cx->runtime->jsPositiveInfinity; + } else { + d /= d2; + } + break; + + case JSOP_MOD: + if (d2 == 0) { + d = *cx->runtime->jsNaN; + } else { +#if defined(XP_WIN) + /* Workaround MS fmod bug where 42 % (1/0) => NaN, not 42. */ + if (!(JSDOUBLE_IS_FINITE(d) && JSDOUBLE_IS_INFINITE(d2))) +#endif + d = fmod(d, d2); + } + break; + + default:; + } + + /* Take care to allow pn1 or pn2 to alias pn. */ + if (pn1 != pn) + RecycleTree(pn1, tc); + if (pn2 != pn) + RecycleTree(pn2, tc); + pn->pn_type = TOK_NUMBER; + pn->pn_op = JSOP_NUMBER; + pn->pn_arity = PN_NULLARY; + pn->pn_dval = d; + return JS_TRUE; +} + +JSBool +js_FoldConstants(JSContext *cx, JSParseNode *pn, JSTreeContext *tc) +{ + JSParseNode *pn1 = NULL, *pn2 = NULL, *pn3 = NULL; + int stackDummy; + + if (!JS_CHECK_STACK_SIZE(cx, stackDummy)) { + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_OVER_RECURSED); + return JS_FALSE; + } + + switch (pn->pn_arity) { + case PN_FUNC: + if (!js_FoldConstants(cx, pn->pn_body, tc)) + return JS_FALSE; + break; + + case PN_LIST: + /* Save the list head in pn1 for later use. */ + for (pn1 = pn2 = pn->pn_head; pn2; pn2 = pn2->pn_next) { + if (!js_FoldConstants(cx, pn2, tc)) + return JS_FALSE; + } + break; + + case PN_TERNARY: + /* Any kid may be null (e.g. for (;;)). */ + pn1 = pn->pn_kid1; + pn2 = pn->pn_kid2; + pn3 = pn->pn_kid3; + if (pn1 && !js_FoldConstants(cx, pn1, tc)) + return JS_FALSE; + if (pn2 && !js_FoldConstants(cx, pn2, tc)) + return JS_FALSE; + if (pn3 && !js_FoldConstants(cx, pn3, tc)) + return JS_FALSE; + break; + + case PN_BINARY: + /* First kid may be null (for default case in switch). */ + pn1 = pn->pn_left; + pn2 = pn->pn_right; + if (pn1 && !js_FoldConstants(cx, pn1, tc)) + return JS_FALSE; + if (!js_FoldConstants(cx, pn2, tc)) + return JS_FALSE; + break; + + case PN_UNARY: + /* Our kid may be null (e.g. return; vs. return e;). */ + pn1 = pn->pn_kid; + if (pn1 && !js_FoldConstants(cx, pn1, tc)) + return JS_FALSE; + break; + + case PN_NAME: + /* + * Skip pn1 down along a chain of dotted member expressions to avoid + * excessive recursion. Our only goal here is to fold constants (if + * any) in the primary expression operand to the left of the first + * dot in the chain. + */ + pn1 = pn->pn_expr; + while (pn1 && pn1->pn_arity == PN_NAME) + pn1 = pn1->pn_expr; + if (pn1 && !js_FoldConstants(cx, pn1, tc)) + return JS_FALSE; + break; + + case PN_NULLARY: + break; + } + + switch (pn->pn_type) { + case TOK_IF: + if (ContainsVarStmt(pn2) || ContainsVarStmt(pn3)) + break; + /* FALL THROUGH */ + + case TOK_HOOK: + /* Reduce 'if (C) T; else E' into T for true C, E for false. */ + switch (pn1->pn_type) { + case TOK_NUMBER: + if (pn1->pn_dval == 0) + pn2 = pn3; + break; + case TOK_STRING: + if (JSSTRING_LENGTH(ATOM_TO_STRING(pn1->pn_atom)) == 0) + pn2 = pn3; + break; + case TOK_PRIMARY: + if (pn1->pn_op == JSOP_TRUE) + break; + if (pn1->pn_op == JSOP_FALSE || pn1->pn_op == JSOP_NULL) { + pn2 = pn3; + break; + } + /* FALL THROUGH */ + default: + /* Early return to dodge common code that copies pn2 to pn. */ + return JS_TRUE; + } + + if (pn2) { + /* pn2 is the then- or else-statement subtree to compile. */ + PN_MOVE_NODE(pn, pn2); + } else { + /* False condition and no else: make pn an empty statement. */ + pn->pn_type = TOK_SEMI; + pn->pn_arity = PN_UNARY; + pn->pn_kid = NULL; + } + RecycleTree(pn2, tc); + if (pn3 && pn3 != pn2) + RecycleTree(pn3, tc); + break; + + case TOK_PLUS: + if (pn->pn_arity == PN_LIST) { + size_t length, length2; + jschar *chars; + JSString *str, *str2; + + /* + * Any string literal term with all others number or string means + * this is a concatenation. If any term is not a string or number + * literal, we can't fold. + */ + JS_ASSERT(pn->pn_count > 2); + if (pn->pn_extra & PNX_CANTFOLD) + return JS_TRUE; + if (pn->pn_extra != PNX_STRCAT) + goto do_binary_op; + + /* Ok, we're concatenating: convert non-string constant operands. */ + length = 0; + for (pn2 = pn1; pn2; pn2 = pn2->pn_next) { + if (!FoldType(cx, pn2, TOK_STRING)) + return JS_FALSE; + /* XXX fold only if all operands convert to string */ + if (pn2->pn_type != TOK_STRING) + return JS_TRUE; + length += ATOM_TO_STRING(pn2->pn_atom)->length; + } + + /* Allocate a new buffer and string descriptor for the result. */ + chars = (jschar *) JS_malloc(cx, (length + 1) * sizeof(jschar)); + if (!chars) + return JS_FALSE; + str = js_NewString(cx, chars, length, 0); + if (!str) { + JS_free(cx, chars); + return JS_FALSE; + } + + /* Fill the buffer, advancing chars and recycling kids as we go. */ + for (pn2 = pn1; pn2; pn2 = pn3) { + str2 = ATOM_TO_STRING(pn2->pn_atom); + length2 = str2->length; + js_strncpy(chars, str2->chars, length2); + chars += length2; + pn3 = pn2->pn_next; + RecycleTree(pn2, tc); + } + *chars = 0; + + /* Atomize the result string and mutate pn to refer to it. */ + pn->pn_atom = js_AtomizeString(cx, str, 0); + if (!pn->pn_atom) + return JS_FALSE; + pn->pn_type = TOK_STRING; + pn->pn_op = JSOP_STRING; + pn->pn_arity = PN_NULLARY; + break; + } + + /* Handle a binary string concatenation. */ + JS_ASSERT(pn->pn_arity == PN_BINARY); + if (pn1->pn_type == TOK_STRING || pn2->pn_type == TOK_STRING) { + JSString *left, *right, *str; + + if (!FoldType(cx, (pn1->pn_type != TOK_STRING) ? pn1 : pn2, + TOK_STRING)) { + return JS_FALSE; + } + if (pn1->pn_type != TOK_STRING || pn2->pn_type != TOK_STRING) + return JS_TRUE; + left = ATOM_TO_STRING(pn1->pn_atom); + right = ATOM_TO_STRING(pn2->pn_atom); + str = js_ConcatStrings(cx, left, right); + if (!str) + return JS_FALSE; + pn->pn_atom = js_AtomizeString(cx, str, 0); + if (!pn->pn_atom) + return JS_FALSE; + pn->pn_type = TOK_STRING; + pn->pn_op = JSOP_STRING; + pn->pn_arity = PN_NULLARY; + RecycleTree(pn1, tc); + RecycleTree(pn2, tc); + break; + } + + /* Can't concatenate string literals, let's try numbers. */ + goto do_binary_op; + + case TOK_STAR: + /* The * in 'import *;' parses as a nullary star node. */ + if (pn->pn_arity == PN_NULLARY) + break; + /* FALL THROUGH */ + + case TOK_SHOP: + case TOK_MINUS: + case TOK_DIVOP: + do_binary_op: + if (pn->pn_arity == PN_LIST) { + JS_ASSERT(pn->pn_count > 2); + for (pn2 = pn1; pn2; pn2 = pn2->pn_next) { + if (!FoldType(cx, pn2, TOK_NUMBER)) + return JS_FALSE; + /* XXX fold only if all operands convert to number */ + if (pn2->pn_type != TOK_NUMBER) + break; + } + if (!pn2) { + JSOp op = pn->pn_op; + + pn2 = pn1->pn_next; + pn3 = pn2->pn_next; + if (!FoldBinaryNumeric(cx, op, pn1, pn2, pn, tc)) + return JS_FALSE; + while ((pn2 = pn3) != NULL) { + pn3 = pn2->pn_next; + if (!FoldBinaryNumeric(cx, op, pn, pn2, pn, tc)) + return JS_FALSE; + } + } + } else { + JS_ASSERT(pn->pn_arity == PN_BINARY); + if (!FoldType(cx, pn1, TOK_NUMBER) || + !FoldType(cx, pn2, TOK_NUMBER)) { + return JS_FALSE; + } + if (pn1->pn_type == TOK_NUMBER && pn2->pn_type == TOK_NUMBER) { + if (!FoldBinaryNumeric(cx, pn->pn_op, pn1, pn2, pn, tc)) + return JS_FALSE; + } + } + break; + + case TOK_UNARYOP: + if (pn1->pn_type == TOK_NUMBER) { + jsdouble d; + int32 i; + + /* Operate on one numeric constant. */ + d = pn1->pn_dval; + switch (pn->pn_op) { + case JSOP_BITNOT: + if (!js_DoubleToECMAInt32(cx, d, &i)) + return JS_FALSE; + d = ~i; + break; + + case JSOP_NEG: +#ifdef HPUX + /* + * Negation of a zero doesn't produce a negative + * zero on HPUX. Perform the operation by bit + * twiddling. + */ + JSDOUBLE_HI32(d) ^= JSDOUBLE_HI32_SIGNBIT; +#else + d = -d; +#endif + break; + + case JSOP_POS: + break; + + case JSOP_NOT: + pn->pn_type = TOK_PRIMARY; + pn->pn_op = (d == 0) ? JSOP_TRUE : JSOP_FALSE; + pn->pn_arity = PN_NULLARY; + /* FALL THROUGH */ + + default: + /* Return early to dodge the common TOK_NUMBER code. */ + return JS_TRUE; + } + pn->pn_type = TOK_NUMBER; + pn->pn_op = JSOP_NUMBER; + pn->pn_arity = PN_NULLARY; + pn->pn_dval = d; + RecycleTree(pn1, tc); + } + break; + + default:; + } + + return JS_TRUE; +} diff --git a/src/dom/js/jsparse.h b/src/dom/js/jsparse.h new file mode 100644 index 000000000..1c6ff893a --- /dev/null +++ b/src/dom/js/jsparse.h @@ -0,0 +1,337 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef jsparse_h___ +#define jsparse_h___ +/* + * JS parser definitions. + */ +#include "jsprvtd.h" +#include "jspubtd.h" +#include "jsscan.h" + +JS_BEGIN_EXTERN_C + +/* + * Parsing builds a tree of nodes that directs code generation. This tree is + * not a concrete syntax tree in all respects (for example, || and && are left + * associative, but (A && B && C) translates into the right-associated tree + * > so that code generation can emit a left-associative branch + * around when A is false). Nodes are labeled by token type, with a + * JSOp secondary label when needed: + * + * Label Variant Members + * ----- ------- ------- + * + * TOK_FUNCTION func pn_funAtom: atom holding function object containing + * arg and var properties. We create the function + * object at parse (not emit) time to specialize arg + * and var bytecodes early. + * pn_body: TOK_LC node for function body statements + * pn_flags: TCF_FUN_* flags (see jsemit.h) collected + * while parsing the function's body + * pn_tryCount: of try statements in function + * + * + * TOK_LC list pn_head: list of pn_count statements + * TOK_EXPORT list pn_head: list of pn_count TOK_NAMEs or one TOK_STAR + * (which is not a multiply node) + * TOK_IMPORT list pn_head: list of pn_count sub-trees of the form + * a.b.*, a[b].*, a.*, a.b, or a[b] -- but never a. + * Each member is expressed with TOK_DOT or TOK_LB. + * Each sub-tree's root node has a pn_op in the set + * JSOP_IMPORT{ALL,PROP,ELEM} + * TOK_IF ternary pn_kid1: cond, pn_kid2: then, pn_kid3: else or null + * TOK_SWITCH binary pn_left: discriminant + * pn_right: list of TOK_CASE nodes, with at most one + * TOK_DEFAULT node + * TOK_CASE, binary pn_left: case expr or null if TOK_DEFAULT + * TOK_DEFAULT pn_right: TOK_LC node for this case's statements + * TOK_WHILE binary pn_left: cond, pn_right: body + * TOK_DO binary pn_left: body, pn_right: cond + * TOK_FOR binary pn_left: either + * for/in loop: a binary TOK_IN node with + * pn_left: TOK_VAR or TOK_NAME to left of 'in' + * pn_right: object expr to right of 'in' + * for(;;) loop: a ternary TOK_RESERVED node with + * pn_kid1: init expr before first ';' + * pn_kid2: cond expr before second ';' + * pn_kid3: update expr after second ';' + * any kid may be null + * pn_right: body + * TOK_THROW unary pn_op: JSOP_THROW, pn_kid: exception + * TOK_TRY ternary pn_kid1: try block + * pn_kid2: catch blocks or null + * pn_kid3: finally block or null + * TOK_CATCH ternary pn_kid1: PN_NAME node for catch var (with pn_expr + * null or the catch guard expression) + * pn_kid2: more catch blocks or null + * pn_kid3: catch block statements + * TOK_BREAK name pn_atom: label or null + * TOK_CONTINUE name pn_atom: label or null + * TOK_WITH binary pn_left: head expr, pn_right: body + * TOK_VAR list pn_head: list of pn_count TOK_NAME nodes + * each name node has + * pn_atom: variable name + * pn_expr: initializer or null + * TOK_RETURN unary pn_kid: return expr or null + * TOK_SEMI unary pn_kid: expr or null statement + * TOK_COLON name pn_atom: label, pn_expr: labeled statement + * + * + * All left-associated binary trees of the same type are optimized into lists + * to avoid recursion when processing expression chains. + * TOK_COMMA list pn_head: list of pn_count comma-separated exprs + * TOK_ASSIGN binary pn_left: lvalue, pn_right: rvalue + * pn_op: JSOP_ADD for +=, etc. + * TOK_HOOK ternary pn_kid1: cond, pn_kid2: then, pn_kid3: else + * TOK_OR binary pn_left: first in || chain, pn_right: rest of chain + * TOK_AND binary pn_left: first in && chain, pn_right: rest of chain + * TOK_BITOR binary pn_left: left-assoc | expr, pn_right: ^ expr + * TOK_BITXOR binary pn_left: left-assoc ^ expr, pn_right: & expr + * TOK_BITAND binary pn_left: left-assoc & expr, pn_right: EQ expr + * TOK_EQOP binary pn_left: left-assoc EQ expr, pn_right: REL expr + * pn_op: JSOP_EQ, JSOP_NE, JSOP_NEW_EQ, JSOP_NEW_NE + * TOK_RELOP binary pn_left: left-assoc REL expr, pn_right: SH expr + * pn_op: JSOP_LT, JSOP_LE, JSOP_GT, JSOP_GE + * TOK_SHOP binary pn_left: left-assoc SH expr, pn_right: ADD expr + * pn_op: JSOP_LSH, JSOP_RSH, JSOP_URSH + * TOK_PLUS, binary pn_left: left-assoc ADD expr, pn_right: MUL expr + * pn_extra: if a left-associated binary TOK_PLUS + * tree has been flattened into a list (see above + * under ), pn_extra will contain + * PNX_STRCAT if at least one list element is a + * string literal (TOK_STRING); if such a list has + * any non-string, non-number term, pn_extra will + * contain PNX_CANTFOLD. + * pn_ + * TOK_MINUS pn_op: JSOP_ADD, JSOP_SUB + * TOK_STAR, binary pn_left: left-assoc MUL expr, pn_right: UNARY expr + * TOK_DIVOP pn_op: JSOP_MUL, JSOP_DIV, JSOP_MOD + * TOK_UNARYOP unary pn_kid: UNARY expr, pn_op: JSOP_NEG, JSOP_POS, + * JSOP_NOT, JSOP_BITNOT, JSOP_TYPEOF, JSOP_VOID + * TOK_INC, unary pn_kid: MEMBER expr + * TOK_DEC + * TOK_NEW list pn_head: list of ctor, arg1, arg2, ... argN + * pn_count: 1 + N (where N is number of args) + * ctor is a MEMBER expr + * TOK_DELETE unary pn_kid: MEMBER expr + * TOK_DOT name pn_expr: MEMBER expr to left of . + * pn_atom: name to right of . + * TOK_LB binary pn_left: MEMBER expr to left of [ + * pn_right: expr between [ and ] + * TOK_LP list pn_head: list of call, arg1, arg2, ... argN + * pn_count: 1 + N (where N is number of args) + * call is a MEMBER expr naming a callable object + * TOK_RB list pn_head: list of pn_count array element exprs + * [,,] holes are represented by TOK_COMMA nodes + * #n=[...] produces TOK_DEFSHARP at head of list + * pn_extra: true if extra comma at end + * TOK_RC list pn_head: list of pn_count TOK_COLON nodes where + * each has pn_left: property id, pn_right: value + * #n={...} produces TOK_DEFSHARP at head of list + * TOK_DEFSHARP unary pn_num: jsint value of n in #n= + * pn_kid: null for #n=[...] and #n={...}, primary + * if #n=primary for function, paren, name, object + * literal expressions + * TOK_USESHARP nullary pn_num: jsint value of n in #n# + * TOK_RP unary pn_kid: parenthesized expression + * TOK_NAME, name pn_atom: name, string, or object atom + * TOK_STRING, pn_op: JSOP_NAME, JSOP_STRING, or JSOP_OBJECT + * TOK_OBJECT If JSOP_NAME, pn_op may be JSOP_*ARG or JSOP_*VAR + * with pn_slot >= 0 and pn_attrs telling const-ness + * TOK_NUMBER dval pn_dval: double value of numeric literal + * TOK_PRIMARY nullary pn_op: JSOp bytecode + */ +typedef enum JSParseNodeArity { + PN_FUNC = -3, + PN_LIST = -2, + PN_TERNARY = 3, + PN_BINARY = 2, + PN_UNARY = 1, + PN_NAME = -1, + PN_NULLARY = 0 +} JSParseNodeArity; + +struct JSParseNode { + JSTokenType pn_type; + JSTokenPos pn_pos; + JSOp pn_op; + ptrdiff_t pn_offset; /* first generated bytecode offset */ + JSParseNodeArity pn_arity; + union { + struct { /* TOK_FUNCTION node */ + JSAtom *funAtom; /* atomized function object */ + JSParseNode *body; /* TOK_LC list of statements */ + uint32 flags; /* accumulated tree context flags */ + uint32 tryCount; /* count of try statements in body */ + } func; + struct { /* list of next-linked nodes */ + JSParseNode *head; /* first node in list */ + JSParseNode **tail; /* ptr to ptr to last node in list */ + uint32 count; /* number of nodes in list */ + uint32 extra; /* extra comma flag for [1,2,,] */ + } list; + struct { /* ternary: if, for(;;), ?: */ + JSParseNode *kid1; /* condition, discriminant, etc. */ + JSParseNode *kid2; /* then-part, case list, etc. */ + JSParseNode *kid3; /* else-part, default case, etc. */ + } ternary; + struct { /* two kids if binary */ + JSParseNode *left; + JSParseNode *right; + jsval val; /* switch case value */ + } binary; + struct { /* one kid if unary */ + JSParseNode *kid; + jsint num; /* -1 or sharp variable number */ + } unary; + struct { /* name, labeled statement, etc. */ + JSAtom *atom; /* name or label atom, null if slot */ + JSParseNode *expr; /* object or initializer */ + jsint slot; /* -1 or arg or local var slot */ + uintN attrs; /* attributes if local var or const */ + } name; + jsdouble dval; /* aligned numeric literal value */ + } pn_u; + JSParseNode *pn_next; /* to align dval and pn_u on RISCs */ +}; + +#define pn_funAtom pn_u.func.funAtom +#define pn_body pn_u.func.body +#define pn_flags pn_u.func.flags +#define pn_tryCount pn_u.func.tryCount +#define pn_head pn_u.list.head +#define pn_tail pn_u.list.tail +#define pn_count pn_u.list.count +#define pn_extra pn_u.list.extra +#define pn_kid1 pn_u.ternary.kid1 +#define pn_kid2 pn_u.ternary.kid2 +#define pn_kid3 pn_u.ternary.kid3 +#define pn_left pn_u.binary.left +#define pn_right pn_u.binary.right +#define pn_val pn_u.binary.val +#define pn_kid pn_u.unary.kid +#define pn_num pn_u.unary.num +#define pn_atom pn_u.name.atom +#define pn_expr pn_u.name.expr +#define pn_slot pn_u.name.slot +#define pn_attrs pn_u.name.attrs +#define pn_dval pn_u.dval + +/* PN_LIST pn_extra flags. */ +#define PNX_STRCAT 0x1 /* TOK_PLUS list has string term */ +#define PNX_CANTFOLD 0x2 /* TOK_PLUS list has unfoldable term */ + +/* + * Move pn2 into pn, preserving pn->pn_pos and pn->pn_offset and handing off + * any kids in pn2->pn_u, by clearing pn2. + */ +#define PN_MOVE_NODE(pn, pn2) \ + JS_BEGIN_MACRO \ + (pn)->pn_type = (pn2)->pn_type; \ + (pn)->pn_op = (pn2)->pn_op; \ + (pn)->pn_arity = (pn2)->pn_arity; \ + (pn)->pn_u = (pn2)->pn_u; \ + PN_CLEAR_NODE(pn2); \ + JS_END_MACRO + +#define PN_CLEAR_NODE(pn) \ + JS_BEGIN_MACRO \ + (pn)->pn_type = TOK_EOF; \ + (pn)->pn_op = JSOP_NOP; \ + (pn)->pn_arity = PN_NULLARY; \ + JS_END_MACRO + +/* True if pn is a parsenode representing a literal constant. */ +#define PN_IS_CONSTANT(pn) \ + ((pn)->pn_type == TOK_NUMBER || \ + (pn)->pn_type == TOK_STRING || \ + ((pn)->pn_type == TOK_PRIMARY && (pn)->pn_op != JSOP_THIS)) + +/* + * Compute a pointer to the last JSParseNode element in a singly-linked list. + * NB: list must be non-empty for correct PN_LAST usage! + */ +#define PN_LAST(list) \ + ((JSParseNode *)((char *)(list)->pn_tail - offsetof(JSParseNode, pn_next))) + +#define PN_INIT_LIST(list) \ + JS_BEGIN_MACRO \ + (list)->pn_head = NULL; \ + (list)->pn_tail = &(list)->pn_head; \ + (list)->pn_count = 0; \ + JS_END_MACRO + +#define PN_INIT_LIST_1(list, pn) \ + JS_BEGIN_MACRO \ + (list)->pn_head = (pn); \ + (list)->pn_tail = &(pn)->pn_next; \ + (list)->pn_count = 1; \ + JS_END_MACRO + +#define PN_APPEND(list, pn) \ + JS_BEGIN_MACRO \ + *(list)->pn_tail = (pn); \ + (list)->pn_tail = &(pn)->pn_next; \ + (list)->pn_count++; \ + JS_END_MACRO + +/* + * Parse a top-level JS script. + * + * The caller must prevent the GC from running while this function is active, + * because atoms and function newborns are not rooted yet. + */ +extern JS_FRIEND_API(JSParseNode *) +js_ParseTokenStream(JSContext *cx, JSObject *chain, JSTokenStream *ts); + +extern JS_FRIEND_API(JSBool) +js_CompileTokenStream(JSContext *cx, JSObject *chain, JSTokenStream *ts, + JSCodeGenerator *cg); + +extern JSBool +js_CompileFunctionBody(JSContext *cx, JSTokenStream *ts, JSFunction *fun); + +extern JSBool +js_FoldConstants(JSContext *cx, JSParseNode *pn, JSTreeContext *tc); + +JS_END_EXTERN_C + +#endif /* jsparse_h___ */ diff --git a/src/dom/js/jsprf.c b/src/dom/js/jsprf.c new file mode 100644 index 000000000..36bf92428 --- /dev/null +++ b/src/dom/js/jsprf.c @@ -0,0 +1,1212 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* +** Portable safe sprintf code. +** +** Author: Kipp E.B. Hickman +*/ +#include "jsstddef.h" +#include +#include +#include +#include +#include "jsprf.h" +#include "jslong.h" +#include "jsutil.h" /* Added by JSIFY */ + +/* +** Note: on some platforms va_list is defined as an array, +** and requires array notation. +*/ +#ifdef HAVE_VA_COPY +#define VARARGS_ASSIGN(foo, bar) VA_COPY(foo,bar) +#elif defined(HAVE_VA_LIST_AS_ARRAY) +#define VARARGS_ASSIGN(foo, bar) foo[0] = bar[0] +#else +#define VARARGS_ASSIGN(foo, bar) (foo) = (bar) +#endif + +/* +** WARNING: This code may *NOT* call JS_LOG (because JS_LOG calls it) +*/ + +/* +** XXX This needs to be internationalized! +*/ + +typedef struct SprintfStateStr SprintfState; + +struct SprintfStateStr { + int (*stuff)(SprintfState *ss, const char *sp, JSUint32 len); + + char *base; + char *cur; + JSUint32 maxlen; + + int (*func)(void *arg, const char *sp, JSUint32 len); + void *arg; +}; + +/* +** Numbered Arguement State +*/ +struct NumArgState{ + int type; /* type of the current ap */ + va_list ap; /* point to the corresponding position on ap */ +}; + +#define NAS_DEFAULT_NUM 20 /* default number of NumberedArgumentState array */ + + +#define TYPE_INT16 0 +#define TYPE_UINT16 1 +#define TYPE_INTN 2 +#define TYPE_UINTN 3 +#define TYPE_INT32 4 +#define TYPE_UINT32 5 +#define TYPE_INT64 6 +#define TYPE_UINT64 7 +#define TYPE_STRING 8 +#define TYPE_DOUBLE 9 +#define TYPE_INTSTR 10 +#define TYPE_UNKNOWN 20 + +#define FLAG_LEFT 0x1 +#define FLAG_SIGNED 0x2 +#define FLAG_SPACED 0x4 +#define FLAG_ZEROS 0x8 +#define FLAG_NEG 0x10 + +/* +** Fill into the buffer using the data in src +*/ +static int fill2(SprintfState *ss, const char *src, int srclen, int width, + int flags) +{ + char space = ' '; + int rv; + + width -= srclen; + if ((width > 0) && ((flags & FLAG_LEFT) == 0)) { /* Right adjusting */ + if (flags & FLAG_ZEROS) { + space = '0'; + } + while (--width >= 0) { + rv = (*ss->stuff)(ss, &space, 1); + if (rv < 0) { + return rv; + } + } + } + + /* Copy out the source data */ + rv = (*ss->stuff)(ss, src, (JSUint32)srclen); + if (rv < 0) { + return rv; + } + + if ((width > 0) && ((flags & FLAG_LEFT) != 0)) { /* Left adjusting */ + while (--width >= 0) { + rv = (*ss->stuff)(ss, &space, 1); + if (rv < 0) { + return rv; + } + } + } + return 0; +} + +/* +** Fill a number. The order is: optional-sign zero-filling conversion-digits +*/ +static int fill_n(SprintfState *ss, const char *src, int srclen, int width, + int prec, int type, int flags) +{ + int zerowidth = 0; + int precwidth = 0; + int signwidth = 0; + int leftspaces = 0; + int rightspaces = 0; + int cvtwidth; + int rv; + char sign; + + if ((type & 1) == 0) { + if (flags & FLAG_NEG) { + sign = '-'; + signwidth = 1; + } else if (flags & FLAG_SIGNED) { + sign = '+'; + signwidth = 1; + } else if (flags & FLAG_SPACED) { + sign = ' '; + signwidth = 1; + } + } + cvtwidth = signwidth + srclen; + + if (prec > 0) { + if (prec > srclen) { + precwidth = prec - srclen; /* Need zero filling */ + cvtwidth += precwidth; + } + } + + if ((flags & FLAG_ZEROS) && (prec < 0)) { + if (width > cvtwidth) { + zerowidth = width - cvtwidth; /* Zero filling */ + cvtwidth += zerowidth; + } + } + + if (flags & FLAG_LEFT) { + if (width > cvtwidth) { + /* Space filling on the right (i.e. left adjusting) */ + rightspaces = width - cvtwidth; + } + } else { + if (width > cvtwidth) { + /* Space filling on the left (i.e. right adjusting) */ + leftspaces = width - cvtwidth; + } + } + while (--leftspaces >= 0) { + rv = (*ss->stuff)(ss, " ", 1); + if (rv < 0) { + return rv; + } + } + if (signwidth) { + rv = (*ss->stuff)(ss, &sign, 1); + if (rv < 0) { + return rv; + } + } + while (--precwidth >= 0) { + rv = (*ss->stuff)(ss, "0", 1); + if (rv < 0) { + return rv; + } + } + while (--zerowidth >= 0) { + rv = (*ss->stuff)(ss, "0", 1); + if (rv < 0) { + return rv; + } + } + rv = (*ss->stuff)(ss, src, (JSUint32)srclen); + if (rv < 0) { + return rv; + } + while (--rightspaces >= 0) { + rv = (*ss->stuff)(ss, " ", 1); + if (rv < 0) { + return rv; + } + } + return 0; +} + +/* +** Convert a long into its printable form +*/ +static int cvt_l(SprintfState *ss, long num, int width, int prec, int radix, + int type, int flags, const char *hexp) +{ + char cvtbuf[100]; + char *cvt; + int digits; + + /* according to the man page this needs to happen */ + if ((prec == 0) && (num == 0)) { + return 0; + } + + /* + ** Converting decimal is a little tricky. In the unsigned case we + ** need to stop when we hit 10 digits. In the signed case, we can + ** stop when the number is zero. + */ + cvt = cvtbuf + sizeof(cvtbuf); + digits = 0; + while (num) { + int digit = (((unsigned long)num) % radix) & 0xF; + *--cvt = hexp[digit]; + digits++; + num = (long)(((unsigned long)num) / radix); + } + if (digits == 0) { + *--cvt = '0'; + digits++; + } + + /* + ** Now that we have the number converted without its sign, deal with + ** the sign and zero padding. + */ + return fill_n(ss, cvt, digits, width, prec, type, flags); +} + +/* +** Convert a 64-bit integer into its printable form +*/ +static int cvt_ll(SprintfState *ss, JSInt64 num, int width, int prec, int radix, + int type, int flags, const char *hexp) +{ + char cvtbuf[100]; + char *cvt; + int digits; + JSInt64 rad; + + /* according to the man page this needs to happen */ + if ((prec == 0) && (JSLL_IS_ZERO(num))) { + return 0; + } + + /* + ** Converting decimal is a little tricky. In the unsigned case we + ** need to stop when we hit 10 digits. In the signed case, we can + ** stop when the number is zero. + */ + JSLL_I2L(rad, radix); + cvt = cvtbuf + sizeof(cvtbuf); + digits = 0; + while (!JSLL_IS_ZERO(num)) { + JSInt32 digit; + JSInt64 quot, rem; + JSLL_UDIVMOD(", &rem, num, rad); + JSLL_L2I(digit, rem); + *--cvt = hexp[digit & 0xf]; + digits++; + num = quot; + } + if (digits == 0) { + *--cvt = '0'; + digits++; + } + + /* + ** Now that we have the number converted without its sign, deal with + ** the sign and zero padding. + */ + return fill_n(ss, cvt, digits, width, prec, type, flags); +} + +/* +** Convert a double precision floating point number into its printable +** form. +** +** XXX stop using sprintf to convert floating point +*/ +static int cvt_f(SprintfState *ss, double d, const char *fmt0, const char *fmt1) +{ + char fin[20]; + char fout[300]; + int amount = fmt1 - fmt0; + + JS_ASSERT((amount > 0) && (amount < (int)sizeof(fin))); + if (amount >= (int)sizeof(fin)) { + /* Totally bogus % command to sprintf. Just ignore it */ + return 0; + } + memcpy(fin, fmt0, (size_t)amount); + fin[amount] = 0; + + /* Convert floating point using the native sprintf code */ +#ifdef DEBUG + { + const char *p = fin; + while (*p) { + JS_ASSERT(*p != 'L'); + p++; + } + } +#endif + sprintf(fout, fin, d); + + /* + ** This assert will catch overflow's of fout, when building with + ** debugging on. At least this way we can track down the evil piece + ** of calling code and fix it! + */ + JS_ASSERT(strlen(fout) < sizeof(fout)); + + return (*ss->stuff)(ss, fout, strlen(fout)); +} + +/* +** Convert a string into its printable form. "width" is the output +** width. "prec" is the maximum number of characters of "s" to output, +** where -1 means until NUL. +*/ +static int cvt_s(SprintfState *ss, const char *s, int width, int prec, + int flags) +{ + int slen; + + if (prec == 0) + return 0; + + /* Limit string length by precision value */ + slen = s ? strlen(s) : 6; + if (prec > 0) { + if (prec < slen) { + slen = prec; + } + } + + /* and away we go */ + return fill2(ss, s ? s : "(null)", slen, width, flags); +} + +/* +** BiuldArgArray stands for Numbered Argument list Sprintf +** for example, +** fmp = "%4$i, %2$d, %3s, %1d"; +** the number must start from 1, and no gap among them +*/ + +static struct NumArgState* BuildArgArray( const char *fmt, va_list ap, int* rv, struct NumArgState* nasArray ) +{ + int number = 0, cn = 0, i; + const char* p; + char c; + struct NumArgState* nas; + + + /* + ** first pass: + ** detemine how many legal % I have got, then allocate space + */ + + p = fmt; + *rv = 0; + i = 0; + while( ( c = *p++ ) != 0 ){ + if( c != '%' ) + continue; + if( ( c = *p++ ) == '%' ) /* skip %% case */ + continue; + + while( c != 0 ){ + if( c > '9' || c < '0' ){ + if( c == '$' ){ /* numbered argument csae */ + if( i > 0 ){ + *rv = -1; + return NULL; + } + number++; + } else { /* non-numbered argument case */ + if( number > 0 ){ + *rv = -1; + return NULL; + } + i = 1; + } + break; + } + + c = *p++; + } + } + + if( number == 0 ){ + return NULL; + } + + + if( number > NAS_DEFAULT_NUM ){ + nas = (struct NumArgState*)malloc( number * sizeof( struct NumArgState ) ); + if( !nas ){ + *rv = -1; + return NULL; + } + } else { + nas = nasArray; + } + + for( i = 0; i < number; i++ ){ + nas[i].type = TYPE_UNKNOWN; + } + + + /* + ** second pass: + ** set nas[].type + */ + + p = fmt; + while( ( c = *p++ ) != 0 ){ + if( c != '%' ) continue; + c = *p++; + if( c == '%' ) continue; + + cn = 0; + while( c && c != '$' ){ /* should imporve error check later */ + cn = cn*10 + c - '0'; + c = *p++; + } + + if( !c || cn < 1 || cn > number ){ + *rv = -1; + break; + } + + /* nas[cn] starts from 0, and make sure nas[cn].type is not assigned */ + cn--; + if( nas[cn].type != TYPE_UNKNOWN ) + continue; + + c = *p++; + + /* width */ + if (c == '*') { + /* not supported feature, for the argument is not numbered */ + *rv = -1; + break; + } + + while ((c >= '0') && (c <= '9')) { + c = *p++; + } + + /* precision */ + if (c == '.') { + c = *p++; + if (c == '*') { + /* not supported feature, for the argument is not numbered */ + *rv = -1; + break; + } + + while ((c >= '0') && (c <= '9')) { + c = *p++; + } + } + + /* size */ + nas[cn].type = TYPE_INTN; + if (c == 'h') { + nas[cn].type = TYPE_INT16; + c = *p++; + } else if (c == 'L') { + /* XXX not quite sure here */ + nas[cn].type = TYPE_INT64; + c = *p++; + } else if (c == 'l') { + nas[cn].type = TYPE_INT32; + c = *p++; + if (c == 'l') { + nas[cn].type = TYPE_INT64; + c = *p++; + } + } + + /* format */ + switch (c) { + case 'd': + case 'c': + case 'i': + case 'o': + case 'u': + case 'x': + case 'X': + break; + + case 'e': + case 'f': + case 'g': + nas[ cn ].type = TYPE_DOUBLE; + break; + + case 'p': + /* XXX should use cpp */ + if (sizeof(void *) == sizeof(JSInt32)) { + nas[ cn ].type = TYPE_UINT32; + } else if (sizeof(void *) == sizeof(JSInt64)) { + nas[ cn ].type = TYPE_UINT64; + } else if (sizeof(void *) == sizeof(JSIntn)) { + nas[ cn ].type = TYPE_UINTN; + } else { + nas[ cn ].type = TYPE_UNKNOWN; + } + break; + + case 'C': + case 'S': + case 'E': + case 'G': + /* XXX not supported I suppose */ + JS_ASSERT(0); + nas[ cn ].type = TYPE_UNKNOWN; + break; + + case 's': + nas[ cn ].type = TYPE_STRING; + break; + + case 'n': + nas[ cn ].type = TYPE_INTSTR; + break; + + default: + JS_ASSERT(0); + nas[ cn ].type = TYPE_UNKNOWN; + break; + } + + /* get a legal para. */ + if( nas[ cn ].type == TYPE_UNKNOWN ){ + *rv = -1; + break; + } + } + + + /* + ** third pass + ** fill the nas[cn].ap + */ + + if( *rv < 0 ){ + if( nas != nasArray ) + JS_DELETE( nas ); + return NULL; + } + + cn = 0; + while( cn < number ){ + if( nas[cn].type == TYPE_UNKNOWN ){ + cn++; + continue; + } + + VARARGS_ASSIGN(nas[cn].ap, ap); + + switch( nas[cn].type ){ + case TYPE_INT16: + case TYPE_UINT16: + case TYPE_INTN: + case TYPE_UINTN: (void)va_arg( ap, JSIntn ); break; + + case TYPE_INT32: (void)va_arg( ap, JSInt32 ); break; + + case TYPE_UINT32: (void)va_arg( ap, JSUint32 ); break; + + case TYPE_INT64: (void)va_arg( ap, JSInt64 ); break; + + case TYPE_UINT64: (void)va_arg( ap, JSUint64 ); break; + + case TYPE_STRING: (void)va_arg( ap, char* ); break; + + case TYPE_INTSTR: (void)va_arg( ap, JSIntn* ); break; + + case TYPE_DOUBLE: (void)va_arg( ap, double ); break; + + default: + if( nas != nasArray ) + JS_DELETE( nas ); + *rv = -1; + return NULL; + } + + cn++; + } + + + return nas; +} + +/* +** The workhorse sprintf code. +*/ +static int dosprintf(SprintfState *ss, const char *fmt, va_list ap) +{ + char c; + int flags, width, prec, radix, type; + union { + char ch; + int i; + long l; + JSInt64 ll; + double d; + const char *s; + int *ip; + } u; + const char *fmt0; + static char *hex = "0123456789abcdef"; + static char *HEX = "0123456789ABCDEF"; + char *hexp; + int rv, i; + struct NumArgState* nas = NULL; + struct NumArgState nasArray[ NAS_DEFAULT_NUM ]; + char pattern[20]; + const char* dolPt = NULL; /* in "%4$.2f", dolPt will poiont to . */ + + + /* + ** build an argument array, IF the fmt is numbered argument + ** list style, to contain the Numbered Argument list pointers + */ + + nas = BuildArgArray( fmt, ap, &rv, nasArray ); + if( rv < 0 ){ + /* the fmt contains error Numbered Argument format, jliu@netscape.com */ + JS_ASSERT(0); + return rv; + } + + while ((c = *fmt++) != 0) { + if (c != '%') { + rv = (*ss->stuff)(ss, fmt - 1, 1); + if (rv < 0) { + return rv; + } + continue; + } + fmt0 = fmt - 1; + + /* + ** Gobble up the % format string. Hopefully we have handled all + ** of the strange cases! + */ + flags = 0; + c = *fmt++; + if (c == '%') { + /* quoting a % with %% */ + rv = (*ss->stuff)(ss, fmt - 1, 1); + if (rv < 0) { + return rv; + } + continue; + } + + if( nas != NULL ){ + /* the fmt contains the Numbered Arguments feature */ + i = 0; + while( c && c != '$' ){ /* should imporve error check later */ + i = ( i * 10 ) + ( c - '0' ); + c = *fmt++; + } + + if( nas[i-1].type == TYPE_UNKNOWN ){ + if( nas && ( nas != nasArray ) ) + JS_DELETE( nas ); + return -1; + } + + ap = nas[i-1].ap; + dolPt = fmt; + c = *fmt++; + } + + /* + * Examine optional flags. Note that we do not implement the + * '#' flag of sprintf(). The ANSI C spec. of the '#' flag is + * somewhat ambiguous and not ideal, which is perhaps why + * the various sprintf() implementations are inconsistent + * on this feature. + */ + while ((c == '-') || (c == '+') || (c == ' ') || (c == '0')) { + if (c == '-') flags |= FLAG_LEFT; + if (c == '+') flags |= FLAG_SIGNED; + if (c == ' ') flags |= FLAG_SPACED; + if (c == '0') flags |= FLAG_ZEROS; + c = *fmt++; + } + if (flags & FLAG_SIGNED) flags &= ~FLAG_SPACED; + if (flags & FLAG_LEFT) flags &= ~FLAG_ZEROS; + + /* width */ + if (c == '*') { + c = *fmt++; + width = va_arg(ap, int); + } else { + width = 0; + while ((c >= '0') && (c <= '9')) { + width = (width * 10) + (c - '0'); + c = *fmt++; + } + } + + /* precision */ + prec = -1; + if (c == '.') { + c = *fmt++; + if (c == '*') { + c = *fmt++; + prec = va_arg(ap, int); + } else { + prec = 0; + while ((c >= '0') && (c <= '9')) { + prec = (prec * 10) + (c - '0'); + c = *fmt++; + } + } + } + + /* size */ + type = TYPE_INTN; + if (c == 'h') { + type = TYPE_INT16; + c = *fmt++; + } else if (c == 'L') { + /* XXX not quite sure here */ + type = TYPE_INT64; + c = *fmt++; + } else if (c == 'l') { + type = TYPE_INT32; + c = *fmt++; + if (c == 'l') { + type = TYPE_INT64; + c = *fmt++; + } + } + + /* format */ + hexp = hex; + switch (c) { + case 'd': case 'i': /* decimal/integer */ + radix = 10; + goto fetch_and_convert; + + case 'o': /* octal */ + radix = 8; + type |= 1; + goto fetch_and_convert; + + case 'u': /* unsigned decimal */ + radix = 10; + type |= 1; + goto fetch_and_convert; + + case 'x': /* unsigned hex */ + radix = 16; + type |= 1; + goto fetch_and_convert; + + case 'X': /* unsigned HEX */ + radix = 16; + hexp = HEX; + type |= 1; + goto fetch_and_convert; + + fetch_and_convert: + switch (type) { + case TYPE_INT16: + u.l = va_arg(ap, int); + if (u.l < 0) { + u.l = -u.l; + flags |= FLAG_NEG; + } + goto do_long; + case TYPE_UINT16: + u.l = va_arg(ap, int) & 0xffff; + goto do_long; + case TYPE_INTN: + u.l = va_arg(ap, int); + if (u.l < 0) { + u.l = -u.l; + flags |= FLAG_NEG; + } + goto do_long; + case TYPE_UINTN: + u.l = (long)va_arg(ap, unsigned int); + goto do_long; + + case TYPE_INT32: + u.l = va_arg(ap, JSInt32); + if (u.l < 0) { + u.l = -u.l; + flags |= FLAG_NEG; + } + goto do_long; + case TYPE_UINT32: + u.l = (long)va_arg(ap, JSUint32); + do_long: + rv = cvt_l(ss, u.l, width, prec, radix, type, flags, hexp); + if (rv < 0) { + return rv; + } + break; + + case TYPE_INT64: + u.ll = va_arg(ap, JSInt64); + if (!JSLL_GE_ZERO(u.ll)) { + JSLL_NEG(u.ll, u.ll); + flags |= FLAG_NEG; + } + goto do_longlong; + case TYPE_UINT64: + u.ll = va_arg(ap, JSUint64); + do_longlong: + rv = cvt_ll(ss, u.ll, width, prec, radix, type, flags, hexp); + if (rv < 0) { + return rv; + } + break; + } + break; + + case 'e': + case 'E': + case 'f': + case 'g': + u.d = va_arg(ap, double); + if( nas != NULL ){ + i = fmt - dolPt; + if( i < (int)sizeof( pattern ) ){ + pattern[0] = '%'; + memcpy( &pattern[1], dolPt, (size_t)i ); + rv = cvt_f(ss, u.d, pattern, &pattern[i+1] ); + } + } else + rv = cvt_f(ss, u.d, fmt0, fmt); + + if (rv < 0) { + return rv; + } + break; + + case 'c': + u.ch = va_arg(ap, int); + if ((flags & FLAG_LEFT) == 0) { + while (width-- > 1) { + rv = (*ss->stuff)(ss, " ", 1); + if (rv < 0) { + return rv; + } + } + } + rv = (*ss->stuff)(ss, &u.ch, 1); + if (rv < 0) { + return rv; + } + if (flags & FLAG_LEFT) { + while (width-- > 1) { + rv = (*ss->stuff)(ss, " ", 1); + if (rv < 0) { + return rv; + } + } + } + break; + + case 'p': + if (sizeof(void *) == sizeof(JSInt32)) { + type = TYPE_UINT32; + } else if (sizeof(void *) == sizeof(JSInt64)) { + type = TYPE_UINT64; + } else if (sizeof(void *) == sizeof(int)) { + type = TYPE_UINTN; + } else { + JS_ASSERT(0); + break; + } + radix = 16; + goto fetch_and_convert; + +#if 0 + case 'C': + case 'S': + case 'E': + case 'G': + /* XXX not supported I suppose */ + JS_ASSERT(0); + break; +#endif + + case 's': + u.s = va_arg(ap, const char*); + rv = cvt_s(ss, u.s, width, prec, flags); + if (rv < 0) { + return rv; + } + break; + + case 'n': + u.ip = va_arg(ap, int*); + if (u.ip) { + *u.ip = ss->cur - ss->base; + } + break; + + default: + /* Not a % token after all... skip it */ +#if 0 + JS_ASSERT(0); +#endif + rv = (*ss->stuff)(ss, "%", 1); + if (rv < 0) { + return rv; + } + rv = (*ss->stuff)(ss, fmt - 1, 1); + if (rv < 0) { + return rv; + } + } + } + + /* Stuff trailing NUL */ + rv = (*ss->stuff)(ss, "\0", 1); + + if( nas && ( nas != nasArray ) ){ + JS_DELETE( nas ); + } + + return rv; +} + +/************************************************************************/ + +static int FuncStuff(SprintfState *ss, const char *sp, JSUint32 len) +{ + int rv; + + rv = (*ss->func)(ss->arg, sp, len); + if (rv < 0) { + return rv; + } + ss->maxlen += len; + return 0; +} + +JS_PUBLIC_API(JSUint32) JS_sxprintf(JSStuffFunc func, void *arg, + const char *fmt, ...) +{ + va_list ap; + int rv; + + va_start(ap, fmt); + rv = JS_vsxprintf(func, arg, fmt, ap); + va_end(ap); + return rv; +} + +JS_PUBLIC_API(JSUint32) JS_vsxprintf(JSStuffFunc func, void *arg, + const char *fmt, va_list ap) +{ + SprintfState ss; + int rv; + + ss.stuff = FuncStuff; + ss.func = func; + ss.arg = arg; + ss.maxlen = 0; + rv = dosprintf(&ss, fmt, ap); + return (rv < 0) ? (JSUint32)-1 : ss.maxlen; +} + +/* +** Stuff routine that automatically grows the malloc'd output buffer +** before it overflows. +*/ +static int GrowStuff(SprintfState *ss, const char *sp, JSUint32 len) +{ + ptrdiff_t off; + char *newbase; + JSUint32 newlen; + + off = ss->cur - ss->base; + if (off + len >= ss->maxlen) { + /* Grow the buffer */ + newlen = ss->maxlen + ((len > 32) ? len : 32); + if (ss->base) { + newbase = (char*) realloc(ss->base, newlen); + } else { + newbase = (char*) malloc(newlen); + } + if (!newbase) { + /* Ran out of memory */ + return -1; + } + ss->base = newbase; + ss->maxlen = newlen; + ss->cur = ss->base + off; + } + + /* Copy data */ + while (len) { + --len; + *ss->cur++ = *sp++; + } + JS_ASSERT((JSUint32)(ss->cur - ss->base) <= ss->maxlen); + return 0; +} + +/* +** sprintf into a malloc'd buffer +*/ +JS_PUBLIC_API(char *) JS_smprintf(const char *fmt, ...) +{ + va_list ap; + char *rv; + + va_start(ap, fmt); + rv = JS_vsmprintf(fmt, ap); + va_end(ap); + return rv; +} + +/* +** Free memory allocated, for the caller, by JS_smprintf +*/ +JS_PUBLIC_API(void) JS_smprintf_free(char *mem) +{ + JS_DELETE(mem); +} + +JS_PUBLIC_API(char *) JS_vsmprintf(const char *fmt, va_list ap) +{ + SprintfState ss; + int rv; + + ss.stuff = GrowStuff; + ss.base = 0; + ss.cur = 0; + ss.maxlen = 0; + rv = dosprintf(&ss, fmt, ap); + if (rv < 0) { + if (ss.base) { + JS_DELETE(ss.base); + } + return 0; + } + return ss.base; +} + +/* +** Stuff routine that discards overflow data +*/ +static int LimitStuff(SprintfState *ss, const char *sp, JSUint32 len) +{ + JSUint32 limit = ss->maxlen - (ss->cur - ss->base); + + if (len > limit) { + len = limit; + } + while (len) { + --len; + *ss->cur++ = *sp++; + } + return 0; +} + +/* +** sprintf into a fixed size buffer. Make sure there is a NUL at the end +** when finished. +*/ +JS_PUBLIC_API(JSUint32) JS_snprintf(char *out, JSUint32 outlen, const char *fmt, ...) +{ + va_list ap; + int rv; + + JS_ASSERT((JSInt32)outlen > 0); + if ((JSInt32)outlen <= 0) { + return 0; + } + + va_start(ap, fmt); + rv = JS_vsnprintf(out, outlen, fmt, ap); + va_end(ap); + return rv; +} + +JS_PUBLIC_API(JSUint32) JS_vsnprintf(char *out, JSUint32 outlen,const char *fmt, + va_list ap) +{ + SprintfState ss; + JSUint32 n; + + JS_ASSERT((JSInt32)outlen > 0); + if ((JSInt32)outlen <= 0) { + return 0; + } + + ss.stuff = LimitStuff; + ss.base = out; + ss.cur = out; + ss.maxlen = outlen; + (void) dosprintf(&ss, fmt, ap); + + /* If we added chars, and we didn't append a null, do it now. */ + if( (ss.cur != ss.base) && (*(ss.cur - 1) != '\0') ) + *(--ss.cur) = '\0'; + + n = ss.cur - ss.base; + return n ? n - 1 : n; +} + +JS_PUBLIC_API(char *) JS_sprintf_append(char *last, const char *fmt, ...) +{ + va_list ap; + char *rv; + + va_start(ap, fmt); + rv = JS_vsprintf_append(last, fmt, ap); + va_end(ap); + return rv; +} + +JS_PUBLIC_API(char *) JS_vsprintf_append(char *last, const char *fmt, va_list ap) +{ + SprintfState ss; + int rv; + + ss.stuff = GrowStuff; + if (last) { + int lastlen = strlen(last); + ss.base = last; + ss.cur = last + lastlen; + ss.maxlen = lastlen; + } else { + ss.base = 0; + ss.cur = 0; + ss.maxlen = 0; + } + rv = dosprintf(&ss, fmt, ap); + if (rv < 0) { + if (ss.base) { + JS_DELETE(ss.base); + } + return 0; + } + return ss.base; +} + diff --git a/src/dom/js/jsprf.h b/src/dom/js/jsprf.h new file mode 100644 index 000000000..e8cc46c0c --- /dev/null +++ b/src/dom/js/jsprf.h @@ -0,0 +1,148 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef jsprf_h___ +#define jsprf_h___ + +/* +** API for PR printf like routines. Supports the following formats +** %d - decimal +** %u - unsigned decimal +** %x - unsigned hex +** %X - unsigned uppercase hex +** %o - unsigned octal +** %hd, %hu, %hx, %hX, %ho - 16-bit versions of above +** %ld, %lu, %lx, %lX, %lo - 32-bit versions of above +** %lld, %llu, %llx, %llX, %llo - 64 bit versions of above +** %s - string +** %c - character +** %p - pointer (deals with machine dependent pointer size) +** %f - float +** %g - float +*/ +#include "jstypes.h" +#include +#include + +JS_BEGIN_EXTERN_C + +/* +** sprintf into a fixed size buffer. Guarantees that a NUL is at the end +** of the buffer. Returns the length of the written output, NOT including +** the NUL, or (JSUint32)-1 if an error occurs. +*/ +extern JS_PUBLIC_API(JSUint32) JS_snprintf(char *out, JSUint32 outlen, const char *fmt, ...); + +/* +** sprintf into a malloc'd buffer. Return a pointer to the malloc'd +** buffer on success, NULL on failure. Call "JS_smprintf_free" to release +** the memory returned. +*/ +extern JS_PUBLIC_API(char*) JS_smprintf(const char *fmt, ...); + +/* +** Free the memory allocated, for the caller, by JS_smprintf +*/ +extern JS_PUBLIC_API(void) JS_smprintf_free(char *mem); + +/* +** "append" sprintf into a malloc'd buffer. "last" is the last value of +** the malloc'd buffer. sprintf will append data to the end of last, +** growing it as necessary using realloc. If last is NULL, JS_sprintf_append +** will allocate the initial string. The return value is the new value of +** last for subsequent calls, or NULL if there is a malloc failure. +*/ +extern JS_PUBLIC_API(char*) JS_sprintf_append(char *last, const char *fmt, ...); + +/* +** sprintf into a function. The function "f" is called with a string to +** place into the output. "arg" is an opaque pointer used by the stuff +** function to hold any state needed to do the storage of the output +** data. The return value is a count of the number of characters fed to +** the stuff function, or (JSUint32)-1 if an error occurs. +*/ +typedef JSIntn (*JSStuffFunc)(void *arg, const char *s, JSUint32 slen); + +extern JS_PUBLIC_API(JSUint32) JS_sxprintf(JSStuffFunc f, void *arg, const char *fmt, ...); + +/* +** va_list forms of the above. +*/ +extern JS_PUBLIC_API(JSUint32) JS_vsnprintf(char *out, JSUint32 outlen, const char *fmt, va_list ap); +extern JS_PUBLIC_API(char*) JS_vsmprintf(const char *fmt, va_list ap); +extern JS_PUBLIC_API(char*) JS_vsprintf_append(char *last, const char *fmt, va_list ap); +extern JS_PUBLIC_API(JSUint32) JS_vsxprintf(JSStuffFunc f, void *arg, const char *fmt, va_list ap); + +/* +*************************************************************************** +** FUNCTION: JS_sscanf +** DESCRIPTION: +** JS_sscanf() scans the input character string, performs data +** conversions, and stores the converted values in the data objects +** pointed to by its arguments according to the format control +** string. +** +** JS_sscanf() behaves the same way as the sscanf() function in the +** Standard C Library (stdio.h), with the following exceptions: +** - JS_sscanf() handles the NSPR integer and floating point types, +** such as JSInt16, JSInt32, JSInt64, and JSFloat64, whereas +** sscanf() handles the standard C types like short, int, long, +** and double. +** - JS_sscanf() has no multibyte character support, while sscanf() +** does. +** INPUTS: +** const char *buf +** a character string holding the input to scan +** const char *fmt +** the format control string for the conversions +** ... +** variable number of arguments, each of them is a pointer to +** a data object in which the converted value will be stored +** OUTPUTS: none +** RETURNS: JSInt32 +** The number of values converted and stored. +** RESTRICTIONS: +** Multibyte characters in 'buf' or 'fmt' are not allowed. +*************************************************************************** +*/ + +extern JS_PUBLIC_API(JSInt32) JS_sscanf(const char *buf, const char *fmt, ...); + +JS_END_EXTERN_C + +#endif /* jsprf_h___ */ diff --git a/src/dom/js/jsprvtd.h b/src/dom/js/jsprvtd.h new file mode 100644 index 000000000..f5f1e77f6 --- /dev/null +++ b/src/dom/js/jsprvtd.h @@ -0,0 +1,174 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef jsprvtd_h___ +#define jsprvtd_h___ +/* + * JS private typename definitions. + * + * This header is included only in other .h files, for convenience and for + * simplicity of type naming. The alternative for structures is to use tags, + * which are named the same as their typedef names (legal in C/C++, and less + * noisy than suffixing the typedef name with "Struct" or "Str"). Instead, + * all .h files that include this file may use the same typedef name, whether + * declaring a pointer to struct type, or defining a member of struct type. + * + * A few fundamental scalar types are defined here too. Neither the scalar + * nor the struct typedefs should change much, therefore the nearly-global + * make dependency induced by this file should not prove painful. + */ + +#include "jspubtd.h" + +/* Scalar typedefs. */ +typedef uint8 jsbytecode; +typedef uint8 jssrcnote; +typedef uint32 jsatomid; + +/* Struct typedefs. */ +typedef struct JSArgumentFormatMap JSArgumentFormatMap; +typedef struct JSCodeGenerator JSCodeGenerator; +typedef struct JSDependentString JSDependentString; +typedef struct JSGCLockHashEntry JSGCLockHashEntry; +typedef struct JSGCRootHashEntry JSGCRootHashEntry; +typedef struct JSGCThing JSGCThing; +typedef struct JSParseNode JSParseNode; +typedef struct JSSharpObjectMap JSSharpObjectMap; +typedef struct JSToken JSToken; +typedef struct JSTokenPos JSTokenPos; +typedef struct JSTokenPtr JSTokenPtr; +typedef struct JSTokenStream JSTokenStream; +typedef struct JSTreeContext JSTreeContext; +typedef struct JSTryNote JSTryNote; + +/* Friend "Advanced API" typedefs. */ +typedef struct JSAtom JSAtom; +typedef struct JSAtomList JSAtomList; +typedef struct JSAtomListElement JSAtomListElement; +typedef struct JSAtomMap JSAtomMap; +typedef struct JSAtomState JSAtomState; +typedef struct JSCodeSpec JSCodeSpec; +typedef struct JSPrinter JSPrinter; +typedef struct JSRegExp JSRegExp; +typedef struct JSRegExpStatics JSRegExpStatics; +typedef struct JSScope JSScope; +typedef struct JSScopeOps JSScopeOps; +typedef struct JSScopeProperty JSScopeProperty; +typedef struct JSStackFrame JSStackFrame; +typedef struct JSStackHeader JSStackHeader; +typedef struct JSSubString JSSubString; + +/* "Friend" types used by jscntxt.h and jsdbgapi.h. */ +typedef enum JSTrapStatus { + JSTRAP_ERROR, + JSTRAP_CONTINUE, + JSTRAP_RETURN, + JSTRAP_THROW, + JSTRAP_LIMIT +} JSTrapStatus; + +typedef JSTrapStatus +(* JS_DLL_CALLBACK JSTrapHandler)(JSContext *cx, JSScript *script, jsbytecode *pc, + jsval *rval, void *closure); + +typedef JSBool +(* JS_DLL_CALLBACK JSWatchPointHandler)(JSContext *cx, JSObject *obj, jsval id, + jsval old, jsval *newp, void *closure); + +/* called just after script creation */ +typedef void +(* JS_DLL_CALLBACK JSNewScriptHook)(JSContext *cx, + const char *filename, /* URL of script */ + uintN lineno, /* line script starts */ + JSScript *script, + JSFunction *fun, + void *callerdata); + +/* called just before script destruction */ +typedef void +(* JS_DLL_CALLBACK JSDestroyScriptHook)(JSContext *cx, + JSScript *script, + void *callerdata); + +typedef void +(* JS_DLL_CALLBACK JSSourceHandler)(const char *filename, uintN lineno, + jschar *str, size_t length, + void **listenerTSData, void *closure); + +/* +* This hook captures high level script execution and function calls +* (JS or native). +* It is used by JS_SetExecuteHook to hook top level scripts and by +* JS_SetCallHook to hook function calls. +* It will get called twice per script or function call: +* just before execution begins and just after it finishes. In both cases +* the 'current' frame is that of the executing code. +* +* The 'before' param is JS_TRUE for the hook invocation before the execution +* and JS_FALSE for the invocation after the code has run. +* +* The 'ok' param is significant only on the post execution invocation to +* signify whether or not the code completed 'normally'. +* +* The 'closure' param is as passed to JS_SetExecuteHook or JS_SetCallHook +* for the 'before'invocation, but is whatever value is returned from that +* invocation for the 'after' invocation. Thus, the hook implementor *could* +* allocate a stucture in the 'before' invocation and return a pointer +* to that structure. The pointer would then be handed to the hook for +* the 'after' invocation. Alternately, the 'before' could just return the +* same value as in 'closure' to cause the 'after' invocation to be called +* with the same 'closure' value as the 'before'. +* +* Returning NULL in the 'before' hook will cause the 'after' hook to +* NOT be called. +*/ + +typedef void * +(* JS_DLL_CALLBACK JSInterpreterHook)(JSContext *cx, JSStackFrame *fp, JSBool before, + JSBool *ok, void *closure); + +typedef void +(* JS_DLL_CALLBACK JSObjectHook)(JSContext *cx, JSObject *obj, JSBool isNew, + void *closure); + +typedef JSBool +(* JS_DLL_CALLBACK JSDebugErrorHook)(JSContext *cx, const char *message, + JSErrorReport *report, void *closure); + +#endif /* jsprvtd_h___ */ diff --git a/src/dom/js/jspubtd.h b/src/dom/js/jspubtd.h new file mode 100644 index 000000000..e3a1a38b5 --- /dev/null +++ b/src/dom/js/jspubtd.h @@ -0,0 +1,564 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef jspubtd_h___ +#define jspubtd_h___ +/* + * JS public API typedefs. + */ +#include "jstypes.h" +#include "jscompat.h" + +JS_BEGIN_EXTERN_C + +/* Scalar typedefs. */ +typedef uint16 jschar; +typedef int32 jsint; +typedef uint32 jsuint; +typedef float64 jsdouble; +typedef jsword jsval; +typedef jsword jsid; +typedef int32 jsrefcount; /* PRInt32 if JS_THREADSAFE, see jslock.h */ + +/* + * Run-time version enumeration. See jsconfig.h for compile-time counterparts + * to these values that may be selected by the JS_VERSION macro, and tested by + * #if expressions. + */ +typedef enum JSVersion { + JSVERSION_1_0 = 100, + JSVERSION_1_1 = 110, + JSVERSION_1_2 = 120, + JSVERSION_1_3 = 130, + JSVERSION_1_4 = 140, + JSVERSION_ECMA_3 = 148, + JSVERSION_1_5 = 150, + JSVERSION_DEFAULT = 0, + JSVERSION_UNKNOWN = -1 +} JSVersion; + +#define JSVERSION_IS_ECMA(version) \ + ((version) == JSVERSION_DEFAULT || (version) >= JSVERSION_1_3) + +/* Result of typeof operator enumeration. */ +typedef enum JSType { + JSTYPE_VOID, /* undefined */ + JSTYPE_OBJECT, /* object */ + JSTYPE_FUNCTION, /* function */ + JSTYPE_STRING, /* string */ + JSTYPE_NUMBER, /* number */ + JSTYPE_BOOLEAN, /* boolean */ + JSTYPE_LIMIT +} JSType; + +/* JSObjectOps.checkAccess mode enumeration. */ +typedef enum JSAccessMode { + JSACC_PROTO = 0, /* XXXbe redundant w.r.t. id */ + JSACC_PARENT = 1, /* XXXbe redundant w.r.t. id */ + JSACC_IMPORT = 2, /* import foo.bar */ + JSACC_WATCH = 3, /* a watchpoint on object foo for id 'bar' */ + JSACC_READ = 4, /* a "get" of foo.bar */ + JSACC_WRITE = 8, /* a "set" of foo.bar = baz */ + JSACC_LIMIT +} JSAccessMode; + +#define JSACC_TYPEMASK (JSACC_WRITE - 1) + +/* + * This enum type is used to control the behavior of a JSObject property + * iterator function that has type JSNewEnumerate. + */ +typedef enum JSIterateOp { + JSENUMERATE_INIT, /* Create new iterator state */ + JSENUMERATE_NEXT, /* Iterate once */ + JSENUMERATE_DESTROY /* Destroy iterator state */ +} JSIterateOp; + +/* Struct typedefs. */ +typedef struct JSClass JSClass; +typedef struct JSConstDoubleSpec JSConstDoubleSpec; +typedef struct JSContext JSContext; +typedef struct JSErrorReport JSErrorReport; +typedef struct JSFunction JSFunction; +typedef struct JSFunctionSpec JSFunctionSpec; +typedef struct JSIdArray JSIdArray; +typedef struct JSProperty JSProperty; +typedef struct JSPropertySpec JSPropertySpec; +typedef struct JSObject JSObject; +typedef struct JSObjectMap JSObjectMap; +typedef struct JSObjectOps JSObjectOps; +typedef struct JSRuntime JSRuntime; +typedef struct JSRuntime JSTaskState; /* XXX deprecated name */ +typedef struct JSScript JSScript; +typedef struct JSString JSString; +typedef struct JSXDRState JSXDRState; +typedef struct JSExceptionState JSExceptionState; +typedef struct JSLocaleCallbacks JSLocaleCallbacks; + +/* JSClass (and JSObjectOps where appropriate) function pointer typedefs. */ + +/* + * Add, delete, get or set a property named by id in obj. Note the jsval id + * type -- id may be a string (Unicode property identifier) or an int (element + * index). The *vp out parameter, on success, is the new property value after + * an add, get, or set. After a successful delete, *vp is JSVAL_FALSE iff + * obj[id] can't be deleted (because it's permanent). + */ +typedef JSBool +(* JS_DLL_CALLBACK JSPropertyOp)(JSContext *cx, JSObject *obj, jsval id, + jsval *vp); + +/* + * This function type is used for callbacks that enumerate the properties of + * a JSObject. The behavior depends on the value of enum_op: + * + * JSENUMERATE_INIT + * A new, opaque iterator state should be allocated and stored in *statep. + * (You can use PRIVATE_TO_JSVAL() to tag the pointer to be stored). + * + * The number of properties that will be enumerated should be returned as + * an integer jsval in *idp, if idp is non-null, and provided the number of + * enumerable properties is known. If idp is non-null and the number of + * enumerable properties can't be computed in advance, *idp should be set + * to JSVAL_ZERO. + * + * JSENUMERATE_NEXT + * A previously allocated opaque iterator state is passed in via statep. + * Return the next jsid in the iteration using *idp. The opaque iterator + * state pointed at by statep is destroyed and *statep is set to JSVAL_NULL + * if there are no properties left to enumerate. + * + * JSENUMERATE_DESTROY + * Destroy the opaque iterator state previously allocated in *statep by a + * call to this function when enum_op was JSENUMERATE_INIT. + * + * The return value is used to indicate success, with a value of JS_FALSE + * indicating failure. + */ +typedef JSBool +(* JS_DLL_CALLBACK JSNewEnumerateOp)(JSContext *cx, JSObject *obj, + JSIterateOp enum_op, + jsval *statep, jsid *idp); + +/* + * The old-style JSClass.enumerate op should define all lazy properties not + * yet reflected in obj. + */ +typedef JSBool +(* JS_DLL_CALLBACK JSEnumerateOp)(JSContext *cx, JSObject *obj); + +/* + * Resolve a lazy property named by id in obj by defining it directly in obj. + * Lazy properties are those reflected from some peer native property space + * (e.g., the DOM attributes for a given node reflected as obj) on demand. + * + * JS looks for a property in an object, and if not found, tries to resolve + * the given id. If resolve succeeds, the engine looks again in case resolve + * defined obj[id]. If no such property exists directly in obj, the process + * is repeated with obj's prototype, etc. + * + * NB: JSNewResolveOp provides a cheaper way to resolve lazy properties. + */ +typedef JSBool +(* JS_DLL_CALLBACK JSResolveOp)(JSContext *cx, JSObject *obj, jsval id); + +/* + * Like JSResolveOp, but flags provide contextual information as follows: + * + * JSRESOLVE_QUALIFIED a qualified property id: obj.id or obj[id], not id + * JSRESOLVE_ASSIGNING obj[id] is on the left-hand side of an assignment + * + * The *objp out parameter, on success, should be null to indicate that id + * was not resolved; and non-null, referring to obj or one of its prototypes, + * if id was resolved. + * + * This hook instead of JSResolveOp is called via the JSClass.resolve member + * if JSCLASS_NEW_RESOLVE is set in JSClass.flags. + * + * Setting JSCLASS_NEW_RESOLVE and JSCLASS_NEW_RESOLVE_GETS_START further + * extends this hook by passing in the starting object on the prototype chain + * via *objp. Thus a resolve hook implementation may define the property id + * being resolved in the object in which the id was first sought, rather than + * in a prototype object whose class led to the resolve hook being called. + * + * When using JSCLASS_NEW_RESOLVE_GETS_START, the resolve hook must therefore + * null *objp to signify "not resolved". With only JSCLASS_NEW_RESOLVE and no + * JSCLASS_NEW_RESOLVE_GETS_START, the hook can assume *objp is null on entry. + * This is not good practice, but enough existing hook implementations count + * on it that we can't break compatibility by passing the starting object in + * *objp without a new JSClass flag. + */ +typedef JSBool +(* JS_DLL_CALLBACK JSNewResolveOp)(JSContext *cx, JSObject *obj, jsval id, + uintN flags, JSObject **objp); + +/* + * Convert obj to the given type, returning true with the resulting value in + * *vp on success, and returning false on error or exception. + */ +typedef JSBool +(* JS_DLL_CALLBACK JSConvertOp)(JSContext *cx, JSObject *obj, JSType type, + jsval *vp); + +/* + * Finalize obj, which the garbage collector has determined to be unreachable + * from other live objects or from GC roots. Obviously, finalizers must never + * store a reference to obj. + */ +typedef void +(* JS_DLL_CALLBACK JSFinalizeOp)(JSContext *cx, JSObject *obj); + +/* + * Used by JS_AddExternalStringFinalizer and JS_RemoveExternalStringFinalizer + * to extend and reduce the set of string types finalized by the GC. + */ +typedef void +(* JS_DLL_CALLBACK JSStringFinalizeOp)(JSContext *cx, JSString *str); + +/* + * The signature for JSClass.getObjectOps, used by JS_NewObject's internals + * to discover the set of high-level object operations to use for new objects + * of the given class. All native objects have a JSClass, which is stored as + * a private (int-tagged) pointer in obj->slots[JSSLOT_CLASS]. In contrast, + * all native and host objects have a JSObjectMap at obj->map, which may be + * shared among a number of objects, and which contains the JSObjectOps *ops + * pointer used to dispatch object operations from API calls. + * + * Thus JSClass (which pre-dates JSObjectOps in the API) provides a low-level + * interface to class-specific code and data, while JSObjectOps allows for a + * higher level of operation, which does not use the object's class except to + * find the class's JSObjectOps struct, by calling clasp->getObjectOps. + * + * If this seems backwards, that's because it is! API compatibility requires + * a JSClass *clasp parameter to JS_NewObject, etc. Most host objects do not + * need to implement the larger JSObjectOps, and can share the common JSScope + * code and data used by the native (js_ObjectOps, see jsobj.c) ops. + */ +typedef JSObjectOps * +(* JS_DLL_CALLBACK JSGetObjectOps)(JSContext *cx, JSClass *clasp); + +/* + * JSClass.checkAccess type: check whether obj[id] may be accessed per mode, + * returning false on error/exception, true on success with obj[id]'s last-got + * value in *vp, and its attributes in *attrsp. As for JSPropertyOp above, id + * is either a string or an int jsval. + * + * See JSCheckAccessIdOp, below, for the JSObjectOps counterpart, which takes + * a jsid (a tagged int or aligned, unique identifier pointer) rather than a + * jsval. The native js_ObjectOps.checkAccess simply forwards to the object's + * clasp->checkAccess, so that both JSClass and JSObjectOps implementors may + * specialize access checks. + */ +typedef JSBool +(* JS_DLL_CALLBACK JSCheckAccessOp)(JSContext *cx, JSObject *obj, jsval id, + JSAccessMode mode, jsval *vp); + +/* + * Encode or decode an object, given an XDR state record representing external + * data. See jsxdrapi.h. + */ +typedef JSBool +(* JS_DLL_CALLBACK JSXDRObjectOp)(JSXDRState *xdr, JSObject **objp); + +/* + * Check whether v is an instance of obj. Return false on error or exception, + * true on success with JS_TRUE in *bp if v is an instance of obj, JS_FALSE in + * *bp otherwise. + */ +typedef JSBool +(* JS_DLL_CALLBACK JSHasInstanceOp)(JSContext *cx, JSObject *obj, jsval v, + JSBool *bp); + +/* + * Function type for JSClass.mark and JSObjectOps.mark, called from the GC to + * scan live GC-things reachable from obj's private data structure. For each + * such thing, a mark implementation must call + * + * JS_MarkGCThing(cx, thing, name, arg); + * + * The trailing name and arg parameters are used for GC_MARK_DEBUG-mode heap + * dumping and ref-path tracing. The mark function should pass a (typically + * literal) string naming the private data member for name, and it must pass + * the opaque arg parameter through from its caller. + * + * For the JSObjectOps.mark hook, the return value is the number of slots at + * obj->slots to scan. For JSClass.mark, the return value is ignored. + * + * NB: JSMarkOp implementations cannot allocate new GC-things (JS_NewObject + * called from a mark function will fail silently, e.g.). + */ +typedef uint32 +(* JS_DLL_CALLBACK JSMarkOp)(JSContext *cx, JSObject *obj, void *arg); + +/* JSObjectOps function pointer typedefs. */ + +/* + * Create a new subclass of JSObjectMap (see jsobj.h), with the nrefs and ops + * members initialized from the same-named parameters, and with the nslots and + * freeslot members initialized according to ops and clasp. Return null on + * error, non-null on success. + * + * JSObjectMaps are reference-counted by generic code in the engine. Usually, + * the nrefs parameter to JSObjectOps.newObjectMap will be 1, to count the ref + * returned to the caller on success. After a successful construction, some + * number of js_HoldObjectMap and js_DropObjectMap calls ensue. When nrefs + * reaches 0 due to a js_DropObjectMap call, JSObjectOps.destroyObjectMap will + * be called to dispose of the map. + */ +typedef JSObjectMap * +(* JS_DLL_CALLBACK JSNewObjectMapOp)(JSContext *cx, jsrefcount nrefs, + JSObjectOps *ops, JSClass *clasp, + JSObject *obj); + +/* + * Generic type for an infallible JSObjectMap operation, used currently by + * JSObjectOps.destroyObjectMap. + */ +typedef void +(* JS_DLL_CALLBACK JSObjectMapOp)(JSContext *cx, JSObjectMap *map); + +/* + * Look for id in obj and its prototype chain, returning false on error or + * exception, true on success. On success, return null in *propp if id was + * not found. If id was found, return the first object searching from obj + * along its prototype chain in which id names a direct property in *objp, and + * return a non-null, opaque property pointer in *propp. + * + * If JSLookupPropOp succeeds and returns with *propp non-null, that pointer + * may be passed as the prop parameter to a JSAttributesOp, as a short-cut + * that bypasses id re-lookup. In any case, a non-null *propp result after a + * successful lookup must be dropped via JSObjectOps.dropProperty. + * + * NB: successful return with non-null *propp means the implementation may + * have locked *objp and added a reference count associated with *propp, so + * callers should not risk deadlock by nesting or interleaving other lookups + * or any obj-bearing ops before dropping *propp. + */ +typedef JSBool +(* JS_DLL_CALLBACK JSLookupPropOp)(JSContext *cx, JSObject *obj, jsid id, + JSObject **objp, JSProperty **propp +#if defined JS_THREADSAFE && defined DEBUG + , const char *file, uintN line +#endif + ); + +/* + * Define obj[id], a direct property of obj named id, having the given initial + * value, with the specified getter, setter, and attributes. If the propp out + * param is non-null, *propp on successful return contains an opaque property + * pointer usable as a speedup hint with JSAttributesOp. But note that propp + * may be null, indicating that the caller is not interested in recovering an + * opaque pointer to the newly-defined property. + * + * If propp is non-null and JSDefinePropOp succeeds, its caller must be sure + * to drop *propp using JSObjectOps.dropProperty in short order, just as with + * JSLookupPropOp. + */ +typedef JSBool +(* JS_DLL_CALLBACK JSDefinePropOp)(JSContext *cx, JSObject *obj, + jsid id, jsval value, + JSPropertyOp getter, JSPropertyOp setter, + uintN attrs, JSProperty **propp); + +/* + * Get, set, or delete obj[id], returning false on error or exception, true + * on success. If getting or setting, the new value is returned in *vp on + * success. If deleting without error, *vp will be JSVAL_FALSE if obj[id] is + * permanent, and JSVAL_TRUE if id named a direct property of obj that was in + * fact deleted, or if id names no direct property of obj (id could name a + * prototype property, or no property in obj or its prototype chain). + */ +typedef JSBool +(* JS_DLL_CALLBACK JSPropertyIdOp)(JSContext *cx, JSObject *obj, jsid id, + jsval *vp); + +/* + * Get or set attributes of the property obj[id]. Return false on error or + * exception, true with current attributes in *attrsp. If prop is non-null, + * it must come from the *propp out parameter of a prior JSDefinePropOp or + * JSLookupPropOp call. + */ +typedef JSBool +(* JS_DLL_CALLBACK JSAttributesOp)(JSContext *cx, JSObject *obj, jsid id, + JSProperty *prop, uintN *attrsp); + +/* + * JSObjectOps.checkAccess type: check whether obj[id] may be accessed per + * mode, returning false on error/exception, true on success with obj[id]'s + * last-got value in *vp, and its attributes in *attrsp. + */ +typedef JSBool +(* JS_DLL_CALLBACK JSCheckAccessIdOp)(JSContext *cx, JSObject *obj, jsid id, + JSAccessMode mode, jsval *vp, + uintN *attrsp); + +/* + * A generic type for functions mapping an object to another object, or null + * if an error or exception was thrown on cx. Used by JSObjectOps.thisObject + * at present. + */ +typedef JSObject * +(* JS_DLL_CALLBACK JSObjectOp)(JSContext *cx, JSObject *obj); + +/* + * A generic type for functions taking a context, object, and property, with + * no return value. Used by JSObjectOps.dropProperty currently (see above, + * JSDefinePropOp and JSLookupPropOp, for the object-locking protocol in which + * dropProperty participates). + */ +typedef void +(* JS_DLL_CALLBACK JSPropertyRefOp)(JSContext *cx, JSObject *obj, + JSProperty *prop); + +/* + * Function type for JSObjectOps.setProto and JSObjectOps.setParent. These + * hooks must check for cycles without deadlocking, and otherwise take special + * steps. See jsobj.c, js_SetProtoOrParent, for an example. + */ +typedef JSBool +(* JS_DLL_CALLBACK JSSetObjectSlotOp)(JSContext *cx, JSObject *obj, + uint32 slot, JSObject *pobj); + +/* + * Get and set a required slot, one that should already have been allocated. + * These operations are infallible, so required slots must be pre-allocated, + * or implementations must suppress out-of-memory errors. The native ops + * (js_ObjectOps, see jsobj.c) access slots reserved by including a call to + * the JSCLASS_HAS_RESERVED_SLOTS(n) macro in the JSClass.flags initializer. + * + * NB: the slot parameter is a zero-based index into obj->slots[], unlike the + * index parameter to the JS_GetReservedSlot and JS_SetReservedSlot API entry + * points, which is a zero-based index into the JSCLASS_RESERVED_SLOTS(clasp) + * reserved slots that come after the initial well-known slots: proto, parent, + * class, and optionally, the private data slot. + */ +typedef jsval +(* JS_DLL_CALLBACK JSGetRequiredSlotOp)(JSContext *cx, JSObject *obj, + uint32 slot); + +typedef void +(* JS_DLL_CALLBACK JSSetRequiredSlotOp)(JSContext *cx, JSObject *obj, + uint32 slot, jsval v); + +/* Typedef for native functions called by the JS VM. */ + +typedef JSBool +(* JS_DLL_CALLBACK JSNative)(JSContext *cx, JSObject *obj, uintN argc, + jsval *argv, jsval *rval); + +/* Callbacks and their arguments. */ + +typedef enum JSGCStatus { + JSGC_BEGIN, + JSGC_END, + JSGC_MARK_END, + JSGC_FINALIZE_END +} JSGCStatus; + +typedef JSBool +(* JS_DLL_CALLBACK JSGCCallback)(JSContext *cx, JSGCStatus status); + +typedef JSBool +(* JS_DLL_CALLBACK JSBranchCallback)(JSContext *cx, JSScript *script); + +typedef void +(* JS_DLL_CALLBACK JSErrorReporter)(JSContext *cx, const char *message, + JSErrorReport *report); + +typedef struct JSErrorFormatString { + const char *format; + uintN argCount; +} JSErrorFormatString; + +typedef const JSErrorFormatString * +(* JS_DLL_CALLBACK JSErrorCallback)(void *userRef, const char *locale, + const uintN errorNumber); + +#ifdef va_start +#define JS_ARGUMENT_FORMATTER_DEFINED 1 + +typedef JSBool +(* JS_DLL_CALLBACK JSArgumentFormatter)(JSContext *cx, const char *format, + JSBool fromJS, jsval **vpp, + va_list *app); +#endif + +typedef JSBool +(* JS_DLL_CALLBACK JSLocaleToUpperCase)(JSContext *cx, JSString *src, + jsval *rval); + +typedef JSBool +(* JS_DLL_CALLBACK JSLocaleToLowerCase)(JSContext *cx, JSString *src, + jsval *rval); + +typedef JSBool +(* JS_DLL_CALLBACK JSLocaleCompare)(JSContext *cx, + JSString *src1, JSString *src2, + jsval *rval); + +/* + * Security protocol types. + */ +typedef struct JSPrincipals JSPrincipals; + +/* + * XDR-encode or -decode a principals instance, based on whether xdr->mode is + * JSXDR_ENCODE, in which case *principalsp should be encoded; or JSXDR_DECODE, + * in which case implementations must return a held (via JSPRINCIPALS_HOLD), + * non-null *principalsp out parameter. Return true on success, false on any + * error, which the implementation must have reported. + */ +typedef JSBool +(* JS_DLL_CALLBACK JSPrincipalsTranscoder)(JSXDRState *xdr, + JSPrincipals **principalsp); + +/* + * Return a weak reference to the principals associated with obj, possibly via + * the immutable parent chain leading from obj to a top-level container (e.g., + * a window object in the DOM level 0). If there are no principals associated + * with obj, return null. Therefore null does not mean an error was reported; + * in no event should an error be reported or an exception be thrown by this + * callback's implementation. + */ +typedef JSPrincipals * +(* JS_DLL_CALLBACK JSObjectPrincipalsFinder)(JSContext *cx, JSObject *obj); + +JS_END_EXTERN_C + +#endif /* jspubtd_h___ */ diff --git a/src/dom/js/jsregexp.c b/src/dom/js/jsregexp.c new file mode 100644 index 000000000..18ab92c35 --- /dev/null +++ b/src/dom/js/jsregexp.c @@ -0,0 +1,3773 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* + * JS regular expressions, after Perl. + */ +#include "jsstddef.h" +#include +#include +#include "jstypes.h" +#include "jsarena.h" /* Added by JSIFY */ +#include "jsutil.h" /* Added by JSIFY */ +#include "jsapi.h" +#include "jsarray.h" +#include "jsatom.h" +#include "jscntxt.h" +#include "jsconfig.h" +#include "jsfun.h" +#include "jsgc.h" +#include "jsinterp.h" +#include "jslock.h" +#include "jsnum.h" +#include "jsobj.h" +#include "jsopcode.h" +#include "jsregexp.h" +#include "jsscan.h" +#include "jsstr.h" + +#ifdef XP_MAC +#include +#endif + +#if JS_HAS_REGEXPS + +/* Note : contiguity of 'simple opcodes' is important for simpleMatch() */ +typedef enum REOp { + REOP_EMPTY = 0, /* match rest of input against rest of r.e. */ + REOP_ALT = 1, /* alternative subexpressions in kid and next */ + REOP_SIMPLE_START = 2, /* start of 'simple opcodes' */ + REOP_BOL = 2, /* beginning of input (or line if multiline) */ + REOP_EOL = 3, /* end of input (or line if multiline) */ + REOP_WBDRY = 4, /* match "" at word boundary */ + REOP_WNONBDRY = 5, /* match "" at word non-boundary */ + REOP_DOT = 6, /* stands for any character */ + REOP_DIGIT = 7, /* match a digit char: [0-9] */ + REOP_NONDIGIT = 8, /* match a non-digit char: [^0-9] */ + REOP_ALNUM = 9, /* match an alphanumeric char: [0-9a-z_A-Z] */ + REOP_NONALNUM = 10, /* match a non-alphanumeric char: [^0-9a-z_A-Z] */ + REOP_SPACE = 11, /* match a whitespace char */ + REOP_NONSPACE = 12, /* match a non-whitespace char */ + REOP_BACKREF = 13, /* back-reference (e.g., \1) to a parenthetical */ + REOP_FLAT = 14, /* match a flat string */ + REOP_FLAT1 = 15, /* match a single char */ + REOP_FLATi = 16, /* case-independent REOP_FLAT */ + REOP_FLAT1i = 17, /* case-independent REOP_FLAT1 */ + REOP_UCFLAT1 = 18, /* single Unicode char */ + REOP_UCFLAT1i = 19, /* case-independent REOP_UCFLAT1 */ + REOP_UCFLAT = 20, /* flat Unicode string; len immediate counts chars */ + REOP_UCFLATi = 21, /* case-independent REOP_UCFLAT */ + REOP_CLASS = 22, /* character class with index */ + REOP_NCLASS = 23, /* negated character class with index */ + REOP_SIMPLE_END = 23, /* end of 'simple opcodes' */ + REOP_QUANT = 25, /* quantified atom: atom{1,2} */ + REOP_STAR = 26, /* zero or more occurrences of kid */ + REOP_PLUS = 27, /* one or more occurrences of kid */ + REOP_OPT = 28, /* optional subexpression in kid */ + REOP_LPAREN = 29, /* left paren bytecode: kid is u.num'th sub-regexp */ + REOP_RPAREN = 30, /* right paren bytecode */ + REOP_JUMP = 31, /* for deoptimized closure loops */ + REOP_DOTSTAR = 32, /* optimize .* to use a single opcode */ + REOP_ANCHOR = 33, /* like .* but skips left context to unanchored r.e. */ + REOP_EOLONLY = 34, /* $ not preceded by any pattern */ + REOP_BACKREFi = 37, /* case-independent REOP_BACKREF */ + REOP_LPARENNON = 41, /* non-capturing version of REOP_LPAREN */ + REOP_ASSERT = 43, /* zero width positive lookahead assertion */ + REOP_ASSERT_NOT = 44, /* zero width negative lookahead assertion */ + REOP_ASSERTTEST = 45, /* sentinel at end of assertion child */ + REOP_ASSERTNOTTEST = 46, /* sentinel at end of !assertion child */ + REOP_MINIMALSTAR = 47, /* non-greedy version of * */ + REOP_MINIMALPLUS = 48, /* non-greedy version of + */ + REOP_MINIMALOPT = 49, /* non-greedy version of ? */ + REOP_MINIMALQUANT = 50, /* non-greedy version of {} */ + REOP_ENDCHILD = 51, /* sentinel at end of quantifier child */ + REOP_REPEAT = 52, /* directs execution of greedy quantifier */ + REOP_MINIMALREPEAT = 53, /* directs execution of non-greedy quantifier */ + REOP_ALTPREREQ = 54, /* prerequisite for ALT, either of two chars */ + REOP_ALTPREREQ2 = 55, /* prerequisite for ALT, a char or a class */ + REOP_ENDALT = 56, /* end of final alternate */ + REOP_CONCAT = 57, /* concatenation of terms (parse time only) */ + + REOP_END +} REOp; + +#define REOP_IS_SIMPLE(op) (((op) >= REOP_SIMPLE_START) && ((op) <= REOP_SIMPLE_END)) + +struct RENode { + REOp op; /* r.e. op bytecode */ + RENode *next; /* next in concatenation order */ + void *kid; /* first operand */ + union { + void *kid2; /* second operand */ + jsint num; /* could be a number */ + jsint parenIndex; /* or a parenthesis index */ + struct { /* or a quantifier range */ + uint16 min; + uint16 max; + JSBool greedy; + } range; + struct { /* or a character class */ + uint16 startIndex; + uint16 kidlen; /* length of string at kid, in jschars */ + uint16 bmsize; /* bitmap size, based on max char code */ + uint16 index; /* index into class list */ + JSBool sense; + } ucclass; + struct { /* or a literal sequence */ + jschar chr; /* of one character */ + uint16 length; /* or many (via the kid) */ + } flat; + struct { + RENode *kid2; /* second operand from ALT */ + jschar ch1; /* match char for ALTPREREQ */ + jschar ch2; /* ditto, or class index for ALTPREREQ2 */ + } altprereq; + } u; +}; + +#define RE_IS_LETTER(c) ( ((c >= 'A') && (c <= 'Z')) || \ + ((c >= 'a') && (c <= 'z')) ) +#define RE_IS_LINE_TERM(c) ( (c == '\n') || (c == '\r') || \ + (c == LINE_SEPARATOR) || (c == PARA_SEPARATOR)) + +#define CLASS_CACHE_SIZE (4) +typedef struct CompilerState { + JSContext *context; + JSTokenStream *tokenStream; /* For reporting errors */ + const jschar *cpbegin; + const jschar *cpend; + const jschar *cp; + uintN flags; + uint16 parenCount; + uint16 classCount; /* number of [] encountered */ + size_t progLength; /* estimated bytecode length */ + uintN treeDepth; /* maximum depth of parse tree */ + RENode *result; + struct { + const jschar *start; /* small cache of class strings */ + uint16 length; /* since they're often the same */ + uint16 index; + } classCache[CLASS_CACHE_SIZE]; +} CompilerState; + +typedef struct RECapture { + int32 index; /* start of contents, -1 for empty */ + uint16 length; /* length of capture */ +} RECapture; + +typedef struct REMatchState { + const jschar *cp; + RECapture parens[1]; /* first of 're->parenCount' captures, + * allocated at end of this struct. + */ +} REMatchState; + +struct REBackTrackData; + +typedef struct REProgState { + jsbytecode *continue_pc; /* current continuation data */ + jsbytecode continue_op; + uint16 index; /* progress in text */ + uintN parenSoFar; /* highest indexed paren started */ + union { + struct { + uint16 min; /* current quantifier limits */ + uint16 max; + } quantifier; + struct { + size_t top; /* backtrack stack state */ + size_t sz; + } assertion; + } u; +} REProgState; + +typedef struct REBackTrackData { + size_t sz; /* size of previous stack entry */ + jsbytecode *backtrack_pc; /* where to backtrack to */ + jsbytecode backtrack_op; + const jschar *cp; /* index in text of match at backtrack */ + intN parenIndex; /* start index of saved paren contents */ + uint16 parenCount; /* # of saved paren contents */ + uint16 precedingStateTop; /* number of parent states */ + /* saved parent states follow */ + /* saved paren contents follow */ +} REBackTrackData; + +#define INITIAL_STATESTACK (100) +#define INITIAL_BACKTRACK (8000) + +typedef struct REGlobalData { + JSContext *cx; + JSRegExp *regexp; /* the RE in execution */ + JSBool ok; /* runtime error (out_of_memory only?) */ + size_t start; /* offset to start at */ + ptrdiff_t skipped; /* chars skipped anchoring this r.e. */ + const jschar *cpbegin, *cpend; /* text base address and limit */ + + REProgState *stateStack; /* stack of state of current parents */ + uint16 stateStackTop; + uint16 maxStateStack; + + REBackTrackData *backTrackStack;/* stack of matched-so-far positions */ + REBackTrackData *backTrackSP; + size_t maxBackTrack; + size_t cursz; /* size of current stack entry */ + + JSArenaPool pool; /* I don't understand but it's faster to + * use this than to malloc/free the three + * items that are allocated from this pool + */ + +} REGlobalData; + + +/* + * 1. If IgnoreCase is false, return ch. + * 2. Let u be ch converted to upper case as if by calling + * String.prototype.toUpperCase on the one-character string ch. + * 3. If u does not consist of a single character, return ch. + * 4. Let cu be u's character. + * 5. If ch's code point value is greater than or equal to decimal 128 and cu's + * code point value is less than decimal 128, then return ch. + * 6. Return cu. + */ +static jschar +upcase(jschar ch) +{ + jschar cu = JS_TOUPPER(ch); + if ((ch >= 128) && (cu < 128)) return ch; + return cu; +} + +static jschar +downcase(jschar ch) +{ + jschar cl = JS_TOLOWER(ch); + if ((cl >= 128) && (ch < 128)) return ch; + return cl; +} + +/* Construct and initialize an RENode, returning NULL for out-of-memory */ +static RENode * +NewRENode(CompilerState *state, REOp op) +{ + JSContext *cx; + RENode *ren; + + cx = state->context; + JS_ARENA_ALLOCATE_CAST(ren, RENode *, &cx->tempPool, sizeof *ren); + if (!ren) { + JS_ReportOutOfMemory(cx); + return NULL; + } + ren->op = op; + ren->next = NULL; + ren->kid = NULL; + return ren; +} + +/* + * Validates and converts hex ascii value. + */ +static JSBool +isASCIIHexDigit(jschar c, uintN *digit) +{ + uintN cv = c; + + if (cv < '0') + return JS_FALSE; + if (cv <= '9') { + *digit = cv - '0'; + return JS_TRUE; + } + cv |= 0x20; + if (cv >= 'a' && cv <= 'f') { + *digit = cv - 'a' + 10; + return JS_TRUE; + } + return JS_FALSE; +} + + +typedef struct { + REOp op; + const jschar *errPos; + uint16 parenIndex; +} REOpData; + + +/* + * Process the op against the two top operands, reducing them to a single + * operand in the penultimate slot. Update progLength and treeDepth. + */ +static JSBool +processOp(CompilerState *state, REOpData *opData, RENode **operandStack, intN operandSP) +{ + RENode *result; + + switch (opData->op) { + case REOP_ALT: + result = NewRENode(state, REOP_ALT); + if (!result) + return JS_FALSE; + result->kid = operandStack[operandSP - 2]; + result->u.kid2 = operandStack[operandSP - 1]; + operandStack[operandSP - 2] = result; + /* + * look at both alternates to see if there's a FLAT or a CLASS at + * the start of each. If so, use a prerequisite match + */ + ++state->treeDepth; + if ((((RENode *)(result->kid))->op == REOP_FLAT) + && (((RENode *)(result->u.kid2))->op == REOP_FLAT) + && ((state->flags & JSREG_FOLD) == 0) ) { + result->op = REOP_ALTPREREQ; + result->u.altprereq.ch1 + = ((RENode *)(result->kid))->u.flat.chr; + result->u.altprereq.ch2 + = ((RENode *)(result->u.kid2))->u.flat.chr; + /* ALTPREREQ, , uch1, uch2, , ..., + JUMP, ... ENDALT */ + state->progLength += 13; + } + else + if ((((RENode *)(result->kid))->op == REOP_CLASS) + && (((RENode *)(result->kid))->u.ucclass.index < 256) + && (((RENode *)(result->u.kid2))->op == REOP_FLAT) + && ((state->flags & JSREG_FOLD) == 0) ) { + result->op = REOP_ALTPREREQ2; + result->u.altprereq.ch1 + = ((RENode *)(result->u.kid2))->u.flat.chr; + result->u.altprereq.ch2 + = ((RENode *)(result->kid))->u.ucclass.index; + /* ALTPREREQ2, , uch1, uch2, , ..., + JUMP, ... ENDALT */ + state->progLength += 13; + } + else + if ((((RENode *)(result->kid))->op == REOP_FLAT) + && (((RENode *)(result->u.kid2))->op == REOP_CLASS) + && (((RENode *)(result->u.kid2))->u.ucclass.index < 256) + && ((state->flags & JSREG_FOLD) == 0) ) { + result->op = REOP_ALTPREREQ2; + result->u.altprereq.ch1 + = ((RENode *)(result->kid))->u.flat.chr; + result->u.altprereq.ch2 + = ((RENode *)(result->u.kid2))->u.ucclass.index; + /* ALTPREREQ2, , uch1, uch2, , ..., + JUMP, ... ENDALT */ + state->progLength += 13; + } + else + /* ALT, , ..., JUMP, ... ENDALT */ + state->progLength += 7; + break; + case REOP_CONCAT: + result = operandStack[operandSP - 2]; + while (result->next) + result = result->next; + result->next = operandStack[operandSP - 1]; + break; + case REOP_ASSERT: + case REOP_ASSERT_NOT: + case REOP_LPARENNON: + case REOP_LPAREN: + /* These should have been processed by a close paren. */ + js_ReportCompileErrorNumber(state->context, state->tokenStream, + NULL, JSREPORT_ERROR, + JSMSG_MISSING_PAREN, opData->errPos); + return JS_FALSE; + default:; + } + return JS_TRUE; +} + +/* + * Parser forward declarations. + */ +static JSBool parseTerm(CompilerState *state); +static JSBool parseQuantifier(CompilerState *state); + +/* + * Top-down regular expression grammar, based closely on Perl4. + * + * regexp: altern A regular expression is one or more + * altern '|' regexp alternatives separated by vertical bar. + */ + +#define INITIAL_STACK_SIZE (128) +static JSBool +parseRegExp(CompilerState *state) +{ + uint16 parenIndex; + RENode *operand; + REOpData *operatorStack; + RENode **operandStack; + REOp op; + intN i; + JSBool result = JS_FALSE; + + intN operatorSP = 0, operatorStackSize = INITIAL_STACK_SIZE; + intN operandSP = 0, operandStackSize = INITIAL_STACK_SIZE; + + /* Watch out for empty regexp */ + if (state->cp == state->cpend) { + state->result = NewRENode(state, REOP_EMPTY); + return (state->result != NULL); + } + + operatorStack = (REOpData *)JS_malloc(state->context, + sizeof(REOpData) * operatorStackSize); + if (!operatorStack) + return JS_FALSE; + + operandStack = (RENode **)JS_malloc(state->context, + sizeof(RENode *) * operandStackSize); + if (!operandStack) + goto out; + + + while (JS_TRUE) { + if (state->cp == state->cpend) { + /* + * If we are at the end of the regexp and we're short an operand, + * the regexp must have the form /x|/ or some such. + */ + if (operatorSP == operandSP) { + operand = NewRENode(state, REOP_EMPTY); + if (!operand) + goto out; + goto pushOperand; + } + } else { + switch (*state->cp) { + /* balance '(' */ + case '(': /* balance ')' */ + ++state->cp; + if ((state->cp < state->cpend) && (*state->cp == '?') + && ( (state->cp[1] == '=') + || (state->cp[1] == '!') + || (state->cp[1] == ':') )) { + ++state->cp; + if (state->cp == state->cpend) { + js_ReportCompileErrorNumber(state->context, + state->tokenStream, + NULL, JSREPORT_ERROR, + JSMSG_MISSING_PAREN); + goto out; + } + switch (*state->cp++) { + case '=': + op = REOP_ASSERT; + /* ASSERT, , ... ASSERTTEST */ + state->progLength += 4; + break; + case '!': + op = REOP_ASSERT_NOT; + /* ASSERTNOT, , ... ASSERTNOTTEST */ + state->progLength += 4; + break; + case ':': + op = REOP_LPARENNON; + break; + } + parenIndex = state->parenCount; + } + else { + op = REOP_LPAREN; + /* LPAREN, , ... RPAREN, */ + state->progLength += 6; + parenIndex = state->parenCount++; + if (state->parenCount == 65535) { + js_ReportCompileErrorNumber(state->context, + state->tokenStream, + NULL, JSREPORT_ERROR, + JSMSG_TOO_MANY_PARENS); + goto out; + } + } + goto pushOperator; + case ')': + /* If there's not a stacked open parenthesis, throw + * a syntax error. + */ + for (i = operatorSP - 1; i >= 0; i--) + if ((operatorStack[i].op == REOP_ASSERT) + || (operatorStack[i].op == REOP_ASSERT_NOT) + || (operatorStack[i].op == REOP_LPARENNON) + || (operatorStack[i].op == REOP_LPAREN)) + break; + if (i == -1) { + js_ReportCompileErrorNumber(state->context, + state->tokenStream, + NULL, JSREPORT_ERROR, + JSMSG_UNMATCHED_RIGHT_PAREN); + goto out; + } + /* fall thru... */ + case '|': + /* Expected an operand before these, so make an empty one */ + operand = NewRENode(state, REOP_EMPTY); + if (!operand) + goto out; + goto pushOperand; + default: + if (!parseTerm(state)) + goto out; + operand = state->result; +pushOperand: + if (operandSP == operandStackSize) { + operandStackSize += operandStackSize; + operandStack = + (RENode **)JS_realloc(state->context, operandStack, + sizeof(RENode *) * operandStackSize); + if (!operandStack) + goto out; + } + operandStack[operandSP++] = operand; + break; + } + } + /* At the end; process remaining operators */ +restartOperator: + if (state->cp == state->cpend) { + while (operatorSP) { + --operatorSP; + if (!processOp(state, &operatorStack[operatorSP], + operandStack, operandSP)) + goto out; + --operandSP; + } + JS_ASSERT(operandSP == 1); + state->result = operandStack[0]; + result = JS_TRUE; + goto out; + } + switch (*state->cp) { + case '|': + /* Process any stacked 'concat' operators */ + ++state->cp; + while (operatorSP + && (operatorStack[operatorSP - 1].op == REOP_CONCAT)) { + --operatorSP; + if (!processOp(state, &operatorStack[operatorSP], + operandStack, operandSP)) + goto out; + --operandSP; + } + op = REOP_ALT; + goto pushOperator; + + case ')': + /* If there's not a stacked open parenthesis,we + * accept the close as a flat. + */ + for (i = operatorSP - 1; i >= 0; i--) + if ((operatorStack[i].op == REOP_ASSERT) + || (operatorStack[i].op == REOP_ASSERT_NOT) + || (operatorStack[i].op == REOP_LPARENNON) + || (operatorStack[i].op == REOP_LPAREN)) + break; + if (i == -1) { + js_ReportCompileErrorNumber(state->context, + state->tokenStream, + NULL, JSREPORT_ERROR, + JSMSG_UNMATCHED_RIGHT_PAREN); + goto out; + } + ++state->cp; + /* process everything on the stack until the open */ + while (JS_TRUE) { + JS_ASSERT(operatorSP); + --operatorSP; + switch (operatorStack[operatorSP].op) { + case REOP_ASSERT: + case REOP_ASSERT_NOT: + case REOP_LPAREN: + operand = NewRENode(state, operatorStack[operatorSP].op); + if (!operand) + goto out; + operand->u.parenIndex + = operatorStack[operatorSP].parenIndex; + JS_ASSERT(operandSP); + operand->kid = operandStack[operandSP - 1]; + operandStack[operandSP - 1] = operand; + ++state->treeDepth; + /* fall thru... */ + case REOP_LPARENNON: + state->result = operandStack[operandSP - 1]; + if (!parseQuantifier(state)) + goto out; + operandStack[operandSP - 1] = state->result; + goto restartOperator; + default: + if (!processOp(state, &operatorStack[operatorSP], + operandStack, operandSP)) + goto out; + --operandSP; + break; + } + } + break; + default: + /* Anything else is the start of the next term */ + op = REOP_CONCAT; +pushOperator: + if (operatorSP == operatorStackSize) { + operatorStackSize += operatorStackSize; + operatorStack = + (REOpData *)JS_realloc(state->context, operatorStack, + sizeof(REOpData) * operatorStackSize); + if (!operatorStack) + goto out; + } + operatorStack[operatorSP].op = op; + operatorStack[operatorSP].errPos = state->cp; + operatorStack[operatorSP++].parenIndex = parenIndex; + break; + } + } +out: + if (operatorStack) + JS_free(state->context, operatorStack); + if (operandStack) + JS_free(state->context, operandStack); + return result; +} + +/* + * Extract and return a decimal value at state->cp, the + * initial character 'c' has already been read. + */ +static intN +getDecimalValue(jschar c, CompilerState *state) +{ + intN value = JS7_UNDEC(c); + while (state->cp < state->cpend) { + c = *state->cp; + if (!JS7_ISDEC(c)) + break; + value = (10 * value) + JS7_UNDEC(c); + ++state->cp; + } + return value; +} + +/* + * Calculate the total size of the bitmap required for a class expression. + */ +static JSBool +calculateBitmapSize(CompilerState *state, RENode *target, const jschar *src, + const jschar *end) +{ + jschar rangeStart, c; + uintN n, digit, nDigits, i; + uintN max = 0; + JSBool inRange = JS_FALSE; + + target->u.ucclass.bmsize = 0; + target->u.ucclass.sense = JS_TRUE; + + if (src == end) + return JS_TRUE; + + if (*src == '^') { + ++src; + target->u.ucclass.sense = JS_FALSE; + } + + while (src != end) { + uintN localMax = 0; + switch (*src) { + case '\\': + ++src; + c = *src++; + switch (c) { + case 'b': + localMax = 0x8; + break; + case 'f': + localMax = 0xC; + break; + case 'n': + localMax = 0xA; + break; + case 'r': + localMax = 0xD; + break; + case 't': + localMax = 0x9; + break; + case 'v': + localMax = 0xB; + break; + case 'c': + if (((src + 1) < end) && RE_IS_LETTER(src[1])) + localMax = (jschar)(*src++ & 0x1F); + else + localMax = '\\'; + break; + case 'x': + nDigits = 2; + goto lexHex; + case 'u': + nDigits = 4; +lexHex: + n = 0; + for (i = 0; (i < nDigits) && (src < end); i++) { + c = *src++; + if (!isASCIIHexDigit(c, &digit)) { + /* + * Back off to accepting the original + *'\' as a literal. + */ + src -= (i + 1); + n = '\\'; + break; + } + n = (n << 4) | digit; + } + localMax = n; + break; + case 'd': + if (inRange) { + JS_ReportErrorNumber(state->context, + js_GetErrorMessage, NULL, + JSMSG_BAD_CLASS_RANGE); + return JS_FALSE; + } + localMax = '9'; + break; + case 'D': + case 's': + case 'S': + case 'w': + case 'W': + if (inRange) { + JS_ReportErrorNumber(state->context, + js_GetErrorMessage, NULL, + JSMSG_BAD_CLASS_RANGE); + return JS_FALSE; + } + target->u.ucclass.bmsize = 65535; + return JS_TRUE; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + /* + * This is a non-ECMA extension - decimal escapes (in this + * case, octal!) are supposed to be an error inside class + * ranges, but supported here for backwards compatibility. + * + */ + n = JS7_UNDEC(c); + c = *src; + if ('0' <= c && c <= '7') { + src++; + n = 8 * n + JS7_UNDEC(c); + c = *src; + if ('0' <= c && c <= '7') { + src++; + i = 8 * n + JS7_UNDEC(c); + if (i <= 0377) + n = i; + else + src--; + } + } + localMax = n; + break; + + default: + localMax = c; + break; + } + break; + default: + localMax = *src++; + break; + } + if (inRange) { + if (rangeStart > localMax) { + JS_ReportErrorNumber(state->context, + js_GetErrorMessage, NULL, + JSMSG_BAD_CLASS_RANGE); + return JS_FALSE; + } + inRange = JS_FALSE; + } + else { + if (src < (end - 1)) { + if (*src == '-') { + ++src; + inRange = JS_TRUE; + rangeStart = (jschar)localMax; + continue; + } + } + } + if (state->flags & JSREG_FOLD) { + c = JS_MAX(upcase((jschar)localMax), downcase((jschar)localMax)); + if (c > localMax) + localMax = c; + } + if (localMax > max) + max = localMax; + } + target->u.ucclass.bmsize = max; + return JS_TRUE; +} + +/* + * item: assertion An item is either an assertion or + * quantatom a quantified atom. + * + * assertion: '^' Assertions match beginning of string + * (or line if the class static property + * RegExp.multiline is true). + * '$' End of string (or line if the class + * static property RegExp.multiline is + * true). + * '\b' Word boundary (between \w and \W). + * '\B' Word non-boundary. + * + * quantatom: atom An unquantified atom. + * quantatom '{' n ',' m '}' + * Atom must occur between n and m times. + * quantatom '{' n ',' '}' Atom must occur at least n times. + * quantatom '{' n '}' Atom must occur exactly n times. + * quantatom '*' Zero or more times (same as {0,}). + * quantatom '+' One or more times (same as {1,}). + * quantatom '?' Zero or one time (same as {0,1}). + * + * any of which can be optionally followed by '?' for ungreedy + * + * atom: '(' regexp ')' A parenthesized regexp (what matched + * can be addressed using a backreference, + * see '\' n below). + * '.' Matches any char except '\n'. + * '[' classlist ']' A character class. + * '[' '^' classlist ']' A negated character class. + * '\f' Form Feed. + * '\n' Newline (Line Feed). + * '\r' Carriage Return. + * '\t' Horizontal Tab. + * '\v' Vertical Tab. + * '\d' A digit (same as [0-9]). + * '\D' A non-digit. + * '\w' A word character, [0-9a-z_A-Z]. + * '\W' A non-word character. + * '\s' A whitespace character, [ \b\f\n\r\t\v]. + * '\S' A non-whitespace character. + * '\' n A backreference to the nth (n decimal + * and positive) parenthesized expression. + * '\' octal An octal escape sequence (octal must be + * two or three digits long, unless it is + * 0 for the null character). + * '\x' hex A hex escape (hex must be two digits). + * '\u' unicode A unicode escape (must be four digits). + * '\c' ctrl A control character, ctrl is a letter. + * '\' literalatomchar Any character except one of the above + * that follow '\' in an atom. + * otheratomchar Any character not first among the other + * atom right-hand sides. + */ +static JSBool +parseTerm(CompilerState *state) +{ + jschar c = *state->cp++; + uintN nDigits; + uintN num, tmp, n, i; + const jschar *termStart; + JSBool foundCachedCopy; + + switch (c) { + /* assertions and atoms */ + case '^': + state->result = NewRENode(state, REOP_BOL); + if (!state->result) + return JS_FALSE; + state->progLength++; + return JS_TRUE; + case '$': + state->result = NewRENode(state, REOP_EOL); + if (!state->result) + return JS_FALSE; + state->progLength++; + return JS_TRUE; + case '\\': + if (state->cp >= state->cpend) { + /* a trailing '\' is an error */ + js_ReportCompileErrorNumber(state->context, state->tokenStream, + NULL, JSREPORT_ERROR, + JSMSG_TRAILING_SLASH); + return JS_FALSE; + } + c = *state->cp++; + switch (c) { + /* assertion escapes */ + case 'b' : + state->result = NewRENode(state, REOP_WBDRY); + if (!state->result) + return JS_FALSE; + state->progLength++; + return JS_TRUE; + case 'B': + state->result = NewRENode(state, REOP_WNONBDRY); + if (!state->result) + return JS_FALSE; + state->progLength++; + return JS_TRUE; + /* Decimal escape */ + case '0': + if (JS_HAS_STRICT_OPTION(state->context)) + c = 0; + else { + doOctal: + num = 0; + while (state->cp < state->cpend) { + if ('0' <= (c = *state->cp) && c <= '7') { + state->cp++; + tmp = 8 * num + (uintN)JS7_UNDEC(c); + if (tmp > 0377) + break; + num = tmp; + } + else + break; + } + c = (jschar)(num); + } + doFlat: + state->result = NewRENode(state, REOP_FLAT); + if (!state->result) + return JS_FALSE; + state->result->u.flat.chr = c; + state->result->u.flat.length = 1; + state->progLength += 3; + break; + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + termStart = state->cp - 1; + num = (uintN)getDecimalValue(c, state); + if (num > 9 && + num > state->parenCount && + !JS_HAS_STRICT_OPTION(state->context)) { + state->cp = termStart; + goto doOctal; + } + state->result = NewRENode(state, REOP_BACKREF); + if (!state->result) + return JS_FALSE; + state->result->u.parenIndex = num - 1; + state->progLength += 3; + break; + /* Control escape */ + case 'f': + c = 0xC; + goto doFlat; + case 'n': + c = 0xA; + goto doFlat; + case 'r': + c = 0xD; + goto doFlat; + case 't': + c = 0x9; + goto doFlat; + case 'v': + c = 0xB; + goto doFlat; + /* Control letter */ + case 'c': + if (((state->cp + 1) < state->cpend) && + RE_IS_LETTER(state->cp[1])) + c = (jschar)(*state->cp++ & 0x1F); + else { + /* back off to accepting the original '\' as a literal */ + --state->cp; + c = '\\'; + } + goto doFlat; + /* HexEscapeSequence */ + case 'x': + nDigits = 2; + goto lexHex; + /* UnicodeEscapeSequence */ + case 'u': + nDigits = 4; +lexHex: + n = 0; + for (i = 0; (i < nDigits) + && (state->cp < state->cpend); i++) { + uintN digit; + c = *state->cp++; + if (!isASCIIHexDigit(c, &digit)) { + /* + * back off to accepting the original + * 'u' or 'x' as a literal + */ + state->cp -= (i + 2); + n = *state->cp++; + break; + } + n = (n << 4) | digit; + } + c = (jschar)(n); + goto doFlat; + /* Character class escapes */ + case 'd': + state->result = NewRENode(state, REOP_DIGIT); +doSimple: + if (!state->result) + return JS_FALSE; + state->progLength++; + break; + case 'D': + state->result = NewRENode(state, REOP_NONDIGIT); + goto doSimple; + case 's': + state->result = NewRENode(state, REOP_SPACE); + goto doSimple; + case 'S': + state->result = NewRENode(state, REOP_NONSPACE); + goto doSimple; + case 'w': + state->result = NewRENode(state, REOP_ALNUM); + goto doSimple; + case 'W': + state->result = NewRENode(state, REOP_NONALNUM); + goto doSimple; + /* IdentityEscape */ + default: + state->result = NewRENode(state, REOP_FLAT); + if (!state->result) + return JS_FALSE; + state->result->u.flat.chr = c; + state->result->u.flat.length = 1; + state->result->kid = (void *)(state->cp - 1); + state->progLength += 3; + break; + } + break; + case '[': + state->result = NewRENode(state, REOP_CLASS); + if (!state->result) + return JS_FALSE; + termStart = state->cp; + state->result->u.ucclass.startIndex = termStart - state->cpbegin; + while (JS_TRUE) { + if (state->cp == state->cpend) { + js_ReportCompileErrorNumber(state->context, state->tokenStream, + NULL, JSREPORT_ERROR, + JSMSG_UNTERM_CLASS, termStart); + return JS_FALSE; + } + if (*state->cp == '\\') + state->cp++; + else { + if (*state->cp == ']') { + state->result->u.ucclass.kidlen = state->cp - termStart; + break; + } + } + state->cp++; + } + foundCachedCopy = JS_FALSE; + for (i = 0; i < CLASS_CACHE_SIZE; i++) { + if (state->classCache[i].start) { + if (state->classCache[i].length == state->result->u.ucclass.kidlen) { + foundCachedCopy = JS_TRUE; + for (n = 0; n < state->classCache[i].length; n++) { + if (state->classCache[i].start[n] != termStart[n]) { + foundCachedCopy = JS_FALSE; + break; + } + } + if (foundCachedCopy) { + state->result->u.ucclass.index = state->classCache[i].index; + break; + } + } + } + else { + state->classCache[i].start = termStart; + state->classCache[i].length = state->result->u.ucclass.kidlen; + state->classCache[i].index = state->classCount; + break; + } + } + if (!foundCachedCopy) + state->result->u.ucclass.index = state->classCount++; + /* + * Call calculateBitmapSize now as we want any errors it finds + * to be reported during the parse phase, not at execution. + */ + if (!calculateBitmapSize(state, state->result, termStart, state->cp++)) + return JS_FALSE; + state->progLength += 3; /* CLASS, */ + break; + + case '.': + state->result = NewRENode(state, REOP_DOT); + goto doSimple; + case '*': + case '+': + case '?': + js_ReportCompileErrorNumber(state->context, state->tokenStream, + NULL, JSREPORT_ERROR, + JSMSG_BAD_QUANTIFIER, state->cp - 1); + return JS_FALSE; +#if 0 + case '{': /* balance '}' */ + /* Treat left-curly in a non-quantifier context as an error only + * if it's followed immediately by a decimal digit. + * This is an Perl extension. + */ + if ((state->cp != state->cpend) && JS7_ISDEC(*state->cp)) { + js_ReportCompileErrorNumber(state->context, state->tokenStream, + NULL, JSREPORT_ERROR, + JSMSG_BAD_QUANTIFIER, state->cp - 1); + return JS_FALSE; + } + /* fall thru... */ +#endif + default: + state->result = NewRENode(state, REOP_FLAT); + if (!state->result) + return JS_FALSE; + state->result->u.flat.chr = c; + state->result->u.flat.length = 1; + state->result->kid = (void *)(state->cp - 1); + state->progLength += 3; + break; + } + return parseQuantifier(state); +} + +static JSBool +parseQuantifier(CompilerState *state) +{ + RENode *term; + term = state->result; + if (state->cp < state->cpend) { + switch (*state->cp) { + case '+': + state->result = NewRENode(state, REOP_QUANT); + if (!state->result) + return JS_FALSE; + state->result->u.range.min = 1; + state->result->u.range.max = -1; + /* , ... */ + state->progLength += 4; + goto quantifier; + case '*': + state->result = NewRENode(state, REOP_QUANT); + if (!state->result) + return JS_FALSE; + state->result->u.range.min = 0; + state->result->u.range.max = -1; + /* , ... */ + state->progLength += 4; + goto quantifier; + case '?': + state->result = NewRENode(state, REOP_QUANT); + if (!state->result) + return JS_FALSE; + state->result->u.range.min = 0; + state->result->u.range.max = 1; + /* , ... */ + state->progLength += 4; + goto quantifier; + case '{': /* balance '}' */ + { + intN err; + intN min = 0; + intN max = -1; + jschar c; + const jschar *errp = state->cp++; + + c = *state->cp; + if (JS7_ISDEC(c)) { + ++state->cp; + min = getDecimalValue(c, state); + c = *state->cp; + + if ((min + 1) >> 16) { + err = JSMSG_MIN_TOO_BIG; + goto quantError; + } + if (c == ',') { + c = *++state->cp; + if (JS7_ISDEC(c)) { + ++state->cp; + max = getDecimalValue(c, state); + c = *state->cp; + if ((max + 1) >> 16) { + err = JSMSG_MAX_TOO_BIG; + goto quantError; + } + if (min > max) { + err = JSMSG_OUT_OF_ORDER; + goto quantError; + } + } + } + else { + max = min; + } + if (c == '}') { + state->result = NewRENode(state, REOP_QUANT); + if (!state->result) + return JS_FALSE; + state->result->u.range.min = min; + state->result->u.range.max = max; + /* QUANT, , , ... */ + state->progLength += 8; + goto quantifier; + } + } + state->cp = errp; + return JS_TRUE; +quantError: + js_ReportCompileErrorNumber(state->context, + state->tokenStream, + NULL, JSREPORT_ERROR, + err, errp); + return JS_FALSE; + } + } + } + return JS_TRUE; + +quantifier: + ++state->treeDepth; + ++state->cp; + state->result->kid = term; + if ((state->cp < state->cpend) && (*state->cp == '?')) { + ++state->cp; + state->result->u.range.greedy = JS_FALSE; + } + else + state->result->u.range.greedy = JS_TRUE; + return JS_TRUE; +} + +#define CHECK_OFFSET(diff) (JS_ASSERT(((diff) >= -32768) && ((diff) <= 32767))) +#define SET_OFFSET(pc,off) ((pc)[0] = JUMP_OFFSET_HI(off), \ + (pc)[1] = JUMP_OFFSET_LO(off)) +#define GET_OFFSET(pc) ((int16)(((pc)[0] << 8) | (pc)[1])) +#define OFFSET_LEN (2) +#define GET_ARG(pc) GET_OFFSET(pc) +#define SET_ARG(pc,arg) SET_OFFSET(pc,arg) +#define ARG_LEN OFFSET_LEN + +/* + * Recursively generate bytecode for the tree rooted at t. Iteratively. + */ + +typedef struct { + RENode *nextAlt; + jsbytecode *nextAltFixup, *nextTermFixup, *endTermFixup; + RENode *continueNode; + REOp continueOp; +} EmitStateStackEntry; + +static jsbytecode * +emitREBytecode(CompilerState *state, JSRegExp *re, intN treeDepth, + jsbytecode *pc, RENode *t) +{ + ptrdiff_t diff; + RECharSet *charSet; + EmitStateStackEntry *emitStateSP, *emitStateStack = NULL; + REOp op; + + if (treeDepth) { + emitStateStack = + (EmitStateStackEntry *)JS_malloc(state->context, + sizeof(EmitStateStackEntry) + * treeDepth); + if (!emitStateStack) + return NULL; + } + emitStateSP = emitStateStack; + op = t->op; + + while (JS_TRUE) { + *pc++ = op; + switch (op) { + case REOP_EMPTY: + --pc; + break; + + case REOP_ALTPREREQ2: + case REOP_ALTPREREQ: + JS_ASSERT(emitStateSP); + emitStateSP->endTermFixup = pc; + pc += OFFSET_LEN; + SET_ARG(pc, t->u.altprereq.ch1); + pc += ARG_LEN; + SET_ARG(pc, t->u.altprereq.ch2); + pc += ARG_LEN; + + emitStateSP->nextAltFixup = pc; /* address of next alternate */ + pc += OFFSET_LEN; + + emitStateSP->continueNode = t; + emitStateSP->continueOp = REOP_JUMP; + ++emitStateSP; + JS_ASSERT((emitStateSP - emitStateStack) <= treeDepth); + t = (RENode *)(t->kid); + op = t->op; + continue; + + case REOP_JUMP: + emitStateSP->nextTermFixup = pc; /* address of following term */ + pc += OFFSET_LEN; + diff = pc - emitStateSP->nextAltFixup; + CHECK_OFFSET(diff); + SET_OFFSET(emitStateSP->nextAltFixup, diff); + emitStateSP->continueOp = REOP_ENDALT; + ++emitStateSP; + JS_ASSERT((emitStateSP - emitStateStack) <= treeDepth); + t = (RENode *)(t->u.kid2); + op = t->op; + continue; + + case REOP_ENDALT: + diff = pc - emitStateSP->nextTermFixup; + CHECK_OFFSET(diff); + SET_OFFSET(emitStateSP->nextTermFixup, diff); + if (t->op != REOP_ALT) { + diff = pc - emitStateSP->endTermFixup; + CHECK_OFFSET(diff); + SET_OFFSET(emitStateSP->endTermFixup, diff); + } + break; + + case REOP_ALT: + JS_ASSERT(emitStateSP); + emitStateSP->nextAltFixup = pc; /* address of pointer to next alternate */ + pc += OFFSET_LEN; + emitStateSP->continueNode = t; + emitStateSP->continueOp = REOP_JUMP; + ++emitStateSP; + JS_ASSERT((emitStateSP - emitStateStack) <= treeDepth); + t = (RENode *)(t->kid); + op = t->op; + continue; + + case REOP_FLAT: + /* + * Consecutize FLAT's if possible. + */ + if (t->kid) { + while (t->next && (t->next->op == REOP_FLAT) + && (((jschar*)(t->kid) + t->u.flat.length) + == (jschar*)(t->next->kid))) { + t->u.flat.length += t->next->u.flat.length; + t->next = t->next->next; + } + } + if (t->kid && (t->u.flat.length > 1)) { + if (state->flags & JSREG_FOLD) + pc[-1] = REOP_FLATi; + else + pc[-1] = REOP_FLAT; + SET_ARG(pc, (jschar *)(t->kid) - state->cpbegin); + pc += ARG_LEN; + SET_ARG(pc, t->u.flat.length); + pc += ARG_LEN; + } + else { + if (t->u.flat.chr < 256) { + if (state->flags & JSREG_FOLD) + pc[-1] = REOP_FLAT1i; + else + pc[-1] = REOP_FLAT1; + *pc++ = (jsbytecode)(t->u.flat.chr); + } + else { + if (state->flags & JSREG_FOLD) + pc[-1] = REOP_UCFLAT1i; + else + pc[-1] = REOP_UCFLAT1; + SET_ARG(pc, t->u.flat.chr); + pc += ARG_LEN; + } + } + break; + + case REOP_LPAREN: + JS_ASSERT(emitStateSP); + SET_ARG(pc, t->u.parenIndex); + pc += ARG_LEN; + emitStateSP->continueNode = t; + emitStateSP->continueOp = REOP_RPAREN; + ++emitStateSP; + JS_ASSERT((emitStateSP - emitStateStack) <= treeDepth); + t = (RENode *)(t->kid); + op = t->op; + continue; + case REOP_RPAREN: + SET_ARG(pc, t->u.parenIndex); + pc += ARG_LEN; + break; + + case REOP_BACKREF: + SET_ARG(pc, t->u.parenIndex); + pc += ARG_LEN; + break; + case REOP_ASSERT: + JS_ASSERT(emitStateSP); + emitStateSP->nextTermFixup = pc; + pc += OFFSET_LEN; + emitStateSP->continueNode = t; + emitStateSP->continueOp = REOP_ASSERTTEST; + ++emitStateSP; + JS_ASSERT((emitStateSP - emitStateStack) <= treeDepth); + t = (RENode *)(t->kid); + op = t->op; + continue; + case REOP_ASSERTTEST: + case REOP_ASSERTNOTTEST: + diff = pc - emitStateSP->nextTermFixup; + CHECK_OFFSET(diff); + SET_OFFSET(emitStateSP->nextTermFixup, diff); + break; + case REOP_ASSERT_NOT: + JS_ASSERT(emitStateSP); + emitStateSP->nextTermFixup = pc; + pc += OFFSET_LEN; + emitStateSP->continueNode = t; + emitStateSP->continueOp = REOP_ASSERTNOTTEST; + ++emitStateSP; + JS_ASSERT((emitStateSP - emitStateStack) <= treeDepth); + t = (RENode *)(t->kid); + op = t->op; + continue; + case REOP_QUANT: + JS_ASSERT(emitStateSP); + if ((t->u.range.min == 0) && (t->u.range.max == (uint16)(-1))) + pc[-1] = (t->u.range.greedy) ? REOP_STAR : REOP_MINIMALSTAR; + else + if ((t->u.range.min == 0) && (t->u.range.max == 1)) + pc[-1] = (t->u.range.greedy) ? REOP_OPT : REOP_MINIMALOPT; + else + if ((t->u.range.min == 1) && (t->u.range.max == (uint16)(-1))) + pc[-1] = (t->u.range.greedy) ? REOP_PLUS : REOP_MINIMALPLUS; + else { + if (!t->u.range.greedy) pc[-1] = REOP_MINIMALQUANT; + SET_ARG(pc, t->u.range.min); + pc += ARG_LEN; + SET_ARG(pc, t->u.range.max); + pc += ARG_LEN; + } + emitStateSP->nextTermFixup = pc; + pc += OFFSET_LEN; + emitStateSP->continueNode = t; + emitStateSP->continueOp = REOP_ENDCHILD; + ++emitStateSP; + JS_ASSERT((emitStateSP - emitStateStack) <= treeDepth); + t = (RENode *)(t->kid); + op = t->op; + continue; + case REOP_ENDCHILD: + diff = pc - emitStateSP->nextTermFixup; + CHECK_OFFSET(diff); + SET_OFFSET(emitStateSP->nextTermFixup, diff); + break; + case REOP_CLASS: + if (!t->u.ucclass.sense) + pc[-1] = REOP_NCLASS; + SET_ARG(pc, t->u.ucclass.index); + pc += ARG_LEN; + charSet = &re->classList[t->u.ucclass.index]; + charSet->converted = JS_FALSE; + charSet->length = t->u.ucclass.bmsize; + charSet->u.src.startIndex = t->u.ucclass.startIndex; + charSet->u.src.length = t->u.ucclass.kidlen; + charSet->sense = t->u.ucclass.sense; + break; + default: + break; + } + t = t->next; + if (t == NULL) { + if (emitStateSP == emitStateStack) + break; + --emitStateSP; + t = emitStateSP->continueNode; + op = emitStateSP->continueOp; + } + else + op = t->op; + } + if (emitStateStack) + JS_free(state->context, emitStateStack); + return pc; +} + + +JSRegExp * +js_NewRegExp(JSContext *cx, JSTokenStream *ts, + JSString *str, uintN flags, JSBool flat) +{ + JSRegExp *re; + void *mark; + CompilerState state; + size_t resize; + jsbytecode *endPC; + uint32 i; + size_t len; + + re = NULL; + mark = JS_ARENA_MARK(&cx->tempPool); + + state.context = cx; + state.tokenStream = ts; + state.cpbegin = state.cp = JSSTRING_CHARS(str); + state.cpend = state.cp + JSSTRING_LENGTH(str); + state.flags = flags; + state.parenCount = 0; + state.classCount = 0; + state.progLength = 0; + state.treeDepth = 0; + for (i = 0; i < CLASS_CACHE_SIZE; i++) + state.classCache[i].start = NULL; + + len = JSSTRING_LENGTH(str); + + if (len != 0 && flat) { + state.result = NewRENode(&state, REOP_FLAT); + state.result->u.flat.chr = *state.cpbegin; + state.result->u.flat.length = JSSTRING_LENGTH(str); + state.result->kid = (void *)(state.cpbegin); + state.progLength += 5; + } + else { + if (!parseRegExp(&state)) + goto out; + } + resize = sizeof *re + state.progLength + 1; + re = (JSRegExp *) JS_malloc(cx, JS_ROUNDUP(resize, sizeof(jsword))); + if (!re) + goto out; + + re->classCount = state.classCount; + if (state.classCount) { + re->classList = (RECharSet *)JS_malloc(cx, sizeof(RECharSet) + * state.classCount); + if (!re->classList) + goto out; + } + else + re->classList = NULL; + endPC = emitREBytecode(&state, re, state.treeDepth, re->program, state.result); + if (!endPC) { + re = NULL; + goto out; + } + *endPC++ = REOP_END; + JS_ASSERT(endPC <= (re->program + (state.progLength + 1))); + + re->nrefs = 1; + re->parenCount = state.parenCount; + re->flags = flags; + re->source = str; + +out: + JS_ARENA_RELEASE(&cx->tempPool, mark); + return re; +} + +JSRegExp * +js_NewRegExpOpt(JSContext *cx, JSTokenStream *ts, + JSString *str, JSString *opt, JSBool flat) +{ + uintN flags; + jschar *s; + size_t i, n; + char charBuf[2]; + + flags = 0; + if (opt) { + s = JSSTRING_CHARS(opt); + for (i = 0, n = JSSTRING_LENGTH(opt); i < n; i++) { + switch (s[i]) { + case 'g': + flags |= JSREG_GLOB; + break; + case 'i': + flags |= JSREG_FOLD; + break; + case 'm': + flags |= JSREG_MULTILINE; + break; + default: + charBuf[0] = (char)s[i]; + charBuf[1] = '\0'; + js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR, + JSMSG_BAD_FLAG, charBuf); + return NULL; + } + } + } + return js_NewRegExp(cx, ts, str, flags, flat); +} + + +#define HOLD_REGEXP(cx, re) JS_ATOMIC_INCREMENT(&(re)->nrefs) +#define DROP_REGEXP(cx, re) js_DestroyRegExp(cx, re) + +/* + * Save the current state of the match - the position in the input + * text as well as the position in the bytecode. The state of any + * parent expressions is also saved (preceding state). + * Contents of parenCount parentheses from parenIndex are also saved. + */ +static REBackTrackData * +pushBackTrackState(REGlobalData *gData, REOp op, + jsbytecode *target, REMatchState *x, const jschar *cp, + intN parenIndex, intN parenCount) +{ + intN i; + REBackTrackData *result + = (REBackTrackData *)((char *)(gData->backTrackSP) + gData->cursz); + + size_t sz = sizeof(REBackTrackData) + + gData->stateStackTop * sizeof(REProgState) + + parenCount * sizeof(RECapture); + + + if (((char *)result + sz) + > (char *)gData->backTrackStack + gData->maxBackTrack) { + ptrdiff_t offset = (char *)result - (char *)gData->backTrackStack; + gData->backTrackStack + = (REBackTrackData *)JS_ArenaGrow(&gData->pool, + gData->backTrackStack, + gData->maxBackTrack, + gData->maxBackTrack); + gData->maxBackTrack <<= 1; + if (!gData->backTrackStack) + return NULL; + result = (REBackTrackData *)((char *)gData->backTrackStack + offset); + } + gData->backTrackSP = result; + result->sz = gData->cursz; + gData->cursz = sz; + + result->backtrack_op = op; + result->backtrack_pc = target; + result->cp = cp; + result->parenCount = parenCount; + + result->precedingStateTop = gData->stateStackTop; + JS_ASSERT(gData->stateStackTop); + memcpy(result + 1, gData->stateStack, + sizeof(REProgState) * result->precedingStateTop); + + if (parenCount != -1) { + result->parenIndex = parenIndex; + memcpy((char *)(result + 1) + + sizeof(REProgState) * result->precedingStateTop, + &x->parens[parenIndex], + sizeof(RECapture) * parenCount); + for (i = 0; i < parenCount; i++) + x->parens[parenIndex + i].index = -1; + } + + return result; +} + + +/* + * Consecutive literal characters. + */ +#if 0 +static REMatchState * +flatNMatcher(REGlobalData *gData, REMatchState *x, jschar *matchChars, + intN length) +{ + intN i; + if ((x->cp + length) > gData->cpend) + return NULL; + for (i = 0; i < length; i++) { + if (matchChars[i] != x->cp[i]) + return NULL; + } + x->cp += length; + return x; +} +#endif + +static REMatchState * +flatNIMatcher(REGlobalData *gData, REMatchState *x, jschar *matchChars, + intN length) +{ + intN i; + if ((x->cp + length) > gData->cpend) + return NULL; + for (i = 0; i < length; i++) { + if (upcase(matchChars[i]) != upcase(x->cp[i])) + return NULL; + } + x->cp += length; + return x; +} + +/* + * 1. Evaluate DecimalEscape to obtain an EscapeValue E. + * 2. If E is not a character then go to step 6. + * 3. Let ch be E's character. + * 4. Let A be a one-element RECharSet containing the character ch. + * 5. Call CharacterSetMatcher(A, false) and return its Matcher result. + * 6. E must be an integer. Let n be that integer. + * 7. If n=0 or n>NCapturingParens then throw a SyntaxError exception. + * 8. Return an internal Matcher closure that takes two arguments, a State x + * and a Continuation c, and performs the following: + * 1. Let cap be x's captures internal array. + * 2. Let s be cap[n]. + * 3. If s is undefined, then call c(x) and return its result. + * 4. Let e be x's endIndex. + * 5. Let len be s's length. + * 6. Let f be e+len. + * 7. If f>InputLength, return failure. + * 8. If there exists an integer i between 0 (inclusive) and len (exclusive) + * such that Canonicalize(s[i]) is not the same character as + * Canonicalize(Input [e+i]), then return failure. + * 9. Let y be the State (f, cap). + * 10. Call c(y) and return its result. + */ +static REMatchState * +backrefMatcher(REGlobalData *gData, REMatchState *x, uintN parenIndex) +{ + uintN len; + uintN i; + const jschar *parenContent; + RECapture *s = &x->parens[parenIndex]; + if (s->index == -1) + return x; + + len = s->length; + if ((x->cp + len) > gData->cpend) + return NULL; + + parenContent = &gData->cpbegin[s->index]; + if (gData->regexp->flags & JSREG_FOLD) { + for (i = 0; i < len; i++) { + if (upcase(parenContent[i]) != upcase(x->cp[i])) + return NULL; + } + } + else { + for (i = 0; i < len; i++) { + if (parenContent[i] != x->cp[i]) + return NULL; + } + } + x->cp += len; + return x; +} + + +/* Add a single character to the RECharSet */ +static void +addCharacterToCharSet(RECharSet *cs, jschar c) +{ + uintN byteIndex = (uintN)(c / 8); + JS_ASSERT(c <= cs->length); + cs->u.bits[byteIndex] |= 1 << (c & 0x7); +} + + +/* Add a character range, c1 to c2 (inclusive) to the RECharSet */ +static void +addCharacterRangeToCharSet(RECharSet *cs, jschar c1, jschar c2) +{ + uintN i; + + uintN byteIndex1 = (uintN)(c1 / 8); + uintN byteIndex2 = (uintN)(c2 / 8); + + JS_ASSERT((c2 <= cs->length) && (c1 <= c2)); + + c1 &= 0x7; + c2 &= 0x7; + + if (byteIndex1 == byteIndex2) + cs->u.bits[byteIndex1] |= ((uint8)(0xFF) >> (7 - (c2 - c1))) << c1; + else { + cs->u.bits[byteIndex1] |= 0xFF << c1; + for (i = byteIndex1 + 1; i < byteIndex2; i++) + cs->u.bits[i] = 0xFF; + cs->u.bits[byteIndex2] |= (uint8)(0xFF) >> (7 - c2); + } +} + +/* Compile the source of the class into a RECharSet */ +static JSBool +processCharSet(REGlobalData *gData, RECharSet *charSet) +{ + const jschar *src = JSSTRING_CHARS(gData->regexp->source) + + charSet->u.src.startIndex; + const jschar *end = src + charSet->u.src.length; + + jschar rangeStart, thisCh; + uintN byteLength; + jschar c; + uintN n; + intN nDigits; + intN i; + JSBool inRange = JS_FALSE; + + JS_ASSERT(!charSet->converted); + charSet->converted = JS_TRUE; + + byteLength = (charSet->length / 8) + 1; + charSet->u.bits = (uint8 *)JS_malloc(gData->cx, byteLength); + if (!charSet->u.bits) + return JS_FALSE; + memset(charSet->u.bits, 0, byteLength); + + if (src == end) + return JS_TRUE; + + if (*src == '^') { + JS_ASSERT(charSet->sense == JS_FALSE); + ++src; + } + else + JS_ASSERT(charSet->sense == JS_TRUE); + + + while (src != end) { + switch (*src) { + case '\\': + ++src; + c = *src++; + switch (c) { + case 'b': + thisCh = 0x8; + break; + case 'f': + thisCh = 0xC; + break; + case 'n': + thisCh = 0xA; + break; + case 'r': + thisCh = 0xD; + break; + case 't': + thisCh = 0x9; + break; + case 'v': + thisCh = 0xB; + break; + case 'c': + if (((src + 1) < end) && JS_ISWORD(src[1])) + thisCh = (jschar)(*src++ & 0x1F); + else { + --src; + thisCh = '\\'; + } + break; + case 'x': + nDigits = 2; + goto lexHex; + case 'u': + nDigits = 4; +lexHex: + n = 0; + for (i = 0; (i < nDigits) && (src < end); i++) { + uintN digit; + c = *src++; + if (!isASCIIHexDigit(c, &digit)) { + /* + * Back off to accepting the original '\' + * as a literal + */ + src -= (i + 1); + n = '\\'; + break; + } + n = (n << 4) | digit; + } + thisCh = (jschar)(n); + break; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + /* + * This is a non-ECMA extension - decimal escapes (in this + * case, octal!) are supposed to be an error inside class + * ranges, but supported here for backwards compatibility. + * + */ + n = JS7_UNDEC(c); + c = *src; + if ('0' <= c && c <= '7') { + src++; + n = 8 * n + JS7_UNDEC(c); + c = *src; + if ('0' <= c && c <= '7') { + src++; + i = 8 * n + JS7_UNDEC(c); + if (i <= 0377) + n = i; + else + src--; + } + } + thisCh = (jschar)(n); + break; + + case 'd': + addCharacterRangeToCharSet(charSet, '0', '9'); + continue; /* don't need range processing */ + case 'D': + addCharacterRangeToCharSet(charSet, 0, '0' - 1); + addCharacterRangeToCharSet(charSet, (jschar)('9' + 1), + (jschar)(charSet->length)); + continue; + case 's': + for (i = (intN)(charSet->length); i >= 0; i--) + if (JS_ISSPACE(i)) + addCharacterToCharSet(charSet, (jschar)(i)); + continue; + case 'S': + for (i = (intN)(charSet->length); i >= 0; i--) + if (!JS_ISSPACE(i)) + addCharacterToCharSet(charSet, (jschar)(i)); + continue; + case 'w': + for (i = (intN)(charSet->length); i >= 0; i--) + if (JS_ISWORD(i)) + addCharacterToCharSet(charSet, (jschar)(i)); + continue; + case 'W': + for (i = (intN)(charSet->length); i >= 0; i--) + if (!JS_ISWORD(i)) + addCharacterToCharSet(charSet, (jschar)(i)); + continue; + default: + thisCh = c; + break; + + } + break; + + default: + thisCh = *src++; + break; + + } + if (inRange) { + if (gData->regexp->flags & JSREG_FOLD) { + addCharacterRangeToCharSet(charSet, upcase(rangeStart), + upcase(thisCh)); + addCharacterRangeToCharSet(charSet, downcase(rangeStart), + downcase(thisCh)); + } else { + addCharacterRangeToCharSet(charSet, rangeStart, thisCh); + } + inRange = JS_FALSE; + } + else { + if (gData->regexp->flags & JSREG_FOLD) { + addCharacterToCharSet(charSet, upcase(thisCh)); + addCharacterToCharSet(charSet, downcase(thisCh)); + } else { + addCharacterToCharSet(charSet, thisCh); + } + if (src < (end - 1)) { + if (*src == '-') { + ++src; + inRange = JS_TRUE; + rangeStart = thisCh; + } + } + } + } + return JS_TRUE; +} + +void +js_DestroyRegExp(JSContext *cx, JSRegExp *re) +{ + uintN i; + if (JS_ATOMIC_DECREMENT(&re->nrefs) == 0) { + if (re->classList) { + for (i = 0; i < re->classCount; i++) { + if (re->classList[i].converted) + JS_free(cx, re->classList[i].u.bits); + re->classList[i].u.bits = NULL; + } + JS_free(cx, re->classList); + } + JS_free(cx, re); + } +} + +static JSBool +reallocStateStack(REGlobalData *gData) +{ + size_t sz = sizeof(REProgState) * gData->maxStateStack; + gData->maxStateStack <<= 1; + gData->stateStack + = (REProgState *)JS_ArenaGrow(&gData->pool, gData->stateStack, sz, sz); + if (!gData->stateStack) { + gData->ok = JS_FALSE; + return JS_FALSE; + } + return JS_TRUE; +} + +/* +* Apply the current op against the given input to see if +* it's going to match or fail. Return false if we don't +* get a match, true if we do and update the state of the +* input and pc if the update flag is true. +*/ +static REMatchState *simpleMatch(REGlobalData *gData, REMatchState *x, + REOp op, jsbytecode **startpc, JSBool update) +{ + REMatchState *result = NULL; + jschar matchCh; + intN parenIndex; + intN offset, length, index; + jsbytecode *pc = *startpc; /* pc has already been incremented past op */ + jschar *source; + const jschar *startcp = x->cp; + jschar ch; + RECharSet *charSet; + + + switch (op) { + default: + JS_ASSERT(JS_FALSE); + case REOP_BOL: + if (x->cp != gData->cpbegin) { + if (gData->cx->regExpStatics.multiline || + (gData->regexp->flags & JSREG_MULTILINE)) { + if (!RE_IS_LINE_TERM(x->cp[-1])) + break; + } + else + break; + } + result = x; + break; + case REOP_EOL: + if (x->cp != gData->cpend) { + if (gData->cx->regExpStatics.multiline || + (gData->regexp->flags & JSREG_MULTILINE)) { + if (!RE_IS_LINE_TERM(*x->cp)) + break; + } + else + break; + } + result = x; + break; + case REOP_WBDRY: + if ((x->cp == gData->cpbegin || !JS_ISWORD(x->cp[-1])) + ^ !((x->cp != gData->cpend) && JS_ISWORD(*x->cp))) + result = x; + break; + case REOP_WNONBDRY: + if ((x->cp == gData->cpbegin || !JS_ISWORD(x->cp[-1])) + ^ ((x->cp != gData->cpend) && JS_ISWORD(*x->cp))) + result = x; + break; + case REOP_DOT: + if (x->cp != gData->cpend && !RE_IS_LINE_TERM(*x->cp)) { + result = x; + result->cp++; + } + break; + case REOP_DIGIT: + if (x->cp != gData->cpend && JS_ISDIGIT(*x->cp)) { + result = x; + result->cp++; + } + break; + case REOP_NONDIGIT: + if (x->cp != gData->cpend && !JS_ISDIGIT(*x->cp)) { + result = x; + result->cp++; + } + break; + case REOP_ALNUM: + if (x->cp != gData->cpend && JS_ISWORD(*x->cp)) { + result = x; + result->cp++; + } + break; + case REOP_NONALNUM: + if (x->cp != gData->cpend && !JS_ISWORD(*x->cp)) { + result = x; + result->cp++; + } + break; + case REOP_SPACE: + if (x->cp != gData->cpend && JS_ISSPACE(*x->cp)) { + result = x; + result->cp++; + } + break; + case REOP_NONSPACE: + if (x->cp != gData->cpend && !JS_ISSPACE(*x->cp)) { + result = x; + result->cp++; + } + break; + case REOP_BACKREF: + parenIndex = GET_ARG(pc); + pc += ARG_LEN; + result = backrefMatcher(gData, x, parenIndex); + break; + case REOP_FLAT: + offset = GET_ARG(pc); + pc += ARG_LEN; + length = GET_ARG(pc); + pc += ARG_LEN; + source = JSSTRING_CHARS(gData->regexp->source) + offset; + if ((x->cp + length) <= gData->cpend) { + for (index = 0; index < length; index++) { + if (source[index] != x->cp[index]) + return NULL; + } + x->cp += length; + result = x; + } + break; + case REOP_FLAT1: + matchCh = *pc++; + if ((x->cp != gData->cpend) && (*x->cp == matchCh)) { + result = x; + result->cp++; + } + break; + case REOP_FLATi: + offset = GET_ARG(pc); + pc += ARG_LEN; + length = GET_ARG(pc); + pc += ARG_LEN; + source = JSSTRING_CHARS(gData->regexp->source); + result = flatNIMatcher(gData, x, source + offset, length); + break; + case REOP_FLAT1i: + matchCh = *pc++; + if ((x->cp != gData->cpend) && (upcase(*x->cp) == upcase(matchCh))) { + result = x; + result->cp++; + } + break; + case REOP_UCFLAT1: + matchCh = GET_ARG(pc); + pc += ARG_LEN; + if ((x->cp != gData->cpend) && (*x->cp == matchCh)) { + result = x; + result->cp++; + } + break; + case REOP_UCFLAT1i: + matchCh = GET_ARG(pc); + pc += ARG_LEN; + if ((x->cp != gData->cpend) && (upcase(*x->cp) == upcase(matchCh))) { + result = x; + result->cp++; + } + break; + case REOP_CLASS: + index = GET_ARG(pc); + pc += ARG_LEN; + if (x->cp != gData->cpend) { + charSet = &gData->regexp->classList[index]; + JS_ASSERT(charSet->converted); + ch = *x->cp; + index = ch / 8; + if ((charSet->length != 0) && + ( (ch <= charSet->length) + && ((charSet->u.bits[index] & (1 << (ch & 0x7))) != 0) )) { + result = x; + result->cp++; + } + } + break; + case REOP_NCLASS: + index = GET_ARG(pc); + pc += ARG_LEN; + if (x->cp != gData->cpend) { + charSet = &gData->regexp->classList[index]; + JS_ASSERT(charSet->converted); + ch = *x->cp; + index = ch / 8; + if ((charSet->length == 0) || + ( (ch > charSet->length) + || ((charSet->u.bits[index] & (1 << (ch & 0x7))) == 0) )) { + result = x; + result->cp++; + } + } + break; + } + if (result != NULL) { + if (update) + *startpc = pc; + else + x->cp = startcp; + return result; + } + x->cp = startcp; + return NULL; +} + +static REMatchState * +executeREBytecode(REGlobalData *gData, REMatchState *x) +{ + REMatchState *result; + REBackTrackData *backTrackData; + intN offset; + jsbytecode *nextpc; + REOp nextop; + RECapture *cap; + REProgState *curState; + const jschar *startcp; + uintN parenIndex, k; + uintN parenSoFar = 0; + + jschar matchCh1, matchCh2; + RECharSet *charSet; + + JSBool anchor; + jsbytecode *pc = gData->regexp->program; + REOp op = (REOp)(*pc++); + + /* + * If the first node is a simple match, step the index into + * the string until that match is made, or fail if it can't be + * found at all. + */ + if (REOP_IS_SIMPLE(op)) { + anchor = JS_FALSE; + while (x->cp <= gData->cpend) { + nextpc = pc; /* reset back to start each time */ + result = simpleMatch(gData, x, op, &nextpc, JS_TRUE); + if (result) { + anchor = JS_TRUE; + x = result; + pc = nextpc; /* accept skip to next opcode */ + op = (REOp)(*pc++); + break; + } + else { + gData->skipped++; + x->cp++; + } + } + if (!anchor) + return NULL; + } + + while (JS_TRUE) { + if (REOP_IS_SIMPLE(op)) + result = simpleMatch(gData, x, op, &pc, JS_TRUE); + else { + curState = &gData->stateStack[gData->stateStackTop]; + switch (op) { + case REOP_EMPTY: + result = x; + break; + + case REOP_ALTPREREQ2: + nextpc = pc + GET_OFFSET(pc); /* start of next op */ + pc += ARG_LEN; + matchCh2 = GET_ARG(pc); + pc += ARG_LEN; + k = GET_ARG(pc); + pc += ARG_LEN; + + if (x->cp != gData->cpend) { + if (*x->cp == matchCh2) + goto doAlt; + + charSet = &gData->regexp->classList[k]; + if (!charSet->converted) + if (!processCharSet(gData, charSet)) + return NULL; + matchCh1 = *x->cp; + k = matchCh1 / 8; + if ((charSet->length == 0 || + matchCh1 > charSet->length || + (charSet->u.bits[k] & (1 << (matchCh1 & 0x7))) == 0) + ^ charSet->sense) { + goto doAlt; + } + } + result = NULL; + break; + + case REOP_ALTPREREQ: + nextpc = pc + GET_OFFSET(pc); /* start of next op */ + pc += ARG_LEN; + matchCh1 = GET_ARG(pc); + pc += ARG_LEN; + matchCh2 = GET_ARG(pc); + pc += ARG_LEN; + if ((x->cp == gData->cpend) + || ((*x->cp != matchCh1) && (*x->cp != matchCh2))) { + result = NULL; + break; + } + /* else false thru... */ + + case REOP_ALT: +doAlt: + nextpc = pc + GET_OFFSET(pc); /* start of next alternate */ + pc += ARG_LEN; /* start of this alternate */ + curState->parenSoFar = parenSoFar; + ++gData->stateStackTop; + if (gData->stateStackTop == gData->maxStateStack) + if (!reallocStateStack(gData)) + return NULL; + op = (REOp)(*pc++); + startcp = x->cp; + if (REOP_IS_SIMPLE(op)) { + if (!simpleMatch(gData, x, op, &pc, JS_TRUE)) { + op = (REOp)(*nextpc++); + pc = nextpc; + continue; + } + else { /* accept the match and move on */ + result = x; + op = (REOp)(*pc++); + } + } + nextop = (REOp)(*nextpc++); + if (!pushBackTrackState(gData, nextop, nextpc, x, startcp, 0, 0)) + return NULL; + continue; + + /* + * Occurs at (succesful) end of REOP_ALT, + */ + case REOP_JUMP: + --gData->stateStackTop; + offset = GET_OFFSET(pc); + pc += offset; + op = (REOp)(*pc++); + continue; + + /* + * Occurs at last (succesful) end of REOP_ALT, + */ + case REOP_ENDALT: + --gData->stateStackTop; + op = (REOp)(*pc++); + continue; + + case REOP_LPAREN: + parenIndex = GET_ARG(pc); + if ((parenIndex + 1) > parenSoFar) + parenSoFar = parenIndex + 1; + pc += ARG_LEN; + x->parens[parenIndex].index = x->cp - gData->cpbegin; + x->parens[parenIndex].length = 0; + op = (REOp)(*pc++); + continue; + case REOP_RPAREN: + parenIndex = GET_ARG(pc); + pc += ARG_LEN; + cap = &x->parens[parenIndex]; + cap->length = x->cp - (gData->cpbegin + cap->index); + op = (REOp)(*pc++); + continue; + + case REOP_ASSERT: + nextpc = pc + GET_OFFSET(pc); /* start of term after ASSERT */ + pc += ARG_LEN; /* start of ASSERT child */ + op = (REOp)(*pc++); + if (REOP_IS_SIMPLE(op) + && !simpleMatch(gData, x, op, &pc, JS_FALSE)) { + result = NULL; + break; + } + else { + curState->u.assertion.top + = (char *)gData->backTrackSP + - (char *)gData->backTrackStack; + curState->u.assertion.sz = gData->cursz; + curState->index = x->cp - gData->cpbegin; + curState->parenSoFar = parenSoFar; + ++gData->stateStackTop; + if (gData->stateStackTop == gData->maxStateStack) + if (!reallocStateStack(gData)) + return NULL; + if (!pushBackTrackState(gData, REOP_ASSERTTEST, + nextpc, x, x->cp, 0, 0)) + return NULL; + } + continue; + case REOP_ASSERT_NOT: + nextpc = pc + GET_OFFSET(pc); + pc += ARG_LEN; + op = (REOp)(*pc++); + if (REOP_IS_SIMPLE(op) + /* Note - fail to fail! */ + && simpleMatch(gData, x, op, &pc, JS_FALSE)) { + result = NULL; + break; + } + else { + curState->u.assertion.top + = (char *)gData->backTrackSP + - (char *)gData->backTrackStack; + curState->u.assertion.sz = gData->cursz; + curState->index = x->cp - gData->cpbegin; + curState->parenSoFar = parenSoFar; + ++gData->stateStackTop; + if (gData->stateStackTop == gData->maxStateStack) + if (!reallocStateStack(gData)) + return NULL; + if (!pushBackTrackState(gData, REOP_ASSERTNOTTEST, + nextpc, x, x->cp, 0, 0)) + return NULL; + } + continue; + case REOP_ASSERTTEST: + --gData->stateStackTop; + --curState; + x->cp = gData->cpbegin + curState->index; + gData->backTrackSP + = (REBackTrackData *)((char *)gData->backTrackStack + + curState->u.assertion.top); + gData->cursz = curState->u.assertion.sz; + if (result != NULL) + result = x; + break; + case REOP_ASSERTNOTTEST: + --gData->stateStackTop; + --curState; + x->cp = gData->cpbegin + curState->index; + gData->backTrackSP + = (REBackTrackData *)((char *)gData->backTrackStack + + curState->u.assertion.top); + gData->cursz = curState->u.assertion.sz; + if (result == NULL) + result = x; + else + result = NULL; + break; + + case REOP_END: + if (x != NULL) + return x; + break; + + case REOP_STAR: + curState->u.quantifier.min = 0; + curState->u.quantifier.max = -1; + goto quantcommon; + case REOP_PLUS: + curState->u.quantifier.min = 1; + curState->u.quantifier.max = -1; + goto quantcommon; + case REOP_OPT: + curState->u.quantifier.min = 0; + curState->u.quantifier.max = 1; + goto quantcommon; + case REOP_QUANT: + curState->u.quantifier.min = GET_ARG(pc); + pc += ARG_LEN; + curState->u.quantifier.max = GET_ARG(pc); + pc += ARG_LEN; +quantcommon: + if (curState->u.quantifier.max == 0) { + pc = pc + GET_OFFSET(pc); + op = (REOp)(*pc++); + result = x; + continue; + } + /* Step over */ + nextpc = pc + ARG_LEN; + op = (REOp)(*nextpc++); + startcp = x->cp; + if (REOP_IS_SIMPLE(op)) { + if (!simpleMatch(gData, x, op, &nextpc, JS_TRUE)) { + if (curState->u.quantifier.min == 0) + result = x; + else + result = NULL; + pc = pc + GET_OFFSET(pc); + break; + } + else { + op = (REOp)(*nextpc++); + result = x; + } + } + curState->index = startcp - gData->cpbegin; + curState->continue_op = REOP_REPEAT; + curState->continue_pc = pc; + curState->parenSoFar = parenSoFar; + ++gData->stateStackTop; + if (gData->stateStackTop == gData->maxStateStack) + if (!reallocStateStack(gData)) + return NULL; + if (curState->u.quantifier.min == 0) + if (!pushBackTrackState(gData, REOP_REPEAT, + pc, x, startcp, 0, 0)) + return NULL; + pc = nextpc; + continue; + + case REOP_ENDCHILD: /* marks the end of a quantifier child */ + pc = curState[-1].continue_pc; + op = curState[-1].continue_op; + continue; + + case REOP_REPEAT: + --curState; +repeatAgain: + --gData->stateStackTop; + if (result == NULL) { + /* + * There's been a failure, see if we have enough children. + */ + if (curState->u.quantifier.min == 0) { + result = x; + goto repeatDone; + } + break; + } + else { + if ((curState->u.quantifier.min == 0) + && (x->cp == gData->cpbegin + curState->index)) { + /* matched an empty string, that'll get us nowhere */ + result = NULL; + break; + } + if (curState->u.quantifier.min != 0) + curState->u.quantifier.min--; + if (curState->u.quantifier.max != (uint16)(-1)) + curState->u.quantifier.max--; + if (curState->u.quantifier.max == 0) { + result = x; + goto repeatDone; + } + nextpc = pc + ARG_LEN; + nextop = (REOp)(*nextpc); + startcp = x->cp; + if (REOP_IS_SIMPLE(nextop)) { + nextpc++; + if (!simpleMatch(gData, x, nextop, &nextpc, JS_TRUE)) { + if (curState->u.quantifier.min == 0) { + result = x; + goto repeatDone; + } + else + result = NULL; + break; + } + result = x; + } + curState->index = startcp - gData->cpbegin; + ++gData->stateStackTop; + if (gData->stateStackTop == gData->maxStateStack) + if (!reallocStateStack(gData)) + return NULL; + if (curState->u.quantifier.min == 0) + if (!pushBackTrackState(gData, REOP_REPEAT, + pc, x, startcp, + curState->parenSoFar, + parenSoFar + - curState->parenSoFar)) + return NULL; + if (*nextpc == REOP_ENDCHILD) + goto repeatAgain; + pc = nextpc; + op = (REOp)(*pc++); + parenSoFar = curState->parenSoFar; + } + continue; +repeatDone: + pc = pc + GET_OFFSET(pc); + break; + + + case REOP_MINIMALSTAR: + curState->u.quantifier.min = 0; + curState->u.quantifier.max = -1; + goto minimalquantcommon; + case REOP_MINIMALPLUS: + curState->u.quantifier.min = 1; + curState->u.quantifier.max = -1; + goto minimalquantcommon; + case REOP_MINIMALOPT: + curState->u.quantifier.min = 0; + curState->u.quantifier.max = 1; + goto minimalquantcommon; + case REOP_MINIMALQUANT: + curState->u.quantifier.min = GET_ARG(pc); + pc += ARG_LEN; + curState->u.quantifier.max = GET_ARG(pc); + pc += ARG_LEN; +minimalquantcommon: + curState->index = x->cp - gData->cpbegin; + curState->parenSoFar = parenSoFar; + ++gData->stateStackTop; + if (gData->stateStackTop == gData->maxStateStack) + if (!reallocStateStack(gData)) + return NULL; + if (curState->u.quantifier.min != 0) { + curState->continue_op = REOP_MINIMALREPEAT; + curState->continue_pc = pc; + /* step over */ + pc += ARG_LEN; + op = (REOp)(*pc++); + } + else { + if (!pushBackTrackState(gData, REOP_MINIMALREPEAT, + pc, x, x->cp, 0, 0)) + return NULL; + --gData->stateStackTop; + pc = pc + GET_OFFSET(pc); + op = (REOp)(*pc++); + } + continue; + + case REOP_MINIMALREPEAT: + --gData->stateStackTop; + --curState; + + if (result == NULL) { + /* + * Non-greedy failure - try to consume another child. + */ + if ((curState->u.quantifier.max == (uint16)(-1)) + || (curState->u.quantifier.max > 0)) { + curState->index = x->cp - gData->cpbegin; + curState->continue_op = REOP_MINIMALREPEAT; + curState->continue_pc = pc; + pc += ARG_LEN; + for (k = curState->parenSoFar; k < parenSoFar; k++) + x->parens[k].index = -1; + ++gData->stateStackTop; + if (gData->stateStackTop == gData->maxStateStack) + if (!reallocStateStack(gData)) + return NULL; + op = (REOp)(*pc++); + continue; + } + else { + /* Don't need to adjust pc since we're going to pop. */ + break; + } + } + else { + if ((curState->u.quantifier.min == 0) + && (x->cp == gData->cpbegin + curState->index)) { + /* Matched an empty string, that'll get us nowhere. */ + result = NULL; + break; + } + if (curState->u.quantifier.min != 0) + curState->u.quantifier.min--; + if (curState->u.quantifier.max != (uint16)(-1)) + curState->u.quantifier.max--; + if (curState->u.quantifier.min != 0) { + curState->continue_op = REOP_MINIMALREPEAT; + curState->continue_pc = pc; + pc += ARG_LEN; + for (k = curState->parenSoFar; k < parenSoFar; k++) + x->parens[k].index = -1; + curState->index = x->cp - gData->cpbegin; + ++gData->stateStackTop; + if (gData->stateStackTop == gData->maxStateStack) + if (!reallocStateStack(gData)) + return NULL; + op = (REOp)(*pc++); + continue; + } + else { + curState->index = x->cp - gData->cpbegin; + curState->parenSoFar = parenSoFar; + ++gData->stateStackTop; + if (gData->stateStackTop == gData->maxStateStack) + if (!reallocStateStack(gData)) + return NULL; + if (!pushBackTrackState(gData, REOP_MINIMALREPEAT, + pc, x, x->cp, + curState->parenSoFar, + parenSoFar + - curState->parenSoFar)) + return NULL; + --gData->stateStackTop; + pc = pc + GET_OFFSET(pc); + op = (REOp)(*pc++); + continue; + } + } + + default: + JS_ASSERT(JS_FALSE); + result = NULL; + } + } + /* + * If the match failed and there's a backtrack option, take it. + * Otherwise this is a complete and utter failure. + */ + if (result == NULL) { + if (gData->cursz > 0) { + backTrackData = gData->backTrackSP; + gData->cursz = backTrackData->sz; + gData->backTrackSP + = (REBackTrackData *)((char *)backTrackData + - backTrackData->sz); + x->cp = backTrackData->cp; + pc = backTrackData->backtrack_pc; + op = backTrackData->backtrack_op; + gData->stateStackTop = backTrackData->precedingStateTop; + JS_ASSERT(gData->stateStackTop); + + memcpy(gData->stateStack, backTrackData + 1, + sizeof(REProgState) * backTrackData->precedingStateTop); + curState = &gData->stateStack[gData->stateStackTop - 1]; + + if (backTrackData->parenCount) { + memcpy(&x->parens[backTrackData->parenIndex], + (char *)(backTrackData + 1) + sizeof(REProgState) * backTrackData->precedingStateTop, + sizeof(RECapture) * backTrackData->parenCount); + parenSoFar = backTrackData->parenIndex + backTrackData->parenCount; + } + else { + for (k = curState->parenSoFar; k < parenSoFar; k++) + x->parens[k].index = -1; + parenSoFar = curState->parenSoFar; + } + continue; + } + else + return NULL; + } + else + x = result; + + /* + * Continue with the expression. + */ + op = (REOp)*pc++; + } + return NULL; +} + +static REMatchState * +MatchRegExp(REGlobalData *gData, REMatchState *x) +{ + REMatchState *result; + const jschar *cp = x->cp; + const jschar *cp2; + uintN j; + + /* + * Have to include the position beyond the last character + * in order to detect end-of-input/line condition. + */ + for (cp2 = cp; cp2 <= gData->cpend; cp2++) { + gData->skipped = cp2 - cp; + x->cp = cp2; + for (j = 0; j < gData->regexp->parenCount; j++) + x->parens[j].index = -1; + result = executeREBytecode(gData, x); + if (!gData->ok || result) + return result; + gData->backTrackSP = gData->backTrackStack; + gData->cursz = 0; + gData->stateStackTop = 0; + cp2 = cp + gData->skipped; + } + return NULL; +} + + +static REMatchState * +initMatch(JSContext *cx, REGlobalData *gData, JSRegExp *re) +{ + REMatchState *result; + uintN i; + + gData->maxBackTrack = INITIAL_BACKTRACK; + JS_ARENA_ALLOCATE_CAST(gData->backTrackStack, REBackTrackData *, + &gData->pool, + INITIAL_BACKTRACK); + if (!gData->backTrackStack) + return NULL; + gData->backTrackSP = gData->backTrackStack; + gData->cursz = 0; + + + gData->maxStateStack = INITIAL_STATESTACK; + JS_ARENA_ALLOCATE_CAST(gData->stateStack, REProgState *, + &gData->pool, + sizeof(REProgState) * INITIAL_STATESTACK); + if (!gData->stateStack) + return NULL; + gData->stateStackTop = 0; + + gData->cx = cx; + gData->regexp = re; + gData->ok = JS_TRUE; + + JS_ARENA_ALLOCATE_CAST(result, REMatchState *, + &gData->pool, + sizeof(REMatchState) + + (re->parenCount - 1) * sizeof(RECapture)); + if (!result) + return NULL; + + for (i = 0; i < re->classCount; i++) + if (!re->classList[i].converted) + if (!processCharSet(gData, &re->classList[i])) + return NULL; + + return result; +} + +JSBool +js_ExecuteRegExp(JSContext *cx, JSRegExp *re, JSString *str, size_t *indexp, + JSBool test, jsval *rval) +{ + REGlobalData gData; + REMatchState *x, *result; + + const jschar *cp, *ep; + size_t i, length, start; + JSSubString *morepar; + JSBool ok; + JSRegExpStatics *res; + ptrdiff_t matchlen; + uintN num, morenum; + JSString *parstr, *matchstr; + JSObject *obj; + + RECapture *parsub; + + /* + * It's safe to load from cp because JSStrings have a zero at the end, + * and we never let cp get beyond cpend. + */ + start = *indexp; + length = JSSTRING_LENGTH(str); + if (start > length) + start = length; + cp = JSSTRING_CHARS(str); + gData.cpbegin = cp; + gData.cpend = cp + length; + cp += start; + gData.start = start; + gData.skipped = 0; + + JS_InitArenaPool(&gData.pool, "RegExpPool", 8096, 4); + x = initMatch(cx, &gData, re); + if (!x) + return JS_FALSE; + x->cp = cp; + + /* + * Call the recursive matcher to do the real work. Return null on mismatch + * whether testing or not. On match, return an extended Array object. + */ + result = MatchRegExp(&gData, x); + if (!(ok = gData.ok)) goto out; + if (!result) { + *rval = JSVAL_NULL; + goto out; + } + cp = result->cp; + i = PTRDIFF(cp, gData.cpbegin, jschar); + *indexp = i; + matchlen = i - (start + gData.skipped); + ep = cp; + cp -= matchlen; + + if (test) { + /* + * Testing for a match and updating cx->regExpStatics: don't allocate + * an array object, do return true. + */ + *rval = JSVAL_TRUE; + + /* Avoid warning. (gcc doesn't detect that obj is needed iff !test); */ + obj = NULL; + } else { + /* + * The array returned on match has element 0 bound to the matched + * string, elements 1 through state.parenCount bound to the paren + * matches, an index property telling the length of the left context, + * and an input property referring to the input string. + */ + obj = js_NewArrayObject(cx, 0, NULL); + if (!obj) { + ok = JS_FALSE; + goto out; + } + *rval = OBJECT_TO_JSVAL(obj); + +#define DEFVAL(val, id) { \ + ok = js_DefineProperty(cx, obj, id, val, \ + JS_PropertyStub, JS_PropertyStub, \ + JSPROP_ENUMERATE, NULL); \ + if (!ok) { \ + cx->newborn[GCX_OBJECT] = NULL; \ + cx->newborn[GCX_STRING] = NULL; \ + goto out; \ + } \ +} + + matchstr = js_NewStringCopyN(cx, cp, matchlen, 0); + if (!matchstr) { + cx->newborn[GCX_OBJECT] = NULL; + ok = JS_FALSE; + goto out; + } + DEFVAL(STRING_TO_JSVAL(matchstr), INT_TO_JSVAL(0)); + } + + res = &cx->regExpStatics; + res->input = str; + res->parenCount = re->parenCount; + if (re->parenCount == 0) + res->lastParen = js_EmptySubString; + else { + for (num = 0; num < re->parenCount; num++) { + parsub = &result->parens[num]; + if (num < 9) { + if (parsub->index == -1) { + res->parens[num].chars = NULL; + res->parens[num].length = 0; + } + else { + res->parens[num].chars = gData.cpbegin + parsub->index; + res->parens[num].length = parsub->length; + } + } else { + morenum = num - 9; + morepar = res->moreParens; + if (!morepar) { + res->moreLength = 10; + morepar = (JSSubString*) JS_malloc(cx, + 10 * sizeof(JSSubString)); + } else if (morenum >= res->moreLength) { + res->moreLength += 10; + morepar = (JSSubString*) JS_realloc(cx, morepar, + res->moreLength * sizeof(JSSubString)); + } + if (!morepar) { + cx->newborn[GCX_OBJECT] = NULL; + cx->newborn[GCX_STRING] = NULL; + ok = JS_FALSE; + goto out; + } + res->moreParens = morepar; + if (parsub->index == -1) { + morepar[morenum].chars = NULL; + morepar[morenum].length = 0; + } + else { + morepar[morenum].chars = gData.cpbegin + parsub->index; + morepar[morenum].length = parsub->length; + } + } + if (test) + continue; + if (parsub->index == -1) + ok = js_DefineProperty(cx, obj, INT_TO_JSVAL(num + 1), + JSVAL_VOID, NULL, NULL, + JSPROP_ENUMERATE, NULL); + else { + parstr = js_NewStringCopyN(cx, gData.cpbegin + parsub->index, + parsub->length, 0); + if (!parstr) { + cx->newborn[GCX_OBJECT] = NULL; + cx->newborn[GCX_STRING] = NULL; + ok = JS_FALSE; + goto out; + } + ok = js_DefineProperty(cx, obj, INT_TO_JSVAL(num + 1), + STRING_TO_JSVAL(parstr), NULL, NULL, + JSPROP_ENUMERATE, NULL); + } + if (!ok) { + cx->newborn[GCX_OBJECT] = NULL; + cx->newborn[GCX_STRING] = NULL; + goto out; + } + } + if (parsub->index == -1) { + res->lastParen.chars = NULL; + res->lastParen.length = 0; + } + else { + res->lastParen.chars = gData.cpbegin + parsub->index; + res->lastParen.length = parsub->length; + } + } + + if (!test) { + /* + * Define the index and input properties last for better for/in loop + * order (so they come after the elements). + */ + DEFVAL(INT_TO_JSVAL(start + gData.skipped), + (jsid)cx->runtime->atomState.indexAtom); + DEFVAL(STRING_TO_JSVAL(str), + (jsid)cx->runtime->atomState.inputAtom); + } + +#undef DEFVAL + + res->lastMatch.chars = cp; + res->lastMatch.length = matchlen; + if (cx->version == JSVERSION_1_2) { + /* + * JS1.2 emulated Perl4.0.1.8 (patch level 36) for global regexps used + * in scalar contexts, and unintentionally for the string.match "list" + * psuedo-context. On "hi there bye", the following would result: + * + * Language while(/ /g){print("$`");} s/ /$`/g + * perl4.036 "hi", "there" "hihitherehi therebye" + * perl5 "hi", "hi there" "hihitherehi therebye" + * js1.2 "hi", "there" "hihitheretherebye" + */ + res->leftContext.chars = JSSTRING_CHARS(str) + start; + res->leftContext.length = gData.skipped; + } else { + /* + * For JS1.3 and ECMAv2, emulate Perl5 exactly: + * + * js1.3 "hi", "hi there" "hihitherehi therebye" + */ + res->leftContext.chars = JSSTRING_CHARS(str); + res->leftContext.length = start + gData.skipped; + } + res->rightContext.chars = ep; + res->rightContext.length = gData.cpend - ep; + +out: + JS_FinishArenaPool(&gData.pool); + return ok; +} + +/************************************************************************/ + +enum regexp_tinyid { + REGEXP_SOURCE = -1, + REGEXP_GLOBAL = -2, + REGEXP_IGNORE_CASE = -3, + REGEXP_LAST_INDEX = -4, + REGEXP_MULTILINE = -5 +}; + +#define REGEXP_PROP_ATTRS (JSPROP_PERMANENT|JSPROP_SHARED) + +static JSPropertySpec regexp_props[] = { + {"source", REGEXP_SOURCE, REGEXP_PROP_ATTRS | JSPROP_READONLY,0,0}, + {"global", REGEXP_GLOBAL, REGEXP_PROP_ATTRS | JSPROP_READONLY,0,0}, + {"ignoreCase", REGEXP_IGNORE_CASE, REGEXP_PROP_ATTRS | JSPROP_READONLY,0,0}, + {"lastIndex", REGEXP_LAST_INDEX, REGEXP_PROP_ATTRS,0,0}, + {"multiline", REGEXP_MULTILINE, REGEXP_PROP_ATTRS | JSPROP_READONLY,0,0}, + {0,0,0,0,0} +}; + +static JSBool +regexp_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp) +{ + jsint slot; + JSRegExp *re; + + if (!JSVAL_IS_INT(id)) + return JS_TRUE; + slot = JSVAL_TO_INT(id); + if (slot == REGEXP_LAST_INDEX) + return JS_GetReservedSlot(cx, obj, 0, vp); + + JS_LOCK_OBJ(cx, obj); + re = (JSRegExp *) JS_GetInstancePrivate(cx, obj, &js_RegExpClass, NULL); + if (re) { + switch (slot) { + case REGEXP_SOURCE: + *vp = STRING_TO_JSVAL(re->source); + break; + case REGEXP_GLOBAL: + *vp = BOOLEAN_TO_JSVAL((re->flags & JSREG_GLOB) != 0); + break; + case REGEXP_IGNORE_CASE: + *vp = BOOLEAN_TO_JSVAL((re->flags & JSREG_FOLD) != 0); + break; + case REGEXP_MULTILINE: + *vp = BOOLEAN_TO_JSVAL((re->flags & JSREG_MULTILINE) != 0); + break; + } + } + JS_UNLOCK_OBJ(cx, obj); + return JS_TRUE; +} + +static JSBool +regexp_setProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp) +{ + JSBool ok; + jsint slot; + jsdouble lastIndex; + + ok = JS_TRUE; + if (!JSVAL_IS_INT(id)) + return ok; + slot = JSVAL_TO_INT(id); + if (slot == REGEXP_LAST_INDEX) { + if (!js_ValueToNumber(cx, *vp, &lastIndex)) + return JS_FALSE; + lastIndex = js_DoubleToInteger(lastIndex); + ok = js_NewNumberValue(cx, lastIndex, vp) && + JS_SetReservedSlot(cx, obj, 0, *vp); + } + return ok; +} + +/* + * RegExp class static properties and their Perl counterparts: + * + * RegExp.input $_ + * RegExp.multiline $* + * RegExp.lastMatch $& + * RegExp.lastParen $+ + * RegExp.leftContext $` + * RegExp.rightContext $' + */ +enum regexp_static_tinyid { + REGEXP_STATIC_INPUT = -1, + REGEXP_STATIC_MULTILINE = -2, + REGEXP_STATIC_LAST_MATCH = -3, + REGEXP_STATIC_LAST_PAREN = -4, + REGEXP_STATIC_LEFT_CONTEXT = -5, + REGEXP_STATIC_RIGHT_CONTEXT = -6 +}; + +JSBool +js_InitRegExpStatics(JSContext *cx, JSRegExpStatics *res) +{ + JS_ClearRegExpStatics(cx); + return js_AddRoot(cx, &res->input, "res->input"); +} + +void +js_FreeRegExpStatics(JSContext *cx, JSRegExpStatics *res) +{ + if (res->moreParens) { + JS_free(cx, res->moreParens); + res->moreParens = NULL; + } + js_RemoveRoot(cx->runtime, &res->input); +} + +static JSBool +regexp_static_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp) +{ + jsint slot; + JSRegExpStatics *res; + JSString *str; + JSSubString *sub; + + res = &cx->regExpStatics; + if (!JSVAL_IS_INT(id)) + return JS_TRUE; + slot = JSVAL_TO_INT(id); + switch (slot) { + case REGEXP_STATIC_INPUT: + *vp = res->input ? STRING_TO_JSVAL(res->input) + : JS_GetEmptyStringValue(cx); + return JS_TRUE; + case REGEXP_STATIC_MULTILINE: + *vp = BOOLEAN_TO_JSVAL(res->multiline); + return JS_TRUE; + case REGEXP_STATIC_LAST_MATCH: + sub = &res->lastMatch; + break; + case REGEXP_STATIC_LAST_PAREN: + sub = &res->lastParen; + break; + case REGEXP_STATIC_LEFT_CONTEXT: + sub = &res->leftContext; + break; + case REGEXP_STATIC_RIGHT_CONTEXT: + sub = &res->rightContext; + break; + default: + sub = REGEXP_PAREN_SUBSTRING(res, slot); + break; + } + str = js_NewStringCopyN(cx, sub->chars, sub->length, 0); + if (!str) + return JS_FALSE; + *vp = STRING_TO_JSVAL(str); + return JS_TRUE; +} + +static JSBool +regexp_static_setProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp) +{ + JSRegExpStatics *res; + + if (!JSVAL_IS_INT(id)) + return JS_TRUE; + res = &cx->regExpStatics; + /* XXX use if-else rather than switch to keep MSVC1.52 from crashing */ + if (JSVAL_TO_INT(id) == REGEXP_STATIC_INPUT) { + if (!JSVAL_IS_STRING(*vp) && + !JS_ConvertValue(cx, *vp, JSTYPE_STRING, vp)) { + return JS_FALSE; + } + res->input = JSVAL_TO_STRING(*vp); + } else if (JSVAL_TO_INT(id) == REGEXP_STATIC_MULTILINE) { + if (!JSVAL_IS_BOOLEAN(*vp) && + !JS_ConvertValue(cx, *vp, JSTYPE_BOOLEAN, vp)) { + return JS_FALSE; + } + res->multiline = JSVAL_TO_BOOLEAN(*vp); + } + return JS_TRUE; +} + +static JSPropertySpec regexp_static_props[] = { + {"input", + REGEXP_STATIC_INPUT, + JSPROP_ENUMERATE|JSPROP_SHARED, + regexp_static_getProperty, regexp_static_setProperty}, + {"multiline", + REGEXP_STATIC_MULTILINE, + JSPROP_ENUMERATE|JSPROP_SHARED, + regexp_static_getProperty, regexp_static_setProperty}, + {"lastMatch", + REGEXP_STATIC_LAST_MATCH, + JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_SHARED, + regexp_static_getProperty, regexp_static_getProperty}, + {"lastParen", + REGEXP_STATIC_LAST_PAREN, + JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_SHARED, + regexp_static_getProperty, regexp_static_getProperty}, + {"leftContext", + REGEXP_STATIC_LEFT_CONTEXT, + JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_SHARED, + regexp_static_getProperty, regexp_static_getProperty}, + {"rightContext", + REGEXP_STATIC_RIGHT_CONTEXT, + JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_SHARED, + regexp_static_getProperty, regexp_static_getProperty}, + + /* XXX should have block scope and local $1, etc. */ + {"$1", 0, JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_SHARED, + regexp_static_getProperty, regexp_static_getProperty}, + {"$2", 1, JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_SHARED, + regexp_static_getProperty, regexp_static_getProperty}, + {"$3", 2, JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_SHARED, + regexp_static_getProperty, regexp_static_getProperty}, + {"$4", 3, JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_SHARED, + regexp_static_getProperty, regexp_static_getProperty}, + {"$5", 4, JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_SHARED, + regexp_static_getProperty, regexp_static_getProperty}, + {"$6", 5, JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_SHARED, + regexp_static_getProperty, regexp_static_getProperty}, + {"$7", 6, JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_SHARED, + regexp_static_getProperty, regexp_static_getProperty}, + {"$8", 7, JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_SHARED, + regexp_static_getProperty, regexp_static_getProperty}, + {"$9", 8, JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_SHARED, + regexp_static_getProperty, regexp_static_getProperty}, + + {0,0,0,0,0} +}; + +static void +regexp_finalize(JSContext *cx, JSObject *obj) +{ + JSRegExp *re; + + re = (JSRegExp *) JS_GetPrivate(cx, obj); + if (!re) + return; + js_DestroyRegExp(cx, re); +} + +/* Forward static prototype. */ +static JSBool +regexp_exec(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval); + +static JSBool +regexp_call(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + return regexp_exec(cx, JSVAL_TO_OBJECT(argv[-2]), argc, argv, rval); +} + +#if JS_HAS_XDR + +#include "jsxdrapi.h" + +static JSBool +regexp_xdrObject(JSXDRState *xdr, JSObject **objp) +{ + JSRegExp *re; + JSString *source; + uint8 flags; + + if (xdr->mode == JSXDR_ENCODE) { + re = (JSRegExp *) JS_GetPrivate(xdr->cx, *objp); + if (!re) + return JS_FALSE; + source = re->source; + flags = (uint8) re->flags; + } + if (!JS_XDRString(xdr, &source) || + !JS_XDRUint8(xdr, &flags)) { + return JS_FALSE; + } + if (xdr->mode == JSXDR_DECODE) { + *objp = js_NewObject(xdr->cx, &js_RegExpClass, NULL, NULL); + if (!*objp) + return JS_FALSE; + re = js_NewRegExp(xdr->cx, NULL, source, flags, JS_FALSE); + if (!re) + return JS_FALSE; + if (!JS_SetPrivate(xdr->cx, *objp, re) || + !js_SetLastIndex(xdr->cx, *objp, 0)) { + js_DestroyRegExp(xdr->cx, re); + return JS_FALSE; + } + } + return JS_TRUE; +} + +#else /* !JS_HAS_XDR */ + +#define regexp_xdrObject NULL + +#endif /* !JS_HAS_XDR */ + +static uint32 +regexp_mark(JSContext *cx, JSObject *obj, void *arg) +{ + JSRegExp *re = (JSRegExp *) JS_GetPrivate(cx, obj); + if (re) + JS_MarkGCThing(cx, re->source, "source", arg); + return 0; +} + +JSClass js_RegExpClass = { + js_RegExp_str, + JSCLASS_HAS_PRIVATE | JSCLASS_HAS_RESERVED_SLOTS(1), + JS_PropertyStub, JS_PropertyStub, regexp_getProperty, regexp_setProperty, + JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, regexp_finalize, + NULL, NULL, regexp_call, NULL, + regexp_xdrObject, NULL, regexp_mark, 0 +}; + +static const jschar empty_regexp_ucstr[] = {'(', '?', ':', ')', 0}; + +static JSBool +regexp_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval) +{ + JSRegExp *re; + const jschar *source; + jschar *chars; + size_t length, nflags; + uintN flags; + JSString *str; + + if (!JS_InstanceOf(cx, obj, &js_RegExpClass, argv)) + return JS_FALSE; + JS_LOCK_OBJ(cx, obj); + re = (JSRegExp *) JS_GetPrivate(cx, obj); + if (!re) { + JS_UNLOCK_OBJ(cx, obj); + *rval = STRING_TO_JSVAL(cx->runtime->emptyString); + return JS_TRUE; + } + + source = JSSTRING_CHARS(re->source); + length = JSSTRING_LENGTH(re->source); + if (length == 0) { + source = empty_regexp_ucstr; + length = sizeof(empty_regexp_ucstr) / sizeof(jschar) - 1; + } + length += 2; + nflags = 0; + for (flags = re->flags; flags != 0; flags &= flags - 1) + nflags++; + chars = (jschar*) JS_malloc(cx, (length + nflags + 1) * sizeof(jschar)); + if (!chars) { + JS_UNLOCK_OBJ(cx, obj); + return JS_FALSE; + } + + chars[0] = '/'; + js_strncpy(&chars[1], source, length - 2); + chars[length-1] = '/'; + if (nflags) { + if (re->flags & JSREG_GLOB) + chars[length++] = 'g'; + if (re->flags & JSREG_FOLD) + chars[length++] = 'i'; + if (re->flags & JSREG_MULTILINE) + chars[length++] = 'm'; + } + JS_UNLOCK_OBJ(cx, obj); + chars[length] = 0; + + str = js_NewString(cx, chars, length, 0); + if (!str) { + JS_free(cx, chars); + return JS_FALSE; + } + *rval = STRING_TO_JSVAL(str); + return JS_TRUE; +} + +static JSBool +regexp_compile(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval) +{ + JSString *opt, *str; + JSRegExp *oldre, *re; + JSBool ok; + JSObject *obj2; + + if (!JS_InstanceOf(cx, obj, &js_RegExpClass, argv)) + return JS_FALSE; + opt = NULL; + if (argc == 0) { + str = cx->runtime->emptyString; + } else { + if (JSVAL_IS_OBJECT(argv[0])) { + /* + * If we get passed in a RegExp object we construct a new + * RegExp that is a duplicate of it by re-compiling the + * original source code. ECMA requires that it be an error + * here if the flags are specified. (We must use the flags + * from the original RegExp also). + */ + obj2 = JSVAL_TO_OBJECT(argv[0]); + if (obj2 && OBJ_GET_CLASS(cx, obj2) == &js_RegExpClass) { + if (argc >= 2 && !JSVAL_IS_VOID(argv[1])) { /* 'flags' passed */ + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, + JSMSG_NEWREGEXP_FLAGGED); + return JS_FALSE; + } + JS_LOCK_OBJ(cx, obj2); + re = (JSRegExp *) JS_GetPrivate(cx, obj2); + if (!re) { + JS_UNLOCK_OBJ(cx, obj2); + return JS_FALSE; + } + re = js_NewRegExp(cx, NULL, re->source, re->flags, JS_FALSE); + JS_UNLOCK_OBJ(cx, obj2); + goto madeit; + } + } + str = js_ValueToString(cx, argv[0]); + if (!str) + return JS_FALSE; + argv[0] = STRING_TO_JSVAL(str); + if (argc > 1) { + if (JSVAL_IS_VOID(argv[1])) { + opt = NULL; + } else { + opt = js_ValueToString(cx, argv[1]); + if (!opt) + return JS_FALSE; + argv[1] = STRING_TO_JSVAL(opt); + } + } + } + re = js_NewRegExpOpt(cx, NULL, str, opt, JS_FALSE); +madeit: + if (!re) + return JS_FALSE; + JS_LOCK_OBJ(cx, obj); + oldre = (JSRegExp *) JS_GetPrivate(cx, obj); + ok = JS_SetPrivate(cx, obj, re) && js_SetLastIndex(cx, obj, 0); + JS_UNLOCK_OBJ(cx, obj); + if (!ok) { + js_DestroyRegExp(cx, re); + } else { + if (oldre) + js_DestroyRegExp(cx, oldre); + *rval = OBJECT_TO_JSVAL(obj); + } + return ok; +} + +static JSBool +regexp_exec_sub(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + JSBool test, jsval *rval) +{ + JSBool ok; + JSRegExp *re; + jsdouble lastIndex; + JSString *str; + size_t i; + + ok = JS_InstanceOf(cx, obj, &js_RegExpClass, argv); + if (!ok) + return JS_FALSE; + JS_LOCK_OBJ(cx, obj); + re = (JSRegExp *) JS_GetPrivate(cx, obj); + if (!re) { + JS_UNLOCK_OBJ(cx, obj); + return JS_TRUE; + } + + /* NB: we must reach out: after this paragraph, in order to drop re. */ + HOLD_REGEXP(cx, re); + if (re->flags & JSREG_GLOB) { + ok = js_GetLastIndex(cx, obj, &lastIndex); + } else { + lastIndex = 0; + } + JS_UNLOCK_OBJ(cx, obj); + if (!ok) + goto out; + + /* Now that obj is unlocked, it's safe to (potentially) grab the GC lock. */ + if (argc == 0) { + str = cx->regExpStatics.input; + if (!str) { + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, + JSMSG_NO_INPUT, + JS_GetStringBytes(re->source), + (re->flags & JSREG_GLOB) ? "g" : "", + (re->flags & JSREG_FOLD) ? "i" : "", + (re->flags & JSREG_MULTILINE) ? "m" : ""); + ok = JS_FALSE; + goto out; + } + } else { + str = js_ValueToString(cx, argv[0]); + if (!str) + goto out; + argv[0] = STRING_TO_JSVAL(str); + } + + if (lastIndex < 0 || JSSTRING_LENGTH(str) < lastIndex) { + ok = js_SetLastIndex(cx, obj, 0); + *rval = JSVAL_NULL; + } else { + i = (size_t) lastIndex; + ok = js_ExecuteRegExp(cx, re, str, &i, test, rval); + if (ok && (re->flags & JSREG_GLOB)) + ok = js_SetLastIndex(cx, obj, (*rval == JSVAL_NULL) ? 0 : i); + } + +out: + DROP_REGEXP(cx, re); + return ok; +} + +static JSBool +regexp_exec(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + return regexp_exec_sub(cx, obj, argc, argv, JS_FALSE, rval); +} + +static JSBool +regexp_test(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + if (!regexp_exec_sub(cx, obj, argc, argv, JS_TRUE, rval)) + return JS_FALSE; + if (*rval != JSVAL_TRUE) + *rval = JSVAL_FALSE; + return JS_TRUE; +} + +static JSFunctionSpec regexp_methods[] = { +#if JS_HAS_TOSOURCE + {js_toSource_str, regexp_toString, 0,0,0}, +#endif + {js_toString_str, regexp_toString, 0,0,0}, + {"compile", regexp_compile, 1,0,0}, + {"exec", regexp_exec, 0,0,0}, + {"test", regexp_test, 0,0,0}, + {0,0,0,0,0} +}; + +static JSBool +RegExp(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + if (!(cx->fp->flags & JSFRAME_CONSTRUCTING)) { + /* + * If first arg is regexp and no flags are given, just return the arg. + * (regexp_compile detects the regexp + flags case and throws a + * TypeError.) See 10.15.3.1. + */ + if ((argc < 2 || JSVAL_IS_VOID(argv[1])) && JSVAL_IS_OBJECT(argv[0]) && + OBJ_GET_CLASS(cx, JSVAL_TO_OBJECT(argv[0])) == &js_RegExpClass) { + *rval = argv[0]; + return JS_TRUE; + } + + /* Otherwise, replace obj with a new RegExp object. */ + obj = js_NewObject(cx, &js_RegExpClass, NULL, NULL); + if (!obj) + return JS_FALSE; + } + return regexp_compile(cx, obj, argc, argv, rval); +} + +JSObject * +js_InitRegExpClass(JSContext *cx, JSObject *obj) +{ + JSObject *proto, *ctor; + jsval rval; + + proto = JS_InitClass(cx, obj, NULL, &js_RegExpClass, RegExp, 1, + regexp_props, regexp_methods, + regexp_static_props, NULL); + + if (!proto || !(ctor = JS_GetConstructor(cx, proto))) + return NULL; + if (!JS_AliasProperty(cx, ctor, "input", "$_") || + !JS_AliasProperty(cx, ctor, "multiline", "$*") || + !JS_AliasProperty(cx, ctor, "lastMatch", "$&") || + !JS_AliasProperty(cx, ctor, "lastParen", "$+") || + !JS_AliasProperty(cx, ctor, "leftContext", "$`") || + !JS_AliasProperty(cx, ctor, "rightContext", "$'")) { + goto bad; + } + + /* Give RegExp.prototype private data so it matches the empty string. */ + if (!regexp_compile(cx, proto, 0, NULL, &rval)) + goto bad; + return proto; + +bad: + JS_DeleteProperty(cx, obj, js_RegExpClass.name); + return NULL; +} + +JSObject * +js_NewRegExpObject(JSContext *cx, JSTokenStream *ts, + jschar *chars, size_t length, uintN flags) +{ + JSString *str; + JSObject *obj; + JSRegExp *re; + + str = js_NewStringCopyN(cx, chars, length, 0); + if (!str) + return NULL; + re = js_NewRegExp(cx, ts, str, flags, JS_FALSE); + if (!re) + return NULL; + obj = js_NewObject(cx, &js_RegExpClass, NULL, NULL); + if (!obj || !JS_SetPrivate(cx, obj, re) || !js_SetLastIndex(cx, obj, 0)) { + js_DestroyRegExp(cx, re); + return NULL; + } + return obj; +} + +JSObject * +js_CloneRegExpObject(JSContext *cx, JSObject *obj, JSObject *parent) +{ + JSObject *clone; + JSRegExp *re; + + JS_ASSERT(OBJ_GET_CLASS(cx, obj) == &js_RegExpClass); + clone = js_NewObject(cx, &js_RegExpClass, NULL, parent); + if (!clone) + return NULL; + re = JS_GetPrivate(cx, obj); + if (!JS_SetPrivate(cx, clone, re) || !js_SetLastIndex(cx, clone, 0)) { + cx->newborn[GCX_OBJECT] = NULL; + return NULL; + } + HOLD_REGEXP(cx, re); + return clone; +} + +JSBool +js_GetLastIndex(JSContext *cx, JSObject *obj, jsdouble *lastIndex) +{ + jsval v; + + return JS_GetReservedSlot(cx, obj, 0, &v) && + js_ValueToNumber(cx, v, lastIndex); +} + +JSBool +js_SetLastIndex(JSContext *cx, JSObject *obj, jsdouble lastIndex) +{ + jsval v; + + return js_NewNumberValue(cx, lastIndex, &v) && + JS_SetReservedSlot(cx, obj, 0, v); +} + +#endif /* JS_HAS_REGEXPS */ diff --git a/src/dom/js/jsregexp.h b/src/dom/js/jsregexp.h new file mode 100644 index 000000000..0485c2860 --- /dev/null +++ b/src/dom/js/jsregexp.h @@ -0,0 +1,168 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef jsregexp_h___ +#define jsregexp_h___ +/* + * JS regular expression interface. + */ +#include +#include "jspubtd.h" +#include "jsstr.h" + +#ifdef JS_THREADSAFE +#include "jsdhash.h" +#endif + +struct JSRegExpStatics { + JSString *input; /* input string to match (perl $_, GC root) */ + JSBool multiline; /* whether input contains newlines (perl $*) */ + uintN parenCount; /* number of valid elements in parens[] */ + uintN moreLength; /* number of allocated elements in moreParens */ + JSSubString parens[9]; /* last set of parens matched (perl $1, $2) */ + JSSubString *moreParens; /* null or realloc'd vector for $10, etc. */ + JSSubString lastMatch; /* last string matched (perl $&) */ + JSSubString lastParen; /* last paren matched (perl $+) */ + JSSubString leftContext; /* input to left of last match (perl $`) */ + JSSubString rightContext; /* input to right of last match (perl $') */ +}; + +/* + * This struct holds a bitmap representation of a class from a regexp. + * There's a list of these referenced by the classList field in the JSRegExp + * struct below. The initial state has startIndex set to the offset in the + * original regexp source of the beginning of the class contents. The first + * use of the class converts the source representation into a bitmap. + * + */ +typedef struct RECharSet { + JSBool converted; + JSBool sense; + uint16 length; + union { + uint8 *bits; + struct { + uint16 startIndex; + uint16 length; + } src; + } u; +} RECharSet; + +/* + * This macro is safe because moreParens is guaranteed to be allocated and big + * enough to hold parenCount, or else be null when parenCount is 0. + */ +#define REGEXP_PAREN_SUBSTRING(res, num) \ + (((jsuint)(num) < (jsuint)(res)->parenCount) \ + ? ((jsuint)(num) < 9) \ + ? &(res)->parens[num] \ + : &(res)->moreParens[(num) - 9] \ + : &js_EmptySubString) + +typedef struct RENode RENode; + +struct JSRegExp { + jsrefcount nrefs; /* reference count */ + uint32 parenCount:24, /* number of parenthesized submatches */ + flags:8; /* flags, see jsapi.h's JSREG_* defines */ + uint32 classCount; /* count [...] bitmaps */ + RECharSet *classList; /* list of [...] bitmaps */ + JSString *source; /* locked source string, sans // */ + jsbytecode program[1]; /* regular expression bytecode */ +}; + +extern JSRegExp * +js_NewRegExp(JSContext *cx, JSTokenStream *ts, + JSString *str, uintN flags, JSBool flat); + +extern JSRegExp * +js_NewRegExpOpt(JSContext *cx, JSTokenStream *ts, + JSString *str, JSString *opt, JSBool flat); + +extern void +js_DestroyRegExp(JSContext *cx, JSRegExp *re); + +/* + * Execute re on input str at *indexp, returning null in *rval on mismatch. + * On match, return true if test is true, otherwise return an array object. + * Update *indexp and cx->regExpStatics always on match. + */ +extern JSBool +js_ExecuteRegExp(JSContext *cx, JSRegExp *re, JSString *str, size_t *indexp, + JSBool test, jsval *rval); + +/* + * These two add and remove GC roots, respectively, so their calls must be + * well-ordered. + */ +extern JSBool +js_InitRegExpStatics(JSContext *cx, JSRegExpStatics *res); + +extern void +js_FreeRegExpStatics(JSContext *cx, JSRegExpStatics *res); + +#define JSVAL_IS_REGEXP(cx, v) \ + (JSVAL_IS_OBJECT(v) && JSVAL_TO_OBJECT(v) && \ + OBJ_GET_CLASS(cx, JSVAL_TO_OBJECT(v)) == &js_RegExpClass) + +extern JSClass js_RegExpClass; + +extern JSObject * +js_InitRegExpClass(JSContext *cx, JSObject *obj); + +/* + * Create a new RegExp object. + */ +extern JSObject * +js_NewRegExpObject(JSContext *cx, JSTokenStream *ts, + jschar *chars, size_t length, uintN flags); + +extern JSBool +js_XDRRegExp(JSXDRState *xdr, JSObject **objp); + +extern JSObject * +js_CloneRegExpObject(JSContext *cx, JSObject *obj, JSObject *parent); + +extern JSBool +js_GetLastIndex(JSContext *cx, JSObject *obj, jsdouble *lastIndex); + +extern JSBool +js_SetLastIndex(JSContext *cx, JSObject *obj, jsdouble lastIndex); + +#endif /* jsregexp_h___ */ diff --git a/src/dom/js/jsscan.c b/src/dom/js/jsscan.c new file mode 100644 index 000000000..e0bc5cd92 --- /dev/null +++ b/src/dom/js/jsscan.c @@ -0,0 +1,1315 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* + * JS lexical scanner. + */ +#include "jsstddef.h" +#include /* first to avoid trouble on some systems */ +#include +#include +#include +#ifdef HAVE_MEMORY_H +#include +#endif +#include +#include +#include +#include "jstypes.h" +#include "jsarena.h" /* Added by JSIFY */ +#include "jsutil.h" /* Added by JSIFY */ +#include "jsdtoa.h" +#include "jsprf.h" +#include "jsapi.h" +#include "jsatom.h" +#include "jscntxt.h" +#include "jsconfig.h" +#include "jsemit.h" +#include "jsexn.h" +#include "jsnum.h" +#include "jsopcode.h" +#include "jsregexp.h" +#include "jsscan.h" + +#define RESERVE_JAVA_KEYWORDS +#define RESERVE_ECMA_KEYWORDS + +static struct keyword { + const char *name; + JSTokenType tokentype; /* JSTokenType */ + JSOp op; /* JSOp */ + JSVersion version; /* JSVersion */ +} keywords[] = { + {"break", TOK_BREAK, JSOP_NOP, JSVERSION_DEFAULT}, + {"case", TOK_CASE, JSOP_NOP, JSVERSION_DEFAULT}, + {"continue", TOK_CONTINUE, JSOP_NOP, JSVERSION_DEFAULT}, + {"default", TOK_DEFAULT, JSOP_NOP, JSVERSION_DEFAULT}, + {js_delete_str, TOK_DELETE, JSOP_NOP, JSVERSION_DEFAULT}, + {"do", TOK_DO, JSOP_NOP, JSVERSION_DEFAULT}, + {"else", TOK_ELSE, JSOP_NOP, JSVERSION_DEFAULT}, + {"export", TOK_EXPORT, JSOP_NOP, JSVERSION_1_2}, + {js_false_str, TOK_PRIMARY, JSOP_FALSE, JSVERSION_DEFAULT}, + {"for", TOK_FOR, JSOP_NOP, JSVERSION_DEFAULT}, + {js_function_str, TOK_FUNCTION, JSOP_NOP, JSVERSION_DEFAULT}, + {"if", TOK_IF, JSOP_NOP, JSVERSION_DEFAULT}, + {js_in_str, TOK_IN, JSOP_IN, JSVERSION_DEFAULT}, + {js_new_str, TOK_NEW, JSOP_NEW, JSVERSION_DEFAULT}, + {js_null_str, TOK_PRIMARY, JSOP_NULL, JSVERSION_DEFAULT}, + {"return", TOK_RETURN, JSOP_NOP, JSVERSION_DEFAULT}, + {"switch", TOK_SWITCH, JSOP_NOP, JSVERSION_DEFAULT}, + {js_this_str, TOK_PRIMARY, JSOP_THIS, JSVERSION_DEFAULT}, + {js_true_str, TOK_PRIMARY, JSOP_TRUE, JSVERSION_DEFAULT}, + {js_typeof_str, TOK_UNARYOP, JSOP_TYPEOF,JSVERSION_DEFAULT}, + {"var", TOK_VAR, JSOP_DEFVAR,JSVERSION_DEFAULT}, + {js_void_str, TOK_UNARYOP, JSOP_VOID, JSVERSION_DEFAULT}, + {"while", TOK_WHILE, JSOP_NOP, JSVERSION_DEFAULT}, + {"with", TOK_WITH, JSOP_NOP, JSVERSION_DEFAULT}, + +#if JS_HAS_CONST + {js_const_str, TOK_VAR, JSOP_DEFCONST,JSVERSION_DEFAULT}, +#else + {js_const_str, TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT}, +#endif + +#if JS_HAS_EXCEPTIONS + {"try", TOK_TRY, JSOP_NOP, JSVERSION_DEFAULT}, + {"catch", TOK_CATCH, JSOP_NOP, JSVERSION_DEFAULT}, + {"finally", TOK_FINALLY, JSOP_NOP, JSVERSION_DEFAULT}, + {"throw", TOK_THROW, JSOP_NOP, JSVERSION_DEFAULT}, +#else + {"try", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT}, + {"catch", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT}, + {"finally", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT}, + {"throw", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT}, +#endif + +#if JS_HAS_INSTANCEOF + {js_instanceof_str, TOK_INSTANCEOF, JSOP_INSTANCEOF,JSVERSION_1_4}, +#else + {js_instanceof_str, TOK_RESERVED, JSOP_NOP, JSVERSION_1_4}, +#endif + +#ifdef RESERVE_JAVA_KEYWORDS + {"abstract", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT}, + {"boolean", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT}, + {"byte", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT}, + {"char", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT}, + {"class", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT}, + {"double", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT}, + {"extends", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT}, + {"final", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT}, + {"float", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT}, + {"goto", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT}, + {"implements", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT}, + {"import", TOK_IMPORT, JSOP_NOP, JSVERSION_DEFAULT}, + {"int", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT}, + {"interface", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT}, + {"long", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT}, + {"native", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT}, + {"package", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT}, + {"private", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT}, + {"protected", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT}, + {"public", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT}, + {"short", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT}, + {"static", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT}, + {"super", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT}, + {"synchronized", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT}, + {"throws", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT}, + {"transient", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT}, + {"volatile", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT}, +#endif + +#ifdef RESERVE_ECMA_KEYWORDS + {"enum", TOK_RESERVED, JSOP_NOP, JSVERSION_1_3}, +#endif + +#if JS_HAS_DEBUGGER_KEYWORD + {"debugger", TOK_DEBUGGER, JSOP_NOP, JSVERSION_1_3}, +#elif defined(RESERVE_ECMA_KEYWORDS) + {"debugger", TOK_RESERVED, JSOP_NOP, JSVERSION_1_3}, +#endif + {0, TOK_EOF, JSOP_NOP, JSVERSION_DEFAULT} +}; + +JSBool +js_InitScanner(JSContext *cx) +{ + struct keyword *kw; + JSAtom *atom; + + for (kw = keywords; kw->name; kw++) { + atom = js_Atomize(cx, kw->name, strlen(kw->name), ATOM_PINNED); + if (!atom) + return JS_FALSE; + ATOM_SET_KEYWORD(atom, kw); + } + return JS_TRUE; +} + +JS_FRIEND_API(void) +js_MapKeywords(void (*mapfun)(const char *)) +{ + struct keyword *kw; + + for (kw = keywords; kw->name; kw++) + mapfun(kw->name); +} + +JSTokenStream * +js_NewTokenStream(JSContext *cx, const jschar *base, size_t length, + const char *filename, uintN lineno, + JSPrincipals *principals) +{ + JSTokenStream *ts; + + ts = js_NewBufferTokenStream(cx, base, length); + if (!ts) + return NULL; + ts->filename = filename; + ts->lineno = lineno; + if (principals) + JSPRINCIPALS_HOLD(cx, principals); + ts->principals = principals; + return ts; +} + +JS_FRIEND_API(JSTokenStream *) +js_NewBufferTokenStream(JSContext *cx, const jschar *base, size_t length) +{ + size_t nb; + JSTokenStream *ts; + + nb = sizeof(JSTokenStream) + JS_LINE_LIMIT * sizeof(jschar); + JS_ARENA_ALLOCATE_CAST(ts, JSTokenStream *, &cx->tempPool, nb); + if (!ts) { + JS_ReportOutOfMemory(cx); + return NULL; + } + memset(ts, 0, nb); + ts->lineno = 1; + ts->linebuf.base = ts->linebuf.limit = ts->linebuf.ptr = (jschar *)(ts + 1); + ts->userbuf.base = (jschar *)base; + ts->userbuf.limit = (jschar *)base + length; + ts->userbuf.ptr = (jschar *)base; + ts->listener = cx->runtime->sourceHandler; + ts->listenerData = cx->runtime->sourceHandlerData; + return ts; +} + +JS_FRIEND_API(JSTokenStream *) +js_NewFileTokenStream(JSContext *cx, const char *filename, FILE *defaultfp) +{ + jschar *base; + JSTokenStream *ts; + FILE *file; + + JS_ARENA_ALLOCATE_CAST(base, jschar *, &cx->tempPool, + JS_LINE_LIMIT * sizeof(jschar)); + if (!base) + return NULL; + ts = js_NewBufferTokenStream(cx, base, JS_LINE_LIMIT); + if (!ts) + return NULL; + if (!filename || strcmp(filename, "-") == 0) { + file = defaultfp; + } else { + file = fopen(filename, "r"); + if (!file) { + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_OPEN, + filename, "No such file or directory"); + return NULL; + } + } + ts->userbuf.ptr = ts->userbuf.limit; + ts->file = file; + ts->filename = filename; + return ts; +} + +JS_FRIEND_API(JSBool) +js_CloseTokenStream(JSContext *cx, JSTokenStream *ts) +{ + if (ts->principals) + JSPRINCIPALS_DROP(cx, ts->principals); + return !ts->file || fclose(ts->file) == 0; +} + +static int +my_fgets(char *buf, int size, FILE *file) +{ + int n, i, c; + JSBool crflag; + + n = size - 1; + if (n < 0) + return -1; + + crflag = JS_FALSE; + for (i = 0; i < n && (c = getc(file)) != EOF; i++) { + buf[i] = c; + if (c == '\n') { /* any \n ends a line */ + i++; /* keep the \n; we know there is room for \0 */ + break; + } + if (crflag) { /* \r not followed by \n ends line at the \r */ + ungetc(c, file); + break; /* and overwrite c in buf with \0 */ + } + crflag = (c == '\r'); + } + + buf[i] = '\0'; + return i; +} + +static int32 +GetChar(JSTokenStream *ts) +{ + int32 c; + ptrdiff_t i, j, len, olen; + JSBool crflag; + char cbuf[JS_LINE_LIMIT]; + jschar *ubuf, *nl; + + if (ts->ungetpos != 0) { + c = ts->ungetbuf[--ts->ungetpos]; + } else { + do { + if (ts->linebuf.ptr == ts->linebuf.limit) { + len = PTRDIFF(ts->userbuf.limit, ts->userbuf.ptr, jschar); + if (len <= 0) { + if (!ts->file) { + ts->flags |= TSF_EOF; + return EOF; + } + + /* Fill ts->userbuf so that \r and \r\n convert to \n. */ + crflag = (ts->flags & TSF_CRFLAG) != 0; + len = my_fgets(cbuf, JS_LINE_LIMIT - crflag, ts->file); + if (len <= 0) { + ts->flags |= TSF_EOF; + return EOF; + } + olen = len; + ubuf = ts->userbuf.base; + i = 0; + if (crflag) { + ts->flags &= ~TSF_CRFLAG; + if (cbuf[0] != '\n') { + ubuf[i++] = '\n'; + len++; + ts->linepos--; + } + } + for (j = 0; i < len; i++, j++) + ubuf[i] = (jschar) (unsigned char) cbuf[j]; + ts->userbuf.limit = ubuf + len; + ts->userbuf.ptr = ubuf; + } + if (ts->listener) { + ts->listener(ts->filename, ts->lineno, ts->userbuf.ptr, len, + &ts->listenerTSData, ts->listenerData); + } + + /* + * Any one of \n, \r, or \r\n ends a line (longest match wins). + * Also allow the Unicode line and paragraph separators. + */ + for (nl = ts->userbuf.ptr; nl < ts->userbuf.limit; nl++) { + /* + * Try to prevent value-testing on most characters by + * filtering out characters that aren't 000x or 202x. + */ + if ((*nl & 0xDFD0) == 0) { + if (*nl == '\n') + break; + if (*nl == '\r') { + if (nl + 1 < ts->userbuf.limit && nl[1] == '\n') + nl++; + break; + } + if (*nl == LINE_SEPARATOR || *nl == PARA_SEPARATOR) + break; + } + } + + /* + * If there was a line terminator, copy thru it into linebuf. + * Else copy JS_LINE_LIMIT-1 bytes into linebuf. + */ + if (nl < ts->userbuf.limit) + len = PTRDIFF(nl, ts->userbuf.ptr, jschar) + 1; + if (len >= JS_LINE_LIMIT) + len = JS_LINE_LIMIT - 1; + js_strncpy(ts->linebuf.base, ts->userbuf.ptr, len); + ts->userbuf.ptr += len; + olen = len; + + /* + * Make sure linebuf contains \n for EOL (don't do this in + * userbuf because the user's string might be readonly). + */ + if (nl < ts->userbuf.limit) { + if (*nl == '\r') { + if (ts->linebuf.base[len-1] == '\r') { + /* + * Does the line segment end in \r? We must check + * for a \n at the front of the next segment before + * storing a \n into linebuf. This case matters + * only when we're reading from a file. + */ + if (nl + 1 == ts->userbuf.limit && ts->file) { + len--; + ts->flags |= TSF_CRFLAG; /* clear NLFLAG? */ + if (len == 0) { + /* + * This can happen when a segment ends in + * \r\r. Start over. ptr == limit in this + * case, so we'll fall into buffer-filling + * code. + */ + return GetChar(ts); + } + } else { + ts->linebuf.base[len-1] = '\n'; + } + } + } else if (*nl == '\n') { + if (nl > ts->userbuf.base && + nl[-1] == '\r' && + ts->linebuf.base[len-2] == '\r') { + len--; + JS_ASSERT(ts->linebuf.base[len] == '\n'); + ts->linebuf.base[len-1] = '\n'; + } + } else if (*nl == LINE_SEPARATOR || *nl == PARA_SEPARATOR) { + ts->linebuf.base[len-1] = '\n'; + } + } + + /* Reset linebuf based on adjusted segment length. */ + ts->linebuf.limit = ts->linebuf.base + len; + ts->linebuf.ptr = ts->linebuf.base; + + /* Update position of linebuf within physical userbuf line. */ + if (!(ts->flags & TSF_NLFLAG)) + ts->linepos += ts->linelen; + else + ts->linepos = 0; + if (ts->linebuf.limit[-1] == '\n') + ts->flags |= TSF_NLFLAG; + else + ts->flags &= ~TSF_NLFLAG; + + /* Update linelen from original segment length. */ + ts->linelen = olen; + } + c = *ts->linebuf.ptr++; + } while (JS_ISFORMAT(c)); + } + if (c == '\n') + ts->lineno++; + return c; +} + +static void +UngetChar(JSTokenStream *ts, int32 c) +{ + if (c == EOF) + return; + JS_ASSERT(ts->ungetpos < sizeof ts->ungetbuf / sizeof ts->ungetbuf[0]); + if (c == '\n') + ts->lineno--; + ts->ungetbuf[ts->ungetpos++] = (jschar)c; +} + +static int32 +PeekChar(JSTokenStream *ts) +{ + int32 c; + + c = GetChar(ts); + UngetChar(ts, c); + return c; +} + +static JSBool +PeekChars(JSTokenStream *ts, intN n, jschar *cp) +{ + intN i, j; + int32 c; + + for (i = 0; i < n; i++) { + c = GetChar(ts); + if (c == EOF) + break; + cp[i] = (jschar)c; + } + for (j = i - 1; j >= 0; j--) + UngetChar(ts, cp[j]); + return i == n; +} + +static void +SkipChars(JSTokenStream *ts, intN n) +{ + while (--n >= 0) + GetChar(ts); +} + +static JSBool +MatchChar(JSTokenStream *ts, int32 expect) +{ + int32 c; + + c = GetChar(ts); + if (c == expect) + return JS_TRUE; + UngetChar(ts, c); + return JS_FALSE; +} + +JSBool +js_ReportCompileErrorNumber(JSContext *cx, JSTokenStream *ts, + JSCodeGenerator *cg, uintN flags, + const uintN errorNumber, ...) +{ + va_list ap; + JSErrorReporter onError; + JSErrorReport report; + jschar *tokenptr; + JSString *linestr = NULL; + char *message; + JSBool warning; + + if ((flags & JSREPORT_STRICT) && !JS_HAS_STRICT_OPTION(cx)) + return JS_TRUE; + + memset(&report, 0, sizeof (struct JSErrorReport)); + report.flags = flags; + report.errorNumber = errorNumber; + message = NULL; + + va_start(ap, errorNumber); + if (!js_ExpandErrorArguments(cx, js_GetErrorMessage, NULL, + errorNumber, &message, &report, &warning, + JS_TRUE, ap)) { + return JS_FALSE; + } + va_end(ap); + + js_AddRoot(cx, &linestr, "error line buffer"); + + JS_ASSERT(!ts || ts->linebuf.limit < ts->linebuf.base + JS_LINE_LIMIT); + onError = cx->errorReporter; + if (onError) { + /* + * We are typically called with non-null ts and null cg from jsparse.c. + * We can be called with null ts from the regexp compilation functions. + * The code generator (jsemit.c) may pass null ts and non-null cg. + */ + if (ts) { + report.filename = ts->filename; + report.lineno = ts->lineno; + linestr = js_NewStringCopyN(cx, ts->linebuf.base, + ts->linebuf.limit - ts->linebuf.base, + 0); + report.linebuf = linestr + ? JS_GetStringBytes(linestr) + : NULL; + tokenptr = + ts->tokens[(ts->cursor + ts->lookahead) & NTOKENS_MASK].ptr; + report.tokenptr = linestr + ? report.linebuf + (tokenptr - ts->linebuf.base) + : NULL; + report.uclinebuf = linestr + ? JS_GetStringChars(linestr) + : NULL; + report.uctokenptr = linestr + ? report.uclinebuf + (tokenptr - ts->linebuf.base) + : NULL; + } else if (cg) { + report.filename = cg->filename; + report.lineno = CG_CURRENT_LINE(cg); + } + +#if JS_HAS_ERROR_EXCEPTIONS + /* + * If there's a runtime exception type associated with this error + * number, set that as the pending exception. For errors occuring at + * compile time, this is very likely to be a JSEXN_SYNTAXERR. + * + * If an exception is thrown but not caught, the JSREPORT_EXCEPTION + * flag will be set in report.flags. Proper behavior for an error + * reporter is to ignore a report with this flag for all but top-level + * compilation errors. The exception will remain pending, and so long + * as the non-top-level "load", "eval", or "compile" native function + * returns false, the top-level reporter will eventually receive the + * uncaught exception report. + * + * XXX it'd probably be best if there was only one call to this + * function, but there seem to be two error reporter call points. + */ + + /* + * Only try to raise an exception if there isn't one already set - + * otherwise the exception will describe only the last compile error, + * which is likely spurious. + */ + if (!(ts && (ts->flags & TSF_ERROR))) + if (js_ErrorToException(cx, message, &report)) + onError = NULL; + + /* + * Suppress any compiletime errors that don't occur at the top level. + * This may still fail, as interplevel may be zero in contexts where we + * don't really want to call the error reporter, as when js is called + * by other code which could catch the error. + */ + if (cx->interpLevel != 0) + onError = NULL; +#endif + if (cx->runtime->debugErrorHook && onError) { + JSDebugErrorHook hook = cx->runtime->debugErrorHook; + /* test local in case debugErrorHook changed on another thread */ + if (hook && !hook(cx, message, &report, + cx->runtime->debugErrorHookData)) { + onError = NULL; + } + } + if (onError) + (*onError)(cx, message, &report); + } + if (message) + JS_free(cx, message); + if (report.messageArgs) { + int i = 0; + while (report.messageArgs[i]) + JS_free(cx, (void *)report.messageArgs[i++]); + JS_free(cx, (void *)report.messageArgs); + } + if (report.ucmessage) + JS_free(cx, (void *)report.ucmessage); + + js_RemoveRoot(cx->runtime, &linestr); + + if (ts && !JSREPORT_IS_WARNING(flags)) { + /* Set the error flag to suppress spurious reports. */ + ts->flags |= TSF_ERROR; + } + return warning; +} + +JSTokenType +js_PeekToken(JSContext *cx, JSTokenStream *ts) +{ + JSTokenType tt; + + if (ts->lookahead != 0) { + tt = ts->tokens[(ts->cursor + ts->lookahead) & NTOKENS_MASK].type; + } else { + tt = js_GetToken(cx, ts); + js_UngetToken(ts); + } + return tt; +} + +JSTokenType +js_PeekTokenSameLine(JSContext *cx, JSTokenStream *ts) +{ + JSTokenType tt; + + JS_ASSERT(ts->lookahead == 0 || + ON_CURRENT_LINE(ts, CURRENT_TOKEN(ts).pos)); + ts->flags |= TSF_NEWLINES; + tt = js_PeekToken(cx, ts); + ts->flags &= ~TSF_NEWLINES; + return tt; +} + +#define TBMIN 64 + +static JSBool +GrowTokenBuf(JSContext *cx, JSTokenBuf *tb) +{ + jschar *base; + ptrdiff_t offset, length; + size_t tbsize; + JSArenaPool *pool; + + base = tb->base; + offset = PTRDIFF(tb->ptr, base, jschar); + pool = &cx->tempPool; + if (!base) { + tbsize = TBMIN * sizeof(jschar); + length = TBMIN; + JS_ARENA_ALLOCATE_CAST(base, jschar *, pool, tbsize); + } else { + length = PTRDIFF(tb->limit, base, jschar); + tbsize = length * sizeof(jschar); + length <<= 1; + JS_ARENA_GROW_CAST(base, jschar *, pool, tbsize, tbsize); + } + if (!base) { + JS_ReportOutOfMemory(cx); + return JS_FALSE; + } + tb->base = base; + tb->limit = base + length; + tb->ptr = base + offset; + return JS_TRUE; +} + +static JSBool +AddToTokenBuf(JSContext *cx, JSTokenBuf *tb, jschar c) +{ + if (tb->ptr == tb->limit && !GrowTokenBuf(cx, tb)) + return JS_FALSE; + *tb->ptr++ = c; + return JS_TRUE; +} + +/* + * We have encountered a '\': check for a Unicode escape sequence after it, + * returning the character code value if we found a Unicode escape sequence. + * Otherwise, non-destructively return the original '\'. + */ +static int32 +GetUnicodeEscape(JSTokenStream *ts) +{ + jschar cp[5]; + int32 c; + + if (PeekChars(ts, 5, cp) && cp[0] == 'u' && + JS7_ISHEX(cp[1]) && JS7_ISHEX(cp[2]) && + JS7_ISHEX(cp[3]) && JS7_ISHEX(cp[4])) + { + c = (((((JS7_UNHEX(cp[1]) << 4) + + JS7_UNHEX(cp[2])) << 4) + + JS7_UNHEX(cp[3])) << 4) + + JS7_UNHEX(cp[4]); + SkipChars(ts, 5); + return c; + } + return '\\'; +} + +JSTokenType +js_GetToken(JSContext *cx, JSTokenStream *ts) +{ + JSTokenType tt; + JSToken *tp; + int32 c; + JSAtom *atom; + JSBool hadUnicodeEscape; + +#define INIT_TOKENBUF(tb) ((tb)->ptr = (tb)->base) +#define FINISH_TOKENBUF(tb) if (!AddToTokenBuf(cx, tb, 0)) RETURN(TOK_ERROR) +#define TOKEN_LENGTH(tb) ((tb)->ptr - (tb)->base - 1) +#define RETURN(tt) { if (tt == TOK_ERROR) ts->flags |= TSF_ERROR; \ + tp->pos.end.index = ts->linepos + \ + (ts->linebuf.ptr - ts->linebuf.base) - \ + ts->ungetpos; \ + return (tp->type = tt); } + + /* If there was a fatal error, keep returning TOK_ERROR. */ + if (ts->flags & TSF_ERROR) + return TOK_ERROR; + + /* Check for a pushed-back token resulting from mismatching lookahead. */ + while (ts->lookahead != 0) { + ts->lookahead--; + ts->cursor = (ts->cursor + 1) & NTOKENS_MASK; + tt = CURRENT_TOKEN(ts).type; + if (tt != TOK_EOL || (ts->flags & TSF_NEWLINES)) + return tt; + } + +retry: + do { + c = GetChar(ts); + if (c == '\n') { + ts->flags &= ~TSF_DIRTYLINE; + if (ts->flags & TSF_NEWLINES) + break; + } + } while (JS_ISSPACE(c)); + + ts->cursor = (ts->cursor + 1) & NTOKENS_MASK; + tp = &CURRENT_TOKEN(ts); + tp->ptr = ts->linebuf.ptr - 1; + tp->pos.begin.index = ts->linepos + (tp->ptr - ts->linebuf.base); + tp->pos.begin.lineno = tp->pos.end.lineno = (uint16)ts->lineno; + + if (c == EOF) + RETURN(TOK_EOF); + if (c != '-' && c != '\n') + ts->flags |= TSF_DIRTYLINE; + + hadUnicodeEscape = JS_FALSE; + if (JS_ISIDENT_START(c) || + (c == '\\' && + (c = GetUnicodeEscape(ts), + hadUnicodeEscape = JS_ISIDENT_START(c)))) { + INIT_TOKENBUF(&ts->tokenbuf); + for (;;) { + if (!AddToTokenBuf(cx, &ts->tokenbuf, (jschar)c)) + RETURN(TOK_ERROR); + c = GetChar(ts); + if (c == '\\') { + c = GetUnicodeEscape(ts); + if (!JS_ISIDENT(c)) + break; + hadUnicodeEscape = JS_TRUE; + } else { + if (!JS_ISIDENT(c)) + break; + } + } + UngetChar(ts, c); + FINISH_TOKENBUF(&ts->tokenbuf); + + atom = js_AtomizeChars(cx, + ts->tokenbuf.base, + TOKEN_LENGTH(&ts->tokenbuf), + 0); + if (!atom) + RETURN(TOK_ERROR); + if (!hadUnicodeEscape && ATOM_KEYWORD(atom)) { + struct keyword *kw = ATOM_KEYWORD(atom); + + if (JSVERSION_IS_ECMA(cx->version) || kw->version <= cx->version) { + tp->t_op = (JSOp) kw->op; + RETURN(kw->tokentype); + } + } + tp->t_op = JSOP_NAME; + tp->t_atom = atom; + RETURN(TOK_NAME); + } + + if (JS7_ISDEC(c) || (c == '.' && JS7_ISDEC(PeekChar(ts)))) { + jsint radix; + const jschar *endptr; + jsdouble dval; + + radix = 10; + INIT_TOKENBUF(&ts->tokenbuf); + + if (c == '0') { + if (!AddToTokenBuf(cx, &ts->tokenbuf, (jschar)c)) + RETURN(TOK_ERROR); + c = GetChar(ts); + if (JS_TOLOWER(c) == 'x') { + if (!AddToTokenBuf(cx, &ts->tokenbuf, (jschar)c)) + RETURN(TOK_ERROR); + c = GetChar(ts); + radix = 16; + } else if (JS7_ISDEC(c)) { + radix = 8; + } + } + + while (JS7_ISHEX(c)) { + if (radix < 16) { + if (JS7_ISLET(c)) + break; + + /* + * We permit 08 and 09 as decimal numbers, which makes our + * behaviour a superset of the ECMA numeric grammar. We might + * not always be so permissive, so we warn about it. + */ + if (radix == 8 && c >= '8') { + if (!js_ReportCompileErrorNumber(cx, ts, NULL, + JSREPORT_WARNING, + JSMSG_BAD_OCTAL, + c == '8' ? "08" : "09")) { + RETURN(TOK_ERROR); + } + radix = 10; + } + } + if (!AddToTokenBuf(cx, &ts->tokenbuf, (jschar)c)) + RETURN(TOK_ERROR); + c = GetChar(ts); + } + + if (radix == 10 && (c == '.' || JS_TOLOWER(c) == 'e')) { + if (c == '.') { + do { + if (!AddToTokenBuf(cx, &ts->tokenbuf, (jschar)c)) + RETURN(TOK_ERROR); + c = GetChar(ts); + } while (JS7_ISDEC(c)); + } + if (JS_TOLOWER(c) == 'e') { + if (!AddToTokenBuf(cx, &ts->tokenbuf, (jschar)c)) + RETURN(TOK_ERROR); + c = GetChar(ts); + if (c == '+' || c == '-') { + if (!AddToTokenBuf(cx, &ts->tokenbuf, (jschar)c)) + RETURN(TOK_ERROR); + c = GetChar(ts); + } + if (!JS7_ISDEC(c)) { + js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR, + JSMSG_MISSING_EXPONENT); + RETURN(TOK_ERROR); + } + do { + if (!AddToTokenBuf(cx, &ts->tokenbuf, (jschar)c)) + RETURN(TOK_ERROR); + c = GetChar(ts); + } while (JS7_ISDEC(c)); + } + } + + UngetChar(ts, c); + FINISH_TOKENBUF(&ts->tokenbuf); + + if (radix == 10) { + if (!js_strtod(cx, ts->tokenbuf.base, &endptr, &dval)) { + js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR, + JSMSG_OUT_OF_MEMORY); + RETURN(TOK_ERROR); + } + } else { + if (!js_strtointeger(cx, ts->tokenbuf.base, &endptr, radix, &dval)) { + js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR, + JSMSG_OUT_OF_MEMORY); + RETURN(TOK_ERROR); + } + } + tp->t_dval = dval; + RETURN(TOK_NUMBER); + } + + if (c == '"' || c == '\'') { + int32 val, qc = c; + + INIT_TOKENBUF(&ts->tokenbuf); + while ((c = GetChar(ts)) != qc) { + if (c == '\n' || c == EOF) { + UngetChar(ts, c); + js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR, + JSMSG_UNTERMINATED_STRING); + RETURN(TOK_ERROR); + } + if (c == '\\') { + switch (c = GetChar(ts)) { + case 'b': c = '\b'; break; + case 'f': c = '\f'; break; + case 'n': c = '\n'; break; + case 'r': c = '\r'; break; + case 't': c = '\t'; break; + case 'v': c = '\v'; break; + + default: + if ('0' <= c && c < '8') { + val = JS7_UNDEC(c); + c = PeekChar(ts); + if ('0' <= c && c < '8') { + val = 8 * val + JS7_UNDEC(c); + GetChar(ts); + c = PeekChar(ts); + if ('0' <= c && c < '8') { + int32 save = val; + val = 8 * val + JS7_UNDEC(c); + if (val <= 0377) + GetChar(ts); + else + val = save; + } + } + c = (jschar)val; + } else if (c == 'u') { + jschar cp[4]; + if (PeekChars(ts, 4, cp) && + JS7_ISHEX(cp[0]) && JS7_ISHEX(cp[1]) && + JS7_ISHEX(cp[2]) && JS7_ISHEX(cp[3])) { + c = (((((JS7_UNHEX(cp[0]) << 4) + + JS7_UNHEX(cp[1])) << 4) + + JS7_UNHEX(cp[2])) << 4) + + JS7_UNHEX(cp[3]); + SkipChars(ts, 4); + } + } else if (c == 'x') { + jschar cp[2]; + if (PeekChars(ts, 2, cp) && + JS7_ISHEX(cp[0]) && JS7_ISHEX(cp[1])) { + c = (JS7_UNHEX(cp[0]) << 4) + JS7_UNHEX(cp[1]); + SkipChars(ts, 2); + } + } else if (c == '\n' && JSVERSION_IS_ECMA(cx->version)) { + /* ECMA follows C by removing escaped newlines. */ + continue; + } + break; + } + } + if (!AddToTokenBuf(cx, &ts->tokenbuf, (jschar)c)) + RETURN(TOK_ERROR); + } + FINISH_TOKENBUF(&ts->tokenbuf); + atom = js_AtomizeChars(cx, + ts->tokenbuf.base, + TOKEN_LENGTH(&ts->tokenbuf), + 0); + if (!atom) + RETURN(TOK_ERROR); + tp->pos.end.lineno = (uint16)ts->lineno; + tp->t_op = JSOP_STRING; + tp->t_atom = atom; + RETURN(TOK_STRING); + } + + switch (c) { + case '\n': + c = TOK_EOL; + break; + + case ';': c = TOK_SEMI; break; + case '.': c = TOK_DOT; break; + case '[': c = TOK_LB; break; + case ']': c = TOK_RB; break; + case '{': c = TOK_LC; break; + case '}': c = TOK_RC; break; + case '(': c = TOK_LP; break; + case ')': c = TOK_RP; break; + case ',': c = TOK_COMMA; break; + case '?': c = TOK_HOOK; break; + + case ':': + /* + * Default so compiler can modify to JSOP_GETTER if 'p getter: v' in an + * object initializer, likewise for setter. + */ + tp->t_op = JSOP_NOP; + c = TOK_COLON; + break; + + case '|': + if (MatchChar(ts, c)) { + c = TOK_OR; + } else if (MatchChar(ts, '=')) { + tp->t_op = JSOP_BITOR; + c = TOK_ASSIGN; + } else { + c = TOK_BITOR; + } + break; + + case '^': + if (MatchChar(ts, '=')) { + tp->t_op = JSOP_BITXOR; + c = TOK_ASSIGN; + } else { + c = TOK_BITXOR; + } + break; + + case '&': + if (MatchChar(ts, c)) { + c = TOK_AND; + } else if (MatchChar(ts, '=')) { + tp->t_op = JSOP_BITAND; + c = TOK_ASSIGN; + } else { + c = TOK_BITAND; + } + break; + + case '=': + if (MatchChar(ts, c)) { +#if JS_HAS_TRIPLE_EQOPS + tp->t_op = MatchChar(ts, c) ? JSOP_NEW_EQ : (JSOp)cx->jsop_eq; +#else + tp->t_op = cx->jsop_eq; +#endif + c = TOK_EQOP; + } else { + tp->t_op = JSOP_NOP; + c = TOK_ASSIGN; + } + break; + + case '!': + if (MatchChar(ts, '=')) { +#if JS_HAS_TRIPLE_EQOPS + tp->t_op = MatchChar(ts, '=') ? JSOP_NEW_NE : (JSOp)cx->jsop_ne; +#else + tp->t_op = cx->jsop_ne; +#endif + c = TOK_EQOP; + } else { + tp->t_op = JSOP_NOT; + c = TOK_UNARYOP; + } + break; + + case '<': + /* NB: treat HTML begin-comment as comment-till-end-of-line */ + if (MatchChar(ts, '!')) { + if (MatchChar(ts, '-')) { + if (MatchChar(ts, '-')) + goto skipline; + UngetChar(ts, '-'); + } + UngetChar(ts, '!'); + } + if (MatchChar(ts, c)) { + tp->t_op = JSOP_LSH; + c = MatchChar(ts, '=') ? TOK_ASSIGN : TOK_SHOP; + } else { + tp->t_op = MatchChar(ts, '=') ? JSOP_LE : JSOP_LT; + c = TOK_RELOP; + } + break; + + case '>': + if (MatchChar(ts, c)) { + tp->t_op = MatchChar(ts, c) ? JSOP_URSH : JSOP_RSH; + c = MatchChar(ts, '=') ? TOK_ASSIGN : TOK_SHOP; + } else { + tp->t_op = MatchChar(ts, '=') ? JSOP_GE : JSOP_GT; + c = TOK_RELOP; + } + break; + + case '*': + tp->t_op = JSOP_MUL; + c = MatchChar(ts, '=') ? TOK_ASSIGN : TOK_STAR; + break; + + case '/': + if (MatchChar(ts, '/')) { +skipline: + while ((c = GetChar(ts)) != EOF && c != '\n') + /* skip to end of line */; + UngetChar(ts, c); + goto retry; + } + if (MatchChar(ts, '*')) { + while ((c = GetChar(ts)) != EOF && + !(c == '*' && MatchChar(ts, '/'))) { + /* Ignore all characters until comment close. */ + } + if (c == EOF) { + js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR, + JSMSG_UNTERMINATED_COMMENT); + RETURN(TOK_ERROR); + } + goto retry; + } + +#if JS_HAS_REGEXPS + if (ts->flags & TSF_REGEXP) { + JSObject *obj; + uintN flags; + + INIT_TOKENBUF(&ts->tokenbuf); + while ((c = GetChar(ts)) != '/') { + if (c == '\n' || c == EOF) { + UngetChar(ts, c); + js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR, + JSMSG_UNTERMINATED_REGEXP); + RETURN(TOK_ERROR); + } + if (c == '\\') { + if (!AddToTokenBuf(cx, &ts->tokenbuf, (jschar)c)) + RETURN(TOK_ERROR); + c = GetChar(ts); + } + if (!AddToTokenBuf(cx, &ts->tokenbuf, (jschar)c)) + RETURN(TOK_ERROR); + } + FINISH_TOKENBUF(&ts->tokenbuf); + for (flags = 0; ; ) { + if (MatchChar(ts, 'g')) + flags |= JSREG_GLOB; + else if (MatchChar(ts, 'i')) + flags |= JSREG_FOLD; + else if (MatchChar(ts, 'm')) + flags |= JSREG_MULTILINE; + else + break; + } + c = PeekChar(ts); + if (JS7_ISLET(c)) { + tp->ptr = ts->linebuf.ptr - 1; + js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR, + JSMSG_BAD_REGEXP_FLAG); + (void) GetChar(ts); + RETURN(TOK_ERROR); + } + obj = js_NewRegExpObject(cx, ts, + ts->tokenbuf.base, + TOKEN_LENGTH(&ts->tokenbuf), + flags); + if (!obj) + RETURN(TOK_ERROR); + atom = js_AtomizeObject(cx, obj, 0); + if (!atom) + RETURN(TOK_ERROR); + tp->t_op = JSOP_OBJECT; + tp->t_atom = atom; + RETURN(TOK_OBJECT); + } +#endif /* JS_HAS_REGEXPS */ + + tp->t_op = JSOP_DIV; + c = MatchChar(ts, '=') ? TOK_ASSIGN : TOK_DIVOP; + break; + + case '%': + tp->t_op = JSOP_MOD; + c = MatchChar(ts, '=') ? TOK_ASSIGN : TOK_DIVOP; + break; + + case '~': + tp->t_op = JSOP_BITNOT; + c = TOK_UNARYOP; + break; + + case '+': + if (MatchChar(ts, '=')) { + tp->t_op = JSOP_ADD; + c = TOK_ASSIGN; + } else if (MatchChar(ts, c)) { + c = TOK_INC; + } else { + tp->t_op = JSOP_POS; + c = TOK_PLUS; + } + break; + + case '-': + if (MatchChar(ts, '=')) { + tp->t_op = JSOP_SUB; + c = TOK_ASSIGN; + } else if (MatchChar(ts, c)) { + if (PeekChar(ts) == '>' && !(ts->flags & TSF_DIRTYLINE)) + goto skipline; + c = TOK_DEC; + } else { + tp->t_op = JSOP_NEG; + c = TOK_MINUS; + } + ts->flags |= TSF_DIRTYLINE; + break; + +#if JS_HAS_SHARP_VARS + case '#': + { + uint32 n; + + c = GetChar(ts); + if (!JS7_ISDEC(c)) { + UngetChar(ts, c); + goto badchar; + } + n = (uint32)JS7_UNDEC(c); + for (;;) { + c = GetChar(ts); + if (!JS7_ISDEC(c)) + break; + n = 10 * n + JS7_UNDEC(c); + if (n >= ATOM_INDEX_LIMIT) { + js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR, + JSMSG_SHARPVAR_TOO_BIG); + RETURN(TOK_ERROR); + } + } + tp->t_dval = (jsdouble) n; + if (JS_HAS_STRICT_OPTION(cx) && + (c == '=' || c == '#')) { + char buf[20]; + JS_snprintf(buf, sizeof buf, "#%u%c", n, c); + if (!js_ReportCompileErrorNumber(cx, ts, NULL, + JSREPORT_WARNING | + JSREPORT_STRICT, + JSMSG_DEPRECATED_USAGE, + buf)) { + RETURN(TOK_ERROR); + } + } + if (c == '=') + RETURN(TOK_DEFSHARP); + if (c == '#') + RETURN(TOK_USESHARP); + goto badchar; + } + + badchar: +#endif /* JS_HAS_SHARP_VARS */ + + default: + js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR, + JSMSG_ILLEGAL_CHARACTER); + RETURN(TOK_ERROR); + } + + JS_ASSERT(c < TOK_LIMIT); + RETURN((JSTokenType)c); + +#undef INIT_TOKENBUF +#undef FINISH_TOKENBUF +#undef TOKEN_LENGTH +#undef RETURN +} + +void +js_UngetToken(JSTokenStream *ts) +{ + JS_ASSERT(ts->lookahead < NTOKENS_MASK); + if (ts->flags & TSF_ERROR) + return; + ts->lookahead++; + ts->cursor = (ts->cursor - 1) & NTOKENS_MASK; +} + +JSBool +js_MatchToken(JSContext *cx, JSTokenStream *ts, JSTokenType tt) +{ + if (js_GetToken(cx, ts) == tt) + return JS_TRUE; + js_UngetToken(ts); + return JS_FALSE; +} diff --git a/src/dom/js/jsscan.h b/src/dom/js/jsscan.h new file mode 100644 index 000000000..c61eff926 --- /dev/null +++ b/src/dom/js/jsscan.h @@ -0,0 +1,264 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef jsscan_h___ +#define jsscan_h___ +/* + * JS lexical scanner interface. + */ +#include +#include +#include "jsopcode.h" +#include "jsprvtd.h" +#include "jspubtd.h" + +JS_BEGIN_EXTERN_C + +typedef enum JSTokenType { + TOK_ERROR = -1, /* well-known as the only code < EOF */ + TOK_EOF = 0, /* end of file */ + TOK_EOL = 1, /* end of line */ + TOK_SEMI = 2, /* semicolon */ + TOK_COMMA = 3, /* comma operator */ + TOK_ASSIGN = 4, /* assignment ops (= += -= etc.) */ + TOK_HOOK = 5, TOK_COLON = 6, /* conditional (?:) */ + TOK_OR = 7, /* logical or (||) */ + TOK_AND = 8, /* logical and (&&) */ + TOK_BITOR = 9, /* bitwise-or (|) */ + TOK_BITXOR = 10, /* bitwise-xor (^) */ + TOK_BITAND = 11, /* bitwise-and (&) */ + TOK_EQOP = 12, /* equality ops (== !=) */ + TOK_RELOP = 13, /* relational ops (< <= > >=) */ + TOK_SHOP = 14, /* shift ops (<< >> >>>) */ + TOK_PLUS = 15, /* plus */ + TOK_MINUS = 16, /* minus */ + TOK_STAR = 17, TOK_DIVOP = 18, /* multiply/divide ops (* / %) */ + TOK_UNARYOP = 19, /* unary prefix operator */ + TOK_INC = 20, TOK_DEC = 21, /* increment/decrement (++ --) */ + TOK_DOT = 22, /* member operator (.) */ + TOK_LB = 23, TOK_RB = 24, /* left and right brackets */ + TOK_LC = 25, TOK_RC = 26, /* left and right curlies (braces) */ + TOK_LP = 27, TOK_RP = 28, /* left and right parentheses */ + TOK_NAME = 29, /* identifier */ + TOK_NUMBER = 30, /* numeric constant */ + TOK_STRING = 31, /* string constant */ + TOK_OBJECT = 32, /* RegExp or other object constant */ + TOK_PRIMARY = 33, /* true, false, null, this, super */ + TOK_FUNCTION = 34, /* function keyword */ + TOK_EXPORT = 35, /* export keyword */ + TOK_IMPORT = 36, /* import keyword */ + TOK_IF = 37, /* if keyword */ + TOK_ELSE = 38, /* else keyword */ + TOK_SWITCH = 39, /* switch keyword */ + TOK_CASE = 40, /* case keyword */ + TOK_DEFAULT = 41, /* default keyword */ + TOK_WHILE = 42, /* while keyword */ + TOK_DO = 43, /* do keyword */ + TOK_FOR = 44, /* for keyword */ + TOK_BREAK = 45, /* break keyword */ + TOK_CONTINUE = 46, /* continue keyword */ + TOK_IN = 47, /* in keyword */ + TOK_VAR = 48, /* var keyword */ + TOK_WITH = 49, /* with keyword */ + TOK_RETURN = 50, /* return keyword */ + TOK_NEW = 51, /* new keyword */ + TOK_DELETE = 52, /* delete keyword */ + TOK_DEFSHARP = 53, /* #n= for object/array initializers */ + TOK_USESHARP = 54, /* #n# for object/array initializers */ + TOK_TRY = 55, /* try keyword */ + TOK_CATCH = 56, /* catch keyword */ + TOK_FINALLY = 57, /* finally keyword */ + TOK_THROW = 58, /* throw keyword */ + TOK_INSTANCEOF = 59, /* instanceof keyword */ + TOK_DEBUGGER = 60, /* debugger keyword */ + TOK_RESERVED, /* reserved keywords */ + TOK_LIMIT /* domain size */ +} JSTokenType; + +#define IS_PRIMARY_TOKEN(tt) \ + ((uintN)((tt) - TOK_NAME) <= (uintN)(TOK_PRIMARY - TOK_NAME)) + +struct JSTokenPtr { + uint16 index; /* index of char in physical line */ + uint16 lineno; /* physical line number */ +}; + +struct JSTokenPos { + JSTokenPtr begin; /* first character and line of token */ + JSTokenPtr end; /* index 1 past last char, last line */ +}; + +struct JSToken { + JSTokenType type; /* char value or above enumerator */ + JSTokenPos pos; /* token position in file */ + jschar *ptr; /* beginning of token in line buffer */ + union { + struct { + JSOp op; /* operator, for minimal parser */ + JSAtom *atom; /* atom table entry */ + } s; + jsdouble dval; /* floating point number */ + } u; +}; + +#define t_op u.s.op +#define t_atom u.s.atom +#define t_dval u.dval + +typedef struct JSTokenBuf { + jschar *base; /* base of line or stream buffer */ + jschar *limit; /* limit for quick bounds check */ + jschar *ptr; /* next char to get, or slot to use */ +} JSTokenBuf; + +#define JS_LINE_LIMIT 256 /* logical line buffer size limit -- + physical line length is unlimited */ +#define NTOKENS 4 /* 1 current + 2 lookahead, rounded */ +#define NTOKENS_MASK (NTOKENS-1) /* to power of 2 to avoid divmod by 3 */ + +struct JSTokenStream { + JSToken tokens[NTOKENS];/* circular token buffer */ + uintN cursor; /* index of last parsed token */ + uintN lookahead; /* count of lookahead tokens */ + uintN lineno; /* current line number */ + uintN ungetpos; /* next free char slot in ungetbuf */ + jschar ungetbuf[6]; /* at most 6, for \uXXXX lookahead */ + uintN flags; /* flags -- see below */ + ptrdiff_t linelen; /* physical linebuf segment length */ + ptrdiff_t linepos; /* linebuf offset in physical line */ + JSTokenBuf linebuf; /* line buffer for diagnostics */ + JSTokenBuf userbuf; /* user input buffer if !file */ + JSTokenBuf tokenbuf; /* current token string buffer */ + const char *filename; /* input filename or null */ + FILE *file; /* stdio stream if reading from file */ + JSPrincipals *principals; /* principals associated with source */ + JSSourceHandler listener; /* callback for source; eg debugger */ + void *listenerData; /* listener 'this' data */ + void *listenerTSData;/* listener data for this TokenStream */ +}; + +#define CURRENT_TOKEN(ts) ((ts)->tokens[(ts)->cursor]) +#define ON_CURRENT_LINE(ts,pos) ((uint16)(ts)->lineno == (pos).end.lineno) + +/* JSTokenStream flags */ +#define TSF_ERROR 0x01 /* fatal error while compiling */ +#define TSF_EOF 0x02 /* hit end of file */ +#define TSF_NEWLINES 0x04 /* tokenize newlines */ +#define TSF_REGEXP 0x08 /* looking for a regular expression */ +#define TSF_NLFLAG 0x20 /* last linebuf ended with \n */ +#define TSF_CRFLAG 0x40 /* linebuf would have ended with \r */ +#define TSF_DIRTYLINE 0x80 /* stuff other than whitespace since start of line */ + +/* Unicode separators that are treated as line terminators, in addition to \n, \r */ +#define LINE_SEPARATOR 0x2028 +#define PARA_SEPARATOR 0x2029 + +/* + * Create a new token stream, either from an input buffer or from a file. + * Return null on file-open or memory-allocation failure. + * + * NB: All of js_New{,Buffer,File}TokenStream() return a pointer to transient + * memory in the current context's temp pool. This memory is deallocated via + * JS_ARENA_RELEASE() after parsing is finished. + */ +extern JSTokenStream * +js_NewTokenStream(JSContext *cx, const jschar *base, size_t length, + const char *filename, uintN lineno, JSPrincipals *principals); + +extern JS_FRIEND_API(JSTokenStream *) +js_NewBufferTokenStream(JSContext *cx, const jschar *base, size_t length); + +extern JS_FRIEND_API(JSTokenStream *) +js_NewFileTokenStream(JSContext *cx, const char *filename, FILE *defaultfp); + +extern JS_FRIEND_API(JSBool) +js_CloseTokenStream(JSContext *cx, JSTokenStream *ts); + +/* + * Initialize the scanner, installing JS keywords into cx's global scope. + */ +extern JSBool +js_InitScanner(JSContext *cx); + +/* + * Friend-exported API entry point to call a mapping function on each reserved + * identifier in the scanner's keyword table. + */ +extern JS_FRIEND_API(void) +js_MapKeywords(void (*mapfun)(const char *)); + +/* + * Report a compile-time error by its number, using ts or cg to show context. + * Return true for a warning, false for an error. + */ +extern JSBool +js_ReportCompileErrorNumber(JSContext *cx, JSTokenStream *ts, + JSCodeGenerator *cg, uintN flags, + const uintN errorNumber, ...); + +/* + * Look ahead one token and return its type. + */ +extern JSTokenType +js_PeekToken(JSContext *cx, JSTokenStream *ts); + +extern JSTokenType +js_PeekTokenSameLine(JSContext *cx, JSTokenStream *ts); + +/* + * Get the next token from ts. + */ +extern JSTokenType +js_GetToken(JSContext *cx, JSTokenStream *ts); + +/* + * Push back the last scanned token onto ts. + */ +extern void +js_UngetToken(JSTokenStream *ts); + +/* + * Get the next token from ts if its type is tt. + */ +extern JSBool +js_MatchToken(JSContext *cx, JSTokenStream *ts, JSTokenType tt); + +JS_END_EXTERN_C + +#endif /* jsscan_h___ */ diff --git a/src/dom/js/jsscope.c b/src/dom/js/jsscope.c new file mode 100644 index 000000000..20243e9b7 --- /dev/null +++ b/src/dom/js/jsscope.c @@ -0,0 +1,1581 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* + * JS symbol tables. + */ +#include "jsstddef.h" +#include +#include +#include "jstypes.h" +#include "jsarena.h" +#include "jsbit.h" +#include "jsclist.h" +#include "jsdhash.h" +#include "jsutil.h" /* Added by JSIFY */ +#include "jsapi.h" +#include "jsatom.h" +#include "jscntxt.h" +#include "jsdbgapi.h" +#include "jslock.h" +#include "jsnum.h" +#include "jsscope.h" +#include "jsstr.h" + +JSScope * +js_GetMutableScope(JSContext *cx, JSObject *obj) +{ + JSScope *scope, *newscope; + + scope = OBJ_SCOPE(obj); + JS_ASSERT(JS_IS_SCOPE_LOCKED(cx, scope)); + if (scope->object == obj) + return scope; + newscope = js_NewScope(cx, 0, scope->map.ops, LOCKED_OBJ_GET_CLASS(obj), + obj); + if (!newscope) + return NULL; + JS_LOCK_SCOPE(cx, newscope); + obj->map = js_HoldObjectMap(cx, &newscope->map); + scope = (JSScope *) js_DropObjectMap(cx, &scope->map, obj); + JS_TRANSFER_SCOPE_LOCK(cx, scope, newscope); + return newscope; +} + +/* + * JSScope uses multiplicative hashing, _a la_ jsdhash.[ch], but specialized + * to minimize footprint. But if a scope has fewer than SCOPE_HASH_THRESHOLD + * entries, we use linear search and avoid allocating scope->table. + */ +#define SCOPE_HASH_THRESHOLD 6 +#define MIN_SCOPE_SIZE_LOG2 4 +#define MIN_SCOPE_SIZE JS_BIT(MIN_SCOPE_SIZE_LOG2) +#define SCOPE_TABLE_NBYTES(n) ((n) * sizeof(JSScopeProperty *)) + +static void +InitMinimalScope(JSScope *scope) +{ + scope->hashShift = JS_DHASH_BITS - MIN_SCOPE_SIZE_LOG2; + scope->entryCount = scope->removedCount = 0; + scope->table = NULL; + scope->lastProp = NULL; +} + +static JSBool +CreateScopeTable(JSScope *scope) +{ + int sizeLog2; + JSScopeProperty *sprop, **spp; + + JS_ASSERT(!scope->table); + JS_ASSERT(scope->lastProp); + + if (scope->entryCount > SCOPE_HASH_THRESHOLD) { + /* + * Ouch: calloc failed at least once already -- let's try again, + * overallocating to hold at least twice the current population. + */ + sizeLog2 = JS_CeilingLog2(2 * scope->entryCount); + scope->hashShift = JS_DHASH_BITS - sizeLog2; + } else { + JS_ASSERT(scope->hashShift == JS_DHASH_BITS - MIN_SCOPE_SIZE_LOG2); + sizeLog2 = MIN_SCOPE_SIZE_LOG2; + } + + scope->table = (JSScopeProperty **) + calloc(JS_BIT(sizeLog2), sizeof(JSScopeProperty *)); + if (!scope->table) + return JS_FALSE; + + scope->hashShift = JS_DHASH_BITS - sizeLog2; + for (sprop = scope->lastProp; sprop; sprop = sprop->parent) { + spp = js_SearchScope(scope, sprop->id, JS_TRUE); + SPROP_STORE_PRESERVING_COLLISION(spp, sprop); + } + return JS_TRUE; +} + +JSScope * +js_NewScope(JSContext *cx, jsrefcount nrefs, JSObjectOps *ops, JSClass *clasp, + JSObject *obj) +{ + JSScope *scope; + + scope = (JSScope *) JS_malloc(cx, sizeof(JSScope)); + if (!scope) + return NULL; + + js_InitObjectMap(&scope->map, nrefs, ops, clasp); + scope->object = obj; + scope->flags = 0; + InitMinimalScope(scope); + +#ifdef JS_THREADSAFE + scope->ownercx = cx; + memset(&scope->lock, 0, sizeof scope->lock); + + /* + * Set u.link = NULL, not u.count = 0, in case the target architecture's + * null pointer has a non-zero integer representation. + */ + scope->u.link = NULL; + +#ifdef DEBUG + scope->file[0] = scope->file[1] = scope->file[2] = scope->file[3] = NULL; + scope->line[0] = scope->line[1] = scope->line[2] = scope->line[3] = 0; +#endif +#endif + + JS_RUNTIME_METER(cx->runtime, liveScopes); + JS_RUNTIME_METER(cx->runtime, totalScopes); + return scope; +} + +#ifdef DEBUG_SCOPE_COUNT +extern void +js_unlog_scope(JSScope *scope); +#endif + +void +js_DestroyScope(JSContext *cx, JSScope *scope) +{ +#ifdef DEBUG_SCOPE_COUNT + js_unlog_scope(scope); +#endif + +#ifdef JS_THREADSAFE + /* Scope must be single-threaded at this point, so set scope->ownercx. */ + JS_ASSERT(scope->u.count == 0); + scope->ownercx = cx; + js_FinishLock(&scope->lock); +#endif + if (scope->table) + JS_free(cx, scope->table); + +#ifdef DEBUG + JS_LOCK_RUNTIME_VOID(cx->runtime, + cx->runtime->liveScopeProps -= scope->entryCount); +#endif + JS_RUNTIME_UNMETER(cx->runtime, liveScopes); + JS_free(cx, scope); +} + +#ifdef DEBUG_brendan +typedef struct JSScopeStats { + jsrefcount searches; + jsrefcount steps; + jsrefcount hits; + jsrefcount misses; + jsrefcount stepHits; + jsrefcount stepMisses; + jsrefcount adds; + jsrefcount redundantAdds; + jsrefcount addFailures; + jsrefcount changeFailures; + jsrefcount compresses; + jsrefcount grows; + jsrefcount removes; + jsrefcount removeFrees; + jsrefcount uselessRemoves; + jsrefcount shrinks; +} JSScopeStats; + +JS_FRIEND_DATA(JSScopeStats) js_scope_stats; + +# define METER(x) JS_ATOMIC_INCREMENT(&js_scope_stats.x) +#else +# define METER(x) /* nothing */ +#endif + +/* + * Double hashing needs the second hash code to be relatively prime to table + * size, so we simply make hash2 odd. The inputs to multiplicative hash are + * the golden ratio, expressed as a fixed-point 32 bit fraction, and the int + * property index or named property's atom number (observe that most objects + * have either no indexed properties, or almost all indexed and a few names, + * so collisions between index and atom number are unlikely). + */ +#define SCOPE_HASH0(id) (HASH_ID(id) * JS_GOLDEN_RATIO) +#define SCOPE_HASH1(hash0,shift) ((hash0) >> (shift)) +#define SCOPE_HASH2(hash0,log2,shift) ((((hash0) << (log2)) >> (shift)) | 1) + +JS_FRIEND_API(JSScopeProperty **) +js_SearchScope(JSScope *scope, jsid id, JSBool adding) +{ + JSHashNumber hash0, hash1, hash2; + int hashShift, sizeLog2; + JSScopeProperty *stored, *sprop, **spp, **firstRemoved; + uint32 sizeMask; + + METER(searches); + if (!scope->table) { + /* Not enough properties to justify hashing: search from lastProp. */ + JS_ASSERT(!SCOPE_HAD_MIDDLE_DELETE(scope)); + for (spp = &scope->lastProp; (sprop = *spp); spp = &sprop->parent) { + if (sprop->id == id) { + METER(hits); + return spp; + } + } + METER(misses); + return spp; + } + + /* Compute the primary hash address. */ + hash0 = SCOPE_HASH0(id); + hashShift = scope->hashShift; + hash1 = SCOPE_HASH1(hash0, hashShift); + spp = scope->table + hash1; + + /* Miss: return space for a new entry. */ + stored = *spp; + if (SPROP_IS_FREE(stored)) { + METER(misses); + return spp; + } + + /* Hit: return entry. */ + sprop = SPROP_CLEAR_COLLISION(stored); + if (sprop && sprop->id == id) { + METER(hits); + return spp; + } + + /* Collision: double hash. */ + sizeLog2 = JS_DHASH_BITS - hashShift; + hash2 = SCOPE_HASH2(hash0, sizeLog2, hashShift); + sizeMask = JS_BITMASK(sizeLog2); + + /* Save the first removed entry pointer so we can recycle it if adding. */ + if (SPROP_IS_REMOVED(stored)) { + firstRemoved = spp; + } else { + firstRemoved = NULL; + if (adding && !SPROP_HAD_COLLISION(stored)) + SPROP_FLAG_COLLISION(spp, sprop); + } + + for (;;) { + METER(steps); + hash1 -= hash2; + hash1 &= sizeMask; + spp = scope->table + hash1; + + stored = *spp; + if (SPROP_IS_FREE(stored)) { + METER(stepMisses); + return (adding && firstRemoved) ? firstRemoved : spp; + } + + sprop = SPROP_CLEAR_COLLISION(stored); + if (sprop && sprop->id == id) { + METER(stepHits); + return spp; + } + + if (SPROP_IS_REMOVED(stored)) { + if (!firstRemoved) + firstRemoved = spp; + } else { + if (adding && !SPROP_HAD_COLLISION(stored)) + SPROP_FLAG_COLLISION(spp, sprop); + } + } + + /* NOTREACHED */ + return NULL; +} + +static JSBool +ChangeScope(JSContext *cx, JSScope *scope, int change) +{ + int oldlog2, newlog2; + uint32 oldsize, newsize, nbytes; + JSScopeProperty **table, **oldtable, **spp, **oldspp, *sprop; + + /* Grow, shrink, or compress by changing scope->table. */ + oldlog2 = JS_DHASH_BITS - scope->hashShift; + newlog2 = oldlog2 + change; + oldsize = JS_BIT(oldlog2); + newsize = JS_BIT(newlog2); + nbytes = SCOPE_TABLE_NBYTES(newsize); + table = (JSScopeProperty **) calloc(nbytes, 1); + if (!table) { + JS_ReportOutOfMemory(cx); + return JS_FALSE; + } + + /* Now that we have a new table allocated, update scope members. */ + scope->hashShift = JS_DHASH_BITS - newlog2; + scope->removedCount = 0; + oldtable = scope->table; + scope->table = table; + + /* Copy only live entries, leaving removed and free ones behind. */ + for (oldspp = oldtable; oldsize != 0; oldspp++) { + sprop = SPROP_FETCH(oldspp); + if (sprop) { + spp = js_SearchScope(scope, sprop->id, JS_TRUE); + JS_ASSERT(SPROP_IS_FREE(*spp)); + *spp = sprop; + } + oldsize--; + } + + /* Finally, free the old table storage. */ + JS_free(cx, oldtable); + return JS_TRUE; +} + +/* + * Take care to exclude the mark and duplicate bits, in case we're called from + * the GC, or we are searching for a property that has not yet been flagged as + * a duplicate when making a duplicate formal parameter. + */ +#define SPROP_FLAGS_NOT_MATCHED (SPROP_MARK | SPROP_IS_DUPLICATE) + +JS_STATIC_DLL_CALLBACK(JSDHashNumber) +js_HashScopeProperty(JSDHashTable *table, const void *key) +{ + const JSScopeProperty *sprop = (const JSScopeProperty *)key; + JSDHashNumber hash; + JSPropertyOp gsop; + + /* Accumulate from least to most random so the low bits are most random. */ + hash = 0; + gsop = sprop->getter; + if (gsop) + hash = (hash >> (JS_DHASH_BITS - 4)) ^ (hash << 4) ^ (jsword)gsop; + gsop = sprop->setter; + if (gsop) + hash = (hash >> (JS_DHASH_BITS - 4)) ^ (hash << 4) ^ (jsword)gsop; + + hash = (hash >> (JS_DHASH_BITS - 4)) ^ (hash << 4) + ^ (sprop->flags & ~SPROP_FLAGS_NOT_MATCHED); + + hash = (hash >> (JS_DHASH_BITS - 4)) ^ (hash << 4) ^ sprop->attrs; + hash = (hash >> (JS_DHASH_BITS - 4)) ^ (hash << 4) ^ sprop->shortid; + hash = (hash >> (JS_DHASH_BITS - 4)) ^ (hash << 4) ^ sprop->slot; + hash = (hash >> (JS_DHASH_BITS - 4)) ^ (hash << 4) ^ sprop->id; + return hash; +} + +#define SPROP_MATCH(sprop, child) \ + SPROP_MATCH_PARAMS(sprop, (child)->id, (child)->getter, (child)->setter, \ + (child)->slot, (child)->attrs, (child)->flags, \ + (child)->shortid) + +#define SPROP_MATCH_PARAMS(sprop, aid, agetter, asetter, aslot, aattrs, \ + aflags, ashortid) \ + ((sprop)->id == (aid) && \ + SPROP_MATCH_PARAMS_AFTER_ID(sprop, agetter, asetter, aslot, aattrs, \ + aflags, ashortid)) + +#define SPROP_MATCH_PARAMS_AFTER_ID(sprop, agetter, asetter, aslot, aattrs, \ + aflags, ashortid) \ + ((sprop)->getter == (agetter) && \ + (sprop)->setter == (asetter) && \ + (sprop)->slot == (aslot) && \ + (sprop)->attrs == (aattrs) && \ + (((sprop)->flags ^ (aflags)) & ~SPROP_FLAGS_NOT_MATCHED) == 0 && \ + (sprop)->shortid == (ashortid)) + +JS_STATIC_DLL_CALLBACK(JSBool) +js_MatchScopeProperty(JSDHashTable *table, + const JSDHashEntryHdr *hdr, + const void *key) +{ + const JSPropertyTreeEntry *entry = (const JSPropertyTreeEntry *)hdr; + const JSScopeProperty *sprop = entry->child; + const JSScopeProperty *kprop = (const JSScopeProperty *)key; + + return SPROP_MATCH(sprop, kprop); +} + +static const JSDHashTableOps PropertyTreeHashOps = { + JS_DHashAllocTable, + JS_DHashFreeTable, + JS_DHashGetKeyStub, + js_HashScopeProperty, + js_MatchScopeProperty, + JS_DHashMoveEntryStub, + JS_DHashClearEntryStub, + JS_DHashFinalizeStub, + NULL +}; + +/* + * A property tree node on rt->propertyFreeList overlays the following prefix + * struct on JSScopeProperty. + */ +typedef struct FreeNode { + jsid id; + JSScopeProperty *next; + JSScopeProperty **prevp; +} FreeNode; + +#define FREENODE(sprop) ((FreeNode *) (sprop)) + +#define FREENODE_INSERT(list, sprop) \ + JS_BEGIN_MACRO \ + FREENODE(sprop)->next = (list); \ + FREENODE(sprop)->prevp = &(list); \ + if (list) \ + FREENODE(list)->prevp = &FREENODE(sprop)->next; \ + (list) = (sprop); \ + JS_END_MACRO + +#define FREENODE_REMOVE(sprop) \ + JS_BEGIN_MACRO \ + *FREENODE(sprop)->prevp = FREENODE(sprop)->next; \ + if (FREENODE(sprop)->next) \ + FREENODE(FREENODE(sprop)->next)->prevp = FREENODE(sprop)->prevp; \ + JS_END_MACRO + +/* NB: Called with the runtime lock held. */ +static JSScopeProperty * +NewScopeProperty(JSRuntime *rt) +{ + JSScopeProperty *sprop; + + sprop = rt->propertyFreeList; + if (sprop) { + FREENODE_REMOVE(sprop); + } else { + JS_ARENA_ALLOCATE_CAST(sprop, JSScopeProperty *, + &rt->propertyArenaPool, + sizeof(JSScopeProperty)); + if (!sprop) + return NULL; + } + + JS_RUNTIME_METER(rt, livePropTreeNodes); + JS_RUNTIME_METER(rt, totalPropTreeNodes); + return sprop; +} + +#define CHUNKY_KIDS_TAG ((jsuword)1) +#define KIDS_IS_CHUNKY(kids) ((jsuword)(kids) & CHUNKY_KIDS_TAG) +#define KIDS_TO_CHUNK(kids) ((PropTreeKidsChunk *) \ + ((jsuword)(kids) & ~CHUNKY_KIDS_TAG)) +#define CHUNK_TO_KIDS(chunk) ((JSScopeProperty *) \ + ((jsuword)(chunk) | CHUNKY_KIDS_TAG)) +#define MAX_KIDS_PER_CHUNK 10 + +typedef struct PropTreeKidsChunk PropTreeKidsChunk; + +struct PropTreeKidsChunk { + JSScopeProperty *kids[MAX_KIDS_PER_CHUNK]; + PropTreeKidsChunk *next; +}; + +static PropTreeKidsChunk * +NewPropTreeKidsChunk(JSRuntime *rt) +{ + PropTreeKidsChunk *chunk; + + chunk = calloc(1, sizeof *chunk); + if (!chunk) + return NULL; + JS_ASSERT(((jsuword)chunk & CHUNKY_KIDS_TAG) == 0); + JS_RUNTIME_METER(rt, propTreeKidsChunks); + return chunk; +} + +static void +DestroyPropTreeKidsChunk(JSRuntime *rt, PropTreeKidsChunk *chunk) +{ + JS_RUNTIME_UNMETER(rt, propTreeKidsChunks); + free(chunk); +} + +/* NB: Called with the runtime lock held. */ +static JSBool +InsertPropertyTreeChild(JSRuntime *rt, JSScopeProperty *parent, + JSScopeProperty *child) +{ + JSPropertyTreeEntry *entry; + JSScopeProperty **childp, *kids, *sprop; + PropTreeKidsChunk *chunk, **chunkp; + uintN i; + + JS_ASSERT(!parent || child->parent != parent); + + if (!parent) { + entry = (JSPropertyTreeEntry *) + JS_DHashTableOperate(&rt->propertyTreeHash, child, JS_DHASH_ADD); + if (!entry) + return JS_FALSE; + childp = &entry->child; + sprop = *childp; + if (!sprop) { + *childp = child; + } else { + /* + * A "Duplicate child" case. + * + * We can't do away with child, as at least one live scope entry + * still points at it. What's more, that scope's lastProp chains + * through an ancestor line to reach child, and js_Enumerate and + * others count on this linkage. We must leave child out of the + * hash table, and not require it to be there when we eventually + * GC it (see RemovePropertyTreeChild, below). + * + * It is necessary to leave the duplicate child out of the hash + * table to preserve entry uniqueness. It is safe to leave the + * child out of the hash table (unlike the duplicate child cases + * below), because the child's parent link will be null, which + * can't dangle. + */ + JS_ASSERT(sprop != child && SPROP_MATCH(sprop, child)); + JS_RUNTIME_METER(rt, duplicatePropTreeNodes); + } + } else { + childp = &parent->kids; + kids = *childp; + if (kids) { + if (KIDS_IS_CHUNKY(kids)) { + chunk = KIDS_TO_CHUNK(kids); + do { + for (i = 0; i < MAX_KIDS_PER_CHUNK; i++) { + childp = &chunk->kids[i]; + sprop = *childp; + if (!sprop) + goto insert; + + JS_ASSERT(sprop != child); + if (SPROP_MATCH(sprop, child)) { + /* + * Duplicate child, see comment above. In this + * case, we must let the duplicate be inserted at + * this level in the tree, so we keep iterating, + * looking for an empty slot in which to insert. + */ + JS_ASSERT(sprop != child); + JS_RUNTIME_METER(rt, duplicatePropTreeNodes); + } + } + chunkp = &chunk->next; + } while ((chunk = *chunkp) != NULL); + + chunk = NewPropTreeKidsChunk(rt); + if (!chunk) + return JS_FALSE; + *chunkp = chunk; + childp = &chunk->kids[0]; + } else { + sprop = kids; + JS_ASSERT(sprop != child); + if (SPROP_MATCH(sprop, child)) { + /* + * Duplicate child, see comment above. Once again, we + * must let duplicates created by deletion pile up in a + * kids-chunk-list, in order to find them when sweeping + * and thereby avoid dangling parent pointers. + */ + JS_RUNTIME_METER(rt, duplicatePropTreeNodes); + } + + chunk = NewPropTreeKidsChunk(rt); + if (!chunk) + return JS_FALSE; + parent->kids = CHUNK_TO_KIDS(chunk); + chunk->kids[0] = sprop; + childp = &chunk->kids[1]; + } + } + insert: + *childp = child; + } + + child->parent = parent; + return JS_TRUE; +} + +/* NB: Called with the runtime lock held. */ +static void +RemovePropertyTreeChild(JSRuntime *rt, JSScopeProperty *child) +{ + JSPropertyTreeEntry *entry; + JSScopeProperty *parent, *kids, *kid; + PropTreeKidsChunk *list, *chunk, **chunkp, *lastChunk; + uintN i, j; + + parent = child->parent; + if (!parent) { + /* + * Don't remove child if it is not in rt->propertyTreeHash, but only + * matches a root child in the table that has compatible members. See + * the "Duplicate child" comments in InsertPropertyTreeChild, above. + */ + entry = (JSPropertyTreeEntry *) + JS_DHashTableOperate(&rt->propertyTreeHash, child, JS_DHASH_LOOKUP); + + if (entry->child == child) + JS_DHashTableRawRemove(&rt->propertyTreeHash, &entry->hdr); + } else { + kids = parent->kids; + if (KIDS_IS_CHUNKY(kids)) { + list = chunk = KIDS_TO_CHUNK(kids); + chunkp = &list; + + do { + for (i = 0; i < MAX_KIDS_PER_CHUNK; i++) { + if (chunk->kids[i] == child) { + lastChunk = chunk; + if (!lastChunk->next) { + j = i + 1; + } else { + j = 0; + do { + chunkp = &lastChunk->next; + lastChunk = *chunkp; + } while (lastChunk->next); + } + for (; j < MAX_KIDS_PER_CHUNK; j++) { + if (!lastChunk->kids[j]) + break; + } + --j; + if (chunk != lastChunk || j > i) + chunk->kids[i] = lastChunk->kids[j]; + lastChunk->kids[j] = NULL; + if (j == 0) { + *chunkp = NULL; + if (!list) + parent->kids = NULL; + DestroyPropTreeKidsChunk(rt, lastChunk); + } + return; + } + } + + chunkp = &chunk->next; + } while ((chunk = *chunkp) != NULL); + } else { + kid = kids; + if (kid == child) + parent->kids = NULL; + } + } +} + +/* + * Called *without* the runtime lock held, this function acquires that lock + * only when inserting a new child. Thus there may be races to find or add + * a node that result in duplicates. We expect such races to be rare! + */ +static JSScopeProperty * +GetPropertyTreeChild(JSContext *cx, JSScopeProperty *parent, + JSScopeProperty *child) +{ + JSRuntime *rt; + JSPropertyTreeEntry *entry; + JSScopeProperty *sprop; + PropTreeKidsChunk *chunk; + uintN i; + + rt = cx->runtime; + if (!parent) { + JS_LOCK_RUNTIME(rt); + + entry = (JSPropertyTreeEntry *) + JS_DHashTableOperate(&rt->propertyTreeHash, child, JS_DHASH_ADD); + if (!entry) + goto out_of_memory; + + sprop = entry->child; + if (sprop) + goto out; + } else { + /* + * Because chunks are appended at the end and never deleted except by + * the GC, we can search without taking the runtime lock. We may miss + * a matching sprop added by another thread, and make a duplicate one, + * but that is an unlikely, therefore small, cost. The property tree + * has extremely low fan-out below its root in popular embeddings with + * real-world workloads. + * + * If workload changes so as to increase fan-out significantly below + * the property tree root, we'll want to add another tag bit stored in + * parent->kids that indicates a JSDHashTable pointer. + */ + entry = NULL; + sprop = parent->kids; + if (sprop) { + if (KIDS_IS_CHUNKY(sprop)) { + chunk = KIDS_TO_CHUNK(sprop); + do { + for (i = 0; i < MAX_KIDS_PER_CHUNK; i++) { + sprop = chunk->kids[i]; + if (!sprop) + goto not_found; + + if (SPROP_MATCH(sprop, child)) + return sprop; + } + } while ((chunk = chunk->next) != NULL); + } else { + if (SPROP_MATCH(sprop, child)) + return sprop; + } + } + + not_found: + JS_LOCK_RUNTIME(rt); + } + + sprop = NewScopeProperty(rt); + if (!sprop) + goto out_of_memory; + + sprop->id = child->id; + sprop->getter = child->getter; + sprop->setter = child->setter; + sprop->slot = child->slot; + sprop->attrs = child->attrs; + sprop->flags = child->flags; + sprop->shortid = child->shortid; + sprop->parent = sprop->kids = NULL; + if (!parent) { + entry->child = sprop; + } else { + if (!InsertPropertyTreeChild(rt, parent, sprop)) + goto out_of_memory; + } + +out: + JS_UNLOCK_RUNTIME(rt); + return sprop; + +out_of_memory: + JS_UNLOCK_RUNTIME(rt); + JS_ReportOutOfMemory(cx); + return NULL; +} + +#ifdef DEBUG_notbrendan +#define CHECK_ANCESTOR_LINE(scope, sparse) \ + JS_BEGIN_MACRO \ + if ((scope)->table) CheckAncestorLine(scope, sparse); \ + JS_END_MACRO + +static void +CheckAncestorLine(JSScope *scope, JSBool sparse) +{ + uint32 size; + JSScopeProperty **spp, **start, **end, *ancestorLine, *sprop, *aprop; + uint32 entryCount, ancestorCount; + + ancestorLine = SCOPE_LAST_PROP(scope); + if (ancestorLine) + JS_ASSERT(SCOPE_HAS_PROPERTY(scope, ancestorLine)); + + entryCount = 0; + size = SCOPE_CAPACITY(scope); + start = scope->table; + for (spp = start, end = start + size; spp < end; spp++) { + sprop = SPROP_FETCH(spp); + if (sprop) { + entryCount++; + for (aprop = ancestorLine; aprop; aprop = aprop->parent) { + if (aprop == sprop) + break; + } + JS_ASSERT(aprop); + } + } + JS_ASSERT(entryCount == scope->entryCount); + + ancestorCount = 0; + for (sprop = ancestorLine; sprop; sprop = sprop->parent) { + if (SCOPE_HAD_MIDDLE_DELETE(scope) && + !SCOPE_HAS_PROPERTY(scope, sprop)) { + JS_ASSERT(sparse || (sprop->flags & SPROP_IS_DUPLICATE)); + continue; + } + ancestorCount++; + } + JS_ASSERT(ancestorCount == scope->entryCount); +} +#else +#define CHECK_ANCESTOR_LINE(scope, sparse) /* nothing */ +#endif + +static void +ReportReadOnlyScope(JSContext *cx, JSScope *scope) +{ + JSString *str; + + str = js_ValueToString(cx, OBJECT_TO_JSVAL(scope->object)); + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_READ_ONLY, + str + ? JS_GetStringBytes(str) + : LOCKED_OBJ_GET_CLASS(scope->object)->name); +} + +JSScopeProperty * +js_AddScopeProperty(JSContext *cx, JSScope *scope, jsid id, + JSPropertyOp getter, JSPropertyOp setter, uint32 slot, + uintN attrs, uintN flags, intN shortid) +{ + JSScopeProperty **spp, *sprop, *overwriting, **spvec, **spp2, child; + uint32 size, splen, i; + int change; + + JS_ASSERT(JS_IS_SCOPE_LOCKED(cx, scope)); + CHECK_ANCESTOR_LINE(scope, JS_TRUE); + + /* + * You can't add properties to a sealed scope. But note well that you can + * change property attributes in a sealed scope, even though that replaces + * a JSScopeProperty * in the scope's hash table -- but no id is added, so + * the scope remains sealed. + */ + if (SCOPE_IS_SEALED(scope)) { + ReportReadOnlyScope(cx, scope); + return NULL; + } + + /* + * Normalize stub getter and setter values for faster is-stub testing in + * the SPROP_CALL_[GS]ETTER macros. + */ + if (getter == JS_PropertyStub) + getter = NULL; + if (setter == JS_PropertyStub) + setter = NULL; + + /* + * Search for id in order to claim its entry, allocating a property tree + * node if one doesn't already exist for our parameters. + */ + spp = js_SearchScope(scope, id, JS_TRUE); + sprop = overwriting = SPROP_FETCH(spp); + if (!sprop) { + /* Check whether we need to grow, if the load factor is >= .75. */ + size = SCOPE_CAPACITY(scope); + if (scope->entryCount + scope->removedCount >= size - (size >> 2)) { + if (scope->removedCount >= size >> 2) { + METER(compresses); + change = 0; + } else { + METER(grows); + change = 1; + } + if (!ChangeScope(cx, scope, change) && + scope->entryCount + scope->removedCount == size - 1) { + METER(addFailures); + return NULL; + } + spp = js_SearchScope(scope, id, JS_TRUE); + JS_ASSERT(!SPROP_FETCH(spp)); + } + } else { + /* Property exists: js_SearchScope must have returned a valid entry. */ + JS_ASSERT(!SPROP_IS_REMOVED(*spp)); + + /* + * If all property members match, this is a redundant add and we can + * return early. If the caller wants to allocate a slot, but doesn't + * care which slot, copy sprop->slot into slot so we can match sprop, + * if all other members match. + */ + if (!(attrs & JSPROP_SHARED) && + slot == SPROP_INVALID_SLOT && + SPROP_HAS_VALID_SLOT(sprop, scope)) { + slot = sprop->slot; + } + if (SPROP_MATCH_PARAMS_AFTER_ID(sprop, getter, setter, slot, attrs, + flags, shortid)) { + METER(redundantAdds); + return sprop; + } + + /* + * Duplicate formal parameters require us to leave the old property + * on the ancestor line, so the decompiler can find it, even though + * its entry in scope->table is overwritten to point at a new property + * descending from the old one. The SPROP_IS_DUPLICATE flag helps us + * cope with the consequent disparity between ancestor line height and + * scope->entryCount. + */ + if (flags & SPROP_IS_DUPLICATE) { + sprop->flags |= SPROP_IS_DUPLICATE; + } else { + /* + * If we are clearing sprop to force an existing property to be + * overwritten (apart from a duplicate formal parameter), we must + * unlink it from the ancestor line at scope->lastProp, lazily if + * sprop is not lastProp. And we must remove the entry at *spp, + * precisely so the lazy "middle delete" fixup code further below + * won't find sprop in scope->table, in spite of sprop being on + * the ancestor line. + * + * When we finally succeed in finding or creating a new sprop + * and storing its pointer at *spp, we'll use the |overwriting| + * local saved when we first looked up id to decide whether we're + * indeed creating a new entry, or merely overwriting an existing + * property. + */ + if (sprop == SCOPE_LAST_PROP(scope)) { + do { + SCOPE_REMOVE_LAST_PROP(scope); + if (!SCOPE_HAD_MIDDLE_DELETE(scope)) + break; + sprop = SCOPE_LAST_PROP(scope); + } while (sprop && !SCOPE_HAS_PROPERTY(scope, sprop)); + } else if (!SCOPE_HAD_MIDDLE_DELETE(scope)) { + /* + * If we have no hash table yet, we need one now. The middle + * delete code is simple-minded that way! + */ + if (!scope->table) { + if (!CreateScopeTable(scope)) { + JS_ReportOutOfMemory(cx); + return NULL; + } + spp = js_SearchScope(scope, id, JS_TRUE); + sprop = overwriting = SPROP_FETCH(spp); + } + SCOPE_SET_MIDDLE_DELETE(scope); + } + } + + /* + * If we fail later on trying to find or create a new sprop, we will + * goto fail_overwrite and restore *spp from |overwriting|. Note that + * we don't bother to keep scope->removedCount in sync, because we'll + * fix up *spp and scope->entryCount shortly, no matter how control + * flow returns from this function. + */ + if (scope->table) + SPROP_STORE_PRESERVING_COLLISION(spp, NULL); + scope->entryCount--; + CHECK_ANCESTOR_LINE(scope, JS_TRUE); + sprop = NULL; + } + + if (!sprop) { + /* + * If properties were deleted from the middle of the list starting at + * scope->lastProp, we may need to fork the property tree and squeeze + * all deleted properties out of scope's ancestor line. Otherwise we + * risk adding a node with the same id as a "middle" node, violating + * the rule that properties along an ancestor line have distinct ids + * (unless flagged SPROP_IS_DUPLICATE). + */ + if (SCOPE_HAD_MIDDLE_DELETE(scope)) { + JS_ASSERT(scope->table); + CHECK_ANCESTOR_LINE(scope, JS_TRUE); + + splen = scope->entryCount; + if (splen == 0) { + JS_ASSERT(scope->lastProp == NULL); + } else { + /* + * Enumerate live entries in scope->table using a temporary + * vector, by walking the (possibly sparse, due to deletions) + * ancestor line from scope->lastProp. + */ + spvec = (JSScopeProperty **) + JS_malloc(cx, SCOPE_TABLE_NBYTES(splen)); + if (!spvec) + goto fail_overwrite; + i = splen; + sprop = SCOPE_LAST_PROP(scope); + JS_ASSERT(sprop); + do { + /* + * NB: test SCOPE_GET_PROPERTY, not SCOPE_HAS_PROPERTY -- + * the latter insists that sprop->id maps to sprop, while + * the former simply tests whether sprop->id is bound in + * scope. We must allow for duplicate formal parameters + * along the ancestor line, and fork them as needed. + */ + if (!SCOPE_GET_PROPERTY(scope, sprop->id)) + continue; + + JS_ASSERT(sprop != overwriting); + if (i == 0) { + /* + * If our original splen estimate, scope->entryCount, + * is less than the ancestor line height, there must + * be duplicate formal parameters in this (function + * object) scope. Count remaining ancestors in order + * to realloc spvec. + */ + JSScopeProperty *tmp = sprop; + do { + if (SCOPE_GET_PROPERTY(scope, tmp->id)) + i++; + } while ((tmp = tmp->parent) != NULL); + spp2 = (JSScopeProperty **) + JS_realloc(cx, spvec, SCOPE_TABLE_NBYTES(splen+i)); + if (!spp2) { + JS_free(cx, spvec); + goto fail_overwrite; + } + + spvec = spp2; + memmove(spvec + i, spvec, SCOPE_TABLE_NBYTES(splen)); + splen += i; + } + + spvec[--i] = sprop; + } while ((sprop = sprop->parent) != NULL); + JS_ASSERT(i == 0); + + /* + * Now loop forward through spvec, forking the property tree + * whenever we see a "parent gap" due to deletions from scope. + * NB: sprop is null on first entry to the loop body. + */ + do { + if (spvec[i]->parent == sprop) { + sprop = spvec[i]; + } else { + sprop = GetPropertyTreeChild(cx, sprop, spvec[i]); + if (!sprop) { + JS_free(cx, spvec); + goto fail_overwrite; + } + + spp2 = js_SearchScope(scope, sprop->id, JS_FALSE); + JS_ASSERT(SPROP_FETCH(spp2) == spvec[i]); + SPROP_STORE_PRESERVING_COLLISION(spp2, sprop); + } + } while (++i < splen); + JS_free(cx, spvec); + + /* + * Now sprop points to the last property in scope, where the + * ancestor line from sprop to the root is dense w.r.t. scope: + * it contains no nodes not mapped by scope->table, apart from + * any stinking ECMA-mandated duplicate formal parameters. + */ + scope->lastProp = sprop; + CHECK_ANCESTOR_LINE(scope, JS_FALSE); + JS_RUNTIME_METER(cx->runtime, middleDeleteFixups); + } + + SCOPE_CLR_MIDDLE_DELETE(scope); + } + + /* + * Aliases share another property's slot, passed in the |slot| param. + * Shared properties have no slot. Unshared properties that do not + * alias another property's slot get one here, but may lose it due to + * a JS_ClearScope call. + */ + if (!(flags & SPROP_IS_ALIAS)) { + if (attrs & JSPROP_SHARED) { + slot = SPROP_INVALID_SLOT; + } else { + /* + * We may have set slot from a nearly-matching sprop, above. + * If so, we're overwriting that nearly-matching sprop, so we + * can reuse its slot -- we don't need to allocate a new one. + * Callers should therefore pass SPROP_INVALID_SLOT for all + * non-alias, unshared property adds. + */ + if (slot != SPROP_INVALID_SLOT) + JS_ASSERT(overwriting); + else if (!js_AllocSlot(cx, scope->object, &slot)) + goto fail_overwrite; + } + } + + /* + * Check for a watchpoint on a deleted property; if one exists, change + * setter to js_watch_set. + * XXXbe this could get expensive with lots of watchpoints... + */ + if (!JS_CLIST_IS_EMPTY(&cx->runtime->watchPointList) && + js_FindWatchPoint(cx->runtime, scope, id)) { + setter = js_WrapWatchedSetter(cx, id, attrs, setter); + if (!setter) + goto fail_overwrite; + } + + /* Find or create a property tree node labeled by our arguments. */ + child.id = id; + child.getter = getter; + child.setter = setter; + child.slot = slot; + child.attrs = attrs; + child.flags = flags; + child.shortid = shortid; + sprop = GetPropertyTreeChild(cx, scope->lastProp, &child); + if (!sprop) + goto fail_overwrite; + + /* Store the tree node pointer in the table entry for id. */ + if (scope->table) + SPROP_STORE_PRESERVING_COLLISION(spp, sprop); + scope->entryCount++; + scope->lastProp = sprop; + CHECK_ANCESTOR_LINE(scope, JS_FALSE); + if (!overwriting) { + JS_RUNTIME_METER(cx->runtime, liveScopeProps); + JS_RUNTIME_METER(cx->runtime, totalScopeProps); + } + + /* + * If we reach the hashing threshold, try to allocate scope->table. + * If we can't (a rare event, preceded by swapping to death on most + * modern OSes), stick with linear search rather than whining about + * this little set-back. Therefore we must test !scope->table and + * scope->entryCount >= SCOPE_HASH_THRESHOLD, not merely whether the + * entry count just reached the threshold. + */ + if (!scope->table && scope->entryCount >= SCOPE_HASH_THRESHOLD) + (void) CreateScopeTable(scope); + } + + METER(adds); + return sprop; + +fail_overwrite: + if (overwriting) { + /* + * We may or may not have forked overwriting out of scope's ancestor + * line, so we must check (the alternative is to set a flag above, but + * that hurts the common, non-error case). If we did fork overwriting + * out, we'll add it back at scope->lastProp. This means enumeration + * order can change due to a failure to overwrite an id. + * XXXbe very minor incompatibility + */ + for (sprop = SCOPE_LAST_PROP(scope); ; sprop = sprop->parent) { + if (!sprop) { + sprop = SCOPE_LAST_PROP(scope); + if (overwriting->parent == sprop) { + scope->lastProp = overwriting; + } else { + sprop = GetPropertyTreeChild(cx, sprop, overwriting); + if (sprop) { + JS_ASSERT(sprop != overwriting); + scope->lastProp = sprop; + } + overwriting = sprop; + } + break; + } + if (sprop == overwriting) + break; + } + if (overwriting) { + if (scope->table) + SPROP_STORE_PRESERVING_COLLISION(spp, overwriting); + scope->entryCount++; + } + CHECK_ANCESTOR_LINE(scope, JS_TRUE); + } + METER(addFailures); + return NULL; +} + +JSScopeProperty * +js_ChangeScopePropertyAttrs(JSContext *cx, JSScope *scope, + JSScopeProperty *sprop, uintN attrs, uintN mask, + JSPropertyOp getter, JSPropertyOp setter) +{ + JSScopeProperty child, *newsprop, **spp; + + CHECK_ANCESTOR_LINE(scope, JS_TRUE); + + /* Allow only shared (slot-less) => unshared (slot-full) transition. */ + attrs |= sprop->attrs & mask; + JS_ASSERT(!((attrs ^ sprop->attrs) & JSPROP_SHARED) || + !(attrs & JSPROP_SHARED)); + if (getter == JS_PropertyStub) + getter = NULL; + if (setter == JS_PropertyStub) + setter = NULL; + if (sprop->attrs == attrs && + sprop->getter == getter && + sprop->setter == setter) { + return sprop; + } + + child.id = sprop->id; + child.getter = getter; + child.setter = setter; + child.slot = sprop->slot; + child.attrs = attrs; + child.flags = sprop->flags; + child.shortid = sprop->shortid; + + if (SCOPE_LAST_PROP(scope) == sprop) { + /* + * Optimize the case where the last property added to scope is changed + * to have a different attrs, getter, or setter. In the last property + * case, we need not fork the property tree. But since we do not call + * js_AddScopeProperty, we may need to allocate a new slot directly. + */ + if ((sprop->attrs & JSPROP_SHARED) && !(attrs & JSPROP_SHARED)) { + JS_ASSERT(child.slot == SPROP_INVALID_SLOT); + if (!js_AllocSlot(cx, scope->object, &child.slot)) + return NULL; + } + + newsprop = GetPropertyTreeChild(cx, sprop->parent, &child); + if (newsprop) { + spp = js_SearchScope(scope, sprop->id, JS_FALSE); + JS_ASSERT(SPROP_FETCH(spp) == sprop); + + if (scope->table) + SPROP_STORE_PRESERVING_COLLISION(spp, newsprop); + scope->lastProp = newsprop; + CHECK_ANCESTOR_LINE(scope, JS_TRUE); + } + } else { + /* + * Let js_AddScopeProperty handle this |overwriting| case, including + * the conservation of sprop->slot (if it's valid). We must not call + * js_RemoveScopeProperty here, it will free a valid sprop->slot and + * js_AddScopeProperty won't re-allocate it. + */ + newsprop = js_AddScopeProperty(cx, scope, child.id, + child.getter, child.setter, child.slot, + child.attrs, child.flags, child.shortid); + } + +#ifdef DEBUG_brendan + if (!newsprop) + METER(changeFailures); +#endif + return newsprop; +} + +JSBool +js_RemoveScopeProperty(JSContext *cx, JSScope *scope, jsid id) +{ + JSScopeProperty **spp, *stored, *sprop; + uint32 size; + + JS_ASSERT(JS_IS_SCOPE_LOCKED(cx, scope)); + CHECK_ANCESTOR_LINE(scope, JS_TRUE); + if (SCOPE_IS_SEALED(scope)) { + ReportReadOnlyScope(cx, scope); + return JS_FALSE; + } + METER(removes); + + spp = js_SearchScope(scope, id, JS_FALSE); + stored = *spp; + sprop = SPROP_CLEAR_COLLISION(stored); + if (!sprop) { + METER(uselessRemoves); + return JS_TRUE; + } + + /* Convert from a list to a hash so we can handle "middle deletes". */ + if (!scope->table && sprop != scope->lastProp) { + if (!CreateScopeTable(scope)) { + JS_ReportOutOfMemory(cx); + return JS_FALSE; + } + spp = js_SearchScope(scope, id, JS_FALSE); + stored = *spp; + sprop = SPROP_CLEAR_COLLISION(stored); + } + + /* First, if sprop is unshared and not cleared, free its slot number. */ + if (SPROP_HAS_VALID_SLOT(sprop, scope)) + js_FreeSlot(cx, scope->object, sprop->slot); + + /* Next, remove id by setting its entry to a removed or free sentinel. */ + if (SPROP_HAD_COLLISION(stored)) { + JS_ASSERT(scope->table); + *spp = SPROP_REMOVED; + scope->removedCount++; + } else { + METER(removeFrees); + if (scope->table) + *spp = NULL; + } + scope->entryCount--; + JS_RUNTIME_UNMETER(cx->runtime, liveScopeProps); + + /* Update scope->lastProp directly, or set its deferred update flag. */ + if (sprop == SCOPE_LAST_PROP(scope)) { + do { + SCOPE_REMOVE_LAST_PROP(scope); + if (!SCOPE_HAD_MIDDLE_DELETE(scope)) + break; + sprop = SCOPE_LAST_PROP(scope); + } while (sprop && !SCOPE_HAS_PROPERTY(scope, sprop)); + } else if (!SCOPE_HAD_MIDDLE_DELETE(scope)) { + SCOPE_SET_MIDDLE_DELETE(scope); + } + CHECK_ANCESTOR_LINE(scope, JS_TRUE); + + /* Last, consider shrinking scope's table if its load factor is <= .25. */ + size = SCOPE_CAPACITY(scope); + if (size > MIN_SCOPE_SIZE && scope->entryCount <= size >> 2) { + METER(shrinks); + (void) ChangeScope(cx, scope, -1); + } + + return JS_TRUE; +} + +void +js_ClearScope(JSContext *cx, JSScope *scope) +{ + CHECK_ANCESTOR_LINE(scope, JS_TRUE); +#ifdef DEBUG + JS_LOCK_RUNTIME_VOID(cx->runtime, + cx->runtime->liveScopeProps -= scope->entryCount); +#endif + + if (scope->table) + free(scope->table); + SCOPE_CLR_MIDDLE_DELETE(scope); + InitMinimalScope(scope); +} + +#ifdef DEBUG_brendan + +#include +#include + +uint32 js_nkids_max; +uint32 js_nkids_sum; +double js_nkids_sqsum; +uint32 js_nkids_hist[11]; + +static void +MeterKidCount(uintN nkids) +{ + if (nkids) { + js_nkids_sum += nkids; + js_nkids_sqsum += (double)nkids * nkids; + if (nkids > js_nkids_max) + js_nkids_max = nkids; + } + js_nkids_hist[JS_MIN(nkids, 10)]++; +} + +static void +MeterPropertyTree(JSScopeProperty *node) +{ + uintN i, nkids; + JSScopeProperty *kids, *kid; + PropTreeKidsChunk *chunk; + + nkids = 0; + kids = node->kids; + if (kids) { + if (KIDS_IS_CHUNKY(kids)) { + for (chunk = KIDS_TO_CHUNK(kids); chunk; chunk = chunk->next) { + for (i = 0; i < MAX_KIDS_PER_CHUNK; i++) { + kid = chunk->kids[i]; + if (!kid) + break; + MeterPropertyTree(kid); + nkids++; + } + } + } else { + MeterPropertyTree(kids); + nkids = 1; + } + } + + MeterKidCount(nkids); +} + +JS_STATIC_DLL_CALLBACK(JSDHashOperator) +js_MeterPropertyTree(JSDHashTable *table, JSDHashEntryHdr *hdr, uint32 number, + void *arg) +{ + JSPropertyTreeEntry *entry = (JSPropertyTreeEntry *)hdr; + + MeterPropertyTree(entry->child); + return JS_DHASH_NEXT; +} + +#endif /* DEBUG_brendan */ + +void +js_SweepScopeProperties(JSRuntime *rt) +{ + JSArena **ap, *a; + JSScopeProperty *limit, *sprop, *parent, *kids, *kid; + uintN liveCount; + PropTreeKidsChunk *chunk, *nextChunk; + uintN i; + +#ifdef DEBUG_brendan + uint32 livePropCapacity = 0, totalLiveCount = 0; + static FILE *logfp; + if (!logfp) + logfp = fopen("/tmp/proptree.stats", "a"); + + MeterKidCount(rt->propertyTreeHash.entryCount); + JS_DHashTableEnumerate(&rt->propertyTreeHash, js_MeterPropertyTree, NULL); + + { + double mean = 0., var = 0., sigma = 0.; + double nodesum = rt->livePropTreeNodes; + double kidsum = js_nkids_sum; + if (nodesum > 0 && kidsum >= 0) { + mean = kidsum / nodesum; + var = nodesum * js_nkids_sqsum - kidsum * kidsum; + if (var < 0.0 || nodesum <= 1) + var = 0.0; + else + var /= nodesum * (nodesum - 1); + + /* Windows says sqrt(0.0) is "-1.#J" (?!) so we must test. */ + sigma = (var != 0.) ? sqrt(var) : 0.; + } + + fprintf(logfp, + "props %u nodes %g beta %g meankids %g sigma %g max %u", + rt->liveScopeProps, nodesum, nodesum / rt->liveScopeProps, + mean, sigma, js_nkids_max); + } + + fprintf(logfp, " histogram %u %u %u %u %u %u %u %u %u %u %u", + js_nkids_hist[0], js_nkids_hist[1], + js_nkids_hist[2], js_nkids_hist[3], + js_nkids_hist[4], js_nkids_hist[5], + js_nkids_hist[6], js_nkids_hist[7], + js_nkids_hist[8], js_nkids_hist[9], + js_nkids_hist[10]); + js_nkids_sum = js_nkids_max = 0; + js_nkids_sqsum = 0; + memset(js_nkids_hist, 0, sizeof js_nkids_hist); +#endif + + ap = &rt->propertyArenaPool.first.next; + while ((a = *ap) != NULL) { + limit = (JSScopeProperty *) a->avail; + liveCount = 0; + for (sprop = (JSScopeProperty *) a->base; sprop < limit; sprop++) { + /* If the id is null, sprop is already on the freelist. */ + if (sprop->id == JSVAL_NULL) + continue; + + /* If the mark bit is set, sprop is alive, so we skip it. */ + if (sprop->flags & SPROP_MARK) { + sprop->flags &= ~SPROP_MARK; + liveCount++; + continue; + } + + /* Ok, sprop is garbage to collect: unlink it from its parent. */ + RemovePropertyTreeChild(rt, sprop); + + /* Take care to reparent all sprop's kids to their grandparent. */ + kids = sprop->kids; + if (kids) { + sprop->kids = NULL; + parent = sprop->parent; + if (KIDS_IS_CHUNKY(kids)) { + chunk = KIDS_TO_CHUNK(kids); + do { + for (i = 0; i < MAX_KIDS_PER_CHUNK; i++) { + kid = chunk->kids[i]; + if (!kid) + break; + JS_ASSERT(kid->parent == sprop); + InsertPropertyTreeChild(rt, parent, kid); + } + nextChunk = chunk->next; + DestroyPropTreeKidsChunk(rt, chunk); + } while ((chunk = nextChunk) != NULL); + } else { + kid = kids; + InsertPropertyTreeChild(rt, parent, kid); + } + } + + /* Clear id so we know (above) that sprop is on the freelist. */ + sprop->id = JSVAL_NULL; + FREENODE_INSERT(rt->propertyFreeList, sprop); + JS_RUNTIME_UNMETER(rt, livePropTreeNodes); + } + + /* If a contains no live properties, return it to the malloc heap. */ + if (liveCount == 0) { + for (sprop = (JSScopeProperty *) a->base; sprop < limit; sprop++) + FREENODE_REMOVE(sprop); + JS_ARENA_DESTROY(&rt->propertyArenaPool, a, ap); + } else { +#ifdef DEBUG_brendan + livePropCapacity += limit - (JSScopeProperty *) a->base; + totalLiveCount += liveCount; +#endif + ap = &a->next; + } + } + +#ifdef DEBUG_brendan + fprintf(logfp, " arenautil %g%%\n", + (totalLiveCount * 100.) / livePropCapacity); + fflush(logfp); +#endif +} + +JSBool +js_InitPropertyTree(JSRuntime *rt) +{ + if (!JS_DHashTableInit(&rt->propertyTreeHash, &PropertyTreeHashOps, NULL, + sizeof(JSPropertyTreeEntry), JS_DHASH_MIN_SIZE)) { + rt->propertyTreeHash.ops = NULL; + return JS_FALSE; + } + JS_InitArenaPool(&rt->propertyArenaPool, "properties", + 256 * sizeof(JSScopeProperty), sizeof(void *)); + return JS_TRUE; +} + +void +js_FinishPropertyTree(JSRuntime *rt) +{ + if (rt->propertyTreeHash.ops) { + JS_DHashTableFinish(&rt->propertyTreeHash); + rt->propertyTreeHash.ops = NULL; + } + JS_FinishArenaPool(&rt->propertyArenaPool); +} diff --git a/src/dom/js/jsscope.h b/src/dom/js/jsscope.h new file mode 100644 index 000000000..4f66441b4 --- /dev/null +++ b/src/dom/js/jsscope.h @@ -0,0 +1,386 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef jsscope_h___ +#define jsscope_h___ +/* + * JS symbol tables. + */ +#include "jstypes.h" +#include "jsobj.h" +#include "jsprvtd.h" +#include "jspubtd.h" + +#ifdef JS_THREADSAFE +# include "jslock.h" +#endif + +/* + * Given P independent, non-unique properties each of size S words mapped by + * all scopes in a runtime, construct a property tree of N nodes each of size + * S+L words (L for tree linkage). A nominal L value is 2 for leftmost-child + * and right-sibling links. We hope that the N < P by enough that the space + * overhead of L, and the overhead of scope entries pointing at property tree + * nodes, is worth it. + * + * The tree construction goes as follows. If any empty scope in the runtime + * has a property X added to it, find or create a node under the tree root + * labeled X, and set scope->lastProp to point at that node. If any non-empty + * scope whose most recently added property is labeled Y has another property + * labeled Z added, find or create a node for Z under the node that was added + * for Y, and set scope->lastProp to point at that node. + * + * A property is labeled by its members' values: id, getter, setter, slot, + * attributes, tiny or short id, and a field telling for..in order. Note that + * labels are not unique in the tree, but they are unique among a node's kids + * (barring rare and benign multi-threaded race condition outcomes, see below) + * and along any ancestor line from the tree root to a given leaf node (except + * for the hard case of duplicate formal parameters to a function). + * + * Thus the root of the tree represents all empty scopes, and the first ply + * of the tree represents all scopes containing one property, etc. Each node + * in the tree can stand for any number of scopes having the same ordered set + * of properties, where that node was the last added to the scope. (We need + * not store the root of the tree as a node, and do not -- all we need are + * links to its kids.) + * + * Sidebar on for..in loop order: ECMA requires no particular order, but this + * implementation has promised and delivered property definition order, and + * compatibility is king. We could use an order number per property, which + * would require a sort in js_Enumerate, and an entry order generation number + * per scope. An order number beats a list, which should be doubly-linked for + * O(1) delete. An even better scheme is to use a parent link in the property + * tree, so that the ancestor line can be iterated from scope->lastProp when + * filling in a JSIdArray from back to front. This parent link also helps the + * GC to sweep properties iteratively. + * + * What if a property Y is deleted from a scope? If Y is the last property in + * the scope, we simply adjust the scope's lastProp member after we remove the + * scope's hash-table entry pointing at that property node. The parent link + * mentioned in the for..in sidebar above makes this adjustment O(1). But if + * Y comes between X and Z in the scope, then we might have to "fork" the tree + * at X, leaving X->Y->Z in case other scopes have those properties added in + * that order; and to finish the fork, we'd add a node labeled Z with the path + * X->Z, if it doesn't exist. This could lead to lots of extra nodes, and to + * O(n^2) growth when deleting lots of properties. + * + * Rather, for O(1) growth all around, we should share the path X->Y->Z among + * scopes having those three properties added in that order, and among scopes + * having only X->Z where Y was deleted. All such scopes have a lastProp that + * points to the Z child of Y. But a scope in which Y was deleted does not + * have a table entry for Y, and when iterating that scope by traversing the + * ancestor line from Z, we will have to test for a table entry for each node, + * skipping nodes that lack entries. + * + * What if we add Y again? X->Y->Z->Y is wrong and we'll enumerate Y twice. + * Therefore we must fork in such a case, if not earlier. Because delete is + * "bursty", we should not fork eagerly. Delaying a fork till we are at risk + * of adding Y after it was deleted already requires a flag in the JSScope, to + * wit, SCOPE_MIDDLE_DELETE. + * + * What about thread safety? If the property tree operations done by requests + * are find-node and insert-node, then the only hazard is duplicate insertion. + * This is harmless except for minor bloat. When all requests have ended or + * been suspended, the GC is free to sweep the tree after marking all nodes + * reachable from scopes, performing remove-node operations as needed. Note + * also that the stable storage of the property nodes during active requests + * permits the property cache (see jsinterp.h) to dereference JSScopeProperty + * weak references safely. + * + * Is the property tree worth it compared to property storage in each table's + * entries? To decide, we must find the relation <> between the words used + * with a property tree and the words required without a tree. + * + * Model all scopes as one super-scope of capacity T entries (T a power of 2). + * Let alpha be the load factor of this double hash-table. With the property + * tree, each entry in the table is a word-sized pointer to a node that can be + * shared by many scopes. But all such pointers are overhead compared to the + * situation without the property tree, where the table stores property nodes + * directly, as entries each of size S words. With the property tree, we need + * L=2 extra words per node for siblings and kids pointers. Without the tree, + * (1-alpha)*S*T words are wasted on free or removed sentinel-entries required + * by double hashing. + * + * Therefore, + * + * (property tree) <> (no property tree) + * N*(S+L) + T <> S*T + * N*(S+L) + T <> P*S + (1-alpha)*S*T + * N*(S+L) + alpha*T + (1-alpha)*T <> P*S + (1-alpha)*S*T + * + * Note that P is alpha*T by definition, so + * + * N*(S+L) + P + (1-alpha)*T <> P*S + (1-alpha)*S*T + * N*(S+L) <> P*S - P + (1-alpha)*S*T - (1-alpha)*T + * N*(S+L) <> (P + (1-alpha)*T) * (S-1) + * N*(S+L) <> (P + (1-alpha)*P/alpha) * (S-1) + * N*(S+L) <> P * (1/alpha) * (S-1) + * + * Let N = P*beta for a compression ratio beta, beta <= 1: + * + * P*beta*(S+L) <> P * (1/alpha) * (S-1) + * beta*(S+L) <> (S-1)/alpha + * beta <> (S-1)/((S+L)*alpha) + * + * For S = 6 (32-bit architectures) and L = 2, the property tree wins iff + * + * beta < 5/(8*alpha) + * + * We ensure that alpha <= .75, so the property tree wins if beta < .83_. An + * average beta from recent Mozilla browser startups was around .6. + * + * Can we reduce L? Observe that the property tree degenerates into a list of + * lists if at most one property Y follows X in all scopes. In or near such a + * case, we waste a word on the right-sibling link outside of the root ply of + * the tree. Note also that the root ply tends to be large, so O(n^2) growth + * searching it is likely, indicating the need for hashing (but with increased + * thread safety costs). + * + * If only K out of N nodes in the property tree have more than one child, we + * could eliminate the sibling link and overlay a children list or hash-table + * pointer on the leftmost-child link (which would then be either null or an + * only-child link; the overlay could be tagged in the low bit of the pointer, + * or flagged elsewhere in the property tree node, although such a flag must + * not be considered when comparing node labels during tree search). + * + * For such a system, L = 1 + (K * averageChildrenTableSize) / N instead of 2. + * If K << N, L approaches 1 and the property tree wins if beta < .95. + * + * We observe that fan-out below the root ply of the property tree appears to + * have extremely low degree (see the MeterPropertyTree code that histograms + * child-counts in jsscope.c), so instead of a hash-table we use a linked list + * of child node pointer arrays ("kid chunks"). The details are isolated in + * jsscope.c; others must treat JSScopeProperty.kids as opaque. We leave it + * strongly typed for debug-ability of the common (null or one-kid) cases. + * + * One final twist (can you stand it?): the mean number of entries per scope + * in Mozilla is < 5, with a large standard deviation (~8). Instead of always + * allocating scope->table, we leave it null while initializing all the other + * scope members as if it were non-null and minimal-length. Until a property + * is added that crosses the threshold of 6 or more entries for hashing, or + * until a "middle delete" occurs, we use linear search from scope->lastProp + * to find a given id, and save on the space overhead of a hash table. + */ + +struct JSScope { + JSObjectMap map; /* base class state */ + JSObject *object; /* object that owns this scope */ + uint16 flags; /* flags, see below */ + int16 hashShift; /* multiplicative hash shift */ + uint32 entryCount; /* number of entries in table */ + uint32 removedCount; /* removed entry sentinels in table */ + JSScopeProperty **table; /* table of ptrs to shared tree nodes */ + JSScopeProperty *lastProp; /* pointer to last property added */ +#ifdef JS_THREADSAFE + JSContext *ownercx; /* creating context, NULL if shared */ + JSThinLock lock; /* binary semaphore protecting scope */ + union { /* union lockful and lock-free state: */ + jsrefcount count; /* lock entry count for reentrancy */ + JSScope *link; /* next link in rt->scopeSharingTodo */ + } u; +#ifdef DEBUG + const char *file[4]; /* file where lock was (re-)taken */ + unsigned int line[4]; /* line where lock was (re-)taken */ +#endif +#endif +}; + +#define OBJ_SCOPE(obj) ((JSScope *)(obj)->map) + +/* By definition, hashShift = JS_DHASH_BITS - log2(capacity). */ +#define SCOPE_CAPACITY(scope) JS_BIT(JS_DHASH_BITS-(scope)->hashShift) + +/* Scope flags and some macros to hide them from other files than jsscope.c. */ +#define SCOPE_MIDDLE_DELETE 0x0001 +#define SCOPE_SEALED 0x0002 + +#define SCOPE_HAD_MIDDLE_DELETE(scope) ((scope)->flags & SCOPE_MIDDLE_DELETE) +#define SCOPE_SET_MIDDLE_DELETE(scope) ((scope)->flags |= SCOPE_MIDDLE_DELETE) +#define SCOPE_CLR_MIDDLE_DELETE(scope) ((scope)->flags &= ~SCOPE_MIDDLE_DELETE) + +#define SCOPE_IS_SEALED(scope) ((scope)->flags & SCOPE_SEALED) +#define SCOPE_SET_SEALED(scope) ((scope)->flags |= SCOPE_SEALED) +#if 0 +/* + * Don't define this, it can't be done safely because JS_LOCK_OBJ will avoid + * taking the lock if the object owns its scope and the scope is sealed. + */ +#define SCOPE_CLR_SEALED(scope) ((scope)->flags &= ~SCOPE_SEALED) +#endif + +/* + * A little information hiding for scope->lastProp, in case it ever becomes + * a tagged pointer again. + */ +#define SCOPE_LAST_PROP(scope) ((scope)->lastProp) +#define SCOPE_REMOVE_LAST_PROP(scope) ((scope)->lastProp = \ + (scope)->lastProp->parent) + +struct JSScopeProperty { + jsid id; /* int-tagged jsval/untagged JSAtom* */ + JSPropertyOp getter; /* getter and setter hooks or objects */ + JSPropertyOp setter; + uint32 slot; /* index in obj->slots vector */ + uint8 attrs; /* attributes, see jsapi.h JSPROP_* */ + uint8 flags; /* flags, see below for defines */ + int16 shortid; /* tinyid, or local arg/var index */ + JSScopeProperty *parent; /* parent node, reverse for..in order */ + JSScopeProperty *kids; /* null, single child, or a tagged ptr + to many-kids data structure */ +}; + +/* JSScopeProperty pointer tag bit indicating a collision. */ +#define SPROP_COLLISION ((jsuword)1) +#define SPROP_REMOVED ((JSScopeProperty *) SPROP_COLLISION) + +/* Macros to get and set sprop pointer values and collision flags. */ +#define SPROP_IS_FREE(sprop) ((sprop) == NULL) +#define SPROP_IS_REMOVED(sprop) ((sprop) == SPROP_REMOVED) +#define SPROP_IS_LIVE(sprop) ((sprop) > SPROP_REMOVED) +#define SPROP_FLAG_COLLISION(spp,sprop) (*(spp) = (JSScopeProperty *) \ + ((jsuword)(sprop) | SPROP_COLLISION)) +#define SPROP_HAD_COLLISION(sprop) ((jsuword)(sprop) & SPROP_COLLISION) +#define SPROP_FETCH(spp) SPROP_CLEAR_COLLISION(*(spp)) + +#define SPROP_CLEAR_COLLISION(sprop) \ + ((JSScopeProperty *) ((jsuword)(sprop) & ~SPROP_COLLISION)) + +#define SPROP_STORE_PRESERVING_COLLISION(spp, sprop) \ + (*(spp) = (JSScopeProperty *) ((jsuword)(sprop) \ + | SPROP_HAD_COLLISION(*(spp)))) + +/* Bits stored in sprop->flags. */ +#define SPROP_MARK 0x01 +#define SPROP_IS_DUPLICATE 0x02 +#define SPROP_IS_ALIAS 0x04 +#define SPROP_HAS_SHORTID 0x08 + +/* + * If SPROP_HAS_SHORTID is set in sprop->flags, we use sprop->shortid rather + * than id when calling sprop's getter or setter. + */ +#define SPROP_USERID(sprop) \ + (((sprop)->flags & SPROP_HAS_SHORTID) ? INT_TO_JSVAL((sprop)->shortid) \ + : ID_TO_VALUE((sprop)->id)) + +#define SPROP_INVALID_SLOT 0xffffffff + +#define SPROP_HAS_VALID_SLOT(sprop, scope) \ + ((sprop)->slot < (scope)->map.freeslot) + +#define SPROP_CALL_GETTER(cx,sprop,getter,obj,obj2,vp) \ + (!(getter) || \ + (getter)(cx, OBJ_THIS_OBJECT(cx,obj), SPROP_USERID(sprop), vp)) +#define SPROP_CALL_SETTER(cx,sprop,setter,obj,obj2,vp) \ + (!(setter) || \ + (setter)(cx, OBJ_THIS_OBJECT(cx,obj), SPROP_USERID(sprop), vp)) + +#define SPROP_GET(cx,sprop,obj,obj2,vp) \ + (((sprop)->attrs & JSPROP_GETTER) \ + ? js_InternalGetOrSet(cx, obj, (sprop)->id, \ + OBJECT_TO_JSVAL((sprop)->getter), JSACC_READ, \ + 0, 0, vp) \ + : SPROP_CALL_GETTER(cx, sprop, (sprop)->getter, obj, obj2, vp)) + +#define SPROP_SET(cx,sprop,obj,obj2,vp) \ + (((sprop)->attrs & JSPROP_SETTER) \ + ? js_InternalGetOrSet(cx, obj, (sprop)->id, \ + OBJECT_TO_JSVAL((sprop)->setter), JSACC_WRITE, \ + 1, vp, vp) \ + : ((sprop)->attrs & JSPROP_GETTER) \ + ? (JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, \ + JSMSG_GETTER_ONLY, NULL), JS_FALSE) \ + : SPROP_CALL_SETTER(cx, sprop, (sprop)->setter, obj, obj2, vp)) + +/* Macro for common expression to test for shared permanent attributes. */ +#define SPROP_IS_SHARED_PERMANENT(sprop) \ + ((~(sprop)->attrs & (JSPROP_SHARED | JSPROP_PERMANENT)) == 0) + +extern JSScope * +js_GetMutableScope(JSContext *cx, JSObject *obj); + +extern JSScope * +js_NewScope(JSContext *cx, jsrefcount nrefs, JSObjectOps *ops, JSClass *clasp, + JSObject *obj); + +extern void +js_DestroyScope(JSContext *cx, JSScope *scope); + +#define ID_TO_VALUE(id) (((id) & JSVAL_INT) ? id : ATOM_KEY((JSAtom *)(id))) +#define HASH_ID(id) (((id) & JSVAL_INT) \ + ? (jsatomid) JSVAL_TO_INT(id) \ + : ((JSAtom *)id)->number) + +extern JS_FRIEND_API(JSScopeProperty **) +js_SearchScope(JSScope *scope, jsid id, JSBool adding); + +#define SCOPE_GET_PROPERTY(scope, id) \ + SPROP_FETCH(js_SearchScope(scope, id, JS_FALSE)) + +#define SCOPE_HAS_PROPERTY(scope, sprop) \ + (SCOPE_GET_PROPERTY(scope, (sprop)->id) == (sprop)) + +extern JSScopeProperty * +js_AddScopeProperty(JSContext *cx, JSScope *scope, jsid id, + JSPropertyOp getter, JSPropertyOp setter, uint32 slot, + uintN attrs, uintN flags, intN shortid); + +extern JSScopeProperty * +js_ChangeScopePropertyAttrs(JSContext *cx, JSScope *scope, + JSScopeProperty *sprop, uintN attrs, uintN mask, + JSPropertyOp getter, JSPropertyOp setter); + +extern JSBool +js_RemoveScopeProperty(JSContext *cx, JSScope *scope, jsid id); + +extern void +js_ClearScope(JSContext *cx, JSScope *scope); + +#define MARK_SCOPE_PROPERTY(sprop) ((sprop)->flags |= SPROP_MARK) + +extern void +js_SweepScopeProperties(JSRuntime *rt); + +extern JSBool +js_InitPropertyTree(JSRuntime *rt); + +extern void +js_FinishPropertyTree(JSRuntime *rt); + +#endif /* jsscope_h___ */ diff --git a/src/dom/js/jsscript.c b/src/dom/js/jsscript.c new file mode 100644 index 000000000..504cbbd6d --- /dev/null +++ b/src/dom/js/jsscript.c @@ -0,0 +1,1287 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* + * JS script operations. + */ +#include "jsstddef.h" +#include +#include "jstypes.h" +#include "jsutil.h" /* Added by JSIFY */ +#include "jsprf.h" +#include "jsapi.h" +#include "jsatom.h" +#include "jscntxt.h" +#include "jsconfig.h" +#include "jsdbgapi.h" +#include "jsemit.h" +#include "jsfun.h" +#include "jsinterp.h" +#include "jslock.h" +#include "jsnum.h" +#include "jsopcode.h" +#include "jsscript.h" +#if JS_HAS_XDR +#include "jsxdrapi.h" +#endif + +#if JS_HAS_SCRIPT_OBJECT + +#if JS_HAS_TOSOURCE +static JSBool +script_toSource(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval) +{ + JSScript *script; + size_t i, j, k, n; + char buf[16]; + jschar *s, *t; + uint32 indent; + JSString *str; + + if (!JS_InstanceOf(cx, obj, &js_ScriptClass, argv)) + return JS_FALSE; + script = (JSScript *) JS_GetPrivate(cx, obj); + + /* Let n count the source string length, j the "front porch" length. */ + j = JS_snprintf(buf, sizeof buf, "(new %s(", js_ScriptClass.name); + n = j + 2; + if (!script) { + /* Let k count the constructor argument string length. */ + k = 0; + s = NULL; /* quell GCC overwarning */ + } else { + indent = 0; + if (argc && !js_ValueToECMAUint32(cx, argv[0], &indent)) + return JS_FALSE; + str = JS_DecompileScript(cx, script, "Script.prototype.toSource", + (uintN)indent); + if (!str) + return JS_FALSE; + str = js_QuoteString(cx, str, '\''); + if (!str) + return JS_FALSE; + s = JSSTRING_CHARS(str); + k = JSSTRING_LENGTH(str); + n += k; + } + + /* Allocate the source string and copy into it. */ + t = (jschar *) JS_malloc(cx, (n + 1) * sizeof(jschar)); + if (!t) + return JS_FALSE; + for (i = 0; i < j; i++) + t[i] = buf[i]; + for (j = 0; j < k; i++, j++) + t[i] = s[j]; + t[i++] = ')'; + t[i++] = ')'; + t[i] = 0; + + /* Create and return a JS string for t. */ + str = JS_NewUCString(cx, t, n); + if (!str) { + JS_free(cx, t); + return JS_FALSE; + } + *rval = STRING_TO_JSVAL(str); + return JS_TRUE; +} +#endif /* JS_HAS_TOSOURCE */ + +static JSBool +script_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval) +{ + JSScript *script; + uint32 indent; + JSString *str; + + if (!JS_InstanceOf(cx, obj, &js_ScriptClass, argv)) + return JS_FALSE; + script = (JSScript *) JS_GetPrivate(cx, obj); + if (!script) { + *rval = STRING_TO_JSVAL(cx->runtime->emptyString); + return JS_TRUE; + } + + indent = 0; + if (argc && !js_ValueToECMAUint32(cx, argv[0], &indent)) + return JS_FALSE; + str = JS_DecompileScript(cx, script, "Script.prototype.toString", + (uintN)indent); + if (!str) + return JS_FALSE; + *rval = STRING_TO_JSVAL(str); + return JS_TRUE; +} + +static JSBool +script_compile(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval) +{ + JSScript *oldscript, *script; + JSString *str; + JSStackFrame *fp, *caller; + JSObject *scopeobj; + const char *file; + uintN line; + JSPrincipals *principals; + + /* Make sure obj is a Script object. */ + if (!JS_InstanceOf(cx, obj, &js_ScriptClass, argv)) + return JS_FALSE; + + /* If no args, leave private undefined and return early. */ + if (argc == 0) + goto out; + + /* Otherwise, the first arg is the script source to compile. */ + str = js_ValueToString(cx, argv[0]); + if (!str) + return JS_FALSE; + + /* Compile using the caller's scope chain, which js_Invoke passes to fp. */ + fp = cx->fp; + caller = JS_GetScriptedCaller(cx, fp); + JS_ASSERT(!caller || fp->scopeChain == caller->scopeChain); + + scopeobj = NULL; + if (argc >= 2) { + if (!js_ValueToObject(cx, argv[1], &scopeobj)) + return JS_FALSE; + argv[1] = OBJECT_TO_JSVAL(scopeobj); + } + if (caller) { + if (!scopeobj) + scopeobj = caller->scopeChain; + + file = caller->script->filename; + line = js_PCToLineNumber(cx, caller->script, caller->pc); + principals = JS_EvalFramePrincipals(cx, fp, caller); + } else { + file = NULL; + line = 0; + principals = NULL; + } + + /* XXXbe set only for the compiler, which does not currently test it */ + fp->flags |= JSFRAME_EVAL; + + /* Compile the new script using the caller's scope chain, a la eval(). */ + script = JS_CompileUCScriptForPrincipals(cx, scopeobj, principals, + JSSTRING_CHARS(str), + JSSTRING_LENGTH(str), + file, line); + if (!script) + return JS_FALSE; + + /* Swap script for obj's old script, if any. */ + oldscript = (JSScript *) JS_GetPrivate(cx, obj); + if (!JS_SetPrivate(cx, obj, script)) { + js_DestroyScript(cx, script); + return JS_FALSE; + } + if (oldscript) + js_DestroyScript(cx, oldscript); + + script->object = obj; +out: + /* Return the object. */ + *rval = OBJECT_TO_JSVAL(obj); + return JS_TRUE; +} + +static JSBool +script_exec(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + JSScript *script; + JSObject *scopeobj, *parent; + JSStackFrame *fp, *caller; + + if (!JS_InstanceOf(cx, obj, &js_ScriptClass, argv)) + return JS_FALSE; + script = (JSScript *) JS_GetPrivate(cx, obj); + if (!script) + return JS_TRUE; + + scopeobj = NULL; + if (argc) { + if (!js_ValueToObject(cx, argv[0], &scopeobj)) + return JS_FALSE; + argv[0] = OBJECT_TO_JSVAL(scopeobj); + } + + /* + * Emulate eval() by using caller's this, var object, sharp array, etc., + * all propagated by js_Execute via a non-null fourth (down) argument to + * js_Execute. If there is no scripted caller, js_Execute uses its second + * (chain) argument to set the exec frame's varobj, thisp, and scopeChain. + * + * Unlike eval, which the compiler detects, Script.prototype.exec may be + * called from a lightweight function, or even from native code (in which + * case fp->varobj and fp->scopeChain are null). If exec is called from + * a lightweight function, we will need to get a Call object representing + * its frame, to act as the var object and scope chain head. + */ + fp = cx->fp; + caller = JS_GetScriptedCaller(cx, fp); + if (caller && !caller->varobj) { + /* Called from a lightweight function. */ + JS_ASSERT(caller->fun && !(caller->fun->flags & JSFUN_HEAVYWEIGHT)); + + /* Scope chain links from Call object to callee's parent. */ + parent = OBJ_GET_PARENT(cx, JSVAL_TO_OBJECT(caller->argv[-2])); + if (!js_GetCallObject(cx, caller, parent)) + return JS_FALSE; + } + + if (!scopeobj) { + /* No scope object passed in: try to use the caller's scope chain. */ + if (caller) { + /* + * Load caller->scopeChain after the conditional js_GetCallObject + * call above, which resets scopeChain as well as varobj. + */ + scopeobj = caller->scopeChain; + } else { + /* + * Called from native code, so we don't know what scope object to + * use. We could use parent (see above), but Script.prototype.exec + * might be a shared/sealed "superglobal" method. A more general + * approach would use cx->globalObject, which will be the same as + * exec.__parent__ in the non-superglobal case. In the superglobal + * case it's the right object: the global, not the superglobal. + */ + scopeobj = cx->globalObject; + } + } + + return js_Execute(cx, scopeobj, script, caller, JSFRAME_EVAL, rval); +} + +#if JS_HAS_XDR + +static JSBool +XDRAtomListElement(JSXDRState *xdr, JSAtomListElement *ale) +{ + jsval value; + jsatomid index; + + if (xdr->mode == JSXDR_ENCODE) + value = ATOM_KEY(ALE_ATOM(ale)); + + index = ALE_INDEX(ale); + if (!JS_XDRUint32(xdr, &index)) + return JS_FALSE; + ALE_SET_INDEX(ale, index); + + if (!JS_XDRValue(xdr, &value)) + return JS_FALSE; + + if (xdr->mode == JSXDR_DECODE) { + if (!ALE_SET_ATOM(ale, js_AtomizeValue(xdr->cx, value, 0))) + return JS_FALSE; + } + return JS_TRUE; +} + +static JSBool +XDRAtomMap(JSXDRState *xdr, JSAtomMap *map) +{ + uint32 length; + uintN i; + JSBool ok; + + if (xdr->mode == JSXDR_ENCODE) + length = map->length; + + if (!JS_XDRUint32(xdr, &length)) + return JS_FALSE; + + if (xdr->mode == JSXDR_DECODE) { + JSContext *cx; + void *mark; + JSAtomList al; + JSAtomListElement *ale; + + cx = xdr->cx; + mark = JS_ARENA_MARK(&cx->tempPool); + ATOM_LIST_INIT(&al); + for (i = 0; i < length; i++) { + JS_ARENA_ALLOCATE_TYPE(ale, JSAtomListElement, &cx->tempPool); + if (!ale || + !XDRAtomListElement(xdr, ale)) { + if (!ale) + JS_ReportOutOfMemory(cx); + JS_ARENA_RELEASE(&cx->tempPool, mark); + return JS_FALSE; + } + ALE_SET_NEXT(ale, al.list); + al.count++; + al.list = ale; + } + ok = js_InitAtomMap(cx, map, &al); + JS_ARENA_RELEASE(&cx->tempPool, mark); + return ok; + } + + if (xdr->mode == JSXDR_ENCODE) { + JSAtomListElement ale; + + for (i = 0; i < map->length; i++) { + ALE_SET_ATOM(&ale, map->vector[i]); + ALE_SET_INDEX(&ale, i); + if (!XDRAtomListElement(xdr, &ale)) + return JS_FALSE; + } + } + return JS_TRUE; +} + +JSBool +js_XDRScript(JSXDRState *xdr, JSScript **scriptp, JSBool *hasMagic) +{ + JSContext *cx; + JSScript *script, *newscript; + uint32 length, lineno, depth, magic, nsrcnotes, ntrynotes; + uint32 prologLength, version; + JSBool filenameWasSaved; + jssrcnote *notes, *sn; + + cx = xdr->cx; + script = *scriptp; + nsrcnotes = ntrynotes = 0; + filenameWasSaved = JS_FALSE; + notes = NULL; + + /* + * Encode prologLength and version after script->length (_2 or greater), + * but decode both new (>= _2) and old, prolog&version-free (_1) scripts. + * Version _3 supports principals serialization. Version _4 reorders the + * nsrcnotes and ntrynotes fields to come before everything except magic, + * length, prologLength, and version, so that srcnote and trynote storage + * can be allocated as part of the JSScript (along with bytecode storage). + */ + if (xdr->mode == JSXDR_ENCODE) + magic = JSXDR_MAGIC_SCRIPT_CURRENT; + if (!JS_XDRUint32(xdr, &magic)) + return JS_FALSE; + if (magic != JSXDR_MAGIC_SCRIPT_4 && + magic != JSXDR_MAGIC_SCRIPT_3 && + magic != JSXDR_MAGIC_SCRIPT_2 && + magic != JSXDR_MAGIC_SCRIPT_1) { + if (!hasMagic) { + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, + JSMSG_BAD_SCRIPT_MAGIC); + return JS_FALSE; + } + *hasMagic = JS_FALSE; + return JS_TRUE; + } + if (hasMagic) + *hasMagic = JS_TRUE; + + if (xdr->mode == JSXDR_ENCODE) { + length = script->length; + prologLength = PTRDIFF(script->main, script->code, jsbytecode); + version = (int32)script->version; + lineno = (uint32)script->lineno; + depth = (uint32)script->depth; + + /* Count the srcnotes, keeping notes pointing at the first one. */ + notes = SCRIPT_NOTES(script); + for (sn = notes; !SN_IS_TERMINATOR(sn); sn = SN_NEXT(sn)) + continue; + nsrcnotes = PTRDIFF(sn, notes, jssrcnote); + nsrcnotes++; /* room for the terminator */ + + /* Count the trynotes. */ + if (script->trynotes) { + while (script->trynotes[ntrynotes].catchStart) + ntrynotes++; + ntrynotes++; /* room for the end marker */ + } + } + + if (!JS_XDRUint32(xdr, &length)) + return JS_FALSE; + if (magic >= JSXDR_MAGIC_SCRIPT_2) { + if (!JS_XDRUint32(xdr, &prologLength)) + return JS_FALSE; + if (!JS_XDRUint32(xdr, &version)) + return JS_FALSE; + + /* To fuse allocations, we need srcnote and trynote counts early. */ + if (magic >= JSXDR_MAGIC_SCRIPT_4) { + if (!JS_XDRUint32(xdr, &nsrcnotes)) + return JS_FALSE; + if (!JS_XDRUint32(xdr, &ntrynotes)) + return JS_FALSE; + } + } + + if (xdr->mode == JSXDR_DECODE) { + script = js_NewScript(cx, length, nsrcnotes, ntrynotes); + if (!script) + return JS_FALSE; + if (magic >= JSXDR_MAGIC_SCRIPT_2) { + script->main += prologLength; + script->version = (JSVersion) version; + + /* If we know nsrcnotes, we allocated space for notes in script. */ + if (magic >= JSXDR_MAGIC_SCRIPT_4) + notes = SCRIPT_NOTES(script); + } + *scriptp = script; + } + + /* + * Control hereafter must goto error on failure, in order for the DECODE + * case to destroy script and conditionally free notes, which if non-null + * in the (DECODE and version < _4) case must point at a temporary vector + * allocated just below. + */ + if (!JS_XDRBytes(xdr, (char *)script->code, length * sizeof(jsbytecode)) || + !XDRAtomMap(xdr, &script->atomMap)) { + goto error; + } + + if (magic < JSXDR_MAGIC_SCRIPT_4) { + if (!JS_XDRUint32(xdr, &nsrcnotes)) + goto error; + if (xdr->mode == JSXDR_DECODE) { + notes = (jssrcnote *) JS_malloc(cx, nsrcnotes * sizeof(jssrcnote)); + if (!notes) + goto error; + } + } + + if (!JS_XDRBytes(xdr, (char *)notes, nsrcnotes * sizeof(jssrcnote)) || + !JS_XDRCStringOrNull(xdr, (char **)&script->filename) || + !JS_XDRUint32(xdr, &lineno) || + !JS_XDRUint32(xdr, &depth) || + (magic < JSXDR_MAGIC_SCRIPT_4 && !JS_XDRUint32(xdr, &ntrynotes))) { + goto error; + } + + /* Script principals transcoding support comes with versions >= _3. */ + if (magic >= JSXDR_MAGIC_SCRIPT_3) { + JSPrincipals *principals; + uint32 encodeable; + + if (xdr->mode == JSXDR_ENCODE) { + principals = script->principals; + encodeable = (cx->runtime->principalsTranscoder != NULL); + if (!JS_XDRUint32(xdr, &encodeable)) + goto error; + if (encodeable && + !cx->runtime->principalsTranscoder(xdr, &principals)) { + goto error; + } + } else { + if (!JS_XDRUint32(xdr, &encodeable)) + goto error; + if (encodeable) { + if (!cx->runtime->principalsTranscoder) { + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, + JSMSG_CANT_DECODE_PRINCIPALS); + goto error; + } + if (!cx->runtime->principalsTranscoder(xdr, &principals)) + goto error; + script->principals = principals; + } + } + } + + if (xdr->mode == JSXDR_DECODE) { + const char *filename = script->filename; + if (filename) { + filename = js_SaveScriptFilename(cx, filename); + if (!filename) + goto error; + JS_free(cx, (void *) script->filename); + script->filename = filename; + filenameWasSaved = JS_TRUE; + } + script->lineno = (uintN)lineno; + script->depth = (uintN)depth; + + if (magic < JSXDR_MAGIC_SCRIPT_4) { + /* + * Argh, we have to reallocate script, copy notes into the extra + * space after the bytecodes, and free the temporary notes vector. + * First, add enough slop to nsrcnotes so we can align the address + * after the srcnotes of the first trynote. + */ + uint32 osrcnotes = nsrcnotes; + + if (ntrynotes) + nsrcnotes += JSTRYNOTE_ALIGNMASK; + newscript = (JSScript *) JS_realloc(cx, script, + sizeof(JSScript) + + length * sizeof(jsbytecode) + + nsrcnotes * sizeof(jssrcnote) + + ntrynotes * sizeof(JSTryNote)); + if (!newscript) + goto error; + + *scriptp = script = newscript; + script->code = (jsbytecode *)(script + 1); + script->main = script->code + prologLength; + memcpy(script->code + length, notes, osrcnotes * sizeof(jssrcnote)); + JS_free(cx, (void *) notes); + notes = NULL; + if (ntrynotes) { + script->trynotes = (JSTryNote *) + ((jsword)(SCRIPT_NOTES(script) + nsrcnotes) & + ~(jsword)JSTRYNOTE_ALIGNMASK); + } + } + } + + while (ntrynotes) { + JSTryNote *tn = &script->trynotes[--ntrynotes]; + uint32 start = (uint32) tn->start, + catchLength = (uint32) tn->length, + catchStart = (uint32) tn->catchStart; + + if (!JS_XDRUint32(xdr, &start) || + !JS_XDRUint32(xdr, &catchLength) || + !JS_XDRUint32(xdr, &catchStart)) { + goto error; + } + tn->start = (ptrdiff_t) start; + tn->length = (ptrdiff_t) catchLength; + tn->catchStart = (ptrdiff_t) catchStart; + } + return JS_TRUE; + + error: + if (xdr->mode == JSXDR_DECODE) { + if (script->filename && !filenameWasSaved) { + JS_free(cx, (void *) script->filename); + script->filename = NULL; + } + if (notes && magic < JSXDR_MAGIC_SCRIPT_4) + JS_free(cx, (void *) notes); + js_DestroyScript(cx, script); + *scriptp = NULL; + } + return JS_FALSE; +} + +#if JS_HAS_XDR_FREEZE_THAW +/* + * These cannot be exposed to web content, and chrome does not need them, so + * we take them out of the Mozilla client altogether. Fortunately, there is + * no way to serialize a native function (see fun_xdrObject in jsfun.c). + */ + +static JSBool +script_freeze(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval) +{ + JSXDRState *xdr; + JSScript *script; + JSBool ok, hasMagic; + uint32 len; + void *buf; + JSString *str; + + if (!JS_InstanceOf(cx, obj, &js_ScriptClass, argv)) + return JS_FALSE; + script = (JSScript *) JS_GetPrivate(cx, obj); + if (!script) + return JS_TRUE; + + /* create new XDR */ + xdr = JS_XDRNewMem(cx, JSXDR_ENCODE); + if (!xdr) + return JS_FALSE; + + /* write */ + ok = js_XDRScript(xdr, &script, &hasMagic); + if (!ok) + goto out; + if (!hasMagic) { + *rval = JSVAL_VOID; + goto out; + } + + buf = JS_XDRMemGetData(xdr, &len); + if (!buf) { + ok = JS_FALSE; + goto out; + } + + JS_ASSERT((jsword)buf % sizeof(jschar) == 0); + len /= sizeof(jschar); + str = JS_NewUCStringCopyN(cx, (jschar *)buf, len); + if (!str) { + ok = JS_FALSE; + goto out; + } + +#if IS_BIG_ENDIAN + { + jschar *chars; + uint32 i; + + /* Swap bytes in Unichars to keep frozen strings machine-independent. */ + chars = JS_GetStringChars(str); + for (i = 0; i < len; i++) + chars[i] = JSXDR_SWAB16(chars[i]); + } +#endif + *rval = STRING_TO_JSVAL(str); + +out: + JS_XDRDestroy(xdr); + return ok; +} + +static JSBool +script_thaw(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval) +{ + JSXDRState *xdr; + JSString *str; + void *buf; + uint32 len; + JSScript *script, *oldscript; + JSBool ok, hasMagic; + + if (!JS_InstanceOf(cx, obj, &js_ScriptClass, argv)) + return JS_FALSE; + + if (argc == 0) + return JS_TRUE; + str = js_ValueToString(cx, argv[0]); + if (!str) + return JS_FALSE; + + /* create new XDR */ + xdr = JS_XDRNewMem(cx, JSXDR_DECODE); + if (!xdr) + return JS_FALSE; + + buf = JS_GetStringChars(str); + len = JS_GetStringLength(str); +#if IS_BIG_ENDIAN + { + jschar *from, *to; + uint32 i; + + /* Swap bytes in Unichars to keep frozen strings machine-independent. */ + from = (jschar *)buf; + to = (jschar *) JS_malloc(cx, len * sizeof(jschar)); + if (!to) { + JS_XDRDestroy(xdr); + return JS_FALSE; + } + for (i = 0; i < len; i++) + to[i] = JSXDR_SWAB16(from[i]); + buf = (char *)to; + } +#endif + len *= sizeof(jschar); + JS_XDRMemSetData(xdr, buf, len); + + /* XXXbe should magic mismatch be error, or false return value? */ + ok = js_XDRScript(xdr, &script, &hasMagic); + if (!ok) + goto out; + if (!hasMagic) { + *rval = JSVAL_FALSE; + goto out; + } + + /* Swap script for obj's old script, if any. */ + oldscript = (JSScript *) JS_GetPrivate(cx, obj); + ok = JS_SetPrivate(cx, obj, script); + if (!ok) { + JS_free(cx, script); + goto out; + } + if (oldscript) + js_DestroyScript(cx, oldscript); + + script->object = obj; + js_CallNewScriptHook(cx, script, NULL); + +out: + /* + * We reset the buffer to be NULL so that it doesn't free the chars + * memory owned by str (argv[0]). + */ + JS_XDRMemSetData(xdr, NULL, 0); + JS_XDRDestroy(xdr); +#if IS_BIG_ENDIAN + JS_free(cx, buf); +#endif + *rval = JSVAL_TRUE; + return ok; +} + +static const char js_thaw_str[] = "thaw"; + +#endif /* JS_HAS_XDR_FREEZE_THAW */ +#endif /* JS_HAS_XDR */ + +static JSFunctionSpec script_methods[] = { +#if JS_HAS_TOSOURCE + {js_toSource_str, script_toSource, 0,0,0}, +#endif + {js_toString_str, script_toString, 0,0,0}, + {"compile", script_compile, 2,0,0}, + {"exec", script_exec, 1,0,0}, +#if JS_HAS_XDR_FREEZE_THAW + {"freeze", script_freeze, 0,0,0}, + {js_thaw_str, script_thaw, 1,0,0}, +#endif /* JS_HAS_XDR_FREEZE_THAW */ + {0,0,0,0,0} +}; + +#endif /* JS_HAS_SCRIPT_OBJECT */ + +static void +script_finalize(JSContext *cx, JSObject *obj) +{ + JSScript *script; + + script = (JSScript *) JS_GetPrivate(cx, obj); + if (script) + js_DestroyScript(cx, script); +} + +static JSBool +script_call(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ +#if JS_HAS_SCRIPT_OBJECT + return script_exec(cx, JSVAL_TO_OBJECT(argv[-2]), argc, argv, rval); +#else + return JS_FALSE; +#endif +} + +static uint32 +script_mark(JSContext *cx, JSObject *obj, void *arg) +{ + JSScript *script; + + script = (JSScript *) JS_GetPrivate(cx, obj); + if (script) + js_MarkScript(cx, script, arg); + return 0; +} + +JS_FRIEND_DATA(JSClass) js_ScriptClass = { + js_Script_str, + JSCLASS_HAS_PRIVATE, + JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, + JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, script_finalize, + NULL, NULL, script_call, NULL,/*XXXbe xdr*/ + NULL, NULL, script_mark, 0 +}; + +#if JS_HAS_SCRIPT_OBJECT + +static JSBool +Script(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + /* If not constructing, replace obj with a new Script object. */ + if (!(cx->fp->flags & JSFRAME_CONSTRUCTING)) { + obj = js_NewObject(cx, &js_ScriptClass, NULL, NULL); + if (!obj) + return JS_FALSE; + } + return script_compile(cx, obj, argc, argv, rval); +} + +#if JS_HAS_XDR_FREEZE_THAW + +static JSBool +script_static_thaw(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval) +{ + obj = js_NewObject(cx, &js_ScriptClass, NULL, NULL); + if (!obj) + return JS_FALSE; + if (!script_thaw(cx, obj, argc, argv, rval)) + return JS_FALSE; + *rval = OBJECT_TO_JSVAL(obj); + return JS_TRUE; +} + +static JSFunctionSpec script_static_methods[] = { + {js_thaw_str, script_static_thaw, 1,0,0}, + {0,0,0,0,0} +}; + +#else /* !JS_HAS_XDR_FREEZE_THAW */ + +#define script_static_methods NULL + +#endif /* !JS_HAS_XDR_FREEZE_THAW */ + +JSObject * +js_InitScriptClass(JSContext *cx, JSObject *obj) +{ + return JS_InitClass(cx, obj, NULL, &js_ScriptClass, Script, 1, + NULL, script_methods, NULL, script_static_methods); +} + +#endif /* JS_HAS_SCRIPT_OBJECT */ + +/* + * Shared script filename management. + */ +static JSHashTable *script_filename_table; +#ifdef JS_THREADSAFE +static JSLock *script_filename_table_lock; +#endif + +JS_STATIC_DLL_CALLBACK(int) +js_compare_strings(const void *k1, const void *k2) +{ + return strcmp(k1, k2) == 0; +} + +/* Shared with jsatom.c to save code space. */ +extern void * JS_DLL_CALLBACK +js_alloc_table_space(void *priv, size_t size); + +extern void JS_DLL_CALLBACK +js_free_table_space(void *priv, void *item); + +/* NB: This struct overlays JSHashEntry -- see jshash.h, do not reorganize. */ +typedef struct ScriptFilenameEntry { + JSHashEntry *next; /* hash chain linkage */ + JSHashNumber keyHash; /* key hash function result */ + const void *key; /* ptr to filename, below */ + JSPackedBool mark; /* mark flag, for GC */ + char filename[3]; /* two or more bytes, NUL-terminated */ +} ScriptFilenameEntry; + +JS_STATIC_DLL_CALLBACK(JSHashEntry *) +js_alloc_entry(void *priv, const void *key) +{ + size_t nbytes = offsetof(ScriptFilenameEntry, filename) + strlen(key) + 1; + + return (JSHashEntry *) malloc(JS_MAX(nbytes, sizeof(JSHashEntry))); +} + +JS_STATIC_DLL_CALLBACK(void) +js_free_entry(void *priv, JSHashEntry *he, uintN flag) +{ + if (flag != HT_FREE_ENTRY) + return; + free(he); +} + +static JSHashAllocOps table_alloc_ops = { + js_alloc_table_space, js_free_table_space, + js_alloc_entry, js_free_entry +}; + +JSBool +js_InitScriptGlobals() +{ +#ifdef JS_THREADSAFE + /* Must come through here once in primordial thread to init safely! */ + if (!script_filename_table_lock) { + script_filename_table_lock = JS_NEW_LOCK(); + if (!script_filename_table_lock) + return JS_FALSE; + } +#endif + if (!script_filename_table) { + JS_ACQUIRE_LOCK(script_filename_table_lock); + if (!script_filename_table) { + script_filename_table = + JS_NewHashTable(16, JS_HashString, js_compare_strings, NULL, + &table_alloc_ops, NULL); + } + JS_RELEASE_LOCK(script_filename_table_lock); + if (!script_filename_table) + return JS_FALSE; + } + return JS_TRUE; +} + +void +js_FreeScriptGlobals() +{ + if (script_filename_table) { + JS_HashTableDestroy(script_filename_table); + script_filename_table = NULL; + } +#ifdef JS_THREADSAFE + if (script_filename_table_lock) { + JS_DESTROY_LOCK(script_filename_table_lock); + script_filename_table_lock = NULL; + } +#endif +} + +#ifdef DEBUG_brendan +size_t sft_savings = 0; +#endif + +const char * +js_SaveScriptFilename(JSContext *cx, const char *filename) +{ + JSHashTable *table; + JSHashNumber hash; + JSHashEntry **hep; + ScriptFilenameEntry *sfe; + + JS_ACQUIRE_LOCK(script_filename_table_lock); + table = script_filename_table; + hash = JS_HashString(filename); + hep = JS_HashTableRawLookup(table, hash, filename); + sfe = (ScriptFilenameEntry *) *hep; +#ifdef DEBUG_brendan + if (sfe) + sft_savings += strlen(sfe->filename); +#endif + if (!sfe) { + sfe = (ScriptFilenameEntry *) + JS_HashTableRawAdd(table, hep, hash, filename, NULL); + if (sfe) { + sfe->key = strcpy(sfe->filename, filename); + JS_ASSERT(!sfe->mark); + } + } + JS_RELEASE_LOCK(script_filename_table_lock); + if (!sfe) { + JS_ReportOutOfMemory(cx); + return NULL; + } + return sfe->filename; +} + +void +js_MarkScriptFilename(const char *filename) +{ + ScriptFilenameEntry *sfe; + + /* + * Back up from filename by its offset within its hash table entry. + * The sfe->key member, redundant given sfe->filename but required by + * the old jshash.c code, here gives us a useful sanity check. This + * assertion will very likely botch if someone tries to mark a string + * that wasn't allocated as an sfe->filename. + */ + sfe = (ScriptFilenameEntry *) + (filename - offsetof(ScriptFilenameEntry, filename)); + JS_ASSERT(sfe->key == sfe->filename); + sfe->mark = JS_TRUE; +} + +JS_STATIC_DLL_CALLBACK(intN) +js_script_filename_sweeper(JSHashEntry *he, intN i, void *arg) +{ + ScriptFilenameEntry *sfe = (ScriptFilenameEntry *) he; + + if (!sfe->mark) + return HT_ENUMERATE_REMOVE; + sfe->mark = JS_FALSE; + return HT_ENUMERATE_NEXT; +} + +void +js_SweepScriptFilenames(JSRuntime *rt) +{ + JS_HashTableEnumerateEntries(script_filename_table, + js_script_filename_sweeper, + rt); +#ifdef DEBUG_brendan + printf("script filename table savings so far: %u\n", sft_savings); +#endif +} + +JSScript * +js_NewScript(JSContext *cx, uint32 length, uint32 nsrcnotes, uint32 ntrynotes) +{ + JSScript *script; + + /* Round up source note count to align script->trynotes for its type. */ + if (ntrynotes) + nsrcnotes += JSTRYNOTE_ALIGNMASK; + script = (JSScript *) JS_malloc(cx, + sizeof(JSScript) + + length * sizeof(jsbytecode) + + nsrcnotes * sizeof(jssrcnote) + + ntrynotes * sizeof(JSTryNote)); + if (!script) + return NULL; + memset(script, 0, sizeof(JSScript)); + script->code = script->main = (jsbytecode *)(script + 1); + script->length = length; + script->version = cx->version; + if (ntrynotes) { + script->trynotes = (JSTryNote *) + ((jsword)(SCRIPT_NOTES(script) + nsrcnotes) & + ~(jsword)JSTRYNOTE_ALIGNMASK); + } + return script; +} + +JS_FRIEND_API(JSScript *) +js_NewScriptFromCG(JSContext *cx, JSCodeGenerator *cg, JSFunction *fun) +{ + uint32 mainLength, prologLength, nsrcnotes, ntrynotes; + JSScript *script; + const char *filename; + + mainLength = CG_OFFSET(cg); + prologLength = CG_PROLOG_OFFSET(cg); + CG_COUNT_FINAL_SRCNOTES(cg, nsrcnotes); + CG_COUNT_FINAL_TRYNOTES(cg, ntrynotes); + script = js_NewScript(cx, prologLength + mainLength, nsrcnotes, ntrynotes); + if (!script) + return NULL; + + /* Now that we have script, error control flow must go to label bad. */ + script->main += prologLength; + memcpy(script->code, CG_PROLOG_BASE(cg), prologLength * sizeof(jsbytecode)); + memcpy(script->main, CG_BASE(cg), mainLength * sizeof(jsbytecode)); + if (!js_InitAtomMap(cx, &script->atomMap, &cg->atomList)) + goto bad; + + filename = cg->filename; + if (filename) { + script->filename = js_SaveScriptFilename(cx, filename); + if (!script->filename) + goto bad; + } + script->lineno = cg->firstLine; + script->depth = cg->maxStackDepth; + if (cg->principals) { + script->principals = cg->principals; + JSPRINCIPALS_HOLD(cx, script->principals); + } + + if (!js_FinishTakingSrcNotes(cx, cg, SCRIPT_NOTES(script))) + goto bad; + if (script->trynotes) + js_FinishTakingTryNotes(cx, cg, script->trynotes); + + /* Tell the debugger about this compiled script. */ + js_CallNewScriptHook(cx, script, fun); + return script; + +bad: + js_DestroyScript(cx, script); + return NULL; +} + +JS_FRIEND_API(void) +js_CallNewScriptHook(JSContext *cx, JSScript *script, JSFunction *fun) +{ + JSRuntime *rt; + JSNewScriptHook hook; + + rt = cx->runtime; + hook = rt->newScriptHook; + if (hook) { + /* + * We use a dummy stack frame to protect the script from a GC caused + * by debugger-hook execution. + * + * XXX We really need a way to manage local roots and such more + * XXX automatically, at which point we can remove this one-off hack + * XXX and others within the engine. See bug 40757 for discussion. + */ + JSStackFrame dummy; + + memset(&dummy, 0, sizeof dummy); + dummy.down = cx->fp; + dummy.script = script; + cx->fp = &dummy; + + hook(cx, script->filename, script->lineno, script, fun, + rt->newScriptHookData); + + cx->fp = dummy.down; + } +} + +void +js_DestroyScript(JSContext *cx, JSScript *script) +{ + JSRuntime *rt; + JSDestroyScriptHook hook; + + rt = cx->runtime; + hook = rt->destroyScriptHook; + if (hook) + hook(cx, script, rt->destroyScriptHookData); + + JS_ClearScriptTraps(cx, script); + js_FreeAtomMap(cx, &script->atomMap); + if (script->principals) + JSPRINCIPALS_DROP(cx, script->principals); + JS_free(cx, script); +} + +void +js_MarkScript(JSContext *cx, JSScript *script, void *arg) +{ + JSAtomMap *map; + uintN i, length; + JSAtom **vector; + + map = &script->atomMap; + length = map->length; + vector = map->vector; + for (i = 0; i < length; i++) + GC_MARK_ATOM(cx, vector[i], arg); + + if (script->filename) + js_MarkScriptFilename(script->filename); +} + +jssrcnote * +js_GetSrcNote(JSScript *script, jsbytecode *pc) +{ + jssrcnote *sn; + ptrdiff_t offset, target; + + target = PTRDIFF(pc, script->code, jsbytecode); + if ((uint32)target >= script->length) + return NULL; + offset = 0; + for (sn = SCRIPT_NOTES(script); !SN_IS_TERMINATOR(sn); sn = SN_NEXT(sn)) { + offset += SN_DELTA(sn); + if (offset == target && SN_IS_GETTABLE(sn)) + return sn; + } + return NULL; +} + +uintN +js_PCToLineNumber(JSContext *cx, JSScript *script, jsbytecode *pc) +{ + JSAtom *atom; + JSFunction *fun; + uintN lineno; + ptrdiff_t offset, target; + jssrcnote *sn; + JSSrcNoteType type; + + /* + * Special case: function definition needs no line number note because + * the function's script contains its starting line number. + */ + if (*pc == JSOP_DEFFUN) { + atom = GET_ATOM(cx, script, pc); + fun = (JSFunction *) JS_GetPrivate(cx, ATOM_TO_OBJECT(atom)); + return fun->script->lineno; + } + + /* + * General case: walk through source notes accumulating their deltas, + * keeping track of line-number notes, until we pass the note for pc's + * offset within script->code. + */ + lineno = script->lineno; + offset = 0; + target = PTRDIFF(pc, script->code, jsbytecode); + for (sn = SCRIPT_NOTES(script); !SN_IS_TERMINATOR(sn); sn = SN_NEXT(sn)) { + offset += SN_DELTA(sn); + type = (JSSrcNoteType) SN_TYPE(sn); + if (type == SRC_SETLINE) { + if (offset <= target) + lineno = (uintN) js_GetSrcNoteOffset(sn, 0); + } else if (type == SRC_NEWLINE) { + if (offset <= target) + lineno++; + } + if (offset > target) + break; + } + return lineno; +} + +jsbytecode * +js_LineNumberToPC(JSScript *script, uintN target) +{ + ptrdiff_t offset; + uintN lineno; + jssrcnote *sn; + JSSrcNoteType type; + + offset = 0; + lineno = script->lineno; + for (sn = SCRIPT_NOTES(script); !SN_IS_TERMINATOR(sn); sn = SN_NEXT(sn)) { + if (lineno >= target) + break; + offset += SN_DELTA(sn); + type = (JSSrcNoteType) SN_TYPE(sn); + if (type == SRC_SETLINE) { + lineno = (uintN) js_GetSrcNoteOffset(sn, 0); + } else if (type == SRC_NEWLINE) { + lineno++; + } + } + return script->code + offset; +} + +uintN +js_GetScriptLineExtent(JSScript *script) +{ + uintN lineno; + jssrcnote *sn; + JSSrcNoteType type; + + lineno = script->lineno; + for (sn = SCRIPT_NOTES(script); !SN_IS_TERMINATOR(sn); sn = SN_NEXT(sn)) { + type = (JSSrcNoteType) SN_TYPE(sn); + if (type == SRC_SETLINE) { + lineno = (uintN) js_GetSrcNoteOffset(sn, 0); + } else if (type == SRC_NEWLINE) { + lineno++; + } + } + return 1 + lineno - script->lineno; +} diff --git a/src/dom/js/jsscript.h b/src/dom/js/jsscript.h new file mode 100644 index 000000000..ffcc40de7 --- /dev/null +++ b/src/dom/js/jsscript.h @@ -0,0 +1,178 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef jsscript_h___ +#define jsscript_h___ +/* + * JS script descriptor. + */ +#include "jsatom.h" +#include "jsprvtd.h" + +JS_BEGIN_EXTERN_C + +/* + * Exception handling runtime information. + * + * All fields except length are code offsets, relative to the beginning of + * the script. If script->trynotes is not null, it points to a vector of + * these structs terminated by one with catchStart == 0. + */ +struct JSTryNote { + ptrdiff_t start; /* start of try statement */ + ptrdiff_t length; /* count of try statement bytecodes */ + ptrdiff_t catchStart; /* start of catch block (0 if end) */ +}; + +#define JSTRYNOTE_GRAIN sizeof(ptrdiff_t) +#define JSTRYNOTE_ALIGNMASK (JSTRYNOTE_GRAIN - 1) + +struct JSScript { + jsbytecode *code; /* bytecodes and their immediate operands */ + uint32 length; /* length of code vector */ + jsbytecode *main; /* main entry point, after predef'ing prolog */ + JSVersion version; /* JS version under which script was compiled */ + JSAtomMap atomMap; /* maps immediate index to literal struct */ + const char *filename; /* source filename or null */ + uintN lineno; /* base line number of script */ + uintN depth; /* maximum stack depth in slots */ + JSTryNote *trynotes; /* exception table for this script */ + JSPrincipals *principals; /* principals for this script */ + JSObject *object; /* optional Script-class object wrapper */ +}; + +/* No need to store script->notes now that it is allocated right after code. */ +#define SCRIPT_NOTES(script) ((jssrcnote*)((script)->code+(script)->length)) + +#define SCRIPT_FIND_CATCH_START(script, pc, catchpc) \ + JS_BEGIN_MACRO \ + JSTryNote *tn_ = (script)->trynotes; \ + jsbytecode *catchpc_ = NULL; \ + if (tn_) { \ + ptrdiff_t off_ = PTRDIFF(pc, (script)->main, jsbytecode); \ + if (off_ >= 0) { \ + while ((jsuword)(off_ - tn_->start) >= (jsuword)tn_->length) \ + ++tn_; \ + if (tn_->catchStart) \ + catchpc_ = (script)->main + tn_->catchStart; \ + } \ + } \ + catchpc = catchpc_; \ + JS_END_MACRO + +extern JS_FRIEND_DATA(JSClass) js_ScriptClass; + +extern JSObject * +js_InitScriptClass(JSContext *cx, JSObject *obj); + +extern JSBool +js_InitScriptGlobals(); + +extern void +js_FreeScriptGlobals(); + +extern const char * +js_SaveScriptFilename(JSContext *cx, const char *filename); + +extern void +js_MarkScriptFilename(const char *filename); + +extern void +js_SweepScriptFilenames(JSRuntime *rt); + +/* + * Two successively less primitive ways to make a new JSScript. The first + * does *not* call a non-null cx->runtime->newScriptHook -- only the second, + * js_NewScriptFromCG, calls this optional debugger hook. + * + * The js_NewScript function can't know whether the script it creates belongs + * to a function, or is top-level or eval code, but the debugger wants access + * to the newly made script's function, if any -- so callers of js_NewScript + * are responsible for notifying the debugger after successfully creating any + * kind (function or other) of new JSScript. + */ +extern JSScript * +js_NewScript(JSContext *cx, uint32 length, uint32 snlength, uint32 tnlength); + +extern JS_FRIEND_API(JSScript *) +js_NewScriptFromCG(JSContext *cx, JSCodeGenerator *cg, JSFunction *fun); + +/* + * New-script-hook calling is factored from js_NewScriptFromCG so that it + * and callers of js_XDRScript can share this code. In the case of callers + * of js_XDRScript, the hook should be invoked only after successful decode + * of any owning function (the fun parameter) or script object (null fun). + */ +extern JS_FRIEND_API(void) +js_CallNewScriptHook(JSContext *cx, JSScript *script, JSFunction *fun); + +extern void +js_DestroyScript(JSContext *cx, JSScript *script); + +extern void +js_MarkScript(JSContext *cx, JSScript *script, void *arg); + +extern jssrcnote * +js_GetSrcNote(JSScript *script, jsbytecode *pc); + +/* XXX need cx to lock function objects declared by prolog bytecodes. */ +extern uintN +js_PCToLineNumber(JSContext *cx, JSScript *script, jsbytecode *pc); + +extern jsbytecode * +js_LineNumberToPC(JSScript *script, uintN lineno); + +extern uintN +js_GetScriptLineExtent(JSScript *script); + +/* + * If magic is non-null, js_XDRScript succeeds on magic number mismatch but + * returns false in *magic; it reflects a match via a true *magic out param. + * If magic is null, js_XDRScript returns false on bad magic number errors, + * which it reports. + * + * NB: callers must call js_CallNewScriptHook after successful JSXDR_DECODE + * and subsequent set-up of owning function or script object, if any. + */ +extern JSBool +js_XDRScript(JSXDRState *xdr, JSScript **scriptp, JSBool *magic); + +JS_END_EXTERN_C + +#endif /* jsscript_h___ */ diff --git a/src/dom/js/jsshell.msg b/src/dom/js/jsshell.msg new file mode 100644 index 000000000..4b811ac01 --- /dev/null +++ b/src/dom/js/jsshell.msg @@ -0,0 +1,50 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* + Error messages for JSShell. See js.msg for format. +*/ + +MSG_DEF(JSSMSG_NOT_AN_ERROR, 0, 0, JSEXN_NONE, "") +MSG_DEF(JSSMSG_CANT_OPEN, 1, 2, JSEXN_NONE, "can't open {0}: {1}") +MSG_DEF(JSSMSG_TRAP_USAGE, 2, 0, JSEXN_NONE, "usage: trap [fun] [pc] expr") +MSG_DEF(JSSMSG_LINE2PC_USAGE, 3, 0, JSEXN_NONE, "usage: line2pc [fun] line") +MSG_DEF(JSSMSG_FILE_SCRIPTS_ONLY, 4, 0, JSEXN_NONE, "only works on JS scripts read from files") +MSG_DEF(JSSMSG_UNEXPECTED_EOF, 5, 1, JSEXN_NONE, "unexpected EOF in {0}") +MSG_DEF(JSSMSG_DOEXP_USAGE, 6, 0, JSEXN_NONE, "usage: doexp obj id") diff --git a/src/dom/js/jsstddef.h b/src/dom/js/jsstddef.h new file mode 100644 index 000000000..0d87b0c0c --- /dev/null +++ b/src/dom/js/jsstddef.h @@ -0,0 +1,83 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* + * stddef inclusion here to first declare ptrdif as a signed long instead of a + * signed int. + */ + +#ifdef _WINDOWS +# ifndef XP_WIN +# define XP_WIN +# endif +#if defined(_WIN32) || defined(WIN32) +# ifndef XP_WIN32 +# define XP_WIN32 +# endif +#else +# ifndef XP_WIN16 +# define XP_WIN16 +# endif +#endif +#endif + +#ifdef XP_WIN16 +#ifndef _PTRDIFF_T_DEFINED +typedef long ptrdiff_t; + +/* + * The Win16 compiler treats pointer differences as 16-bit signed values. + * This macro allows us to treat them as 17-bit signed values, stored in + * a 32-bit type. + */ +#define PTRDIFF(p1, p2, type) \ + ((((unsigned long)(p1)) - ((unsigned long)(p2))) / sizeof(type)) + +#define _PTRDIFF_T_DEFINED +#endif /*_PTRDIFF_T_DEFINED*/ +#else /*WIN16*/ + +#define PTRDIFF(p1, p2, type) \ + ((p1) - (p2)) + +#endif + +#include + + diff --git a/src/dom/js/jsstr.c b/src/dom/js/jsstr.c new file mode 100644 index 000000000..e143ab8df --- /dev/null +++ b/src/dom/js/jsstr.c @@ -0,0 +1,4502 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* + * JS string type implementation. + * + * In order to avoid unnecessary js_LockGCThing/js_UnlockGCThing calls, these + * native methods store strings (possibly newborn) converted from their 'this' + * parameter and arguments on the stack: 'this' conversions at argv[-1], arg + * conversions at their index (argv[0], argv[1]). This is a legitimate method + * of rooting things that might lose their newborn root due to subsequent GC + * allocations in the same native method. + */ +#include "jsstddef.h" +#include +#include +#include "jstypes.h" +#include "jsutil.h" /* Added by JSIFY */ +#include "jshash.h" /* Added by JSIFY */ +#include "jsprf.h" +#include "jsapi.h" +#include "jsarray.h" +#include "jsatom.h" +#include "jsbool.h" +#include "jscntxt.h" +#include "jsconfig.h" +#include "jsgc.h" +#include "jsinterp.h" +#include "jslock.h" +#include "jsnum.h" +#include "jsobj.h" +#include "jsopcode.h" +#include "jsregexp.h" +#include "jsstr.h" + +#if JS_HAS_REPLACE_LAMBDA +#include "jsinterp.h" +#endif + +#define JSSTRDEP_RECURSION_LIMIT 100 + +size_t +js_MinimizeDependentStrings(JSString *str, int level, JSString **basep) +{ + JSString *base; + size_t start, length; + + JS_ASSERT(JSSTRING_IS_DEPENDENT(str)); + base = JSSTRDEP_BASE(str); + start = JSSTRDEP_START(str); + if (JSSTRING_IS_DEPENDENT(base)) { + if (level < JSSTRDEP_RECURSION_LIMIT) { + start += js_MinimizeDependentStrings(base, level + 1, &base); + } else { + do { + start += JSSTRDEP_START(base); + base = JSSTRDEP_BASE(base); + } while (JSSTRING_IS_DEPENDENT(base)); + } + if (start == 0) { + JS_ASSERT(JSSTRING_IS_PREFIX(str)); + JSPREFIX_SET_BASE(str, base); + } else if (start <= JSSTRDEP_START_MASK) { + length = JSSTRDEP_LENGTH(str); + JSSTRDEP_SET_START_AND_LENGTH(str, start, length); + JSSTRDEP_SET_BASE(str, base); + } + } + *basep = base; + return start; +} + +jschar * +js_GetDependentStringChars(JSString *str) +{ + size_t start; + JSString *base; + + start = js_MinimizeDependentStrings(str, 0, &base); + JS_ASSERT(!JSSTRING_IS_DEPENDENT(base)); + JS_ASSERT(start < base->length); + return base->chars + start; +} + +jschar * +js_GetStringChars(JSString *str) +{ + if (JSSTRING_IS_DEPENDENT(str) && !js_UndependString(NULL, str)) + return NULL; + + *js_GetGCThingFlags(str) &= ~GCF_MUTABLE; + return str->chars; +} + +JSString * +js_ConcatStrings(JSContext *cx, JSString *left, JSString *right) +{ + size_t rn, ln, lrdist, n; + jschar *rs, *ls, *s; + JSDependentString *ldep; /* non-null if left should become dependent */ + JSString *str; + + if (JSSTRING_IS_DEPENDENT(right)) { + rn = JSSTRDEP_LENGTH(right); + rs = JSSTRDEP_CHARS(right); + } else { + rn = right->length; + rs = right->chars; + } + if (rn == 0) + return left; + + if (JSSTRING_IS_DEPENDENT(left) || + !(*js_GetGCThingFlags(left) & GCF_MUTABLE)) { + /* We must copy if left does not own a buffer to realloc. */ + ln = JSSTRING_LENGTH(left); + if (ln == 0) + return right; + ls = JSSTRING_CHARS(left); + s = (jschar *) JS_malloc(cx, (ln + rn + 1) * sizeof(jschar)); + if (!s) + return NULL; + js_strncpy(s, ls, ln); + ldep = NULL; + } else { + /* We can realloc left's space and make it depend on our result. */ + ln = left->length; + if (ln == 0) + return right; + ls = left->chars; + s = (jschar *) JS_realloc(cx, ls, (ln + rn + 1) * sizeof(jschar)); + if (!s) + return NULL; + + /* Take care: right could depend on left! */ + lrdist = (size_t)(rs - ls); + if (lrdist < ln) + rs = s + lrdist; + left->chars = ls = s; + ldep = JSSTRDEP(left); + } + + js_strncpy(s + ln, rs, rn); + n = ln + rn; + s[n] = 0; + str = js_NewString(cx, s, n, GCF_MUTABLE); + if (!str) { + /* Out of memory: clean up any space we (re-)allocated. */ + if (!ldep) { + JS_free(cx, s); + } else { + s = JS_realloc(cx, ls, (ln + 1) * sizeof(jschar)); + if (s) + left->chars = s; + } + } else { + /* Morph left into a dependent prefix if we realloc'd its buffer. */ + if (ldep) { + JSPREFIX_SET_LENGTH(ldep, ln); + JSPREFIX_SET_BASE(ldep, str); +#ifdef DEBUG + { + JSRuntime *rt = cx->runtime; + JS_RUNTIME_METER(rt, liveDependentStrings); + JS_RUNTIME_METER(rt, totalDependentStrings); + JS_LOCK_RUNTIME_VOID(rt, + (rt->strdepLengthSum += (double)ln, + rt->strdepLengthSquaredSum += (double)ln * (double)ln)); + } +#endif + } + } + + return str; +} + +/* + * May be called with null cx by js_GetStringChars, above; and by the jslock.c + * MAKE_STRING_IMMUTABLE file-local macro. + */ +const jschar * +js_UndependString(JSContext *cx, JSString *str) +{ + size_t n, size; + jschar *s; + + if (JSSTRING_IS_DEPENDENT(str)) { + n = JSSTRDEP_LENGTH(str); + size = (n + 1) * sizeof(jschar); + s = (jschar *) (cx ? JS_malloc(cx, size) : malloc(size)); + if (!s) + return NULL; + + js_strncpy(s, JSSTRDEP_CHARS(str), n); + s[n] = 0; + str->length = n; + str->chars = s; + +#ifdef DEBUG + if (cx) { + JSRuntime *rt = cx->runtime; + JS_RUNTIME_UNMETER(rt, liveDependentStrings); + JS_RUNTIME_UNMETER(rt, totalDependentStrings); + JS_LOCK_RUNTIME_VOID(rt, + (rt->strdepLengthSum -= (double)n, + rt->strdepLengthSquaredSum -= (double)n * (double)n)); + } +#endif + } + + return str->chars; +} + +/* + * Forward declarations for URI encode/decode and helper routines + */ +static JSBool +str_decodeURI(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval); + +static JSBool +str_decodeURI_Component(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval); + +static JSBool +str_encodeURI(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval); + +static JSBool +str_encodeURI_Component(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval); + +static int +OneUcs4ToUtf8Char(uint8 *utf8Buffer, uint32 ucs4Char); + +static uint32 +Utf8ToOneUcs4Char(const uint8 *utf8Buffer, int utf8Length); + +/* + * Contributions from the String class to the set of methods defined for the + * global object. escape and unescape used to be defined in the Mocha library, + * but as ECMA decided to spec them, they've been moved to the core engine + * and made ECMA-compliant. (Incomplete escapes are interpreted as literal + * characters by unescape.) + */ + +/* + * Stuff to emulate the old libmocha escape, which took a second argument + * giving the type of escape to perform. Retained for compatibility, and + * copied here to avoid reliance on net.h, mkparse.c/NET_EscapeBytes. + */ + +#define URL_XALPHAS ((uint8) 1) +#define URL_XPALPHAS ((uint8) 2) +#define URL_PATH ((uint8) 4) + +static const uint8 urlCharType[256] = +/* Bit 0 xalpha -- the alphas + * Bit 1 xpalpha -- as xalpha but + * converts spaces to plus and plus to %20 + * Bit 2 ... path -- as xalphas but doesn't escape '/' + */ + /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ + { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x */ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1x */ + 0,0,0,0,0,0,0,0,0,0,7,4,0,7,7,4, /* 2x !"#$%&'()*+,-./ */ + 7,7,7,7,7,7,7,7,7,7,0,0,0,0,0,0, /* 3x 0123456789:;<=>? */ + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, /* 4x @ABCDEFGHIJKLMNO */ + 7,7,7,7,7,7,7,7,7,7,7,0,0,0,0,7, /* 5X PQRSTUVWXYZ[\]^_ */ + 0,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, /* 6x `abcdefghijklmno */ + 7,7,7,7,7,7,7,7,7,7,7,0,0,0,0,0, /* 7X pqrstuvwxyz{\}~ DEL */ + 0, }; + +/* This matches the ECMA escape set when mask is 7 (default.) */ + +#define IS_OK(C, mask) (urlCharType[((uint8) (C))] & (mask)) + +/* See ECMA-262 15.1.2.4. */ +JSBool +js_str_escape(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + JSString *str; + size_t i, ni, length, newlength; + const jschar *chars; + jschar *newchars; + jschar ch; + jsint mask; + jsdouble d; + const char digits[] = {'0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; + + mask = URL_XALPHAS | URL_XPALPHAS | URL_PATH; + if (argc > 1) { + if (!js_ValueToNumber(cx, argv[1], &d)) + return JS_FALSE; + if (!JSDOUBLE_IS_FINITE(d) || + (mask = (jsint)d) != d || + mask & ~(URL_XALPHAS | URL_XPALPHAS | URL_PATH)) + { + char numBuf[12]; + JS_snprintf(numBuf, sizeof numBuf, "%lx", (unsigned long) mask); + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, + JSMSG_BAD_STRING_MASK, numBuf); + return JS_FALSE; + } + } + + str = js_ValueToString(cx, argv[0]); + if (!str) + return JS_FALSE; + argv[0] = STRING_TO_JSVAL(str); + + chars = JSSTRING_CHARS(str); + length = newlength = JSSTRING_LENGTH(str); + + /* Take a first pass and see how big the result string will need to be. */ + for (i = 0; i < length; i++) { + if ((ch = chars[i]) < 128 && IS_OK(ch, mask)) + continue; + if (ch < 256) { + if (mask == URL_XPALPHAS && ch == ' ') + continue; /* The character will be encoded as '+' */ + newlength += 2; /* The character will be encoded as %XX */ + } else { + newlength += 5; /* The character will be encoded as %uXXXX */ + } + } + + newchars = (jschar *) JS_malloc(cx, (newlength + 1) * sizeof(jschar)); + if (!newchars) + return JS_FALSE; + for (i = 0, ni = 0; i < length; i++) { + if ((ch = chars[i]) < 128 && IS_OK(ch, mask)) { + newchars[ni++] = ch; + } else if (ch < 256) { + if (mask == URL_XPALPHAS && ch == ' ') { + newchars[ni++] = '+'; /* convert spaces to pluses */ + } else { + newchars[ni++] = '%'; + newchars[ni++] = digits[ch >> 4]; + newchars[ni++] = digits[ch & 0xF]; + } + } else { + newchars[ni++] = '%'; + newchars[ni++] = 'u'; + newchars[ni++] = digits[ch >> 12]; + newchars[ni++] = digits[(ch & 0xF00) >> 8]; + newchars[ni++] = digits[(ch & 0xF0) >> 4]; + newchars[ni++] = digits[ch & 0xF]; + } + } + JS_ASSERT(ni == newlength); + newchars[newlength] = 0; + + str = js_NewString(cx, newchars, newlength, 0); + if (!str) { + JS_free(cx, newchars); + return JS_FALSE; + } + *rval = STRING_TO_JSVAL(str); + return JS_TRUE; +} +#undef IS_OK + +/* See ECMA-262 15.1.2.5 */ +static JSBool +str_unescape(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + JSString *str; + size_t i, ni, length; + const jschar *chars; + jschar *newchars; + jschar ch; + + str = js_ValueToString(cx, argv[0]); + if (!str) + return JS_FALSE; + argv[0] = STRING_TO_JSVAL(str); + + chars = JSSTRING_CHARS(str); + length = JSSTRING_LENGTH(str); + + /* Don't bother allocating less space for the new string. */ + newchars = (jschar *) JS_malloc(cx, (length + 1) * sizeof(jschar)); + if (!newchars) + return JS_FALSE; + ni = i = 0; + while (i < length) { + ch = chars[i++]; + if (ch == '%') { + if (i + 1 < length && + JS7_ISHEX(chars[i]) && JS7_ISHEX(chars[i + 1])) + { + ch = JS7_UNHEX(chars[i]) * 16 + JS7_UNHEX(chars[i + 1]); + i += 2; + } else if (i + 4 < length && chars[i] == 'u' && + JS7_ISHEX(chars[i + 1]) && JS7_ISHEX(chars[i + 2]) && + JS7_ISHEX(chars[i + 3]) && JS7_ISHEX(chars[i + 4])) + { + ch = (((((JS7_UNHEX(chars[i + 1]) << 4) + + JS7_UNHEX(chars[i + 2])) << 4) + + JS7_UNHEX(chars[i + 3])) << 4) + + JS7_UNHEX(chars[i + 4]); + i += 5; + } + } + newchars[ni++] = ch; + } + newchars[ni] = 0; + + str = js_NewString(cx, newchars, ni, 0); + if (!str) { + JS_free(cx, newchars); + return JS_FALSE; + } + *rval = STRING_TO_JSVAL(str); + return JS_TRUE; +} + +#if JS_HAS_UNEVAL +static JSBool +str_uneval(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + JSString *str; + + str = js_ValueToSource(cx, argv[0]); + if (!str) + return JS_FALSE; + *rval = STRING_TO_JSVAL(str); + return JS_TRUE; +} +#endif + +const char js_escape_str[] = "escape"; +const char js_unescape_str[] = "unescape"; +#if JS_HAS_UNEVAL +const char js_uneval_str[] = "uneval"; +#endif +const char js_decodeURI_str[] = "decodeURI"; +const char js_encodeURI_str[] = "encodeURI"; +const char js_decodeURIComponent_str[] = "decodeURIComponent"; +const char js_encodeURIComponent_str[] = "encodeURIComponent"; + +static JSFunctionSpec string_functions[] = { + {js_escape_str, js_str_escape, 1,0,0}, + {js_unescape_str, str_unescape, 1,0,0}, +#if JS_HAS_UNEVAL + {js_uneval_str, str_uneval, 1,0,0}, +#endif + {js_decodeURI_str, str_decodeURI, 1,0,0}, + {js_encodeURI_str, str_encodeURI, 1,0,0}, + {js_decodeURIComponent_str, str_decodeURI_Component, 1,0,0}, + {js_encodeURIComponent_str, str_encodeURI_Component, 1,0,0}, + + {0,0,0,0,0} +}; + +jschar js_empty_ucstr[] = {0}; +JSSubString js_EmptySubString = {0, js_empty_ucstr}; + +enum string_tinyid { + STRING_LENGTH = -1 +}; + +static JSPropertySpec string_props[] = { + {js_length_str, STRING_LENGTH, + JSPROP_READONLY|JSPROP_PERMANENT|JSPROP_SHARED, 0,0}, + {0,0,0,0,0} +}; + +static JSBool +str_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp) +{ + JSString *str; + jsint slot; + + if (!JSVAL_IS_INT(id)) + return JS_TRUE; + str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj)); + if (!str) + return JS_FALSE; + slot = JSVAL_TO_INT(id); + if (slot == STRING_LENGTH) + *vp = INT_TO_JSVAL((jsint) JSSTRING_LENGTH(str)); + return JS_TRUE; +} + +#define STRING_ELEMENT_ATTRS (JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT) + +static JSBool +str_enumerate(JSContext *cx, JSObject *obj) +{ + JSString *str, *str1; + size_t i, length; + + str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj)); + if (!str) + return JS_FALSE; + length = JSSTRING_LENGTH(str); + for (i = 0; i < length; i++) { + str1 = js_NewDependentString(cx, str, i, 1, 0); + if (!str1) + return JS_FALSE; + if (!OBJ_DEFINE_PROPERTY(cx, obj, INT_TO_JSVAL(i), + STRING_TO_JSVAL(str1), NULL, NULL, + STRING_ELEMENT_ATTRS, NULL)) { + return JS_FALSE; + } + } + return JS_TRUE; +} + +static JSBool +str_resolve(JSContext *cx, JSObject *obj, jsval id) +{ + JSString *str, *str1; + jsint slot; + + if (!JSVAL_IS_INT(id)) + return JS_TRUE; + + str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj)); + if (!str) + return JS_FALSE; + slot = JSVAL_TO_INT(id); + if ((size_t)slot < JSSTRING_LENGTH(str)) { + str1 = js_NewDependentString(cx, str, (size_t)slot, 1, 0); + if (!str1) + return JS_FALSE; + if (!OBJ_DEFINE_PROPERTY(cx, obj, INT_TO_JSVAL(slot), + STRING_TO_JSVAL(str1), NULL, NULL, + STRING_ELEMENT_ATTRS, NULL)) { + return JS_FALSE; + } + } + return JS_TRUE; +} + +static JSClass string_class = { + js_String_str, + JSCLASS_HAS_PRIVATE, + JS_PropertyStub, JS_PropertyStub, str_getProperty, JS_PropertyStub, + str_enumerate, str_resolve, JS_ConvertStub, JS_FinalizeStub, + JSCLASS_NO_OPTIONAL_MEMBERS +}; + +#if JS_HAS_TOSOURCE + +/* + * String.prototype.quote is generic (as are most string methods), unlike + * toSource, toString, and valueOf. + */ +static JSBool +str_quote(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + JSString *str; + + str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj)); + if (!str) + return JS_FALSE; + str = js_QuoteString(cx, str, '"'); + if (!str) + return JS_FALSE; + *rval = STRING_TO_JSVAL(str); + return JS_TRUE; +} + +static JSBool +str_toSource(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + jsval v; + JSString *str; + size_t i, j, k, n; + char buf[16]; + jschar *s, *t; + + if (!JS_InstanceOf(cx, obj, &string_class, argv)) + return JS_FALSE; + v = OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE); + if (!JSVAL_IS_STRING(v)) + return js_obj_toSource(cx, obj, argc, argv, rval); + str = js_QuoteString(cx, JSVAL_TO_STRING(v), '"'); + if (!str) + return JS_FALSE; + j = JS_snprintf(buf, sizeof buf, "(new %s(", string_class.name); + s = JSSTRING_CHARS(str); + k = JSSTRING_LENGTH(str); + n = j + k + 2; + t = (jschar *) JS_malloc(cx, (n + 1) * sizeof(jschar)); + if (!t) + return JS_FALSE; + for (i = 0; i < j; i++) + t[i] = buf[i]; + for (j = 0; j < k; i++, j++) + t[i] = s[j]; + t[i++] = ')'; + t[i++] = ')'; + t[i] = 0; + str = js_NewString(cx, t, n, 0); + if (!str) { + JS_free(cx, t); + return JS_FALSE; + } + *rval = STRING_TO_JSVAL(str); + return JS_TRUE; +} + +#endif /* JS_HAS_TOSOURCE */ + +static JSBool +str_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + jsval v; + + if (!JS_InstanceOf(cx, obj, &string_class, argv)) + return JS_FALSE; + v = OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE); + if (!JSVAL_IS_STRING(v)) + return js_obj_toString(cx, obj, argc, argv, rval); + *rval = v; + return JS_TRUE; +} + +static JSBool +str_valueOf(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + if (!JS_InstanceOf(cx, obj, &string_class, argv)) + return JS_FALSE; + *rval = OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE); + return JS_TRUE; +} + +/* + * Java-like string native methods. + */ +static JSBool +str_substring(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval) +{ + JSString *str; + jsdouble d; + jsdouble length, begin, end; + + str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj)); + if (!str) + return JS_FALSE; + argv[-1] = STRING_TO_JSVAL(str); + + if (argc != 0) { + if (!js_ValueToNumber(cx, argv[0], &d)) + return JS_FALSE; + length = JSSTRING_LENGTH(str); + begin = js_DoubleToInteger(d); + if (begin < 0) + begin = 0; + else if (begin > length) + begin = length; + + if (argc == 1) { + end = length; + } else { + if (!js_ValueToNumber(cx, argv[1], &d)) + return JS_FALSE; + end = js_DoubleToInteger(d); + if (end < 0) + end = 0; + else if (end > length) + end = length; + if (end < begin) { + if (cx->version != JSVERSION_1_2) { + /* XXX emulate old JDK1.0 java.lang.String.substring. */ + jsdouble tmp = begin; + begin = end; + end = tmp; + } else { + end = begin; + } + } + } + + str = js_NewDependentString(cx, str, (size_t)begin, + (size_t)(end - begin), 0); + if (!str) + return JS_FALSE; + } + *rval = STRING_TO_JSVAL(str); + return JS_TRUE; +} + +static JSBool +str_toLowerCase(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval) +{ + JSString *str; + size_t i, n; + jschar *s, *news; + + str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj)); + if (!str) + return JS_FALSE; + n = JSSTRING_LENGTH(str); + news = (jschar *) JS_malloc(cx, (n + 1) * sizeof(jschar)); + if (!news) + return JS_FALSE; + s = JSSTRING_CHARS(str); + for (i = 0; i < n; i++) + news[i] = JS_TOLOWER(s[i]); + news[n] = 0; + str = js_NewString(cx, news, n, 0); + if (!str) { + JS_free(cx, news); + return JS_FALSE; + } + *rval = STRING_TO_JSVAL(str); + return JS_TRUE; +} + +static JSBool +str_toLocaleLowerCase(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval) +{ + JSString *str; + + /* + * Forcefully ignore the first (or any) argument and return toLowerCase(), + * ECMA has reserved that argument, presumably for defining the locale. + */ + if (cx->localeCallbacks && cx->localeCallbacks->localeToLowerCase) { + str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj)); + if (!str) + return JS_FALSE; + return cx->localeCallbacks->localeToLowerCase(cx, str, rval); + } + return str_toLowerCase(cx, obj, 0, argv, rval); +} + +static JSBool +str_toUpperCase(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval) +{ + JSString *str; + size_t i, n; + jschar *s, *news; + + str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj)); + if (!str) + return JS_FALSE; + n = JSSTRING_LENGTH(str); + news = (jschar *) JS_malloc(cx, (n + 1) * sizeof(jschar)); + if (!news) + return JS_FALSE; + s = JSSTRING_CHARS(str); + for (i = 0; i < n; i++) + news[i] = JS_TOUPPER(s[i]); + news[n] = 0; + str = js_NewString(cx, news, n, 0); + if (!str) { + JS_free(cx, news); + return JS_FALSE; + } + *rval = STRING_TO_JSVAL(str); + return JS_TRUE; +} + +static JSBool +str_toLocaleUpperCase(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval) +{ + JSString *str; + + /* + * Forcefully ignore the first (or any) argument and return toUpperCase(), + * ECMA has reserved that argument, presumbaly for defining the locale. + */ + if (cx->localeCallbacks && cx->localeCallbacks->localeToUpperCase) { + str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj)); + if (!str) + return JS_FALSE; + return cx->localeCallbacks->localeToUpperCase(cx, str, rval); + } + return str_toUpperCase(cx, obj, 0, argv, rval); +} + +static JSBool +str_localeCompare(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval) +{ + JSString *str, *thatStr; + + str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj)); + if (!str) + return JS_FALSE; + argv[-1] = STRING_TO_JSVAL(str); + + if (argc == 0) { + *rval = JSVAL_ZERO; + } else { + thatStr = js_ValueToString(cx, argv[0]); + if (!thatStr) + return JS_FALSE; + if (cx->localeCallbacks && cx->localeCallbacks->localeCompare) + return cx->localeCallbacks->localeCompare(cx, str, thatStr, rval); + *rval = INT_TO_JSVAL(js_CompareStrings(str, thatStr)); + } + return JS_TRUE; +} + +static JSBool +str_charAt(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + JSString *str; + jsdouble d; + size_t index; + + str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj)); + if (!str) + return JS_FALSE; + argv[-1] = STRING_TO_JSVAL(str); + + if (argc == 0) { + d = 0.0; + } else { + if (!js_ValueToNumber(cx, argv[0], &d)) + return JS_FALSE; + d = js_DoubleToInteger(d); + } + + if (d < 0 || JSSTRING_LENGTH(str) <= d) { + *rval = JS_GetEmptyStringValue(cx); + } else { + index = (size_t)d; + str = js_NewDependentString(cx, str, index, 1, 0); + if (!str) + return JS_FALSE; + *rval = STRING_TO_JSVAL(str); + } + return JS_TRUE; +} + +static JSBool +str_charCodeAt(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval) +{ + JSString *str; + jsdouble d; + size_t index; + + str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj)); + if (!str) + return JS_FALSE; + argv[-1] = STRING_TO_JSVAL(str); + + if (argc == 0) { + d = 0.0; + } else { + if (!js_ValueToNumber(cx, argv[0], &d)) + return JS_FALSE; + d = js_DoubleToInteger(d); + } + + if (d < 0 || JSSTRING_LENGTH(str) <= d) { + *rval = JS_GetNaNValue(cx); + } else { + index = (size_t)d; + *rval = INT_TO_JSVAL((jsint) JSSTRING_CHARS(str)[index]); + } + return JS_TRUE; +} + +jsint +js_BoyerMooreHorspool(const jschar *text, jsint textlen, + const jschar *pat, jsint patlen, + jsint start) +{ + jsint i, j, k, m; + uint8 skip[BMH_CHARSET_SIZE]; + jschar c; + + JS_ASSERT(0 < patlen && patlen <= BMH_PATLEN_MAX); + for (i = 0; i < BMH_CHARSET_SIZE; i++) + skip[i] = (uint8)patlen; + m = patlen - 1; + for (i = 0; i < m; i++) { + c = pat[i]; + if (c >= BMH_CHARSET_SIZE) + return BMH_BAD_PATTERN; + skip[c] = (uint8)(m - i); + } + for (k = start + m; + k < textlen; + k += ((c = text[k]) >= BMH_CHARSET_SIZE) ? patlen : skip[c]) { + for (i = k, j = m; ; i--, j--) { + if (j < 0) + return i + 1; + if (text[i] != pat[j]) + break; + } + } + return -1; +} + +static JSBool +str_indexOf(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + JSString *str, *str2; + jsint i, j, index, textlen, patlen; + const jschar *text, *pat; + jsdouble d; + + str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj)); + if (!str) + return JS_FALSE; + argv[-1] = STRING_TO_JSVAL(str); + text = JSSTRING_CHARS(str); + textlen = (jsint) JSSTRING_LENGTH(str); + + str2 = js_ValueToString(cx, argv[0]); + if (!str2) + return JS_FALSE; + argv[0] = STRING_TO_JSVAL(str2); + pat = JSSTRING_CHARS(str2); + patlen = (jsint) JSSTRING_LENGTH(str2); + + if (argc > 1) { + if (!js_ValueToNumber(cx, argv[1], &d)) + return JS_FALSE; + d = js_DoubleToInteger(d); + if (d < 0) + i = 0; + else if (d > textlen) + i = textlen; + else + i = (jsint)d; + } else { + i = 0; + } + if (patlen == 0) { + *rval = INT_TO_JSVAL(i); + return JS_TRUE; + } + + /* XXX tune the BMH threshold (512) */ + if ((jsuint)(patlen - 2) <= BMH_PATLEN_MAX - 2 && textlen >= 512) { + index = js_BoyerMooreHorspool(text, textlen, pat, patlen, i); + if (index != BMH_BAD_PATTERN) + goto out; + } + + index = -1; + j = 0; + while (i + j < textlen) { + if (text[i + j] == pat[j]) { + if (++j == patlen) { + index = i; + break; + } + } else { + i++; + j = 0; + } + } + +out: + *rval = INT_TO_JSVAL(index); + return JS_TRUE; +} + +static JSBool +str_lastIndexOf(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval) +{ + JSString *str, *str2; + const jschar *text, *pat; + jsint i, j, textlen, patlen; + jsdouble d; + + str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj)); + if (!str) + return JS_FALSE; + argv[-1] = STRING_TO_JSVAL(str); + text = JSSTRING_CHARS(str); + textlen = (jsint) JSSTRING_LENGTH(str); + + str2 = js_ValueToString(cx, argv[0]); + if (!str2) + return JS_FALSE; + argv[0] = STRING_TO_JSVAL(str2); + pat = JSSTRING_CHARS(str2); + patlen = (jsint) JSSTRING_LENGTH(str2); + + if (argc > 1) { + if (!js_ValueToNumber(cx, argv[1], &d)) + return JS_FALSE; + if (JSDOUBLE_IS_NaN(d)) { + i = textlen; + } else { + d = js_DoubleToInteger(d); + if (d < 0) + i = 0; + else if (d > textlen - patlen) + i = textlen - patlen; + else + i = (jsint)d; + } + } else { + i = textlen; + } + + if (patlen == 0) { + *rval = INT_TO_JSVAL(i); + return JS_TRUE; + } + + j = 0; + while (i >= 0) { + /* Don't assume that text is NUL-terminated: it could be dependent. */ + if (i + j < textlen && text[i + j] == pat[j]) { + if (++j == patlen) + break; + } else { + i--; + j = 0; + } + } + *rval = INT_TO_JSVAL(i); + return JS_TRUE; +} + +/* + * Perl-inspired string functions. + */ +#if JS_HAS_REGEXPS +typedef struct GlobData { + uintN flags; /* inout: mode and flag bits, see below */ + uintN optarg; /* in: index of optional flags argument */ + JSString *str; /* out: 'this' parameter object as string */ + JSRegExp *regexp; /* out: regexp parameter object private data */ +} GlobData; + +/* + * Mode and flag bit definitions for match_or_replace's GlobData.flags field. + */ +#define MODE_MATCH 0x00 /* in: return match array on success */ +#define MODE_REPLACE 0x01 /* in: match and replace */ +#define MODE_SEARCH 0x02 /* in: search only, return match index or -1 */ +#define GET_MODE(f) ((f) & 0x03) +#define FORCE_FLAT 0x04 /* in: force flat (non-regexp) string match */ +#define KEEP_REGEXP 0x08 /* inout: keep GlobData.regexp alive for caller + of match_or_replace; if set on input + but clear on output, regexp ownership + does not pass to caller */ +#define GLOBAL_REGEXP 0x10 /* out: regexp had the 'g' flag */ + +static JSBool +match_or_replace(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + JSBool (*glob)(JSContext *cx, jsint count, GlobData *data), + GlobData *data, jsval *rval) +{ + JSString *str, *src, *opt; + JSObject *reobj; + JSRegExp *re; + size_t index, length; + JSBool ok, test; + jsint count; + + str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj)); + if (!str) + return JS_FALSE; + argv[-1] = STRING_TO_JSVAL(str); + data->str = str; + + if (JSVAL_IS_REGEXP(cx, argv[0])) { + reobj = JSVAL_TO_OBJECT(argv[0]); + re = (JSRegExp *) JS_GetPrivate(cx, reobj); + } else { + src = js_ValueToString(cx, argv[0]); + if (!src) + return JS_FALSE; + if (data->optarg < argc) { + argv[0] = STRING_TO_JSVAL(src); + opt = js_ValueToString(cx, argv[data->optarg]); + if (!opt) + return JS_FALSE; + } else { + opt = NULL; + } + re = js_NewRegExpOpt(cx, NULL, src, opt, + (data->flags & FORCE_FLAT) != 0); + if (!re) + return JS_FALSE; + reobj = NULL; + } + data->regexp = re; + + if (re->flags & JSREG_GLOB) + data->flags |= GLOBAL_REGEXP; + index = 0; + if (GET_MODE(data->flags) == MODE_SEARCH) { + ok = js_ExecuteRegExp(cx, re, str, &index, JS_TRUE, rval); + if (ok) { + *rval = (*rval == JSVAL_TRUE) + ? INT_TO_JSVAL(cx->regExpStatics.leftContext.length) + : INT_TO_JSVAL(-1); + } + } else if (data->flags & GLOBAL_REGEXP) { + if (reobj) { + /* Set the lastIndex property's reserved slot to 0. */ + ok = js_SetLastIndex(cx, reobj, 0); + if (!ok) + return JS_FALSE; + } else { + ok = JS_TRUE; + } + length = JSSTRING_LENGTH(str); + for (count = 0; index <= length; count++) { + ok = js_ExecuteRegExp(cx, re, str, &index, JS_TRUE, rval); + if (!ok || *rval != JSVAL_TRUE) + break; + ok = glob(cx, count, data); + if (!ok) + break; + if (cx->regExpStatics.lastMatch.length == 0) { + if (index == length) + break; + index++; + } + } + } else { + if (GET_MODE(data->flags) == MODE_REPLACE) { + test = JS_TRUE; + } else { + /* + * MODE_MATCH implies str_match is being called from a script or a + * scripted function. If the caller cares only about testing null + * vs. non-null return value, optimize away the array object that + * would normally be returned in *rval. + */ + JS_ASSERT(*cx->fp->down->pc == JSOP_CALL || + *cx->fp->down->pc == JSOP_NEW); + JS_ASSERT(js_CodeSpec[*cx->fp->down->pc].length == 3); + switch (cx->fp->down->pc[3]) { + case JSOP_POP: + case JSOP_IFEQ: + case JSOP_IFNE: + case JSOP_IFEQX: + case JSOP_IFNEX: + test = JS_TRUE; + break; + default: + test = JS_FALSE; + break; + } + } + ok = js_ExecuteRegExp(cx, re, str, &index, test, rval); + } + + if (reobj) { + /* Tell our caller that it doesn't need to destroy data->regexp. */ + data->flags &= ~KEEP_REGEXP; + } else if (!(data->flags & KEEP_REGEXP)) { + /* Caller didn't want to keep data->regexp, so null and destroy it. */ + data->regexp = NULL; + js_DestroyRegExp(cx, re); + } + return ok; +} + +typedef struct MatchData { + GlobData base; + jsval *arrayval; /* NB: local root pointer */ +} MatchData; + +static JSBool +match_glob(JSContext *cx, jsint count, GlobData *data) +{ + MatchData *mdata; + JSObject *arrayobj; + JSSubString *matchsub; + JSString *matchstr; + jsval v; + + mdata = (MatchData *)data; + arrayobj = JSVAL_TO_OBJECT(*mdata->arrayval); + if (!arrayobj) { + arrayobj = js_ConstructObject(cx, &js_ArrayClass, NULL, NULL, 0, NULL); + if (!arrayobj) + return JS_FALSE; + *mdata->arrayval = OBJECT_TO_JSVAL(arrayobj); + } + matchsub = &cx->regExpStatics.lastMatch; + matchstr = js_NewStringCopyN(cx, matchsub->chars, matchsub->length, 0); + if (!matchstr) + return JS_FALSE; + v = STRING_TO_JSVAL(matchstr); + return js_SetProperty(cx, arrayobj, INT_TO_JSVAL(count), &v); +} + +static JSBool +str_match(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + MatchData mdata; + JSBool ok; + + mdata.base.flags = MODE_MATCH; + mdata.base.optarg = 1; + mdata.arrayval = &argv[2]; + *mdata.arrayval = JSVAL_NULL; + ok = match_or_replace(cx, obj, argc, argv, match_glob, &mdata.base, rval); + if (ok && !JSVAL_IS_NULL(*mdata.arrayval)) + *rval = *mdata.arrayval; + return ok; +} + +static JSBool +str_search(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + GlobData data; + + data.flags = MODE_SEARCH; + data.optarg = 1; + return match_or_replace(cx, obj, argc, argv, NULL, &data, rval); +} + +typedef struct ReplaceData { + GlobData base; /* base struct state */ + JSObject *lambda; /* replacement function object or null */ + JSString *repstr; /* replacement string */ + jschar *dollar; /* null or pointer to first $ in repstr */ + jschar *dollarEnd; /* limit pointer for js_strchr_limit */ + jschar *chars; /* result chars, null initially */ + size_t length; /* result length, 0 initially */ + jsint index; /* index in result of next replacement */ + jsint leftIndex; /* left context index in base.str->chars */ + JSSubString dollarStr; /* for "$$" interpret_dollar result */ +} ReplaceData; + +static JSSubString * +interpret_dollar(JSContext *cx, jschar *dp, ReplaceData *rdata, size_t *skip) +{ + JSRegExpStatics *res; + jschar dc, *cp; + uintN num, tmp; + JSString *str; + + JS_ASSERT(*dp == '$'); + + /* + * Allow a real backslash (literal "\\" before "$1") to escape "$1", e.g. + * Do this only for versions strictly less than ECMAv3. + */ + if (cx->version != JSVERSION_DEFAULT && cx->version <= JSVERSION_1_4) { + if (dp > JSSTRING_CHARS(rdata->repstr) && dp[-1] == '\\') + return NULL; + } + + /* Interpret all Perl match-induced dollar variables. */ + res = &cx->regExpStatics; + dc = dp[1]; + if (JS7_ISDEC(dc)) { + if (cx->version != JSVERSION_DEFAULT && cx->version <= JSVERSION_1_4) { + if (dc == '0') + return NULL; + + /* Check for overflow to avoid gobbling arbitrary decimal digits. */ + num = 0; + cp = dp; + while ((dc = *++cp) != 0 && JS7_ISDEC(dc)) { + tmp = 10 * num + JS7_UNDEC(dc); + if (tmp < num) + break; + num = tmp; + } + } else { /* ECMA 3, 1-9 or 01-99 */ + num = JS7_UNDEC(dc); + if (num > res->parenCount) + return NULL; + cp = dp + 2; + dc = *cp; + if ((dc != 0) && JS7_ISDEC(dc)) { + tmp = 10 * num + JS7_UNDEC(dc); + if (tmp <= res->parenCount) { + cp++; + num = tmp; + } + } + if (num == 0) + return NULL; + } + /* Adjust num from 1 $n-origin to 0 array-index-origin. */ + num--; + *skip = cp - dp; + return REGEXP_PAREN_SUBSTRING(res, num); + } + + *skip = 2; + switch (dc) { + case '$': + rdata->dollarStr.chars = dp; + rdata->dollarStr.length = 1; + return &rdata->dollarStr; + case '&': + return &res->lastMatch; + case '+': + return &res->lastParen; + case '`': + if (cx->version == JSVERSION_1_2) { + /* + * JS1.2 imitated the Perl4 bug where left context at each step + * in an iterative use of a global regexp started from last match, + * not from the start of the target string. But Perl4 does start + * $` at the beginning of the target string when it is used in a + * substitution, so we emulate that special case here. + */ + str = rdata->base.str; + res->leftContext.chars = JSSTRING_CHARS(str); + res->leftContext.length = res->lastMatch.chars + - JSSTRING_CHARS(str); + } + return &res->leftContext; + case '\'': + return &res->rightContext; + } + return NULL; +} + +static JSBool +find_replen(JSContext *cx, ReplaceData *rdata, size_t *sizep) +{ + JSString *repstr; + size_t replen, skip; + jschar *dp, *ep; + JSSubString *sub; +#if JS_HAS_REPLACE_LAMBDA + JSObject *lambda; + + lambda = rdata->lambda; + if (lambda) { + uintN argc, i, j, m, n, p; + jsval *sp, *oldsp, rval; + void *mark; + JSStackFrame *fp; + JSBool ok; + + /* + * Save the rightContext from the current regexp, since it + * gets stuck at the end of the replacement string and may + * be clobbered by a RegExp usage in the lambda function. + */ + JSSubString saveRightContext = cx->regExpStatics.rightContext; + + /* + * In the lambda case, not only do we find the replacement string's + * length, we compute repstr and return it via rdata for use within + * do_replace. The lambda is called with arguments ($&, $1, $2, ..., + * index, input), i.e., all the properties of a regexp match array. + * For $&, etc., we must create string jsvals from cx->regExpStatics. + * We grab up stack space to keep the newborn strings GC-rooted. + */ + p = rdata->base.regexp->parenCount; + argc = 1 + p + 2; + sp = js_AllocStack(cx, 2 + argc, &mark); + if (!sp) + return JS_FALSE; + + /* Push lambda and its 'this' parameter. */ + *sp++ = OBJECT_TO_JSVAL(lambda); + *sp++ = OBJECT_TO_JSVAL(OBJ_GET_PARENT(cx, lambda)); + +#define PUSH_REGEXP_STATIC(sub) \ + JS_BEGIN_MACRO \ + JSString *str = js_NewStringCopyN(cx, \ + cx->regExpStatics.sub.chars, \ + cx->regExpStatics.sub.length, \ + 0); \ + if (!str) { \ + ok = JS_FALSE; \ + goto lambda_out; \ + } \ + *sp++ = STRING_TO_JSVAL(str); \ + JS_END_MACRO + + /* Push $&, $1, $2, ... */ + PUSH_REGEXP_STATIC(lastMatch); + i = 0; + m = cx->regExpStatics.parenCount; + n = JS_MIN(m, 9); + for (j = 0; i < n; i++, j++) + PUSH_REGEXP_STATIC(parens[j]); + for (j = 0; i < m; i++, j++) + PUSH_REGEXP_STATIC(moreParens[j]); + +#undef PUSH_REGEXP_STATIC + + /* Make sure to push undefined for any unmatched parens. */ + for (; i < p; i++) + *sp++ = JSVAL_VOID; + + /* Push match index and input string. */ + *sp++ = INT_TO_JSVAL((jsint)cx->regExpStatics.leftContext.length); + *sp++ = STRING_TO_JSVAL(rdata->base.str); + + /* Lift current frame to include the args and do the call. */ + fp = cx->fp; + oldsp = fp->sp; + fp->sp = sp; + ok = js_Invoke(cx, argc, JSINVOKE_INTERNAL); + rval = fp->sp[-1]; + fp->sp = oldsp; + + if (ok) { + /* + * NB: we count on the newborn string root to hold any string + * created by this js_ValueToString that would otherwise be GC- + * able, until we use rdata->repstr in do_replace. + */ + repstr = js_ValueToString(cx, rval); + if (!repstr) { + ok = JS_FALSE; + } else { + rdata->repstr = repstr; + *sizep = JSSTRING_LENGTH(repstr); + } + } + + lambda_out: + js_FreeStack(cx, mark); + cx->regExpStatics.rightContext = saveRightContext; + return ok; + } +#endif /* JS_HAS_REPLACE_LAMBDA */ + + repstr = rdata->repstr; + replen = JSSTRING_LENGTH(repstr); + for (dp = rdata->dollar, ep = rdata->dollarEnd; dp; + dp = js_strchr_limit(dp, '$', ep)) { + sub = interpret_dollar(cx, dp, rdata, &skip); + if (sub) { + replen += sub->length - skip; + dp += skip; + } + else + dp++; + } + *sizep = replen; + return JS_TRUE; +} + +static void +do_replace(JSContext *cx, ReplaceData *rdata, jschar *chars) +{ + JSString *repstr; + jschar *bp, *cp, *dp, *ep; + size_t len, skip; + JSSubString *sub; + + repstr = rdata->repstr; + bp = cp = JSSTRING_CHARS(repstr); + for (dp = rdata->dollar, ep = rdata->dollarEnd; dp; + dp = js_strchr_limit(dp, '$', ep)) { + len = dp - cp; + js_strncpy(chars, cp, len); + chars += len; + cp = dp; + sub = interpret_dollar(cx, dp, rdata, &skip); + if (sub) { + len = sub->length; + js_strncpy(chars, sub->chars, len); + chars += len; + cp += skip; + dp += skip; + } else { + dp++; + } + } + js_strncpy(chars, cp, JSSTRING_LENGTH(repstr) - (cp - bp)); +} + +static JSBool +replace_glob(JSContext *cx, jsint count, GlobData *data) +{ + ReplaceData *rdata; + JSString *str; + size_t leftoff, leftlen, replen, growth; + const jschar *left; + jschar *chars; + + rdata = (ReplaceData *)data; + str = data->str; + leftoff = rdata->leftIndex; + left = JSSTRING_CHARS(str) + leftoff; + leftlen = cx->regExpStatics.lastMatch.chars - left; + rdata->leftIndex = cx->regExpStatics.lastMatch.chars - JSSTRING_CHARS(str); + rdata->leftIndex += cx->regExpStatics.lastMatch.length; + if (!find_replen(cx, rdata, &replen)) + return JS_FALSE; + growth = leftlen + replen; + chars = (jschar *) + (rdata->chars + ? JS_realloc(cx, rdata->chars, (rdata->length + growth + 1) + * sizeof(jschar)) + : JS_malloc(cx, (growth + 1) * sizeof(jschar))); + if (!chars) { + JS_free(cx, rdata->chars); + rdata->chars = NULL; + return JS_FALSE; + } + rdata->chars = chars; + rdata->length += growth; + chars += rdata->index; + rdata->index += growth; + js_strncpy(chars, left, leftlen); + chars += leftlen; + do_replace(cx, rdata, chars); + return JS_TRUE; +} + +static JSBool +str_replace(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + JSObject *lambda; + JSString *repstr, *str; + ReplaceData rdata; + JSBool ok; + jschar *chars; + size_t leftlen, rightlen, length; + +#if JS_HAS_REPLACE_LAMBDA + if (JS_TypeOfValue(cx, argv[1]) == JSTYPE_FUNCTION) { + lambda = JSVAL_TO_OBJECT(argv[1]); + repstr = NULL; + } else +#endif + { + if (!JS_ConvertValue(cx, argv[1], JSTYPE_STRING, &argv[1])) + return JS_FALSE; + repstr = JSVAL_TO_STRING(argv[1]); + lambda = NULL; + } + + /* + * For ECMA Edition 3, the first argument is to be converted to a string + * to match in a "flat" sense (without regular expression metachars having + * special meanings) UNLESS the first arg is a RegExp object. + */ + rdata.base.flags = MODE_REPLACE | KEEP_REGEXP; + if (cx->version == JSVERSION_DEFAULT || cx->version > JSVERSION_1_4) + rdata.base.flags |= FORCE_FLAT; + rdata.base.optarg = 2; + + rdata.lambda = lambda; + rdata.repstr = repstr; + if (repstr) { + rdata.dollarEnd = JSSTRING_CHARS(repstr) + JSSTRING_LENGTH(repstr); + rdata.dollar = js_strchr_limit(JSSTRING_CHARS(repstr), '$', + rdata.dollarEnd); + } else { + rdata.dollar = rdata.dollarEnd = NULL; + } + rdata.chars = NULL; + rdata.length = 0; + rdata.index = 0; + rdata.leftIndex = 0; + + ok = match_or_replace(cx, obj, argc, argv, replace_glob, &rdata.base, rval); + if (!ok) + return JS_FALSE; + + if (!rdata.chars) { + if ((rdata.base.flags & GLOBAL_REGEXP) || *rval != JSVAL_TRUE) { + /* Didn't match even once. */ + *rval = STRING_TO_JSVAL(rdata.base.str); + goto out; + } + leftlen = cx->regExpStatics.leftContext.length; + ok = find_replen(cx, &rdata, &length); + if (!ok) + goto out; + length += leftlen; + chars = (jschar *) JS_malloc(cx, (length + 1) * sizeof(jschar)); + if (!chars) { + ok = JS_FALSE; + goto out; + } + js_strncpy(chars, cx->regExpStatics.leftContext.chars, leftlen); + do_replace(cx, &rdata, chars + leftlen); + rdata.chars = chars; + rdata.length = length; + } + + rightlen = cx->regExpStatics.rightContext.length; + length = rdata.length + rightlen; + chars = (jschar *) + JS_realloc(cx, rdata.chars, (length + 1) * sizeof(jschar)); + if (!chars) { + JS_free(cx, rdata.chars); + ok = JS_FALSE; + goto out; + } + js_strncpy(chars + rdata.length, cx->regExpStatics.rightContext.chars, + rightlen); + chars[length] = 0; + + str = js_NewString(cx, chars, length, 0); + if (!str) { + JS_free(cx, chars); + ok = JS_FALSE; + goto out; + } + *rval = STRING_TO_JSVAL(str); + +out: + /* If KEEP_REGEXP is still set, it's our job to destroy regexp now. */ + if (rdata.base.flags & KEEP_REGEXP) + js_DestroyRegExp(cx, rdata.base.regexp); + return ok; +} +#endif /* JS_HAS_REGEXPS */ + +/* + * Subroutine used by str_split to find the next split point in str, starting + * at offset *ip and looking either for the separator substring given by sep, + * or for the next re match. In the re case, return the matched separator in + * *sep, and the possibly updated offset in *ip. + * + * Return -2 on error, -1 on end of string, >= 0 for a valid index of the next + * separator occurrence if found, or str->length if no separator is found. + */ +static jsint +find_split(JSContext *cx, JSString *str, JSRegExp *re, jsint *ip, + JSSubString *sep) +{ + jsint i, j, k; + jschar *chars; + size_t length; + + /* + * Stop if past end of string. If at end of string, we will compare the + * null char stored there (by js_NewString*) to sep->chars[j] in the while + * loop at the end of this function, so that + * + * "ab,".split(',') => ["ab", ""] + * + * and the resulting array converts back to the string "ab," for symmetry. + * However, we ape Perl and do this only if there is a sufficiently large + * limit argument (see str_split). + */ + i = *ip; + if ((size_t)i > JSSTRING_LENGTH(str)) + return -1; + + /* + * Perl4 special case for str.split(' '), only if the user has selected + * JavaScript1.2 explicitly. Split on whitespace, and skip leading w/s. + * Strange but true, apparently modeled after awk. + * + * NB: we set sep->length to the length of the w/s run, so we must test + * sep->chars[1] == 0 to make sure sep is just one space. + */ + chars = JSSTRING_CHARS(str); + length = JSSTRING_LENGTH(str); + if (cx->version == JSVERSION_1_2 && + !re && *sep->chars == ' ' && sep->chars[1] == 0) { + + /* Skip leading whitespace if at front of str. */ + if (i == 0) { + while (JS_ISSPACE(chars[i])) + i++; + *ip = i; + } + + /* Don't delimit whitespace at end of string. */ + if ((size_t)i == length) + return -1; + + /* Skip over the non-whitespace chars. */ + while ((size_t)i < length && !JS_ISSPACE(chars[i])) + i++; + + /* Now skip the next run of whitespace. */ + j = i; + while ((size_t)j < length && JS_ISSPACE(chars[j])) + j++; + + /* Update sep->length to count delimiter chars. */ + sep->length = (size_t)(j - i); + return i; + } + +#if JS_HAS_REGEXPS + /* + * Match a regular expression against the separator at or above index i. + * Call js_ExecuteRegExp with true for the test argument. On successful + * match, get the separator from cx->regExpStatics.lastMatch. + */ + if (re) { + size_t index; + jsval rval; + + again: + /* JS1.2 deviated from Perl by never matching at end of string. */ + index = (size_t)i; + if (!js_ExecuteRegExp(cx, re, str, &index, JS_TRUE, &rval)) + return -2; + if (rval != JSVAL_TRUE) { + /* Mismatch: ensure our caller advances i past end of string. */ + sep->length = 1; + return length; + } + i = (jsint)index; + *sep = cx->regExpStatics.lastMatch; + if (sep->length == 0) { + /* + * Empty string match: never split on an empty match at the start + * of a find_split cycle. Same rule as for an empty global match + * in match_or_replace. + */ + if (i == *ip) { + /* + * "Bump-along" to avoid sticking at an empty match, but don't + * bump past end of string -- our caller must do that by adding + * sep->length to our return value. + */ + if ((size_t)i == length) { + if (cx->version == JSVERSION_1_2) { + sep->length = 1; + return i; + } + return -1; + } + i++; + goto again; + } + } + JS_ASSERT((size_t)i >= sep->length); + return i - sep->length; + } +#endif /* JS_HAS_REGEXPS */ + + /* + * Deviate from ECMA by never splitting an empty string by any separator + * string into a non-empty array (an array of length 1 that contains the + * empty string). + */ + if (!JSVERSION_IS_ECMA(cx->version) && length == 0) + return -1; + + /* + * Special case: if sep is the empty string, split str into one character + * substrings. Let our caller worry about whether to split once at end of + * string into an empty substring. + * + * For 1.2 compatibility, at the end of the string, we return the length as + * the result, and set the separator length to 1 -- this allows the caller + * to include an additional null string at the end of the substring list. + */ + if (sep->length == 0) { + if (cx->version == JSVERSION_1_2) { + if ((size_t)i == length) { + sep->length = 1; + return i; + } + return i + 1; + } + return ((size_t)i == length) ? -1 : i + 1; + } + + /* + * Now that we know sep is non-empty, search starting at i in str for an + * occurrence of all of sep's chars. If we find them, return the index of + * the first separator char. Otherwise, return length. + */ + j = 0; + while ((size_t)(k = i + j) < length) { + if (chars[k] == sep->chars[j]) { + if ((size_t)++j == sep->length) + return i; + } else { + i++; + j = 0; + } + } + return k; +} + +static JSBool +str_split(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + JSString *str, *sub; + JSObject *arrayobj; + jsval v; + JSBool ok, limited; + JSRegExp *re; + JSSubString *sep, tmp; + jsdouble d; + jsint i, j; + uint32 len, limit; + + str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj)); + if (!str) + return JS_FALSE; + argv[-1] = STRING_TO_JSVAL(str); + + arrayobj = js_ConstructObject(cx, &js_ArrayClass, NULL, NULL, 0, NULL); + if (!arrayobj) + return JS_FALSE; + *rval = OBJECT_TO_JSVAL(arrayobj); + + if (argc == 0) { + v = STRING_TO_JSVAL(str); + ok = JS_SetElement(cx, arrayobj, 0, &v); + } else { +#if JS_HAS_REGEXPS + if (JSVAL_IS_REGEXP(cx, argv[0])) { + re = (JSRegExp *) JS_GetPrivate(cx, JSVAL_TO_OBJECT(argv[0])); + sep = &tmp; + + /* Set a magic value so we can detect a successful re match. */ + sep->chars = NULL; + } else +#endif + { + JSString *str2 = js_ValueToString(cx, argv[0]); + if (!str2) + return JS_FALSE; + argv[0] = STRING_TO_JSVAL(str2); + + /* + * Point sep at a local copy of str2's header because find_split + * will modify sep->length. + */ + tmp.length = JSSTRING_LENGTH(str2); + tmp.chars = JSSTRING_CHARS(str2); + sep = &tmp; + re = NULL; + } + + /* Use the second argument as the split limit, if given. */ + limited = (argc > 1) && !JSVAL_IS_VOID(argv[1]); + limit = 0; /* Avoid warning. */ + if (limited) { + if (!js_ValueToNumber(cx, argv[1], &d)) + return JS_FALSE; + + /* Clamp limit between 0 and 1 + string length. */ + if (!js_DoubleToECMAUint32(cx, d, &limit)) + return JS_FALSE; + if (limit > JSSTRING_LENGTH(str)) + limit = 1 + JSSTRING_LENGTH(str); + } + + len = i = 0; + while ((j = find_split(cx, str, re, &i, sep)) >= 0) { + if (limited && len >= limit) + break; + sub = js_NewDependentString(cx, str, i, (size_t)(j - i), 0); + if (!sub) + return JS_FALSE; + v = STRING_TO_JSVAL(sub); + if (!JS_SetElement(cx, arrayobj, len, &v)) + return JS_FALSE; + len++; +#if JS_HAS_REGEXPS + /* + * Imitate perl's feature of including parenthesized substrings + * that matched part of the delimiter in the new array, after the + * split substring that was delimited. + */ + if (re && sep->chars) { + uintN num; + JSSubString *parsub; + + for (num = 0; num < cx->regExpStatics.parenCount; num++) { + if (limited && len >= limit) + break; + parsub = REGEXP_PAREN_SUBSTRING(&cx->regExpStatics, num); + sub = js_NewStringCopyN(cx, parsub->chars, parsub->length, + 0); + if (!sub) + return JS_FALSE; + v = STRING_TO_JSVAL(sub); + if (!JS_SetElement(cx, arrayobj, len, &v)) + return JS_FALSE; + len++; + } + sep->chars = NULL; + } +#endif + i = j + sep->length; + if (!JSVERSION_IS_ECMA(cx->version)) { + /* + * Deviate from ECMA to imitate Perl, which omits a final + * split unless a limit argument is given and big enough. + */ + if (!limited && (size_t)i == JSSTRING_LENGTH(str)) + break; + } + } + ok = (j != -2); + } + return ok; +} + +#if JS_HAS_PERL_SUBSTR +static JSBool +str_substr(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + JSString *str; + jsdouble d; + jsdouble length, begin, end; + + str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj)); + if (!str) + return JS_FALSE; + + if (argc != 0) { + if (!js_ValueToNumber(cx, argv[0], &d)) + return JS_FALSE; + length = JSSTRING_LENGTH(str); + begin = js_DoubleToInteger(d); + if (begin < 0) { + begin += length; + if (begin < 0) + begin = 0; + } else if (begin > length) { + begin = length; + } + + if (argc == 1) { + end = length; + } else { + if (!js_ValueToNumber(cx, argv[1], &d)) + return JS_FALSE; + end = js_DoubleToInteger(d); + if (end < 0) + end = 0; + end += begin; + if (end > length) + end = length; + } + + str = js_NewDependentString(cx, str, (size_t)begin, + (size_t)(end - begin), 0); + if (!str) + return JS_FALSE; + } + *rval = STRING_TO_JSVAL(str); + return JS_TRUE; +} +#endif /* JS_HAS_PERL_SUBSTR */ + +#if JS_HAS_SEQUENCE_OPS +/* + * Python-esque sequence operations. + */ +static JSBool +str_concat(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + JSString *str, *str2; + uintN i; + + str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj)); + if (!str) + return JS_FALSE; + argv[-1] = STRING_TO_JSVAL(str); + + for (i = 0; i < argc; i++) { + str2 = js_ValueToString(cx, argv[i]); + if (!str2) + return JS_FALSE; + argv[i] = STRING_TO_JSVAL(str2); + + str = js_ConcatStrings(cx, str, str2); + if (!str) + return JS_FALSE; + } + + *rval = STRING_TO_JSVAL(str); + return JS_TRUE; +} + +static JSBool +str_slice(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + JSString *str; + jsdouble d; + jsdouble length, begin, end; + + str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj)); + if (!str) + return JS_FALSE; + argv[-1] = STRING_TO_JSVAL(str); + + if (argc != 0) { + if (!js_ValueToNumber(cx, argv[0], &d)) + return JS_FALSE; + length = JSSTRING_LENGTH(str); + begin = js_DoubleToInteger(d); + if (begin < 0) { + begin += length; + if (begin < 0) + begin = 0; + } else if (begin > length) { + begin = length; + } + + if (argc == 1) { + end = length; + } else { + if (!js_ValueToNumber(cx, argv[1], &d)) + return JS_FALSE; + end = js_DoubleToInteger(d); + if (end < 0) { + end += length; + if (end < 0) + end = 0; + } else if (end > length) { + end = length; + } + if (end < begin) + end = begin; + } + + str = js_NewDependentString(cx, str, (size_t)begin, + (size_t)(end - begin), 0); + if (!str) + return JS_FALSE; + } + *rval = STRING_TO_JSVAL(str); + return JS_TRUE; +} +#endif /* JS_HAS_SEQUENCE_OPS */ + +#if JS_HAS_STR_HTML_HELPERS +/* + * HTML composition aids. + */ +static JSBool +tagify(JSContext *cx, JSObject *obj, jsval *argv, + const char *begin, const jschar *param, const char *end, + jsval *rval) +{ + JSString *str; + jschar *tagbuf; + size_t beglen, endlen, parlen, taglen; + size_t i, j; + + str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj)); + if (!str) + return JS_FALSE; + argv[-1] = STRING_TO_JSVAL(str); + + if (!end) + end = begin; + + beglen = strlen(begin); + taglen = 1 + beglen + 1; /* '' */ + parlen = 0; /* Avoid warning. */ + if (param) { + parlen = js_strlen(param); + taglen += 2 + parlen + 1; /* '="param"' */ + } + endlen = strlen(end); + taglen += JSSTRING_LENGTH(str) + 2 + endlen + 1; /* 'str' */ + + tagbuf = (jschar *) JS_malloc(cx, (taglen + 1) * sizeof(jschar)); + if (!tagbuf) + return JS_FALSE; + + j = 0; + tagbuf[j++] = '<'; + for (i = 0; i < beglen; i++) + tagbuf[j++] = (jschar)begin[i]; + if (param) { + tagbuf[j++] = '='; + tagbuf[j++] = '"'; + js_strncpy(&tagbuf[j], param, parlen); + j += parlen; + tagbuf[j++] = '"'; + } + tagbuf[j++] = '>'; + js_strncpy(&tagbuf[j], JSSTRING_CHARS(str), JSSTRING_LENGTH(str)); + j += JSSTRING_LENGTH(str); + tagbuf[j++] = '<'; + tagbuf[j++] = '/'; + for (i = 0; i < endlen; i++) + tagbuf[j++] = (jschar)end[i]; + tagbuf[j++] = '>'; + JS_ASSERT(j == taglen); + tagbuf[j] = 0; + + str = js_NewString(cx, tagbuf, taglen, 0); + if (!str) { + free((char *)tagbuf); + return JS_FALSE; + } + *rval = STRING_TO_JSVAL(str); + return JS_TRUE; +} + +static JSBool +tagify_value(JSContext *cx, JSObject *obj, jsval *argv, + const char *begin, const char *end, + jsval *rval) +{ + JSString *param; + + param = js_ValueToString(cx, argv[0]); + if (!param) + return JS_FALSE; + argv[0] = STRING_TO_JSVAL(param); + return tagify(cx, obj, argv, begin, JSSTRING_CHARS(param), end, rval); +} + +static JSBool +str_bold(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + return tagify(cx, obj, argv, "b", NULL, NULL, rval); +} + +static JSBool +str_italics(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + return tagify(cx, obj, argv, "i", NULL, NULL, rval); +} + +static JSBool +str_fixed(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + return tagify(cx, obj, argv, "tt", NULL, NULL, rval); +} + +static JSBool +str_fontsize(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + return tagify_value(cx, obj, argv, "font size", "font", rval); +} + +static JSBool +str_fontcolor(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval) +{ + return tagify_value(cx, obj, argv, "font color", "font", rval); +} + +static JSBool +str_link(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + return tagify_value(cx, obj, argv, "a href", "a", rval); +} + +static JSBool +str_anchor(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + return tagify_value(cx, obj, argv, "a name", "a", rval); +} + +static JSBool +str_strike(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + return tagify(cx, obj, argv, "strike", NULL, NULL, rval); +} + +static JSBool +str_small(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + return tagify(cx, obj, argv, "small", NULL, NULL, rval); +} + +static JSBool +str_big(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + return tagify(cx, obj, argv, "big", NULL, NULL, rval); +} + +static JSBool +str_blink(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + return tagify(cx, obj, argv, "blink", NULL, NULL, rval); +} + +static JSBool +str_sup(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + return tagify(cx, obj, argv, "sup", NULL, NULL, rval); +} + +static JSBool +str_sub(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + return tagify(cx, obj, argv, "sub", NULL, NULL, rval); +} +#endif /* JS_HAS_STR_HTML_HELPERS */ + +static JSFunctionSpec string_methods[] = { +#if JS_HAS_TOSOURCE + {"quote", str_quote, 0,0,0}, + {js_toSource_str, str_toSource, 0,0,0}, +#endif + + /* Java-like methods. */ + {js_toString_str, str_toString, 0,0,0}, + {js_valueOf_str, str_valueOf, 0,0,0}, + {"substring", str_substring, 2,0,0}, + {"toLowerCase", str_toLowerCase, 0,0,0}, + {"toUpperCase", str_toUpperCase, 0,0,0}, + {"charAt", str_charAt, 1,0,0}, + {"charCodeAt", str_charCodeAt, 1,0,0}, + {"indexOf", str_indexOf, 1,0,0}, + {"lastIndexOf", str_lastIndexOf, 1,0,0}, + {"toLocaleLowerCase", str_toLocaleLowerCase, 0,0,0}, + {"toLocaleUpperCase", str_toLocaleUpperCase, 0,0,0}, + {"localeCompare", str_localeCompare, 1,0,0}, + + /* Perl-ish methods (search is actually Python-esque). */ +#if JS_HAS_REGEXPS + {"match", str_match, 1,0,2}, + {"search", str_search, 1,0,0}, + {"replace", str_replace, 2,0,0}, + {"split", str_split, 2,0,0}, +#endif +#if JS_HAS_PERL_SUBSTR + {"substr", str_substr, 2,0,0}, +#endif + + /* Python-esque sequence methods. */ +#if JS_HAS_SEQUENCE_OPS + {"concat", str_concat, 0,0,0}, + {"slice", str_slice, 0,0,0}, +#endif + + /* HTML string methods. */ +#if JS_HAS_STR_HTML_HELPERS + {"bold", str_bold, 0,0,0}, + {"italics", str_italics, 0,0,0}, + {"fixed", str_fixed, 0,0,0}, + {"fontsize", str_fontsize, 1,0,0}, + {"fontcolor", str_fontcolor, 1,0,0}, + {"link", str_link, 1,0,0}, + {"anchor", str_anchor, 1,0,0}, + {"strike", str_strike, 0,0,0}, + {"small", str_small, 0,0,0}, + {"big", str_big, 0,0,0}, + {"blink", str_blink, 0,0,0}, + {"sup", str_sup, 0,0,0}, + {"sub", str_sub, 0,0,0}, +#endif + + {0,0,0,0,0} +}; + +static JSBool +String(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + JSString *str; + + if (argc > 0) { + str = js_ValueToString(cx, argv[0]); + if (!str) + return JS_FALSE; + } else { + str = cx->runtime->emptyString; + } + if (!(cx->fp->flags & JSFRAME_CONSTRUCTING)) { + *rval = STRING_TO_JSVAL(str); + return JS_TRUE; + } + OBJ_SET_SLOT(cx, obj, JSSLOT_PRIVATE, STRING_TO_JSVAL(str)); + return JS_TRUE; +} + +static JSBool +str_fromCharCode(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval) +{ + jschar *chars; + uintN i; + uint16 code; + JSString *str; + + chars = (jschar *) JS_malloc(cx, (argc + 1) * sizeof(jschar)); + if (!chars) + return JS_FALSE; + for (i = 0; i < argc; i++) { + if (!js_ValueToUint16(cx, argv[i], &code)) { + JS_free(cx, chars); + return JS_FALSE; + } + chars[i] = (jschar)code; + } + chars[i] = 0; + str = js_NewString(cx, chars, argc, 0); + if (!str) { + JS_free(cx, chars); + return JS_FALSE; + } + *rval = STRING_TO_JSVAL(str); + return JS_TRUE; +} + +static JSFunctionSpec string_static_methods[] = { + {"fromCharCode", str_fromCharCode, 1,0,0}, + {0,0,0,0,0} +}; + +static JSHashTable *deflated_string_cache; +#ifdef DEBUG +static uint32 deflated_string_cache_bytes; +#endif +#ifdef JS_THREADSAFE +static JSLock *deflated_string_cache_lock; +#endif + +JSBool +js_InitStringGlobals(void) +{ +#ifdef JS_THREADSAFE + /* Must come through here once in primordial thread to init safely! */ + if (!deflated_string_cache_lock) { + deflated_string_cache_lock = JS_NEW_LOCK(); + if (!deflated_string_cache_lock) + return JS_FALSE; + } +#endif + return JS_TRUE; +} + +void +js_FreeStringGlobals() +{ + if (deflated_string_cache) { + JS_HashTableDestroy(deflated_string_cache); + deflated_string_cache = NULL; + } +#ifdef JS_THREADSAFE + if (deflated_string_cache_lock) { + JS_DESTROY_LOCK(deflated_string_cache_lock); + deflated_string_cache_lock = NULL; + } +#endif +} + +JSBool +js_InitRuntimeStringState(JSContext *cx) +{ + JSRuntime *rt; + JSString *empty; + + rt = cx->runtime; + JS_ASSERT(!rt->emptyString); + + /* Make a permanently locked empty string. */ + empty = js_NewStringCopyN(cx, js_empty_ucstr, 0, GCF_LOCK); + if (!empty) + return JS_FALSE; + + /* Atomize it for scripts that use '' + x to convert x to string. */ + if (!js_AtomizeString(cx, empty, ATOM_PINNED)) + return JS_FALSE; + + rt->emptyString = empty; + return JS_TRUE; +} + +void +js_FinishRuntimeStringState(JSContext *cx) +{ + JSRuntime *rt = cx->runtime; + + js_UnlockGCThingRT(rt, rt->emptyString); + rt->emptyString = NULL; +} + +JSObject * +js_InitStringClass(JSContext *cx, JSObject *obj) +{ + JSObject *proto; + + /* Define the escape, unescape functions in the global object. */ + if (!JS_DefineFunctions(cx, obj, string_functions)) + return NULL; + + proto = JS_InitClass(cx, obj, NULL, &string_class, String, 1, + string_props, string_methods, + NULL, string_static_methods); + if (!proto) + return NULL; + OBJ_SET_SLOT(cx, proto, JSSLOT_PRIVATE, + STRING_TO_JSVAL(cx->runtime->emptyString)); + return proto; +} + +JSString * +js_NewString(JSContext *cx, jschar *chars, size_t length, uintN gcflag) +{ + JSString *str; + + if (length > JSSTRING_LENGTH_MASK) { + JS_ReportOutOfMemory(cx); + return NULL; + } + + str = (JSString *) js_AllocGCThing(cx, gcflag | GCX_STRING); + if (!str) + return NULL; + str->length = length; + str->chars = chars; +#ifdef DEBUG + { + JSRuntime *rt = cx->runtime; + JS_RUNTIME_METER(rt, liveStrings); + JS_RUNTIME_METER(rt, totalStrings); + JS_LOCK_RUNTIME_VOID(rt, + (rt->lengthSum += (double)length, + rt->lengthSquaredSum += (double)length * (double)length)); + } +#endif + return str; +} + +JSString * +js_NewDependentString(JSContext *cx, JSString *base, size_t start, + size_t length, uintN gcflag) +{ + JSDependentString *ds; + + if (length == 0) + return cx->runtime->emptyString; + + if (start > JSSTRDEP_START_MASK || + (start != 0 && length > JSSTRDEP_LENGTH_MASK)) { + return js_NewStringCopyN(cx, JSSTRING_CHARS(base) + start, length, + gcflag); + } + + ds = (JSDependentString *) js_AllocGCThing(cx, gcflag | GCX_MUTABLE_STRING); + if (!ds) + return NULL; + if (start == 0) { + JSPREFIX_SET_LENGTH(ds, length); + JSPREFIX_SET_BASE(ds, base); + } else { + JSSTRDEP_SET_START_AND_LENGTH(ds, start, length); + JSSTRDEP_SET_BASE(ds, base); + } +#ifdef DEBUG + { + JSRuntime *rt = cx->runtime; + JS_RUNTIME_METER(rt, liveDependentStrings); + JS_RUNTIME_METER(rt, totalDependentStrings); + JS_RUNTIME_METER(rt, liveStrings); + JS_RUNTIME_METER(rt, totalStrings); + JS_LOCK_RUNTIME_VOID(rt, + (rt->strdepLengthSum += (double)length, + rt->strdepLengthSquaredSum += (double)length * (double)length)); + JS_LOCK_RUNTIME_VOID(rt, + (rt->lengthSum += (double)length, + rt->lengthSquaredSum += (double)length * (double)length)); + } +#endif + return (JSString *)ds; +} + +#ifdef DEBUG +#include + +void printJSStringStats(JSRuntime *rt) { + double mean = 0., var = 0., sigma = 0.; + jsrefcount count = rt->totalStrings; + if (count > 0 && rt->lengthSum >= 0) { + mean = rt->lengthSum / count; + var = count * rt->lengthSquaredSum - rt->lengthSum * rt->lengthSum; + if (var < 0.0 || count <= 1) + var = 0.0; + else + var /= count * (count - 1); + + /* Windows says sqrt(0.0) is "-1.#J" (?!) so we must test. */ + sigma = (var != 0.) ? sqrt(var) : 0.; + } + fprintf(stderr, "%lu total strings, mean length %g (sigma %g)\n", + (unsigned long)count, mean, sigma); + + mean = var = sigma = 0.; + count = rt->totalDependentStrings; + if (count > 0 && rt->strdepLengthSum >= 0) { + mean = rt->strdepLengthSum / count; + var = count * rt->strdepLengthSquaredSum + - rt->strdepLengthSum * rt->strdepLengthSum; + if (var < 0.0 || count <= 1) + var = 0.0; + else + var /= count * (count - 1); + + /* Windows says sqrt(0.0) is "-1.#J" (?!) so we must test. */ + sigma = (var != 0.) ? sqrt(var) : 0.; + } + fprintf(stderr, "%lu total dependent strings, mean length %g (sigma %g)\n", + (unsigned long)count, mean, sigma); +} +#endif + +JSString * +js_NewStringCopyN(JSContext *cx, const jschar *s, size_t n, uintN gcflag) +{ + jschar *news; + JSString *str; + + news = (jschar *)JS_malloc(cx, (n + 1) * sizeof(jschar)); + if (!news) + return NULL; + js_strncpy(news, s, n); + news[n] = 0; + str = js_NewString(cx, news, n, gcflag); + if (!str) + JS_free(cx, news); + return str; +} + +JSString * +js_NewStringCopyZ(JSContext *cx, const jschar *s, uintN gcflag) +{ + size_t n, m; + jschar *news; + JSString *str; + + n = js_strlen(s); + m = (n + 1) * sizeof(jschar); + news = (jschar *) JS_malloc(cx, m); + if (!news) + return NULL; + memcpy(news, s, m); + str = js_NewString(cx, news, n, gcflag); + if (!str) + JS_free(cx, news); + return str; +} + +JS_STATIC_DLL_CALLBACK(JSHashNumber) +js_hash_string_pointer(const void *key) +{ + return (JSHashNumber)key >> JSVAL_TAGBITS; +} + +void +js_PurgeDeflatedStringCache(JSString *str) +{ + JSHashNumber hash; + JSHashEntry *he, **hep; + + if (!deflated_string_cache) + return; + + hash = js_hash_string_pointer(str); + JS_ACQUIRE_LOCK(deflated_string_cache_lock); + hep = JS_HashTableRawLookup(deflated_string_cache, hash, str); + he = *hep; + if (he) { +#ifdef DEBUG + deflated_string_cache_bytes -= JSSTRING_LENGTH(str); +#endif + free(he->value); + JS_HashTableRawRemove(deflated_string_cache, hep, he); + } + JS_RELEASE_LOCK(deflated_string_cache_lock); +} + +void +js_FinalizeString(JSContext *cx, JSString *str) +{ + js_FinalizeStringRT(cx->runtime, str); +} + +void +js_FinalizeStringRT(JSRuntime *rt, JSString *str) +{ + JSBool valid; + + JS_RUNTIME_UNMETER(rt, liveStrings); + if (JSSTRING_IS_DEPENDENT(str)) { + /* If JSSTRFLAG_DEPENDENT is set, this string must be valid. */ + JS_ASSERT(JSSTRDEP_BASE(str)); + JS_RUNTIME_UNMETER(rt, liveDependentStrings); + valid = JS_TRUE; + } else { + /* A stillborn string has null chars, so is not valid. */ + valid = (str->chars != NULL); + if (valid) + free(str->chars); + } + if (valid) { + js_PurgeDeflatedStringCache(str); + str->chars = NULL; + } + str->length = 0; +} + +JSObject * +js_StringToObject(JSContext *cx, JSString *str) +{ + JSObject *obj; + + obj = js_NewObject(cx, &string_class, NULL, NULL); + if (!obj) + return NULL; + OBJ_SET_SLOT(cx, obj, JSSLOT_PRIVATE, STRING_TO_JSVAL(str)); + return obj; +} + +JSString * +js_ValueToString(JSContext *cx, jsval v) +{ + JSObject *obj; + JSString *str; + + if (JSVAL_IS_OBJECT(v)) { + obj = JSVAL_TO_OBJECT(v); + if (!obj) + return ATOM_TO_STRING(cx->runtime->atomState.nullAtom); + if (!OBJ_DEFAULT_VALUE(cx, obj, JSTYPE_STRING, &v)) + return NULL; + } + if (JSVAL_IS_STRING(v)) { + str = JSVAL_TO_STRING(v); + } else if (JSVAL_IS_INT(v)) { + str = js_NumberToString(cx, JSVAL_TO_INT(v)); + } else if (JSVAL_IS_DOUBLE(v)) { + str = js_NumberToString(cx, *JSVAL_TO_DOUBLE(v)); + } else if (JSVAL_IS_BOOLEAN(v)) { + str = js_BooleanToString(cx, JSVAL_TO_BOOLEAN(v)); + } else { + str = ATOM_TO_STRING(cx->runtime->atomState.typeAtoms[JSTYPE_VOID]); + } + return str; +} + +JSString * +js_ValueToSource(JSContext *cx, jsval v) +{ + if (JSVAL_IS_STRING(v)) + return js_QuoteString(cx, JSVAL_TO_STRING(v), '"'); + if (JSVAL_IS_PRIMITIVE(v)) { + /* Special case to preserve negative zero, _contra_ toString. */ + if (JSVAL_IS_DOUBLE(v) && JSDOUBLE_IS_NEGZERO(*JSVAL_TO_DOUBLE(v))) { + /* NB: _ucNstr rather than _ucstr to indicate non-terminated. */ + static const jschar js_negzero_ucNstr[] = {'-', '0'}; + + return js_NewStringCopyN(cx, js_negzero_ucNstr, 2, 0); + } + } else { + if (!js_TryMethod(cx, JSVAL_TO_OBJECT(v), + cx->runtime->atomState.toSourceAtom, + 0, NULL, &v)) { + return NULL; + } + } + return js_ValueToString(cx, v); +} + +JSHashNumber +js_HashString(JSString *str) +{ + JSHashNumber h; + const jschar *s; + size_t n; + + h = 0; + for (s = JSSTRING_CHARS(str), n = JSSTRING_LENGTH(str); n; s++, n--) + h = (h >> (JS_HASH_BITS - 4)) ^ (h << 4) ^ *s; + return h; +} + +intN +js_CompareStrings(JSString *str1, JSString *str2) +{ + size_t l1, l2, n, i; + const jschar *s1, *s2; + intN cmp; + + l1 = JSSTRING_LENGTH(str1), l2 = JSSTRING_LENGTH(str2); + s1 = JSSTRING_CHARS(str1), s2 = JSSTRING_CHARS(str2); + n = JS_MIN(l1, l2); + for (i = 0; i < n; i++) { + cmp = s1[i] - s2[i]; + if (cmp != 0) + return cmp; + } + return (intN)(l1 - l2); +} + +size_t +js_strlen(const jschar *s) +{ + const jschar *t; + + for (t = s; *t != 0; t++) + continue; + return (size_t)(t - s); +} + +jschar * +js_strchr(const jschar *s, jschar c) +{ + while (*s != 0) { + if (*s == c) + return (jschar *)s; + s++; + } + return NULL; +} + +jschar * +js_strchr_limit(const jschar *s, jschar c, const jschar *limit) +{ + while (s < limit) { + if (*s == c) + return (jschar *)s; + s++; + } + return NULL; +} + +const jschar * +js_SkipWhiteSpace(const jschar *s) +{ + /* JS_ISSPACE is false on a null. */ + while (JS_ISSPACE(*s)) + s++; + return s; +} + +#define INFLATE_STRING_BODY \ + for (i = 0; i < length; i++) \ + chars[i] = (unsigned char) bytes[i]; \ + chars[i] = 0; + +void +js_InflateStringToBuffer(jschar *chars, const char *bytes, size_t length) +{ + size_t i; + + INFLATE_STRING_BODY +} + +jschar * +js_InflateString(JSContext *cx, const char *bytes, size_t length) +{ + jschar *chars; + size_t i; + + chars = (jschar *) JS_malloc(cx, (length + 1) * sizeof(jschar)); + if (!chars) + return NULL; + + INFLATE_STRING_BODY + + return chars; +} + +/* + * May be called with null cx by js_GetStringBytes, see below. + */ +char * +js_DeflateString(JSContext *cx, const jschar *chars, size_t length) +{ + size_t i, size; + char *bytes; + + size = (length + 1) * sizeof(char); + bytes = (char *) (cx ? JS_malloc(cx, size) : malloc(size)); + if (!bytes) + return NULL; + for (i = 0; i < length; i++) + bytes[i] = (char) chars[i]; + bytes[i] = 0; + return bytes; +} + +static JSHashTable * +GetDeflatedStringCache(void) +{ + JSHashTable *cache; + + cache = deflated_string_cache; + if (!cache) { + cache = JS_NewHashTable(8, js_hash_string_pointer, + JS_CompareValues, JS_CompareValues, + NULL, NULL); + deflated_string_cache = cache; + } + return cache; +} + +JSBool +js_SetStringBytes(JSString *str, char *bytes, size_t length) +{ + JSHashTable *cache; + JSBool ok; + JSHashNumber hash; + JSHashEntry **hep; + + JS_ACQUIRE_LOCK(deflated_string_cache_lock); + + cache = GetDeflatedStringCache(); + if (!cache) { + ok = JS_FALSE; + } else { + hash = js_hash_string_pointer(str); + hep = JS_HashTableRawLookup(cache, hash, str); + JS_ASSERT(*hep == NULL); + ok = JS_HashTableRawAdd(cache, hep, hash, str, bytes) != NULL; +#ifdef DEBUG + if (ok) + deflated_string_cache_bytes += length; +#endif + } + + JS_RELEASE_LOCK(deflated_string_cache_lock); + return ok; +} + +char * +js_GetStringBytes(JSString *str) +{ + JSHashTable *cache; + char *bytes; + JSHashNumber hash; + JSHashEntry *he, **hep; + + JS_ACQUIRE_LOCK(deflated_string_cache_lock); + + cache = GetDeflatedStringCache(); + if (!cache) { + bytes = NULL; + } else { + hash = js_hash_string_pointer(str); + hep = JS_HashTableRawLookup(cache, hash, str); + he = *hep; + if (he) { + bytes = (char *) he->value; + + /* Try to catch failure to JS_ShutDown between runtime epochs. */ + JS_ASSERT((*bytes == '\0' && JSSTRING_LENGTH(str) == 0) || + *bytes == (char) JSSTRING_CHARS(str)[0]); + } else { + bytes = js_DeflateString(NULL, JSSTRING_CHARS(str), + JSSTRING_LENGTH(str)); + if (bytes) { + if (JS_HashTableRawAdd(cache, hep, hash, str, bytes)) { +#ifdef DEBUG + deflated_string_cache_bytes += JSSTRING_LENGTH(str); +#endif + } else { + free(bytes); + bytes = NULL; + } + } + } + } + + JS_RELEASE_LOCK(deflated_string_cache_lock); + return bytes; +} + +/* + * From java.lang.Character.java: + * + * The character properties are currently encoded into 32 bits in the + * following manner: + * + * 10 bits signed offset used for converting case + * 1 bit if 1, adding the signed offset converts the character to + * lowercase + * 1 bit if 1, subtracting the signed offset converts the character to + * uppercase + * 1 bit if 1, character has a titlecase equivalent (possibly itself) + * 3 bits 0 may not be part of an identifier + * 1 ignorable control; may continue a Unicode identifier or JS + * identifier + * 2 may continue a JS identifier but not a Unicode identifier + * (unused) + * 3 may continue a Unicode identifier or JS identifier + * 4 is a JS whitespace character + * 5 may start or continue a JS identifier; + * may continue but not start a Unicode identifier (_) + * 6 may start or continue a JS identifier but not a Unicode + * identifier ($) + * 7 may start or continue a Unicode identifier or JS identifier + * Thus: + * 5, 6, 7 may start a JS identifier + * 1, 2, 3, 5, 6, 7 may continue a JS identifier + * 7 may start a Unicode identifier + * 1, 3, 5, 7 may continue a Unicode identifier + * 1 is ignorable within an identifier + * 4 is JS whitespace + * 2 bits 0 this character has no numeric property + * 1 adding the digit offset to the character code and then + * masking with 0x1F will produce the desired numeric value + * 2 this character has a "strange" numeric value + * 3 a JS supradecimal digit: adding the digit offset to the + * character code, then masking with 0x1F, then adding 10 + * will produce the desired numeric value + * 5 bits digit offset + * 4 bits reserved for future use + * 5 bits character type + */ + +/* The X table has 1024 entries for a total of 1024 bytes. */ + +const uint8 js_X[] = { + 0, 1, 2, 3, 4, 5, 6, 7, /* 0x0000 */ + 8, 9, 10, 11, 12, 13, 14, 15, /* 0x0200 */ + 16, 17, 18, 19, 20, 21, 22, 23, /* 0x0400 */ + 24, 25, 26, 27, 28, 28, 28, 28, /* 0x0600 */ + 28, 28, 28, 28, 29, 30, 31, 32, /* 0x0800 */ + 33, 34, 35, 36, 37, 38, 39, 40, /* 0x0A00 */ + 41, 42, 43, 44, 45, 46, 28, 28, /* 0x0C00 */ + 47, 48, 49, 50, 51, 52, 53, 28, /* 0x0E00 */ + 28, 28, 54, 55, 56, 57, 58, 59, /* 0x1000 */ + 28, 28, 28, 28, 28, 28, 28, 28, /* 0x1200 */ + 28, 28, 28, 28, 28, 28, 28, 28, /* 0x1400 */ + 28, 28, 28, 28, 28, 28, 28, 28, /* 0x1600 */ + 28, 28, 28, 28, 28, 28, 28, 28, /* 0x1800 */ + 28, 28, 28, 28, 28, 28, 28, 28, /* 0x1A00 */ + 28, 28, 28, 28, 28, 28, 28, 28, /* 0x1C00 */ + 60, 60, 61, 62, 63, 64, 65, 66, /* 0x1E00 */ + 67, 68, 69, 70, 71, 72, 73, 74, /* 0x2000 */ + 75, 75, 75, 76, 77, 78, 28, 28, /* 0x2200 */ + 79, 80, 81, 82, 83, 83, 84, 85, /* 0x2400 */ + 86, 85, 28, 28, 87, 88, 89, 28, /* 0x2600 */ + 28, 28, 28, 28, 28, 28, 28, 28, /* 0x2800 */ + 28, 28, 28, 28, 28, 28, 28, 28, /* 0x2A00 */ + 28, 28, 28, 28, 28, 28, 28, 28, /* 0x2C00 */ + 28, 28, 28, 28, 28, 28, 28, 28, /* 0x2E00 */ + 90, 91, 92, 93, 94, 56, 95, 28, /* 0x3000 */ + 96, 97, 98, 99, 83, 100, 83, 101, /* 0x3200 */ + 28, 28, 28, 28, 28, 28, 28, 28, /* 0x3400 */ + 28, 28, 28, 28, 28, 28, 28, 28, /* 0x3600 */ + 28, 28, 28, 28, 28, 28, 28, 28, /* 0x3800 */ + 28, 28, 28, 28, 28, 28, 28, 28, /* 0x3A00 */ + 28, 28, 28, 28, 28, 28, 28, 28, /* 0x3C00 */ + 28, 28, 28, 28, 28, 28, 28, 28, /* 0x3E00 */ + 28, 28, 28, 28, 28, 28, 28, 28, /* 0x4000 */ + 28, 28, 28, 28, 28, 28, 28, 28, /* 0x4200 */ + 28, 28, 28, 28, 28, 28, 28, 28, /* 0x4400 */ + 28, 28, 28, 28, 28, 28, 28, 28, /* 0x4600 */ + 28, 28, 28, 28, 28, 28, 28, 28, /* 0x4800 */ + 28, 28, 28, 28, 28, 28, 28, 28, /* 0x4A00 */ + 28, 28, 28, 28, 28, 28, 28, 28, /* 0x4C00 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0x4E00 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0x5000 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0x5200 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0x5400 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0x5600 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0x5800 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0x5A00 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0x5C00 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0x5E00 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0x6000 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0x6200 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0x6400 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0x6600 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0x6800 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0x6A00 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0x6C00 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0x6E00 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0x7000 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0x7200 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0x7400 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0x7600 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0x7800 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0x7A00 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0x7C00 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0x7E00 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0x8000 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0x8200 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0x8400 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0x8600 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0x8800 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0x8A00 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0x8C00 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0x8E00 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0x9000 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0x9200 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0x9400 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0x9600 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0x9800 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0x9A00 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0x9C00 */ + 56, 56, 56, 56, 56, 56, 102, 28, /* 0x9E00 */ + 28, 28, 28, 28, 28, 28, 28, 28, /* 0xA000 */ + 28, 28, 28, 28, 28, 28, 28, 28, /* 0xA200 */ + 28, 28, 28, 28, 28, 28, 28, 28, /* 0xA400 */ + 28, 28, 28, 28, 28, 28, 28, 28, /* 0xA600 */ + 28, 28, 28, 28, 28, 28, 28, 28, /* 0xA800 */ + 28, 28, 28, 28, 28, 28, 28, 28, /* 0xAA00 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0xAC00 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0xAE00 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0xB000 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0xB200 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0xB400 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0xB600 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0xB800 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0xBA00 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0xBC00 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0xBE00 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0xC000 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0xC200 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0xC400 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0xC600 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0xC800 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0xCA00 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0xCC00 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0xCE00 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0xD000 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0xD200 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0xD400 */ + 56, 56, 56, 56, 56, 56, 103, 28, /* 0xD600 */ +104, 104, 104, 104, 104, 104, 104, 104, /* 0xD800 */ +104, 104, 104, 104, 104, 104, 104, 104, /* 0xDA00 */ +104, 104, 104, 104, 104, 104, 104, 104, /* 0xDC00 */ +104, 104, 104, 104, 104, 104, 104, 104, /* 0xDE00 */ +105, 105, 105, 105, 105, 105, 105, 105, /* 0xE000 */ +105, 105, 105, 105, 105, 105, 105, 105, /* 0xE200 */ +105, 105, 105, 105, 105, 105, 105, 105, /* 0xE400 */ +105, 105, 105, 105, 105, 105, 105, 105, /* 0xE600 */ +105, 105, 105, 105, 105, 105, 105, 105, /* 0xE800 */ +105, 105, 105, 105, 105, 105, 105, 105, /* 0xEA00 */ +105, 105, 105, 105, 105, 105, 105, 105, /* 0xEC00 */ +105, 105, 105, 105, 105, 105, 105, 105, /* 0xEE00 */ +105, 105, 105, 105, 105, 105, 105, 105, /* 0xF000 */ +105, 105, 105, 105, 105, 105, 105, 105, /* 0xF200 */ +105, 105, 105, 105, 105, 105, 105, 105, /* 0xF400 */ +105, 105, 105, 105, 105, 105, 105, 105, /* 0xF600 */ +105, 105, 105, 105, 56, 56, 56, 56, /* 0xF800 */ +106, 28, 28, 28, 107, 108, 109, 110, /* 0xFA00 */ + 56, 56, 56, 56, 111, 112, 113, 114, /* 0xFC00 */ +115, 116, 56, 117, 118, 119, 120, 121 /* 0xFE00 */ +}; + +/* The Y table has 7808 entries for a total of 7808 bytes. */ + +const uint8 js_Y[] = { + 0, 0, 0, 0, 0, 0, 0, 0, /* 0 */ + 0, 1, 1, 1, 1, 1, 0, 0, /* 0 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 0 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 0 */ + 2, 3, 3, 3, 4, 3, 3, 3, /* 0 */ + 5, 6, 3, 7, 3, 8, 3, 3, /* 0 */ + 9, 9, 9, 9, 9, 9, 9, 9, /* 0 */ + 9, 9, 3, 3, 7, 7, 7, 3, /* 0 */ + 3, 10, 10, 10, 10, 10, 10, 10, /* 1 */ + 10, 10, 10, 10, 10, 10, 10, 10, /* 1 */ + 10, 10, 10, 10, 10, 10, 10, 10, /* 1 */ + 10, 10, 10, 5, 3, 6, 11, 12, /* 1 */ + 11, 13, 13, 13, 13, 13, 13, 13, /* 1 */ + 13, 13, 13, 13, 13, 13, 13, 13, /* 1 */ + 13, 13, 13, 13, 13, 13, 13, 13, /* 1 */ + 13, 13, 13, 5, 7, 6, 7, 0, /* 1 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 2 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 2 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 2 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 2 */ + 2, 3, 4, 4, 4, 4, 15, 15, /* 2 */ + 11, 15, 16, 5, 7, 8, 15, 11, /* 2 */ + 15, 7, 17, 17, 11, 16, 15, 3, /* 2 */ + 11, 18, 16, 6, 19, 19, 19, 3, /* 2 */ + 20, 20, 20, 20, 20, 20, 20, 20, /* 3 */ + 20, 20, 20, 20, 20, 20, 20, 20, /* 3 */ + 20, 20, 20, 20, 20, 20, 20, 7, /* 3 */ + 20, 20, 20, 20, 20, 20, 20, 16, /* 3 */ + 21, 21, 21, 21, 21, 21, 21, 21, /* 3 */ + 21, 21, 21, 21, 21, 21, 21, 21, /* 3 */ + 21, 21, 21, 21, 21, 21, 21, 7, /* 3 */ + 21, 21, 21, 21, 21, 21, 21, 22, /* 3 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 4 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 4 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 4 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 4 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 4 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 4 */ + 25, 26, 23, 24, 23, 24, 23, 24, /* 4 */ + 16, 23, 24, 23, 24, 23, 24, 23, /* 4 */ + 24, 23, 24, 23, 24, 23, 24, 23, /* 5 */ + 24, 16, 23, 24, 23, 24, 23, 24, /* 5 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 5 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 5 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 5 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 5 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 5 */ + 27, 23, 24, 23, 24, 23, 24, 28, /* 5 */ + 16, 29, 23, 24, 23, 24, 30, 23, /* 6 */ + 24, 31, 31, 23, 24, 16, 32, 32, /* 6 */ + 33, 23, 24, 31, 34, 16, 35, 36, /* 6 */ + 23, 24, 16, 16, 35, 37, 16, 38, /* 6 */ + 23, 24, 23, 24, 23, 24, 38, 23, /* 6 */ + 24, 39, 40, 16, 23, 24, 39, 23, /* 6 */ + 24, 41, 41, 23, 24, 23, 24, 42, /* 6 */ + 23, 24, 16, 40, 23, 24, 40, 40, /* 6 */ + 40, 40, 40, 40, 43, 44, 45, 43, /* 7 */ + 44, 45, 43, 44, 45, 23, 24, 23, /* 7 */ + 24, 23, 24, 23, 24, 23, 24, 23, /* 7 */ + 24, 23, 24, 23, 24, 16, 23, 24, /* 7 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 7 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 7 */ + 16, 43, 44, 45, 23, 24, 46, 46, /* 7 */ + 46, 46, 23, 24, 23, 24, 23, 24, /* 7 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 8 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 8 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 8 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 8 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 8 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 8 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 8 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 8 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 9 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 9 */ + 16, 16, 16, 47, 48, 16, 49, 49, /* 9 */ + 50, 50, 16, 51, 16, 16, 16, 16, /* 9 */ + 49, 16, 16, 52, 16, 16, 16, 16, /* 9 */ + 53, 54, 16, 16, 16, 16, 16, 54, /* 9 */ + 16, 16, 55, 16, 16, 16, 16, 16, /* 9 */ + 16, 16, 16, 16, 16, 16, 16, 16, /* 9 */ + 16, 16, 16, 56, 16, 16, 16, 16, /* 10 */ + 56, 16, 57, 57, 16, 16, 16, 16, /* 10 */ + 16, 16, 58, 16, 16, 16, 16, 16, /* 10 */ + 16, 16, 16, 16, 16, 16, 16, 16, /* 10 */ + 16, 16, 16, 16, 16, 16, 16, 16, /* 10 */ + 16, 46, 46, 46, 46, 46, 46, 46, /* 10 */ + 59, 59, 59, 59, 59, 59, 59, 59, /* 10 */ + 59, 11, 11, 59, 59, 59, 59, 59, /* 10 */ + 59, 59, 11, 11, 11, 11, 11, 11, /* 11 */ + 11, 11, 11, 11, 11, 11, 11, 11, /* 11 */ + 59, 59, 11, 11, 11, 11, 11, 11, /* 11 */ + 11, 11, 11, 11, 11, 11, 11, 46, /* 11 */ + 59, 59, 59, 59, 59, 11, 11, 11, /* 11 */ + 11, 11, 46, 46, 46, 46, 46, 46, /* 11 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 11 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 11 */ + 60, 60, 60, 60, 60, 60, 60, 60, /* 12 */ + 60, 60, 60, 60, 60, 60, 60, 60, /* 12 */ + 60, 60, 60, 60, 60, 60, 60, 60, /* 12 */ + 60, 60, 60, 60, 60, 60, 60, 60, /* 12 */ + 60, 60, 60, 60, 60, 60, 60, 60, /* 12 */ + 60, 60, 60, 60, 60, 60, 60, 60, /* 12 */ + 60, 60, 60, 60, 60, 60, 60, 60, /* 12 */ + 60, 60, 60, 60, 60, 60, 60, 60, /* 12 */ + 60, 60, 60, 60, 60, 60, 46, 46, /* 13 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 13 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 13 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 13 */ + 60, 60, 46, 46, 46, 46, 46, 46, /* 13 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 13 */ + 46, 46, 46, 46, 3, 3, 46, 46, /* 13 */ + 46, 46, 59, 46, 46, 46, 3, 46, /* 13 */ + 46, 46, 46, 46, 11, 11, 61, 3, /* 14 */ + 62, 62, 62, 46, 63, 46, 64, 64, /* 14 */ + 16, 20, 20, 20, 20, 20, 20, 20, /* 14 */ + 20, 20, 20, 20, 20, 20, 20, 20, /* 14 */ + 20, 20, 46, 20, 20, 20, 20, 20, /* 14 */ + 20, 20, 20, 20, 65, 66, 66, 66, /* 14 */ + 16, 21, 21, 21, 21, 21, 21, 21, /* 14 */ + 21, 21, 21, 21, 21, 21, 21, 21, /* 14 */ + 21, 21, 16, 21, 21, 21, 21, 21, /* 15 */ + 21, 21, 21, 21, 67, 68, 68, 46, /* 15 */ + 69, 70, 38, 38, 38, 71, 72, 46, /* 15 */ + 46, 46, 38, 46, 38, 46, 38, 46, /* 15 */ + 38, 46, 23, 24, 23, 24, 23, 24, /* 15 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 15 */ + 73, 74, 16, 40, 46, 46, 46, 46, /* 15 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 15 */ + 46, 75, 75, 75, 75, 75, 75, 75, /* 16 */ + 75, 75, 75, 75, 75, 46, 75, 75, /* 16 */ + 20, 20, 20, 20, 20, 20, 20, 20, /* 16 */ + 20, 20, 20, 20, 20, 20, 20, 20, /* 16 */ + 20, 20, 20, 20, 20, 20, 20, 20, /* 16 */ + 20, 20, 20, 20, 20, 20, 20, 20, /* 16 */ + 21, 21, 21, 21, 21, 21, 21, 21, /* 16 */ + 21, 21, 21, 21, 21, 21, 21, 21, /* 16 */ + 21, 21, 21, 21, 21, 21, 21, 21, /* 17 */ + 21, 21, 21, 21, 21, 21, 21, 21, /* 17 */ + 46, 74, 74, 74, 74, 74, 74, 74, /* 17 */ + 74, 74, 74, 74, 74, 46, 74, 74, /* 17 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 17 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 17 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 17 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 17 */ + 23, 24, 15, 60, 60, 60, 60, 46, /* 18 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 18 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 18 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 18 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 18 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 18 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 18 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 18 */ + 40, 23, 24, 23, 24, 46, 46, 23, /* 19 */ + 24, 46, 46, 23, 24, 46, 46, 46, /* 19 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 19 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 19 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 19 */ + 23, 24, 23, 24, 46, 46, 23, 24, /* 19 */ + 23, 24, 23, 24, 23, 24, 46, 46, /* 19 */ + 23, 24, 46, 46, 46, 46, 46, 46, /* 19 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 20 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 20 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 20 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 20 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 20 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 20 */ + 46, 76, 76, 76, 76, 76, 76, 76, /* 20 */ + 76, 76, 76, 76, 76, 76, 76, 76, /* 20 */ + 76, 76, 76, 76, 76, 76, 76, 76, /* 21 */ + 76, 76, 76, 76, 76, 76, 76, 76, /* 21 */ + 76, 76, 76, 76, 76, 76, 76, 46, /* 21 */ + 46, 59, 3, 3, 3, 3, 3, 3, /* 21 */ + 46, 77, 77, 77, 77, 77, 77, 77, /* 21 */ + 77, 77, 77, 77, 77, 77, 77, 77, /* 21 */ + 77, 77, 77, 77, 77, 77, 77, 77, /* 21 */ + 77, 77, 77, 77, 77, 77, 77, 77, /* 21 */ + 77, 77, 77, 77, 77, 77, 77, 16, /* 22 */ + 46, 3, 46, 46, 46, 46, 46, 46, /* 22 */ + 46, 60, 60, 60, 60, 60, 60, 60, /* 22 */ + 60, 60, 60, 60, 60, 60, 60, 60, /* 22 */ + 60, 60, 46, 60, 60, 60, 60, 60, /* 22 */ + 60, 60, 60, 60, 60, 60, 60, 60, /* 22 */ + 60, 60, 60, 60, 60, 60, 60, 60, /* 22 */ + 60, 60, 46, 60, 60, 60, 3, 60, /* 22 */ + 3, 60, 60, 3, 60, 46, 46, 46, /* 23 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 23 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 23 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 23 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 23 */ + 40, 40, 40, 46, 46, 46, 46, 46, /* 23 */ + 40, 40, 40, 3, 3, 46, 46, 46, /* 23 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 23 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 24 */ + 46, 46, 46, 46, 3, 46, 46, 46, /* 24 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 24 */ + 46, 46, 46, 3, 46, 46, 46, 3, /* 24 */ + 46, 40, 40, 40, 40, 40, 40, 40, /* 24 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 24 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 24 */ + 40, 40, 40, 46, 46, 46, 46, 46, /* 24 */ + 59, 40, 40, 40, 40, 40, 40, 40, /* 25 */ + 40, 40, 40, 60, 60, 60, 60, 60, /* 25 */ + 60, 60, 60, 46, 46, 46, 46, 46, /* 25 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 25 */ + 78, 78, 78, 78, 78, 78, 78, 78, /* 25 */ + 78, 78, 3, 3, 3, 3, 46, 46, /* 25 */ + 60, 40, 40, 40, 40, 40, 40, 40, /* 25 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 25 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 26 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 26 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 26 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 26 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 26 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 26 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 26 */ + 46, 46, 40, 40, 40, 40, 40, 46, /* 26 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 27 */ + 40, 40, 40, 40, 40, 40, 40, 46, /* 27 */ + 40, 40, 40, 40, 3, 40, 60, 60, /* 27 */ + 60, 60, 60, 60, 60, 79, 79, 60, /* 27 */ + 60, 60, 60, 60, 60, 59, 59, 60, /* 27 */ + 60, 15, 60, 60, 60, 60, 46, 46, /* 27 */ + 9, 9, 9, 9, 9, 9, 9, 9, /* 27 */ + 9, 9, 46, 46, 46, 46, 46, 46, /* 27 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 28 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 28 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 28 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 28 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 28 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 28 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 28 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 28 */ + 46, 60, 60, 80, 46, 40, 40, 40, /* 29 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 29 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 29 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 29 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 29 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 29 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 29 */ + 40, 40, 46, 46, 60, 40, 80, 80, /* 29 */ + 80, 60, 60, 60, 60, 60, 60, 60, /* 30 */ + 60, 80, 80, 80, 80, 60, 46, 46, /* 30 */ + 15, 60, 60, 60, 60, 46, 46, 46, /* 30 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 30 */ + 40, 40, 60, 60, 3, 3, 81, 81, /* 30 */ + 81, 81, 81, 81, 81, 81, 81, 81, /* 30 */ + 3, 46, 46, 46, 46, 46, 46, 46, /* 30 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 30 */ + 46, 60, 80, 80, 46, 40, 40, 40, /* 31 */ + 40, 40, 40, 40, 40, 46, 46, 40, /* 31 */ + 40, 46, 46, 40, 40, 40, 40, 40, /* 31 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 31 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 31 */ + 40, 46, 40, 40, 40, 40, 40, 40, /* 31 */ + 40, 46, 40, 46, 46, 46, 40, 40, /* 31 */ + 40, 40, 46, 46, 60, 46, 80, 80, /* 31 */ + 80, 60, 60, 60, 60, 46, 46, 80, /* 32 */ + 80, 46, 46, 80, 80, 60, 46, 46, /* 32 */ + 46, 46, 46, 46, 46, 46, 46, 80, /* 32 */ + 46, 46, 46, 46, 40, 40, 46, 40, /* 32 */ + 40, 40, 60, 60, 46, 46, 81, 81, /* 32 */ + 81, 81, 81, 81, 81, 81, 81, 81, /* 32 */ + 40, 40, 4, 4, 82, 82, 82, 82, /* 32 */ + 19, 83, 15, 46, 46, 46, 46, 46, /* 32 */ + 46, 46, 60, 46, 46, 40, 40, 40, /* 33 */ + 40, 40, 40, 46, 46, 46, 46, 40, /* 33 */ + 40, 46, 46, 40, 40, 40, 40, 40, /* 33 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 33 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 33 */ + 40, 46, 40, 40, 40, 40, 40, 40, /* 33 */ + 40, 46, 40, 40, 46, 40, 40, 46, /* 33 */ + 40, 40, 46, 46, 60, 46, 80, 80, /* 33 */ + 80, 60, 60, 46, 46, 46, 46, 60, /* 34 */ + 60, 46, 46, 60, 60, 60, 46, 46, /* 34 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 34 */ + 46, 40, 40, 40, 40, 46, 40, 46, /* 34 */ + 46, 46, 46, 46, 46, 46, 81, 81, /* 34 */ + 81, 81, 81, 81, 81, 81, 81, 81, /* 34 */ + 60, 60, 40, 40, 40, 46, 46, 46, /* 34 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 34 */ + 46, 60, 60, 80, 46, 40, 40, 40, /* 35 */ + 40, 40, 40, 40, 46, 40, 46, 40, /* 35 */ + 40, 40, 46, 40, 40, 40, 40, 40, /* 35 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 35 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 35 */ + 40, 46, 40, 40, 40, 40, 40, 40, /* 35 */ + 40, 46, 40, 40, 46, 40, 40, 40, /* 35 */ + 40, 40, 46, 46, 60, 40, 80, 80, /* 35 */ + 80, 60, 60, 60, 60, 60, 46, 60, /* 36 */ + 60, 80, 46, 80, 80, 60, 46, 46, /* 36 */ + 15, 46, 46, 46, 46, 46, 46, 46, /* 36 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 36 */ + 40, 46, 46, 46, 46, 46, 81, 81, /* 36 */ + 81, 81, 81, 81, 81, 81, 81, 81, /* 36 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 36 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 36 */ + 46, 60, 80, 80, 46, 40, 40, 40, /* 37 */ + 40, 40, 40, 40, 40, 46, 46, 40, /* 37 */ + 40, 46, 46, 40, 40, 40, 40, 40, /* 37 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 37 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 37 */ + 40, 46, 40, 40, 40, 40, 40, 40, /* 37 */ + 40, 46, 40, 40, 46, 46, 40, 40, /* 37 */ + 40, 40, 46, 46, 60, 40, 80, 60, /* 37 */ + 80, 60, 60, 60, 46, 46, 46, 80, /* 38 */ + 80, 46, 46, 80, 80, 60, 46, 46, /* 38 */ + 46, 46, 46, 46, 46, 46, 60, 80, /* 38 */ + 46, 46, 46, 46, 40, 40, 46, 40, /* 38 */ + 40, 40, 46, 46, 46, 46, 81, 81, /* 38 */ + 81, 81, 81, 81, 81, 81, 81, 81, /* 38 */ + 15, 46, 46, 46, 46, 46, 46, 46, /* 38 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 38 */ + 46, 46, 60, 80, 46, 40, 40, 40, /* 39 */ + 40, 40, 40, 46, 46, 46, 40, 40, /* 39 */ + 40, 46, 40, 40, 40, 40, 46, 46, /* 39 */ + 46, 40, 40, 46, 40, 46, 40, 40, /* 39 */ + 46, 46, 46, 40, 40, 46, 46, 46, /* 39 */ + 40, 40, 40, 46, 46, 46, 40, 40, /* 39 */ + 40, 40, 40, 40, 40, 40, 46, 40, /* 39 */ + 40, 40, 46, 46, 46, 46, 80, 80, /* 39 */ + 60, 80, 80, 46, 46, 46, 80, 80, /* 40 */ + 80, 46, 80, 80, 80, 60, 46, 46, /* 40 */ + 46, 46, 46, 46, 46, 46, 46, 80, /* 40 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 40 */ + 46, 46, 46, 46, 46, 46, 46, 81, /* 40 */ + 81, 81, 81, 81, 81, 81, 81, 81, /* 40 */ + 84, 19, 19, 46, 46, 46, 46, 46, /* 40 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 40 */ + 46, 80, 80, 80, 46, 40, 40, 40, /* 41 */ + 40, 40, 40, 40, 40, 46, 40, 40, /* 41 */ + 40, 46, 40, 40, 40, 40, 40, 40, /* 41 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 41 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 41 */ + 40, 46, 40, 40, 40, 40, 40, 40, /* 41 */ + 40, 40, 40, 40, 46, 40, 40, 40, /* 41 */ + 40, 40, 46, 46, 46, 46, 60, 60, /* 41 */ + 60, 80, 80, 80, 80, 46, 60, 60, /* 42 */ + 60, 46, 60, 60, 60, 60, 46, 46, /* 42 */ + 46, 46, 46, 46, 46, 60, 60, 46, /* 42 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 42 */ + 40, 40, 46, 46, 46, 46, 81, 81, /* 42 */ + 81, 81, 81, 81, 81, 81, 81, 81, /* 42 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 42 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 42 */ + 46, 46, 80, 80, 46, 40, 40, 40, /* 43 */ + 40, 40, 40, 40, 40, 46, 40, 40, /* 43 */ + 40, 46, 40, 40, 40, 40, 40, 40, /* 43 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 43 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 43 */ + 40, 46, 40, 40, 40, 40, 40, 40, /* 43 */ + 40, 40, 40, 40, 46, 40, 40, 40, /* 43 */ + 40, 40, 46, 46, 46, 46, 80, 60, /* 43 */ + 80, 80, 80, 80, 80, 46, 60, 80, /* 44 */ + 80, 46, 80, 80, 60, 60, 46, 46, /* 44 */ + 46, 46, 46, 46, 46, 80, 80, 46, /* 44 */ + 46, 46, 46, 46, 46, 46, 40, 46, /* 44 */ + 40, 40, 46, 46, 46, 46, 81, 81, /* 44 */ + 81, 81, 81, 81, 81, 81, 81, 81, /* 44 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 44 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 44 */ + 46, 46, 80, 80, 46, 40, 40, 40, /* 45 */ + 40, 40, 40, 40, 40, 46, 40, 40, /* 45 */ + 40, 46, 40, 40, 40, 40, 40, 40, /* 45 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 45 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 45 */ + 40, 46, 40, 40, 40, 40, 40, 40, /* 45 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 45 */ + 40, 40, 46, 46, 46, 46, 80, 80, /* 45 */ + 80, 60, 60, 60, 46, 46, 80, 80, /* 46 */ + 80, 46, 80, 80, 80, 60, 46, 46, /* 46 */ + 46, 46, 46, 46, 46, 46, 46, 80, /* 46 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 46 */ + 40, 40, 46, 46, 46, 46, 81, 81, /* 46 */ + 81, 81, 81, 81, 81, 81, 81, 81, /* 46 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 46 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 46 */ + 46, 40, 40, 40, 40, 40, 40, 40, /* 47 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 47 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 47 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 47 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 47 */ + 40, 40, 40, 40, 40, 40, 40, 3, /* 47 */ + 40, 60, 40, 40, 60, 60, 60, 60, /* 47 */ + 60, 60, 60, 46, 46, 46, 46, 4, /* 47 */ + 40, 40, 40, 40, 40, 40, 59, 60, /* 48 */ + 60, 60, 60, 60, 60, 60, 60, 15, /* 48 */ + 9, 9, 9, 9, 9, 9, 9, 9, /* 48 */ + 9, 9, 3, 3, 46, 46, 46, 46, /* 48 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 48 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 48 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 48 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 48 */ + 46, 40, 40, 46, 40, 46, 46, 40, /* 49 */ + 40, 46, 40, 46, 46, 40, 46, 46, /* 49 */ + 46, 46, 46, 46, 40, 40, 40, 40, /* 49 */ + 46, 40, 40, 40, 40, 40, 40, 40, /* 49 */ + 46, 40, 40, 40, 46, 40, 46, 40, /* 49 */ + 46, 46, 40, 40, 46, 40, 40, 3, /* 49 */ + 40, 60, 40, 40, 60, 60, 60, 60, /* 49 */ + 60, 60, 46, 60, 60, 40, 46, 46, /* 49 */ + 40, 40, 40, 40, 40, 46, 59, 46, /* 50 */ + 60, 60, 60, 60, 60, 60, 46, 46, /* 50 */ + 9, 9, 9, 9, 9, 9, 9, 9, /* 50 */ + 9, 9, 46, 46, 40, 40, 46, 46, /* 50 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 50 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 50 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 50 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 50 */ + 15, 15, 15, 15, 3, 3, 3, 3, /* 51 */ + 3, 3, 3, 3, 3, 3, 3, 3, /* 51 */ + 3, 3, 3, 15, 15, 15, 15, 15, /* 51 */ + 60, 60, 15, 15, 15, 15, 15, 15, /* 51 */ + 78, 78, 78, 78, 78, 78, 78, 78, /* 51 */ + 78, 78, 85, 85, 85, 85, 85, 85, /* 51 */ + 85, 85, 85, 85, 15, 60, 15, 60, /* 51 */ + 15, 60, 5, 6, 5, 6, 80, 80, /* 51 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 52 */ + 46, 40, 40, 40, 40, 40, 40, 40, /* 52 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 52 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 52 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 52 */ + 40, 40, 46, 46, 46, 46, 46, 46, /* 52 */ + 46, 60, 60, 60, 60, 60, 60, 60, /* 52 */ + 60, 60, 60, 60, 60, 60, 60, 80, /* 52 */ + 60, 60, 60, 60, 60, 3, 60, 60, /* 53 */ + 60, 60, 60, 60, 46, 46, 46, 46, /* 53 */ + 60, 60, 60, 60, 60, 60, 46, 60, /* 53 */ + 46, 60, 60, 60, 60, 60, 60, 60, /* 53 */ + 60, 60, 60, 60, 60, 60, 60, 60, /* 53 */ + 60, 60, 60, 60, 60, 60, 46, 46, /* 53 */ + 46, 60, 60, 60, 60, 60, 60, 60, /* 53 */ + 46, 60, 46, 46, 46, 46, 46, 46, /* 53 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 54 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 54 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 54 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 54 */ + 76, 76, 76, 76, 76, 76, 76, 76, /* 54 */ + 76, 76, 76, 76, 76, 76, 76, 76, /* 54 */ + 76, 76, 76, 76, 76, 76, 76, 76, /* 54 */ + 76, 76, 76, 76, 76, 76, 76, 76, /* 54 */ + 76, 76, 76, 76, 76, 76, 46, 46, /* 55 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 55 */ + 16, 16, 16, 16, 16, 16, 16, 16, /* 55 */ + 16, 16, 16, 16, 16, 16, 16, 16, /* 55 */ + 16, 16, 16, 16, 16, 16, 16, 16, /* 55 */ + 16, 16, 16, 16, 16, 16, 16, 16, /* 55 */ + 16, 16, 16, 16, 16, 16, 16, 46, /* 55 */ + 46, 46, 46, 3, 46, 46, 46, 46, /* 55 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 56 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 56 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 56 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 56 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 56 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 56 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 56 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 56 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 57 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 57 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 57 */ + 40, 40, 46, 46, 46, 46, 46, 40, /* 57 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 57 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 57 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 57 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 57 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 58 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 58 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 58 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 58 */ + 40, 40, 40, 46, 46, 46, 46, 46, /* 58 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 58 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 58 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 58 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 59 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 59 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 59 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 59 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 59 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 59 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 59 */ + 40, 40, 46, 46, 46, 46, 46, 46, /* 59 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 60 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 60 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 60 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 60 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 60 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 60 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 60 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 60 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 61 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 61 */ + 23, 24, 23, 24, 23, 24, 16, 16, /* 61 */ + 16, 16, 16, 16, 46, 46, 46, 46, /* 61 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 61 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 61 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 61 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 61 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 62 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 62 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 62 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 62 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 62 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 62 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 62 */ + 23, 24, 46, 46, 46, 46, 46, 46, /* 62 */ + 86, 86, 86, 86, 86, 86, 86, 86, /* 63 */ + 87, 87, 87, 87, 87, 87, 87, 87, /* 63 */ + 86, 86, 86, 86, 86, 86, 46, 46, /* 63 */ + 87, 87, 87, 87, 87, 87, 46, 46, /* 63 */ + 86, 86, 86, 86, 86, 86, 86, 86, /* 63 */ + 87, 87, 87, 87, 87, 87, 87, 87, /* 63 */ + 86, 86, 86, 86, 86, 86, 86, 86, /* 63 */ + 87, 87, 87, 87, 87, 87, 87, 87, /* 63 */ + 86, 86, 86, 86, 86, 86, 46, 46, /* 64 */ + 87, 87, 87, 87, 87, 87, 46, 46, /* 64 */ + 16, 86, 16, 86, 16, 86, 16, 86, /* 64 */ + 46, 87, 46, 87, 46, 87, 46, 87, /* 64 */ + 86, 86, 86, 86, 86, 86, 86, 86, /* 64 */ + 87, 87, 87, 87, 87, 87, 87, 87, /* 64 */ + 88, 88, 89, 89, 89, 89, 90, 90, /* 64 */ + 91, 91, 92, 92, 93, 93, 46, 46, /* 64 */ + 86, 86, 86, 86, 86, 86, 86, 86, /* 65 */ + 87, 87, 87, 87, 87, 87, 87, 87, /* 65 */ + 86, 86, 86, 86, 86, 86, 86, 86, /* 65 */ + 87, 87, 87, 87, 87, 87, 87, 87, /* 65 */ + 86, 86, 86, 86, 86, 86, 86, 86, /* 65 */ + 87, 87, 87, 87, 87, 87, 87, 87, /* 65 */ + 86, 86, 16, 94, 16, 46, 16, 16, /* 65 */ + 87, 87, 95, 95, 96, 11, 38, 11, /* 65 */ + 11, 11, 16, 94, 16, 46, 16, 16, /* 66 */ + 97, 97, 97, 97, 96, 11, 11, 11, /* 66 */ + 86, 86, 16, 16, 46, 46, 16, 16, /* 66 */ + 87, 87, 98, 98, 46, 11, 11, 11, /* 66 */ + 86, 86, 16, 16, 16, 99, 16, 16, /* 66 */ + 87, 87, 100, 100, 101, 11, 11, 11, /* 66 */ + 46, 46, 16, 94, 16, 46, 16, 16, /* 66 */ +102, 102, 103, 103, 96, 11, 11, 46, /* 66 */ + 2, 2, 2, 2, 2, 2, 2, 2, /* 67 */ + 2, 2, 2, 2, 104, 104, 104, 104, /* 67 */ + 8, 8, 8, 8, 8, 8, 3, 3, /* 67 */ + 5, 6, 5, 5, 5, 6, 5, 5, /* 67 */ + 3, 3, 3, 3, 3, 3, 3, 3, /* 67 */ +105, 106, 104, 104, 104, 104, 104, 46, /* 67 */ + 3, 3, 3, 3, 3, 3, 3, 3, /* 67 */ + 3, 5, 6, 3, 3, 3, 3, 12, /* 67 */ + 12, 3, 3, 3, 7, 5, 6, 46, /* 68 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 68 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 68 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 68 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 68 */ + 46, 46, 104, 104, 104, 104, 104, 104, /* 68 */ + 17, 46, 46, 46, 17, 17, 17, 17, /* 68 */ + 17, 17, 7, 7, 7, 5, 6, 16, /* 68 */ +107, 107, 107, 107, 107, 107, 107, 107, /* 69 */ +107, 107, 7, 7, 7, 5, 6, 46, /* 69 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 69 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 69 */ + 4, 4, 4, 4, 4, 4, 4, 4, /* 69 */ + 4, 4, 4, 4, 46, 46, 46, 46, /* 69 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 69 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 69 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 70 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 70 */ + 60, 60, 60, 60, 60, 60, 60, 60, /* 70 */ + 60, 60, 60, 60, 60, 79, 79, 79, /* 70 */ + 79, 60, 46, 46, 46, 46, 46, 46, /* 70 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 70 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 70 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 70 */ + 15, 15, 38, 15, 15, 15, 15, 38, /* 71 */ + 15, 15, 16, 38, 38, 38, 16, 16, /* 71 */ + 38, 38, 38, 16, 15, 38, 15, 15, /* 71 */ + 38, 38, 38, 38, 38, 38, 15, 15, /* 71 */ + 15, 15, 15, 15, 38, 15, 38, 15, /* 71 */ + 38, 15, 38, 38, 38, 38, 16, 16, /* 71 */ + 38, 38, 15, 38, 16, 40, 40, 40, /* 71 */ + 40, 46, 46, 46, 46, 46, 46, 46, /* 71 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 72 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 72 */ + 46, 46, 46, 19, 19, 19, 19, 19, /* 72 */ + 19, 19, 19, 19, 19, 19, 19, 108, /* 72 */ +109, 109, 109, 109, 109, 109, 109, 109, /* 72 */ +109, 109, 109, 109, 110, 110, 110, 110, /* 72 */ +111, 111, 111, 111, 111, 111, 111, 111, /* 72 */ +111, 111, 111, 111, 112, 112, 112, 112, /* 72 */ +113, 113, 113, 46, 46, 46, 46, 46, /* 73 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 73 */ + 7, 7, 7, 7, 7, 15, 15, 15, /* 73 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 73 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 73 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 73 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 73 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 73 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 74 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 74 */ + 15, 15, 7, 15, 7, 15, 15, 15, /* 74 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 74 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 74 */ + 15, 15, 15, 46, 46, 46, 46, 46, /* 74 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 74 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 74 */ + 7, 7, 7, 7, 7, 7, 7, 7, /* 75 */ + 7, 7, 7, 7, 7, 7, 7, 7, /* 75 */ + 7, 7, 7, 7, 7, 7, 7, 7, /* 75 */ + 7, 7, 7, 7, 7, 7, 7, 7, /* 75 */ + 7, 7, 7, 7, 7, 7, 7, 7, /* 75 */ + 7, 7, 7, 7, 7, 7, 7, 7, /* 75 */ + 7, 7, 7, 7, 7, 7, 7, 7, /* 75 */ + 7, 7, 7, 7, 7, 7, 7, 7, /* 75 */ + 7, 7, 7, 7, 7, 7, 7, 7, /* 76 */ + 7, 7, 7, 7, 7, 7, 7, 7, /* 76 */ + 7, 7, 7, 7, 7, 7, 7, 7, /* 76 */ + 7, 7, 7, 7, 7, 7, 7, 7, /* 76 */ + 7, 7, 7, 7, 7, 7, 7, 7, /* 76 */ + 7, 7, 7, 7, 7, 7, 7, 7, /* 76 */ + 7, 7, 46, 46, 46, 46, 46, 46, /* 76 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 76 */ + 15, 46, 15, 15, 15, 15, 15, 15, /* 77 */ + 7, 7, 7, 7, 15, 15, 15, 15, /* 77 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 77 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 77 */ + 7, 7, 15, 15, 15, 15, 15, 15, /* 77 */ + 15, 5, 6, 15, 15, 15, 15, 15, /* 77 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 77 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 77 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 78 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 78 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 78 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 78 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 78 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 78 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 78 */ + 15, 15, 15, 46, 46, 46, 46, 46, /* 78 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 79 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 79 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 79 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 79 */ + 15, 15, 15, 15, 15, 46, 46, 46, /* 79 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 79 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 79 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 79 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 80 */ + 15, 15, 15, 46, 46, 46, 46, 46, /* 80 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 80 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 80 */ +114, 114, 114, 114, 114, 114, 114, 114, /* 80 */ +114, 114, 114, 114, 114, 114, 114, 114, /* 80 */ +114, 114, 114, 114, 82, 82, 82, 82, /* 80 */ + 82, 82, 82, 82, 82, 82, 82, 82, /* 80 */ + 82, 82, 82, 82, 82, 82, 82, 82, /* 81 */ +115, 115, 115, 115, 115, 115, 115, 115, /* 81 */ +115, 115, 115, 115, 115, 115, 115, 115, /* 81 */ +115, 115, 115, 115, 15, 15, 15, 15, /* 81 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 81 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 81 */ + 15, 15, 15, 15, 15, 15, 116, 116, /* 81 */ +116, 116, 116, 116, 116, 116, 116, 116, /* 81 */ +116, 116, 116, 116, 116, 116, 116, 116, /* 82 */ +116, 116, 116, 116, 116, 116, 116, 116, /* 82 */ +117, 117, 117, 117, 117, 117, 117, 117, /* 82 */ +117, 117, 117, 117, 117, 117, 117, 117, /* 82 */ +117, 117, 117, 117, 117, 117, 117, 117, /* 82 */ +117, 117, 118, 46, 46, 46, 46, 46, /* 82 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 82 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 82 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 83 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 83 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 83 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 83 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 83 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 83 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 83 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 83 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 84 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 84 */ + 15, 15, 15, 15, 15, 15, 46, 46, /* 84 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 84 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 84 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 84 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 84 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 84 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 85 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 85 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 85 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 85 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 85 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 85 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 85 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 85 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 86 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 86 */ + 15, 15, 15, 15, 46, 46, 46, 46, /* 86 */ + 46, 46, 15, 15, 15, 15, 15, 15, /* 86 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 86 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 86 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 86 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 86 */ + 46, 15, 15, 15, 15, 46, 15, 15, /* 87 */ + 15, 15, 46, 46, 15, 15, 15, 15, /* 87 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 87 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 87 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 87 */ + 46, 15, 15, 15, 15, 15, 15, 15, /* 87 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 87 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 87 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 88 */ + 15, 15, 15, 15, 46, 15, 46, 15, /* 88 */ + 15, 15, 15, 46, 46, 46, 15, 46, /* 88 */ + 15, 15, 15, 15, 15, 15, 15, 46, /* 88 */ + 46, 15, 15, 15, 15, 15, 15, 15, /* 88 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 88 */ + 46, 46, 46, 46, 46, 46, 119, 119, /* 88 */ +119, 119, 119, 119, 119, 119, 119, 119, /* 88 */ +114, 114, 114, 114, 114, 114, 114, 114, /* 89 */ +114, 114, 83, 83, 83, 83, 83, 83, /* 89 */ + 83, 83, 83, 83, 15, 46, 46, 46, /* 89 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 89 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 89 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 89 */ + 46, 15, 15, 15, 15, 15, 15, 15, /* 89 */ + 15, 15, 15, 15, 15, 15, 15, 46, /* 89 */ + 2, 3, 3, 3, 15, 59, 3, 120, /* 90 */ + 5, 6, 5, 6, 5, 6, 5, 6, /* 90 */ + 5, 6, 15, 15, 5, 6, 5, 6, /* 90 */ + 5, 6, 5, 6, 8, 5, 6, 5, /* 90 */ + 15, 121, 121, 121, 121, 121, 121, 121, /* 90 */ +121, 121, 60, 60, 60, 60, 60, 60, /* 90 */ + 8, 59, 59, 59, 59, 59, 15, 15, /* 90 */ + 46, 46, 46, 46, 46, 46, 46, 15, /* 90 */ + 46, 40, 40, 40, 40, 40, 40, 40, /* 91 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 91 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 91 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 91 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 91 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 91 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 91 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 91 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 92 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 92 */ + 40, 40, 40, 40, 40, 46, 46, 46, /* 92 */ + 46, 60, 60, 59, 59, 59, 59, 46, /* 92 */ + 46, 40, 40, 40, 40, 40, 40, 40, /* 92 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 92 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 92 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 92 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 93 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 93 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 93 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 93 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 93 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 93 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 93 */ + 40, 40, 40, 3, 59, 59, 59, 46, /* 93 */ + 46, 46, 46, 46, 46, 40, 40, 40, /* 94 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 94 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 94 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 94 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 94 */ + 40, 40, 40, 40, 40, 46, 46, 46, /* 94 */ + 46, 40, 40, 40, 40, 40, 40, 40, /* 94 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 94 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 95 */ + 40, 40, 40, 40, 40, 40, 40, 46, /* 95 */ + 15, 15, 85, 85, 85, 85, 15, 15, /* 95 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 95 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 95 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 95 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 95 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 95 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 96 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 96 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 96 */ + 15, 15, 15, 15, 15, 46, 46, 46, /* 96 */ + 85, 85, 85, 85, 85, 85, 85, 85, /* 96 */ + 85, 85, 15, 15, 15, 15, 15, 15, /* 96 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 96 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 96 */ + 15, 15, 15, 15, 46, 46, 46, 46, /* 97 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 97 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 97 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 97 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 97 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 97 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 97 */ + 15, 15, 15, 15, 46, 46, 46, 15, /* 97 */ +114, 114, 114, 114, 114, 114, 114, 114, /* 98 */ +114, 114, 15, 15, 15, 15, 15, 15, /* 98 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 98 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 98 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 98 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 98 */ + 15, 46, 46, 46, 46, 46, 46, 46, /* 98 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 98 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 99 */ + 15, 15, 15, 15, 46, 46, 46, 46, /* 99 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 99 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 99 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 99 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 99 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 99 */ + 15, 15, 15, 15, 15, 15, 15, 46, /* 99 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 100 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 100 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 100 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 100 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 100 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 100 */ + 15, 15, 15, 15, 15, 15, 15, 46, /* 100 */ + 46, 46, 46, 15, 15, 15, 15, 15, /* 100 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 101 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 101 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 101 */ + 15, 15, 15, 15, 15, 15, 46, 46, /* 101 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 101 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 101 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 101 */ + 15, 15, 15, 15, 15, 15, 15, 46, /* 101 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 102 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 102 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 102 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 102 */ + 40, 40, 40, 40, 40, 40, 46, 46, /* 102 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 102 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 102 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 102 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 103 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 103 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 103 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 103 */ + 40, 40, 40, 40, 46, 46, 46, 46, /* 103 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 103 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 103 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 103 */ +122, 122, 122, 122, 122, 122, 122, 122, /* 104 */ +122, 122, 122, 122, 122, 122, 122, 122, /* 104 */ +122, 122, 122, 122, 122, 122, 122, 122, /* 104 */ +122, 122, 122, 122, 122, 122, 122, 122, /* 104 */ +122, 122, 122, 122, 122, 122, 122, 122, /* 104 */ +122, 122, 122, 122, 122, 122, 122, 122, /* 104 */ +122, 122, 122, 122, 122, 122, 122, 122, /* 104 */ +122, 122, 122, 122, 122, 122, 122, 122, /* 104 */ +123, 123, 123, 123, 123, 123, 123, 123, /* 105 */ +123, 123, 123, 123, 123, 123, 123, 123, /* 105 */ +123, 123, 123, 123, 123, 123, 123, 123, /* 105 */ +123, 123, 123, 123, 123, 123, 123, 123, /* 105 */ +123, 123, 123, 123, 123, 123, 123, 123, /* 105 */ +123, 123, 123, 123, 123, 123, 123, 123, /* 105 */ +123, 123, 123, 123, 123, 123, 123, 123, /* 105 */ +123, 123, 123, 123, 123, 123, 123, 123, /* 105 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 106 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 106 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 106 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 106 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 106 */ + 40, 40, 40, 40, 40, 40, 46, 46, /* 106 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 106 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 106 */ + 16, 16, 16, 16, 16, 16, 16, 46, /* 107 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 107 */ + 46, 46, 46, 16, 16, 16, 16, 16, /* 107 */ + 46, 46, 46, 46, 46, 46, 60, 40, /* 107 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 107 */ + 40, 7, 40, 40, 40, 40, 40, 40, /* 107 */ + 40, 40, 40, 40, 40, 40, 40, 46, /* 107 */ + 40, 40, 40, 40, 40, 46, 40, 46, /* 107 */ + 40, 40, 46, 40, 40, 46, 40, 40, /* 108 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 108 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 108 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 108 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 108 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 108 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 108 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 108 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 109 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 109 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 109 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 109 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 109 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 109 */ + 40, 40, 46, 46, 46, 46, 46, 46, /* 109 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 109 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 110 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 110 */ + 46, 46, 46, 40, 40, 40, 40, 40, /* 110 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 110 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 110 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 110 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 110 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 110 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 111 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 111 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 111 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 111 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 111 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 111 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 111 */ + 40, 40, 40, 40, 40, 40, 5, 6, /* 111 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 112 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 112 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 112 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 112 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 112 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 112 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 112 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 112 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 113 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 113 */ + 46, 46, 40, 40, 40, 40, 40, 40, /* 113 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 113 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 113 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 113 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 113 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 113 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 114 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 114 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 114 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 114 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 114 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 114 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 114 */ + 40, 40, 40, 40, 46, 46, 46, 46, /* 114 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 115 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 115 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 115 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 115 */ + 60, 60, 60, 60, 46, 46, 46, 46, /* 115 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 115 */ + 3, 8, 8, 12, 12, 5, 6, 5, /* 115 */ + 6, 5, 6, 5, 6, 5, 6, 5, /* 115 */ + 6, 5, 6, 5, 6, 46, 46, 46, /* 116 */ + 46, 3, 3, 3, 3, 12, 12, 12, /* 116 */ + 3, 3, 3, 46, 3, 3, 3, 3, /* 116 */ + 8, 5, 6, 5, 6, 5, 6, 3, /* 116 */ + 3, 3, 7, 8, 7, 7, 7, 46, /* 116 */ + 3, 4, 3, 3, 46, 46, 46, 46, /* 116 */ + 40, 40, 40, 46, 40, 46, 40, 40, /* 116 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 116 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 117 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 117 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 117 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 117 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 117 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 117 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 117 */ + 40, 40, 40, 40, 40, 46, 46, 104, /* 117 */ + 46, 3, 3, 3, 4, 3, 3, 3, /* 118 */ + 5, 6, 3, 7, 3, 8, 3, 3, /* 118 */ + 9, 9, 9, 9, 9, 9, 9, 9, /* 118 */ + 9, 9, 3, 3, 7, 7, 7, 3, /* 118 */ + 3, 10, 10, 10, 10, 10, 10, 10, /* 118 */ + 10, 10, 10, 10, 10, 10, 10, 10, /* 118 */ + 10, 10, 10, 10, 10, 10, 10, 10, /* 118 */ + 10, 10, 10, 5, 3, 6, 11, 12, /* 118 */ + 11, 13, 13, 13, 13, 13, 13, 13, /* 119 */ + 13, 13, 13, 13, 13, 13, 13, 13, /* 119 */ + 13, 13, 13, 13, 13, 13, 13, 13, /* 119 */ + 13, 13, 13, 5, 7, 6, 7, 46, /* 119 */ + 46, 3, 5, 6, 3, 3, 40, 40, /* 119 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 119 */ + 59, 40, 40, 40, 40, 40, 40, 40, /* 119 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 119 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 120 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 120 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 120 */ + 40, 40, 40, 40, 40, 40, 59, 59, /* 120 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 120 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 120 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 120 */ + 40, 40, 40, 40, 40, 40, 40, 46, /* 120 */ + 46, 46, 40, 40, 40, 40, 40, 40, /* 121 */ + 46, 46, 40, 40, 40, 40, 40, 40, /* 121 */ + 46, 46, 40, 40, 40, 40, 40, 40, /* 121 */ + 46, 46, 40, 40, 40, 46, 46, 46, /* 121 */ + 4, 4, 7, 11, 15, 4, 4, 46, /* 121 */ + 7, 7, 7, 7, 7, 15, 15, 46, /* 121 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 121 */ + 46, 46, 46, 46, 46, 15, 46, 46 /* 121 */ +}; + +/* The A table has 124 entries for a total of 496 bytes. */ + +const uint32 js_A[] = { +0x0001000F, /* 0 Cc, ignorable */ +0x0004000F, /* 1 Cc, whitespace */ +0x0004000C, /* 2 Zs, whitespace */ +0x00000018, /* 3 Po */ +0x0006001A, /* 4 Sc, currency */ +0x00000015, /* 5 Ps */ +0x00000016, /* 6 Pe */ +0x00000019, /* 7 Sm */ +0x00000014, /* 8 Pd */ +0x00036009, /* 9 Nd, identifier part, decimal 16 */ +0x0827FE01, /* 10 Lu, hasLower (add 32), identifier start, supradecimal 31 */ +0x0000001B, /* 11 Sk */ +0x00050017, /* 12 Pc, underscore */ +0x0817FE02, /* 13 Ll, hasUpper (subtract 32), identifier start, supradecimal 31 */ +0x0000000C, /* 14 Zs */ +0x0000001C, /* 15 So */ +0x00070002, /* 16 Ll, identifier start */ +0x0000600B, /* 17 No, decimal 16 */ +0x0000500B, /* 18 No, decimal 8 */ +0x0000800B, /* 19 No, strange */ +0x08270001, /* 20 Lu, hasLower (add 32), identifier start */ +0x08170002, /* 21 Ll, hasUpper (subtract 32), identifier start */ +0xE1D70002, /* 22 Ll, hasUpper (subtract -121), identifier start */ +0x00670001, /* 23 Lu, hasLower (add 1), identifier start */ +0x00570002, /* 24 Ll, hasUpper (subtract 1), identifier start */ +0xCE670001, /* 25 Lu, hasLower (add -199), identifier start */ +0x3A170002, /* 26 Ll, hasUpper (subtract 232), identifier start */ +0xE1E70001, /* 27 Lu, hasLower (add -121), identifier start */ +0x4B170002, /* 28 Ll, hasUpper (subtract 300), identifier start */ +0x34A70001, /* 29 Lu, hasLower (add 210), identifier start */ +0x33A70001, /* 30 Lu, hasLower (add 206), identifier start */ +0x33670001, /* 31 Lu, hasLower (add 205), identifier start */ +0x32A70001, /* 32 Lu, hasLower (add 202), identifier start */ +0x32E70001, /* 33 Lu, hasLower (add 203), identifier start */ +0x33E70001, /* 34 Lu, hasLower (add 207), identifier start */ +0x34E70001, /* 35 Lu, hasLower (add 211), identifier start */ +0x34670001, /* 36 Lu, hasLower (add 209), identifier start */ +0x35670001, /* 37 Lu, hasLower (add 213), identifier start */ +0x00070001, /* 38 Lu, identifier start */ +0x36A70001, /* 39 Lu, hasLower (add 218), identifier start */ +0x00070005, /* 40 Lo, identifier start */ +0x36670001, /* 41 Lu, hasLower (add 217), identifier start */ +0x36E70001, /* 42 Lu, hasLower (add 219), identifier start */ +0x00AF0001, /* 43 Lu, hasLower (add 2), hasTitle, identifier start */ +0x007F0003, /* 44 Lt, hasUpper (subtract 1), hasLower (add 1), hasTitle, identifier start */ +0x009F0002, /* 45 Ll, hasUpper (subtract 2), hasTitle, identifier start */ +0x00000000, /* 46 unassigned */ +0x34970002, /* 47 Ll, hasUpper (subtract 210), identifier start */ +0x33970002, /* 48 Ll, hasUpper (subtract 206), identifier start */ +0x33570002, /* 49 Ll, hasUpper (subtract 205), identifier start */ +0x32970002, /* 50 Ll, hasUpper (subtract 202), identifier start */ +0x32D70002, /* 51 Ll, hasUpper (subtract 203), identifier start */ +0x33D70002, /* 52 Ll, hasUpper (subtract 207), identifier start */ +0x34570002, /* 53 Ll, hasUpper (subtract 209), identifier start */ +0x34D70002, /* 54 Ll, hasUpper (subtract 211), identifier start */ +0x35570002, /* 55 Ll, hasUpper (subtract 213), identifier start */ +0x36970002, /* 56 Ll, hasUpper (subtract 218), identifier start */ +0x36570002, /* 57 Ll, hasUpper (subtract 217), identifier start */ +0x36D70002, /* 58 Ll, hasUpper (subtract 219), identifier start */ +0x00070004, /* 59 Lm, identifier start */ +0x00030006, /* 60 Mn, identifier part */ +0x09A70001, /* 61 Lu, hasLower (add 38), identifier start */ +0x09670001, /* 62 Lu, hasLower (add 37), identifier start */ +0x10270001, /* 63 Lu, hasLower (add 64), identifier start */ +0x0FE70001, /* 64 Lu, hasLower (add 63), identifier start */ +0x09970002, /* 65 Ll, hasUpper (subtract 38), identifier start */ +0x09570002, /* 66 Ll, hasUpper (subtract 37), identifier start */ +0x10170002, /* 67 Ll, hasUpper (subtract 64), identifier start */ +0x0FD70002, /* 68 Ll, hasUpper (subtract 63), identifier start */ +0x0F970002, /* 69 Ll, hasUpper (subtract 62), identifier start */ +0x0E570002, /* 70 Ll, hasUpper (subtract 57), identifier start */ +0x0BD70002, /* 71 Ll, hasUpper (subtract 47), identifier start */ +0x0D970002, /* 72 Ll, hasUpper (subtract 54), identifier start */ +0x15970002, /* 73 Ll, hasUpper (subtract 86), identifier start */ +0x14170002, /* 74 Ll, hasUpper (subtract 80), identifier start */ +0x14270001, /* 75 Lu, hasLower (add 80), identifier start */ +0x0C270001, /* 76 Lu, hasLower (add 48), identifier start */ +0x0C170002, /* 77 Ll, hasUpper (subtract 48), identifier start */ +0x00034009, /* 78 Nd, identifier part, decimal 0 */ +0x00000007, /* 79 Me */ +0x00030008, /* 80 Mc, identifier part */ +0x00037409, /* 81 Nd, identifier part, decimal 26 */ +0x00005A0B, /* 82 No, decimal 13 */ +0x00006E0B, /* 83 No, decimal 23 */ +0x0000740B, /* 84 No, decimal 26 */ +0x0000000B, /* 85 No */ +0xFE170002, /* 86 Ll, hasUpper (subtract -8), identifier start */ +0xFE270001, /* 87 Lu, hasLower (add -8), identifier start */ +0xED970002, /* 88 Ll, hasUpper (subtract -74), identifier start */ +0xEA970002, /* 89 Ll, hasUpper (subtract -86), identifier start */ +0xE7170002, /* 90 Ll, hasUpper (subtract -100), identifier start */ +0xE0170002, /* 91 Ll, hasUpper (subtract -128), identifier start */ +0xE4170002, /* 92 Ll, hasUpper (subtract -112), identifier start */ +0xE0970002, /* 93 Ll, hasUpper (subtract -126), identifier start */ +0xFDD70002, /* 94 Ll, hasUpper (subtract -9), identifier start */ +0xEDA70001, /* 95 Lu, hasLower (add -74), identifier start */ +0xFDE70001, /* 96 Lu, hasLower (add -9), identifier start */ +0xEAA70001, /* 97 Lu, hasLower (add -86), identifier start */ +0xE7270001, /* 98 Lu, hasLower (add -100), identifier start */ +0xFE570002, /* 99 Ll, hasUpper (subtract -7), identifier start */ +0xE4270001, /* 100 Lu, hasLower (add -112), identifier start */ +0xFE670001, /* 101 Lu, hasLower (add -7), identifier start */ +0xE0270001, /* 102 Lu, hasLower (add -128), identifier start */ +0xE0A70001, /* 103 Lu, hasLower (add -126), identifier start */ +0x00010010, /* 104 Cf, ignorable */ +0x0004000D, /* 105 Zl, whitespace */ +0x0004000E, /* 106 Zp, whitespace */ +0x0000400B, /* 107 No, decimal 0 */ +0x0000440B, /* 108 No, decimal 2 */ +0x0427420A, /* 109 Nl, hasLower (add 16), identifier start, decimal 1 */ +0x0427800A, /* 110 Nl, hasLower (add 16), identifier start, strange */ +0x0417620A, /* 111 Nl, hasUpper (subtract 16), identifier start, decimal 17 */ +0x0417800A, /* 112 Nl, hasUpper (subtract 16), identifier start, strange */ +0x0007800A, /* 113 Nl, identifier start, strange */ +0x0000420B, /* 114 No, decimal 1 */ +0x0000720B, /* 115 No, decimal 25 */ +0x06A0001C, /* 116 So, hasLower (add 26) */ +0x0690001C, /* 117 So, hasUpper (subtract 26) */ +0x00006C0B, /* 118 No, decimal 22 */ +0x0000560B, /* 119 No, decimal 11 */ +0x0007720A, /* 120 Nl, identifier start, decimal 25 */ +0x0007400A, /* 121 Nl, identifier start, decimal 0 */ +0x00000013, /* 122 Cs */ +0x00000012 /* 123 Co */ +}; + +const jschar js_uriReservedPlusPound_ucstr[] = + {';', '/', '?', ':', '@', '&', '=', '+', '$', ',', '#', 0}; +const jschar js_uriUnescaped_ucstr[] = + {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', + 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', + 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', + '-', '_', '.', '!', '~', '*', '\'', '(', ')', 0}; + +#define URI_CHUNK 64U + +/* Concatenate jschars onto an unshared/newborn JSString. */ +static JSBool +AddCharsToURI(JSContext *cx, JSString *str, const jschar *chars, size_t length) +{ + size_t total; + + JS_ASSERT(!JSSTRING_IS_DEPENDENT(str)); + total = str->length + length + 1; + if (!str->chars || + JS_HOWMANY(total, URI_CHUNK) > JS_HOWMANY(str->length + 1, URI_CHUNK)) { + total = JS_ROUNDUP(total, URI_CHUNK); + str->chars = JS_realloc(cx, str->chars, total * sizeof(jschar)); + if (!str->chars) + return JS_FALSE; + } + js_strncpy(str->chars + str->length, chars, length); + str->length += length; + str->chars[str->length] = 0; + return JS_TRUE; +} + +/* + * ECMA 3, 15.1.3 URI Handling Function Properties + * + * The following are implementations of the algorithms + * given in the ECMA specification for the hidden functions + * 'Encode' and 'Decode'. + */ +static JSBool +Encode(JSContext *cx, JSString *str, const jschar *unescapedSet, + const jschar *unescapedSet2, jsval *rval) +{ + size_t length, j, k, L; + jschar *chars, C, C2; + uint32 V; + uint8 utf8buf[6]; + jschar hexBuf[4]; + static const char HexDigits[] = "0123456789ABCDEF"; /* NB: uppercase */ + JSString *R; + + R = js_NewString(cx, NULL, 0, 0); + if (!R) + return JS_FALSE; + + hexBuf[0] = '%'; + hexBuf[3] = 0; + chars = JSSTRING_CHARS(str); + length = JSSTRING_LENGTH(str); + for (k = 0; k < length; k++) { + C = chars[k]; + if (js_strchr(unescapedSet, C) || + (unescapedSet2 && js_strchr(unescapedSet2, C))) { + if (!AddCharsToURI(cx, R, &C, 1)) + return JS_FALSE; + } else { + if ((C >= 0xDC00) && (C <= 0xDFFF)) { + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, + JSMSG_BAD_URI, NULL); + return JS_FALSE; + } + if (C < 0xD800 || C > 0xDBFF) { + V = C; + } else { + k++; + if (k == length) { + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, + JSMSG_BAD_URI, NULL); + return JS_FALSE; + } + C2 = chars[k]; + if ((C2 < 0xDC00) || (C2 > 0xDFFF)) { + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, + JSMSG_BAD_URI, NULL); + return JS_FALSE; + } + V = ((C - 0xD800) << 10) + (C2 - 0xDC00) + 0x10000; + } + L = OneUcs4ToUtf8Char(utf8buf, V); + for (j = 0; j < L; j++) { + hexBuf[1] = HexDigits[utf8buf[j] >> 4]; + hexBuf[2] = HexDigits[utf8buf[j] & 0xf]; + if (!AddCharsToURI(cx, R, hexBuf, 3)) + return JS_FALSE; + } + } + } + + /* + * Shrinking realloc can fail (e.g., with a BSD-style allocator), but we + * don't worry about that case here. Worst case, R hangs onto URI_CHUNK-1 + * more jschars than it needs. + */ + chars = (jschar *) JS_realloc(cx, R->chars, (R->length+1) * sizeof(jschar)); + if (chars) + R->chars = chars; + *rval = STRING_TO_JSVAL(R); + return JS_TRUE; +} + +static JSBool +Decode(JSContext *cx, JSString *str, const jschar *reservedSet, jsval *rval) +{ + size_t length, start, k; + jschar *chars, C, H; + uint32 V; + jsuint B; + uint8 octets[6]; + JSString *R; + intN j, n; + + R = js_NewString(cx, NULL, 0, 0); + if (!R) + return JS_FALSE; + + chars = JSSTRING_CHARS(str); + length = JSSTRING_LENGTH(str); + for (k = 0; k < length; k++) { + C = chars[k]; + if (C == '%') { + start = k; + if ((k + 2) >= length) + goto bad; + if (!JS7_ISHEX(chars[k+1]) || !JS7_ISHEX(chars[k+2])) + goto bad; + B = JS7_UNHEX(chars[k+1]) * 16 + JS7_UNHEX(chars[k+2]); + k += 2; + if (!(B & 0x80)) { + C = (jschar)B; + } else { + n = 1; + while (B & (0x80 >> n)) + n++; + if (n == 1 || n > 6) + goto bad; + octets[0] = (uint8)B; + if (k + 3 * (n - 1) >= length) + goto bad; + for (j = 1; j < n; j++) { + k++; + if (chars[k] != '%') + goto bad; + if (!JS7_ISHEX(chars[k+1]) || !JS7_ISHEX(chars[k+2])) + goto bad; + B = JS7_UNHEX(chars[k+1]) * 16 + JS7_UNHEX(chars[k+2]); + if ((B & 0xC0) != 0x80) + goto bad; + k += 2; + octets[j] = (char)B; + } + V = Utf8ToOneUcs4Char(octets, n); + if (V >= 0x10000) { + V -= 0x10000; + if (V > 0xFFFFF) + goto bad; + C = (jschar)((V & 0x3FF) + 0xDC00); + H = (jschar)((V >> 10) + 0xD800); + if (!AddCharsToURI(cx, R, &H, 1)) + return JS_FALSE; + } else { + C = (jschar)V; + } + } + if (js_strchr(reservedSet, C)) { + if (!AddCharsToURI(cx, R, &chars[start], (k - start + 1))) + return JS_FALSE; + } else { + if (!AddCharsToURI(cx, R, &C, 1)) + return JS_FALSE; + } + } else { + if (!AddCharsToURI(cx, R, &C, 1)) + return JS_FALSE; + } + } + + /* + * Shrinking realloc can fail (e.g., with a BSD-style allocator), but we + * don't worry about that case here. Worst case, R hangs onto URI_CHUNK-1 + * more jschars than it needs. + */ + chars = (jschar *) JS_realloc(cx, R->chars, (R->length+1) * sizeof(jschar)); + if (chars) + R->chars = chars; + *rval = STRING_TO_JSVAL(R); + return JS_TRUE; + +bad: + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BAD_URI); + return JS_FALSE; +} + +static JSBool +str_decodeURI(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval) +{ + JSString *str; + + str = js_ValueToString(cx, argv[0]); + if (!str) + return JS_FALSE; + return Decode(cx, str, js_uriReservedPlusPound_ucstr, rval); +} + +static JSBool +str_decodeURI_Component(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval) +{ + JSString *str; + + str = js_ValueToString(cx, argv[0]); + if (!str) + return JS_FALSE; + return Decode(cx, str, js_empty_ucstr, rval); +} + +static JSBool +str_encodeURI(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval) +{ + JSString *str; + + str = js_ValueToString(cx, argv[0]); + if (!str) + return JS_FALSE; + return Encode(cx, str, js_uriReservedPlusPound_ucstr, js_uriUnescaped_ucstr, + rval); +} + +static JSBool +str_encodeURI_Component(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval) +{ + JSString *str; + + str = js_ValueToString(cx, argv[0]); + if (!str) + return JS_FALSE; + return Encode(cx, str, js_uriUnescaped_ucstr, NULL, rval); +} + +/* + * Convert one UCS-4 char and write it into a UTF-8 buffer, which must be at + * least 6 bytes long. Return the number of UTF-8 bytes of data written. + */ +static int +OneUcs4ToUtf8Char(uint8 *utf8Buffer, uint32 ucs4Char) +{ + int utf8Length = 1; + + JS_ASSERT(ucs4Char <= 0x7FFFFFFF); + if (ucs4Char < 0x80) { + *utf8Buffer = (uint8)ucs4Char; + } else { + int i; + uint32 a = ucs4Char >> 11; + utf8Length = 2; + while (a) { + a >>= 5; + utf8Length++; + } + i = utf8Length; + while (--i) { + utf8Buffer[i] = (uint8)((ucs4Char & 0x3F) | 0x80); + ucs4Char >>= 6; + } + *utf8Buffer = (uint8)(0x100 - (1 << (8-utf8Length)) + ucs4Char); + } + return utf8Length; +} + +/* + * Convert a utf8 character sequence into a UCS-4 character and return that + * character. It is assumed that the caller already checked that the sequence + * is valid. + */ +static uint32 +Utf8ToOneUcs4Char(const uint8 *utf8Buffer, int utf8Length) +{ + uint32 ucs4Char; + uint32 minucs4Char; + /* from Unicode 3.1, non-shortest form is illegal */ + static const uint32 minucs4Table[] = { + 0x00000080, 0x00000800, 0x0001000, 0x0020000, 0x0400000 + }; + + JS_ASSERT(utf8Length >= 1 && utf8Length <= 6); + if (utf8Length == 1) { + ucs4Char = *utf8Buffer; + JS_ASSERT(!(ucs4Char & 0x80)); + } else { + JS_ASSERT((*utf8Buffer & (0x100 - (1 << (7-utf8Length)))) == + (0x100 - (1 << (8-utf8Length)))); + ucs4Char = *utf8Buffer++ & ((1<<(7-utf8Length))-1); + minucs4Char = minucs4Table[utf8Length-2]; + while (--utf8Length) { + JS_ASSERT((*utf8Buffer & 0xC0) == 0x80); + ucs4Char = ucs4Char<<6 | (*utf8Buffer++ & 0x3F); + } + if (ucs4Char < minucs4Char || + ucs4Char == 0xFFFE || ucs4Char == 0xFFFF) { + ucs4Char = 0xFFFD; + } + } + return ucs4Char; +} diff --git a/src/dom/js/jsstr.h b/src/dom/js/jsstr.h new file mode 100644 index 000000000..94ebe97b9 --- /dev/null +++ b/src/dom/js/jsstr.h @@ -0,0 +1,439 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef jsstr_h___ +#define jsstr_h___ +/* + * JS string type implementation. + * + * A JS string is a counted array of unicode characters. To support handoff + * of API client memory, the chars are allocated separately from the length, + * necessitating a pointer after the count, to form a separately allocated + * string descriptor. String descriptors are GC'ed, while their chars are + * allocated from the malloc heap. + * + * When a string is treated as an object (by following it with . or []), the + * runtime wraps it with a JSObject whose valueOf method returns the unwrapped + * string descriptor. + */ +#include +#include "jspubtd.h" +#include "jsprvtd.h" +#include "jshash.h" + +JS_BEGIN_EXTERN_C + +/* + * The original GC-thing "string" type, a flat character string owned by its + * GC-thing descriptor. The chars member points to a vector having byte size + * (length + 1) * sizeof(jschar), terminated at index length by a zero jschar. + * The terminator is purely a backstop, in case the chars pointer flows out to + * native code that requires \u0000 termination. + * + * NB: Always use the JSSTRING_LENGTH and JSSTRING_CHARS accessor macros, + * unless you guard str->member uses with !JSSTRING_IS_DEPENDENT(str). + */ +struct JSString { + size_t length; + jschar *chars; +}; + +/* + * Overlay structure for a string that depends on another string's characters. + * Distinguished by the JSSTRFLAG_DEPENDENT bit being set in length. The base + * member may point to another dependent string if JSSTRING_CHARS has not been + * called yet. The length chars in a dependent string are stored starting at + * base->chars + start, and are not necessarily zero-terminated. If start is + * 0, it is not stored, length is a full size_t (minus the JSSTRFLAG_* bits in + * the high two positions), and the JSSTRFLAG_PREFIX flag is set. + */ +struct JSDependentString { + size_t length; + JSString *base; +}; + +/* Definitions for flags stored in the high order bits of JSString.length. */ +#define JSSTRFLAG_BITS 2 +#define JSSTRFLAG_SHIFT(flg) ((size_t)(flg) << JSSTRING_LENGTH_BITS) +#define JSSTRFLAG_MASK JSSTRFLAG_SHIFT(JS_BITMASK(JSSTRFLAG_BITS)) +#define JSSTRFLAG_DEPENDENT JSSTRFLAG_SHIFT(1) +#define JSSTRFLAG_PREFIX JSSTRFLAG_SHIFT(2) + +/* Universal JSString type inquiry and accessor macros. */ +#define JSSTRING_BIT(n) ((size_t)1 << (n)) +#define JSSTRING_BITMASK(n) (JSSTRING_BIT(n) - 1) +#define JSSTRING_HAS_FLAG(str,flg) ((str)->length & (flg)) +#define JSSTRING_IS_DEPENDENT(str) JSSTRING_HAS_FLAG(str, JSSTRFLAG_DEPENDENT) +#define JSSTRING_IS_PREFIX(str) JSSTRING_HAS_FLAG(str, JSSTRFLAG_PREFIX) +#define JSSTRING_CHARS(str) (JSSTRING_IS_DEPENDENT(str) \ + ? JSSTRDEP_CHARS(str) \ + : (str)->chars) +#define JSSTRING_LENGTH(str) (JSSTRING_IS_DEPENDENT(str) \ + ? JSSTRDEP_LENGTH(str) \ + : (str)->length) +#define JSSTRING_LENGTH_BITS (sizeof(size_t) * JS_BITS_PER_BYTE \ + - JSSTRFLAG_BITS) +#define JSSTRING_LENGTH_MASK JSSTRING_BITMASK(JSSTRING_LENGTH_BITS) + +/* Specific JSDependentString shift/mask accessor and mutator macros. */ +#define JSSTRDEP_START_BITS (JSSTRING_LENGTH_BITS-JSSTRDEP_LENGTH_BITS) +#define JSSTRDEP_START_SHIFT JSSTRDEP_LENGTH_BITS +#define JSSTRDEP_START_MASK JSSTRING_BITMASK(JSSTRDEP_START_BITS) +#define JSSTRDEP_LENGTH_BITS (JSSTRING_LENGTH_BITS / 2) +#define JSSTRDEP_LENGTH_MASK JSSTRING_BITMASK(JSSTRDEP_LENGTH_BITS) + +#define JSSTRDEP(str) ((JSDependentString *)(str)) +#define JSSTRDEP_START(str) (JSSTRING_IS_PREFIX(str) ? 0 \ + : ((JSSTRDEP(str)->length \ + >> JSSTRDEP_START_SHIFT) \ + & JSSTRDEP_START_MASK)) +#define JSSTRDEP_LENGTH(str) (JSSTRDEP(str)->length \ + & (JSSTRING_IS_PREFIX(str) \ + ? JSSTRING_LENGTH_MASK \ + : JSSTRDEP_LENGTH_MASK)) + +#define JSSTRDEP_SET_START_AND_LENGTH(str,off,len) \ + (JSSTRDEP(str)->length = JSSTRFLAG_DEPENDENT \ + | ((off) << JSSTRDEP_START_SHIFT) \ + | (len)) +#define JSPREFIX_SET_LENGTH(str,len) \ + (JSSTRDEP(str)->length = JSSTRFLAG_DEPENDENT | JSSTRFLAG_PREFIX | (len)) + +#define JSSTRDEP_BASE(str) (JSSTRDEP(str)->base) +#define JSSTRDEP_SET_BASE(str,bstr) (JSSTRDEP(str)->base = (bstr)) +#define JSPREFIX_BASE(str) JSSTRDEP_BASE(str) +#define JSPREFIX_SET_BASE(str,bstr) JSSTRDEP_SET_BASE(str,bstr) + +#define JSSTRDEP_CHARS(str) \ + (JSSTRING_IS_DEPENDENT(JSSTRDEP_BASE(str)) \ + ? js_GetDependentStringChars(str) \ + : JSSTRDEP_BASE(str)->chars + JSSTRDEP_START(str)) + +extern size_t +js_MinimizeDependentStrings(JSString *str, int level, JSString **basep); + +extern jschar * +js_GetDependentStringChars(JSString *str); + +extern jschar * +js_GetStringChars(JSString *str); + +extern JSString * +js_ConcatStrings(JSContext *cx, JSString *left, JSString *right); + +extern const jschar * +js_UndependString(JSContext *cx, JSString *str); + +struct JSSubString { + size_t length; + const jschar *chars; +}; + +extern jschar js_empty_ucstr[]; +extern JSSubString js_EmptySubString; + +/* Unicode character attribute lookup tables. */ +extern const uint8 js_X[]; +extern const uint8 js_Y[]; +extern const uint32 js_A[]; + +/* Enumerated Unicode general category types. */ +typedef enum JSCharType { + JSCT_UNASSIGNED = 0, + JSCT_UPPERCASE_LETTER = 1, + JSCT_LOWERCASE_LETTER = 2, + JSCT_TITLECASE_LETTER = 3, + JSCT_MODIFIER_LETTER = 4, + JSCT_OTHER_LETTER = 5, + JSCT_NON_SPACING_MARK = 6, + JSCT_ENCLOSING_MARK = 7, + JSCT_COMBINING_SPACING_MARK = 8, + JSCT_DECIMAL_DIGIT_NUMBER = 9, + JSCT_LETTER_NUMBER = 10, + JSCT_OTHER_NUMBER = 11, + JSCT_SPACE_SEPARATOR = 12, + JSCT_LINE_SEPARATOR = 13, + JSCT_PARAGRAPH_SEPARATOR = 14, + JSCT_CONTROL = 15, + JSCT_FORMAT = 16, + JSCT_PRIVATE_USE = 18, + JSCT_SURROGATE = 19, + JSCT_DASH_PUNCTUATION = 20, + JSCT_START_PUNCTUATION = 21, + JSCT_END_PUNCTUATION = 22, + JSCT_CONNECTOR_PUNCTUATION = 23, + JSCT_OTHER_PUNCTUATION = 24, + JSCT_MATH_SYMBOL = 25, + JSCT_CURRENCY_SYMBOL = 26, + JSCT_MODIFIER_SYMBOL = 27, + JSCT_OTHER_SYMBOL = 28 +} JSCharType; + +/* Character classifying and mapping macros, based on java.lang.Character. */ +#define JS_CCODE(c) (js_A[js_Y[(js_X[(uint16)(c)>>6]<<6)|((c)&0x3F)]]) +#define JS_CTYPE(c) (JS_CCODE(c) & 0x1F) + +#define JS_ISALPHA(c) ((((1 << JSCT_UPPERCASE_LETTER) | \ + (1 << JSCT_LOWERCASE_LETTER) | \ + (1 << JSCT_TITLECASE_LETTER) | \ + (1 << JSCT_MODIFIER_LETTER) | \ + (1 << JSCT_OTHER_LETTER)) \ + >> JS_CTYPE(c)) & 1) + +#define JS_ISALNUM(c) ((((1 << JSCT_UPPERCASE_LETTER) | \ + (1 << JSCT_LOWERCASE_LETTER) | \ + (1 << JSCT_TITLECASE_LETTER) | \ + (1 << JSCT_MODIFIER_LETTER) | \ + (1 << JSCT_OTHER_LETTER) | \ + (1 << JSCT_DECIMAL_DIGIT_NUMBER)) \ + >> JS_CTYPE(c)) & 1) + +/* A unicode letter, suitable for use in an identifier. */ +#define JS_ISUC_LETTER(c) ((((1 << JSCT_UPPERCASE_LETTER) | \ + (1 << JSCT_LOWERCASE_LETTER) | \ + (1 << JSCT_TITLECASE_LETTER) | \ + (1 << JSCT_MODIFIER_LETTER) | \ + (1 << JSCT_OTHER_LETTER) | \ + (1 << JSCT_LETTER_NUMBER)) \ + >> JS_CTYPE(c)) & 1) + +/* +* 'IdentifierPart' from ECMA grammar, is Unicode letter or +* combining mark or digit or connector punctuation. +*/ +#define JS_ISID_PART(c) ((((1 << JSCT_UPPERCASE_LETTER) | \ + (1 << JSCT_LOWERCASE_LETTER) | \ + (1 << JSCT_TITLECASE_LETTER) | \ + (1 << JSCT_MODIFIER_LETTER) | \ + (1 << JSCT_OTHER_LETTER) | \ + (1 << JSCT_LETTER_NUMBER) | \ + (1 << JSCT_NON_SPACING_MARK) | \ + (1 << JSCT_COMBINING_SPACING_MARK) | \ + (1 << JSCT_DECIMAL_DIGIT_NUMBER) | \ + (1 << JSCT_CONNECTOR_PUNCTUATION)) \ + >> JS_CTYPE(c)) & 1) + +/* Unicode control-format characters, ignored in input */ +#define JS_ISFORMAT(c) (((1 << JSCT_FORMAT) >> JS_CTYPE(c)) & 1) + +#define JS_ISWORD(c) (JS_ISALNUM(c) || (c) == '_') + +/* XXXbe unify on A/X/Y tbls, avoid ctype.h? */ +#define JS_ISIDENT_START(c) (JS_ISUC_LETTER(c) || (c) == '_' || (c) == '$') +#define JS_ISIDENT(c) (JS_ISID_PART(c) || (c) == '_' || (c) == '$') + +#define JS_ISDIGIT(c) (JS_CTYPE(c) == JSCT_DECIMAL_DIGIT_NUMBER) + +/* XXXbe fs, etc. ? */ +#define JS_ISSPACE(c) ((JS_CCODE(c) & 0x00070000) == 0x00040000) +#define JS_ISPRINT(c) ((c) < 128 && isprint(c)) + +#define JS_ISUPPER(c) (JS_CTYPE(c) == JSCT_UPPERCASE_LETTER) +#define JS_ISLOWER(c) (JS_CTYPE(c) == JSCT_LOWERCASE_LETTER) + +#define JS_TOUPPER(c) ((JS_CCODE(c) & 0x00100000) ? (c) - ((int32)JS_CCODE(c) >> 22) : (c)) +#define JS_TOLOWER(c) ((JS_CCODE(c) & 0x00200000) ? (c) + ((int32)JS_CCODE(c) >> 22) : (c)) + +#define JS_TOCTRL(c) ((c) ^ 64) /* XXX unsafe! requires uppercase c */ + +/* Shorthands for ASCII (7-bit) decimal and hex conversion. */ +#define JS7_ISDEC(c) ((c) < 128 && isdigit(c)) +#define JS7_UNDEC(c) ((c) - '0') +#define JS7_ISHEX(c) ((c) < 128 && isxdigit(c)) +#define JS7_UNHEX(c) (uintN)(isdigit(c) ? (c) - '0' : 10 + tolower(c) - 'a') +#define JS7_ISLET(c) ((c) < 128 && isalpha(c)) + +/* Initialize truly global state associated with JS strings. */ +extern JSBool +js_InitStringGlobals(void); + +extern void +js_FreeStringGlobals(void); + +extern void +js_PurgeDeflatedStringCache(JSString *str); + +/* Initialize per-runtime string state for the first context in the runtime. */ +extern JSBool +js_InitRuntimeStringState(JSContext *cx); + +extern void +js_FinishRuntimeStringState(JSContext *cx); + +/* Initialize the String class, returning its prototype object. */ +extern JSObject * +js_InitStringClass(JSContext *cx, JSObject *obj); + +extern const char js_escape_str[]; +extern const char js_unescape_str[]; +extern const char js_uneval_str[]; +extern const char js_decodeURI_str[]; +extern const char js_encodeURI_str[]; +extern const char js_decodeURIComponent_str[]; +extern const char js_encodeURIComponent_str[]; + +/* GC-allocate a string descriptor for the given malloc-allocated chars. */ +extern JSString * +js_NewString(JSContext *cx, jschar *chars, size_t length, uintN gcflag); + +extern JSString * +js_NewDependentString(JSContext *cx, JSString *base, size_t start, + size_t length, uintN gcflag); + +/* Copy a counted string and GC-allocate a descriptor for it. */ +extern JSString * +js_NewStringCopyN(JSContext *cx, const jschar *s, size_t n, uintN gcflag); + +/* Copy a C string and GC-allocate a descriptor for it. */ +extern JSString * +js_NewStringCopyZ(JSContext *cx, const jschar *s, uintN gcflag); + +/* Free the chars held by str when it is finalized by the GC. */ +extern void +js_FinalizeString(JSContext *cx, JSString *str); + +extern void +js_FinalizeStringRT(JSRuntime *rt, JSString *str); + +/* Wrap a string value in a String object. */ +extern JSObject * +js_StringToObject(JSContext *cx, JSString *str); + +/* + * Convert a value to a string, returning null after reporting an error, + * otherwise returning a new string reference. + */ +extern JSString * +js_ValueToString(JSContext *cx, jsval v); + +/* + * Convert a value to its source expression, returning null after reporting + * an error, otherwise returning a new string reference. + */ +extern JSString * +js_ValueToSource(JSContext *cx, jsval v); + +#ifdef HT_ENUMERATE_NEXT /* XXX don't require jshash.h */ +/* + * Compute a hash function from str. + */ +extern JSHashNumber +js_HashString(JSString *str); +#endif + +/* + * Return less than, equal to, or greater than zero depending on whether + * str1 is less than, equal to, or greater than str2. + */ +extern intN +js_CompareStrings(JSString *str1, JSString *str2); + +/* + * Boyer-Moore-Horspool superlinear search for pat:patlen in text:textlen. + * The patlen argument must be positive and no greater than BMH_PATLEN_MAX. + * The start argument tells where in text to begin the search. + * + * Return the index of pat in text, or -1 if not found. + */ +#define BMH_CHARSET_SIZE 256 /* ISO-Latin-1 */ +#define BMH_PATLEN_MAX 255 /* skip table element is uint8 */ + +#define BMH_BAD_PATTERN (-2) /* return value if pat is not ISO-Latin-1 */ + +extern jsint +js_BoyerMooreHorspool(const jschar *text, jsint textlen, + const jschar *pat, jsint patlen, + jsint start); + +extern size_t +js_strlen(const jschar *s); + +extern jschar * +js_strchr(const jschar *s, jschar c); + +extern jschar * +js_strchr_limit(const jschar *s, jschar c, const jschar *limit); + +#define js_strncpy(t, s, n) memcpy((t), (s), (n) * sizeof(jschar)) + +/* + * Return s advanced past any Unicode white space characters. + */ +extern const jschar * +js_SkipWhiteSpace(const jschar *s); + +/* + * Inflate bytes to JS chars and vice versa. Report out of memory via cx + * and return null on error, otherwise return the jschar or byte vector that + * was JS_malloc'ed. + */ +extern jschar * +js_InflateString(JSContext *cx, const char *bytes, size_t length); + +extern char * +js_DeflateString(JSContext *cx, const jschar *chars, size_t length); + +/* + * Inflate bytes to JS chars into a buffer. + * 'chars' must be large enough for 'length'+1 jschars. + */ +extern void +js_InflateStringToBuffer(jschar *chars, const char *bytes, size_t length); + +/* + * Associate bytes with str in the deflated string cache, returning true on + * successful association, false on out of memory. + */ +extern JSBool +js_SetStringBytes(JSString *str, char *bytes, size_t length); + +/* + * Find or create a deflated string cache entry for str that contains its + * characters chopped from Unicode code points into bytes. + */ +extern char * +js_GetStringBytes(JSString *str); + +JSBool +js_str_escape(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval); + +JS_END_EXTERN_C + +#endif /* jsstr_h___ */ diff --git a/src/dom/js/jstypes.h b/src/dom/js/jstypes.h new file mode 100644 index 000000000..1709c6461 --- /dev/null +++ b/src/dom/js/jstypes.h @@ -0,0 +1,388 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * IBM Corp. + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* +** File: jstypes.h +** Description: Definitions of NSPR's basic types +** +** Prototypes and macros used to make up for deficiencies in ANSI environments +** that we have found. +** +** Since we do not wrap and all the other standard headers, authors +** of portable code will not know in general that they need these definitions. +** Instead of requiring these authors to find the dependent uses in their code +** and take the following steps only in those C files, we take steps once here +** for all C files. +**/ + +#ifndef jstypes_h___ +#define jstypes_h___ + +#include + +/*********************************************************************** +** MACROS: JS_EXTERN_API +** JS_EXPORT_API +** DESCRIPTION: +** These are only for externally visible routines and globals. For +** internal routines, just use "extern" for type checking and that +** will not export internal cross-file or forward-declared symbols. +** Define a macro for declaring procedures return types. We use this to +** deal with windoze specific type hackery for DLL definitions. Use +** JS_EXTERN_API when the prototype for the method is declared. Use +** JS_EXPORT_API for the implementation of the method. +** +** Example: +** in dowhim.h +** JS_EXTERN_API( void ) DoWhatIMean( void ); +** in dowhim.c +** JS_EXPORT_API( void ) DoWhatIMean( void ) { return; } +** +** +***********************************************************************/ +#ifdef WIN32 +/* These also work for __MWERKS__ */ +#define JS_EXTERN_API(__type) extern __declspec(dllexport) __type +#define JS_EXPORT_API(__type) __declspec(dllexport) __type +#define JS_EXTERN_DATA(__type) extern __declspec(dllexport) __type +#define JS_EXPORT_DATA(__type) __declspec(dllexport) __type + +#define JS_DLL_CALLBACK +#define JS_STATIC_DLL_CALLBACK(__x) static __x + +#elif defined(WIN16) + +#ifdef _WINDLL +#define JS_EXTERN_API(__type) extern __type _cdecl _export _loadds +#define JS_EXPORT_API(__type) __type _cdecl _export _loadds +#define JS_EXTERN_DATA(__type) extern __type _export +#define JS_EXPORT_DATA(__type) __type _export + +#define JS_DLL_CALLBACK __cdecl __loadds +#define JS_STATIC_DLL_CALLBACK(__x) static __x CALLBACK + +#else /* this must be .EXE */ +#define JS_EXTERN_API(__type) extern __type _cdecl _export +#define JS_EXPORT_API(__type) __type _cdecl _export +#define JS_EXTERN_DATA(__type) extern __type _export +#define JS_EXPORT_DATA(__type) __type _export + +#define JS_DLL_CALLBACK __cdecl __loadds +#define JS_STATIC_DLL_CALLBACK(__x) __x JS_DLL_CALLBACK +#endif /* _WINDLL */ + +#elif defined(XP_MAC) +#define JS_EXTERN_API(__type) extern __declspec(export) __type +#define JS_EXPORT_API(__type) __declspec(export) __type +#define JS_EXTERN_DATA(__type) extern __declspec(export) __type +#define JS_EXPORT_DATA(__type) __declspec(export) __type + +#define JS_DLL_CALLBACK +#define JS_STATIC_DLL_CALLBACK(__x) static __x + +#else /* Unix */ + +#define JS_EXTERN_API(__type) extern __type +#define JS_EXPORT_API(__type) __type +#define JS_EXTERN_DATA(__type) extern __type +#define JS_EXPORT_DATA(__type) __type + +#define JS_DLL_CALLBACK +#define JS_STATIC_DLL_CALLBACK(__x) static __x + +#endif + +#ifdef _WIN32 +# if defined(__MWERKS__) || defined(__GNUC__) +# define JS_IMPORT_API(__x) __x +# else +# define JS_IMPORT_API(__x) __declspec(dllimport) __x +# endif +#else +# define JS_IMPORT_API(__x) JS_EXPORT_API (__x) +#endif + +#if defined(_WIN32) && !defined(__MWERKS__) &&!defined(__GNUC__) +# define JS_IMPORT_DATA(__x) __declspec(dllimport) __x +#else +# define JS_IMPORT_DATA(__x) __x +#endif + +/* + * The linkage of JS API functions differs depending on whether the file is + * used within the JS library or not. Any source file within the JS + * interpreter should define EXPORT_JS_API whereas any client of the library + * should not. + */ +#ifdef EXPORT_JS_API +#define JS_PUBLIC_API(t) JS_EXPORT_API(t) +#define JS_PUBLIC_DATA(t) JS_EXPORT_DATA(t) +#else +#define JS_PUBLIC_API(t) JS_IMPORT_API(t) +#define JS_PUBLIC_DATA(t) JS_IMPORT_DATA(t) +#endif + +#define JS_FRIEND_API(t) JS_PUBLIC_API(t) +#define JS_FRIEND_DATA(t) JS_PUBLIC_DATA(t) + +#ifdef _WIN32 +# define JS_INLINE __inline +#elif defined(__GNUC__) +# define JS_INLINE +#else +# define JS_INLINE +#endif + +/*********************************************************************** +** MACROS: JS_BEGIN_MACRO +** JS_END_MACRO +** DESCRIPTION: +** Macro body brackets so that macros with compound statement definitions +** behave syntactically more like functions when called. +***********************************************************************/ +#define JS_BEGIN_MACRO do { +#define JS_END_MACRO } while (0) + +/*********************************************************************** +** MACROS: JS_BEGIN_EXTERN_C +** JS_END_EXTERN_C +** DESCRIPTION: +** Macro shorthands for conditional C++ extern block delimiters. +***********************************************************************/ +#ifdef __cplusplus +#define JS_BEGIN_EXTERN_C extern "C" { +#define JS_END_EXTERN_C } +#else +#define JS_BEGIN_EXTERN_C +#define JS_END_EXTERN_C +#endif + +/*********************************************************************** +** MACROS: JS_BIT +** JS_BITMASK +** DESCRIPTION: +** Bit masking macros. XXX n must be <= 31 to be portable +***********************************************************************/ +#define JS_BIT(n) ((JSUint32)1 << (n)) +#define JS_BITMASK(n) (JS_BIT(n) - 1) + +/*********************************************************************** +** MACROS: JS_HOWMANY +** JS_ROUNDUP +** JS_MIN +** JS_MAX +** DESCRIPTION: +** Commonly used macros for operations on compatible types. +***********************************************************************/ +#define JS_HOWMANY(x,y) (((x)+(y)-1)/(y)) +#define JS_ROUNDUP(x,y) (JS_HOWMANY(x,y)*(y)) +#define JS_MIN(x,y) ((x)<(y)?(x):(y)) +#define JS_MAX(x,y) ((x)>(y)?(x):(y)) + +#if (defined(XP_MAC) || defined(XP_WIN)) && !defined(CROSS_COMPILE) +# include "jscpucfg.h" /* Use standard Mac or Windows configuration */ +#elif defined(XP_UNIX) || defined(XP_BEOS) || defined(XP_OS2) || defined(CROSS_COMPILE) +# include "jsautocfg.h" /* Use auto-detected configuration */ +# include "jsosdep.h" /* ...and platform-specific flags */ +#else +# error "Must define one of XP_BEOS, XP_MAC, XP_OS2, XP_WIN or XP_UNIX" +#endif + +JS_BEGIN_EXTERN_C + +/************************************************************************ +** TYPES: JSUint8 +** JSInt8 +** DESCRIPTION: +** The int8 types are known to be 8 bits each. There is no type that +** is equivalent to a plain "char". +************************************************************************/ +#if JS_BYTES_PER_BYTE == 1 +typedef unsigned char JSUint8; +typedef signed char JSInt8; +#else +#error No suitable type for JSInt8/JSUint8 +#endif + +/************************************************************************ +** TYPES: JSUint16 +** JSInt16 +** DESCRIPTION: +** The int16 types are known to be 16 bits each. +************************************************************************/ +#if JS_BYTES_PER_SHORT == 2 +typedef unsigned short JSUint16; +typedef short JSInt16; +#else +#error No suitable type for JSInt16/JSUint16 +#endif + +/************************************************************************ +** TYPES: JSUint32 +** JSInt32 +** DESCRIPTION: +** The int32 types are known to be 32 bits each. +************************************************************************/ +#if JS_BYTES_PER_INT == 4 +typedef unsigned int JSUint32; +typedef int JSInt32; +#define JS_INT32(x) x +#define JS_UINT32(x) x ## U +#elif JS_BYTES_PER_LONG == 4 +typedef unsigned long JSUint32; +typedef long JSInt32; +#define JS_INT32(x) x ## L +#define JS_UINT32(x) x ## UL +#else +#error No suitable type for JSInt32/JSUint32 +#endif + +/************************************************************************ +** TYPES: JSUint64 +** JSInt64 +** DESCRIPTION: +** The int64 types are known to be 64 bits each. Care must be used when +** declaring variables of type JSUint64 or JSInt64. Different hardware +** architectures and even different compilers have varying support for +** 64 bit values. The only guaranteed portability requires the use of +** the JSLL_ macros (see jslong.h). +************************************************************************/ +#ifdef JS_HAVE_LONG_LONG +#if JS_BYTES_PER_LONG == 8 +typedef long JSInt64; +typedef unsigned long JSUint64; +#elif defined(WIN16) +typedef __int64 JSInt64; +typedef unsigned __int64 JSUint64; +#elif defined(WIN32) && !defined(__GNUC__) +typedef __int64 JSInt64; +typedef unsigned __int64 JSUint64; +#else +typedef long long JSInt64; +typedef unsigned long long JSUint64; +#endif /* JS_BYTES_PER_LONG == 8 */ +#else /* !JS_HAVE_LONG_LONG */ +typedef struct { +#ifdef IS_LITTLE_ENDIAN + JSUint32 lo, hi; +#else + JSUint32 hi, lo; +#endif +} JSInt64; +typedef JSInt64 JSUint64; +#endif /* !JS_HAVE_LONG_LONG */ + +/************************************************************************ +** TYPES: JSUintn +** JSIntn +** DESCRIPTION: +** The JSIntn types are most appropriate for automatic variables. They are +** guaranteed to be at least 16 bits, though various architectures may +** define them to be wider (e.g., 32 or even 64 bits). These types are +** never valid for fields of a structure. +************************************************************************/ +#if JS_BYTES_PER_INT >= 2 +typedef int JSIntn; +typedef unsigned int JSUintn; +#else +#error 'sizeof(int)' not sufficient for platform use +#endif + +/************************************************************************ +** TYPES: JSFloat64 +** DESCRIPTION: +** NSPR's floating point type is always 64 bits. +************************************************************************/ +typedef double JSFloat64; + +/************************************************************************ +** TYPES: JSSize +** DESCRIPTION: +** A type for representing the size of objects. +************************************************************************/ +typedef size_t JSSize; + +/************************************************************************ +** TYPES: JSPtrDiff +** DESCRIPTION: +** A type for pointer difference. Variables of this type are suitable +** for storing a pointer or pointer sutraction. +************************************************************************/ +typedef ptrdiff_t JSPtrdiff; + +/************************************************************************ +** TYPES: JSUptrdiff +** DESCRIPTION: +** A type for pointer difference. Variables of this type are suitable +** for storing a pointer or pointer sutraction. +************************************************************************/ +typedef unsigned long JSUptrdiff; + +/************************************************************************ +** TYPES: JSBool +** DESCRIPTION: +** Use JSBool for variables and parameter types. Use JS_FALSE and JS_TRUE +** for clarity of target type in assignments and actual arguments. Use +** 'if (bool)', 'while (!bool)', '(bool) ? x : y' etc., to test booleans +** just as you would C int-valued conditions. +************************************************************************/ +typedef JSIntn JSBool; +#define JS_TRUE (JSIntn)1 +#define JS_FALSE (JSIntn)0 + +/************************************************************************ +** TYPES: JSPackedBool +** DESCRIPTION: +** Use JSPackedBool within structs where bitfields are not desireable +** but minimum and consistant overhead matters. +************************************************************************/ +typedef JSUint8 JSPackedBool; + +/* +** A JSWord is an integer that is the same size as a void* +*/ +typedef long JSWord; +typedef unsigned long JSUword; + +#include "jsotypes.h" + +JS_END_EXTERN_C + +#endif /* jstypes_h___ */ + diff --git a/src/dom/js/jsutil.c b/src/dom/js/jsutil.c new file mode 100644 index 000000000..f64718ad4 --- /dev/null +++ b/src/dom/js/jsutil.c @@ -0,0 +1,157 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * IBM Corp. + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* + * PR assertion checker. + */ +#include "jsstddef.h" +#include +#include +#include "jstypes.h" +#include "jsutil.h" + +#ifdef WIN32 +# include +#endif + +#ifdef XP_MAC +# include +# include +# include "jsprf.h" +#endif + +#ifdef XP_MAC +/* + * PStrFromCStr converts the source C string to a destination + * pascal string as it copies. The dest string will + * be truncated to fit into an Str255 if necessary. + * If the C String pointer is NULL, the pascal string's length is + * set to zero. + */ +static void PStrFromCStr(const char* src, Str255 dst) +{ + short length = 0; + + /* handle case of overlapping strings */ + if ( (void*)src == (void*)dst ) + { + unsigned char* curdst = &dst[1]; + unsigned char thisChar; + + thisChar = *(const unsigned char*)src++; + while ( thisChar != '\0' ) + { + unsigned char nextChar; + + /* + * Use nextChar so we don't overwrite what we + * are about to read + */ + nextChar = *(const unsigned char*)src++; + *curdst++ = thisChar; + thisChar = nextChar; + + if ( ++length >= 255 ) + break; + } + } + else if ( src != NULL ) + { + unsigned char* curdst = &dst[1]; + /* count down so test it loop is faster */ + short overflow = 255; + register char temp; + + /* + * Can't do the K&R C thing of while (*s++ = *t++) + * because it will copy trailing zero which might + * overrun pascal buffer. Instead we use a temp variable. + */ + while ( (temp = *src++) != 0 ) + { + *(char*)curdst++ = temp; + + if ( --overflow <= 0 ) + break; + } + length = 255 - overflow; + } + dst[0] = length; +} + +static void jsdebugstr(const char *debuggerMsg) +{ + Str255 pStr; + + PStrFromCStr(debuggerMsg, pStr); + DebugStr(pStr); +} + +static void dprintf(const char *format, ...) +{ + va_list ap; + char *buffer; + + va_start(ap, format); + buffer = (char *)JS_vsmprintf(format, ap); + va_end(ap); + + jsdebugstr(buffer); + JS_DELETE(buffer); +} +#endif /* XP_MAC */ + +JS_PUBLIC_API(void) JS_Assert(const char *s, const char *file, JSIntn ln) +{ +#ifdef XP_MAC + dprintf("Assertion failure: %s, at %s:%d\n", s, file, ln); +#else + fprintf(stderr, "Assertion failure: %s, at %s:%d\n", s, file, ln); +#endif +#if defined(WIN32) + DebugBreak(); +#endif +#if defined(XP_OS2) + asm("int $3"); +#endif +#ifndef XP_MAC + abort(); +#endif +} diff --git a/src/dom/js/jsutil.h b/src/dom/js/jsutil.h new file mode 100644 index 000000000..d4edb919c --- /dev/null +++ b/src/dom/js/jsutil.h @@ -0,0 +1,106 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* + * PR assertion checker. + */ + +#ifndef jsutil_h___ +#define jsutil_h___ + +JS_BEGIN_EXTERN_C + +/*********************************************************************** +** FUNCTION: JS_MALLOC() +** DESCRIPTION: +** JS_NEW() allocates an untyped item of size _size from the heap. +** INPUTS: _size: size in bytes of item to be allocated +** OUTPUTS: untyped pointer to the node allocated +** RETURN: pointer to node or error returned from malloc(). +***********************************************************************/ +#define JS_MALLOC(_bytes) (malloc((_bytes))) + +/*********************************************************************** +** FUNCTION: JS_DELETE() +** DESCRIPTION: +** JS_DELETE() unallocates an object previosly allocated via JS_NEW() +** or JS_NEWZAP() to the heap. +** INPUTS: pointer to previously allocated object +** OUTPUTS: the referenced object is returned to the heap +** RETURN: void +***********************************************************************/ +#define JS_DELETE(_ptr) { free(_ptr); (_ptr) = NULL; } + +/*********************************************************************** +** FUNCTION: JS_NEW() +** DESCRIPTION: +** JS_NEW() allocates an item of type _struct from the heap. +** INPUTS: _struct: a data type +** OUTPUTS: pointer to _struct +** RETURN: pointer to _struct or error returns from malloc(). +***********************************************************************/ +#define JS_NEW(_struct) ((_struct *) JS_MALLOC(sizeof(_struct))) + +#ifdef DEBUG + +extern JS_PUBLIC_API(void) +JS_Assert(const char *s, const char *file, JSIntn ln); +#define JS_ASSERT(_expr) \ + ((_expr)?((void)0):JS_Assert(# _expr,__FILE__,__LINE__)) + +#define JS_NOT_REACHED(_reasonStr) \ + JS_Assert(_reasonStr,__FILE__,__LINE__) + +#else + +#define JS_ASSERT(expr) ((void) 0) +#define JS_NOT_REACHED(reasonStr) + +#endif /* defined(DEBUG) */ + +/* +** Abort the process in a non-graceful manner. This will cause a core file, +** call to the debugger or other moral equivalent as well as causing the +** entire process to stop. +*/ +extern JS_PUBLIC_API(void) JS_Abort(void); + +JS_END_EXTERN_C + +#endif /* jsutil_h___ */ diff --git a/src/dom/js/jsxdrapi.c b/src/dom/js/jsxdrapi.c new file mode 100644 index 000000000..1b092924d --- /dev/null +++ b/src/dom/js/jsxdrapi.c @@ -0,0 +1,690 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ +#include "jsstddef.h" +#include "jsconfig.h" + +#if JS_HAS_XDR + +#include +#include "jstypes.h" +#include "jsutil.h" /* Added by JSIFY */ +#include "jsdhash.h" +#include "jsprf.h" +#include "jsapi.h" +#include "jscntxt.h" +#include "jsobj.h" /* js_XDRObject */ +#include "jsscript.h" /* js_XDRScript */ +#include "jsstr.h" +#include "jsxdrapi.h" + +#ifdef DEBUG +#define DBG(x) x +#else +#define DBG(x) ((void)0) +#endif + +typedef struct JSXDRMemState { + JSXDRState state; + char *base; + uint32 count; + uint32 limit; +} JSXDRMemState; + +#define MEM_BLOCK 8192 +#define MEM_PRIV(xdr) ((JSXDRMemState *)(xdr)) + +#define MEM_BASE(xdr) (MEM_PRIV(xdr)->base) +#define MEM_COUNT(xdr) (MEM_PRIV(xdr)->count) +#define MEM_LIMIT(xdr) (MEM_PRIV(xdr)->limit) + +#define MEM_LEFT(xdr, bytes) \ + JS_BEGIN_MACRO \ + if ((xdr)->mode == JSXDR_DECODE && \ + MEM_COUNT(xdr) + bytes > MEM_LIMIT(xdr)) { \ + JS_ReportErrorNumber((xdr)->cx, js_GetErrorMessage, NULL, \ + JSMSG_END_OF_DATA); \ + return 0; \ + } \ + JS_END_MACRO + +#define MEM_NEED(xdr, bytes) \ + JS_BEGIN_MACRO \ + if ((xdr)->mode == JSXDR_ENCODE) { \ + if (MEM_LIMIT(xdr) && \ + MEM_COUNT(xdr) + bytes > MEM_LIMIT(xdr)) { \ + uint32 limit_ = JS_ROUNDUP(MEM_COUNT(xdr) + bytes, MEM_BLOCK);\ + void *data_ = JS_realloc((xdr)->cx, MEM_BASE(xdr), limit_); \ + if (!data_) \ + return 0; \ + MEM_BASE(xdr) = data_; \ + MEM_LIMIT(xdr) = limit_; \ + } \ + } else { \ + MEM_LEFT(xdr, bytes); \ + } \ + JS_END_MACRO + +#define MEM_DATA(xdr) ((void *)(MEM_BASE(xdr) + MEM_COUNT(xdr))) +#define MEM_INCR(xdr,bytes) (MEM_COUNT(xdr) += (bytes)) + +static JSBool +mem_get32(JSXDRState *xdr, uint32 *lp) +{ + MEM_LEFT(xdr, 4); + *lp = *(uint32 *)MEM_DATA(xdr); + MEM_INCR(xdr, 4); + return JS_TRUE; +} + +static JSBool +mem_set32(JSXDRState *xdr, uint32 *lp) +{ + MEM_NEED(xdr, 4); + *(uint32 *)MEM_DATA(xdr) = *lp; + MEM_INCR(xdr, 4); + return JS_TRUE; +} + +static JSBool +mem_getbytes(JSXDRState *xdr, char *bytes, uint32 len) +{ + MEM_LEFT(xdr, len); + memcpy(bytes, MEM_DATA(xdr), len); + MEM_INCR(xdr, len); + return JS_TRUE; +} + +static JSBool +mem_setbytes(JSXDRState *xdr, char *bytes, uint32 len) +{ + MEM_NEED(xdr, len); + memcpy(MEM_DATA(xdr), bytes, len); + MEM_INCR(xdr, len); + return JS_TRUE; +} + +static void * +mem_raw(JSXDRState *xdr, uint32 len) +{ + void *data; + if (xdr->mode == JSXDR_ENCODE) { + MEM_NEED(xdr, len); + } else if (xdr->mode == JSXDR_DECODE) { + MEM_LEFT(xdr, len); + } + data = MEM_DATA(xdr); + MEM_INCR(xdr, len); + return data; +} + +static JSBool +mem_seek(JSXDRState *xdr, int32 offset, JSXDRWhence whence) +{ + switch (whence) { + case JSXDR_SEEK_CUR: + if ((int32)MEM_COUNT(xdr) + offset < 0) { + JS_ReportErrorNumber(xdr->cx, js_GetErrorMessage, NULL, + JSMSG_SEEK_BEYOND_START); + return JS_FALSE; + } + if (offset > 0) + MEM_NEED(xdr, offset); + MEM_COUNT(xdr) += offset; + return JS_TRUE; + case JSXDR_SEEK_SET: + if (offset < 0) { + JS_ReportErrorNumber(xdr->cx, js_GetErrorMessage, NULL, + JSMSG_SEEK_BEYOND_START); + return JS_FALSE; + } + if (xdr->mode == JSXDR_ENCODE) { + if ((uint32)offset > MEM_COUNT(xdr)) + MEM_NEED(xdr, offset - MEM_COUNT(xdr)); + MEM_COUNT(xdr) = offset; + } else { + if ((uint32)offset > MEM_LIMIT(xdr)) { + JS_ReportErrorNumber(xdr->cx, js_GetErrorMessage, NULL, + JSMSG_SEEK_BEYOND_END); + return JS_FALSE; + } + MEM_COUNT(xdr) = offset; + } + return JS_TRUE; + case JSXDR_SEEK_END: + if (offset >= 0 || + xdr->mode == JSXDR_ENCODE || + (int32)MEM_LIMIT(xdr) + offset < 0) { + JS_ReportErrorNumber(xdr->cx, js_GetErrorMessage, NULL, + JSMSG_END_SEEK); + return JS_FALSE; + } + MEM_COUNT(xdr) = MEM_LIMIT(xdr) + offset; + return JS_TRUE; + default: { + char numBuf[12]; + JS_snprintf(numBuf, sizeof numBuf, "%d", whence); + JS_ReportErrorNumber(xdr->cx, js_GetErrorMessage, NULL, + JSMSG_WHITHER_WHENCE, numBuf); + return JS_FALSE; + } + } +} + +static uint32 +mem_tell(JSXDRState *xdr) +{ + return MEM_COUNT(xdr); +} + +static void +mem_finalize(JSXDRState *xdr) +{ + JS_free(xdr->cx, MEM_BASE(xdr)); +} + +static JSXDROps xdrmem_ops = { + mem_get32, mem_set32, mem_getbytes, mem_setbytes, + mem_raw, mem_seek, mem_tell, mem_finalize +}; + +JS_PUBLIC_API(void) +JS_XDRInitBase(JSXDRState *xdr, JSXDRMode mode, JSContext *cx) +{ + xdr->mode = mode; + xdr->cx = cx; + xdr->registry = NULL; + xdr->numclasses = xdr->maxclasses = 0; + xdr->reghash = NULL; + xdr->userdata = NULL; +} + +JS_PUBLIC_API(JSXDRState *) +JS_XDRNewMem(JSContext *cx, JSXDRMode mode) +{ + JSXDRState *xdr = (JSXDRState *) JS_malloc(cx, sizeof(JSXDRMemState)); + if (!xdr) + return NULL; + JS_XDRInitBase(xdr, mode, cx); + if (mode == JSXDR_ENCODE) { + if (!(MEM_BASE(xdr) = JS_malloc(cx, MEM_BLOCK))) { + JS_free(cx, xdr); + return NULL; + } + } else { + /* XXXbe ok, so better not deref MEM_BASE(xdr) if not ENCODE */ + MEM_BASE(xdr) = NULL; + } + xdr->ops = &xdrmem_ops; + MEM_COUNT(xdr) = 0; + MEM_LIMIT(xdr) = MEM_BLOCK; + return xdr; +} + +JS_PUBLIC_API(void *) +JS_XDRMemGetData(JSXDRState *xdr, uint32 *lp) +{ + if (xdr->ops != &xdrmem_ops) + return NULL; + *lp = MEM_COUNT(xdr); + return MEM_BASE(xdr); +} + +JS_PUBLIC_API(void) +JS_XDRMemSetData(JSXDRState *xdr, void *data, uint32 len) +{ + if (xdr->ops != &xdrmem_ops) + return; + MEM_LIMIT(xdr) = len; + MEM_BASE(xdr) = data; + MEM_COUNT(xdr) = 0; +} + +JS_PUBLIC_API(uint32) +JS_XDRMemDataLeft(JSXDRState *xdr) +{ + if (xdr->ops != &xdrmem_ops) + return 0; + return MEM_LIMIT(xdr) - MEM_COUNT(xdr); +} + +JS_PUBLIC_API(void) +JS_XDRMemResetData(JSXDRState *xdr) +{ + if (xdr->ops != &xdrmem_ops) + return; + MEM_COUNT(xdr) = 0; +} + +JS_PUBLIC_API(void) +JS_XDRDestroy(JSXDRState *xdr) +{ + JSContext *cx = xdr->cx; + xdr->ops->finalize(xdr); + if (xdr->registry) { + JS_free(cx, xdr->registry); + if (xdr->reghash) + JS_DHashTableDestroy(xdr->reghash); + } + JS_free(cx, xdr); +} + +JS_PUBLIC_API(JSBool) +JS_XDRUint8(JSXDRState *xdr, uint8 *b) +{ + uint32 l = *b; + if (!JS_XDRUint32(xdr, &l)) + return JS_FALSE; + *b = (uint8) l; + return JS_TRUE; +} + +JS_PUBLIC_API(JSBool) +JS_XDRUint16(JSXDRState *xdr, uint16 *s) +{ + uint32 l = *s; + if (!JS_XDRUint32(xdr, &l)) + return JS_FALSE; + *s = (uint16) l; + return JS_TRUE; +} + +JS_PUBLIC_API(JSBool) +JS_XDRUint32(JSXDRState *xdr, uint32 *lp) +{ + JSBool ok = JS_TRUE; + if (xdr->mode == JSXDR_ENCODE) { + uint32 xl = JSXDR_SWAB32(*lp); + ok = xdr->ops->set32(xdr, &xl); + } else if (xdr->mode == JSXDR_DECODE) { + ok = xdr->ops->get32(xdr, lp); + *lp = JSXDR_SWAB32(*lp); + } + return ok; +} + +JS_PUBLIC_API(JSBool) +JS_XDRBytes(JSXDRState *xdr, char *bytes, uint32 len) +{ + uint32 padlen; + static char padbuf[JSXDR_ALIGN-1]; + + if (xdr->mode == JSXDR_ENCODE) { + if (!xdr->ops->setbytes(xdr, bytes, len)) + return JS_FALSE; + } else { + if (!xdr->ops->getbytes(xdr, bytes, len)) + return JS_FALSE; + } + len = xdr->ops->tell(xdr); + if (len % JSXDR_ALIGN) { + padlen = JSXDR_ALIGN - (len % JSXDR_ALIGN); + if (xdr->mode == JSXDR_ENCODE) { + if (!xdr->ops->setbytes(xdr, padbuf, padlen)) + return JS_FALSE; + } else { + if (!xdr->ops->seek(xdr, padlen, JSXDR_SEEK_CUR)) + return JS_FALSE; + } + } + return JS_TRUE; +} + +/** + * Convert between a C string and the XDR representation: + * leading 32-bit count, then counted vector of chars, + * then possibly \0 padding to multiple of 4. + */ +JS_PUBLIC_API(JSBool) +JS_XDRCString(JSXDRState *xdr, char **sp) +{ + uint32 len; + + if (xdr->mode == JSXDR_ENCODE) + len = strlen(*sp); + JS_XDRUint32(xdr, &len); + if (xdr->mode == JSXDR_DECODE) { + if (!(*sp = (char *) JS_malloc(xdr->cx, len + 1))) + return JS_FALSE; + } + if (!JS_XDRBytes(xdr, *sp, len)) { + if (xdr->mode == JSXDR_DECODE) + JS_free(xdr->cx, *sp); + return JS_FALSE; + } + if (xdr->mode == JSXDR_DECODE) { + (*sp)[len] = '\0'; + } else if (xdr->mode == JSXDR_FREE) { + JS_free(xdr->cx, *sp); + *sp = NULL; + } + return JS_TRUE; +} + +JS_PUBLIC_API(JSBool) +JS_XDRCStringOrNull(JSXDRState *xdr, char **sp) +{ + uint32 null = (*sp == NULL); + if (!JS_XDRUint32(xdr, &null)) + return JS_FALSE; + if (null) { + *sp = NULL; + return JS_TRUE; + } + return JS_XDRCString(xdr, sp); +} + +/* + * Convert between a JS (Unicode) string and the XDR representation. + */ +JS_PUBLIC_API(JSBool) +JS_XDRString(JSXDRState *xdr, JSString **strp) +{ + uint32 i, len, padlen, nbytes; + jschar *chars = NULL, *raw; + + if (xdr->mode == JSXDR_ENCODE) + len = JSSTRING_LENGTH(*strp); + if (!JS_XDRUint32(xdr, &len)) + return JS_FALSE; + nbytes = len * sizeof(jschar); + + if (xdr->mode == JSXDR_DECODE) { + if (!(chars = (jschar *) JS_malloc(xdr->cx, nbytes + sizeof(jschar)))) + return JS_FALSE; + } else { + chars = JSSTRING_CHARS(*strp); + } + + padlen = nbytes % JSXDR_ALIGN; + if (padlen) { + padlen = JSXDR_ALIGN - padlen; + nbytes += padlen; + } + if (!(raw = (jschar *) xdr->ops->raw(xdr, nbytes))) + goto bad; + if (xdr->mode == JSXDR_ENCODE) { + for (i = 0; i < len; i++) + raw[i] = JSXDR_SWAB16(chars[i]); + if (padlen) + memset((char *)raw + nbytes - padlen, 0, padlen); + } else if (xdr->mode == JSXDR_DECODE) { + for (i = 0; i < len; i++) + chars[i] = JSXDR_SWAB16(raw[i]); + chars[len] = 0; + + if (!(*strp = JS_NewUCString(xdr->cx, chars, len))) + goto bad; + } + return JS_TRUE; + +bad: + if (xdr->mode == JSXDR_DECODE) + JS_free(xdr->cx, chars); + return JS_FALSE; +} + +JS_PUBLIC_API(JSBool) +JS_XDRStringOrNull(JSXDRState *xdr, JSString **strp) +{ + uint32 null = (*strp == NULL); + if (!JS_XDRUint32(xdr, &null)) + return JS_FALSE; + if (null) { + *strp = NULL; + return JS_TRUE; + } + return JS_XDRString(xdr, strp); +} + +JS_PUBLIC_API(JSBool) +JS_XDRDouble(JSXDRState *xdr, jsdouble **dp) +{ + jsdouble d; + if (xdr->mode == JSXDR_ENCODE) + d = **dp; +#if IS_BIG_ENDIAN + if (!JS_XDRUint32(xdr, (uint32 *)&d + 1) || + !JS_XDRUint32(xdr, (uint32 *)&d)) +#else + if (!JS_XDRUint32(xdr, (uint32 *)&d) || + !JS_XDRUint32(xdr, (uint32 *)&d + 1)) +#endif + return JS_FALSE; + if (xdr->mode == JSXDR_DECODE) { + *dp = JS_NewDouble(xdr->cx, d); + if (!*dp) + return JS_FALSE; + } + return JS_TRUE; +} + +/* These are magic pseudo-tags: see jsapi.h, near the top, for real tags. */ +#define JSVAL_XDRNULL 0x8 +#define JSVAL_XDRVOID 0xA + +JS_PUBLIC_API(JSBool) +JS_XDRValue(JSXDRState *xdr, jsval *vp) +{ + uint32 type; + + if (xdr->mode == JSXDR_ENCODE) { + if (JSVAL_IS_NULL(*vp)) + type = JSVAL_XDRNULL; + else if (JSVAL_IS_VOID(*vp)) + type = JSVAL_XDRVOID; + else + type = JSVAL_TAG(*vp); + } + if (!JS_XDRUint32(xdr, &type)) + return JS_FALSE; + + switch (type) { + case JSVAL_XDRNULL: + *vp = JSVAL_NULL; + break; + case JSVAL_XDRVOID: + *vp = JSVAL_VOID; + break; + case JSVAL_STRING: { + JSString *str; + if (xdr->mode == JSXDR_ENCODE) + str = JSVAL_TO_STRING(*vp); + if (!JS_XDRString(xdr, &str)) + return JS_FALSE; + if (xdr->mode == JSXDR_DECODE) + *vp = STRING_TO_JSVAL(str); + break; + } + case JSVAL_DOUBLE: { + jsdouble *dp; + if (xdr->mode == JSXDR_ENCODE) + dp = JSVAL_TO_DOUBLE(*vp); + if (!JS_XDRDouble(xdr, &dp)) + return JS_FALSE; + if (xdr->mode == JSXDR_DECODE) + *vp = DOUBLE_TO_JSVAL(dp); + break; + } + case JSVAL_OBJECT: { + JSObject *obj; + if (xdr->mode == JSXDR_ENCODE) + obj = JSVAL_TO_OBJECT(*vp); + if (!js_XDRObject(xdr, &obj)) + return JS_FALSE; + if (xdr->mode == JSXDR_DECODE) + *vp = OBJECT_TO_JSVAL(obj); + break; + } + case JSVAL_BOOLEAN: { + uint32 b; + if (xdr->mode == JSXDR_ENCODE) + b = (uint32) JSVAL_TO_BOOLEAN(*vp); + if (!JS_XDRUint32(xdr, &b)) + return JS_FALSE; + if (xdr->mode == JSXDR_DECODE) + *vp = BOOLEAN_TO_JSVAL((JSBool) b); + break; + } + default: { + uint32 i; + + JS_ASSERT(type & JSVAL_INT); + if (xdr->mode == JSXDR_ENCODE) + i = (uint32) JSVAL_TO_INT(*vp); + if (!JS_XDRUint32(xdr, &i)) + return JS_FALSE; + if (xdr->mode == JSXDR_DECODE) + *vp = INT_TO_JSVAL((int32) i); + break; + } + } + return JS_TRUE; +} + +JS_PUBLIC_API(JSBool) +JS_XDRScript(JSXDRState *xdr, JSScript **scriptp) +{ + if (!js_XDRScript(xdr, scriptp, NULL)) + return JS_FALSE; + if (xdr->mode == JSXDR_DECODE) + js_CallNewScriptHook(xdr->cx, *scriptp, NULL); + return JS_TRUE; +} + +#define CLASS_REGISTRY_MIN 8 +#define CLASS_INDEX_TO_ID(i) ((i)+1) +#define CLASS_ID_TO_INDEX(id) ((id)-1) + +typedef struct JSRegHashEntry { + JSDHashEntryHdr hdr; + const char *name; + uint32 index; +} JSRegHashEntry; + +JS_PUBLIC_API(JSBool) +JS_XDRRegisterClass(JSXDRState *xdr, JSClass *clasp, uint32 *idp) +{ + uintN numclasses, maxclasses; + JSClass **registry; + + numclasses = xdr->numclasses; + maxclasses = xdr->maxclasses; + if (numclasses == maxclasses) { + maxclasses = (maxclasses == 0) ? CLASS_REGISTRY_MIN : maxclasses << 1; + registry = (JSClass **) + JS_realloc(xdr->cx, xdr->registry, maxclasses * sizeof(JSClass *)); + if (!registry) + return JS_FALSE; + xdr->registry = registry; + xdr->maxclasses = maxclasses; + } else { + JS_ASSERT(numclasses && numclasses < maxclasses); + registry = xdr->registry; + } + + registry[numclasses] = clasp; + if (xdr->reghash) { + JSRegHashEntry *entry = (JSRegHashEntry *) + JS_DHashTableOperate(xdr->reghash, clasp->name, JS_DHASH_ADD); + if (!entry) { + JS_ReportOutOfMemory(xdr->cx); + return JS_FALSE; + } + entry->name = clasp->name; + entry->index = numclasses; + } + *idp = CLASS_INDEX_TO_ID(numclasses); + xdr->numclasses = ++numclasses; + return JS_TRUE; +} + +JS_PUBLIC_API(uint32) +JS_XDRFindClassIdByName(JSXDRState *xdr, const char *name) +{ + uintN i, numclasses; + + numclasses = xdr->numclasses; + if (numclasses >= 10) { + JSRegHashEntry *entry; + + /* Bootstrap reghash from registry on first overpopulated Find. */ + if (!xdr->reghash) { + xdr->reghash = JS_NewDHashTable(JS_DHashGetStubOps(), NULL, + sizeof(JSRegHashEntry), + numclasses); + if (xdr->reghash) { + for (i = 0; i < numclasses; i++) { + JSClass *clasp = xdr->registry[i]; + entry = (JSRegHashEntry *) + JS_DHashTableOperate(xdr->reghash, clasp->name, + JS_DHASH_ADD); + entry->name = clasp->name; + entry->index = i; + } + } + } + + /* If we managed to create reghash, use it for O(1) Find. */ + if (xdr->reghash) { + entry = (JSRegHashEntry *) + JS_DHashTableOperate(xdr->reghash, name, JS_DHASH_LOOKUP); + if (JS_DHASH_ENTRY_IS_BUSY(&entry->hdr)) + return CLASS_INDEX_TO_ID(entry->index); + } + } + + /* Only a few classes, or we couldn't malloc reghash: use linear search. */ + for (i = 0; i < numclasses; i++) { + if (!strcmp(name, xdr->registry[i]->name)) + return CLASS_INDEX_TO_ID(i); + } + return 0; +} + +JS_PUBLIC_API(JSClass *) +JS_XDRFindClassById(JSXDRState *xdr, uint32 id) +{ + uintN i = CLASS_ID_TO_INDEX(id); + + if (i >= xdr->numclasses) + return NULL; + return xdr->registry[i]; +} + +#endif /* JS_HAS_XDR */ diff --git a/src/dom/js/jsxdrapi.h b/src/dom/js/jsxdrapi.h new file mode 100644 index 000000000..874a62eeb --- /dev/null +++ b/src/dom/js/jsxdrapi.h @@ -0,0 +1,193 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef jsxdrapi_h___ +#define jsxdrapi_h___ + +/* + * JS external data representation interface API. + * + * The XDR system is comprised of three major parts: + * + * - the state serialization/deserialization APIs, which allow consumers + * of the API to serialize JS runtime state (script bytecodes, atom maps, + * object graphs, etc.) for later restoration. These portions + * are implemented in various appropriate files, such as jsscript.c + * for the script portions and jsobj.c for object state. + * - the callback APIs through which the runtime requests an opaque + * representation of a native object, and through which the runtime + * constructs a live native object from an opaque representation. These + * portions are the responsibility of the native object implementor. + * - utility functions for en/decoding of primitive types, such as + * JSStrings. This portion is implemented in jsxdrapi.c. + * + * Spiritually guided by Sun's XDR, where appropriate. + */ + +#include "jspubtd.h" +#include "jsprvtd.h" + +JS_BEGIN_EXTERN_C + +/* We use little-endian byteorder for all encoded data */ + +#if defined IS_LITTLE_ENDIAN +#define JSXDR_SWAB32(x) x +#define JSXDR_SWAB16(x) x +#elif defined IS_BIG_ENDIAN +#define JSXDR_SWAB32(x) (((uint32)(x) >> 24) | \ + (((uint32)(x) >> 8) & 0xff00) | \ + (((uint32)(x) << 8) & 0xff0000) | \ + ((uint32)(x) << 24)) +#define JSXDR_SWAB16(x) (((uint16)(x) >> 8) | ((uint16)(x) << 8)) +#else +#error "unknown byte order" +#endif + +#define JSXDR_ALIGN 4 + +typedef enum JSXDRMode { + JSXDR_ENCODE, + JSXDR_DECODE, + JSXDR_FREE +} JSXDRMode; + +typedef enum JSXDRWhence { + JSXDR_SEEK_SET, + JSXDR_SEEK_CUR, + JSXDR_SEEK_END +} JSXDRWhence; + +typedef struct JSXDROps { + JSBool (*get32)(JSXDRState *, uint32 *); + JSBool (*set32)(JSXDRState *, uint32 *); + JSBool (*getbytes)(JSXDRState *, char *, uint32); + JSBool (*setbytes)(JSXDRState *, char *, uint32); + void * (*raw)(JSXDRState *, uint32); + JSBool (*seek)(JSXDRState *, int32, JSXDRWhence); + uint32 (*tell)(JSXDRState *); + void (*finalize)(JSXDRState *); +} JSXDROps; + +struct JSXDRState { + JSXDRMode mode; + JSXDROps *ops; + JSContext *cx; + JSClass **registry; + uintN numclasses; + uintN maxclasses; + void *reghash; + void *userdata; +}; + +extern JS_PUBLIC_API(void) +JS_XDRInitBase(JSXDRState *xdr, JSXDRMode mode, JSContext *cx); + +extern JS_PUBLIC_API(JSXDRState *) +JS_XDRNewMem(JSContext *cx, JSXDRMode mode); + +extern JS_PUBLIC_API(void *) +JS_XDRMemGetData(JSXDRState *xdr, uint32 *lp); + +extern JS_PUBLIC_API(void) +JS_XDRMemSetData(JSXDRState *xdr, void *data, uint32 len); + +extern JS_PUBLIC_API(uint32) +JS_XDRMemDataLeft(JSXDRState *xdr); + +extern JS_PUBLIC_API(void) +JS_XDRMemResetData(JSXDRState *xdr); + +extern JS_PUBLIC_API(void) +JS_XDRDestroy(JSXDRState *xdr); + +extern JS_PUBLIC_API(JSBool) +JS_XDRUint8(JSXDRState *xdr, uint8 *b); + +extern JS_PUBLIC_API(JSBool) +JS_XDRUint16(JSXDRState *xdr, uint16 *s); + +extern JS_PUBLIC_API(JSBool) +JS_XDRUint32(JSXDRState *xdr, uint32 *lp); + +extern JS_PUBLIC_API(JSBool) +JS_XDRBytes(JSXDRState *xdr, char *bytes, uint32 len); + +extern JS_PUBLIC_API(JSBool) +JS_XDRCString(JSXDRState *xdr, char **sp); + +extern JS_PUBLIC_API(JSBool) +JS_XDRCStringOrNull(JSXDRState *xdr, char **sp); + +extern JS_PUBLIC_API(JSBool) +JS_XDRString(JSXDRState *xdr, JSString **strp); + +extern JS_PUBLIC_API(JSBool) +JS_XDRStringOrNull(JSXDRState *xdr, JSString **strp); + +extern JS_PUBLIC_API(JSBool) +JS_XDRDouble(JSXDRState *xdr, jsdouble **dp); + +extern JS_PUBLIC_API(JSBool) +JS_XDRValue(JSXDRState *xdr, jsval *vp); + +extern JS_PUBLIC_API(JSBool) +JS_XDRScript(JSXDRState *xdr, JSScript **scriptp); + +extern JS_PUBLIC_API(JSBool) +JS_XDRRegisterClass(JSXDRState *xdr, JSClass *clasp, uint32 *lp); + +extern JS_PUBLIC_API(uint32) +JS_XDRFindClassIdByName(JSXDRState *xdr, const char *name); + +extern JS_PUBLIC_API(JSClass *) +JS_XDRFindClassById(JSXDRState *xdr, uint32 id); + +/* + * Magic numbers. + */ +#define JSXDR_MAGIC_SCRIPT_1 0xdead0001 +#define JSXDR_MAGIC_SCRIPT_2 0xdead0002 +#define JSXDR_MAGIC_SCRIPT_3 0xdead0003 +#define JSXDR_MAGIC_SCRIPT_4 0xdead0004 +#define JSXDR_MAGIC_SCRIPT_CURRENT JSXDR_MAGIC_SCRIPT_4 + +JS_END_EXTERN_C + +#endif /* ! jsxdrapi_h___ */ diff --git a/src/dom/js/prmjtime.c b/src/dom/js/prmjtime.c new file mode 100644 index 000000000..0a53f76bf --- /dev/null +++ b/src/dom/js/prmjtime.c @@ -0,0 +1,646 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* + * PR time code. + */ +#include "jsstddef.h" +#ifdef SOLARIS +#define _REENTRANT 1 +#endif +#include +#include +#include "jstypes.h" +#include "jsutil.h" + +#include "jsprf.h" +#include "prmjtime.h" + +#define PRMJ_DO_MILLISECONDS 1 + +#ifdef XP_OS2 +#include +#endif +#ifdef XP_WIN +#include +#include +#endif + +#ifdef XP_MAC +#include +#include +#include +#include +#include +#include +#include +#if !TARGET_CARBON +#include +#endif +#endif + +#if defined(XP_UNIX) || defined(XP_BEOS) + +#ifdef _SVID_GETTOD /* Defined only on Solaris, see Solaris */ +extern int gettimeofday(struct timeval *tv); +#endif + +#include + +#endif /* XP_UNIX */ + +#ifdef XP_MAC +static uint64 dstLocalBaseMicroseconds; +static unsigned long gJanuaryFirst1970Seconds; + +static void MacintoshInitializeTime(void) +{ + uint64 upTime; + unsigned long currentLocalTimeSeconds, + startupTimeSeconds; + uint64 startupTimeMicroSeconds; + uint32 upTimeSeconds; + uint64 oneMillion, upTimeSecondsLong, microSecondsToSeconds; + DateTimeRec firstSecondOfUnixTime; + + /* + * Figure out in local time what time the machine started up. This information can be added to + * upTime to figure out the current local time as well as GMT. + */ + + Microseconds((UnsignedWide*)&upTime); + + GetDateTime(¤tLocalTimeSeconds); + + JSLL_I2L(microSecondsToSeconds, PRMJ_USEC_PER_SEC); + JSLL_DIV(upTimeSecondsLong, upTime, microSecondsToSeconds); + JSLL_L2I(upTimeSeconds, upTimeSecondsLong); + + startupTimeSeconds = currentLocalTimeSeconds - upTimeSeconds; + + /* Make sure that we normalize the macintosh base seconds to the unix base of January 1, 1970. + */ + + firstSecondOfUnixTime.year = 1970; + firstSecondOfUnixTime.month = 1; + firstSecondOfUnixTime.day = 1; + firstSecondOfUnixTime.hour = 0; + firstSecondOfUnixTime.minute = 0; + firstSecondOfUnixTime.second = 0; + firstSecondOfUnixTime.dayOfWeek = 0; + + DateToSeconds(&firstSecondOfUnixTime, &gJanuaryFirst1970Seconds); + + startupTimeSeconds -= gJanuaryFirst1970Seconds; + + /* Now convert the startup time into a wide so that we can figure out GMT and DST. + */ + + JSLL_I2L(startupTimeMicroSeconds, startupTimeSeconds); + JSLL_I2L(oneMillion, PRMJ_USEC_PER_SEC); + JSLL_MUL(dstLocalBaseMicroseconds, oneMillion, startupTimeMicroSeconds); +} + +static SleepQRec gSleepQEntry = { NULL, sleepQType, NULL, 0 }; +static JSBool gSleepQEntryInstalled = JS_FALSE; + +static pascal long MySleepQProc(long message, SleepQRecPtr sleepQ) +{ + /* just woke up from sleeping, so must recompute dstLocalBaseMicroseconds. */ + if (message == kSleepWakeUp) + MacintoshInitializeTime(); + return 0; +} + +/* Because serial port and SLIP conflict with ReadXPram calls, + * we cache the call here + */ + +static void MyReadLocation(MachineLocation * loc) +{ + static MachineLocation storedLoc; /* InsideMac, OSUtilities, page 4-20 */ + static JSBool didReadLocation = JS_FALSE; + if (!didReadLocation) + { + MacintoshInitializeTime(); + ReadLocation(&storedLoc); + /* install a sleep queue routine, so that when the machine wakes up, time can be recomputed. */ + if (&SleepQInstall != (void*)kUnresolvedCFragSymbolAddress +#if !TARGET_CARBON + && NGetTrapAddress(0xA28A, OSTrap) != NGetTrapAddress(_Unimplemented, ToolTrap) +#endif + ) { + if ((gSleepQEntry.sleepQProc = NewSleepQUPP(MySleepQProc)) != NULL) { + SleepQInstall(&gSleepQEntry); + gSleepQEntryInstalled = JS_TRUE; + } + } + didReadLocation = JS_TRUE; + } + *loc = storedLoc; +} + + +#ifndef XP_MACOSX + +/* CFM library init and terminate routines. We'll use the terminate routine + to clean up the sleep Q entry. On Mach-O, the sleep Q entry gets cleaned + up for us, so nothing to do there. +*/ + +extern pascal OSErr __NSInitialize(const CFragInitBlock* initBlock); +extern pascal void __NSTerminate(); + +pascal OSErr __JSInitialize(const CFragInitBlock* initBlock); +pascal void __JSTerminate(void); + +pascal OSErr __JSInitialize(const CFragInitBlock* initBlock) +{ + return __NSInitialize(initBlock); +} + +pascal void __JSTerminate() +{ + /* clean up the sleepQ entry */ + if (gSleepQEntryInstalled) + SleepQRemove(&gSleepQEntry); + + __NSTerminate(); +} +#endif /* XP_MACOSX */ + +#endif /* XP_MAC */ + +#define IS_LEAP(year) \ + (year != 0 && ((((year & 0x3) == 0) && \ + ((year - ((year/100) * 100)) != 0)) || \ + (year - ((year/400) * 400)) == 0)) + +#define PRMJ_HOUR_SECONDS 3600L +#define PRMJ_DAY_SECONDS (24L * PRMJ_HOUR_SECONDS) +#define PRMJ_YEAR_SECONDS (PRMJ_DAY_SECONDS * 365L) +#define PRMJ_MAX_UNIX_TIMET 2145859200L /*time_t value equiv. to 12/31/2037 */ +/* function prototypes */ +static void PRMJ_basetime(JSInt64 tsecs, PRMJTime *prtm); +/* + * get the difference in seconds between this time zone and UTC (GMT) + */ +JSInt32 +PRMJ_LocalGMTDifference() +{ +#if defined(XP_UNIX) || defined(XP_WIN) || defined(XP_OS2) || defined(XP_BEOS) + struct tm ltime; + + /* get the difference between this time zone and GMT */ + memset((char *)<ime,0,sizeof(ltime)); + ltime.tm_mday = 2; + ltime.tm_year = 70; +#ifdef SUNOS4 + ltime.tm_zone = 0; + ltime.tm_gmtoff = 0; + return timelocal(<ime) - (24 * 3600); +#else + return mktime(<ime) - (24L * 3600L); +#endif +#endif +#if defined(XP_MAC) + static JSInt32 zone = -1L; + MachineLocation machineLocation; + JSInt32 gmtOffsetSeconds; + + /* difference has been set no need to recalculate */ + if (zone != -1) + return zone; + + /* Get the information about the local machine, including + * its GMT offset and its daylight savings time info. + * Convert each into wides that we can add to + * startupTimeMicroSeconds. + */ + + MyReadLocation(&machineLocation); + + /* Mask off top eight bits of gmtDelta, sign extend lower three. */ + gmtOffsetSeconds = (machineLocation.u.gmtDelta << 8); + gmtOffsetSeconds >>= 8; + + /* Backout OS adjustment for DST, to give consistent GMT offset. */ + if (machineLocation.u.dlsDelta != 0) + gmtOffsetSeconds -= PRMJ_HOUR_SECONDS; + return (zone = -gmtOffsetSeconds); +#endif +} + +/* Constants for GMT offset from 1970 */ +#define G1970GMTMICROHI 0x00dcdcad /* micro secs to 1970 hi */ +#define G1970GMTMICROLOW 0x8b3fa000 /* micro secs to 1970 low */ + +#define G2037GMTMICROHI 0x00e45fab /* micro secs to 2037 high */ +#define G2037GMTMICROLOW 0x7a238000 /* micro secs to 2037 low */ + +/* Convert from base time to extended time */ +static JSInt64 +PRMJ_ToExtendedTime(JSInt32 base_time) +{ + JSInt64 exttime; + JSInt64 g1970GMTMicroSeconds; + JSInt64 low; + JSInt32 diff; + JSInt64 tmp; + JSInt64 tmp1; + + diff = PRMJ_LocalGMTDifference(); + JSLL_UI2L(tmp, PRMJ_USEC_PER_SEC); + JSLL_I2L(tmp1,diff); + JSLL_MUL(tmp,tmp,tmp1); + + JSLL_UI2L(g1970GMTMicroSeconds,G1970GMTMICROHI); + JSLL_UI2L(low,G1970GMTMICROLOW); +#ifndef JS_HAVE_LONG_LONG + JSLL_SHL(g1970GMTMicroSeconds,g1970GMTMicroSeconds,16); + JSLL_SHL(g1970GMTMicroSeconds,g1970GMTMicroSeconds,16); +#else + JSLL_SHL(g1970GMTMicroSeconds,g1970GMTMicroSeconds,32); +#endif + JSLL_ADD(g1970GMTMicroSeconds,g1970GMTMicroSeconds,low); + + JSLL_I2L(exttime,base_time); + JSLL_ADD(exttime,exttime,g1970GMTMicroSeconds); + JSLL_SUB(exttime,exttime,tmp); + return exttime; +} + +JSInt64 +PRMJ_Now(void) +{ +#ifdef XP_OS2 + JSInt64 s, us, ms2us, s2us; + struct timeb b; +#endif +#ifdef XP_WIN + JSInt64 s, us, + win2un = JSLL_INIT(0x19DB1DE, 0xD53E8000), + ten = JSLL_INIT(0, 10); + FILETIME time, midnight; +#endif +#if defined(XP_UNIX) || defined(XP_BEOS) + struct timeval tv; + JSInt64 s, us, s2us; +#endif /* XP_UNIX */ +#ifdef XP_MAC + JSUint64 upTime; + JSInt64 localTime; + JSInt64 gmtOffset; + JSInt64 dstOffset; + JSInt32 gmtDiff; + JSInt64 s2us; +#endif /* XP_MAC */ + +#ifdef XP_OS2 + ftime(&b); + JSLL_UI2L(ms2us, PRMJ_USEC_PER_MSEC); + JSLL_UI2L(s2us, PRMJ_USEC_PER_SEC); + JSLL_UI2L(s, b.time); + JSLL_UI2L(us, b.millitm); + JSLL_MUL(us, us, ms2us); + JSLL_MUL(s, s, s2us); + JSLL_ADD(s, s, us); + return s; +#endif +#ifdef XP_WIN + /* The windows epoch is around 1600. The unix epoch is around 1970. + win2un is the difference (in windows time units which are 10 times + more precise than the JS time unit) */ + GetSystemTimeAsFileTime(&time); + /* Win9x gets confused at midnight + http://support.microsoft.com/default.aspx?scid=KB;en-us;q224423 + So if the low part (precision <8mins) is 0 then we get the time + again. */ + if (!time.dwLowDateTime) { + GetSystemTimeAsFileTime(&midnight); + time.dwHighDateTime = midnight.dwHighDateTime; + } + JSLL_UI2L(s, time.dwHighDateTime); + JSLL_UI2L(us, time.dwLowDateTime); + JSLL_SHL(s, s, 32); + JSLL_ADD(s, s, us); + JSLL_SUB(s, s, win2un); + JSLL_DIV(s, s, ten); + return s; +#endif + +#if defined(XP_UNIX) || defined(XP_BEOS) +#ifdef _SVID_GETTOD /* Defined only on Solaris, see Solaris */ + gettimeofday(&tv); +#else + gettimeofday(&tv, 0); +#endif /* _SVID_GETTOD */ + JSLL_UI2L(s2us, PRMJ_USEC_PER_SEC); + JSLL_UI2L(s, tv.tv_sec); + JSLL_UI2L(us, tv.tv_usec); + JSLL_MUL(s, s, s2us); + JSLL_ADD(s, s, us); + return s; +#endif /* XP_UNIX */ +#ifdef XP_MAC + JSLL_UI2L(localTime,0); + gmtDiff = PRMJ_LocalGMTDifference(); + JSLL_I2L(gmtOffset,gmtDiff); + JSLL_UI2L(s2us, PRMJ_USEC_PER_SEC); + JSLL_MUL(gmtOffset,gmtOffset,s2us); + + /* don't adjust for DST since it sets ctime and gmtime off on the MAC */ + Microseconds((UnsignedWide*)&upTime); + JSLL_ADD(localTime,localTime,gmtOffset); + JSLL_ADD(localTime,localTime, dstLocalBaseMicroseconds); + JSLL_ADD(localTime,localTime, upTime); + + dstOffset = PRMJ_DSTOffset(localTime); + JSLL_SUB(localTime,localTime,dstOffset); + + return *((JSUint64 *)&localTime); +#endif /* XP_MAC */ +} + +/* Get the DST timezone offset for the time passed in */ +JSInt64 +PRMJ_DSTOffset(JSInt64 local_time) +{ + JSInt64 us2s; +#ifdef XP_MAC + /* + * Convert the local time passed in to Macintosh epoch seconds. Use UTC utilities to convert + * to UTC time, then compare difference with our GMT offset. If they are the same, then + * DST must not be in effect for the input date/time. + */ + UInt32 macLocalSeconds = (local_time / PRMJ_USEC_PER_SEC) + gJanuaryFirst1970Seconds, utcSeconds; + ConvertLocalTimeToUTC(macLocalSeconds, &utcSeconds); + if ((utcSeconds - macLocalSeconds) == PRMJ_LocalGMTDifference()) + return 0; + else { + JSInt64 dlsOffset; + JSLL_UI2L(us2s, PRMJ_USEC_PER_SEC); + JSLL_UI2L(dlsOffset, PRMJ_HOUR_SECONDS); + JSLL_MUL(dlsOffset, dlsOffset, us2s); + return dlsOffset; + } +#else + time_t local; + JSInt32 diff; + JSInt64 maxtimet; + struct tm tm; + PRMJTime prtm; +#ifndef HAVE_LOCALTIME_R + struct tm *ptm; +#endif + + + JSLL_UI2L(us2s, PRMJ_USEC_PER_SEC); + JSLL_DIV(local_time, local_time, us2s); + + /* get the maximum of time_t value */ + JSLL_UI2L(maxtimet,PRMJ_MAX_UNIX_TIMET); + + if(JSLL_CMP(local_time,>,maxtimet)){ + JSLL_UI2L(local_time,PRMJ_MAX_UNIX_TIMET); + } else if(!JSLL_GE_ZERO(local_time)){ + /*go ahead a day to make localtime work (does not work with 0) */ + JSLL_UI2L(local_time,PRMJ_DAY_SECONDS); + } + JSLL_L2UI(local,local_time); + PRMJ_basetime(local_time,&prtm); +#ifndef HAVE_LOCALTIME_R + ptm = localtime(&local); + if(!ptm){ + return JSLL_ZERO; + } + tm = *ptm; +#else + localtime_r(&local,&tm); /* get dst information */ +#endif + + diff = ((tm.tm_hour - prtm.tm_hour) * PRMJ_HOUR_SECONDS) + + ((tm.tm_min - prtm.tm_min) * 60); + + if(diff < 0){ + diff += PRMJ_DAY_SECONDS; + } + + JSLL_UI2L(local_time,diff); + + JSLL_MUL(local_time,local_time,us2s); + + return(local_time); +#endif +} + +/* Format a time value into a buffer. Same semantics as strftime() */ +size_t +PRMJ_FormatTime(char *buf, int buflen, char *fmt, PRMJTime *prtm) +{ +#if defined(XP_UNIX) || defined(XP_WIN) || defined(XP_OS2) || defined(XP_MAC) || defined(XP_BEOS) + struct tm a; + + /* Zero out the tm struct. Linux, SunOS 4 struct tm has extra members int + * tm_gmtoff, char *tm_zone; when tm_zone is garbage, strftime gets + * confused and dumps core. NSPR20 prtime.c attempts to fill these in by + * calling mktime on the partially filled struct, but this doesn't seem to + * work as well; the result string has "can't get timezone" for ECMA-valid + * years. Might still make sense to use this, but find the range of years + * for which valid tz information exists, and map (per ECMA hint) from the + * given year into that range. + + * N.B. This hasn't been tested with anything that actually _uses_ + * tm_gmtoff; zero might be the wrong thing to set it to if you really need + * to format a time. This fix is for jsdate.c, which only uses + * JS_FormatTime to get a string representing the time zone. */ + memset(&a, 0, sizeof(struct tm)); + + a.tm_sec = prtm->tm_sec; + a.tm_min = prtm->tm_min; + a.tm_hour = prtm->tm_hour; + a.tm_mday = prtm->tm_mday; + a.tm_mon = prtm->tm_mon; + a.tm_wday = prtm->tm_wday; + a.tm_year = prtm->tm_year - 1900; + a.tm_yday = prtm->tm_yday; + a.tm_isdst = prtm->tm_isdst; + + /* Even with the above, SunOS 4 seems to detonate if tm_zone and tm_gmtoff + * are null. This doesn't quite work, though - the timezone is off by + * tzoff + dst. (And mktime seems to return -1 for the exact dst + * changeover time.) + + */ + +#if defined(SUNOS4) + if (mktime(&a) == -1) { + /* Seems to fail whenever the requested date is outside of the 32-bit + * UNIX epoch. We could proceed at this point (setting a.tm_zone to + * "") but then strftime returns a string with a 2-digit field of + * garbage for the year. So we return 0 and hope jsdate.c + * will fall back on toString. + */ + return 0; + } +#endif + + return strftime(buf, buflen, fmt, &a); +#endif +} + +/* table for number of days in a month */ +static int mtab[] = { + /* jan, feb,mar,apr,may,jun */ + 31,28,31,30,31,30, + /* july,aug,sep,oct,nov,dec */ + 31,31,30,31,30,31 +}; + +/* + * basic time calculation functionality for localtime and gmtime + * setups up prtm argument with correct values based upon input number + * of seconds. + */ +static void +PRMJ_basetime(JSInt64 tsecs, PRMJTime *prtm) +{ + /* convert tsecs back to year,month,day,hour,secs */ + JSInt32 year = 0; + JSInt32 month = 0; + JSInt32 yday = 0; + JSInt32 mday = 0; + JSInt32 wday = 6; /* start on a Sunday */ + JSInt32 days = 0; + JSInt32 seconds = 0; + JSInt32 minutes = 0; + JSInt32 hours = 0; + JSInt32 isleap = 0; + JSInt64 result; + JSInt64 result1; + JSInt64 result2; + JSInt64 base; + + JSLL_UI2L(result,0); + JSLL_UI2L(result1,0); + JSLL_UI2L(result2,0); + + /* get the base time via UTC */ + base = PRMJ_ToExtendedTime(0); + JSLL_UI2L(result, PRMJ_USEC_PER_SEC); + JSLL_DIV(base,base,result); + JSLL_ADD(tsecs,tsecs,base); + + JSLL_UI2L(result, PRMJ_YEAR_SECONDS); + JSLL_UI2L(result1,PRMJ_DAY_SECONDS); + JSLL_ADD(result2,result,result1); + + /* get the year */ + while ((isleap == 0) ? !JSLL_CMP(tsecs,<,result) : !JSLL_CMP(tsecs,<,result2)) { + /* subtract a year from tsecs */ + JSLL_SUB(tsecs,tsecs,result); + days += 365; + /* is it a leap year ? */ + if(IS_LEAP(year)){ + JSLL_SUB(tsecs,tsecs,result1); + days++; + } + year++; + isleap = IS_LEAP(year); + } + + JSLL_UI2L(result1,PRMJ_DAY_SECONDS); + + JSLL_DIV(result,tsecs,result1); + JSLL_L2I(mday,result); + + /* let's find the month */ + while(((month == 1 && isleap) ? + (mday >= mtab[month] + 1) : + (mday >= mtab[month]))){ + yday += mtab[month]; + days += mtab[month]; + + mday -= mtab[month]; + + /* it's a Feb, check if this is a leap year */ + if(month == 1 && isleap != 0){ + yday++; + days++; + mday--; + } + month++; + } + + /* now adjust tsecs */ + JSLL_MUL(result,result,result1); + JSLL_SUB(tsecs,tsecs,result); + + mday++; /* day of month always start with 1 */ + days += mday; + wday = (days + wday) % 7; + + yday += mday; + + /* get the hours */ + JSLL_UI2L(result1,PRMJ_HOUR_SECONDS); + JSLL_DIV(result,tsecs,result1); + JSLL_L2I(hours,result); + JSLL_MUL(result,result,result1); + JSLL_SUB(tsecs,tsecs,result); + + /* get minutes */ + JSLL_UI2L(result1,60); + JSLL_DIV(result,tsecs,result1); + JSLL_L2I(minutes,result); + JSLL_MUL(result,result,result1); + JSLL_SUB(tsecs,tsecs,result); + + JSLL_L2I(seconds,tsecs); + + prtm->tm_usec = 0L; + prtm->tm_sec = (JSInt8)seconds; + prtm->tm_min = (JSInt8)minutes; + prtm->tm_hour = (JSInt8)hours; + prtm->tm_mday = (JSInt8)mday; + prtm->tm_mon = (JSInt8)month; + prtm->tm_wday = (JSInt8)wday; + prtm->tm_year = (JSInt16)year; + prtm->tm_yday = (JSInt16)yday; +} diff --git a/src/dom/js/prmjtime.h b/src/dom/js/prmjtime.h new file mode 100644 index 000000000..6a94a11b1 --- /dev/null +++ b/src/dom/js/prmjtime.h @@ -0,0 +1,95 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef prmjtime_h___ +#define prmjtime_h___ +/* + * PR date stuff for mocha and java. Placed here temporarily not to break + * Navigator and localize changes to mocha. + */ +#include +#include "jslong.h" +#ifdef MOZILLA_CLIENT +#include "jscompat.h" +#endif + +JS_BEGIN_EXTERN_C + +typedef struct PRMJTime PRMJTime; + +/* + * Broken down form of 64 bit time value. + */ +struct PRMJTime { + JSInt32 tm_usec; /* microseconds of second (0-999999) */ + JSInt8 tm_sec; /* seconds of minute (0-59) */ + JSInt8 tm_min; /* minutes of hour (0-59) */ + JSInt8 tm_hour; /* hour of day (0-23) */ + JSInt8 tm_mday; /* day of month (1-31) */ + JSInt8 tm_mon; /* month of year (0-11) */ + JSInt8 tm_wday; /* 0=sunday, 1=monday, ... */ + JSInt16 tm_year; /* absolute year, AD */ + JSInt16 tm_yday; /* day of year (0 to 365) */ + JSInt8 tm_isdst; /* non-zero if DST in effect */ +}; + +/* Some handy constants */ +#define PRMJ_USEC_PER_SEC 1000000L +#define PRMJ_USEC_PER_MSEC 1000L + +/* Return the current local time in micro-seconds */ +extern JSInt64 +PRMJ_Now(void); + +/* get the difference between this time zone and gmt timezone in seconds */ +extern JSInt32 +PRMJ_LocalGMTDifference(void); + +/* Format a time value into a buffer. Same semantics as strftime() */ +extern size_t +PRMJ_FormatTime(char *buf, int buflen, char *fmt, PRMJTime *tm); + +/* Get the DST offset for the local time passed in */ +extern JSInt64 +PRMJ_DSTOffset(JSInt64 local_time); + +JS_END_EXTERN_C + +#endif /* prmjtime_h___ */ + diff --git a/src/dom/js/resource.h b/src/dom/js/resource.h new file mode 100644 index 000000000..9301810e4 --- /dev/null +++ b/src/dom/js/resource.h @@ -0,0 +1,15 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by js3240.rc +// + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 101 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1000 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/src/dom/knut.svg b/src/dom/knut.svg new file mode 100755 index 000000000..0d52bf913 --- /dev/null +++ b/src/dom/knut.svg @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + diff --git a/src/dom/ls.h b/src/dom/ls.h new file mode 100755 index 000000000..658e602f9 --- /dev/null +++ b/src/dom/ls.h @@ -0,0 +1,940 @@ +#ifndef __LS_H__ +#define __LS_H__ +/** + * Phoebe DOM Implementation. + * + * This is a C++ approximation of the W3C DOM model, which follows + * fairly closely the specifications in the various .idl files, copies of + * which are provided for reference. Most important is this one: + * + * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/idl-definitions.html + * + * Authors: + * Bob Jamison + * + * Copyright (C) 2005 Bob Jamison + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +#include "dom.h" +#include "events.h" +#include "traversal.h" + +#include "domstream.h" + +namespace org +{ +namespace w3c +{ +namespace dom +{ +namespace ls +{ + + + +//Local definitions +//The idl said Object. Since this is undefined, we will +//use our own class which is designed to be a bit similar to +//java.io streams + +typedef dom::InputStream LSInputStream; +typedef dom::OutputStream LSOutputStream; +typedef dom::Reader LSReader; +typedef dom::Writer LSWriter; + + +//local definitions +typedef dom::DOMString DOMString; +typedef dom::DOMConfiguration DOMConfiguration; +typedef dom::Node Node; +typedef dom::Document Document; +typedef dom::Element Element; + + +//forward declarations +class LSParser; +class LSSerializer; +class LSInput; +class LSOutput; +class LSParserFilter; +class LSSerializerFilter; + + + +/*######################################################################### +## LSException +#########################################################################*/ + +/** + * Maybe this should inherit from DOMException? + */ +class LSException +{ + +public: + + LSException(const DOMString &reasonMsg) + { msg = reasonMsg; } + + LSException(short theCode) + { + code = theCode; + } + + virtual ~LSException() throw() + {} + + /** + * + */ + unsigned short code; + + /** + * + */ + DOMString msg; + + /** + * Get a string, translated from the code. + * Like std::exception. Not in spec. + */ + const char *what() + { return msg.c_str(); } + + + +}; + + +/** + * LSExceptionCode + */ +typedef enum + { + PARSE_ERR = 81, + SERIALIZE_ERR = 82 + } XPathExceptionCode; + + +/*######################################################################### +## LSParserFilter +#########################################################################*/ + +/** + * + */ +class LSParserFilter +{ +public: + + // Constants returned by startElement and acceptNode + typedef enum + { + FILTER_ACCEPT = 1, + FILTER_REJECT = 2, + FILTER_SKIP = 3, + FILTER_INTERRUPT = 4 + } ReturnValues; + + + /** + * + */ + virtual unsigned short startElement(const Element *elementArg) =0; + + /** + * + */ + virtual unsigned short acceptNode(const Node *nodeArg) =0; + + /** + * + */ + virtual unsigned long getWhatToShow() =0; + + //################## + //# Non-API methods + //################## + + /** + * + */ + virtual ~LSParserFilter() {} + + + +}; + +/*######################################################################### +## LSInput +#########################################################################*/ + +/** + * + */ +class LSInput +{ +public: + + /** + * + */ + virtual LSReader *getCharacterStream() const + { return characterStream; } + + /** + * + */ + virtual void setCharacterStream(const LSReader *val) + { characterStream = (LSReader *)val; } + + /** + * + */ + virtual LSInputStream *getByteStream() const + { return byteStream; } + + /** + * + */ + virtual void setByteStream(const LSInputStream *val) + { byteStream = (LSInputStream *)val; } + + /** + * + */ + virtual DOMString getStringData() const + { return stringData; } + + /** + * + */ + virtual void setStringData(const DOMString &val) + { stringData = val; } + + /** + * + */ + virtual DOMString getSystemId() const + { return systemId; } + + /** + * + */ + virtual void setSystemId(const DOMString &val) + { systemId = val; } + + /** + * + */ + virtual DOMString getPublicId() const + { return publicId; } + + /** + * + */ + virtual void setPublicId(const DOMString &val) + { publicId = val; } + + /** + * + */ + virtual DOMString getBaseURI() const + { return baseURI; } + + /** + * + */ + virtual void setBaseURI(const DOMString &val) + { baseURI = val; } + + /** + * + */ + virtual DOMString getEncoding() const + { return encoding; } + + /** + * + */ + virtual void setEncoding(const DOMString &val) + { encoding = val; } + + /** + * + */ + virtual bool getCertifiedText() const + { return certifiedText; } + + /** + * + */ + virtual void setCertifiedText(bool val) + { certifiedText = val; } + + //################## + //# Non-API methods + //################## + + + /** + * + */ + LSInput() + { + characterStream = NULL; + byteStream = NULL; + stringData = ""; + systemId = ""; + publicId = ""; + baseURI = ""; + encoding = ""; + certifiedText = false; + } + + + + /** + * + */ + LSInput(const LSInput &other) + { + characterStream = other.characterStream; + byteStream = other.byteStream; + stringData = other.stringData; + systemId = other.systemId; + publicId = other.publicId; + baseURI = other.baseURI; + encoding = other.encoding; + certifiedText = other.certifiedText; + } + + /** + * + */ + virtual ~LSInput() + {} + +private: + + LSReader *characterStream; + LSInputStream *byteStream; + DOMString stringData; + DOMString systemId; + DOMString publicId; + DOMString baseURI; + DOMString encoding; + bool certifiedText; + + +}; + + +/*######################################################################### +## LSParser +#########################################################################*/ + +/** + * + */ +class LSParser +{ +public: + + + /** + * + */ + virtual DOMConfiguration *getDomConfig() + { return NULL; } + + /** + * + */ + virtual LSParserFilter *getFilter() + { return filter; } + + /** + * + */ + virtual void setFilter(const LSParserFilter *val) + { filter = (LSParserFilter *)val; } + + /** + * + */ + virtual bool getAsync() + { return false; } + + /** + * + */ + virtual bool getBusy() + { return false; } + + /** + * + */ + virtual Document *parse(const LSInput &input) + throw(dom::DOMException, LSException) + { return NULL; } + + + /** + * + */ + virtual Document *parseURI(const DOMString &uri) + throw(dom::DOMException, LSException) + { return NULL; } + + typedef enum + { + ACTION_APPEND_AS_CHILDREN = 1, + ACTION_REPLACE_CHILDREN = 2, + ACTION_INSERT_BEFORE = 3, + ACTION_INSERT_AFTER = 4, + ACTION_REPLACE = 5 + } ActionTypes; + + + /** + * + */ + virtual Node *parseWithContext(const LSInput &input, + const Node *contextArg, + unsigned short action) + throw(dom::DOMException, LSException) + { return NULL; } + + /** + * + */ + virtual void abort() + {} + + + + //################## + //# Non-API methods + //################## + + /** + * + */ + LSParser() + { + filter = NULL; + } + + /** + * + */ + LSParser(const LSParser &other) + { + filter = other.filter; + } + + /** + * + */ + virtual ~LSParser() {} + +protected: + + LSParserFilter *filter; +}; + + + +/*######################################################################### +## LSResourceResolver +#########################################################################*/ + +/** + * + */ +class LSResourceResolver +{ +public: + + /** + * + */ + virtual LSInput resolveResource(const DOMString &type, + const DOMString &namespaceURI, + const DOMString &publicId, + const DOMString &systemId, + const DOMString &baseURI) + { + LSInput input; + //do something + return input; + } + + //################## + //# Non-API methods + //################## + + /** + * + */ + LSResourceResolver() {} + + /** + * + */ + LSResourceResolver(const LSResourceResolver &other) + { + } + + /** + * + */ + virtual ~LSResourceResolver() {} + + + +}; + +/*######################################################################### +## LSOutput +#########################################################################*/ + +/** + * + */ +class LSOutput +{ +public: + + /** + * + */ + virtual LSWriter *getCharacterStream() const + { return characterStream; } + + /** + * + */ + virtual void setCharacterStream(const LSWriter *val) + { characterStream = (LSWriter *)val; } + + /** + * + */ + virtual LSOutputStream *getByteStream() const + { return byteStream; } + + /** + * + */ + virtual void setByteStream(const LSOutputStream *val) + { byteStream = (LSOutputStream *) val; } + + /** + * + */ + virtual DOMString getSystemId() const + { return systemId; } + + /** + * + */ + virtual void setSystemId(const DOMString &val) + { systemId = val; } + + /** + * + */ + virtual DOMString getEncoding() const + { return encoding; } + + /** + * + */ + virtual void setEncoding(const DOMString &val) + { encoding = val; } + + + //################## + //# Non-API methods + //################## + + /** + * + */ + LSOutput() + { + characterStream = NULL; + byteStream = NULL; + systemId = ""; + encoding = ""; + } + + + /** + * + */ + LSOutput(const LSOutput &other) + { + characterStream = other.characterStream; + byteStream = other.byteStream; + systemId = other.systemId; + encoding = other.encoding; + } + + /** + * + */ + virtual ~LSOutput() + {} + +private: + + LSWriter *characterStream; + LSOutputStream *byteStream; + DOMString systemId; + DOMString encoding; + +}; + + +/*######################################################################### +## LSSerializer +#########################################################################*/ + +/** + * + */ +class LSSerializer +{ +public: + + /** + * + */ + virtual DOMConfiguration *getDomConfig() + { return NULL; } + + /** + * + */ + virtual DOMString getNewLine() + { return newLine; } + /** + * + */ + virtual void setNewLine(const DOMString &val) + { newLine = val; } + + /** + * + */ + virtual LSSerializerFilter *getFilter() + { return filter; } + + /** + * + */ + virtual void setFilter(const LSSerializerFilter *val) + { filter = (LSSerializerFilter *)val; } + + /** + * + */ + virtual bool write(const Node *nodeArg, + const LSOutput &destination) + throw (LSException) + { return false; } + + /** + * + */ + virtual bool writeToURI(const Node *nodeArg, + const DOMString &uri) + throw(LSException) + { return false; } + + /** + * + */ + virtual DOMString writeToString(const Node *nodeArg) + throw(dom::DOMException, LSException) + { + DOMString str; + return str; + } + + //################## + //# Non-API methods + //################## + + /** + * + */ + LSSerializer() + { + filter = NULL; + newLine = "\n"; + } + + /** + * + */ + LSSerializer(const LSSerializer &other) + { + filter = other.filter; + newLine = other.newLine; + } + + /** + * + */ + virtual ~LSSerializer() {} + +protected: + + LSSerializerFilter *filter; + DOMString newLine; + +}; + +/*######################################################################### +## LSProgressEvent +#########################################################################*/ + +/** + * + */ +class LSProgressEvent : virtual public events::Event +{ +public: + + /** + * + */ + virtual LSInput &getInput() + { + return input; + } + + /** + * + */ + virtual unsigned long getPosition() + { return position; } + + /** + * + */ + virtual unsigned long getTotalSize() + { return totalSize; } + + //################## + //# Non-API methods + //################## + + /** + * + */ + LSProgressEvent(const LSInput &inputArg, unsigned long positionArg, + unsigned long totalSizeArg) : input((LSInput &)inputArg) + { + position = positionArg; + totalSize = totalSizeArg; + } + + + /** + * + */ + LSProgressEvent(const LSProgressEvent &other) + : events::Event(other) , input(other.input) + { + position = other.position; + totalSize = other.totalSize; + } + + + /** + * + */ + virtual ~LSProgressEvent() {} + +protected: + + LSInput &input; + unsigned long position; + unsigned long totalSize; + +}; + +/*######################################################################### +## LSLoadEvent +#########################################################################*/ + +/** + * + */ +class LSLoadEvent : public events::Event +{ +public: + + /** + * + */ + virtual Document *getNewDocument() + { return newDocument; } + + /** + * + */ + virtual LSInput &getInput() + { return input; } + + //################## + //# Non-API methods + //################## + + /** + * + */ + LSLoadEvent(const LSInput &inputArg, const Document *docArg) + : input((LSInput &)inputArg) + { newDocument = (Document *)docArg; } + + /** + * + */ + LSLoadEvent(const LSLoadEvent &other) : events::Event(other) , input(other.input) + { + newDocument = other.newDocument; + } + + /** + * + */ + virtual ~LSLoadEvent() {} + +protected: + + Document *newDocument; + + LSInput &input; + + +}; + + + +/*######################################################################### +## LSSerializerFilter +#########################################################################*/ + +/** + * + */ +class LSSerializerFilter : virtual public traversal::NodeFilter +{ +public: + + /** + * + */ + virtual unsigned long getWhatToShow() =0; + + //################## + //# Non-API methods + //################## + + /** + * + */ + virtual ~LSSerializerFilter() {} +}; + + + + +/*######################################################################### +## DOMImplementationLS +#########################################################################*/ + +/** + * + */ +class DOMImplementationLS +{ +public: + + typedef enum + { + MODE_SYNCHRONOUS = 1, + MODE_ASYNCHRONOUS = 2 + } DOMImplementationLSMode; + + /** + * To use, for this and subclasses: + * LSParser &parser = myImplementation.createLSParser(mode, schemaType); + */ + virtual LSParser &createLSParser(unsigned short mode, + const DOMString &schemaType) + throw (dom::DOMException) =0; + + /** + * To use, for this and subclasses: + * LSSerializer &serializer = myImplementation.createLSSerializer(); + * + */ + virtual LSSerializer &createLSSerializer() =0; + + /** + * + */ + virtual LSInput createLSInput() =0; + + /** + * + */ + virtual LSOutput createLSOutput() =0; + + //################## + //# Non-API methods + //################## + + /** + * + */ + virtual ~DOMImplementationLS() {} +}; + + + + +} //namespace ls +} //namespace dom +} //namespace w3c +} //namespace org + + +#endif // __LS_H__ + +/*######################################################################### +## E N D O F F I L E +#########################################################################*/ + diff --git a/src/dom/ls.idl b/src/dom/ls.idl new file mode 100755 index 000000000..db53ab79c --- /dev/null +++ b/src/dom/ls.idl @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2004 World Wide Web Consortium, + * + * (Massachusetts Institute of Technology, European Research Consortium for + * Informatics and Mathematics, Keio University). All Rights Reserved. This + * work is distributed under the W3C(r) Software License [1] in the hope that + * it will be useful, but WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * [1] http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 + */ + +// File: http://www.w3.org/TR/2004/REC-DOM-Level-3-LS-20040407/ls.idl + +#ifndef _LS_IDL_ +#define _LS_IDL_ + +#include "dom.idl" +#include "events.idl" +#include "traversal.idl" + +#pragma prefix "dom.w3c.org" +module ls +{ + + typedef Object LSInputStream; + + typedef Object LSOutputStream; + + typedef Object LSReader; + + typedef Object LSWriter; + + typedef dom::DOMString DOMString; + typedef dom::DOMConfiguration DOMConfiguration; + typedef dom::Node Node; + typedef dom::Document Document; + typedef dom::Element Element; + + interface LSParser; + interface LSSerializer; + interface LSInput; + interface LSOutput; + interface LSParserFilter; + interface LSSerializerFilter; + + exception LSException { + unsigned short code; + }; + // LSExceptionCode + const unsigned short PARSE_ERR = 81; + const unsigned short SERIALIZE_ERR = 82; + + + interface DOMImplementationLS { + + // DOMImplementationLSMode + const unsigned short MODE_SYNCHRONOUS = 1; + const unsigned short MODE_ASYNCHRONOUS = 2; + + LSParser createLSParser(in unsigned short mode, + in DOMString schemaType) + raises(dom::DOMException); + LSSerializer createLSSerializer(); + LSInput createLSInput(); + LSOutput createLSOutput(); + }; + + interface LSParser { + readonly attribute DOMConfiguration domConfig; + attribute LSParserFilter filter; + readonly attribute boolean async; + readonly attribute boolean busy; + Document parse(in LSInput input) + raises(dom::DOMException, + LSException); + Document parseURI(in DOMString uri) + raises(dom::DOMException, + LSException); + + // ACTION_TYPES + const unsigned short ACTION_APPEND_AS_CHILDREN = 1; + const unsigned short ACTION_REPLACE_CHILDREN = 2; + const unsigned short ACTION_INSERT_BEFORE = 3; + const unsigned short ACTION_INSERT_AFTER = 4; + const unsigned short ACTION_REPLACE = 5; + + Node parseWithContext(in LSInput input, + in Node contextArg, + in unsigned short action) + raises(dom::DOMException, + LSException); + void abort(); + }; + + interface LSInput { + // Depending on the language binding in use, + // this attribute may not be available. + attribute LSReader characterStream; + attribute LSInputStream byteStream; + attribute DOMString stringData; + attribute DOMString systemId; + attribute DOMString publicId; + attribute DOMString baseURI; + attribute DOMString encoding; + attribute boolean certifiedText; + }; + + interface LSResourceResolver { + LSInput resolveResource(in DOMString type, + in DOMString namespaceURI, + in DOMString publicId, + in DOMString systemId, + in DOMString baseURI); + }; + + interface LSParserFilter { + + // Constants returned by startElement and acceptNode + const short FILTER_ACCEPT = 1; + const short FILTER_REJECT = 2; + const short FILTER_SKIP = 3; + const short FILTER_INTERRUPT = 4; + + unsigned short startElement(in Element elementArg); + unsigned short acceptNode(in Node nodeArg); + readonly attribute unsigned long whatToShow; + }; + + interface LSSerializer { + readonly attribute DOMConfiguration domConfig; + attribute DOMString newLine; + attribute LSSerializerFilter filter; + boolean write(in Node nodeArg, + in LSOutput destination) + raises(LSException); + boolean writeToURI(in Node nodeArg, + in DOMString uri) + raises(LSException); + DOMString writeToString(in Node nodeArg) + raises(dom::DOMException, + LSException); + }; + + interface LSOutput { + // Depending on the language binding in use, + // this attribute may not be available. + attribute LSWriter characterStream; + attribute LSOutputStream byteStream; + attribute DOMString systemId; + attribute DOMString encoding; + }; + + interface LSProgressEvent : events::Event { + readonly attribute LSInput input; + readonly attribute unsigned long position; + readonly attribute unsigned long totalSize; + }; + + interface LSLoadEvent : events::Event { + readonly attribute Document newDocument; + readonly attribute LSInput input; + }; + + interface LSSerializerFilter : traversal::NodeFilter { + readonly attribute unsigned long whatToShow; + }; +}; + +#endif // _LS_IDL_ + diff --git a/src/dom/lsimpl.cpp b/src/dom/lsimpl.cpp new file mode 100755 index 000000000..67c899f35 --- /dev/null +++ b/src/dom/lsimpl.cpp @@ -0,0 +1,437 @@ +/** + * Phoebe DOM Implementation. + * + * This is a C++ approximation of the W3C DOM model, which follows + * fairly closely the specifications in the various .idl files, copies of + * which are provided for reference. Most important is this one: + * + * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/idl-definitions.html + * + * Authors: + * Bob Jamison + * + * Copyright (C) 2005 Bob Jamison + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "lsimpl.h" + +#include + +namespace org +{ +namespace w3c +{ +namespace dom +{ +namespace ls +{ + + + +/*######################################################################### +## LSParserImpl +#########################################################################*/ + + +/** + * + */ +bool LSParserImpl::getBusy() +{ + return false; +} + +/** + * + */ +Document *LSParserImpl::parse(const LSInput &input) + throw(dom::DOMException, LSException) +{ + + //#### Check the various inputs of 'input' in order, according + //# to the L&S spec + LSReader *lsreader = input.getCharacterStream(); + if (lsreader) + { + DOMString buf; + while (true) + { + int ch = lsreader->get(); + if (ch < 0) + break; + buf.push_back(ch); + } + XmlReader reader; + Document *doc = reader.parse(buf); + return doc; + } + + LSInputStream *inputStream = input.getByteStream(); + if (inputStream) + { + DOMString buf; + while (true) + { + int ch = inputStream->get(); + if (ch < 0) + break; + buf.push_back(ch); + } + XmlReader reader; + Document *doc = reader.parse(buf); + return doc; + } + + DOMString stringData = input.getStringData(); + if (stringData.size() > 0) + { + XmlReader reader; + Document *doc = reader.parse(stringData); + return doc; + } + + DOMString systemId = input.getSystemId(); + if (systemId.size() > 0) + { + //lets not do this yet + return NULL; + } + + DOMString publicId = input.getPublicId(); + if (publicId.size() > 0) + { + //lets not do this yet + return NULL; + } + + return NULL; +} + + +/** + * + */ +Document *LSParserImpl::parseURI(const DOMString &uri) + throw(dom::DOMException, LSException) +{ + return NULL; +} + + /** + * + */ +Node *LSParserImpl::parseWithContext(const LSInput &input, + const Node *contextArg, + unsigned short action) + throw(dom::DOMException, LSException) +{ + return NULL; +} + + + +//################## +//# Non-API methods +//################## + + + + + + + + + + + +/*######################################################################### +## LSSerializerImpl +#########################################################################*/ + + +/** + * + */ +bool LSSerializerImpl::write( + const Node *nodeArg, + const LSOutput &destination) + throw (LSException) +{ + outbuf = ""; + indent = 0; + + writeNode(nodeArg); + + //## Check in order specified in the L&S specs + LSWriter *writer = destination.getCharacterStream(); + if (writer) + { + for (unsigned int i=0 ; iput(ch); + } + return true; + } + + LSOutputStream *outputStream = destination.getByteStream(); + if (outputStream) + { + for (unsigned int i=0 ; iput(ch); + } + return true; + } + + DOMString systemId = destination.getSystemId(); + if (systemId.size() > 0) + { + //DO SOMETHING + return true; + } + + return false; +} + +/** + * + */ +bool LSSerializerImpl::writeToURI(const Node *nodeArg, + const DOMString &uriArg) + throw(LSException) +{ + outbuf = ""; + indent = 0; + + writeNode(nodeArg); + + DOMString uri = uriArg; + char *fileName = (char *) uri.c_str(); //temporary hack + FILE *f = fopen(fileName, "rb"); + if (!f) + return false; + for (unsigned int i=0 ; i') + outbuf.append(">"); + else if (ch == '"') + outbuf.append("""); + else if (ch == '\'') + outbuf.append("'"); + else + outbuf.push_back(ch); + } +} + +/** + * + */ +void LSSerializerImpl::writeNode(const Node *nodeArg) +{ + Node *node = (Node *)nodeArg; + + int type = node->getNodeType(); + + switch (type) + { + + //############# + //# DOCUMENT + //############# + case Node::DOCUMENT_NODE: + { + Document *doc = dynamic_cast(node); + writeNode(doc->getDocumentElement()); + } + break; + + //############# + //# TEXT + //############# + case Node::TEXT_NODE: + { + poxml(node->getNodeValue()); + } + break; + + + //############# + //# CDATA + //############# + case Node::CDATA_SECTION_NODE: + { + pos("getNodeValue()); + pos("]]>"); + } + break; + + + //############# + //# ELEMENT + //############# + case Node::ELEMENT_NODE: + { + + indent+=2; + + NamedNodeMap attributes = node->getAttributes(); + int nrAttrs = attributes.getLength(); + + //### Start open tag + spaces(); + po("<"); + pos(node->getNodeName()); + //if (nrAttrs>0) + // pos(newLine); + + //### Attributes + for (int i=0 ; igetNodeName()); + po("=\""); + pos(attr->getNodeValue()); + po("\""); + //pos(newLine); + } + + //### Finish open tag + //if (nrAttrs>0) + // spaces(); + po(">"); + //pos(newLine); + + //### Contents + //spaces(); + pos(node->getNodeValue()); + + //### Children + for (Node *child = node->getFirstChild() ; + child ; + child=child->getNextSibling()) + { + writeNode(child); + } + + //### Close tag + //spaces(); + po("getNodeName()); + po(">"); + pos(newLine); + + indent-=2; + } + break; + + }//switch + +} + + + + + + + + + + +} //namespace ls +} //namespace dom +} //namespace w3c +} //namespace org + + + + + +/*######################################################################### +## E N D O F F I L E +#########################################################################*/ + diff --git a/src/dom/lsimpl.cpp.orig b/src/dom/lsimpl.cpp.orig new file mode 100755 index 000000000..4397a2517 --- /dev/null +++ b/src/dom/lsimpl.cpp.orig @@ -0,0 +1,671 @@ +/* + * Copyright (c) 2004 World Wide Web Consortium, + * + * (Massachusetts Institute of Technology, European Research Consortium for + * Informatics and Mathematics, Keio University). All Rights Reserved. This + * work is distributed under the W3C(r) Software License [1] in the hope that + * it will be useful, but WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * [1] http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 + */ + +// File: http://www.w3.org/TR/2004/REC-DOM-Level-3-LS-20040407/ls.idl + +#include "domimpl.h" +#include "eventsimpl.h" +#include "traversalimpl.h" +#include "lsimpl.h" + + + +namespace org { +namespace w3c { +namespace dom { +namespace ls { + + + + +/*######################################################################### +## DOMImplementationLSImpl +#########################################################################*/ + + +/** + * + */ +LSParser *DOMImplementationLSImpl::createLSParser(unsigned short mode, + const DOMString &schemaType) + throw (dom::DOMException) +{ + return NULL; +} + +/** + * + */ +LSSerializer *DOMImplementationLSImpl::createLSSerializer() +{ + return NULL; +} + +/** + * + */ +LSInput *DOMImplementationLSImpl::createLSInput() +{ + return NULL; +} + +/** + * + */ +LSOutput *DOMImplementationLSImpl::createLSOutput() +{ + return NULL; +} + +//################## +//# Non-API methods +//################## + +/** + * + */ +DOMImplementationLSImpl::~DOMImplementationLSImpl() +{ +} + +/*######################################################################### +## LSParserImpl +#########################################################################*/ + + +/** + * + */ +DOMConfiguration *LSParserImpl::getDomConfig() +{ + return NULL; +} + +/** + * + */ +LSParserFilter *LSParserImpl::getFilter() +{ + return NULL; +} + +/** + * + */ +void LSParserImpl::setFilter(const LSParserFilter *val) +{ +} + +/** + * + */ +bool LSParserImpl::getAsync() +{ + return false; +} + +/** + * + */ +bool LSParserImpl::getBusy() +{ + return false; +} + +/** + * + */ +Document *LSParserImpl::parse(const LSInput *input) + throw(dom::DOMException, LSException) +{ + return NULL; +} + + +/** + * + */ +Document *LSParserImpl::parseURI(const DOMString &uri) + throw(dom::DOMException, LSException) +{ + return NULL; +} + + /** + * + */ +Node *LSParserImpl::parseWithContext(const LSInput *input, + const Node *contextArg, + unsigned short action) + throw(dom::DOMException, LSException) +{ + return NULL; +} + +/** + * + */ +void LSParserImpl::abort() +{ +} + + + +//################## +//# Non-API methods +//################## + +/** + * + */ +LSParserImpl::~LSParserImpl() +{ +} + + +/*######################################################################### +## LSInputImpl +#########################################################################*/ + +/** + * + */ +LSReader *LSInputImpl::getCharacterStream() +{ + return NULL; +} + +/** + * + */ +void LSInputImpl::setCharacterStream(const LSReader *val) +{ +} + +/** + * + */ +LSInputStream *LSInputImpl::getByteStream() +{ + return NULL; +} + +/** + * + */ +void LSInputImpl::setByteStream(const LSInputStream *val) +{ +} + +/** + * + */ +DOMString LSInputImpl::getStringData() +{ + return DOMString(""); +} + +/** + * + */ +void LSInputImpl::setStringData(const DOMString &val) +{ +} + +/** + * + */ +DOMString LSInputImpl::getSystemId() +{ + return DOMString(""); +} + +/** + * + */ +void LSInputImpl::setSystemId(const DOMString &val) +{ +} + +/** + * + */ +DOMString LSInputImpl::getPublicId() +{ + return DOMString(""); +} + +/** + * + */ +void LSInputImpl::setPublicId(const DOMString &val) +{ +} + +/** + * + */ +DOMString LSInputImpl::getBaseURI() +{ + return DOMString(""); +} + +/** + * + */ +void LSInputImpl::setBaseURI(const DOMString &val) +{ +} + +/** + * + */ +DOMString LSInputImpl::getEncoding() +{ + return DOMString(""); +} + +/** + * + */ +void LSInputImpl::setEncoding(const DOMString &val) +{ +} + +/** + * + */ +bool LSInputImpl::getCertifiedText() +{ + return false; +} + +/** + * + */ +void LSInputImpl::setCertifiedText(bool val) +{ +} + +//################## +//# Non-API methods +//################## + +/** + * + */ +LSInputImpl::~LSInputImpl() +{ +} + + + + + + + +/*######################################################################### +## LSResourceResolverImpl +#########################################################################*/ + +/** + * + */ +LSInput *LSResourceResolverImpl::resolveResource(const DOMString &type, + const DOMString &namespaceURI, + const DOMString &publicId, + const DOMString *systemId, + const DOMString &baseURI) +{ +} + +//################## +//# Non-API methods +//################## + +/** + * + */ +LSResourceResolverImpl::~LSResourceResolverImpl() +{ +} + + + + +/*######################################################################### +## LSParserFilterImpl +#########################################################################*/ + + +/** + * + */ +unsigned short LSParserFilterImpl::startElement(const Element *elementArg) +{ + return 0; +} + +/** + * + */ +unsigned short LSParserFilterImpl::acceptNode(const Node *nodeArg) +{ + return 0; +} + +/** + * + */ +unsigned long LSParserFilterImpl::getWhatToShow() +{ + return 0L; +} + +//################## +//# Non-API methods +//################## + +/** + * + */ +LSParserFilterImpl::~LSParserFilterImpl() +{ +} + + + + +/*######################################################################### +## LSSerializerImpl +#########################################################################*/ + + +/** + * + */ +DOMConfiguration *LSSerializerImpl::getDomConfig() +{ + return NULL; +} + +/** + * + */ +DOMString LSSerializerImpl::getNewLine() +{ + return DOMString(""); +} + +/** + * + */ +void LSSerializerImpl::setNewLine(const DOMString &val) +{ +} + +/** + * + */ +LSSerializerFilter *LSSerializerImpl::getFilter() +{ + return NULL; +} + +/** + * + */ +void LSSerializerImpl::setFilter(const LSSerializerFilter *val) +{ +} + +/** + * + */ +bool LSSerializerImpl::write(const Node *nodeArg, + const LSOutput *destination) + throw (LSException) +{ + return false; +} + +/** + * + */ +bool LSSerializerImpl::writeToURI(const Node *nodeArg, + const DOMString &uri) + throw(LSException) +{ + return false; +} + +/** + * + */ +DOMString LSSerializerImpl::writeToString(const Node *nodeArg) + throw(dom::DOMException, LSException) +{ + return DOMString(""); +} + +//################## +//# Non-API methods +//################## + +/** + * + */ +LSSerializerImpl::~LSSerializerImpl() +{ +} + + + + +/*######################################################################### +## LSOutputImpl +#########################################################################*/ + +/** + * + */ +LSWriter *LSOutputImpl::getCharacterStream() +{ + return NULL; +} + +/** + * + */ +void LSOutputImpl::setCharacterStream(const LSWriter *val) +{ +} + +/** + * + */ +LSOutputStream *LSOutputImpl::getByteStream() +{ + return NULL; +} + +/** + * + */ +void LSOutputImpl::setByteStream(const LSOutputStream *val) +{ +} + +/** + * + */ +DOMString LSOutputImpl::getSystemId() +{ + return DOMString(""); +} + +/** + * + */ +void LSOutputImpl::setSystemId(const DOMString &val) +{ +} + +/** + * + */ +DOMString LSOutputImpl::getEncoding() +{ + return DOMString(""); +} + +/** + * + */ +void LSOutputImpl::setEncoding(const DOMString &val) +{ +} + + +//################## +//# Non-API methods +//################## + +/** + * + */ +LSOutputImpl::~LSOutputImpl() +{ +} + + + +/*######################################################################### +## LSProgressEventImpl +#########################################################################*/ + +/** + * + */ +LSInput *LSProgressEventImpl::getInput() +{ + return NULL; +} + +/** + * + */ +unsigned long LSProgressEventImpl::getPosition() +{ + return 0L; +} + +/** + * + */ +unsigned long LSProgressEventImpl::getTotalSize() +{ + return 0L; +} + +//################## +//# Non-API methods +//################## + +/** + * + */ +LSProgressEventImpl::~LSProgressEventImpl() +{ +} + + + +/*######################################################################### +## LSLoadEventImpl +#########################################################################*/ + +/** + * + */ +Document *LSLoadEventImpl::getNewDocument() +{ + return NULL; +} + +/** + * + */ +LSInput *LSLoadEventImpl::getInput() +{ + return NULL; +} + +//################## +//# Non-API methods +//################## + +/** + * + */ +LSLoadEventImpl::~LSLoadEventImpl() +{ +} + + + + + +/*######################################################################### +## LSSerializerFilterImpl +#########################################################################*/ + + +/** + * + */ +unsigned long LSSerializerFilterImpl::getWhatToShow() +{ + return 0L; +} + +//################## +//# Non-API methods +//################## + +/** + * + */ +LSSerializerFilterImpl::~LSSerializerFilterImpl() +{ +} + + + + + + + + +} //namespace ls +} //namespace dom +} //namespace w3c +} //namespace org + + + + + +/*######################################################################### +## E N D O F F I L E +#########################################################################*/ + diff --git a/src/dom/lsimpl.h b/src/dom/lsimpl.h new file mode 100755 index 000000000..ee6360143 --- /dev/null +++ b/src/dom/lsimpl.h @@ -0,0 +1,376 @@ +#ifndef __LSIMPL_H__ +#define __LSIMPL_H__ +/** + * Phoebe DOM Implementation. + * + * This is a C++ approximation of the W3C DOM model, which follows + * fairly closely the specifications in the various .idl files, copies of + * which are provided for reference. Most important is this one: + * + * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/idl-definitions.html + * + * Authors: + * Bob Jamison + * + * Copyright (C) 2005 Bob Jamison + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "domimpl.h" +#include "events.h" +#include "traversal.h" +#include "ls.h" + + +#include "xmlreader.h" + +namespace org +{ +namespace w3c +{ +namespace dom +{ +namespace ls +{ + + +/*######################################################################### +## LSParserImpl +#########################################################################*/ + +/** + * + */ +class LSParserImpl : virtual public LSParser +{ +public: + + typedef enum + { + PARSE_AS_DATA = 0, + PARSE_AS_DOCUMENT = 1 + } ParsingModes; + + /** + * + */ + virtual bool getBusy(); + + /** + * + */ + virtual Document *parse(const LSInput &input) + throw(dom::DOMException, LSException); + + + /** + * + */ + virtual Document *parseURI(const DOMString &uri) + throw(dom::DOMException, LSException); + + /** + * + */ + virtual Node *parseWithContext(const LSInput &input, + const Node *contextArg, + unsigned short action) + throw(dom::DOMException, LSException); + + + //################## + //# Non-API methods + //################## + + /** + * + */ + LSParserImpl() + {} + + /** + * + */ + LSParserImpl(const LSParserImpl &other) : LSParser(other) + {} + + /** + * + */ + virtual ~LSParserImpl() + {} + + + + //################## + //# Internals + //################## + + +protected: + + XmlReader reader; + LSParserFilter *filter; + +}; + + + + +/*######################################################################### +## LSParserFilterImpl +#########################################################################*/ + +/** + * + */ +class LSParserFilterImpl : virtual public LSParserFilter +{ +public: + + /** + * + */ + virtual unsigned short startElement(const Element *elementArg) + { return 0; } + + /** + * + */ + virtual unsigned short acceptNode(const Node *nodeArg) + { return 0; } + + /** + * + */ + virtual unsigned long getWhatToShow() + { return 0; } + + //################## + //# Non-API methods + //################## + + /** + * + */ + virtual ~LSParserFilterImpl() + {} + + + +}; + +/*######################################################################### +## LSSerializerImpl +#########################################################################*/ + +/** + * + */ +class LSSerializerImpl : virtual public LSSerializer +{ +public: + + + /** + * + */ + virtual bool write(const Node *nodeArg, + const LSOutput &destination) + throw (LSException); + + /** + * + */ + virtual bool writeToURI(const Node *nodeArg, + const DOMString &uri) + throw(LSException); + + /** + * + */ + virtual DOMString writeToString(const Node *nodeArg) + throw(dom::DOMException, LSException); + + //################## + //# Non-API methods + //################## + + /** + * + */ + LSSerializerImpl() + { + indent = 0; + } + + /** + * + */ + virtual ~LSSerializerImpl() + {} + + + +protected: + + /** + * + */ + void writeNode(const Node *nodeArg); + +private: + + void spaces(); + + void po(char *fmt, ...); + + void pos(const DOMString &str); + + void poxml(const DOMString &str); + + DOMString outbuf; + + int indent; + + DOMConfiguration *domConfig; + + LSSerializerFilter *filter; + + + +}; + + + + +/*######################################################################### +## LSSerializerFilterImpl +#########################################################################*/ + +/** + * + */ +class LSSerializerFilterImpl : virtual public LSSerializerFilter +{ +public: + + /** + * + */ + virtual unsigned long getWhatToShow() + { return 0; } + + //################## + //# Non-API methods + //################## + + /** + * + */ + virtual ~LSSerializerFilterImpl() + {} +}; + + + +/*######################################################################### +## DOMImplementationLSImpl +#########################################################################*/ + +/** + * + */ +class DOMImplementationLSImpl : virtual public DOMImplementationLS +{ +public: + + /** + * + */ + virtual LSParser &createLSParser(unsigned short mode, + const DOMString &schemaType) + throw (dom::DOMException) + { + LSParserImpl newParser; + parser = newParser; + return parser; + } + + + /** + * + */ + virtual LSSerializer &createLSSerializer() + { + LSSerializerImpl newSerializer; + serializer = newSerializer; + return serializer; + } + + + /** + * + */ + virtual LSInput createLSInput() + { + LSInput input; + return input; + } + + /** + * + */ + virtual LSOutput createLSOutput() + { + LSOutput output; + return output; + } + + //################## + //# Non-API methods + //################## + + /** + * + */ + virtual ~DOMImplementationLSImpl() {} + +protected: + + LSParserImpl parser; + LSSerializerImpl serializer; +}; + + + + + + +} //namespace ls +} //namespace dom +} //namespace w3c +} //namespace org + + + + +#endif /* __LSIMPL_H__ */ + +/*######################################################################### +## E N D O F F I L E +#########################################################################*/ + diff --git a/src/dom/makefile.in b/src/dom/makefile.in new file mode 100644 index 000000000..1e0b42977 --- /dev/null +++ b/src/dom/makefile.in @@ -0,0 +1,17 @@ +# Convenience stub makefile to call the real Makefile. + +@SET_MAKE@ + +# Explicit so that it's the default rule. +all: + cd .. && $(MAKE) dom/all + +clean %.a %.o: + cd .. && $(MAKE) dom/$@ + +.PHONY: all clean + +OBJEXT = @OBJEXT@ + +.SUFFIXES: +.SUFFIXES: .a .$(OBJEXT) diff --git a/src/dom/meyerweb.css b/src/dom/meyerweb.css new file mode 100755 index 000000000..9cce6b65e --- /dev/null +++ b/src/dom/meyerweb.css @@ -0,0 +1,181 @@ +@import url(skel.css); + +/* generics */ + +* {font-size: 100%; padding: 0; margin: 0;} +body {font: 0.84em/1.333 Arial, sans-serif; margin: 0; padding: 0; + color: #202020; background: #FFF; + min-width: 40em; margin: 0 auto;} +a:link {color: #339;} +a:visited {color: #848;} +a img {border: none;} +h1 {font-size: 2em; margin: 2em 0 0.5em; padding: 0.25em 0;} +h2 {font-size: 1.5em; margin: 2em 0 0.33em; padding: 0.25em 0;} +h3 {font-size: 1.33em; margin: 2em 0 0.25em; padding: 0.125em 0;} +h4 {font-size: 1.1em; margin: 0.5em 0 0;} +h5 {font-size: 1em; margin: 0.5em 0 0;} +h6 {font-size: 0.85em; margin: 0.5em 0 0;} +p {margin: 0.33em 0 1em 0;} +ul, ol {margin: 1em 0; padding-left: 2.5em;} +dt {margin: 0.5em 0 0;} +dd {margin: 0.25em 0 0.5em 2.5em;} +pre, code, tt {font: 110% "Andale Mono", Courier, "Courier New", monospace;} +small {font-size: 85%;} +big {font-size: 115%;} +sup {font-size: smaller; vertical-align: 0.5em; line-height: 1px;} +img.pic {float: right; position: relative; margin: 0.25em 0 0.66em 1.5em;} +img.border {border: 3px double;} +img.standalone {display: block; margin: 0.5em auto; width: auto; max-width: 100%;} +p.standalone {text-align: center;} +p.standalone img {display: inline;} +.warning {background: #FF8; color: red; border: 2px solid; padding: 1em;} +.highlight {background: #B4D5FF; font-weight: bold;} + +table.chart {margin: 1em auto;} +table.chart caption {font-weight: bold; font-style: italic; font-size: 90%;} +table.chart th {text-align: left;} +table.chart thead th {border-bottom: 1px solid #CCC;} +table.chart th, table.chart td {border-bottom: 1px dotted #DDD;} +table.chart tbody th {padding-right: 1em;} + +/* masthead */ + +#sitemast {padding: 0; margin: 0; overflow: hidden; border-bottom: 1px solid #000; + height: 128px; width: 100%; position: relative; z-index: 1;} +#sitemast h1 {font-size: 2em; line-height: 1em; letter-spacing: 0.13em; + padding: 0; margin: 0; + position: absolute; left: 0; top: 100px; + /* hide-from-IE5/Mac hack \*/ + top: auto; bottom: 0; + /* end hack */} +#sitemast h1 a {padding: 0 0.25em;} +#sitemast h1 a, .panel a {text-decoration: none;} + +/* main content */ + +#main {margin: 2.25em 20em 0 12em; padding: 3.5em 0; + min-height: 30em;} +#main h2 {border-bottom: 1px solid #888; margin: 0; padding: 0; + font-size: 1.75em; line-height: 1;} +#main p.contact {margin: 0 1em; text-align: right; font-size: 90%;} + +#main p {line-height: 1.4;} +#main li {line-height: 1.33; margin-bottom: 0.33em;} +#main .compact li {line-height: normal; margin-bottom: 0;} +#main ul li {list-style: square;} +#main ol li {list-style: decimal;} + +#main blockquote {font-style: normal; margin: 1em 1em 1em 2em;} +#main blockquote em {font-style: italic; font-weight: inherit;} +#main blockquote p {margin: 0.33em 2.5% 0.33em 0 !important; + line-height: 1.2; text-indent: 2em;} +#main blockquote.book p {margin: 0 2.5% 0 0 !important;} +#main blockquote.lyric {font-style: italic; white-space: pre; + border: none; margin-left: 1em;} +#main blockquote.lyric p {text-indent: 0;} +.quoteattrib {margin: -0.75em 3em 0.66em; font-size: 87.5%;} +.quoteattrib cite {font-style: italic;} + +/* search bits */ + +#search {position: absolute; top: 129px; right: 0; + z-index: 10; + text-align: right; padding: 0.25em 0 1.25em 5px; + background: url(pix/logoogle2.gif) no-repeat 0% 100%;} +#search h4 {display: none;} +#search form {margin: 0; padding: 2px 1em 0;} +#search input[type="text"] {width: 14em; border: 2px inset #999;} +#search small {display: block; margin: 0 1.25em; padding: 0; + text-align: right; line-height: 1;} +#search small a {background: #FFF; color: #668; font-style: italic;} + +/* navbar */ + +#navigate {position: absolute; top: 129px; left: 0; right: 0; + padding: 0.25em 0 0.25em 1em; + z-index: 1; overflow: hidden; + height: auto; width: 85%; line-height: 2;} +#navigate h4 {display: none;} +#navigate ul, #navigate li {margin: 0; padding: 0;} +#navigate ul {padding-left: 0.5em;} + +#navlinks {float: left; width: 100%;} +#navlinks a {text-decoration: none;} +#navlinks li {float: left; list-style: none; margin-left: 1px;} +#navlinks li a {padding: 0.25em 1em; margin-right: 0.125em; + border-top: 0.75em solid #AAC; border-bottom: 1px dotted #FFF; + font-weight: bold; color: #668;} +#navlinks li ul {display: none; border: none;} +#navlinks li li a {font-weight: normal;} +#navlinks a:hover {border-top-color: #88A;} +#navlinks #otherLink {margin-left: 1.75em;} + +.arch #archLink a, +.css #cssLink a, +.tools #toolsLink a, +.write #writeLink a, +.speak #speakLink a, +.other #otherLink a +{border-color: #226 #FFF #FFF; background: #CCE; color: #226; font-style: italic;} + +/* 'sidebar' */ + +#extra {position: absolute; top: 129px; right: 0; z-index: 100; width: 18em; + font-size: 1em; line-height: 1.2; + padding: 1.75em 0 0; margin: 3em 0 0; + color: #5A5A5F;} +#extra a:link {color: #66A;} +#extra a:visited {color: #858;} + +#extra .panel {margin: 1em 0 0; padding: 1em 1em 0 3em; border: 1px dotted #FFF;} +#extra .panel h4, #extra .panel h5 {margin: 0 0 0.25em; padding: 0 0.5em 0 0; + font-size: 90%; line-height: 1; + border-bottom: 1px solid #AAA;} +#extra .panel ul {list-style: none; margin: 0 1em 0 0; padding: 0; font-size: 90%;} +#extra .panel li {margin-left: 1em; text-indent: -1em;} +#extra .panel .more {float: right; margin: -1.5em 1px 0 0.5em; + font-style: italic; text-align: right; font-size: smaller;} +#extra .panel .more a {padding-left: 15px; background: url(pix/morearr.gif) 0 66% no-repeat;} + +#extra #blogroll h5 {padding-right: 95px;} +#extra #blogroll ul {margin: 0.5em 1em 0 0;} +#extra #xfn-btn {float: right; margin: -20px 1px 0 5px;} + +#extra #excuse {text-align: center; padding: 0 0.25em 0.66em; margin: 2em 1em -2em 3em; + border: 1px solid #CCC;} +#extra #excuse h4 {display: inline; position: relative; top: -0.6em; + border: 0; padding: 0 0.25em; margin: 0; + background: #FFF; color: #666; + text-transform: capitalize; font-size: 1em; font-weight: normal;} +#extra #excuse p {margin: 0; padding: 0; color: #444;} + +#extra #extras {padding: 1em 0.5em 1em; margin: 2em 1em 0 3em; width: 13em; + color: #666; border: 1px solid #AAA; border-width: 1px 0;} +#extra #extras h4 {display: none;} +#extra #extras ul {margin: 0; text-align: center; list-style: none;} +#extra #extras li {margin-left: 0.25em; display: inline;} +#extra #extras a {margin-right: 0.25em;} + +/* miscellaneous */ + +#footer {margin: 3em 18em 0 12em; padding: 0.5em 0 3.5em; + border-top: 1px solid gray; + text-align: center; + color: gray; background: #FFF;} +#footer a {color: #558;} +#footer a:visited {color: #858;} +#footer p {line-height: 1; margin: 0; padding: 0.5em 0.25em 0; font-size: 0.85em; } + +#reading img {border: 1px solid silver;} +#extra #reading img {margin: 0.5em;} + +.book #main img.cover {float: right; margin: 1em 0 1em 2em; + border: 1px solid; border-color: #AAA #444 #444 #AAA;} + +/* Hack-o-rama! */ + +* html #navigate {padding-top: 0;} + +/*\*//*/ +body #search {width: 20em;} +/**/ diff --git a/src/dom/mingwenv.bat b/src/dom/mingwenv.bat new file mode 100755 index 000000000..48e8bf096 --- /dev/null +++ b/src/dom/mingwenv.bat @@ -0,0 +1,2 @@ +set PATH=c:\mingw\bin;%PATH% +set RM=del diff --git a/src/dom/phoebedom.h b/src/dom/phoebedom.h new file mode 100755 index 000000000..4f8143843 --- /dev/null +++ b/src/dom/phoebedom.h @@ -0,0 +1,86 @@ +#ifndef __PHOBEDOM_H__ +#define __PHOBEDOM_H__ +/** + * Phoebe DOM Implementation. + * + * This is a C++ approximation of the W3C DOM model, which follows + * fairly closely the specifications in the various .idl files, copies of + * which are provided for reference. Most important is this one: + * + * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/idl-definitions.html + * + * Authors: + * Bob Jamison + * + * Copyright (C) 2005 Bob Jamison + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +#include "domimpl.h" +#include "lsimpl.h" +#include "svglsimpl.h" + +namespace phoebe +{ + +class PhoebeDOMImplementation : public org::w3c::dom::ls::DOMImplementationLSImpl +{ + +public: + + /** + * + */ + PhoebeDOMImplementation() + {} + + org::w3c::dom::ls::LSParser createLSParser(unsigned short mode, + const org::w3c::dom::DOMString &schemaType) + throw (org::w3c::dom::DOMException) + { + if (schemaType == "svg" || schemaType == "SVG") + { + org::w3c::dom::ls::SVGLSParserImpl parser; + return parser; + } + else + { + org::w3c::dom::ls::LSParser parser; + return parser; + } + } + + + /** + * + */ + virtual ~PhoebeDOMImplementation() + {} + +private: + + + +}; + + + +} // namespace phoebe + + +#endif /* __PHOBEDOM_H__ */ + diff --git a/src/dom/prop-css.cpp b/src/dom/prop-css.cpp new file mode 100755 index 000000000..59da4b54f --- /dev/null +++ b/src/dom/prop-css.cpp @@ -0,0 +1,1161 @@ +/** + * Phoebe DOM Implementation. + * + * This is a C++ approximation of the W3C DOM model, which follows + * fairly closely the specifications in the various .idl files, copies of + * which are provided for reference. Most important is this one: + * + * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/idl-definitions.html + * + * Authors: + * Bob Jamison + * + * Copyright (C) 2005 Bob Jamison + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include + + +struct CssProp_def +{ + char *name; + char *values; + char *defaultValue; + char *appliesTo; + bool inherited; + char *percentages; + char *mediaGroups; +}; + +typedef struct CssProp_def CssProp; + +static CssProp cssProps[] = +{ + +{ +"azimuth", +" | [[ left-side | far-left | left | center-left | center | center-right | right | far-right | right-side ] || behind ] | leftwards | rightwards | inherit", +"center", +"", +true, +"", +"aural" +}, + + +{ +"background-attachment", +"scroll | fixed | inherit", +"scroll", +"", +false, +"", +"visual" +}, + + +{ +"background-color", +" | transparent | inherit", +"transparent", +"", +false, +"", +"visual" +}, + + +{ +"background-image", +" | none | inherit", +"none", +"", +false, +"", +"visual" +}, + + +{ +"background-position", +"[ [ | | left | center | right ] [ | | top | center | bottom ]? ] | [ [ left | center | right ] || [ top | center | bottom ] ] | inherit", +"0% 0%", +"", +false, +"refer to the size of the box itself", +"visual" +}, + + +{ +"background-repeat", +"repeat | repeat-x | repeat-y | no-repeat | inherit", +"repeat", +"", +false, +"", +"visual" +}, + + +{ +"background", +"['background-color' || 'background-image' || 'background-repeat' || 'background-attachment' || 'background-position'] | inherit", +"see individual properties", +"", +false, +"allowed on 'background-position", +"visual" +}, + + +{ +"border-collapse", +"collapse | separate | inherit", +"separate", +"table' and 'inline-table' elements", +true, +"", +"visual" +}, + + +{ +"border-color", +"[ | transparent ]{1,4} | inherit", +"see individual properties", +"", +false, +"", +"visual" +}, + + +{ +"border-spacing", +" ? | inherit", +"0", +"table' and 'inline-table' elements", +true, +"", +"visual" +}, + + +{ +"border-style", +"{1,4} | inherit", +"see individual properties", +"", +false, +"", +"visual" +}, + + +{ +"border-top' 'border-right' 'border-bottom' 'border-left", +"[ || || 'border-top-color' ] | inherit", +"see individual properties", +"", +false, +"", +"visual" +}, + + +{ +"border-top-color' 'border-right-color' 'border-bottom-color' 'border-left-color", +" | transparent | inherit", +"the value of the 'color' property", +"", +false, +"", +"visual" +}, + + +{ +"border-top-style' 'border-right-style' 'border-bottom-style' 'border-left-style", +" | inherit", +"none", +"", +false, +"", +"visual" +}, + + +{ +"border-top-width' 'border-right-width' 'border-bottom-width' 'border-left-width", +" | inherit", +"medium", +"", +false, +"", +"visual" +}, + + +{ +"border-width", +"{1,4} | inherit", +"see individual properties", +"", +false, +"", +"visual" +}, + + +{ +"border", +"[ || || 'border-top-color' ] | inherit", +"see individual properties", +"", +false, +"", +"visual" +}, + + +{ +"bottom", +" | | auto | inherit", +"auto", +"positioned elements", +false, +"refer to height of containing block", +"visual" +}, + + +{ +"caption-side", +"top | bottom | inherit", +"top", +"table-caption' elements", +true, +"", +"visual" +}, + + +{ +"clear", +"none | left | right | both | inherit", +"none", +"block-level elements", +false, +"", +"visual" +}, + + +{ +"clip", +" | auto | inherit", +"auto", +"absolutely positioned elements", +false, +"", +"visual" +}, + + +{ +"color", +" | inherit", +"depends on user agent", +"", +true, +"", +"visual" +}, + + +{ +"content", +"normal | [ | | | attr() | open-quote | close-quote | no-open-quote | no-close-quote ]+ | inherit", +"normal", +":before and :after pseudo-elements", +false, +"", +"all " +}, + + +{ +"counter-increment", +"[ ? ]+ | none | inherit", +"none", +"", +false, +"", +"all " +}, + + +{ +"counter-reset", +"[ ? ]+ | none | inherit", +"none", +"", +false, +"", +"all " +}, + + +{ +"cue-after", +" | none | inherit", +"none", +"", +false, +"", +"aural" +}, + + +{ +"cue-before", +" | none | inherit", +"none", +"", +false, +"", +"aural" +}, + + +{ +"cue", +"[ 'cue-before' || 'cue-after' ] | inherit", +"see individual properties", +"", +false, +"", +"aural" +}, + + +{ +"cursor", +"[ [ ,]* [ auto | crosshair | default | pointer | move | e-resize | ne-resize | nw-resize | n-resize | se-resize | sw-resize | s-resize | w-resize | text | wait | help | progress ] ] | inherit", +"auto", +"", +true, +"", +"visual, interactive " +}, + + +{ +"direction", +"ltr | rtl | inherit", +"ltr", +"all elements, but see prose", +true, +"", +"visual" +}, + + +{ +"display", +"inline | block | list-item | run-in | inline-block | table | inline-table | table-row-group | table-header-group | table-footer-group | table-row | table-column-group | table-column | table-cell | table-caption | none | inherit", +"inline", +"", +false, +"", +"all " +}, + + +{ +"elevation", +" | below | level | above | higher | lower | inherit", +"level", +"", +true, +"", +"aural" +}, + + +{ +"empty-cells", +"show | hide | inherit", +"show", +"table-cell' elements", +true, +"", +"visual" +}, + + +{ +"float", +"left | right | none | inherit", +"none", +"all, but see 9.7", +false, +"", +"visual" +}, + + +{ +"font-family", +"[[ | ] [, | ]* ] | inherit", +"depends on user agent", +"", +true, +"", +"visual" +}, + + +{ +"font-size", +" | | | | inherit", +"medium", +"", +true, +"refer to parent element's font size", +"visual" +}, + + +{ +"font-style", +"normal | italic | oblique | inherit", +"normal", +"", +true, +"", +"visual" +}, + + +{ +"font-variant", +"normal | small-caps | inherit", +"normal", +"", +true, +"", +"visual" +}, + + +{ +"font-weight", +"normal | bold | bolder | lighter | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | inherit", +"normal", +"", +true, +"", +"visual" +}, + + +{ +"font", +"[ [ 'font-style' || 'font-variant' || 'font-weight' ]? 'font-size' [ / 'line-height' ]? 'font-family' ] | caption | icon | menu | message-box | small-caption | status-bar | inherit", +"see individual properties", +"", +true, +"see individual properties", +"visual" +}, + + +{ +"height", +" | | auto | inherit", +"auto", +"all elements but non-replaced inline elements, table columns, and column groups", +false, +"see prose", +"visual" +}, + + +{ +"left", +" | | auto | inherit", +"auto", +"positioned elements", +false, +"refer to width of containing block", +"visual" +}, + + +{ +"letter-spacing", +"normal | | inherit", +"normal", +"", +true, +"", +"visual" +}, + + +{ +"line-height", +"normal | | | | inherit", +"normal", +"", +true, +"refer to the font size of the element itself", +"visual" +}, + + +{ +"list-style-image", +" | none | inherit", +"none", +"elements with 'display: list-item", +true, +"", +"visual" +}, + + +{ +"list-style-position", +"inside | outside | inherit", +"outside", +"elements with 'display: list-item", +true, +"", +"visual" +}, + + +{ +"list-style-type", +"disc | circle | square | decimal | decimal-leading-zero | lower-roman | upper-roman | lower-greek | lower-latin | upper-latin | armenian | georgian | none | inherit", +"disc", +"elements with 'display: list-item", +true, +"", +"visual" +}, + + +{ +"list-style", +"[ 'list-style-type' || 'list-style-position' || 'list-style-image' ] | inherit", +"see individual properties", +"elements with 'display: list-item", +true, +"", +"visual" +}, + + +{ +"margin-right' 'margin-left", +" | inherit", +"0", +"all elements except elements with table display types other than table and inline-table", +false, +"refer to width of containing block", +"visual" +}, + + +{ +"margin-top' 'margin-bottom", +" | inherit", +"0", +"all elements except elements with table display types other than table and inline-table", +false, +"refer to width of containing block", +"visual" +}, + + +{ +"margin", +"{1,4} | inherit", +"see individual properties", +"all elements except elements with table display types other than table and inline-table", +false, +"refer to width of containing block", +"visual" +}, + + +{ +"max-height", +" | | none | inherit", +"none", +"all elements except non-replaced inline elements and table elements", +false, +"see prose", +"visual" +}, + + +{ +"max-width", +" | | none | inherit", +"none", +"all elements except non-replaced inline elements and table elements", +false, +"refer to width of containing block", +"visual" +}, + + +{ +"min-height", +" | | inherit", +"0", +"all elements except non-replaced inline elements and table elements", +false, +"see prose", +"visual" +}, + + +{ +"min-width", +" | | inherit", +"0", +"all elements except non-replaced inline elements and table elements", +false, +"refer to width of containing block", +"visual" +}, + + +{ +"orphans", +" | inherit", +"2", +"block-level elements", +true, +"", +"visual, paged " +}, + + +{ +"outline-color", +" | invert | inherit", +"invert", +"", +false, +"", +"visual, interactive " +}, + + +{ +"outline-style", +" | inherit", +"none", +"", +false, +"", +"visual, interactive " +}, + + +{ +"outline-width", +" | inherit", +"medium", +"", +false, +"", +"visual, interactive " +}, + + +{ +"outline", +"[ 'outline-color' || 'outline-style' || 'outline-width' ] | inherit", +"see individual properties", +"", +false, +"", +"visual, interactive " +}, + + +{ +"overflow", +"visible | hidden | scroll | auto | inherit", +"visible", +"block-level and replaced elements, table cells, inline blocks", +false, +"", +"visual" +}, + + +{ +"padding-top' 'padding-right' 'padding-bottom' 'padding-left", +" | inherit", +"0", +"all elements except elements with table display types other than table, inline-table, and table-cell", +false, +"refer to width of containing block", +"visual" +}, + + +{ +"padding", +"{1,4} | inherit", +"see individual properties", +"all elements except elements with table display types other than table, inline-table, and table-cell", +false, +"refer to width of containing block", +"visual" +}, + + +{ +"page-break-after", +"auto | always | avoid | left | right | inherit", +"auto", +"block-level elements", +false, +"", +"visual, paged " +}, + + +{ +"page-break-before", +"auto | always | avoid | left | right | inherit", +"auto", +"block-level elements", +false, +"", +"visual, paged " +}, + + +{ +"page-break-inside", +"avoid | auto | inherit", +"auto", +"block-level elements", +true, +"", +"visual, paged " +}, + + +{ +"pause-after", +"> so that code generation can emit a left-associative branch + * around when A is false). Nodes are labeled by token type, with a + * JSOp secondary label when needed: + * + * Label Variant Members + * ----- ------- ------- + * + * TOK_FUNCTION func pn_funAtom: atom holding function object containing + * arg and var properties. We create the function + * object at parse (not emit) time to specialize arg + * and var bytecodes early. + * pn_body: TOK_LC node for function body statements + * pn_flags: TCF_FUN_* flags (see jsemit.h) collected + * while parsing the function's body + * pn_tryCount: of try statements in function + * + * + * TOK_LC list pn_head: list of pn_count statements + * TOK_EXPORT list pn_head: list of pn_count TOK_NAMEs or one TOK_STAR + * (which is not a multiply node) + * TOK_IMPORT list pn_head: list of pn_count sub-trees of the form + * a.b.*, a[b].*, a.*, a.b, or a[b] -- but never a. + * Each member is expressed with TOK_DOT or TOK_LB. + * Each sub-tree's root node has a pn_op in the set + * JSOP_IMPORT{ALL,PROP,ELEM} + * TOK_IF ternary pn_kid1: cond, pn_kid2: then, pn_kid3: else or null + * TOK_SWITCH binary pn_left: discriminant + * pn_right: list of TOK_CASE nodes, with at most one + * TOK_DEFAULT node + * TOK_CASE, binary pn_left: case expr or null if TOK_DEFAULT + * TOK_DEFAULT pn_right: TOK_LC node for this case's statements + * TOK_WHILE binary pn_left: cond, pn_right: body + * TOK_DO binary pn_left: body, pn_right: cond + * TOK_FOR binary pn_left: either + * for/in loop: a binary TOK_IN node with + * pn_left: TOK_VAR or TOK_NAME to left of 'in' + * pn_right: object expr to right of 'in' + * for(;;) loop: a ternary TOK_RESERVED node with + * pn_kid1: init expr before first ';' + * pn_kid2: cond expr before second ';' + * pn_kid3: update expr after second ';' + * any kid may be null + * pn_right: body + * TOK_THROW unary pn_op: JSOP_THROW, pn_kid: exception + * TOK_TRY ternary pn_kid1: try block + * pn_kid2: catch blocks or null + * pn_kid3: finally block or null + * TOK_CATCH ternary pn_kid1: PN_NAME node for catch var (with pn_expr + * null or the catch guard expression) + * pn_kid2: more catch blocks or null + * pn_kid3: catch block statements + * TOK_BREAK name pn_atom: label or null + * TOK_CONTINUE name pn_atom: label or null + * TOK_WITH binary pn_left: head expr, pn_right: body + * TOK_VAR list pn_head: list of pn_count TOK_NAME nodes + * each name node has + * pn_atom: variable name + * pn_expr: initializer or null + * TOK_RETURN unary pn_kid: return expr or null + * TOK_SEMI unary pn_kid: expr or null statement + * TOK_COLON name pn_atom: label, pn_expr: labeled statement + * + * + * All left-associated binary trees of the same type are optimized into lists + * to avoid recursion when processing expression chains. + * TOK_COMMA list pn_head: list of pn_count comma-separated exprs + * TOK_ASSIGN binary pn_left: lvalue, pn_right: rvalue + * pn_op: JSOP_ADD for +=, etc. + * TOK_HOOK ternary pn_kid1: cond, pn_kid2: then, pn_kid3: else + * TOK_OR binary pn_left: first in || chain, pn_right: rest of chain + * TOK_AND binary pn_left: first in && chain, pn_right: rest of chain + * TOK_BITOR binary pn_left: left-assoc | expr, pn_right: ^ expr + * TOK_BITXOR binary pn_left: left-assoc ^ expr, pn_right: & expr + * TOK_BITAND binary pn_left: left-assoc & expr, pn_right: EQ expr + * TOK_EQOP binary pn_left: left-assoc EQ expr, pn_right: REL expr + * pn_op: JSOP_EQ, JSOP_NE, JSOP_NEW_EQ, JSOP_NEW_NE + * TOK_RELOP binary pn_left: left-assoc REL expr, pn_right: SH expr + * pn_op: JSOP_LT, JSOP_LE, JSOP_GT, JSOP_GE + * TOK_SHOP binary pn_left: left-assoc SH expr, pn_right: ADD expr + * pn_op: JSOP_LSH, JSOP_RSH, JSOP_URSH + * TOK_PLUS, binary pn_left: left-assoc ADD expr, pn_right: MUL expr + * pn_extra: if a left-associated binary TOK_PLUS + * tree has been flattened into a list (see above + * under ), pn_extra will contain + * PNX_STRCAT if at least one list element is a + * string literal (TOK_STRING); if such a list has + * any non-string, non-number term, pn_extra will + * contain PNX_CANTFOLD. + * pn_ + * TOK_MINUS pn_op: JSOP_ADD, JSOP_SUB + * TOK_STAR, binary pn_left: left-assoc MUL expr, pn_right: UNARY expr + * TOK_DIVOP pn_op: JSOP_MUL, JSOP_DIV, JSOP_MOD + * TOK_UNARYOP unary pn_kid: UNARY expr, pn_op: JSOP_NEG, JSOP_POS, + * JSOP_NOT, JSOP_BITNOT, JSOP_TYPEOF, JSOP_VOID + * TOK_INC, unary pn_kid: MEMBER expr + * TOK_DEC + * TOK_NEW list pn_head: list of ctor, arg1, arg2, ... argN + * pn_count: 1 + N (where N is number of args) + * ctor is a MEMBER expr + * TOK_DELETE unary pn_kid: MEMBER expr + * TOK_DOT name pn_expr: MEMBER expr to left of . + * pn_atom: name to right of . + * TOK_LB binary pn_left: MEMBER expr to left of [ + * pn_right: expr between [ and ] + * TOK_LP list pn_head: list of call, arg1, arg2, ... argN + * pn_count: 1 + N (where N is number of args) + * call is a MEMBER expr naming a callable object + * TOK_RB list pn_head: list of pn_count array element exprs + * [,,] holes are represented by TOK_COMMA nodes + * #n=[...] produces TOK_DEFSHARP at head of list + * pn_extra: true if extra comma at end + * TOK_RC list pn_head: list of pn_count TOK_COLON nodes where + * each has pn_left: property id, pn_right: value + * #n={...} produces TOK_DEFSHARP at head of list + * TOK_DEFSHARP unary pn_num: jsint value of n in #n= + * pn_kid: null for #n=[...] and #n={...}, primary + * if #n=primary for function, paren, name, object + * literal expressions + * TOK_USESHARP nullary pn_num: jsint value of n in #n# + * TOK_RP unary pn_kid: parenthesized expression + * TOK_NAME, name pn_atom: name, string, or object atom + * TOK_STRING, pn_op: JSOP_NAME, JSOP_STRING, or JSOP_OBJECT + * TOK_OBJECT If JSOP_NAME, pn_op may be JSOP_*ARG or JSOP_*VAR + * with pn_slot >= 0 and pn_attrs telling const-ness + * TOK_NUMBER dval pn_dval: double value of numeric literal + * TOK_PRIMARY nullary pn_op: JSOp bytecode + */ +typedef enum JSParseNodeArity { + PN_FUNC = -3, + PN_LIST = -2, + PN_TERNARY = 3, + PN_BINARY = 2, + PN_UNARY = 1, + PN_NAME = -1, + PN_NULLARY = 0 +} JSParseNodeArity; + +struct JSParseNode { + JSTokenType pn_type; + JSTokenPos pn_pos; + JSOp pn_op; + ptrdiff_t pn_offset; /* first generated bytecode offset */ + JSParseNodeArity pn_arity; + union { + struct { /* TOK_FUNCTION node */ + JSAtom *funAtom; /* atomized function object */ + JSParseNode *body; /* TOK_LC list of statements */ + uint32 flags; /* accumulated tree context flags */ + uint32 tryCount; /* count of try statements in body */ + } func; + struct { /* list of next-linked nodes */ + JSParseNode *head; /* first node in list */ + JSParseNode **tail; /* ptr to ptr to last node in list */ + uint32 count; /* number of nodes in list */ + uint32 extra; /* extra comma flag for [1,2,,] */ + } list; + struct { /* ternary: if, for(;;), ?: */ + JSParseNode *kid1; /* condition, discriminant, etc. */ + JSParseNode *kid2; /* then-part, case list, etc. */ + JSParseNode *kid3; /* else-part, default case, etc. */ + } ternary; + struct { /* two kids if binary */ + JSParseNode *left; + JSParseNode *right; + jsval val; /* switch case value */ + } binary; + struct { /* one kid if unary */ + JSParseNode *kid; + jsint num; /* -1 or sharp variable number */ + } unary; + struct { /* name, labeled statement, etc. */ + JSAtom *atom; /* name or label atom, null if slot */ + JSParseNode *expr; /* object or initializer */ + jsint slot; /* -1 or arg or local var slot */ + uintN attrs; /* attributes if local var or const */ + } name; + jsdouble dval; /* aligned numeric literal value */ + } pn_u; + JSParseNode *pn_next; /* to align dval and pn_u on RISCs */ +}; + +#define pn_funAtom pn_u.func.funAtom +#define pn_body pn_u.func.body +#define pn_flags pn_u.func.flags +#define pn_tryCount pn_u.func.tryCount +#define pn_head pn_u.list.head +#define pn_tail pn_u.list.tail +#define pn_count pn_u.list.count +#define pn_extra pn_u.list.extra +#define pn_kid1 pn_u.ternary.kid1 +#define pn_kid2 pn_u.ternary.kid2 +#define pn_kid3 pn_u.ternary.kid3 +#define pn_left pn_u.binary.left +#define pn_right pn_u.binary.right +#define pn_val pn_u.binary.val +#define pn_kid pn_u.unary.kid +#define pn_num pn_u.unary.num +#define pn_atom pn_u.name.atom +#define pn_expr pn_u.name.expr +#define pn_slot pn_u.name.slot +#define pn_attrs pn_u.name.attrs +#define pn_dval pn_u.dval + +/* PN_LIST pn_extra flags. */ +#define PNX_STRCAT 0x1 /* TOK_PLUS list has string term */ +#define PNX_CANTFOLD 0x2 /* TOK_PLUS list has unfoldable term */ + +/* + * Move pn2 into pn, preserving pn->pn_pos and pn->pn_offset and handing off + * any kids in pn2->pn_u, by clearing pn2. + */ +#define PN_MOVE_NODE(pn, pn2) \ + JS_BEGIN_MACRO \ + (pn)->pn_type = (pn2)->pn_type; \ + (pn)->pn_op = (pn2)->pn_op; \ + (pn)->pn_arity = (pn2)->pn_arity; \ + (pn)->pn_u = (pn2)->pn_u; \ + PN_CLEAR_NODE(pn2); \ + JS_END_MACRO + +#define PN_CLEAR_NODE(pn) \ + JS_BEGIN_MACRO \ + (pn)->pn_type = TOK_EOF; \ + (pn)->pn_op = JSOP_NOP; \ + (pn)->pn_arity = PN_NULLARY; \ + JS_END_MACRO + +/* True if pn is a parsenode representing a literal constant. */ +#define PN_IS_CONSTANT(pn) \ + ((pn)->pn_type == TOK_NUMBER || \ + (pn)->pn_type == TOK_STRING || \ + ((pn)->pn_type == TOK_PRIMARY && (pn)->pn_op != JSOP_THIS)) + +/* + * Compute a pointer to the last JSParseNode element in a singly-linked list. + * NB: list must be non-empty for correct PN_LAST usage! + */ +#define PN_LAST(list) \ + ((JSParseNode *)((char *)(list)->pn_tail - offsetof(JSParseNode, pn_next))) + +#define PN_INIT_LIST(list) \ + JS_BEGIN_MACRO \ + (list)->pn_head = NULL; \ + (list)->pn_tail = &(list)->pn_head; \ + (list)->pn_count = 0; \ + JS_END_MACRO + +#define PN_INIT_LIST_1(list, pn) \ + JS_BEGIN_MACRO \ + (list)->pn_head = (pn); \ + (list)->pn_tail = &(pn)->pn_next; \ + (list)->pn_count = 1; \ + JS_END_MACRO + +#define PN_APPEND(list, pn) \ + JS_BEGIN_MACRO \ + *(list)->pn_tail = (pn); \ + (list)->pn_tail = &(pn)->pn_next; \ + (list)->pn_count++; \ + JS_END_MACRO + +/* + * Parse a top-level JS script. + * + * The caller must prevent the GC from running while this function is active, + * because atoms and function newborns are not rooted yet. + */ +extern JS_FRIEND_API(JSParseNode *) +js_ParseTokenStream(JSContext *cx, JSObject *chain, JSTokenStream *ts); + +extern JS_FRIEND_API(JSBool) +js_CompileTokenStream(JSContext *cx, JSObject *chain, JSTokenStream *ts, + JSCodeGenerator *cg); + +extern JSBool +js_CompileFunctionBody(JSContext *cx, JSTokenStream *ts, JSFunction *fun); + +extern JSBool +js_FoldConstants(JSContext *cx, JSParseNode *pn, JSTreeContext *tc); + +JS_END_EXTERN_C + +#endif /* jsparse_h___ */ diff --git a/src/extension/script/js/jsprf.c b/src/extension/script/js/jsprf.c new file mode 100644 index 000000000..36bf92428 --- /dev/null +++ b/src/extension/script/js/jsprf.c @@ -0,0 +1,1212 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* +** Portable safe sprintf code. +** +** Author: Kipp E.B. Hickman +*/ +#include "jsstddef.h" +#include +#include +#include +#include +#include "jsprf.h" +#include "jslong.h" +#include "jsutil.h" /* Added by JSIFY */ + +/* +** Note: on some platforms va_list is defined as an array, +** and requires array notation. +*/ +#ifdef HAVE_VA_COPY +#define VARARGS_ASSIGN(foo, bar) VA_COPY(foo,bar) +#elif defined(HAVE_VA_LIST_AS_ARRAY) +#define VARARGS_ASSIGN(foo, bar) foo[0] = bar[0] +#else +#define VARARGS_ASSIGN(foo, bar) (foo) = (bar) +#endif + +/* +** WARNING: This code may *NOT* call JS_LOG (because JS_LOG calls it) +*/ + +/* +** XXX This needs to be internationalized! +*/ + +typedef struct SprintfStateStr SprintfState; + +struct SprintfStateStr { + int (*stuff)(SprintfState *ss, const char *sp, JSUint32 len); + + char *base; + char *cur; + JSUint32 maxlen; + + int (*func)(void *arg, const char *sp, JSUint32 len); + void *arg; +}; + +/* +** Numbered Arguement State +*/ +struct NumArgState{ + int type; /* type of the current ap */ + va_list ap; /* point to the corresponding position on ap */ +}; + +#define NAS_DEFAULT_NUM 20 /* default number of NumberedArgumentState array */ + + +#define TYPE_INT16 0 +#define TYPE_UINT16 1 +#define TYPE_INTN 2 +#define TYPE_UINTN 3 +#define TYPE_INT32 4 +#define TYPE_UINT32 5 +#define TYPE_INT64 6 +#define TYPE_UINT64 7 +#define TYPE_STRING 8 +#define TYPE_DOUBLE 9 +#define TYPE_INTSTR 10 +#define TYPE_UNKNOWN 20 + +#define FLAG_LEFT 0x1 +#define FLAG_SIGNED 0x2 +#define FLAG_SPACED 0x4 +#define FLAG_ZEROS 0x8 +#define FLAG_NEG 0x10 + +/* +** Fill into the buffer using the data in src +*/ +static int fill2(SprintfState *ss, const char *src, int srclen, int width, + int flags) +{ + char space = ' '; + int rv; + + width -= srclen; + if ((width > 0) && ((flags & FLAG_LEFT) == 0)) { /* Right adjusting */ + if (flags & FLAG_ZEROS) { + space = '0'; + } + while (--width >= 0) { + rv = (*ss->stuff)(ss, &space, 1); + if (rv < 0) { + return rv; + } + } + } + + /* Copy out the source data */ + rv = (*ss->stuff)(ss, src, (JSUint32)srclen); + if (rv < 0) { + return rv; + } + + if ((width > 0) && ((flags & FLAG_LEFT) != 0)) { /* Left adjusting */ + while (--width >= 0) { + rv = (*ss->stuff)(ss, &space, 1); + if (rv < 0) { + return rv; + } + } + } + return 0; +} + +/* +** Fill a number. The order is: optional-sign zero-filling conversion-digits +*/ +static int fill_n(SprintfState *ss, const char *src, int srclen, int width, + int prec, int type, int flags) +{ + int zerowidth = 0; + int precwidth = 0; + int signwidth = 0; + int leftspaces = 0; + int rightspaces = 0; + int cvtwidth; + int rv; + char sign; + + if ((type & 1) == 0) { + if (flags & FLAG_NEG) { + sign = '-'; + signwidth = 1; + } else if (flags & FLAG_SIGNED) { + sign = '+'; + signwidth = 1; + } else if (flags & FLAG_SPACED) { + sign = ' '; + signwidth = 1; + } + } + cvtwidth = signwidth + srclen; + + if (prec > 0) { + if (prec > srclen) { + precwidth = prec - srclen; /* Need zero filling */ + cvtwidth += precwidth; + } + } + + if ((flags & FLAG_ZEROS) && (prec < 0)) { + if (width > cvtwidth) { + zerowidth = width - cvtwidth; /* Zero filling */ + cvtwidth += zerowidth; + } + } + + if (flags & FLAG_LEFT) { + if (width > cvtwidth) { + /* Space filling on the right (i.e. left adjusting) */ + rightspaces = width - cvtwidth; + } + } else { + if (width > cvtwidth) { + /* Space filling on the left (i.e. right adjusting) */ + leftspaces = width - cvtwidth; + } + } + while (--leftspaces >= 0) { + rv = (*ss->stuff)(ss, " ", 1); + if (rv < 0) { + return rv; + } + } + if (signwidth) { + rv = (*ss->stuff)(ss, &sign, 1); + if (rv < 0) { + return rv; + } + } + while (--precwidth >= 0) { + rv = (*ss->stuff)(ss, "0", 1); + if (rv < 0) { + return rv; + } + } + while (--zerowidth >= 0) { + rv = (*ss->stuff)(ss, "0", 1); + if (rv < 0) { + return rv; + } + } + rv = (*ss->stuff)(ss, src, (JSUint32)srclen); + if (rv < 0) { + return rv; + } + while (--rightspaces >= 0) { + rv = (*ss->stuff)(ss, " ", 1); + if (rv < 0) { + return rv; + } + } + return 0; +} + +/* +** Convert a long into its printable form +*/ +static int cvt_l(SprintfState *ss, long num, int width, int prec, int radix, + int type, int flags, const char *hexp) +{ + char cvtbuf[100]; + char *cvt; + int digits; + + /* according to the man page this needs to happen */ + if ((prec == 0) && (num == 0)) { + return 0; + } + + /* + ** Converting decimal is a little tricky. In the unsigned case we + ** need to stop when we hit 10 digits. In the signed case, we can + ** stop when the number is zero. + */ + cvt = cvtbuf + sizeof(cvtbuf); + digits = 0; + while (num) { + int digit = (((unsigned long)num) % radix) & 0xF; + *--cvt = hexp[digit]; + digits++; + num = (long)(((unsigned long)num) / radix); + } + if (digits == 0) { + *--cvt = '0'; + digits++; + } + + /* + ** Now that we have the number converted without its sign, deal with + ** the sign and zero padding. + */ + return fill_n(ss, cvt, digits, width, prec, type, flags); +} + +/* +** Convert a 64-bit integer into its printable form +*/ +static int cvt_ll(SprintfState *ss, JSInt64 num, int width, int prec, int radix, + int type, int flags, const char *hexp) +{ + char cvtbuf[100]; + char *cvt; + int digits; + JSInt64 rad; + + /* according to the man page this needs to happen */ + if ((prec == 0) && (JSLL_IS_ZERO(num))) { + return 0; + } + + /* + ** Converting decimal is a little tricky. In the unsigned case we + ** need to stop when we hit 10 digits. In the signed case, we can + ** stop when the number is zero. + */ + JSLL_I2L(rad, radix); + cvt = cvtbuf + sizeof(cvtbuf); + digits = 0; + while (!JSLL_IS_ZERO(num)) { + JSInt32 digit; + JSInt64 quot, rem; + JSLL_UDIVMOD(", &rem, num, rad); + JSLL_L2I(digit, rem); + *--cvt = hexp[digit & 0xf]; + digits++; + num = quot; + } + if (digits == 0) { + *--cvt = '0'; + digits++; + } + + /* + ** Now that we have the number converted without its sign, deal with + ** the sign and zero padding. + */ + return fill_n(ss, cvt, digits, width, prec, type, flags); +} + +/* +** Convert a double precision floating point number into its printable +** form. +** +** XXX stop using sprintf to convert floating point +*/ +static int cvt_f(SprintfState *ss, double d, const char *fmt0, const char *fmt1) +{ + char fin[20]; + char fout[300]; + int amount = fmt1 - fmt0; + + JS_ASSERT((amount > 0) && (amount < (int)sizeof(fin))); + if (amount >= (int)sizeof(fin)) { + /* Totally bogus % command to sprintf. Just ignore it */ + return 0; + } + memcpy(fin, fmt0, (size_t)amount); + fin[amount] = 0; + + /* Convert floating point using the native sprintf code */ +#ifdef DEBUG + { + const char *p = fin; + while (*p) { + JS_ASSERT(*p != 'L'); + p++; + } + } +#endif + sprintf(fout, fin, d); + + /* + ** This assert will catch overflow's of fout, when building with + ** debugging on. At least this way we can track down the evil piece + ** of calling code and fix it! + */ + JS_ASSERT(strlen(fout) < sizeof(fout)); + + return (*ss->stuff)(ss, fout, strlen(fout)); +} + +/* +** Convert a string into its printable form. "width" is the output +** width. "prec" is the maximum number of characters of "s" to output, +** where -1 means until NUL. +*/ +static int cvt_s(SprintfState *ss, const char *s, int width, int prec, + int flags) +{ + int slen; + + if (prec == 0) + return 0; + + /* Limit string length by precision value */ + slen = s ? strlen(s) : 6; + if (prec > 0) { + if (prec < slen) { + slen = prec; + } + } + + /* and away we go */ + return fill2(ss, s ? s : "(null)", slen, width, flags); +} + +/* +** BiuldArgArray stands for Numbered Argument list Sprintf +** for example, +** fmp = "%4$i, %2$d, %3s, %1d"; +** the number must start from 1, and no gap among them +*/ + +static struct NumArgState* BuildArgArray( const char *fmt, va_list ap, int* rv, struct NumArgState* nasArray ) +{ + int number = 0, cn = 0, i; + const char* p; + char c; + struct NumArgState* nas; + + + /* + ** first pass: + ** detemine how many legal % I have got, then allocate space + */ + + p = fmt; + *rv = 0; + i = 0; + while( ( c = *p++ ) != 0 ){ + if( c != '%' ) + continue; + if( ( c = *p++ ) == '%' ) /* skip %% case */ + continue; + + while( c != 0 ){ + if( c > '9' || c < '0' ){ + if( c == '$' ){ /* numbered argument csae */ + if( i > 0 ){ + *rv = -1; + return NULL; + } + number++; + } else { /* non-numbered argument case */ + if( number > 0 ){ + *rv = -1; + return NULL; + } + i = 1; + } + break; + } + + c = *p++; + } + } + + if( number == 0 ){ + return NULL; + } + + + if( number > NAS_DEFAULT_NUM ){ + nas = (struct NumArgState*)malloc( number * sizeof( struct NumArgState ) ); + if( !nas ){ + *rv = -1; + return NULL; + } + } else { + nas = nasArray; + } + + for( i = 0; i < number; i++ ){ + nas[i].type = TYPE_UNKNOWN; + } + + + /* + ** second pass: + ** set nas[].type + */ + + p = fmt; + while( ( c = *p++ ) != 0 ){ + if( c != '%' ) continue; + c = *p++; + if( c == '%' ) continue; + + cn = 0; + while( c && c != '$' ){ /* should imporve error check later */ + cn = cn*10 + c - '0'; + c = *p++; + } + + if( !c || cn < 1 || cn > number ){ + *rv = -1; + break; + } + + /* nas[cn] starts from 0, and make sure nas[cn].type is not assigned */ + cn--; + if( nas[cn].type != TYPE_UNKNOWN ) + continue; + + c = *p++; + + /* width */ + if (c == '*') { + /* not supported feature, for the argument is not numbered */ + *rv = -1; + break; + } + + while ((c >= '0') && (c <= '9')) { + c = *p++; + } + + /* precision */ + if (c == '.') { + c = *p++; + if (c == '*') { + /* not supported feature, for the argument is not numbered */ + *rv = -1; + break; + } + + while ((c >= '0') && (c <= '9')) { + c = *p++; + } + } + + /* size */ + nas[cn].type = TYPE_INTN; + if (c == 'h') { + nas[cn].type = TYPE_INT16; + c = *p++; + } else if (c == 'L') { + /* XXX not quite sure here */ + nas[cn].type = TYPE_INT64; + c = *p++; + } else if (c == 'l') { + nas[cn].type = TYPE_INT32; + c = *p++; + if (c == 'l') { + nas[cn].type = TYPE_INT64; + c = *p++; + } + } + + /* format */ + switch (c) { + case 'd': + case 'c': + case 'i': + case 'o': + case 'u': + case 'x': + case 'X': + break; + + case 'e': + case 'f': + case 'g': + nas[ cn ].type = TYPE_DOUBLE; + break; + + case 'p': + /* XXX should use cpp */ + if (sizeof(void *) == sizeof(JSInt32)) { + nas[ cn ].type = TYPE_UINT32; + } else if (sizeof(void *) == sizeof(JSInt64)) { + nas[ cn ].type = TYPE_UINT64; + } else if (sizeof(void *) == sizeof(JSIntn)) { + nas[ cn ].type = TYPE_UINTN; + } else { + nas[ cn ].type = TYPE_UNKNOWN; + } + break; + + case 'C': + case 'S': + case 'E': + case 'G': + /* XXX not supported I suppose */ + JS_ASSERT(0); + nas[ cn ].type = TYPE_UNKNOWN; + break; + + case 's': + nas[ cn ].type = TYPE_STRING; + break; + + case 'n': + nas[ cn ].type = TYPE_INTSTR; + break; + + default: + JS_ASSERT(0); + nas[ cn ].type = TYPE_UNKNOWN; + break; + } + + /* get a legal para. */ + if( nas[ cn ].type == TYPE_UNKNOWN ){ + *rv = -1; + break; + } + } + + + /* + ** third pass + ** fill the nas[cn].ap + */ + + if( *rv < 0 ){ + if( nas != nasArray ) + JS_DELETE( nas ); + return NULL; + } + + cn = 0; + while( cn < number ){ + if( nas[cn].type == TYPE_UNKNOWN ){ + cn++; + continue; + } + + VARARGS_ASSIGN(nas[cn].ap, ap); + + switch( nas[cn].type ){ + case TYPE_INT16: + case TYPE_UINT16: + case TYPE_INTN: + case TYPE_UINTN: (void)va_arg( ap, JSIntn ); break; + + case TYPE_INT32: (void)va_arg( ap, JSInt32 ); break; + + case TYPE_UINT32: (void)va_arg( ap, JSUint32 ); break; + + case TYPE_INT64: (void)va_arg( ap, JSInt64 ); break; + + case TYPE_UINT64: (void)va_arg( ap, JSUint64 ); break; + + case TYPE_STRING: (void)va_arg( ap, char* ); break; + + case TYPE_INTSTR: (void)va_arg( ap, JSIntn* ); break; + + case TYPE_DOUBLE: (void)va_arg( ap, double ); break; + + default: + if( nas != nasArray ) + JS_DELETE( nas ); + *rv = -1; + return NULL; + } + + cn++; + } + + + return nas; +} + +/* +** The workhorse sprintf code. +*/ +static int dosprintf(SprintfState *ss, const char *fmt, va_list ap) +{ + char c; + int flags, width, prec, radix, type; + union { + char ch; + int i; + long l; + JSInt64 ll; + double d; + const char *s; + int *ip; + } u; + const char *fmt0; + static char *hex = "0123456789abcdef"; + static char *HEX = "0123456789ABCDEF"; + char *hexp; + int rv, i; + struct NumArgState* nas = NULL; + struct NumArgState nasArray[ NAS_DEFAULT_NUM ]; + char pattern[20]; + const char* dolPt = NULL; /* in "%4$.2f", dolPt will poiont to . */ + + + /* + ** build an argument array, IF the fmt is numbered argument + ** list style, to contain the Numbered Argument list pointers + */ + + nas = BuildArgArray( fmt, ap, &rv, nasArray ); + if( rv < 0 ){ + /* the fmt contains error Numbered Argument format, jliu@netscape.com */ + JS_ASSERT(0); + return rv; + } + + while ((c = *fmt++) != 0) { + if (c != '%') { + rv = (*ss->stuff)(ss, fmt - 1, 1); + if (rv < 0) { + return rv; + } + continue; + } + fmt0 = fmt - 1; + + /* + ** Gobble up the % format string. Hopefully we have handled all + ** of the strange cases! + */ + flags = 0; + c = *fmt++; + if (c == '%') { + /* quoting a % with %% */ + rv = (*ss->stuff)(ss, fmt - 1, 1); + if (rv < 0) { + return rv; + } + continue; + } + + if( nas != NULL ){ + /* the fmt contains the Numbered Arguments feature */ + i = 0; + while( c && c != '$' ){ /* should imporve error check later */ + i = ( i * 10 ) + ( c - '0' ); + c = *fmt++; + } + + if( nas[i-1].type == TYPE_UNKNOWN ){ + if( nas && ( nas != nasArray ) ) + JS_DELETE( nas ); + return -1; + } + + ap = nas[i-1].ap; + dolPt = fmt; + c = *fmt++; + } + + /* + * Examine optional flags. Note that we do not implement the + * '#' flag of sprintf(). The ANSI C spec. of the '#' flag is + * somewhat ambiguous and not ideal, which is perhaps why + * the various sprintf() implementations are inconsistent + * on this feature. + */ + while ((c == '-') || (c == '+') || (c == ' ') || (c == '0')) { + if (c == '-') flags |= FLAG_LEFT; + if (c == '+') flags |= FLAG_SIGNED; + if (c == ' ') flags |= FLAG_SPACED; + if (c == '0') flags |= FLAG_ZEROS; + c = *fmt++; + } + if (flags & FLAG_SIGNED) flags &= ~FLAG_SPACED; + if (flags & FLAG_LEFT) flags &= ~FLAG_ZEROS; + + /* width */ + if (c == '*') { + c = *fmt++; + width = va_arg(ap, int); + } else { + width = 0; + while ((c >= '0') && (c <= '9')) { + width = (width * 10) + (c - '0'); + c = *fmt++; + } + } + + /* precision */ + prec = -1; + if (c == '.') { + c = *fmt++; + if (c == '*') { + c = *fmt++; + prec = va_arg(ap, int); + } else { + prec = 0; + while ((c >= '0') && (c <= '9')) { + prec = (prec * 10) + (c - '0'); + c = *fmt++; + } + } + } + + /* size */ + type = TYPE_INTN; + if (c == 'h') { + type = TYPE_INT16; + c = *fmt++; + } else if (c == 'L') { + /* XXX not quite sure here */ + type = TYPE_INT64; + c = *fmt++; + } else if (c == 'l') { + type = TYPE_INT32; + c = *fmt++; + if (c == 'l') { + type = TYPE_INT64; + c = *fmt++; + } + } + + /* format */ + hexp = hex; + switch (c) { + case 'd': case 'i': /* decimal/integer */ + radix = 10; + goto fetch_and_convert; + + case 'o': /* octal */ + radix = 8; + type |= 1; + goto fetch_and_convert; + + case 'u': /* unsigned decimal */ + radix = 10; + type |= 1; + goto fetch_and_convert; + + case 'x': /* unsigned hex */ + radix = 16; + type |= 1; + goto fetch_and_convert; + + case 'X': /* unsigned HEX */ + radix = 16; + hexp = HEX; + type |= 1; + goto fetch_and_convert; + + fetch_and_convert: + switch (type) { + case TYPE_INT16: + u.l = va_arg(ap, int); + if (u.l < 0) { + u.l = -u.l; + flags |= FLAG_NEG; + } + goto do_long; + case TYPE_UINT16: + u.l = va_arg(ap, int) & 0xffff; + goto do_long; + case TYPE_INTN: + u.l = va_arg(ap, int); + if (u.l < 0) { + u.l = -u.l; + flags |= FLAG_NEG; + } + goto do_long; + case TYPE_UINTN: + u.l = (long)va_arg(ap, unsigned int); + goto do_long; + + case TYPE_INT32: + u.l = va_arg(ap, JSInt32); + if (u.l < 0) { + u.l = -u.l; + flags |= FLAG_NEG; + } + goto do_long; + case TYPE_UINT32: + u.l = (long)va_arg(ap, JSUint32); + do_long: + rv = cvt_l(ss, u.l, width, prec, radix, type, flags, hexp); + if (rv < 0) { + return rv; + } + break; + + case TYPE_INT64: + u.ll = va_arg(ap, JSInt64); + if (!JSLL_GE_ZERO(u.ll)) { + JSLL_NEG(u.ll, u.ll); + flags |= FLAG_NEG; + } + goto do_longlong; + case TYPE_UINT64: + u.ll = va_arg(ap, JSUint64); + do_longlong: + rv = cvt_ll(ss, u.ll, width, prec, radix, type, flags, hexp); + if (rv < 0) { + return rv; + } + break; + } + break; + + case 'e': + case 'E': + case 'f': + case 'g': + u.d = va_arg(ap, double); + if( nas != NULL ){ + i = fmt - dolPt; + if( i < (int)sizeof( pattern ) ){ + pattern[0] = '%'; + memcpy( &pattern[1], dolPt, (size_t)i ); + rv = cvt_f(ss, u.d, pattern, &pattern[i+1] ); + } + } else + rv = cvt_f(ss, u.d, fmt0, fmt); + + if (rv < 0) { + return rv; + } + break; + + case 'c': + u.ch = va_arg(ap, int); + if ((flags & FLAG_LEFT) == 0) { + while (width-- > 1) { + rv = (*ss->stuff)(ss, " ", 1); + if (rv < 0) { + return rv; + } + } + } + rv = (*ss->stuff)(ss, &u.ch, 1); + if (rv < 0) { + return rv; + } + if (flags & FLAG_LEFT) { + while (width-- > 1) { + rv = (*ss->stuff)(ss, " ", 1); + if (rv < 0) { + return rv; + } + } + } + break; + + case 'p': + if (sizeof(void *) == sizeof(JSInt32)) { + type = TYPE_UINT32; + } else if (sizeof(void *) == sizeof(JSInt64)) { + type = TYPE_UINT64; + } else if (sizeof(void *) == sizeof(int)) { + type = TYPE_UINTN; + } else { + JS_ASSERT(0); + break; + } + radix = 16; + goto fetch_and_convert; + +#if 0 + case 'C': + case 'S': + case 'E': + case 'G': + /* XXX not supported I suppose */ + JS_ASSERT(0); + break; +#endif + + case 's': + u.s = va_arg(ap, const char*); + rv = cvt_s(ss, u.s, width, prec, flags); + if (rv < 0) { + return rv; + } + break; + + case 'n': + u.ip = va_arg(ap, int*); + if (u.ip) { + *u.ip = ss->cur - ss->base; + } + break; + + default: + /* Not a % token after all... skip it */ +#if 0 + JS_ASSERT(0); +#endif + rv = (*ss->stuff)(ss, "%", 1); + if (rv < 0) { + return rv; + } + rv = (*ss->stuff)(ss, fmt - 1, 1); + if (rv < 0) { + return rv; + } + } + } + + /* Stuff trailing NUL */ + rv = (*ss->stuff)(ss, "\0", 1); + + if( nas && ( nas != nasArray ) ){ + JS_DELETE( nas ); + } + + return rv; +} + +/************************************************************************/ + +static int FuncStuff(SprintfState *ss, const char *sp, JSUint32 len) +{ + int rv; + + rv = (*ss->func)(ss->arg, sp, len); + if (rv < 0) { + return rv; + } + ss->maxlen += len; + return 0; +} + +JS_PUBLIC_API(JSUint32) JS_sxprintf(JSStuffFunc func, void *arg, + const char *fmt, ...) +{ + va_list ap; + int rv; + + va_start(ap, fmt); + rv = JS_vsxprintf(func, arg, fmt, ap); + va_end(ap); + return rv; +} + +JS_PUBLIC_API(JSUint32) JS_vsxprintf(JSStuffFunc func, void *arg, + const char *fmt, va_list ap) +{ + SprintfState ss; + int rv; + + ss.stuff = FuncStuff; + ss.func = func; + ss.arg = arg; + ss.maxlen = 0; + rv = dosprintf(&ss, fmt, ap); + return (rv < 0) ? (JSUint32)-1 : ss.maxlen; +} + +/* +** Stuff routine that automatically grows the malloc'd output buffer +** before it overflows. +*/ +static int GrowStuff(SprintfState *ss, const char *sp, JSUint32 len) +{ + ptrdiff_t off; + char *newbase; + JSUint32 newlen; + + off = ss->cur - ss->base; + if (off + len >= ss->maxlen) { + /* Grow the buffer */ + newlen = ss->maxlen + ((len > 32) ? len : 32); + if (ss->base) { + newbase = (char*) realloc(ss->base, newlen); + } else { + newbase = (char*) malloc(newlen); + } + if (!newbase) { + /* Ran out of memory */ + return -1; + } + ss->base = newbase; + ss->maxlen = newlen; + ss->cur = ss->base + off; + } + + /* Copy data */ + while (len) { + --len; + *ss->cur++ = *sp++; + } + JS_ASSERT((JSUint32)(ss->cur - ss->base) <= ss->maxlen); + return 0; +} + +/* +** sprintf into a malloc'd buffer +*/ +JS_PUBLIC_API(char *) JS_smprintf(const char *fmt, ...) +{ + va_list ap; + char *rv; + + va_start(ap, fmt); + rv = JS_vsmprintf(fmt, ap); + va_end(ap); + return rv; +} + +/* +** Free memory allocated, for the caller, by JS_smprintf +*/ +JS_PUBLIC_API(void) JS_smprintf_free(char *mem) +{ + JS_DELETE(mem); +} + +JS_PUBLIC_API(char *) JS_vsmprintf(const char *fmt, va_list ap) +{ + SprintfState ss; + int rv; + + ss.stuff = GrowStuff; + ss.base = 0; + ss.cur = 0; + ss.maxlen = 0; + rv = dosprintf(&ss, fmt, ap); + if (rv < 0) { + if (ss.base) { + JS_DELETE(ss.base); + } + return 0; + } + return ss.base; +} + +/* +** Stuff routine that discards overflow data +*/ +static int LimitStuff(SprintfState *ss, const char *sp, JSUint32 len) +{ + JSUint32 limit = ss->maxlen - (ss->cur - ss->base); + + if (len > limit) { + len = limit; + } + while (len) { + --len; + *ss->cur++ = *sp++; + } + return 0; +} + +/* +** sprintf into a fixed size buffer. Make sure there is a NUL at the end +** when finished. +*/ +JS_PUBLIC_API(JSUint32) JS_snprintf(char *out, JSUint32 outlen, const char *fmt, ...) +{ + va_list ap; + int rv; + + JS_ASSERT((JSInt32)outlen > 0); + if ((JSInt32)outlen <= 0) { + return 0; + } + + va_start(ap, fmt); + rv = JS_vsnprintf(out, outlen, fmt, ap); + va_end(ap); + return rv; +} + +JS_PUBLIC_API(JSUint32) JS_vsnprintf(char *out, JSUint32 outlen,const char *fmt, + va_list ap) +{ + SprintfState ss; + JSUint32 n; + + JS_ASSERT((JSInt32)outlen > 0); + if ((JSInt32)outlen <= 0) { + return 0; + } + + ss.stuff = LimitStuff; + ss.base = out; + ss.cur = out; + ss.maxlen = outlen; + (void) dosprintf(&ss, fmt, ap); + + /* If we added chars, and we didn't append a null, do it now. */ + if( (ss.cur != ss.base) && (*(ss.cur - 1) != '\0') ) + *(--ss.cur) = '\0'; + + n = ss.cur - ss.base; + return n ? n - 1 : n; +} + +JS_PUBLIC_API(char *) JS_sprintf_append(char *last, const char *fmt, ...) +{ + va_list ap; + char *rv; + + va_start(ap, fmt); + rv = JS_vsprintf_append(last, fmt, ap); + va_end(ap); + return rv; +} + +JS_PUBLIC_API(char *) JS_vsprintf_append(char *last, const char *fmt, va_list ap) +{ + SprintfState ss; + int rv; + + ss.stuff = GrowStuff; + if (last) { + int lastlen = strlen(last); + ss.base = last; + ss.cur = last + lastlen; + ss.maxlen = lastlen; + } else { + ss.base = 0; + ss.cur = 0; + ss.maxlen = 0; + } + rv = dosprintf(&ss, fmt, ap); + if (rv < 0) { + if (ss.base) { + JS_DELETE(ss.base); + } + return 0; + } + return ss.base; +} + diff --git a/src/extension/script/js/jsprf.h b/src/extension/script/js/jsprf.h new file mode 100644 index 000000000..e8cc46c0c --- /dev/null +++ b/src/extension/script/js/jsprf.h @@ -0,0 +1,148 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef jsprf_h___ +#define jsprf_h___ + +/* +** API for PR printf like routines. Supports the following formats +** %d - decimal +** %u - unsigned decimal +** %x - unsigned hex +** %X - unsigned uppercase hex +** %o - unsigned octal +** %hd, %hu, %hx, %hX, %ho - 16-bit versions of above +** %ld, %lu, %lx, %lX, %lo - 32-bit versions of above +** %lld, %llu, %llx, %llX, %llo - 64 bit versions of above +** %s - string +** %c - character +** %p - pointer (deals with machine dependent pointer size) +** %f - float +** %g - float +*/ +#include "jstypes.h" +#include +#include + +JS_BEGIN_EXTERN_C + +/* +** sprintf into a fixed size buffer. Guarantees that a NUL is at the end +** of the buffer. Returns the length of the written output, NOT including +** the NUL, or (JSUint32)-1 if an error occurs. +*/ +extern JS_PUBLIC_API(JSUint32) JS_snprintf(char *out, JSUint32 outlen, const char *fmt, ...); + +/* +** sprintf into a malloc'd buffer. Return a pointer to the malloc'd +** buffer on success, NULL on failure. Call "JS_smprintf_free" to release +** the memory returned. +*/ +extern JS_PUBLIC_API(char*) JS_smprintf(const char *fmt, ...); + +/* +** Free the memory allocated, for the caller, by JS_smprintf +*/ +extern JS_PUBLIC_API(void) JS_smprintf_free(char *mem); + +/* +** "append" sprintf into a malloc'd buffer. "last" is the last value of +** the malloc'd buffer. sprintf will append data to the end of last, +** growing it as necessary using realloc. If last is NULL, JS_sprintf_append +** will allocate the initial string. The return value is the new value of +** last for subsequent calls, or NULL if there is a malloc failure. +*/ +extern JS_PUBLIC_API(char*) JS_sprintf_append(char *last, const char *fmt, ...); + +/* +** sprintf into a function. The function "f" is called with a string to +** place into the output. "arg" is an opaque pointer used by the stuff +** function to hold any state needed to do the storage of the output +** data. The return value is a count of the number of characters fed to +** the stuff function, or (JSUint32)-1 if an error occurs. +*/ +typedef JSIntn (*JSStuffFunc)(void *arg, const char *s, JSUint32 slen); + +extern JS_PUBLIC_API(JSUint32) JS_sxprintf(JSStuffFunc f, void *arg, const char *fmt, ...); + +/* +** va_list forms of the above. +*/ +extern JS_PUBLIC_API(JSUint32) JS_vsnprintf(char *out, JSUint32 outlen, const char *fmt, va_list ap); +extern JS_PUBLIC_API(char*) JS_vsmprintf(const char *fmt, va_list ap); +extern JS_PUBLIC_API(char*) JS_vsprintf_append(char *last, const char *fmt, va_list ap); +extern JS_PUBLIC_API(JSUint32) JS_vsxprintf(JSStuffFunc f, void *arg, const char *fmt, va_list ap); + +/* +*************************************************************************** +** FUNCTION: JS_sscanf +** DESCRIPTION: +** JS_sscanf() scans the input character string, performs data +** conversions, and stores the converted values in the data objects +** pointed to by its arguments according to the format control +** string. +** +** JS_sscanf() behaves the same way as the sscanf() function in the +** Standard C Library (stdio.h), with the following exceptions: +** - JS_sscanf() handles the NSPR integer and floating point types, +** such as JSInt16, JSInt32, JSInt64, and JSFloat64, whereas +** sscanf() handles the standard C types like short, int, long, +** and double. +** - JS_sscanf() has no multibyte character support, while sscanf() +** does. +** INPUTS: +** const char *buf +** a character string holding the input to scan +** const char *fmt +** the format control string for the conversions +** ... +** variable number of arguments, each of them is a pointer to +** a data object in which the converted value will be stored +** OUTPUTS: none +** RETURNS: JSInt32 +** The number of values converted and stored. +** RESTRICTIONS: +** Multibyte characters in 'buf' or 'fmt' are not allowed. +*************************************************************************** +*/ + +extern JS_PUBLIC_API(JSInt32) JS_sscanf(const char *buf, const char *fmt, ...); + +JS_END_EXTERN_C + +#endif /* jsprf_h___ */ diff --git a/src/extension/script/js/jsprvtd.h b/src/extension/script/js/jsprvtd.h new file mode 100644 index 000000000..f5f1e77f6 --- /dev/null +++ b/src/extension/script/js/jsprvtd.h @@ -0,0 +1,174 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef jsprvtd_h___ +#define jsprvtd_h___ +/* + * JS private typename definitions. + * + * This header is included only in other .h files, for convenience and for + * simplicity of type naming. The alternative for structures is to use tags, + * which are named the same as their typedef names (legal in C/C++, and less + * noisy than suffixing the typedef name with "Struct" or "Str"). Instead, + * all .h files that include this file may use the same typedef name, whether + * declaring a pointer to struct type, or defining a member of struct type. + * + * A few fundamental scalar types are defined here too. Neither the scalar + * nor the struct typedefs should change much, therefore the nearly-global + * make dependency induced by this file should not prove painful. + */ + +#include "jspubtd.h" + +/* Scalar typedefs. */ +typedef uint8 jsbytecode; +typedef uint8 jssrcnote; +typedef uint32 jsatomid; + +/* Struct typedefs. */ +typedef struct JSArgumentFormatMap JSArgumentFormatMap; +typedef struct JSCodeGenerator JSCodeGenerator; +typedef struct JSDependentString JSDependentString; +typedef struct JSGCLockHashEntry JSGCLockHashEntry; +typedef struct JSGCRootHashEntry JSGCRootHashEntry; +typedef struct JSGCThing JSGCThing; +typedef struct JSParseNode JSParseNode; +typedef struct JSSharpObjectMap JSSharpObjectMap; +typedef struct JSToken JSToken; +typedef struct JSTokenPos JSTokenPos; +typedef struct JSTokenPtr JSTokenPtr; +typedef struct JSTokenStream JSTokenStream; +typedef struct JSTreeContext JSTreeContext; +typedef struct JSTryNote JSTryNote; + +/* Friend "Advanced API" typedefs. */ +typedef struct JSAtom JSAtom; +typedef struct JSAtomList JSAtomList; +typedef struct JSAtomListElement JSAtomListElement; +typedef struct JSAtomMap JSAtomMap; +typedef struct JSAtomState JSAtomState; +typedef struct JSCodeSpec JSCodeSpec; +typedef struct JSPrinter JSPrinter; +typedef struct JSRegExp JSRegExp; +typedef struct JSRegExpStatics JSRegExpStatics; +typedef struct JSScope JSScope; +typedef struct JSScopeOps JSScopeOps; +typedef struct JSScopeProperty JSScopeProperty; +typedef struct JSStackFrame JSStackFrame; +typedef struct JSStackHeader JSStackHeader; +typedef struct JSSubString JSSubString; + +/* "Friend" types used by jscntxt.h and jsdbgapi.h. */ +typedef enum JSTrapStatus { + JSTRAP_ERROR, + JSTRAP_CONTINUE, + JSTRAP_RETURN, + JSTRAP_THROW, + JSTRAP_LIMIT +} JSTrapStatus; + +typedef JSTrapStatus +(* JS_DLL_CALLBACK JSTrapHandler)(JSContext *cx, JSScript *script, jsbytecode *pc, + jsval *rval, void *closure); + +typedef JSBool +(* JS_DLL_CALLBACK JSWatchPointHandler)(JSContext *cx, JSObject *obj, jsval id, + jsval old, jsval *newp, void *closure); + +/* called just after script creation */ +typedef void +(* JS_DLL_CALLBACK JSNewScriptHook)(JSContext *cx, + const char *filename, /* URL of script */ + uintN lineno, /* line script starts */ + JSScript *script, + JSFunction *fun, + void *callerdata); + +/* called just before script destruction */ +typedef void +(* JS_DLL_CALLBACK JSDestroyScriptHook)(JSContext *cx, + JSScript *script, + void *callerdata); + +typedef void +(* JS_DLL_CALLBACK JSSourceHandler)(const char *filename, uintN lineno, + jschar *str, size_t length, + void **listenerTSData, void *closure); + +/* +* This hook captures high level script execution and function calls +* (JS or native). +* It is used by JS_SetExecuteHook to hook top level scripts and by +* JS_SetCallHook to hook function calls. +* It will get called twice per script or function call: +* just before execution begins and just after it finishes. In both cases +* the 'current' frame is that of the executing code. +* +* The 'before' param is JS_TRUE for the hook invocation before the execution +* and JS_FALSE for the invocation after the code has run. +* +* The 'ok' param is significant only on the post execution invocation to +* signify whether or not the code completed 'normally'. +* +* The 'closure' param is as passed to JS_SetExecuteHook or JS_SetCallHook +* for the 'before'invocation, but is whatever value is returned from that +* invocation for the 'after' invocation. Thus, the hook implementor *could* +* allocate a stucture in the 'before' invocation and return a pointer +* to that structure. The pointer would then be handed to the hook for +* the 'after' invocation. Alternately, the 'before' could just return the +* same value as in 'closure' to cause the 'after' invocation to be called +* with the same 'closure' value as the 'before'. +* +* Returning NULL in the 'before' hook will cause the 'after' hook to +* NOT be called. +*/ + +typedef void * +(* JS_DLL_CALLBACK JSInterpreterHook)(JSContext *cx, JSStackFrame *fp, JSBool before, + JSBool *ok, void *closure); + +typedef void +(* JS_DLL_CALLBACK JSObjectHook)(JSContext *cx, JSObject *obj, JSBool isNew, + void *closure); + +typedef JSBool +(* JS_DLL_CALLBACK JSDebugErrorHook)(JSContext *cx, const char *message, + JSErrorReport *report, void *closure); + +#endif /* jsprvtd_h___ */ diff --git a/src/extension/script/js/jspubtd.h b/src/extension/script/js/jspubtd.h new file mode 100644 index 000000000..e3a1a38b5 --- /dev/null +++ b/src/extension/script/js/jspubtd.h @@ -0,0 +1,564 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef jspubtd_h___ +#define jspubtd_h___ +/* + * JS public API typedefs. + */ +#include "jstypes.h" +#include "jscompat.h" + +JS_BEGIN_EXTERN_C + +/* Scalar typedefs. */ +typedef uint16 jschar; +typedef int32 jsint; +typedef uint32 jsuint; +typedef float64 jsdouble; +typedef jsword jsval; +typedef jsword jsid; +typedef int32 jsrefcount; /* PRInt32 if JS_THREADSAFE, see jslock.h */ + +/* + * Run-time version enumeration. See jsconfig.h for compile-time counterparts + * to these values that may be selected by the JS_VERSION macro, and tested by + * #if expressions. + */ +typedef enum JSVersion { + JSVERSION_1_0 = 100, + JSVERSION_1_1 = 110, + JSVERSION_1_2 = 120, + JSVERSION_1_3 = 130, + JSVERSION_1_4 = 140, + JSVERSION_ECMA_3 = 148, + JSVERSION_1_5 = 150, + JSVERSION_DEFAULT = 0, + JSVERSION_UNKNOWN = -1 +} JSVersion; + +#define JSVERSION_IS_ECMA(version) \ + ((version) == JSVERSION_DEFAULT || (version) >= JSVERSION_1_3) + +/* Result of typeof operator enumeration. */ +typedef enum JSType { + JSTYPE_VOID, /* undefined */ + JSTYPE_OBJECT, /* object */ + JSTYPE_FUNCTION, /* function */ + JSTYPE_STRING, /* string */ + JSTYPE_NUMBER, /* number */ + JSTYPE_BOOLEAN, /* boolean */ + JSTYPE_LIMIT +} JSType; + +/* JSObjectOps.checkAccess mode enumeration. */ +typedef enum JSAccessMode { + JSACC_PROTO = 0, /* XXXbe redundant w.r.t. id */ + JSACC_PARENT = 1, /* XXXbe redundant w.r.t. id */ + JSACC_IMPORT = 2, /* import foo.bar */ + JSACC_WATCH = 3, /* a watchpoint on object foo for id 'bar' */ + JSACC_READ = 4, /* a "get" of foo.bar */ + JSACC_WRITE = 8, /* a "set" of foo.bar = baz */ + JSACC_LIMIT +} JSAccessMode; + +#define JSACC_TYPEMASK (JSACC_WRITE - 1) + +/* + * This enum type is used to control the behavior of a JSObject property + * iterator function that has type JSNewEnumerate. + */ +typedef enum JSIterateOp { + JSENUMERATE_INIT, /* Create new iterator state */ + JSENUMERATE_NEXT, /* Iterate once */ + JSENUMERATE_DESTROY /* Destroy iterator state */ +} JSIterateOp; + +/* Struct typedefs. */ +typedef struct JSClass JSClass; +typedef struct JSConstDoubleSpec JSConstDoubleSpec; +typedef struct JSContext JSContext; +typedef struct JSErrorReport JSErrorReport; +typedef struct JSFunction JSFunction; +typedef struct JSFunctionSpec JSFunctionSpec; +typedef struct JSIdArray JSIdArray; +typedef struct JSProperty JSProperty; +typedef struct JSPropertySpec JSPropertySpec; +typedef struct JSObject JSObject; +typedef struct JSObjectMap JSObjectMap; +typedef struct JSObjectOps JSObjectOps; +typedef struct JSRuntime JSRuntime; +typedef struct JSRuntime JSTaskState; /* XXX deprecated name */ +typedef struct JSScript JSScript; +typedef struct JSString JSString; +typedef struct JSXDRState JSXDRState; +typedef struct JSExceptionState JSExceptionState; +typedef struct JSLocaleCallbacks JSLocaleCallbacks; + +/* JSClass (and JSObjectOps where appropriate) function pointer typedefs. */ + +/* + * Add, delete, get or set a property named by id in obj. Note the jsval id + * type -- id may be a string (Unicode property identifier) or an int (element + * index). The *vp out parameter, on success, is the new property value after + * an add, get, or set. After a successful delete, *vp is JSVAL_FALSE iff + * obj[id] can't be deleted (because it's permanent). + */ +typedef JSBool +(* JS_DLL_CALLBACK JSPropertyOp)(JSContext *cx, JSObject *obj, jsval id, + jsval *vp); + +/* + * This function type is used for callbacks that enumerate the properties of + * a JSObject. The behavior depends on the value of enum_op: + * + * JSENUMERATE_INIT + * A new, opaque iterator state should be allocated and stored in *statep. + * (You can use PRIVATE_TO_JSVAL() to tag the pointer to be stored). + * + * The number of properties that will be enumerated should be returned as + * an integer jsval in *idp, if idp is non-null, and provided the number of + * enumerable properties is known. If idp is non-null and the number of + * enumerable properties can't be computed in advance, *idp should be set + * to JSVAL_ZERO. + * + * JSENUMERATE_NEXT + * A previously allocated opaque iterator state is passed in via statep. + * Return the next jsid in the iteration using *idp. The opaque iterator + * state pointed at by statep is destroyed and *statep is set to JSVAL_NULL + * if there are no properties left to enumerate. + * + * JSENUMERATE_DESTROY + * Destroy the opaque iterator state previously allocated in *statep by a + * call to this function when enum_op was JSENUMERATE_INIT. + * + * The return value is used to indicate success, with a value of JS_FALSE + * indicating failure. + */ +typedef JSBool +(* JS_DLL_CALLBACK JSNewEnumerateOp)(JSContext *cx, JSObject *obj, + JSIterateOp enum_op, + jsval *statep, jsid *idp); + +/* + * The old-style JSClass.enumerate op should define all lazy properties not + * yet reflected in obj. + */ +typedef JSBool +(* JS_DLL_CALLBACK JSEnumerateOp)(JSContext *cx, JSObject *obj); + +/* + * Resolve a lazy property named by id in obj by defining it directly in obj. + * Lazy properties are those reflected from some peer native property space + * (e.g., the DOM attributes for a given node reflected as obj) on demand. + * + * JS looks for a property in an object, and if not found, tries to resolve + * the given id. If resolve succeeds, the engine looks again in case resolve + * defined obj[id]. If no such property exists directly in obj, the process + * is repeated with obj's prototype, etc. + * + * NB: JSNewResolveOp provides a cheaper way to resolve lazy properties. + */ +typedef JSBool +(* JS_DLL_CALLBACK JSResolveOp)(JSContext *cx, JSObject *obj, jsval id); + +/* + * Like JSResolveOp, but flags provide contextual information as follows: + * + * JSRESOLVE_QUALIFIED a qualified property id: obj.id or obj[id], not id + * JSRESOLVE_ASSIGNING obj[id] is on the left-hand side of an assignment + * + * The *objp out parameter, on success, should be null to indicate that id + * was not resolved; and non-null, referring to obj or one of its prototypes, + * if id was resolved. + * + * This hook instead of JSResolveOp is called via the JSClass.resolve member + * if JSCLASS_NEW_RESOLVE is set in JSClass.flags. + * + * Setting JSCLASS_NEW_RESOLVE and JSCLASS_NEW_RESOLVE_GETS_START further + * extends this hook by passing in the starting object on the prototype chain + * via *objp. Thus a resolve hook implementation may define the property id + * being resolved in the object in which the id was first sought, rather than + * in a prototype object whose class led to the resolve hook being called. + * + * When using JSCLASS_NEW_RESOLVE_GETS_START, the resolve hook must therefore + * null *objp to signify "not resolved". With only JSCLASS_NEW_RESOLVE and no + * JSCLASS_NEW_RESOLVE_GETS_START, the hook can assume *objp is null on entry. + * This is not good practice, but enough existing hook implementations count + * on it that we can't break compatibility by passing the starting object in + * *objp without a new JSClass flag. + */ +typedef JSBool +(* JS_DLL_CALLBACK JSNewResolveOp)(JSContext *cx, JSObject *obj, jsval id, + uintN flags, JSObject **objp); + +/* + * Convert obj to the given type, returning true with the resulting value in + * *vp on success, and returning false on error or exception. + */ +typedef JSBool +(* JS_DLL_CALLBACK JSConvertOp)(JSContext *cx, JSObject *obj, JSType type, + jsval *vp); + +/* + * Finalize obj, which the garbage collector has determined to be unreachable + * from other live objects or from GC roots. Obviously, finalizers must never + * store a reference to obj. + */ +typedef void +(* JS_DLL_CALLBACK JSFinalizeOp)(JSContext *cx, JSObject *obj); + +/* + * Used by JS_AddExternalStringFinalizer and JS_RemoveExternalStringFinalizer + * to extend and reduce the set of string types finalized by the GC. + */ +typedef void +(* JS_DLL_CALLBACK JSStringFinalizeOp)(JSContext *cx, JSString *str); + +/* + * The signature for JSClass.getObjectOps, used by JS_NewObject's internals + * to discover the set of high-level object operations to use for new objects + * of the given class. All native objects have a JSClass, which is stored as + * a private (int-tagged) pointer in obj->slots[JSSLOT_CLASS]. In contrast, + * all native and host objects have a JSObjectMap at obj->map, which may be + * shared among a number of objects, and which contains the JSObjectOps *ops + * pointer used to dispatch object operations from API calls. + * + * Thus JSClass (which pre-dates JSObjectOps in the API) provides a low-level + * interface to class-specific code and data, while JSObjectOps allows for a + * higher level of operation, which does not use the object's class except to + * find the class's JSObjectOps struct, by calling clasp->getObjectOps. + * + * If this seems backwards, that's because it is! API compatibility requires + * a JSClass *clasp parameter to JS_NewObject, etc. Most host objects do not + * need to implement the larger JSObjectOps, and can share the common JSScope + * code and data used by the native (js_ObjectOps, see jsobj.c) ops. + */ +typedef JSObjectOps * +(* JS_DLL_CALLBACK JSGetObjectOps)(JSContext *cx, JSClass *clasp); + +/* + * JSClass.checkAccess type: check whether obj[id] may be accessed per mode, + * returning false on error/exception, true on success with obj[id]'s last-got + * value in *vp, and its attributes in *attrsp. As for JSPropertyOp above, id + * is either a string or an int jsval. + * + * See JSCheckAccessIdOp, below, for the JSObjectOps counterpart, which takes + * a jsid (a tagged int or aligned, unique identifier pointer) rather than a + * jsval. The native js_ObjectOps.checkAccess simply forwards to the object's + * clasp->checkAccess, so that both JSClass and JSObjectOps implementors may + * specialize access checks. + */ +typedef JSBool +(* JS_DLL_CALLBACK JSCheckAccessOp)(JSContext *cx, JSObject *obj, jsval id, + JSAccessMode mode, jsval *vp); + +/* + * Encode or decode an object, given an XDR state record representing external + * data. See jsxdrapi.h. + */ +typedef JSBool +(* JS_DLL_CALLBACK JSXDRObjectOp)(JSXDRState *xdr, JSObject **objp); + +/* + * Check whether v is an instance of obj. Return false on error or exception, + * true on success with JS_TRUE in *bp if v is an instance of obj, JS_FALSE in + * *bp otherwise. + */ +typedef JSBool +(* JS_DLL_CALLBACK JSHasInstanceOp)(JSContext *cx, JSObject *obj, jsval v, + JSBool *bp); + +/* + * Function type for JSClass.mark and JSObjectOps.mark, called from the GC to + * scan live GC-things reachable from obj's private data structure. For each + * such thing, a mark implementation must call + * + * JS_MarkGCThing(cx, thing, name, arg); + * + * The trailing name and arg parameters are used for GC_MARK_DEBUG-mode heap + * dumping and ref-path tracing. The mark function should pass a (typically + * literal) string naming the private data member for name, and it must pass + * the opaque arg parameter through from its caller. + * + * For the JSObjectOps.mark hook, the return value is the number of slots at + * obj->slots to scan. For JSClass.mark, the return value is ignored. + * + * NB: JSMarkOp implementations cannot allocate new GC-things (JS_NewObject + * called from a mark function will fail silently, e.g.). + */ +typedef uint32 +(* JS_DLL_CALLBACK JSMarkOp)(JSContext *cx, JSObject *obj, void *arg); + +/* JSObjectOps function pointer typedefs. */ + +/* + * Create a new subclass of JSObjectMap (see jsobj.h), with the nrefs and ops + * members initialized from the same-named parameters, and with the nslots and + * freeslot members initialized according to ops and clasp. Return null on + * error, non-null on success. + * + * JSObjectMaps are reference-counted by generic code in the engine. Usually, + * the nrefs parameter to JSObjectOps.newObjectMap will be 1, to count the ref + * returned to the caller on success. After a successful construction, some + * number of js_HoldObjectMap and js_DropObjectMap calls ensue. When nrefs + * reaches 0 due to a js_DropObjectMap call, JSObjectOps.destroyObjectMap will + * be called to dispose of the map. + */ +typedef JSObjectMap * +(* JS_DLL_CALLBACK JSNewObjectMapOp)(JSContext *cx, jsrefcount nrefs, + JSObjectOps *ops, JSClass *clasp, + JSObject *obj); + +/* + * Generic type for an infallible JSObjectMap operation, used currently by + * JSObjectOps.destroyObjectMap. + */ +typedef void +(* JS_DLL_CALLBACK JSObjectMapOp)(JSContext *cx, JSObjectMap *map); + +/* + * Look for id in obj and its prototype chain, returning false on error or + * exception, true on success. On success, return null in *propp if id was + * not found. If id was found, return the first object searching from obj + * along its prototype chain in which id names a direct property in *objp, and + * return a non-null, opaque property pointer in *propp. + * + * If JSLookupPropOp succeeds and returns with *propp non-null, that pointer + * may be passed as the prop parameter to a JSAttributesOp, as a short-cut + * that bypasses id re-lookup. In any case, a non-null *propp result after a + * successful lookup must be dropped via JSObjectOps.dropProperty. + * + * NB: successful return with non-null *propp means the implementation may + * have locked *objp and added a reference count associated with *propp, so + * callers should not risk deadlock by nesting or interleaving other lookups + * or any obj-bearing ops before dropping *propp. + */ +typedef JSBool +(* JS_DLL_CALLBACK JSLookupPropOp)(JSContext *cx, JSObject *obj, jsid id, + JSObject **objp, JSProperty **propp +#if defined JS_THREADSAFE && defined DEBUG + , const char *file, uintN line +#endif + ); + +/* + * Define obj[id], a direct property of obj named id, having the given initial + * value, with the specified getter, setter, and attributes. If the propp out + * param is non-null, *propp on successful return contains an opaque property + * pointer usable as a speedup hint with JSAttributesOp. But note that propp + * may be null, indicating that the caller is not interested in recovering an + * opaque pointer to the newly-defined property. + * + * If propp is non-null and JSDefinePropOp succeeds, its caller must be sure + * to drop *propp using JSObjectOps.dropProperty in short order, just as with + * JSLookupPropOp. + */ +typedef JSBool +(* JS_DLL_CALLBACK JSDefinePropOp)(JSContext *cx, JSObject *obj, + jsid id, jsval value, + JSPropertyOp getter, JSPropertyOp setter, + uintN attrs, JSProperty **propp); + +/* + * Get, set, or delete obj[id], returning false on error or exception, true + * on success. If getting or setting, the new value is returned in *vp on + * success. If deleting without error, *vp will be JSVAL_FALSE if obj[id] is + * permanent, and JSVAL_TRUE if id named a direct property of obj that was in + * fact deleted, or if id names no direct property of obj (id could name a + * prototype property, or no property in obj or its prototype chain). + */ +typedef JSBool +(* JS_DLL_CALLBACK JSPropertyIdOp)(JSContext *cx, JSObject *obj, jsid id, + jsval *vp); + +/* + * Get or set attributes of the property obj[id]. Return false on error or + * exception, true with current attributes in *attrsp. If prop is non-null, + * it must come from the *propp out parameter of a prior JSDefinePropOp or + * JSLookupPropOp call. + */ +typedef JSBool +(* JS_DLL_CALLBACK JSAttributesOp)(JSContext *cx, JSObject *obj, jsid id, + JSProperty *prop, uintN *attrsp); + +/* + * JSObjectOps.checkAccess type: check whether obj[id] may be accessed per + * mode, returning false on error/exception, true on success with obj[id]'s + * last-got value in *vp, and its attributes in *attrsp. + */ +typedef JSBool +(* JS_DLL_CALLBACK JSCheckAccessIdOp)(JSContext *cx, JSObject *obj, jsid id, + JSAccessMode mode, jsval *vp, + uintN *attrsp); + +/* + * A generic type for functions mapping an object to another object, or null + * if an error or exception was thrown on cx. Used by JSObjectOps.thisObject + * at present. + */ +typedef JSObject * +(* JS_DLL_CALLBACK JSObjectOp)(JSContext *cx, JSObject *obj); + +/* + * A generic type for functions taking a context, object, and property, with + * no return value. Used by JSObjectOps.dropProperty currently (see above, + * JSDefinePropOp and JSLookupPropOp, for the object-locking protocol in which + * dropProperty participates). + */ +typedef void +(* JS_DLL_CALLBACK JSPropertyRefOp)(JSContext *cx, JSObject *obj, + JSProperty *prop); + +/* + * Function type for JSObjectOps.setProto and JSObjectOps.setParent. These + * hooks must check for cycles without deadlocking, and otherwise take special + * steps. See jsobj.c, js_SetProtoOrParent, for an example. + */ +typedef JSBool +(* JS_DLL_CALLBACK JSSetObjectSlotOp)(JSContext *cx, JSObject *obj, + uint32 slot, JSObject *pobj); + +/* + * Get and set a required slot, one that should already have been allocated. + * These operations are infallible, so required slots must be pre-allocated, + * or implementations must suppress out-of-memory errors. The native ops + * (js_ObjectOps, see jsobj.c) access slots reserved by including a call to + * the JSCLASS_HAS_RESERVED_SLOTS(n) macro in the JSClass.flags initializer. + * + * NB: the slot parameter is a zero-based index into obj->slots[], unlike the + * index parameter to the JS_GetReservedSlot and JS_SetReservedSlot API entry + * points, which is a zero-based index into the JSCLASS_RESERVED_SLOTS(clasp) + * reserved slots that come after the initial well-known slots: proto, parent, + * class, and optionally, the private data slot. + */ +typedef jsval +(* JS_DLL_CALLBACK JSGetRequiredSlotOp)(JSContext *cx, JSObject *obj, + uint32 slot); + +typedef void +(* JS_DLL_CALLBACK JSSetRequiredSlotOp)(JSContext *cx, JSObject *obj, + uint32 slot, jsval v); + +/* Typedef for native functions called by the JS VM. */ + +typedef JSBool +(* JS_DLL_CALLBACK JSNative)(JSContext *cx, JSObject *obj, uintN argc, + jsval *argv, jsval *rval); + +/* Callbacks and their arguments. */ + +typedef enum JSGCStatus { + JSGC_BEGIN, + JSGC_END, + JSGC_MARK_END, + JSGC_FINALIZE_END +} JSGCStatus; + +typedef JSBool +(* JS_DLL_CALLBACK JSGCCallback)(JSContext *cx, JSGCStatus status); + +typedef JSBool +(* JS_DLL_CALLBACK JSBranchCallback)(JSContext *cx, JSScript *script); + +typedef void +(* JS_DLL_CALLBACK JSErrorReporter)(JSContext *cx, const char *message, + JSErrorReport *report); + +typedef struct JSErrorFormatString { + const char *format; + uintN argCount; +} JSErrorFormatString; + +typedef const JSErrorFormatString * +(* JS_DLL_CALLBACK JSErrorCallback)(void *userRef, const char *locale, + const uintN errorNumber); + +#ifdef va_start +#define JS_ARGUMENT_FORMATTER_DEFINED 1 + +typedef JSBool +(* JS_DLL_CALLBACK JSArgumentFormatter)(JSContext *cx, const char *format, + JSBool fromJS, jsval **vpp, + va_list *app); +#endif + +typedef JSBool +(* JS_DLL_CALLBACK JSLocaleToUpperCase)(JSContext *cx, JSString *src, + jsval *rval); + +typedef JSBool +(* JS_DLL_CALLBACK JSLocaleToLowerCase)(JSContext *cx, JSString *src, + jsval *rval); + +typedef JSBool +(* JS_DLL_CALLBACK JSLocaleCompare)(JSContext *cx, + JSString *src1, JSString *src2, + jsval *rval); + +/* + * Security protocol types. + */ +typedef struct JSPrincipals JSPrincipals; + +/* + * XDR-encode or -decode a principals instance, based on whether xdr->mode is + * JSXDR_ENCODE, in which case *principalsp should be encoded; or JSXDR_DECODE, + * in which case implementations must return a held (via JSPRINCIPALS_HOLD), + * non-null *principalsp out parameter. Return true on success, false on any + * error, which the implementation must have reported. + */ +typedef JSBool +(* JS_DLL_CALLBACK JSPrincipalsTranscoder)(JSXDRState *xdr, + JSPrincipals **principalsp); + +/* + * Return a weak reference to the principals associated with obj, possibly via + * the immutable parent chain leading from obj to a top-level container (e.g., + * a window object in the DOM level 0). If there are no principals associated + * with obj, return null. Therefore null does not mean an error was reported; + * in no event should an error be reported or an exception be thrown by this + * callback's implementation. + */ +typedef JSPrincipals * +(* JS_DLL_CALLBACK JSObjectPrincipalsFinder)(JSContext *cx, JSObject *obj); + +JS_END_EXTERN_C + +#endif /* jspubtd_h___ */ diff --git a/src/extension/script/js/jsregexp.c b/src/extension/script/js/jsregexp.c new file mode 100644 index 000000000..18ab92c35 --- /dev/null +++ b/src/extension/script/js/jsregexp.c @@ -0,0 +1,3773 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* + * JS regular expressions, after Perl. + */ +#include "jsstddef.h" +#include +#include +#include "jstypes.h" +#include "jsarena.h" /* Added by JSIFY */ +#include "jsutil.h" /* Added by JSIFY */ +#include "jsapi.h" +#include "jsarray.h" +#include "jsatom.h" +#include "jscntxt.h" +#include "jsconfig.h" +#include "jsfun.h" +#include "jsgc.h" +#include "jsinterp.h" +#include "jslock.h" +#include "jsnum.h" +#include "jsobj.h" +#include "jsopcode.h" +#include "jsregexp.h" +#include "jsscan.h" +#include "jsstr.h" + +#ifdef XP_MAC +#include +#endif + +#if JS_HAS_REGEXPS + +/* Note : contiguity of 'simple opcodes' is important for simpleMatch() */ +typedef enum REOp { + REOP_EMPTY = 0, /* match rest of input against rest of r.e. */ + REOP_ALT = 1, /* alternative subexpressions in kid and next */ + REOP_SIMPLE_START = 2, /* start of 'simple opcodes' */ + REOP_BOL = 2, /* beginning of input (or line if multiline) */ + REOP_EOL = 3, /* end of input (or line if multiline) */ + REOP_WBDRY = 4, /* match "" at word boundary */ + REOP_WNONBDRY = 5, /* match "" at word non-boundary */ + REOP_DOT = 6, /* stands for any character */ + REOP_DIGIT = 7, /* match a digit char: [0-9] */ + REOP_NONDIGIT = 8, /* match a non-digit char: [^0-9] */ + REOP_ALNUM = 9, /* match an alphanumeric char: [0-9a-z_A-Z] */ + REOP_NONALNUM = 10, /* match a non-alphanumeric char: [^0-9a-z_A-Z] */ + REOP_SPACE = 11, /* match a whitespace char */ + REOP_NONSPACE = 12, /* match a non-whitespace char */ + REOP_BACKREF = 13, /* back-reference (e.g., \1) to a parenthetical */ + REOP_FLAT = 14, /* match a flat string */ + REOP_FLAT1 = 15, /* match a single char */ + REOP_FLATi = 16, /* case-independent REOP_FLAT */ + REOP_FLAT1i = 17, /* case-independent REOP_FLAT1 */ + REOP_UCFLAT1 = 18, /* single Unicode char */ + REOP_UCFLAT1i = 19, /* case-independent REOP_UCFLAT1 */ + REOP_UCFLAT = 20, /* flat Unicode string; len immediate counts chars */ + REOP_UCFLATi = 21, /* case-independent REOP_UCFLAT */ + REOP_CLASS = 22, /* character class with index */ + REOP_NCLASS = 23, /* negated character class with index */ + REOP_SIMPLE_END = 23, /* end of 'simple opcodes' */ + REOP_QUANT = 25, /* quantified atom: atom{1,2} */ + REOP_STAR = 26, /* zero or more occurrences of kid */ + REOP_PLUS = 27, /* one or more occurrences of kid */ + REOP_OPT = 28, /* optional subexpression in kid */ + REOP_LPAREN = 29, /* left paren bytecode: kid is u.num'th sub-regexp */ + REOP_RPAREN = 30, /* right paren bytecode */ + REOP_JUMP = 31, /* for deoptimized closure loops */ + REOP_DOTSTAR = 32, /* optimize .* to use a single opcode */ + REOP_ANCHOR = 33, /* like .* but skips left context to unanchored r.e. */ + REOP_EOLONLY = 34, /* $ not preceded by any pattern */ + REOP_BACKREFi = 37, /* case-independent REOP_BACKREF */ + REOP_LPARENNON = 41, /* non-capturing version of REOP_LPAREN */ + REOP_ASSERT = 43, /* zero width positive lookahead assertion */ + REOP_ASSERT_NOT = 44, /* zero width negative lookahead assertion */ + REOP_ASSERTTEST = 45, /* sentinel at end of assertion child */ + REOP_ASSERTNOTTEST = 46, /* sentinel at end of !assertion child */ + REOP_MINIMALSTAR = 47, /* non-greedy version of * */ + REOP_MINIMALPLUS = 48, /* non-greedy version of + */ + REOP_MINIMALOPT = 49, /* non-greedy version of ? */ + REOP_MINIMALQUANT = 50, /* non-greedy version of {} */ + REOP_ENDCHILD = 51, /* sentinel at end of quantifier child */ + REOP_REPEAT = 52, /* directs execution of greedy quantifier */ + REOP_MINIMALREPEAT = 53, /* directs execution of non-greedy quantifier */ + REOP_ALTPREREQ = 54, /* prerequisite for ALT, either of two chars */ + REOP_ALTPREREQ2 = 55, /* prerequisite for ALT, a char or a class */ + REOP_ENDALT = 56, /* end of final alternate */ + REOP_CONCAT = 57, /* concatenation of terms (parse time only) */ + + REOP_END +} REOp; + +#define REOP_IS_SIMPLE(op) (((op) >= REOP_SIMPLE_START) && ((op) <= REOP_SIMPLE_END)) + +struct RENode { + REOp op; /* r.e. op bytecode */ + RENode *next; /* next in concatenation order */ + void *kid; /* first operand */ + union { + void *kid2; /* second operand */ + jsint num; /* could be a number */ + jsint parenIndex; /* or a parenthesis index */ + struct { /* or a quantifier range */ + uint16 min; + uint16 max; + JSBool greedy; + } range; + struct { /* or a character class */ + uint16 startIndex; + uint16 kidlen; /* length of string at kid, in jschars */ + uint16 bmsize; /* bitmap size, based on max char code */ + uint16 index; /* index into class list */ + JSBool sense; + } ucclass; + struct { /* or a literal sequence */ + jschar chr; /* of one character */ + uint16 length; /* or many (via the kid) */ + } flat; + struct { + RENode *kid2; /* second operand from ALT */ + jschar ch1; /* match char for ALTPREREQ */ + jschar ch2; /* ditto, or class index for ALTPREREQ2 */ + } altprereq; + } u; +}; + +#define RE_IS_LETTER(c) ( ((c >= 'A') && (c <= 'Z')) || \ + ((c >= 'a') && (c <= 'z')) ) +#define RE_IS_LINE_TERM(c) ( (c == '\n') || (c == '\r') || \ + (c == LINE_SEPARATOR) || (c == PARA_SEPARATOR)) + +#define CLASS_CACHE_SIZE (4) +typedef struct CompilerState { + JSContext *context; + JSTokenStream *tokenStream; /* For reporting errors */ + const jschar *cpbegin; + const jschar *cpend; + const jschar *cp; + uintN flags; + uint16 parenCount; + uint16 classCount; /* number of [] encountered */ + size_t progLength; /* estimated bytecode length */ + uintN treeDepth; /* maximum depth of parse tree */ + RENode *result; + struct { + const jschar *start; /* small cache of class strings */ + uint16 length; /* since they're often the same */ + uint16 index; + } classCache[CLASS_CACHE_SIZE]; +} CompilerState; + +typedef struct RECapture { + int32 index; /* start of contents, -1 for empty */ + uint16 length; /* length of capture */ +} RECapture; + +typedef struct REMatchState { + const jschar *cp; + RECapture parens[1]; /* first of 're->parenCount' captures, + * allocated at end of this struct. + */ +} REMatchState; + +struct REBackTrackData; + +typedef struct REProgState { + jsbytecode *continue_pc; /* current continuation data */ + jsbytecode continue_op; + uint16 index; /* progress in text */ + uintN parenSoFar; /* highest indexed paren started */ + union { + struct { + uint16 min; /* current quantifier limits */ + uint16 max; + } quantifier; + struct { + size_t top; /* backtrack stack state */ + size_t sz; + } assertion; + } u; +} REProgState; + +typedef struct REBackTrackData { + size_t sz; /* size of previous stack entry */ + jsbytecode *backtrack_pc; /* where to backtrack to */ + jsbytecode backtrack_op; + const jschar *cp; /* index in text of match at backtrack */ + intN parenIndex; /* start index of saved paren contents */ + uint16 parenCount; /* # of saved paren contents */ + uint16 precedingStateTop; /* number of parent states */ + /* saved parent states follow */ + /* saved paren contents follow */ +} REBackTrackData; + +#define INITIAL_STATESTACK (100) +#define INITIAL_BACKTRACK (8000) + +typedef struct REGlobalData { + JSContext *cx; + JSRegExp *regexp; /* the RE in execution */ + JSBool ok; /* runtime error (out_of_memory only?) */ + size_t start; /* offset to start at */ + ptrdiff_t skipped; /* chars skipped anchoring this r.e. */ + const jschar *cpbegin, *cpend; /* text base address and limit */ + + REProgState *stateStack; /* stack of state of current parents */ + uint16 stateStackTop; + uint16 maxStateStack; + + REBackTrackData *backTrackStack;/* stack of matched-so-far positions */ + REBackTrackData *backTrackSP; + size_t maxBackTrack; + size_t cursz; /* size of current stack entry */ + + JSArenaPool pool; /* I don't understand but it's faster to + * use this than to malloc/free the three + * items that are allocated from this pool + */ + +} REGlobalData; + + +/* + * 1. If IgnoreCase is false, return ch. + * 2. Let u be ch converted to upper case as if by calling + * String.prototype.toUpperCase on the one-character string ch. + * 3. If u does not consist of a single character, return ch. + * 4. Let cu be u's character. + * 5. If ch's code point value is greater than or equal to decimal 128 and cu's + * code point value is less than decimal 128, then return ch. + * 6. Return cu. + */ +static jschar +upcase(jschar ch) +{ + jschar cu = JS_TOUPPER(ch); + if ((ch >= 128) && (cu < 128)) return ch; + return cu; +} + +static jschar +downcase(jschar ch) +{ + jschar cl = JS_TOLOWER(ch); + if ((cl >= 128) && (ch < 128)) return ch; + return cl; +} + +/* Construct and initialize an RENode, returning NULL for out-of-memory */ +static RENode * +NewRENode(CompilerState *state, REOp op) +{ + JSContext *cx; + RENode *ren; + + cx = state->context; + JS_ARENA_ALLOCATE_CAST(ren, RENode *, &cx->tempPool, sizeof *ren); + if (!ren) { + JS_ReportOutOfMemory(cx); + return NULL; + } + ren->op = op; + ren->next = NULL; + ren->kid = NULL; + return ren; +} + +/* + * Validates and converts hex ascii value. + */ +static JSBool +isASCIIHexDigit(jschar c, uintN *digit) +{ + uintN cv = c; + + if (cv < '0') + return JS_FALSE; + if (cv <= '9') { + *digit = cv - '0'; + return JS_TRUE; + } + cv |= 0x20; + if (cv >= 'a' && cv <= 'f') { + *digit = cv - 'a' + 10; + return JS_TRUE; + } + return JS_FALSE; +} + + +typedef struct { + REOp op; + const jschar *errPos; + uint16 parenIndex; +} REOpData; + + +/* + * Process the op against the two top operands, reducing them to a single + * operand in the penultimate slot. Update progLength and treeDepth. + */ +static JSBool +processOp(CompilerState *state, REOpData *opData, RENode **operandStack, intN operandSP) +{ + RENode *result; + + switch (opData->op) { + case REOP_ALT: + result = NewRENode(state, REOP_ALT); + if (!result) + return JS_FALSE; + result->kid = operandStack[operandSP - 2]; + result->u.kid2 = operandStack[operandSP - 1]; + operandStack[operandSP - 2] = result; + /* + * look at both alternates to see if there's a FLAT or a CLASS at + * the start of each. If so, use a prerequisite match + */ + ++state->treeDepth; + if ((((RENode *)(result->kid))->op == REOP_FLAT) + && (((RENode *)(result->u.kid2))->op == REOP_FLAT) + && ((state->flags & JSREG_FOLD) == 0) ) { + result->op = REOP_ALTPREREQ; + result->u.altprereq.ch1 + = ((RENode *)(result->kid))->u.flat.chr; + result->u.altprereq.ch2 + = ((RENode *)(result->u.kid2))->u.flat.chr; + /* ALTPREREQ, , uch1, uch2, , ..., + JUMP, ... ENDALT */ + state->progLength += 13; + } + else + if ((((RENode *)(result->kid))->op == REOP_CLASS) + && (((RENode *)(result->kid))->u.ucclass.index < 256) + && (((RENode *)(result->u.kid2))->op == REOP_FLAT) + && ((state->flags & JSREG_FOLD) == 0) ) { + result->op = REOP_ALTPREREQ2; + result->u.altprereq.ch1 + = ((RENode *)(result->u.kid2))->u.flat.chr; + result->u.altprereq.ch2 + = ((RENode *)(result->kid))->u.ucclass.index; + /* ALTPREREQ2, , uch1, uch2, , ..., + JUMP, ... ENDALT */ + state->progLength += 13; + } + else + if ((((RENode *)(result->kid))->op == REOP_FLAT) + && (((RENode *)(result->u.kid2))->op == REOP_CLASS) + && (((RENode *)(result->u.kid2))->u.ucclass.index < 256) + && ((state->flags & JSREG_FOLD) == 0) ) { + result->op = REOP_ALTPREREQ2; + result->u.altprereq.ch1 + = ((RENode *)(result->kid))->u.flat.chr; + result->u.altprereq.ch2 + = ((RENode *)(result->u.kid2))->u.ucclass.index; + /* ALTPREREQ2, , uch1, uch2, , ..., + JUMP, ... ENDALT */ + state->progLength += 13; + } + else + /* ALT, , ..., JUMP, ... ENDALT */ + state->progLength += 7; + break; + case REOP_CONCAT: + result = operandStack[operandSP - 2]; + while (result->next) + result = result->next; + result->next = operandStack[operandSP - 1]; + break; + case REOP_ASSERT: + case REOP_ASSERT_NOT: + case REOP_LPARENNON: + case REOP_LPAREN: + /* These should have been processed by a close paren. */ + js_ReportCompileErrorNumber(state->context, state->tokenStream, + NULL, JSREPORT_ERROR, + JSMSG_MISSING_PAREN, opData->errPos); + return JS_FALSE; + default:; + } + return JS_TRUE; +} + +/* + * Parser forward declarations. + */ +static JSBool parseTerm(CompilerState *state); +static JSBool parseQuantifier(CompilerState *state); + +/* + * Top-down regular expression grammar, based closely on Perl4. + * + * regexp: altern A regular expression is one or more + * altern '|' regexp alternatives separated by vertical bar. + */ + +#define INITIAL_STACK_SIZE (128) +static JSBool +parseRegExp(CompilerState *state) +{ + uint16 parenIndex; + RENode *operand; + REOpData *operatorStack; + RENode **operandStack; + REOp op; + intN i; + JSBool result = JS_FALSE; + + intN operatorSP = 0, operatorStackSize = INITIAL_STACK_SIZE; + intN operandSP = 0, operandStackSize = INITIAL_STACK_SIZE; + + /* Watch out for empty regexp */ + if (state->cp == state->cpend) { + state->result = NewRENode(state, REOP_EMPTY); + return (state->result != NULL); + } + + operatorStack = (REOpData *)JS_malloc(state->context, + sizeof(REOpData) * operatorStackSize); + if (!operatorStack) + return JS_FALSE; + + operandStack = (RENode **)JS_malloc(state->context, + sizeof(RENode *) * operandStackSize); + if (!operandStack) + goto out; + + + while (JS_TRUE) { + if (state->cp == state->cpend) { + /* + * If we are at the end of the regexp and we're short an operand, + * the regexp must have the form /x|/ or some such. + */ + if (operatorSP == operandSP) { + operand = NewRENode(state, REOP_EMPTY); + if (!operand) + goto out; + goto pushOperand; + } + } else { + switch (*state->cp) { + /* balance '(' */ + case '(': /* balance ')' */ + ++state->cp; + if ((state->cp < state->cpend) && (*state->cp == '?') + && ( (state->cp[1] == '=') + || (state->cp[1] == '!') + || (state->cp[1] == ':') )) { + ++state->cp; + if (state->cp == state->cpend) { + js_ReportCompileErrorNumber(state->context, + state->tokenStream, + NULL, JSREPORT_ERROR, + JSMSG_MISSING_PAREN); + goto out; + } + switch (*state->cp++) { + case '=': + op = REOP_ASSERT; + /* ASSERT, , ... ASSERTTEST */ + state->progLength += 4; + break; + case '!': + op = REOP_ASSERT_NOT; + /* ASSERTNOT, , ... ASSERTNOTTEST */ + state->progLength += 4; + break; + case ':': + op = REOP_LPARENNON; + break; + } + parenIndex = state->parenCount; + } + else { + op = REOP_LPAREN; + /* LPAREN, , ... RPAREN, */ + state->progLength += 6; + parenIndex = state->parenCount++; + if (state->parenCount == 65535) { + js_ReportCompileErrorNumber(state->context, + state->tokenStream, + NULL, JSREPORT_ERROR, + JSMSG_TOO_MANY_PARENS); + goto out; + } + } + goto pushOperator; + case ')': + /* If there's not a stacked open parenthesis, throw + * a syntax error. + */ + for (i = operatorSP - 1; i >= 0; i--) + if ((operatorStack[i].op == REOP_ASSERT) + || (operatorStack[i].op == REOP_ASSERT_NOT) + || (operatorStack[i].op == REOP_LPARENNON) + || (operatorStack[i].op == REOP_LPAREN)) + break; + if (i == -1) { + js_ReportCompileErrorNumber(state->context, + state->tokenStream, + NULL, JSREPORT_ERROR, + JSMSG_UNMATCHED_RIGHT_PAREN); + goto out; + } + /* fall thru... */ + case '|': + /* Expected an operand before these, so make an empty one */ + operand = NewRENode(state, REOP_EMPTY); + if (!operand) + goto out; + goto pushOperand; + default: + if (!parseTerm(state)) + goto out; + operand = state->result; +pushOperand: + if (operandSP == operandStackSize) { + operandStackSize += operandStackSize; + operandStack = + (RENode **)JS_realloc(state->context, operandStack, + sizeof(RENode *) * operandStackSize); + if (!operandStack) + goto out; + } + operandStack[operandSP++] = operand; + break; + } + } + /* At the end; process remaining operators */ +restartOperator: + if (state->cp == state->cpend) { + while (operatorSP) { + --operatorSP; + if (!processOp(state, &operatorStack[operatorSP], + operandStack, operandSP)) + goto out; + --operandSP; + } + JS_ASSERT(operandSP == 1); + state->result = operandStack[0]; + result = JS_TRUE; + goto out; + } + switch (*state->cp) { + case '|': + /* Process any stacked 'concat' operators */ + ++state->cp; + while (operatorSP + && (operatorStack[operatorSP - 1].op == REOP_CONCAT)) { + --operatorSP; + if (!processOp(state, &operatorStack[operatorSP], + operandStack, operandSP)) + goto out; + --operandSP; + } + op = REOP_ALT; + goto pushOperator; + + case ')': + /* If there's not a stacked open parenthesis,we + * accept the close as a flat. + */ + for (i = operatorSP - 1; i >= 0; i--) + if ((operatorStack[i].op == REOP_ASSERT) + || (operatorStack[i].op == REOP_ASSERT_NOT) + || (operatorStack[i].op == REOP_LPARENNON) + || (operatorStack[i].op == REOP_LPAREN)) + break; + if (i == -1) { + js_ReportCompileErrorNumber(state->context, + state->tokenStream, + NULL, JSREPORT_ERROR, + JSMSG_UNMATCHED_RIGHT_PAREN); + goto out; + } + ++state->cp; + /* process everything on the stack until the open */ + while (JS_TRUE) { + JS_ASSERT(operatorSP); + --operatorSP; + switch (operatorStack[operatorSP].op) { + case REOP_ASSERT: + case REOP_ASSERT_NOT: + case REOP_LPAREN: + operand = NewRENode(state, operatorStack[operatorSP].op); + if (!operand) + goto out; + operand->u.parenIndex + = operatorStack[operatorSP].parenIndex; + JS_ASSERT(operandSP); + operand->kid = operandStack[operandSP - 1]; + operandStack[operandSP - 1] = operand; + ++state->treeDepth; + /* fall thru... */ + case REOP_LPARENNON: + state->result = operandStack[operandSP - 1]; + if (!parseQuantifier(state)) + goto out; + operandStack[operandSP - 1] = state->result; + goto restartOperator; + default: + if (!processOp(state, &operatorStack[operatorSP], + operandStack, operandSP)) + goto out; + --operandSP; + break; + } + } + break; + default: + /* Anything else is the start of the next term */ + op = REOP_CONCAT; +pushOperator: + if (operatorSP == operatorStackSize) { + operatorStackSize += operatorStackSize; + operatorStack = + (REOpData *)JS_realloc(state->context, operatorStack, + sizeof(REOpData) * operatorStackSize); + if (!operatorStack) + goto out; + } + operatorStack[operatorSP].op = op; + operatorStack[operatorSP].errPos = state->cp; + operatorStack[operatorSP++].parenIndex = parenIndex; + break; + } + } +out: + if (operatorStack) + JS_free(state->context, operatorStack); + if (operandStack) + JS_free(state->context, operandStack); + return result; +} + +/* + * Extract and return a decimal value at state->cp, the + * initial character 'c' has already been read. + */ +static intN +getDecimalValue(jschar c, CompilerState *state) +{ + intN value = JS7_UNDEC(c); + while (state->cp < state->cpend) { + c = *state->cp; + if (!JS7_ISDEC(c)) + break; + value = (10 * value) + JS7_UNDEC(c); + ++state->cp; + } + return value; +} + +/* + * Calculate the total size of the bitmap required for a class expression. + */ +static JSBool +calculateBitmapSize(CompilerState *state, RENode *target, const jschar *src, + const jschar *end) +{ + jschar rangeStart, c; + uintN n, digit, nDigits, i; + uintN max = 0; + JSBool inRange = JS_FALSE; + + target->u.ucclass.bmsize = 0; + target->u.ucclass.sense = JS_TRUE; + + if (src == end) + return JS_TRUE; + + if (*src == '^') { + ++src; + target->u.ucclass.sense = JS_FALSE; + } + + while (src != end) { + uintN localMax = 0; + switch (*src) { + case '\\': + ++src; + c = *src++; + switch (c) { + case 'b': + localMax = 0x8; + break; + case 'f': + localMax = 0xC; + break; + case 'n': + localMax = 0xA; + break; + case 'r': + localMax = 0xD; + break; + case 't': + localMax = 0x9; + break; + case 'v': + localMax = 0xB; + break; + case 'c': + if (((src + 1) < end) && RE_IS_LETTER(src[1])) + localMax = (jschar)(*src++ & 0x1F); + else + localMax = '\\'; + break; + case 'x': + nDigits = 2; + goto lexHex; + case 'u': + nDigits = 4; +lexHex: + n = 0; + for (i = 0; (i < nDigits) && (src < end); i++) { + c = *src++; + if (!isASCIIHexDigit(c, &digit)) { + /* + * Back off to accepting the original + *'\' as a literal. + */ + src -= (i + 1); + n = '\\'; + break; + } + n = (n << 4) | digit; + } + localMax = n; + break; + case 'd': + if (inRange) { + JS_ReportErrorNumber(state->context, + js_GetErrorMessage, NULL, + JSMSG_BAD_CLASS_RANGE); + return JS_FALSE; + } + localMax = '9'; + break; + case 'D': + case 's': + case 'S': + case 'w': + case 'W': + if (inRange) { + JS_ReportErrorNumber(state->context, + js_GetErrorMessage, NULL, + JSMSG_BAD_CLASS_RANGE); + return JS_FALSE; + } + target->u.ucclass.bmsize = 65535; + return JS_TRUE; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + /* + * This is a non-ECMA extension - decimal escapes (in this + * case, octal!) are supposed to be an error inside class + * ranges, but supported here for backwards compatibility. + * + */ + n = JS7_UNDEC(c); + c = *src; + if ('0' <= c && c <= '7') { + src++; + n = 8 * n + JS7_UNDEC(c); + c = *src; + if ('0' <= c && c <= '7') { + src++; + i = 8 * n + JS7_UNDEC(c); + if (i <= 0377) + n = i; + else + src--; + } + } + localMax = n; + break; + + default: + localMax = c; + break; + } + break; + default: + localMax = *src++; + break; + } + if (inRange) { + if (rangeStart > localMax) { + JS_ReportErrorNumber(state->context, + js_GetErrorMessage, NULL, + JSMSG_BAD_CLASS_RANGE); + return JS_FALSE; + } + inRange = JS_FALSE; + } + else { + if (src < (end - 1)) { + if (*src == '-') { + ++src; + inRange = JS_TRUE; + rangeStart = (jschar)localMax; + continue; + } + } + } + if (state->flags & JSREG_FOLD) { + c = JS_MAX(upcase((jschar)localMax), downcase((jschar)localMax)); + if (c > localMax) + localMax = c; + } + if (localMax > max) + max = localMax; + } + target->u.ucclass.bmsize = max; + return JS_TRUE; +} + +/* + * item: assertion An item is either an assertion or + * quantatom a quantified atom. + * + * assertion: '^' Assertions match beginning of string + * (or line if the class static property + * RegExp.multiline is true). + * '$' End of string (or line if the class + * static property RegExp.multiline is + * true). + * '\b' Word boundary (between \w and \W). + * '\B' Word non-boundary. + * + * quantatom: atom An unquantified atom. + * quantatom '{' n ',' m '}' + * Atom must occur between n and m times. + * quantatom '{' n ',' '}' Atom must occur at least n times. + * quantatom '{' n '}' Atom must occur exactly n times. + * quantatom '*' Zero or more times (same as {0,}). + * quantatom '+' One or more times (same as {1,}). + * quantatom '?' Zero or one time (same as {0,1}). + * + * any of which can be optionally followed by '?' for ungreedy + * + * atom: '(' regexp ')' A parenthesized regexp (what matched + * can be addressed using a backreference, + * see '\' n below). + * '.' Matches any char except '\n'. + * '[' classlist ']' A character class. + * '[' '^' classlist ']' A negated character class. + * '\f' Form Feed. + * '\n' Newline (Line Feed). + * '\r' Carriage Return. + * '\t' Horizontal Tab. + * '\v' Vertical Tab. + * '\d' A digit (same as [0-9]). + * '\D' A non-digit. + * '\w' A word character, [0-9a-z_A-Z]. + * '\W' A non-word character. + * '\s' A whitespace character, [ \b\f\n\r\t\v]. + * '\S' A non-whitespace character. + * '\' n A backreference to the nth (n decimal + * and positive) parenthesized expression. + * '\' octal An octal escape sequence (octal must be + * two or three digits long, unless it is + * 0 for the null character). + * '\x' hex A hex escape (hex must be two digits). + * '\u' unicode A unicode escape (must be four digits). + * '\c' ctrl A control character, ctrl is a letter. + * '\' literalatomchar Any character except one of the above + * that follow '\' in an atom. + * otheratomchar Any character not first among the other + * atom right-hand sides. + */ +static JSBool +parseTerm(CompilerState *state) +{ + jschar c = *state->cp++; + uintN nDigits; + uintN num, tmp, n, i; + const jschar *termStart; + JSBool foundCachedCopy; + + switch (c) { + /* assertions and atoms */ + case '^': + state->result = NewRENode(state, REOP_BOL); + if (!state->result) + return JS_FALSE; + state->progLength++; + return JS_TRUE; + case '$': + state->result = NewRENode(state, REOP_EOL); + if (!state->result) + return JS_FALSE; + state->progLength++; + return JS_TRUE; + case '\\': + if (state->cp >= state->cpend) { + /* a trailing '\' is an error */ + js_ReportCompileErrorNumber(state->context, state->tokenStream, + NULL, JSREPORT_ERROR, + JSMSG_TRAILING_SLASH); + return JS_FALSE; + } + c = *state->cp++; + switch (c) { + /* assertion escapes */ + case 'b' : + state->result = NewRENode(state, REOP_WBDRY); + if (!state->result) + return JS_FALSE; + state->progLength++; + return JS_TRUE; + case 'B': + state->result = NewRENode(state, REOP_WNONBDRY); + if (!state->result) + return JS_FALSE; + state->progLength++; + return JS_TRUE; + /* Decimal escape */ + case '0': + if (JS_HAS_STRICT_OPTION(state->context)) + c = 0; + else { + doOctal: + num = 0; + while (state->cp < state->cpend) { + if ('0' <= (c = *state->cp) && c <= '7') { + state->cp++; + tmp = 8 * num + (uintN)JS7_UNDEC(c); + if (tmp > 0377) + break; + num = tmp; + } + else + break; + } + c = (jschar)(num); + } + doFlat: + state->result = NewRENode(state, REOP_FLAT); + if (!state->result) + return JS_FALSE; + state->result->u.flat.chr = c; + state->result->u.flat.length = 1; + state->progLength += 3; + break; + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + termStart = state->cp - 1; + num = (uintN)getDecimalValue(c, state); + if (num > 9 && + num > state->parenCount && + !JS_HAS_STRICT_OPTION(state->context)) { + state->cp = termStart; + goto doOctal; + } + state->result = NewRENode(state, REOP_BACKREF); + if (!state->result) + return JS_FALSE; + state->result->u.parenIndex = num - 1; + state->progLength += 3; + break; + /* Control escape */ + case 'f': + c = 0xC; + goto doFlat; + case 'n': + c = 0xA; + goto doFlat; + case 'r': + c = 0xD; + goto doFlat; + case 't': + c = 0x9; + goto doFlat; + case 'v': + c = 0xB; + goto doFlat; + /* Control letter */ + case 'c': + if (((state->cp + 1) < state->cpend) && + RE_IS_LETTER(state->cp[1])) + c = (jschar)(*state->cp++ & 0x1F); + else { + /* back off to accepting the original '\' as a literal */ + --state->cp; + c = '\\'; + } + goto doFlat; + /* HexEscapeSequence */ + case 'x': + nDigits = 2; + goto lexHex; + /* UnicodeEscapeSequence */ + case 'u': + nDigits = 4; +lexHex: + n = 0; + for (i = 0; (i < nDigits) + && (state->cp < state->cpend); i++) { + uintN digit; + c = *state->cp++; + if (!isASCIIHexDigit(c, &digit)) { + /* + * back off to accepting the original + * 'u' or 'x' as a literal + */ + state->cp -= (i + 2); + n = *state->cp++; + break; + } + n = (n << 4) | digit; + } + c = (jschar)(n); + goto doFlat; + /* Character class escapes */ + case 'd': + state->result = NewRENode(state, REOP_DIGIT); +doSimple: + if (!state->result) + return JS_FALSE; + state->progLength++; + break; + case 'D': + state->result = NewRENode(state, REOP_NONDIGIT); + goto doSimple; + case 's': + state->result = NewRENode(state, REOP_SPACE); + goto doSimple; + case 'S': + state->result = NewRENode(state, REOP_NONSPACE); + goto doSimple; + case 'w': + state->result = NewRENode(state, REOP_ALNUM); + goto doSimple; + case 'W': + state->result = NewRENode(state, REOP_NONALNUM); + goto doSimple; + /* IdentityEscape */ + default: + state->result = NewRENode(state, REOP_FLAT); + if (!state->result) + return JS_FALSE; + state->result->u.flat.chr = c; + state->result->u.flat.length = 1; + state->result->kid = (void *)(state->cp - 1); + state->progLength += 3; + break; + } + break; + case '[': + state->result = NewRENode(state, REOP_CLASS); + if (!state->result) + return JS_FALSE; + termStart = state->cp; + state->result->u.ucclass.startIndex = termStart - state->cpbegin; + while (JS_TRUE) { + if (state->cp == state->cpend) { + js_ReportCompileErrorNumber(state->context, state->tokenStream, + NULL, JSREPORT_ERROR, + JSMSG_UNTERM_CLASS, termStart); + return JS_FALSE; + } + if (*state->cp == '\\') + state->cp++; + else { + if (*state->cp == ']') { + state->result->u.ucclass.kidlen = state->cp - termStart; + break; + } + } + state->cp++; + } + foundCachedCopy = JS_FALSE; + for (i = 0; i < CLASS_CACHE_SIZE; i++) { + if (state->classCache[i].start) { + if (state->classCache[i].length == state->result->u.ucclass.kidlen) { + foundCachedCopy = JS_TRUE; + for (n = 0; n < state->classCache[i].length; n++) { + if (state->classCache[i].start[n] != termStart[n]) { + foundCachedCopy = JS_FALSE; + break; + } + } + if (foundCachedCopy) { + state->result->u.ucclass.index = state->classCache[i].index; + break; + } + } + } + else { + state->classCache[i].start = termStart; + state->classCache[i].length = state->result->u.ucclass.kidlen; + state->classCache[i].index = state->classCount; + break; + } + } + if (!foundCachedCopy) + state->result->u.ucclass.index = state->classCount++; + /* + * Call calculateBitmapSize now as we want any errors it finds + * to be reported during the parse phase, not at execution. + */ + if (!calculateBitmapSize(state, state->result, termStart, state->cp++)) + return JS_FALSE; + state->progLength += 3; /* CLASS, */ + break; + + case '.': + state->result = NewRENode(state, REOP_DOT); + goto doSimple; + case '*': + case '+': + case '?': + js_ReportCompileErrorNumber(state->context, state->tokenStream, + NULL, JSREPORT_ERROR, + JSMSG_BAD_QUANTIFIER, state->cp - 1); + return JS_FALSE; +#if 0 + case '{': /* balance '}' */ + /* Treat left-curly in a non-quantifier context as an error only + * if it's followed immediately by a decimal digit. + * This is an Perl extension. + */ + if ((state->cp != state->cpend) && JS7_ISDEC(*state->cp)) { + js_ReportCompileErrorNumber(state->context, state->tokenStream, + NULL, JSREPORT_ERROR, + JSMSG_BAD_QUANTIFIER, state->cp - 1); + return JS_FALSE; + } + /* fall thru... */ +#endif + default: + state->result = NewRENode(state, REOP_FLAT); + if (!state->result) + return JS_FALSE; + state->result->u.flat.chr = c; + state->result->u.flat.length = 1; + state->result->kid = (void *)(state->cp - 1); + state->progLength += 3; + break; + } + return parseQuantifier(state); +} + +static JSBool +parseQuantifier(CompilerState *state) +{ + RENode *term; + term = state->result; + if (state->cp < state->cpend) { + switch (*state->cp) { + case '+': + state->result = NewRENode(state, REOP_QUANT); + if (!state->result) + return JS_FALSE; + state->result->u.range.min = 1; + state->result->u.range.max = -1; + /* , ... */ + state->progLength += 4; + goto quantifier; + case '*': + state->result = NewRENode(state, REOP_QUANT); + if (!state->result) + return JS_FALSE; + state->result->u.range.min = 0; + state->result->u.range.max = -1; + /* , ... */ + state->progLength += 4; + goto quantifier; + case '?': + state->result = NewRENode(state, REOP_QUANT); + if (!state->result) + return JS_FALSE; + state->result->u.range.min = 0; + state->result->u.range.max = 1; + /* , ... */ + state->progLength += 4; + goto quantifier; + case '{': /* balance '}' */ + { + intN err; + intN min = 0; + intN max = -1; + jschar c; + const jschar *errp = state->cp++; + + c = *state->cp; + if (JS7_ISDEC(c)) { + ++state->cp; + min = getDecimalValue(c, state); + c = *state->cp; + + if ((min + 1) >> 16) { + err = JSMSG_MIN_TOO_BIG; + goto quantError; + } + if (c == ',') { + c = *++state->cp; + if (JS7_ISDEC(c)) { + ++state->cp; + max = getDecimalValue(c, state); + c = *state->cp; + if ((max + 1) >> 16) { + err = JSMSG_MAX_TOO_BIG; + goto quantError; + } + if (min > max) { + err = JSMSG_OUT_OF_ORDER; + goto quantError; + } + } + } + else { + max = min; + } + if (c == '}') { + state->result = NewRENode(state, REOP_QUANT); + if (!state->result) + return JS_FALSE; + state->result->u.range.min = min; + state->result->u.range.max = max; + /* QUANT, , , ... */ + state->progLength += 8; + goto quantifier; + } + } + state->cp = errp; + return JS_TRUE; +quantError: + js_ReportCompileErrorNumber(state->context, + state->tokenStream, + NULL, JSREPORT_ERROR, + err, errp); + return JS_FALSE; + } + } + } + return JS_TRUE; + +quantifier: + ++state->treeDepth; + ++state->cp; + state->result->kid = term; + if ((state->cp < state->cpend) && (*state->cp == '?')) { + ++state->cp; + state->result->u.range.greedy = JS_FALSE; + } + else + state->result->u.range.greedy = JS_TRUE; + return JS_TRUE; +} + +#define CHECK_OFFSET(diff) (JS_ASSERT(((diff) >= -32768) && ((diff) <= 32767))) +#define SET_OFFSET(pc,off) ((pc)[0] = JUMP_OFFSET_HI(off), \ + (pc)[1] = JUMP_OFFSET_LO(off)) +#define GET_OFFSET(pc) ((int16)(((pc)[0] << 8) | (pc)[1])) +#define OFFSET_LEN (2) +#define GET_ARG(pc) GET_OFFSET(pc) +#define SET_ARG(pc,arg) SET_OFFSET(pc,arg) +#define ARG_LEN OFFSET_LEN + +/* + * Recursively generate bytecode for the tree rooted at t. Iteratively. + */ + +typedef struct { + RENode *nextAlt; + jsbytecode *nextAltFixup, *nextTermFixup, *endTermFixup; + RENode *continueNode; + REOp continueOp; +} EmitStateStackEntry; + +static jsbytecode * +emitREBytecode(CompilerState *state, JSRegExp *re, intN treeDepth, + jsbytecode *pc, RENode *t) +{ + ptrdiff_t diff; + RECharSet *charSet; + EmitStateStackEntry *emitStateSP, *emitStateStack = NULL; + REOp op; + + if (treeDepth) { + emitStateStack = + (EmitStateStackEntry *)JS_malloc(state->context, + sizeof(EmitStateStackEntry) + * treeDepth); + if (!emitStateStack) + return NULL; + } + emitStateSP = emitStateStack; + op = t->op; + + while (JS_TRUE) { + *pc++ = op; + switch (op) { + case REOP_EMPTY: + --pc; + break; + + case REOP_ALTPREREQ2: + case REOP_ALTPREREQ: + JS_ASSERT(emitStateSP); + emitStateSP->endTermFixup = pc; + pc += OFFSET_LEN; + SET_ARG(pc, t->u.altprereq.ch1); + pc += ARG_LEN; + SET_ARG(pc, t->u.altprereq.ch2); + pc += ARG_LEN; + + emitStateSP->nextAltFixup = pc; /* address of next alternate */ + pc += OFFSET_LEN; + + emitStateSP->continueNode = t; + emitStateSP->continueOp = REOP_JUMP; + ++emitStateSP; + JS_ASSERT((emitStateSP - emitStateStack) <= treeDepth); + t = (RENode *)(t->kid); + op = t->op; + continue; + + case REOP_JUMP: + emitStateSP->nextTermFixup = pc; /* address of following term */ + pc += OFFSET_LEN; + diff = pc - emitStateSP->nextAltFixup; + CHECK_OFFSET(diff); + SET_OFFSET(emitStateSP->nextAltFixup, diff); + emitStateSP->continueOp = REOP_ENDALT; + ++emitStateSP; + JS_ASSERT((emitStateSP - emitStateStack) <= treeDepth); + t = (RENode *)(t->u.kid2); + op = t->op; + continue; + + case REOP_ENDALT: + diff = pc - emitStateSP->nextTermFixup; + CHECK_OFFSET(diff); + SET_OFFSET(emitStateSP->nextTermFixup, diff); + if (t->op != REOP_ALT) { + diff = pc - emitStateSP->endTermFixup; + CHECK_OFFSET(diff); + SET_OFFSET(emitStateSP->endTermFixup, diff); + } + break; + + case REOP_ALT: + JS_ASSERT(emitStateSP); + emitStateSP->nextAltFixup = pc; /* address of pointer to next alternate */ + pc += OFFSET_LEN; + emitStateSP->continueNode = t; + emitStateSP->continueOp = REOP_JUMP; + ++emitStateSP; + JS_ASSERT((emitStateSP - emitStateStack) <= treeDepth); + t = (RENode *)(t->kid); + op = t->op; + continue; + + case REOP_FLAT: + /* + * Consecutize FLAT's if possible. + */ + if (t->kid) { + while (t->next && (t->next->op == REOP_FLAT) + && (((jschar*)(t->kid) + t->u.flat.length) + == (jschar*)(t->next->kid))) { + t->u.flat.length += t->next->u.flat.length; + t->next = t->next->next; + } + } + if (t->kid && (t->u.flat.length > 1)) { + if (state->flags & JSREG_FOLD) + pc[-1] = REOP_FLATi; + else + pc[-1] = REOP_FLAT; + SET_ARG(pc, (jschar *)(t->kid) - state->cpbegin); + pc += ARG_LEN; + SET_ARG(pc, t->u.flat.length); + pc += ARG_LEN; + } + else { + if (t->u.flat.chr < 256) { + if (state->flags & JSREG_FOLD) + pc[-1] = REOP_FLAT1i; + else + pc[-1] = REOP_FLAT1; + *pc++ = (jsbytecode)(t->u.flat.chr); + } + else { + if (state->flags & JSREG_FOLD) + pc[-1] = REOP_UCFLAT1i; + else + pc[-1] = REOP_UCFLAT1; + SET_ARG(pc, t->u.flat.chr); + pc += ARG_LEN; + } + } + break; + + case REOP_LPAREN: + JS_ASSERT(emitStateSP); + SET_ARG(pc, t->u.parenIndex); + pc += ARG_LEN; + emitStateSP->continueNode = t; + emitStateSP->continueOp = REOP_RPAREN; + ++emitStateSP; + JS_ASSERT((emitStateSP - emitStateStack) <= treeDepth); + t = (RENode *)(t->kid); + op = t->op; + continue; + case REOP_RPAREN: + SET_ARG(pc, t->u.parenIndex); + pc += ARG_LEN; + break; + + case REOP_BACKREF: + SET_ARG(pc, t->u.parenIndex); + pc += ARG_LEN; + break; + case REOP_ASSERT: + JS_ASSERT(emitStateSP); + emitStateSP->nextTermFixup = pc; + pc += OFFSET_LEN; + emitStateSP->continueNode = t; + emitStateSP->continueOp = REOP_ASSERTTEST; + ++emitStateSP; + JS_ASSERT((emitStateSP - emitStateStack) <= treeDepth); + t = (RENode *)(t->kid); + op = t->op; + continue; + case REOP_ASSERTTEST: + case REOP_ASSERTNOTTEST: + diff = pc - emitStateSP->nextTermFixup; + CHECK_OFFSET(diff); + SET_OFFSET(emitStateSP->nextTermFixup, diff); + break; + case REOP_ASSERT_NOT: + JS_ASSERT(emitStateSP); + emitStateSP->nextTermFixup = pc; + pc += OFFSET_LEN; + emitStateSP->continueNode = t; + emitStateSP->continueOp = REOP_ASSERTNOTTEST; + ++emitStateSP; + JS_ASSERT((emitStateSP - emitStateStack) <= treeDepth); + t = (RENode *)(t->kid); + op = t->op; + continue; + case REOP_QUANT: + JS_ASSERT(emitStateSP); + if ((t->u.range.min == 0) && (t->u.range.max == (uint16)(-1))) + pc[-1] = (t->u.range.greedy) ? REOP_STAR : REOP_MINIMALSTAR; + else + if ((t->u.range.min == 0) && (t->u.range.max == 1)) + pc[-1] = (t->u.range.greedy) ? REOP_OPT : REOP_MINIMALOPT; + else + if ((t->u.range.min == 1) && (t->u.range.max == (uint16)(-1))) + pc[-1] = (t->u.range.greedy) ? REOP_PLUS : REOP_MINIMALPLUS; + else { + if (!t->u.range.greedy) pc[-1] = REOP_MINIMALQUANT; + SET_ARG(pc, t->u.range.min); + pc += ARG_LEN; + SET_ARG(pc, t->u.range.max); + pc += ARG_LEN; + } + emitStateSP->nextTermFixup = pc; + pc += OFFSET_LEN; + emitStateSP->continueNode = t; + emitStateSP->continueOp = REOP_ENDCHILD; + ++emitStateSP; + JS_ASSERT((emitStateSP - emitStateStack) <= treeDepth); + t = (RENode *)(t->kid); + op = t->op; + continue; + case REOP_ENDCHILD: + diff = pc - emitStateSP->nextTermFixup; + CHECK_OFFSET(diff); + SET_OFFSET(emitStateSP->nextTermFixup, diff); + break; + case REOP_CLASS: + if (!t->u.ucclass.sense) + pc[-1] = REOP_NCLASS; + SET_ARG(pc, t->u.ucclass.index); + pc += ARG_LEN; + charSet = &re->classList[t->u.ucclass.index]; + charSet->converted = JS_FALSE; + charSet->length = t->u.ucclass.bmsize; + charSet->u.src.startIndex = t->u.ucclass.startIndex; + charSet->u.src.length = t->u.ucclass.kidlen; + charSet->sense = t->u.ucclass.sense; + break; + default: + break; + } + t = t->next; + if (t == NULL) { + if (emitStateSP == emitStateStack) + break; + --emitStateSP; + t = emitStateSP->continueNode; + op = emitStateSP->continueOp; + } + else + op = t->op; + } + if (emitStateStack) + JS_free(state->context, emitStateStack); + return pc; +} + + +JSRegExp * +js_NewRegExp(JSContext *cx, JSTokenStream *ts, + JSString *str, uintN flags, JSBool flat) +{ + JSRegExp *re; + void *mark; + CompilerState state; + size_t resize; + jsbytecode *endPC; + uint32 i; + size_t len; + + re = NULL; + mark = JS_ARENA_MARK(&cx->tempPool); + + state.context = cx; + state.tokenStream = ts; + state.cpbegin = state.cp = JSSTRING_CHARS(str); + state.cpend = state.cp + JSSTRING_LENGTH(str); + state.flags = flags; + state.parenCount = 0; + state.classCount = 0; + state.progLength = 0; + state.treeDepth = 0; + for (i = 0; i < CLASS_CACHE_SIZE; i++) + state.classCache[i].start = NULL; + + len = JSSTRING_LENGTH(str); + + if (len != 0 && flat) { + state.result = NewRENode(&state, REOP_FLAT); + state.result->u.flat.chr = *state.cpbegin; + state.result->u.flat.length = JSSTRING_LENGTH(str); + state.result->kid = (void *)(state.cpbegin); + state.progLength += 5; + } + else { + if (!parseRegExp(&state)) + goto out; + } + resize = sizeof *re + state.progLength + 1; + re = (JSRegExp *) JS_malloc(cx, JS_ROUNDUP(resize, sizeof(jsword))); + if (!re) + goto out; + + re->classCount = state.classCount; + if (state.classCount) { + re->classList = (RECharSet *)JS_malloc(cx, sizeof(RECharSet) + * state.classCount); + if (!re->classList) + goto out; + } + else + re->classList = NULL; + endPC = emitREBytecode(&state, re, state.treeDepth, re->program, state.result); + if (!endPC) { + re = NULL; + goto out; + } + *endPC++ = REOP_END; + JS_ASSERT(endPC <= (re->program + (state.progLength + 1))); + + re->nrefs = 1; + re->parenCount = state.parenCount; + re->flags = flags; + re->source = str; + +out: + JS_ARENA_RELEASE(&cx->tempPool, mark); + return re; +} + +JSRegExp * +js_NewRegExpOpt(JSContext *cx, JSTokenStream *ts, + JSString *str, JSString *opt, JSBool flat) +{ + uintN flags; + jschar *s; + size_t i, n; + char charBuf[2]; + + flags = 0; + if (opt) { + s = JSSTRING_CHARS(opt); + for (i = 0, n = JSSTRING_LENGTH(opt); i < n; i++) { + switch (s[i]) { + case 'g': + flags |= JSREG_GLOB; + break; + case 'i': + flags |= JSREG_FOLD; + break; + case 'm': + flags |= JSREG_MULTILINE; + break; + default: + charBuf[0] = (char)s[i]; + charBuf[1] = '\0'; + js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR, + JSMSG_BAD_FLAG, charBuf); + return NULL; + } + } + } + return js_NewRegExp(cx, ts, str, flags, flat); +} + + +#define HOLD_REGEXP(cx, re) JS_ATOMIC_INCREMENT(&(re)->nrefs) +#define DROP_REGEXP(cx, re) js_DestroyRegExp(cx, re) + +/* + * Save the current state of the match - the position in the input + * text as well as the position in the bytecode. The state of any + * parent expressions is also saved (preceding state). + * Contents of parenCount parentheses from parenIndex are also saved. + */ +static REBackTrackData * +pushBackTrackState(REGlobalData *gData, REOp op, + jsbytecode *target, REMatchState *x, const jschar *cp, + intN parenIndex, intN parenCount) +{ + intN i; + REBackTrackData *result + = (REBackTrackData *)((char *)(gData->backTrackSP) + gData->cursz); + + size_t sz = sizeof(REBackTrackData) + + gData->stateStackTop * sizeof(REProgState) + + parenCount * sizeof(RECapture); + + + if (((char *)result + sz) + > (char *)gData->backTrackStack + gData->maxBackTrack) { + ptrdiff_t offset = (char *)result - (char *)gData->backTrackStack; + gData->backTrackStack + = (REBackTrackData *)JS_ArenaGrow(&gData->pool, + gData->backTrackStack, + gData->maxBackTrack, + gData->maxBackTrack); + gData->maxBackTrack <<= 1; + if (!gData->backTrackStack) + return NULL; + result = (REBackTrackData *)((char *)gData->backTrackStack + offset); + } + gData->backTrackSP = result; + result->sz = gData->cursz; + gData->cursz = sz; + + result->backtrack_op = op; + result->backtrack_pc = target; + result->cp = cp; + result->parenCount = parenCount; + + result->precedingStateTop = gData->stateStackTop; + JS_ASSERT(gData->stateStackTop); + memcpy(result + 1, gData->stateStack, + sizeof(REProgState) * result->precedingStateTop); + + if (parenCount != -1) { + result->parenIndex = parenIndex; + memcpy((char *)(result + 1) + + sizeof(REProgState) * result->precedingStateTop, + &x->parens[parenIndex], + sizeof(RECapture) * parenCount); + for (i = 0; i < parenCount; i++) + x->parens[parenIndex + i].index = -1; + } + + return result; +} + + +/* + * Consecutive literal characters. + */ +#if 0 +static REMatchState * +flatNMatcher(REGlobalData *gData, REMatchState *x, jschar *matchChars, + intN length) +{ + intN i; + if ((x->cp + length) > gData->cpend) + return NULL; + for (i = 0; i < length; i++) { + if (matchChars[i] != x->cp[i]) + return NULL; + } + x->cp += length; + return x; +} +#endif + +static REMatchState * +flatNIMatcher(REGlobalData *gData, REMatchState *x, jschar *matchChars, + intN length) +{ + intN i; + if ((x->cp + length) > gData->cpend) + return NULL; + for (i = 0; i < length; i++) { + if (upcase(matchChars[i]) != upcase(x->cp[i])) + return NULL; + } + x->cp += length; + return x; +} + +/* + * 1. Evaluate DecimalEscape to obtain an EscapeValue E. + * 2. If E is not a character then go to step 6. + * 3. Let ch be E's character. + * 4. Let A be a one-element RECharSet containing the character ch. + * 5. Call CharacterSetMatcher(A, false) and return its Matcher result. + * 6. E must be an integer. Let n be that integer. + * 7. If n=0 or n>NCapturingParens then throw a SyntaxError exception. + * 8. Return an internal Matcher closure that takes two arguments, a State x + * and a Continuation c, and performs the following: + * 1. Let cap be x's captures internal array. + * 2. Let s be cap[n]. + * 3. If s is undefined, then call c(x) and return its result. + * 4. Let e be x's endIndex. + * 5. Let len be s's length. + * 6. Let f be e+len. + * 7. If f>InputLength, return failure. + * 8. If there exists an integer i between 0 (inclusive) and len (exclusive) + * such that Canonicalize(s[i]) is not the same character as + * Canonicalize(Input [e+i]), then return failure. + * 9. Let y be the State (f, cap). + * 10. Call c(y) and return its result. + */ +static REMatchState * +backrefMatcher(REGlobalData *gData, REMatchState *x, uintN parenIndex) +{ + uintN len; + uintN i; + const jschar *parenContent; + RECapture *s = &x->parens[parenIndex]; + if (s->index == -1) + return x; + + len = s->length; + if ((x->cp + len) > gData->cpend) + return NULL; + + parenContent = &gData->cpbegin[s->index]; + if (gData->regexp->flags & JSREG_FOLD) { + for (i = 0; i < len; i++) { + if (upcase(parenContent[i]) != upcase(x->cp[i])) + return NULL; + } + } + else { + for (i = 0; i < len; i++) { + if (parenContent[i] != x->cp[i]) + return NULL; + } + } + x->cp += len; + return x; +} + + +/* Add a single character to the RECharSet */ +static void +addCharacterToCharSet(RECharSet *cs, jschar c) +{ + uintN byteIndex = (uintN)(c / 8); + JS_ASSERT(c <= cs->length); + cs->u.bits[byteIndex] |= 1 << (c & 0x7); +} + + +/* Add a character range, c1 to c2 (inclusive) to the RECharSet */ +static void +addCharacterRangeToCharSet(RECharSet *cs, jschar c1, jschar c2) +{ + uintN i; + + uintN byteIndex1 = (uintN)(c1 / 8); + uintN byteIndex2 = (uintN)(c2 / 8); + + JS_ASSERT((c2 <= cs->length) && (c1 <= c2)); + + c1 &= 0x7; + c2 &= 0x7; + + if (byteIndex1 == byteIndex2) + cs->u.bits[byteIndex1] |= ((uint8)(0xFF) >> (7 - (c2 - c1))) << c1; + else { + cs->u.bits[byteIndex1] |= 0xFF << c1; + for (i = byteIndex1 + 1; i < byteIndex2; i++) + cs->u.bits[i] = 0xFF; + cs->u.bits[byteIndex2] |= (uint8)(0xFF) >> (7 - c2); + } +} + +/* Compile the source of the class into a RECharSet */ +static JSBool +processCharSet(REGlobalData *gData, RECharSet *charSet) +{ + const jschar *src = JSSTRING_CHARS(gData->regexp->source) + + charSet->u.src.startIndex; + const jschar *end = src + charSet->u.src.length; + + jschar rangeStart, thisCh; + uintN byteLength; + jschar c; + uintN n; + intN nDigits; + intN i; + JSBool inRange = JS_FALSE; + + JS_ASSERT(!charSet->converted); + charSet->converted = JS_TRUE; + + byteLength = (charSet->length / 8) + 1; + charSet->u.bits = (uint8 *)JS_malloc(gData->cx, byteLength); + if (!charSet->u.bits) + return JS_FALSE; + memset(charSet->u.bits, 0, byteLength); + + if (src == end) + return JS_TRUE; + + if (*src == '^') { + JS_ASSERT(charSet->sense == JS_FALSE); + ++src; + } + else + JS_ASSERT(charSet->sense == JS_TRUE); + + + while (src != end) { + switch (*src) { + case '\\': + ++src; + c = *src++; + switch (c) { + case 'b': + thisCh = 0x8; + break; + case 'f': + thisCh = 0xC; + break; + case 'n': + thisCh = 0xA; + break; + case 'r': + thisCh = 0xD; + break; + case 't': + thisCh = 0x9; + break; + case 'v': + thisCh = 0xB; + break; + case 'c': + if (((src + 1) < end) && JS_ISWORD(src[1])) + thisCh = (jschar)(*src++ & 0x1F); + else { + --src; + thisCh = '\\'; + } + break; + case 'x': + nDigits = 2; + goto lexHex; + case 'u': + nDigits = 4; +lexHex: + n = 0; + for (i = 0; (i < nDigits) && (src < end); i++) { + uintN digit; + c = *src++; + if (!isASCIIHexDigit(c, &digit)) { + /* + * Back off to accepting the original '\' + * as a literal + */ + src -= (i + 1); + n = '\\'; + break; + } + n = (n << 4) | digit; + } + thisCh = (jschar)(n); + break; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + /* + * This is a non-ECMA extension - decimal escapes (in this + * case, octal!) are supposed to be an error inside class + * ranges, but supported here for backwards compatibility. + * + */ + n = JS7_UNDEC(c); + c = *src; + if ('0' <= c && c <= '7') { + src++; + n = 8 * n + JS7_UNDEC(c); + c = *src; + if ('0' <= c && c <= '7') { + src++; + i = 8 * n + JS7_UNDEC(c); + if (i <= 0377) + n = i; + else + src--; + } + } + thisCh = (jschar)(n); + break; + + case 'd': + addCharacterRangeToCharSet(charSet, '0', '9'); + continue; /* don't need range processing */ + case 'D': + addCharacterRangeToCharSet(charSet, 0, '0' - 1); + addCharacterRangeToCharSet(charSet, (jschar)('9' + 1), + (jschar)(charSet->length)); + continue; + case 's': + for (i = (intN)(charSet->length); i >= 0; i--) + if (JS_ISSPACE(i)) + addCharacterToCharSet(charSet, (jschar)(i)); + continue; + case 'S': + for (i = (intN)(charSet->length); i >= 0; i--) + if (!JS_ISSPACE(i)) + addCharacterToCharSet(charSet, (jschar)(i)); + continue; + case 'w': + for (i = (intN)(charSet->length); i >= 0; i--) + if (JS_ISWORD(i)) + addCharacterToCharSet(charSet, (jschar)(i)); + continue; + case 'W': + for (i = (intN)(charSet->length); i >= 0; i--) + if (!JS_ISWORD(i)) + addCharacterToCharSet(charSet, (jschar)(i)); + continue; + default: + thisCh = c; + break; + + } + break; + + default: + thisCh = *src++; + break; + + } + if (inRange) { + if (gData->regexp->flags & JSREG_FOLD) { + addCharacterRangeToCharSet(charSet, upcase(rangeStart), + upcase(thisCh)); + addCharacterRangeToCharSet(charSet, downcase(rangeStart), + downcase(thisCh)); + } else { + addCharacterRangeToCharSet(charSet, rangeStart, thisCh); + } + inRange = JS_FALSE; + } + else { + if (gData->regexp->flags & JSREG_FOLD) { + addCharacterToCharSet(charSet, upcase(thisCh)); + addCharacterToCharSet(charSet, downcase(thisCh)); + } else { + addCharacterToCharSet(charSet, thisCh); + } + if (src < (end - 1)) { + if (*src == '-') { + ++src; + inRange = JS_TRUE; + rangeStart = thisCh; + } + } + } + } + return JS_TRUE; +} + +void +js_DestroyRegExp(JSContext *cx, JSRegExp *re) +{ + uintN i; + if (JS_ATOMIC_DECREMENT(&re->nrefs) == 0) { + if (re->classList) { + for (i = 0; i < re->classCount; i++) { + if (re->classList[i].converted) + JS_free(cx, re->classList[i].u.bits); + re->classList[i].u.bits = NULL; + } + JS_free(cx, re->classList); + } + JS_free(cx, re); + } +} + +static JSBool +reallocStateStack(REGlobalData *gData) +{ + size_t sz = sizeof(REProgState) * gData->maxStateStack; + gData->maxStateStack <<= 1; + gData->stateStack + = (REProgState *)JS_ArenaGrow(&gData->pool, gData->stateStack, sz, sz); + if (!gData->stateStack) { + gData->ok = JS_FALSE; + return JS_FALSE; + } + return JS_TRUE; +} + +/* +* Apply the current op against the given input to see if +* it's going to match or fail. Return false if we don't +* get a match, true if we do and update the state of the +* input and pc if the update flag is true. +*/ +static REMatchState *simpleMatch(REGlobalData *gData, REMatchState *x, + REOp op, jsbytecode **startpc, JSBool update) +{ + REMatchState *result = NULL; + jschar matchCh; + intN parenIndex; + intN offset, length, index; + jsbytecode *pc = *startpc; /* pc has already been incremented past op */ + jschar *source; + const jschar *startcp = x->cp; + jschar ch; + RECharSet *charSet; + + + switch (op) { + default: + JS_ASSERT(JS_FALSE); + case REOP_BOL: + if (x->cp != gData->cpbegin) { + if (gData->cx->regExpStatics.multiline || + (gData->regexp->flags & JSREG_MULTILINE)) { + if (!RE_IS_LINE_TERM(x->cp[-1])) + break; + } + else + break; + } + result = x; + break; + case REOP_EOL: + if (x->cp != gData->cpend) { + if (gData->cx->regExpStatics.multiline || + (gData->regexp->flags & JSREG_MULTILINE)) { + if (!RE_IS_LINE_TERM(*x->cp)) + break; + } + else + break; + } + result = x; + break; + case REOP_WBDRY: + if ((x->cp == gData->cpbegin || !JS_ISWORD(x->cp[-1])) + ^ !((x->cp != gData->cpend) && JS_ISWORD(*x->cp))) + result = x; + break; + case REOP_WNONBDRY: + if ((x->cp == gData->cpbegin || !JS_ISWORD(x->cp[-1])) + ^ ((x->cp != gData->cpend) && JS_ISWORD(*x->cp))) + result = x; + break; + case REOP_DOT: + if (x->cp != gData->cpend && !RE_IS_LINE_TERM(*x->cp)) { + result = x; + result->cp++; + } + break; + case REOP_DIGIT: + if (x->cp != gData->cpend && JS_ISDIGIT(*x->cp)) { + result = x; + result->cp++; + } + break; + case REOP_NONDIGIT: + if (x->cp != gData->cpend && !JS_ISDIGIT(*x->cp)) { + result = x; + result->cp++; + } + break; + case REOP_ALNUM: + if (x->cp != gData->cpend && JS_ISWORD(*x->cp)) { + result = x; + result->cp++; + } + break; + case REOP_NONALNUM: + if (x->cp != gData->cpend && !JS_ISWORD(*x->cp)) { + result = x; + result->cp++; + } + break; + case REOP_SPACE: + if (x->cp != gData->cpend && JS_ISSPACE(*x->cp)) { + result = x; + result->cp++; + } + break; + case REOP_NONSPACE: + if (x->cp != gData->cpend && !JS_ISSPACE(*x->cp)) { + result = x; + result->cp++; + } + break; + case REOP_BACKREF: + parenIndex = GET_ARG(pc); + pc += ARG_LEN; + result = backrefMatcher(gData, x, parenIndex); + break; + case REOP_FLAT: + offset = GET_ARG(pc); + pc += ARG_LEN; + length = GET_ARG(pc); + pc += ARG_LEN; + source = JSSTRING_CHARS(gData->regexp->source) + offset; + if ((x->cp + length) <= gData->cpend) { + for (index = 0; index < length; index++) { + if (source[index] != x->cp[index]) + return NULL; + } + x->cp += length; + result = x; + } + break; + case REOP_FLAT1: + matchCh = *pc++; + if ((x->cp != gData->cpend) && (*x->cp == matchCh)) { + result = x; + result->cp++; + } + break; + case REOP_FLATi: + offset = GET_ARG(pc); + pc += ARG_LEN; + length = GET_ARG(pc); + pc += ARG_LEN; + source = JSSTRING_CHARS(gData->regexp->source); + result = flatNIMatcher(gData, x, source + offset, length); + break; + case REOP_FLAT1i: + matchCh = *pc++; + if ((x->cp != gData->cpend) && (upcase(*x->cp) == upcase(matchCh))) { + result = x; + result->cp++; + } + break; + case REOP_UCFLAT1: + matchCh = GET_ARG(pc); + pc += ARG_LEN; + if ((x->cp != gData->cpend) && (*x->cp == matchCh)) { + result = x; + result->cp++; + } + break; + case REOP_UCFLAT1i: + matchCh = GET_ARG(pc); + pc += ARG_LEN; + if ((x->cp != gData->cpend) && (upcase(*x->cp) == upcase(matchCh))) { + result = x; + result->cp++; + } + break; + case REOP_CLASS: + index = GET_ARG(pc); + pc += ARG_LEN; + if (x->cp != gData->cpend) { + charSet = &gData->regexp->classList[index]; + JS_ASSERT(charSet->converted); + ch = *x->cp; + index = ch / 8; + if ((charSet->length != 0) && + ( (ch <= charSet->length) + && ((charSet->u.bits[index] & (1 << (ch & 0x7))) != 0) )) { + result = x; + result->cp++; + } + } + break; + case REOP_NCLASS: + index = GET_ARG(pc); + pc += ARG_LEN; + if (x->cp != gData->cpend) { + charSet = &gData->regexp->classList[index]; + JS_ASSERT(charSet->converted); + ch = *x->cp; + index = ch / 8; + if ((charSet->length == 0) || + ( (ch > charSet->length) + || ((charSet->u.bits[index] & (1 << (ch & 0x7))) == 0) )) { + result = x; + result->cp++; + } + } + break; + } + if (result != NULL) { + if (update) + *startpc = pc; + else + x->cp = startcp; + return result; + } + x->cp = startcp; + return NULL; +} + +static REMatchState * +executeREBytecode(REGlobalData *gData, REMatchState *x) +{ + REMatchState *result; + REBackTrackData *backTrackData; + intN offset; + jsbytecode *nextpc; + REOp nextop; + RECapture *cap; + REProgState *curState; + const jschar *startcp; + uintN parenIndex, k; + uintN parenSoFar = 0; + + jschar matchCh1, matchCh2; + RECharSet *charSet; + + JSBool anchor; + jsbytecode *pc = gData->regexp->program; + REOp op = (REOp)(*pc++); + + /* + * If the first node is a simple match, step the index into + * the string until that match is made, or fail if it can't be + * found at all. + */ + if (REOP_IS_SIMPLE(op)) { + anchor = JS_FALSE; + while (x->cp <= gData->cpend) { + nextpc = pc; /* reset back to start each time */ + result = simpleMatch(gData, x, op, &nextpc, JS_TRUE); + if (result) { + anchor = JS_TRUE; + x = result; + pc = nextpc; /* accept skip to next opcode */ + op = (REOp)(*pc++); + break; + } + else { + gData->skipped++; + x->cp++; + } + } + if (!anchor) + return NULL; + } + + while (JS_TRUE) { + if (REOP_IS_SIMPLE(op)) + result = simpleMatch(gData, x, op, &pc, JS_TRUE); + else { + curState = &gData->stateStack[gData->stateStackTop]; + switch (op) { + case REOP_EMPTY: + result = x; + break; + + case REOP_ALTPREREQ2: + nextpc = pc + GET_OFFSET(pc); /* start of next op */ + pc += ARG_LEN; + matchCh2 = GET_ARG(pc); + pc += ARG_LEN; + k = GET_ARG(pc); + pc += ARG_LEN; + + if (x->cp != gData->cpend) { + if (*x->cp == matchCh2) + goto doAlt; + + charSet = &gData->regexp->classList[k]; + if (!charSet->converted) + if (!processCharSet(gData, charSet)) + return NULL; + matchCh1 = *x->cp; + k = matchCh1 / 8; + if ((charSet->length == 0 || + matchCh1 > charSet->length || + (charSet->u.bits[k] & (1 << (matchCh1 & 0x7))) == 0) + ^ charSet->sense) { + goto doAlt; + } + } + result = NULL; + break; + + case REOP_ALTPREREQ: + nextpc = pc + GET_OFFSET(pc); /* start of next op */ + pc += ARG_LEN; + matchCh1 = GET_ARG(pc); + pc += ARG_LEN; + matchCh2 = GET_ARG(pc); + pc += ARG_LEN; + if ((x->cp == gData->cpend) + || ((*x->cp != matchCh1) && (*x->cp != matchCh2))) { + result = NULL; + break; + } + /* else false thru... */ + + case REOP_ALT: +doAlt: + nextpc = pc + GET_OFFSET(pc); /* start of next alternate */ + pc += ARG_LEN; /* start of this alternate */ + curState->parenSoFar = parenSoFar; + ++gData->stateStackTop; + if (gData->stateStackTop == gData->maxStateStack) + if (!reallocStateStack(gData)) + return NULL; + op = (REOp)(*pc++); + startcp = x->cp; + if (REOP_IS_SIMPLE(op)) { + if (!simpleMatch(gData, x, op, &pc, JS_TRUE)) { + op = (REOp)(*nextpc++); + pc = nextpc; + continue; + } + else { /* accept the match and move on */ + result = x; + op = (REOp)(*pc++); + } + } + nextop = (REOp)(*nextpc++); + if (!pushBackTrackState(gData, nextop, nextpc, x, startcp, 0, 0)) + return NULL; + continue; + + /* + * Occurs at (succesful) end of REOP_ALT, + */ + case REOP_JUMP: + --gData->stateStackTop; + offset = GET_OFFSET(pc); + pc += offset; + op = (REOp)(*pc++); + continue; + + /* + * Occurs at last (succesful) end of REOP_ALT, + */ + case REOP_ENDALT: + --gData->stateStackTop; + op = (REOp)(*pc++); + continue; + + case REOP_LPAREN: + parenIndex = GET_ARG(pc); + if ((parenIndex + 1) > parenSoFar) + parenSoFar = parenIndex + 1; + pc += ARG_LEN; + x->parens[parenIndex].index = x->cp - gData->cpbegin; + x->parens[parenIndex].length = 0; + op = (REOp)(*pc++); + continue; + case REOP_RPAREN: + parenIndex = GET_ARG(pc); + pc += ARG_LEN; + cap = &x->parens[parenIndex]; + cap->length = x->cp - (gData->cpbegin + cap->index); + op = (REOp)(*pc++); + continue; + + case REOP_ASSERT: + nextpc = pc + GET_OFFSET(pc); /* start of term after ASSERT */ + pc += ARG_LEN; /* start of ASSERT child */ + op = (REOp)(*pc++); + if (REOP_IS_SIMPLE(op) + && !simpleMatch(gData, x, op, &pc, JS_FALSE)) { + result = NULL; + break; + } + else { + curState->u.assertion.top + = (char *)gData->backTrackSP + - (char *)gData->backTrackStack; + curState->u.assertion.sz = gData->cursz; + curState->index = x->cp - gData->cpbegin; + curState->parenSoFar = parenSoFar; + ++gData->stateStackTop; + if (gData->stateStackTop == gData->maxStateStack) + if (!reallocStateStack(gData)) + return NULL; + if (!pushBackTrackState(gData, REOP_ASSERTTEST, + nextpc, x, x->cp, 0, 0)) + return NULL; + } + continue; + case REOP_ASSERT_NOT: + nextpc = pc + GET_OFFSET(pc); + pc += ARG_LEN; + op = (REOp)(*pc++); + if (REOP_IS_SIMPLE(op) + /* Note - fail to fail! */ + && simpleMatch(gData, x, op, &pc, JS_FALSE)) { + result = NULL; + break; + } + else { + curState->u.assertion.top + = (char *)gData->backTrackSP + - (char *)gData->backTrackStack; + curState->u.assertion.sz = gData->cursz; + curState->index = x->cp - gData->cpbegin; + curState->parenSoFar = parenSoFar; + ++gData->stateStackTop; + if (gData->stateStackTop == gData->maxStateStack) + if (!reallocStateStack(gData)) + return NULL; + if (!pushBackTrackState(gData, REOP_ASSERTNOTTEST, + nextpc, x, x->cp, 0, 0)) + return NULL; + } + continue; + case REOP_ASSERTTEST: + --gData->stateStackTop; + --curState; + x->cp = gData->cpbegin + curState->index; + gData->backTrackSP + = (REBackTrackData *)((char *)gData->backTrackStack + + curState->u.assertion.top); + gData->cursz = curState->u.assertion.sz; + if (result != NULL) + result = x; + break; + case REOP_ASSERTNOTTEST: + --gData->stateStackTop; + --curState; + x->cp = gData->cpbegin + curState->index; + gData->backTrackSP + = (REBackTrackData *)((char *)gData->backTrackStack + + curState->u.assertion.top); + gData->cursz = curState->u.assertion.sz; + if (result == NULL) + result = x; + else + result = NULL; + break; + + case REOP_END: + if (x != NULL) + return x; + break; + + case REOP_STAR: + curState->u.quantifier.min = 0; + curState->u.quantifier.max = -1; + goto quantcommon; + case REOP_PLUS: + curState->u.quantifier.min = 1; + curState->u.quantifier.max = -1; + goto quantcommon; + case REOP_OPT: + curState->u.quantifier.min = 0; + curState->u.quantifier.max = 1; + goto quantcommon; + case REOP_QUANT: + curState->u.quantifier.min = GET_ARG(pc); + pc += ARG_LEN; + curState->u.quantifier.max = GET_ARG(pc); + pc += ARG_LEN; +quantcommon: + if (curState->u.quantifier.max == 0) { + pc = pc + GET_OFFSET(pc); + op = (REOp)(*pc++); + result = x; + continue; + } + /* Step over */ + nextpc = pc + ARG_LEN; + op = (REOp)(*nextpc++); + startcp = x->cp; + if (REOP_IS_SIMPLE(op)) { + if (!simpleMatch(gData, x, op, &nextpc, JS_TRUE)) { + if (curState->u.quantifier.min == 0) + result = x; + else + result = NULL; + pc = pc + GET_OFFSET(pc); + break; + } + else { + op = (REOp)(*nextpc++); + result = x; + } + } + curState->index = startcp - gData->cpbegin; + curState->continue_op = REOP_REPEAT; + curState->continue_pc = pc; + curState->parenSoFar = parenSoFar; + ++gData->stateStackTop; + if (gData->stateStackTop == gData->maxStateStack) + if (!reallocStateStack(gData)) + return NULL; + if (curState->u.quantifier.min == 0) + if (!pushBackTrackState(gData, REOP_REPEAT, + pc, x, startcp, 0, 0)) + return NULL; + pc = nextpc; + continue; + + case REOP_ENDCHILD: /* marks the end of a quantifier child */ + pc = curState[-1].continue_pc; + op = curState[-1].continue_op; + continue; + + case REOP_REPEAT: + --curState; +repeatAgain: + --gData->stateStackTop; + if (result == NULL) { + /* + * There's been a failure, see if we have enough children. + */ + if (curState->u.quantifier.min == 0) { + result = x; + goto repeatDone; + } + break; + } + else { + if ((curState->u.quantifier.min == 0) + && (x->cp == gData->cpbegin + curState->index)) { + /* matched an empty string, that'll get us nowhere */ + result = NULL; + break; + } + if (curState->u.quantifier.min != 0) + curState->u.quantifier.min--; + if (curState->u.quantifier.max != (uint16)(-1)) + curState->u.quantifier.max--; + if (curState->u.quantifier.max == 0) { + result = x; + goto repeatDone; + } + nextpc = pc + ARG_LEN; + nextop = (REOp)(*nextpc); + startcp = x->cp; + if (REOP_IS_SIMPLE(nextop)) { + nextpc++; + if (!simpleMatch(gData, x, nextop, &nextpc, JS_TRUE)) { + if (curState->u.quantifier.min == 0) { + result = x; + goto repeatDone; + } + else + result = NULL; + break; + } + result = x; + } + curState->index = startcp - gData->cpbegin; + ++gData->stateStackTop; + if (gData->stateStackTop == gData->maxStateStack) + if (!reallocStateStack(gData)) + return NULL; + if (curState->u.quantifier.min == 0) + if (!pushBackTrackState(gData, REOP_REPEAT, + pc, x, startcp, + curState->parenSoFar, + parenSoFar + - curState->parenSoFar)) + return NULL; + if (*nextpc == REOP_ENDCHILD) + goto repeatAgain; + pc = nextpc; + op = (REOp)(*pc++); + parenSoFar = curState->parenSoFar; + } + continue; +repeatDone: + pc = pc + GET_OFFSET(pc); + break; + + + case REOP_MINIMALSTAR: + curState->u.quantifier.min = 0; + curState->u.quantifier.max = -1; + goto minimalquantcommon; + case REOP_MINIMALPLUS: + curState->u.quantifier.min = 1; + curState->u.quantifier.max = -1; + goto minimalquantcommon; + case REOP_MINIMALOPT: + curState->u.quantifier.min = 0; + curState->u.quantifier.max = 1; + goto minimalquantcommon; + case REOP_MINIMALQUANT: + curState->u.quantifier.min = GET_ARG(pc); + pc += ARG_LEN; + curState->u.quantifier.max = GET_ARG(pc); + pc += ARG_LEN; +minimalquantcommon: + curState->index = x->cp - gData->cpbegin; + curState->parenSoFar = parenSoFar; + ++gData->stateStackTop; + if (gData->stateStackTop == gData->maxStateStack) + if (!reallocStateStack(gData)) + return NULL; + if (curState->u.quantifier.min != 0) { + curState->continue_op = REOP_MINIMALREPEAT; + curState->continue_pc = pc; + /* step over */ + pc += ARG_LEN; + op = (REOp)(*pc++); + } + else { + if (!pushBackTrackState(gData, REOP_MINIMALREPEAT, + pc, x, x->cp, 0, 0)) + return NULL; + --gData->stateStackTop; + pc = pc + GET_OFFSET(pc); + op = (REOp)(*pc++); + } + continue; + + case REOP_MINIMALREPEAT: + --gData->stateStackTop; + --curState; + + if (result == NULL) { + /* + * Non-greedy failure - try to consume another child. + */ + if ((curState->u.quantifier.max == (uint16)(-1)) + || (curState->u.quantifier.max > 0)) { + curState->index = x->cp - gData->cpbegin; + curState->continue_op = REOP_MINIMALREPEAT; + curState->continue_pc = pc; + pc += ARG_LEN; + for (k = curState->parenSoFar; k < parenSoFar; k++) + x->parens[k].index = -1; + ++gData->stateStackTop; + if (gData->stateStackTop == gData->maxStateStack) + if (!reallocStateStack(gData)) + return NULL; + op = (REOp)(*pc++); + continue; + } + else { + /* Don't need to adjust pc since we're going to pop. */ + break; + } + } + else { + if ((curState->u.quantifier.min == 0) + && (x->cp == gData->cpbegin + curState->index)) { + /* Matched an empty string, that'll get us nowhere. */ + result = NULL; + break; + } + if (curState->u.quantifier.min != 0) + curState->u.quantifier.min--; + if (curState->u.quantifier.max != (uint16)(-1)) + curState->u.quantifier.max--; + if (curState->u.quantifier.min != 0) { + curState->continue_op = REOP_MINIMALREPEAT; + curState->continue_pc = pc; + pc += ARG_LEN; + for (k = curState->parenSoFar; k < parenSoFar; k++) + x->parens[k].index = -1; + curState->index = x->cp - gData->cpbegin; + ++gData->stateStackTop; + if (gData->stateStackTop == gData->maxStateStack) + if (!reallocStateStack(gData)) + return NULL; + op = (REOp)(*pc++); + continue; + } + else { + curState->index = x->cp - gData->cpbegin; + curState->parenSoFar = parenSoFar; + ++gData->stateStackTop; + if (gData->stateStackTop == gData->maxStateStack) + if (!reallocStateStack(gData)) + return NULL; + if (!pushBackTrackState(gData, REOP_MINIMALREPEAT, + pc, x, x->cp, + curState->parenSoFar, + parenSoFar + - curState->parenSoFar)) + return NULL; + --gData->stateStackTop; + pc = pc + GET_OFFSET(pc); + op = (REOp)(*pc++); + continue; + } + } + + default: + JS_ASSERT(JS_FALSE); + result = NULL; + } + } + /* + * If the match failed and there's a backtrack option, take it. + * Otherwise this is a complete and utter failure. + */ + if (result == NULL) { + if (gData->cursz > 0) { + backTrackData = gData->backTrackSP; + gData->cursz = backTrackData->sz; + gData->backTrackSP + = (REBackTrackData *)((char *)backTrackData + - backTrackData->sz); + x->cp = backTrackData->cp; + pc = backTrackData->backtrack_pc; + op = backTrackData->backtrack_op; + gData->stateStackTop = backTrackData->precedingStateTop; + JS_ASSERT(gData->stateStackTop); + + memcpy(gData->stateStack, backTrackData + 1, + sizeof(REProgState) * backTrackData->precedingStateTop); + curState = &gData->stateStack[gData->stateStackTop - 1]; + + if (backTrackData->parenCount) { + memcpy(&x->parens[backTrackData->parenIndex], + (char *)(backTrackData + 1) + sizeof(REProgState) * backTrackData->precedingStateTop, + sizeof(RECapture) * backTrackData->parenCount); + parenSoFar = backTrackData->parenIndex + backTrackData->parenCount; + } + else { + for (k = curState->parenSoFar; k < parenSoFar; k++) + x->parens[k].index = -1; + parenSoFar = curState->parenSoFar; + } + continue; + } + else + return NULL; + } + else + x = result; + + /* + * Continue with the expression. + */ + op = (REOp)*pc++; + } + return NULL; +} + +static REMatchState * +MatchRegExp(REGlobalData *gData, REMatchState *x) +{ + REMatchState *result; + const jschar *cp = x->cp; + const jschar *cp2; + uintN j; + + /* + * Have to include the position beyond the last character + * in order to detect end-of-input/line condition. + */ + for (cp2 = cp; cp2 <= gData->cpend; cp2++) { + gData->skipped = cp2 - cp; + x->cp = cp2; + for (j = 0; j < gData->regexp->parenCount; j++) + x->parens[j].index = -1; + result = executeREBytecode(gData, x); + if (!gData->ok || result) + return result; + gData->backTrackSP = gData->backTrackStack; + gData->cursz = 0; + gData->stateStackTop = 0; + cp2 = cp + gData->skipped; + } + return NULL; +} + + +static REMatchState * +initMatch(JSContext *cx, REGlobalData *gData, JSRegExp *re) +{ + REMatchState *result; + uintN i; + + gData->maxBackTrack = INITIAL_BACKTRACK; + JS_ARENA_ALLOCATE_CAST(gData->backTrackStack, REBackTrackData *, + &gData->pool, + INITIAL_BACKTRACK); + if (!gData->backTrackStack) + return NULL; + gData->backTrackSP = gData->backTrackStack; + gData->cursz = 0; + + + gData->maxStateStack = INITIAL_STATESTACK; + JS_ARENA_ALLOCATE_CAST(gData->stateStack, REProgState *, + &gData->pool, + sizeof(REProgState) * INITIAL_STATESTACK); + if (!gData->stateStack) + return NULL; + gData->stateStackTop = 0; + + gData->cx = cx; + gData->regexp = re; + gData->ok = JS_TRUE; + + JS_ARENA_ALLOCATE_CAST(result, REMatchState *, + &gData->pool, + sizeof(REMatchState) + + (re->parenCount - 1) * sizeof(RECapture)); + if (!result) + return NULL; + + for (i = 0; i < re->classCount; i++) + if (!re->classList[i].converted) + if (!processCharSet(gData, &re->classList[i])) + return NULL; + + return result; +} + +JSBool +js_ExecuteRegExp(JSContext *cx, JSRegExp *re, JSString *str, size_t *indexp, + JSBool test, jsval *rval) +{ + REGlobalData gData; + REMatchState *x, *result; + + const jschar *cp, *ep; + size_t i, length, start; + JSSubString *morepar; + JSBool ok; + JSRegExpStatics *res; + ptrdiff_t matchlen; + uintN num, morenum; + JSString *parstr, *matchstr; + JSObject *obj; + + RECapture *parsub; + + /* + * It's safe to load from cp because JSStrings have a zero at the end, + * and we never let cp get beyond cpend. + */ + start = *indexp; + length = JSSTRING_LENGTH(str); + if (start > length) + start = length; + cp = JSSTRING_CHARS(str); + gData.cpbegin = cp; + gData.cpend = cp + length; + cp += start; + gData.start = start; + gData.skipped = 0; + + JS_InitArenaPool(&gData.pool, "RegExpPool", 8096, 4); + x = initMatch(cx, &gData, re); + if (!x) + return JS_FALSE; + x->cp = cp; + + /* + * Call the recursive matcher to do the real work. Return null on mismatch + * whether testing or not. On match, return an extended Array object. + */ + result = MatchRegExp(&gData, x); + if (!(ok = gData.ok)) goto out; + if (!result) { + *rval = JSVAL_NULL; + goto out; + } + cp = result->cp; + i = PTRDIFF(cp, gData.cpbegin, jschar); + *indexp = i; + matchlen = i - (start + gData.skipped); + ep = cp; + cp -= matchlen; + + if (test) { + /* + * Testing for a match and updating cx->regExpStatics: don't allocate + * an array object, do return true. + */ + *rval = JSVAL_TRUE; + + /* Avoid warning. (gcc doesn't detect that obj is needed iff !test); */ + obj = NULL; + } else { + /* + * The array returned on match has element 0 bound to the matched + * string, elements 1 through state.parenCount bound to the paren + * matches, an index property telling the length of the left context, + * and an input property referring to the input string. + */ + obj = js_NewArrayObject(cx, 0, NULL); + if (!obj) { + ok = JS_FALSE; + goto out; + } + *rval = OBJECT_TO_JSVAL(obj); + +#define DEFVAL(val, id) { \ + ok = js_DefineProperty(cx, obj, id, val, \ + JS_PropertyStub, JS_PropertyStub, \ + JSPROP_ENUMERATE, NULL); \ + if (!ok) { \ + cx->newborn[GCX_OBJECT] = NULL; \ + cx->newborn[GCX_STRING] = NULL; \ + goto out; \ + } \ +} + + matchstr = js_NewStringCopyN(cx, cp, matchlen, 0); + if (!matchstr) { + cx->newborn[GCX_OBJECT] = NULL; + ok = JS_FALSE; + goto out; + } + DEFVAL(STRING_TO_JSVAL(matchstr), INT_TO_JSVAL(0)); + } + + res = &cx->regExpStatics; + res->input = str; + res->parenCount = re->parenCount; + if (re->parenCount == 0) + res->lastParen = js_EmptySubString; + else { + for (num = 0; num < re->parenCount; num++) { + parsub = &result->parens[num]; + if (num < 9) { + if (parsub->index == -1) { + res->parens[num].chars = NULL; + res->parens[num].length = 0; + } + else { + res->parens[num].chars = gData.cpbegin + parsub->index; + res->parens[num].length = parsub->length; + } + } else { + morenum = num - 9; + morepar = res->moreParens; + if (!morepar) { + res->moreLength = 10; + morepar = (JSSubString*) JS_malloc(cx, + 10 * sizeof(JSSubString)); + } else if (morenum >= res->moreLength) { + res->moreLength += 10; + morepar = (JSSubString*) JS_realloc(cx, morepar, + res->moreLength * sizeof(JSSubString)); + } + if (!morepar) { + cx->newborn[GCX_OBJECT] = NULL; + cx->newborn[GCX_STRING] = NULL; + ok = JS_FALSE; + goto out; + } + res->moreParens = morepar; + if (parsub->index == -1) { + morepar[morenum].chars = NULL; + morepar[morenum].length = 0; + } + else { + morepar[morenum].chars = gData.cpbegin + parsub->index; + morepar[morenum].length = parsub->length; + } + } + if (test) + continue; + if (parsub->index == -1) + ok = js_DefineProperty(cx, obj, INT_TO_JSVAL(num + 1), + JSVAL_VOID, NULL, NULL, + JSPROP_ENUMERATE, NULL); + else { + parstr = js_NewStringCopyN(cx, gData.cpbegin + parsub->index, + parsub->length, 0); + if (!parstr) { + cx->newborn[GCX_OBJECT] = NULL; + cx->newborn[GCX_STRING] = NULL; + ok = JS_FALSE; + goto out; + } + ok = js_DefineProperty(cx, obj, INT_TO_JSVAL(num + 1), + STRING_TO_JSVAL(parstr), NULL, NULL, + JSPROP_ENUMERATE, NULL); + } + if (!ok) { + cx->newborn[GCX_OBJECT] = NULL; + cx->newborn[GCX_STRING] = NULL; + goto out; + } + } + if (parsub->index == -1) { + res->lastParen.chars = NULL; + res->lastParen.length = 0; + } + else { + res->lastParen.chars = gData.cpbegin + parsub->index; + res->lastParen.length = parsub->length; + } + } + + if (!test) { + /* + * Define the index and input properties last for better for/in loop + * order (so they come after the elements). + */ + DEFVAL(INT_TO_JSVAL(start + gData.skipped), + (jsid)cx->runtime->atomState.indexAtom); + DEFVAL(STRING_TO_JSVAL(str), + (jsid)cx->runtime->atomState.inputAtom); + } + +#undef DEFVAL + + res->lastMatch.chars = cp; + res->lastMatch.length = matchlen; + if (cx->version == JSVERSION_1_2) { + /* + * JS1.2 emulated Perl4.0.1.8 (patch level 36) for global regexps used + * in scalar contexts, and unintentionally for the string.match "list" + * psuedo-context. On "hi there bye", the following would result: + * + * Language while(/ /g){print("$`");} s/ /$`/g + * perl4.036 "hi", "there" "hihitherehi therebye" + * perl5 "hi", "hi there" "hihitherehi therebye" + * js1.2 "hi", "there" "hihitheretherebye" + */ + res->leftContext.chars = JSSTRING_CHARS(str) + start; + res->leftContext.length = gData.skipped; + } else { + /* + * For JS1.3 and ECMAv2, emulate Perl5 exactly: + * + * js1.3 "hi", "hi there" "hihitherehi therebye" + */ + res->leftContext.chars = JSSTRING_CHARS(str); + res->leftContext.length = start + gData.skipped; + } + res->rightContext.chars = ep; + res->rightContext.length = gData.cpend - ep; + +out: + JS_FinishArenaPool(&gData.pool); + return ok; +} + +/************************************************************************/ + +enum regexp_tinyid { + REGEXP_SOURCE = -1, + REGEXP_GLOBAL = -2, + REGEXP_IGNORE_CASE = -3, + REGEXP_LAST_INDEX = -4, + REGEXP_MULTILINE = -5 +}; + +#define REGEXP_PROP_ATTRS (JSPROP_PERMANENT|JSPROP_SHARED) + +static JSPropertySpec regexp_props[] = { + {"source", REGEXP_SOURCE, REGEXP_PROP_ATTRS | JSPROP_READONLY,0,0}, + {"global", REGEXP_GLOBAL, REGEXP_PROP_ATTRS | JSPROP_READONLY,0,0}, + {"ignoreCase", REGEXP_IGNORE_CASE, REGEXP_PROP_ATTRS | JSPROP_READONLY,0,0}, + {"lastIndex", REGEXP_LAST_INDEX, REGEXP_PROP_ATTRS,0,0}, + {"multiline", REGEXP_MULTILINE, REGEXP_PROP_ATTRS | JSPROP_READONLY,0,0}, + {0,0,0,0,0} +}; + +static JSBool +regexp_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp) +{ + jsint slot; + JSRegExp *re; + + if (!JSVAL_IS_INT(id)) + return JS_TRUE; + slot = JSVAL_TO_INT(id); + if (slot == REGEXP_LAST_INDEX) + return JS_GetReservedSlot(cx, obj, 0, vp); + + JS_LOCK_OBJ(cx, obj); + re = (JSRegExp *) JS_GetInstancePrivate(cx, obj, &js_RegExpClass, NULL); + if (re) { + switch (slot) { + case REGEXP_SOURCE: + *vp = STRING_TO_JSVAL(re->source); + break; + case REGEXP_GLOBAL: + *vp = BOOLEAN_TO_JSVAL((re->flags & JSREG_GLOB) != 0); + break; + case REGEXP_IGNORE_CASE: + *vp = BOOLEAN_TO_JSVAL((re->flags & JSREG_FOLD) != 0); + break; + case REGEXP_MULTILINE: + *vp = BOOLEAN_TO_JSVAL((re->flags & JSREG_MULTILINE) != 0); + break; + } + } + JS_UNLOCK_OBJ(cx, obj); + return JS_TRUE; +} + +static JSBool +regexp_setProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp) +{ + JSBool ok; + jsint slot; + jsdouble lastIndex; + + ok = JS_TRUE; + if (!JSVAL_IS_INT(id)) + return ok; + slot = JSVAL_TO_INT(id); + if (slot == REGEXP_LAST_INDEX) { + if (!js_ValueToNumber(cx, *vp, &lastIndex)) + return JS_FALSE; + lastIndex = js_DoubleToInteger(lastIndex); + ok = js_NewNumberValue(cx, lastIndex, vp) && + JS_SetReservedSlot(cx, obj, 0, *vp); + } + return ok; +} + +/* + * RegExp class static properties and their Perl counterparts: + * + * RegExp.input $_ + * RegExp.multiline $* + * RegExp.lastMatch $& + * RegExp.lastParen $+ + * RegExp.leftContext $` + * RegExp.rightContext $' + */ +enum regexp_static_tinyid { + REGEXP_STATIC_INPUT = -1, + REGEXP_STATIC_MULTILINE = -2, + REGEXP_STATIC_LAST_MATCH = -3, + REGEXP_STATIC_LAST_PAREN = -4, + REGEXP_STATIC_LEFT_CONTEXT = -5, + REGEXP_STATIC_RIGHT_CONTEXT = -6 +}; + +JSBool +js_InitRegExpStatics(JSContext *cx, JSRegExpStatics *res) +{ + JS_ClearRegExpStatics(cx); + return js_AddRoot(cx, &res->input, "res->input"); +} + +void +js_FreeRegExpStatics(JSContext *cx, JSRegExpStatics *res) +{ + if (res->moreParens) { + JS_free(cx, res->moreParens); + res->moreParens = NULL; + } + js_RemoveRoot(cx->runtime, &res->input); +} + +static JSBool +regexp_static_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp) +{ + jsint slot; + JSRegExpStatics *res; + JSString *str; + JSSubString *sub; + + res = &cx->regExpStatics; + if (!JSVAL_IS_INT(id)) + return JS_TRUE; + slot = JSVAL_TO_INT(id); + switch (slot) { + case REGEXP_STATIC_INPUT: + *vp = res->input ? STRING_TO_JSVAL(res->input) + : JS_GetEmptyStringValue(cx); + return JS_TRUE; + case REGEXP_STATIC_MULTILINE: + *vp = BOOLEAN_TO_JSVAL(res->multiline); + return JS_TRUE; + case REGEXP_STATIC_LAST_MATCH: + sub = &res->lastMatch; + break; + case REGEXP_STATIC_LAST_PAREN: + sub = &res->lastParen; + break; + case REGEXP_STATIC_LEFT_CONTEXT: + sub = &res->leftContext; + break; + case REGEXP_STATIC_RIGHT_CONTEXT: + sub = &res->rightContext; + break; + default: + sub = REGEXP_PAREN_SUBSTRING(res, slot); + break; + } + str = js_NewStringCopyN(cx, sub->chars, sub->length, 0); + if (!str) + return JS_FALSE; + *vp = STRING_TO_JSVAL(str); + return JS_TRUE; +} + +static JSBool +regexp_static_setProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp) +{ + JSRegExpStatics *res; + + if (!JSVAL_IS_INT(id)) + return JS_TRUE; + res = &cx->regExpStatics; + /* XXX use if-else rather than switch to keep MSVC1.52 from crashing */ + if (JSVAL_TO_INT(id) == REGEXP_STATIC_INPUT) { + if (!JSVAL_IS_STRING(*vp) && + !JS_ConvertValue(cx, *vp, JSTYPE_STRING, vp)) { + return JS_FALSE; + } + res->input = JSVAL_TO_STRING(*vp); + } else if (JSVAL_TO_INT(id) == REGEXP_STATIC_MULTILINE) { + if (!JSVAL_IS_BOOLEAN(*vp) && + !JS_ConvertValue(cx, *vp, JSTYPE_BOOLEAN, vp)) { + return JS_FALSE; + } + res->multiline = JSVAL_TO_BOOLEAN(*vp); + } + return JS_TRUE; +} + +static JSPropertySpec regexp_static_props[] = { + {"input", + REGEXP_STATIC_INPUT, + JSPROP_ENUMERATE|JSPROP_SHARED, + regexp_static_getProperty, regexp_static_setProperty}, + {"multiline", + REGEXP_STATIC_MULTILINE, + JSPROP_ENUMERATE|JSPROP_SHARED, + regexp_static_getProperty, regexp_static_setProperty}, + {"lastMatch", + REGEXP_STATIC_LAST_MATCH, + JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_SHARED, + regexp_static_getProperty, regexp_static_getProperty}, + {"lastParen", + REGEXP_STATIC_LAST_PAREN, + JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_SHARED, + regexp_static_getProperty, regexp_static_getProperty}, + {"leftContext", + REGEXP_STATIC_LEFT_CONTEXT, + JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_SHARED, + regexp_static_getProperty, regexp_static_getProperty}, + {"rightContext", + REGEXP_STATIC_RIGHT_CONTEXT, + JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_SHARED, + regexp_static_getProperty, regexp_static_getProperty}, + + /* XXX should have block scope and local $1, etc. */ + {"$1", 0, JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_SHARED, + regexp_static_getProperty, regexp_static_getProperty}, + {"$2", 1, JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_SHARED, + regexp_static_getProperty, regexp_static_getProperty}, + {"$3", 2, JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_SHARED, + regexp_static_getProperty, regexp_static_getProperty}, + {"$4", 3, JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_SHARED, + regexp_static_getProperty, regexp_static_getProperty}, + {"$5", 4, JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_SHARED, + regexp_static_getProperty, regexp_static_getProperty}, + {"$6", 5, JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_SHARED, + regexp_static_getProperty, regexp_static_getProperty}, + {"$7", 6, JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_SHARED, + regexp_static_getProperty, regexp_static_getProperty}, + {"$8", 7, JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_SHARED, + regexp_static_getProperty, regexp_static_getProperty}, + {"$9", 8, JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_SHARED, + regexp_static_getProperty, regexp_static_getProperty}, + + {0,0,0,0,0} +}; + +static void +regexp_finalize(JSContext *cx, JSObject *obj) +{ + JSRegExp *re; + + re = (JSRegExp *) JS_GetPrivate(cx, obj); + if (!re) + return; + js_DestroyRegExp(cx, re); +} + +/* Forward static prototype. */ +static JSBool +regexp_exec(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval); + +static JSBool +regexp_call(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + return regexp_exec(cx, JSVAL_TO_OBJECT(argv[-2]), argc, argv, rval); +} + +#if JS_HAS_XDR + +#include "jsxdrapi.h" + +static JSBool +regexp_xdrObject(JSXDRState *xdr, JSObject **objp) +{ + JSRegExp *re; + JSString *source; + uint8 flags; + + if (xdr->mode == JSXDR_ENCODE) { + re = (JSRegExp *) JS_GetPrivate(xdr->cx, *objp); + if (!re) + return JS_FALSE; + source = re->source; + flags = (uint8) re->flags; + } + if (!JS_XDRString(xdr, &source) || + !JS_XDRUint8(xdr, &flags)) { + return JS_FALSE; + } + if (xdr->mode == JSXDR_DECODE) { + *objp = js_NewObject(xdr->cx, &js_RegExpClass, NULL, NULL); + if (!*objp) + return JS_FALSE; + re = js_NewRegExp(xdr->cx, NULL, source, flags, JS_FALSE); + if (!re) + return JS_FALSE; + if (!JS_SetPrivate(xdr->cx, *objp, re) || + !js_SetLastIndex(xdr->cx, *objp, 0)) { + js_DestroyRegExp(xdr->cx, re); + return JS_FALSE; + } + } + return JS_TRUE; +} + +#else /* !JS_HAS_XDR */ + +#define regexp_xdrObject NULL + +#endif /* !JS_HAS_XDR */ + +static uint32 +regexp_mark(JSContext *cx, JSObject *obj, void *arg) +{ + JSRegExp *re = (JSRegExp *) JS_GetPrivate(cx, obj); + if (re) + JS_MarkGCThing(cx, re->source, "source", arg); + return 0; +} + +JSClass js_RegExpClass = { + js_RegExp_str, + JSCLASS_HAS_PRIVATE | JSCLASS_HAS_RESERVED_SLOTS(1), + JS_PropertyStub, JS_PropertyStub, regexp_getProperty, regexp_setProperty, + JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, regexp_finalize, + NULL, NULL, regexp_call, NULL, + regexp_xdrObject, NULL, regexp_mark, 0 +}; + +static const jschar empty_regexp_ucstr[] = {'(', '?', ':', ')', 0}; + +static JSBool +regexp_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval) +{ + JSRegExp *re; + const jschar *source; + jschar *chars; + size_t length, nflags; + uintN flags; + JSString *str; + + if (!JS_InstanceOf(cx, obj, &js_RegExpClass, argv)) + return JS_FALSE; + JS_LOCK_OBJ(cx, obj); + re = (JSRegExp *) JS_GetPrivate(cx, obj); + if (!re) { + JS_UNLOCK_OBJ(cx, obj); + *rval = STRING_TO_JSVAL(cx->runtime->emptyString); + return JS_TRUE; + } + + source = JSSTRING_CHARS(re->source); + length = JSSTRING_LENGTH(re->source); + if (length == 0) { + source = empty_regexp_ucstr; + length = sizeof(empty_regexp_ucstr) / sizeof(jschar) - 1; + } + length += 2; + nflags = 0; + for (flags = re->flags; flags != 0; flags &= flags - 1) + nflags++; + chars = (jschar*) JS_malloc(cx, (length + nflags + 1) * sizeof(jschar)); + if (!chars) { + JS_UNLOCK_OBJ(cx, obj); + return JS_FALSE; + } + + chars[0] = '/'; + js_strncpy(&chars[1], source, length - 2); + chars[length-1] = '/'; + if (nflags) { + if (re->flags & JSREG_GLOB) + chars[length++] = 'g'; + if (re->flags & JSREG_FOLD) + chars[length++] = 'i'; + if (re->flags & JSREG_MULTILINE) + chars[length++] = 'm'; + } + JS_UNLOCK_OBJ(cx, obj); + chars[length] = 0; + + str = js_NewString(cx, chars, length, 0); + if (!str) { + JS_free(cx, chars); + return JS_FALSE; + } + *rval = STRING_TO_JSVAL(str); + return JS_TRUE; +} + +static JSBool +regexp_compile(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval) +{ + JSString *opt, *str; + JSRegExp *oldre, *re; + JSBool ok; + JSObject *obj2; + + if (!JS_InstanceOf(cx, obj, &js_RegExpClass, argv)) + return JS_FALSE; + opt = NULL; + if (argc == 0) { + str = cx->runtime->emptyString; + } else { + if (JSVAL_IS_OBJECT(argv[0])) { + /* + * If we get passed in a RegExp object we construct a new + * RegExp that is a duplicate of it by re-compiling the + * original source code. ECMA requires that it be an error + * here if the flags are specified. (We must use the flags + * from the original RegExp also). + */ + obj2 = JSVAL_TO_OBJECT(argv[0]); + if (obj2 && OBJ_GET_CLASS(cx, obj2) == &js_RegExpClass) { + if (argc >= 2 && !JSVAL_IS_VOID(argv[1])) { /* 'flags' passed */ + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, + JSMSG_NEWREGEXP_FLAGGED); + return JS_FALSE; + } + JS_LOCK_OBJ(cx, obj2); + re = (JSRegExp *) JS_GetPrivate(cx, obj2); + if (!re) { + JS_UNLOCK_OBJ(cx, obj2); + return JS_FALSE; + } + re = js_NewRegExp(cx, NULL, re->source, re->flags, JS_FALSE); + JS_UNLOCK_OBJ(cx, obj2); + goto madeit; + } + } + str = js_ValueToString(cx, argv[0]); + if (!str) + return JS_FALSE; + argv[0] = STRING_TO_JSVAL(str); + if (argc > 1) { + if (JSVAL_IS_VOID(argv[1])) { + opt = NULL; + } else { + opt = js_ValueToString(cx, argv[1]); + if (!opt) + return JS_FALSE; + argv[1] = STRING_TO_JSVAL(opt); + } + } + } + re = js_NewRegExpOpt(cx, NULL, str, opt, JS_FALSE); +madeit: + if (!re) + return JS_FALSE; + JS_LOCK_OBJ(cx, obj); + oldre = (JSRegExp *) JS_GetPrivate(cx, obj); + ok = JS_SetPrivate(cx, obj, re) && js_SetLastIndex(cx, obj, 0); + JS_UNLOCK_OBJ(cx, obj); + if (!ok) { + js_DestroyRegExp(cx, re); + } else { + if (oldre) + js_DestroyRegExp(cx, oldre); + *rval = OBJECT_TO_JSVAL(obj); + } + return ok; +} + +static JSBool +regexp_exec_sub(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + JSBool test, jsval *rval) +{ + JSBool ok; + JSRegExp *re; + jsdouble lastIndex; + JSString *str; + size_t i; + + ok = JS_InstanceOf(cx, obj, &js_RegExpClass, argv); + if (!ok) + return JS_FALSE; + JS_LOCK_OBJ(cx, obj); + re = (JSRegExp *) JS_GetPrivate(cx, obj); + if (!re) { + JS_UNLOCK_OBJ(cx, obj); + return JS_TRUE; + } + + /* NB: we must reach out: after this paragraph, in order to drop re. */ + HOLD_REGEXP(cx, re); + if (re->flags & JSREG_GLOB) { + ok = js_GetLastIndex(cx, obj, &lastIndex); + } else { + lastIndex = 0; + } + JS_UNLOCK_OBJ(cx, obj); + if (!ok) + goto out; + + /* Now that obj is unlocked, it's safe to (potentially) grab the GC lock. */ + if (argc == 0) { + str = cx->regExpStatics.input; + if (!str) { + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, + JSMSG_NO_INPUT, + JS_GetStringBytes(re->source), + (re->flags & JSREG_GLOB) ? "g" : "", + (re->flags & JSREG_FOLD) ? "i" : "", + (re->flags & JSREG_MULTILINE) ? "m" : ""); + ok = JS_FALSE; + goto out; + } + } else { + str = js_ValueToString(cx, argv[0]); + if (!str) + goto out; + argv[0] = STRING_TO_JSVAL(str); + } + + if (lastIndex < 0 || JSSTRING_LENGTH(str) < lastIndex) { + ok = js_SetLastIndex(cx, obj, 0); + *rval = JSVAL_NULL; + } else { + i = (size_t) lastIndex; + ok = js_ExecuteRegExp(cx, re, str, &i, test, rval); + if (ok && (re->flags & JSREG_GLOB)) + ok = js_SetLastIndex(cx, obj, (*rval == JSVAL_NULL) ? 0 : i); + } + +out: + DROP_REGEXP(cx, re); + return ok; +} + +static JSBool +regexp_exec(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + return regexp_exec_sub(cx, obj, argc, argv, JS_FALSE, rval); +} + +static JSBool +regexp_test(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + if (!regexp_exec_sub(cx, obj, argc, argv, JS_TRUE, rval)) + return JS_FALSE; + if (*rval != JSVAL_TRUE) + *rval = JSVAL_FALSE; + return JS_TRUE; +} + +static JSFunctionSpec regexp_methods[] = { +#if JS_HAS_TOSOURCE + {js_toSource_str, regexp_toString, 0,0,0}, +#endif + {js_toString_str, regexp_toString, 0,0,0}, + {"compile", regexp_compile, 1,0,0}, + {"exec", regexp_exec, 0,0,0}, + {"test", regexp_test, 0,0,0}, + {0,0,0,0,0} +}; + +static JSBool +RegExp(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + if (!(cx->fp->flags & JSFRAME_CONSTRUCTING)) { + /* + * If first arg is regexp and no flags are given, just return the arg. + * (regexp_compile detects the regexp + flags case and throws a + * TypeError.) See 10.15.3.1. + */ + if ((argc < 2 || JSVAL_IS_VOID(argv[1])) && JSVAL_IS_OBJECT(argv[0]) && + OBJ_GET_CLASS(cx, JSVAL_TO_OBJECT(argv[0])) == &js_RegExpClass) { + *rval = argv[0]; + return JS_TRUE; + } + + /* Otherwise, replace obj with a new RegExp object. */ + obj = js_NewObject(cx, &js_RegExpClass, NULL, NULL); + if (!obj) + return JS_FALSE; + } + return regexp_compile(cx, obj, argc, argv, rval); +} + +JSObject * +js_InitRegExpClass(JSContext *cx, JSObject *obj) +{ + JSObject *proto, *ctor; + jsval rval; + + proto = JS_InitClass(cx, obj, NULL, &js_RegExpClass, RegExp, 1, + regexp_props, regexp_methods, + regexp_static_props, NULL); + + if (!proto || !(ctor = JS_GetConstructor(cx, proto))) + return NULL; + if (!JS_AliasProperty(cx, ctor, "input", "$_") || + !JS_AliasProperty(cx, ctor, "multiline", "$*") || + !JS_AliasProperty(cx, ctor, "lastMatch", "$&") || + !JS_AliasProperty(cx, ctor, "lastParen", "$+") || + !JS_AliasProperty(cx, ctor, "leftContext", "$`") || + !JS_AliasProperty(cx, ctor, "rightContext", "$'")) { + goto bad; + } + + /* Give RegExp.prototype private data so it matches the empty string. */ + if (!regexp_compile(cx, proto, 0, NULL, &rval)) + goto bad; + return proto; + +bad: + JS_DeleteProperty(cx, obj, js_RegExpClass.name); + return NULL; +} + +JSObject * +js_NewRegExpObject(JSContext *cx, JSTokenStream *ts, + jschar *chars, size_t length, uintN flags) +{ + JSString *str; + JSObject *obj; + JSRegExp *re; + + str = js_NewStringCopyN(cx, chars, length, 0); + if (!str) + return NULL; + re = js_NewRegExp(cx, ts, str, flags, JS_FALSE); + if (!re) + return NULL; + obj = js_NewObject(cx, &js_RegExpClass, NULL, NULL); + if (!obj || !JS_SetPrivate(cx, obj, re) || !js_SetLastIndex(cx, obj, 0)) { + js_DestroyRegExp(cx, re); + return NULL; + } + return obj; +} + +JSObject * +js_CloneRegExpObject(JSContext *cx, JSObject *obj, JSObject *parent) +{ + JSObject *clone; + JSRegExp *re; + + JS_ASSERT(OBJ_GET_CLASS(cx, obj) == &js_RegExpClass); + clone = js_NewObject(cx, &js_RegExpClass, NULL, parent); + if (!clone) + return NULL; + re = JS_GetPrivate(cx, obj); + if (!JS_SetPrivate(cx, clone, re) || !js_SetLastIndex(cx, clone, 0)) { + cx->newborn[GCX_OBJECT] = NULL; + return NULL; + } + HOLD_REGEXP(cx, re); + return clone; +} + +JSBool +js_GetLastIndex(JSContext *cx, JSObject *obj, jsdouble *lastIndex) +{ + jsval v; + + return JS_GetReservedSlot(cx, obj, 0, &v) && + js_ValueToNumber(cx, v, lastIndex); +} + +JSBool +js_SetLastIndex(JSContext *cx, JSObject *obj, jsdouble lastIndex) +{ + jsval v; + + return js_NewNumberValue(cx, lastIndex, &v) && + JS_SetReservedSlot(cx, obj, 0, v); +} + +#endif /* JS_HAS_REGEXPS */ diff --git a/src/extension/script/js/jsregexp.h b/src/extension/script/js/jsregexp.h new file mode 100644 index 000000000..0485c2860 --- /dev/null +++ b/src/extension/script/js/jsregexp.h @@ -0,0 +1,168 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef jsregexp_h___ +#define jsregexp_h___ +/* + * JS regular expression interface. + */ +#include +#include "jspubtd.h" +#include "jsstr.h" + +#ifdef JS_THREADSAFE +#include "jsdhash.h" +#endif + +struct JSRegExpStatics { + JSString *input; /* input string to match (perl $_, GC root) */ + JSBool multiline; /* whether input contains newlines (perl $*) */ + uintN parenCount; /* number of valid elements in parens[] */ + uintN moreLength; /* number of allocated elements in moreParens */ + JSSubString parens[9]; /* last set of parens matched (perl $1, $2) */ + JSSubString *moreParens; /* null or realloc'd vector for $10, etc. */ + JSSubString lastMatch; /* last string matched (perl $&) */ + JSSubString lastParen; /* last paren matched (perl $+) */ + JSSubString leftContext; /* input to left of last match (perl $`) */ + JSSubString rightContext; /* input to right of last match (perl $') */ +}; + +/* + * This struct holds a bitmap representation of a class from a regexp. + * There's a list of these referenced by the classList field in the JSRegExp + * struct below. The initial state has startIndex set to the offset in the + * original regexp source of the beginning of the class contents. The first + * use of the class converts the source representation into a bitmap. + * + */ +typedef struct RECharSet { + JSBool converted; + JSBool sense; + uint16 length; + union { + uint8 *bits; + struct { + uint16 startIndex; + uint16 length; + } src; + } u; +} RECharSet; + +/* + * This macro is safe because moreParens is guaranteed to be allocated and big + * enough to hold parenCount, or else be null when parenCount is 0. + */ +#define REGEXP_PAREN_SUBSTRING(res, num) \ + (((jsuint)(num) < (jsuint)(res)->parenCount) \ + ? ((jsuint)(num) < 9) \ + ? &(res)->parens[num] \ + : &(res)->moreParens[(num) - 9] \ + : &js_EmptySubString) + +typedef struct RENode RENode; + +struct JSRegExp { + jsrefcount nrefs; /* reference count */ + uint32 parenCount:24, /* number of parenthesized submatches */ + flags:8; /* flags, see jsapi.h's JSREG_* defines */ + uint32 classCount; /* count [...] bitmaps */ + RECharSet *classList; /* list of [...] bitmaps */ + JSString *source; /* locked source string, sans // */ + jsbytecode program[1]; /* regular expression bytecode */ +}; + +extern JSRegExp * +js_NewRegExp(JSContext *cx, JSTokenStream *ts, + JSString *str, uintN flags, JSBool flat); + +extern JSRegExp * +js_NewRegExpOpt(JSContext *cx, JSTokenStream *ts, + JSString *str, JSString *opt, JSBool flat); + +extern void +js_DestroyRegExp(JSContext *cx, JSRegExp *re); + +/* + * Execute re on input str at *indexp, returning null in *rval on mismatch. + * On match, return true if test is true, otherwise return an array object. + * Update *indexp and cx->regExpStatics always on match. + */ +extern JSBool +js_ExecuteRegExp(JSContext *cx, JSRegExp *re, JSString *str, size_t *indexp, + JSBool test, jsval *rval); + +/* + * These two add and remove GC roots, respectively, so their calls must be + * well-ordered. + */ +extern JSBool +js_InitRegExpStatics(JSContext *cx, JSRegExpStatics *res); + +extern void +js_FreeRegExpStatics(JSContext *cx, JSRegExpStatics *res); + +#define JSVAL_IS_REGEXP(cx, v) \ + (JSVAL_IS_OBJECT(v) && JSVAL_TO_OBJECT(v) && \ + OBJ_GET_CLASS(cx, JSVAL_TO_OBJECT(v)) == &js_RegExpClass) + +extern JSClass js_RegExpClass; + +extern JSObject * +js_InitRegExpClass(JSContext *cx, JSObject *obj); + +/* + * Create a new RegExp object. + */ +extern JSObject * +js_NewRegExpObject(JSContext *cx, JSTokenStream *ts, + jschar *chars, size_t length, uintN flags); + +extern JSBool +js_XDRRegExp(JSXDRState *xdr, JSObject **objp); + +extern JSObject * +js_CloneRegExpObject(JSContext *cx, JSObject *obj, JSObject *parent); + +extern JSBool +js_GetLastIndex(JSContext *cx, JSObject *obj, jsdouble *lastIndex); + +extern JSBool +js_SetLastIndex(JSContext *cx, JSObject *obj, jsdouble lastIndex); + +#endif /* jsregexp_h___ */ diff --git a/src/extension/script/js/jsscan.c b/src/extension/script/js/jsscan.c new file mode 100644 index 000000000..e0bc5cd92 --- /dev/null +++ b/src/extension/script/js/jsscan.c @@ -0,0 +1,1315 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* + * JS lexical scanner. + */ +#include "jsstddef.h" +#include /* first to avoid trouble on some systems */ +#include +#include +#include +#ifdef HAVE_MEMORY_H +#include +#endif +#include +#include +#include +#include "jstypes.h" +#include "jsarena.h" /* Added by JSIFY */ +#include "jsutil.h" /* Added by JSIFY */ +#include "jsdtoa.h" +#include "jsprf.h" +#include "jsapi.h" +#include "jsatom.h" +#include "jscntxt.h" +#include "jsconfig.h" +#include "jsemit.h" +#include "jsexn.h" +#include "jsnum.h" +#include "jsopcode.h" +#include "jsregexp.h" +#include "jsscan.h" + +#define RESERVE_JAVA_KEYWORDS +#define RESERVE_ECMA_KEYWORDS + +static struct keyword { + const char *name; + JSTokenType tokentype; /* JSTokenType */ + JSOp op; /* JSOp */ + JSVersion version; /* JSVersion */ +} keywords[] = { + {"break", TOK_BREAK, JSOP_NOP, JSVERSION_DEFAULT}, + {"case", TOK_CASE, JSOP_NOP, JSVERSION_DEFAULT}, + {"continue", TOK_CONTINUE, JSOP_NOP, JSVERSION_DEFAULT}, + {"default", TOK_DEFAULT, JSOP_NOP, JSVERSION_DEFAULT}, + {js_delete_str, TOK_DELETE, JSOP_NOP, JSVERSION_DEFAULT}, + {"do", TOK_DO, JSOP_NOP, JSVERSION_DEFAULT}, + {"else", TOK_ELSE, JSOP_NOP, JSVERSION_DEFAULT}, + {"export", TOK_EXPORT, JSOP_NOP, JSVERSION_1_2}, + {js_false_str, TOK_PRIMARY, JSOP_FALSE, JSVERSION_DEFAULT}, + {"for", TOK_FOR, JSOP_NOP, JSVERSION_DEFAULT}, + {js_function_str, TOK_FUNCTION, JSOP_NOP, JSVERSION_DEFAULT}, + {"if", TOK_IF, JSOP_NOP, JSVERSION_DEFAULT}, + {js_in_str, TOK_IN, JSOP_IN, JSVERSION_DEFAULT}, + {js_new_str, TOK_NEW, JSOP_NEW, JSVERSION_DEFAULT}, + {js_null_str, TOK_PRIMARY, JSOP_NULL, JSVERSION_DEFAULT}, + {"return", TOK_RETURN, JSOP_NOP, JSVERSION_DEFAULT}, + {"switch", TOK_SWITCH, JSOP_NOP, JSVERSION_DEFAULT}, + {js_this_str, TOK_PRIMARY, JSOP_THIS, JSVERSION_DEFAULT}, + {js_true_str, TOK_PRIMARY, JSOP_TRUE, JSVERSION_DEFAULT}, + {js_typeof_str, TOK_UNARYOP, JSOP_TYPEOF,JSVERSION_DEFAULT}, + {"var", TOK_VAR, JSOP_DEFVAR,JSVERSION_DEFAULT}, + {js_void_str, TOK_UNARYOP, JSOP_VOID, JSVERSION_DEFAULT}, + {"while", TOK_WHILE, JSOP_NOP, JSVERSION_DEFAULT}, + {"with", TOK_WITH, JSOP_NOP, JSVERSION_DEFAULT}, + +#if JS_HAS_CONST + {js_const_str, TOK_VAR, JSOP_DEFCONST,JSVERSION_DEFAULT}, +#else + {js_const_str, TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT}, +#endif + +#if JS_HAS_EXCEPTIONS + {"try", TOK_TRY, JSOP_NOP, JSVERSION_DEFAULT}, + {"catch", TOK_CATCH, JSOP_NOP, JSVERSION_DEFAULT}, + {"finally", TOK_FINALLY, JSOP_NOP, JSVERSION_DEFAULT}, + {"throw", TOK_THROW, JSOP_NOP, JSVERSION_DEFAULT}, +#else + {"try", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT}, + {"catch", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT}, + {"finally", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT}, + {"throw", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT}, +#endif + +#if JS_HAS_INSTANCEOF + {js_instanceof_str, TOK_INSTANCEOF, JSOP_INSTANCEOF,JSVERSION_1_4}, +#else + {js_instanceof_str, TOK_RESERVED, JSOP_NOP, JSVERSION_1_4}, +#endif + +#ifdef RESERVE_JAVA_KEYWORDS + {"abstract", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT}, + {"boolean", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT}, + {"byte", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT}, + {"char", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT}, + {"class", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT}, + {"double", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT}, + {"extends", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT}, + {"final", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT}, + {"float", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT}, + {"goto", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT}, + {"implements", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT}, + {"import", TOK_IMPORT, JSOP_NOP, JSVERSION_DEFAULT}, + {"int", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT}, + {"interface", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT}, + {"long", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT}, + {"native", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT}, + {"package", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT}, + {"private", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT}, + {"protected", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT}, + {"public", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT}, + {"short", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT}, + {"static", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT}, + {"super", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT}, + {"synchronized", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT}, + {"throws", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT}, + {"transient", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT}, + {"volatile", TOK_RESERVED, JSOP_NOP, JSVERSION_DEFAULT}, +#endif + +#ifdef RESERVE_ECMA_KEYWORDS + {"enum", TOK_RESERVED, JSOP_NOP, JSVERSION_1_3}, +#endif + +#if JS_HAS_DEBUGGER_KEYWORD + {"debugger", TOK_DEBUGGER, JSOP_NOP, JSVERSION_1_3}, +#elif defined(RESERVE_ECMA_KEYWORDS) + {"debugger", TOK_RESERVED, JSOP_NOP, JSVERSION_1_3}, +#endif + {0, TOK_EOF, JSOP_NOP, JSVERSION_DEFAULT} +}; + +JSBool +js_InitScanner(JSContext *cx) +{ + struct keyword *kw; + JSAtom *atom; + + for (kw = keywords; kw->name; kw++) { + atom = js_Atomize(cx, kw->name, strlen(kw->name), ATOM_PINNED); + if (!atom) + return JS_FALSE; + ATOM_SET_KEYWORD(atom, kw); + } + return JS_TRUE; +} + +JS_FRIEND_API(void) +js_MapKeywords(void (*mapfun)(const char *)) +{ + struct keyword *kw; + + for (kw = keywords; kw->name; kw++) + mapfun(kw->name); +} + +JSTokenStream * +js_NewTokenStream(JSContext *cx, const jschar *base, size_t length, + const char *filename, uintN lineno, + JSPrincipals *principals) +{ + JSTokenStream *ts; + + ts = js_NewBufferTokenStream(cx, base, length); + if (!ts) + return NULL; + ts->filename = filename; + ts->lineno = lineno; + if (principals) + JSPRINCIPALS_HOLD(cx, principals); + ts->principals = principals; + return ts; +} + +JS_FRIEND_API(JSTokenStream *) +js_NewBufferTokenStream(JSContext *cx, const jschar *base, size_t length) +{ + size_t nb; + JSTokenStream *ts; + + nb = sizeof(JSTokenStream) + JS_LINE_LIMIT * sizeof(jschar); + JS_ARENA_ALLOCATE_CAST(ts, JSTokenStream *, &cx->tempPool, nb); + if (!ts) { + JS_ReportOutOfMemory(cx); + return NULL; + } + memset(ts, 0, nb); + ts->lineno = 1; + ts->linebuf.base = ts->linebuf.limit = ts->linebuf.ptr = (jschar *)(ts + 1); + ts->userbuf.base = (jschar *)base; + ts->userbuf.limit = (jschar *)base + length; + ts->userbuf.ptr = (jschar *)base; + ts->listener = cx->runtime->sourceHandler; + ts->listenerData = cx->runtime->sourceHandlerData; + return ts; +} + +JS_FRIEND_API(JSTokenStream *) +js_NewFileTokenStream(JSContext *cx, const char *filename, FILE *defaultfp) +{ + jschar *base; + JSTokenStream *ts; + FILE *file; + + JS_ARENA_ALLOCATE_CAST(base, jschar *, &cx->tempPool, + JS_LINE_LIMIT * sizeof(jschar)); + if (!base) + return NULL; + ts = js_NewBufferTokenStream(cx, base, JS_LINE_LIMIT); + if (!ts) + return NULL; + if (!filename || strcmp(filename, "-") == 0) { + file = defaultfp; + } else { + file = fopen(filename, "r"); + if (!file) { + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_OPEN, + filename, "No such file or directory"); + return NULL; + } + } + ts->userbuf.ptr = ts->userbuf.limit; + ts->file = file; + ts->filename = filename; + return ts; +} + +JS_FRIEND_API(JSBool) +js_CloseTokenStream(JSContext *cx, JSTokenStream *ts) +{ + if (ts->principals) + JSPRINCIPALS_DROP(cx, ts->principals); + return !ts->file || fclose(ts->file) == 0; +} + +static int +my_fgets(char *buf, int size, FILE *file) +{ + int n, i, c; + JSBool crflag; + + n = size - 1; + if (n < 0) + return -1; + + crflag = JS_FALSE; + for (i = 0; i < n && (c = getc(file)) != EOF; i++) { + buf[i] = c; + if (c == '\n') { /* any \n ends a line */ + i++; /* keep the \n; we know there is room for \0 */ + break; + } + if (crflag) { /* \r not followed by \n ends line at the \r */ + ungetc(c, file); + break; /* and overwrite c in buf with \0 */ + } + crflag = (c == '\r'); + } + + buf[i] = '\0'; + return i; +} + +static int32 +GetChar(JSTokenStream *ts) +{ + int32 c; + ptrdiff_t i, j, len, olen; + JSBool crflag; + char cbuf[JS_LINE_LIMIT]; + jschar *ubuf, *nl; + + if (ts->ungetpos != 0) { + c = ts->ungetbuf[--ts->ungetpos]; + } else { + do { + if (ts->linebuf.ptr == ts->linebuf.limit) { + len = PTRDIFF(ts->userbuf.limit, ts->userbuf.ptr, jschar); + if (len <= 0) { + if (!ts->file) { + ts->flags |= TSF_EOF; + return EOF; + } + + /* Fill ts->userbuf so that \r and \r\n convert to \n. */ + crflag = (ts->flags & TSF_CRFLAG) != 0; + len = my_fgets(cbuf, JS_LINE_LIMIT - crflag, ts->file); + if (len <= 0) { + ts->flags |= TSF_EOF; + return EOF; + } + olen = len; + ubuf = ts->userbuf.base; + i = 0; + if (crflag) { + ts->flags &= ~TSF_CRFLAG; + if (cbuf[0] != '\n') { + ubuf[i++] = '\n'; + len++; + ts->linepos--; + } + } + for (j = 0; i < len; i++, j++) + ubuf[i] = (jschar) (unsigned char) cbuf[j]; + ts->userbuf.limit = ubuf + len; + ts->userbuf.ptr = ubuf; + } + if (ts->listener) { + ts->listener(ts->filename, ts->lineno, ts->userbuf.ptr, len, + &ts->listenerTSData, ts->listenerData); + } + + /* + * Any one of \n, \r, or \r\n ends a line (longest match wins). + * Also allow the Unicode line and paragraph separators. + */ + for (nl = ts->userbuf.ptr; nl < ts->userbuf.limit; nl++) { + /* + * Try to prevent value-testing on most characters by + * filtering out characters that aren't 000x or 202x. + */ + if ((*nl & 0xDFD0) == 0) { + if (*nl == '\n') + break; + if (*nl == '\r') { + if (nl + 1 < ts->userbuf.limit && nl[1] == '\n') + nl++; + break; + } + if (*nl == LINE_SEPARATOR || *nl == PARA_SEPARATOR) + break; + } + } + + /* + * If there was a line terminator, copy thru it into linebuf. + * Else copy JS_LINE_LIMIT-1 bytes into linebuf. + */ + if (nl < ts->userbuf.limit) + len = PTRDIFF(nl, ts->userbuf.ptr, jschar) + 1; + if (len >= JS_LINE_LIMIT) + len = JS_LINE_LIMIT - 1; + js_strncpy(ts->linebuf.base, ts->userbuf.ptr, len); + ts->userbuf.ptr += len; + olen = len; + + /* + * Make sure linebuf contains \n for EOL (don't do this in + * userbuf because the user's string might be readonly). + */ + if (nl < ts->userbuf.limit) { + if (*nl == '\r') { + if (ts->linebuf.base[len-1] == '\r') { + /* + * Does the line segment end in \r? We must check + * for a \n at the front of the next segment before + * storing a \n into linebuf. This case matters + * only when we're reading from a file. + */ + if (nl + 1 == ts->userbuf.limit && ts->file) { + len--; + ts->flags |= TSF_CRFLAG; /* clear NLFLAG? */ + if (len == 0) { + /* + * This can happen when a segment ends in + * \r\r. Start over. ptr == limit in this + * case, so we'll fall into buffer-filling + * code. + */ + return GetChar(ts); + } + } else { + ts->linebuf.base[len-1] = '\n'; + } + } + } else if (*nl == '\n') { + if (nl > ts->userbuf.base && + nl[-1] == '\r' && + ts->linebuf.base[len-2] == '\r') { + len--; + JS_ASSERT(ts->linebuf.base[len] == '\n'); + ts->linebuf.base[len-1] = '\n'; + } + } else if (*nl == LINE_SEPARATOR || *nl == PARA_SEPARATOR) { + ts->linebuf.base[len-1] = '\n'; + } + } + + /* Reset linebuf based on adjusted segment length. */ + ts->linebuf.limit = ts->linebuf.base + len; + ts->linebuf.ptr = ts->linebuf.base; + + /* Update position of linebuf within physical userbuf line. */ + if (!(ts->flags & TSF_NLFLAG)) + ts->linepos += ts->linelen; + else + ts->linepos = 0; + if (ts->linebuf.limit[-1] == '\n') + ts->flags |= TSF_NLFLAG; + else + ts->flags &= ~TSF_NLFLAG; + + /* Update linelen from original segment length. */ + ts->linelen = olen; + } + c = *ts->linebuf.ptr++; + } while (JS_ISFORMAT(c)); + } + if (c == '\n') + ts->lineno++; + return c; +} + +static void +UngetChar(JSTokenStream *ts, int32 c) +{ + if (c == EOF) + return; + JS_ASSERT(ts->ungetpos < sizeof ts->ungetbuf / sizeof ts->ungetbuf[0]); + if (c == '\n') + ts->lineno--; + ts->ungetbuf[ts->ungetpos++] = (jschar)c; +} + +static int32 +PeekChar(JSTokenStream *ts) +{ + int32 c; + + c = GetChar(ts); + UngetChar(ts, c); + return c; +} + +static JSBool +PeekChars(JSTokenStream *ts, intN n, jschar *cp) +{ + intN i, j; + int32 c; + + for (i = 0; i < n; i++) { + c = GetChar(ts); + if (c == EOF) + break; + cp[i] = (jschar)c; + } + for (j = i - 1; j >= 0; j--) + UngetChar(ts, cp[j]); + return i == n; +} + +static void +SkipChars(JSTokenStream *ts, intN n) +{ + while (--n >= 0) + GetChar(ts); +} + +static JSBool +MatchChar(JSTokenStream *ts, int32 expect) +{ + int32 c; + + c = GetChar(ts); + if (c == expect) + return JS_TRUE; + UngetChar(ts, c); + return JS_FALSE; +} + +JSBool +js_ReportCompileErrorNumber(JSContext *cx, JSTokenStream *ts, + JSCodeGenerator *cg, uintN flags, + const uintN errorNumber, ...) +{ + va_list ap; + JSErrorReporter onError; + JSErrorReport report; + jschar *tokenptr; + JSString *linestr = NULL; + char *message; + JSBool warning; + + if ((flags & JSREPORT_STRICT) && !JS_HAS_STRICT_OPTION(cx)) + return JS_TRUE; + + memset(&report, 0, sizeof (struct JSErrorReport)); + report.flags = flags; + report.errorNumber = errorNumber; + message = NULL; + + va_start(ap, errorNumber); + if (!js_ExpandErrorArguments(cx, js_GetErrorMessage, NULL, + errorNumber, &message, &report, &warning, + JS_TRUE, ap)) { + return JS_FALSE; + } + va_end(ap); + + js_AddRoot(cx, &linestr, "error line buffer"); + + JS_ASSERT(!ts || ts->linebuf.limit < ts->linebuf.base + JS_LINE_LIMIT); + onError = cx->errorReporter; + if (onError) { + /* + * We are typically called with non-null ts and null cg from jsparse.c. + * We can be called with null ts from the regexp compilation functions. + * The code generator (jsemit.c) may pass null ts and non-null cg. + */ + if (ts) { + report.filename = ts->filename; + report.lineno = ts->lineno; + linestr = js_NewStringCopyN(cx, ts->linebuf.base, + ts->linebuf.limit - ts->linebuf.base, + 0); + report.linebuf = linestr + ? JS_GetStringBytes(linestr) + : NULL; + tokenptr = + ts->tokens[(ts->cursor + ts->lookahead) & NTOKENS_MASK].ptr; + report.tokenptr = linestr + ? report.linebuf + (tokenptr - ts->linebuf.base) + : NULL; + report.uclinebuf = linestr + ? JS_GetStringChars(linestr) + : NULL; + report.uctokenptr = linestr + ? report.uclinebuf + (tokenptr - ts->linebuf.base) + : NULL; + } else if (cg) { + report.filename = cg->filename; + report.lineno = CG_CURRENT_LINE(cg); + } + +#if JS_HAS_ERROR_EXCEPTIONS + /* + * If there's a runtime exception type associated with this error + * number, set that as the pending exception. For errors occuring at + * compile time, this is very likely to be a JSEXN_SYNTAXERR. + * + * If an exception is thrown but not caught, the JSREPORT_EXCEPTION + * flag will be set in report.flags. Proper behavior for an error + * reporter is to ignore a report with this flag for all but top-level + * compilation errors. The exception will remain pending, and so long + * as the non-top-level "load", "eval", or "compile" native function + * returns false, the top-level reporter will eventually receive the + * uncaught exception report. + * + * XXX it'd probably be best if there was only one call to this + * function, but there seem to be two error reporter call points. + */ + + /* + * Only try to raise an exception if there isn't one already set - + * otherwise the exception will describe only the last compile error, + * which is likely spurious. + */ + if (!(ts && (ts->flags & TSF_ERROR))) + if (js_ErrorToException(cx, message, &report)) + onError = NULL; + + /* + * Suppress any compiletime errors that don't occur at the top level. + * This may still fail, as interplevel may be zero in contexts where we + * don't really want to call the error reporter, as when js is called + * by other code which could catch the error. + */ + if (cx->interpLevel != 0) + onError = NULL; +#endif + if (cx->runtime->debugErrorHook && onError) { + JSDebugErrorHook hook = cx->runtime->debugErrorHook; + /* test local in case debugErrorHook changed on another thread */ + if (hook && !hook(cx, message, &report, + cx->runtime->debugErrorHookData)) { + onError = NULL; + } + } + if (onError) + (*onError)(cx, message, &report); + } + if (message) + JS_free(cx, message); + if (report.messageArgs) { + int i = 0; + while (report.messageArgs[i]) + JS_free(cx, (void *)report.messageArgs[i++]); + JS_free(cx, (void *)report.messageArgs); + } + if (report.ucmessage) + JS_free(cx, (void *)report.ucmessage); + + js_RemoveRoot(cx->runtime, &linestr); + + if (ts && !JSREPORT_IS_WARNING(flags)) { + /* Set the error flag to suppress spurious reports. */ + ts->flags |= TSF_ERROR; + } + return warning; +} + +JSTokenType +js_PeekToken(JSContext *cx, JSTokenStream *ts) +{ + JSTokenType tt; + + if (ts->lookahead != 0) { + tt = ts->tokens[(ts->cursor + ts->lookahead) & NTOKENS_MASK].type; + } else { + tt = js_GetToken(cx, ts); + js_UngetToken(ts); + } + return tt; +} + +JSTokenType +js_PeekTokenSameLine(JSContext *cx, JSTokenStream *ts) +{ + JSTokenType tt; + + JS_ASSERT(ts->lookahead == 0 || + ON_CURRENT_LINE(ts, CURRENT_TOKEN(ts).pos)); + ts->flags |= TSF_NEWLINES; + tt = js_PeekToken(cx, ts); + ts->flags &= ~TSF_NEWLINES; + return tt; +} + +#define TBMIN 64 + +static JSBool +GrowTokenBuf(JSContext *cx, JSTokenBuf *tb) +{ + jschar *base; + ptrdiff_t offset, length; + size_t tbsize; + JSArenaPool *pool; + + base = tb->base; + offset = PTRDIFF(tb->ptr, base, jschar); + pool = &cx->tempPool; + if (!base) { + tbsize = TBMIN * sizeof(jschar); + length = TBMIN; + JS_ARENA_ALLOCATE_CAST(base, jschar *, pool, tbsize); + } else { + length = PTRDIFF(tb->limit, base, jschar); + tbsize = length * sizeof(jschar); + length <<= 1; + JS_ARENA_GROW_CAST(base, jschar *, pool, tbsize, tbsize); + } + if (!base) { + JS_ReportOutOfMemory(cx); + return JS_FALSE; + } + tb->base = base; + tb->limit = base + length; + tb->ptr = base + offset; + return JS_TRUE; +} + +static JSBool +AddToTokenBuf(JSContext *cx, JSTokenBuf *tb, jschar c) +{ + if (tb->ptr == tb->limit && !GrowTokenBuf(cx, tb)) + return JS_FALSE; + *tb->ptr++ = c; + return JS_TRUE; +} + +/* + * We have encountered a '\': check for a Unicode escape sequence after it, + * returning the character code value if we found a Unicode escape sequence. + * Otherwise, non-destructively return the original '\'. + */ +static int32 +GetUnicodeEscape(JSTokenStream *ts) +{ + jschar cp[5]; + int32 c; + + if (PeekChars(ts, 5, cp) && cp[0] == 'u' && + JS7_ISHEX(cp[1]) && JS7_ISHEX(cp[2]) && + JS7_ISHEX(cp[3]) && JS7_ISHEX(cp[4])) + { + c = (((((JS7_UNHEX(cp[1]) << 4) + + JS7_UNHEX(cp[2])) << 4) + + JS7_UNHEX(cp[3])) << 4) + + JS7_UNHEX(cp[4]); + SkipChars(ts, 5); + return c; + } + return '\\'; +} + +JSTokenType +js_GetToken(JSContext *cx, JSTokenStream *ts) +{ + JSTokenType tt; + JSToken *tp; + int32 c; + JSAtom *atom; + JSBool hadUnicodeEscape; + +#define INIT_TOKENBUF(tb) ((tb)->ptr = (tb)->base) +#define FINISH_TOKENBUF(tb) if (!AddToTokenBuf(cx, tb, 0)) RETURN(TOK_ERROR) +#define TOKEN_LENGTH(tb) ((tb)->ptr - (tb)->base - 1) +#define RETURN(tt) { if (tt == TOK_ERROR) ts->flags |= TSF_ERROR; \ + tp->pos.end.index = ts->linepos + \ + (ts->linebuf.ptr - ts->linebuf.base) - \ + ts->ungetpos; \ + return (tp->type = tt); } + + /* If there was a fatal error, keep returning TOK_ERROR. */ + if (ts->flags & TSF_ERROR) + return TOK_ERROR; + + /* Check for a pushed-back token resulting from mismatching lookahead. */ + while (ts->lookahead != 0) { + ts->lookahead--; + ts->cursor = (ts->cursor + 1) & NTOKENS_MASK; + tt = CURRENT_TOKEN(ts).type; + if (tt != TOK_EOL || (ts->flags & TSF_NEWLINES)) + return tt; + } + +retry: + do { + c = GetChar(ts); + if (c == '\n') { + ts->flags &= ~TSF_DIRTYLINE; + if (ts->flags & TSF_NEWLINES) + break; + } + } while (JS_ISSPACE(c)); + + ts->cursor = (ts->cursor + 1) & NTOKENS_MASK; + tp = &CURRENT_TOKEN(ts); + tp->ptr = ts->linebuf.ptr - 1; + tp->pos.begin.index = ts->linepos + (tp->ptr - ts->linebuf.base); + tp->pos.begin.lineno = tp->pos.end.lineno = (uint16)ts->lineno; + + if (c == EOF) + RETURN(TOK_EOF); + if (c != '-' && c != '\n') + ts->flags |= TSF_DIRTYLINE; + + hadUnicodeEscape = JS_FALSE; + if (JS_ISIDENT_START(c) || + (c == '\\' && + (c = GetUnicodeEscape(ts), + hadUnicodeEscape = JS_ISIDENT_START(c)))) { + INIT_TOKENBUF(&ts->tokenbuf); + for (;;) { + if (!AddToTokenBuf(cx, &ts->tokenbuf, (jschar)c)) + RETURN(TOK_ERROR); + c = GetChar(ts); + if (c == '\\') { + c = GetUnicodeEscape(ts); + if (!JS_ISIDENT(c)) + break; + hadUnicodeEscape = JS_TRUE; + } else { + if (!JS_ISIDENT(c)) + break; + } + } + UngetChar(ts, c); + FINISH_TOKENBUF(&ts->tokenbuf); + + atom = js_AtomizeChars(cx, + ts->tokenbuf.base, + TOKEN_LENGTH(&ts->tokenbuf), + 0); + if (!atom) + RETURN(TOK_ERROR); + if (!hadUnicodeEscape && ATOM_KEYWORD(atom)) { + struct keyword *kw = ATOM_KEYWORD(atom); + + if (JSVERSION_IS_ECMA(cx->version) || kw->version <= cx->version) { + tp->t_op = (JSOp) kw->op; + RETURN(kw->tokentype); + } + } + tp->t_op = JSOP_NAME; + tp->t_atom = atom; + RETURN(TOK_NAME); + } + + if (JS7_ISDEC(c) || (c == '.' && JS7_ISDEC(PeekChar(ts)))) { + jsint radix; + const jschar *endptr; + jsdouble dval; + + radix = 10; + INIT_TOKENBUF(&ts->tokenbuf); + + if (c == '0') { + if (!AddToTokenBuf(cx, &ts->tokenbuf, (jschar)c)) + RETURN(TOK_ERROR); + c = GetChar(ts); + if (JS_TOLOWER(c) == 'x') { + if (!AddToTokenBuf(cx, &ts->tokenbuf, (jschar)c)) + RETURN(TOK_ERROR); + c = GetChar(ts); + radix = 16; + } else if (JS7_ISDEC(c)) { + radix = 8; + } + } + + while (JS7_ISHEX(c)) { + if (radix < 16) { + if (JS7_ISLET(c)) + break; + + /* + * We permit 08 and 09 as decimal numbers, which makes our + * behaviour a superset of the ECMA numeric grammar. We might + * not always be so permissive, so we warn about it. + */ + if (radix == 8 && c >= '8') { + if (!js_ReportCompileErrorNumber(cx, ts, NULL, + JSREPORT_WARNING, + JSMSG_BAD_OCTAL, + c == '8' ? "08" : "09")) { + RETURN(TOK_ERROR); + } + radix = 10; + } + } + if (!AddToTokenBuf(cx, &ts->tokenbuf, (jschar)c)) + RETURN(TOK_ERROR); + c = GetChar(ts); + } + + if (radix == 10 && (c == '.' || JS_TOLOWER(c) == 'e')) { + if (c == '.') { + do { + if (!AddToTokenBuf(cx, &ts->tokenbuf, (jschar)c)) + RETURN(TOK_ERROR); + c = GetChar(ts); + } while (JS7_ISDEC(c)); + } + if (JS_TOLOWER(c) == 'e') { + if (!AddToTokenBuf(cx, &ts->tokenbuf, (jschar)c)) + RETURN(TOK_ERROR); + c = GetChar(ts); + if (c == '+' || c == '-') { + if (!AddToTokenBuf(cx, &ts->tokenbuf, (jschar)c)) + RETURN(TOK_ERROR); + c = GetChar(ts); + } + if (!JS7_ISDEC(c)) { + js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR, + JSMSG_MISSING_EXPONENT); + RETURN(TOK_ERROR); + } + do { + if (!AddToTokenBuf(cx, &ts->tokenbuf, (jschar)c)) + RETURN(TOK_ERROR); + c = GetChar(ts); + } while (JS7_ISDEC(c)); + } + } + + UngetChar(ts, c); + FINISH_TOKENBUF(&ts->tokenbuf); + + if (radix == 10) { + if (!js_strtod(cx, ts->tokenbuf.base, &endptr, &dval)) { + js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR, + JSMSG_OUT_OF_MEMORY); + RETURN(TOK_ERROR); + } + } else { + if (!js_strtointeger(cx, ts->tokenbuf.base, &endptr, radix, &dval)) { + js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR, + JSMSG_OUT_OF_MEMORY); + RETURN(TOK_ERROR); + } + } + tp->t_dval = dval; + RETURN(TOK_NUMBER); + } + + if (c == '"' || c == '\'') { + int32 val, qc = c; + + INIT_TOKENBUF(&ts->tokenbuf); + while ((c = GetChar(ts)) != qc) { + if (c == '\n' || c == EOF) { + UngetChar(ts, c); + js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR, + JSMSG_UNTERMINATED_STRING); + RETURN(TOK_ERROR); + } + if (c == '\\') { + switch (c = GetChar(ts)) { + case 'b': c = '\b'; break; + case 'f': c = '\f'; break; + case 'n': c = '\n'; break; + case 'r': c = '\r'; break; + case 't': c = '\t'; break; + case 'v': c = '\v'; break; + + default: + if ('0' <= c && c < '8') { + val = JS7_UNDEC(c); + c = PeekChar(ts); + if ('0' <= c && c < '8') { + val = 8 * val + JS7_UNDEC(c); + GetChar(ts); + c = PeekChar(ts); + if ('0' <= c && c < '8') { + int32 save = val; + val = 8 * val + JS7_UNDEC(c); + if (val <= 0377) + GetChar(ts); + else + val = save; + } + } + c = (jschar)val; + } else if (c == 'u') { + jschar cp[4]; + if (PeekChars(ts, 4, cp) && + JS7_ISHEX(cp[0]) && JS7_ISHEX(cp[1]) && + JS7_ISHEX(cp[2]) && JS7_ISHEX(cp[3])) { + c = (((((JS7_UNHEX(cp[0]) << 4) + + JS7_UNHEX(cp[1])) << 4) + + JS7_UNHEX(cp[2])) << 4) + + JS7_UNHEX(cp[3]); + SkipChars(ts, 4); + } + } else if (c == 'x') { + jschar cp[2]; + if (PeekChars(ts, 2, cp) && + JS7_ISHEX(cp[0]) && JS7_ISHEX(cp[1])) { + c = (JS7_UNHEX(cp[0]) << 4) + JS7_UNHEX(cp[1]); + SkipChars(ts, 2); + } + } else if (c == '\n' && JSVERSION_IS_ECMA(cx->version)) { + /* ECMA follows C by removing escaped newlines. */ + continue; + } + break; + } + } + if (!AddToTokenBuf(cx, &ts->tokenbuf, (jschar)c)) + RETURN(TOK_ERROR); + } + FINISH_TOKENBUF(&ts->tokenbuf); + atom = js_AtomizeChars(cx, + ts->tokenbuf.base, + TOKEN_LENGTH(&ts->tokenbuf), + 0); + if (!atom) + RETURN(TOK_ERROR); + tp->pos.end.lineno = (uint16)ts->lineno; + tp->t_op = JSOP_STRING; + tp->t_atom = atom; + RETURN(TOK_STRING); + } + + switch (c) { + case '\n': + c = TOK_EOL; + break; + + case ';': c = TOK_SEMI; break; + case '.': c = TOK_DOT; break; + case '[': c = TOK_LB; break; + case ']': c = TOK_RB; break; + case '{': c = TOK_LC; break; + case '}': c = TOK_RC; break; + case '(': c = TOK_LP; break; + case ')': c = TOK_RP; break; + case ',': c = TOK_COMMA; break; + case '?': c = TOK_HOOK; break; + + case ':': + /* + * Default so compiler can modify to JSOP_GETTER if 'p getter: v' in an + * object initializer, likewise for setter. + */ + tp->t_op = JSOP_NOP; + c = TOK_COLON; + break; + + case '|': + if (MatchChar(ts, c)) { + c = TOK_OR; + } else if (MatchChar(ts, '=')) { + tp->t_op = JSOP_BITOR; + c = TOK_ASSIGN; + } else { + c = TOK_BITOR; + } + break; + + case '^': + if (MatchChar(ts, '=')) { + tp->t_op = JSOP_BITXOR; + c = TOK_ASSIGN; + } else { + c = TOK_BITXOR; + } + break; + + case '&': + if (MatchChar(ts, c)) { + c = TOK_AND; + } else if (MatchChar(ts, '=')) { + tp->t_op = JSOP_BITAND; + c = TOK_ASSIGN; + } else { + c = TOK_BITAND; + } + break; + + case '=': + if (MatchChar(ts, c)) { +#if JS_HAS_TRIPLE_EQOPS + tp->t_op = MatchChar(ts, c) ? JSOP_NEW_EQ : (JSOp)cx->jsop_eq; +#else + tp->t_op = cx->jsop_eq; +#endif + c = TOK_EQOP; + } else { + tp->t_op = JSOP_NOP; + c = TOK_ASSIGN; + } + break; + + case '!': + if (MatchChar(ts, '=')) { +#if JS_HAS_TRIPLE_EQOPS + tp->t_op = MatchChar(ts, '=') ? JSOP_NEW_NE : (JSOp)cx->jsop_ne; +#else + tp->t_op = cx->jsop_ne; +#endif + c = TOK_EQOP; + } else { + tp->t_op = JSOP_NOT; + c = TOK_UNARYOP; + } + break; + + case '<': + /* NB: treat HTML begin-comment as comment-till-end-of-line */ + if (MatchChar(ts, '!')) { + if (MatchChar(ts, '-')) { + if (MatchChar(ts, '-')) + goto skipline; + UngetChar(ts, '-'); + } + UngetChar(ts, '!'); + } + if (MatchChar(ts, c)) { + tp->t_op = JSOP_LSH; + c = MatchChar(ts, '=') ? TOK_ASSIGN : TOK_SHOP; + } else { + tp->t_op = MatchChar(ts, '=') ? JSOP_LE : JSOP_LT; + c = TOK_RELOP; + } + break; + + case '>': + if (MatchChar(ts, c)) { + tp->t_op = MatchChar(ts, c) ? JSOP_URSH : JSOP_RSH; + c = MatchChar(ts, '=') ? TOK_ASSIGN : TOK_SHOP; + } else { + tp->t_op = MatchChar(ts, '=') ? JSOP_GE : JSOP_GT; + c = TOK_RELOP; + } + break; + + case '*': + tp->t_op = JSOP_MUL; + c = MatchChar(ts, '=') ? TOK_ASSIGN : TOK_STAR; + break; + + case '/': + if (MatchChar(ts, '/')) { +skipline: + while ((c = GetChar(ts)) != EOF && c != '\n') + /* skip to end of line */; + UngetChar(ts, c); + goto retry; + } + if (MatchChar(ts, '*')) { + while ((c = GetChar(ts)) != EOF && + !(c == '*' && MatchChar(ts, '/'))) { + /* Ignore all characters until comment close. */ + } + if (c == EOF) { + js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR, + JSMSG_UNTERMINATED_COMMENT); + RETURN(TOK_ERROR); + } + goto retry; + } + +#if JS_HAS_REGEXPS + if (ts->flags & TSF_REGEXP) { + JSObject *obj; + uintN flags; + + INIT_TOKENBUF(&ts->tokenbuf); + while ((c = GetChar(ts)) != '/') { + if (c == '\n' || c == EOF) { + UngetChar(ts, c); + js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR, + JSMSG_UNTERMINATED_REGEXP); + RETURN(TOK_ERROR); + } + if (c == '\\') { + if (!AddToTokenBuf(cx, &ts->tokenbuf, (jschar)c)) + RETURN(TOK_ERROR); + c = GetChar(ts); + } + if (!AddToTokenBuf(cx, &ts->tokenbuf, (jschar)c)) + RETURN(TOK_ERROR); + } + FINISH_TOKENBUF(&ts->tokenbuf); + for (flags = 0; ; ) { + if (MatchChar(ts, 'g')) + flags |= JSREG_GLOB; + else if (MatchChar(ts, 'i')) + flags |= JSREG_FOLD; + else if (MatchChar(ts, 'm')) + flags |= JSREG_MULTILINE; + else + break; + } + c = PeekChar(ts); + if (JS7_ISLET(c)) { + tp->ptr = ts->linebuf.ptr - 1; + js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR, + JSMSG_BAD_REGEXP_FLAG); + (void) GetChar(ts); + RETURN(TOK_ERROR); + } + obj = js_NewRegExpObject(cx, ts, + ts->tokenbuf.base, + TOKEN_LENGTH(&ts->tokenbuf), + flags); + if (!obj) + RETURN(TOK_ERROR); + atom = js_AtomizeObject(cx, obj, 0); + if (!atom) + RETURN(TOK_ERROR); + tp->t_op = JSOP_OBJECT; + tp->t_atom = atom; + RETURN(TOK_OBJECT); + } +#endif /* JS_HAS_REGEXPS */ + + tp->t_op = JSOP_DIV; + c = MatchChar(ts, '=') ? TOK_ASSIGN : TOK_DIVOP; + break; + + case '%': + tp->t_op = JSOP_MOD; + c = MatchChar(ts, '=') ? TOK_ASSIGN : TOK_DIVOP; + break; + + case '~': + tp->t_op = JSOP_BITNOT; + c = TOK_UNARYOP; + break; + + case '+': + if (MatchChar(ts, '=')) { + tp->t_op = JSOP_ADD; + c = TOK_ASSIGN; + } else if (MatchChar(ts, c)) { + c = TOK_INC; + } else { + tp->t_op = JSOP_POS; + c = TOK_PLUS; + } + break; + + case '-': + if (MatchChar(ts, '=')) { + tp->t_op = JSOP_SUB; + c = TOK_ASSIGN; + } else if (MatchChar(ts, c)) { + if (PeekChar(ts) == '>' && !(ts->flags & TSF_DIRTYLINE)) + goto skipline; + c = TOK_DEC; + } else { + tp->t_op = JSOP_NEG; + c = TOK_MINUS; + } + ts->flags |= TSF_DIRTYLINE; + break; + +#if JS_HAS_SHARP_VARS + case '#': + { + uint32 n; + + c = GetChar(ts); + if (!JS7_ISDEC(c)) { + UngetChar(ts, c); + goto badchar; + } + n = (uint32)JS7_UNDEC(c); + for (;;) { + c = GetChar(ts); + if (!JS7_ISDEC(c)) + break; + n = 10 * n + JS7_UNDEC(c); + if (n >= ATOM_INDEX_LIMIT) { + js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR, + JSMSG_SHARPVAR_TOO_BIG); + RETURN(TOK_ERROR); + } + } + tp->t_dval = (jsdouble) n; + if (JS_HAS_STRICT_OPTION(cx) && + (c == '=' || c == '#')) { + char buf[20]; + JS_snprintf(buf, sizeof buf, "#%u%c", n, c); + if (!js_ReportCompileErrorNumber(cx, ts, NULL, + JSREPORT_WARNING | + JSREPORT_STRICT, + JSMSG_DEPRECATED_USAGE, + buf)) { + RETURN(TOK_ERROR); + } + } + if (c == '=') + RETURN(TOK_DEFSHARP); + if (c == '#') + RETURN(TOK_USESHARP); + goto badchar; + } + + badchar: +#endif /* JS_HAS_SHARP_VARS */ + + default: + js_ReportCompileErrorNumber(cx, ts, NULL, JSREPORT_ERROR, + JSMSG_ILLEGAL_CHARACTER); + RETURN(TOK_ERROR); + } + + JS_ASSERT(c < TOK_LIMIT); + RETURN((JSTokenType)c); + +#undef INIT_TOKENBUF +#undef FINISH_TOKENBUF +#undef TOKEN_LENGTH +#undef RETURN +} + +void +js_UngetToken(JSTokenStream *ts) +{ + JS_ASSERT(ts->lookahead < NTOKENS_MASK); + if (ts->flags & TSF_ERROR) + return; + ts->lookahead++; + ts->cursor = (ts->cursor - 1) & NTOKENS_MASK; +} + +JSBool +js_MatchToken(JSContext *cx, JSTokenStream *ts, JSTokenType tt) +{ + if (js_GetToken(cx, ts) == tt) + return JS_TRUE; + js_UngetToken(ts); + return JS_FALSE; +} diff --git a/src/extension/script/js/jsscan.h b/src/extension/script/js/jsscan.h new file mode 100644 index 000000000..c61eff926 --- /dev/null +++ b/src/extension/script/js/jsscan.h @@ -0,0 +1,264 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef jsscan_h___ +#define jsscan_h___ +/* + * JS lexical scanner interface. + */ +#include +#include +#include "jsopcode.h" +#include "jsprvtd.h" +#include "jspubtd.h" + +JS_BEGIN_EXTERN_C + +typedef enum JSTokenType { + TOK_ERROR = -1, /* well-known as the only code < EOF */ + TOK_EOF = 0, /* end of file */ + TOK_EOL = 1, /* end of line */ + TOK_SEMI = 2, /* semicolon */ + TOK_COMMA = 3, /* comma operator */ + TOK_ASSIGN = 4, /* assignment ops (= += -= etc.) */ + TOK_HOOK = 5, TOK_COLON = 6, /* conditional (?:) */ + TOK_OR = 7, /* logical or (||) */ + TOK_AND = 8, /* logical and (&&) */ + TOK_BITOR = 9, /* bitwise-or (|) */ + TOK_BITXOR = 10, /* bitwise-xor (^) */ + TOK_BITAND = 11, /* bitwise-and (&) */ + TOK_EQOP = 12, /* equality ops (== !=) */ + TOK_RELOP = 13, /* relational ops (< <= > >=) */ + TOK_SHOP = 14, /* shift ops (<< >> >>>) */ + TOK_PLUS = 15, /* plus */ + TOK_MINUS = 16, /* minus */ + TOK_STAR = 17, TOK_DIVOP = 18, /* multiply/divide ops (* / %) */ + TOK_UNARYOP = 19, /* unary prefix operator */ + TOK_INC = 20, TOK_DEC = 21, /* increment/decrement (++ --) */ + TOK_DOT = 22, /* member operator (.) */ + TOK_LB = 23, TOK_RB = 24, /* left and right brackets */ + TOK_LC = 25, TOK_RC = 26, /* left and right curlies (braces) */ + TOK_LP = 27, TOK_RP = 28, /* left and right parentheses */ + TOK_NAME = 29, /* identifier */ + TOK_NUMBER = 30, /* numeric constant */ + TOK_STRING = 31, /* string constant */ + TOK_OBJECT = 32, /* RegExp or other object constant */ + TOK_PRIMARY = 33, /* true, false, null, this, super */ + TOK_FUNCTION = 34, /* function keyword */ + TOK_EXPORT = 35, /* export keyword */ + TOK_IMPORT = 36, /* import keyword */ + TOK_IF = 37, /* if keyword */ + TOK_ELSE = 38, /* else keyword */ + TOK_SWITCH = 39, /* switch keyword */ + TOK_CASE = 40, /* case keyword */ + TOK_DEFAULT = 41, /* default keyword */ + TOK_WHILE = 42, /* while keyword */ + TOK_DO = 43, /* do keyword */ + TOK_FOR = 44, /* for keyword */ + TOK_BREAK = 45, /* break keyword */ + TOK_CONTINUE = 46, /* continue keyword */ + TOK_IN = 47, /* in keyword */ + TOK_VAR = 48, /* var keyword */ + TOK_WITH = 49, /* with keyword */ + TOK_RETURN = 50, /* return keyword */ + TOK_NEW = 51, /* new keyword */ + TOK_DELETE = 52, /* delete keyword */ + TOK_DEFSHARP = 53, /* #n= for object/array initializers */ + TOK_USESHARP = 54, /* #n# for object/array initializers */ + TOK_TRY = 55, /* try keyword */ + TOK_CATCH = 56, /* catch keyword */ + TOK_FINALLY = 57, /* finally keyword */ + TOK_THROW = 58, /* throw keyword */ + TOK_INSTANCEOF = 59, /* instanceof keyword */ + TOK_DEBUGGER = 60, /* debugger keyword */ + TOK_RESERVED, /* reserved keywords */ + TOK_LIMIT /* domain size */ +} JSTokenType; + +#define IS_PRIMARY_TOKEN(tt) \ + ((uintN)((tt) - TOK_NAME) <= (uintN)(TOK_PRIMARY - TOK_NAME)) + +struct JSTokenPtr { + uint16 index; /* index of char in physical line */ + uint16 lineno; /* physical line number */ +}; + +struct JSTokenPos { + JSTokenPtr begin; /* first character and line of token */ + JSTokenPtr end; /* index 1 past last char, last line */ +}; + +struct JSToken { + JSTokenType type; /* char value or above enumerator */ + JSTokenPos pos; /* token position in file */ + jschar *ptr; /* beginning of token in line buffer */ + union { + struct { + JSOp op; /* operator, for minimal parser */ + JSAtom *atom; /* atom table entry */ + } s; + jsdouble dval; /* floating point number */ + } u; +}; + +#define t_op u.s.op +#define t_atom u.s.atom +#define t_dval u.dval + +typedef struct JSTokenBuf { + jschar *base; /* base of line or stream buffer */ + jschar *limit; /* limit for quick bounds check */ + jschar *ptr; /* next char to get, or slot to use */ +} JSTokenBuf; + +#define JS_LINE_LIMIT 256 /* logical line buffer size limit -- + physical line length is unlimited */ +#define NTOKENS 4 /* 1 current + 2 lookahead, rounded */ +#define NTOKENS_MASK (NTOKENS-1) /* to power of 2 to avoid divmod by 3 */ + +struct JSTokenStream { + JSToken tokens[NTOKENS];/* circular token buffer */ + uintN cursor; /* index of last parsed token */ + uintN lookahead; /* count of lookahead tokens */ + uintN lineno; /* current line number */ + uintN ungetpos; /* next free char slot in ungetbuf */ + jschar ungetbuf[6]; /* at most 6, for \uXXXX lookahead */ + uintN flags; /* flags -- see below */ + ptrdiff_t linelen; /* physical linebuf segment length */ + ptrdiff_t linepos; /* linebuf offset in physical line */ + JSTokenBuf linebuf; /* line buffer for diagnostics */ + JSTokenBuf userbuf; /* user input buffer if !file */ + JSTokenBuf tokenbuf; /* current token string buffer */ + const char *filename; /* input filename or null */ + FILE *file; /* stdio stream if reading from file */ + JSPrincipals *principals; /* principals associated with source */ + JSSourceHandler listener; /* callback for source; eg debugger */ + void *listenerData; /* listener 'this' data */ + void *listenerTSData;/* listener data for this TokenStream */ +}; + +#define CURRENT_TOKEN(ts) ((ts)->tokens[(ts)->cursor]) +#define ON_CURRENT_LINE(ts,pos) ((uint16)(ts)->lineno == (pos).end.lineno) + +/* JSTokenStream flags */ +#define TSF_ERROR 0x01 /* fatal error while compiling */ +#define TSF_EOF 0x02 /* hit end of file */ +#define TSF_NEWLINES 0x04 /* tokenize newlines */ +#define TSF_REGEXP 0x08 /* looking for a regular expression */ +#define TSF_NLFLAG 0x20 /* last linebuf ended with \n */ +#define TSF_CRFLAG 0x40 /* linebuf would have ended with \r */ +#define TSF_DIRTYLINE 0x80 /* stuff other than whitespace since start of line */ + +/* Unicode separators that are treated as line terminators, in addition to \n, \r */ +#define LINE_SEPARATOR 0x2028 +#define PARA_SEPARATOR 0x2029 + +/* + * Create a new token stream, either from an input buffer or from a file. + * Return null on file-open or memory-allocation failure. + * + * NB: All of js_New{,Buffer,File}TokenStream() return a pointer to transient + * memory in the current context's temp pool. This memory is deallocated via + * JS_ARENA_RELEASE() after parsing is finished. + */ +extern JSTokenStream * +js_NewTokenStream(JSContext *cx, const jschar *base, size_t length, + const char *filename, uintN lineno, JSPrincipals *principals); + +extern JS_FRIEND_API(JSTokenStream *) +js_NewBufferTokenStream(JSContext *cx, const jschar *base, size_t length); + +extern JS_FRIEND_API(JSTokenStream *) +js_NewFileTokenStream(JSContext *cx, const char *filename, FILE *defaultfp); + +extern JS_FRIEND_API(JSBool) +js_CloseTokenStream(JSContext *cx, JSTokenStream *ts); + +/* + * Initialize the scanner, installing JS keywords into cx's global scope. + */ +extern JSBool +js_InitScanner(JSContext *cx); + +/* + * Friend-exported API entry point to call a mapping function on each reserved + * identifier in the scanner's keyword table. + */ +extern JS_FRIEND_API(void) +js_MapKeywords(void (*mapfun)(const char *)); + +/* + * Report a compile-time error by its number, using ts or cg to show context. + * Return true for a warning, false for an error. + */ +extern JSBool +js_ReportCompileErrorNumber(JSContext *cx, JSTokenStream *ts, + JSCodeGenerator *cg, uintN flags, + const uintN errorNumber, ...); + +/* + * Look ahead one token and return its type. + */ +extern JSTokenType +js_PeekToken(JSContext *cx, JSTokenStream *ts); + +extern JSTokenType +js_PeekTokenSameLine(JSContext *cx, JSTokenStream *ts); + +/* + * Get the next token from ts. + */ +extern JSTokenType +js_GetToken(JSContext *cx, JSTokenStream *ts); + +/* + * Push back the last scanned token onto ts. + */ +extern void +js_UngetToken(JSTokenStream *ts); + +/* + * Get the next token from ts if its type is tt. + */ +extern JSBool +js_MatchToken(JSContext *cx, JSTokenStream *ts, JSTokenType tt); + +JS_END_EXTERN_C + +#endif /* jsscan_h___ */ diff --git a/src/extension/script/js/jsscope.c b/src/extension/script/js/jsscope.c new file mode 100644 index 000000000..20243e9b7 --- /dev/null +++ b/src/extension/script/js/jsscope.c @@ -0,0 +1,1581 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* + * JS symbol tables. + */ +#include "jsstddef.h" +#include +#include +#include "jstypes.h" +#include "jsarena.h" +#include "jsbit.h" +#include "jsclist.h" +#include "jsdhash.h" +#include "jsutil.h" /* Added by JSIFY */ +#include "jsapi.h" +#include "jsatom.h" +#include "jscntxt.h" +#include "jsdbgapi.h" +#include "jslock.h" +#include "jsnum.h" +#include "jsscope.h" +#include "jsstr.h" + +JSScope * +js_GetMutableScope(JSContext *cx, JSObject *obj) +{ + JSScope *scope, *newscope; + + scope = OBJ_SCOPE(obj); + JS_ASSERT(JS_IS_SCOPE_LOCKED(cx, scope)); + if (scope->object == obj) + return scope; + newscope = js_NewScope(cx, 0, scope->map.ops, LOCKED_OBJ_GET_CLASS(obj), + obj); + if (!newscope) + return NULL; + JS_LOCK_SCOPE(cx, newscope); + obj->map = js_HoldObjectMap(cx, &newscope->map); + scope = (JSScope *) js_DropObjectMap(cx, &scope->map, obj); + JS_TRANSFER_SCOPE_LOCK(cx, scope, newscope); + return newscope; +} + +/* + * JSScope uses multiplicative hashing, _a la_ jsdhash.[ch], but specialized + * to minimize footprint. But if a scope has fewer than SCOPE_HASH_THRESHOLD + * entries, we use linear search and avoid allocating scope->table. + */ +#define SCOPE_HASH_THRESHOLD 6 +#define MIN_SCOPE_SIZE_LOG2 4 +#define MIN_SCOPE_SIZE JS_BIT(MIN_SCOPE_SIZE_LOG2) +#define SCOPE_TABLE_NBYTES(n) ((n) * sizeof(JSScopeProperty *)) + +static void +InitMinimalScope(JSScope *scope) +{ + scope->hashShift = JS_DHASH_BITS - MIN_SCOPE_SIZE_LOG2; + scope->entryCount = scope->removedCount = 0; + scope->table = NULL; + scope->lastProp = NULL; +} + +static JSBool +CreateScopeTable(JSScope *scope) +{ + int sizeLog2; + JSScopeProperty *sprop, **spp; + + JS_ASSERT(!scope->table); + JS_ASSERT(scope->lastProp); + + if (scope->entryCount > SCOPE_HASH_THRESHOLD) { + /* + * Ouch: calloc failed at least once already -- let's try again, + * overallocating to hold at least twice the current population. + */ + sizeLog2 = JS_CeilingLog2(2 * scope->entryCount); + scope->hashShift = JS_DHASH_BITS - sizeLog2; + } else { + JS_ASSERT(scope->hashShift == JS_DHASH_BITS - MIN_SCOPE_SIZE_LOG2); + sizeLog2 = MIN_SCOPE_SIZE_LOG2; + } + + scope->table = (JSScopeProperty **) + calloc(JS_BIT(sizeLog2), sizeof(JSScopeProperty *)); + if (!scope->table) + return JS_FALSE; + + scope->hashShift = JS_DHASH_BITS - sizeLog2; + for (sprop = scope->lastProp; sprop; sprop = sprop->parent) { + spp = js_SearchScope(scope, sprop->id, JS_TRUE); + SPROP_STORE_PRESERVING_COLLISION(spp, sprop); + } + return JS_TRUE; +} + +JSScope * +js_NewScope(JSContext *cx, jsrefcount nrefs, JSObjectOps *ops, JSClass *clasp, + JSObject *obj) +{ + JSScope *scope; + + scope = (JSScope *) JS_malloc(cx, sizeof(JSScope)); + if (!scope) + return NULL; + + js_InitObjectMap(&scope->map, nrefs, ops, clasp); + scope->object = obj; + scope->flags = 0; + InitMinimalScope(scope); + +#ifdef JS_THREADSAFE + scope->ownercx = cx; + memset(&scope->lock, 0, sizeof scope->lock); + + /* + * Set u.link = NULL, not u.count = 0, in case the target architecture's + * null pointer has a non-zero integer representation. + */ + scope->u.link = NULL; + +#ifdef DEBUG + scope->file[0] = scope->file[1] = scope->file[2] = scope->file[3] = NULL; + scope->line[0] = scope->line[1] = scope->line[2] = scope->line[3] = 0; +#endif +#endif + + JS_RUNTIME_METER(cx->runtime, liveScopes); + JS_RUNTIME_METER(cx->runtime, totalScopes); + return scope; +} + +#ifdef DEBUG_SCOPE_COUNT +extern void +js_unlog_scope(JSScope *scope); +#endif + +void +js_DestroyScope(JSContext *cx, JSScope *scope) +{ +#ifdef DEBUG_SCOPE_COUNT + js_unlog_scope(scope); +#endif + +#ifdef JS_THREADSAFE + /* Scope must be single-threaded at this point, so set scope->ownercx. */ + JS_ASSERT(scope->u.count == 0); + scope->ownercx = cx; + js_FinishLock(&scope->lock); +#endif + if (scope->table) + JS_free(cx, scope->table); + +#ifdef DEBUG + JS_LOCK_RUNTIME_VOID(cx->runtime, + cx->runtime->liveScopeProps -= scope->entryCount); +#endif + JS_RUNTIME_UNMETER(cx->runtime, liveScopes); + JS_free(cx, scope); +} + +#ifdef DEBUG_brendan +typedef struct JSScopeStats { + jsrefcount searches; + jsrefcount steps; + jsrefcount hits; + jsrefcount misses; + jsrefcount stepHits; + jsrefcount stepMisses; + jsrefcount adds; + jsrefcount redundantAdds; + jsrefcount addFailures; + jsrefcount changeFailures; + jsrefcount compresses; + jsrefcount grows; + jsrefcount removes; + jsrefcount removeFrees; + jsrefcount uselessRemoves; + jsrefcount shrinks; +} JSScopeStats; + +JS_FRIEND_DATA(JSScopeStats) js_scope_stats; + +# define METER(x) JS_ATOMIC_INCREMENT(&js_scope_stats.x) +#else +# define METER(x) /* nothing */ +#endif + +/* + * Double hashing needs the second hash code to be relatively prime to table + * size, so we simply make hash2 odd. The inputs to multiplicative hash are + * the golden ratio, expressed as a fixed-point 32 bit fraction, and the int + * property index or named property's atom number (observe that most objects + * have either no indexed properties, or almost all indexed and a few names, + * so collisions between index and atom number are unlikely). + */ +#define SCOPE_HASH0(id) (HASH_ID(id) * JS_GOLDEN_RATIO) +#define SCOPE_HASH1(hash0,shift) ((hash0) >> (shift)) +#define SCOPE_HASH2(hash0,log2,shift) ((((hash0) << (log2)) >> (shift)) | 1) + +JS_FRIEND_API(JSScopeProperty **) +js_SearchScope(JSScope *scope, jsid id, JSBool adding) +{ + JSHashNumber hash0, hash1, hash2; + int hashShift, sizeLog2; + JSScopeProperty *stored, *sprop, **spp, **firstRemoved; + uint32 sizeMask; + + METER(searches); + if (!scope->table) { + /* Not enough properties to justify hashing: search from lastProp. */ + JS_ASSERT(!SCOPE_HAD_MIDDLE_DELETE(scope)); + for (spp = &scope->lastProp; (sprop = *spp); spp = &sprop->parent) { + if (sprop->id == id) { + METER(hits); + return spp; + } + } + METER(misses); + return spp; + } + + /* Compute the primary hash address. */ + hash0 = SCOPE_HASH0(id); + hashShift = scope->hashShift; + hash1 = SCOPE_HASH1(hash0, hashShift); + spp = scope->table + hash1; + + /* Miss: return space for a new entry. */ + stored = *spp; + if (SPROP_IS_FREE(stored)) { + METER(misses); + return spp; + } + + /* Hit: return entry. */ + sprop = SPROP_CLEAR_COLLISION(stored); + if (sprop && sprop->id == id) { + METER(hits); + return spp; + } + + /* Collision: double hash. */ + sizeLog2 = JS_DHASH_BITS - hashShift; + hash2 = SCOPE_HASH2(hash0, sizeLog2, hashShift); + sizeMask = JS_BITMASK(sizeLog2); + + /* Save the first removed entry pointer so we can recycle it if adding. */ + if (SPROP_IS_REMOVED(stored)) { + firstRemoved = spp; + } else { + firstRemoved = NULL; + if (adding && !SPROP_HAD_COLLISION(stored)) + SPROP_FLAG_COLLISION(spp, sprop); + } + + for (;;) { + METER(steps); + hash1 -= hash2; + hash1 &= sizeMask; + spp = scope->table + hash1; + + stored = *spp; + if (SPROP_IS_FREE(stored)) { + METER(stepMisses); + return (adding && firstRemoved) ? firstRemoved : spp; + } + + sprop = SPROP_CLEAR_COLLISION(stored); + if (sprop && sprop->id == id) { + METER(stepHits); + return spp; + } + + if (SPROP_IS_REMOVED(stored)) { + if (!firstRemoved) + firstRemoved = spp; + } else { + if (adding && !SPROP_HAD_COLLISION(stored)) + SPROP_FLAG_COLLISION(spp, sprop); + } + } + + /* NOTREACHED */ + return NULL; +} + +static JSBool +ChangeScope(JSContext *cx, JSScope *scope, int change) +{ + int oldlog2, newlog2; + uint32 oldsize, newsize, nbytes; + JSScopeProperty **table, **oldtable, **spp, **oldspp, *sprop; + + /* Grow, shrink, or compress by changing scope->table. */ + oldlog2 = JS_DHASH_BITS - scope->hashShift; + newlog2 = oldlog2 + change; + oldsize = JS_BIT(oldlog2); + newsize = JS_BIT(newlog2); + nbytes = SCOPE_TABLE_NBYTES(newsize); + table = (JSScopeProperty **) calloc(nbytes, 1); + if (!table) { + JS_ReportOutOfMemory(cx); + return JS_FALSE; + } + + /* Now that we have a new table allocated, update scope members. */ + scope->hashShift = JS_DHASH_BITS - newlog2; + scope->removedCount = 0; + oldtable = scope->table; + scope->table = table; + + /* Copy only live entries, leaving removed and free ones behind. */ + for (oldspp = oldtable; oldsize != 0; oldspp++) { + sprop = SPROP_FETCH(oldspp); + if (sprop) { + spp = js_SearchScope(scope, sprop->id, JS_TRUE); + JS_ASSERT(SPROP_IS_FREE(*spp)); + *spp = sprop; + } + oldsize--; + } + + /* Finally, free the old table storage. */ + JS_free(cx, oldtable); + return JS_TRUE; +} + +/* + * Take care to exclude the mark and duplicate bits, in case we're called from + * the GC, or we are searching for a property that has not yet been flagged as + * a duplicate when making a duplicate formal parameter. + */ +#define SPROP_FLAGS_NOT_MATCHED (SPROP_MARK | SPROP_IS_DUPLICATE) + +JS_STATIC_DLL_CALLBACK(JSDHashNumber) +js_HashScopeProperty(JSDHashTable *table, const void *key) +{ + const JSScopeProperty *sprop = (const JSScopeProperty *)key; + JSDHashNumber hash; + JSPropertyOp gsop; + + /* Accumulate from least to most random so the low bits are most random. */ + hash = 0; + gsop = sprop->getter; + if (gsop) + hash = (hash >> (JS_DHASH_BITS - 4)) ^ (hash << 4) ^ (jsword)gsop; + gsop = sprop->setter; + if (gsop) + hash = (hash >> (JS_DHASH_BITS - 4)) ^ (hash << 4) ^ (jsword)gsop; + + hash = (hash >> (JS_DHASH_BITS - 4)) ^ (hash << 4) + ^ (sprop->flags & ~SPROP_FLAGS_NOT_MATCHED); + + hash = (hash >> (JS_DHASH_BITS - 4)) ^ (hash << 4) ^ sprop->attrs; + hash = (hash >> (JS_DHASH_BITS - 4)) ^ (hash << 4) ^ sprop->shortid; + hash = (hash >> (JS_DHASH_BITS - 4)) ^ (hash << 4) ^ sprop->slot; + hash = (hash >> (JS_DHASH_BITS - 4)) ^ (hash << 4) ^ sprop->id; + return hash; +} + +#define SPROP_MATCH(sprop, child) \ + SPROP_MATCH_PARAMS(sprop, (child)->id, (child)->getter, (child)->setter, \ + (child)->slot, (child)->attrs, (child)->flags, \ + (child)->shortid) + +#define SPROP_MATCH_PARAMS(sprop, aid, agetter, asetter, aslot, aattrs, \ + aflags, ashortid) \ + ((sprop)->id == (aid) && \ + SPROP_MATCH_PARAMS_AFTER_ID(sprop, agetter, asetter, aslot, aattrs, \ + aflags, ashortid)) + +#define SPROP_MATCH_PARAMS_AFTER_ID(sprop, agetter, asetter, aslot, aattrs, \ + aflags, ashortid) \ + ((sprop)->getter == (agetter) && \ + (sprop)->setter == (asetter) && \ + (sprop)->slot == (aslot) && \ + (sprop)->attrs == (aattrs) && \ + (((sprop)->flags ^ (aflags)) & ~SPROP_FLAGS_NOT_MATCHED) == 0 && \ + (sprop)->shortid == (ashortid)) + +JS_STATIC_DLL_CALLBACK(JSBool) +js_MatchScopeProperty(JSDHashTable *table, + const JSDHashEntryHdr *hdr, + const void *key) +{ + const JSPropertyTreeEntry *entry = (const JSPropertyTreeEntry *)hdr; + const JSScopeProperty *sprop = entry->child; + const JSScopeProperty *kprop = (const JSScopeProperty *)key; + + return SPROP_MATCH(sprop, kprop); +} + +static const JSDHashTableOps PropertyTreeHashOps = { + JS_DHashAllocTable, + JS_DHashFreeTable, + JS_DHashGetKeyStub, + js_HashScopeProperty, + js_MatchScopeProperty, + JS_DHashMoveEntryStub, + JS_DHashClearEntryStub, + JS_DHashFinalizeStub, + NULL +}; + +/* + * A property tree node on rt->propertyFreeList overlays the following prefix + * struct on JSScopeProperty. + */ +typedef struct FreeNode { + jsid id; + JSScopeProperty *next; + JSScopeProperty **prevp; +} FreeNode; + +#define FREENODE(sprop) ((FreeNode *) (sprop)) + +#define FREENODE_INSERT(list, sprop) \ + JS_BEGIN_MACRO \ + FREENODE(sprop)->next = (list); \ + FREENODE(sprop)->prevp = &(list); \ + if (list) \ + FREENODE(list)->prevp = &FREENODE(sprop)->next; \ + (list) = (sprop); \ + JS_END_MACRO + +#define FREENODE_REMOVE(sprop) \ + JS_BEGIN_MACRO \ + *FREENODE(sprop)->prevp = FREENODE(sprop)->next; \ + if (FREENODE(sprop)->next) \ + FREENODE(FREENODE(sprop)->next)->prevp = FREENODE(sprop)->prevp; \ + JS_END_MACRO + +/* NB: Called with the runtime lock held. */ +static JSScopeProperty * +NewScopeProperty(JSRuntime *rt) +{ + JSScopeProperty *sprop; + + sprop = rt->propertyFreeList; + if (sprop) { + FREENODE_REMOVE(sprop); + } else { + JS_ARENA_ALLOCATE_CAST(sprop, JSScopeProperty *, + &rt->propertyArenaPool, + sizeof(JSScopeProperty)); + if (!sprop) + return NULL; + } + + JS_RUNTIME_METER(rt, livePropTreeNodes); + JS_RUNTIME_METER(rt, totalPropTreeNodes); + return sprop; +} + +#define CHUNKY_KIDS_TAG ((jsuword)1) +#define KIDS_IS_CHUNKY(kids) ((jsuword)(kids) & CHUNKY_KIDS_TAG) +#define KIDS_TO_CHUNK(kids) ((PropTreeKidsChunk *) \ + ((jsuword)(kids) & ~CHUNKY_KIDS_TAG)) +#define CHUNK_TO_KIDS(chunk) ((JSScopeProperty *) \ + ((jsuword)(chunk) | CHUNKY_KIDS_TAG)) +#define MAX_KIDS_PER_CHUNK 10 + +typedef struct PropTreeKidsChunk PropTreeKidsChunk; + +struct PropTreeKidsChunk { + JSScopeProperty *kids[MAX_KIDS_PER_CHUNK]; + PropTreeKidsChunk *next; +}; + +static PropTreeKidsChunk * +NewPropTreeKidsChunk(JSRuntime *rt) +{ + PropTreeKidsChunk *chunk; + + chunk = calloc(1, sizeof *chunk); + if (!chunk) + return NULL; + JS_ASSERT(((jsuword)chunk & CHUNKY_KIDS_TAG) == 0); + JS_RUNTIME_METER(rt, propTreeKidsChunks); + return chunk; +} + +static void +DestroyPropTreeKidsChunk(JSRuntime *rt, PropTreeKidsChunk *chunk) +{ + JS_RUNTIME_UNMETER(rt, propTreeKidsChunks); + free(chunk); +} + +/* NB: Called with the runtime lock held. */ +static JSBool +InsertPropertyTreeChild(JSRuntime *rt, JSScopeProperty *parent, + JSScopeProperty *child) +{ + JSPropertyTreeEntry *entry; + JSScopeProperty **childp, *kids, *sprop; + PropTreeKidsChunk *chunk, **chunkp; + uintN i; + + JS_ASSERT(!parent || child->parent != parent); + + if (!parent) { + entry = (JSPropertyTreeEntry *) + JS_DHashTableOperate(&rt->propertyTreeHash, child, JS_DHASH_ADD); + if (!entry) + return JS_FALSE; + childp = &entry->child; + sprop = *childp; + if (!sprop) { + *childp = child; + } else { + /* + * A "Duplicate child" case. + * + * We can't do away with child, as at least one live scope entry + * still points at it. What's more, that scope's lastProp chains + * through an ancestor line to reach child, and js_Enumerate and + * others count on this linkage. We must leave child out of the + * hash table, and not require it to be there when we eventually + * GC it (see RemovePropertyTreeChild, below). + * + * It is necessary to leave the duplicate child out of the hash + * table to preserve entry uniqueness. It is safe to leave the + * child out of the hash table (unlike the duplicate child cases + * below), because the child's parent link will be null, which + * can't dangle. + */ + JS_ASSERT(sprop != child && SPROP_MATCH(sprop, child)); + JS_RUNTIME_METER(rt, duplicatePropTreeNodes); + } + } else { + childp = &parent->kids; + kids = *childp; + if (kids) { + if (KIDS_IS_CHUNKY(kids)) { + chunk = KIDS_TO_CHUNK(kids); + do { + for (i = 0; i < MAX_KIDS_PER_CHUNK; i++) { + childp = &chunk->kids[i]; + sprop = *childp; + if (!sprop) + goto insert; + + JS_ASSERT(sprop != child); + if (SPROP_MATCH(sprop, child)) { + /* + * Duplicate child, see comment above. In this + * case, we must let the duplicate be inserted at + * this level in the tree, so we keep iterating, + * looking for an empty slot in which to insert. + */ + JS_ASSERT(sprop != child); + JS_RUNTIME_METER(rt, duplicatePropTreeNodes); + } + } + chunkp = &chunk->next; + } while ((chunk = *chunkp) != NULL); + + chunk = NewPropTreeKidsChunk(rt); + if (!chunk) + return JS_FALSE; + *chunkp = chunk; + childp = &chunk->kids[0]; + } else { + sprop = kids; + JS_ASSERT(sprop != child); + if (SPROP_MATCH(sprop, child)) { + /* + * Duplicate child, see comment above. Once again, we + * must let duplicates created by deletion pile up in a + * kids-chunk-list, in order to find them when sweeping + * and thereby avoid dangling parent pointers. + */ + JS_RUNTIME_METER(rt, duplicatePropTreeNodes); + } + + chunk = NewPropTreeKidsChunk(rt); + if (!chunk) + return JS_FALSE; + parent->kids = CHUNK_TO_KIDS(chunk); + chunk->kids[0] = sprop; + childp = &chunk->kids[1]; + } + } + insert: + *childp = child; + } + + child->parent = parent; + return JS_TRUE; +} + +/* NB: Called with the runtime lock held. */ +static void +RemovePropertyTreeChild(JSRuntime *rt, JSScopeProperty *child) +{ + JSPropertyTreeEntry *entry; + JSScopeProperty *parent, *kids, *kid; + PropTreeKidsChunk *list, *chunk, **chunkp, *lastChunk; + uintN i, j; + + parent = child->parent; + if (!parent) { + /* + * Don't remove child if it is not in rt->propertyTreeHash, but only + * matches a root child in the table that has compatible members. See + * the "Duplicate child" comments in InsertPropertyTreeChild, above. + */ + entry = (JSPropertyTreeEntry *) + JS_DHashTableOperate(&rt->propertyTreeHash, child, JS_DHASH_LOOKUP); + + if (entry->child == child) + JS_DHashTableRawRemove(&rt->propertyTreeHash, &entry->hdr); + } else { + kids = parent->kids; + if (KIDS_IS_CHUNKY(kids)) { + list = chunk = KIDS_TO_CHUNK(kids); + chunkp = &list; + + do { + for (i = 0; i < MAX_KIDS_PER_CHUNK; i++) { + if (chunk->kids[i] == child) { + lastChunk = chunk; + if (!lastChunk->next) { + j = i + 1; + } else { + j = 0; + do { + chunkp = &lastChunk->next; + lastChunk = *chunkp; + } while (lastChunk->next); + } + for (; j < MAX_KIDS_PER_CHUNK; j++) { + if (!lastChunk->kids[j]) + break; + } + --j; + if (chunk != lastChunk || j > i) + chunk->kids[i] = lastChunk->kids[j]; + lastChunk->kids[j] = NULL; + if (j == 0) { + *chunkp = NULL; + if (!list) + parent->kids = NULL; + DestroyPropTreeKidsChunk(rt, lastChunk); + } + return; + } + } + + chunkp = &chunk->next; + } while ((chunk = *chunkp) != NULL); + } else { + kid = kids; + if (kid == child) + parent->kids = NULL; + } + } +} + +/* + * Called *without* the runtime lock held, this function acquires that lock + * only when inserting a new child. Thus there may be races to find or add + * a node that result in duplicates. We expect such races to be rare! + */ +static JSScopeProperty * +GetPropertyTreeChild(JSContext *cx, JSScopeProperty *parent, + JSScopeProperty *child) +{ + JSRuntime *rt; + JSPropertyTreeEntry *entry; + JSScopeProperty *sprop; + PropTreeKidsChunk *chunk; + uintN i; + + rt = cx->runtime; + if (!parent) { + JS_LOCK_RUNTIME(rt); + + entry = (JSPropertyTreeEntry *) + JS_DHashTableOperate(&rt->propertyTreeHash, child, JS_DHASH_ADD); + if (!entry) + goto out_of_memory; + + sprop = entry->child; + if (sprop) + goto out; + } else { + /* + * Because chunks are appended at the end and never deleted except by + * the GC, we can search without taking the runtime lock. We may miss + * a matching sprop added by another thread, and make a duplicate one, + * but that is an unlikely, therefore small, cost. The property tree + * has extremely low fan-out below its root in popular embeddings with + * real-world workloads. + * + * If workload changes so as to increase fan-out significantly below + * the property tree root, we'll want to add another tag bit stored in + * parent->kids that indicates a JSDHashTable pointer. + */ + entry = NULL; + sprop = parent->kids; + if (sprop) { + if (KIDS_IS_CHUNKY(sprop)) { + chunk = KIDS_TO_CHUNK(sprop); + do { + for (i = 0; i < MAX_KIDS_PER_CHUNK; i++) { + sprop = chunk->kids[i]; + if (!sprop) + goto not_found; + + if (SPROP_MATCH(sprop, child)) + return sprop; + } + } while ((chunk = chunk->next) != NULL); + } else { + if (SPROP_MATCH(sprop, child)) + return sprop; + } + } + + not_found: + JS_LOCK_RUNTIME(rt); + } + + sprop = NewScopeProperty(rt); + if (!sprop) + goto out_of_memory; + + sprop->id = child->id; + sprop->getter = child->getter; + sprop->setter = child->setter; + sprop->slot = child->slot; + sprop->attrs = child->attrs; + sprop->flags = child->flags; + sprop->shortid = child->shortid; + sprop->parent = sprop->kids = NULL; + if (!parent) { + entry->child = sprop; + } else { + if (!InsertPropertyTreeChild(rt, parent, sprop)) + goto out_of_memory; + } + +out: + JS_UNLOCK_RUNTIME(rt); + return sprop; + +out_of_memory: + JS_UNLOCK_RUNTIME(rt); + JS_ReportOutOfMemory(cx); + return NULL; +} + +#ifdef DEBUG_notbrendan +#define CHECK_ANCESTOR_LINE(scope, sparse) \ + JS_BEGIN_MACRO \ + if ((scope)->table) CheckAncestorLine(scope, sparse); \ + JS_END_MACRO + +static void +CheckAncestorLine(JSScope *scope, JSBool sparse) +{ + uint32 size; + JSScopeProperty **spp, **start, **end, *ancestorLine, *sprop, *aprop; + uint32 entryCount, ancestorCount; + + ancestorLine = SCOPE_LAST_PROP(scope); + if (ancestorLine) + JS_ASSERT(SCOPE_HAS_PROPERTY(scope, ancestorLine)); + + entryCount = 0; + size = SCOPE_CAPACITY(scope); + start = scope->table; + for (spp = start, end = start + size; spp < end; spp++) { + sprop = SPROP_FETCH(spp); + if (sprop) { + entryCount++; + for (aprop = ancestorLine; aprop; aprop = aprop->parent) { + if (aprop == sprop) + break; + } + JS_ASSERT(aprop); + } + } + JS_ASSERT(entryCount == scope->entryCount); + + ancestorCount = 0; + for (sprop = ancestorLine; sprop; sprop = sprop->parent) { + if (SCOPE_HAD_MIDDLE_DELETE(scope) && + !SCOPE_HAS_PROPERTY(scope, sprop)) { + JS_ASSERT(sparse || (sprop->flags & SPROP_IS_DUPLICATE)); + continue; + } + ancestorCount++; + } + JS_ASSERT(ancestorCount == scope->entryCount); +} +#else +#define CHECK_ANCESTOR_LINE(scope, sparse) /* nothing */ +#endif + +static void +ReportReadOnlyScope(JSContext *cx, JSScope *scope) +{ + JSString *str; + + str = js_ValueToString(cx, OBJECT_TO_JSVAL(scope->object)); + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_READ_ONLY, + str + ? JS_GetStringBytes(str) + : LOCKED_OBJ_GET_CLASS(scope->object)->name); +} + +JSScopeProperty * +js_AddScopeProperty(JSContext *cx, JSScope *scope, jsid id, + JSPropertyOp getter, JSPropertyOp setter, uint32 slot, + uintN attrs, uintN flags, intN shortid) +{ + JSScopeProperty **spp, *sprop, *overwriting, **spvec, **spp2, child; + uint32 size, splen, i; + int change; + + JS_ASSERT(JS_IS_SCOPE_LOCKED(cx, scope)); + CHECK_ANCESTOR_LINE(scope, JS_TRUE); + + /* + * You can't add properties to a sealed scope. But note well that you can + * change property attributes in a sealed scope, even though that replaces + * a JSScopeProperty * in the scope's hash table -- but no id is added, so + * the scope remains sealed. + */ + if (SCOPE_IS_SEALED(scope)) { + ReportReadOnlyScope(cx, scope); + return NULL; + } + + /* + * Normalize stub getter and setter values for faster is-stub testing in + * the SPROP_CALL_[GS]ETTER macros. + */ + if (getter == JS_PropertyStub) + getter = NULL; + if (setter == JS_PropertyStub) + setter = NULL; + + /* + * Search for id in order to claim its entry, allocating a property tree + * node if one doesn't already exist for our parameters. + */ + spp = js_SearchScope(scope, id, JS_TRUE); + sprop = overwriting = SPROP_FETCH(spp); + if (!sprop) { + /* Check whether we need to grow, if the load factor is >= .75. */ + size = SCOPE_CAPACITY(scope); + if (scope->entryCount + scope->removedCount >= size - (size >> 2)) { + if (scope->removedCount >= size >> 2) { + METER(compresses); + change = 0; + } else { + METER(grows); + change = 1; + } + if (!ChangeScope(cx, scope, change) && + scope->entryCount + scope->removedCount == size - 1) { + METER(addFailures); + return NULL; + } + spp = js_SearchScope(scope, id, JS_TRUE); + JS_ASSERT(!SPROP_FETCH(spp)); + } + } else { + /* Property exists: js_SearchScope must have returned a valid entry. */ + JS_ASSERT(!SPROP_IS_REMOVED(*spp)); + + /* + * If all property members match, this is a redundant add and we can + * return early. If the caller wants to allocate a slot, but doesn't + * care which slot, copy sprop->slot into slot so we can match sprop, + * if all other members match. + */ + if (!(attrs & JSPROP_SHARED) && + slot == SPROP_INVALID_SLOT && + SPROP_HAS_VALID_SLOT(sprop, scope)) { + slot = sprop->slot; + } + if (SPROP_MATCH_PARAMS_AFTER_ID(sprop, getter, setter, slot, attrs, + flags, shortid)) { + METER(redundantAdds); + return sprop; + } + + /* + * Duplicate formal parameters require us to leave the old property + * on the ancestor line, so the decompiler can find it, even though + * its entry in scope->table is overwritten to point at a new property + * descending from the old one. The SPROP_IS_DUPLICATE flag helps us + * cope with the consequent disparity between ancestor line height and + * scope->entryCount. + */ + if (flags & SPROP_IS_DUPLICATE) { + sprop->flags |= SPROP_IS_DUPLICATE; + } else { + /* + * If we are clearing sprop to force an existing property to be + * overwritten (apart from a duplicate formal parameter), we must + * unlink it from the ancestor line at scope->lastProp, lazily if + * sprop is not lastProp. And we must remove the entry at *spp, + * precisely so the lazy "middle delete" fixup code further below + * won't find sprop in scope->table, in spite of sprop being on + * the ancestor line. + * + * When we finally succeed in finding or creating a new sprop + * and storing its pointer at *spp, we'll use the |overwriting| + * local saved when we first looked up id to decide whether we're + * indeed creating a new entry, or merely overwriting an existing + * property. + */ + if (sprop == SCOPE_LAST_PROP(scope)) { + do { + SCOPE_REMOVE_LAST_PROP(scope); + if (!SCOPE_HAD_MIDDLE_DELETE(scope)) + break; + sprop = SCOPE_LAST_PROP(scope); + } while (sprop && !SCOPE_HAS_PROPERTY(scope, sprop)); + } else if (!SCOPE_HAD_MIDDLE_DELETE(scope)) { + /* + * If we have no hash table yet, we need one now. The middle + * delete code is simple-minded that way! + */ + if (!scope->table) { + if (!CreateScopeTable(scope)) { + JS_ReportOutOfMemory(cx); + return NULL; + } + spp = js_SearchScope(scope, id, JS_TRUE); + sprop = overwriting = SPROP_FETCH(spp); + } + SCOPE_SET_MIDDLE_DELETE(scope); + } + } + + /* + * If we fail later on trying to find or create a new sprop, we will + * goto fail_overwrite and restore *spp from |overwriting|. Note that + * we don't bother to keep scope->removedCount in sync, because we'll + * fix up *spp and scope->entryCount shortly, no matter how control + * flow returns from this function. + */ + if (scope->table) + SPROP_STORE_PRESERVING_COLLISION(spp, NULL); + scope->entryCount--; + CHECK_ANCESTOR_LINE(scope, JS_TRUE); + sprop = NULL; + } + + if (!sprop) { + /* + * If properties were deleted from the middle of the list starting at + * scope->lastProp, we may need to fork the property tree and squeeze + * all deleted properties out of scope's ancestor line. Otherwise we + * risk adding a node with the same id as a "middle" node, violating + * the rule that properties along an ancestor line have distinct ids + * (unless flagged SPROP_IS_DUPLICATE). + */ + if (SCOPE_HAD_MIDDLE_DELETE(scope)) { + JS_ASSERT(scope->table); + CHECK_ANCESTOR_LINE(scope, JS_TRUE); + + splen = scope->entryCount; + if (splen == 0) { + JS_ASSERT(scope->lastProp == NULL); + } else { + /* + * Enumerate live entries in scope->table using a temporary + * vector, by walking the (possibly sparse, due to deletions) + * ancestor line from scope->lastProp. + */ + spvec = (JSScopeProperty **) + JS_malloc(cx, SCOPE_TABLE_NBYTES(splen)); + if (!spvec) + goto fail_overwrite; + i = splen; + sprop = SCOPE_LAST_PROP(scope); + JS_ASSERT(sprop); + do { + /* + * NB: test SCOPE_GET_PROPERTY, not SCOPE_HAS_PROPERTY -- + * the latter insists that sprop->id maps to sprop, while + * the former simply tests whether sprop->id is bound in + * scope. We must allow for duplicate formal parameters + * along the ancestor line, and fork them as needed. + */ + if (!SCOPE_GET_PROPERTY(scope, sprop->id)) + continue; + + JS_ASSERT(sprop != overwriting); + if (i == 0) { + /* + * If our original splen estimate, scope->entryCount, + * is less than the ancestor line height, there must + * be duplicate formal parameters in this (function + * object) scope. Count remaining ancestors in order + * to realloc spvec. + */ + JSScopeProperty *tmp = sprop; + do { + if (SCOPE_GET_PROPERTY(scope, tmp->id)) + i++; + } while ((tmp = tmp->parent) != NULL); + spp2 = (JSScopeProperty **) + JS_realloc(cx, spvec, SCOPE_TABLE_NBYTES(splen+i)); + if (!spp2) { + JS_free(cx, spvec); + goto fail_overwrite; + } + + spvec = spp2; + memmove(spvec + i, spvec, SCOPE_TABLE_NBYTES(splen)); + splen += i; + } + + spvec[--i] = sprop; + } while ((sprop = sprop->parent) != NULL); + JS_ASSERT(i == 0); + + /* + * Now loop forward through spvec, forking the property tree + * whenever we see a "parent gap" due to deletions from scope. + * NB: sprop is null on first entry to the loop body. + */ + do { + if (spvec[i]->parent == sprop) { + sprop = spvec[i]; + } else { + sprop = GetPropertyTreeChild(cx, sprop, spvec[i]); + if (!sprop) { + JS_free(cx, spvec); + goto fail_overwrite; + } + + spp2 = js_SearchScope(scope, sprop->id, JS_FALSE); + JS_ASSERT(SPROP_FETCH(spp2) == spvec[i]); + SPROP_STORE_PRESERVING_COLLISION(spp2, sprop); + } + } while (++i < splen); + JS_free(cx, spvec); + + /* + * Now sprop points to the last property in scope, where the + * ancestor line from sprop to the root is dense w.r.t. scope: + * it contains no nodes not mapped by scope->table, apart from + * any stinking ECMA-mandated duplicate formal parameters. + */ + scope->lastProp = sprop; + CHECK_ANCESTOR_LINE(scope, JS_FALSE); + JS_RUNTIME_METER(cx->runtime, middleDeleteFixups); + } + + SCOPE_CLR_MIDDLE_DELETE(scope); + } + + /* + * Aliases share another property's slot, passed in the |slot| param. + * Shared properties have no slot. Unshared properties that do not + * alias another property's slot get one here, but may lose it due to + * a JS_ClearScope call. + */ + if (!(flags & SPROP_IS_ALIAS)) { + if (attrs & JSPROP_SHARED) { + slot = SPROP_INVALID_SLOT; + } else { + /* + * We may have set slot from a nearly-matching sprop, above. + * If so, we're overwriting that nearly-matching sprop, so we + * can reuse its slot -- we don't need to allocate a new one. + * Callers should therefore pass SPROP_INVALID_SLOT for all + * non-alias, unshared property adds. + */ + if (slot != SPROP_INVALID_SLOT) + JS_ASSERT(overwriting); + else if (!js_AllocSlot(cx, scope->object, &slot)) + goto fail_overwrite; + } + } + + /* + * Check for a watchpoint on a deleted property; if one exists, change + * setter to js_watch_set. + * XXXbe this could get expensive with lots of watchpoints... + */ + if (!JS_CLIST_IS_EMPTY(&cx->runtime->watchPointList) && + js_FindWatchPoint(cx->runtime, scope, id)) { + setter = js_WrapWatchedSetter(cx, id, attrs, setter); + if (!setter) + goto fail_overwrite; + } + + /* Find or create a property tree node labeled by our arguments. */ + child.id = id; + child.getter = getter; + child.setter = setter; + child.slot = slot; + child.attrs = attrs; + child.flags = flags; + child.shortid = shortid; + sprop = GetPropertyTreeChild(cx, scope->lastProp, &child); + if (!sprop) + goto fail_overwrite; + + /* Store the tree node pointer in the table entry for id. */ + if (scope->table) + SPROP_STORE_PRESERVING_COLLISION(spp, sprop); + scope->entryCount++; + scope->lastProp = sprop; + CHECK_ANCESTOR_LINE(scope, JS_FALSE); + if (!overwriting) { + JS_RUNTIME_METER(cx->runtime, liveScopeProps); + JS_RUNTIME_METER(cx->runtime, totalScopeProps); + } + + /* + * If we reach the hashing threshold, try to allocate scope->table. + * If we can't (a rare event, preceded by swapping to death on most + * modern OSes), stick with linear search rather than whining about + * this little set-back. Therefore we must test !scope->table and + * scope->entryCount >= SCOPE_HASH_THRESHOLD, not merely whether the + * entry count just reached the threshold. + */ + if (!scope->table && scope->entryCount >= SCOPE_HASH_THRESHOLD) + (void) CreateScopeTable(scope); + } + + METER(adds); + return sprop; + +fail_overwrite: + if (overwriting) { + /* + * We may or may not have forked overwriting out of scope's ancestor + * line, so we must check (the alternative is to set a flag above, but + * that hurts the common, non-error case). If we did fork overwriting + * out, we'll add it back at scope->lastProp. This means enumeration + * order can change due to a failure to overwrite an id. + * XXXbe very minor incompatibility + */ + for (sprop = SCOPE_LAST_PROP(scope); ; sprop = sprop->parent) { + if (!sprop) { + sprop = SCOPE_LAST_PROP(scope); + if (overwriting->parent == sprop) { + scope->lastProp = overwriting; + } else { + sprop = GetPropertyTreeChild(cx, sprop, overwriting); + if (sprop) { + JS_ASSERT(sprop != overwriting); + scope->lastProp = sprop; + } + overwriting = sprop; + } + break; + } + if (sprop == overwriting) + break; + } + if (overwriting) { + if (scope->table) + SPROP_STORE_PRESERVING_COLLISION(spp, overwriting); + scope->entryCount++; + } + CHECK_ANCESTOR_LINE(scope, JS_TRUE); + } + METER(addFailures); + return NULL; +} + +JSScopeProperty * +js_ChangeScopePropertyAttrs(JSContext *cx, JSScope *scope, + JSScopeProperty *sprop, uintN attrs, uintN mask, + JSPropertyOp getter, JSPropertyOp setter) +{ + JSScopeProperty child, *newsprop, **spp; + + CHECK_ANCESTOR_LINE(scope, JS_TRUE); + + /* Allow only shared (slot-less) => unshared (slot-full) transition. */ + attrs |= sprop->attrs & mask; + JS_ASSERT(!((attrs ^ sprop->attrs) & JSPROP_SHARED) || + !(attrs & JSPROP_SHARED)); + if (getter == JS_PropertyStub) + getter = NULL; + if (setter == JS_PropertyStub) + setter = NULL; + if (sprop->attrs == attrs && + sprop->getter == getter && + sprop->setter == setter) { + return sprop; + } + + child.id = sprop->id; + child.getter = getter; + child.setter = setter; + child.slot = sprop->slot; + child.attrs = attrs; + child.flags = sprop->flags; + child.shortid = sprop->shortid; + + if (SCOPE_LAST_PROP(scope) == sprop) { + /* + * Optimize the case where the last property added to scope is changed + * to have a different attrs, getter, or setter. In the last property + * case, we need not fork the property tree. But since we do not call + * js_AddScopeProperty, we may need to allocate a new slot directly. + */ + if ((sprop->attrs & JSPROP_SHARED) && !(attrs & JSPROP_SHARED)) { + JS_ASSERT(child.slot == SPROP_INVALID_SLOT); + if (!js_AllocSlot(cx, scope->object, &child.slot)) + return NULL; + } + + newsprop = GetPropertyTreeChild(cx, sprop->parent, &child); + if (newsprop) { + spp = js_SearchScope(scope, sprop->id, JS_FALSE); + JS_ASSERT(SPROP_FETCH(spp) == sprop); + + if (scope->table) + SPROP_STORE_PRESERVING_COLLISION(spp, newsprop); + scope->lastProp = newsprop; + CHECK_ANCESTOR_LINE(scope, JS_TRUE); + } + } else { + /* + * Let js_AddScopeProperty handle this |overwriting| case, including + * the conservation of sprop->slot (if it's valid). We must not call + * js_RemoveScopeProperty here, it will free a valid sprop->slot and + * js_AddScopeProperty won't re-allocate it. + */ + newsprop = js_AddScopeProperty(cx, scope, child.id, + child.getter, child.setter, child.slot, + child.attrs, child.flags, child.shortid); + } + +#ifdef DEBUG_brendan + if (!newsprop) + METER(changeFailures); +#endif + return newsprop; +} + +JSBool +js_RemoveScopeProperty(JSContext *cx, JSScope *scope, jsid id) +{ + JSScopeProperty **spp, *stored, *sprop; + uint32 size; + + JS_ASSERT(JS_IS_SCOPE_LOCKED(cx, scope)); + CHECK_ANCESTOR_LINE(scope, JS_TRUE); + if (SCOPE_IS_SEALED(scope)) { + ReportReadOnlyScope(cx, scope); + return JS_FALSE; + } + METER(removes); + + spp = js_SearchScope(scope, id, JS_FALSE); + stored = *spp; + sprop = SPROP_CLEAR_COLLISION(stored); + if (!sprop) { + METER(uselessRemoves); + return JS_TRUE; + } + + /* Convert from a list to a hash so we can handle "middle deletes". */ + if (!scope->table && sprop != scope->lastProp) { + if (!CreateScopeTable(scope)) { + JS_ReportOutOfMemory(cx); + return JS_FALSE; + } + spp = js_SearchScope(scope, id, JS_FALSE); + stored = *spp; + sprop = SPROP_CLEAR_COLLISION(stored); + } + + /* First, if sprop is unshared and not cleared, free its slot number. */ + if (SPROP_HAS_VALID_SLOT(sprop, scope)) + js_FreeSlot(cx, scope->object, sprop->slot); + + /* Next, remove id by setting its entry to a removed or free sentinel. */ + if (SPROP_HAD_COLLISION(stored)) { + JS_ASSERT(scope->table); + *spp = SPROP_REMOVED; + scope->removedCount++; + } else { + METER(removeFrees); + if (scope->table) + *spp = NULL; + } + scope->entryCount--; + JS_RUNTIME_UNMETER(cx->runtime, liveScopeProps); + + /* Update scope->lastProp directly, or set its deferred update flag. */ + if (sprop == SCOPE_LAST_PROP(scope)) { + do { + SCOPE_REMOVE_LAST_PROP(scope); + if (!SCOPE_HAD_MIDDLE_DELETE(scope)) + break; + sprop = SCOPE_LAST_PROP(scope); + } while (sprop && !SCOPE_HAS_PROPERTY(scope, sprop)); + } else if (!SCOPE_HAD_MIDDLE_DELETE(scope)) { + SCOPE_SET_MIDDLE_DELETE(scope); + } + CHECK_ANCESTOR_LINE(scope, JS_TRUE); + + /* Last, consider shrinking scope's table if its load factor is <= .25. */ + size = SCOPE_CAPACITY(scope); + if (size > MIN_SCOPE_SIZE && scope->entryCount <= size >> 2) { + METER(shrinks); + (void) ChangeScope(cx, scope, -1); + } + + return JS_TRUE; +} + +void +js_ClearScope(JSContext *cx, JSScope *scope) +{ + CHECK_ANCESTOR_LINE(scope, JS_TRUE); +#ifdef DEBUG + JS_LOCK_RUNTIME_VOID(cx->runtime, + cx->runtime->liveScopeProps -= scope->entryCount); +#endif + + if (scope->table) + free(scope->table); + SCOPE_CLR_MIDDLE_DELETE(scope); + InitMinimalScope(scope); +} + +#ifdef DEBUG_brendan + +#include +#include + +uint32 js_nkids_max; +uint32 js_nkids_sum; +double js_nkids_sqsum; +uint32 js_nkids_hist[11]; + +static void +MeterKidCount(uintN nkids) +{ + if (nkids) { + js_nkids_sum += nkids; + js_nkids_sqsum += (double)nkids * nkids; + if (nkids > js_nkids_max) + js_nkids_max = nkids; + } + js_nkids_hist[JS_MIN(nkids, 10)]++; +} + +static void +MeterPropertyTree(JSScopeProperty *node) +{ + uintN i, nkids; + JSScopeProperty *kids, *kid; + PropTreeKidsChunk *chunk; + + nkids = 0; + kids = node->kids; + if (kids) { + if (KIDS_IS_CHUNKY(kids)) { + for (chunk = KIDS_TO_CHUNK(kids); chunk; chunk = chunk->next) { + for (i = 0; i < MAX_KIDS_PER_CHUNK; i++) { + kid = chunk->kids[i]; + if (!kid) + break; + MeterPropertyTree(kid); + nkids++; + } + } + } else { + MeterPropertyTree(kids); + nkids = 1; + } + } + + MeterKidCount(nkids); +} + +JS_STATIC_DLL_CALLBACK(JSDHashOperator) +js_MeterPropertyTree(JSDHashTable *table, JSDHashEntryHdr *hdr, uint32 number, + void *arg) +{ + JSPropertyTreeEntry *entry = (JSPropertyTreeEntry *)hdr; + + MeterPropertyTree(entry->child); + return JS_DHASH_NEXT; +} + +#endif /* DEBUG_brendan */ + +void +js_SweepScopeProperties(JSRuntime *rt) +{ + JSArena **ap, *a; + JSScopeProperty *limit, *sprop, *parent, *kids, *kid; + uintN liveCount; + PropTreeKidsChunk *chunk, *nextChunk; + uintN i; + +#ifdef DEBUG_brendan + uint32 livePropCapacity = 0, totalLiveCount = 0; + static FILE *logfp; + if (!logfp) + logfp = fopen("/tmp/proptree.stats", "a"); + + MeterKidCount(rt->propertyTreeHash.entryCount); + JS_DHashTableEnumerate(&rt->propertyTreeHash, js_MeterPropertyTree, NULL); + + { + double mean = 0., var = 0., sigma = 0.; + double nodesum = rt->livePropTreeNodes; + double kidsum = js_nkids_sum; + if (nodesum > 0 && kidsum >= 0) { + mean = kidsum / nodesum; + var = nodesum * js_nkids_sqsum - kidsum * kidsum; + if (var < 0.0 || nodesum <= 1) + var = 0.0; + else + var /= nodesum * (nodesum - 1); + + /* Windows says sqrt(0.0) is "-1.#J" (?!) so we must test. */ + sigma = (var != 0.) ? sqrt(var) : 0.; + } + + fprintf(logfp, + "props %u nodes %g beta %g meankids %g sigma %g max %u", + rt->liveScopeProps, nodesum, nodesum / rt->liveScopeProps, + mean, sigma, js_nkids_max); + } + + fprintf(logfp, " histogram %u %u %u %u %u %u %u %u %u %u %u", + js_nkids_hist[0], js_nkids_hist[1], + js_nkids_hist[2], js_nkids_hist[3], + js_nkids_hist[4], js_nkids_hist[5], + js_nkids_hist[6], js_nkids_hist[7], + js_nkids_hist[8], js_nkids_hist[9], + js_nkids_hist[10]); + js_nkids_sum = js_nkids_max = 0; + js_nkids_sqsum = 0; + memset(js_nkids_hist, 0, sizeof js_nkids_hist); +#endif + + ap = &rt->propertyArenaPool.first.next; + while ((a = *ap) != NULL) { + limit = (JSScopeProperty *) a->avail; + liveCount = 0; + for (sprop = (JSScopeProperty *) a->base; sprop < limit; sprop++) { + /* If the id is null, sprop is already on the freelist. */ + if (sprop->id == JSVAL_NULL) + continue; + + /* If the mark bit is set, sprop is alive, so we skip it. */ + if (sprop->flags & SPROP_MARK) { + sprop->flags &= ~SPROP_MARK; + liveCount++; + continue; + } + + /* Ok, sprop is garbage to collect: unlink it from its parent. */ + RemovePropertyTreeChild(rt, sprop); + + /* Take care to reparent all sprop's kids to their grandparent. */ + kids = sprop->kids; + if (kids) { + sprop->kids = NULL; + parent = sprop->parent; + if (KIDS_IS_CHUNKY(kids)) { + chunk = KIDS_TO_CHUNK(kids); + do { + for (i = 0; i < MAX_KIDS_PER_CHUNK; i++) { + kid = chunk->kids[i]; + if (!kid) + break; + JS_ASSERT(kid->parent == sprop); + InsertPropertyTreeChild(rt, parent, kid); + } + nextChunk = chunk->next; + DestroyPropTreeKidsChunk(rt, chunk); + } while ((chunk = nextChunk) != NULL); + } else { + kid = kids; + InsertPropertyTreeChild(rt, parent, kid); + } + } + + /* Clear id so we know (above) that sprop is on the freelist. */ + sprop->id = JSVAL_NULL; + FREENODE_INSERT(rt->propertyFreeList, sprop); + JS_RUNTIME_UNMETER(rt, livePropTreeNodes); + } + + /* If a contains no live properties, return it to the malloc heap. */ + if (liveCount == 0) { + for (sprop = (JSScopeProperty *) a->base; sprop < limit; sprop++) + FREENODE_REMOVE(sprop); + JS_ARENA_DESTROY(&rt->propertyArenaPool, a, ap); + } else { +#ifdef DEBUG_brendan + livePropCapacity += limit - (JSScopeProperty *) a->base; + totalLiveCount += liveCount; +#endif + ap = &a->next; + } + } + +#ifdef DEBUG_brendan + fprintf(logfp, " arenautil %g%%\n", + (totalLiveCount * 100.) / livePropCapacity); + fflush(logfp); +#endif +} + +JSBool +js_InitPropertyTree(JSRuntime *rt) +{ + if (!JS_DHashTableInit(&rt->propertyTreeHash, &PropertyTreeHashOps, NULL, + sizeof(JSPropertyTreeEntry), JS_DHASH_MIN_SIZE)) { + rt->propertyTreeHash.ops = NULL; + return JS_FALSE; + } + JS_InitArenaPool(&rt->propertyArenaPool, "properties", + 256 * sizeof(JSScopeProperty), sizeof(void *)); + return JS_TRUE; +} + +void +js_FinishPropertyTree(JSRuntime *rt) +{ + if (rt->propertyTreeHash.ops) { + JS_DHashTableFinish(&rt->propertyTreeHash); + rt->propertyTreeHash.ops = NULL; + } + JS_FinishArenaPool(&rt->propertyArenaPool); +} diff --git a/src/extension/script/js/jsscope.h b/src/extension/script/js/jsscope.h new file mode 100644 index 000000000..4f66441b4 --- /dev/null +++ b/src/extension/script/js/jsscope.h @@ -0,0 +1,386 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef jsscope_h___ +#define jsscope_h___ +/* + * JS symbol tables. + */ +#include "jstypes.h" +#include "jsobj.h" +#include "jsprvtd.h" +#include "jspubtd.h" + +#ifdef JS_THREADSAFE +# include "jslock.h" +#endif + +/* + * Given P independent, non-unique properties each of size S words mapped by + * all scopes in a runtime, construct a property tree of N nodes each of size + * S+L words (L for tree linkage). A nominal L value is 2 for leftmost-child + * and right-sibling links. We hope that the N < P by enough that the space + * overhead of L, and the overhead of scope entries pointing at property tree + * nodes, is worth it. + * + * The tree construction goes as follows. If any empty scope in the runtime + * has a property X added to it, find or create a node under the tree root + * labeled X, and set scope->lastProp to point at that node. If any non-empty + * scope whose most recently added property is labeled Y has another property + * labeled Z added, find or create a node for Z under the node that was added + * for Y, and set scope->lastProp to point at that node. + * + * A property is labeled by its members' values: id, getter, setter, slot, + * attributes, tiny or short id, and a field telling for..in order. Note that + * labels are not unique in the tree, but they are unique among a node's kids + * (barring rare and benign multi-threaded race condition outcomes, see below) + * and along any ancestor line from the tree root to a given leaf node (except + * for the hard case of duplicate formal parameters to a function). + * + * Thus the root of the tree represents all empty scopes, and the first ply + * of the tree represents all scopes containing one property, etc. Each node + * in the tree can stand for any number of scopes having the same ordered set + * of properties, where that node was the last added to the scope. (We need + * not store the root of the tree as a node, and do not -- all we need are + * links to its kids.) + * + * Sidebar on for..in loop order: ECMA requires no particular order, but this + * implementation has promised and delivered property definition order, and + * compatibility is king. We could use an order number per property, which + * would require a sort in js_Enumerate, and an entry order generation number + * per scope. An order number beats a list, which should be doubly-linked for + * O(1) delete. An even better scheme is to use a parent link in the property + * tree, so that the ancestor line can be iterated from scope->lastProp when + * filling in a JSIdArray from back to front. This parent link also helps the + * GC to sweep properties iteratively. + * + * What if a property Y is deleted from a scope? If Y is the last property in + * the scope, we simply adjust the scope's lastProp member after we remove the + * scope's hash-table entry pointing at that property node. The parent link + * mentioned in the for..in sidebar above makes this adjustment O(1). But if + * Y comes between X and Z in the scope, then we might have to "fork" the tree + * at X, leaving X->Y->Z in case other scopes have those properties added in + * that order; and to finish the fork, we'd add a node labeled Z with the path + * X->Z, if it doesn't exist. This could lead to lots of extra nodes, and to + * O(n^2) growth when deleting lots of properties. + * + * Rather, for O(1) growth all around, we should share the path X->Y->Z among + * scopes having those three properties added in that order, and among scopes + * having only X->Z where Y was deleted. All such scopes have a lastProp that + * points to the Z child of Y. But a scope in which Y was deleted does not + * have a table entry for Y, and when iterating that scope by traversing the + * ancestor line from Z, we will have to test for a table entry for each node, + * skipping nodes that lack entries. + * + * What if we add Y again? X->Y->Z->Y is wrong and we'll enumerate Y twice. + * Therefore we must fork in such a case, if not earlier. Because delete is + * "bursty", we should not fork eagerly. Delaying a fork till we are at risk + * of adding Y after it was deleted already requires a flag in the JSScope, to + * wit, SCOPE_MIDDLE_DELETE. + * + * What about thread safety? If the property tree operations done by requests + * are find-node and insert-node, then the only hazard is duplicate insertion. + * This is harmless except for minor bloat. When all requests have ended or + * been suspended, the GC is free to sweep the tree after marking all nodes + * reachable from scopes, performing remove-node operations as needed. Note + * also that the stable storage of the property nodes during active requests + * permits the property cache (see jsinterp.h) to dereference JSScopeProperty + * weak references safely. + * + * Is the property tree worth it compared to property storage in each table's + * entries? To decide, we must find the relation <> between the words used + * with a property tree and the words required without a tree. + * + * Model all scopes as one super-scope of capacity T entries (T a power of 2). + * Let alpha be the load factor of this double hash-table. With the property + * tree, each entry in the table is a word-sized pointer to a node that can be + * shared by many scopes. But all such pointers are overhead compared to the + * situation without the property tree, where the table stores property nodes + * directly, as entries each of size S words. With the property tree, we need + * L=2 extra words per node for siblings and kids pointers. Without the tree, + * (1-alpha)*S*T words are wasted on free or removed sentinel-entries required + * by double hashing. + * + * Therefore, + * + * (property tree) <> (no property tree) + * N*(S+L) + T <> S*T + * N*(S+L) + T <> P*S + (1-alpha)*S*T + * N*(S+L) + alpha*T + (1-alpha)*T <> P*S + (1-alpha)*S*T + * + * Note that P is alpha*T by definition, so + * + * N*(S+L) + P + (1-alpha)*T <> P*S + (1-alpha)*S*T + * N*(S+L) <> P*S - P + (1-alpha)*S*T - (1-alpha)*T + * N*(S+L) <> (P + (1-alpha)*T) * (S-1) + * N*(S+L) <> (P + (1-alpha)*P/alpha) * (S-1) + * N*(S+L) <> P * (1/alpha) * (S-1) + * + * Let N = P*beta for a compression ratio beta, beta <= 1: + * + * P*beta*(S+L) <> P * (1/alpha) * (S-1) + * beta*(S+L) <> (S-1)/alpha + * beta <> (S-1)/((S+L)*alpha) + * + * For S = 6 (32-bit architectures) and L = 2, the property tree wins iff + * + * beta < 5/(8*alpha) + * + * We ensure that alpha <= .75, so the property tree wins if beta < .83_. An + * average beta from recent Mozilla browser startups was around .6. + * + * Can we reduce L? Observe that the property tree degenerates into a list of + * lists if at most one property Y follows X in all scopes. In or near such a + * case, we waste a word on the right-sibling link outside of the root ply of + * the tree. Note also that the root ply tends to be large, so O(n^2) growth + * searching it is likely, indicating the need for hashing (but with increased + * thread safety costs). + * + * If only K out of N nodes in the property tree have more than one child, we + * could eliminate the sibling link and overlay a children list or hash-table + * pointer on the leftmost-child link (which would then be either null or an + * only-child link; the overlay could be tagged in the low bit of the pointer, + * or flagged elsewhere in the property tree node, although such a flag must + * not be considered when comparing node labels during tree search). + * + * For such a system, L = 1 + (K * averageChildrenTableSize) / N instead of 2. + * If K << N, L approaches 1 and the property tree wins if beta < .95. + * + * We observe that fan-out below the root ply of the property tree appears to + * have extremely low degree (see the MeterPropertyTree code that histograms + * child-counts in jsscope.c), so instead of a hash-table we use a linked list + * of child node pointer arrays ("kid chunks"). The details are isolated in + * jsscope.c; others must treat JSScopeProperty.kids as opaque. We leave it + * strongly typed for debug-ability of the common (null or one-kid) cases. + * + * One final twist (can you stand it?): the mean number of entries per scope + * in Mozilla is < 5, with a large standard deviation (~8). Instead of always + * allocating scope->table, we leave it null while initializing all the other + * scope members as if it were non-null and minimal-length. Until a property + * is added that crosses the threshold of 6 or more entries for hashing, or + * until a "middle delete" occurs, we use linear search from scope->lastProp + * to find a given id, and save on the space overhead of a hash table. + */ + +struct JSScope { + JSObjectMap map; /* base class state */ + JSObject *object; /* object that owns this scope */ + uint16 flags; /* flags, see below */ + int16 hashShift; /* multiplicative hash shift */ + uint32 entryCount; /* number of entries in table */ + uint32 removedCount; /* removed entry sentinels in table */ + JSScopeProperty **table; /* table of ptrs to shared tree nodes */ + JSScopeProperty *lastProp; /* pointer to last property added */ +#ifdef JS_THREADSAFE + JSContext *ownercx; /* creating context, NULL if shared */ + JSThinLock lock; /* binary semaphore protecting scope */ + union { /* union lockful and lock-free state: */ + jsrefcount count; /* lock entry count for reentrancy */ + JSScope *link; /* next link in rt->scopeSharingTodo */ + } u; +#ifdef DEBUG + const char *file[4]; /* file where lock was (re-)taken */ + unsigned int line[4]; /* line where lock was (re-)taken */ +#endif +#endif +}; + +#define OBJ_SCOPE(obj) ((JSScope *)(obj)->map) + +/* By definition, hashShift = JS_DHASH_BITS - log2(capacity). */ +#define SCOPE_CAPACITY(scope) JS_BIT(JS_DHASH_BITS-(scope)->hashShift) + +/* Scope flags and some macros to hide them from other files than jsscope.c. */ +#define SCOPE_MIDDLE_DELETE 0x0001 +#define SCOPE_SEALED 0x0002 + +#define SCOPE_HAD_MIDDLE_DELETE(scope) ((scope)->flags & SCOPE_MIDDLE_DELETE) +#define SCOPE_SET_MIDDLE_DELETE(scope) ((scope)->flags |= SCOPE_MIDDLE_DELETE) +#define SCOPE_CLR_MIDDLE_DELETE(scope) ((scope)->flags &= ~SCOPE_MIDDLE_DELETE) + +#define SCOPE_IS_SEALED(scope) ((scope)->flags & SCOPE_SEALED) +#define SCOPE_SET_SEALED(scope) ((scope)->flags |= SCOPE_SEALED) +#if 0 +/* + * Don't define this, it can't be done safely because JS_LOCK_OBJ will avoid + * taking the lock if the object owns its scope and the scope is sealed. + */ +#define SCOPE_CLR_SEALED(scope) ((scope)->flags &= ~SCOPE_SEALED) +#endif + +/* + * A little information hiding for scope->lastProp, in case it ever becomes + * a tagged pointer again. + */ +#define SCOPE_LAST_PROP(scope) ((scope)->lastProp) +#define SCOPE_REMOVE_LAST_PROP(scope) ((scope)->lastProp = \ + (scope)->lastProp->parent) + +struct JSScopeProperty { + jsid id; /* int-tagged jsval/untagged JSAtom* */ + JSPropertyOp getter; /* getter and setter hooks or objects */ + JSPropertyOp setter; + uint32 slot; /* index in obj->slots vector */ + uint8 attrs; /* attributes, see jsapi.h JSPROP_* */ + uint8 flags; /* flags, see below for defines */ + int16 shortid; /* tinyid, or local arg/var index */ + JSScopeProperty *parent; /* parent node, reverse for..in order */ + JSScopeProperty *kids; /* null, single child, or a tagged ptr + to many-kids data structure */ +}; + +/* JSScopeProperty pointer tag bit indicating a collision. */ +#define SPROP_COLLISION ((jsuword)1) +#define SPROP_REMOVED ((JSScopeProperty *) SPROP_COLLISION) + +/* Macros to get and set sprop pointer values and collision flags. */ +#define SPROP_IS_FREE(sprop) ((sprop) == NULL) +#define SPROP_IS_REMOVED(sprop) ((sprop) == SPROP_REMOVED) +#define SPROP_IS_LIVE(sprop) ((sprop) > SPROP_REMOVED) +#define SPROP_FLAG_COLLISION(spp,sprop) (*(spp) = (JSScopeProperty *) \ + ((jsuword)(sprop) | SPROP_COLLISION)) +#define SPROP_HAD_COLLISION(sprop) ((jsuword)(sprop) & SPROP_COLLISION) +#define SPROP_FETCH(spp) SPROP_CLEAR_COLLISION(*(spp)) + +#define SPROP_CLEAR_COLLISION(sprop) \ + ((JSScopeProperty *) ((jsuword)(sprop) & ~SPROP_COLLISION)) + +#define SPROP_STORE_PRESERVING_COLLISION(spp, sprop) \ + (*(spp) = (JSScopeProperty *) ((jsuword)(sprop) \ + | SPROP_HAD_COLLISION(*(spp)))) + +/* Bits stored in sprop->flags. */ +#define SPROP_MARK 0x01 +#define SPROP_IS_DUPLICATE 0x02 +#define SPROP_IS_ALIAS 0x04 +#define SPROP_HAS_SHORTID 0x08 + +/* + * If SPROP_HAS_SHORTID is set in sprop->flags, we use sprop->shortid rather + * than id when calling sprop's getter or setter. + */ +#define SPROP_USERID(sprop) \ + (((sprop)->flags & SPROP_HAS_SHORTID) ? INT_TO_JSVAL((sprop)->shortid) \ + : ID_TO_VALUE((sprop)->id)) + +#define SPROP_INVALID_SLOT 0xffffffff + +#define SPROP_HAS_VALID_SLOT(sprop, scope) \ + ((sprop)->slot < (scope)->map.freeslot) + +#define SPROP_CALL_GETTER(cx,sprop,getter,obj,obj2,vp) \ + (!(getter) || \ + (getter)(cx, OBJ_THIS_OBJECT(cx,obj), SPROP_USERID(sprop), vp)) +#define SPROP_CALL_SETTER(cx,sprop,setter,obj,obj2,vp) \ + (!(setter) || \ + (setter)(cx, OBJ_THIS_OBJECT(cx,obj), SPROP_USERID(sprop), vp)) + +#define SPROP_GET(cx,sprop,obj,obj2,vp) \ + (((sprop)->attrs & JSPROP_GETTER) \ + ? js_InternalGetOrSet(cx, obj, (sprop)->id, \ + OBJECT_TO_JSVAL((sprop)->getter), JSACC_READ, \ + 0, 0, vp) \ + : SPROP_CALL_GETTER(cx, sprop, (sprop)->getter, obj, obj2, vp)) + +#define SPROP_SET(cx,sprop,obj,obj2,vp) \ + (((sprop)->attrs & JSPROP_SETTER) \ + ? js_InternalGetOrSet(cx, obj, (sprop)->id, \ + OBJECT_TO_JSVAL((sprop)->setter), JSACC_WRITE, \ + 1, vp, vp) \ + : ((sprop)->attrs & JSPROP_GETTER) \ + ? (JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, \ + JSMSG_GETTER_ONLY, NULL), JS_FALSE) \ + : SPROP_CALL_SETTER(cx, sprop, (sprop)->setter, obj, obj2, vp)) + +/* Macro for common expression to test for shared permanent attributes. */ +#define SPROP_IS_SHARED_PERMANENT(sprop) \ + ((~(sprop)->attrs & (JSPROP_SHARED | JSPROP_PERMANENT)) == 0) + +extern JSScope * +js_GetMutableScope(JSContext *cx, JSObject *obj); + +extern JSScope * +js_NewScope(JSContext *cx, jsrefcount nrefs, JSObjectOps *ops, JSClass *clasp, + JSObject *obj); + +extern void +js_DestroyScope(JSContext *cx, JSScope *scope); + +#define ID_TO_VALUE(id) (((id) & JSVAL_INT) ? id : ATOM_KEY((JSAtom *)(id))) +#define HASH_ID(id) (((id) & JSVAL_INT) \ + ? (jsatomid) JSVAL_TO_INT(id) \ + : ((JSAtom *)id)->number) + +extern JS_FRIEND_API(JSScopeProperty **) +js_SearchScope(JSScope *scope, jsid id, JSBool adding); + +#define SCOPE_GET_PROPERTY(scope, id) \ + SPROP_FETCH(js_SearchScope(scope, id, JS_FALSE)) + +#define SCOPE_HAS_PROPERTY(scope, sprop) \ + (SCOPE_GET_PROPERTY(scope, (sprop)->id) == (sprop)) + +extern JSScopeProperty * +js_AddScopeProperty(JSContext *cx, JSScope *scope, jsid id, + JSPropertyOp getter, JSPropertyOp setter, uint32 slot, + uintN attrs, uintN flags, intN shortid); + +extern JSScopeProperty * +js_ChangeScopePropertyAttrs(JSContext *cx, JSScope *scope, + JSScopeProperty *sprop, uintN attrs, uintN mask, + JSPropertyOp getter, JSPropertyOp setter); + +extern JSBool +js_RemoveScopeProperty(JSContext *cx, JSScope *scope, jsid id); + +extern void +js_ClearScope(JSContext *cx, JSScope *scope); + +#define MARK_SCOPE_PROPERTY(sprop) ((sprop)->flags |= SPROP_MARK) + +extern void +js_SweepScopeProperties(JSRuntime *rt); + +extern JSBool +js_InitPropertyTree(JSRuntime *rt); + +extern void +js_FinishPropertyTree(JSRuntime *rt); + +#endif /* jsscope_h___ */ diff --git a/src/extension/script/js/jsscript.c b/src/extension/script/js/jsscript.c new file mode 100644 index 000000000..504cbbd6d --- /dev/null +++ b/src/extension/script/js/jsscript.c @@ -0,0 +1,1287 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* + * JS script operations. + */ +#include "jsstddef.h" +#include +#include "jstypes.h" +#include "jsutil.h" /* Added by JSIFY */ +#include "jsprf.h" +#include "jsapi.h" +#include "jsatom.h" +#include "jscntxt.h" +#include "jsconfig.h" +#include "jsdbgapi.h" +#include "jsemit.h" +#include "jsfun.h" +#include "jsinterp.h" +#include "jslock.h" +#include "jsnum.h" +#include "jsopcode.h" +#include "jsscript.h" +#if JS_HAS_XDR +#include "jsxdrapi.h" +#endif + +#if JS_HAS_SCRIPT_OBJECT + +#if JS_HAS_TOSOURCE +static JSBool +script_toSource(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval) +{ + JSScript *script; + size_t i, j, k, n; + char buf[16]; + jschar *s, *t; + uint32 indent; + JSString *str; + + if (!JS_InstanceOf(cx, obj, &js_ScriptClass, argv)) + return JS_FALSE; + script = (JSScript *) JS_GetPrivate(cx, obj); + + /* Let n count the source string length, j the "front porch" length. */ + j = JS_snprintf(buf, sizeof buf, "(new %s(", js_ScriptClass.name); + n = j + 2; + if (!script) { + /* Let k count the constructor argument string length. */ + k = 0; + s = NULL; /* quell GCC overwarning */ + } else { + indent = 0; + if (argc && !js_ValueToECMAUint32(cx, argv[0], &indent)) + return JS_FALSE; + str = JS_DecompileScript(cx, script, "Script.prototype.toSource", + (uintN)indent); + if (!str) + return JS_FALSE; + str = js_QuoteString(cx, str, '\''); + if (!str) + return JS_FALSE; + s = JSSTRING_CHARS(str); + k = JSSTRING_LENGTH(str); + n += k; + } + + /* Allocate the source string and copy into it. */ + t = (jschar *) JS_malloc(cx, (n + 1) * sizeof(jschar)); + if (!t) + return JS_FALSE; + for (i = 0; i < j; i++) + t[i] = buf[i]; + for (j = 0; j < k; i++, j++) + t[i] = s[j]; + t[i++] = ')'; + t[i++] = ')'; + t[i] = 0; + + /* Create and return a JS string for t. */ + str = JS_NewUCString(cx, t, n); + if (!str) { + JS_free(cx, t); + return JS_FALSE; + } + *rval = STRING_TO_JSVAL(str); + return JS_TRUE; +} +#endif /* JS_HAS_TOSOURCE */ + +static JSBool +script_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval) +{ + JSScript *script; + uint32 indent; + JSString *str; + + if (!JS_InstanceOf(cx, obj, &js_ScriptClass, argv)) + return JS_FALSE; + script = (JSScript *) JS_GetPrivate(cx, obj); + if (!script) { + *rval = STRING_TO_JSVAL(cx->runtime->emptyString); + return JS_TRUE; + } + + indent = 0; + if (argc && !js_ValueToECMAUint32(cx, argv[0], &indent)) + return JS_FALSE; + str = JS_DecompileScript(cx, script, "Script.prototype.toString", + (uintN)indent); + if (!str) + return JS_FALSE; + *rval = STRING_TO_JSVAL(str); + return JS_TRUE; +} + +static JSBool +script_compile(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval) +{ + JSScript *oldscript, *script; + JSString *str; + JSStackFrame *fp, *caller; + JSObject *scopeobj; + const char *file; + uintN line; + JSPrincipals *principals; + + /* Make sure obj is a Script object. */ + if (!JS_InstanceOf(cx, obj, &js_ScriptClass, argv)) + return JS_FALSE; + + /* If no args, leave private undefined and return early. */ + if (argc == 0) + goto out; + + /* Otherwise, the first arg is the script source to compile. */ + str = js_ValueToString(cx, argv[0]); + if (!str) + return JS_FALSE; + + /* Compile using the caller's scope chain, which js_Invoke passes to fp. */ + fp = cx->fp; + caller = JS_GetScriptedCaller(cx, fp); + JS_ASSERT(!caller || fp->scopeChain == caller->scopeChain); + + scopeobj = NULL; + if (argc >= 2) { + if (!js_ValueToObject(cx, argv[1], &scopeobj)) + return JS_FALSE; + argv[1] = OBJECT_TO_JSVAL(scopeobj); + } + if (caller) { + if (!scopeobj) + scopeobj = caller->scopeChain; + + file = caller->script->filename; + line = js_PCToLineNumber(cx, caller->script, caller->pc); + principals = JS_EvalFramePrincipals(cx, fp, caller); + } else { + file = NULL; + line = 0; + principals = NULL; + } + + /* XXXbe set only for the compiler, which does not currently test it */ + fp->flags |= JSFRAME_EVAL; + + /* Compile the new script using the caller's scope chain, a la eval(). */ + script = JS_CompileUCScriptForPrincipals(cx, scopeobj, principals, + JSSTRING_CHARS(str), + JSSTRING_LENGTH(str), + file, line); + if (!script) + return JS_FALSE; + + /* Swap script for obj's old script, if any. */ + oldscript = (JSScript *) JS_GetPrivate(cx, obj); + if (!JS_SetPrivate(cx, obj, script)) { + js_DestroyScript(cx, script); + return JS_FALSE; + } + if (oldscript) + js_DestroyScript(cx, oldscript); + + script->object = obj; +out: + /* Return the object. */ + *rval = OBJECT_TO_JSVAL(obj); + return JS_TRUE; +} + +static JSBool +script_exec(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + JSScript *script; + JSObject *scopeobj, *parent; + JSStackFrame *fp, *caller; + + if (!JS_InstanceOf(cx, obj, &js_ScriptClass, argv)) + return JS_FALSE; + script = (JSScript *) JS_GetPrivate(cx, obj); + if (!script) + return JS_TRUE; + + scopeobj = NULL; + if (argc) { + if (!js_ValueToObject(cx, argv[0], &scopeobj)) + return JS_FALSE; + argv[0] = OBJECT_TO_JSVAL(scopeobj); + } + + /* + * Emulate eval() by using caller's this, var object, sharp array, etc., + * all propagated by js_Execute via a non-null fourth (down) argument to + * js_Execute. If there is no scripted caller, js_Execute uses its second + * (chain) argument to set the exec frame's varobj, thisp, and scopeChain. + * + * Unlike eval, which the compiler detects, Script.prototype.exec may be + * called from a lightweight function, or even from native code (in which + * case fp->varobj and fp->scopeChain are null). If exec is called from + * a lightweight function, we will need to get a Call object representing + * its frame, to act as the var object and scope chain head. + */ + fp = cx->fp; + caller = JS_GetScriptedCaller(cx, fp); + if (caller && !caller->varobj) { + /* Called from a lightweight function. */ + JS_ASSERT(caller->fun && !(caller->fun->flags & JSFUN_HEAVYWEIGHT)); + + /* Scope chain links from Call object to callee's parent. */ + parent = OBJ_GET_PARENT(cx, JSVAL_TO_OBJECT(caller->argv[-2])); + if (!js_GetCallObject(cx, caller, parent)) + return JS_FALSE; + } + + if (!scopeobj) { + /* No scope object passed in: try to use the caller's scope chain. */ + if (caller) { + /* + * Load caller->scopeChain after the conditional js_GetCallObject + * call above, which resets scopeChain as well as varobj. + */ + scopeobj = caller->scopeChain; + } else { + /* + * Called from native code, so we don't know what scope object to + * use. We could use parent (see above), but Script.prototype.exec + * might be a shared/sealed "superglobal" method. A more general + * approach would use cx->globalObject, which will be the same as + * exec.__parent__ in the non-superglobal case. In the superglobal + * case it's the right object: the global, not the superglobal. + */ + scopeobj = cx->globalObject; + } + } + + return js_Execute(cx, scopeobj, script, caller, JSFRAME_EVAL, rval); +} + +#if JS_HAS_XDR + +static JSBool +XDRAtomListElement(JSXDRState *xdr, JSAtomListElement *ale) +{ + jsval value; + jsatomid index; + + if (xdr->mode == JSXDR_ENCODE) + value = ATOM_KEY(ALE_ATOM(ale)); + + index = ALE_INDEX(ale); + if (!JS_XDRUint32(xdr, &index)) + return JS_FALSE; + ALE_SET_INDEX(ale, index); + + if (!JS_XDRValue(xdr, &value)) + return JS_FALSE; + + if (xdr->mode == JSXDR_DECODE) { + if (!ALE_SET_ATOM(ale, js_AtomizeValue(xdr->cx, value, 0))) + return JS_FALSE; + } + return JS_TRUE; +} + +static JSBool +XDRAtomMap(JSXDRState *xdr, JSAtomMap *map) +{ + uint32 length; + uintN i; + JSBool ok; + + if (xdr->mode == JSXDR_ENCODE) + length = map->length; + + if (!JS_XDRUint32(xdr, &length)) + return JS_FALSE; + + if (xdr->mode == JSXDR_DECODE) { + JSContext *cx; + void *mark; + JSAtomList al; + JSAtomListElement *ale; + + cx = xdr->cx; + mark = JS_ARENA_MARK(&cx->tempPool); + ATOM_LIST_INIT(&al); + for (i = 0; i < length; i++) { + JS_ARENA_ALLOCATE_TYPE(ale, JSAtomListElement, &cx->tempPool); + if (!ale || + !XDRAtomListElement(xdr, ale)) { + if (!ale) + JS_ReportOutOfMemory(cx); + JS_ARENA_RELEASE(&cx->tempPool, mark); + return JS_FALSE; + } + ALE_SET_NEXT(ale, al.list); + al.count++; + al.list = ale; + } + ok = js_InitAtomMap(cx, map, &al); + JS_ARENA_RELEASE(&cx->tempPool, mark); + return ok; + } + + if (xdr->mode == JSXDR_ENCODE) { + JSAtomListElement ale; + + for (i = 0; i < map->length; i++) { + ALE_SET_ATOM(&ale, map->vector[i]); + ALE_SET_INDEX(&ale, i); + if (!XDRAtomListElement(xdr, &ale)) + return JS_FALSE; + } + } + return JS_TRUE; +} + +JSBool +js_XDRScript(JSXDRState *xdr, JSScript **scriptp, JSBool *hasMagic) +{ + JSContext *cx; + JSScript *script, *newscript; + uint32 length, lineno, depth, magic, nsrcnotes, ntrynotes; + uint32 prologLength, version; + JSBool filenameWasSaved; + jssrcnote *notes, *sn; + + cx = xdr->cx; + script = *scriptp; + nsrcnotes = ntrynotes = 0; + filenameWasSaved = JS_FALSE; + notes = NULL; + + /* + * Encode prologLength and version after script->length (_2 or greater), + * but decode both new (>= _2) and old, prolog&version-free (_1) scripts. + * Version _3 supports principals serialization. Version _4 reorders the + * nsrcnotes and ntrynotes fields to come before everything except magic, + * length, prologLength, and version, so that srcnote and trynote storage + * can be allocated as part of the JSScript (along with bytecode storage). + */ + if (xdr->mode == JSXDR_ENCODE) + magic = JSXDR_MAGIC_SCRIPT_CURRENT; + if (!JS_XDRUint32(xdr, &magic)) + return JS_FALSE; + if (magic != JSXDR_MAGIC_SCRIPT_4 && + magic != JSXDR_MAGIC_SCRIPT_3 && + magic != JSXDR_MAGIC_SCRIPT_2 && + magic != JSXDR_MAGIC_SCRIPT_1) { + if (!hasMagic) { + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, + JSMSG_BAD_SCRIPT_MAGIC); + return JS_FALSE; + } + *hasMagic = JS_FALSE; + return JS_TRUE; + } + if (hasMagic) + *hasMagic = JS_TRUE; + + if (xdr->mode == JSXDR_ENCODE) { + length = script->length; + prologLength = PTRDIFF(script->main, script->code, jsbytecode); + version = (int32)script->version; + lineno = (uint32)script->lineno; + depth = (uint32)script->depth; + + /* Count the srcnotes, keeping notes pointing at the first one. */ + notes = SCRIPT_NOTES(script); + for (sn = notes; !SN_IS_TERMINATOR(sn); sn = SN_NEXT(sn)) + continue; + nsrcnotes = PTRDIFF(sn, notes, jssrcnote); + nsrcnotes++; /* room for the terminator */ + + /* Count the trynotes. */ + if (script->trynotes) { + while (script->trynotes[ntrynotes].catchStart) + ntrynotes++; + ntrynotes++; /* room for the end marker */ + } + } + + if (!JS_XDRUint32(xdr, &length)) + return JS_FALSE; + if (magic >= JSXDR_MAGIC_SCRIPT_2) { + if (!JS_XDRUint32(xdr, &prologLength)) + return JS_FALSE; + if (!JS_XDRUint32(xdr, &version)) + return JS_FALSE; + + /* To fuse allocations, we need srcnote and trynote counts early. */ + if (magic >= JSXDR_MAGIC_SCRIPT_4) { + if (!JS_XDRUint32(xdr, &nsrcnotes)) + return JS_FALSE; + if (!JS_XDRUint32(xdr, &ntrynotes)) + return JS_FALSE; + } + } + + if (xdr->mode == JSXDR_DECODE) { + script = js_NewScript(cx, length, nsrcnotes, ntrynotes); + if (!script) + return JS_FALSE; + if (magic >= JSXDR_MAGIC_SCRIPT_2) { + script->main += prologLength; + script->version = (JSVersion) version; + + /* If we know nsrcnotes, we allocated space for notes in script. */ + if (magic >= JSXDR_MAGIC_SCRIPT_4) + notes = SCRIPT_NOTES(script); + } + *scriptp = script; + } + + /* + * Control hereafter must goto error on failure, in order for the DECODE + * case to destroy script and conditionally free notes, which if non-null + * in the (DECODE and version < _4) case must point at a temporary vector + * allocated just below. + */ + if (!JS_XDRBytes(xdr, (char *)script->code, length * sizeof(jsbytecode)) || + !XDRAtomMap(xdr, &script->atomMap)) { + goto error; + } + + if (magic < JSXDR_MAGIC_SCRIPT_4) { + if (!JS_XDRUint32(xdr, &nsrcnotes)) + goto error; + if (xdr->mode == JSXDR_DECODE) { + notes = (jssrcnote *) JS_malloc(cx, nsrcnotes * sizeof(jssrcnote)); + if (!notes) + goto error; + } + } + + if (!JS_XDRBytes(xdr, (char *)notes, nsrcnotes * sizeof(jssrcnote)) || + !JS_XDRCStringOrNull(xdr, (char **)&script->filename) || + !JS_XDRUint32(xdr, &lineno) || + !JS_XDRUint32(xdr, &depth) || + (magic < JSXDR_MAGIC_SCRIPT_4 && !JS_XDRUint32(xdr, &ntrynotes))) { + goto error; + } + + /* Script principals transcoding support comes with versions >= _3. */ + if (magic >= JSXDR_MAGIC_SCRIPT_3) { + JSPrincipals *principals; + uint32 encodeable; + + if (xdr->mode == JSXDR_ENCODE) { + principals = script->principals; + encodeable = (cx->runtime->principalsTranscoder != NULL); + if (!JS_XDRUint32(xdr, &encodeable)) + goto error; + if (encodeable && + !cx->runtime->principalsTranscoder(xdr, &principals)) { + goto error; + } + } else { + if (!JS_XDRUint32(xdr, &encodeable)) + goto error; + if (encodeable) { + if (!cx->runtime->principalsTranscoder) { + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, + JSMSG_CANT_DECODE_PRINCIPALS); + goto error; + } + if (!cx->runtime->principalsTranscoder(xdr, &principals)) + goto error; + script->principals = principals; + } + } + } + + if (xdr->mode == JSXDR_DECODE) { + const char *filename = script->filename; + if (filename) { + filename = js_SaveScriptFilename(cx, filename); + if (!filename) + goto error; + JS_free(cx, (void *) script->filename); + script->filename = filename; + filenameWasSaved = JS_TRUE; + } + script->lineno = (uintN)lineno; + script->depth = (uintN)depth; + + if (magic < JSXDR_MAGIC_SCRIPT_4) { + /* + * Argh, we have to reallocate script, copy notes into the extra + * space after the bytecodes, and free the temporary notes vector. + * First, add enough slop to nsrcnotes so we can align the address + * after the srcnotes of the first trynote. + */ + uint32 osrcnotes = nsrcnotes; + + if (ntrynotes) + nsrcnotes += JSTRYNOTE_ALIGNMASK; + newscript = (JSScript *) JS_realloc(cx, script, + sizeof(JSScript) + + length * sizeof(jsbytecode) + + nsrcnotes * sizeof(jssrcnote) + + ntrynotes * sizeof(JSTryNote)); + if (!newscript) + goto error; + + *scriptp = script = newscript; + script->code = (jsbytecode *)(script + 1); + script->main = script->code + prologLength; + memcpy(script->code + length, notes, osrcnotes * sizeof(jssrcnote)); + JS_free(cx, (void *) notes); + notes = NULL; + if (ntrynotes) { + script->trynotes = (JSTryNote *) + ((jsword)(SCRIPT_NOTES(script) + nsrcnotes) & + ~(jsword)JSTRYNOTE_ALIGNMASK); + } + } + } + + while (ntrynotes) { + JSTryNote *tn = &script->trynotes[--ntrynotes]; + uint32 start = (uint32) tn->start, + catchLength = (uint32) tn->length, + catchStart = (uint32) tn->catchStart; + + if (!JS_XDRUint32(xdr, &start) || + !JS_XDRUint32(xdr, &catchLength) || + !JS_XDRUint32(xdr, &catchStart)) { + goto error; + } + tn->start = (ptrdiff_t) start; + tn->length = (ptrdiff_t) catchLength; + tn->catchStart = (ptrdiff_t) catchStart; + } + return JS_TRUE; + + error: + if (xdr->mode == JSXDR_DECODE) { + if (script->filename && !filenameWasSaved) { + JS_free(cx, (void *) script->filename); + script->filename = NULL; + } + if (notes && magic < JSXDR_MAGIC_SCRIPT_4) + JS_free(cx, (void *) notes); + js_DestroyScript(cx, script); + *scriptp = NULL; + } + return JS_FALSE; +} + +#if JS_HAS_XDR_FREEZE_THAW +/* + * These cannot be exposed to web content, and chrome does not need them, so + * we take them out of the Mozilla client altogether. Fortunately, there is + * no way to serialize a native function (see fun_xdrObject in jsfun.c). + */ + +static JSBool +script_freeze(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval) +{ + JSXDRState *xdr; + JSScript *script; + JSBool ok, hasMagic; + uint32 len; + void *buf; + JSString *str; + + if (!JS_InstanceOf(cx, obj, &js_ScriptClass, argv)) + return JS_FALSE; + script = (JSScript *) JS_GetPrivate(cx, obj); + if (!script) + return JS_TRUE; + + /* create new XDR */ + xdr = JS_XDRNewMem(cx, JSXDR_ENCODE); + if (!xdr) + return JS_FALSE; + + /* write */ + ok = js_XDRScript(xdr, &script, &hasMagic); + if (!ok) + goto out; + if (!hasMagic) { + *rval = JSVAL_VOID; + goto out; + } + + buf = JS_XDRMemGetData(xdr, &len); + if (!buf) { + ok = JS_FALSE; + goto out; + } + + JS_ASSERT((jsword)buf % sizeof(jschar) == 0); + len /= sizeof(jschar); + str = JS_NewUCStringCopyN(cx, (jschar *)buf, len); + if (!str) { + ok = JS_FALSE; + goto out; + } + +#if IS_BIG_ENDIAN + { + jschar *chars; + uint32 i; + + /* Swap bytes in Unichars to keep frozen strings machine-independent. */ + chars = JS_GetStringChars(str); + for (i = 0; i < len; i++) + chars[i] = JSXDR_SWAB16(chars[i]); + } +#endif + *rval = STRING_TO_JSVAL(str); + +out: + JS_XDRDestroy(xdr); + return ok; +} + +static JSBool +script_thaw(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval) +{ + JSXDRState *xdr; + JSString *str; + void *buf; + uint32 len; + JSScript *script, *oldscript; + JSBool ok, hasMagic; + + if (!JS_InstanceOf(cx, obj, &js_ScriptClass, argv)) + return JS_FALSE; + + if (argc == 0) + return JS_TRUE; + str = js_ValueToString(cx, argv[0]); + if (!str) + return JS_FALSE; + + /* create new XDR */ + xdr = JS_XDRNewMem(cx, JSXDR_DECODE); + if (!xdr) + return JS_FALSE; + + buf = JS_GetStringChars(str); + len = JS_GetStringLength(str); +#if IS_BIG_ENDIAN + { + jschar *from, *to; + uint32 i; + + /* Swap bytes in Unichars to keep frozen strings machine-independent. */ + from = (jschar *)buf; + to = (jschar *) JS_malloc(cx, len * sizeof(jschar)); + if (!to) { + JS_XDRDestroy(xdr); + return JS_FALSE; + } + for (i = 0; i < len; i++) + to[i] = JSXDR_SWAB16(from[i]); + buf = (char *)to; + } +#endif + len *= sizeof(jschar); + JS_XDRMemSetData(xdr, buf, len); + + /* XXXbe should magic mismatch be error, or false return value? */ + ok = js_XDRScript(xdr, &script, &hasMagic); + if (!ok) + goto out; + if (!hasMagic) { + *rval = JSVAL_FALSE; + goto out; + } + + /* Swap script for obj's old script, if any. */ + oldscript = (JSScript *) JS_GetPrivate(cx, obj); + ok = JS_SetPrivate(cx, obj, script); + if (!ok) { + JS_free(cx, script); + goto out; + } + if (oldscript) + js_DestroyScript(cx, oldscript); + + script->object = obj; + js_CallNewScriptHook(cx, script, NULL); + +out: + /* + * We reset the buffer to be NULL so that it doesn't free the chars + * memory owned by str (argv[0]). + */ + JS_XDRMemSetData(xdr, NULL, 0); + JS_XDRDestroy(xdr); +#if IS_BIG_ENDIAN + JS_free(cx, buf); +#endif + *rval = JSVAL_TRUE; + return ok; +} + +static const char js_thaw_str[] = "thaw"; + +#endif /* JS_HAS_XDR_FREEZE_THAW */ +#endif /* JS_HAS_XDR */ + +static JSFunctionSpec script_methods[] = { +#if JS_HAS_TOSOURCE + {js_toSource_str, script_toSource, 0,0,0}, +#endif + {js_toString_str, script_toString, 0,0,0}, + {"compile", script_compile, 2,0,0}, + {"exec", script_exec, 1,0,0}, +#if JS_HAS_XDR_FREEZE_THAW + {"freeze", script_freeze, 0,0,0}, + {js_thaw_str, script_thaw, 1,0,0}, +#endif /* JS_HAS_XDR_FREEZE_THAW */ + {0,0,0,0,0} +}; + +#endif /* JS_HAS_SCRIPT_OBJECT */ + +static void +script_finalize(JSContext *cx, JSObject *obj) +{ + JSScript *script; + + script = (JSScript *) JS_GetPrivate(cx, obj); + if (script) + js_DestroyScript(cx, script); +} + +static JSBool +script_call(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ +#if JS_HAS_SCRIPT_OBJECT + return script_exec(cx, JSVAL_TO_OBJECT(argv[-2]), argc, argv, rval); +#else + return JS_FALSE; +#endif +} + +static uint32 +script_mark(JSContext *cx, JSObject *obj, void *arg) +{ + JSScript *script; + + script = (JSScript *) JS_GetPrivate(cx, obj); + if (script) + js_MarkScript(cx, script, arg); + return 0; +} + +JS_FRIEND_DATA(JSClass) js_ScriptClass = { + js_Script_str, + JSCLASS_HAS_PRIVATE, + JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, + JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, script_finalize, + NULL, NULL, script_call, NULL,/*XXXbe xdr*/ + NULL, NULL, script_mark, 0 +}; + +#if JS_HAS_SCRIPT_OBJECT + +static JSBool +Script(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + /* If not constructing, replace obj with a new Script object. */ + if (!(cx->fp->flags & JSFRAME_CONSTRUCTING)) { + obj = js_NewObject(cx, &js_ScriptClass, NULL, NULL); + if (!obj) + return JS_FALSE; + } + return script_compile(cx, obj, argc, argv, rval); +} + +#if JS_HAS_XDR_FREEZE_THAW + +static JSBool +script_static_thaw(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval) +{ + obj = js_NewObject(cx, &js_ScriptClass, NULL, NULL); + if (!obj) + return JS_FALSE; + if (!script_thaw(cx, obj, argc, argv, rval)) + return JS_FALSE; + *rval = OBJECT_TO_JSVAL(obj); + return JS_TRUE; +} + +static JSFunctionSpec script_static_methods[] = { + {js_thaw_str, script_static_thaw, 1,0,0}, + {0,0,0,0,0} +}; + +#else /* !JS_HAS_XDR_FREEZE_THAW */ + +#define script_static_methods NULL + +#endif /* !JS_HAS_XDR_FREEZE_THAW */ + +JSObject * +js_InitScriptClass(JSContext *cx, JSObject *obj) +{ + return JS_InitClass(cx, obj, NULL, &js_ScriptClass, Script, 1, + NULL, script_methods, NULL, script_static_methods); +} + +#endif /* JS_HAS_SCRIPT_OBJECT */ + +/* + * Shared script filename management. + */ +static JSHashTable *script_filename_table; +#ifdef JS_THREADSAFE +static JSLock *script_filename_table_lock; +#endif + +JS_STATIC_DLL_CALLBACK(int) +js_compare_strings(const void *k1, const void *k2) +{ + return strcmp(k1, k2) == 0; +} + +/* Shared with jsatom.c to save code space. */ +extern void * JS_DLL_CALLBACK +js_alloc_table_space(void *priv, size_t size); + +extern void JS_DLL_CALLBACK +js_free_table_space(void *priv, void *item); + +/* NB: This struct overlays JSHashEntry -- see jshash.h, do not reorganize. */ +typedef struct ScriptFilenameEntry { + JSHashEntry *next; /* hash chain linkage */ + JSHashNumber keyHash; /* key hash function result */ + const void *key; /* ptr to filename, below */ + JSPackedBool mark; /* mark flag, for GC */ + char filename[3]; /* two or more bytes, NUL-terminated */ +} ScriptFilenameEntry; + +JS_STATIC_DLL_CALLBACK(JSHashEntry *) +js_alloc_entry(void *priv, const void *key) +{ + size_t nbytes = offsetof(ScriptFilenameEntry, filename) + strlen(key) + 1; + + return (JSHashEntry *) malloc(JS_MAX(nbytes, sizeof(JSHashEntry))); +} + +JS_STATIC_DLL_CALLBACK(void) +js_free_entry(void *priv, JSHashEntry *he, uintN flag) +{ + if (flag != HT_FREE_ENTRY) + return; + free(he); +} + +static JSHashAllocOps table_alloc_ops = { + js_alloc_table_space, js_free_table_space, + js_alloc_entry, js_free_entry +}; + +JSBool +js_InitScriptGlobals() +{ +#ifdef JS_THREADSAFE + /* Must come through here once in primordial thread to init safely! */ + if (!script_filename_table_lock) { + script_filename_table_lock = JS_NEW_LOCK(); + if (!script_filename_table_lock) + return JS_FALSE; + } +#endif + if (!script_filename_table) { + JS_ACQUIRE_LOCK(script_filename_table_lock); + if (!script_filename_table) { + script_filename_table = + JS_NewHashTable(16, JS_HashString, js_compare_strings, NULL, + &table_alloc_ops, NULL); + } + JS_RELEASE_LOCK(script_filename_table_lock); + if (!script_filename_table) + return JS_FALSE; + } + return JS_TRUE; +} + +void +js_FreeScriptGlobals() +{ + if (script_filename_table) { + JS_HashTableDestroy(script_filename_table); + script_filename_table = NULL; + } +#ifdef JS_THREADSAFE + if (script_filename_table_lock) { + JS_DESTROY_LOCK(script_filename_table_lock); + script_filename_table_lock = NULL; + } +#endif +} + +#ifdef DEBUG_brendan +size_t sft_savings = 0; +#endif + +const char * +js_SaveScriptFilename(JSContext *cx, const char *filename) +{ + JSHashTable *table; + JSHashNumber hash; + JSHashEntry **hep; + ScriptFilenameEntry *sfe; + + JS_ACQUIRE_LOCK(script_filename_table_lock); + table = script_filename_table; + hash = JS_HashString(filename); + hep = JS_HashTableRawLookup(table, hash, filename); + sfe = (ScriptFilenameEntry *) *hep; +#ifdef DEBUG_brendan + if (sfe) + sft_savings += strlen(sfe->filename); +#endif + if (!sfe) { + sfe = (ScriptFilenameEntry *) + JS_HashTableRawAdd(table, hep, hash, filename, NULL); + if (sfe) { + sfe->key = strcpy(sfe->filename, filename); + JS_ASSERT(!sfe->mark); + } + } + JS_RELEASE_LOCK(script_filename_table_lock); + if (!sfe) { + JS_ReportOutOfMemory(cx); + return NULL; + } + return sfe->filename; +} + +void +js_MarkScriptFilename(const char *filename) +{ + ScriptFilenameEntry *sfe; + + /* + * Back up from filename by its offset within its hash table entry. + * The sfe->key member, redundant given sfe->filename but required by + * the old jshash.c code, here gives us a useful sanity check. This + * assertion will very likely botch if someone tries to mark a string + * that wasn't allocated as an sfe->filename. + */ + sfe = (ScriptFilenameEntry *) + (filename - offsetof(ScriptFilenameEntry, filename)); + JS_ASSERT(sfe->key == sfe->filename); + sfe->mark = JS_TRUE; +} + +JS_STATIC_DLL_CALLBACK(intN) +js_script_filename_sweeper(JSHashEntry *he, intN i, void *arg) +{ + ScriptFilenameEntry *sfe = (ScriptFilenameEntry *) he; + + if (!sfe->mark) + return HT_ENUMERATE_REMOVE; + sfe->mark = JS_FALSE; + return HT_ENUMERATE_NEXT; +} + +void +js_SweepScriptFilenames(JSRuntime *rt) +{ + JS_HashTableEnumerateEntries(script_filename_table, + js_script_filename_sweeper, + rt); +#ifdef DEBUG_brendan + printf("script filename table savings so far: %u\n", sft_savings); +#endif +} + +JSScript * +js_NewScript(JSContext *cx, uint32 length, uint32 nsrcnotes, uint32 ntrynotes) +{ + JSScript *script; + + /* Round up source note count to align script->trynotes for its type. */ + if (ntrynotes) + nsrcnotes += JSTRYNOTE_ALIGNMASK; + script = (JSScript *) JS_malloc(cx, + sizeof(JSScript) + + length * sizeof(jsbytecode) + + nsrcnotes * sizeof(jssrcnote) + + ntrynotes * sizeof(JSTryNote)); + if (!script) + return NULL; + memset(script, 0, sizeof(JSScript)); + script->code = script->main = (jsbytecode *)(script + 1); + script->length = length; + script->version = cx->version; + if (ntrynotes) { + script->trynotes = (JSTryNote *) + ((jsword)(SCRIPT_NOTES(script) + nsrcnotes) & + ~(jsword)JSTRYNOTE_ALIGNMASK); + } + return script; +} + +JS_FRIEND_API(JSScript *) +js_NewScriptFromCG(JSContext *cx, JSCodeGenerator *cg, JSFunction *fun) +{ + uint32 mainLength, prologLength, nsrcnotes, ntrynotes; + JSScript *script; + const char *filename; + + mainLength = CG_OFFSET(cg); + prologLength = CG_PROLOG_OFFSET(cg); + CG_COUNT_FINAL_SRCNOTES(cg, nsrcnotes); + CG_COUNT_FINAL_TRYNOTES(cg, ntrynotes); + script = js_NewScript(cx, prologLength + mainLength, nsrcnotes, ntrynotes); + if (!script) + return NULL; + + /* Now that we have script, error control flow must go to label bad. */ + script->main += prologLength; + memcpy(script->code, CG_PROLOG_BASE(cg), prologLength * sizeof(jsbytecode)); + memcpy(script->main, CG_BASE(cg), mainLength * sizeof(jsbytecode)); + if (!js_InitAtomMap(cx, &script->atomMap, &cg->atomList)) + goto bad; + + filename = cg->filename; + if (filename) { + script->filename = js_SaveScriptFilename(cx, filename); + if (!script->filename) + goto bad; + } + script->lineno = cg->firstLine; + script->depth = cg->maxStackDepth; + if (cg->principals) { + script->principals = cg->principals; + JSPRINCIPALS_HOLD(cx, script->principals); + } + + if (!js_FinishTakingSrcNotes(cx, cg, SCRIPT_NOTES(script))) + goto bad; + if (script->trynotes) + js_FinishTakingTryNotes(cx, cg, script->trynotes); + + /* Tell the debugger about this compiled script. */ + js_CallNewScriptHook(cx, script, fun); + return script; + +bad: + js_DestroyScript(cx, script); + return NULL; +} + +JS_FRIEND_API(void) +js_CallNewScriptHook(JSContext *cx, JSScript *script, JSFunction *fun) +{ + JSRuntime *rt; + JSNewScriptHook hook; + + rt = cx->runtime; + hook = rt->newScriptHook; + if (hook) { + /* + * We use a dummy stack frame to protect the script from a GC caused + * by debugger-hook execution. + * + * XXX We really need a way to manage local roots and such more + * XXX automatically, at which point we can remove this one-off hack + * XXX and others within the engine. See bug 40757 for discussion. + */ + JSStackFrame dummy; + + memset(&dummy, 0, sizeof dummy); + dummy.down = cx->fp; + dummy.script = script; + cx->fp = &dummy; + + hook(cx, script->filename, script->lineno, script, fun, + rt->newScriptHookData); + + cx->fp = dummy.down; + } +} + +void +js_DestroyScript(JSContext *cx, JSScript *script) +{ + JSRuntime *rt; + JSDestroyScriptHook hook; + + rt = cx->runtime; + hook = rt->destroyScriptHook; + if (hook) + hook(cx, script, rt->destroyScriptHookData); + + JS_ClearScriptTraps(cx, script); + js_FreeAtomMap(cx, &script->atomMap); + if (script->principals) + JSPRINCIPALS_DROP(cx, script->principals); + JS_free(cx, script); +} + +void +js_MarkScript(JSContext *cx, JSScript *script, void *arg) +{ + JSAtomMap *map; + uintN i, length; + JSAtom **vector; + + map = &script->atomMap; + length = map->length; + vector = map->vector; + for (i = 0; i < length; i++) + GC_MARK_ATOM(cx, vector[i], arg); + + if (script->filename) + js_MarkScriptFilename(script->filename); +} + +jssrcnote * +js_GetSrcNote(JSScript *script, jsbytecode *pc) +{ + jssrcnote *sn; + ptrdiff_t offset, target; + + target = PTRDIFF(pc, script->code, jsbytecode); + if ((uint32)target >= script->length) + return NULL; + offset = 0; + for (sn = SCRIPT_NOTES(script); !SN_IS_TERMINATOR(sn); sn = SN_NEXT(sn)) { + offset += SN_DELTA(sn); + if (offset == target && SN_IS_GETTABLE(sn)) + return sn; + } + return NULL; +} + +uintN +js_PCToLineNumber(JSContext *cx, JSScript *script, jsbytecode *pc) +{ + JSAtom *atom; + JSFunction *fun; + uintN lineno; + ptrdiff_t offset, target; + jssrcnote *sn; + JSSrcNoteType type; + + /* + * Special case: function definition needs no line number note because + * the function's script contains its starting line number. + */ + if (*pc == JSOP_DEFFUN) { + atom = GET_ATOM(cx, script, pc); + fun = (JSFunction *) JS_GetPrivate(cx, ATOM_TO_OBJECT(atom)); + return fun->script->lineno; + } + + /* + * General case: walk through source notes accumulating their deltas, + * keeping track of line-number notes, until we pass the note for pc's + * offset within script->code. + */ + lineno = script->lineno; + offset = 0; + target = PTRDIFF(pc, script->code, jsbytecode); + for (sn = SCRIPT_NOTES(script); !SN_IS_TERMINATOR(sn); sn = SN_NEXT(sn)) { + offset += SN_DELTA(sn); + type = (JSSrcNoteType) SN_TYPE(sn); + if (type == SRC_SETLINE) { + if (offset <= target) + lineno = (uintN) js_GetSrcNoteOffset(sn, 0); + } else if (type == SRC_NEWLINE) { + if (offset <= target) + lineno++; + } + if (offset > target) + break; + } + return lineno; +} + +jsbytecode * +js_LineNumberToPC(JSScript *script, uintN target) +{ + ptrdiff_t offset; + uintN lineno; + jssrcnote *sn; + JSSrcNoteType type; + + offset = 0; + lineno = script->lineno; + for (sn = SCRIPT_NOTES(script); !SN_IS_TERMINATOR(sn); sn = SN_NEXT(sn)) { + if (lineno >= target) + break; + offset += SN_DELTA(sn); + type = (JSSrcNoteType) SN_TYPE(sn); + if (type == SRC_SETLINE) { + lineno = (uintN) js_GetSrcNoteOffset(sn, 0); + } else if (type == SRC_NEWLINE) { + lineno++; + } + } + return script->code + offset; +} + +uintN +js_GetScriptLineExtent(JSScript *script) +{ + uintN lineno; + jssrcnote *sn; + JSSrcNoteType type; + + lineno = script->lineno; + for (sn = SCRIPT_NOTES(script); !SN_IS_TERMINATOR(sn); sn = SN_NEXT(sn)) { + type = (JSSrcNoteType) SN_TYPE(sn); + if (type == SRC_SETLINE) { + lineno = (uintN) js_GetSrcNoteOffset(sn, 0); + } else if (type == SRC_NEWLINE) { + lineno++; + } + } + return 1 + lineno - script->lineno; +} diff --git a/src/extension/script/js/jsscript.h b/src/extension/script/js/jsscript.h new file mode 100644 index 000000000..ffcc40de7 --- /dev/null +++ b/src/extension/script/js/jsscript.h @@ -0,0 +1,178 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef jsscript_h___ +#define jsscript_h___ +/* + * JS script descriptor. + */ +#include "jsatom.h" +#include "jsprvtd.h" + +JS_BEGIN_EXTERN_C + +/* + * Exception handling runtime information. + * + * All fields except length are code offsets, relative to the beginning of + * the script. If script->trynotes is not null, it points to a vector of + * these structs terminated by one with catchStart == 0. + */ +struct JSTryNote { + ptrdiff_t start; /* start of try statement */ + ptrdiff_t length; /* count of try statement bytecodes */ + ptrdiff_t catchStart; /* start of catch block (0 if end) */ +}; + +#define JSTRYNOTE_GRAIN sizeof(ptrdiff_t) +#define JSTRYNOTE_ALIGNMASK (JSTRYNOTE_GRAIN - 1) + +struct JSScript { + jsbytecode *code; /* bytecodes and their immediate operands */ + uint32 length; /* length of code vector */ + jsbytecode *main; /* main entry point, after predef'ing prolog */ + JSVersion version; /* JS version under which script was compiled */ + JSAtomMap atomMap; /* maps immediate index to literal struct */ + const char *filename; /* source filename or null */ + uintN lineno; /* base line number of script */ + uintN depth; /* maximum stack depth in slots */ + JSTryNote *trynotes; /* exception table for this script */ + JSPrincipals *principals; /* principals for this script */ + JSObject *object; /* optional Script-class object wrapper */ +}; + +/* No need to store script->notes now that it is allocated right after code. */ +#define SCRIPT_NOTES(script) ((jssrcnote*)((script)->code+(script)->length)) + +#define SCRIPT_FIND_CATCH_START(script, pc, catchpc) \ + JS_BEGIN_MACRO \ + JSTryNote *tn_ = (script)->trynotes; \ + jsbytecode *catchpc_ = NULL; \ + if (tn_) { \ + ptrdiff_t off_ = PTRDIFF(pc, (script)->main, jsbytecode); \ + if (off_ >= 0) { \ + while ((jsuword)(off_ - tn_->start) >= (jsuword)tn_->length) \ + ++tn_; \ + if (tn_->catchStart) \ + catchpc_ = (script)->main + tn_->catchStart; \ + } \ + } \ + catchpc = catchpc_; \ + JS_END_MACRO + +extern JS_FRIEND_DATA(JSClass) js_ScriptClass; + +extern JSObject * +js_InitScriptClass(JSContext *cx, JSObject *obj); + +extern JSBool +js_InitScriptGlobals(); + +extern void +js_FreeScriptGlobals(); + +extern const char * +js_SaveScriptFilename(JSContext *cx, const char *filename); + +extern void +js_MarkScriptFilename(const char *filename); + +extern void +js_SweepScriptFilenames(JSRuntime *rt); + +/* + * Two successively less primitive ways to make a new JSScript. The first + * does *not* call a non-null cx->runtime->newScriptHook -- only the second, + * js_NewScriptFromCG, calls this optional debugger hook. + * + * The js_NewScript function can't know whether the script it creates belongs + * to a function, or is top-level or eval code, but the debugger wants access + * to the newly made script's function, if any -- so callers of js_NewScript + * are responsible for notifying the debugger after successfully creating any + * kind (function or other) of new JSScript. + */ +extern JSScript * +js_NewScript(JSContext *cx, uint32 length, uint32 snlength, uint32 tnlength); + +extern JS_FRIEND_API(JSScript *) +js_NewScriptFromCG(JSContext *cx, JSCodeGenerator *cg, JSFunction *fun); + +/* + * New-script-hook calling is factored from js_NewScriptFromCG so that it + * and callers of js_XDRScript can share this code. In the case of callers + * of js_XDRScript, the hook should be invoked only after successful decode + * of any owning function (the fun parameter) or script object (null fun). + */ +extern JS_FRIEND_API(void) +js_CallNewScriptHook(JSContext *cx, JSScript *script, JSFunction *fun); + +extern void +js_DestroyScript(JSContext *cx, JSScript *script); + +extern void +js_MarkScript(JSContext *cx, JSScript *script, void *arg); + +extern jssrcnote * +js_GetSrcNote(JSScript *script, jsbytecode *pc); + +/* XXX need cx to lock function objects declared by prolog bytecodes. */ +extern uintN +js_PCToLineNumber(JSContext *cx, JSScript *script, jsbytecode *pc); + +extern jsbytecode * +js_LineNumberToPC(JSScript *script, uintN lineno); + +extern uintN +js_GetScriptLineExtent(JSScript *script); + +/* + * If magic is non-null, js_XDRScript succeeds on magic number mismatch but + * returns false in *magic; it reflects a match via a true *magic out param. + * If magic is null, js_XDRScript returns false on bad magic number errors, + * which it reports. + * + * NB: callers must call js_CallNewScriptHook after successful JSXDR_DECODE + * and subsequent set-up of owning function or script object, if any. + */ +extern JSBool +js_XDRScript(JSXDRState *xdr, JSScript **scriptp, JSBool *magic); + +JS_END_EXTERN_C + +#endif /* jsscript_h___ */ diff --git a/src/extension/script/js/jsshell.msg b/src/extension/script/js/jsshell.msg new file mode 100644 index 000000000..4b811ac01 --- /dev/null +++ b/src/extension/script/js/jsshell.msg @@ -0,0 +1,50 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* + Error messages for JSShell. See js.msg for format. +*/ + +MSG_DEF(JSSMSG_NOT_AN_ERROR, 0, 0, JSEXN_NONE, "") +MSG_DEF(JSSMSG_CANT_OPEN, 1, 2, JSEXN_NONE, "can't open {0}: {1}") +MSG_DEF(JSSMSG_TRAP_USAGE, 2, 0, JSEXN_NONE, "usage: trap [fun] [pc] expr") +MSG_DEF(JSSMSG_LINE2PC_USAGE, 3, 0, JSEXN_NONE, "usage: line2pc [fun] line") +MSG_DEF(JSSMSG_FILE_SCRIPTS_ONLY, 4, 0, JSEXN_NONE, "only works on JS scripts read from files") +MSG_DEF(JSSMSG_UNEXPECTED_EOF, 5, 1, JSEXN_NONE, "unexpected EOF in {0}") +MSG_DEF(JSSMSG_DOEXP_USAGE, 6, 0, JSEXN_NONE, "usage: doexp obj id") diff --git a/src/extension/script/js/jsstddef.h b/src/extension/script/js/jsstddef.h new file mode 100644 index 000000000..0d87b0c0c --- /dev/null +++ b/src/extension/script/js/jsstddef.h @@ -0,0 +1,83 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* + * stddef inclusion here to first declare ptrdif as a signed long instead of a + * signed int. + */ + +#ifdef _WINDOWS +# ifndef XP_WIN +# define XP_WIN +# endif +#if defined(_WIN32) || defined(WIN32) +# ifndef XP_WIN32 +# define XP_WIN32 +# endif +#else +# ifndef XP_WIN16 +# define XP_WIN16 +# endif +#endif +#endif + +#ifdef XP_WIN16 +#ifndef _PTRDIFF_T_DEFINED +typedef long ptrdiff_t; + +/* + * The Win16 compiler treats pointer differences as 16-bit signed values. + * This macro allows us to treat them as 17-bit signed values, stored in + * a 32-bit type. + */ +#define PTRDIFF(p1, p2, type) \ + ((((unsigned long)(p1)) - ((unsigned long)(p2))) / sizeof(type)) + +#define _PTRDIFF_T_DEFINED +#endif /*_PTRDIFF_T_DEFINED*/ +#else /*WIN16*/ + +#define PTRDIFF(p1, p2, type) \ + ((p1) - (p2)) + +#endif + +#include + + diff --git a/src/extension/script/js/jsstr.c b/src/extension/script/js/jsstr.c new file mode 100644 index 000000000..e143ab8df --- /dev/null +++ b/src/extension/script/js/jsstr.c @@ -0,0 +1,4502 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* + * JS string type implementation. + * + * In order to avoid unnecessary js_LockGCThing/js_UnlockGCThing calls, these + * native methods store strings (possibly newborn) converted from their 'this' + * parameter and arguments on the stack: 'this' conversions at argv[-1], arg + * conversions at their index (argv[0], argv[1]). This is a legitimate method + * of rooting things that might lose their newborn root due to subsequent GC + * allocations in the same native method. + */ +#include "jsstddef.h" +#include +#include +#include "jstypes.h" +#include "jsutil.h" /* Added by JSIFY */ +#include "jshash.h" /* Added by JSIFY */ +#include "jsprf.h" +#include "jsapi.h" +#include "jsarray.h" +#include "jsatom.h" +#include "jsbool.h" +#include "jscntxt.h" +#include "jsconfig.h" +#include "jsgc.h" +#include "jsinterp.h" +#include "jslock.h" +#include "jsnum.h" +#include "jsobj.h" +#include "jsopcode.h" +#include "jsregexp.h" +#include "jsstr.h" + +#if JS_HAS_REPLACE_LAMBDA +#include "jsinterp.h" +#endif + +#define JSSTRDEP_RECURSION_LIMIT 100 + +size_t +js_MinimizeDependentStrings(JSString *str, int level, JSString **basep) +{ + JSString *base; + size_t start, length; + + JS_ASSERT(JSSTRING_IS_DEPENDENT(str)); + base = JSSTRDEP_BASE(str); + start = JSSTRDEP_START(str); + if (JSSTRING_IS_DEPENDENT(base)) { + if (level < JSSTRDEP_RECURSION_LIMIT) { + start += js_MinimizeDependentStrings(base, level + 1, &base); + } else { + do { + start += JSSTRDEP_START(base); + base = JSSTRDEP_BASE(base); + } while (JSSTRING_IS_DEPENDENT(base)); + } + if (start == 0) { + JS_ASSERT(JSSTRING_IS_PREFIX(str)); + JSPREFIX_SET_BASE(str, base); + } else if (start <= JSSTRDEP_START_MASK) { + length = JSSTRDEP_LENGTH(str); + JSSTRDEP_SET_START_AND_LENGTH(str, start, length); + JSSTRDEP_SET_BASE(str, base); + } + } + *basep = base; + return start; +} + +jschar * +js_GetDependentStringChars(JSString *str) +{ + size_t start; + JSString *base; + + start = js_MinimizeDependentStrings(str, 0, &base); + JS_ASSERT(!JSSTRING_IS_DEPENDENT(base)); + JS_ASSERT(start < base->length); + return base->chars + start; +} + +jschar * +js_GetStringChars(JSString *str) +{ + if (JSSTRING_IS_DEPENDENT(str) && !js_UndependString(NULL, str)) + return NULL; + + *js_GetGCThingFlags(str) &= ~GCF_MUTABLE; + return str->chars; +} + +JSString * +js_ConcatStrings(JSContext *cx, JSString *left, JSString *right) +{ + size_t rn, ln, lrdist, n; + jschar *rs, *ls, *s; + JSDependentString *ldep; /* non-null if left should become dependent */ + JSString *str; + + if (JSSTRING_IS_DEPENDENT(right)) { + rn = JSSTRDEP_LENGTH(right); + rs = JSSTRDEP_CHARS(right); + } else { + rn = right->length; + rs = right->chars; + } + if (rn == 0) + return left; + + if (JSSTRING_IS_DEPENDENT(left) || + !(*js_GetGCThingFlags(left) & GCF_MUTABLE)) { + /* We must copy if left does not own a buffer to realloc. */ + ln = JSSTRING_LENGTH(left); + if (ln == 0) + return right; + ls = JSSTRING_CHARS(left); + s = (jschar *) JS_malloc(cx, (ln + rn + 1) * sizeof(jschar)); + if (!s) + return NULL; + js_strncpy(s, ls, ln); + ldep = NULL; + } else { + /* We can realloc left's space and make it depend on our result. */ + ln = left->length; + if (ln == 0) + return right; + ls = left->chars; + s = (jschar *) JS_realloc(cx, ls, (ln + rn + 1) * sizeof(jschar)); + if (!s) + return NULL; + + /* Take care: right could depend on left! */ + lrdist = (size_t)(rs - ls); + if (lrdist < ln) + rs = s + lrdist; + left->chars = ls = s; + ldep = JSSTRDEP(left); + } + + js_strncpy(s + ln, rs, rn); + n = ln + rn; + s[n] = 0; + str = js_NewString(cx, s, n, GCF_MUTABLE); + if (!str) { + /* Out of memory: clean up any space we (re-)allocated. */ + if (!ldep) { + JS_free(cx, s); + } else { + s = JS_realloc(cx, ls, (ln + 1) * sizeof(jschar)); + if (s) + left->chars = s; + } + } else { + /* Morph left into a dependent prefix if we realloc'd its buffer. */ + if (ldep) { + JSPREFIX_SET_LENGTH(ldep, ln); + JSPREFIX_SET_BASE(ldep, str); +#ifdef DEBUG + { + JSRuntime *rt = cx->runtime; + JS_RUNTIME_METER(rt, liveDependentStrings); + JS_RUNTIME_METER(rt, totalDependentStrings); + JS_LOCK_RUNTIME_VOID(rt, + (rt->strdepLengthSum += (double)ln, + rt->strdepLengthSquaredSum += (double)ln * (double)ln)); + } +#endif + } + } + + return str; +} + +/* + * May be called with null cx by js_GetStringChars, above; and by the jslock.c + * MAKE_STRING_IMMUTABLE file-local macro. + */ +const jschar * +js_UndependString(JSContext *cx, JSString *str) +{ + size_t n, size; + jschar *s; + + if (JSSTRING_IS_DEPENDENT(str)) { + n = JSSTRDEP_LENGTH(str); + size = (n + 1) * sizeof(jschar); + s = (jschar *) (cx ? JS_malloc(cx, size) : malloc(size)); + if (!s) + return NULL; + + js_strncpy(s, JSSTRDEP_CHARS(str), n); + s[n] = 0; + str->length = n; + str->chars = s; + +#ifdef DEBUG + if (cx) { + JSRuntime *rt = cx->runtime; + JS_RUNTIME_UNMETER(rt, liveDependentStrings); + JS_RUNTIME_UNMETER(rt, totalDependentStrings); + JS_LOCK_RUNTIME_VOID(rt, + (rt->strdepLengthSum -= (double)n, + rt->strdepLengthSquaredSum -= (double)n * (double)n)); + } +#endif + } + + return str->chars; +} + +/* + * Forward declarations for URI encode/decode and helper routines + */ +static JSBool +str_decodeURI(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval); + +static JSBool +str_decodeURI_Component(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval); + +static JSBool +str_encodeURI(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval); + +static JSBool +str_encodeURI_Component(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval); + +static int +OneUcs4ToUtf8Char(uint8 *utf8Buffer, uint32 ucs4Char); + +static uint32 +Utf8ToOneUcs4Char(const uint8 *utf8Buffer, int utf8Length); + +/* + * Contributions from the String class to the set of methods defined for the + * global object. escape and unescape used to be defined in the Mocha library, + * but as ECMA decided to spec them, they've been moved to the core engine + * and made ECMA-compliant. (Incomplete escapes are interpreted as literal + * characters by unescape.) + */ + +/* + * Stuff to emulate the old libmocha escape, which took a second argument + * giving the type of escape to perform. Retained for compatibility, and + * copied here to avoid reliance on net.h, mkparse.c/NET_EscapeBytes. + */ + +#define URL_XALPHAS ((uint8) 1) +#define URL_XPALPHAS ((uint8) 2) +#define URL_PATH ((uint8) 4) + +static const uint8 urlCharType[256] = +/* Bit 0 xalpha -- the alphas + * Bit 1 xpalpha -- as xalpha but + * converts spaces to plus and plus to %20 + * Bit 2 ... path -- as xalphas but doesn't escape '/' + */ + /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ + { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x */ + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1x */ + 0,0,0,0,0,0,0,0,0,0,7,4,0,7,7,4, /* 2x !"#$%&'()*+,-./ */ + 7,7,7,7,7,7,7,7,7,7,0,0,0,0,0,0, /* 3x 0123456789:;<=>? */ + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, /* 4x @ABCDEFGHIJKLMNO */ + 7,7,7,7,7,7,7,7,7,7,7,0,0,0,0,7, /* 5X PQRSTUVWXYZ[\]^_ */ + 0,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, /* 6x `abcdefghijklmno */ + 7,7,7,7,7,7,7,7,7,7,7,0,0,0,0,0, /* 7X pqrstuvwxyz{\}~ DEL */ + 0, }; + +/* This matches the ECMA escape set when mask is 7 (default.) */ + +#define IS_OK(C, mask) (urlCharType[((uint8) (C))] & (mask)) + +/* See ECMA-262 15.1.2.4. */ +JSBool +js_str_escape(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + JSString *str; + size_t i, ni, length, newlength; + const jschar *chars; + jschar *newchars; + jschar ch; + jsint mask; + jsdouble d; + const char digits[] = {'0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; + + mask = URL_XALPHAS | URL_XPALPHAS | URL_PATH; + if (argc > 1) { + if (!js_ValueToNumber(cx, argv[1], &d)) + return JS_FALSE; + if (!JSDOUBLE_IS_FINITE(d) || + (mask = (jsint)d) != d || + mask & ~(URL_XALPHAS | URL_XPALPHAS | URL_PATH)) + { + char numBuf[12]; + JS_snprintf(numBuf, sizeof numBuf, "%lx", (unsigned long) mask); + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, + JSMSG_BAD_STRING_MASK, numBuf); + return JS_FALSE; + } + } + + str = js_ValueToString(cx, argv[0]); + if (!str) + return JS_FALSE; + argv[0] = STRING_TO_JSVAL(str); + + chars = JSSTRING_CHARS(str); + length = newlength = JSSTRING_LENGTH(str); + + /* Take a first pass and see how big the result string will need to be. */ + for (i = 0; i < length; i++) { + if ((ch = chars[i]) < 128 && IS_OK(ch, mask)) + continue; + if (ch < 256) { + if (mask == URL_XPALPHAS && ch == ' ') + continue; /* The character will be encoded as '+' */ + newlength += 2; /* The character will be encoded as %XX */ + } else { + newlength += 5; /* The character will be encoded as %uXXXX */ + } + } + + newchars = (jschar *) JS_malloc(cx, (newlength + 1) * sizeof(jschar)); + if (!newchars) + return JS_FALSE; + for (i = 0, ni = 0; i < length; i++) { + if ((ch = chars[i]) < 128 && IS_OK(ch, mask)) { + newchars[ni++] = ch; + } else if (ch < 256) { + if (mask == URL_XPALPHAS && ch == ' ') { + newchars[ni++] = '+'; /* convert spaces to pluses */ + } else { + newchars[ni++] = '%'; + newchars[ni++] = digits[ch >> 4]; + newchars[ni++] = digits[ch & 0xF]; + } + } else { + newchars[ni++] = '%'; + newchars[ni++] = 'u'; + newchars[ni++] = digits[ch >> 12]; + newchars[ni++] = digits[(ch & 0xF00) >> 8]; + newchars[ni++] = digits[(ch & 0xF0) >> 4]; + newchars[ni++] = digits[ch & 0xF]; + } + } + JS_ASSERT(ni == newlength); + newchars[newlength] = 0; + + str = js_NewString(cx, newchars, newlength, 0); + if (!str) { + JS_free(cx, newchars); + return JS_FALSE; + } + *rval = STRING_TO_JSVAL(str); + return JS_TRUE; +} +#undef IS_OK + +/* See ECMA-262 15.1.2.5 */ +static JSBool +str_unescape(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + JSString *str; + size_t i, ni, length; + const jschar *chars; + jschar *newchars; + jschar ch; + + str = js_ValueToString(cx, argv[0]); + if (!str) + return JS_FALSE; + argv[0] = STRING_TO_JSVAL(str); + + chars = JSSTRING_CHARS(str); + length = JSSTRING_LENGTH(str); + + /* Don't bother allocating less space for the new string. */ + newchars = (jschar *) JS_malloc(cx, (length + 1) * sizeof(jschar)); + if (!newchars) + return JS_FALSE; + ni = i = 0; + while (i < length) { + ch = chars[i++]; + if (ch == '%') { + if (i + 1 < length && + JS7_ISHEX(chars[i]) && JS7_ISHEX(chars[i + 1])) + { + ch = JS7_UNHEX(chars[i]) * 16 + JS7_UNHEX(chars[i + 1]); + i += 2; + } else if (i + 4 < length && chars[i] == 'u' && + JS7_ISHEX(chars[i + 1]) && JS7_ISHEX(chars[i + 2]) && + JS7_ISHEX(chars[i + 3]) && JS7_ISHEX(chars[i + 4])) + { + ch = (((((JS7_UNHEX(chars[i + 1]) << 4) + + JS7_UNHEX(chars[i + 2])) << 4) + + JS7_UNHEX(chars[i + 3])) << 4) + + JS7_UNHEX(chars[i + 4]); + i += 5; + } + } + newchars[ni++] = ch; + } + newchars[ni] = 0; + + str = js_NewString(cx, newchars, ni, 0); + if (!str) { + JS_free(cx, newchars); + return JS_FALSE; + } + *rval = STRING_TO_JSVAL(str); + return JS_TRUE; +} + +#if JS_HAS_UNEVAL +static JSBool +str_uneval(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + JSString *str; + + str = js_ValueToSource(cx, argv[0]); + if (!str) + return JS_FALSE; + *rval = STRING_TO_JSVAL(str); + return JS_TRUE; +} +#endif + +const char js_escape_str[] = "escape"; +const char js_unescape_str[] = "unescape"; +#if JS_HAS_UNEVAL +const char js_uneval_str[] = "uneval"; +#endif +const char js_decodeURI_str[] = "decodeURI"; +const char js_encodeURI_str[] = "encodeURI"; +const char js_decodeURIComponent_str[] = "decodeURIComponent"; +const char js_encodeURIComponent_str[] = "encodeURIComponent"; + +static JSFunctionSpec string_functions[] = { + {js_escape_str, js_str_escape, 1,0,0}, + {js_unescape_str, str_unescape, 1,0,0}, +#if JS_HAS_UNEVAL + {js_uneval_str, str_uneval, 1,0,0}, +#endif + {js_decodeURI_str, str_decodeURI, 1,0,0}, + {js_encodeURI_str, str_encodeURI, 1,0,0}, + {js_decodeURIComponent_str, str_decodeURI_Component, 1,0,0}, + {js_encodeURIComponent_str, str_encodeURI_Component, 1,0,0}, + + {0,0,0,0,0} +}; + +jschar js_empty_ucstr[] = {0}; +JSSubString js_EmptySubString = {0, js_empty_ucstr}; + +enum string_tinyid { + STRING_LENGTH = -1 +}; + +static JSPropertySpec string_props[] = { + {js_length_str, STRING_LENGTH, + JSPROP_READONLY|JSPROP_PERMANENT|JSPROP_SHARED, 0,0}, + {0,0,0,0,0} +}; + +static JSBool +str_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp) +{ + JSString *str; + jsint slot; + + if (!JSVAL_IS_INT(id)) + return JS_TRUE; + str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj)); + if (!str) + return JS_FALSE; + slot = JSVAL_TO_INT(id); + if (slot == STRING_LENGTH) + *vp = INT_TO_JSVAL((jsint) JSSTRING_LENGTH(str)); + return JS_TRUE; +} + +#define STRING_ELEMENT_ATTRS (JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_PERMANENT) + +static JSBool +str_enumerate(JSContext *cx, JSObject *obj) +{ + JSString *str, *str1; + size_t i, length; + + str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj)); + if (!str) + return JS_FALSE; + length = JSSTRING_LENGTH(str); + for (i = 0; i < length; i++) { + str1 = js_NewDependentString(cx, str, i, 1, 0); + if (!str1) + return JS_FALSE; + if (!OBJ_DEFINE_PROPERTY(cx, obj, INT_TO_JSVAL(i), + STRING_TO_JSVAL(str1), NULL, NULL, + STRING_ELEMENT_ATTRS, NULL)) { + return JS_FALSE; + } + } + return JS_TRUE; +} + +static JSBool +str_resolve(JSContext *cx, JSObject *obj, jsval id) +{ + JSString *str, *str1; + jsint slot; + + if (!JSVAL_IS_INT(id)) + return JS_TRUE; + + str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj)); + if (!str) + return JS_FALSE; + slot = JSVAL_TO_INT(id); + if ((size_t)slot < JSSTRING_LENGTH(str)) { + str1 = js_NewDependentString(cx, str, (size_t)slot, 1, 0); + if (!str1) + return JS_FALSE; + if (!OBJ_DEFINE_PROPERTY(cx, obj, INT_TO_JSVAL(slot), + STRING_TO_JSVAL(str1), NULL, NULL, + STRING_ELEMENT_ATTRS, NULL)) { + return JS_FALSE; + } + } + return JS_TRUE; +} + +static JSClass string_class = { + js_String_str, + JSCLASS_HAS_PRIVATE, + JS_PropertyStub, JS_PropertyStub, str_getProperty, JS_PropertyStub, + str_enumerate, str_resolve, JS_ConvertStub, JS_FinalizeStub, + JSCLASS_NO_OPTIONAL_MEMBERS +}; + +#if JS_HAS_TOSOURCE + +/* + * String.prototype.quote is generic (as are most string methods), unlike + * toSource, toString, and valueOf. + */ +static JSBool +str_quote(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + JSString *str; + + str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj)); + if (!str) + return JS_FALSE; + str = js_QuoteString(cx, str, '"'); + if (!str) + return JS_FALSE; + *rval = STRING_TO_JSVAL(str); + return JS_TRUE; +} + +static JSBool +str_toSource(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + jsval v; + JSString *str; + size_t i, j, k, n; + char buf[16]; + jschar *s, *t; + + if (!JS_InstanceOf(cx, obj, &string_class, argv)) + return JS_FALSE; + v = OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE); + if (!JSVAL_IS_STRING(v)) + return js_obj_toSource(cx, obj, argc, argv, rval); + str = js_QuoteString(cx, JSVAL_TO_STRING(v), '"'); + if (!str) + return JS_FALSE; + j = JS_snprintf(buf, sizeof buf, "(new %s(", string_class.name); + s = JSSTRING_CHARS(str); + k = JSSTRING_LENGTH(str); + n = j + k + 2; + t = (jschar *) JS_malloc(cx, (n + 1) * sizeof(jschar)); + if (!t) + return JS_FALSE; + for (i = 0; i < j; i++) + t[i] = buf[i]; + for (j = 0; j < k; i++, j++) + t[i] = s[j]; + t[i++] = ')'; + t[i++] = ')'; + t[i] = 0; + str = js_NewString(cx, t, n, 0); + if (!str) { + JS_free(cx, t); + return JS_FALSE; + } + *rval = STRING_TO_JSVAL(str); + return JS_TRUE; +} + +#endif /* JS_HAS_TOSOURCE */ + +static JSBool +str_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + jsval v; + + if (!JS_InstanceOf(cx, obj, &string_class, argv)) + return JS_FALSE; + v = OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE); + if (!JSVAL_IS_STRING(v)) + return js_obj_toString(cx, obj, argc, argv, rval); + *rval = v; + return JS_TRUE; +} + +static JSBool +str_valueOf(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + if (!JS_InstanceOf(cx, obj, &string_class, argv)) + return JS_FALSE; + *rval = OBJ_GET_SLOT(cx, obj, JSSLOT_PRIVATE); + return JS_TRUE; +} + +/* + * Java-like string native methods. + */ +static JSBool +str_substring(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval) +{ + JSString *str; + jsdouble d; + jsdouble length, begin, end; + + str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj)); + if (!str) + return JS_FALSE; + argv[-1] = STRING_TO_JSVAL(str); + + if (argc != 0) { + if (!js_ValueToNumber(cx, argv[0], &d)) + return JS_FALSE; + length = JSSTRING_LENGTH(str); + begin = js_DoubleToInteger(d); + if (begin < 0) + begin = 0; + else if (begin > length) + begin = length; + + if (argc == 1) { + end = length; + } else { + if (!js_ValueToNumber(cx, argv[1], &d)) + return JS_FALSE; + end = js_DoubleToInteger(d); + if (end < 0) + end = 0; + else if (end > length) + end = length; + if (end < begin) { + if (cx->version != JSVERSION_1_2) { + /* XXX emulate old JDK1.0 java.lang.String.substring. */ + jsdouble tmp = begin; + begin = end; + end = tmp; + } else { + end = begin; + } + } + } + + str = js_NewDependentString(cx, str, (size_t)begin, + (size_t)(end - begin), 0); + if (!str) + return JS_FALSE; + } + *rval = STRING_TO_JSVAL(str); + return JS_TRUE; +} + +static JSBool +str_toLowerCase(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval) +{ + JSString *str; + size_t i, n; + jschar *s, *news; + + str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj)); + if (!str) + return JS_FALSE; + n = JSSTRING_LENGTH(str); + news = (jschar *) JS_malloc(cx, (n + 1) * sizeof(jschar)); + if (!news) + return JS_FALSE; + s = JSSTRING_CHARS(str); + for (i = 0; i < n; i++) + news[i] = JS_TOLOWER(s[i]); + news[n] = 0; + str = js_NewString(cx, news, n, 0); + if (!str) { + JS_free(cx, news); + return JS_FALSE; + } + *rval = STRING_TO_JSVAL(str); + return JS_TRUE; +} + +static JSBool +str_toLocaleLowerCase(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval) +{ + JSString *str; + + /* + * Forcefully ignore the first (or any) argument and return toLowerCase(), + * ECMA has reserved that argument, presumably for defining the locale. + */ + if (cx->localeCallbacks && cx->localeCallbacks->localeToLowerCase) { + str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj)); + if (!str) + return JS_FALSE; + return cx->localeCallbacks->localeToLowerCase(cx, str, rval); + } + return str_toLowerCase(cx, obj, 0, argv, rval); +} + +static JSBool +str_toUpperCase(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval) +{ + JSString *str; + size_t i, n; + jschar *s, *news; + + str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj)); + if (!str) + return JS_FALSE; + n = JSSTRING_LENGTH(str); + news = (jschar *) JS_malloc(cx, (n + 1) * sizeof(jschar)); + if (!news) + return JS_FALSE; + s = JSSTRING_CHARS(str); + for (i = 0; i < n; i++) + news[i] = JS_TOUPPER(s[i]); + news[n] = 0; + str = js_NewString(cx, news, n, 0); + if (!str) { + JS_free(cx, news); + return JS_FALSE; + } + *rval = STRING_TO_JSVAL(str); + return JS_TRUE; +} + +static JSBool +str_toLocaleUpperCase(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval) +{ + JSString *str; + + /* + * Forcefully ignore the first (or any) argument and return toUpperCase(), + * ECMA has reserved that argument, presumbaly for defining the locale. + */ + if (cx->localeCallbacks && cx->localeCallbacks->localeToUpperCase) { + str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj)); + if (!str) + return JS_FALSE; + return cx->localeCallbacks->localeToUpperCase(cx, str, rval); + } + return str_toUpperCase(cx, obj, 0, argv, rval); +} + +static JSBool +str_localeCompare(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval) +{ + JSString *str, *thatStr; + + str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj)); + if (!str) + return JS_FALSE; + argv[-1] = STRING_TO_JSVAL(str); + + if (argc == 0) { + *rval = JSVAL_ZERO; + } else { + thatStr = js_ValueToString(cx, argv[0]); + if (!thatStr) + return JS_FALSE; + if (cx->localeCallbacks && cx->localeCallbacks->localeCompare) + return cx->localeCallbacks->localeCompare(cx, str, thatStr, rval); + *rval = INT_TO_JSVAL(js_CompareStrings(str, thatStr)); + } + return JS_TRUE; +} + +static JSBool +str_charAt(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + JSString *str; + jsdouble d; + size_t index; + + str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj)); + if (!str) + return JS_FALSE; + argv[-1] = STRING_TO_JSVAL(str); + + if (argc == 0) { + d = 0.0; + } else { + if (!js_ValueToNumber(cx, argv[0], &d)) + return JS_FALSE; + d = js_DoubleToInteger(d); + } + + if (d < 0 || JSSTRING_LENGTH(str) <= d) { + *rval = JS_GetEmptyStringValue(cx); + } else { + index = (size_t)d; + str = js_NewDependentString(cx, str, index, 1, 0); + if (!str) + return JS_FALSE; + *rval = STRING_TO_JSVAL(str); + } + return JS_TRUE; +} + +static JSBool +str_charCodeAt(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval) +{ + JSString *str; + jsdouble d; + size_t index; + + str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj)); + if (!str) + return JS_FALSE; + argv[-1] = STRING_TO_JSVAL(str); + + if (argc == 0) { + d = 0.0; + } else { + if (!js_ValueToNumber(cx, argv[0], &d)) + return JS_FALSE; + d = js_DoubleToInteger(d); + } + + if (d < 0 || JSSTRING_LENGTH(str) <= d) { + *rval = JS_GetNaNValue(cx); + } else { + index = (size_t)d; + *rval = INT_TO_JSVAL((jsint) JSSTRING_CHARS(str)[index]); + } + return JS_TRUE; +} + +jsint +js_BoyerMooreHorspool(const jschar *text, jsint textlen, + const jschar *pat, jsint patlen, + jsint start) +{ + jsint i, j, k, m; + uint8 skip[BMH_CHARSET_SIZE]; + jschar c; + + JS_ASSERT(0 < patlen && patlen <= BMH_PATLEN_MAX); + for (i = 0; i < BMH_CHARSET_SIZE; i++) + skip[i] = (uint8)patlen; + m = patlen - 1; + for (i = 0; i < m; i++) { + c = pat[i]; + if (c >= BMH_CHARSET_SIZE) + return BMH_BAD_PATTERN; + skip[c] = (uint8)(m - i); + } + for (k = start + m; + k < textlen; + k += ((c = text[k]) >= BMH_CHARSET_SIZE) ? patlen : skip[c]) { + for (i = k, j = m; ; i--, j--) { + if (j < 0) + return i + 1; + if (text[i] != pat[j]) + break; + } + } + return -1; +} + +static JSBool +str_indexOf(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + JSString *str, *str2; + jsint i, j, index, textlen, patlen; + const jschar *text, *pat; + jsdouble d; + + str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj)); + if (!str) + return JS_FALSE; + argv[-1] = STRING_TO_JSVAL(str); + text = JSSTRING_CHARS(str); + textlen = (jsint) JSSTRING_LENGTH(str); + + str2 = js_ValueToString(cx, argv[0]); + if (!str2) + return JS_FALSE; + argv[0] = STRING_TO_JSVAL(str2); + pat = JSSTRING_CHARS(str2); + patlen = (jsint) JSSTRING_LENGTH(str2); + + if (argc > 1) { + if (!js_ValueToNumber(cx, argv[1], &d)) + return JS_FALSE; + d = js_DoubleToInteger(d); + if (d < 0) + i = 0; + else if (d > textlen) + i = textlen; + else + i = (jsint)d; + } else { + i = 0; + } + if (patlen == 0) { + *rval = INT_TO_JSVAL(i); + return JS_TRUE; + } + + /* XXX tune the BMH threshold (512) */ + if ((jsuint)(patlen - 2) <= BMH_PATLEN_MAX - 2 && textlen >= 512) { + index = js_BoyerMooreHorspool(text, textlen, pat, patlen, i); + if (index != BMH_BAD_PATTERN) + goto out; + } + + index = -1; + j = 0; + while (i + j < textlen) { + if (text[i + j] == pat[j]) { + if (++j == patlen) { + index = i; + break; + } + } else { + i++; + j = 0; + } + } + +out: + *rval = INT_TO_JSVAL(index); + return JS_TRUE; +} + +static JSBool +str_lastIndexOf(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval) +{ + JSString *str, *str2; + const jschar *text, *pat; + jsint i, j, textlen, patlen; + jsdouble d; + + str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj)); + if (!str) + return JS_FALSE; + argv[-1] = STRING_TO_JSVAL(str); + text = JSSTRING_CHARS(str); + textlen = (jsint) JSSTRING_LENGTH(str); + + str2 = js_ValueToString(cx, argv[0]); + if (!str2) + return JS_FALSE; + argv[0] = STRING_TO_JSVAL(str2); + pat = JSSTRING_CHARS(str2); + patlen = (jsint) JSSTRING_LENGTH(str2); + + if (argc > 1) { + if (!js_ValueToNumber(cx, argv[1], &d)) + return JS_FALSE; + if (JSDOUBLE_IS_NaN(d)) { + i = textlen; + } else { + d = js_DoubleToInteger(d); + if (d < 0) + i = 0; + else if (d > textlen - patlen) + i = textlen - patlen; + else + i = (jsint)d; + } + } else { + i = textlen; + } + + if (patlen == 0) { + *rval = INT_TO_JSVAL(i); + return JS_TRUE; + } + + j = 0; + while (i >= 0) { + /* Don't assume that text is NUL-terminated: it could be dependent. */ + if (i + j < textlen && text[i + j] == pat[j]) { + if (++j == patlen) + break; + } else { + i--; + j = 0; + } + } + *rval = INT_TO_JSVAL(i); + return JS_TRUE; +} + +/* + * Perl-inspired string functions. + */ +#if JS_HAS_REGEXPS +typedef struct GlobData { + uintN flags; /* inout: mode and flag bits, see below */ + uintN optarg; /* in: index of optional flags argument */ + JSString *str; /* out: 'this' parameter object as string */ + JSRegExp *regexp; /* out: regexp parameter object private data */ +} GlobData; + +/* + * Mode and flag bit definitions for match_or_replace's GlobData.flags field. + */ +#define MODE_MATCH 0x00 /* in: return match array on success */ +#define MODE_REPLACE 0x01 /* in: match and replace */ +#define MODE_SEARCH 0x02 /* in: search only, return match index or -1 */ +#define GET_MODE(f) ((f) & 0x03) +#define FORCE_FLAT 0x04 /* in: force flat (non-regexp) string match */ +#define KEEP_REGEXP 0x08 /* inout: keep GlobData.regexp alive for caller + of match_or_replace; if set on input + but clear on output, regexp ownership + does not pass to caller */ +#define GLOBAL_REGEXP 0x10 /* out: regexp had the 'g' flag */ + +static JSBool +match_or_replace(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + JSBool (*glob)(JSContext *cx, jsint count, GlobData *data), + GlobData *data, jsval *rval) +{ + JSString *str, *src, *opt; + JSObject *reobj; + JSRegExp *re; + size_t index, length; + JSBool ok, test; + jsint count; + + str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj)); + if (!str) + return JS_FALSE; + argv[-1] = STRING_TO_JSVAL(str); + data->str = str; + + if (JSVAL_IS_REGEXP(cx, argv[0])) { + reobj = JSVAL_TO_OBJECT(argv[0]); + re = (JSRegExp *) JS_GetPrivate(cx, reobj); + } else { + src = js_ValueToString(cx, argv[0]); + if (!src) + return JS_FALSE; + if (data->optarg < argc) { + argv[0] = STRING_TO_JSVAL(src); + opt = js_ValueToString(cx, argv[data->optarg]); + if (!opt) + return JS_FALSE; + } else { + opt = NULL; + } + re = js_NewRegExpOpt(cx, NULL, src, opt, + (data->flags & FORCE_FLAT) != 0); + if (!re) + return JS_FALSE; + reobj = NULL; + } + data->regexp = re; + + if (re->flags & JSREG_GLOB) + data->flags |= GLOBAL_REGEXP; + index = 0; + if (GET_MODE(data->flags) == MODE_SEARCH) { + ok = js_ExecuteRegExp(cx, re, str, &index, JS_TRUE, rval); + if (ok) { + *rval = (*rval == JSVAL_TRUE) + ? INT_TO_JSVAL(cx->regExpStatics.leftContext.length) + : INT_TO_JSVAL(-1); + } + } else if (data->flags & GLOBAL_REGEXP) { + if (reobj) { + /* Set the lastIndex property's reserved slot to 0. */ + ok = js_SetLastIndex(cx, reobj, 0); + if (!ok) + return JS_FALSE; + } else { + ok = JS_TRUE; + } + length = JSSTRING_LENGTH(str); + for (count = 0; index <= length; count++) { + ok = js_ExecuteRegExp(cx, re, str, &index, JS_TRUE, rval); + if (!ok || *rval != JSVAL_TRUE) + break; + ok = glob(cx, count, data); + if (!ok) + break; + if (cx->regExpStatics.lastMatch.length == 0) { + if (index == length) + break; + index++; + } + } + } else { + if (GET_MODE(data->flags) == MODE_REPLACE) { + test = JS_TRUE; + } else { + /* + * MODE_MATCH implies str_match is being called from a script or a + * scripted function. If the caller cares only about testing null + * vs. non-null return value, optimize away the array object that + * would normally be returned in *rval. + */ + JS_ASSERT(*cx->fp->down->pc == JSOP_CALL || + *cx->fp->down->pc == JSOP_NEW); + JS_ASSERT(js_CodeSpec[*cx->fp->down->pc].length == 3); + switch (cx->fp->down->pc[3]) { + case JSOP_POP: + case JSOP_IFEQ: + case JSOP_IFNE: + case JSOP_IFEQX: + case JSOP_IFNEX: + test = JS_TRUE; + break; + default: + test = JS_FALSE; + break; + } + } + ok = js_ExecuteRegExp(cx, re, str, &index, test, rval); + } + + if (reobj) { + /* Tell our caller that it doesn't need to destroy data->regexp. */ + data->flags &= ~KEEP_REGEXP; + } else if (!(data->flags & KEEP_REGEXP)) { + /* Caller didn't want to keep data->regexp, so null and destroy it. */ + data->regexp = NULL; + js_DestroyRegExp(cx, re); + } + return ok; +} + +typedef struct MatchData { + GlobData base; + jsval *arrayval; /* NB: local root pointer */ +} MatchData; + +static JSBool +match_glob(JSContext *cx, jsint count, GlobData *data) +{ + MatchData *mdata; + JSObject *arrayobj; + JSSubString *matchsub; + JSString *matchstr; + jsval v; + + mdata = (MatchData *)data; + arrayobj = JSVAL_TO_OBJECT(*mdata->arrayval); + if (!arrayobj) { + arrayobj = js_ConstructObject(cx, &js_ArrayClass, NULL, NULL, 0, NULL); + if (!arrayobj) + return JS_FALSE; + *mdata->arrayval = OBJECT_TO_JSVAL(arrayobj); + } + matchsub = &cx->regExpStatics.lastMatch; + matchstr = js_NewStringCopyN(cx, matchsub->chars, matchsub->length, 0); + if (!matchstr) + return JS_FALSE; + v = STRING_TO_JSVAL(matchstr); + return js_SetProperty(cx, arrayobj, INT_TO_JSVAL(count), &v); +} + +static JSBool +str_match(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + MatchData mdata; + JSBool ok; + + mdata.base.flags = MODE_MATCH; + mdata.base.optarg = 1; + mdata.arrayval = &argv[2]; + *mdata.arrayval = JSVAL_NULL; + ok = match_or_replace(cx, obj, argc, argv, match_glob, &mdata.base, rval); + if (ok && !JSVAL_IS_NULL(*mdata.arrayval)) + *rval = *mdata.arrayval; + return ok; +} + +static JSBool +str_search(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + GlobData data; + + data.flags = MODE_SEARCH; + data.optarg = 1; + return match_or_replace(cx, obj, argc, argv, NULL, &data, rval); +} + +typedef struct ReplaceData { + GlobData base; /* base struct state */ + JSObject *lambda; /* replacement function object or null */ + JSString *repstr; /* replacement string */ + jschar *dollar; /* null or pointer to first $ in repstr */ + jschar *dollarEnd; /* limit pointer for js_strchr_limit */ + jschar *chars; /* result chars, null initially */ + size_t length; /* result length, 0 initially */ + jsint index; /* index in result of next replacement */ + jsint leftIndex; /* left context index in base.str->chars */ + JSSubString dollarStr; /* for "$$" interpret_dollar result */ +} ReplaceData; + +static JSSubString * +interpret_dollar(JSContext *cx, jschar *dp, ReplaceData *rdata, size_t *skip) +{ + JSRegExpStatics *res; + jschar dc, *cp; + uintN num, tmp; + JSString *str; + + JS_ASSERT(*dp == '$'); + + /* + * Allow a real backslash (literal "\\" before "$1") to escape "$1", e.g. + * Do this only for versions strictly less than ECMAv3. + */ + if (cx->version != JSVERSION_DEFAULT && cx->version <= JSVERSION_1_4) { + if (dp > JSSTRING_CHARS(rdata->repstr) && dp[-1] == '\\') + return NULL; + } + + /* Interpret all Perl match-induced dollar variables. */ + res = &cx->regExpStatics; + dc = dp[1]; + if (JS7_ISDEC(dc)) { + if (cx->version != JSVERSION_DEFAULT && cx->version <= JSVERSION_1_4) { + if (dc == '0') + return NULL; + + /* Check for overflow to avoid gobbling arbitrary decimal digits. */ + num = 0; + cp = dp; + while ((dc = *++cp) != 0 && JS7_ISDEC(dc)) { + tmp = 10 * num + JS7_UNDEC(dc); + if (tmp < num) + break; + num = tmp; + } + } else { /* ECMA 3, 1-9 or 01-99 */ + num = JS7_UNDEC(dc); + if (num > res->parenCount) + return NULL; + cp = dp + 2; + dc = *cp; + if ((dc != 0) && JS7_ISDEC(dc)) { + tmp = 10 * num + JS7_UNDEC(dc); + if (tmp <= res->parenCount) { + cp++; + num = tmp; + } + } + if (num == 0) + return NULL; + } + /* Adjust num from 1 $n-origin to 0 array-index-origin. */ + num--; + *skip = cp - dp; + return REGEXP_PAREN_SUBSTRING(res, num); + } + + *skip = 2; + switch (dc) { + case '$': + rdata->dollarStr.chars = dp; + rdata->dollarStr.length = 1; + return &rdata->dollarStr; + case '&': + return &res->lastMatch; + case '+': + return &res->lastParen; + case '`': + if (cx->version == JSVERSION_1_2) { + /* + * JS1.2 imitated the Perl4 bug where left context at each step + * in an iterative use of a global regexp started from last match, + * not from the start of the target string. But Perl4 does start + * $` at the beginning of the target string when it is used in a + * substitution, so we emulate that special case here. + */ + str = rdata->base.str; + res->leftContext.chars = JSSTRING_CHARS(str); + res->leftContext.length = res->lastMatch.chars + - JSSTRING_CHARS(str); + } + return &res->leftContext; + case '\'': + return &res->rightContext; + } + return NULL; +} + +static JSBool +find_replen(JSContext *cx, ReplaceData *rdata, size_t *sizep) +{ + JSString *repstr; + size_t replen, skip; + jschar *dp, *ep; + JSSubString *sub; +#if JS_HAS_REPLACE_LAMBDA + JSObject *lambda; + + lambda = rdata->lambda; + if (lambda) { + uintN argc, i, j, m, n, p; + jsval *sp, *oldsp, rval; + void *mark; + JSStackFrame *fp; + JSBool ok; + + /* + * Save the rightContext from the current regexp, since it + * gets stuck at the end of the replacement string and may + * be clobbered by a RegExp usage in the lambda function. + */ + JSSubString saveRightContext = cx->regExpStatics.rightContext; + + /* + * In the lambda case, not only do we find the replacement string's + * length, we compute repstr and return it via rdata for use within + * do_replace. The lambda is called with arguments ($&, $1, $2, ..., + * index, input), i.e., all the properties of a regexp match array. + * For $&, etc., we must create string jsvals from cx->regExpStatics. + * We grab up stack space to keep the newborn strings GC-rooted. + */ + p = rdata->base.regexp->parenCount; + argc = 1 + p + 2; + sp = js_AllocStack(cx, 2 + argc, &mark); + if (!sp) + return JS_FALSE; + + /* Push lambda and its 'this' parameter. */ + *sp++ = OBJECT_TO_JSVAL(lambda); + *sp++ = OBJECT_TO_JSVAL(OBJ_GET_PARENT(cx, lambda)); + +#define PUSH_REGEXP_STATIC(sub) \ + JS_BEGIN_MACRO \ + JSString *str = js_NewStringCopyN(cx, \ + cx->regExpStatics.sub.chars, \ + cx->regExpStatics.sub.length, \ + 0); \ + if (!str) { \ + ok = JS_FALSE; \ + goto lambda_out; \ + } \ + *sp++ = STRING_TO_JSVAL(str); \ + JS_END_MACRO + + /* Push $&, $1, $2, ... */ + PUSH_REGEXP_STATIC(lastMatch); + i = 0; + m = cx->regExpStatics.parenCount; + n = JS_MIN(m, 9); + for (j = 0; i < n; i++, j++) + PUSH_REGEXP_STATIC(parens[j]); + for (j = 0; i < m; i++, j++) + PUSH_REGEXP_STATIC(moreParens[j]); + +#undef PUSH_REGEXP_STATIC + + /* Make sure to push undefined for any unmatched parens. */ + for (; i < p; i++) + *sp++ = JSVAL_VOID; + + /* Push match index and input string. */ + *sp++ = INT_TO_JSVAL((jsint)cx->regExpStatics.leftContext.length); + *sp++ = STRING_TO_JSVAL(rdata->base.str); + + /* Lift current frame to include the args and do the call. */ + fp = cx->fp; + oldsp = fp->sp; + fp->sp = sp; + ok = js_Invoke(cx, argc, JSINVOKE_INTERNAL); + rval = fp->sp[-1]; + fp->sp = oldsp; + + if (ok) { + /* + * NB: we count on the newborn string root to hold any string + * created by this js_ValueToString that would otherwise be GC- + * able, until we use rdata->repstr in do_replace. + */ + repstr = js_ValueToString(cx, rval); + if (!repstr) { + ok = JS_FALSE; + } else { + rdata->repstr = repstr; + *sizep = JSSTRING_LENGTH(repstr); + } + } + + lambda_out: + js_FreeStack(cx, mark); + cx->regExpStatics.rightContext = saveRightContext; + return ok; + } +#endif /* JS_HAS_REPLACE_LAMBDA */ + + repstr = rdata->repstr; + replen = JSSTRING_LENGTH(repstr); + for (dp = rdata->dollar, ep = rdata->dollarEnd; dp; + dp = js_strchr_limit(dp, '$', ep)) { + sub = interpret_dollar(cx, dp, rdata, &skip); + if (sub) { + replen += sub->length - skip; + dp += skip; + } + else + dp++; + } + *sizep = replen; + return JS_TRUE; +} + +static void +do_replace(JSContext *cx, ReplaceData *rdata, jschar *chars) +{ + JSString *repstr; + jschar *bp, *cp, *dp, *ep; + size_t len, skip; + JSSubString *sub; + + repstr = rdata->repstr; + bp = cp = JSSTRING_CHARS(repstr); + for (dp = rdata->dollar, ep = rdata->dollarEnd; dp; + dp = js_strchr_limit(dp, '$', ep)) { + len = dp - cp; + js_strncpy(chars, cp, len); + chars += len; + cp = dp; + sub = interpret_dollar(cx, dp, rdata, &skip); + if (sub) { + len = sub->length; + js_strncpy(chars, sub->chars, len); + chars += len; + cp += skip; + dp += skip; + } else { + dp++; + } + } + js_strncpy(chars, cp, JSSTRING_LENGTH(repstr) - (cp - bp)); +} + +static JSBool +replace_glob(JSContext *cx, jsint count, GlobData *data) +{ + ReplaceData *rdata; + JSString *str; + size_t leftoff, leftlen, replen, growth; + const jschar *left; + jschar *chars; + + rdata = (ReplaceData *)data; + str = data->str; + leftoff = rdata->leftIndex; + left = JSSTRING_CHARS(str) + leftoff; + leftlen = cx->regExpStatics.lastMatch.chars - left; + rdata->leftIndex = cx->regExpStatics.lastMatch.chars - JSSTRING_CHARS(str); + rdata->leftIndex += cx->regExpStatics.lastMatch.length; + if (!find_replen(cx, rdata, &replen)) + return JS_FALSE; + growth = leftlen + replen; + chars = (jschar *) + (rdata->chars + ? JS_realloc(cx, rdata->chars, (rdata->length + growth + 1) + * sizeof(jschar)) + : JS_malloc(cx, (growth + 1) * sizeof(jschar))); + if (!chars) { + JS_free(cx, rdata->chars); + rdata->chars = NULL; + return JS_FALSE; + } + rdata->chars = chars; + rdata->length += growth; + chars += rdata->index; + rdata->index += growth; + js_strncpy(chars, left, leftlen); + chars += leftlen; + do_replace(cx, rdata, chars); + return JS_TRUE; +} + +static JSBool +str_replace(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + JSObject *lambda; + JSString *repstr, *str; + ReplaceData rdata; + JSBool ok; + jschar *chars; + size_t leftlen, rightlen, length; + +#if JS_HAS_REPLACE_LAMBDA + if (JS_TypeOfValue(cx, argv[1]) == JSTYPE_FUNCTION) { + lambda = JSVAL_TO_OBJECT(argv[1]); + repstr = NULL; + } else +#endif + { + if (!JS_ConvertValue(cx, argv[1], JSTYPE_STRING, &argv[1])) + return JS_FALSE; + repstr = JSVAL_TO_STRING(argv[1]); + lambda = NULL; + } + + /* + * For ECMA Edition 3, the first argument is to be converted to a string + * to match in a "flat" sense (without regular expression metachars having + * special meanings) UNLESS the first arg is a RegExp object. + */ + rdata.base.flags = MODE_REPLACE | KEEP_REGEXP; + if (cx->version == JSVERSION_DEFAULT || cx->version > JSVERSION_1_4) + rdata.base.flags |= FORCE_FLAT; + rdata.base.optarg = 2; + + rdata.lambda = lambda; + rdata.repstr = repstr; + if (repstr) { + rdata.dollarEnd = JSSTRING_CHARS(repstr) + JSSTRING_LENGTH(repstr); + rdata.dollar = js_strchr_limit(JSSTRING_CHARS(repstr), '$', + rdata.dollarEnd); + } else { + rdata.dollar = rdata.dollarEnd = NULL; + } + rdata.chars = NULL; + rdata.length = 0; + rdata.index = 0; + rdata.leftIndex = 0; + + ok = match_or_replace(cx, obj, argc, argv, replace_glob, &rdata.base, rval); + if (!ok) + return JS_FALSE; + + if (!rdata.chars) { + if ((rdata.base.flags & GLOBAL_REGEXP) || *rval != JSVAL_TRUE) { + /* Didn't match even once. */ + *rval = STRING_TO_JSVAL(rdata.base.str); + goto out; + } + leftlen = cx->regExpStatics.leftContext.length; + ok = find_replen(cx, &rdata, &length); + if (!ok) + goto out; + length += leftlen; + chars = (jschar *) JS_malloc(cx, (length + 1) * sizeof(jschar)); + if (!chars) { + ok = JS_FALSE; + goto out; + } + js_strncpy(chars, cx->regExpStatics.leftContext.chars, leftlen); + do_replace(cx, &rdata, chars + leftlen); + rdata.chars = chars; + rdata.length = length; + } + + rightlen = cx->regExpStatics.rightContext.length; + length = rdata.length + rightlen; + chars = (jschar *) + JS_realloc(cx, rdata.chars, (length + 1) * sizeof(jschar)); + if (!chars) { + JS_free(cx, rdata.chars); + ok = JS_FALSE; + goto out; + } + js_strncpy(chars + rdata.length, cx->regExpStatics.rightContext.chars, + rightlen); + chars[length] = 0; + + str = js_NewString(cx, chars, length, 0); + if (!str) { + JS_free(cx, chars); + ok = JS_FALSE; + goto out; + } + *rval = STRING_TO_JSVAL(str); + +out: + /* If KEEP_REGEXP is still set, it's our job to destroy regexp now. */ + if (rdata.base.flags & KEEP_REGEXP) + js_DestroyRegExp(cx, rdata.base.regexp); + return ok; +} +#endif /* JS_HAS_REGEXPS */ + +/* + * Subroutine used by str_split to find the next split point in str, starting + * at offset *ip and looking either for the separator substring given by sep, + * or for the next re match. In the re case, return the matched separator in + * *sep, and the possibly updated offset in *ip. + * + * Return -2 on error, -1 on end of string, >= 0 for a valid index of the next + * separator occurrence if found, or str->length if no separator is found. + */ +static jsint +find_split(JSContext *cx, JSString *str, JSRegExp *re, jsint *ip, + JSSubString *sep) +{ + jsint i, j, k; + jschar *chars; + size_t length; + + /* + * Stop if past end of string. If at end of string, we will compare the + * null char stored there (by js_NewString*) to sep->chars[j] in the while + * loop at the end of this function, so that + * + * "ab,".split(',') => ["ab", ""] + * + * and the resulting array converts back to the string "ab," for symmetry. + * However, we ape Perl and do this only if there is a sufficiently large + * limit argument (see str_split). + */ + i = *ip; + if ((size_t)i > JSSTRING_LENGTH(str)) + return -1; + + /* + * Perl4 special case for str.split(' '), only if the user has selected + * JavaScript1.2 explicitly. Split on whitespace, and skip leading w/s. + * Strange but true, apparently modeled after awk. + * + * NB: we set sep->length to the length of the w/s run, so we must test + * sep->chars[1] == 0 to make sure sep is just one space. + */ + chars = JSSTRING_CHARS(str); + length = JSSTRING_LENGTH(str); + if (cx->version == JSVERSION_1_2 && + !re && *sep->chars == ' ' && sep->chars[1] == 0) { + + /* Skip leading whitespace if at front of str. */ + if (i == 0) { + while (JS_ISSPACE(chars[i])) + i++; + *ip = i; + } + + /* Don't delimit whitespace at end of string. */ + if ((size_t)i == length) + return -1; + + /* Skip over the non-whitespace chars. */ + while ((size_t)i < length && !JS_ISSPACE(chars[i])) + i++; + + /* Now skip the next run of whitespace. */ + j = i; + while ((size_t)j < length && JS_ISSPACE(chars[j])) + j++; + + /* Update sep->length to count delimiter chars. */ + sep->length = (size_t)(j - i); + return i; + } + +#if JS_HAS_REGEXPS + /* + * Match a regular expression against the separator at or above index i. + * Call js_ExecuteRegExp with true for the test argument. On successful + * match, get the separator from cx->regExpStatics.lastMatch. + */ + if (re) { + size_t index; + jsval rval; + + again: + /* JS1.2 deviated from Perl by never matching at end of string. */ + index = (size_t)i; + if (!js_ExecuteRegExp(cx, re, str, &index, JS_TRUE, &rval)) + return -2; + if (rval != JSVAL_TRUE) { + /* Mismatch: ensure our caller advances i past end of string. */ + sep->length = 1; + return length; + } + i = (jsint)index; + *sep = cx->regExpStatics.lastMatch; + if (sep->length == 0) { + /* + * Empty string match: never split on an empty match at the start + * of a find_split cycle. Same rule as for an empty global match + * in match_or_replace. + */ + if (i == *ip) { + /* + * "Bump-along" to avoid sticking at an empty match, but don't + * bump past end of string -- our caller must do that by adding + * sep->length to our return value. + */ + if ((size_t)i == length) { + if (cx->version == JSVERSION_1_2) { + sep->length = 1; + return i; + } + return -1; + } + i++; + goto again; + } + } + JS_ASSERT((size_t)i >= sep->length); + return i - sep->length; + } +#endif /* JS_HAS_REGEXPS */ + + /* + * Deviate from ECMA by never splitting an empty string by any separator + * string into a non-empty array (an array of length 1 that contains the + * empty string). + */ + if (!JSVERSION_IS_ECMA(cx->version) && length == 0) + return -1; + + /* + * Special case: if sep is the empty string, split str into one character + * substrings. Let our caller worry about whether to split once at end of + * string into an empty substring. + * + * For 1.2 compatibility, at the end of the string, we return the length as + * the result, and set the separator length to 1 -- this allows the caller + * to include an additional null string at the end of the substring list. + */ + if (sep->length == 0) { + if (cx->version == JSVERSION_1_2) { + if ((size_t)i == length) { + sep->length = 1; + return i; + } + return i + 1; + } + return ((size_t)i == length) ? -1 : i + 1; + } + + /* + * Now that we know sep is non-empty, search starting at i in str for an + * occurrence of all of sep's chars. If we find them, return the index of + * the first separator char. Otherwise, return length. + */ + j = 0; + while ((size_t)(k = i + j) < length) { + if (chars[k] == sep->chars[j]) { + if ((size_t)++j == sep->length) + return i; + } else { + i++; + j = 0; + } + } + return k; +} + +static JSBool +str_split(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + JSString *str, *sub; + JSObject *arrayobj; + jsval v; + JSBool ok, limited; + JSRegExp *re; + JSSubString *sep, tmp; + jsdouble d; + jsint i, j; + uint32 len, limit; + + str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj)); + if (!str) + return JS_FALSE; + argv[-1] = STRING_TO_JSVAL(str); + + arrayobj = js_ConstructObject(cx, &js_ArrayClass, NULL, NULL, 0, NULL); + if (!arrayobj) + return JS_FALSE; + *rval = OBJECT_TO_JSVAL(arrayobj); + + if (argc == 0) { + v = STRING_TO_JSVAL(str); + ok = JS_SetElement(cx, arrayobj, 0, &v); + } else { +#if JS_HAS_REGEXPS + if (JSVAL_IS_REGEXP(cx, argv[0])) { + re = (JSRegExp *) JS_GetPrivate(cx, JSVAL_TO_OBJECT(argv[0])); + sep = &tmp; + + /* Set a magic value so we can detect a successful re match. */ + sep->chars = NULL; + } else +#endif + { + JSString *str2 = js_ValueToString(cx, argv[0]); + if (!str2) + return JS_FALSE; + argv[0] = STRING_TO_JSVAL(str2); + + /* + * Point sep at a local copy of str2's header because find_split + * will modify sep->length. + */ + tmp.length = JSSTRING_LENGTH(str2); + tmp.chars = JSSTRING_CHARS(str2); + sep = &tmp; + re = NULL; + } + + /* Use the second argument as the split limit, if given. */ + limited = (argc > 1) && !JSVAL_IS_VOID(argv[1]); + limit = 0; /* Avoid warning. */ + if (limited) { + if (!js_ValueToNumber(cx, argv[1], &d)) + return JS_FALSE; + + /* Clamp limit between 0 and 1 + string length. */ + if (!js_DoubleToECMAUint32(cx, d, &limit)) + return JS_FALSE; + if (limit > JSSTRING_LENGTH(str)) + limit = 1 + JSSTRING_LENGTH(str); + } + + len = i = 0; + while ((j = find_split(cx, str, re, &i, sep)) >= 0) { + if (limited && len >= limit) + break; + sub = js_NewDependentString(cx, str, i, (size_t)(j - i), 0); + if (!sub) + return JS_FALSE; + v = STRING_TO_JSVAL(sub); + if (!JS_SetElement(cx, arrayobj, len, &v)) + return JS_FALSE; + len++; +#if JS_HAS_REGEXPS + /* + * Imitate perl's feature of including parenthesized substrings + * that matched part of the delimiter in the new array, after the + * split substring that was delimited. + */ + if (re && sep->chars) { + uintN num; + JSSubString *parsub; + + for (num = 0; num < cx->regExpStatics.parenCount; num++) { + if (limited && len >= limit) + break; + parsub = REGEXP_PAREN_SUBSTRING(&cx->regExpStatics, num); + sub = js_NewStringCopyN(cx, parsub->chars, parsub->length, + 0); + if (!sub) + return JS_FALSE; + v = STRING_TO_JSVAL(sub); + if (!JS_SetElement(cx, arrayobj, len, &v)) + return JS_FALSE; + len++; + } + sep->chars = NULL; + } +#endif + i = j + sep->length; + if (!JSVERSION_IS_ECMA(cx->version)) { + /* + * Deviate from ECMA to imitate Perl, which omits a final + * split unless a limit argument is given and big enough. + */ + if (!limited && (size_t)i == JSSTRING_LENGTH(str)) + break; + } + } + ok = (j != -2); + } + return ok; +} + +#if JS_HAS_PERL_SUBSTR +static JSBool +str_substr(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + JSString *str; + jsdouble d; + jsdouble length, begin, end; + + str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj)); + if (!str) + return JS_FALSE; + + if (argc != 0) { + if (!js_ValueToNumber(cx, argv[0], &d)) + return JS_FALSE; + length = JSSTRING_LENGTH(str); + begin = js_DoubleToInteger(d); + if (begin < 0) { + begin += length; + if (begin < 0) + begin = 0; + } else if (begin > length) { + begin = length; + } + + if (argc == 1) { + end = length; + } else { + if (!js_ValueToNumber(cx, argv[1], &d)) + return JS_FALSE; + end = js_DoubleToInteger(d); + if (end < 0) + end = 0; + end += begin; + if (end > length) + end = length; + } + + str = js_NewDependentString(cx, str, (size_t)begin, + (size_t)(end - begin), 0); + if (!str) + return JS_FALSE; + } + *rval = STRING_TO_JSVAL(str); + return JS_TRUE; +} +#endif /* JS_HAS_PERL_SUBSTR */ + +#if JS_HAS_SEQUENCE_OPS +/* + * Python-esque sequence operations. + */ +static JSBool +str_concat(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + JSString *str, *str2; + uintN i; + + str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj)); + if (!str) + return JS_FALSE; + argv[-1] = STRING_TO_JSVAL(str); + + for (i = 0; i < argc; i++) { + str2 = js_ValueToString(cx, argv[i]); + if (!str2) + return JS_FALSE; + argv[i] = STRING_TO_JSVAL(str2); + + str = js_ConcatStrings(cx, str, str2); + if (!str) + return JS_FALSE; + } + + *rval = STRING_TO_JSVAL(str); + return JS_TRUE; +} + +static JSBool +str_slice(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + JSString *str; + jsdouble d; + jsdouble length, begin, end; + + str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj)); + if (!str) + return JS_FALSE; + argv[-1] = STRING_TO_JSVAL(str); + + if (argc != 0) { + if (!js_ValueToNumber(cx, argv[0], &d)) + return JS_FALSE; + length = JSSTRING_LENGTH(str); + begin = js_DoubleToInteger(d); + if (begin < 0) { + begin += length; + if (begin < 0) + begin = 0; + } else if (begin > length) { + begin = length; + } + + if (argc == 1) { + end = length; + } else { + if (!js_ValueToNumber(cx, argv[1], &d)) + return JS_FALSE; + end = js_DoubleToInteger(d); + if (end < 0) { + end += length; + if (end < 0) + end = 0; + } else if (end > length) { + end = length; + } + if (end < begin) + end = begin; + } + + str = js_NewDependentString(cx, str, (size_t)begin, + (size_t)(end - begin), 0); + if (!str) + return JS_FALSE; + } + *rval = STRING_TO_JSVAL(str); + return JS_TRUE; +} +#endif /* JS_HAS_SEQUENCE_OPS */ + +#if JS_HAS_STR_HTML_HELPERS +/* + * HTML composition aids. + */ +static JSBool +tagify(JSContext *cx, JSObject *obj, jsval *argv, + const char *begin, const jschar *param, const char *end, + jsval *rval) +{ + JSString *str; + jschar *tagbuf; + size_t beglen, endlen, parlen, taglen; + size_t i, j; + + str = js_ValueToString(cx, OBJECT_TO_JSVAL(obj)); + if (!str) + return JS_FALSE; + argv[-1] = STRING_TO_JSVAL(str); + + if (!end) + end = begin; + + beglen = strlen(begin); + taglen = 1 + beglen + 1; /* '' */ + parlen = 0; /* Avoid warning. */ + if (param) { + parlen = js_strlen(param); + taglen += 2 + parlen + 1; /* '="param"' */ + } + endlen = strlen(end); + taglen += JSSTRING_LENGTH(str) + 2 + endlen + 1; /* 'str' */ + + tagbuf = (jschar *) JS_malloc(cx, (taglen + 1) * sizeof(jschar)); + if (!tagbuf) + return JS_FALSE; + + j = 0; + tagbuf[j++] = '<'; + for (i = 0; i < beglen; i++) + tagbuf[j++] = (jschar)begin[i]; + if (param) { + tagbuf[j++] = '='; + tagbuf[j++] = '"'; + js_strncpy(&tagbuf[j], param, parlen); + j += parlen; + tagbuf[j++] = '"'; + } + tagbuf[j++] = '>'; + js_strncpy(&tagbuf[j], JSSTRING_CHARS(str), JSSTRING_LENGTH(str)); + j += JSSTRING_LENGTH(str); + tagbuf[j++] = '<'; + tagbuf[j++] = '/'; + for (i = 0; i < endlen; i++) + tagbuf[j++] = (jschar)end[i]; + tagbuf[j++] = '>'; + JS_ASSERT(j == taglen); + tagbuf[j] = 0; + + str = js_NewString(cx, tagbuf, taglen, 0); + if (!str) { + free((char *)tagbuf); + return JS_FALSE; + } + *rval = STRING_TO_JSVAL(str); + return JS_TRUE; +} + +static JSBool +tagify_value(JSContext *cx, JSObject *obj, jsval *argv, + const char *begin, const char *end, + jsval *rval) +{ + JSString *param; + + param = js_ValueToString(cx, argv[0]); + if (!param) + return JS_FALSE; + argv[0] = STRING_TO_JSVAL(param); + return tagify(cx, obj, argv, begin, JSSTRING_CHARS(param), end, rval); +} + +static JSBool +str_bold(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + return tagify(cx, obj, argv, "b", NULL, NULL, rval); +} + +static JSBool +str_italics(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + return tagify(cx, obj, argv, "i", NULL, NULL, rval); +} + +static JSBool +str_fixed(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + return tagify(cx, obj, argv, "tt", NULL, NULL, rval); +} + +static JSBool +str_fontsize(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + return tagify_value(cx, obj, argv, "font size", "font", rval); +} + +static JSBool +str_fontcolor(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval) +{ + return tagify_value(cx, obj, argv, "font color", "font", rval); +} + +static JSBool +str_link(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + return tagify_value(cx, obj, argv, "a href", "a", rval); +} + +static JSBool +str_anchor(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + return tagify_value(cx, obj, argv, "a name", "a", rval); +} + +static JSBool +str_strike(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + return tagify(cx, obj, argv, "strike", NULL, NULL, rval); +} + +static JSBool +str_small(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + return tagify(cx, obj, argv, "small", NULL, NULL, rval); +} + +static JSBool +str_big(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + return tagify(cx, obj, argv, "big", NULL, NULL, rval); +} + +static JSBool +str_blink(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + return tagify(cx, obj, argv, "blink", NULL, NULL, rval); +} + +static JSBool +str_sup(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + return tagify(cx, obj, argv, "sup", NULL, NULL, rval); +} + +static JSBool +str_sub(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + return tagify(cx, obj, argv, "sub", NULL, NULL, rval); +} +#endif /* JS_HAS_STR_HTML_HELPERS */ + +static JSFunctionSpec string_methods[] = { +#if JS_HAS_TOSOURCE + {"quote", str_quote, 0,0,0}, + {js_toSource_str, str_toSource, 0,0,0}, +#endif + + /* Java-like methods. */ + {js_toString_str, str_toString, 0,0,0}, + {js_valueOf_str, str_valueOf, 0,0,0}, + {"substring", str_substring, 2,0,0}, + {"toLowerCase", str_toLowerCase, 0,0,0}, + {"toUpperCase", str_toUpperCase, 0,0,0}, + {"charAt", str_charAt, 1,0,0}, + {"charCodeAt", str_charCodeAt, 1,0,0}, + {"indexOf", str_indexOf, 1,0,0}, + {"lastIndexOf", str_lastIndexOf, 1,0,0}, + {"toLocaleLowerCase", str_toLocaleLowerCase, 0,0,0}, + {"toLocaleUpperCase", str_toLocaleUpperCase, 0,0,0}, + {"localeCompare", str_localeCompare, 1,0,0}, + + /* Perl-ish methods (search is actually Python-esque). */ +#if JS_HAS_REGEXPS + {"match", str_match, 1,0,2}, + {"search", str_search, 1,0,0}, + {"replace", str_replace, 2,0,0}, + {"split", str_split, 2,0,0}, +#endif +#if JS_HAS_PERL_SUBSTR + {"substr", str_substr, 2,0,0}, +#endif + + /* Python-esque sequence methods. */ +#if JS_HAS_SEQUENCE_OPS + {"concat", str_concat, 0,0,0}, + {"slice", str_slice, 0,0,0}, +#endif + + /* HTML string methods. */ +#if JS_HAS_STR_HTML_HELPERS + {"bold", str_bold, 0,0,0}, + {"italics", str_italics, 0,0,0}, + {"fixed", str_fixed, 0,0,0}, + {"fontsize", str_fontsize, 1,0,0}, + {"fontcolor", str_fontcolor, 1,0,0}, + {"link", str_link, 1,0,0}, + {"anchor", str_anchor, 1,0,0}, + {"strike", str_strike, 0,0,0}, + {"small", str_small, 0,0,0}, + {"big", str_big, 0,0,0}, + {"blink", str_blink, 0,0,0}, + {"sup", str_sup, 0,0,0}, + {"sub", str_sub, 0,0,0}, +#endif + + {0,0,0,0,0} +}; + +static JSBool +String(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + JSString *str; + + if (argc > 0) { + str = js_ValueToString(cx, argv[0]); + if (!str) + return JS_FALSE; + } else { + str = cx->runtime->emptyString; + } + if (!(cx->fp->flags & JSFRAME_CONSTRUCTING)) { + *rval = STRING_TO_JSVAL(str); + return JS_TRUE; + } + OBJ_SET_SLOT(cx, obj, JSSLOT_PRIVATE, STRING_TO_JSVAL(str)); + return JS_TRUE; +} + +static JSBool +str_fromCharCode(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval) +{ + jschar *chars; + uintN i; + uint16 code; + JSString *str; + + chars = (jschar *) JS_malloc(cx, (argc + 1) * sizeof(jschar)); + if (!chars) + return JS_FALSE; + for (i = 0; i < argc; i++) { + if (!js_ValueToUint16(cx, argv[i], &code)) { + JS_free(cx, chars); + return JS_FALSE; + } + chars[i] = (jschar)code; + } + chars[i] = 0; + str = js_NewString(cx, chars, argc, 0); + if (!str) { + JS_free(cx, chars); + return JS_FALSE; + } + *rval = STRING_TO_JSVAL(str); + return JS_TRUE; +} + +static JSFunctionSpec string_static_methods[] = { + {"fromCharCode", str_fromCharCode, 1,0,0}, + {0,0,0,0,0} +}; + +static JSHashTable *deflated_string_cache; +#ifdef DEBUG +static uint32 deflated_string_cache_bytes; +#endif +#ifdef JS_THREADSAFE +static JSLock *deflated_string_cache_lock; +#endif + +JSBool +js_InitStringGlobals(void) +{ +#ifdef JS_THREADSAFE + /* Must come through here once in primordial thread to init safely! */ + if (!deflated_string_cache_lock) { + deflated_string_cache_lock = JS_NEW_LOCK(); + if (!deflated_string_cache_lock) + return JS_FALSE; + } +#endif + return JS_TRUE; +} + +void +js_FreeStringGlobals() +{ + if (deflated_string_cache) { + JS_HashTableDestroy(deflated_string_cache); + deflated_string_cache = NULL; + } +#ifdef JS_THREADSAFE + if (deflated_string_cache_lock) { + JS_DESTROY_LOCK(deflated_string_cache_lock); + deflated_string_cache_lock = NULL; + } +#endif +} + +JSBool +js_InitRuntimeStringState(JSContext *cx) +{ + JSRuntime *rt; + JSString *empty; + + rt = cx->runtime; + JS_ASSERT(!rt->emptyString); + + /* Make a permanently locked empty string. */ + empty = js_NewStringCopyN(cx, js_empty_ucstr, 0, GCF_LOCK); + if (!empty) + return JS_FALSE; + + /* Atomize it for scripts that use '' + x to convert x to string. */ + if (!js_AtomizeString(cx, empty, ATOM_PINNED)) + return JS_FALSE; + + rt->emptyString = empty; + return JS_TRUE; +} + +void +js_FinishRuntimeStringState(JSContext *cx) +{ + JSRuntime *rt = cx->runtime; + + js_UnlockGCThingRT(rt, rt->emptyString); + rt->emptyString = NULL; +} + +JSObject * +js_InitStringClass(JSContext *cx, JSObject *obj) +{ + JSObject *proto; + + /* Define the escape, unescape functions in the global object. */ + if (!JS_DefineFunctions(cx, obj, string_functions)) + return NULL; + + proto = JS_InitClass(cx, obj, NULL, &string_class, String, 1, + string_props, string_methods, + NULL, string_static_methods); + if (!proto) + return NULL; + OBJ_SET_SLOT(cx, proto, JSSLOT_PRIVATE, + STRING_TO_JSVAL(cx->runtime->emptyString)); + return proto; +} + +JSString * +js_NewString(JSContext *cx, jschar *chars, size_t length, uintN gcflag) +{ + JSString *str; + + if (length > JSSTRING_LENGTH_MASK) { + JS_ReportOutOfMemory(cx); + return NULL; + } + + str = (JSString *) js_AllocGCThing(cx, gcflag | GCX_STRING); + if (!str) + return NULL; + str->length = length; + str->chars = chars; +#ifdef DEBUG + { + JSRuntime *rt = cx->runtime; + JS_RUNTIME_METER(rt, liveStrings); + JS_RUNTIME_METER(rt, totalStrings); + JS_LOCK_RUNTIME_VOID(rt, + (rt->lengthSum += (double)length, + rt->lengthSquaredSum += (double)length * (double)length)); + } +#endif + return str; +} + +JSString * +js_NewDependentString(JSContext *cx, JSString *base, size_t start, + size_t length, uintN gcflag) +{ + JSDependentString *ds; + + if (length == 0) + return cx->runtime->emptyString; + + if (start > JSSTRDEP_START_MASK || + (start != 0 && length > JSSTRDEP_LENGTH_MASK)) { + return js_NewStringCopyN(cx, JSSTRING_CHARS(base) + start, length, + gcflag); + } + + ds = (JSDependentString *) js_AllocGCThing(cx, gcflag | GCX_MUTABLE_STRING); + if (!ds) + return NULL; + if (start == 0) { + JSPREFIX_SET_LENGTH(ds, length); + JSPREFIX_SET_BASE(ds, base); + } else { + JSSTRDEP_SET_START_AND_LENGTH(ds, start, length); + JSSTRDEP_SET_BASE(ds, base); + } +#ifdef DEBUG + { + JSRuntime *rt = cx->runtime; + JS_RUNTIME_METER(rt, liveDependentStrings); + JS_RUNTIME_METER(rt, totalDependentStrings); + JS_RUNTIME_METER(rt, liveStrings); + JS_RUNTIME_METER(rt, totalStrings); + JS_LOCK_RUNTIME_VOID(rt, + (rt->strdepLengthSum += (double)length, + rt->strdepLengthSquaredSum += (double)length * (double)length)); + JS_LOCK_RUNTIME_VOID(rt, + (rt->lengthSum += (double)length, + rt->lengthSquaredSum += (double)length * (double)length)); + } +#endif + return (JSString *)ds; +} + +#ifdef DEBUG +#include + +void printJSStringStats(JSRuntime *rt) { + double mean = 0., var = 0., sigma = 0.; + jsrefcount count = rt->totalStrings; + if (count > 0 && rt->lengthSum >= 0) { + mean = rt->lengthSum / count; + var = count * rt->lengthSquaredSum - rt->lengthSum * rt->lengthSum; + if (var < 0.0 || count <= 1) + var = 0.0; + else + var /= count * (count - 1); + + /* Windows says sqrt(0.0) is "-1.#J" (?!) so we must test. */ + sigma = (var != 0.) ? sqrt(var) : 0.; + } + fprintf(stderr, "%lu total strings, mean length %g (sigma %g)\n", + (unsigned long)count, mean, sigma); + + mean = var = sigma = 0.; + count = rt->totalDependentStrings; + if (count > 0 && rt->strdepLengthSum >= 0) { + mean = rt->strdepLengthSum / count; + var = count * rt->strdepLengthSquaredSum + - rt->strdepLengthSum * rt->strdepLengthSum; + if (var < 0.0 || count <= 1) + var = 0.0; + else + var /= count * (count - 1); + + /* Windows says sqrt(0.0) is "-1.#J" (?!) so we must test. */ + sigma = (var != 0.) ? sqrt(var) : 0.; + } + fprintf(stderr, "%lu total dependent strings, mean length %g (sigma %g)\n", + (unsigned long)count, mean, sigma); +} +#endif + +JSString * +js_NewStringCopyN(JSContext *cx, const jschar *s, size_t n, uintN gcflag) +{ + jschar *news; + JSString *str; + + news = (jschar *)JS_malloc(cx, (n + 1) * sizeof(jschar)); + if (!news) + return NULL; + js_strncpy(news, s, n); + news[n] = 0; + str = js_NewString(cx, news, n, gcflag); + if (!str) + JS_free(cx, news); + return str; +} + +JSString * +js_NewStringCopyZ(JSContext *cx, const jschar *s, uintN gcflag) +{ + size_t n, m; + jschar *news; + JSString *str; + + n = js_strlen(s); + m = (n + 1) * sizeof(jschar); + news = (jschar *) JS_malloc(cx, m); + if (!news) + return NULL; + memcpy(news, s, m); + str = js_NewString(cx, news, n, gcflag); + if (!str) + JS_free(cx, news); + return str; +} + +JS_STATIC_DLL_CALLBACK(JSHashNumber) +js_hash_string_pointer(const void *key) +{ + return (JSHashNumber)key >> JSVAL_TAGBITS; +} + +void +js_PurgeDeflatedStringCache(JSString *str) +{ + JSHashNumber hash; + JSHashEntry *he, **hep; + + if (!deflated_string_cache) + return; + + hash = js_hash_string_pointer(str); + JS_ACQUIRE_LOCK(deflated_string_cache_lock); + hep = JS_HashTableRawLookup(deflated_string_cache, hash, str); + he = *hep; + if (he) { +#ifdef DEBUG + deflated_string_cache_bytes -= JSSTRING_LENGTH(str); +#endif + free(he->value); + JS_HashTableRawRemove(deflated_string_cache, hep, he); + } + JS_RELEASE_LOCK(deflated_string_cache_lock); +} + +void +js_FinalizeString(JSContext *cx, JSString *str) +{ + js_FinalizeStringRT(cx->runtime, str); +} + +void +js_FinalizeStringRT(JSRuntime *rt, JSString *str) +{ + JSBool valid; + + JS_RUNTIME_UNMETER(rt, liveStrings); + if (JSSTRING_IS_DEPENDENT(str)) { + /* If JSSTRFLAG_DEPENDENT is set, this string must be valid. */ + JS_ASSERT(JSSTRDEP_BASE(str)); + JS_RUNTIME_UNMETER(rt, liveDependentStrings); + valid = JS_TRUE; + } else { + /* A stillborn string has null chars, so is not valid. */ + valid = (str->chars != NULL); + if (valid) + free(str->chars); + } + if (valid) { + js_PurgeDeflatedStringCache(str); + str->chars = NULL; + } + str->length = 0; +} + +JSObject * +js_StringToObject(JSContext *cx, JSString *str) +{ + JSObject *obj; + + obj = js_NewObject(cx, &string_class, NULL, NULL); + if (!obj) + return NULL; + OBJ_SET_SLOT(cx, obj, JSSLOT_PRIVATE, STRING_TO_JSVAL(str)); + return obj; +} + +JSString * +js_ValueToString(JSContext *cx, jsval v) +{ + JSObject *obj; + JSString *str; + + if (JSVAL_IS_OBJECT(v)) { + obj = JSVAL_TO_OBJECT(v); + if (!obj) + return ATOM_TO_STRING(cx->runtime->atomState.nullAtom); + if (!OBJ_DEFAULT_VALUE(cx, obj, JSTYPE_STRING, &v)) + return NULL; + } + if (JSVAL_IS_STRING(v)) { + str = JSVAL_TO_STRING(v); + } else if (JSVAL_IS_INT(v)) { + str = js_NumberToString(cx, JSVAL_TO_INT(v)); + } else if (JSVAL_IS_DOUBLE(v)) { + str = js_NumberToString(cx, *JSVAL_TO_DOUBLE(v)); + } else if (JSVAL_IS_BOOLEAN(v)) { + str = js_BooleanToString(cx, JSVAL_TO_BOOLEAN(v)); + } else { + str = ATOM_TO_STRING(cx->runtime->atomState.typeAtoms[JSTYPE_VOID]); + } + return str; +} + +JSString * +js_ValueToSource(JSContext *cx, jsval v) +{ + if (JSVAL_IS_STRING(v)) + return js_QuoteString(cx, JSVAL_TO_STRING(v), '"'); + if (JSVAL_IS_PRIMITIVE(v)) { + /* Special case to preserve negative zero, _contra_ toString. */ + if (JSVAL_IS_DOUBLE(v) && JSDOUBLE_IS_NEGZERO(*JSVAL_TO_DOUBLE(v))) { + /* NB: _ucNstr rather than _ucstr to indicate non-terminated. */ + static const jschar js_negzero_ucNstr[] = {'-', '0'}; + + return js_NewStringCopyN(cx, js_negzero_ucNstr, 2, 0); + } + } else { + if (!js_TryMethod(cx, JSVAL_TO_OBJECT(v), + cx->runtime->atomState.toSourceAtom, + 0, NULL, &v)) { + return NULL; + } + } + return js_ValueToString(cx, v); +} + +JSHashNumber +js_HashString(JSString *str) +{ + JSHashNumber h; + const jschar *s; + size_t n; + + h = 0; + for (s = JSSTRING_CHARS(str), n = JSSTRING_LENGTH(str); n; s++, n--) + h = (h >> (JS_HASH_BITS - 4)) ^ (h << 4) ^ *s; + return h; +} + +intN +js_CompareStrings(JSString *str1, JSString *str2) +{ + size_t l1, l2, n, i; + const jschar *s1, *s2; + intN cmp; + + l1 = JSSTRING_LENGTH(str1), l2 = JSSTRING_LENGTH(str2); + s1 = JSSTRING_CHARS(str1), s2 = JSSTRING_CHARS(str2); + n = JS_MIN(l1, l2); + for (i = 0; i < n; i++) { + cmp = s1[i] - s2[i]; + if (cmp != 0) + return cmp; + } + return (intN)(l1 - l2); +} + +size_t +js_strlen(const jschar *s) +{ + const jschar *t; + + for (t = s; *t != 0; t++) + continue; + return (size_t)(t - s); +} + +jschar * +js_strchr(const jschar *s, jschar c) +{ + while (*s != 0) { + if (*s == c) + return (jschar *)s; + s++; + } + return NULL; +} + +jschar * +js_strchr_limit(const jschar *s, jschar c, const jschar *limit) +{ + while (s < limit) { + if (*s == c) + return (jschar *)s; + s++; + } + return NULL; +} + +const jschar * +js_SkipWhiteSpace(const jschar *s) +{ + /* JS_ISSPACE is false on a null. */ + while (JS_ISSPACE(*s)) + s++; + return s; +} + +#define INFLATE_STRING_BODY \ + for (i = 0; i < length; i++) \ + chars[i] = (unsigned char) bytes[i]; \ + chars[i] = 0; + +void +js_InflateStringToBuffer(jschar *chars, const char *bytes, size_t length) +{ + size_t i; + + INFLATE_STRING_BODY +} + +jschar * +js_InflateString(JSContext *cx, const char *bytes, size_t length) +{ + jschar *chars; + size_t i; + + chars = (jschar *) JS_malloc(cx, (length + 1) * sizeof(jschar)); + if (!chars) + return NULL; + + INFLATE_STRING_BODY + + return chars; +} + +/* + * May be called with null cx by js_GetStringBytes, see below. + */ +char * +js_DeflateString(JSContext *cx, const jschar *chars, size_t length) +{ + size_t i, size; + char *bytes; + + size = (length + 1) * sizeof(char); + bytes = (char *) (cx ? JS_malloc(cx, size) : malloc(size)); + if (!bytes) + return NULL; + for (i = 0; i < length; i++) + bytes[i] = (char) chars[i]; + bytes[i] = 0; + return bytes; +} + +static JSHashTable * +GetDeflatedStringCache(void) +{ + JSHashTable *cache; + + cache = deflated_string_cache; + if (!cache) { + cache = JS_NewHashTable(8, js_hash_string_pointer, + JS_CompareValues, JS_CompareValues, + NULL, NULL); + deflated_string_cache = cache; + } + return cache; +} + +JSBool +js_SetStringBytes(JSString *str, char *bytes, size_t length) +{ + JSHashTable *cache; + JSBool ok; + JSHashNumber hash; + JSHashEntry **hep; + + JS_ACQUIRE_LOCK(deflated_string_cache_lock); + + cache = GetDeflatedStringCache(); + if (!cache) { + ok = JS_FALSE; + } else { + hash = js_hash_string_pointer(str); + hep = JS_HashTableRawLookup(cache, hash, str); + JS_ASSERT(*hep == NULL); + ok = JS_HashTableRawAdd(cache, hep, hash, str, bytes) != NULL; +#ifdef DEBUG + if (ok) + deflated_string_cache_bytes += length; +#endif + } + + JS_RELEASE_LOCK(deflated_string_cache_lock); + return ok; +} + +char * +js_GetStringBytes(JSString *str) +{ + JSHashTable *cache; + char *bytes; + JSHashNumber hash; + JSHashEntry *he, **hep; + + JS_ACQUIRE_LOCK(deflated_string_cache_lock); + + cache = GetDeflatedStringCache(); + if (!cache) { + bytes = NULL; + } else { + hash = js_hash_string_pointer(str); + hep = JS_HashTableRawLookup(cache, hash, str); + he = *hep; + if (he) { + bytes = (char *) he->value; + + /* Try to catch failure to JS_ShutDown between runtime epochs. */ + JS_ASSERT((*bytes == '\0' && JSSTRING_LENGTH(str) == 0) || + *bytes == (char) JSSTRING_CHARS(str)[0]); + } else { + bytes = js_DeflateString(NULL, JSSTRING_CHARS(str), + JSSTRING_LENGTH(str)); + if (bytes) { + if (JS_HashTableRawAdd(cache, hep, hash, str, bytes)) { +#ifdef DEBUG + deflated_string_cache_bytes += JSSTRING_LENGTH(str); +#endif + } else { + free(bytes); + bytes = NULL; + } + } + } + } + + JS_RELEASE_LOCK(deflated_string_cache_lock); + return bytes; +} + +/* + * From java.lang.Character.java: + * + * The character properties are currently encoded into 32 bits in the + * following manner: + * + * 10 bits signed offset used for converting case + * 1 bit if 1, adding the signed offset converts the character to + * lowercase + * 1 bit if 1, subtracting the signed offset converts the character to + * uppercase + * 1 bit if 1, character has a titlecase equivalent (possibly itself) + * 3 bits 0 may not be part of an identifier + * 1 ignorable control; may continue a Unicode identifier or JS + * identifier + * 2 may continue a JS identifier but not a Unicode identifier + * (unused) + * 3 may continue a Unicode identifier or JS identifier + * 4 is a JS whitespace character + * 5 may start or continue a JS identifier; + * may continue but not start a Unicode identifier (_) + * 6 may start or continue a JS identifier but not a Unicode + * identifier ($) + * 7 may start or continue a Unicode identifier or JS identifier + * Thus: + * 5, 6, 7 may start a JS identifier + * 1, 2, 3, 5, 6, 7 may continue a JS identifier + * 7 may start a Unicode identifier + * 1, 3, 5, 7 may continue a Unicode identifier + * 1 is ignorable within an identifier + * 4 is JS whitespace + * 2 bits 0 this character has no numeric property + * 1 adding the digit offset to the character code and then + * masking with 0x1F will produce the desired numeric value + * 2 this character has a "strange" numeric value + * 3 a JS supradecimal digit: adding the digit offset to the + * character code, then masking with 0x1F, then adding 10 + * will produce the desired numeric value + * 5 bits digit offset + * 4 bits reserved for future use + * 5 bits character type + */ + +/* The X table has 1024 entries for a total of 1024 bytes. */ + +const uint8 js_X[] = { + 0, 1, 2, 3, 4, 5, 6, 7, /* 0x0000 */ + 8, 9, 10, 11, 12, 13, 14, 15, /* 0x0200 */ + 16, 17, 18, 19, 20, 21, 22, 23, /* 0x0400 */ + 24, 25, 26, 27, 28, 28, 28, 28, /* 0x0600 */ + 28, 28, 28, 28, 29, 30, 31, 32, /* 0x0800 */ + 33, 34, 35, 36, 37, 38, 39, 40, /* 0x0A00 */ + 41, 42, 43, 44, 45, 46, 28, 28, /* 0x0C00 */ + 47, 48, 49, 50, 51, 52, 53, 28, /* 0x0E00 */ + 28, 28, 54, 55, 56, 57, 58, 59, /* 0x1000 */ + 28, 28, 28, 28, 28, 28, 28, 28, /* 0x1200 */ + 28, 28, 28, 28, 28, 28, 28, 28, /* 0x1400 */ + 28, 28, 28, 28, 28, 28, 28, 28, /* 0x1600 */ + 28, 28, 28, 28, 28, 28, 28, 28, /* 0x1800 */ + 28, 28, 28, 28, 28, 28, 28, 28, /* 0x1A00 */ + 28, 28, 28, 28, 28, 28, 28, 28, /* 0x1C00 */ + 60, 60, 61, 62, 63, 64, 65, 66, /* 0x1E00 */ + 67, 68, 69, 70, 71, 72, 73, 74, /* 0x2000 */ + 75, 75, 75, 76, 77, 78, 28, 28, /* 0x2200 */ + 79, 80, 81, 82, 83, 83, 84, 85, /* 0x2400 */ + 86, 85, 28, 28, 87, 88, 89, 28, /* 0x2600 */ + 28, 28, 28, 28, 28, 28, 28, 28, /* 0x2800 */ + 28, 28, 28, 28, 28, 28, 28, 28, /* 0x2A00 */ + 28, 28, 28, 28, 28, 28, 28, 28, /* 0x2C00 */ + 28, 28, 28, 28, 28, 28, 28, 28, /* 0x2E00 */ + 90, 91, 92, 93, 94, 56, 95, 28, /* 0x3000 */ + 96, 97, 98, 99, 83, 100, 83, 101, /* 0x3200 */ + 28, 28, 28, 28, 28, 28, 28, 28, /* 0x3400 */ + 28, 28, 28, 28, 28, 28, 28, 28, /* 0x3600 */ + 28, 28, 28, 28, 28, 28, 28, 28, /* 0x3800 */ + 28, 28, 28, 28, 28, 28, 28, 28, /* 0x3A00 */ + 28, 28, 28, 28, 28, 28, 28, 28, /* 0x3C00 */ + 28, 28, 28, 28, 28, 28, 28, 28, /* 0x3E00 */ + 28, 28, 28, 28, 28, 28, 28, 28, /* 0x4000 */ + 28, 28, 28, 28, 28, 28, 28, 28, /* 0x4200 */ + 28, 28, 28, 28, 28, 28, 28, 28, /* 0x4400 */ + 28, 28, 28, 28, 28, 28, 28, 28, /* 0x4600 */ + 28, 28, 28, 28, 28, 28, 28, 28, /* 0x4800 */ + 28, 28, 28, 28, 28, 28, 28, 28, /* 0x4A00 */ + 28, 28, 28, 28, 28, 28, 28, 28, /* 0x4C00 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0x4E00 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0x5000 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0x5200 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0x5400 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0x5600 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0x5800 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0x5A00 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0x5C00 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0x5E00 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0x6000 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0x6200 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0x6400 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0x6600 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0x6800 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0x6A00 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0x6C00 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0x6E00 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0x7000 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0x7200 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0x7400 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0x7600 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0x7800 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0x7A00 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0x7C00 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0x7E00 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0x8000 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0x8200 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0x8400 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0x8600 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0x8800 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0x8A00 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0x8C00 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0x8E00 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0x9000 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0x9200 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0x9400 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0x9600 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0x9800 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0x9A00 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0x9C00 */ + 56, 56, 56, 56, 56, 56, 102, 28, /* 0x9E00 */ + 28, 28, 28, 28, 28, 28, 28, 28, /* 0xA000 */ + 28, 28, 28, 28, 28, 28, 28, 28, /* 0xA200 */ + 28, 28, 28, 28, 28, 28, 28, 28, /* 0xA400 */ + 28, 28, 28, 28, 28, 28, 28, 28, /* 0xA600 */ + 28, 28, 28, 28, 28, 28, 28, 28, /* 0xA800 */ + 28, 28, 28, 28, 28, 28, 28, 28, /* 0xAA00 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0xAC00 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0xAE00 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0xB000 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0xB200 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0xB400 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0xB600 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0xB800 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0xBA00 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0xBC00 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0xBE00 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0xC000 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0xC200 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0xC400 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0xC600 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0xC800 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0xCA00 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0xCC00 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0xCE00 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0xD000 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0xD200 */ + 56, 56, 56, 56, 56, 56, 56, 56, /* 0xD400 */ + 56, 56, 56, 56, 56, 56, 103, 28, /* 0xD600 */ +104, 104, 104, 104, 104, 104, 104, 104, /* 0xD800 */ +104, 104, 104, 104, 104, 104, 104, 104, /* 0xDA00 */ +104, 104, 104, 104, 104, 104, 104, 104, /* 0xDC00 */ +104, 104, 104, 104, 104, 104, 104, 104, /* 0xDE00 */ +105, 105, 105, 105, 105, 105, 105, 105, /* 0xE000 */ +105, 105, 105, 105, 105, 105, 105, 105, /* 0xE200 */ +105, 105, 105, 105, 105, 105, 105, 105, /* 0xE400 */ +105, 105, 105, 105, 105, 105, 105, 105, /* 0xE600 */ +105, 105, 105, 105, 105, 105, 105, 105, /* 0xE800 */ +105, 105, 105, 105, 105, 105, 105, 105, /* 0xEA00 */ +105, 105, 105, 105, 105, 105, 105, 105, /* 0xEC00 */ +105, 105, 105, 105, 105, 105, 105, 105, /* 0xEE00 */ +105, 105, 105, 105, 105, 105, 105, 105, /* 0xF000 */ +105, 105, 105, 105, 105, 105, 105, 105, /* 0xF200 */ +105, 105, 105, 105, 105, 105, 105, 105, /* 0xF400 */ +105, 105, 105, 105, 105, 105, 105, 105, /* 0xF600 */ +105, 105, 105, 105, 56, 56, 56, 56, /* 0xF800 */ +106, 28, 28, 28, 107, 108, 109, 110, /* 0xFA00 */ + 56, 56, 56, 56, 111, 112, 113, 114, /* 0xFC00 */ +115, 116, 56, 117, 118, 119, 120, 121 /* 0xFE00 */ +}; + +/* The Y table has 7808 entries for a total of 7808 bytes. */ + +const uint8 js_Y[] = { + 0, 0, 0, 0, 0, 0, 0, 0, /* 0 */ + 0, 1, 1, 1, 1, 1, 0, 0, /* 0 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 0 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 0 */ + 2, 3, 3, 3, 4, 3, 3, 3, /* 0 */ + 5, 6, 3, 7, 3, 8, 3, 3, /* 0 */ + 9, 9, 9, 9, 9, 9, 9, 9, /* 0 */ + 9, 9, 3, 3, 7, 7, 7, 3, /* 0 */ + 3, 10, 10, 10, 10, 10, 10, 10, /* 1 */ + 10, 10, 10, 10, 10, 10, 10, 10, /* 1 */ + 10, 10, 10, 10, 10, 10, 10, 10, /* 1 */ + 10, 10, 10, 5, 3, 6, 11, 12, /* 1 */ + 11, 13, 13, 13, 13, 13, 13, 13, /* 1 */ + 13, 13, 13, 13, 13, 13, 13, 13, /* 1 */ + 13, 13, 13, 13, 13, 13, 13, 13, /* 1 */ + 13, 13, 13, 5, 7, 6, 7, 0, /* 1 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 2 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 2 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 2 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 2 */ + 2, 3, 4, 4, 4, 4, 15, 15, /* 2 */ + 11, 15, 16, 5, 7, 8, 15, 11, /* 2 */ + 15, 7, 17, 17, 11, 16, 15, 3, /* 2 */ + 11, 18, 16, 6, 19, 19, 19, 3, /* 2 */ + 20, 20, 20, 20, 20, 20, 20, 20, /* 3 */ + 20, 20, 20, 20, 20, 20, 20, 20, /* 3 */ + 20, 20, 20, 20, 20, 20, 20, 7, /* 3 */ + 20, 20, 20, 20, 20, 20, 20, 16, /* 3 */ + 21, 21, 21, 21, 21, 21, 21, 21, /* 3 */ + 21, 21, 21, 21, 21, 21, 21, 21, /* 3 */ + 21, 21, 21, 21, 21, 21, 21, 7, /* 3 */ + 21, 21, 21, 21, 21, 21, 21, 22, /* 3 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 4 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 4 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 4 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 4 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 4 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 4 */ + 25, 26, 23, 24, 23, 24, 23, 24, /* 4 */ + 16, 23, 24, 23, 24, 23, 24, 23, /* 4 */ + 24, 23, 24, 23, 24, 23, 24, 23, /* 5 */ + 24, 16, 23, 24, 23, 24, 23, 24, /* 5 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 5 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 5 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 5 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 5 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 5 */ + 27, 23, 24, 23, 24, 23, 24, 28, /* 5 */ + 16, 29, 23, 24, 23, 24, 30, 23, /* 6 */ + 24, 31, 31, 23, 24, 16, 32, 32, /* 6 */ + 33, 23, 24, 31, 34, 16, 35, 36, /* 6 */ + 23, 24, 16, 16, 35, 37, 16, 38, /* 6 */ + 23, 24, 23, 24, 23, 24, 38, 23, /* 6 */ + 24, 39, 40, 16, 23, 24, 39, 23, /* 6 */ + 24, 41, 41, 23, 24, 23, 24, 42, /* 6 */ + 23, 24, 16, 40, 23, 24, 40, 40, /* 6 */ + 40, 40, 40, 40, 43, 44, 45, 43, /* 7 */ + 44, 45, 43, 44, 45, 23, 24, 23, /* 7 */ + 24, 23, 24, 23, 24, 23, 24, 23, /* 7 */ + 24, 23, 24, 23, 24, 16, 23, 24, /* 7 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 7 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 7 */ + 16, 43, 44, 45, 23, 24, 46, 46, /* 7 */ + 46, 46, 23, 24, 23, 24, 23, 24, /* 7 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 8 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 8 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 8 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 8 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 8 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 8 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 8 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 8 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 9 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 9 */ + 16, 16, 16, 47, 48, 16, 49, 49, /* 9 */ + 50, 50, 16, 51, 16, 16, 16, 16, /* 9 */ + 49, 16, 16, 52, 16, 16, 16, 16, /* 9 */ + 53, 54, 16, 16, 16, 16, 16, 54, /* 9 */ + 16, 16, 55, 16, 16, 16, 16, 16, /* 9 */ + 16, 16, 16, 16, 16, 16, 16, 16, /* 9 */ + 16, 16, 16, 56, 16, 16, 16, 16, /* 10 */ + 56, 16, 57, 57, 16, 16, 16, 16, /* 10 */ + 16, 16, 58, 16, 16, 16, 16, 16, /* 10 */ + 16, 16, 16, 16, 16, 16, 16, 16, /* 10 */ + 16, 16, 16, 16, 16, 16, 16, 16, /* 10 */ + 16, 46, 46, 46, 46, 46, 46, 46, /* 10 */ + 59, 59, 59, 59, 59, 59, 59, 59, /* 10 */ + 59, 11, 11, 59, 59, 59, 59, 59, /* 10 */ + 59, 59, 11, 11, 11, 11, 11, 11, /* 11 */ + 11, 11, 11, 11, 11, 11, 11, 11, /* 11 */ + 59, 59, 11, 11, 11, 11, 11, 11, /* 11 */ + 11, 11, 11, 11, 11, 11, 11, 46, /* 11 */ + 59, 59, 59, 59, 59, 11, 11, 11, /* 11 */ + 11, 11, 46, 46, 46, 46, 46, 46, /* 11 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 11 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 11 */ + 60, 60, 60, 60, 60, 60, 60, 60, /* 12 */ + 60, 60, 60, 60, 60, 60, 60, 60, /* 12 */ + 60, 60, 60, 60, 60, 60, 60, 60, /* 12 */ + 60, 60, 60, 60, 60, 60, 60, 60, /* 12 */ + 60, 60, 60, 60, 60, 60, 60, 60, /* 12 */ + 60, 60, 60, 60, 60, 60, 60, 60, /* 12 */ + 60, 60, 60, 60, 60, 60, 60, 60, /* 12 */ + 60, 60, 60, 60, 60, 60, 60, 60, /* 12 */ + 60, 60, 60, 60, 60, 60, 46, 46, /* 13 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 13 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 13 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 13 */ + 60, 60, 46, 46, 46, 46, 46, 46, /* 13 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 13 */ + 46, 46, 46, 46, 3, 3, 46, 46, /* 13 */ + 46, 46, 59, 46, 46, 46, 3, 46, /* 13 */ + 46, 46, 46, 46, 11, 11, 61, 3, /* 14 */ + 62, 62, 62, 46, 63, 46, 64, 64, /* 14 */ + 16, 20, 20, 20, 20, 20, 20, 20, /* 14 */ + 20, 20, 20, 20, 20, 20, 20, 20, /* 14 */ + 20, 20, 46, 20, 20, 20, 20, 20, /* 14 */ + 20, 20, 20, 20, 65, 66, 66, 66, /* 14 */ + 16, 21, 21, 21, 21, 21, 21, 21, /* 14 */ + 21, 21, 21, 21, 21, 21, 21, 21, /* 14 */ + 21, 21, 16, 21, 21, 21, 21, 21, /* 15 */ + 21, 21, 21, 21, 67, 68, 68, 46, /* 15 */ + 69, 70, 38, 38, 38, 71, 72, 46, /* 15 */ + 46, 46, 38, 46, 38, 46, 38, 46, /* 15 */ + 38, 46, 23, 24, 23, 24, 23, 24, /* 15 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 15 */ + 73, 74, 16, 40, 46, 46, 46, 46, /* 15 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 15 */ + 46, 75, 75, 75, 75, 75, 75, 75, /* 16 */ + 75, 75, 75, 75, 75, 46, 75, 75, /* 16 */ + 20, 20, 20, 20, 20, 20, 20, 20, /* 16 */ + 20, 20, 20, 20, 20, 20, 20, 20, /* 16 */ + 20, 20, 20, 20, 20, 20, 20, 20, /* 16 */ + 20, 20, 20, 20, 20, 20, 20, 20, /* 16 */ + 21, 21, 21, 21, 21, 21, 21, 21, /* 16 */ + 21, 21, 21, 21, 21, 21, 21, 21, /* 16 */ + 21, 21, 21, 21, 21, 21, 21, 21, /* 17 */ + 21, 21, 21, 21, 21, 21, 21, 21, /* 17 */ + 46, 74, 74, 74, 74, 74, 74, 74, /* 17 */ + 74, 74, 74, 74, 74, 46, 74, 74, /* 17 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 17 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 17 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 17 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 17 */ + 23, 24, 15, 60, 60, 60, 60, 46, /* 18 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 18 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 18 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 18 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 18 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 18 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 18 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 18 */ + 40, 23, 24, 23, 24, 46, 46, 23, /* 19 */ + 24, 46, 46, 23, 24, 46, 46, 46, /* 19 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 19 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 19 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 19 */ + 23, 24, 23, 24, 46, 46, 23, 24, /* 19 */ + 23, 24, 23, 24, 23, 24, 46, 46, /* 19 */ + 23, 24, 46, 46, 46, 46, 46, 46, /* 19 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 20 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 20 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 20 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 20 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 20 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 20 */ + 46, 76, 76, 76, 76, 76, 76, 76, /* 20 */ + 76, 76, 76, 76, 76, 76, 76, 76, /* 20 */ + 76, 76, 76, 76, 76, 76, 76, 76, /* 21 */ + 76, 76, 76, 76, 76, 76, 76, 76, /* 21 */ + 76, 76, 76, 76, 76, 76, 76, 46, /* 21 */ + 46, 59, 3, 3, 3, 3, 3, 3, /* 21 */ + 46, 77, 77, 77, 77, 77, 77, 77, /* 21 */ + 77, 77, 77, 77, 77, 77, 77, 77, /* 21 */ + 77, 77, 77, 77, 77, 77, 77, 77, /* 21 */ + 77, 77, 77, 77, 77, 77, 77, 77, /* 21 */ + 77, 77, 77, 77, 77, 77, 77, 16, /* 22 */ + 46, 3, 46, 46, 46, 46, 46, 46, /* 22 */ + 46, 60, 60, 60, 60, 60, 60, 60, /* 22 */ + 60, 60, 60, 60, 60, 60, 60, 60, /* 22 */ + 60, 60, 46, 60, 60, 60, 60, 60, /* 22 */ + 60, 60, 60, 60, 60, 60, 60, 60, /* 22 */ + 60, 60, 60, 60, 60, 60, 60, 60, /* 22 */ + 60, 60, 46, 60, 60, 60, 3, 60, /* 22 */ + 3, 60, 60, 3, 60, 46, 46, 46, /* 23 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 23 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 23 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 23 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 23 */ + 40, 40, 40, 46, 46, 46, 46, 46, /* 23 */ + 40, 40, 40, 3, 3, 46, 46, 46, /* 23 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 23 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 24 */ + 46, 46, 46, 46, 3, 46, 46, 46, /* 24 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 24 */ + 46, 46, 46, 3, 46, 46, 46, 3, /* 24 */ + 46, 40, 40, 40, 40, 40, 40, 40, /* 24 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 24 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 24 */ + 40, 40, 40, 46, 46, 46, 46, 46, /* 24 */ + 59, 40, 40, 40, 40, 40, 40, 40, /* 25 */ + 40, 40, 40, 60, 60, 60, 60, 60, /* 25 */ + 60, 60, 60, 46, 46, 46, 46, 46, /* 25 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 25 */ + 78, 78, 78, 78, 78, 78, 78, 78, /* 25 */ + 78, 78, 3, 3, 3, 3, 46, 46, /* 25 */ + 60, 40, 40, 40, 40, 40, 40, 40, /* 25 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 25 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 26 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 26 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 26 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 26 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 26 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 26 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 26 */ + 46, 46, 40, 40, 40, 40, 40, 46, /* 26 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 27 */ + 40, 40, 40, 40, 40, 40, 40, 46, /* 27 */ + 40, 40, 40, 40, 3, 40, 60, 60, /* 27 */ + 60, 60, 60, 60, 60, 79, 79, 60, /* 27 */ + 60, 60, 60, 60, 60, 59, 59, 60, /* 27 */ + 60, 15, 60, 60, 60, 60, 46, 46, /* 27 */ + 9, 9, 9, 9, 9, 9, 9, 9, /* 27 */ + 9, 9, 46, 46, 46, 46, 46, 46, /* 27 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 28 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 28 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 28 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 28 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 28 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 28 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 28 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 28 */ + 46, 60, 60, 80, 46, 40, 40, 40, /* 29 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 29 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 29 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 29 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 29 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 29 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 29 */ + 40, 40, 46, 46, 60, 40, 80, 80, /* 29 */ + 80, 60, 60, 60, 60, 60, 60, 60, /* 30 */ + 60, 80, 80, 80, 80, 60, 46, 46, /* 30 */ + 15, 60, 60, 60, 60, 46, 46, 46, /* 30 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 30 */ + 40, 40, 60, 60, 3, 3, 81, 81, /* 30 */ + 81, 81, 81, 81, 81, 81, 81, 81, /* 30 */ + 3, 46, 46, 46, 46, 46, 46, 46, /* 30 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 30 */ + 46, 60, 80, 80, 46, 40, 40, 40, /* 31 */ + 40, 40, 40, 40, 40, 46, 46, 40, /* 31 */ + 40, 46, 46, 40, 40, 40, 40, 40, /* 31 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 31 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 31 */ + 40, 46, 40, 40, 40, 40, 40, 40, /* 31 */ + 40, 46, 40, 46, 46, 46, 40, 40, /* 31 */ + 40, 40, 46, 46, 60, 46, 80, 80, /* 31 */ + 80, 60, 60, 60, 60, 46, 46, 80, /* 32 */ + 80, 46, 46, 80, 80, 60, 46, 46, /* 32 */ + 46, 46, 46, 46, 46, 46, 46, 80, /* 32 */ + 46, 46, 46, 46, 40, 40, 46, 40, /* 32 */ + 40, 40, 60, 60, 46, 46, 81, 81, /* 32 */ + 81, 81, 81, 81, 81, 81, 81, 81, /* 32 */ + 40, 40, 4, 4, 82, 82, 82, 82, /* 32 */ + 19, 83, 15, 46, 46, 46, 46, 46, /* 32 */ + 46, 46, 60, 46, 46, 40, 40, 40, /* 33 */ + 40, 40, 40, 46, 46, 46, 46, 40, /* 33 */ + 40, 46, 46, 40, 40, 40, 40, 40, /* 33 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 33 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 33 */ + 40, 46, 40, 40, 40, 40, 40, 40, /* 33 */ + 40, 46, 40, 40, 46, 40, 40, 46, /* 33 */ + 40, 40, 46, 46, 60, 46, 80, 80, /* 33 */ + 80, 60, 60, 46, 46, 46, 46, 60, /* 34 */ + 60, 46, 46, 60, 60, 60, 46, 46, /* 34 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 34 */ + 46, 40, 40, 40, 40, 46, 40, 46, /* 34 */ + 46, 46, 46, 46, 46, 46, 81, 81, /* 34 */ + 81, 81, 81, 81, 81, 81, 81, 81, /* 34 */ + 60, 60, 40, 40, 40, 46, 46, 46, /* 34 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 34 */ + 46, 60, 60, 80, 46, 40, 40, 40, /* 35 */ + 40, 40, 40, 40, 46, 40, 46, 40, /* 35 */ + 40, 40, 46, 40, 40, 40, 40, 40, /* 35 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 35 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 35 */ + 40, 46, 40, 40, 40, 40, 40, 40, /* 35 */ + 40, 46, 40, 40, 46, 40, 40, 40, /* 35 */ + 40, 40, 46, 46, 60, 40, 80, 80, /* 35 */ + 80, 60, 60, 60, 60, 60, 46, 60, /* 36 */ + 60, 80, 46, 80, 80, 60, 46, 46, /* 36 */ + 15, 46, 46, 46, 46, 46, 46, 46, /* 36 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 36 */ + 40, 46, 46, 46, 46, 46, 81, 81, /* 36 */ + 81, 81, 81, 81, 81, 81, 81, 81, /* 36 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 36 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 36 */ + 46, 60, 80, 80, 46, 40, 40, 40, /* 37 */ + 40, 40, 40, 40, 40, 46, 46, 40, /* 37 */ + 40, 46, 46, 40, 40, 40, 40, 40, /* 37 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 37 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 37 */ + 40, 46, 40, 40, 40, 40, 40, 40, /* 37 */ + 40, 46, 40, 40, 46, 46, 40, 40, /* 37 */ + 40, 40, 46, 46, 60, 40, 80, 60, /* 37 */ + 80, 60, 60, 60, 46, 46, 46, 80, /* 38 */ + 80, 46, 46, 80, 80, 60, 46, 46, /* 38 */ + 46, 46, 46, 46, 46, 46, 60, 80, /* 38 */ + 46, 46, 46, 46, 40, 40, 46, 40, /* 38 */ + 40, 40, 46, 46, 46, 46, 81, 81, /* 38 */ + 81, 81, 81, 81, 81, 81, 81, 81, /* 38 */ + 15, 46, 46, 46, 46, 46, 46, 46, /* 38 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 38 */ + 46, 46, 60, 80, 46, 40, 40, 40, /* 39 */ + 40, 40, 40, 46, 46, 46, 40, 40, /* 39 */ + 40, 46, 40, 40, 40, 40, 46, 46, /* 39 */ + 46, 40, 40, 46, 40, 46, 40, 40, /* 39 */ + 46, 46, 46, 40, 40, 46, 46, 46, /* 39 */ + 40, 40, 40, 46, 46, 46, 40, 40, /* 39 */ + 40, 40, 40, 40, 40, 40, 46, 40, /* 39 */ + 40, 40, 46, 46, 46, 46, 80, 80, /* 39 */ + 60, 80, 80, 46, 46, 46, 80, 80, /* 40 */ + 80, 46, 80, 80, 80, 60, 46, 46, /* 40 */ + 46, 46, 46, 46, 46, 46, 46, 80, /* 40 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 40 */ + 46, 46, 46, 46, 46, 46, 46, 81, /* 40 */ + 81, 81, 81, 81, 81, 81, 81, 81, /* 40 */ + 84, 19, 19, 46, 46, 46, 46, 46, /* 40 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 40 */ + 46, 80, 80, 80, 46, 40, 40, 40, /* 41 */ + 40, 40, 40, 40, 40, 46, 40, 40, /* 41 */ + 40, 46, 40, 40, 40, 40, 40, 40, /* 41 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 41 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 41 */ + 40, 46, 40, 40, 40, 40, 40, 40, /* 41 */ + 40, 40, 40, 40, 46, 40, 40, 40, /* 41 */ + 40, 40, 46, 46, 46, 46, 60, 60, /* 41 */ + 60, 80, 80, 80, 80, 46, 60, 60, /* 42 */ + 60, 46, 60, 60, 60, 60, 46, 46, /* 42 */ + 46, 46, 46, 46, 46, 60, 60, 46, /* 42 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 42 */ + 40, 40, 46, 46, 46, 46, 81, 81, /* 42 */ + 81, 81, 81, 81, 81, 81, 81, 81, /* 42 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 42 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 42 */ + 46, 46, 80, 80, 46, 40, 40, 40, /* 43 */ + 40, 40, 40, 40, 40, 46, 40, 40, /* 43 */ + 40, 46, 40, 40, 40, 40, 40, 40, /* 43 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 43 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 43 */ + 40, 46, 40, 40, 40, 40, 40, 40, /* 43 */ + 40, 40, 40, 40, 46, 40, 40, 40, /* 43 */ + 40, 40, 46, 46, 46, 46, 80, 60, /* 43 */ + 80, 80, 80, 80, 80, 46, 60, 80, /* 44 */ + 80, 46, 80, 80, 60, 60, 46, 46, /* 44 */ + 46, 46, 46, 46, 46, 80, 80, 46, /* 44 */ + 46, 46, 46, 46, 46, 46, 40, 46, /* 44 */ + 40, 40, 46, 46, 46, 46, 81, 81, /* 44 */ + 81, 81, 81, 81, 81, 81, 81, 81, /* 44 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 44 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 44 */ + 46, 46, 80, 80, 46, 40, 40, 40, /* 45 */ + 40, 40, 40, 40, 40, 46, 40, 40, /* 45 */ + 40, 46, 40, 40, 40, 40, 40, 40, /* 45 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 45 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 45 */ + 40, 46, 40, 40, 40, 40, 40, 40, /* 45 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 45 */ + 40, 40, 46, 46, 46, 46, 80, 80, /* 45 */ + 80, 60, 60, 60, 46, 46, 80, 80, /* 46 */ + 80, 46, 80, 80, 80, 60, 46, 46, /* 46 */ + 46, 46, 46, 46, 46, 46, 46, 80, /* 46 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 46 */ + 40, 40, 46, 46, 46, 46, 81, 81, /* 46 */ + 81, 81, 81, 81, 81, 81, 81, 81, /* 46 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 46 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 46 */ + 46, 40, 40, 40, 40, 40, 40, 40, /* 47 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 47 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 47 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 47 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 47 */ + 40, 40, 40, 40, 40, 40, 40, 3, /* 47 */ + 40, 60, 40, 40, 60, 60, 60, 60, /* 47 */ + 60, 60, 60, 46, 46, 46, 46, 4, /* 47 */ + 40, 40, 40, 40, 40, 40, 59, 60, /* 48 */ + 60, 60, 60, 60, 60, 60, 60, 15, /* 48 */ + 9, 9, 9, 9, 9, 9, 9, 9, /* 48 */ + 9, 9, 3, 3, 46, 46, 46, 46, /* 48 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 48 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 48 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 48 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 48 */ + 46, 40, 40, 46, 40, 46, 46, 40, /* 49 */ + 40, 46, 40, 46, 46, 40, 46, 46, /* 49 */ + 46, 46, 46, 46, 40, 40, 40, 40, /* 49 */ + 46, 40, 40, 40, 40, 40, 40, 40, /* 49 */ + 46, 40, 40, 40, 46, 40, 46, 40, /* 49 */ + 46, 46, 40, 40, 46, 40, 40, 3, /* 49 */ + 40, 60, 40, 40, 60, 60, 60, 60, /* 49 */ + 60, 60, 46, 60, 60, 40, 46, 46, /* 49 */ + 40, 40, 40, 40, 40, 46, 59, 46, /* 50 */ + 60, 60, 60, 60, 60, 60, 46, 46, /* 50 */ + 9, 9, 9, 9, 9, 9, 9, 9, /* 50 */ + 9, 9, 46, 46, 40, 40, 46, 46, /* 50 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 50 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 50 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 50 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 50 */ + 15, 15, 15, 15, 3, 3, 3, 3, /* 51 */ + 3, 3, 3, 3, 3, 3, 3, 3, /* 51 */ + 3, 3, 3, 15, 15, 15, 15, 15, /* 51 */ + 60, 60, 15, 15, 15, 15, 15, 15, /* 51 */ + 78, 78, 78, 78, 78, 78, 78, 78, /* 51 */ + 78, 78, 85, 85, 85, 85, 85, 85, /* 51 */ + 85, 85, 85, 85, 15, 60, 15, 60, /* 51 */ + 15, 60, 5, 6, 5, 6, 80, 80, /* 51 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 52 */ + 46, 40, 40, 40, 40, 40, 40, 40, /* 52 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 52 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 52 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 52 */ + 40, 40, 46, 46, 46, 46, 46, 46, /* 52 */ + 46, 60, 60, 60, 60, 60, 60, 60, /* 52 */ + 60, 60, 60, 60, 60, 60, 60, 80, /* 52 */ + 60, 60, 60, 60, 60, 3, 60, 60, /* 53 */ + 60, 60, 60, 60, 46, 46, 46, 46, /* 53 */ + 60, 60, 60, 60, 60, 60, 46, 60, /* 53 */ + 46, 60, 60, 60, 60, 60, 60, 60, /* 53 */ + 60, 60, 60, 60, 60, 60, 60, 60, /* 53 */ + 60, 60, 60, 60, 60, 60, 46, 46, /* 53 */ + 46, 60, 60, 60, 60, 60, 60, 60, /* 53 */ + 46, 60, 46, 46, 46, 46, 46, 46, /* 53 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 54 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 54 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 54 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 54 */ + 76, 76, 76, 76, 76, 76, 76, 76, /* 54 */ + 76, 76, 76, 76, 76, 76, 76, 76, /* 54 */ + 76, 76, 76, 76, 76, 76, 76, 76, /* 54 */ + 76, 76, 76, 76, 76, 76, 76, 76, /* 54 */ + 76, 76, 76, 76, 76, 76, 46, 46, /* 55 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 55 */ + 16, 16, 16, 16, 16, 16, 16, 16, /* 55 */ + 16, 16, 16, 16, 16, 16, 16, 16, /* 55 */ + 16, 16, 16, 16, 16, 16, 16, 16, /* 55 */ + 16, 16, 16, 16, 16, 16, 16, 16, /* 55 */ + 16, 16, 16, 16, 16, 16, 16, 46, /* 55 */ + 46, 46, 46, 3, 46, 46, 46, 46, /* 55 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 56 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 56 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 56 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 56 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 56 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 56 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 56 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 56 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 57 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 57 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 57 */ + 40, 40, 46, 46, 46, 46, 46, 40, /* 57 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 57 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 57 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 57 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 57 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 58 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 58 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 58 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 58 */ + 40, 40, 40, 46, 46, 46, 46, 46, /* 58 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 58 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 58 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 58 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 59 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 59 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 59 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 59 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 59 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 59 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 59 */ + 40, 40, 46, 46, 46, 46, 46, 46, /* 59 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 60 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 60 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 60 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 60 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 60 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 60 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 60 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 60 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 61 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 61 */ + 23, 24, 23, 24, 23, 24, 16, 16, /* 61 */ + 16, 16, 16, 16, 46, 46, 46, 46, /* 61 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 61 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 61 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 61 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 61 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 62 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 62 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 62 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 62 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 62 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 62 */ + 23, 24, 23, 24, 23, 24, 23, 24, /* 62 */ + 23, 24, 46, 46, 46, 46, 46, 46, /* 62 */ + 86, 86, 86, 86, 86, 86, 86, 86, /* 63 */ + 87, 87, 87, 87, 87, 87, 87, 87, /* 63 */ + 86, 86, 86, 86, 86, 86, 46, 46, /* 63 */ + 87, 87, 87, 87, 87, 87, 46, 46, /* 63 */ + 86, 86, 86, 86, 86, 86, 86, 86, /* 63 */ + 87, 87, 87, 87, 87, 87, 87, 87, /* 63 */ + 86, 86, 86, 86, 86, 86, 86, 86, /* 63 */ + 87, 87, 87, 87, 87, 87, 87, 87, /* 63 */ + 86, 86, 86, 86, 86, 86, 46, 46, /* 64 */ + 87, 87, 87, 87, 87, 87, 46, 46, /* 64 */ + 16, 86, 16, 86, 16, 86, 16, 86, /* 64 */ + 46, 87, 46, 87, 46, 87, 46, 87, /* 64 */ + 86, 86, 86, 86, 86, 86, 86, 86, /* 64 */ + 87, 87, 87, 87, 87, 87, 87, 87, /* 64 */ + 88, 88, 89, 89, 89, 89, 90, 90, /* 64 */ + 91, 91, 92, 92, 93, 93, 46, 46, /* 64 */ + 86, 86, 86, 86, 86, 86, 86, 86, /* 65 */ + 87, 87, 87, 87, 87, 87, 87, 87, /* 65 */ + 86, 86, 86, 86, 86, 86, 86, 86, /* 65 */ + 87, 87, 87, 87, 87, 87, 87, 87, /* 65 */ + 86, 86, 86, 86, 86, 86, 86, 86, /* 65 */ + 87, 87, 87, 87, 87, 87, 87, 87, /* 65 */ + 86, 86, 16, 94, 16, 46, 16, 16, /* 65 */ + 87, 87, 95, 95, 96, 11, 38, 11, /* 65 */ + 11, 11, 16, 94, 16, 46, 16, 16, /* 66 */ + 97, 97, 97, 97, 96, 11, 11, 11, /* 66 */ + 86, 86, 16, 16, 46, 46, 16, 16, /* 66 */ + 87, 87, 98, 98, 46, 11, 11, 11, /* 66 */ + 86, 86, 16, 16, 16, 99, 16, 16, /* 66 */ + 87, 87, 100, 100, 101, 11, 11, 11, /* 66 */ + 46, 46, 16, 94, 16, 46, 16, 16, /* 66 */ +102, 102, 103, 103, 96, 11, 11, 46, /* 66 */ + 2, 2, 2, 2, 2, 2, 2, 2, /* 67 */ + 2, 2, 2, 2, 104, 104, 104, 104, /* 67 */ + 8, 8, 8, 8, 8, 8, 3, 3, /* 67 */ + 5, 6, 5, 5, 5, 6, 5, 5, /* 67 */ + 3, 3, 3, 3, 3, 3, 3, 3, /* 67 */ +105, 106, 104, 104, 104, 104, 104, 46, /* 67 */ + 3, 3, 3, 3, 3, 3, 3, 3, /* 67 */ + 3, 5, 6, 3, 3, 3, 3, 12, /* 67 */ + 12, 3, 3, 3, 7, 5, 6, 46, /* 68 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 68 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 68 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 68 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 68 */ + 46, 46, 104, 104, 104, 104, 104, 104, /* 68 */ + 17, 46, 46, 46, 17, 17, 17, 17, /* 68 */ + 17, 17, 7, 7, 7, 5, 6, 16, /* 68 */ +107, 107, 107, 107, 107, 107, 107, 107, /* 69 */ +107, 107, 7, 7, 7, 5, 6, 46, /* 69 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 69 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 69 */ + 4, 4, 4, 4, 4, 4, 4, 4, /* 69 */ + 4, 4, 4, 4, 46, 46, 46, 46, /* 69 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 69 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 69 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 70 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 70 */ + 60, 60, 60, 60, 60, 60, 60, 60, /* 70 */ + 60, 60, 60, 60, 60, 79, 79, 79, /* 70 */ + 79, 60, 46, 46, 46, 46, 46, 46, /* 70 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 70 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 70 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 70 */ + 15, 15, 38, 15, 15, 15, 15, 38, /* 71 */ + 15, 15, 16, 38, 38, 38, 16, 16, /* 71 */ + 38, 38, 38, 16, 15, 38, 15, 15, /* 71 */ + 38, 38, 38, 38, 38, 38, 15, 15, /* 71 */ + 15, 15, 15, 15, 38, 15, 38, 15, /* 71 */ + 38, 15, 38, 38, 38, 38, 16, 16, /* 71 */ + 38, 38, 15, 38, 16, 40, 40, 40, /* 71 */ + 40, 46, 46, 46, 46, 46, 46, 46, /* 71 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 72 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 72 */ + 46, 46, 46, 19, 19, 19, 19, 19, /* 72 */ + 19, 19, 19, 19, 19, 19, 19, 108, /* 72 */ +109, 109, 109, 109, 109, 109, 109, 109, /* 72 */ +109, 109, 109, 109, 110, 110, 110, 110, /* 72 */ +111, 111, 111, 111, 111, 111, 111, 111, /* 72 */ +111, 111, 111, 111, 112, 112, 112, 112, /* 72 */ +113, 113, 113, 46, 46, 46, 46, 46, /* 73 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 73 */ + 7, 7, 7, 7, 7, 15, 15, 15, /* 73 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 73 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 73 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 73 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 73 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 73 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 74 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 74 */ + 15, 15, 7, 15, 7, 15, 15, 15, /* 74 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 74 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 74 */ + 15, 15, 15, 46, 46, 46, 46, 46, /* 74 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 74 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 74 */ + 7, 7, 7, 7, 7, 7, 7, 7, /* 75 */ + 7, 7, 7, 7, 7, 7, 7, 7, /* 75 */ + 7, 7, 7, 7, 7, 7, 7, 7, /* 75 */ + 7, 7, 7, 7, 7, 7, 7, 7, /* 75 */ + 7, 7, 7, 7, 7, 7, 7, 7, /* 75 */ + 7, 7, 7, 7, 7, 7, 7, 7, /* 75 */ + 7, 7, 7, 7, 7, 7, 7, 7, /* 75 */ + 7, 7, 7, 7, 7, 7, 7, 7, /* 75 */ + 7, 7, 7, 7, 7, 7, 7, 7, /* 76 */ + 7, 7, 7, 7, 7, 7, 7, 7, /* 76 */ + 7, 7, 7, 7, 7, 7, 7, 7, /* 76 */ + 7, 7, 7, 7, 7, 7, 7, 7, /* 76 */ + 7, 7, 7, 7, 7, 7, 7, 7, /* 76 */ + 7, 7, 7, 7, 7, 7, 7, 7, /* 76 */ + 7, 7, 46, 46, 46, 46, 46, 46, /* 76 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 76 */ + 15, 46, 15, 15, 15, 15, 15, 15, /* 77 */ + 7, 7, 7, 7, 15, 15, 15, 15, /* 77 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 77 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 77 */ + 7, 7, 15, 15, 15, 15, 15, 15, /* 77 */ + 15, 5, 6, 15, 15, 15, 15, 15, /* 77 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 77 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 77 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 78 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 78 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 78 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 78 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 78 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 78 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 78 */ + 15, 15, 15, 46, 46, 46, 46, 46, /* 78 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 79 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 79 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 79 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 79 */ + 15, 15, 15, 15, 15, 46, 46, 46, /* 79 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 79 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 79 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 79 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 80 */ + 15, 15, 15, 46, 46, 46, 46, 46, /* 80 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 80 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 80 */ +114, 114, 114, 114, 114, 114, 114, 114, /* 80 */ +114, 114, 114, 114, 114, 114, 114, 114, /* 80 */ +114, 114, 114, 114, 82, 82, 82, 82, /* 80 */ + 82, 82, 82, 82, 82, 82, 82, 82, /* 80 */ + 82, 82, 82, 82, 82, 82, 82, 82, /* 81 */ +115, 115, 115, 115, 115, 115, 115, 115, /* 81 */ +115, 115, 115, 115, 115, 115, 115, 115, /* 81 */ +115, 115, 115, 115, 15, 15, 15, 15, /* 81 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 81 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 81 */ + 15, 15, 15, 15, 15, 15, 116, 116, /* 81 */ +116, 116, 116, 116, 116, 116, 116, 116, /* 81 */ +116, 116, 116, 116, 116, 116, 116, 116, /* 82 */ +116, 116, 116, 116, 116, 116, 116, 116, /* 82 */ +117, 117, 117, 117, 117, 117, 117, 117, /* 82 */ +117, 117, 117, 117, 117, 117, 117, 117, /* 82 */ +117, 117, 117, 117, 117, 117, 117, 117, /* 82 */ +117, 117, 118, 46, 46, 46, 46, 46, /* 82 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 82 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 82 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 83 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 83 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 83 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 83 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 83 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 83 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 83 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 83 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 84 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 84 */ + 15, 15, 15, 15, 15, 15, 46, 46, /* 84 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 84 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 84 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 84 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 84 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 84 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 85 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 85 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 85 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 85 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 85 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 85 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 85 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 85 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 86 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 86 */ + 15, 15, 15, 15, 46, 46, 46, 46, /* 86 */ + 46, 46, 15, 15, 15, 15, 15, 15, /* 86 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 86 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 86 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 86 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 86 */ + 46, 15, 15, 15, 15, 46, 15, 15, /* 87 */ + 15, 15, 46, 46, 15, 15, 15, 15, /* 87 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 87 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 87 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 87 */ + 46, 15, 15, 15, 15, 15, 15, 15, /* 87 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 87 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 87 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 88 */ + 15, 15, 15, 15, 46, 15, 46, 15, /* 88 */ + 15, 15, 15, 46, 46, 46, 15, 46, /* 88 */ + 15, 15, 15, 15, 15, 15, 15, 46, /* 88 */ + 46, 15, 15, 15, 15, 15, 15, 15, /* 88 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 88 */ + 46, 46, 46, 46, 46, 46, 119, 119, /* 88 */ +119, 119, 119, 119, 119, 119, 119, 119, /* 88 */ +114, 114, 114, 114, 114, 114, 114, 114, /* 89 */ +114, 114, 83, 83, 83, 83, 83, 83, /* 89 */ + 83, 83, 83, 83, 15, 46, 46, 46, /* 89 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 89 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 89 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 89 */ + 46, 15, 15, 15, 15, 15, 15, 15, /* 89 */ + 15, 15, 15, 15, 15, 15, 15, 46, /* 89 */ + 2, 3, 3, 3, 15, 59, 3, 120, /* 90 */ + 5, 6, 5, 6, 5, 6, 5, 6, /* 90 */ + 5, 6, 15, 15, 5, 6, 5, 6, /* 90 */ + 5, 6, 5, 6, 8, 5, 6, 5, /* 90 */ + 15, 121, 121, 121, 121, 121, 121, 121, /* 90 */ +121, 121, 60, 60, 60, 60, 60, 60, /* 90 */ + 8, 59, 59, 59, 59, 59, 15, 15, /* 90 */ + 46, 46, 46, 46, 46, 46, 46, 15, /* 90 */ + 46, 40, 40, 40, 40, 40, 40, 40, /* 91 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 91 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 91 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 91 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 91 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 91 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 91 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 91 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 92 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 92 */ + 40, 40, 40, 40, 40, 46, 46, 46, /* 92 */ + 46, 60, 60, 59, 59, 59, 59, 46, /* 92 */ + 46, 40, 40, 40, 40, 40, 40, 40, /* 92 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 92 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 92 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 92 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 93 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 93 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 93 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 93 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 93 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 93 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 93 */ + 40, 40, 40, 3, 59, 59, 59, 46, /* 93 */ + 46, 46, 46, 46, 46, 40, 40, 40, /* 94 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 94 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 94 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 94 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 94 */ + 40, 40, 40, 40, 40, 46, 46, 46, /* 94 */ + 46, 40, 40, 40, 40, 40, 40, 40, /* 94 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 94 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 95 */ + 40, 40, 40, 40, 40, 40, 40, 46, /* 95 */ + 15, 15, 85, 85, 85, 85, 15, 15, /* 95 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 95 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 95 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 95 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 95 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 95 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 96 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 96 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 96 */ + 15, 15, 15, 15, 15, 46, 46, 46, /* 96 */ + 85, 85, 85, 85, 85, 85, 85, 85, /* 96 */ + 85, 85, 15, 15, 15, 15, 15, 15, /* 96 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 96 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 96 */ + 15, 15, 15, 15, 46, 46, 46, 46, /* 97 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 97 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 97 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 97 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 97 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 97 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 97 */ + 15, 15, 15, 15, 46, 46, 46, 15, /* 97 */ +114, 114, 114, 114, 114, 114, 114, 114, /* 98 */ +114, 114, 15, 15, 15, 15, 15, 15, /* 98 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 98 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 98 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 98 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 98 */ + 15, 46, 46, 46, 46, 46, 46, 46, /* 98 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 98 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 99 */ + 15, 15, 15, 15, 46, 46, 46, 46, /* 99 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 99 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 99 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 99 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 99 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 99 */ + 15, 15, 15, 15, 15, 15, 15, 46, /* 99 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 100 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 100 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 100 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 100 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 100 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 100 */ + 15, 15, 15, 15, 15, 15, 15, 46, /* 100 */ + 46, 46, 46, 15, 15, 15, 15, 15, /* 100 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 101 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 101 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 101 */ + 15, 15, 15, 15, 15, 15, 46, 46, /* 101 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 101 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 101 */ + 15, 15, 15, 15, 15, 15, 15, 15, /* 101 */ + 15, 15, 15, 15, 15, 15, 15, 46, /* 101 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 102 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 102 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 102 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 102 */ + 40, 40, 40, 40, 40, 40, 46, 46, /* 102 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 102 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 102 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 102 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 103 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 103 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 103 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 103 */ + 40, 40, 40, 40, 46, 46, 46, 46, /* 103 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 103 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 103 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 103 */ +122, 122, 122, 122, 122, 122, 122, 122, /* 104 */ +122, 122, 122, 122, 122, 122, 122, 122, /* 104 */ +122, 122, 122, 122, 122, 122, 122, 122, /* 104 */ +122, 122, 122, 122, 122, 122, 122, 122, /* 104 */ +122, 122, 122, 122, 122, 122, 122, 122, /* 104 */ +122, 122, 122, 122, 122, 122, 122, 122, /* 104 */ +122, 122, 122, 122, 122, 122, 122, 122, /* 104 */ +122, 122, 122, 122, 122, 122, 122, 122, /* 104 */ +123, 123, 123, 123, 123, 123, 123, 123, /* 105 */ +123, 123, 123, 123, 123, 123, 123, 123, /* 105 */ +123, 123, 123, 123, 123, 123, 123, 123, /* 105 */ +123, 123, 123, 123, 123, 123, 123, 123, /* 105 */ +123, 123, 123, 123, 123, 123, 123, 123, /* 105 */ +123, 123, 123, 123, 123, 123, 123, 123, /* 105 */ +123, 123, 123, 123, 123, 123, 123, 123, /* 105 */ +123, 123, 123, 123, 123, 123, 123, 123, /* 105 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 106 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 106 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 106 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 106 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 106 */ + 40, 40, 40, 40, 40, 40, 46, 46, /* 106 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 106 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 106 */ + 16, 16, 16, 16, 16, 16, 16, 46, /* 107 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 107 */ + 46, 46, 46, 16, 16, 16, 16, 16, /* 107 */ + 46, 46, 46, 46, 46, 46, 60, 40, /* 107 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 107 */ + 40, 7, 40, 40, 40, 40, 40, 40, /* 107 */ + 40, 40, 40, 40, 40, 40, 40, 46, /* 107 */ + 40, 40, 40, 40, 40, 46, 40, 46, /* 107 */ + 40, 40, 46, 40, 40, 46, 40, 40, /* 108 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 108 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 108 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 108 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 108 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 108 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 108 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 108 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 109 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 109 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 109 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 109 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 109 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 109 */ + 40, 40, 46, 46, 46, 46, 46, 46, /* 109 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 109 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 110 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 110 */ + 46, 46, 46, 40, 40, 40, 40, 40, /* 110 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 110 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 110 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 110 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 110 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 110 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 111 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 111 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 111 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 111 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 111 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 111 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 111 */ + 40, 40, 40, 40, 40, 40, 5, 6, /* 111 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 112 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 112 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 112 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 112 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 112 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 112 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 112 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 112 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 113 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 113 */ + 46, 46, 40, 40, 40, 40, 40, 40, /* 113 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 113 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 113 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 113 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 113 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 113 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 114 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 114 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 114 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 114 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 114 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 114 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 114 */ + 40, 40, 40, 40, 46, 46, 46, 46, /* 114 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 115 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 115 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 115 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 115 */ + 60, 60, 60, 60, 46, 46, 46, 46, /* 115 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 115 */ + 3, 8, 8, 12, 12, 5, 6, 5, /* 115 */ + 6, 5, 6, 5, 6, 5, 6, 5, /* 115 */ + 6, 5, 6, 5, 6, 46, 46, 46, /* 116 */ + 46, 3, 3, 3, 3, 12, 12, 12, /* 116 */ + 3, 3, 3, 46, 3, 3, 3, 3, /* 116 */ + 8, 5, 6, 5, 6, 5, 6, 3, /* 116 */ + 3, 3, 7, 8, 7, 7, 7, 46, /* 116 */ + 3, 4, 3, 3, 46, 46, 46, 46, /* 116 */ + 40, 40, 40, 46, 40, 46, 40, 40, /* 116 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 116 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 117 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 117 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 117 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 117 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 117 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 117 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 117 */ + 40, 40, 40, 40, 40, 46, 46, 104, /* 117 */ + 46, 3, 3, 3, 4, 3, 3, 3, /* 118 */ + 5, 6, 3, 7, 3, 8, 3, 3, /* 118 */ + 9, 9, 9, 9, 9, 9, 9, 9, /* 118 */ + 9, 9, 3, 3, 7, 7, 7, 3, /* 118 */ + 3, 10, 10, 10, 10, 10, 10, 10, /* 118 */ + 10, 10, 10, 10, 10, 10, 10, 10, /* 118 */ + 10, 10, 10, 10, 10, 10, 10, 10, /* 118 */ + 10, 10, 10, 5, 3, 6, 11, 12, /* 118 */ + 11, 13, 13, 13, 13, 13, 13, 13, /* 119 */ + 13, 13, 13, 13, 13, 13, 13, 13, /* 119 */ + 13, 13, 13, 13, 13, 13, 13, 13, /* 119 */ + 13, 13, 13, 5, 7, 6, 7, 46, /* 119 */ + 46, 3, 5, 6, 3, 3, 40, 40, /* 119 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 119 */ + 59, 40, 40, 40, 40, 40, 40, 40, /* 119 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 119 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 120 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 120 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 120 */ + 40, 40, 40, 40, 40, 40, 59, 59, /* 120 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 120 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 120 */ + 40, 40, 40, 40, 40, 40, 40, 40, /* 120 */ + 40, 40, 40, 40, 40, 40, 40, 46, /* 120 */ + 46, 46, 40, 40, 40, 40, 40, 40, /* 121 */ + 46, 46, 40, 40, 40, 40, 40, 40, /* 121 */ + 46, 46, 40, 40, 40, 40, 40, 40, /* 121 */ + 46, 46, 40, 40, 40, 46, 46, 46, /* 121 */ + 4, 4, 7, 11, 15, 4, 4, 46, /* 121 */ + 7, 7, 7, 7, 7, 15, 15, 46, /* 121 */ + 46, 46, 46, 46, 46, 46, 46, 46, /* 121 */ + 46, 46, 46, 46, 46, 15, 46, 46 /* 121 */ +}; + +/* The A table has 124 entries for a total of 496 bytes. */ + +const uint32 js_A[] = { +0x0001000F, /* 0 Cc, ignorable */ +0x0004000F, /* 1 Cc, whitespace */ +0x0004000C, /* 2 Zs, whitespace */ +0x00000018, /* 3 Po */ +0x0006001A, /* 4 Sc, currency */ +0x00000015, /* 5 Ps */ +0x00000016, /* 6 Pe */ +0x00000019, /* 7 Sm */ +0x00000014, /* 8 Pd */ +0x00036009, /* 9 Nd, identifier part, decimal 16 */ +0x0827FE01, /* 10 Lu, hasLower (add 32), identifier start, supradecimal 31 */ +0x0000001B, /* 11 Sk */ +0x00050017, /* 12 Pc, underscore */ +0x0817FE02, /* 13 Ll, hasUpper (subtract 32), identifier start, supradecimal 31 */ +0x0000000C, /* 14 Zs */ +0x0000001C, /* 15 So */ +0x00070002, /* 16 Ll, identifier start */ +0x0000600B, /* 17 No, decimal 16 */ +0x0000500B, /* 18 No, decimal 8 */ +0x0000800B, /* 19 No, strange */ +0x08270001, /* 20 Lu, hasLower (add 32), identifier start */ +0x08170002, /* 21 Ll, hasUpper (subtract 32), identifier start */ +0xE1D70002, /* 22 Ll, hasUpper (subtract -121), identifier start */ +0x00670001, /* 23 Lu, hasLower (add 1), identifier start */ +0x00570002, /* 24 Ll, hasUpper (subtract 1), identifier start */ +0xCE670001, /* 25 Lu, hasLower (add -199), identifier start */ +0x3A170002, /* 26 Ll, hasUpper (subtract 232), identifier start */ +0xE1E70001, /* 27 Lu, hasLower (add -121), identifier start */ +0x4B170002, /* 28 Ll, hasUpper (subtract 300), identifier start */ +0x34A70001, /* 29 Lu, hasLower (add 210), identifier start */ +0x33A70001, /* 30 Lu, hasLower (add 206), identifier start */ +0x33670001, /* 31 Lu, hasLower (add 205), identifier start */ +0x32A70001, /* 32 Lu, hasLower (add 202), identifier start */ +0x32E70001, /* 33 Lu, hasLower (add 203), identifier start */ +0x33E70001, /* 34 Lu, hasLower (add 207), identifier start */ +0x34E70001, /* 35 Lu, hasLower (add 211), identifier start */ +0x34670001, /* 36 Lu, hasLower (add 209), identifier start */ +0x35670001, /* 37 Lu, hasLower (add 213), identifier start */ +0x00070001, /* 38 Lu, identifier start */ +0x36A70001, /* 39 Lu, hasLower (add 218), identifier start */ +0x00070005, /* 40 Lo, identifier start */ +0x36670001, /* 41 Lu, hasLower (add 217), identifier start */ +0x36E70001, /* 42 Lu, hasLower (add 219), identifier start */ +0x00AF0001, /* 43 Lu, hasLower (add 2), hasTitle, identifier start */ +0x007F0003, /* 44 Lt, hasUpper (subtract 1), hasLower (add 1), hasTitle, identifier start */ +0x009F0002, /* 45 Ll, hasUpper (subtract 2), hasTitle, identifier start */ +0x00000000, /* 46 unassigned */ +0x34970002, /* 47 Ll, hasUpper (subtract 210), identifier start */ +0x33970002, /* 48 Ll, hasUpper (subtract 206), identifier start */ +0x33570002, /* 49 Ll, hasUpper (subtract 205), identifier start */ +0x32970002, /* 50 Ll, hasUpper (subtract 202), identifier start */ +0x32D70002, /* 51 Ll, hasUpper (subtract 203), identifier start */ +0x33D70002, /* 52 Ll, hasUpper (subtract 207), identifier start */ +0x34570002, /* 53 Ll, hasUpper (subtract 209), identifier start */ +0x34D70002, /* 54 Ll, hasUpper (subtract 211), identifier start */ +0x35570002, /* 55 Ll, hasUpper (subtract 213), identifier start */ +0x36970002, /* 56 Ll, hasUpper (subtract 218), identifier start */ +0x36570002, /* 57 Ll, hasUpper (subtract 217), identifier start */ +0x36D70002, /* 58 Ll, hasUpper (subtract 219), identifier start */ +0x00070004, /* 59 Lm, identifier start */ +0x00030006, /* 60 Mn, identifier part */ +0x09A70001, /* 61 Lu, hasLower (add 38), identifier start */ +0x09670001, /* 62 Lu, hasLower (add 37), identifier start */ +0x10270001, /* 63 Lu, hasLower (add 64), identifier start */ +0x0FE70001, /* 64 Lu, hasLower (add 63), identifier start */ +0x09970002, /* 65 Ll, hasUpper (subtract 38), identifier start */ +0x09570002, /* 66 Ll, hasUpper (subtract 37), identifier start */ +0x10170002, /* 67 Ll, hasUpper (subtract 64), identifier start */ +0x0FD70002, /* 68 Ll, hasUpper (subtract 63), identifier start */ +0x0F970002, /* 69 Ll, hasUpper (subtract 62), identifier start */ +0x0E570002, /* 70 Ll, hasUpper (subtract 57), identifier start */ +0x0BD70002, /* 71 Ll, hasUpper (subtract 47), identifier start */ +0x0D970002, /* 72 Ll, hasUpper (subtract 54), identifier start */ +0x15970002, /* 73 Ll, hasUpper (subtract 86), identifier start */ +0x14170002, /* 74 Ll, hasUpper (subtract 80), identifier start */ +0x14270001, /* 75 Lu, hasLower (add 80), identifier start */ +0x0C270001, /* 76 Lu, hasLower (add 48), identifier start */ +0x0C170002, /* 77 Ll, hasUpper (subtract 48), identifier start */ +0x00034009, /* 78 Nd, identifier part, decimal 0 */ +0x00000007, /* 79 Me */ +0x00030008, /* 80 Mc, identifier part */ +0x00037409, /* 81 Nd, identifier part, decimal 26 */ +0x00005A0B, /* 82 No, decimal 13 */ +0x00006E0B, /* 83 No, decimal 23 */ +0x0000740B, /* 84 No, decimal 26 */ +0x0000000B, /* 85 No */ +0xFE170002, /* 86 Ll, hasUpper (subtract -8), identifier start */ +0xFE270001, /* 87 Lu, hasLower (add -8), identifier start */ +0xED970002, /* 88 Ll, hasUpper (subtract -74), identifier start */ +0xEA970002, /* 89 Ll, hasUpper (subtract -86), identifier start */ +0xE7170002, /* 90 Ll, hasUpper (subtract -100), identifier start */ +0xE0170002, /* 91 Ll, hasUpper (subtract -128), identifier start */ +0xE4170002, /* 92 Ll, hasUpper (subtract -112), identifier start */ +0xE0970002, /* 93 Ll, hasUpper (subtract -126), identifier start */ +0xFDD70002, /* 94 Ll, hasUpper (subtract -9), identifier start */ +0xEDA70001, /* 95 Lu, hasLower (add -74), identifier start */ +0xFDE70001, /* 96 Lu, hasLower (add -9), identifier start */ +0xEAA70001, /* 97 Lu, hasLower (add -86), identifier start */ +0xE7270001, /* 98 Lu, hasLower (add -100), identifier start */ +0xFE570002, /* 99 Ll, hasUpper (subtract -7), identifier start */ +0xE4270001, /* 100 Lu, hasLower (add -112), identifier start */ +0xFE670001, /* 101 Lu, hasLower (add -7), identifier start */ +0xE0270001, /* 102 Lu, hasLower (add -128), identifier start */ +0xE0A70001, /* 103 Lu, hasLower (add -126), identifier start */ +0x00010010, /* 104 Cf, ignorable */ +0x0004000D, /* 105 Zl, whitespace */ +0x0004000E, /* 106 Zp, whitespace */ +0x0000400B, /* 107 No, decimal 0 */ +0x0000440B, /* 108 No, decimal 2 */ +0x0427420A, /* 109 Nl, hasLower (add 16), identifier start, decimal 1 */ +0x0427800A, /* 110 Nl, hasLower (add 16), identifier start, strange */ +0x0417620A, /* 111 Nl, hasUpper (subtract 16), identifier start, decimal 17 */ +0x0417800A, /* 112 Nl, hasUpper (subtract 16), identifier start, strange */ +0x0007800A, /* 113 Nl, identifier start, strange */ +0x0000420B, /* 114 No, decimal 1 */ +0x0000720B, /* 115 No, decimal 25 */ +0x06A0001C, /* 116 So, hasLower (add 26) */ +0x0690001C, /* 117 So, hasUpper (subtract 26) */ +0x00006C0B, /* 118 No, decimal 22 */ +0x0000560B, /* 119 No, decimal 11 */ +0x0007720A, /* 120 Nl, identifier start, decimal 25 */ +0x0007400A, /* 121 Nl, identifier start, decimal 0 */ +0x00000013, /* 122 Cs */ +0x00000012 /* 123 Co */ +}; + +const jschar js_uriReservedPlusPound_ucstr[] = + {';', '/', '?', ':', '@', '&', '=', '+', '$', ',', '#', 0}; +const jschar js_uriUnescaped_ucstr[] = + {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', + 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', + 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', + '-', '_', '.', '!', '~', '*', '\'', '(', ')', 0}; + +#define URI_CHUNK 64U + +/* Concatenate jschars onto an unshared/newborn JSString. */ +static JSBool +AddCharsToURI(JSContext *cx, JSString *str, const jschar *chars, size_t length) +{ + size_t total; + + JS_ASSERT(!JSSTRING_IS_DEPENDENT(str)); + total = str->length + length + 1; + if (!str->chars || + JS_HOWMANY(total, URI_CHUNK) > JS_HOWMANY(str->length + 1, URI_CHUNK)) { + total = JS_ROUNDUP(total, URI_CHUNK); + str->chars = JS_realloc(cx, str->chars, total * sizeof(jschar)); + if (!str->chars) + return JS_FALSE; + } + js_strncpy(str->chars + str->length, chars, length); + str->length += length; + str->chars[str->length] = 0; + return JS_TRUE; +} + +/* + * ECMA 3, 15.1.3 URI Handling Function Properties + * + * The following are implementations of the algorithms + * given in the ECMA specification for the hidden functions + * 'Encode' and 'Decode'. + */ +static JSBool +Encode(JSContext *cx, JSString *str, const jschar *unescapedSet, + const jschar *unescapedSet2, jsval *rval) +{ + size_t length, j, k, L; + jschar *chars, C, C2; + uint32 V; + uint8 utf8buf[6]; + jschar hexBuf[4]; + static const char HexDigits[] = "0123456789ABCDEF"; /* NB: uppercase */ + JSString *R; + + R = js_NewString(cx, NULL, 0, 0); + if (!R) + return JS_FALSE; + + hexBuf[0] = '%'; + hexBuf[3] = 0; + chars = JSSTRING_CHARS(str); + length = JSSTRING_LENGTH(str); + for (k = 0; k < length; k++) { + C = chars[k]; + if (js_strchr(unescapedSet, C) || + (unescapedSet2 && js_strchr(unescapedSet2, C))) { + if (!AddCharsToURI(cx, R, &C, 1)) + return JS_FALSE; + } else { + if ((C >= 0xDC00) && (C <= 0xDFFF)) { + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, + JSMSG_BAD_URI, NULL); + return JS_FALSE; + } + if (C < 0xD800 || C > 0xDBFF) { + V = C; + } else { + k++; + if (k == length) { + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, + JSMSG_BAD_URI, NULL); + return JS_FALSE; + } + C2 = chars[k]; + if ((C2 < 0xDC00) || (C2 > 0xDFFF)) { + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, + JSMSG_BAD_URI, NULL); + return JS_FALSE; + } + V = ((C - 0xD800) << 10) + (C2 - 0xDC00) + 0x10000; + } + L = OneUcs4ToUtf8Char(utf8buf, V); + for (j = 0; j < L; j++) { + hexBuf[1] = HexDigits[utf8buf[j] >> 4]; + hexBuf[2] = HexDigits[utf8buf[j] & 0xf]; + if (!AddCharsToURI(cx, R, hexBuf, 3)) + return JS_FALSE; + } + } + } + + /* + * Shrinking realloc can fail (e.g., with a BSD-style allocator), but we + * don't worry about that case here. Worst case, R hangs onto URI_CHUNK-1 + * more jschars than it needs. + */ + chars = (jschar *) JS_realloc(cx, R->chars, (R->length+1) * sizeof(jschar)); + if (chars) + R->chars = chars; + *rval = STRING_TO_JSVAL(R); + return JS_TRUE; +} + +static JSBool +Decode(JSContext *cx, JSString *str, const jschar *reservedSet, jsval *rval) +{ + size_t length, start, k; + jschar *chars, C, H; + uint32 V; + jsuint B; + uint8 octets[6]; + JSString *R; + intN j, n; + + R = js_NewString(cx, NULL, 0, 0); + if (!R) + return JS_FALSE; + + chars = JSSTRING_CHARS(str); + length = JSSTRING_LENGTH(str); + for (k = 0; k < length; k++) { + C = chars[k]; + if (C == '%') { + start = k; + if ((k + 2) >= length) + goto bad; + if (!JS7_ISHEX(chars[k+1]) || !JS7_ISHEX(chars[k+2])) + goto bad; + B = JS7_UNHEX(chars[k+1]) * 16 + JS7_UNHEX(chars[k+2]); + k += 2; + if (!(B & 0x80)) { + C = (jschar)B; + } else { + n = 1; + while (B & (0x80 >> n)) + n++; + if (n == 1 || n > 6) + goto bad; + octets[0] = (uint8)B; + if (k + 3 * (n - 1) >= length) + goto bad; + for (j = 1; j < n; j++) { + k++; + if (chars[k] != '%') + goto bad; + if (!JS7_ISHEX(chars[k+1]) || !JS7_ISHEX(chars[k+2])) + goto bad; + B = JS7_UNHEX(chars[k+1]) * 16 + JS7_UNHEX(chars[k+2]); + if ((B & 0xC0) != 0x80) + goto bad; + k += 2; + octets[j] = (char)B; + } + V = Utf8ToOneUcs4Char(octets, n); + if (V >= 0x10000) { + V -= 0x10000; + if (V > 0xFFFFF) + goto bad; + C = (jschar)((V & 0x3FF) + 0xDC00); + H = (jschar)((V >> 10) + 0xD800); + if (!AddCharsToURI(cx, R, &H, 1)) + return JS_FALSE; + } else { + C = (jschar)V; + } + } + if (js_strchr(reservedSet, C)) { + if (!AddCharsToURI(cx, R, &chars[start], (k - start + 1))) + return JS_FALSE; + } else { + if (!AddCharsToURI(cx, R, &C, 1)) + return JS_FALSE; + } + } else { + if (!AddCharsToURI(cx, R, &C, 1)) + return JS_FALSE; + } + } + + /* + * Shrinking realloc can fail (e.g., with a BSD-style allocator), but we + * don't worry about that case here. Worst case, R hangs onto URI_CHUNK-1 + * more jschars than it needs. + */ + chars = (jschar *) JS_realloc(cx, R->chars, (R->length+1) * sizeof(jschar)); + if (chars) + R->chars = chars; + *rval = STRING_TO_JSVAL(R); + return JS_TRUE; + +bad: + JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BAD_URI); + return JS_FALSE; +} + +static JSBool +str_decodeURI(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval) +{ + JSString *str; + + str = js_ValueToString(cx, argv[0]); + if (!str) + return JS_FALSE; + return Decode(cx, str, js_uriReservedPlusPound_ucstr, rval); +} + +static JSBool +str_decodeURI_Component(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval) +{ + JSString *str; + + str = js_ValueToString(cx, argv[0]); + if (!str) + return JS_FALSE; + return Decode(cx, str, js_empty_ucstr, rval); +} + +static JSBool +str_encodeURI(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval) +{ + JSString *str; + + str = js_ValueToString(cx, argv[0]); + if (!str) + return JS_FALSE; + return Encode(cx, str, js_uriReservedPlusPound_ucstr, js_uriUnescaped_ucstr, + rval); +} + +static JSBool +str_encodeURI_Component(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval) +{ + JSString *str; + + str = js_ValueToString(cx, argv[0]); + if (!str) + return JS_FALSE; + return Encode(cx, str, js_uriUnescaped_ucstr, NULL, rval); +} + +/* + * Convert one UCS-4 char and write it into a UTF-8 buffer, which must be at + * least 6 bytes long. Return the number of UTF-8 bytes of data written. + */ +static int +OneUcs4ToUtf8Char(uint8 *utf8Buffer, uint32 ucs4Char) +{ + int utf8Length = 1; + + JS_ASSERT(ucs4Char <= 0x7FFFFFFF); + if (ucs4Char < 0x80) { + *utf8Buffer = (uint8)ucs4Char; + } else { + int i; + uint32 a = ucs4Char >> 11; + utf8Length = 2; + while (a) { + a >>= 5; + utf8Length++; + } + i = utf8Length; + while (--i) { + utf8Buffer[i] = (uint8)((ucs4Char & 0x3F) | 0x80); + ucs4Char >>= 6; + } + *utf8Buffer = (uint8)(0x100 - (1 << (8-utf8Length)) + ucs4Char); + } + return utf8Length; +} + +/* + * Convert a utf8 character sequence into a UCS-4 character and return that + * character. It is assumed that the caller already checked that the sequence + * is valid. + */ +static uint32 +Utf8ToOneUcs4Char(const uint8 *utf8Buffer, int utf8Length) +{ + uint32 ucs4Char; + uint32 minucs4Char; + /* from Unicode 3.1, non-shortest form is illegal */ + static const uint32 minucs4Table[] = { + 0x00000080, 0x00000800, 0x0001000, 0x0020000, 0x0400000 + }; + + JS_ASSERT(utf8Length >= 1 && utf8Length <= 6); + if (utf8Length == 1) { + ucs4Char = *utf8Buffer; + JS_ASSERT(!(ucs4Char & 0x80)); + } else { + JS_ASSERT((*utf8Buffer & (0x100 - (1 << (7-utf8Length)))) == + (0x100 - (1 << (8-utf8Length)))); + ucs4Char = *utf8Buffer++ & ((1<<(7-utf8Length))-1); + minucs4Char = minucs4Table[utf8Length-2]; + while (--utf8Length) { + JS_ASSERT((*utf8Buffer & 0xC0) == 0x80); + ucs4Char = ucs4Char<<6 | (*utf8Buffer++ & 0x3F); + } + if (ucs4Char < minucs4Char || + ucs4Char == 0xFFFE || ucs4Char == 0xFFFF) { + ucs4Char = 0xFFFD; + } + } + return ucs4Char; +} diff --git a/src/extension/script/js/jsstr.h b/src/extension/script/js/jsstr.h new file mode 100644 index 000000000..94ebe97b9 --- /dev/null +++ b/src/extension/script/js/jsstr.h @@ -0,0 +1,439 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef jsstr_h___ +#define jsstr_h___ +/* + * JS string type implementation. + * + * A JS string is a counted array of unicode characters. To support handoff + * of API client memory, the chars are allocated separately from the length, + * necessitating a pointer after the count, to form a separately allocated + * string descriptor. String descriptors are GC'ed, while their chars are + * allocated from the malloc heap. + * + * When a string is treated as an object (by following it with . or []), the + * runtime wraps it with a JSObject whose valueOf method returns the unwrapped + * string descriptor. + */ +#include +#include "jspubtd.h" +#include "jsprvtd.h" +#include "jshash.h" + +JS_BEGIN_EXTERN_C + +/* + * The original GC-thing "string" type, a flat character string owned by its + * GC-thing descriptor. The chars member points to a vector having byte size + * (length + 1) * sizeof(jschar), terminated at index length by a zero jschar. + * The terminator is purely a backstop, in case the chars pointer flows out to + * native code that requires \u0000 termination. + * + * NB: Always use the JSSTRING_LENGTH and JSSTRING_CHARS accessor macros, + * unless you guard str->member uses with !JSSTRING_IS_DEPENDENT(str). + */ +struct JSString { + size_t length; + jschar *chars; +}; + +/* + * Overlay structure for a string that depends on another string's characters. + * Distinguished by the JSSTRFLAG_DEPENDENT bit being set in length. The base + * member may point to another dependent string if JSSTRING_CHARS has not been + * called yet. The length chars in a dependent string are stored starting at + * base->chars + start, and are not necessarily zero-terminated. If start is + * 0, it is not stored, length is a full size_t (minus the JSSTRFLAG_* bits in + * the high two positions), and the JSSTRFLAG_PREFIX flag is set. + */ +struct JSDependentString { + size_t length; + JSString *base; +}; + +/* Definitions for flags stored in the high order bits of JSString.length. */ +#define JSSTRFLAG_BITS 2 +#define JSSTRFLAG_SHIFT(flg) ((size_t)(flg) << JSSTRING_LENGTH_BITS) +#define JSSTRFLAG_MASK JSSTRFLAG_SHIFT(JS_BITMASK(JSSTRFLAG_BITS)) +#define JSSTRFLAG_DEPENDENT JSSTRFLAG_SHIFT(1) +#define JSSTRFLAG_PREFIX JSSTRFLAG_SHIFT(2) + +/* Universal JSString type inquiry and accessor macros. */ +#define JSSTRING_BIT(n) ((size_t)1 << (n)) +#define JSSTRING_BITMASK(n) (JSSTRING_BIT(n) - 1) +#define JSSTRING_HAS_FLAG(str,flg) ((str)->length & (flg)) +#define JSSTRING_IS_DEPENDENT(str) JSSTRING_HAS_FLAG(str, JSSTRFLAG_DEPENDENT) +#define JSSTRING_IS_PREFIX(str) JSSTRING_HAS_FLAG(str, JSSTRFLAG_PREFIX) +#define JSSTRING_CHARS(str) (JSSTRING_IS_DEPENDENT(str) \ + ? JSSTRDEP_CHARS(str) \ + : (str)->chars) +#define JSSTRING_LENGTH(str) (JSSTRING_IS_DEPENDENT(str) \ + ? JSSTRDEP_LENGTH(str) \ + : (str)->length) +#define JSSTRING_LENGTH_BITS (sizeof(size_t) * JS_BITS_PER_BYTE \ + - JSSTRFLAG_BITS) +#define JSSTRING_LENGTH_MASK JSSTRING_BITMASK(JSSTRING_LENGTH_BITS) + +/* Specific JSDependentString shift/mask accessor and mutator macros. */ +#define JSSTRDEP_START_BITS (JSSTRING_LENGTH_BITS-JSSTRDEP_LENGTH_BITS) +#define JSSTRDEP_START_SHIFT JSSTRDEP_LENGTH_BITS +#define JSSTRDEP_START_MASK JSSTRING_BITMASK(JSSTRDEP_START_BITS) +#define JSSTRDEP_LENGTH_BITS (JSSTRING_LENGTH_BITS / 2) +#define JSSTRDEP_LENGTH_MASK JSSTRING_BITMASK(JSSTRDEP_LENGTH_BITS) + +#define JSSTRDEP(str) ((JSDependentString *)(str)) +#define JSSTRDEP_START(str) (JSSTRING_IS_PREFIX(str) ? 0 \ + : ((JSSTRDEP(str)->length \ + >> JSSTRDEP_START_SHIFT) \ + & JSSTRDEP_START_MASK)) +#define JSSTRDEP_LENGTH(str) (JSSTRDEP(str)->length \ + & (JSSTRING_IS_PREFIX(str) \ + ? JSSTRING_LENGTH_MASK \ + : JSSTRDEP_LENGTH_MASK)) + +#define JSSTRDEP_SET_START_AND_LENGTH(str,off,len) \ + (JSSTRDEP(str)->length = JSSTRFLAG_DEPENDENT \ + | ((off) << JSSTRDEP_START_SHIFT) \ + | (len)) +#define JSPREFIX_SET_LENGTH(str,len) \ + (JSSTRDEP(str)->length = JSSTRFLAG_DEPENDENT | JSSTRFLAG_PREFIX | (len)) + +#define JSSTRDEP_BASE(str) (JSSTRDEP(str)->base) +#define JSSTRDEP_SET_BASE(str,bstr) (JSSTRDEP(str)->base = (bstr)) +#define JSPREFIX_BASE(str) JSSTRDEP_BASE(str) +#define JSPREFIX_SET_BASE(str,bstr) JSSTRDEP_SET_BASE(str,bstr) + +#define JSSTRDEP_CHARS(str) \ + (JSSTRING_IS_DEPENDENT(JSSTRDEP_BASE(str)) \ + ? js_GetDependentStringChars(str) \ + : JSSTRDEP_BASE(str)->chars + JSSTRDEP_START(str)) + +extern size_t +js_MinimizeDependentStrings(JSString *str, int level, JSString **basep); + +extern jschar * +js_GetDependentStringChars(JSString *str); + +extern jschar * +js_GetStringChars(JSString *str); + +extern JSString * +js_ConcatStrings(JSContext *cx, JSString *left, JSString *right); + +extern const jschar * +js_UndependString(JSContext *cx, JSString *str); + +struct JSSubString { + size_t length; + const jschar *chars; +}; + +extern jschar js_empty_ucstr[]; +extern JSSubString js_EmptySubString; + +/* Unicode character attribute lookup tables. */ +extern const uint8 js_X[]; +extern const uint8 js_Y[]; +extern const uint32 js_A[]; + +/* Enumerated Unicode general category types. */ +typedef enum JSCharType { + JSCT_UNASSIGNED = 0, + JSCT_UPPERCASE_LETTER = 1, + JSCT_LOWERCASE_LETTER = 2, + JSCT_TITLECASE_LETTER = 3, + JSCT_MODIFIER_LETTER = 4, + JSCT_OTHER_LETTER = 5, + JSCT_NON_SPACING_MARK = 6, + JSCT_ENCLOSING_MARK = 7, + JSCT_COMBINING_SPACING_MARK = 8, + JSCT_DECIMAL_DIGIT_NUMBER = 9, + JSCT_LETTER_NUMBER = 10, + JSCT_OTHER_NUMBER = 11, + JSCT_SPACE_SEPARATOR = 12, + JSCT_LINE_SEPARATOR = 13, + JSCT_PARAGRAPH_SEPARATOR = 14, + JSCT_CONTROL = 15, + JSCT_FORMAT = 16, + JSCT_PRIVATE_USE = 18, + JSCT_SURROGATE = 19, + JSCT_DASH_PUNCTUATION = 20, + JSCT_START_PUNCTUATION = 21, + JSCT_END_PUNCTUATION = 22, + JSCT_CONNECTOR_PUNCTUATION = 23, + JSCT_OTHER_PUNCTUATION = 24, + JSCT_MATH_SYMBOL = 25, + JSCT_CURRENCY_SYMBOL = 26, + JSCT_MODIFIER_SYMBOL = 27, + JSCT_OTHER_SYMBOL = 28 +} JSCharType; + +/* Character classifying and mapping macros, based on java.lang.Character. */ +#define JS_CCODE(c) (js_A[js_Y[(js_X[(uint16)(c)>>6]<<6)|((c)&0x3F)]]) +#define JS_CTYPE(c) (JS_CCODE(c) & 0x1F) + +#define JS_ISALPHA(c) ((((1 << JSCT_UPPERCASE_LETTER) | \ + (1 << JSCT_LOWERCASE_LETTER) | \ + (1 << JSCT_TITLECASE_LETTER) | \ + (1 << JSCT_MODIFIER_LETTER) | \ + (1 << JSCT_OTHER_LETTER)) \ + >> JS_CTYPE(c)) & 1) + +#define JS_ISALNUM(c) ((((1 << JSCT_UPPERCASE_LETTER) | \ + (1 << JSCT_LOWERCASE_LETTER) | \ + (1 << JSCT_TITLECASE_LETTER) | \ + (1 << JSCT_MODIFIER_LETTER) | \ + (1 << JSCT_OTHER_LETTER) | \ + (1 << JSCT_DECIMAL_DIGIT_NUMBER)) \ + >> JS_CTYPE(c)) & 1) + +/* A unicode letter, suitable for use in an identifier. */ +#define JS_ISUC_LETTER(c) ((((1 << JSCT_UPPERCASE_LETTER) | \ + (1 << JSCT_LOWERCASE_LETTER) | \ + (1 << JSCT_TITLECASE_LETTER) | \ + (1 << JSCT_MODIFIER_LETTER) | \ + (1 << JSCT_OTHER_LETTER) | \ + (1 << JSCT_LETTER_NUMBER)) \ + >> JS_CTYPE(c)) & 1) + +/* +* 'IdentifierPart' from ECMA grammar, is Unicode letter or +* combining mark or digit or connector punctuation. +*/ +#define JS_ISID_PART(c) ((((1 << JSCT_UPPERCASE_LETTER) | \ + (1 << JSCT_LOWERCASE_LETTER) | \ + (1 << JSCT_TITLECASE_LETTER) | \ + (1 << JSCT_MODIFIER_LETTER) | \ + (1 << JSCT_OTHER_LETTER) | \ + (1 << JSCT_LETTER_NUMBER) | \ + (1 << JSCT_NON_SPACING_MARK) | \ + (1 << JSCT_COMBINING_SPACING_MARK) | \ + (1 << JSCT_DECIMAL_DIGIT_NUMBER) | \ + (1 << JSCT_CONNECTOR_PUNCTUATION)) \ + >> JS_CTYPE(c)) & 1) + +/* Unicode control-format characters, ignored in input */ +#define JS_ISFORMAT(c) (((1 << JSCT_FORMAT) >> JS_CTYPE(c)) & 1) + +#define JS_ISWORD(c) (JS_ISALNUM(c) || (c) == '_') + +/* XXXbe unify on A/X/Y tbls, avoid ctype.h? */ +#define JS_ISIDENT_START(c) (JS_ISUC_LETTER(c) || (c) == '_' || (c) == '$') +#define JS_ISIDENT(c) (JS_ISID_PART(c) || (c) == '_' || (c) == '$') + +#define JS_ISDIGIT(c) (JS_CTYPE(c) == JSCT_DECIMAL_DIGIT_NUMBER) + +/* XXXbe fs, etc. ? */ +#define JS_ISSPACE(c) ((JS_CCODE(c) & 0x00070000) == 0x00040000) +#define JS_ISPRINT(c) ((c) < 128 && isprint(c)) + +#define JS_ISUPPER(c) (JS_CTYPE(c) == JSCT_UPPERCASE_LETTER) +#define JS_ISLOWER(c) (JS_CTYPE(c) == JSCT_LOWERCASE_LETTER) + +#define JS_TOUPPER(c) ((JS_CCODE(c) & 0x00100000) ? (c) - ((int32)JS_CCODE(c) >> 22) : (c)) +#define JS_TOLOWER(c) ((JS_CCODE(c) & 0x00200000) ? (c) + ((int32)JS_CCODE(c) >> 22) : (c)) + +#define JS_TOCTRL(c) ((c) ^ 64) /* XXX unsafe! requires uppercase c */ + +/* Shorthands for ASCII (7-bit) decimal and hex conversion. */ +#define JS7_ISDEC(c) ((c) < 128 && isdigit(c)) +#define JS7_UNDEC(c) ((c) - '0') +#define JS7_ISHEX(c) ((c) < 128 && isxdigit(c)) +#define JS7_UNHEX(c) (uintN)(isdigit(c) ? (c) - '0' : 10 + tolower(c) - 'a') +#define JS7_ISLET(c) ((c) < 128 && isalpha(c)) + +/* Initialize truly global state associated with JS strings. */ +extern JSBool +js_InitStringGlobals(void); + +extern void +js_FreeStringGlobals(void); + +extern void +js_PurgeDeflatedStringCache(JSString *str); + +/* Initialize per-runtime string state for the first context in the runtime. */ +extern JSBool +js_InitRuntimeStringState(JSContext *cx); + +extern void +js_FinishRuntimeStringState(JSContext *cx); + +/* Initialize the String class, returning its prototype object. */ +extern JSObject * +js_InitStringClass(JSContext *cx, JSObject *obj); + +extern const char js_escape_str[]; +extern const char js_unescape_str[]; +extern const char js_uneval_str[]; +extern const char js_decodeURI_str[]; +extern const char js_encodeURI_str[]; +extern const char js_decodeURIComponent_str[]; +extern const char js_encodeURIComponent_str[]; + +/* GC-allocate a string descriptor for the given malloc-allocated chars. */ +extern JSString * +js_NewString(JSContext *cx, jschar *chars, size_t length, uintN gcflag); + +extern JSString * +js_NewDependentString(JSContext *cx, JSString *base, size_t start, + size_t length, uintN gcflag); + +/* Copy a counted string and GC-allocate a descriptor for it. */ +extern JSString * +js_NewStringCopyN(JSContext *cx, const jschar *s, size_t n, uintN gcflag); + +/* Copy a C string and GC-allocate a descriptor for it. */ +extern JSString * +js_NewStringCopyZ(JSContext *cx, const jschar *s, uintN gcflag); + +/* Free the chars held by str when it is finalized by the GC. */ +extern void +js_FinalizeString(JSContext *cx, JSString *str); + +extern void +js_FinalizeStringRT(JSRuntime *rt, JSString *str); + +/* Wrap a string value in a String object. */ +extern JSObject * +js_StringToObject(JSContext *cx, JSString *str); + +/* + * Convert a value to a string, returning null after reporting an error, + * otherwise returning a new string reference. + */ +extern JSString * +js_ValueToString(JSContext *cx, jsval v); + +/* + * Convert a value to its source expression, returning null after reporting + * an error, otherwise returning a new string reference. + */ +extern JSString * +js_ValueToSource(JSContext *cx, jsval v); + +#ifdef HT_ENUMERATE_NEXT /* XXX don't require jshash.h */ +/* + * Compute a hash function from str. + */ +extern JSHashNumber +js_HashString(JSString *str); +#endif + +/* + * Return less than, equal to, or greater than zero depending on whether + * str1 is less than, equal to, or greater than str2. + */ +extern intN +js_CompareStrings(JSString *str1, JSString *str2); + +/* + * Boyer-Moore-Horspool superlinear search for pat:patlen in text:textlen. + * The patlen argument must be positive and no greater than BMH_PATLEN_MAX. + * The start argument tells where in text to begin the search. + * + * Return the index of pat in text, or -1 if not found. + */ +#define BMH_CHARSET_SIZE 256 /* ISO-Latin-1 */ +#define BMH_PATLEN_MAX 255 /* skip table element is uint8 */ + +#define BMH_BAD_PATTERN (-2) /* return value if pat is not ISO-Latin-1 */ + +extern jsint +js_BoyerMooreHorspool(const jschar *text, jsint textlen, + const jschar *pat, jsint patlen, + jsint start); + +extern size_t +js_strlen(const jschar *s); + +extern jschar * +js_strchr(const jschar *s, jschar c); + +extern jschar * +js_strchr_limit(const jschar *s, jschar c, const jschar *limit); + +#define js_strncpy(t, s, n) memcpy((t), (s), (n) * sizeof(jschar)) + +/* + * Return s advanced past any Unicode white space characters. + */ +extern const jschar * +js_SkipWhiteSpace(const jschar *s); + +/* + * Inflate bytes to JS chars and vice versa. Report out of memory via cx + * and return null on error, otherwise return the jschar or byte vector that + * was JS_malloc'ed. + */ +extern jschar * +js_InflateString(JSContext *cx, const char *bytes, size_t length); + +extern char * +js_DeflateString(JSContext *cx, const jschar *chars, size_t length); + +/* + * Inflate bytes to JS chars into a buffer. + * 'chars' must be large enough for 'length'+1 jschars. + */ +extern void +js_InflateStringToBuffer(jschar *chars, const char *bytes, size_t length); + +/* + * Associate bytes with str in the deflated string cache, returning true on + * successful association, false on out of memory. + */ +extern JSBool +js_SetStringBytes(JSString *str, char *bytes, size_t length); + +/* + * Find or create a deflated string cache entry for str that contains its + * characters chopped from Unicode code points into bytes. + */ +extern char * +js_GetStringBytes(JSString *str); + +JSBool +js_str_escape(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval); + +JS_END_EXTERN_C + +#endif /* jsstr_h___ */ diff --git a/src/extension/script/js/jstypes.h b/src/extension/script/js/jstypes.h new file mode 100644 index 000000000..1709c6461 --- /dev/null +++ b/src/extension/script/js/jstypes.h @@ -0,0 +1,388 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * IBM Corp. + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* +** File: jstypes.h +** Description: Definitions of NSPR's basic types +** +** Prototypes and macros used to make up for deficiencies in ANSI environments +** that we have found. +** +** Since we do not wrap and all the other standard headers, authors +** of portable code will not know in general that they need these definitions. +** Instead of requiring these authors to find the dependent uses in their code +** and take the following steps only in those C files, we take steps once here +** for all C files. +**/ + +#ifndef jstypes_h___ +#define jstypes_h___ + +#include + +/*********************************************************************** +** MACROS: JS_EXTERN_API +** JS_EXPORT_API +** DESCRIPTION: +** These are only for externally visible routines and globals. For +** internal routines, just use "extern" for type checking and that +** will not export internal cross-file or forward-declared symbols. +** Define a macro for declaring procedures return types. We use this to +** deal with windoze specific type hackery for DLL definitions. Use +** JS_EXTERN_API when the prototype for the method is declared. Use +** JS_EXPORT_API for the implementation of the method. +** +** Example: +** in dowhim.h +** JS_EXTERN_API( void ) DoWhatIMean( void ); +** in dowhim.c +** JS_EXPORT_API( void ) DoWhatIMean( void ) { return; } +** +** +***********************************************************************/ +#ifdef WIN32 +/* These also work for __MWERKS__ */ +#define JS_EXTERN_API(__type) extern __declspec(dllexport) __type +#define JS_EXPORT_API(__type) __declspec(dllexport) __type +#define JS_EXTERN_DATA(__type) extern __declspec(dllexport) __type +#define JS_EXPORT_DATA(__type) __declspec(dllexport) __type + +#define JS_DLL_CALLBACK +#define JS_STATIC_DLL_CALLBACK(__x) static __x + +#elif defined(WIN16) + +#ifdef _WINDLL +#define JS_EXTERN_API(__type) extern __type _cdecl _export _loadds +#define JS_EXPORT_API(__type) __type _cdecl _export _loadds +#define JS_EXTERN_DATA(__type) extern __type _export +#define JS_EXPORT_DATA(__type) __type _export + +#define JS_DLL_CALLBACK __cdecl __loadds +#define JS_STATIC_DLL_CALLBACK(__x) static __x CALLBACK + +#else /* this must be .EXE */ +#define JS_EXTERN_API(__type) extern __type _cdecl _export +#define JS_EXPORT_API(__type) __type _cdecl _export +#define JS_EXTERN_DATA(__type) extern __type _export +#define JS_EXPORT_DATA(__type) __type _export + +#define JS_DLL_CALLBACK __cdecl __loadds +#define JS_STATIC_DLL_CALLBACK(__x) __x JS_DLL_CALLBACK +#endif /* _WINDLL */ + +#elif defined(XP_MAC) +#define JS_EXTERN_API(__type) extern __declspec(export) __type +#define JS_EXPORT_API(__type) __declspec(export) __type +#define JS_EXTERN_DATA(__type) extern __declspec(export) __type +#define JS_EXPORT_DATA(__type) __declspec(export) __type + +#define JS_DLL_CALLBACK +#define JS_STATIC_DLL_CALLBACK(__x) static __x + +#else /* Unix */ + +#define JS_EXTERN_API(__type) extern __type +#define JS_EXPORT_API(__type) __type +#define JS_EXTERN_DATA(__type) extern __type +#define JS_EXPORT_DATA(__type) __type + +#define JS_DLL_CALLBACK +#define JS_STATIC_DLL_CALLBACK(__x) static __x + +#endif + +#ifdef _WIN32 +# if defined(__MWERKS__) || defined(__GNUC__) +# define JS_IMPORT_API(__x) __x +# else +# define JS_IMPORT_API(__x) __declspec(dllimport) __x +# endif +#else +# define JS_IMPORT_API(__x) JS_EXPORT_API (__x) +#endif + +#if defined(_WIN32) && !defined(__MWERKS__) &&!defined(__GNUC__) +# define JS_IMPORT_DATA(__x) __declspec(dllimport) __x +#else +# define JS_IMPORT_DATA(__x) __x +#endif + +/* + * The linkage of JS API functions differs depending on whether the file is + * used within the JS library or not. Any source file within the JS + * interpreter should define EXPORT_JS_API whereas any client of the library + * should not. + */ +#ifdef EXPORT_JS_API +#define JS_PUBLIC_API(t) JS_EXPORT_API(t) +#define JS_PUBLIC_DATA(t) JS_EXPORT_DATA(t) +#else +#define JS_PUBLIC_API(t) JS_IMPORT_API(t) +#define JS_PUBLIC_DATA(t) JS_IMPORT_DATA(t) +#endif + +#define JS_FRIEND_API(t) JS_PUBLIC_API(t) +#define JS_FRIEND_DATA(t) JS_PUBLIC_DATA(t) + +#ifdef _WIN32 +# define JS_INLINE __inline +#elif defined(__GNUC__) +# define JS_INLINE +#else +# define JS_INLINE +#endif + +/*********************************************************************** +** MACROS: JS_BEGIN_MACRO +** JS_END_MACRO +** DESCRIPTION: +** Macro body brackets so that macros with compound statement definitions +** behave syntactically more like functions when called. +***********************************************************************/ +#define JS_BEGIN_MACRO do { +#define JS_END_MACRO } while (0) + +/*********************************************************************** +** MACROS: JS_BEGIN_EXTERN_C +** JS_END_EXTERN_C +** DESCRIPTION: +** Macro shorthands for conditional C++ extern block delimiters. +***********************************************************************/ +#ifdef __cplusplus +#define JS_BEGIN_EXTERN_C extern "C" { +#define JS_END_EXTERN_C } +#else +#define JS_BEGIN_EXTERN_C +#define JS_END_EXTERN_C +#endif + +/*********************************************************************** +** MACROS: JS_BIT +** JS_BITMASK +** DESCRIPTION: +** Bit masking macros. XXX n must be <= 31 to be portable +***********************************************************************/ +#define JS_BIT(n) ((JSUint32)1 << (n)) +#define JS_BITMASK(n) (JS_BIT(n) - 1) + +/*********************************************************************** +** MACROS: JS_HOWMANY +** JS_ROUNDUP +** JS_MIN +** JS_MAX +** DESCRIPTION: +** Commonly used macros for operations on compatible types. +***********************************************************************/ +#define JS_HOWMANY(x,y) (((x)+(y)-1)/(y)) +#define JS_ROUNDUP(x,y) (JS_HOWMANY(x,y)*(y)) +#define JS_MIN(x,y) ((x)<(y)?(x):(y)) +#define JS_MAX(x,y) ((x)>(y)?(x):(y)) + +#if (defined(XP_MAC) || defined(XP_WIN)) && !defined(CROSS_COMPILE) +# include "jscpucfg.h" /* Use standard Mac or Windows configuration */ +#elif defined(XP_UNIX) || defined(XP_BEOS) || defined(XP_OS2) || defined(CROSS_COMPILE) +# include "jsautocfg.h" /* Use auto-detected configuration */ +# include "jsosdep.h" /* ...and platform-specific flags */ +#else +# error "Must define one of XP_BEOS, XP_MAC, XP_OS2, XP_WIN or XP_UNIX" +#endif + +JS_BEGIN_EXTERN_C + +/************************************************************************ +** TYPES: JSUint8 +** JSInt8 +** DESCRIPTION: +** The int8 types are known to be 8 bits each. There is no type that +** is equivalent to a plain "char". +************************************************************************/ +#if JS_BYTES_PER_BYTE == 1 +typedef unsigned char JSUint8; +typedef signed char JSInt8; +#else +#error No suitable type for JSInt8/JSUint8 +#endif + +/************************************************************************ +** TYPES: JSUint16 +** JSInt16 +** DESCRIPTION: +** The int16 types are known to be 16 bits each. +************************************************************************/ +#if JS_BYTES_PER_SHORT == 2 +typedef unsigned short JSUint16; +typedef short JSInt16; +#else +#error No suitable type for JSInt16/JSUint16 +#endif + +/************************************************************************ +** TYPES: JSUint32 +** JSInt32 +** DESCRIPTION: +** The int32 types are known to be 32 bits each. +************************************************************************/ +#if JS_BYTES_PER_INT == 4 +typedef unsigned int JSUint32; +typedef int JSInt32; +#define JS_INT32(x) x +#define JS_UINT32(x) x ## U +#elif JS_BYTES_PER_LONG == 4 +typedef unsigned long JSUint32; +typedef long JSInt32; +#define JS_INT32(x) x ## L +#define JS_UINT32(x) x ## UL +#else +#error No suitable type for JSInt32/JSUint32 +#endif + +/************************************************************************ +** TYPES: JSUint64 +** JSInt64 +** DESCRIPTION: +** The int64 types are known to be 64 bits each. Care must be used when +** declaring variables of type JSUint64 or JSInt64. Different hardware +** architectures and even different compilers have varying support for +** 64 bit values. The only guaranteed portability requires the use of +** the JSLL_ macros (see jslong.h). +************************************************************************/ +#ifdef JS_HAVE_LONG_LONG +#if JS_BYTES_PER_LONG == 8 +typedef long JSInt64; +typedef unsigned long JSUint64; +#elif defined(WIN16) +typedef __int64 JSInt64; +typedef unsigned __int64 JSUint64; +#elif defined(WIN32) && !defined(__GNUC__) +typedef __int64 JSInt64; +typedef unsigned __int64 JSUint64; +#else +typedef long long JSInt64; +typedef unsigned long long JSUint64; +#endif /* JS_BYTES_PER_LONG == 8 */ +#else /* !JS_HAVE_LONG_LONG */ +typedef struct { +#ifdef IS_LITTLE_ENDIAN + JSUint32 lo, hi; +#else + JSUint32 hi, lo; +#endif +} JSInt64; +typedef JSInt64 JSUint64; +#endif /* !JS_HAVE_LONG_LONG */ + +/************************************************************************ +** TYPES: JSUintn +** JSIntn +** DESCRIPTION: +** The JSIntn types are most appropriate for automatic variables. They are +** guaranteed to be at least 16 bits, though various architectures may +** define them to be wider (e.g., 32 or even 64 bits). These types are +** never valid for fields of a structure. +************************************************************************/ +#if JS_BYTES_PER_INT >= 2 +typedef int JSIntn; +typedef unsigned int JSUintn; +#else +#error 'sizeof(int)' not sufficient for platform use +#endif + +/************************************************************************ +** TYPES: JSFloat64 +** DESCRIPTION: +** NSPR's floating point type is always 64 bits. +************************************************************************/ +typedef double JSFloat64; + +/************************************************************************ +** TYPES: JSSize +** DESCRIPTION: +** A type for representing the size of objects. +************************************************************************/ +typedef size_t JSSize; + +/************************************************************************ +** TYPES: JSPtrDiff +** DESCRIPTION: +** A type for pointer difference. Variables of this type are suitable +** for storing a pointer or pointer sutraction. +************************************************************************/ +typedef ptrdiff_t JSPtrdiff; + +/************************************************************************ +** TYPES: JSUptrdiff +** DESCRIPTION: +** A type for pointer difference. Variables of this type are suitable +** for storing a pointer or pointer sutraction. +************************************************************************/ +typedef unsigned long JSUptrdiff; + +/************************************************************************ +** TYPES: JSBool +** DESCRIPTION: +** Use JSBool for variables and parameter types. Use JS_FALSE and JS_TRUE +** for clarity of target type in assignments and actual arguments. Use +** 'if (bool)', 'while (!bool)', '(bool) ? x : y' etc., to test booleans +** just as you would C int-valued conditions. +************************************************************************/ +typedef JSIntn JSBool; +#define JS_TRUE (JSIntn)1 +#define JS_FALSE (JSIntn)0 + +/************************************************************************ +** TYPES: JSPackedBool +** DESCRIPTION: +** Use JSPackedBool within structs where bitfields are not desireable +** but minimum and consistant overhead matters. +************************************************************************/ +typedef JSUint8 JSPackedBool; + +/* +** A JSWord is an integer that is the same size as a void* +*/ +typedef long JSWord; +typedef unsigned long JSUword; + +#include "jsotypes.h" + +JS_END_EXTERN_C + +#endif /* jstypes_h___ */ + diff --git a/src/extension/script/js/jsutil.c b/src/extension/script/js/jsutil.c new file mode 100644 index 000000000..f64718ad4 --- /dev/null +++ b/src/extension/script/js/jsutil.c @@ -0,0 +1,157 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * IBM Corp. + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* + * PR assertion checker. + */ +#include "jsstddef.h" +#include +#include +#include "jstypes.h" +#include "jsutil.h" + +#ifdef WIN32 +# include +#endif + +#ifdef XP_MAC +# include +# include +# include "jsprf.h" +#endif + +#ifdef XP_MAC +/* + * PStrFromCStr converts the source C string to a destination + * pascal string as it copies. The dest string will + * be truncated to fit into an Str255 if necessary. + * If the C String pointer is NULL, the pascal string's length is + * set to zero. + */ +static void PStrFromCStr(const char* src, Str255 dst) +{ + short length = 0; + + /* handle case of overlapping strings */ + if ( (void*)src == (void*)dst ) + { + unsigned char* curdst = &dst[1]; + unsigned char thisChar; + + thisChar = *(const unsigned char*)src++; + while ( thisChar != '\0' ) + { + unsigned char nextChar; + + /* + * Use nextChar so we don't overwrite what we + * are about to read + */ + nextChar = *(const unsigned char*)src++; + *curdst++ = thisChar; + thisChar = nextChar; + + if ( ++length >= 255 ) + break; + } + } + else if ( src != NULL ) + { + unsigned char* curdst = &dst[1]; + /* count down so test it loop is faster */ + short overflow = 255; + register char temp; + + /* + * Can't do the K&R C thing of while (*s++ = *t++) + * because it will copy trailing zero which might + * overrun pascal buffer. Instead we use a temp variable. + */ + while ( (temp = *src++) != 0 ) + { + *(char*)curdst++ = temp; + + if ( --overflow <= 0 ) + break; + } + length = 255 - overflow; + } + dst[0] = length; +} + +static void jsdebugstr(const char *debuggerMsg) +{ + Str255 pStr; + + PStrFromCStr(debuggerMsg, pStr); + DebugStr(pStr); +} + +static void dprintf(const char *format, ...) +{ + va_list ap; + char *buffer; + + va_start(ap, format); + buffer = (char *)JS_vsmprintf(format, ap); + va_end(ap); + + jsdebugstr(buffer); + JS_DELETE(buffer); +} +#endif /* XP_MAC */ + +JS_PUBLIC_API(void) JS_Assert(const char *s, const char *file, JSIntn ln) +{ +#ifdef XP_MAC + dprintf("Assertion failure: %s, at %s:%d\n", s, file, ln); +#else + fprintf(stderr, "Assertion failure: %s, at %s:%d\n", s, file, ln); +#endif +#if defined(WIN32) + DebugBreak(); +#endif +#if defined(XP_OS2) + asm("int $3"); +#endif +#ifndef XP_MAC + abort(); +#endif +} diff --git a/src/extension/script/js/jsutil.h b/src/extension/script/js/jsutil.h new file mode 100644 index 000000000..d4edb919c --- /dev/null +++ b/src/extension/script/js/jsutil.h @@ -0,0 +1,106 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* + * PR assertion checker. + */ + +#ifndef jsutil_h___ +#define jsutil_h___ + +JS_BEGIN_EXTERN_C + +/*********************************************************************** +** FUNCTION: JS_MALLOC() +** DESCRIPTION: +** JS_NEW() allocates an untyped item of size _size from the heap. +** INPUTS: _size: size in bytes of item to be allocated +** OUTPUTS: untyped pointer to the node allocated +** RETURN: pointer to node or error returned from malloc(). +***********************************************************************/ +#define JS_MALLOC(_bytes) (malloc((_bytes))) + +/*********************************************************************** +** FUNCTION: JS_DELETE() +** DESCRIPTION: +** JS_DELETE() unallocates an object previosly allocated via JS_NEW() +** or JS_NEWZAP() to the heap. +** INPUTS: pointer to previously allocated object +** OUTPUTS: the referenced object is returned to the heap +** RETURN: void +***********************************************************************/ +#define JS_DELETE(_ptr) { free(_ptr); (_ptr) = NULL; } + +/*********************************************************************** +** FUNCTION: JS_NEW() +** DESCRIPTION: +** JS_NEW() allocates an item of type _struct from the heap. +** INPUTS: _struct: a data type +** OUTPUTS: pointer to _struct +** RETURN: pointer to _struct or error returns from malloc(). +***********************************************************************/ +#define JS_NEW(_struct) ((_struct *) JS_MALLOC(sizeof(_struct))) + +#ifdef DEBUG + +extern JS_PUBLIC_API(void) +JS_Assert(const char *s, const char *file, JSIntn ln); +#define JS_ASSERT(_expr) \ + ((_expr)?((void)0):JS_Assert(# _expr,__FILE__,__LINE__)) + +#define JS_NOT_REACHED(_reasonStr) \ + JS_Assert(_reasonStr,__FILE__,__LINE__) + +#else + +#define JS_ASSERT(expr) ((void) 0) +#define JS_NOT_REACHED(reasonStr) + +#endif /* defined(DEBUG) */ + +/* +** Abort the process in a non-graceful manner. This will cause a core file, +** call to the debugger or other moral equivalent as well as causing the +** entire process to stop. +*/ +extern JS_PUBLIC_API(void) JS_Abort(void); + +JS_END_EXTERN_C + +#endif /* jsutil_h___ */ diff --git a/src/extension/script/js/jsxdrapi.c b/src/extension/script/js/jsxdrapi.c new file mode 100644 index 000000000..1b092924d --- /dev/null +++ b/src/extension/script/js/jsxdrapi.c @@ -0,0 +1,690 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ +#include "jsstddef.h" +#include "jsconfig.h" + +#if JS_HAS_XDR + +#include +#include "jstypes.h" +#include "jsutil.h" /* Added by JSIFY */ +#include "jsdhash.h" +#include "jsprf.h" +#include "jsapi.h" +#include "jscntxt.h" +#include "jsobj.h" /* js_XDRObject */ +#include "jsscript.h" /* js_XDRScript */ +#include "jsstr.h" +#include "jsxdrapi.h" + +#ifdef DEBUG +#define DBG(x) x +#else +#define DBG(x) ((void)0) +#endif + +typedef struct JSXDRMemState { + JSXDRState state; + char *base; + uint32 count; + uint32 limit; +} JSXDRMemState; + +#define MEM_BLOCK 8192 +#define MEM_PRIV(xdr) ((JSXDRMemState *)(xdr)) + +#define MEM_BASE(xdr) (MEM_PRIV(xdr)->base) +#define MEM_COUNT(xdr) (MEM_PRIV(xdr)->count) +#define MEM_LIMIT(xdr) (MEM_PRIV(xdr)->limit) + +#define MEM_LEFT(xdr, bytes) \ + JS_BEGIN_MACRO \ + if ((xdr)->mode == JSXDR_DECODE && \ + MEM_COUNT(xdr) + bytes > MEM_LIMIT(xdr)) { \ + JS_ReportErrorNumber((xdr)->cx, js_GetErrorMessage, NULL, \ + JSMSG_END_OF_DATA); \ + return 0; \ + } \ + JS_END_MACRO + +#define MEM_NEED(xdr, bytes) \ + JS_BEGIN_MACRO \ + if ((xdr)->mode == JSXDR_ENCODE) { \ + if (MEM_LIMIT(xdr) && \ + MEM_COUNT(xdr) + bytes > MEM_LIMIT(xdr)) { \ + uint32 limit_ = JS_ROUNDUP(MEM_COUNT(xdr) + bytes, MEM_BLOCK);\ + void *data_ = JS_realloc((xdr)->cx, MEM_BASE(xdr), limit_); \ + if (!data_) \ + return 0; \ + MEM_BASE(xdr) = data_; \ + MEM_LIMIT(xdr) = limit_; \ + } \ + } else { \ + MEM_LEFT(xdr, bytes); \ + } \ + JS_END_MACRO + +#define MEM_DATA(xdr) ((void *)(MEM_BASE(xdr) + MEM_COUNT(xdr))) +#define MEM_INCR(xdr,bytes) (MEM_COUNT(xdr) += (bytes)) + +static JSBool +mem_get32(JSXDRState *xdr, uint32 *lp) +{ + MEM_LEFT(xdr, 4); + *lp = *(uint32 *)MEM_DATA(xdr); + MEM_INCR(xdr, 4); + return JS_TRUE; +} + +static JSBool +mem_set32(JSXDRState *xdr, uint32 *lp) +{ + MEM_NEED(xdr, 4); + *(uint32 *)MEM_DATA(xdr) = *lp; + MEM_INCR(xdr, 4); + return JS_TRUE; +} + +static JSBool +mem_getbytes(JSXDRState *xdr, char *bytes, uint32 len) +{ + MEM_LEFT(xdr, len); + memcpy(bytes, MEM_DATA(xdr), len); + MEM_INCR(xdr, len); + return JS_TRUE; +} + +static JSBool +mem_setbytes(JSXDRState *xdr, char *bytes, uint32 len) +{ + MEM_NEED(xdr, len); + memcpy(MEM_DATA(xdr), bytes, len); + MEM_INCR(xdr, len); + return JS_TRUE; +} + +static void * +mem_raw(JSXDRState *xdr, uint32 len) +{ + void *data; + if (xdr->mode == JSXDR_ENCODE) { + MEM_NEED(xdr, len); + } else if (xdr->mode == JSXDR_DECODE) { + MEM_LEFT(xdr, len); + } + data = MEM_DATA(xdr); + MEM_INCR(xdr, len); + return data; +} + +static JSBool +mem_seek(JSXDRState *xdr, int32 offset, JSXDRWhence whence) +{ + switch (whence) { + case JSXDR_SEEK_CUR: + if ((int32)MEM_COUNT(xdr) + offset < 0) { + JS_ReportErrorNumber(xdr->cx, js_GetErrorMessage, NULL, + JSMSG_SEEK_BEYOND_START); + return JS_FALSE; + } + if (offset > 0) + MEM_NEED(xdr, offset); + MEM_COUNT(xdr) += offset; + return JS_TRUE; + case JSXDR_SEEK_SET: + if (offset < 0) { + JS_ReportErrorNumber(xdr->cx, js_GetErrorMessage, NULL, + JSMSG_SEEK_BEYOND_START); + return JS_FALSE; + } + if (xdr->mode == JSXDR_ENCODE) { + if ((uint32)offset > MEM_COUNT(xdr)) + MEM_NEED(xdr, offset - MEM_COUNT(xdr)); + MEM_COUNT(xdr) = offset; + } else { + if ((uint32)offset > MEM_LIMIT(xdr)) { + JS_ReportErrorNumber(xdr->cx, js_GetErrorMessage, NULL, + JSMSG_SEEK_BEYOND_END); + return JS_FALSE; + } + MEM_COUNT(xdr) = offset; + } + return JS_TRUE; + case JSXDR_SEEK_END: + if (offset >= 0 || + xdr->mode == JSXDR_ENCODE || + (int32)MEM_LIMIT(xdr) + offset < 0) { + JS_ReportErrorNumber(xdr->cx, js_GetErrorMessage, NULL, + JSMSG_END_SEEK); + return JS_FALSE; + } + MEM_COUNT(xdr) = MEM_LIMIT(xdr) + offset; + return JS_TRUE; + default: { + char numBuf[12]; + JS_snprintf(numBuf, sizeof numBuf, "%d", whence); + JS_ReportErrorNumber(xdr->cx, js_GetErrorMessage, NULL, + JSMSG_WHITHER_WHENCE, numBuf); + return JS_FALSE; + } + } +} + +static uint32 +mem_tell(JSXDRState *xdr) +{ + return MEM_COUNT(xdr); +} + +static void +mem_finalize(JSXDRState *xdr) +{ + JS_free(xdr->cx, MEM_BASE(xdr)); +} + +static JSXDROps xdrmem_ops = { + mem_get32, mem_set32, mem_getbytes, mem_setbytes, + mem_raw, mem_seek, mem_tell, mem_finalize +}; + +JS_PUBLIC_API(void) +JS_XDRInitBase(JSXDRState *xdr, JSXDRMode mode, JSContext *cx) +{ + xdr->mode = mode; + xdr->cx = cx; + xdr->registry = NULL; + xdr->numclasses = xdr->maxclasses = 0; + xdr->reghash = NULL; + xdr->userdata = NULL; +} + +JS_PUBLIC_API(JSXDRState *) +JS_XDRNewMem(JSContext *cx, JSXDRMode mode) +{ + JSXDRState *xdr = (JSXDRState *) JS_malloc(cx, sizeof(JSXDRMemState)); + if (!xdr) + return NULL; + JS_XDRInitBase(xdr, mode, cx); + if (mode == JSXDR_ENCODE) { + if (!(MEM_BASE(xdr) = JS_malloc(cx, MEM_BLOCK))) { + JS_free(cx, xdr); + return NULL; + } + } else { + /* XXXbe ok, so better not deref MEM_BASE(xdr) if not ENCODE */ + MEM_BASE(xdr) = NULL; + } + xdr->ops = &xdrmem_ops; + MEM_COUNT(xdr) = 0; + MEM_LIMIT(xdr) = MEM_BLOCK; + return xdr; +} + +JS_PUBLIC_API(void *) +JS_XDRMemGetData(JSXDRState *xdr, uint32 *lp) +{ + if (xdr->ops != &xdrmem_ops) + return NULL; + *lp = MEM_COUNT(xdr); + return MEM_BASE(xdr); +} + +JS_PUBLIC_API(void) +JS_XDRMemSetData(JSXDRState *xdr, void *data, uint32 len) +{ + if (xdr->ops != &xdrmem_ops) + return; + MEM_LIMIT(xdr) = len; + MEM_BASE(xdr) = data; + MEM_COUNT(xdr) = 0; +} + +JS_PUBLIC_API(uint32) +JS_XDRMemDataLeft(JSXDRState *xdr) +{ + if (xdr->ops != &xdrmem_ops) + return 0; + return MEM_LIMIT(xdr) - MEM_COUNT(xdr); +} + +JS_PUBLIC_API(void) +JS_XDRMemResetData(JSXDRState *xdr) +{ + if (xdr->ops != &xdrmem_ops) + return; + MEM_COUNT(xdr) = 0; +} + +JS_PUBLIC_API(void) +JS_XDRDestroy(JSXDRState *xdr) +{ + JSContext *cx = xdr->cx; + xdr->ops->finalize(xdr); + if (xdr->registry) { + JS_free(cx, xdr->registry); + if (xdr->reghash) + JS_DHashTableDestroy(xdr->reghash); + } + JS_free(cx, xdr); +} + +JS_PUBLIC_API(JSBool) +JS_XDRUint8(JSXDRState *xdr, uint8 *b) +{ + uint32 l = *b; + if (!JS_XDRUint32(xdr, &l)) + return JS_FALSE; + *b = (uint8) l; + return JS_TRUE; +} + +JS_PUBLIC_API(JSBool) +JS_XDRUint16(JSXDRState *xdr, uint16 *s) +{ + uint32 l = *s; + if (!JS_XDRUint32(xdr, &l)) + return JS_FALSE; + *s = (uint16) l; + return JS_TRUE; +} + +JS_PUBLIC_API(JSBool) +JS_XDRUint32(JSXDRState *xdr, uint32 *lp) +{ + JSBool ok = JS_TRUE; + if (xdr->mode == JSXDR_ENCODE) { + uint32 xl = JSXDR_SWAB32(*lp); + ok = xdr->ops->set32(xdr, &xl); + } else if (xdr->mode == JSXDR_DECODE) { + ok = xdr->ops->get32(xdr, lp); + *lp = JSXDR_SWAB32(*lp); + } + return ok; +} + +JS_PUBLIC_API(JSBool) +JS_XDRBytes(JSXDRState *xdr, char *bytes, uint32 len) +{ + uint32 padlen; + static char padbuf[JSXDR_ALIGN-1]; + + if (xdr->mode == JSXDR_ENCODE) { + if (!xdr->ops->setbytes(xdr, bytes, len)) + return JS_FALSE; + } else { + if (!xdr->ops->getbytes(xdr, bytes, len)) + return JS_FALSE; + } + len = xdr->ops->tell(xdr); + if (len % JSXDR_ALIGN) { + padlen = JSXDR_ALIGN - (len % JSXDR_ALIGN); + if (xdr->mode == JSXDR_ENCODE) { + if (!xdr->ops->setbytes(xdr, padbuf, padlen)) + return JS_FALSE; + } else { + if (!xdr->ops->seek(xdr, padlen, JSXDR_SEEK_CUR)) + return JS_FALSE; + } + } + return JS_TRUE; +} + +/** + * Convert between a C string and the XDR representation: + * leading 32-bit count, then counted vector of chars, + * then possibly \0 padding to multiple of 4. + */ +JS_PUBLIC_API(JSBool) +JS_XDRCString(JSXDRState *xdr, char **sp) +{ + uint32 len; + + if (xdr->mode == JSXDR_ENCODE) + len = strlen(*sp); + JS_XDRUint32(xdr, &len); + if (xdr->mode == JSXDR_DECODE) { + if (!(*sp = (char *) JS_malloc(xdr->cx, len + 1))) + return JS_FALSE; + } + if (!JS_XDRBytes(xdr, *sp, len)) { + if (xdr->mode == JSXDR_DECODE) + JS_free(xdr->cx, *sp); + return JS_FALSE; + } + if (xdr->mode == JSXDR_DECODE) { + (*sp)[len] = '\0'; + } else if (xdr->mode == JSXDR_FREE) { + JS_free(xdr->cx, *sp); + *sp = NULL; + } + return JS_TRUE; +} + +JS_PUBLIC_API(JSBool) +JS_XDRCStringOrNull(JSXDRState *xdr, char **sp) +{ + uint32 null = (*sp == NULL); + if (!JS_XDRUint32(xdr, &null)) + return JS_FALSE; + if (null) { + *sp = NULL; + return JS_TRUE; + } + return JS_XDRCString(xdr, sp); +} + +/* + * Convert between a JS (Unicode) string and the XDR representation. + */ +JS_PUBLIC_API(JSBool) +JS_XDRString(JSXDRState *xdr, JSString **strp) +{ + uint32 i, len, padlen, nbytes; + jschar *chars = NULL, *raw; + + if (xdr->mode == JSXDR_ENCODE) + len = JSSTRING_LENGTH(*strp); + if (!JS_XDRUint32(xdr, &len)) + return JS_FALSE; + nbytes = len * sizeof(jschar); + + if (xdr->mode == JSXDR_DECODE) { + if (!(chars = (jschar *) JS_malloc(xdr->cx, nbytes + sizeof(jschar)))) + return JS_FALSE; + } else { + chars = JSSTRING_CHARS(*strp); + } + + padlen = nbytes % JSXDR_ALIGN; + if (padlen) { + padlen = JSXDR_ALIGN - padlen; + nbytes += padlen; + } + if (!(raw = (jschar *) xdr->ops->raw(xdr, nbytes))) + goto bad; + if (xdr->mode == JSXDR_ENCODE) { + for (i = 0; i < len; i++) + raw[i] = JSXDR_SWAB16(chars[i]); + if (padlen) + memset((char *)raw + nbytes - padlen, 0, padlen); + } else if (xdr->mode == JSXDR_DECODE) { + for (i = 0; i < len; i++) + chars[i] = JSXDR_SWAB16(raw[i]); + chars[len] = 0; + + if (!(*strp = JS_NewUCString(xdr->cx, chars, len))) + goto bad; + } + return JS_TRUE; + +bad: + if (xdr->mode == JSXDR_DECODE) + JS_free(xdr->cx, chars); + return JS_FALSE; +} + +JS_PUBLIC_API(JSBool) +JS_XDRStringOrNull(JSXDRState *xdr, JSString **strp) +{ + uint32 null = (*strp == NULL); + if (!JS_XDRUint32(xdr, &null)) + return JS_FALSE; + if (null) { + *strp = NULL; + return JS_TRUE; + } + return JS_XDRString(xdr, strp); +} + +JS_PUBLIC_API(JSBool) +JS_XDRDouble(JSXDRState *xdr, jsdouble **dp) +{ + jsdouble d; + if (xdr->mode == JSXDR_ENCODE) + d = **dp; +#if IS_BIG_ENDIAN + if (!JS_XDRUint32(xdr, (uint32 *)&d + 1) || + !JS_XDRUint32(xdr, (uint32 *)&d)) +#else + if (!JS_XDRUint32(xdr, (uint32 *)&d) || + !JS_XDRUint32(xdr, (uint32 *)&d + 1)) +#endif + return JS_FALSE; + if (xdr->mode == JSXDR_DECODE) { + *dp = JS_NewDouble(xdr->cx, d); + if (!*dp) + return JS_FALSE; + } + return JS_TRUE; +} + +/* These are magic pseudo-tags: see jsapi.h, near the top, for real tags. */ +#define JSVAL_XDRNULL 0x8 +#define JSVAL_XDRVOID 0xA + +JS_PUBLIC_API(JSBool) +JS_XDRValue(JSXDRState *xdr, jsval *vp) +{ + uint32 type; + + if (xdr->mode == JSXDR_ENCODE) { + if (JSVAL_IS_NULL(*vp)) + type = JSVAL_XDRNULL; + else if (JSVAL_IS_VOID(*vp)) + type = JSVAL_XDRVOID; + else + type = JSVAL_TAG(*vp); + } + if (!JS_XDRUint32(xdr, &type)) + return JS_FALSE; + + switch (type) { + case JSVAL_XDRNULL: + *vp = JSVAL_NULL; + break; + case JSVAL_XDRVOID: + *vp = JSVAL_VOID; + break; + case JSVAL_STRING: { + JSString *str; + if (xdr->mode == JSXDR_ENCODE) + str = JSVAL_TO_STRING(*vp); + if (!JS_XDRString(xdr, &str)) + return JS_FALSE; + if (xdr->mode == JSXDR_DECODE) + *vp = STRING_TO_JSVAL(str); + break; + } + case JSVAL_DOUBLE: { + jsdouble *dp; + if (xdr->mode == JSXDR_ENCODE) + dp = JSVAL_TO_DOUBLE(*vp); + if (!JS_XDRDouble(xdr, &dp)) + return JS_FALSE; + if (xdr->mode == JSXDR_DECODE) + *vp = DOUBLE_TO_JSVAL(dp); + break; + } + case JSVAL_OBJECT: { + JSObject *obj; + if (xdr->mode == JSXDR_ENCODE) + obj = JSVAL_TO_OBJECT(*vp); + if (!js_XDRObject(xdr, &obj)) + return JS_FALSE; + if (xdr->mode == JSXDR_DECODE) + *vp = OBJECT_TO_JSVAL(obj); + break; + } + case JSVAL_BOOLEAN: { + uint32 b; + if (xdr->mode == JSXDR_ENCODE) + b = (uint32) JSVAL_TO_BOOLEAN(*vp); + if (!JS_XDRUint32(xdr, &b)) + return JS_FALSE; + if (xdr->mode == JSXDR_DECODE) + *vp = BOOLEAN_TO_JSVAL((JSBool) b); + break; + } + default: { + uint32 i; + + JS_ASSERT(type & JSVAL_INT); + if (xdr->mode == JSXDR_ENCODE) + i = (uint32) JSVAL_TO_INT(*vp); + if (!JS_XDRUint32(xdr, &i)) + return JS_FALSE; + if (xdr->mode == JSXDR_DECODE) + *vp = INT_TO_JSVAL((int32) i); + break; + } + } + return JS_TRUE; +} + +JS_PUBLIC_API(JSBool) +JS_XDRScript(JSXDRState *xdr, JSScript **scriptp) +{ + if (!js_XDRScript(xdr, scriptp, NULL)) + return JS_FALSE; + if (xdr->mode == JSXDR_DECODE) + js_CallNewScriptHook(xdr->cx, *scriptp, NULL); + return JS_TRUE; +} + +#define CLASS_REGISTRY_MIN 8 +#define CLASS_INDEX_TO_ID(i) ((i)+1) +#define CLASS_ID_TO_INDEX(id) ((id)-1) + +typedef struct JSRegHashEntry { + JSDHashEntryHdr hdr; + const char *name; + uint32 index; +} JSRegHashEntry; + +JS_PUBLIC_API(JSBool) +JS_XDRRegisterClass(JSXDRState *xdr, JSClass *clasp, uint32 *idp) +{ + uintN numclasses, maxclasses; + JSClass **registry; + + numclasses = xdr->numclasses; + maxclasses = xdr->maxclasses; + if (numclasses == maxclasses) { + maxclasses = (maxclasses == 0) ? CLASS_REGISTRY_MIN : maxclasses << 1; + registry = (JSClass **) + JS_realloc(xdr->cx, xdr->registry, maxclasses * sizeof(JSClass *)); + if (!registry) + return JS_FALSE; + xdr->registry = registry; + xdr->maxclasses = maxclasses; + } else { + JS_ASSERT(numclasses && numclasses < maxclasses); + registry = xdr->registry; + } + + registry[numclasses] = clasp; + if (xdr->reghash) { + JSRegHashEntry *entry = (JSRegHashEntry *) + JS_DHashTableOperate(xdr->reghash, clasp->name, JS_DHASH_ADD); + if (!entry) { + JS_ReportOutOfMemory(xdr->cx); + return JS_FALSE; + } + entry->name = clasp->name; + entry->index = numclasses; + } + *idp = CLASS_INDEX_TO_ID(numclasses); + xdr->numclasses = ++numclasses; + return JS_TRUE; +} + +JS_PUBLIC_API(uint32) +JS_XDRFindClassIdByName(JSXDRState *xdr, const char *name) +{ + uintN i, numclasses; + + numclasses = xdr->numclasses; + if (numclasses >= 10) { + JSRegHashEntry *entry; + + /* Bootstrap reghash from registry on first overpopulated Find. */ + if (!xdr->reghash) { + xdr->reghash = JS_NewDHashTable(JS_DHashGetStubOps(), NULL, + sizeof(JSRegHashEntry), + numclasses); + if (xdr->reghash) { + for (i = 0; i < numclasses; i++) { + JSClass *clasp = xdr->registry[i]; + entry = (JSRegHashEntry *) + JS_DHashTableOperate(xdr->reghash, clasp->name, + JS_DHASH_ADD); + entry->name = clasp->name; + entry->index = i; + } + } + } + + /* If we managed to create reghash, use it for O(1) Find. */ + if (xdr->reghash) { + entry = (JSRegHashEntry *) + JS_DHashTableOperate(xdr->reghash, name, JS_DHASH_LOOKUP); + if (JS_DHASH_ENTRY_IS_BUSY(&entry->hdr)) + return CLASS_INDEX_TO_ID(entry->index); + } + } + + /* Only a few classes, or we couldn't malloc reghash: use linear search. */ + for (i = 0; i < numclasses; i++) { + if (!strcmp(name, xdr->registry[i]->name)) + return CLASS_INDEX_TO_ID(i); + } + return 0; +} + +JS_PUBLIC_API(JSClass *) +JS_XDRFindClassById(JSXDRState *xdr, uint32 id) +{ + uintN i = CLASS_ID_TO_INDEX(id); + + if (i >= xdr->numclasses) + return NULL; + return xdr->registry[i]; +} + +#endif /* JS_HAS_XDR */ diff --git a/src/extension/script/js/jsxdrapi.h b/src/extension/script/js/jsxdrapi.h new file mode 100644 index 000000000..874a62eeb --- /dev/null +++ b/src/extension/script/js/jsxdrapi.h @@ -0,0 +1,193 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef jsxdrapi_h___ +#define jsxdrapi_h___ + +/* + * JS external data representation interface API. + * + * The XDR system is comprised of three major parts: + * + * - the state serialization/deserialization APIs, which allow consumers + * of the API to serialize JS runtime state (script bytecodes, atom maps, + * object graphs, etc.) for later restoration. These portions + * are implemented in various appropriate files, such as jsscript.c + * for the script portions and jsobj.c for object state. + * - the callback APIs through which the runtime requests an opaque + * representation of a native object, and through which the runtime + * constructs a live native object from an opaque representation. These + * portions are the responsibility of the native object implementor. + * - utility functions for en/decoding of primitive types, such as + * JSStrings. This portion is implemented in jsxdrapi.c. + * + * Spiritually guided by Sun's XDR, where appropriate. + */ + +#include "jspubtd.h" +#include "jsprvtd.h" + +JS_BEGIN_EXTERN_C + +/* We use little-endian byteorder for all encoded data */ + +#if defined IS_LITTLE_ENDIAN +#define JSXDR_SWAB32(x) x +#define JSXDR_SWAB16(x) x +#elif defined IS_BIG_ENDIAN +#define JSXDR_SWAB32(x) (((uint32)(x) >> 24) | \ + (((uint32)(x) >> 8) & 0xff00) | \ + (((uint32)(x) << 8) & 0xff0000) | \ + ((uint32)(x) << 24)) +#define JSXDR_SWAB16(x) (((uint16)(x) >> 8) | ((uint16)(x) << 8)) +#else +#error "unknown byte order" +#endif + +#define JSXDR_ALIGN 4 + +typedef enum JSXDRMode { + JSXDR_ENCODE, + JSXDR_DECODE, + JSXDR_FREE +} JSXDRMode; + +typedef enum JSXDRWhence { + JSXDR_SEEK_SET, + JSXDR_SEEK_CUR, + JSXDR_SEEK_END +} JSXDRWhence; + +typedef struct JSXDROps { + JSBool (*get32)(JSXDRState *, uint32 *); + JSBool (*set32)(JSXDRState *, uint32 *); + JSBool (*getbytes)(JSXDRState *, char *, uint32); + JSBool (*setbytes)(JSXDRState *, char *, uint32); + void * (*raw)(JSXDRState *, uint32); + JSBool (*seek)(JSXDRState *, int32, JSXDRWhence); + uint32 (*tell)(JSXDRState *); + void (*finalize)(JSXDRState *); +} JSXDROps; + +struct JSXDRState { + JSXDRMode mode; + JSXDROps *ops; + JSContext *cx; + JSClass **registry; + uintN numclasses; + uintN maxclasses; + void *reghash; + void *userdata; +}; + +extern JS_PUBLIC_API(void) +JS_XDRInitBase(JSXDRState *xdr, JSXDRMode mode, JSContext *cx); + +extern JS_PUBLIC_API(JSXDRState *) +JS_XDRNewMem(JSContext *cx, JSXDRMode mode); + +extern JS_PUBLIC_API(void *) +JS_XDRMemGetData(JSXDRState *xdr, uint32 *lp); + +extern JS_PUBLIC_API(void) +JS_XDRMemSetData(JSXDRState *xdr, void *data, uint32 len); + +extern JS_PUBLIC_API(uint32) +JS_XDRMemDataLeft(JSXDRState *xdr); + +extern JS_PUBLIC_API(void) +JS_XDRMemResetData(JSXDRState *xdr); + +extern JS_PUBLIC_API(void) +JS_XDRDestroy(JSXDRState *xdr); + +extern JS_PUBLIC_API(JSBool) +JS_XDRUint8(JSXDRState *xdr, uint8 *b); + +extern JS_PUBLIC_API(JSBool) +JS_XDRUint16(JSXDRState *xdr, uint16 *s); + +extern JS_PUBLIC_API(JSBool) +JS_XDRUint32(JSXDRState *xdr, uint32 *lp); + +extern JS_PUBLIC_API(JSBool) +JS_XDRBytes(JSXDRState *xdr, char *bytes, uint32 len); + +extern JS_PUBLIC_API(JSBool) +JS_XDRCString(JSXDRState *xdr, char **sp); + +extern JS_PUBLIC_API(JSBool) +JS_XDRCStringOrNull(JSXDRState *xdr, char **sp); + +extern JS_PUBLIC_API(JSBool) +JS_XDRString(JSXDRState *xdr, JSString **strp); + +extern JS_PUBLIC_API(JSBool) +JS_XDRStringOrNull(JSXDRState *xdr, JSString **strp); + +extern JS_PUBLIC_API(JSBool) +JS_XDRDouble(JSXDRState *xdr, jsdouble **dp); + +extern JS_PUBLIC_API(JSBool) +JS_XDRValue(JSXDRState *xdr, jsval *vp); + +extern JS_PUBLIC_API(JSBool) +JS_XDRScript(JSXDRState *xdr, JSScript **scriptp); + +extern JS_PUBLIC_API(JSBool) +JS_XDRRegisterClass(JSXDRState *xdr, JSClass *clasp, uint32 *lp); + +extern JS_PUBLIC_API(uint32) +JS_XDRFindClassIdByName(JSXDRState *xdr, const char *name); + +extern JS_PUBLIC_API(JSClass *) +JS_XDRFindClassById(JSXDRState *xdr, uint32 id); + +/* + * Magic numbers. + */ +#define JSXDR_MAGIC_SCRIPT_1 0xdead0001 +#define JSXDR_MAGIC_SCRIPT_2 0xdead0002 +#define JSXDR_MAGIC_SCRIPT_3 0xdead0003 +#define JSXDR_MAGIC_SCRIPT_4 0xdead0004 +#define JSXDR_MAGIC_SCRIPT_CURRENT JSXDR_MAGIC_SCRIPT_4 + +JS_END_EXTERN_C + +#endif /* ! jsxdrapi_h___ */ diff --git a/src/extension/script/js/prmjtime.c b/src/extension/script/js/prmjtime.c new file mode 100644 index 000000000..0a53f76bf --- /dev/null +++ b/src/extension/script/js/prmjtime.c @@ -0,0 +1,646 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* + * PR time code. + */ +#include "jsstddef.h" +#ifdef SOLARIS +#define _REENTRANT 1 +#endif +#include +#include +#include "jstypes.h" +#include "jsutil.h" + +#include "jsprf.h" +#include "prmjtime.h" + +#define PRMJ_DO_MILLISECONDS 1 + +#ifdef XP_OS2 +#include +#endif +#ifdef XP_WIN +#include +#include +#endif + +#ifdef XP_MAC +#include +#include +#include +#include +#include +#include +#include +#if !TARGET_CARBON +#include +#endif +#endif + +#if defined(XP_UNIX) || defined(XP_BEOS) + +#ifdef _SVID_GETTOD /* Defined only on Solaris, see Solaris */ +extern int gettimeofday(struct timeval *tv); +#endif + +#include + +#endif /* XP_UNIX */ + +#ifdef XP_MAC +static uint64 dstLocalBaseMicroseconds; +static unsigned long gJanuaryFirst1970Seconds; + +static void MacintoshInitializeTime(void) +{ + uint64 upTime; + unsigned long currentLocalTimeSeconds, + startupTimeSeconds; + uint64 startupTimeMicroSeconds; + uint32 upTimeSeconds; + uint64 oneMillion, upTimeSecondsLong, microSecondsToSeconds; + DateTimeRec firstSecondOfUnixTime; + + /* + * Figure out in local time what time the machine started up. This information can be added to + * upTime to figure out the current local time as well as GMT. + */ + + Microseconds((UnsignedWide*)&upTime); + + GetDateTime(¤tLocalTimeSeconds); + + JSLL_I2L(microSecondsToSeconds, PRMJ_USEC_PER_SEC); + JSLL_DIV(upTimeSecondsLong, upTime, microSecondsToSeconds); + JSLL_L2I(upTimeSeconds, upTimeSecondsLong); + + startupTimeSeconds = currentLocalTimeSeconds - upTimeSeconds; + + /* Make sure that we normalize the macintosh base seconds to the unix base of January 1, 1970. + */ + + firstSecondOfUnixTime.year = 1970; + firstSecondOfUnixTime.month = 1; + firstSecondOfUnixTime.day = 1; + firstSecondOfUnixTime.hour = 0; + firstSecondOfUnixTime.minute = 0; + firstSecondOfUnixTime.second = 0; + firstSecondOfUnixTime.dayOfWeek = 0; + + DateToSeconds(&firstSecondOfUnixTime, &gJanuaryFirst1970Seconds); + + startupTimeSeconds -= gJanuaryFirst1970Seconds; + + /* Now convert the startup time into a wide so that we can figure out GMT and DST. + */ + + JSLL_I2L(startupTimeMicroSeconds, startupTimeSeconds); + JSLL_I2L(oneMillion, PRMJ_USEC_PER_SEC); + JSLL_MUL(dstLocalBaseMicroseconds, oneMillion, startupTimeMicroSeconds); +} + +static SleepQRec gSleepQEntry = { NULL, sleepQType, NULL, 0 }; +static JSBool gSleepQEntryInstalled = JS_FALSE; + +static pascal long MySleepQProc(long message, SleepQRecPtr sleepQ) +{ + /* just woke up from sleeping, so must recompute dstLocalBaseMicroseconds. */ + if (message == kSleepWakeUp) + MacintoshInitializeTime(); + return 0; +} + +/* Because serial port and SLIP conflict with ReadXPram calls, + * we cache the call here + */ + +static void MyReadLocation(MachineLocation * loc) +{ + static MachineLocation storedLoc; /* InsideMac, OSUtilities, page 4-20 */ + static JSBool didReadLocation = JS_FALSE; + if (!didReadLocation) + { + MacintoshInitializeTime(); + ReadLocation(&storedLoc); + /* install a sleep queue routine, so that when the machine wakes up, time can be recomputed. */ + if (&SleepQInstall != (void*)kUnresolvedCFragSymbolAddress +#if !TARGET_CARBON + && NGetTrapAddress(0xA28A, OSTrap) != NGetTrapAddress(_Unimplemented, ToolTrap) +#endif + ) { + if ((gSleepQEntry.sleepQProc = NewSleepQUPP(MySleepQProc)) != NULL) { + SleepQInstall(&gSleepQEntry); + gSleepQEntryInstalled = JS_TRUE; + } + } + didReadLocation = JS_TRUE; + } + *loc = storedLoc; +} + + +#ifndef XP_MACOSX + +/* CFM library init and terminate routines. We'll use the terminate routine + to clean up the sleep Q entry. On Mach-O, the sleep Q entry gets cleaned + up for us, so nothing to do there. +*/ + +extern pascal OSErr __NSInitialize(const CFragInitBlock* initBlock); +extern pascal void __NSTerminate(); + +pascal OSErr __JSInitialize(const CFragInitBlock* initBlock); +pascal void __JSTerminate(void); + +pascal OSErr __JSInitialize(const CFragInitBlock* initBlock) +{ + return __NSInitialize(initBlock); +} + +pascal void __JSTerminate() +{ + /* clean up the sleepQ entry */ + if (gSleepQEntryInstalled) + SleepQRemove(&gSleepQEntry); + + __NSTerminate(); +} +#endif /* XP_MACOSX */ + +#endif /* XP_MAC */ + +#define IS_LEAP(year) \ + (year != 0 && ((((year & 0x3) == 0) && \ + ((year - ((year/100) * 100)) != 0)) || \ + (year - ((year/400) * 400)) == 0)) + +#define PRMJ_HOUR_SECONDS 3600L +#define PRMJ_DAY_SECONDS (24L * PRMJ_HOUR_SECONDS) +#define PRMJ_YEAR_SECONDS (PRMJ_DAY_SECONDS * 365L) +#define PRMJ_MAX_UNIX_TIMET 2145859200L /*time_t value equiv. to 12/31/2037 */ +/* function prototypes */ +static void PRMJ_basetime(JSInt64 tsecs, PRMJTime *prtm); +/* + * get the difference in seconds between this time zone and UTC (GMT) + */ +JSInt32 +PRMJ_LocalGMTDifference() +{ +#if defined(XP_UNIX) || defined(XP_WIN) || defined(XP_OS2) || defined(XP_BEOS) + struct tm ltime; + + /* get the difference between this time zone and GMT */ + memset((char *)<ime,0,sizeof(ltime)); + ltime.tm_mday = 2; + ltime.tm_year = 70; +#ifdef SUNOS4 + ltime.tm_zone = 0; + ltime.tm_gmtoff = 0; + return timelocal(<ime) - (24 * 3600); +#else + return mktime(<ime) - (24L * 3600L); +#endif +#endif +#if defined(XP_MAC) + static JSInt32 zone = -1L; + MachineLocation machineLocation; + JSInt32 gmtOffsetSeconds; + + /* difference has been set no need to recalculate */ + if (zone != -1) + return zone; + + /* Get the information about the local machine, including + * its GMT offset and its daylight savings time info. + * Convert each into wides that we can add to + * startupTimeMicroSeconds. + */ + + MyReadLocation(&machineLocation); + + /* Mask off top eight bits of gmtDelta, sign extend lower three. */ + gmtOffsetSeconds = (machineLocation.u.gmtDelta << 8); + gmtOffsetSeconds >>= 8; + + /* Backout OS adjustment for DST, to give consistent GMT offset. */ + if (machineLocation.u.dlsDelta != 0) + gmtOffsetSeconds -= PRMJ_HOUR_SECONDS; + return (zone = -gmtOffsetSeconds); +#endif +} + +/* Constants for GMT offset from 1970 */ +#define G1970GMTMICROHI 0x00dcdcad /* micro secs to 1970 hi */ +#define G1970GMTMICROLOW 0x8b3fa000 /* micro secs to 1970 low */ + +#define G2037GMTMICROHI 0x00e45fab /* micro secs to 2037 high */ +#define G2037GMTMICROLOW 0x7a238000 /* micro secs to 2037 low */ + +/* Convert from base time to extended time */ +static JSInt64 +PRMJ_ToExtendedTime(JSInt32 base_time) +{ + JSInt64 exttime; + JSInt64 g1970GMTMicroSeconds; + JSInt64 low; + JSInt32 diff; + JSInt64 tmp; + JSInt64 tmp1; + + diff = PRMJ_LocalGMTDifference(); + JSLL_UI2L(tmp, PRMJ_USEC_PER_SEC); + JSLL_I2L(tmp1,diff); + JSLL_MUL(tmp,tmp,tmp1); + + JSLL_UI2L(g1970GMTMicroSeconds,G1970GMTMICROHI); + JSLL_UI2L(low,G1970GMTMICROLOW); +#ifndef JS_HAVE_LONG_LONG + JSLL_SHL(g1970GMTMicroSeconds,g1970GMTMicroSeconds,16); + JSLL_SHL(g1970GMTMicroSeconds,g1970GMTMicroSeconds,16); +#else + JSLL_SHL(g1970GMTMicroSeconds,g1970GMTMicroSeconds,32); +#endif + JSLL_ADD(g1970GMTMicroSeconds,g1970GMTMicroSeconds,low); + + JSLL_I2L(exttime,base_time); + JSLL_ADD(exttime,exttime,g1970GMTMicroSeconds); + JSLL_SUB(exttime,exttime,tmp); + return exttime; +} + +JSInt64 +PRMJ_Now(void) +{ +#ifdef XP_OS2 + JSInt64 s, us, ms2us, s2us; + struct timeb b; +#endif +#ifdef XP_WIN + JSInt64 s, us, + win2un = JSLL_INIT(0x19DB1DE, 0xD53E8000), + ten = JSLL_INIT(0, 10); + FILETIME time, midnight; +#endif +#if defined(XP_UNIX) || defined(XP_BEOS) + struct timeval tv; + JSInt64 s, us, s2us; +#endif /* XP_UNIX */ +#ifdef XP_MAC + JSUint64 upTime; + JSInt64 localTime; + JSInt64 gmtOffset; + JSInt64 dstOffset; + JSInt32 gmtDiff; + JSInt64 s2us; +#endif /* XP_MAC */ + +#ifdef XP_OS2 + ftime(&b); + JSLL_UI2L(ms2us, PRMJ_USEC_PER_MSEC); + JSLL_UI2L(s2us, PRMJ_USEC_PER_SEC); + JSLL_UI2L(s, b.time); + JSLL_UI2L(us, b.millitm); + JSLL_MUL(us, us, ms2us); + JSLL_MUL(s, s, s2us); + JSLL_ADD(s, s, us); + return s; +#endif +#ifdef XP_WIN + /* The windows epoch is around 1600. The unix epoch is around 1970. + win2un is the difference (in windows time units which are 10 times + more precise than the JS time unit) */ + GetSystemTimeAsFileTime(&time); + /* Win9x gets confused at midnight + http://support.microsoft.com/default.aspx?scid=KB;en-us;q224423 + So if the low part (precision <8mins) is 0 then we get the time + again. */ + if (!time.dwLowDateTime) { + GetSystemTimeAsFileTime(&midnight); + time.dwHighDateTime = midnight.dwHighDateTime; + } + JSLL_UI2L(s, time.dwHighDateTime); + JSLL_UI2L(us, time.dwLowDateTime); + JSLL_SHL(s, s, 32); + JSLL_ADD(s, s, us); + JSLL_SUB(s, s, win2un); + JSLL_DIV(s, s, ten); + return s; +#endif + +#if defined(XP_UNIX) || defined(XP_BEOS) +#ifdef _SVID_GETTOD /* Defined only on Solaris, see Solaris */ + gettimeofday(&tv); +#else + gettimeofday(&tv, 0); +#endif /* _SVID_GETTOD */ + JSLL_UI2L(s2us, PRMJ_USEC_PER_SEC); + JSLL_UI2L(s, tv.tv_sec); + JSLL_UI2L(us, tv.tv_usec); + JSLL_MUL(s, s, s2us); + JSLL_ADD(s, s, us); + return s; +#endif /* XP_UNIX */ +#ifdef XP_MAC + JSLL_UI2L(localTime,0); + gmtDiff = PRMJ_LocalGMTDifference(); + JSLL_I2L(gmtOffset,gmtDiff); + JSLL_UI2L(s2us, PRMJ_USEC_PER_SEC); + JSLL_MUL(gmtOffset,gmtOffset,s2us); + + /* don't adjust for DST since it sets ctime and gmtime off on the MAC */ + Microseconds((UnsignedWide*)&upTime); + JSLL_ADD(localTime,localTime,gmtOffset); + JSLL_ADD(localTime,localTime, dstLocalBaseMicroseconds); + JSLL_ADD(localTime,localTime, upTime); + + dstOffset = PRMJ_DSTOffset(localTime); + JSLL_SUB(localTime,localTime,dstOffset); + + return *((JSUint64 *)&localTime); +#endif /* XP_MAC */ +} + +/* Get the DST timezone offset for the time passed in */ +JSInt64 +PRMJ_DSTOffset(JSInt64 local_time) +{ + JSInt64 us2s; +#ifdef XP_MAC + /* + * Convert the local time passed in to Macintosh epoch seconds. Use UTC utilities to convert + * to UTC time, then compare difference with our GMT offset. If they are the same, then + * DST must not be in effect for the input date/time. + */ + UInt32 macLocalSeconds = (local_time / PRMJ_USEC_PER_SEC) + gJanuaryFirst1970Seconds, utcSeconds; + ConvertLocalTimeToUTC(macLocalSeconds, &utcSeconds); + if ((utcSeconds - macLocalSeconds) == PRMJ_LocalGMTDifference()) + return 0; + else { + JSInt64 dlsOffset; + JSLL_UI2L(us2s, PRMJ_USEC_PER_SEC); + JSLL_UI2L(dlsOffset, PRMJ_HOUR_SECONDS); + JSLL_MUL(dlsOffset, dlsOffset, us2s); + return dlsOffset; + } +#else + time_t local; + JSInt32 diff; + JSInt64 maxtimet; + struct tm tm; + PRMJTime prtm; +#ifndef HAVE_LOCALTIME_R + struct tm *ptm; +#endif + + + JSLL_UI2L(us2s, PRMJ_USEC_PER_SEC); + JSLL_DIV(local_time, local_time, us2s); + + /* get the maximum of time_t value */ + JSLL_UI2L(maxtimet,PRMJ_MAX_UNIX_TIMET); + + if(JSLL_CMP(local_time,>,maxtimet)){ + JSLL_UI2L(local_time,PRMJ_MAX_UNIX_TIMET); + } else if(!JSLL_GE_ZERO(local_time)){ + /*go ahead a day to make localtime work (does not work with 0) */ + JSLL_UI2L(local_time,PRMJ_DAY_SECONDS); + } + JSLL_L2UI(local,local_time); + PRMJ_basetime(local_time,&prtm); +#ifndef HAVE_LOCALTIME_R + ptm = localtime(&local); + if(!ptm){ + return JSLL_ZERO; + } + tm = *ptm; +#else + localtime_r(&local,&tm); /* get dst information */ +#endif + + diff = ((tm.tm_hour - prtm.tm_hour) * PRMJ_HOUR_SECONDS) + + ((tm.tm_min - prtm.tm_min) * 60); + + if(diff < 0){ + diff += PRMJ_DAY_SECONDS; + } + + JSLL_UI2L(local_time,diff); + + JSLL_MUL(local_time,local_time,us2s); + + return(local_time); +#endif +} + +/* Format a time value into a buffer. Same semantics as strftime() */ +size_t +PRMJ_FormatTime(char *buf, int buflen, char *fmt, PRMJTime *prtm) +{ +#if defined(XP_UNIX) || defined(XP_WIN) || defined(XP_OS2) || defined(XP_MAC) || defined(XP_BEOS) + struct tm a; + + /* Zero out the tm struct. Linux, SunOS 4 struct tm has extra members int + * tm_gmtoff, char *tm_zone; when tm_zone is garbage, strftime gets + * confused and dumps core. NSPR20 prtime.c attempts to fill these in by + * calling mktime on the partially filled struct, but this doesn't seem to + * work as well; the result string has "can't get timezone" for ECMA-valid + * years. Might still make sense to use this, but find the range of years + * for which valid tz information exists, and map (per ECMA hint) from the + * given year into that range. + + * N.B. This hasn't been tested with anything that actually _uses_ + * tm_gmtoff; zero might be the wrong thing to set it to if you really need + * to format a time. This fix is for jsdate.c, which only uses + * JS_FormatTime to get a string representing the time zone. */ + memset(&a, 0, sizeof(struct tm)); + + a.tm_sec = prtm->tm_sec; + a.tm_min = prtm->tm_min; + a.tm_hour = prtm->tm_hour; + a.tm_mday = prtm->tm_mday; + a.tm_mon = prtm->tm_mon; + a.tm_wday = prtm->tm_wday; + a.tm_year = prtm->tm_year - 1900; + a.tm_yday = prtm->tm_yday; + a.tm_isdst = prtm->tm_isdst; + + /* Even with the above, SunOS 4 seems to detonate if tm_zone and tm_gmtoff + * are null. This doesn't quite work, though - the timezone is off by + * tzoff + dst. (And mktime seems to return -1 for the exact dst + * changeover time.) + + */ + +#if defined(SUNOS4) + if (mktime(&a) == -1) { + /* Seems to fail whenever the requested date is outside of the 32-bit + * UNIX epoch. We could proceed at this point (setting a.tm_zone to + * "") but then strftime returns a string with a 2-digit field of + * garbage for the year. So we return 0 and hope jsdate.c + * will fall back on toString. + */ + return 0; + } +#endif + + return strftime(buf, buflen, fmt, &a); +#endif +} + +/* table for number of days in a month */ +static int mtab[] = { + /* jan, feb,mar,apr,may,jun */ + 31,28,31,30,31,30, + /* july,aug,sep,oct,nov,dec */ + 31,31,30,31,30,31 +}; + +/* + * basic time calculation functionality for localtime and gmtime + * setups up prtm argument with correct values based upon input number + * of seconds. + */ +static void +PRMJ_basetime(JSInt64 tsecs, PRMJTime *prtm) +{ + /* convert tsecs back to year,month,day,hour,secs */ + JSInt32 year = 0; + JSInt32 month = 0; + JSInt32 yday = 0; + JSInt32 mday = 0; + JSInt32 wday = 6; /* start on a Sunday */ + JSInt32 days = 0; + JSInt32 seconds = 0; + JSInt32 minutes = 0; + JSInt32 hours = 0; + JSInt32 isleap = 0; + JSInt64 result; + JSInt64 result1; + JSInt64 result2; + JSInt64 base; + + JSLL_UI2L(result,0); + JSLL_UI2L(result1,0); + JSLL_UI2L(result2,0); + + /* get the base time via UTC */ + base = PRMJ_ToExtendedTime(0); + JSLL_UI2L(result, PRMJ_USEC_PER_SEC); + JSLL_DIV(base,base,result); + JSLL_ADD(tsecs,tsecs,base); + + JSLL_UI2L(result, PRMJ_YEAR_SECONDS); + JSLL_UI2L(result1,PRMJ_DAY_SECONDS); + JSLL_ADD(result2,result,result1); + + /* get the year */ + while ((isleap == 0) ? !JSLL_CMP(tsecs,<,result) : !JSLL_CMP(tsecs,<,result2)) { + /* subtract a year from tsecs */ + JSLL_SUB(tsecs,tsecs,result); + days += 365; + /* is it a leap year ? */ + if(IS_LEAP(year)){ + JSLL_SUB(tsecs,tsecs,result1); + days++; + } + year++; + isleap = IS_LEAP(year); + } + + JSLL_UI2L(result1,PRMJ_DAY_SECONDS); + + JSLL_DIV(result,tsecs,result1); + JSLL_L2I(mday,result); + + /* let's find the month */ + while(((month == 1 && isleap) ? + (mday >= mtab[month] + 1) : + (mday >= mtab[month]))){ + yday += mtab[month]; + days += mtab[month]; + + mday -= mtab[month]; + + /* it's a Feb, check if this is a leap year */ + if(month == 1 && isleap != 0){ + yday++; + days++; + mday--; + } + month++; + } + + /* now adjust tsecs */ + JSLL_MUL(result,result,result1); + JSLL_SUB(tsecs,tsecs,result); + + mday++; /* day of month always start with 1 */ + days += mday; + wday = (days + wday) % 7; + + yday += mday; + + /* get the hours */ + JSLL_UI2L(result1,PRMJ_HOUR_SECONDS); + JSLL_DIV(result,tsecs,result1); + JSLL_L2I(hours,result); + JSLL_MUL(result,result,result1); + JSLL_SUB(tsecs,tsecs,result); + + /* get minutes */ + JSLL_UI2L(result1,60); + JSLL_DIV(result,tsecs,result1); + JSLL_L2I(minutes,result); + JSLL_MUL(result,result,result1); + JSLL_SUB(tsecs,tsecs,result); + + JSLL_L2I(seconds,tsecs); + + prtm->tm_usec = 0L; + prtm->tm_sec = (JSInt8)seconds; + prtm->tm_min = (JSInt8)minutes; + prtm->tm_hour = (JSInt8)hours; + prtm->tm_mday = (JSInt8)mday; + prtm->tm_mon = (JSInt8)month; + prtm->tm_wday = (JSInt8)wday; + prtm->tm_year = (JSInt16)year; + prtm->tm_yday = (JSInt16)yday; +} diff --git a/src/extension/script/js/prmjtime.h b/src/extension/script/js/prmjtime.h new file mode 100644 index 000000000..6a94a11b1 --- /dev/null +++ b/src/extension/script/js/prmjtime.h @@ -0,0 +1,95 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef prmjtime_h___ +#define prmjtime_h___ +/* + * PR date stuff for mocha and java. Placed here temporarily not to break + * Navigator and localize changes to mocha. + */ +#include +#include "jslong.h" +#ifdef MOZILLA_CLIENT +#include "jscompat.h" +#endif + +JS_BEGIN_EXTERN_C + +typedef struct PRMJTime PRMJTime; + +/* + * Broken down form of 64 bit time value. + */ +struct PRMJTime { + JSInt32 tm_usec; /* microseconds of second (0-999999) */ + JSInt8 tm_sec; /* seconds of minute (0-59) */ + JSInt8 tm_min; /* minutes of hour (0-59) */ + JSInt8 tm_hour; /* hour of day (0-23) */ + JSInt8 tm_mday; /* day of month (1-31) */ + JSInt8 tm_mon; /* month of year (0-11) */ + JSInt8 tm_wday; /* 0=sunday, 1=monday, ... */ + JSInt16 tm_year; /* absolute year, AD */ + JSInt16 tm_yday; /* day of year (0 to 365) */ + JSInt8 tm_isdst; /* non-zero if DST in effect */ +}; + +/* Some handy constants */ +#define PRMJ_USEC_PER_SEC 1000000L +#define PRMJ_USEC_PER_MSEC 1000L + +/* Return the current local time in micro-seconds */ +extern JSInt64 +PRMJ_Now(void); + +/* get the difference between this time zone and gmt timezone in seconds */ +extern JSInt32 +PRMJ_LocalGMTDifference(void); + +/* Format a time value into a buffer. Same semantics as strftime() */ +extern size_t +PRMJ_FormatTime(char *buf, int buflen, char *fmt, PRMJTime *tm); + +/* Get the DST offset for the local time passed in */ +extern JSInt64 +PRMJ_DSTOffset(JSInt64 local_time); + +JS_END_EXTERN_C + +#endif /* prmjtime_h___ */ + diff --git a/src/extension/script/js/resource.h b/src/extension/script/js/resource.h new file mode 100644 index 000000000..9301810e4 --- /dev/null +++ b/src/extension/script/js/resource.h @@ -0,0 +1,15 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by js3240.rc +// + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 101 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1000 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/src/extension/script/makefile.in b/src/extension/script/makefile.in new file mode 100644 index 000000000..7ebfd5217 --- /dev/null +++ b/src/extension/script/makefile.in @@ -0,0 +1,17 @@ +# Convenience stub makefile to call the real Makefile. + +@SET_MAKE@ + +# Explicit so that it's the default rule. +all: + cd ../.. && $(MAKE) extension/script/all + +clean %.a %.o: + cd ../.. && $(MAKE) extension/script/$@ + +.PHONY: all clean + +OBJEXT = @OBJEXT@ + +.SUFFIXES: +.SUFFIXES: .a .$(OBJEXT) diff --git a/src/extension/script/quotefile.pl b/src/extension/script/quotefile.pl new file mode 100644 index 000000000..9eb769a25 --- /dev/null +++ b/src/extension/script/quotefile.pl @@ -0,0 +1,82 @@ +#!/usr/bin/perl +############################################################################ +# +# Quote all of the lines of a text file, so that it can be loaded +# into C/C++ +# +############################################################################ + +# +# main - top level code +# + + +if ( $#ARGV != 1 ) { # parse command line args + print "usage: perl quotefile.pl infile outfile\n\n"; + exit 1; +} + +$inName = $ARGV[0]; +$outName = $ARGV[1]; + +print "#######################################################\n"; +print "## Quoting $inName to $outName\n"; +print "#######################################################\n"; + +&doQuoteFile(); #Do your magic! + +print "#######################################################\n"; +print "## DONE\n"; +print "#######################################################\n"; + +exit 0; + + + +############################################################################ +# +# +# +# +############################################################################ +sub doQuoteFile +{ + my $line; #current line from input file + my $datestr; #Current date + local(*INFILE); + local(*OUTFILE); + + $datestr = gmtime(); + + if ( -r $inName ) + { + open INFILE, $inName or + die "$inName: $!"; + open OUTFILE, ">$outName" or + die "$outName: $!"; + print OUTFILE "\n"; + print OUTFILE "/* ###################################################\n"; + print OUTFILE "## This file generated by quotefile.pl from\n"; + print OUTFILE "## $inName on $datestr\n"; + print OUTFILE "## DO NOT EDIT\n"; + print OUTFILE "################################################### */\n"; + print OUTFILE "\n"; + print OUTFILE "static char *inkscape_module_script =\n"; + while () + { + $line = $_; + #Escape existing quotes + $line =~ s/\"/\\"/g; + #Add outer quotes + $line =~ s/^/\"/; + $line =~ s/$/\\n\"/; + + print OUTFILE $line + } + close INFILE; + print OUTFILE "\"\";\n"; + close OUTFILE; + } + +} + diff --git a/src/extension/script/runme.py b/src/extension/script/runme.py new file mode 100644 index 000000000..706676064 --- /dev/null +++ b/src/extension/script/runme.py @@ -0,0 +1,8 @@ + +import inkscape_py + +inkscape = inkscape_py.getInkscape() +desktop = inkscape.getDesktop() +document = desktop.getDocument() +document.hello() + diff --git a/src/extension/script/wrap_swig_module.sh b/src/extension/script/wrap_swig_module.sh new file mode 100644 index 000000000..8c6236f2d --- /dev/null +++ b/src/extension/script/wrap_swig_module.sh @@ -0,0 +1,27 @@ +#!/bin/sh + +inf=$1 +outf=$2 +datestr=`date` + +echo "" > ${outf} +echo "/* ###################################################" >> ${outf} +echo "## This file generated by wrap_swig_module.sh from" >> ${outf} +echo "## ${inf} on ${datestr}" >> ${outf} +echo "## DO NOT EDIT" >> ${outf} +echo "################################################### */" >> ${outf} +echo "" >> ${outf} + +echo "static char *inkscape_module_script =" >> ${outf} +echo "\"\n\"" >> ${outf} + +cat ${inf} | \ +sed -e 's/\"/\\"/g' -e 's/^/\"/g' -e 's/$/\\n\"/g' >> ${outf} + +echo "\"\n\";" >> ${outf} + + + + + + diff --git a/src/extension/system.cpp b/src/extension/system.cpp new file mode 100644 index 000000000..34855cd4e --- /dev/null +++ b/src/extension/system.cpp @@ -0,0 +1,476 @@ +/* + * This is file is kind of the junk file. Basically everything that + * didn't fit in one of the other well defined areas, well, it's now + * here. Which is good in someways, but this file really needs some + * definition. Hopefully that will come ASAP. + * + * Authors: + * Ted Gould + * + * Copyright (C) 2002-2004 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#include "db.h" +#include "input.h" +#include "output.h" +#include "effect.h" +#include "print.h" +#include "implementation/script.h" +/* #include "implementation/plugin.h" */ + +namespace Inkscape { +namespace Extension { + +static void open_internal(Inkscape::Extension::Extension *in_plug, gpointer in_data); +static void save_internal(Inkscape::Extension::Extension *in_plug, gpointer in_data); +static Extension *build_from_reprdoc(Inkscape::XML::Document *doc, Implementation::Implementation *in_imp); + +/** + * \return A new document created from the filename passed in + * \brief This is a generic function to use the open function of + * a module (including Autodetect) + * \param key Identifier of which module to use + * \param filename The file that should be opened + * + * First things first, are we looking at an autodetection? Well if that's the case then the module + * needs to be found, and that is done with a database lookup through the module DB. The foreach + * function is called, with the parameter being a gpointer array. It contains both the filename + * (to find its extension) and where to write the module when it is found. + * + * If there is no autodetection, then the module database is queried with the key given. + * + * If everything is cool at this point, the module is loaded, and there is possibility for + * preferences. If there is a function, then it is executed to get the dialog to be displayed. + * After it is finished the function continues. + * + * Lastly, the open function is called in the module itself. + */ +SPDocument * +open(Extension *key, gchar const *filename) +{ + Input *imod = NULL; + if (key == NULL) { + gpointer parray[2]; + parray[0] = (gpointer)filename; + parray[1] = (gpointer)&imod; + db.foreach(open_internal, (gpointer)&parray); + } else { + imod = dynamic_cast(key); + } + + bool last_chance_svg = false; + if (key == NULL && imod == NULL) { + last_chance_svg = true; + imod = dynamic_cast(db.get(SP_MODULE_KEY_INPUT_SVG)); + } + + if (imod == NULL) { + throw Input::no_extension_found(); + } + + imod->set_state(Extension::STATE_LOADED); + + if (!imod->loaded()) { + throw Input::open_failed(); + } + + if (!imod->prefs(filename)) + return NULL; + + SPDocument *doc = imod->open(filename); + if (!doc) { + return NULL; + } + + if (last_chance_svg) { + /* We can't call sp_ui_error_dialog because we may be + running from the console, in which case calling sp_ui + routines will cause a segfault. See bug 1000350 - bryce */ + // sp_ui_error_dialog(_("Format autodetect failed. The file is being opened as SVG.")); + g_warning(_("Format autodetect failed. The file is being opened as SVG.")); + } + + /* This kinda overkill as most of these are already set, but I want + to make sure for this release -- TJG */ + Inkscape::XML::Node *repr = sp_document_repr_root(doc); + gboolean saved = sp_document_get_undo_sensitive(doc); + sp_document_set_undo_sensitive(doc, FALSE); + repr->setAttribute("sodipodi:modified", NULL); + sp_document_set_undo_sensitive(doc, saved); + + sp_document_set_uri(doc, filename); + + return doc; +} + +/** + * \return none + * \brief This is the function that searches each module to see + * if it matches the filename for autodetection. + * \param in_plug The module to be tested + * \param in_data An array of pointers containing the filename, and + * the place to put a successfully found module. + * + * Basically this function only looks at input modules as it is part of the open function. If the + * module is an input module, it then starts to take it apart, and the data that is passed in. + * Because the data being passed in is in such a weird format, there are a few casts to make it + * easier to use. While it looks like a lot of local variables, they'll all get removed by the + * compiler. + * + * First thing that is checked is if the filename is shorter than the extension itself. There is + * no way for a match in that case. If it's long enough then there is a string compare of the end + * of the filename (for the length of the extension), and the extension itself. If this passes + * then the pointer passed in is set to the current module. + */ +static void +open_internal(Extension *in_plug, gpointer in_data) +{ + if (!in_plug->deactivated() && dynamic_cast(in_plug)) { + gpointer *parray = (gpointer *)in_data; + gchar const *filename = (gchar const *)parray[0]; + Input **pimod = (Input **)parray[1]; + + // skip all the rest if we already found a function to open it + // since they're ordered by preference now. + if (!*pimod) { + gchar const *ext = dynamic_cast(in_plug)->get_extension(); + + gchar *filenamelower = g_utf8_strdown(filename, -1); + gchar *extensionlower = g_utf8_strdown(ext, -1); + + if (g_str_has_suffix(filenamelower, extensionlower)) { + *pimod = dynamic_cast(in_plug); + } + + g_free(filenamelower); + g_free(extensionlower); + } + } + + return; +} + +/** + * \return None + * \brief This is a generic function to use the save function of + * a module (including Autodetect) + * \param key Identifier of which module to use + * \param doc The document to be saved + * \param filename The file that the document should be saved to + * \param official (optional) whether to set :output_module and :modified in the + * document; is true for normal save, false for temporary saves + * + * First things first, are we looking at an autodetection? Well if that's the case then the module + * needs to be found, and that is done with a database lookup through the module DB. The foreach + * function is called, with the parameter being a gpointer array. It contains both the filename + * (to find its extension) and where to write the module when it is found. + * + * If there is no autodetection the module database is queried with the key given. + * + * If everything is cool at this point, the module is loaded, and there is possibility for + * preferences. If there is a function, then it is executed to get the dialog to be displayed. + * After it is finished the function continues. + * + * Lastly, the save function is called in the module itself. + */ +void +save(Extension *key, SPDocument *doc, gchar const *filename, bool setextension, bool check_overwrite, bool official) +{ + Output *omod; + if (key == NULL) { + gpointer parray[2]; + parray[0] = (gpointer)filename; + parray[1] = (gpointer)&omod; + omod = NULL; + db.foreach(save_internal, (gpointer)&parray); + + /* This is a nasty hack, but it is required to ensure that + autodetect will always save with the Inkscape extensions + if they are available. */ + if (omod != NULL && !strcmp(omod->get_id(), SP_MODULE_KEY_OUTPUT_SVG)) { + omod = dynamic_cast(db.get(SP_MODULE_KEY_OUTPUT_SVG_INKSCAPE)); + } + /* If autodetect fails, save as Inkscape SVG */ + if (omod == NULL) { + omod = dynamic_cast(db.get(SP_MODULE_KEY_OUTPUT_SVG_INKSCAPE)); + } + } else { + omod = dynamic_cast(key); + } + + if (!dynamic_cast(omod)) { + g_warning("Unable to find output module to handle file: %s\n", filename); + throw Output::no_extension_found(); + return; + } + + omod->set_state(Extension::STATE_LOADED); + if (!omod->loaded()) { + throw Output::save_failed(); + } + + if (!omod->prefs()) + return; + + gchar *fileName = NULL; + if (setextension) { + gchar *lowerfile = g_utf8_strdown(filename, -1); + gchar *lowerext = g_utf8_strdown(omod->get_extension(), -1); + + if (!g_str_has_suffix(lowerfile, lowerext)) { + fileName = g_strdup_printf("%s%s", filename, omod->get_extension()); + } + + g_free(lowerfile); + g_free(lowerext); + } + + if (fileName == NULL) { + fileName = g_strdup(filename); + } + + if (check_overwrite && !sp_ui_overwrite_file(fileName)) { + g_free(fileName); + throw Output::no_overwrite(); + } + + if (official) { + sp_document_set_uri(doc, fileName); + } + + omod->save(doc, fileName); + + g_free(fileName); + return; +} + +/** + * \return none + * \brief This is the function that searches each module to see + * if it matches the filename for autodetection. + * \param in_plug The module to be tested + * \param in_data An array of pointers containing the filename, and + * the place to put a successfully found module. + * + * Basically this function only looks at output modules as it is part of the open function. If the + * module is an output module, it then starts to take it apart, and the data that is passed in. + * Because the data being passed in is in such a weird format, there are a few casts to make it + * easier to use. While it looks like a lot of local variables, they'll all get removed by the + * compiler. + * + * First thing that is checked is if the filename is shorter than the extension itself. There is + * no way for a match in that case. If it's long enough then there is a string compare of the end + * of the filename (for the length of the extension), and the extension itself. If this passes + * then the pointer passed in is set to the current module. + */ +static void +save_internal(Extension *in_plug, gpointer in_data) +{ + if (!in_plug->deactivated() && dynamic_cast(in_plug)) { + gpointer *parray = (gpointer *)in_data; + gchar const *filename = (gchar const *)parray[0]; + Output **pomod = (Output **)parray[1]; + + // skip all the rest if we already found someone to save it + // since they're ordered by preference now. + if (!*pomod) { + gchar const *ext = dynamic_cast(in_plug)->get_extension(); + + gchar *filenamelower = g_utf8_strdown(filename, -1); + gchar *extensionlower = g_utf8_strdown(ext, -1); + + if (g_str_has_suffix(filenamelower, extensionlower)) { + *pomod = dynamic_cast(in_plug); + } + + g_free(filenamelower); + g_free(extensionlower); + } + } + + return; +} + +Print * +get_print(gchar const *key) +{ + return dynamic_cast(db.get(key)); +} + +/** + * \return The built module + * \brief Creates a module from a Inkscape::XML::Document describing the module + * \param doc The XML description of the module + * + * This function basically has two segments. The first is that it goes through the Repr tree + * provided, and determines what kind of of module this is, and what kind of implementation to use. + * All of these are then stored in two enums that are defined in this function. This makes it + * easier to add additional types (which will happen in the future, I'm sure). + * + * Second, there is case statements for these enums. The first one is the type of module. This is + * the one where the module is actually created. After that, then the implementation is applied to + * get the load and unload functions. If there is no implementation then these are not set. This + * case could apply to modules that are built in (like the SVG load/save functions). + */ +static Extension * +build_from_reprdoc(Inkscape::XML::Document *doc, Implementation::Implementation *in_imp) +{ + enum { + MODULE_EXTENSION, + /* MODULE_PLUGIN, */ + MODULE_UNKNOWN_IMP + } module_implementation_type = MODULE_UNKNOWN_IMP; + enum { + MODULE_INPUT, + MODULE_OUTPUT, + MODULE_FILTER, + MODULE_PRINT, + MODULE_UNKNOWN_FUNC + } module_functional_type = MODULE_UNKNOWN_FUNC; + + g_return_val_if_fail(doc != NULL, NULL); + + Inkscape::XML::Node *repr = sp_repr_document_root(doc); + + /* sp_repr_print(repr); */ + + if (strcmp(repr->name(), "inkscape-extension")) { + g_warning("Extension definition started with <%s> instead of . Extension will not be created.\n", repr->name()); + return NULL; + } + + Inkscape::XML::Node *child_repr = sp_repr_children(repr); + while (child_repr != NULL) { + char const *element_name = child_repr->name(); + /* printf("Child: %s\n", child_repr->name()); */ + if (!strcmp(element_name, "input")) { + module_functional_type = MODULE_INPUT; + } else if (!strcmp(element_name, "output")) { + module_functional_type = MODULE_OUTPUT; + } else if (!strcmp(element_name, "effect")) { + module_functional_type = MODULE_FILTER; + } else if (!strcmp(element_name, "print")) { + module_functional_type = MODULE_PRINT; + } else if (!strcmp(element_name, "script")) { + module_implementation_type = MODULE_EXTENSION; +#if 0 + } else if (!strcmp(element_name, "plugin")) { + module_implementation_type = MODULE_PLUGIN; +#endif + } + + //Inkscape::XML::Node *old_repr = child_repr; + child_repr = sp_repr_next(child_repr); + //Inkscape::GC::release(old_repr); + } + + Implementation::Implementation *imp; + if (in_imp == NULL) { + switch (module_implementation_type) { + case MODULE_EXTENSION: { + Implementation::Script *script = new Implementation::Script(); + imp = static_cast(script); + break; + } +#if 0 + case MODULE_PLUGIN: { + Implementation::Plugin *plugin = new Implementation::Plugin(); + imp = static_cast(plugin); + break; + } +#endif + default: { + imp = NULL; + break; + } + } + } else { + imp = in_imp; + } + + Extension *module = NULL; + switch (module_functional_type) { + case MODULE_INPUT: { + module = new Input(repr, imp); + break; + } + case MODULE_OUTPUT: { + module = new Output(repr, imp); + break; + } + case MODULE_FILTER: { + module = new Effect(repr, imp); + break; + } + case MODULE_PRINT: { + module = new Print(repr, imp); + break; + } + default: { + break; + } + } + + return module; +} + +/** + * \return The module created + * \brief This function creates a module from a filename of an + * XML description. + * \param filename The file holding the XML description of the module. + * + * This function calls build_from_reprdoc with using sp_repr_read_file to create the reprdoc. + */ +Extension * +build_from_file(gchar const *filename) +{ + /* TODO: Need to define namespace here, need to write the + DTD in general for this stuff */ + Inkscape::XML::Document *doc = sp_repr_read_file(filename, NULL); + Extension *ext = build_from_reprdoc(doc, NULL); + Inkscape::GC::release(doc); + if (ext == NULL) + g_warning("Unable to create extension from definition file %s.\n", filename); + return ext; +} + +/** + * \return The module created + * \brief This function creates a module from a buffer holding an + * XML description. + * \param buffer The buffer holding the XML description of the module. + * + * This function calls build_from_reprdoc with using sp_repr_read_mem to create the reprdoc. It + * finds the length of the buffer using strlen. + */ +Extension * +build_from_mem(gchar const *buffer, Implementation::Implementation *in_imp) +{ + Inkscape::XML::Document *doc = sp_repr_read_mem(buffer, strlen(buffer), NULL); + Extension *ext = build_from_reprdoc(doc, in_imp); + Inkscape::GC::release(doc); + return ext; +} + + +} } /* namespace Inkscape::Extension */ + +/* + 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 : diff --git a/src/extension/system.h b/src/extension/system.h new file mode 100644 index 000000000..6c23b2f0d --- /dev/null +++ b/src/extension/system.h @@ -0,0 +1,44 @@ +/* + * This is file is kind of the junk file. Basically everything that + * didn't fit in one of the other well defined areas, well, it's now + * here. Which is good in someways, but this file really needs some + * definition. Hopefully that will come ASAP. + * + * Authors: + * Ted Gould + * + * Copyright (C) 2002-2004 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifndef INKSCAPE_EXTENSION_SYSTEM_H__ +#define INKSCAPE_EXTENSION_SYSTEM_H__ + +#include "document.h" +#include "extension/extension.h" + +namespace Inkscape { +namespace Extension { + +SPDocument *open(Extension *key, gchar const *filename); +void save(Extension *key, SPDocument *doc, gchar const *filename, + bool setextension, bool check_overwrite, bool official); +Print *get_print(gchar const *key); +Extension *build_from_file(gchar const *filename); +Extension *build_from_mem(gchar const *buffer, Implementation::Implementation *in_imp); + +} } /* namespace Inkscape::Extension */ + +#endif /* INKSCAPE_EXTENSION_SYSTEM_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 : diff --git a/src/extension/timer.cpp b/src/extension/timer.cpp new file mode 100644 index 000000000..0e7a6ad11 --- /dev/null +++ b/src/extension/timer.cpp @@ -0,0 +1,214 @@ +/* + * Here is where the extensions can get timed on when they load and + * unload. All of the timing is done in here. + * + * Authors: + * Ted Gould + * + * Copyright (C) 2004 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + + + +#include "extension.h" +#include "timer.h" + +namespace Inkscape { +namespace Extension { + +#define TIMER_SCALE_VALUE 20 + +ExpirationTimer * ExpirationTimer::timer_list = NULL; +ExpirationTimer * ExpirationTimer::idle_start = NULL; +long ExpirationTimer::timeout = 240; +bool ExpirationTimer::timer_started = false; + +/** \brief Create a new expiration timer + \param in_extension Which extension this timer is related to + + This function creates the timer, and sets the time to the current + time, plus what ever the current timeout is. Also, if this is + the first timer extension, the timer is kicked off. This function + also sets up teh circularly linked list of all the timers. +*/ +ExpirationTimer::ExpirationTimer (Extension * in_extension) +{ + locked = false; + extension = in_extension; + + /* Fix Me! */ + if (timer_list == NULL) { + next = this; + timer_list = this; + } else { + next = timer_list->next; + timer_list->next = this; + } + + expiration.assign_current_time(); + expiration += timeout; + + if (!timer_started) { + Glib::signal_timeout().connect(sigc::ptr_fun(&timer_func), timeout * 1000 / TIMER_SCALE_VALUE); + timer_started = true; + } + + return; +} + +/** \brief Deletes a \c ExpirationTimer + + The most complex thing that this function does is remove the timer + from the circularly linked list. If this is the only entry in the + list that is easy, otherwise all the entries must be found, and this + one removed from the list. +*/ +ExpirationTimer::~ExpirationTimer(void) +{ + if (this != next) { + /* This will remove this entry from the circularly linked + list. */ + ExpirationTimer * prev; + for (prev = timer_list; + prev->next != this; + prev = prev->next); + prev->next = next; + + if (idle_start == this) + idle_start = next; + + /* This may occur more than you think, just because the guy + doing most of the deletions is the idle function, who tracks + where it is looking using the \c timer_list variable. */ + if (timer_list == this) + timer_list = next; + } else { + /* If we're the only entry in the list, the list needs to go + to NULL */ + timer_list = NULL; + idle_start = NULL; + } + + return; +} + +/** \brief Touches the timer to extend the length before it expires + + Basically it adds more time to the timer. One thing that is kinda + tricky is that it adds half the time remaining back into the timer. + This allows for some extensions that are used regularly to having + extended expiration times. So, in the end, they stay loaded longer. + Extensions that are only used once will expire at a standard rate + set by \c timeout. +*/ +void +ExpirationTimer::touch (void) +{ + Glib::TimeVal current; + current.assign_current_time(); + + long time_left = (long)(expiration.as_double() - current.as_double()); + if (time_left < 0) time_left = 0; + time_left /= 2; + + expiration = current + timeout + time_left; + return; +} + +/** \brief Check to see if the timer has expired + + Checks the time against the current time. +*/ +bool +ExpirationTimer::expired (void) const +{ + if (locked) return false; + + Glib::TimeVal current; + current.assign_current_time(); + return expiration < current; +} + +// int idle_cnt = 0; + +/** \brief This function goes in the idle loop to find expired extensions + \return Whether the function should be requeued or not + + This function first insures that there is a timer list, and then checks + to see if the one on the top of the list has expired. If it has + expired it unloads the module. By unloading the module, the timer + gets deleted (happens in the unload function). If the list is + no empty, the function returns that it should be dequeued and sets + the \c timer_started variable so that the timer will be reissued when + a timer is added. If there is entries left, but the next one is + where this function started, then the timer is set up. The timer + will then re-add the idle loop function when it runs. +*/ +bool +ExpirationTimer::idle_func (void) +{ + // std::cout << "Idle func pass: " << idle_cnt++ << " timer list: " << timer_list << std::endl; + + /* see if this is the last */ + if (timer_list == NULL) { + timer_started = false; + return false; + } + + /* evalutate current */ + if (timer_list->expired()) { + timer_list->extension->set_state(Extension::STATE_UNLOADED); + } + + /* see if this is the last */ + if (timer_list == NULL) { + timer_started = false; + return false; + } + + if (timer_list->next == idle_start) { + /* if so, set up the timer and return FALSE */ + /* Note: This may cause one to be missed on the evaluation if + the one before it expires and it is last in the list. + While this could be taken care of, it isn't worth the + complexity for this lazy removal that we're doing. It + should get picked up next time */ + Glib::signal_timeout().connect(sigc::ptr_fun(&timer_func), timeout * 1000 / TIMER_SCALE_VALUE); + return false; + } + + /* If nothing else, continue on */ + timer_list = timer_list->next; + return true; +} + +/** \brief A timer function to set up the idle function + \return Always false -- to disable the timer + + This function sets up the idle loop when it runs. The idle loop is + the one that unloads all the extensions. +*/ +bool +ExpirationTimer::timer_func (void) +{ + // std::cout << "Timer func" << std::endl; + idle_start = timer_list; + // idle_cnt = 0; + Glib::signal_idle().connect(sigc::ptr_fun(&idle_func)); + return false; +} + +}; }; /* namespace Inkscape, Extension */ + +/* + 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 : diff --git a/src/extension/timer.h b/src/extension/timer.h new file mode 100644 index 000000000..b9649e899 --- /dev/null +++ b/src/extension/timer.h @@ -0,0 +1,72 @@ +/* + * Here is where the extensions can get timed on when they load and + * unload. All of the timing is done in here. + * + * Authors: + * Ted Gould + * + * Copyright (C) 2004 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifndef INKSCAPE_EXTENSION_TIMER_H__ +#define INKSCAPE_EXTENSION_TIMER_H__ + +#include +#include +#include "extension-forward.h" + +namespace Inkscape { +namespace Extension { + +class ExpirationTimer { + /** \brief Circularly linked list of all timers */ + static ExpirationTimer * timer_list; + /** \brief Which timer was on top when we started the idle loop */ + static ExpirationTimer * idle_start; + /** \brief What the current timeout is */ + static long timeout; + /** \brief Has the timer been started? */ + static bool timer_started; + + /** \brief Is this extension locked from being unloaded? */ + bool locked; + /** \brief Next entry in the list */ + ExpirationTimer * next; + /** \brief When this timer expires */ + Glib::TimeVal expiration; + /** \brief What extension this function relates to */ + Extension * extension; + + bool expired(void) const; + + static bool idle_func (void); + static bool timer_func (void); + +public: + ExpirationTimer(Extension * in_extension); + ~ExpirationTimer(void); + + void touch (void); + void lock (void) { locked = true; }; + void unlock (void) { locked = false; }; + + /** \brief Set the timeout variable */ + static void set_timeout (long in_seconds) { timeout = in_seconds; }; +}; + +}; }; /* namespace Inkscape, Extension */ + +#endif /* INKSCAPE_EXTENSION_TIMER_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 : diff --git a/src/extract-uri-test.cpp b/src/extract-uri-test.cpp new file mode 100644 index 000000000..9bf44baca --- /dev/null +++ b/src/extract-uri-test.cpp @@ -0,0 +1,56 @@ +#include +#include "extract-uri.h" +#include +#include + +struct Case { + char const *input; + char const *exp; +}; + +static void test_extract_uri_case(Case const &c) +{ + char * const p = extract_uri(c.input); + UTEST_TEST(c.input) { + UTEST_ASSERT( ( p == NULL ) == ( c.exp == NULL ) ); + if (p) { + UTEST_ASSERT( strcmp(p, c.exp) == 0 ); + } + } + g_free(p); +} + +int main(int argc, char *argv[]) +{ + utest_start("extract_uri"); + + Case const cases[] = { + { "url(#foo)", "#foo" }, + { "url foo ", "foo" }, + { "url", NULL }, + { "url ", NULL }, + { "url()", NULL }, + { "url ( ) ", NULL }, + { "url foo bar ", "foo bar" } + }; + + for(unsigned i = 0; i < G_N_ELEMENTS(cases); ++i) { + Case const &c = cases[i]; + test_extract_uri_case(c); + } + + return ( utest_end() + ? EXIT_SUCCESS + : EXIT_FAILURE ); +} + +/* + 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:textwidth=99 : diff --git a/src/extract-uri.cpp b/src/extract-uri.cpp new file mode 100644 index 000000000..dd6549c8f --- /dev/null +++ b/src/extract-uri.cpp @@ -0,0 +1,40 @@ +#include +#include + +// FIXME: kill this ugliness when we have a proper CSS parser +gchar *extract_uri(gchar const *s) +{ + gchar const *sb = s; + g_assert( strncmp(sb, "url", 3) == 0 ); + sb += 3; + + while ( ( *sb == ' ' ) || + ( *sb == '(' ) ) + { + sb++; + } + + gchar const *se = sb + strlen(sb); + while ( ( se[-1] == ' ' ) || + ( se[-1] == ')' ) ) + { + se--; + } + + if ( sb < se ) { + return g_strndup(sb, se - sb); + } else { + return NULL; + } +} + +/* + 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:textwidth=99 : diff --git a/src/extract-uri.h b/src/extract-uri.h new file mode 100644 index 000000000..10def3904 --- /dev/null +++ b/src/extract-uri.h @@ -0,0 +1,20 @@ +#ifndef SEEN_EXTRACT_URI_H +#define SEEN_EXTRACT_URI_H + +#include + +gchar *extract_uri(gchar const *s); + + +#endif /* !SEEN_EXTRACT_URI_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:encoding=utf-8:textwidth=99 : diff --git a/src/file.cpp b/src/file.cpp new file mode 100644 index 000000000..acc6e101a --- /dev/null +++ b/src/file.cpp @@ -0,0 +1,1337 @@ +#define __SP_FILE_C__ + +/* + * File/Print operations + * + * Authors: + * Lauris Kaplinski + * Chema Celorio + * bulia byak + * + * Copyright (C) 1999-2005 Authors + * Copyright (C) 2001-2002 Ximian, Inc. + * Copyright (C) 2004 David Turner + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +/** + * Note: This file needs to be cleaned up extensively. + * What it probably needs is to have one .h file for + * the API, and two or more .cpp files for the implementations. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "document-private.h" +#include "selection-chemistry.h" +#include "ui/view/view-widget.h" +#include "dir-util.h" +#include "helper/png-write.h" +#include "dialogs/export.h" +#include +#include "inkscape.h" +#include "desktop.h" +#include "selection.h" +#include "interface.h" +#include "style.h" +#include "print.h" +#include "file.h" +#include "message-stack.h" +#include "dialogs/filedialog.h" +#include "prefs-utils.h" +#include "path-prefix.h" + +#include "sp-namedview.h" +#include "desktop-handles.h" + +#include "extension/db.h" +#include "extension/input.h" +#include "extension/output.h" +/* #include "extension/menu.h" */ +#include "extension/system.h" + +#include "io/sys.h" +#include "application/application.h" +#include "application/editor.h" +#include "inkscape.h" +#include "uri.h" + +#ifdef WITH_INKBOARD +#include "jabber_whiteboard/session-manager.h" +#endif + +/** + * 'Current' paths. Used to remember which directory + * had the last file accessed. + * Static globals are evil. This will be gone soon + * as C++ification continues + */ +static gchar *import_path = NULL; + +//#define INK_DUMP_FILENAME_CONV 1 +#undef INK_DUMP_FILENAME_CONV + +//#define INK_DUMP_FOPEN 1 +#undef INK_DUMP_FOPEN + +void dump_str(gchar const *str, gchar const *prefix); +void dump_ustr(Glib::ustring const &ustr); + + +/*###################### +## N E W +######################*/ + +/** + * Create a blank document and add it to the desktop + */ +SPDesktop* +sp_file_new(gchar const *templ) +{ + SPDocument *doc = sp_document_new(templ, TRUE, true); + g_return_val_if_fail(doc != NULL, NULL); + + SPDesktop *dt; + if (Inkscape::NSApplication::Application::getNewGui()) + { + dt = Inkscape::NSApplication::Editor::createDesktop (doc); + } else { + SPViewWidget *dtw = sp_desktop_widget_new(sp_document_namedview(doc, NULL)); + g_return_val_if_fail(dtw != NULL, NULL); + sp_document_unref(doc); + + sp_create_window(dtw, TRUE); + dt = static_cast(dtw->view); + sp_namedview_window_from_document(dt); + } + return dt; +} + +SPDesktop* +sp_file_new_default() +{ + std::list sources; + sources.push_back( profile_path("templates") ); // first try user's local dir + sources.push_back( g_strdup(INKSCAPE_TEMPLATESDIR) ); // then the system templates dir + + while (!sources.empty()) { + gchar *dirname = sources.front(); + if ( Inkscape::IO::file_test( dirname, (GFileTest)(G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR) ) ) { + + // TRANSLATORS: default.svg is localizable - this is the name of the default document + // template. This way you can localize the default pagesize, translate the name of + // the default layer, etc. If you wish to localize this file, please create a + // localized share/templates/default.xx.svg file, where xx is your language code. + char *default_template = g_build_filename(dirname, _("default.svg"), NULL); + if (Inkscape::IO::file_test(default_template, G_FILE_TEST_IS_REGULAR)) { + return sp_file_new(default_template); + } + } + g_free(dirname); + sources.pop_front(); + } + + return sp_file_new(NULL); +} + + +/*###################### +## D E L E T E +######################*/ + +/** + * Perform document closures preceding an exit() + */ +void +sp_file_exit() +{ + sp_ui_close_all(); + // no need to call inkscape_exit here; last document being closed will take care of that +} + + +/*###################### +## O P E N +######################*/ + +/** + * Open a file, add the document to the desktop + * + * \param replace_empty if true, and the current desktop is empty, this document + * will replace the empty one. + */ +bool +sp_file_open(gchar const *uri, Inkscape::Extension::Extension *key, bool add_to_recent, bool replace_empty) +{ + SPDocument *doc; + try { + doc = Inkscape::Extension::open(key, uri); + } catch (Inkscape::Extension::Input::no_extension_found &e) { + doc = NULL; + } catch (Inkscape::Extension::Input::open_failed &e) { + doc = NULL; + } + + if (doc) { + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + SPDocument *existing = desktop ? SP_DT_DOCUMENT(desktop) : NULL; + + if (existing && existing->virgin && replace_empty) { + // If the current desktop is empty, open the document there + desktop->change_document(doc); + } else { + if (!Inkscape::NSApplication::Application::getNewGui()) { + // create a whole new desktop and window + SPViewWidget *dtw = sp_desktop_widget_new(sp_document_namedview(doc, NULL)); + sp_create_window(dtw, TRUE); + desktop = static_cast(dtw->view); + } else { + desktop = Inkscape::NSApplication::Editor::createDesktop (doc); + } + } + + doc->virgin = FALSE; + // everyone who cares now has a reference, get rid of ours + sp_document_unref(doc); + // resize the window to match the document properties + // (this may be redundant for new windows... if so, move to the "virgin" + // section above) +#ifdef WITH_INKBOARD + desktop->whiteboard_session_manager()->setDesktop(desktop); +#endif + sp_namedview_window_from_document(desktop); + + if (add_to_recent) { + prefs_set_recent_file(SP_DOCUMENT_URI(doc), SP_DOCUMENT_NAME(doc)); + } + + return TRUE; + } else { + gchar *safeUri = Inkscape::IO::sanitizeString(uri); + gchar *text = g_strdup_printf(_("Failed to load the requested file %s"), safeUri); + sp_ui_error_dialog(text); + g_free(text); + g_free(safeUri); + return FALSE; + } +} + +/** + * Handle prompting user for "do you want to revert"? Revert on "OK" + */ +void +sp_file_revert_dialog() +{ + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + g_assert(desktop != NULL); + + SPDocument *doc = SP_DT_DOCUMENT(desktop); + g_assert(doc != NULL); + + Inkscape::XML::Node *repr = sp_document_repr_root(doc); + g_assert(repr != NULL); + + gchar const *uri = doc->uri; + if (!uri) { + desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("Document not saved yet. Cannot revert.")); + return; + } + + bool do_revert = true; + if (repr->attribute("sodipodi:modified") != NULL) { + gchar *text = g_strdup_printf(_("Changes will be lost! Are you sure you want to reload document %s?"), uri); + + bool response = desktop->warnDialog (text); + g_free(text); + + if (!response) { + do_revert = false; + } + } + + bool reverted; + if (do_revert) { + // Allow overwriting of current document. + doc->virgin = TRUE; + reverted = sp_file_open(uri,NULL); + } else { + reverted = false; + } + + if (reverted) { + desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Document reverted.")); + } else { + desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("Document not reverted.")); + } +} + +void dump_str(gchar const *str, gchar const *prefix) +{ + Glib::ustring tmp; + tmp = prefix; + tmp += " ["; + size_t const total = strlen(str); + for (unsigned i = 0; i < total; i++) { + gchar *const tmp2 = g_strdup_printf(" %02x", (0x0ff & str[i])); + tmp += tmp2; + g_free(tmp2); + } + + tmp += "]"; + g_message(tmp.c_str()); +} + +void dump_ustr(Glib::ustring const &ustr) +{ + char const *cstr = ustr.c_str(); + char const *data = ustr.data(); + Glib::ustring::size_type const byteLen = ustr.bytes(); + Glib::ustring::size_type const dataLen = ustr.length(); + Glib::ustring::size_type const cstrLen = strlen(cstr); + + g_message(" size: %lu\n length: %lu\n bytes: %lu\n clen: %lu", + gulong(ustr.size()), gulong(dataLen), gulong(byteLen), gulong(cstrLen) ); + g_message( " ASCII? %s", (ustr.is_ascii() ? "yes":"no") ); + g_message( " UTF-8? %s", (ustr.validate() ? "yes":"no") ); + + try { + Glib::ustring tmp; + for (Glib::ustring::size_type i = 0; i < ustr.bytes(); i++) { + tmp = " "; + if (i < dataLen) { + Glib::ustring::value_type val = ustr.at(i); + gchar* tmp2 = g_strdup_printf( (((val & 0xff00) == 0) ? " %02x" : "%04x"), val ); + tmp += tmp2; + g_free( tmp2 ); + } else { + tmp += " "; + } + + if (i < byteLen) { + int val = (0x0ff & data[i]); + gchar *tmp2 = g_strdup_printf(" %02x", val); + tmp += tmp2; + g_free( tmp2 ); + if ( val > 32 && val < 127 ) { + tmp2 = g_strdup_printf( " '%c'", (gchar)val ); + tmp += tmp2; + g_free( tmp2 ); + } else { + tmp += " . "; + } + } else { + tmp += " "; + } + + if ( i < cstrLen ) { + int val = (0x0ff & cstr[i]); + gchar* tmp2 = g_strdup_printf(" %02x", val); + tmp += tmp2; + g_free(tmp2); + if ( val > 32 && val < 127 ) { + tmp2 = g_strdup_printf(" '%c'", (gchar) val); + tmp += tmp2; + g_free( tmp2 ); + } else { + tmp += " . "; + } + } else { + tmp += " "; + } + + g_message( tmp.c_str() ); + } + } catch (...) { + g_message("XXXXXXXXXXXXXXXXXX Exception" ); + } + g_message("---------------"); +} + +static Inkscape::UI::Dialogs::FileOpenDialog *openDialogInstance = NULL; + +/** + * Display an file Open selector. Open a document if OK is pressed. + * Can select single or multiple files for opening. + */ +void +sp_file_open_dialog(gpointer object, gpointer data) +{ + gchar *open_path2 = NULL; + + gchar *open_path = g_strdup(prefs_get_string_attribute("dialogs.open", "path")); + if (open_path != NULL && open_path[0] == '\0') { + g_free(open_path); + open_path = NULL; + } + if (open_path && !Inkscape::IO::file_test(open_path, (GFileTest)(G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))) { + g_free(open_path); + open_path = NULL; + } + if (open_path == NULL) + open_path = g_strconcat(g_get_home_dir(), G_DIR_SEPARATOR_S, NULL); + + if (!openDialogInstance) { + openDialogInstance = + Inkscape::UI::Dialogs::FileOpenDialog::create( + (char const *)open_path, + Inkscape::UI::Dialogs::SVG_TYPES, + (char const *)_("Select file to open")); + } + bool const success = openDialogInstance->show(); + gchar *fileName = ( success + ? g_strdup(openDialogInstance->getFilename()) + : NULL ); + Inkscape::Extension::Extension *selection = + openDialogInstance->getSelectionType(); + g_free(open_path); + + if (!success) return; + + // Code to check & open iff multiple files. + Glib::SListHandle flist=openDialogInstance->getFilenames(); + GSList *list=flist.data(); + + if(g_slist_length(list)>1) + { + gchar *fileName=NULL; + + while(list!=NULL) + { + +#ifdef INK_DUMP_FILENAME_CONV + g_message(" FileName: %s",(const char *)list->data); +#endif + + fileName=(gchar *)g_strdup((gchar *)list->data); + + if (fileName && !g_file_test(fileName,G_FILE_TEST_IS_DIR)) { + gsize bytesRead = 0; + gsize bytesWritten = 0; + GError *error = NULL; +#ifdef INK_DUMP_FILENAME_CONV + dump_str( fileName, "A file pre is " ); +#endif + gchar *newFileName = g_filename_to_utf8(fileName, + -1, + &bytesRead, + &bytesWritten, + &error); + if ( newFileName != NULL ) { + g_free(fileName); + fileName = newFileName; +#ifdef INK_DUMP_FILENAME_CONV + dump_str( fileName, "A file post is " ); +#endif + } else { + // TODO: bulia, please look over + g_warning( "ERROR CONVERTING OPEN FILENAME TO UTF-8" ); + } + +#ifdef INK_DUMP_FILENAME_CONV + g_message("Opening File %s\n",fileName); +#endif + + sp_file_open(fileName, selection); + g_free(fileName); + } + else + { + g_message("Cannot Open Directory %s\n",fileName); + } + + list=list->next; + } + + return; + } + + + if (fileName) { + gsize bytesRead = 0; + gsize bytesWritten = 0; + GError *error = NULL; +#ifdef INK_DUMP_FILENAME_CONV + dump_str( fileName, "A file pre is " ); +#endif + gchar *newFileName = g_filename_to_utf8(fileName, + -1, + &bytesRead, + &bytesWritten, + &error); + if ( newFileName != NULL ) { + g_free(fileName); + fileName = newFileName; +#ifdef INK_DUMP_FILENAME_CONV + dump_str( fileName, "A file post is " ); +#endif + } else { + // TODO: bulia, please look over + g_warning( "ERROR CONVERTING OPEN FILENAME TO UTF-8" ); + } + + + if ( !g_utf8_validate(fileName, -1, NULL) ) { + // TODO: bulia, please look over + g_warning( "INPUT FILENAME IS NOT UTF-8" ); + } + + + open_path = g_dirname(fileName); + open_path2 = g_strconcat(open_path, G_DIR_SEPARATOR_S, NULL); + prefs_set_string_attribute("dialogs.open", "path", open_path2); + g_free(open_path); + g_free(open_path2); + + sp_file_open(fileName, selection); + g_free(fileName); + } + + return; +} + + +/*###################### +## V A C U U M +######################*/ + +/** + * Remove unreferenced defs from the defs section of the document. + */ + + +void +sp_file_vacuum() +{ + SPDocument *doc = SP_ACTIVE_DOCUMENT; + + unsigned int diff = vacuum_document (doc); + + sp_document_done(doc); + + SPDesktop *dt = SP_ACTIVE_DESKTOP; + if (diff > 0) { + dt->messageStack()->flashF(Inkscape::NORMAL_MESSAGE, + ngettext("Removed %i unused definition in <defs>.", + "Removed %i unused definitions in <defs>.", + diff), + diff); + } else { + dt->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("No unused definitions in <defs>.")); + } +} + + + +/*###################### +## S A V E +######################*/ + +/** + * This 'save' function called by the others below + */ +static bool +file_save(SPDocument *doc, gchar const *uri, Inkscape::Extension::Extension *key, bool saveas) +{ + if (!doc || !uri) //Safety check + return FALSE; + + try { + Inkscape::Extension::save(key, doc, uri, + saveas && prefs_get_int_attribute("dialogs.save_as", "append_extension", 1), + saveas, TRUE); // save officially, with inkscape: attributes set + } catch (Inkscape::Extension::Output::no_extension_found &e) { + gchar *safeUri = Inkscape::IO::sanitizeString(uri); + gchar *text = g_strdup_printf(_("No Inkscape extension found to save document (%s). This may have been caused by an unknown filename extension."), safeUri); + SP_ACTIVE_DESKTOP->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("Document not saved.")); + sp_ui_error_dialog(text); + g_free(text); + g_free(safeUri); + return FALSE; + } catch (Inkscape::Extension::Output::save_failed &e) { + gchar *safeUri = Inkscape::IO::sanitizeString(uri); + gchar *text = g_strdup_printf(_("File %s could not be saved."), safeUri); + SP_ACTIVE_DESKTOP->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("Document not saved.")); + sp_ui_error_dialog(text); + g_free(text); + g_free(safeUri); + return FALSE; + } catch (Inkscape::Extension::Output::no_overwrite &e) { + return sp_file_save_dialog(doc); + } + + SP_ACTIVE_DESKTOP->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Document saved.")); + return TRUE; +} + +static Inkscape::UI::Dialogs::FileSaveDialog *saveDialogInstance = NULL; + +/** + * Display a SaveAs dialog. Save the document if OK pressed. + */ +gboolean +sp_file_save_dialog(SPDocument *doc) +{ + Inkscape::XML::Node *repr = sp_document_repr_root(doc); + gchar const *default_extension = NULL; + gchar *save_loc; + Inkscape::Extension::Output *extension; + gchar *save_path = NULL; + + default_extension = repr->attribute("inkscape:output_extension"); + if (default_extension == NULL) { + default_extension = prefs_get_string_attribute("dialogs.save_as", "default"); + } + //g_warning("%s: extension name: '%s'", __FUNCTION__, default_extension); + + if (doc->uri == NULL) { + int i = 1; + char const *filename_extension; + char *temp_filename; + + extension = dynamic_cast(Inkscape::Extension::db.get(default_extension)); + //g_warning("%s: extension ptr: 0x%x", __FUNCTION__, (unsigned int)extension); + if (extension == NULL) { + filename_extension = ".svg"; + } else { + filename_extension = extension->get_extension(); + } + + save_path = g_strdup(prefs_get_string_attribute("dialogs.save_as", "path")); + if (save_path != NULL && save_path[0] == '\0') { + g_free(save_path); + save_path = NULL; + } + if (save_path && !Inkscape::IO::file_test(save_path, (GFileTest)(G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))) { + g_free(save_path); + save_path = NULL; + } + if (save_path == NULL) + save_path = g_strdup(g_get_home_dir()); + temp_filename = g_strdup_printf(_("drawing%s"), filename_extension); + save_loc = g_build_filename(save_path, temp_filename, NULL); + g_free(temp_filename); + + while (Inkscape::IO::file_test(save_loc, G_FILE_TEST_EXISTS)) { + g_free(save_loc); + temp_filename = g_strdup_printf(_("drawing-%d%s"), i++, filename_extension); + save_loc = g_build_filename(save_path, temp_filename, NULL); + g_free(temp_filename); + } + } else { + save_loc = g_path_get_dirname(doc->uri); /* \todo should use a getter */ + } + + { // convert save_loc from utf-8 to locale + // is this needed any more, now that everything is handled in + // Inkscape::IO? + gsize bytesRead = 0; + gsize bytesWritten = 0; + GError* error = NULL; +#ifdef INK_DUMP_FILENAME_CONV + dump_str( save_loc, "B file pre is " ); +#endif + gchar* save_loc_local = g_filename_from_utf8( save_loc, -1, &bytesRead, &bytesWritten, &error); + + if ( save_loc_local != NULL ) { + g_free(save_loc); + save_loc = save_loc_local; +#ifdef INK_DUMP_FILENAME_CONV + dump_str( save_loc, "B file post is " ); +#endif + } else { + //g_warning( "Error converting save filename stored in the file to locale encoding."); + } + } + + if (!saveDialogInstance) { + saveDialogInstance = + Inkscape::UI::Dialogs::FileSaveDialog::create( + (char const *) save_loc, + Inkscape::UI::Dialogs::SVG_TYPES, + (char const *) _("Select file to save to"), + default_extension + ); + } // FIXME: else (i.e. if reshowing an already shown dialog) save_loc is not used, it thus always displays the previously opened dir + bool success = saveDialogInstance->show(); + char *fileName = ( success + ? g_strdup(saveDialogInstance->getFilename()) + : NULL ); + Inkscape::Extension::Extension *selectionType = + saveDialogInstance->getSelectionType(); + g_free(save_loc); + g_free(save_path); + if (!success) { + return success; + } + + if (fileName && *fileName) { + gsize bytesRead = 0; + gsize bytesWritten = 0; + GError *error = NULL; +#ifdef INK_DUMP_FILENAME_CONV + dump_str( fileName, "C file pre is " ); +#endif + gchar *newFileName = g_filename_to_utf8(fileName, + -1, + &bytesRead, + &bytesWritten, + &error); + if ( newFileName != NULL ) { + g_free(fileName); + fileName = newFileName; +#ifdef INK_DUMP_FILENAME_CONV + dump_str( fileName, "C file post is " ); +#endif + } else { + g_warning( "Error converting save filename to UTF-8." ); + } + + if (!g_utf8_validate(fileName, -1, NULL)) { + // TODO: bulia, please look over + g_warning( "The filename is not UTF-8." ); + } + + success = file_save(doc, fileName, selectionType, TRUE); + + if (success) { + prefs_set_recent_file(SP_DOCUMENT_URI(doc), SP_DOCUMENT_NAME(doc)); + } + + save_path = g_dirname(fileName); + prefs_set_string_attribute("dialogs.save_as", "path", save_path); + g_free(save_path); + + g_free(fileName); + return success; + } else { + return FALSE; + } +} + + +/** + * Save a document, displaying a SaveAs dialog if necessary. + */ +gboolean +sp_file_save_document(SPDocument *doc) +{ + gboolean success = TRUE; + + Inkscape::XML::Node *repr = sp_document_repr_root(doc); + + gchar const *fn = repr->attribute("sodipodi:modified"); + if (fn != NULL) { + if (doc->uri == NULL + || repr->attribute("inkscape:output_extension") == NULL) + { + return sp_file_save_dialog(doc); + } else { + fn = g_strdup(doc->uri); + gchar const *ext = repr->attribute("inkscape:output_extension"); + success = file_save(doc, fn, Inkscape::Extension::db.get(ext), FALSE); + g_free((void *) fn); + } + } else { + SP_ACTIVE_DESKTOP->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("No changes need to be saved.")); + success = TRUE; + } + + return success; +} + + +/** + * Save a document. + */ +bool +sp_file_save(gpointer object, gpointer data) +{ + if (!SP_ACTIVE_DOCUMENT) + return false; + sp_namedview_document_from_window(SP_ACTIVE_DESKTOP); + return sp_file_save_document(SP_ACTIVE_DOCUMENT); +} + + +/** + * Save a document, always displaying the SaveAs dialog. + */ +bool +sp_file_save_as(gpointer object, gpointer data) +{ + if (!SP_ACTIVE_DOCUMENT) + return false; + sp_namedview_document_from_window(SP_ACTIVE_DESKTOP); + return sp_file_save_dialog(SP_ACTIVE_DOCUMENT); +} + + + + +/*###################### +## I M P O R T +######################*/ + +/** + * Import a resource. Called by sp_file_import() + */ +void +file_import(SPDocument *in_doc, gchar const *uri, Inkscape::Extension::Extension *key) +{ + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + + //DEBUG_MESSAGE( fileImport, "file_import( in_doc:%p uri:[%s], key:%p", in_doc, uri, key ); + SPDocument *doc; + try { + doc = Inkscape::Extension::open(key, uri); + } catch (Inkscape::Extension::Input::no_extension_found &e) { + doc = NULL; + } catch (Inkscape::Extension::Input::open_failed &e) { + doc = NULL; + } + + if (doc != NULL) { + // the import extension has passed us a document, now we need to embed it into our document + if ( 0 ) { +// const gchar *docbase = (sp_repr_document_root( sp_repr_document( repr ))->attribute("sodipodi:docbase" ); + g_message(" settings uri [%s]", doc->uri ); + g_message(" base [%s]", doc->base ); + g_message(" name [%s]", doc->name ); + Inkscape::IO::fixupHrefs( doc, doc->base, TRUE ); + g_message(" mid-fixup"); + Inkscape::IO::fixupHrefs( doc, in_doc->base, TRUE ); + } + + // move imported defs to our document's defs + SPObject *in_defs = SP_DOCUMENT_DEFS(in_doc); + SPObject *defs = SP_DOCUMENT_DEFS(doc); + Inkscape::XML::Node *last_def = SP_OBJECT_REPR(in_defs)->lastChild(); + for (SPObject *child = sp_object_first_child(defs); + child != NULL; child = SP_OBJECT_NEXT(child)) + { + // FIXME: in case of id conflict, newly added thing will be re-ided and thus likely break a reference to it from imported stuff + SP_OBJECT_REPR(in_defs)->addChild(SP_OBJECT_REPR(child)->duplicate(), last_def); + } + + guint items_count = 0; + for (SPObject *child = sp_object_first_child(SP_DOCUMENT_ROOT(doc)); + child != NULL; child = SP_OBJECT_NEXT(child)) { + if (SP_IS_ITEM(child)) + items_count ++; + } + SPCSSAttr *style = sp_css_attr_from_object (SP_DOCUMENT_ROOT (doc)); + + SPObject *new_obj = NULL; + + if ((style && style->firstChild()) || items_count > 1) { + // create group + Inkscape::XML::Node *newgroup = sp_repr_new("svg:g"); + sp_repr_css_set (newgroup, style, "style"); + + for (SPObject *child = sp_object_first_child(SP_DOCUMENT_ROOT(doc)); child != NULL; child = SP_OBJECT_NEXT(child) ) { + if (SP_IS_ITEM(child)) { + Inkscape::XML::Node *newchild = SP_OBJECT_REPR(child)->duplicate(); + + // convert layers to groups; FIXME: add "preserve layers" mode where each layer + // from impot is copied to the same-named layer in host + newchild->setAttribute("inkscape:groupmode", NULL); + + newgroup->appendChild(newchild); + } + } + + if (desktop) { + // Add it to the current layer + new_obj = desktop->currentLayer()->appendChildRepr(newgroup); + } else { + // There's no desktop (command line run?) + // FIXME: For such cases we need a document:: method to return the current layer + new_obj = SP_DOCUMENT_ROOT(in_doc)->appendChildRepr(newgroup); + } + + Inkscape::GC::release(newgroup); + } else { + // just add one item + for (SPObject *child = sp_object_first_child(SP_DOCUMENT_ROOT(doc)); child != NULL; child = SP_OBJECT_NEXT(child) ) { + if (SP_IS_ITEM(child)) { + Inkscape::XML::Node *newitem = SP_OBJECT_REPR(child)->duplicate(); + newitem->setAttribute("inkscape:groupmode", NULL); + + if (desktop) { + // Add it to the current layer + new_obj = desktop->currentLayer()->appendChildRepr(newitem); + } else { + // There's no desktop (command line run?) + // FIXME: For such cases we need a document:: method to return the current layer + new_obj = SP_DOCUMENT_ROOT(in_doc)->appendChildRepr(newitem); + } + + } + } + } + + if (style) sp_repr_css_attr_unref (style); + + // select and move the imported item + if (new_obj && SP_IS_ITEM(new_obj)) { + Inkscape::Selection *selection = SP_DT_SELECTION(desktop); + selection->set(SP_ITEM(new_obj)); + + // To move the imported object, we must temporarily set the "transform pattern with + // object" option. + { + int const saved_pref = prefs_get_int_attribute("options.transform", "pattern", 1); + prefs_set_int_attribute("options.transform", "pattern", 1); + sp_document_ensure_up_to_date(SP_DT_DOCUMENT(desktop)); + NR::Point m( desktop->point() - selection->bounds().midpoint() ); + sp_selection_move_relative(selection, m); + prefs_set_int_attribute("options.transform", "pattern", saved_pref); + } + } + + sp_document_unref(doc); + sp_document_done(in_doc); + + } else { + gchar *text = g_strdup_printf(_("Failed to load the requested file %s"), uri); + sp_ui_error_dialog(text); + g_free(text); + } + + return; +} + + +static Inkscape::UI::Dialogs::FileOpenDialog *importDialogInstance = NULL; + +/** + * Display an Open dialog, import a resource if OK pressed. + */ +void +sp_file_import(GtkWidget *widget) +{ + SPDocument *doc = SP_ACTIVE_DOCUMENT; + if (!doc) + return; + + if (!importDialogInstance) { + importDialogInstance = + Inkscape::UI::Dialogs::FileOpenDialog::create( + (char const *)import_path, + Inkscape::UI::Dialogs::IMPORT_TYPES, + (char const *)_("Select file to import")); + } + bool success = importDialogInstance->show(); + char *fileName = ( success + ? g_strdup(importDialogInstance->getFilename()) + : NULL ); + Inkscape::Extension::Extension *selection = + importDialogInstance->getSelectionType(); + + if (!success) return; + if (fileName) { + gsize bytesRead = 0; + gsize bytesWritten = 0; + GError *error = NULL; +#ifdef INK_DUMP_FILENAME_CONV + dump_str( fileName, "D file pre is " ); +#endif + gchar *newFileName = g_filename_to_utf8( fileName, + -1, + &bytesRead, + &bytesWritten, + &error); + if ( newFileName != NULL ) { + g_free(fileName); + fileName = newFileName; +#ifdef INK_DUMP_FILENAME_CONV + dump_str( fileName, "D file post is " ); +#endif + } else { + // TODO: bulia, please look over + g_warning( "ERROR CONVERTING OPEN FILENAME TO UTF-8" ); + } + + + if (!g_utf8_validate(fileName, -1, NULL)) { + // TODO: bulia, please look over + g_warning( "INPUT FILENAME IS NOT UTF-8" ); + } + + g_free(import_path); + import_path = g_dirname(fileName); + if (import_path) import_path = g_strconcat(import_path, G_DIR_SEPARATOR_S, NULL); + + file_import(doc, fileName, selection); + g_free(fileName); + } + + return; +} + + + +/*###################### +## E X P O R T +######################*/ + +/** + * + */ +void +sp_file_export_dialog(void *widget) +{ + sp_export_dialog(); +} + +#include +#include + +struct SPEBP { + int width, height, sheight; + guchar r, g, b, a; + NRArenaItem *root; // the root arena item to show; it is assumed that all unneeded items are hidden + guchar *px; + unsigned (*status)(float, void *); + void *data; +}; + + +/** + * + */ +static int +sp_export_get_rows(guchar const **rows, int row, int num_rows, void *data) +{ + struct SPEBP *ebp = (struct SPEBP *) data; + + if (ebp->status) { + if (!ebp->status((float) row / ebp->height, ebp->data)) return 0; + } + + num_rows = MIN(num_rows, ebp->sheight); + num_rows = MIN(num_rows, ebp->height - row); + + /* Set area of interest */ + NRRectL bbox; + bbox.x0 = 0; + bbox.y0 = row; + bbox.x1 = ebp->width; + bbox.y1 = row + num_rows; + /* Update to renderable state */ + NRGC gc(NULL); + nr_matrix_set_identity(&gc.transform); + + nr_arena_item_invoke_update(ebp->root, &bbox, &gc, NR_ARENA_ITEM_STATE_ALL, NR_ARENA_ITEM_STATE_NONE); + + NRPixBlock pb; + nr_pixblock_setup_extern(&pb, NR_PIXBLOCK_MODE_R8G8B8A8N, + bbox.x0, bbox.y0, bbox.x1, bbox.y1, + ebp->px, 4 * ebp->width, FALSE, FALSE); + + for (int r = 0; r < num_rows; r++) { + guchar *p = NR_PIXBLOCK_PX(&pb) + r * pb.rs; + for (int c = 0; c < ebp->width; c++) { + *p++ = ebp->r; + *p++ = ebp->g; + *p++ = ebp->b; + *p++ = ebp->a; + } + } + + /* Render */ + nr_arena_item_invoke_render(ebp->root, &bbox, &pb, 0); + + for (int r = 0; r < num_rows; r++) { + rows[r] = NR_PIXBLOCK_PX(&pb) + r * pb.rs; + } + + nr_pixblock_release(&pb); + + return num_rows; +} + +/** +Hide all items which are not listed in list, recursively, skipping groups and defs +*/ +void +hide_other_items_recursively(SPObject *o, GSList *list, unsigned dkey) +{ + if (SP_IS_ITEM(o) + && !SP_IS_DEFS(o) + && !SP_IS_ROOT(o) + && !SP_IS_GROUP(o) + && !g_slist_find(list, o)) + { + sp_item_invoke_hide(SP_ITEM(o), dkey); + } + + // recurse + if (!g_slist_find(list, o)) { + for (SPObject *child = sp_object_first_child(o) ; child != NULL; child = SP_OBJECT_NEXT(child) ) { + hide_other_items_recursively(child, list, dkey); + } + } +} + + +/** + * Render the SVG drawing onto a PNG raster image, then save to + * a file. Returns TRUE if succeeded in writing the file, + * FALSE otherwise. + */ +int +sp_export_png_file(SPDocument *doc, gchar const *filename, + double x0, double y0, double x1, double y1, + unsigned width, unsigned height, + unsigned long bgcolor, + unsigned (*status)(float, void *), + void *data, bool force_overwrite, + GSList *items_only) +{ + int write_status = TRUE; + g_return_val_if_fail(doc != NULL, FALSE); + g_return_val_if_fail(filename != NULL, FALSE); + g_return_val_if_fail(width >= 1, FALSE); + g_return_val_if_fail(height >= 1, FALSE); + + if (!force_overwrite && !sp_ui_overwrite_file(filename)) { + return FALSE; + } + + sp_document_ensure_up_to_date(doc); + + /* Go to document coordinates */ + gdouble t = y0; + y0 = sp_document_height(doc) - y1; + y1 = sp_document_height(doc) - t; + + /* + * 1) a[0] * x0 + a[2] * y1 + a[4] = 0.0 + * 2) a[1] * x0 + a[3] * y1 + a[5] = 0.0 + * 3) a[0] * x1 + a[2] * y1 + a[4] = width + * 4) a[1] * x0 + a[3] * y0 + a[5] = height + * 5) a[1] = 0.0; + * 6) a[2] = 0.0; + * + * (1,3) a[0] * x1 - a[0] * x0 = width + * a[0] = width / (x1 - x0) + * (2,4) a[3] * y0 - a[3] * y1 = height + * a[3] = height / (y0 - y1) + * (1) a[4] = -a[0] * x0 + * (2) a[5] = -a[3] * y1 + */ + + NRMatrix affine; + affine.c[0] = width / (x1 - x0); + affine.c[1] = 0.0; + affine.c[2] = 0.0; + affine.c[3] = height / (y1 - y0); + affine.c[4] = -affine.c[0] * x0; + affine.c[5] = -affine.c[3] * y0; + + //SP_PRINT_MATRIX("SVG2PNG", &affine); + + struct SPEBP ebp; + ebp.width = width; + ebp.height = height; + ebp.r = NR_RGBA32_R(bgcolor); + ebp.g = NR_RGBA32_G(bgcolor); + ebp.b = NR_RGBA32_B(bgcolor); + ebp.a = NR_RGBA32_A(bgcolor); + + /* Create new arena */ + NRArena *arena = NRArena::create(); + unsigned dkey = sp_item_display_key_new(1); + + /* Create ArenaItems and set transform */ + ebp.root = sp_item_invoke_show(SP_ITEM(sp_document_root(doc)), arena, dkey, SP_ITEM_SHOW_DISPLAY); + nr_arena_item_set_transform(NR_ARENA_ITEM(ebp.root), NR::Matrix(&affine)); + + // We show all and then hide all items we don't want, instead of showing only requested items, + // because that would not work if the shown item references something in defs + if (items_only) { + hide_other_items_recursively(sp_document_root(doc), items_only, dkey); + } + + ebp.status = status; + ebp.data = data; + + if ((width < 256) || ((width * height) < 32768)) { + ebp.px = nr_pixelstore_64K_new(FALSE, 0); + ebp.sheight = 65536 / (4 * width); + write_status = sp_png_write_rgba_striped(filename, width, height, sp_export_get_rows, &ebp); + nr_pixelstore_64K_free(ebp.px); + } else { + ebp.px = nr_new(guchar, 4 * 64 * width); + ebp.sheight = 64; + write_status = sp_png_write_rgba_striped(filename, width, height, sp_export_get_rows, &ebp); + nr_free(ebp.px); + } + + // Hide items + sp_item_invoke_hide(SP_ITEM(sp_document_root(doc)), dkey); + + /* Free Arena and ArenaItem */ + nr_arena_item_unref(ebp.root); + nr_object_unref((NRObject *) arena); + return write_status; +} + + +/*###################### +## P R I N T +######################*/ + + +/** + * Print the current document, if any. + */ +void +sp_file_print() +{ + SPDocument *doc = SP_ACTIVE_DOCUMENT; + if (doc) + sp_print_document(doc, FALSE); +} + + +/** + * Print the current document, if any. Do not use + * the machine's print drivers. + */ +void +sp_file_print_direct() +{ + SPDocument *doc = SP_ACTIVE_DOCUMENT; + if (doc) + sp_print_document(doc, TRUE); +} + + +/** + * Display what the drawing would look like, if + * printed. + */ +void +sp_file_print_preview(gpointer object, gpointer data) +{ + + SPDocument *doc = SP_ACTIVE_DOCUMENT; + if (doc) + sp_print_preview_document(doc); + +} + +void Inkscape::IO::fixupHrefs( SPDocument *doc, const gchar *base, gboolean spns ) +{ + //g_message("Inkscape::IO::fixupHrefs( , [%s], )", base ); + + if ( 0 ) { + gchar const* things[] = { + "data:foo,bar", + "http://www.google.com/image.png", + "ftp://ssd.com/doo", + "/foo/dee/bar.svg", + "foo.svg", + "file:/foo/dee/bar.svg", + "file:///foo/dee/bar.svg", + "file:foo.svg", + "/foo/bar\xe1\x84\x92.svg", + "file:///foo/bar\xe1\x84\x92.svg", + "file:///foo/bar%e1%84%92.svg", + "/foo/bar%e1%84%92.svg", + "bar\xe1\x84\x92.svg", + "bar%e1%84%92.svg", + NULL + }; + g_message("+------"); + for ( int i = 0; things[i]; i++ ) + { + try + { + URI uri(things[i]); + gboolean isAbs = g_path_is_absolute( things[i] ); + gchar *str = uri.toString(); + g_message( "abs:%d isRel:%d scheme:[%s] path:[%s][%s] uri[%s] / [%s]", (int)isAbs, + (int)uri.isRelative(), + uri.getScheme(), + uri.getPath(), + uri.getOpaque(), + things[i], + str ); + g_free(str); + } + catch ( MalformedURIException err ) + { + dump_str( things[i], "MalformedURIException" ); + xmlChar *redo = xmlURIEscape((xmlChar const *)things[i]); + g_message(" gone from [%s] to [%s]", things[i], redo ); + if ( redo == NULL ) + { + URI again = URI::fromUtf8( things[i] ); + gboolean isAbs = g_path_is_absolute( things[i] ); + gchar *str = again.toString(); + g_message( "abs:%d isRel:%d scheme:[%s] path:[%s][%s] uri[%s] / [%s]", (int)isAbs, + (int)again.isRelative(), + again.getScheme(), + again.getPath(), + again.getOpaque(), + things[i], + str ); + g_free(str); + g_message(" ----"); + } + } + } + g_message("+------"); + } + + GSList const *images = sp_document_get_resource_list(doc, "image"); + for (GSList const *l = images; l != NULL; l = l->next) { + Inkscape::XML::Node *ir = SP_OBJECT_REPR(l->data); + + const gchar *href = ir->attribute("xlink:href"); + + // First try to figure out an absolute path to the asset + //g_message("image href [%s]", href ); + if (spns && !g_path_is_absolute(href)) { + const gchar *absref = ir->attribute("sodipodi:absref"); + const gchar *base_href = g_build_filename(base, href, NULL); + //g_message(" absr [%s]", absref ); + + if ( absref && Inkscape::IO::file_test(absref, G_FILE_TEST_EXISTS) && !Inkscape::IO::file_test(base_href, G_FILE_TEST_EXISTS)) + { + // only switch over if the absref is valid while href is not + href = absref; + //g_message(" copied absref to href"); + } + } + + // Once we have an absolute path, convert it relative to the new location + if (href && g_path_is_absolute(href)) { + const gchar *relname = sp_relative_path_from_path(href, base); + //g_message(" setting to [%s]", relname ); + ir->setAttribute("xlink:href", relname); + } +// TODO next refinement is to make the first choice keeping the relative path as-is if +// based on the new location it gives us a valid file. + } +} + + +/* + 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 : diff --git a/src/file.h b/src/file.h new file mode 100644 index 000000000..af053f027 --- /dev/null +++ b/src/file.h @@ -0,0 +1,171 @@ +#ifndef __SP_FILE_H__ +#define __SP_FILE_H__ + +/* + * File/Print operations + * + * Authors: + * Lauris Kaplinski + * Chema Celorio + * + * Copyright (C) 1999-2002 Authors + * Copyright (C) 2001-2002 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include + +#include "forward.h" +#include +#include + +/*###################### +## N E W +######################*/ + +/** + * Creates a new Inkscape document and window. + * Return value is a pointer to the newly created desktop. + */ +SPDesktop* sp_file_new (const gchar *templ); +SPDesktop* sp_file_new_default (void); + +/*###################### +## D E L E T E +######################*/ + +/** + * Close the document/view + */ +void sp_file_exit (void); + +/*###################### +## O P E N +######################*/ + +/** + * Opens a new file and window from the given URI + */ +bool sp_file_open( + const gchar *uri, Inkscape::Extension::Extension *key, + bool add_to_recent = true, bool replace_empty = true + ); + +/** + * Displays a file open dialog. Calls sp_file_open on + * an OK. + */ +void sp_file_open_dialog (gpointer object, gpointer data); + +/** + * Reverts file to disk-copy on "YES" + */ +void sp_file_revert_dialog (); + +/*###################### +## S A V E +######################*/ + +/** + * + */ +bool sp_file_save (gpointer object, gpointer data); + +/** + * Saves the given document. Displays a file select dialog + * to choose the new name. + */ +bool sp_file_save_as (gpointer object, gpointer data); + +/** + * Saves the given document. Displays a file select dialog + * if needed. + */ +gboolean sp_file_save_document (SPDocument *document); + +/* Do the saveas dialog with a document as the parameter */ +gboolean sp_file_save_dialog (SPDocument *doc); + + +/*###################### +## I M P O R T +######################*/ + +/** + * Displays a file selector dialog, to allow the + * user to import data into the current document. + */ +void sp_file_import (GtkWidget * widget); + +/** + * Imports a resource + */ +void file_import(SPDocument *in_doc, gchar const *uri, Inkscape::Extension::Extension *key); + +/*###################### +## E X P O R T +######################*/ + +/** + * Displays a "Save as" dialog for the user, with an + * additional type selection, to allow the user to export + * the a document as a given type. + */ +void sp_file_export_dialog (void *widget); + +/** + * Export the given document as a Portable Network Graphics (PNG) + * file. Returns FALSE if an error was encountered while writing + * the file, TRUE otherwise. + */ +int sp_export_png_file (SPDocument *doc, const gchar *filename, + double x0, double y0, double x1, double y1, + unsigned int width, unsigned int height, + unsigned long bgcolor, + unsigned int (*status) (float, void *), void *data, bool force_overwrite = false, GSList *items_only = NULL); + + +/*###################### +## P R I N T +######################*/ + +/* These functions are redundant now, but +would be useful as instance methods +*/ + +/** + * + */ +void sp_file_print (void); + +/** + * + */ +void sp_file_print_direct (void); + +/** + * + */ +void sp_file_print_preview (gpointer object, gpointer data); + +/*##################### +## U T I L I T Y +#####################*/ + +/** + * clean unused defs out of file + */ +void sp_file_vacuum (); + + +namespace Inkscape { +namespace IO { + +void fixupHrefs( SPDocument *doc, const gchar *uri, gboolean spns ); + +} +} + + +#endif diff --git a/src/fill-or-stroke.h b/src/fill-or-stroke.h new file mode 100644 index 000000000..d0b174dca --- /dev/null +++ b/src/fill-or-stroke.h @@ -0,0 +1,9 @@ +#ifndef SEEN_FILL_OR_STROKE_H +#define SEEN_FILL_OR_STROKE_H + +/** \file Definition of the FillOrStroke enum. */ + +/** \post STROKE == 0, FILL != 0. */ +enum FillOrStroke { STROKE = 0, FILL = 1 }; + +#endif /* !SEEN_FILL_OR_STROKE_H */ diff --git a/src/fixes.cpp b/src/fixes.cpp new file mode 100644 index 000000000..72498c448 --- /dev/null +++ b/src/fixes.cpp @@ -0,0 +1,193 @@ +/* + * + * This is the header file to include to fix any broken definitions or funcs + * + * $Id$ + * + * 2004 Kees Cook + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * http://www.gnu.org/copyleft/gpl.html + * + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#if defined(g_ascii_strtod) +/* + * until 2004-04-22, g_ascii_strtod could not handle having a locale-based + * decimal separator immediately following the number ("5,4" would + * parse to "5,4" instead of "5.0" in fr_FR) + * + * This is the corrected function, lifted from 1.107 gstrfuncs.c in glib + */ +extern "C" { +#include +#include +#include +#include +#include + +gdouble +fixed_g_ascii_strtod (const gchar *nptr, + gchar **endptr) +{ + gchar *fail_pos; + gdouble val; + struct lconv *locale_data; + const char *decimal_point; + int decimal_point_len; + const char *p, *decimal_point_pos; + const char *end = NULL; /* Silence gcc */ + + g_return_val_if_fail (nptr != NULL, 0); + + fail_pos = NULL; + + locale_data = localeconv (); + decimal_point = locale_data->decimal_point; + decimal_point_len = strlen (decimal_point); + + g_assert (decimal_point_len != 0); + + decimal_point_pos = NULL; + if (decimal_point[0] != '.' || + decimal_point[1] != 0) + { + p = nptr; + /* Skip leading space */ + while (g_ascii_isspace (*p)) + p++; + + /* Skip leading optional sign */ + if (*p == '+' || *p == '-') + p++; + + if (p[0] == '0' && + (p[1] == 'x' || p[1] == 'X')) + { + p += 2; + /* HEX - find the (optional) decimal point */ + + while (g_ascii_isxdigit (*p)) + p++; + + if (*p == '.') + { + decimal_point_pos = p++; + + while (g_ascii_isxdigit (*p)) + p++; + + if (*p == 'p' || *p == 'P') + p++; + if (*p == '+' || *p == '-') + p++; + while (g_ascii_isdigit (*p)) + p++; + } + } + else + { + while (g_ascii_isdigit (*p)) + p++; + + if (*p == '.') + { + decimal_point_pos = p++; + + while (g_ascii_isdigit (*p)) + p++; + + if (*p == 'e' || *p == 'E') + p++; + if (*p == '+' || *p == '-') + p++; + while (g_ascii_isdigit (*p)) + p++; + } + } + /* For the other cases, we need not convert the decimal point */ + end = p; + } + + /* Set errno to zero, so that we can distinguish zero results + and underflows */ + errno = 0; + + if (decimal_point_pos) + { + char *copy, *c; + + /* We need to convert the '.' to the locale specific decimal point */ + copy = (char*)g_malloc (end - nptr + 1 + decimal_point_len); + + c = copy; + memcpy (c, nptr, decimal_point_pos - nptr); + c += decimal_point_pos - nptr; + memcpy (c, decimal_point, decimal_point_len); + c += decimal_point_len; + memcpy (c, decimal_point_pos + 1, end - (decimal_point_pos + 1)); + c += end - (decimal_point_pos + 1); + *c = 0; + + val = strtod (copy, &fail_pos); + + if (fail_pos) + { + if (fail_pos - copy > decimal_point_pos - nptr) + fail_pos = (char *)nptr + (fail_pos - copy) - (decimal_point_len - 1); + else + fail_pos = (char *)nptr + (fail_pos - copy); + } + + g_free (copy); + + } + else if (decimal_point[0] != '.' || + decimal_point[1] != 0) + { + char *copy; + + copy = (char*)g_malloc (end - (char *)nptr + 1); + memcpy (copy, nptr, end - nptr); + *(copy + (end - (char *)nptr)) = 0; + + val = strtod (copy, &fail_pos); + + if (fail_pos) + { + fail_pos = (char *)nptr + (fail_pos - copy); + } + + g_free (copy); + } + else + { + val = strtod (nptr, &fail_pos); + } + + if (endptr) + *endptr = fail_pos; + + return val; +} +} + +#endif /* BROKEN_G_ASCII_STRTOD */ + + diff --git a/src/fontsize-expansion.cpp b/src/fontsize-expansion.cpp new file mode 100644 index 000000000..50169c3c2 --- /dev/null +++ b/src/fontsize-expansion.cpp @@ -0,0 +1,30 @@ +#include "libnr/nr-matrix-ops.h" + +/** + * Returns the distance from the transformed baseline to the + * transformation of a point at (0, 1); or 0 if \a m has no inverse. + */ +double +fontsize_expansion(NR::Matrix const &m) +{ + double const denom(hypot(m[0], m[1])); + if (!(denom > 1e-100)) { + return 0.; + } + double const numer(m.descrim2()); + if (!(numer > 1e-100)) { + return 0.; + } + return numer / denom; +} + +/* + 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:textwidth=99 : diff --git a/src/fontsize-expansion.h b/src/fontsize-expansion.h new file mode 100644 index 000000000..2477cd49c --- /dev/null +++ b/src/fontsize-expansion.h @@ -0,0 +1,9 @@ +#ifndef INKSCAPE_FONTSIZE_EXPANSION_H +#define INKSCAPE_FONTSIZE_EXPANSION_H + +#include "libnr/nr-forward.h" + +double fontsize_expansion(NR::Matrix const &m); + + +#endif /* !INKSCAPE_FONTSIZE_EXPANSION_H */ diff --git a/src/forward.h b/src/forward.h new file mode 100644 index 000000000..ef05ea026 --- /dev/null +++ b/src/forward.h @@ -0,0 +1,208 @@ +#ifndef __FORWARD_H__ +#define __FORWARD_H__ + +/* + * Forward declarations of most used objects + * + * Author: + * Lauris Kaplinski + * + * Copyright (C) 2001-2002 Lauris Kaplinski + * Copyright (C) 2001 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include + +/* Generic containers */ + +namespace Inkscape { +struct Application; +struct ApplicationClass; +} + +/* Editing window */ + +class SPDesktop; +class SPDesktopClass; + +class SPDesktopWidget; +class SPDesktopWidgetClass; + +GType sp_desktop_get_type (); + +class SPEventContext; +class SPEventContextClass; + +#define SP_TYPE_EVENT_CONTEXT (sp_event_context_get_type ()) +#define SP_EVENT_CONTEXT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), SP_TYPE_EVENT_CONTEXT, SPEventContext)) +#define SP_IS_EVENT_CONTEXT(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), SP_TYPE_EVENT_CONTEXT)) + +GType sp_event_context_get_type (); + +/* Document tree */ + +class SPDocument; +class SPDocumentClass; + +#define SP_TYPE_DOCUMENT (sp_document_get_type ()) +#define SP_DOCUMENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SP_TYPE_DOCUMENT, SPDocument)) +#define SP_IS_DOCUMENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_DOCUMENT)) + +GType sp_document_get_type (); + +/* Objects */ + +class SPObject; +class SPObjectClass; + +#define SP_TYPE_OBJECT (sp_object_get_type ()) +#define SP_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SP_TYPE_OBJECT, SPObject)) +#define SP_IS_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_OBJECT)) + +GType sp_object_get_type (); + +class SPItem; +class SPItemClass; + +#define SP_TYPE_ITEM (sp_item_get_type ()) +#define SP_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SP_TYPE_ITEM, SPItem)) +#define SP_IS_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_ITEM)) + +GType sp_item_get_type (); + +class SPGroup; +class SPGroupClass; + +class SPDefs; +class SPDefsClass; + +class SPRoot; +class SPRootClass; + +class SPNamedView; +class SPNamedViewClass; + +class SPGuide; +class SPGuideClass; + +class SPObjectGroup; +class SPObjectGroupClass; + +struct SPMarker; +struct SPMarkerClass; +class SPMarkerReference; + +class SPPath; +class SPPathClass; + +class SPShape; +class SPShapeClass; + +class SPPolygon; +class SPPolygonClass; + +class SPEllipse; +class SPEllipseClass; + +class SPCircle; +class SPCircleClass; + +class SPArc; +class SPArcClass; + +class SPChars; +class SPCharsClass; + +class SPText; +class SPTextClass; + +class SPTSpan; +class SPTSpanClass; + +class SPString; +class SPStringClass; + +class SPPaintServer; +class SPPaintServerClass; + +class SPStop; +class SPStopClass; + +class SPGradient; +class SPGradientClass; +class SPGradientReference; + +class SPLinearGradient; +class SPLinearGradientClass; + +class SPRadialGradient; +class SPRadialGradientClass; + +class SPPattern; + +class SPClipPath; +class SPClipPathClass; +class SPClipPathReference; + +class SPMaskReference; + +class SPAvoidRef; + +class SPAnchor; +class SPAnchorClass; + +/* Misc */ + +class ColorRGBA; + +class SPColorSpace; +class SPColor; + +class SPStyle; + +class SPEvent; + +class SPPrintContext; + +namespace Inkscape { +namespace UI { +namespace View { +class View; +}; +}; +}; + +class SPViewWidget; +class SPViewWidgetClass; + +class StopOnTrue; + +namespace Inkscape { +class URI; +class URIReference; +} + +struct box_solution; + + +/* verbs */ + +typedef int sp_verb_t; +namespace Inkscape { + class Verb; +} + +#endif /* !__FORWARD_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 : diff --git a/src/gc-alloc.h b/src/gc-alloc.h new file mode 100644 index 000000000..83811c0b3 --- /dev/null +++ b/src/gc-alloc.h @@ -0,0 +1,89 @@ +/* + * Inkscape::GC::Alloc - GC-aware STL allocator + * + * Copyright 2004 MenTaLguY + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * See the file COPYING for details. + * + */ + +#ifndef SEEN_INKSCAPE_GC_ALLOC_H +#define SEEN_INKSCAPE_GC_ALLOC_H + +#include +#include "gc-core.h" + +namespace Inkscape { + +namespace GC { + +template +class Alloc { +public: + typedef T value_type; + typedef T *pointer; + typedef T const *const_pointer; + typedef T &reference; + typedef T const &const_reference; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + + template + struct rebind { typedef Alloc other; }; + + Alloc() {} + template Alloc(Alloc const &) {} + + pointer address(reference r) { return &r; } + const_pointer address(const_reference r) { return &r; } + + size_type max_size() const { + return std::numeric_limits::max() / sizeof(T); + } + + pointer allocate(size_type count, void const * =NULL) { + return static_cast(::operator new(count * sizeof(T), SCANNED, collect)); + } + + void construct(pointer p, const_reference value) { + new (static_cast(p)) T(value); + } + void destroy(pointer p) { p->~T(); } + + void deallocate(pointer p, size_type) { ::operator delete(p, GC); } +}; + +// allocators with the same collection policy are interchangable + +template +bool operator==(Alloc const &, Alloc const &) { + return collect1 == collect2; +} + +template +bool operator!=(Alloc const &, Alloc const &) { + return collect1 != collect2; +} + +} + +} + +#endif +/* + 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:textwidth=99 : diff --git a/src/gc-anchored.cpp b/src/gc-anchored.cpp new file mode 100644 index 000000000..02dff76d4 --- /dev/null +++ b/src/gc-anchored.cpp @@ -0,0 +1,39 @@ +/* + * Inkscape::GC::Anchored - base class for anchored GC-managed objects + * + * Authors: + * MenTaLguY + * + * Copyright (C) 2004 MenTaLguY + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "gc-anchored.h" + +namespace Inkscape { + +namespace GC { + +Anchored::Anchor *Anchored::_new_anchor() const { + return new Anchor(this); +} + +void Anchored::_free_anchor(Anchored::Anchor *anchor) const { + delete anchor; +} + +} + +} + +/* + 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:textwidth=99 : diff --git a/src/gc-anchored.h b/src/gc-anchored.h new file mode 100644 index 000000000..f9d609074 --- /dev/null +++ b/src/gc-anchored.h @@ -0,0 +1,185 @@ +/** \file + * Inkscape::GC::Anchored - base class for anchored GC-managed objects + * + * Authors: + * MenTaLguY + * + * Copyright (C) 2004 MenTaLguY + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifndef SEEN_INKSCAPE_GC_ANCHORED_H +#define SEEN_INKSCAPE_GC_ANCHORED_H + +#include +#include "gc-managed.h" + +namespace Inkscape { + +namespace GC { + +/** + * A base class for anchored objects. + * + * Objects are managed by our mark-and-sweep collector, but are anchored + * against garbage collection so long as their reference count is nonzero. + * + * Object and member destructors will not be called on destruction + * unless a subclass also inherits from Inkscape::GC::Finalized. + * + * New instances of anchored objects should be created using the C++ new + * operator. Under normal circumstances they should not be created on + * the stack. + * + * A newly created anchored object begins with a refcount of one, and + * will not be collected unless the refcount is zero. + * + * NOTE: If you create an object yourself, it is already anchored for + * you. You do not need to anchor it a second time. + * + * Note that a cycle involving an anchored object (with nonzero refcount) + * cannot be collected. To avoid this, don't increment refcounts for + * pointers between two garbage-collected objects. + * + * @see Inkscape::GC::Managed + * @see Inkscape::GC::Finalized + * @see Inkscape::GC::anchor + * @see Inkscape::GC::release + */ + +class Anchored { +public: + void anchor() const { + if (!_anchor) { + _anchor = _new_anchor(); + } + _anchor->refcount++; + } + + void release() const { + if (!--_anchor->refcount) { + _free_anchor(_anchor); + _anchor = NULL; + } + } + +protected: + Anchored() : _anchor(NULL) { anchor(); } // initial refcount of one + +private: + struct Anchor : public Managed { + Anchor() : refcount(0) {} + Anchor(Anchored const *obj) : refcount(0) { + base = Core::base(const_cast(obj)); + } + int refcount; + void *base; + }; + + mutable Anchor *_anchor; + + Anchor *_new_anchor() const; + void _free_anchor(Anchor *anchor) const; + + Anchored(Anchored const &); // no copy + void operator=(Anchored const &); // no assign +}; + +/** + * @brief Increments the reference count of a anchored object. + * + * This function template generates functions which take + * a reference to a anchored object of a given type, increment + * that object's reference count, and return a reference to the + * object of the same type as the function's parameter. + * + * @param m a reference to a anchored object + * + * @return the reference to the object + */ +template +static R &anchor(R &r) { + static_cast(const_cast(r)).anchor(); + return r; +} + +/** + * @brief Increments the reference count of a anchored object. + * + * This function template generates functions which take + * a pointer to a anchored object of a given type, increment + * that object's reference count, and return a pointer to the + * object of the same type as the function's parameter. + * + * @param m a pointer to anchored object + * + * @return the pointer to the object + */ +template +static R *anchor(R *r) { + static_cast(const_cast(r))->anchor(); + return r; +} + +/** + * @brief Decrements the reference count of a anchored object. + * + * This function template generates functions which take + * a reference to a anchored object of a given type, increment + * that object's reference count, and return a reference to the + * object of the same type as the function's parameter. + * + * The return value is safe to use since the object, even if + * its refcount has reached zero, will not actually be collected + * until there are no references to it in local variables or + * parameters. + * + * @param m a reference to a anchored object + * + * @return the reference to the object + */ +template +static R &release(R &r) { + static_cast(const_cast(r)).release(); + return r; +} + +/** + * @brief Decrements the reference count of a anchored object. + * + * This function template generates functions which take + * a pointer to a anchored object of a given type, increment + * that object's reference count, and return a pointer to the + * object of the same type as the function's parameter. + * + * The return value is safe to use since the object, even if + * its refcount has reached zero, will not actually be collected + * until there are no references to it in local variables or + * parameters. + * + * @param m a pointer to a anchored object + * + * @return the pointer to the object + */ +template +static R *release(R *r) { + static_cast(const_cast(r))->release(); + return r; +} + +} + +} + +#endif +/* + 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:textwidth=99 : diff --git a/src/gc-core.h b/src/gc-core.h new file mode 100644 index 000000000..cec617d42 --- /dev/null +++ b/src/gc-core.h @@ -0,0 +1,212 @@ +/* + * Inkscape::GC - Wrapper for Boehm GC + * + * Authors: + * MenTaLguY + * + * Copyright (C) 2004 MenTaLguY + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifndef SEEN_INKSCAPE_GC_CORE_H +#define SEEN_INKSCAPE_GC_CORE_H + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include +#ifdef HAVE_GC_GC_H +# include +#else +# include +#endif +#include + +namespace Inkscape { +namespace GC { + +enum ScanPolicy { + SCANNED, + ATOMIC +}; + +enum CollectionPolicy { + AUTO, + MANUAL +}; + +enum Delete { + GC +}; + +typedef void (*CleanupFunc)(void *mem, void *data); + +struct Ops { + void (*do_init)(); + void *(*malloc)(std::size_t size); + void *(*malloc_atomic)(std::size_t size); + void *(*malloc_uncollectable)(std::size_t size); + void *(*malloc_atomic_uncollectable)(std::size_t size); + void *(*base)(void *ptr); + void (*register_finalizer_ignore_self)(void *base, + CleanupFunc func, void *data, + CleanupFunc *old_func, + void **old_data); + int (*general_register_disappearing_link)(void **p_ptr, + void *base); + int (*unregister_disappearing_link)(void **p_ptr); + std::size_t (*get_heap_size)(); + std::size_t (*get_free_bytes)(); + void (*gcollect)(); + void (*enable)(); + void (*disable)(); + void (*free)(void *ptr); +}; + +struct Core { +public: + static void init(); + static inline void *malloc(std::size_t size) { + return _ops.malloc(size); + } + static inline void *malloc_atomic(std::size_t size) { + return _ops.malloc_atomic(size); + } + static inline void *malloc_uncollectable(std::size_t size) { + return _ops.malloc_uncollectable(size); + } + static inline void *malloc_atomic_uncollectable(std::size_t size) { + return _ops.malloc_atomic_uncollectable(size); + } + static inline void *base(void *ptr) { + return _ops.base(ptr); + } + static inline void register_finalizer_ignore_self(void *base, + CleanupFunc func, + void *data, + CleanupFunc *old_func, + void **old_data) + { + return _ops.register_finalizer_ignore_self(base, func, data, + old_func, old_data); + } + static inline int general_register_disappearing_link(void **p_ptr, + void *base) + { + return _ops.general_register_disappearing_link(p_ptr, base); + } + static inline int unregister_disappearing_link(void **p_ptr) { + return _ops.unregister_disappearing_link(p_ptr); + } + static inline std::size_t get_heap_size() { + return _ops.get_heap_size(); + } + static inline std::size_t get_free_bytes() { + return _ops.get_free_bytes(); + } + static inline void gcollect() { + _ops.gcollect(); + } + static inline void enable() { + _ops.enable(); + } + static inline void disable() { + _ops.disable(); + } + static inline void free(void *ptr) { + return _ops.free(ptr); + } +private: + static Ops _ops; +}; + +inline void init() { + Core::init(); +} + +} +} + +inline void *operator new(std::size_t size, + Inkscape::GC::ScanPolicy scan, + Inkscape::GC::CollectionPolicy collect, + Inkscape::GC::CleanupFunc cleanup=NULL, + void *data=NULL) +throw(std::bad_alloc) +{ + using namespace Inkscape::GC; + + void *mem; + if ( collect == AUTO ) { + if ( scan == SCANNED ) { + mem = Core::malloc(size); + } else { + mem = Core::malloc_atomic(size); + } + } else { + if ( scan == SCANNED ) { + mem = Core::malloc_uncollectable(size); + } else { + mem = Core::malloc_atomic_uncollectable(size); + } + } + if (!mem) { + throw std::bad_alloc(); + } + if (cleanup) { + Core::register_finalizer_ignore_self(mem, cleanup, data, NULL, NULL); + } + return mem; +} + +inline void *operator new(std::size_t size, + Inkscape::GC::ScanPolicy scan, + Inkscape::GC::CleanupFunc cleanup=NULL, + void *data=NULL) +throw(std::bad_alloc) +{ + return operator new(size, scan, Inkscape::GC::AUTO, cleanup, data); +} + +inline void *operator new[](std::size_t size, + Inkscape::GC::ScanPolicy scan, + Inkscape::GC::CollectionPolicy collect, + Inkscape::GC::CleanupFunc cleanup=NULL, + void *data=NULL) +throw(std::bad_alloc) +{ + return operator new(size, scan, collect, cleanup, data); +} + +inline void *operator new[](std::size_t size, + Inkscape::GC::ScanPolicy scan, + Inkscape::GC::CleanupFunc cleanup=NULL, + void *data=NULL) +throw(std::bad_alloc) +{ + return operator new[](size, scan, Inkscape::GC::AUTO, cleanup, data); +} + +inline void operator delete(void *mem, Inkscape::GC::Delete) { + Inkscape::GC::Core::free(mem); +} + +inline void operator delete[](void *mem, Inkscape::GC::Delete) { + operator delete(mem, Inkscape::GC::GC); +} + +#endif +/* + 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:textwidth=99 : diff --git a/src/gc-finalized.h b/src/gc-finalized.h new file mode 100644 index 000000000..a31155653 --- /dev/null +++ b/src/gc-finalized.h @@ -0,0 +1,155 @@ +/* + * Inkscape::GC::Finalized - mixin for GC-managed objects with non-trivial + * destructors + * + * Copyright 2004 MenTaLguY + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * See the file COPYING for details. + * + */ + +#ifndef SEEN_INKSCAPE_GC_FINALIZED_H +#define SEEN_INKSCAPE_GC_FINALIZED_H + +#include +#include "gc-core.h" + +namespace Inkscape { + +namespace GC { + +/* @brief a mix-in ensuring that a object's destructor will get called before + * the garbage collector destroys it + * + * Normally, the garbage collector does not call destructors before destroying + * an object. On construction, this "mix-in" will register a finalizer + * function to call destructors before derived objects are destroyed. + * + * This works pretty well, with the following caveats: + * + * 1. The garbage collector uses strictly topologically-ordered + * finalization; if objects with finalizers reference each other + * directly or indirectly, the collector will refuse to finalize (and + * therefor free) them. You'll see a warning on the console if this + * happens. + * + * The best way to limit this effect is to only make "leaf" objects + * (i.e. those that don't point to other finalizaable objects) + * finalizable, or if the object also derives from GC::Managed<>, + * use GC::Managed<>::clearOnceInaccessible to register those links + * to be cleared once the object is made inacecssible (and before it's + * finalized). + * + * In a tree structure that has parent links and finalized nodes, + * you will almost always want to do this with the parent links + * if you can't avoid having them. + * + * @see Inkscape::GC::Managed<>::clearOnceInaccessible + * @see Inkscape::GC::Managed<>::cancelClearOnceInacessible + * + * 2. Because there is no guarantee when the collector will destroy + * objects, there is no guarantee when the destructor will get called. + * + * It may not get called until the very end of the program, or never. + * + * 3. If allocated in arrays, only the first object in the array will + * have its destructor called, unless you make other arrangements by + * registering your own finalizer instead. + * + * 4. Similarly, making multiple GC::Finalized-derived objects members + * of a non-finalized but garbage-collected object generally won't + * work unless you take care of registering finalizers yourself. + * + * [n.b., by "member", I mean an actual by-value-member of a type that + * derives from GC::Finalized, not simply a member that's a pointer or a + * reference to such a type] + * + */ +class Finalized { +public: + Finalized() { + void *base=Core::base(this); + if (base) { // only if we are managed by the collector + CleanupFunc old_cleanup; + void *old_data; + + // the finalization callback needs to know the value of 'this' + // to call the destructor, but registering a real pointer to + // ourselves would pin us forever and prevent us from being + // finalized; instead we use an offset-from-base-address + + Core::register_finalizer_ignore_self(base, _invoke_dtor, + _offset(base, this), + &old_cleanup, &old_data); + + if (old_cleanup) { + // If there was already a finalizer registered for our + // base address, there are two main possibilities: + // + // 1. one of our members is also a GC::Finalized and had + // already registered a finalizer -- keep ours, since + // it will call that member's destructor, too + // + // 2. someone else registered a finalizer and we will have + // to trust that they will call the destructor -- put + // the existing finalizer back + // + // It's also possible that a member's constructor was called + // after ours (e.g. via placement new). Don't do that. + + if ( old_cleanup != _invoke_dtor ) { + Core::register_finalizer_ignore_self(base, + old_cleanup, old_data, + NULL, NULL); + } + } + } + } + + virtual ~Finalized() { + // make sure the destructor won't get invoked twice + Core::register_finalizer_ignore_self(Core::base(this), + NULL, NULL, NULL, NULL); + } + +private: + /// invoke the destructor for an object given a base and offset pair + static void _invoke_dtor(void *base, void *offset) { + _unoffset(base, offset)->~Finalized(); + } + + /// turn 'this' pointer into an offset-from-base-address (stored as void *) + static void *_offset(void *base, Finalized *self) { + return reinterpret_cast( + reinterpret_cast(self) - reinterpret_cast(base) + ); + } + /// reconstitute 'this' given an offset-from-base-address in a void * + static Finalized *_unoffset(void *base, void *offset) { + return reinterpret_cast( + reinterpret_cast(base) + + reinterpret_cast(offset) + ); + } +}; + +} + +} + +#endif +/* + 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:textwidth=99 : diff --git a/src/gc-managed.h b/src/gc-managed.h new file mode 100644 index 000000000..fc13b2513 --- /dev/null +++ b/src/gc-managed.h @@ -0,0 +1,84 @@ +/** \file + * Inkscape::GC::Managed - base class for GC-managed objects + * + * Copyright 2004 MenTaLguY + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * See the file COPYING for details. + * + */ + +#ifndef SEEN_INKSCAPE_GC_MANAGED_H +#define SEEN_INKSCAPE_GC_MANAGED_H + +#include "gc-core.h" + +namespace Inkscape { + +namespace GC { + +/** @brief A base class for objects for whom the normal new and delete + * operators should use the garbage-collected allocator + */ +template +class Managed { +public: + /** @brief Registers a pointer to be cleared when this object becomes + * inaccessible. + */ + template + void clearOnceInaccessible(T **p_ptr) { + Core::general_register_disappearing_link( + reinterpret_cast(p_ptr), Core::base(this) + ); + } + + /** @brief Cancels the registration of a pointer, so it will not be + * cleared when this object becomes inacessible. + */ + template + void cancelClearOnceInaccessible(T **p_ptr) { + Core::unregister_disappearing_link( + reinterpret_cast(p_ptr) + ); + } + + void *operator new(std::size_t size, + ScanPolicy scan=default_scan, + CollectionPolicy collect=default_collect) + throw (std::bad_alloc) + { + return ::operator new(size, scan, collect); + } + + void *operator new[](std::size_t size, + ScanPolicy scan=default_scan, + CollectionPolicy collect=default_collect) + throw (std::bad_alloc) + { + return ::operator new[](size, scan, collect); + } + + void operator delete(void *p) { return ::operator delete(p, GC); } +}; + +} + +} + +#endif +/* + 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:textwidth=99 : diff --git a/src/gc.cpp b/src/gc.cpp new file mode 100644 index 000000000..7333b4641 --- /dev/null +++ b/src/gc.cpp @@ -0,0 +1,279 @@ +/* + * Inkscape::GC - Wrapper for Boehm GC + * + * Authors: + * MenTaLguY + * + * Copyright (C) 2004 MenTaLguY + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "gc-core.h" +#include +#include + +namespace Inkscape { +namespace GC { + +namespace { + +void display_warning(char *msg, GC_word arg) { + g_warning(msg, arg); +} + +void do_init() { + GC_no_dls = 1; + GC_all_interior_pointers = 1; + GC_finalize_on_demand = 0; + + GC_INIT(); + + GC_set_warn_proc(&display_warning); +} + +void *debug_malloc(std::size_t size) { + return GC_debug_malloc(size, GC_EXTRAS); +} + +void *debug_malloc_atomic(std::size_t size) { + return GC_debug_malloc_atomic(size, GC_EXTRAS); +} + +void *debug_malloc_uncollectable(std::size_t size) { + return GC_debug_malloc_uncollectable(size, GC_EXTRAS); +} + +void *debug_malloc_atomic_uncollectable(std::size_t size) { + return GC_debug_malloc_uncollectable(size, GC_EXTRAS); +} + +std::ptrdiff_t compute_debug_base_fixup() { + char *base=reinterpret_cast(GC_debug_malloc(1, GC_EXTRAS)); + char *real_base=reinterpret_cast(GC_base(base)); + GC_debug_free(base); + return base - real_base; +} + +inline std::ptrdiff_t const &debug_base_fixup() { + static std::ptrdiff_t fixup=compute_debug_base_fixup(); + return fixup; +} + +void *debug_base(void *ptr) { + char *base=reinterpret_cast(GC_base(ptr)); + return base + debug_base_fixup(); +} + +int debug_general_register_disappearing_link(void **p_ptr, void *base) { + char *real_base=reinterpret_cast(base) - debug_base_fixup(); + return GC_general_register_disappearing_link(p_ptr, real_base); +} + +void dummy_do_init() {} + +void *dummy_base(void *) { return NULL; } + +void dummy_register_finalizer(void *, CleanupFunc, void *, + CleanupFunc *old_func, void **old_data) +{ + if (old_func) { + *old_func = NULL; + } + if (old_data) { + *old_data = NULL; + } +} + +int dummy_general_register_disappearing_link(void **, void *) { return false; } + +int dummy_unregister_disappearing_link(void **link) { return false; } + +std::size_t dummy_get_heap_size() { return 0; } + +std::size_t dummy_get_free_bytes() { return 0; } + +void dummy_gcollect() {} + +void dummy_enable() {} + +void dummy_disable() {} + +Ops enabled_ops = { + &do_init, + &GC_malloc, + &GC_malloc_atomic, + &GC_malloc_uncollectable, + &GC_malloc_atomic_uncollectable, + &GC_base, + &GC_register_finalizer_ignore_self, + &GC_general_register_disappearing_link, + &GC_unregister_disappearing_link, + &GC_get_heap_size, + &GC_get_free_bytes, + &GC_gcollect, + &GC_enable, + &GC_disable, + &GC_free +}; + +Ops debug_ops = { + &do_init, + &debug_malloc, + &debug_malloc_atomic, + &debug_malloc_uncollectable, + &debug_malloc_atomic_uncollectable, + &debug_base, + &GC_debug_register_finalizer_ignore_self, + &debug_general_register_disappearing_link, + &GC_unregister_disappearing_link, + &GC_get_heap_size, + &GC_get_free_bytes, + &GC_gcollect, + &GC_enable, + &GC_disable, + &GC_debug_free +}; + +Ops disabled_ops = { + &dummy_do_init, + &std::malloc, + &std::malloc, + &std::malloc, + &std::malloc, + &dummy_base, + &dummy_register_finalizer, + &dummy_general_register_disappearing_link, + &dummy_unregister_disappearing_link, + &dummy_get_heap_size, + &dummy_get_free_bytes, + &dummy_gcollect, + &dummy_enable, + &dummy_disable, + &std::free +}; + +class InvalidGCModeError : public std::runtime_error { +public: + InvalidGCModeError(const char *mode) + : runtime_error(std::string("Unknown GC mode \"") + mode + "\"") + {} +}; + +Ops const &get_ops() throw (InvalidGCModeError) { + char *mode_string=std::getenv("_INKSCAPE_GC"); + if (mode_string) { + if (!std::strcmp(mode_string, "enable")) { + return enabled_ops; + } else if (!std::strcmp(mode_string, "debug")) { + return debug_ops; + } else if (!std::strcmp(mode_string, "disable")) { + return disabled_ops; + } else { + throw InvalidGCModeError(mode_string); + } + } else { + return enabled_ops; + } +} + +void die_because_not_initialized() { + g_error("Attempt to use GC allocator before call to Inkscape::GC::init()"); +} + +void *stub_malloc(std::size_t) { + die_because_not_initialized(); + return NULL; +} + +void *stub_base(void *) { + die_because_not_initialized(); + return NULL; +} + +void stub_register_finalizer_ignore_self(void *, CleanupFunc, void *, + CleanupFunc *, void **) +{ + die_because_not_initialized(); +} + +int stub_general_register_disappearing_link(void **, void *) { + die_because_not_initialized(); + return 0; +} + +int stub_unregister_disappearing_link(void **) { + die_because_not_initialized(); + return 0; +} + +std::size_t stub_get_heap_size() { + die_because_not_initialized(); + return 0; +} + +std::size_t stub_get_free_bytes() { + die_because_not_initialized(); + return 0; +} + +void stub_gcollect() { + die_because_not_initialized(); +} + +void stub_enable() { + die_because_not_initialized(); +} + +void stub_disable() { + die_because_not_initialized(); +} + +void stub_free(void *) { + die_because_not_initialized(); +} + +} + +Ops Core::_ops = { + NULL, + &stub_malloc, + &stub_malloc, + &stub_malloc, + &stub_malloc, + &stub_base, + &stub_register_finalizer_ignore_self, + &stub_general_register_disappearing_link, + &stub_unregister_disappearing_link, + &stub_get_heap_size, + &stub_get_free_bytes, + &stub_gcollect, + &stub_enable, + &stub_disable, + &stub_free +}; + +void Core::init() { + try { + _ops = get_ops(); + } catch (InvalidGCModeError &e) { + g_warning("%s; enabling normal collection", e.what()); + _ops = enabled_ops; + } + + _ops.do_init(); +} + +} +} + +/* + 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:textwidth=99 : diff --git a/src/geom.cpp b/src/geom.cpp new file mode 100644 index 000000000..2749d6d7d --- /dev/null +++ b/src/geom.cpp @@ -0,0 +1,172 @@ +/** + * \file src/geom.cpp + * \brief Various geometrical calculations. + */ + +#ifdef HAVE_CONFIG_H +# include +#endif +#include "geom.h" +#include + +/** + * Finds the intersection of the two (infinite) lines + * defined by the points p such that dot(n0, p) == d0 and dot(n1, p) == d1. + * + * If the two lines intersect, then \a result becomes their point of + * intersection; otherwise, \a result remains unchanged. + * + * This function finds the intersection of the two lines (infinite) + * defined by n0.X = d0 and x1.X = d1. The algorithm is as follows: + * To compute the intersection point use kramer's rule: + * \verbatim + * convert lines to form + * ax + by = c + * dx + ey = f + * + * ( + * e.g. a = (x2 - x1), b = (y2 - y1), c = (x2 - x1)*x1 + (y2 - y1)*y1 + * ) + * + * In our case we use: + * a = n0.x d = n1.x + * b = n0.y e = n1.y + * c = d0 f = d1 + * + * so: + * + * adx + bdy = cd + * adx + aey = af + * + * bdy - aey = cd - af + * (bd - ae)y = cd - af + * + * y = (cd - af)/(bd - ae) + * + * repeat for x and you get: + * + * x = (fb - ce)/(bd - ae) \endverbatim + * + * If the denominator (bd-ae) is 0 then the lines are parallel, if the + * numerators are then 0 then the lines coincide. + * + * \todo Why not use existing but outcommented code below + * (HAVE_NEW_INTERSECTOR_CODE)? + */ +IntersectorKind intersector_line_intersection(NR::Point const &n0, double const d0, + NR::Point const &n1, double const d1, + NR::Point &result) +{ + double denominator = dot(NR::rot90(n0), n1); + double X = n1[NR::Y] * d0 - + n0[NR::Y] * d1; + /* X = (-d1, d0) dot (n0[Y], n1[Y]) */ + + if (denominator == 0) { + if ( X == 0 ) { + return COINCIDENT; + } else { + return PARALLEL; + } + } + + double Y = n0[NR::X] * d1 - + n1[NR::X] * d0; + + result = NR::Point(X, Y) / denominator; + + return INTERSECTS; +} + + + + +/* + New code which we are not yet using +*/ +#ifdef HAVE_NEW_INTERSECTOR_CODE + + +/* ccw exists as a building block */ +static int +sp_intersector_ccw(const NR::Point p0, const NR::Point p1, const NR::Point p2) +/* Determine which way a set of three points winds. */ +{ + NR::Point d1 = p1 - p0; + NR::Point d2 = p2 - p0; +/* compare slopes but avoid division operation */ + double c = dot(NR::rot90(d1), d2); + if(c > 0) + return +1; // ccw - do these match def'n in header? + if(c < 0) + return -1; // cw + + /* Colinear [or NaN]. Decide the order. */ + if ( ( d1[0] * d2[0] < 0 ) || + ( d1[1] * d2[1] < 0 ) ) { + return -1; // p2 < p0 < p1 + } else if ( dot(d1,d1) < dot(d2,d2) ) { + return +1; // p0 <= p1 < p2 + } else { + return 0; // p0 <= p2 <= p1 + } +} + +/** Determine whether two line segments intersect. This doesn't find + the point of intersection, use the line_intersect function above, + or the segment_intersection interface below. + + \pre neither segment is zero-length; i.e. p00 != p01 and p10 != p11. + */ +static bool +sp_intersector_segment_intersectp(NR::Point const &p00, NR::Point const &p01, + NR::Point const &p10, NR::Point const &p11) +{ + g_return_val_if_fail(p00 != p01, false); + g_return_val_if_fail(p10 != p11, false); + + /* true iff ( (the p1 segment straddles the p0 infinite line) + * and (the p0 segment straddles the p1 infinite line) ). */ + return ((sp_intersector_ccw(p00,p01, p10) + *sp_intersector_ccw(p00, p01, p11)) <=0 ) + && + ((sp_intersector_ccw(p10,p11, p00) + *sp_intersector_ccw(p10, p11, p01)) <=0 ); +} + + +/** Determine whether \& where two line segments intersect. + + If the two segments don't intersect, then \a result remains unchanged. + + \pre neither segment is zero-length; i.e. p00 != p01 and p10 != p11. +**/ +static sp_intersector_kind +sp_intersector_segment_intersect(NR::Point const &p00, NR::Point const &p01, + NR::Point const &p10, NR::Point const &p11, + NR::Point &result) +{ + if(sp_intersector_segment_intersectp(p00, p01, p10, p11)) { + NR::Point n0 = (p00 - p01).ccw(); + double d0 = dot(n0,p00); + + NR::Point n1 = (p10 - p11).ccw(); + double d1 = dot(n1,p10); + return sp_intersector_line_intersection(n0, d0, n1, d1, result); + } else { + return no_intersection; + } +} + +#endif /* end yet-unused HAVE_NEW_INTERSECTOR_CODE code */ + +/* + 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:textwidth=99 : diff --git a/src/geom.h b/src/geom.h new file mode 100644 index 000000000..d00a4e37c --- /dev/null +++ b/src/geom.h @@ -0,0 +1,30 @@ +/** + * \file geom.h + * \brief Various geometrical calculations + * + * Authors: + * Nathan Hurst + * + * Copyright (C) 1999-2002 authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "libnr/nr-forward.h" + +enum IntersectorKind { + INTERSECTS = 0, + PARALLEL, + COINCIDENT, + NO_INTERSECTION +}; + +/* Define here various primatives, such as line, line segment, circle, bezier path etc. */ + + + +/* intersectors */ + +IntersectorKind intersector_line_intersection(NR::Point const &n0, double const d0, + NR::Point const &n1, double const d1, + NR::Point &result); diff --git a/src/gnuc-attribute.h b/src/gnuc-attribute.h new file mode 100644 index 000000000..4b3e57632 --- /dev/null +++ b/src/gnuc-attribute.h @@ -0,0 +1,11 @@ +/** + * Define _gnuc_attribute(blah) as synonym for __attribute__(blah) on gcc, + * or as nothing on other compilers. + */ +#ifndef _gnuc_attribute +# ifdef __GNUC__ +# define _gnuc_attribute(_attr) __attribute__(_attr) +# else +# define _gnuc_attribute(_attr) +# endif +#endif diff --git a/src/gradient-chemistry.cpp b/src/gradient-chemistry.cpp new file mode 100644 index 000000000..aa77ea0ad --- /dev/null +++ b/src/gradient-chemistry.cpp @@ -0,0 +1,1133 @@ +#define __SP_GRADIENT_CHEMISTRY_C__ + +/* + * Various utility methods for gradients + * + * Authors: + * Lauris Kaplinski + * bulia byak + * + * Copyright (C) 2001-2005 authors + * Copyright (C) 2001 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + + +#include "style.h" +#include "document-private.h" +#include "desktop-style.h" + +#include "sp-gradient-reference.h" +#include "sp-linear-gradient.h" +#include "sp-radial-gradient.h" +#include "sp-stop.h" +#include "widgets/gradient-vector.h" + +#include "sp-text.h" +#include "sp-tspan.h" +#include +#include "xml/repr.h" +#include "svg/svg.h" + + +// Terminology: +// +// "vector" is a gradient that has stops but not position coords. It can be referenced by one or +// more privates. Objects should not refer to it directly. It has no radial/linear distinction. +// +// "private" is a gradient that has no stops but has position coords (e.g. center, radius etc for a +// radial). It references a vector for the actual colors. Each private is only used by one +// object. It is either linear or radial. + +static void sp_gradient_repr_set_link(Inkscape::XML::Node *repr, SPGradient *gr); +static void sp_item_repr_set_style_gradient(Inkscape::XML::Node *repr, gchar const *property, + SPGradient *gr, bool recursive); + +SPGradient * +sp_gradient_ensure_vector_normalized(SPGradient *gr) +{ + g_return_val_if_fail(gr != NULL, NULL); + g_return_val_if_fail(SP_IS_GRADIENT(gr), NULL); + + /* If we are already normalized vector, just return */ + if (gr->state == SP_GRADIENT_STATE_VECTOR) return gr; + /* Fail, if we have wrong state set */ + if (gr->state != SP_GRADIENT_STATE_UNKNOWN) { + g_warning("file %s: line %d: Cannot normalize private gradient to vector (%s)", __FILE__, __LINE__, SP_OBJECT_ID(gr)); + return NULL; + } + + /* First make sure we have vector directly defined (i.e. gr has its own stops) */ + if (!gr->has_stops) { + /* We do not have stops ourselves, so flatten stops as well */ + sp_gradient_ensure_vector(gr); + g_assert(gr->vector.built); + // this adds stops from gr->vector as children to gr + sp_gradient_repr_write_vector (gr); + } + + /* If gr hrefs some other gradient, remove the href */ + if (gr->ref->getObject()) { + /* We are hrefing someone, so require flattening */ + SP_OBJECT(gr)->updateRepr(((SPObject *) gr)->repr, SP_OBJECT_WRITE_EXT | SP_OBJECT_WRITE_ALL); + sp_gradient_repr_set_link(SP_OBJECT_REPR(gr), NULL); + } + + /* Everything is OK, set state flag */ + gr->state = SP_GRADIENT_STATE_VECTOR; + return gr; +} + +/** + * Creates new private gradient for the given vector + */ + +static SPGradient * +sp_gradient_get_private_normalized(SPDocument *document, SPGradient *vector, SPGradientType type) +{ + g_return_val_if_fail(document != NULL, NULL); + g_return_val_if_fail(vector != NULL, NULL); + g_return_val_if_fail(SP_IS_GRADIENT(vector), NULL); + g_return_val_if_fail(SP_GRADIENT_HAS_STOPS(vector), NULL); + + SPDefs *defs = (SPDefs *) SP_DOCUMENT_DEFS(document); + + // create a new private gradient of the requested type + Inkscape::XML::Node *repr; + if (type == SP_GRADIENT_TYPE_LINEAR) { + repr = sp_repr_new("svg:linearGradient"); + } else { + repr = sp_repr_new("svg:radialGradient"); + } + + // privates are garbage-collectable + repr->setAttribute("inkscape:collect", "always"); + + // link to vector + sp_gradient_repr_set_link(repr, vector); + + /* Append the new private gradient to defs */ + SP_OBJECT_REPR(defs)->appendChild(repr); + Inkscape::GC::release(repr); + + // get corresponding object + SPGradient *gr = (SPGradient *) document->getObjectByRepr(repr); + g_assert(gr != NULL); + g_assert(SP_IS_GRADIENT(gr)); + + return gr; +} + +/** +Count how many times gr is used by the styles of o and its descendants +*/ +guint +count_gradient_hrefs(SPObject *o, SPGradient *gr) +{ + if (!o) + return 1; + + guint i = 0; + + SPStyle *style = SP_OBJECT_STYLE(o); + if (style + && style->fill.type == SP_PAINT_TYPE_PAINTSERVER + && SP_IS_GRADIENT(SP_STYLE_FILL_SERVER(style)) + && SP_GRADIENT(SP_STYLE_FILL_SERVER(style)) == gr) + { + i ++; + } + if (style + && style->stroke.type == SP_PAINT_TYPE_PAINTSERVER + && SP_IS_GRADIENT(SP_STYLE_STROKE_SERVER(style)) + && SP_GRADIENT(SP_STYLE_STROKE_SERVER(style)) == gr) + { + i ++; + } + + for (SPObject *child = sp_object_first_child(o); + child != NULL; child = SP_OBJECT_NEXT(child)) { + i += count_gradient_hrefs(child, gr); + } + + return i; +} + + +/** + * If gr has other users, create a new private; also check if gr links to vector, relink if not + */ +SPGradient * +sp_gradient_fork_private_if_necessary(SPGradient *gr, SPGradient *vector, + SPGradientType type, SPObject *o) +{ + g_return_val_if_fail(gr != NULL, NULL); + g_return_val_if_fail(SP_IS_GRADIENT(gr), NULL); + + // Orphaned gradient, no vector with stops at the end of the line; this used to be an assert + // but i think we should not abort on this - maybe just write a validity warning into some sort + // of log + if (!vector || !SP_GRADIENT_HAS_STOPS(vector)) + return (gr); + + // user is the object that uses this gradient; normally it's item but for tspans, we + // check its ancestor text so that tspans don't get different gradients from their + // texts. + SPObject *user = o; + while (SP_IS_TSPAN(user)) { + user = SP_OBJECT_PARENT(user); + } + + // Check the number of uses of the gradient within this object; + // if we are private and there are no other users, + if (SP_OBJECT_HREFCOUNT(gr) <= count_gradient_hrefs(user, gr)) { + // check vector + if ( gr != vector && gr->ref->getObject() != vector ) { + /* our href is not the vector, and vector is different from gr; relink */ + sp_gradient_repr_set_link(SP_OBJECT_REPR(gr), vector); + } + return gr; + } + + SPDocument *doc = SP_OBJECT_DOCUMENT(gr); + SPObject *defs = SP_DOCUMENT_DEFS(doc); + + if ((gr->has_stops) || + (gr->state != SP_GRADIENT_STATE_UNKNOWN) || + (SP_OBJECT_PARENT(gr) != SP_OBJECT(defs)) || + (SP_OBJECT_HREFCOUNT(gr) > 1)) { + // we have to clone a fresh new private gradient for the given vector + + // create an empty one + SPGradient *gr_new = sp_gradient_get_private_normalized(doc, vector, type); + + // copy all the attributes to it + Inkscape::XML::Node *repr_new = SP_OBJECT_REPR(gr_new); + Inkscape::XML::Node *repr = SP_OBJECT_REPR(gr); + repr_new->setAttribute("gradientUnits", repr->attribute("gradientUnits")); + repr_new->setAttribute("gradientTransform", repr->attribute("gradientTransform")); + repr_new->setAttribute("spreadMethod", repr->attribute("spreadMethod")); + if (SP_IS_RADIALGRADIENT(gr)) { + repr_new->setAttribute("cx", repr->attribute("cx")); + repr_new->setAttribute("cy", repr->attribute("cy")); + repr_new->setAttribute("fx", repr->attribute("fx")); + repr_new->setAttribute("fy", repr->attribute("fy")); + repr_new->setAttribute("r", repr->attribute("r")); + } else { + repr_new->setAttribute("x1", repr->attribute("x1")); + repr_new->setAttribute("y1", repr->attribute("y1")); + repr_new->setAttribute("x2", repr->attribute("x2")); + repr_new->setAttribute("y2", repr->attribute("y2")); + } + + return gr_new; + } else { + return gr; + } +} + +SPGradient * +sp_gradient_fork_vector_if_necessary (SPGradient *gr) +{ + if (SP_OBJECT_HREFCOUNT(gr) > 1) { + SPDocument *document = SP_OBJECT_DOCUMENT(gr); + + Inkscape::XML::Node *repr = SP_OBJECT_REPR (gr)->duplicate(); + SP_OBJECT_REPR (SP_DOCUMENT_DEFS (document))->addChild(repr, NULL); + SPGradient *gr_new = (SPGradient *) document->getObjectByRepr(repr); + gr_new = sp_gradient_ensure_vector_normalized (gr_new); + Inkscape::GC::release(repr); + return gr_new; + } + return gr; +} + +/** + * Convert an item's gradient to userspace _without_ preserving coords, setting them to defaults + * instead. No forking or reapplying is done because this is only called for newly created privates. + * @return The new gradient. + */ +SPGradient * +sp_gradient_reset_to_userspace (SPGradient *gr, SPItem *item) +{ + Inkscape::XML::Node *repr = SP_OBJECT_REPR(gr); + + // calculate the bbox of the item + sp_document_ensure_up_to_date(SP_OBJECT_DOCUMENT(item)); + NR::Rect const bbox = item->invokeBbox(NR::identity()); // we need "true" bbox without item_i2d_affine + + NR::Coord const width = bbox.dimensions()[NR::X]; + NR::Coord const height = bbox.dimensions()[NR::Y]; + g_assert(width > 0 && height > 0); + + NR::Point const center = bbox.midpoint(); + + if (SP_IS_RADIALGRADIENT(gr)) { + sp_repr_set_svg_double(repr, "cx", center[NR::X]); + sp_repr_set_svg_double(repr, "cy", center[NR::Y]); + sp_repr_set_svg_double(repr, "fx", center[NR::X]); + sp_repr_set_svg_double(repr, "fy", center[NR::Y]); + sp_repr_set_svg_double(repr, "r", width/2); + + // we want it to be elliptic, not circular + NR::Matrix squeeze = NR::Matrix (NR::translate (-center)) * + NR::Matrix (NR::scale(1, height/width)) * + NR::Matrix (NR::translate (center)); + + gr->gradientTransform = squeeze; + { + gchar c[256]; + if (sp_svg_transform_write(c, 256, gr->gradientTransform)) { + SP_OBJECT_REPR(gr)->setAttribute("gradientTransform", c); + } else { + SP_OBJECT_REPR(gr)->setAttribute("gradientTransform", NULL); + } + } + } else { + sp_repr_set_svg_double(repr, "x1", (center - NR::Point(width/2, 0))[NR::X]); + sp_repr_set_svg_double(repr, "y1", (center - NR::Point(width/2, 0))[NR::Y]); + sp_repr_set_svg_double(repr, "x2", (center + NR::Point(width/2, 0))[NR::X]); + sp_repr_set_svg_double(repr, "y2", (center + NR::Point(width/2, 0))[NR::Y]); + } + + // set the gradientUnits + repr->setAttribute("gradientUnits", "userSpaceOnUse"); + + return gr; +} + +/** + * Convert an item's gradient to userspace if necessary, also fork it if necessary. + * @return The new gradient. + */ +SPGradient * +sp_gradient_convert_to_userspace(SPGradient *gr, SPItem *item, gchar const *property) +{ + g_return_val_if_fail(SP_IS_GRADIENT(gr), NULL); + + // First, fork it if it is shared + gr = sp_gradient_fork_private_if_necessary(gr, sp_gradient_get_vector(gr, FALSE), + SP_IS_RADIALGRADIENT(gr) ? SP_GRADIENT_TYPE_RADIAL : SP_GRADIENT_TYPE_LINEAR, SP_OBJECT(item)); + + if (gr->units == SP_GRADIENT_UNITS_OBJECTBOUNDINGBOX) { + + Inkscape::XML::Node *repr = SP_OBJECT_REPR(gr); + + // calculate the bbox of the item + sp_document_ensure_up_to_date(SP_OBJECT_DOCUMENT(item)); + NR::Rect const bbox = item->invokeBbox(NR::identity()); // we need "true" bbox without item_i2d_affine + NR::Matrix bbox2user(bbox.dimensions()[NR::X], 0, + 0, bbox.dimensions()[NR::Y], + bbox.min()[NR::X], bbox.min()[NR::Y]); + + /* skew is the additional transform, defined by the proportions of the item, that we need + * to apply to the gradient in order to work around this weird bit from SVG 1.1 + * (http://www.w3.org/TR/SVG11/pservers.html#LinearGradients): + * + * When gradientUnits="objectBoundingBox" and gradientTransform is the identity + * matrix, the stripes of the linear gradient are perpendicular to the gradient + * vector in object bounding box space (i.e., the abstract coordinate system where + * (0,0) is at the top/left of the object bounding box and (1,1) is at the + * bottom/right of the object bounding box). When the object's bounding box is not + * square, the stripes that are conceptually perpendicular to the gradient vector + * within object bounding box space will render non-perpendicular relative to the + * gradient vector in user space due to application of the non-uniform scaling + * transformation from bounding box space to user space. + */ + NR::Matrix skew = bbox2user; + double exp = skew.expansion(); + skew[0] /= exp; + skew[1] /= exp; + skew[2] /= exp; + skew[3] /= exp; + skew[4] = 0; + skew[5] = 0; + + // apply skew to the gradient + gr->gradientTransform = skew; + { + gchar c[256]; + if (sp_svg_transform_write(c, 256, gr->gradientTransform)) { + SP_OBJECT_REPR(gr)->setAttribute("gradientTransform", c); + } else { + SP_OBJECT_REPR(gr)->setAttribute("gradientTransform", NULL); + } + } + + // Matrix to convert points to userspace coords; postmultiply by inverse of skew so + // as to cancel it out when it's applied to the gradient during rendering + NR::Matrix point_convert = bbox2user * skew.inverse(); + + if (SP_IS_RADIALGRADIENT(gr)) { + SPRadialGradient *rg = SP_RADIALGRADIENT(gr); + + // original points in the bbox coords + NR::Point c_b = NR::Point(rg->cx.computed, rg->cy.computed); + NR::Point f_b = NR::Point(rg->fx.computed, rg->fy.computed); + double r_b = rg->r.computed; + + // converted points in userspace coords + NR::Point c_u = c_b * point_convert; + NR::Point f_u = f_b * point_convert; + double r_u = r_b * point_convert.expansion(); + + sp_repr_set_svg_double(repr, "cx", c_u[NR::X]); + sp_repr_set_svg_double(repr, "cy", c_u[NR::Y]); + sp_repr_set_svg_double(repr, "fx", f_u[NR::X]); + sp_repr_set_svg_double(repr, "fy", f_u[NR::Y]); + sp_repr_set_svg_double(repr, "r", r_u); + + } else { + SPLinearGradient *lg = SP_LINEARGRADIENT(gr); + + NR::Point p1_b = NR::Point(lg->x1.computed, lg->y1.computed); + NR::Point p2_b = NR::Point(lg->x2.computed, lg->y2.computed); + + NR::Point p1_u = p1_b * point_convert; + NR::Point p2_u = p2_b * point_convert; + + sp_repr_set_svg_double(repr, "x1", p1_u[NR::X]); + sp_repr_set_svg_double(repr, "y1", p1_u[NR::Y]); + sp_repr_set_svg_double(repr, "x2", p2_u[NR::X]); + sp_repr_set_svg_double(repr, "y2", p2_u[NR::Y]); + } + + // set the gradientUnits + repr->setAttribute("gradientUnits", "userSpaceOnUse"); + } + + // apply the gradient to the item (may be necessary if we forked it); not recursive + // generally because grouped items will be taken care of later (we're being called + // from sp_item_adjust_paint_recursive); however text and all its children should all + // refer to one gradient, hence the recursive call for text (because we can't/don't + // want to access tspans and set gradients on them separately) + if (SP_IS_TEXT(item)) + sp_item_repr_set_style_gradient(SP_OBJECT_REPR(item), property, gr, true); + else + sp_item_repr_set_style_gradient(SP_OBJECT_REPR(item), property, gr, false); + + return gr; +} + +void +sp_gradient_transform_multiply(SPGradient *gradient, NR::Matrix postmul, bool set) +{ + if (set) { + gradient->gradientTransform = postmul; + } else { + gradient->gradientTransform *= postmul; // fixme: get gradient transform by climbing to hrefs? + } + gradient->gradientTransform_set = TRUE; + + gchar c[256]; + if (sp_svg_transform_write(c, 256, gradient->gradientTransform)) { + SP_OBJECT_REPR(gradient)->setAttribute("gradientTransform", c); + } else { + SP_OBJECT_REPR(gradient)->setAttribute("gradientTransform", NULL); + } +} + +SPGradient * +sp_item_gradient (SPItem *item, bool fill_or_stroke) +{ + SPStyle *style = SP_OBJECT_STYLE (item); + SPGradient *gradient = NULL; + + if (fill_or_stroke) { + if (style && (style->fill.type == SP_PAINT_TYPE_PAINTSERVER)) { + SPObject *server = SP_OBJECT_STYLE_FILL_SERVER(item); + if (SP_IS_GRADIENT (server)) { + gradient = SP_GRADIENT (server); + } + } + } else { + if (style && (style->stroke.type == SP_PAINT_TYPE_PAINTSERVER)) { + SPObject *server = SP_OBJECT_STYLE_STROKE_SERVER(item); + if (SP_IS_GRADIENT (server)) { + gradient = SP_GRADIENT (server); + } + } + } + + return gradient; +} + + +SPStop* +sp_first_stop(SPGradient *gradient) +{ + for (SPObject *ochild = sp_object_first_child(gradient); ochild != NULL; ochild = SP_OBJECT_NEXT(ochild)) { + if (SP_IS_STOP (ochild)) + return SP_STOP(ochild); + } + return NULL; +} + +SPStop* +sp_prev_stop(SPStop *stop, SPGradient *gradient) +{ + if (sp_object_first_child(SP_OBJECT(gradient)) == SP_OBJECT(stop)) + return NULL; + SPObject *found = NULL; + for ( SPObject *ochild = sp_object_first_child(SP_OBJECT(gradient)) ; ochild != NULL ; ochild = SP_OBJECT_NEXT(ochild) ) { + if (SP_IS_STOP (ochild)) { + found = ochild; + } + if (SP_OBJECT_NEXT(ochild) == SP_OBJECT(stop) || SP_OBJECT(ochild) == SP_OBJECT(stop)) { + break; + } + } + return SP_STOP(found); +} + +SPStop* +sp_next_stop(SPStop *stop) +{ + for (SPObject *ochild = SP_OBJECT_NEXT(stop); ochild != NULL; ochild = SP_OBJECT_NEXT(ochild)) { + if (SP_IS_STOP (ochild)) + return SP_STOP(ochild); + } + return NULL; +} + +SPStop* +sp_last_stop(SPGradient *gradient) +{ + for (SPStop *stop = sp_first_stop (gradient); stop != NULL; stop = sp_next_stop (stop)) { + if (sp_next_stop (stop) == NULL) + return stop; + } + return NULL; +} + + +void +sp_item_gradient_edit_stop (SPItem *item, guint point_num, bool fill_or_stroke) +{ + SPGradient *gradient = sp_item_gradient (item, fill_or_stroke); + + if (!gradient || !SP_IS_GRADIENT(gradient)) + return; + + SPGradient *vector = sp_gradient_get_vector (gradient, false); + switch (point_num) { + case POINT_LG_P1: + case POINT_RG_CENTER: + case POINT_RG_FOCUS: + { + GtkWidget *dialog = sp_gradient_vector_editor_new (vector, sp_first_stop (vector)); + gtk_widget_show (dialog); + } + break; + + case POINT_LG_P2: + case POINT_RG_R1: + case POINT_RG_R2: + { + GtkWidget *dialog = sp_gradient_vector_editor_new (vector, sp_last_stop (vector)); + gtk_widget_show (dialog); + } + break; + default: + break; + } +} + +guint32 +sp_item_gradient_stop_query_style (SPItem *item, guint point_num, bool fill_or_stroke) +{ + SPGradient *gradient = sp_item_gradient (item, fill_or_stroke); + + if (!gradient || !SP_IS_GRADIENT(gradient)) + return 0; + + SPGradient *vector = sp_gradient_get_vector (gradient, false); + + if (!vector) // orphan! + return 0; // what else to do? + + switch (point_num) { + case POINT_LG_P1: + case POINT_RG_CENTER: + case POINT_RG_FOCUS: + { + SPStop *first = sp_first_stop (vector); + if (first) { + return sp_stop_get_rgba32(first); + } + } + break; + + case POINT_LG_P2: + case POINT_RG_R1: + case POINT_RG_R2: + { + SPStop *last = sp_last_stop (vector); + if (last) { + return sp_stop_get_rgba32(last); + } + } + break; + default: + break; + } + return 0; +} + +void +sp_item_gradient_stop_set_style (SPItem *item, guint point_num, bool fill_or_stroke, SPCSSAttr *stop) +{ + SPGradient *gradient = sp_item_gradient (item, fill_or_stroke); + + if (!gradient || !SP_IS_GRADIENT(gradient)) + return; + + SPGradient *vector = sp_gradient_get_vector (gradient, false); + + if (!vector) // orphan! + return; + + vector = sp_gradient_fork_vector_if_necessary (vector); + if ( gradient != vector && gradient->ref->getObject() != vector ) { + sp_gradient_repr_set_link(SP_OBJECT_REPR(gradient), vector); + } + + switch (point_num) { + case POINT_LG_P1: + case POINT_RG_CENTER: + case POINT_RG_FOCUS: + { + SPStop *first = sp_first_stop (vector); + if (first) { + sp_repr_css_change (SP_OBJECT_REPR (first), stop, "style"); + } + } + break; + + case POINT_LG_P2: + case POINT_RG_R1: + case POINT_RG_R2: + { + SPStop *last = sp_last_stop (vector); + if (last) { + sp_repr_css_change (SP_OBJECT_REPR (last), stop, "style"); + } + } + break; + default: + break; + } +} + +void +sp_item_gradient_reverse_vector (SPItem *item, bool fill_or_stroke) +{ + SPGradient *gradient = sp_item_gradient (item, fill_or_stroke); + if (!gradient || !SP_IS_GRADIENT(gradient)) + return; + + SPGradient *vector = sp_gradient_get_vector (gradient, false); + if (!vector) // orphan! + return; + + vector = sp_gradient_fork_vector_if_necessary (vector); + if ( gradient != vector && gradient->ref->getObject() != vector ) { + sp_gradient_repr_set_link(SP_OBJECT_REPR(gradient), vector); + } + + GSList *child_reprs = NULL; + GSList *child_objects = NULL; + std::vector offsets; + for (SPObject *child = sp_object_first_child(vector); + child != NULL; child = SP_OBJECT_NEXT(child)) { + child_reprs = g_slist_prepend (child_reprs, SP_OBJECT_REPR(child)); + child_objects = g_slist_prepend (child_objects, child); + offsets.push_back(sp_repr_get_double_attribute(SP_OBJECT_REPR(child), "offset", 0)); + } + + GSList *child_copies = NULL; + for (GSList *i = child_reprs; i != NULL; i = i->next) { + Inkscape::XML::Node *repr = (Inkscape::XML::Node *) i->data; + child_copies = g_slist_append (child_copies, repr->duplicate()); + } + + + for (GSList *i = child_objects; i != NULL; i = i->next) { + SPObject *child = SP_OBJECT (i->data); + child->deleteObject(); + } + + std::vector::iterator iter = offsets.end() - 1; + for (GSList *i = child_copies; i != NULL; i = i->next) { + Inkscape::XML::Node *copy = (Inkscape::XML::Node *) i->data; + vector->appendChildRepr(copy); + sp_repr_set_svg_double (copy, "offset", 1 - *iter); + iter --; + Inkscape::GC::release(copy); + } + + g_slist_free (child_reprs); + g_slist_free (child_copies); + g_slist_free (child_objects); +} + + + +/** +Set the position of point point_num of the gradient applied to item (either fill_or_stroke) to +p_w (in desktop coordinates). Write_repr if you want the change to become permanent. +*/ +void +sp_item_gradient_set_coords (SPItem *item, guint point_num, NR::Point p_w, bool fill_or_stroke, bool write_repr, bool scale) +{ + SPGradient *gradient = sp_item_gradient (item, fill_or_stroke); + + if (!gradient || !SP_IS_GRADIENT(gradient)) + return; + + gradient = sp_gradient_convert_to_userspace (gradient, item, fill_or_stroke? "fill" : "stroke"); + + NR::Matrix i2d = sp_item_i2d_affine (item); + NR::Point p = p_w * i2d.inverse(); + p *= (gradient->gradientTransform).inverse(); + // now p is in gradient's original coordinates + + Inkscape::XML::Node *repr = SP_OBJECT_REPR(gradient); + + if (SP_IS_LINEARGRADIENT(gradient)) { + SPLinearGradient *lg = SP_LINEARGRADIENT(gradient); + switch (point_num) { + case POINT_LG_P1: + if (scale) { + lg->x2.computed += (lg->x1.computed - p[NR::X]); + lg->y2.computed += (lg->y1.computed - p[NR::Y]); + } + lg->x1.computed = p[NR::X]; + lg->y1.computed = p[NR::Y]; + if (write_repr) { + if (scale) { + sp_repr_set_svg_double(repr, "x2", lg->x2.computed); + sp_repr_set_svg_double(repr, "y2", lg->y2.computed); + } + sp_repr_set_svg_double(repr, "x1", lg->x1.computed); + sp_repr_set_svg_double(repr, "y1", lg->y1.computed); + } else { + SP_OBJECT (gradient)->requestModified(SP_OBJECT_MODIFIED_FLAG); + } + break; + case POINT_LG_P2: + if (scale) { + lg->x1.computed += (lg->x2.computed - p[NR::X]); + lg->y1.computed += (lg->y2.computed - p[NR::Y]); + } + lg->x2.computed = p[NR::X]; + lg->y2.computed = p[NR::Y]; + if (write_repr) { + if (scale) { + sp_repr_set_svg_double(repr, "x1", lg->x1.computed); + sp_repr_set_svg_double(repr, "y1", lg->y1.computed); + } + sp_repr_set_svg_double(repr, "x2", lg->x2.computed); + sp_repr_set_svg_double(repr, "y2", lg->y2.computed); + } else { + SP_OBJECT (gradient)->requestModified(SP_OBJECT_MODIFIED_FLAG); + } + break; + default: + break; + } + } else if (SP_IS_RADIALGRADIENT(gradient)) { + + SPRadialGradient *rg = SP_RADIALGRADIENT(gradient); + NR::Point c (rg->cx.computed, rg->cy.computed); + NR::Point c_w = c * gradient->gradientTransform * i2d; // now in desktop coords + if ((point_num == POINT_RG_R1 || point_num == POINT_RG_R2) && NR::L2 (p_w - c_w) < 1e-3) { + // prevent setting a radius too close to the center + return; + } + NR::Matrix new_transform; + bool transform_set = false; + + switch (point_num) { + case POINT_RG_CENTER: + rg->fx.computed = p[NR::X] + (rg->fx.computed - rg->cx.computed); + rg->fy.computed = p[NR::Y] + (rg->fy.computed - rg->cy.computed); + rg->cx.computed = p[NR::X]; + rg->cy.computed = p[NR::Y]; + if (write_repr) { + sp_repr_set_svg_double(repr, "fx", rg->fx.computed); + sp_repr_set_svg_double(repr, "fy", rg->fy.computed); + sp_repr_set_svg_double(repr, "cx", rg->cx.computed); + sp_repr_set_svg_double(repr, "cy", rg->cy.computed); + } else { + SP_OBJECT (gradient)->requestModified(SP_OBJECT_MODIFIED_FLAG); + } + break; + case POINT_RG_FOCUS: + rg->fx.computed = p[NR::X]; + rg->fy.computed = p[NR::Y]; + if (write_repr) { + sp_repr_set_svg_double(repr, "fx", rg->fx.computed); + sp_repr_set_svg_double(repr, "fy", rg->fy.computed); + } else { + SP_OBJECT (gradient)->requestModified(SP_OBJECT_MODIFIED_FLAG); + } + break; + case POINT_RG_R1: + { + NR::Point r1_w = (c + NR::Point(rg->r.computed, 0)) * gradient->gradientTransform * i2d; + double r1_angle = NR::atan2(r1_w - c_w); + double move_angle = NR::atan2(p_w - c_w) - r1_angle; + double move_stretch = NR::L2(p_w - c_w) / NR::L2(r1_w - c_w); + + NR::Matrix move = NR::Matrix (NR::translate (-c_w)) * + NR::Matrix (NR::rotate(-r1_angle)) * + NR::Matrix (NR::scale(move_stretch, scale? move_stretch : 1)) * + NR::Matrix (NR::rotate(r1_angle)) * + NR::Matrix (NR::rotate(move_angle)) * + NR::Matrix (NR::translate (c_w)); + + new_transform = gradient->gradientTransform * i2d * move * i2d.inverse(); + transform_set = true; + + break; + } + case POINT_RG_R2: + { + NR::Point r2_w = (c + NR::Point(0, -rg->r.computed)) * gradient->gradientTransform * i2d; + double r2_angle = NR::atan2(r2_w - c_w); + double move_angle = NR::atan2(p_w - c_w) - r2_angle; + double move_stretch = NR::L2(p_w - c_w) / NR::L2(r2_w - c_w); + + NR::Matrix move = NR::Matrix (NR::translate (-c_w)) * + NR::Matrix (NR::rotate(-r2_angle)) * + NR::Matrix (NR::scale(move_stretch, scale? move_stretch : 1)) * + NR::Matrix (NR::rotate(r2_angle)) * + NR::Matrix (NR::rotate(move_angle)) * + NR::Matrix (NR::translate (c_w)); + + new_transform = gradient->gradientTransform * i2d * move * i2d.inverse(); + transform_set = true; + + break; + } + } + + if (transform_set) { + gradient->gradientTransform = new_transform; + gradient->gradientTransform_set = TRUE; + if (write_repr) { + gchar s[256]; + if (sp_svg_transform_write(s, 256, gradient->gradientTransform)) { + SP_OBJECT_REPR(gradient)->setAttribute("gradientTransform", s); + } else { + SP_OBJECT_REPR(gradient)->setAttribute("gradientTransform", NULL); + } + } else { + SP_OBJECT (gradient)->requestModified(SP_OBJECT_MODIFIED_FLAG); + } + } + } +} + +SPGradient * +sp_item_gradient_get_vector (SPItem *item, bool fill_or_stroke) +{ + SPGradient *gradient = sp_item_gradient (item, fill_or_stroke); + + if (gradient) + return sp_gradient_get_vector (gradient, false); + return NULL; +} + +SPGradientSpread +sp_item_gradient_get_spread (SPItem *item, bool fill_or_stroke) +{ + SPGradient *gradient = sp_item_gradient (item, fill_or_stroke); + + if (gradient) + return sp_gradient_get_spread (gradient); + return SP_GRADIENT_SPREAD_PAD; +} + + +/** +Returns the position of point point_num of the gradient applied to item (either fill_or_stroke), +in desktop coordinates. +*/ + +NR::Point +sp_item_gradient_get_coords (SPItem *item, guint point_num, bool fill_or_stroke) +{ + SPGradient *gradient = sp_item_gradient (item, fill_or_stroke); + + NR::Point p (0, 0); + + if (!gradient) + return p; + + if (SP_IS_LINEARGRADIENT(gradient)) { + SPLinearGradient *lg = SP_LINEARGRADIENT(gradient); + switch (point_num) { + case POINT_LG_P1: + p = NR::Point (lg->x1.computed, lg->y1.computed); + break; + case POINT_LG_P2: + p = NR::Point (lg->x2.computed, lg->y2.computed); + break; + } + } else if (SP_IS_RADIALGRADIENT(gradient)) { + SPRadialGradient *rg = SP_RADIALGRADIENT(gradient); + switch (point_num) { + case POINT_RG_CENTER: + p = NR::Point (rg->cx.computed, rg->cy.computed); + break; + case POINT_RG_FOCUS: + p = NR::Point (rg->fx.computed, rg->fy.computed); + break; + case POINT_RG_R1: + p = NR::Point (rg->cx.computed + rg->r.computed, rg->cy.computed); + break; + case POINT_RG_R2: + p = NR::Point (rg->cx.computed, rg->cy.computed - rg->r.computed); + break; + } + } + + if (SP_GRADIENT(gradient)->units == SP_GRADIENT_UNITS_OBJECTBOUNDINGBOX) { + sp_document_ensure_up_to_date(SP_OBJECT_DOCUMENT(item)); + NR::Rect const bbox = item->invokeBbox(NR::identity()); // we need "true" bbox without item_i2d_affine + p *= NR::Matrix(bbox.dimensions()[NR::X], 0, + 0, bbox.dimensions()[NR::Y], + bbox.min()[NR::X], bbox.min()[NR::Y]); + } + p *= NR::Matrix(gradient->gradientTransform) * sp_item_i2d_affine(item); + return p; +} + + +/** + * Sets item fill or stroke to the gradient of the specified type with given vector, creating + * new private gradient, if needed. + * gr has to be a normalized vector. + */ + +SPGradient * +sp_item_set_gradient(SPItem *item, SPGradient *gr, SPGradientType type, bool is_fill) +{ + g_return_val_if_fail(item != NULL, NULL); + g_return_val_if_fail(SP_IS_ITEM(item), NULL); + g_return_val_if_fail(gr != NULL, NULL); + g_return_val_if_fail(SP_IS_GRADIENT(gr), NULL); + g_return_val_if_fail(gr->state == SP_GRADIENT_STATE_VECTOR, NULL); + + SPStyle *style = SP_OBJECT_STYLE(item); + g_assert(style != NULL); + + guint style_type = is_fill? style->fill.type : style->stroke.type; + SPPaintServer *ps = NULL; + if (style_type == SP_PAINT_TYPE_PAINTSERVER) + ps = is_fill? SP_STYLE_FILL_SERVER(style) : SP_STYLE_STROKE_SERVER(style); + + if (ps + && ( (type == SP_GRADIENT_TYPE_LINEAR && SP_IS_LINEARGRADIENT(ps)) || + (type == SP_GRADIENT_TYPE_RADIAL && SP_IS_RADIALGRADIENT(ps)) ) ) + { + + /* Current fill style is the gradient of the required type */ + SPGradient *current = SP_GRADIENT(ps); + + //g_print("hrefcount %d count %d\n", SP_OBJECT_HREFCOUNT(ig), count_gradient_hrefs(SP_OBJECT(item), ig)); + + if (SP_OBJECT_HREFCOUNT(current) == 1 || + SP_OBJECT_HREFCOUNT(current) == count_gradient_hrefs(SP_OBJECT(item), current)) { + + // current is private and it's either used once, or all its uses are by children of item; + // so just change its href to vector + + if ( current != gr && sp_gradient_get_vector(current, false) != gr ) { + /* href is not the vector */ + sp_gradient_repr_set_link(SP_OBJECT_REPR(current), gr); + } + SP_OBJECT(item)->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG); + return current; + + } else { + + // the gradient is not private, or it is shared with someone else; + // normalize it (this includes creating new private if necessary) + SPGradient *normalized = sp_gradient_fork_private_if_necessary(current, gr, type, item); + + g_return_val_if_fail(normalized != NULL, NULL); + + if (normalized != current) { + + /* We have to change object style here; recursive because this is used from + * fill&stroke and must work for groups etc. */ + sp_item_repr_set_style_gradient(SP_OBJECT_REPR(item), is_fill? "fill" : "stroke", normalized, true); + } + SP_OBJECT(item)->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG); + return normalized; + } + + } else { + /* Current fill style is not a gradient or wrong type, so construct everything */ + SPGradient *constructed = sp_gradient_get_private_normalized(SP_OBJECT_DOCUMENT(item), gr, type); + constructed = sp_gradient_reset_to_userspace(constructed, item); + sp_item_repr_set_style_gradient(SP_OBJECT_REPR(item), + ( is_fill ? "fill" : "stroke" ), + constructed, true); + SP_OBJECT(item)->requestDisplayUpdate(( SP_OBJECT_MODIFIED_FLAG | + SP_OBJECT_STYLE_MODIFIED_FLAG )); + return constructed; + } +} + +static void +sp_gradient_repr_set_link(Inkscape::XML::Node *repr, SPGradient *link) +{ + g_return_if_fail(repr != NULL); + g_return_if_fail(link != NULL); + g_return_if_fail(SP_IS_GRADIENT(link)); + + gchar *ref; + if (link) { + gchar const *id = SP_OBJECT_ID(link); + size_t const len = strlen(id); + ref = (gchar*) alloca(len + 2); + *ref = '#'; + memcpy(ref + 1, id, len + 1); + } else { + ref = NULL; + } + + repr->setAttribute("xlink:href", ref); +} + +static void +sp_item_repr_set_style_gradient(Inkscape::XML::Node *repr, gchar const *property, + SPGradient *gr, bool recursive) +{ + g_return_if_fail(repr != NULL); + g_return_if_fail(gr != NULL); + g_return_if_fail(SP_IS_GRADIENT(gr)); + + gchar *val = g_strdup_printf("url(#%s)", SP_OBJECT_ID(gr)); + + SPCSSAttr *css = sp_repr_css_attr_new(); + sp_repr_css_set_property(css, property, val); + g_free(val); + if (recursive) { + sp_repr_css_change_recursive(repr, css, "style"); + } else { + sp_repr_css_change(repr, css, "style"); + } + sp_repr_css_attr_unref(css); +} + +/* + * Get default normalized gradient vector of document, create if there is none + */ + +SPGradient * +sp_document_default_gradient_vector(SPDocument *document, guint32 color) +{ + SPDefs *defs = (SPDefs *) SP_DOCUMENT_DEFS(document); + + Inkscape::XML::Node *repr = sp_repr_new("svg:linearGradient"); + + repr->setAttribute("inkscape:collect", "always"); + // set here, but removed when it's edited in the gradient editor + // to further reduce clutter, we could + // (1) here, search gradients by color and return what is found without duplication + // (2) in fill & stroke, show only one copy of each gradient in list + + Inkscape::XML::Node *stop = sp_repr_new("svg:stop"); + + gchar b[64]; + sp_svg_write_color(b, 64, color); + + { + gchar *t = g_strdup_printf("stop-color:%s;stop-opacity:1;", b); + stop->setAttribute("style", t); + g_free(t); + } + + stop->setAttribute("offset", "0"); + + repr->appendChild(stop); + Inkscape::GC::release(stop); + + stop = sp_repr_new("svg:stop"); + + { + gchar *t = g_strdup_printf("stop-color:%s;stop-opacity:0;", b); + stop->setAttribute("style", t); + g_free(t); + } + + stop->setAttribute("offset", "1"); + + repr->appendChild(stop); + Inkscape::GC::release(stop); + + SP_OBJECT_REPR(defs)->addChild(repr, NULL); + Inkscape::GC::release(repr); + + /* fixme: This does not look like nice */ + SPGradient *gr; + gr = (SPGradient *) document->getObjectByRepr(repr); + g_assert(gr != NULL); + g_assert(SP_IS_GRADIENT(gr)); + /* fixme: Maybe add extra sanity check here */ + gr->state = SP_GRADIENT_STATE_VECTOR; + + return gr; +} + +/** +Return the preferred vector for \a o, made from (in order of preference) its current vector, +current fill or stroke color, or from desktop style if \a o is NULL or doesn't have style. +*/ +SPGradient * +sp_gradient_vector_for_object(SPDocument *const doc, SPDesktop *const desktop, + SPObject *const o, bool const is_fill) +{ + guint32 rgba = 0; + if (o == NULL || SP_OBJECT_STYLE(o) == NULL) { + rgba = sp_desktop_get_color(desktop, is_fill); + } else { + // take the color of the object + SPStyle const &style = *SP_OBJECT_STYLE(o); + SPIPaint const &paint = ( is_fill + ? style.fill + : style.stroke ); + if (paint.type == SP_PAINT_TYPE_COLOR) { + rgba = sp_color_get_rgba32_ualpha(&paint.value.color, 0xff); + } else if (paint.type == SP_PAINT_TYPE_PAINTSERVER) { + SPObject *server = is_fill? SP_OBJECT_STYLE_FILL_SERVER(o) : SP_OBJECT_STYLE_STROKE_SERVER(o); + if (SP_IS_GRADIENT (server)) { + return sp_gradient_get_vector(SP_GRADIENT (server), TRUE); + } else { + rgba = sp_desktop_get_color(desktop, is_fill); + } + } else { + // if o doesn't use flat color, then take current color of the desktop. + rgba = sp_desktop_get_color(desktop, is_fill); + } + } + + return sp_document_default_gradient_vector(doc, rgba); +} + +/* + 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:textwidth=99 : diff --git a/src/gradient-chemistry.h b/src/gradient-chemistry.h new file mode 100644 index 000000000..b649a22ec --- /dev/null +++ b/src/gradient-chemistry.h @@ -0,0 +1,82 @@ +#ifndef __SP_GRADIENT_CHEMISTRY_H__ +#define __SP_GRADIENT_CHEMISTRY_H__ + +/* + * Various utility methods for gradients + * + * Author: + * Lauris Kaplinski + * bulia byak + * + * Copyright (C) 2001-2002 Lauris Kaplinski + * Copyright (C) 2001 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "forward.h" +#include "sp-gradient.h" + +/* + * Either normalizes given gradient to vector, or returns fresh normalized + * vector - in latter case, original gradient is flattened and stops cleared + * No transrefing - i.e. caller shouldn't hold reference to original and + * does not get one to new automatically (doc holds ref of every object anyways) + */ + +SPGradient *sp_gradient_ensure_vector_normalized (SPGradient *gradient); + + +/* + * Sets item fill/stroke to lineargradient with given vector, creating + * new private gradient, if needed + * gr has to be normalized vector + */ + +SPGradient *sp_item_set_gradient (SPItem *item, SPGradient *gr, SPGradientType type, bool is_fill); + +/* + * Get default normalized gradient vector of document, create if there is none + */ + +SPGradient *sp_document_default_gradient_vector (SPDocument *document, guint32 color = 0); +SPGradient *sp_gradient_vector_for_object (SPDocument *doc, SPDesktop *desktop, SPObject *o, bool is_fill); + +void sp_object_ensure_fill_gradient_normalized (SPObject *object); +void sp_object_ensure_stroke_gradient_normalized (SPObject *object); + +SPGradient *sp_gradient_convert_to_userspace (SPGradient *gr, SPItem *item, const gchar *property); +SPGradient *sp_gradient_reset_to_userspace (SPGradient *gr, SPItem *item); + +SPGradient *sp_gradient_fork_vector_if_necessary (SPGradient *gr); + +SPStop* sp_first_stop(SPGradient *gradient); +SPStop* sp_last_stop(SPGradient *gradient); +SPStop* sp_prev_stop(SPStop *stop, SPGradient *gradient); +SPStop* sp_next_stop(SPStop *stop); + +void sp_gradient_transform_multiply (SPGradient *gradient, NR::Matrix postmul, bool set); + +void sp_item_gradient_set_coords (SPItem *item, guint point_num, NR::Point p_desk, bool fill_or_stroke, bool write_repr, bool scale); +NR::Point sp_item_gradient_get_coords (SPItem *item, guint point_num, bool fill_or_stroke); +SPGradient *sp_item_gradient_get_vector (SPItem *item, bool fill_or_stroke); +SPGradientSpread sp_item_gradient_get_spread (SPItem *item, bool fill_or_stroke); + +struct SPCSSAttr; +void sp_item_gradient_stop_set_style (SPItem *item, guint point_num, bool fill_or_stroke, SPCSSAttr *stop); +guint32 sp_item_gradient_stop_query_style (SPItem *item, guint point_num, bool fill_or_stroke); +void sp_item_gradient_edit_stop (SPItem *item, guint point_num, bool fill_or_stroke); +void sp_item_gradient_reverse_vector (SPItem *item, bool fill_or_stroke); + +#endif + +/* + 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:textwidth=99 : diff --git a/src/gradient-context.cpp b/src/gradient-context.cpp new file mode 100644 index 000000000..84bed562d --- /dev/null +++ b/src/gradient-context.cpp @@ -0,0 +1,468 @@ +#define __SP_GRADIENT_CONTEXT_C__ + +/* + * Gradient drawing and editing tool + * + * Authors: + * bulia byak + * + * Copyright (C) 2005 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + + +#include + +#include "macros.h" +#include "document.h" +#include "selection.h" +#include "desktop.h" +#include "desktop-handles.h" +#include "message-context.h" +#include "message-stack.h" +#include "pixmaps/cursor-gradient.xpm" +#include "gradient-context.h" +#include +#include "prefs-utils.h" +#include "gradient-drag.h" +#include "gradient-chemistry.h" +#include "xml/repr.h" +#include "sp-item.h" + +static void sp_gradient_context_class_init(SPGradientContextClass *klass); +static void sp_gradient_context_init(SPGradientContext *gr_context); +static void sp_gradient_context_dispose(GObject *object); + +static void sp_gradient_context_setup(SPEventContext *ec); + +static gint sp_gradient_context_root_handler(SPEventContext *event_context, GdkEvent *event); + +static void sp_gradient_drag(SPGradientContext &rc, NR::Point const pt, guint state, guint32 etime); + +static SPEventContextClass *parent_class; + + +GtkType sp_gradient_context_get_type() +{ + static GType type = 0; + if (!type) { + GTypeInfo info = { + sizeof(SPGradientContextClass), + NULL, NULL, + (GClassInitFunc) sp_gradient_context_class_init, + NULL, NULL, + sizeof(SPGradientContext), + 4, + (GInstanceInitFunc) sp_gradient_context_init, + NULL, /* value_table */ + }; + type = g_type_register_static(SP_TYPE_EVENT_CONTEXT, "SPGradientContext", &info, (GTypeFlags) 0); + } + return type; +} + +static void sp_gradient_context_class_init(SPGradientContextClass *klass) +{ + GObjectClass *object_class = (GObjectClass *) klass; + SPEventContextClass *event_context_class = (SPEventContextClass *) klass; + + parent_class = (SPEventContextClass *) g_type_class_peek_parent(klass); + + object_class->dispose = sp_gradient_context_dispose; + + event_context_class->setup = sp_gradient_context_setup; + event_context_class->root_handler = sp_gradient_context_root_handler; +} + +static void sp_gradient_context_init(SPGradientContext *gr_context) +{ + SPEventContext *event_context = SP_EVENT_CONTEXT(gr_context); + + event_context->cursor_shape = cursor_gradient_xpm; + event_context->hot_x = 4; + event_context->hot_y = 4; + event_context->xp = 0; + event_context->yp = 0; + event_context->tolerance = 0; + event_context->within_tolerance = false; + event_context->item_to_select = NULL; +} + +static void sp_gradient_context_dispose(GObject *object) +{ + SPGradientContext *rc = SP_GRADIENT_CONTEXT(object); + SPEventContext *ec = SP_EVENT_CONTEXT(object); + + ec->enableGrDrag(false); + + if (rc->_message_context) { + delete rc->_message_context; + } + + G_OBJECT_CLASS(parent_class)->dispose(object); +} + +static void sp_gradient_context_setup(SPEventContext *ec) +{ + SPGradientContext *rc = SP_GRADIENT_CONTEXT(ec); + + if (((SPEventContextClass *) parent_class)->setup) { + ((SPEventContextClass *) parent_class)->setup(ec); + } + + if (prefs_get_int_attribute("tools.gradient", "selcue", 1) != 0) { + ec->enableSelectionCue(); + } + + ec->enableGrDrag(); + + rc->_message_context = new Inkscape::MessageContext(SP_DT_MSGSTACK(ec->desktop)); +} + +static gint sp_gradient_context_root_handler(SPEventContext *event_context, GdkEvent *event) +{ + static bool dragging; + + SPDesktop *desktop = event_context->desktop; + Inkscape::Selection *selection = SP_DT_SELECTION (desktop); + + SPGradientContext *rc = SP_GRADIENT_CONTEXT(event_context); + + event_context->tolerance = prefs_get_int_attribute_limited("options.dragtolerance", "value", 0, 0, 100); + double const nudge = prefs_get_double_attribute_limited("options.nudgedistance", "value", 2, 0, 1000); // in px + + GrDrag *drag = event_context->_grdrag; + g_assert (drag); + + gint ret = FALSE; + switch (event->type) { + case GDK_2BUTTON_PRESS: + if ( event->button.button == 1 ) { + for (GSList const* i = selection->itemList(); i != NULL; i = i->next) { + SPItem *item = SP_ITEM(i->data); + SPGradientType new_type = (SPGradientType) prefs_get_int_attribute ("tools.gradient", "newgradient", SP_GRADIENT_TYPE_LINEAR); + guint new_fill = prefs_get_int_attribute ("tools.gradient", "newfillorstroke", 1); + + SPGradient *vector = sp_gradient_vector_for_object(SP_DT_DOCUMENT(desktop), desktop, SP_OBJECT (item), new_fill); + + SPGradient *priv = sp_item_set_gradient(item, vector, new_type, new_fill); + sp_gradient_reset_to_userspace(priv, item); + } + + sp_document_done (SP_DT_DOCUMENT (desktop)); + + ret = TRUE; + } + break; + case GDK_BUTTON_PRESS: + if ( event->button.button == 1 ) { + NR::Point const button_w(event->button.x, event->button.y); + + // save drag origin + event_context->xp = (gint) button_w[NR::X]; + event_context->yp = (gint) button_w[NR::Y]; + event_context->within_tolerance = true; + + // remember clicked item, disregarding groups, honoring Alt; do nothing with Crtl to + // enable Ctrl+doubleclick of exactly the selected item(s) + if (!(event->button.state & GDK_CONTROL_MASK)) + event_context->item_to_select = sp_event_context_find_item (desktop, button_w, event->button.state & GDK_MOD1_MASK, TRUE); + + dragging = true; + /* Position center */ + NR::Point const button_dt = desktop->w2d(button_w); + /* Snap center to nearest magnetic point */ + + rc->origin = button_dt; + + ret = TRUE; + } + break; + case GDK_MOTION_NOTIFY: + if ( dragging + && ( event->motion.state & GDK_BUTTON1_MASK ) ) + { + if ( event_context->within_tolerance + && ( abs( (gint) event->motion.x - event_context->xp ) < event_context->tolerance ) + && ( abs( (gint) event->motion.y - event_context->yp ) < event_context->tolerance ) ) { + break; // do not drag if we're within tolerance from origin + } + // Once the user has moved farther than tolerance from the original location + // (indicating they intend to draw, not click), then always process the + // motion notify coordinates as given (no snapping back to origin) + event_context->within_tolerance = false; + + NR::Point const motion_w(event->motion.x, + event->motion.y); + NR::Point const motion_dt = event_context->desktop->w2d(motion_w); + + sp_gradient_drag(*rc, motion_dt, event->motion.state, event->motion.time); + + ret = TRUE; + } + break; + case GDK_BUTTON_RELEASE: + event_context->xp = event_context->yp = 0; + if ( event->button.button == 1 ) { + dragging = false; + + // unless clicked with Ctrl (to enable Ctrl+doubleclick) + if (event->button.state & GDK_CONTROL_MASK) { + ret = TRUE; + break; + } + + if (!event_context->within_tolerance) { + // we've been dragging, do nothing (grdrag handles that) + } else if (event_context->item_to_select) { + // no dragging, select clicked item if any + if (event->button.state & GDK_SHIFT_MASK) { + selection->toggle(event_context->item_to_select); + } else { + selection->set(event_context->item_to_select); + } + } else { + // click in an empty space; do the same as Esc + if (drag->selected) { + drag->setSelected (NULL); + } else { + selection->clear(); + } + } + + event_context->item_to_select = NULL; + ret = TRUE; + } + break; + case GDK_KEY_PRESS: + switch (get_group0_keyval (&event->key)) { + case GDK_Alt_L: + case GDK_Alt_R: + case GDK_Control_L: + case GDK_Control_R: + case GDK_Shift_L: + case GDK_Shift_R: + case GDK_Meta_L: // Meta is when you press Shift+Alt (at least on my machine) + case GDK_Meta_R: + sp_event_show_modifier_tip (event_context->defaultMessageContext(), event, + _("Ctrl: snap gradient angle"), + _("Shift: draw gradient around the starting point"), + NULL); + break; + + case GDK_x: + case GDK_X: + if (MOD__ALT_ONLY) { + desktop->setToolboxFocusTo ("altx-grad"); + ret = TRUE; + } + break; + + case GDK_Escape: + if (drag->selected) { + drag->setSelected (NULL); + } else { + selection->clear(); + } + ret = TRUE; + //TODO: make dragging escapable by Esc + break; + + case GDK_Tab: // Tab - cycle selection forward + if (!(MOD__CTRL_ONLY || (MOD__CTRL && MOD__SHIFT))) { + drag->select_next(); + ret = TRUE; + } + break; + case GDK_ISO_Left_Tab: // Shift Tab - cycle selection backward + if (!(MOD__CTRL_ONLY || (MOD__CTRL && MOD__SHIFT))) { + drag->select_prev(); + ret = TRUE; + } + break; + + case GDK_Left: // move handle left + case GDK_KP_Left: + case GDK_KP_4: + if (!MOD__CTRL) { // not ctrl + if (MOD__ALT) { // alt + if (MOD__SHIFT) drag->selected_move_screen(-10, 0); // shift + else drag->selected_move_screen(-1, 0); // no shift + } + else { // no alt + if (MOD__SHIFT) drag->selected_move(-10*nudge, 0); // shift + else drag->selected_move(-nudge, 0); // no shift + } + ret = TRUE; + } + break; + case GDK_Up: // move handle up + case GDK_KP_Up: + case GDK_KP_8: + if (!MOD__CTRL) { // not ctrl + if (MOD__ALT) { // alt + if (MOD__SHIFT) drag->selected_move_screen(0, 10); // shift + else drag->selected_move_screen(0, 1); // no shift + } + else { // no alt + if (MOD__SHIFT) drag->selected_move(0, 10*nudge); // shift + else drag->selected_move(0, nudge); // no shift + } + ret = TRUE; + } + break; + case GDK_Right: // move handle right + case GDK_KP_Right: + case GDK_KP_6: + if (!MOD__CTRL) { // not ctrl + if (MOD__ALT) { // alt + if (MOD__SHIFT) drag->selected_move_screen(10, 0); // shift + else drag->selected_move_screen(1, 0); // no shift + } + else { // no alt + if (MOD__SHIFT) drag->selected_move(10*nudge, 0); // shift + else drag->selected_move(nudge, 0); // no shift + } + ret = TRUE; + } + break; + case GDK_Down: // move handle down + case GDK_KP_Down: + case GDK_KP_2: + if (!MOD__CTRL) { // not ctrl + if (MOD__ALT) { // alt + if (MOD__SHIFT) drag->selected_move_screen(0, -10); // shift + else drag->selected_move_screen(0, -1); // no shift + } + else { // no alt + if (MOD__SHIFT) drag->selected_move(0, -10*nudge); // shift + else drag->selected_move(0, -nudge); // no shift + } + ret = TRUE; + } + break; + case GDK_r: + case GDK_R: + if (MOD__SHIFT_ONLY) { + // First try selected dragger + if (drag && drag->selected) { + drag->selected_reverse_vector(); + } else { // If no drag or no dragger selected, act on selection (both fill and stroke gradients) + for (GSList const* i = selection->itemList(); i != NULL; i = i->next) { + sp_item_gradient_reverse_vector (SP_ITEM(i->data), true); + sp_item_gradient_reverse_vector (SP_ITEM(i->data), false); + } + } + // we did an undoable action + sp_document_done (SP_DT_DOCUMENT (desktop)); + ret = TRUE; + } + break; + default: + break; + } + break; + case GDK_KEY_RELEASE: + switch (get_group0_keyval (&event->key)) { + case GDK_Alt_L: + case GDK_Alt_R: + case GDK_Control_L: + case GDK_Control_R: + case GDK_Shift_L: + case GDK_Shift_R: + case GDK_Meta_L: // Meta is when you press Shift+Alt + case GDK_Meta_R: + event_context->defaultMessageContext()->clear(); + break; + default: + break; + } + break; + default: + break; + } + + if (!ret) { + if (((SPEventContextClass *) parent_class)->root_handler) { + ret = ((SPEventContextClass *) parent_class)->root_handler(event_context, event); + } + } + + return ret; +} + +static void sp_gradient_drag(SPGradientContext &rc, NR::Point const pt, guint state, guint32 etime) +{ + SPDesktop *desktop = SP_EVENT_CONTEXT(&rc)->desktop; + Inkscape::Selection *selection = SP_DT_SELECTION(desktop); + SPDocument *document = SP_DT_DOCUMENT(desktop); + SPEventContext *ec = SP_EVENT_CONTEXT(&rc); + + if (!selection->isEmpty()) { + int type = prefs_get_int_attribute ("tools.gradient", "newgradient", 1); + int fill_or_stroke = prefs_get_int_attribute ("tools.gradient", "newfillorstroke", 1); + + SPGradient *vector; + if (ec->item_to_select) { + vector = sp_gradient_vector_for_object(document, desktop, ec->item_to_select, fill_or_stroke); + } else { + vector = sp_gradient_vector_for_object(document, desktop, SP_ITEM(selection->itemList()->data), fill_or_stroke); + } + + // HACK: reset fill-opacity - that 0.75 is annoying; BUT remove this when we have an opacity slider for all tabs + SPCSSAttr *css = sp_repr_css_attr_new(); + sp_repr_css_set_property(css, "fill-opacity", "1.0"); + + for (GSList const *i = selection->itemList(); i != NULL; i = i->next) { + + //FIXME: see above + sp_repr_css_change_recursive(SP_OBJECT_REPR(i->data), css, "style"); + + sp_item_set_gradient(SP_ITEM(i->data), vector, (SPGradientType) type, fill_or_stroke); + + if (type == SP_GRADIENT_TYPE_LINEAR) { + sp_item_gradient_set_coords (SP_ITEM(i->data), POINT_LG_P1, rc.origin, fill_or_stroke, true, false); + sp_item_gradient_set_coords (SP_ITEM(i->data), POINT_LG_P2, pt, fill_or_stroke, true, false); + } else if (type == SP_GRADIENT_TYPE_RADIAL) { + sp_item_gradient_set_coords (SP_ITEM(i->data), POINT_RG_CENTER, rc.origin, fill_or_stroke, true, false); + sp_item_gradient_set_coords (SP_ITEM(i->data), POINT_RG_R1, pt, fill_or_stroke, true, false); + } + SP_OBJECT (i->data)->requestModified(SP_OBJECT_MODIFIED_FLAG); + } + if (ec->_grdrag) { + ec->_grdrag->updateDraggers(); + // prevent regenerating draggers by selection modified signal, which sometimes + // comes too late and thus destroys the knot which we will now grab: + ec->_grdrag->local_change = true; + // give the grab out-of-bounds values of xp/yp because we're already dragging + // and therefore are already out of tolerance + ec->_grdrag->grabKnot (SP_ITEM(selection->itemList()->data), + type == SP_GRADIENT_TYPE_LINEAR? POINT_LG_P2 : POINT_RG_R1, + fill_or_stroke, 99999, 99999, etime); + } + // We did an undoable action, but sp_document_done will be called by the knot when released + + // status text; we do not track coords because this branch is run once, not all the time + // during drag + rc._message_context->setF(Inkscape::NORMAL_MESSAGE, _("Gradient for %d objects; with Ctrl to snap angle"), g_slist_length((GSList *) selection->itemList())); + } else { + SP_DT_MSGSTACK(desktop)->flash(Inkscape::WARNING_MESSAGE, _("Select objects on which to create gradient.")); + } +} + + +/* + 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:textwidth=99 : diff --git a/src/gradient-context.h b/src/gradient-context.h new file mode 100644 index 000000000..3eb7910f8 --- /dev/null +++ b/src/gradient-context.h @@ -0,0 +1,56 @@ +#ifndef __SP_GRADIENT_CONTEXT_H__ +#define __SP_GRADIENT_CONTEXT_H__ + +/* + * Gradient drawing and editing tool + * + * Authors: + * bulia byak + * + * Copyright (C) 2005 Authors + * + * Released under GNU GPL + */ + +#include +#include "event-context.h" +#include "libnr/nr-point.h" +struct SPKnotHolder; + +#define SP_TYPE_GRADIENT_CONTEXT (sp_gradient_context_get_type()) +#define SP_GRADIENT_CONTEXT(obj) (GTK_CHECK_CAST((obj), SP_TYPE_GRADIENT_CONTEXT, SPGradientContext)) +#define SP_GRADIENT_CONTEXT_CLASS(klass) (GTK_CHECK_CLASS_CAST((klass), SP_TYPE_GRADIENT_CONTEXT, SPGradientContextClass)) +#define SP_IS_GRADIENT_CONTEXT(obj) (GTK_CHECK_TYPE((obj), SP_TYPE_GRADIENT_CONTEXT)) +#define SP_IS_GRADIENT_CONTEXT_CLASS(klass) (GTK_CHECK_CLASS_TYPE((klass), SP_TYPE_GRADIENT_CONTEXT)) + +class SPGradientContext; +class SPGradientContextClass; + +struct SPGradientContext : public SPEventContext { + + NR::Point origin; + + Inkscape::MessageContext *_message_context; +}; + +struct SPGradientContextClass { + SPEventContextClass parent_class; +}; + +/* Standard Gtk function */ + +GtkType sp_gradient_context_get_type(); + +#endif + + +/* + 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:textwidth=99 : diff --git a/src/gradient-drag.cpp b/src/gradient-drag.cpp new file mode 100644 index 000000000..ffc1b7fc6 --- /dev/null +++ b/src/gradient-drag.cpp @@ -0,0 +1,1108 @@ +#define __GRADIENT_DRAG_C__ + +/* + * On-canvas gradient dragging + * + * Authors: + * bulia byak + * + * Copyright (C) 2005 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include + +#include "desktop-handles.h" +#include "selection.h" +#include "desktop.h" +#include "desktop-style.h" +#include "document.h" +#include "display/sp-ctrlline.h" + +#include "xml/repr.h" + +#include "prefs-utils.h" +#include "sp-item.h" +#include "style.h" +#include "knot.h" +#include "sp-linear-gradient.h" +#include "sp-radial-gradient.h" +#include "gradient-chemistry.h" +#include "gradient-drag.h" + +#define GR_KNOT_COLOR_NORMAL 0xffffff00 +#define GR_KNOT_COLOR_SELECTED 0x0000ff00 + +#define GR_LINE_COLOR_FILL 0x0000ff7f +#define GR_LINE_COLOR_STROKE 0x9999007f + +// screen pixels between knots when they snap: +#define SNAP_DIST 5 + +// absolute distance between gradient points for them to become a single dragger when the drag is created: +#define MERGE_DIST 0.1 + +// knot shapes corresponding to GrPoint enum +SPKnotShapeType gr_knot_shapes [] = { + SP_KNOT_SHAPE_SQUARE, //POINT_LG_P1 + SP_KNOT_SHAPE_SQUARE, + SP_KNOT_SHAPE_DIAMOND, + SP_KNOT_SHAPE_CIRCLE, + SP_KNOT_SHAPE_CIRCLE, + SP_KNOT_SHAPE_CROSS // POINT_RG_FOCUS +}; + +const gchar *gr_knot_descr [] = { + N_("Linear gradient start"), //POINT_LG_P1 + N_("Linear gradient end"), + N_("Radial gradient center"), + N_("Radial gradient radius"), + N_("Radial gradient radius"), + N_("Radial gradient focus") // POINT_RG_FOCUS +}; + +static void +gr_drag_sel_changed(Inkscape::Selection *selection, gpointer data) +{ + GrDrag *drag = (GrDrag *) data; + drag->updateDraggers (); + drag->updateLines (); + drag->updateLevels (); +} + +static void +gr_drag_sel_modified (Inkscape::Selection *selection, guint flags, gpointer data) +{ + GrDrag *drag = (GrDrag *) data; + if (drag->local_change) { + drag->local_change = false; + } else { + drag->updateDraggers (); + } + drag->updateLines (); + drag->updateLevels (); +} + +/** +When a _query_style_signal is received, check that \a property requests fill/stroke (otherwise +skip), and fill the \a style with the averaged color of all draggables of the selected dragger, if +any. +*/ +int +gr_drag_style_query (SPStyle *style, int property, gpointer data) +{ + GrDrag *drag = (GrDrag *) data; + + if (property != QUERY_STYLE_PROPERTY_FILL && property != QUERY_STYLE_PROPERTY_STROKE) { + return QUERY_STYLE_NOTHING; + } + + if (!drag->selected) { + return QUERY_STYLE_NOTHING; + } else { + int ret = QUERY_STYLE_NOTHING; + + float cf[4]; + cf[0] = cf[1] = cf[2] = cf[3] = 0; + + int count = 0; + + for (GSList const* i = drag->selected->draggables; i != NULL; i = i->next) { // for all draggables of dragger + GrDraggable *draggable = (GrDraggable *) i->data; + + if (ret == QUERY_STYLE_NOTHING) { + ret = QUERY_STYLE_SINGLE; + } else if (ret == QUERY_STYLE_SINGLE) { + ret = QUERY_STYLE_MULTIPLE_AVERAGED; + } + + guint32 c = sp_item_gradient_stop_query_style (draggable->item, draggable->point_num, draggable->fill_or_stroke); + cf[0] += SP_RGBA32_R_F (c); + cf[1] += SP_RGBA32_G_F (c); + cf[2] += SP_RGBA32_B_F (c); + cf[3] += SP_RGBA32_A_F (c); + + count ++; + } + + if (count) { + cf[0] /= count; + cf[1] /= count; + cf[2] /= count; + cf[3] /= count; + + // set both fill and stroke with our stop-color and stop-opacity + sp_color_set_rgb_float((SPColor *) &style->fill.value.color, cf[0], cf[1], cf[2]); + style->fill.set = TRUE; + style->fill.type = SP_PAINT_TYPE_COLOR; + sp_color_set_rgb_float((SPColor *) &style->stroke.value.color, cf[0], cf[1], cf[2]); + style->stroke.set = TRUE; + style->stroke.type = SP_PAINT_TYPE_COLOR; + + style->fill_opacity.value = SP_SCALE24_FROM_FLOAT (cf[3]); + style->fill_opacity.set = TRUE; + style->stroke_opacity.value = SP_SCALE24_FROM_FLOAT (cf[3]); + style->stroke_opacity.set = TRUE; + } + + return ret; + } +} + +bool +gr_drag_style_set (const SPCSSAttr *css, gpointer data) +{ + GrDrag *drag = (GrDrag *) data; + + if (!drag->selected) + return false; + + SPCSSAttr *stop = sp_repr_css_attr_new (); + + // See if the css contains interesting properties, and if so, translate them into the format + // acceptable for gradient stops + + // any of color properties, in order of increasing priority: + if (css->attribute("flood-color")) + sp_repr_css_set_property (stop, "stop-color", css->attribute("flood-color")); + + if (css->attribute("lighting-color")) + sp_repr_css_set_property (stop, "stop-color", css->attribute("lighting-color")); + + if (css->attribute("color")) + sp_repr_css_set_property (stop, "stop-color", css->attribute("color")); + + if (css->attribute("stroke") && strcmp(css->attribute("stroke"), "none")) + sp_repr_css_set_property (stop, "stop-color", css->attribute("stroke")); + + if (css->attribute("fill") && strcmp(css->attribute("fill"), "none")) + sp_repr_css_set_property (stop, "stop-color", css->attribute("fill")); + + if (css->attribute("stop-color")) + sp_repr_css_set_property (stop, "stop-color", css->attribute("stop-color")); + + // any of opacity properties, in order of increasing priority: + if (css->attribute("flood-opacity")) + sp_repr_css_set_property (stop, "stop-opacity", css->attribute("flood-color")); + + if (css->attribute("opacity")) // TODO: multiply + sp_repr_css_set_property (stop, "stop-opacity", css->attribute("color")); + + if (css->attribute("stroke-opacity")) // TODO: multiply + sp_repr_css_set_property (stop, "stop-opacity", css->attribute("stroke-opacity")); + + if (css->attribute("fill-opacity")) // TODO: multiply + sp_repr_css_set_property (stop, "stop-opacity", css->attribute("fill-opacity")); + + if ((css->attribute("fill") && !strcmp(css->attribute("fill"), "none")) || + (css->attribute("stroke") && !strcmp(css->attribute("stroke"), "none"))) + sp_repr_css_set_property (stop, "stop-opacity", "0"); // if set to none, don't change color, set opacity to 0 + + if (css->attribute("stop-opacity")) + sp_repr_css_set_property (stop, "stop-opacity", css->attribute("stop-opacity")); + + if (!stop->attributeList()) { // nothing for us here, pass it on + sp_repr_css_attr_unref(stop); + return false; + } + + for (GSList const* i = drag->selected->draggables; i != NULL; i = i->next) { // for all draggables of dragger + GrDraggable *draggable = (GrDraggable *) i->data; + + drag->local_change = true; + sp_item_gradient_stop_set_style (draggable->item, draggable->point_num, draggable->fill_or_stroke, stop); + } + + //sp_repr_css_print(stop); + sp_repr_css_attr_unref(stop); + return true; +} + +GrDrag::GrDrag(SPDesktop *desktop) { + + this->desktop = desktop; + + this->selection = SP_DT_SELECTION(desktop); + + this->draggers = NULL; + this->lines = NULL; + this->selected = NULL; + + this->hor_levels.clear(); + this->vert_levels.clear(); + + this->local_change = false; + + this->sel_changed_connection = this->selection->connectChanged( + sigc::bind ( + sigc::ptr_fun(&gr_drag_sel_changed), + (gpointer)this ) + + ); + this->sel_modified_connection = this->selection->connectModified( + sigc::bind( + sigc::ptr_fun(&gr_drag_sel_modified), + (gpointer)this ) + ); + + this->style_set_connection = this->desktop->connectSetStyle( + sigc::bind( + sigc::ptr_fun(&gr_drag_style_set), + (gpointer)this ) + ); + + this->style_query_connection = this->desktop->connectQueryStyle( + sigc::bind( + sigc::ptr_fun(&gr_drag_style_query), + (gpointer)this ) + ); + + this->updateDraggers (); + this->updateLines (); + this->updateLevels (); + + if (desktop->gr_item) { + this->setSelected (getDraggerFor (desktop->gr_item, desktop->gr_point_num, desktop->gr_fill_or_stroke)); + } +} + +GrDrag::~GrDrag() +{ + this->sel_changed_connection.disconnect(); + this->sel_modified_connection.disconnect(); + this->style_set_connection.disconnect(); + this->style_query_connection.disconnect(); + + if (this->selected) { + GrDraggable *draggable = (GrDraggable *) this->selected->draggables->data; + desktop->gr_item = draggable->item; + desktop->gr_point_num = draggable->point_num; + desktop->gr_fill_or_stroke = draggable->fill_or_stroke; + } else { + desktop->gr_item = NULL; + desktop->gr_point_num = 0; + desktop->gr_fill_or_stroke = true; + } + + for (GList *l = this->draggers; l != NULL; l = l->next) { + delete ((GrDragger *) l->data); + } + g_list_free (this->draggers); + this->draggers = NULL; + this->selected = NULL; + + for (GSList *l = this->lines; l != NULL; l = l->next) { + gtk_object_destroy( GTK_OBJECT (l->data)); + } + g_slist_free (this->lines); + this->lines = NULL; +} + +GrDraggable::GrDraggable (SPItem *item, guint point_num, bool fill_or_stroke) +{ + this->item = item; + this->point_num = point_num; + this->fill_or_stroke = fill_or_stroke; + + g_object_ref (G_OBJECT (this->item)); +} + +GrDraggable::~GrDraggable () +{ + g_object_unref (G_OBJECT (this->item)); +} + +NR::Point * +get_snap_vector (NR::Point p, NR::Point o, double snap, double initial) +{ + double r = NR::L2 (p - o); + if (r < 1e-3) + return NULL; + double angle = NR::atan2 (p - o); + // snap angle to snaps increments, starting from initial: + double a_snapped = initial + floor((angle - initial)/snap + 0.5) * snap; + // calculate the new position and subtract p to get the vector: + return new NR::Point (o + r * NR::Point(cos(a_snapped), sin(a_snapped)) - p); +} + +static void +gr_knot_moved_handler(SPKnot *knot, NR::Point const *ppointer, guint state, gpointer data) +{ + GrDragger *dragger = (GrDragger *) data; + + NR::Point p = *ppointer; + + // FIXME: take from prefs + double snap_dist = SNAP_DIST / dragger->parent->desktop->current_zoom(); + + if (state & GDK_SHIFT_MASK) { + // with Shift; unsnap if we carry more than one draggable + if (dragger->draggables && dragger->draggables->next) { + // create a new dragger + GrDragger *dr_new = new GrDragger (dragger->parent, dragger->point, NULL); + dragger->parent->draggers = g_list_prepend (dragger->parent->draggers, dr_new); + // relink to it all but the first draggable in the list + for (GSList const* i = dragger->draggables->next; i != NULL; i = i->next) { + GrDraggable *draggable = (GrDraggable *) i->data; + dr_new->addDraggable (draggable); + } + dr_new->updateKnotShape(); + g_slist_free (dragger->draggables->next); + dragger->draggables->next = NULL; + dragger->updateKnotShape(); + dragger->updateTip(); + } + } else if (!(state & GDK_CONTROL_MASK)) { + // without Shift or Ctrl; see if we need to snap to another dragger + for (GList *di = dragger->parent->draggers; di != NULL; di = di->next) { + GrDragger *d_new = (GrDragger *) di->data; + if (dragger->mayMerge(d_new) && NR::L2 (d_new->point - p) < snap_dist) { + + // Merge draggers: + for (GSList const* i = dragger->draggables; i != NULL; i = i->next) { // for all draggables of dragger + GrDraggable *draggable = (GrDraggable *) i->data; + // copy draggable to d_new: + GrDraggable *da_new = new GrDraggable (draggable->item, draggable->point_num, draggable->fill_or_stroke); + d_new->addDraggable (da_new); + } + + // unlink and delete this dragger + dragger->parent->draggers = g_list_remove (dragger->parent->draggers, dragger); + delete dragger; + + // update the new merged dragger + d_new->fireDraggables(true, false, true); + d_new->parent->updateLines(); + d_new->parent->setSelected (d_new); + d_new->updateKnotShape (); + d_new->updateTip (); + d_new->updateDependencies(true); + sp_document_done (SP_DT_DOCUMENT (d_new->parent->desktop)); + return; + } + } + } + + if (!((state & GDK_SHIFT_MASK) || ((state & GDK_CONTROL_MASK) && (state & GDK_MOD1_MASK)))) { + // See if we need to snap to any of the levels + for (guint i = 0; i < dragger->parent->hor_levels.size(); i++) { + if (fabs(p[NR::Y] - dragger->parent->hor_levels[i]) < snap_dist) { + p[NR::Y] = dragger->parent->hor_levels[i]; + sp_knot_moveto (knot, &p); + } + } + for (guint i = 0; i < dragger->parent->vert_levels.size(); i++) { + if (fabs(p[NR::X] - dragger->parent->vert_levels[i]) < snap_dist) { + p[NR::X] = dragger->parent->vert_levels[i]; + sp_knot_moveto (knot, &p); + } + } + } + + if (state & GDK_CONTROL_MASK) { + unsigned snaps = abs(prefs_get_int_attribute("options.rotationsnapsperpi", "value", 12)); + /* 0 means no snapping. */ + + // This list will store snap vectors from all draggables of dragger + GSList *snap_vectors = NULL; + + for (GSList const* i = dragger->draggables; i != NULL; i = i->next) { + GrDraggable *draggable = (GrDraggable *) i->data; + + NR::Point *dr_snap = NULL; + + if (draggable->point_num == POINT_LG_P1 || draggable->point_num == POINT_LG_P2) { + for (GList *di = dragger->parent->draggers; di != NULL; di = di->next) { + GrDragger *d_new = (GrDragger *) di->data; + if (d_new == dragger) + continue; + if (d_new->isA (draggable->item, + draggable->point_num == POINT_LG_P1? POINT_LG_P2 : POINT_LG_P1, + draggable->fill_or_stroke)) { + // found the other end of the linear gradient; + if (state & GDK_SHIFT_MASK) { + // moving linear around center + NR::Point center = NR::Point (0.5*(d_new->point + dragger->point)); + dr_snap = ¢er; + } else { + // moving linear around the other end + dr_snap = &d_new->point; + } + } + } + } else if (draggable->point_num == POINT_RG_R1 || draggable->point_num == POINT_RG_R2 || draggable->point_num == POINT_RG_FOCUS) { + for (GList *di = dragger->parent->draggers; di != NULL; di = di->next) { + GrDragger *d_new = (GrDragger *) di->data; + if (d_new == dragger) + continue; + if (d_new->isA (draggable->item, + POINT_RG_CENTER, + draggable->fill_or_stroke)) { + // found the center of the radial gradient; + dr_snap = &(d_new->point); + } + } + } else if (draggable->point_num == POINT_RG_CENTER) { + // radial center snaps to hor/vert relative to its original position + dr_snap = &(dragger->point_original); + } + + NR::Point *snap_vector = NULL; + if (dr_snap) { + if (state & GDK_MOD1_MASK) { + // with Alt, snap to the original angle and its perpendiculars + snap_vector = get_snap_vector (p, *dr_snap, M_PI/2, NR::atan2 (dragger->point_original - *dr_snap)); + } else { + // with Ctrl, snap to M_PI/snaps + snap_vector = get_snap_vector (p, *dr_snap, M_PI/snaps, 0); + } + } + if (snap_vector) { + snap_vectors = g_slist_prepend (snap_vectors, snap_vector); + } + } + + // Move by the smallest of snap vectors: + NR::Point move(9999, 9999); + for (GSList const *i = snap_vectors; i != NULL; i = i->next) { + NR::Point *snap_vector = (NR::Point *) i->data; + if (NR::L2(*snap_vector) < NR::L2(move)) + move = *snap_vector; + } + if (move[NR::X] < 9999) { + p += move; + sp_knot_moveto (knot, &p); + } + } + + dragger->point = p; + + if ((state & GDK_CONTROL_MASK) && (state & GDK_SHIFT_MASK)) { + dragger->fireDraggables (false, true); + } else { + dragger->fireDraggables (false); + } + + dragger->updateDependencies(false); +} + +/** +Called when the mouse releases a dragger knot; changes gradient writing to repr, updates other draggers if needed +*/ +static void +gr_knot_ungrabbed_handler (SPKnot *knot, unsigned int state, gpointer data) +{ + GrDragger *dragger = (GrDragger *) data; + + dragger->point_original = dragger->point = knot->pos; + + if ((state & GDK_CONTROL_MASK) && (state & GDK_SHIFT_MASK)) { + dragger->fireDraggables (true, true); + } else { + dragger->fireDraggables (true); + } + + // make this dragger selected + dragger->parent->setSelected (dragger); + + dragger->updateDependencies(true); + + // we did an undoable action + sp_document_done (SP_DT_DOCUMENT (dragger->parent->desktop)); +} + +/** +Called when a dragger knot is clicked; selects the dragger +*/ +static void +gr_knot_clicked_handler(SPKnot *knot, guint state, gpointer data) +{ + GrDragger *dragger = (GrDragger *) data; + + dragger->point_original = dragger->point; + + dragger->parent->setSelected (dragger); +} + +/** +Called when a dragger knot is doubleclicked; opens gradient editor with the stop from the first draggable +*/ +static void +gr_knot_doubleclicked_handler (SPKnot *knot, guint state, gpointer data) +{ + GrDragger *dragger = (GrDragger *) data; + + dragger->point_original = dragger->point; + + if (dragger->draggables == NULL) + return; + + GrDraggable *draggable = (GrDraggable *) dragger->draggables->data; + sp_item_gradient_edit_stop (draggable->item, draggable->point_num, draggable->fill_or_stroke); +} + +/** +Act upon all draggables of the dragger, setting them to the dragger's point +*/ +void +GrDragger::fireDraggables (bool write_repr, bool scale_radial, bool merging_focus) +{ + for (GSList const* i = this->draggables; i != NULL; i = i->next) { + GrDraggable *draggable = (GrDraggable *) i->data; + + // set local_change flag so that selection_changed callback does not regenerate draggers + this->parent->local_change = true; + + // change gradient, optionally writing to repr; prevent focus from moving if it's snapped + // to the center, unless it's the first update upon merge when we must snap it to the point + if (merging_focus || + !(draggable->point_num == POINT_RG_FOCUS && this->isA(draggable->item, POINT_RG_CENTER, draggable->fill_or_stroke))) + sp_item_gradient_set_coords (draggable->item, draggable->point_num, this->point, draggable->fill_or_stroke, write_repr, scale_radial); + } +} + +/** +Checks if the dragger has a draggable with this point_num + */ +bool +GrDragger::isA (guint point_num) +{ + for (GSList const* i = this->draggables; i != NULL; i = i->next) { + GrDraggable *draggable = (GrDraggable *) i->data; + if (draggable->point_num == point_num) { + return true; + } + } + return false; +} + +/** +Checks if the dragger has a draggable with this item, point_num, fill_or_stroke + */ +bool +GrDragger::isA (SPItem *item, guint point_num, bool fill_or_stroke) +{ + for (GSList const* i = this->draggables; i != NULL; i = i->next) { + GrDraggable *draggable = (GrDraggable *) i->data; + if (draggable->point_num == point_num && draggable->item == item && draggable->fill_or_stroke == fill_or_stroke) { + return true; + } + } + return false; +} + +bool +GrDraggable::mayMerge (GrDraggable *da2) +{ + if ((this->item == da2->item) && (this->fill_or_stroke == da2->fill_or_stroke)) { + // we must not merge the points of the same gradient! + if (!((this->point_num == POINT_RG_FOCUS && da2->point_num == POINT_RG_CENTER) || + (this->point_num == POINT_RG_CENTER && da2->point_num == POINT_RG_FOCUS))) { + // except that we can snap center and focus together + return false; + } + } + return true; +} + +bool +GrDragger::mayMerge (GrDragger *other) +{ + if (this == other) + return false; + + for (GSList const* i = this->draggables; i != NULL; i = i->next) { // for all draggables of this + GrDraggable *da1 = (GrDraggable *) i->data; + for (GSList const* j = other->draggables; j != NULL; j = j->next) { // for all draggables of other + GrDraggable *da2 = (GrDraggable *) j->data; + if (!da1->mayMerge(da2)) + return false; + } + } + return true; +} + +bool +GrDragger::mayMerge (GrDraggable *da2) +{ + for (GSList const* i = this->draggables; i != NULL; i = i->next) { // for all draggables of this + GrDraggable *da1 = (GrDraggable *) i->data; + if (!da1->mayMerge(da2)) + return false; + } + return true; +} + +/** +Updates the statusbar tip of the dragger knot, based on its draggables + */ +void +GrDragger::updateTip () +{ + if (this->knot && this->knot->tip) { + g_free (this->knot->tip); + this->knot->tip = NULL; + } + + if (g_slist_length (this->draggables) == 1) { + GrDraggable *draggable = (GrDraggable *) this->draggables->data; + char *item_desc = sp_item_description(draggable->item); + this->knot->tip = g_strdup_printf (_("%s for: %s%s; drag with Ctrl to snap angle, with Ctrl+Alt to preserve angle, with Ctrl+Shift to scale around center"), + _(gr_knot_descr[draggable->point_num]), + item_desc, + draggable->fill_or_stroke == false ? _(" (stroke)") : ""); + g_free(item_desc); + } else if (g_slist_length (draggables) == 2 && isA (POINT_RG_CENTER) && isA (POINT_RG_FOCUS)) { + this->knot->tip = g_strdup_printf (_("Radial gradient center and focus; drag with Shift to separate focus")); + } else { + this->knot->tip = g_strdup_printf (_("Gradient point shared by %d gradients; drag with Shift to separate"), + g_slist_length (this->draggables)); + } +} + +/** +Adds a draggable to the dragger + */ +void +GrDragger::updateKnotShape () +{ + if (!draggables) + return; + GrDraggable *last = (GrDraggable *) g_slist_last(draggables)->data; + g_object_set (G_OBJECT (this->knot->item), "shape", gr_knot_shapes[last->point_num], NULL); +} + +/** +Adds a draggable to the dragger + */ +void +GrDragger::addDraggable (GrDraggable *draggable) +{ + this->draggables = g_slist_prepend (this->draggables, draggable); + + this->updateTip(); +} + + +/** +Moves this dragger to the point of the given draggable, acting upon all other draggables + */ +void +GrDragger::moveThisToDraggable (SPItem *item, guint point_num, bool fill_or_stroke, bool write_repr) +{ + this->point = sp_item_gradient_get_coords (item, point_num, fill_or_stroke); + this->point_original = this->point; + + sp_knot_moveto (this->knot, &(this->point)); + + for (GSList const* i = this->draggables; i != NULL; i = i->next) { + GrDraggable *da = (GrDraggable *) i->data; + if (da->item == item && da->point_num == point_num && da->fill_or_stroke == fill_or_stroke) { + continue; + } + sp_item_gradient_set_coords (da->item, da->point_num, this->point, da->fill_or_stroke, write_repr, false); + } + // FIXME: here we should also call this->updateDependencies(write_repr); to propagate updating, but how to prevent loops? +} + + +/** +Moves all draggables that depend on this one + */ +void +GrDragger::updateDependencies (bool write_repr) +{ + for (GSList const* i = this->draggables; i != NULL; i = i->next) { + GrDraggable *draggable = (GrDraggable *) i->data; + switch (draggable->point_num) { + case POINT_LG_P1: + // the other point is dependent only when dragging with ctrl+shift + this->moveOtherToDraggable (draggable->item, POINT_LG_P2, draggable->fill_or_stroke, write_repr); + break; + case POINT_LG_P2: + this->moveOtherToDraggable (draggable->item, POINT_LG_P1, draggable->fill_or_stroke, write_repr); + break; + case POINT_RG_R2: + this->moveOtherToDraggable (draggable->item, POINT_RG_R1, draggable->fill_or_stroke, write_repr); + this->moveOtherToDraggable (draggable->item, POINT_RG_FOCUS, draggable->fill_or_stroke, write_repr); + break; + case POINT_RG_R1: + this->moveOtherToDraggable (draggable->item, POINT_RG_R2, draggable->fill_or_stroke, write_repr); + this->moveOtherToDraggable (draggable->item, POINT_RG_FOCUS, draggable->fill_or_stroke, write_repr); + break; + case POINT_RG_CENTER: + this->moveOtherToDraggable (draggable->item, POINT_RG_R1, draggable->fill_or_stroke, write_repr); + this->moveOtherToDraggable (draggable->item, POINT_RG_R2, draggable->fill_or_stroke, write_repr); + this->moveOtherToDraggable (draggable->item, POINT_RG_FOCUS, draggable->fill_or_stroke, write_repr); + break; + case POINT_RG_FOCUS: + // nothing can depend on that + break; + default: + break; + } + } +} + + + +GrDragger::GrDragger (GrDrag *parent, NR::Point p, GrDraggable *draggable) +{ + this->draggables = NULL; + + this->parent = parent; + + this->point = p; + this->point_original = p; + + // create the knot + this->knot = sp_knot_new (parent->desktop, NULL); + g_object_set (G_OBJECT (this->knot->item), "mode", SP_KNOT_MODE_XOR, NULL); + this->knot->fill [SP_KNOT_STATE_NORMAL] = GR_KNOT_COLOR_NORMAL; + this->knot->stroke [SP_KNOT_STATE_NORMAL] = 0x000000ff; + this->knot->stroke [SP_KNOT_STATE_DRAGGING] = 0x000000ff; + this->knot->stroke [SP_KNOT_STATE_MOUSEOVER] = 0x000000ff; + g_object_set (G_OBJECT (this->knot->item), "stroke_color", 0x000000ff, NULL); + + // move knot to the given point + sp_knot_set_position (this->knot, &p, SP_KNOT_STATE_NORMAL); + sp_knot_show (this->knot); + + // connect knot's signals + this->handler_id = g_signal_connect (G_OBJECT (this->knot), "moved", G_CALLBACK (gr_knot_moved_handler), this); + g_signal_connect (G_OBJECT (this->knot), "clicked", G_CALLBACK (gr_knot_clicked_handler), this); + g_signal_connect (G_OBJECT (this->knot), "doubleclicked", G_CALLBACK (gr_knot_doubleclicked_handler), this); + g_signal_connect (G_OBJECT (this->knot), "ungrabbed", G_CALLBACK (gr_knot_ungrabbed_handler), this); + + // add the initial draggable + if (draggable) + this->addDraggable (draggable); + updateKnotShape(); +} + +GrDragger::~GrDragger () +{ + // unselect if it was selected + if (this->parent->selected == this) + this->parent->setSelected (NULL); + + /* unref should call destroy */ + g_object_unref (G_OBJECT (this->knot)); + + // delete all draggables + for (GSList const* i = this->draggables; i != NULL; i = i->next) { + delete ((GrDraggable *) i->data); + } + g_slist_free (this->draggables); + this->draggables = NULL; +} + +/** +Select the dragger which has the given draggable. +*/ +GrDragger * +GrDrag::getDraggerFor (SPItem *item, guint point_num, bool fill_or_stroke) +{ + for (GList const* i = this->draggers; i != NULL; i = i->next) { + GrDragger *dragger = (GrDragger *) i->data; + for (GSList const* j = dragger->draggables; j != NULL; j = j->next) { + GrDraggable *da2 = (GrDraggable *) j->data; + if (da2->item == item && da2->point_num == point_num && da2->fill_or_stroke == fill_or_stroke) { + return (dragger); + } + } + } + return NULL; +} + + +void +GrDragger::moveOtherToDraggable (SPItem *item, guint point_num, bool fill_or_stroke, bool write_repr) +{ + GrDragger *d = this->parent->getDraggerFor (item, point_num, fill_or_stroke); + if (d && d != this) { + d->moveThisToDraggable (item, point_num, fill_or_stroke, write_repr); + } +} + + +/** +Set selected dragger +*/ +void +GrDrag::setSelected (GrDragger *dragger) +{ + if (this->selected) { + this->selected->knot->fill [SP_KNOT_STATE_NORMAL] = GR_KNOT_COLOR_NORMAL; + g_object_set (G_OBJECT (this->selected->knot->item), "fill_color", GR_KNOT_COLOR_NORMAL, NULL); + } + if (dragger) { + dragger->knot->fill [SP_KNOT_STATE_NORMAL] = GR_KNOT_COLOR_SELECTED; + g_object_set (G_OBJECT (dragger->knot->item), "fill_color", GR_KNOT_COLOR_SELECTED, NULL); + } + this->selected = dragger; + + this->desktop->emitToolSubselectionChanged((gpointer) dragger); +} + +/** +Create a line from p1 to p2 and add it to the lines list + */ +void +GrDrag::addLine (NR::Point p1, NR::Point p2, guint32 rgba) +{ + SPCanvasItem *line = sp_canvas_item_new(SP_DT_CONTROLS(this->desktop), + SP_TYPE_CTRLLINE, NULL); + sp_ctrlline_set_coords(SP_CTRLLINE(line), p1, p2); + if (rgba != GR_LINE_COLOR_FILL) // fill is the default, so don't set color for it to speed up redraw + sp_ctrlline_set_rgba32 (SP_CTRLLINE(line), rgba); + sp_canvas_item_show (line); + this->lines = g_slist_append (this->lines, line); +} + +/** +If there already exists a dragger within MERGE_DIST of p, add the draggable to it; otherwise create +new dragger and add it to draggers list + */ +void +GrDrag::addDragger (GrDraggable *draggable) +{ + NR::Point p = sp_item_gradient_get_coords (draggable->item, draggable->point_num, draggable->fill_or_stroke); + + for (GList *i = this->draggers; i != NULL; i = i->next) { + GrDragger *dragger = (GrDragger *) i->data; + if (dragger->mayMerge (draggable) && NR::L2 (dragger->point - p) < MERGE_DIST) { + // distance is small, merge this draggable into dragger, no need to create new dragger + dragger->addDraggable (draggable); + dragger->updateKnotShape(); + return; + } + } + + GrDragger *new_dragger = new GrDragger(this, p, draggable); + this->draggers = g_list_prepend (this->draggers, new_dragger); +} + +/** +Add draggers for the radial gradient rg on item +*/ +void +GrDrag::addDraggersRadial (SPRadialGradient *rg, SPItem *item, bool fill_or_stroke) +{ + addDragger (new GrDraggable (item, POINT_RG_CENTER, fill_or_stroke)); + addDragger (new GrDraggable (item, POINT_RG_FOCUS, fill_or_stroke)); + addDragger (new GrDraggable (item, POINT_RG_R1, fill_or_stroke)); + addDragger (new GrDraggable (item, POINT_RG_R2, fill_or_stroke)); +} + +/** +Add draggers for the linear gradient lg on item +*/ +void +GrDrag::addDraggersLinear (SPLinearGradient *lg, SPItem *item, bool fill_or_stroke) +{ + addDragger (new GrDraggable (item, POINT_LG_P1, fill_or_stroke)); + addDragger (new GrDraggable (item, POINT_LG_P2, fill_or_stroke)); +} + +/** +Artificially grab the knot of the dragger with this draggable; used by the gradient context +*/ +void +GrDrag::grabKnot (SPItem *item, guint point_num, bool fill_or_stroke, gint x, gint y, guint32 etime) +{ + GrDragger *dragger = getDraggerFor (item, point_num, fill_or_stroke); + if (dragger) { + sp_knot_start_dragging (dragger->knot, dragger->point, x, y, etime); + } +} + +/** +Regenerates the draggers list from the current selection; is called when selection is changed or +modified, also when a radial dragger needs to update positions of other draggers in the gradient +*/ +void +GrDrag::updateDraggers () +{ + // delete old draggers and deselect + for (GList const* i = this->draggers; i != NULL; i = i->next) { + delete ((GrDragger *) i->data); + } + g_list_free (this->draggers); + this->draggers = NULL; + this->selected = NULL; + + g_return_if_fail (this->selection != NULL); + + for (GSList const* i = this->selection->itemList(); i != NULL; i = i->next) { + + SPItem *item = SP_ITEM(i->data); + SPStyle *style = SP_OBJECT_STYLE (item); + + if (style && (style->fill.type == SP_PAINT_TYPE_PAINTSERVER)) { + SPObject *server = SP_OBJECT_STYLE_FILL_SERVER (item); + if (SP_IS_LINEARGRADIENT (server)) { + addDraggersLinear (SP_LINEARGRADIENT (server), item, true); + } else if (SP_IS_RADIALGRADIENT (server)) { + addDraggersRadial (SP_RADIALGRADIENT (server), item, true); + } + } + + if (style && (style->stroke.type == SP_PAINT_TYPE_PAINTSERVER)) { + SPObject *server = SP_OBJECT_STYLE_STROKE_SERVER (item); + if (SP_IS_LINEARGRADIENT (server)) { + addDraggersLinear (SP_LINEARGRADIENT (server), item, false); + } else if (SP_IS_RADIALGRADIENT (server)) { + addDraggersRadial (SP_RADIALGRADIENT (server), item, false); + } + } + + + } +} + +/** +Regenerates the lines list from the current selection; is called on each move of a dragger, so that +lines are always in sync with the actual gradient +*/ +void +GrDrag::updateLines () +{ + // delete old lines + for (GSList const *i = this->lines; i != NULL; i = i->next) { + gtk_object_destroy( GTK_OBJECT (i->data)); + } + g_slist_free (this->lines); + this->lines = NULL; + + g_return_if_fail (this->selection != NULL); + + for (GSList const* i = this->selection->itemList(); i != NULL; i = i->next) { + + SPItem *item = SP_ITEM(i->data); + + SPStyle *style = SP_OBJECT_STYLE (item); + + if (style && (style->fill.type == SP_PAINT_TYPE_PAINTSERVER)) { + SPObject *server = SP_OBJECT_STYLE_FILL_SERVER (item); + if (SP_IS_LINEARGRADIENT (server)) { + this->addLine (sp_item_gradient_get_coords (item, POINT_LG_P1, true), sp_item_gradient_get_coords (item, POINT_LG_P2, true), GR_LINE_COLOR_FILL); + } else if (SP_IS_RADIALGRADIENT (server)) { + NR::Point center = sp_item_gradient_get_coords (item, POINT_RG_CENTER, true); + this->addLine (center, sp_item_gradient_get_coords (item, POINT_RG_R1, true), GR_LINE_COLOR_FILL); + this->addLine (center, sp_item_gradient_get_coords (item, POINT_RG_R2, true), GR_LINE_COLOR_FILL); + } + } + + if (style && (style->stroke.type == SP_PAINT_TYPE_PAINTSERVER)) { + SPObject *server = SP_OBJECT_STYLE_STROKE_SERVER (item); + if (SP_IS_LINEARGRADIENT (server)) { + this->addLine (sp_item_gradient_get_coords (item, POINT_LG_P1, false), sp_item_gradient_get_coords (item, POINT_LG_P2, false), GR_LINE_COLOR_STROKE); + } else if (SP_IS_RADIALGRADIENT (server)) { + NR::Point center = sp_item_gradient_get_coords (item, POINT_RG_CENTER, false); + this->addLine (center, sp_item_gradient_get_coords (item, POINT_RG_R1, false), GR_LINE_COLOR_STROKE); + this->addLine (center, sp_item_gradient_get_coords (item, POINT_RG_R2, false), GR_LINE_COLOR_STROKE); + } + } + } +} + +/** +Regenerates the levels list from the current selection +*/ +void +GrDrag::updateLevels () +{ + hor_levels.clear(); + vert_levels.clear(); + + g_return_if_fail (this->selection != NULL); + + for (GSList const* i = this->selection->itemList(); i != NULL; i = i->next) { + SPItem *item = SP_ITEM(i->data); + NR::Rect rect = sp_item_bbox_desktop (item); + // Remember the edges of the bbox and the center axis + hor_levels.push_back(rect.min()[NR::Y]); + hor_levels.push_back(rect.max()[NR::Y]); + hor_levels.push_back(0.5 * (rect.min()[NR::Y] + rect.max()[NR::Y])); + vert_levels.push_back(rect.min()[NR::X]); + vert_levels.push_back(rect.max()[NR::X]); + vert_levels.push_back(0.5 * (rect.min()[NR::X] + rect.max()[NR::X])); + } +} + +void +GrDrag::selected_reverse_vector () +{ + if (selected == NULL) + return; + + for (GSList const* i = selected->draggables; i != NULL; i = i->next) { + GrDraggable *draggable = (GrDraggable *) i->data; + + sp_item_gradient_reverse_vector (draggable->item, draggable->fill_or_stroke); + } +} + +void +GrDrag::selected_move (double x, double y) +{ + if (selected == NULL) + return; + + selected->point += NR::Point (x, y); + selected->point_original = selected->point; + sp_knot_moveto (selected->knot, &(selected->point)); + + selected->fireDraggables (true); + + selected->updateDependencies(true); + + // we did an undoable action + sp_document_done (SP_DT_DOCUMENT (desktop)); +} + +void +GrDrag::selected_move_screen (double x, double y) +{ + gdouble zoom = desktop->current_zoom(); + gdouble zx = x / zoom; + gdouble zy = y / zoom; + + selected_move (zx, zy); +} + +void +GrDrag::select_next () +{ + if (selected == NULL || g_list_find(draggers, selected)->next == NULL) { + if (draggers) + setSelected ((GrDragger *) draggers->data); + } else { + setSelected ((GrDragger *) g_list_find(draggers, selected)->next->data); + } +} + +void +GrDrag::select_prev () +{ + if (selected == NULL || g_list_find(draggers, selected)->prev == NULL) { + if (draggers) + setSelected ((GrDragger *) g_list_last (draggers)->data); + } else { + setSelected ((GrDragger *) g_list_find(draggers, selected)->prev->data); + } +} + + +/* + 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 : diff --git a/src/gradient-drag.h b/src/gradient-drag.h new file mode 100644 index 000000000..365da9b92 --- /dev/null +++ b/src/gradient-drag.h @@ -0,0 +1,143 @@ +#ifndef __GRADIENT_DRAG_H__ +#define __GRADIENT_DRAG_H__ + +/* + * On-canvas gradient dragging + * + * Authors: + * bulia byak + * + * Copyright (C) 2005 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include +#include +#include + +#include +#include + +struct SPItem; +struct SPKnot; +namespace NR { +class Point; +} + +/** +This class represents a single draggable point of a gradient. It remembers the item +which has the gradient, whether it's fill or stroke, and the point number (from the +GrPoint enum). +*/ +struct GrDraggable { + GrDraggable(SPItem *item, guint point_num, bool fill_or_stroke); + ~GrDraggable(); + + SPItem *item; + guint point_num; + bool fill_or_stroke; + + bool mayMerge (GrDraggable *da2); + + inline int equals (GrDraggable *other) { + return ((item == other->item) && (point_num == other->point_num) && (fill_or_stroke == other->fill_or_stroke)); + } +}; + +struct GrDrag; + +/** +This class holds together a visible on-canvas knot and a list of draggables that need to +be moved when the knot moves. Normally there's one draggable in the list, but there may +be more when draggers are snapped together. +*/ +struct GrDragger { + GrDragger (GrDrag *parent, NR::Point p, GrDraggable *draggable); + ~GrDragger(); + + GrDrag *parent; + + SPKnot *knot; + + // position of the knot, desktop coords + NR::Point point; + // position of the knot before it began to drag; updated when released + NR::Point point_original; + + /** Connection to \a knot's "moved" signal, for blocking it (unused?). */ + guint handler_id; + + GSList *draggables; + + void addDraggable(GrDraggable *draggable); + + void updateKnotShape(); + void updateTip(); + + void moveThisToDraggable (SPItem *item, guint point_num, bool fill_or_stroke, bool write_repr); + void moveOtherToDraggable (SPItem *item, guint point_num, bool fill_or_stroke, bool write_repr); + void updateDependencies (bool write_repr); + + bool mayMerge (GrDragger *other); + bool mayMerge (GrDraggable *da2); + + bool isA (guint point_num); + bool isA (SPItem *item, guint point_num, bool fill_or_stroke); + + void fireDraggables (bool write_repr, bool scale_radial = false, bool merging_focus = false); +}; + +/** +This is the root class of the gradient dragging machinery. It holds lists of GrDraggers +and of lines (simple canvas items). It also remembers one of the draggers as selected. +*/ +struct GrDrag { + GrDrag(SPDesktop *desktop); + ~GrDrag(); + + void addLine (NR::Point p1, NR::Point p2, guint32 rgba); + + void addDragger (GrDraggable *draggable); + + void addDraggersRadial (SPRadialGradient *rg, SPItem *item, bool fill_or_stroke); + void addDraggersLinear (SPLinearGradient *lg, SPItem *item, bool fill_or_stroke); + + GrDragger *selected; + void setSelected (GrDragger *dragger); + + GrDragger *getDraggerFor (SPItem *item, guint point_num, bool fill_or_stroke); + + void grabKnot (SPItem *item, guint point_num, bool fill_or_stroke, gint x, gint y, guint32 etime); + + bool local_change; + + SPDesktop *desktop; + Inkscape::Selection *selection; + sigc::connection sel_changed_connection; + sigc::connection sel_modified_connection; + + sigc::connection style_set_connection; + sigc::connection style_query_connection; + + // lists of edges of selection bboxes, to snap draggers to + std::vector hor_levels; + std::vector vert_levels; + + GList *draggers; + GSList *lines; + + void updateDraggers (); + void updateLines (); + void updateLevels (); + + void selected_move (double x, double y); + void selected_move_screen (double x, double y); + + void select_next (); + void select_prev (); + + void selected_reverse_vector (); +}; + +#endif diff --git a/src/grid-snapper.cpp b/src/grid-snapper.cpp new file mode 100644 index 000000000..61bfa30d4 --- /dev/null +++ b/src/grid-snapper.cpp @@ -0,0 +1,78 @@ +/** + * \file grid-snapper.cpp + * \brief Snapping things to grids. + * + * Authors: + * Lauris Kaplinski + * Frank Felfe + * Carl Hetherington + * + * Copyright (C) 1999-2002 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "sp-namedview.h" +#include "display/canvas-grid.h" + +/** + * \return x rounded to the nearest multiple of c1 plus c0. + * + * \note + * If c1==0 (and c0 is finite), then returns +/-inf. This makes grid spacing of zero + * mean "ignore the grid in this dimention". We're currently discussing "good" semantics + * for guide/grid snapping. + */ + +/* FIXME: move this somewhere else, perhaps */ +static double round_to_nearest_multiple_plus(double x, double const c1, double const c0) +{ + return floor((x - c0) / c1 + .5) * c1 + c0; +} + +Inkscape::GridSnapper::GridSnapper(SPNamedView const *nv, NR::Coord const d) : LineSnapper(nv, d) +{ + +} + +Inkscape::LineSnapper::LineList Inkscape::GridSnapper::_getSnapLines(NR::Point const &p) const +{ + LineList s; + + SPCGrid *griditem = NULL; + for (GSList *l = _named_view->gridviews; l != NULL; l = l->next) { + // FIXME : this is a hack since there is only one view for now + // but when we'll handle multiple views, snapping should + // must be rethought and maybe only the current view + // should give back it's SHOWN lines to snap to + // For now, the last SPCGrid in _named_view->gridviews will be used. + griditem = SP_CGRID(l->data); + } + + g_assert(griditem != NULL); + + for (unsigned int i = 0; i < 2; ++i) { + + /* This is to make sure we snap to only visible grid lines */ + double const scale = griditem->scaled[i] ? griditem->empspacing : 1; + + NR::Coord const rounded = round_to_nearest_multiple_plus(p[i], + _named_view->gridspacing[i] * scale, + _named_view->gridorigin[i]); + + s.push_back(std::make_pair(NR::Dim2(i), rounded)); + } + + return s; +} + +/* + 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 : diff --git a/src/grid-snapper.h b/src/grid-snapper.h new file mode 100644 index 000000000..247823ac7 --- /dev/null +++ b/src/grid-snapper.h @@ -0,0 +1,46 @@ +#ifndef SEEN_GRID_SNAPPER_H +#define SEEN_GRID_SNAPPER_H + +/** + * \file grid-snapper.h + * \brief Snapping things to grids. + * + * Authors: + * Lauris Kaplinski + * Frank Felfe + * Carl Hetherington + * + * Copyright (C) 1999-2002 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "line-snapper.h" + +namespace Inkscape +{ + +/// Snap to grid +class GridSnapper : public LineSnapper +{ +public: + GridSnapper(SPNamedView const *nv, NR::Coord const d); + +private: + LineList _getSnapLines(NR::Point const &p) const; +}; + +} + +#endif + +/* + 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 : diff --git a/src/guide-snapper.cpp b/src/guide-snapper.cpp new file mode 100644 index 000000000..e247c0451 --- /dev/null +++ b/src/guide-snapper.cpp @@ -0,0 +1,52 @@ +/** + * \file guide-snapper.cpp + * \brief Snapping things to guides. + * + * Authors: + * Lauris Kaplinski + * Frank Felfe + * Carl Hetherington + * + * Copyright (C) 1999-2002 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "libnr/nr-values.h" +#include "libnr/nr-point-fns.h" +#include "sp-namedview.h" +#include "sp-guide.h" + +Inkscape::GuideSnapper::GuideSnapper(SPNamedView const *nv, NR::Coord const d) : LineSnapper(nv, d) +{ + +} + +Inkscape::GuideSnapper::LineList Inkscape::GuideSnapper::_getSnapLines(NR::Point const &p) const +{ + LineList s; + + for (GSList const *l = _named_view->guides; l != NULL; l = l->next) { + SPGuide const *g = SP_GUIDE(l->data); + + /* We assume here that guides are horizontal or vertical */ + if (g->normal == component_vectors[NR::X]) { + s.push_back(std::make_pair(NR::X, g->position)); + } else { + s.push_back(std::make_pair(NR::Y, g->position)); + } + } + + return s; +} + +/* + 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 : diff --git a/src/guide-snapper.h b/src/guide-snapper.h new file mode 100644 index 000000000..f4c7b2de7 --- /dev/null +++ b/src/guide-snapper.h @@ -0,0 +1,52 @@ +#ifndef SEEN_GUIDE_SNAPPER_H +#define SEEN_GUIDE_SNAPPER_H + +/** + * \file guide-snapper.h + * \brief Snapping things to guides. + * + * Authors: + * Lauris Kaplinski + * Frank Felfe + * Carl Hetherington + * + * Copyright (C) 1999-2002 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "libnr/nr-forward.h" +#include "libnr/nr-coord.h" +#include "snapper.h" + +struct SPNamedView; + +namespace Inkscape +{ + +/// Snap to guides +class GuideSnapper : public LineSnapper +{ +public: + GuideSnapper(SPNamedView const *nv, NR::Coord const d); + +private: + LineList _getSnapLines(NR::Point const &p) const; +}; + +} + +#endif + + + +/* + 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 : diff --git a/src/help.cpp b/src/help.cpp new file mode 100644 index 000000000..919a200b0 --- /dev/null +++ b/src/help.cpp @@ -0,0 +1,59 @@ +#define __SP_HELP_C__ + +/* + * Help/About window + * + * Authors: + * Lauris Kaplinski + * bulia byak + * + * Copyright (C) 1999-2005 authors + * Copyright (C) 2000-2002 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif +#include "path-prefix.h" + +#include "help.h" +#include "file.h" + +#include "ui/dialog/aboutbox.h" + +void +sp_help_about (void) +{ + Inkscape::UI::Dialog::AboutBox::show_about(); +} + +void +sp_help_open_tutorial(GtkMenuItem *, gpointer data) +{ + gchar const *name = static_cast(data); + gchar *c = g_build_filename(INKSCAPE_TUTORIALSDIR, name, NULL); + sp_file_open(c, NULL, false, false); + g_free(c); +} + +void +sp_help_open_screen(gchar const *name) +{ + gchar *c = g_build_filename(INKSCAPE_SCREENSDIR, name, NULL); + sp_file_open(c, NULL, false, false); + g_free(c); +} + + +/* + 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 : diff --git a/src/help.h b/src/help.h new file mode 100644 index 000000000..34569e840 --- /dev/null +++ b/src/help.h @@ -0,0 +1,35 @@ +#ifndef SEEN_HELP_H +#define SEEN_HELP_H + +/** + * Help/About window + * + * Authors: + * Lauris Kaplinski + * + * Copyright (C) 1999-2003 authors + * Copyright (C) 2000-2002 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include +#include + +void sp_help_about(void); +void sp_help_open_tutorial(GtkMenuItem *menuitem, gpointer data); +void sp_help_open_screen(gchar const *name); + + +#endif /* !SEEN_HELP_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:encoding=utf-8:textwidth=99 : diff --git a/src/helper/.cvsignore b/src/helper/.cvsignore new file mode 100644 index 000000000..4a5454d13 --- /dev/null +++ b/src/helper/.cvsignore @@ -0,0 +1,9 @@ +Makefile +Makefile.in +.deps +.libs +sp-marshal.cpp +sp-marshal.h +makefile +.dirstamp +*-test diff --git a/src/helper/HACKING b/src/helper/HACKING new file mode 100644 index 000000000..2e3ddcbcd --- /dev/null +++ b/src/helper/HACKING @@ -0,0 +1,35 @@ +* +* Unsystematized and temporary helper things +* + +1. libspchelp + +Here you find: + +Useful add-ons to gnome-canvas, such as: + gnome_canvas_item_i2p_affine + +Canvas items useful for editing: +Ctrl - a small rectangle, which do no scale when parent is scaled +CtrlRect - 'rubberband' box +CtrlLine - simple straight line +Probably some of these will be rendered without libart at all - we do not +need antialias for rubberband. + +Yet to implement: +Guide - simple guideline. +FastSVP, FastVpath - not decided yet, but for node editing it seems to be +useful to have special rendering mode - fast stroking of single pixel wide +lines without antialias. + +2. libgt1 + +This is complete placeholder. All type1 parsing code is already included +in gnome-print development version and as soon as it will be more widely +available, I remove this. + +These programs are written mainly by Adobe and Raph Levien, probably others. +I modified gt1-parset1.c to force it to display most of iso-8859-1 characters. + +Lauris Kaplinski + diff --git a/src/helper/Makefile_insert b/src/helper/Makefile_insert new file mode 100644 index 000000000..9f061c090 --- /dev/null +++ b/src/helper/Makefile_insert @@ -0,0 +1,51 @@ +## Makefile.am fragment sourced by src/Makefile.am. + +# +# Miscellaneous unsystematized and temporary helper utilities +# +# libspchelp - canvas utilities, specific canvas items +# + +helper/all: helper/libspchelp.a + +helper/clean: + rm -f helper/libspchelp.a $(helper_libspchelp_a_OBJECTS) + +helper/unit-menu.$(OBJEXT): helper/sp-marshal.h + +helper_libspchelp_a_SOURCES = \ + helper/action.cpp \ + helper/action.h \ + helper/gnome-utils.cpp \ + helper/gnome-utils.h \ + helper/helper-forward.h \ + helper/png-write.cpp \ + helper/png-write.h \ + helper/sp-marshal.cpp \ + helper/sp-marshal.h \ + helper/stlport.h \ + helper/unit-menu.cpp \ + helper/unit-menu.h \ + helper/units.cpp \ + helper/units.h \ + helper/window.cpp \ + helper/window.h \ + helper/stock-items.cpp \ + helper/stock-items.h + + +# TODO: Check that the generated sp-marshal.h is the same as before. +helper/sp-marshal.h: helper/sp-marshal.list + glib-genmarshal --prefix=sp_marshal --header $(srcdir)/helper/sp-marshal.list > helper/tmp.$$$$ \ + && mv helper/tmp.$$$$ helper/sp-marshal.h + +helper/sp-marshal.cpp: helper/sp-marshal.list helper/sp-marshal.h + ( echo '#include "helper/sp-marshal.h"' && \ + glib-genmarshal --prefix=sp_marshal --body $(srcdir)/helper/sp-marshal.list ) \ + > helper/tmp.$$$$ \ + && mv helper/tmp.$$$$ helper/sp-marshal.cpp + +helper/sp-marshal.cpp helper/sp-marshal.h: Makefile + +helper_units_test_SOURCES = helper/units-test.cpp +helper_units_test_LDADD = helper/libspchelp.a -lglib-2.0 diff --git a/src/helper/action.cpp b/src/helper/action.cpp new file mode 100644 index 000000000..9584c5dae --- /dev/null +++ b/src/helper/action.cpp @@ -0,0 +1,228 @@ +#define __SP_ACTION_C__ + +/** \file + * SPAction implementation + * + * Author: + * Lauris Kaplinski + * + * Copyright (C) 2003 Lauris Kaplinski + * + * This code is in public domain + */ + +#include + + +#include "helper/action.h" + +static void sp_action_class_init (SPActionClass *klass); +static void sp_action_init (SPAction *action); +static void sp_action_finalize (NRObject *object); + +static NRActiveObjectClass *parent_class; + +/** + * Register SPAction class and return its type. + */ +NRType +sp_action_get_type (void) +{ + static unsigned int type = 0; + if (!type) { + type = nr_object_register_type (NR_TYPE_ACTIVE_OBJECT, + "SPAction", + sizeof (SPActionClass), + sizeof (SPAction), + (void (*) (NRObjectClass *)) sp_action_class_init, + (void (*) (NRObject *)) sp_action_init); + } + return type; +} + +/** + * SPAction vtable initialization. + */ +static void +sp_action_class_init (SPActionClass *klass) +{ + NRObjectClass * object_class; + + object_class = (NRObjectClass *) klass; + + parent_class = (NRActiveObjectClass *) (((NRObjectClass *) klass)->parent); + + object_class->finalize = sp_action_finalize; + object_class->cpp_ctor = NRObject::invoke_ctor; +} + +/** + * Callback for SPAction object initialization. + */ +static void +sp_action_init (SPAction *action) +{ + action->sensitive = 0; + action->active = 0; + action->view = NULL; + action->id = action->name = action->tip = NULL; + action->image = NULL; +} + +/** + * Called before SPAction object destruction. + */ +static void +sp_action_finalize (NRObject *object) +{ + SPAction *action; + + action = (SPAction *) object; + + if (action->image) free (action->image); + if (action->tip) free (action->tip); + if (action->name) free (action->name); + if (action->id) free (action->id); + + ((NRObjectClass *) (parent_class))->finalize (object); +} + +/** + * Create new SPAction object and set its properties. + */ +SPAction * +sp_action_new(Inkscape::UI::View::View *view, + const gchar *id, + const gchar *name, + const gchar *tip, + const gchar *image, + Inkscape::Verb * verb) +{ + SPAction *action = (SPAction *)nr_object_new(SP_TYPE_ACTION); + + action->view = view; + action->sensitive = TRUE; + if (id) action->id = strdup (id); + if (name) action->name = strdup (name); + if (tip) action->tip = strdup (tip); + if (image) action->image = strdup (image); + action->verb = verb; + + return action; +} + +/** + \return None + \brief Executes an action + \param action The action to be executed + \param data Data that is passed into the action. This depends + on the situation that the action is used in. + + This function implements the 'action' in SPActions. It first validates + its parameters, making sure it got an action passed in. Then it + turns that action into its parent class of NRActiveObject. The + NRActiveObject allows for listeners to be attached to it. This + function goes through those listeners and calls them with the + vector that was attached to the listener. +*/ +void +sp_action_perform (SPAction *action, void * data) +{ + NRActiveObject *aobject; + + nr_return_if_fail (action != NULL); + nr_return_if_fail (SP_IS_ACTION (action)); + + aobject = NR_ACTIVE_OBJECT(action); + if (aobject->callbacks) { + unsigned int i; + for (i = 0; i < aobject->callbacks->length; i++) { + NRObjectListener *listener; + SPActionEventVector *avector; + + listener = &aobject->callbacks->listeners[i]; + avector = (SPActionEventVector *) listener->vector; + + if ((listener->size >= sizeof (SPActionEventVector)) && avector != NULL && avector->perform != NULL) { + avector->perform (action, listener->data, data); + } + } + } +} + +/** + * Change activation in all actions that can be taken with the action. + */ +void +sp_action_set_active (SPAction *action, unsigned int active) +{ + nr_return_if_fail (action != NULL); + nr_return_if_fail (SP_IS_ACTION (action)); + + if (active != action->active) { + NRActiveObject *aobject; + action->active = active; + aobject = (NRActiveObject *) action; + if (aobject->callbacks) { + unsigned int i; + for (i = 0; i < aobject->callbacks->length; i++) { + NRObjectListener *listener; + SPActionEventVector *avector; + listener = aobject->callbacks->listeners + i; + avector = (SPActionEventVector *) listener->vector; + if ((listener->size >= sizeof (SPActionEventVector)) && avector->set_active) { + avector->set_active (action, active, listener->data); + } + } + } + } +} + +/** + * Change sensitivity in all actions that can be taken with the action. + */ +void +sp_action_set_sensitive (SPAction *action, unsigned int sensitive) +{ + nr_return_if_fail (action != NULL); + nr_return_if_fail (SP_IS_ACTION (action)); + + if (sensitive != action->sensitive) { + NRActiveObject *aobject; + action->sensitive = sensitive; + aobject = (NRActiveObject *) action; + if (aobject->callbacks) { + unsigned int i; + for (i = 0; i < aobject->callbacks->length; i++) { + NRObjectListener *listener; + SPActionEventVector *avector; + listener = aobject->callbacks->listeners + i; + avector = (SPActionEventVector *) listener->vector; + if ((listener->size >= sizeof (SPActionEventVector)) && avector->set_sensitive) { + avector->set_sensitive (action, sensitive, listener->data); + } + } + } + } +} + +/** + * Return View associated with the action. + */ +Inkscape::UI::View::View * +sp_action_get_view (SPAction *action) +{ + g_return_val_if_fail (SP_IS_ACTION (action), NULL); + return action->view; +} + +/* + 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 : diff --git a/src/helper/action.h b/src/helper/action.h new file mode 100644 index 000000000..1e3646439 --- /dev/null +++ b/src/helper/action.h @@ -0,0 +1,91 @@ +#ifndef __SP_ACTION_H__ +#define __SP_ACTION_H__ + +/** \file + * Inkscape UI action implementation + */ + +/* + * Author: + * Lauris Kaplinski + * + * Copyright (C) 2003 Lauris Kaplinski + * + * This code is in public domain + */ + +/** A macro to get the GType for actions */ +#define SP_TYPE_ACTION (sp_action_get_type()) +/** A macro to cast and check the cast of changing an object to an action */ +#define SP_ACTION(o) (NR_CHECK_INSTANCE_CAST((o), SP_TYPE_ACTION, SPAction)) +/** A macro to check whether or not something is an action */ +#define SP_IS_ACTION(o) (NR_CHECK_INSTANCE_TYPE((o), SP_TYPE_ACTION)) + +#include "helper/helper-forward.h" +#include "libnr/nr-object.h" +#include "forward.h" + +//class Inkscape::UI::View::View; + +namespace Inkscape { +class Verb; +} + + +/** This is a structure that is used to hold all the possible + actions that can be taken with an action. These are the + function pointers available. */ +struct SPActionEventVector { + NRObjectEventVector object_vector; /**< Parent class */ + void (* perform)(SPAction *action, void *ldata, void *pdata); /**< Actually do the action of the event. Called by sp_perform_action */ + void (* set_active)(SPAction *action, unsigned active, void *data); /**< Callback for activation change */ + void (* set_sensitive)(SPAction *action, unsigned sensitive, void *data); /**< Callback for a change in sensitivity */ + void (* set_shortcut)(SPAction *action, unsigned shortcut, void *data); /**< Callback for setting the shortcut for this function */ +}; + +/** All the data that is required to be an action. This + structure identifies the action and has the data to + create menus and toolbars for the action */ +struct SPAction : public NRActiveObject { + unsigned sensitive : 1; /**< Value to track whether the action is sensitive */ + unsigned active : 1; /**< Value to track whether the action is active */ + Inkscape::UI::View::View *view; /**< The View to which this action is attached */ + gchar *id; /**< The identifier for the action */ + gchar *name; /**< Full text name of the action */ + gchar *tip; /**< A tooltip to describe the action */ + gchar *image; /**< An image to visually identify the action */ + Inkscape::Verb *verb; /**< The verb that produced this action */ +}; + +/** The action class is the same as its parent. */ +struct SPActionClass { + NRActiveObjectClass parent_class; /**< Parent Class */ +}; + +NRType sp_action_get_type(); + +SPAction *sp_action_new(Inkscape::UI::View::View *view, + gchar const *id, + gchar const *name, + gchar const *tip, + gchar const *image, + Inkscape::Verb *verb); + +void sp_action_perform(SPAction *action, void *data); +void sp_action_set_active(SPAction *action, unsigned active); +void sp_action_set_sensitive(SPAction *action, unsigned sensitive); +Inkscape::UI::View::View *sp_action_get_view(SPAction *action); + +#endif + + +/* + 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:textwidth=99 : diff --git a/src/helper/gnome-utils.cpp b/src/helper/gnome-utils.cpp new file mode 100644 index 000000000..aa70dd1a2 --- /dev/null +++ b/src/helper/gnome-utils.cpp @@ -0,0 +1,108 @@ +#define __GNOME_UTILS_C__ + +/* + * Helpers + * + * Author: + * Mitsuru Oka + * Lauris Kaplinski + * + * Copyright (C) 2002 authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include +#include +#include + +/** + * gnome_uri_list_extract_uris: + * @uri_list: an uri-list in the standard format. + * + * Returns a GList containing strings allocated with g_malloc + * that have been splitted from @uri-list. + */ +GList* +gnome_uri_list_extract_uris (const gchar* uri_list) +{ + const gchar *p, *q; + gchar *retval; + GList *result = NULL; + + g_return_val_if_fail (uri_list != NULL, NULL); + + p = uri_list; + + /* We don't actually try to validate the URI according to RFC + * 2396, or even check for allowed characters - we just ignore + * comments and trim whitespace off the ends. We also + * allow LF delimination as well as the specified CRLF. + */ + while (p) { + if (*p != '#') { + while (isspace(*p)) + p++; + + q = p; + while (*q && (*q != '\n') && (*q != '\r')) + q++; + + if (q > p) { + q--; + while (q > p && isspace(*q)) + q--; + + retval = (gchar*)g_malloc (q - p + 2); + strncpy (retval, p, q - p + 1); + retval[q - p + 1] = '\0'; + + result = g_list_prepend (result, retval); + } + } + p = strchr (p, '\n'); + if (p) + p++; + } + + return g_list_reverse (result); +} + +/** + * gnome_uri_list_extract_filenames: + * @uri_list: an uri-list in the standard format + * + * Returns a GList containing strings allocated with g_malloc + * that contain the filenames in the uri-list. + * + * Note that unlike gnome_uri_list_extract_uris() function, this + * will discard any non-file uri from the result value. + */ +GList* +gnome_uri_list_extract_filenames (const gchar* uri_list) +{ + GList *tmp_list, *node, *result; + + g_return_val_if_fail (uri_list != NULL, NULL); + + result = gnome_uri_list_extract_uris (uri_list); + + tmp_list = result; + while (tmp_list) { + gchar *s = (gchar*)tmp_list->data; + + node = tmp_list; + tmp_list = tmp_list->next; + + if (!strncmp (s, "file:", 5)) { + node->data = g_filename_from_uri (s, NULL, NULL); + /* not sure if this fallback is useful at all */ + if (!node->data) node->data = g_strdup (s+5); + } else { + result = g_list_remove_link(result, node); + g_list_free_1 (node); + } + g_free (s); + } + return result; +} diff --git a/src/helper/gnome-utils.h b/src/helper/gnome-utils.h new file mode 100644 index 000000000..0a28c95a9 --- /dev/null +++ b/src/helper/gnome-utils.h @@ -0,0 +1,36 @@ +/* + * GNOME Utils - Migration helper + * + * Author: + * GNOME Developer + * Mitsuru Oka + * Lauris Kaplinski + * + * Copyright (C) 2001 Lauris Kaplinski and Ximian, Inc. + * + * Released under GNU GPL + */ + + +#ifndef __GNOME_UTILS_H__ +#define __GNOME_UTILS_H__ + +#include +#include + +GList *gnome_uri_list_extract_uris(gchar const *uri_list); + +GList *gnome_uri_list_extract_filenames(gchar const *uri_list); + +#endif /* __GNOME_UTILS_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:encoding=utf-8:textwidth=99 : diff --git a/src/helper/helper-forward.h b/src/helper/helper-forward.h new file mode 100644 index 000000000..7cb0cddea --- /dev/null +++ b/src/helper/helper-forward.h @@ -0,0 +1,35 @@ +#ifndef __HELPER_FORWARD_H__ +#define __HELPER_FORWARD_H__ + +/* + * Forward declarations + * + * Author: + * Lauris Kaplinski + * + * Copyright (C) 2002 Lauris Kaplinski + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + + +struct SPAction; +struct SPActionClass; +struct SPActionEventVector; + +struct SPUnit; +struct SPUnitSelector; +struct SPUnitSelectorClass; + +#endif + +/* + 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:textwidth=99 : diff --git a/src/helper/makefile.in b/src/helper/makefile.in new file mode 100644 index 000000000..edb3951aa --- /dev/null +++ b/src/helper/makefile.in @@ -0,0 +1,17 @@ +# Convenience stub makefile to call the real Makefile. + +@SET_MAKE@ + +# Explicit so that it's the default rule. +all: + cd .. && $(MAKE) helper/all + +clean %.a %.o: + cd .. && $(MAKE) helper/$@ + +.PHONY: all clean + +OBJEXT = @OBJEXT@ + +.SUFFIXES: +.SUFFIXES: .a .$(OBJEXT) diff --git a/src/helper/png-write.cpp b/src/helper/png-write.cpp new file mode 100644 index 000000000..21eca1efa --- /dev/null +++ b/src/helper/png-write.cpp @@ -0,0 +1,205 @@ +#define __SP_PNG_WRITE_C__ + +/* + * PNG file format utilities + * + * Authors: + * Lauris Kaplinski + * Whoever wrote this example in libpng documentation + * + * Copyright (C) 1999-2002 authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include "png-write.h" +#include "io/sys.h" + +/* This is an example of how to use libpng to read and write PNG files. + * The file libpng.txt is much more verbose then this. If you have not + * read it, do so first. This was designed to be a starting point of an + * implementation. This is not officially part of libpng, and therefore + * does not require a copyright notice. + * + * This file does not currently compile, because it is missing certain + * parts, like allocating memory to hold an image. You will have to + * supply these parts to get it to compile. For an example of a minimal + * working PNG reader/writer, see pngtest.c, included in this distribution. + */ + +/* write a png file */ + +typedef struct SPPNGBD { + const guchar *px; + int rowstride; +} SPPNGBD; + +static int +sp_png_get_block_stripe (const guchar **rows, int row, int num_rows, void *data) +{ + SPPNGBD *bd = (SPPNGBD *) data; + + for (int r = 0; r < num_rows; r++) { + rows[r] = bd->px + (row + r) * bd->rowstride; + } + + return num_rows; +} + +int +sp_png_write_rgba (const gchar *filename, const guchar *px, int width, int height, int rowstride) +{ + SPPNGBD bd; + + bd.px = px; + bd.rowstride = rowstride; + + return sp_png_write_rgba_striped (filename, width, height, sp_png_get_block_stripe, &bd); +} + +int +sp_png_write_rgba_striped (const gchar *filename, int width, int height, + int (* get_rows) (const guchar **rows, int row, int num_rows, void *data), + void *data) +{ + FILE *fp; + png_structp png_ptr; + png_infop info_ptr; + png_color_8 sig_bit; + png_text text_ptr[3]; + png_uint_32 r; + + g_return_val_if_fail (filename != NULL, FALSE); + + /* open the file */ + + Inkscape::IO::dump_fopen_call(filename, "M"); + fp = Inkscape::IO::fopen_utf8name(filename, "wb"); + g_return_val_if_fail (fp != NULL, FALSE); + + /* Create and initialize the png_struct with the desired error handler + * functions. If you want to use the default stderr and longjump method, + * you can supply NULL for the last three parameters. We also check that + * the library version is compatible with the one used at compile time, + * in case we are using dynamically linked libraries. REQUIRED. + */ + png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + + if (png_ptr == NULL) { + fclose(fp); + return FALSE; + } + + /* Allocate/initialize the image information data. REQUIRED */ + info_ptr = png_create_info_struct(png_ptr); + if (info_ptr == NULL) { + fclose(fp); + png_destroy_write_struct(&png_ptr, NULL); + return FALSE; + } + + /* Set error handling. REQUIRED if you aren't supplying your own + * error hadnling functions in the png_create_write_struct() call. + */ + if (setjmp(png_ptr->jmpbuf)) { + /* If we get here, we had a problem reading the file */ + fclose(fp); + png_destroy_write_struct(&png_ptr, &info_ptr); + return FALSE; + } + + /* set up the output control if you are using standard C streams */ + png_init_io(png_ptr, fp); + + /* Set the image information here. Width and height are up to 2^31, + * bit_depth is one of 1, 2, 4, 8, or 16, but valid values also depend on + * the color_type selected. color_type is one of PNG_COLOR_TYPE_GRAY, + * PNG_COLOR_TYPE_GRAY_ALPHA, PNG_COLOR_TYPE_PALETTE, PNG_COLOR_TYPE_RGB, + * or PNG_COLOR_TYPE_RGB_ALPHA. interlace is either PNG_INTERLACE_NONE or + * PNG_INTERLACE_ADAM7, and the compression_type and filter_type MUST + * currently be PNG_COMPRESSION_TYPE_BASE and PNG_FILTER_TYPE_BASE. REQUIRED + */ + png_set_IHDR(png_ptr, info_ptr, + width, + height, + 8, /* bit_depth */ + PNG_COLOR_TYPE_RGB_ALPHA, + PNG_INTERLACE_NONE, + PNG_COMPRESSION_TYPE_BASE, + PNG_FILTER_TYPE_BASE); + + /* otherwise, if we are dealing with a color image then */ + sig_bit.red = 8; + sig_bit.green = 8; + sig_bit.blue = 8; + /* if the image has an alpha channel then */ + sig_bit.alpha = 8; + png_set_sBIT(png_ptr, info_ptr, &sig_bit); + + /* Made by Inkscape comment */ + text_ptr[0].key = "Software"; + text_ptr[0].text = "www.inkscape.org"; + text_ptr[0].compression = PNG_TEXT_COMPRESSION_NONE; + png_set_text(png_ptr, info_ptr, text_ptr, 1); + + /* other optional chunks like cHRM, bKGD, tRNS, tIME, oFFs, pHYs, */ + /* note that if sRGB is present the cHRM chunk must be ignored + * on read and must be written in accordance with the sRGB profile */ + + /* Write the file header information. REQUIRED */ + png_write_info(png_ptr, info_ptr); + + /* Once we write out the header, the compression type on the text + * chunks gets changed to PNG_TEXT_COMPRESSION_NONE_WR or + * PNG_TEXT_COMPRESSION_zTXt_WR, so it doesn't get written out again + * at the end. + */ + + /* set up the transformations you want. Note that these are + * all optional. Only call them if you want them. + */ + + /* --- CUT --- */ + + /* The easiest way to write the image (you may have a different memory + * layout, however, so choose what fits your needs best). You need to + * use the first method if you aren't handling interlacing yourself. + */ + + r = 0; + while (r < static_cast< png_uint_32 > (height) ) { + png_bytep row_pointers[64]; + int h, n; + + h = MIN (height - r, 64); + n = get_rows ((const unsigned char **) row_pointers, r, h, data); + if (!n) break; + png_write_rows (png_ptr, row_pointers, n); + r += n; + } + + /* You can write optional chunks like tEXt, zTXt, and tIME at the end + * as well. + */ + + /* It is REQUIRED to call this to finish writing the rest of the file */ + png_write_end(png_ptr, info_ptr); + + /* if you allocated any text comments, free them here */ + + /* clean up after the write, and free any memory allocated */ + png_destroy_write_struct(&png_ptr, &info_ptr); + + /* close the file */ + fclose(fp); + + /* that's it */ + return TRUE; +} + diff --git a/src/helper/png-write.h b/src/helper/png-write.h new file mode 100644 index 000000000..2d2c16544 --- /dev/null +++ b/src/helper/png-write.h @@ -0,0 +1,23 @@ +#ifndef __SP_PNG_WRITE_H__ +#define __SP_PNG_WRITE_H__ + +/* + * PNG file format utilities + * + * Authors: + * Lauris Kaplinski + * + * Copyright (C) 1999-2002 Lauris Kaplinski + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include + +int sp_png_write_rgba(gchar const *filename, guchar const *px, int width, int height, int rowstride); + +int sp_png_write_rgba_striped(gchar const *filename, int width, int height, + int (* get_rows) (guchar const **rows, int row, int num_rows, void *data), + void *data); + +#endif diff --git a/src/helper/sp-marshal.cpp.mingw b/src/helper/sp-marshal.cpp.mingw new file mode 100644 index 000000000..8a7e7648c --- /dev/null +++ b/src/helper/sp-marshal.cpp.mingw @@ -0,0 +1,520 @@ +#include "helper/sp-marshal.h" + +#include + + +#ifdef G_ENABLE_DEBUG +#define g_marshal_value_peek_boolean(v) g_value_get_boolean (v) +#define g_marshal_value_peek_char(v) g_value_get_char (v) +#define g_marshal_value_peek_uchar(v) g_value_get_uchar (v) +#define g_marshal_value_peek_int(v) g_value_get_int (v) +#define g_marshal_value_peek_uint(v) g_value_get_uint (v) +#define g_marshal_value_peek_long(v) g_value_get_long (v) +#define g_marshal_value_peek_ulong(v) g_value_get_ulong (v) +#define g_marshal_value_peek_int64(v) g_value_get_int64 (v) +#define g_marshal_value_peek_uint64(v) g_value_get_uint64 (v) +#define g_marshal_value_peek_enum(v) g_value_get_enum (v) +#define g_marshal_value_peek_flags(v) g_value_get_flags (v) +#define g_marshal_value_peek_float(v) g_value_get_float (v) +#define g_marshal_value_peek_double(v) g_value_get_double (v) +#define g_marshal_value_peek_string(v) (char*) g_value_get_string (v) +#define g_marshal_value_peek_param(v) g_value_get_param (v) +#define g_marshal_value_peek_boxed(v) g_value_get_boxed (v) +#define g_marshal_value_peek_pointer(v) g_value_get_pointer (v) +#define g_marshal_value_peek_object(v) g_value_get_object (v) +#else /* !G_ENABLE_DEBUG */ +/* WARNING: This code accesses GValues directly, which is UNSUPPORTED API. + * Do not access GValues directly in your code. Instead, use the + * g_value_get_*() functions + */ +#define g_marshal_value_peek_boolean(v) (v)->data[0].v_int +#define g_marshal_value_peek_char(v) (v)->data[0].v_int +#define g_marshal_value_peek_uchar(v) (v)->data[0].v_uint +#define g_marshal_value_peek_int(v) (v)->data[0].v_int +#define g_marshal_value_peek_uint(v) (v)->data[0].v_uint +#define g_marshal_value_peek_long(v) (v)->data[0].v_long +#define g_marshal_value_peek_ulong(v) (v)->data[0].v_ulong +#define g_marshal_value_peek_int64(v) (v)->data[0].v_int64 +#define g_marshal_value_peek_uint64(v) (v)->data[0].v_uint64 +#define g_marshal_value_peek_enum(v) (v)->data[0].v_int +#define g_marshal_value_peek_flags(v) (v)->data[0].v_uint +#define g_marshal_value_peek_float(v) (v)->data[0].v_float +#define g_marshal_value_peek_double(v) (v)->data[0].v_double +#define g_marshal_value_peek_string(v) (v)->data[0].v_pointer +#define g_marshal_value_peek_param(v) (v)->data[0].v_pointer +#define g_marshal_value_peek_boxed(v) (v)->data[0].v_pointer +#define g_marshal_value_peek_pointer(v) (v)->data[0].v_pointer +#define g_marshal_value_peek_object(v) (v)->data[0].v_pointer +#endif /* !G_ENABLE_DEBUG */ + + +/* NONE:NONE (sp-marshal.list:2) */ + +/* NONE:UINT (sp-marshal.list:3) */ + +/* NONE:POINTER (sp-marshal.list:4) */ + +/* NONE:POINTER,BOOLEAN (sp-marshal.list:5) */ +void +sp_marshal_VOID__POINTER_BOOLEAN (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data) +{ + typedef void (*GMarshalFunc_VOID__POINTER_BOOLEAN) (gpointer data1, + gpointer arg_1, + gboolean arg_2, + gpointer data2); + register GMarshalFunc_VOID__POINTER_BOOLEAN callback; + register GCClosure *cc = (GCClosure*) closure; + register gpointer data1, data2; + + g_return_if_fail (n_param_values == 3); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__POINTER_BOOLEAN) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + g_marshal_value_peek_pointer (param_values + 1), + g_marshal_value_peek_boolean (param_values + 2), + data2); +} + +/* NONE:POINTER,UINT (sp-marshal.list:6) */ +void +sp_marshal_VOID__POINTER_UINT (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data) +{ + typedef void (*GMarshalFunc_VOID__POINTER_UINT) (gpointer data1, + gpointer arg_1, + guint arg_2, + gpointer data2); + register GMarshalFunc_VOID__POINTER_UINT callback; + register GCClosure *cc = (GCClosure*) closure; + register gpointer data1, data2; + + g_return_if_fail (n_param_values == 3); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__POINTER_UINT) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + g_marshal_value_peek_pointer (param_values + 1), + g_marshal_value_peek_uint (param_values + 2), + data2); +} + +/* NONE:POINTER,DOUBLE (sp-marshal.list:7) */ +void +sp_marshal_VOID__POINTER_DOUBLE (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data) +{ + typedef void (*GMarshalFunc_VOID__POINTER_DOUBLE) (gpointer data1, + gpointer arg_1, + gdouble arg_2, + gpointer data2); + register GMarshalFunc_VOID__POINTER_DOUBLE callback; + register GCClosure *cc = (GCClosure*) closure; + register gpointer data1, data2; + + g_return_if_fail (n_param_values == 3); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__POINTER_DOUBLE) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + g_marshal_value_peek_pointer (param_values + 1), + g_marshal_value_peek_double (param_values + 2), + data2); +} + +/* NONE:DOUBLE,DOUBLE (sp-marshal.list:8) */ +void +sp_marshal_VOID__DOUBLE_DOUBLE (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data) +{ + typedef void (*GMarshalFunc_VOID__DOUBLE_DOUBLE) (gpointer data1, + gdouble arg_1, + gdouble arg_2, + gpointer data2); + register GMarshalFunc_VOID__DOUBLE_DOUBLE callback; + register GCClosure *cc = (GCClosure*) closure; + register gpointer data1, data2; + + g_return_if_fail (n_param_values == 3); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__DOUBLE_DOUBLE) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + g_marshal_value_peek_double (param_values + 1), + g_marshal_value_peek_double (param_values + 2), + data2); +} + +/* NONE:STRING,BOOL (sp-marshal.list:9) */ +void +sp_marshal_VOID__STRING_BOOLEAN (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data) +{ + typedef void (*GMarshalFunc_VOID__STRING_BOOLEAN) (gpointer data1, + gpointer arg_1, + gboolean arg_2, + gpointer data2); + register GMarshalFunc_VOID__STRING_BOOLEAN callback; + register GCClosure *cc = (GCClosure*) closure; + register gpointer data1, data2; + + g_return_if_fail (n_param_values == 3); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__STRING_BOOLEAN) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + g_marshal_value_peek_string (param_values + 1), + g_marshal_value_peek_boolean (param_values + 2), + data2); +} + +/* BOOLEAN:NONE (sp-marshal.list:10) */ +void +sp_marshal_BOOLEAN__VOID (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data) +{ + typedef gboolean (*GMarshalFunc_BOOLEAN__VOID) (gpointer data1, + gpointer data2); + register GMarshalFunc_BOOLEAN__VOID callback; + register GCClosure *cc = (GCClosure*) closure; + register gpointer data1, data2; + gboolean v_return; + + g_return_if_fail (return_value != NULL); + g_return_if_fail (n_param_values == 1); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_BOOLEAN__VOID) (marshal_data ? marshal_data : cc->callback); + + v_return = callback (data1, + data2); + + g_value_set_boolean (return_value, v_return); +} + +/* BOOLEAN:UINT (sp-marshal.list:11) */ +void +sp_marshal_BOOLEAN__UINT (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data) +{ + typedef gboolean (*GMarshalFunc_BOOLEAN__UINT) (gpointer data1, + guint arg_1, + gpointer data2); + register GMarshalFunc_BOOLEAN__UINT callback; + register GCClosure *cc = (GCClosure*) closure; + register gpointer data1, data2; + gboolean v_return; + + g_return_if_fail (return_value != NULL); + g_return_if_fail (n_param_values == 2); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_BOOLEAN__UINT) (marshal_data ? marshal_data : cc->callback); + + v_return = callback (data1, + g_marshal_value_peek_uint (param_values + 1), + data2); + + g_value_set_boolean (return_value, v_return); +} + +/* BOOLEAN:POINTER (sp-marshal.list:12) */ +void +sp_marshal_BOOLEAN__POINTER (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data) +{ + typedef gboolean (*GMarshalFunc_BOOLEAN__POINTER) (gpointer data1, + gpointer arg_1, + gpointer data2); + register GMarshalFunc_BOOLEAN__POINTER callback; + register GCClosure *cc = (GCClosure*) closure; + register gpointer data1, data2; + gboolean v_return; + + g_return_if_fail (return_value != NULL); + g_return_if_fail (n_param_values == 2); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_BOOLEAN__POINTER) (marshal_data ? marshal_data : cc->callback); + + v_return = callback (data1, + g_marshal_value_peek_pointer (param_values + 1), + data2); + + g_value_set_boolean (return_value, v_return); +} + +/* BOOLEAN:POINTER,UINT (sp-marshal.list:13) */ +void +sp_marshal_BOOLEAN__POINTER_UINT (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data) +{ + typedef gboolean (*GMarshalFunc_BOOLEAN__POINTER_UINT) (gpointer data1, + gpointer arg_1, + guint arg_2, + gpointer data2); + register GMarshalFunc_BOOLEAN__POINTER_UINT callback; + register GCClosure *cc = (GCClosure*) closure; + register gpointer data1, data2; + gboolean v_return; + + g_return_if_fail (return_value != NULL); + g_return_if_fail (n_param_values == 3); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_BOOLEAN__POINTER_UINT) (marshal_data ? marshal_data : cc->callback); + + v_return = callback (data1, + g_marshal_value_peek_pointer (param_values + 1), + g_marshal_value_peek_uint (param_values + 2), + data2); + + g_value_set_boolean (return_value, v_return); +} + +/* BOOLEAN:POINTER,POINTER (sp-marshal.list:14) */ +void +sp_marshal_BOOLEAN__POINTER_POINTER (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data) +{ + typedef gboolean (*GMarshalFunc_BOOLEAN__POINTER_POINTER) (gpointer data1, + gpointer arg_1, + gpointer arg_2, + gpointer data2); + register GMarshalFunc_BOOLEAN__POINTER_POINTER callback; + register GCClosure *cc = (GCClosure*) closure; + register gpointer data1, data2; + gboolean v_return; + + g_return_if_fail (return_value != NULL); + g_return_if_fail (n_param_values == 3); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_BOOLEAN__POINTER_POINTER) (marshal_data ? marshal_data : cc->callback); + + v_return = callback (data1, + g_marshal_value_peek_pointer (param_values + 1), + g_marshal_value_peek_pointer (param_values + 2), + data2); + + g_value_set_boolean (return_value, v_return); +} + +/* INT:POINTER,POINTER (sp-marshal.list:15) */ +void +sp_marshal_INT__POINTER_POINTER (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data) +{ + typedef gint (*GMarshalFunc_INT__POINTER_POINTER) (gpointer data1, + gpointer arg_1, + gpointer arg_2, + gpointer data2); + register GMarshalFunc_INT__POINTER_POINTER callback; + register GCClosure *cc = (GCClosure*) closure; + register gpointer data1, data2; + gint v_return; + + g_return_if_fail (return_value != NULL); + g_return_if_fail (n_param_values == 3); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_INT__POINTER_POINTER) (marshal_data ? marshal_data : cc->callback); + + v_return = callback (data1, + g_marshal_value_peek_pointer (param_values + 1), + g_marshal_value_peek_pointer (param_values + 2), + data2); + + g_value_set_int (return_value, v_return); +} + +/* DOUBLE:POINTER,UINT (sp-marshal.list:16) */ +void +sp_marshal_DOUBLE__POINTER_UINT (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data) +{ + typedef gdouble (*GMarshalFunc_DOUBLE__POINTER_UINT) (gpointer data1, + gpointer arg_1, + guint arg_2, + gpointer data2); + register GMarshalFunc_DOUBLE__POINTER_UINT callback; + register GCClosure *cc = (GCClosure*) closure; + register gpointer data1, data2; + gdouble v_return; + + g_return_if_fail (return_value != NULL); + g_return_if_fail (n_param_values == 3); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_DOUBLE__POINTER_UINT) (marshal_data ? marshal_data : cc->callback); + + v_return = callback (data1, + g_marshal_value_peek_pointer (param_values + 1), + g_marshal_value_peek_uint (param_values + 2), + data2); + + g_value_set_double (return_value, v_return); +} + diff --git a/src/helper/sp-marshal.h.mingw b/src/helper/sp-marshal.h.mingw new file mode 100644 index 000000000..9b573c523 --- /dev/null +++ b/src/helper/sp-marshal.h.mingw @@ -0,0 +1,125 @@ + +#ifndef __sp_marshal_MARSHAL_H__ +#define __sp_marshal_MARSHAL_H__ + +#include + +G_BEGIN_DECLS + +/* NONE:NONE (sp-marshal.list:2) */ +#define sp_marshal_VOID__VOID g_cclosure_marshal_VOID__VOID +#define sp_marshal_NONE__NONE sp_marshal_VOID__VOID + +/* NONE:UINT (sp-marshal.list:3) */ +#define sp_marshal_VOID__UINT g_cclosure_marshal_VOID__UINT +#define sp_marshal_NONE__UINT sp_marshal_VOID__UINT + +/* NONE:POINTER (sp-marshal.list:4) */ +#define sp_marshal_VOID__POINTER g_cclosure_marshal_VOID__POINTER +#define sp_marshal_NONE__POINTER sp_marshal_VOID__POINTER + +/* NONE:POINTER,BOOLEAN (sp-marshal.list:5) */ +extern void sp_marshal_VOID__POINTER_BOOLEAN (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); +#define sp_marshal_NONE__POINTER_BOOLEAN sp_marshal_VOID__POINTER_BOOLEAN + +/* NONE:POINTER,UINT (sp-marshal.list:6) */ +extern void sp_marshal_VOID__POINTER_UINT (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); +#define sp_marshal_NONE__POINTER_UINT sp_marshal_VOID__POINTER_UINT + +/* NONE:POINTER,DOUBLE (sp-marshal.list:7) */ +extern void sp_marshal_VOID__POINTER_DOUBLE (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); +#define sp_marshal_NONE__POINTER_DOUBLE sp_marshal_VOID__POINTER_DOUBLE + +/* NONE:DOUBLE,DOUBLE (sp-marshal.list:8) */ +extern void sp_marshal_VOID__DOUBLE_DOUBLE (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); +#define sp_marshal_NONE__DOUBLE_DOUBLE sp_marshal_VOID__DOUBLE_DOUBLE + +/* NONE:STRING,BOOL (sp-marshal.list:9) */ +extern void sp_marshal_VOID__STRING_BOOLEAN (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); +#define sp_marshal_NONE__STRING_BOOL sp_marshal_VOID__STRING_BOOLEAN + +/* BOOLEAN:NONE (sp-marshal.list:10) */ +extern void sp_marshal_BOOLEAN__VOID (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); +#define sp_marshal_BOOLEAN__NONE sp_marshal_BOOLEAN__VOID + +/* BOOLEAN:UINT (sp-marshal.list:11) */ +extern void sp_marshal_BOOLEAN__UINT (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); + +/* BOOLEAN:POINTER (sp-marshal.list:12) */ +extern void sp_marshal_BOOLEAN__POINTER (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); + +/* BOOLEAN:POINTER,UINT (sp-marshal.list:13) */ +extern void sp_marshal_BOOLEAN__POINTER_UINT (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); + +/* BOOLEAN:POINTER,POINTER (sp-marshal.list:14) */ +extern void sp_marshal_BOOLEAN__POINTER_POINTER (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); + +/* INT:POINTER,POINTER (sp-marshal.list:15) */ +extern void sp_marshal_INT__POINTER_POINTER (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); + +/* DOUBLE:POINTER,UINT (sp-marshal.list:16) */ +extern void sp_marshal_DOUBLE__POINTER_UINT (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); + +G_END_DECLS + +#endif /* __sp_marshal_MARSHAL_H__ */ diff --git a/src/helper/sp-marshal.list b/src/helper/sp-marshal.list new file mode 100644 index 000000000..15ddb1ec4 --- /dev/null +++ b/src/helper/sp-marshal.list @@ -0,0 +1,16 @@ +# marshallers for sodipodi +NONE:NONE +NONE:UINT +NONE:POINTER +NONE:POINTER,BOOLEAN +NONE:POINTER,UINT +NONE:POINTER,DOUBLE +NONE:DOUBLE,DOUBLE +NONE:STRING,BOOL +BOOLEAN:NONE +BOOLEAN:UINT +BOOLEAN:POINTER +BOOLEAN:POINTER,UINT +BOOLEAN:POINTER,POINTER +INT:POINTER,POINTER +DOUBLE:POINTER,UINT diff --git a/src/helper/stlport.h b/src/helper/stlport.h new file mode 100644 index 000000000..c9389e814 --- /dev/null +++ b/src/helper/stlport.h @@ -0,0 +1,26 @@ +#ifndef __STL_PORT_H__ +#define __STK_PORT_H__ + + +#include +#include +#include + +template +class StlConv { +public : + static void slist(std::list &stlList, const GSList *slist) { + for (const GSList *l = slist; l != NULL; l = l->next) { + T item = reinterpret_cast(l->data); + stlList.push_back(item); + } + } + static void list(std::list &stlList, const GList *list) { + for (const GList *l = list; l != NULL; l = l->next) { + T item = reinterpret_cast(l->data); + stlList.push_back(item); + } + } +}; + +#endif diff --git a/src/helper/stock-items.cpp b/src/helper/stock-items.cpp new file mode 100644 index 000000000..fe2026043 --- /dev/null +++ b/src/helper/stock-items.cpp @@ -0,0 +1,267 @@ +#define __INK_STOCK_ITEMS__ + +/* + * Stock-items + * + * Stock Item management code + * + * Authors: + * John Cliff + * + * Copyright 2004 John Cliff + * + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#define noSP_SS_VERBOSE + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif +#include "path-prefix.h" + + +#include +#include "sp-gradient-fns.h" +#include "document-private.h" +#include "sp-pattern.h" +#include "sp-marker.h" +#include "desktop-handles.h" +#include "inkscape.h" + +#include "io/sys.h" + + + + +static SPObject *sp_gradient_load_from_svg(gchar const *name, SPDocument *current_doc); +static SPObject *sp_marker_load_from_svg(gchar const *name, SPDocument *current_doc); +static SPObject *sp_gradient_load_from_svg(gchar const *name, SPDocument *current_doc); + + +// FIXME: these should be merged with the icon loading code so they +// can share a common file/doc cache. This function should just +// take the dir to look in, and the file to check for, and cache +// against that, rather than the existing copy/paste code seen here. + +static SPObject * sp_marker_load_from_svg(gchar const *name, SPDocument *current_doc) +{ + static SPDocument *doc = NULL; + static unsigned int edoc = FALSE; + if (!current_doc) { + return NULL; + } + /* Try to load from document */ + if (!edoc && !doc) { + gchar *markers = g_build_filename(INKSCAPE_MARKERSDIR, "/markers.svg", NULL); + if (Inkscape::IO::file_test(markers, G_FILE_TEST_IS_REGULAR)) { + doc = sp_document_new(markers, FALSE); + } + g_free(markers); + if (doc) { + sp_document_ensure_up_to_date(doc); + } else { + edoc = TRUE; + } + } + if (!edoc && doc) { + /* Get the marker we want */ + SPObject *object = doc->getObjectById(name); + if (object && SP_IS_MARKER(object)) { + SPDefs *defs= (SPDefs *) SP_DOCUMENT_DEFS(current_doc); + Inkscape::XML::Node *mark_repr = SP_OBJECT_REPR(object)->duplicate(); + SP_OBJECT_REPR(defs)->addChild(mark_repr, NULL); + SPObject *cloned_item = current_doc->getObjectByRepr(mark_repr); + Inkscape::GC::release(mark_repr); + return cloned_item; + } + } + return NULL; +} + + +static SPObject * +sp_pattern_load_from_svg(gchar const *name, SPDocument *current_doc) +{ + static SPDocument *doc = NULL; + static unsigned int edoc = FALSE; + if (!current_doc) { + return NULL; + } + /* Try to load from document */ + if (!edoc && !doc) { + gchar *patterns = g_build_filename(INKSCAPE_PATTERNSDIR, "/patterns.svg", NULL); + if (Inkscape::IO::file_test(patterns, G_FILE_TEST_IS_REGULAR)) { + doc = sp_document_new(patterns, FALSE); + } + g_free(patterns); + if (doc) { + sp_document_ensure_up_to_date(doc); + } else { + edoc = TRUE; + } + } + if (!edoc && doc) { + /* Get the pattern we want */ + SPObject *object = doc->getObjectById(name); + if (object && SP_IS_PATTERN(object)) { + SPDefs *defs= (SPDefs *) SP_DOCUMENT_DEFS(current_doc); + Inkscape::XML::Node *pat_repr = SP_OBJECT_REPR(object)->duplicate(); + SP_OBJECT_REPR(defs)->addChild(pat_repr, NULL); + Inkscape::GC::release(pat_repr); + return object; + } + } + return NULL; +} + + +static SPObject * +sp_gradient_load_from_svg(gchar const *name, SPDocument *current_doc) +{ + static SPDocument *doc = NULL; + static unsigned int edoc = FALSE; + if (!current_doc) { + return NULL; + } + /* Try to load from document */ + if (!edoc && !doc) { + gchar *gradients = g_build_filename(INKSCAPE_GRADIENTSDIR, "/gradients.svg", NULL); + if (Inkscape::IO::file_test(gradients, G_FILE_TEST_IS_REGULAR)) { + doc = sp_document_new(gradients, FALSE); + } + g_free(gradients); + if (doc) { + sp_document_ensure_up_to_date(doc); + } else { + edoc = TRUE; + } + } + if (!edoc && doc) { + /* Get the gradient we want */ + SPObject *object = doc->getObjectById(name); + if (object && SP_IS_GRADIENT(object)) { + SPDefs *defs= (SPDefs *) SP_DOCUMENT_DEFS(current_doc); + Inkscape::XML::Node *pat_repr = SP_OBJECT_REPR(object)->duplicate(); + SP_OBJECT_REPR(defs)->addChild(pat_repr, NULL); + Inkscape::GC::release(pat_repr); + return object; + } + } + return NULL; +} + +// get_stock_item returns a pointer to an instance of the desired stock object in the current doc +// if necessary it will import the object. Copes with name clashes through use of the inkscape:stockid property +// This should be set to be the same as the id in the libary file. + +SPObject *get_stock_item(gchar const *urn) +{ + g_assert(urn != NULL); + + /* check its an inkscape URN */ + if (!strncmp (urn, "urn:inkscape:", 13)) { + + gchar const *e = urn + 13; + int a = 0; + gchar * name = g_strdup(e); + gchar *name_p = name; + while (*name_p != ':' && *name_p != '\0'){ + name_p++; + a++; + } + + if (*name_p ==':') { + name_p++; + } + + gchar * base = g_strndup(e, a); + + SPDesktop *desktop = inkscape_active_desktop(); + SPDocument *doc = SP_DT_DOCUMENT(desktop); + SPDefs *defs= (SPDefs *) SP_DOCUMENT_DEFS(doc); + + SPObject *object = NULL; + if (!strcmp(base, "marker")) { + for (SPObject *child = sp_object_first_child(SP_OBJECT(defs)); + child != NULL; + child = SP_OBJECT_NEXT(child)) + { + if (SP_OBJECT_REPR(child)->attribute("inkscape:stockid") && + !strcmp(name_p, SP_OBJECT_REPR(child)->attribute("inkscape:stockid")) && + SP_IS_MARKER(child)) + { + object = child; + } + } + + } + else if (!strcmp(base,"pattern")) { + for (SPObject *child = sp_object_first_child(SP_OBJECT(defs)) ; + child != NULL; + child = SP_OBJECT_NEXT(child) ) + { + if (SP_OBJECT_REPR(child)->attribute("inkscape:stockid") && + !strcmp(name_p, SP_OBJECT_REPR(child)->attribute("inkscape:stockid")) && + SP_IS_PATTERN(child)) + { + object = child; + } + } + + } + else if (!strcmp(base,"gradient")) { + for (SPObject *child = sp_object_first_child(SP_OBJECT(defs)); + child != NULL; + child = SP_OBJECT_NEXT(child)) + { + if (SP_OBJECT_REPR(child)->attribute("inkscape:stockid") && + !strcmp(name_p, SP_OBJECT_REPR(child)->attribute("inkscape:stockid")) && + SP_IS_GRADIENT(child)) + { + object = child; + } + } + + } + + if (object == NULL) { + + if (!strcmp(base, "marker")) { + object = sp_marker_load_from_svg(name_p, doc); + } + else if (!strcmp(base, "pattern")) { + object = sp_pattern_load_from_svg(name_p, doc); + } + else if (!strcmp(base, "gradient")) { + object = sp_gradient_load_from_svg(name_p, doc); + } + } + + g_free(base); + g_free(name); + + return object; + } + + else { + + SPDesktop *desktop = inkscape_active_desktop(); + SPDocument *doc = SP_DT_DOCUMENT(desktop); + SPObject *object = doc->getObjectById(urn); + + return object; + } +} + +/* + 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 : diff --git a/src/helper/stock-items.h b/src/helper/stock-items.h new file mode 100644 index 000000000..ddad55415 --- /dev/null +++ b/src/helper/stock-items.h @@ -0,0 +1,20 @@ +#define __INK_STOCK_ITEMS__ + +/* + * Stock-items + * + * Stock Item management code + * + * Authors: + * John Cliff + * + * Copyright 2004 John Cliff + * + */ + +#include + +#include + +SPObject *get_stock_item(gchar const *urn); + diff --git a/src/helper/unit-menu.cpp b/src/helper/unit-menu.cpp new file mode 100644 index 000000000..34a2b6344 --- /dev/null +++ b/src/helper/unit-menu.cpp @@ -0,0 +1,372 @@ +#define __SP_UNIT_MENU_C__ + +/* + * Unit selector with autupdate capability + * + * Authors: + * Lauris Kaplinski + * bulia byak + * + * Copyright (C) 2000-2002 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#define noUNIT_SELECTOR_VERBOSE + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif +#include +#include +#include +#include +#include "helper/sp-marshal.h" +#include "helper/units.h" +#include "unit-menu.h" +#include "widgets/spw-utilities.h" + +struct SPUnitSelector { + GtkHBox box; + + GtkWidget *menu; + + guint bases; + GSList *units; + SPUnit const *unit; + gdouble ctmscale; + guint plural : 1; + guint abbr : 1; + + guint update : 1; + + GSList *adjustments; +}; + +struct SPUnitSelectorClass { + GtkHBoxClass parent_class; + + gboolean (* set_unit)(SPUnitSelector *us, SPUnit const *old, SPUnit const *new_unit); +}; + +enum {SET_UNIT, LAST_SIGNAL}; + +static void sp_unit_selector_class_init(SPUnitSelectorClass *klass); +static void sp_unit_selector_init(SPUnitSelector *selector); +static void sp_unit_selector_finalize(GObject *object); + +static GtkHBoxClass *unit_selector_parent_class; +static guint signals[LAST_SIGNAL] = {0}; + +GtkType +sp_unit_selector_get_type(void) +{ + static GtkType type = 0; + if (!type) { + static GtkTypeInfo const info = { + "SPUnitSelector", + sizeof(SPUnitSelector), + sizeof(SPUnitSelectorClass), + (GtkClassInitFunc) sp_unit_selector_class_init, + (GtkObjectInitFunc) sp_unit_selector_init, + NULL, NULL, NULL + }; + type = gtk_type_unique(GTK_TYPE_HBOX, &info); + } + return type; +} + +static void +sp_unit_selector_class_init(SPUnitSelectorClass *klass) +{ + GObjectClass *object_class; + GtkWidgetClass *widget_class; + + object_class = G_OBJECT_CLASS(klass); + widget_class = GTK_WIDGET_CLASS(klass); + + unit_selector_parent_class = (GtkHBoxClass*)gtk_type_class(GTK_TYPE_HBOX); + + signals[SET_UNIT] = g_signal_new("set_unit", + G_TYPE_FROM_CLASS(klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(SPUnitSelectorClass, set_unit), + NULL, NULL, + sp_marshal_BOOLEAN__POINTER_POINTER, + G_TYPE_BOOLEAN, 2, + G_TYPE_POINTER, G_TYPE_POINTER); + + object_class->finalize = sp_unit_selector_finalize; +} + +static void +sp_unit_selector_init(SPUnitSelector *us) +{ + us->ctmscale = 1.0; + us->abbr = FALSE; + us->plural = TRUE; + + us->menu = gtk_option_menu_new(); + + gtk_widget_show(us->menu); + gtk_box_pack_start(GTK_BOX(us), us->menu, TRUE, TRUE, 0); +} + +static void +sp_unit_selector_finalize(GObject *object) +{ + SPUnitSelector *selector = SP_UNIT_SELECTOR(object); + + if (selector->menu) { + selector->menu = NULL; + } + + while (selector->adjustments) { + gtk_object_unref(GTK_OBJECT(selector->adjustments->data)); + selector->adjustments = g_slist_remove(selector->adjustments, selector->adjustments->data); + } + + if (selector->units) { + sp_unit_free_list(selector->units); + } + + selector->unit = NULL; + + G_OBJECT_CLASS(unit_selector_parent_class)->finalize(object); +} + +GtkWidget * +sp_unit_selector_new(guint bases) +{ + SPUnitSelector *us = (SPUnitSelector*)gtk_type_new(SP_TYPE_UNIT_SELECTOR); + + sp_unit_selector_set_bases(us, bases); + + return (GtkWidget *) us; +} + +void +sp_unit_selector_setsize(GtkWidget *us, guint w, guint h) +{ + gtk_widget_set_size_request(((SPUnitSelector *) us)->menu, w, h); +} + +SPUnit const * +sp_unit_selector_get_unit(SPUnitSelector const *us) +{ + g_return_val_if_fail(us != NULL, NULL); + g_return_val_if_fail(SP_IS_UNIT_SELECTOR(us), NULL); + + return us->unit; +} + +static void +spus_unit_activate(GtkWidget *widget, SPUnitSelector *us) +{ + SPUnit const *unit = (SPUnit const *) gtk_object_get_data(GTK_OBJECT(widget), "unit"); + g_return_if_fail(unit != NULL); + +#ifdef UNIT_SELECTOR_VERBOSE + g_print("Old unit %s new unit %s\n", us->unit->name, unit->name); +#endif + + SPUnit const *old = us->unit; + us->unit = unit; + + us->update = TRUE; + + gboolean consumed = FALSE; + g_signal_emit(G_OBJECT(us), signals[SET_UNIT], 0, old, unit, &consumed); + + if ( !consumed + && ( unit->base == old->base + || ( unit->base == SP_UNIT_ABSOLUTE && old->base == SP_UNIT_DEVICE ) + || ( old->base == SP_UNIT_ABSOLUTE && unit->base == SP_UNIT_DEVICE ) ) ) { + // Either the same base, or absolute<->device: + /* Recalculate adjustments. */ + for (GSList *l = us->adjustments; l != NULL; l = g_slist_next(l)) { + GtkAdjustment *adj = GTK_ADJUSTMENT(l->data); + gdouble val = adj->value; +#ifdef UNIT_SELECTOR_VERBOSE + g_print("Old val %g ... ", val); +#endif + val = sp_convert_distance_full(val, *old, *unit); +#ifdef UNIT_SELECTOR_VERBOSE + g_print("new val %g\n", val); +#endif + adj->value = val; + } + /* need to separate the value changing from the notification + * or else the unit changes can break the calculations */ + for (GSList *l = us->adjustments; l != NULL; l = g_slist_next(l)) { + gtk_adjustment_value_changed(GTK_ADJUSTMENT(l->data)); + } + } else if (!consumed && unit->base != old->base) { + /* when the base changes, signal all the adjustments to get them + * to recalculate */ + for (GSList *l = us->adjustments; l != NULL; l = g_slist_next(l)) { + gtk_signal_emit_by_name(GTK_OBJECT(l->data), "value_changed"); + } + } + + us->update = FALSE; +} + +static void +spus_rebuild_menu(SPUnitSelector *us) +{ + if (GTK_OPTION_MENU(us->menu)->menu) { + gtk_option_menu_remove_menu(GTK_OPTION_MENU(us->menu)); + } + + GtkWidget *m = gtk_menu_new(); + + gtk_widget_show(m); + + gint pos = 0; + gint p = 0; + for (GSList *l = us->units; l != NULL; l = l->next) { + SPUnit const *u = (SPUnit*)l->data; + + // use only abbreviations in the menu + // i = gtk_menu_item_new_with_label((us->abbr) ? (us->plural) ? u->abbr_plural : u->abbr : (us->plural) ? u->plural : u->name); + GtkWidget *i = gtk_menu_item_new_with_label( u->abbr ); + + gtk_object_set_data(GTK_OBJECT(i), "unit", (gpointer) u); + gtk_signal_connect(GTK_OBJECT(i), "activate", GTK_SIGNAL_FUNC(spus_unit_activate), us); + + sp_set_font_size_smaller (i); + + gtk_widget_show(i); + + gtk_menu_shell_append(GTK_MENU_SHELL(m), i); + if (u == us->unit) pos = p; + p += 1; + } + + gtk_option_menu_set_menu(GTK_OPTION_MENU(us->menu), m); + + gtk_option_menu_set_history(GTK_OPTION_MENU(us->menu), pos); +} + +void +sp_unit_selector_set_bases(SPUnitSelector *us, guint bases) +{ + g_return_if_fail(us != NULL); + g_return_if_fail(SP_IS_UNIT_SELECTOR(us)); + + if (bases == us->bases) return; + + GSList *units = sp_unit_get_list(bases); + g_return_if_fail(units != NULL); + sp_unit_free_list(us->units); + us->units = units; + us->unit = (SPUnit*)units->data; + + spus_rebuild_menu(us); +} + +void +sp_unit_selector_add_unit(SPUnitSelector *us, SPUnit const *unit, int position) +{ + if (!g_slist_find(us->units, (gpointer) unit)) { + us->units = g_slist_insert(us->units, (gpointer) unit, position); + + spus_rebuild_menu(us); + } +} + +void +sp_unit_selector_set_unit(SPUnitSelector *us, SPUnit const *unit) +{ + g_return_if_fail(us != NULL); + g_return_if_fail(SP_IS_UNIT_SELECTOR(us)); + + if (unit == NULL) { + return; // silently return, by default a newly created selector uses pt + } + if (unit == us->unit) { + return; + } + + gint const pos = g_slist_index(us->units, (gpointer) unit); + g_return_if_fail(pos >= 0); + + gtk_option_menu_set_history(GTK_OPTION_MENU(us->menu), pos); + + SPUnit const *old = us->unit; + us->unit = unit; + + /* Recalculate adjustments */ + for (GSList *l = us->adjustments; l != NULL; l = l->next) { + GtkAdjustment *adj = GTK_ADJUSTMENT(l->data); + gdouble const val = sp_convert_distance_full(adj->value, *old, *unit); + gtk_adjustment_set_value(adj, val); + } +} + +void +sp_unit_selector_add_adjustment(SPUnitSelector *us, GtkAdjustment *adj) +{ + g_return_if_fail(us != NULL); + g_return_if_fail(SP_IS_UNIT_SELECTOR(us)); + g_return_if_fail(adj != NULL); + g_return_if_fail(GTK_IS_ADJUSTMENT(adj)); + + g_return_if_fail(!g_slist_find(us->adjustments, adj)); + + gtk_object_ref(GTK_OBJECT(adj)); + us->adjustments = g_slist_prepend(us->adjustments, adj); +} + +void +sp_unit_selector_remove_adjustment(SPUnitSelector *us, GtkAdjustment *adj) +{ + g_return_if_fail(us != NULL); + g_return_if_fail(SP_IS_UNIT_SELECTOR(us)); + g_return_if_fail(adj != NULL); + g_return_if_fail(GTK_IS_ADJUSTMENT(adj)); + + g_return_if_fail(g_slist_find(us->adjustments, adj)); + + us->adjustments = g_slist_remove(us->adjustments, adj); + gtk_object_unref(GTK_OBJECT(adj)); +} + +gboolean +sp_unit_selector_update_test(SPUnitSelector const *selector) +{ + g_return_val_if_fail(selector != NULL, FALSE); + g_return_val_if_fail(SP_IS_UNIT_SELECTOR(selector), FALSE); + + return selector->update; +} + +double +sp_unit_selector_get_value_in_pixels(SPUnitSelector const *selector, GtkAdjustment *adj) +{ + g_return_val_if_fail(selector != NULL, adj->value); + g_return_val_if_fail(SP_IS_UNIT_SELECTOR(selector), adj->value); + + return sp_units_get_pixels(adj->value, *(selector->unit)); +} + +void +sp_unit_selector_set_value_in_pixels(SPUnitSelector *selector, GtkAdjustment *adj, double value) +{ + g_return_if_fail(selector != NULL); + g_return_if_fail(SP_IS_UNIT_SELECTOR(selector)); + + gtk_adjustment_set_value(adj, sp_pixels_get_units(value, *(selector->unit))); +} + +/* + 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:textwidth=99 : diff --git a/src/helper/unit-menu.h b/src/helper/unit-menu.h new file mode 100644 index 000000000..bf5bb260e --- /dev/null +++ b/src/helper/unit-menu.h @@ -0,0 +1,59 @@ +#ifndef __SP_UNIT_MENU_H__ +#define __SP_UNIT_MENU_H__ + +/* + * SPUnitMenu + * + * Generic (and quite unintelligent) grid item for gnome canvas + * + * Copyright (C) Lauris Kaplinski 2000 + * + */ + +#include +#include + +#include + + +/* Unit selector Widget */ + +#define SP_TYPE_UNIT_SELECTOR (sp_unit_selector_get_type()) +#define SP_UNIT_SELECTOR(o) (GTK_CHECK_CAST((o), SP_TYPE_UNIT_SELECTOR, SPUnitSelector)) +#define SP_UNIT_SELECTOR_CLASS(k) (GTK_CHECK_CLASS_CAST((k), SP_TYPE_UNIT_SELECTOR, SPUnitSelectorClass)) +#define SP_IS_UNIT_SELECTOR(o) (GTK_CHECK_TYPE((o), SP_TYPE_UNIT_SELECTOR)) +#define SP_IS_UNIT_SELECTOR_CLASS(k) (GTK_CHECK_CLASS_TYPE((k), SP_TYPE_UNIT_SELECTOR)) + +GType sp_unit_selector_get_type(void); + +GtkWidget *sp_unit_selector_new(guint bases); +void sp_unit_selector_setsize(GtkWidget *us, guint w, guint h); + +SPUnit const *sp_unit_selector_get_unit(SPUnitSelector const *selector); + +void sp_unit_selector_set_bases(SPUnitSelector *selector, guint bases); +void sp_unit_selector_add_unit(SPUnitSelector *selector, SPUnit const *unit, int position); + +void sp_unit_selector_set_unit(SPUnitSelector *selector, SPUnit const *unit); +void sp_unit_selector_add_adjustment(SPUnitSelector *selector, GtkAdjustment *adjustment); +void sp_unit_selector_remove_adjustment(SPUnitSelector *selector, GtkAdjustment *adjustment); + +gboolean sp_unit_selector_update_test(SPUnitSelector const *selector); + +double sp_unit_selector_get_value_in_pixels(SPUnitSelector const *selector, GtkAdjustment *adj); +void sp_unit_selector_set_value_in_pixels(SPUnitSelector *selector, GtkAdjustment *adj, double value); + + + +#endif + +/* + 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:textwidth=99 : diff --git a/src/helper/units-test.cpp b/src/helper/units-test.cpp new file mode 100644 index 000000000..1a983fece --- /dev/null +++ b/src/helper/units-test.cpp @@ -0,0 +1,115 @@ +#ifdef HAVE_CONFIG_H +# include +#endif +#include + +#include +#include +#include + + +/* N.B. Wrongly returns false if both near 0. (Not a problem for current users.) */ +static bool +approx_equal(double const x, double const y) +{ + return fabs(x / y - 1) < 1e-15; +} + +static double +sp_units_get_points(double const x, SPUnit const &unit) +{ + SPUnit const &pt_unit = sp_unit_get_by_id(SP_UNIT_PT); + double const px = sp_units_get_pixels(x, unit); + return sp_pixels_get_units(px, pt_unit); +} + +static double +sp_points_get_units(double const pts, SPUnit const &unit) +{ + SPUnit const &pt_unit = sp_unit_get_by_id(SP_UNIT_PT); + double const px = sp_units_get_pixels(pts, pt_unit); + return sp_pixels_get_units(px, unit); +} + +static bool +test_conversions() +{ + utest_start("sp_units_get_pixels, sp_pixels_get_units"); + + struct Case { double x; char const *abbr; double pts; } const tests[] = { + { 1.0, "pt", 1.0 }, + { 5.0, "pt", 5.0 }, + { 1.0, "in", 72.0 }, + { 2.0, "in", 144.0 }, + { 254., "mm", 720.0 }, + { 254., "cm", 7200. }, + { 254., "m", 720000. }, + { 1.5, "mm", (15 * 72. / 254) } + }; + for (unsigned i = 0; i < G_N_ELEMENTS(tests); ++i) { + char name[80]; + Case const &c = tests[i]; + SPUnit const &unit = *sp_unit_get_by_abbreviation(N_(c.abbr)); + + double const calc_pts = sp_units_get_points(c.x, unit); + snprintf(name, sizeof(name), "%.1f %s -> %.1f pt", c.x, c.abbr, c.pts); + UTEST_TEST(name) { + UTEST_ASSERT(approx_equal(calc_pts, c.pts)); + } + + double const calc_x = sp_points_get_units(c.pts, unit); + snprintf(name, sizeof(name), "%.1f pt -> %.1f %s", c.pts, c.x, c.abbr); + UTEST_TEST(name) { + UTEST_ASSERT(approx_equal(calc_x, c.x)); + } + + double tmp = c.x; + bool const converted_to_pts = sp_convert_distance(&tmp, &unit, SP_PS_UNIT); + snprintf(name, sizeof(name), "convert %.1f %s -> %.1f pt", c.x, c.abbr, c.pts); + UTEST_TEST(name) { + UTEST_ASSERT(converted_to_pts); + UTEST_ASSERT(approx_equal(tmp, c.pts)); + } + + tmp = c.pts; + bool const converted_from_pts = sp_convert_distance(&tmp, SP_PS_UNIT, &unit); + snprintf(name, sizeof(name), "convert %.1f pt -> %.1f %s", c.pts, c.x, c.abbr); + UTEST_TEST(name) { + UTEST_ASSERT(converted_from_pts); + UTEST_ASSERT(approx_equal(tmp, c.x)); + } + } + return utest_end(); +} + +static bool +test_unit_table() +{ + utest_start("unit table"); + UTEST_TEST("sp_units_table_sane") { + UTEST_ASSERT(sp_units_table_sane()); + } + return utest_end(); +} + +int +main(int argc, char *argv[]) +{ + int const ret = ( ( test_conversions() + && test_unit_table() ) + ? EXIT_SUCCESS + : EXIT_FAILURE ); + return ret; +} + + +/* + 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 : diff --git a/src/helper/units.cpp b/src/helper/units.cpp new file mode 100644 index 000000000..448f60302 --- /dev/null +++ b/src/helper/units.cpp @@ -0,0 +1,260 @@ +#define __SP_PAPER_C__ + +/* + * SPUnit + * + * Ported from libgnomeprint + * + * Authors: + * Dirk Luetjens + * Yves Arrouye + * Lauris Kaplinski + * bulia byak + * + * Copyright 1999-2001 Ximian, Inc. and authors + * + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "helper/units.h" +#include +#include "unit-constants.h" +#include "svg/svg-length.h" + +/* todo: use some fancy unit program */ + +/* The order determines the order of the list returned by sp_unit_get_list. + * (It can also affect string lookups if there are any duplicates in the + * current locale... hopefully none.) If you re-order this list, then you must + * also re-order the SPUnitId enum values accordingly. Run `make check' (which + * calls sp_unit_table_sane) to ensure that the two are in sync. + */ +SPUnit const sp_units[] = { + {SP_UNIT_SCALE, SP_UNIT_DIMENSIONLESS, 1.0, NONE, SVGLength::NONE, N_("Unit"), "", N_("Units"), ""}, + {SP_UNIT_PT, SP_UNIT_ABSOLUTE, PX_PER_PT, SP_PT, SVGLength::PT, N_("Point"), N_("pt"), N_("Points"), N_("Pt")}, + {SP_UNIT_PX, SP_UNIT_DEVICE, PX_PER_PX, SP_PX, SVGLength::PX, N_("Pixel"), N_("px"), N_("Pixels"), N_("Px")}, + /* You can add new elements from this point forward */ + {SP_UNIT_PERCENT, SP_UNIT_DIMENSIONLESS, 0.01, NONE, SVGLength::PERCENT, N_("Percent"), N_("%"), N_("Percents"), N_("%")}, + {SP_UNIT_MM, SP_UNIT_ABSOLUTE, PX_PER_MM, SP_MM, SVGLength::MM, N_("Millimeter"), N_("mm"), N_("Millimeters"), N_("mm")}, + {SP_UNIT_CM, SP_UNIT_ABSOLUTE, PX_PER_CM, SP_CM, SVGLength::CM, N_("Centimeter"), N_("cm"), N_("Centimeters"), N_("cm")}, + {SP_UNIT_M, SP_UNIT_ABSOLUTE, PX_PER_M, SP_M, SVGLength::NONE, N_("Meter"), N_("m"), N_("Meters"), N_("m")}, // no svg_unit + {SP_UNIT_IN, SP_UNIT_ABSOLUTE, PX_PER_IN, SP_IN, SVGLength::INCH, N_("Inch"), N_("in"), N_("Inches"), N_("in")}, + /* Volatiles do not have default, so there are none here */ + // TRANSLATORS: for info, see http://www.w3.org/TR/REC-CSS2/syndata.html#length-units + {SP_UNIT_EM, SP_UNIT_VOLATILE, 1.0, NONE, SVGLength::EM, N_("Em square"), N_("em"), N_("Em squares"), N_("em")}, + // TRANSLATORS: for info, see http://www.w3.org/TR/REC-CSS2/syndata.html#length-units + {SP_UNIT_EX, SP_UNIT_VOLATILE, 1.0, NONE, SVGLength::EX, N_("Ex square"), N_("ex"), N_("Ex squares"), N_("ex")}, +}; + +#define sp_num_units G_N_ELEMENTS(sp_units) + +SPUnit const * +sp_unit_get_by_abbreviation(gchar const *abbreviation) +{ + g_return_val_if_fail(abbreviation != NULL, NULL); + + for (unsigned i = 0 ; i < sp_num_units ; i++) { + if (!g_strcasecmp(abbreviation, sp_units[i].abbr)) return &sp_units[i]; + if (!g_strcasecmp(abbreviation, sp_units[i].abbr_plural)) return &sp_units[i]; + } + + return NULL; +} + +gchar const * +sp_unit_get_abbreviation(SPUnit const *unit) +{ + g_return_val_if_fail(unit != NULL, NULL); + + return unit->abbr; +} + +gchar const * +sp_unit_get_plural (SPUnit const *unit) +{ + g_return_val_if_fail(unit != NULL, NULL); + + return unit->plural; +} + +SPMetric +sp_unit_get_metric(SPUnit const *unit) +{ + g_return_val_if_fail(unit != NULL, NONE); + + return unit->metric; +} + +guint +sp_unit_get_svg_unit(SPUnit const *unit) +{ + g_return_val_if_fail(unit != NULL, NONE); + + return unit->svg_unit; +} + +GSList * +sp_unit_get_list(guint bases) +{ + g_return_val_if_fail((bases & ~SP_UNITS_ALL) == 0, NULL); + + GSList *units = NULL; + for (unsigned i = sp_num_units ; i--; ) { + if (bases & sp_units[i].base) { + units = g_slist_prepend(units, (gpointer) &sp_units[i]); + } + } + + return units; +} + +void +sp_unit_free_list(GSList *units) +{ + g_slist_free(units); +} + +/* These are pure utility */ +/* Return TRUE if conversion is possible */ +gboolean +sp_convert_distance(gdouble *distance, SPUnit const *from, SPUnit const *to) +{ + g_return_val_if_fail(distance != NULL, FALSE); + g_return_val_if_fail(from != NULL, FALSE); + g_return_val_if_fail(to != NULL, FALSE); + + if (from == to) return TRUE; + if ((from->base == SP_UNIT_DIMENSIONLESS) || (to->base == SP_UNIT_DIMENSIONLESS)) { + *distance = *distance * from->unittobase / to->unittobase; + return TRUE; + } + if ((from->base == SP_UNIT_VOLATILE) || (to->base == SP_UNIT_VOLATILE)) return FALSE; + + if ((from->base == to->base) + || (from->base == SP_UNIT_DEVICE) && (to->base == SP_UNIT_ABSOLUTE) + || (from->base == SP_UNIT_ABSOLUTE) && (to->base == SP_UNIT_DEVICE)) + { + *distance = *distance * from->unittobase / to->unittobase; + return TRUE; + } + + return FALSE; +} + +/** @param devicetransform for device units. */ +/* TODO: Remove the ctmscale parameter given that we no longer have SP_UNIT_USERSPACE. */ +gdouble +sp_convert_distance_full(gdouble const from_dist, SPUnit const &from, SPUnit const &to) +{ + if (&from == &to) { + return from_dist; + } + if (from.base == to.base) { + gdouble ret = from_dist; + bool const succ = sp_convert_distance(&ret, &from, &to); + g_assert(succ); + return ret; + } + if ((from.base == SP_UNIT_DIMENSIONLESS) + || (to.base == SP_UNIT_DIMENSIONLESS)) + { + return from_dist * from.unittobase / to.unittobase; + } + g_return_val_if_fail(((from.base != SP_UNIT_VOLATILE) + && (to.base != SP_UNIT_VOLATILE)), + from_dist); + + gdouble absolute; + switch (from.base) { + case SP_UNIT_ABSOLUTE: + case SP_UNIT_DEVICE: + absolute = from_dist * from.unittobase; + break; + default: + g_warning("file %s: line %d: Illegal unit (base 0x%x)", __FILE__, __LINE__, from.base); + return from_dist; + } + + gdouble ret; + switch (to.base) { + default: + g_warning("file %s: line %d: Illegal unit (base 0x%x)", __FILE__, __LINE__, to.base); + /* FALL-THROUGH */ + case SP_UNIT_ABSOLUTE: + case SP_UNIT_DEVICE: + ret = absolute / to.unittobase; + break; + } + + return ret; +} + +/* Some more convenience */ + +gdouble +sp_units_get_pixels(gdouble const units, SPUnit const &unit) +{ + if (unit.base == SP_UNIT_ABSOLUTE || unit.base == SP_UNIT_DEVICE) { + return units * unit.unittobase; + } else { + g_warning("Different unit bases: No exact unit conversion available"); + return units * unit.unittobase; + } +} + +gdouble +sp_pixels_get_units(gdouble const pixels, SPUnit const &unit) +{ + if (unit.base == SP_UNIT_ABSOLUTE || unit.base == SP_UNIT_DEVICE) { + return pixels / unit.unittobase; + } else { + g_warning("Different unit bases: No exact unit conversion available"); + return pixels / unit.unittobase; + } +} + +bool +sp_units_table_sane() +{ + for (unsigned i = 0; i < G_N_ELEMENTS(sp_units); ++i) { + if (unsigned(sp_units[i].unit_id) != i) { + return false; + } + } + return true; +} + +/** Converts angle (in deg) to compass display */ +double +angle_to_compass(double angle) +{ + double ret = 90 - angle; + if (ret < 0) + ret = 360 + ret; + return ret; +} + +/** Converts angle (in deg) to compass display */ +double +angle_from_compass(double angle) +{ + double ret = 90 - angle; + if (ret > 180) + ret = ret - 180; + return ret; +} + + +/* + 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:textwidth=99 : diff --git a/src/helper/units.h b/src/helper/units.h new file mode 100644 index 000000000..3acb65828 --- /dev/null +++ b/src/helper/units.h @@ -0,0 +1,146 @@ +#ifndef __SP_UNIT_H__ +#define __SP_UNIT_H__ + +/* + * SPUnit + * + * Ported from libgnomeprint + * + * Authors: + * Dirk Luetjens + * Yves Arrouye + * Lauris Kaplinski + * + * Copyright 1999-2001 Ximian, Inc. and authors + * + */ + +#include +#include +#include +#include "sp-metric.h" + + +/* + * Units and conversion methods used by libgnomeprint. + * + * You need those for certain config keys (like paper size), if you are + * interested in using these (look at gnome-print-config.h for discussion, + * why you may NOT be interested in paper size). + * + * Unit bases define set of mutually unrelated measuring systems (numbers, + * paper, screen and dimesionless user coordinates). Still, you can convert + * between those, specifying scaling factors explicitly. + * + * Paper (i.e. output) coordinates are taken as absolute real world units. + * It has some justification, because screen unit (pixel) size changes, + * if you change screen resolution, while you cannot change output on paper + * as easily (unless you have thermally contracting paper, of course). + * + */ + +struct SPUnit; +struct SPDistance; + +/* + * The base linear ("absolute") unit is 1/72th of an inch, i.e. the base unit of postscript. + */ + +/* + * Unit bases + */ +enum SPUnitBase { + SP_UNIT_DIMENSIONLESS = (1 << 0), /* For percentages and like */ + SP_UNIT_ABSOLUTE = (1 << 1), /* Real world distances - i.e. mm, cm... */ + SP_UNIT_DEVICE = (1 << 2), /* Pixels in the SVG/CSS sense. */ + SP_UNIT_VOLATILE = (1 << 3) /* em and ex */ +}; + +/* + * Units: indexes into sp_units. + */ +enum SPUnitId { + SP_UNIT_SCALE, // 1.0 == 100% + SP_UNIT_PT, // Postscript points: exactly 72 per inch + SP_UNIT_PX, // "Pixels" in the CSS sense; though Inkscape assumes a constant 90 per inch. + SP_UNIT_PERCENT, /* Note: In Inkscape this often means "relative to current value" (for + users to edit a value), rather than the SVG/CSS use of percentages. */ + SP_UNIT_MM, // millimetres + SP_UNIT_CM, // centimetres + SP_UNIT_M, // metres + SP_UNIT_IN, // inches + SP_UNIT_EM, // font-size of relevant font + SP_UNIT_EX, // x-height of relevant font + sp_max_unit_id = SP_UNIT_EX // For bounds-checking in sp_unit_get_by_id. +}; + +/* + * Notice, that for correct menus etc. you have to use + * ngettext method family yourself. For that reason we + * do not provide translations in unit names. + * I also do not know, whether to allow user-created units, + * because this would certainly confuse textdomain. + */ + +struct SPUnit { + SPUnitId unit_id; /* used as sanity check */ + SPUnitBase base; + gdouble unittobase; /* how many base units in this unit */ + SPMetric metric; // the corresponding SPMetric from sp-metrics.h + guint svg_unit; // the corresponding SVGLengthUnit + + /* When using, you must call "gettext" on them so they're translated */ + gchar const *name; + gchar const *abbr; + gchar const *plural; + gchar const *abbr_plural; +}; + +const SPUnit *sp_unit_get_by_abbreviation (const gchar *abbreviation); +/* When using, you must call "gettext" on them so they're translated */ +const gchar *sp_unit_get_abbreviation (const SPUnit *unit); +gchar const *sp_unit_get_plural (SPUnit const *unit); + +SPMetric sp_unit_get_metric(SPUnit const *unit); +guint sp_unit_get_svg_unit(SPUnit const *unit); + +extern SPUnit const sp_units[]; + +inline SPUnit const & +sp_unit_get_by_id(SPUnitId const id) +{ + /* inline because the compiler should optimize away the g_return_val_if_fail test in the + usual case that the argument value is known at compile-time, leaving just + "return sp_units[constant]". */ + unsigned const ix = unsigned(id); + g_return_val_if_fail(ix <= sp_max_unit_id, sp_units[SP_UNIT_PX]); + return sp_units[ix]; +} + +#define SP_PS_UNIT (&sp_unit_get_by_id(SP_UNIT_PT)) + + +/** Used solely by units-test.cpp. */ +bool sp_units_table_sane(); + +#define SP_UNITS_ALL (SP_UNIT_DIMENSIONLESS | SP_UNIT_ABSOLUTE | SP_UNIT_DEVICE | SP_UNIT_VOLATILE) + +GSList *sp_unit_get_list (guint bases); +void sp_unit_free_list (GSList *units); + +/* These are pure utility */ +/* Return TRUE if conversion is possible, FALSE if unit bases differ */ +gboolean sp_convert_distance (gdouble *distance, const SPUnit *from, const SPUnit *to); + +/* If either one is NULL, transconverting to/from that base fails */ +/* Generic conversion between volatile units would be useless anyways */ +gdouble sp_convert_distance_full(gdouble const from_dist, SPUnit const &from, SPUnit const &to); + +/* Some more convenience */ +gdouble sp_units_get_pixels(gdouble const units, SPUnit const &unit); +gdouble sp_pixels_get_units(gdouble const pixels, SPUnit const &unit); + +double angle_to_compass(double angle); +double angle_from_compass(double angle); + +#endif diff --git a/src/helper/window.cpp b/src/helper/window.cpp new file mode 100644 index 000000000..346bd19f1 --- /dev/null +++ b/src/helper/window.cpp @@ -0,0 +1,47 @@ +#define __SP_WINDOW_C__ + +/* + * Generic window implementation + * + * Author: + * Lauris Kaplinski + * + * This code is in public domain + */ + +#ifdef HAVE_CONFIG_H +# include +#endif +#include + +#include "inkscape.h" +#include "shortcuts.h" +#include "desktop.h" +#include "event-context.h" + +static gboolean +sp_window_key_press (GtkWidget *widget, GdkEventKey *event) +{ + unsigned int shortcut; + shortcut = get_group0_keyval (event) | + ( event->state & GDK_SHIFT_MASK ? + SP_SHORTCUT_SHIFT_MASK : 0 ) | + ( event->state & GDK_CONTROL_MASK ? + SP_SHORTCUT_CONTROL_MASK : 0 ) | + ( event->state & GDK_MOD1_MASK ? + SP_SHORTCUT_ALT_MASK : 0 ); + return sp_shortcut_invoke (shortcut, SP_ACTIVE_DESKTOP); +} + +GtkWidget * +sp_window_new (const gchar *title, unsigned int resizeable) +{ + GtkWidget *window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_window_set_title ((GtkWindow *) window, title); + gtk_window_set_resizable ((GtkWindow *) window, resizeable); + g_signal_connect_after ((GObject *) window, "key_press_event", (GCallback) sp_window_key_press, NULL); + + return window; +} + + diff --git a/src/helper/window.h b/src/helper/window.h new file mode 100644 index 000000000..764cb0413 --- /dev/null +++ b/src/helper/window.h @@ -0,0 +1,28 @@ +#ifndef __SP_WINDOW_H__ +#define __SP_WINDOW_H__ + +/* + * Generic window implementation + * + * Author: + * Lauris Kaplinski + * + * This code is in public domain + */ + +#include + +GtkWidget *sp_window_new (const gchar *title, unsigned int resizeable); + +#endif + +/* + 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:textwidth=99 : diff --git a/src/inkjar/.cvsignore b/src/inkjar/.cvsignore new file mode 100644 index 000000000..e8014d011 --- /dev/null +++ b/src/inkjar/.cvsignore @@ -0,0 +1,5 @@ +Makefile +Makefile.in +.deps +makefile +.dirstamp diff --git a/src/inkjar/Makefile_insert b/src/inkjar/Makefile_insert new file mode 100644 index 000000000..0376015fa --- /dev/null +++ b/src/inkjar/Makefile_insert @@ -0,0 +1,10 @@ +## Makefile.am fragment sourced by src/Makefile.am. + +inkjar/all: inkjar/libinkjar.a + +inkjar/clean: + rm -f inkjar/libinkjar.a $(inkjar_libinkjar_OBJECTS) + +inkjar_libinkjar_a_SOURCES = \ + inkjar/jar.cpp \ + inkjar/jar.h diff --git a/src/inkjar/jar.cpp b/src/inkjar/jar.cpp new file mode 100644 index 000000000..655f11cbb --- /dev/null +++ b/src/inkjar/jar.cpp @@ -0,0 +1,541 @@ +/* + * Copyright (C) 1999, 2000 Bryan Burns + * Copyright (C) 2004 Johan Ceuppens + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +/* + * TODO/FIXME: + * - configure #ifdefs should be enabled + * - move to cstdlib instead of stdlib.h etc. + * - remove exit functions + * - move to clean C++ code + * - windowsify + * - remove a few g_free/g_mallocs + * - unseekable files + * - move to LGPL by rewriting macros + * - crcs for compressed files + * - put in eof + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + + +//#ifdef STDC_HEADERS +//#endif + +//#ifdef HAVE_UNISTD_H +//#endif + +//#ifdef HAVE_SYS_PARAM_H +//#else +//#define MAXPATHLEN 1024 +//#endif + +//#ifdef HAVE_DIRENT_H +//#endif + +//#ifdef HAVE_FCNTL_H +#include +//#endif + + +#include + +#include "jar.h" + +#include +#ifdef WORDS_BIGENDIAN + +#define L2BI(l) ((l & 0xff000000) >> 24) | \ +((l & 0x00ff0000) >> 8) | \ +((l & 0x0000ff00) << 8) | \ +((l & 0x000000ff) << 24); + +#define L2BS(l) ((l & 0xff00) >> 8) | ((l & 0x00ff) << 8); + +#endif + +namespace Inkjar { + +JarFile::JarFile(gchar const*new_filename) +{ + _filename = strdup(new_filename); + _last_filename = NULL; + fd = -1; +} + +//fixme: the following should probably just return a const gchar* and not +// use strdup +gchar *JarFile::get_last_filename() const +{ + return (_last_filename != NULL ? strdup(_last_filename) : NULL); +} + +JarFile::~JarFile() +{ + if (_filename != NULL) + g_free(_filename); + if (_last_filename != NULL) + g_free(_last_filename); +} + +bool JarFile::init_inflation() +{ + memset(&_zs, 0, sizeof(z_stream)); + + _zs.zalloc = Z_NULL; + _zs.zfree = Z_NULL; + _zs.opaque = Z_NULL; + + if(inflateInit2(&_zs, -15) != Z_OK) { + fprintf(stderr,"error initializing inflation!\n"); + return false; + } + + return true; +} + +bool JarFile::open() +{ + if ((fd = ::open(_filename, O_RDONLY)) < 0) { + fprintf(stderr, "open failed.\n"); + return false; + } + if (!init_inflation()) + return false; + + return true; +} + +bool JarFile::close() +{ + if (fd >= 0 && !::close(fd)) { + inflateEnd(&_zs); + return true; + } + return false; +} + +bool JarFile::read_signature() +{ + guint8 *bytes = (guint8 *)g_malloc(sizeof(guint8) * 4); + if (!read(bytes, 4)) { + g_free(bytes); + return false; + } + + guint32 signature = UNPACK_UB4(bytes, 0); + g_free(bytes); + +#ifdef DEBUG + std::printf("signature is %x\n", signature); +#endif + + if (signature == 0x08074b50) { + //skip data descriptor + bytes = (guint8 *)malloc(sizeof(guint8) * 12); + if (!read(bytes, 12)) { + g_free(bytes); + return false; + } + } else if (signature == 0x02014b50 || signature == 0x04034b50) { + return true; + } else { + return false; + } + return false; +} + +guint32 JarFile::get_crc(guint8 *bytes, guint16 flags) +{ + guint32 crc = 0; + //no data descriptor + if (!(flags & 0x0008)) { + crc = UNPACK_UB4(bytes, LOC_CRC); + +#ifdef DEBUG + std::printf("CRC from file is %x\n", crc); +#endif + } + + return crc; +} + +guint8 *JarFile::read_filename(guint16 filename_length) +{ + guint8 *filename = (guint8 *)g_malloc(sizeof(guint8) + * (filename_length+1)); + if (!read(filename, filename_length)) { + g_free(filename); + return NULL; + } + filename[filename_length] = '\0'; + +#ifdef DEBUG + std::printf("Filename is %s\n", filename); +#endif + + return filename; +} + +bool JarFile::check_compression_method(guint16 method, guint16 flags) +{ + return !(method != 8 && flags & 0x0008); +} + +GByteArray *JarFile::get_next_file_contents() +{ + guint8 *bytes; + GByteArray *gba = g_byte_array_new(); + + read_signature(); + + //get compressed size + bytes = (guint8 *)g_malloc(sizeof(guint8) * 30); + if (!read(bytes+4, 26)) { + g_free(bytes); + return NULL; + } + guint32 compressed_size = UNPACK_UB4(bytes, LOC_CSIZE); + guint16 filename_length = UNPACK_UB2(bytes, LOC_FNLEN); + guint16 eflen = UNPACK_UB2(bytes, LOC_EFLEN); + guint16 flags = UNPACK_UB2(bytes, LOC_EXTRA); + guint16 method = UNPACK_UB2(bytes, LOC_COMP); + + if (filename_length == 0) { + g_byte_array_free(gba, TRUE); + if (_last_filename != NULL) + g_free(_last_filename); + _last_filename = NULL; + return NULL; + } + + +#ifdef DEBUG + std::printf("Compressed size is %u\n", compressed_size); + std::printf("Filename length is %hu\n", filename_length); + std::printf("Extra field length is %hu\n", eflen); + std::printf("Flags are %#hx\n", flags); + std::printf("Compression method is %#hx\n", method); +#endif + + guint32 crc = get_crc(bytes, flags); + + gchar *filename = (gchar *)read_filename(filename_length); + g_free(bytes); + + if (filename == NULL) + return NULL; + + if (_last_filename != NULL) + g_free(_last_filename); + _last_filename = filename; + + //check if this is a directory and skip + + char *c_ptr; + if ((c_ptr = std::strrchr(filename, '/')) != NULL) { + if (*(++c_ptr) == '\0') { + return NULL; + } + } + + if (!check_compression_method(method, flags)) { + std::fprintf(stderr, "error in jar file\n"); + return NULL; + } + + if (method == 8 || flags & 0x0008) { + unsigned int file_length = 0;//uncompressed file length + lseek(fd, eflen, SEEK_CUR); + guint8 *file_data = get_compressed_file(compressed_size, file_length, + crc, flags); + if (file_data == NULL) { + g_byte_array_free(gba, FALSE); + return NULL; + } + g_byte_array_append(gba, file_data, file_length); + } else if (method == 0) { + guint8 *file_data = get_uncompressed_file(compressed_size, crc, + eflen, flags); + + if (file_data == NULL) { + g_byte_array_free(gba, TRUE); + return NULL; + } + g_byte_array_append(gba, file_data, compressed_size); + } else { + lseek(fd, compressed_size+eflen, SEEK_CUR); + g_byte_array_free(gba, FALSE); + return NULL; + } + + + return gba; +} + +guint8 *JarFile::get_uncompressed_file(guint32 compressed_size, guint32 crc, + guint16 eflen, guint16 flags) +{ + GByteArray *gba = g_byte_array_new(); + unsigned int out_a = 0; + unsigned int in_a = compressed_size; + guint8 *bytes; + guint32 crc2 = 0; + + crc2 = crc32(crc2, NULL, 0); + + bytes = (guint8 *)g_malloc(sizeof(guint8) * RDSZ); + while(out_a < compressed_size){ + unsigned int nbytes = (in_a > RDSZ ? RDSZ : in_a); + + if (!(nbytes = read(bytes, nbytes))) { + g_free(bytes); + return NULL; + } + + crc2 = crc32(crc2, (Bytef*)bytes, nbytes); + + g_byte_array_append (gba, bytes, nbytes); + out_a += nbytes; + in_a -= nbytes; + +#ifdef DEBUG + std::printf("%d bytes written\n", out_a); +#endif + } + lseek(fd, eflen, SEEK_CUR); + g_free(bytes); + + if (!check_crc(crc, crc2, flags)) { + bytes = gba->data; + g_byte_array_free(gba, FALSE);//FALSE argument does not free actual data + return NULL; + } + + return bytes; +} + +int JarFile::read(guint8 *buf, int count) +{ + int nbytes; + if ((nbytes = ::read(fd, buf, count)) != count) { + fprintf(stderr, "read error\n"); + exit(1); + return 0; + } + return nbytes; +} + +/* FIXME: this could probably use ZlibBuffer */ +guint8 *JarFile::get_compressed_file(guint32 compressed_size, + unsigned int& file_length, + guint32 oldcrc, guint16 flags) +{ + if (compressed_size == 0) + return NULL; + + guint8 in_buffer[RDSZ]; + guint8 out_buffer[RDSZ]; + int nbytes; + unsigned int leftover_in = compressed_size; + GByteArray *gba = g_byte_array_new(); + + _zs.avail_in = 0; + guint32 crc = crc32(0, Z_NULL, 0); + + do { + + if (!_zs.avail_in) { + + if ((nbytes = ::read(fd, in_buffer, + (leftover_in < RDSZ ? leftover_in : RDSZ))) + < 0) { + fprintf(stderr, "jarfile read error"); + } + _zs.avail_in = nbytes; + _zs.next_in = in_buffer; + crc = crc32(crc, in_buffer, _zs.avail_in); + leftover_in -= RDSZ; + } + _zs.next_out = out_buffer; + _zs.avail_out = RDSZ; + + int ret = inflate(&_zs, Z_NO_FLUSH); + if (RDSZ != _zs.avail_out) { + unsigned int tmp_len = RDSZ - _zs.avail_out; + guint8 *tmp_bytes = (guint8 *)g_malloc(sizeof(guint8) + * tmp_len); + memcpy(tmp_bytes, out_buffer, tmp_len); + g_byte_array_append(gba, tmp_bytes, tmp_len); + } + + if (ret == Z_STREAM_END) { + break; + } + if (ret != Z_OK) + std::printf("decompression error %d\n", ret); + } while (_zs.total_in < compressed_size); + + file_length = _zs.total_out; +#ifdef DEBUG + std::printf("done inflating\n"); + std::printf("%d bytes left over\n", _zs.avail_in); + std::printf("CRC is %x\n", crc); +#endif + + guint8 *ret_bytes; + if (check_crc(oldcrc, crc, flags) && gba->len > 0) + ret_bytes = gba->data; + else + ret_bytes = NULL; + g_byte_array_free(gba, FALSE); + + inflateReset(&_zs); + return ret_bytes; +} + +bool JarFile::check_crc(guint32 oldcrc, guint32 crc, guint16 flags) +{ + //fixme: does not work yet + + if(flags & 0x0008) { + guint8 *bytes = (guint8 *)g_malloc(sizeof(guint8) * 16); + if (!read(bytes, 16)) { + g_free(bytes); + return false; + } + + guint32 signature = UNPACK_UB4(bytes, 0); + g_free(bytes); + if(signature != 0x08074b50) { + fprintf(stderr, "missing data descriptor!\n"); + } + + crc = UNPACK_UB4(bytes, 4); + + } + if (oldcrc != crc) { +#ifdef DEBUG + std::fprintf(stderr, "Error! CRCs do not match! Got %x, expected %x\n", + oldcrc, crc); +#endif + } + return true; +} + +JarFile::JarFile(JarFile const& rhs) +{ + *this = rhs; +} + +JarFile& JarFile::operator=(JarFile const& rhs) +{ + if (this == &rhs) + return *this; + + _zs = rhs._zs;//fixme + if (_filename == NULL) + _filename = NULL; + else + _filename = strdup(rhs._filename); + if (_last_filename == NULL) + _last_filename = NULL; + else + _last_filename = strdup(rhs._last_filename); + fd = rhs.fd; + + return *this; +} + + +///////////////////////// +// JarFileReader // +///////////////////////// + +GByteArray *JarFileReader::get_next_file() +{ + if (_state == CLOSED) { + _jarfile.open(); + _state = OPEN; + } + + return _jarfile.get_next_file_contents(); +} + +JarFileReader& JarFileReader::operator=(JarFileReader const& rhs) +{ + if (&rhs == this) + return *this; + + _jarfile = rhs._jarfile; + _state = rhs._state; + + return *this; +} + +/* + * If the filename gets reset, a jarfile object gets generated again, + * ready to be opened for reading. + */ +void JarFileReader::set_filename(gchar const *new_filename) +{ + _jarfile.close(); + _jarfile = JarFile(new_filename); +} + +void JarFileReader::set_jarfile(JarFile const& new_jarfile) +{ + _jarfile = new_jarfile; +} + +JarFileReader::JarFileReader(JarFileReader const& rhs) +{ + *this = rhs; +} + +} // namespace Inkjar + + +#if 0 //testing code +#include "jar.h" +/* + * This program writes all the files from a jarfile to stdout and inflates + * where needed. + */ +int main(int argc, char *argv[]) +{ + gchar *filename; + if (argc < 2) { + filename = "./ide.jar\0"; + } else { + filename = argv[1]; + } + + Inkjar::JarFileReader jar_file_reader(filename); + + for (;;) { + GByteArray *gba = jar_file_reader.get_next_file(); + if (gba == NULL) { + char *c_ptr; + gchar *last_filename = jar_file_reader.get_last_filename(); + if (last_filename == NULL) + break; + if ((c_ptr = std::strrchr(last_filename, '/')) != NULL) { + if (*(++c_ptr) == '\0') { + g_free(last_filename); + continue; + } + } + } else if (gba->len > 0) + ::write(1, gba->data, gba->len); + else + break; + } + return 0; +} +#endif diff --git a/src/inkjar/jar.h b/src/inkjar/jar.h new file mode 100644 index 000000000..2340a74c7 --- /dev/null +++ b/src/inkjar/jar.h @@ -0,0 +1,151 @@ +#ifndef __INKJAR_JAR_H_ +#define __INKJAR_JAR_H_ +/* + * Copyright (C) 1999 Bryan Burns + * Copyright (C) 2004 Johan Ceuppens + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include +#include +#include +#include + +namespace Inkjar { + +unsigned const RDSZ = 4096; + +//#define DEBUG 1 //uncommment for debug messages + +enum JarFileReaderState {CLOSED, OPEN}; + +//fixme: The following will be removed +typedef uint8_t ub1; +typedef uint16_t ub2; +typedef uint32_t ub4; + +#define LOC_EXTRA 6 /* extra bytes */ +#define LOC_COMP 8 /* compression method */ +#define LOC_MODTIME 10 /* last modification time */ +#define LOC_MODDATE 12 /* last modification date */ +#define LOC_CRC 14 /* CRC */ +#define LOC_CSIZE 18 /* compressed size */ +#define LOC_USIZE 22 /* uncompressed size */ +#define LOC_FNLEN 26 /* filename length */ +#define LOC_EFLEN 28 /* extra-field length */ + +#define CEN_COMP 10 /* compression method */ +#define CEN_MODTIME 12 +#define CEN_MODDATE 14 +#define CEN_CRC 16 +#define CEN_CSIZE 20 +#define CEN_USIZE 24 +#define CEN_FNLEN 28 +#define CEN_EFLEN 30 +#define CEN_COMLEN 32 +#define CEN_OFFSET 42 + + +/* macros */ +#define PACK_UB4(d, o, v) d[o] = (ub1)((v) & 0x000000ff); \ + d[o + 1] = (ub1)(((v) & 0x0000ff00) >> 8); \ + d[o + 2] = (ub1)(((v) & 0x00ff0000) >> 16); \ + d[o + 3] = (ub1)(((v) & 0xff000000) >> 24) + +#define PACK_UB2(d, o, v) d[o] = (ub1)((v) & 0x00ff); \ + d[o + 1] = (ub1)(((v) & 0xff00) >> 8) + +#define UNPACK_UB4(s, o) (ub4)s[o] + (((ub4)s[o + 1]) << 8) +\ + (((ub4)s[o + 2]) << 16) + (((ub4)s[o + 3]) << 24) + +#define UNPACK_UB2(s, o) (ub2)s[o] + (((ub2)s[o + 1]) << 8) + + + +/* + * JarFile: + * + * This is a wrapper class for canonical jarfile functions like reading, + * writing, seeking etc. JarFile is a dumb class with no state information. + * + * All memory allocations are done with g_malloc. + */ + +class JarFile { +public: + + JarFile() : fd(-1), _filename(NULL), _last_filename(NULL) {} + virtual ~JarFile(); + JarFile(gchar const *new_filename); + + GByteArray *get_next_file_contents(); + gchar *get_last_filename() const; + bool open(); + bool close(); + int read(guint8 *buf, int count); + + JarFile(JarFile const &rhs); + JarFile &operator=(JarFile const &rhs); + +private: + + int fd; + gchar *_filename; + z_stream _zs; + gchar *_last_filename; + + bool init_inflation(); + bool read_signature(); + guint32 get_crc(guint8 *bytes, guint16 flags); + guint8 *read_filename(guint16 filename_length); + bool check_compression_method(guint16 method, guint16 flags); + bool check_crc(guint32 oldcrc, guint32 crc, guint16 flags); + guint8 *get_compressed_file(guint32 compressed_size, + unsigned int &file_length, + guint32 oldcrc, guint16 flags); + guint8 *get_uncompressed_file(guint32 compressed_szie, guint32 crc, + guint16 eflen, guint16 flags); +}; // class JarFile + + +/* + * JarFileReader: + * + * This provides some smarter functions for operating on a jarfile object + * It should be able to grep for files or return the contents of a specific + * file. + */ + +class JarFileReader { +public: + + JarFileReader(gchar const *new_filename) + : _state(CLOSED), _jarfile(new_filename) {} + JarFileReader() : _state(CLOSED) {} + virtual ~JarFileReader() { if (_state == OPEN) _jarfile.close(); } + //fixme return types are incorrect + GByteArray *get_next_file();//fixme clean up return type + void set_filename(gchar const *new_filename); + void set_jarfile(JarFile const &new_jarfile); + gchar *get_last_filename() const { return _jarfile.get_last_filename(); }; + JarFileReader(JarFileReader const &rhs); + JarFileReader &operator=(JarFileReader const &rhs); +private: + JarFileReaderState _state; + JarFile _jarfile; + +}; // class JarFileReader + +} // namespace Inkjar +#endif // header guard + +/* + 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 : diff --git a/src/inkjar/makefile.in b/src/inkjar/makefile.in new file mode 100644 index 000000000..0ccb68b59 --- /dev/null +++ b/src/inkjar/makefile.in @@ -0,0 +1,17 @@ +# Convenience stub makefile to call the real Makefile. + +@SET_MAKE@ + +# Explicit so that it's the default rule. +all: + cd .. && $(MAKE) inkjar/all + +clean %.a %.o: + cd .. && $(MAKE) inkjar/$@ + +.PHONY: all clean + +OBJEXT = @OBJEXT@ + +.SUFFIXES: +.SUFFIXES: .a .$(OBJEXT) diff --git a/src/inkscape-private.h b/src/inkscape-private.h new file mode 100644 index 000000000..e6e6a44ea --- /dev/null +++ b/src/inkscape-private.h @@ -0,0 +1,62 @@ +#ifndef __INKSCAPE_PRIVATE_H__ +#define __INKSCAPE_PRIVATE_H__ + +/* + * Some forward declarations + * + * Authors: + * Lauris Kaplinski + * + * Copyright (C) 1999-2002 Lauris Kaplinski + * Copyright (C) 2001-2002 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#define SP_TYPE_INKSCAPE (inkscape_get_type ()) +#define SP_INKSCAPE(obj) (GTK_CHECK_CAST ((obj), SP_TYPE_INKSCAPE, Inkscape)) +#define SP_INKSCAPE_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), SP_TYPE_INKSCAPE, InkscapeClass)) +#define SP_IS_INKSCAPE(obj) (GTK_CHECK_TYPE ((obj), SP_TYPE_INKSCAPE)) +#define SP_IS_INKSCAPE_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), SP_TYPE_INKSCAPE)) + +#include "forward.h" +#include "inkscape.h" + +namespace Inkscape { class Selection; } + +GType inkscape_get_type (void); + +void inkscape_ref (void); +void inkscape_unref (void); + +/* + * These are meant solely for desktop, document etc. implementations + */ + +void inkscape_selection_modified (Inkscape::Selection *selection, guint flags); +void inkscape_selection_changed (Inkscape::Selection * selection); +void inkscape_selection_set (Inkscape::Selection * selection); +void inkscape_eventcontext_set (SPEventContext * eventcontext); +void inkscape_add_desktop (SPDesktop * desktop); +void inkscape_remove_desktop (SPDesktop * desktop); +void inkscape_activate_desktop (SPDesktop * desktop); +void inkscape_reactivate_desktop (SPDesktop * desktop); +void inkscape_add_document (SPDocument *document); +void inkscape_remove_document (SPDocument *document); + +void inkscape_set_color (SPColor *color, float opacity); + +#endif + + + +/* + 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:textwidth=99 : diff --git a/src/inkscape-stock.cpp b/src/inkscape-stock.cpp new file mode 100644 index 000000000..16bf883d0 --- /dev/null +++ b/src/inkscape-stock.cpp @@ -0,0 +1,51 @@ +/* + * @file inkscape-stock.h GTK+ Stock resources + * + * Authors: + * Robert Crosbie + * + * Copyright (C) 1999-2002 Authors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "gtk/gtkiconfactory.h" + + +void +inkscape_gtk_stock_init() { + static bool stock_initialized = false; + + if (stock_initialized) + return; + + GtkIconFactory *icon_factory = gtk_icon_factory_new(); + /* todo: Should we simply remove this file now that we're no longer + * calling gtk_icon_factory_add here? */ + gtk_icon_factory_add_default(icon_factory); + + stock_initialized = true; +} + +/* + 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:textwidth=99 : diff --git a/src/inkscape-stock.h b/src/inkscape-stock.h new file mode 100644 index 000000000..0a18b7284 --- /dev/null +++ b/src/inkscape-stock.h @@ -0,0 +1,150 @@ +/* + * @file inkscape-stock.h GTK+ Stock resources + * + * Authors: + * Robert Crosbie + * + * Copyright (C) 1999-2002 Authors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _INKSCAPE_STOCK_H_ +#define _INKSCAPE_STOCK_H_ + +/**************************************************************************/ +/** @name Inkscape Stock images */ +/**************************************************************************/ +/*@{*/ + +/*stroke style*/ +//#define INKSCAPE_STOCK_ABOUT "inkscape-about" +#define INKSCAPE_STOCK_JOIN_MITER "join_miter" +#define INKSCAPE_STOCK_JOIN_ROUND "join_round" +#define INKSCAPE_STOCK_JOIN_BEVEL "join_bevel" +#define INKSCAPE_STOCK_CAP_BUTT "cap_butt" +#define INKSCAPE_STOCK_CAP_ROUND "cap_round" +#define INKSCAPE_STOCK_CAP_SQUARE "cap_square" +//#define INKSCAPE_STOCK_START_MARKER "start_marker" +//#define INKSCAPE_STOCK_MID_MARKER "mid_marker" +//#define INKSCAPE_STOCK_END_MARKER "end_marker" +//#define INKSCAPE_STOCK_MARKER_NONE "-none" +//#define INKSCAPE_STOCK_MARKER_FILLED_ARROW "-filled_arrow" +//#define INKSCAPE_STOCK_MARKER_HOLLOW_ARROW "-hollow_arrow" +//#define INKSCAPE_STOCK_MARKER_QTY (3) + +/*object properties*/ +#define INKSCAPE_STOCK_ROTATE_LEFT "transform_rotate" +#define INKSCAPE_STOCK_SCALE_HOR "transform_scale_hor" +#define INKSCAPE_STOCK_SCALE_VER "transform_scale_ver" +#define INKSCAPE_STOCK_ARROWS_HOR "arrows_hor" +#define INKSCAPE_STOCK_ARROWS_VER "arrows_ver" +//#define INKSCAPE_STOCK_DIMENSION_HOR "dimension_hor" +//#define INKSCAPE_STOCK_DIMENSION_VER "dimension_ver" + +/*text editing*/ +#define INKSCAPE_STOCK_WRITING_MODE_LR "writing_mode_lr" +#define INKSCAPE_STOCK_WRITING_MODE_TB "writing_mode_tb" +#define INKSCAPE_STOCK_TEXT_LETTER_SPACING "text_letter_spacing" +#define INKSCAPE_STOCK_TEXT_LINE_SPACING "text_line_spacing" +#define INKSCAPE_STOCK_TEXT_HORZ_KERN "text_horz_kern" +#define INKSCAPE_STOCK_TEXT_VERT_KERN "text_vert_kern" +#define INKSCAPE_STOCK_TEXT_ROTATION "text_rotation" +#define INKSCAPE_STOCK_TEXT_REMOVE_KERNS "text_remove_kerns" + +/*xml-tree*/ +#define INKSCAPE_STOCK_ADD_XML_ELEMENT_NODE "add_xml_element_node" +#define INKSCAPE_STOCK_ADD_XML_TEXT_NODE "add_xml_text_node" +#define INKSCAPE_STOCK_DUPLICATE_XML_NODE "duplicate_xml_node" +#define INKSCAPE_STOCK_DELETE_XML_NODE "delete_xml_node" +#define INKSCAPE_STOCK_DELETE_XML_ATTRIBUTE "delete_xml_attribute" +#define INKSCAPE_STOCK_SET "set" + +/*paint-selector*/ +#define INKSCAPE_STOCK_FILL_NONE "fill_none" +#define INKSCAPE_STOCK_FILL_SOLID "fill_solid" +#define INKSCAPE_STOCK_FILL_GRADIENT "fill_gradient" +#define INKSCAPE_STOCK_FILL_RADIAL "fill_radial" +#define INKSCAPE_STOCK_FILL_PATTERN "fill_pattern" +#define INKSCAPE_STOCK_FILL_UNSET "fill_unset" +#define INKSCAPE_STOCK_FILL_FRACTAL "fill_fractal" + +//#define INKSCAPE_STOCK_GUIDE_DIALOG "guide_dialog" + +//#define INKSCAPE_STOCK_EDIT_DUPLICATE "edit_duplicate" + +//#define INKSCAPE_STOCK_SELECTION_TOP "selection_top" +//#define INKSCAPE_STOCK_SELECTION_BOT "selection_bot" +//#define INKSCAPE_STOCK_SELECTION_UP "selection_up" +//#define INKSCAPE_STOCK_SELECTION_DOWN "selection_down" +//#define INKSCAPE_STOCK_SELECTION_GROUP "selection_group" +//#define INKSCAPE_STOCK_SELECTION_UNGROUP "selection_ungroup" +//#define INKSCAPE_STOCK_SELECTION_COMBINE "selection_combine" +//#define INKSCAPE_STOCK_SELECTION_BREAK "selection_break" + +//#define INKSCAPE_STOCK_OBJECT_ROTATE "object_rotate" +//#define INKSCAPE_STOCK_OBJECT_RESET "object_reset" +//#define INKSCAPE_STOCK_OBJECT_TOCURVE "object_tocurve" + +//#define INKSCAPE_STOCK_DRAW_SELECT "draw_select" +//#define INKSCAPE_STOCK_DRAW_NODE "draw_node" +//#define INKSCAPE_STOCK_DRAW_RECT "draw_rect" +//#define INKSCAPE_STOCK_DRAW_ARC "draw_arc" +//#define INKSCAPE_STOCK_DRAW_STAR "draw_star" +//#define INKSCAPE_STOCK_DRAW_SPIRAL "draw_spiral" +//#define INKSCAPE_STOCK_DRAW_FREEHAND "draw_freehand" +//#define INKSCAPE_STOCK_DRAW_PEN "draw_pen" +//#define INKSCAPE_STOCK_DRAW_DYNAHAND "draw_dynahand" +//#define INKSCAPE_STOCK_DRAW_TEXT "draw_text" +//#define INKSCAPE_STOCK_DRAW_ZOOM "draw_zoom" +//#define INKSCAPE_STOCK_DRAW_DROPPER "draw_dropper" + +//#define INKSCAPE_STOCK_ZOOM_IN "zoom_in" +//#define INKSCAPE_STOCK_ZOOM_OUT "zoom_out" +//#define INKSCAPE_STOCK_TOGGLE_GRID "toggle_grid" +//#define INKSCAPE_STOCK_TOGGLE_GUIDES "toggle_guides" +//#define INKSCAPE_STOCK_ZOOM_PAGE "zoom_page" +//#define INKSCAPE_STOCK_ZOOM_DRAW "zoom_draw" +//#define INKSCAPE_STOCK_ZOOM_SELECT "zoom_select" + +//#define INKSCAPE_STOCK_OBJECT_LAYOUT "object_layout" +//#define INKSCAPE_STOCK_OBJECT_TRANS "object_trans" +//#define INKSCAPE_STOCK_OBJECT_ALIGN "object_align" +//#define INKSCAPE_STOCK_OBJECT_FONT "object_font" + +#define INKSCAPE_STOCK_PROPERTIES_FILL_PAGE "properties_fill" +#define INKSCAPE_STOCK_PROPERTIES_STROKE_PAINT_PAGE "properties_stroke_paint" +#define INKSCAPE_STOCK_PROPERTIES_STROKE_PAGE "properties_stroke" + +/** + * Sets up the inkscape stock repository. + */ + +void inkscape_gtk_stock_init(void); + +/*@}*/ +#endif /* _INKSCAPE_STOCK_H_ */ + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : + diff --git a/src/inkscape.cpp b/src/inkscape.cpp new file mode 100644 index 000000000..9c0d93173 --- /dev/null +++ b/src/inkscape.cpp @@ -0,0 +1,1413 @@ +#define __INKSCAPE_C__ + +/* + * Interface to main application + * + * Authors: + * Lauris Kaplinski + * bulia byak + * + * Copyright (C) 1999-2005 authors + * g++ port Copyright (C) 2003 Nathan Hurst + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + + +#include "debug/simple-event.h" +#include "debug/event-tracker.h" + +#ifndef WIN32 +# define HAS_PROC_SELF_EXE //to get path of executable +#else + +// For now to get at is_os_wide(). +# include "extension/internal/win32.h" +using Inkscape::Extension::Internal::PrintWin32; + +#define _WIN32_IE 0x0400 +//#define HAS_SHGetSpecialFolderPath +#define HAS_SHGetSpecialFolderLocation +#define HAS_GetModuleFileName +# include +#endif + +#include + +#include +#include + +#include +#include "helper/sp-marshal.h" +#include "dialogs/debugdialog.h" +#include "application/application.h" +#include "application/editor.h" +#include "preferences.h" + + +#include "document.h" +#include "desktop.h" +#include "desktop-handles.h" +#include "selection.h" +#include "event-context.h" +#include "inkscape-private.h" +#include "prefs-utils.h" +#include "xml/repr.h" +#include "io/sys.h" + +#include "extension/init.h" + +static Inkscape::Application *inkscape = NULL; + +/* Backbones of configuration xml data */ +#include "menus-skeleton.h" + +enum { + MODIFY_SELECTION, // global: one of selections modified + CHANGE_SELECTION, // global: one of selections changed + CHANGE_SUBSELECTION, // global: one of subselections (text selection, gradient handle, etc) changed + SET_SELECTION, // global: one of selections set + SET_EVENTCONTEXT, // tool switched + ACTIVATE_DESKTOP, // some desktop got focus + DEACTIVATE_DESKTOP, // some desktop lost focus + SHUTDOWN_SIGNAL, // inkscape is quitting + DIALOGS_HIDE, // user pressed F12 + DIALOGS_UNHIDE, // user pressed F12 + EXTERNAL_CHANGE, // a document was changed by some external means (undo or XML editor); this + // may not be reflected by a selection change and thus needs a separate signal + LAST_SIGNAL +}; + +#define DESKTOP_IS_ACTIVE(d) ((d) == inkscape->desktops->data) + + +/*################################ +# FORWARD DECLARATIONS +################################*/ + +gboolean inkscape_app_use_gui( Inkscape::Application const * app ); + +static void inkscape_class_init (Inkscape::ApplicationClass *klass); +static void inkscape_init (SPObject *object); +static void inkscape_dispose (GObject *object); + +static void inkscape_activate_desktop_private (Inkscape::Application *inkscape, SPDesktop *desktop); +static void inkscape_deactivate_desktop_private (Inkscape::Application *inkscape, SPDesktop *desktop); + +static bool inkscape_init_config (Inkscape::XML::Document *doc, const gchar *config_name, const gchar *skeleton, + unsigned int skel_size, + const gchar *e_mkdir, + const gchar *e_notdir, + const gchar *e_ccf, + const gchar *e_cwf, + const gchar *warn); + +struct Inkscape::Application { + GObject object; + Inkscape::XML::Document *menus; + GSList *documents; + GSList *desktops; + gchar *argv0; + gboolean dialogs_toggle; + gboolean use_gui; // may want to consider a virtual function + // for overriding things like the warning dlg's +}; + +struct Inkscape::ApplicationClass { + GObjectClass object_class; + + /* Signals */ + void (* change_selection) (Inkscape::Application * inkscape, Inkscape::Selection * selection); + void (* change_subselection) (Inkscape::Application * inkscape, SPDesktop *desktop); + void (* modify_selection) (Inkscape::Application * inkscape, Inkscape::Selection * selection, guint flags); + void (* set_selection) (Inkscape::Application * inkscape, Inkscape::Selection * selection); + void (* set_eventcontext) (Inkscape::Application * inkscape, SPEventContext * eventcontext); + void (* activate_desktop) (Inkscape::Application * inkscape, SPDesktop * desktop); + void (* deactivate_desktop) (Inkscape::Application * inkscape, SPDesktop * desktop); + void (* destroy_document) (Inkscape::Application *inkscape, SPDocument *doc); + void (* color_set) (Inkscape::Application *inkscape, SPColor *color, double opacity); + void (* shut_down) (Inkscape::Application *inkscape); + void (* dialogs_hide) (Inkscape::Application *inkscape); + void (* dialogs_unhide) (Inkscape::Application *inkscape); + void (* external_change) (Inkscape::Application *inkscape); +}; + +static GObjectClass * parent_class; +static guint inkscape_signals[LAST_SIGNAL] = {0}; + +static void (* segv_handler) (int) = NULL; + +#ifdef WIN32 +#define INKSCAPE_PROFILE_DIR "Inkscape" +#else +#define INKSCAPE_PROFILE_DIR ".inkscape" +#endif + +#define MENUS_FILE "menus.xml" + + +/** + * Retrieves the GType for the Inkscape Application object. + */ +GType +inkscape_get_type (void) +{ + static GType type = 0; + if (!type) { + GTypeInfo info = { + sizeof (Inkscape::ApplicationClass), + NULL, NULL, + (GClassInitFunc) inkscape_class_init, + NULL, NULL, + sizeof (Inkscape::Application), + 4, + (GInstanceInitFunc) inkscape_init, + NULL + }; + type = g_type_register_static (G_TYPE_OBJECT, "Inkscape_Application", &info, (GTypeFlags)0); + } + return type; +} + + +/** + * Initializes the inkscape class, registering all of its signal handlers + * and virtual functions + */ +static void +inkscape_class_init (Inkscape::ApplicationClass * klass) +{ + GObjectClass * object_class; + + object_class = (GObjectClass *) klass; + + parent_class = (GObjectClass *)g_type_class_peek_parent (klass); + + inkscape_signals[MODIFY_SELECTION] = g_signal_new ("modify_selection", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (Inkscape::ApplicationClass, modify_selection), + NULL, NULL, + sp_marshal_NONE__POINTER_UINT, + G_TYPE_NONE, 2, + G_TYPE_POINTER, G_TYPE_UINT); + inkscape_signals[CHANGE_SELECTION] = g_signal_new ("change_selection", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (Inkscape::ApplicationClass, change_selection), + NULL, NULL, + sp_marshal_NONE__POINTER, + G_TYPE_NONE, 1, + G_TYPE_POINTER); + inkscape_signals[CHANGE_SUBSELECTION] = g_signal_new ("change_subselection", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (Inkscape::ApplicationClass, change_subselection), + NULL, NULL, + sp_marshal_NONE__POINTER, + G_TYPE_NONE, 1, + G_TYPE_POINTER); + inkscape_signals[SET_SELECTION] = g_signal_new ("set_selection", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (Inkscape::ApplicationClass, set_selection), + NULL, NULL, + sp_marshal_NONE__POINTER, + G_TYPE_NONE, 1, + G_TYPE_POINTER); + inkscape_signals[SET_EVENTCONTEXT] = g_signal_new ("set_eventcontext", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (Inkscape::ApplicationClass, set_eventcontext), + NULL, NULL, + sp_marshal_NONE__POINTER, + G_TYPE_NONE, 1, + G_TYPE_POINTER); + inkscape_signals[ACTIVATE_DESKTOP] = g_signal_new ("activate_desktop", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (Inkscape::ApplicationClass, activate_desktop), + NULL, NULL, + sp_marshal_NONE__POINTER, + G_TYPE_NONE, 1, + G_TYPE_POINTER); + inkscape_signals[DEACTIVATE_DESKTOP] = g_signal_new ("deactivate_desktop", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (Inkscape::ApplicationClass, deactivate_desktop), + NULL, NULL, + sp_marshal_NONE__POINTER, + G_TYPE_NONE, 1, + G_TYPE_POINTER); + inkscape_signals[SHUTDOWN_SIGNAL] = g_signal_new ("shut_down", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (Inkscape::ApplicationClass, shut_down), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + inkscape_signals[DIALOGS_HIDE] = g_signal_new ("dialogs_hide", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (Inkscape::ApplicationClass, dialogs_hide), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + inkscape_signals[DIALOGS_UNHIDE] = g_signal_new ("dialogs_unhide", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (Inkscape::ApplicationClass, dialogs_unhide), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + inkscape_signals[EXTERNAL_CHANGE] = g_signal_new ("external_change", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (Inkscape::ApplicationClass, external_change), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + object_class->dispose = inkscape_dispose; + + klass->activate_desktop = inkscape_activate_desktop_private; + klass->deactivate_desktop = inkscape_deactivate_desktop_private; +} + + +static void +inkscape_init (SPObject * object) +{ + if (!inkscape) { + inkscape = (Inkscape::Application *) object; + } else { + g_assert_not_reached (); + } + + inkscape->menus = sp_repr_read_mem (_(menus_skeleton), MENUS_SKELETON_SIZE, NULL); + + inkscape->documents = NULL; + inkscape->desktops = NULL; + + inkscape->dialogs_toggle = TRUE; +} + + +static void +inkscape_dispose (GObject *object) +{ + Inkscape::Application *inkscape = (Inkscape::Application *) object; + + while (inkscape->documents) { + // we don't otherwise unref, so why here? + sp_document_unref((SPDocument *)inkscape->documents->data); + } + + g_assert (!inkscape->desktops); + + Inkscape::Preferences::save(); + + if (inkscape->menus) { + /* fixme: This is not the best place */ + Inkscape::GC::release(inkscape->menus); + inkscape->menus = NULL; + } + + G_OBJECT_CLASS (parent_class)->dispose (object); + + gtk_main_quit (); +} + + +void +inkscape_ref (void) +{ + if (inkscape) + g_object_ref (G_OBJECT (inkscape)); +} + + +void +inkscape_unref (void) +{ + if (inkscape) + g_object_unref (G_OBJECT (inkscape)); +} + + +static void +inkscape_activate_desktop_private (Inkscape::Application *inkscape, SPDesktop *desktop) +{ + desktop->set_active (true); +} + + +static void +inkscape_deactivate_desktop_private (Inkscape::Application *inkscape, SPDesktop *desktop) +{ + desktop->set_active (false); +} + + +/* fixme: This is EVIL, and belongs to main after all */ + +#define SP_INDENT 8 + + +static void +inkscape_segv_handler (int signum) +{ + using Inkscape::Debug::SimpleEvent; + using Inkscape::Debug::EventTracker; + using Inkscape::Debug::Logger; + + static gint recursion = FALSE; + + /* let any SIGABRTs seen from within this handler dump core */ + signal(SIGABRT, SIG_DFL); + + /* Kill loops */ + if (recursion) { + abort (); + } + recursion = TRUE; + + EventTracker > tracker("crash"); + tracker.set >("emergency-save"); + + fprintf(stderr, "\nEmergency save activated!\n"); + + time_t sptime = time (NULL); + struct tm *sptm = localtime (&sptime); + gchar sptstr[256]; + strftime (sptstr, 256, "%Y_%m_%d_%H_%M_%S", sptm); + + gint count = 0; + GSList *savednames = NULL; + GSList *failednames = NULL; + for (GSList *l = inkscape->documents; l != NULL; l = l->next) { + SPDocument *doc; + Inkscape::XML::Node *repr; + doc = (SPDocument *) l->data; + repr = sp_document_repr_root (doc); + if (repr->attribute("sodipodi:modified")) { + const gchar *docname, *d0, *d; + gchar n[64], c[1024]; + FILE *file; + + /* originally, the document name was retrieved from + * the sodipod:docname attribute */ + docname = doc->name; + if (docname) { + /* fixme: Quick hack to remove emergency file suffix */ + d0 = strrchr ((char*)docname, '.'); + if (d0 && (d0 > docname)) { + d0 = strrchr ((char*)(d0 - 1), '.'); + if (d0 && (d0 > docname)) { + d = d0; + while (isdigit (*d) || (*d == '.') || (*d == '_')) d += 1; + if (*d) { + memcpy (n, docname, MIN (d0 - docname - 1, 64)); + n[63] = '\0'; + docname = n; + } + } + } + } + + if (!docname || !*docname) docname = "emergency"; + // try saving to the profile location + g_snprintf (c, 1024, "%.256s.%s.%d", docname, sptstr, count); + gchar * location = homedir_path(c); + Inkscape::IO::dump_fopen_call(location, "E"); + file = Inkscape::IO::fopen_utf8name(location, "w"); + g_free(location); + if (!file) { + // try saving to /tmp + g_snprintf (c, 1024, "/tmp/inkscape-%.256s.%s.%d", docname, sptstr, count); + Inkscape::IO::dump_fopen_call(c, "G"); + file = Inkscape::IO::fopen_utf8name(c, "w"); + } + if (!file) { + // try saving to the current directory + g_snprintf (c, 1024, "inkscape-%.256s.%s.%d", docname, sptstr, count); + Inkscape::IO::dump_fopen_call(c, "F"); + file = Inkscape::IO::fopen_utf8name(c, "w"); + } + if (file) { + sp_repr_save_stream (sp_repr_document (repr), file, SP_SVG_NS_URI); + savednames = g_slist_prepend (savednames, g_strdup (c)); + fclose (file); + } else { + docname = repr->attribute("sodipodi:docname"); + failednames = g_slist_prepend (failednames, (docname) ? g_strdup (docname) : g_strdup (_("Untitled document"))); + } + count++; + } + } + + savednames = g_slist_reverse (savednames); + failednames = g_slist_reverse (failednames); + if (savednames) { + fprintf (stderr, "\nEmergency save document locations:\n"); + for (GSList *l = savednames; l != NULL; l = l->next) { + fprintf (stderr, " %s\n", (gchar *) l->data); + } + } + if (failednames) { + fprintf (stderr, "\nFailed to do emergency save for documents:\n"); + for (GSList *l = failednames; l != NULL; l = l->next) { + fprintf (stderr, " %s\n", (gchar *) l->data); + } + } + + Inkscape::Preferences::save(); + + fprintf (stderr, "Emergency save completed. Inkscape will close now.\n"); + fprintf (stderr, "If you can reproduce this crash, please file a bug at www.inkscape.org\n"); + fprintf (stderr, "with a detailed description of the steps leading to the crash, so we can fix it.\n"); + + /* Show nice dialog box */ + + char const *istr = N_("Inkscape encountered an internal error and will close now.\n"); + char const *sstr = N_("Automatic backups of unsaved documents were done to the following locations:\n"); + char const *fstr = N_("Automatic backup of the following documents failed:\n"); + gint nllen = strlen ("\n"); + gint len = strlen (istr) + strlen (sstr) + strlen (fstr); + for (GSList *l = savednames; l != NULL; l = l->next) { + len = len + SP_INDENT + strlen ((gchar *) l->data) + nllen; + } + for (GSList *l = failednames; l != NULL; l = l->next) { + len = len + SP_INDENT + strlen ((gchar *) l->data) + nllen; + } + len += 1; + gchar *b = g_new (gchar, len); + gint pos = 0; + len = strlen (istr); + memcpy (b + pos, istr, len); + pos += len; + if (savednames) { + len = strlen (sstr); + memcpy (b + pos, sstr, len); + pos += len; + for (GSList *l = savednames; l != NULL; l = l->next) { + memset (b + pos, ' ', SP_INDENT); + pos += SP_INDENT; + len = strlen ((gchar *) l->data); + memcpy (b + pos, l->data, len); + pos += len; + memcpy (b + pos, "\n", nllen); + pos += nllen; + } + } + if (failednames) { + len = strlen (fstr); + memcpy (b + pos, fstr, len); + pos += len; + for (GSList *l = failednames; l != NULL; l = l->next) { + memset (b + pos, ' ', SP_INDENT); + pos += SP_INDENT; + len = strlen ((gchar *) l->data); + memcpy (b + pos, l->data, len); + pos += len; + memcpy (b + pos, "\n", nllen); + pos += nllen; + } + } + *(b + pos) = '\0'; + + if ( inkscape_get_instance() && inkscape_app_use_gui( inkscape_get_instance() ) ) { + GtkWidget *msgbox = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, "%s", b); + gtk_dialog_run (GTK_DIALOG (msgbox)); + gtk_widget_destroy (msgbox); + } + else + { + g_message( "Error: %s", b ); + } + g_free (b); + + tracker.clear(); + Logger::shutdown(); + + (* segv_handler) (signum); +} + + + +void +inkscape_application_init (const gchar *argv0, gboolean use_gui) +{ + inkscape = (Inkscape::Application *)g_object_new (SP_TYPE_INKSCAPE, NULL); + /* fixme: load application defaults */ + + segv_handler = signal (SIGSEGV, inkscape_segv_handler); + signal (SIGFPE, inkscape_segv_handler); + signal (SIGILL, inkscape_segv_handler); +#ifndef WIN32 + signal (SIGBUS, inkscape_segv_handler); +#endif + signal (SIGABRT, inkscape_segv_handler); + + inkscape->use_gui = use_gui; + inkscape->argv0 = g_strdup(argv0); + + /* Attempt to load the preferences, and set the save_preferences flag to TRUE + if we could, or FALSE if we couldn't */ + Inkscape::Preferences::load(); + inkscape_load_menus(inkscape); + + /* DebugDialog redirection. On Linux, default to OFF, on Win32, default to ON */ +#ifdef WIN32 +#define DEFAULT_LOG_REDIRECT true +#else +#define DEFAULT_LOG_REDIRECT false +#endif + + if (prefs_get_int_attribute("dialogs.debug", "redirect", DEFAULT_LOG_REDIRECT)) + { + Inkscape::UI::Dialogs::DebugDialog::getInstance()->captureLogMessages(); + } + + /* Initialize the extensions */ + Inkscape::Extension::init(); + + return; +} + +/** + * Returns the current Inkscape::Application global object + */ +Inkscape::Application * +inkscape_get_instance() +{ + return inkscape; +} + +gboolean inkscape_app_use_gui( Inkscape::Application const * app ) +{ + return app->use_gui; +} + +/** + * Preference management + * We use '.' as separator + * + * Returns TRUE if the config file was successfully loaded, FALSE if not. + */ +bool +inkscape_load_config (const gchar *filename, Inkscape::XML::Document *config, const gchar *skeleton, + unsigned int skel_size, const gchar *e_notreg, const gchar *e_notxml, + const gchar *e_notsp, const gchar *warn) +{ + gchar *fn = profile_path(filename); + if (!Inkscape::IO::file_test(fn, G_FILE_TEST_EXISTS)) { + bool result; + /* No such file */ + result = inkscape_init_config (config, filename, skeleton, + skel_size, + _("Cannot create directory %s.\n%s"), + _("%s is not a valid directory.\n%s"), + _("Cannot create file %s.\n%s"), + _("Cannot write file %s.\n%s"), + _("Although Inkscape will run, it will use default settings,\n" + "and any changes made in preferences will not be saved.")); + g_free (fn); + return result; + } + + if (!Inkscape::IO::file_test(fn, G_FILE_TEST_IS_REGULAR)) { + /* Not a regular file */ + gchar *safeFn = Inkscape::IO::sanitizeString(fn); + GtkWidget *w = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_WARNING, GTK_BUTTONS_OK, e_notreg, safeFn, warn); + gtk_dialog_run (GTK_DIALOG (w)); + gtk_widget_destroy (w); + g_free(safeFn); + g_free (fn); + return false; + } + + Inkscape::XML::Document *doc = sp_repr_read_file (fn, NULL); + if (doc == NULL) { + /* Not an valid xml file */ + gchar *safeFn = Inkscape::IO::sanitizeString(fn); + GtkWidget *w = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_WARNING, GTK_BUTTONS_OK, e_notxml, safeFn, warn); + gtk_dialog_run (GTK_DIALOG (w)); + gtk_widget_destroy (w); + g_free(safeFn); + g_free (fn); + return false; + } + + Inkscape::XML::Node *root = sp_repr_document_root (doc); + if (strcmp (root->name(), "inkscape")) { + gchar *safeFn = Inkscape::IO::sanitizeString(fn); + GtkWidget *w = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_WARNING, GTK_BUTTONS_OK, e_notsp, safeFn, warn); + gtk_dialog_run (GTK_DIALOG (w)); + gtk_widget_destroy (w); + Inkscape::GC::release(doc); + g_free(safeFn); + g_free (fn); + return false; + } + + /** \todo this is a hack, need to figure out how to get + * a reasonable merge working with the menus.xml file */ + if (skel_size == MENUS_SKELETON_SIZE) { + if (INKSCAPE) + INKSCAPE->menus = doc; + doc = config; + } else { + config->root()->mergeFrom(doc->root(), "id"); + } + + Inkscape::GC::release(doc); + g_free (fn); + return true; +} + +/** + * Menus management + * + */ +bool +inkscape_load_menus (Inkscape::Application *inkscape) +{ + gchar *fn = profile_path(MENUS_FILE); + bool retval = false; + if (Inkscape::IO::file_test(fn, G_FILE_TEST_EXISTS)) { + retval = inkscape_load_config (MENUS_FILE, + inkscape->menus, + menus_skeleton, + MENUS_SKELETON_SIZE, + _("%s is not a regular file.\n%s"), + _("%s not a valid XML file, or\n" + "you don't have read permissions on it.\n%s"), + _("%s is not a valid menus file.\n%s"), + _("Inkscape will run with default menus.\n" + "New menus will not be saved.")); + } else { + INKSCAPE->menus = sp_repr_read_mem(menus_skeleton, MENUS_SKELETON_SIZE, NULL); + if (INKSCAPE->menus != NULL) + retval = true; + } + g_free(fn); + return retval; +} + +/** + * We use '.' as separator + * \param inkscape Unused + */ +Inkscape::XML::Node * +inkscape_get_repr (Inkscape::Application *inkscape, const gchar *key) +{ + if (key == NULL) { + return NULL; + } + + Inkscape::XML::Node *repr = sp_repr_document_root (Inkscape::Preferences::get()); + g_assert (!(strcmp (repr->name(), "inkscape"))); + + gchar const *s = key; + while ((s) && (*s)) { + + /* Find next name */ + gchar const *e = strchr (s, '.'); + guint len; + if (e) { + len = e++ - s; + } else { + len = strlen (s); + } + + Inkscape::XML::Node* child; + for (child = repr->firstChild(); child != NULL; child = child->next()) { + gchar const *id = child->attribute("id"); + if ((id) && (strlen (id) == len) && (!strncmp (id, s, len))) + { + break; + } + } + if (child == NULL) { + return NULL; + } + + repr = child; + s = e; + } + return repr; +} + + + +void +inkscape_selection_modified (Inkscape::Selection *selection, guint flags) +{ + if (Inkscape::NSApplication::Application::getNewGui()) { + Inkscape::NSApplication::Editor::selectionModified (selection, flags); + return; + } + g_return_if_fail (selection != NULL); + + if (DESKTOP_IS_ACTIVE (selection->desktop())) { + g_signal_emit (G_OBJECT (inkscape), inkscape_signals[MODIFY_SELECTION], 0, selection, flags); + } +} + + +void +inkscape_selection_changed (Inkscape::Selection * selection) +{ + if (Inkscape::NSApplication::Application::getNewGui()) { + Inkscape::NSApplication::Editor::selectionChanged (selection); + return; + } + g_return_if_fail (selection != NULL); + + if (DESKTOP_IS_ACTIVE (selection->desktop())) { + g_signal_emit (G_OBJECT (inkscape), inkscape_signals[CHANGE_SELECTION], 0, selection); + } +} + +void +inkscape_subselection_changed (SPDesktop *desktop) +{ + if (Inkscape::NSApplication::Application::getNewGui()) { + Inkscape::NSApplication::Editor::subSelectionChanged (desktop); + return; + } + g_return_if_fail (desktop != NULL); + + if (DESKTOP_IS_ACTIVE (desktop)) { + g_signal_emit (G_OBJECT (inkscape), inkscape_signals[CHANGE_SUBSELECTION], 0, desktop); + } +} + + +void +inkscape_selection_set (Inkscape::Selection * selection) +{ + if (Inkscape::NSApplication::Application::getNewGui()) { + Inkscape::NSApplication::Editor::selectionSet (selection); + return; + } + g_return_if_fail (selection != NULL); + + if (DESKTOP_IS_ACTIVE (selection->desktop())) { + g_signal_emit (G_OBJECT (inkscape), inkscape_signals[SET_SELECTION], 0, selection); + g_signal_emit (G_OBJECT (inkscape), inkscape_signals[CHANGE_SELECTION], 0, selection); + } +} + + +void +inkscape_eventcontext_set (SPEventContext * eventcontext) +{ + if (Inkscape::NSApplication::Application::getNewGui()) { + Inkscape::NSApplication::Editor::eventContextSet (eventcontext); + return; + } + g_return_if_fail (eventcontext != NULL); + g_return_if_fail (SP_IS_EVENT_CONTEXT (eventcontext)); + + if (DESKTOP_IS_ACTIVE (eventcontext->desktop)) { + g_signal_emit (G_OBJECT (inkscape), inkscape_signals[SET_EVENTCONTEXT], 0, eventcontext); + } +} + + +void +inkscape_add_desktop (SPDesktop * desktop) +{ + g_return_if_fail (desktop != NULL); + + if (Inkscape::NSApplication::Application::getNewGui()) + { + Inkscape::NSApplication::Editor::addDesktop (desktop); + return; + } + g_return_if_fail (inkscape != NULL); + + g_assert (!g_slist_find (inkscape->desktops, desktop)); + + inkscape->desktops = g_slist_append (inkscape->desktops, desktop); + + if (DESKTOP_IS_ACTIVE (desktop)) { + g_signal_emit (G_OBJECT (inkscape), inkscape_signals[ACTIVATE_DESKTOP], 0, desktop); + g_signal_emit (G_OBJECT (inkscape), inkscape_signals[SET_EVENTCONTEXT], 0, SP_DT_EVENTCONTEXT (desktop)); + g_signal_emit (G_OBJECT (inkscape), inkscape_signals[SET_SELECTION], 0, SP_DT_SELECTION (desktop)); + g_signal_emit (G_OBJECT (inkscape), inkscape_signals[CHANGE_SELECTION], 0, SP_DT_SELECTION (desktop)); + } +} + + + +void +inkscape_remove_desktop (SPDesktop * desktop) +{ + g_return_if_fail (desktop != NULL); + if (Inkscape::NSApplication::Application::getNewGui()) + { + Inkscape::NSApplication::Editor::removeDesktop (desktop); + return; + } + g_return_if_fail (inkscape != NULL); + + g_assert (g_slist_find (inkscape->desktops, desktop)); + + if (DESKTOP_IS_ACTIVE (desktop)) { + g_signal_emit (G_OBJECT (inkscape), inkscape_signals[DEACTIVATE_DESKTOP], 0, desktop); + if (inkscape->desktops->next != NULL) { + SPDesktop * new_desktop = (SPDesktop *) inkscape->desktops->next->data; + inkscape->desktops = g_slist_remove (inkscape->desktops, new_desktop); + inkscape->desktops = g_slist_prepend (inkscape->desktops, new_desktop); + g_signal_emit (G_OBJECT (inkscape), inkscape_signals[ACTIVATE_DESKTOP], 0, new_desktop); + g_signal_emit (G_OBJECT (inkscape), inkscape_signals[SET_EVENTCONTEXT], 0, SP_DT_EVENTCONTEXT (new_desktop)); + g_signal_emit (G_OBJECT (inkscape), inkscape_signals[SET_SELECTION], 0, SP_DT_SELECTION (new_desktop)); + g_signal_emit (G_OBJECT (inkscape), inkscape_signals[CHANGE_SELECTION], 0, SP_DT_SELECTION (new_desktop)); + } else { + g_signal_emit (G_OBJECT (inkscape), inkscape_signals[SET_EVENTCONTEXT], 0, NULL); + if (SP_DT_SELECTION(desktop)) + SP_DT_SELECTION(desktop)->clear(); + } + } + + inkscape->desktops = g_slist_remove (inkscape->desktops, desktop); + + // if this was the last desktop, shut down the program + if (inkscape->desktops == NULL) { + inkscape_exit (inkscape); + } +} + + + +void +inkscape_activate_desktop (SPDesktop * desktop) +{ + g_return_if_fail (desktop != NULL); + if (Inkscape::NSApplication::Application::getNewGui()) + { + Inkscape::NSApplication::Editor::activateDesktop (desktop); + return; + } + g_return_if_fail (inkscape != NULL); + + if (DESKTOP_IS_ACTIVE (desktop)) { + return; + } + + g_assert (g_slist_find (inkscape->desktops, desktop)); + + SPDesktop *current = (SPDesktop *) inkscape->desktops->data; + + g_signal_emit (G_OBJECT (inkscape), inkscape_signals[DEACTIVATE_DESKTOP], 0, current); + + inkscape->desktops = g_slist_remove (inkscape->desktops, desktop); + inkscape->desktops = g_slist_prepend (inkscape->desktops, desktop); + + g_signal_emit (G_OBJECT (inkscape), inkscape_signals[ACTIVATE_DESKTOP], 0, desktop); + g_signal_emit (G_OBJECT (inkscape), inkscape_signals[SET_EVENTCONTEXT], 0, SP_DT_EVENTCONTEXT (desktop)); + g_signal_emit (G_OBJECT (inkscape), inkscape_signals[SET_SELECTION], 0, SP_DT_SELECTION (desktop)); + g_signal_emit (G_OBJECT (inkscape), inkscape_signals[CHANGE_SELECTION], 0, SP_DT_SELECTION (desktop)); +} + + +/** + * Resends ACTIVATE_DESKTOP for current desktop; needed when a new desktop has got its window that dialogs will transientize to + */ +void +inkscape_reactivate_desktop (SPDesktop * desktop) +{ + g_return_if_fail (desktop != NULL); + if (Inkscape::NSApplication::Application::getNewGui()) + { + Inkscape::NSApplication::Editor::reactivateDesktop (desktop); + return; + } + g_return_if_fail (inkscape != NULL); + + if (DESKTOP_IS_ACTIVE (desktop)) + g_signal_emit (G_OBJECT (inkscape), inkscape_signals[ACTIVATE_DESKTOP], 0, desktop); +} + + + +SPDesktop * +inkscape_find_desktop_by_dkey (unsigned int dkey) +{ + for (GSList *r = inkscape->desktops; r; r = r->next) { + if (((SPDesktop *) r->data)->dkey == dkey) + return ((SPDesktop *) r->data); + } + return NULL; +} + + + + +unsigned int +inkscape_maximum_dkey() +{ + unsigned int dkey = 0; + + for (GSList *r = inkscape->desktops; r; r = r->next) { + if (((SPDesktop *) r->data)->dkey > dkey) + dkey = ((SPDesktop *) r->data)->dkey; + } + + return dkey; +} + + + +SPDesktop * +inkscape_next_desktop () +{ + SPDesktop *d = NULL; + unsigned int dkey_current = ((SPDesktop *) inkscape->desktops->data)->dkey; + + if (dkey_current < inkscape_maximum_dkey()) { + // find next existing + for (unsigned int i = dkey_current + 1; i <= inkscape_maximum_dkey(); i++) { + d = inkscape_find_desktop_by_dkey (i); + if (d) { + break; + } + } + } else { + // find first existing + for (unsigned int i = 0; i <= inkscape_maximum_dkey(); i++) { + d = inkscape_find_desktop_by_dkey (i); + if (d) { + break; + } + } + } + + g_assert (d); + + return d; +} + + + +SPDesktop * +inkscape_prev_desktop () +{ + SPDesktop *d = NULL; + unsigned int dkey_current = ((SPDesktop *) inkscape->desktops->data)->dkey; + + if (dkey_current > 0) { + // find prev existing + for (signed int i = dkey_current - 1; i >= 0; i--) { + d = inkscape_find_desktop_by_dkey (i); + if (d) { + break; + } + } + } + if (!d) { + // find last existing + d = inkscape_find_desktop_by_dkey (inkscape_maximum_dkey()); + } + + g_assert (d); + + return d; +} + + + +void +inkscape_switch_desktops_next () +{ + inkscape_next_desktop()->presentWindow(); +} + + + +void +inkscape_switch_desktops_prev () +{ + inkscape_prev_desktop()->presentWindow(); +} + + + +void +inkscape_dialogs_hide () +{ + if (Inkscape::NSApplication::Application::getNewGui()) + Inkscape::NSApplication::Editor::hideDialogs(); + else + { + g_signal_emit (G_OBJECT (inkscape), inkscape_signals[DIALOGS_HIDE], 0); + inkscape->dialogs_toggle = FALSE; + } +} + + + +void +inkscape_dialogs_unhide () +{ + if (Inkscape::NSApplication::Application::getNewGui()) + Inkscape::NSApplication::Editor::unhideDialogs(); + else + { + g_signal_emit (G_OBJECT (inkscape), inkscape_signals[DIALOGS_UNHIDE], 0); + inkscape->dialogs_toggle = TRUE; + } +} + + + +void +inkscape_dialogs_toggle () +{ + if (inkscape->dialogs_toggle) { + inkscape_dialogs_hide (); + } else { + inkscape_dialogs_unhide (); + } +} + +void +inkscape_external_change () +{ + g_return_if_fail (inkscape != NULL); + + g_signal_emit (G_OBJECT (inkscape), inkscape_signals[EXTERNAL_CHANGE], 0); +} + +/** + * fixme: These need probably signals too + */ +void +inkscape_add_document (SPDocument *document) +{ + g_return_if_fail (document != NULL); + + if (!Inkscape::NSApplication::Application::getNewGui()) + { + g_assert (!g_slist_find (inkscape->documents, document)); + inkscape->documents = g_slist_append (inkscape->documents, document); + } + else + { + Inkscape::NSApplication::Editor::addDocument (document); + } +} + + + +void +inkscape_remove_document (SPDocument *document) +{ + g_return_if_fail (document != NULL); + + if (!Inkscape::NSApplication::Application::getNewGui()) + { + g_assert (g_slist_find (inkscape->documents, document)); + inkscape->documents = g_slist_remove (inkscape->documents, document); + } + else + { + Inkscape::NSApplication::Editor::removeDocument (document); + } + + return; +} + +SPDesktop * +inkscape_active_desktop (void) +{ + if (Inkscape::NSApplication::Application::getNewGui()) + return Inkscape::NSApplication::Editor::getActiveDesktop(); + + if (inkscape->desktops == NULL) { + return NULL; + } + + return (SPDesktop *) inkscape->desktops->data; +} + +SPDocument * +inkscape_active_document (void) +{ + if (Inkscape::NSApplication::Application::getNewGui()) + return Inkscape::NSApplication::Editor::getActiveDocument(); + + if (SP_ACTIVE_DESKTOP) { + return SP_DT_DOCUMENT (SP_ACTIVE_DESKTOP); + } + + return NULL; +} + +bool inkscape_is_sole_desktop_for_document(SPDesktop const &desktop) { + SPDocument const* document = desktop.doc(); + if (!document) { + return false; + } + for ( GSList *iter = inkscape->desktops ; iter ; iter = iter->next ) { + SPDesktop *other_desktop=(SPDesktop *)iter->data; + SPDocument *other_document=other_desktop->doc(); + if ( other_document == document && other_desktop != &desktop ) { + return false; + } + } + return true; +} + +SPEventContext * +inkscape_active_event_context (void) +{ + if (SP_ACTIVE_DESKTOP) { + return SP_DT_EVENTCONTEXT (SP_ACTIVE_DESKTOP); + } + + return NULL; +} + + + +/*##################### +# HELPERS +#####################*/ + +static bool +inkscape_init_config (Inkscape::XML::Document *doc, const gchar *config_name, const gchar *skeleton, + unsigned int skel_size, + const gchar *e_mkdir, + const gchar *e_notdir, + const gchar *e_ccf, + const gchar *e_cwf, + const gchar *warn) +{ + gchar *dn = profile_path(NULL); + bool use_gui = (Inkscape::NSApplication::Application::getNewGui())? Inkscape::NSApplication::Application::getUseGui() : inkscape->use_gui; + if (!Inkscape::IO::file_test(dn, G_FILE_TEST_EXISTS)) { + if (Inkscape::IO::mkdir_utf8name(dn)) + { + if (use_gui) { + // Cannot create directory + gchar *safeDn = Inkscape::IO::sanitizeString(dn); + GtkWidget *w = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_WARNING, GTK_BUTTONS_OK, e_mkdir, safeDn, warn); + gtk_dialog_run (GTK_DIALOG (w)); + gtk_widget_destroy (w); + g_free(safeDn); + g_free (dn); + return false; + } else { + g_warning(e_mkdir, dn, warn); + g_free (dn); + return false; + } + } + } else if (!Inkscape::IO::file_test(dn, G_FILE_TEST_IS_DIR)) { + if (use_gui) { + // Not a directory + gchar *safeDn = Inkscape::IO::sanitizeString(dn); + GtkWidget *w = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_WARNING, GTK_BUTTONS_OK, e_notdir, safeDn, warn); + gtk_dialog_run (GTK_DIALOG (w)); + gtk_widget_destroy (w); + g_free( safeDn ); + g_free (dn); + return false; + } else { + g_warning(e_notdir, dn, warn); + g_free(dn); + return false; + } + } + g_free (dn); + + gchar *fn = profile_path(config_name); + + Inkscape::IO::dump_fopen_call(fn, "H"); + FILE *fh = Inkscape::IO::fopen_utf8name(fn, "w"); + if (!fh) { + if (use_gui) { + /* Cannot create file */ + gchar *safeFn = Inkscape::IO::sanitizeString(fn); + GtkWidget *w = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_WARNING, GTK_BUTTONS_OK, e_ccf, safeFn, warn); + gtk_dialog_run (GTK_DIALOG (w)); + gtk_widget_destroy (w); + g_free(safeFn); + g_free (fn); + return false; + } else { + g_warning(e_ccf, fn, warn); + g_free(fn); + return false; + } + } + if ( fwrite(skeleton, 1, skel_size, fh) != skel_size ) { + if (use_gui) { + /* Cannot create file */ + gchar *safeFn = Inkscape::IO::sanitizeString(fn); + GtkWidget *w = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_WARNING, GTK_BUTTONS_OK, e_cwf, safeFn, warn); + gtk_dialog_run (GTK_DIALOG (w)); + gtk_widget_destroy (w); + g_free(safeFn); + g_free (fn); + fclose(fh); + return false; + } else { + g_warning(e_cwf, fn, warn); + g_free(fn); + fclose(fh); + return false; + } + } + + g_free(fn); + fclose(fh); + return true; +} + +void +inkscape_refresh_display (Inkscape::Application *inkscape) +{ + for (GSList *l = inkscape->desktops; l != NULL; l = l->next) { + (static_cast(l->data))->requestRedraw(); + } +} + + +/** + * Handler for Inkscape's Exit verb. This emits the shutdown signal, + * saves the preferences if appropriate, and quits. + */ +void +inkscape_exit (Inkscape::Application *inkscape) +{ + g_assert (INKSCAPE); + + //emit shutdown signal so that dialogs could remember layout + g_signal_emit (G_OBJECT (INKSCAPE), inkscape_signals[SHUTDOWN_SIGNAL], 0); + + Inkscape::Preferences::save(); + gtk_main_quit (); +} + +gchar * +homedir_path(const char *filename) +{ + static const gchar *homedir = NULL; + if (!homedir) { + homedir = g_get_home_dir(); + gchar* utf8Path = g_filename_to_utf8( homedir, -1, NULL, NULL, NULL ); + if ( utf8Path ) + { + homedir = utf8Path; + if (!g_utf8_validate(homedir, -1, NULL)) { + g_warning( "g_get_home_dir() post A IS NOT UTF-8" ); + } + } + } + if (!homedir) { + gchar * path = g_path_get_dirname(INKSCAPE->argv0); + gchar* utf8Path = g_filename_to_utf8( path, -1, NULL, NULL, NULL ); + g_free(path); + if ( utf8Path ) + { + homedir = utf8Path; + if (!g_utf8_validate(homedir, -1, NULL)) { + g_warning( "g_get_home_dir() post B IS NOT UTF-8" ); + } + } + } + return g_build_filename(homedir, filename, NULL); +} + + +/** + * Get, or guess, or decide the location where the preferences.xml + * file should be located. + */ +gchar * +profile_path(const char *filename) +{ + static const gchar *prefdir = NULL; + if (!prefdir) { +#ifdef HAS_SHGetSpecialFolderLocation + // prefer c:\Documents and Settings\UserName\Application Data\ to + // c:\Documents and Settings\userName\; + if (!prefdir) { + ITEMIDLIST *pidl = 0; + if ( SHGetSpecialFolderLocation( NULL, CSIDL_APPDATA, &pidl ) == NOERROR ) { + gchar * utf8Path = NULL; + + if ( PrintWin32::is_os_wide() ) { + wchar_t pathBuf[MAX_PATH+1]; + g_assert(sizeof(wchar_t) == sizeof(gunichar2)); + + if ( SHGetPathFromIDListW( pidl, pathBuf ) ) { + utf8Path = g_utf16_to_utf8( (gunichar2*)(&pathBuf[0]), -1, NULL, NULL, NULL ); + } + } else { + char pathBuf[MAX_PATH+1]; + + if ( SHGetPathFromIDListA( pidl, pathBuf ) ) { + utf8Path = g_filename_to_utf8( pathBuf, -1, NULL, NULL, NULL ); + } + } + + if ( utf8Path ) { + if (!g_utf8_validate(utf8Path, -1, NULL)) { + g_warning( "SHGetPathFromIDList%c() resulted in invalid UTF-8", (PrintWin32::is_os_wide() ? 'W' : 'A') ); + g_free( utf8Path ); + utf8Path = 0; + } else { + prefdir = utf8Path; + } + } + + + /* not compiling yet... + + // Remember to free the list pointer + IMalloc * imalloc = 0; + if ( SHGetMalloc(&imalloc) == NOERROR) { + imalloc->lpVtbl->Free( imalloc, pidl ); + imalloc->lpVtbl->Release( imalloc ); + } + */ + } + } +#endif + if (!prefdir) { + prefdir = homedir_path(NULL); + } + } + return g_build_filename(prefdir, INKSCAPE_PROFILE_DIR, filename, NULL); +} + +Inkscape::XML::Node * +inkscape_get_menus (Inkscape::Application * inkscape) +{ + Inkscape::XML::Node *repr = sp_repr_document_root (inkscape->menus); + g_assert (!(strcmp (repr->name(), "inkscape"))); + return repr->firstChild(); +} + + + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/inkscape.h b/src/inkscape.h new file mode 100644 index 000000000..9907f320f --- /dev/null +++ b/src/inkscape.h @@ -0,0 +1,86 @@ +#ifndef __INKSCAPE_H__ +#define __INKSCAPE_H__ + +/* + * Interface to main application + * + * Authors: + * Lauris Kaplinski + * + * Copyright (C) 1999-2003 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "forward.h" + +namespace Inkscape { +namespace XML { +class Node; +class Document; +} +} + + +#define INKSCAPE inkscape_get_instance() + +void inkscape_application_init (const gchar *argv0, gboolean use_gui); + +bool inkscape_load_config (const gchar *filename, Inkscape::XML::Document *config, const gchar *skeleton, unsigned int skel_size, const gchar *e_notreg, const gchar *e_notxml, const gchar *e_notsp, const gchar *warn); +Inkscape::XML::Node *inkscape_get_repr (Inkscape::Application *inkscape, const gchar *key); + +/* Menus */ +bool inkscape_load_menus (Inkscape::Application * inkscape); +bool inkscape_save_menus (Inkscape::Application * inkscape); +Inkscape::XML::Node *inkscape_get_menus (Inkscape::Application * inkscape); + +Inkscape::Application *inkscape_get_instance(); + +#define SP_ACTIVE_EVENTCONTEXT inkscape_active_event_context () +SPEventContext * inkscape_active_event_context (void); + +#define SP_ACTIVE_DOCUMENT inkscape_active_document () +SPDocument * inkscape_active_document (void); + +#define SP_ACTIVE_DESKTOP inkscape_active_desktop () +SPDesktop * inkscape_active_desktop (void); + +bool inkscape_is_sole_desktop_for_document(SPDesktop const &desktop); + +gchar *homedir_path(const char *filename); +gchar *profile_path(const char *filename); + +void inkscape_switch_desktops_next (); +void inkscape_switch_desktops_prev (); + +void inkscape_dialogs_hide (); +void inkscape_dialogs_unhide (); +void inkscape_dialogs_toggle (); + +void inkscape_external_change (); +void inkscape_subselection_changed (SPDesktop *desktop); + +/* + * fixme: This has to be rethought + */ + +void inkscape_refresh_display (Inkscape::Application *inkscape); + +/* + * fixme: This also + */ + +void inkscape_exit (Inkscape::Application *inkscape); + +#endif + +/* + 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:textwidth=99 : diff --git a/src/inkscape.rc b/src/inkscape.rc new file mode 100644 index 000000000..25dde0b28 --- /dev/null +++ b/src/inkscape.rc @@ -0,0 +1,3 @@ + +APPLICATION_ICON ICON DISCARDABLE "../inkscape32-16.ico" + diff --git a/src/inkscape_version.h.mingw b/src/inkscape_version.h.mingw new file mode 100644 index 000000000..c0f2937ab --- /dev/null +++ b/src/inkscape_version.h.mingw @@ -0,0 +1 @@ +#define INKSCAPE_VERSION "0.43+devel" diff --git a/src/inkview.cpp b/src/inkview.cpp new file mode 100644 index 000000000..bd1ef6e31 --- /dev/null +++ b/src/inkview.cpp @@ -0,0 +1,491 @@ +#define __SPSVGVIEW_C__ + +/* + * Inkscape - an ambitious vector drawing program + * + * Authors: + * Lauris Kaplinski + * Frank Felfe + * Davide Puricelli + * Mitsuru Oka + * Masatake YAMATO + * F.J.Franklin + * Michael Meeks + * Chema Celorio + * Pawel Palucha + * ... and various people who have worked with various projects + * + * Copyright (C) 1999-2002 authors + * Copyright (C) 2001-2002 Ximian, Inc. + * + * Inkscape authors: + * Johan Ceuppens + * + * Copyright (C) 2004 Inkscape authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "gc-core.h" +#include "preferences.h" + +#include +#include "document.h" +#include "svg-view.h" +#include "svg-view-widget.h" + +#ifdef WITH_INKJAR +#include "inkjar/jar.h" +#endif + +#include "inkscape-private.h" + +Inkscape::Application *inkscape; + +#include + +#ifndef HAVE_BIND_TEXTDOMAIN_CODESET +#define bind_textdomain_codeset(p,c) +#endif + +struct SPSlideShow { + char **slides; + int size; + int length; + int current; + SPDocument *doc; + GtkWidget *view; + GtkWindow *window; + bool fullscreen; +}; + +static GtkWidget *sp_svgview_control_show (struct SPSlideShow *ss); +static void sp_svgview_show_next (struct SPSlideShow *ss); +static void sp_svgview_show_prev (struct SPSlideShow *ss); +static void sp_svgview_goto_first (struct SPSlideShow *ss); +static void sp_svgview_goto_last (struct SPSlideShow *ss); + +static int sp_svgview_show_next_cb (GtkWidget *widget, void *data); +static int sp_svgview_show_prev_cb (GtkWidget *widget, void *data); +static int sp_svgview_goto_first_cb (GtkWidget *widget, void *data); +static int sp_svgview_goto_last_cb (GtkWidget *widget, void *data); +#ifdef WITH_INKJAR +static bool is_jar(char const *filename); +#endif +static void usage(); + +static GtkWidget *ctrlwin = NULL; + +/// Dummy functions to keep linker happy +int sp_main_gui (int, char const**) { return 0; } +int sp_main_console (int, char const**) { return 0; } + +static int +sp_svgview_main_delete (GtkWidget *widget, GdkEvent *event, struct SPSlideShow *ss) +{ + gtk_main_quit (); + return FALSE; +} + +static int +sp_svgview_main_key_press (GtkWidget *widget, GdkEventKey *event, struct SPSlideShow *ss) +{ + switch (event->keyval) { + case GDK_Up: + sp_svgview_goto_first(ss); + break; + case GDK_Down: + sp_svgview_goto_last(ss); + break; + case GDK_F11: +#ifdef HAVE_GTK_WINDOW_FULLSCREEN + if (ss->fullscreen) { + gtk_window_unfullscreen ((GtkWindow *) widget); + ss->fullscreen = false; + } else { + gtk_window_fullscreen ((GtkWindow *) widget); + ss->fullscreen = true; + } +#else + std::cout<<"Your GTK+ does not support fullscreen mode. Upgrade to 2.2."<doc)); + return FALSE; +} + +int +main (int argc, const char **argv) +{ + if (argc == 1) { + usage(); + } + + struct SPSlideShow ss; + + GtkWidget *w; + int i; + + bindtextdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR); + bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); + textdomain (GETTEXT_PACKAGE); + + LIBXML_TEST_VERSION + + Inkscape::GC::init(); + Inkscape::Preferences::loadSkeleton(); + + gtk_init (&argc, (char ***) &argv); + +#ifdef lalaWITH_MODULES + g_warning ("Have to autoinit modules (lauris)"); + sp_modulesys_init(); +#endif /* WITH_MODULES */ + + /* We must set LC_NUMERIC to default, or otherwise */ + /* we'll end with localised SVG files :-( */ + + setlocale (LC_NUMERIC, "C"); + + ss.size = 32; + ss.length = 0; + ss.current = 0; + ss.slides = nr_new (char *, ss.size); + ss.current = 0; + ss.doc = NULL; + ss.view = NULL; + ss.fullscreen = false; + + inkscape = (Inkscape::Application *)g_object_new (SP_TYPE_INKSCAPE, NULL); + Inkscape::Preferences::load(); + + for (i = 1; i < argc; i++) { + struct stat st; + if (stat (argv[i], &st) + || !S_ISREG (st.st_mode) + || (st.st_size < 64)) { + fprintf(stderr, "could not open file %s\n", argv[i]); + } else { + +#ifdef WITH_INKJAR + if (is_jar(argv[i])) { + Inkjar::JarFileReader jar_file_reader(argv[i]); + for (;;) { + GByteArray *gba = jar_file_reader.get_next_file(); + if (gba == NULL) { + char *c_ptr; + gchar *last_filename = jar_file_reader.get_last_filename(); + if (last_filename == NULL) + break; + if ((c_ptr = std::strrchr(last_filename, '/')) != NULL) { + if (*(++c_ptr) == '\0') { + g_free(last_filename); + continue; + } + } + } else if (gba->len > 0) { + //::write(1, gba->data, gba->len); + /* Append to list */ + if (ss.length >= ss.size) { + /* Expand */ + ss.size <<= 1; + ss.slides = nr_renew (ss.slides, char *, ss.size); + } + + ss.doc = sp_document_new_from_mem ((const gchar *)gba->data, + gba->len, + TRUE); + gchar *last_filename = jar_file_reader.get_last_filename(); + if (ss.doc) { + ss.slides[ss.length++] = strdup (last_filename); + sp_document_set_uri (ss.doc, strdup(last_filename)); + } + g_byte_array_free(gba, TRUE); + g_free(last_filename); + } else + break; + } + } else { +#endif /* WITH_INKJAR */ + /* Append to list */ + if (ss.length >= ss.size) { + /* Expand */ + ss.size <<= 1; + ss.slides = nr_renew (ss.slides, char *, ss.size); + + } + + ss.slides[ss.length++] = strdup (argv[i]); + ss.doc = sp_document_new (ss.slides[ss.current], TRUE, false); + + if (!ss.doc && ++ss.current >= ss.length) { + /* No loadable documents */ + return 1; + } +#ifdef WITH_INKJAR + } +#endif + } + } + + if(!ss.doc) + return 1; /* none of the slides loadable */ + + w = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_window_set_title (GTK_WINDOW (w), SP_DOCUMENT_NAME (ss.doc)); + gtk_window_set_default_size (GTK_WINDOW (w), + MIN ((int)sp_document_width (ss.doc), (int)gdk_screen_width () - 64), + MIN ((int)sp_document_height (ss.doc), (int)gdk_screen_height () - 64)); + gtk_window_set_policy (GTK_WINDOW (w), TRUE, TRUE, FALSE); + + g_signal_connect (G_OBJECT (w), "delete_event", (GCallback) sp_svgview_main_delete, &ss); + g_signal_connect (G_OBJECT (w), "key_press_event", (GCallback) sp_svgview_main_key_press, &ss); + + ss.view = sp_svg_view_widget_new (ss.doc); + sp_svg_view_widget_set_resize (SP_SVG_VIEW_WIDGET (ss.view), FALSE, sp_document_width (ss.doc), sp_document_height (ss.doc)); + sp_document_ensure_up_to_date (ss.doc); + sp_document_unref (ss.doc); + gtk_widget_show (ss.view); + gtk_container_add (GTK_CONTAINER (w), ss.view); + + gtk_widget_show (w); + + gtk_main (); + + return 0; +} + +static int +sp_svgview_ctrlwin_delete (GtkWidget *widget, GdkEvent *event, void *data) +{ + ctrlwin = NULL; + return FALSE; +} + +static GtkWidget * +sp_svgview_control_show (struct SPSlideShow *ss) +{ + if (!ctrlwin) { + GtkWidget *t, *b; + ctrlwin = gtk_window_new (GTK_WINDOW_TOPLEVEL); + g_signal_connect (G_OBJECT (ctrlwin), "delete_event", (GCallback) sp_svgview_ctrlwin_delete, NULL); + t = gtk_table_new (1, 4, TRUE); + gtk_container_add ((GtkContainer *) ctrlwin, t); + b = gtk_button_new_from_stock (GTK_STOCK_GOTO_FIRST); + gtk_table_attach ((GtkTable *) t, b, 0, 1, 0, 1, + (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), + (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), + 0, 0); + g_signal_connect ((GObject *) b, "clicked", (GCallback) sp_svgview_goto_first_cb, ss); + b = gtk_button_new_from_stock (GTK_STOCK_GO_BACK); + gtk_table_attach ((GtkTable *) t, b, 1, 2, 0, 1, + (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), + (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), + 0, 0); + g_signal_connect (G_OBJECT(b), "clicked", (GCallback) sp_svgview_show_prev_cb, ss); + b = gtk_button_new_from_stock (GTK_STOCK_GO_FORWARD); + gtk_table_attach ((GtkTable *) t, b, 2, 3, 0, 1, + (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), + (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), + 0, 0); + g_signal_connect (G_OBJECT(b), "clicked", (GCallback) sp_svgview_show_next_cb, ss); + b = gtk_button_new_from_stock (GTK_STOCK_GOTO_LAST); + gtk_table_attach ((GtkTable *) t, b, 3, 4, 0, 1, + (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), + (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), + 0, 0); + g_signal_connect (G_OBJECT(b), "clicked", (GCallback) sp_svgview_goto_last_cb, ss); + gtk_widget_show_all (ctrlwin); + } else { + gtk_window_present ((GtkWindow *) ctrlwin); + } + + return NULL; +} + +static int +sp_svgview_show_next_cb (GtkWidget *widget, void *data) +{ + sp_svgview_show_next(static_cast(data)); + return FALSE; +} + +static int +sp_svgview_show_prev_cb (GtkWidget *widget, void *data) +{ + sp_svgview_show_prev(static_cast(data)); + return FALSE; +} + +static int +sp_svgview_goto_first_cb (GtkWidget *widget, void *data) +{ + sp_svgview_goto_first(static_cast(data)); + return FALSE; +} + +static int +sp_svgview_goto_last_cb (GtkWidget *widget, void *data) +{ + sp_svgview_goto_last(static_cast(data)); + return FALSE; +} + +static void +sp_svgview_show_next (struct SPSlideShow *ss) +{ + SPDocument *doc; + int current; + doc = NULL; + current = ss->current; + while (!doc && (current < ss->length - 1)) { + doc = sp_document_new (ss->slides[++current], TRUE, false); + } + if (doc) { + reinterpret_cast(SP_VIEW_WIDGET_VIEW (ss->view))->setDocument (doc); + sp_document_ensure_up_to_date (doc); + ss->doc = doc; + ss->current = current; + } +} + +static void +sp_svgview_show_prev (struct SPSlideShow *ss) +{ + SPDocument *doc; + int current; + doc = NULL; + current = ss->current; + while (!doc && (current > 0)) { + doc = sp_document_new (ss->slides[--current], TRUE, false); + } + if (doc) { + reinterpret_cast(SP_VIEW_WIDGET_VIEW (ss->view))->setDocument (doc); + sp_document_ensure_up_to_date (doc); + ss->doc = doc; + ss->current = current; + } +} + +static void +sp_svgview_goto_first (struct SPSlideShow *ss) +{ + SPDocument *doc = NULL; + int current = 0; + for ( ; !doc && (current < ss->length); current++) { + doc = sp_document_new (ss->slides[current], TRUE, false); + } + if (doc) { + reinterpret_cast(SP_VIEW_WIDGET_VIEW (ss->view))->setDocument (doc); + sp_document_ensure_up_to_date (doc); + ss->doc = doc; + ss->current = current; + } +} + +static void +sp_svgview_goto_last (struct SPSlideShow *ss) +{ + SPDocument *doc = NULL; + int current = ss->length - 1; + for ( ; !doc && (current >= 0); current--) { + doc = sp_document_new (ss->slides[current], TRUE, false); + } + if (doc) { + reinterpret_cast(SP_VIEW_WIDGET_VIEW (ss->view))->setDocument (doc); + sp_document_ensure_up_to_date (doc); + ss->doc = doc; + ss->current = current; + } +} + +#ifdef WITH_INKJAR +static bool +is_jar(char const *filename) +{ + /* fixme: Check MIME type or something. /usr/share/misc/file/magic suggests that checking for + initial string "PK\003\004" in content should suffice. */ + size_t const filename_len = strlen(filename); + if (filename_len < 5) { + return false; + } + char const *extension = filename + filename_len - 4; + return ((memcmp(extension, ".jar", 4) == 0) || + (memcmp(extension, ".sxw", 4) == 0) ); +} +#endif /* WITH_INKJAR */ + +static void usage() +{ + fprintf(stderr, + "Usage: inkview [FILES ...]\n" + "\twhere FILES are SVG (.svg or .svgz)" +#ifdef WITH_INKJAR + "or archives of SVGs (.sxw, .jar)" +#endif + "\n"); + exit(1); +} + +#ifdef XXX +/* TODO !!! make this temporary stub unnecessary */ +Inkscape::Application *inkscape_get_instance() { return NULL; } +void inkscape_ref (void) {} +void inkscape_unref (void) {} +void inkscape_add_document (SPDocument *document) {} +void inkscape_remove_document (SPDocument *document) {} +Inkscape::XML::Node *inkscape_get_repr (Inkscape::Application *inkscape, const gchar *key) {return NULL;} +#endif + + +/* + 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 : diff --git a/src/interface.cpp b/src/interface.cpp new file mode 100644 index 000000000..69ed8818b --- /dev/null +++ b/src/interface.cpp @@ -0,0 +1,1197 @@ +#define __SP_INTERFACE_C__ + +/** + * Main UI stuff + * + * Authors: + * Lauris Kaplinski + * Frank Felfe + * bulia byak + * + * Copyright (C) 1999-2005 authors + * Copyright (C) 2001-2002 Ximian, Inc. + * Copyright (C) 2004 David Turner + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include "inkscape-private.h" +#include "extension/effect.h" +#include "widgets/icon.h" +#include "prefs-utils.h" +#include "path-prefix.h" + +#include "shortcuts.h" + +#include "document.h" +#include "desktop-handles.h" +#include "file.h" +#include "interface.h" +#include "desktop.h" +#include "object-ui.h" +#include "selection.h" +#include "selection-chemistry.h" +#include "svg-view-widget.h" +#include "widgets/desktop-widget.h" +#include "sp-item-group.h" +#include "sp-namedview.h" + +#include "helper/action.h" +#include "helper/gnome-utils.h" +#include "helper/window.h" + +#include "io/sys.h" +#include "io/stringstream.h" +#include "io/base64stream.h" + +#include "dialogs/dialog-events.h" + +#include "message-context.h" + + +using Inkscape::IO::StringOutputStream; +using Inkscape::IO::Base64OutputStream; + +/* forward declaration */ +static gint sp_ui_delete(GtkWidget *widget, GdkEvent *event, Inkscape::UI::View::View *view); + +/* Drag and Drop */ +typedef enum { + URI_LIST, + SVG_XML_DATA, + SVG_DATA, + PNG_DATA, + JPEG_DATA, + IMAGE_DATA +} ui_drop_target_info; + +static GtkTargetEntry ui_drop_target_entries [] = { + {"text/uri-list", 0, URI_LIST}, + {"image/svg+xml", 0, SVG_XML_DATA}, + {"image/svg", 0, SVG_DATA}, + {"image/png", 0, PNG_DATA}, + {"image/jpeg", 0, JPEG_DATA}, +}; + +static GtkTargetEntry *completeDropTargets = 0; +static int completeDropTargetsCount = 0; + +#define ENTRIES_SIZE(n) sizeof(n)/sizeof(n[0]) +static guint nui_drop_target_entries = ENTRIES_SIZE(ui_drop_target_entries); +static void sp_ui_import_files(gchar *buffer); +static void sp_ui_import_one_file(char const *filename); +static void sp_ui_import_one_file_with_check(gpointer filename, gpointer unused); +static void sp_ui_drag_data_received(GtkWidget *widget, + GdkDragContext *drag_context, + gint x, gint y, + GtkSelectionData *data, + guint info, + guint event_time, + gpointer user_data); +static void sp_ui_menu_item_set_sensitive(SPAction *action, + unsigned int sensitive, + void *data); + +SPActionEventVector menu_item_event_vector = { + {NULL}, + NULL, + NULL, /* set_active */ + sp_ui_menu_item_set_sensitive, /* set_sensitive */ + NULL /* set_shortcut */ +}; + +void +sp_create_window(SPViewWidget *vw, gboolean editable) +{ + GtkWidget *w, *hb; + + g_return_if_fail(vw != NULL); + g_return_if_fail(SP_IS_VIEW_WIDGET(vw)); + + w = sp_window_new("", TRUE); + + if (editable) { + g_object_set_data(G_OBJECT(vw), "window", w); + reinterpret_cast(vw)->window = + static_cast((void*)w); + } + + hb = gtk_hbox_new(FALSE, 0); + gtk_widget_show(hb); + gtk_container_add(GTK_CONTAINER(w), hb); + g_object_set_data(G_OBJECT(w), "hbox", hb); + + /* fixme: */ + if (editable) { + gtk_window_set_default_size((GtkWindow *) w, 640, 480); + g_object_set_data(G_OBJECT(w), "desktop", SP_DESKTOP_WIDGET(vw)->desktop); + g_object_set_data(G_OBJECT(w), "desktopwidget", vw); + g_signal_connect(G_OBJECT(w), "delete_event", G_CALLBACK(sp_ui_delete), vw->view); + g_signal_connect(G_OBJECT(w), "focus_in_event", G_CALLBACK(sp_desktop_widget_set_focus), vw); + } else { + gtk_window_set_policy(GTK_WINDOW(w), TRUE, TRUE, TRUE); + } + + gtk_box_pack_end(GTK_BOX(hb), GTK_WIDGET(vw), TRUE, TRUE, 0); + gtk_widget_show(GTK_WIDGET(vw)); + + + if ( completeDropTargets == 0 || completeDropTargetsCount == 0 ) + { + std::vector types; + + GSList *list = gdk_pixbuf_get_formats(); + while ( list ) { + int i = 0; + GdkPixbufFormat *one = (GdkPixbufFormat*)list->data; + gchar** typesXX = gdk_pixbuf_format_get_mime_types(one); + for ( i = 0; typesXX[i]; i++ ) { + types.push_back(g_strdup(typesXX[i])); + } + g_strfreev(typesXX); + + list = g_slist_next(list); + } + completeDropTargetsCount = nui_drop_target_entries + types.size(); + completeDropTargets = new GtkTargetEntry[completeDropTargetsCount]; + for ( int i = 0; i < (int)nui_drop_target_entries; i++ ) { + completeDropTargets[i] = ui_drop_target_entries[i]; + } + int pos = nui_drop_target_entries; + + for (std::vector::iterator it = types.begin() ; it != types.end() ; it++) { + completeDropTargets[pos].target = *it; + completeDropTargets[pos].flags = 0; + completeDropTargets[pos].info = IMAGE_DATA; + pos++; + } + } + + gtk_drag_dest_set(w, + GTK_DEST_DEFAULT_ALL, + completeDropTargets, + completeDropTargetsCount, + GdkDragAction(GDK_ACTION_COPY | GDK_ACTION_MOVE)); + g_signal_connect(G_OBJECT(w), + "drag_data_received", + G_CALLBACK(sp_ui_drag_data_received), + NULL); + gtk_widget_show(w); + + // needed because the first ACTIVATE_DESKTOP was sent when there was no window yet + inkscape_reactivate_desktop(SP_DESKTOP_WIDGET(vw)->desktop); +} + +void +sp_ui_new_view() +{ + SPDocument *document; + SPViewWidget *dtw; + + document = SP_ACTIVE_DOCUMENT; + if (!document) return; + + dtw = sp_desktop_widget_new(sp_document_namedview(document, NULL)); + g_return_if_fail(dtw != NULL); + + sp_create_window(dtw, TRUE); + sp_namedview_window_from_document(static_cast(dtw->view)); +} + +/* TODO: not yet working */ +/* To be re-enabled (by adding to menu) once it works. */ +void +sp_ui_new_view_preview() +{ + SPDocument *document; + SPViewWidget *dtw; + + document = SP_ACTIVE_DOCUMENT; + if (!document) return; + + dtw = (SPViewWidget *) sp_svg_view_widget_new(document); + g_return_if_fail(dtw != NULL); + sp_svg_view_widget_set_resize(SP_SVG_VIEW_WIDGET(dtw), TRUE, 400.0, 400.0); + + sp_create_window(dtw, FALSE); +} + +/** + * \param widget unused + */ +void +sp_ui_close_view(GtkWidget *widget) +{ + if (SP_ACTIVE_DESKTOP == NULL) { + return; + } + if ((SP_ACTIVE_DESKTOP)->shutdown()) { + return; + } + SP_ACTIVE_DESKTOP->destroyWidget(); +} + + +/** + * sp_ui_close_all + * + * This function is called to exit the program, and iterates through all + * open document view windows, attempting to close each in turn. If the + * view has unsaved information, the user will be prompted to save, + * discard, or cancel. + * + * Returns FALSE if the user cancels the close_all operation, TRUE + * otherwise. + */ +unsigned int +sp_ui_close_all(void) +{ + /* Iterate through all the windows, destroying each in the order they + become active */ + while (SP_ACTIVE_DESKTOP) { + if ((SP_ACTIVE_DESKTOP)->shutdown()) { + /* The user cancelled the operation, so end doing the close */ + return FALSE; + } + SP_ACTIVE_DESKTOP->destroyWidget(); + } + + return TRUE; +} + +static gint +sp_ui_delete(GtkWidget *widget, GdkEvent *event, Inkscape::UI::View::View *view) +{ + return view->shutdown(); +} + +/* + * Some day when the right-click menus are ready to start working + * smarter with the verbs, we'll need to change this NULL being + * sent to sp_action_perform to something useful, or set some kind + * of global "right-clicked position" variable for actions to + * investigate when they're called. + */ +static void +sp_ui_menu_activate(void *object, SPAction *action) +{ + sp_action_perform(action, NULL); +} + +static void +sp_ui_menu_select_action(void *object, SPAction *action) +{ + action->view->tipsMessageContext()->set(Inkscape::NORMAL_MESSAGE, action->tip); +} + +static void +sp_ui_menu_deselect_action(void *object, SPAction *action) +{ + action->view->tipsMessageContext()->clear(); +} + +static void +sp_ui_menu_select(gpointer object, gpointer tip) +{ + Inkscape::UI::View::View *view = static_cast (g_object_get_data(G_OBJECT(object), "view")); + view->tipsMessageContext()->set(Inkscape::NORMAL_MESSAGE, (gchar *)tip); +} + +static void +sp_ui_menu_deselect(gpointer object) +{ + Inkscape::UI::View::View *view = static_cast (g_object_get_data(G_OBJECT(object), "view")); + view->tipsMessageContext()->clear(); +} + +/** + * sp_ui_menuitem_add_icon + * + * Creates and attaches a scaled icon to the given menu item. + * + */ +void +sp_ui_menuitem_add_icon( GtkWidget *item, gchar *icon_name ) +{ + GtkWidget *icon; + + icon = sp_icon_new( GTK_ICON_SIZE_MENU, icon_name ); + gtk_widget_show(icon); + gtk_image_menu_item_set_image((GtkImageMenuItem *) item, icon); +} // end of sp_ui_menu_add_icon + +/** + * sp_ui_menu_append_item + * + * Appends a UI item with specific info for Inkscape/Sodipodi. + * + */ +static GtkWidget * +sp_ui_menu_append_item( GtkMenu *menu, gchar const *stock, + gchar const *label, gchar const *tip, Inkscape::UI::View::View *view, GCallback callback, + gpointer data, gboolean with_mnemonic = TRUE ) +{ + GtkWidget *item; + + if (stock) { + item = gtk_image_menu_item_new_from_stock(stock, NULL); + } else if (label) { + item = (with_mnemonic) + ? gtk_image_menu_item_new_with_mnemonic(label) : + gtk_image_menu_item_new_with_label(label); + } else { + item = gtk_separator_menu_item_new(); + } + + gtk_widget_show(item); + + if (callback) { + g_signal_connect(G_OBJECT(item), "activate", callback, data); + } + + if (tip && view) { + g_object_set_data(G_OBJECT(item), "view", (gpointer) view); + g_signal_connect( G_OBJECT(item), "select", G_CALLBACK(sp_ui_menu_select), (gpointer) tip ); + g_signal_connect( G_OBJECT(item), "deselect", G_CALLBACK(sp_ui_menu_deselect), NULL); + } + + gtk_menu_append(GTK_MENU(menu), item); + + return item; + +} // end of sp_ui_menu_append_item() + +/** +\brief a wrapper around gdk_keyval_name producing (when possible) characters, not names + */ +static gchar const * +sp_key_name(guint keyval) +{ + /* TODO: Compare with the definition of gtk_accel_label_refetch in gtk/gtkaccellabel.c (or + simply use GtkAccelLabel as the TODO comment in sp_ui_shortcut_string suggests). */ + gchar const *n = gdk_keyval_name(gdk_keyval_to_upper(keyval)); + + if (!strcmp(n, "asciicircum")) return "^"; + else if (!strcmp(n, "parenleft" )) return "("; + else if (!strcmp(n, "parenright" )) return ")"; + else if (!strcmp(n, "plus" )) return "+"; + else if (!strcmp(n, "minus" )) return "-"; + else if (!strcmp(n, "asterisk" )) return "*"; + else if (!strcmp(n, "KP_Multiply")) return "*"; + else if (!strcmp(n, "Delete" )) return "Del"; + else if (!strcmp(n, "Page_Up" )) return "PgUp"; + else if (!strcmp(n, "Page_Down" )) return "PgDn"; + else if (!strcmp(n, "grave" )) return "`"; + else if (!strcmp(n, "numbersign" )) return "#"; + else if (!strcmp(n, "bar" )) return "|"; + else if (!strcmp(n, "slash" )) return "/"; + else if (!strcmp(n, "exclam" )) return "!"; + else return n; +} + + +/** + * \param shortcut A GDK keyval OR'd with SP_SHORTCUT_blah_MASK values. + * \param c Points to a buffer at least 256 bytes long. + */ +void +sp_ui_shortcut_string(unsigned const shortcut, gchar *const c) +{ + /* TODO: This function shouldn't exist. Our callers should use GtkAccelLabel instead of + * a generic GtkLabel containing this string, and should call gtk_widget_add_accelerator. + * Will probably need to change sp_shortcut_invoke callers. + * + * The existing gtk_label_new_with_mnemonic call can be replaced with + * g_object_new(GTK_TYPE_ACCEL_LABEL, NULL) followed by + * gtk_label_set_text_with_mnemonic(lbl, str). + */ + static GtkAccelLabelClass const &accel_lbl_cls + = *(GtkAccelLabelClass const *) g_type_class_peek_static(GTK_TYPE_ACCEL_LABEL); + + struct { unsigned test; char const *name; } const modifier_tbl[] = { + { SP_SHORTCUT_SHIFT_MASK, accel_lbl_cls.mod_name_shift }, + { SP_SHORTCUT_CONTROL_MASK, accel_lbl_cls.mod_name_control }, + { SP_SHORTCUT_ALT_MASK, accel_lbl_cls.mod_name_alt } + }; + + gchar *p = c; + gchar *end = p + 256; + + for (unsigned i = 0; i < G_N_ELEMENTS(modifier_tbl); ++i) { + if ((shortcut & modifier_tbl[i].test) + && (p < end)) + { + p += g_snprintf(p, end - p, "%s%s", + modifier_tbl[i].name, + accel_lbl_cls.mod_separator); + } + } + if (p < end) { + p += g_snprintf(p, end - p, "%s", sp_key_name(shortcut & 0xffffff)); + } + end[-1] = '\0'; // snprintf doesn't guarantee to nul-terminate the string. +} + +void +sp_ui_dialog_title_string(Inkscape::Verb *verb, gchar *c) +{ + SPAction *action; + unsigned int shortcut; + gchar *s; + gchar key[256]; + gchar *atitle; + + action = verb->get_action(NULL); + if (!action) + return; + + atitle = sp_action_get_title(action); + + s = g_stpcpy(c, atitle); + + g_free(atitle); + + shortcut = sp_shortcut_get_primary(verb); + if (shortcut) { + s = g_stpcpy(s, " ("); + sp_ui_shortcut_string(shortcut, key); + s = g_stpcpy(s, key); + s = g_stpcpy(s, ")"); + } +} + + +/** + * sp_ui_menu_append_item_from_verb + * + * Appends a custom menu UI from a verb. + * + */ + +static GtkWidget * +sp_ui_menu_append_item_from_verb(GtkMenu *menu, Inkscape::Verb *verb, Inkscape::UI::View::View *view, bool radio = false, GSList *group = NULL) +{ + SPAction *action; + GtkWidget *item; + + if (verb->get_code() == SP_VERB_NONE) { + + item = gtk_separator_menu_item_new(); + + } else { + unsigned int shortcut; + + action = verb->get_action(view); + + if (!action) return NULL; + + shortcut = sp_shortcut_get_primary(verb); + if (shortcut) { + gchar c[256]; + sp_ui_shortcut_string(shortcut, c); + GtkWidget *const hb = gtk_hbox_new(FALSE, 16); + GtkWidget *const name_lbl = gtk_label_new(""); + gtk_label_set_markup_with_mnemonic(GTK_LABEL(name_lbl), action->name); + gtk_misc_set_alignment((GtkMisc *) name_lbl, 0.0, 0.5); + gtk_box_pack_start((GtkBox *) hb, name_lbl, TRUE, TRUE, 0); + GtkWidget *const accel_lbl = gtk_label_new(c); + gtk_misc_set_alignment((GtkMisc *) accel_lbl, 1.0, 0.5); + gtk_box_pack_end((GtkBox *) hb, accel_lbl, FALSE, FALSE, 0); + gtk_widget_show_all(hb); + if (radio) { + item = gtk_radio_menu_item_new (group); + } else { + item = gtk_image_menu_item_new(); + } + gtk_container_add((GtkContainer *) item, hb); + } else { + if (radio) { + item = gtk_radio_menu_item_new (group); + } else { + item = gtk_image_menu_item_new (); + } + GtkWidget *const name_lbl = gtk_label_new(""); + gtk_label_set_markup_with_mnemonic(GTK_LABEL(name_lbl), action->name); + gtk_misc_set_alignment((GtkMisc *) name_lbl, 0.0, 0.5); + gtk_container_add((GtkContainer *) item, name_lbl); + } + + nr_active_object_add_listener((NRActiveObject *)action, (NRObjectEventVector *)&menu_item_event_vector, sizeof(SPActionEventVector), item); + if (!action->sensitive) { + gtk_widget_set_sensitive(item, FALSE); + } + + if (action->image) { + sp_ui_menuitem_add_icon(item, action->image); + } + gtk_widget_set_events(item, GDK_KEY_PRESS_MASK); + g_signal_connect( G_OBJECT(item), "activate", + G_CALLBACK(sp_ui_menu_activate), action ); + + g_signal_connect( G_OBJECT(item), "select", G_CALLBACK(sp_ui_menu_select_action), action ); + g_signal_connect( G_OBJECT(item), "deselect", G_CALLBACK(sp_ui_menu_deselect_action), action ); + } + + gtk_widget_show(item); + gtk_menu_append(GTK_MENU(menu), item); + + return item; + +} // end of sp_ui_menu_append_item_from_verb + + +static void +checkitem_toggled(GtkCheckMenuItem *menuitem, gpointer user_data) +{ + gchar const *pref = (gchar const *) user_data; + Inkscape::UI::View::View *view = (Inkscape::UI::View::View *) g_object_get_data(G_OBJECT(menuitem), "view"); + + gchar const *pref_path; + if (reinterpret_cast(view)->is_fullscreen) + pref_path = g_strconcat("fullscreen.", pref, NULL); + else + pref_path = g_strconcat("window.", pref, NULL); + + gboolean checked = gtk_check_menu_item_get_active(menuitem); + prefs_set_int_attribute(pref_path, "state", checked); + + reinterpret_cast(view)->layoutWidget(); +} + +static gboolean +checkitem_update(GtkWidget *widget, GdkEventExpose *event, gpointer user_data) +{ + GtkCheckMenuItem *menuitem=GTK_CHECK_MENU_ITEM(widget); + + gchar const *pref = (gchar const *) user_data; + Inkscape::UI::View::View *view = (Inkscape::UI::View::View *) g_object_get_data(G_OBJECT(menuitem), "view"); + + gchar const *pref_path; + if (static_cast(view)->is_fullscreen) + pref_path = g_strconcat("fullscreen.", pref, NULL); + else + pref_path = g_strconcat("window.", pref, NULL); + + gint ison = prefs_get_int_attribute_limited(pref_path, "state", 1, 0, 1); + + g_signal_handlers_block_by_func(G_OBJECT(menuitem), (gpointer)(GCallback)checkitem_toggled, user_data); + gtk_check_menu_item_set_active(menuitem, ison); + g_signal_handlers_unblock_by_func(G_OBJECT(menuitem), (gpointer)(GCallback)checkitem_toggled, user_data); + + return FALSE; +} + + +void +sp_ui_menu_append_check_item_from_verb(GtkMenu *menu, Inkscape::UI::View::View *view, gchar const *label, gchar const *tip, gchar const *pref, + void (*callback_toggle)(GtkCheckMenuItem *, gpointer user_data), + gboolean (*callback_update)(GtkWidget *widget, GdkEventExpose *event, gpointer user_data), + Inkscape::Verb *verb) +{ + GtkWidget *item; + + unsigned int shortcut = 0; + SPAction *action = NULL; + + if (verb) { + shortcut = sp_shortcut_get_primary(verb); + action = verb->get_action(view); + } + + if (verb && shortcut) { + gchar c[256]; + sp_ui_shortcut_string(shortcut, c); + + GtkWidget *hb = gtk_hbox_new(FALSE, 16); + + { + GtkWidget *l = gtk_label_new_with_mnemonic(action ? action->name : label); + gtk_misc_set_alignment((GtkMisc *) l, 0.0, 0.5); + gtk_box_pack_start((GtkBox *) hb, l, TRUE, TRUE, 0); + } + + { + GtkWidget *l = gtk_label_new(c); + gtk_misc_set_alignment((GtkMisc *) l, 1.0, 0.5); + gtk_box_pack_end((GtkBox *) hb, l, FALSE, FALSE, 0); + } + + gtk_widget_show_all(hb); + + item = gtk_check_menu_item_new(); + gtk_container_add((GtkContainer *) item, hb); + } else { + GtkWidget *l = gtk_label_new_with_mnemonic(action ? action->name : label); + gtk_misc_set_alignment((GtkMisc *) l, 0.0, 0.5); + item = gtk_check_menu_item_new(); + gtk_container_add((GtkContainer *) item, l); + } +#if 0 + nr_active_object_add_listener((NRActiveObject *)action, (NRObjectEventVector *)&menu_item_event_vector, sizeof(SPActionEventVector), item); + if (!action->sensitive) { + gtk_widget_set_sensitive(item, FALSE); + } +#endif + gtk_widget_show(item); + + gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); + + g_object_set_data(G_OBJECT(item), "view", (gpointer) view); + + g_signal_connect( G_OBJECT(item), "toggled", (GCallback) callback_toggle, (void *) pref); + g_signal_connect( G_OBJECT(item), "expose_event", (GCallback) callback_update, (void *) pref); + + g_signal_connect( G_OBJECT(item), "select", G_CALLBACK(sp_ui_menu_select), (gpointer) (action ? action->tip : tip)); + g_signal_connect( G_OBJECT(item), "deselect", G_CALLBACK(sp_ui_menu_deselect), NULL); +} + +static void +sp_recent_open(GtkWidget *widget, gchar const *uri) +{ + sp_file_open(uri, NULL); +} + +static void +sp_file_new_from_template(GtkWidget *widget, gchar const *uri) +{ + sp_file_new(uri); +} + +void +sp_menu_append_new_templates(GtkWidget *menu, Inkscape::UI::View::View *view) +{ + std::list sources; + sources.push_back( profile_path("templates") ); // first try user's local dir + sources.push_back( g_strdup(INKSCAPE_TEMPLATESDIR) ); // then the system templates dir + + // Use this loop to iterate through a list of possible document locations. + while (!sources.empty()) { + gchar *dirname = sources.front(); + + if ( Inkscape::IO::file_test( dirname, (GFileTest)(G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR) ) ) { + GError *err = 0; + GDir *dir = g_dir_open(dirname, 0, &err); + + if (dir) { + for (gchar const *file = g_dir_read_name(dir); file != NULL; file = g_dir_read_name(dir)) { + if (!g_str_has_suffix(file, ".svg")) + continue; // skip non-svg files + + gchar *basename = g_path_get_basename(file); + if (g_str_has_suffix(basename, ".svg") && g_str_has_prefix(basename, "default.")) + continue; // skip default.*.svg (i.e. default.svg and translations) - it's in the menu already + + gchar const *filepath = g_build_filename(dirname, file, NULL); + gchar *dupfile = g_strndup(file, strlen(file) - 4); + gchar *filename = g_filename_to_utf8(dupfile, -1, NULL, NULL, NULL); + g_free(dupfile); + GtkWidget *item = gtk_menu_item_new_with_label(filename); + g_free(filename); + + gtk_widget_show(item); + // how does "filepath" ever get freed? + g_signal_connect(G_OBJECT(item), + "activate", + G_CALLBACK(sp_file_new_from_template), + (gpointer) filepath); + + if (view) { + // set null tip for now; later use a description from the template file + g_object_set_data(G_OBJECT(item), "view", (gpointer) view); + g_signal_connect( G_OBJECT(item), "select", G_CALLBACK(sp_ui_menu_select), (gpointer) NULL ); + g_signal_connect( G_OBJECT(item), "deselect", G_CALLBACK(sp_ui_menu_deselect), NULL); + } + + gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); + } + g_dir_close(dir); + } + } + + // toss the dirname + g_free(dirname); + sources.pop_front(); + } +} + +void +sp_menu_append_recent_documents(GtkWidget *menu, Inkscape::UI::View::View* /* view */) +{ + gchar const **recent = prefs_get_recent_files(); + if (recent) { + int i; + + for (i = 0; recent[i] != NULL; i += 2) { + gchar const *uri = recent[i]; + gchar const *name = recent[i + 1]; + + GtkWidget *item = gtk_menu_item_new_with_label(name); + gtk_widget_show(item); + g_signal_connect(G_OBJECT(item), + "activate", + G_CALLBACK(sp_recent_open), + (gpointer)uri); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); + } + + g_free(recent); + } else { + GtkWidget *item = gtk_menu_item_new_with_label(_("None")); + gtk_widget_show(item); + gtk_widget_set_sensitive(item, FALSE); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); + } +} + +void +sp_ui_checkboxes_menus(GtkMenu *m, Inkscape::UI::View::View *view) +{ + //sp_ui_menu_append_check_item_from_verb(m, view, _("_Menu"), _("Show or hide the menu bar"), "menu", + // checkitem_toggled, checkitem_update, 0); + sp_ui_menu_append_check_item_from_verb(m, view, _("Commands Bar"), _("Show or hide the Commands bar (under the menu)"), "commands", + checkitem_toggled, checkitem_update, 0); + sp_ui_menu_append_check_item_from_verb(m, view, _("Tool Controls"), _("Show or hide the Tool Controls panel"), "toppanel", + checkitem_toggled, checkitem_update, 0); + sp_ui_menu_append_check_item_from_verb(m, view, _("_Toolbox"), _("Show or hide the main toolbox (on the left)"), "toolbox", + checkitem_toggled, checkitem_update, 0); + sp_ui_menu_append_check_item_from_verb(m, view, NULL, NULL, "rulers", + checkitem_toggled, checkitem_update, Inkscape::Verb::get(SP_VERB_TOGGLE_RULERS)); + sp_ui_menu_append_check_item_from_verb(m, view, NULL, NULL, "scrollbars", + checkitem_toggled, checkitem_update, Inkscape::Verb::get(SP_VERB_TOGGLE_SCROLLBARS)); + sp_ui_menu_append_check_item_from_verb(m, view, _("_Statusbar"), _("Show or hide the statusbar (at the bottom of the window)"), "statusbar", + checkitem_toggled, checkitem_update, 0); + sp_ui_menu_append_check_item_from_verb(m, view, _("_Panels"), _("Show or hide the panels"), "panels", + checkitem_toggled, checkitem_update, 0); +} + +/** \brief This function turns XML into a menu + \param menus This is the XML that defines the menu + \param menu Menu to be added to + \param view The View that this menu is being built for + + This function is realitively simple as it just goes through the XML + and parses the individual elements. In the case of a submenu, it + just calls itself recursively. Because it is only reasonable to have + a couple of submenus, it is unlikely this will go more than two or + three times. + + In the case of an unreconginzed verb, a menu item is made to identify + the verb that is missing, and display that. The menu item is also made + insensitive. +*/ +void +sp_ui_build_dyn_menus(Inkscape::XML::Node *menus, GtkWidget *menu, Inkscape::UI::View::View *view) +{ + if (menus == NULL) return; + if (menu == NULL) return; + GSList *group = NULL; + + for (Inkscape::XML::Node *menu_pntr = menus; + menu_pntr != NULL; + menu_pntr = menu_pntr->next()) { + if (!strcmp(menu_pntr->name(), "submenu")) { + if (!strcmp(menu_pntr->attribute("name"), "Effects") && !prefs_get_int_attribute("extensions", "show-effects-menu", 0)) { + continue; + } + GtkWidget *mitem = gtk_menu_item_new_with_mnemonic(_(menu_pntr->attribute("name"))); + GtkWidget *submenu = gtk_menu_new(); + sp_ui_build_dyn_menus(menu_pntr->firstChild(), submenu, view); + gtk_menu_item_set_submenu(GTK_MENU_ITEM(mitem), GTK_WIDGET(submenu)); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), mitem); + continue; + } + if (!strcmp(menu_pntr->name(), "verb")) { + gchar const *verb_name = menu_pntr->attribute("verb-id"); + Inkscape::Verb *verb = Inkscape::Verb::getbyid(verb_name); + + if (verb != NULL) { + if (menu_pntr->attribute("radio") != NULL) { + GtkWidget *item = sp_ui_menu_append_item_from_verb (GTK_MENU(menu), verb, view, true, group); + group = gtk_radio_menu_item_get_group( GTK_RADIO_MENU_ITEM(item)); + if (menu_pntr->attribute("default") != NULL) { + gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), TRUE); + } + } else { + sp_ui_menu_append_item_from_verb(GTK_MENU(menu), verb, view); + group = NULL; + } + } else { + gchar string[120]; + g_snprintf(string, 120, _("Verb \"%s\" Unknown"), verb_name); + string[119] = '\0'; /* may not be terminated */ + GtkWidget *item = gtk_menu_item_new_with_label(string); + gtk_widget_set_sensitive(item, false); + gtk_widget_show(item); + gtk_menu_append(GTK_MENU(menu), item); + } + continue; + } + if (!strcmp(menu_pntr->name(), "separator") + // This was spelt wrong in the original version + // and so this is for backward compatibility. It can + // probably be dropped after the 0.44 release. + || !strcmp(menu_pntr->name(), "seperator")) { + GtkWidget *item = gtk_separator_menu_item_new(); + gtk_widget_show(item); + gtk_menu_append(GTK_MENU(menu), item); + continue; + } + if (!strcmp(menu_pntr->name(), "template-list")) { + sp_menu_append_new_templates(menu, view); + continue; + } + if (!strcmp(menu_pntr->name(), "recent-file-list")) { + sp_menu_append_recent_documents(menu, view); + continue; + } + if (!strcmp(menu_pntr->name(), "objects-checkboxes")) { + sp_ui_checkboxes_menus(GTK_MENU(menu), view); + continue; + } + } +} + +/** \brief Build the main tool bar + \param view View to build the bar for + + Currently the main tool bar is built as a dynamic XML menu using + \c sp_ui_build_dyn_menus. This function builds the bar, and then + pass it to get items attached to it. +*/ +GtkWidget * +sp_ui_main_menubar(Inkscape::UI::View::View *view) +{ + GtkWidget *mbar = gtk_menu_bar_new(); + + sp_ui_build_dyn_menus(inkscape_get_menus(INKSCAPE), mbar, view); + + return mbar; +} + +static void leave_group(GtkMenuItem *, SPDesktop *desktop) { + desktop->setCurrentLayer(SP_OBJECT_PARENT(desktop->currentLayer())); +} + +static void enter_group(GtkMenuItem *mi, SPDesktop *desktop) { + desktop->setCurrentLayer(reinterpret_cast(g_object_get_data(G_OBJECT(mi), "group"))); + SP_DT_SELECTION(desktop)->clear(); +} + +GtkWidget * +sp_ui_context_menu(Inkscape::UI::View::View *view, SPItem *item) +{ + GtkWidget *m; + SPDesktop *dt; + + dt = static_cast(view); + + m = gtk_menu_new(); + + /* Undo and Redo */ + sp_ui_menu_append_item_from_verb(GTK_MENU(m), Inkscape::Verb::get(SP_VERB_EDIT_UNDO), view); + sp_ui_menu_append_item_from_verb(GTK_MENU(m), Inkscape::Verb::get(SP_VERB_EDIT_REDO), view); + + /* Separator */ + sp_ui_menu_append_item(GTK_MENU(m), NULL, NULL, NULL, NULL, NULL, NULL); + + sp_ui_menu_append_item_from_verb(GTK_MENU(m), Inkscape::Verb::get(SP_VERB_EDIT_CUT), view); + sp_ui_menu_append_item_from_verb(GTK_MENU(m), Inkscape::Verb::get(SP_VERB_EDIT_COPY), view); + sp_ui_menu_append_item_from_verb(GTK_MENU(m), Inkscape::Verb::get(SP_VERB_EDIT_PASTE), view); + + /* Separator */ + sp_ui_menu_append_item(GTK_MENU(m), NULL, NULL, NULL, NULL, NULL, NULL); + + sp_ui_menu_append_item_from_verb(GTK_MENU(m), Inkscape::Verb::get(SP_VERB_EDIT_DUPLICATE), view); + sp_ui_menu_append_item_from_verb(GTK_MENU(m), Inkscape::Verb::get(SP_VERB_EDIT_DELETE), view); + + /* Item menu */ + if (item) { + sp_ui_menu_append_item(GTK_MENU(m), NULL, NULL, NULL, NULL, NULL, NULL); + sp_object_menu((SPObject *) item, dt, GTK_MENU(m)); + } + + /* layer menu */ + SPGroup *group=NULL; + if (item) { + if (SP_IS_GROUP(item)) { + group = SP_GROUP(item); + } else if ( item != dt->currentRoot() && SP_IS_GROUP(SP_OBJECT_PARENT(item)) ) { + group = SP_GROUP(SP_OBJECT_PARENT(item)); + } + } + + if (( group && group != dt->currentLayer() ) || + ( dt->currentLayer() != dt->currentRoot() ) ) { + sp_ui_menu_append_item(GTK_MENU(m), NULL, NULL, NULL, NULL, NULL, NULL); + } + + if ( group && group != dt->currentLayer() ) { + /* TRANSLATORS: #%s is the id of the group e.g. , not a number. */ + gchar *label=g_strdup_printf(_("Enter group #%s"), SP_OBJECT_ID(group)); + GtkWidget *w = gtk_menu_item_new_with_label(label); + g_free(label); + g_object_set_data(G_OBJECT(w), "group", group); + g_signal_connect(G_OBJECT(w), "activate", GCallback(enter_group), dt); + gtk_widget_show(w); + gtk_menu_shell_append(GTK_MENU_SHELL(m), w); + } + + if ( dt->currentLayer() != dt->currentRoot() ) { + if ( SP_OBJECT_PARENT(dt->currentLayer()) != dt->currentRoot() ) { + GtkWidget *w = gtk_menu_item_new_with_label(_("Go to parent")); + g_signal_connect(G_OBJECT(w), "activate", GCallback(leave_group), dt); + gtk_widget_show(w); + gtk_menu_shell_append(GTK_MENU_SHELL(m), w); + + } + } + + return m; +} + +/* Drag and Drop */ +void +sp_ui_drag_data_received(GtkWidget *widget, + GdkDragContext *drag_context, + gint x, gint y, + GtkSelectionData *data, + guint info, + guint event_time, + gpointer user_data) +{ + switch (info) { + case SVG_DATA: + case SVG_XML_DATA: { + gchar *svgdata = (gchar *)data->data; + + SPDocument *doc = SP_ACTIVE_DOCUMENT; + + Inkscape::XML::Document *rnewdoc = sp_repr_read_mem(svgdata, data->length, SP_SVG_NS_URI); + + if (rnewdoc == NULL) { + sp_ui_error_dialog(_("Could not parse SVG data")); + return; + } + + Inkscape::XML::Node *repr = sp_repr_document_root(rnewdoc); + gchar const *style = repr->attribute("style"); + + Inkscape::XML::Node *newgroup = sp_repr_new("svg:g"); + newgroup->setAttribute("style", style); + + for (Inkscape::XML::Node *child = repr->firstChild(); child != NULL; child = child->next()) { + Inkscape::XML::Node *newchild = child->duplicate(); + newgroup->appendChild(newchild); + } + + Inkscape::GC::release(rnewdoc); + + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + // Add it to the current layer + + // Greg's edits to add intelligent positioning of svg drops + SPObject *new_obj = NULL; + new_obj = desktop->currentLayer()->appendChildRepr(newgroup); + + Inkscape::Selection *selection = SP_DT_SELECTION(desktop); + selection->set(SP_ITEM(new_obj)); + // To move the imported object, we must temporarily set the "transform pattern with + // object" option. + { + int const saved_pref = prefs_get_int_attribute("options.transform", "pattern", 1); + prefs_set_int_attribute("options.transform", "pattern", 1); + sp_document_ensure_up_to_date(SP_DT_DOCUMENT(desktop)); + NR::Point m( desktop->point() - selection->bounds().midpoint() ); + sp_selection_move_relative(selection, m); + prefs_set_int_attribute("options.transform", "pattern", saved_pref); + } + + Inkscape::GC::release(newgroup); + sp_document_done(doc); + break; + } + + case URI_LIST: { + gchar *uri = (gchar *)data->data; + sp_ui_import_files(uri); + break; + } + + case PNG_DATA: + case JPEG_DATA: + case IMAGE_DATA: { + char tmp[1024]; + + StringOutputStream outs; + Base64OutputStream b64out(outs); + b64out.setColumnWidth(0); + + SPDocument *doc = SP_ACTIVE_DOCUMENT; + + Inkscape::XML::Node *newImage = sp_repr_new("svg:image"); + + for ( int i = 0; i < data->length; i++ ) { + b64out.put( data->data[i] ); + } + b64out.close(); + + + Glib::ustring str = outs.getString(); + + snprintf( tmp, sizeof(tmp), "data:%s;base64,", gdk_atom_name(data->type) ); + str.insert( 0, tmp ); + newImage->setAttribute("xlink:href", str.c_str()); + + GError *error = NULL; + GdkPixbufLoader *loader = gdk_pixbuf_loader_new_with_mime_type( gdk_atom_name(data->type), &error ); + if ( loader ) { + error = NULL; + if ( gdk_pixbuf_loader_write( loader, data->data, data->length, &error) ) { + GdkPixbuf *pbuf = gdk_pixbuf_loader_get_pixbuf(loader); + if ( pbuf ) { + int width = gdk_pixbuf_get_width(pbuf); + int height = gdk_pixbuf_get_height(pbuf); + snprintf( tmp, sizeof(tmp), "%d", width ); + newImage->setAttribute("width", tmp); + + snprintf( tmp, sizeof(tmp), "%d", height ); + newImage->setAttribute("height", tmp); + } + } + } + + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + + // Add it to the current layer + desktop->currentLayer()->appendChildRepr(newImage); + + Inkscape::GC::release(newImage); + sp_document_done( doc ); + break; + } + } +} + +static void +sp_ui_import_files(gchar *buffer) +{ + GList *list = gnome_uri_list_extract_filenames(buffer); + if (!list) + return; + g_list_foreach(list, sp_ui_import_one_file_with_check, NULL); + g_list_foreach(list, (GFunc) g_free, NULL); + g_list_free(list); +} + +static void +sp_ui_import_one_file_with_check(gpointer filename, gpointer unused) +{ + if (filename) { + if (strlen((char const *)filename) > 2) + sp_ui_import_one_file((char const *)filename); + } +} + +static void +sp_ui_import_one_file(char const *filename) +{ + SPDocument *doc = SP_ACTIVE_DOCUMENT; + if (!doc) return; + + if (filename == NULL) return; + + // Pass off to common implementation + // TODO might need to get the proper type of Inkscape::Extension::Extension + file_import( doc, filename, NULL ); +} + +void +sp_ui_error_dialog(gchar const *message) +{ + GtkWidget *dlg; + gchar *safeMsg = Inkscape::IO::sanitizeString(message); + + dlg = gtk_message_dialog_new(NULL, GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, + GTK_BUTTONS_CLOSE, safeMsg); + sp_transientize(dlg); + gtk_window_set_resizable(GTK_WINDOW(dlg), FALSE); + gtk_dialog_run(GTK_DIALOG(dlg)); + gtk_widget_destroy(dlg); + g_free(safeMsg); +} + +bool +sp_ui_overwrite_file(gchar const *filename) +{ + bool return_value = FALSE; + GtkWidget *dialog; + GtkWidget *hbox; + GtkWidget *boxdata; + gchar *title; + gchar *text; + + if (Inkscape::IO::file_test(filename, G_FILE_TEST_EXISTS)) { + + title = g_strdup_printf(_("Overwrite %s"), filename); + dialog = gtk_dialog_new_with_buttons(title, + NULL, + (GtkDialogFlags)(GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT), + GTK_STOCK_NO, + GTK_RESPONSE_NO, + GTK_STOCK_YES, + GTK_RESPONSE_YES, + NULL); + gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_YES); + + sp_transientize(dialog); + gtk_window_set_resizable(GTK_WINDOW(dialog), FALSE); + + hbox = gtk_hbox_new(FALSE, 5); + boxdata = gtk_image_new_from_stock(GTK_STOCK_DIALOG_QUESTION, GTK_ICON_SIZE_DIALOG); + gtk_widget_show(boxdata); + gtk_box_pack_start(GTK_BOX(hbox), boxdata, TRUE, TRUE, 5); + text = g_strdup_printf(_("The file %s already exists. Do you want to overwrite that file with the current document?"), filename); + boxdata = gtk_label_new(text); + gtk_label_set_line_wrap(GTK_LABEL(boxdata), TRUE); + gtk_widget_show(boxdata); + gtk_box_pack_start(GTK_BOX(hbox), boxdata, FALSE, FALSE, 5); + gtk_widget_show(hbox); + gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, TRUE, TRUE, 5); + + if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_YES) { + return_value = TRUE; + } else { + return_value = FALSE; + } + + gtk_widget_destroy(dialog); + g_free(title); + g_free(text); + } else { + return_value = TRUE; + } + + return return_value; +} + +static void +sp_ui_menu_item_set_sensitive(SPAction *action, unsigned int sensitive, void *data) +{ + return gtk_widget_set_sensitive(GTK_WIDGET(data), sensitive); +} + +/* + 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:textwidth=99 : diff --git a/src/interface.h b/src/interface.h new file mode 100644 index 000000000..099fdd277 --- /dev/null +++ b/src/interface.h @@ -0,0 +1,85 @@ +#ifndef __SP_INTERFACE_H__ +#define __SP_INTERFACE_H__ + +/* + * Main UI stuff + * + * Authors: + * Lauris Kaplinski + * Frank Felfe + * + * Copyright (C) 1999-2002 authors + * Copyright (C) 2001-2002 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include + +#include "forward.h" + + +/** + * Create a new document window. + */ +void sp_create_window (SPViewWidget *vw, gboolean editable); + +/** + * + */ +void sp_ui_close_view (GtkWidget *widget); + +/** + * + */ +void sp_ui_new_view (void); +void sp_ui_new_view_preview (void); + +/** + * + */ +unsigned int sp_ui_close_all (void); + +/** + * + */ +GtkWidget *sp_ui_main_menubar (Inkscape::UI::View::View *view); + +/** + * + */ +GtkWidget *sp_ui_context_menu (Inkscape::UI::View::View *v, SPItem *item); + + +/** + * + */ +void sp_menu_append_recent_documents (GtkWidget *menu); + + +/** + * + */ +void sp_ui_dialog_title_string (Inkscape::Verb * verb, gchar* c); + + +/** + * + */ +void sp_ui_error_dialog (const gchar * message); +bool sp_ui_overwrite_file (const gchar * filename); + +void sp_ui_shortcut_string (unsigned int shortcut, gchar* c); + +#endif + +/* + 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:textwidth=99 : diff --git a/src/io/.cvsignore b/src/io/.cvsignore new file mode 100644 index 000000000..a437e318b --- /dev/null +++ b/src/io/.cvsignore @@ -0,0 +1,5 @@ +.deps +.dirstamp +.libs +makefile +streamtest diff --git a/src/io/Makefile.tst b/src/io/Makefile.tst new file mode 100644 index 000000000..1d6789fd2 --- /dev/null +++ b/src/io/Makefile.tst @@ -0,0 +1,47 @@ +############################################## +# +# Test makefile for InkscapeStreams +# +############################################## + + +CC = gcc +CXX = g++ + + +INC = -I. -I.. + +XSLT_CFLAGS = `pkg-config --cflags libxslt` +XSLT_LIBS = `pkg-config --libs libxslt` + +GLIBMM_CFLAGS = `pkg-config --cflags glibmm-2.4` +GLIBMM_LIBS = `pkg-config --libs glibmm-2.4` + +CFLAGS = -g $(GLIBMM_CFLAGS) $(XSLT_CFLAGS) +LIBS = $(GLIBMM_LIBS) $(XSLT_LIBS) ../uri.o -lz + +OBJ = \ +inkscapestream.o \ +base64stream.o \ +gzipstream.o \ +stringstream.o \ +uristream.o \ +xsltstream.o \ +ftos.o + +all: streamtest + +streamtest: inkscapestream.h libstream.a streamtest.o + $(CXX) -o streamtest streamtest.o libstream.a $(LIBS) + +libstream.a: $(OBJ) + ar crv libstream.a $(OBJ) + + +.cpp.o: + $(CXX) $(CFLAGS) $(INC) -c -o $@ $< + +clean: + -$(RM) *.o *.a + -$(RM) streamtest + diff --git a/src/io/Makefile_insert b/src/io/Makefile_insert new file mode 100644 index 000000000..57978d678 --- /dev/null +++ b/src/io/Makefile_insert @@ -0,0 +1,29 @@ +## Makefile.am fragment sourced by src/Makefile.am. + +io/all: io/libio.a + +io/clean: + rm -f io/libio.a $(io_libio_a_OBJECTS) + +io_libio_a_SOURCES = \ + io/base64stream.h \ + io/base64stream.cpp \ + io/ftos.cpp \ + io/ftos.h \ + io/gzipstream.cpp \ + io/gzipstream.h \ + io/inkscapestream.cpp \ + io/inkscapestream.h \ + io/simple-sax.cpp \ + io/simple-sax.h \ + io/stringstream.cpp \ + io/stringstream.h \ + io/sys.h \ + io/sys.cpp \ + io/uristream.cpp \ + io/uristream.h \ + io/xsltstream.cpp \ + io/xsltstream.h + +#io_streamtest_SOURCES = io/streamtest.cpp +#io_streamtest_LDADD = $(all_libs) diff --git a/src/io/base64stream.cpp b/src/io/base64stream.cpp new file mode 100644 index 000000000..e9f8fe2a2 --- /dev/null +++ b/src/io/base64stream.cpp @@ -0,0 +1,315 @@ +/** + * Base64-enabled input and output streams + * + * This class allows easy encoding and decoding + * of Base64 data with a stream interface, hiding + * the implementation from the user. + * + * Authors: + * Bob Jamison + * + * Copyright (C) 2004 Inkscape.org + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "base64stream.h" + + + +namespace Inkscape +{ +namespace IO +{ + +//######################################################################### +//# B A S E 6 4 I N P U T S T R E A M +//######################################################################### + +static int base64decode[] = +{ +/*00*/ -1, -1, -1, -1, -1, -1, -1, -1, +/*08*/ -1, -1, -1, -1, -1, -1, -1, -1, +/*10*/ -1, -1, -1, -1, -1, -1, -1, -1, +/*18*/ -1, -1, -1, -1, -1, -1, -1, -1, +/*20*/ -1, -1, -1, -1, -1, -1, -1, -1, +/*28*/ -1, -1, -1, 62, -1, -1, -1, 63, +/*30*/ 52, 53, 54, 55, 56, 57, 58, 59, +/*38*/ 60, 61, -1, -1, -1, -1, -1, -1, +/*40*/ -1, 0, 1, 2, 3, 4, 5, 6, +/*48*/ 7, 8, 9, 10, 11, 12, 13, 14, +/*50*/ 15, 16, 17, 18, 19, 20, 21, 22, +/*58*/ 23, 24, 25, -1, -1, -1, -1, -1, +/*60*/ -1, 26, 27, 28, 29, 30, 31, 32, +/*68*/ 33, 34, 35, 36, 37, 38, 39, 40, +/*70*/ 41, 42, 43, 44, 45, 46, 47, 48, +/*78*/ 49, 50, 51, -1, -1, -1, -1, -1 +}; + + +/** + * + */ +Base64InputStream::Base64InputStream(InputStream &sourceStream) + : BasicInputStream(sourceStream) +{ + outCount = 0; + padCount = 0; + closed = false; + done = false; +} + +/** + * + */ +Base64InputStream::~Base64InputStream() +{ + close(); +} + +/** + * Returns the number of bytes that can be read (or skipped over) from + * this input stream without blocking by the next caller of a method for + * this input stream. + */ +int Base64InputStream::available() +{ + if (closed ) + return 0; + int len = source.available() * 2 / 3; + return len; +} + + +/** + * Closes this input stream and releases any system resources + * associated with the stream. + */ +void Base64InputStream::close() +{ + if (closed) + return; + source.close(); + closed = true; +} + +/** + * Reads the next byte of data from the input stream. -1 if EOF + */ +int Base64InputStream::get() +{ + if (closed) + return -1; + + if (outCount - padCount > 0) + { + return outBytes[3-(outCount--)]; + } + + if (done) + return -1; + + int inBytes[4]; + int inCount = 0; + while (inCount < 4) + { + int ch = source.get(); + if (ch < 0) + { + while (inCount < 4) //pad if needed + { + inBytes[inCount++] = 0; + padCount++; + } + done = true; + break; + } + if (isspace(ch)) //ascii whitespace + { + //nothing + } + else if (ch == '=') //padding + { + inBytes[inCount++] = 0; + padCount++; + } + else + { + int byteVal = base64decode[ch & 0x7f]; + //printf("char:%c %d\n", ch, byteVal); + if (byteVal < 0) + { + //Bad lookup value + } + inBytes[inCount++] = byteVal; + } + } + + outBytes[0] = ((inBytes[0]<<2) & 0xfc) | ((inBytes[1]>>4) & 0x03); + outBytes[1] = ((inBytes[1]<<4) & 0xf0) | ((inBytes[2]>>2) & 0x0f); + outBytes[2] = ((inBytes[2]<<6) & 0xc0) | ((inBytes[3] ) & 0x3f); + + outCount = 3; + + //try again + if (outCount - padCount > 0) + { + return outBytes[3-(outCount--)]; + } + + return -1; + +} + + +//######################################################################### +//# B A S E 6 4 O U T P U T S T R E A M +//######################################################################### + +static char *base64encode = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +/** + * + */ +Base64OutputStream::Base64OutputStream(OutputStream &destinationStream) + : BasicOutputStream(destinationStream) +{ + column = 0; + columnWidth = 72; + outBuf = 0L; + bitCount = 0; +} + +/** + * + */ +Base64OutputStream::~Base64OutputStream() +{ + close(); +} + +/** + * Closes this output stream and releases any system resources + * associated with this stream. + */ +void Base64OutputStream::close() +{ + if (closed) + return; + + //get any last bytes (1 or 2) out of the buffer + if (bitCount == 16) + { + outBuf <<= 2; //pad to make 18 bits + + int indx = (int)((outBuf & 0x0003f000L) >> 12); + int obyte = (int)base64encode[indx & 63]; + putCh(obyte); + + indx = (int)((outBuf & 0x00000fc0L) >> 6); + obyte = (int)base64encode[indx & 63]; + putCh(obyte); + + indx = (int)((outBuf & 0x0000003fL) ); + obyte = (int)base64encode[indx & 63]; + putCh(obyte); + + putCh('='); + } + else if (bitCount == 8) + { + outBuf <<= 4; //pad to make 12 bits + + int indx = (int)((outBuf & 0x00000fc0L) >> 6); + int obyte = (int)base64encode[indx & 63]; + putCh(obyte); + + indx = (int)((outBuf & 0x0000003fL) ); + obyte = (int)base64encode[indx & 63]; + putCh(obyte); + + putCh('='); + putCh('='); + } + + if (columnWidth > 0) //if <=0, no newlines + destination.put('\n'); + + destination.close(); + closed = true; +} + +/** + * Flushes this output stream and forces any buffered output + * bytes to be written out. + */ +void Base64OutputStream::flush() +{ + if (closed) + return; + //dont flush here. do it on close() + destination.flush(); +} + +/** + * Private. Put a char to the output stream, checking for line length + */ +void Base64OutputStream::putCh(int ch) +{ + destination.put(ch); + column++; + if (columnWidth > 0 && column >= columnWidth) + { + destination.put('\n'); + column = 0; + } +} + + +/** + * Writes the specified byte to this output stream. + */ +void Base64OutputStream::put(int ch) +{ + if (closed) + { + //probably throw an exception here + return; + } + + outBuf <<= 8; + outBuf |= (ch & 0xff); + bitCount += 8; + if (bitCount >= 24) + { + int indx = (int)((outBuf & 0x00fc0000L) >> 18); + int obyte = (int)base64encode[indx & 63]; + putCh(obyte); + + indx = (int)((outBuf & 0x0003f000L) >> 12); + obyte = (int)base64encode[indx & 63]; + putCh(obyte); + + indx = (int)((outBuf & 0x00000fc0L) >> 6); + obyte = (int)base64encode[indx & 63]; + putCh(obyte); + + indx = (int)((outBuf & 0x0000003fL) ); + obyte = (int)base64encode[indx & 63]; + putCh(obyte); + + bitCount = 0; + outBuf = 0L; + } +} + + + +} // namespace IO +} // namespace Inkscape + + +//######################################################################### +//# E N D O F F I L E +//######################################################################### diff --git a/src/io/base64stream.h b/src/io/base64stream.h new file mode 100644 index 000000000..7bfe73e5f --- /dev/null +++ b/src/io/base64stream.h @@ -0,0 +1,122 @@ +#ifndef __INKSCAPE_IO_BASE64STREAM_H__ +#define __INKSCAPE_IO_BASE64STREAM_H__ + +/** + * Base64-enabled input and output streams + * + * This class allows easy encoding and decoding + * of Base64 data with a stream interface, hiding + * the implementation from the user. + * + * Authors: + * Bob Jamison + * + * Copyright (C) 2004 Inkscape.org + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + + +#include "inkscapestream.h" + + + +namespace Inkscape +{ +namespace IO +{ + +//######################################################################### +//# B A S E 6 4 I N P U T S T R E A M +//######################################################################### + +/** + * This class is for decoding a Base-64 encoded InputStream source + * + */ +class Base64InputStream : public BasicInputStream +{ + +public: + + Base64InputStream(InputStream &sourceStream); + + virtual ~Base64InputStream(); + + virtual int available(); + + virtual void close(); + + virtual int get(); + +private: + + int outBytes[3]; + + int outCount; + + int padCount; + + bool done; + +}; // class Base64InputStream + + + + +//######################################################################### +//# B A S E 6 4 O U T P U T S T R E A M +//######################################################################### + +/** + * This class is for Base-64 encoding data going to the + * destination OutputStream + * + */ +class Base64OutputStream : public BasicOutputStream +{ + +public: + + Base64OutputStream(OutputStream &destinationStream); + + virtual ~Base64OutputStream(); + + virtual void close(); + + virtual void flush(); + + virtual void put(int ch); + + /** + * Sets the maximum line length for base64 output. If + * set to <=0, then there will be no line breaks; + */ + virtual void setColumnWidth(int val) + { columnWidth = val; } + +private: + + void putCh(int ch); + + int column; + + int columnWidth; + + unsigned long outBuf; + + int bitCount; + +}; // class Base64OutputStream + + + + + + + +} // namespace IO +} // namespace Inkscape + + +#endif /* __INKSCAPE_IO_BASE64STREAM_H__ */ diff --git a/src/io/crystalegg.xml b/src/io/crystalegg.xml new file mode 100644 index 000000000..a94220c28 --- /dev/null +++ b/src/io/crystalegg.xml @@ -0,0 +1,769 @@ + + + + + + The Crystal Egg + H. G.Wells + + + + + + + There was, until a year ago, a little and very grimy-looking shop +near Seven Dials over which, in weather-worn yellow lettering, the name +of "C. Cave, Naturalist and Dealer in Antiquities," was inscribed. The +contents of its window were curiously variegated. They comprised some +elephant tusks and an imperfect set of chessmen, beads and weapons, a +box of eyes, two skulls of tigers and one human, several moth-eaten +stuffed monkeys (one holding a lamp), an old-fashioned cabinet, a +flyblown ostrich egg or so, some fishing-tackle, and an extraordinarily +dirty, empty glass fish tank. There was also, at the moment the story +begins, a mass of crystal, worked into the shape of an egg and +brilliantly polished. And at that two people, who stood outside the +window, were looking, one of them a tall, thin clergyman, the other a +black-bearded young man of dusky complexion and unobtrusive costume. The +dusky young man spoke with eager gestulation, and seemed anxious for his +companion to purchase the article. + + + + While they were there, Mr. Cave came into his shop, his beard still +wagging with the bread and butter of his tea. When he saw these men and +the object of their regard, his countenance fell. He glanced guiltily +over his shoulder, and softly shut the door. He was a little old man, +with pale face and peculiar watery blue eyes; his hair was a dirty grey, +and he wore a shabby blue frock-coat, an ancient silk hat, and carpet +slippers very much down at heel. He remained watching the two men as +they talked. The clergyman went deep into his trouser pocket, examined a +handful of money, and showed his teeth in an agreeable smile. Mr. Cave +seemed still more depressed when they came into the shop. + + + + The clergyman, without any ceremony, asked the price of the crystal +egg. Mr. Cave glanced nervously towards the door leading into the +parlour, and said five pounds. The clergyman protested that the price +was high, to his companion as well as to Mr. Cave -- it was, indeed, +very much more than Mr. Cave had intended to ask, when he had stocked +the article -- and an attempt at bargaining ensued. Mr. Cave stepped to +the shop-door, and held it open. "Five pounds is my price," he said, as +though he wished to save himself the trouble of unprofitable discussion. +As he did so, the upper portion of a woman's face appeared above the +blind in the glass upper panel of the door leading into the parlour, and +stared curiously at the two customers. "Five pounds is my price," said +Mr. Cave, with a quiver in his voice. + + + + The swarthy young man had so far remained a spectator, watching Cave +keenly. Now he spoke. "Give him five pounds," he said. The clergyman +glanced at him to see if he were in earnest, and, when he looked at Mr. +Cave again, he saw that the latter's face was white. "It's a lot of +money," said the clergyman, and, diving into his pocket, began counting +his resources. He had little more than thirty shillings, and he appealed +to his companion, with whom he seemed to be on terms of considerable +intimacy. This gave Mr. Cave an opportunity of collecting his thoughts, +and he began to explain in an agitated manner that the crystal was not, +as a matter of fact, entirely free for sale. His two customers were +naturally surprised at this, and inquired why he had not thought of that +before he began to bargain. Mr. Cave became confused, but he stuck to +his story, that the crystal was not in the market that afternoon, that a +probable purchaser of it had already appeared. The two, treating this as +an attempt to raise the price still further, made as if they would leave +the shop. But at this point the parlour door opened, and the owner of +the dark fringe and the little eyes appeared. + + + + She was a coarse-featured, corpulent woman, younger and very much +larger than Mr. Cave; she walked heavily, and her face was flushed. +"That crystal is for sale, she said. "And five pounds is a good enough +price for it. I can't think what you're about, Cave, not to take the +gentleman's offer!" + + + + Mr. Cave, greatly perturbed by the irruption, looked angrily at her +over the rims of his spectacles, and, without excessive assurance, +asserted his right to manage his business in his own way. An altercation +began. The two customers watched the scene with interest and some +amusement, occasionally assisting Mrs. Cave with suggestions. Mr. Cave, +hard driven, persisted in a confused and impossible story of an enquiry +for the crystal that morning, and his agitation became painful. But he +stuck to his point with extraordinary persistence. +It was the young Oriental who ended this curious controversy. He +proposed that they should call again in the course of two days -- so as +to give the alleged enquirer a fair chance. "And then we must insist," +said the clergyman. "Five pounds." Mrs. Cave took it on herself to +apologise for her husband, explaining that he was sometimes "a little +odd," and as the two customers left, the couple prepared for a free +discussion of the incident in all its bearings. + + + + Mrs. Cave talked to her husband with singular directness. The poor +little man, quivering with emotion, muddled himself between his stories, +maintaining on the one hand that he had another customer in view, and on +the other asserting that the crystal was honestly worth ten guineas. +"Why did you ask five pounds?" said his wife. "Do let me manage my +business my own way!" said Mr. Cave. + + + + Mr. Cave had living with him a step-daughter and a step-son, and at +supper that night the transaction was re-discussed. None of them had a +high opinion of Mr. Cave's business methods, and this action seemed a +culminating folly. + + + + "It's my opinion he's refused that crystal before," said the +step-son, a loose-limbed lout of eighteen. + + + + "But Five Pounds!" said the step-daughter, an argumentative young +woman of six-and-twenty. + + + + Mr. Cave's answers were wretched; he could only mumble weak +assertions that he knew his own business best. They drove him from his +half-eaten supper into the shop, to close it for the night, his ears +aflame and tears of vexation behind his spectacles. "Why had he left the +crystal in the window so long? The folly of it!" That was the trouble +closest in his mind. For a time he could see no way of evading sale. + + + + After supper his step-daughter and step-son smartened themselves up +and went out and his wife retired upstairs to reflect upon the business +aspects of the crystal, over a little sugar and lemon and so forth in +hot water. Mr. Cave went into the shop, and stayed there until late, +ostensibly to make ornamental rockeries for gold-fish cases but really +for a private purpose that will be better explained later. The next day +Mrs. Cave found that the crystal had been removed from the window, and +was lying behind some second-hand books on angling. She replaced it in a +conspicuous position. But she did not argue further about it, as a +nervous headache disinclined her from debate. Mr. Cave was always +disinclined. The day passed disagreeably. Mr. Cave was, if anything, +more absent-minded than usual, and uncommonly irritable withal. In the +afternoon, when his wife was taking her customary sleep, he removed the +crystal from the window again. + + + + The next day Mr. Cave had to deliver a consignment of dog-fish at one +of the hospital schools, where they were needed for dissection. In his +absence Mrs. Cave's mind reverted to the topic of the crystal, and the +methods of expenditure suitable to a windfall of five pounds. She had +already devised some very agreeable expedients, among others a dress of +green silk for herself and a trip to Richmond, when a jangling of the +front door bell summoned her into the shop. The customer was an +examination coach who came to complain of the non-delivery of certain +frogs asked for the previous day. Mrs. Cave did not approve of this +particular branch of Mr. Cave's business, and the gentleman, who had +called in a somewhat aggressive mood, retired after a brief exchange of +words -- entirely civil so far as he was concerned. Mrs. Cave's eye then +naturally turned to the window; for the sight of the crystal was an +assurance of the five pounds and of her dreams. What was her surprise to +find it gone! + + + + She went to the place behind the locker on the counter, where she had +discovered it the day before. It was not there; and she immediately +began an eager search about the shop. + + + + When Mr. Cave returned from his business with the dog-fish, about a +quarter to two in the afternoon, he found the shop in some confusion, +and his wife, extremely exasperated and on her knees behind the counter, +routing among his taxidermic material. Her face came up hot and angry +over the counter, as the jangling bell announced his return, and she +forthwith accused him of "hiding it." + + + + "Hid what?" asked Mr. Cave. + + + + "The crystal!" + + + + At that Mr. Cave, apparently much surprised, rushed to the window. +"Isn't it here?" he said. "Great Heavens! what has become of it?" + + + + Just then, Mr. Cave's step-son re-entered the shop from the inner +room -- he had come home a minute or so before Mr. Cave -- and he was +blaspheming freely. He was apprenticed to a second-hand furniture dealer +down the road, but he had his meals at home, and he was naturally +annoyed to find no dinner ready. + + + + But, when he heard of the loss of the crystal, he forgot his meal, +and his anger was diverted from his mother to his step-father. Their +first idea, of course, was that he had hidden it. But Mr. Cave stoutly +denied all knowledge of its fate -- freely offering his bedabbled +affidavit in the matter -- and at last was worked up to the point of +accusing, first, his wife and then his step-son of having taken it with +a view to a private sale. So began an exceedingly acrimonious and +emotional discussion, which ended for Mrs. Cave in a peculiar nervous +condition midway between hysterics and amuck, and caused the step-son to +be half-an-hour late at the furniture establishment in the afternoon. +Mr. Cave took refuge from his wife's emotions in the shop. + + + + In the evening the matter was resumed, with less passion and in a +judicial spirit, under the presidency of the step-daughter. The supper +passed unhappily and culminated in a painful scene. Mr. Cave gave way at +last to extreme exasperation, and went out banging the front door +violently. The rest of the family, having discussed him with the freedom +his absence warranted, hunted the house from garret to cellar, hoping to +light upon the crystal. + + + + The next day the two customers called again. They were received by +Mrs. Cave almost in tears. It transpired that no one could imagine all +that she had stood from Cave at various times in her married pilgrimage. +. . . She also gave a garbled account of the disappearance. The +clergyman and the Oriental laughed silently at one another, and said it +was very extraordinary. As Mrs. Cave seemed disposed to give them the +complete history of her life they made to leave the shop. Thereupon Mrs. +Cave, still clinging to hope, asked for the clergyman's address, so +that, if she could get anything out of Cave, she might communicate it. +The address was duly given, but apparently was afterwards mislaid. Mrs. +Cave can remember nothing about it. + + + + In the evening of that day, the Caves seem to have exhausted their +emotions, and Mr. Cave, who had been out in the afternoon, supped in a +gloomy isolation that contrasted pleasantly with the impassioned +controversy of the previous days. For some time matters were very badly +strained in the Cave household, but neither crystal nor customer +reappeared. + + + + Now, without mincing the matter, we must admit that Mr. Cave was a +liar. He knew perfectly well where the crystal was. It was in the rooms +of Mr. Jacoby Wace, Assistant Demonstrator at St. Catherine's Hospital, +Westbourne Street. It stood on the sideboard partially covered by a +black velvet cloth, and beside a decanter of American whisky. It is from +Mr. Wace, indeed, that the particulars upon which this narrative is +based were derived. Cave had taken off the thing to the hospital hidden +in the dog-fish sack, and there had pressed the young investigator to +keep it for him. Mr. Wace was a little dubious at first. His +relationship to Cave was peculiar. He had a taste for singular +characters, and he had more than once invited the old man to smoke and +drink in his rooms, and to unfold his rather amusing views of life in +general and of his wife in particular. Mr. Wace had encountered Mrs. +Cave, too, on occasions when Mr. Cave was not at home to attend to him. +He knew the constant interference to which Cave was subjected, and +having weighed the story judicially, he decided to give the crystal a +refuge. Mr. Cave promised to explain the reasons for his remarkable +affection for the crystal more fully +on a later occasion, but he spoke distinctly of seeing visions therein. +He called on Mr. Wace the same evening. + + + + He told a complicated story. The crystal he said had come into his +possession with other oddments at the forced sale of another curiosity +dealer's effects, and not knowing what its value might be, he had +ticketed it at ten shillings. It had hung upon his hands at that price +for some months, and he was thinking of "reducing the figure," when he +made a singular discovery. + + + + At that time his health was very bad -- and it must be borne in mind +that, throughout all this experience, his physical condition was one of +ebb -- and he was in considerable distress by reason of the negligence, +the positive ill-treatment even, he received from his wife and +step-children. His wife was vain, extravagant, unfeeling and had a +growing taste for private drinking; his step-daughter was mean and +over-reaching; and his step-son had conceived a violent dislike for him, +and lost no chance of showing it. The requirements of his business +pressed heavily upon him, and Mr. Wace does not think that he was +altogether free from occasional intemperance. He had begun life in a +comfortable position, he was a man of fair education, and he suffered, +for weeks at a stretch, from melancholia and insomnia. Afraid to disturb +his family, he would slip quietly from his wife's side, when his +thoughts became intolerable, and wander about the house. And about three +o'clock one morning, late in August, chance directed him into the shop. + + + + The dirty little place was impenetrably black except in one spot, +where he perceived an unusual glow of light. Approaching this, he +discovered it to be the crystal egg, which was standing on the corner of +the counter towards the window. A thin ray smote through a crack in the +shutters, impinged upon the object, and seemed as it were to fill its +entire interior. + + + + It occurred to Mr. Cave that this was not in accordance with the laws +of optics as he had known them in his younger days. He could understand +the rays being refracted by the crystal and coming to a focus in its +interior, but this diffusion jarred with his physical conceptions. He +approached the crystal nearly, peering into it and round it, with a +transient revival of the scientific curiosity that in his youth had +determined his choice of a calling. He was surprised to find the light +not steady, but writhing within the substance of the egg, as though that +object was a hollow sphere of some luminous vapour. In moving about to +get different points of view, he suddenly found that he had come between +it and the ray, and that the crystal none the less remained luminous. +Greatly astonished, he lifted it out of the light ray and carried it to +the darkest part of the shop. It remained +bright for some four or five minutes, when it slowly faded and went out. +He placed it in the thin streak of daylight, and its luminousness was +almost immediately restored. + + + + So far, at least, Mr. Wace was able to verify the remarkable story of +Mr. Cave. He has himself repeatedly held this crystal in a ray of light +(which had to be of a less diameter than one millimetre). And in a +perfect darkness, such as could be produced by velvet wrapping, the +crystal did undoubtedly appear very faintly phosphorescent. It would +seem, however, that the luminousness was of some exceptional sort, and +not equally visible to all eyes; for Mr. Harbinger -- whose name will be +familiar to the scientific reader in connection with the Pasteur +Institute -- was quite unable to see any light whatever. And Mr. Wace's +own capacity for its appreciation was out of comparison inferior to that +of Mr. Cave's. Even with Mr. Cave the power varied very considerably: +his vision was most vivid during states of extreme weakness and fatigue. + + + + Now, from the outset this light in the crystal exercised a curious +fascination upon Mr. Cave. And it says more for his loneliness of soul +than a volume of pathetic writing could do, that he told no human being +of his curious observations. He seems to have been living in such an +atmosphere of petty spite that to admit the existence of a pleasure +would have been to risk the loss of it. He found that as the dawn +advanced, and the amount of diffused light increased, the crystal became +to all appearance non-luminous. And for some time he was unable to see +anything in it, except at night-time, in dark corners of the shop. + + + + But the use of an old velvet cloth, which he used as a background for +a collection of minerals, occurred to him, and by doubling this, and +putting it over his head and hands, he was able to get a sight of the +luminous movement within the crystal even in the day-time. He was very +cautious lest he should be thus discovered by his wife, and he practised +this occupation only in the afternoons, while she was asleep upstairs, +and then circumspectly in a hollow under the counter. And one day, +turning the crystal about in his hands, he saw something. It came and +went like a flash, but it gave him the impression that the object had +for a moment opened to him the view of a wide and spacious and strange +country; and, turning it about, he did, just as the light faded, see the +same vision again. + + + + Now, it would be tedious and unnecessary to state all the phases of +Mr. Cave's discovery from this point. Suffice that the effect was this: +the crystal, being peered into at an angle of about 137 degrees from the +direction of the illuminating ray, gave a clear and consistent picture +of a wide and peculiar country-side. It was not dream-like at +all: it produced a definite impression of reality, and the better the +light the more real and solid it seemed. It was a moving picture: that +is to say, certain objects moved in it, but slowly in an orderly manner +like real things, and, according as the direction of the lighting and +vision changed, the picture changed also. It must, indeed, have been +like looking through an oval glass at a view, and turning the glass +about to get at different aspects. + + + + Mr. Cave's statements, Mr. Wace assures me, were extremely +circumstantial, and entirely free from any of that emotional quality +that taints hallucinatory impressions. But it must be remembered that +all the efforts of Mr. Wace to see any similar clarity in the faint +opalescence of the crystal were wholly unsuccessful, try as he would. +The difference in intensity of the impressions received by the two men +was very great, and it is quite conceivable that what was a view to Mr. +Cave was a mere blurred nebulosity to Mr. Wace. + + + + The view, as Mr. Cave described it, was invariably of an extensive +plain, and he seemed always to be looking at it from a considerable +height, as if from a tower or a mast. To the east and to the west the +plain was bounded at a remote distance by vast reddish cliffs, which +reminded him of those he had seen in some picture; but what the picture +was Mr. Wace was unable to ascertain. These cliffs passed north and +south -- he could tell the points of the compass by the stars that were +visible of a night -- receding in an almost illimitable perspective and +fading into the mists of the distance before they met. He was nearer the +eastern set of cliffs, on the occasion of his first vision the sun was +rising over them, and black against the sunlight and pale against their +shadow appeared a multitude of soaring forms that Mr. Cave regarded as +birds. A vast range of buildings spread below him; he seemed to be +looking down upon them; and, as they approached the blurred and +refracted edge of the picture, they became indistinct. There were also +trees curious in shape, and in colouring, a deep mossy green and an +exquisite grey, beside a wide and shining canal. And something great and +brilliantly coloured flew across the picture. But the first time Mr. +Cave saw these pictures he saw only in flashes, his hands shook, his +head moved, the vision came and went, and grew foggy and indistinct. And +at first he had the greatest difficulty in finding the picture again +once the direction of it was lost. + + + + His next clear vision, which came about a week after the first, the +interval having yielded nothing but tantalising glimpses and some useful +experience, showed him the view down the length of the valley. The view +was different, but he had a curious persuasion, which his subsequent +observations abundantly confirmed, that he was regarding this strange +world from exactly the same spot, although he was looking +in a different direction. The long facade of the great building, whose +roof he had looked down upon before, was now receding in perspective. He +recognised the roof. In the front of the facade was a terrace of massive +proportions and extraordinary length, and down the middle of the +terrace, at certain intervals, stood huge but very graceful masts, +bearing small shiny objects which reflected the setting sun. The import +of these small objects did not occur to Mr. Cave until some time after, +as he was describing the scene to Mr. Wace. The terrace overhung a +thicket of the most luxuriant and graceful vegetation, and beyond this +was a wide grassy lawn on which certain broad creatures, in form like +beetles but enormously larger, reposed. Beyond this again was a richly +decorated causeway of pinkish stone; and beyond that, and lined with +dense red weeds, and passing up the valley exactly parallel with the +distant cliffs, was a broad and mirror-like expanse of water. The air +seemed full of squadrons of great birds, manoeuvring in stately curves; +and across the river was a multitude of splendid buildings, richly +coloured and glittering with metallic tracery and facets, among a forest +of moss-like and lichenous trees. And suddenly something flapped +repeatedly across the vision, like the fluttering of a jewelled fan or +the beating of a wing, and a face, or rather the upper part of a face +with very large eyes, came as it were close to his own and as if on the +other side of the crystal. Mr. Cave was so startled and so impressed by +the absolute reality of these eyes, that he drew his head back from the +crystal to look behind it. He had become so absorbed in watching that he +was quite surprised to find himself in the cool darkness of his little +shop, with its familiar odour of methyl, mustiness, and decay. And, as +he blinked about him, the glowing crystal faded, and went out. + + + + Such were the first general impressions of Mr. Cave. The story is +curiously direct and circumstantial. From the outset, when the valley +first flashed momentarily on his senses, his imagination was strangely +affected, and, as he began to appreciate the details of the scene he +saw, his wonder rose to the point of a passion. He went about his +business listless and distraught, thinking only of the time when he +should be able to return to his watching. And then a few weeks after his +first sight of the valley came the two customers, the stress and +excitement of their offer, and the narrow escape of the crystal from +sale, as I have already told. + + + + Now, while the thing was Mr. Cave's secret, it remained a mere +wonder, a thing to creep to covertly and peep at, as a child might peep +upon a forbidden garden. But Mr. Wace has, for a young scientific +investigator, a particularly lucid and consecutive habit of mind. +himself, by seeing the phosphorescence with his own eyes, that there +really was a certain evidence for Mr. Cave's statements, he proceeded to +develop the matter systematically. Mr. Cave was only too eager to come +and feast his eyes on this wonderland he saw, and he came every night +from half-past eight until half-past ten, and sometimes, in Mr. Wace's +absence, during the day. On Sunday afternoons, also, he came. From the +outset Mr. Wace made copious notes, and it was due to his scientific +method that the relation between the direction from which the initiating +ray entered the crystal and the orientation of the picture were proved. +And, by covering the crystal in a box perforated only with a small +aperture to admit the exciting ray, and by substituting black holland +for his buff blinds, he greatly improved the conditions of the +observations; so that in a little while they were able to survey the +valley in any direction they desired. + + + + So having cleared the way, we may give a brief account of this +visionary world within the crystal. The things were in all cases seen by +Mr. Cave, and the method of working was invariably for him to watch the +crystal and report what he saw, while Mr. Wace (who as a science student +had learnt the trick of writing in the dark) wrote a brief note of his +report. When the crystal faded, it was put into its box in the proper +position and the electric light turned on. Mr. Wace asked questions, and +suggested observations to clear up difficult points. Nothing, indeed, +could have been less visionary and more matter-of-fact. + + + + The attention of Mr. Cave had been speedily directed to the bird-like +creatures he had seen so abundantly present in each of his earlier +visions. His first impression was soon corrected, and he considered for +a time that they might represent a diurnal species of bat. Then he +thought, grotesquely enough, that they might be cherubs. Their heads +were round, and curiously human, and it was the eyes of one of them that +had so startled him on his second observation. They had broad, silvery +wings, not feathered, but glistening almost as brilliantly as new-killed +fish and with the same subtle play of colour, and these wings were not +built on the plan of a bird-wing or bat, Mr. Wace learned, but supported +by curved ribs radiating from the body. (A sort of butterfly wing with +curved ribs seems best to express their appearance.) The body was small, +but fitted with two bunches of prehensile organs, like long tentacles, +immediately under the mouth. Incredible as it appeared to Mr. Wace, the +persuasion at last became irresistible, that it was these creatures +which owned the great quasi-human buildings and the magnificent garden +that made the broad valley so splendid. And Mr. Cave perceived that the +buildings, with other peculiarities, had no doors, but that the great +circular windows, which +opened freely, gave the creatures egress and entrance. They would alight +upon their tentacles, fold their wings to a smallness almost rod-like, +and hop into the interior. But among them was a multitude of +smaller-winged creatures, like great dragon-flies and moths and flying +beetles, and across the greensward brilliantly-coloured gigantic +ground-beetles crawled lazily to and fro. Moreover, on the causeways and +terraces, large-headed creatures similar to the greater winged flies, +but wingless, were visible, hopping busily upon their hand-like tangle +of tentacles. + + + + Allusion has already been made to the glittering objects upon masts +that stood upon the terrace of the nearer building. It dawned upon Mr. +Cave, after regarding one of these masts very fixedly on one +particularly vivid day, that the glittering object there was a crystal +exactly like that into which he peered. And a still more careful +scrutiny convinced him that each one in a vista of nearly twenty carried +a similar object. + + + + Occasionally one of the large flying creatures would flutter up to +one, and, folding its wings and coiling a number of its tentacles about +the mast, would regard the crystal fixedly for a space, -- sometimes for +as long as fifteen minutes. And a series of observations, made at the +suggestion of Mr. Wace, convinced both watchers that, so far as this +visionary world was concerned, the crystal into which they peered +actually stood at the summit of the end-most mast on the terrace, and +that on one occasion at least one of these inhabitants of this other +world had looked into Mr. Cave's face while he was making these +observations. + + + + So much for the essential facts of this very singular story. Unless +we dismiss it all as the ingenious fabrication of Mr. Wace, we have to +believe one of two things: either that Mr. Cave's crystal was in two +worlds at once, and that, while it was carried about in one, it remained +stationary in the other, which seems altogether absurd; or else that it +had some peculiar relation of sympathy with another and exactly similar +crystal in this other world, so that what was seen in the interior of +the one in this world, was, under suitable conditions, visible to an +observer in the corresponding crystal in the other world; and vice +versa. At present, indeed, we do not know of any way in which two +crystals could so come en rapport, but nowadays we know enough to +understand that the thing is not altogether impossible. This view of the +crystals as en rapport was the supposition that occurred to Mr. Wace, +and to me at least it seems extremely plausible. . . . + + + + And where was this other world? On this, also, the alert intelligence +of Mr. Wace speedily threw light. After sunset, the sky darkened +rapidly -- there was a very brief twilight interval indeed -- and the +stars shone out. They were recognisably the same as those we see, +arranged in the same constellations. Mr. Cave recognised the Bear, the +Pleiades, Aldebaran, and Sirius: so that the other world must be +somewhere in the solar system, and, at the utmost, only a few hundreds +of millions of miles from our own. Following up this clue, Mr. Wace +learned that the midnight sky was a darker blue even than our midwinter +sky, and that the sun seemed a little smaller. And there were two small +moons! "like our moon but smaller, and quite differently marked" one of +which moved so rapidly that its motion was clearly visible as one +regarded it. These moons were never high in the sky, but vanished as +they rose: that is, every time they revolved they were eclipsed because +they were so near their primary planet. And all this answers quite +completely, although. Mr. Cave did not know it, to what must be the +condition of things on Mars. + + + + Indeed, it seems an exceedingly plausible conclusion that peering +into this crystal Mr. Cave did actually see the planet Mars and its +inhabitants. And, if that be the case, then the evening star that shone +so brilliantly in the sky of that distant vision, was neither more nor +less than our own familiar earth. + + + + For a time the Martians -- if they were Martians -- do not seem to +have known of Mr. Cave's inspection. Once or twice one would come to +peer, and go away very shortly to some other mast, as though the vision +was unsatisfactory. During this time Mr. Cave was able to watch the +proceedings of these winged people without being disturbed by their +attentions, and, although his report is necessarily vague and +fragmentary, it is nevertheless very suggestive. Imagine the impression +of humanity a Martian observer would get who, after a difficult process +of preparation and with considerable fatigue to the eyes, was able to +peer at London from the steeple of St. Martin's Church for stretches, at +longest, of four minutes at a time. Mr. Cave was unable to ascertain if +the winged Martians were the same as the Martians who hopped about the +causeways and terraces, and if the latter could put on wings at will. He +several times saw certain clumsy bipeds, dimly suggestive of apes, white +and partially translucent, feeding among certain of the lichenous trees, +and once some of these fled before one of the hopping, round-headed +Martians. The latter caught one in its tentacles, and then the picture +faded suddenly and left Mr. Cave most tantalisingly in the dark. On +another occasion a vast thing, that Mr. Cave thought at first was some +gigantic insect, appeared advancing along the causeway beside the canal +with extraordinary rapidity. As this drew nearer Mr. Cave perceived that +it was a mechanism of shining +metals and of extraordinary complexity. And then, when he looked again, +it had passed out of sight. + + + + After a time Mr. Wace aspired to attract the attention of the +Martians, and the next time that the strange eyes of one of them +appeared close to the crystal Mr. Cave cried out and sprang away, and +they immediately turned on the light and began to gesticulate in a +manner suggestive of signalling. But when at last Mr. Cave examined the +crystal again the Martian had departed. + + + + Thus far these observations had progressed in early November, and +then Mr. Cave, feeling that the suspicions of his family about the +crystal were allayed, began to take it to and fro with him in order +that, as occasion arose in the daytime or night, he might comfort +himself with what was fast becoming the most real thing in his existence. + + + + In December Mr. Wace's work in connection with a forthcoming +examination became heavy, the sittings were reluctantly suspended for a +week, and for ten or eleven days -- he is not quite sure which -- he saw +nothing of Cave. He then grew anxious to resume these investigations, +and, the stress of his seasonal labours being abated, he went down to +Seven Dials. At the corner he noticed a shutter before a bird fancier's +window, and then another at a cobbler's. Mr. Cave's shop was closed. + + + + He rapped and the door was opened by the step-son in black. He at +once called Mrs. Cave, who was, Mr. Wace could not but observe, in cheap +but ample widow's weeds of the most imposing pattern. Without any very +great surprise Mr. Wace learnt that Cave was dead and already buried. +She was in tears, and her voice was a little thick. She had just +returned from Highgate. Her mind seemed occupied with her own prospects +and the honourable details of the obsequies, but Mr. Wace was at last +able to learn the particulars of Cave's death. He had been found dead in +his shop in the early morning, the day after his last visit to Mr. Wace, +and the crystal had been clasped in his stone-cold hands. His face was +smiling, said Mrs. Cave, and the velvet cloth from the minerals lay on +the floor at his feet. He must have been dead five or six hours when he +was found. + + + + This came as a great shock to Wace, and he began to reproach ho,self +bitterly for having neglected the plain symptoms of the old man's +ill-health. But his chief thought was of the crystal. He approached that +topic in a gingerly manner, because he knew Mrs. Cave's peculiarities. +He was dumbfoundered to learn that it was sold. + + + + Mrs. Cave's first impulse, directly Cave's body had been taken +upstairs, had been to write to the mad clergyman who had offered five +pounds for the crystal, informing him of its recovery; but after a +violent hunt in which her daughter joined her, they were convinced + + + +of the loss of his address. As they were without the means required to +mourn and bury Cave in the elaborate style the dignity of an old Seven +Dials inhabitant demands, they had appealed to a friendly +fellow-tradesman in Great Portland Street. He had very kindly taken over +a portion of the stock at a valuation. The valuation was his own and the +crystal egg was included in one of the lots. Mr. Wace, after a few +suitable consolatory observations, a little offhandedly proffered +perhaps, hurried at once to Great Portland Street. But there he learned +that the crystal egg had already been sold to a tall, dark man in grey. +And there the material facts in this curious, and to me at least very +suggestive, story come abruptly to an end. The Great Portland Street +dealer did not know who the tall dark man in grey was, nor had he +observed him with sufficient attention to describe him minutely. He did +not even know which way this person had gone after leaving the shop. For +a time Mr. Wace remained in the shop, trying the dealer's patience with +hopeless questions, venting his own exasperation. And at last, realising +abruptly that the whole thing had passed out of his hands, had vanished +like a vision of the night, he returned to his own rooms, a little +astonished to find the notes he had made still tangible and visible upon +his untidy table. + + + + His annoyance and disappointment were naturally very great. He made a +second call (equally ineffectual) upon the Great Portland Street dealer, +and he resorted to advertisements in such periodicals as were likely to +come into the hands of a bric-a-brac collector. He also wrote letters to +The Daily Chronicle and Nature, but both those periodicals, suspecting a +hoax, asked him to reconsider his action before they printed, and he was +advised that such a strange story, unfortunately so bare of supporting +evidence, might imperil his reputation as an investigator. Moreover, the +calls of his proper work were urgent. So that after a month or so, save +for an occasional reminder to certain dealers, he had reluctantly to +abandon the quest for the crystal egg, and from that day to this it +remains undiscovered. Occasionally, however, he tells me, and I can +quite believe him, he has bursts of zeal, in which he abandons his more +urgent occupation and resumes the search. + + + + Whether or not it will remain lost for ever, with the material and +origin of it, are things equally speculative at the present time. If the +present purchaser is a collector, one would have expected the enquiries +of Mr. Wace to have readied him through the dealers. He has been able to +discover Mr. Cave's clergyman and "Oriental" -- no other than the Rev. +James Parker and the young Prince of Bosso-Kuni in Java. I am obliged to +them for certain particulars. The object of the Prince was simply +curiosity -- and extravagance. He was so eager to buy, +because Cave was so oddly reluctant to sell. It is just as possible that +the buyer in the second instance was simply a casual purchaser and not a +collector at all, and the crystal egg, for all I know, may at the +present moment be within a mile of me, decorating a drawing-room or +serving as a paper-weight -- its remarkable functions all unknown. +Indeed, it is partly with the idea of such a possibility that I have +thrown this narrative into a form that will give it a chance of being +read by the ordinary consumer of fiction. + + + + My own ideas in the matter are practically identical with those of +Mr. Wace. I believe the crystal on the mast in Mars and the crystal egg +of Mr. Cave's to be in some physical, but at present quite inexplicable, +way en rapport, and we both believe further that the terrestrial crystal +must have been -- possibly at some remote date -- sent hither from that +planet, in order to give the Martians a near view of our affairs. +Possibly the fellows to the crystals in the other masts are also on our +globe. No theory of hallucination suffices for the facts. + + + + + + diff --git a/src/io/doc2html.xsl b/src/io/doc2html.xsl new file mode 100644 index 000000000..f8734a1c2 --- /dev/null +++ b/src/io/doc2html.xsl @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + +

+ + +

+ + + +

+
+ + + +
+ +
+ + +

+ +

+
+ + diff --git a/src/io/ftos.cpp b/src/io/ftos.cpp new file mode 100644 index 000000000..47f0dc232 --- /dev/null +++ b/src/io/ftos.cpp @@ -0,0 +1,482 @@ +/* ////////////////////////////////////////////////////////////////////// +// ftos.cc +// +// Copyright (c) 1996-2003 Bryce W. Harrington [bryce at osdl dot org] +// +//----------------------------------------------------------------------- +// License: This code may be used by anyone for any purpose +// so long as the copyright notices and this license +// statement remains attached. +//----------------------------------------------------------------------- +// +// string ftos(double val[, char mode[, int sigfig[, int precision[, int options]]]]) +// +// DESCRIPTION +// This routine is intended to replace the typical use of sprintf for +// converting floating point numbers into strings. +// +// To one-up sprintf, an additional mode was created - 'h' mode - +// which produces numbers in 'engineering notation' - exponents are +// always shown in multiples of 3. To non-engineers this mode is +// probably irrelevant, but for engineers (and scientists) it is SOP. +// +// One other new feature is an option to use 'x10^' instead of the +// conventional 'E' for exponental notation. This is entirely for +// aesthetics since numbers in the 'x10^' form cannot be used as +// inputs for most programs. +// +// For most cases, the routine can simply be used with the defaults +// and acceptable results will be produced. No fill zeros or trailing +// zeros are shown, and exponential notation is only used for numbers +// greater than 1e6 or less than 1e-3. +// +// The one area where sprintf may surpass this routine is in width control. +// No provisions are made in this routine to restrict a number to a +// certain number of digits (thus allowing the number to be constrained +// to an 8 space column, for instance.) Along with this, it does not +// support pre-padding a number with zeros (e.g., '5' -> '0005') and will +// not post-pad a number with spaces (i.e., allow left-justification.) +// +// If width control is this important, then the user will probably want to +// use the stdio routines, which really is well suited for outputting +// columns of data with a brief amount of code. +// +// PARAMETERS +// val - number to be converted +// mode - can be one of four possible values. Default is 'g' +// +// e: Produces numbers in scientific notation. One digit +// is shown on the left side of the decimal, the rest +// on the right, and the exponential is always shown. +// EXAMPLE: 1.04e-4 +// +// f: Produces numbers with fixed format. Number is shown +// exact, with no exponent. +// EXAMPLE: 0.000104 +// +// g: If val is greater than 1e6 or less than 1e-3 it will +// be shown in 'e' format, otherwise 'f' format will be +// used. +// +// h: Produces numbers in engineering format. Result is +// identical to 'f' format for numbers between 1 and +// 1e3, otherwise, the number is shown such that it +// always begins with a nonzero digit on the left side +// (unless number equals zero), and the exponential is +// a multiple of 3. +// EXAMPLE: 104e-6 +// +// If the mode is expressed as a capital letter (e.g., 'F') +// then the exponential part of the number will also be +// capitalized (e.g., '1E6' or '1X10^6'.) +// +// sigfig - the number of significant figures. These are the digits +// that are "retained". For example, the following numbers +// all have four sigfigs: +// 1234 12.34 0.0001234 1.234e-10 +// the last digit shown will be rounded in the standard +// manner (down if the next digit is less than 5, up otherwise.) +// +// precision - the number of digits to show to the right of the decimal. +// For example, all of the following numbers have precisions +// of 2: +// 1234.00 12.34 0.00 1.23e-10 123.40e-12 +// +// options - several options are allowed to control the look of the +// output. +// +// FORCE_DECIMAL - require the decimal point to be shown for +// numbers that do not have any fractional digits (or that +// have a precision set to zero) +// EXAMPLE: 1.e6 +// FORCE_EXP_ZERO - pad the 10's zero in exponent if necessary +// EXAMPLE: 1e06 +// FORCE_HUNDRED_EXP_ZERO - pad the 100's zero in exponent if +// necessary. Also pads 10's zero in exponent if necessary. +// EXAMPLE: 1e006 +// FORCE_EXP_PLUS - show the '+' in the exponent if exponent +// is used. +// EXAMPLE: 1e+6 +// FORCE_EXP - force the output to display the exponent +// EXAMPLE: 0e0 +// FORCE_X10 - use x10^ instead of E +// EXAMPLE: 1x10^6 +// FORCE_PLUS - force output of the '+' for positive numbers +// EXAMPLE: +1e6 +// +// Options can be combined using the usual OR method. For +// example, +// +// ftos(123.456, 'f', -1, -1, FORCE_PLUS | FORCE_X10 | FORCE_EXP) +// +// gives "+123.456x10^0" +// +// RETURN VALUE +// The string representation of the number is returned from the routine. +// The ANSI C++ Standard "string" class was used for several important +// reasons. First, because the string class manages it's own space, the +// ftos routine does not need to concern itself with writing to unallocated +// areas of memory or with handling memory reallocation internally. Second, +// it allows return of an object, not a pointer to an object; this may not +// be as efficient, but it is cleaner and safer than the alternative. Third, +// the routine's return value can be directly assigned to a variable, i.e. +// string var = ftos(3.1415); +// which makes code much easier to comprehend and modify. +// +// Internally, the ftos routine uses fairly typical string operators (=, +=, +// +, etc.) which pretty much any other flavor of string class will define as +// well. Thus if one does not have access to the ANSI C++ Standard string +// class, the user can substitute another with little difficulty. (If the +// alternate class is not named "string" then redefine "string" to whatever +// you wish to use. For example, +// #define string CString +// +// November 1996 - Bryce Harrington +// Created ftoa and ftos +// +// December 1996 - Bryce Harrington +// Added engineering notation mode, added sigfig capability, added +// significant debug code, added options, thoroughly debugged and +// tested the code. +// +// +// June 1999 - Bryce Harrington +// Modified to run on Linux for WorldForge +// +// March 2003 - Bryce Harrington +// Removed DTAG() macros - use of fprintf(stderr,...) instead +// Broke out round/itos/ftos into separate files +// Removed curses bits +// +/////////////////////////////////////////////////////////////////////// */ + + +// This is the routine used for converting a floating point into a string +// This may be included in stdlib.h on some systems and may conflict. +// Let me know your system & etc. so I can properly #ifdef this, but +// try commenting the following four lines out if you run into conflicts. +// extern "C" { +// char* +// ecvt (double val, size_t ndigit, int *decpt, int *sign); +// } + +using namespace std; + +#ifndef HAS_ECVT +#include +#endif + + +#include "ftos.h" + + +// This routine counts from the end of a string like '10229000' to find the index +// of the first non-'0' character (5 would be returned for the above number.) +int countDigs(char *p) +{ + int length =0; + while (*(p+length)!='\0') length++; // Count total length + while (length>0 && *(p+length-1)=='0') length--; // Scan backwards for a non-'0' + return length; +} + +// This routine determines how many digits make up the left hand +// side of the number if the abs value of the number is greater than 1, or the +// digits that make up the right hand side if the abs value of the number +// is between 0 and 1. Returns 1 if v==0. Return value is positive for numbers +// greater than or equal to 1, negative for numbers less than 0.1, and zero for +// numbers between 0.1 and 1. +int countLhsDigits(double v) +{ + if (v<0) v = -v; // Take abs value + else if (v==0) return 1; // Special case if v==0 + + int n=0; + for (; v<0.1; v*=10) // Count digits on right hand side (l.t. 0.1) + { n--; } + for (; v>=1; v/=10) // Count digits on left hand side (g.e. 1.0) + { n++; } + return n; +} + +// This is the routine that does the work of converting the number into a string. +string ftos(double val, char mode, int sigfig, int precision, int options) +{ + // Parse the options to a more usable form + // These options allow the user to control some of the ornaments on the + // number that is output. By default they are all false. Turning them + // on helps to "fix" the format of the number so it lines up in columns + // better. + // - require the decimal point to be shown for numbers that do not have + // any fractional digits (or that have a precision set to zero + bool forceDecimal = (options & FORCE_DECIMAL); + // - show the 10's and 100's zero in exponent + bool forceExpZero = (options & FORCE_EXP_ZERO); + bool forceHundredExpZero = (options & FORCE_HUNDRED_EXP_ZERO); + // - show the '+' in the exponent if exponent is used + bool forceExpPlus = (options & FORCE_EXP_PLUS); + // - force the output to display the exponent + bool forceExponent = (options & FORCE_EXP); + // - use x10^ instead of E + bool forcex10 = (options & FORCE_X10); + // - force output of the '+' for positive numbers + bool forcePlus = (options & FORCE_PLUS); + +#ifdef DEBUG + fprintf(stderr, "Options: "); + fprintf(stderr, " %4s = %s ", "x10", (forcex10 ? "on" : "off" )); + fprintf(stderr, " %4s = %s ", ".", (forceDecimal ? "on" : "off" )); + fprintf(stderr, " %4s = %s ", "e0", (forceExpZero ? "on" : "off" )); + fprintf(stderr, " %4s = %s ", "e00", (forceHundredExpZero ? "on" : "off" )); + fprintf(stderr, " %4s = %s ", "e+", (forceExpPlus ? "on" : "off" )); + fprintf(stderr, " %4s = %s ", "e", (forceExponent ? "on" : "off" )); + fprintf(stderr, " %4s = %s \n", "+#", (forcePlus ? "on" : "off" )); +#endif + + // - exponent usage + bool useExponent = false; + + // Determine the case for the 'e' (if used) + char E = (forcex10)? 'x' : 'e'; + if (g_ascii_isupper(mode)) { + E = g_ascii_toupper(E); + mode = g_ascii_tolower(mode); + } + + // Determine how many decimals we're interested in + int L = countLhsDigits(val); + +#ifdef DEBUG + fprintf(stderr, "*** L is %s\n", itos(L).c_str()); +#endif + + int count = 0; + if (sigfig==0) // bad input - don't want any sigfigs??!! + return ""; + else if (precision>=0) { // Use fixed number of decimal places + count = precision; + if (mode == 'e') count += 1; + else if (mode == 'f') count += L; + else if (mode == 'g') count += (L>6 || L<-3)? 1 : L; + else if (mode == 'h') count += (L>0)? ((L-1)%3+1) : (L%3+3); + if (sigfig>0) count = (sigfig > count)? count : sigfig; // Use sigfig # if it means more decimal places + } + else if (sigfig>0) // Just use sigfigs + count = sigfig; + else // prec < 0 and sigfig < 0 + count = 10; +#ifdef DEBUG + fprintf(stderr, "*** count is %s\n", itos(count).c_str()); +#endif + + // Get number's string rep, sign, and exponent + int sign = 0; + int decimal=0; + +#ifdef HAS_ECVT + char *p = ecvt(val, count, &decimal, &sign); +#else + char *p = (char *) g_strdup_printf("%.0f", val); + // asprintf(&p, "%.0f", val); +#endif + +#ifdef DEBUG + fprintf(stderr, "*** string rep is %s\n", p); + fprintf(stderr, "*** decimal is %s\n", itos(decimal).c_str()); + fprintf(stderr, "*** sign is %s\n", itos(sign).c_str()); +#endif + + // Count the number of relevant digits in the resultant number + int dig = countDigs(p); + if (dig < sigfig) dig = sigfig; + +#ifdef DEBUG + fprintf(stderr, "*** digs is %s\n", itos(dig).c_str()); +#endif + + // Determine number of digits to put on left side of the decimal point + int lhs=0; + // For 'g' mode, decide whether to use 'e' or 'f' format. + if (mode=='g') mode = (decimal>6 || decimal<-3)? 'e' : 'f'; + switch (mode) { + case 'e': + lhs = 1; // only need one char on left side + useExponent = true; // force exponent use + break; + + case 'f': + lhs = (decimal<1)? 1 : decimal; + // use one char on left for num < 1, + // otherwise, use the number of decimal places. + useExponent = false; // don't want exponent for 'f' format + break; + + case 'h': + if (val==0.0) // special case for if value is zero exactly. + lhs = 0; // this prevents code from returning '000.0' + else + lhs = (decimal<=0)? (decimal)%3 + 3 : (decimal-1)%3+1; + useExponent = !(lhs==decimal); // only use exponent if we really need it + break; + + default: + return "**bad mode**"; + } + +#ifdef DEBUG + fprintf(stderr, "*** lhs is %s\n", itos(lhs).c_str()); +#endif + + // Figure out the number of digits to show in the right hand side + int rhs=0; + if (precision>=0) + rhs = precision; + else if (val == 0.0) + rhs = 0; + else if (useExponent || decimal>0) + rhs = dig-lhs; + else + rhs = dig-decimal; + + // can't use a negative rhs value, so turn it to zero if that is the case + if (rhs<0) rhs = 0; + +#ifdef DEBUG + fprintf(stderr, "*** rhs is", itos(rhs).c_str()); +#endif + + // Determine the exponent + int exponent = decimal - lhs; + if (val==0.0) exponent=0; // prevent zero from getting an exponent +#ifdef DEBUG + fprintf(stderr, "*** exponent is %s\n", itos(exponent).c_str()); +#endif + + string ascii; + + // output the sign + if (sign) ascii += "-"; + else if (forcePlus) ascii += "+"; + + // output the left hand side + if (!useExponent && decimal<=0) // if fraction, put the 0 out front + ascii += '0'; + else // is either exponential or >= 1, so write the lhs + for (; lhs>0; lhs--) + ascii += (*p)? *p++ : int('0'); // now fill in the numbers before decimal + +#ifdef DEBUG + fprintf(stderr, "*** ascii + sign + lhs is %s\n", ascii.c_str()); +#endif + + // output the decimal point + if (forceDecimal || rhs>0) + ascii += '.'; + + // output the right hand side + if (!useExponent && rhs>0) // first fill in zeros after dp and before numbers + while (decimal++ <0 && rhs-->0) + ascii += '0'; + for (; rhs>0 ; rhs--) // now fill in the numbers after decimal + ascii += (*p)? *p++ : int('0'); + +#ifdef DEBUG + fprintf(stderr, "*** ascii + . + rhs is %s\n", ascii.c_str()); +#endif + + if (forceExponent || useExponent) // output the entire exponent if required + { + ascii += E; // output the E or X + if (forcex10) ascii += "10^"; // if using 'x10^' format, output the '10^' part + + // output the exponent's sign + if (exponent < 0) { // Negative exponent + exponent = -exponent; // make exponent positive if needed + ascii += '-'; // output negative sign + } + else if (forceExpPlus) // We only want the '+' if it is asked for explicitly + ascii += '+'; + + // output the exponent + if (forceHundredExpZero || exponent >= 100) + ascii += ( (exponent/100) % 10 + '0' ); + if (forceHundredExpZero || forceExpZero || exponent >= 10) + ascii += ( (exponent/10) % 10 + '0' ); + ascii += ( exponent % 10 + '0' ); + +#ifdef DEBUG + fprintf(stderr, "*** ascii + exp is %s\n", ascii.c_str()); +#endif + } + +#ifdef DEBUG + fprintf(stderr, "*** End of ftos with ascii = ", ascii.c_str()); +#endif + /* finally, we can return */ + return ascii; +} + +#ifdef TESTFTOS + +int main() +{ + cout << "Normal (g): " << endl; + cout << "1.0 = " << ftos(1.0) << endl; + cout << "42 = " << ftos(42) << endl; + cout << "3.141 = " << ftos(3.141) << endl; + cout << "0.01 = " << ftos(0.01) << endl; + cout << "1.0e7 = " << ftos(1.0e7) << endl; + cout << endl; + + cout << "Scientific (e): " << endl; + cout << "1.0 = " << ftos(1.0, 'e') << endl; + cout << "42 = " << ftos(42, 'e') << endl; + cout << "3.141 = " << ftos(3.141, 'e') << endl; + cout << "0.01 = " << ftos(0.01, 'e') << endl; + cout << "1.0e7 = " << ftos(1.0e7, 'e') << endl; + cout << endl; + + cout << "Fixed (f): " << endl; + cout << "1.0 = " << ftos(1.0, 'f') << endl; + cout << "42 = " << ftos(42, 'f') << endl; + cout << "3.141 = " << ftos(3.141, 'f') << endl; + cout << "0.01 = " << ftos(0.01, 'f') << endl; + cout << "1.0e7 = " << ftos(1.0e7, 'f') << endl; + cout << endl; + + cout << "Engineering (h): " << endl; + cout << "1.0 = " << ftos(1.0, 'h') << endl; + cout << "42 = " << ftos(42, 'h') << endl; + cout << "3.141 = " << ftos(3.141, 'h') << endl; + cout << "0.01 = " << ftos(0.01, 'h') << endl; + cout << "1.0e7 = " << ftos(1.0e7, 'h') << endl; + cout << endl; + + cout << "Sigfigs: " << endl; + cout << "2 sf = " << ftos(1234, 'g', 2) << " " + << ftos(12.34, 'g', 2) << " " + << ftos(0, 'g', 2) << " " + << ftos(123.4e-11, 'g', 2) << endl; + cout << "4 sf = " << ftos(1234, 'g', 4) << " " + << ftos(12.34, 'g', 4) << " " + << ftos(0, 'g', 4) << " " + << ftos(123.4e-11, 'g', 4) << endl; + cout << "8 sf = " << ftos(1234, 'g', 8) << " " + << ftos(12.34, 'g', 8) << " " + << ftos(0, 'g', 8) << " " + << ftos(123.4e-11, 'g', 8) << endl; + cout << endl; + + cout << "x10 mode: " << endl; + cout << "1234 = " << ftos(1234, 'e', 4, -1, FORCE_X10 | FORCE_EXP) << endl; + cout << "1.01e10 = " << ftos(1.01e10, 'h', -1, -1, FORCE_X10 | FORCE_EXP) << endl; + cout << endl; + + cout << "itos tests..." << endl; + cout << "42 = " << itos(42) << endl; + cout << endl; + + return 0; +} + +#endif // TESTFTOS diff --git a/src/io/ftos.h b/src/io/ftos.h new file mode 100644 index 000000000..888def639 --- /dev/null +++ b/src/io/ftos.h @@ -0,0 +1,54 @@ +///////////////////////////////////////////////////////////////////////// +// ftos.h +// +// Copyright (c) 1996 Bryce W. Harrington - bryce@neptune.net +// +//----------------------------------------------------------------------- +// License: This code may be used by anyone for any purpose +// so long as the copyright notices and this license +// statement remains attached. +//----------------------------------------------------------------------- +// Description of file contents +// 1993 - Bryce Harrington +// Created initial ftoa routine +// +// October 1996 - Bryce Harrington +// Created itos from code taken from Kernighan & Ritchie +// _The C Programming Language_ 2nd edition +// +// November 1996 - Bryce Harrington +// Created new ftoa and ftos +// +// July 1999 - Bryce Harrington +// Ported to Linux for use in WorldForge +// +// January 2000 - Karsten Laux klaux@rhrk.uni-kl.de +// added ultos - convering ulong to string +// +///////////////////////////////////////////////////////////////////////// +#ifndef ftos_h +#define ftos_h + +#include + +// ftos routine +const int FORCE_X10 = (1 << 0); +const int FORCE_DECIMAL = (1 << 1); +const int FORCE_EXP_ZERO = (1 << 2); +const int FORCE_HUNDRED_EXP_ZERO = (1 << 3); +const int FORCE_EXP_PLUS = (1 << 4); +const int FORCE_EXP = (1 << 5); +const int FORCE_PLUS = (1 << 6); + +/// +std::string ftos(double val, char mode='g', int sigfig=-1, int precision=-1, int options=0); +/// +std::string itos(int n); +/// +std::string ultos(unsigned long n); +/// +double rround(double x); // use rounding rule -> x to nearest int. +/// +double rround(double x, int k); // round to the kth place + +#endif // ftos_h diff --git a/src/io/gzipstream.cpp b/src/io/gzipstream.cpp new file mode 100644 index 000000000..02309ecdd --- /dev/null +++ b/src/io/gzipstream.cpp @@ -0,0 +1,458 @@ +/** + * Zlib-enabled input and output streams + * + * This is a thin wrapper of libz calls, in order + * to provide a simple interface to our developers + * for gzip input and output. + * + * Authors: + * Bob Jamison + * + * Copyright (C) 2004 Inkscape.org + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "gzipstream.h" + + +namespace Inkscape +{ +namespace IO +{ + +//######################################################################### +//# G Z I P I N P U T S T R E A M +//######################################################################### + +#define OUT_SIZE 4000 + +/** + * + */ +GzipInputStream::GzipInputStream(InputStream &sourceStream) + : BasicInputStream(sourceStream), + loaded(false), + totalIn(0), + totalOut(0), + outputBuf(NULL), + crc(0), + srcCrc(0), + srcSiz(0), + srcConsumed(0), + srcLen(0), + outputBufPos(0), + outputBufLen(0) +{ + memset( &d_stream, 0, sizeof(d_stream) ); +} + +/** + * + */ +GzipInputStream::~GzipInputStream() +{ + close(); + if ( srcBuf ) { + free(srcBuf); + srcBuf = 0; + } + if ( outputBuf ) { + free(outputBuf); + outputBuf = 0; + } +} + +/** + * Returns the number of bytes that can be read (or skipped over) from + * this input stream without blocking by the next caller of a method for + * this input stream. + */ +int GzipInputStream::available() +{ + if (closed || !outputBuf) + return 0; + return outputBufLen - outputBufPos; +} + + +/** + * Closes this input stream and releases any system resources + * associated with the stream. + */ +void GzipInputStream::close() +{ + if (closed) + return; + + int zerr = inflateEnd(&d_stream); + if (zerr != Z_OK) { + printf("inflateEnd: Some kind of problem: %d\n", zerr); + } + + if ( srcBuf ) { + free(srcBuf); + srcBuf = 0; + } + if ( outputBuf ) { + free(outputBuf); + outputBuf = 0; + } + closed = true; +} + +/** + * Reads the next byte of data from the input stream. -1 if EOF + */ +int GzipInputStream::get() +{ + int ch = -1; + if (closed) { + // leave return value -1 + } + else if (!loaded && !load()) { + closed=true; + } else { + loaded = true; + + int zerr = Z_OK; + if ( outputBufPos >= outputBufLen ) { + // time to read more, if we can + zerr = fetchMore(); + } + + if ( outputBufPos < outputBufLen ) { + ch = (int)outputBuf[outputBufPos++]; + } + } + + return ch; +} + +#define FTEXT 0x01 +#define FHCRC 0x02 +#define FEXTRA 0x04 +#define FNAME 0x08 +#define FCOMMENT 0x10 + +bool GzipInputStream::load() +{ + crc = crc32(0L, Z_NULL, 0); + + std::vector inputBuf; + while (true) + { + int ch = source.get(); + if (ch<0) + break; + inputBuf.push_back((Byte)(ch & 0xff)); + } + long inputBufLen = inputBuf.size(); + + if (inputBufLen < 19) //header + tail + 1 + { + return false; + } + + srcLen = inputBuf.size(); + srcBuf = (Bytef *)malloc(srcLen * sizeof(Byte)); + if (!srcBuf) { + return false; + } + + outputBuf = (unsigned char *)malloc(OUT_SIZE); + if ( !outputBuf ) { + free(srcBuf); + srcBuf = 0; + return false; + } + outputBufLen = 0; // Not filled in yet + + std::vector::iterator iter; + Bytef *p = srcBuf; + for (iter=inputBuf.begin() ; iter != inputBuf.end() ; iter++) + *p++ = *iter; + + int headerLen = 10; + + //Magic + int val = (int)srcBuf[0]; + //printf("val:%x\n", val); + val = (int)srcBuf[1]; + //printf("val:%x\n", val); + + //Method + val = (int)srcBuf[2]; + //printf("val:%x\n", val); + + //flags + int flags = (int)srcBuf[3]; + + //time + val = (int)srcBuf[4]; + val = (int)srcBuf[5]; + val = (int)srcBuf[6]; + val = (int)srcBuf[7]; + + //xflags + val = (int)srcBuf[8]; + //OS + val = (int)srcBuf[9]; + + int cur = 10; +// if ( flags & FEXTRA ) { +// headerLen += 2; +// int xlen = +// TODO deal with optional header parts +// } + if ( flags & FNAME ) { + while ( srcBuf[cur] ) + { + cur++; + headerLen++; + } + headerLen++; + } + + + srcCrc = ((0x0ff & srcBuf[srcLen - 5]) << 24) + | ((0x0ff & srcBuf[srcLen - 6]) << 16) + | ((0x0ff & srcBuf[srcLen - 7]) << 8) + | ((0x0ff & srcBuf[srcLen - 8]) << 0); + //printf("srcCrc:%lx\n", srcCrc); + + srcSiz = ((0x0ff & srcBuf[srcLen - 1]) << 24) + | ((0x0ff & srcBuf[srcLen - 2]) << 16) + | ((0x0ff & srcBuf[srcLen - 3]) << 8) + | ((0x0ff & srcBuf[srcLen - 4]) << 0); + //printf("srcSiz:%lx/%ld\n", srcSiz, srcSiz); + + if ( srcSiz <= 0 ) { + return false; + } + + //outputBufLen = srcSiz + srcSiz/100 + 14; + + unsigned char *data = srcBuf + headerLen; + unsigned long dataLen = srcLen - (headerLen + 8); + //printf("%x %x\n", data[0], data[dataLen-1]); + + d_stream.zalloc = (alloc_func)0; + d_stream.zfree = (free_func)0; + d_stream.opaque = (voidpf)0; + d_stream.next_in = data; + d_stream.avail_in = dataLen; + d_stream.next_out = outputBuf; + d_stream.avail_out = OUT_SIZE; + + int zerr = inflateInit2(&d_stream, -MAX_WBITS); + if ( zerr == Z_OK ) + { + zerr = fetchMore(); + } else { + printf("inflateInit2: Some kind of problem: %d\n", zerr); + } + + + return (zerr == Z_OK) || (zerr == Z_STREAM_END); +} + + +int GzipInputStream::fetchMore() +{ + int zerr = Z_OK; + + // TODO assumes we aren't called till the buffer is empty + d_stream.next_out = outputBuf; + d_stream.avail_out = OUT_SIZE; + outputBufLen = 0; + outputBufPos = 0; + + zerr = inflate( &d_stream, Z_SYNC_FLUSH ); + if ( zerr == Z_OK || zerr == Z_STREAM_END ) { + outputBufLen = OUT_SIZE - d_stream.avail_out; + if ( outputBufLen ) { + crc = crc32(crc, (const Bytef *)outputBuf, outputBufLen); + } + //printf("crc:%lx\n", crc); +// } else if ( zerr != Z_STREAM_END ) { +// // TODO check to be sure this won't happen for partial end reads +// printf("inflate: Some kind of problem: %d\n", zerr); + } + + return zerr; +} + +//######################################################################### +//# G Z I P O U T P U T S T R E A M +//######################################################################### + +/** + * + */ +GzipOutputStream::GzipOutputStream(OutputStream &destinationStream) + : BasicOutputStream(destinationStream) +{ + + totalIn = 0; + totalOut = 0; + crc = crc32(0L, Z_NULL, 0); + + //Gzip header + destination.put(0x1f); + destination.put(0x8b); + + //Say it is compressed + destination.put(Z_DEFLATED); + + //flags + destination.put(0); + + //time + destination.put(0); + destination.put(0); + destination.put(0); + destination.put(0); + + //xflags + destination.put(0); + + //OS code - from zutil.h + //destination.put(OS_CODE); + //apparently, we should not explicitly include zutil.h + destination.put(0); + +} + +/** + * + */ +GzipOutputStream::~GzipOutputStream() +{ + close(); +} + +/** + * Closes this output stream and releases any system resources + * associated with this stream. + */ +void GzipOutputStream::close() +{ + if (closed) + return; + + flush(); + + //# Send the CRC + uLong outlong = crc; + for (int n = 0; n < 4; n++) + { + destination.put((int)(outlong & 0xff)); + outlong >>= 8; + } + //# send the file length + outlong = totalIn & 0xffffffffL; + for (int n = 0; n < 4; n++) + { + destination.put((int)(outlong & 0xff)); + outlong >>= 8; + } + + destination.close(); + closed = true; +} + +/** + * Flushes this output stream and forces any buffered output + * bytes to be written out. + */ +void GzipOutputStream::flush() +{ + if (closed || inputBuf.size()<1) + return; + + uLong srclen = inputBuf.size(); + Bytef *srcbuf = (Bytef *)malloc(srclen * sizeof(Byte)); + if (!srcbuf) + { + return; + } + + uLong destlen = srclen; + Bytef *destbuf = (Bytef *)malloc((destlen + (srclen/100) + 13) * sizeof(Byte)); + if (!destbuf) + { + free(srcbuf); + return; + } + + std::vector::iterator iter; + Bytef *p = srcbuf; + for (iter=inputBuf.begin() ; iter != inputBuf.end() ; iter++) + *p++ = *iter; + + crc = crc32(crc, (const Bytef *)srcbuf, srclen); + + int zerr = compress(destbuf, (uLongf *)&destlen, srcbuf, srclen); + if (zerr != Z_OK) + { + printf("Some kind of problem\n"); + } + + totalOut += destlen; + //skip the redundant zlib header and checksum + for (uLong i=2; i + * + * Copyright (C) 2004 Inkscape.org + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + + +#include "inkscapestream.h" +#include + +namespace Inkscape +{ +namespace IO +{ + +//######################################################################### +//# G Z I P I N P U T S T R E A M +//######################################################################### + +/** + * This class is for deflating a gzip-compressed InputStream source + * + */ +class GzipInputStream : public BasicInputStream +{ + +public: + + GzipInputStream(InputStream &sourceStream); + + virtual ~GzipInputStream(); + + virtual int available(); + + virtual void close(); + + virtual int get(); + +private: + + bool load(); + int fetchMore(); + + bool loaded; + + long totalIn; + long totalOut; + + unsigned char *outputBuf; + unsigned char *srcBuf; + + unsigned long crc; + unsigned long srcCrc; + unsigned long srcSiz; + unsigned long srcConsumed; + unsigned long srcLen; + long outputBufPos; + long outputBufLen; + + z_stream d_stream; +}; // class GzipInputStream + + + + +//######################################################################### +//# G Z I P O U T P U T S T R E A M +//######################################################################### + +/** + * This class is for gzip-compressing data going to the + * destination OutputStream + * + */ +class GzipOutputStream : public BasicOutputStream +{ + +public: + + GzipOutputStream(OutputStream &destinationStream); + + virtual ~GzipOutputStream(); + + virtual void close(); + + virtual void flush(); + + virtual void put(int ch); + +private: + + std::vector inputBuf; + + long totalIn; + long totalOut; + unsigned long crc; + +}; // class GzipOutputStream + + + + + + + +} // namespace IO +} // namespace Inkscape + + +#endif /* __INKSCAPE_IO_GZIPSTREAM_H__ */ diff --git a/src/io/inkscapestream.cpp b/src/io/inkscapestream.cpp new file mode 100644 index 000000000..e527101f6 --- /dev/null +++ b/src/io/inkscapestream.cpp @@ -0,0 +1,842 @@ +/** + * Our base input/output stream classes. These are is directly + * inherited from iostreams, and includes any extra + * functionality that we might need. + * + * Authors: + * Bob Jamison + * + * Copyright (C) 2004 Inkscape.org + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + + +#include "inkscapestream.h" + +namespace Inkscape +{ +namespace IO +{ + +//######################################################################### +//# U T I L I T Y +//######################################################################### + +void pipeStream(InputStream &source, OutputStream &dest) +{ + for (;;) + { + int ch = source.get(); + if (ch<0) + break; + dest.put(ch); + } + dest.flush(); +} + +//######################################################################### +//# B A S I C I N P U T S T R E A M +//######################################################################### + + +/** + * + */ +BasicInputStream::BasicInputStream(InputStream &sourceStream) + : source(sourceStream) +{ + closed = false; +} + +/** + * Returns the number of bytes that can be read (or skipped over) from + * this input stream without blocking by the next caller of a method for + * this input stream. + */ +int BasicInputStream::available() +{ + if (closed) + return 0; + return source.available(); +} + + +/** + * Closes this input stream and releases any system resources + * associated with the stream. + */ +void BasicInputStream::close() +{ + if (closed) + return; + source.close(); + closed = true; +} + +/** + * Reads the next byte of data from the input stream. -1 if EOF + */ +int BasicInputStream::get() +{ + if (closed) + return -1; + return source.get(); +} + + + +//######################################################################### +//# B A S I C O U T P U T S T R E A M +//######################################################################### + +/** + * + */ +BasicOutputStream::BasicOutputStream(OutputStream &destinationStream) + : destination(destinationStream) +{ + closed = false; +} + +/** + * Closes this output stream and releases any system resources + * associated with this stream. + */ +void BasicOutputStream::close() +{ + if (closed) + return; + destination.close(); + closed = true; +} + +/** + * Flushes this output stream and forces any buffered output + * bytes to be written out. + */ +void BasicOutputStream::flush() +{ + if (closed) + return; + destination.flush(); +} + +/** + * Writes the specified byte to this output stream. + */ +void BasicOutputStream::put(int ch) +{ + if (closed) + return; + destination.put(ch); +} + + + +//######################################################################### +//# B A S I C R E A D E R +//######################################################################### + + +/** + * + */ +BasicReader::BasicReader(Reader &sourceReader) +{ + source = &sourceReader; +} + +/** + * Returns the number of bytes that can be read (or skipped over) from + * this reader without blocking by the next caller of a method for + * this reader. + */ +int BasicReader::available() +{ + if (source) + return source->available(); + else + return 0; +} + + +/** + * Closes this reader and releases any system resources + * associated with the reader. + */ +void BasicReader::close() +{ + if (source) + source->close(); +} + +/** + * Reads the next byte of data from the reader. + */ +gunichar BasicReader::get() +{ + if (source) + return source->get(); + else + return (gunichar)-1; +} + + + + + + +/** + * Reads a line of data from the reader. + */ +Glib::ustring BasicReader::readLine() +{ + Glib::ustring str; + while (available() > 0) + { + gunichar ch = get(); + if (ch == '\n') + break; + str.push_back(ch); + } + return str; +} + +/** + * Reads a line of data from the reader. + */ +Glib::ustring BasicReader::readWord() +{ + Glib::ustring str; + while (available() > 0) + { + gunichar ch = get(); + if (!g_unichar_isprint(ch)) + break; + str.push_back(ch); + } + return str; +} + + +static bool getLong(Glib::ustring &str, long *val) +{ + const char *begin = str.raw().c_str(); + char *end; + long ival = strtol(begin, &end, 10); + if (str == end) + return false; + *val = ival; + return true; +} + +static bool getULong(Glib::ustring &str, unsigned long *val) +{ + const char *begin = str.raw().c_str(); + char *end; + unsigned long ival = strtoul(begin, &end, 10); + if (str == end) + return false; + *val = ival; + return true; +} + +static bool getDouble(Glib::ustring &str, double *val) +{ + const char *begin = str.raw().c_str(); + char *end; + double ival = strtod(begin, &end); + if (str == end) + return false; + *val = ival; + return true; +} + + + + + + + +/** + * + */ +const Reader &BasicReader::readBool (bool& val ) +{ + Glib::ustring buf = readWord(); + if (buf == "true") + val = true; + else + val = false; + return *this; +} + +/** + * + */ +const Reader &BasicReader::readShort (short& val ) +{ + Glib::ustring buf = readWord(); + long ival; + if (getLong(buf, &ival)) + val = (short) ival; + return *this; +} + +/** + * + */ +const Reader &BasicReader::readUnsignedShort (unsigned short& val ) +{ + Glib::ustring buf = readWord(); + unsigned long ival; + if (getULong(buf, &ival)) + val = (unsigned short) ival; + return *this; +} + +/** + * + */ +const Reader &BasicReader::readInt (int& val ) +{ + Glib::ustring buf = readWord(); + long ival; + if (getLong(buf, &ival)) + val = (int) ival; + return *this; +} + +/** + * + */ +const Reader &BasicReader::readUnsignedInt (unsigned int& val ) +{ + Glib::ustring buf = readWord(); + unsigned long ival; + if (getULong(buf, &ival)) + val = (unsigned int) ival; + return *this; +} + +/** + * + */ +const Reader &BasicReader::readLong (long& val ) +{ + Glib::ustring buf = readWord(); + long ival; + if (getLong(buf, &ival)) + val = ival; + return *this; +} + +/** + * + */ +const Reader &BasicReader::readUnsignedLong (unsigned long& val ) +{ + Glib::ustring buf = readWord(); + unsigned long ival; + if (getULong(buf, &ival)) + val = ival; + return *this; +} + +/** + * + */ +const Reader &BasicReader::readFloat (float& val ) +{ + Glib::ustring buf = readWord(); + double ival; + if (getDouble(buf, &ival)) + val = (float)ival; + return *this; +} + +/** + * + */ +const Reader &BasicReader::readDouble (double& val ) +{ + Glib::ustring buf = readWord(); + double ival; + if (getDouble(buf, &ival)) + val = ival; + return *this; +} + + + +//######################################################################### +//# I N P U T S T R E A M R E A D E R +//######################################################################### + + +InputStreamReader::InputStreamReader(InputStream &inputStreamSource) + : inputStream(inputStreamSource) +{ +} + + + +/** + * Close the underlying OutputStream + */ +void InputStreamReader::close() +{ + inputStream.close(); +} + +/** + * Flush the underlying OutputStream + */ +int InputStreamReader::available() +{ + return inputStream.available(); +} + +/** + * Overloaded to receive its bytes from an InputStream + * rather than a Reader + */ +gunichar InputStreamReader::get() +{ + //Do we need conversions here? + gunichar ch = (gunichar)inputStream.get(); + return ch; +} + + + +//######################################################################### +//# S T D R E A D E R +//######################################################################### + + +/** + * + */ +StdReader::StdReader() +{ + inputStream = new StdInputStream(); +} + +/** + * + */ +StdReader::~StdReader() +{ + delete inputStream; +} + + + +/** + * Close the underlying OutputStream + */ +void StdReader::close() +{ + inputStream->close(); +} + +/** + * Flush the underlying OutputStream + */ +int StdReader::available() +{ + return inputStream->available(); +} + +/** + * Overloaded to receive its bytes from an InputStream + * rather than a Reader + */ +gunichar StdReader::get() +{ + //Do we need conversions here? + gunichar ch = (gunichar)inputStream->get(); + return ch; +} + + + + + +//######################################################################### +//# B A S I C W R I T E R +//######################################################################### + +/** + * + */ +BasicWriter::BasicWriter(Writer &destinationWriter) +{ + destination = &destinationWriter; +} + +/** + * Closes this writer and releases any system resources + * associated with this writer. + */ +void BasicWriter::close() +{ + if (destination) + destination->close(); +} + +/** + * Flushes this output stream and forces any buffered output + * bytes to be written out. + */ +void BasicWriter::flush() +{ + if (destination) + destination->flush(); +} + +/** + * Writes the specified byte to this output writer. + */ +void BasicWriter::put(gunichar ch) +{ + if (destination) + destination->put(ch); +} + +/** + * Provide printf()-like formatting + */ +Writer &BasicWriter::printf(char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + gchar *buf = g_strdup_vprintf(fmt, args); + va_end(args); + if (buf) { + writeString(buf); + g_free(buf); + } + return *this; +} +/** + * Writes the specified character to this output writer. + */ +Writer &BasicWriter::writeChar(char ch) +{ + gunichar uch = ch; + put(uch); + return *this; +} + + +/** + * Writes the specified unicode string to this output writer. + */ +Writer &BasicWriter::writeUString(Glib::ustring &str) +{ + for (int i=0; i< (int)str.size(); i++) + put(str[i]); + return *this; +} + +/** + * Writes the specified standard string to this output writer. + */ +Writer &BasicWriter::writeStdString(std::string &str) +{ + Glib::ustring tmp(str); + writeUString(tmp); + return *this; +} + +/** + * Writes the specified character string to this output writer. + */ +Writer &BasicWriter::writeString(const char *str) +{ + Glib::ustring tmp; + if (str) + tmp = str; + else + tmp = "null"; + writeUString(tmp); + return *this; +} + + + + +/** + * + */ +Writer &BasicWriter::writeBool (bool val ) +{ + if (val) + writeString("true"); + else + writeString("false"); + return *this; +} + + +/** + * + */ +Writer &BasicWriter::writeShort (short val ) +{ + gchar *buf = g_strdup_printf("%d", val); + if (buf) { + writeString(buf); + g_free(buf); + } + return *this; +} + + + +/** + * + */ +Writer &BasicWriter::writeUnsignedShort (unsigned short val ) +{ + gchar *buf = g_strdup_printf("%u", val); + if (buf) { + writeString(buf); + g_free(buf); + } + return *this; +} + +/** + * + */ +Writer &BasicWriter::writeInt (int val) +{ + gchar *buf = g_strdup_printf("%d", val); + if (buf) { + writeString(buf); + g_free(buf); + } + return *this; +} + +/** + * + */ +Writer &BasicWriter::writeUnsignedInt (unsigned int val) +{ + gchar *buf = g_strdup_printf("%u", val); + if (buf) { + writeString(buf); + g_free(buf); + } + return *this; +} + +/** + * + */ +Writer &BasicWriter::writeLong (long val) +{ + gchar *buf = g_strdup_printf("%ld", val); + if (buf) { + writeString(buf); + g_free(buf); + } + return *this; +} + +/** + * + */ +Writer &BasicWriter::writeUnsignedLong(unsigned long val) +{ + gchar *buf = g_strdup_printf("%lu", val); + if (buf) { + writeString(buf); + g_free(buf); + } + return *this; +} + +/** + * + */ +Writer &BasicWriter::writeFloat(float val) +{ +#if 1 + gchar *buf = g_strdup_printf("%8.3f", val); + if (buf) { + writeString(buf); + g_free(buf); + } +#else + std::string tmp = ftos(val, 'g', 8, 3, 0); + writeStdString(tmp); +#endif + return *this; +} + +/** + * + */ +Writer &BasicWriter::writeDouble(double val) +{ +#if 1 + gchar *buf = g_strdup_printf("%8.3f", val); + if (buf) { + writeString(buf); + g_free(buf); + } +#else + std::string tmp = ftos(val, 'g', 8, 3, 0); + writeStdString(tmp); +#endif + return *this; +} + + +Writer& operator<< (Writer &writer, char val) + { return writer.writeChar(val); } + +Writer& operator<< (Writer &writer, Glib::ustring &val) + { return writer.writeUString(val); } + +Writer& operator<< (Writer &writer, std::string &val) + { return writer.writeStdString(val); } + +Writer& operator<< (Writer &writer, char *val) + { return writer.writeString(val); } + +Writer& operator<< (Writer &writer, bool val) + { return writer.writeBool(val); } + +Writer& operator<< (Writer &writer, short val) + { return writer.writeShort(val); } + +Writer& operator<< (Writer &writer, unsigned short val) + { return writer.writeUnsignedShort(val); } + +Writer& operator<< (Writer &writer, int val) + { return writer.writeInt(val); } + +Writer& operator<< (Writer &writer, unsigned int val) + { return writer.writeUnsignedInt(val); } + +Writer& operator<< (Writer &writer, long val) + { return writer.writeLong(val); } + +Writer& operator<< (Writer &writer, unsigned long val) + { return writer.writeUnsignedLong(val); } + +Writer& operator<< (Writer &writer, float val) + { return writer.writeFloat(val); } + +Writer& operator<< (Writer &writer, double val) + { return writer.writeDouble(val); } + + + +//######################################################################### +//# O U T P U T S T R E A M W R I T E R +//######################################################################### + + +OutputStreamWriter::OutputStreamWriter(OutputStream &outputStreamDest) + : outputStream(outputStreamDest) +{ +} + + + +/** + * Close the underlying OutputStream + */ +void OutputStreamWriter::close() +{ + flush(); + outputStream.close(); +} + +/** + * Flush the underlying OutputStream + */ +void OutputStreamWriter::flush() +{ + outputStream.flush(); +} + +/** + * Overloaded to redirect the output chars from the next Writer + * in the chain to an OutputStream instead. + */ +void OutputStreamWriter::put(gunichar ch) +{ + //Do we need conversions here? + int intCh = (int) ch; + outputStream.put(intCh); +} + +//######################################################################### +//# S T D W R I T E R +//######################################################################### + + +/** + * + */ +StdWriter::StdWriter() +{ + outputStream = new StdOutputStream(); +} + + +/** + * + */ +StdWriter::~StdWriter() +{ + delete outputStream; +} + + + +/** + * Close the underlying OutputStream + */ +void StdWriter::close() +{ + flush(); + outputStream->close(); +} + +/** + * Flush the underlying OutputStream + */ +void StdWriter::flush() +{ + outputStream->flush(); +} + +/** + * Overloaded to redirect the output chars from the next Writer + * in the chain to an OutputStream instead. + */ +void StdWriter::put(gunichar ch) +{ + //Do we need conversions here? + int intCh = (int) ch; + outputStream->put(intCh); +} + + +} // namespace IO +} // namespace Inkscape + + +//######################################################################### +//# E N D O F F I L E +//######################################################################### diff --git a/src/io/inkscapestream.h b/src/io/inkscapestream.h new file mode 100644 index 000000000..ad213dad9 --- /dev/null +++ b/src/io/inkscapestream.h @@ -0,0 +1,669 @@ +#ifndef __INKSCAPE_IO_INKSCAPESTREAM_H__ +#define __INKSCAPE_IO_INKSCAPESTREAM_H__ +/** + * Our base basic stream classes. + * + * Authors: + * Bob Jamison + * + * Copyright (C) 2004 Inkscape.org + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + + +#include + +namespace Inkscape +{ +namespace IO +{ + +class StreamException : public std::exception +{ +public: + + StreamException(const char *theReason) throw() + { reason = theReason; } + StreamException(Glib::ustring &theReason) throw() + { reason = theReason; } + ~StreamException() throw() + { } + char const *what() const throw() + { return reason.c_str(); } + +private: + Glib::ustring reason; + +}; + +//######################################################################### +//# I N P U T S T R E A M +//######################################################################### + +/** + * This interface is the base of all input stream classes. Users who wish + * to make an InputStream that is part of a chain should inherit from + * BasicInputStream. Inherit from this class to make a source endpoint, + * such as a URI or buffer. + * + */ +class InputStream +{ + +public: + + /** + * Constructor. + */ + InputStream() {} + + /** + * Destructor + */ + virtual ~InputStream() {} + + /** + * Return the number of bytes that are currently available + * to be read + */ + virtual int available() = 0; + + /** + * Do whatever it takes to 'close' this input stream + * The most likely implementation of this method will be + * for endpoints that use a resource for their data. + */ + virtual void close() = 0; + + /** + * Read one byte from this input stream. This is a blocking + * call. If no data is currently available, this call will + * not return until it exists. If the user does not want + * their code to block, then the usual solution is: + * if (available() > 0) + * myChar = get(); + * This call returns -1 on end-of-file. + */ + virtual int get() = 0; + +}; // class InputStream + + + + +/** + * This is the class that most users should inherit, to provide + * their own streams. + * + */ +class BasicInputStream : public InputStream +{ + +public: + + BasicInputStream(InputStream &sourceStream); + + virtual ~BasicInputStream() {} + + virtual int available(); + + virtual void close(); + + virtual int get(); + +protected: + + bool closed; + + InputStream &source; + +private: + + +}; // class BasicInputStream + + + +/** + * Convenience class for reading from standard input + */ +class StdInputStream : public InputStream +{ +public: + + int available() + { return 0; } + + void close() + { /* do nothing */ } + + int get() + { return getchar(); } + +}; + + + + + + +//######################################################################### +//# O U T P U T S T R E A M +//######################################################################### + +/** + * This interface is the base of all input stream classes. Users who wish + * to make an OutputStream that is part of a chain should inherit from + * BasicOutputStream. Inherit from this class to make a destination endpoint, + * such as a URI or buffer. + */ +class OutputStream +{ + +public: + + /** + * Constructor. + */ + OutputStream() {} + + /** + * Destructor + */ + virtual ~OutputStream() {} + + /** + * This call should + * 1. flush itself + * 2. close itself + * 3. close the destination stream + */ + virtual void close() = 0; + + /** + * This call should push any pending data it might have to + * the destination stream. It should NOT call flush() on + * the destination stream. + */ + virtual void flush() = 0; + + /** + * Send one byte to the destination stream. + */ + virtual void put(int ch) = 0; + + +}; // class OutputStream + + +/** + * This is the class that most users should inherit, to provide + * their own output streams. + */ +class BasicOutputStream : public OutputStream +{ + +public: + + BasicOutputStream(OutputStream &destinationStream); + + virtual ~BasicOutputStream() {} + + virtual void close(); + + virtual void flush(); + + virtual void put(int ch); + +protected: + + bool closed; + + OutputStream &destination; + + +}; // class BasicOutputStream + + + +/** + * Convenience class for writing to standard output + */ +class StdOutputStream : public OutputStream +{ +public: + + void close() + { } + + void flush() + { } + + void put(int ch) + { putchar(ch); } + +}; + + + + +//######################################################################### +//# R E A D E R +//######################################################################### + + +/** + * This interface and its descendants are for unicode character-oriented input + * + */ +class Reader +{ + +public: + + /** + * Constructor. + */ + Reader() {} + + /** + * Destructor + */ + virtual ~Reader() {} + + + virtual int available() = 0; + + virtual void close() = 0; + + virtual gunichar get() = 0; + + virtual Glib::ustring readLine() = 0; + + virtual Glib::ustring readWord() = 0; + + /* Input formatting */ + virtual const Reader& readBool (bool& val ) = 0; + virtual const Reader& operator>> (bool& val ) = 0; + + virtual const Reader& readShort (short &val) = 0; + virtual const Reader& operator>> (short &val) = 0; + + virtual const Reader& readUnsignedShort (unsigned short &val) = 0; + virtual const Reader& operator>> (unsigned short &val) = 0; + + virtual const Reader& readInt (int &val) = 0; + virtual const Reader& operator>> (int &val) = 0; + + virtual const Reader& readUnsignedInt (unsigned int &val) = 0; + virtual const Reader& operator>> (unsigned int &val) = 0; + + virtual const Reader& readLong (long &val) = 0; + virtual const Reader& operator>> (long &val) = 0; + + virtual const Reader& readUnsignedLong (unsigned long &val) = 0; + virtual const Reader& operator>> (unsigned long &val) = 0; + + virtual const Reader& readFloat (float &val) = 0; + virtual const Reader& operator>> (float &val) = 0; + + virtual const Reader& readDouble (double &val) = 0; + virtual const Reader& operator>> (double &val) = 0; + +}; // interface Reader + + + +/** + * This class and its descendants are for unicode character-oriented input + * + */ +class BasicReader : public Reader +{ + +public: + + BasicReader(Reader &sourceStream); + + virtual ~BasicReader() {} + + virtual int available(); + + virtual void close(); + + virtual gunichar get(); + + virtual Glib::ustring readLine(); + + virtual Glib::ustring readWord(); + + /* Input formatting */ + virtual const Reader& readBool (bool& val ); + virtual const Reader& operator>> (bool& val ) + { return readBool(val); } + + virtual const Reader& readShort (short &val); + virtual const Reader& operator>> (short &val) + { return readShort(val); } + + virtual const Reader& readUnsignedShort (unsigned short &val); + virtual const Reader& operator>> (unsigned short &val) + { return readUnsignedShort(val); } + + virtual const Reader& readInt (int &val); + virtual const Reader& operator>> (int &val) + { return readInt(val); } + + virtual const Reader& readUnsignedInt (unsigned int &val); + virtual const Reader& operator>> (unsigned int &val) + { return readUnsignedInt(val); } + + virtual const Reader& readLong (long &val); + virtual const Reader& operator>> (long &val) + { return readLong(val); } + + virtual const Reader& readUnsignedLong (unsigned long &val); + virtual const Reader& operator>> (unsigned long &val) + { return readUnsignedLong(val); } + + virtual const Reader& readFloat (float &val); + virtual const Reader& operator>> (float &val) + { return readFloat(val); } + + virtual const Reader& readDouble (double &val); + virtual const Reader& operator>> (double &val) + { return readDouble(val); } + + +protected: + + Reader *source; + + BasicReader() + { source = NULL; } + +private: + +}; // class BasicReader + + + +/** + * Class for placing a Reader on an open InputStream + * + */ +class InputStreamReader : public BasicReader +{ +public: + + InputStreamReader(InputStream &inputStreamSource); + + /*Overload these 3 for your implementation*/ + virtual int available(); + + virtual void close(); + + virtual gunichar get(); + + +private: + + InputStream &inputStream; + + +}; + +/** + * Convenience class for reading formatted from standard input + * + */ +class StdReader : public BasicReader +{ +public: + + StdReader(); + + ~StdReader(); + + /*Overload these 3 for your implementation*/ + virtual int available(); + + virtual void close(); + + virtual gunichar get(); + + +private: + + InputStream *inputStream; + + +}; + + + + + +//######################################################################### +//# W R I T E R +//######################################################################### + +/** + * This interface and its descendants are for unicode character-oriented output + * + */ +class Writer +{ + +public: + + /** + * Constructor. + */ + Writer() {} + + /** + * Destructor + */ + virtual ~Writer() {} + + virtual void close() = 0; + + virtual void flush() = 0; + + virtual void put(gunichar ch) = 0; + + /* Formatted output */ + virtual Writer& printf(char *fmt, ...) = 0; + + virtual Writer& writeChar(char val) = 0; + + virtual Writer& writeUString(Glib::ustring &val) = 0; + + virtual Writer& writeStdString(std::string &val) = 0; + + virtual Writer& writeString(const char *str) = 0; + + virtual Writer& writeBool (bool val ) = 0; + + virtual Writer& writeShort (short val ) = 0; + + virtual Writer& writeUnsignedShort (unsigned short val ) = 0; + + virtual Writer& writeInt (int val ) = 0; + + virtual Writer& writeUnsignedInt (unsigned int val ) = 0; + + virtual Writer& writeLong (long val ) = 0; + + virtual Writer& writeUnsignedLong (unsigned long val ) = 0; + + virtual Writer& writeFloat (float val ) = 0; + + virtual Writer& writeDouble (double val ) = 0; + + + +}; // interface Writer + + +/** + * This class and its descendants are for unicode character-oriented output + * + */ +class BasicWriter : public Writer +{ + +public: + + BasicWriter(Writer &destinationWriter); + + virtual ~BasicWriter() {} + + /*Overload these 3 for your implementation*/ + virtual void close(); + + virtual void flush(); + + virtual void put(gunichar ch); + + + + /* Formatted output */ + virtual Writer &printf(char *fmt, ...); + + virtual Writer& writeChar(char val); + + virtual Writer& writeUString(Glib::ustring &val); + + virtual Writer& writeStdString(std::string &val); + + virtual Writer& writeString(const char *str); + + virtual Writer& writeBool (bool val ); + + virtual Writer& writeShort (short val ); + + virtual Writer& writeUnsignedShort (unsigned short val ); + + virtual Writer& writeInt (int val ); + + virtual Writer& writeUnsignedInt (unsigned int val ); + + virtual Writer& writeLong (long val ); + + virtual Writer& writeUnsignedLong (unsigned long val ); + + virtual Writer& writeFloat (float val ); + + virtual Writer& writeDouble (double val ); + + +protected: + + Writer *destination; + + BasicWriter() + { destination = NULL; } + +private: + +}; // class BasicWriter + + + +Writer& operator<< (Writer &writer, char val); + +Writer& operator<< (Writer &writer, Glib::ustring &val); + +Writer& operator<< (Writer &writer, std::string &val); + +Writer& operator<< (Writer &writer, char *val); + +Writer& operator<< (Writer &writer, bool val); + +Writer& operator<< (Writer &writer, short val); + +Writer& operator<< (Writer &writer, unsigned short val); + +Writer& operator<< (Writer &writer, int val); + +Writer& operator<< (Writer &writer, unsigned int val); + +Writer& operator<< (Writer &writer, long val); + +Writer& operator<< (Writer &writer, unsigned long val); + +Writer& operator<< (Writer &writer, float val); + +Writer& operator<< (Writer &writer, double val); + + + + +/** + * Class for placing a Writer on an open OutputStream + * + */ +class OutputStreamWriter : public BasicWriter +{ +public: + + OutputStreamWriter(OutputStream &outputStreamDest); + + /*Overload these 3 for your implementation*/ + virtual void close(); + + virtual void flush(); + + virtual void put(gunichar ch); + + +private: + + OutputStream &outputStream; + + +}; + + +/** + * Convenience class for writing to standard output + */ +class StdWriter : public BasicWriter +{ +public: + StdWriter(); + + ~StdWriter(); + + + virtual void close(); + + + virtual void flush(); + + + virtual void put(gunichar ch); + + +private: + + OutputStream *outputStream; + +}; + +//######################################################################### +//# U T I L I T Y +//######################################################################### + +void pipeStream(InputStream &source, OutputStream &dest); + + + +} // namespace IO +} // namespace Inkscape + + +#endif /* __INKSCAPE_IO_INKSCAPESTREAM_H__ */ diff --git a/src/io/makefile.in b/src/io/makefile.in new file mode 100644 index 000000000..61ee7437f --- /dev/null +++ b/src/io/makefile.in @@ -0,0 +1,17 @@ +# Convenience stub makefile to call the real Makefile. + +@SET_MAKE@ + +# Explicit so that it's the default rule. +all: + cd .. && $(MAKE) io/all + +clean %.a %.o: + cd .. && $(MAKE) io/$@ + +.PHONY: all clean + +OBJEXT = @OBJEXT@ + +.SUFFIXES: +.SUFFIXES: .a .$(OBJEXT) diff --git a/src/io/simple-sax.cpp b/src/io/simple-sax.cpp new file mode 100644 index 000000000..2dd78b451 --- /dev/null +++ b/src/io/simple-sax.cpp @@ -0,0 +1,1493 @@ +/* + * SimpleSAX + * + * Authors: + * Jon A. Cruz + * + * Copyright (C) 2004 AUTHORS + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + + +#include "simple-sax.h" + +namespace Inkscape { +namespace IO { + +SaxHandler::SaxHandler() +{ + memset( &sax, 0, sizeof(sax) ); + sax.startDocument = startDocument; + sax.endDocument = endDocument; + sax.startElement = startElement; + sax.endElement = endElement; + sax.characters = characters; +} + +SaxHandler::~SaxHandler() +{ +} + + +static int xmlErrorVals[] = { + XML_ERR_OK, + XML_ERR_INTERNAL_ERROR, + XML_ERR_NO_MEMORY, + XML_ERR_DOCUMENT_START, + XML_ERR_DOCUMENT_EMPTY, + XML_ERR_DOCUMENT_END, + XML_ERR_INVALID_HEX_CHARREF, + XML_ERR_INVALID_DEC_CHARREF, + XML_ERR_INVALID_CHARREF, + XML_ERR_INVALID_CHAR, + XML_ERR_CHARREF_AT_EOF, + XML_ERR_CHARREF_IN_PROLOG, + XML_ERR_CHARREF_IN_EPILOG, + XML_ERR_CHARREF_IN_DTD, + XML_ERR_ENTITYREF_AT_EOF, + XML_ERR_ENTITYREF_IN_PROLOG, + XML_ERR_ENTITYREF_IN_EPILOG, + XML_ERR_ENTITYREF_IN_DTD, + XML_ERR_PEREF_AT_EOF, + XML_ERR_PEREF_IN_PROLOG, + XML_ERR_PEREF_IN_EPILOG, + XML_ERR_PEREF_IN_INT_SUBSET, + XML_ERR_ENTITYREF_NO_NAME, + XML_ERR_ENTITYREF_SEMICOL_MISSING, + XML_ERR_PEREF_NO_NAME, + XML_ERR_PEREF_SEMICOL_MISSING, + XML_ERR_UNDECLARED_ENTITY, + XML_WAR_UNDECLARED_ENTITY, + XML_ERR_UNPARSED_ENTITY, + XML_ERR_ENTITY_IS_EXTERNAL, + XML_ERR_ENTITY_IS_PARAMETER, + XML_ERR_UNKNOWN_ENCODING, + XML_ERR_UNSUPPORTED_ENCODING, + XML_ERR_STRING_NOT_STARTED, + XML_ERR_STRING_NOT_CLOSED, + XML_ERR_NS_DECL_ERROR, + XML_ERR_ENTITY_NOT_STARTED, + XML_ERR_ENTITY_NOT_FINISHED, + XML_ERR_LT_IN_ATTRIBUTE, + XML_ERR_ATTRIBUTE_NOT_STARTED, + XML_ERR_ATTRIBUTE_NOT_FINISHED, + XML_ERR_ATTRIBUTE_WITHOUT_VALUE, + XML_ERR_ATTRIBUTE_REDEFINED, + XML_ERR_LITERAL_NOT_STARTED, + XML_ERR_LITERAL_NOT_FINISHED, + XML_ERR_COMMENT_NOT_FINISHED, + XML_ERR_PI_NOT_STARTED, + XML_ERR_PI_NOT_FINISHED, + XML_ERR_NOTATION_NOT_STARTED, + XML_ERR_NOTATION_NOT_FINISHED, + XML_ERR_ATTLIST_NOT_STARTED, + XML_ERR_ATTLIST_NOT_FINISHED, + XML_ERR_MIXED_NOT_STARTED, + XML_ERR_MIXED_NOT_FINISHED, + XML_ERR_ELEMCONTENT_NOT_STARTED, + XML_ERR_ELEMCONTENT_NOT_FINISHED, + XML_ERR_XMLDECL_NOT_STARTED, + XML_ERR_XMLDECL_NOT_FINISHED, + XML_ERR_CONDSEC_NOT_STARTED, + XML_ERR_CONDSEC_NOT_FINISHED, + XML_ERR_EXT_SUBSET_NOT_FINISHED, + XML_ERR_DOCTYPE_NOT_FINISHED, + XML_ERR_MISPLACED_CDATA_END, + XML_ERR_CDATA_NOT_FINISHED, + XML_ERR_RESERVED_XML_NAME, + XML_ERR_SPACE_REQUIRED, + XML_ERR_SEPARATOR_REQUIRED, + XML_ERR_NMTOKEN_REQUIRED, + XML_ERR_NAME_REQUIRED, + XML_ERR_PCDATA_REQUIRED, + XML_ERR_URI_REQUIRED, + XML_ERR_PUBID_REQUIRED, + XML_ERR_LT_REQUIRED, + XML_ERR_GT_REQUIRED, + XML_ERR_LTSLASH_REQUIRED, + XML_ERR_EQUAL_REQUIRED, + XML_ERR_TAG_NAME_MISMATCH, + XML_ERR_TAG_NOT_FINISHED, + XML_ERR_STANDALONE_VALUE, + XML_ERR_ENCODING_NAME, + XML_ERR_HYPHEN_IN_COMMENT, + XML_ERR_INVALID_ENCODING, + XML_ERR_EXT_ENTITY_STANDALONE, + XML_ERR_CONDSEC_INVALID, + XML_ERR_VALUE_REQUIRED, + XML_ERR_NOT_WELL_BALANCED, + XML_ERR_EXTRA_CONTENT, + XML_ERR_ENTITY_CHAR_ERROR, + XML_ERR_ENTITY_PE_INTERNAL, + XML_ERR_ENTITY_LOOP, + XML_ERR_ENTITY_BOUNDARY, + XML_ERR_INVALID_URI, + XML_ERR_URI_FRAGMENT, + XML_WAR_CATALOG_PI, + XML_ERR_NO_DTD, + XML_ERR_CONDSEC_INVALID_KEYWORD, + XML_ERR_VERSION_MISSING, + XML_WAR_UNKNOWN_VERSION, + XML_WAR_LANG_VALUE, + XML_WAR_NS_URI, + XML_WAR_NS_URI_RELATIVE, + XML_ERR_MISSING_ENCODING, + XML_NS_ERR_XML_NAMESPACE, + XML_NS_ERR_UNDEFINED_NAMESPACE, + XML_NS_ERR_QNAME, + XML_NS_ERR_ATTRIBUTE_REDEFINED, + XML_DTD_ATTRIBUTE_DEFAULT, + XML_DTD_ATTRIBUTE_REDEFINED, + XML_DTD_ATTRIBUTE_VALUE, + XML_DTD_CONTENT_ERROR, + XML_DTD_CONTENT_MODEL, + XML_DTD_CONTENT_NOT_DETERMINIST, + XML_DTD_DIFFERENT_PREFIX, + XML_DTD_ELEM_DEFAULT_NAMESPACE, + XML_DTD_ELEM_NAMESPACE, + XML_DTD_ELEM_REDEFINED, + XML_DTD_EMPTY_NOTATION, + XML_DTD_ENTITY_TYPE, + XML_DTD_ID_FIXED, + XML_DTD_ID_REDEFINED, + XML_DTD_ID_SUBSET, + XML_DTD_INVALID_CHILD, + XML_DTD_INVALID_DEFAULT, + XML_DTD_LOAD_ERROR, + XML_DTD_MISSING_ATTRIBUTE, + XML_DTD_MIXED_CORRUPT, + XML_DTD_MULTIPLE_ID, + XML_DTD_NO_DOC, + XML_DTD_NO_DTD, + XML_DTD_NO_ELEM_NAME, + XML_DTD_NO_PREFIX, + XML_DTD_NO_ROOT, + XML_DTD_NOTATION_REDEFINED, + XML_DTD_NOTATION_VALUE, + XML_DTD_NOT_EMPTY, + XML_DTD_NOT_PCDATA, + XML_DTD_NOT_STANDALONE, + XML_DTD_ROOT_NAME, + XML_DTD_STANDALONE_WHITE_SPACE, + XML_DTD_UNKNOWN_ATTRIBUTE, + XML_DTD_UNKNOWN_ELEM, + XML_DTD_UNKNOWN_ENTITY, + XML_DTD_UNKNOWN_ID, + XML_DTD_UNKNOWN_NOTATION, + XML_DTD_STANDALONE_DEFAULTED, + XML_DTD_XMLID_VALUE, + XML_DTD_XMLID_TYPE, + XML_HTML_STRUCURE_ERROR, + XML_HTML_UNKNOWN_TAG, + XML_RNGP_ANYNAME_ATTR_ANCESTOR, + XML_RNGP_ATTR_CONFLICT, + XML_RNGP_ATTRIBUTE_CHILDREN, + XML_RNGP_ATTRIBUTE_CONTENT, + XML_RNGP_ATTRIBUTE_EMPTY, + XML_RNGP_ATTRIBUTE_NOOP, + XML_RNGP_CHOICE_CONTENT, + XML_RNGP_CHOICE_EMPTY, + XML_RNGP_CREATE_FAILURE, + XML_RNGP_DATA_CONTENT, + XML_RNGP_DEF_CHOICE_AND_INTERLEAVE, + XML_RNGP_DEFINE_CREATE_FAILED, + XML_RNGP_DEFINE_EMPTY, + XML_RNGP_DEFINE_MISSING, + XML_RNGP_DEFINE_NAME_MISSING, + XML_RNGP_ELEM_CONTENT_EMPTY, + XML_RNGP_ELEM_CONTENT_ERROR, + XML_RNGP_ELEMENT_EMPTY, + XML_RNGP_ELEMENT_CONTENT, + XML_RNGP_ELEMENT_NAME, + XML_RNGP_ELEMENT_NO_CONTENT, + XML_RNGP_ELEM_TEXT_CONFLICT, + XML_RNGP_EMPTY, + XML_RNGP_EMPTY_CONSTRUCT, + XML_RNGP_EMPTY_CONTENT, + XML_RNGP_EMPTY_NOT_EMPTY, + XML_RNGP_ERROR_TYPE_LIB, + XML_RNGP_EXCEPT_EMPTY, + XML_RNGP_EXCEPT_MISSING, + XML_RNGP_EXCEPT_MULTIPLE, + XML_RNGP_EXCEPT_NO_CONTENT, + XML_RNGP_EXTERNALREF_EMTPY, + XML_RNGP_EXTERNAL_REF_FAILURE, + XML_RNGP_EXTERNALREF_RECURSE, + XML_RNGP_FORBIDDEN_ATTRIBUTE, + XML_RNGP_FOREIGN_ELEMENT, + XML_RNGP_GRAMMAR_CONTENT, + XML_RNGP_GRAMMAR_EMPTY, + XML_RNGP_GRAMMAR_MISSING, + XML_RNGP_GRAMMAR_NO_START, + XML_RNGP_GROUP_ATTR_CONFLICT, + XML_RNGP_HREF_ERROR, + XML_RNGP_INCLUDE_EMPTY, + XML_RNGP_INCLUDE_FAILURE, + XML_RNGP_INCLUDE_RECURSE, + XML_RNGP_INTERLEAVE_ADD, + XML_RNGP_INTERLEAVE_CREATE_FAILED, + XML_RNGP_INTERLEAVE_EMPTY, + XML_RNGP_INTERLEAVE_NO_CONTENT, + XML_RNGP_INVALID_DEFINE_NAME, + XML_RNGP_INVALID_URI, + XML_RNGP_INVALID_VALUE, + XML_RNGP_MISSING_HREF, + XML_RNGP_NAME_MISSING, + XML_RNGP_NEED_COMBINE, + XML_RNGP_NOTALLOWED_NOT_EMPTY, + XML_RNGP_NSNAME_ATTR_ANCESTOR, + XML_RNGP_NSNAME_NO_NS, + XML_RNGP_PARAM_FORBIDDEN, + XML_RNGP_PARAM_NAME_MISSING, + XML_RNGP_PARENTREF_CREATE_FAILED, + XML_RNGP_PARENTREF_NAME_INVALID, + XML_RNGP_PARENTREF_NO_NAME, + XML_RNGP_PARENTREF_NO_PARENT, + XML_RNGP_PARENTREF_NOT_EMPTY, + XML_RNGP_PARSE_ERROR, + XML_RNGP_PAT_ANYNAME_EXCEPT_ANYNAME, + XML_RNGP_PAT_ATTR_ATTR, + XML_RNGP_PAT_ATTR_ELEM, + XML_RNGP_PAT_DATA_EXCEPT_ATTR, + XML_RNGP_PAT_DATA_EXCEPT_ELEM, + XML_RNGP_PAT_DATA_EXCEPT_EMPTY, + XML_RNGP_PAT_DATA_EXCEPT_GROUP, + XML_RNGP_PAT_DATA_EXCEPT_INTERLEAVE, + XML_RNGP_PAT_DATA_EXCEPT_LIST, + XML_RNGP_PAT_DATA_EXCEPT_ONEMORE, + XML_RNGP_PAT_DATA_EXCEPT_REF, + XML_RNGP_PAT_DATA_EXCEPT_TEXT, + XML_RNGP_PAT_LIST_ATTR, + XML_RNGP_PAT_LIST_ELEM, + XML_RNGP_PAT_LIST_INTERLEAVE, + XML_RNGP_PAT_LIST_LIST, + XML_RNGP_PAT_LIST_REF, + XML_RNGP_PAT_LIST_TEXT, + XML_RNGP_PAT_NSNAME_EXCEPT_ANYNAME, + XML_RNGP_PAT_NSNAME_EXCEPT_NSNAME, + XML_RNGP_PAT_ONEMORE_GROUP_ATTR, + XML_RNGP_PAT_ONEMORE_INTERLEAVE_ATTR, + XML_RNGP_PAT_START_ATTR, + XML_RNGP_PAT_START_DATA, + XML_RNGP_PAT_START_EMPTY, + XML_RNGP_PAT_START_GROUP, + XML_RNGP_PAT_START_INTERLEAVE, + XML_RNGP_PAT_START_LIST, + XML_RNGP_PAT_START_ONEMORE, + XML_RNGP_PAT_START_TEXT, + XML_RNGP_PAT_START_VALUE, + XML_RNGP_PREFIX_UNDEFINED, + XML_RNGP_REF_CREATE_FAILED, + XML_RNGP_REF_CYCLE, + XML_RNGP_REF_NAME_INVALID, + XML_RNGP_REF_NO_DEF, + XML_RNGP_REF_NO_NAME, + XML_RNGP_REF_NOT_EMPTY, + XML_RNGP_START_CHOICE_AND_INTERLEAVE, + XML_RNGP_START_CONTENT, + XML_RNGP_START_EMPTY, + XML_RNGP_START_MISSING, + XML_RNGP_TEXT_EXPECTED, + XML_RNGP_TEXT_HAS_CHILD, + XML_RNGP_TYPE_MISSING, + XML_RNGP_TYPE_NOT_FOUND, + XML_RNGP_TYPE_VALUE, + XML_RNGP_UNKNOWN_ATTRIBUTE, + XML_RNGP_UNKNOWN_COMBINE, + XML_RNGP_UNKNOWN_CONSTRUCT, + XML_RNGP_UNKNOWN_TYPE_LIB, + XML_RNGP_URI_FRAGMENT, + XML_RNGP_URI_NOT_ABSOLUTE, + XML_RNGP_VALUE_EMPTY, + XML_RNGP_VALUE_NO_CONTENT, + XML_RNGP_XMLNS_NAME, + XML_RNGP_XML_NS, + XML_XPATH_EXPRESSION_OK, + XML_XPATH_NUMBER_ERROR, + XML_XPATH_UNFINISHED_LITERAL_ERROR, + XML_XPATH_START_LITERAL_ERROR, + XML_XPATH_VARIABLE_REF_ERROR, + XML_XPATH_UNDEF_VARIABLE_ERROR, + XML_XPATH_INVALID_PREDICATE_ERROR, + XML_XPATH_EXPR_ERROR, + XML_XPATH_UNCLOSED_ERROR, + XML_XPATH_UNKNOWN_FUNC_ERROR, + XML_XPATH_INVALID_OPERAND, + XML_XPATH_INVALID_TYPE, + XML_XPATH_INVALID_ARITY, + XML_XPATH_INVALID_CTXT_SIZE, + XML_XPATH_INVALID_CTXT_POSITION, + XML_XPATH_MEMORY_ERROR, + XML_XPTR_SYNTAX_ERROR, + XML_XPTR_RESOURCE_ERROR, + XML_XPTR_SUB_RESOURCE_ERROR, + XML_XPATH_UNDEF_PREFIX_ERROR, + XML_XPATH_ENCODING_ERROR, + XML_XPATH_INVALID_CHAR_ERROR, + XML_TREE_INVALID_HEX, + XML_TREE_INVALID_DEC, + XML_TREE_UNTERMINATED_ENTITY, + XML_SAVE_NOT_UTF8, + XML_SAVE_CHAR_INVALID, + XML_SAVE_NO_DOCTYPE, + XML_SAVE_UNKNOWN_ENCODING, + XML_REGEXP_COMPILE_ERROR, + XML_IO_UNKNOWN, + XML_IO_EACCES, + XML_IO_EAGAIN, + XML_IO_EBADF, + XML_IO_EBADMSG, + XML_IO_EBUSY, + XML_IO_ECANCELED, + XML_IO_ECHILD, + XML_IO_EDEADLK, + XML_IO_EDOM, + XML_IO_EEXIST, + XML_IO_EFAULT, + XML_IO_EFBIG, + XML_IO_EINPROGRESS, + XML_IO_EINTR, + XML_IO_EINVAL, + XML_IO_EIO, + XML_IO_EISDIR, + XML_IO_EMFILE, + XML_IO_EMLINK, + XML_IO_EMSGSIZE, + XML_IO_ENAMETOOLONG, + XML_IO_ENFILE, + XML_IO_ENODEV, + XML_IO_ENOENT, + XML_IO_ENOEXEC, + XML_IO_ENOLCK, + XML_IO_ENOMEM, + XML_IO_ENOSPC, + XML_IO_ENOSYS, + XML_IO_ENOTDIR, + XML_IO_ENOTEMPTY, + XML_IO_ENOTSUP, + XML_IO_ENOTTY, + XML_IO_ENXIO, + XML_IO_EPERM, + XML_IO_EPIPE, + XML_IO_ERANGE, + XML_IO_EROFS, + XML_IO_ESPIPE, + XML_IO_ESRCH, + XML_IO_ETIMEDOUT, + XML_IO_EXDEV, + XML_IO_NETWORK_ATTEMPT, + XML_IO_ENCODER, + XML_IO_FLUSH, + XML_IO_WRITE, + XML_IO_NO_INPUT, + XML_IO_BUFFER_FULL, + XML_IO_LOAD_ERROR, + XML_IO_ENOTSOCK, + XML_IO_EISCONN, + XML_IO_ECONNREFUSED, + XML_IO_ENETUNREACH, + XML_IO_EADDRINUSE, + XML_IO_EALREADY, + XML_IO_EAFNOSUPPORT, + XML_XINCLUDE_RECURSION, + XML_XINCLUDE_PARSE_VALUE, + XML_XINCLUDE_ENTITY_DEF_MISMATCH, + XML_XINCLUDE_NO_HREF, + XML_XINCLUDE_NO_FALLBACK, + XML_XINCLUDE_HREF_URI, + XML_XINCLUDE_TEXT_FRAGMENT, + XML_XINCLUDE_TEXT_DOCUMENT, + XML_XINCLUDE_INVALID_CHAR, + XML_XINCLUDE_BUILD_FAILED, + XML_XINCLUDE_UNKNOWN_ENCODING, + XML_XINCLUDE_MULTIPLE_ROOT, + XML_XINCLUDE_XPTR_FAILED, + XML_XINCLUDE_XPTR_RESULT, + XML_XINCLUDE_INCLUDE_IN_INCLUDE, + XML_XINCLUDE_FALLBACKS_IN_INCLUDE, + XML_XINCLUDE_FALLBACK_NOT_IN_INCLUDE, + XML_XINCLUDE_DEPRECATED_NS, + XML_XINCLUDE_FRAGMENT_ID, + XML_CATALOG_MISSING_ATTR, + XML_CATALOG_ENTRY_BROKEN, + XML_CATALOG_PREFER_VALUE, + XML_CATALOG_NOT_CATALOG, + XML_CATALOG_RECURSION, + XML_SCHEMAP_PREFIX_UNDEFINED, + XML_SCHEMAP_ATTRFORMDEFAULT_VALUE, + XML_SCHEMAP_ATTRGRP_NONAME_NOREF, + XML_SCHEMAP_ATTR_NONAME_NOREF, + XML_SCHEMAP_COMPLEXTYPE_NONAME_NOREF, + XML_SCHEMAP_ELEMFORMDEFAULT_VALUE, + XML_SCHEMAP_ELEM_NONAME_NOREF, + XML_SCHEMAP_EXTENSION_NO_BASE, + XML_SCHEMAP_FACET_NO_VALUE, + XML_SCHEMAP_FAILED_BUILD_IMPORT, + XML_SCHEMAP_GROUP_NONAME_NOREF, + XML_SCHEMAP_IMPORT_NAMESPACE_NOT_URI, + XML_SCHEMAP_IMPORT_REDEFINE_NSNAME, + XML_SCHEMAP_IMPORT_SCHEMA_NOT_URI, + XML_SCHEMAP_INVALID_BOOLEAN, + XML_SCHEMAP_INVALID_ENUM, + XML_SCHEMAP_INVALID_FACET, + XML_SCHEMAP_INVALID_FACET_VALUE, + XML_SCHEMAP_INVALID_MAXOCCURS, + XML_SCHEMAP_INVALID_MINOCCURS, + XML_SCHEMAP_INVALID_REF_AND_SUBTYPE, + XML_SCHEMAP_INVALID_WHITE_SPACE, + XML_SCHEMAP_NOATTR_NOREF, + XML_SCHEMAP_NOTATION_NO_NAME, + XML_SCHEMAP_NOTYPE_NOREF, + XML_SCHEMAP_REF_AND_SUBTYPE, + XML_SCHEMAP_RESTRICTION_NONAME_NOREF, + XML_SCHEMAP_SIMPLETYPE_NONAME, + XML_SCHEMAP_TYPE_AND_SUBTYPE, + XML_SCHEMAP_UNKNOWN_ALL_CHILD, + XML_SCHEMAP_UNKNOWN_ANYATTRIBUTE_CHILD, + XML_SCHEMAP_UNKNOWN_ATTR_CHILD, + XML_SCHEMAP_UNKNOWN_ATTRGRP_CHILD, + XML_SCHEMAP_UNKNOWN_ATTRIBUTE_GROUP, + XML_SCHEMAP_UNKNOWN_BASE_TYPE, + XML_SCHEMAP_UNKNOWN_CHOICE_CHILD, + XML_SCHEMAP_UNKNOWN_COMPLEXCONTENT_CHILD, + XML_SCHEMAP_UNKNOWN_COMPLEXTYPE_CHILD, + XML_SCHEMAP_UNKNOWN_ELEM_CHILD, + XML_SCHEMAP_UNKNOWN_EXTENSION_CHILD, + XML_SCHEMAP_UNKNOWN_FACET_CHILD, + XML_SCHEMAP_UNKNOWN_FACET_TYPE, + XML_SCHEMAP_UNKNOWN_GROUP_CHILD, + XML_SCHEMAP_UNKNOWN_IMPORT_CHILD, + XML_SCHEMAP_UNKNOWN_LIST_CHILD, + XML_SCHEMAP_UNKNOWN_NOTATION_CHILD, + XML_SCHEMAP_UNKNOWN_PROCESSCONTENT_CHILD, + XML_SCHEMAP_UNKNOWN_REF, + XML_SCHEMAP_UNKNOWN_RESTRICTION_CHILD, + XML_SCHEMAP_UNKNOWN_SCHEMAS_CHILD, + XML_SCHEMAP_UNKNOWN_SEQUENCE_CHILD, + XML_SCHEMAP_UNKNOWN_SIMPLECONTENT_CHILD, + XML_SCHEMAP_UNKNOWN_SIMPLETYPE_CHILD, + XML_SCHEMAP_UNKNOWN_TYPE, + XML_SCHEMAP_UNKNOWN_UNION_CHILD, + XML_SCHEMAP_ELEM_DEFAULT_FIXED, + XML_SCHEMAP_REGEXP_INVALID, + XML_SCHEMAP_FAILED_LOAD, + XML_SCHEMAP_NOTHING_TO_PARSE, + XML_SCHEMAP_NOROOT, + XML_SCHEMAP_REDEFINED_GROUP, + XML_SCHEMAP_REDEFINED_TYPE, + XML_SCHEMAP_REDEFINED_ELEMENT, + XML_SCHEMAP_REDEFINED_ATTRGROUP, + XML_SCHEMAP_REDEFINED_ATTR, + XML_SCHEMAP_REDEFINED_NOTATION, + XML_SCHEMAP_FAILED_PARSE, + XML_SCHEMAP_UNKNOWN_PREFIX, + XML_SCHEMAP_DEF_AND_PREFIX, + XML_SCHEMAP_UNKNOWN_INCLUDE_CHILD, + XML_SCHEMAP_INCLUDE_SCHEMA_NOT_URI, + XML_SCHEMAP_INCLUDE_SCHEMA_NO_URI, + XML_SCHEMAP_NOT_SCHEMA, + XML_SCHEMAP_UNKNOWN_MEMBER_TYPE, + XML_SCHEMAP_INVALID_ATTR_USE, + XML_SCHEMAP_RECURSIVE, + XML_SCHEMAP_SUPERNUMEROUS_LIST_ITEM_TYPE, + XML_SCHEMAP_INVALID_ATTR_COMBINATION, + XML_SCHEMAP_INVALID_ATTR_INLINE_COMBINATION, + XML_SCHEMAP_MISSING_SIMPLETYPE_CHILD, + XML_SCHEMAP_INVALID_ATTR_NAME, + XML_SCHEMAP_REF_AND_CONTENT, + XML_SCHEMAP_CT_PROPS_CORRECT_1, + XML_SCHEMAP_CT_PROPS_CORRECT_2, + XML_SCHEMAP_CT_PROPS_CORRECT_3, + XML_SCHEMAP_CT_PROPS_CORRECT_4, + XML_SCHEMAP_CT_PROPS_CORRECT_5, + XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1, + XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_1, + XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_2, + XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_2, + XML_SCHEMAP_DERIVATION_OK_RESTRICTION_3, + XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER, + XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE, + XML_SCHEMAP_UNION_NOT_EXPRESSIBLE, + XML_SCHEMAP_SRC_IMPORT_3_1, + XML_SCHEMAP_SRC_IMPORT_3_2, + XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_1, + XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_2, + XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_3, + XML_SCHEMAP_COS_CT_EXTENDS_1_3, + XML_SCHEMAV_NOROOT, + XML_SCHEMAV_UNDECLAREDELEM, + XML_SCHEMAV_NOTTOPLEVEL, + XML_SCHEMAV_MISSING, + XML_SCHEMAV_WRONGELEM, + XML_SCHEMAV_NOTYPE, + XML_SCHEMAV_NOROLLBACK, + XML_SCHEMAV_ISABSTRACT, + XML_SCHEMAV_NOTEMPTY, + XML_SCHEMAV_ELEMCONT, + XML_SCHEMAV_HAVEDEFAULT, + XML_SCHEMAV_NOTNILLABLE, + XML_SCHEMAV_EXTRACONTENT, + XML_SCHEMAV_INVALIDATTR, + XML_SCHEMAV_INVALIDELEM, + XML_SCHEMAV_NOTDETERMINIST, + XML_SCHEMAV_CONSTRUCT, + XML_SCHEMAV_INTERNAL, + XML_SCHEMAV_NOTSIMPLE, + XML_SCHEMAV_ATTRUNKNOWN, + XML_SCHEMAV_ATTRINVALID, + XML_SCHEMAV_VALUE, + XML_SCHEMAV_FACET, + XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1, + XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2, + XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3, + XML_SCHEMAV_CVC_TYPE_3_1_1, + XML_SCHEMAV_CVC_TYPE_3_1_2, + XML_SCHEMAV_CVC_FACET_VALID, + XML_SCHEMAV_CVC_LENGTH_VALID, + XML_SCHEMAV_CVC_MINLENGTH_VALID, + XML_SCHEMAV_CVC_MAXLENGTH_VALID, + XML_SCHEMAV_CVC_MININCLUSIVE_VALID, + XML_SCHEMAV_CVC_MAXINCLUSIVE_VALID, + XML_SCHEMAV_CVC_MINEXCLUSIVE_VALID, + XML_SCHEMAV_CVC_MAXEXCLUSIVE_VALID, + XML_SCHEMAV_CVC_TOTALDIGITS_VALID, + XML_SCHEMAV_CVC_FRACTIONDIGITS_VALID, + XML_SCHEMAV_CVC_PATTERN_VALID, + XML_SCHEMAV_CVC_ENUMERATION_VALID, + XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1, + XML_SCHEMAV_CVC_COMPLEX_TYPE_2_2, + XML_SCHEMAV_CVC_COMPLEX_TYPE_2_3, + XML_SCHEMAV_CVC_COMPLEX_TYPE_2_4, + +#if defined XML_SCHEMAV_CVC_ELT_1 + XML_SCHEMAV_CVC_ELT_1, + XML_SCHEMAV_CVC_ELT_2, + XML_SCHEMAV_CVC_ELT_3_1, + XML_SCHEMAV_CVC_ELT_3_2_1, + XML_SCHEMAV_CVC_ELT_3_2_2, + XML_SCHEMAV_CVC_ELT_4_1, + XML_SCHEMAV_CVC_ELT_4_2, + XML_SCHEMAV_CVC_ELT_4_3, + XML_SCHEMAV_CVC_ELT_5_1_1, + XML_SCHEMAV_CVC_ELT_5_1_2, + XML_SCHEMAV_CVC_ELT_5_2_1, + XML_SCHEMAV_CVC_ELT_5_2_2_1, + XML_SCHEMAV_CVC_ELT_5_2_2_2_1, + XML_SCHEMAV_CVC_ELT_5_2_2_2_2, + XML_SCHEMAV_CVC_ELT_6, + XML_SCHEMAV_CVC_ELT_7, + XML_SCHEMAV_CVC_ATTRIBUTE_1, + XML_SCHEMAV_CVC_ATTRIBUTE_2, + XML_SCHEMAV_CVC_ATTRIBUTE_3, + XML_SCHEMAV_CVC_ATTRIBUTE_4, + XML_SCHEMAV_CVC_COMPLEX_TYPE_3_1, + XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_1, + XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_2, + XML_SCHEMAV_CVC_COMPLEX_TYPE_4, + XML_SCHEMAV_CVC_COMPLEX_TYPE_5_1, + XML_SCHEMAV_CVC_COMPLEX_TYPE_5_2, + XML_SCHEMAV_ELEMENT_CONTENT, + XML_SCHEMAV_DOCUMENT_ELEMENT_MISSING, +#endif + +#if defined XML_SCHEMAV_CVC_COMPLEX_TYPE_1 + XML_SCHEMAV_CVC_COMPLEX_TYPE_1, + XML_SCHEMAV_CVC_AU, + XML_SCHEMAV_CVC_TYPE_1, + XML_SCHEMAV_CVC_TYPE_2, +#endif + + XML_XPTR_UNKNOWN_SCHEME, + XML_XPTR_CHILDSEQ_START, + XML_XPTR_EVAL_FAILED, + XML_XPTR_EXTRA_OBJECTS, + XML_C14N_CREATE_CTXT, + XML_C14N_REQUIRES_UTF8, + XML_C14N_CREATE_STACK, + XML_C14N_INVALID_NODE, + XML_FTP_PASV_ANSWER, + XML_FTP_EPSV_ANSWER, + XML_FTP_ACCNT, + XML_HTTP_URL_SYNTAX, + XML_HTTP_USE_IP, + XML_HTTP_UNKNOWN_HOST, + XML_SCHEMAP_SRC_SIMPLE_TYPE_1, + XML_SCHEMAP_SRC_SIMPLE_TYPE_2, + XML_SCHEMAP_SRC_SIMPLE_TYPE_3, + XML_SCHEMAP_SRC_SIMPLE_TYPE_4, + XML_SCHEMAP_SRC_RESOLVE, + XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE, + XML_SCHEMAP_SRC_LIST_ITEMTYPE_OR_SIMPLETYPE, + XML_SCHEMAP_SRC_UNION_MEMBERTYPES_OR_SIMPLETYPES, + XML_SCHEMAP_ST_PROPS_CORRECT_1, + XML_SCHEMAP_ST_PROPS_CORRECT_2, + XML_SCHEMAP_ST_PROPS_CORRECT_3, + XML_SCHEMAP_COS_ST_RESTRICTS_1_1, + XML_SCHEMAP_COS_ST_RESTRICTS_1_2, + XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1, + XML_SCHEMAP_COS_ST_RESTRICTS_1_3_2, + XML_SCHEMAP_COS_ST_RESTRICTS_2_1, + XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1, + XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2, + XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1, + XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2, + XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3, + XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4, + XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_5, + XML_SCHEMAP_COS_ST_RESTRICTS_3_1, + XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1, + XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2, + XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2, + XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1, + XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3, + XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4, + XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_5, + XML_SCHEMAP_COS_ST_DERIVED_OK_2_1, + XML_SCHEMAP_COS_ST_DERIVED_OK_2_2, + XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED, + XML_SCHEMAP_S4S_ELEM_MISSING, + XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, + XML_SCHEMAP_S4S_ATTR_MISSING, + +#if defined XML_SCHEMAP_S4S_ATTR_INVALID_VALUE + XML_SCHEMAP_S4S_ATTR_INVALID_VALUE, + XML_SCHEMAP_SRC_ELEMENT_1, + XML_SCHEMAP_SRC_ELEMENT_2_1, + XML_SCHEMAP_SRC_ELEMENT_2_2, + XML_SCHEMAP_SRC_ELEMENT_3, + XML_SCHEMAP_P_PROPS_CORRECT_1, + XML_SCHEMAP_P_PROPS_CORRECT_2_1, + XML_SCHEMAP_P_PROPS_CORRECT_2_2, + XML_SCHEMAP_E_PROPS_CORRECT_2, + XML_SCHEMAP_E_PROPS_CORRECT_3, + XML_SCHEMAP_E_PROPS_CORRECT_4, + XML_SCHEMAP_E_PROPS_CORRECT_5, + XML_SCHEMAP_E_PROPS_CORRECT_6, + XML_SCHEMAP_SRC_INCLUDE, + XML_SCHEMAP_SRC_ATTRIBUTE_1, + XML_SCHEMAP_SRC_ATTRIBUTE_2, + XML_SCHEMAP_SRC_ATTRIBUTE_3_1, + XML_SCHEMAP_SRC_ATTRIBUTE_3_2, + XML_SCHEMAP_SRC_ATTRIBUTE_4, + XML_SCHEMAP_NO_XMLNS, + XML_SCHEMAP_NO_XSI, + XML_SCHEMAP_COS_VALID_DEFAULT_1, + XML_SCHEMAP_COS_VALID_DEFAULT_2_1, + XML_SCHEMAP_COS_VALID_DEFAULT_2_2_1, + XML_SCHEMAP_COS_VALID_DEFAULT_2_2_2, + XML_SCHEMAP_CVC_SIMPLE_TYPE, + XML_SCHEMAP_COS_CT_EXTENDS_1_1, + XML_SCHEMAP_SRC_IMPORT_1_1, + XML_SCHEMAP_SRC_IMPORT_1_2, + XML_SCHEMAP_SRC_IMPORT_2, + XML_SCHEMAP_SRC_IMPORT_2_1, + XML_SCHEMAP_SRC_IMPORT_2_2, +#endif + +#if defined XML_SCHEMAP_INTERNAL + XML_SCHEMAP_INTERNAL, + XML_SCHEMAP_NOT_DETERMINISTIC, +#endif + +#if defined XML_SCHEMAP_SRC_ATTRIBUTE_GROUP_1 + XML_SCHEMAP_SRC_ATTRIBUTE_GROUP_1, + XML_SCHEMAP_SRC_ATTRIBUTE_GROUP_2, + XML_SCHEMAP_SRC_ATTRIBUTE_GROUP_3, + XML_SCHEMAP_MG_PROPS_CORRECT_1, + XML_SCHEMAP_MG_PROPS_CORRECT_2, + XML_SCHEMAP_SRC_CT_1, + XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_3, + XML_SCHEMAP_AU_PROPS_CORRECT_2, + XML_SCHEMAP_A_PROPS_CORRECT_2, +#endif + -1 +}; + + +static const char* xmlErrorStrs[] = { + "ERR_OK", + "ERR_INTERNAL_ERROR", + "ERR_NO_MEMORY", + "ERR_DOCUMENT_START", + "ERR_DOCUMENT_EMPTY", + "ERR_DOCUMENT_END", + "ERR_INVALID_HEX_CHARREF", + "ERR_INVALID_DEC_CHARREF", + "ERR_INVALID_CHARREF", + "ERR_INVALID_CHAR", + "ERR_CHARREF_AT_EOF", + "ERR_CHARREF_IN_PROLOG", + "ERR_CHARREF_IN_EPILOG", + "ERR_CHARREF_IN_DTD", + "ERR_ENTITYREF_AT_EOF", + "ERR_ENTITYREF_IN_PROLOG", + "ERR_ENTITYREF_IN_EPILOG", + "ERR_ENTITYREF_IN_DTD", + "ERR_PEREF_AT_EOF", + "ERR_PEREF_IN_PROLOG", + "ERR_PEREF_IN_EPILOG", + "ERR_PEREF_IN_INT_SUBSET", + "ERR_ENTITYREF_NO_NAME", + "ERR_ENTITYREF_SEMICOL_MISSING", + "ERR_PEREF_NO_NAME", + "ERR_PEREF_SEMICOL_MISSING", + "ERR_UNDECLARED_ENTITY", + "WAR_UNDECLARED_ENTITY", + "ERR_UNPARSED_ENTITY", + "ERR_ENTITY_IS_EXTERNAL", + "ERR_ENTITY_IS_PARAMETER", + "ERR_UNKNOWN_ENCODING", + "ERR_UNSUPPORTED_ENCODING", + "ERR_STRING_NOT_STARTED", + "ERR_STRING_NOT_CLOSED", + "ERR_NS_DECL_ERROR", + "ERR_ENTITY_NOT_STARTED", + "ERR_ENTITY_NOT_FINISHED", + "ERR_LT_IN_ATTRIBUTE", + "ERR_ATTRIBUTE_NOT_STARTED", + "ERR_ATTRIBUTE_NOT_FINISHED", + "ERR_ATTRIBUTE_WITHOUT_VALUE", + "ERR_ATTRIBUTE_REDEFINED", + "ERR_LITERAL_NOT_STARTED", + "ERR_LITERAL_NOT_FINISHED", + "ERR_COMMENT_NOT_FINISHED", + "ERR_PI_NOT_STARTED", + "ERR_PI_NOT_FINISHED", + "ERR_NOTATION_NOT_STARTED", + "ERR_NOTATION_NOT_FINISHED", + "ERR_ATTLIST_NOT_STARTED", + "ERR_ATTLIST_NOT_FINISHED", + "ERR_MIXED_NOT_STARTED", + "ERR_MIXED_NOT_FINISHED", + "ERR_ELEMCONTENT_NOT_STARTED", + "ERR_ELEMCONTENT_NOT_FINISHED", + "ERR_XMLDECL_NOT_STARTED", + "ERR_XMLDECL_NOT_FINISHED", + "ERR_CONDSEC_NOT_STARTED", + "ERR_CONDSEC_NOT_FINISHED", + "ERR_EXT_SUBSET_NOT_FINISHED", + "ERR_DOCTYPE_NOT_FINISHED", + "ERR_MISPLACED_CDATA_END", + "ERR_CDATA_NOT_FINISHED", + "ERR_RESERVED_XML_NAME", + "ERR_SPACE_REQUIRED", + "ERR_SEPARATOR_REQUIRED", + "ERR_NMTOKEN_REQUIRED", + "ERR_NAME_REQUIRED", + "ERR_PCDATA_REQUIRED", + "ERR_URI_REQUIRED", + "ERR_PUBID_REQUIRED", + "ERR_LT_REQUIRED", + "ERR_GT_REQUIRED", + "ERR_LTSLASH_REQUIRED", + "ERR_EQUAL_REQUIRED", + "ERR_TAG_NAME_MISMATCH", + "ERR_TAG_NOT_FINISHED", + "ERR_STANDALONE_VALUE", + "ERR_ENCODING_NAME", + "ERR_HYPHEN_IN_COMMENT", + "ERR_INVALID_ENCODING", + "ERR_EXT_ENTITY_STANDALONE", + "ERR_CONDSEC_INVALID", + "ERR_VALUE_REQUIRED", + "ERR_NOT_WELL_BALANCED", + "ERR_EXTRA_CONTENT", + "ERR_ENTITY_CHAR_ERROR", + "ERR_ENTITY_PE_INTERNAL", + "ERR_ENTITY_LOOP", + "ERR_ENTITY_BOUNDARY", + "ERR_INVALID_URI", + "ERR_URI_FRAGMENT", + "WAR_CATALOG_PI", + "ERR_NO_DTD", + "ERR_CONDSEC_INVALID_KEYWORD", + "ERR_VERSION_MISSING", + "WAR_UNKNOWN_VERSION", + "WAR_LANG_VALUE", + "WAR_NS_URI", + "WAR_NS_URI_RELATIVE", + "ERR_MISSING_ENCODING", + "NS_ERR_XML_NAMESPACE", + "NS_ERR_UNDEFINED_NAMESPACE", + "NS_ERR_QNAME", + "NS_ERR_ATTRIBUTE_REDEFINED", + "DTD_ATTRIBUTE_DEFAULT", + "DTD_ATTRIBUTE_REDEFINED", + "DTD_ATTRIBUTE_VALUE", + "DTD_CONTENT_ERROR", + "DTD_CONTENT_MODEL", + "DTD_CONTENT_NOT_DETERMINIST", + "DTD_DIFFERENT_PREFIX", + "DTD_ELEM_DEFAULT_NAMESPACE", + "DTD_ELEM_NAMESPACE", + "DTD_ELEM_REDEFINED", + "DTD_EMPTY_NOTATION", + "DTD_ENTITY_TYPE", + "DTD_ID_FIXED", + "DTD_ID_REDEFINED", + "DTD_ID_SUBSET", + "DTD_INVALID_CHILD", + "DTD_INVALID_DEFAULT", + "DTD_LOAD_ERROR", + "DTD_MISSING_ATTRIBUTE", + "DTD_MIXED_CORRUPT", + "DTD_MULTIPLE_ID", + "DTD_NO_DOC", + "DTD_NO_DTD", + "DTD_NO_ELEM_NAME", + "DTD_NO_PREFIX", + "DTD_NO_ROOT", + "DTD_NOTATION_REDEFINED", + "DTD_NOTATION_VALUE", + "DTD_NOT_EMPTY", + "DTD_NOT_PCDATA", + "DTD_NOT_STANDALONE", + "DTD_ROOT_NAME", + "DTD_STANDALONE_WHITE_SPACE", + "DTD_UNKNOWN_ATTRIBUTE", + "DTD_UNKNOWN_ELEM", + "DTD_UNKNOWN_ENTITY", + "DTD_UNKNOWN_ID", + "DTD_UNKNOWN_NOTATION", + "DTD_STANDALONE_DEFAULTED", + "DTD_XMLID_VALUE", + "DTD_XMLID_TYPE", + "HTML_STRUCURE_ERROR", + "HTML_UNKNOWN_TAG", + "RNGP_ANYNAME_ATTR_ANCESTOR", + "RNGP_ATTR_CONFLICT", + "RNGP_ATTRIBUTE_CHILDREN", + "RNGP_ATTRIBUTE_CONTENT", + "RNGP_ATTRIBUTE_EMPTY", + "RNGP_ATTRIBUTE_NOOP", + "RNGP_CHOICE_CONTENT", + "RNGP_CHOICE_EMPTY", + "RNGP_CREATE_FAILURE", + "RNGP_DATA_CONTENT", + "RNGP_DEF_CHOICE_AND_INTERLEAVE", + "RNGP_DEFINE_CREATE_FAILED", + "RNGP_DEFINE_EMPTY", + "RNGP_DEFINE_MISSING", + "RNGP_DEFINE_NAME_MISSING", + "RNGP_ELEM_CONTENT_EMPTY", + "RNGP_ELEM_CONTENT_ERROR", + "RNGP_ELEMENT_EMPTY", + "RNGP_ELEMENT_CONTENT", + "RNGP_ELEMENT_NAME", + "RNGP_ELEMENT_NO_CONTENT", + "RNGP_ELEM_TEXT_CONFLICT", + "RNGP_EMPTY", + "RNGP_EMPTY_CONSTRUCT", + "RNGP_EMPTY_CONTENT", + "RNGP_EMPTY_NOT_EMPTY", + "RNGP_ERROR_TYPE_LIB", + "RNGP_EXCEPT_EMPTY", + "RNGP_EXCEPT_MISSING", + "RNGP_EXCEPT_MULTIPLE", + "RNGP_EXCEPT_NO_CONTENT", + "RNGP_EXTERNALREF_EMTPY", + "RNGP_EXTERNAL_REF_FAILURE", + "RNGP_EXTERNALREF_RECURSE", + "RNGP_FORBIDDEN_ATTRIBUTE", + "RNGP_FOREIGN_ELEMENT", + "RNGP_GRAMMAR_CONTENT", + "RNGP_GRAMMAR_EMPTY", + "RNGP_GRAMMAR_MISSING", + "RNGP_GRAMMAR_NO_START", + "RNGP_GROUP_ATTR_CONFLICT", + "RNGP_HREF_ERROR", + "RNGP_INCLUDE_EMPTY", + "RNGP_INCLUDE_FAILURE", + "RNGP_INCLUDE_RECURSE", + "RNGP_INTERLEAVE_ADD", + "RNGP_INTERLEAVE_CREATE_FAILED", + "RNGP_INTERLEAVE_EMPTY", + "RNGP_INTERLEAVE_NO_CONTENT", + "RNGP_INVALID_DEFINE_NAME", + "RNGP_INVALID_URI", + "RNGP_INVALID_VALUE", + "RNGP_MISSING_HREF", + "RNGP_NAME_MISSING", + "RNGP_NEED_COMBINE", + "RNGP_NOTALLOWED_NOT_EMPTY", + "RNGP_NSNAME_ATTR_ANCESTOR", + "RNGP_NSNAME_NO_NS", + "RNGP_PARAM_FORBIDDEN", + "RNGP_PARAM_NAME_MISSING", + "RNGP_PARENTREF_CREATE_FAILED", + "RNGP_PARENTREF_NAME_INVALID", + "RNGP_PARENTREF_NO_NAME", + "RNGP_PARENTREF_NO_PARENT", + "RNGP_PARENTREF_NOT_EMPTY", + "RNGP_PARSE_ERROR", + "RNGP_PAT_ANYNAME_EXCEPT_ANYNAME", + "RNGP_PAT_ATTR_ATTR", + "RNGP_PAT_ATTR_ELEM", + "RNGP_PAT_DATA_EXCEPT_ATTR", + "RNGP_PAT_DATA_EXCEPT_ELEM", + "RNGP_PAT_DATA_EXCEPT_EMPTY", + "RNGP_PAT_DATA_EXCEPT_GROUP", + "RNGP_PAT_DATA_EXCEPT_INTERLEAVE", + "RNGP_PAT_DATA_EXCEPT_LIST", + "RNGP_PAT_DATA_EXCEPT_ONEMORE", + "RNGP_PAT_DATA_EXCEPT_REF", + "RNGP_PAT_DATA_EXCEPT_TEXT", + "RNGP_PAT_LIST_ATTR", + "RNGP_PAT_LIST_ELEM", + "RNGP_PAT_LIST_INTERLEAVE", + "RNGP_PAT_LIST_LIST", + "RNGP_PAT_LIST_REF", + "RNGP_PAT_LIST_TEXT", + "RNGP_PAT_NSNAME_EXCEPT_ANYNAME", + "RNGP_PAT_NSNAME_EXCEPT_NSNAME", + "RNGP_PAT_ONEMORE_GROUP_ATTR", + "RNGP_PAT_ONEMORE_INTERLEAVE_ATTR", + "RNGP_PAT_START_ATTR", + "RNGP_PAT_START_DATA", + "RNGP_PAT_START_EMPTY", + "RNGP_PAT_START_GROUP", + "RNGP_PAT_START_INTERLEAVE", + "RNGP_PAT_START_LIST", + "RNGP_PAT_START_ONEMORE", + "RNGP_PAT_START_TEXT", + "RNGP_PAT_START_VALUE", + "RNGP_PREFIX_UNDEFINED", + "RNGP_REF_CREATE_FAILED", + "RNGP_REF_CYCLE", + "RNGP_REF_NAME_INVALID", + "RNGP_REF_NO_DEF", + "RNGP_REF_NO_NAME", + "RNGP_REF_NOT_EMPTY", + "RNGP_START_CHOICE_AND_INTERLEAVE", + "RNGP_START_CONTENT", + "RNGP_START_EMPTY", + "RNGP_START_MISSING", + "RNGP_TEXT_EXPECTED", + "RNGP_TEXT_HAS_CHILD", + "RNGP_TYPE_MISSING", + "RNGP_TYPE_NOT_FOUND", + "RNGP_TYPE_VALUE", + "RNGP_UNKNOWN_ATTRIBUTE", + "RNGP_UNKNOWN_COMBINE", + "RNGP_UNKNOWN_CONSTRUCT", + "RNGP_UNKNOWN_TYPE_LIB", + "RNGP_URI_FRAGMENT", + "RNGP_URI_NOT_ABSOLUTE", + "RNGP_VALUE_EMPTY", + "RNGP_VALUE_NO_CONTENT", + "RNGP_XMLNS_NAME", + "RNGP_XML_NS", + "XPATH_EXPRESSION_OK", + "XPATH_NUMBER_ERROR", + "XPATH_UNFINISHED_LITERAL_ERROR", + "XPATH_START_LITERAL_ERROR", + "XPATH_VARIABLE_REF_ERROR", + "XPATH_UNDEF_VARIABLE_ERROR", + "XPATH_INVALID_PREDICATE_ERROR", + "XPATH_EXPR_ERROR", + "XPATH_UNCLOSED_ERROR", + "XPATH_UNKNOWN_FUNC_ERROR", + "XPATH_INVALID_OPERAND", + "XPATH_INVALID_TYPE", + "XPATH_INVALID_ARITY", + "XPATH_INVALID_CTXT_SIZE", + "XPATH_INVALID_CTXT_POSITION", + "XPATH_MEMORY_ERROR", + "XPTR_SYNTAX_ERROR", + "XPTR_RESOURCE_ERROR", + "XPTR_SUB_RESOURCE_ERROR", + "XPATH_UNDEF_PREFIX_ERROR", + "XPATH_ENCODING_ERROR", + "XPATH_INVALID_CHAR_ERROR", + "TREE_INVALID_HEX", + "TREE_INVALID_DEC", + "TREE_UNTERMINATED_ENTITY", + "SAVE_NOT_UTF8", + "SAVE_CHAR_INVALID", + "SAVE_NO_DOCTYPE", + "SAVE_UNKNOWN_ENCODING", + "REGEXP_COMPILE_ERROR", + "IO_UNKNOWN", + "IO_EACCES", + "IO_EAGAIN", + "IO_EBADF", + "IO_EBADMSG", + "IO_EBUSY", + "IO_ECANCELED", + "IO_ECHILD", + "IO_EDEADLK", + "IO_EDOM", + "IO_EEXIST", + "IO_EFAULT", + "IO_EFBIG", + "IO_EINPROGRESS", + "IO_EINTR", + "IO_EINVAL", + "IO_EIO", + "IO_EISDIR", + "IO_EMFILE", + "IO_EMLINK", + "IO_EMSGSIZE", + "IO_ENAMETOOLONG", + "IO_ENFILE", + "IO_ENODEV", + "IO_ENOENT", + "IO_ENOEXEC", + "IO_ENOLCK", + "IO_ENOMEM", + "IO_ENOSPC", + "IO_ENOSYS", + "IO_ENOTDIR", + "IO_ENOTEMPTY", + "IO_ENOTSUP", + "IO_ENOTTY", + "IO_ENXIO", + "IO_EPERM", + "IO_EPIPE", + "IO_ERANGE", + "IO_EROFS", + "IO_ESPIPE", + "IO_ESRCH", + "IO_ETIMEDOUT", + "IO_EXDEV", + "IO_NETWORK_ATTEMPT", + "IO_ENCODER", + "IO_FLUSH", + "IO_WRITE", + "IO_NO_INPUT", + "IO_BUFFER_FULL", + "IO_LOAD_ERROR", + "IO_ENOTSOCK", + "IO_EISCONN", + "IO_ECONNREFUSED", + "IO_ENETUNREACH", + "IO_EADDRINUSE", + "IO_EALREADY", + "IO_EAFNOSUPPORT", + "XINCLUDE_RECURSION", + "XINCLUDE_PARSE_VALUE", + "XINCLUDE_ENTITY_DEF_MISMATCH", + "XINCLUDE_NO_HREF", + "XINCLUDE_NO_FALLBACK", + "XINCLUDE_HREF_URI", + "XINCLUDE_TEXT_FRAGMENT", + "XINCLUDE_TEXT_DOCUMENT", + "XINCLUDE_INVALID_CHAR", + "XINCLUDE_BUILD_FAILED", + "XINCLUDE_UNKNOWN_ENCODING", + "XINCLUDE_MULTIPLE_ROOT", + "XINCLUDE_XPTR_FAILED", + "XINCLUDE_XPTR_RESULT", + "XINCLUDE_INCLUDE_IN_INCLUDE", + "XINCLUDE_FALLBACKS_IN_INCLUDE", + "XINCLUDE_FALLBACK_NOT_IN_INCLUDE", + "XINCLUDE_DEPRECATED_NS", + "XINCLUDE_FRAGMENT_ID", + "CATALOG_MISSING_ATTR", + "CATALOG_ENTRY_BROKEN", + "CATALOG_PREFER_VALUE", + "CATALOG_NOT_CATALOG", + "CATALOG_RECURSION", + "SCHEMAP_PREFIX_UNDEFINED", + "SCHEMAP_ATTRFORMDEFAULT_VALUE", + "SCHEMAP_ATTRGRP_NONAME_NOREF", + "SCHEMAP_ATTR_NONAME_NOREF", + "SCHEMAP_COMPLEXTYPE_NONAME_NOREF", + "SCHEMAP_ELEMFORMDEFAULT_VALUE", + "SCHEMAP_ELEM_NONAME_NOREF", + "SCHEMAP_EXTENSION_NO_BASE", + "SCHEMAP_FACET_NO_VALUE", + "SCHEMAP_FAILED_BUILD_IMPORT", + "SCHEMAP_GROUP_NONAME_NOREF", + "SCHEMAP_IMPORT_NAMESPACE_NOT_URI", + "SCHEMAP_IMPORT_REDEFINE_NSNAME", + "SCHEMAP_IMPORT_SCHEMA_NOT_URI", + "SCHEMAP_INVALID_BOOLEAN", + "SCHEMAP_INVALID_ENUM", + "SCHEMAP_INVALID_FACET", + "SCHEMAP_INVALID_FACET_VALUE", + "SCHEMAP_INVALID_MAXOCCURS", + "SCHEMAP_INVALID_MINOCCURS", + "SCHEMAP_INVALID_REF_AND_SUBTYPE", + "SCHEMAP_INVALID_WHITE_SPACE", + "SCHEMAP_NOATTR_NOREF", + "SCHEMAP_NOTATION_NO_NAME", + "SCHEMAP_NOTYPE_NOREF", + "SCHEMAP_REF_AND_SUBTYPE", + "SCHEMAP_RESTRICTION_NONAME_NOREF", + "SCHEMAP_SIMPLETYPE_NONAME", + "SCHEMAP_TYPE_AND_SUBTYPE", + "SCHEMAP_UNKNOWN_ALL_CHILD", + "SCHEMAP_UNKNOWN_ANYATTRIBUTE_CHILD", + "SCHEMAP_UNKNOWN_ATTR_CHILD", + "SCHEMAP_UNKNOWN_ATTRGRP_CHILD", + "SCHEMAP_UNKNOWN_ATTRIBUTE_GROUP", + "SCHEMAP_UNKNOWN_BASE_TYPE", + "SCHEMAP_UNKNOWN_CHOICE_CHILD", + "SCHEMAP_UNKNOWN_COMPLEXCONTENT_CHILD", + "SCHEMAP_UNKNOWN_COMPLEXTYPE_CHILD", + "SCHEMAP_UNKNOWN_ELEM_CHILD", + "SCHEMAP_UNKNOWN_EXTENSION_CHILD", + "SCHEMAP_UNKNOWN_FACET_CHILD", + "SCHEMAP_UNKNOWN_FACET_TYPE", + "SCHEMAP_UNKNOWN_GROUP_CHILD", + "SCHEMAP_UNKNOWN_IMPORT_CHILD", + "SCHEMAP_UNKNOWN_LIST_CHILD", + "SCHEMAP_UNKNOWN_NOTATION_CHILD", + "SCHEMAP_UNKNOWN_PROCESSCONTENT_CHILD", + "SCHEMAP_UNKNOWN_REF", + "SCHEMAP_UNKNOWN_RESTRICTION_CHILD", + "SCHEMAP_UNKNOWN_SCHEMAS_CHILD", + "SCHEMAP_UNKNOWN_SEQUENCE_CHILD", + "SCHEMAP_UNKNOWN_SIMPLECONTENT_CHILD", + "SCHEMAP_UNKNOWN_SIMPLETYPE_CHILD", + "SCHEMAP_UNKNOWN_TYPE", + "SCHEMAP_UNKNOWN_UNION_CHILD", + "SCHEMAP_ELEM_DEFAULT_FIXED", + "SCHEMAP_REGEXP_INVALID", + "SCHEMAP_FAILED_LOAD", + "SCHEMAP_NOTHING_TO_PARSE", + "SCHEMAP_NOROOT", + "SCHEMAP_REDEFINED_GROUP", + "SCHEMAP_REDEFINED_TYPE", + "SCHEMAP_REDEFINED_ELEMENT", + "SCHEMAP_REDEFINED_ATTRGROUP", + "SCHEMAP_REDEFINED_ATTR", + "SCHEMAP_REDEFINED_NOTATION", + "SCHEMAP_FAILED_PARSE", + "SCHEMAP_UNKNOWN_PREFIX", + "SCHEMAP_DEF_AND_PREFIX", + "SCHEMAP_UNKNOWN_INCLUDE_CHILD", + "SCHEMAP_INCLUDE_SCHEMA_NOT_URI", + "SCHEMAP_INCLUDE_SCHEMA_NO_URI", + "SCHEMAP_NOT_SCHEMA", + "SCHEMAP_UNKNOWN_MEMBER_TYPE", + "SCHEMAP_INVALID_ATTR_USE", + "SCHEMAP_RECURSIVE", + "SCHEMAP_SUPERNUMEROUS_LIST_ITEM_TYPE", + "SCHEMAP_INVALID_ATTR_COMBINATION", + "SCHEMAP_INVALID_ATTR_INLINE_COMBINATION", + "SCHEMAP_MISSING_SIMPLETYPE_CHILD", + "SCHEMAP_INVALID_ATTR_NAME", + "SCHEMAP_REF_AND_CONTENT", + "SCHEMAP_CT_PROPS_CORRECT_1", + "SCHEMAP_CT_PROPS_CORRECT_2", + "SCHEMAP_CT_PROPS_CORRECT_3", + "SCHEMAP_CT_PROPS_CORRECT_4", + "SCHEMAP_CT_PROPS_CORRECT_5", + "SCHEMAP_DERIVATION_OK_RESTRICTION_1", + "SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_1", + "SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_2", + "SCHEMAP_DERIVATION_OK_RESTRICTION_2_2", + "SCHEMAP_DERIVATION_OK_RESTRICTION_3", + "SCHEMAP_WILDCARD_INVALID_NS_MEMBER", + "SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE", + "SCHEMAP_UNION_NOT_EXPRESSIBLE", + "SCHEMAP_SRC_IMPORT_3_1", + "SCHEMAP_SRC_IMPORT_3_2", + "SCHEMAP_DERIVATION_OK_RESTRICTION_4_1", + "SCHEMAP_DERIVATION_OK_RESTRICTION_4_2", + "SCHEMAP_DERIVATION_OK_RESTRICTION_4_3", + "SCHEMAP_COS_CT_EXTENDS_1_3", + "SCHEMAV_NOROOT", + "SCHEMAV_UNDECLAREDELEM", + "SCHEMAV_NOTTOPLEVEL", + "SCHEMAV_MISSING", + "SCHEMAV_WRONGELEM", + "SCHEMAV_NOTYPE", + "SCHEMAV_NOROLLBACK", + "SCHEMAV_ISABSTRACT", + "SCHEMAV_NOTEMPTY", + "SCHEMAV_ELEMCONT", + "SCHEMAV_HAVEDEFAULT", + "SCHEMAV_NOTNILLABLE", + "SCHEMAV_EXTRACONTENT", + "SCHEMAV_INVALIDATTR", + "SCHEMAV_INVALIDELEM", + "SCHEMAV_NOTDETERMINIST", + "SCHEMAV_CONSTRUCT", + "SCHEMAV_INTERNAL", + "SCHEMAV_NOTSIMPLE", + "SCHEMAV_ATTRUNKNOWN", + "SCHEMAV_ATTRINVALID", + "SCHEMAV_VALUE", + "SCHEMAV_FACET", + "SCHEMAV_CVC_DATATYPE_VALID_1_2_1", + "SCHEMAV_CVC_DATATYPE_VALID_1_2_2", + "SCHEMAV_CVC_DATATYPE_VALID_1_2_3", + "SCHEMAV_CVC_TYPE_3_1_1", + "SCHEMAV_CVC_TYPE_3_1_2", + "SCHEMAV_CVC_FACET_VALID", + "SCHEMAV_CVC_LENGTH_VALID", + "SCHEMAV_CVC_MINLENGTH_VALID", + "SCHEMAV_CVC_MAXLENGTH_VALID", + "SCHEMAV_CVC_MININCLUSIVE_VALID", + "SCHEMAV_CVC_MAXINCLUSIVE_VALID", + "SCHEMAV_CVC_MINEXCLUSIVE_VALID", + "SCHEMAV_CVC_MAXEXCLUSIVE_VALID", + "SCHEMAV_CVC_TOTALDIGITS_VALID", + "SCHEMAV_CVC_FRACTIONDIGITS_VALID", + "SCHEMAV_CVC_PATTERN_VALID", + "SCHEMAV_CVC_ENUMERATION_VALID", + "SCHEMAV_CVC_COMPLEX_TYPE_2_1", + "SCHEMAV_CVC_COMPLEX_TYPE_2_2", + "SCHEMAV_CVC_COMPLEX_TYPE_2_3", + "SCHEMAV_CVC_COMPLEX_TYPE_2_4", + +#if defined XML_SCHEMAV_CVC_ELT_1 + "SCHEMAV_CVC_ELT_1", + "SCHEMAV_CVC_ELT_2", + "SCHEMAV_CVC_ELT_3_1", + "SCHEMAV_CVC_ELT_3_2_1", + "SCHEMAV_CVC_ELT_3_2_2", + "SCHEMAV_CVC_ELT_4_1", + "SCHEMAV_CVC_ELT_4_2", + "SCHEMAV_CVC_ELT_4_3", + "SCHEMAV_CVC_ELT_5_1_1", + "SCHEMAV_CVC_ELT_5_1_2", + "SCHEMAV_CVC_ELT_5_2_1", + "SCHEMAV_CVC_ELT_5_2_2_1", + "SCHEMAV_CVC_ELT_5_2_2_2_1", + "SCHEMAV_CVC_ELT_5_2_2_2_2", + "SCHEMAV_CVC_ELT_6", + "SCHEMAV_CVC_ELT_7", + "SCHEMAV_CVC_ATTRIBUTE_1", + "SCHEMAV_CVC_ATTRIBUTE_2", + "SCHEMAV_CVC_ATTRIBUTE_3", + "SCHEMAV_CVC_ATTRIBUTE_4", + "SCHEMAV_CVC_COMPLEX_TYPE_3_1", + "SCHEMAV_CVC_COMPLEX_TYPE_3_2_1", + "SCHEMAV_CVC_COMPLEX_TYPE_3_2_2", + "SCHEMAV_CVC_COMPLEX_TYPE_4", + "SCHEMAV_CVC_COMPLEX_TYPE_5_1", + "SCHEMAV_CVC_COMPLEX_TYPE_5_2", + "SCHEMAV_ELEMENT_CONTENT", + "SCHEMAV_DOCUMENT_ELEMENT_MISSING", +#endif + +#if defined XML_SCHEMAV_CVC_COMPLEX_TYPE_1 + "SCHEMAV_CVC_COMPLEX_TYPE_1", + "SCHEMAV_CVC_AU", + "SCHEMAV_CVC_TYPE_1", + "SCHEMAV_CVC_TYPE_2", +#endif + + "XPTR_UNKNOWN_SCHEME", + "XPTR_CHILDSEQ_START", + "XPTR_EVAL_FAILED", + "XPTR_EXTRA_OBJECTS", + "C14N_CREATE_CTXT", + "C14N_REQUIRES_UTF8", + "C14N_CREATE_STACK", + "C14N_INVALID_NODE", + "FTP_PASV_ANSWER", + "FTP_EPSV_ANSWER", + "FTP_ACCNT", + "HTTP_URL_SYNTAX", + "HTTP_USE_IP", + "HTTP_UNKNOWN_HOST", + "SCHEMAP_SRC_SIMPLE_TYPE_1", + "SCHEMAP_SRC_SIMPLE_TYPE_2", + "SCHEMAP_SRC_SIMPLE_TYPE_3", + "SCHEMAP_SRC_SIMPLE_TYPE_4", + "SCHEMAP_SRC_RESOLVE", + "SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE", + "SCHEMAP_SRC_LIST_ITEMTYPE_OR_SIMPLETYPE", + "SCHEMAP_SRC_UNION_MEMBERTYPES_OR_SIMPLETYPES", + "SCHEMAP_ST_PROPS_CORRECT_1", + "SCHEMAP_ST_PROPS_CORRECT_2", + "SCHEMAP_ST_PROPS_CORRECT_3", + "SCHEMAP_COS_ST_RESTRICTS_1_1", + "SCHEMAP_COS_ST_RESTRICTS_1_2", + "SCHEMAP_COS_ST_RESTRICTS_1_3_1", + "SCHEMAP_COS_ST_RESTRICTS_1_3_2", + "SCHEMAP_COS_ST_RESTRICTS_2_1", + "SCHEMAP_COS_ST_RESTRICTS_2_3_1_1", + "SCHEMAP_COS_ST_RESTRICTS_2_3_1_2", + "SCHEMAP_COS_ST_RESTRICTS_2_3_2_1", + "SCHEMAP_COS_ST_RESTRICTS_2_3_2_2", + "SCHEMAP_COS_ST_RESTRICTS_2_3_2_3", + "SCHEMAP_COS_ST_RESTRICTS_2_3_2_4", + "SCHEMAP_COS_ST_RESTRICTS_2_3_2_5", + "SCHEMAP_COS_ST_RESTRICTS_3_1", + "SCHEMAP_COS_ST_RESTRICTS_3_3_1", + "SCHEMAP_COS_ST_RESTRICTS_3_3_1_2", + "SCHEMAP_COS_ST_RESTRICTS_3_3_2_2", + "SCHEMAP_COS_ST_RESTRICTS_3_3_2_1", + "SCHEMAP_COS_ST_RESTRICTS_3_3_2_3", + "SCHEMAP_COS_ST_RESTRICTS_3_3_2_4", + "SCHEMAP_COS_ST_RESTRICTS_3_3_2_5", + "SCHEMAP_COS_ST_DERIVED_OK_2_1", + "SCHEMAP_COS_ST_DERIVED_OK_2_2", + "SCHEMAP_S4S_ELEM_NOT_ALLOWED", + "SCHEMAP_S4S_ELEM_MISSING", + "SCHEMAP_S4S_ATTR_NOT_ALLOWED", + "SCHEMAP_S4S_ATTR_MISSING", + +#if defined XML_SCHEMAP_S4S_ATTR_INVALID_VALUE + "SCHEMAP_S4S_ATTR_INVALID_VALUE", + "SCHEMAP_SRC_ELEMENT_1", + "SCHEMAP_SRC_ELEMENT_2_1", + "SCHEMAP_SRC_ELEMENT_2_2", + "SCHEMAP_SRC_ELEMENT_3", + "SCHEMAP_P_PROPS_CORRECT_1", + "SCHEMAP_P_PROPS_CORRECT_2_1", + "SCHEMAP_P_PROPS_CORRECT_2_2", + "SCHEMAP_E_PROPS_CORRECT_2", + "SCHEMAP_E_PROPS_CORRECT_3", + "SCHEMAP_E_PROPS_CORRECT_4", + "SCHEMAP_E_PROPS_CORRECT_5", + "SCHEMAP_E_PROPS_CORRECT_6", + "SCHEMAP_SRC_INCLUDE", + "SCHEMAP_SRC_ATTRIBUTE_1", + "SCHEMAP_SRC_ATTRIBUTE_2", + "SCHEMAP_SRC_ATTRIBUTE_3_1", + "SCHEMAP_SRC_ATTRIBUTE_3_2", + "SCHEMAP_SRC_ATTRIBUTE_4", + "SCHEMAP_NO_XMLNS", + "SCHEMAP_NO_XSI", + "SCHEMAP_COS_VALID_DEFAULT_1", + "SCHEMAP_COS_VALID_DEFAULT_2_1", + "SCHEMAP_COS_VALID_DEFAULT_2_2_1", + "SCHEMAP_COS_VALID_DEFAULT_2_2_2", + "SCHEMAP_CVC_SIMPLE_TYPE", + "SCHEMAP_COS_CT_EXTENDS_1_1", + "SCHEMAP_SRC_IMPORT_1_1", + "SCHEMAP_SRC_IMPORT_1_2", + "SCHEMAP_SRC_IMPORT_2", + "SCHEMAP_SRC_IMPORT_2_1", + "SCHEMAP_SRC_IMPORT_2_2", +#endif + +#if defined XML_SCHEMAP_INTERNAL + "SCHEMAP_INTERNAL", + "SCHEMAP_NOT_DETERMINISTIC", +#endif + +#if defined XML_SCHEMAP_SRC_ATTRIBUTE_GROUP_1 + "SCHEMAP_SRC_ATTRIBUTE_GROUP_1", + "SCHEMAP_SRC_ATTRIBUTE_GROUP_2", + "SCHEMAP_SRC_ATTRIBUTE_GROUP_3", + "SCHEMAP_MG_PROPS_CORRECT_1", + "SCHEMAP_MG_PROPS_CORRECT_2", + "SCHEMAP_SRC_CT_1", + "SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_3", + "SCHEMAP_AU_PROPS_CORRECT_2", + "SCHEMAP_A_PROPS_CORRECT_2", +#endif + NULL +}; + +const char* SaxHandler::errToStr( int errVal ) +{ + const char* str = NULL; + int index = 0; + while ( errVal != xmlErrorVals[index] && xmlErrorVals[index] >= 0 ) + { + index++; + } + + if ( errVal == xmlErrorVals[index] ) + { + str = xmlErrorStrs[index]; + } + + return str; +} + + +int SaxHandler::parseMemory( const char* buffer, int size ) +{ + int result = xmlSAXUserParseMemory( &sax, + this, + buffer, + size ); + return result; +} + +int SaxHandler::parseFile( const char* filename ) +{ + int result = xmlSAXUserParseFile( &sax, + this, + filename ); + return result; +} + +void SaxHandler::startDocument(void *user_data) +{ + SaxHandler* self = reinterpret_cast(user_data); + self->_startDocument(); +} + +void SaxHandler::endDocument(void *user_data) +{ + SaxHandler* self = reinterpret_cast(user_data); + self->_endDocument(); +} +void SaxHandler::startElement(void *user_data, + const xmlChar *name, + const xmlChar **attrs) +{ + SaxHandler* self = reinterpret_cast(user_data); + self->_startElement(name, attrs); +} +void SaxHandler::endElement(void *user_data, + const xmlChar *name) +{ + SaxHandler* self = reinterpret_cast(user_data); + self->_endElement(name); +} +void SaxHandler::characters(void *user_data, + const xmlChar *ch, + int len) +{ + SaxHandler* self = reinterpret_cast(user_data); + self->_characters(ch, len); +} + + + + + + + +FlatSaxHandler::FlatSaxHandler() + : SaxHandler() +{ +} + +FlatSaxHandler::~FlatSaxHandler() +{ +} + +void FlatSaxHandler::_startElement(const xmlChar *name, const xmlChar **attrs) +{ + data.clear(); +} + +void FlatSaxHandler::_endElement(const xmlChar *name) +{ + //g_message("<%s>%s", name, data.c_str(), name); + data.clear(); +} + +void FlatSaxHandler::_characters(const xmlChar *ch, int len) +{ + data.append((const char*)ch, len); +} + + +} // namespace IO +} // 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:textwidth=99 : diff --git a/src/io/simple-sax.h b/src/io/simple-sax.h new file mode 100644 index 000000000..7de816a14 --- /dev/null +++ b/src/io/simple-sax.h @@ -0,0 +1,97 @@ +#ifndef SEEN_SIMPLE_SAX_H +#define SEEN_SIMPLE_SAX_H + +/* + * SimpleSAX + * + * Authors: + * Jon A. Cruz + * + * Copyright (C) 2004 AUTHORS + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include +#include + +namespace Inkscape { +namespace IO +{ + +class SaxHandler +{ +public: + SaxHandler(); + virtual ~SaxHandler(); + + int parseMemory( const char* buffer, int size ); + int parseFile( const char* filename ); + + static const char* errToStr( int errVal ); + +protected: + virtual void _startDocument() {} + virtual void _endDocument() {} + virtual void _startElement(const xmlChar *name, const xmlChar **attrs) {} + virtual void _endElement(const xmlChar *name) {} + virtual void _characters(const xmlChar *ch, int len) {} + +private: + static void startDocument(void *user_data); + static void endDocument(void *user_data); + static void startElement(void *user_data, + const xmlChar *name, + const xmlChar **attrs); + static void endElement(void *user_data, + const xmlChar *name); + static void characters(void * user_data, + const xmlChar *ch, + int len); + + // Disable: + SaxHandler(SaxHandler const &); + SaxHandler &operator=(SaxHandler const &); + + xmlSAXHandler sax; +}; + + + +class FlatSaxHandler : public SaxHandler +{ +public: + FlatSaxHandler(); + virtual ~FlatSaxHandler(); + +protected: + virtual void _startElement(const xmlChar *name, const xmlChar **attrs); + virtual void _endElement(const xmlChar *name); + virtual void _characters(const xmlChar *ch, int len); + + Glib::ustring data; + +private: + // Disable: + FlatSaxHandler(FlatSaxHandler const &); + FlatSaxHandler &operator=(FlatSaxHandler const &); +}; + + + +} // namespace IO +} // 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 : + +#endif // SEEN_SIMPLE_SAX_H diff --git a/src/io/streamtest.cpp b/src/io/streamtest.cpp new file mode 100644 index 000000000..b25ef43f0 --- /dev/null +++ b/src/io/streamtest.cpp @@ -0,0 +1,244 @@ + + +#include +#include // realpath +#include // mkdtemp, realpath +#include // chdir +#include // strlen, strncpy, strrchr + +#include "inkscapestream.h" +#include "base64stream.h" +#include "gzipstream.h" +#include "stringstream.h" +#include "uristream.h" +#include "xsltstream.h" + +// quick way to pass the name of the executable into the test +char myself[PATH_MAX]; + +// names and path storage for other tests +char *xmlname = "crystalegg.xml"; +char xmlpath[PATH_MAX]; +char *xslname = "doc2html.xsl"; +char xslpath[PATH_MAX]; + +bool testUriStream() +{ + printf("######### UriStream copy ############\n"); + Inkscape::URI inUri(myself); + Inkscape::IO::UriInputStream ins(inUri); + Inkscape::URI outUri("streamtest.copy"); + Inkscape::IO::UriOutputStream outs(outUri); + + pipeStream(ins, outs); + + ins.close(); + outs.close(); + + return true; +} + +bool testWriter() +{ + printf("######### OutputStreamWriter ############\n"); + Inkscape::IO::StdOutputStream outs; + Inkscape::IO::OutputStreamWriter writer(outs); + + writer << "Hello, world! " << 123.45 << " times\n"; + + writer.printf("There are %f quick brown foxes in %d states\n", 123.45, 88); + + return true; +} + +bool testStdWriter() +{ + printf("######### StdWriter ############\n"); + Inkscape::IO::StdWriter writer; + + writer << "Hello, world! " << 123.45 << " times\n"; + + writer.printf("There are %f quick brown foxes in %d states\n", 123.45, 88); + + return true; +} + +bool testBase64() +{ + printf("######### Base64 Out ############\n"); + Inkscape::URI plainInUri(xmlpath); + Inkscape::IO::UriInputStream ins1(plainInUri); + + Inkscape::URI b64OutUri("crystalegg.xml.b64"); + Inkscape::IO::UriOutputStream outs1(b64OutUri); + Inkscape::IO::Base64OutputStream b64Outs(outs1); + + pipeStream(ins1, b64Outs); + + ins1.close(); + b64Outs.close(); + + printf("######### Base64 In ############\n"); + Inkscape::URI b64InUri("crystalegg.xml.b64"); + Inkscape::IO::UriInputStream ins2(b64InUri); + Inkscape::IO::Base64InputStream b64Ins(ins2); + + Inkscape::URI plainOutUri("crystalegg.xml.b64dec"); + Inkscape::IO::UriOutputStream outs2(plainOutUri); + + pipeStream(b64Ins, outs2); + + outs2.close(); + b64Ins.close(); + + return true; +} + +bool testXslt() +{ + printf("######### XSLT Sheet ############\n"); + Inkscape::URI xsltSheetUri(xslpath); + Inkscape::IO::UriInputStream xsltSheetIns(xsltSheetUri); + Inkscape::IO::XsltStyleSheet stylesheet(xsltSheetIns); + xsltSheetIns.close(); + + Inkscape::URI sourceUri(xmlpath); + Inkscape::IO::UriInputStream xmlIns(sourceUri); + + printf("######### XSLT Input ############\n"); + Inkscape::URI destUri("test.html"); + Inkscape::IO::UriOutputStream xmlOuts(destUri); + + Inkscape::IO::XsltInputStream xsltIns(xmlIns, stylesheet); + pipeStream(xsltIns, xmlOuts); + xsltIns.close(); + xmlOuts.close(); + + + printf("######### XSLT Output ############\n"); + + Inkscape::IO::UriInputStream xmlIns2(sourceUri); + + Inkscape::URI destUri2("test2.html"); + Inkscape::IO::UriOutputStream xmlOuts2(destUri2); + + Inkscape::IO::XsltOutputStream xsltOuts(xmlOuts2, stylesheet); + pipeStream(xmlIns2, xsltOuts); + xmlIns2.close(); + xsltOuts.close(); + + return true; +} + +bool testGzip() +{ + + printf("######### Gzip Output ############\n"); + Inkscape::URI gzUri("test.gz"); + Inkscape::URI sourceUri(xmlpath); + Inkscape::IO::UriInputStream sourceIns(sourceUri); + Inkscape::IO::UriOutputStream gzOuts(gzUri); + + Inkscape::IO::GzipOutputStream gzipOuts(gzOuts); + pipeStream(sourceIns, gzipOuts); + sourceIns.close(); + gzipOuts.close(); + + printf("######### Gzip Input ############\n"); + + Inkscape::IO::UriInputStream gzIns(gzUri); + Inkscape::URI destUri("crystalegg2.xml"); + Inkscape::IO::UriOutputStream destOuts(destUri); + + Inkscape::IO::GzipInputStream gzipIns(gzIns); + pipeStream(gzipIns, destOuts); + gzipIns.close(); + destOuts.close(); + + return true; +} + +bool doTest() +{ + if (!testUriStream()) + { + return false; + } + if (!testWriter()) + { + return false; + } + if (!testStdWriter()) + { + return false; + } + if (!testBase64()) + { + return false; + } + if (!testXslt()) + { + return false; + } + if (!testGzip()) + { + return false; + } + return true; +} + +void path_init(char *path, char *name) +{ + if (strlen(name)>PATH_MAX-strlen(myself)) + { + printf("merging paths would be too long\n"); + exit(1); + } + strncpy(path,myself,PATH_MAX); + char * ptr = strrchr(path,'/'); + if (!ptr) + { + printf("path '%s' is missing any slashes\n",path); + exit(1); + } + strncpy(ptr+1,name,strlen(name)+1); + printf("'%s'\n",path); +} + + +int main(int argc, char **argv) +{ + if (!realpath(argv[0],myself)) + { + perror("realpath"); + return 1; + } + path_init(xmlpath,xmlname); + path_init(xslpath,xslname); + + // create temp files somewhere else instead of current dir + // TODO: clean them up too + char * testpath = strdup("/tmp/streamtest-XXXXXX"); + testpath = mkdtemp(testpath); + if (!testpath) + { + perror("mkdtemp"); + return 1; + } + if (chdir(testpath)) + { + perror("chdir"); + return 1; + } + + if (!doTest()) + { + printf("#### Test failed\n"); + return 1; + } + else + { + printf("##### Test succeeded\n"); + } + return 0; +} diff --git a/src/io/stringstream.cpp b/src/io/stringstream.cpp new file mode 100644 index 000000000..45fb6fe30 --- /dev/null +++ b/src/io/stringstream.cpp @@ -0,0 +1,128 @@ +/** + * Our base String stream classes. We implement these to + * be based on Glib::ustring + * + * Authors: + * Bob Jamison + * + * Copyright (C) 2004 Inkscape.org + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + + +#include "stringstream.h" + +namespace Inkscape +{ +namespace IO +{ + + +//######################################################################### +//# S T R I N G I N P U T S T R E A M +//######################################################################### + + +/** + * + */ +StringInputStream::StringInputStream(Glib::ustring &sourceString) + : buffer(sourceString) +{ + position = 0; +} + +/** + * + */ +StringInputStream::~StringInputStream() +{ + +} + +/** + * Returns the number of bytes that can be read (or skipped over) from + * this input stream without blocking by the next caller of a method for + * this input stream. + */ +int StringInputStream::available() +{ + return buffer.size() - position; +} + + +/** + * Closes this input stream and releases any system resources + * associated with the stream. + */ +void StringInputStream::close() +{ +} + +/** + * Reads the next byte of data from the input stream. -1 if EOF + */ +int StringInputStream::get() +{ + if (position >= (int)buffer.size()) + return -1; + int ch = (int) buffer[position++]; + return ch; +} + + + + +//######################################################################### +//# S T R I N G O U T P U T S T R E A M +//######################################################################### + +/** + * + */ +StringOutputStream::StringOutputStream() +{ +} + +/** + * + */ +StringOutputStream::~StringOutputStream() +{ +} + +/** + * Closes this output stream and releases any system resources + * associated with this stream. + */ +void StringOutputStream::close() +{ +} + +/** + * Flushes this output stream and forces any buffered output + * bytes to be written out. + */ +void StringOutputStream::flush() +{ + //nothing to do +} + +/** + * Writes the specified byte to this output stream. + */ +void StringOutputStream::put(int ch) +{ + gunichar uch = (gunichar)ch; + buffer.push_back(uch); +} + + +} // namespace IO +} // namespace Inkscape + + +//######################################################################### +//# E N D O F F I L E +//######################################################################### diff --git a/src/io/stringstream.h b/src/io/stringstream.h new file mode 100644 index 000000000..4a05d88a9 --- /dev/null +++ b/src/io/stringstream.h @@ -0,0 +1,96 @@ +#ifndef __INKSCAPE_IO_STRINGSTREAM_H__ +#define __INKSCAPE_IO_STRINGSTREAM_H__ + +#include + +#include "inkscapestream.h" + + +namespace Inkscape +{ +namespace IO +{ + + +//######################################################################### +//# S T R I N G I N P U T S T R E A M +//######################################################################### + +/** + * This class is for reading character from a Glib::ustring + * + */ +class StringInputStream : public InputStream +{ + +public: + + StringInputStream(Glib::ustring &sourceString); + + virtual ~StringInputStream(); + + virtual int available(); + + virtual void close(); + + virtual int get(); + +private: + + Glib::ustring &buffer; + + long position; + +}; // class StringInputStream + + + + +//######################################################################### +//# S T R I N G O U T P U T S T R E A M +//######################################################################### + +/** + * This class is for sending a stream to a Glib::ustring + * + */ +class StringOutputStream : public OutputStream +{ + +public: + + StringOutputStream(); + + virtual ~StringOutputStream(); + + virtual void close(); + + virtual void flush(); + + virtual void put(int ch); + + virtual Glib::ustring &getString() + { return buffer; } + + virtual void clear() + { buffer = ""; } + +private: + + Glib::ustring buffer; + + +}; // class StringOutputStream + + + + + + + +} // namespace IO +} // namespace Inkscape + + + +#endif /* __INKSCAPE_IO_STRINGSTREAM_H__ */ diff --git a/src/io/sys.cpp b/src/io/sys.cpp new file mode 100644 index 000000000..89afe9fb4 --- /dev/null +++ b/src/io/sys.cpp @@ -0,0 +1,300 @@ + +/* + * System abstraction utility routines + * + * Authors: + * Jon A. Cruz + * + * Copyright (C) 2004-2005 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#if GLIB_CHECK_VERSION(2,6,0) + #include +#endif +#include +#include + +#include "prefs-utils.h" +#include "sys.h" + +#ifdef WIN32 + +// For now to get at is_os_wide(). +#include "extension/internal/win32.h" +using Inkscape::Extension::Internal::PrintWin32; + +#endif + +//#define INK_DUMP_FILENAME_CONV 1 +#undef INK_DUMP_FILENAME_CONV + +//#define INK_DUMP_FOPEN 1 +#undef INK_DUMP_FOPEN + +void dump_str(gchar const *str, gchar const *prefix); +void dump_ustr(Glib::ustring const &ustr); + +extern guint update_in_progress; + + +#define DEBUG_MESSAGE(key, ...) \ +{\ + gint dump = prefs_get_int_attribute_limited("options.bulia", #key, 0, 0, 1);\ + gint dumpD = prefs_get_int_attribute_limited("options.bulia", #key"D", 0, 0, 1);\ + gint dumpD2 = prefs_get_int_attribute_limited("options.bulia", #key"D2", 0, 0, 1);\ + dumpD &= ( (update_in_progress == 0) || dumpD2 );\ + if ( dump )\ + {\ + g_message( __VA_ARGS__ );\ +\ + }\ + if ( dumpD )\ + {\ + GtkWidget *dialog = gtk_message_dialog_new(NULL,\ + GTK_DIALOG_DESTROY_WITH_PARENT, \ + GTK_MESSAGE_INFO, \ + GTK_BUTTONS_OK, \ + __VA_ARGS__ \ + );\ + g_signal_connect_swapped(dialog, "response",\ + G_CALLBACK(gtk_widget_destroy), \ + dialog); \ + gtk_widget_show_all( dialog );\ + }\ +} + + + + +void Inkscape::IO::dump_fopen_call( char const *utf8name, char const *id ) +{ +#ifdef INK_DUMP_FOPEN + Glib::ustring str; + for ( int i = 0; utf8name[i]; i++ ) + { + if ( utf8name[i] == '\\' ) + { + str += "\\\\"; + } + else if ( (utf8name[i] >= 0x20) && ((0x0ff & utf8name[i]) <= 0x7f) ) + { + str += utf8name[i]; + } + else + { + gchar tmp[32]; + g_snprintf( tmp, sizeof(tmp), "\\x%02x", (0x0ff & utf8name[i]) ); + str += tmp; + } + } + g_message( "fopen call %s for [%s]", id, str.data() ); +#endif +} + +FILE *Inkscape::IO::fopen_utf8name( char const *utf8name, char const *mode ) +{ + static gint counter = 0; + FILE* fp = NULL; + + DEBUG_MESSAGE( dumpOne, "entering fopen_utf8name( '%s', '%s' )[%d]", utf8name, mode, (counter++) ); + +#ifndef WIN32 + DEBUG_MESSAGE( dumpOne, " STEP 0 ( '%s', '%s' )[%d]", utf8name, mode, (counter++) ); + gchar *filename = g_filename_from_utf8( utf8name, -1, NULL, NULL, NULL ); + if ( filename ) + { + DEBUG_MESSAGE( dumpOne, " STEP 1 ( '%s', '%s' )[%d]", utf8name, mode, (counter++) ); + fp = std::fopen(filename, mode); + DEBUG_MESSAGE( dumpOne, " STEP 2 ( '%s', '%s' )[%d]", utf8name, mode, (counter++) ); + g_free(filename); + DEBUG_MESSAGE( dumpOne, " STEP 3 ( '%s', '%s' )[%d]", utf8name, mode, (counter++) ); + filename = 0; + } +#else + Glib::ustring how( mode ); + how.append("b"); + DEBUG_MESSAGE( dumpOne, " calling is_os_wide() ( '%s', '%s' )[%d]", utf8name, mode, (counter++) ); + + fp = g_fopen(utf8name, how.c_str()); +#endif + + DEBUG_MESSAGE( dumpOne, "leaving fopen_utf8name( '%s', '%s' )[%d]", utf8name, mode, (counter++) ); + + return fp; +} + + +int Inkscape::IO::mkdir_utf8name( char const *utf8name ) +{ + static gint counter = 0; + int retval = -1; + + DEBUG_MESSAGE( dumpMk, "entering mkdir_utf8name( '%s' )[%d]", utf8name, (counter++) ); + +#ifndef WIN32 + DEBUG_MESSAGE( dumpMk, " STEP 0 ( '%s' )[%d]", utf8name, (counter++) ); + gchar *filename = g_filename_from_utf8( utf8name, -1, NULL, NULL, NULL ); + if ( filename ) + { + DEBUG_MESSAGE( dumpMk, " STEP 1 ( '%s' )[%d]", utf8name, (counter++) ); + retval = ::mkdir(filename, S_IRWXU | S_IRGRP | S_IXGRP); + DEBUG_MESSAGE( dumpMk, " STEP 2 ( '%s' )[%d]", utf8name, (counter++) ); + g_free(filename); + DEBUG_MESSAGE( dumpMk, " STEP 3 ( '%s' )[%d]", utf8name, (counter++) ); + filename = 0; + } +#else + DEBUG_MESSAGE( dumpMk, " calling is_os_wide() ( '%s' )[%d]", utf8name, (counter++) ); + + // Mode should be ingnored inside of glib on the way in + retval = g_mkdir( utf8name, 0 ); +#endif + + DEBUG_MESSAGE( dumpMk, "leaving mkdir_utf8name( '%s' )[%d]", utf8name, (counter++) ); + + return retval; +} + +bool Inkscape::IO::file_test( char const *utf8name, GFileTest test ) +{ + bool exists = false; + + if ( utf8name ) { + gchar *filename = NULL; + if (utf8name && !g_utf8_validate(utf8name, -1, NULL)) { + /* FIXME: Trying to guess whether or not a filename is already in utf8 is unreliable. + If any callers pass non-utf8 data (e.g. using g_get_home_dir), then change caller to + use simple g_file_test. Then add g_return_val_if_fail(g_utf_validate(...), false) + to beginning of this function. */ + filename = g_strdup(utf8name); + // Looks like g_get_home_dir isn't safe. + //g_warning("invalid UTF-8 detected internally. HUNT IT DOWN AND KILL IT!!!"); + } else { + filename = g_filename_from_utf8 ( utf8name, -1, NULL, NULL, NULL ); + } + if ( filename ) { + exists = g_file_test (filename, test); + g_free(filename); + filename = NULL; + } else { + g_warning( "Unable to convert filename in IO:file_test" ); + } + } + + return exists; +} + +/** Wrapper around g_dir_open, but taking a utf8name as first argument. */ +GDir * +Inkscape::IO::dir_open(gchar const *const utf8name, guint const flags, GError **const error) +{ + gchar *const opsys_name = g_filename_from_utf8(utf8name, -1, NULL, NULL, error); + if (opsys_name) { + GDir *ret = g_dir_open(opsys_name, flags, error); + g_free(opsys_name); + return ret; + } else { + return NULL; + } +} + +/** + * Like g_dir_read_name, but returns a utf8name (which must be freed, unlike g_dir_read_name). + * + * N.B. Skips over any dir entries that fail to convert to utf8. + */ +gchar * +Inkscape::IO::dir_read_utf8name(GDir *dir) +{ + for (;;) { + gchar const *const opsys_name = g_dir_read_name(dir); + if (!opsys_name) { + return NULL; + } + gchar *utf8_name = g_filename_to_utf8(opsys_name, -1, NULL, NULL, NULL); + if (utf8_name) { + return utf8_name; + } + } +} + + +gchar* Inkscape::IO::locale_to_utf8_fallback( const gchar *opsysstring, + gssize len, + gsize *bytes_read, + gsize *bytes_written, + GError **error ) +{ + gchar *result = NULL; + if ( opsysstring ) { + gchar *newFileName = g_locale_to_utf8( opsysstring, len, bytes_read, bytes_written, error ); + if ( newFileName ) { + if ( !g_utf8_validate(newFileName, -1, NULL) ) { + g_warning( "input filename did not yield UTF-8" ); + g_free( newFileName ); + } else { + result = newFileName; + } + newFileName = 0; + } else if ( g_utf8_validate(opsysstring, -1, NULL) ) { + // This *might* be a case that we want + // g_warning( "input failed filename->utf8, fell back to original" ); + // TODO handle cases when len >= 0 + result = g_strdup( opsysstring ); + } else { + gchar const *charset = 0; + g_get_charset(&charset); + g_warning( "input filename conversion failed for file with locale charset '%s'", charset ); + } + } + return result; +} + + +gchar* Inkscape::IO::sanitizeString( gchar const * str ) +{ + gchar *result = NULL; + if ( str ) { + if ( g_utf8_validate(str, -1, NULL) ) { + result = g_strdup(str); + } else { + guchar scratch[8]; + Glib::ustring buf; + guchar const *ptr = (guchar const*)str; + while ( *ptr ) + { + if ( *ptr == '\\' ) + { + buf.append("\\\\"); + } else if ( *ptr < 0x80 ) { + buf += (char)(*ptr); + } else { + g_snprintf((gchar*)scratch, sizeof(scratch), "\\x%02x", *ptr); + buf.append((const char*)scratch); + } + ptr++; + } + result = g_strdup(buf.c_str()); + } + } + return result; +} + +/* + 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 : diff --git a/src/io/sys.h b/src/io/sys.h new file mode 100644 index 000000000..29c0ad96a --- /dev/null +++ b/src/io/sys.h @@ -0,0 +1,51 @@ +#ifndef SEEN_SYS_H +#define SEEN_SYS_H + +/* + * System abstraction utility routines + * + * Authors: + * Jon A. Cruz + * + * Copyright (C) 2004-2005 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include +#include +#include +#include + +/*##################### +## U T I L I T Y +#####################*/ + +namespace Inkscape { +namespace IO { + +void dump_fopen_call( char const *utf8name, char const *id ); + +FILE *fopen_utf8name( char const *utf8name, char const *mode ); + +int mkdir_utf8name( char const *utf8name ); + +bool file_test( char const *utf8name, GFileTest test ); + +GDir *dir_open(gchar const *utf8name, guint flags, GError **error); + +gchar *dir_read_utf8name(GDir *dir); + +gchar* locale_to_utf8_fallback( const gchar *opsysstring, + gssize len, + gsize *bytes_read, + gsize *bytes_written, + GError **error ); + +gchar* sanitizeString( gchar const * str ); + +} +} + + +#endif // SEEN_SYS_H diff --git a/src/io/uristream.cpp b/src/io/uristream.cpp new file mode 100644 index 000000000..e06498d52 --- /dev/null +++ b/src/io/uristream.cpp @@ -0,0 +1,499 @@ +/** + * Our base String stream classes. We implement these to + * be based on Glib::ustring + * + * Authors: + * Bob Jamison + * + * Copyright (C) 2004 Inkscape.org + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + + +#include "uristream.h" +#include "sys.h" + +#ifdef WIN32 +// For now to get at is_os_wide(). +# include "extension/internal/win32.h" +using Inkscape::Extension::Internal::PrintWin32; +#endif + + +namespace Inkscape +{ +namespace IO +{ + +/* + * URI scheme types + */ +#define SCHEME_NONE 0 +#define SCHEME_FILE 1 +#define SCHEME_DATA 2 + +/* + * A temporary modification of Jon Cruz's portable fopen(). + * Simplified a bit, since we will always use binary +*/ + +#define FILE_READ 1 +#define FILE_WRITE 2 + +static FILE *fopen_utf8name( char const *utf8name, int mode ) +{ + FILE *fp = NULL; + if (!utf8name) + { + return NULL; + } + if (mode!=FILE_READ && mode!=FILE_WRITE) + { + return NULL; + } + +#ifndef WIN32 + gchar *filename = g_filename_from_utf8( utf8name, -1, NULL, NULL, NULL ); + if ( filename ) { + if (mode == FILE_READ) + fp = std::fopen(filename, "rb"); + else + fp = std::fopen(filename, "wb"); + g_free(filename); + } +#else + if ( PrintWin32::is_os_wide() ) { + gunichar2 *wideName = g_utf8_to_utf16( utf8name, -1, NULL, NULL, NULL ); + if ( wideName ) { + if (mode == FILE_READ) + fp = _wfopen( (wchar_t*)wideName, L"rb" ); + else + fp = _wfopen( (wchar_t*)wideName, L"wb" ); + g_free( wideName ); + } else { + gchar *safe = Inkscape::IO::sanitizeString(utf8name); + g_message("Unable to convert filename from UTF-8 to UTF-16 [%s]", safe); + g_free(safe); + } + } else { + gchar *filename = g_filename_from_utf8( utf8name, -1, NULL, NULL, NULL ); + if ( filename ) { + if (mode == FILE_READ) + fp = std::fopen(filename, "rb"); + else + fp = std::fopen(filename, "wb"); + g_free(filename); + } + } +#endif + + return fp; +} + + + +//######################################################################### +//# U R I I N P U T S T R E A M / R E A D E R +//######################################################################### + + +/** + * + */ +UriInputStream::UriInputStream(Inkscape::URI &source) + throw (StreamException): uri(source) +{ + //get information from uri + char *schemestr = (char *) uri.getScheme(); + scheme = SCHEME_FILE; + if (!schemestr || strncmp("file", schemestr, 4)==0) + scheme = SCHEME_FILE; + else if (strncmp("data", schemestr, 4)==0) + scheme = SCHEME_DATA; + //printf("in schemestr:'%s' scheme:'%d'\n", schemestr, scheme); + char *cpath = NULL; + + switch (scheme) { + + case SCHEME_FILE: + cpath = (char *) uri.toNativeFilename(); + //printf("in cpath:'%s'\n", cpath); + inf = fopen_utf8name(cpath, FILE_READ); + //inf = fopen(cpath, "rb"); + g_free(cpath); + if (!inf) { + Glib::ustring err = "UriInputStream cannot open file "; + err += cpath; + throw StreamException(err); + } + break; + + case SCHEME_DATA: + data = (unsigned char *) uri.getPath(); + //printf("in data:'%s'\n", data); + dataPos = 0; + dataLen = strlen((const char *)data); + break; + + } + closed = false; +} + +/** + * + */ +UriInputStream::UriInputStream(FILE *source, Inkscape::URI &uri) + throw (StreamException): inf(source), + uri(uri) +{ + scheme = SCHEME_FILE; + if (!inf) { + Glib::ustring err = "UriInputStream passed NULL"; + throw StreamException(err); + } + closed = false; +} + +/** + * + */ +UriInputStream::~UriInputStream() throw(StreamException) +{ + close(); +} + +/** + * Returns the number of bytes that can be read (or skipped over) from + * this input stream without blocking by the next caller of a method for + * this input stream. + */ +int UriInputStream::available() throw(StreamException) +{ + return 0; +} + + +/** + * Closes this input stream and releases any system resources + * associated with the stream. + */ +void UriInputStream::close() throw(StreamException) +{ + if (closed) + return; + + switch (scheme) { + + case SCHEME_FILE: + if (!inf) + return; + fflush(inf); + fclose(inf); + inf=NULL; + break; + + case SCHEME_DATA: + //do nothing + break; + + }//switch + + closed = true; +} + +/** + * Reads the next byte of data from the input stream. -1 if EOF + */ +int UriInputStream::get() throw(StreamException) +{ + int retVal = -1; + if (!closed) + { + switch (scheme) { + + case SCHEME_FILE: + if (!inf || feof(inf)) + { + retVal = -1; + } + else + { + retVal = fgetc(inf); + } + break; + + case SCHEME_DATA: + if (dataPos >= dataLen) + { + retVal = -1; + } + else + { + retVal = data[dataPos++]; + } + break; + }//switch + } + return retVal; +} + + + + + + +/** + * + */ +UriReader::UriReader(Inkscape::URI &uri) + throw (StreamException) +{ + inputStream = new UriInputStream(uri); +} + +/** + * + */ +UriReader::~UriReader() throw (StreamException) +{ + delete inputStream; +} + +/** + * + */ +int UriReader::available() throw(StreamException) +{ + return inputStream->available(); +} + +/** + * + */ +void UriReader::close() throw(StreamException) +{ + inputStream->close(); +} + +/** + * + */ +gunichar UriReader::get() throw(StreamException) +{ + gunichar ch = (gunichar)inputStream->get(); + return ch; +} + + +//######################################################################### +//# U R I O U T P U T S T R E A M / W R I T E R +//######################################################################### + +/** + * Temporary kludge + */ +UriOutputStream::UriOutputStream(FILE* fp, Inkscape::URI &destination) + throw (StreamException): closed(false), + ownsFile(false), + outf(fp), + uri(destination), + scheme(SCHEME_FILE) +{ + if (!outf) { + Glib::ustring err = "UriOutputStream given null file "; + throw StreamException(err); + } +} + +/** + * + */ +UriOutputStream::UriOutputStream(Inkscape::URI &destination) + throw (StreamException): closed(false), + ownsFile(true), + outf(NULL), + uri(destination), + scheme(SCHEME_FILE) +{ + //get information from uri + char *schemestr = (char *) uri.getScheme(); + if (!schemestr || strncmp("file", schemestr, 4)==0) + scheme = SCHEME_FILE; + else if (strncmp("data", schemestr, 4)==0) + scheme = SCHEME_DATA; + //printf("out schemestr:'%s' scheme:'%d'\n", schemestr, scheme); + char *cpath = NULL; + + switch (scheme) { + + case SCHEME_FILE: + cpath = (char *) uri.toNativeFilename(); + //printf("out path:'%s'\n", cpath); + outf = fopen_utf8name(cpath, FILE_WRITE); + //outf = fopen(cpath, "wb"); + g_free(cpath); + if (!outf) { + Glib::ustring err = "UriOutputStream cannot open file "; + err += cpath; + throw StreamException(err); + } + break; + + case SCHEME_DATA: + data = "data:"; + break; + + }//switch +} + + +/** + * + */ +UriOutputStream::~UriOutputStream() throw(StreamException) +{ + close(); +} + +/** + * Closes this output stream and releases any system resources + * associated with this stream. + */ +void UriOutputStream::close() throw(StreamException) +{ + if (closed) + return; + + switch (scheme) { + + case SCHEME_FILE: + if (!outf) + return; + fflush(outf); + if ( ownsFile ) + fclose(outf); + outf=NULL; + break; + + case SCHEME_DATA: + uri = URI(data.raw().c_str()); + break; + + }//switch + + closed = true; +} + +/** + * Flushes this output stream and forces any buffered output + * bytes to be written out. + */ +void UriOutputStream::flush() throw(StreamException) +{ + if (closed) + return; + + switch (scheme) { + + case SCHEME_FILE: + if (!outf) + return; + fflush(outf); + break; + + case SCHEME_DATA: + //nothing + break; + + }//switch + +} + +/** + * Writes the specified byte to this output stream. + */ +void UriOutputStream::put(int ch) throw(StreamException) +{ + if (closed) + return; + + unsigned char uch; + gunichar gch; + + switch (scheme) { + + case SCHEME_FILE: + if (!outf) + return; + uch = (unsigned char)(ch & 0xff); + fputc(uch, outf); + //fwrite(uch, 1, 1, outf); + break; + + case SCHEME_DATA: + gch = (gunichar) ch; + data.push_back(gch); + break; + + }//switch + +} + + + + + +/** + * + */ +UriWriter::UriWriter(Inkscape::URI &uri) + throw (StreamException) +{ + outputStream = new UriOutputStream(uri); +} + +/** + * + */ +UriWriter::~UriWriter() throw (StreamException) +{ + delete outputStream; +} + +/** + * + */ +void UriWriter::close() throw(StreamException) +{ + outputStream->close(); +} + +/** + * + */ +void UriWriter::flush() throw(StreamException) +{ + outputStream->flush(); +} + +/** + * + */ +void UriWriter::put(gunichar ch) throw(StreamException) +{ + int ich = (int)ch; + outputStream->put(ich); +} + + + + + +} // namespace IO +} // namespace Inkscape + + +//######################################################################### +//# E N D O F F I L E +//######################################################################### diff --git a/src/io/uristream.h b/src/io/uristream.h new file mode 100644 index 000000000..d62065976 --- /dev/null +++ b/src/io/uristream.h @@ -0,0 +1,173 @@ +#ifndef __INKSCAPE_IO_URISTREAM_H__ +#define __INKSCAPE_IO_URISTREAM_H__ +/** + * This should be the only way that we provide sources/sinks + * to any input/output stream. + * + * Authors: + * Bob Jamison + * + * Copyright (C) 2004 Inkscape.org + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + + +#include + +#include "inkscapestream.h" + + +namespace Inkscape +{ +namespace IO +{ + +//######################################################################### +//# U R I I N P U T S T R E A M / R E A D E R +//######################################################################### + +/** + * This class is for receiving a stream of data from a resource + * defined in a URI + */ +class UriInputStream : public InputStream +{ + +public: + UriInputStream(FILE *source, Inkscape::URI &uri) throw(StreamException); + + UriInputStream(Inkscape::URI &source) throw(StreamException); + + virtual ~UriInputStream() throw(StreamException); + + virtual int available() throw(StreamException); + + virtual void close() throw(StreamException); + + virtual int get() throw(StreamException); + +private: + + bool closed; + + FILE *inf; //for file: uris + unsigned char *data; //for data: uris + int dataPos; // current read position in data field + int dataLen; // length of data buffer + + Inkscape::URI &uri; + + int scheme; + +}; // class UriInputStream + + + + +/** + * This class is for receiving a stream of formatted data from a resource + * defined in a URI + */ +class UriReader : public BasicReader +{ + +public: + + UriReader(Inkscape::URI &source) throw(StreamException); + + virtual ~UriReader() throw(StreamException); + + virtual int available() throw(StreamException); + + virtual void close() throw(StreamException); + + virtual gunichar get() throw(StreamException); + +private: + + UriInputStream *inputStream; + +}; // class UriReader + + + +//######################################################################### +//# U R I O U T P U T S T R E A M / W R I T E R +//######################################################################### + +/** + * This class is for sending a stream to a destination resource + * defined in a URI + * + */ +class UriOutputStream : public OutputStream +{ + +public: + + UriOutputStream(FILE *fp, Inkscape::URI &destination) throw(StreamException); + + UriOutputStream(Inkscape::URI &destination) throw(StreamException); + + virtual ~UriOutputStream() throw(StreamException); + + virtual void close() throw(StreamException); + + virtual void flush() throw(StreamException); + + virtual void put(int ch) throw(StreamException); + +private: + + bool closed; + bool ownsFile; + + FILE *outf; //for file: uris + Glib::ustring data; //for data: uris + + Inkscape::URI &uri; + + int scheme; + +}; // class UriOutputStream + + + + + +/** + * This class is for sending a stream of formatted data to a resource + * defined in a URI + */ +class UriWriter : public BasicWriter +{ + +public: + + UriWriter(Inkscape::URI &source) throw(StreamException); + + virtual ~UriWriter() throw(StreamException); + + virtual void close() throw(StreamException); + + virtual void flush() throw(StreamException); + + virtual void put(gunichar ch) throw(StreamException); + +private: + + UriOutputStream *outputStream; + +}; // class UriReader + + + + + + +} // namespace IO +} // namespace Inkscape + + +#endif /* __INKSCAPE_IO_URISTREAM_H__ */ diff --git a/src/io/xsltstream.cpp b/src/io/xsltstream.cpp new file mode 100644 index 000000000..71619a51e --- /dev/null +++ b/src/io/xsltstream.cpp @@ -0,0 +1,220 @@ +/** + * XSL Transforming input and output classes + * + * Authors: + * Bob Jamison + * + * Copyright (C) 2004 Inkscape.org + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + + +#include "xsltstream.h" +#include "stringstream.h" +#include + + + + +namespace Inkscape +{ +namespace IO +{ + +//######################################################################### +//# X S L T S T Y L E S H E E T +//######################################################################### +/** + * + */ +XsltStyleSheet::XsltStyleSheet(InputStream &xsltSource) throw (StreamException) +{ + StringOutputStream outs; + pipeStream(xsltSource, outs); + std::string strBuf = outs.getString().raw(); + xmlDocPtr doc = xmlParseMemory(strBuf.c_str(), strBuf.size()); + stylesheet = xsltParseStylesheetDoc(doc); + //xmlFreeDoc(doc); +} + +/** + * + */ +XsltStyleSheet::~XsltStyleSheet() +{ + xsltFreeStylesheet(stylesheet); +} + + + +//######################################################################### +//# X S L T I N P U T S T R E A M +//######################################################################### + + +/** + * + */ +XsltInputStream::XsltInputStream(InputStream &xmlSource, XsltStyleSheet &sheet) + throw (StreamException) + : BasicInputStream(xmlSource), stylesheet(sheet) +{ + //Load the data + StringOutputStream outs; + pipeStream(source, outs); + std::string strBuf = outs.getString().raw(); + + //Do the processing + const char *params[1]; + params[0] = NULL; + xmlDocPtr srcDoc = xmlParseMemory(strBuf.c_str(), strBuf.size()); + xmlDocPtr resDoc = xsltApplyStylesheet(stylesheet.stylesheet, srcDoc, params); + xmlDocDumpFormatMemory(resDoc, &outbuf, &outsize, 1); + outpos = 0; + + //Free our mem + xmlFreeDoc(resDoc); + xmlFreeDoc(srcDoc); +} + +/** + * + */ +XsltInputStream::~XsltInputStream() throw (StreamException) +{ + xmlFree(outbuf); +} + +/** + * Returns the number of bytes that can be read (or skipped over) from + * this input stream without blocking by the next caller of a method for + * this input stream. + */ +int XsltInputStream::available() throw (StreamException) +{ + return outsize - outpos; +} + + +/** + * Closes this input stream and releases any system resources + * associated with the stream. + */ +void XsltInputStream::close() throw (StreamException) +{ + closed = true; +} + +/** + * Reads the next byte of data from the input stream. -1 if EOF + */ +int XsltInputStream::get() throw (StreamException) +{ + if (closed) + return -1; + if (outpos >= outsize) + return -1; + int ch = (int) outbuf[outpos++]; + return ch; +} + + + + + + +//######################################################################### +//# X S L T O U T P U T S T R E A M +//######################################################################### + +/** + * + */ +XsltOutputStream::XsltOutputStream(OutputStream &dest, XsltStyleSheet &sheet) + throw (StreamException) + : BasicOutputStream(dest), stylesheet(sheet) +{ + flushed = false; +} + +/** + * + */ +XsltOutputStream::~XsltOutputStream() throw (StreamException) +{ + //do not automatically close +} + +/** + * Closes this output stream and releases any system resources + * associated with this stream. + */ +void XsltOutputStream::close() throw (StreamException) +{ + flush(); + destination.close(); +} + +/** + * Flushes this output stream and forces any buffered output + * bytes to be written out. + */ +void XsltOutputStream::flush() throw (StreamException) +{ + if (flushed) + { + destination.flush(); + return; + } + + //Do the processing + xmlChar *resbuf; + int resSize; + const char *params[1]; + params[0] = NULL; + xmlDocPtr srcDoc = xmlParseMemory(outbuf.raw().c_str(), outbuf.size()); + xmlDocPtr resDoc = xsltApplyStylesheet(stylesheet.stylesheet, srcDoc, params); + xmlDocDumpFormatMemory(resDoc, &resbuf, &resSize, 1); + /* + xmlErrorPtr err = xmlGetLastError(); + if (err) + { + throw StreamException(err->message); + } + */ + + for (int i=0 ; i + * + * Copyright (C) 2004 Inkscape.org + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + + +#include "inkscapestream.h" + +#include +#include + + +namespace Inkscape +{ +namespace IO +{ + +//######################################################################### +//# X S L T S T Y L E S H E E T +//######################################################################### +/** + * This is a container for reusing a loaded stylesheet + */ +class XsltStyleSheet +{ + +public: + + XsltStyleSheet(InputStream &source) throw (StreamException); + + ~XsltStyleSheet(); + + xsltStylesheetPtr stylesheet; + + +}; // class XsltStyleSheet + + +//######################################################################### +//# X S L T I N P U T S T R E A M +//######################################################################### + +/** + * This class is for transforming stream input by a given stylesheet + */ +class XsltInputStream : public BasicInputStream +{ + +public: + + XsltInputStream(InputStream &xmlSource, XsltStyleSheet &stylesheet) + throw (StreamException); + + virtual ~XsltInputStream() throw (StreamException); + + virtual int available() throw (StreamException); + + virtual void close() throw (StreamException); + + virtual int get() throw (StreamException); + + +private: + + XsltStyleSheet &stylesheet; + + xmlChar *outbuf; + int outsize; + int outpos; + +}; // class UriInputStream + + + + +//######################################################################### +//# X S L T O U T P U T S T R E A M +//######################################################################### + +/** + * This class is for transforming stream output by a given stylesheet + */ +class XsltOutputStream : public BasicOutputStream +{ + +public: + + XsltOutputStream(OutputStream &destination, XsltStyleSheet &stylesheet) + throw (StreamException); + + virtual ~XsltOutputStream() throw (StreamException); + + virtual void close() throw (StreamException); + + virtual void flush() throw (StreamException); + + virtual void put(int ch) throw (StreamException); + +private: + + XsltStyleSheet &stylesheet; + + Glib::ustring outbuf; + + bool flushed; + +}; // class UriOutputStream + + + +} // namespace IO +} // namespace Inkscape + + +#endif /* __INKSCAPE_IO_XSLTSTREAM_H__ */ diff --git a/src/isnan.h b/src/isnan.h new file mode 100644 index 000000000..cfae92fc7 --- /dev/null +++ b/src/isnan.h @@ -0,0 +1,57 @@ +#ifndef __ISNAN_H__ +#define __ISNAN_H__ + +/* + * Temporary fix for various misdefinitions of isnan(). + * isnan() is becoming undef'd in some .h files. + * #include this last in your .cpp file to get it right. + * + * The problem is that isnan and isfinite are part of C99 but aren't part of + * the C++ standard (which predates C99). + * + * Authors: + * Inkscape groupies and obsessive-compulsives + * + * Copyright (C) 2004 authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + * + * 2005 modification hereby placed in public domain. Probably supercedes the 2004 copyright + * for the code itself. + */ + +#include +/* You might try changing the above to if you have problems. + * Whether you use math.h or cmath, you may need to edit the .cpp file + * and/or other .h files to use the same header file. + */ + +#if defined(__isnan) +# define isNaN(_a) (__isnan(_a)) /* MacOSX/Darwin definition < 10.4 */ +#elif defined(WIN32) || defined(_isnan) +# define isNaN(_a) (_isnan(_a)) /* Win32 definition */ +#elif defined(isnan) || defined(__FreeBSD__) +# define isNaN(_a) (isnan(_a)) /* GNU definition */ +#else +# define isNaN(_a) (std::isnan(_a)) +#endif +/* If the above doesn't work, then try (a != a). + * Also, please report a bug as per http://www.inkscape.org/report_bugs.php, + * giving information about what platform and compiler version you're using. + */ + + +#if defined(__isfinite) +# define isFinite(_a) (__isfinite(_a)) /* MacOSX/Darwin definition < 10.4 */ +#elif defined(isfinite) +# define isFinite(_a) (isfinite(_a)) +#else +# define isFinite(_a) (std::isfinite(_a)) +#endif +/* If the above doesn't work, then try (finite(_a) && !isNaN(_a)) or (!isNaN((_a) - (_a))). + * Also, please report a bug as per http://www.inkscape.org/report_bugs.php, + * giving information about what platform and compiler version you're using. + */ + + +#endif /* __ISNAN_H__ */ diff --git a/src/jabber_whiteboard/.cvsignore b/src/jabber_whiteboard/.cvsignore new file mode 100644 index 000000000..ec96903b9 --- /dev/null +++ b/src/jabber_whiteboard/.cvsignore @@ -0,0 +1,2 @@ +.deps +.dirstamp diff --git a/src/jabber_whiteboard/Makefile_insert b/src/jabber_whiteboard/Makefile_insert new file mode 100644 index 000000000..7e120c002 --- /dev/null +++ b/src/jabber_whiteboard/Makefile_insert @@ -0,0 +1,77 @@ +## Makefile.am fragment sourced by src/Makefile.am. +# +# Jabber whiteboard communication and Inkscape listener components +# Author: David Yip + +jabber_whiteboard/all: jabber_whiteboard/libjabber_whiteboard.a + +jabber_whiteboard/clean: + rm -f jabber_whiteboard/libjabber_whiteboard.a $(jabber_whiteboard_libjabber_whiteboard_a_OBJECTS) + +jabber_whiteboard_SOURCES = \ + jabber_whiteboard/buddy-list-manager.cpp \ + jabber_whiteboard/buddy-list-manager.h \ + jabber_whiteboard/callbacks.cpp \ + jabber_whiteboard/callbacks.h \ + jabber_whiteboard/chat-handler.cpp \ + jabber_whiteboard/chat-handler.h \ + jabber_whiteboard/connection-establishment.cpp \ + jabber_whiteboard/defines.h \ + jabber_whiteboard/deserializer.cpp \ + jabber_whiteboard/deserializer.h \ + jabber_whiteboard/error-codes.h \ + jabber_whiteboard/internal-constants.cpp \ + jabber_whiteboard/internal-constants.h \ + jabber_whiteboard/invitation-confirm-dialog.cpp \ + jabber_whiteboard/invitation-confirm-dialog.h \ + jabber_whiteboard/jabber-handlers.cpp \ + jabber_whiteboard/jabber-handlers.h \ + jabber_whiteboard/message-aggregator.cpp \ + jabber_whiteboard/message-aggregator.h \ + jabber_whiteboard/message-contexts.cpp \ + jabber_whiteboard/message-contexts.h \ + jabber_whiteboard/message-handler.cpp \ + jabber_whiteboard/message-handler.h \ + jabber_whiteboard/message-node.h \ + jabber_whiteboard/message-processors.cpp \ + jabber_whiteboard/message-processors.h \ + jabber_whiteboard/message-queue.cpp \ + jabber_whiteboard/message-queue.h \ + jabber_whiteboard/message-tags.cpp \ + jabber_whiteboard/message-tags.h \ + jabber_whiteboard/message-utilities.cpp \ + jabber_whiteboard/message-utilities.h \ + jabber_whiteboard/node-tracker.cpp \ + jabber_whiteboard/node-tracker-event-tracker.cpp \ + jabber_whiteboard/node-tracker-event-tracker.h \ + jabber_whiteboard/node-tracker.h \ + jabber_whiteboard/node-tracker-observer.h \ + jabber_whiteboard/node-utilities.cpp \ + jabber_whiteboard/node-utilities.h \ + jabber_whiteboard/pedrodom.cpp \ + jabber_whiteboard/pedrodom.h \ + jabber_whiteboard/pedroxmpp.cpp \ + jabber_whiteboard/pedroxmpp.h \ + jabber_whiteboard/serializer.cpp \ + jabber_whiteboard/serializer.h \ + jabber_whiteboard/session-file.cpp \ + jabber_whiteboard/session-file.h \ + jabber_whiteboard/session-file-player.cpp \ + jabber_whiteboard/session-file-player.h \ + jabber_whiteboard/session-file-selector.cpp \ + jabber_whiteboard/session-file-selector.h \ + jabber_whiteboard/session-manager.cpp \ + jabber_whiteboard/session-manager.h \ + jabber_whiteboard/tracker-node.h \ + jabber_whiteboard/typedefs.h \ + jabber_whiteboard/undo-stack-observer.cpp \ + jabber_whiteboard/undo-stack-observer.h + + +if WITH_INKBOARD +temp_whiteboard_files = $(jabber_whiteboard_SOURCES) +endif + +jabber_whiteboard_libjabber_whiteboard_a_SOURCES = \ + jabber_whiteboard/empty.cpp \ + $(temp_whiteboard_files) diff --git a/src/jabber_whiteboard/buddy-list-manager.cpp b/src/jabber_whiteboard/buddy-list-manager.cpp new file mode 100644 index 000000000..4cce2308c --- /dev/null +++ b/src/jabber_whiteboard/buddy-list-manager.cpp @@ -0,0 +1,84 @@ +/** + * Whiteboard session manager + * Buddy list management facility + * + * Authors: + * David Yip + * + * Copyright (c) 2005 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + + +#include +#include + +#include "jabber_whiteboard/typedefs.h" +#include "jabber_whiteboard/buddy-list-manager.h" + +namespace Inkscape { + +namespace Whiteboard { + +BuddyListManager::BuddyListManager() { } +BuddyListManager::~BuddyListManager() { } + +void +BuddyListManager::addInsertListener(BuddyListListener listener) +{ + this->_sig_insert.connect(listener); +} + +void +BuddyListManager::addEraseListener(BuddyListListener listener) +{ + this->_sig_erase.connect(listener); +} + +void +BuddyListManager::insert(std::string& jid) +{ + this->_bl.insert(jid); + this->_sig_insert.emit(jid); +} + +void +BuddyListManager::erase(std::string& jid) +{ + this->_bl.erase(jid); + this->_sig_erase.emit(jid); +} + +BuddyList::iterator +BuddyListManager::begin() +{ + return this->_bl.begin(); +} + +BuddyList::iterator +BuddyListManager::end() +{ + return this->_bl.end(); +} + +BuddyList& +BuddyListManager::getList() +{ + return this->_bl; +} + +} + +} + +/* + 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:textwidth=99 : diff --git a/src/jabber_whiteboard/buddy-list-manager.h b/src/jabber_whiteboard/buddy-list-manager.h new file mode 100644 index 000000000..fcd0bb688 --- /dev/null +++ b/src/jabber_whiteboard/buddy-list-manager.h @@ -0,0 +1,59 @@ +/** + * Whiteboard session manager + * Buddy list management facility + * + * Authors: + * David Yip + * + * Copyright (c) 2005 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifndef __WHITEBOARD_BUDDYLIST_MANAGER_H__ +#define __WHITEBOARD_BUDDYLIST_MANAGER_H__ + +#include +#include +#include "jabber_whiteboard/typedefs.h" + +namespace Inkscape { + +namespace Whiteboard { + +class BuddyListManager { +public: + BuddyListManager(); + ~BuddyListManager(); + void insert(std::string& jid); + void erase(std::string& jid); + BuddyList::iterator begin(); + BuddyList::iterator end(); + + void addInsertListener(BuddyListListener listener); + void addEraseListener(BuddyListListener listener); + + BuddyList& getList(); +private: + BuddyList _bl; + BuddyListSignal _sig_insert; + BuddyListSignal _sig_erase; + +}; + +} + +} + +#endif + +/* + 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:textwidth=99 : diff --git a/src/jabber_whiteboard/callbacks.cpp b/src/jabber_whiteboard/callbacks.cpp new file mode 100644 index 000000000..8216f33c6 --- /dev/null +++ b/src/jabber_whiteboard/callbacks.cpp @@ -0,0 +1,206 @@ +/** + * Whiteboard session manager + * Message dispatch devices and timeout triggers + * + * Authors: + * David Yip + * + * Copyright (c) 2005 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +extern "C" { +#include +} + +#include + +#include "message-stack.h" +#include "document.h" +#include "desktop-handles.h" + +#include "jabber_whiteboard/undo-stack-observer.h" +#include "jabber_whiteboard/jabber-handlers.h" +#include "jabber_whiteboard/defines.h" +#include "jabber_whiteboard/typedefs.h" +#include "jabber_whiteboard/session-manager.h" +#include "jabber_whiteboard/message-queue.h" +#include "jabber_whiteboard/message-handler.h" +#include "jabber_whiteboard/message-node.h" +#include "jabber_whiteboard/callbacks.h" + +namespace Inkscape { + +namespace Whiteboard { + +Callbacks::Callbacks(SessionManager* sm) : _sm(sm) +{ + this->_sd = this->_sm->session_data; +} + +Callbacks::~Callbacks() +{ +} + +bool +Callbacks::dispatchSendQueue() +{ + // If we're not in a whiteboard session, don't dispatch anything + if (!(this->_sd->status[IN_WHITEBOARD])) { + return false; + } + + // If the connection is not open, inform the user that an error has occurred + // and stop the queue + LmConnectionState state = lm_connection_get_state(this->_sd->connection); + + if (state != LM_CONNECTION_STATE_OPEN && state != LM_CONNECTION_STATE_AUTHENTICATED) { + SP_DT_MSGSTACK(this->_sm->desktop())->flash(Inkscape::INFORMATION_MESSAGE, _("Jabber connection lost.")); + return false; + } + + // If there's nothing to send, don't do anything + if (this->_sd->send_queue->empty()) { + return true; + } + + // otherwise, send out the first change + MessageNode* first = this->_sd->send_queue->first(); + + SP_DT_MSGSTACK(this->_sm->desktop())->flashF(Inkscape::NORMAL_MESSAGE, + ngettext("Sending message; %u message remaining in send queue.", + "Sending message; %u messages remaining in send queue.", + this->_sd->send_queue->size()), + this->_sd->send_queue->size()); + + if (this->_sd->send_queue->empty()) { + SP_DT_MSGSTACK(this->_sm->desktop())->flash(Inkscape::NORMAL_MESSAGE, _("Receive queue empty.")); + } + + switch (first->type()) { + case CHANGE_REPEATABLE: + case CHANGE_NOT_REPEATABLE: + case CHANGE_COMMIT: + case DOCUMENT_BEGIN: + case DOCUMENT_END: + this->_sm->sendMessage(first->type(), first->sequence(), first->message(), first->recipient().c_str(), first->chatroom()); + break; + default: + g_warning("MessageNode with unknown change type found in send queue; discarding message. This may lead to desynchronization!"); + break; + } + + this->_sd->send_queue->popFront(); + + return true; +} + +bool +Callbacks::dispatchReceiveQueue() +{ + CommitsQueue& rcq = this->_sd->recipients_committed_queue; + // See if we have any commits submitted. + if (!rcq.empty()) { + // Pick the first one off the queue. + ReceivedCommitEvent& committer = rcq.front(); + + // Find the commit event sender's receive queue. + ReceiveMessageQueue* rmq = this->_sd->receive_queues[committer]; + + if (rmq != NULL) { + if (!rmq->empty()) { + // Get the first message off the sender's receive queue. + MessageNode* msg = rmq->first(); + + // There are a few message change types that demand special processing; + // handle them here. + // + // TODO: clean this up. This should be a simple dispatching routine, + // and should not be performing operations like it's doing right now. + // These really should go into connection-establishment.cpp + // (although that should only happen after SessionManager itself + // is cleaned up). + switch(msg->type()) { + case CHANGE_COMMIT: + rcq.pop_front(); + break; + case DOCUMENT_BEGIN: + if (this->_sm->session_data->status[WAITING_TO_SYNC_TO_CHAT]) { + this->_sm->session_data->status.set(WAITING_TO_SYNC_TO_CHAT, 0); + this->_sm->session_data->status.set(SYNCHRONIZING_WITH_CHAT, 1); + } + break; + case DOCUMENT_END: + rcq.pop_front(); + if (this->_sm->session_data->status[SYNCHRONIZING_WITH_CHAT]) { + this->_sm->sendMessage(CONNECTED_SIGNAL, 0, "", this->_sm->session_data->recipient, true); + this->_sm->session_data->status.set(SYNCHRONIZING_WITH_CHAT, 0); + this->_sm->session_data->status.set(IN_CHATROOM, 1); + } else { + this->_sm->sendMessage(CONNECTED_SIGNAL, 0, "", msg->sender().c_str(), false); + } + break; + case CHANGE_REPEATABLE: + case CHANGE_NOT_REPEATABLE: + default: + break; + } + + + // Pass the message to the received change handler. + this->_sm->receiveChange(msg->message()); + SP_DT_MSGSTACK(this->_sm->desktop())->flashF(Inkscape::NORMAL_MESSAGE, + ngettext("Receiving change; %u change left to process.", + "Receiving change; %u changes left to process.", + rmq->size()), + rmq->size()); + + + // Register this message as the latest message received from this + // sender. + rmq->setLatestProcessedPacket(msg->sequence()); + + // Pop this message off the receive queue. + rmq->popFront(); + return true; + } else { + // This really shouldn't happen. + // If we have a commit request from a valid sender, there should + // be something in the receive queue to process. However, + // if a client is buggy or has managed to trick us into accepting + // a commit, we should handle the event gracefully. + g_warning("Processing commit, but no changes to commit were found; ignoring commit event."); + + // Remove this sender from the commit list. If they want to commit + // later, they can. + rcq.pop_front(); + return true; + } + } else { + // If the receive queue returned is NULL, then we don't know about + // this sender. Remove the sender from the commit list. + g_warning("Attempting to process commit from unknown sender; ignoring."); + rcq.pop_front(); + return true; + } + } else { + return true; + } +} + +} + +} + + +/* + 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:textwidth=99 : diff --git a/src/jabber_whiteboard/callbacks.h b/src/jabber_whiteboard/callbacks.h new file mode 100644 index 000000000..7a41a4010 --- /dev/null +++ b/src/jabber_whiteboard/callbacks.h @@ -0,0 +1,79 @@ +/** + * Whiteboard session manager + * Message dispatch devices and timeout triggers + * + * Authors: + * David Yip + * + * Copyright (c) 2005 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifndef __WHITEBOARD_CALLBACKS_H__ +#define __WHITEBOARD_CALLBACKS_H__ + +#include + +namespace Inkscape { + +namespace Whiteboard { + +class SessionManager; +class SessionData; + +/** + * Callback methods used in timers to dispatch MessageNodes from message queues. + */ +class Callbacks { +public: + /** + * Constructor. + * + * \param sm The SessionManager to associate with. + */ + Callbacks(SessionManager* sm); + ~Callbacks(); + + /** + * Dispatch a message from the send queue to the associated SessionManager object. + * + * The SessionManager object handles the task of actually sending out a Jabber message. + * + * \see Inkscape::Whiteboard::SessionManager::sendMessage + * \return Whether or not this callback should be called again by the timer routine. + */ + bool dispatchSendQueue(); + + /** + * Dispatch a message from the receive queue to the associated SessionManager object. + * + * The SessionManager object handles the task of actually processing a Jabber message. + * + * \see Inkscape::Whiteboard::SessionManager::receiveChange + * \return Whether or not this callback should be called again by the timer routine. + */ + bool dispatchReceiveQueue(); + +private: + SessionManager* _sm; + SessionData* _sd; +}; + + +} + +} + +#endif + +/* + 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:textwidth=99 : diff --git a/src/jabber_whiteboard/chat-handler.cpp b/src/jabber_whiteboard/chat-handler.cpp new file mode 100644 index 000000000..bf7a2a31e --- /dev/null +++ b/src/jabber_whiteboard/chat-handler.cpp @@ -0,0 +1,249 @@ +/** + * Whiteboard session manager + * Chatroom message handler + * + * Authors: + * David Yip + * + * Copyright (c) 2005 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include + +//#include + +#include "message-stack.h" +#include "desktop-handles.h" +#include "document.h" + +#include "util/ucompose.hpp" + +#include "xml/node.h" + +#include "jabber_whiteboard/typedefs.h" +#include "jabber_whiteboard/message-utilities.h" +#include "jabber_whiteboard/message-queue.h" +#include "jabber_whiteboard/jabber-handlers.h" +#include "jabber_whiteboard/defines.h" +#include "jabber_whiteboard/session-manager.h" +#include "jabber_whiteboard/node-tracker.h" +#include "jabber_whiteboard/chat-handler.h" +#include "jabber_whiteboard/error-codes.h" + + +namespace Inkscape { + +namespace Whiteboard { + +ChatMessageHandler::ChatMessageHandler(SessionManager* sm) : _sm(sm) +{ + +} + +ChatMessageHandler::~ChatMessageHandler() +{ + +} + +LmHandlerResult +ChatMessageHandler::parse(LmMessage* message) +{ + // Retrieve the message type + LmMessageType mtype = lm_message_get_type(message); + + // Retrieve root node of message + LmMessageNode* root = lm_message_get_node(message); + if (root == NULL) { + g_warning("Received a chat message with NULL root node; discarding."); + return LM_HANDLER_RESULT_REMOVE_MESSAGE; + } + + LmMessageSubType msubtype; + + + msubtype = lm_message_get_sub_type(message); + + switch (mtype) { + case LM_MESSAGE_TYPE_MESSAGE: + switch(msubtype) { + case LM_MESSAGE_SUB_TYPE_ERROR: + { + LmMessageNode* error = lm_message_node_get_child(root, "error"); + if (error != NULL) { + this->_handleError(lm_message_node_get_attribute(error, "code")); + } + break; + } + case LM_MESSAGE_SUB_TYPE_GROUPCHAT: + { + // FIXME: We should be checking to see if we're in a room in the presence stanzas as indicated in + // but current versions of mu-conference + // don't broadcast presence in the correct order. + // + // Therefore we need to use some sort of hacked-up method to make this work. We listen for + // the sentinel value in a groupchat message -- currently it is '[username] INKBOARD-JOINED' -- + // and begin processing that way. + LmMessageNode* body = lm_message_node_get_child(root, "body"); + if (body != NULL) { + gchar const* val = lm_message_node_get_value(body); + if (strcmp(val, String::ucompose("%1 INKBOARD-JOINED", this->_sm->session_data->chat_handle).c_str()) == 0) { + return this->_finishConnection(); break; + } else { + return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS; + break; + } + } else { + return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS; + break; + } + } + + default: + return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS; + break; + } + break; + case LM_MESSAGE_TYPE_PRESENCE: + // Retrieve the subtype. + switch (msubtype) { + case LM_MESSAGE_SUB_TYPE_ERROR: + { + g_warning("Could not connect to chatroom"); + // Extract error type + LmMessageNode* error = lm_message_node_get_child(root, "error"); + if (error != NULL) { + this->_handleError(lm_message_node_get_attribute(error, "code")); + } + // Reset status bits + this->_sm->session_data->status.set(CONNECTING_TO_CHAT, 0); + this->_sm->session_data->recipient = ""; + this->_sm->session_data->chat_handle = ""; + + return LM_HANDLER_RESULT_REMOVE_MESSAGE; + break; + } + + case LM_MESSAGE_SUB_TYPE_AVAILABLE: + { + // Extract the handle + // (see JEP-0045, section 6.3.3 - ) + Glib::ustring sender = lm_message_node_get_attribute(root, MESSAGE_FROM); + Glib::ustring chatter = sender.substr(sender.find_last_of('/') + 1, sender.length()); + if (chatter != this->_sm->session_data->chat_handle) { + this->_sm->session_data->chatters.insert(g_strdup(chatter.data())); + // Make a receive queue for this chatter + this->_sm->session_data->receive_queues[sender.raw()] = new ReceiveMessageQueue(this->_sm); + + } else { + // If the presence message is from ourselves, then we know that we + // have successfully entered the chatroom _and_ have received the entire room roster, + // and can therefore decide whether we need to synchronize with the rest of the room. + // (see JEP-0045, section 6.3.3 - ) + } + return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS; + } + + case LM_MESSAGE_SUB_TYPE_UNAVAILABLE: + { + Glib::ustring sender = lm_message_node_get_attribute(root, MESSAGE_FROM); + Glib::ustring chatter = sender.substr(sender.find_last_of('/') + 1, sender.length()); + this->_sm->session_data->chatters.erase(chatter.data()); + + // Delete the message queue used by this sender + this->_sm->session_data->receive_queues.erase(sender.raw()); + + SP_DT_MSGSTACK(this->_sm->desktop())->flashF(Inkscape::INFORMATION_MESSAGE, _("%s has left the chatroom."), sender.c_str()); + } + + default: + // no idea what this message is; discard it + return LM_HANDLER_RESULT_REMOVE_MESSAGE; + break; + } + break; + default: + break; + } + + return LM_HANDLER_RESULT_REMOVE_MESSAGE; +} + +LmHandlerResult +ChatMessageHandler::_finishConnection() +{ + if (this->_sm->session_data->status[CONNECTING_TO_CHAT]) { + this->_sm->session_data->status.set(CONNECTING_TO_CHAT, 0); + + if (this->_sm->session_data->chatters.empty()) { + // We are the only one in the chatroom, so there is no + // need for synchronization + this->_sm->session_data->status.set(IN_CHATROOM, 1); + + // Populate node tracker + KeyToNodeMap newids; + NodeToKeyMap newnodes; + NewChildObjectMessageList newchildren; + + XML::Node* root = this->_sm->document()->rroot; + + this->_sm->setupInkscapeInterface(); + this->_sm->setupCommitListener(); + + for ( Inkscape::XML::Node *child = root->firstChild() ; child != NULL ; child = child->next() ) { + MessageUtilities::newObjectMessage(NULL, newids, newnodes, newchildren, this->_sm->node_tracker(), child, true); + } + + this->_sm->node_tracker()->put(newids, newnodes); + // this->_sm->node_tracker()->dump(); + + } else { + this->_sm->session_data->status.set(WAITING_TO_SYNC_TO_CHAT, 1); + // Send synchronization request to chatroom + this->_sm->sendMessage(CHATROOM_SYNCHRONIZE_REQUEST, 0, "", this->_sm->session_data->recipient, true); + } + } + return LM_HANDLER_RESULT_REMOVE_MESSAGE; +} + +void +ChatMessageHandler::_handleError(char const* errcode) +{ +// try { + unsigned int code = atoi(errcode); + +// unsigned int code = boost::lexical_cast< unsigned int >(errcode); + + Glib::ustring buf; + switch (code) { + case ErrorCodes::CHAT_HANDLE_IN_USE: + buf = String::ucompose(_("Nickname %1 is already in use. Please choose a different nickname."), this->_sm->session_data->chat_handle); + this->_sm->connectionError(buf); + break; + case ErrorCodes::SERVER_CONNECT_FAILED: + buf = _("An error was encountered while attempting to connect to the server."); + this->_sm->connectionError(buf); + break; + default: + break; + } +// } catch (boost::bad_lexical_cast&) { + +// } +} + +} + +} + +/* + 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:textwidth=99 : diff --git a/src/jabber_whiteboard/chat-handler.h b/src/jabber_whiteboard/chat-handler.h new file mode 100644 index 000000000..f87c8142d --- /dev/null +++ b/src/jabber_whiteboard/chat-handler.h @@ -0,0 +1,63 @@ +/** + * Whiteboard session manager + * Chatroom message handler + * + * Authors: + * David Yip + * + * Copyright (c) 2005 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifndef __WHITEBOARD_CHAT_HANDLER_H__ +#define __WHITEBOARD_CHAT_HANDLER_H__ + +extern "C" { +#include +} + +namespace Inkscape { + +namespace Whiteboard { + +class SessionManager; + + +// TODO: find some way to better integrate this with the rest of the message +// handling framework (i.e. message-processors.cpp, message-handler.cpp, +// message-contexts.cpp) +class ChatMessageHandler { +public: + ChatMessageHandler(SessionManager* sm); + ~ChatMessageHandler(); + + LmHandlerResult parse(LmMessage* message); + +private: + LmHandlerResult _finishConnection(); + void _handleError(char const* errcode); + + SessionManager* _sm; + + // noncopyable, nonassignable + ChatMessageHandler(ChatMessageHandler&); + void operator=(ChatMessageHandler&); +}; + +} + +} + +#endif + +/* + 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:textwidth=99 : diff --git a/src/jabber_whiteboard/connection-establishment.cpp b/src/jabber_whiteboard/connection-establishment.cpp new file mode 100644 index 000000000..9382227fb --- /dev/null +++ b/src/jabber_whiteboard/connection-establishment.cpp @@ -0,0 +1,307 @@ +/** + * Whiteboard session manager + * Methods for establishing connections and notifying the user of events + * + * Authors: + * David Yip + * + * Copyright (c) 2005 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "util/ucompose.hpp" +#include +#include +#include + +#include "desktop.h" +#include "file.h" +#include "document.h" + +#include "xml/repr.h" + +#include "jabber_whiteboard/defines.h" +#include "jabber_whiteboard/typedefs.h" +#include "jabber_whiteboard/node-tracker.h" +#include "jabber_whiteboard/chat-handler.h" +#include "jabber_whiteboard/message-queue.h" +#include "jabber_whiteboard/session-manager.h" +#include "jabber_whiteboard/invitation-confirm-dialog.h" + +namespace Inkscape { + +namespace Whiteboard { + +void +SessionManager::sendRequestToUser(std::string const& recipientJID) +{ + /* + Glib::ustring doccopy; + if (document != NULL) { + doccopy = *document; + } + */ + this->session_data->status.set(WAITING_FOR_INVITE_RESPONSE, 1); + this->sendMessage(CONNECT_REQUEST_USER, 0, "", recipientJID.c_str(), false); +} + +void +SessionManager::sendRequestToChatroom(Glib::ustring const& server, Glib::ustring const& chatroom, Glib::ustring const& handle, Glib::ustring const& password) +{ + // We do not yet use the Basic MUC Protocol for connection establishment etc + // . The protocol we use is the + // old GroupChat system; extension to MUC is TODO + + // Compose room@service/nick string for "to" field + Glib::ustring dest = String::ucompose("%1@%2/%3", chatroom, server, handle); + LmMessage* presence_req = lm_message_new(dest.data(), LM_MESSAGE_TYPE_PRESENCE); + + // Add 'from' attribute + LmMessageNode* preq_root = lm_message_get_node(presence_req); + + lm_message_node_set_attribute(preq_root, "from", lm_connection_get_jid(this->session_data->connection)); + + // Add + // (Not anymore: we don't speak it! -- yipdw) + LmMessageNode* xmlns_node = lm_message_node_add_child(preq_root, "x", ""); + lm_message_node_set_attribute(xmlns_node, "xmlns", "http://jabber.org/protocol/muc/"); + + // If a password was supplied, add it to xmlns_node + if (password != NULL) { + lm_message_node_add_child(xmlns_node, "password", password.c_str()); + } + + // Create chat message handler and node tracker + if (!this->_myChatHandler) { + this->_myChatHandler = new ChatMessageHandler(this); + } + + // Flag ourselves as connecting to a chatroom (but not yet connected) + this->session_data->status.set(CONNECTING_TO_CHAT, 1); + // Send the message + GError *error = NULL; + if (!lm_connection_send(this->session_data->connection, presence_req, &error)) { + g_error("Presence message could not be sent to %s: %s", dest.data(), error->message); + this->session_data->status.set(CONNECTING_TO_CHAT, 0); + } + + this->session_data->chat_handle = handle; + this->session_data->chat_server = server; + this->session_data->chat_name = chatroom; + + this->setRecipient(String::ucompose("%1@%2", chatroom, server).data()); + + lm_message_unref(presence_req); +} + +void +SessionManager::sendConnectRequestResponse(char const* recipientJID, gboolean accepted_request) +{ + if (accepted_request == TRUE) { + this->setRecipient(recipientJID); + this->session_data->status.set(IN_WHITEBOARD, 1); + } + + this->sendMessage(CONNECT_REQUEST_RESPONSE_USER, accepted_request, "", recipientJID, false); +} + +// When this method is invoked, it means that the user has received an invitation from another peer +// to engage in a whiteboard session (i.e. 1:1 communication). The user may accept or reject this invitation. +void +SessionManager::receiveConnectRequest(gchar const* requesterJID) +{ + int x, y; + Gdk::ModifierType mt; + Gdk::Display::get_default()->get_pointer(x, y, mt); + + if (mt) { + // Attach a polling timeout + this->_notify_incoming_request = Glib::signal_timeout().connect(sigc::bind< 0 >(sigc::mem_fun(*this, &SessionManager::_pollReceiveConnectRequest), requesterJID), 50); + return; + } + + if (this->session_data->status[IN_WHITEBOARD]) { + this->sendMessage(ALREADY_IN_SESSION, 0, "", requesterJID, false); + } + + // Check to see if the user made any modifications to this document. If so, + // we want to give them the option of (1) letting us clear their document or (2) + // opening a new, blank document for the whiteboard session. + Glib::ustring primary = "" + String::ucompose(_("%1 has invited you to a whiteboard session."), requesterJID) + "\n\n"; + Glib::ustring title = String::ucompose(_("Incoming whiteboard invitation from %1"), requesterJID); + + if (sp_document_repr_root(this->_myDoc)->attribute("sodipodi:modified") == NULL) { + primary += String::ucompose(_("Do you wish to accept %1's whiteboard session invitation?"), requesterJID); + } else { + primary += String::ucompose(_("Would you like to accept %1's invitation in a new document window?\nAccepting the invitation in your current window will discard unsaved changes."), requesterJID); + } + + // Construct confirmation dialog + InvitationConfirmDialog dialog(primary); + + dialog.add_button(_("Accept invitation"), ACCEPT_INVITATION); + dialog.add_button(_("Decline invitation"), DECLINE_INVITATION); + dialog.add_button(_("Accept invitation in new document window"), ACCEPT_INVITATION_IN_NEW_WINDOW); + + bool undecided = true; + InvitationResponses resp = static_cast< InvitationResponses >(dialog.run()); + + while(undecided) { + if (resp == ACCEPT_INVITATION) { + undecided = false; + this->clearDocument(); + + // Create a receive queue for the initiator of this request + this->session_data->receive_queues[requesterJID] = new ReceiveMessageQueue(this); + + this->setupInkscapeInterface(); + if (dialog.useSessionFile()) { + this->session_data->sessionFile = dialog.getSessionFilePath(); + this->_tryToStartLog(); + } + this->sendConnectRequestResponse(requesterJID, TRUE); + + } else if (resp == ACCEPT_INVITATION_IN_NEW_WINDOW) { + SPDesktop* newdesktop = sp_file_new_default(); + if (newdesktop != NULL) { + undecided = false; + + // Swap desktops around + + // Destroy the new desktop's session manager and add this one in + delete newdesktop->_whiteboard_session_manager; + newdesktop->_whiteboard_session_manager = this; + + // Assign a new session manager to our old desktop + this->_myDesktop->_whiteboard_session_manager = new SessionManager(this->_myDesktop); + + // Reset our desktop and document pointers + this->setDesktop(newdesktop); + + // Prepare document and send acceptance notification + this->session_data->receive_queues[requesterJID] = new ReceiveMessageQueue(this); + this->clearDocument(); + this->setupInkscapeInterface(); + if (dialog.useSessionFile()) { + this->session_data->sessionFile = dialog.getSessionFilePath(); + this->_tryToStartLog(); + } + this->sendConnectRequestResponse(requesterJID, TRUE); + + } else { + // We could not create a new desktop; ask the user if she or he wants to + // replace the current document and accept the invitation, or reject the invitation. + // TRANSLATORS: %1 is a userid here + Glib::ustring msg = "" + String::ucompose(_("A new document window could not be opened for a whiteboard session with %1"), requesterJID) + ".\n\nWould you like to accept the whiteboard connection in the active document or refuse the invitation?"; + InvitationConfirmDialog replace_dialog(msg); + dialog.add_button(_("Accept invitation"), ACCEPT_INVITATION); + dialog.add_button(_("Decline invitation"), DECLINE_INVITATION); + resp = static_cast< InvitationResponses >(dialog.run()); + } + } else { + undecided = false; + this->sendMessage(CONNECT_REQUEST_REFUSED_BY_PEER, 0, "", requesterJID, false); + } + } +} + +// When this method is invoked, it means that the other peer +// has accepted our request. +void +SessionManager::receiveConnectRequestResponse(InvitationResponses response, std::string& sender) +{ + this->session_data->status.set(WAITING_FOR_INVITE_RESPONSE, 0); + + switch(response) { + case ACCEPT_INVITATION: + { + + // Create a receive queue for the other peer. + this->session_data->receive_queues[sender] = new ReceiveMessageQueue(this); + + KeyToNodeMap newids; + NodeToKeyMap newnodes; + this->_myTracker = new XMLNodeTracker(this); + this->setupInkscapeInterface(); + this->_tryToStartLog(); + this->resendDocument(this->session_data->recipient, newids, newnodes); + this->_myTracker->put(newids, newnodes); +// this->_myTracker->dump(); + this->setupCommitListener(); + break; + } + + case DECLINE_INVITATION: + { + // TRANSLATORS: %1 is the peer whom refused our invitation. + Glib::ustring primary = String::ucompose(_("The user %1 has refused your whiteboard invitation.\n\n"), sender); + + // TRANSLATORS: %1 is the peer whom refused our invitation, %2 is our Jabber identity. + Glib::ustring secondary = String::ucompose(_("You are still connected to a Jabber server as %2, and may send an invitation to %1 again, or you may send an invitation to a different user."), sender, lm_connection_get_jid(this->session_data->connection)); + + Gtk::MessageDialog dialog(primary + secondary, true, Gtk::MESSAGE_INFO, Gtk::BUTTONS_CLOSE, false); + dialog.run(); + break; + + } + + case PEER_ALREADY_IN_SESSION: + { + // TRANSLATORS: %1 is the peer whom we tried to contact, but is already in a whiteboard session. + Glib::ustring primary = String::ucompose(_("The user %1 is already in a whiteboard session.\n\n"), sender); + + // TRANSLATORS: %1 is the peer whom we tried to contact, but is already in a whiteboard session. + Glib::ustring secondary = String::ucompose(_("You are still connected to a Jabber server as %1, and may send an invitation to a different user."), sender); + Gtk::MessageDialog dialog(primary + secondary, true, Gtk::MESSAGE_INFO, Gtk::BUTTONS_CLOSE, false); + dialog.run(); + + break; + } + default: + break; + } +} + +void +SessionManager::receiveConnectRequestResponseChat(gchar const* recipient) +{ + // When responding to connection request responses in chatrooms, + // the responding user is already established in the whiteboard session. + // Therefore we do not need to perform any setup of observers or dispatchers; the requesting user + // will do that. + + KeyToNodeMap newids; + NodeToKeyMap newnodes; + this->resendDocument(recipient, newids, newnodes); +} + +bool +SessionManager::_pollReceiveConnectRequest(Glib::ustring const recipientJID) +{ + int x, y; + Gdk::ModifierType mt; + Gdk::Display::get_default()->get_pointer(x, y, mt); + + if (mt) { + return true; + } else { + this->receiveConnectRequest(recipientJID.c_str()); + return false; + } +} + +} + +} + +/* + 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:textwidth=99 : diff --git a/src/jabber_whiteboard/defines.h b/src/jabber_whiteboard/defines.h new file mode 100644 index 000000000..3fc3c0e45 --- /dev/null +++ b/src/jabber_whiteboard/defines.h @@ -0,0 +1,98 @@ +/** + * Whiteboard session manager + * Definitions + * + * Authors: + * David Yip + * + * Copyright (c) 2005 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifndef __WHITEBOARD_DEFINES_H__ +#define __WHITEBOARD_DEFINES_H__ + +#include "jabber_whiteboard/message-tags.h" +#include "jabber_whiteboard/internal-constants.h" + +namespace Inkscape { + +namespace Whiteboard { + +// message types +// explicitly numbered to aid protocol description later on +enum MessageType { + // image and internal data + CHANGE_NOT_REPEATABLE = 0, + CHANGE_REPEATABLE = 1, + DUMMY_CHANGE = 2, + CHANGE_COMMIT = 3, + DOCUMENT_BEGIN = 4, + DOCUMENT_END = 5, + // 1-1 connections + CONNECT_REQUEST_USER = 6, + CONNECT_REQUEST_RESPONSE_USER = 7, + // chat connections + CONNECT_REQUEST_RESPONSE_CHAT = 8, + // chatroom document synchronization + CHATROOM_SYNCHRONIZE_REQUEST = 9, + CHATROOM_SYNCHRONIZE_RESPONSE = 10, + // requests + DOCUMENT_SENDER_REQUEST = 11, + DOCUMENT_SENDER_REQUEST_RESPONSE = 12, + DOCUMENT_REQUEST = 13, + // notifications + CONNECTED_SIGNAL = 14, + DISCONNECTED_FROM_USER_SIGNAL = 15, + // error responses + CONNECT_REQUEST_REFUSED_BY_PEER = 16, + UNSUPPORTED_PROTOCOL_VERSION = 17, + ALREADY_IN_SESSION = 18, + + // error cases, i.e. garbled messages or bad clients. These should + // never actually be transmitted + UNKNOWN = 21 +}; + +// Responses to whiteboard invitations +enum InvitationResponses { + ACCEPT_INVITATION, + ACCEPT_INVITATION_IN_NEW_WINDOW, + DECLINE_INVITATION, + PEER_ALREADY_IN_SESSION +}; + +// Message handler modes +enum HandlerMode { + DEFAULT, + PRESENCE, + ERROR +}; + +// Actions to pass to the node tracker when we modify a node in +// the document tree upon event serialization +enum NodeTrackerAction { + NODE_ADD, + NODE_REMOVE, + NODE_UNKNOWN +}; + +} + +} + + + +#endif + +/* + 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:textwidth=99 : diff --git a/src/jabber_whiteboard/deserializer.cpp b/src/jabber_whiteboard/deserializer.cpp new file mode 100644 index 000000000..40047051e --- /dev/null +++ b/src/jabber_whiteboard/deserializer.cpp @@ -0,0 +1,417 @@ +/** + * Inkboard message -> XML::Event* deserializer + * + * Authors: + * David Yip + * + * Copyright (c) 2005 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "xml/log-builder.h" +#include "xml/event.h" +#include "xml/node.h" +#include "xml/repr.h" + +#include "util/shared-c-string-ptr.h" + +#include "gc-anchored.h" + +#include "jabber_whiteboard/message-utilities.h" +#include "jabber_whiteboard/typedefs.h" +#include "jabber_whiteboard/node-utilities.h" +#include "jabber_whiteboard/node-tracker.h" +#include "jabber_whiteboard/deserializer.h" +#include + +namespace Inkscape { + +namespace Whiteboard { + +void +Deserializer::deserializeEventAdd(Glib::ustring const& msg) +{ + // 1. Extract required attributes: parent, child, node name, and node type. + // If any of these cannot be found, return. + std::string parent, child, prev; + Glib::ustring name, type; + + struct Node buf; + + buf.tag = MESSAGE_PARENT; + if (!MessageUtilities::findTag(buf, msg)) { + return; + } + parent = buf.data.c_str(); + + buf.tag = MESSAGE_CHILD; + if (!MessageUtilities::findTag(buf, msg)) { + return; + } + child = buf.data.c_str(); + + KeyToNodeMap::iterator i = this->_newnodes.find(child); + if (i != this->_newnodes.end()) { + if (this->_node_action_tracker.getAction(i->second) == NODE_ADD) { + return; + } + } + + buf.tag = MESSAGE_NAME; + if (!MessageUtilities::findTag(buf, msg)) { + return; + } else { + name = buf.data; + } + + buf.tag = MESSAGE_NODETYPE; + if (!MessageUtilities::findTag(buf, msg)) { + return; + } else { + type = buf.data; + } + + // 2. Extract optional attributes: the node previous to the new child node. + buf.tag = MESSAGE_REF; + if (MessageUtilities::findTag(buf, msg)) { + prev = buf.data.c_str(); + } + + // 3. Check if the received child node is a special node. If it is, and we are already + // tracking it, then we should not add the node. + if (this->_xnt->isSpecialNode(name)) { + if (this->_xnt->isTracking(this->_xnt->getSpecialNodeKeyFromName(name))) { + return; + } + } + + // 4. Look up the parent node. If we cannot find it, return. + XML::Node* parentRepr = this->_getNodeByID(parent); + if (parentRepr == NULL) { + g_warning("Cannot find parent node identified by %s", parent.c_str()); + return; + } + + // 5. Look up the node previous to the child, if it exists. + // If we cannot find it, we may be in a change conflict situation. + // In that case, just append the node. + XML::Node* prevRepr = NULL; + if (!prev.empty()) { + prevRepr = this->_getNodeByID(prev); + if (prevRepr == NULL) { + g_warning("Prev node %s could not be found; appending incoming node. Document may not be synchronized.", prev.c_str()); + prevRepr = parentRepr->lastChild(); + } + } + + if (prevRepr) { + if (prevRepr->parent() != parentRepr) { + if (this->_parent_child_map[prevRepr] != parentRepr) { + g_warning("ref mismatch on node %s: child=%s ref=%p parent=%p ref->parent()=%p", prev.c_str(), child.c_str(), prevRepr, parentRepr, prevRepr->parent()); + g_warning("parent_child_map[%p (%s)] = %p (%s)", prevRepr, this->_xnt->get(*prevRepr).c_str(), this->_parent_child_map[prevRepr], this->_xnt->get(*(this->_parent_child_map[prevRepr])).c_str()); + return; + } + } + } + + XML::Node* childRepr = NULL; + + // 6. Create the child node. + + switch (NodeUtilities::stringToNodeType(type)) { + case XML::TEXT_NODE: + buf.tag = MESSAGE_CONTENT; + if (!MessageUtilities::findTag(buf, msg)) { + childRepr = sp_repr_new_text(""); + } else { + childRepr = sp_repr_new_text(buf.data.c_str()); + } + break; + case XML::DOCUMENT_NODE: + // TODO + case XML::COMMENT_NODE: + buf.tag = MESSAGE_CONTENT; + if (!MessageUtilities::findTag(buf, msg)) { + childRepr = sp_repr_new_comment(""); + } else { + childRepr = sp_repr_new_comment(buf.data.c_str()); + } + break; + case XML::ELEMENT_NODE: + default: + childRepr = sp_repr_new(name.data()); + break; + } + + + this->_actions.push_back(SerializedEventNodeAction(KeyNodePair(child, childRepr), NODE_ADD)); + this->_newnodes[child] = childRepr; + this->_newkeys[childRepr] = child; + + + // 8. Deserialize the event. + this->_builder.addChild(*parentRepr, *childRepr, prevRepr); + this->_parent_child_map.erase(childRepr); + this->_parent_child_map[childRepr] = parentRepr; + this->_addOneEvent(this->_builder.detach()); + Inkscape::GC::release(childRepr); +} + +void +Deserializer::deserializeEventDel(Glib::ustring const& msg) +{ + // 1. Extract required attributes: parent, child. If we do not know these, + // return. + std::string parent, child, prev; + + struct Node buf; + + buf.tag = MESSAGE_PARENT; + if (!MessageUtilities::findTag(buf, msg)) { + return; + } + parent = buf.data.c_str(); + + buf.tag = MESSAGE_CHILD; + if (!MessageUtilities::findTag(buf, msg)) { + return; + } + child = buf.data.c_str(); + + KeyToNodeMap::iterator i = this->_newnodes.find(child); + if (i != this->_newnodes.end()) { + if (this->_node_action_tracker.getAction(i->second) == NODE_REMOVE) { + return; + } + } + + // 2. Extract optional attributes: previous node. + buf.tag = MESSAGE_REF; + if (MessageUtilities::findTag(buf, msg)) { + prev = buf.data.c_str(); + } + + // 3. Retrieve nodes. If we cannot find all nodes involved, return. + XML::Node* parentRepr = this->_getNodeByID(parent); + XML::Node* childRepr = this->_getNodeByID(child); + XML::Node* prevRepr = NULL; + if (!prev.empty()) { + prevRepr = this->_getNodeByID(prev); + if (prevRepr == NULL) { + return; + } + } + + // 4. Deserialize the event. + if (parentRepr && childRepr) { + if (childRepr->parent() == parentRepr || this->_parent_child_map[childRepr] == parentRepr) { +// this->_actions.push_back(SerializedEventNodeAction(KeyNodePair(child, childRepr), NODE_REMOVE)); + this->_builder.removeChild(*parentRepr, *childRepr, prevRepr); + this->_parent_child_map.erase(childRepr); + this->_addOneEvent(this->_builder.detach()); + + // 5. Mark the removed node and all its children for removal from the tracker. + this->_recursiveMarkForRemoval(childRepr); + } else { + g_warning("child->parent() == parent mismatch on child=%s (%p), parent=%s: parent=%p child->parent()=%p", child.c_str(), childRepr, parent.c_str(), parentRepr, childRepr->parent()); + g_warning("parent_child_map[%p] = %p", childRepr, this->_parent_child_map[childRepr]); + } + } else { + g_warning("Missing parentRepr and childRepr: parent=%p, child=%p", parentRepr, childRepr); + } +} + +void +Deserializer::deserializeEventChgOrder(Glib::ustring const& msg) +{ + // 1. Extract required attributes: node ID, parent ID, new previous node ID. + // If we do not know these, return. + std::string id, parentid, oldprevid, newprevid; + Node buf; + + buf.tag = MESSAGE_ID; + if (MessageUtilities::findTag(buf, msg)) { + id = buf.data.raw(); + } else { + return; + } + + buf.tag = MESSAGE_PARENT; + if (MessageUtilities::findTag(buf, msg)) { + parentid = buf.data.raw(); + } else { + return; + } + + // 2. Extract optional attributes: old previous node, new previous node. + buf.tag = MESSAGE_OLDVAL; + if (MessageUtilities::findTag(buf, msg)) { + oldprevid = buf.data.raw(); + } + + buf.tag = MESSAGE_NEWVAL; + if (MessageUtilities::findTag(buf, msg)) { + newprevid = buf.data.raw(); + } else { + return; + } + + // 3. Find the identified nodes. If we do not know about the parent and child, return. + XML::Node* node = this->_getNodeByID(id); + XML::Node* parent = this->_getNodeByID(parentid); + XML::Node* oldprev = NULL; + XML::Node* newprev = NULL; + if (!oldprevid.empty()) { + oldprev = this->_getNodeByID(oldprevid); + } + + if (!newprevid.empty()) { + newprev = this->_getNodeByID(newprevid); + } + + if (parent && node) { + // 4. Deserialize the event. + this->_builder.setChildOrder(*parent, *node, oldprev, newprev); + this->_addOneEvent(this->_builder.detach()); + } else { + return; + } +} + +void +Deserializer::deserializeEventChgContent(Glib::ustring const& msg) +{ + // 1. Extract required attributes: node ID. If we do not know these, return. + std::string id; + Util::SharedCStringPtr oldval, newval; + Node buf; + + buf.tag = MESSAGE_ID; + if (!MessageUtilities::findTag(buf, msg)) { + return; + } else { + id = buf.data.raw(); + } + + // 2. Extract optional attributes: old value, new value. + buf.tag = MESSAGE_OLDVAL; + if (MessageUtilities::findTag(buf, msg)) { + oldval = Util::SharedCStringPtr::copy(buf.data.c_str()); + } else { + oldval = Util::SharedCStringPtr::copy(""); + } + + buf.tag = MESSAGE_NEWVAL; + if (MessageUtilities::findTag(buf, msg)) { + newval = Util::SharedCStringPtr::copy(buf.data.c_str()); + } else { + newval = Util::SharedCStringPtr::copy(""); + } + + // 3. Find the node identified by the ID. If we cannot find it, return. + XML::Node* node = this->_getNodeByID(id); + if (node == NULL) { + return; + } + + // 4. Deserialize the event. + this->_builder.setContent(*node, oldval, newval); + this->_addOneEvent(this->_builder.detach()); +} + +void +Deserializer::deserializeEventChgAttr(Glib::ustring const& msg) +{ + // 1. Extract required attributes: node ID, attribute key. If we do not know these, + // return. + + struct Node buf; + buf.tag = MESSAGE_ID; + if (!MessageUtilities::findTag(buf, msg)) { + return; + } + + std::string id = buf.data.data(); + + buf.tag = MESSAGE_KEY; + if (!MessageUtilities::findTag(buf, msg)) { + return; + } + + Glib::ustring key = buf.data; + + // 2. Extract optional attributes: new value. If we do not find it in the message, + // assume there is no new value. + buf.tag = MESSAGE_NEWVAL; + Util::SharedCStringPtr newval; + if (MessageUtilities::findTag(buf, msg)) { + newval = Util::SharedCStringPtr::copy(buf.data.c_str()); + } else { + newval = Util::SharedCStringPtr::copy(""); + } + + // 3. Extract optional attributes: old value. If we do not find it in the message, + // assume that there is no old value. + buf.tag = MESSAGE_OLDVAL; + Util::SharedCStringPtr oldval; + if (MessageUtilities::findTag(buf, msg)) { + oldval = Util::SharedCStringPtr::copy(buf.data.c_str()); + } else { + oldval = Util::SharedCStringPtr::copy(""); + } + + // 4. Look up this node in the local node database and external tracker. + // If it cannot be found, return. + XML::Node* node = this->_getNodeByID(id); + if (node == NULL) { + g_warning("Could not find node %s on which to change attribute", id.c_str()); + return; + } + + // 5. If this node is in the actions queue and is marked as "new", we need to apply + // _all_ received attributes to it _before_ adding it to the document tree. + if (this->_newnodes.find(id) != this->_newnodes.end()) { + node->setAttribute(key.c_str(), newval.cString()); + } + + // 6. Deserialize the event. + this->_builder.setAttribute(*node, g_quark_from_string(key.c_str()), oldval, newval); + this->_updated.insert(node); + this->_addOneEvent(this->_builder.detach()); +} + +void +Deserializer::_recursiveMarkForRemoval(XML::Node* node) +{ + if (node != NULL) { + NodeToKeyMap::iterator i = this->_newkeys.find(node); + if (i == this->_newkeys.end()) { + std::string id = this->_xnt->get(*node); + if (!id.empty()) { + this->_actions.push_back(SerializedEventNodeAction(KeyNodePair(id, node), NODE_REMOVE)); + } + } else { + this->_actions.push_back(SerializedEventNodeAction(KeyNodePair((*i).second, node), NODE_REMOVE)); + } + + for (XML::Node* child = node->firstChild(); child; child = child->next()) { + this->_recursiveMarkForRemoval(child); + } + } +} + +} + +} + +/* + 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:textwidth=99 : diff --git a/src/jabber_whiteboard/deserializer.h b/src/jabber_whiteboard/deserializer.h new file mode 100644 index 000000000..715ca4c66 --- /dev/null +++ b/src/jabber_whiteboard/deserializer.h @@ -0,0 +1,285 @@ +/** + * Inkboard message -> XML::Event* deserializer + * + * Authors: + * David Yip + * + * Copyright (c) 2005 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifndef __WHITEBOARD_MESSAGE_DESERIALIZER_H__ +#define __WHITEBOARD_MESSAGE_DESERIALIZER_H__ + +#include "xml/log-builder.h" +#include "xml/event.h" + +#include "jabber_whiteboard/node-tracker-event-tracker.h" +#include "jabber_whiteboard/node-tracker.h" +#include "jabber_whiteboard/typedefs.h" + +#include +#include +#include + +namespace Inkscape { + +namespace Whiteboard { + +/** + * A stateful XML::Event deserializer. + * + * The Deserializer class is meant to deserialize XML::Events serialized by + * Inkscape::Whiteboard::Serializer or a serializer that serializes + * XML::Events into the same format. + * + * Usage is as follows: + *
    + *
  1. For each serialized event called, call the appropriate deserialization method.
  2. + *
  3. Detach the deserialized event.
  4. + *
+ * + * The deserializer does not actually modify any aspect of the document or node-tracking systems. + * Methods are provided to provide the information necessary to perform the modifications outside + * of the deserializer. + */ +class Deserializer { +public: + /** + * Constructor. + * + * \param xnt The XMLNodeTracker that a Deserializer should use for retrieving + * XML::Nodes based on string keys. + */ + Deserializer(XMLNodeTracker* xnt) : _xnt(xnt) + { + this->clearEventLog(); + } + + ~Deserializer() { } + + /** + * Deserialize a node add event. + * + * \see XML::EventAdd + * \param msg The message that describes the event. + */ + void deserializeEventAdd(Glib::ustring const& msg); + + /** + * Deserialize a node remove event. + * + * \see XML::EventDel + * \param msg The message that describes the event. + */ + void deserializeEventDel(Glib::ustring const& msg); + + /** + * Deserialize a node order change event. + * + * \see XML::EventChgOrder + * \param msg The message that describes the event. + */ + void deserializeEventChgOrder(Glib::ustring const& msg); + + /** + * Deserialize a node content change event. + * + * \see XML::EventChgContent + * \param msg The message that describes the event. + */ + void deserializeEventChgContent(Glib::ustring const& msg); + + /** + * Deserialize a node attribute change event. + * + * \see XML::EventChgAttr + * \param msg The message that describes the event. + */ + void deserializeEventChgAttr(Glib::ustring const& msg); + + /** + * Retrieve the deserialized event log. + * This method does not clear the internal event log kept by the deserializer. + * To do that, use detachEventLog. + * + * \return The deserialized event log. + */ + XML::Event* getEventLog() + { + return this->_log; + } + + /** + * Retrieve the deserialized event log and clear the internal event log kept by the deserializer. + * + * \return The deserialized event log. + */ + XML::Event* detachEventLog() + { + XML::Event* ret = this->_log; + this->clearEventLog(); + return ret; + } + + /** + * Clear the internal event log. + */ + void clearEventLog() + { + g_log(NULL, G_LOG_LEVEL_DEBUG, "Clearing event log"); + this->_log = NULL; + } + + /** + * Retrieve a list of node entry actions (add node entry, remove node entry) + * that need to be performed on the XMLNodeTracker. + * + * Because this method returns a reference to a list, it is not safe for use + * across multiple invocations of this Deserializer. + * + * \return A reference to a list of node entry actions generated while deserializing. + */ + KeyToNodeActionList& getNodeTrackerActions() + { + return this->_actions; + } + + /** + * Retrieve a list of node entry actions (add node entry, remove node entry) + * that need to be performed on the XMLNodeTracker. + * + * \return A list of node entry actions generated while deserializing. + */ + KeyToNodeActionList getNodeTrackerActionsCopy() + { + return this->_actions; + } + + /** + * Retrieve a set of nodes for which an EventChgAttr was deserialized. + * + * For some actions (i.e. text tool) it is necessary to call updateRepr() on + * the updated nodes. This method provides the information required to perform + * that action. + * + * Because this method returns a reference to a set, it is not safe for use + * across multiple invocations of this Deserializer. + * + * \return A reference to a set of nodes for which an EventChgAttr was deserialized. + */ + AttributesUpdatedSet& getUpdatedAttributeNodeSet() + { + return this->_updated; + } + + /** + * Retrieve a set of nodes for which an EventChgAttr was deserialized. + * + * For some actions (i.e. text tool) it is necessary to call updateRepr() on + * the updated nodes. This method provides the information required to perform + * that action. + * + * \return A set of nodes for which an EventChgAttr was deserialized. + */ + AttributesUpdatedSet getUpdatedAttributeNodeSetCopy() + { + return this->_updated; + } + + /** + * Clear all internal node buffers. + */ + void clearNodeBuffers() + { + g_log(NULL, G_LOG_LEVEL_DEBUG, "Clearing deserializer node buffers"); + this->_newnodes.clear(); + this->_actions.clear(); + this->_newkeys.clear(); + this->_parent_child_map.clear(); + this->_updated.clear(); + } + + /** + * Clear all internal state. + */ + void reset() + { + this->clearEventLog(); + this->clearNodeBuffers(); + } + +private: + XML::Node* _getNodeByID(std::string const& id) + { + KeyToNodeMap::iterator i = this->_newnodes.find(id); + if (i != this->_newnodes.end()) { + return const_cast< XML::Node* >(i->second); + } else { + if (this->_xnt->isTracking(id)) { + return this->_xnt->get(id); + } else { + return NULL; + } + } + } + + void _addOneEvent(XML::Event* event) + { + if (this->_log == NULL) { + this->_log = event; + } else { + event->next = this->_log; + this->_log = event; + } + } + + void _recursiveMarkForRemoval(XML::Node* node); + + // internal states with accessors: + + // node tracker actions (add node, remove node) + KeyToNodeActionList _actions; + + // nodes that have had their attributes updated + AttributesUpdatedSet _updated; + + // the deserialized event log + XML::Event* _log; + + + // for internal use: + + // These maps only store information on a single node. That's fine, though; + // all we care about is the ability to do key <-> node association. The NodeTrackerEventTracker + // and KeyToNodeActionList keep track of the actual actions we need to perform + // on the node tracker. + NodeToKeyMap _newkeys; + KeyToNodeMap _newnodes; + NodeTrackerEventTracker _node_action_tracker; + + typedef std::map< XML::Node*, XML::Node* > _pc_map_type; + _pc_map_type _parent_child_map; + + XMLNodeTracker* _xnt; + + XML::LogBuilder _builder; +}; + +} + +} + +#endif + +/* + 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:textwidth=99 : diff --git a/src/jabber_whiteboard/empty.cpp b/src/jabber_whiteboard/empty.cpp new file mode 100644 index 000000000..0fed24e45 --- /dev/null +++ b/src/jabber_whiteboard/empty.cpp @@ -0,0 +1,14 @@ +/// Some archivers don't seem to like creating an archive without being +/// given any members to archive. This file acts as a placeholder + + +/* + 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:textwidth=99 : diff --git a/src/jabber_whiteboard/error-codes.h b/src/jabber_whiteboard/error-codes.h new file mode 100644 index 000000000..e5c6268fa --- /dev/null +++ b/src/jabber_whiteboard/error-codes.h @@ -0,0 +1,41 @@ +/** + * Whiteboard session manager + * Error codes + * + * Authors: + * David Yip + * + * Copyright (c) 2005 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifndef __WHITEBOARD_JABBER_ERROR_CODES_H__ +#define __WHITEBOARD_JABBER_ERROR_CODES_H__ + +namespace Inkscape { + +namespace Whiteboard { + +namespace ErrorCodes { + +static unsigned int const SERVER_CONNECT_FAILED = 502; +static unsigned int const CHAT_HANDLE_IN_USE = 409; + +} + +} + +} +#endif + +/* + 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:textwidth=99 : diff --git a/src/jabber_whiteboard/internal-constants.cpp b/src/jabber_whiteboard/internal-constants.cpp new file mode 100644 index 000000000..4956a402c --- /dev/null +++ b/src/jabber_whiteboard/internal-constants.cpp @@ -0,0 +1,76 @@ +/** + * Whiteboard session manager + * Internal constants + * + * Authors: + * David Yip + * + * Copyright (c) 2005 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "jabber_whiteboard/internal-constants.h" + +namespace Inkscape { + +namespace Whiteboard { +// Protocol versions +char const* MESSAGE_PROTOCOL_V1 = "1"; +char const* MESSAGE_PROTOCOL_V2 = "2"; +int const HIGHEST_SUPPORTED = 1; + +// Node types (as strings) +char const* NODETYPE_DOCUMENT_STR = "document"; +char const* NODETYPE_ELEMENT_STR = "element"; +char const* NODETYPE_TEXT_STR = "text"; +char const* NODETYPE_COMMENT_STR = "comment"; + +// Number of chars to allocate for type field (in SessionManager::sendMessage) +int const TYPE_FIELD_SIZE = 5; + +// Number of chars to allocate for sequence number field (in SessionManager::sendMessage) +int const SEQNUM_FIELD_SIZE = 70; + +// Designators for certain "special" nodes in the document +// These nodes are "special" because they are generally present in all documents, +// and we generally only want one copy of them +char const* DOCUMENT_ROOT_NODE = "ROOT"; +char const* DOCUMENT_NAMEDVIEW_NODE = "NAMEDVIEW"; + +// Names of these special nodes +char const* DOCUMENT_ROOT_NAME = "svg:svg"; +char const* DOCUMENT_NAMEDVIEW_NAME = "sodipodi:namedview"; + +// Inkboard client states +int const IN_WHITEBOARD = 0; +int const LOGGED_IN = 1; +int const IN_CHATROOM = 2; +int const WAITING_FOR_INVITE_RESPONSE = 3; +int const CONNECTING_TO_CHAT = 4; +int const WAITING_TO_SYNC_TO_CHAT = 5; +int const SYNCHRONIZING_WITH_CHAT = 6; +int const OPEN_FOR_DOC = 7; +int const PLAYING_SESSION_FILE = 8; + +// TODO: make this user-configurable, within sane limits +// ("sane" limits being roughly in the range (10, 100], from personal testing) +// Based on discussions with Ted, it seems that we're going to make the Jabber guys +// accomodate Inkscape, not the other way around... +// Dispatch interval (in milliseconds) +int const SEND_TIMEOUT = 35; +} + +} + + +/* + 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:textwidth=99 : diff --git a/src/jabber_whiteboard/internal-constants.h b/src/jabber_whiteboard/internal-constants.h new file mode 100644 index 000000000..5a14737be --- /dev/null +++ b/src/jabber_whiteboard/internal-constants.h @@ -0,0 +1,83 @@ +/** + * Whiteboard session manager + * Internal constants + * + * Authors: + * David Yip + * + * Copyright (c) 2005 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifndef __WHITEBOARD_INTERNAL_CONSTANTS_H__ +#define __WHITEBOARD_INTERNAL_CONSTANTS_H__ + +namespace Inkscape { + +namespace Whiteboard { + +// TODO: breaking these up into namespaces would be nice, but it's too much typing +// for now + +// Protocol versions +extern char const* MESSAGE_PROTOCOL_V1; +extern int const HIGHEST_SUPPORTED; + +// Node types (as strings) +extern char const* NODETYPE_DOCUMENT_STR; +extern char const* NODETYPE_ELEMENT_STR; +extern char const* NODETYPE_TEXT_STR; +extern char const* NODETYPE_COMMENT_STR; + +// Number of chars to allocate for type field (in SessionManager::sendMessage) +extern int const TYPE_FIELD_SIZE; + +// Number of chars to allocate for sequence number field (in SessionManager::sendMessage) +extern int const SEQNUM_FIELD_SIZE; + +// Designators for certain "special" nodes in the document +// These nodes are "special" because they are generally present in all documents +extern char const* DOCUMENT_ROOT_NODE; +extern char const* DOCUMENT_NAMEDVIEW_NODE; + +// Names of these special nodes +extern char const* DOCUMENT_ROOT_NAME; +extern char const* DOCUMENT_NAMEDVIEW_NAME; + +// Inkboard client states +extern int const IN_WHITEBOARD; +extern int const LOGGED_IN; +extern int const IN_CHATROOM; +extern int const WAITING_FOR_INVITE_RESPONSE; +extern int const CONNECTING_TO_CHAT; +extern int const WAITING_TO_SYNC_TO_CHAT; +extern int const SYNCHRONIZING_WITH_CHAT; +extern int const OPEN_FOR_DOC; +extern int const PLAYING_SESSION_FILE; + +// update this if any other status flags are added +#define NUM_FLAGS 9 + +// TODO: make this user-configurable, within sane limits +// ("sane" limits being roughly in the range (10, 100], from personal testing) +// Based on discussions with Ted, it seems that we're going to make the Jabber guys +// accomodate Inkscape, not the other way around... +// Dispatch interval (in milliseconds) +extern int const SEND_TIMEOUT; +} + +} + +#endif + +/* + 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:textwidth=99 : diff --git a/src/jabber_whiteboard/invitation-confirm-dialog.cpp b/src/jabber_whiteboard/invitation-confirm-dialog.cpp new file mode 100644 index 000000000..8590abab8 --- /dev/null +++ b/src/jabber_whiteboard/invitation-confirm-dialog.cpp @@ -0,0 +1,66 @@ +/** + * Whiteboard invitation confirmation dialog -- + * quick subclass of Gtk::MessageDialog + * + * Authors: + * David Yip + * + * Copyright (c) 2005 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include + +#include "invitation-confirm-dialog.h" +#include "session-file-selector.h" + +namespace Inkscape { + +namespace Whiteboard { + +InvitationConfirmDialog::InvitationConfirmDialog(Glib::ustring const& msg) : + Gtk::MessageDialog(msg, true, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_NONE, false), + _usesessionfile(_("_Write session file:"), true) +{ + this->_construct(); + this->get_vbox()->show_all_children(); +} + +InvitationConfirmDialog::~InvitationConfirmDialog() +{ + +} + +Glib::ustring const& +InvitationConfirmDialog::getSessionFilePath() +{ + return this->_sfsbox.getFilename(); +} + +bool +InvitationConfirmDialog::useSessionFile() +{ + return this->_sfsbox.isSelected(); +} + +void +InvitationConfirmDialog::_construct() +{ + this->get_vbox()->pack_end(this->_sfsbox); +} + +} + +} + +/* + 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:textwidth=99 : diff --git a/src/jabber_whiteboard/invitation-confirm-dialog.h b/src/jabber_whiteboard/invitation-confirm-dialog.h new file mode 100644 index 000000000..42cea9b56 --- /dev/null +++ b/src/jabber_whiteboard/invitation-confirm-dialog.h @@ -0,0 +1,69 @@ +/** + * Whiteboard invitation confirmation dialog -- + * quick subclass of Gtk::MessageDialog + * + * Authors: + * David Yip + * + * Copyright (c) 2005 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifndef __WHITEBOARD_INVITATION_CONFIRM_DIALOG_H__ +#define __WHITEBOARD_INVITATION_CONFIRM_DIALOG_H__ + +#include +#include +#include + +#include "jabber_whiteboard/session-file-selector.h" + + +namespace Inkscape { + +namespace Whiteboard { + +class InvitationConfirmDialog : public Gtk::MessageDialog { +public: + InvitationConfirmDialog(Glib::ustring const& msg); + ~InvitationConfirmDialog(); + + Glib::ustring const& getSessionFilePath(); + bool useSessionFile(); + +private: + static unsigned int const SELECT_FILE = 0; + + void _respCallback(int resp); + + Gtk::HBox _filesel; + + SessionFileSelectorBox _sfsbox; + Gtk::CheckButton _usesessionfile; + Gtk::Entry _sessionfile; + Gtk::Button _getfilepath; + + void _construct(); + Glib::ustring _selectedpath; + + // noncopyable, nonassignable + InvitationConfirmDialog(InvitationConfirmDialog const&); + InvitationConfirmDialog& operator=(InvitationConfirmDialog const&); +}; + +} + +} +#endif + +/* + 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:textwidth=99 : diff --git a/src/jabber_whiteboard/jabber-handlers.cpp b/src/jabber_whiteboard/jabber-handlers.cpp new file mode 100644 index 000000000..308978025 --- /dev/null +++ b/src/jabber_whiteboard/jabber-handlers.cpp @@ -0,0 +1,65 @@ +/** + * Whiteboard session manager + * C-style Loudmouth callbacks + * + * Authors: + * David Yip + * + * Copyright (c) 2005 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "jabber_whiteboard/defines.h" +#include "jabber_whiteboard/jabber-handlers.h" +#include "jabber_whiteboard/message-handler.h" +#include "jabber_whiteboard/session-manager.h" + +namespace Inkscape { + +namespace Whiteboard { + +LmHandlerResult +default_handler(LmMessageHandler* handler, LmConnection* connection, LmMessage* message, gpointer user_data) +{ + MessageHandler* mh = reinterpret_cast< MessageHandler* >(user_data); + return mh->handle(message, DEFAULT); +} + + +LmHandlerResult +presence_handler(LmMessageHandler* handler, LmConnection* connection, LmMessage* message, gpointer user_data) +{ + MessageHandler* mh = reinterpret_cast< MessageHandler* >(user_data); + return mh->handle(message, PRESENCE); +} + + +LmHandlerResult +stream_error_handler(LmMessageHandler* handler, LmConnection* connection, LmMessage* message, gpointer user_data) +{ + MessageHandler* mh = reinterpret_cast< MessageHandler* >(user_data); + return mh->handle(message, ERROR); +} + +LmSSLResponse +ssl_error_handler(LmSSL* ssl, LmSSLStatus status, gpointer user_data) +{ + SessionManager* sm = reinterpret_cast< SessionManager* >(user_data); + return sm->handleSSLError(ssl, status); +} + +} + +} + +/* + 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:textwidth=99 : diff --git a/src/jabber_whiteboard/jabber-handlers.h b/src/jabber_whiteboard/jabber-handlers.h new file mode 100644 index 000000000..2eec08c78 --- /dev/null +++ b/src/jabber_whiteboard/jabber-handlers.h @@ -0,0 +1,86 @@ +/** + * Whiteboard session manager + * C-style Loudmouth callbacks + * + * Authors: + * David Yip + * + * Copyright (c) 2005 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifndef __WHITEBOARD_LOUDMOUTH_CALLBACKS__ +#define __WHITEBOARD_LOUDMOUTH_CALLBACKS__ + +extern "C" { +#include +} + +#include + +namespace Inkscape { + +namespace Whiteboard { + +/** + * C-style callback for Loudmouth to handle received presence messages. + * + * \param handler The LmMessageHandler handling this event. + * \param connection The LmConnection with which the LmMessageHandler is associated. + * \param message The Jabber message received that triggered this handler. + * \param user_data A pointer to an instance of Inkscape::Whiteboard::MessageHandler, which performs + * the real message processing work. + */ +LmHandlerResult presence_handler(LmMessageHandler* handler, LmConnection* connection, LmMessage* message, gpointer user_data); + +/** + * C-style callback for Loudmouth to handle received messages. + * + * This handler handles messages that are not presence or error messages. + * + * \param handler The LmMessageHandler handling this event. + * \param connection The LmConnection with which the LmMessageHandler is associated. + * \param message The Jabber message received that triggered this handler. + * \param user_data A pointer to an instance of Inkscape::Whiteboard::MessageHandler, which performs + * the real message processing work. + */ +LmHandlerResult default_handler(LmMessageHandler* handler, LmConnection* connection, LmMessage* message, gpointer user_data); + +/** + * C-style callback for Loudmouth to handle received error messages. + * + * \param handler The LmMessageHandler handling this event. + * \param connection The LmConnection with which the LmMessageHandler is associated. + * \param message The Jabber message received that triggered this handler. + * \param user_data A pointer to an instance of Inkscape::Whiteboard::MessageHandler, which performs + * the real message processing work. + */ +LmHandlerResult stream_error_handler(LmMessageHandler* handler, LmConnection* connection, LmMessage* message, gpointer user_data); + +/** + * C-style callback for Loudmouth to handle SSL errors. + * + * \param ssl The SSL data structure used by Loudmouth. + * \param status The error code representing the error that occurred. + * \param user_data A pointer to the SessionManager instance handling associated with the connection attempt that + * threw the SSL error. + */ +LmSSLResponse ssl_error_handler(LmSSL* ssl, LmSSLStatus status, gpointer user_data); + +} + +} + +#endif + +/* + 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:textwidth=99 : diff --git a/src/jabber_whiteboard/makefile.in b/src/jabber_whiteboard/makefile.in new file mode 100644 index 000000000..839569d0b --- /dev/null +++ b/src/jabber_whiteboard/makefile.in @@ -0,0 +1,17 @@ +# Convenience stub makefile to call the real Makefile. + +@SET_MAKE@ + +# Explicit so that it's the default rule. +all: + cd .. && $(MAKE) jabber_whiteboard/all + +clean %.a %.o: + cd .. && $(MAKE) jabber_whiteboard/$@ + +.PHONY: all clean + +OBJEXT = @OBJEXT@ + +.SUFFIXES: +.SUFFIXES: .a .$(OBJEXT) diff --git a/src/jabber_whiteboard/message-aggregator.cpp b/src/jabber_whiteboard/message-aggregator.cpp new file mode 100644 index 000000000..2077dcc6d --- /dev/null +++ b/src/jabber_whiteboard/message-aggregator.cpp @@ -0,0 +1,64 @@ +/** + * Aggregates individual serialized XML::Events into larger packages + * for more efficient delivery + * + * Authors: + * David Yip + * + * Copyright (c) 2005 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include +#include "jabber_whiteboard/message-aggregator.h" + +namespace Inkscape { + +namespace Whiteboard { + +bool +MessageAggregator::addOne(Glib::ustring const& msg, Glib::ustring& buf) +{ + // 1. If msg.bytes() > maximum size and the buffer is clear, + // then we have to send an oversize packet -- + // we won't be able to deliver the message any other way. + // Add it to the buffer and return true. Any further attempt to + // aggregate a message will be handled by condition #2. + if (msg.bytes() > MessageAggregator::MAX_SIZE && buf.empty()) { + buf += msg; + return true; + } + + // 2. If msg.bytes() + buf.bytes() > maximum size, return false. + // The user of this class is responsible for retrieving the aggregated message, + // doing something with it, clearing the buffer, and trying again. + // Otherwise, append the message to the buffer and return true. + if (msg.bytes() + buf.bytes() > MessageAggregator::MAX_SIZE) { + return false; + } else { + buf += msg; + return true; + } +} + +bool +MessageAggregator::addOne(Glib::ustring const& msg) +{ + return this->addOne(msg, this->_buf); +} + +} + +} + +/* + 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:textwidth=99 : diff --git a/src/jabber_whiteboard/message-aggregator.h b/src/jabber_whiteboard/message-aggregator.h new file mode 100644 index 000000000..56cd8e3da --- /dev/null +++ b/src/jabber_whiteboard/message-aggregator.h @@ -0,0 +1,135 @@ +/** + * Aggregates individual serialized XML::Events into larger packages + * for more efficient delivery + * + * Authors: + * David Yip + * + * Copyright (c) 2005 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifndef __WHITEBOARD_MESSAGE_AGGREGATOR_H__ +#define __WHITEBOARD_MESSAGE_AGGREGATOR_H__ + +#include + +namespace Inkscape { + +namespace Whiteboard { + +/** + * Aggregates individual serialized XML::Events into larger messages for increased + * efficiency. + * + * \see Inkscape::Whiteboard::Serializer + */ +class MessageAggregator { +public: + // TODO: This should be user-configurable; perhaps an option in Inkscape Preferences... + /// Maximum size of aggregates in kilobytes; ULONG_MAX = no limit. + static unsigned int const MAX_SIZE = 16384; + + MessageAggregator() { } + ~MessageAggregator() { } + + /** + * Return the instance of this class. + * + * \return MessageAggregator instance. + */ + static MessageAggregator& instance() + { + static MessageAggregator singleton; + return singleton; + } + + /** + * Adds one message to the aggregate + * using a user-provided buffer. Returns true if more messages can be + * added to the buffer; false otherwise. + * + * \param msg The message to add to the aggregate. + * \param buf The aggregate buffer. + * \return Whether or not more messages can be added to the buffer. + */ + bool addOne(Glib::ustring const& msg, Glib::ustring& buf); + + /** + * Adds one message to the aggregate using the internal buffer. + * Note that since this class is designed to be a singleton class, usage of the internal + * buffer is not thread-safe. Use the above method if this matters to you + * (it currently shouldn't matter, but in future...) + * + * Also note that usage of the internal buffer means that you will have to manually + * clear the internal buffer; use reset() for that. + * + * \param msg The message to add to the aggregate. + * \return Whether or not more messages can be added to the buffer. + */ + bool addOne(Glib::ustring const& msg); + + /** + * Return the aggregate message. + * + * Because this method returns a reference to a string, it is not safe for use + * across multiple invocations of this Deserializer. + * + * \return A reference to the aggregate message. + */ + Glib::ustring const& getAggregate() + { + return this->_buf; + } + + /** + * Return the aggregate message. + * + * \return The aggregate message. + */ + Glib::ustring const getAggregateCopy() + { + return this->_buf; + } + + /** + * Return the aggregate message and clear the internal buffer. + * + * \return The aggregate message. + */ + Glib::ustring const detachAggregate() + { + Glib::ustring ret = this->_buf; + this->_buf.clear(); + return ret; + } + + /** + * Clear the internal buffer. + */ + void reset() + { + this->_buf.clear(); + } + +private: + Glib::ustring _buf; +}; + +} + +} + +#endif + +/* + 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:textwidth=99 : diff --git a/src/jabber_whiteboard/message-contexts.cpp b/src/jabber_whiteboard/message-contexts.cpp new file mode 100644 index 000000000..1b5ea12fd --- /dev/null +++ b/src/jabber_whiteboard/message-contexts.cpp @@ -0,0 +1,134 @@ +/** + * Whiteboard session manager + * Inkboard message context definitions + * + * Authors: + * David Yip + * + * Copyright (c) 2005 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "jabber_whiteboard/defines.h" +#include "jabber_whiteboard/message-contexts.h" + +#include + +namespace Inkscape { + +namespace Whiteboard { + +void +initialize_received_message_contexts(MessageContextMap& mcm) +{ + + // Each Inkboard message has a context of validity according to an Inkboard + // client's state. That is, certain messages should be acknowledged and processed + // in some states, whereas other messages should not. + // For instance, a whiteboard invitation should be acknowledged if an Inkboard + // client is not in a whiteboard session, but should be refused if said client + // _is_ in a whiteboard session. + + // Only the flags that are required to be set must be set; all flags, by default, + // are zero. Explicit definition doesn't hurt, though. + + // The general format of message context creation and registration is + // std::bitset< NUM_FLAGS > m_ + // m_.set( ); + // m_.set( ); + // mcm[ ] = m_; + + + // Begin + + // Special bitsets + std::bitset< NUM_FLAGS > all_contexts; + all_contexts.flip(); + + // Messages: CHANGE_NOT_REPEATABLE, CHANGE_REPEATABLE, DUMMY_CHANGE, CHANGE_COMMIT + std::bitset< NUM_FLAGS > m1; + m1.set(LOGGED_IN); + m1.set(IN_WHITEBOARD); + m1.set(IN_CHATROOM); + m1.set(SYNCHRONIZING_WITH_CHAT); + mcm[CHANGE_NOT_REPEATABLE] = m1; + mcm[CHANGE_REPEATABLE] = m1; + mcm[DUMMY_CHANGE] = m1; + mcm[CHANGE_COMMIT] = m1; + + // Messages: DOCUMENT_BEGIN, DOCUMENT_END + std::bitset< NUM_FLAGS > m4; + m4.set(LOGGED_IN); + m4.set(IN_WHITEBOARD); + m4.set(SYNCHRONIZING_WITH_CHAT); + mcm[DOCUMENT_BEGIN] = m4; + mcm[DOCUMENT_END] = m4; + + // Message: CONNECT_REQUEST_USER + std::bitset< NUM_FLAGS > m5; + m5.set(LOGGED_IN); + mcm[CONNECT_REQUEST_USER] = m5; + + // Message: CONNECT_REQUEST_RESPONSE_USER + std::bitset< NUM_FLAGS > m6; + m6.set(LOGGED_IN); + m6.set(WAITING_FOR_INVITE_RESPONSE); + mcm[CONNECT_REQUEST_RESPONSE_USER] = m6; + + // Message: CHATROOM_SYNCHRONIZE_REQUEST + std::bitset< NUM_FLAGS > m7; + m7.set(LOGGED_IN); + m7.set(IN_CHATROOM); + m7.set(IN_WHITEBOARD); + mcm[CHATROOM_SYNCHRONIZE_REQUEST] = m7; + + // Message: CHATROOM_SYNCHRONIZE_RESPONSE + std::bitset< NUM_FLAGS > m8; + m8.set(LOGGED_IN); + m8.set(WAITING_TO_SYNC_TO_CHAT); + mcm[CHATROOM_SYNCHRONIZE_RESPONSE] = m8; + + // Message: CONNECT_REQUEST_RESPONSE_CHAT + std::bitset< NUM_FLAGS > m9; + m9.set(LOGGED_IN); + m9.set(IN_CHATROOM); + m9.set(IN_WHITEBOARD); + mcm[CONNECT_REQUEST_RESPONSE_CHAT] = m9; + + // Message: CONNECTED_SIGNAL + mcm[CONNECTED_SIGNAL] = all_contexts; + + // Message: DISCONNECTED_FROM_USER_SIGNAL + std::bitset< NUM_FLAGS > m11; + m11.set(LOGGED_IN); + m11.set(IN_WHITEBOARD); + mcm[DISCONNECTED_FROM_USER_SIGNAL] = m11; + + // Messages: CONNECT_REQUEST_REFUSED_BY_PEER, ALREADY_IN_SESSION + std::bitset< NUM_FLAGS > m12; + m12.set(LOGGED_IN); + m12.set(WAITING_FOR_INVITE_RESPONSE); + mcm[CONNECT_REQUEST_REFUSED_BY_PEER] = m12; + mcm[ALREADY_IN_SESSION] = m12; + + // Message: UNSUPPORTED_PROTOCOL_VERSION + std::bitset< NUM_FLAGS > m14; + m14.set(LOGGED_IN); + mcm[UNSUPPORTED_PROTOCOL_VERSION] = m14; +} + +} + +} + +/* + 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:textwidth=99 : diff --git a/src/jabber_whiteboard/message-contexts.h b/src/jabber_whiteboard/message-contexts.h new file mode 100644 index 000000000..49653c693 --- /dev/null +++ b/src/jabber_whiteboard/message-contexts.h @@ -0,0 +1,39 @@ +/** + * Whiteboard session manager + * Inkboard message context definitions + * + * Authors: + * David Yip + * + * Copyright (c) 2005 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifndef __WHITEBOARD_MESSAGE_CONTEXTS_H__ +#define __WHITEBOARD_MESSAGE_CONTEXTS_H__ + +#include "jabber_whiteboard/typedefs.h" + +namespace Inkscape { + +namespace Whiteboard { + +void initialize_received_message_contexts(MessageContextMap& mcm); + +} + +} + +#endif + +/* + 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:textwidth=99 : diff --git a/src/jabber_whiteboard/message-handler.cpp b/src/jabber_whiteboard/message-handler.cpp new file mode 100644 index 000000000..cdcef74b8 --- /dev/null +++ b/src/jabber_whiteboard/message-handler.cpp @@ -0,0 +1,456 @@ +/** + * Whiteboard session manager + * Jabber received message handling + * + * Authors: + * David Yip + * Steven Montgomery, Jonas Collaros (original C version) + * + * Copyright (c) 2004-2005 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +extern "C" { +#include +} + +#include +#include +#include +#include + +#include "jabber_whiteboard/defines.h" +#include "jabber_whiteboard/typedefs.h" +#include "jabber_whiteboard/message-processors.h" +#include "jabber_whiteboard/message-handler.h" +#include "jabber_whiteboard/session-manager.h" +#include "jabber_whiteboard/chat-handler.h" +#include "jabber_whiteboard/buddy-list-manager.h" + +namespace Inkscape { + +namespace Whiteboard { + +bool message_contexts_initialized = false; +MessageContextMap _received_message_contexts; + +MessageHandler::MessageHandler(SessionManager* sm) : _sm(sm) +{ + if (message_contexts_initialized == false) { +// this->_initializeContexts(); + MessageHandler::_initializeContexts(); + } + this->_initializeProcessors(); +} + +MessageHandler::~MessageHandler() +{ + this->_destructProcessors(); +} + +LmHandlerResult +MessageHandler::handle(LmMessage* message, HandlerMode mode) +{ + if (this->_isValidMessage(message)) { + switch(mode) { + case DEFAULT: + return this->_default(message); + case PRESENCE: + return this->_presence(message); + case ERROR: + return this->_error(message); + default: + g_warning("Jabber message handler was asked to process a message of an unhandled type; discarding message."); + return LM_HANDLER_RESULT_REMOVE_MESSAGE; + } + } else { + return LM_HANDLER_RESULT_REMOVE_MESSAGE; + } +} + +bool +MessageHandler::_hasValidReceiveContext(LmMessage* message) +{ + MessageType type = this->_getType(message); + std::bitset< NUM_FLAGS >& status = this->_sm->session_data->status; + + std::string s1 = status.to_string< char, std::char_traits< char >, std::allocator< char > >(); + + + if (type == UNKNOWN) { + // unknown types never have a valid receive context + return false; + } else { + std::bitset< NUM_FLAGS >& recvcontext = _received_message_contexts[type]; + + // TODO: remove this debug block + if ((status & recvcontext).to_ulong() < status.to_ulong()) { + g_warning("Received message in incorrect context (current is not a subset of required); discarding message."); + + std::string s2 = recvcontext.to_string< char, std::char_traits< char >, std::allocator< char > >(); + + + g_warning("current context=%s required context=%s (msgtype %s)", s1.c_str(), s2.c_str(), MessageHandler::ink_type_to_string(type)); + } + + return ((status & recvcontext).to_ulong() >= status.to_ulong()); + } +} + +bool +MessageHandler::_isValidMessage(LmMessage* message) +{ + // Global sanity checks + LmMessageNode* root; + LmMessageNode* protocolver; + LmMessageNode* offline; + LmMessageType mtype; + LmMessageSubType msubtype; + gchar const* tmp; + + Glib::ustring sender; + + + // 0. The message must have a root node. + root = lm_message_get_node(message); + if (root == NULL) { + g_warning("Check 0 failed (message has no root node)"); + return false; + } + + + // 1. The message must be of LM_MESSAGE_TYPE_MESSAGE to continue the sanity checks. + // If it is not, check to see if it is either + // a presence message or an error message. If it is either of these, then automatically + // consider it sane. + // + // FIXME: + // (That is probably a dangerous assumption. We should probably at least validate + // the source for error messages.) + // + // We do not handle IQ stanzas or STREAM messages (yet), and we certainly don't + // handle unknowns. + + mtype = lm_message_get_type(message); + switch(mtype) { + case LM_MESSAGE_TYPE_PRESENCE: + case LM_MESSAGE_TYPE_STREAM_ERROR: + return true; + case LM_MESSAGE_TYPE_IQ: + case LM_MESSAGE_TYPE_STREAM: + case LM_MESSAGE_TYPE_UNKNOWN: + g_warning("Check 1 failed (Loudmouth reported type IQ, STREAM, or UNKNOWN)"); + return false; + case LM_MESSAGE_TYPE_MESSAGE: + break; + } + + // 2. The message must contain the JID of the sender. + tmp = lm_message_node_get_attribute(root, MESSAGE_FROM); + + if (tmp == NULL) { + g_warning("Check 2 failed (no sender attribute present)"); + return false; + } else { + sender = tmp; + } + + // 3. We do not yet handle messages from offline storage, so ensure that this is not + // such a message. + offline = lm_message_node_get_child(root, "x"); + if (offline != NULL) { + if (strcmp(lm_message_node_get_value(offline), "Offline Storage") == 0) { + return false; + } + } + + // 4. If this is a regular chat message... + msubtype = lm_message_get_sub_type(message); + + if (msubtype == LM_MESSAGE_SUB_TYPE_CHAT) { + // 4a. A protocol version node must be present. + protocolver = lm_message_node_get_child(root, MESSAGE_PROTOCOL_VER); + if (protocolver == NULL) { + g_warning("Check 4a failed (no protocol attribute in chat message)"); + return false; + } else { + tmp = lm_message_node_get_value(protocolver); + if (tmp == NULL) { + g_warning("Check 4a failed (no protocol attribute in chat message)"); + return false; + } + } + + // 5a. The protocol version must be supported. + if (atoi(tmp) > HIGHEST_SUPPORTED) { + g_warning("Check 5a failed (received a message with protocol version %s, but version %s is not supported)", tmp, tmp); + return false; + } + + // ...otherwise, if this is a groupchat message, we may not have a protocol version + // (since it may be communication from the Jabber server). In this case, we have a + // different set of sanity checks. + } else if (msubtype == LM_MESSAGE_SUB_TYPE_GROUPCHAT) { + // 4b. + // In a chatroom situation, we need to ensure that we don't process messages that + // originated from us. + int cutoff = sender.find_last_of('/') + 1; + if (sender.substr(cutoff, sender.length()) == this->_sm->session_data->chat_handle) { + return false; + } + // TODO: 6b. If the message is NOT from the Jabber server, then check the protocol version. + } + + // If all tests pass, then the message is at least valid. + // Correct context has not yet been established, however; that is the job of the default handler + // and hasValidReceiveContext. + + return true; +} + +MessageType +MessageHandler::_getType(LmMessage* message) +{ + LmMessageNode* root; + LmMessageNode* typenode; + + root = lm_message_get_node(message); + if (root != NULL) { + typenode = lm_message_node_get_child(root, MESSAGE_TYPE); + if (typenode != NULL) { + return static_cast< MessageType >(atoi(lm_message_node_get_value(typenode))); + } + } + return UNKNOWN; +} + +JabberMessage +MessageHandler::_extractData(LmMessage* message) +{ + + JabberMessage jm(message); + LmMessageNode* root; + LmMessageNode* sequence; + LmMessageNode* body; + gchar const* tmp; + + root = lm_message_get_node(message); + + if (root != NULL) { + sequence = lm_message_node_get_child(root, MESSAGE_SEQNUM); + body = lm_message_node_get_child(root, MESSAGE_BODY); + + jm.sender = lm_message_node_get_attribute(root, MESSAGE_FROM); + + if (sequence) { + tmp = lm_message_node_get_value(sequence); + if (tmp != NULL) { + jm.sequence = atoi(tmp); + } + } + + if (body) { + tmp = lm_message_node_get_value(body); + if (tmp != NULL) { + jm.body = tmp; + } + } + + } else { + jm.sequence = 0; + jm.sender = ""; + jm.body = ""; + } + + return jm; +} + +LmHandlerResult +MessageHandler::_default(LmMessage* message) +{ + std::bitset< NUM_FLAGS >& status = this->_sm->session_data->status; + + // Pass groupchat messages with no Inkboard type off to the chat message handler + if (this->_getType(message) == UNKNOWN) { + if (lm_message_get_sub_type(message) == LM_MESSAGE_SUB_TYPE_GROUPCHAT) { + if (status[IN_CHATROOM] || status[CONNECTING_TO_CHAT]) { + return this->_sm->chat_handler()->parse(message); + } + } else { + return LM_HANDLER_RESULT_REMOVE_MESSAGE; + } + } + + if (this->_hasValidReceiveContext(message)) { + // Extract message data + JabberMessage msg = this->_extractData(message); + MessageType type = this->_getType(message); + + // Call message handler and return instruction value to Loudmouth + + return (*this->_received_message_processors[type])(type, msg); + } else { + g_warning("Default message handler received message in invalid receive context; discarding message."); + return LM_HANDLER_RESULT_REMOVE_MESSAGE; + } +} + +LmHandlerResult +MessageHandler::_presence(LmMessage* message) +{ + LmMessageNode* root; + LmMessageSubType msubtype; + gchar const* tmp; + std::string sender; + + SessionData* sd = this->_sm->session_data; + std::bitset< NUM_FLAGS >& status = this->_sm->session_data->status; + + root = lm_message_get_node(message); + if (root == NULL) { + return LM_HANDLER_RESULT_REMOVE_MESSAGE; + } + + tmp = lm_message_node_get_attribute(root, MESSAGE_FROM); + if (tmp == NULL) { + return LM_HANDLER_RESULT_REMOVE_MESSAGE; + } else { + sender = tmp; + } + + msubtype = lm_message_get_sub_type(message); + if (status[CONNECTING_TO_CHAT] || status[IN_CHATROOM]) { + this->_sm->chat_handler()->parse(message); + } else { + switch(msubtype) { + case LM_MESSAGE_SUB_TYPE_UNAVAILABLE: + // remove buddy from online roster + sd->buddyList.erase(sender); + + // if this buddy is in a 1-1 session with us, we need to exit + // the whiteboard + if (status[IN_WHITEBOARD] && !(status[IN_CHATROOM]) && strcasecmp(sender.c_str(), sd->recipient) == 0) { + status.set(IN_WHITEBOARD, 0); + this->_sm->userDisconnectedFromWhiteboard(sender); + this->_sm->closeSession(); + } + return LM_HANDLER_RESULT_REMOVE_MESSAGE; + + case LM_MESSAGE_SUB_TYPE_AVAILABLE: + // we don't want to insert an entry into a buddy list + // if it's our own presence + if (sender != lm_connection_get_jid(this->_sm->session_data->connection)) { + sd->buddyList.insert(sender); + } + return LM_HANDLER_RESULT_REMOVE_MESSAGE; + default: + break; + } + } + return LM_HANDLER_RESULT_REMOVE_MESSAGE; +} + +LmHandlerResult +MessageHandler::_error(LmMessage* message) +{ + LmMessageNode* root; + LmMessageSubType msubtype; + + root = lm_message_get_node(message); + if (root != NULL) { + msubtype = lm_message_get_sub_type(message); + if (msubtype == LM_MESSAGE_SUB_TYPE_ERROR) { + gchar* error = g_strdup(lm_message_node_get_value(root)); + g_warning(error); + + // TODO: more robust error handling code + this->_sm->disconnectFromDocument(); + this->_sm->disconnectFromServer(); + this->_sm->connectionError(error); + } + } + + return LM_HANDLER_RESULT_REMOVE_MESSAGE; +} + +void +MessageHandler::_initializeContexts() +{ + initialize_received_message_contexts(_received_message_contexts); + message_contexts_initialized = true; +} + +void +MessageHandler::_initializeProcessors() +{ + initialize_received_message_processors(this->_sm, this->_received_message_processors); +} + +void +MessageHandler::_destructProcessors() +{ + destroy_received_message_processors(this->_received_message_processors); +} + + +char const* +MessageHandler::ink_type_to_string(gint ink_type) { + switch(ink_type) { + case Inkscape::Whiteboard::CHANGE_NOT_REPEATABLE: + return "CHANGE_NOT_REPEATABLE"; + case Inkscape::Whiteboard::CHANGE_REPEATABLE: + return "CHANGE_REPEATABLE"; + case Inkscape::Whiteboard::DUMMY_CHANGE: + return "DUMMY_CHANGE"; + case Inkscape::Whiteboard::CHANGE_COMMIT: + return "CHANGE_COMMIT"; + case Inkscape::Whiteboard::CONNECT_REQUEST_USER: + return "CONNECT_REQUEST_USER"; + case Inkscape::Whiteboard::CONNECT_REQUEST_RESPONSE_USER: + return "CONNECT_REQUEST_RESPONSE_USER"; + case Inkscape::Whiteboard::CONNECT_REQUEST_RESPONSE_CHAT: + return "CONNECT_REQUEST_RESPONSE_CHAT"; + case Inkscape::Whiteboard::DOCUMENT_SENDER_REQUEST: + return "DOCUMENT_SENDER_REQUEST"; + case Inkscape::Whiteboard::DOCUMENT_SENDER_REQUEST_RESPONSE: + return "DOCUMENT_SENDER_REQUEST_RESPONSE"; + case Inkscape::Whiteboard::DOCUMENT_REQUEST: + return "DOCUMENT_REQUEST"; + case Inkscape::Whiteboard::DOCUMENT_BEGIN: + return "DOCUMENT_BEGIN"; + case Inkscape::Whiteboard::DOCUMENT_END: + return "DOCUMENT_END"; + case Inkscape::Whiteboard::CONNECTED_SIGNAL: + return "CONNECTED_SIGNAL"; + case Inkscape::Whiteboard::DISCONNECTED_FROM_USER_SIGNAL: + return "DISCONNECTED_FROM_USER_SIGNAL"; + case Inkscape::Whiteboard::CONNECT_REQUEST_REFUSED_BY_PEER: + return "CONNECT_REQUEST_REFUSED_BY_PEER"; + case Inkscape::Whiteboard::UNSUPPORTED_PROTOCOL_VERSION: + return "UNSUPPORTED_PROTOCOL_VERSION"; + case Inkscape::Whiteboard::CHATROOM_SYNCHRONIZE_REQUEST: + return "CHATROOM_SYNCHRONIZE_REQUEST"; + case Inkscape::Whiteboard::CHATROOM_SYNCHRONIZE_RESPONSE: + return "CHATROOM_SYNCHRONIZE_RESPONSE"; + case Inkscape::Whiteboard::ALREADY_IN_SESSION: + return "ALREADY_IN_SESSION"; + default: + return "UNKNOWN"; + } +} + +} + +} + +/* + 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:textwidth=99 : diff --git a/src/jabber_whiteboard/message-handler.h b/src/jabber_whiteboard/message-handler.h new file mode 100644 index 000000000..700665f74 --- /dev/null +++ b/src/jabber_whiteboard/message-handler.h @@ -0,0 +1,88 @@ +/** + * Whiteboard session manager + * Jabber message handling + * + * Authors: + * David Yip + * Steven Montgomery, Jonas Collaros (original C version) + * + * Copyright (c) 2004-2005 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifndef __WHITEBOARD_MESSAGE_HANDLER_H__ +#define __WHITEBOARD_MESSAGE_HANDLER_H__ + +extern "C" { +#include +} + +#include "jabber_whiteboard/defines.h" +#include "jabber_whiteboard/typedefs.h" +#include "jabber_whiteboard/message-contexts.h" + +namespace Inkscape { + +namespace Whiteboard { + +struct JabberMessage; +class SessionManager; + +/** + * Handles received Jabber messages. + */ +class MessageHandler { +public: + MessageHandler(SessionManager* sm); + ~MessageHandler(); + LmHandlerResult handle(LmMessage* message, HandlerMode mode); + + bool _hasValidReceiveContext(LmMessage* message); + + static char const* ink_type_to_string(gint ink_type); + +private: + static void _initializeContexts(); + + void _initializeProcessors(); + void _destructProcessors(); + + // Utilities + bool _isValidMessage(LmMessage* message); + MessageType _getType(LmMessage* message); + struct JabberMessage _extractData(LmMessage* message); + + + // Individual message handlers + LmHandlerResult _default(LmMessage* message); + LmHandlerResult _error(LmMessage* message); + LmHandlerResult _presence(LmMessage* message); + + // Message processors map +// MessageContextMap _received_message_contexts; + MessageProcessorMap _received_message_processors; + + SessionManager* _sm; + + // noncopyable, nonassignable + MessageHandler(MessageHandler const&); + MessageHandler& operator=(MessageHandler const&); +}; + +} + +} + +#endif + +/* + 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:textwidth=99 : diff --git a/src/jabber_whiteboard/message-node.h b/src/jabber_whiteboard/message-node.h new file mode 100644 index 000000000..5e1b6a674 --- /dev/null +++ b/src/jabber_whiteboard/message-node.h @@ -0,0 +1,134 @@ +/** + * Whiteboard message queue and queue handler functions + * Node for storing messages in message queues + * + * Authors: + * David Yip + * + * Copyright (c) 2005 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifndef __WHITEBOARD_MESSAGE_NODE_H__ +#define __WHITEBOARD_MESSAGE_NODE_H__ + +#include +#include + +#include "gc-managed.h" +#include "gc-anchored.h" +#include "gc-finalized.h" + +namespace Inkscape { + +namespace Whiteboard { + +/** + * Encapsulates a document change message received by or sent to an Inkboard client. + * + * Received messages that end up in a MessageNode are of the following types: + *
    + *
  1. CHANGE_REPEATABLE
  2. + *
  3. CHANGE_NOT_REPEATABLE
  4. + *
  5. CHANGE_COMMIT
  6. + *
  7. DOCUMENT_BEGIN
  8. + *
  9. DOCUMENT_END
  10. + *
  11. DUMMY_CHANGE
  12. + *
+ * + * This class is intended for use in MessageQueues, although it could potentially + * see use outside of that context. + * + * \see Inkscape::Whiteboard::MessageQueue + */ +class MessageNode : public GC::Managed<>, public GC::Anchored, public GC::Finalized { +public: + /** + * Constructor. + * + * \param seq The sequence number of the message being encapsulated. + * \param sender The sender of the message. + * \param recip The intended recipient. + * \param message_body The body of the message. + * \param type The type of the message. + * \param chatroom Whether or not this message is to be sent to / was received from a chatroom. + */ + MessageNode(unsigned int seq, std::string sender, std::string recip, Glib::ustring const& message_body, MessageType type, bool document, bool chatroom) : + _seq(seq), _type(type), _message(message_body), _document(document), _chatroom(chatroom) + { + this->_sender = sender; + this->_recipient = recip; + } + + ~MessageNode() + { +// g_log(NULL, G_LOG_LEVEL_DEBUG, "MessageNode destructor"); + /* + if (this->_message) { + delete this->_message; + } + */ + } + + unsigned int sequence() + { + return this->_seq; + } + + MessageType type() + { + return this->_type; + } + + bool chatroom() + { + return this->_chatroom; + } + + bool document() + { + return this->_document; + } + + std::string recipient() + { + return this->_recipient; + } + + std::string sender() + { + return this->_sender; + } + + Glib::ustring const& message() + { + return this->_message; + } + +private: + unsigned int _seq; + std::string _sender; + std::string _recipient; + MessageType _type; + Glib::ustring _message; + bool _document; + bool _chatroom; +}; + +} + +} + +#endif + +/* + 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:textwidth=99 : diff --git a/src/jabber_whiteboard/message-processors.cpp b/src/jabber_whiteboard/message-processors.cpp new file mode 100644 index 000000000..bd24f7ad8 --- /dev/null +++ b/src/jabber_whiteboard/message-processors.cpp @@ -0,0 +1,330 @@ +/** + * Whiteboard session manager + * Jabber received message processors + * + * Authors: + * David Yip + * + * Copyright (c) 2005 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +extern "C" { +#include +} + +#include + +#include "xml/session.h" +#include "xml/document.h" + +#include "desktop-handles.h" +#include "document.h" +#include "message-stack.h" + +#include "jabber_whiteboard/undo-stack-observer.h" +#include "jabber_whiteboard/session-manager.h" +#include "jabber_whiteboard/message-node.h" +#include "jabber_whiteboard/message-queue.h" +#include "jabber_whiteboard/message-processors.h" +#include "jabber_whiteboard/typedefs.h" + +namespace Inkscape { + +namespace Whiteboard { + +// Message processors are here! + +// TODO: Remove unnecessary status checks from processors -- +// we do all of that in MessageHandler::_hasValidReceiveContext + +// ********************************************************************* +// ChangeHandler begin +// ********************************************************************* + +/** + * MessageProcessor for document change and event commit messages. + */ +struct ChangeHandler : public MessageProcessor { +public: + ~ChangeHandler() + { + + } + + ChangeHandler(SessionManager* sm) : MessageProcessor(sm) + { + + } + + LmHandlerResult + operator()(MessageType mode, JabberMessage& p) + { + MessageNode* msgNode; + bool chatroom = this->_sm->session_data->status[IN_CHATROOM]; + + ReceiveMessageQueue* rmq = this->_sm->session_data->receive_queues[p.sender]; + + if (rmq != NULL) { + switch (mode) { + case CHANGE_REPEATABLE: + case CHANGE_NOT_REPEATABLE: + case DOCUMENT_BEGIN: + msgNode = new MessageNode(p.sequence, p.sender, "", p.body, mode, false, chatroom); + rmq->insert(msgNode); + Inkscape::GC::release(msgNode); + break; + case DOCUMENT_END: + this->_sm->session_data->recipients_committed_queue.push_back(p.sender); + msgNode = new MessageNode(p.sequence, p.sender, "", p.body, mode, false, chatroom); + rmq->insert(msgNode); + Inkscape::GC::release(msgNode); + break; + case CHANGE_COMMIT: + this->_sm->session_data->recipients_committed_queue.push_back(p.sender); + msgNode = new MessageNode(p.sequence, p.sender, "", p.body, CHANGE_COMMIT, false, chatroom); + rmq->insert(msgNode); + Inkscape::GC::release(msgNode); + break; + case DUMMY_CHANGE: + default: + break; + } + } else { + g_warning("Received message from unknown sender %s", p.sender.c_str()); + } + + return LM_HANDLER_RESULT_REMOVE_MESSAGE; + } +}; +// ********************************************************************* +// ChangeHandler end +// ********************************************************************* + + +// ********************************************************************* +// ConnectRequestHandler begin +// ********************************************************************* +/** + * MessageProcessor for connection request messages. + */ +struct ConnectRequestHandler : public MessageProcessor { +public: + ~ConnectRequestHandler() + { + + } + + ConnectRequestHandler(SessionManager* sm) : MessageProcessor(sm) + { + + } + + LmHandlerResult + operator()(MessageType mode, JabberMessage& m) + { + std::bitset< NUM_FLAGS >& status = this->_sm->session_data->status; + switch(mode) { + case CONNECT_REQUEST_USER: + this->_sm->receiveConnectRequest(m.sender.c_str()); + break; + case CONNECT_REQUEST_RESPONSE_USER: + if (m.sequence == 0) { + this->_sm->receiveConnectRequestResponse(DECLINE_INVITATION, m.sender); + } else { // FIXME: this has got to be buggy... + this->_sm->setRecipient(m.sender.c_str()); + this->_sm->receiveConnectRequestResponse(ACCEPT_INVITATION, m.sender); + } + break; + case Inkscape::Whiteboard::CONNECTED_SIGNAL: + if (!status[IN_CHATROOM] && !status[CONNECTING_TO_CHAT] && !status[SYNCHRONIZING_WITH_CHAT] && !status[WAITING_TO_SYNC_TO_CHAT]) { + this->_sm->userConnectedToWhiteboard(m.sender.c_str()); + this->_sm->setRecipient(m.sender.c_str()); + } else { + SP_DT_MSGSTACK(this->_sm->desktop())->flashF(Inkscape::INFORMATION_MESSAGE, _("%s has joined the chatroom."), m.sender.c_str()); + } + break; + default: + break; + } + return LM_HANDLER_RESULT_REMOVE_MESSAGE; + } +}; +// ********************************************************************* +// ConnectRequestHandler end +// ********************************************************************* + + + + +// ********************************************************************* +// ConnectErrorHandler begin +// ********************************************************************* +/** + * MessageProcessor for connection error messages. + */ +struct ConnectErrorHandler : public MessageProcessor { +public: + ~ConnectErrorHandler() + { + + } + + ConnectErrorHandler(SessionManager* sm) : MessageProcessor(sm) + { + + } + + LmHandlerResult + operator()(MessageType mode, JabberMessage& m) + { + switch(mode) { + case CONNECT_REQUEST_REFUSED_BY_PEER: + if (this->_sm->session_data->status[WAITING_FOR_INVITE_RESPONSE]) { + this->_sm->receiveConnectRequestResponse(DECLINE_INVITATION, m.sender); + } + break; + case Inkscape::Whiteboard::ALREADY_IN_SESSION: + if (this->_sm->session_data->status[WAITING_FOR_INVITE_RESPONSE]) { + this->_sm->receiveConnectRequestResponse(PEER_ALREADY_IN_SESSION, m.sender); + } + break; + case Inkscape::Whiteboard::DISCONNECTED_FROM_USER_SIGNAL: + if (!this->_sm->session_data->status[IN_CHATROOM]) { + this->_sm->closeSession(); + this->_sm->userDisconnectedFromWhiteboard(m.sender.c_str()); + } + break; + default: + break; + } + return LM_HANDLER_RESULT_REMOVE_MESSAGE; + } +}; +// ********************************************************************* +// ConnectErrorHandler end +// ********************************************************************* + + + + +// ********************************************************************* +// ChatSynchronizeHandler begin +// ********************************************************************* +/** + * MessageProcessor for messages specific to chatroom synchronization. + */ +struct ChatSynchronizeHandler : public MessageProcessor { +public: + ~ChatSynchronizeHandler() + { + + } + + ChatSynchronizeHandler(SessionManager* sm) : MessageProcessor(sm) + { + + } + + LmHandlerResult + operator()(MessageType mode, JabberMessage& m) + { + switch(mode) { + case CONNECT_REQUEST_RESPONSE_CHAT: + this->_sm->receiveConnectRequestResponseChat(m.sender.c_str()); + break; + case CHATROOM_SYNCHRONIZE_REQUEST: + if (this->_sm->session_data->status[IN_CHATROOM] && this->_sm->session_data->status[IN_WHITEBOARD]) { + // Send response. Everyone in the chatroom will do this, + // but the client will accept only one response. + // The response is sent privately to the client + // + this->_sm->sendMessage(CHATROOM_SYNCHRONIZE_RESPONSE, this->_sm->session_data->sequence_number, "", m.sender.c_str(), false); + } + break; + case CHATROOM_SYNCHRONIZE_RESPONSE: + if (m.sequence != 0) { + // Set sequence number + this->_sm->session_data->sequence_number = m.sequence; + + // Set status flags + this->_sm->session_data->status.set(WAITING_TO_SYNC_TO_CHAT, 0); + this->_sm->session_data->status.set(SYNCHRONIZING_WITH_CHAT, 1); + + // Send document synchronization request + this->_sm->clearDocument(); + this->_sm->setupInkscapeInterface(); + this->_sm->sendMessage(CONNECT_REQUEST_RESPONSE_CHAT, m.sequence, "", m.sender.c_str(), false); + } else { + this->_sm->sendMessage(CHATROOM_SYNCHRONIZE_REQUEST, 0, "", this->_sm->session_data->recipient, true); + } + break; + default: + break; + } + return LM_HANDLER_RESULT_REMOVE_MESSAGE; + } +}; +// ********************************************************************* +// ChatSynchronizeHandler end +// ********************************************************************* + + + + +// ********************************************************************* +// Initializer +// ********************************************************************* +void +initialize_received_message_processors(SessionManager* sm, MessageProcessorMap& mpm) +{ + MessageProcessor* ch = new ChangeHandler(sm); + MessageProcessor* crh = new ConnectRequestHandler(sm); + MessageProcessor* ceh = new ConnectErrorHandler(sm); + MessageProcessor* csh = new ChatSynchronizeHandler(sm); + + mpm[CHANGE_REPEATABLE] = ch; + mpm[CHANGE_NOT_REPEATABLE] = ch; + mpm[DUMMY_CHANGE] = ch; + mpm[CHANGE_COMMIT] = ch; + mpm[DOCUMENT_BEGIN] = ch; + mpm[DOCUMENT_END] = ch; + + mpm[CONNECT_REQUEST_USER] = crh; + mpm[CONNECT_REQUEST_RESPONSE_USER] = crh; + mpm[CONNECTED_SIGNAL] = crh; + + mpm[CONNECT_REQUEST_REFUSED_BY_PEER] = ceh; + mpm[ALREADY_IN_SESSION] = ceh; + mpm[DISCONNECTED_FROM_USER_SIGNAL] = ceh; + + mpm[CONNECT_REQUEST_RESPONSE_CHAT] = csh; + mpm[CHATROOM_SYNCHRONIZE_REQUEST] = csh; + mpm[CHATROOM_SYNCHRONIZE_RESPONSE] = csh; +} + +/* + * This function is provided solely for convenience and style. You can, of course, + * delete every MessageProcessor in the map with your own loop. + */ +void +destroy_received_message_processors(MessageProcessorMap& mpm) +{ + mpm.clear(); +} + +} + +} + +/* + 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:textwidth=99 : diff --git a/src/jabber_whiteboard/message-processors.h b/src/jabber_whiteboard/message-processors.h new file mode 100644 index 000000000..8b0887444 --- /dev/null +++ b/src/jabber_whiteboard/message-processors.h @@ -0,0 +1,176 @@ +/** + * Whiteboard session manager + * Jabber received message processors + * + * Authors: + * David Yip + * + * Copyright (c) 2005 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifndef __WHITEBOARD_MESSAGE_PROCESSORS_H__ +#define __WHITEBOARD_MESSAGE_PROCESSORS_H__ + +#include "jabber_whiteboard/typedefs.h" + +#include "gc-managed.h" +#include "gc-finalized.h" + +namespace Inkscape { + +namespace Whiteboard { + +class SessionManager; + +// Processor forward declarations +struct ChangeHandler; +struct DocumentSignalHandler; +struct ConnectRequestHandler; +struct ConnectErrorHandler; +struct ChatSynchronizeHandler; + +/** + * Encapsulates a pointer to an LmMessage along with additional information, + * such as the message's sequence number, its sender, and its body. + * + * All of the above data members can be extracted directly from the LmMessage; + * they are provided for convenience. + */ +struct JabberMessage { +public: + /** + * Constructor. + * + * The constructor attaches a reference to the LmMessage to prevent Loudmouth from + * freeing the message. + */ + JabberMessage(LmMessage* m) : message(m), sequence(0) + { + lm_message_ref(this->message); + } + + /** + * Destructor. + * + * The destructor deletes a reference to the LmMessage, which, assuming all other + * references have been deleted, will allow Loudmouth to free the LmMessage object. + */ + ~JabberMessage() + { + lm_message_unref(this->message); + } + + + // TODO: Hide, or, better, remove this. There's no real reason why it should be here, + // and it allows for the possibility of reference count-induced memory leaks. + /** + * Pointer to original Loudmouth message object. + */ + LmMessage* message; + + /** + * Sequence number of this message. + */ + unsigned int sequence; + + /** + * The JID of this message's sender. + */ + std::string sender; + + /** + * The body of this message. + */ + Glib::ustring body; + +private: + // noncopyable, nonassignable (for now, anyway...) +// JabberMessage(JabberMessage const&); +// JabberMessage& operator=(JabberMessage const&); +}; + +/** + * A MessageProcessor is a functor that is associated with one or more Inkboard message types. + * When an Inkboard client receives an Inkboard message, it passes it to the appropriate + * MessageProcessor. + */ +struct MessageProcessor : public GC::Managed<>, public GC::Finalized { +public: + virtual ~MessageProcessor() + { + + } + + /** + * Functor action operator. + * + * \param mode The type of the message being processed. + * \param m A reference to the JabberMessage encapsulating the received Jabber message. + */ + virtual LmHandlerResult operator()(MessageType mode, JabberMessage& m) = 0; + + /** + * Constructor. + * + * \param sm The SessionManager with which a MessageProcessor instance is associated. + */ + MessageProcessor(SessionManager* sm) : _sm(sm) { } +protected: + /** + * Pointer to the associated SessionManager object. + */ + SessionManager *_sm; + +private: + // noncopyable, nonassignable + MessageProcessor(MessageProcessor const&); + MessageProcessor& operator=(MessageProcessor const&); +}; + +/* +struct ProcessorShell : public GC::Managed<>, public std::binary_function< MessageType, JabberMessage, LmHandlerResult > { +public: + ProcessorShell(MessageProcessor* mpm) : _mpm(mpm) { } + + LmHandlerResult operator()(MessageType type, JabberMessage msg) + { + return (*this->_mpm)(type, msg); + } +private: + MessageProcessor* _mpm; +}; +*/ + +/** + * Initialize the message -> MessageProcessor map. + * + * \param sm The SessionManager with which all created MessageProcessors should be associated with. + * \param mpm Reference to the MessageProcessorMap to initialize. + */ +void initialize_received_message_processors(SessionManager* sm, MessageProcessorMap& mpm); + +/** + * Clean up the message -> MessageProcessor map. + * + * \param mpm Reference to the MessageProcessorMap to clean up. + */ +void destroy_received_message_processors(MessageProcessorMap& mpm); + +} + +} + +#endif + +/* + 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:textwidth=99 : diff --git a/src/jabber_whiteboard/message-queue.cpp b/src/jabber_whiteboard/message-queue.cpp new file mode 100644 index 000000000..89c20d66f --- /dev/null +++ b/src/jabber_whiteboard/message-queue.cpp @@ -0,0 +1,138 @@ +/** + * Whiteboard message queue + * + * Authors: + * David Yip + * + * Copyright (c) 2005 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include + +#include "desktop-handles.h" +#include "message-stack.h" + +#include "jabber_whiteboard/session-manager.h" +#include "jabber_whiteboard/message-node.h" +#include "jabber_whiteboard/message-queue.h" + +namespace Inkscape { + +namespace Whiteboard { + +MessageQueue::MessageQueue(SessionManager* sm) : _sm(sm) +{ + +} + +MessageQueue::~MessageQueue() +{ + +} + +MessageNode* +MessageQueue::first() +{ + return this->_queue.front(); +} + +void +MessageQueue::popFront() +{ + this->_queue.pop_front(); +// g_log(NULL, G_LOG_LEVEL_DEBUG, "Removed element, queue size (for %s): %u", lm_connection_get_jid(this->_sm->session_data->connection), this->_queue.size()); +} + +unsigned int +MessageQueue::size() +{ + return this->_queue.size(); +} + +bool +MessageQueue::empty() +{ + return this->_queue.empty(); +} + +void +MessageQueue::clear() +{ + this->_queue.clear(); +} + +ReceiveMessageQueue::ReceiveMessageQueue(SessionManager* sm) : MessageQueue(sm), _latest(0) +{ + +} + +void +ReceiveMessageQueue::insert(MessageNode* msg) +{ + // Check to see if the incoming message has a sequence number + // lower than the sequence number of the latest message processed + // by this message's sender. If it does, drop the message and produce + // a warning. + if (msg->sequence() < this->_latest) { + g_warning("Received late message (message sequence number is %u, but latest processed message had sequence number %u). Discarding message; session may be desynchronized.", msg->sequence(), this->_latest); + return; + } + + // Otherwise, it is safe to insert this message. +// Inkscape::GC::anchor(msg); + this->_queue.push_back(msg); + SP_DT_MSGSTACK(this->_sm->desktop())->flashF(Inkscape::NORMAL_MESSAGE, + ngettext("%u change in receive queue.", + "%u changes in receive queue.", + this->_queue.size()), + this->_queue.size()); +// g_log(NULL, G_LOG_LEVEL_DEBUG, "Receive queue size (for %s): %u", lm_connection_get_jid(this->_sm->session_data->connection), this->_queue.size()); +} + +void +ReceiveMessageQueue::insertDeferred(MessageNode* msg) +{ + this->_deferred.push_back(msg); +} + +void +ReceiveMessageQueue::setLatestProcessedPacket(unsigned int seq) +{ + this->_latest = seq; +} + +SendMessageQueue::SendMessageQueue(SessionManager* sm) : MessageQueue(sm) +{ + +} + +void +SendMessageQueue::insert(MessageNode* msg) +{ +// Inkscape::GC::anchor(msg); + this->_queue.push_back(msg); + SP_DT_MSGSTACK(this->_sm->desktop())->flashF(Inkscape::NORMAL_MESSAGE, + ngettext("%u change in send queue.", + "%u changes in send queue.", + this->_queue.size()), + this->_queue.size()); +// g_log(NULL, G_LOG_LEVEL_DEBUG, "Send queue size (for %s): %u", lm_connection_get_jid(this->_sm->session_data->connection), this->_queue.size()); +} + +} + +} + + +/* + 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:textwidth=99 : diff --git a/src/jabber_whiteboard/message-queue.h b/src/jabber_whiteboard/message-queue.h new file mode 100644 index 000000000..e607ed81b --- /dev/null +++ b/src/jabber_whiteboard/message-queue.h @@ -0,0 +1,177 @@ +/** + * Whiteboard message queue + * + * Authors: + * David Yip + * + * Copyright (c) 2005 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifndef __WHITEBOARD_MESSAGE_QUEUE_H__ +#define __WHITEBOARD_MESSAGE_QUEUE_H__ + +#include +#include + +#include "gc-alloc.h" + +#include "gc-managed.h" + +#include "util/list-container.h" + +namespace Inkscape { + +namespace Whiteboard { + +class SessionManager; +class MessageNode; + +/// Definition of the basic message node queue +typedef std::list< MessageNode*, GC::Alloc< MessageNode*, GC::MANUAL > > MessageQueueBuffer; + +/** + * MessageQueue interface. + * + * A message queue is used to queue up document change messages for sending and receiving. + * + * Message queues exist to allow us to send/process messages at a given rate rather than + * immediately: this allows us to avoid flooding Jabber servers and clients. + * + * Only one message queue should be created per sender. Message queues store MessageNodes. + * + * \see Inkscape::Whiteboard::MessageNode + */ +class MessageQueue { +public: + /** + * Constructor. + * + * \param sm The SessionManager to associate this MessageQueue with. + */ + MessageQueue(SessionManager *sm); + virtual ~MessageQueue(); + + /** + * Retrieve the MessageNode at the front of the queue. + */ + MessageNode* first(); + + /** + * Remove the element at the front of the queue. + */ + void popFront(); + + /** + * Get the size of the queue. + * + * \return The size of the queue. + */ + unsigned int size(); + + /** + * Returns whether or not the queue is empty. + * + * \return Whether or not the queue is empty. + */ + bool empty(); + + /** + * Clear the queue. + */ + void clear(); + + /** + * The insertion method. The insertion procedure must be defined + * by a subclass. + * + * \param msg The MessageNode to insert. + */ + virtual void insert(MessageNode* msg) = 0; + +protected: + /** + * Implementation of the queue. + */ + MessageQueueBuffer _queue; + + /** + * Pointer to SessionManager. + */ + SessionManager* _sm; +}; + + +/** + * MessageQueue subclass designed to queue up received messages. + * Received messages are dispatched for processing on a periodic basis by a timeout. + * + * \see Inkscape::Whiteboard::Callbacks::dispatchReceiveQueue + */ +class ReceiveMessageQueue : public MessageQueue, public GC::Managed<> { +public: + ReceiveMessageQueue(SessionManager* sm); + + /** + * Insert a message into the queue. + * Late messages (out-of-sequence messages) will be discarded. + * + * \param msg The message node to insert. + */ + void insert(MessageNode* msg); + + /** + * Insert a message into the deferred queue. + * The deferred message queue is used for messages that are not discarded, + * but cannot yet be processed due to missing dependencies. + * + * \param msg The message node to insert. + */ + void insertDeferred(MessageNode* msg); + + /** + * Update the latest processed packet count for this message queue. + * + * \param seq The sequence number of the latest processed packet. + */ + void setLatestProcessedPacket(unsigned int seq); +private: + MessageQueueBuffer _deferred; + unsigned int _latest; +}; + +/** + * MessageQueue subclass designed to queue up messages for sending. + * Messages in this queue are dispatched on a periodic basis by a timeout. + * + * \see Inkscape::Whiteboard::Callbacks::dispatchSendQueue + */ +class SendMessageQueue : public MessageQueue { +public: + SendMessageQueue(SessionManager* sm); + + /** + * Insert a message into the queue. + * + * \param msg The message node to insert. + */ + void insert(MessageNode* msg); +}; + +} + +} + +#endif + +/* + 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:textwidth=99 : diff --git a/src/jabber_whiteboard/message-tags.cpp b/src/jabber_whiteboard/message-tags.cpp new file mode 100644 index 000000000..a46c27356 --- /dev/null +++ b/src/jabber_whiteboard/message-tags.cpp @@ -0,0 +1,67 @@ +/** + * Whiteboard session manager + * Message tags + * + * Authors: + * David Yip + * + * Copyright (c) 2005 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "jabber_whiteboard/message-tags.h" + +namespace Inkscape { + +namespace Whiteboard { + +const char* MESSAGE_CHANGE = "inkboard:change"; +const char* MESSAGE_NEWOBJ = "inkboard:new"; +const char* MESSAGE_DELETE = "inkboard:delete"; +const char* MESSAGE_DOCUMENT = "inkboard:document"; +const char* MESSAGE_NODECONTENT = "inkboard:node-content"; +const char* MESSAGE_ORDERCHANGE = "inkboard:order-change"; +const char* MESSAGE_COMMIT = "inkboard:commit"; +const char* MESSAGE_UNDO = "inkboard:undo"; +const char* MESSAGE_REDO = "inkboard:redo"; +const char* MESSAGE_DOCBEGIN = "inkboard:document-begin"; +const char* MESSAGE_DOCEND = "inkboard:document-end"; +const char* MESSAGE_OBJKEY = "objid"; +const char* MESSAGE_ID = "id"; +const char* MESSAGE_KEY = "key"; +const char* MESSAGE_OLDVAL = "old"; +const char* MESSAGE_NEWVAL = "new"; +const char* MESSAGE_NAME = "name"; +const char* MESSAGE_ISINTERACTIVE = "interactive"; +const char* MESSAGE_DATA = "data"; +const char* MESSAGE_PARENT = "parent"; +const char* MESSAGE_CHILD = "child"; +const char* MESSAGE_REF = "ref"; +const char* MESSAGE_CONTENT = "content"; +const char* MESSAGE_REPEATABLE = "repeatable"; +const char* MESSAGE_CHATROOM = "chatroom"; + +const char* MESSAGE_TYPE = "inkboard-type"; +const char* MESSAGE_NODETYPE = "node-type"; +const char* MESSAGE_FROM = "from"; +const char* MESSAGE_TO = "to"; +const char* MESSAGE_BODY = "body"; +const char* MESSAGE_QUEUE = "queue"; +const char* MESSAGE_SEQNUM = "sequence-number"; +const char* MESSAGE_PROTOCOL_VER = "inkboard-protocol"; + +} + +} + +/* + 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:textwidth=99 : diff --git a/src/jabber_whiteboard/message-tags.h b/src/jabber_whiteboard/message-tags.h new file mode 100644 index 000000000..5cbb8a079 --- /dev/null +++ b/src/jabber_whiteboard/message-tags.h @@ -0,0 +1,139 @@ +/** + * Whiteboard session manager + * Message tags + * + * Authors: + * David Yip + * + * Copyright (c) 2005 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifndef __WHITEBOARD_MESSAGE_TAGS_H__ +#define __WHITEBOARD_MESSAGE_TAGS_H__ + +namespace Inkscape { + +namespace Whiteboard { +/** + * + * These message tags are not used in all messages. + * They are confined to messages of type CHANGE_* and DOCUMENT_*; + * they define the tags that are used inside those messages' bodies. + */ +// TODO: breaking these up into namespaces would be nice, but it's too much typing +// for now +// +// TODO: Some of these message tags are obsolete, and should be removed... + +/// Message tag signaling an attribute change on a node. +extern char const* MESSAGE_CHANGE; + +/// Message tag signaling a new node. +extern char const* MESSAGE_NEWOBJ; + +/// Message tag signaling a node to remove. +extern char const* MESSAGE_DELETE; + +/// Message tag signaling the beginning of a document synchronization. +extern char const* MESSAGE_DOCUMENT; + +/// Message tag signaling a change in node content. +extern char const* MESSAGE_NODECONTENT; + +/// Message tag signaling a change in node order. +extern char const* MESSAGE_ORDERCHANGE; + +/// Message tag signaling a commit. +extern char const* MESSAGE_COMMIT; + +/// Message tag signaling an undo. +extern char const* MESSAGE_UNDO; + +/// Message tag signaling a redo. +extern char const* MESSAGE_REDO; + +/// Message tag signaling the beginning of a document synchronization. +extern char const* MESSAGE_DOCBEGIN; + +/// Message tag signaling the end of a document synchronization. +extern char const* MESSAGE_DOCEND; + +/// Message tag used to identify an object's key. +extern char const* MESSAGE_OBJKEY; + +/// Message tag used to identify a node ID. +extern char const* MESSAGE_ID; + +/// Message tag used to identify an attribute key. +extern char const* MESSAGE_KEY; + +/// Message tag used to identify an old value (attribute or content). +extern char const* MESSAGE_OLDVAL; + +/// Message tag used to identify a new value (attribute or content). +extern char const* MESSAGE_NEWVAL; + +/// Message tag used to identify a node name. +extern char const* MESSAGE_NAME; + +extern char const* MESSAGE_ISINTERACTIVE; +extern char const* MESSAGE_DATA; + +/// Message tag used to identify the parent of a node by string key. +extern char const* MESSAGE_PARENT; + +/// Message tag used to identify a child node by string key. +extern char const* MESSAGE_CHILD; + +/// Message tag used to identify the node previous to a child node by string key. +extern char const* MESSAGE_REF; + +/// Message tag used to identify the content in a node. +extern char const* MESSAGE_CONTENT; +extern char const* MESSAGE_REPEATABLE; +extern char const* MESSAGE_CHATROOM; + +/** + * These message tags are used in all messages. + */ + +/// Message tag used to identify the message type. +extern char const* MESSAGE_TYPE; + +/// Message tag used to identify the type of node being operated on. +extern char const* MESSAGE_NODETYPE; + +/// Message tag used to identify the sender. +extern char const* MESSAGE_FROM; + +/// Message tag used to identify the recipient. +extern char const* MESSAGE_TO; + +/// Message tag used to identify the body portion of the message. +extern char const* MESSAGE_BODY; +extern char const* MESSAGE_QUEUE; + +/// Message tag used to identify the sequence number of the message. +extern char const* MESSAGE_SEQNUM; + +/// Message tag used to identify the Inkboard protocol version being used. +extern char const* MESSAGE_PROTOCOL_VER; + +} + +} + +#endif + +/* + 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:textwidth=99 : diff --git a/src/jabber_whiteboard/message-utilities.cpp b/src/jabber_whiteboard/message-utilities.cpp new file mode 100644 index 000000000..431545ac0 --- /dev/null +++ b/src/jabber_whiteboard/message-utilities.cpp @@ -0,0 +1,452 @@ +/** + * Message generation utilities + * + * Authors: + * David Yip + * Jonas Collaros, Stephen Montgomery + * + * Copyright (c) 2004-2005 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include + +#include "util/shared-c-string-ptr.h" +#include "util/list.h" + +#include "xml/node.h" +#include "xml/attribute-record.h" +#include "xml/repr.h" + +#include "jabber_whiteboard/defines.h" +#include "jabber_whiteboard/typedefs.h" +#include "jabber_whiteboard/node-utilities.h" +#include "jabber_whiteboard/message-utilities.h" +#include "jabber_whiteboard/node-tracker.h" + +#include + +namespace Inkscape { + +namespace Whiteboard { + +// This method can be instructed to not build a message string but only collect nodes that _would_ be transmitted +// and subsequently added to the tracker. This can be useful in the case where an Inkboard user is the only one +// in a chatroom and therefore needs to fill out the node tracker, but does not need to build the message string. +// This can be controlled with the only_collect_nodes flag, which will only create pointers to new XML::Nodes +// in the maps referenced by newidsbuf and newnodesbuf. Passing NULL as the message buffer has the same effect. +// +// only_collect_nodes defaults to false because most invocations of this method also use the message string. +void +MessageUtilities::newObjectMessage(Glib::ustring* msgbuf, KeyToNodeMap& newidsbuf, NodeToKeyMap& newnodesbuf, NewChildObjectMessageList& childmsgbuf, XMLNodeTracker* xmt, Inkscape::XML::Node const* node, bool only_collect_nodes, bool collect_children) +{ + // Initialize pointers + std::string id, refid, parentid; + + gchar const* name = NULL; + XML::Node* parent = NULL; + XML::Node* ref = NULL; + + bool only_add_children = false; + + + if (node != NULL) { + parent = sp_repr_parent(node); + if (parent != NULL) { + parentid = NodeUtilities::findNodeID(*parent, xmt, newnodesbuf); + if (parentid.empty()) { + g_warning("Parent %p is not being tracked, creating new ID", parent); + parentid = xmt->generateKey(); + newidsbuf[parentid] = parent; + newnodesbuf[parent] = parentid; + } + + if ( node != parent->firstChild() && parent != NULL ) { + ref = parent->firstChild(); + while (ref->next() != node) { + ref = ref->next(); + } + } + } + + if (ref != NULL) { + refid = NodeUtilities::findNodeID(*ref, xmt, newnodesbuf); + if (refid.empty() && ref != NULL) { + g_warning("Ref %p is not being tracked, creating new ID", ref); + refid = xmt->generateKey(); + newidsbuf[refid] = ref; + newnodesbuf[ref] = refid; + } + } + + name = static_cast< gchar const* >(node->name()); + } + + // Generate an id for this object and append it onto the list, if + // it's not already in the tracker + if (!xmt->isSpecialNode(node->name())) { + if (!xmt->isTracking(*node)) { + id = xmt->generateKey(); + newidsbuf[id] = node; + newnodesbuf[node] = id; + } else { + id = xmt->get(*node); + } + } else { + id = xmt->get(*node); + if (id.empty()) { + g_warning("Node %p (name %s) is a special node, but it could not be found in the node tracker (possible unexpected duplicate?) Generating unique ID anyway.", node, node->name()); + id = xmt->generateKey(); + newidsbuf[id] = node; + newnodesbuf[node] = id; + } + only_add_children = true; + } + + // If we're only adding children (i.e. this is a special node) + // don't process the given node. + if( !only_add_children && !id.empty() && msgbuf != NULL && !only_collect_nodes ) { + // + (*msgbuf) = (*msgbuf) + "<" + MESSAGE_NEWOBJ + ">"; + + // + (*msgbuf) = (*msgbuf) + "<" + MESSAGE_PARENT + ">"; + + if(!parentid.empty()) { + (*msgbuf) += parentid; + } + + // id + (*msgbuf) = (*msgbuf) + ""; + + (*msgbuf) = (*msgbuf) + "<" + MESSAGE_CHILD + ">"; + (*msgbuf) += id; + + (*msgbuf) = (*msgbuf) + ""; + + if(!refid.empty()) { + // refid + (*msgbuf) = (*msgbuf) + "<" + MESSAGE_REF + ">"; + + (*msgbuf) += refid; + + (*msgbuf) = (*msgbuf) + ""; + } + + // *node.type() + (*msgbuf) = (*msgbuf) + "<" + MESSAGE_NODETYPE + ">" + NodeUtilities::nodeTypeToString(*node); + (*msgbuf) = (*msgbuf) + ""; + + if (node->content() != NULL) { + // node->content() + (*msgbuf) = (*msgbuf) + "<" + MESSAGE_CONTENT + ">" + node->content(); + (*msgbuf) = (*msgbuf) + ""; + } + + // name + (*msgbuf) = (*msgbuf) + "<" + MESSAGE_NAME + ">"; + + if( name != NULL ) { + (*msgbuf) += name; + } + + (*msgbuf) = (*msgbuf) + ""; + + // + (*msgbuf) = (*msgbuf) + ""; + } else if (id.empty()) { + // if ID is NULL, then we have a real problem -- we were not able to find a key + // nor generate one. The only thing we can really do here is abort, since we have + // no way to let the other client(s) uniquely identify this object. + /* FIXME: If this indicates a programming bug, then don't request translation with + * _(...): it is most useful in untranslated form so that developers may search for + * it when someone reports it in a bug report (as we want users to do for all bugs, + * as indicated by it being a g_warning string). + * + * Otherwise, if it is not a programming bug but a network error or a bug in the + * remote peer (perhaps running different software) or whatever, then present it in + * an alert box, and avoid use of technical jargon `NULL'. + */ + g_warning(_("ID for new object is NULL even after generation and lookup attempts: the new object will NOT be sent, nor will any of its child objects!")); + return; + } else { + + } + + + if (!only_collect_nodes && msgbuf != NULL && !id.empty()) { + // Collect new object's attributes and append them onto the msgbuf + Inkscape::Util::List attrlist = node->attributeList(); + + for(; attrlist; attrlist++) { + MessageUtilities::objectChangeMessage(msgbuf, xmt, id, g_quark_to_string(attrlist->key), NULL, attrlist->value, false); + } + } + + if (!only_collect_nodes) { + childmsgbuf.push_back(*msgbuf); + } + + if (!id.empty() && collect_children) { + Glib::ustring childbuf; + // Collect any child objects of this new object + for ( Inkscape::XML::Node const *child = node->firstChild(); child != NULL; child = child->next() ) { + childbuf.clear(); + MessageUtilities::newObjectMessage(&childbuf, newidsbuf, newnodesbuf, childmsgbuf, xmt, child, only_collect_nodes); + if (!only_collect_nodes) { + // we're recursing down the tree, so we're picking up child nodes first + // and parents afterwards +// childmsgbuf.push_front(childbuf); + } + + } + } +} + +void +MessageUtilities::objectChangeMessage(ustring* msgbuf, XMLNodeTracker* xmt, std::string const id, gchar const* key, gchar const* oldval, gchar const* newval, bool is_interactive) +{ + // Construct message + + // id + (*msgbuf) = (*msgbuf) + "<" + MESSAGE_CHANGE + ">"; + (*msgbuf) = (*msgbuf) + "<" + MESSAGE_ID + ">"; + (*msgbuf) += id; + (*msgbuf) = (*msgbuf) + ""; + + // key + (*msgbuf) = (*msgbuf) + "<" + MESSAGE_KEY + ">"; + if (key != NULL) { + (*msgbuf) += key; + } + (*msgbuf) = (*msgbuf) + ""; + + // oldval + (*msgbuf) = (*msgbuf) + "<" + MESSAGE_OLDVAL + ">"; + if (oldval != NULL) { + (*msgbuf) += oldval; + } + (*msgbuf) = (*msgbuf) + ""; + + // newval + (*msgbuf) = (*msgbuf) + "<" + MESSAGE_NEWVAL + ">"; + if (newval != NULL) { + (*msgbuf) += newval; + } + (*msgbuf) = (*msgbuf) + ""; + + // is_interactive + (*msgbuf) = (*msgbuf) + "<" + MESSAGE_ISINTERACTIVE + ">"; + if (is_interactive) { + (*msgbuf) += "true"; + } else { + (*msgbuf) += "false"; + } + (*msgbuf) = (*msgbuf) + ""; + + // + (*msgbuf) = (*msgbuf) + ""; +} + +void +MessageUtilities::objectDeleteMessage(Glib::ustring* msgbuf, XMLNodeTracker* xmt, Inkscape::XML::Node const& parent, Inkscape::XML::Node const& child, Inkscape::XML::Node const* prev) +{ + /* + gchar const* parentid = NULL; + gchar const* previd = NULL; + gchar const* childid = NULL; + + childid = child.attribute("id"); + parentid = parent.attribute("id"); + if (prev != NULL) { + previd = prev->attribute("id"); + }*/ + + std::string parentid, previd, childid; + + childid = xmt->get(child); + parentid = xmt->get(parent); + previd = xmt->get(*prev); + + if (!childid.empty()) { + // parentid + (*msgbuf) = (*msgbuf) + "<" + MESSAGE_DELETE + ">" + "<" + MESSAGE_PARENT + ">"; + if (!parentid.empty()) { + (*msgbuf) += parentid; + } + (*msgbuf) = (*msgbuf) + ""; + + // childid + (*msgbuf) = (*msgbuf) + "<" + MESSAGE_CHILD + ">"; + if (!childid.empty()) { + (*msgbuf) += childid; + } + (*msgbuf) = (*msgbuf) + ""; + + // previd + (*msgbuf) = (*msgbuf) + "<" + MESSAGE_REF + ">"; + if (!previd.empty()) { + (*msgbuf) += previd; + } + (*msgbuf) = (*msgbuf) + ""; + + // + (*msgbuf) = (*msgbuf) + ""; + } +} + +void +MessageUtilities::contentChangeMessage(Glib::ustring& msgbuf, std::string const nodeid, Util::SharedCStringPtr old_value, Util::SharedCStringPtr new_value) +{ + if (!nodeid.empty()) { + // + msgbuf = msgbuf + "<" + MESSAGE_NODECONTENT + ">"; + + // nodeid + msgbuf = msgbuf + "<" + MESSAGE_ID + ">"; + msgbuf += nodeid; + msgbuf = msgbuf + ""; + + // old_value + msgbuf = msgbuf + "<" + MESSAGE_OLDVAL + ">"; + msgbuf += old_value.cString(); + msgbuf = msgbuf + ""; + + // new_value + msgbuf = msgbuf + "<" + MESSAGE_NEWVAL + ">"; + msgbuf += new_value.cString(); + msgbuf = msgbuf + ""; + + // + msgbuf = msgbuf + ""; + } +} + +void +MessageUtilities::childOrderChangeMessage(Glib::ustring& msgbuf, std::string const childid, std::string const oldprevid, std::string const newprevid) +{ + if (!childid.empty()) { + // + msgbuf = msgbuf + "<" + MESSAGE_ORDERCHANGE + ">"; + + // nodeid + msgbuf = msgbuf + "<" + MESSAGE_CHILD + ">"; + msgbuf += childid; + msgbuf = msgbuf + ""; + + // oldprevid + /* + msgbuf = msgbuf + "<" + MESSAGE_OLDVAL + ">"; + msgbuf += (*oldprevid); + msgbuf = msgbuf + ""; + */ + + // newprevid + msgbuf = msgbuf + "<" + MESSAGE_NEWVAL + ">"; + msgbuf += newprevid; + msgbuf = msgbuf + ""; + + // + msgbuf = msgbuf + ""; + } +} + + +bool +MessageUtilities::getFirstMessageTag(struct Node& buf, Glib::ustring const& msg) +{ + if (msg.empty()) { + return false; + } + + // See if we have a valid start tag, i.e. < ... >. If we do, + // continue; if not, stop and return NULL. + // + // find_first_of returns ULONG_MAX when it cannot find the first + // instance of the given character. + + Glib::ustring::size_type startDelim = msg.find_first_of('<'); + if (startDelim != ULONG_MAX) { + Glib::ustring::size_type endDelim = msg.find_first_of('>'); + if (endDelim != ULONG_MAX) { + if (endDelim > startDelim) { + buf.tag = msg.substr(startDelim+1, (endDelim-startDelim)-1); + if (buf.tag.find_first_of('/') == ULONG_MAX) { // start tags should not be end tags + + + // construct end tag () + Glib::ustring endTag(buf.tag); + endTag.insert(0, "/"); + + Glib::ustring::size_type endTagLoc = msg.find(endTag, endDelim); + if (endTagLoc != ULONG_MAX) { + buf.data = msg.substr(endDelim+1, ((endTagLoc - 1) - (endDelim + 1))); + buf.next_pos = endTagLoc + endTag.length() + 1; + + return true; + } + } + } + } + } + + return false; +} + +bool +MessageUtilities::findTag(struct Node& buf, Glib::ustring const& msg) +{ + if (msg.empty()) { + return false; + } + + // Read desired tag type out of buffer, and append + // < > to it + + Glib::ustring searchterm("<"); + searchterm += buf.tag; + searchterm + ">"; + + Glib::ustring::size_type tagStart = msg.find(searchterm, 0); + if (tagStart != ULONG_MAX) { + // Find ending tag starting at the point at the end of + // the start tag. + searchterm.insert(1, "/"); + Glib::ustring::size_type tagEnd = msg.find(searchterm, tagStart + searchterm.length()); + if (tagEnd != ULONG_MAX) { + Glib::ustring::size_type start = tagStart + searchterm.length(); + buf.data = msg.substr(start, tagEnd - start); + return true; + } + } + return false; +} + +Glib::ustring +MessageUtilities::makeTagWithContent(Glib::ustring tagname, Glib::ustring content) +{ + Glib::ustring buf; + buf = "<" + tagname + ">"; + buf += content; + buf += ""; + return buf; +} + + +} + +} + + + +/* + 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:textwidth=99 : diff --git a/src/jabber_whiteboard/message-utilities.h b/src/jabber_whiteboard/message-utilities.h new file mode 100644 index 000000000..11acb1a95 --- /dev/null +++ b/src/jabber_whiteboard/message-utilities.h @@ -0,0 +1,84 @@ +/** + * Whiteboard session manager + * Message generation utilities + * + * Authors: + * David Yip + * Jonas Collaros, Stephen Montgomery + * + * Copyright (c) 2004-2005 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifndef __WHITEBOARD_MESSAGE_UTILITIES_H__ +#define __WHITEBOARD_MESSAGE_UTILITIES_H__ + +#include +#include "xml/repr.h" + +#include "xml/node.h" +#include "jabber_whiteboard/typedefs.h" + +using Glib::ustring; + +namespace Inkscape { + +namespace Util { + +class SharedCStringPtr; + +} + +namespace Whiteboard { + +struct Node { + ustring tag; + ustring data; + ustring::size_type next_pos; +}; + +class XMLNodeTracker; + +class MessageUtilities { +public: + // Message generation utilities + static void newObjectMessage(ustring* msgbuf, KeyToNodeMap& newidsbuf, NodeToKeyMap& newnodesbuf, NewChildObjectMessageList& childmsgbuf, XMLNodeTracker* xmt, Inkscape::XML::Node const* node, bool only_collect_nodes = false, bool collect_children = true); + static void objectChangeMessage(ustring* msgbuf, XMLNodeTracker* xmt, std::string const id, gchar const* key, gchar const* oldval, gchar const* newval, bool is_interactive); + static void objectDeleteMessage(ustring* msgbuf, XMLNodeTracker* xmt, Inkscape::XML::Node const& parent, Inkscape::XML::Node const& child, Inkscape::XML::Node const* prev); + static void contentChangeMessage(ustring& msgbuf, std::string const nodeid, Util::SharedCStringPtr old_value, Util::SharedCStringPtr new_value); + static void childOrderChangeMessage(ustring& msgbuf, std::string const childid, std::string const oldprevid, std::string const newprevid); + + // Message parsing utilities + static bool getFirstMessageTag(struct Node& buf, ustring const& msg); + static bool findTag(struct Node& buf, ustring const& msg); + + // Message tag generation utilities + static Glib::ustring makeTagWithContent(Glib::ustring tagname, Glib::ustring content); + +private: + // noncopyable, nonassignable + MessageUtilities(MessageUtilities const&); + MessageUtilities& operator=(MessageUtilities const&); + +}; + +} + +} + + + + + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +#endif diff --git a/src/jabber_whiteboard/node-tracker-event-tracker.cpp b/src/jabber_whiteboard/node-tracker-event-tracker.cpp new file mode 100644 index 000000000..da872c5e6 --- /dev/null +++ b/src/jabber_whiteboard/node-tracker-event-tracker.cpp @@ -0,0 +1,56 @@ +/** + * Tracks node add/remove events to an XMLNodeTracker, and eliminates cases such as + * consecutive add/remove. + * + * Authors: + * David Yip + * + * Copyright (c) 2005 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "xml/node.h" + +#include "jabber_whiteboard/node-tracker-event-tracker.h" + +namespace Inkscape { + +namespace Whiteboard { + +bool +NodeTrackerEventTracker::tryToTrack(XML::Node* node, NodeTrackerAction action) +{ + // 1. Check if node is being tracked. + NodeActionMap::iterator i = this->_actions.find(node); + if (i != this->_actions.end()) { + // 2a. Check the action. If it is the same as the action we are registering, + // return false. Otherwise, register the action with the actions map + // and return true. + if (i->second == action) { + return false; + } else { + this->_actions[node] = action; + return true; + } + } else { + // 2b. If we aren't tracking this node, insert it with the given action. + this->_actions[node] = action; + return true; + } +} + +} + +} + +/* + 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:textwidth=99 : diff --git a/src/jabber_whiteboard/node-tracker-event-tracker.h b/src/jabber_whiteboard/node-tracker-event-tracker.h new file mode 100644 index 000000000..c600592d4 --- /dev/null +++ b/src/jabber_whiteboard/node-tracker-event-tracker.h @@ -0,0 +1,66 @@ +/** + * Tracks node add/remove events to an XMLNodeTracker, and eliminates cases such as + * consecutive add/remove. + * + * Authors: + * David Yip + * + * Copyright (c) 2005 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifndef __WHITEBOARD_NODE_TRACKER_EVENT_TRACKER_H__ +#define __WHITEBOARD_NODE_TRACKER_EVENT_TRACKER_H__ + +#include + +#include "jabber_whiteboard/typedefs.h" + +namespace Inkscape { + +namespace Whiteboard { + +typedef std::pair< XML::Node*, std::string > NodeKeyPair; +typedef std::map< XML::Node*, NodeTrackerAction > NodeActionMap; + +class NodeTrackerEventTracker { +public: + NodeTrackerEventTracker() { } + ~NodeTrackerEventTracker() { } + bool tryToTrack(XML::Node* node, NodeTrackerAction action); + + NodeTrackerAction getAction(XML::Node const* node) + { + NodeActionMap::iterator i = this->_actions.find(const_cast< XML::Node* >(node)); + if (i != this->_actions.end()) { + return i->second; + } else { + return NODE_UNKNOWN; + } + } + + void clear() + { + this->_actions.clear(); + } +private: + NodeActionMap _actions; +}; + +} + +} + +#endif + +/* + 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:textwidth=99 : diff --git a/src/jabber_whiteboard/node-tracker-observer.h b/src/jabber_whiteboard/node-tracker-observer.h new file mode 100644 index 000000000..600500c70 --- /dev/null +++ b/src/jabber_whiteboard/node-tracker-observer.h @@ -0,0 +1,119 @@ +/** + * Convenience base class for XML::NodeObservers that need to extract data + * from an XMLNodeTracker and queue up added or removed nodes for later + * processing + * + * Authors: + * David Yip + * + * Copyright (c) 2005 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifndef __WHITEBOARD_NODE_TRACKER_OBSERVER_H__ +#define __WHITEBOARD_NODE_TRACKER_OBSERVER_H__ + +#include "xml/node-observer.h" + +#include "jabber_whiteboard/node-tracker-event-tracker.h" +#include "jabber_whiteboard/node-tracker.h" +#include "jabber_whiteboard/typedefs.h" + +namespace Inkscape { + +namespace XML { + +class Node; + +} + +namespace Whiteboard { + +class NodeTrackerObserver : public XML::NodeObserver { +public: + NodeTrackerObserver(XMLNodeTracker* xnt) : _xnt(xnt) { } + virtual ~NodeTrackerObserver() { } + + // just reinforce the fact that we don't implement any of the + // notification methods here + virtual void notifyChildAdded(XML::Node &node, XML::Node &child, XML::Node *prev)=0; + + virtual void notifyChildRemoved(XML::Node &node, XML::Node &child, XML::Node *prev)=0; + + virtual void notifyChildOrderChanged(XML::Node &node, XML::Node &child, + XML::Node *old_prev, XML::Node *new_prev)=0; + + virtual void notifyContentChanged(XML::Node &node, + Util::SharedCStringPtr old_content, + Util::SharedCStringPtr new_content)=0; + + virtual void notifyAttributeChanged(XML::Node &node, GQuark name, + Util::SharedCStringPtr old_value, + Util::SharedCStringPtr new_value)=0; + + + // ...but we do provide node tracking facilities + KeyToNodeActionList& getNodeTrackerActions() + { + return this->newnodes; + } + + KeyToNodeActionList getNodeTrackerActionsCopy() + { + return this->newnodes; + } + + void clearNodeBuffers() + { + this->newnodes.clear(); + this->newkeys.clear(); + this->actions.clear(); + } + +protected: + std::string _findOrGenerateNodeID(XML::Node& node) + { + NodeToKeyMap::iterator i = newkeys.find(&node); + if (i != newkeys.end()) { +// g_log(NULL, G_LOG_LEVEL_DEBUG, "Found key for %p (local): %s", &node, i->second.c_str()); + return i->second; + } else { + std::string nodeid = this->_xnt->get(node); + if (nodeid.empty()) { +// g_log(NULL, G_LOG_LEVEL_DEBUG, "Generating key for %p", &node); + return this->_xnt->generateKey(); + } else { +// g_log(NULL, G_LOG_LEVEL_DEBUG, "Found key for %p (tracker): %s", &node, nodeid.c_str()); + return nodeid; + } + } + } + + KeyToNodeActionList newnodes; + NodeTrackerEventTracker actions; + NodeToKeyMap newkeys; + XMLNodeTracker* _xnt; + +private: + // noncopyable, nonassignable + NodeTrackerObserver(NodeTrackerObserver const& other); + NodeTrackerObserver& operator=(NodeTrackerObserver const& other); + +}; + +} + +} +#endif + +/* + 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:textwidth=99 : diff --git a/src/jabber_whiteboard/node-tracker.cpp b/src/jabber_whiteboard/node-tracker.cpp new file mode 100644 index 000000000..07f9069eb --- /dev/null +++ b/src/jabber_whiteboard/node-tracker.cpp @@ -0,0 +1,368 @@ +/** + * Whiteboard session manager + * XML node tracking facility + * + * Authors: + * David Yip + * + * Copyright (c) 2005 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "sp-object.h" +#include "sp-item-group.h" +#include "document.h" +#include "document-private.h" + +#include "xml/node.h" + +#include "util/compose.hpp" + +#include "jabber_whiteboard/session-manager.h" +#include "jabber_whiteboard/node-tracker.h" + + +// TODO: remove redundant calls to isTracking(); it's a rather unnecessary +// performance burden. +namespace Inkscape { + +namespace Whiteboard { + +// Lookup tables + +/** + * Keys for special nodes. + * + * A special node is a node that can only appear once in a document. + */ +char const* specialnodekeys[] = { + DOCUMENT_ROOT_NODE, + DOCUMENT_NAMEDVIEW_NODE, +}; + +/** + * Names of special nodes. + * + * A special node is a node that can only appear once in a document. + */ +char const* specialnodenames[] = { + DOCUMENT_ROOT_NAME, + DOCUMENT_NAMEDVIEW_NAME, +}; + +XMLNodeTracker::XMLNodeTracker(SessionManager* sm) : + _rootKey(DOCUMENT_ROOT_NODE), + _namedviewKey(DOCUMENT_NAMEDVIEW_NODE) +{ + this->_sm = sm; + this->_counter = 0; + + // Construct special node maps + this->createSpecialNodeTables(); + this->reset(); +} + +XMLNodeTracker::~XMLNodeTracker() +{ + this->_clear(); +} + +void +XMLNodeTracker::put(std::string key, XML::Node const& node) +{ + this->put(key, const_cast< XML::Node& >(node)); +} + +void +XMLNodeTracker::put(std::string key, XML::Node& node) +{ + KeyToTrackerNodeMap::iterator i = this->_keyToNode.find(key); + if (i != this->_keyToNode.end()) { + this->_keyToNode.erase(i); + } + this->_keyToNode.insert(std::make_pair< std::string, XML::Node* >(key, &node)); + + TrackerNodeToKeyMap::iterator j = this->_nodeToKey.find(&node); + if (j != this->_nodeToKey.end()) { + this->_nodeToKey.erase(j); + } + this->_nodeToKey.insert(std::make_pair< XML::Node*, std::string >(&node, key)); +} + +void +XMLNodeTracker::put(KeyToNodeMap& newids, NodeToKeyMap& newnodes) +{ + // TODO: redo + KeyToNodeMap::iterator i = newids.begin(); + + for(; i != newids.end(); i++) { + this->put((*i).first, *((*i).second)); + } +} + +void +XMLNodeTracker::process(KeyToNodeActionList& actions) +{ + KeyToNodeActionList::iterator i = actions.begin(); + for(; i != actions.end(); i++) { + // Get the action to perform. + SerializedEventNodeAction action = *i; + switch(action.second) { + case NODE_ADD: + this->put(action.first.first, *action.first.second); + break; + case NODE_REMOVE: + // this->remove(const_cast< XML::Node& >(*action.first.second)); + break; + default: + break; + } + } +} + +XML::Node* +XMLNodeTracker::get(std::string& key) +{ + KeyToTrackerNodeMap::iterator i = this->_keyToNode.find(key); + if (i != this->_keyToNode.end()) { + return (*i).second; + } else { + g_warning("Key %s is not being tracked!", key.c_str()); + return NULL; + } +} + +XML::Node* +XMLNodeTracker::get(std::string const& key) +{ + return this->get(const_cast< std::string& >(key)); +} + + +std::string const +XMLNodeTracker::get(XML::Node& node) +{ + TrackerNodeToKeyMap::iterator i = this->_nodeToKey.find(&node); + if (i != this->_nodeToKey.end()) { + return (*i).second; + } else { + return ""; + } +} + +std::string const +XMLNodeTracker::get(XML::Node const& node) +{ + return this->get(const_cast< XML::Node& >(node)); +} + +bool +XMLNodeTracker::isTracking(std::string& key) +{ + return (this->_keyToNode.find(key) != this->_keyToNode.end()); +} + +bool +XMLNodeTracker::isTracking(std::string const& key) +{ + return this->isTracking(const_cast< std::string& >(key)); +} + +bool +XMLNodeTracker::isTracking(XML::Node& node) +{ + return (this->_nodeToKey.find(&node) != this->_nodeToKey.end()); +} + +bool +XMLNodeTracker::isTracking(XML::Node const& node) +{ + return this->isTracking(const_cast< XML::Node& >(node)); +} + +bool +XMLNodeTracker::isRootNode(XML::Node& node) +{ + XML::Node* docroot = sp_document_repr_root(this->_sm->document()); + return (docroot == &node); +} + + +void +XMLNodeTracker::remove(std::string& key) +{ + if (this->isTracking(key)) { + XML::Node* element = this->get(key); + this->_keyToNode.erase(key); + this->_nodeToKey.erase(element); + } +} + +void +XMLNodeTracker::remove(XML::Node& node) +{ + if (this->isTracking(node)) { + std::string const element = this->get(node); + this->_nodeToKey.erase(&node); + this->_keyToNode.erase(element); + } +} + +bool +XMLNodeTracker::isSpecialNode(char const* name) +{ + return (this->_specialnodes.find(name) != this->_specialnodes.end()); +} + +bool +XMLNodeTracker::isSpecialNode(std::string const& name) +{ + return (this->_specialnodes.find(name.data()) != this->_specialnodes.end()); +} + +std::string const +XMLNodeTracker::getSpecialNodeKeyFromName(Glib::ustring const& name) +{ + return this->_specialnodes[name.data()]; +} + +std::string const +XMLNodeTracker::getSpecialNodeKeyFromName(Glib::ustring const* name) +{ + return this->_specialnodes[name->data()]; +} + +std::string +XMLNodeTracker::generateKey(gchar const* JID) +{ + return String::compose("%1;%2", this->_counter++, JID); +} + +std::string +XMLNodeTracker::generateKey() +{ + SessionData* sd = this->_sm->session_data; + std::bitset< NUM_FLAGS >& status = sd->status; + if (status[IN_CHATROOM]) { + // This is not strictly required for chatrooms: chatrooms will + // function just fine with the user-to-user ID scheme. However, + // the user-to-user scheme can lead to loss of anonymity + // in anonymous chat rooms, since it contains the real JID + // of a user. + return String::compose("%1;%2@%3/%4", this->_counter++, sd->chat_name, sd->chat_server, sd->chat_handle); + } else { + return String::compose("%1;%2", this->_counter++, lm_connection_get_jid(sd->connection)); + } +} + +void +XMLNodeTracker::createSpecialNodeTables() +{ + int const sz = sizeof(specialnodekeys) / sizeof(char const*); + for(int i = 0; i < sz; i++) { + this->_specialnodes[specialnodenames[i]] = specialnodekeys[i]; + } +} + + +// rather nasty and crufty debugging function +void +XMLNodeTracker::dump() +{ + g_log(NULL, G_LOG_LEVEL_DEBUG, "XMLNodeTracker dump for %s", lm_connection_get_jid(this->_sm->session_data->connection)); + KeyToTrackerNodeMap::iterator i = this->_keyToNode.begin(); + TrackerNodeToKeyMap::iterator j = this->_nodeToKey.begin(); + std::map< char const*, char const* >::iterator k = this->_specialnodes.begin(); + + + g_log(NULL, G_LOG_LEVEL_DEBUG, "%u entries in keyToNode, %u entries in nodeToKey", this->_keyToNode.size(), this->_nodeToKey.size()); + + if (this->_keyToNode.size() != this->_nodeToKey.size()) { + g_warning("Map sizes do not match!"); + } + + g_log(NULL, G_LOG_LEVEL_DEBUG, "XMLNodeTracker keyToNode dump"); + while(i != this->_keyToNode.end()) { + if (!((*i).first.empty())) { + if ((*i).second != NULL) { + g_log(NULL, G_LOG_LEVEL_DEBUG, "%s\t->\t%p (%s) (%s)", (*i).first.c_str(), (*i).second, (*i).second->name(), (*i).second->content()); + } else { + g_log(NULL, G_LOG_LEVEL_DEBUG, "%s\t->\t(null)", (*i).first.c_str()); + } + } else { + g_log(NULL, G_LOG_LEVEL_DEBUG, "(null)\t->\t%p (%s)", (*i).second, (*i).second->name()); + } + i++; + } + + g_log(NULL, G_LOG_LEVEL_DEBUG, "XMLNodeTracker nodeToKey dump"); + while(j != this->_nodeToKey.end()) { + if (!((*j).second.empty())) { + if ((*j).first) { + g_log(NULL, G_LOG_LEVEL_DEBUG, "%p\t->\t%s (parent %p)", (*j).first, (*j).second.c_str(), (*j).first->parent()); + } else { + g_log(NULL, G_LOG_LEVEL_DEBUG, "(null)\t->\t%s", (*j).second.c_str()); + } + } else { + g_log(NULL, G_LOG_LEVEL_DEBUG, "%p\t->\t(null)", (*j).first); + } + j++; + } + + g_log(NULL, G_LOG_LEVEL_DEBUG, "_specialnodes dump"); + while(k != this->_specialnodes.end()) { + g_log(NULL, G_LOG_LEVEL_DEBUG, "%s\t->\t%s", (*k).first, (*k).second); + k++; + } +} + +void +XMLNodeTracker::reset() +{ + this->_clear(); + + // Find and insert special nodes + // root node + this->put(this->_rootKey, *(sp_document_repr_root(this->_sm->document()))); + + // namedview node + SPObject* namedview = sp_item_group_get_child_by_name((SPGroup *)this->_sm->document()->root, NULL, DOCUMENT_NAMEDVIEW_NAME); + if (!namedview) { + g_warning("namedview node does not exist; it will be created during synchronization"); + } else { + this->put(this->_namedviewKey, *(SP_OBJECT_REPR(namedview))); + } +} + +void +XMLNodeTracker::_clear() +{ + // Remove all keys in both trackers, and delete each key. + this->_keyToNode.clear(); + this->_nodeToKey.clear(); + + /* + TrackerNodeToKeyMap::iterator j = this->_nodeToKey.begin(); + for(; j != this->_nodeToKey.end(); j++) { + this->_nodeToKey.erase(j); + } + */ +} + +} + +} + + + +/* + 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:textwidth=99 : diff --git a/src/jabber_whiteboard/node-tracker.h b/src/jabber_whiteboard/node-tracker.h new file mode 100644 index 000000000..9c92b815a --- /dev/null +++ b/src/jabber_whiteboard/node-tracker.h @@ -0,0 +1,300 @@ +/** + * Whiteboard session manager + * XML node tracking facility + * + * Authors: + * David Yip + * + * Copyright (c) 2005 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifndef __WHITEBOARD_XML_NODE_TRACKER_H__ +#define __WHITEBOARD_XML_NODE_TRACKER_H__ + +#include "jabber_whiteboard/tracker-node.h" +#include "jabber_whiteboard/typedefs.h" + +#include +#include +#include +#include + +namespace Inkscape { + +namespace Whiteboard { + +class SessionManager; + +/** + * std::less-like functor for C-style strings. + */ +struct strcmpless : public std::binary_function< char const*, char const*, bool > +{ + bool operator()(char const* _x, char const* _y) const + { + return (strcmp(_x, _y) < 0); + } +}; + + +// TODO: This is a pretty heinous mess of methods that accept +// both pointers and references -- a lot of it has to do with +// XML::Node& in the node observer and XML::Node* elsewhere, +// although some of it (like Glib::ustring const& vs. +// Glib::ustring const*) is completely mea culpa. When possible +// it'd be good to thin this class out. + +/** + * XMLNodeTracker generates and watches unique IDs for XML::Nodes for use in + * document event serialization and deserialization. + * + * More specifically, it has three tasks: + *
    + *
  1. Association XML::Nodes with string IDs, and vice versa.
  2. + *
  3. Facilitation of lookup of a string ID or XML::Node given the other key.
  4. + *
  5. Generation of new string IDs for XML::Nodes.
  6. + *
+ * + * XML::Nodes are assigned an ID that follows one of two forms: + *
    + *
  1. unsigned integer;user JID
  2. + *
  3. unsigned integer;chatroom@conference server/handle
  4. + *
+ * + * Form 1 is used in user-to-user sessions; form 2 is used in chatroom sessions. + */ +class XMLNodeTracker { +public: + /** + * Constructor. + * + * \param sm The SessionManager with which an XMLNodeTracker instance is to be associated with. + */ + XMLNodeTracker(SessionManager* sm); + ~XMLNodeTracker(); + + /** + * Insert a (key,node) pair into the tracker. + * + * \param key The key to associate with the node. + * \param node The node to associate with the key. + */ + void put(std::string key, XML::Node& node); + + /** + * Insert a (key,node) pair into the tracker. + * + * \param key The key to associate with the node. + * \param node The node to associate with the key. + */ + void put(std::string key, XML::Node const& node); + + /** + * Insert a range of (key,node) pairs into the tracker. + * + * The size of the two maps must be the same. + * \param newids The keys to associate with the nodes. + * \param newnodes The nodes to associate with the keys. + */ + void put(KeyToNodeMap& newids, NodeToKeyMap& newnodes); + + /** + * Process a list of node actions to add and remove nodes from the tracker. + * + * \param actions The action list to process. + */ + void process(KeyToNodeActionList& actions); + + /** + * Retrieve an XML::Node given a key. + * + * \param key Reference to a string key. + * \return Pointer to an XML::Node, or NULL if no associated node could be found. + */ + XML::Node* get(std::string& key); + + /** + * Retrieve an XML::Node given a key. + * + * \param key Reference to a const string key. + * \return Pointer to an XML::Node, or NULL if no associated node could be found. + */ + XML::Node* get(std::string const& key); + + /** + * Retrieve a string key given a reference to an XML::Node. + * + * \param node Reference to an XML::Node. + * \return The associated string key, or an empty string if no associated key could be found. + */ + std::string const get(XML::Node& node); + + /** + * Retrieve a string key given a reference to an XML::Node. + * + * \param node Reference to a const XML::Node. + * \return The associated string key, or an empty string if no associated key could be found. + */ + std::string const get(XML::Node const& node); + + /** + * Remove an entry from the tracker based on key. + * + * \param The key of the entry to remove. + */ + void remove(std::string& key); + + /** + * Remove an entry from the tracker based on XML::Node. + * + * \param A reference to the XML::Node associated with the entry to remove. + */ + void remove(XML::Node& node); + + /** + * Return whether or not a (key,node) pair is being tracked, given a string key. + * + * \param The key associated with the pair to check. + * \return Whether or not the pair is being tracked. + */ + bool isTracking(std::string& key); + + /** + * Return whether or not a (key,node) pair is being tracked, given a string key. + * + * \param The key associated with the pair to check. + * \return Whether or not the pair is being tracked. + */ + bool isTracking(std::string const& key); + + /** + * Return whether or not a (key,node) pair is being tracked, given a node. + * + * \param The node associated with the pair to check. + * \return Whether or not the pair is being tracked. + */ + bool isTracking(XML::Node& node); + + /** + * Return whether or not a (key,node) pair is being tracked, given a node. + * + * \param The node associated with the pair to check. + * \return Whether or not the pair is being tracked. + */ + bool isTracking(XML::Node const& node); + + /** + * Return whether or not a node identified by a given name is a special node. + * + * \see Inkscape::Whiteboard::specialnodekeys + * \see Inkscape::Whiteboard::specialnodenames + * + * \param The name associated with the node. + * \return Whether or not the node is a special node. + */ + bool isSpecialNode(char const* name); + + /** + * Return whether or not a node identified by a given name is a special node. + * + * \see Inkscape::Whiteboard::specialnodekeys + * \see Inkscape::Whiteboard::specialnodenames + * + * \param The name associated with the node. + * \return Whether or not the node is a special node. + */ + bool isSpecialNode(std::string const& name); + + /** + * Retrieve the key of a special node given the name of a special node. + * + * \see Inkscape::Whiteboard::specialnodekeys + * \see Inkscape::Whiteboard::specialnodenames + * + * \param The name associated with the node. + * \return The key of the special node. + */ + std::string const getSpecialNodeKeyFromName(Glib::ustring const& name); + + /** + * Retrieve the key of a special node given the name of a special node. + * + * \see Inkscape::Whiteboard::specialnodekeys + * \see Inkscape::Whiteboard::specialnodenames + * + * \param The name associated with the node. + * \return The key of the special node. + */ + std::string const getSpecialNodeKeyFromName(Glib::ustring const* name); + + /** + * Returns whether or not the given node is the root node of the SPDocument associated + * with an XMLNodeTracker's SessionManager. + * + * \param Reference to an XML::Node to test. + * \return Whether or not the given node is the document root node. + */ + bool isRootNode(XML::Node& node); + + /** + * Generate a node key given a JID. + * + * \param The JID to use in the key. + * \return A node string key. + */ + std::string generateKey(gchar const* JID); + + /** + * Generate a node key given the JID specified in the SessionData structure associated + * with an XMLNodeTracker's SessionManager. + * + * \return A node string key. + */ + std::string generateKey(); + + // TODO: remove debugging function + void dump(); + void reset(); + +private: + void createSpecialNodeTables(); + void _clear(); + + unsigned int _counter; + SessionManager* _sm; + + // defined in typedefs.h + KeyToTrackerNodeMap _keyToNode; + TrackerNodeToKeyMap _nodeToKey; + + std::map< char const*, char const*, strcmpless > _specialnodes; + + // Keys for special nodes + std::string _rootKey; + std::string _defsKey; + std::string _namedviewKey; + std::string _metadataKey; + + // noncopyable, nonassignable + XMLNodeTracker(XMLNodeTracker const&); + XMLNodeTracker& operator=(XMLNodeTracker const&); +}; + +} + +} + + +#endif +/* + 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:textwidth=99 : diff --git a/src/jabber_whiteboard/node-utilities.cpp b/src/jabber_whiteboard/node-utilities.cpp new file mode 100644 index 000000000..35b2772a1 --- /dev/null +++ b/src/jabber_whiteboard/node-utilities.cpp @@ -0,0 +1,119 @@ +/** + * Whiteboard session manager + * XML node manipulation / retrieval utilities + * + * Authors: + * David Yip + * + * Copyright (c) 2005 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "util/shared-c-string-ptr.h" +#include "util/list.h" + +#include "xml/node-observer.h" +#include "xml/attribute-record.h" +#include "xml/repr.h" + +#include "jabber_whiteboard/defines.h" +#include "jabber_whiteboard/typedefs.h" +#include "jabber_whiteboard/node-utilities.h" +#include "jabber_whiteboard/node-tracker.h" +//#include "jabber_whiteboard/node-observer.h" + +namespace Inkscape { + +namespace Whiteboard { + +/* +Inkscape::XML::Node* +NodeUtilities::lookupReprByValue(Inkscape::XML::Node* root, gchar const* key, Glib::ustring const* value) +{ + GQuark const quark = g_quark_from_string(key); + if (root == NULL) { + return NULL; + } + + Inkscape::Util::List attrlist = root->attributeList(); + for( ; attrlist ; attrlist++) { + if ((attrlist->key == quark) && (strcmp(attrlist->value, value->data()) == 0)) { + return root; + } + } + Inkscape::XML::Node* result; + for ( Inkscape::XML::Node* child = root->firstChild() ; child != NULL ; child = child->next() ) { + result = NodeUtilities::lookupReprByValue(child, key, value); + if(result != NULL) { + return result; + } + } + + return NULL; +} +*/ + +Glib::ustring const +NodeUtilities::nodeTypeToString(XML::Node const& node) +{ + switch(node.type()) { + case XML::DOCUMENT_NODE: + return NODETYPE_DOCUMENT_STR; + case XML::ELEMENT_NODE: + return NODETYPE_ELEMENT_STR; + case XML::TEXT_NODE: + return NODETYPE_TEXT_STR; + case XML::COMMENT_NODE: + default: + return NODETYPE_COMMENT_STR; + } +} + +XML::NodeType +NodeUtilities::stringToNodeType(Glib::ustring const& type) +{ + if (type == NODETYPE_DOCUMENT_STR) { + return XML::DOCUMENT_NODE; + } else if (type == NODETYPE_ELEMENT_STR) { + return XML::ELEMENT_NODE; + } else if (type == NODETYPE_TEXT_STR) { + return XML::TEXT_NODE; + } else { + return XML::COMMENT_NODE; + } +} + +std::string const +NodeUtilities::findNodeID(XML::Node const& node, XMLNodeTracker* tracker, NodeToKeyMap const& newnodes) +{ +// g_log(NULL, G_LOG_LEVEL_DEBUG, "Attempting to locate id for %p", &node); + NodeToKeyMap::const_iterator result = newnodes.find(&node); + if (result != newnodes.end()) { +// g_log(NULL, G_LOG_LEVEL_DEBUG, "Located id for %p: %s", &node, (*result).second.c_str()); + return (*result).second; + } + + if (tracker->isTracking(node)) { +// g_log(NULL, G_LOG_LEVEL_DEBUG, "Located id for %p (in tracker): %s", &node, tracker->get(node).c_str()); + return tracker->get(node); + } else { +// g_log(NULL, G_LOG_LEVEL_DEBUG, "Failed to locate id"); + return ""; + } +} + +} + +} + +/* + 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:textwidth=99 : diff --git a/src/jabber_whiteboard/node-utilities.h b/src/jabber_whiteboard/node-utilities.h new file mode 100644 index 000000000..c74027de2 --- /dev/null +++ b/src/jabber_whiteboard/node-utilities.h @@ -0,0 +1,61 @@ +/** + * Whiteboard session manager + * XML node manipulation / retrieval utilities + * + * Authors: + * David Yip + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifndef __WHITEBOARD_NODE_UTILITIES_H__ +#define __WHITEBOARD_NODE_UTILITIES_H__ + +#include "jabber_whiteboard/typedefs.h" +#include "xml/node.h" +#include + +namespace Inkscape { + +namespace XML { + +class Node; + +} + +namespace Whiteboard { + +class XMLNodeTracker; + +class NodeUtilities { +public: + // Node utilities +// static Inkscape::XML::Node* lookupReprByValue(Inkscape::XML::Node* root, gchar const* key, ustring const* value); + static Glib::ustring const nodeTypeToString(XML::Node const& node); + static XML::NodeType stringToNodeType(Glib::ustring const& type); + + // Node key search utility method + static std::string const findNodeID(XML::Node const& node, XMLNodeTracker* tracker, NodeToKeyMap const& newnodes); + +private: + // noncopyable, nonassignable + NodeUtilities(NodeUtilities const&); + NodeUtilities& operator=(NodeUtilities const&); +}; + +} + +} + +#endif + +/* + 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:textwidth=99 : diff --git a/src/jabber_whiteboard/pedrodom.cpp b/src/jabber_whiteboard/pedrodom.cpp new file mode 100644 index 000000000..2ed770a1a --- /dev/null +++ b/src/jabber_whiteboard/pedrodom.cpp @@ -0,0 +1,784 @@ +/* + * Implementation of the Pedro mini-DOM parser and tree + * + * Authors: + * Bob Jamison + * + * Copyright (C) 2005 Bob Jamison + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + + +#include +#include +#include +#ifdef HAVE_MALLOC_H +#include +#endif +#include +#include + + +#include "pedrodom.h" + +namespace Pedro +{ + + + +//######################################################################## +//# E L E M E N T +//######################################################################## + +Element *Element::clone() +{ + Element *elem = new Element(name, value); + elem->parent = parent; + elem->attributes = attributes; + elem->namespaces = namespaces; + + std::vector::iterator iter; + for (iter = children.begin(); iter != children.end() ; iter++) + { + elem->addChild((*iter)->clone()); + } + return elem; +} + + +void Element::findElementsRecursive(std::vector&res, const DOMString &name) +{ + if (getName() == name) + { + res.push_back(this); + } + for (unsigned int i=0; ifindElementsRecursive(res, name); +} + +std::vector Element::findElements(const DOMString &name) +{ + std::vector res; + findElementsRecursive(res, name); + return res; +} + +DOMString Element::getAttribute(const DOMString &name) +{ + for (unsigned int i=0 ; ielems = findElements(tagName); + if (elems.size() <1) + return ""; + DOMString res = elems[0]->getAttribute(attrName); + return res; +} + +DOMString Element::getTagValue(const DOMString &tagName) +{ + std::vectorelems = findElements(tagName); + if (elems.size() <1) + return ""; + DOMString res = elems[0]->getValue(); + return res; +} + +void Element::addChild(Element *child) +{ + if (!child) + return; + child->parent = this; + children.push_back(child); +} + + +void Element::addAttribute(const DOMString &name, const DOMString &value) +{ + Attribute attr(name, value); + attributes.push_back(attr); +} + +void Element::addNamespace(const DOMString &prefix, const DOMString &namespaceURI) +{ + Namespace ns(prefix, namespaceURI); + namespaces.push_back(ns); +} + +void Element::writeIndentedRecursive(FILE *f, int indent) +{ + int i; + if (!f) + return; + //Opening tag, and attributes + for (i=0;i\n"); + + //Between the tags + if (value.size() > 0) + { + for (int i=0;iwriteIndentedRecursive(f, indent+2); + + //Closing tag + for (int i=0; i\n", name.c_str()); +} + +void Element::writeIndented(FILE *f) +{ + writeIndentedRecursive(f, 0); +} + +void Element::print() +{ + writeIndented(stdout); +} + + +//######################################################################## +//# P A R S E R +//######################################################################## + + + +typedef struct + { + char *escaped; + char value; + } EntityEntry; + +static EntityEntry entities[] = +{ + { "&" , '&' }, + { "<" , '<' }, + { ">" , '>' }, + { "'", '\'' }, + { """, '"' }, + { NULL , '\0' } +}; + + + +void Parser::getLineAndColumn(long pos, long *lineNr, long *colNr) +{ + long line = 1; + long col = 1; + for (long i=0 ; i= parselen) + return -1; + currentPosition = pos; + int ch = parsebuf[pos]; + //printf("ch:%c\n", ch); + return ch; +} + + + +DOMString Parser::encode(const DOMString &str) +{ + DOMString ret; + for (unsigned int i=0 ; i') + ret.append(">"); + else if (ch == '\'') + ret.append("'"); + else if (ch == '"') + ret.append("""); + else + ret.push_back(ch); + + } + return ret; +} + + +int Parser::match(long p0, const char *text) +{ + int p = p0; + while (*text) + { + if (peek(p) != *text) + return p0; + p++; text++; + } + return p; +} + + + +int Parser::skipwhite(long p) +{ + + while (p p) + { + p = p2; + while (p"); + if (p2 > p) + { + p = p2; + break; + } + p++; + } + } + XMLCh b = peek(p); + if (!isspace(b)) + break; + p++; + } + return p; +} + +/* modify this to allow all chars for an element or attribute name*/ +int Parser::getWord(int p0, DOMString &buf) +{ + int p = p0; + while (p' || b=='=') + break; + buf.push_back(b); + p++; + } + return p; +} + +int Parser::getQuoted(int p0, DOMString &buf, int do_i_parse) +{ + + int p = p0; + if (peek(p) != '"' && peek(p) != '\'') + return p0; + p++; + + while ( pvalue ; ee++) + { + int p2 = match(p, ee->escaped); + if (p2>p) + { + buf.push_back(ee->value); + p = p2; + found = true; + break; + } + } + if (!found) + { + error("unterminated entity"); + return false; + } + } + else + { + buf.push_back(b); + p++; + } + } + return p; +} + +int Parser::parseVersion(int p0) +{ + //printf("### parseVersion: %d\n", p0); + + int p = p0; + + p = skipwhite(p0); + + if (peek(p) != '<') + return p0; + + p++; + if (p>=parselen || peek(p)!='?') + return p0; + + p++; + + DOMString buf; + + while (p=parselen || peek(p)!='<') + return p0; + + p++; + + if (peek(p)!='!' || peek(p+1)=='-') + return p0; + p++; + + DOMString buf; + while (p') + { + p++; + break; + } + buf.push_back(ch); + p++; + } + + //printf("Got doctype:%s\n",buf.c_str()); + return p; +} + +int Parser::parseElement(int p0, Element *par,int depth) +{ + + int p = p0; + + int p2 = p; + + p = skipwhite(p); + + //## Get open tag + XMLCh ch = peek(p); + if (ch!='<') + return p0; + + p++; + + DOMString openTagName; + p = skipwhite(p); + p = getWord(p, openTagName); + //printf("####tag :%s\n", openTagName.c_str()); + p = skipwhite(p); + + //Add element to tree + Element *n = new Element(openTagName); + n->parent = par; + par->addChild(n); + + // Get attributes + if (peek(p) != '>') + { + while (p') + break; + else if (ch=='/' && p') + { + p++; + //printf("quick close\n"); + return p; + } + } + DOMString attrName; + p2 = getWord(p, attrName); + if (p2==p) + break; + //printf("name:%s",buf); + p=p2; + p = skipwhite(p); + ch = peek(p); + //printf("ch:%c\n",ch); + if (ch!='=') + break; + p++; + p = skipwhite(p); + // ch = parsebuf[p]; + // printf("ch:%c\n",ch); + DOMString attrVal; + p2 = getQuoted(p, attrVal, true); + p=p2+1; + //printf("name:'%s' value:'%s'\n",attrName.c_str(),attrVal.c_str()); + char *namestr = (char *)attrName.c_str(); + if (strncmp(namestr, "xmlns:", 6)==0) + n->addNamespace(attrName, attrVal); + else + n->addAttribute(attrName, attrVal); + } + } + + bool cdata = false; + + p++; + // ### Get intervening data ### */ + DOMString data; + while (pp) + { + p = p2; + while (p"); + if (p2 > p) + { + p = p2; + break; + } + p++; + } + } + + ch = peek(p); + //# END TAG + if (ch=='<' && !cdata && peek(p+1)=='/') + { + break; + } + //# CDATA + p2 = match(p, " p) + { + cdata = true; + p = p2; + continue; + } + + //# CHILD ELEMENT + if (ch == '<') + { + p2 = parseElement(p, n, depth+1); + if (p2 == p) + { + /* + printf("problem on element:%s. p2:%d p:%d\n", + openTagName.c_str(), p2, p); + */ + return p0; + } + p = p2; + continue; + } + //# ENTITY + if (ch=='&' && !cdata) + { + bool found = false; + for (EntityEntry *ee = entities ; ee->value ; ee++) + { + int p2 = match(p, ee->escaped); + if (p2>p) + { + data.push_back(ee->value); + p = p2; + found = true; + break; + } + } + if (!found) + { + error("unterminated entity"); + return -1; + } + continue; + } + + //# NONE OF THE ABOVE + data.push_back(ch); + p++; + }/*while*/ + + + n->value = data; + //printf("%d : data:%s\n",p,data.c_str()); + + //## Get close tag + p = skipwhite(p); + ch = peek(p); + if (ch != '<') + { + error("no < for end tag\n"); + return p0; + } + p++; + ch = peek(p); + if (ch != '/') + { + error("no / on end tag"); + return p0; + } + p++; + ch = peek(p); + p = skipwhite(p); + DOMString closeTagName; + p = getWord(p, closeTagName); + if (openTagName != closeTagName) + { + error("Mismatched closing tag. Expected . Got '%S'.", + openTagName.c_str(), closeTagName.c_str()); + return p0; + } + p = skipwhite(p); + if (peek(p) != '>') + { + error("no > on end tag for '%s'", closeTagName.c_str()); + return p0; + } + p++; + // printf("close element:%s\n",closeTagName.c_str()); + p = skipwhite(p); + return p; +} + + + + +Element *Parser::parse(XMLCh *buf,int pos,int len) +{ + parselen = len; + parsebuf = buf; + Element *rootNode = new Element("root"); + pos = parseVersion(pos); + pos = parseDoctype(pos); + pos = parseElement(pos, rootNode, 0); + return rootNode; +} + + +Element *Parser::parse(const char *buf, int pos, int len) +{ + + XMLCh *charbuf = (XMLCh *)malloc((len+1) * sizeof(XMLCh)); + long i = 0; + while (i< len) + { + charbuf[i] = (XMLCh)buf[i]; + i++; + } + charbuf[i] = '\0'; + Element *n = parse(charbuf, 0, len); + free(charbuf); + return n; +} + +Element *Parser::parse(const DOMString &buf) +{ + long len = buf.size(); + XMLCh *charbuf = (XMLCh *)malloc((len+1) * sizeof(XMLCh)); + long i = 0; + while (i< len) + { + charbuf[i] = (XMLCh)buf[i]; + i++; + } + charbuf[i] = '\0'; + Element *n = parse(charbuf, 0, len); + free(charbuf); + return n; +} + +Element *Parser::parseFile(const char *fileName) +{ + + //##### LOAD INTO A CHAR BUF, THEN CONVERT TO XMLCh + if (!fileName) + return NULL; + + FILE *f = fopen(fileName, "rb"); + if (!f) + return NULL; + + struct stat statBuf; + if (fstat(fileno(f),&statBuf)<0) + { + fclose(f); + return NULL; + } + long filelen = statBuf.st_size; + + //printf("length:%d\n",filelen); + XMLCh *charbuf = (XMLCh *)malloc((filelen+1) * sizeof(XMLCh)); + for (XMLCh *p=charbuf ; !feof(f) ; p++) + { + *p = (XMLCh)fgetc(f); + } + fclose(f); + charbuf[filelen] = '\0'; + + + /* + printf("nrbytes:%d\n",wc_count); + printf("buf:%ls\n======\n",charbuf); + */ + Element *n = parse(charbuf, 0, filelen); + free(charbuf); + return n; +} + + + + + + + +}//namespace Pedro + +#if 0 +//######################################################################## +//# T E S T +//######################################################################## + +bool doTest(char *fileName) +{ + Pedro::Parser parser; + + Pedro::Element *elem = parser.parseFile(fileName); + + if (!elem) + { + printf("Parsing failed\n"); + return false; + } + + elem->print(); + + delete elem; + + return true; +} + + + +int main(int argc, char **argv) +{ + if (argc != 2) + { + printf("usage: %s \n", argv[0]); + return 1; + } + + if (!doTest(argv[1])) + return 1; + + return 0; +} + +#endif + +//######################################################################## +//# E N D O F F I L E +//######################################################################## + + diff --git a/src/jabber_whiteboard/pedrodom.h b/src/jabber_whiteboard/pedrodom.h new file mode 100644 index 000000000..cd10f80c0 --- /dev/null +++ b/src/jabber_whiteboard/pedrodom.h @@ -0,0 +1,308 @@ +#ifndef __PEDRODOM_H__ +#define __PEDRODOM_H__ +/* + * API for the Pedro mini-DOM parser and tree + * + * Authors: + * Bob Jamison + * + * Copyright (C) 2005 Bob Jamison + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include + + +namespace Pedro +{ +typedef std::string DOMString; +typedef unsigned int XMLCh; + + +class Namespace +{ +public: + Namespace() + {} + + Namespace(const DOMString &prefixArg, const DOMString &namespaceURIArg) + { + prefix = prefixArg; + namespaceURI = namespaceURIArg; + } + + Namespace(const Namespace &other) + { + prefix = other.prefix; + namespaceURI = other.namespaceURI; + } + + virtual ~Namespace() + {} + + virtual DOMString getPrefix() + { return prefix; } + + virtual DOMString getNamespaceURI() + { return namespaceURI; } + +protected: + + DOMString prefix; + DOMString namespaceURI; + +}; + +class Attribute +{ +public: + Attribute() + {} + + Attribute(const DOMString &nameArg, const DOMString &valueArg) + { + name = nameArg; + value = valueArg; + } + + Attribute(const Attribute &other) + { + name = other.name; + value = other.value; + } + + virtual ~Attribute() + {} + + virtual DOMString getName() + { return name; } + + virtual DOMString getValue() + { return value; } + +protected: + + DOMString name; + DOMString value; + +}; + + +class Element +{ +friend class Parser; + +public: + Element() + { + parent = NULL; + } + + Element(const DOMString &nameArg) + { + parent = NULL; + name = nameArg; + } + + Element(const DOMString &nameArg, const DOMString &valueArg) + { + parent = NULL; + name = nameArg; + value = valueArg; + } + + Element(const Element &other) + { + parent = other.parent; + children = other.children; + attributes = other.attributes; + namespaces = other.namespaces; + name = other.name; + value = other.value; + } + + virtual Element *clone(); + + virtual ~Element() + { + for (unsigned int i=0 ; i getChildren() + { return children; } + + std::vector findElements(const DOMString &name); + + DOMString getAttribute(const DOMString &name); + + DOMString getTagAttribute(const DOMString &tagName, const DOMString &attrName); + + DOMString getTagValue(const DOMString &tagName); + + void addChild(Element *child); + + void addAttribute(const DOMString &name, const DOMString &value); + + void addNamespace(const DOMString &prefix, const DOMString &namespaceURI); + + + /** + * Prettyprint an XML tree to an output stream. Elements are indented + * according to element hierarchy. + * @param f a stream to receive the output + * @param elem the element to output + */ + void writeIndented(FILE *f); + + /** + * Prettyprint an XML tree to standard output. This is the equivalent of + * writeIndented(stdout). + * @param elem the element to output + */ + void print(); + +protected: + + + void findElementsRecursive(std::vector&res, const DOMString &name); + + void writeIndentedRecursive(FILE *f, int indent); + + Element *parent; + + std::vectorchildren; + + std::vector attributes; + std::vector namespaces; + + DOMString name; + DOMString value; + +}; + + + + + +class Parser +{ +public: + Parser() + { init(); } + + virtual ~Parser() + {} + + /** + * Parse XML in a char buffer. + * @param buf a character buffer to parse + * @param pos position to start parsing + * @param len number of chars, from pos, to parse. + * @return a pointer to the root of the XML document; + */ + Element *parse(const char *buf,int pos,int len); + + /** + * Parse XML in a char buffer. + * @param buf a character buffer to parse + * @param pos position to start parsing + * @param len number of chars, from pos, to parse. + * @return a pointer to the root of the XML document; + */ + Element *parse(const DOMString &buf); + + /** + * Parse a named XML file. The file is loaded like a data file; + * the original format is not preserved. + * @param fileName the name of the file to read + * @return a pointer to the root of the XML document; + */ + Element *parseFile(const char *fileName); + + /** + * Utility method to preprocess a string for XML + * output, escaping its entities. + * @param str the string to encode + */ + static DOMString encode(const DOMString &str); + + +private: + + void init() + { + keepGoing = true; + currentNode = NULL; + parselen = 0; + parsebuf = NULL; + currentPosition = 0; + } + + void getLineAndColumn(long pos, long *lineNr, long *colNr); + + void error(char *fmt, ...); + + int peek(long pos); + + int match(long pos, const char *text); + + int skipwhite(long p); + + int getWord(int p0, DOMString &buf); + + int getQuoted(int p0, DOMString &buf, int do_i_parse); + + int parseVersion(int p0); + + int parseDoctype(int p0); + + int parseElement(int p0, Element *par,int depth); + + Element *parse(XMLCh *buf,int pos,int len); + + bool keepGoing; + Element *currentNode; + long parselen; + XMLCh *parsebuf; + DOMString cdatabuf; + long currentPosition; + int colNr; + + +}; + + + +}//namespace Pedro + + +#endif /* __PEDRODOM_H__ */ + +//######################################################################## +//# E N D O F F I L E +//######################################################################## + diff --git a/src/jabber_whiteboard/pedroxmpp.cpp b/src/jabber_whiteboard/pedroxmpp.cpp new file mode 100644 index 000000000..0429a172f --- /dev/null +++ b/src/jabber_whiteboard/pedroxmpp.cpp @@ -0,0 +1,4786 @@ +/* + * Implementation the Pedro mini-XMPP client + * + * Authors: + * Bob Jamison + * + * Copyright (C) 2005 Bob Jamison + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + +#include +#include + +#include + +#include "pedroxmpp.h" +#include "pedrodom.h" + +#ifdef __WIN32__ + +#include + +#else /* UNIX */ + +#include +#include +#include +#include +#include +#include + +#include + +#endif + +#ifdef WITH_SSL +#include +#include +#endif + + +namespace Pedro +{ + +//######################################################################## +//######################################################################## +//### U T I L I T Y +//######################################################################## +//######################################################################## + + +//######################################################################## +//# B A S E 6 4 +//######################################################################## + +//################# +//# ENCODER +//################# + + +static char *base64encode = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +/** + * This class is for Base-64 encoding + */ +class Base64Encoder +{ + +public: + + Base64Encoder() + { + reset(); + } + + virtual ~Base64Encoder() + {} + + virtual void reset() + { + outBuf = 0L; + bitCount = 0; + buf = ""; + } + + virtual void append(int ch); + + virtual void append(char *str); + + virtual void append(unsigned char *str, int len); + + virtual void append(const DOMString &str); + + virtual DOMString finish(); + + static DOMString encode(const DOMString &str); + + +private: + + + unsigned long outBuf; + + int bitCount; + + DOMString buf; + +}; + + + +/** + * Writes the specified byte to the output buffer + */ +void Base64Encoder::append(int ch) +{ + outBuf <<= 8; + outBuf |= (ch & 0xff); + bitCount += 8; + if (bitCount >= 24) + { + int indx = (int)((outBuf & 0x00fc0000L) >> 18); + int obyte = (int)base64encode[indx & 63]; + buf.push_back(obyte); + + indx = (int)((outBuf & 0x0003f000L) >> 12); + obyte = (int)base64encode[indx & 63]; + buf.push_back(obyte); + + indx = (int)((outBuf & 0x00000fc0L) >> 6); + obyte = (int)base64encode[indx & 63]; + buf.push_back(obyte); + + indx = (int)((outBuf & 0x0000003fL) ); + obyte = (int)base64encode[indx & 63]; + buf.push_back(obyte); + + bitCount = 0; + outBuf = 0L; + } +} + +/** + * Writes the specified string to the output buffer + */ +void Base64Encoder::append(char *str) +{ + while (*str) + append((int)*str++); +} + +/** + * Writes the specified string to the output buffer + */ +void Base64Encoder::append(unsigned char *str, int len) +{ + while (len>0) + { + append((int)*str++); + len--; + } +} + +/** + * Writes the specified string to the output buffer + */ +void Base64Encoder::append(const DOMString &str) +{ + append((char *)str.c_str()); +} + +/** + * Closes this output stream and releases any system resources + * associated with this stream. + */ +DOMString Base64Encoder::finish() +{ + //get any last bytes (1 or 2) out of the buffer + if (bitCount == 16) + { + outBuf <<= 2; //pad to make 18 bits + + int indx = (int)((outBuf & 0x0003f000L) >> 12); + int obyte = (int)base64encode[indx & 63]; + buf.push_back(obyte); + + indx = (int)((outBuf & 0x00000fc0L) >> 6); + obyte = (int)base64encode[indx & 63]; + buf.push_back(obyte); + + indx = (int)((outBuf & 0x0000003fL) ); + obyte = (int)base64encode[indx & 63]; + buf.push_back(obyte); + + buf.push_back('='); + } + else if (bitCount == 8) + { + outBuf <<= 4; //pad to make 12 bits + + int indx = (int)((outBuf & 0x00000fc0L) >> 6); + int obyte = (int)base64encode[indx & 63]; + buf.push_back(obyte); + + indx = (int)((outBuf & 0x0000003fL) ); + obyte = (int)base64encode[indx & 63]; + buf.push_back(obyte); + + buf.push_back('='); + buf.push_back('='); + } + + DOMString ret = buf; + reset(); + return ret; +} + + +DOMString Base64Encoder::encode(const DOMString &str) +{ + Base64Encoder encoder; + encoder.append(str); + DOMString ret = encoder.finish(); + return ret; +} + + + +//################# +//# DECODER +//################# + +static int base64decode[] = +{ +/*00*/ -1, -1, -1, -1, -1, -1, -1, -1, +/*08*/ -1, -1, -1, -1, -1, -1, -1, -1, +/*10*/ -1, -1, -1, -1, -1, -1, -1, -1, +/*18*/ -1, -1, -1, -1, -1, -1, -1, -1, +/*20*/ -1, -1, -1, -1, -1, -1, -1, -1, +/*28*/ -1, -1, -1, 62, -1, -1, -1, 63, +/*30*/ 52, 53, 54, 55, 56, 57, 58, 59, +/*38*/ 60, 61, -1, -1, -1, -1, -1, -1, +/*40*/ -1, 0, 1, 2, 3, 4, 5, 6, +/*48*/ 7, 8, 9, 10, 11, 12, 13, 14, +/*50*/ 15, 16, 17, 18, 19, 20, 21, 22, +/*58*/ 23, 24, 25, -1, -1, -1, -1, -1, +/*60*/ -1, 26, 27, 28, 29, 30, 31, 32, +/*68*/ 33, 34, 35, 36, 37, 38, 39, 40, +/*70*/ 41, 42, 43, 44, 45, 46, 47, 48, +/*78*/ 49, 50, 51, -1, -1, -1, -1, -1 +}; + +class Base64Decoder +{ +public: + Base64Decoder() + { + reset(); + } + + virtual ~Base64Decoder() + {} + + virtual void reset() + { + inCount = 0; + buf.clear(); + } + + + virtual void append(int ch); + + virtual void append(char *str); + + virtual void append(const DOMString &str); + + std::vector finish(); + + static std::vector decode(const DOMString &str); + + static DOMString decodeToString(const DOMString &str); + +private: + + int inBytes[4]; + int inCount; + std::vector buf; +}; + +/** + * Appends one char to the decoder + */ +void Base64Decoder::append(int ch) +{ + if (isspace(ch)) + return; + else if (ch == '=') //padding + { + inBytes[inCount++] = 0; + } + else + { + int byteVal = base64decode[ch & 0x7f]; + //printf("char:%c %d\n", ch, byteVal); + if (byteVal < 0) + { + //Bad lookup value + } + inBytes[inCount++] = byteVal; + } + + if (inCount >=4 ) + { + unsigned char b0 = ((inBytes[0]<<2) & 0xfc) | ((inBytes[1]>>4) & 0x03); + unsigned char b1 = ((inBytes[1]<<4) & 0xf0) | ((inBytes[2]>>2) & 0x0f); + unsigned char b2 = ((inBytes[2]<<6) & 0xc0) | ((inBytes[3] ) & 0x3f); + buf.push_back(b0); + buf.push_back(b1); + buf.push_back(b2); + inCount = 0; + } + +} + +void Base64Decoder::append(char *str) +{ + while (*str) + append((int)*str++); +} + +void Base64Decoder::append(const DOMString &str) +{ + append((char *)str.c_str()); +} + +std::vector Base64Decoder::finish() +{ + std::vector ret = buf; + reset(); + return ret; +} + +std::vector Base64Decoder::decode(const DOMString &str) +{ + Base64Decoder decoder; + decoder.append(str); + std::vector ret = decoder.finish(); + return ret; +} + +DOMString Base64Decoder::decodeToString(const DOMString &str) +{ + Base64Decoder decoder; + decoder.append(str); + std::vector ret = decoder.finish(); + DOMString buf; + for (unsigned int i=0 ; i>4) & 15 ]); + ret.push_back(sha1hex[ ch & 15 ]); + } + return ret; +} + + +void Sha1::init() +{ + + lenW = 0; + sizeHi = 0; + sizeLo = 0; + + // Initialize H with the magic constants (see FIPS180 for constants) + H[0] = 0x67452301L; + H[1] = 0xefcdab89L; + H[2] = 0x98badcfeL; + H[3] = 0x10325476L; + H[4] = 0xc3d2e1f0L; + + for (int i = 0; i < 80; i++) + W[i] = 0; +} + + +void Sha1::append(unsigned char *dataIn, int len) +{ + // Read the data into W and process blocks as they get full + for (int i = 0; i < len; i++) + { + W[lenW / 4] <<= 8; + W[lenW / 4] |= (unsigned long)dataIn[i]; + if ((++lenW) % 64 == 0) + { + hashblock(); + lenW = 0; + } + sizeLo += 8; + sizeHi += (sizeLo < 8); + } +} + + +void Sha1::finish(unsigned char hashout[20]) +{ + unsigned char pad0x80 = 0x80; + unsigned char pad0x00 = 0x00; + unsigned char padlen[8]; + + // Pad with a binary 1 (e.g. 0x80), then zeroes, then length + padlen[0] = (unsigned char)((sizeHi >> 24) & 255); + padlen[1] = (unsigned char)((sizeHi >> 16) & 255); + padlen[2] = (unsigned char)((sizeHi >> 8) & 255); + padlen[3] = (unsigned char)((sizeHi >> 0) & 255); + padlen[4] = (unsigned char)((sizeLo >> 24) & 255); + padlen[5] = (unsigned char)((sizeLo >> 16) & 255); + padlen[6] = (unsigned char)((sizeLo >> 8) & 255); + padlen[7] = (unsigned char)((sizeLo >> 0) & 255); + + append(&pad0x80, 1); + + while (lenW != 56) + append(&pad0x00, 1); + append(padlen, 8); + + // Output hash + for (int i = 0; i < 20; i++) + { + hashout[i] = (unsigned char)(H[i / 4] >> 24); + H[i / 4] <<= 8; + } + + // Re-initialize the context (also zeroizes contents) + init(); +} + + +#define SHA_ROTL(X,n) ((((X) << (n)) | ((X) >> (32-(n)))) & 0xffffffffL) + +void Sha1::hashblock() +{ + + for (int t = 16; t <= 79; t++) + W[t] = SHA_ROTL(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16], 1); + + unsigned long A = H[0]; + unsigned long B = H[1]; + unsigned long C = H[2]; + unsigned long D = H[3]; + unsigned long E = H[4]; + + unsigned long TEMP; + + for (int t = 0; t <= 19; t++) + { + TEMP = (SHA_ROTL(A,5) + (((C^D)&B)^D) + + E + W[t] + 0x5a827999L) & 0xffffffffL; + E = D; D = C; C = SHA_ROTL(B, 30); B = A; A = TEMP; + } + for (int t = 20; t <= 39; t++) + { + TEMP = (SHA_ROTL(A,5) + (B^C^D) + + E + W[t] + 0x6ed9eba1L) & 0xffffffffL; + E = D; D = C; C = SHA_ROTL(B, 30); B = A; A = TEMP; + } + for (int t = 40; t <= 59; t++) + { + TEMP = (SHA_ROTL(A,5) + ((B&C)|(D&(B|C))) + + E + W[t] + 0x8f1bbcdcL) & 0xffffffffL; + E = D; D = C; C = SHA_ROTL(B, 30); B = A; A = TEMP; + } + for (int t = 60; t <= 79; t++) + { + TEMP = (SHA_ROTL(A,5) + (B^C^D) + + E + W[t] + 0xca62c1d6L) & 0xffffffffL; + E = D; D = C; C = SHA_ROTL(B, 30); B = A; A = TEMP; + } + + H[0] += A; + H[1] += B; + H[2] += C; + H[3] += D; + H[4] += E; +} + + + + + +//######################################################################## +//# M D 5 +//######################################################################## + +class Md5 +{ +public: + + /** + * + */ + Md5() + { init(); } + + /** + * + */ + virtual ~Md5() + {} + + /** + * Static convenience method. + * @parm digest points to an buffer of 16 unsigned chars + */ + static void hash(unsigned char *dataIn, + unsigned long len, unsigned char *digest); + + static DOMString hashHex(unsigned char *dataIn, unsigned long len); + + /** + * Initialize the context (also zeroizes contents) + */ + virtual void init(); + + /** + * + */ + virtual void append(unsigned char *dataIn, unsigned long len); + + /** + * + */ + virtual void append(const DOMString &str); + + /** + * Finalize and output the hash. + * @parm digest points to an buffer of 16 unsigned chars + */ + virtual void finish(unsigned char *digest); + + + /** + * Same as above , but hex to an output String + */ + virtual DOMString finishHex(); + +private: + + void transform(unsigned long *buf, unsigned long *in); + + unsigned long buf[4]; + unsigned long bits[2]; + unsigned char in[64]; + +}; + + + + +void Md5::hash(unsigned char *dataIn, unsigned long len, unsigned char *digest) +{ + Md5 md5; + md5.append(dataIn, len); + md5.finish(digest); +} + +DOMString Md5::hashHex(unsigned char *dataIn, unsigned long len) +{ + Md5 md5; + md5.append(dataIn, len); + DOMString ret = md5.finishHex(); + return ret; +} + + + +/* + * Note: this code is harmless on little-endian machines. + */ +/* +static void byteReverse(unsigned char *buf, unsigned long longs) +{ + do + { + unsigned long t = (unsigned long) + ((unsigned) buf[3] << 8 | buf[2]) << 16 | + ((unsigned) buf[1] << 8 | buf[0]); + *(unsigned long *) buf = t; + buf += 4; + } while (--longs); +} +*/ + +static void md5_memcpy(void *dest, void *src, int n) +{ + unsigned char *s1 = (unsigned char *)dest; + unsigned char *s2 = (unsigned char *)src; + while (n--) + *s1++ = *s2++; +} + +static void md5_memset(void *dest, char v, int n) +{ + unsigned char *s = (unsigned char *)dest; + while (n--) + *s++ = v; +} + +/** + * Initialize MD5 polynomials and storage + */ +void Md5::init() +{ + buf[0] = 0x67452301; + buf[1] = 0xefcdab89; + buf[2] = 0x98badcfe; + buf[3] = 0x10325476; + + bits[0] = 0; + bits[1] = 0; +} + +/* + * Update context to reflect the concatenation of another buffer full + * of bytes. + */ +void Md5::append(unsigned char *source, unsigned long len) +{ + + // Update bitcount + unsigned long t = bits[0]; + if ((bits[0] = t + ((unsigned long) len << 3)) < t) + bits[1]++;// Carry from low to high + bits[1] += len >> 29; + + //Bytes already in shsInfo->data + t = (t >> 3) & 0x3f; + + + // Handle any leading odd-sized chunks + if (t) + { + unsigned char *p = (unsigned char *) in + t; + t = 64 - t; + if (len < t) + { + md5_memcpy(p, source, len); + return; + } + md5_memcpy(p, source, t); + //byteReverse(in, 16); + transform(buf, (unsigned long *) in); + source += t; + len -= t; + } + + // Process data in 64-byte chunks + while (len >= 64) + { + md5_memcpy(in, source, 64); + //byteReverse(in, 16); + transform(buf, (unsigned long *) in); + source += 64; + len -= 64; + } + + // Handle any remaining bytes of data. + md5_memcpy(in, source, len); +} + +/* + * Update context to reflect the concatenation of another string + */ +void Md5::append(const DOMString &str) +{ + append((unsigned char *)str.c_str(), str.size()); +} + +/* + * Final wrapup - pad to 64-byte boundary with the bit pattern + * 1 0* (64-bit count of bits processed, MSB-first) + */ +void Md5::finish(unsigned char *digest) +{ + // Compute number of bytes mod 64 + unsigned int count = (bits[0] >> 3) & 0x3F; + + // Set the first char of padding to 0x80. + // This is safe since there is always at least one byte free + unsigned char *p = in + count; + *p++ = 0x80; + + // Bytes of padding needed to make 64 bytes + count = 64 - 1 - count; + + // Pad out to 56 mod 64 + if (count < 8) + { + // Two lots of padding: Pad the first block to 64 bytes + md5_memset(p, 0, count); + //byteReverse(in, 16); + transform(buf, (unsigned long *) in); + + // Now fill the next block with 56 bytes + md5_memset(in, 0, 56); + } + else + { + // Pad block to 56 bytes + md5_memset(p, 0, count - 8); + } + //byteReverse(in, 14); + + // Append length in bits and transform + ((unsigned long *) in)[14] = bits[0]; + ((unsigned long *) in)[15] = bits[1]; + + transform(buf, (unsigned long *) in); + //byteReverse((unsigned char *) buf, 4); + md5_memcpy(digest, buf, 16); + init(); // Security! ;-) +} + +static char *md5hex = "0123456789abcdef"; + +DOMString Md5::finishHex() +{ + unsigned char hashout[16]; + finish(hashout); + DOMString ret; + for (int i=0 ; i<16 ; i++) + { + unsigned char ch = hashout[i]; + ret.push_back(md5hex[ (ch>>4) & 15 ]); + ret.push_back(md5hex[ ch & 15 ]); + } + return ret; +} + + + +//# The four core functions - F1 is optimized somewhat + +// #define F1(x, y, z) (x & y | ~x & z) +#define F1(x, y, z) (z ^ (x & (y ^ z))) +#define F2(x, y, z) F1(z, x, y) +#define F3(x, y, z) (x ^ y ^ z) +#define F4(x, y, z) (y ^ (x | ~z)) + +// ## This is the central step in the MD5 algorithm. +#define MD5STEP(f, w, x, y, z, data, s) \ + ( w += f(x, y, z) + data, w = w<>(32-s), w += x ) + +/* + * The core of the MD5 algorithm, this alters an existing MD5 hash to + * reflect the addition of 16 longwords of new data. MD5Update blocks + * the data and converts bytes into longwords for this routine. + * @parm buf points to an array of 4 unsigned longs + * @parm in points to an array of 16 unsigned longs + */ +void Md5::transform(unsigned long *buf, unsigned long *in) +{ + unsigned long a = buf[0]; + unsigned long b = buf[1]; + unsigned long c = buf[2]; + unsigned long d = buf[3]; + + MD5STEP(F1, a, b, c, d, in[ 0] + 0xd76aa478, 7); + MD5STEP(F1, d, a, b, c, in[ 1] + 0xe8c7b756, 12); + MD5STEP(F1, c, d, a, b, in[ 2] + 0x242070db, 17); + MD5STEP(F1, b, c, d, a, in[ 3] + 0xc1bdceee, 22); + MD5STEP(F1, a, b, c, d, in[ 4] + 0xf57c0faf, 7); + MD5STEP(F1, d, a, b, c, in[ 5] + 0x4787c62a, 12); + MD5STEP(F1, c, d, a, b, in[ 6] + 0xa8304613, 17); + MD5STEP(F1, b, c, d, a, in[ 7] + 0xfd469501, 22); + MD5STEP(F1, a, b, c, d, in[ 8] + 0x698098d8, 7); + MD5STEP(F1, d, a, b, c, in[ 9] + 0x8b44f7af, 12); + MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); + MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); + MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); + MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); + MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); + MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); + + MD5STEP(F2, a, b, c, d, in[ 1] + 0xf61e2562, 5); + MD5STEP(F2, d, a, b, c, in[ 6] + 0xc040b340, 9); + MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); + MD5STEP(F2, b, c, d, a, in[ 0] + 0xe9b6c7aa, 20); + MD5STEP(F2, a, b, c, d, in[ 5] + 0xd62f105d, 5); + MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); + MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); + MD5STEP(F2, b, c, d, a, in[ 4] + 0xe7d3fbc8, 20); + MD5STEP(F2, a, b, c, d, in[ 9] + 0x21e1cde6, 5); + MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); + MD5STEP(F2, c, d, a, b, in[ 3] + 0xf4d50d87, 14); + MD5STEP(F2, b, c, d, a, in[ 8] + 0x455a14ed, 20); + MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); + MD5STEP(F2, d, a, b, c, in[ 2] + 0xfcefa3f8, 9); + MD5STEP(F2, c, d, a, b, in[ 7] + 0x676f02d9, 14); + MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); + + MD5STEP(F3, a, b, c, d, in[ 5] + 0xfffa3942, 4); + MD5STEP(F3, d, a, b, c, in[ 8] + 0x8771f681, 11); + MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); + MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); + MD5STEP(F3, a, b, c, d, in[ 1] + 0xa4beea44, 4); + MD5STEP(F3, d, a, b, c, in[ 4] + 0x4bdecfa9, 11); + MD5STEP(F3, c, d, a, b, in[ 7] + 0xf6bb4b60, 16); + MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); + MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); + MD5STEP(F3, d, a, b, c, in[ 0] + 0xeaa127fa, 11); + MD5STEP(F3, c, d, a, b, in[ 3] + 0xd4ef3085, 16); + MD5STEP(F3, b, c, d, a, in[ 6] + 0x04881d05, 23); + MD5STEP(F3, a, b, c, d, in[ 9] + 0xd9d4d039, 4); + MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); + MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); + MD5STEP(F3, b, c, d, a, in[ 2] + 0xc4ac5665, 23); + + MD5STEP(F4, a, b, c, d, in[ 0] + 0xf4292244, 6); + MD5STEP(F4, d, a, b, c, in[ 7] + 0x432aff97, 10); + MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); + MD5STEP(F4, b, c, d, a, in[ 5] + 0xfc93a039, 21); + MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); + MD5STEP(F4, d, a, b, c, in[ 3] + 0x8f0ccc92, 10); + MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); + MD5STEP(F4, b, c, d, a, in[ 1] + 0x85845dd1, 21); + MD5STEP(F4, a, b, c, d, in[ 8] + 0x6fa87e4f, 6); + MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); + MD5STEP(F4, c, d, a, b, in[ 6] + 0xa3014314, 15); + MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); + MD5STEP(F4, a, b, c, d, in[ 4] + 0xf7537e82, 6); + MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); + MD5STEP(F4, c, d, a, b, in[ 2] + 0x2ad7d2bb, 15); + MD5STEP(F4, b, c, d, a, in[ 9] + 0xeb86d391, 21); + + buf[0] += a; + buf[1] += b; + buf[2] += c; + buf[3] += d; +} + + + + + + + +//######################################################################## +//######################################################################## +//### T H R E A D +//######################################################################## +//######################################################################## + + +//######################################################################## +//### T H R E A D +//######################################################################## + +/** + * This is the interface for a delegate class which can + * be run by a Thread. + * Thread thread(runnable); + * thread.start(); + */ +class Runnable +{ +public: + + Runnable() + {} + virtual ~Runnable() + {} + + /** + * The method of a delegate class which can + * be run by a Thread. Thread is completed when this + * method is done. + */ + virtual void run() = 0; + +}; + + + +/** + * A simple wrapper of native threads in a portable class. + * It can be used either to execute its own run() method, or + * delegate to a Runnable class's run() method. + */ +class Thread +{ +public: + + /** + * Create a thread which will execute its own run() method. + */ + Thread() + { runnable = NULL ; started = false; } + + /** + * Create a thread which will run a Runnable class's run() method. + */ + Thread(const Runnable &runner) + { runnable = (Runnable *)&runner; started = false; } + + /** + * This does not kill a spawned thread. + */ + virtual ~Thread() + {} + + /** + * Static method to pause the current thread for a given + * number of milliseconds. + */ + static void sleep(unsigned long millis); + + /** + * This method will be executed if the Thread was created with + * no delegated Runnable class. The thread is completed when + * the method is done. + */ + virtual void run() + {} + + /** + * Starts the thread. + */ + virtual void start(); + + /** + * Calls either this class's run() method, or that of a Runnable. + * A user would normally not call this directly. + */ + virtual void execute() + { + started = true; + if (runnable) + runnable->run(); + else + run(); + } + +private: + + Runnable *runnable; + + bool started; + +}; + + + + + +#ifdef __WIN32__ + + +static DWORD WINAPI WinThreadFunction(LPVOID context) +{ + Thread *thread = (Thread *)context; + thread->execute(); +} + + +void Thread::start() +{ + DWORD dwThreadId; + HANDLE hThread = CreateThread(NULL, 0, WinThreadFunction, + (LPVOID)this, 0, &dwThreadId); + //Make sure the thread is started before 'this' is deallocated + while (!started) + sleep(10); + CloseHandle(hThread); +} + +void Thread::sleep(unsigned long millis) +{ + Sleep(millis); +} + +#else /* UNIX */ + + +void *PthreadThreadFunction(void *context) +{ + Thread *thread = (Thread *)context; + thread->execute(); + return NULL; +} + + +void Thread::start() +{ + pthread_t thread; + + int ret = pthread_create(&thread, NULL, + PthreadThreadFunction, (void *)this); + if (ret != 0) + printf("Thread::start: thread creation failed: %s\n", strerror(ret)); + + //Make sure the thread is started before 'this' is deallocated + while (!started) + sleep(10); + +} + +void Thread::sleep(unsigned long millis) +{ + timespec requested; + requested.tv_sec = millis / 1000; + requested.tv_nsec = (millis % 1000 ) * 1000000L; + nanosleep(&requested, NULL); +} + +#endif + + +//######################################################################## +//######################################################################## +//### S O C K E T +//######################################################################## +//######################################################################## + + + + + +class TcpSocket +{ +public: + + TcpSocket(); + + TcpSocket(const std::string &hostname, int port); + + TcpSocket(const char *hostname, int port); + + TcpSocket(const TcpSocket &other); + + virtual ~TcpSocket(); + + bool isConnected(); + + void enableSSL(bool val); + + bool connect(const std::string &hostname, int portno); + + bool connect(const char *hostname, int portno); + + bool startTls(); + + bool connect(); + + bool disconnect(); + + bool setReceiveTimeout(unsigned long millis); + + long available(); + + bool write(int ch); + + bool write(char *str); + + bool write(const std::string &str); + + int read(); + + std::string readLine(); + +private: + void init(); + + std::string hostname; + int portno; + int sock; + bool connected; + + bool sslEnabled; + + unsigned long receiveTimeout; + +#ifdef WITH_SSL + SSL_CTX *sslContext; + SSL *sslStream; +#endif + +}; + + + +//######################################################################### +//# U T I L I T Y +//######################################################################### + +static void mybzero(void *s, size_t n) +{ + unsigned char *p = (unsigned char *)s; + while (n > 0) + { + *p++ = (unsigned char)0; + n--; + } +} + +static void mybcopy(void *src, void *dest, size_t n) +{ + unsigned char *p = (unsigned char *)dest; + unsigned char *q = (unsigned char *)src; + while (n > 0) + { + *p++ = *q++; + n--; + } +} + + + +//######################################################################### +//# T C P C O N N E C T I O N +//######################################################################### + +TcpSocket::TcpSocket() +{ + init(); +} + + +TcpSocket::TcpSocket(const char *hostnameArg, int port) +{ + init(); + hostname = hostnameArg; + portno = port; +} + +TcpSocket::TcpSocket(const std::string &hostnameArg, int port) +{ + init(); + hostname = hostnameArg; + portno = port; +} + + +#ifdef WITH_SSL + +static void cryptoLockCallback(int mode, int type, const char *file, int line) +{ + //printf("########### LOCK\n"); + static int modes[CRYPTO_NUM_LOCKS]; /* = {0, 0, ... } */ + const char *errstr = NULL; + + int rw = mode & (CRYPTO_READ|CRYPTO_WRITE); + if (!((rw == CRYPTO_READ) || (rw == CRYPTO_WRITE))) + { + errstr = "invalid mode"; + goto err; + } + + if (type < 0 || type >= CRYPTO_NUM_LOCKS) + { + errstr = "type out of bounds"; + goto err; + } + + if (mode & CRYPTO_LOCK) + { + if (modes[type]) + { + errstr = "already locked"; + /* must not happen in a single-threaded program + * (would deadlock) + */ + goto err; + } + + modes[type] = rw; + } + else if (mode & CRYPTO_UNLOCK) + { + if (!modes[type]) + { + errstr = "not locked"; + goto err; + } + + if (modes[type] != rw) + { + errstr = (rw == CRYPTO_READ) ? + "CRYPTO_r_unlock on write lock" : + "CRYPTO_w_unlock on read lock"; + } + + modes[type] = 0; + } + else + { + errstr = "invalid mode"; + goto err; + } + + err: + if (errstr) + { + /* we cannot use bio_err here */ + fprintf(stderr, "openssl (lock_dbg_cb): %s (mode=%d, type=%d) at %s:%d\n", + errstr, mode, type, file, line); + } +} + +static unsigned long cryptoIdCallback() +{ +#ifdef __WIN32__ + unsigned long ret = (unsigned long) GetCurrentThreadId(); +#else + unsigned long ret = (unsigned long) pthread_self(); +#endif + return ret; +} + +#endif + + +TcpSocket::TcpSocket(const TcpSocket &other) +{ + init(); + sock = other.sock; + hostname = other.hostname; + portno = other.portno; +} + +static bool tcp_socket_inited = false; + +void TcpSocket::init() +{ + if (!tcp_socket_inited) + { +#ifdef __WIN32__ + WORD wVersionRequested = MAKEWORD( 2, 2 ); + WSADATA wsaData; + int err = WSAStartup( wVersionRequested, &wsaData ); +#endif +#ifdef WITH_SSL + sslStream = NULL; + sslContext = NULL; + CRYPTO_set_locking_callback(cryptoLockCallback); + CRYPTO_set_id_callback(cryptoIdCallback); + SSL_library_init(); + SSL_load_error_strings(); +#endif + tcp_socket_inited = true; + } + sock = -1; + connected = false; + hostname = ""; + portno = -1; + sslEnabled = false; + receiveTimeout = 0; +} + +TcpSocket::~TcpSocket() +{ + disconnect(); +} + +bool TcpSocket::isConnected() +{ + if (!connected || sock < 0) + return false; + return true; +} + +void TcpSocket::enableSSL(bool val) +{ + sslEnabled = val; +} + + +bool TcpSocket::connect(const char *hostnameArg, int portnoArg) +{ + hostname = hostnameArg; + portno = portnoArg; + return connect(); +} + +bool TcpSocket::connect(const std::string &hostnameArg, int portnoArg) +{ + hostname = hostnameArg; + portno = portnoArg; + return connect(); +} + + + +#ifdef WITH_SSL +/* +static int password_cb(char *buf, int bufLen, int rwflag, void *userdata) +{ + char *password = "password"; + if (bufLen < (int)(strlen(password)+1)) + return 0; + + strcpy(buf,password); + int ret = strlen(password); + return ret; +} + +static void infoCallback(const SSL *ssl, int where, int ret) +{ + switch (where) + { + case SSL_CB_ALERT: + { + printf("## %d SSL ALERT: %s\n", where, SSL_alert_desc_string_long(ret)); + break; + } + default: + { + printf("## %d SSL: %s\n", where, SSL_state_string_long(ssl)); + break; + } + } +} +*/ +#endif + + +bool TcpSocket::startTls() +{ +#ifdef WITH_SSL + sslStream = NULL; + sslContext = NULL; + + //SSL_METHOD *meth = SSLv23_method(); + //SSL_METHOD *meth = SSLv3_client_method(); + SSL_METHOD *meth = TLSv1_client_method(); + sslContext = SSL_CTX_new(meth); + //SSL_CTX_set_info_callback(sslContext, infoCallback); + +#if 0 + char *keyFile = "client.pem"; + char *caList = "root.pem"; + /* Load our keys and certificates*/ + if (!(SSL_CTX_use_certificate_chain_file(sslContext, keyFile))) + { + fprintf(stderr, "Can't read certificate file\n"); + disconnect(); + return false; + } + + SSL_CTX_set_default_passwd_cb(sslContext, password_cb); + + if (!(SSL_CTX_use_PrivateKey_file(sslContext, keyFile, SSL_FILETYPE_PEM))) + { + fprintf(stderr, "Can't read key file\n"); + disconnect(); + return false; + } + + /* Load the CAs we trust*/ + if (!(SSL_CTX_load_verify_locations(sslContext, caList, 0))) + { + fprintf(stderr, "Can't read CA list\n"); + disconnect(); + return false; + } +#endif + + /* Connect the SSL socket */ + sslStream = SSL_new(sslContext); + SSL_set_fd(sslStream, sock); + + if (SSL_connect(sslStream)<=0) + { + fprintf(stderr, "SSL connect error\n"); + disconnect(); + return false; + } + + sslEnabled = true; +#endif /*WITH_SSL*/ + return true; +} + + +bool TcpSocket::connect() +{ + if (hostname.size()<1) + { + printf("open: null hostname\n"); + return false; + } + + if (portno<1) + { + printf("open: bad port number\n"); + return false; + } + + sock = socket(PF_INET, SOCK_STREAM, 0); + if (sock < 0) + { + printf("open: error creating socket\n"); + return false; + } + + char *c_hostname = (char *)hostname.c_str(); + struct hostent *server = gethostbyname(c_hostname); + if (!server) + { + printf("open: could not locate host '%s'\n", c_hostname); + return false; + } + + struct sockaddr_in serv_addr; + mybzero((char *) &serv_addr, sizeof(serv_addr)); + serv_addr.sin_family = AF_INET; + mybcopy((char *)server->h_addr, (char *)&serv_addr.sin_addr.s_addr, + server->h_length); + serv_addr.sin_port = htons(portno); + + int ret = ::connect(sock, (const sockaddr *)&serv_addr, sizeof(serv_addr)); + if (ret < 0) + { + printf("open: could not connect to host '%s'\n", c_hostname); + return false; + } + + if (sslEnabled) + { + if (!startTls()) + return false; + } + connected = true; + return true; +} + +bool TcpSocket::disconnect() +{ + bool ret = true; + connected = false; +#ifdef WITH_SSL + if (sslEnabled) + { + if (sslStream) + { + int r = SSL_shutdown(sslStream); + switch(r) + { + case 1: + break; /* Success */ + case 0: + case -1: + default: + //printf("Shutdown failed"); + ret = false; + } + SSL_free(sslStream); + } + if (sslContext) + SSL_CTX_free(sslContext); + } + sslStream = NULL; + sslContext = NULL; +#endif /*WITH_SSL*/ + +#ifdef __WIN32__ + closesocket(sock); +#else + ::close(sock); +#endif + sock = -1; + sslEnabled = false; + + return ret; +} + + + +bool TcpSocket::setReceiveTimeout(unsigned long millis) +{ + receiveTimeout = millis; + return true; +} + +/** + * For normal sockets, return the number of bytes waiting to be received. + * For SSL, just return >0 when something is ready to be read. + */ +long TcpSocket::available() +{ + if (!isConnected()) + return -1; + + long count = 0; +#ifdef __WIN32__ + if (ioctlsocket(sock, FIONREAD, (unsigned long *)&count) != 0) + return -1; +#else + if (ioctl(sock, FIONREAD, &count) != 0) + return -1; +#endif + if (count<=0 && sslEnabled) + { +#ifdef WITH_SSL + return SSL_pending(sslStream); +#endif + } + return count; +} + + + +bool TcpSocket::write(int ch) +{ + if (!isConnected()) + { + printf("write: socket closed\n"); + return false; + } + unsigned char c = (unsigned char)ch; + + if (sslEnabled) + { +#ifdef WITH_SSL + int r = SSL_write(sslStream, &c, 1); + if (r<=0) + { + switch(SSL_get_error(sslStream, r)) + { + default: + printf("SSL write problem"); + return -1; + } + } +#endif + } + else + { + if (send(sock, (const char *)&c, 1, 0) < 0) + //if (send(sock, &c, 1, 0) < 0) + { + printf("write: could not send data\n"); + return false; + } + } + return true; +} + +bool TcpSocket::write(char *str) +{ + if (!isConnected()) + { + printf("write(str): socket closed\n"); + return false; + } + unsigned char *s = (unsigned char *)str; + int len = strlen(str); + + if (sslEnabled) + { +#ifdef WITH_SSL + int r = SSL_write(sslStream, s, len); + if (r<=0) + { + switch(SSL_get_error(sslStream, r)) + { + default: + printf("SSL write problem"); + return -1; + } + } +#endif + } + else + { + if (send(sock, s, len, 0) < 0) + //if (send(sock, &c, 1, 0) < 0) + { + printf("write: could not send data\n"); + return false; + } + } + return true; +} + +bool TcpSocket::write(const std::string &str) +{ + return write((char *)str.c_str()); +} + +int TcpSocket::read() +{ + if (!isConnected()) + return -1; + + //We'll use this loop for timeouts, so that SSL and plain sockets + //will behave the same way + if (receiveTimeout > 0) + { + unsigned long tim = 0; + while (true) + { + int avail = available(); + if (avail > 0) + break; + if (tim >= receiveTimeout) + return -2; + Thread::sleep(20); + tim += 20; + } + } + + //check again + if (!isConnected()) + return -1; + + unsigned char ch; + if (sslEnabled) + { +#ifdef WITH_SSL + if (!sslStream) + return -1; + int r = SSL_read(sslStream, &ch, 1); + unsigned long err = SSL_get_error(sslStream, r); + switch (err) + { + case SSL_ERROR_NONE: + break; + case SSL_ERROR_ZERO_RETURN: + return -1; + case SSL_ERROR_SYSCALL: + printf("SSL read problem(syscall) %s\n", + ERR_error_string(ERR_get_error(), NULL)); + return -1; + default: + printf("SSL read problem %s\n", + ERR_error_string(ERR_get_error(), NULL)); + return -1; + } +#endif + } + else + { + if (recv(sock, (char *)&ch, 1, 0) <= 0) + { + printf("read: could not receive data\n"); + disconnect(); + return -1; + } + } + return (int)ch; +} + +std::string TcpSocket::readLine() +{ + std::string ret; + + while (isConnected()) + { + int ch = read(); + if (ch<0) + return ret; + if (ch=='\r' || ch=='\n') + return ret; + ret.push_back((char)ch); + } + + return ret; +} + + +//######################################################################## +//######################################################################## +//### X M P P +//######################################################################## +//######################################################################## + + + + +//######################################################################## +//# X M P P E V E N T +//######################################################################## + + +XmppEvent::XmppEvent(int type) +{ + eventType = type; + presence = false; + dom = NULL; +} + +XmppEvent::XmppEvent(const XmppEvent &other) +{ + assign(other); +} + +XmppEvent &XmppEvent::operator=(const XmppEvent &other) +{ + assign(other); + return (*this); +} + +XmppEvent::~XmppEvent() +{ + if (dom) + delete dom; +} + +void XmppEvent::assign(const XmppEvent &other) +{ + eventType = other.eventType; + presence = other.presence; + status = other.status; + show = other.show; + to = other.to; + from = other.from; + group = other.group; + data = other.data; + fileName = other.fileName; + fileDesc = other.fileDesc; + fileSize = other.fileSize; + fileHash = other.fileHash; + setDOM(other.dom); +} + +int XmppEvent::getType() const +{ + return eventType; +} + +DOMString XmppEvent::getIqId() const +{ + return iqId; +} + +void XmppEvent::setIqId(const DOMString &val) +{ + iqId = val; +} + +DOMString XmppEvent::getStreamId() const +{ + return streamId; +} + +void XmppEvent::setStreamId(const DOMString &val) +{ + streamId = val; +} + +bool XmppEvent::getPresence() const +{ + return presence; +} + +void XmppEvent::setPresence(bool val) +{ + presence = val; +} + +DOMString XmppEvent::getShow() const +{ + return show; +} + +void XmppEvent::setShow(const DOMString &val) +{ + show = val; +} + +DOMString XmppEvent::getStatus() const +{ + return status; +} + +void XmppEvent::setStatus(const DOMString &val) +{ + status = val; +} + +DOMString XmppEvent::getTo() const +{ + return to; +} + +void XmppEvent::setTo(const DOMString &val) +{ + to = val; +} + +DOMString XmppEvent::getFrom() const +{ + return from; +} + +void XmppEvent::setFrom(const DOMString &val) +{ + from = val; +} + +DOMString XmppEvent::getGroup() const +{ + return group; +} + +void XmppEvent::setGroup(const DOMString &val) +{ + group = val; +} + +DOMString XmppEvent::getData() const +{ + return data; +} + +void XmppEvent::setData(const DOMString &val) +{ + data = val; +} + +DOMString XmppEvent::getFileName() const +{ + return fileName; +} + +void XmppEvent::setFileName(const DOMString &val) +{ + fileName = val; +} + +DOMString XmppEvent::getFileDesc() const +{ + return fileDesc; +} + +void XmppEvent::setFileDesc(const DOMString &val) +{ + fileDesc = val; +} + +long XmppEvent::getFileSize() const +{ + return fileSize; +} + +void XmppEvent::setFileSize(long val) +{ + fileSize = val; +} + +DOMString XmppEvent::getFileHash() const +{ + return fileHash; +} + +void XmppEvent::setFileHash(const DOMString &val) +{ + fileHash = val; +} + +Element *XmppEvent::getDOM() const +{ + return dom; +} + +void XmppEvent::setDOM(const Element *val) +{ + if (!val) + dom = NULL; + else + dom = ((Element *)val)->clone(); +} + + +std::vector XmppEvent::getUserList() const +{ + return userList; +} + +void XmppEvent::setUserList(const std::vector &val) +{ + userList = val; +} + +//######################################################################## +//# X M P P E V E N T T A R G E T +//######################################################################## + +//########################### +//# CONSTRUCTORS +//########################### + +XmppEventTarget::XmppEventTarget() +{ + eventQueueEnabled = false; +} + + +XmppEventTarget::XmppEventTarget(const XmppEventTarget &other) +{ + listeners = other.listeners; + eventQueueEnabled = other.eventQueueEnabled; +} + +XmppEventTarget::~XmppEventTarget() +{ +} + + +//########################### +//# M E S S A G E S +//########################### + +void XmppEventTarget::error(char *fmt, ...) +{ + va_list args; + va_start(args,fmt); + vsnprintf(targetWriteBuf, targetWriteBufLen, fmt, args); + va_end(args) ; + printf("Error:%s\n", targetWriteBuf); + XmppEvent evt(XmppEvent::EVENT_ERROR); + evt.setData(targetWriteBuf); + dispatchXmppEvent(evt); +} + +void XmppEventTarget::status(char *fmt, ...) +{ + va_list args; + va_start(args,fmt); + vsnprintf(targetWriteBuf, targetWriteBufLen, fmt, args); + va_end(args) ; + //printf("Status:%s\n", targetWriteBuf); + XmppEvent evt(XmppEvent::EVENT_STATUS); + evt.setData(targetWriteBuf); + dispatchXmppEvent(evt); +} + + + +//########################### +//# L I S T E N E R S +//########################### + +void XmppEventTarget::dispatchXmppEvent(const XmppEvent &event) +{ + std::vector::iterator iter; + for (iter = listeners.begin(); iter != listeners.end() ; iter++) + (*iter)->processXmppEvent(event); + if (eventQueueEnabled) + eventQueue.push_back(event); +} + +void XmppEventTarget::addXmppEventListener(const XmppEventListener &listener) +{ + XmppEventListener *lsnr = (XmppEventListener *)&listener; + std::vector::iterator iter; + for (iter = listeners.begin(); iter != listeners.end() ; iter++) + if (*iter == lsnr) + return; + listeners.push_back(lsnr); +} + +void XmppEventTarget::removeXmppEventListener(const XmppEventListener &listener) +{ + XmppEventListener *lsnr = (XmppEventListener *)&listener; + std::vector::iterator iter; + for (iter = listeners.begin(); iter != listeners.end() ; iter++) + if (*iter == lsnr) + listeners.erase(iter); +} + +void XmppEventTarget::clearXmppEventListeners() +{ + listeners.clear(); +} + + +//########################### +//# E V E N T Q U E U E +//########################### + +void XmppEventTarget::eventQueueEnable(bool val) +{ + eventQueueEnabled = val; + if (!eventQueueEnabled) + eventQueue.clear(); +} + +int XmppEventTarget::eventQueueAvailable() +{ + return eventQueue.size(); +} + +XmppEvent XmppEventTarget::eventQueuePop() +{ + if (!eventQueueEnabled || eventQueue.size()<1) + { + XmppEvent dummy(XmppEvent::EVENT_NONE); + return dummy; + } + XmppEvent event = *(eventQueue.begin()); + eventQueue.erase(eventQueue.begin()); + return event; +} + + +//######################################################################## +//# X M P P S T R E A M +//######################################################################## + +/** + * + */ +class XmppStream +{ +public: + + /** + * + */ + XmppStream(); + + /** + * + */ + virtual ~XmppStream(); + + /** + * + */ + virtual void reset(); + + /** + * + */ + virtual int getState(); + + /** + * + */ + virtual void setState(int val); + + /** + * + */ + virtual DOMString getStreamId(); + + /** + * + */ + void setStreamId(const DOMString &val); + + /** + * + */ + virtual DOMString getIqId(); + + /** + * + */ + void setIqId(const DOMString &val); + + /** + * + */ + virtual int getSeqNr(); + + /** + * + */ + virtual DOMString getPeerId(); + + /** + * + */ + virtual void setPeerId(const DOMString &val); + + /** + * + */ + int available(); + + /** + * + */ + void receiveData(std::vector &newData); + + /** + * + */ + std::vector read(); + +private: + + + DOMString streamId; + + DOMString iqId; + + DOMString sourceId; + + int state; + + long seqNr; + + std::vector data; +}; + + +/** + * + */ +XmppStream::XmppStream() +{ + reset(); +} + +/** + * + */ +XmppStream::~XmppStream() +{ + reset(); +} + +/** + * + */ +void XmppStream::reset() +{ + state = XmppClient::STREAM_AVAILABLE; + seqNr = 0; + data.clear(); +} + +/** + * + */ +int XmppStream::getState() +{ + return state; +} + +/** + * + */ +void XmppStream::setState(int val) +{ + state = val; +} + +/** + * + */ +DOMString XmppStream::getStreamId() +{ + return streamId; +} + +/** + * + */ +void XmppStream::setStreamId(const DOMString &val) +{ + streamId = val; +} + +/** + * + */ +DOMString XmppStream::getIqId() +{ + return iqId; +} + + +/** + * + */ +void XmppStream::setIqId(const DOMString &val) +{ + iqId = val; +} + +/** + * Source or destination JID + */ +void XmppStream::setPeerId(const DOMString &val) +{ + sourceId = val; +} + +/** + * Source or destination JID + */ +DOMString XmppStream::getPeerId() +{ + return sourceId; +} + +/** + * Stream packet sequence number + */ +int XmppStream::getSeqNr() +{ + seqNr++; + if (seqNr >= 65535) + seqNr = 0; + return seqNr; +} + +/** + * + */ +int XmppStream::available() +{ + return data.size(); +} + +/** + * + */ +void XmppStream::receiveData(std::vector &newData) +{ + std::vector::iterator iter; + for (iter=newData.begin() ; iter!=newData.end() ; iter++) + data.push_back(*iter); +} + +/** + * + */ +std::vector XmppStream::read() +{ + if (state != XmppClient::STREAM_OPEN) + { + std::vectordummy; + return dummy; + } + std::vector ret = data; + data.clear(); + return ret; +} + + + + + + +//######################################################################## +//# X M P P C L I E N T +//######################################################################## +class ReceiverThread : public Runnable +{ +public: + + ReceiverThread(XmppClient &par) : client(par) {} + + virtual ~ReceiverThread() {} + + void run() + { client.receiveAndProcessLoop(); } + +private: + + XmppClient &client; +}; + + +//########################### +//# CONSTRUCTORS +//########################### + +XmppClient::XmppClient() +{ + init(); +} + + +XmppClient::XmppClient(const XmppClient &other) : XmppEventTarget(other) +{ + init(); + assign(other); +} + +void XmppClient::assign(const XmppClient &other) +{ + msgId = other.msgId; + host = other.host; + realm = other.realm; + port = other.port; + username = other.username; + password = other.password; + resource = other.resource; + connected = other.connected; + groupChats = other.groupChats; +} + + +void XmppClient::init() +{ + sock = new TcpSocket(); + msgId = 0; + connected = false; + + for (int i=0 ; i0 ; i--) + if (!isspace(str[i-1])) + break; + int end = i; + if (start>=end) + return ""; + return str.substr(start, end); +} + +//############################################## +//# VARIABLES (ones that need special handling) +//############################################## +/** + * + */ +DOMString XmppClient::getUsername() +{ + return username; +} + +/** + * + */ +void XmppClient::setUsername(const DOMString &val) +{ + int p = strIndex(val, "@"); + if (p > 0) + { + username = val.substr(0, p); + realm = val.substr(p+1, jid.size()-p-1); + } + else + { + realm = host; + username = val; + } +} + +//############################################## +//# CONNECTION +//############################################## + +//####################### +//# RECEIVING +//####################### +DOMString XmppClient::readStanza() +{ + int openCount = 0; + bool inTag = false; + bool slashSeen = false; + bool trivialTag = false; + bool querySeen = false; + bool inQuote = false; + bool textSeen = false; + DOMString buf; + + while (true) + { + int ch = sock->read(); + //printf("%c", ch); fflush(stdout); + if (ch<0) + { + if (ch == -2) //a simple timeout, not an error + { + //Since we are timed out, let's assume that we + //are between chunks of text. Let's reset all states. + //printf("-----#### Timeout\n"); + continue; + } + else + { + keepGoing = false; + if (!sock->isConnected()) + { + disconnect(); + return ""; + } + else + { + error("socket read error"); + disconnect(); + return ""; + } + } + } + buf.push_back(ch); + if (ch == '<') + { + inTag = true; + slashSeen = false; + querySeen = false; + inQuote = false; + textSeen = false; + trivialTag = false; + } + else if (ch == '>') + { + if (!inTag) //unescaped '>' in pcdata? horror + continue; + inTag = false; + if (!trivialTag && !querySeen) + { + if (slashSeen) + openCount--; + else + openCount++; + } + //printf("# openCount:%d t:%d q:%d\n", + // openCount, trivialTag, querySeen); + //check if we are 'balanced', but not a tag + if (openCount <= 0 && !querySeen) + { + break; + } + //we know that this one will be open-ended + if (strIndex(buf, "= 0) + { + buf.append(""); + break; + } + } + else if (ch == '/') + { + if (inTag && !inQuote) + { + slashSeen = true; + if (textSeen) // <--looks like this + trivialTag = true; + } + } + else if (ch == '?') + { + if (inTag && !inQuote) + querySeen = true; + } + else if (ch == '"' || ch == '\'') + { + if (inTag) + inQuote = !inQuote; + } + else + { + if (inTag && !inQuote && !isspace(ch)) + textSeen = true; + } + } + return buf; +} + + + +static bool isGroupChat(Element *root) +{ + if (!root) + return false; + std::vectorelems = root->findElements("x"); + for (unsigned int i=0 ; igetAttribute("xmlns"); + //printf("### XMLNS ### %s\n", xmlns.c_str()); + if (strIndex(xmlns, "http://jabber.org/protocol/muc") >=0 ) + return true; + } + return false; +} + + + + +static bool getGroupIds(const DOMString &jid, + DOMString &groupJid, DOMString &userNick) +{ + int p = strIndex(jid, "/"); + if (p < 0) + { + groupJid = jid; + userNick = ""; + return true; + } + groupJid = jid.substr(0, p); + userNick = jid.substr(p+1, jid.size()-p-1); + return true; +} + + + + +bool XmppClient::processMessage(Element *root) +{ + DOMString from = root->getTagAttribute("message", "from"); + DOMString to = root->getTagAttribute("message", "to"); + DOMString type = root->getTagAttribute("message", "type"); + + //####Check for embedded namespaces here + //# IN BAND BYTESTREAMS + DOMString ibbNamespace = "http://jabber.org/protocol/ibb"; + if (root->getTagAttribute("data", "xmlns") == ibbNamespace) + { + DOMString streamId = root->getTagAttribute("data", "sid"); + if (streamId.size() > 0) + { + for (int i=0 ; igetStreamId().c_str(), streamId.c_str()); + if (ins->getStreamId() == streamId) + { + //# We have a winner + if (ins->getState() != STREAM_OPEN) + { + XmppEvent event(XmppEvent::EVENT_ERROR); + event.setFrom(from); + event.setData("received unrequested stream data"); + dispatchXmppEvent(event); + return true; + } + DOMString data = root->getTagValue("data"); + std::vectorbinData = + Base64Decoder::decode(data); + ins->receiveData(binData); + } + } + } + } + + + //#### NORMAL MESSAGES + DOMString subject = root->getTagValue("subject"); + DOMString body = root->getTagValue("body"); + DOMString thread = root->getTagValue("thread"); + //##rfc 3921, para 2.4. ignore if no recognizable info + if (subject.size() < 1 && body.size()<1 && thread.size()<1) + return true; + + if (type == "groupchat") + { + DOMString fromGid; + DOMString fromNick; + getGroupIds(from, fromGid, fromNick); + //printf("fromGid:%s fromNick:%s\n", + // fromGid.c_str(), fromNick.c_str()); + DOMString toGid; + DOMString toNick; + getGroupIds(to, toGid, toNick); + //printf("toGid:%s toNick:%s\n", + // toGid.c_str(), toNick.c_str()); + + if (fromNick.size() > 0)//normal group message + { + XmppEvent event(XmppEvent::EVENT_MUC_MESSAGE); + event.setGroup(fromGid); + event.setFrom(fromNick); + event.setData(body); + event.setDOM(root); + dispatchXmppEvent(event); + } + else // from the server itself + { + //note the space before, so it doesnt match 'unlocked' + if (strIndex(body, " locked") >= 0) + { + printf("LOCKED!! ;)\n"); + char *fmt = + "" + "" + "" + "\n"; + if (!write(fmt, jid.c_str(), msgId++, fromGid.c_str())) + return false; + } + } + } + else + { + XmppEvent event(XmppEvent::EVENT_MESSAGE); + event.setFrom(from); + event.setData(body); + event.setDOM(root); + dispatchXmppEvent(event); + } + + return true; +} + + + + +bool XmppClient::processPresence(Element *root) +{ + + DOMString from = root->getTagAttribute("presence", "from"); + DOMString to = root->getTagAttribute("presence", "to"); + DOMString presenceStr = root->getTagAttribute("presence", "type"); + bool presence = true; + if (presenceStr == "unavailable") + presence = false; + DOMString status = root->getTagValue("status"); + DOMString show = root->getTagValue("show"); + + if (isGroupChat(root)) + { + DOMString fromGid; + DOMString fromNick; + getGroupIds(from, fromGid, fromNick); + //printf("fromGid:%s fromNick:%s\n", + // fromGid.c_str(), fromNick.c_str()); + DOMString item_jid = root->getTagAttribute("item", "jid"); + if (item_jid == jid) //Me + { + if (presence) + { + groupChatCreate(fromGid); + groupChatUserAdd(fromGid, fromNick); + + XmppEvent event(XmppEvent::EVENT_MUC_JOIN); + event.setGroup(fromGid); + event.setFrom(fromNick); + event.setPresence(presence); + event.setShow(show); + event.setStatus(status); + dispatchXmppEvent(event); + } + else + { + groupChatDelete(fromGid); + groupChatUserDelete(fromGid, fromNick); + + XmppEvent event(XmppEvent::EVENT_MUC_LEAVE); + event.setGroup(fromGid); + event.setFrom(fromNick); + event.setPresence(presence); + event.setShow(show); + event.setStatus(status); + dispatchXmppEvent(event); + } + } + else + { + if (presence) + groupChatUserAdd(fromGid, fromNick); + else + groupChatUserDelete(fromGid, fromNick); + XmppEvent event(XmppEvent::EVENT_MUC_PRESENCE); + event.setGroup(fromGid); + event.setFrom(fromNick); + event.setPresence(presence); + event.setShow(show); + event.setStatus(status); + dispatchXmppEvent(event); + } + } + else + { + XmppEvent event(XmppEvent::EVENT_PRESENCE); + event.setFrom(from); + event.setPresence(presence); + event.setShow(show); + event.setStatus(status); + dispatchXmppEvent(event); + } + + return true; +} + + + +bool XmppClient::processIq(Element *root) +{ + DOMString from = root->getTagAttribute("iq", "from"); + DOMString id = root->getTagAttribute("iq", "id"); + DOMString type = root->getTagAttribute("iq", "type"); + DOMString xmlns = root->getTagAttribute("query", "xmlns"); + + if (id.size()<1) + return true; + + //Group chat + if (strIndex(xmlns, "http://jabber.org/protocol/muc") >=0 ) + { + printf("results of MUC query\n"); + } + //printf("###IQ xmlns:%s\n", xmlns.c_str()); + + //### FILE TRANSFERS + DOMString siNamespace = "http://jabber.org/protocol/si"; + if (root->getTagAttribute("si", "xmlns") == siNamespace) + { + if (type == "set") + { + DOMString streamId = root->getTagAttribute("si", "id"); + DOMString fname = root->getTagAttribute("file", "name"); + DOMString sizeStr = root->getTagAttribute("file", "size"); + DOMString hash = root->getTagAttribute("file", "hash"); + XmppEvent event(XmppEvent::XmppEvent::EVENT_FILE_RECEIVE); + event.setFrom(from); + event.setIqId(id); + event.setStreamId(streamId); + event.setFileName(fname); + event.setFileHash(hash); + event.setFileSize(atol(sizeStr.c_str())); + dispatchXmppEvent(event); + } + else //result + { + printf("Got result\n"); + for (int i=0 ; igetIqId() == id && + from == outf->getPeerId()) + { + if (type == "error") + { + outf->setState(STREAM_ERROR); + error("user '%s' rejected file", from.c_str()); + return true; + } + else if (type == "result") + { + if (outf->getState() == STREAM_OPENING) + { + XmppEvent event(XmppEvent::XmppEvent::EVENT_FILE_ACCEPTED); + event.setFrom(from); + dispatchXmppEvent(event); + outf->setState(STREAM_OPEN); + } + else if (outf->getState() == STREAM_CLOSING) + { + outf->setState(STREAM_CLOSED); + } + return true; + } + } + } + } + return true; + } + + + //### IN-BAND BYTESTREAMS + //### Incoming stream requests + DOMString ibbNamespace = "http://jabber.org/protocol/ibb"; + if (root->getTagAttribute("open", "xmlns") == ibbNamespace) + { + DOMString streamId = root->getTagAttribute("open", "sid"); + XmppEvent event(XmppEvent::XmppEvent::EVENT_STREAM_RECEIVE_INIT); + dispatchXmppEvent(event); + if (streamId.size()>0) + { + for (int i=0 ; igetStreamId() == streamId) + { + ins->setState(STREAM_OPENING); + ins->setIqId(id); + return true; + } + } + } + return true; + } + else if (root->getTagAttribute("close", "xmlns") == ibbNamespace) + { + XmppEvent event(XmppEvent::XmppEvent::EVENT_STREAM_RECEIVE_CLOSE); + dispatchXmppEvent(event); + DOMString streamId = root->getTagAttribute("close", "sid"); + if (streamId.size()>0) + { + for (int i=0 ; igetStreamId() == streamId && + from == ins->getPeerId()) + { + ins->setState(STREAM_CLOSING); + ins->setIqId(id); + return true; + } + } + } + return true; + } + //### Responses to outgoing requests + for (int i=0 ; igetIqId() == id) + { + if (type == "error") + { + outs->setState(STREAM_ERROR); + return true; + } + else if (type == "result") + { + if (outs->getState() == STREAM_OPENING) + { + outs->setState(STREAM_OPEN); + } + else if (outs->getState() == STREAM_CLOSING) + { + outs->setState(STREAM_CLOSED); + } + return true; + } + } + } + + //###Normal Roster stuff + if (root->getTagAttribute("query", "xmlns") == "jabber:iq:roster") + { + roster.clear(); + std::vectorelems = root->findElements("item"); + for (unsigned int i=0 ; igetAttribute("jid"); + DOMString name = item->getAttribute("name"); + DOMString subscription = item->getAttribute("subscription"); + DOMString group = item->getTagValue("group"); + //printf("jid:%s name:%s sub:%s group:%s\n", userJid.c_str(), name.c_str(), + // subscription.c_str(), group.c_str()); + XmppUser user(userJid, name, subscription, group); + roster.push_back(user); + } + XmppEvent event(XmppEvent::XmppEvent::EVENT_ROSTER); + dispatchXmppEvent(event); + } + + return true; +} + + + +bool XmppClient::receiveAndProcess() +{ + if (!keepGoing) + return false; + + Parser parser; + + DOMString recvBuf = readStanza(); + recvBuf = trim(recvBuf); + if (recvBuf.size() < 1) + return true; + + //Ugly hack. Apparently the first char can be dropped on timeouts + //if (recvBuf[0] != '<') + // recvBuf.insert(0, "<"); + + status("RECV: %s", recvBuf.c_str()); + Element *root = parser.parse(recvBuf); + if (!root) + { + printf("Bad elem\n"); + return true; + } + + //#### MESSAGE + std::vectorelems = root->findElements("message"); + if (elems.size()>0) + { + if (!processMessage(root)) + return false; + } + + //#### PRESENCE + elems = root->findElements("presence"); + if (elems.size()>0) + { + if (!processPresence(root)) + return false; + } + + //#### INFO + elems = root->findElements("iq"); + if (elems.size()>0) + { + if (!processIq(root)) + return false; + } + + delete root; + + return true; +} + + +bool XmppClient::receiveAndProcessLoop() +{ + keepGoing = true; + while (true) + { + if (!keepGoing) + { + printf("Abort requested\n"); + break; + } + if (!receiveAndProcess()) + return false; + } + return true; +} + +//####################### +//# SENDING +//####################### + +bool XmppClient::write(char *fmt, ...) +{ + va_list args; + va_start(args,fmt); + vsnprintf((char *)writeBuf, writeBufLen, fmt,args); + va_end(args) ; + status("SEND: %s", writeBuf); + if (!sock->write((char *)writeBuf)) + { + error("Cannot write to socket"); + return false; + } + return true; +} + +//####################### +//# CONNECT +//####################### + +bool XmppClient::checkConnect() +{ + if (!connected) + { + XmppEvent evt(XmppEvent::EVENT_ERROR); + evt.setData("Attempted operation while disconnected"); + dispatchXmppEvent(evt); + return false; + } + return true; +} + +bool XmppClient::iqAuthenticate(const DOMString &streamId) +{ + Parser parser; + + char *fmt = + "" + "%s" + "\n"; + if (!write(fmt, realm.c_str(), msgId++, username.c_str())) + return false; + + DOMString recbuf = readStanza(); + //printf("iq received: '%s'\n", recbuf.c_str()); + Element *elem = parser.parse(recbuf); + //elem->print(); + DOMString iqType = elem->getTagAttribute("iq", "type"); + //printf("##iqType:%s\n", iqType.c_str()); + delete elem; + + if (iqType != "result") + { + error("error:server does not allow login"); + return false; + } + + bool digest = true; + if (digest) + { + //## Digest authentication + DOMString digest = streamId; + digest.append(password); + digest = Sha1::hashHex((unsigned char *)digest.c_str(), digest.size()); + //printf("digest:%s\n", digest.c_str()); + fmt = + "" + "" + "%s" + "%s" + "%s" + "" + "\n"; + if (!write(fmt, msgId++, username.c_str(), + digest.c_str(), resource.c_str())) + return false; + } + else + { + + //## Plaintext authentication + fmt = + "" + "" + "%s" + "%s" + "%s" + "" + "\n"; + if (!write(fmt, msgId++, username.c_str(), + password.c_str(), resource.c_str())) + return false; + } + + recbuf = readStanza(); + //printf("iq received: '%s'\n", recbuf.c_str()); + elem = parser.parse(recbuf); + //elem->print(); + iqType = elem->getTagAttribute("iq", "type"); + //printf("##iqType:%s\n", iqType.c_str()); + delete elem; + + if (iqType != "result") + { + error("server does not allow login"); + return false; + } + + return true; +} + + + +bool XmppClient::saslMd5Authenticate() +{ + Parser parser; + char *fmt = + "\n"; + if (!write(fmt)) + return false; + + DOMString recbuf = readStanza(); + status("challenge received: '%s'", recbuf.c_str()); + Element *elem = parser.parse(recbuf); + //elem->print(); + DOMString b64challenge = elem->getTagValue("challenge"); + delete elem; + + if (b64challenge.size() < 1) + { + error("login: no SASL challenge offered by server"); + return false; + } + DOMString challenge = Base64Decoder::decodeToString(b64challenge); + status("challenge:'%s'", challenge.c_str()); + + unsigned int p1 = challenge.find("nonce=\""); + if (p1 == DOMString::npos) + { + error("login: no SASL nonce sent by server"); + return false; + } + p1 += 7; + unsigned int p2 = challenge.find("\"", p1); + if (p2 == DOMString::npos) + { + error("login: unterminated SASL nonce sent by server"); + return false; + } + DOMString nonce = challenge.substr(p1, p2-p1); + //printf("nonce: '%s'\n", nonce.c_str()); + char idBuf[7]; + snprintf(idBuf, 6, "%dsasl", msgId++); + DOMString cnonce = Sha1::hashHex((unsigned char *)idBuf, 7); + DOMString authzid = username; authzid.append("@"); authzid.append(host); + DOMString digest_uri = "xmpp/"; digest_uri.append(host); + + //## Make A1 + Md5 md5; + md5.append(username); + md5.append(":"); + md5.append(realm); + md5.append(":"); + md5.append(password); + unsigned char a1tmp[16]; + md5.finish(a1tmp); + md5.init(); + md5.append(a1tmp, 16); + md5.append(":"); + md5.append(nonce); + md5.append(":"); + md5.append(cnonce); + md5.append(":"); + md5.append(authzid); + DOMString a1 = md5.finishHex(); + status("##a1:'%s'", a1.c_str()); + + //# Make A2 + md5.init(); + md5.append("AUTHENTICATE:"); + md5.append(digest_uri); + DOMString a2 = md5.finishHex(); + status("##a2:'%s'", a2.c_str()); + + //# Now make the response + md5.init(); + md5.append(a1); + md5.append(":"); + md5.append(nonce); + md5.append(":"); + md5.append("00000001");//nc + md5.append(":"); + md5.append(cnonce); + md5.append(":"); + md5.append("auth");//qop + md5.append(":"); + md5.append(a2); + DOMString response = md5.finishHex(); + + DOMString resp; + resp.append("username=\""); resp.append(username); resp.append("\","); + resp.append("realm=\""); resp.append(realm); resp.append("\","); + resp.append("nonce=\""); resp.append(nonce); resp.append("\","); + resp.append("cnonce=\""); resp.append(cnonce); resp.append("\","); + resp.append("nc=00000001,qop=auth,"); + resp.append("digest-uri=\""); resp.append(digest_uri); resp.append("\"," ); + resp.append("authzid=\""); resp.append(authzid); resp.append("\","); + resp.append("response=\""); resp.append(response); resp.append("\","); + resp.append("charset=utf-8"); + status("sending response:'%s'", resp.c_str()); + resp = Base64Encoder::encode(resp); + status("base64 response:'%s'", resp.c_str()); + fmt = + "%s\n"; + if (!write(fmt, resp.c_str())) + return false; + + recbuf = readStanza(); + status("server says:: '%s'", recbuf.c_str()); + elem = parser.parse(recbuf); + //elem->print(); + b64challenge = elem->getTagValue("challenge"); + delete elem; + + if (b64challenge.size() < 1) + { + error("login: no second SASL challenge offered by server"); + return false; + } + + challenge = Base64Decoder::decodeToString(b64challenge); + status("challenge: '%s'", challenge.c_str()); + p1 = challenge.find("rspauth="); + if (p1 == DOMString::npos) + { + error("login: no SASL respauth sent by server\n"); + return false; + } + + fmt = + "\n"; + if (!write(fmt)) + return false; + + recbuf = readStanza(); + status("server says: '%s", recbuf.c_str()); + elem = parser.parse(recbuf); + //elem->print(); + b64challenge = elem->getTagValue("challenge"); + bool success = (elem->findElements("success").size() > 0); + delete elem; + + return success; +} + +bool XmppClient::saslPlainAuthenticate() +{ + Parser parser; + + DOMString id = username; + //id.append("@"); + //id.append(host); + Base64Encoder encoder; + encoder.append('\0'); + encoder.append(id); + encoder.append('\0'); + encoder.append(password); + DOMString base64Auth = encoder.finish(); + //printf("authbuf:%s\n", base64Auth.c_str()); + + char *fmt = + "%s\n"; + if (!write(fmt, base64Auth.c_str())) + return false; + DOMString recbuf = readStanza(); + status("challenge received: '%s'", recbuf.c_str()); + Element *elem = parser.parse(recbuf); + + bool success = (elem->findElements("success").size() > 0); + delete elem; + + return success; +} + + + +bool XmppClient::saslAuthenticate() +{ + Parser parser; + + DOMString recbuf = readStanza(); + status("RECV: '%s'\n", recbuf.c_str()); + Element *elem = parser.parse(recbuf); + //elem->print(); + + //Check for starttls + bool wantStartTls = false; + if (elem->findElements("starttls").size() > 0) + { + wantStartTls = true; + if (elem->findElements("required").size() > 0) + status("login: STARTTLS required"); + else + status("login: STARTTLS available"); + } + + if (wantStartTls) + { + delete elem; + char *fmt = + "\n"; + if (!write(fmt)) + return false; + recbuf = readStanza(); + status("RECV: '%s'\n", recbuf.c_str()); + elem = parser.parse(recbuf); + if (elem->getTagAttribute("proceed", "xmlns").size()<1) + { + error("Server rejected TLS negotiation"); + disconnect(); + return false; + } + delete elem; + if (!sock->startTls()) + { + error("Could not start TLS"); + disconnect(); + return false; + } + + fmt = + "\n\n"; + if (!write(fmt, realm.c_str())) + return false; + + recbuf = readStanza(); + status("RECVx: '%s'", recbuf.c_str()); + recbuf.append(""); + elem = parser.parse(recbuf); + bool success = + (elem->getTagAttribute("stream:stream", "id").size()>0); + if (!success) + { + error("STARTTLS negotiation failed"); + disconnect(); + return false; + } + delete elem; + recbuf = readStanza(); + status("RECV: '%s'\n", recbuf.c_str()); + elem = parser.parse(recbuf); + } + + //check for sasl authentication mechanisms + std::vector elems = + elem->findElements("mechanism"); + if (elems.size() < 1) + { + error("login: no SASL mechanism offered by server"); + return false; + } + bool md5Found = false; + bool plainFound = false; + for (unsigned int i=0 ; igetValue(); + if (mech == "DIGEST-MD5") + { + status("MD5 authentication offered"); + md5Found = true; + } + else if (mech == "PLAIN") + { + status("PLAIN authentication offered"); + plainFound = true; + } + } + delete elem; + + bool success = false; + if (md5Found) + { + success = saslMd5Authenticate(); + } + else if (plainFound) + { + success = saslPlainAuthenticate(); + } + else + { + error("not able to handle sasl authentication mechanisms"); + return false; + } + + if (success) + status("###### SASL authentication success\n"); + else + error("###### SASL authentication failure\n"); + + return success; +} + + + + + +bool XmppClient::createSession() +{ + + Parser parser; + if (port==443 || port==5223) + sock->enableSSL(true); + if (!sock->connect(host, port)) + { + return false; + } + + char *fmt = + "\n\n"; + if (!write(fmt, realm.c_str())) + return false; + + DOMString recbuf = readStanza(); + //printf("received: '%s'\n", recbuf.c_str()); + recbuf.append(""); + Element *elem = parser.parse(recbuf); + //elem->print(); + bool useSasl = false; + DOMString streamId = elem->getTagAttribute("stream:stream", "id"); + //printf("### StreamID: %s\n", streamId.c_str()); + DOMString streamVersion = elem->getTagAttribute("stream:stream", "version"); + if (streamVersion == "1.0") + useSasl = true; + + if (useSasl) + { + if (!saslAuthenticate()) + return false; + fmt = + "\n\n"; + + if (!write(fmt, realm.c_str())) + return false; + recbuf = readStanza(); + recbuf.append("\n"); + //printf("now server says:: '%s'\n", recbuf.c_str()); + elem = parser.parse(recbuf); + //elem->print(); + delete elem; + + recbuf = readStanza(); + //printf("now server says:: '%s'\n", recbuf.c_str()); + elem = parser.parse(recbuf); + bool hasBind = (elem->findElements("bind").size() > 0); + //elem->print(); + delete elem; + + if (!hasBind) + { + error("no binding provided by server"); + return false; + } + + + } + else // not SASL + { + if (!iqAuthenticate(streamId)) + return false; + } + + + //### Resource binding + fmt = + "" + "" + "%s" + "\n"; + if (!write(fmt, msgId++, resource.c_str())) + return false; + + recbuf = readStanza(); + status("bind result: '%s'", recbuf.c_str()); + elem = parser.parse(recbuf); + //elem->print(); + DOMString bindType = elem->getTagAttribute("iq", "type"); + //printf("##bindType:%s\n", bindType.c_str()); + delete elem; + + if (bindType != "result") + { + error("no binding with server failed"); + return false; + } + + fmt = + "" + "" + "\n"; + if (!write(fmt, msgId++)) + return false; + + recbuf = readStanza(); + status("session received: '%s'", recbuf.c_str()); + elem = parser.parse(recbuf); + //elem->print(); + DOMString sessionType = elem->getTagAttribute("iq", "type"); + //printf("##sessionType:%s\n", sessionType.c_str()); + delete elem; + + if (sessionType != "result") + { + error("no session provided by server"); + return false; + } + + //printf("########## COOL #########\n"); + //Now that we are bound, we have a valid JID + jid = username; + jid.append("@"); + jid.append(realm); + jid.append("/"); + jid.append(resource); + + //We are now done with the synchronous handshaking. Let's go into + //async mode + + fmt = + "\n"; + if (!write(fmt)) + return false; + + fmt = + "\n"; + if (!write(fmt, msgId++)) + return false; + + fmt = + "" + "\n"; + if (!write(fmt, msgId++, realm.c_str())) + return false; + + fmt = + "" + "\n"; + if (!write(fmt, msgId++, realm.c_str())) + return false; + + /* + recbuf = readStanza(); + status("stream received: '%s'", recbuf.c_str()); + elem = parser.parse(recbuf); + //elem->print(); + delete elem; + */ + + //We are now logged in + status("Connected"); + connected = true; + XmppEvent evt(XmppEvent::EVENT_CONNECTED); + dispatchXmppEvent(evt); + //Thread::sleep(1000000); + + sock->setReceiveTimeout(1000); + ReceiverThread runner(*this); + Thread thread(runner); + thread.start(); + + return true; +} + +bool XmppClient::connect() +{ + if (!createSession()) + { + disconnect(); + return false; + } + return true; +} + + +bool XmppClient::connect(DOMString hostArg, int portArg, + DOMString usernameArg, + DOMString passwordArg, + DOMString resourceArg) +{ + host = hostArg; + port = portArg; + password = passwordArg; + resource = resourceArg; + + //parse this one + setUsername(usernameArg); + + bool ret = connect(); + return ret; +} + +bool XmppClient::disconnect() +{ + if (connected) + { + char *fmt = + "\n"; + write(fmt, jid.c_str()); + } + keepGoing = false; + connected = false; + Thread::sleep(3000); //allow receiving thread to quit + sock->disconnect(); + roster.clear(); + groupChatsClear(); + XmppEvent event(XmppEvent::EVENT_DISCONNECTED); + dispatchXmppEvent(event); + return true; +} + +//####################### +//# ROSTER +//####################### + +bool XmppClient::rosterAdd(const DOMString &rosterGroup, + const DOMString &otherJid, + const DOMString &name) +{ + if (!checkConnect()) + return false; + char *fmt = + "" + "" + "%s" + "\n"; + if (!write(fmt, jid.c_str(), msgId++, otherJid.c_str(), + name.c_str(), rosterGroup.c_str())) + { + return false; + } + return true; +} + +bool XmppClient::rosterDelete(const DOMString &otherJid) +{ + if (!checkConnect()) + return false; + char *fmt = + "" + "" + "%s" + "\n"; + if (!write(fmt, jid.c_str(), msgId++, otherJid.c_str())) + { + return false; + } + return true; +} + + +static bool xmppRosterCompare(const XmppUser& p1, const XmppUser& p2) +{ + DOMString s1 = p1.group; + DOMString s2 = p2.group; + for (unsigned int len=0 ; len XmppClient::getRoster() +{ + std::vector ros = roster; + std::sort(ros.begin(), ros.end(), xmppRosterCompare); + return ros; +} + +//####################### +//# CHAT (individual) +//####################### + +bool XmppClient::message(const DOMString &user, const DOMString &subj, + const DOMString &msg) +{ + if (!checkConnect()) + return false; + + DOMString xmlSubj = toXml(subj); + DOMString xmlMsg = toXml(msg); + + if (xmlSubj.size() > 0) + { + char *fmt = + "" + "%s%s\n"; + if (!write(fmt, jid.c_str(), user.c_str(), + xmlSubj.c_str(), xmlMsg.c_str())) + return false; + } + else + { + char *fmt = + "" + "%s\n"; + if (!write(fmt, jid.c_str(), user.c_str(), xmlMsg.c_str())) + return false; + } + return true; +} + + + +bool XmppClient::message(const DOMString &user, const DOMString &msg) +{ + return message(user, "", msg); +} + + + +bool XmppClient::presence(const DOMString &presence) +{ + if (!checkConnect()) + return false; + + DOMString xmlPres = toXml(presence); + + char *fmt = + "%s\n"; + if (!write(fmt, jid.c_str(), xmlPres.c_str())) + return false; + return true; +} + +//####################### +//# GROUP CHAT +//####################### + +bool XmppClient::groupChatCreate(const DOMString &groupJid) +{ + std::vector::iterator iter; + for (iter=groupChats.begin() ; iter!=groupChats.end() ; iter++) + { + if ((*iter)->getGroupJid() == groupJid) + { + error("Group chat '%s' already exists", groupJid.c_str()); + return false; + } + } + XmppGroupChat *chat = new XmppGroupChat(groupJid); + groupChats.push_back(chat); + return true; +} + +/** + * + */ +void XmppClient::groupChatDelete(const DOMString &groupJid) +{ + std::vector::iterator iter; + for (iter=groupChats.begin() ; iter!=groupChats.end() ; ) + { + XmppGroupChat *chat = *iter; + if (chat->getGroupJid() == groupJid) + { + iter = groupChats.erase(iter); + delete chat; + } + else + iter++; + } +} + +/** + * + */ +bool XmppClient::groupChatExists(const DOMString &groupJid) +{ + std::vector::iterator iter; + for (iter=groupChats.begin() ; iter!=groupChats.end() ; iter++) + if ((*iter)->getGroupJid() == groupJid) + return true; + return false; +} + +/** + * + */ +void XmppClient::groupChatsClear() +{ + std::vector::iterator iter; + for (iter=groupChats.begin() ; iter!=groupChats.end() ; iter++) + delete (*iter); + groupChats.clear(); +} + + +/** + * + */ +void XmppClient::groupChatUserAdd(const DOMString &groupJid, + const DOMString &nick) +{ + std::vector::iterator iter; + for (iter=groupChats.begin() ; iter!=groupChats.end() ; iter++) + { + if ((*iter)->getGroupJid() == groupJid) + { + (*iter)->userAdd("", nick); + } + } +} + +/** + * + */ +void XmppClient::groupChatUserDelete(const DOMString &groupJid, + const DOMString &nick) +{ + std::vector::iterator iter; + for (iter=groupChats.begin() ; iter!=groupChats.end() ; iter++) + { + if ((*iter)->getGroupJid() == groupJid) + { + (*iter)->userDelete("", nick); + } + } +} + +static bool xmppUserCompare(const XmppUser& p1, const XmppUser& p2) +{ + DOMString s1 = p1.nick; + DOMString s2 = p2.nick; + int comp = 0; + for (unsigned int len=0 ; len XmppClient::groupChatGetUserList( + const DOMString &groupJid) +{ + if (!checkConnect()) + { + std::vector dummy; + return dummy; + } + + std::vector::iterator iter; + for (iter=groupChats.begin() ; iter!=groupChats.end() ; iter++) + { + if ((*iter)->getGroupJid() == groupJid ) + { + std::vector uList = (*iter)->getUserList(); + std::sort(uList.begin(), uList.end(), xmppUserCompare); + return uList; + } + } + std::vector dummy; + return dummy; +} + +bool XmppClient::groupChatJoin(const DOMString &groupJid, + const DOMString &nick, + const DOMString &pass) +{ + if (!checkConnect()) + return false; + + DOMString user = nick; + if (user.size()<1) + user = username; + + char *fmt = + "" + "\n"; + if (!write(fmt, groupJid.c_str(), user.c_str())) + return false; + return true; +} + + +bool XmppClient::groupChatLeave(const DOMString &groupJid, + const DOMString &nick) +{ + if (!checkConnect()) + return false; + + DOMString user = nick; + if (user.size()<1) + user = username; + + char *fmt = + "" + "\n"; + if (!write(fmt, groupJid.c_str(), user.c_str())) + return false; + return true; +} + + +bool XmppClient::groupChatMessage(const DOMString &groupJid, + const DOMString &msg) +{ + if (!checkConnect()) + { + return false; + } + + DOMString xmlMsg = toXml(msg); + + char *fmt = + "" + "%s\n"; + if (!write(fmt, jid.c_str(), groupJid.c_str(), xmlMsg.c_str())) + return false; + return true; +} + +bool XmppClient::groupChatPrivateMessage(const DOMString &groupJid, + const DOMString &toNick, + const DOMString &msg) +{ + if (!checkConnect()) + return false; + + DOMString xmlMsg = toXml(msg); + + char *fmt = + "" + "%s\n"; + if (!write(fmt, jid.c_str(), groupJid.c_str(), + toNick.c_str(), xmlMsg.c_str())) + return false; + return true; +} + +bool XmppClient::groupChatPresence(const DOMString &groupJid, + const DOMString &myNick, + const DOMString &presence) +{ + if (!checkConnect()) + return false; + + DOMString user = myNick; + if (user.size()<1) + user = username; + + DOMString xmlPresence = toXml(presence); + + char *fmt = + "" + "\n"; + if (!write(fmt, jid.c_str(), groupJid.c_str(), user.c_str(), xmlPresence.c_str())) + return true; + return true; +} + + + +//####################### +//# S T R E A M S +//####################### + + +/** + * + */ +int XmppClient::outputStreamOpen(const DOMString &destId, + const DOMString &streamIdArg) +{ + int i; + for (i=0; igetState() == STREAM_AVAILABLE) + break; + if (i>=outputStreamCount) + { + error("No available output streams"); + return -1; + } + int streamNr = i; + XmppStream *outs = outputStreams[streamNr]; + + outs->setState(STREAM_OPENING); + + char buf[32]; + snprintf(buf, 31, "inband%d", getMsgId()); + DOMString iqId = buf; + + DOMString streamId = streamIdArg; + if (streamId.size()<1) + { + snprintf(buf, 31, "stream%d", getMsgId()); + DOMString streamId = buf; + } + outs->setIqId(iqId); + outs->setStreamId(streamId); + outs->setPeerId(destId); + + char *fmt = + "" + "\n"; + if (!write(fmt, jid.c_str(), + destId.c_str(), iqId.c_str(), + streamId.c_str())) + { + outs->reset(); + return -1; + } + + int state = outs->getState(); + for (int tim=0 ; tim<20 ; tim++) + { + if (state == STREAM_OPEN) + break; + else if (state == STREAM_ERROR) + { + printf("ERROR\n"); + outs->reset(); + return -1; + } + Thread::sleep(1000); + state = outs->getState(); + } + if (state != STREAM_OPEN) + { + printf("TIMEOUT ERROR\n"); + outs->reset(); + return -1; + } + + return streamNr; +} + +/** + * + */ +int XmppClient::outputStreamWrite(int streamNr, + const unsigned char *buf, unsigned long len) +{ + XmppStream *outs = outputStreams[streamNr]; + + unsigned long outLen = 0; + unsigned char *p = (unsigned char *)buf; + + while (outLen < len) + { + unsigned long chunksize = 1024; + if (chunksize + outLen > len) + chunksize = len - outLen; + + Base64Encoder encoder; + encoder.append(p, chunksize); + DOMString b64data = encoder.finish(); + p += chunksize; + outLen += chunksize; + + char *fmt = + "" + "" + "%s" + "" + "" + "" + "" + "" + "\n"; + if (!write(fmt, jid.c_str(), + outs->getPeerId().c_str(), + getMsgId(), + outs->getStreamId().c_str(), + outs->getSeqNr(), + b64data.c_str())) + { + outs->reset(); + return -1; + } + pause(5000); + } + return outLen; +} + +/** + * + */ +int XmppClient::outputStreamClose(int streamNr) +{ + XmppStream *outs = outputStreams[streamNr]; + + char buf[32]; + snprintf(buf, 31, "inband%d", getMsgId()); + DOMString iqId = buf; + outs->setIqId(iqId); + + outs->setState(STREAM_CLOSING); + char *fmt = + "" + "\n"; + if (!write(fmt, jid.c_str(), + outs->getPeerId().c_str(), + iqId.c_str(), + outs->getStreamId().c_str())) + return false; + + int state = outs->getState(); + for (int tim=0 ; tim<20 ; tim++) + { + if (state == STREAM_CLOSED) + break; + else if (state == STREAM_ERROR) + { + printf("ERROR\n"); + outs->reset(); + return -1; + } + Thread::sleep(1000); + state = outs->getState(); + } + if (state != STREAM_CLOSED) + { + printf("TIMEOUT ERROR\n"); + outs->reset(); + return -1; + } + + outs->reset(); + return 1; +} + + +/** + * + */ +int XmppClient::inputStreamOpen(const DOMString &fromJid, const DOMString &streamId, + const DOMString &iqId) +{ + int i; + for (i=0 ; igetState() == STREAM_AVAILABLE) + break; + } + if (i>=inputStreamCount) + { + error("No available input streams"); + return -1; + } + int streamNr = i; + XmppStream *ins = inputStreams[streamNr]; + ins->reset(); + ins->setPeerId(fromJid); + ins->setState(STREAM_CLOSED); + ins->setStreamId(streamId); + + int state = ins->getState(); + for (int tim=0 ; tim<20 ; tim++) + { + if (state == STREAM_OPENING) + break; + else if (state == STREAM_ERROR) + { + printf("ERROR\n"); + ins->reset(); + return -1; + } + Thread::sleep(1000); + state = ins->getState(); + } + if (state != STREAM_OPENING) + { + printf("TIMEOUT ERROR\n"); + ins->reset(); + return -1; + } + char *fmt = + "\n"; + if (!write(fmt, jid.c_str(), fromJid.c_str(), ins->getIqId().c_str())) + { + return -1; + } + + ins->setState(STREAM_OPEN); + return streamNr; +} + +/** + * + */ +int XmppClient::inputStreamAvailable(int streamNr) +{ + XmppStream *ins = inputStreams[streamNr]; + return ins->available(); +} + +/** + * + */ +std::vector XmppClient::inputStreamRead(int streamNr) +{ + XmppStream *ins = inputStreams[streamNr]; + return ins->read(); +} + +/** + * + */ +bool XmppClient::inputStreamClosing(int streamNr) +{ + XmppStream *ins = inputStreams[streamNr]; + if (ins->getState() == STREAM_CLOSING) + return true; + return false; +} + + +/** + * + */ +int XmppClient::inputStreamClose(int streamNr) +{ + int ret=1; + XmppStream *ins = inputStreams[streamNr]; + if (ins->getState() == STREAM_CLOSING) + { + char *fmt = + "\n"; + if (!write(fmt, jid.c_str(), ins->getPeerId().c_str(), + ins->getIqId().c_str())) + { + ret = -1; + } + } + ins->reset(); + return ret; +} + + + + +//####################### +//# FILE TRANSFERS +//####################### + + +/** + * + */ +bool XmppClient::fileSend(const DOMString &destJidArg, + const DOMString &offeredNameArg, + const DOMString &fileNameArg, + const DOMString &descriptionArg) +{ + DOMString destJid = destJidArg; + DOMString offeredName = offeredNameArg; + DOMString fileName = fileNameArg; + DOMString description = descriptionArg; + + int i; + for (i=0; igetState() == STREAM_AVAILABLE) + break; + if (i>=fileSendCount) + { + error("No available file send streams"); + return false; + } + int fileSendNr = i; + XmppStream *outf = fileSends[fileSendNr]; + + outf->setState(STREAM_OPENING); + + struct stat finfo; + if (stat(fileName.c_str(), &finfo)<0) + { + error("Cannot stat file '%s' for sending", fileName.c_str()); + return false; + } + long fileLen = finfo.st_size; + if (!fileLen > 1000000) + { + error("'%s' too large", fileName.c_str()); + return false; + } + if (!S_ISREG(finfo.st_mode)) + { + error("'%s' is not a regular file", fileName.c_str()); + return false; + } + FILE *f = fopen(fileName.c_str(), "rb"); + if (!f) + { + error("cannot open '%s' for sending", fileName.c_str()); + return false; + } + unsigned char *sendBuf = (unsigned char *)malloc(fileLen+1); + if (!sendBuf) + { + error("cannot cannot allocate send buffer for %s", fileName.c_str()); + return false; + } + for (long i=0 ; i=0 && slashPos<=(int)(fileName.size()-1)) + { + offeredName = fileName.substr(slashPos+1, + fileName.size()-slashPos-1); + printf("offeredName:%s\n", offeredName.c_str()); + } + } + + char buf[32]; + snprintf(buf, 31, "file%d", getMsgId()); + DOMString iqId = buf; + outf->setIqId(iqId); + + snprintf(buf, 31, "stream%d", getMsgId()); + DOMString streamId = buf; + //outf->setStreamId(streamId); + + DOMString hash = Md5::hashHex(sendBuf, fileLen); + printf("Hash:%s\n", hash.c_str()); + + outf->setPeerId(destJid); + + char dtgBuf[81]; + struct tm *timeVal = gmtime(&(finfo.st_mtime)); + strftime(dtgBuf, 80, "%Y-%m-%dT%H:%M:%Sz", timeVal); + + char *fmt = + "" + "" + "%s" + "" + "" + "" + //"" + "" + "\n"; + if (!write(fmt, iqId.c_str(), destJid.c_str(), + streamId.c_str(), offeredName.c_str(), fileLen, + hash.c_str(), dtgBuf, description.c_str())) + { + free(sendBuf); + return false; + } + + int state = outf->getState(); + for (int tim=0 ; tim<20 ; tim++) + { + printf("##### waiting for open\n"); + if (state == STREAM_OPEN) + { + outf->reset(); + break; + } + else if (state == STREAM_ERROR) + { + printf("ERROR\n"); + outf->reset(); + return false; + } + Thread::sleep(1000); + state = outf->getState(); + } + if (state != STREAM_OPEN) + { + printf("TIMEOUT ERROR\n"); + outf->reset(); + return false; + } + + //free up this reqource + outf->reset(); + + int streamNr = outputStreamOpen(destJid, streamId); + if (streamNr<0) + { + error("cannot open output stream %s", streamId.c_str()); + outf->reset(); + return false; + } + + int ret = outputStreamWrite(streamNr, sendBuf, fileLen); + + if (ret<0) + { + } + + outputStreamClose(streamNr); + + free(sendBuf); + return true; +} + + +class FileSendThread : public Thread +{ +public: + + FileSendThread(XmppClient &par, + const DOMString &destJidArg, + const DOMString &offeredNameArg, + const DOMString &fileNameArg, + const DOMString &descriptionArg) : client(par) + { + destJid = destJidArg; + offeredName = offeredNameArg; + fileName = fileNameArg; + description = descriptionArg; + } + + virtual ~FileSendThread() {} + + void run() + { + client.fileSend(destJid, offeredName, + fileName, description); + } + +private: + + XmppClient &client; + DOMString destJid; + DOMString offeredName; + DOMString fileName; + DOMString description; +}; + +/** + * + */ +bool XmppClient::fileSendBackground(const DOMString &destJid, + const DOMString &offeredName, + const DOMString &fileName, + const DOMString &description) +{ + FileSendThread thread(*this, destJid, offeredName, + fileName, description); + thread.start(); + return true; +} + + +/** + * + */ +bool XmppClient::fileReceive(const DOMString &fromJid, + const DOMString &iqId, + const DOMString &streamId, + const DOMString &fileName, + long fileSize, + const DOMString &fileHash) +{ + char *fmt = + "" + "" + "" + "" + "" + "" + "http://jabber.org/protocol/ibb" + "\n"; + if (!write(fmt, fromJid.c_str(), iqId.c_str())) + { + return false; + } + + int streamNr = inputStreamOpen(fromJid, streamId, iqId); + if (streamNr < 0) + { + return false; + } + + + Md5 md5; + FILE *f = fopen(fileName.c_str(), "wb"); + if (!f) + { + return false; + } + + while (true) + { + if (inputStreamAvailable(streamNr)<1) + { + if (inputStreamClosing(streamNr)) + break; + pause(100); + continue; + } + std::vector ret = inputStreamRead(streamNr); + std::vector::iterator iter; + for (iter=ret.begin() ; iter!=ret.end() ; iter++) + { + unsigned char ch = *iter; + md5.append(&ch, 1); + fwrite(&ch, 1, 1, f); + } + } + + inputStreamClose(streamNr); + fclose(f); + + DOMString hash = md5.finishHex(); + printf("received file hash:%s\n", hash.c_str()); + + return true; +} + + + +class FileReceiveThread : public Thread +{ +public: + + FileReceiveThread(XmppClient &par, + const DOMString &fromJidArg, + const DOMString &iqIdArg, + const DOMString &streamIdArg, + const DOMString &fileNameArg, + long fileSizeArg, + const DOMString &fileHashArg) : client(par) + { + fromJid = fromJidArg; + iqId = iqIdArg; + streamId = streamIdArg; + fileName = fileNameArg; + fileSize = fileSizeArg; + fileHash = fileHashArg; + } + + virtual ~FileReceiveThread() {} + + void run() + { + client.fileReceive(fromJid, iqId, streamId, + fileName, fileSize, fileHash); + } + +private: + + XmppClient &client; + DOMString fromJid; + DOMString iqId; + DOMString streamId; + DOMString fileName; + long fileSize; + DOMString fileHash; +}; + +/** + * + */ +bool XmppClient::fileReceiveBackground(const DOMString &fromJid, + const DOMString &iqId, + const DOMString &streamId, + const DOMString &fileName, + long fileSize, + const DOMString &fileHash) +{ + FileReceiveThread thread(*this, fromJid, iqId, streamId, + fileName, fileSize, fileHash); + thread.start(); + return true; +} + + + +//######################################################################## +//# X M P P G R O U P C H A T +//######################################################################## + +/** + * + */ +XmppGroupChat::XmppGroupChat(const DOMString &groupJidArg) +{ + groupJid = groupJidArg; +} + +/** + * + */ +XmppGroupChat::XmppGroupChat(const XmppGroupChat &other) +{ + groupJid = other.groupJid; + userList = other.userList; +} + +/** + * + */ +XmppGroupChat::~XmppGroupChat() +{ +} + + +/** + * + */ +DOMString XmppGroupChat::getGroupJid() +{ + return groupJid; +} + + +void XmppGroupChat::userAdd(const DOMString &jid, const DOMString &nick) +{ + std::vector::iterator iter; + for (iter= userList.begin() ; iter!=userList.end() ; iter++) + { + if (iter->nick == nick) + return; + } + XmppUser user(jid, nick); + userList.push_back(user); +} + +void XmppGroupChat::userDelete(const DOMString &jid, const DOMString &nick) +{ + std::vector::iterator iter; + for (iter= userList.begin() ; iter!=userList.end() ; ) + { + if (iter->nick == nick) + iter = userList.erase(iter); + else + iter++; + } +} + +std::vector XmppGroupChat::getUserList() const +{ + return userList; +} + + + + + + +} //namespace Pedro +//######################################################################## +//# E N D O F F I L E +//######################################################################## + + + + + + + + + + + + + + + diff --git a/src/jabber_whiteboard/pedroxmpp.h b/src/jabber_whiteboard/pedroxmpp.h new file mode 100644 index 000000000..574371bf7 --- /dev/null +++ b/src/jabber_whiteboard/pedroxmpp.h @@ -0,0 +1,1023 @@ +#ifndef __XMPP_H__ +#define __XMPP_H__ +/* + * API for the Pedro mini-XMPP client. + * + * Authors: + * Bob Jamison + * + * Copyright (C) 2005 Bob Jamison + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include + +#include + +#include "pedrodom.h" + +namespace Pedro +{ + +typedef std::string DOMString; + + +//######################################################################## +//# X M P P E V E N T +//######################################################################## +class XmppUser +{ +public: + XmppUser() + { + } + XmppUser(const DOMString &jidArg, const DOMString &nickArg) + { + jid = jidArg; + nick = nickArg; + } + XmppUser(const DOMString &jidArg, const DOMString &nickArg, + const DOMString &subscriptionArg, const DOMString &groupArg) + { + jid = jidArg; + nick = nickArg; + subscription = subscriptionArg; + group = groupArg; + } + XmppUser(const XmppUser &other) + { + jid = other.jid; + nick = other.nick; + subscription = other.subscription; + group = other.group; + show = other.show; + } + XmppUser &operator=(const XmppUser &other) + { + jid = other.jid; + nick = other.nick; + subscription = other.subscription; + group = other.group; + show = other.show; + return *this; + } + virtual ~XmppUser() + {} + DOMString jid; + DOMString nick; + DOMString subscription; + DOMString group; + DOMString show; +}; + +class XmppEvent +{ + +public: + +typedef enum + { + EVENT_NONE, + EVENT_STATUS, + EVENT_ERROR, + EVENT_CONNECTED, + EVENT_DISCONNECTED, + EVENT_PRESENCE, + EVENT_ROSTER, + EVENT_MESSAGE, + EVENT_MUC_JOIN, + EVENT_MUC_LEAVE, + EVENT_MUC_PRESENCE, + EVENT_MUC_MESSAGE, + EVENT_STREAM_RECEIVE_INIT, + EVENT_STREAM_RECEIVE, + EVENT_STREAM_RECEIVE_CLOSE, + EVENT_FILE_ACCEPTED, + EVENT_FILE_RECEIVE + } XmppEventType; + + + /** + * + */ + XmppEvent(int type); + + /** + * + */ + XmppEvent(const XmppEvent &other); + + /** + * + */ + virtual XmppEvent &operator=(const XmppEvent &other); + + /** + * + */ + virtual ~XmppEvent(); + + /** + * + */ + virtual void assign(const XmppEvent &other); + + /** + * + */ + virtual int getType() const; + + + /** + * + */ + virtual DOMString getIqId() const; + + + /** + * + */ + virtual void setIqId(const DOMString &val); + + /** + * + */ + virtual DOMString getStreamId() const; + + + /** + * + */ + virtual void setStreamId(const DOMString &val); + + /** + * + */ + virtual bool getPresence() const; + + + /** + * + */ + virtual void setPresence(bool val); + + /** + * + */ + virtual DOMString getShow() const; + + + /** + * + */ + virtual void setShow(const DOMString &val); + + /** + * + */ + virtual DOMString getStatus() const; + + /** + * + */ + virtual void setStatus(const DOMString &val); + + /** + * + */ + virtual DOMString getTo() const; + + /** + * + */ + virtual void setTo(const DOMString &val); + + /** + * + */ + virtual DOMString getFrom() const; + + /** + * + */ + virtual void setFrom(const DOMString &val); + + /** + * + */ + virtual DOMString getGroup() const; + + /** + * + */ + virtual void setGroup(const DOMString &val); + + /** + * + */ + virtual Element *getDOM() const; + + + /** + * + */ + virtual void setDOM(const Element *val); + + /** + * + */ + virtual std::vector getUserList() const; + + /** + * + */ + virtual void setUserList(const std::vector &userList); + + /** + * + */ + virtual DOMString getFileName() const; + + + /** + * + */ + virtual void setFileName(const DOMString &val); + + + /** + * + */ + virtual DOMString getFileDesc() const; + + + /** + * + */ + virtual void setFileDesc(const DOMString &val); + + + /** + * + */ + virtual long getFileSize() const; + + + /** + * + */ + virtual void setFileSize(long val); + + /** + * + */ + virtual DOMString getFileHash() const; + + /** + * + */ + virtual void setFileHash(const DOMString &val); + + /** + * + */ + virtual DOMString getData() const; + + + /** + * + */ + virtual void setData(const DOMString &val); + +private: + + int eventType; + + DOMString iqId; + + DOMString streamId; + + bool presence; + + DOMString show; + + DOMString status; + + DOMString to; + + DOMString from; + + DOMString group; + + DOMString data; + + DOMString fileName; + DOMString fileDesc; + long fileSize; + DOMString fileHash; + + Element *dom; + + std::vectoruserList; + +}; + + +//######################################################################## +//# X M P P E V E N T L I S T E N E R +//######################################################################## + +class XmppEventListener +{ +public: + + /** + * + */ + XmppEventListener() + {} + + /** + * + */ + XmppEventListener(const XmppEventListener &other) + {} + + /** + * + */ + virtual void operator=(const XmppEventListener &other) + {} + + /** + * + */ + virtual ~XmppEventListener() + {} + + /** + * + */ + virtual void processXmppEvent(const XmppEvent &event) + {} + +}; + + + +//######################################################################## +//# X M P P E V E N T T A R G E T +//######################################################################## + +class XmppEventTarget +{ +public: + + /** + * + */ + XmppEventTarget(); + + /** + * + */ + XmppEventTarget(const XmppEventTarget &other); + + /** + * + */ + virtual ~XmppEventTarget(); + + + //########################### + //# M E S S A G E S + //########################### + + + /** + * Send an error message to all subscribers + */ + void error(char *fmt, ...); + + + /** + * Send a status message to all subscribers + */ + void status(char *fmt, ...); + + //########################### + //# LISTENERS + //########################### + + /** + * + */ + virtual void dispatchXmppEvent(const XmppEvent &event); + + /** + * + */ + virtual void addXmppEventListener(const XmppEventListener &listener); + + /** + * + */ + virtual void removeXmppEventListener(const XmppEventListener &listener); + + /** + * + */ + virtual void clearXmppEventListeners(); + + /** + * + */ + void eventQueueEnable(bool val); + + /** + * + */ + int eventQueueAvailable(); + + /** + * + */ + XmppEvent eventQueuePop(); + + +private: + + std::vector listeners; + + std::vector eventQueue; + bool eventQueueEnabled; + + static const int targetWriteBufLen = 2048; + + char targetWriteBuf[targetWriteBufLen]; +}; + + + + + +//######################################################################## +//# X M P P C L I E N T +//######################################################################## + + +class TcpSocket; +class XmppChat; +class XmppGroupChat; +class XmppStream; + +class XmppClient : public XmppEventTarget +{ + +public: + + //########################### + //# CONSTRUCTORS + //########################### + + /** + * + */ + XmppClient(); + + /** + * + */ + XmppClient(const XmppClient &other); + + /** + * + */ + void assign(const XmppClient &other); + + /** + * + */ + virtual ~XmppClient(); + + + //########################### + //# UTILITY + //########################### + + /** + * + */ + virtual bool pause(unsigned long millis); + + //########################### + //# CONNECTION + //########################### + + /** + * + */ + virtual bool connect(); + + /** + * + */ + virtual bool connect(DOMString host, int port, + DOMString userName, + DOMString password, + DOMString resource); + + /** + * + */ + virtual bool disconnect(); + + + /** + * + */ + virtual bool write(char *fmt, ...); + + /** + * + */ + virtual bool isConnected() + { return connected; } + + /** + * + */ + virtual DOMString getHost() + { return host; } + + /** + * + */ + virtual void setHost(const DOMString &val) + { host = val; } + + /** + * + */ + virtual DOMString getRealm() + { return realm; } + + /** + * + */ + virtual void setRealm(const DOMString &val) + { realm = val; } + + /** + * + */ + virtual int getPort() + { return port; } + + /** + * + */ + virtual void setPort(int val) + { port = val; } + + /** + * + */ + virtual DOMString getUsername(); + + /** + * + */ + virtual void setUsername(const DOMString &val); + + /** + * + */ + virtual DOMString getPassword() + { return password; } + + /** + * + */ + virtual void setPassword(const DOMString &val) + { password = val; } + + /** + * + */ + virtual DOMString getResource() + { return resource; } + + /** + * + */ + virtual void setResource(const DOMString &val) + { resource = val; } + + /** + * + */ + virtual DOMString getJid() + { return jid; } + /** + * + */ + virtual int getMsgId() + { return msgId++; } + + /** + * + */ + bool processMessage(Element *root); + + /** + * + */ + bool processPresence(Element *root); + + /** + * + */ + bool processIq(Element *root); + + /** + * + */ + virtual bool receiveAndProcess(); + + /** + * + */ + virtual bool receiveAndProcessLoop(); + + //####################### + //# ROSTER + //####################### + + /** + * + */ + bool rosterAdd(const DOMString &rosterGroup, + const DOMString &otherJid, + const DOMString &name); + + /** + * + */ + bool rosterDelete(const DOMString &otherJid); + + /** + * + */ + std::vector getRoster(); + + + //####################### + //# CHAT (individual) + //####################### + + /** + * + */ + virtual bool message(const DOMString &user, const DOMString &subj, + const DOMString &text); + + /** + * + */ + virtual bool message(const DOMString &user, const DOMString &text); + + /** + * + */ + virtual bool presence(const DOMString &presence); + + //####################### + //# GROUP CHAT + //####################### + + /** + * + */ + virtual bool groupChatCreate(const DOMString &groupJid); + + /** + * + */ + virtual void groupChatDelete(const DOMString &groupJid); + + /** + * + */ + bool groupChatExists(const DOMString &groupJid); + + /** + * + */ + virtual void groupChatsClear(); + + /** + * + */ + virtual void groupChatUserAdd(const DOMString &groupJid, + const DOMString &nick); + + /** + * + */ + virtual void groupChatUserDelete(const DOMString &groupJid, + const DOMString &nick); + + /** + * + */ + virtual std::vector + groupChatGetUserList(const DOMString &groupJid); + + /** + * + */ + virtual bool groupChatJoin(const DOMString &groupJid, + const DOMString &nick, + const DOMString &pass); + + /** + * + */ + virtual bool groupChatLeave(const DOMString &groupJid, + const DOMString &nick); + + /** + * + */ + virtual bool groupChatMessage(const DOMString &groupJid, + const DOMString &msg); + + /** + * + */ + virtual bool groupChatPrivateMessage(const DOMString &groupJid, + const DOMString &toNick, + const DOMString &msg); + + /** + * + */ + virtual bool groupChatPresence(const DOMString &groupJid, + const DOMString &nick, + const DOMString &presence); + + + //####################### + //# STREAMS + //####################### + + typedef enum + { + STREAM_AVAILABLE, + STREAM_OPENING, + STREAM_OPEN, + STREAM_CLOSING, + STREAM_CLOSED, + STREAM_ERROR + } StreamStates; + + /** + * + */ + virtual int outputStreamOpen(const DOMString &jid, + const DOMString &streamId); + + /** + * + */ + virtual int outputStreamWrite(int streamId, + const unsigned char *buf, unsigned long len); + + /** + * + */ + virtual int outputStreamClose(int streamId); + + /** + * + */ + virtual int inputStreamOpen(const DOMString &jid, + const DOMString &streamId, + const DOMString &iqId); + + /** + * + */ + virtual int inputStreamAvailable(int streamId); + + /** + * + */ + virtual std::vector inputStreamRead(int streamId); + + /** + * + */ + virtual bool inputStreamClosing(int streamId); + + /** + * + */ + virtual int inputStreamClose(int streamId); + + + //####################### + //# FILE TRANSFERS + //####################### + + /** + * + */ + virtual bool fileSend(const DOMString &destJid, + const DOMString &offeredName, + const DOMString &fileName, + const DOMString &description); + + /** + * + */ + virtual bool fileSendBackground(const DOMString &destJid, + const DOMString &offeredName, + const DOMString &fileName, + const DOMString &description); + + /** + * + */ + virtual bool fileReceive(const DOMString &fromJid, + const DOMString &iqId, + const DOMString &streamId, + const DOMString &fileName, + long fileSize, + const DOMString &fileHash); + /** + * + */ + virtual bool fileReceiveBackground(const DOMString &fromJid, + const DOMString &iqId, + const DOMString &streamId, + const DOMString &fileName, + long fileSize, + const DOMString &fileHash); + + +private: + + void init(); + + DOMString host; + + /** + * will be same as host, unless username is + * user@realm + */ + DOMString realm; + + int port; + + DOMString username; + + DOMString password; + + DOMString resource; + + DOMString jid; + + int msgId; + + TcpSocket *sock; + + bool connected; + + bool createSession(); + + bool checkConnect(); + + DOMString readStanza(); + + bool saslMd5Authenticate(); + + bool saslPlainAuthenticate(); + + bool saslAuthenticate(); + + bool iqAuthenticate(const DOMString &streamId); + + bool keepGoing; + + static const int writeBufLen = 2048; + + unsigned char writeBuf[writeBufLen]; + + std::vectorgroupChats; + + static const int outputStreamCount = 16; + + XmppStream *outputStreams[outputStreamCount]; + + static const int inputStreamCount = 16; + + XmppStream *inputStreams[inputStreamCount]; + + static const int fileSendCount = 16; + + XmppStream *fileSends[fileSendCount]; + + std::vectorroster; +}; + + + + +//######################################################################## +//# X M P P G R O U P C H A T +//######################################################################## + +/** + * + */ +class XmppGroupChat +{ +public: + + /** + * + */ + XmppGroupChat(const DOMString &groupJid); + + /** + * + */ + XmppGroupChat(const XmppGroupChat &other); + + /** + * + */ + virtual ~XmppGroupChat(); + + /** + * + */ + virtual DOMString getGroupJid(); + + /** + * + */ + virtual void userAdd(const DOMString &jid, const DOMString &nick); + + /** + * + */ + virtual void userDelete(const DOMString &jid, const DOMString &nick); + + /** + * + */ + virtual std::vector getUserList() const; + + +private: + + DOMString groupJid; + + std::vectoruserList; + +}; + + + + + + + + + + +} //namespace Pedro + +#endif /* __XMPP_H__ */ + +//######################################################################## +//# E N D O F F I L E +//######################################################################## + diff --git a/src/jabber_whiteboard/serializer.cpp b/src/jabber_whiteboard/serializer.cpp new file mode 100644 index 000000000..ddba47299 --- /dev/null +++ b/src/jabber_whiteboard/serializer.cpp @@ -0,0 +1,304 @@ +/** + * Inkboard message -> XML::Event* serializer + * + * Authors: + * David Yip + * + * Copyright (c) 2005 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "xml/attribute-record.h" + +#include "jabber_whiteboard/serializer.h" + +#include "util/list.h" +#include "util/shared-c-string-ptr.h" + +#include "jabber_whiteboard/message-utilities.h" +#include "jabber_whiteboard/message-tags.h" +#include "jabber_whiteboard/typedefs.h" +#include "jabber_whiteboard/node-tracker.h" +#include "jabber_whiteboard/node-utilities.h" +#include "jabber_whiteboard/node-tracker-observer.h" + +namespace Inkscape { + +namespace Whiteboard { + +void +Serializer::notifyChildAdded(XML::Node& node, XML::Node& child, XML::Node* prev) +{ + // do not recurse upon initial notification + this->_newObjectEventHelper(node, child, prev, false); + this->_nn.insert(&child); +} + +void +Serializer::_newObjectEventHelper(XML::Node& node, XML::Node& child, XML::Node* prev, bool recurse) +{ + // 1. Check if we are tracking the parent node, + // and issue it an ID if we are not. + std::string parentid = this->_findOrGenerateNodeID(node); + + // 2. Check if the child node is a special node. + // Special nodes are nodes that should appear only once in a document. + // If it is, we do not want to generate a new ID for the child; we will use + // the existing ID. Otherwise, we will generate a new ID for it, since we + // have not yet seen it. + std::string childid; + if (this->_xnt->isSpecialNode(child.name())) { + childid = this->_xnt->get(child); + } else { + // If the child id already exists in the new node buffer, then we've already seen it. + if (!this->actions.tryToTrack(&child, NODE_ADD)) { + return; + } else { + childid = this->_xnt->generateKey(); +// childid = this->_findOrGenerateNodeID(child); + } + } + + // 3. Find this node's previous node, and, if it has one, retrieve its ID. + std::string previd; + if (prev) { + previd = this->_findOrGenerateNodeID(*prev); + } + + // 4. Serialize. + Glib::ustring childmsg = MessageUtilities::makeTagWithContent(MESSAGE_CHILD, childid); + Glib::ustring parentmsg = MessageUtilities::makeTagWithContent(MESSAGE_PARENT, parentid); + Glib::ustring namemsg = MessageUtilities::makeTagWithContent(MESSAGE_NAME, child.name()); + Glib::ustring nodetype = MessageUtilities::makeTagWithContent(MESSAGE_NODETYPE, NodeUtilities::nodeTypeToString(child)); + + Glib::ustring prevmsg; + if (!previd.empty()) { + prevmsg = MessageUtilities::makeTagWithContent(MESSAGE_REF, previd); + } + + Glib::ustring buf = MessageUtilities::makeTagWithContent(MESSAGE_NEWOBJ, childmsg + parentmsg + prevmsg + namemsg + nodetype); + + + this->_events.push_back(buf); + + // 5. Add the child node to the new nodes buffers. + this->newnodes.push_back(SerializedEventNodeAction(KeyNodePair(childid, &child), NODE_ADD)); + this->newkeys[&child] = childid; + this->_parent_child_map[&child] = &node; + + // 6. Scan attributes and content. + Inkscape::Util::List attrlist = child.attributeList(); + + for(; attrlist; attrlist++) { + this->notifyAttributeChanged(child, attrlist->key, Util::SharedCStringPtr(), attrlist->value); + } + + if (child.content()) { + this->notifyContentChanged(child, Util::SharedCStringPtr(), Util::SharedCStringPtr::copy(child.content())); + } + + this->_attributes_scanned.insert(childid); + + // 7. Repeat this process for each child of this child. + if (recurse && child.childCount() > 0) { + XML::Node* prev = child.firstChild(); + for(XML::Node* ch = child.firstChild(); ch; ch = ch->next()) { + if (ch == child.firstChild()) { + // No prev node in this case. + this->_newObjectEventHelper(child, *ch, NULL, true); + } else { + this->_newObjectEventHelper(child, *ch, prev, true); + prev = ch; + } + } + } + + return; +} + + +void +Serializer::notifyChildRemoved(XML::Node& node, XML::Node& child, XML::Node* prev) +{ + // 1. Get the ID of the child. + std::string childid; + + _pc_map_type::iterator i = this->_parent_child_map.find(&child); + if (i != this->_parent_child_map.end() && i->second != &node) { + // Don't look in local! Go for the tracker. + childid = this->_xnt->get(child); + } else if (i == this->_parent_child_map.end()) { + childid = this->_findOrGenerateNodeID(child); + } else if (i->second == &node) { + childid = this->_findOrGenerateNodeID(child); + this->_parent_child_map.erase(i); + } else { + childid = this->_findOrGenerateNodeID(child); + } + + // 2. Double-deletes don't make any sense. If we've seen this node already and if it's + // marked for deletion, return. + if (!this->actions.tryToTrack(&child, NODE_REMOVE)) { + return; + } else { + // 2a. Although we do not have to remove all child nodes of this subtree, + // we _do_ have to mark each child node as deleted. + this->_recursiveMarkAsRemoved(child); + } + + // 2. Mark this node as deleted. We don't want to be faced with the possibility of + // generating a new key for this deleted node, so insert it into both maps. + this->newnodes.push_back(SerializedEventNodeAction(KeyNodePair(childid, &child), NODE_REMOVE)); + this->newkeys[&child] = childid; + this->_nn.erase(&child); + std::string parentid = this->_findOrGenerateNodeID(node); + + + // 4. Serialize the event. + this->_attributes_scanned.erase(childid); + Glib::ustring childidmsg = MessageUtilities::makeTagWithContent(MESSAGE_CHILD, childid); + Glib::ustring parentidmsg = MessageUtilities::makeTagWithContent(MESSAGE_PARENT, parentid); + this->_events.push_back(MessageUtilities::makeTagWithContent(MESSAGE_DELETE, childidmsg + parentidmsg)); +} + + +void +Serializer::notifyChildOrderChanged(XML::Node& node, XML::Node& child, XML::Node* old_prev, XML::Node* new_prev) +{ + // 1. Find the ID of the node, or generate it if it does not exist. + std::string nodeid = this->_findOrGenerateNodeID(child); + + // 2. Find the ID of the parent of this node, or generate it if it does not exist. + std::string parentid = this->_findOrGenerateNodeID(*(child.parent())); + + // 3. Get the ID for the new child reference node, or generate it if it does not exist. + std::string newprevid = this->_findOrGenerateNodeID(*new_prev); + + // 4. Get the ID for the old child reference node, or generate it if it does not exist. + std::string oldprevid = this->_findOrGenerateNodeID(*old_prev); + + // 5. Serialize the event. + Glib::ustring nodeidmsg = MessageUtilities::makeTagWithContent(MESSAGE_ID, nodeid); + Glib::ustring parentidmsg = MessageUtilities::makeTagWithContent(MESSAGE_PARENT, parentid); + Glib::ustring oldprevidmsg = MessageUtilities::makeTagWithContent(MESSAGE_OLDVAL, oldprevid); + Glib::ustring newprevidmsg = MessageUtilities::makeTagWithContent(MESSAGE_NEWVAL, newprevid); + + this->_events.push_back(MessageUtilities::makeTagWithContent(MESSAGE_ORDERCHANGE, nodeidmsg + parentidmsg + oldprevidmsg + newprevidmsg)); +} + +void +Serializer::notifyContentChanged(XML::Node& node, Util::SharedCStringPtr old_content, Util::SharedCStringPtr new_content) +{ + // 1. Find the ID of the node, or generate it if it does not exist. + std::string nodeid = this->_findOrGenerateNodeID(node); + + std::string oldvalmsg, newvalmsg; + + // 2. If the old and new content are identical, don't send out this change. + // (identical meaning "same string" or "same string content") + if (old_content == new_content) { + return; + } + + if (old_content.cString() != NULL && new_content.cString() != NULL) { + if (strcmp(old_content.cString(), new_content.cString()) == 0) { + return; + } + } + + // 3. Serialize the event. + if (old_content.cString() != NULL) { + oldvalmsg = MessageUtilities::makeTagWithContent(MESSAGE_OLDVAL, old_content.cString()); + } + + if (new_content.cString() != NULL) { + newvalmsg = MessageUtilities::makeTagWithContent(MESSAGE_NEWVAL, new_content.cString()); + } + + Glib::ustring nodeidmsg = MessageUtilities::makeTagWithContent(MESSAGE_ID, nodeid); + this->_events.push_back(MessageUtilities::makeTagWithContent(MESSAGE_NODECONTENT, nodeidmsg + oldvalmsg + newvalmsg)); +} + +void +Serializer::notifyAttributeChanged(XML::Node& node, GQuark name, Util::SharedCStringPtr old_value, Util::SharedCStringPtr new_value) +{ + // 1. Find the ID of the node that has had an attribute modified, or generate it if it + // does not exist. + std::string nodeid = this->_findOrGenerateNodeID(node); + + // Proceed with 2-4 if the node has not already been scanned by notifyChildAdded. + if (this->_attributes_scanned.find(nodeid) == this->_attributes_scanned.end()) { + // 2. Convert the key to a string. + Glib::ustring key = g_quark_to_string(name); + + // 3. If oldval == newval, don't echo this change. + if (new_value.cString() != NULL && old_value.cString() != NULL) { + if (strcmp(new_value.cString(), old_value.cString()) == 0) { + return; + } + } + + // 4. Serialize the event. + Glib::ustring keymsg = MessageUtilities::makeTagWithContent(MESSAGE_KEY, key); + Glib::ustring oldvalmsg, newvalmsg; + + if (old_value.cString() != NULL) { + oldvalmsg = MessageUtilities::makeTagWithContent(MESSAGE_OLDVAL, old_value.cString()); + } + + if (new_value.cString() != NULL) { + newvalmsg = MessageUtilities::makeTagWithContent(MESSAGE_NEWVAL, new_value.cString()); + } + + Glib::ustring nodeidmsg = MessageUtilities::makeTagWithContent(MESSAGE_ID, nodeid); + + this->_events.push_back(MessageUtilities::makeTagWithContent(MESSAGE_CHANGE, nodeidmsg + keymsg + oldvalmsg + newvalmsg)); + } +} + +void +Serializer::synthesizeChildNodeAddEvents() +{ + _New_nodes_type::iterator i = this->_nn.begin(); + for(; i != this->_nn.end(); ++i) { + XML::Node* parent = *i; + // The root of the subtree defined by parent has already been considered; now, + // recursively look at the rest of the tree. + XML::Node* prev = parent->firstChild(); + for(XML::Node* ch = parent->firstChild(); ch; ch = ch->next()) { + if (ch == parent->firstChild()) { + this->_newObjectEventHelper(*parent, *ch, NULL, true); + } else { + this->_newObjectEventHelper(*parent, *ch, prev, true); + prev = ch; + } + } + } +} + + +void +Serializer::_recursiveMarkAsRemoved(XML::Node& node) +{ + this->actions.tryToTrack(&node, NODE_REMOVE); + + for(XML::Node* ch = node.firstChild(); ch; ch = ch->next()) { + this->_recursiveMarkAsRemoved(*ch); + } +} + +} + +} + +/* + 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:textwidth=99 : diff --git a/src/jabber_whiteboard/serializer.h b/src/jabber_whiteboard/serializer.h new file mode 100644 index 000000000..cc0aa97b6 --- /dev/null +++ b/src/jabber_whiteboard/serializer.h @@ -0,0 +1,118 @@ +/** + * Inkboard message -> XML::Event* serializer + * + * Authors: + * David Yip + * + * Copyright (c) 2005 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifndef __WHITEBOARD_MESSAGE_SERIALIZER_H__ +#define __WHITEBOARD_MESSAGE_SERIALIZER_H__ + +#include "xml/node-observer.h" + +#include "util/shared-c-string-ptr.h" + +#include "jabber_whiteboard/node-tracker.h" +#include "jabber_whiteboard/typedefs.h" +#include "jabber_whiteboard/node-tracker-observer.h" + +#include + +namespace Inkscape { + +namespace Whiteboard { + +class Serializer : public NodeTrackerObserver { +public: + Serializer(XMLNodeTracker* xnt) : NodeTrackerObserver(xnt) { } + ~Serializer() { } + + void notifyChildAdded(XML::Node &node, XML::Node &child, XML::Node *prev); + + void notifyChildRemoved(XML::Node &node, XML::Node &child, XML::Node *prev); + + void notifyChildOrderChanged(XML::Node &node, XML::Node &child, + XML::Node *old_prev, XML::Node *new_prev); + + void notifyContentChanged(XML::Node &node, + Util::SharedCStringPtr old_content, + Util::SharedCStringPtr new_content); + + void notifyAttributeChanged(XML::Node &node, GQuark name, + Util::SharedCStringPtr old_value, + Util::SharedCStringPtr new_value); + + void synthesizeChildNodeAddEvents(); + + SerializedEventList& getEventList() + { + return this->_events; + } + + SerializedEventList getEventListCopy() + { + return this->_events; + } + + SerializedEventList getAndClearEventList() + { + SerializedEventList ret = this->_events; + this->_events.clear(); + return ret; + } + + void clearEventList() + { + this->_events.clear(); + } + + void clearAttributesScannedBuffer() + { + this->_attributes_scanned.clear(); + } + + // Convenience method for resetting all stateful aspects of the serializer + void reset() + { + g_log(NULL, G_LOG_LEVEL_DEBUG, "Clearing serializer buffers"); + this->clearEventList(); + this->_parent_child_map.clear(); + this->_nn.clear(); + this->clearNodeBuffers(); + this->clearAttributesScannedBuffer(); + } + +private: + typedef std::set< XML::Node* > _New_nodes_type; + typedef std::map< XML::Node*, XML::Node* > _pc_map_type; + + SerializedEventList _events; + AttributesScannedSet _attributes_scanned; + + _New_nodes_type _nn; + _pc_map_type _parent_child_map; + + void _newObjectEventHelper(XML::Node& parent, XML::Node& child, XML::Node* prev, bool recurse); + void _recursiveMarkAsRemoved(XML::Node& node); +}; + +} + +} + +#endif + +/* + 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:textwidth=99 : diff --git a/src/jabber_whiteboard/session-file-player.cpp b/src/jabber_whiteboard/session-file-player.cpp new file mode 100644 index 000000000..538d0bc91 --- /dev/null +++ b/src/jabber_whiteboard/session-file-player.cpp @@ -0,0 +1,176 @@ +/** + * Whiteboard session file playback mechanism + * + * Authors: + * David Yip + * + * Copyright (c) 2005 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + + +#include +#include + +#include + +#include "desktop-handles.h" +#include "document.h" + +#include "jabber_whiteboard/defines.h" +#include "jabber_whiteboard/session-file.h" +#include "jabber_whiteboard/session-file-player.h" +#include "jabber_whiteboard/session-manager.h" + +namespace Inkscape { + +namespace Whiteboard { + +SessionFilePlayer::SessionFilePlayer(unsigned int bufsz, SessionManager* sm) +{ + this->_sm = sm; + this->_delay = 100; + this->_playing = false; + this->_curdir = FORWARD; + + this->_current = this->_next = 0; + this->_sf = NULL; + + if (sm->session_file() != NULL) { + this->_sf = sm->session_file(); + } else { + g_warning("Cannot operate on NULL SessionFile."); + } +} + +SessionFilePlayer::~SessionFilePlayer() +{ + +} + +void +SessionFilePlayer::load(SessionFile* sm) +{ + this->stop(); + if (this->_sm != NULL) { + this->_sf = sm; + this->_current = this->_next = 0; + this->_visited.clear(); + } +} + +SessionFile* +SessionFilePlayer::unload() +{ + SessionFile* sf = this->_sf; + this->stop(); + this->_sf = NULL; + return sf; +} + +Glib::ustring const& +SessionFilePlayer::filename() +{ + return this->_sf->filename(); +} + +Glib::ustring const& +SessionFilePlayer::curmsg() +{ + return this->_curmsg; +} + +void +SessionFilePlayer::start() +{ + this->_playback_dispatcher = Glib::signal_timeout().connect(sigc::bind< 0 > (sigc::mem_fun(*(this), &SessionFilePlayer::step), this->_curdir), this->_delay); + this->_playing = true; +} + +void +SessionFilePlayer::stop() +{ + this->_playback_dispatcher.disconnect(); + this->_playing = false; +} + +void +SessionFilePlayer::setDelay(unsigned int delay) +{ + this->_delay = delay; + if (this->_playing) { + this->stop(); + this->start(); + } +} + +void +SessionFilePlayer::setMessageOutputWidget(Glib::RefPtr const& widgetptr) +{ + this->_outputwidget = widgetptr; +} + +bool +SessionFilePlayer::step(unsigned short dir) +{ + switch (dir) { + case FORWARD: { + // Glib::ustring buf; + this->_current = this->_next; + this->_next = this->_sf->nextMessageFrom(this->_current, this->_curmsg); + if (this->_next == this->_current) { + return false; + } else { + this->_visited.push_front(std::make_pair< gint64, gint64 >(this->_current, this->_curmsg.bytes())); + this->_outputMessageToWidget(); + this->_sm->receiveChange(this->_curmsg); + sp_document_done(SP_DT_DOCUMENT(this->_sm->desktop())); + this->_curdir = FORWARD; + return true; + } + break; + } + case BACKWARD: + if (this->_current == 0) { + return false; + } else { + this->_visited.pop_front(); + std::pair< gint64, gint64 > last = this->_visited.front(); + this->_current = last.first; + this->_next = last.first + last.second; + this->_sf->nextMessageFrom(this->_current, this->_curmsg); + this->_outputMessageToWidget(); + sp_document_undo(SP_DT_DOCUMENT(this->_sm->desktop())); + this->_curdir = BACKWARD; + return true; + } + break; + default: + return true; + break; + } +} + +void +SessionFilePlayer::_outputMessageToWidget() +{ + if (this->_outputwidget) { + this->_outputwidget->set_text(this->_curmsg); + } +} + +} + +} + +/* + 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:textwidth=99 : diff --git a/src/jabber_whiteboard/session-file-player.h b/src/jabber_whiteboard/session-file-player.h new file mode 100644 index 000000000..aa2e2b4c1 --- /dev/null +++ b/src/jabber_whiteboard/session-file-player.h @@ -0,0 +1,99 @@ +/** + * Whiteboard session file playback mechanism + * + * Authors: + * David Yip + * + * Copyright (c) 2005 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifndef __WHITEBOARD_SESSION_FILE_PLAYER_H__ +#define __WHITEBOARD_SESSION_FILE_PLAYER_H__ + +#include +#include +#include +#include +#include + +struct SPDesktop; + +namespace Inkscape { + namespace UI { + namespace Dialog { + class SessionPlaybackDialogImpl; + } + } + namespace Whiteboard { + +class SessionFile; +class SessionManager; + +class SessionFilePlayer { +friend class UI::Dialog::SessionPlaybackDialogImpl; + +public: + SessionFilePlayer(unsigned int bufsz, SessionManager* sm); + ~SessionFilePlayer(); + + void load(SessionFile* sm); + SessionFile* unload(); + + Glib::ustring const& filename(); + Glib::ustring const& curmsg(); + + void start(); + void stop(); + void setDelay(unsigned int delay); + void setMessageOutputWidget(Glib::RefPtr const& widgetptr); + + static unsigned short const BACKWARD = 0; + static unsigned short const FORWARD = 1; + +private: + bool step(unsigned short dir); + void _outputMessageToWidget(); + + SessionManager* _sm; + SessionFile* _sf; + + // Output widget refptr + Glib::RefPtr _outputwidget; + + // Playback signal + sigc::connection _playback_dispatcher; + + // trackers + unsigned int _delay; + unsigned short _curdir; + bool _playing; + Glib::ustring _curmsg; + + // (position, msgsize) + std::list< std::pair< gint64, gint64 > > _visited; + gint64 _current; + gint64 _next; + + // noncopyable, nonassignable + SessionFilePlayer(SessionFilePlayer const&); + void operator=(SessionFilePlayer const&); +}; + +} + +} + +#endif + +/* + 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:textwidth=99 : diff --git a/src/jabber_whiteboard/session-file-selector.cpp b/src/jabber_whiteboard/session-file-selector.cpp new file mode 100644 index 000000000..85a3a3ec1 --- /dev/null +++ b/src/jabber_whiteboard/session-file-selector.cpp @@ -0,0 +1,90 @@ +/** + * Session file selector widget + * + * Authors: + * David Yip + * + * Copyright (c) 2005 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "session-file-selector.h" + +#include +#include +#include + +namespace Inkscape { + +namespace Whiteboard { + +SessionFileSelectorBox::SessionFileSelectorBox() : + _usesessionfile(_("_Write session file:"), true) +{ + this->_construct(); +} + +SessionFileSelectorBox::~SessionFileSelectorBox() +{ + +} + +bool +SessionFileSelectorBox::isSelected() +{ + return this->_usesessionfile.get_active(); +} + +Glib::ustring const& +SessionFileSelectorBox::getFilename() +{ + return this->_filename; +} + +void +SessionFileSelectorBox::_construct() +{ + this->_getfilepath.set_label("..."); + + this->pack_start(this->_usesessionfile); + this->pack_start(this->_sessionfile); + this->pack_end(this->_getfilepath); + + this->_getfilepath.signal_clicked().connect(sigc::mem_fun(*this, &SessionFileSelectorBox::_callback)); +} + +void +SessionFileSelectorBox::_callback() { + Gtk::FileChooserDialog sessionfiledlg(_("Select a location and filename"), Gtk::FILE_CHOOSER_ACTION_SAVE); + sessionfiledlg.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); + sessionfiledlg.add_button(_("Set filename"), Gtk::RESPONSE_OK); + int result = sessionfiledlg.run(); + switch (result) { + case Gtk::RESPONSE_OK: + { + this->_usesessionfile.set_active(); + this->_sessionfile.set_text(sessionfiledlg.get_filename()); + this->_filename = sessionfiledlg.get_filename(); + break; + } + case Gtk::RESPONSE_CANCEL: + default: + break; + } +} + +} + +} + + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ diff --git a/src/jabber_whiteboard/session-file-selector.h b/src/jabber_whiteboard/session-file-selector.h new file mode 100644 index 000000000..fe097e4ab --- /dev/null +++ b/src/jabber_whiteboard/session-file-selector.h @@ -0,0 +1,61 @@ +/** + * Session file selector widget + * + * Authors: + * David Yip + * + * Copyright (c) 2005 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifndef __WHITEBOARD_SESSION_FILE_SELECTOR_BOX_H__ +#define __WHITEBOARD_SESSION_FILE_SELECTOR_BOX_H__ + +#include +#include +#include +#include + +namespace Inkscape { + +namespace Whiteboard { + +class SessionFileSelectorBox : public Gtk::HBox { +public: + SessionFileSelectorBox(); + ~SessionFileSelectorBox(); + + bool isSelected(); + Glib::ustring const& getFilename(); + +private: + // Construction + void _construct(); + void _callback(); + + // GTK+ widgets + Gtk::CheckButton _usesessionfile; + Gtk::Entry _sessionfile; + Gtk::Button _getfilepath; + + // Internal state + Glib::ustring _filename; +}; + +} + +} + +#endif + +/* + 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:textwidth=99 : diff --git a/src/jabber_whiteboard/session-file.cpp b/src/jabber_whiteboard/session-file.cpp new file mode 100644 index 000000000..137e56510 --- /dev/null +++ b/src/jabber_whiteboard/session-file.cpp @@ -0,0 +1,140 @@ +/** + * Whiteboard session file object + * + * Authors: + * David Yip + * + * Copyright (c) 2005 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include +#include + +#include "util/list-container.h" + +#include "jabber_whiteboard/message-utilities.h" +#include "jabber_whiteboard/node-utilities.h" +#include "jabber_whiteboard/typedefs.h" + +#include "jabber_whiteboard/session-file.h" + + +namespace Inkscape { + +namespace Whiteboard { + +SessionFile::SessionFile(Glib::ustring const& filename, bool reading, bool compress) : _filename(filename), _compress(compress), _reading(reading) +{ + try { + + if (!reading) { + this->fptr = Glib::IOChannel::create_from_file(filename, "w+"); + } else { + this->fptr = Glib::IOChannel::create_from_file(filename, "r"); + } + this->_ateof = false; + } catch (Glib::FileError) { + throw; + } +} + +SessionFile::~SessionFile() +{ + if (!this->_reading) { + this->commit(); + } + this->close(); +} + +gint64 +SessionFile::nextMessageFrom(gint64 from, Glib::ustring& buf) +{ + try { + Glib::ustring line; + Glib::IOStatus st; + Node part; + + gint64 accum = from; + buf = ""; + this->fptr->seek(accum, Glib::SEEK_TYPE_SET); + + while(part.tag != MESSAGE_COMMIT) { + st = this->fptr->read_line(line); + if (st == Glib::IO_STATUS_EOF) { + break; + } else { + accum += line.bytes(); + this->fptr->seek(accum); + MessageUtilities::getFirstMessageTag(part, line); + buf += line; + line.clear(); + } + } + + if (st == Glib::IO_STATUS_NORMAL) { + // reset eof flag if successful + this->_ateof = false; + return from + buf.bytes(); + } else { + if (st == Glib::IO_STATUS_EOF) { + this->_ateof = true; + } + return from; + } + } catch (Glib::IOChannelError e) { + g_warning("Could not read next message due to I/O error (error: %s)!", e.what().data()); + } catch (Glib::ConvertError e) { + g_warning("Could not read next message due to charset conversion error (error: %s)!", e.what().data()); + } + + return from; +} + +void +SessionFile::addMessage(Glib::ustring const& message) +{ + Glib::ustring msg = message; + this->changes.push_back(msg); +} + +void +SessionFile::commit() +{ + if (!this->_reading) { + SessionQueue::iterator i = changes.begin(); + for(; i != changes.end(); i++) { + try { + fptr->write(*i); + changes.erase(i); + } catch (Glib::IOChannelError e) { + g_warning("Caught I/O exception (error string: %s) while committing change to session file %s. Attempting to commit remaining changes; session file will be inconsistent with whiteboard session history.", e.what().c_str(), this->_filename.c_str()); + } catch (Glib::ConvertError e) { + g_warning("Caught character set conversion error (error string: %s) while committing change to session file %s. Attempting to commit remaining changes; session file will be inconsistent with whiteboard session history.", e.what().c_str(), this->_filename.c_str()); + } + } + fptr->write("\n"); + } +} + +void +SessionFile::close() +{ + fptr->close(true); +} + +} + +} + +/* + 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:textwidth=99 : diff --git a/src/jabber_whiteboard/session-file.h b/src/jabber_whiteboard/session-file.h new file mode 100644 index 000000000..926d27af5 --- /dev/null +++ b/src/jabber_whiteboard/session-file.h @@ -0,0 +1,78 @@ +/** + * Whiteboard session file object + * + * Authors: + * David Yip + * + * Copyright (c) 2005 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifndef __WHITEBOARD_SESSION_FILE_H__ +#define __WHITEBOARD_SESSION_FILE_H__ + +#include +#include "util/list-container.h" + +struct SPDesktop; + +namespace Inkscape { + +namespace Whiteboard { + +typedef Glib::RefPtr< Glib::IOChannel > SessionFilePtr; +typedef Util::ListContainer< Glib::ustring const > SessionQueue; + +class SessionFile { +public: + SessionFile(Glib::ustring const& filename, bool reading, bool compress); + ~SessionFile(); + + gint64 nextMessageFrom(gint64 from, Glib::ustring& buf); + + void addMessage(Glib::ustring const& message); + void commit(); + void close(); + + Glib::ustring const& filename() + { + return this->_filename; + } + + bool isReadOnly() + { + return this->_reading; + } + + bool eof() + { + return this->_ateof; + } + +private: + SessionQueue changes; + SessionFilePtr fptr; + Glib::ustring _filename; + + bool _ateof; + bool _compress; + bool _reading; +}; + +} + +} +#endif + + +/* + 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:textwidth=99 : diff --git a/src/jabber_whiteboard/session-manager.cpp b/src/jabber_whiteboard/session-manager.cpp new file mode 100644 index 000000000..a52a7a878 --- /dev/null +++ b/src/jabber_whiteboard/session-manager.cpp @@ -0,0 +1,1118 @@ +/** + * Whiteboard session manager + * + * Authors: + * David Yip + * + * Copyright (c) 2005 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +/* +#include "inkscape.h" +*/ + +#include + +#include +#include +#include +#include +#include + +#include "gc-anchored.h" + +#include "xml/repr.h" +#include "xml/node-observer.h" + +#include "util/ucompose.hpp" + +#include "message-context.h" +#include "message-stack.h" +#include "desktop-handles.h" +#include "document.h" +#include "document-private.h" +#include "verbs.h" + +#include "jabber_whiteboard/defines.h" +#include "jabber_whiteboard/typedefs.h" +#include "jabber_whiteboard/deserializer.h" +#include "jabber_whiteboard/message-utilities.h" +#include "jabber_whiteboard/message-handler.h" +#include "jabber_whiteboard/node-tracker.h" +#include "jabber_whiteboard/jabber-handlers.h" +#include "jabber_whiteboard/callbacks.h" +#include "jabber_whiteboard/chat-handler.h" +#include "jabber_whiteboard/session-file.h" +#include "jabber_whiteboard/session-file-player.h" +#include "jabber_whiteboard/session-manager.h" +#include "jabber_whiteboard/message-aggregator.h" +#include "jabber_whiteboard/undo-stack-observer.h" +#include "jabber_whiteboard/serializer.h" + +//#include "jabber_whiteboard/pedro/pedroxmpp.h" + +#include "jabber_whiteboard/message-node.h" +#include "jabber_whiteboard/message-queue.h" + +namespace Inkscape { + +namespace Whiteboard { + +#ifdef WIN32 +static bool lm_initialize_called = false; +#endif + +SessionData::SessionData(SessionManager *sm) +{ + this->_sm = sm; + this->recipient = NULL; + this->connection = NULL; + this->ssl = NULL; + this->ignoreFurtherSSLErrors = false; + this->send_queue = new SendMessageQueue(sm); + this->sequence_number = 1; +} + +SessionData::~SessionData() +{ + this->receive_queues.clear(); + + if (this->send_queue) { + delete this->send_queue; + } +} + +SessionManager::SessionManager(::SPDesktop *desktop) +{ + + // Initialize private members to NULL to facilitate deletion in destructor + this->_myDoc = NULL; + this->session_data = NULL; + this->_myCallbacks = NULL; + this->_myTracker = NULL; + this->_myChatHandler = NULL; + this->_mySessionFile = NULL; + this->_mySessionPlayer = NULL; + this->_myMessageHandler = NULL; + this->_myUndoObserver = NULL; + this->_mySerializer = NULL; + this->_myDeserializer = NULL; + + this->setDesktop(desktop); + + if (this->_myDoc == NULL) { + g_error("Initializing SessionManager on null document object!"); + } + + +#ifdef WIN32 + //# lm_initialize() must be called before any network code + if (!lm_initialize_called) { + lm_initialize(); + lm_initialize_called = true; + } +#endif + + this->_setVerbSensitivity(INITIAL); +} + +SessionManager::~SessionManager() +{ + + if (this->session_data) { + if (this->session_data->status[IN_WHITEBOARD]) { + // also calls closeSession + this->disconnectFromDocument(); + } + this->disconnectFromServer(); + + if (this->session_data->status[LOGGED_IN]) { + // TODO: unref message handlers + } + } + + if (this->_mySessionFile) { + delete this->_mySessionPlayer; + delete this->_mySessionFile; + } + + delete this->_myChatHandler; + + + // Deletion of _myTracker is done in closeSession; + // no need to do it here. + + // Deletion is handled separately from session teardown and server disconnection + // because some teardown methods (e.g. closeSession) require access to members that we will + // be deleting. Separating deletion from teardown means that we do not have + // to worry (as much) about proper ordering of the teardown sequence. (We still need + // to ensure that destructors in each object being deleted have access to all the + // members they need, though.) + + // Stop dispatchers + if (this->_myCallbacks) { + this->stopSendQueueDispatch(); + this->stopReceiveQueueDispatch(); + delete this->_myCallbacks; + } + + delete this->_myMessageHandler; + + delete this->session_data; + + Inkscape::GC::release(this->_myDoc); + +} + +void +SessionManager::setDesktop(::SPDesktop* desktop) +{ + this->_myDesktop = desktop; + if (this->_myDoc != NULL) { + Inkscape::GC::release(this->_myDoc); + } + if (SP_DT_DOCUMENT(desktop) != NULL) { + this->_myDoc = SP_DT_DOCUMENT(desktop); + Inkscape::GC::anchor(this->_myDoc); + } +} + +int +SessionManager::connectToServer(Glib::ustring const& server, Glib::ustring const& port, Glib::ustring const& username, Glib::ustring const& pw, bool usessl) +{ + GError* error = NULL; + Glib::ustring jid; + + // JID format is username@server/resource + jid += username + "@" + server + "/" + RESOURCE_NAME; + + LmMessage* m; + LmMessageHandler* mh; + + if (!this->session_data) { + this->session_data = new SessionData(this); + } + + if (!this->_myMessageHandler) { + this->_myMessageHandler = new MessageHandler(this); + } + + // Connect to server + // We need to check to see if this object already exists, because + // the user may be reusing an old connection that failed due to e.g. + // authentication failure. + if (this->session_data->connection) { + lm_connection_close(this->session_data->connection, &error); + lm_connection_unref(this->session_data->connection); + } + + this->session_data->connection = lm_connection_new(server.c_str()); + + lm_connection_set_port(this->session_data->connection, atoi(port.c_str())); + + if (usessl) { + if (lm_ssl_is_supported()) { + this->session_data->ssl = lm_ssl_new(NULL, ssl_error_handler, reinterpret_cast< gpointer >(this), NULL); + + lm_ssl_ref(this->session_data->ssl); + } else { + return SSL_INITIALIZATION_ERROR; + } + lm_connection_set_ssl(this->session_data->connection, this->session_data->ssl); + } + + // Send authorization + lm_connection_set_jid(this->session_data->connection, jid.c_str()); + + // TODO: + // Asynchronous connection and authentication would be nice, + // but it's a huge mess of mixing C callbacks and C++ method calls. + // I've tried to do it and only managed to severely destabilize the Jabber + // server connection routines. + // + // This, of course, is an invitation to anyone more capable than me + // to convert this from synchronous to asynchronous Loudmouth calls. + if (!lm_connection_open_and_block(this->session_data->connection, &error)) { + if (error != NULL) { + g_warning("Failed to open: %s", error->message); + } + return FAILED_TO_CONNECT; + } + + // Authenticate + if (!lm_connection_authenticate_and_block(this->session_data->connection, username.c_str(), pw.c_str(), RESOURCE_NAME, &error)) { + if (error != NULL) { + g_warning("Failed to authenticate: %s", error->message); + } + lm_connection_close(this->session_data->connection, NULL); + lm_connection_unref(this->session_data->connection); + this->session_data->connection = NULL; + return INVALID_AUTH; + } + + // Register message handler for presence messages + mh = lm_message_handler_new((LmHandleMessageFunction)presence_handler, reinterpret_cast< gpointer >(this->_myMessageHandler), NULL); + lm_connection_register_message_handler(this->session_data->connection, mh, LM_MESSAGE_TYPE_PRESENCE, LM_HANDLER_PRIORITY_NORMAL); + + // Register message handler for stream error messages + mh = lm_message_handler_new((LmHandleMessageFunction)stream_error_handler, reinterpret_cast< gpointer >(this->_myMessageHandler), NULL); + lm_connection_register_message_handler(this->session_data->connection, mh, LM_MESSAGE_TYPE_STREAM_ERROR, LM_HANDLER_PRIORITY_NORMAL); + + // Register message handler for chat messages + mh = lm_message_handler_new((LmHandleMessageFunction)default_handler, reinterpret_cast< gpointer >(this->_myMessageHandler), NULL); + lm_connection_register_message_handler(this->session_data->connection, mh, LM_MESSAGE_TYPE_MESSAGE, LM_HANDLER_PRIORITY_NORMAL); + + // Send presence message to server + m = lm_message_new_with_sub_type(NULL, LM_MESSAGE_TYPE_PRESENCE, LM_MESSAGE_SUB_TYPE_NOT_SET); + if (!lm_connection_send(this->session_data->connection, m, &error)) { + if (error != NULL) { + g_warning("Presence message could not be sent: %s", error->message); + } + lm_connection_close(this->session_data->connection, NULL); + lm_connection_unref(this->session_data->connection); + this->session_data->connection = NULL; + return FAILED_TO_CONNECT; + } + + this->session_data->status.set(LOGGED_IN, 1); + + this->_myCallbacks = new Callbacks(this); + + lm_message_unref(m); + + this->_setVerbSensitivity(ESTABLISHED_CONNECTION); + + return CONNECT_SUCCESS; +} + +LmSSLResponse +SessionManager::handleSSLError(LmSSL* ssl, LmSSLStatus status) +{ + if (this->session_data->ignoreFurtherSSLErrors) { + return LM_SSL_RESPONSE_CONTINUE; + } + + Glib::ustring msg; + + // TODO: It'd be nice to provide the user with additional information in some cases, + // like fingerprints, hostname, etc. + switch(status) { + case LM_SSL_STATUS_NO_CERT_FOUND: + msg = _("No SSL certificate was found."); + break; + case LM_SSL_STATUS_UNTRUSTED_CERT: + msg = _("The SSL certificate provided by the Jabber server is untrusted."); + break; + case LM_SSL_STATUS_CERT_EXPIRED: + msg = _("The SSL certificate provided by the Jabber server is expired."); + break; + case LM_SSL_STATUS_CERT_NOT_ACTIVATED: + msg = _("The SSL certificate provided by the Jabber server has not been activated."); + break; + case LM_SSL_STATUS_CERT_HOSTNAME_MISMATCH: + msg = _("The SSL certificate provided by the Jabber server contains a hostname that does not match the Jabber server's hostname."); + break; + case LM_SSL_STATUS_CERT_FINGERPRINT_MISMATCH: + msg = _("The SSL certificate provided by the Jabber server contains an invalid fingerprint."); + break; + case LM_SSL_STATUS_GENERIC_ERROR: + msg = _("An unknown error occurred while setting up the SSL connection."); + break; + } + + // TRANSLATORS: %1 is the message that describes the specific error that occurred when + // establishing the SSL connection. + Glib::ustring mainmsg = String::ucompose(_("%1\n\nDo you wish to continue connecting to the Jabber server?"), msg); + + Gtk::MessageDialog dlg(mainmsg, true, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_NONE, false); + dlg.add_button(_("Continue connecting and ignore further errors"), 0); + dlg.add_button(_("Continue connecting, but warn me of further errors"), 1); + dlg.add_button(_("Cancel connection"), 2); + + switch(dlg.run()) { + case 0: + this->session_data->ignoreFurtherSSLErrors = true; + /* FALL-THROUGH */ + case 1: + return LM_SSL_RESPONSE_CONTINUE; + + default: + return LM_SSL_RESPONSE_STOP; + } +} + +void +SessionManager::disconnectFromServer() +{ + if (this->session_data->connection) { + GError* error = NULL; + + LmMessage *m; + this->disconnectFromDocument(); + m = lm_message_new_with_sub_type(NULL, LM_MESSAGE_TYPE_PRESENCE, LM_MESSAGE_SUB_TYPE_UNAVAILABLE); + if (!lm_connection_send(this->session_data->connection, m, &error)) { + g_warning("Could not send unavailable presence message: %s", error->message); + } + + lm_message_unref(m); + lm_connection_close(this->session_data->connection, NULL); + lm_connection_unref(this->session_data->connection); + if (this->session_data->ssl) { + lm_ssl_unref(this->session_data->ssl); + } + + this->session_data->connection = NULL; + this->session_data->ssl = NULL; + this->_setVerbSensitivity(INITIAL); + } +} + +void +SessionManager::disconnectFromDocument() +{ + if (this->session_data->status[IN_WHITEBOARD] || !this->session_data->status[IN_CHATROOM]) { + this->sendMessage(DISCONNECTED_FROM_USER_SIGNAL, 0, "", this->session_data->recipient, false); + } + this->closeSession(); + this->_setVerbSensitivity(DISCONNECTED_FROM_SESSION); +} + +void +SessionManager::closeSession() +{ + + if (this->session_data->status[IN_WHITEBOARD]) { + this->session_data->status.set(IN_WHITEBOARD, 0); + this->session_data->receive_queues.clear(); + this->session_data->send_queue->clear(); + this->stopSendQueueDispatch(); + this->stopReceiveQueueDispatch(); + } + + if (this->_myUndoObserver) { + this->_myDoc->removeUndoObserver(*this->_myUndoObserver); + } + + delete this->_myUndoObserver; + delete this->_mySerializer; + delete this->_myDeserializer; + + this->_myUndoObserver = NULL; + this->_mySerializer = NULL; + this->_myDeserializer = NULL; + + if (this->_myTracker) { + delete this->_myTracker; + this->_myTracker = NULL; + } + + + this->setRecipient(NULL); +} + +void +SessionManager::setRecipient(char const* recipientJID) +{ + if (this->session_data->recipient) { + free(const_cast< gchar* >(this->session_data->recipient)); + } + + if (recipientJID == NULL) { + this->session_data->recipient = NULL; + } else { + this->session_data->recipient = g_strdup(recipientJID); + } +} + +void +SessionManager::sendChange(Glib::ustring const& msg, MessageType type, std::string const& recipientJID, bool chatroom) +{ + if (!this->session_data->status[IN_WHITEBOARD]) { + return; + } + + std::string& recipient = const_cast< std::string& >(recipientJID); + if (recipient.empty()) { + recipient = this->session_data->recipient; + } + + + switch (type) { + case DOCUMENT_BEGIN: + case DOCUMENT_END: + case CHANGE_NOT_REPEATABLE: + case CHANGE_REPEATABLE: + case CHANGE_COMMIT: + { + MessageNode *newNode = new MessageNode(this->session_data->sequence_number++, lm_connection_get_jid(this->session_data->connection), recipient, msg, type, false, chatroom); + this->session_data->send_queue->insert(newNode); + Inkscape::GC::release(newNode); + break; + } + default: + g_warning("Cannot insert MessageNode with unknown change type into send queue; discarding message. This may lead to desynchronization!"); + break; + } +} + + +// FIXME: +// This method needs a massive, massive, massive overhaul. +int +SessionManager::sendMessage(MessageType msgtype, unsigned int sequence, Glib::ustring const& msg, char const* recipientJID, bool chatroom) +{ + LmMessage* m; + GError* error = NULL; + char* type, * seq; + + if (recipientJID == NULL || recipientJID == "") { + g_warning("Null recipient JID specified; not sending message."); + return NO_RECIPIENT_JID; + } else { + } + + // create message + m = lm_message_new(recipientJID, LM_MESSAGE_TYPE_MESSAGE); + + // add sender + lm_message_node_set_attribute(m->node, "from", lm_connection_get_jid(this->session_data->connection)); + + // set message subtype according to whether or not this is + // destined for a chatroom + if (chatroom) { + lm_message_node_set_attribute(m->node, "type", "groupchat"); + } else { + lm_message_node_set_attribute(m->node, "type", "chat"); + } + + // set protocol version; + // we are currently fixed at version 1 + lm_message_node_add_child(m->node, MESSAGE_PROTOCOL_VER, MESSAGE_PROTOCOL_V1); + + // add message type + type = (char *)calloc(TYPE_FIELD_SIZE, sizeof(char)); + snprintf(type, TYPE_FIELD_SIZE, "%i", msgtype); + lm_message_node_add_child(m->node, MESSAGE_TYPE, type); + free(type); + + // add message body + if (!msg.empty()) { + lm_message_node_add_child(m->node, MESSAGE_BODY, msg.c_str()); + } else { + } + + // add sequence number + switch(msgtype) { + case CHANGE_REPEATABLE: + case CHANGE_NOT_REPEATABLE: + case DUMMY_CHANGE: + case CHANGE_COMMIT: + case DOCUMENT_BEGIN: + case DOCUMENT_END: + case CONNECT_REQUEST_RESPONSE_CHAT: + case CONNECT_REQUEST_RESPONSE_USER: + case CHATROOM_SYNCHRONIZE_RESPONSE: + seq = (char* )calloc(SEQNUM_FIELD_SIZE, sizeof(char)); + sprintf(seq, "%u", sequence); + lm_message_node_add_child(m->node, MESSAGE_SEQNUM, seq); + free(seq); + break; + + case CONNECT_REQUEST_USER: + case CONNECTED_SIGNAL: + case DISCONNECTED_FROM_USER_SIGNAL: + break; + + // Error messages and synchronization requests do not need a sequence number + case CHATROOM_SYNCHRONIZE_REQUEST: + case CONNECT_REQUEST_REFUSED_BY_PEER: + case UNSUPPORTED_PROTOCOL_VERSION: + case ALREADY_IN_SESSION: + break; + + default: + g_warning("Outgoing message type not recognized; not sending."); + lm_message_unref(m); + return UNKNOWN_OUTGOING_TYPE; + } + + // We want to log messages even if they were not successfully sent, + // since the user may opt to re-synchronize a session using the session + // file record. + if (!msg.empty()) { + this->_log(msg); + this->_commitLog(); + } + + // send message + + if (!lm_connection_send(this->session_data->connection, m, &error)) { + g_warning("Send failed: %s", error->message); + lm_message_unref(m); + return CONNECTION_ERROR; + } + + lm_message_unref(m); + return SEND_SUCCESS; +} + +void +SessionManager::connectionError(Glib::ustring const& errmsg) +{ + Gtk::MessageDialog dlg(errmsg, true, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_CLOSE); + dlg.run(); +// sp_whiteboard_connect_dialog(const_cast< gchar* >(errmsg)); +} + +void +SessionManager::resendDocument(char const* recipientJID, KeyToNodeMap& newidsbuf, NodeToKeyMap& newnodesbuf) +{ + Glib::ustring docbegin = MessageUtilities::makeTagWithContent(MESSAGE_DOCBEGIN, ""); + this->sendChange(docbegin, DOCUMENT_BEGIN, recipientJID, false); + + Inkscape::XML::Node* root = sp_document_repr_root(this->_myDoc); + + if(root == NULL) { + return; + } + + NewChildObjectMessageList newchildren; + MessageAggregator& agg = MessageAggregator::instance(); + Glib::ustring buf; + + for ( Inkscape::XML::Node *child = root->firstChild() ; child != NULL ; child = child->next() ) { + // TODO: replace with Serializer methods + MessageUtilities::newObjectMessage(&buf, newidsbuf, newnodesbuf, newchildren, this->_myTracker, child); + + NewChildObjectMessageList::iterator j = newchildren.begin(); + Glib::ustring aggbuf; + + for(; j != newchildren.end(); j++) { + if (!agg.addOne(*j, aggbuf)) { + this->sendChange(aggbuf, CHANGE_REPEATABLE, recipientJID, false); + aggbuf.clear(); + agg.addOne(*j, aggbuf); + } + } + + // send remaining changes + if (!aggbuf.empty()) { + this->sendChange(aggbuf, CHANGE_REPEATABLE, recipientJID, false); + aggbuf.clear(); + } + + newchildren.clear(); + buf.clear(); + } + + Glib::ustring commit = MessageUtilities::makeTagWithContent(MESSAGE_COMMIT, ""); + this->sendChange(commit, CHANGE_COMMIT, recipientJID, false); + Glib::ustring docend = MessageUtilities::makeTagWithContent(MESSAGE_DOCEND, ""); + this->sendChange(docend, DOCUMENT_END, recipientJID, false); +} + +void +SessionManager::receiveChange(Glib::ustring const& changemsg) +{ + + struct Node part; + + Glib::ustring msgcopy = changemsg.c_str(); + + + while(MessageUtilities::getFirstMessageTag(part, msgcopy) != false) { + // TODO: + // Yikes. This is ugly. + if (part.tag == MESSAGE_CHANGE) { + this->_myDeserializer->deserializeEventChgAttr(part.data); + msgcopy.erase(0, part.next_pos); + + } else if (part.tag == MESSAGE_NEWOBJ) { + this->_myDeserializer->deserializeEventAdd(part.data); + msgcopy.erase(0, part.next_pos); + + } else if (part.tag == MESSAGE_DELETE) { + this->_myDeserializer->deserializeEventDel(part.data); + msgcopy.erase(0, part.next_pos); + + } else if (part.tag == MESSAGE_DOCUMENT) { + // no special handler, just keep going with the rest of the message + msgcopy.erase(0, part.next_pos); + + } else if (part.tag == MESSAGE_NODECONTENT) { + this->_myDeserializer->deserializeEventChgContent(part.data); + msgcopy.erase(0, part.next_pos); + + } else if (part.tag == MESSAGE_ORDERCHANGE) { + this->_myDeserializer->deserializeEventChgOrder(part.data); + msgcopy.erase(0, part.next_pos); + + } else if (part.tag == MESSAGE_COMMIT) { + // Retrieve the deserialized event log, node actions, and nodes with updated attributes + XML::Event* log = this->_myDeserializer->getEventLog(); + KeyToNodeActionList& node_changes = this->_myDeserializer->getNodeTrackerActions(); + AttributesUpdatedSet& updated = this->_myDeserializer->getUpdatedAttributeNodeSet(); + + // Make document insensitive to undo + gboolean saved = sp_document_get_undo_sensitive(this->_myDoc); + sp_document_set_undo_sensitive(this->_myDoc, FALSE); + + // Replay the log and push it onto the undo stack + sp_repr_replay_log(log); + + // Call updateRepr on changed nodes + // This is required for some tools to function properly, i.e. text tool + // (TODO: we don't need to update _all_ changed nodes, just their parents) + AttributesUpdatedSet::iterator i = updated.begin(); + for(; i != updated.end(); i++) { + SPObject* updated = this->_myDoc->getObjectByRepr(*i); + if (updated) { + updated->updateRepr(); + } + } + + // merge the events generated by updateRepr + sp_repr_coalesce_log(this->_myDoc->priv->partial, log); + this->_myDoc->priv->partial = NULL; + + this->_myDoc->priv->undo = g_slist_prepend(this->_myDoc->priv->undo, log); + + // Restore undo sensitivity + sp_document_set_undo_sensitive(this->_myDoc, saved); + + // Add or delete nodes to/from the tracker + this->_myTracker->process(node_changes); + + // Reset deserializer state + this->_myDeserializer->reset(); + break; + + } else if (part.tag == MESSAGE_UNDO) { + this->_myUndoObserver->lockObserverFromSending(UndoStackObserver::UNDO_EVENT); + sp_document_undo(this->_myDoc); + this->_myUndoObserver->unlockObserverFromSending(UndoStackObserver::UNDO_EVENT); + msgcopy.erase(0, part.next_pos); + + } else if (part.tag == MESSAGE_REDO) { + this->_myUndoObserver->lockObserverFromSending(UndoStackObserver::REDO_EVENT); + sp_document_redo(this->_myDoc); + this->_myUndoObserver->unlockObserverFromSending(UndoStackObserver::REDO_EVENT); + msgcopy.erase(0, part.next_pos); + + } else if (part.tag == MESSAGE_DOCBEGIN) { + msgcopy.erase(0, part.next_pos); + + } else if (part.tag == MESSAGE_DOCEND) { + // Set this to be the new original state of the document + sp_document_done(this->document()); + sp_document_clear_redo(this->document()); + sp_document_clear_undo(this->document()); + this->setupCommitListener(); + msgcopy.erase(0, part.next_pos); + + } else { + msgcopy.erase(0, part.next_pos); + + } + } + + this->_log(changemsg); + + this->_commitLog(); +} + +bool +SessionManager::isPlayingSessionFile() +{ + return this->session_data->status[PLAYING_SESSION_FILE]; +} + +void +SessionManager::loadSessionFile(Glib::ustring filename) +{ + if (!this->session_data || !this->session_data->status[IN_WHITEBOARD]) { + try { + if (this->_mySessionFile) { + delete this->_mySessionFile; + } + this->_mySessionFile = new SessionFile(filename, true, false); + + // Initialize objects needed for session playback + if (this->_mySessionPlayer == NULL) { + this->_mySessionPlayer = new SessionFilePlayer(16, this); + } else { + this->_mySessionPlayer->load(this->_mySessionFile); + } + + if (this->_myTracker == NULL) { + this->_myTracker = new XMLNodeTracker(this); + } else { + this->_myTracker->reset(); + } + + if (!this->session_data) { + this->session_data = new SessionData(this); + } + + if (!this->_myDeserializer) { + this->_myDeserializer = new Deserializer(this->node_tracker()); + } + + if (!this->_myUndoObserver) { + this->setupCommitListener(); + } + + this->session_data->status.set(PLAYING_SESSION_FILE, 1); + + + } catch (Glib::FileError e) { + g_warning("Could not load session file: %s", e.what().data()); + } + } +} + +void +SessionManager::userConnectedToWhiteboard(gchar const* JID) +{ + SP_DT_MSGSTACK(this->_myDesktop)->flashF(Inkscape::INFORMATION_MESSAGE, _("Established whiteboard session with %s."), JID); +} + + +void +SessionManager::userDisconnectedFromWhiteboard(std::string const& JID) +{ + + SP_DT_MSGSTACK(this->_myDesktop)->flashF(Inkscape::INFORMATION_MESSAGE, _("%s has left the whiteboard session."), JID.c_str()); + + // Inform the user + // TRANSLATORS: %1 is the name of the user that disconnected, %2 is the name of the user whom the disconnected user disconnected from. + // This message is not used in a chatroom context. + Glib::ustring primary = String::ucompose(_("The user %1 has left the whiteboard session.\n\n"), JID); + // TRANSLATORS: %1 and %2 are userids + Glib::ustring secondary = String::ucompose(_("You are still connected to a Jabber server as %2, and may establish a new session to %1 or a different user."), JID, lm_connection_get_jid(this->session_data->connection)); + + // TODO: parent this dialog to the active desktop + Gtk::MessageDialog dialog(primary + secondary, true, Gtk::MESSAGE_INFO, Gtk::BUTTONS_CLOSE, false); + /* + dialog.set_message(primary, true); + dialog.set_secondary_text(secondary, true); + */ + dialog.run(); +} + +void +SessionManager::startSendQueueDispatch() +{ + this->_send_queue_dispatcher = Glib::signal_timeout().connect(sigc::mem_fun(*(this->_myCallbacks), &Callbacks::dispatchSendQueue), SEND_TIMEOUT); +} + +void +SessionManager::stopSendQueueDispatch() +{ + if (this->_send_queue_dispatcher) { + this->_send_queue_dispatcher.disconnect(); + } +} + +void +SessionManager::startReceiveQueueDispatch() +{ + this->_receive_queue_dispatcher = Glib::signal_timeout().connect(sigc::mem_fun(*(this->_myCallbacks), &Callbacks::dispatchReceiveQueue), SEND_TIMEOUT); +} + +void +SessionManager::stopReceiveQueueDispatch() +{ + if (this->_receive_queue_dispatcher) { + this->_receive_queue_dispatcher.disconnect(); + } +} + +void +SessionManager::clearDocument() +{ + // clear all layers, definitions, and metadata + XML::Node* rroot = this->_myDoc->rroot; + + // clear definitions + XML::Node* defs = SP_OBJECT_REPR((SPDefs*)SP_DOCUMENT_DEFS(this->_myDoc)); + g_assert(SP_ROOT(this->_myDoc->root)->defs); + + for(XML::Node* child = defs->firstChild(); child; child = child->next()) { + defs->removeChild(child); + } + + // clear layers + for(XML::Node* child = rroot->firstChild(); child; child = child->next()) { + if (strcmp(child->name(), "svg:g") == 0) { + rroot->removeChild(child); + } + } + + // clear metadata + for(XML::Node* child = rroot->firstChild(); child; child = child->next()) { + if (strcmp(child->name(), "svg:metadata") == 0) { + rroot->removeChild(child); + } + } + +// sp_document_done(this->_myDoc); +} + +void +SessionManager::setupInkscapeInterface() +{ + this->session_data->status.set(IN_WHITEBOARD, 1); + this->startSendQueueDispatch(); + this->startReceiveQueueDispatch(); + if (!this->_myTracker) { + this->_myTracker = new XMLNodeTracker(this); + } + + this->_mySerializer = new Serializer(this->node_tracker()); + this->_myDeserializer = new Deserializer(this->node_tracker()); + + // We're in a whiteboard session now, so set verb sensitivity accordingly + this->_setVerbSensitivity(ESTABLISHED_SESSION); +} + +void +SessionManager::setupCommitListener() +{ + this->_myUndoObserver = new Whiteboard::UndoStackObserver(this); + this->_myDoc->addUndoObserver(*this->_myUndoObserver); +} + +::SPDesktop* +SessionManager::desktop() +{ + return this->_myDesktop; +} + +::SPDocument* +SessionManager::document() +{ + return this->_myDoc; +} + +Callbacks* +SessionManager::callbacks() +{ + return this->_myCallbacks; +} + +Whiteboard::UndoStackObserver* +SessionManager::undo_stack_observer() +{ + return this->_myUndoObserver; +} + +Serializer* +SessionManager::serializer() +{ + return this->_mySerializer; +} + +XMLNodeTracker* +SessionManager::node_tracker() +{ + return this->_myTracker; +} + + +ChatMessageHandler* +SessionManager::chat_handler() +{ + return this->_myChatHandler; +} + +SessionFilePlayer* +SessionManager::session_player() +{ + return this->_mySessionPlayer; +} + +SessionFile* +SessionManager::session_file() +{ + return this->_mySessionFile; +} + +void +SessionManager::_log(Glib::ustring const& message) +{ + if (this->_mySessionFile && !this->_mySessionFile->isReadOnly()) { + this->_mySessionFile->addMessage(message); + } +} + +void +SessionManager::_commitLog() +{ + if (this->_mySessionFile && !this->_mySessionFile->isReadOnly()) { + this->_mySessionFile->commit(); + } +} + +void +SessionManager::_closeLog() +{ + if (this->_mySessionFile) { + this->_mySessionFile->close(); + } +} + +void +SessionManager::startLog(Glib::ustring filename) +{ + try { + this->_mySessionFile = new SessionFile(filename, false, false); + } catch (Glib::FileError e) { + g_warning("Caught I/O error %s while attemping to open file %s for session recording.", e.what().c_str(), filename.c_str()); + throw; + } +} + +void +SessionManager::_tryToStartLog() +{ + if (this->session_data) { + if (!this->session_data->sessionFile.empty()) { + bool undecided = true; + while(undecided) { + try { + this->startLog(this->session_data->sessionFile); + undecided = false; + } catch (Glib::FileError e) { + undecided = true; + Glib::ustring msg = String::ucompose(_("Could not open file %1 for session recording.\nThe error encountered was: %2.\n\nYou may select a different location to record the session, or you may opt to not record this session."), this->session_data->sessionFile, e.what()); + Gtk::MessageDialog dlg(msg, true, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_NONE, false); + dlg.add_button(_("Choose a different location"), 0); + dlg.add_button(_("Skip session recording"), 1); + switch (dlg.run()) { + case 0: + { + Gtk::FileChooserDialog sessionfiledlg(_("Select a location and filename"), Gtk::FILE_CHOOSER_ACTION_SAVE); + sessionfiledlg.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); + sessionfiledlg.add_button(_("Set filename"), Gtk::RESPONSE_OK); + int result = sessionfiledlg.run(); + switch (result) { + case Gtk::RESPONSE_OK: + { + this->session_data->sessionFile = sessionfiledlg.get_filename(); + break; + } + case Gtk::RESPONSE_CANCEL: + default: + undecided = false; + break; + } + break; + } + case 1: + default: + undecided = false; + break; + } + } + } + } + } +} + +void +SessionManager::_setVerbSensitivity(SensitivityMode mode) +{ + return; + + switch (mode) { + case ESTABLISHED_CONNECTION: + // Upon successful connection, we can disconnect from the server. + // We can also start sharing a document with a user or chatroom. + // We cannot, however, connect to a new server without first disconnecting. + Inkscape::Verb::get(SP_VERB_DIALOG_WHITEBOARD_CONNECT)->sensitive(this->_myDoc, false); + Inkscape::Verb::get(SP_VERB_DIALOG_WHITEBOARD_DISCONNECT_FROM_SERVER)->sensitive(this->_myDoc, true); + Inkscape::Verb::get(SP_VERB_DIALOG_WHITEBOARD_SHAREWITHUSER)->sensitive(this->_myDoc, true); + Inkscape::Verb::get(SP_VERB_DIALOG_WHITEBOARD_SHAREWITHCHAT)->sensitive(this->_myDoc, true); + break; + + case ESTABLISHED_SESSION: + // When we have established a session, we should not permit the user to go and + // establish another session from the same document without first disconnecting. + // + // TODO: Well, actually, we probably _should_, but there's no real reconnection logic just yet. + Inkscape::Verb::get(SP_VERB_DIALOG_WHITEBOARD_SHAREWITHUSER)->sensitive(this->_myDoc, false); + Inkscape::Verb::get(SP_VERB_DIALOG_WHITEBOARD_SHAREWITHCHAT)->sensitive(this->_myDoc, false); + Inkscape::Verb::get(SP_VERB_DIALOG_WHITEBOARD_DISCONNECT_FROM_SESSION)->sensitive(this->_myDoc, true); + break; + case DISCONNECTED_FROM_SESSION: + // Upon disconnecting from a session, we can establish a new session and disconnect + // from the server, but we cannot disconnect from a session (since we just left it.) + Inkscape::Verb::get(SP_VERB_DIALOG_WHITEBOARD_DISCONNECT_FROM_SESSION)->sensitive(this->_myDoc, false); + Inkscape::Verb::get(SP_VERB_DIALOG_WHITEBOARD_SHAREWITHUSER)->sensitive(this->_myDoc, true); + Inkscape::Verb::get(SP_VERB_DIALOG_WHITEBOARD_SHAREWITHCHAT)->sensitive(this->_myDoc, true); + + case INITIAL: + default: + // Upon construction, there is no active connection, so we cannot do the following: + // (1) disconnect from a session + // (2) disconnect from a server + // (3) share with a user + // (4) share with a chatroom + Inkscape::Verb::get(SP_VERB_DIALOG_WHITEBOARD_CONNECT)->sensitive(this->_myDoc, true); + Inkscape::Verb::get(SP_VERB_DIALOG_WHITEBOARD_SHAREWITHUSER)->sensitive(this->_myDoc, false); + Inkscape::Verb::get(SP_VERB_DIALOG_WHITEBOARD_SHAREWITHCHAT)->sensitive(this->_myDoc, false); + Inkscape::Verb::get(SP_VERB_DIALOG_WHITEBOARD_DISCONNECT_FROM_SESSION)->sensitive(this->_myDoc, false); + Inkscape::Verb::get(SP_VERB_DIALOG_WHITEBOARD_DISCONNECT_FROM_SERVER)->sensitive(this->_myDoc, false); + break; + }; +} + +/* +void +SessionManager::Listener::processXmppEvent(Pedro::XmppEvent const& event) +{ + int type = event.getType(); + + switch (type) { + case Pedro::XmppEvent::EVENT_STATUS: + break; + case Pedro::XmppEvent::EVENT_ERROR: + break; + case Pedro::XmppEvent::EVENT_CONNECTED: + break; + case Pedro::XmppEvent::EVENT_DISCONNECTED: + break; + case Pedro::XmppEvent::EVENT_MESSAGE: + break; + case Pedro::XmppEvent::EVENT_PRESENCE: + break; + case Pedro::XmppEvent::EVENT_MUC_MESSAGE: + break; + case Pedro::XmppEvent::EVENT_MUC_JOIN: + break; + case Pedro::XmppEvent::EVENT_MUC_LEAVE: + break; + case Pedro::XmppEvent::EVENT_MUC_PRESENCE: + break; + } +} +*/ + +} + +} + + +/* + 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:textwidth=99 : diff --git a/src/jabber_whiteboard/session-manager.h b/src/jabber_whiteboard/session-manager.h new file mode 100644 index 000000000..d52cca3de --- /dev/null +++ b/src/jabber_whiteboard/session-manager.h @@ -0,0 +1,568 @@ +/** + * Whiteboard session manager + * + * Authors: + * David Yip + * + * Copyright (c) 2005 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifndef __SESSION_MANAGER_H__ +#define __SESSION_MANAGER_H__ + +#include +#include +#include + +extern "C" { +#include +} + +#include "jabber_whiteboard/typedefs.h" +#include "jabber_whiteboard/defines.h" +#include "jabber_whiteboard/buddy-list-manager.h" + +#include "gc-alloc.h" + +struct SPDesktop; +struct SPDocument; + +namespace Inkscape { +namespace XML { +class Node; +} +} + +namespace Inkscape { + +namespace Whiteboard { + +class ReceiveMessageQueue; +class SendMessageQueue; +class XMLNodeTracker; +class SessionManager; +class MessageHandler; +class ChatMessageHandler; +class Callbacks; +class SessionFile; +class SessionFilePlayer; +class UndoStackObserver; +class Serializer; +class Deserializer; + +/// Jabber resource name +#define RESOURCE_NAME "Inkboard" + +/// connectToServer return values +#define CONNECT_SUCCESS 0 +#define FAILED_TO_CONNECT 1 +#define INVALID_AUTH 2 +#define SSL_INITIALIZATION_ERROR 3 + +/// sendMessage return values +#define SEND_SUCCESS 0 +#define CONNECTION_ERROR 1 +#define UNKNOWN_OUTGOING_TYPE 2 +#define NO_RECIPIENT_JID 3 + +/** + * Structure grouping data items pertinent to a whiteboard session. + * + * SessionData holds all session data for both 1:1 and chatroom conferences. + * Access to members should be controlled by first querying the status bitset + * to see if useful data will actually exist in that member -- i.e. checking + * status[IN_CHATROOM] to see if the chatters set will contain anything. + * It usually won't hurt to do a straight query -- there are very few members + * that remain uninitialized for very long -- but it's a good idea to check. + */ +struct SessionData { +public: + /** + * Constructor. + * + * \param sm The SessionManager with which a SessionData instance should be + * associated with. + */ + SessionData(SessionManager *sm); + + ~SessionData(); + + /** + * The JID of the recipient: either another user JID or the JID of a chatroom. + */ + gchar const* recipient; + + /** + * Pointer to Loudmouth connection structure. + * Used for Loudmouth calls that require it. + */ + LmConnection* connection; + + /** + * SSL information structure for SSL connections. + */ + LmSSL* ssl; + + /** + * Flag indicating whether or not we should ignore further SSL errors for a given session. + */ + bool ignoreFurtherSSLErrors; + + + /** + * A user's handle in a Jabber chatroom. + */ + Glib::ustring chat_handle; + + /** + * Name of the chatroom that a user in a chatroom is connected to. + */ + Glib::ustring chat_name; + + /** + * Name of the conference server. + */ + Glib::ustring chat_server; + + // Message queues + + /** + * Map associating senders to receive queues. + */ + RecipientToReceiveQueueMap receive_queues; + + /** + * Map associating senders to commit events sent by those committers. + */ + CommitsQueue recipients_committed_queue; + + /** + * Pointer to queue for messages to be sent. + */ + SendMessageQueue* send_queue; + + // Message sequence numbers + + /** + * The sequence number of the latest message sent by this client in a given session. + * Used for determining the sequence number of the next message. + */ + unsigned int sequence_number; + + //unsigned int latest_sent_transaction; + //RecipientToLatestTransactionMap latest_processed_transactions; + + + // Status tracking + /** + * Session state and status flags. + */ + std::bitset< NUM_FLAGS > status; + + /** + * Jabber buddy list data. + */ + BuddyListManager buddyList; + + /** + * List of participants in a Jabber chatroom. + */ + ChatterList chatters; + + /** + * Session file filename; blank if no session file is to be + * recorded. + */ + Glib::ustring sessionFile; + +private: + // access to containing class + SessionManager *_sm; + + // noncopyable, nonassignable + SessionData(SessionData const&); + SessionData& operator=(SessionData const&); +}; + + +// TODO: This class is huge. It might be best to refactor it into smaller, +// more coherent chunks. +// +// TODO: convert to pass-by-reference where appropriate. In particular, a lot of the +// string buffers passed to methods in the argument list can be made into references +// appropriately and easily. + +/** + * Session management class for Inkboard. + * + * By "session management", we refer to the management of all events that an Inkboard + * session may need to handle: negotiating a connection to a Jabber server, negotiating + * sessions with users and chatrooms, sending, receiving, and parsing messages, and so + * forth. + * + * SessionManager instances are associated with Inkscape desktop objects on a 1:1 basis. + */ +class SessionManager { +public: + /** + * Constructor. + * + * \param desktop The desktop with which this SessionManager is associated. */ + SessionManager(::SPDesktop *desktop); + ~SessionManager(); + + // Session tracking data + + /** + * Pointer to SessionData structure. + */ + struct SessionData *session_data; + + // Inkscape interface + + /** + * Set the desktop with which this SessionManager is associated. + * + * @param desktop the desktop with which this SessionManager should be associated + */ + void setDesktop(::SPDesktop* desktop); + + // Session management + + /** + * Connect to a Jabber server. + * + * @param server Jabber server URL + * @param username Jabber username + * @param pw password for Jabber account + * @param usessl use SSL for connection + * + * @return CONNECT_SUCCESS if connection successful; FAILED_TO_CONNECT if connection failed or INVALID_AUTH + * if authentication invalid + */ + int connectToServer(Glib::ustring const& server, Glib::ustring const& port, Glib::ustring const& username, Glib::ustring const& pw, bool usessl); + + /** + * Handle an SSL error by prompting the user for feedback, and continuing or aborting the connection + * process based on that feedback. + * + * @param ssl pointer to LmSSL structure + * @param status The error message + * + * @return LM_SSL_RESPONSE_CONTINUE if user wishes to continue establishing the connection or LM_SSL_RESPONSE_STOP if user wishes to abort connection + */ + LmSSLResponse handleSSLError(LmSSL* ssl, LmSSLStatus status); + + /** + * Disconnect from a Jabber server. + * + * This invokes disconnectFromDocument(). + * + * \see Inkscape::Whiteboard::SessionManager::disconnectFromDocument + */ + void disconnectFromServer(); + + /** + * Disconnect from a document session. The connection to the Jabber server is not + * broken, and may be reused to connect to a new document session. + * + */ + void disconnectFromDocument(); + + /** + * Perform session teardown. This method by itself does not disconnect from a document or + * a Jabber server. + * + */ + void closeSession(); + + /** + * Set the recipient for Inkboard messages. + * + * @param recipientJID the recipient's JID + */ + void setRecipient(char const* recipientJID); + + // Message sending utilities + + /** + * Put an Inkboard message into the send queue. + * This method does not actually send anything to an Inkboard client. + * + * \see Inkscape::Whiteboard::SessionManager::sendMessage + * + * + * @param msg the message to send + * @param type the type of message (only CHANGE_* types permitted) + * @param chatroom whether or not this message is destined for a chatroom + */ + void sendChange(Glib::ustring const& msg, MessageType type, std::string const& recipientJID, bool chatroom); + + /** + * Send a message to an Inkboard client. + * + * + * @param msgtype the type of message to send + * @param sequence message sequence number + * @param msg the message to send + * @param recipientJID the JID of the recipient + * @param chatroom whether or not this message is destined for a chatroom + * + * @return SEND_SUCCESS if successful; otherwise: UNKNOWN_OUTGOING_TYPE if msgtype is not recognized, NO_RECIPIENT_JID if recipientJID is NULL or blank, CONNECTION_ERROR if Jabber connection error occurred + */ + int sendMessage(MessageType msgtype, unsigned int sequence, Glib::ustring const& msg, char const* recipientJID, bool chatroom); + + /** + * Inform the user of a connection error via a Gtk::MessageDialog. + * + * @param errmsg message to display + */ + void connectionError(Glib::ustring const& errmsg); + + /** + * Stream the contents of the document with which this SessionManager is associated with to the given recipient. + * + * @param recipientJID the JID of the recipient + * @param newidsbuf buffer to store IDs of new nodes + * @param newnodesbuf buffer to store address of new nodes + */ + void resendDocument(char const* recipientJID, KeyToNodeMap& newidsbuf, NodeToKeyMap& newnodesbuf); + + + /** + * Send a connection request to another Inkboard client. + * + * + * @param recipientJID the JID to connect to + * @param document document message to send + */ + void sendRequestToUser(std::string const& recipientJID); + + /** + * Send a connection request to chatroom. + * + * @param server server to connect to + * @param chatroom name of chatroom + * @param handle chatroom handle to use + * @param password chatroom password; leave NULL if no password + */ + void sendRequestToChatroom(Glib::ustring const& server, Glib::ustring const& chatroom, Glib::ustring const& handle, Glib::ustring const& password); + + /** + * Send a connection request response to a user who requested to connect to us. + * + * @param requesterJID the JID of the user whom sent us the request + * @param accepted_request whether or not we accepted the request + */ + void sendConnectRequestResponse(char const* requesterJID, gboolean accepted_request); + + /** + * Method called when a connection request is received. This method produces a dialog + * that asks the user whether or not s/he would like to accept the request. + * + * + * @param requesterJID the JID of the user whom sent us the request + * @param msg the message associated with this request + */ + void receiveConnectRequest(gchar const* requesterJID); + + /** + * Method called when a response to a connection request is received. + * This method performs any necessary session setup/teardown and user notification + * depending on the response received. + * + * + * @param msg the message associated with this request + * @param response the response code + * @param sender the JID of the user whom responded to our request + */ + void receiveConnectRequestResponse(InvitationResponses response, std::string& sender); + + /** + * Method called when a document synchronization request is received from a new conference + * member in a chatroom. + * + * \param recipient the recipient JID + */ + void receiveConnectRequestResponseChat(gchar const* recipient); + + // Message parsing and passing + + /** + * Processes a group of document change messages. + * + * \param changemsg The change message group to process. + */ + void receiveChange(Glib::ustring const& changemsg); + + // Logging and session file handling + /** + * Start a session log with the given filename. + * + * \param filename Full path to the file that the session log should be written to. + * \throw Glib::FileError Thrown if an exception is thrown during session file creation. + */ + void startLog(Glib::ustring filename); + + /** + * Load a session file for playback. + * + * \param filename Full path to the session file that is to be loaded. + */ + void loadSessionFile(Glib::ustring filename); + + /** + * Returns whether or not the session is in session file playback mode. + * + * \return Whether or not the session is in session file playback mode. + */ + bool isPlayingSessionFile(); + + // User event notification + + /** + * Method to notify the user that a whiteboard session to another user has been successfully + * established. + * + * \param JID The JID with whom the user established a session. + */ + void userConnectedToWhiteboard(gchar const* JID); + + /** + * Method to notify the user that the other user in a user-to-user whiteboard session + * has disconnected. + * + * \param JID The JID of the user who left the whiteboard session. + */ + void userDisconnectedFromWhiteboard(std::string const& JID); + + // Queue dispatching and UI setup + + /** + * Start the send queue for this session. + */ + void startSendQueueDispatch(); + + /** + * Stop the send queue for this session. + */ + void stopSendQueueDispatch(); + + /** + * Start the receive queue for this session. + */ + void startReceiveQueueDispatch(); + + /** + * Stop the receive queue for this session. + */ + void stopReceiveQueueDispatch(); + + /** + * Clear all layers, definitions, and metadata from the document with which a + * SessionManager instance is associated. + * + * Documents are cleared to assist synchronization between two clients + * or a client and a chatroom. + */ + void clearDocument(); + + /** + * Set up objects for handling actions generated by the user interacting with + * Inkscape. This includes marking the active session as being in a whiteboard session, + * starting send and receive queues, and creating an event serializer and deserializer. + * + * \see Inkscape::Whiteboard::SendMessageQueue + * \see Inkscape::Whiteboard::ReceiveMessageQueue + * \see Inkscape::Whiteboard::Serializer + * \see Inkscape::Whiteboard::Deserializer + */ + void setupInkscapeInterface(); + + /** + * Reset whiteboard verbs to INITIAL state. + */ + void setInitialVerbSensitivity() { + this->_setVerbSensitivity(INITIAL); + } + + /** + * Set up the event commit listener. + * + * The event commit listener watches for events that are committed to the document's undo log, + * serializes those events, and then adds them to the message send queue. + * + * \see Inkscape::Whiteboard::SendMessageQueue + * \see Inkscape::Whiteboard::UndoStackObserver + */ + void setupCommitListener(); + + // Private object retrieval + ::SPDesktop* desktop(); + ::SPDocument* document(); + Callbacks* callbacks(); + Whiteboard::UndoStackObserver* undo_stack_observer(); + Serializer* serializer(); + XMLNodeTracker* node_tracker(); + Deserializer* deserializer(); + ChatMessageHandler* chat_handler(); + SessionFilePlayer* session_player(); + SessionFile* session_file(); + +private: + // Internal logging methods + void _log(Glib::ustring const& message); + void _commitLog(); + void _closeLog(); + void _tryToStartLog(); + + enum SensitivityMode { + INITIAL, + ESTABLISHED_CONNECTION, + ESTABLISHED_SESSION, + DISCONNECTED_FROM_SESSION + }; + + void _setVerbSensitivity(SensitivityMode mode); + + bool _pollReceiveConnectRequest(Glib::ustring const recipient); + + ::SPDesktop* _myDesktop; + ::SPDocument* _myDoc; + Whiteboard::UndoStackObserver* _myUndoObserver; + XMLNodeTracker* _myTracker; + ChatMessageHandler* _myChatHandler; + Callbacks* _myCallbacks; + SessionFile* _mySessionFile; + SessionFilePlayer* _mySessionPlayer; + MessageHandler* _myMessageHandler; + Serializer* _mySerializer; + Deserializer* _myDeserializer; + + sigc::connection _send_queue_dispatcher; + sigc::connection _receive_queue_dispatcher; + sigc::connection _notify_incoming_request; + + // noncopyable, nonassignable + SessionManager(SessionManager const&); + SessionManager& operator=(SessionManager const&); +}; + +} + +} + +#endif + +/* + 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:textwidth=99 : diff --git a/src/jabber_whiteboard/tracker-node.h b/src/jabber_whiteboard/tracker-node.h new file mode 100644 index 000000000..bbaf527ce --- /dev/null +++ b/src/jabber_whiteboard/tracker-node.h @@ -0,0 +1,94 @@ +/** + * Whiteboard session manager + * XML node tracking facility + * + * Authors: + * David Yip + * + * Copyright (c) 2005 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifndef __WHITEBOARD_TRACKER_NODE_H__ +#define __WHITEBOARD_TRACKER_NODE_H__ + +#include "xml/node.h" + +#include "gc-managed.h" +#include "gc-finalized.h" + +#include +#include + +namespace Inkscape { + +namespace Whiteboard { + +// set _size in TrackerNode private members if you add or delete +// any more listeners +enum ListenerType { + ATTR_CHANGED, + CHILD_ADDED, + CHILD_REMOVED, + CHILD_ORDER_CHANGED, + CONTENT_CHANGED +}; + +struct TrackerNode : public GC::Managed<> { +public: + TrackerNode(XML::Node const* n) : _node(n) + { + } + + ~TrackerNode() + { + } + + void lock(ListenerType listener) + { + if (listener < _size) { + this->_listener_locks.set(listener, true); + } + } + + void unlock(ListenerType listener) + { + if (listener < _size) { + this->_listener_locks.set(listener, false); + } + } + + bool isLocked(ListenerType listener) + { + return (this->_listener_locks[listener]); + } + + XML::Node const* _node; + +private: + // change this if any other flags are added + static unsigned short const _size = 5; + std::bitset< _size > _listener_locks; + + // noncopyable, nonassignable + TrackerNode(TrackerNode const&); + TrackerNode& operator=(TrackerNode const&); +}; + +} + +} + +#endif + +/* + 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:textwidth=99 : diff --git a/src/jabber_whiteboard/typedefs.h b/src/jabber_whiteboard/typedefs.h new file mode 100644 index 000000000..10adbdaf8 --- /dev/null +++ b/src/jabber_whiteboard/typedefs.h @@ -0,0 +1,159 @@ +/** + * Whiteboard session manager + * Typedef declarations and template specializations + * + * Authors: + * David Yip + * + * Copyright (c) 2005 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifndef __WHITEBOARD_TYPEDEFS_H__ +#define __WHITEBOARD_TYPEDEFS_H__ + +extern "C" { +#include +} + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "jabber_whiteboard/defines.h" + +#include "gc-alloc.h" + +namespace Inkscape { + +namespace XML { + +class Node; + +} + +namespace Util { + +template< typename T > +class ListContainer; + +} + +} + +// Various specializations of std::less for XMLNodeTracker maps. +namespace std { +using Inkscape::XML::Node; + +/** + * Specialization of std::less<> for pointers to XML::Nodes.a + * + * \see Inkscape::XML::Node + */ +template<> +struct less< Node* > : public binary_function < Node*, Node*, bool > +{ + bool operator()(Node* _x, Node* _y) const + { + return _x < _y; + } + +}; + +} + +namespace Inkscape { + +namespace Whiteboard { +// I am assuming that std::string (which will not properly represent Unicode data) will +// suffice for associating (integer, Jabber ID) identifiers with nodes. +// We do not need to preserve all semantics handled by Unicode; we just need to have +// the byte representation. std::string is good enough for that. +// +// The reason for this is that comparisons with std::string are much faster than +// comparisons with Glib::ustring (simply because the latter is using significantly +// more complex text-handling algorithms), and we need speed here. We _could_ use +// Glib::ustring::collate_key() here and therefore get the best of both worlds, +// but collation keys are rather big. +// +// XML node tracker maps + +/// Associates node keys to pointers to XML::Nodes. +/// \see Inkscape::Whiteboard::XMLNodeTracker +typedef std::map< std::string, XML::Node*, std::less< std::string >, GC::Alloc< std::pair< const std::string, XML::Node* >, GC::MANUAL > > KeyToTrackerNodeMap; + +/// Associates pointers to XML::Nodes with node keys. +/// \see Inkscape::Whiteboard::XMLNodeTracker +typedef std::map< XML::Node*, std::string, std::less< XML::Node* >, GC::Alloc< std::pair< XML::Node* const, std::string >, GC::MANUAL > > TrackerNodeToKeyMap; + + +// TODO: Clean up these typedefs. I'm sure quite a few of these aren't used anymore; additionally, +// it's probably possible to consolidate a few of these types into one. + +// Temporary storage of new object messages and new nodes in said messages +typedef std::list< Glib::ustring > NewChildObjectMessageList; + +typedef std::pair< std::string, XML::Node* > KeyNodePair; +typedef std::pair< KeyNodePair, NodeTrackerAction > SerializedEventNodeAction; + +typedef std::list< SerializedEventNodeAction > KeyToNodeActionList; + +//typedef std::map< std::string, SerializedEventNodeAction > KeyToNodeActionMap; + +typedef std::set< std::string > AttributesScannedSet; +typedef std::set< XML::Node* > AttributesUpdatedSet; + +typedef std::map< std::string, XML::Node const* > KeyToNodeMap; +typedef std::map< XML::Node const*, std::string > NodeToKeyMap; + +// Buddy list management +typedef std::set< std::string > BuddyList; +typedef sigc::signal< void, std::string const& > BuddyListSignal; +typedef sigc::slot< void, std::string const& > BuddyListListener; + +// Chatroom list participants +typedef std::set< char const* > ChatterList; + +// Message context verification and processing +struct MessageProcessor; +class ReceiveMessageQueue; + +typedef std::map< MessageType, std::bitset< NUM_FLAGS > > MessageContextMap; +typedef std::map< MessageType, MessageProcessor*, std::less< MessageType >, GC::Alloc< std::pair< const MessageType, MessageProcessor* >, GC::MANUAL > > MessageProcessorMap; + +typedef std::map< std::string, ReceiveMessageQueue*, std::less< std::string >, GC::Alloc< std::pair< const std::string, ReceiveMessageQueue* >, GC::MANUAL > > RecipientToReceiveQueueMap; +typedef std::map< std::string, unsigned int > ReceipientToLatestTransactionMap; + +typedef std::string ReceivedCommitEvent; +typedef std::list< ReceivedCommitEvent > CommitsQueue; + +// Message serialization +typedef std::list< Glib::ustring > SerializedEventList; + +// Error handling -- someday +// TODO: finish and integrate this +//typedef boost::function< LmHandlerResult (unsigned int code) > ErrorHandlerFunctor; +//typedef std::map< unsigned int, ErrorHandlerFunctor > ErrorHandlerFunctorMap; +} + +} + + +#endif +/* + 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:textwidth=99 : diff --git a/src/jabber_whiteboard/undo-stack-observer.cpp b/src/jabber_whiteboard/undo-stack-observer.cpp new file mode 100644 index 000000000..7750dc73c --- /dev/null +++ b/src/jabber_whiteboard/undo-stack-observer.cpp @@ -0,0 +1,181 @@ +/** + * Undo / redo / undo log commit listener + * + * Authors: + * David Yip + * + * Copyright (c) 2005 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "document.h" +#include "document-private.h" + +#include "xml/event.h" +#include "xml/event-fns.h" +#include "undo-stack-observer.h" + +#include "util/list.h" +#include "util/reverse-list.h" + +#include "jabber_whiteboard/defines.h" +#include "jabber_whiteboard/session-manager.h" +#include "jabber_whiteboard/node-tracker.h" +#include "jabber_whiteboard/serializer.h" +#include "jabber_whiteboard/message-utilities.h" +#include "jabber_whiteboard/message-aggregator.h" +#include "jabber_whiteboard/message-tags.h" + + +#include + +namespace Inkscape { + +namespace Whiteboard { + +UndoStackObserver::UndoStackObserver(SessionManager* sm) : _sm(sm), _undoSendEventLocks(0), _redoSendEventLocks(0), _undoCommitSendEventLocks(0) { +} + +UndoStackObserver::~UndoStackObserver() { } + +void +UndoStackObserver::notifyUndoEvent(XML::Event* log) +{ + if (this->_undoSendEventLocks == 0) { + bool chatroom = this->_sm->session_data->status.test(IN_CHATROOM); + Glib::ustring commit = MessageUtilities::makeTagWithContent(MESSAGE_UNDO, ""); + this->_sm->sendChange(commit, CHANGE_COMMIT, "", chatroom); + } + + // Retrieve and process added/deleted nodes in the undo log + // TODO: re-enable; right now it doesn't work because we can't recover the names + // of deleted nodes (although perhaps creating a subclass of XML::Event that stored + // names of serialized nodes along with all other Event information would fix this) + /* + KeyToNodeActionMap node_actions = this->_action_observer.getNodeActionMap(); + this->_sm->node_tracker()->process(node_actions); + this->_action_observer.clearNodeBuffers(); + */ + +} + +void +UndoStackObserver::notifyRedoEvent(XML::Event* log) +{ + if (this->_redoSendEventLocks == 0) { + bool chatroom = this->_sm->session_data->status.test(IN_CHATROOM); + Glib::ustring commit = MessageUtilities::makeTagWithContent(MESSAGE_REDO, ""); + this->_sm->sendChange(commit, CHANGE_COMMIT, "", chatroom); + } + + // Retrieve and process added/deleted nodes in the redo log + /* + KeyToNodeActionMap node_actions = this->_action_observer.getNodeActionMap(); + this->_sm->node_tracker()->process(node_actions); + this->_action_observer.clearNodeBuffers(); + */ +} + +void +UndoStackObserver::notifyUndoCommitEvent(XML::Event* log) +{ + if (this->_undoCommitSendEventLocks == 0) { + this->_doAction(log); + } +} + +void +UndoStackObserver::lockObserverFromSending(ObserverType type) +{ + switch (type) { + case UNDO_EVENT: + ++this->_undoSendEventLocks; + break; + case REDO_EVENT: + ++this->_redoSendEventLocks; + break; + case UNDO_COMMIT_EVENT: + ++this->_undoCommitSendEventLocks; + break; + default: + break; + } +} + +void +UndoStackObserver::unlockObserverFromSending(ObserverType type) +{ + switch(type) { + case UNDO_EVENT: + if (this->_undoSendEventLocks) { + --this->_undoSendEventLocks; + } + break; + case REDO_EVENT: + if (this->_redoSendEventLocks) { + --this->_redoSendEventLocks; + } + break; + case UNDO_COMMIT_EVENT: + if (this->_undoCommitSendEventLocks) { + --this->_undoCommitSendEventLocks; + } + break; + default: + break; + } +} + +void +UndoStackObserver::_doAction(XML::Event* log) +{ + if (this->_sm->serializer()) { + bool chatroom = this->_sm->session_data->status.test(IN_CHATROOM); + XML::replay_log_to_observer(log, *this->_sm->serializer()); + + this->_sm->serializer()->synthesizeChildNodeAddEvents(); + + SerializedEventList& events = this->_sm->serializer()->getEventList(); + + SerializedEventList::iterator i = events.begin(); + MessageAggregator& agg = MessageAggregator::instance(); + Glib::ustring msgbuf; + + while(i != events.end()) { + while(agg.addOne(*i++, msgbuf)) { + if (i == events.end()) { + break; + } + } + + if (i != events.end()) { + i--; + } + + this->_sm->sendChange(msgbuf, CHANGE_REPEATABLE, "", chatroom); + msgbuf.clear(); + } + + KeyToNodeActionList& node_actions = this->_sm->serializer()->getNodeTrackerActions(); + this->_sm->node_tracker()->process(node_actions); + this->_sm->serializer()->reset(); + Glib::ustring commit = MessageUtilities::makeTagWithContent(MESSAGE_COMMIT, ""); + this->_sm->sendChange(commit, CHANGE_COMMIT, "", chatroom); + } +} + +} + +} + +/* + 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:textwidth=99 : diff --git a/src/jabber_whiteboard/undo-stack-observer.h b/src/jabber_whiteboard/undo-stack-observer.h new file mode 100644 index 000000000..3b3884780 --- /dev/null +++ b/src/jabber_whiteboard/undo-stack-observer.h @@ -0,0 +1,75 @@ +/** + * Undo / redo / undo log commit listener + * + * Authors: + * David Yip + * + * Copyright (c) 2005 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifndef __WHITEBOARD_UNDO_COMMIT_OBSERVER_H__ +#define __WHITEBOARD_UNDO_COMMIT_OBSERVER_H__ + +#include +#include "../undo-stack-observer.h" +#include "jabber_whiteboard/typedefs.h" + +namespace Inkscape { + +namespace Whiteboard { + +class SessionManager; + +/** + * Inkboard implementation of Inkscape::UndoStackObserver. + */ +class UndoStackObserver : public Inkscape::UndoStackObserver { +public: + enum ObserverType { + UNDO_EVENT, + REDO_EVENT, + UNDO_COMMIT_EVENT + }; + + UndoStackObserver(SessionManager* sm); + ~UndoStackObserver(); + void notifyUndoEvent(XML::Event* log); + void notifyRedoEvent(XML::Event* log); + void notifyUndoCommitEvent(XML::Event* log); + + void lockObserverFromSending(ObserverType type); + void unlockObserverFromSending(ObserverType type); + +private: + SessionManager* _sm; + + // common action handler + void _doAction(XML::Event* log); + + // noncopyable, nonassignable + UndoStackObserver(UndoStackObserver const& other); + UndoStackObserver& operator=(UndoStackObserver const& other); + + unsigned int _undoSendEventLocks; + unsigned int _redoSendEventLocks; + unsigned int _undoCommitSendEventLocks; +}; + +} + +} + +#endif + +/* + 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:textwidth=99 : diff --git a/src/knot-enums.h b/src/knot-enums.h new file mode 100644 index 000000000..708d3e19b --- /dev/null +++ b/src/knot-enums.h @@ -0,0 +1,58 @@ +#ifndef SEEN_KNOT_ENUMS_H +#define SEEN_KNOT_ENUMS_H + +/** \file + * Some enums used by SPKnot and by related types \& functions. + * + * Authors: + * Lauris Kaplinski + * + * Copyright (C) 1999-2002 authors + * Copyright (C) 2001-2002 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +typedef enum { + SP_KNOT_SHAPE_SQUARE, + SP_KNOT_SHAPE_DIAMOND, + SP_KNOT_SHAPE_CIRCLE, + SP_KNOT_SHAPE_CROSS, + SP_KNOT_SHAPE_BITMAP, + SP_KNOT_SHAPE_IMAGE +} SPKnotShapeType; + +typedef enum { + SP_KNOT_MODE_COLOR, + SP_KNOT_MODE_XOR +} SPKnotModeType; + +typedef enum { + SP_KNOT_STATE_NORMAL, + SP_KNOT_STATE_MOUSEOVER, + SP_KNOT_STATE_DRAGGING, + SP_KNOT_STATE_HIDDEN +} SPKnotStateType; + +#define SP_KNOT_VISIBLE_STATES 3 + +enum { + SP_KNOT_VISIBLE = 1 << 0, + SP_KNOT_MOUSEOVER = 1 << 1, + SP_KNOT_DRAGGING = 1 << 2, + SP_KNOT_GRABBED = 1 << 3 +}; + + +#endif /* !SEEN_KNOT_ENUMS_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:encoding=utf-8:textwidth=99 : diff --git a/src/knot-holder-entity.h b/src/knot-holder-entity.h new file mode 100644 index 000000000..1e9001e67 --- /dev/null +++ b/src/knot-holder-entity.h @@ -0,0 +1,62 @@ +#ifndef SEEN_KNOT_HOLDER_ENTITY_H +#define SEEN_KNOT_HOLDER_ENTITY_H + +/** \file + * SPKnotHolderEntity definition. + * + * Authors: + * Mitsuru Oka + * + * Copyright (C) 1999-2001 Lauris Kaplinski + * Copyright (C) 2000-2001 Ximian, Inc. + * Copyright (C) 2001 Mitsuru Oka + * Copyright (C) 2004 Monash University + * + * Released under GNU GPL + */ + +#include + +struct SPItem; +struct SPKnot; +namespace NR { +class Point; +} + +/// SPKnotHolderEntity definition. +struct SPKnotHolderEntity { + SPKnot *knot; + + /** Connection to \a knot's "moved" signal. */ + guint handler_id; + + /** + * Called solely from knot_moved_handler. + * + * \param p Requested position of the knot, in item coordinates + * \param origin Position where the knot started being dragged + * \param state GTK event state (for keyboard modifiers) + */ + void (* knot_set) (SPItem *item, NR::Point const &p, NR::Point const &origin, guint state); + + /** + * Returns the position of the knot representation, in item coordinates. + */ + NR::Point (* knot_get) (SPItem *item); + + void (* knot_click) (SPItem *item, guint state); +}; + + +#endif /* !SEEN_KNOT_HOLDER_ENTITY_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:encoding=utf-8:textwidth=99 : diff --git a/src/knot.cpp b/src/knot.cpp new file mode 100644 index 000000000..af567e6e4 --- /dev/null +++ b/src/knot.cpp @@ -0,0 +1,926 @@ +#define __SP_KNOT_C__ + +/** \file + * SPKnot implementation + * + * Authors: + * Lauris Kaplinski + * bulia byak + * + * Copyright (C) 1999-2005 authors + * Copyright (C) 2001-2002 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifdef HAVE_CONFIG_H +# include +#endif +#include +#include +#include "helper/sp-marshal.h" +#include "display/sodipodi-ctrl.h" +#include "desktop.h" +#include "desktop-handles.h" +#include "knot.h" +#include "document.h" +#include "prefs-utils.h" +#include "message-stack.h" +#include "message-context.h" +#include "event-context.h" + + +#define KNOT_EVENT_MASK (GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | \ + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | \ + GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK) + +static bool nograb = false; + +static bool grabbed = FALSE; +static bool moved = FALSE; + +static gint xp = 0, yp = 0; // where drag started +static gint tolerance = 0; +static bool within_tolerance = false; + +static bool transform_escaped = false; // true iff resize or rotate was cancelled by esc. + +enum { + PROP_0, + + PROP_SIZE, + PROP_ANCHOR, + PROP_SHAPE, + PROP_MODE, + PROP_FILL, PROP_FILL_MOUSEOVER, PROP_FILL_DRAGGING, + PROP_STROKE, PROP_STROKE_MOUSEOVER, PROP_STROKE_DRAGGING, + PROP_IMAGE, PROP_IMAGE_MOUSEOVER, PROP_IMAGE_DRAGGING, + PROP_CURSOR, PROP_CURSOR_MOUSEOVER, PROP_CURSOR_DRAGGING, + PROP_PIXBUF, + PROP_TIP, + + PROP_LAST +}; + +enum { + EVENT, + CLICKED, + DOUBLECLICKED, + GRABBED, + UNGRABBED, + MOVED, + REQUEST, + DISTANCE, + LAST_SIGNAL +}; + +static void sp_knot_class_init(SPKnotClass *klass); +static void sp_knot_init(SPKnot *knot); +static void sp_knot_dispose(GObject *object); +static void sp_knot_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); +static void sp_knot_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); + +static int sp_knot_handler(SPCanvasItem *item, GdkEvent *event, SPKnot *knot); +static void sp_knot_set_flag(SPKnot *knot, guint flag, bool set); +static void sp_knot_update_ctrl(SPKnot *knot); +static void sp_knot_set_ctrl_state(SPKnot *knot); + +static GObjectClass *parent_class; +static guint knot_signals[LAST_SIGNAL] = { 0 }; + +/** + * Registers SPKnot class and returns its type number. + */ +GType sp_knot_get_type() +{ + static GType type = 0; + if (!type) { + GTypeInfo info = { + sizeof(SPKnotClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) sp_knot_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (SPKnot), + 16, /* n_preallocs */ + (GInstanceInitFunc) sp_knot_init, + NULL + }; + type = g_type_register_static (G_TYPE_OBJECT, "SPKnot", &info, (GTypeFlags) 0); + } + return type; +} + +/** + * SPKnot vtable initialization. + */ +static void sp_knot_class_init(SPKnotClass *klass) +{ + GObjectClass *object_class = (GObjectClass *) klass; + + parent_class = (GObjectClass*) g_type_class_peek_parent(klass); + + object_class->dispose = sp_knot_dispose; + object_class->set_property = sp_knot_set_property; + object_class->get_property = sp_knot_get_property; + + /* Huh :) */ + + g_object_class_install_property(object_class, + PROP_SIZE, + g_param_spec_uint("size", "Size", "", + 0, + 0xffffffff, + 0xff000000, + (GParamFlags) G_PARAM_READWRITE)); + g_object_class_install_property(object_class, + PROP_ANCHOR, + g_param_spec_enum("anchor", "Anchor", "", + GTK_TYPE_ANCHOR_TYPE, + GTK_ANCHOR_CENTER, + (GParamFlags) G_PARAM_READWRITE)); + g_object_class_install_property(object_class, + PROP_SHAPE, + g_param_spec_int("shape", "Shape", "", + SP_KNOT_SHAPE_SQUARE, + SP_KNOT_SHAPE_IMAGE, + SP_KNOT_SHAPE_SQUARE, + (GParamFlags) G_PARAM_READWRITE)); + + g_object_class_install_property(object_class, + PROP_MODE, + g_param_spec_int("mode", "Mode", "", + SP_KNOT_MODE_COLOR, + SP_KNOT_MODE_XOR, + SP_KNOT_MODE_XOR, + (GParamFlags) G_PARAM_READWRITE)); + + g_object_class_install_property(object_class, + PROP_FILL, + g_param_spec_uint("fill", "Fill", "", + 0, + 0xffffffff, + 0xff000000, + (GParamFlags) G_PARAM_READWRITE)); + + g_object_class_install_property(object_class, + PROP_FILL_MOUSEOVER, + g_param_spec_uint("fill_mouseover", "Fill mouse over", "", + 0, + 0xffffffff, + 0xff000000, + (GParamFlags) G_PARAM_READWRITE)); + + g_object_class_install_property(object_class, + PROP_FILL_DRAGGING, + g_param_spec_uint("fill_dragging", "Fill dragging", "", + 0, + 0xffffffff, + 0xff000000, + (GParamFlags) G_PARAM_READWRITE)); + + g_object_class_install_property(object_class, + PROP_STROKE, + g_param_spec_uint("stroke", "Stroke", "", + 0, + 0xffffffff, + 0x01000000, + (GParamFlags) G_PARAM_READWRITE)); + + g_object_class_install_property(object_class, + PROP_STROKE_MOUSEOVER, + g_param_spec_uint("stroke_mouseover", "Stroke mouseover", "", + 0, + 0xffffffff, + 0x01000000, + (GParamFlags) G_PARAM_READWRITE)); + + g_object_class_install_property(object_class, + PROP_STROKE_DRAGGING, + g_param_spec_uint("stroke_dragging", "Stroke dragging", "", + 0, + 0xffffffff, + 0x01000000, + (GParamFlags) G_PARAM_READWRITE)); + + g_object_class_install_property(object_class, + PROP_IMAGE, + g_param_spec_pointer("image", "Image", "", + (GParamFlags) G_PARAM_READWRITE)); + + g_object_class_install_property(object_class, + PROP_IMAGE_MOUSEOVER, + g_param_spec_pointer("image_mouseover", "Image mouseover", "", + (GParamFlags) G_PARAM_READWRITE)); + + g_object_class_install_property(object_class, + PROP_IMAGE_DRAGGING, + g_param_spec_pointer("image_dragging", "Image dragging", "", + (GParamFlags) G_PARAM_READWRITE)); + + g_object_class_install_property(object_class, + PROP_CURSOR, + g_param_spec_boxed("cursor", "Cursor", "", + GDK_TYPE_CURSOR, + (GParamFlags) G_PARAM_READWRITE)); + + g_object_class_install_property(object_class, + PROP_CURSOR_MOUSEOVER, + g_param_spec_boxed("cursor_mouseover", "Cursor mouseover", "", + GDK_TYPE_CURSOR, + (GParamFlags) G_PARAM_READWRITE)); + + g_object_class_install_property(object_class, + PROP_CURSOR_DRAGGING, + g_param_spec_boxed("cursor_dragging", "Cursor dragging", "", + GDK_TYPE_CURSOR, + (GParamFlags) G_PARAM_READWRITE)); + + g_object_class_install_property(object_class, + PROP_PIXBUF, + g_param_spec_pointer("pixbuf", "Pixbuf", "", + (GParamFlags) G_PARAM_READWRITE)); + + g_object_class_install_property(object_class, + PROP_TIP, + g_param_spec_pointer("tip", "Tip", "", + (GParamFlags) G_PARAM_READWRITE)); + + knot_signals[EVENT] = g_signal_new("event", + G_TYPE_FROM_CLASS(klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(SPKnotClass, event), + NULL, NULL, + sp_marshal_BOOLEAN__POINTER, + G_TYPE_BOOLEAN, 1, + GDK_TYPE_EVENT); + + knot_signals[CLICKED] = g_signal_new("clicked", + G_TYPE_FROM_CLASS(klass), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET(SPKnotClass, clicked), + NULL, NULL, + sp_marshal_NONE__UINT, + G_TYPE_NONE, 1, + G_TYPE_UINT); + + knot_signals[DOUBLECLICKED] = g_signal_new("doubleclicked", + G_TYPE_FROM_CLASS(klass), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET(SPKnotClass, doubleclicked), + NULL, NULL, + sp_marshal_NONE__UINT, + G_TYPE_NONE, 1, + G_TYPE_UINT); + + knot_signals[GRABBED] = g_signal_new("grabbed", + G_TYPE_FROM_CLASS(klass), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET(SPKnotClass, grabbed), + NULL, NULL, + sp_marshal_NONE__UINT, + G_TYPE_NONE, 1, + G_TYPE_UINT); + + knot_signals[UNGRABBED] = g_signal_new("ungrabbed", + G_TYPE_FROM_CLASS(klass), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET(SPKnotClass, ungrabbed), + NULL, NULL, + sp_marshal_NONE__UINT, + G_TYPE_NONE, 1, + G_TYPE_UINT); + + knot_signals[MOVED] = g_signal_new("moved", + G_TYPE_FROM_CLASS(klass), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET(SPKnotClass, moved), + NULL, NULL, + sp_marshal_NONE__POINTER_UINT, + G_TYPE_NONE, 2, + G_TYPE_POINTER, G_TYPE_UINT); + + knot_signals[REQUEST] = g_signal_new("request", + G_TYPE_FROM_CLASS(klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(SPKnotClass, request), + NULL, NULL, + sp_marshal_BOOLEAN__POINTER_UINT, + G_TYPE_BOOLEAN, 2, + G_TYPE_POINTER, G_TYPE_UINT); + + knot_signals[DISTANCE] = g_signal_new("distance", + G_TYPE_FROM_CLASS(klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(SPKnotClass, distance), + NULL, NULL, + sp_marshal_DOUBLE__POINTER_UINT, + G_TYPE_DOUBLE, 2, + G_TYPE_POINTER, G_TYPE_UINT); + + const gchar *nograbenv = getenv("INKSCAPE_NO_GRAB"); + nograb = (nograbenv && *nograbenv && (*nograbenv != '0')); +} + +/** + * Callback for SPKnot initialization. + */ +static void sp_knot_init(SPKnot *knot) +{ + knot->desktop = NULL; + knot->item = NULL; + knot->flags = 0; + + knot->size = 8; + knot->pos = NR::Point(0, 0); + knot->grabbed_rel_pos = NR::Point(0, 0); + knot->anchor = GTK_ANCHOR_CENTER; + knot->shape = SP_KNOT_SHAPE_SQUARE; + knot->mode = SP_KNOT_MODE_XOR; + knot->tip = NULL; + + knot->fill[SP_KNOT_STATE_NORMAL] = 0xffffff00; + knot->fill[SP_KNOT_STATE_MOUSEOVER] = 0xff0000ff; + knot->fill[SP_KNOT_STATE_DRAGGING] = 0x0000ffff; + + knot->stroke[SP_KNOT_STATE_NORMAL] = 0x01000000; + knot->stroke[SP_KNOT_STATE_MOUSEOVER] = 0x01000000; + knot->stroke[SP_KNOT_STATE_DRAGGING] = 0x01000000; + + knot->image[SP_KNOT_STATE_NORMAL] = NULL; + knot->image[SP_KNOT_STATE_MOUSEOVER] = NULL; + knot->image[SP_KNOT_STATE_DRAGGING] = NULL; + + knot->cursor[SP_KNOT_STATE_NORMAL] = NULL; + knot->cursor[SP_KNOT_STATE_MOUSEOVER] = NULL; + knot->cursor[SP_KNOT_STATE_DRAGGING] = NULL; + + knot->saved_cursor = NULL; + knot->pixbuf = NULL; +} + +/** + * Called before SPKnot destruction. + */ +static void sp_knot_dispose(GObject *object) +{ + SPKnot *knot = (SPKnot *) object; + + if ((knot->flags & SP_KNOT_GRABBED) && gdk_pointer_is_grabbed ()) { + // This happens e.g. when deleting a node in node tool while dragging it + gdk_pointer_ungrab (GDK_CURRENT_TIME); + } + + if (knot->item) { + gtk_object_destroy (GTK_OBJECT (knot->item)); + knot->item = NULL; + } + + for (gint i = 0; i < SP_KNOT_VISIBLE_STATES; i++) { + if (knot->cursor[i]) { + gdk_cursor_unref(knot->cursor[i]); + knot->cursor[i] = NULL; + } + } + + if (knot->tip) { + g_free(knot->tip); + knot->tip = NULL; + } + + if (((GObjectClass *) (parent_class))->dispose) { + (* ((GObjectClass *) (parent_class))->dispose) (object); + } +} + +/** + * Callback to set property. + */ +static void sp_knot_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + GdkCursor *cursor; + + SPKnot *knot = SP_KNOT(object); + + switch (prop_id) { + case PROP_SIZE: + knot->size = g_value_get_uint(value); + break; + case PROP_ANCHOR: + knot->anchor = (GtkAnchorType) g_value_get_enum(value); + break; + case PROP_SHAPE: + knot->shape = (SPKnotShapeType) g_value_get_int(value); + break; + case PROP_MODE: + knot->mode = (SPKnotModeType) g_value_get_int(value); + break; + case PROP_FILL: + knot->fill[SP_KNOT_STATE_NORMAL] = + knot->fill[SP_KNOT_STATE_MOUSEOVER] = + knot->fill[SP_KNOT_STATE_DRAGGING] = g_value_get_uint(value); + break; + case PROP_FILL_MOUSEOVER: + knot->fill[SP_KNOT_STATE_MOUSEOVER] = + knot->fill[SP_KNOT_STATE_DRAGGING] = g_value_get_uint(value); + break; + case PROP_FILL_DRAGGING: + knot->fill[SP_KNOT_STATE_DRAGGING] = g_value_get_uint(value); + break; + case PROP_STROKE: + knot->stroke[SP_KNOT_STATE_NORMAL] = + knot->stroke[SP_KNOT_STATE_MOUSEOVER] = + knot->stroke[SP_KNOT_STATE_DRAGGING] = g_value_get_uint(value); + break; + case PROP_STROKE_MOUSEOVER: + knot->stroke[SP_KNOT_STATE_MOUSEOVER] = + knot->stroke[SP_KNOT_STATE_DRAGGING] = g_value_get_uint(value); + break; + case PROP_STROKE_DRAGGING: + knot->stroke[SP_KNOT_STATE_DRAGGING] = g_value_get_uint(value); + break; + case PROP_IMAGE: + knot->image[SP_KNOT_STATE_NORMAL] = + knot->image[SP_KNOT_STATE_MOUSEOVER] = + knot->image[SP_KNOT_STATE_DRAGGING] = (guchar*) g_value_get_pointer(value); + break; + case PROP_IMAGE_MOUSEOVER: + knot->image[SP_KNOT_STATE_MOUSEOVER] = (guchar*) g_value_get_pointer(value); + break; + case PROP_IMAGE_DRAGGING: + knot->image[SP_KNOT_STATE_DRAGGING] = (guchar*) g_value_get_pointer(value); + break; + case PROP_CURSOR: + cursor = (GdkCursor*) g_value_get_boxed(value); + for (gint i = 0; i < SP_KNOT_VISIBLE_STATES; i++) { + if (knot->cursor[i]) { + gdk_cursor_unref(knot->cursor[i]); + } + knot->cursor[i] = cursor; + if (cursor) { + gdk_cursor_ref(cursor); + } + } + break; + case PROP_CURSOR_MOUSEOVER: + cursor = (GdkCursor*) g_value_get_boxed(value); + if (knot->cursor[SP_KNOT_STATE_MOUSEOVER]) { + gdk_cursor_unref(knot->cursor[SP_KNOT_STATE_MOUSEOVER]); + } + knot->cursor[SP_KNOT_STATE_MOUSEOVER] = cursor; + if (cursor) { + gdk_cursor_ref(cursor); + } + break; + case PROP_CURSOR_DRAGGING: + cursor = (GdkCursor*) g_value_get_boxed(value); + if (knot->cursor[SP_KNOT_STATE_DRAGGING]) { + gdk_cursor_unref(knot->cursor[SP_KNOT_STATE_DRAGGING]); + } + knot->cursor[SP_KNOT_STATE_DRAGGING] = cursor; + if (cursor) { + gdk_cursor_ref(cursor); + } + break; + case PROP_PIXBUF: + knot->pixbuf = g_value_get_pointer(value); + break; + case PROP_TIP: + knot->tip = g_strdup((const gchar *) g_value_get_pointer(value)); + break; + default: + g_assert_not_reached(); + break; + } + + sp_knot_update_ctrl(knot); +} + +/// Not reached. +static void sp_knot_get_property(GObject *, guint, GValue *, GParamSpec *) +{ + g_assert_not_reached(); +} + +/** + * Update knot for dragging and tell canvas an item was grabbed. + */ +void sp_knot_start_dragging(SPKnot *knot, NR::Point p, gint x, gint y, guint32 etime) +{ + // save drag origin + xp = x; + yp = y; + within_tolerance = true; + + knot->grabbed_rel_pos = p - knot->pos; + knot->drag_origin = knot->pos; + if (!nograb) { + sp_canvas_item_grab(knot->item, + KNOT_EVENT_MASK, + knot->cursor[SP_KNOT_STATE_DRAGGING], + etime); + } + sp_knot_set_flag(knot, SP_KNOT_GRABBED, TRUE); + grabbed = TRUE; +} + +/** + * Called to handle events on knots. + */ +static int sp_knot_handler(SPCanvasItem *item, GdkEvent *event, SPKnot *knot) +{ + g_assert(knot != NULL); + g_assert(SP_IS_KNOT(knot)); + + tolerance = prefs_get_int_attribute_limited("options.dragtolerance", "value", 0, 0, 100); + + gboolean consumed = FALSE; + + /* Run client universal event handler, if present */ + + g_signal_emit(G_OBJECT(knot), knot_signals[EVENT], 0, event, &consumed); + + if (consumed) { + return TRUE; + } + + switch (event->type) { + case GDK_2BUTTON_PRESS: + if (event->button.button == 1) { + g_signal_emit(G_OBJECT(knot), knot_signals[DOUBLECLICKED], 0, event->button.state); + + grabbed = FALSE; + moved = FALSE; + consumed = TRUE; + } + break; + case GDK_BUTTON_PRESS: + if (event->button.button == 1) { + NR::Point const p = knot->desktop->w2d(NR::Point(event->button.x, event->button.y)); + sp_knot_start_dragging(knot, p, (gint) event->button.x, (gint) event->button.y, event->button.time); + consumed = TRUE; + } + break; + case GDK_BUTTON_RELEASE: + if (event->button.button == 1) { + if (transform_escaped) { + transform_escaped = false; + consumed = TRUE; + } else { + sp_knot_set_flag(knot, SP_KNOT_GRABBED, FALSE); + if (!nograb) { + sp_canvas_item_ungrab(knot->item, event->button.time); + } + if (moved) { + sp_knot_set_flag(knot, + SP_KNOT_DRAGGING, + FALSE); + g_signal_emit(G_OBJECT (knot), + knot_signals[UNGRABBED], 0, + event->button.state); + } else { + g_signal_emit(G_OBJECT (knot), + knot_signals[CLICKED], 0, + event->button.state); + } + grabbed = FALSE; + moved = FALSE; + consumed = TRUE; + } + } + break; + case GDK_MOTION_NOTIFY: + if (grabbed) { + consumed = TRUE; + + if ( within_tolerance + && ( abs( (gint) event->motion.x - xp ) < tolerance ) + && ( abs( (gint) event->motion.y - yp ) < tolerance ) ) { + break; // do not drag if we're within tolerance from origin + } + + // Once the user has moved farther than tolerance from the original location + // (indicating they intend to move the object, not click), then always process the + // motion notify coordinates as given (no snapping back to origin) + within_tolerance = false; + + if (!moved) { + g_signal_emit(G_OBJECT (knot), + knot_signals[GRABBED], 0, + event->motion.state); + sp_knot_set_flag(knot, + SP_KNOT_DRAGGING, + TRUE); + } + NR::Point const motion_w(event->motion.x, event->motion.y); + NR::Point const motion_dt = knot->desktop->w2d(motion_w); + NR::Point p = motion_dt - knot->grabbed_rel_pos; + sp_knot_request_position (knot, &p, event->motion.state); + knot->desktop->scroll_to_point (&motion_dt); + moved = TRUE; + } + break; + case GDK_ENTER_NOTIFY: + sp_knot_set_flag(knot, SP_KNOT_MOUSEOVER, TRUE); + sp_knot_set_flag(knot, SP_KNOT_GRABBED, FALSE); + + if (knot->tip) { + knot->desktop->event_context->defaultMessageContext()->set(Inkscape::NORMAL_MESSAGE, knot->tip); + } + + grabbed = FALSE; + moved = FALSE; + consumed = TRUE; + break; + case GDK_LEAVE_NOTIFY: + sp_knot_set_flag(knot, SP_KNOT_MOUSEOVER, FALSE); + sp_knot_set_flag(knot, SP_KNOT_GRABBED, FALSE); + + if (knot->tip) { + knot->desktop->event_context->defaultMessageContext()->clear(); + } + + grabbed = FALSE; + moved = FALSE; + + consumed = TRUE; + break; + case GDK_KEY_PRESS: // keybindings for knot + switch (get_group0_keyval(&event->key)) { + case GDK_Escape: + sp_knot_set_flag(knot, SP_KNOT_GRABBED, FALSE); + if (!nograb) { + sp_canvas_item_ungrab(knot->item, event->button.time); + } + if (moved) { + sp_knot_set_flag(knot, + SP_KNOT_DRAGGING, + FALSE); + g_signal_emit(G_OBJECT(knot), + knot_signals[UNGRABBED], 0, + event->button.state); + sp_document_undo(SP_DT_DOCUMENT(knot->desktop)); + knot->desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Node or handle drag canceled.")); + transform_escaped = true; + consumed = TRUE; + } + grabbed = FALSE; + moved = FALSE; + break; + default: + consumed = FALSE; + break; + } + break; + default: + break; + } + + + return consumed; +} + +/** + * Return new knot object. + */ +SPKnot *sp_knot_new(SPDesktop *desktop, const gchar *tip) +{ + g_return_val_if_fail(desktop != NULL, NULL); + + SPKnot * knot = (SPKnot*) g_object_new(SP_TYPE_KNOT, 0); + + knot->desktop = desktop; + knot->flags = SP_KNOT_VISIBLE; + if (tip) { + knot->tip = g_strdup (tip); + } + + knot->item = sp_canvas_item_new(SP_DT_CONTROLS (desktop), + SP_TYPE_CTRL, + "anchor", GTK_ANCHOR_CENTER, + "size", 8.0, + "filled", TRUE, + "fill_color", 0xffffff00, + "stroked", TRUE, + "stroke_color", 0x01000000, + "mode", SP_KNOT_MODE_XOR, + NULL); + + gtk_signal_connect(GTK_OBJECT(knot->item), "event", + GTK_SIGNAL_FUNC(sp_knot_handler), knot); + + return knot; +} + +/** + * Show knot on its canvas. + */ +void sp_knot_show(SPKnot *knot) +{ + g_return_if_fail(knot != NULL); + g_return_if_fail(SP_IS_KNOT (knot)); + + sp_knot_set_flag(knot, SP_KNOT_VISIBLE, TRUE); +} + +/** + * Hide knot on its canvas. + */ +void sp_knot_hide(SPKnot *knot) +{ + g_return_if_fail(knot != NULL); + g_return_if_fail(SP_IS_KNOT(knot)); + + sp_knot_set_flag(knot, SP_KNOT_VISIBLE, FALSE); +} + +/** + * Request or set new position for knot. + */ +void sp_knot_request_position(SPKnot *knot, NR::Point *p, guint state) +{ + g_return_if_fail(knot != NULL); + g_return_if_fail(SP_IS_KNOT(knot)); + + gboolean done = FALSE; + + g_signal_emit(G_OBJECT (knot), + knot_signals[REQUEST], 0, + p, + state, + &done); + + /* If user did not complete, we simply move knot to new position */ + + if (!done) { + sp_knot_set_position (knot, p, state); + } +} + +/** + * Return distance of point to knot's position; unused. + */ +gdouble sp_knot_distance(SPKnot * knot, NR::Point *p, guint state) +{ + g_return_val_if_fail(knot != NULL, 1e18); + g_return_val_if_fail(SP_IS_KNOT(knot), 1e18); + + gdouble distance = NR::L2(*p - knot->pos); + + g_signal_emit(G_OBJECT(knot), + knot_signals[DISTANCE], 0, + p, + state, + &distance); + + return distance; +} + +/** + * Move knot to new position. + */ +void sp_knot_set_position(SPKnot *knot, NR::Point *p, guint state) +{ + g_return_if_fail(knot != NULL); + g_return_if_fail(SP_IS_KNOT (knot)); + + knot->pos = *p; + + if (knot->item) { + SP_CTRL(knot->item)->moveto (*p); + } + + g_signal_emit(G_OBJECT (knot), + knot_signals[MOVED], 0, + p, + state); +} + +/** + * Move knot to new position, without emitting a MOVED signal. + */ +void sp_knot_moveto(SPKnot *knot, NR::Point *p) +{ + g_return_if_fail(knot != NULL); + g_return_if_fail(SP_IS_KNOT(knot)); + + knot->pos = *p; + + if (knot->item) { + SP_CTRL(knot->item)->moveto (*p); + } +} + +/** + * Returns position of knot. + */ +NR::Point sp_knot_position(SPKnot const *knot) +{ + g_assert(knot != NULL); + g_assert(SP_IS_KNOT (knot)); + + return knot->pos; +} + +/** + * Set flag in knot, with side effects. + */ +static void sp_knot_set_flag(SPKnot *knot, guint flag, bool set) +{ + g_assert(knot != NULL); + g_assert(SP_IS_KNOT(knot)); + + if (set) { + knot->flags |= flag; + } else { + knot->flags &= ~flag; + } + + switch (flag) { + case SP_KNOT_VISIBLE: + if (set) { + sp_canvas_item_show(knot->item); + } else { + sp_canvas_item_hide(knot->item); + } + break; + case SP_KNOT_MOUSEOVER: + case SP_KNOT_DRAGGING: + sp_knot_set_ctrl_state(knot); + break; + case SP_KNOT_GRABBED: + break; + default: + g_assert_not_reached(); + break; + } +} + +/** + * Update knot's pixbuf and set its control state. + */ +static void sp_knot_update_ctrl(SPKnot *knot) +{ + if (!knot->item) { + return; + } + + gtk_object_set(GTK_OBJECT(knot->item), "shape", knot->shape, NULL); + gtk_object_set(GTK_OBJECT(knot->item), "mode", knot->mode, NULL); + gtk_object_set(GTK_OBJECT(knot->item), "size", (gdouble) knot->size, NULL); + gtk_object_set(GTK_OBJECT(knot->item), "anchor", knot->anchor, NULL); + if (knot->pixbuf) { + gtk_object_set(GTK_OBJECT (knot->item), "pixbuf", knot->pixbuf, NULL); + } + + sp_knot_set_ctrl_state(knot); +} + +/** + * Set knot control state (dragging/mouseover/normal). + */ +static void sp_knot_set_ctrl_state(SPKnot *knot) +{ + if (knot->flags & SP_KNOT_DRAGGING) { + gtk_object_set(GTK_OBJECT (knot->item), + "fill_color", + knot->fill[SP_KNOT_STATE_DRAGGING], + NULL); + gtk_object_set(GTK_OBJECT (knot->item), + "stroke_color", + knot->stroke[SP_KNOT_STATE_DRAGGING], + NULL); + } else if (knot->flags & SP_KNOT_MOUSEOVER) { + gtk_object_set(GTK_OBJECT(knot->item), + "fill_color", + knot->fill[SP_KNOT_STATE_MOUSEOVER], + NULL); + gtk_object_set(GTK_OBJECT(knot->item), + "stroke_color", + knot->stroke[SP_KNOT_STATE_MOUSEOVER], + NULL); + } else { + gtk_object_set(GTK_OBJECT(knot->item), + "fill_color", + knot->fill[SP_KNOT_STATE_NORMAL], + NULL); + gtk_object_set(GTK_OBJECT(knot->item), + "stroke_color", + knot->stroke[SP_KNOT_STATE_NORMAL], + NULL); + } +} + + + +/* + 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 : diff --git a/src/knot.h b/src/knot.h new file mode 100644 index 000000000..02c0f19ad --- /dev/null +++ b/src/knot.h @@ -0,0 +1,127 @@ +#ifndef __SP_KNOT_H__ +#define __SP_KNOT_H__ + +/** \file + * Declarations for SPKnot: Desktop-bound visual control object. + */ +/* + * Authors: + * Lauris Kaplinski + * + * Copyright (C) 1999-2002 authors + * Copyright (C) 2001-2002 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include +#include +#include "display/display-forward.h" +#include "forward.h" +#include +#include "knot-enums.h" + +class SPKnot; +class SPKnotClass; + +#define SP_TYPE_KNOT (sp_knot_get_type()) +#define SP_KNOT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), SP_TYPE_KNOT, SPKnot)) +#define SP_KNOT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), SP_TYPE_KNOT, SPKnotClass)) +#define SP_IS_KNOT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), SP_TYPE_KNOT)) +#define SP_IS_KNOT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), SP_TYPE_KNOT)) + +/** + * Desktop-bound visual control object. + * + * A knot is a draggable object, with callbacks to change something by + * dragging it, visuably represented by a canvas item (mostly square). + */ +struct SPKnot { + GObject object; + SPDesktop *desktop; /**< Desktop we are on. */ + SPCanvasItem *item; /**< Our CanvasItem. */ + guint flags; + + guint size; /**< Always square. */ + NR::Point pos; /**< Our desktop coordinates. */ + NR::Point grabbed_rel_pos; /**< Grabbed relative position. */ + NR::Point drag_origin; /**< Origin of drag. */ + GtkAnchorType anchor; /**< Anchor. */ + + SPKnotShapeType shape; /**< Shape type. */ + SPKnotModeType mode; + + guint32 fill[SP_KNOT_VISIBLE_STATES]; + guint32 stroke[SP_KNOT_VISIBLE_STATES]; + guchar *image[SP_KNOT_VISIBLE_STATES]; + + GdkCursor *cursor[SP_KNOT_VISIBLE_STATES]; + + GdkCursor *saved_cursor; + gpointer pixbuf; + + gchar *tip; +}; + +/// The SPKnot vtable. +struct SPKnotClass { + GObjectClass parent_class; + + gint (* event) (SPKnot *knot, GdkEvent *event); + + /* + * These are unconditional. + */ + + void (* clicked) (SPKnot *knot, guint state); + void (* doubleclicked) (SPKnot *knot, guint state); + void (* grabbed) (SPKnot *knot, guint state); + void (* ungrabbed) (SPKnot *knot, guint state); + void (* moved) (SPKnot *knot, NR::Point *position, guint state); + void (* stamped) (SPKnot *know, guint state); + + /** Request knot to move to absolute position. */ + bool (* request) (SPKnot *knot, NR::Point *pos, guint state); + + /** Find complex distance from knot to point. */ + gdouble (* distance) (SPKnot *knot, NR::Point *pos, guint state); +}; + +GType sp_knot_get_type(); + +SPKnot *sp_knot_new(SPDesktop *desktop, gchar const *tip = NULL); + +#define SP_KNOT_IS_VISIBLE(k) ((k->flags & SP_KNOT_VISIBLE) != 0) +#define SP_KNOT_IS_MOSEOVER(k) ((k->flags & SP_KNOT_MOUSEOVER) != 0) +#define SP_KNOT_IS_DRAGGING(k) ((k->flags & SP_KNOT_DRAGGING) != 0) +#define SP_KNOT_IS_GRABBED(k) ((k->flags & SP_KNOT_GRABBED) != 0) + +void sp_knot_show(SPKnot *knot); +void sp_knot_hide(SPKnot *knot); + +void sp_knot_request_position(SPKnot *knot, NR::Point *pos, guint state); +gdouble sp_knot_distance(SPKnot *knot, NR::Point *p, guint state); + +void sp_knot_start_dragging(SPKnot *knot, NR::Point p, gint x, gint y, guint32 etime); + +/** Moves knot and emits "moved" signal. */ +void sp_knot_set_position(SPKnot *knot, NR::Point *p, guint state); + +/** Moves knot without any signal. */ +void sp_knot_moveto(SPKnot *knot, NR::Point *p); + +NR::Point sp_knot_position(SPKnot const *knot); + + +#endif /* !__SP_KNOT_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:encoding=utf-8:textwidth=99 : diff --git a/src/knotholder.cpp b/src/knotholder.cpp new file mode 100644 index 000000000..70a234260 --- /dev/null +++ b/src/knotholder.cpp @@ -0,0 +1,229 @@ +#define __KNOT_HOLDER_C__ + +/* + * Container for SPKnot visual handles + * + * Authors: + * Mitsuru Oka + * bulia byak + * + * Copyright (C) 2001-2005 authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#define noKNOT_HOLDER_DEBUG + + +#include "document.h" +#include "sp-shape.h" +#include "knot.h" +#include "knotholder.h" +#include "knot-holder-entity.h" +#include + +class SPDesktop; + +static void knot_clicked_handler (SPKnot *knot, guint state, gpointer data); +static void knot_moved_handler(SPKnot *knot, NR::Point const *p, guint state, gpointer data); +static void knot_ungrabbed_handler (SPKnot *knot, unsigned int state, SPKnotHolder *kh); + +#ifdef KNOT_HOLDER_DEBUG + +static void sp_knot_holder_debug(GtkObject *object, gpointer data) +{ + g_print("sp-knot-holder-debug: [type=%s] [data=%s]\n", gtk_type_name(GTK_OBJECT_TYPE(object)), (const gchar *) data); +} +#endif + +SPKnotHolder *sp_knot_holder_new(SPDesktop *desktop, SPItem *item, SPKnotHolderReleasedFunc relhandler) +{ + Inkscape::XML::Node *repr = SP_OBJECT(item)->repr; + + g_return_val_if_fail(desktop != NULL, NULL); + g_return_val_if_fail(item != NULL, NULL); + g_return_val_if_fail(SP_IS_ITEM(item), NULL); + + SPKnotHolder *knot_holder = g_new(SPKnotHolder, 1); + knot_holder->desktop = desktop; + knot_holder->item = item; + g_object_ref(G_OBJECT(item)); + knot_holder->entity = NULL; + + knot_holder->released = relhandler; + + knot_holder->repr = repr; + knot_holder->local_change = FALSE; + +#ifdef KNOT_HOLDER_DEBUG + g_signal_connect(G_OBJECT(desktop), "destroy", sp_knot_holder_debug, (gpointer) "SPKnotHolder::item"); +#endif + + return knot_holder; +} + +void sp_knot_holder_destroy(SPKnotHolder *kh) +{ + if (kh) { + g_object_unref(G_OBJECT(kh->item)); + while (kh->entity) { + SPKnotHolderEntity *e = (SPKnotHolderEntity *) kh->entity->data; + /* unref should call destroy */ + g_object_unref(G_OBJECT(e->knot)); + g_free(e); + kh->entity = g_slist_remove(kh->entity, e); + } + + g_free(kh); + } +} + +void sp_knot_holder_add( + SPKnotHolder *knot_holder, + SPKnotHolderSetFunc knot_set, + SPKnotHolderGetFunc knot_get, + void (* knot_click) (SPItem *item, guint state), + const gchar *tip + ) +{ + sp_knot_holder_add_full(knot_holder, knot_set, knot_get, knot_click, SP_KNOT_SHAPE_DIAMOND, SP_KNOT_MODE_XOR, tip); +} + +void sp_knot_holder_add_full( + SPKnotHolder *knot_holder, + SPKnotHolderSetFunc knot_set, + SPKnotHolderGetFunc knot_get, + void (* knot_click) (SPItem *item, guint state), + SPKnotShapeType shape, + SPKnotModeType mode, + const gchar *tip + ) +{ + g_return_if_fail(knot_holder != NULL); + g_return_if_fail(knot_set != NULL); + g_return_if_fail(knot_get != NULL); + + SPItem *item = SP_ITEM(knot_holder->item); + + /* create new SPKnotHolderEntry */ + SPKnotHolderEntity *e = g_new(SPKnotHolderEntity, 1); + e->knot = sp_knot_new(knot_holder->desktop, tip); + e->knot_set = knot_set; + e->knot_get = knot_get; + if (knot_click) { + e->knot_click = knot_click; + } else { + e->knot_click = NULL; + } + + g_object_set(G_OBJECT (e->knot->item), "shape", shape, NULL); + g_object_set(G_OBJECT (e->knot->item), "mode", mode, NULL); + + // TODO: add a color argument + //e->knot->fill [SP_KNOT_STATE_NORMAL] = 0x00ff0000; + //g_object_set (G_OBJECT (e->knot->item), "fill_color", 0x00ff0000, NULL); + + knot_holder->entity = g_slist_append(knot_holder->entity, e); + + /* Move to current point. */ + NR::Point dp = e->knot_get(item) * sp_item_i2d_affine(item); + sp_knot_set_position(e->knot, &dp, SP_KNOT_STATE_NORMAL); + + e->handler_id = g_signal_connect(G_OBJECT(e->knot), "moved", G_CALLBACK(knot_moved_handler), knot_holder); + g_signal_connect(G_OBJECT(e->knot), "clicked", G_CALLBACK(knot_clicked_handler), knot_holder); + g_signal_connect(G_OBJECT(e->knot), "ungrabbed", G_CALLBACK(knot_ungrabbed_handler), knot_holder); + +#ifdef KNOT_HOLDER_DEBUG + g_signal_connect(ob, "destroy", sp_knot_holder_debug, "SPKnotHolder::knot"); +#endif + sp_knot_show(e->knot); +} + +/** + * \param p In desktop coordinates. + */ + +static void knotholder_update_knots(SPKnotHolder *knot_holder, SPItem *item) +{ + NR::Matrix const i2d(sp_item_i2d_affine(item)); + + for (GSList *el = knot_holder->entity; el; el = el->next) { + SPKnotHolderEntity *e = (SPKnotHolderEntity *) el->data; + GObject *kob = G_OBJECT(e->knot); + + NR::Point dp( e->knot_get(item) * i2d ); + g_signal_handler_block(kob, e->handler_id); + sp_knot_set_position(e->knot, &dp, SP_KNOT_STATE_NORMAL); + g_signal_handler_unblock(kob, e->handler_id); + } +} + +static void knot_clicked_handler(SPKnot *knot, guint state, gpointer data) +{ + SPKnotHolder *knot_holder = (SPKnotHolder *) data; + SPItem *item = SP_ITEM (knot_holder->item); + + for (GSList *el = knot_holder->entity; el; el = el->next) { + SPKnotHolderEntity *e = (SPKnotHolderEntity *) el->data; + if (e->knot == knot) { + if (e->knot_click) { + e->knot_click(item, state); + } + break; + } + } + + if (SP_IS_SHAPE(item)) { + sp_shape_set_shape(SP_SHAPE(item)); + } + + knotholder_update_knots(knot_holder, item); + + // for drag, this is done by ungrabbed_handler, but for click we must do it here + sp_document_done(SP_OBJECT_DOCUMENT(knot_holder->item)); +} + +static void knot_moved_handler(SPKnot *knot, NR::Point const *p, guint state, gpointer data) +{ + SPKnotHolder *knot_holder = (SPKnotHolder *) data; + SPItem *item = SP_ITEM (knot_holder->item); + // this was a local change and the knotholder does not need to be recreated: + knot_holder->local_change = TRUE; + + for (GSList *el = knot_holder->entity; el; el = el->next) { + SPKnotHolderEntity *e = (SPKnotHolderEntity *) el->data; + if (e->knot == knot) { + NR::Point const q = *p / sp_item_i2d_affine(item); + e->knot_set(item, q, e->knot->drag_origin / sp_item_i2d_affine(item), state); + break; + } + } + + if (SP_IS_SHAPE (item)) { + sp_shape_set_shape(SP_SHAPE (item)); + } + + knotholder_update_knots(knot_holder, item); +} + +static void knot_ungrabbed_handler(SPKnot *knot, unsigned int state, SPKnotHolder *kh) +{ + if (kh->released) { + kh->released(kh->item); + } else { + SPObject *object = (SPObject *) kh->item; + object->updateRepr(object->repr, SP_OBJECT_WRITE_EXT); + sp_document_done(SP_OBJECT_DOCUMENT (object)); + } +} + +/* + 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:textwidth=99 : diff --git a/src/knotholder.h b/src/knotholder.h new file mode 100644 index 000000000..6980e2fdd --- /dev/null +++ b/src/knotholder.h @@ -0,0 +1,79 @@ +#ifndef __SP_KNOTHOLDER_H__ +#define __SP_KNOTHOLDER_H__ + +/* + * SPKnotHolder - Hold SPKnot list and manage signals + * + * Author: + * Mitsuru Oka + * + * Copyright (C) 1999-2001 Lauris Kaplinski + * Copyright (C) 2000-2001 Ximian, Inc. + * Copyright (C) 2001 Mitsuru Oka + * + * Released under GNU GPL + * + */ + +#include +#include "knot-enums.h" +#include "forward.h" +#include "libnr/nr-forward.h" + +namespace Inkscape { +namespace XML { +class Node; +} +} + + +typedef void (* SPKnotHolderSetFunc) (SPItem *item, NR::Point const &p, NR::Point const &origin, guint state); +typedef NR::Point (* SPKnotHolderGetFunc) (SPItem *item); +/* fixme: Think how to make callbacks most sensitive (Lauris) */ +typedef void (* SPKnotHolderReleasedFunc) (SPItem *item); + +struct SPKnotHolder { + SPDesktop *desktop; + SPItem *item; + GSList *entity; + + SPKnotHolderReleasedFunc released; + + Inkscape::XML::Node *repr; ///< repr of the item, for setting and releasing listeners. + + gboolean local_change; ///< if true, no need to recreate knotholder if repr was changed. +}; + + +/* fixme: As a temporary solution, if released is NULL knotholder flushes undo itself (Lauris) */ +SPKnotHolder *sp_knot_holder_new(SPDesktop *desktop, SPItem *item, SPKnotHolderReleasedFunc relhandler); + +void sp_knot_holder_destroy(SPKnotHolder *knots); + +void sp_knot_holder_add(SPKnotHolder *knot_holder, + SPKnotHolderSetFunc knot_set, + SPKnotHolderGetFunc knot_get, + void (* knot_click) (SPItem *item, guint state), + gchar const *tip); + +void sp_knot_holder_add_full(SPKnotHolder *knot_holder, + SPKnotHolderSetFunc knot_set, + SPKnotHolderGetFunc knot_get, + void (* knot_click) (SPItem *item, guint state), + SPKnotShapeType shape, + SPKnotModeType mode, + gchar const *tip); + + +#endif /* !__SP_KNOTHOLDER_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:encoding=utf-8:textwidth=99 : diff --git a/src/layer-fns.cpp b/src/layer-fns.cpp new file mode 100644 index 000000000..fadcd0f1e --- /dev/null +++ b/src/layer-fns.cpp @@ -0,0 +1,186 @@ +/* + * Inkscape::SelectionDescriber - shows messages describing selection + * + * Authors: + * MenTaLguY + * + * Copyright (C) 2004 MenTaLguY + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "document.h" +#include "sp-item-group.h" +#include "xml/repr.h" +#include "algorithms/find-last-if.h" + +namespace Inkscape { + +/** + * Creates a new layer. Advances to the next layer id indicated + * by the string "layerNN", then creates a new group object of + * that id with attribute inkscape:groupmode='layer', and finally + * appends the new group object to \a root after object \a layer. + * + * \pre \a root should be either \a layer or an ancestor of it + */ +SPObject *create_layer(SPObject *root, SPObject *layer) { + SPDocument *document=SP_OBJECT_DOCUMENT(root); + + static int layer_suffix=1; + gchar *id=NULL; + do { + g_free(id); + id = g_strdup_printf("layer%d", layer_suffix++); + } while (document->getObjectById(id)); + + Inkscape::XML::Node *repr=sp_repr_new("svg:g"); + repr->setAttribute("inkscape:groupmode", "layer"); + repr->setAttribute("id", id); + g_free(id); + + if ( root == layer ) { + SP_OBJECT_REPR(root)->appendChild(repr); + } else { + Inkscape::XML::Node *layer_repr=SP_OBJECT_REPR(layer); + sp_repr_parent(layer_repr)->addChild(repr, layer_repr); + } + + return document->getObjectByRepr(repr); +} + +namespace { + +bool is_layer(SPObject &object) { + return SP_IS_GROUP(&object) && + SP_GROUP(&object)->layerMode() == SPGroup::LAYER; +} + +SPObject *next_sibling_layer(SPObject *layer) { + using std::find_if; + + return find_if( + SP_OBJECT_NEXT(layer), NULL, &is_layer + ); +} + +SPObject *previous_sibling_layer(SPObject *layer) { + using Inkscape::Algorithms::find_last_if; + + SPObject *sibling(find_last_if( + SP_OBJECT_PARENT(layer)->firstChild(), layer, &is_layer + )); + + return ( sibling != layer ) ? sibling : NULL; +} + +SPObject *first_descendant_layer(SPObject *layer) { + using std::find_if; + + SPObject *first_descendant=NULL; + while (layer) { + layer = find_if( + layer->firstChild(), NULL, &is_layer + ); + if (layer) { + first_descendant = layer; + } + } + + return first_descendant; +} + +SPObject *last_child_layer(SPObject *layer) { + using Inkscape::Algorithms::find_last_if; + + return find_last_if( + layer->firstChild(), NULL, &is_layer + ); +} + +SPObject *last_elder_layer(SPObject *root, SPObject *layer) { + using Inkscape::Algorithms::find_last_if; + + while ( layer != root ) { + SPObject *sibling(previous_sibling_layer(layer)); + if (sibling) { + return sibling; + } + layer = SP_OBJECT_PARENT(layer); + } + + return NULL; +} + +} + +/** Finds the next layer under \a root, relative to \a layer in + * depth-first order. + * + * @returns NULL if there are no further layers under \a root + */ +SPObject *next_layer(SPObject *root, SPObject *layer) { + using std::find_if; + + g_return_val_if_fail(layer != NULL, NULL); + + SPObject *sibling(next_sibling_layer(layer)); + if (sibling) { + SPObject *descendant(first_descendant_layer(sibling)); + if (descendant) { + return descendant; + } else { + return sibling; + } + } else { + SPObject *parent=SP_OBJECT_PARENT(layer); + if ( parent != root ) { + return parent; + } else { + return NULL; + } + } +} + + +/** Finds the previous layer under \a root, relative to \a layer in + * depth-first order. + * + * @returns NULL if there are no prior layers under \a root. + */ +SPObject *previous_layer(SPObject *root, SPObject *layer) { + using Inkscape::Algorithms::find_last_if; + + g_return_val_if_fail(layer != NULL, NULL); + + SPObject *child(last_child_layer(layer)); + if (child) { + return child; + } else if ( layer != root ) { + SPObject *sibling(previous_sibling_layer(layer)); + if (sibling) { + return sibling; + } else { + return last_elder_layer(root, SP_OBJECT_PARENT(layer)); + } + } + + return NULL; +} + +} + +/* + 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:textwidth=99 : diff --git a/src/layer-fns.h b/src/layer-fns.h new file mode 100644 index 000000000..ba11bab6a --- /dev/null +++ b/src/layer-fns.h @@ -0,0 +1,37 @@ +/* + * assorted functions related to layers + * + * Authors: + * MenTaLguY + * + * Copyright (C) 2004 MenTaLguY + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifndef SEEN_INKSCAPE_LAYER_FNS_H +#define SEEN_INKSCAPE_LAYER_FNS_H + +class SPObject; + +namespace Inkscape { + +SPObject *create_layer(SPObject *root, SPObject *layer); + +SPObject *next_layer(SPObject *root, SPObject *layer); + +SPObject *previous_layer(SPObject *root, SPObject *layer); + +} + +#endif +/* + 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:textwidth=99 : diff --git a/src/libavoid/.cvsignore b/src/libavoid/.cvsignore new file mode 100644 index 000000000..38efca7bc --- /dev/null +++ b/src/libavoid/.cvsignore @@ -0,0 +1,3 @@ +.deps +.dirstamp +makefile diff --git a/src/libavoid/Makefile_insert b/src/libavoid/Makefile_insert new file mode 100644 index 000000000..146344813 --- /dev/null +++ b/src/libavoid/Makefile_insert @@ -0,0 +1,33 @@ +## Makefile.am fragment sourced by src/Makefile.am. + +libavoid/all: libavoid/libavoid.a + +libavoid/clean: + rm -f libavoid/libavoid.a $(libavoid_libavoid_a_OBJECTS) + +libavoid_libavoid_a_SOURCES = \ + libavoid/connector.cpp \ + libavoid/connector.h \ + libavoid/debug.h \ + libavoid/geometry.cpp \ + libavoid/geometry.h \ + libavoid/geomtypes.h \ + libavoid/graph.cpp \ + libavoid/graph.h \ + libavoid/incremental.cpp \ + libavoid/incremental.h \ + libavoid/makepath.cpp \ + libavoid/makepath.h \ + libavoid/polyutil.cpp \ + libavoid/polyutil.h \ + libavoid/shape.cpp \ + libavoid/shape.h \ + libavoid/static.cpp \ + libavoid/static.h \ + libavoid/timer.cpp \ + libavoid/timer.h \ + libavoid/vertices.cpp \ + libavoid/vertices.h \ + libavoid/visibility.cpp \ + libavoid/visibility.h \ + libavoid/libavoid.h diff --git a/src/libavoid/README b/src/libavoid/README new file mode 100644 index 000000000..ada0e9908 --- /dev/null +++ b/src/libavoid/README @@ -0,0 +1,5 @@ +This directory contains libavoid-0.1. It has been included here since it is +a new library without wide availablity. + +The project page is http://www.sourceforge.net/projects/libavoid/ +The library's maintainer is Michael Wybrow, an Inkscape developer. diff --git a/src/libavoid/connector.cpp b/src/libavoid/connector.cpp new file mode 100644 index 000000000..cde387c5b --- /dev/null +++ b/src/libavoid/connector.cpp @@ -0,0 +1,408 @@ +/* + * vim: ts=4 sw=4 et tw=0 wm=0 + * + * libavoid - Fast, Incremental, Object-avoiding Line Router + * Copyright (C) 2004-2005 Michael Wybrow + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * +*/ + +#include "libavoid/graph.h" +#include "libavoid/makepath.h" +#include "libavoid/visibility.h" +#include "libavoid/debug.h" + + +namespace Avoid { + + +ConnRefList connRefs; + + +ConnRef::ConnRef(const uint id) + : _id(id) + , _needs_reroute_flag(true) + , _false_path(false) + , _active(false) + , _route_dist(0) + , _srcVert(NULL) + , _dstVert(NULL) + , _initialised(false) + , _callback(NULL) + , _connector(NULL) +{ + // TODO: Store endpoints and details. + _route.pn = 0; + _route.ps = NULL; +} + + +ConnRef::ConnRef(const uint id, const Point& src, const Point& dst) + : _id(id) + , _needs_reroute_flag(true) + , _false_path(false) + , _active(false) + , _route_dist(0) + , _srcVert(NULL) + , _dstVert(NULL) + , _initialised(false) + , _callback(NULL) + , _connector(NULL) +{ + _route.pn = 0; + _route.ps = NULL; + + if (IncludeEndpoints) + { + bool isShape = false; + _srcVert = new VertInf(VertID(id, isShape, 1), src); + _dstVert = new VertInf(VertID(id, isShape, 2), dst); + vertices.addVertex(_srcVert); + vertices.addVertex(_dstVert); + makeActive(); + _initialised = true; + } +} + + +ConnRef::~ConnRef() +{ + freeRoute(); + + if (_srcVert) + { + vertices.removeVertex(_srcVert); + delete _srcVert; + _srcVert = NULL; + } + + if (_dstVert) + { + vertices.removeVertex(_dstVert); + delete _dstVert; + _dstVert = NULL; + } + + if (_active) + { + makeInactive(); + } +} + +void ConnRef::updateEndPoint(const uint type, const Point& point) +{ + assert((type == (uint) VertID::src) || (type == (uint) VertID::tar)); + //assert(IncludeEndpoints); + + VertInf *altered = NULL; + VertInf *partner = NULL; + bool isShape = false; + + if (type == (uint) VertID::src) + { + if (_srcVert) + { + _srcVert->Reset(point); + } + else + { + _srcVert = new VertInf(VertID(_id, isShape, type), point); + vertices.addVertex(_srcVert); + } + + altered = _srcVert; + partner = _dstVert; + } + else // if (type == (uint) VertID::dst) + { + if (_dstVert) + { + _dstVert->Reset(point); + } + else + { + _dstVert = new VertInf(VertID(_id, isShape, type), point); + vertices.addVertex(_dstVert); + } + + altered = _dstVert; + partner = _srcVert; + } + + bool knownNew = false; + vertexVisibility(altered, partner, knownNew, true); +} + + +void ConnRef::makeActive(void) +{ + assert(!_active); + + // Add to connRefs list. + _pos = connRefs.insert(connRefs.begin(), this); + _active = true; +} + + +void ConnRef::makeInactive(void) +{ + assert(_active); + + // Remove from connRefs list. + connRefs.erase(_pos); + _active = false; +} + + +void ConnRef::freeRoute(void) +{ + if (_route.ps) + { + _route.pn = 0; + std::free(_route.ps); + _route.ps = NULL; + } +} + + +PolyLine& ConnRef::route(void) +{ + return _route; +} + + +void ConnRef::calcRouteDist(void) +{ + _route_dist = 0; + for (int i = 1; i < _route.pn; i++) + { + _route_dist += dist(_route.ps[i], _route.ps[i - 1]); + } +} + + +bool ConnRef::needsReroute(void) +{ + return (_false_path || _needs_reroute_flag); +} + + +void ConnRef::moveRoute(const int& diff_x, const int& diff_y) +{ + for (int i = 0; i < _route.pn; i++) + { + _route.ps[i].x += diff_x; + _route.ps[i].y += diff_y; + } +} + + +void ConnRef::lateSetup(const Point& src, const Point& dst) +{ + assert(!_initialised); + + bool isShape = false; + _srcVert = new VertInf(VertID(_id, isShape, 1), src); + _dstVert = new VertInf(VertID(_id, isShape, 2), dst); + vertices.addVertex(_srcVert); + vertices.addVertex(_dstVert); + makeActive(); + _initialised = true; +} + + +VertInf *ConnRef::src(void) +{ + return _srcVert; +} + + +VertInf *ConnRef::dst(void) +{ + return _dstVert; +} + + +bool ConnRef::isInitialised(void) +{ + return _initialised; +} + + +void ConnRef::unInitialise(void) +{ + vertices.removeVertex(_srcVert); + vertices.removeVertex(_dstVert); + makeInactive(); + _initialised = false; +} + + +void ConnRef::removeFromGraph(void) +{ + for (VertInf *iter = _srcVert; iter != NULL; ) + { + VertInf *tmp = iter; + iter = (iter == _srcVert) ? _dstVert : NULL; + + // For each vertex. + EdgeInfList& visList = tmp->visList; + EdgeInfList::iterator finish = visList.end(); + EdgeInfList::iterator edge; + while ((edge = visList.begin()) != finish) + { + // Remove each visibility edge + delete (*edge); + } + + EdgeInfList& invisList = tmp->invisList; + finish = invisList.end(); + while ((edge = invisList.begin()) != finish) + { + // Remove each invisibility edge + delete (*edge); + } + } +} + + +void ConnRef::setCallback(void (*cb)(void *), void *ptr) +{ + _callback = cb; + _connector = ptr; +} + + +void ConnRef::handleInvalid(void) +{ + if (_false_path || _needs_reroute_flag) { + if (_callback) { + _callback(_connector); + } + } +} + + +void ConnRef::makePathInvalid(void) +{ + _needs_reroute_flag = true; +} + + +int ConnRef::generatePath(Point p0, Point p1) +{ + if (!_false_path && !_needs_reroute_flag) { + // This connector is up to date. + return (int) false; + } + + _false_path = false; + _needs_reroute_flag = false; + + VertInf *src = _srcVert; + VertInf *tar = _dstVert; + + if (!IncludeEndpoints) + { + lateSetup(p0, p1); + + // Update as they have just been set by lateSetup. + src = _srcVert; + tar = _dstVert; + + bool knownNew = true; + vertexVisibility(src, tar, knownNew); + vertexVisibility(tar, src, knownNew); + } + + bool *flag = &(_needs_reroute_flag); + + makePath(this, flag); + + bool result = true; + + int pathlen = 1; + for (VertInf *i = tar; i != src; i = i->pathNext) + { + pathlen++; + if (i == NULL) + { + db_printf("Warning: Path not found...\n"); + pathlen = 2; + tar->pathNext = src; + if (InvisibilityGrph) + { + // TODO: Could we know this edge already? + EdgeInf *edge = EdgeInf::existingEdge(src, tar); + assert(edge != NULL); + edge->addCycleBlocker(); + } + result = false; + break; + } + if (pathlen > 100) + { + fprintf(stderr, "ERROR: Should never be here...\n"); + exit(1); + } + } + Point *path = (Point *) malloc(pathlen * sizeof(Point)); + + int j = pathlen - 1; + for (VertInf *i = tar; i != src; i = i->pathNext) + { + if (InvisibilityGrph) + { + // TODO: Again, we could know this edge without searching. + EdgeInf *edge = EdgeInf::existingEdge(i, i->pathNext); + edge->addConn(flag); + } + else + { + _false_path = true; + } + path[j--] = i->point; + } + path[0] = src->point; + + + // Would clear visibility for endpoints here if required. + + PolyLine& output_route = route(); + output_route.pn = pathlen; + output_route.ps = path; + + return (int) result; +} + + +//============================================================================ + + + // It's intended this function is called after shape movement has + // happened to alert connectors that they need to be rerouted. +void callbackAllInvalidConnectors(void) +{ + ConnRefList::iterator fin = connRefs.end(); + for (ConnRefList::iterator i = connRefs.begin(); i != fin; ++i) { + (*i)->handleInvalid(); + } +} + + +} + + diff --git a/src/libavoid/connector.h b/src/libavoid/connector.h new file mode 100644 index 000000000..6abb01d49 --- /dev/null +++ b/src/libavoid/connector.h @@ -0,0 +1,93 @@ +/* + * vim: ts=4 sw=4 et tw=0 wm=0 + * + * libavoid - Fast, Incremental, Object-avoiding Line Router + * Copyright (C) 2004-2005 Michael Wybrow + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * +*/ + +#ifndef AVOID_CONNECTOR_H +#define AVOID_CONNECTOR_H + +#include "libavoid/geometry.h" +#include "libavoid/shape.h" +#include + + +namespace Avoid { + +typedef unsigned int uint; + +class ConnRef; + +typedef std::list ConnRefList; + + +class ConnRef +{ + public: + ConnRef(const uint id); + ConnRef(const uint id, const Point& src, const Point& dst); + ~ConnRef(); + + PolyLine& route(void); + bool needsReroute(void); + void moveRoute(const int& diff_x, const int& diff_y); + void freeRoute(void); + void calcRouteDist(void); + void updateEndPoint(const uint type, const Point& point); + void makeActive(void); + void makeInactive(void); + void lateSetup(const Point& src, const Point& dst); + VertInf *src(void); + VertInf *dst(void); + void removeFromGraph(void); + bool isInitialised(void); + void unInitialise(void); + void setCallback(void (*cb)(void *), void *ptr); + void handleInvalid(void); + int generatePath(Point p0, Point p1); + void makePathInvalid(void); + + friend void markConnectors(ShapeRef *shape); + + private: + uint _id; + bool _needs_reroute_flag; + bool _false_path; + bool _active; + PolyLine _route; + double _route_dist; + ConnRefList::iterator _pos; + VertInf *_srcVert; + VertInf *_dstVert; + bool _initialised; + void (*_callback)(void *); + void *_connector; +}; + + +extern ConnRefList connRefs; + +extern void callbackAllInvalidConnectors(void); + +} + + +#endif + + diff --git a/src/libavoid/debug.h b/src/libavoid/debug.h new file mode 100644 index 000000000..0b182d442 --- /dev/null +++ b/src/libavoid/debug.h @@ -0,0 +1,61 @@ +/* + * vim: ts=4 sw=4 et tw=0 wm=0 + * + * libavoid - Fast, Incremental, Object-avoiding Line Router + * Copyright (C) 2004-2005 Michael Wybrow + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * +*/ + +#ifndef AVOID_DEBUG_H +#define AVOID_DEBUG_H + + + +#ifndef NDEBUG + //#define DBPRINTF_DEBUG +#endif + + +#ifdef DBPRINTF_DEBUG + +#include +#include + +#endif + +namespace Avoid { + +#ifdef DBPRINTF_DEBUG +inline void db_printf(const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + vfprintf(stdout, fmt, ap); + va_end(ap); +} +#else +inline void db_printf(const char *fmt, ...) +{ +} +#endif + +} + + +#endif + + diff --git a/src/libavoid/geometry.cpp b/src/libavoid/geometry.cpp new file mode 100644 index 000000000..d720693ac --- /dev/null +++ b/src/libavoid/geometry.cpp @@ -0,0 +1,260 @@ +/* + * vim: ts=4 sw=4 et tw=0 wm=0 + * + * libavoid - Fast, Incremental, Object-avoiding Line Router + * Copyright (C) 2004-2005 Michael Wybrow + * + * -------------------------------------------------------------------- + * Much of the code in this module is based on code published with + * and/or described in "Computational Geometry in C" (Second Edition), + * Copyright (C) 1998 Joseph O'Rourke + * -------------------------------------------------------------------- + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * +*/ + +#include "libavoid/graph.h" +#include "libavoid/polyutil.h" + +#include + +namespace Avoid { + + +// Returns true iff the point c lies on the closed segment ab. +// +// Based on the code of 'Between'. +// +static const bool inBetween(const Point& a, const Point& b, const Point& c) +{ + // We only call this when we know the points are collinear, + // otherwise we should be checking this here. + assert(vecDir(a, b, c) == 0); + + if (a.x != b.x) + { + // not vertical + return (((a.x < c.x) && (c.x < b.x)) || + ((b.x < c.x) && (c.x < a.x))); + } + else + { + return (((a.y < c.y) && (c.y < b.y)) || + ((b.y < c.y) && (c.y < a.y))); + } +} + + +// Returns true if the segment cd intersects the segment ab, blocking +// visibility. +// +// Based on the code of 'IntersectProp' and 'Intersect'. +// +bool segmentIntersect(const Point& a, const Point& b, const Point& c, + const Point& d) +{ + int ab_c = vecDir(a, b, c); + if ((ab_c == 0) && inBetween(a, b, c)) + { + return true; + } + + int ab_d = vecDir(a, b, d); + if ((ab_d == 0) && inBetween(a, b, d)) + { + return true; + } + + // It's ok for either of the points a or b to be on the line cd, + // so we don't have to check the other two cases. + + int cd_a = vecDir(c, d, a); + int cd_b = vecDir(c, d, b); + + // Is an intersection if a and b are on opposite sides of cd, + // and c and d are on opposite sides of the line ab. + // + // Note: this is safe even though the textbook warns about it + // since, unlike them, out vecDir is equivilent to 'AreaSign' + // rather than 'Area2'. + return (((ab_c * ab_d) < 0) && ((cd_a * cd_b) < 0)); +} + + +// Returns true iff the point p in a valid region that can contain +// shortest paths. a0, a1, a2 are ordered vertices of a shape. +// This function may seem 'backwards' to the user due to some of +// the code being reversed due to screen cooridinated being the +// opposite of graph paper coords. +// TODO: Rewrite this after checking whether it works for Inkscape. +// +// Based on the code of 'InCone'. +// +bool inValidRegion(const Point& a0, const Point& a1, const Point& a2, + const Point& b) +{ + int rSide = vecDir(b, a0, a1); + int sSide = vecDir(b, a1, a2); + + bool rOutOn = (rSide >= 0); + bool sOutOn = (sSide >= 0); + + bool rOut = (rSide > 0); + bool sOut = (sSide > 0); + + if (vecDir(a0, a1, a2) > 0) + { + // Concave at a1: + // + // !rO rO + // !sO !sO + // + // +---s--- + // | + // !rO r rO + // sO | sO + // + // + return (IgnoreRegions ? false : (rOutOn && sOutOn)); + } + else + { + // Convex at a1: + // + // !rO rO + // sO sO + // + // ---s---+ + // | + // !rO r rO + // !sO | !sO + // + // + if (IgnoreRegions) + { + return (rOutOn && !sOut) || (!rOut && sOutOn); + } + return (rOutOn || sOutOn); + } +} + + +// Returns the distance between points a and b. +// +double dist(const Point& a, const Point& b) +{ + double xdiff = a.x - b.x; + double ydiff = a.y - b.y; + + return sqrt((xdiff * xdiff) + (ydiff * ydiff)); +} + + +// Returns true iff the point q is inside (or on the edge of) the +// polygon argpoly. +// +// Based on the code of 'InPoly'. +// +bool inPoly(const Polygn& argpoly, const Point& q) +{ + // Numbers of right and left edge/ray crossings. + int Rcross = 0; + int Lcross = 0; + + // Copy the argument polygon + Polygn poly = copyPoly(argpoly); + Point *P = poly.ps; + int n = poly.pn; + + // Shift so that q is the origin. This is done for pedogical clarity. + for (int i = 0; i < n; ++i) + { + P[i].x = P[i].x - q.x; + P[i].y = P[i].y - q.y; + } + + // For each edge e=(i-1,i), see if crosses ray. + for (int i = 0; i < n; ++i) + { + // First see if q=(0,0) is a vertex. + if ((P[i].x == 0) && (P[i].y == 0)) + { + // We count a vertex as inside. + freePoly(poly); + return true; + } + + // point index; i1 = i-1 mod n + int i1 = ( i + n - 1 ) % n; + + // if e "straddles" the x-axis... + // The commented-out statement is logically equivalent to the one + // following. + // if( ((P[i].y > 0) && (P[i1].y <= 0)) || + // ((P[i1].y > 0) && (P[i].y <= 0)) ) + + if ((P[i].y > 0) != (P[i1].y > 0)) + { + // e straddles ray, so compute intersection with ray. + double x = (P[i].x * P[i1].y - P[i1].x * P[i].y) + / (P[i1].y - P[i].y); + + // crosses ray if strictly positive intersection. + if (x > 0) + { + Rcross++; + } + } + + // if e straddles the x-axis when reversed... + // if( ((P[i].y < 0) && (P[i1].y >= 0)) || + // ((P[i1].y < 0) && (P[i].y >= 0)) ) + + if ((P[i].y < 0) != (P[i1].y < 0)) + { + // e straddles ray, so compute intersection with ray. + double x = (P[i].x * P[i1].y - P[i1].x * P[i].y) + / (P[i1].y - P[i].y); + + // crosses ray if strictly positive intersection. + if (x < 0) + { + Lcross++; + } + } + } + freePoly(poly); + + // q on the edge if left and right cross are not the same parity. + if ( (Rcross % 2) != (Lcross % 2) ) + { + // We count the edge as inside. + return true; + } + + // Inside iff an odd number of crossings. + if ((Rcross % 2) == 1) + { + return true; + } + + // Outside. + return false; +} + + +} + diff --git a/src/libavoid/geometry.h b/src/libavoid/geometry.h new file mode 100644 index 000000000..500da6273 --- /dev/null +++ b/src/libavoid/geometry.h @@ -0,0 +1,75 @@ +/* + * vim: ts=4 sw=4 et tw=0 wm=0 + * + * libavoid - Fast, Incremental, Object-avoiding Line Router + * Copyright (C) 2004-2005 Michael Wybrow + * + * -------------------------------------------------------------------- + * Much of the code in this module is based on code published with + * and/or described in "Computational Geometry in C" (Second Edition), + * Copyright (C) 1998 Joseph O'Rourke + * -------------------------------------------------------------------- + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * +*/ + + +#ifndef _GEOMETRY_H +#define _GEOMETRY_H + +#include "libavoid/geomtypes.h" + +namespace Avoid { + + +extern double dist(const Point& a, const Point& b); +extern bool segmentIntersect(const Point& a, const Point& b, + const Point& c, const Point& d); +extern bool inPoly(const Polygn& poly, const Point& q); +extern bool inValidRegion(const Point& a0, const Point& a1, const Point& a2, + const Point& b); + + +// Direction from vector. +// Looks at the position of point c from the directed segment ab and +// returns the following: +// 1 counterclockwise +// 0 collinear +// -1 clockwise +// +// Based on the code of 'AreaSign'. +// +static inline int vecDir(const Point& a, const Point& b, const Point& c) +{ + double area2 = ((b.x - a.x) * (c.y - a.y)) - + ((c.x - a.x) * (b.y - a.y)); + + if (area2 < -0.001) + { + return -1; + } + else if (area2 > 0.001) + { + return 1; + } + return 0; +} + + +} + + +#endif diff --git a/src/libavoid/geomtypes.h b/src/libavoid/geomtypes.h new file mode 100644 index 000000000..9b682759a --- /dev/null +++ b/src/libavoid/geomtypes.h @@ -0,0 +1,61 @@ +/* + * vim: ts=4 sw=4 et tw=0 wm=0 + * + * libavoid - Fast, Incremental, Object-avoiding Line Router + * Copyright (C) 2004-2005 Michael Wybrow + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * +*/ + + +#ifndef AVOID_GEOMTYPES_H +#define AVOID_GEOMTYPES_H + + +namespace Avoid +{ + + +typedef struct +{ + double x; + double y; +} Point; + + +typedef Point Vector; + + +typedef struct +{ + int id; + Point *ps; + int pn; +} Polygn; + +typedef Polygn PolyLine; + + +typedef struct +{ + Point a; + Point b; +} Edge; + + +} + +#endif diff --git a/src/libavoid/graph.cpp b/src/libavoid/graph.cpp new file mode 100644 index 000000000..9b1d602be --- /dev/null +++ b/src/libavoid/graph.cpp @@ -0,0 +1,986 @@ +/* + * vim: ts=4 sw=4 et tw=0 wm=0 + * + * libavoid - Fast, Incremental, Object-avoiding Line Router + * Copyright (C) 2004-2005 Michael Wybrow + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * +*/ + +#include "libavoid/debug.h" +#include "libavoid/graph.h" +#include "libavoid/connector.h" +#include "libavoid/polyutil.h" +#include "libavoid/timer.h" + +#include + +namespace Avoid { + + +static int st_checked_edges = 0; + +EdgeList visGraph; +EdgeList invisGraph; + + +EdgeInf::EdgeInf(VertInf *v1, VertInf *v2) + : lstPrev(NULL) + , lstNext(NULL) + , _added(false) + , _visible(false) + , _v1(v1) + , _v2(v2) + , _dist(-1) +{ + _blockers.clear(); + _conns.clear(); +} + + +EdgeInf::~EdgeInf() +{ + if (_added) + { + makeInactive(); + } +} + + +void EdgeInf::makeActive(void) +{ + assert(_added == false); + + if (_visible) + { + visGraph.addEdge(this); + _pos1 = _v1->visList.insert(_v1->visList.begin(), this); + _v1->visListSize++; + _pos2 = _v2->visList.insert(_v2->visList.begin(), this); + _v2->visListSize++; + } + else // if (invisible) + { + invisGraph.addEdge(this); + _pos1 = _v1->invisList.insert(_v1->invisList.begin(), this); + _v1->invisListSize++; + _pos2 = _v2->invisList.insert(_v2->invisList.begin(), this); + _v2->invisListSize++; + } + _added = true; +} + + +void EdgeInf::makeInactive(void) +{ + assert(_added == true); + + if (_visible) + { + visGraph.removeEdge(this); + _v1->visList.erase(_pos1); + _v1->visListSize--; + _v2->visList.erase(_pos2); + _v2->visListSize--; + } + else // if (invisible) + { + invisGraph.removeEdge(this); + _v1->invisList.erase(_pos1); + _v1->invisListSize--; + _v2->invisList.erase(_pos2); + _v2->invisListSize--; + } + _blockers.clear(); + _conns.clear(); + _added = false; +} + + +double EdgeInf::getDist(void) +{ + return _dist; +} + + +void EdgeInf::setDist(double dist) +{ + //assert(dist != 0); + + if (_added && !_visible) + { + makeInactive(); + } + if (!_added) + { + _visible = true; + makeActive(); + } + _dist = dist; + _blockers.clear(); +} + + +void EdgeInf::alertConns(void) +{ + for (FlagList::iterator i = _conns.begin(); i != _conns.end(); ++i) + { + *(*i) = true; + } + _conns.clear(); +} + + +void EdgeInf::addConn(bool *flag) +{ + _conns.push_back(flag); +} + + +void EdgeInf::addCycleBlocker(void) +{ + // Needs to be in invisibility graph. + addBlocker(-1); +} + + +void EdgeInf::addBlocker(int b) +{ + assert(InvisibilityGrph); + + if (_added && _visible) + { + makeInactive(); + } + if (!_added) + { + _visible = false; + makeActive(); + } + _dist = 0; + _blockers.clear(); + _blockers.push_back(b); +} + + +bool EdgeInf::hasBlocker(int b) +{ + assert(InvisibilityGrph); + + ShapeList::iterator finish = _blockers.end(); + for (ShapeList::iterator it = _blockers.begin(); it != finish; ++it) + { + if ((*it) == -1) + { + alertConns(); + return true; + } + else if ((*it) == b) + { + return true; + } + } + return false; +} + + +pair EdgeInf::ids(void) +{ + return std::make_pair(_v1->id, _v2->id); +} + + +pair EdgeInf::points(void) +{ + return std::make_pair(_v1->point, _v2->point); +} + + +void EdgeInf::db_print(void) +{ + db_printf("Edge("); + _v1->id.db_print(); + db_printf(","); + _v2->id.db_print(); + db_printf(")\n"); +} + + +void EdgeInf::checkVis(void) +{ + if (_added && !_visible) + { + db_printf("\tChecking visibility for existing invisibility edge..." + "\n\t\t"); + db_print(); + } + else if (_added && _visible) + { + db_printf("\tChecking visibility for existing visibility edge..." + "\n\t\t"); + db_print(); + } + + int blocker = 0; + bool cone1 = true; + bool cone2 = true; + + VertInf *i = _v1; + VertInf *j = _v2; + const VertID& iID = i->id; + const VertID& jID = j->id; + const Point& iPoint = i->point; + const Point& jPoint = j->point; + + st_checked_edges++; + + if (iID.isShape) + { + cone1 = inValidRegion(i->shPrev->point, iPoint, i->shNext->point, + jPoint); + } + else + { + ShapeSet& ss = contains[iID]; + + if ((jID.isShape) && (ss.find(jID.objID) != ss.end())) + { + db_printf("1: Edge of bounding shape\n"); + // Don't even check this edge, it should be zero, + // since a point in a shape can't see it's corners + cone1 = false; + } + } + + if (cone1) + { + // If outside the first cone, don't even bother checking. + if (jID.isShape) + { + cone2 = inValidRegion(j->shPrev->point, jPoint, j->shNext->point, + iPoint); + } + else + { + ShapeSet& ss = contains[jID]; + + if ((iID.isShape) && (ss.find(iID.objID) != ss.end())) + { + db_printf("2: Edge of bounding shape\n"); + // Don't even check this edge, it should be zero, + // since a point in a shape can't see it's corners + cone2 = false; + } + } + } + + if (cone1 && cone2 && ((blocker = firstBlocker()) == 0)) + { + + // if i and j see each other, add edge + db_printf("\tSetting visibility edge... \n\t\t"); + db_print(); + + double d = dist(iPoint, jPoint); + + setDist(d); + + } + else if (InvisibilityGrph) + { +#if 0 + db_printf("%d, %d, %d\n", cone1, cone2, blocker); + db_printf("\t(%d, %d)--(%d, %d)\n", (int) iInfo.point.x, + (int) iInfo.point.y, (int) jInfo.point.x, + (int) jInfo.point.y); +#endif + + // if i and j can't see each other, add blank edge + db_printf("\tSetting invisibility edge... \n\t\t"); + db_print(); + addBlocker(blocker); + } +} + + +int EdgeInf::firstBlocker(void) +{ + ShapeSet ss = ShapeSet(); + + Point& pti = _v1->point; + Point& ptj = _v2->point; + VertID& iID = _v1->id; + VertID& jID = _v2->id; + + if (!(iID.isShape)) + { + ss.insert(contains[iID].begin(), contains[iID].end()); + } + if (!(jID.isShape)) + { + ss.insert(contains[jID].begin(), contains[jID].end()); + } + + VertInf *last = vertices.end(); + for (VertInf *k = vertices.shapesBegin(); k != last; ) + { + VertID kID = k->id; + if ((ss.find(kID.objID) != ss.end())) + { + uint shapeID = kID.objID; + db_printf("Endpoint is inside shape %u so ignore shape edges.\n", + kID.objID); + // One of the endpoints is inside this shape so ignore it. + while ((k != last) && (k->id.objID == shapeID)) + { + // And skip the other vertices from this shape. + k = k->lstNext; + } + continue; + } + Point& kPoint = k->point; + Point& kPrevPoint = k->shPrev->point; + + if (segmentIntersect(pti, ptj, kPrevPoint, kPoint)) + { + ss.clear(); + return kID.objID; + } + k = k->lstNext; + } + ss.clear(); + return 0; +} + + +bool EdgeInf::isBetween(VertInf *i, VertInf *j) +{ + if ( ((i == _v1) && (j == _v2)) || + ((i == _v2) && (j == _v1)) ) + { + return true; + } + return false; +} + + +VertInf *EdgeInf::otherVert(VertInf *vert) +{ + assert((vert == _v1) || (vert == _v2)); + + if (vert == _v1) + { + return _v2; + } + return _v1; +} + + +EdgeInf *EdgeInf::checkEdgeVisibility(VertInf *i, VertInf *j, bool knownNew) +{ + EdgeInf *edge = NULL; + + if (knownNew) + { + assert(existingEdge(i, j) == NULL); + edge = new EdgeInf(i, j); + } + else + { + edge = existingEdge(i, j); + if (edge == NULL) + { + edge = new EdgeInf(i, j); + } + } + edge->checkVis(); + if (!(edge->_added) && !InvisibilityGrph) + { + delete edge; + edge = NULL; + } + + return edge; +} + + +EdgeInf *EdgeInf::existingEdge(VertInf *i, VertInf *j) +{ + VertInf *selected = NULL; + + if (i->visListSize <= j->visListSize) + { + selected = i; + } + else + { + selected = j; + } + + EdgeInfList& visList = selected->visList; + EdgeInfList::iterator finish = visList.end(); + for (EdgeInfList::iterator edge = visList.begin(); edge != finish; + ++edge) + { + if ((*edge)->isBetween(i, j)) + { + return (*edge); + } + } + + if (i->invisListSize <= j->invisListSize) + { + selected = i; + } + else + { + selected = j; + } + + EdgeInfList& invisList = selected->invisList; + finish = invisList.end(); + for (EdgeInfList::iterator edge = invisList.begin(); edge != finish; + ++edge) + { + if ((*edge)->isBetween(i, j)) + { + return (*edge); + } + } + + return NULL; +} + + +//=========================================================================== + + +EdgeList::EdgeList() + : _firstEdge(NULL) + , _lastEdge(NULL) + , _count(0) +{ +} + + +void EdgeList::addEdge(EdgeInf *edge) +{ + if (_firstEdge == NULL) + { + assert(_lastEdge == NULL); + + _lastEdge = edge; + _firstEdge = edge; + + edge->lstPrev = NULL; + edge->lstNext = NULL; + } + else + { + assert(_lastEdge != NULL); + + _lastEdge->lstNext = edge; + edge->lstPrev = _lastEdge; + + _lastEdge = edge; + + edge->lstNext = NULL; + } + _count++; +} + + +void EdgeList::removeEdge(EdgeInf *edge) +{ + if (edge->lstPrev) + { + edge->lstPrev->lstNext = edge->lstNext; + } + if (edge->lstNext) + { + edge->lstNext->lstPrev = edge->lstPrev; + } + if (edge == _lastEdge) + { + _lastEdge = edge->lstPrev; + if (edge == _firstEdge) + { + _firstEdge = NULL; + } + } + else if (edge == _firstEdge) + { + _firstEdge = edge->lstNext; + } + + + edge->lstPrev = NULL; + edge->lstNext = NULL; + + _count--; +} + + +EdgeInf *EdgeList::begin(void) +{ + return _firstEdge; +} + + +EdgeInf *EdgeList::end(void) +{ + return NULL; +} + + +// General visibility graph utility functions + + +void newBlockingShape(Polygn *poly, int pid) +{ + // o Check all visibility edges to see if this one shape + // blocks them. + EdgeInf *finish = visGraph.end(); + for (EdgeInf *iter = visGraph.begin(); iter != finish ; ) + { + EdgeInf *tmp = iter; + iter = iter->lstNext; + + if (tmp->getDist() != 0) + { + pair ids(tmp->ids()); + VertID eID1 = ids.first; + VertID eID2 = ids.second; + pair points(tmp->points()); + Point e1 = points.first; + Point e2 = points.second; + bool blocked = false; + + bool ep_in_poly1 = !(eID1.isShape) ? inPoly(*poly, e1) : false; + bool ep_in_poly2 = !(eID2.isShape) ? inPoly(*poly, e2) : false; + if (ep_in_poly1 || ep_in_poly2) + { + // Don't check edges that have a connector endpoint + // and are inside the shape being added. + continue; + } + + for (int pt_i = 0; pt_i < poly->pn; pt_i++) + { + int pt_n = (pt_i == (poly->pn - 1)) ? 0 : pt_i + 1; + if (segmentIntersect(e1, e2, poly->ps[pt_i], poly->ps[pt_n])) + { + blocked = true; + break; + } + } + if (blocked) + { + db_printf("\tRemoving newly blocked edge (by shape %3d)" + "... \n\t\t", pid); + tmp->alertConns(); + tmp->db_print(); + if (InvisibilityGrph) + { + tmp->addBlocker(pid); + } + else + { + delete tmp; + } + } + } + } +} + + +void checkAllBlockedEdges(int pid) +{ + assert(InvisibilityGrph); + + for (EdgeInf *iter = invisGraph.begin(); iter != invisGraph.end() ; ) + { + EdgeInf *tmp = iter; + iter = iter->lstNext; + + if (tmp->hasBlocker(pid)) + { + tmp->checkVis(); + } + } +} + + +void checkAllMissingEdges(void) +{ + assert(!InvisibilityGrph); + + VertInf *first = NULL; + + if (IncludeEndpoints) + { + first = vertices.connsBegin(); + } + else + { + first = vertices.shapesBegin(); + } + + VertInf *pend = vertices.end(); + for (VertInf *i = first; i != pend; i = i->lstNext) + { + VertID iID = i->id; + + // Check remaining, earlier vertices + for (VertInf *j = first ; j != i; j = j->lstNext) + { + VertID jID = j->id; + if (!(iID.isShape) && (iID.objID != jID.objID)) + { + // Don't keep visibility between edges of different conns + continue; + } + + // See if the edge is already there? + bool found = (EdgeInf::existingEdge(i, j) != NULL); + + if (!found) + { + // Didn't already exist, check. + bool knownNew = true; + EdgeInf::checkEdgeVisibility(i, j, knownNew); + } + } + } +} + + +void generateContains(VertInf *pt) +{ + contains[pt->id].clear(); + + ShapeRefList::iterator finish = shapeRefs.end(); + for (ShapeRefList::iterator i = shapeRefs.begin(); i != finish; ++i) + { + Polygn poly = copyPoly(*i); + if (inPoly(poly, pt->point)) + { + contains[pt->id].insert((*i)->id()); + } + freePoly(poly); + } +} + + +void adjustContainsWithAdd(const Polygn& poly, const int p_shape) +{ + for (VertInf *k = vertices.connsBegin(); k != vertices.shapesBegin(); + k = k->lstNext) + { + if (inPoly(poly, k->point)) + { + contains[k->id].insert(p_shape); + } + } +} + + +void adjustContainsWithDel(const int p_shape) +{ + for (VertInf *k = vertices.connsBegin(); k != vertices.shapesBegin(); + k = k->lstNext) + { + contains[k->id].erase(p_shape); + } +} + + +// Maybe this one should be in with the connector stuff, but it may later +// need to operate on a particular section of the visibility graph so it +// may have to stay here. +// +#define MIN(a, b) (((a) <= (b)) ? (a) : (b)) +#define MAX(a, b) (((a) >= (b)) ? (a) : (b)) + +#ifdef SELECTIVE_DEBUG +static double AngleAFromThreeSides(const double a, const double b, + const double c) +{ + // returns angle A, the angle opposite from side a, in radians + return acos((pow(b, 2) + pow(c, 2) - pow(a, 2)) / (2 * b * c)); +} +#endif + +void markConnectors(ShapeRef *shape) +{ + assert(SelectiveReroute); + + ConnRefList::iterator end = connRefs.end(); + for (ConnRefList::iterator it = connRefs.begin(); it != end; ++it) + { + ConnRef *conn = (*it); + + if (conn->_route.pn == 0) + { + // Ignore uninitialised connectors. + continue; + } + + Point start = conn->_route.ps[0]; + Point end = conn->_route.ps[conn->_route.pn - 1]; + + double conndist = conn->_route_dist; + + double estdist; + double e1, e2; + + VertInf *beginV = shape->firstVert(); + VertInf *endV = shape->lastVert()->lstNext; + for (VertInf *i = beginV; i != endV; i = i->lstNext) + { + const Point& p1 = i->point; + const Point& p2 = i->shNext->point; + + double offy; + double a; + double b; + double c; + double d; + + double min; + double max; + + if (p1.y == p2.y) + { + // Standard case + offy = p1.y; + a = start.x; + b = start.y - offy; + c = end.x; + d = end.y - offy; + + min = MIN(p1.x, p2.x); + max = MAX(p1.x, p2.x); + } + else if (p1.x == p2.x) + { + // Other Standard case + offy = p1.x; + a = start.y; + b = start.x - offy; + c = end.y; + d = end.x - offy; + + min = MIN(p1.y, p2.y); + max = MAX(p1.y, p2.y); + } + else + { + // Need to do rotation + Point n_p2 = { p2.x - p1.x, p2.y - p1.y }; + Point n_start = { start.x - p1.x, start.y - p1.y }; + Point n_end = { end.x - p1.x, end.y - p1.y }; + //printf("n_p2: (%.1f, %.1f)\n", n_p2.x, n_p2.y); + //printf("n_start: (%.1f, %.1f)\n", n_start.x, n_start.y); + //printf("n_end: (%.1f, %.1f)\n", n_end.x, n_end.y); + + double theta = 0 - atan2(n_p2.y, n_p2.x); + //printf("theta = %.2f\n", theta * (180 / PI)); + + Point r_p1 = {0, 0}; + Point r_p2 = n_p2; + start = n_start; + end = n_end; + + double cosv = cos(theta); + double sinv = sin(theta); + + r_p2.x = cosv * n_p2.x - sinv * n_p2.y; + r_p2.y = cosv * n_p2.y + sinv * n_p2.x; + start.x = cosv * n_start.x - sinv * n_start.y; + start.y = cosv * n_start.y + sinv * n_start.x; + end.x = cosv * n_end.x - sinv * n_end.y; + end.y = cosv * n_end.y + sinv * n_end.x; + //printf("r_p2: (%.1f, %.1f)\n", r_p2.x, r_p2.y); + //printf("r_start: (%.1f, %.1f)\n", start.x, start.y); + //printf("r_end: (%.1f, %.1f)\n", end.x, end.y); + + if (((int) r_p2.y) != 0) + { + printf("r_p2.y: %f != 0\n", r_p2.y); + abort(); + } + // This might be slightly off. + r_p2.y = 0; + + offy = r_p1.y; + a = start.x; + b = start.y - offy; + c = end.x; + d = end.y - offy; + + min = MIN(r_p1.x, r_p2.x); + max = MAX(r_p1.x, r_p2.x); + + } + + double x; + if ((b + d) == 0) + { + db_printf("WARNING: (b + d) == 0\n"); + d = d * -1; + } + + if ((b == 0) && (d == 0)) + { + db_printf("WARNING: b == d == 0\n"); + if (((a < min) && (c < min)) || + ((a > max) && (c > max))) + { + // It's going to get adjusted. + x = a; + } + else + { + continue; + } + } + else + { + x = ((b*c) + (a*d)) / (b + d); + } + + //printf("%.1f, %.1f, %.1f, %.1f\n", a, b, c, d); + //printf("x = %.1f\n", x); + + // XXX: Use MAX and MIN + x = (x < min) ? min : x; + x = (x > max) ? max : x; + + //printf("x = %.1f\n", x); + + Point xp; + if (p1.x == p2.x) + { + xp.x = offy; + xp.y = x; + } + else + { + xp.x = x; + xp.y = offy; + } + //printf("(%.1f, %.1f)\n", xp.x, xp.y); + + e1 = dist(start, xp); + e2 = dist(xp, end); + estdist = e1 + e2; + + + //printf("is %.1f < %.1f\n", estdist, conndist); + if (estdist < conndist) + { +#ifdef SELECTIVE_DEBUG + //double angle = AngleAFromThreeSides(dist(start, end), + // e1, e2); + printf("[%3d] - Possible better path found (%.1f < %.1f)\n", + conn->_id, estdist, conndist); +#endif + conn->_needs_reroute_flag = true; + break; + } + + } + } +} + + +void printInfo(void) +{ + FILE *fp = stdout; + fprintf(fp, "\nVisibility Graph info:\n"); + fprintf(fp, "----------------------\n"); + + uint currshape = 0; + int st_shapes = 0; + int st_vertices = 0; + int st_endpoints = 0; + int st_valid_shape_visedges = 0; + int st_valid_endpt_visedges = 0; + int st_invalid_visedges = 0; + VertInf *finish = vertices.end(); + for (VertInf *t = vertices.connsBegin(); t != finish; t = t->lstNext) + { + VertID pID = t->id; + + if ((pID.isShape) && (pID.objID != currshape)) + { + currshape = pID.objID; + st_shapes++; + } + if (pID.isShape) + { + st_vertices++; + } + else + { + // The shape 0 ones are temporary and not considered. + st_endpoints++; + } + } + for (EdgeInf *t = visGraph.begin(); t != visGraph.end(); + t = t->lstNext) + { + std::pair idpair = t->ids(); + + if (!(idpair.first.isShape) || !(idpair.second.isShape)) + { + st_valid_endpt_visedges++; + } + else + { + st_valid_shape_visedges++; + } + } + for (EdgeInf *t = invisGraph.begin(); t != invisGraph.end(); + t = t->lstNext) + { + st_invalid_visedges++; + } + fprintf(fp, "Number of shapes: %d\n", st_shapes); + fprintf(fp, "Number of vertices: %d (%d real, %d endpoints)\n", + st_vertices + st_endpoints, st_vertices, st_endpoints); + fprintf(fp, "Number of vis_edges: %d (%d valid [%d normal, %d endpt], " + "%d invalid)\n", st_valid_shape_visedges + st_invalid_visedges + + st_valid_endpt_visedges, st_valid_shape_visedges + + st_valid_endpt_visedges, st_valid_shape_visedges, + st_valid_endpt_visedges, st_invalid_visedges); + fprintf(fp, "----------------------\n"); + fprintf(fp, "checkVisEdge tally: %d\n", st_checked_edges); + fprintf(fp, "----------------------\n"); + + fprintf(fp, "ADDS: "); timers.Print(tmAdd); + fprintf(fp, "DELS: "); timers.Print(tmDel); + fprintf(fp, "MOVS: "); timers.Print(tmMov); + fprintf(fp, "***S: "); timers.Print(tmSev); + fprintf(fp, "PTHS: "); timers.Print(tmPth); + fprintf(fp, "\n"); +} + + +} + + diff --git a/src/libavoid/graph.h b/src/libavoid/graph.h new file mode 100644 index 000000000..d30f394cf --- /dev/null +++ b/src/libavoid/graph.h @@ -0,0 +1,127 @@ +/* + * vim: ts=4 sw=4 et tw=0 wm=0 + * + * libavoid - Fast, Incremental, Object-avoiding Line Router + * Copyright (C) 2004-2005 Michael Wybrow + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * +*/ + +#ifndef AVOID_GRAPH_H +#define AVOID_GRAPH_H + + +#include +#include +#include +using std::pair; + +#include "libavoid/vertices.h" + + +namespace Avoid { + + +extern bool UseAStarSearch; +extern bool IgnoreRegions; +extern bool SelectiveReroute; +extern bool IncludeEndpoints; +extern bool UseLeesAlgorithm; +extern bool InvisibilityGrph; +extern bool PartialFeedback; + + +typedef std::list ShapeList; +typedef std::list FlagList; + + +class EdgeInf +{ + public: + EdgeInf(VertInf *v1, VertInf *v2); + ~EdgeInf(); + double getDist(void); + void setDist(double dist); + void alertConns(void); + void addConn(bool *flag); + void addCycleBlocker(void); + void addBlocker(int b); + bool hasBlocker(int b); + pair ids(void); + pair points(void); + void db_print(void); + void checkVis(void); + VertInf *otherVert(VertInf *vert); + static EdgeInf *checkEdgeVisibility(VertInf *i, VertInf *j, + bool knownNew = false); + static EdgeInf *existingEdge(VertInf *i, VertInf *j); + + EdgeInf *lstPrev; + EdgeInf *lstNext; + private: + bool _added; + bool _visible; + VertInf *_v1; + VertInf *_v2; + EdgeInfList::iterator _pos1; + EdgeInfList::iterator _pos2; + ShapeList _blockers; + FlagList _conns; + double _dist; + + void makeActive(void); + void makeInactive(void); + int firstBlocker(void); + bool isBetween(VertInf *i, VertInf *j); +}; + + +class EdgeList +{ + public: + EdgeList(); + void addEdge(EdgeInf *edge); + void removeEdge(EdgeInf *edge); + EdgeInf *begin(void); + EdgeInf *end(void); + private: + EdgeInf *_firstEdge; + EdgeInf *_lastEdge; + unsigned int _count; +}; + + +extern EdgeList visGraph; +extern EdgeList invisGraph; + +class ShapeRef; + +extern void newBlockingShape(Polygn *poly, int pid); +extern void checkAllBlockedEdges(int pid); +extern void checkAllMissingEdges(void); +extern void generateContains(VertInf *pt); +extern void adjustContainsWithAdd(const Polygn& poly, const int p_shape); +extern void adjustContainsWithDel(const int p_shape); +extern void markConnectors(ShapeRef *shape); +extern void printInfo(void); + + +} + + +#endif + + diff --git a/src/libavoid/incremental.cpp b/src/libavoid/incremental.cpp new file mode 100644 index 000000000..3830c70ee --- /dev/null +++ b/src/libavoid/incremental.cpp @@ -0,0 +1,139 @@ +/* + * vim: ts=4 sw=4 et tw=0 wm=0 + * + * libavoid - Fast, Incremental, Object-avoiding Line Router + * Copyright (C) 2004-2005 Michael Wybrow + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * +*/ + +#include "libavoid/connector.h" +#include "libavoid/graph.h" +#include "libavoid/visibility.h" + +namespace Avoid { + + +void addShape(ShapeRef *shape) +{ + uint pid = shape->id(); + Polygn poly = shape->poly(); + + adjustContainsWithAdd(poly, pid); + + // o Check all visibility edges to see if this one shape + // blocks them. + newBlockingShape(&poly, pid); + + // o Calculate visibility for the new vertices. + if (UseLeesAlgorithm) + { + shapeVisSweep(shape); + } + else + { + shapeVis(shape); + } + callbackAllInvalidConnectors(); +} + + +void delShape(ShapeRef *shape) +{ + uint pid = shape->id(); + + // o Remove entries related to this shape's vertices + shape->removeFromGraph(); + + if (SelectiveReroute) + { + markConnectors(shape); + } + + adjustContainsWithDel(pid); + + delete shape; + + // o Check all edges that were blocked by this shape. + if (InvisibilityGrph) + { + checkAllBlockedEdges(pid); + } + else + { + // check all edges not in graph + checkAllMissingEdges(); + } + callbackAllInvalidConnectors(); +} + + +ShapeRef *moveShape(ShapeRef *oldShape, Polygn *newPoly) +{ + uint pid = oldShape->id(); + + // o Remove entries related to this shape's vertices + oldShape->removeFromGraph(); + + if (SelectiveReroute && !(PartialFeedback && PartialTime)) + { + markConnectors(oldShape); + } + + adjustContainsWithDel(pid); + + delete oldShape; + oldShape = NULL; + + adjustContainsWithAdd(*newPoly, pid); + + // o Check all edges that were blocked by this shape. + if (InvisibilityGrph) + { + checkAllBlockedEdges(pid); + } + else + { + // check all edges not in graph + checkAllMissingEdges(); + } + + ShapeRef *newShape = new ShapeRef(pid, *newPoly); + + // o Check all visibility edges to see if this one shape + // blocks them. + if (!(PartialFeedback && PartialTime)) + { + newBlockingShape(newPoly, pid); + } + + // o Calculate visibility for the new vertices. + if (UseLeesAlgorithm) + { + shapeVisSweep(newShape); + } + else + { + shapeVis(newShape); + } + callbackAllInvalidConnectors(); + + return newShape; +} + + +} + diff --git a/src/libavoid/incremental.h b/src/libavoid/incremental.h new file mode 100644 index 000000000..50ef8f7dc --- /dev/null +++ b/src/libavoid/incremental.h @@ -0,0 +1,39 @@ +/* + * vim: ts=4 sw=4 et tw=0 wm=0 + * + * libavoid - Fast, Incremental, Object-avoiding Line Router + * Copyright (C) 2004-2005 Michael Wybrow + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * +*/ + + +#ifndef AVOID_INCREMENTAL_H +#define AVOID_INCREMENTAL_H + +#include "libavoid/shape.h" + + +namespace Avoid { + +extern void addShape(ShapeRef *shape); +extern void delShape(ShapeRef *shape); +extern ShapeRef *moveShape(ShapeRef *oldShape, Polygn *newPoly); + +} + + +#endif diff --git a/src/libavoid/libavoid.h b/src/libavoid/libavoid.h new file mode 100644 index 000000000..0b6c7a819 --- /dev/null +++ b/src/libavoid/libavoid.h @@ -0,0 +1,40 @@ +/* + * vim: ts=4 sw=4 et tw=0 wm=0 + * + * libavoid - Fast, Incremental, Object-avoiding Line Router + * Copyright (C) 2004-2005 Michael Wybrow + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * +*/ + +#ifndef AVOID_LIBAVOID_H +#define AVOID_LIBAVOID_H + +#include "libavoid/geomtypes.h" +#include "libavoid/polyutil.h" +#include "libavoid/connector.h" +#include "libavoid/graph.h" +#include "libavoid/debug.h" +#include "libavoid/timer.h" +#include "libavoid/makepath.h" +#include "libavoid/vertices.h" +#include "libavoid/visibility.h" +#include "libavoid/static.h" +#include "libavoid/incremental.h" + +#endif + + diff --git a/src/libavoid/makefile.in b/src/libavoid/makefile.in new file mode 100644 index 000000000..e651e0ef1 --- /dev/null +++ b/src/libavoid/makefile.in @@ -0,0 +1,17 @@ +# Convenience stub makefile to call the real Makefile. + +@SET_MAKE@ + +# Explicit so that it's the default rule. +all: + cd .. && $(MAKE) libavoid/all + +clean %.a %.o: + cd .. && $(MAKE) libavoid/$@ + +.PHONY: all clean + +OBJEXT = @OBJEXT@ + +.SUFFIXES: +.SUFFIXES: .a .$(OBJEXT) diff --git a/src/libavoid/makepath.cpp b/src/libavoid/makepath.cpp new file mode 100644 index 000000000..776ffd307 --- /dev/null +++ b/src/libavoid/makepath.cpp @@ -0,0 +1,462 @@ +/* + * vim: ts=4 sw=4 et tw=0 wm=0 + * + * libavoid - Fast, Incremental, Object-avoiding Line Router + * Copyright (C) 2004-2005 Michael Wybrow + * + * -------------------------------------------------------------------- + * The dijkstraPath function is based on code published and described + * in "Algorithms in C" (Second Edition), 1990, by Robert Sedgewick. + * -------------------------------------------------------------------- + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * +*/ + +#include "libavoid/connector.h" +#include "libavoid/graph.h" +#include +#include + +namespace Avoid { + + +double segmt_penalty = 0; +double angle_penalty = 0; + + +static double Dot(const Point& l, const Point& r) +{ + return (l.x * r.x) + (l.y * r.y); +} + +static double CrossLength(const Point& l, const Point& r) +{ + return (l.x * r.y) - (l.y * r.x); +} + + +// Return the angle between the two line segments made by the +// points p1--p2 and p2--p3. Return value is in radians. +// +static double angleBetween(const Point& p1, const Point& p2, const Point& p3) +{ + Point v1 = { p1.x - p2.x, p1.y - p2.y }; + Point v2 = { p3.x - p2.x, p3.y - p2.y }; + + return fabs(atan2(CrossLength(v1, v2), Dot(v1, v2))); +} + + +// Given the two points for a new segment of a path (inf2 & inf3) +// as well as the distance between these points (dist), as well as +// possibly the previous point (inf1) [from inf1--inf2], return a +// cost associated with this route. +// +double cost(const double dist, VertInf *inf1, + VertInf *inf2, VertInf *inf3) +{ + double result = dist; + + if (inf2->pathNext != NULL) + { + // This is not the first segment, so there is a bend + // between it and the last one in the existing path. + if ((angle_penalty > 0) || (segmt_penalty > 0)) + { + Point p1 = inf1->point; + Point p2 = inf2->point; + Point p3 = inf3->point; + + double rad = M_PI - angleBetween(p1, p2, p3); + + // Make `rad' between 0--10 then take its log so small + // angles are not penalised as much as large ones. + result += (angle_penalty * log((rad * 10 / M_PI) + 1)); + + // Don't penalise as an extra segment if there is no turn. + if (rad > 0.0005) + { + result += segmt_penalty; + } + } + + } + + return result; +} + + +// Returns the best path from src to tar using the cost function. +// +// The path is worked out via Dijkstra's algorithm, and is encoded via +// pathNext links in each of the VerInfs along the path. +// +// Based on the code of 'matrixpfs'. +// +static void dijkstraPath(VertInf *src, VertInf *tar) +{ + double unseen = (double) INT_MAX; + + // initialize arrays + VertInf *finish = vertices.end(); + for (VertInf *t = vertices.connsBegin(); t != finish; t = t->lstNext) + { + t->pathNext = NULL; + t->pathDist = -unseen; + } + + VertInf *min = src; + while (min != tar) + { + VertInf *k = min; + min = NULL; + + k->pathDist *= -1; + if (k->pathDist == unseen) + { + k->pathDist = 0; + } + + EdgeInfList& visList = k->visList; + EdgeInfList::iterator finish = visList.end(); + for (EdgeInfList::iterator edge = visList.begin(); edge != finish; + ++edge) + { + VertInf *t = (*edge)->otherVert(k); + VertID tID = t->id; + + // Only check shape verticies, or endpoints. + if ((t->pathDist < 0) && + ((tID.objID == src->id.objID) || tID.isShape)) + { + double kt_dist = (*edge)->getDist(); + double priority = k->pathDist + + cost(kt_dist, k->pathNext, k, t); + + if ((kt_dist != 0) && (t->pathDist < -priority)) + { + t->pathDist = -priority; + t->pathNext = k; + } + if ((min == NULL) || (t->pathDist > min->pathDist)) + { + min = t; + } + } + } + EdgeInfList& invisList = k->invisList; + finish = invisList.end(); + for (EdgeInfList::iterator edge = invisList.begin(); edge != finish; + ++edge) + { + VertInf *t = (*edge)->otherVert(k); + VertID tID = t->id; + + // Only check shape verticies, or endpoints. + if ((t->pathDist < 0) && + ((tID.objID == src->id.objID) || tID.isShape > 0)) + { + if ((min == NULL) || (t->pathDist > min->pathDist)) + { + min = t; + } + } + } + } +} + + +class ANode +{ + public: + VertInf* inf; + double g; // Gone + double h; // Heuristic + double f; // Formula f = g + h + VertInf *pp; + + ANode(VertInf *vinf) + : inf(vinf) + , g(0) + , h(0) + , f(0) + , pp(NULL) + { + } + ANode() + : inf(NULL) + , g(0) + , h(0) + , f(0) + , pp(NULL) + { + } +}; + +bool operator<(const ANode &a, const ANode &b) +{ + return a.f < b.f; +} + + +bool operator>(const ANode &a, const ANode &b) +{ + return a.f > b.f; +} + + +// Returns the best path from src to tar using the cost function. +// +// The path is worked out using the aStar algorithm, and is encoded via +// pathNext links in each of the VerInfs along the path. +// +// The aStar STL code is based on public domain code available on the +// internet. +// +static void aStarPath(VertInf *src, VertInf *tar) +{ + std::vector PENDING; // STL Vectors chosen because of rapid + std::vector DONE; // insertions/deletions at back, + ANode Node, BestNode; // Temporary Node and BestNode + bool bNodeFound = false; // Flag if node is found in container + + tar->pathNext = NULL; + + // Create the start node + Node = ANode(src); + Node.g = 0; + Node.h = dist(Node.inf->point, tar->point); + Node.f = Node.g + Node.h; + // Set a null parent, so cost function knows this is the first segment. + Node.pp = NULL; + + // Populate the PENDING container with the first location + PENDING.push_back(Node); + // Create a heap from PENDING for sorting + using std::make_heap; using std::push_heap; using std::pop_heap; + make_heap( PENDING.begin(), PENDING.end() ); + + while (!PENDING.empty()) + { + // Ascending sort based on overloaded operators below + sort_heap(PENDING.begin(), PENDING.end()); + + // Set the Node with lowest f value to BESTNODE + BestNode = PENDING.front(); + + // Pop off the heap. Actually this moves the + // far left value to the far right. The node + // is not actually removed since the pop is to + // the heap and not the container. + pop_heap(PENDING.begin(), PENDING.end()); + + + // Remove node from right (the value we pop_heap'd) + PENDING.pop_back(); + + // Push the BestNode onto DONE + BestNode.inf->pathNext = BestNode.pp; + DONE.push_back(BestNode); + +#if 0 + printf("Considering... "); + BestNode.ID->print(stdout); + printf(" - g: %3.1f h: %3.1f f: %3.1f back: ", BestNode.g, BestNode.h, + BestNode.f); + BestNode.pp.print(stdout); + printf("\n"); +#endif + + // If at destination, break and create path below + if (BestNode.inf == tar) + { + //bPathFound = true; // arrived at destination... + break; + } + + // Check adjacent points in graph + EdgeInfList& visList = BestNode.inf->visList; + EdgeInfList::iterator finish = visList.end(); + for (EdgeInfList::iterator edge = visList.begin(); edge != finish; + ++edge) + { + Node.inf = (*edge)->otherVert(BestNode.inf); + + // Only check shape verticies, or the tar endpoint. + if (!(Node.inf->id.isShape) && (Node.inf != tar)) + { + continue; + } + + double edgeDist = (*edge)->getDist(); + + if (edgeDist == 0) + { + continue; + } + + VertInf *prevInf = BestNode.inf->pathNext; + + Node.g = BestNode.g + cost(edgeDist, prevInf, + BestNode.inf, Node.inf); + + // Calculate the Heuristic. + Node.h = dist(Node.inf->point, tar->point); + + // The A* formula + Node.f = Node.g + Node.h; + // Point parent to last BestNode (pushed onto DONE) + Node.pp = BestNode.inf; + + bNodeFound = false; + + // Check to see if already on PENDING + for (unsigned int i = 0; i < PENDING.size(); i++) + { + if (Node.inf == PENDING.at(i).inf) + { // If already on PENDING + if (Node.g < PENDING.at(i).g) + { + PENDING.at(i).g = Node.g; + PENDING.at(i).f = Node.g + PENDING.at(i).h; + PENDING.at(i).pp = Node.pp; + } + bNodeFound = true; + break; + } + } + if (!bNodeFound ) // If Node NOT found on PENDING + { + // Check to see if already on DONE + for (unsigned int i = 0; i < DONE.size(); i++) + { + if (Node.inf == DONE.at(i).inf) + { + // If on DONE, Which has lower gone? + if (Node.g < DONE.at(i).g) + { + DONE.at(i).g = Node.g; + DONE.at(i).f = Node.g + DONE.at(i).h; + DONE.at(i).pp = Node.pp; + DONE.at(i).inf->pathNext = Node.pp; + } + bNodeFound = true; + break; + } + } + } + + if (!bNodeFound ) // If Node NOT found on PENDING or DONE + { + // Push NewNode onto PENDING + PENDING.push_back(Node); + // Push NewNode onto heap + push_heap( PENDING.begin(), PENDING.end() ); + // Re-Assert heap, or will be short by one + make_heap( PENDING.begin(), PENDING.end() ); + +#if 0 + // Display PENDING and DONE containers (For Debugging) + cout << "PENDING: "; + for (int i = 0; i < PENDING.size(); i++) + { + cout << PENDING.at(i).x << "," << PENDING.at(i).y << ","; + cout << PENDING.at(i).g << "," << PENDING.at(i).h << " "; + } + cout << endl; + cout << "DONE: "; + for (int i = 0; i < DONE.size(); i++) + { + cout << DONE.at(i).x << "," << DONE.at(i).y << ","; + cout << DONE.at(i).g << "," << DONE.at(i).h << " "; + } + cout << endl << endl; + int ch = _getch(); +#endif + } + } + } +} + + +// Returns the best path for the connector referred to by lineRef. +// +// The path encoded in the pathNext links in each of the VerInfs +// backwards along the path, from the tar back to the source. +// +void makePath(ConnRef *lineRef, bool *flag) +{ + VertInf *src = lineRef->src(); + VertInf *tar = lineRef->dst(); + + // TODO: Could be more efficient here. + EdgeInf *directEdge = EdgeInf::existingEdge(src, tar); + if (!IncludeEndpoints && directVis(src, tar)) + { + Point p = src->point; + Point q = tar->point; + + assert(directEdge == NULL); + + directEdge = new EdgeInf(src, tar); + tar->pathNext = src; + directEdge->setDist(dist(p, q)); + directEdge->addConn(flag); + + return; + } + else if (IncludeEndpoints && directEdge && (directEdge->getDist() > 0)) + { + tar->pathNext = src; + directEdge->addConn(flag); + } + else + { + // Mark the path endpoints as not being able to see + // each other. This is true if we are here. + if (!IncludeEndpoints && InvisibilityGrph) + { + directEdge->addBlocker(0); + } + + if (UseAStarSearch) + { + aStarPath(src, tar); + } + else + { + dijkstraPath(src, tar); + } + +#if 0 + PointMap::iterator t; + for (VertInf *t = vertices.connsBegin(); t != vertices.end(); + t = t->lstNext) + { + + t->id.print(); + printf(" -> "); + t->pathNext->id.print(); + printf("\n"); + } +#endif + } +} + + +} + + diff --git a/src/libavoid/makepath.h b/src/libavoid/makepath.h new file mode 100644 index 000000000..5ab21b993 --- /dev/null +++ b/src/libavoid/makepath.h @@ -0,0 +1,42 @@ +/* + * vim: ts=4 sw=4 et tw=0 wm=0 + * + * libavoid - Fast, Incremental, Object-avoiding Line Router + * Copyright (C) 2004-2005 Michael Wybrow + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * +*/ + +#ifndef AVOID_MAKEPATH_H +#define AVOID_MAKEPATH_H + +#include "libavoid/connector.h" + +namespace Avoid { + + +extern double segmt_penalty; +extern double angle_penalty; + +extern void makePath(ConnRef *lineRef, bool *flag); + + +} + + +#endif + + diff --git a/src/libavoid/polyutil.cpp b/src/libavoid/polyutil.cpp new file mode 100644 index 000000000..6ece50e63 --- /dev/null +++ b/src/libavoid/polyutil.cpp @@ -0,0 +1,86 @@ +/* + * vim: ts=4 sw=4 et tw=0 wm=0 + * + * libavoid - Fast, Incremental, Object-avoiding Line Router + * Copyright (C) 2004-2005 Michael Wybrow + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * +*/ + + +#include "libavoid/shape.h" + +namespace Avoid { + + +Polygn newPoly(int size) +{ + Polygn newpoly; + + newpoly.pn = size; + newpoly.ps = (Point *) calloc(size, sizeof(Point)); + if (!newpoly.ps) + { + fprintf(stderr, + "Error: Unable to allocate Point array in Avoid::newPoly\n"); + abort(); + } + return newpoly; +} + + +Polygn copyPoly(Polygn poly) +{ + Polygn newpoly = newPoly(poly.pn); + + newpoly.id = poly.id; + for (int i = 0; i < poly.pn; i++) + { + newpoly.ps[i] = poly.ps[i]; + } + return newpoly; +} + + +Polygn copyPoly(ShapeRef *shape) +{ + Polygn poly = shape->poly(); + Polygn newpoly = newPoly(poly.pn); + + newpoly.id = poly.id; + for (int i = 0; i < poly.pn; i++) + { + newpoly.ps[i] = poly.ps[i]; + } + return newpoly; +} + + +void freePoly(Polygn& poly) +{ + std::free(poly.ps); +} + + +void freePtrPoly(Polygn *poly) +{ + std::free(poly->ps); + std::free(poly); +} + + +} + diff --git a/src/libavoid/polyutil.h b/src/libavoid/polyutil.h new file mode 100644 index 000000000..456e190fb --- /dev/null +++ b/src/libavoid/polyutil.h @@ -0,0 +1,41 @@ +/* + * vim: ts=4 sw=4 et tw=0 wm=0 + * + * libavoid - Fast, Incremental, Object-avoiding Line Router + * Copyright (C) 2004-2005 Michael Wybrow + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * +*/ + +#include "libavoid/geometry.h" +#include "libavoid/shape.h" + +#ifndef AVOID_POLYUTIL_H +#define AVOID_POLYUTIL_H + +namespace Avoid { + + +extern Polygn newPoly(int size); +extern Polygn copyPoly(Polygn); +extern Polygn copyPoly(ShapeRef *shape); +extern void freePoly(Polygn&); +extern void freePtrPoly(Polygn *argpoly); + + +} + +#endif diff --git a/src/libavoid/shape.cpp b/src/libavoid/shape.cpp new file mode 100644 index 000000000..b08e75f3e --- /dev/null +++ b/src/libavoid/shape.cpp @@ -0,0 +1,176 @@ +/* + * vim: ts=4 sw=4 et tw=0 wm=0 + * + * libavoid - Fast, Incremental, Object-avoiding Line Router + * Copyright (C) 2004-2005 Michael Wybrow + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * +*/ + + +#include "libavoid/graph.h" // For alertConns +#include "libavoid/polyutil.h" + + +namespace Avoid { + + +ShapeRefList shapeRefs; + + +ShapeRef::ShapeRef(uint id, Polygn& ply) + : _id(id) + , _poly(copyPoly(ply)) + , _active(false) + , _firstVert(NULL) + , _lastVert(NULL) +{ + bool isShape = true; + VertID i = VertID(id, isShape, 0); + + VertInf *last = NULL; + VertInf *node = NULL; + for (int pt_i = 0; pt_i < _poly.pn; pt_i++) + { + node = new VertInf(i, _poly.ps[pt_i]); + + if (!_firstVert) + { + _firstVert = node; + } + else + { + node->shPrev = last; + last->shNext = node; + //node->lstPrev = last; + //last->lstNext = node; + } + vertices.addVertex(node); + + last = node; + i++; + // Increase total vertices count ++; + } + _lastVert = node; + + _lastVert->shNext = _firstVert; + _firstVert->shPrev = _lastVert; + + // Increase total shape count ++; + makeActive(); +} + + +ShapeRef::~ShapeRef() +{ + assert(_firstVert != NULL); + + VertInf *it = _firstVert; + do + { + VertInf *tmp = it; + it = it->shNext; + + // XXX: This could possibly be done less + // safely but faster, all at once. + vertices.removeVertex(tmp); + delete tmp; + } + while (it != _firstVert); + _firstVert = _lastVert = NULL; + + freePoly(_poly); + + makeInactive(); +} + + +void ShapeRef::makeActive(void) +{ + assert(!_active); + + // Add to connRefs list. + _pos = shapeRefs.insert(shapeRefs.begin(), this); + _active = true; +} + + +void ShapeRef::makeInactive(void) +{ + assert(_active); + + // Remove from connRefs list. + shapeRefs.erase(_pos); + _active = false; +} + + +VertInf *ShapeRef::firstVert(void) +{ + return _firstVert; +} + + +VertInf *ShapeRef::lastVert(void) +{ + return _lastVert; +} + + +uint ShapeRef::id(void) +{ + return _id; +} + + +Polygn ShapeRef::poly(void) +{ + return _poly; +} + + +void ShapeRef::removeFromGraph(void) +{ + for (VertInf *iter = firstVert(); iter != lastVert()->lstNext; ) + { + VertInf *tmp = iter; + iter = iter->lstNext; + + // For each vertex. + EdgeInfList& visList = tmp->visList; + EdgeInfList::iterator finish = visList.end(); + EdgeInfList::iterator edge; + while ((edge = visList.begin()) != finish) + { + // Remove each visibility edge + (*edge)->alertConns(); + delete (*edge); + } + + EdgeInfList& invisList = tmp->invisList; + finish = invisList.end(); + while ((edge = invisList.begin()) != finish) + { + // Remove each invisibility edge + delete (*edge); + } + } +} + + +} + + diff --git a/src/libavoid/shape.h b/src/libavoid/shape.h new file mode 100644 index 000000000..acdb36983 --- /dev/null +++ b/src/libavoid/shape.h @@ -0,0 +1,73 @@ +/* + * vim: ts=4 sw=4 et tw=0 wm=0 + * + * libavoid - Fast, Incremental, Object-avoiding Line Router + * Copyright (C) 2004-2005 Michael Wybrow + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * +*/ + +#ifndef AVOID_SHAPE_H +#define AVOID_SHAPE_H + +#include "libavoid/geometry.h" +#include + + +namespace Avoid { + +typedef unsigned int uint; + +class ShapeRef; +class VertInf; + +typedef std::list ShapeRefList; + + +class ShapeRef +{ + public: + ShapeRef(uint id, Polygn& poly); + ~ShapeRef(); + VertInf *firstVert(void); + VertInf *lastVert(void); + uint id(void); + Polygn poly(void); + + void makeActive(void); + void makeInactive(void); + + void removeFromGraph(void); + + private: + uint _id; + Polygn _poly; + bool _active; + ShapeRefList::iterator _pos; + VertInf *_firstVert; + VertInf *_lastVert; +}; + + +extern ShapeRefList shapeRefs; + + +} + + +#endif + + diff --git a/src/libavoid/static.cpp b/src/libavoid/static.cpp new file mode 100644 index 000000000..d424a2e7f --- /dev/null +++ b/src/libavoid/static.cpp @@ -0,0 +1,76 @@ +/* + * vim: ts=4 sw=4 et tw=0 wm=0 + * + * libavoid - Fast, Incremental, Object-avoiding Line Router + * Copyright (C) 2004-2005 Michael Wybrow + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * +*/ + +#include +#include "libavoid/connector.h" +#include "libavoid/visibility.h" + +namespace Avoid { + + +// This should only be used for the static algorithm. +// +// XXX: If to set up the vis graph for incremental it would need +// the shapeRef ppinters in obs. +// +void CreateVisGraph(Polygn **obs, int n_obs) +{ + for (int poly_i = 0; poly_i < n_obs; poly_i++) + { + uint id = obs[poly_i]->id; + + new ShapeRef(id, *(obs[poly_i])); + } + computeCompleteVis(); +} + + +void DestroyVisGraph(void) +{ + ShapeRefList::iterator sFinish = shapeRefs.end(); + ShapeRefList::iterator sCurr; + + while ((sCurr = shapeRefs.begin()) != sFinish) + { + ShapeRef *shape = (*sCurr); + + shape->removeFromGraph(); + delete shape; + } + + ConnRefList::iterator cFinish = connRefs.end(); + ConnRefList::iterator cCurr; + + while ((cCurr = connRefs.begin())!= cFinish) + { + ConnRef *conn = (*cCurr); + + conn->removeFromGraph(); + conn->unInitialise(); + } + + assert(vertices.connsBegin() == NULL); +} + + +} + diff --git a/src/libavoid/static.h b/src/libavoid/static.h new file mode 100644 index 000000000..c02c6be2f --- /dev/null +++ b/src/libavoid/static.h @@ -0,0 +1,38 @@ +/* + * vim: ts=4 sw=4 et tw=0 wm=0 + * + * libavoid - Fast, Incremental, Object-avoiding Line Router + * Copyright (C) 2004-2005 Michael Wybrow + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * +*/ + + +#ifndef AVOID_STATIC_H +#define AVOID_STATIC_H + +#include "libavoid/geomtypes.h" + + +namespace Avoid { + +extern void CreateVisGraph(Polygn **obstacles, int n_obstacles); +extern void DestroyVisGraph(void); + +} + + +#endif diff --git a/src/libavoid/timer.cpp b/src/libavoid/timer.cpp new file mode 100644 index 000000000..7e930d011 --- /dev/null +++ b/src/libavoid/timer.cpp @@ -0,0 +1,168 @@ +/* + * vim: ts=4 sw=4 et tw=0 wm=0 + * + * libavoid - Fast, Incremental, Object-avoiding Line Router + * Copyright (C) 2004-2005 Michael Wybrow + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * +*/ + +#include +#include +#include +using std::abort; +#include + +#include "libavoid/timer.h" + +namespace Avoid { + + +Timer timers = Timer(); + + +Timer::Timer() +{ + Reset(); +} + + +void Timer::Reset(void) +{ + for (int i = 0; i < tmCount; i++) + { + //tTotal[i] = 0; + cTotal[i] = cPath[i] = 0; + cTally[i] = cPathTally[i] = 0; + cMax[i] = cPathMax[i] = 0; + } + running = false; + count = 0; + type = lasttype = tmNon; +} + + +void Timer::Register(const int t, const bool start) +{ + assert(t != tmNon); + + if (type == tmNon) + { + type = t; + } + else + { + type = tmSev; + } + + if (start) + { + Start(); + } +} + +void Timer::Start(void) +{ + if (running) + { + fprintf(stderr, "ERROR: Timer already running in Timer::Start()\n"); + abort(); + } + cStart[type] = clock(); // CPU time + running = true; +} + + +void Timer::Stop(void) +{ + if (!running) + { + fprintf(stderr, "ERROR: Timer not running in Timer::Stop()\n"); + abort(); + } + clock_t cStop = clock(); // CPU time + running = false; + + bigclock_t cDiff; + if (cStop < cStart[type]) + { + // Uh-oh, the clock value has wrapped around. + // + bigclock_t realStop = ((bigclock_t) cStop) + ULONG_MAX + 1; + cDiff = realStop - cStart[type]; + } + else + { + cDiff = cStop - cStart[type]; + } + + if (cDiff > LONG_MAX) + { + fprintf(stderr, "Error: cDiff overflow in Timer:Stop()\n"); + abort(); + } + + if (type == tmPth) + { + cPath[lasttype] += cDiff; + cPathTally[lasttype]++; + if (((clock_t) cDiff) > cPathMax[lasttype]) + { + cPathMax[lasttype] = (clock_t) cDiff; + } + } + else + { + cTotal[type] += cDiff; + cTally[type]++; + if (((clock_t) cDiff) > cMax[type]) + { + cMax[type] = (clock_t) cDiff; + } + lasttype = type; + } + + type = tmNon; +} + + +void Timer::PrintAll(void) +{ + for (int i = 0; i < tmCount; i++) + { + Print(i); + } +} + + +#define toMsec(tot) ((bigclock_t) ((tot) / (((double) CLOCKS_PER_SEC) / 1000))) +#define toAvg(tot, cnt) ((((cnt) > 0) ? ((long double) (tot)) / (cnt) : 0)) + +void Timer::Print(const int t) +{ + bigclock_t avg = toMsec(toAvg(cTotal[t], cTally[t])); + bigclock_t pind = toMsec(toAvg(cPath[t], cPathTally[t])); + bigclock_t pavg = toMsec(toAvg(cPath[t], cTally[t])); + double max = toMsec(cMax[t]); + double pmax = toMsec(cPathMax[t]); + printf("\t%lld %d %lld %.0f %lld %d %lld %.0f %lld\n", + cTotal[t], cTally[t], avg, max, + cPath[t], cPathTally[t], pavg, pmax, pind); +} + + +} + diff --git a/src/libavoid/timer.h b/src/libavoid/timer.h new file mode 100644 index 000000000..9446ecc51 --- /dev/null +++ b/src/libavoid/timer.h @@ -0,0 +1,92 @@ +/* + * vim: ts=4 sw=4 et tw=0 wm=0 + * + * libavoid - Fast, Incremental, Object-avoiding Line Router + * Copyright (C) 2004-2005 Michael Wybrow + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * +*/ + +#ifndef PROFILE_H +#define PROFILE_H + +#include + +namespace Avoid { + + +#ifdef NOTIMERS + + #define register_timer(t) do {} while(0) + #define regstart_timer(t) do {} while(0) + #define start_timer() do {} while(0) + #define stop_timer() do {} while(0) + +#else + + #define register_timer(t) timers.Register(t) + #define regstart_timer(t) timers.Register(t, timerStart) + #define start_timer() timers.Start() + #define stop_timer() timers.Stop() + +#endif + +typedef unsigned long long int bigclock_t; + +static const int tmCount = 5; + +static const int tmNon = -1; +static const int tmAdd = 0; +static const int tmDel = 1; +static const int tmMov = 2; +static const int tmPth = 3; +static const int tmSev = 4; + + +static const bool timerStart = true; +static const bool timerDelay = false; + + +class Timer +{ + public: + Timer(); + void Register(const int t, const bool start = timerDelay); + void Start(void); + void Stop(void); + void Reset(void); + void Print(const int t); + void PrintAll(void); + + private: + clock_t cStart[tmCount]; + bigclock_t cTotal[tmCount]; + bigclock_t cPath[tmCount]; + int cTally[tmCount]; + int cPathTally[tmCount]; + clock_t cMax[tmCount]; + clock_t cPathMax[tmCount]; + + bool running; + long count; + int type, lasttype; +}; + +extern Timer timers; + +} + +#endif diff --git a/src/libavoid/vertices.cpp b/src/libavoid/vertices.cpp new file mode 100644 index 000000000..7e74509f0 --- /dev/null +++ b/src/libavoid/vertices.cpp @@ -0,0 +1,438 @@ +/* + * vim: ts=4 sw=4 et tw=0 wm=0 + * + * libavoid - Fast, Incremental, Object-avoiding Line Router + * Copyright (C) 2004-2005 Michael Wybrow + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * +*/ + +#include "libavoid/geometry.h" +#include "libavoid/graph.h" // For alertConns +#include "libavoid/debug.h" + + + +namespace Avoid { + + +ContainsMap contains; + + +VertID::VertID() +{ +} + + +VertID::VertID(unsigned int id, bool s, int n) + : objID(id) + , isShape(s) + , vn(n) +{ +} + + +VertID::VertID(const VertID& other) + : objID(other.objID) + , isShape(other.isShape) + , vn(other.vn) +{ +} + + +VertID& VertID::operator= (const VertID& rhs) +{ + // Gracefully handle self assignment + //if (this == &rhs) return *this; + + objID = rhs.objID; + isShape = rhs.isShape; + vn = rhs.vn; + + return *this; +} + + +bool VertID::operator==(const VertID& rhs) const +{ + if ((objID != rhs.objID) || (vn != rhs.vn)) + { + return false; + } + assert(isShape == rhs.isShape); + return true; +} + + +bool VertID::operator!=(const VertID& rhs) const +{ + if ((objID != rhs.objID) || (vn != rhs.vn)) + { + return true; + } + assert(isShape == rhs.isShape); + return false; +} + + +bool VertID::operator<(const VertID& rhs) const +{ + if ((objID < rhs.objID) || + ((objID == rhs.objID) && (vn < rhs.vn))) + { + return true; + } + return false; +} + + +VertID VertID::operator+(const int& rhs) const +{ + return VertID(objID, isShape, vn + rhs); +} + + +VertID VertID::operator-(const int& rhs) const +{ + return VertID(objID, isShape, vn - rhs); +} + + +VertID& VertID::operator++(int) +{ + vn += 1; + return *this; +} + + +void VertID::print(FILE *file) const +{ + fprintf(file, "[%u,%d]", objID, vn); +} + + +void VertID::db_print(void) const +{ + db_printf("[%u,%d]", objID, vn); +} + + +const int VertID::src = 1; +const int VertID::tar = 2; + + +VertInf::VertInf(const VertID& vid, const Point& vpoint) + : id(vid) + , point(vpoint) + , lstPrev(NULL) + , lstNext(NULL) + , shPrev(NULL) + , shNext(NULL) + , visListSize(0) + , invisListSize(0) + , pathNext(NULL) + , pathDist(0) +{ +} + + +void VertInf::Reset(const Point& vpoint) +{ + point = vpoint; +} + + +void VertInf::removeFromGraph(const bool isConnVert) +{ + if (isConnVert) + { + assert(!(id.isShape)); + } + + VertInf *tmp = this; + + // For each vertex. + EdgeInfList& visList = tmp->visList; + EdgeInfList::iterator finish = visList.end(); + EdgeInfList::iterator edge; + while ((edge = visList.begin()) != finish) + { + // Remove each visibility edge + (*edge)->alertConns(); + delete (*edge); + } + + EdgeInfList& invisList = tmp->invisList; + finish = invisList.end(); + while ((edge = invisList.begin()) != finish) + { + // Remove each invisibility edge + delete (*edge); + } +} + + +bool directVis(VertInf *src, VertInf *dst) +{ + ShapeSet ss = ShapeSet(); + + Point& p = src->point; + Point& q = dst->point; + + VertID& pID = src->id; + VertID& qID = dst->id; + + if (!(pID.isShape)) + { + ss.insert(contains[pID].begin(), contains[pID].end()); + } + if (!(qID.isShape)) + { + ss.insert(contains[qID].begin(), contains[qID].end()); + } + + // The "beginning" should be the first shape vertex, rather + // than an endpoint, which are also stored in "vertices". + VertInf *endVert = vertices.end(); + for (VertInf *k = vertices.shapesBegin(); k != endVert; k = k->lstNext) + { + if ((ss.find(k->id.objID) == ss.end())) + { + if (segmentIntersect(p, q, k->point, k->shNext->point)) + { + return false; + } + } + } + return true; +} + + +VertInfList::VertInfList() + : _firstShapeVert(NULL) + , _firstConnVert(NULL) + , _lastShapeVert(NULL) + , _lastConnVert(NULL) + , _shapeVertices(0) + , _connVertices(0) +{ +} + + +#define checkVertInfListConditions() \ + do { \ + assert((!_firstConnVert && (_connVertices == 0)) || \ + ((_firstConnVert->lstPrev == NULL) && (_connVertices > 0))); \ + assert((!_firstShapeVert && (_shapeVertices == 0)) || \ + ((_firstShapeVert->lstPrev == NULL) && (_shapeVertices > 0))); \ + assert(!_lastShapeVert || (_lastShapeVert->lstNext == NULL)); \ + assert(!_lastConnVert || (_lastConnVert->lstNext == _firstShapeVert)); \ + assert((!_firstConnVert && !_lastConnVert) || \ + (_firstConnVert && _lastConnVert) ); \ + assert((!_firstShapeVert && !_lastShapeVert) || \ + (_firstShapeVert && _lastShapeVert) ); \ + assert(!_firstShapeVert || _firstShapeVert->id.isShape); \ + assert(!_lastShapeVert || _lastShapeVert->id.isShape); \ + assert(!_firstConnVert || !(_firstConnVert->id.isShape)); \ + assert(!_lastConnVert || !(_lastConnVert->id.isShape)); \ + } while(0) + + +void VertInfList::addVertex(VertInf *vert) +{ + checkVertInfListConditions(); + assert(vert->lstPrev == NULL); + assert(vert->lstNext == NULL); + + if (!(vert->id.isShape)) + { + // A Connector vertex + if (_firstConnVert) + { + // Join with previous front + vert->lstNext = _firstConnVert; + _firstConnVert->lstPrev = vert; + + // Make front + _firstConnVert = vert; + } + else + { + // Make front and back + _firstConnVert = vert; + _lastConnVert = vert; + + // Link to front of shapes list + vert->lstNext = _firstShapeVert; + } + _connVertices++; + } + else // if (vert->id.shape > 0) + { + // A Shape vertex + if (_lastShapeVert) + { + // Join with previous back + vert->lstPrev = _lastShapeVert; + _lastShapeVert->lstNext = vert; + + // Make back + _lastShapeVert = vert; + } + else + { + // Make first and last + _firstShapeVert = vert; + _lastShapeVert = vert; + + // Join with conns list + if (_lastConnVert) + { + assert (_lastConnVert->lstNext == NULL); + + _lastConnVert->lstNext = vert; + } + } + _shapeVertices++; + } + checkVertInfListConditions(); +} + + +void VertInfList::removeVertex(VertInf *vert) +{ + // Conditions for correct data structure + checkVertInfListConditions(); + + if (!(vert->id.isShape)) + { + // A Connector vertex + if (vert == _firstConnVert) + { + + if (vert == _lastConnVert) + { + _firstConnVert = NULL; + _lastConnVert = NULL; + } + else + { + // Set new first + _firstConnVert = _firstConnVert->lstNext; + + if (_firstConnVert) + { + // Set previous + _firstConnVert->lstPrev = NULL; + } + } + } + else if (vert == _lastConnVert) + { + // Set new last + _lastConnVert = _lastConnVert->lstPrev; + + // Make last point to shapes list + _lastConnVert->lstNext = _firstShapeVert; + } + else + { + vert->lstNext->lstPrev = vert->lstPrev; + vert->lstPrev->lstNext = vert->lstNext; + } + _connVertices--; + } + else // if (vert->id.shape > 0) + { + // A Shape vertex + if (vert == _lastShapeVert) + { + // Set new last + _lastShapeVert = _lastShapeVert->lstPrev; + + if (vert == _firstShapeVert) + { + _firstShapeVert = NULL; + if (_lastConnVert) + { + _lastConnVert->lstNext = NULL; + } + } + + if (_lastShapeVert) + { + _lastShapeVert->lstNext = NULL; + } + } + else if (vert == _firstShapeVert) + { + // Set new first + _firstShapeVert = _firstShapeVert->lstNext; + + // Correct the last conn vertex + if (_lastConnVert) + { + _lastConnVert->lstNext = _firstShapeVert; + } + + if (_firstShapeVert) + { + _firstShapeVert->lstPrev = NULL; + } + } + else + { + vert->lstNext->lstPrev = vert->lstPrev; + vert->lstPrev->lstNext = vert->lstNext; + } + _shapeVertices--; + } + vert->lstPrev = NULL; + vert->lstNext = NULL; + + checkVertInfListConditions(); +} + + +VertInf *VertInfList::shapesBegin(void) +{ + return _firstShapeVert; +} + + +VertInf *VertInfList::connsBegin(void) +{ + if (_firstConnVert) + { + return _firstConnVert; + } + // No connector vertices + return _firstShapeVert; +} + + +VertInf *VertInfList::end(void) +{ + return NULL; +} + + +VertInfList vertices; + + +} + + diff --git a/src/libavoid/vertices.h b/src/libavoid/vertices.h new file mode 100644 index 000000000..c2ff6977f --- /dev/null +++ b/src/libavoid/vertices.h @@ -0,0 +1,124 @@ +/* + * vim: ts=4 sw=4 et tw=0 wm=0 + * + * libavoid - Fast, Incremental, Object-avoiding Line Router + * Copyright (C) 2004-2005 Michael Wybrow + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * +*/ + +#ifndef AVOID_VERTICES_H +#define AVOID_VERTICES_H + +#include +#include +#include +#include +#include "libavoid/geomtypes.h" + +namespace Avoid { + +class EdgeInf; + +typedef std::list EdgeInfList; + + +class VertID +{ + public: + unsigned int objID; + bool isShape; + int vn; + + static const int src; + static const int tar; + + VertID(); + VertID(unsigned int id, bool s, int n); + VertID(const VertID& other); + VertID& operator= (const VertID& rhs); + bool operator==(const VertID& rhs) const; + bool operator!=(const VertID& rhs) const; + bool operator<(const VertID& rhs) const; + VertID operator+(const int& rhs) const; + VertID operator-(const int& rhs) const; + VertID& operator++(int); + void print(FILE *file = stdout) const; + void db_print(void) const; +}; + + +class VertInf +{ + public: + VertInf(const VertID& vid, const Point& vpoint); + void Reset(const Point& vpoint); + void removeFromGraph(const bool isConnVert = true); + + VertID id; + Point point; + VertInf *lstPrev; + VertInf *lstNext; + VertInf *shPrev; + VertInf *shNext; + EdgeInfList visList; + unsigned int visListSize; + EdgeInfList invisList; + unsigned int invisListSize; + VertInf *pathNext; + double pathDist; +}; + + +bool directVis(VertInf *src, VertInf *dst); + + +class VertInfList +{ + public: + VertInfList(); + void addVertex(VertInf *vert); + void removeVertex(VertInf *vert); + VertInf *shapesBegin(void); + VertInf *connsBegin(void); + VertInf *end(void); + void stats(void) + { + printf("Conns %d, shapes %d\n", _connVertices, _shapeVertices); + } + private: + VertInf *_firstShapeVert; + VertInf *_firstConnVert; + VertInf *_lastShapeVert; + VertInf *_lastConnVert; + unsigned int _shapeVertices; + unsigned int _connVertices; +}; + + +typedef std::set ShapeSet; +typedef std::map ContainsMap; + +extern ContainsMap contains; +extern VertInfList vertices; + + +} + + +#endif + + diff --git a/src/libavoid/visibility.cpp b/src/libavoid/visibility.cpp new file mode 100644 index 000000000..e13656f5f --- /dev/null +++ b/src/libavoid/visibility.cpp @@ -0,0 +1,653 @@ +/* + * vim: ts=4 sw=4 et tw=0 wm=0 + * + * libavoid - Fast, Incremental, Object-avoiding Line Router + * Copyright (C) 2004-2005 Michael Wybrow + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * +*/ + + +#include + +#include "libavoid/shape.h" +#include "libavoid/debug.h" +#include "libavoid/visibility.h" +#include "libavoid/graph.h" + +#include + +#ifdef LINEDEBUG + #include "SDL_gfxPrimitives.h" +#endif + +namespace Avoid { + + +bool UseAStarSearch = true; +bool IgnoreRegions = true; +bool SelectiveReroute = true; +bool IncludeEndpoints = true; +bool UseLeesAlgorithm = false; +bool InvisibilityGrph = true; +bool PartialFeedback = false; + +bool PartialTime = false; + + +void computeCompleteVis(void) +{ + VertInf *beginVert = vertices.shapesBegin(); + VertInf *endVert = vertices.end(); + for (VertInf *i = beginVert; i != endVert; i = i->lstNext) + { + db_printf("-- CONSIDERING --\n"); + i->id.db_print(); + + for (VertInf *j = i->lstPrev ; j != NULL; j = j->lstPrev) + { + bool knownNew = true; + EdgeInf::checkEdgeVisibility(i, j, knownNew); + } + } +} + + +void shapeVis(ShapeRef *shape) +{ + if (!InvisibilityGrph) + { + // Clear shape from graph. + shape->removeFromGraph(); + } + + VertInf *shapeBegin = shape->firstVert(); + VertInf *shapeEnd = shape->lastVert()->lstNext; + + VertInf *pointsBegin = NULL; + if (IncludeEndpoints) + { + pointsBegin = vertices.connsBegin(); + } + else + { + pointsBegin = vertices.shapesBegin(); + } + + for (VertInf *curr = shapeBegin; curr != shapeEnd; curr = curr->lstNext) + { + bool knownNew = true; + + db_printf("-- CONSIDERING --\n"); + curr->id.db_print(); + + db_printf("\tFirst Half:\n"); + for (VertInf *j = pointsBegin ; j != curr; j = j->lstNext) + { + EdgeInf::checkEdgeVisibility(curr, j, knownNew); + } + + db_printf("\tSecond Half:\n"); + VertInf *pointsEnd = vertices.end(); + for (VertInf *k = shapeEnd; k != pointsEnd; k = k->lstNext) + { + EdgeInf::checkEdgeVisibility(curr, k, knownNew); + } + } +} + + +void shapeVisSweep(ShapeRef *shape) +{ + if (!InvisibilityGrph) + { + // Clear shape from graph. + shape->removeFromGraph(); + } + + VertInf *startIter = shape->firstVert(); + VertInf *endIter = shape->lastVert()->lstNext; + + for (VertInf *i = startIter; i != endIter; i = i->lstNext) + { + vertexSweep(i); + } +} + + +void vertexVisibility(VertInf *point, VertInf *partner, bool knownNew, + const bool gen_contains) +{ + const VertID& pID = point->id; + + // Make sure we're only doing ptVis for endpoints. + assert(!(pID.isShape)); + + if (!InvisibilityGrph) + { + point->removeFromGraph(); + } + + if (gen_contains && !(pID.isShape)) + { + generateContains(point); + } + + if (UseLeesAlgorithm) + { + vertexSweep(point); + } + else + { + VertInf *shapesEnd = vertices.end(); + for (VertInf *k = vertices.shapesBegin(); k != shapesEnd; + k = k->lstNext) + { + EdgeInf::checkEdgeVisibility(point, k, knownNew); + } + if (IncludeEndpoints && partner) + { + EdgeInf::checkEdgeVisibility(point, partner, knownNew); + } + } +} + + +//============================================================================ +// SWEEP CODE +// + +static VertInf *centerInf; +static Point centerPoint; +static VertID centerID; +static double centerAngle; + +#ifdef LINEDEBUG + SDL_Surface *avoid_screen = NULL; +#endif + + +class PointPair +{ + public: + PointPair(VertInf *inf) + : vInf(inf) + { + double x = vInf->point.x - centerPoint.x; + double y = vInf->point.y - centerPoint.y; + + angle = pos_to_angle(x, y); + } + bool operator==(const PointPair& rhs) const + { + if (vInf->id == rhs.vInf->id) + { + return true; + } + return false; + } + static double pos_to_angle(double x, double y) + { + double ang = atan(y / x); + ang = (ang * 180) / M_PI; + if (x < 0) + { + ang += 180; + } + else if (y < 0) + { + ang += 360; + } + return ang; + } + + VertInf *vInf; + double angle; +}; + + +typedef std::list VertList; + + +class EdgePair +{ + public: + EdgePair(VertInf *v1, VertInf *v2, double d, double a) + : vInf1(v1), vInf2(v2), initdist(d), initangle(a) + { + currdist = initdist; + currangle = initangle; + } + bool operator<(const EdgePair& rhs) const + { + if (initdist == rhs.initdist) + { + // TODO: This is a bit of a hack, should be + // set by the call to the constructor. + return dist(centerPoint, vInf2->point) < + dist(centerPoint, rhs.vInf2->point); + } + return (initdist < rhs.initdist); + } + bool operator==(const EdgePair& rhs) const + { + if (((vInf1->id == rhs.vInf1->id) && + (vInf2->id == rhs.vInf2->id)) || + ((vInf1->id == rhs.vInf2->id) && + (vInf2->id == rhs.vInf1->id))) + { + return true; + } + return false; + } + bool operator!=(const EdgePair& rhs) const + { + if (((vInf1->id == rhs.vInf1->id) && + (vInf2->id == rhs.vInf2->id)) || + ((vInf1->id == rhs.vInf2->id) && + (vInf2->id == rhs.vInf1->id))) + { + return false; + } + return true; + } + void SetObsAng(double a) + { + obsAngle = fmod(initangle - (a - 180), 360); + + //db_printf("SetObsAng: %.2f (from init %.2f, a %.2f)\n", + // obsAngle, initangle, a); + } + + VertInf *vInf1; + VertInf *vInf2; + double initdist; + double initangle; + double currdist; + double currangle; + double obsAngle; +}; + +typedef std::set EdgeSet; + + +static bool ppCompare(PointPair& pp1, PointPair& pp2) +{ + if (pp1.angle == pp2.angle) + { + // If the points are colinear, then order them in increasing + // distance from the point we are sweeping around. + return dist(centerPoint, pp1.vInf->point) < + dist(centerPoint, pp2.vInf->point); + } + return pp1.angle < pp2.angle; +} + + +#define AHEAD 1 +#define BEHIND -1 + +class isBoundingShape +{ + public: + // constructor remembers the value provided + isBoundingShape(ShapeSet& set) + : ss(set) + { } + // the following is an overloading of the function call operator + bool operator () (const PointPair& pp) + { + if (pp.vInf->id.isShape && + (ss.find(pp.vInf->id.objID) != ss.end())) + { + return true; + } + return false; + } + private: + ShapeSet& ss; +}; + + +static bool sweepVisible(EdgeSet& T, VertInf *currInf, VertInf *lastInf, + bool lastVisible, double lastAngle, int *blocker) +{ + + if (!lastInf || (lastAngle != centerAngle)) + { + // Nothing before it on the current ray + EdgeSet::iterator closestIt = T.begin(); + if (closestIt != T.end()) + { + + Point &e1 = (*closestIt).vInf1->point; + Point &e2 = (*closestIt).vInf2->point; + + if (segmentIntersect(centerInf->point, currInf->point, e1, e2)) + { + *blocker = (*closestIt).vInf1->id.objID; + return false; + } + else + { + return true; + } + } + else + { + return true; + } + } + else + { + // There was another point before this on the ray (lastInf) + if (!lastVisible) + { + *blocker = -1; + return false; + } + else + { + // Check if there is an edge in T that blocks the ray + // between lastInf and currInf. + EdgeSet::iterator tfin = T.end(); + for (EdgeSet::iterator l = T.begin(); l != tfin; ++l) + { + Point &e1 = (*l).vInf1->point; + Point &e2 = (*l).vInf2->point; + + if (segmentIntersect(lastInf->point, currInf->point, e1, e2)) + { + *blocker = (*l).vInf1->id.objID; + return false; + } + } + return true; + } + } +} + + +void vertexSweep(VertInf *vert) +{ + VertID& pID = vert->id; + Point& pPoint = vert->point; + + centerInf = vert; + centerID = pID; + centerPoint = pPoint; + Point centerPt = pPoint; + centerAngle = -1; + + // List of shape (and maybe endpt) vertices, except p + // Sort list, around + VertList v; + + // Initialise the vertex list + VertInf *beginVert = vertices.connsBegin(); + VertInf *endVert = vertices.end(); + for (VertInf *inf = beginVert; inf != endVert; inf = inf->lstNext) + { + if (inf->id == centerID) + { + // Don't include the center point + continue; + } + + if (inf->id.isShape) + { + // Add shape vertex + v.push_back(inf); + } + else + { + if (IncludeEndpoints) + { + if (centerID.isShape) + { + // Add endpoint vertex + v.push_back(inf); + } + else + { + // Center is an endpoint, so only include the other + // endpoint from the matching connector. + VertID partnerID = VertID(centerID.objID, false, + (centerID.vn == 1) ? 2 : 1); + if (inf->id == partnerID) + { + v.push_back(inf); + } + } + } + } + } + // TODO: This should be done with a sorted data type and insertion sort. + v.sort(ppCompare); + + EdgeSet e; + ShapeSet& ss = contains[centerID]; + + // And edge to T that intersect the initial ray. + VertInf *last = vertices.end(); + for (VertInf *k = vertices.shapesBegin(); k != last; ) + { + VertID kID = k->id; + if (!(centerID.isShape) && (ss.find(kID.objID) != ss.end())) + { + uint shapeID = kID.objID; + db_printf("Center is inside shape %u so ignore shape edges.\n", + shapeID); + // One of the endpoints is inside this shape so ignore it. + while ((k != last) && (k->id.objID == shapeID)) + { + // And skip the other vertices from this shape. + k = k->lstNext; + } + continue; + } + + VertInf *kPrev = k->shPrev; + if ((centerInf == k) || (centerInf == kPrev)) + { + k = k->lstNext; + continue; + } + + Point xaxis = { DBL_MAX, centerInf->point.y }; + + if (segmentIntersect(centerInf->point, xaxis, kPrev->point, k->point)) + { + double distance; + if (vecDir(centerInf->point, xaxis, kPrev->point) == BEHIND) + { + distance = dist(centerInf->point, kPrev->point); + } + else + { + distance = dist(centerInf->point, k->point); + } + + EdgePair intPair = EdgePair(k, kPrev, distance, 0.0); + e.insert(intPair).first; + } + k = k->lstNext; + } + + // Start the actual sweep. + db_printf("SWEEP: "); centerID.db_print(); db_printf("\n"); + + VertInf *lastInf = NULL; + double lastAngle = 0; + bool lastVisible = false; + int lastBlocker = 0; + + isBoundingShape isBounding(contains[centerID]); + VertList::iterator vfst = v.begin(); + VertList::iterator vfin = v.end(); + for (VertList::iterator t = vfst; t != vfin; ++t) + { + VertInf *currInf = (*t).vInf; + VertID& currID = currInf->id; + Point& currPt = currInf->point; + centerAngle = (*t).angle; + +#ifdef LINEDEBUG + Sint16 ppx = (int) centerPt.x; + Sint16 ppy = (int) centerPt.y; + + Sint16 cx = (int) currPt.x; + Sint16 cy = (int) currPt.y; +#endif + + double currDist = dist(centerPt, currPt); + db_printf("Dist: %.1f.\n", currDist); + + EdgeInf *edge = EdgeInf::existingEdge(centerInf, currInf); + if (edge == NULL) + { + edge = new EdgeInf(centerInf, currInf); + } + // Ignore vertices from bounding shapes, if sweeping round an endpoint. + if (!(centerID.isShape) && isBounding(*t)) + { + if (InvisibilityGrph) + { + // if p and t can't see each other, add blank edge + db_printf("\tSkipping visibility edge... \n\t\t"); + edge->addBlocker(currInf->id.objID); + edge->db_print(); + } + continue; + } + + + bool cone1 = true, cone2 = true; + if (centerID.isShape) + { + cone1 = inValidRegion(centerInf->shPrev->point, centerPoint, + centerInf->shNext->point, currInf->point); + } + if (currInf->id.isShape) + { + cone2 = inValidRegion(currInf->shPrev->point, currInf->point, + currInf->shNext->point, centerPoint); + } + + if (!cone1 || !cone2) + { + lastInf = NULL; + if (InvisibilityGrph) + { + db_printf("\tSetting invisibility edge... \n\t\t"); + edge->addBlocker(0); + edge->db_print(); + } + } + else + { + int blocker = 0; + // Check visibility. + bool currVisible = sweepVisible(e, currInf, + lastInf, lastVisible, lastAngle, &blocker); + if (blocker == -1) + { + blocker = lastBlocker; + } + if (currVisible) + { +#ifdef LINEDEBUG + lineRGBA(avoid_screen, ppx, ppy, cx, cy, 255, 0, 0, 32); +#endif + db_printf("\tSetting visibility edge... \n\t\t"); + edge->setDist(currDist); + edge->db_print(); + } + else if (InvisibilityGrph) + { + db_printf("\tSetting invisibility edge... \n\t\t"); + edge->addBlocker(blocker); + edge->db_print(); + } + + lastVisible = currVisible; + lastInf = currInf; + lastAngle = centerAngle; + lastBlocker = blocker; + } + + if (currID.isShape) + { + // This is a shape edge + Point& prevPt = currInf->shPrev->point; + Point& nextPt = currInf->shNext->point; + + int prevDir = vecDir(centerPt, currPt, prevPt); + EdgePair prevPair = EdgePair(currInf, currInf->shPrev, + currDist, centerAngle); + + EdgeSet::iterator ePtr; + if (prevDir == BEHIND) + { + ePtr = e.find(prevPair); + if (ePtr != e.end()) + { + e.erase(ePtr); + } + } + else if ((prevDir == AHEAD) && (currInf->shPrev != centerInf)) + { + double x = prevPt.x - currPt.x; + double y = prevPt.y - currPt.y; + double angle = PointPair::pos_to_angle(x, y); + prevPair.SetObsAng(angle); + + ePtr = e.insert(prevPair).first; + } + + + int nextDir = vecDir(centerPt, currPt, nextPt); + EdgePair nextPair = EdgePair(currInf, currInf->shNext, + currDist, centerAngle); + + if (nextDir == BEHIND) + { + ePtr = e.find(nextPair); + if (ePtr != e.end()) + { + e.erase(ePtr); + } + } + else if ((nextDir == AHEAD) && (currInf->shNext != centerInf)) + { + double x = nextPt.x - currPt.x; + double y = nextPt.y - currPt.y; + double angle = PointPair::pos_to_angle(x, y); + nextPair.SetObsAng(angle); + + ePtr = e.insert(nextPair).first; + } + } + +#ifdef LINEDEBUG + SDL_Flip(avoid_screen); +#endif + } +} + + +} + diff --git a/src/libavoid/visibility.h b/src/libavoid/visibility.h new file mode 100644 index 000000000..edfc3b16c --- /dev/null +++ b/src/libavoid/visibility.h @@ -0,0 +1,57 @@ +/* + * vim: ts=4 sw=4 et tw=0 wm=0 + * + * libavoid - Fast, Incremental, Object-avoiding Line Router + * Copyright (C) 2004-2005 Michael Wybrow + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * +*/ + +#ifndef AVOID_VISIBILITY_H +#define AVOID_VISIBILITY_H + +#include "libavoid/vertices.h" + + +//#define LINEDEBUG + +#ifdef LINEDEBUG + #include +#endif + + +namespace Avoid { + +extern bool PartialTime; +#ifdef LINEDEBUG + extern SDL_Surface *avoid_screen; +#endif + + +extern void vertexVisibility(VertInf *point, VertInf *partner, bool knownNew, + const bool gen_contains = false); +extern void vertexSweep(VertInf *point); +extern void computeCompleteVis(void); +extern void shapeVis(ShapeRef *shape); +extern void shapeVisSweep(ShapeRef *shape); + + +} + + +#endif + + diff --git a/src/libcroco/.cvsignore b/src/libcroco/.cvsignore new file mode 100644 index 000000000..38efca7bc --- /dev/null +++ b/src/libcroco/.cvsignore @@ -0,0 +1,3 @@ +.deps +.dirstamp +makefile diff --git a/src/libcroco/Makefile_insert b/src/libcroco/Makefile_insert new file mode 100644 index 000000000..97ed49ee8 --- /dev/null +++ b/src/libcroco/Makefile_insert @@ -0,0 +1,64 @@ +## Makefile.am fragment sourced by src/Makefile.am. + +libcroco/all: libcroco/libcroco.a + +libcroco/clean: + rm -f libcroco/libcroco.a $(libcroco_libcroco_a_OBJECTS) + +libcroco_libcroco_a_SOURCES = \ + libcroco/cr-utils.c \ + libcroco/cr-utils.h \ + libcroco/cr-input.c \ + libcroco/cr-input.h \ + libcroco/cr-enc-handler.c \ + libcroco/cr-enc-handler.h \ + libcroco/cr-num.c \ + libcroco/cr-num.h \ + libcroco/cr-rgb.c \ + libcroco/cr-rgb.h \ + libcroco/cr-token.c \ + libcroco/cr-token.h \ + libcroco/cr-tknzr.c \ + libcroco/cr-tknzr.h \ + libcroco/cr-term.c \ + libcroco/cr-term.h \ + libcroco/cr-attr-sel.c \ + libcroco/cr-attr-sel.h \ + libcroco/cr-pseudo.c \ + libcroco/cr-pseudo.h \ + libcroco/cr-additional-sel.c \ + libcroco/cr-additional-sel.h \ + libcroco/cr-simple-sel.c \ + libcroco/cr-simple-sel.h \ + libcroco/cr-selector.c \ + libcroco/cr-selector.h \ + libcroco/cr-doc-handler.c \ + libcroco/cr-doc-handler.h \ + libcroco/cr-parser.c \ + libcroco/cr-parser.h \ + libcroco/cr-declaration.c \ + libcroco/cr-declaration.h \ + libcroco/cr-statement.c \ + libcroco/cr-statement.h \ + libcroco/cr-stylesheet.c \ + libcroco/cr-stylesheet.h \ + libcroco/cr-cascade.c \ + libcroco/cr-cascade.h \ + libcroco/cr-om-parser.c \ + libcroco/cr-om-parser.h \ + libcroco/cr-style.c \ + libcroco/cr-style.h \ + libcroco/cr-libxml-node-iface.c \ + libcroco/cr-libxml-node-iface.h \ + libcroco/cr-node-iface.h \ + libcroco/cr-sel-eng.c \ + libcroco/cr-sel-eng.h \ + libcroco/cr-fonts.c \ + libcroco/cr-fonts.h \ + libcroco/cr-prop-list.c \ + libcroco/cr-prop-list.h \ + libcroco/cr-parsing-location.c \ + libcroco/cr-parsing-location.h \ + libcroco/cr-string.c \ + libcroco/cr-string.h \ + libcroco/libcroco.h diff --git a/src/libcroco/README b/src/libcroco/README new file mode 100644 index 000000000..74df23145 --- /dev/null +++ b/src/libcroco/README @@ -0,0 +1,11 @@ +This code is derived from libcroco-0.6. We hope that the changes will find +their way into libcroco-0.7 (in some form). + +The main changed file is cr-sel-eng.{c,h}. The cr-sel-eng in libcroco-0.6 is +somewhat experimental: it has a few bugs, and the interface requires that the +XML node storage be libxml2. The version in this directory has a modification +of allowing passing in a "vtable" of operations so that we can use our +preferred representation Inkscape::XML::Node. + +Once libcroco-0.7 is widely available (with the vtable interface or a +functional equivalent), this directory should be removed. diff --git a/src/libcroco/cr-additional-sel.c b/src/libcroco/cr-additional-sel.c new file mode 100644 index 000000000..9f511af06 --- /dev/null +++ b/src/libcroco/cr-additional-sel.c @@ -0,0 +1,468 @@ +/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * Author: Dodji Seketeli + * See COPYRIGHTS file for copyright information. + * + */ + +#include "cr-additional-sel.h" +#include "string.h" + +/** + *Default constructor of #CRAdditionalSel. + *@return the newly build instance of #CRAdditionalSel. + */ +CRAdditionalSel * +cr_additional_sel_new (void) +{ + CRAdditionalSel *result = NULL; + + result = g_try_malloc (sizeof (CRAdditionalSel)); + + if (result == NULL) { + cr_utils_trace_debug ("Out of memory"); + return NULL; + } + + memset (result, 0, sizeof (CRAdditionalSel)); + + return result; +} + +/** + *Constructor of #CRAdditionalSel. + *@param a_sel_type the type of the newly built instance + *of #CRAdditionalSel. + *@return the newly built instance of #CRAdditionalSel. + */ +CRAdditionalSel * +cr_additional_sel_new_with_type (enum AddSelectorType a_sel_type) +{ + CRAdditionalSel *result = NULL; + + result = cr_additional_sel_new (); + + g_return_val_if_fail (result, NULL); + + result->type = a_sel_type; + + return result; +} + +/** + *Sets a new class name to a + *CLASS additional selector. + *@param a_this the "this pointer" of the current instance + *of #CRAdditionalSel . + *@param a_class_name the new class name to set. + * + */ +void +cr_additional_sel_set_class_name (CRAdditionalSel * a_this, + CRString * a_class_name) +{ + g_return_if_fail (a_this && a_this->type == CLASS_ADD_SELECTOR); + + if (a_this->content.class_name) { + cr_string_destroy (a_this->content.class_name); + } + + a_this->content.class_name = a_class_name; +} + +/** + *Sets a new id name to an + *ID additional selector. + *@param a_this the "this pointer" of the current instance + *of #CRAdditionalSel . + *@param a_id the new id to set. + */ +void +cr_additional_sel_set_id_name (CRAdditionalSel * a_this, CRString * a_id) +{ + g_return_if_fail (a_this && a_this->type == ID_ADD_SELECTOR); + + if (a_this->content.id_name) { + cr_string_destroy (a_this->content.id_name); + } + + a_this->content.id_name = a_id; +} + +/** + *Sets a new pseudo to a + *PSEUDO additional selector. + *@param a_this the "this pointer" of the current instance + *of #CRAdditionalSel . + *@param a_pseudo the new pseudo to set. + */ +void +cr_additional_sel_set_pseudo (CRAdditionalSel * a_this, CRPseudo * a_pseudo) +{ + g_return_if_fail (a_this + && a_this->type == PSEUDO_CLASS_ADD_SELECTOR); + + if (a_this->content.pseudo) { + cr_pseudo_destroy (a_this->content.pseudo); + } + + a_this->content.pseudo = a_pseudo; +} + +/** + *Sets a new instance of #CRAttrSel to + *a ATTRIBUTE additional selector. + *@param a_this the "this pointer" of the current instance + *of #CRAdditionalSel . + *@param a_sel the new instance of #CRAttrSel to set. + */ +void +cr_additional_sel_set_attr_sel (CRAdditionalSel * a_this, CRAttrSel * a_sel) +{ + g_return_if_fail (a_this && a_this->type == ATTRIBUTE_ADD_SELECTOR); + + if (a_this->content.attr_sel) { + cr_attr_sel_destroy (a_this->content.attr_sel); + } + + a_this->content.attr_sel = a_sel; +} + +/** + *Appends a new instance of #CRAdditional to the + *current list of #CRAdditional. + *@param a_this the "this pointer" of the current instance + *of #CRAdditionalSel . + *@param a_sel the new instance to #CRAdditional to append. + *@return the new list of CRAdditionalSel or NULL if an error arises. + */ +CRAdditionalSel * +cr_additional_sel_append (CRAdditionalSel * a_this, CRAdditionalSel * a_sel) +{ + CRAdditionalSel *cur_sel = NULL; + + g_return_val_if_fail (a_sel, NULL); + + if (a_this == NULL) { + return a_sel; + } + + if (a_sel == NULL) + return NULL; + + for (cur_sel = a_this; + cur_sel && cur_sel->next; cur_sel = cur_sel->next) ; + + g_return_val_if_fail (cur_sel != NULL, NULL); + + cur_sel->next = a_sel; + a_sel->prev = cur_sel; + + return a_this; +} + +/** + *Preppends a new instance of #CRAdditional to the + *current list of #CRAdditional. + *@param a_this the "this pointer" of the current instance + *of #CRAdditionalSel . + *@param a_sel the new instance to #CRAdditional to preappend. + *@return the new list of CRAdditionalSel or NULL if an error arises. + */ +CRAdditionalSel * +cr_additional_sel_prepend (CRAdditionalSel * a_this, CRAdditionalSel * a_sel) +{ + g_return_val_if_fail (a_sel, NULL); + + if (a_this == NULL) { + return a_sel; + } + + a_sel->next = a_this; + a_this->prev = a_sel; + + return a_sel; +} + +guchar * +cr_additional_sel_to_string (CRAdditionalSel * a_this) +{ + guchar *result = NULL; + GString *str_buf = NULL; + CRAdditionalSel *cur = NULL; + + g_return_val_if_fail (a_this, NULL); + + str_buf = g_string_new (NULL); + + for (cur = a_this; cur; cur = cur->next) { + switch (cur->type) { + case CLASS_ADD_SELECTOR: + { + guchar *name = NULL; + + if (cur->content.class_name) { + name = g_strndup + (cur->content.class_name->stryng->str, + cur->content.class_name->stryng->len); + + if (name) { + g_string_append_printf + (str_buf, ".%s", + name); + g_free (name); + name = NULL; + } + } + } + break; + + case ID_ADD_SELECTOR: + { + guchar *name = NULL; + + if (cur->content.class_name) { + name = g_strndup + (cur->content.id_name->stryng->str, + cur->content.id_name->stryng->len); + + if (name) { + g_string_append_printf + (str_buf, "#%s", + name); + g_free (name); + name = NULL; + } + } + } + + break; + + case PSEUDO_CLASS_ADD_SELECTOR: + { + if (cur->content.pseudo) { + guchar *tmp_str = NULL; + + tmp_str = cr_pseudo_to_string + (cur->content.pseudo); + if (tmp_str) { + g_string_append_printf + (str_buf, ":%s", + tmp_str); + g_free (tmp_str); + tmp_str = NULL; + } + } + } + break; + + case ATTRIBUTE_ADD_SELECTOR: + if (cur->content.attr_sel) { + guchar *tmp_str = NULL; + + g_string_append_c (str_buf, '['); + tmp_str = cr_attr_sel_to_string + (cur->content.attr_sel); + if (tmp_str) { + g_string_append_printf + (str_buf, "%s]", tmp_str); + g_free (tmp_str); + tmp_str = NULL; + } + } + break; + + default: + break; + } + } + + if (str_buf) { + result = str_buf->str; + g_string_free (str_buf, FALSE); + str_buf = NULL; + } + + return result; +} + +guchar * +cr_additional_sel_one_to_string (CRAdditionalSel *a_this) +{ + guchar *result = NULL; + GString *str_buf = NULL; + + g_return_val_if_fail (a_this, NULL) ; + + str_buf = g_string_new (NULL) ; + + switch (a_this->type) { + case CLASS_ADD_SELECTOR: + { + guchar *name = NULL; + + if (a_this->content.class_name) { + name = g_strndup + (a_this->content.class_name->stryng->str, + a_this->content.class_name->stryng->len); + + if (name) { + g_string_append_printf + (str_buf, ".%s", + name); + g_free (name); + name = NULL; + } + } + } + break; + + case ID_ADD_SELECTOR: + { + guchar *name = NULL; + + if (a_this->content.class_name) { + name = g_strndup + (a_this->content.id_name->stryng->str, + a_this->content.id_name->stryng->len); + + if (name) { + g_string_append_printf + (str_buf, "#%s", + name); + g_free (name); + name = NULL; + } + } + } + + break; + + case PSEUDO_CLASS_ADD_SELECTOR: + { + if (a_this->content.pseudo) { + guchar *tmp_str = NULL; + + tmp_str = cr_pseudo_to_string + (a_this->content.pseudo); + if (tmp_str) { + g_string_append_printf + (str_buf, ":%s", + tmp_str); + g_free (tmp_str); + tmp_str = NULL; + } + } + } + break; + + case ATTRIBUTE_ADD_SELECTOR: + if (a_this->content.attr_sel) { + guchar *tmp_str = NULL; + + g_string_append_printf (str_buf, "["); + tmp_str = cr_attr_sel_to_string + (a_this->content.attr_sel); + if (tmp_str) { + g_string_append_printf + (str_buf, "%s]", tmp_str); + g_free (tmp_str); + tmp_str = NULL; + } + } + break; + + default: + break; + } + + if (str_buf) { + result = str_buf->str; + g_string_free (str_buf, FALSE); + str_buf = NULL; + } + + return result; +} + +/** + *Dumps the current instance of #CRAdditionalSel to a file + *@param a_this the "this pointer" of the current instance of + *#CRAdditionalSel. + *@param a_fp the destination file. + */ +void +cr_additional_sel_dump (CRAdditionalSel * a_this, FILE * a_fp) +{ + guchar *tmp_str = NULL; + + g_return_if_fail (a_fp); + + if (a_this) { + tmp_str = cr_additional_sel_to_string (a_this); + if (tmp_str) { + fprintf (a_fp, "%s", tmp_str); + g_free (tmp_str); + tmp_str = NULL; + } + } +} + +/** + *Destroys an instance of #CRAdditional. + *@param a_this the "this pointer" of the current instance + *of #CRAdditionalSel . + */ +void +cr_additional_sel_destroy (CRAdditionalSel * a_this) +{ + g_return_if_fail (a_this); + + switch (a_this->type) { + case CLASS_ADD_SELECTOR: + cr_string_destroy (a_this->content.class_name); + a_this->content.class_name = NULL; + break; + + case PSEUDO_CLASS_ADD_SELECTOR: + cr_pseudo_destroy (a_this->content.pseudo); + a_this->content.pseudo = NULL; + break; + + case ID_ADD_SELECTOR: + cr_string_destroy (a_this->content.id_name); + a_this->content.id_name = NULL; + break; + + case ATTRIBUTE_ADD_SELECTOR: + cr_attr_sel_destroy (a_this->content.attr_sel); + a_this->content.attr_sel = NULL; + break; + + default: + break; + } + + if (a_this->next) { + cr_additional_sel_destroy (a_this->next); + } + + g_free (a_this); +} diff --git a/src/libcroco/cr-additional-sel.h b/src/libcroco/cr-additional-sel.h new file mode 100644 index 000000000..1ec1aa0ec --- /dev/null +++ b/src/libcroco/cr-additional-sel.h @@ -0,0 +1,112 @@ +/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * Author: Dodji Seketeli + * See the COPYRIGHTS file for copyright information. + */ + + +/** + *@file + *This file holds the declaration of the + *#CRAddSel class. + */ +#ifndef __CR_ADD_SEL_H__ +#define __CR_ADD_SEL_H__ + +#include +#include +#include "cr-utils.h" +#include "cr-attr-sel.h" +#include "cr-pseudo.h" +#include "cr-additional-sel.h" + +G_BEGIN_DECLS + +enum AddSelectorType +{ + NO_ADD_SELECTOR = 0 , + CLASS_ADD_SELECTOR = 1 , + PSEUDO_CLASS_ADD_SELECTOR = 1 << 1, + ID_ADD_SELECTOR = 1 << 3, + ATTRIBUTE_ADD_SELECTOR = 1 << 4 +} ; + +union CRAdditionalSelectorContent +{ + CRString *class_name ; + CRString *id_name ; + CRPseudo *pseudo ; + CRAttrSel *attr_sel ; +} ; + +typedef struct _CRAdditionalSel CRAdditionalSel ; + +/** + *#CRAdditionalSel abstracts + *an additionnal selector. + *An additional selector is the selector part + *that comes after the combination of type selectors. + *It can be either "a class selector (the .class part), + *a pseudo class selector, an attribute selector + *or an id selector. + */ +struct _CRAdditionalSel +{ + enum AddSelectorType type ; + union CRAdditionalSelectorContent content ; + + CRAdditionalSel * next ; + CRAdditionalSel * prev ; + CRParsingLocation location ; +} ; + +CRAdditionalSel * cr_additional_sel_new (void) ; + +CRAdditionalSel * cr_additional_sel_new_with_type (enum AddSelectorType a_sel_type) ; + +CRAdditionalSel * cr_additional_sel_append (CRAdditionalSel *a_this, + CRAdditionalSel *a_sel) ; + +void cr_additional_sel_set_class_name (CRAdditionalSel *a_this, + CRString *a_class_name) ; + +void cr_additional_sel_set_id_name (CRAdditionalSel *a_this, + CRString *a_id) ; + +void cr_additional_sel_set_pseudo (CRAdditionalSel *a_this, + CRPseudo *a_pseudo) ; + +void cr_additional_sel_set_attr_sel (CRAdditionalSel *a_this, + CRAttrSel *a_sel) ; + +CRAdditionalSel * cr_additional_sel_prepend (CRAdditionalSel *a_this, + CRAdditionalSel *a_sel) ; + +guchar * cr_additional_sel_to_string (CRAdditionalSel *a_this) ; + +guchar * cr_additional_sel_one_to_string (CRAdditionalSel *a_this) ; + +void cr_additional_sel_dump (CRAdditionalSel *a_this, FILE *a_fp) ; + +void cr_additional_sel_destroy (CRAdditionalSel *a_this) ; + +G_END_DECLS + +#endif /*__CR_ADD_SEL_H*/ diff --git a/src/libcroco/cr-attr-sel.c b/src/libcroco/cr-attr-sel.c new file mode 100644 index 000000000..cf048d102 --- /dev/null +++ b/src/libcroco/cr-attr-sel.c @@ -0,0 +1,221 @@ +/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * See COPYRIGHTS file for copyrights information. + */ + +#include +#include "cr-attr-sel.h" + +/** + *@file + *The class that abstracts an attribute selector. + *Attributes selectors are described in the css2 spec [5.8]. + *There are more generally used in the css2 selectors described in + *css2 spec [5] . + */ + +/** + *The constructor of #CRAttrSel. + *@return the newly allocated instance + *of #CRAttrSel. + */ +CRAttrSel * +cr_attr_sel_new (void) +{ + CRAttrSel *result = NULL; + + result = g_malloc0 (sizeof (CRAttrSel)); + + return result; +} + +/** + *Appends an attribute selector to the current list of + *attribute selectors represented by a_this. + * + *@param a_this the this pointer of the current instance of + *#CRAttrSel. + *@param a_attr_sel selector to append. + *@return CR_OK upon successfull completion, an error code otherwise. + */ +enum CRStatus +cr_attr_sel_append_attr_sel (CRAttrSel * a_this, CRAttrSel * a_attr_sel) +{ + CRAttrSel *cur_sel = NULL; + + g_return_val_if_fail (a_this && a_attr_sel, + CR_BAD_PARAM_ERROR); + + for (cur_sel = a_this; + cur_sel->next; + cur_sel = cur_sel->next) ; + + cur_sel->next = a_attr_sel; + a_attr_sel->prev = cur_sel; + + return CR_OK; +} + +/** + *Prepends an attribute selector to the list of + *attributes selector represented by a_this. + * + *@param a_this the "this pointer" of the current instance + *of #CRAttrSel. + *@param a_attr_sel the attribute selector to append. + *@return CR_OK upon successfull completion, an error code otherwise. + */ +enum CRStatus +cr_attr_sel_prepend_attr_sel (CRAttrSel * a_this, + CRAttrSel * a_attr_sel) +{ + g_return_val_if_fail (a_this && a_attr_sel, + CR_BAD_PARAM_ERROR); + + a_attr_sel->next = a_this; + a_this->prev = a_attr_sel; + + return CR_OK; +} + +guchar * +cr_attr_sel_to_string (CRAttrSel * a_this) +{ + CRAttrSel *cur = NULL; + guchar *result = NULL; + GString *str_buf = NULL; + + g_return_val_if_fail (a_this, NULL); + + str_buf = g_string_new (NULL); + + for (cur = a_this; cur; cur = cur->next) { + if (cur->prev) { + g_string_append_c (str_buf, ' '); + } + + if (cur->name) { + guchar *name = NULL; + + name = g_strndup (cur->name->stryng->str, + cur->name->stryng->len); + if (name) { + g_string_append (str_buf, name); + g_free (name); + name = NULL; + } + } + + if (cur->value) { + guchar *value = NULL; + + value = g_strndup (cur->value->stryng->str, + cur->value->stryng->len); + if (value) { + switch (cur->match_way) { + case SET: + break; + + case EQUALS: + g_string_append_c (str_buf, '='); + break; + + case INCLUDES: + g_string_append (str_buf, "~="); + break; + + case DASHMATCH: + g_string_append (str_buf, "|="); + break; + + default: + break; + } + + g_string_append_printf + (str_buf, "\"%s\"", value); + + g_free (value); + value = NULL; + } + } + } + + if (str_buf) { + result = str_buf->str; + g_string_free (str_buf, FALSE); + } + + return result; +} + +/** + *Dumps the current instance of #CRAttrSel to a file. + *@param a_this the "this pointer" of the current instance of + *#CRAttrSel. + *@param a_fp the destination file. + */ +void +cr_attr_sel_dump (CRAttrSel * a_this, FILE * a_fp) +{ + guchar *tmp_str = NULL; + + g_return_if_fail (a_this); + + tmp_str = cr_attr_sel_to_string (a_this); + + if (tmp_str) { + fprintf (a_fp, "%s", tmp_str); + g_free (tmp_str); + tmp_str = NULL; + } +} + +/** + *Destroys the current instance of #CRAttrSel. + *Frees all the fields if they are non null. + *@param a_this the "this pointer" of the current + *instance of #CRAttrSel. + */ +void +cr_attr_sel_destroy (CRAttrSel * a_this) +{ + g_return_if_fail (a_this); + + if (a_this->name) { + cr_string_destroy (a_this->name); + a_this->name = NULL; + } + + if (a_this->value) { + cr_string_destroy (a_this->value); + a_this->value = NULL; + } + + if (a_this->next) { + cr_attr_sel_destroy (a_this->next); + a_this->next = NULL; + } + + if (a_this) { + g_free (a_this); + a_this = NULL; + } +} diff --git a/src/libcroco/cr-attr-sel.h b/src/libcroco/cr-attr-sel.h new file mode 100644 index 000000000..9cc03d358 --- /dev/null +++ b/src/libcroco/cr-attr-sel.h @@ -0,0 +1,74 @@ +/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * Author: Dodji Seketeli + * See COPYRIGHTS file for copyright information. + */ + +#ifndef __CR_ATTR_SEL_H__ +#define __CR_ATTR_SEL_H__ + +#include +#include +#include "cr-utils.h" +#include "cr-parsing-location.h" +#include "cr-string.h" + +G_BEGIN_DECLS + + +struct _CRAttrSel ; +typedef struct _CRAttrSel CRAttrSel ; + +enum AttrMatchWay +{ + NO_MATCH = 0, + SET, + EQUALS, + INCLUDES, + DASHMATCH +} ; + +struct _CRAttrSel +{ + CRString *name ; + CRString *value ; + enum AttrMatchWay match_way ; + CRAttrSel *next ; + CRAttrSel *prev ; + CRParsingLocation location ; +} ; + +CRAttrSel * cr_attr_sel_new (void) ; + +enum CRStatus cr_attr_sel_append_attr_sel (CRAttrSel * a_this, + CRAttrSel *a_new) ; + +enum CRStatus cr_attr_sel_prepend_attr_sel (CRAttrSel *a_this, + CRAttrSel *a_attr_sel) ; + +guchar * cr_attr_sel_to_string (CRAttrSel *a_this) ; + +void cr_attr_sel_dump (CRAttrSel *a_this, FILE *a_fp) ; + +void cr_attr_sel_destroy (CRAttrSel *a_this) ; + +G_END_DECLS + +#endif /*__CR_ATTR_SEL_H__*/ diff --git a/src/libcroco/cr-cascade.c b/src/libcroco/cr-cascade.c new file mode 100644 index 000000000..51c6df5ac --- /dev/null +++ b/src/libcroco/cr-cascade.c @@ -0,0 +1,197 @@ +/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */ + +/* + * This file is part of The Croco Library + * + * Copyright (C) 2002-2003 Dodji Seketeli + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the + * GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the + * GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + +/* + *$Id: cr-cascade.c,v 1.6 2004/03/07 13:22:47 dodji Exp $ + */ + +#include +#include "cr-cascade.h" + +#define PRIVATE(a_this) ((a_this)->priv) + +struct _CRCascadePriv { + /** + *the 3 style sheets of the cascade: + *author, user, and useragent sheet. + *Intended to be addressed by + *sheets[ORIGIN_AUTHOR] or sheets[ORIGIN_USER] + *of sheets[ORIGIN_UA] ; + */ + CRStyleSheet *sheets[3]; + guint ref_count; +}; + +/** + *Constructor of the #CRCascade class. + *Note that all three parameters of this + *method are ref counted and their refcount is increased. + *Their refcount will be decreased at the destruction of + *the instance of #CRCascade. + *So the caller should not call their destructor. The caller + *should call their ref/unref method instead if it wants + *@param a_author_sheet the autor origin style sheet + *@param a_user_sheet the user origin style sheet. + *@param a_ua_sheet the user agent origin style sheet. + *@return the newly built instance of CRCascade or NULL if + *an error arose during constrution. + */ +CRCascade * +cr_cascade_new (CRStyleSheet * a_author_sheet, + CRStyleSheet * a_user_sheet, CRStyleSheet * a_ua_sheet) +{ + CRCascade *result = NULL; + + result = g_try_malloc (sizeof (CRCascade)); + if (!result) { + cr_utils_trace_info ("Out of memory"); + return NULL; + } + memset (result, 0, sizeof (CRCascade)); + + PRIVATE (result) = g_try_malloc (sizeof (CRCascadePriv)); + if (!PRIVATE (result)) { + cr_utils_trace_info ("Out of memory"); + return NULL; + } + memset (PRIVATE (result), 0, sizeof (CRCascadePriv)); + + if (a_author_sheet) { + cr_cascade_set_sheet (result, a_author_sheet, ORIGIN_AUTHOR); + } + if (a_user_sheet) { + cr_cascade_set_sheet (result, a_user_sheet, ORIGIN_USER); + } + if (a_ua_sheet) { + cr_cascade_set_sheet (result, a_ua_sheet, ORIGIN_UA); + } + + return result; +} + +/** + *Gets a given origin sheet. + *Note that the returned stylesheet + *is refcounted so if the caller wants + *to manage its lifecycle, it must use + *cr_stylesheet_ref()/cr_stylesheet_unref() instead + *of the cr_stylesheet_destroy() method. + *@param a_this the current instance of #CRCascade. + *@param a_origin the origin of the style sheet as + *defined in the css2 spec in chapter 6.4. + *@return the style sheet, or NULL if it does not + *exist. + */ +CRStyleSheet * +cr_cascade_get_sheet (CRCascade * a_this, enum CRStyleOrigin a_origin) +{ + g_return_val_if_fail (a_this + && (unsigned)a_origin < NB_ORIGINS, NULL); + + return PRIVATE (a_this)->sheets[a_origin]; +} + +/** + *Sets a stylesheet in the cascade + *@param a_this the current instance of #CRCascade. + *@param a_sheet the stylesheet to set. + *@param a_origin the origin of the stylesheet. + *@return CR_OK upon successfull completion, an error + *code otherwise. + */ +enum CRStatus +cr_cascade_set_sheet (CRCascade * a_this, + CRStyleSheet * a_sheet, enum CRStyleOrigin a_origin) +{ + g_return_val_if_fail (a_this + && a_sheet + && (unsigned)a_origin < NB_ORIGINS, CR_BAD_PARAM_ERROR); + + if (PRIVATE (a_this)->sheets[a_origin]) + cr_stylesheet_unref (PRIVATE (a_this)->sheets[a_origin]); + PRIVATE (a_this)->sheets[a_origin] = a_sheet; + cr_stylesheet_ref (a_sheet); + a_sheet->origin = a_origin; + return CR_OK; +} + +/** + *Increases the reference counter of the current instance + *of #CRCascade. + *@param a_this the current instance of #CRCascade + * + */ +void +cr_cascade_ref (CRCascade * a_this) +{ + g_return_if_fail (a_this && PRIVATE (a_this)); + + PRIVATE (a_this)->ref_count++; +} + +/** + *Decrements the reference counter associated + *to this instance of #CRCascade. If the reference + *counter reaches zero, the instance is destroyed + *using cr_cascade_destroy() + *@param a_this the current instance of + *#CRCascade. + */ +void +cr_cascade_unref (CRCascade * a_this) +{ + g_return_if_fail (a_this && PRIVATE (a_this)); + + if (PRIVATE (a_this)->ref_count) + PRIVATE (a_this)->ref_count--; + if (!PRIVATE (a_this)->ref_count) { + cr_cascade_destroy (a_this); + } +} + +/** + *Destructor of #CRCascade. + */ +void +cr_cascade_destroy (CRCascade * a_this) +{ + g_return_if_fail (a_this); + + if (PRIVATE (a_this)) { + gulong i = 0; + + for (i = 0; PRIVATE (a_this)->sheets && i < NB_ORIGINS; i++) { + if (PRIVATE (a_this)->sheets[i]) { + if (cr_stylesheet_unref + (PRIVATE (a_this)->sheets[i]) + == TRUE) { + PRIVATE (a_this)->sheets[i] = NULL; + } + } + } + g_free (PRIVATE (a_this)); + PRIVATE (a_this) = NULL; + } + g_free (a_this); +} diff --git a/src/libcroco/cr-cascade.h b/src/libcroco/cr-cascade.h new file mode 100644 index 000000000..5e718427d --- /dev/null +++ b/src/libcroco/cr-cascade.h @@ -0,0 +1,74 @@ +/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the + * GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the + * GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + */ + +/* + *$Id: cr-cascade.h,v 1.6 2004/01/29 22:05:14 dodji Exp $ + */ + +#ifndef __CR_CASCADE_H__ +#define __CR_CASCADE_H__ + +#include "cr-stylesheet.h" + +/** + *@file + *the declaration of the #CRCascade class. + */ + +G_BEGIN_DECLS + + +typedef struct _CRCascadePriv CRCascadePriv ; + +/** + *An abstraction of the "Cascade" defined + *in the css2 spec, chapter 6.4. + */ +typedef struct _CRCascade CRCascade ; + +struct _CRCascade +{ + CRCascadePriv *priv ; +}; + + +CRCascade * cr_cascade_new (CRStyleSheet *a_author_sheet, + CRStyleSheet *a_user_sheet, + CRStyleSheet *a_ua_sheet) ; + +CRStyleSheet * cr_cascade_get_sheet (CRCascade *a_this, + enum CRStyleOrigin a_origin) ; + +enum CRStatus cr_cascade_set_sheet (CRCascade *a_this, + CRStyleSheet *a_sheet, + enum CRStyleOrigin a_origin) ; + +void cr_cascade_ref (CRCascade *a_this) ; + +void cr_cascade_unref (CRCascade *a_this) ; + +void cr_cascade_destroy (CRCascade *a_this) ; + +G_END_DECLS + +#endif /*__CR_CASCADE_H__*/ diff --git a/src/libcroco/cr-declaration.c b/src/libcroco/cr-declaration.c new file mode 100644 index 000000000..a1ff0d292 --- /dev/null +++ b/src/libcroco/cr-declaration.c @@ -0,0 +1,775 @@ +/* -*- Mode: C; indent-tabs-mode: ni; c-basic-offset: 8 -*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * Author: Dodji Seketeli. + * See COPYRIGHTS file for copyright information. + */ + + +#include +#include "cr-declaration.h" +#include "cr-statement.h" +#include "cr-parser.h" + +/** + *@file + *The definition of the #CRDeclaration class. + */ + +/** + *Dumps (serializes) one css declaration to a file. + *@param a_this the current instance of #CRDeclaration. + *@param a_fp the destination file pointer. + *@param a_indent the number of indentation white char. + */ +static void +dump (CRDeclaration * a_this, FILE * a_fp, glong a_indent) +{ + guchar *str = NULL; + + g_return_if_fail (a_this); + + str = cr_declaration_to_string (a_this, a_indent); + if (str) { + fprintf (a_fp, "%s", str); + g_free (str); + str = NULL; + } +} + +/** + *Constructor of #CRDeclaration. + *@param a_property the property string of the declaration + *@param a_value the value expression of the declaration. + *@return the newly built instance of #CRDeclaration, or NULL in + *case of error. + */ +CRDeclaration * +cr_declaration_new (CRStatement * a_statement, + CRString * a_property, CRTerm * a_value) +{ + CRDeclaration *result = NULL; + + g_return_val_if_fail (a_property, NULL); + + if (a_statement) + g_return_val_if_fail (a_statement + && ((a_statement->type == RULESET_STMT) + || (a_statement->type + == AT_FONT_FACE_RULE_STMT) + || (a_statement->type + == AT_PAGE_RULE_STMT)), NULL); + + result = g_try_malloc (sizeof (CRDeclaration)); + if (!result) { + cr_utils_trace_info ("Out of memory"); + return NULL; + } + memset (result, 0, sizeof (CRDeclaration)); + result->property = a_property; + result->value = a_value; + + if (a_value) { + cr_term_ref (a_value); + } + result->parent_statement = a_statement; + return result; +} + +/** + *Parses a text buffer that contains + *a css declaration. + * + *@param a_statement the parent css2 statement of this + *this declaration. Must be non NULL and of type + *RULESET_STMT (must be a ruleset). + *@param a_str the string that contains the statement. + *@param a_enc the encoding of a_str. + *@return the parsed declaration, or NULL in case of error. + */ +CRDeclaration * +cr_declaration_parse_from_buf (CRStatement * a_statement, + const guchar * a_str, enum CREncoding a_enc) +{ + enum CRStatus status = CR_OK; + CRTerm *value = NULL; + CRString *property = NULL; + CRDeclaration *result = NULL; + CRParser *parser = NULL; + gboolean important = FALSE; + + g_return_val_if_fail (a_str, NULL); + if (a_statement) + g_return_val_if_fail (a_statement->type == RULESET_STMT, + NULL); + + parser = cr_parser_new_from_buf ((guchar*)a_str, strlen (a_str), a_enc, FALSE); + g_return_val_if_fail (parser, NULL); + + status = cr_parser_try_to_skip_spaces_and_comments (parser); + if (status != CR_OK) + goto cleanup; + + status = cr_parser_parse_declaration (parser, &property, + &value, &important); + if (status != CR_OK || !property) + goto cleanup; + + result = cr_declaration_new (a_statement, property, value); + if (result) { + property = NULL; + value = NULL; + result->important = important; + } + + cleanup: + + if (parser) { + cr_parser_destroy (parser); + parser = NULL; + } + + if (property) { + cr_string_destroy (property); + property = NULL; + } + + if (value) { + cr_term_destroy (value); + value = NULL; + } + + return result; +} + +/** + *Parses a ';' separated list of properties declaration. + *@param a_str the input buffer that contains the list of declaration to + *parse. + *@param a_enc the encoding of a_str + *@return the parsed list of declaration, NULL if parsing failed. + */ +CRDeclaration * +cr_declaration_parse_list_from_buf (const guchar * a_str, + enum CREncoding a_enc) +{ + + enum CRStatus status = CR_OK; + CRTerm *value = NULL; + CRString *property = NULL; + CRDeclaration *result = NULL, + *cur_decl = NULL; + CRParser *parser = NULL; + CRTknzr *tokenizer = NULL; + gboolean important = FALSE; + + g_return_val_if_fail (a_str, NULL); + + parser = cr_parser_new_from_buf ((guchar*)a_str, strlen (a_str), a_enc, FALSE); + g_return_val_if_fail (parser, NULL); + status = cr_parser_get_tknzr (parser, &tokenizer); + if (status != CR_OK || !tokenizer) { + if (status == CR_OK) + status = CR_ERROR; + goto cleanup; + } + status = cr_parser_try_to_skip_spaces_and_comments (parser); + if (status != CR_OK) + goto cleanup; + + status = cr_parser_parse_declaration (parser, &property, + &value, &important); + if (status != CR_OK || !property) { + if (status != CR_OK) + status = CR_ERROR; + goto cleanup; + } + result = cr_declaration_new (NULL, property, value); + if (result) { + property = NULL; + value = NULL; + result->important = important; + } + /*now, go parse the other declarations */ + for (;;) { + guint32 c = 0; + + cr_parser_try_to_skip_spaces_and_comments (parser); + status = cr_tknzr_peek_char (tokenizer, &c); + if (status != CR_OK) { + if (status == CR_END_OF_INPUT_ERROR) + status = CR_OK; + goto cleanup; + } + if (c == ';') { + status = cr_tknzr_read_char (tokenizer, &c); + } else { + break; + } + important = FALSE; + cr_parser_try_to_skip_spaces_and_comments (parser); + status = cr_parser_parse_declaration (parser, &property, + &value, &important); + if (status != CR_OK || !property) { + if (status == CR_END_OF_INPUT_ERROR) { + status = CR_OK; + } + break; + } + cur_decl = cr_declaration_new (NULL, property, value); + if (cur_decl) { + cur_decl->important = important; + result = cr_declaration_append (result, cur_decl); + property = NULL; + value = NULL; + cur_decl = NULL; + } else { + break; + } + } + + cleanup: + + if (parser) { + cr_parser_destroy (parser); + parser = NULL; + } + + if (property) { + cr_string_destroy (property); + property = NULL; + } + + if (value) { + cr_term_destroy (value); + value = NULL; + } + + if (status != CR_OK && result) { + cr_declaration_destroy (result); + result = NULL; + } + return result; +} + +/** + *Appends a new declaration to the current declarations list. + *@param a_this the current declaration list. + *@param a_new the declaration to append. + *@return the declaration list with a_new appended to it, or NULL + *in case of error. + */ +CRDeclaration * +cr_declaration_append (CRDeclaration * a_this, CRDeclaration * a_new) +{ + CRDeclaration *cur = NULL; + + g_return_val_if_fail (a_new, NULL); + + if (!a_this) + return a_new; + + for (cur = a_this; cur && cur->next; cur = cur->next) ; + + cur->next = a_new; + a_new->prev = cur; + + return a_this; +} + +/** + *Unlinks the declaration from the declaration list. + *@param a_decl the declaration to unlink. + *@return a pointer to the unlinked declaration in + *case of a successfull completion, NULL otherwise. + */ +CRDeclaration * +cr_declaration_unlink (CRDeclaration * a_decl) +{ + CRDeclaration *result = a_decl; + + g_return_val_if_fail (result, NULL); + + /* + *some sanity checks first + */ + if (a_decl->prev) { + g_return_val_if_fail (a_decl->prev->next == a_decl, NULL); + + } + if (a_decl->next) { + g_return_val_if_fail (a_decl->next->prev == a_decl, NULL); + } + + /* + *now, the real unlinking job. + */ + if (a_decl->prev) { + a_decl->prev->next = a_decl->next; + } + if (a_decl->next) { + a_decl->next->prev = a_decl->prev; + } + if (a_decl->parent_statement) { + CRDeclaration **children_decl_ptr = NULL; + + switch (a_decl->parent_statement->type) { + case RULESET_STMT: + if (a_decl->parent_statement->kind.ruleset) { + children_decl_ptr = + &a_decl->parent_statement-> + kind.ruleset->decl_list; + } + + break; + + case AT_FONT_FACE_RULE_STMT: + if (a_decl->parent_statement->kind.font_face_rule) { + children_decl_ptr = + &a_decl->parent_statement-> + kind.font_face_rule->decl_list; + } + break; + case AT_PAGE_RULE_STMT: + if (a_decl->parent_statement->kind.page_rule) { + children_decl_ptr = + &a_decl->parent_statement-> + kind.page_rule->decl_list; + } + + default: + break; + } + if (children_decl_ptr + && *children_decl_ptr && *children_decl_ptr == a_decl) + *children_decl_ptr = (*children_decl_ptr)->next; + } + + a_decl->next = NULL; + a_decl->prev = NULL; + a_decl->parent_statement = NULL; + + return result; +} + +/** + *prepends a declaration to the current declaration list. + *@param a_this the current declaration list. + *@param a_new the declaration to prepend. + *@return the list with a_new prepended or NULL in case of error. + */ +CRDeclaration * +cr_declaration_prepend (CRDeclaration * a_this, CRDeclaration * a_new) +{ + CRDeclaration *cur = NULL; + + g_return_val_if_fail (a_new, NULL); + + if (!a_this) + return a_new; + + a_this->prev = a_new; + a_new->next = a_this; + + for (cur = a_new; cur && cur->prev; cur = cur->prev) ; + + return cur; +} + +/** + *Appends a declaration to the current declaration list. + *@param a_this the current declaration list. + *@param a_prop the property string of the declaration to append. + *@param a_value the value of the declaration to append. + *@return the list with the new property appended to it, or NULL in + *case of an error. + */ +CRDeclaration * +cr_declaration_append2 (CRDeclaration * a_this, + CRString * a_prop, CRTerm * a_value) +{ + CRDeclaration *new_elem = NULL; + + if (a_this) { + new_elem = cr_declaration_new (a_this->parent_statement, + a_prop, a_value); + } else { + new_elem = cr_declaration_new (NULL, a_prop, a_value); + } + + g_return_val_if_fail (new_elem, NULL); + + return cr_declaration_append (a_this, new_elem); +} + +/** + *Dumps a declaration list to a file. + *@param a_this the current instance of #CRDeclaration. + *@param a_fp the destination file. + *@param a_indent the number of indentation white char. + */ +void +cr_declaration_dump (CRDeclaration * a_this, FILE * a_fp, glong a_indent, + gboolean a_one_per_line) +{ + CRDeclaration *cur = NULL; + + g_return_if_fail (a_this); + + for (cur = a_this; cur; cur = cur->next) { + if (cur->prev) { + if (a_one_per_line == TRUE) + fprintf (a_fp, ";\n"); + else + fprintf (a_fp, "; "); + } + dump (cur, a_fp, a_indent); + } +} + +/** + *Dumps the first declaration of the declaration list to a file. + *@param a_this the current instance of #CRDeclaration. + *@param a_fp the destination file. + *@param a_indent the number of indentation white char. + */ +void +cr_declaration_dump_one (CRDeclaration * a_this, FILE * a_fp, glong a_indent) +{ + g_return_if_fail (a_this); + + dump (a_this, a_fp, a_indent); +} + +/** + *Serializes the declaration into a string + *@param a_this the current instance of #CRDeclaration. + *@param a_indent the number of indentation white char + *to put before the actual serialisation. + */ +gchar * +cr_declaration_to_string (CRDeclaration * a_this, gulong a_indent) +{ + GString *stringue = NULL; + + guchar *str = NULL, + *result = NULL; + + g_return_val_if_fail (a_this, NULL); + + stringue = g_string_new (NULL); + + if (a_this->property + && a_this->property->stryng + && a_this->property->stryng->str) { + str = g_strndup (a_this->property->stryng->str, + a_this->property->stryng->len); + if (str) { + cr_utils_dump_n_chars2 (' ', stringue, + a_indent); + g_string_append (stringue, str); + g_free (str); + str = NULL; + } else + goto error; + + if (a_this->value) { + guchar *value_str = NULL; + + value_str = cr_term_to_string (a_this->value); + if (value_str) { + g_string_append_printf (stringue, " : %s", + value_str); + g_free (value_str); + } else + goto error; + } + if (a_this->important == TRUE) { + g_string_append_printf (stringue, " %s", + "!important"); + } + } + if (stringue && stringue->str) { + result = stringue->str; + g_string_free (stringue, FALSE); + } + return result; + + error: + if (stringue) { + g_string_free (stringue, TRUE); + stringue = NULL; + } + if (str) { + g_free (str); + str = NULL; + } + + return result; +} + +/** + *Serializes the declaration list into a string + *@param a_this the current instance of #CRDeclaration. + *@param a_indent the number of indentation white char + *to put before the actual serialisation. + */ +guchar * +cr_declaration_list_to_string (CRDeclaration * a_this, gulong a_indent) +{ + CRDeclaration *cur = NULL; + GString *stringue = NULL; + guchar *str = NULL, + *result = NULL; + + g_return_val_if_fail (a_this, NULL); + + stringue = g_string_new (NULL); + + for (cur = a_this; cur; cur = cur->next) { + str = cr_declaration_to_string (cur, a_indent); + if (str) { + g_string_append_printf (stringue, "%s;", str); + g_free (str); + } else + break; + } + if (stringue && stringue->str) { + result = stringue->str; + g_string_free (stringue, FALSE); + } + + return result; +} + +/** + *Serializes the declaration list into a string + *@param a_this the current instance of #CRDeclaration. + *@param a_indent the number of indentation white char + *to put before the actual serialisation. + */ +guchar * +cr_declaration_list_to_string2 (CRDeclaration * a_this, + gulong a_indent, gboolean a_one_decl_per_line) +{ + CRDeclaration *cur = NULL; + GString *stringue = NULL; + guchar *str = NULL, + *result = NULL; + + g_return_val_if_fail (a_this, NULL); + + stringue = g_string_new (NULL); + + for (cur = a_this; cur; cur = cur->next) { + str = cr_declaration_to_string (cur, a_indent); + if (str) { + if (a_one_decl_per_line == TRUE) { + if (cur->next) + g_string_append_printf (stringue, + "%s;\n", str); + else + g_string_append (stringue, + str); + } else { + if (cur->next) + g_string_append_printf (stringue, + "%s;", str); + else + g_string_append (stringue, + str); + } + g_free (str); + } else + break; + } + if (stringue && stringue->str) { + result = stringue->str; + g_string_free (stringue, FALSE); + } + + return result; +} + +/** + *Return the number of properties in the declaration; + *@param a_this the current instance of #CRDeclaration. + *@return number of properties in the declaration list. + */ +gint +cr_declaration_nr_props (CRDeclaration * a_this) +{ + CRDeclaration *cur = NULL; + int nr = 0; + + g_return_val_if_fail (a_this, -1); + + for (cur = a_this; cur; cur = cur->next) + nr++; + return nr; +} + +/** + *Use an index to get a CRDeclaration from the declaration list. + *@param a_this the current instance of #CRDeclaration. + *@param itemnr the index into the declaration list. + *@return CRDeclaration at position itemnr, if itemnr > number of declarations - 1, + *it will return NULL. + */ +CRDeclaration * +cr_declaration_get_from_list (CRDeclaration * a_this, int itemnr) +{ + CRDeclaration *cur = NULL; + int nr = 0; + + g_return_val_if_fail (a_this, NULL); + + for (cur = a_this; cur; cur = cur->next) + if (nr++ == itemnr) + return cur; + return NULL; +} + +/** + *Use property name to get a CRDeclaration from the declaration list. + *@param a_this the current instance of #CRDeclaration. + *@param a_prop the property name to search for. + *@return CRDeclaration with property name a_prop, or NULL if not found. + */ +CRDeclaration * +cr_declaration_get_by_prop_name (CRDeclaration * a_this, + const guchar * a_prop) +{ + CRDeclaration *cur = NULL; + + g_return_val_if_fail (a_this, NULL); + g_return_val_if_fail (a_prop, NULL); + + for (cur = a_this; cur; cur = cur->next) { + if (cur->property + && cur->property->stryng + && cur->property->stryng->str) { + if (!strcmp (cur->property->stryng->str, + a_prop)) { + return cur; + } + } + } + return NULL; +} + +/** + *Increases the ref count of the current instance of #CRDeclaration. + *@param a_this the current instance of #CRDeclaration. + */ +void +cr_declaration_ref (CRDeclaration * a_this) +{ + g_return_if_fail (a_this); + + a_this->ref_count++; +} + +/** + *Decrements the ref count of the current instance of #CRDeclaration. + *If the ref count reaches zero, the current instance of #CRDeclaration + *if destroyed. + *@param a_this the current instance of #CRDeclaration. + *@return TRUE if the current instance of #CRDeclaration has been destroyed + *(ref count reached zero), FALSE otherwise. + */ +gboolean +cr_declaration_unref (CRDeclaration * a_this) +{ + g_return_val_if_fail (a_this, FALSE); + + if (a_this->ref_count) { + a_this->ref_count--; + } + + if (a_this->ref_count == 0) { + cr_declaration_destroy (a_this); + return TRUE; + } + return FALSE; +} + +/** + *Destructor of the declaration list. + *@param a_this the current instance of #CRDeclaration. + */ +void +cr_declaration_destroy (CRDeclaration * a_this) +{ + CRDeclaration *cur = NULL; + + g_return_if_fail (a_this); + + /* + *Go get the tail of the list. + *Meanwhile, free each property/value pair contained in the list. + */ + for (cur = a_this; cur && cur->next; cur = cur->next) { + if (cur->property) { + cr_string_destroy (cur->property); + cur->property = NULL; + } + + if (cur->value) { + cr_term_destroy (cur->value); + cur->value = NULL; + } + } + + if (cur) { + if (cur->property) { + cr_string_destroy (cur->property); + cur->property = NULL; + } + + if (cur->value) { + cr_term_destroy (cur->value); + cur->value = NULL; + } + } + + /*in case the list contains only one element */ + if (cur && !cur->prev) { + g_free (cur); + return; + } + + /*walk backward the list and free each "next" element */ + for (cur = cur->prev; cur && cur->prev; cur = cur->prev) { + if (cur->next) { + g_free (cur->next); + cur->next = NULL; + } + } + + if (!cur) + return; + + if (cur->next) { + g_free (cur->next); + cur->next = NULL; + } + + g_free (cur); +} diff --git a/src/libcroco/cr-declaration.h b/src/libcroco/cr-declaration.h new file mode 100644 index 000000000..00523956c --- /dev/null +++ b/src/libcroco/cr-declaration.h @@ -0,0 +1,136 @@ +/* -*- Mode: C; indent-tabs-mode: ni; c-basic-offset: 8 -*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * See the COPYRIGHTS file for copyright information. + */ + +#ifndef __CR_DECLARATION_H__ +#define __CR_DECLARATION_H__ + +#include +#include "cr-utils.h" +#include "cr-term.h" +#include "cr-parsing-location.h" + +G_BEGIN_DECLS + +/** + *@file + *The declaration of the #CRDeclaration class. + */ + +/*forward declaration of what is defined in cr-statement.h*/ +typedef struct _CRStatement CRStatement ; + +/** + *The abstraction of a css declaration defined by the + *css2 spec in chapter 4. + *It is actually a chained list of property/value pairs. + */ +typedef struct _CRDeclaration CRDeclaration ; +struct _CRDeclaration +{ + /**The property.*/ + CRString *property ; + + /**The value of the property.*/ + CRTerm *value ; + + /*the ruleset that contains this declaration*/ + CRStatement *parent_statement ; + + /*the next declaration*/ + CRDeclaration *next ; + + /*the previous one declaration*/ + CRDeclaration *prev ; + + /*does the declaration have the important keyword ?*/ + gboolean important ; + + glong ref_count ; + + CRParsingLocation location ; + /*reserved for future usage*/ + gpointer rfu0 ; + gpointer rfu1 ; + gpointer rfu2 ; + gpointer rfu3 ; +} ; + + +CRDeclaration * cr_declaration_new (CRStatement *a_statement, + CRString *a_property, + CRTerm *a_value) ; + + +CRDeclaration * cr_declaration_parse_from_buf (CRStatement *a_statement, + const guchar *a_str, + enum CREncoding a_enc) ; + +CRDeclaration * cr_declaration_parse_list_from_buf (const guchar *a_str, + enum CREncoding a_enc) ; + +CRDeclaration * cr_declaration_append (CRDeclaration *a_this, + CRDeclaration *a_new) ; + +CRDeclaration * cr_declaration_append2 (CRDeclaration *a_this, + CRString *a_prop, + CRTerm *a_value) ; + +CRDeclaration * cr_declaration_prepend (CRDeclaration *a_this, + CRDeclaration *a_new) ; + +CRDeclaration * cr_declaration_unlink (CRDeclaration * a_decl) ; + +void +cr_declaration_dump (CRDeclaration *a_this, + FILE *a_fp, glong a_indent, + gboolean a_one_per_line) ; + +void cr_declaration_dump_one (CRDeclaration *a_this, + FILE *a_fp, glong a_indent) ; + +gint cr_declaration_nr_props (CRDeclaration *a_this) ; + +CRDeclaration * cr_declaration_get_from_list (CRDeclaration *a_this, + int itemnr) ; + +CRDeclaration * cr_declaration_get_by_prop_name (CRDeclaration *a_this, + const guchar *a_str) ; + +gchar * cr_declaration_to_string (CRDeclaration *a_this, + gulong a_indent) ; + +guchar * cr_declaration_list_to_string (CRDeclaration *a_this, + gulong a_indent) ; + +guchar * cr_declaration_list_to_string2 (CRDeclaration *a_this, + gulong a_indent, + gboolean a_one_decl_per_line) ; + +void cr_declaration_ref (CRDeclaration *a_this) ; + +gboolean cr_declaration_unref (CRDeclaration *a_this) ; + +void cr_declaration_destroy (CRDeclaration *a_this) ; + +G_END_DECLS + +#endif /*__CR_DECLARATION_H__*/ diff --git a/src/libcroco/cr-doc-handler.c b/src/libcroco/cr-doc-handler.c new file mode 100644 index 000000000..2780b6a20 --- /dev/null +++ b/src/libcroco/cr-doc-handler.c @@ -0,0 +1,252 @@ +/* -*- Mode: C; indent-tabs-mode: ni; c-basic-offset: 8 -*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * See COPRYRIGHTS file for copyright information. + */ + +#include +#include "cr-doc-handler.h" +#include "cr-parser.h" + +/** + *@file + *The definition of the CRDocHandler class. + *Contains methods to instantiate, destroy, + *and initialyze instances of #CRDocHandler + *to custom values. + */ + +#define PRIVATE(obj) (obj)->priv + +struct _CRDocHandlerPriv { + /** + *This pointer is to hold an application parsing context. + *For example, it used by the Object Model parser to + *store it parsing context. #CRParser does not touch it, but + *#CROMParser does. #CROMParser allocates this pointer at + *the beginning of the css document, and frees it at the end + *of the document. + */ + gpointer context; + + /** + *The place where #CROMParser puts the result of its parsing, if + *any. + */ + gpointer result; + /** + *a pointer to the parser used to parse + *the current document. + */ + CRParser *parser ; +}; + +/** + *Constructor of #CRDocHandler. + *@return the newly built instance of + *#CRDocHandler + */ +CRDocHandler * +cr_doc_handler_new (void) +{ + CRDocHandler *result = NULL; + + result = g_try_malloc (sizeof (CRDocHandler)); + + g_return_val_if_fail (result, NULL); + + memset (result, 0, sizeof (CRDocHandler)); + + result->priv = g_try_malloc (sizeof (CRDocHandlerPriv)); + if (!result->priv) { + cr_utils_trace_info ("Out of memory exception"); + g_free (result); + return NULL; + } + + cr_doc_handler_set_default_sac_handler (result); + + return result; +} + +/** + *Returns the private parsing context. + *The private parsing context is used by libcroco only. + *@param a_this the current instance of #CRDocHandler. + *@param a_ctxt out parameter. The new parsing context. + *@return CR_OK upon successfull completion, an error code otherwise. + *@return the parsing context, or NULL if an error occured. + */ +enum CRStatus +cr_doc_handler_get_ctxt (CRDocHandler * a_this, gpointer * a_ctxt) +{ + g_return_val_if_fail (a_this && a_this->priv, CR_BAD_PARAM_ERROR); + + *a_ctxt = a_this->priv->context; + + return CR_OK; +} + +/** + *Sets the private parsing context. + *This is used by libcroco only. + *@param a_this the current instance of #CRDocHandler + *@param a_ctxt a pointer to the parsing context. + *@return CR_OK upon successfull completion, an error code otherwise. + */ +enum CRStatus +cr_doc_handler_set_ctxt (CRDocHandler * a_this, gpointer a_ctxt) +{ + g_return_val_if_fail (a_this && a_this->priv, CR_BAD_PARAM_ERROR); + a_this->priv->context = a_ctxt; + return CR_OK; +} + +/** + *Returns the private parsing result. + *The private parsing result is used by libcroco only. + *@param a_this the current instance of #CRDocHandler + *@param a_result out parameter. The returned result. + *@return CR_OK upon successfull completion, an error code otherwise. + */ +enum CRStatus +cr_doc_handler_get_result (CRDocHandler * a_this, gpointer * a_result) +{ + g_return_val_if_fail (a_this && a_this->priv, CR_BAD_PARAM_ERROR); + + *a_result = a_this->priv->result; + + return CR_OK; +} + +/** + *Sets the private parsing context. + *This is used by libcroco only. + *@param a_this the current instance of #CRDocHandler + *@param a_result the new result. + *@return CR_OK upon successfull completion, an error code otherwise. + */ +enum CRStatus +cr_doc_handler_set_result (CRDocHandler * a_this, gpointer a_result) +{ + g_return_val_if_fail (a_this && a_this->priv, CR_BAD_PARAM_ERROR); + a_this->priv->result = a_result; + return CR_OK; +} + +/** + *Sets the sac handlers contained in the current + *instance of DocHandler to the default handlers. + *For the time being the default handlers are + *test handlers. This is expected to change in a + *near future, when the libcroco gets a bit debugged. + * + *@param a_this a pointer to the current instance of #CRDocHandler. + *@return CR_OK upon successfull completion, an error code otherwise. + */ +enum CRStatus +cr_doc_handler_set_default_sac_handler (CRDocHandler * a_this) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + a_this->start_document = NULL; + a_this->end_document = NULL; + a_this->import_style = NULL; + a_this->namespace_declaration = NULL; + a_this->comment = NULL; + a_this->start_selector = NULL; + a_this->end_selector = NULL; + a_this->property = NULL; + a_this->start_font_face = NULL; + a_this->end_font_face = NULL; + a_this->start_media = NULL; + a_this->end_media = NULL; + a_this->start_page = NULL; + a_this->end_page = NULL; + a_this->ignorable_at_rule = NULL; + a_this->error = NULL; + a_this->unrecoverable_error = NULL; + return CR_OK; +} + +/** + *Increases the reference count of the doc handler + *@param a_this the current instance of #CRDocHandler. + */ +void +cr_doc_handler_ref (CRDocHandler * a_this) +{ + g_return_if_fail (a_this); + + a_this->ref_count++; +} + +/** + *Decreases the ref count of the current instance of #CRDocHandler. + *If the ref count reaches '0' then, destroys the instance. + *@param a_this the currrent instance of #CRDocHandler. + *@return TRUE if the instance as been destroyed, FALSE otherwise. + */ +gboolean +cr_doc_handler_unref (CRDocHandler * a_this) +{ + g_return_val_if_fail (a_this, FALSE); + + if (a_this->ref_count > 0) { + a_this->ref_count--; + } + + if (a_this->ref_count == 0) { + cr_doc_handler_destroy (a_this); + return TRUE; + } + return FALSE ; +} + +/** + *The destructor of the #CRDocHandler class. + *@param a_this the instance of #CRDocHandler to + *destroy. + */ +void +cr_doc_handler_destroy (CRDocHandler * a_this) +{ + g_return_if_fail (a_this); + + if (a_this->priv) { + g_free (a_this->priv); + a_this->priv = NULL; + } + g_free (a_this); +} + +/** + *Associates a parser to the current document handler + *@param a_this the current instance of document handler. + *@param a_parser the parser to associate. + */ +void +cr_doc_handler_associate_a_parser (CRDocHandler *a_this, + gpointer a_parser) +{ + g_return_if_fail (a_this && PRIVATE (a_this) + && a_parser) ; + + PRIVATE (a_this)->parser = a_parser ; +} diff --git a/src/libcroco/cr-doc-handler.h b/src/libcroco/cr-doc-handler.h new file mode 100644 index 000000000..704f186f5 --- /dev/null +++ b/src/libcroco/cr-doc-handler.h @@ -0,0 +1,298 @@ +/* -*- Mode: C; indent-tabs-mode: ni; c-basic-offset: 8 -*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * See the COPYRIGHTS file for copyright information. + */ + +#ifndef __CR_DOC_HANDLER_H__ +#define __CR_DOC_HANDLER_H__ + +/** + *@file + *The declaration of the #CRDocumentHandler class. + *This class is actually the parsing events handler. + */ + +#include +#include "cr-utils.h" +#include "cr-input.h" +#include "cr-stylesheet.h" + +G_BEGIN_DECLS + + +typedef struct _CRDocHandler CRDocHandler ; + +struct _CRDocHandlerPriv ; +typedef struct _CRDocHandlerPriv CRDocHandlerPriv ; + + +/** + *The SAC document handler. + *An instance of this class is to + *be passed to a parser. Then, during the parsing + *the parser calls the convenient function pointer + *whenever a particular event (a css construction) occurs. + */ +struct _CRDocHandler +{ + CRDocHandlerPriv *priv ; + + /** + *This pointer is to be used by the application for + *it custom needs. It is there to extend the doc handler. + */ + gpointer app_data ; + + /** + *Is called at the beginning of the parsing of the document. + *@param a_this a pointer to the current instance of + *#CRDocHandler. + */ + void (*start_document) (CRDocHandler *a_this) ; + + /** + *Is called to notify the end of the parsing of the document. + *@param a_this a pointer to the current instance of + *#CRDocHandler. + */ + void (*end_document) (CRDocHandler *a_this) ; + + /** + *Is called to notify an at charset rule. + *@param a_this the document handler. + *@param a_charset the declared charset. + */ + void (*charset) (CRDocHandler *a_this, + CRString *a_charset, + CRParsingLocation *a_charset_sym_location) ; + + /** + *Is called to notify an import statement in + *the stylesheet. + *@param a_this the current instance of #CRDocHandler. + *@param a_media_list a doubly linked list of GString objects. + *Each GString object contains a string which is the + *destination media for style information. + *@param a_uri the uri of the imported style sheet. + *@param a_uri_default_ns the default namespace of URI + *@param a_location the parsing location of the '@import' + *keyword. + *of the imported style sheet. + */ + void (*import_style) (CRDocHandler *a_this, + GList *a_media_list, + CRString *a_uri, + CRString *a_uri_default_ns, + CRParsingLocation *a_location) ; + + void (*import_style_result) (CRDocHandler *a_this, + GList *a_media_list, + CRString *a_uri, + CRString *a_uri_default_ns, + CRStyleSheet *a_sheet) ; + + /** + *Is called to notify a namespace declaration. + *Not used yet. + *@param a_this the current instance of #CRDocHandler. + *@param a_prefix the prefix of the namespace. + *@param a_uri the uri of the namespace. + *@param a_location the location of the "@namespace" keyword. + */ + void (*namespace_declaration) (CRDocHandler *a_this, + CRString *a_prefix, + CRString *a_uri, + CRParsingLocation *a_location) ; + + /** + *Is called to notify a comment. + *@param a_this a pointer to the current instance + *of #CRDocHandler. + *@param a_comment the comment. + */ + void (*comment) (CRDocHandler *a_this, + CRString *a_comment) ; + + /** + *Is called to notify the beginning of a rule + *statement. + *@param a_this the current instance of #CRDocHandler. + *@param a_selector_list the list of selectors that precedes + *the rule declarations. + */ + void (*start_selector) (CRDocHandler * a_this, + CRSelector *a_selector_list) ; + + /** + *Is called to notify the end of a rule statement. + *@param a_this the current instance of #CRDocHandler. + *@param a_selector_list the list of selectors that precedes + *the rule declarations. This pointer is the same as + *the one passed to start_selector() ; + */ + void (*end_selector) (CRDocHandler *a_this, + CRSelector *a_selector_list) ; + + + /** + *Is called to notify a declaration. + *@param a_this a pointer to the current instance + *of #CRDocHandler. + *@param a_name the name of the parsed property. + *@param a_expression a css expression that represents + *the value of the property. A css expression is + *actually a linked list of 'terms'. Each term can + *be linked to other using operators. + * + */ + void (*property) (CRDocHandler *a_this, + CRString *a_name, + CRTerm *a_expression, + gboolean a_is_important) ; + /** + *Is called to notify the start of a font face statement. + *The parser invokes this method at the beginning of every + *font face statement in the style sheet. There will + *be a corresponding end_font_face () event for every + *start_font_face () event. + * + *@param a_this a pointer to the current instance of + *#CRDocHandler. + *@param a_location the parsing location of the "@font-face" + *keyword. + */ + void (*start_font_face) (CRDocHandler *a_this, + CRParsingLocation *a_location) ; + + /** + *Is called to notify the end of a font face statement. + *@param a_this a pointer to the current instance of + *#CRDocHandler. + */ + void (*end_font_face) (CRDocHandler *a_this) ; + + + /** + *Is called to notify the beginning of a media statement. + *The parser will invoke this method at the beginning of + *every media statement in the style sheet. There will be + *a corresponding end_media() event for every start_media() + *event. + *@param a_this a pointer to the current instance of + *#CRDocHandler. + *@param a_media_list a double linked list of + #CRString * objects. + *Each CRString objects is actually a destination media for + *the style information. + */ + void (*start_media) (CRDocHandler *a_this, + GList *a_media_list, + CRParsingLocation *a_location) ; + + /** + *Is called to notify the end of a media statement. + *@param a_this a pointer to the current instance + *of #CRDocHandler. + *@param a_media_list a double linked list of GString * objects. + *Each GString objects is actually a destination media for + *the style information. + */ + void (*end_media) (CRDocHandler *a_this, + GList *a_media_list) ; + + /** + *Is called to notify the beginning of a page statement. + *The parser invokes this function at the beginning of + *every page statement in the style sheet. There will be + *a corresponding end_page() event for every single + *start_page() event. + *@param a_this a pointer to the current instance of + *#CRDocHandler. + *@param a_name the name of the page (if any, null otherwise). + *@param a_pseudo_page the pseudo page (if any, null otherwise). + *@param a_location the parsing location of the "@page" keyword. + */ + void (*start_page) (CRDocHandler *a_this, + CRString *a_name, + CRString *a_pseudo_page, + CRParsingLocation *a_location) ; + + /** + *Is called to notify the end of a page statement. + *@param a_this a pointer to the current instance of + *#CRDocHandler. + *@param a_name the name of the page (if any, null otherwise). + *@parap a_pseudo_page the pseudo page (if any, null otherwise). + */ + void (*end_page) (CRDocHandler *a_this, + CRString *a_name, + CRString *pseudo_page) ; + + /** + *Is Called to notify an unknown at-rule not supported + *by this parser. + */ + void (*ignorable_at_rule) (CRDocHandler *a_this, + CRString *a_name) ; + + /** + *Is called to notify a parsing error. After this error + *the application must ignore the rule being parsed, if + *any. After completion of this callback, + *the parser will then try to resume the parsing, + *ignoring the current error. + */ + void (*error) (CRDocHandler *a_this) ; + + /** + *Is called to notify an unrecoverable parsing error. + *This is the place to put emergency routines that free allocated + *resources. + */ + void (*unrecoverable_error) (CRDocHandler *a_this) ; + + gboolean resolve_import ; + gulong ref_count ; +} ; + +CRDocHandler * cr_doc_handler_new (void) ; + +enum CRStatus cr_doc_handler_set_result (CRDocHandler *a_this, gpointer a_result) ; + +enum CRStatus cr_doc_handler_get_result (CRDocHandler *a_this, gpointer * a_result) ; + +enum CRStatus cr_doc_handler_set_ctxt (CRDocHandler *a_this, gpointer a_ctxt) ; + +enum CRStatus cr_doc_handler_get_ctxt (CRDocHandler *a_this, gpointer * a_ctxt) ; + +enum CRStatus cr_doc_handler_set_default_sac_handler (CRDocHandler *a_this) ; + +void cr_doc_handler_associate_a_parser (CRDocHandler *a_this, + gpointer a_parser) ; + +void cr_doc_handler_ref (CRDocHandler *a_this) ; + +gboolean cr_doc_handler_unref (CRDocHandler *a_this) ; + +void cr_doc_handler_destroy (CRDocHandler *a_this) ; + +G_END_DECLS + +#endif /*__CR_DOC_HANDLER_H__*/ diff --git a/src/libcroco/cr-enc-handler.c b/src/libcroco/cr-enc-handler.c new file mode 100644 index 000000000..509793ab7 --- /dev/null +++ b/src/libcroco/cr-enc-handler.c @@ -0,0 +1,177 @@ +/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ + +/* + * This file is part of The Croco Library + * + * Copyright (C) 2002-2003 Dodji Seketeli + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + +/* + *$Id: cr-enc-handler.c,v 1.7 2004/03/07 13:22:47 dodji Exp $ + */ + +/** + *@file + *The definition of the #CREncHandler class. + */ + +#include "cr-enc-handler.h" +#include "cr-utils.h" + +#include + +struct CREncAlias { + const gchar *name; + enum CREncoding encoding; +}; + +static struct CREncAlias gv_default_aliases[] = { + {"UTF-8", CR_UTF_8}, + {"UTF_8", CR_UTF_8}, + {"UTF8", CR_UTF_8}, + {"UTF-16", CR_UTF_16}, + {"UTF_16", CR_UTF_16}, + {"UTF16", CR_UTF_16}, + {"UCS1", CR_UCS_1}, + {"UCS-1", CR_UCS_1}, + {"UCS_1", CR_UCS_1}, + {"ISO-8859-1", CR_UCS_1}, + {"ISO_8859-1", CR_UCS_1}, + {"UCS-1", CR_UCS_1}, + {"UCS_1", CR_UCS_1}, + {"UCS4", CR_UCS_4}, + {"UCS-4", CR_UCS_4}, + {"UCS_4", CR_UCS_4}, + {"ASCII", CR_ASCII}, + {0, 0} +}; + +static CREncHandler gv_default_enc_handlers[] = { + {CR_UCS_1, cr_utils_ucs1_to_utf8, cr_utils_utf8_to_ucs1, + cr_utils_ucs1_str_len_as_utf8, cr_utils_utf8_str_len_as_ucs1}, + + {CR_ISO_8859_1, cr_utils_ucs1_to_utf8, cr_utils_utf8_to_ucs1, + cr_utils_ucs1_str_len_as_utf8, cr_utils_utf8_str_len_as_ucs1}, + + {CR_ASCII, cr_utils_ucs1_to_utf8, cr_utils_utf8_to_ucs1, + cr_utils_ucs1_str_len_as_utf8, cr_utils_utf8_str_len_as_ucs1}, + + {0, NULL, NULL, NULL, NULL} +}; + +/** + *Gets the instance of encoding handler. + *This function implements a singleton pattern. + *@param a_enc the encoding of the Handler. + *@return the instance of #CREncHandler. + */ +CREncHandler * +cr_enc_handler_get_instance (enum CREncoding a_enc) +{ + gulong i = 0; + + for (i = 0; gv_default_enc_handlers[i].encoding; i++) { + if (gv_default_enc_handlers[i].encoding == a_enc) { + return (CREncHandler *) + & gv_default_enc_handlers[i].encoding; + } + } + + return NULL; +} + +/** + *Given an encoding name (called an alias name) + *the function returns the matching encoding type. + *@param a_alias_name the encoding name + *@param a_enc output param. The returned encoding type + *or 0 if the alias is not supported. + *@return CR_OK upon successfull completion, an error code otherwise. + */ +enum CRStatus +cr_enc_handler_resolve_enc_alias (const guchar * a_alias_name, + enum CREncoding *a_enc) +{ + gulong i = 0; + guchar *alias_name_up = NULL; + enum CRStatus status = CR_ENCODING_NOT_FOUND_ERROR; + + g_return_val_if_fail (a_alias_name != NULL, CR_BAD_PARAM_ERROR); + + alias_name_up = g_strdup (a_alias_name); + g_ascii_strup (alias_name_up, -1); + + for (i = 0; gv_default_aliases[i].name; i++) { + if (!strcmp (gv_default_aliases[i].name, alias_name_up)) { + *a_enc = gv_default_aliases[i].encoding; + status = CR_OK; + break; + } + } + + return status; +} + +/** + *Converts a raw input buffer into an utf8 buffer. + *@param a_this the current instance of #CREncHandler. + *@param a_in the input buffer to convert. + *@param a_in_len in/out parameter. The len of the input + *buffer to convert. After return, contains the number of + *bytes actually consumed. + *@param @a_out output parameter. The converted output buffer. + *Must be freed by the buffer. + *@param a_out_len output parameter. The length of the output buffer. + *@return CR_OK upon successfull completion, an error code otherwise. + */ +enum CRStatus +cr_enc_handler_convert_input (CREncHandler * a_this, + const guchar * a_in, + gulong * a_in_len, + guchar ** a_out, gulong * a_out_len) +{ + enum CRStatus status = CR_OK; + + g_return_val_if_fail (a_this && a_in && a_in_len && a_out, + CR_BAD_PARAM_ERROR); + + if (a_this->decode_input == NULL) + return CR_OK; + + if (a_this->enc_str_len_as_utf8) { + status = a_this->enc_str_len_as_utf8 (a_in, + &a_in[*a_in_len - 1], + a_out_len); + + g_return_val_if_fail (status == CR_OK, status); + } else { + *a_out_len = *a_in_len; + } + + *a_out = g_malloc0 (*a_out_len); + + status = a_this->decode_input (a_in, a_in_len, *a_out, a_out_len); + + if (status != CR_OK) { + g_free (*a_out); + *a_out = NULL; + } + + g_return_val_if_fail (status == CR_OK, status); + + return CR_OK; +} diff --git a/src/libcroco/cr-enc-handler.h b/src/libcroco/cr-enc-handler.h new file mode 100644 index 000000000..2f5da69f9 --- /dev/null +++ b/src/libcroco/cr-enc-handler.h @@ -0,0 +1,96 @@ +/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ + +/* + * This file is part of The Croco Library + * + * Copyright (C) 2002-2003 Dodji Seketeli + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + +/* + *$Id: cr-enc-handler.h,v 1.5 2004/01/24 19:24:01 dodji Exp $ + */ + +/** + *@file: + *The declaration of the #CREncHandler class. + * + */ + +#ifndef __CR_ENC_HANDLER_H__ +#define __CR_ENC_HANDLER_H__ + +#include "cr-utils.h" + +G_BEGIN_DECLS + + +typedef struct _CREncHandler CREncHandler ; + +typedef enum CRStatus (*CREncInputFunc) (const guchar * a_in, + gulong *a_in_len, + guchar *a_out, + gulong *a_out_len) ; + +typedef enum CRStatus (*CREncOutputFunc) (const guchar * a_in, + gulong *a_in_len, + guchar *a_out, + gulong *a_out_len) ; + +typedef enum CRStatus (*CREncInputStrLenAsUtf8Func) +(const guchar *a_in_start, + const guchar *a_in_end, + gulong *a_in_size); + +typedef enum CRStatus (*CREncUtf8StrLenAsOutputFunc) +(const guchar *a_in_start, + const guchar *a_in_end, + gulong *a_in_size) ; + +/** + *This class is responsible of the + *the encoding conversions stuffs in + *libcroco. + */ + +struct _CREncHandler +{ + enum CREncoding encoding ; + CREncInputFunc decode_input ; + CREncInputFunc encode_output ; + CREncInputStrLenAsUtf8Func enc_str_len_as_utf8 ; + CREncUtf8StrLenAsOutputFunc utf8_str_len_as_enc ; +} ; + +CREncHandler * +cr_enc_handler_get_instance (enum CREncoding a_enc) ; + +enum CRStatus +cr_enc_handler_resolve_enc_alias (const guchar *a_en_alias, + enum CREncoding *a_enc) ; +void +cr_enc_handler_destroy (CREncHandler * a_enc_hdlr) ; + +enum CRStatus +cr_enc_handler_convert_input (CREncHandler *a_this, + const guchar *a_in, + gulong *a_in_len, + guchar **a_out, + gulong *a_out_len) ; + +G_END_DECLS + +#endif /*__CR_ENC_HANDLER_H__*/ diff --git a/src/libcroco/cr-fonts.c b/src/libcroco/cr-fonts.c new file mode 100644 index 000000000..8c87aa229 --- /dev/null +++ b/src/libcroco/cr-fonts.c @@ -0,0 +1,761 @@ +/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */ + +/* + * This file is part of The Croco Library + * + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of + * the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the + * GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + *See COPYRIGHTS file for copyright information + */ + +#include "cr-fonts.h" +#include + +static enum CRStatus +cr_font_family_to_string_real (CRFontFamily * a_this, + gboolean a_walk_list, GString ** a_string) +{ + guchar *name = NULL; + enum CRStatus result = CR_OK; + + if (!*a_string) { + *a_string = g_string_new (NULL); + g_return_val_if_fail (*a_string, + CR_INSTANCIATION_FAILED_ERROR); + } + + if (!a_this) { + g_string_append (*a_string, "NULL"); + return CR_OK; + } + + switch (a_this->type) { + case FONT_FAMILY_SANS_SERIF: + name = (guchar *) "sans-serif"; + break; + + case FONT_FAMILY_SERIF: + name = (guchar *) "sans-serif"; + break; + + case FONT_FAMILY_CURSIVE: + name = (guchar *) "cursive"; + break; + + case FONT_FAMILY_FANTASY: + name = (guchar *) "fantasy"; + break; + + case FONT_FAMILY_MONOSPACE: + name = (guchar *) "monospace"; + break; + + case FONT_FAMILY_NON_GENERIC: + name = (guchar *) a_this->name; + break; + + default: + name = (guchar *) NULL; + break; + } + + if (name) { + if (a_this->prev) { + g_string_append_printf (*a_string, ", %s", name); + } else { + g_string_append (*a_string, name); + } + } + if (a_walk_list == TRUE && a_this->next) { + result = cr_font_family_to_string_real (a_this->next, + TRUE, a_string); + } + return result; +} + +static const gchar * +cr_predefined_absolute_font_size_to_string (enum CRPredefinedAbsoluteFontSize + a_code) +{ + gchar *str = NULL; + + switch (a_code) { + case FONT_SIZE_XX_SMALL: + str = (gchar *) "xx-small"; + break; + case FONT_SIZE_X_SMALL: + str = (gchar *) "x-small"; + break; + case FONT_SIZE_SMALL: + str = (gchar *) "small"; + break; + case FONT_SIZE_MEDIUM: + str = (gchar *) "medium"; + break; + case FONT_SIZE_LARGE: + str = (gchar *) "large"; + break; + case FONT_SIZE_X_LARGE: + str = (gchar *) "x-large"; + break; + case FONT_SIZE_XX_LARGE: + str = (gchar *) "xx-large"; + break; + default: + str = (gchar *) "unknown absolute font size value"; + } + return str; +} + +static const gchar * +cr_relative_font_size_to_string (enum CRRelativeFontSize a_code) +{ + gchar *str = NULL; + + switch (a_code) { + case FONT_SIZE_LARGER: + str = (gchar *) "larger"; + break; + case FONT_SIZE_SMALLER: + str = (gchar *) "smaller"; + break; + default: + str = (gchar *) "unknown relative font size value"; + break; + } + return str; +} + +CRFontFamily * +cr_font_family_new (enum CRFontFamilyType a_type, guchar * a_name) +{ + CRFontFamily *result = NULL; + + result = g_try_malloc (sizeof (CRFontFamily)); + + if (!result) { + cr_utils_trace_info ("Out of memory"); + return NULL; + } + + memset (result, 0, sizeof (CRFontFamily)); + result->type = a_type; + + cr_font_family_set_name (result, a_name); + + return result; +} + +guchar * +cr_font_family_to_string (CRFontFamily * a_this, + gboolean a_walk_font_family_list) +{ + enum CRStatus status = CR_OK; + guchar *result = NULL; + GString *stringue = NULL; + + if (!a_this) { + result = g_strdup ("NULL"); + g_return_val_if_fail (result, NULL); + return result; + } + status = cr_font_family_to_string_real (a_this, + a_walk_font_family_list, + &stringue); + + if (status == CR_OK && stringue) { + result = stringue->str; + g_string_free (stringue, FALSE); + stringue = NULL; + + } else { + if (stringue) { + g_string_free (stringue, TRUE); + stringue = NULL; + } + } + + return result; +} +enum CRStatus +cr_font_family_set_name (CRFontFamily * a_this, guchar * a_name) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + /* + *only non generic font families can have a name + */ + + if (a_this->type != FONT_FAMILY_NON_GENERIC) { + return CR_BAD_PARAM_ERROR; + } + + if (a_this->name) { + g_free (a_this->name); + a_this->name = NULL; + } + + a_this->name = a_name; + return CR_OK; +} + +CRFontFamily * +cr_font_family_append (CRFontFamily * a_this, + CRFontFamily * a_family_to_append) +{ + CRFontFamily *cur_ff = NULL; + + g_return_val_if_fail (a_family_to_append, NULL); + + if (!a_this) + return a_family_to_append; + + for (cur_ff = a_this; cur_ff && cur_ff->next; cur_ff = cur_ff->next) ; + + cur_ff->next = a_family_to_append; + a_family_to_append->prev = cur_ff; + + return a_this; + +} + +CRFontFamily * +cr_font_family_prepend (CRFontFamily * a_this, + CRFontFamily * a_family_to_prepend) +{ + g_return_val_if_fail (a_this && a_family_to_prepend, NULL); + + if (!a_this) + return a_family_to_prepend; + + a_family_to_prepend->next = a_this; + a_this->prev = a_family_to_prepend; + + return CR_OK; +} + +enum CRStatus +cr_font_family_destroy (CRFontFamily * a_this) +{ + CRFontFamily *cur_ff = NULL; + + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + for (cur_ff = a_this; cur_ff && cur_ff->next; cur_ff = cur_ff->next) ; + + for (; cur_ff; cur_ff = cur_ff->prev) { + if (a_this->name) { + g_free (a_this->name); + a_this->name = NULL; + } + + if (cur_ff->next) { + g_free (cur_ff->next); + + } + + if (cur_ff->prev == NULL) { + g_free (a_this); + } + } + + return CR_OK; +} + +/*************************************************** + *'font-size' manipulation functions definitions + ***************************************************/ + +CRFontSize * +cr_font_size_new (void) +{ + CRFontSize *result = NULL; + + result = g_try_malloc (sizeof (CRFontSize)); + if (!result) { + cr_utils_trace_info ("Out of memory"); + return NULL; + } + memset (result, 0, sizeof (CRFontSize)); + + return result; +} + +enum CRStatus +cr_font_size_clear (CRFontSize * a_this) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + switch (a_this->type) { + case PREDEFINED_ABSOLUTE_FONT_SIZE: + case RELATIVE_FONT_SIZE: + case INHERITED_FONT_SIZE: + memset (a_this, 0, sizeof (CRFontSize)); + break; + + case ABSOLUTE_FONT_SIZE: + memset (a_this, 0, sizeof (CRFontSize)); + break; + + default: + return CR_UNKNOWN_TYPE_ERROR; + } + + return CR_OK; +} + +enum CRStatus +cr_font_size_copy (CRFontSize * a_dst, CRFontSize * a_src) +{ + g_return_val_if_fail (a_dst && a_src, CR_BAD_PARAM_ERROR); + + switch (a_src->type) { + case PREDEFINED_ABSOLUTE_FONT_SIZE: + case RELATIVE_FONT_SIZE: + case INHERITED_FONT_SIZE: + cr_font_size_clear (a_dst); + memcpy (a_dst, a_src, sizeof (CRFontSize)); + break; + + case ABSOLUTE_FONT_SIZE: + cr_font_size_clear (a_dst); + cr_num_copy (&a_dst->value.absolute, + &a_src->value.absolute); + a_dst->type = a_src->type; + break; + + default: + return CR_UNKNOWN_TYPE_ERROR; + } + return CR_OK; +} + +enum CRStatus +cr_font_size_set_predefined_absolute_font_size (CRFontSize *a_this, + enum CRPredefinedAbsoluteFontSize a_predefined) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR) ; + g_return_val_if_fail ((unsigned)a_predefined < NB_FONT_SIZE_TYPE, + CR_BAD_PARAM_ERROR) ; + + a_this->type = PREDEFINED_ABSOLUTE_FONT_SIZE ; + a_this->value.predefined = a_predefined ; + + return CR_OK ; +} + +enum CRStatus +cr_font_size_set_relative_font_size (CRFontSize *a_this, + enum CRRelativeFontSize a_relative) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR) ; + g_return_val_if_fail ((unsigned)a_relative < NB_RELATIVE_FONT_SIZE, + CR_BAD_PARAM_ERROR) ; + + a_this->type = RELATIVE_FONT_SIZE ; + a_this->value.relative = a_relative ; + return CR_OK ; +} + +enum CRStatus +cr_font_size_set_absolute_font_size (CRFontSize *a_this, + enum CRNumType a_num_type, + gdouble a_value) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR) ; + g_return_val_if_fail ((unsigned)a_num_type < NB_NUM_TYPE, + CR_BAD_PARAM_ERROR) ; + + a_this->type = ABSOLUTE_FONT_SIZE ; + cr_num_set (&a_this->value.absolute, + a_value, a_num_type) ; + return CR_OK ; +} + +enum CRStatus +cr_font_size_set_to_inherit (CRFontSize *a_this) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR) ; + + cr_font_size_clear (a_this) ; + a_this->type = INHERITED_FONT_SIZE ; + + return CR_OK ; +} + +gboolean +cr_font_size_is_set_to_inherit (CRFontSize *a_this) +{ + g_return_val_if_fail (a_this, FALSE) ; + + return a_this->type == INHERITED_FONT_SIZE ; +} + +gchar * +cr_font_size_to_string (CRFontSize * a_this) +{ + gchar *str = NULL; + + if (!a_this) { + str = g_strdup ("NULL"); + g_return_val_if_fail (str, NULL); + return str; + } + switch (a_this->type) { + case PREDEFINED_ABSOLUTE_FONT_SIZE: + str = g_strdup (cr_predefined_absolute_font_size_to_string + (a_this->value.predefined)); + break; + case ABSOLUTE_FONT_SIZE: + str = cr_num_to_string (&a_this->value.absolute); + break; + case RELATIVE_FONT_SIZE: + str = g_strdup (cr_relative_font_size_to_string + (a_this->value.relative)); + break; + case INHERITED_FONT_SIZE: + str = g_strdup ("inherit"); + break; + default: + break; + } + return str; +} + +void +cr_font_size_get_smaller_predefined_font_size (enum CRPredefinedAbsoluteFontSize a_font_size, + enum CRPredefinedAbsoluteFontSize *a_smaller_size) +{ + enum CRPredefinedAbsoluteFontSize result = FONT_SIZE_MEDIUM ; + + g_return_if_fail (a_smaller_size) ; + g_return_if_fail ((unsigned)a_font_size < NB_PREDEFINED_ABSOLUTE_FONT_SIZES) ; + + switch (a_font_size) { + case FONT_SIZE_XX_SMALL: + result = FONT_SIZE_XX_SMALL ; + break ; + case FONT_SIZE_X_SMALL: + result = FONT_SIZE_XX_SMALL ; + break ; + case FONT_SIZE_SMALL: + result = FONT_SIZE_X_SMALL; + break ; + case FONT_SIZE_MEDIUM: + result = FONT_SIZE_SMALL; + break ; + case FONT_SIZE_LARGE: + result = FONT_SIZE_MEDIUM; + break ; + case FONT_SIZE_X_LARGE: + result = FONT_SIZE_LARGE; + break ; + case FONT_SIZE_XX_LARGE: + result = FONT_SIZE_XX_LARGE; + break ; + case FONT_SIZE_INHERIT: + cr_utils_trace_info ("can't return a smaller size for FONT_SIZE_INHERIT") ; + result = FONT_SIZE_MEDIUM ; + break ; + default: + cr_utils_trace_info ("Unknown FONT_SIZE") ; + result = FONT_SIZE_MEDIUM ; + break ; + } + *a_smaller_size = result ; +} + + +void +cr_font_size_get_larger_predefined_font_size (enum CRPredefinedAbsoluteFontSize a_font_size, + enum CRPredefinedAbsoluteFontSize *a_larger_size) +{ + enum CRPredefinedAbsoluteFontSize result = FONT_SIZE_MEDIUM ; + + g_return_if_fail (a_larger_size) ; + g_return_if_fail ((unsigned)a_font_size < NB_PREDEFINED_ABSOLUTE_FONT_SIZES) ; + + switch (a_font_size) { + case FONT_SIZE_XX_SMALL: + result = FONT_SIZE_X_SMALL ; + break ; + case FONT_SIZE_X_SMALL: + result = FONT_SIZE_SMALL ; + break ; + case FONT_SIZE_SMALL: + result = FONT_SIZE_MEDIUM; + break ; + case FONT_SIZE_MEDIUM: + result = FONT_SIZE_LARGE; + break ; + case FONT_SIZE_LARGE: + result = FONT_SIZE_X_LARGE; + break ; + case FONT_SIZE_X_LARGE: + result = FONT_SIZE_XX_LARGE ; + break ; + case FONT_SIZE_XX_LARGE: + result = FONT_SIZE_XX_LARGE; + break ; + case FONT_SIZE_INHERIT: + cr_utils_trace_info ("can't return a bigger size for FONT_SIZE_INHERIT") ; + result = FONT_SIZE_MEDIUM ; + break ; + default: + cr_utils_trace_info ("Unknown FONT_SIZE") ; + result = FONT_SIZE_MEDIUM ; + break ; + } + *a_larger_size = result ; +} + +gboolean +cr_font_size_is_predefined_absolute_font_size (enum CRPredefinedAbsoluteFontSize a_font_size) +{ + if ((unsigned)a_font_size < NB_PREDEFINED_ABSOLUTE_FONT_SIZES) { + return TRUE ; + } else { + return FALSE ; + } +} + +gchar * +cr_font_size_adjust_to_string (CRFontSizeAdjust * a_this) +{ + gchar *str = NULL; + + if (!a_this) { + str = g_strdup ("NULL"); + g_return_val_if_fail (str, NULL); + return str; + } + + switch (a_this->type) { + case FONT_SIZE_ADJUST_NONE: + str = g_strdup ("none"); + break; + case FONT_SIZE_ADJUST_NUMBER: + if (a_this->num) + str = cr_num_to_string (a_this->num); + else + str = g_strdup ("unknow font-size-adjust property value"); // Should raise an error no? + break; + case FONT_SIZE_ADJUST_INHERIT: + str = g_strdup ("inherit"); + } + return str; +} + +const gchar * +cr_font_style_to_string (enum CRFontStyle a_code) +{ + gchar *str = NULL; + + switch (a_code) { + case FONT_STYLE_NORMAL: + str = (gchar *) "normal"; + break; + case FONT_STYLE_ITALIC: + str = (gchar *) "italic"; + break; + case FONT_STYLE_OBLIQUE: + str = (gchar *) "oblique"; + break; + case FONT_STYLE_INHERIT: + str = (gchar *) "inherit"; + break; + default: + str = (gchar *) "unknown font style value"; + break; + } + return str; +} + +const gchar * +cr_font_variant_to_string (enum CRFontVariant a_code) +{ + gchar *str = NULL; + + switch (a_code) { + case FONT_VARIANT_NORMAL: + str = (gchar *) "normal"; + break; + case FONT_VARIANT_SMALL_CAPS: + str = (gchar *) "small-caps"; + break; + case FONT_VARIANT_INHERIT: + str = (gchar *) "inherit"; + break; + } + return str; +} + +enum CRFontWeight +cr_font_weight_get_bolder (enum CRFontWeight a_weight) +{ + if (a_weight >= NB_FONT_WEIGHTS) { + return FONT_WEIGHT_900 ; + } else if (a_weight < FONT_WEIGHT_NORMAL) { + return FONT_WEIGHT_NORMAL ; + } else if (a_weight == FONT_WEIGHT_BOLDER + || a_weight == FONT_WEIGHT_BOLDER) { + cr_utils_trace_info ("FONT_WEIGHT_BOLDER or FONT_WEIGHT_LIGHTER should not appear here") ; + return FONT_WEIGHT_NORMAL ; + } else { + return a_weight << 1 ; + } +} + +const gchar * +cr_font_weight_to_string (enum CRFontWeight a_code) +{ + gchar *str = NULL; + + switch (a_code) { + case FONT_WEIGHT_NORMAL: + str = (gchar *) "normal"; + break; + case FONT_WEIGHT_BOLD: + str = (gchar *) "bold"; + break; + case FONT_WEIGHT_BOLDER: + str = (gchar *) "bolder"; + break; + case FONT_WEIGHT_LIGHTER: + str = (gchar *) "lighter"; + break; + case FONT_WEIGHT_100: + str = (gchar *) "100"; + break; + case FONT_WEIGHT_200: + str = (gchar *) "200"; + break; + case FONT_WEIGHT_300: + str = (gchar *) "300"; + break; + case FONT_WEIGHT_400: + str = (gchar *) "400"; + break; + case FONT_WEIGHT_500: + str = (gchar *) "500"; + break; + case FONT_WEIGHT_600: + str = (gchar *) "600"; + break; + case FONT_WEIGHT_700: + str = (gchar *) "700"; + break; + case FONT_WEIGHT_800: + str = (gchar *) "800"; + break; + case FONT_WEIGHT_900: + str = (gchar *) "900"; + break; + case FONT_WEIGHT_INHERIT: + str = (gchar *) "inherit"; + break; + default: + str = (gchar *) "unknown font-weight property value"; + break; + } + return str; +} + +const gchar * +cr_font_stretch_to_string (enum CRFontStretch a_code) +{ + gchar *str = NULL; + + switch (a_code) { + case FONT_STRETCH_NORMAL: + str = (gchar *) "normal"; + break; + case FONT_STRETCH_WIDER: + str = (gchar *) "wider"; + break; + case FONT_STRETCH_NARROWER: + str = (gchar *) "narrower"; + break; + case FONT_STRETCH_ULTRA_CONDENSED: + str = (gchar *) "ultra-condensed"; + break; + case FONT_STRETCH_EXTRA_CONDENSED: + str = (gchar *) "extra-condensed"; + break; + case FONT_STRETCH_CONDENSED: + str = (gchar *) "condensed"; + break; + case FONT_STRETCH_SEMI_CONDENSED: + str = (gchar *) "semi-condensed"; + break; + case FONT_STRETCH_SEMI_EXPANDED: + str = (gchar *) "semi-expanded"; + break; + case FONT_STRETCH_EXPANDED: + str = (gchar *) "expanded"; + break; + case FONT_STRETCH_EXTRA_EXPANDED: + str = (gchar *) "extra-expaned"; + break; + case FONT_STRETCH_ULTRA_EXPANDED: + str = (gchar *) "ultra-expanded"; + break; + case FONT_STRETCH_INHERIT: + str = (gchar *) "inherit"; + break; + } + return str; +} + +void +cr_font_size_destroy (CRFontSize * a_font_size) +{ + g_return_if_fail (a_font_size); + + g_free (a_font_size) ; +} + +/******************************************************* + *'font-size-adjust' manipulation function definition + *******************************************************/ + +CRFontSizeAdjust * +cr_font_size_adjust_new (void) +{ + CRFontSizeAdjust *result = NULL; + + result = g_try_malloc (sizeof (CRFontSizeAdjust)); + if (!result) { + cr_utils_trace_info ("Out of memory"); + return NULL; + } + memset (result, 0, sizeof (CRFontSizeAdjust)); + + return result; +} + +void +cr_font_size_adjust_destroy (CRFontSizeAdjust * a_this) +{ + g_return_if_fail (a_this); + + if (a_this->type == FONT_SIZE_ADJUST_NUMBER && a_this->num) { + cr_num_destroy (a_this->num); + a_this->num = NULL; + } +} diff --git a/src/libcroco/cr-fonts.h b/src/libcroco/cr-fonts.h new file mode 100644 index 000000000..45446180b --- /dev/null +++ b/src/libcroco/cr-fonts.h @@ -0,0 +1,314 @@ +/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of + * the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the + * GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * Author: Dodji Seketeli + * See COPYRIGHTS file for copyright information. + */ + +#ifndef __CR_FONTS_H__ +#define __CR_FONTS_H__ +#endif + +#include "cr-utils.h" +#include "cr-num.h" + +/** + *@file + *Various type declarations about font selection related + *properties. + */ +G_BEGIN_DECLS + + +enum CRFontFamilyType +{ + FONT_FAMILY_SANS_SERIF, + FONT_FAMILY_SERIF, + FONT_FAMILY_CURSIVE, + FONT_FAMILY_FANTASY, + FONT_FAMILY_MONOSPACE, + FONT_FAMILY_NON_GENERIC, + FONT_FAMILY_INHERIT, + /**/ + NB_FONT_FAMILIE_TYPES +} ; + +typedef struct _CRFontFamily CRFontFamily ; + +struct _CRFontFamily +{ + enum CRFontFamilyType type ; + + /* + *The name of the font family, in case + *it is non generic. + *Is set only if the type is FONT_FAMILY_NON_GENERIC. + */ + guchar *name ; + + CRFontFamily *next ; + CRFontFamily *prev ; +} ; + + +/** + *The different types + *of absolute font size. + *This is used by the 'font-size' + *property defined in css2 spec + *in chapter 15.2.4 . + *These values a indexes of + *table of size so please, do not + *change their definition order unless + *you know what you are doing. + */ +enum CRPredefinedAbsoluteFontSize +{ + FONT_SIZE_XX_SMALL=0, + FONT_SIZE_X_SMALL, + FONT_SIZE_SMALL, + FONT_SIZE_MEDIUM, + FONT_SIZE_LARGE, + FONT_SIZE_X_LARGE, + FONT_SIZE_XX_LARGE, + FONT_SIZE_INHERIT, + NB_PREDEFINED_ABSOLUTE_FONT_SIZES +} ; + +/** + *The different types + *of relative font size. + *This is used by the 'font-size' + *property defined in css2 spec + *in chapter 15.2.4 . + *These values a indexes of + *table of size so please, do not + *change their definition order unless + *you know what you are doing. + */ +enum CRRelativeFontSize +{ + FONT_SIZE_LARGER, + FONT_SIZE_SMALLER, + NB_RELATIVE_FONT_SIZE +} ; + +/** + *The type of font-size property. + *Used to define the type of #CRFontSize . + *See css2 spec chapter 15.2.4 to understand. + */ +enum CRFontSizeType { + /** + *If the type of #CRFontSize is + *PREDEFINED_ABSOLUTE_FONT_SIZE, + *the CRFontSize::value.predefined_absolute + *field will be defined. + */ + PREDEFINED_ABSOLUTE_FONT_SIZE, + + /** + *If the type of #CRFontSize is + *ABSOLUTE_FONT_SIZE, + *the CRFontSize::value.absolute + *field will be defined. + */ + ABSOLUTE_FONT_SIZE, + + /** + *If the type of #CRFontSize is + *RELATIVE_FONT_SIZE, + *the CRFontSize::value.relative + *field will be defined. + */ + RELATIVE_FONT_SIZE, + + /** + *If the type of #CRFontSize is + *INHERITED_FONT_SIZE, + *the None of the field of the CRFontSize::value enum + *will be defined. + */ + INHERITED_FONT_SIZE, + + NB_FONT_SIZE_TYPE +} ; + +typedef struct _CRFontSize CRFontSize ; +struct _CRFontSize { + enum CRFontSizeType type ; + union { + enum CRPredefinedAbsoluteFontSize predefined ; + enum CRRelativeFontSize relative ; + CRNum absolute ; + } value; +} ; + +enum CRFontSizeAdjustType +{ + FONT_SIZE_ADJUST_NONE = 0, + FONT_SIZE_ADJUST_NUMBER, + FONT_SIZE_ADJUST_INHERIT +} ; +typedef struct _CRFontSizeAdjust CRFontSizeAdjust ; +struct _CRFontSizeAdjust +{ + enum CRFontSizeAdjustType type ; + CRNum *num ; +} ; + +enum CRFontStyle +{ + FONT_STYLE_NORMAL=0, + FONT_STYLE_ITALIC, + FONT_STYLE_OBLIQUE, + FONT_STYLE_INHERIT +} ; + +enum CRFontVariant +{ + FONT_VARIANT_NORMAL=0, + FONT_VARIANT_SMALL_CAPS, + FONT_VARIANT_INHERIT +} ; + +enum CRFontWeight +{ + FONT_WEIGHT_NORMAL = 1, + FONT_WEIGHT_BOLD = 1<<1, + FONT_WEIGHT_BOLDER = 1<<2, + FONT_WEIGHT_LIGHTER = 1<<3, + FONT_WEIGHT_100 = 1<<4, + FONT_WEIGHT_200 = 1<<5, + FONT_WEIGHT_300 = 1<<6, + FONT_WEIGHT_400 = 1<<7, + FONT_WEIGHT_500 = 1<<8, + FONT_WEIGHT_600 = 1<<9, + FONT_WEIGHT_700 = 1<<10, + FONT_WEIGHT_800 = 1<<11, + FONT_WEIGHT_900 = 1<<12, + FONT_WEIGHT_INHERIT = 1<<13, + NB_FONT_WEIGHTS +} ; + +enum CRFontStretch +{ + FONT_STRETCH_NORMAL=0, + FONT_STRETCH_WIDER, + FONT_STRETCH_NARROWER, + FONT_STRETCH_ULTRA_CONDENSED, + FONT_STRETCH_EXTRA_CONDENSED, + FONT_STRETCH_CONDENSED, + FONT_STRETCH_SEMI_CONDENSED, + FONT_STRETCH_SEMI_EXPANDED, + FONT_STRETCH_EXPANDED, + FONT_STRETCH_EXTRA_EXPANDED, + FONT_STRETCH_ULTRA_EXPANDED, + FONT_STRETCH_INHERIT +} ; + +/************************************** + *'font-family' manipulation functions + ***************************************/ +CRFontFamily * +cr_font_family_new (enum CRFontFamilyType a_type, guchar *a_name) ; + +CRFontFamily * +cr_font_family_append (CRFontFamily *a_this, + CRFontFamily *a_family_to_append) ; + +guchar * +cr_font_family_to_string (CRFontFamily *a_this, + gboolean a_walk_font_family_list) ; + +CRFontFamily * +cr_font_family_prepend (CRFontFamily *a_this, + CRFontFamily *a_family_to_prepend); + +enum CRStatus +cr_font_family_destroy (CRFontFamily *a_this) ; + +enum CRStatus +cr_font_family_set_name (CRFontFamily *a_this, guchar *a_name) ; + + +/************************************ + *'font-size' manipulation functions + ***********************************/ + +CRFontSize * cr_font_size_new (void) ; + +enum CRStatus cr_font_size_clear (CRFontSize *a_this) ; + +enum CRStatus cr_font_size_copy (CRFontSize *a_dst, + CRFontSize *a_src) ; +enum CRStatus cr_font_size_set_predefined_absolute_font_size (CRFontSize *a_this, + enum CRPredefinedAbsoluteFontSize a_predefined) ; +enum CRStatus cr_font_size_set_relative_font_size (CRFontSize *a_this, + enum CRRelativeFontSize a_relative) ; + +enum CRStatus cr_font_size_set_absolute_font_size (CRFontSize *a_this, + enum CRNumType a_num_type, + gdouble a_value) ; + +enum CRStatus cr_font_size_set_to_inherit (CRFontSize *a_this) ; + +gboolean cr_font_size_is_set_to_inherit (CRFontSize *a_this) ; + +gchar* cr_font_size_to_string (CRFontSize *a_this) ; + +void cr_font_size_destroy (CRFontSize *a_font_size) ; + +/******************************************************* + *'font-size-adjust' manipulation function declarations + *******************************************************/ + +CRFontSizeAdjust * cr_font_size_adjust_new (void) ; + +gchar * cr_font_size_adjust_to_string (CRFontSizeAdjust *a_this) ; + +void cr_font_size_adjust_destroy (CRFontSizeAdjust *a_this) ; + +void +cr_font_size_get_smaller_predefined_font_size (enum CRPredefinedAbsoluteFontSize a_font_size, + enum CRPredefinedAbsoluteFontSize *a_smaller_size) ; +void +cr_font_size_get_larger_predefined_font_size (enum CRPredefinedAbsoluteFontSize a_font_size, + enum CRPredefinedAbsoluteFontSize *a_larger_size) ; + +gboolean +cr_font_size_is_predefined_absolute_font_size (enum CRPredefinedAbsoluteFontSize a_font_size) ; + +/*********************************** + *various other font related functions + ***********************************/ +const gchar * cr_font_style_to_string (enum CRFontStyle a_code) ; + +const gchar * cr_font_weight_to_string (enum CRFontWeight a_code) ; + +enum CRFontWeight +cr_font_weight_get_bolder (enum CRFontWeight a_weight) ; + +const gchar * cr_font_variant_to_string (enum CRFontVariant a_code) ; + +const gchar * cr_font_stretch_to_string (enum CRFontStretch a_code) ; + +G_END_DECLS diff --git a/src/libcroco/cr-input.c b/src/libcroco/cr-input.c new file mode 100644 index 000000000..9485df3c5 --- /dev/null +++ b/src/libcroco/cr-input.c @@ -0,0 +1,1112 @@ +/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 8-*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * Author: Dodji Seketeli + * See COPYRIGHTS file for copyright information. + */ + +#include "stdio.h" +#include +#include "cr-input.h" +#include "cr-enc-handler.h" + +/** + *@file + *The definition of the #CRInput class. + */ + +/******************* + *Private type defs + *******************/ + +/** + *The private attributes of + *the #CRInputPriv class. + */ +struct _CRInputPriv { + /* + *The input buffer + */ + guchar *in_buf; + gulong in_buf_size; + + gulong nb_bytes; + + /* + *The index of the next byte + *to be read. + */ + gulong next_byte_index; + + /* + *The current line number + */ + gulong line; + + /* + *The current col number + */ + gulong col; + + gboolean end_of_line; + gboolean end_of_input; + + /* + *the reference count of this + *instance. + */ + guint ref_count; + gboolean free_in_buf; +}; + +#define PRIVATE(object) (object)->priv + +/*************************** + *private constants + **************************/ +#define CR_INPUT_MEM_CHUNK_SIZE 1024 * 4 + +static CRInput *cr_input_new_real (void); + +static CRInput * +cr_input_new_real (void) +{ + CRInput *result = NULL; + + result = g_try_malloc (sizeof (CRInput)); + if (!result) { + cr_utils_trace_info ("Out of memory"); + return NULL; + } + memset (result, 0, sizeof (CRInput)); + + PRIVATE (result) = g_try_malloc (sizeof (CRInputPriv)); + if (!PRIVATE (result)) { + cr_utils_trace_info ("Out of memory"); + g_free (result); + return NULL; + } + memset (PRIVATE (result), 0, sizeof (CRInputPriv)); + PRIVATE (result)->free_in_buf = TRUE; + return result; +} + +/**************** + *Public methods + ***************/ + +/** + *Creates a new input stream from a memory buffer. + *@param a_buf the memory buffer to create the input stream from. + *The #CRInput keeps this pointer so user should not free it !. + *@param a_len the size of the input buffer. + *@param a_enc the buffer's encoding. + *@param a_free_buf if set to TRUE, this a_buf will be freed + *at the destruction of this instance. If set to false, it is up + *to the caller to free it. + *@return the newly built instance of #CRInput. + */ +CRInput * +cr_input_new_from_buf (guchar * a_buf, + gulong a_len, + enum CREncoding a_enc, + gboolean a_free_buf) +{ + CRInput *result = NULL; + enum CRStatus status = CR_OK; + CREncHandler *enc_handler = NULL; + gulong len = a_len; + + g_return_val_if_fail (a_buf, NULL); + + result = cr_input_new_real (); + g_return_val_if_fail (result, NULL); + + /*transform the encoding in utf8 */ + if (a_enc != CR_UTF_8) { + enc_handler = cr_enc_handler_get_instance (a_enc); + if (!enc_handler) { + goto error; + } + + status = cr_enc_handler_convert_input + (enc_handler, a_buf, &len, + &PRIVATE (result)->in_buf, + &PRIVATE (result)->in_buf_size); + if (status != CR_OK) + goto error; + PRIVATE (result)->free_in_buf = TRUE; + if (a_free_buf == TRUE && a_buf) { + g_free (a_buf) ; + a_buf = NULL ; + } + PRIVATE (result)->nb_bytes = PRIVATE (result)->in_buf_size; + } else { + PRIVATE (result)->in_buf = (guchar *) a_buf; + PRIVATE (result)->in_buf_size = a_len; + PRIVATE (result)->nb_bytes = a_len; + PRIVATE (result)->free_in_buf = a_free_buf; + } + PRIVATE (result)->line = 1; + PRIVATE (result)->col = 0; + return result; + + error: + if (result) { + cr_input_destroy (result); + result = NULL; + } + + return NULL; +} + +/** + *Creates a new input stream from + *a file. + *@param a_file_uri the file to create + *the input stream from. + *@param a_enc the encoding of the file + *to create the input from + *@return the newly created input stream if + *this method could read the file and create it, + *NULL otherwise. + */ + +CRInput * +cr_input_new_from_uri (const gchar * a_file_uri, enum CREncoding a_enc) +{ + CRInput *result = NULL; + enum CRStatus status = CR_OK; + FILE *file_ptr = NULL; + guchar tmp_buf[CR_INPUT_MEM_CHUNK_SIZE] = { 0 }; + gulong nb_read = 0, + len = 0, + buf_size = 0; + gboolean loop = TRUE; + guchar *buf = NULL; + + g_return_val_if_fail (a_file_uri, NULL); + + file_ptr = fopen (a_file_uri, "r"); + + if (file_ptr == NULL) { + +#ifdef CR_DEBUG + cr_utils_trace_debug ("could not open file"); +#endif + g_warning ("Could not open file %s\n", a_file_uri); + + return NULL; + } + + /*load the file */ + while (loop) { + nb_read = fread (tmp_buf, 1 /*read bytes */ , + CR_INPUT_MEM_CHUNK_SIZE /*nb of bytes */ , + file_ptr); + + if (nb_read != CR_INPUT_MEM_CHUNK_SIZE) { + /*we read less chars than we wanted */ + if (feof (file_ptr)) { + /*we reached eof */ + loop = FALSE; + } else { + /*a pb occured !! */ + cr_utils_trace_debug ("an io error occured"); + status = CR_ERROR; + goto cleanup; + } + } + + if (status == CR_OK) { + /*read went well */ + buf = g_realloc (buf, len + CR_INPUT_MEM_CHUNK_SIZE); + memcpy (buf + len, tmp_buf, nb_read); + len += nb_read; + buf_size += CR_INPUT_MEM_CHUNK_SIZE; + } + } + + if (status == CR_OK) { + result = cr_input_new_from_buf (buf, len, a_enc, TRUE); + if (!result) { + goto cleanup; + } + /* + *we should free buf here because it's own by CRInput. + *(see the last parameter of cr_input_new_from_buf(). + */ + buf = NULL ; + } + + cleanup: + if (file_ptr) { + fclose (file_ptr); + file_ptr = NULL; + } + + if (buf) { + g_free (buf); + buf = NULL; + } + + return result; +} + +/** + *The destructor of the #CRInput class. + *@param a_this the current instance of #CRInput. + */ +void +cr_input_destroy (CRInput * a_this) +{ + if (a_this == NULL) + return; + + if (PRIVATE (a_this)) { + if (PRIVATE (a_this)->in_buf && PRIVATE (a_this)->free_in_buf) { + g_free (PRIVATE (a_this)->in_buf); + PRIVATE (a_this)->in_buf = NULL; + } + + g_free (PRIVATE (a_this)); + PRIVATE (a_this) = NULL; + } + + g_free (a_this); +} + +/** + *Increments the reference count of the current + *instance of #CRInput. + *@param a_this the current instance of #CRInput. + */ +void +cr_input_ref (CRInput * a_this) +{ + g_return_if_fail (a_this && PRIVATE (a_this)); + + PRIVATE (a_this)->ref_count++; +} + +/** + *Decrements the reference count of this instance + *of #CRInput. If the reference count goes down to + *zero, this instance is destroyed. + *@param a_this the current instance of #CRInput. + * + */ +gboolean +cr_input_unref (CRInput * a_this) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this), FALSE); + + if (PRIVATE (a_this)->ref_count) { + PRIVATE (a_this)->ref_count--; + } + + if (PRIVATE (a_this)->ref_count == 0) { + cr_input_destroy (a_this); + return TRUE; + } + return FALSE; +} + +/** + *Tests wether the current instance of + *#CRInput has reached its input buffer. + *@param a_this the current instance of #CRInput. + *@param a_end_of_input out parameter. Is set to TRUE if + *the current instance has reached the end of its input buffer, + *FALSE otherwise. + *@param CR_OK upon successful completion, an error code otherwise. + *Note that all the out parameters of this method are valid if + *and only if this method returns CR_OK. + */ +enum CRStatus +cr_input_end_of_input (CRInput * a_this, gboolean * a_end_of_input) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this) + && a_end_of_input, CR_BAD_PARAM_ERROR); + + *a_end_of_input = (PRIVATE (a_this)->next_byte_index + >= PRIVATE (a_this)->in_buf_size) ? TRUE : FALSE; + + return CR_OK; +} + +/** + *Returns the number of bytes left in the input stream + *before the end. + *@param a_this the current instance of #CRInput. + *@return the number of characters left or -1 in case of error. + */ +glong +cr_input_get_nb_bytes_left (CRInput * a_this) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this), -1); + g_return_val_if_fail (PRIVATE (a_this)->nb_bytes + <= PRIVATE (a_this)->in_buf_size, -1); + g_return_val_if_fail (PRIVATE (a_this)->next_byte_index + <= PRIVATE (a_this)->nb_bytes, -1); + + if (PRIVATE (a_this)->end_of_input) + return 0; + + return PRIVATE (a_this)->nb_bytes - PRIVATE (a_this)->next_byte_index; +} + +/** + *Returns the next byte of the input. + *Update the state of the input so that + *the next invocation of this method returns + *the next coming byte. + * + *@param a_this the current instance of #CRInput. + *@param a_byte out parameter the returned byte. + *@return CR_OK upon successful completion, an error code + *otherwise. All the out parameters of this method are valid if + *and only if this method returns CR_OK. + */ +enum CRStatus +cr_input_read_byte (CRInput * a_this, guchar * a_byte) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this) + && a_byte, CR_BAD_PARAM_ERROR); + + g_return_val_if_fail (PRIVATE (a_this)->next_byte_index <= + PRIVATE (a_this)->nb_bytes, CR_BAD_PARAM_ERROR); + + if (PRIVATE (a_this)->end_of_input == TRUE) + return CR_END_OF_INPUT_ERROR; + + *a_byte = PRIVATE (a_this)->in_buf[PRIVATE (a_this)->next_byte_index]; + + if (PRIVATE (a_this)->nb_bytes - + PRIVATE (a_this)->next_byte_index < 2) { + PRIVATE (a_this)->end_of_input = TRUE; + } else { + PRIVATE (a_this)->next_byte_index++; + } + + return CR_OK; +} + +/** + *Reads an unicode character from the current instance of + *#CRInput. + *@param a_this the current instance of CRInput. + *@param a_char out parameter. The read character. + *@return CR_OK upon successful completion, an error code + *otherwise. + */ +enum CRStatus +cr_input_read_char (CRInput * a_this, guint32 * a_char) +{ + enum CRStatus status = CR_OK; + gulong consumed = 0, + nb_bytes_left = 0; + + g_return_val_if_fail (a_this && PRIVATE (a_this) && a_char, + CR_BAD_PARAM_ERROR); + + if (PRIVATE (a_this)->end_of_input == TRUE) + return CR_END_OF_INPUT_ERROR; + + nb_bytes_left = cr_input_get_nb_bytes_left (a_this); + + if (nb_bytes_left < 1) { + return CR_END_OF_INPUT_ERROR; + } + + status = cr_utils_read_char_from_utf8_buf + (PRIVATE (a_this)->in_buf + + + PRIVATE (a_this)->next_byte_index, + nb_bytes_left, a_char, &consumed); + + if (status == CR_OK) { + /*update next byte index */ + PRIVATE (a_this)->next_byte_index += consumed; + + /*update line and column number */ + if (PRIVATE (a_this)->end_of_line == TRUE) { + PRIVATE (a_this)->col = 1; + PRIVATE (a_this)->line++; + PRIVATE (a_this)->end_of_line = FALSE; + } else if (*a_char != '\n') { + PRIVATE (a_this)->col++; + } + + if (*a_char == '\n') { + PRIVATE (a_this)->end_of_line = TRUE; + } + + } + + return status; +} + +/** + *Setter of the current line number. + *@param a_this the "this pointer" of the current instance of + *#CRInput. + *@param a_line_num the new line number. + *@return CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_input_set_line_num (CRInput * a_this, glong a_line_num) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this), CR_BAD_PARAM_ERROR); + + PRIVATE (a_this)->line = a_line_num; + + return CR_OK; +} + +/** + *Getter of the current line number. + *@param a_this the "this pointer" of the current instance of + *#CRInput. + *@param a_line_num the returned line number. + *@return CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_input_get_line_num (CRInput * a_this, glong * a_line_num) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this) + && a_line_num, CR_BAD_PARAM_ERROR); + + *a_line_num = PRIVATE (a_this)->line; + + return CR_OK; +} + +/** + *Setter of the current column number. + *@param a_this the "this pointer" of the current instance of + *#CRInput. + *@param a_col the new column number. + *@return CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_input_set_column_num (CRInput * a_this, glong a_col) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this), CR_BAD_PARAM_ERROR); + + PRIVATE (a_this)->col = a_col; + + return CR_OK; +} + +/** + *Getter of the current column number. + *@param a_this the "this pointer" of the current instance of + *#CRInput. + *@param a_col out parameter + *@return CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_input_get_column_num (CRInput * a_this, glong * a_col) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this) && a_col, + CR_BAD_PARAM_ERROR); + + *a_col = PRIVATE (a_this)->col; + + return CR_OK; +} + +/** + *Increments the current line number. + *@param a_this the "this pointer" of the current instance of + *#CRInput. + *@return CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_input_increment_line_num (CRInput * a_this, glong a_increment) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this), CR_BAD_PARAM_ERROR); + + PRIVATE (a_this)->line += a_increment; + + return CR_OK; +} + +/** + *Increments the current column number. + *@param a_this the "this pointer" of the current instance of + *#CRInput. + *@return CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_input_increment_col_num (CRInput * a_this, glong a_increment) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this), CR_BAD_PARAM_ERROR); + + PRIVATE (a_this)->col += a_increment; + + return CR_OK; +} + +/** + *Consumes the next character of the input stream if + *and only if that character equals a_char. + * + *@param a_this the this pointer. + *@param a_char the character to consume. If set to zero, + *consumes any character. + *@return CR_OK upon successful completion, CR_PARSING_ERROR if + *next char is different from a_char, an other error code otherwise + */ +enum CRStatus +cr_input_consume_char (CRInput * a_this, guint32 a_char) +{ + guint32 c; + enum CRStatus status; + + g_return_val_if_fail (a_this && PRIVATE (a_this), CR_BAD_PARAM_ERROR); + + if ((status = cr_input_peek_char (a_this, &c)) != CR_OK) { + return status; + } + + if (c == a_char || a_char == 0) { + status = cr_input_read_char (a_this, &c); + } else { + return CR_PARSING_ERROR; + } + + return status; +} + +/** + *Consumes up to a_nb_char occurences of the next contiguous characters + *which equal a_char. Note that the next character of the input stream + **MUST* equal a_char to trigger the consumption, or else, the error + *code CR_PARSING_ERROR is returned. + *If the number of contiguous characters that equals a_char is less than + *a_nb_char, then this function consumes all the characters it can consume. + * + *@param a_this the this pointer of the current instance of #CRInput. + *@param a_char the character to consume. + *@param a_nb_char in/out parameter. The number of characters to consume. + *If set to a negative value, the function will consume all the occurences + *of a_char found. + *After return, if the return value equals CR_OK, this variable contains + *the number of characters actually consumed. + *@return CR_OK if at least one character has been consumed, an error code + *otherwise. + */ +enum CRStatus +cr_input_consume_chars (CRInput * a_this, guint32 a_char, gulong * a_nb_char) +{ + enum CRStatus status = CR_OK; + gulong nb_consumed = 0; + + g_return_val_if_fail (a_this && PRIVATE (a_this) && a_nb_char, + CR_BAD_PARAM_ERROR); + + g_return_val_if_fail (a_char != 0 || a_nb_char != NULL, + CR_BAD_PARAM_ERROR); + + for (nb_consumed = 0; ((status == CR_OK) + && (*a_nb_char > 0 + && nb_consumed < *a_nb_char)); + nb_consumed++) { + status = cr_input_consume_char (a_this, a_char); + } + + *a_nb_char = nb_consumed; + + if ((nb_consumed > 0) + && ((status == CR_PARSING_ERROR) + || (status == CR_END_OF_INPUT_ERROR))) { + status = CR_OK; + } + + return status; +} + +/** + *Same as cr_input_consume_chars() but this one consumes white + *spaces. + * + *@param a_this the "this pointer" of the current instance of #CRInput. + *@param a_nb_chars in/out parameter. The number of white spaces to + *consume. After return, holds the number of white spaces actually consumed. + *@return CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_input_consume_white_spaces (CRInput * a_this, gulong * a_nb_chars) +{ + enum CRStatus status = CR_OK; + guint32 cur_char = 0, + nb_consumed = 0; + + g_return_val_if_fail (a_this && PRIVATE (a_this) && a_nb_chars, + CR_BAD_PARAM_ERROR); + + for (nb_consumed = 0; + ((*a_nb_chars > 0) && (nb_consumed < *a_nb_chars)); + nb_consumed++) { + status = cr_input_peek_char (a_this, &cur_char); + if (status != CR_OK) + break; + + /*if the next char is a white space, consume it ! */ + if (cr_utils_is_white_space (cur_char) == TRUE) { + status = cr_input_read_char (a_this, &cur_char); + if (status != CR_OK) + break; + continue; + } + + break; + + } + + if (nb_consumed && status == CR_END_OF_INPUT_ERROR) { + status = CR_OK; + } + + return status; +} + +/** + *Same as cr_input_read_char() but does not update the + *internal state of the input stream. The next call + *to cr_input_peek_char() or cr_input_read_char() will thus + *return the same character as the current one. + *@param a_this the current instance of #CRInput. + *@param a_char out parameter. The returned character. + *@return CR_OK upon successful completion, an error code + *otherwise. + */ +enum CRStatus +cr_input_peek_char (CRInput * a_this, guint32 * a_char) +{ + enum CRStatus status = CR_OK; + glong consumed = 0, + nb_bytes_left = 0; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && a_char, CR_BAD_PARAM_ERROR); + + if (PRIVATE (a_this)->next_byte_index >= + PRIVATE (a_this)->in_buf_size) { + return CR_END_OF_INPUT_ERROR; + } + + nb_bytes_left = cr_input_get_nb_bytes_left (a_this); + + if (nb_bytes_left < 1) { + return CR_END_OF_INPUT_ERROR; + } + + status = cr_utils_read_char_from_utf8_buf + (PRIVATE (a_this)->in_buf + + PRIVATE (a_this)->next_byte_index, + nb_bytes_left, a_char, &consumed); + + return status; +} + +/** + *Gets a byte from the input stream, + *starting from the current position in the input stream. + *Unlike cr_input_peek_next_byte() this method + *does not update the state of the current input stream. + *Subsequent calls to cr_input_peek_byte with the same arguments + *will return the same byte. + * + *@param a_this the current instance of #CRInput. + *@param a_origin the origin to consider in the calculation + *of the position of the byte to peek. + *@param a_offset the offset of the byte to peek, starting from + *the origin specified by a_origin. + *@param a_byte out parameter the peeked byte. + *@return CR_OK upon successful completion or, + * + *
    + *
  • CR_BAD_PARAM_ERROR if at least one of the parameters is invalid
  • + *
  • CR_OUT_OF_BOUNDS_ERROR if the indexed byte is out of bounds
  • + *
+ */ +enum CRStatus +cr_input_peek_byte (CRInput * a_this, enum CRSeekPos a_origin, + gulong a_offset, guchar * a_byte) +{ + gulong abs_offset = 0; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && a_byte, CR_BAD_PARAM_ERROR); + + switch (a_origin) { + + case CR_SEEK_CUR: + abs_offset = PRIVATE (a_this)->next_byte_index - 1 + a_offset; + break; + + case CR_SEEK_BEGIN: + abs_offset = a_offset; + break; + + case CR_SEEK_END: + abs_offset = PRIVATE (a_this)->in_buf_size - 1 - a_offset; + break; + + default: + return CR_BAD_PARAM_ERROR; + } + + if (abs_offset < PRIVATE (a_this)->in_buf_size) { + + *a_byte = PRIVATE (a_this)->in_buf[abs_offset]; + + return CR_OK; + + } else { + return CR_END_OF_INPUT_ERROR; + } +} + +/** + *Same as cr_input_peek_byte() but with a simplified + *interface. + *@param a_this the current byte input stream. + *@param a_offset the offset of the byte to peek, starting + *from the current input position pointer. + *@param a_eof out parameter. Is set to true is we reach end of + *stream. If set to NULL by the caller, this parameter is not taken + *in account. + *@return the read byte or 0 if something bad happened. + */ +guchar +cr_input_peek_byte2 (CRInput * a_this, gulong a_offset, gboolean * a_eof) +{ + guchar result = 0; + enum CRStatus status = CR_ERROR; + + g_return_val_if_fail (a_this && PRIVATE (a_this), 0); + + if (a_eof) + *a_eof = FALSE; + + status = cr_input_peek_byte (a_this, CR_SEEK_CUR, a_offset, &result); + + if ((status == CR_END_OF_INPUT_ERROR) + && a_eof) + *a_eof = TRUE; + + return result; +} + +/** + *Returns the memory address of the byte located at a given offset + *in the input stream. + *@param a_this the current instance of #CRInput. + *@param a_offset the offset of the byte in the input stream starting + *from the beginning of the stream. + *@return the address, otherwise NULL if an error occured. + */ +guchar * +cr_input_get_byte_addr (CRInput * a_this, gulong a_offset) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this), NULL); + + if (a_offset >= PRIVATE (a_this)->nb_bytes) { + return NULL; + } + + return &PRIVATE (a_this)->in_buf[a_offset]; +} + +/** + *Returns the address of the current character pointer. + *@param a_this the current input stream + *@param a_offset out parameter. The returned address. + *@return CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_input_get_cur_byte_addr (CRInput * a_this, guchar ** a_offset) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this) && a_offset, + CR_BAD_PARAM_ERROR); + + if (!PRIVATE (a_this)->next_byte_index) { + return CR_START_OF_INPUT_ERROR; + } + + *a_offset = cr_input_get_byte_addr + (a_this, PRIVATE (a_this)->next_byte_index - 1); + + return CR_OK; +} + +/** + *Sets the "current byte index" of the current instance + *of #CRInput. Next call to cr_input_get_byte() will return + *the byte next after the new "current byte index". + * + *@param a_this the current instance of #CRInput. + * + *@param a_origin the origin to consider during the calculation + *of the absolute position of the new "current byte index". + * + *@param a_pos the relative offset of the new "current byte index." + *This offset is relative to the origin a_origin. + * + *@return CR_OK upon successful completion otherwise returns + *
    + *
  • CR_BAD_PARAM_ERROR if at least one of the parameters is not valid
  • + *
  • CR_OUT_BOUNDS_ERROR
  • + *
+ */ +enum CRStatus +cr_input_seek_index (CRInput * a_this, enum CRSeekPos a_origin, gint a_pos) +{ + + glong abs_offset = 0; + + g_return_val_if_fail (a_this && PRIVATE (a_this), CR_BAD_PARAM_ERROR); + + switch (a_origin) { + + case CR_SEEK_CUR: + abs_offset = PRIVATE (a_this)->next_byte_index - 1 + a_pos; + break; + + case CR_SEEK_BEGIN: + abs_offset = a_pos; + break; + + case CR_SEEK_END: + abs_offset = PRIVATE (a_this)->in_buf_size - 1 - a_pos; + break; + + default: + return CR_BAD_PARAM_ERROR; + } + + if ((abs_offset > 0) + && (gulong) abs_offset < PRIVATE (a_this)->nb_bytes) { + + /*update the input stream's internal state */ + PRIVATE (a_this)->next_byte_index = abs_offset + 1; + + return CR_OK; + } + + return CR_OUT_OF_BOUNDS_ERROR; +} + +/** + *Gets the position of the "current byte index" which + *is basically the position of the last returned byte in the + *input stream. + * + *@param a_this the current instance of #CRInput. + * + *@param a_pos out parameter. The returned position. + * + *@return CR_OK upon successful completion. Otherwise, + *
    + *
  • CR_BAD_PARAMETER_ERROR if at least one of the arguments is invalid.
  • + *
  • CR_START_OF_INPUT if no call to either cr_input_read_byte() + *or cr_input_seek_index() have been issued before calling + *cr_input_get_cur_pos()
  • + *
+ *Note that the out parameters of this function are valid if and only if this + *function returns CR_OK. + */ +enum CRStatus +cr_input_get_cur_pos (CRInput * a_this, CRInputPos * a_pos) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this) && a_pos, + CR_BAD_PARAM_ERROR); + + a_pos->next_byte_index = PRIVATE (a_this)->next_byte_index; + a_pos->line = PRIVATE (a_this)->line; + a_pos->col = PRIVATE (a_this)->col; + a_pos->end_of_line = PRIVATE (a_this)->end_of_line; + a_pos->end_of_file = PRIVATE (a_this)->end_of_input; + + return CR_OK; +} + +/** + *Gets the current parsing location. + *The Parsing location is a public datastructure that + *represents the current line/column/byte offset/ in the input + *stream. + *@param a_this the current instance of #CRInput + *@param a_loc the set parsing location. + *@return CR_OK upon successful completion, an error + *code otherwise. + */ +enum CRStatus +cr_input_get_parsing_location (CRInput *a_this, + CRParsingLocation *a_loc) +{ + g_return_val_if_fail (a_this + && PRIVATE (a_this) + && a_loc, + CR_BAD_PARAM_ERROR) ; + + a_loc->line = PRIVATE (a_this)->line ; + a_loc->column = PRIVATE (a_this)->col ; + if (PRIVATE (a_this)->next_byte_index) { + a_loc->byte_offset = PRIVATE (a_this)->next_byte_index - 1 ; + } else { + a_loc->byte_offset = PRIVATE (a_this)->next_byte_index ; + } + return CR_OK ; +} + +/** + *Getter of the next byte index. + *It actually returns the index of the + *next byte to be read. + *@param a_this the "this pointer" of the current instance of + *#CRInput + *@param a_index out parameter. The returned index. + *@return CR_OK upon successful completion, an error code + *otherwise. + */ +enum CRStatus +cr_input_get_cur_index (CRInput * a_this, glong * a_index) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this) + && a_index, CR_BAD_PARAM_ERROR); + + *a_index = PRIVATE (a_this)->next_byte_index; + + return CR_OK; +} + +/** + *Setter of the next byte index. + *It sets the index of the next byte to be read. + *@param a_this the "this pointer" of the current instance + *of #CRInput . + *@param a_index the new index to set. + *@return CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_input_set_cur_index (CRInput * a_this, glong a_index) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this), CR_BAD_PARAM_ERROR); + + PRIVATE (a_this)->next_byte_index = a_index; + + return CR_OK; +} + +/** + *Sets the end of file flag. + *@param a_this the current instance of #CRInput. + *@param a_eof the new end of file flag. + *@return CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_input_set_end_of_file (CRInput * a_this, gboolean a_eof) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this), CR_BAD_PARAM_ERROR); + + PRIVATE (a_this)->end_of_input = a_eof; + + return CR_OK; +} + +/** + *Gets the end of file flag. + *@param a_this the current instance of #CRInput. + *@param a_eof out parameter the place to put the end of + *file flag. + *@return CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_input_get_end_of_file (CRInput * a_this, gboolean * a_eof) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this) + && a_eof, CR_BAD_PARAM_ERROR); + + *a_eof = PRIVATE (a_this)->end_of_input; + + return CR_OK; +} + +/** + *Sets the end of line flag. + *@param a_this the current instance of #CRInput. + *@param a_eol the new end of line flag. + *@return CR_OK upon successful completion, an error code + *otherwise. + */ +enum CRStatus +cr_input_set_end_of_line (CRInput * a_this, gboolean a_eol) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this), CR_BAD_PARAM_ERROR); + + PRIVATE (a_this)->end_of_line = a_eol; + + return CR_OK; +} + +/** + *Gets the end of line flag of the current input. + *@param a_this the current instance of #CRInput + *@param a_eol out parameter. The place to put + *the returned flag + *@return CR_OK upon successful completion, an error code + *otherwise. + */ +enum CRStatus +cr_input_get_end_of_line (CRInput * a_this, gboolean * a_eol) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this) + && a_eol, CR_BAD_PARAM_ERROR); + + *a_eol = PRIVATE (a_this)->end_of_line; + + return CR_OK; +} + +/** + *Sets the current position in the input stream. + * + *@param a_this the "this pointer" of the current instance of + *#CRInput. + *@param a_pos the new position. + */ +enum CRStatus +cr_input_set_cur_pos (CRInput * a_this, CRInputPos * a_pos) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this) && a_pos, + CR_BAD_PARAM_ERROR); + + cr_input_set_column_num (a_this, a_pos->col); + cr_input_set_line_num (a_this, a_pos->line); + cr_input_set_cur_index (a_this, a_pos->next_byte_index); + cr_input_set_end_of_line (a_this, a_pos->end_of_line); + cr_input_set_end_of_file (a_this, a_pos->end_of_file); + + return CR_OK; +} diff --git a/src/libcroco/cr-input.h b/src/libcroco/cr-input.h new file mode 100644 index 000000000..976b73fb0 --- /dev/null +++ b/src/libcroco/cr-input.h @@ -0,0 +1,174 @@ +/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset:8 -*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * Author: Dodji Seketeli + * See the COPYRIGHTS file for copyrights information. + */ + +#ifndef __CR_INPUT_SRC_H__ +#define __CR_INPUT_SRC_H__ + + +#include +#include "cr-utils.h" +#include "cr-parsing-location.h" + +G_BEGIN_DECLS + +/** + *@file + *The libcroco basic input stream class + *declaration file. + */ + +typedef struct _CRInput CRInput ; +typedef struct _CRInputPriv CRInputPriv ; + +/** + *The #CRInput class provides the abstraction of + *an utf8-encoded character stream. + */ +struct _CRInput +{ + CRInputPriv *priv ; +} ; + +typedef struct _CRInputPos CRInputPos ; + +struct _CRInputPos +{ + glong line ; + glong col ; + gboolean end_of_file ; + gboolean end_of_line ; + glong next_byte_index ; +} ; + +CRInput * +cr_input_new_from_buf (guchar *a_buf, gulong a_len, + enum CREncoding a_enc, gboolean a_free_buf) ; +CRInput * +cr_input_new_from_uri (const gchar *a_file_uri, + enum CREncoding a_enc) ; + +void +cr_input_destroy (CRInput *a_this) ; + +void +cr_input_ref (CRInput *a_this) ; + +gboolean +cr_input_unref (CRInput *a_this) ; + +enum CRStatus +cr_input_read_byte (CRInput *a_this, guchar *a_byte) ; + +enum CRStatus +cr_input_read_char (CRInput *a_this, guint32 *a_char) ; + +enum CRStatus +cr_input_consume_chars (CRInput *a_this, guint32 a_char, + gulong *a_nb_char) ; + +enum CRStatus +cr_input_consume_char (CRInput *a_this, guint32 a_char) ; + +enum CRStatus +cr_input_consume_white_spaces (CRInput *a_this, gulong *a_nb_chars) ; + +enum CRStatus +cr_input_peek_byte (CRInput *a_this, enum CRSeekPos a_origin, + gulong a_offset, guchar *a_byte) ; + +guchar +cr_input_peek_byte2 (CRInput *a_this, gulong a_offset, + gboolean *a_eof) ; + +enum CRStatus +cr_input_peek_char (CRInput *a_this, guint32 *a_char) ; + +guchar * +cr_input_get_byte_addr (CRInput *a_this, + gulong a_offset) ; + +enum CRStatus +cr_input_get_cur_byte_addr (CRInput *a_this, guchar ** a_offset) ; + +enum CRStatus +cr_input_seek_index (CRInput *a_this, + enum CRSeekPos a_origin, gint a_pos) ; + +enum CRStatus +cr_input_get_cur_index (CRInput *a_this, glong *a_index) ; + +enum CRStatus +cr_input_set_cur_index (CRInput *a_this, glong a_index) ; + +enum CRStatus +cr_input_get_cur_pos (CRInput *a_this, CRInputPos * a_pos) ; + +enum CRStatus +cr_input_set_cur_pos (CRInput *a_this, CRInputPos *a_pos) ; + +enum CRStatus +cr_input_get_parsing_location (CRInput *a_this, + CRParsingLocation *a_loc) ; + +enum CRStatus +cr_input_get_end_of_line (CRInput *a_this, gboolean *a_eol) ; + +enum CRStatus +cr_input_set_end_of_line (CRInput *a_this, gboolean a_eol) ; + +enum CRStatus +cr_input_get_end_of_file (CRInput *a_this, gboolean *a_eof) ; + +enum CRStatus +cr_input_set_end_of_file (CRInput *a_this, gboolean a_eof) ; + +enum CRStatus +cr_input_set_line_num (CRInput *a_this, glong a_line_num) ; + +enum CRStatus +cr_input_get_line_num (CRInput *a_this, glong *a_line_num) ; + +enum CRStatus +cr_input_set_column_num (CRInput *a_this, glong a_col) ; + +enum CRStatus +cr_input_get_column_num (CRInput *a_this, glong *a_col) ; + +enum CRStatus +cr_input_increment_line_num (CRInput *a_this, + glong a_increment) ; + +enum CRStatus +cr_input_increment_col_num (CRInput *a_this, + glong a_increment) ; + +glong +cr_input_get_nb_bytes_left (CRInput *a_this) ; + +enum CRStatus +cr_input_end_of_input (CRInput *a_this, gboolean *a_end_of_input) ; + +G_END_DECLS + +#endif /*__CR_INPUT_SRC_H__*/ + diff --git a/src/libcroco/cr-libxml-node-iface.c b/src/libcroco/cr-libxml-node-iface.c new file mode 100644 index 000000000..fe785491b --- /dev/null +++ b/src/libcroco/cr-libxml-node-iface.c @@ -0,0 +1,81 @@ +#include +#include +#include "cr-libxml-node-iface.h" + +static CRXMLNodePtr +libxml_getParentNode(CRXMLNodePtr cnode) +{ + xmlNode const *xnode = (xmlNode const *) cnode; + return xnode->parent; +} + +static CRXMLNodePtr +libxml_getFirstChild(CRXMLNodePtr cnode) +{ + xmlNode const *xnode = (xmlNode const *) cnode; + return xnode->children; +} + +static CRXMLNodePtr +libxml_getNextSibling(CRXMLNodePtr cnode) +{ + xmlNode const *xnode = (xmlNode const *) cnode; + return xnode->next; +} + +static CRXMLNodePtr +libxml_getPrevSibling(CRXMLNodePtr cnode) +{ + xmlNode const *xnode = (xmlNode const *) cnode; + return xnode->prev; +} + +static char const * +local_part(char const *const qname) +{ + char const *ret = strrchr(qname, ':'); + if (ret) + return ++ret; + else + return qname; +} + +static char const * +libxml_getLocalName(CRXMLNodePtr cnode) +{ + xmlNode const *xnode = (xmlNode const *) cnode; + return local_part(xnode->name); +} + +static char * +libxml_getProp(CRXMLNodePtr cnode, char const *cprop) +{ + xmlNodePtr xnode = (xmlNodePtr) cnode; + xmlChar const *xprop = (xmlChar const *) cprop; + return xmlGetProp(xnode, xprop); +} + +static gboolean +libxml_isElementNode(CRXMLNodePtr cnode) +{ + xmlNode const *xnode = (xmlNode const *) cnode; + return xnode->type == XML_ELEMENT_NODE; +} + +static void +libxml_freePropVal(void *const cval) +{ + xmlFree(cval); +} + +CRNodeIface const cr_libxml_node_iface = { + libxml_getParentNode, + libxml_getFirstChild, + libxml_getNextSibling, + libxml_getPrevSibling, + libxml_getLocalName, + libxml_getProp, /* fixme: Check whether we want xmlGetNoNsProp instead. */ + + libxml_freePropVal, + libxml_isElementNode +}; diff --git a/src/libcroco/cr-libxml-node-iface.h b/src/libcroco/cr-libxml-node-iface.h new file mode 100644 index 000000000..cb9bf2733 --- /dev/null +++ b/src/libcroco/cr-libxml-node-iface.h @@ -0,0 +1,14 @@ +#ifndef __CR_LIBXML_NODE_IFACE_H__ +#define __CR_LIBXML_NODE_IFACE_H__ + +#include +#include "cr-node-iface.h" + +G_BEGIN_DECLS + +CRNodeIface const cr_libxml_node_iface; + +G_END_DECLS + + +#endif/*__CR_LIBXML_NODE_IFACE_H__*/ diff --git a/src/libcroco/cr-node-iface.h b/src/libcroco/cr-node-iface.h new file mode 100644 index 000000000..9c2d30efe --- /dev/null +++ b/src/libcroco/cr-node-iface.h @@ -0,0 +1,35 @@ +#ifndef __CR_NODE_IFACE_H__ +#define __CR_NODE_IFACE_H__ + +#include +#include + +G_BEGIN_DECLS + +typedef gconstpointer CRXMLNodePtr ; +typedef struct _CRNodeIface CRNodeIface ; + +struct _CRNodeIface { + /* Names based on DOM. */ + CRXMLNodePtr (*getParentNode)(CRXMLNodePtr); + CRXMLNodePtr (*getFirstChild)(CRXMLNodePtr); + CRXMLNodePtr (*getNextSibling)(CRXMLNodePtr); + CRXMLNodePtr (*getPrevSibling)(CRXMLNodePtr); + char const *(*getLocalName)(CRXMLNodePtr); + char *(*getProp)(CRXMLNodePtr, char const *); + + /* Others. */ + void (*freePropVal)(void *); + gboolean (*isElementNode)(CRXMLNodePtr); + +#if 0 + char const *getLang(CRXMLNodePtr); + /* todo: Make it easy to have the default xml rules for lang. Maybe interpret NULL + like this. Or provide a cr_get_xml_lang(CRNodeIface const *, CRXMLNodePtr) function. */ +#endif +}; + +G_END_DECLS + + +#endif/*__CR_NODE_IFACE_H__*/ diff --git a/src/libcroco/cr-num.c b/src/libcroco/cr-num.c new file mode 100644 index 000000000..45a63281b --- /dev/null +++ b/src/libcroco/cr-num.c @@ -0,0 +1,299 @@ +/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */ + +/* + * This file is part of The Croco Library + * + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * Author: Dodji Seketeli + * See COPYRIGHTS file for copyrights information. + */ + +/** + *@file + *The definition + *of the #CRNum class. + */ + +#include "cr-num.h" +#include "string.h" + +/** + *The default constructor of + *#CRNum. + *@return the newly built instance of + *#CRNum. + */ +CRNum * +cr_num_new (void) +{ + CRNum *result = NULL; + + result = g_try_malloc (sizeof (CRNum)); + + if (result == NULL) { + cr_utils_trace_info ("Out of memory"); + return NULL; + } + + memset (result, 0, sizeof (CRNum)); + + return result; +} + +/** + *A constructor of #CRNum. + *@param a_is_natural indicates whether the intance of #CRNum is + *a natural number or not. + *@param a_integer_part the integer part of the instance + *of #CRNum + *@param a_decimal_part in case the instance of #CRNum + *natural number (but a decimal one) this parameter + *is the decimal part of the instance of #CRNum. + *@return the newly built instance of #CRNum or + *NULL if an error arises. + */ +CRNum * +cr_num_new_with_val (gdouble a_val, enum CRNumType a_type) +{ + CRNum *result = NULL; + + result = cr_num_new (); + + g_return_val_if_fail (result, NULL); + + result->val = a_val; + result->type = a_type; + + return result; +} + +/** + *Returns the string representation of the + *current instance of #CRNum. + *@param a_this the current instance of #CRNum. + *@return the newly built string representation + *of the current instance of #CRNum. The returned + *string is NULL terminated. The caller *must* + *free the returned string. + */ +guchar * +cr_num_to_string (CRNum * a_this) +{ + gdouble test_val = 0.0; + + guchar *tmp_char1 = NULL, + *tmp_char2 = NULL, + *result = NULL; + + g_return_val_if_fail (a_this, NULL); + + test_val = a_this->val - (glong) a_this->val; + + if (!test_val) { + tmp_char1 = g_strdup_printf ("%ld", (glong) a_this->val); + } else { + /* We can't use g_ascii_dtostr, because that sometimes uses + e notation (which wouldn't be a valid number in CSS). */ + size_t const buflen = 35; /* fairly arbitrary. */ + tmp_char1 = g_malloc (buflen); + g_ascii_formatd (tmp_char1, buflen, "%.17f", a_this->val); + } + + g_return_val_if_fail (tmp_char1, NULL); + + switch (a_this->type) { + case NUM_LENGTH_EM: + tmp_char2 = (guchar *) "em"; + break; + + case NUM_LENGTH_EX: + tmp_char2 = (guchar *) "ex"; + break; + + case NUM_LENGTH_PX: + tmp_char2 = (guchar *) "px"; + break; + + case NUM_LENGTH_IN: + tmp_char2 = (guchar *) "in"; + break; + + case NUM_LENGTH_CM: + tmp_char2 = (guchar *) "cm"; + break; + + case NUM_LENGTH_MM: + tmp_char2 = (guchar *) "mm"; + break; + + case NUM_LENGTH_PT: + tmp_char2 = (guchar *) "pt"; + break; + + case NUM_LENGTH_PC: + tmp_char2 = (guchar *) "pc"; + break; + + case NUM_ANGLE_DEG: + tmp_char2 = (guchar *) "deg"; + break; + + case NUM_ANGLE_RAD: + tmp_char2 = (guchar *) "rad"; + break; + + case NUM_ANGLE_GRAD: + tmp_char2 = (guchar *) "grad"; + break; + + case NUM_TIME_MS: + tmp_char2 = (guchar *) "ms"; + break; + + case NUM_TIME_S: + tmp_char2 = (guchar *) "s"; + break; + + case NUM_FREQ_HZ: + tmp_char2 = (guchar *) "Hz"; + break; + + case NUM_FREQ_KHZ: + tmp_char2 = (guchar *) "KHz"; + break; + + case NUM_PERCENTAGE: + tmp_char2 = (guchar *) "%"; + break; + case NUM_INHERIT: + tmp_char2 = (guchar *) "inherit"; + break ; + case NUM_AUTO: + tmp_char2 = (guchar *) "auto"; + break ; + case NUM_GENERIC: + tmp_char2 = NULL ; + break ; + default: + tmp_char2 = (guchar *) "unknown"; + break; + } + + if (tmp_char2) { + result = g_strconcat (tmp_char1, tmp_char2, NULL); + g_free (tmp_char1); + } else { + result = tmp_char1; + } + + return result; +} + +/** + *Copies an instance of #CRNum. + *@param a_src the instance of #CRNum to copy. + *Must be non NULL. + *@param a_dst the destination of the copy. + *Must be non NULL + *@return CR_OK upon successful completion, an + *error code otherwise. + */ +enum CRStatus +cr_num_copy (CRNum * a_dest, CRNum * a_src) +{ + g_return_val_if_fail (a_dest && a_src, CR_BAD_PARAM_ERROR); + + memcpy (a_dest, a_src, sizeof (CRNum)); + + return CR_OK; +} + +/** + *Duplicates an instance of #CRNum + *@param a_this the instance of #CRNum to duplicate. + *@return the newly created (duplicated) instance of #CRNum. + *Must be freed by cr_num_destroy(). + */ +CRNum * +cr_num_dup (CRNum * a_this) +{ + CRNum *result = NULL; + enum CRStatus status = CR_OK; + + g_return_val_if_fail (a_this, NULL); + + result = cr_num_new (); + g_return_val_if_fail (result, NULL); + + status = cr_num_copy (result, a_this); + g_return_val_if_fail (status == CR_OK, NULL); + + return result; +} + +/** + *Sets an instance of #CRNum. + *@param a_this the current instance of #CRNum to be set. + *@param a_val the new numerical value to be hold by the current + *instance of #CRNum + *@param a_type the new type of #CRNum. + */ +enum CRStatus +cr_num_set (CRNum * a_this, gdouble a_val, enum CRNumType a_type) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + a_this->val = a_val; + a_this->type = a_type; + + return CR_OK; +} + +/** + *Tests if the current instance of #CRNum is a fixed + *length value or not. Typically a fixed length value + *is anything from NUM_LENGTH_EM to NUM_LENGTH_PC. + *See the definition of #CRNumType to see what we mean. + *@return TRUE if the instance of #CRNum is a fixed length number, + *FALSE otherwise. + */ +gboolean +cr_num_is_fixed_length (CRNum * a_this) +{ + gboolean result = FALSE; + + g_return_val_if_fail (a_this, FALSE); + + if (a_this->type >= NUM_LENGTH_EM + && a_this->type <= NUM_LENGTH_PC) { + result = TRUE ; + } + return result ; +} + +/** + *The destructor of #CRNum. + *@param a_this the this pointer of + *the current instance of #CRNum. + */ +void +cr_num_destroy (CRNum * a_this) +{ + g_return_if_fail (a_this); + + g_free (a_this); +} diff --git a/src/libcroco/cr-num.h b/src/libcroco/cr-num.h new file mode 100644 index 000000000..83e9dc7c6 --- /dev/null +++ b/src/libcroco/cr-num.h @@ -0,0 +1,127 @@ +/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * Author: Dodji Seketeli + * See COPYRIGHTS file for copyright information + */ + + +/** + *@file + *The declaration + *of the #CRNum class. + */ + +#ifndef __CR_NUM_H__ +#define __CR_NUM_H__ + +#include +#include "cr-utils.h" +#include "cr-parsing-location.h" + +G_BEGIN_DECLS + +/** + *@file + *The declaration of the #CRNum class. + * + */ + +/** + *The different types + *of numbers. + *Please, do not modify + *the declaration order of the enum + *members, unless you know + *what you are doing. + */ +enum CRNumType +{ + NUM_AUTO = 0, + NUM_GENERIC, + NUM_LENGTH_EM, + NUM_LENGTH_EX, + NUM_LENGTH_PX, + NUM_LENGTH_IN, + NUM_LENGTH_CM, + NUM_LENGTH_MM, + NUM_LENGTH_PT, + NUM_LENGTH_PC, + NUM_ANGLE_DEG, + NUM_ANGLE_RAD, + NUM_ANGLE_GRAD, + NUM_TIME_MS, + NUM_TIME_S, + NUM_FREQ_HZ, + NUM_FREQ_KHZ, + NUM_PERCENTAGE, + NUM_INHERIT, + NUM_UNKNOWN_TYPE, + NB_NUM_TYPE +} ; + + +/** + *An abstraction of a number (num) + *as defined in the css2 spec. + */ +typedef struct _CRNum CRNum ; + +/** + *An abstraction of a number (num) + *as defined in the css2 spec. + */ +struct _CRNum +{ + enum CRNumType type ; + gdouble val ; + CRParsingLocation location ; +} ; + +CRNum * +cr_num_new (void) ; + +CRNum * +cr_num_new_with_val (gdouble a_val, + enum CRNumType a_type) ; + +CRNum * +cr_num_dup (CRNum *a_this) ; + +guchar * +cr_num_to_string (CRNum *a_this) ; + +enum CRStatus +cr_num_copy (CRNum *a_dest, CRNum *a_src) ; + +enum CRStatus +cr_num_set (CRNum *a_this, gdouble a_val, + enum CRNumType a_type) ; + +gboolean +cr_num_is_fixed_length (CRNum *a_this) ; + +void +cr_num_destroy (CRNum *a_this) ; + + +G_END_DECLS + + +#endif /*__CR_NUM_H__*/ diff --git a/src/libcroco/cr-om-parser.c b/src/libcroco/cr-om-parser.c new file mode 100644 index 000000000..245f2d82f --- /dev/null +++ b/src/libcroco/cr-om-parser.c @@ -0,0 +1,1107 @@ +/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * Author: Dodji Seketeli + * See COPYRIGHTS file for copyright information. + */ + +#include +#include "cr-utils.h" +#include "cr-om-parser.h" + +#define UNUSED(_param) ((void)(_param)) + +/** + *@file + *The definition of the CSS Object Model Parser. + *This parser uses (and sits) the SAC api of libcroco defined + *in cr-parser.h and cr-doc-handler.h + */ + +struct _CROMParserPriv { + CRParser *parser; +}; + +#define PRIVATE(a_this) ((a_this)->priv) + +/* + *Forward declaration of a type defined later + *in this file. + */ +struct _ParsingContext; +typedef struct _ParsingContext ParsingContext; + +static ParsingContext *new_parsing_context (void); + +static void destroy_context (ParsingContext * a_ctxt); + +static void unrecoverable_error (CRDocHandler * a_this); + +static void error (CRDocHandler * a_this); + +static void property (CRDocHandler * a_this, + CRString * a_name, + CRTerm * a_expression, + gboolean a_important); + +static void end_selector (CRDocHandler * a_this, + CRSelector * a_selector_list); + +static void start_selector (CRDocHandler * a_this, + CRSelector * a_selector_list); + +static void start_font_face (CRDocHandler * a_this, + CRParsingLocation *a_location); + +static void end_font_face (CRDocHandler * a_this); + +static void end_document (CRDocHandler * a_this); + +static void start_document (CRDocHandler * a_this); + +static void charset (CRDocHandler * a_this, + CRString * a_charset, + CRParsingLocation *a_location); + +static void start_page (CRDocHandler * a_this, CRString * a_page, + CRString * a_pseudo_page, + CRParsingLocation *a_location); + +static void end_page (CRDocHandler * a_this, CRString * a_page, + CRString * a_pseudo_page); + +static void start_media (CRDocHandler * a_this, + GList * a_media_list, + CRParsingLocation *a_location); + +static void end_media (CRDocHandler * a_this, + GList * a_media_list); + +static void import_style (CRDocHandler * a_this, + GList * a_media_list, + CRString * a_uri, + CRString * a_uri_default_ns, + CRParsingLocation *a_location); + +struct _ParsingContext { + CRStyleSheet *stylesheet; + CRStatement *cur_stmt; + CRStatement *cur_media_stmt; +}; + +/******************************************** + *Private methods + ********************************************/ + +static ParsingContext * +new_parsing_context (void) +{ + ParsingContext *result = NULL; + + result = g_try_malloc (sizeof (ParsingContext)); + if (!result) { + cr_utils_trace_info ("Out of Memory"); + return NULL; + } + memset (result, 0, sizeof (ParsingContext)); + return result; +} + +static void +destroy_context (ParsingContext * a_ctxt) +{ + g_return_if_fail (a_ctxt); + + if (a_ctxt->stylesheet) { + cr_stylesheet_destroy (a_ctxt->stylesheet); + a_ctxt->stylesheet = NULL; + } + if (a_ctxt->cur_stmt) { + cr_statement_destroy (a_ctxt->cur_stmt); + a_ctxt->cur_stmt = NULL; + } + g_free (a_ctxt); +} + +static enum CRStatus +cr_om_parser_init_default_sac_handler (CROMParser * a_this) +{ + CRDocHandler *sac_handler = NULL; + gboolean free_hdlr_if_error = FALSE; + enum CRStatus status = CR_OK; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && PRIVATE (a_this)->parser, + CR_BAD_PARAM_ERROR); + + status = cr_parser_get_sac_handler (PRIVATE (a_this)->parser, + &sac_handler); + g_return_val_if_fail (status == CR_OK, status); + + if (!sac_handler) { + sac_handler = cr_doc_handler_new (); + free_hdlr_if_error = TRUE; + } + + /* + *initialyze here the sac handler. + */ + sac_handler->start_document = start_document; + sac_handler->end_document = end_document; + sac_handler->start_selector = start_selector; + sac_handler->end_selector = end_selector; + sac_handler->property = property; + sac_handler->start_font_face = start_font_face; + sac_handler->end_font_face = end_font_face; + sac_handler->error = error; + sac_handler->unrecoverable_error = unrecoverable_error; + sac_handler->charset = charset; + sac_handler->start_page = start_page; + sac_handler->end_page = end_page; + sac_handler->start_media = start_media; + sac_handler->end_media = end_media; + sac_handler->import_style = import_style; + + status = cr_parser_set_sac_handler (PRIVATE (a_this)->parser, + sac_handler); + if (status == CR_OK) { + return CR_OK; + } + + if (sac_handler && free_hdlr_if_error == TRUE) { + cr_doc_handler_destroy (sac_handler); + sac_handler = NULL; + } + + return status; + +} + +static void +start_document (CRDocHandler * a_this) +{ + ParsingContext *ctxt = NULL; + CRStyleSheet *stylesheet = NULL; + + g_return_if_fail (a_this); + + ctxt = new_parsing_context (); + g_return_if_fail (ctxt); + + stylesheet = cr_stylesheet_new (NULL); + ctxt->stylesheet = stylesheet; + cr_doc_handler_set_ctxt (a_this, ctxt); +} + +static void +start_font_face (CRDocHandler * a_this, + CRParsingLocation *a_location) +{ + enum CRStatus status = CR_OK; + ParsingContext *ctxt = NULL; + ParsingContext **ctxtptr = NULL; + + UNUSED(a_location); + + g_return_if_fail (a_this); + ctxtptr = &ctxt; + status = cr_doc_handler_get_ctxt (a_this, (gpointer *) ctxtptr); + g_return_if_fail (status == CR_OK && ctxt); + g_return_if_fail (ctxt->cur_stmt == NULL); + + ctxt->cur_stmt = + cr_statement_new_at_font_face_rule (ctxt->stylesheet, NULL); + + g_return_if_fail (ctxt->cur_stmt); +} + +static void +end_font_face (CRDocHandler * a_this) +{ + enum CRStatus status = CR_OK; + ParsingContext *ctxt = NULL; + ParsingContext **ctxtptr = NULL; + CRStatement *stmts = NULL; + + g_return_if_fail (a_this); + + g_return_if_fail (a_this); + ctxtptr = &ctxt; + status = cr_doc_handler_get_ctxt (a_this, (gpointer *) ctxtptr); + g_return_if_fail (status == CR_OK && ctxt); + g_return_if_fail + (ctxt->cur_stmt + && ctxt->cur_stmt->type == AT_FONT_FACE_RULE_STMT + && ctxt->stylesheet); + + stmts = cr_statement_append (ctxt->stylesheet->statements, + ctxt->cur_stmt); + if (!stmts) + goto error; + + ctxt->stylesheet->statements = stmts; + stmts = NULL; + ctxt->cur_stmt = NULL; + + return; + + error: + + if (ctxt->cur_stmt) { + cr_statement_destroy (ctxt->cur_stmt); + ctxt->cur_stmt = NULL; + } + + if (!stmts) { + cr_statement_destroy (stmts); + stmts = NULL; + } +} + +static void +end_document (CRDocHandler * a_this) +{ + enum CRStatus status = CR_OK; + ParsingContext *ctxt = NULL; + ParsingContext **ctxtptr = NULL; + + g_return_if_fail (a_this); + ctxtptr = &ctxt; + status = cr_doc_handler_get_ctxt (a_this, (gpointer *) ctxtptr); + g_return_if_fail (status == CR_OK && ctxt); + + if (!ctxt->stylesheet || ctxt->cur_stmt) + goto error; + + status = cr_doc_handler_set_result (a_this, ctxt->stylesheet); + g_return_if_fail (status == CR_OK); + + ctxt->stylesheet = NULL; + destroy_context (ctxt); + cr_doc_handler_set_ctxt (a_this, NULL); + + return; + + error: + if (ctxt) { + destroy_context (ctxt); + } +} + +static void +charset (CRDocHandler * a_this, CRString * a_charset, + CRParsingLocation *a_location) +{ + enum CRStatus status = CR_OK; + CRStatement *stmt = NULL, + *stmt2 = NULL; + CRString *charset = NULL; + + ParsingContext *ctxt = NULL; + ParsingContext **ctxtptr = NULL; + + UNUSED(a_location); + + g_return_if_fail (a_this); + ctxtptr = &ctxt; + status = cr_doc_handler_get_ctxt (a_this, (gpointer *) ctxtptr); + g_return_if_fail (status == CR_OK && ctxt); + g_return_if_fail (ctxt->stylesheet); + + charset = cr_string_dup (a_charset) ; + stmt = cr_statement_new_at_charset_rule (ctxt->stylesheet, charset); + g_return_if_fail (stmt); + stmt2 = cr_statement_append (ctxt->stylesheet->statements, stmt); + if (!stmt2) { + if (stmt) { + cr_statement_destroy (stmt); + stmt = NULL; + } + if (charset) { + cr_string_destroy (charset); + } + return; + } + ctxt->stylesheet->statements = stmt2; + stmt2 = NULL; +} + +static void +start_page (CRDocHandler * a_this, + CRString * a_page, + CRString * a_pseudo, + CRParsingLocation *a_location) +{ + enum CRStatus status = CR_OK; + ParsingContext *ctxt = NULL; + ParsingContext **ctxtptr = NULL; + + UNUSED(a_location); + + g_return_if_fail (a_this); + ctxtptr = &ctxt; + status = cr_doc_handler_get_ctxt (a_this, (gpointer *) ctxtptr); + g_return_if_fail (status == CR_OK && ctxt); + g_return_if_fail (ctxt->cur_stmt == NULL); + + ctxt->cur_stmt = cr_statement_new_at_page_rule + (ctxt->stylesheet, NULL, NULL, NULL); + if (a_page) { + ctxt->cur_stmt->kind.page_rule->name = + cr_string_dup (a_page) ; + + if (!ctxt->cur_stmt->kind.page_rule->name) { + goto error; + } + } + if (a_pseudo) { + ctxt->cur_stmt->kind.page_rule->pseudo = + cr_string_dup (a_pseudo) ; + if (!ctxt->cur_stmt->kind.page_rule->pseudo) { + goto error; + } + } + return; + + error: + if (ctxt->cur_stmt) { + cr_statement_destroy (ctxt->cur_stmt); + ctxt->cur_stmt = NULL; + } +} + +static void +end_page (CRDocHandler * a_this, + CRString * a_page, + CRString * a_pseudo_page) +{ + enum CRStatus status = CR_OK; + ParsingContext *ctxt = NULL; + ParsingContext **ctxtptr = NULL; + CRStatement *stmt = NULL; + + g_return_if_fail (a_this); + ctxtptr = &ctxt; + status = cr_doc_handler_get_ctxt (a_this, (gpointer *) ctxtptr); + g_return_if_fail (status == CR_OK && ctxt); + g_return_if_fail (ctxt->cur_stmt + && ctxt->cur_stmt->type == AT_PAGE_RULE_STMT + && ctxt->stylesheet); + + stmt = cr_statement_append (ctxt->stylesheet->statements, + ctxt->cur_stmt); + + if (stmt) { + ctxt->stylesheet->statements = stmt; + stmt = NULL; + ctxt->cur_stmt = NULL; + } + + if (ctxt->cur_stmt) { + cr_statement_destroy (ctxt->cur_stmt); + ctxt->cur_stmt = NULL; + } + a_page = NULL; /*keep compiler happy */ + a_pseudo_page = NULL; /*keep compiler happy */ +} + +static void +start_media (CRDocHandler * a_this, + GList * a_media_list, + CRParsingLocation *a_location) +{ + enum CRStatus status = CR_OK; + ParsingContext *ctxt = NULL; + ParsingContext **ctxtptr = NULL; + GList *media_list = NULL; + + UNUSED(a_location); + + g_return_if_fail (a_this); + ctxtptr = &ctxt; + status = cr_doc_handler_get_ctxt (a_this, (gpointer *) ctxtptr); + g_return_if_fail (status == CR_OK && ctxt); + + g_return_if_fail (ctxt + && ctxt->cur_stmt == NULL + && ctxt->cur_media_stmt == NULL + && ctxt->stylesheet); + if (a_media_list) { + /*duplicate the media_list */ + media_list = cr_utils_dup_glist_of_cr_string + (a_media_list); + } + ctxt->cur_media_stmt = + cr_statement_new_at_media_rule + (ctxt->stylesheet, NULL, media_list); + +} + +static void +end_media (CRDocHandler * a_this, GList * a_media_list) +{ + enum CRStatus status = CR_OK; + ParsingContext *ctxt = NULL; + ParsingContext **ctxtptr = NULL; + CRStatement *stmts = NULL; + + g_return_if_fail (a_this); + ctxtptr = &ctxt; + status = cr_doc_handler_get_ctxt (a_this, (gpointer *) ctxtptr); + g_return_if_fail (status == CR_OK && ctxt); + g_return_if_fail (ctxt + && ctxt->cur_media_stmt + && ctxt->cur_media_stmt->type == AT_MEDIA_RULE_STMT + && ctxt->stylesheet); + + stmts = cr_statement_append (ctxt->stylesheet->statements, + ctxt->cur_media_stmt); + if (!stmts) { + cr_statement_destroy (ctxt->cur_media_stmt); + ctxt->cur_media_stmt = NULL; + } + + ctxt->stylesheet->statements = stmts; + stmts = NULL; + + ctxt->cur_stmt = NULL ; + ctxt->cur_media_stmt = NULL ; + a_media_list = NULL; +} + +static void +import_style (CRDocHandler * a_this, + GList * a_media_list, + CRString * a_uri, + CRString * a_uri_default_ns, + CRParsingLocation *a_location) +{ + enum CRStatus status = CR_OK; + CRString *uri = NULL; + CRStatement *stmt = NULL, + *stmt2 = NULL; + ParsingContext *ctxt = NULL; + ParsingContext **ctxtptr = NULL; + GList *media_list = NULL ; + + UNUSED(a_location); + + g_return_if_fail (a_this); + ctxtptr = &ctxt; + status = cr_doc_handler_get_ctxt (a_this, (gpointer *) ctxtptr); + g_return_if_fail (status == CR_OK && ctxt); + g_return_if_fail (ctxt->stylesheet); + + uri = cr_string_dup (a_uri) ; + if (a_media_list) + media_list = cr_utils_dup_glist_of_cr_string (a_media_list) ; + stmt = cr_statement_new_at_import_rule + (ctxt->stylesheet, uri, media_list, NULL); + if (!stmt) + goto error; + + if (ctxt->cur_stmt) { + stmt2 = cr_statement_append (ctxt->cur_stmt, stmt); + if (!stmt2) + goto error; + ctxt->cur_stmt = stmt2; + stmt2 = NULL; + stmt = NULL; + } else { + stmt2 = cr_statement_append (ctxt->stylesheet->statements, + stmt); + if (!stmt2) + goto error; + ctxt->stylesheet->statements = stmt2; + stmt2 = NULL; + stmt = NULL; + } + + return; + + error: + if (uri) { + cr_string_destroy (uri); + } + + if (stmt) { + cr_statement_destroy (stmt); + stmt = NULL; + } + a_uri_default_ns = NULL; /*keep compiler happy */ +} + +static void +start_selector (CRDocHandler * a_this, CRSelector * a_selector_list) +{ + enum CRStatus status = CR_OK ; + ParsingContext *ctxt = NULL; + ParsingContext **ctxtptr = NULL; + + g_return_if_fail (a_this); + ctxtptr = &ctxt; + status = cr_doc_handler_get_ctxt (a_this, (gpointer *) ctxtptr); + g_return_if_fail (status == CR_OK && ctxt); + if (ctxt->cur_stmt) { + /*hmm, this should be NULL so free it */ + cr_statement_destroy (ctxt->cur_stmt); + ctxt->cur_stmt = NULL; + } + + ctxt->cur_stmt = cr_statement_new_ruleset + (ctxt->stylesheet, a_selector_list, NULL, NULL); +} + +static void +end_selector (CRDocHandler * a_this, CRSelector * a_selector_list) +{ + enum CRStatus status = CR_OK; + ParsingContext *ctxt = NULL; + ParsingContext **ctxtptr = NULL; + + g_return_if_fail (a_this); + ctxtptr = &ctxt; + status = cr_doc_handler_get_ctxt (a_this, (gpointer *) ctxtptr); + g_return_if_fail (status == CR_OK && ctxt); + g_return_if_fail (ctxt->cur_stmt && ctxt->stylesheet); + + if (ctxt->cur_stmt) { + CRStatement *stmts = NULL; + + if (ctxt->cur_media_stmt) { + CRAtMediaRule *media_rule = NULL; + + media_rule = ctxt->cur_media_stmt->kind.media_rule; + + stmts = cr_statement_append + (media_rule->rulesets, ctxt->cur_stmt); + + if (!stmts) { + cr_utils_trace_info + ("Could not append a new statement"); + cr_statement_destroy (media_rule->rulesets); + ctxt->cur_media_stmt-> + kind.media_rule->rulesets = NULL; + return; + } + media_rule->rulesets = stmts; + ctxt->cur_stmt = NULL; + } else { + stmts = cr_statement_append + (ctxt->stylesheet->statements, + ctxt->cur_stmt); + if (!stmts) { + cr_utils_trace_info + ("Could not append a new statement"); + cr_statement_destroy (ctxt->cur_stmt); + ctxt->cur_stmt = NULL; + return; + } + ctxt->stylesheet->statements = stmts; + ctxt->cur_stmt = NULL; + } + + } + a_selector_list = NULL; /*keep compiler happy */ +} + +static void +property (CRDocHandler * a_this, + CRString * a_name, + CRTerm * a_expression, + gboolean a_important) +{ + enum CRStatus status = CR_OK; + ParsingContext *ctxt = NULL; + ParsingContext **ctxtptr = NULL; + CRDeclaration *decl = NULL, + *decl2 = NULL; + CRString *str = NULL; + + g_return_if_fail (a_this); + ctxtptr = &ctxt; + status = cr_doc_handler_get_ctxt (a_this, (gpointer *) ctxtptr); + g_return_if_fail (status == CR_OK && ctxt); + + /* + *make sure a current ruleset statement has been allocated + *already. + */ + g_return_if_fail + (ctxt->cur_stmt + && + (ctxt->cur_stmt->type == RULESET_STMT + || ctxt->cur_stmt->type == AT_FONT_FACE_RULE_STMT + || ctxt->cur_stmt->type == AT_PAGE_RULE_STMT)); + + if (a_name) { + str = cr_string_dup (a_name); + g_return_if_fail (str); + } + + /*instanciates a new declaration */ + decl = cr_declaration_new (ctxt->cur_stmt, str, a_expression); + g_return_if_fail (decl); + str = NULL; + decl->important = a_important; + /* + *add the new declaration to the current statement + *being build. + */ + switch (ctxt->cur_stmt->type) { + case RULESET_STMT: + decl2 = cr_declaration_append + (ctxt->cur_stmt->kind.ruleset->decl_list, decl); + if (!decl2) { + cr_declaration_destroy (decl); + cr_utils_trace_info + ("Could not append decl to ruleset"); + goto error; + } + ctxt->cur_stmt->kind.ruleset->decl_list = decl2; + decl = NULL; + decl2 = NULL; + break; + + case AT_FONT_FACE_RULE_STMT: + decl2 = cr_declaration_append + (ctxt->cur_stmt->kind.font_face_rule->decl_list, + decl); + if (!decl2) { + cr_declaration_destroy (decl); + cr_utils_trace_info + ("Could not append decl to ruleset"); + goto error; + } + ctxt->cur_stmt->kind.font_face_rule->decl_list = decl2; + decl = NULL; + decl2 = NULL; + break; + case AT_PAGE_RULE_STMT: + decl2 = cr_declaration_append + (ctxt->cur_stmt->kind.page_rule->decl_list, decl); + if (!decl2) { + cr_declaration_destroy (decl); + cr_utils_trace_info + ("Could not append decl to ruleset"); + goto error; + } + ctxt->cur_stmt->kind.page_rule->decl_list = decl2; + decl = NULL; + decl2 = NULL; + break; + + default: + goto error; + break; + } + + return; + + error: + if (str) { + g_free (str); + str = NULL; + } + + if (decl) { + cr_declaration_destroy (decl); + decl = NULL; + } +} + +static void +error (CRDocHandler * a_this) +{ + enum CRStatus status = CR_OK; + ParsingContext *ctxt = NULL; + ParsingContext **ctxtptr = NULL; + + g_return_if_fail (a_this); + ctxtptr = &ctxt; + status = cr_doc_handler_get_ctxt (a_this, (gpointer *) ctxtptr); + g_return_if_fail (status == CR_OK && ctxt); + + if (ctxt->cur_stmt) { + cr_statement_destroy (ctxt->cur_stmt); + ctxt->cur_stmt = NULL; + } +} + +static void +unrecoverable_error (CRDocHandler * a_this) +{ + enum CRStatus status = CR_OK; + ParsingContext *ctxt = NULL; + ParsingContext **ctxtptr = NULL; + + ctxtptr = &ctxt; + status = cr_doc_handler_get_ctxt (a_this, (gpointer *) ctxtptr); + g_return_if_fail (status == CR_OK); + + if (ctxt) { + if (ctxt->stylesheet) { + status = cr_doc_handler_set_result + (a_this, ctxt->stylesheet); + g_return_if_fail (status == CR_OK); + } + g_free (ctxt); + cr_doc_handler_set_ctxt (a_this, NULL); + } +} + +/******************************************** + *Public methods + ********************************************/ + +/** + *Constructor of the CROMParser. + *@param a_input the input stream. + *@return the newly built instance of #CROMParser. + */ +CROMParser * +cr_om_parser_new (CRInput * a_input) +{ + CROMParser *result = NULL; + enum CRStatus status = CR_OK; + + result = g_try_malloc (sizeof (CROMParser)); + + if (!result) { + cr_utils_trace_info ("Out of memory"); + return NULL; + } + + memset (result, 0, sizeof (CROMParser)); + PRIVATE (result) = g_try_malloc (sizeof (CROMParserPriv)); + + if (!PRIVATE (result)) { + cr_utils_trace_info ("Out of memory"); + goto error; + } + + memset (PRIVATE (result), 0, sizeof (CROMParserPriv)); + + PRIVATE (result)->parser = cr_parser_new_from_input (a_input); + + if (!PRIVATE (result)->parser) { + cr_utils_trace_info ("parsing instanciation failed"); + goto error; + } + + status = cr_om_parser_init_default_sac_handler (result); + + if (status != CR_OK) { + goto error; + } + + return result; + + error: + + if (result) { + cr_om_parser_destroy (result); + } + + return NULL; +} + +/** + *Parses the content of an in memory buffer. + *@param a_this the current instance of #CROMParser. + *@param a_buf the in memory buffer to parse. + *@param a_len the length of the in memory buffer in number of bytes. + *@param a_enc the encoding of the in memory buffer. + *@param a_result out parameter the resulting style sheet + *@return CR_OK upon successfull completion, an error code otherwise. + */ +enum CRStatus +cr_om_parser_parse_buf (CROMParser * a_this, + const guchar * a_buf, + gulong a_len, + enum CREncoding a_enc, CRStyleSheet ** a_result) +{ + + enum CRStatus status = CR_OK; + + g_return_val_if_fail (a_this && a_result, CR_BAD_PARAM_ERROR); + + if (!PRIVATE (a_this)->parser) { + PRIVATE (a_this)->parser = cr_parser_new (NULL); + } + + status = cr_parser_parse_buf (PRIVATE (a_this)->parser, + a_buf, a_len, a_enc); + + if (status == CR_OK) { + CRStyleSheet *result = NULL; + CRStyleSheet **resultptr = NULL; + CRDocHandler *sac_handler = NULL; + + cr_parser_get_sac_handler (PRIVATE (a_this)->parser, + &sac_handler); + g_return_val_if_fail (sac_handler, CR_ERROR); + resultptr = &result; + status = cr_doc_handler_get_result (sac_handler, + (gpointer *) resultptr); + g_return_val_if_fail (status == CR_OK, status); + + if (result) + *a_result = result; + } + + return status; +} + +/** + *The simpler way to parse an in memory css2 buffer. + *@param a_buf the css2 in memory buffer. + *@param a_len the length of the in memory buffer. + *@param a_enc the encoding of the in memory buffer. + *@param a_result out parameter. The resulting css2 style sheet. + *@return CR_OK upon successfull completion, an error code otherwise. + */ +enum CRStatus +cr_om_parser_simply_parse_buf (const guchar * a_buf, + gulong a_len, + enum CREncoding a_enc, + CRStyleSheet ** a_result) +{ + CROMParser *parser = NULL; + enum CRStatus status = CR_OK; + + parser = cr_om_parser_new (NULL); + if (!parser) { + cr_utils_trace_info ("Could not create om parser"); + cr_utils_trace_info ("System possibly out of memory"); + return CR_ERROR; + } + + status = cr_om_parser_parse_buf (parser, a_buf, a_len, + a_enc, a_result); + + if (parser) { + cr_om_parser_destroy (parser); + parser = NULL; + } + + return status; +} + +/** + *Parses a css2 stylesheet contained + *in a file. + *@param a_this the current instance of the cssom parser. + *@param a_file_uri the uri of the file. + *(only local file paths are suppported so far) + *@param a_enc the encoding of the file. + *@param a_result out parameter. A pointer + *the build css object model. + *@param CR_OK upon successfull completion, an error code + *otherwise. + */ +enum CRStatus +cr_om_parser_parse_file (CROMParser * a_this, + const guchar * a_file_uri, + enum CREncoding a_enc, CRStyleSheet ** a_result) +{ + enum CRStatus status = CR_OK; + + g_return_val_if_fail (a_this && a_file_uri && a_result, + CR_BAD_PARAM_ERROR); + + if (!PRIVATE (a_this)->parser) { + PRIVATE (a_this)->parser = cr_parser_new_from_file + (a_file_uri, a_enc); + } + + status = cr_parser_parse_file (PRIVATE (a_this)->parser, + a_file_uri, a_enc); + + if (status == CR_OK) { + CRStyleSheet *result = NULL; + CRStyleSheet **resultptr = NULL; + CRDocHandler *sac_handler = NULL; + + cr_parser_get_sac_handler (PRIVATE (a_this)->parser, + &sac_handler); + g_return_val_if_fail (sac_handler, CR_ERROR); + resultptr = &result; + status = cr_doc_handler_get_result + (sac_handler, (gpointer *) resultptr); + g_return_val_if_fail (status == CR_OK, status); + if (result) + *a_result = result; + } + + return status; +} + +/** + *The simpler method to parse a css2 file. + *@param a_file_path the css2 local file path. + *@param a_enc the file encoding. + *@param a_result out parameter. The returned css stylesheet. + *Must be freed by the caller using cr_stylesheet_destroy. + *@return CR_OK upon successfull completion, an error code otherwise. + *Note that this method uses cr_om_parser_parse_file() so both methods + *have the same return values. + */ +enum CRStatus +cr_om_parser_simply_parse_file (const guchar * a_file_path, + enum CREncoding a_enc, + CRStyleSheet ** a_result) +{ + CROMParser *parser = NULL; + enum CRStatus status = CR_OK; + + parser = cr_om_parser_new (NULL); + if (!parser) { + cr_utils_trace_info ("Could not allocate om parser"); + cr_utils_trace_info ("System may be out of memory"); + return CR_ERROR; + } + + status = cr_om_parser_parse_file (parser, a_file_path, + a_enc, a_result); + if (parser) { + cr_om_parser_destroy (parser); + parser = NULL; + } + + return status; +} + +/** + *Parses three sheets located by their paths and build a cascade + *@param a_this the current instance of #CROMParser + *@param a_author_path the path to the author stylesheet + *@param a_user_path the path to the user stylesheet + *@param a_ua_path the path to the User Agent stylesheet + *@param a_result out parameter. The resulting cascade if the parsing + *was okay + *@return CR_OK upon successful completion, an error code otherwise + */ +enum CRStatus +cr_om_parser_parse_paths_to_cascade (CROMParser * a_this, + const guchar * a_author_path, + const guchar * a_user_path, + const guchar * a_ua_path, + enum CREncoding a_encoding, + CRCascade ** a_result) +{ + enum CRStatus status = CR_OK; + + /*0->author sheet, 1->user sheet, 2->UA sheet */ + CRStyleSheet *sheets[3]; + guchar *paths[3]; + CRCascade *result = NULL; + gint i = 0; + + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + memset (sheets, 0, sizeof (sheets)); + paths[0] = (guchar *) a_author_path; + paths[1] = (guchar *) a_user_path; + paths[2] = (guchar *) a_ua_path; + + for (i = 0; i < 3; i++) { + status = cr_om_parser_parse_file (a_this, paths[i], + a_encoding, &sheets[i]); + if (status != CR_OK) { + if (sheets[i]) { + cr_stylesheet_unref (sheets[i]); + sheets[i] = NULL; + } + continue; + } + } + result = cr_cascade_new (sheets[0], sheets[1], sheets[2]); + if (!result) { + for (i = 0; i < 3; i++) { + cr_stylesheet_unref (sheets[i]); + sheets[i] = 0; + } + return CR_ERROR; + } + *a_result = result; + return CR_OK; +} + +/** + *Parses three sheets located by their paths and build a cascade + *@param a_author_path the path to the author stylesheet + *@param a_user_path the path to the user stylesheet + *@param a_ua_path the path to the User Agent stylesheet + *@param a_result out parameter. The resulting cascade if the parsing + *was okay + *@return CR_OK upon successful completion, an error code otherwise + */ +enum CRStatus +cr_om_parser_simply_parse_paths_to_cascade (const guchar * a_author_path, + const guchar * a_user_path, + const guchar * a_ua_path, + enum CREncoding a_encoding, + CRCascade ** a_result) +{ + enum CRStatus status = CR_OK; + CROMParser *parser = NULL; + + parser = cr_om_parser_new (NULL); + if (!parser) { + cr_utils_trace_info ("could not allocated om parser"); + cr_utils_trace_info ("System may be out of memory"); + return CR_ERROR; + } + status = cr_om_parser_parse_paths_to_cascade (parser, + a_author_path, + a_user_path, + a_ua_path, + a_encoding, a_result); + if (parser) { + cr_om_parser_destroy (parser); + parser = NULL; + } + return status; +} + +/** + *Destructor of the #CROMParser. + *@param a_this the current instance of #CROMParser. + */ +void +cr_om_parser_destroy (CROMParser * a_this) +{ + g_return_if_fail (a_this && PRIVATE (a_this)); + + if (PRIVATE (a_this)->parser) { + cr_parser_destroy (PRIVATE (a_this)->parser); + PRIVATE (a_this)->parser = NULL; + } + + if (PRIVATE (a_this)) { + g_free (PRIVATE (a_this)); + PRIVATE (a_this) = NULL; + } + + if (a_this) { + g_free (a_this); + a_this = NULL; + } +} diff --git a/src/libcroco/cr-om-parser.h b/src/libcroco/cr-om-parser.h new file mode 100644 index 000000000..4fc63011a --- /dev/null +++ b/src/libcroco/cr-om-parser.h @@ -0,0 +1,98 @@ +/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */ + +/* + * This file is part of The Croco Library + * + * Copyright (C) 2002-2003 Dodji Seketeli + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the + * GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + +/* + *$Id: cr-om-parser.h,v 1.9 2004/01/29 22:05:14 dodji Exp $ + */ + +#ifndef __CR_OM_PARSER_H__ +#define __CR_OM_PARSER_H__ + +#include "cr-parser.h" +#include "cr-cascade.h" + + +/** + *@file + *The definition of the CSS Object Model Parser. + *This parser uses (and sits) the SAC api of libcroco defined + *in cr-parser.h and cr-doc-handler.h + */ + +G_BEGIN_DECLS + +typedef struct _CROMParser CROMParser ; +typedef struct _CROMParserPriv CROMParserPriv ; + +/** + *The Object model parser. + *Can parse a css file and build a css object model. + *This parser uses an instance of #CRParser and defines + *a set of SAC callbacks to build the Object Model. + */ +struct _CROMParser +{ + CROMParserPriv *priv ; +} ; + +CROMParser * cr_om_parser_new (CRInput *a_input) ; + + +enum CRStatus cr_om_parser_simply_parse_file (const guchar *a_file_path, + enum CREncoding a_enc, + CRStyleSheet **a_result) ; + +enum CRStatus cr_om_parser_parse_file (CROMParser *a_this, + const guchar *a_file_uri, + enum CREncoding a_enc, + CRStyleSheet **a_result) ; + +enum CRStatus cr_om_parser_simply_parse_buf (const guchar *a_buf, + gulong a_len, + enum CREncoding a_enc, + CRStyleSheet **a_result) ; + +enum CRStatus cr_om_parser_parse_buf (CROMParser *a_this, + const guchar *a_buf, + gulong a_len, + enum CREncoding a_enc, + CRStyleSheet **a_result) ; + +enum CRStatus cr_om_parser_parse_paths_to_cascade (CROMParser *a_this, + const guchar *a_author_path, + const guchar *a_user_path, + const guchar *a_ua_path, + enum CREncoding a_encoding, + CRCascade ** a_result) ; + +enum CRStatus cr_om_parser_simply_parse_paths_to_cascade (const guchar *a_author_path, + const guchar *a_user_path, + const guchar *a_ua_path, + enum CREncoding a_encoding, + CRCascade ** a_result) ; + +void cr_om_parser_destroy (CROMParser *a_this) ; + +G_END_DECLS + +#endif /*__CR_OM_PARSER_H__*/ diff --git a/src/libcroco/cr-parser.c b/src/libcroco/cr-parser.c new file mode 100644 index 000000000..7e71b927d --- /dev/null +++ b/src/libcroco/cr-parser.c @@ -0,0 +1,4408 @@ +/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */ + +/* + * This file is part of The Croco Library + * + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the + * GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * Author: Dodji Seketeli + * See COPYRIGHTS file for copyrights information. + */ + +/** + *@file + *The definition of the #CRParser class. + */ + +#include "string.h" +#include "cr-parser.h" +#include "cr-num.h" +#include "cr-term.h" +#include "cr-simple-sel.h" +#include "cr-attr-sel.h" + +/* + *Random notes: + *CSS core syntax vs CSS level 2 syntax + *===================================== + * + *One must keep in mind + *that css UA must comply with two syntax. + * + *1/the specific syntax that defines the css language + *for a given level of specificatin (e.g css2 syntax + *defined in appendix D.1 of the css2 spec) + * + *2/the core (general) syntax that is there to allow + *UAs to parse style sheets written in levels of CSS that + *didn't exist at the time the UAs were created. + * + *the name of parsing functions (or methods) contained in this file + *follows the following scheme: cr_parser_parse_ (...) ; + *where is the name + *of a production of the css2 language. + *When a given production is + *defined by the css2 level grammar *and* by the + *css core syntax, there will be two functions to parse that production: + *one will parse the production defined by the css2 level grammar and the + *other will parse the production defined by the css core grammar. + *The css2 level grammar related parsing function will be called: + *cr_parser_parse_ (...) ; + *Then css core grammar related parsing function will be called: + *cr_parser_parse__core (...) ; + * + *If a production is defined only by the css core grammar, then + *it will be named: + *cr_parser_parse__core (...) ; + */ + +typedef struct _CRParserError CRParserError; + +/** + *An abstraction of an error reported by by the + *parsing routines. + */ +struct _CRParserError { + guchar *msg; + enum CRStatus status; + glong line; + glong column; + glong byte_num; +}; + +enum CRParserState { + READY_STATE = 0, + TRY_PARSE_CHARSET_STATE, + CHARSET_PARSED_STATE, + TRY_PARSE_IMPORT_STATE, + IMPORT_PARSED_STATE, + TRY_PARSE_RULESET_STATE, + RULESET_PARSED_STATE, + TRY_PARSE_MEDIA_STATE, + MEDIA_PARSED_STATE, + TRY_PARSE_PAGE_STATE, + PAGE_PARSED_STATE, + TRY_PARSE_FONT_FACE_STATE, + FONT_FACE_PARSED_STATE +} ; + +/** + *The private attributes of + *#CRParser. + */ +struct _CRParserPriv { + /** + *The tokenizer + */ + CRTknzr *tknzr; + + /** + *The sac handlers to call + *to notify the parsing of + *the css2 constructions. + */ + CRDocHandler *sac_handler; + + /** + *A stack of errors reported + *by the parsing routines. + *Contains instance of #CRParserError. + *This pointer is the top of the stack. + */ + GList *err_stack; + + enum CRParserState state; + gboolean resolve_import; + gboolean is_case_sensitive; + gboolean use_core_grammar; +}; + +#define PRIVATE(obj) ((obj)->priv) + +#define CHARS_TAB_SIZE 12 + +/** + *return TRUE if the character is a number ([0-9]), FALSE otherwise + *@param a_char the char to test. + */ +#define IS_NUM(a_char) (((a_char) >= '0' && (a_char) <= '9')?TRUE:FALSE) + +/** + *Checks if 'status' equals CR_OK. If not, goto the 'error' label. + * + *@param status the status (of type enum CRStatus) to test. + *@param is_exception if set to FALSE, the final status returned + *by the current function will be CR_PARSING_ERROR. If set to TRUE, the + *current status will be the current value of the 'status' variable. + * + */ +#define CHECK_PARSING_STATUS(status, is_exception) \ +if ((status) != CR_OK) \ +{ \ + if (is_exception == FALSE) \ + { \ + status = CR_PARSING_ERROR ; \ + } \ + goto error ; \ +} + +/** + *same as CHECK_PARSING_STATUS() but this one pushes an error + *on the parser error stack when an error arises. + *@param a_this the current instance of #CRParser . + *@param a_status the status to check. Is of type enum #CRStatus. + *@param a_is_exception in case of error, if is TRUE, the status + *is set to CR_PARSING_ERROR before goto error. If is false, the + *real low level status is kept and will be returned by the + *upper level function that called this macro. Usally,this must + *be set to FALSE. + * + */ +#define CHECK_PARSING_STATUS_ERR(a_this, a_status, a_is_exception,\ + a_err_msg, a_err_status) \ +if ((a_status) != CR_OK) \ +{ \ + if (a_is_exception == FALSE) a_status = CR_PARSING_ERROR ; \ + cr_parser_push_error (a_this, a_err_msg, a_err_status) ; \ + goto error ; \ +} + +/** + *Peeks the next char from the input stream of the current parser + *by invoking cr_tknzr_input_peek_char(). + *invokes CHECK_PARSING_STATUS on the status returned by + *cr_tknzr_peek_char(). + * + *@param a_this the current instance of #CRParser. + *@param a_to_char a pointer to the char where to store the + *char peeked. + */ +#define PEEK_NEXT_CHAR(a_this, a_to_char) \ +{\ +enum CRStatus status ; \ +status = cr_tknzr_peek_char (PRIVATE (a_this)->tknzr, a_to_char) ; \ +CHECK_PARSING_STATUS (status, TRUE) \ +} + +/** + *Reads the next char from the input stream of the current parser. + *In case of error, jumps to the "error:" label located in the + *function where this macro is called. + *@param a_this the curent instance of #CRParser + *@param to_char a pointer to the guint32 char where to store + *the character read. + */ +#define READ_NEXT_CHAR(a_this, a_to_char) \ +status = cr_tknzr_read_char (PRIVATE (a_this)->tknzr, a_to_char) ; \ +CHECK_PARSING_STATUS (status, TRUE) + +/** + *Gets information about the current position in + *the input of the parser. + *In case of failure, this macro returns from the + *calling function and + *returns a status code of type enum #CRStatus. + *@param a_this the current instance of #CRParser. + *@param a_pos out parameter. A pointer to the position + *inside the current parser input. Must + */ +#define RECORD_INITIAL_POS(a_this, a_pos) \ +status = cr_tknzr_get_cur_pos (PRIVATE \ +(a_this)->tknzr, a_pos) ; \ +g_return_val_if_fail (status == CR_OK, status) + +/** + *Gets the address of the current byte inside the + *parser input. + *@param parser the current instance of #CRParser. + *@param addr out parameter a pointer (guchar*) + *to where the address must be put. + */ +#define RECORD_CUR_BYTE_ADDR(a_this, a_addr) \ +status = cr_tknzr_get_cur_byte_addr \ + (PRIVATE (a_this)->tknzr, a_addr) ; \ +CHECK_PARSING_STATUS (status, TRUE) + +/** + *Peeks a byte from the topmost parser input at + *a given offset from the current position. + *If it fails, goto the "error:" label. + * + *@param a_parser the current instance of #CRParser. + *@param a_offset the offset of the byte to peek, the + *current byte having the offset '0'. + *@param a_byte_ptr out parameter a pointer (guchar*) to + *where the peeked char is to be stored. + */ +#define PEEK_BYTE(a_parser, a_offset, a_byte_ptr) \ +status = cr_tknzr_peek_byte (PRIVATE (a_this)->tknzr, \ + a_offset, \ + a_byte_ptr) ; \ +CHECK_PARSING_STATUS (status, TRUE) ; + +#define BYTE(a_parser, a_offset, a_eof) \ +cr_tknzr_peek_byte2 (PRIVATE (a_this)->tknzr, a_offset, a_eof) + +/** + *Reads a byte from the topmost parser input + *steam. + *If it fails, goto the "error" label. + *@param a_this the current instance of #CRParser. + *@param a_byte_ptr the guchar * where to put the read char. + */ +#define READ_NEXT_BYTE(a_this, a_byte_ptr) \ +status = cr_tknzr_read_byte (PRIVATE (a_this)->tknzr, a_byte_ptr) ; \ +CHECK_PARSING_STATUS (status, TRUE) ; + +/** + *Skips a given number of byte in the topmost + *parser input. Don't update line and column number. + *In case of error, jumps to the "error:" label + *of the surrounding function. + *@param a_parser the current instance of #CRParser. + *@param a_nb_bytes the number of bytes to skip. + */ +#define SKIP_BYTES(a_this, a_nb_bytes) \ +status = cr_tknzr_seek_index (PRIVATE (a_this)->tknzr, \ + CR_SEEK_CUR, a_nb_bytes) ; \ +CHECK_PARSING_STATUS (status, TRUE) ; + +/** + *Skip utf8 encoded characters. + *Updates line and column numbers. + *@param a_parser the current instance of #CRParser. + *@param a_nb_chars the number of chars to skip. Must be of + *type glong. + */ +#define SKIP_CHARS(a_parser, a_nb_chars) \ +{ \ +glong nb_chars = a_nb_chars ; \ +status = cr_tknzr_consume_chars \ + (PRIVATE (a_parser)->tknzr,0, &nb_chars) ; \ +CHECK_PARSING_STATUS (status, TRUE) ; \ +} + +/** + *Tests the condition and if it is false, sets + *status to "CR_PARSING_ERROR" and goto the 'error' + *label. + *@param condition the condition to test. + */ +#define ENSURE_PARSING_COND(condition) \ +if (! (condition)) {status = CR_PARSING_ERROR; goto error ;} + +#define ENSURE_PARSING_COND_ERR(a_this, a_condition, \ + a_err_msg, a_err_status) \ +if (! (a_condition)) \ +{ \ + status = CR_PARSING_ERROR; \ + cr_parser_push_error (a_this, a_err_msg, a_err_status) ; \ + goto error ; \ +} + +#define GET_NEXT_TOKEN(a_this, a_token_ptr) \ +status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, \ + a_token_ptr) ; \ +ENSURE_PARSING_COND (status == CR_OK) ; + +#ifdef WITH_UNICODE_ESCAPE_AND_RANGE +static enum CRStatus cr_parser_parse_unicode_escape (CRParser * a_this, + guint32 * a_unicode); +static enum CRStatus cr_parser_parse_escape (CRParser * a_this, + guint32 * a_esc_code); + +static enum CRStatus cr_parser_parse_unicode_range (CRParser * a_this, + CRString ** a_inf, + CRString ** a_sup); +#endif + +static enum CRStatus cr_parser_parse_stylesheet_core (CRParser * a_this); + +static enum CRStatus cr_parser_parse_atrule_core (CRParser * a_this); + +static enum CRStatus cr_parser_parse_ruleset_core (CRParser * a_this); + +static enum CRStatus cr_parser_parse_selector_core (CRParser * a_this); + +static enum CRStatus cr_parser_parse_declaration_core (CRParser * a_this); + +static enum CRStatus cr_parser_parse_any_core (CRParser * a_this); + +static enum CRStatus cr_parser_parse_block_core (CRParser * a_this); + +static enum CRStatus cr_parser_parse_value_core (CRParser * a_this); + +static enum CRStatus cr_parser_parse_string (CRParser * a_this, + CRString ** a_str); + +static enum CRStatus cr_parser_parse_ident (CRParser * a_this, + CRString ** a_str); + +static enum CRStatus cr_parser_parse_uri (CRParser * a_this, + CRString ** a_str); + +static enum CRStatus cr_parser_parse_function (CRParser * a_this, + CRString ** a_func_name, + CRTerm ** a_expr); +static enum CRStatus cr_parser_parse_property (CRParser * a_this, + CRString ** a_property); + +static enum CRStatus cr_parser_parse_attribute_selector (CRParser * a_this, + CRAttrSel ** a_sel); + +static enum CRStatus cr_parser_parse_simple_selector (CRParser * a_this, + CRSimpleSel ** a_sel); + +static enum CRStatus cr_parser_parse_simple_sels (CRParser * a_this, + CRSimpleSel ** a_sel); + +static CRParserError *cr_parser_error_new (const guchar * a_msg, + enum CRStatus); + +static void cr_parser_error_set_msg (CRParserError * a_this, + const guchar * a_msg); + +static void cr_parser_error_dump (CRParserError * a_this); + +static void cr_parser_error_set_status (CRParserError * a_this, + enum CRStatus a_status); + +static void cr_parser_error_set_pos (CRParserError * a_this, + glong a_line, + glong a_column, glong a_byte_num); +static void + cr_parser_error_destroy (CRParserError * a_this); + +static enum CRStatus cr_parser_push_error (CRParser * a_this, + const guchar * a_msg, + enum CRStatus a_status); + +static enum CRStatus cr_parser_dump_err_stack (CRParser * a_this, + gboolean a_clear_errs); +static enum CRStatus + cr_parser_clear_errors (CRParser * a_this); + +/***************************** + *error managemet methods + *****************************/ + +/** + *Constructor of #CRParserError class. + *@param a_msg the brute error message. + *@param a_status the error status. + *@return the newly built instance of #CRParserError. + */ +static CRParserError * +cr_parser_error_new (const guchar * a_msg, enum CRStatus a_status) +{ + CRParserError *result = NULL; + + result = g_try_malloc (sizeof (CRParserError)); + + if (result == NULL) { + cr_utils_trace_info ("Out of memory"); + return NULL; + } + + memset (result, 0, sizeof (CRParserError)); + + cr_parser_error_set_msg (result, a_msg); + cr_parser_error_set_status (result, a_status); + + return result; +} + +/** + *Sets the message associated to this instance of #CRError. + *@param a_this the current instance of #CRParserError. + *@param a_msg the new message. + */ +static void +cr_parser_error_set_msg (CRParserError * a_this, const guchar * a_msg) +{ + g_return_if_fail (a_this); + + if (a_this->msg) { + g_free (a_this->msg); + } + + a_this->msg = g_strdup (a_msg); +} + +/** + *Sets the error status. + *@param a_this the current instance of #CRParserError. + *@param a_status the new error status. + * + */ +static void +cr_parser_error_set_status (CRParserError * a_this, enum CRStatus a_status) +{ + g_return_if_fail (a_this); + + a_this->status = a_status; +} + +/** + *Sets the position of the parser error. + *@param a_this the current instance of #CRParserError. + *@param a_line the line number. + *@param a_column the column number. + *@param a_byte_num the byte number. + */ +static void +cr_parser_error_set_pos (CRParserError * a_this, + glong a_line, glong a_column, glong a_byte_num) +{ + g_return_if_fail (a_this); + + a_this->line = a_line; + a_this->column = a_column; + a_this->byte_num = a_byte_num; +} + +static void +cr_parser_error_dump (CRParserError * a_this) +{ + g_return_if_fail (a_this); + + g_printerr ("parsing error: %ld:%ld:", a_this->line, a_this->column); + + g_printerr ("%s\n", a_this->msg); +} + +/** + *The destructor of #CRParserError. + *@param a_this the current instance of #CRParserError. + */ +static void +cr_parser_error_destroy (CRParserError * a_this) +{ + g_return_if_fail (a_this); + + if (a_this->msg) { + g_free (a_this->msg); + a_this->msg = NULL; + } + + g_free (a_this); +} + +/** + *Pushes an error on the parser error stack. + *@param a_this the current instance of #CRParser. + *@param a_msg the error message. + *@param a_status the error status. + *@return CR_OK upon successful completion, an error code otherwise. + */ +static enum CRStatus +cr_parser_push_error (CRParser * a_this, + const guchar * a_msg, enum CRStatus a_status) +{ + enum CRStatus status = CR_OK; + + CRParserError *error = NULL; + CRInputPos pos; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && a_msg, CR_BAD_PARAM_ERROR); + + error = cr_parser_error_new (a_msg, a_status); + + g_return_val_if_fail (error, CR_ERROR); + + RECORD_INITIAL_POS (a_this, &pos); + + cr_parser_error_set_pos + (error, pos.line, pos.col, pos.next_byte_index - 1); + + PRIVATE (a_this)->err_stack = + g_list_prepend (PRIVATE (a_this)->err_stack, error); + + if (PRIVATE (a_this)->err_stack == NULL) + goto error; + + return CR_OK; + + error: + + if (error) { + cr_parser_error_destroy (error); + error = NULL; + } + + return status; +} + +/** + *Dumps the error stack using g_printerr. + *@param a_this the current instance of #CRParser. + *@param a_clear_errs whether to clear the error stack + *after the dump or not. + *@return CR_OK upon successfull completion, an error code + *otherwise. + */ +static enum CRStatus +cr_parser_dump_err_stack (CRParser * a_this, gboolean a_clear_errs) +{ + GList *cur = NULL; + + g_return_val_if_fail (a_this && PRIVATE (a_this), CR_BAD_PARAM_ERROR); + + if (PRIVATE (a_this)->err_stack == NULL) + return CR_OK; + + for (cur = PRIVATE (a_this)->err_stack; cur; cur = cur->next) { + cr_parser_error_dump ((CRParserError *) cur->data); + } + + if (a_clear_errs == TRUE) { + cr_parser_clear_errors (a_this); + } + + return CR_OK; +} + +/** + *Clears all the errors contained in the parser error stack. + *Frees all the errors, and the stack that contains'em. + *@param a_this the current instance of #CRParser. + */ +static enum CRStatus +cr_parser_clear_errors (CRParser * a_this) +{ + GList *cur = NULL; + + g_return_val_if_fail (a_this && PRIVATE (a_this), CR_BAD_PARAM_ERROR); + + for (cur = PRIVATE (a_this)->err_stack; cur; cur = cur->next) { + if (cur->data) { + cr_parser_error_destroy ((CRParserError *) + cur->data); + } + } + + if (PRIVATE (a_this)->err_stack) { + g_list_free (PRIVATE (a_this)->err_stack); + PRIVATE (a_this)->err_stack = NULL; + } + + return CR_OK; +} + +/** + *Same as cr_parser_try_to_skip_spaces() but this one skips + *spaces and comments. + * + *@param a_this the current instance of #CRParser. + *@return CR_OK upon successfull completion, an error code otherwise. + */ +enum CRStatus +cr_parser_try_to_skip_spaces_and_comments (CRParser * a_this) +{ + enum CRStatus status = CR_ERROR; + CRToken *token = NULL; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && PRIVATE (a_this)->tknzr, CR_BAD_PARAM_ERROR); + do { + if (token) { + cr_token_destroy (token); + token = NULL; + } + + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, + &token); + if (status != CR_OK) + goto error; + } + while ((token != NULL) + && (token->type == COMMENT_TK || token->type == S_TK)); + + cr_tknzr_unget_token (PRIVATE (a_this)->tknzr, token); + + return status; + + error: + + if (token) { + cr_token_destroy (token); + token = NULL; + } + + return status; +} + +/*************************************** + *End of Parser input handling routines + ***************************************/ + + +/************************************* + *Non trivial terminal productions + *parsing routines + *************************************/ + +/** + *Parses a css stylesheet following the core css grammar. + *This is mainly done for test purposes. + *During the parsing, no callback is called. This is just + *to validate that the stylesheet is well formed according to the + *css core syntax. + *stylesheet : [ CDO | CDC | S | statement ]*; + *@param a_this the current instance of #CRParser. + *@return CR_OK upon successful completion, an error code otherwise. + */ +static enum CRStatus +cr_parser_parse_stylesheet_core (CRParser * a_this) +{ + CRToken *token = NULL; + CRInputPos init_pos; + enum CRStatus status = CR_ERROR; + + g_return_val_if_fail (a_this && PRIVATE (a_this), CR_BAD_PARAM_ERROR); + + RECORD_INITIAL_POS (a_this, &init_pos); + + continue_parsing: + + if (token) { + cr_token_destroy (token); + token = NULL; + } + + cr_parser_try_to_skip_spaces_and_comments (a_this); + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, &token); + if (status == CR_END_OF_INPUT_ERROR) { + status = CR_OK; + goto done; + } else if (status != CR_OK) { + goto error; + } + + switch (token->type) { + + case CDO_TK: + case CDC_TK: + goto continue_parsing; + break; + default: + status = cr_tknzr_unget_token (PRIVATE (a_this)->tknzr, + token); + CHECK_PARSING_STATUS (status, TRUE); + token = NULL; + status = cr_parser_parse_statement_core (a_this); + cr_parser_clear_errors (a_this); + if (status == CR_OK) { + goto continue_parsing; + } else if (status == CR_END_OF_INPUT_ERROR) { + goto done; + } else { + goto error; + } + } + + done: + if (token) { + cr_token_destroy (token); + token = NULL; + } + + cr_parser_clear_errors (a_this); + return CR_OK; + + error: + cr_parser_push_error + (a_this, "could not recognize next production", CR_ERROR); + + cr_parser_dump_err_stack (a_this, TRUE); + + if (token) { + cr_token_destroy (token); + token = NULL; + } + + cr_tknzr_set_cur_pos (PRIVATE (a_this)->tknzr, &init_pos); + + return status; +} + +/** + *Parses an at-rule as defined by the css core grammar + *in chapter 4.1 in the css2 spec. + *at-rule : ATKEYWORD S* any* [ block | ';' S* ]; + *@param a_this the current instance of #CRParser. + *@return CR_OK upon successfull completion, an error code + *otherwise. + */ +static enum CRStatus +cr_parser_parse_atrule_core (CRParser * a_this) +{ + CRToken *token = NULL; + CRInputPos init_pos; + enum CRStatus status = CR_ERROR; + + g_return_val_if_fail (a_this && PRIVATE (a_this), CR_BAD_PARAM_ERROR); + + RECORD_INITIAL_POS (a_this, &init_pos); + + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, + &token); + ENSURE_PARSING_COND (status == CR_OK + && token + && + (token->type == ATKEYWORD_TK + || token->type == IMPORT_SYM_TK + || token->type == PAGE_SYM_TK + || token->type == MEDIA_SYM_TK + || token->type == FONT_FACE_SYM_TK + || token->type == CHARSET_SYM_TK)); + + cr_token_destroy (token); + token = NULL; + + cr_parser_try_to_skip_spaces_and_comments (a_this); + + do { + status = cr_parser_parse_any_core (a_this); + } while (status == CR_OK); + + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, + &token); + ENSURE_PARSING_COND (status == CR_OK && token); + + if (token->type == CBO_TK) { + cr_tknzr_unget_token (PRIVATE (a_this)->tknzr, + token); + token = NULL; + status = cr_parser_parse_block_core (a_this); + CHECK_PARSING_STATUS (status, + FALSE); + goto done; + } else if (token->type == SEMICOLON_TK) { + goto done; + } else { + status = CR_PARSING_ERROR ; + goto error; + } + + done: + if (token) { + cr_token_destroy (token); + token = NULL; + } + return CR_OK; + + error: + if (token) { + cr_token_destroy (token); + token = NULL; + } + cr_tknzr_set_cur_pos (PRIVATE (a_this)->tknzr, + &init_pos); + return status; +} + +/** + *Parses a ruleset as defined by the css core grammar in chapter + *4.1 of the css2 spec. + *ruleset ::= selector? '{' S* declaration? [ ';' S* declaration? ]* '}' S*; + *@param a_this the current instance of #CRParser. + *@return CR_OK upon successfull completion, an error code otherwise. + */ +static enum CRStatus +cr_parser_parse_ruleset_core (CRParser * a_this) +{ + CRToken *token = NULL; + CRInputPos init_pos; + enum CRStatus status = CR_ERROR; + + g_return_val_if_fail (a_this && PRIVATE (a_this), CR_BAD_PARAM_ERROR); + RECORD_INITIAL_POS (a_this, &init_pos); + + status = cr_parser_parse_selector_core (a_this); + + ENSURE_PARSING_COND (status == CR_OK + || status == CR_PARSING_ERROR + || status == CR_END_OF_INPUT_ERROR); + + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, &token); + ENSURE_PARSING_COND (status == CR_OK && token + && token->type == CBO_TK); + cr_token_destroy (token); + token = NULL; + + cr_parser_try_to_skip_spaces_and_comments (a_this); + status = cr_parser_parse_declaration_core (a_this); + + parse_declaration_list: + if (token) { + cr_token_destroy (token); + token = NULL; + } + + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, &token); + ENSURE_PARSING_COND (status == CR_OK && token); + if (token->type == CBC_TK) { + goto done; + } + + ENSURE_PARSING_COND (status == CR_OK + && token && token->type == SEMICOLON_TK); + + cr_token_destroy (token); + token = NULL; + cr_parser_try_to_skip_spaces_and_comments (a_this); + status = cr_parser_parse_declaration_core (a_this); + cr_parser_clear_errors (a_this); + ENSURE_PARSING_COND (status == CR_OK || status == CR_PARSING_ERROR); + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, &token); + ENSURE_PARSING_COND (status == CR_OK && token); + if (token->type == CBC_TK) { + cr_token_destroy (token); + token = NULL; + cr_parser_try_to_skip_spaces_and_comments (a_this); + goto done; + } else { + status = cr_tknzr_unget_token (PRIVATE (a_this)->tknzr, + token); + token = NULL; + goto parse_declaration_list; + } + + done: + if (token) { + cr_token_destroy (token); + token = NULL; + } + + if (status == CR_OK) { + return CR_OK; + } + + error: + if (token) { + cr_token_destroy (token); + token = NULL; + } + + cr_tknzr_set_cur_pos (PRIVATE (a_this)->tknzr, &init_pos); + + return status; +} + +/** + *Parses a "selector" as specified by the css core + *grammar. + *selector : any+; + *@param a_this the current instance of #CRParser. + *@return CR_OK upon successfull completion, an error code + *otherwise. + */ +static enum CRStatus +cr_parser_parse_selector_core (CRParser * a_this) +{ + CRToken *token = NULL; + CRInputPos init_pos; + enum CRStatus status = CR_ERROR; + + g_return_val_if_fail (a_this && PRIVATE (a_this), CR_BAD_PARAM_ERROR); + + RECORD_INITIAL_POS (a_this, &init_pos); + + status = cr_parser_parse_any_core (a_this); + CHECK_PARSING_STATUS (status, FALSE); + + do { + status = cr_parser_parse_any_core (a_this); + + } while (status == CR_OK); + + return CR_OK; + + error: + if (token) { + cr_token_destroy (token); + token = NULL; + } + + cr_tknzr_set_cur_pos (PRIVATE (a_this)->tknzr, &init_pos); + + return status; +} + +/** + *Parses a "block" as defined in the css core grammar + *in chapter 4.1 of the css2 spec. + *block ::= '{' S* [ any | block | ATKEYWORD S* | ';' ]* '}' S*; + *@param a_this the current instance of #CRParser. + *FIXME: code this function. + */ +static enum CRStatus +cr_parser_parse_block_core (CRParser * a_this) +{ + CRToken *token = NULL; + CRInputPos init_pos; + enum CRStatus status = CR_ERROR; + + g_return_val_if_fail (a_this && PRIVATE (a_this), CR_BAD_PARAM_ERROR); + + RECORD_INITIAL_POS (a_this, &init_pos); + + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, &token); + ENSURE_PARSING_COND (status == CR_OK && token + && token->type == CBO_TK); + + parse_block_content: + + if (token) { + cr_token_destroy (token); + token = NULL; + } + + cr_parser_try_to_skip_spaces_and_comments (a_this); + + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, &token); + ENSURE_PARSING_COND (status == CR_OK && token); + + if (token->type == CBC_TK) { + cr_parser_try_to_skip_spaces_and_comments (a_this); + goto done; + } else if (token->type == SEMICOLON_TK) { + goto parse_block_content; + } else if (token->type == ATKEYWORD_TK) { + cr_parser_try_to_skip_spaces_and_comments (a_this); + goto parse_block_content; + } else if (token->type == CBO_TK) { + cr_tknzr_unget_token (PRIVATE (a_this)->tknzr, token); + token = NULL; + status = cr_parser_parse_block_core (a_this); + CHECK_PARSING_STATUS (status, FALSE); + goto parse_block_content; + } else { + cr_tknzr_unget_token (PRIVATE (a_this)->tknzr, token); + token = NULL; + status = cr_parser_parse_any_core (a_this); + CHECK_PARSING_STATUS (status, FALSE); + goto parse_block_content; + } + + done: + if (token) { + cr_token_destroy (token); + token = NULL; + } + + if (status == CR_OK) + return CR_OK; + + error: + if (token) { + cr_token_destroy (token); + token = NULL; + } + + cr_tknzr_set_cur_pos (PRIVATE (a_this)->tknzr, &init_pos); + + return status; +} + +static enum CRStatus +cr_parser_parse_declaration_core (CRParser * a_this) +{ + CRToken *token = NULL; + CRInputPos init_pos; + enum CRStatus status = CR_ERROR; + CRString *prop = NULL; + + g_return_val_if_fail (a_this && PRIVATE (a_this), CR_BAD_PARAM_ERROR); + + RECORD_INITIAL_POS (a_this, &init_pos); + + status = cr_parser_parse_property (a_this, &prop); + CHECK_PARSING_STATUS (status, FALSE); + cr_parser_clear_errors (a_this); + ENSURE_PARSING_COND (status == CR_OK && prop); + cr_string_destroy (prop); + prop = NULL; + + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, &token); + ENSURE_PARSING_COND (status == CR_OK + && token + && token->type == DELIM_TK + && token->u.unichar == ':'); + cr_token_destroy (token); + token = NULL; + cr_parser_try_to_skip_spaces_and_comments (a_this); + status = cr_parser_parse_value_core (a_this); + CHECK_PARSING_STATUS (status, FALSE); + + return CR_OK; + + error: + + if (prop) { + cr_string_destroy (prop); + prop = NULL; + } + + if (token) { + cr_token_destroy (token); + token = NULL; + } + + cr_tknzr_set_cur_pos (PRIVATE (a_this)->tknzr, &init_pos); + + return status; +} + +/** + *Parses a "value" production as defined by the css core grammar + *in chapter 4.1. + *value ::= [ any | block | ATKEYWORD S* ]+; + *@param a_this the current instance of #CRParser. + *@return CR_OK upon successfull completion, an error code otherwise. + */ +static enum CRStatus +cr_parser_parse_value_core (CRParser * a_this) +{ + CRToken *token = NULL; + CRInputPos init_pos; + enum CRStatus status = CR_ERROR; + glong ref = 0; + + g_return_val_if_fail (a_this && PRIVATE (a_this), CR_BAD_PARAM_ERROR); + RECORD_INITIAL_POS (a_this, &init_pos); + + continue_parsing: + + if (token) { + cr_token_destroy (token); + token = NULL; + } + + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, &token); + ENSURE_PARSING_COND (status == CR_OK && token); + + switch (token->type) { + case CBO_TK: + status = cr_tknzr_unget_token (PRIVATE (a_this)->tknzr, + token); + token = NULL; + status = cr_parser_parse_block_core (a_this); + CHECK_PARSING_STATUS (status, FALSE); + ref++; + goto continue_parsing; + + case ATKEYWORD_TK: + cr_parser_try_to_skip_spaces_and_comments (a_this); + ref++; + goto continue_parsing; + + default: + status = cr_tknzr_unget_token (PRIVATE (a_this)->tknzr, + token); + token = NULL; + status = cr_parser_parse_any_core (a_this); + if (status == CR_OK) { + ref++; + goto continue_parsing; + } else if (status == CR_PARSING_ERROR) { + status = CR_OK; + goto done; + } else { + goto error; + } + } + + done: + if (token) { + cr_token_destroy (token); + token = NULL; + } + + if (status == CR_OK && ref) + return CR_OK; + error: + if (token) { + cr_token_destroy (token); + token = NULL; + } + + cr_tknzr_set_cur_pos (PRIVATE (a_this)->tknzr, &init_pos); + + return status; +} + +/** + *Parses an "any" as defined by the css core grammar in the + *css2 spec in chapter 4.1. + *any ::= [ IDENT | NUMBER | PERCENTAGE | DIMENSION | STRING + * | DELIM | URI | HASH | UNICODE-RANGE | INCLUDES + * | FUNCTION | DASHMATCH | '(' any* ')' | '[' any* ']' ] S*; + * + *@param a_this the current instance of #CRParser. + *@return CR_OK upon successfull completion, an error code otherwise. + */ +static enum CRStatus +cr_parser_parse_any_core (CRParser * a_this) +{ + CRToken *token1 = NULL, + *token2 = NULL; + CRInputPos init_pos; + enum CRStatus status = CR_ERROR; + + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + RECORD_INITIAL_POS (a_this, &init_pos); + + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, &token1); + + ENSURE_PARSING_COND (status == CR_OK && token1); + + switch (token1->type) { + case IDENT_TK: + case NUMBER_TK: + case RGB_TK: + case PERCENTAGE_TK: + case DIMEN_TK: + case EMS_TK: + case EXS_TK: + case LENGTH_TK: + case ANGLE_TK: + case FREQ_TK: + case TIME_TK: + case STRING_TK: + case DELIM_TK: + case URI_TK: + case HASH_TK: + case UNICODERANGE_TK: + case INCLUDES_TK: + case DASHMATCH_TK: + case S_TK: + case COMMENT_TK: + case IMPORTANT_SYM_TK: + status = CR_OK; + break; + case FUNCTION_TK: + /* + *this case isn't specified by the spec but it + *does happen. So we have to handle it. + *We must consider function with parameters. + *We consider parameter as being an "any*" production. + */ + do { + status = cr_parser_parse_any_core (a_this); + } while (status == CR_OK); + + ENSURE_PARSING_COND (status == CR_PARSING_ERROR); + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, + &token2); + ENSURE_PARSING_COND (status == CR_OK + && token2 && token2->type == PC_TK); + break; + case PO_TK: + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, + &token2); + ENSURE_PARSING_COND (status == CR_OK && token2); + + if (token2->type == PC_TK) { + cr_token_destroy (token2); + token2 = NULL; + goto done; + } else { + status = cr_tknzr_unget_token + (PRIVATE (a_this)->tknzr, token2); + token2 = NULL; + } + + do { + status = cr_parser_parse_any_core (a_this); + } while (status == CR_OK); + + ENSURE_PARSING_COND (status == CR_PARSING_ERROR); + + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, + &token2); + ENSURE_PARSING_COND (status == CR_OK + && token2 && token2->type == PC_TK); + status = CR_OK; + break; + + case BO_TK: + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, + &token2); + ENSURE_PARSING_COND (status == CR_OK && token2); + + if (token2->type == BC_TK) { + cr_token_destroy (token2); + token2 = NULL; + goto done; + } else { + status = cr_tknzr_unget_token + (PRIVATE (a_this)->tknzr, token2); + token2 = NULL; + } + + do { + status = cr_parser_parse_any_core (a_this); + } while (status == CR_OK); + + ENSURE_PARSING_COND (status == CR_PARSING_ERROR); + + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, + &token2); + ENSURE_PARSING_COND (status == CR_OK + && token2 && token2->type == BC_TK); + status = CR_OK; + break; + default: + status = CR_PARSING_ERROR; + goto error; + } + + done: + if (token1) { + cr_token_destroy (token1); + token1 = NULL; + } + + if (token2) { + cr_token_destroy (token2); + token2 = NULL; + } + + return CR_OK; + + error: + + if (token1) { + cr_token_destroy (token1); + token1 = NULL; + } + + if (token2) { + cr_token_destroy (token2); + token2 = NULL; + } + + cr_tknzr_set_cur_pos (PRIVATE (a_this)->tknzr, &init_pos); + return status; +} + +/** + *Parses an attribute selector as defined in the css2 spec in + *appendix D.1: + *attrib ::= '[' S* IDENT S* [ [ '=' | INCLUDES | DASHMATCH ] S* + * [ IDENT | STRING ] S* ]? ']' + * + *@param a_this the "this pointer" of the current instance of + *#CRParser . + *@param a_sel out parameter. The successfully parsed attribute selector. + *@return CR_OK upon successfull completion, an error code otherwise. + */ +static enum CRStatus +cr_parser_parse_attribute_selector (CRParser * a_this, + CRAttrSel ** a_sel) +{ + enum CRStatus status = CR_OK; + CRInputPos init_pos; + CRToken *token = NULL; + CRAttrSel *result = NULL; + CRParsingLocation location = {0,0,0} ; + + g_return_val_if_fail (a_this && a_sel, CR_BAD_PARAM_ERROR); + + RECORD_INITIAL_POS (a_this, &init_pos); + + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, &token); + ENSURE_PARSING_COND (status == CR_OK && token + && token->type == BO_TK); + cr_parsing_location_copy + (&location, &token->location) ; + cr_token_destroy (token); + token = NULL; + + cr_parser_try_to_skip_spaces_and_comments (a_this); + + result = cr_attr_sel_new (); + if (!result) { + cr_utils_trace_info ("result failed") ; + status = CR_OUT_OF_MEMORY_ERROR ; + goto error ; + } + cr_parsing_location_copy (&result->location, + &location) ; + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, &token); + ENSURE_PARSING_COND (status == CR_OK + && token && token->type == IDENT_TK); + + result->name = token->u.str; + token->u.str = NULL; + cr_token_destroy (token); + token = NULL; + + cr_parser_try_to_skip_spaces_and_comments (a_this); + + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, &token); + ENSURE_PARSING_COND (status == CR_OK && token); + + if (token->type == INCLUDES_TK) { + result->match_way = INCLUDES; + goto parse_right_part; + } else if (token->type == DASHMATCH_TK) { + result->match_way = DASHMATCH; + goto parse_right_part; + } else if (token->type == DELIM_TK && token->u.unichar == '=') { + result->match_way = EQUALS; + goto parse_right_part; + } else if (token->type == BC_TK) { + result->match_way = SET; + goto done; + } + + parse_right_part: + + if (token) { + cr_token_destroy (token); + token = NULL; + } + + cr_parser_try_to_skip_spaces_and_comments (a_this); + + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, &token); + ENSURE_PARSING_COND (status == CR_OK && token); + + if (token->type == IDENT_TK) { + result->value = token->u.str; + token->u.str = NULL; + } else if (token->type == STRING_TK) { + result->value = token->u.str; + token->u.str = NULL; + } else { + status = CR_PARSING_ERROR; + goto error; + } + + if (token) { + cr_token_destroy (token); + token = NULL; + } + + cr_parser_try_to_skip_spaces_and_comments (a_this); + + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, &token); + + ENSURE_PARSING_COND (status == CR_OK && token + && token->type == BC_TK); + done: + if (token) { + cr_token_destroy (token); + token = NULL; + } + + if (*a_sel) { + status = cr_attr_sel_append_attr_sel (*a_sel, result); + CHECK_PARSING_STATUS (status, FALSE); + } else { + *a_sel = result; + } + + cr_parser_clear_errors (a_this); + return CR_OK; + + error: + + if (result) { + cr_attr_sel_destroy (result); + result = NULL; + } + + if (token) { + cr_token_destroy (token); + token = NULL; + } + + cr_tknzr_set_cur_pos (PRIVATE (a_this)->tknzr, &init_pos); + + return status; +} + +/** + *Parses a "property" as specified by the css2 spec at [4.1.1]: + *property : IDENT S*; + * + *@param a_this the "this pointer" of the current instance of #CRParser. + *@param GString a_property out parameter. The parsed property without the + *trailing spaces. If *a_property is NULL, this function allocates a + *new instance of GString and set it content to the parsed property. + *If not, the property is just appended to a_property's previous content. + *In both cases, it is up to the caller to free a_property. + *@return CR_OK upon successfull completion, CR_PARSING_ERROR if the + *next construction was not a "property", or an error code. + */ +static enum CRStatus +cr_parser_parse_property (CRParser * a_this, + CRString ** a_property) +{ + enum CRStatus status = CR_OK; + CRInputPos init_pos; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && PRIVATE (a_this)->tknzr + && a_property, + CR_BAD_PARAM_ERROR); + + RECORD_INITIAL_POS (a_this, &init_pos); + + status = cr_parser_parse_ident (a_this, a_property); + CHECK_PARSING_STATUS (status, TRUE); + + cr_parser_try_to_skip_spaces_and_comments (a_this); + + cr_parser_clear_errors (a_this); + return CR_OK; + + error: + + cr_tknzr_set_cur_pos (PRIVATE (a_this)->tknzr, &init_pos); + + return status; +} + +/** + *Parses a "term" as defined in the css2 spec, appendix D.1: + *term ::= unary_operator? [NUMBER S* | PERCENTAGE S* | LENGTH S* | + *EMS S* | EXS S* | ANGLE S* | TIME S* | FREQ S* | function ] | + *STRING S* | IDENT S* | URI S* | RGB S* | UNICODERANGE S* | hexcolor + * + *TODO: handle parsing of 'RGB' + * + *@param a_term out parameter. The successfully parsed term. + *@return CR_OK upon successfull completion, an error code otherwise. + */ +enum CRStatus +cr_parser_parse_term (CRParser * a_this, CRTerm ** a_term) +{ + enum CRStatus status = CR_PARSING_ERROR; + CRInputPos init_pos; + CRTerm *result = NULL; + CRTerm *param = NULL; + CRToken *token = NULL; + CRString *func_name = NULL; + CRParsingLocation location = {0,0,0} ; + + g_return_val_if_fail (a_this && a_term, CR_BAD_PARAM_ERROR); + + RECORD_INITIAL_POS (a_this, &init_pos); + + result = cr_term_new (); + + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, + &token); + if (status != CR_OK || !token) + goto error; + + cr_parsing_location_copy (&location, &token->location) ; + if (token->type == DELIM_TK && token->u.unichar == '+') { + result->unary_op = PLUS_UOP; + cr_token_destroy (token) ; + token = NULL ; + cr_parser_try_to_skip_spaces_and_comments (a_this); + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, + &token); + if (status != CR_OK || !token) + goto error; + } else if (token->type == DELIM_TK && token->u.unichar == '-') { + result->unary_op = MINUS_UOP; + cr_token_destroy (token) ; + token = NULL ; + cr_parser_try_to_skip_spaces_and_comments (a_this); + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, + &token); + if (status != CR_OK || !token) + goto error; + } + + if (token->type == EMS_TK + || token->type == EXS_TK + || token->type == LENGTH_TK + || token->type == ANGLE_TK + || token->type == TIME_TK + || token->type == FREQ_TK + || token->type == PERCENTAGE_TK + || token->type == NUMBER_TK) { + status = cr_term_set_number (result, token->u.num); + CHECK_PARSING_STATUS (status, TRUE); + token->u.num = NULL; + status = CR_OK; + } else if (token && token->type == FUNCTION_TK) { + status = cr_tknzr_unget_token (PRIVATE (a_this)->tknzr, + token); + token = NULL; + status = cr_parser_parse_function (a_this, &func_name, + ¶m); + + if (status == CR_OK) { + status = cr_term_set_function (result, + func_name, + param); + CHECK_PARSING_STATUS (status, TRUE); + } + } else if (token && token->type == STRING_TK) { + status = cr_term_set_string (result, + token->u.str); + CHECK_PARSING_STATUS (status, TRUE); + token->u.str = NULL; + } else if (token && token->type == IDENT_TK) { + status = cr_term_set_ident (result, token->u.str); + CHECK_PARSING_STATUS (status, TRUE); + token->u.str = NULL; + } else if (token && token->type == URI_TK) { + status = cr_term_set_uri (result, token->u.str); + CHECK_PARSING_STATUS (status, TRUE); + token->u.str = NULL; + } else if (token && token->type == RGB_TK) { + status = cr_term_set_rgb (result, token->u.rgb); + CHECK_PARSING_STATUS (status, TRUE); + token->u.rgb = NULL; + } else if (token && token->type == UNICODERANGE_TK) { + result->type = TERM_UNICODERANGE; + status = CR_PARSING_ERROR; + } else if (token && token->type == HASH_TK) { + status = cr_term_set_hash (result, token->u.str); + CHECK_PARSING_STATUS (status, TRUE); + token->u.str = NULL; + } else { + status = CR_PARSING_ERROR; + } + + if (status != CR_OK) { + goto error; + } + cr_parsing_location_copy (&result->location, + &location) ; + *a_term = cr_term_append_term (*a_term, result); + + result = NULL; + + cr_parser_try_to_skip_spaces_and_comments (a_this); + + if (token) { + cr_token_destroy (token); + token = NULL; + } + + cr_parser_clear_errors (a_this); + return CR_OK; + + error: + + if (result) { + cr_term_destroy (result); + result = NULL; + } + + if (token) { + cr_token_destroy (token); + token = NULL; + } + + if (param) { + cr_term_destroy (param); + param = NULL; + } + + if (func_name) { + cr_string_destroy (func_name); + func_name = NULL; + } + + cr_tknzr_set_cur_pos (PRIVATE (a_this)->tknzr, &init_pos); + + return status; +} + +/** + *Parses a "simple_selector" as defined by the css2 spec in appendix D.1 : + *element_name? [ HASH | class | attrib | pseudo ]* S* + *and where pseudo is: + *pseudo ::= ':' [ IDENT | FUNCTION S* IDENT S* ')' ] + * + *@Param a_this the "this pointer" of the current instance of #CRParser. + *@param a_sel out parameter. Is set to the successfully parsed simple + *selector. + *@return CR_OK upon successfull completion, an error code otherwise. + */ +static enum CRStatus +cr_parser_parse_simple_selector (CRParser * a_this, CRSimpleSel ** a_sel) +{ + enum CRStatus status = CR_ERROR; + CRInputPos init_pos; + CRToken *token = NULL; + CRSimpleSel *sel = NULL; + CRAdditionalSel *add_sel_list = NULL; + gboolean found_sel = FALSE; + guint32 cur_char = 0; + + g_return_val_if_fail (a_this && a_sel, CR_BAD_PARAM_ERROR); + + RECORD_INITIAL_POS (a_this, &init_pos); + + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, &token); + if (status != CR_OK) + goto error; + + sel = cr_simple_sel_new (); + ENSURE_PARSING_COND (sel); + + cr_parsing_location_copy + (&sel->location, + &token->location) ; + + if (token && token->type == DELIM_TK + && token->u.unichar == '*') { + sel->type_mask |= UNIVERSAL_SELECTOR; + sel->name = cr_string_new_from_string ("*"); + found_sel = TRUE; + } else if (token && token->type == IDENT_TK) { + sel->name = token->u.str; + sel->type_mask |= TYPE_SELECTOR; + token->u.str = NULL; + found_sel = TRUE; + } else { + status = cr_tknzr_unget_token + (PRIVATE (a_this)->tknzr, + token); + token = NULL; + } + + if (token) { + cr_token_destroy (token); + token = NULL; + } + + cr_parser_try_to_skip_spaces_and_comments (a_this); + + for (;;) { + if (token) { + cr_token_destroy (token); + token = NULL; + } + + status = cr_tknzr_get_next_token + (PRIVATE (a_this)->tknzr, + &token); + if (status != CR_OK) + goto error; + + if (token && token->type == HASH_TK) { + /*we parsed an attribute id */ + CRAdditionalSel *add_sel = NULL; + + add_sel = cr_additional_sel_new_with_type + (ID_ADD_SELECTOR); + + add_sel->content.id_name = token->u.str; + token->u.str = NULL; + + cr_parsing_location_copy + (&add_sel->location, + &token->location) ; + add_sel_list = + cr_additional_sel_append + (add_sel_list, add_sel); + found_sel = TRUE; + } else if (token && (token->type == DELIM_TK) + && (token->u.unichar == '.')) { + cr_token_destroy (token); + token = NULL; + + status = cr_tknzr_get_next_token + (PRIVATE (a_this)->tknzr, &token); + if (status != CR_OK) + goto error; + + if (token && token->type == IDENT_TK) { + CRAdditionalSel *add_sel = NULL; + + add_sel = cr_additional_sel_new_with_type + (CLASS_ADD_SELECTOR); + + add_sel->content.class_name = token->u.str; + token->u.str = NULL; + + add_sel_list = + cr_additional_sel_append + (add_sel_list, add_sel); + found_sel = TRUE; + + cr_parsing_location_copy + (&add_sel->location, + & token->location) ; + } else { + status = CR_PARSING_ERROR; + goto error; + } + } else if (token && token->type == BO_TK) { + CRAttrSel *attr_sel = NULL; + CRAdditionalSel *add_sel = NULL; + + status = cr_tknzr_unget_token + (PRIVATE (a_this)->tknzr, token); + if (status != CR_OK) + goto error; + token = NULL; + + status = cr_parser_parse_attribute_selector + (a_this, &attr_sel); + CHECK_PARSING_STATUS (status, FALSE); + + add_sel = cr_additional_sel_new_with_type + (ATTRIBUTE_ADD_SELECTOR); + + ENSURE_PARSING_COND (add_sel != NULL); + + add_sel->content.attr_sel = attr_sel; + + add_sel_list = + cr_additional_sel_append + (add_sel_list, add_sel); + found_sel = TRUE; + cr_parsing_location_copy + (&add_sel->location, + &attr_sel->location) ; + } else if (token && (token->type == DELIM_TK) + && (token->u.unichar == ':')) { + CRPseudo *pseudo = NULL; + + /*try to parse a pseudo */ + + if (token) { + cr_token_destroy (token); + token = NULL; + } + + pseudo = cr_pseudo_new (); + + status = cr_tknzr_get_next_token + (PRIVATE (a_this)->tknzr, &token); + ENSURE_PARSING_COND (status == CR_OK && token); + + cr_parsing_location_copy + (&pseudo->location, + &token->location) ; + + if (token->type == IDENT_TK) { + pseudo->type = IDENT_PSEUDO; + pseudo->name = token->u.str; + token->u.str = NULL; + found_sel = TRUE; + } else if (token->type == FUNCTION_TK) { + pseudo->name = token->u.str; + token->u.str = NULL; + cr_parser_try_to_skip_spaces_and_comments + (a_this); + status = cr_parser_parse_ident + (a_this, &pseudo->extra); + + ENSURE_PARSING_COND (status == CR_OK); + READ_NEXT_CHAR (a_this, &cur_char); + ENSURE_PARSING_COND (cur_char == ')'); + pseudo->type = FUNCTION_PSEUDO; + found_sel = TRUE; + } else { + status = CR_PARSING_ERROR; + goto error; + } + + if (status == CR_OK) { + CRAdditionalSel *add_sel = NULL; + + add_sel = cr_additional_sel_new_with_type + (PSEUDO_CLASS_ADD_SELECTOR); + + add_sel->content.pseudo = pseudo; + cr_parsing_location_copy + (&add_sel->location, + &pseudo->location) ; + add_sel_list = + cr_additional_sel_append + (add_sel_list, add_sel); + status = CR_OK; + } + } else { + status = cr_tknzr_unget_token + (PRIVATE (a_this)->tknzr, token); + token = NULL; + break; + } + } + + if (status == CR_OK && found_sel == TRUE) { + cr_parser_try_to_skip_spaces_and_comments (a_this); + + sel->add_sel = add_sel_list; + add_sel_list = NULL; + + if (*a_sel == NULL) { + *a_sel = sel; + } else { + cr_simple_sel_append_simple_sel (*a_sel, sel); + } + + sel = NULL; + + if (token) { + cr_token_destroy (token); + token = NULL; + } + + cr_parser_clear_errors (a_this); + return CR_OK; + } else { + status = CR_PARSING_ERROR; + } + + error: + + if (token) { + cr_token_destroy (token); + token = NULL; + } + + if (add_sel_list) { + cr_additional_sel_destroy (add_sel_list); + add_sel_list = NULL; + } + + if (sel) { + cr_simple_sel_destroy (sel); + sel = NULL; + } + + cr_tknzr_set_cur_pos (PRIVATE (a_this)->tknzr, &init_pos); + + return status; + +} + +/** + *Parses a "selector" as defined by the css2 spec in appendix D.1: + *selector ::= simple_selector [ combinator simple_selector ]* + * + *@param a_this the this pointer of the current instance of #CRParser. + *@param a_start a pointer to the + *first chararcter of the successfully parsed + *string. + *@param a_end a pointer to the last character of the successfully parsed + *string. + *@return CR_OK upon successfull completion, an error code otherwise. + */ +static enum CRStatus +cr_parser_parse_simple_sels (CRParser * a_this, + CRSimpleSel ** a_sel) +{ + enum CRStatus status = CR_ERROR; + CRInputPos init_pos; + CRSimpleSel *sel = NULL; + guint32 cur_char = 0; + + g_return_val_if_fail (a_this + && PRIVATE (a_this) + && a_sel, + CR_BAD_PARAM_ERROR); + + RECORD_INITIAL_POS (a_this, &init_pos); + + status = cr_parser_parse_simple_selector (a_this, &sel); + CHECK_PARSING_STATUS (status, FALSE); + + *a_sel = cr_simple_sel_append_simple_sel (*a_sel, sel); + + for (;;) { + guint32 next_char = 0; + enum Combinator comb = 0; + + sel = NULL; + + PEEK_NEXT_CHAR (a_this, &next_char); + + if (next_char == '+') { + READ_NEXT_CHAR (a_this, &cur_char); + comb = COMB_PLUS; + cr_parser_try_to_skip_spaces_and_comments (a_this); + } else if (next_char == '>') { + READ_NEXT_CHAR (a_this, &cur_char); + comb = COMB_GT; + cr_parser_try_to_skip_spaces_and_comments (a_this); + } else { + comb = COMB_WS; + } + + status = cr_parser_parse_simple_selector (a_this, &sel); + if (status != CR_OK) + break; + + if (comb && sel) { + sel->combinator = comb; + comb = 0; + } + if (sel) { + *a_sel = cr_simple_sel_append_simple_sel (*a_sel, + sel) ; + } + } + cr_parser_clear_errors (a_this); + return CR_OK; + + error: + + cr_tknzr_set_cur_pos (PRIVATE (a_this)->tknzr, &init_pos); + + return status; +} + +/** + *Parses a comma separated list of selectors. + *@param a_this the current instance of #CRParser. + *@param a_selector the parsed list of comma separated + *selectors. + *@return CR_OK upon successful completion, an error + *code otherwise. + */ +static enum CRStatus +cr_parser_parse_selector (CRParser * a_this, + CRSelector ** a_selector) +{ + enum CRStatus status = CR_OK; + CRInputPos init_pos; + guint32 cur_char = 0, + next_char = 0; + CRSimpleSel *simple_sels = NULL; + CRSelector *selector = NULL; + + g_return_val_if_fail (a_this && a_selector, CR_BAD_PARAM_ERROR); + + RECORD_INITIAL_POS (a_this, &init_pos); + + status = cr_parser_parse_simple_sels (a_this, &simple_sels); + CHECK_PARSING_STATUS (status, FALSE); + + if (simple_sels) { + selector = cr_selector_append_simple_sel + (selector, simple_sels); + if (selector) { + cr_parsing_location_copy + (&selector->location, + &simple_sels->location) ; + } + simple_sels = NULL; + } else { + status = CR_PARSING_ERROR ; + goto error ; + } + + status = cr_tknzr_peek_char (PRIVATE (a_this)->tknzr, + &next_char); + if (status != CR_OK) { + if (status == CR_END_OF_INPUT_ERROR) { + status = CR_OK; + goto okay; + } else { + goto error; + } + } + + if (next_char == ',') { + for (;;) { + simple_sels = NULL; + + status = cr_tknzr_peek_char (PRIVATE (a_this)->tknzr, + &next_char); + if (status != CR_OK) { + if (status == CR_END_OF_INPUT_ERROR) { + status = CR_OK; + break; + } else { + goto error; + } + } + + if (next_char != ',') + break; + + /*consume the ',' char */ + READ_NEXT_CHAR (a_this, &cur_char); + + cr_parser_try_to_skip_spaces_and_comments (a_this); + + status = cr_parser_parse_simple_sels + (a_this, &simple_sels); + + CHECK_PARSING_STATUS (status, FALSE); + + if (simple_sels) { + selector = + cr_selector_append_simple_sel + (selector, simple_sels); + + simple_sels = NULL; + } + } + } + + okay: + cr_parser_try_to_skip_spaces_and_comments (a_this); + + if (!*a_selector) { + *a_selector = selector; + } else { + *a_selector = cr_selector_append (*a_selector, selector); + } + + selector = NULL; + return CR_OK; + + error: + + if (simple_sels) { + cr_simple_sel_destroy (simple_sels); + simple_sels = NULL; + } + + if (selector) { + cr_selector_unref (selector); + selector = NULL; + } + + cr_tknzr_set_cur_pos (PRIVATE (a_this)->tknzr, &init_pos); + + return status; +} + +/** + *Parses a "function" as defined in css spec at appendix D.1: + *function ::= FUNCTION S* expr ')' S* + *FUNCTION ::= ident'(' + * + *@param a_this the "this pointer" of the current instance of + *#CRParser. + * + *@param a_func_name out parameter. The parsed function name + *@param a_expr out parameter. The successfully parsed term. + *@return CR_OK upon successfull completion, an error code otherwise. + */ +static enum CRStatus +cr_parser_parse_function (CRParser * a_this, + CRString ** a_func_name, + CRTerm ** a_expr) +{ + CRInputPos init_pos; + enum CRStatus status = CR_OK; + CRToken *token = NULL; + CRTerm *expr = NULL; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && a_func_name, + CR_BAD_PARAM_ERROR); + + RECORD_INITIAL_POS (a_this, &init_pos); + + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, &token); + if (status != CR_OK) + goto error; + + if (token && token->type == FUNCTION_TK) { + *a_func_name = token->u.str; + token->u.str = NULL; + } else { + status = CR_PARSING_ERROR; + goto error; + } + cr_token_destroy (token); + token = NULL; + + cr_parser_try_to_skip_spaces_and_comments (a_this) ; + + status = cr_parser_parse_expr (a_this, &expr); + + CHECK_PARSING_STATUS (status, FALSE); + + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, &token); + if (status != CR_OK) + goto error; + + ENSURE_PARSING_COND (token && token->type == PC_TK); + + cr_token_destroy (token); + token = NULL; + + if (expr) { + *a_expr = cr_term_append_term (*a_expr, expr); + expr = NULL; + } + + cr_parser_clear_errors (a_this); + return CR_OK; + + error: + + if (*a_func_name) { + cr_string_destroy (*a_func_name); + *a_func_name = NULL; + } + + if (expr) { + cr_term_destroy (expr); + expr = NULL; + } + + if (token) { + cr_token_destroy (token); + + } + + cr_tknzr_set_cur_pos (PRIVATE (a_this)->tknzr, &init_pos); + + return status; +} + +/** + *Parses an uri as defined by the css spec [4.1.1]: + * URI ::= url\({w}{string}{w}\) + * |url\({w}([!#$%&*-~]|{nonascii}|{escape})*{w}\) + * + *@param a_this the current instance of #CRParser. + *@param a_str the successfully parsed url. + *@return CR_OK upon successfull completion, an error code otherwise. + */ +static enum CRStatus +cr_parser_parse_uri (CRParser * a_this, CRString ** a_str) +{ + + enum CRStatus status = CR_PARSING_ERROR; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && PRIVATE (a_this)->tknzr, CR_BAD_PARAM_ERROR); + + status = cr_tknzr_parse_token (PRIVATE (a_this)->tknzr, + URI_TK, NO_ET, a_str, NULL); + return status; +} + +/** + *Parses a string type as defined in css spec [4.1.1]: + * + *string ::= {string1}|{string2} + *string1 ::= \"([\t !#$%&(-~]|\\{nl}|\'|{nonascii}|{escape})*\" + *string2 ::= \'([\t !#$%&(-~]|\\{nl}|\"|{nonascii}|{escape})*\' + * + *@param a_this the current instance of #CRParser. + *@param a_start out parameter. Upon successfull completion, + *points to the beginning of the string, points to an undefined value + *otherwise. + *@param a_end out parameter. Upon successfull completion, points to + *the beginning of the string, points to an undefined value otherwise. + *@return CR_OK upon successfull completion, an error code otherwise. + */ +static enum CRStatus +cr_parser_parse_string (CRParser * a_this, CRString ** a_str) +{ + enum CRStatus status = CR_OK; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && PRIVATE (a_this)->tknzr + && a_str, CR_BAD_PARAM_ERROR); + + status = cr_tknzr_parse_token (PRIVATE (a_this)->tknzr, + STRING_TK, NO_ET, a_str, NULL); + return status; +} + +/** + *Parses an "ident" as defined in css spec [4.1.1]: + *ident ::= {nmstart}{nmchar}* + * + *@param a_this the currens instance of #CRParser. + * + *@param a_str a pointer to parsed ident. If *a_str is NULL, + *this function allocates a new instance of #CRString. If not, + *the function just appends the parsed string to the one passed. + *In both cases it is up to the caller to free *a_str. + * + *@return CR_OK upon successfull completion, an error code + *otherwise. + */ +static enum CRStatus +cr_parser_parse_ident (CRParser * a_this, CRString ** a_str) +{ + enum CRStatus status = CR_OK; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && PRIVATE (a_this)->tknzr + && a_str, CR_BAD_PARAM_ERROR); + + status = cr_tknzr_parse_token (PRIVATE (a_this)->tknzr, + IDENT_TK, NO_ET, a_str, NULL); + return status; +} + +/** + *the next rule is ignored as well. This seems to be a bug + *Parses a stylesheet as defined in the css2 spec in appendix D.1: + *stylesheet ::= [ CHARSET_SYM S* STRING S* ';' ]? + * [S|CDO|CDC]* [ import [S|CDO|CDC]* ]* + * [ [ ruleset | media | page | font_face ] [S|CDO|CDC]* ]* + * + *TODO: Finish the code of this function. Think about splitting it into + *smaller functions. + * + *@param a_this the "this pointer" of the current instance of #CRParser. + *@param a_start out parameter. A pointer to the first character of + *the successfully parsed string. + *@param a_end out parameter. A pointer to the first character of + *the successfully parsed string. + * + *@return CR_OK upon successfull completion, an error code otherwise. + */ +static enum CRStatus +cr_parser_parse_stylesheet (CRParser * a_this) +{ + enum CRStatus status = CR_OK; + CRInputPos init_pos; + CRToken *token = NULL; + CRString *charset = NULL; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && PRIVATE (a_this)->tknzr, CR_BAD_PARAM_ERROR); + + RECORD_INITIAL_POS (a_this, &init_pos); + + PRIVATE (a_this)->state = READY_STATE; + + if (PRIVATE (a_this)->sac_handler + && PRIVATE (a_this)->sac_handler->start_document) { + PRIVATE (a_this)->sac_handler->start_document + (PRIVATE (a_this)->sac_handler); + } + + parse_charset: + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, &token); + + if (status == CR_END_OF_INPUT_ERROR) + goto done; + CHECK_PARSING_STATUS (status, TRUE); + + if (token && token->type == CHARSET_SYM_TK) { + CRParsingLocation location = {0,0,0} ; + status = cr_tknzr_unget_token (PRIVATE (a_this)->tknzr, + token); + CHECK_PARSING_STATUS (status, TRUE); + token = NULL; + + status = cr_parser_parse_charset (a_this, + &charset, + &location); + + if (status == CR_OK && charset) { + if (PRIVATE (a_this)->sac_handler + && PRIVATE (a_this)->sac_handler->charset) { + PRIVATE (a_this)->sac_handler->charset + (PRIVATE (a_this)->sac_handler, + charset, &location); + } + } else if (status != CR_END_OF_INPUT_ERROR) { + status = cr_parser_parse_atrule_core (a_this); + CHECK_PARSING_STATUS (status, FALSE); + } + + if (charset) { + cr_string_destroy (charset); + charset = NULL; + } + } else if (token + && (token->type == S_TK + || token->type == COMMENT_TK)) { + status = cr_tknzr_unget_token (PRIVATE (a_this)->tknzr, + token); + token = NULL; + CHECK_PARSING_STATUS (status, TRUE); + + cr_parser_try_to_skip_spaces_and_comments (a_this); + goto parse_charset ; + } else if (token) { + status = cr_tknzr_unget_token (PRIVATE (a_this)->tknzr, + token); + token = NULL; + CHECK_PARSING_STATUS (status, TRUE); + } + +/* parse_imports:*/ + do { + if (token) { + cr_token_destroy (token); + token = NULL; + } + cr_parser_try_to_skip_spaces_and_comments (a_this) ; + status = cr_tknzr_get_next_token + (PRIVATE (a_this)->tknzr, &token); + + if (status == CR_END_OF_INPUT_ERROR) + goto done; + CHECK_PARSING_STATUS (status, TRUE); + } while (token + && (token->type == S_TK + || token->type == CDO_TK || token->type == CDC_TK)); + + if (token) { + status = cr_tknzr_unget_token (PRIVATE (a_this)->tknzr, + token); + token = NULL; + } + + for (;;) { + status = cr_tknzr_get_next_token + (PRIVATE (a_this)->tknzr, &token); + if (status == CR_END_OF_INPUT_ERROR) + goto done; + CHECK_PARSING_STATUS (status, TRUE); + + if (token && token->type == IMPORT_SYM_TK) { + GList *media_list = NULL; + CRString *import_string = NULL; + CRParsingLocation location = {0,0,0} ; + + status = cr_tknzr_unget_token + (PRIVATE (a_this)->tknzr, token); + token = NULL; + CHECK_PARSING_STATUS (status, TRUE); + + status = cr_parser_parse_import (a_this, + &media_list, + &import_string, + &location); + if (status == CR_OK) { + if (import_string + && PRIVATE (a_this)->sac_handler + && PRIVATE (a_this)->sac_handler->import_style) { + PRIVATE (a_this)->sac_handler->import_style + (PRIVATE(a_this)->sac_handler, + media_list, + import_string, + NULL, &location) ; + + if ((PRIVATE (a_this)->sac_handler->resolve_import == TRUE)) { + /* + *TODO: resolve the + *import rule. + */ + } + + if ((PRIVATE (a_this)->sac_handler->import_style_result)) { + PRIVATE (a_this)->sac_handler->import_style_result + (PRIVATE (a_this)->sac_handler, + media_list, import_string, + NULL, NULL); + } + } + } else if (status != CR_END_OF_INPUT_ERROR) { + if (PRIVATE (a_this)->sac_handler + && PRIVATE (a_this)->sac_handler->error) { + PRIVATE (a_this)->sac_handler->error + (PRIVATE (a_this)->sac_handler); + } + status = cr_parser_parse_atrule_core (a_this); + CHECK_PARSING_STATUS (status, TRUE) ; + } else { + goto error ; + } + + /* + *then, after calling the appropriate + *SAC handler, free + *the media_list and import_string. + */ + if (media_list) { + GList *cur = NULL; + + /*free the medium list */ + for (cur = media_list; cur; cur = cur->next) { + if (cur->data) { + cr_string_destroy (cur->data); + } + } + + g_list_free (media_list); + media_list = NULL; + } + + if (import_string) { + cr_string_destroy (import_string); + import_string = NULL; + } + + cr_parser_try_to_skip_spaces_and_comments (a_this); + } else if (token + && (token->type == S_TK + || token->type == CDO_TK + || token->type == CDC_TK)) { + status = cr_tknzr_unget_token + (PRIVATE (a_this)->tknzr, token); + token = NULL; + + do { + if (token) { + cr_token_destroy (token); + token = NULL; + } + + status = cr_tknzr_get_next_token + (PRIVATE (a_this)->tknzr, &token); + + if (status == CR_END_OF_INPUT_ERROR) + goto done; + CHECK_PARSING_STATUS (status, TRUE); + } while (token + && (token->type == S_TK + || token->type == CDO_TK + || token->type == CDC_TK)); + } else { + if (token) { + status = cr_tknzr_unget_token + (PRIVATE (a_this)->tknzr, token); + token = NULL; + } + goto parse_ruleset_and_others; + } + } + + parse_ruleset_and_others: + + cr_parser_try_to_skip_spaces_and_comments (a_this); + + for (;;) { + status = cr_tknzr_get_next_token + (PRIVATE (a_this)->tknzr, &token); + if (status == CR_END_OF_INPUT_ERROR) + goto done; + CHECK_PARSING_STATUS (status, TRUE); + + if (token + && (token->type == S_TK + || token->type == CDO_TK || token->type == CDC_TK)) { + status = cr_tknzr_unget_token + (PRIVATE (a_this)->tknzr, token); + token = NULL; + + do { + if (token) { + cr_token_destroy (token); + token = NULL; + } + + cr_parser_try_to_skip_spaces_and_comments + (a_this); + status = cr_tknzr_get_next_token + (PRIVATE (a_this)->tknzr, &token); + } while (token + && (token->type == S_TK + || token->type == COMMENT_TK + || token->type == CDO_TK + || token->type == CDC_TK)); + if (token) { + cr_tknzr_unget_token + (PRIVATE (a_this)->tknzr, token); + token = NULL; + } + } else if (token + && (token->type == HASH_TK + || (token->type == DELIM_TK + && token->u.unichar == '.') + || (token->type == DELIM_TK + && token->u.unichar == ':') + || (token->type == DELIM_TK + && token->u.unichar == '*') + || (token->type == BO_TK) + || token->type == IDENT_TK)) { + /* + *Try to parse a CSS2 ruleset. + *if the parsing fails, try to parse + *a css core ruleset. + */ + status = cr_tknzr_unget_token + (PRIVATE (a_this)->tknzr, token); + CHECK_PARSING_STATUS (status, TRUE); + token = NULL; + + status = cr_parser_parse_ruleset (a_this); + + if (status == CR_OK) { + continue; + } else { + if (PRIVATE (a_this)->sac_handler + && PRIVATE (a_this)->sac_handler->error) { + PRIVATE (a_this)->sac_handler-> + error + (PRIVATE (a_this)-> + sac_handler); + } + + status = cr_parser_parse_ruleset_core + (a_this); + + if (status == CR_OK) { + continue; + } else { + break; + } + } + } else if (token && token->type == MEDIA_SYM_TK) { + status = cr_tknzr_unget_token + (PRIVATE (a_this)->tknzr, token); + CHECK_PARSING_STATUS (status, TRUE); + token = NULL; + + status = cr_parser_parse_media (a_this); + if (status == CR_OK) { + continue; + } else { + if (PRIVATE (a_this)->sac_handler + && PRIVATE (a_this)->sac_handler->error) { + PRIVATE (a_this)->sac_handler-> + error + (PRIVATE (a_this)-> + sac_handler); + } + + status = cr_parser_parse_atrule_core (a_this); + + if (status == CR_OK) { + continue; + } else { + break; + } + } + + } else if (token && token->type == PAGE_SYM_TK) { + status = cr_tknzr_unget_token + (PRIVATE (a_this)->tknzr, token); + CHECK_PARSING_STATUS (status, TRUE); + token = NULL; + status = cr_parser_parse_page (a_this); + + if (status == CR_OK) { + continue; + } else { + if (PRIVATE (a_this)->sac_handler + && PRIVATE (a_this)->sac_handler->error) { + PRIVATE (a_this)->sac_handler-> + error + (PRIVATE (a_this)-> + sac_handler); + } + + status = cr_parser_parse_atrule_core (a_this); + + if (status == CR_OK) { + continue; + } else { + break; + } + } + } else if (token && token->type == FONT_FACE_SYM_TK) { + status = cr_tknzr_unget_token + (PRIVATE (a_this)->tknzr, token); + CHECK_PARSING_STATUS (status, TRUE); + token = NULL; + status = cr_parser_parse_font_face (a_this); + + if (status == CR_OK) { + continue; + } else { + if (PRIVATE (a_this)->sac_handler + && PRIVATE (a_this)->sac_handler->error) { + PRIVATE (a_this)->sac_handler-> + error + (PRIVATE (a_this)-> + sac_handler); + } + + status = cr_parser_parse_atrule_core (a_this); + + if (status == CR_OK) { + continue; + } else { + break; + } + } + } else { + status = cr_tknzr_unget_token + (PRIVATE (a_this)->tknzr, token); + CHECK_PARSING_STATUS (status, TRUE); + token = NULL; + status = cr_parser_parse_statement_core (a_this); + + if (status == CR_OK) { + continue; + } else { + break; + } + } + } + + done: + if (token) { + cr_token_destroy (token); + token = NULL; + } + + if (status == CR_END_OF_INPUT_ERROR || status == CR_OK) { + + if (PRIVATE (a_this)->sac_handler + && PRIVATE (a_this)->sac_handler->end_document) { + PRIVATE (a_this)->sac_handler->end_document + (PRIVATE (a_this)->sac_handler); + } + + return CR_OK; + } + + cr_parser_push_error + (a_this, "could not recognize next production", CR_ERROR); + + if (PRIVATE (a_this)->sac_handler + && PRIVATE (a_this)->sac_handler->unrecoverable_error) { + PRIVATE (a_this)->sac_handler-> + unrecoverable_error (PRIVATE (a_this)->sac_handler); + } + + cr_parser_dump_err_stack (a_this, TRUE); + + return status; + + error: + + if (token) { + cr_token_destroy (token); + token = NULL; + } + + if (PRIVATE (a_this)->sac_handler + && PRIVATE (a_this)->sac_handler->unrecoverable_error) { + PRIVATE (a_this)->sac_handler-> + unrecoverable_error (PRIVATE (a_this)->sac_handler); + } + + cr_tknzr_set_cur_pos (PRIVATE (a_this)->tknzr, &init_pos); + + return status; +} + +/**************************************** + *Public CRParser Methods + ****************************************/ + +/** + *Creates a new parser to parse data + *coming the input stream given in parameter. + *@param a_input the input stream of the parser. + *Note that the newly created parser will ref + *a_input and unref it when parsing reaches the + *end of the input stream. + *@return the newly created instance of #CRParser, + *or NULL if an error occured. + */ +CRParser * +cr_parser_new (CRTknzr * a_tknzr) +{ + CRParser *result = NULL; + enum CRStatus status = CR_OK; + + result = g_malloc0 (sizeof (CRParser)); + + PRIVATE (result) = g_malloc0 (sizeof (CRParserPriv)); + + if (a_tknzr) { + status = cr_parser_set_tknzr (result, a_tknzr); + } + + g_return_val_if_fail (status == CR_OK, NULL); + + return result; +} + +/** + *Instanciates a new parser from a memory buffer. + *@param a_buf the buffer to parse. + *@param a_len the length of the data in the buffer. + *@param a_enc the encoding of the input buffer a_buf. + *@param a_free_buf if set to TRUE, a_buf will be freed + *during the destruction of the newly built instance + *of #CRParser. If set to FALSE, it is up to the caller to + *eventually free it. + *@return the newly built parser, or NULL if an error arises. + */ +CRParser * +cr_parser_new_from_buf (guchar * a_buf, + gulong a_len, + enum CREncoding a_enc, + gboolean a_free_buf) +{ + CRParser *result = NULL; + CRInput *input = NULL; + + g_return_val_if_fail (a_buf, NULL); + + input = cr_input_new_from_buf (a_buf, a_len, a_enc, a_free_buf); + g_return_val_if_fail (input, NULL); + + result = cr_parser_new_from_input (input); + if (!result) { + cr_input_destroy (input); + input = NULL; + return NULL; + } + return result; +} + +CRParser * +cr_parser_new_from_input (CRInput * a_input) +{ + CRParser *result = NULL; + CRTknzr *tokenizer = NULL; + + if (a_input) { + tokenizer = cr_tknzr_new (a_input); + g_return_val_if_fail (tokenizer, NULL); + } + + result = cr_parser_new (tokenizer); + g_return_val_if_fail (result, NULL); + + return result; +} + +CRParser * +cr_parser_new_from_file (const guchar * a_file_uri, enum CREncoding a_enc) +{ + CRParser *result = NULL; + CRTknzr *tokenizer = NULL; + + tokenizer = cr_tknzr_new_from_uri (a_file_uri, a_enc); + if (!tokenizer) { + cr_utils_trace_info ("Could not open input file"); + return NULL; + } + + result = cr_parser_new (tokenizer); + g_return_val_if_fail (result, NULL); + return result; +} + +/** + *Sets a SAC document handler to the parser. + *@param a_this the "this pointer" of the current instance of #CRParser. + *@param a_handler the handler to set. + *@return CR_OK upon successfull completion, an error code otherwise. + */ +enum CRStatus +cr_parser_set_sac_handler (CRParser * a_this, CRDocHandler * a_handler) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + if (PRIVATE (a_this)->sac_handler) { + cr_doc_handler_unref (PRIVATE (a_this)->sac_handler); + } + + PRIVATE (a_this)->sac_handler = a_handler; + cr_doc_handler_ref (a_handler); + + return CR_OK; +} + +/** + *Gets the SAC document handler. + *@param a_this the "this pointer" of the current instance of + *#CRParser. + *@param a_handler out parameter. The returned handler. + *@return CR_OK upon successfull completion, an error code + *otherwise. + */ +enum CRStatus +cr_parser_get_sac_handler (CRParser * a_this, CRDocHandler ** a_handler) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + *a_handler = PRIVATE (a_this)->sac_handler; + + return CR_OK; +} + +/** + *Sets the SAC handler associated to the current instance + *of #CRParser to the default SAC handler. + *@param a_this a pointer to the current instance of #CRParser. + *@return CR_OK upon successfull completion, an error code otherwise. + */ +enum CRStatus +cr_parser_set_default_sac_handler (CRParser * a_this) +{ + CRDocHandler *default_sac_handler = NULL; + enum CRStatus status = CR_ERROR; + + g_return_val_if_fail (a_this && PRIVATE (a_this), CR_BAD_PARAM_ERROR); + + default_sac_handler = cr_doc_handler_new (); + + cr_doc_handler_set_default_sac_handler (default_sac_handler); + + status = cr_parser_set_sac_handler (a_this, default_sac_handler); + + if (status != CR_OK) { + cr_doc_handler_destroy (default_sac_handler); + default_sac_handler = NULL; + } + + return status; +} + +enum CRStatus +cr_parser_set_use_core_grammar (CRParser * a_this, + gboolean a_use_core_grammar) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this), CR_BAD_PARAM_ERROR); + + PRIVATE (a_this)->use_core_grammar = a_use_core_grammar; + + return CR_OK; +} + +enum CRStatus +cr_parser_get_use_core_grammar (CRParser * a_this, + gboolean * a_use_core_grammar) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this), CR_BAD_PARAM_ERROR); + + *a_use_core_grammar = PRIVATE (a_this)->use_core_grammar; + + return CR_OK; +} + +/** + *Parses a the given in parameter. + *@param a_this a pointer to the current instance of #CRParser. + *@param a_file_uri the uri to the file to load. For the time being, + *only local files are supported. + *@return CR_OK upon successfull completion, an error code otherwise. + */ +enum CRStatus +cr_parser_parse_file (CRParser * a_this, + const guchar * a_file_uri, enum CREncoding a_enc) +{ + enum CRStatus status = CR_ERROR; + CRTknzr *tknzr = NULL; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && a_file_uri, CR_BAD_PARAM_ERROR); + + tknzr = cr_tknzr_new_from_uri (a_file_uri, a_enc); + + g_return_val_if_fail (tknzr != NULL, CR_ERROR); + + status = cr_parser_set_tknzr (a_this, tknzr); + g_return_val_if_fail (status == CR_OK, CR_ERROR); + + status = cr_parser_parse (a_this); + + return status; +} + +/** + *Parses an expression as defined by the css2 spec in appendix + *D.1: + *expr: term [ operator term ]* + */ +enum CRStatus +cr_parser_parse_expr (CRParser * a_this, CRTerm ** a_expr) +{ + enum CRStatus status = CR_ERROR; + CRInputPos init_pos; + CRTerm *expr = NULL, + *expr2 = NULL; + guchar next_byte = 0; + gulong nb_terms = 0; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && a_expr, CR_BAD_PARAM_ERROR); + + RECORD_INITIAL_POS (a_this, &init_pos); + + status = cr_parser_parse_term (a_this, &expr); + + CHECK_PARSING_STATUS (status, FALSE); + + for (;;) { + guchar operator = 0; + + status = cr_tknzr_peek_byte (PRIVATE (a_this)->tknzr, + 1, &next_byte); + if (status != CR_OK) { + if (status == CR_END_OF_INPUT_ERROR) { + /* + if (!nb_terms) + { + goto error ; + } + */ + status = CR_OK; + break; + } else { + goto error; + } + } + + if (next_byte == '/' || next_byte == ',') { + READ_NEXT_BYTE (a_this, &operator); + } + + cr_parser_try_to_skip_spaces_and_comments (a_this); + + status = cr_parser_parse_term (a_this, &expr2); + + if (status != CR_OK || expr2 == NULL) { + status = CR_OK; + break; + } + + switch (operator) { + case '/': + expr2->the_operator = DIVIDE; + break; + case ',': + expr2->the_operator = COMMA; + + default: + break; + } + + expr = cr_term_append_term (expr, expr2); + expr2 = NULL; + operator = 0; + nb_terms++; + } + + if (status == CR_OK) { + *a_expr = cr_term_append_term (*a_expr, expr); + expr = NULL; + + cr_parser_clear_errors (a_this); + return CR_OK; + } + + error: + + if (expr) { + cr_term_destroy (expr); + expr = NULL; + } + + if (expr2) { + cr_term_destroy (expr2); + expr2 = NULL; + } + + cr_tknzr_set_cur_pos (PRIVATE (a_this)->tknzr, &init_pos); + + return status; +} + +/** + *Parses a declaration priority as defined by + *the css2 grammar in appendix C: + *prio: IMPORTANT_SYM S* + *@param a_this the current instance of #CRParser. + *@param a_prio a string representing the priority. + *Today, only "!important" is returned as only this + *priority is defined by css2. + */ +enum CRStatus +cr_parser_parse_prio (CRParser * a_this, CRString ** a_prio) +{ + enum CRStatus status = CR_ERROR; + CRInputPos init_pos; + CRToken *token = NULL; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && a_prio + && *a_prio == NULL, CR_BAD_PARAM_ERROR); + + RECORD_INITIAL_POS (a_this, &init_pos); + + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, &token); + if (status == CR_END_OF_INPUT_ERROR) { + goto error; + } + ENSURE_PARSING_COND (status == CR_OK + && token && token->type == IMPORTANT_SYM_TK); + + cr_parser_try_to_skip_spaces_and_comments (a_this); + *a_prio = cr_string_new_from_string ("!important"); + cr_token_destroy (token); + token = NULL; + return CR_OK; + + error: + if (token) { + cr_token_destroy (token); + token = NULL; + } + cr_tknzr_set_cur_pos (PRIVATE (a_this)->tknzr, &init_pos); + + return status; +} + +/** + *TODO: return the parsed priority, so that + *upper layers can take benefit from it. + *Parses a "declaration" as defined by the css2 spec in appendix D.1: + *declaration ::= [property ':' S* expr prio?]? + * + *@param a_this the "this pointer" of the current instance of #CRParser. + *@param a_property the successfully parsed property. The caller + * *must* free the returned pointer. + *@param a_expr the expression that represents the attribute value. + *The caller *must* free the returned pointer. + *@return CR_OK upon successfull completion, an error code otherwise. + */ +enum CRStatus +cr_parser_parse_declaration (CRParser * a_this, + CRString ** a_property, + CRTerm ** a_expr, gboolean * a_important) +{ + enum CRStatus status = CR_ERROR; + CRInputPos init_pos; + guint32 cur_char = 0; + CRTerm *expr = NULL; + CRString *prio = NULL; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && a_property && a_expr + && a_important, CR_BAD_PARAM_ERROR); + + RECORD_INITIAL_POS (a_this, &init_pos); + + status = cr_parser_parse_property (a_this, a_property); + + if (status == CR_END_OF_INPUT_ERROR) + goto error; + + CHECK_PARSING_STATUS_ERR + (a_this, status, FALSE, + "while parsing declaration: next property is malformed", + CR_SYNTAX_ERROR); + + READ_NEXT_CHAR (a_this, &cur_char); + + if (cur_char != ':') { + status = CR_PARSING_ERROR; + cr_parser_push_error + (a_this, + "while parsing declaration: this char must be ':'", + CR_SYNTAX_ERROR); + goto error; + } + + cr_parser_try_to_skip_spaces_and_comments (a_this); + + status = cr_parser_parse_expr (a_this, &expr); + + CHECK_PARSING_STATUS_ERR + (a_this, status, FALSE, + "while parsing declaration: next expression is malformed", + CR_SYNTAX_ERROR); + + cr_parser_try_to_skip_spaces_and_comments (a_this); + status = cr_parser_parse_prio (a_this, &prio); + if (prio) { + cr_string_destroy (prio); + prio = NULL; + *a_important = TRUE; + } else { + *a_important = FALSE; + } + if (*a_expr) { + cr_term_append_term (*a_expr, expr); + expr = NULL; + } else { + *a_expr = expr; + expr = NULL; + } + + cr_parser_clear_errors (a_this); + return CR_OK; + + error: + + if (expr) { + cr_term_destroy (expr); + expr = NULL; + } + + if (*a_property) { + cr_string_destroy (*a_property); + *a_property = NULL; + } + + cr_tknzr_set_cur_pos (PRIVATE (a_this)->tknzr, &init_pos); + + return status; +} + +/** + *Parses a statement as defined by the css core grammar in + *chapter 4.1 of the css2 spec. + *statement : ruleset | at-rule; + *@param a_this the current instance of #CRParser. + *@return CR_OK upon successfull completion, an error code otherwise. + */ +enum CRStatus +cr_parser_parse_statement_core (CRParser * a_this) +{ + CRToken *token = NULL; + CRInputPos init_pos; + enum CRStatus status = CR_ERROR; + + g_return_val_if_fail (a_this && PRIVATE (a_this), CR_BAD_PARAM_ERROR); + + RECORD_INITIAL_POS (a_this, &init_pos); + + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, &token); + + ENSURE_PARSING_COND (status == CR_OK && token); + + switch (token->type) { + case ATKEYWORD_TK: + case IMPORT_SYM_TK: + case PAGE_SYM_TK: + case MEDIA_SYM_TK: + case FONT_FACE_SYM_TK: + case CHARSET_SYM_TK: + cr_tknzr_unget_token (PRIVATE (a_this)->tknzr, token); + token = NULL; + status = cr_parser_parse_atrule_core (a_this); + CHECK_PARSING_STATUS (status, TRUE); + break; + + default: + cr_tknzr_unget_token (PRIVATE (a_this)->tknzr, token); + token = NULL; + status = cr_parser_parse_ruleset_core (a_this); + cr_parser_clear_errors (a_this); + CHECK_PARSING_STATUS (status, TRUE); + } + + return CR_OK; + + error: + if (token) { + cr_token_destroy (token); + token = NULL; + } + + cr_tknzr_set_cur_pos (PRIVATE (a_this)->tknzr, &init_pos); + + return status; +} + +/** + *Parses a "ruleset" as defined in the css2 spec at appendix D.1. + *ruleset ::= selector [ ',' S* selector ]* + *'{' S* declaration? [ ';' S* declaration? ]* '}' S*; + * + *This methods calls the the SAC handler on the relevant SAC handler + *callbacks whenever it encounters some specific constructions. + *See the documentation of #CRDocHandler (the SAC handler) to know + *when which SAC handler is called. + *@param a_this the "this pointer" of the current instance of #CRParser. + *@return CR_OK upon successfull completion, an error code otherwise. + */ +enum CRStatus +cr_parser_parse_ruleset (CRParser * a_this) +{ + enum CRStatus status = CR_OK; + CRInputPos init_pos; + guint32 cur_char = 0, + next_char = 0; + CRString *property = NULL; + CRTerm *expr = NULL; + CRSimpleSel *simple_sels = NULL; + CRSelector *selector = NULL; + gboolean start_selector = FALSE, + is_important = FALSE; + + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + RECORD_INITIAL_POS (a_this, &init_pos); + + status = cr_parser_parse_selector (a_this, &selector); + CHECK_PARSING_STATUS (status, FALSE); + + READ_NEXT_CHAR (a_this, &cur_char); + + ENSURE_PARSING_COND_ERR + (a_this, cur_char == '{', + "while parsing rulset: current char should be '{'", + CR_SYNTAX_ERROR); + + if (PRIVATE (a_this)->sac_handler + && PRIVATE (a_this)->sac_handler->start_selector) { + /* + *the selector is ref counted so that the parser's user + *can choose to keep it. + */ + if (selector) { + cr_selector_ref (selector); + } + + PRIVATE (a_this)->sac_handler->start_selector + (PRIVATE (a_this)->sac_handler, selector); + start_selector = TRUE; + } + + cr_parser_try_to_skip_spaces_and_comments (a_this); + + PRIVATE (a_this)->state = TRY_PARSE_RULESET_STATE; + + status = cr_parser_parse_declaration (a_this, &property, + &expr, + &is_important); + if (expr) { + cr_term_ref (expr); + } + if (status == CR_OK + && PRIVATE (a_this)->sac_handler + && PRIVATE (a_this)->sac_handler->property) { + PRIVATE (a_this)->sac_handler->property + (PRIVATE (a_this)->sac_handler, property, expr, + is_important); + } + if (status == CR_OK) { + /* + *free the allocated + *'property' and 'term' before parsing + *next declarations. + */ + if (property) { + cr_string_destroy (property); + property = NULL; + } + if (expr) { + cr_term_unref (expr); + expr = NULL; + } + } else {/*status != CR_OK*/ + guint32 c = 0 ; + /* + *test if we have reached '}', which + *would mean that we are parsing an empty ruleset (eg. x{ }) + *In that case, goto end_of_ruleset. + */ + status = cr_tknzr_peek_char (PRIVATE (a_this)->tknzr, &c) ; + if (status == CR_OK && c == '}') { + status = CR_OK ; + goto end_of_ruleset ; + } + } + CHECK_PARSING_STATUS_ERR + (a_this, status, FALSE, + "while parsing ruleset: next construction should be a declaration", + CR_SYNTAX_ERROR); + + for (;;) { + PEEK_NEXT_CHAR (a_this, &next_char); + if (next_char != ';') + break; + + /*consume the ';' char */ + READ_NEXT_CHAR (a_this, &cur_char); + + cr_parser_try_to_skip_spaces_and_comments (a_this); + + status = cr_parser_parse_declaration (a_this, &property, + &expr, &is_important); + + if (expr) { + cr_term_ref (expr); + } + if (status == CR_OK + && PRIVATE (a_this)->sac_handler + && PRIVATE (a_this)->sac_handler->property) { + PRIVATE (a_this)->sac_handler->property + (PRIVATE (a_this)->sac_handler, + property, expr, is_important); + } + if (property) { + cr_string_destroy (property); + property = NULL; + } + if (expr) { + cr_term_unref (expr); + expr = NULL; + } + } + + end_of_ruleset: + cr_parser_try_to_skip_spaces_and_comments (a_this); + READ_NEXT_CHAR (a_this, &cur_char); + ENSURE_PARSING_COND_ERR + (a_this, cur_char == '}', + "while parsing rulset: current char must be a '}'", + CR_SYNTAX_ERROR); + + if (PRIVATE (a_this)->sac_handler + && PRIVATE (a_this)->sac_handler->end_selector) { + PRIVATE (a_this)->sac_handler->end_selector + (PRIVATE (a_this)->sac_handler, selector); + start_selector = FALSE; + } + + if (expr) { + cr_term_unref (expr); + expr = NULL; + } + + if (simple_sels) { + cr_simple_sel_destroy (simple_sels); + simple_sels = NULL; + } + + if (selector) { + cr_selector_unref (selector); + selector = NULL; + } + + cr_parser_clear_errors (a_this); + PRIVATE (a_this)->state = RULESET_PARSED_STATE; + + return CR_OK; + + error: + if (start_selector == TRUE + && PRIVATE (a_this)->sac_handler + && PRIVATE (a_this)->sac_handler->error) { + PRIVATE (a_this)->sac_handler->error + (PRIVATE (a_this)->sac_handler); + } + if (expr) { + cr_term_unref (expr); + expr = NULL; + } + if (simple_sels) { + cr_simple_sel_destroy (simple_sels); + simple_sels = NULL; + } + if (property) { + cr_string_destroy (property); + } + if (selector) { + cr_selector_unref (selector); + selector = NULL; + } + + cr_tknzr_set_cur_pos (PRIVATE (a_this)->tknzr, &init_pos); + + return status; +} + +/** + *Parses an 'import' declaration as defined in the css2 spec + *in appendix D.1: + * + *import ::= + *@import [STRING|URI] S* [ medium [ ',' S* medium]* ]? ';' S* + * + *@param a_this the "this pointer" of the current instance + *of #CRParser. + * + *@param a_medium_list out parameter. A linked list of + *#CRString + *Each CRString is a string that contains + *a 'medium' declaration part of the successfully + *parsed 'import' declaration. + * + *@param a_import_string out parameter. + *A string that contains the 'import + *string". The import string can be either an uri (if it starts with + *the substring "uri(") or a any other css2 string. Note that + * *a_import_string must be initially set to NULL or else, this function + *will return CR_BAD_PARAM_ERROR. + * + *@return CR_OK upon sucessfull completion, an error code otherwise. + */ +enum CRStatus +cr_parser_parse_import (CRParser * a_this, + GList ** a_media_list, + CRString ** a_import_string, + CRParsingLocation *a_location) +{ + enum CRStatus status = CR_OK; + CRInputPos init_pos; + guint32 cur_char = 0, + next_char = 0; + CRString *medium = NULL; + + g_return_val_if_fail (a_this + && a_import_string + && (*a_import_string == NULL), + CR_BAD_PARAM_ERROR); + + RECORD_INITIAL_POS (a_this, &init_pos); + + if (BYTE (a_this, 1, NULL) == '@' + && BYTE (a_this, 2, NULL) == 'i' + && BYTE (a_this, 3, NULL) == 'm' + && BYTE (a_this, 4, NULL) == 'p' + && BYTE (a_this, 5, NULL) == 'o' + && BYTE (a_this, 6, NULL) == 'r' + && BYTE (a_this, 7, NULL) == 't') { + SKIP_CHARS (a_this, 1); + if (a_location) { + cr_parser_get_parsing_location + (a_this, a_location) ; + } + SKIP_CHARS (a_this, 6); + status = CR_OK; + } else { + status = CR_PARSING_ERROR; + goto error; + } + + cr_parser_try_to_skip_spaces_and_comments (a_this); + + PRIVATE (a_this)->state = TRY_PARSE_IMPORT_STATE; + + PEEK_NEXT_CHAR (a_this, &next_char); + + if (next_char == '"' || next_char == '\'') { + status = cr_parser_parse_string (a_this, a_import_string); + + CHECK_PARSING_STATUS (status, FALSE); + } else { + status = cr_parser_parse_uri (a_this, a_import_string); + + CHECK_PARSING_STATUS (status, FALSE); + } + + cr_parser_try_to_skip_spaces_and_comments (a_this); + + status = cr_parser_parse_ident (a_this, &medium); + + if (status == CR_OK && medium) { + *a_media_list = g_list_append (*a_media_list, medium); + medium = NULL; + } + + cr_parser_try_to_skip_spaces_and_comments (a_this); + + for (; status == CR_OK;) { + if ((status = cr_tknzr_peek_char (PRIVATE (a_this)->tknzr, + &next_char)) != CR_OK) { + if (status == CR_END_OF_INPUT_ERROR) { + status = CR_OK; + goto okay; + } + goto error; + } + + if (next_char == ',') { + READ_NEXT_CHAR (a_this, &cur_char); + } else { + break; + } + + cr_parser_try_to_skip_spaces_and_comments (a_this); + + status = cr_parser_parse_ident (a_this, &medium); + + cr_parser_try_to_skip_spaces_and_comments (a_this); + + if ((status == CR_OK) && medium) { + *a_media_list = g_list_append (*a_media_list, medium); + + medium = NULL; + } + + CHECK_PARSING_STATUS (status, FALSE); + cr_parser_try_to_skip_spaces_and_comments (a_this); + } + cr_parser_try_to_skip_spaces_and_comments (a_this); + READ_NEXT_CHAR (a_this, &cur_char); + ENSURE_PARSING_COND (cur_char == ';'); + cr_parser_try_to_skip_spaces_and_comments (a_this); + okay: + cr_parser_clear_errors (a_this); + PRIVATE (a_this)->state = IMPORT_PARSED_STATE; + + return CR_OK; + + error: + + if (*a_media_list) { + GList *cur = NULL; + + /* + *free each element of *a_media_list. + *Note that each element of *a_medium list *must* + *be a GString* or else, the code that is coming next + *will corrupt the memory and lead to hard to debug + *random crashes. + *This is where C++ and its compile time + *type checking mecanism (through STL containers) would + *have prevented us to go through this hassle. + */ + for (cur = *a_media_list; cur; cur = cur->next) { + if (cur->data) { + cr_string_destroy (cur->data); + } + } + + g_list_free (*a_media_list); + *a_media_list = NULL; + } + + if (*a_import_string) { + cr_string_destroy (*a_import_string); + *a_import_string = NULL; + } + + if (medium) { + cr_string_destroy (medium); + medium = NULL; + } + + cr_tknzr_set_cur_pos (PRIVATE (a_this)->tknzr, &init_pos); + + return status; +} + +/** + *Parses a 'media' declaration as specified in the css2 spec at + *appendix D.1: + * + *media ::= @media S* medium [ ',' S* medium ]* '{' S* ruleset* '}' S* + * + *Note that this function calls the required sac handlers during the parsing + *to notify media productions. See #CRDocHandler to know the callback called + *during @media parsing. + *@param a_this the "this pointer" of the current instance of #CRParser. + *@return CR_OK upon successfull completion, an error code otherwise. + */ +enum CRStatus +cr_parser_parse_media (CRParser * a_this) +{ + enum CRStatus status = CR_OK; + CRInputPos init_pos; + CRToken *token = NULL; + guint32 next_char = 0, + cur_char = 0; + CRString *medium = NULL; + GList *media_list = NULL; + CRParsingLocation location = {0,0,0} ; + + g_return_val_if_fail (a_this + && PRIVATE (a_this), + CR_BAD_PARAM_ERROR); + + RECORD_INITIAL_POS (a_this, &init_pos); + + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, + &token); + ENSURE_PARSING_COND (status == CR_OK + && token + && token->type == MEDIA_SYM_TK); + cr_parsing_location_copy (&location, &token->location) ; + cr_token_destroy (token); + token = NULL; + + cr_parser_try_to_skip_spaces_and_comments (a_this); + + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, &token); + ENSURE_PARSING_COND (status == CR_OK + && token && token->type == IDENT_TK); + + medium = token->u.str; + token->u.str = NULL; + cr_token_destroy (token); + token = NULL; + + if (medium) { + media_list = g_list_append (media_list, medium); + medium = NULL; + } + + for (; status == CR_OK;) { + cr_parser_try_to_skip_spaces_and_comments (a_this); + PEEK_NEXT_CHAR (a_this, &next_char); + + if (next_char == ',') { + READ_NEXT_CHAR (a_this, &cur_char); + } else { + break; + } + + cr_parser_try_to_skip_spaces_and_comments (a_this); + + status = cr_parser_parse_ident (a_this, &medium); + + CHECK_PARSING_STATUS (status, FALSE); + + if (medium) { + media_list = g_list_append (media_list, medium); + medium = NULL; + } + } + + READ_NEXT_CHAR (a_this, &cur_char); + + ENSURE_PARSING_COND (cur_char == '{'); + + /* + *call the SAC handler api here. + */ + if (PRIVATE (a_this)->sac_handler + && PRIVATE (a_this)->sac_handler->start_media) { + PRIVATE (a_this)->sac_handler->start_media + (PRIVATE (a_this)->sac_handler, media_list, + &location); + } + + cr_parser_try_to_skip_spaces_and_comments (a_this); + + PRIVATE (a_this)->state = TRY_PARSE_MEDIA_STATE; + + for (; status == CR_OK;) { + status = cr_parser_parse_ruleset (a_this); + cr_parser_try_to_skip_spaces_and_comments (a_this); + } + + READ_NEXT_CHAR (a_this, &cur_char); + + ENSURE_PARSING_COND (cur_char == '}'); + + /* + *call the right SAC handler api here. + */ + if (PRIVATE (a_this)->sac_handler + && PRIVATE (a_this)->sac_handler->end_media) { + PRIVATE (a_this)->sac_handler->end_media + (PRIVATE (a_this)->sac_handler, media_list); + } + + cr_parser_try_to_skip_spaces_and_comments (a_this); + + /* + *Then, free the data structures passed to + *the last call to the SAC handler. + */ + if (medium) { + cr_string_destroy (medium); + medium = NULL; + } + + if (media_list) { + GList *cur = NULL; + + for (cur = media_list; cur; cur = cur->next) { + cr_string_destroy (cur->data); + } + + g_list_free (media_list); + media_list = NULL; + } + + cr_parser_clear_errors (a_this); + PRIVATE (a_this)->state = MEDIA_PARSED_STATE; + + return CR_OK; + + error: + + if (token) { + cr_token_destroy (token); + token = NULL; + } + + if (medium) { + cr_string_destroy (medium); + medium = NULL; + } + + if (media_list) { + GList *cur = NULL; + + for (cur = media_list; cur; cur = cur->next) { + cr_string_destroy (cur->data); + } + + g_list_free (media_list); + media_list = NULL; + } + + cr_tknzr_set_cur_pos (PRIVATE (a_this)->tknzr, &init_pos); + + return status; +} + +/** + *Parses '@page' rule as specified in the css2 spec in appendix D.1: + *page ::= PAGE_SYM S* IDENT? pseudo_page? S* + *'{' S* declaration [ ';' S* declaration ]* '}' S* + * + *This function also calls the relevant SAC handlers whenever it + *encounters a construction that must + *be reported to the calling application. + *@param a_this the "this pointer" of the current instance of #CRParser. + *@return CR_OK upon successfull completion, an error code otherwise. + */ +enum CRStatus +cr_parser_parse_page (CRParser * a_this) +{ + enum CRStatus status = CR_OK; + CRInputPos init_pos; + CRToken *token = NULL; + CRTerm *css_expression = NULL; + CRString *page_selector = NULL, + *page_pseudo_class = NULL, + *property = NULL; + gboolean important = TRUE; + CRParsingLocation location = {0,0,0} ; + + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + RECORD_INITIAL_POS (a_this, &init_pos); + + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, + &token) ; + ENSURE_PARSING_COND (status == CR_OK + && token + && token->type == PAGE_SYM_TK); + + cr_parsing_location_copy (&location, &token->location) ; + cr_token_destroy (token); + token = NULL; + + cr_parser_try_to_skip_spaces_and_comments (a_this); + + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, &token); + ENSURE_PARSING_COND (status == CR_OK && token); + + if (token->type == IDENT_TK) { + page_selector = token->u.str; + token->u.str = NULL; + cr_token_destroy (token); + token = NULL; + } else { + cr_tknzr_unget_token (PRIVATE (a_this)->tknzr, token); + token = NULL; + } + + /* + *try to parse pseudo_page + */ + cr_parser_try_to_skip_spaces_and_comments (a_this); + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, &token); + ENSURE_PARSING_COND (status == CR_OK && token); + + if (token->type == DELIM_TK && token->u.unichar == ':') { + cr_token_destroy (token); + token = NULL; + status = cr_parser_parse_ident (a_this, &page_pseudo_class); + CHECK_PARSING_STATUS (status, FALSE); + } else { + cr_tknzr_unget_token (PRIVATE (a_this)->tknzr, token); + token = NULL; + } + + /* + *parse_block + * + */ + cr_parser_try_to_skip_spaces_and_comments (a_this); + + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, &token); + + ENSURE_PARSING_COND (status == CR_OK && token + && token->type == CBO_TK); + + cr_token_destroy (token); + token = NULL; + + /* + *Call the appropriate SAC handler here. + */ + if (PRIVATE (a_this)->sac_handler + && PRIVATE (a_this)->sac_handler->start_page) { + PRIVATE (a_this)->sac_handler->start_page + (PRIVATE (a_this)->sac_handler, + page_selector, page_pseudo_class, + &location); + } + cr_parser_try_to_skip_spaces_and_comments (a_this); + + PRIVATE (a_this)->state = TRY_PARSE_PAGE_STATE; + + status = cr_parser_parse_declaration (a_this, &property, + &css_expression, + &important); + ENSURE_PARSING_COND (status == CR_OK); + + /* + *call the relevant SAC handler here... + */ + if (PRIVATE (a_this)->sac_handler + && PRIVATE (a_this)->sac_handler->property) { + if (css_expression) + cr_term_ref (css_expression); + + PRIVATE (a_this)->sac_handler->property + (PRIVATE (a_this)->sac_handler, + property, css_expression, important); + } + /* + *... and free the data structure passed to that last + *SAC handler. + */ + if (property) { + cr_string_destroy (property); + property = NULL; + } + if (css_expression) { + cr_term_unref (css_expression); + css_expression = NULL; + } + + for (;;) { + /*parse the other ';' separated declarations */ + if (token) { + cr_token_destroy (token); + token = NULL; + } + status = cr_tknzr_get_next_token + (PRIVATE (a_this)->tknzr, &token); + + ENSURE_PARSING_COND (status == CR_OK && token); + + if (token->type != SEMICOLON_TK) { + cr_tknzr_unget_token + (PRIVATE (a_this)->tknzr, + token); + token = NULL ; + break; + } + + cr_token_destroy (token); + token = NULL; + cr_parser_try_to_skip_spaces_and_comments (a_this); + + status = cr_parser_parse_declaration (a_this, &property, + &css_expression, + &important); + if (status != CR_OK) + break ; + + /* + *call the relevant SAC handler here... + */ + if (PRIVATE (a_this)->sac_handler + && PRIVATE (a_this)->sac_handler->property) { + cr_term_ref (css_expression); + PRIVATE (a_this)->sac_handler->property + (PRIVATE (a_this)->sac_handler, + property, css_expression, important); + } + /* + *... and free the data structure passed to that last + *SAC handler. + */ + if (property) { + cr_string_destroy (property); + property = NULL; + } + if (css_expression) { + cr_term_unref (css_expression); + css_expression = NULL; + } + } + cr_parser_try_to_skip_spaces_and_comments + (a_this) ; + if (token) { + cr_token_destroy (token) ; + token = NULL ; + } + + status = cr_tknzr_get_next_token + (PRIVATE (a_this)->tknzr, &token); + ENSURE_PARSING_COND (status == CR_OK + && token + && token->type == CBC_TK) ; + cr_token_destroy (token) ; + token = NULL ; + /* + *call the relevant SAC handler here. + */ + if (PRIVATE (a_this)->sac_handler + && PRIVATE (a_this)->sac_handler->end_page) { + PRIVATE (a_this)->sac_handler->end_page + (PRIVATE (a_this)->sac_handler, + page_selector, page_pseudo_class); + } + + if (page_selector) { + cr_string_destroy (page_selector); + page_selector = NULL; + } + + if (page_pseudo_class) { + cr_string_destroy (page_pseudo_class); + page_pseudo_class = NULL; + } + + cr_parser_try_to_skip_spaces_and_comments (a_this); + + /*here goes the former implem of this function ... */ + + cr_parser_clear_errors (a_this); + PRIVATE (a_this)->state = PAGE_PARSED_STATE; + + return CR_OK; + + error: + if (token) { + cr_token_destroy (token); + token = NULL; + } + if (page_selector) { + cr_string_destroy (page_selector); + page_selector = NULL; + } + if (page_pseudo_class) { + cr_string_destroy (page_pseudo_class); + page_pseudo_class = NULL; + } + if (property) { + cr_string_destroy (property); + property = NULL; + } + if (css_expression) { + cr_term_destroy (css_expression); + css_expression = NULL; + } + cr_tknzr_set_cur_pos (PRIVATE (a_this)->tknzr, &init_pos); + return status; +} + +/** + *Parses a charset declaration as defined implictly by the css2 spec in + *appendix D.1: + *charset ::= CHARSET_SYM S* STRING S* ';' + * + *@param a_this the "this pointer" of the current instance of #CRParser. + *@param a_value out parameter. The actual parsed value of the charset + *declararation. Note that for safety check reasons, *a_value must be + *set to NULL. + *@param a_charset_sym_location the parsing location of + *@return CR_OK upon successfull completion, an error code otherwise. + */ +enum CRStatus +cr_parser_parse_charset (CRParser * a_this, CRString ** a_value, + CRParsingLocation *a_charset_sym_location) +{ + enum CRStatus status = CR_OK; + CRInputPos init_pos; + CRToken *token = NULL; + CRString *charset_str = NULL; + + g_return_val_if_fail (a_this && a_value + && (*a_value == NULL), + CR_BAD_PARAM_ERROR); + + RECORD_INITIAL_POS (a_this, &init_pos); + + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, &token); + + ENSURE_PARSING_COND (status == CR_OK + && token && token->type == CHARSET_SYM_TK); + if (a_charset_sym_location) { + cr_parsing_location_copy (a_charset_sym_location, + &token->location) ; + } + cr_token_destroy (token); + token = NULL; + + PRIVATE (a_this)->state = TRY_PARSE_CHARSET_STATE; + + cr_parser_try_to_skip_spaces_and_comments (a_this); + + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, &token); + ENSURE_PARSING_COND (status == CR_OK + && token && token->type == STRING_TK); + charset_str = token->u.str; + token->u.str = NULL; + cr_token_destroy (token); + token = NULL; + + cr_parser_try_to_skip_spaces_and_comments (a_this); + + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, &token); + + ENSURE_PARSING_COND (status == CR_OK + && token && token->type == SEMICOLON_TK); + cr_token_destroy (token); + token = NULL; + + if (charset_str) { + *a_value = charset_str; + charset_str = NULL; + } + + PRIVATE (a_this)->state = CHARSET_PARSED_STATE; + return CR_OK; + + error: + + if (token) { + cr_token_destroy (token); + token = NULL; + } + + if (*a_value) { + cr_string_destroy (*a_value); + *a_value = NULL; + } + + if (charset_str) { + cr_string_destroy (charset_str); + charset_str = NULL; + } + + cr_tknzr_set_cur_pos (PRIVATE (a_this)->tknzr, &init_pos); + + return status; +} + +/** + *Parses the "@font-face" rule specified in the css1 spec in + *appendix D.1: + * + *font_face ::= FONT_FACE_SYM S* + *'{' S* declaration [ ';' S* declaration ]* '}' S* + * + *This function will call SAC handlers whenever it is necessary. + *@return CR_OK upon successfull completion, an error code otherwise. + */ +enum CRStatus +cr_parser_parse_font_face (CRParser * a_this) +{ + enum CRStatus status = CR_ERROR; + CRInputPos init_pos; + CRString *property = NULL; + CRTerm *css_expression = NULL; + CRToken *token = NULL; + gboolean important = FALSE; + guint32 next_char = 0, + cur_char = 0; + CRParsingLocation location = {0,0,0} ; + + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + RECORD_INITIAL_POS (a_this, &init_pos); + + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, &token); + ENSURE_PARSING_COND (status == CR_OK + && token + && token->type == FONT_FACE_SYM_TK); + + cr_parser_try_to_skip_spaces_and_comments (a_this); + if (token) { + cr_parsing_location_copy (&location, + &token->location) ; + cr_token_destroy (token); + token = NULL; + } + status = cr_tknzr_get_next_token (PRIVATE (a_this)->tknzr, + &token); + ENSURE_PARSING_COND (status == CR_OK && token + && token->type == CBO_TK); + if (token) { + cr_token_destroy (token); + token = NULL; + } + /* + *here, call the relevant SAC handler. + */ + if (PRIVATE (a_this)->sac_handler + && PRIVATE (a_this)->sac_handler->start_font_face) { + PRIVATE (a_this)->sac_handler->start_font_face + (PRIVATE (a_this)->sac_handler, &location); + } + PRIVATE (a_this)->state = TRY_PARSE_FONT_FACE_STATE; + /* + *and resume the parsing. + */ + cr_parser_try_to_skip_spaces_and_comments (a_this); + status = cr_parser_parse_declaration (a_this, &property, + &css_expression, &important); + if (status == CR_OK) { + /* + *here, call the relevant SAC handler. + */ + cr_term_ref (css_expression); + if (PRIVATE (a_this)->sac_handler && + PRIVATE (a_this)->sac_handler->property) { + PRIVATE (a_this)->sac_handler->property + (PRIVATE (a_this)->sac_handler, + property, css_expression, important); + } + ENSURE_PARSING_COND (css_expression && property); + } + /*free the data structures allocated during last parsing. */ + if (property) { + cr_string_destroy (property); + property = NULL; + } + if (css_expression) { + cr_term_unref (css_expression); + css_expression = NULL; + } + for (;;) { + PEEK_NEXT_CHAR (a_this, &next_char); + if (next_char == ';') { + READ_NEXT_CHAR (a_this, &cur_char); + } else { + break; + } + cr_parser_try_to_skip_spaces_and_comments (a_this); + status = cr_parser_parse_declaration (a_this, + &property, + &css_expression, + &important); + if (status != CR_OK) + break; + /* + *here, call the relevant SAC handler. + */ + cr_term_ref (css_expression); + if (PRIVATE (a_this)->sac_handler->property) { + PRIVATE (a_this)->sac_handler->property + (PRIVATE (a_this)->sac_handler, + property, css_expression, important); + } + /* + *Then, free the data structures allocated during + *last parsing. + */ + if (property) { + cr_string_destroy (property); + property = NULL; + } + if (css_expression) { + cr_term_unref (css_expression); + css_expression = NULL; + } + } + cr_parser_try_to_skip_spaces_and_comments (a_this); + READ_NEXT_CHAR (a_this, &cur_char); + ENSURE_PARSING_COND (cur_char == '}'); + /* + *here, call the relevant SAC handler. + */ + if (PRIVATE (a_this)->sac_handler->end_font_face) { + PRIVATE (a_this)->sac_handler->end_font_face + (PRIVATE (a_this)->sac_handler); + } + cr_parser_try_to_skip_spaces_and_comments (a_this); + + if (token) { + cr_token_destroy (token); + token = NULL; + } + cr_parser_clear_errors (a_this); + PRIVATE (a_this)->state = FONT_FACE_PARSED_STATE; + return CR_OK; + + error: + if (token) { + cr_token_destroy (token); + token = NULL; + } + if (property) { + cr_string_destroy (property); + property = NULL; + } + if (css_expression) { + cr_term_destroy (css_expression); + css_expression = NULL; + } + cr_tknzr_set_cur_pos (PRIVATE (a_this)->tknzr, &init_pos); + return status; +} + +/** + *Parses the data that comes from the + *input previously associated to the current instance of + *#CRParser. + *@param a_this the current instance of #CRParser. + *@return CR_OK ; + */ +enum CRStatus +cr_parser_parse (CRParser * a_this) +{ + enum CRStatus status = CR_ERROR; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && PRIVATE (a_this)->tknzr, CR_BAD_PARAM_ERROR); + + if (PRIVATE (a_this)->use_core_grammar == FALSE) { + status = cr_parser_parse_stylesheet (a_this); + } else { + status = cr_parser_parse_stylesheet_core (a_this); + } + + return status; +} + +enum CRStatus +cr_parser_set_tknzr (CRParser * a_this, CRTknzr * a_tknzr) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this), CR_BAD_PARAM_ERROR); + + if (PRIVATE (a_this)->tknzr) { + cr_tknzr_unref (PRIVATE (a_this)->tknzr); + } + + PRIVATE (a_this)->tknzr = a_tknzr; + + if (a_tknzr) + cr_tknzr_ref (a_tknzr); + + return CR_OK; +} + +/** + *Getter of the parser's underlying tokenizer + *@param a_this the current instance of #CRParser + *@param a_tknzr out parameter. The returned tokenizer + *@return CR_OK upon succesful completion, an error code + *otherwise + */ +enum CRStatus +cr_parser_get_tknzr (CRParser * a_this, CRTknzr ** a_tknzr) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this) + && a_tknzr, CR_BAD_PARAM_ERROR); + + *a_tknzr = PRIVATE (a_this)->tknzr; + return CR_OK; +} + +/** + *Gets the current parsing location. + *@param a_this the current instance of #CRParser + *@param a_loc the parsing location to get. + *@return CR_OK upon succesful completion, an error code + *otherwise. + */ +enum CRStatus +cr_parser_get_parsing_location (CRParser *a_this, + CRParsingLocation *a_loc) +{ + g_return_val_if_fail (a_this + && PRIVATE (a_this) + && a_loc, CR_BAD_PARAM_ERROR) ; + + return cr_tknzr_get_parsing_location + (PRIVATE (a_this)->tknzr, a_loc) ; +} + +/** + *Parses a stylesheet from a buffer + *@param a_this the current instance of #CRparser + *@param a_buf the input buffer + *@param a_len the length of the input buffer + *@param a_enc the encoding of the buffer + *@return CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_parser_parse_buf (CRParser * a_this, + const guchar * a_buf, + gulong a_len, enum CREncoding a_enc) +{ + enum CRStatus status = CR_ERROR; + CRTknzr *tknzr = NULL; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && a_buf, CR_BAD_PARAM_ERROR); + + tknzr = cr_tknzr_new_from_buf ((guchar*)a_buf, a_len, a_enc, FALSE); + + g_return_val_if_fail (tknzr != NULL, CR_ERROR); + + status = cr_parser_set_tknzr (a_this, tknzr); + g_return_val_if_fail (status == CR_OK, CR_ERROR); + + status = cr_parser_parse (a_this); + + return status; +} + +/** + *Destroys the current instance + *of #CRParser. + *@param a_this the current instance of #CRParser to + *destroy. + */ +void +cr_parser_destroy (CRParser * a_this) +{ + g_return_if_fail (a_this && PRIVATE (a_this)); + + if (PRIVATE (a_this)->tknzr) { + if (cr_tknzr_unref (PRIVATE (a_this)->tknzr) == TRUE) + PRIVATE (a_this)->tknzr = NULL; + } + + if (PRIVATE (a_this)->sac_handler) { + cr_doc_handler_unref (PRIVATE (a_this)->sac_handler); + PRIVATE (a_this)->sac_handler = NULL; + } + + if (PRIVATE (a_this)->err_stack) { + cr_parser_clear_errors (a_this); + PRIVATE (a_this)->err_stack = NULL; + } + + if (PRIVATE (a_this)) { + g_free (PRIVATE (a_this)); + PRIVATE (a_this) = NULL; + } + + if (a_this) { + g_free (a_this); + a_this = NULL; /*useless. Just for the sake of coherence */ + } +} diff --git a/src/libcroco/cr-parser.h b/src/libcroco/cr-parser.h new file mode 100644 index 000000000..1534afb86 --- /dev/null +++ b/src/libcroco/cr-parser.h @@ -0,0 +1,128 @@ +/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * Author: Dodji Seketeli + * See COPYRIGHTS file for copyrights information. + */ + +#ifndef __CR_PARSER_H__ +#define __CR_PARSER_H__ + +#include +#include "cr-input.h" +#include "cr-tknzr.h" +#include "cr-utils.h" +#include "cr-doc-handler.h" + +G_BEGIN_DECLS + +/** + *@file + *The declaration file + *of the #CRParser class. + */ +typedef struct _CRParser CRParser ; +typedef struct _CRParserPriv CRParserPriv ; + + +/** + *The implementation of + *the SAC parser. + *The Class is opaque + *and must be manipulated through + *the provided methods. + */ +struct _CRParser { + CRParserPriv *priv ; +} ; + + +CRParser * cr_parser_new (CRTknzr *a_tknzr) ; + +CRParser * cr_parser_new_from_buf (guchar *a_buf, gulong a_len, + enum CREncoding a_enc, + gboolean a_free_buf) ; + +CRParser * cr_parser_new_from_file (const guchar *a_file_uri, + enum CREncoding a_enc) ; + +CRParser * cr_parser_new_from_input (CRInput *a_input) ; + +enum CRStatus cr_parser_set_tknzr (CRParser *a_this, CRTknzr *a_tknzr) ; + +enum CRStatus cr_parser_get_tknzr (CRParser *a_this, CRTknzr **a_tknzr) ; + +enum CRStatus cr_parser_get_parsing_location (CRParser *a_this, CRParsingLocation *a_loc) ; + +enum CRStatus cr_parser_try_to_skip_spaces_and_comments (CRParser *a_this) ; + + +enum CRStatus cr_parser_set_sac_handler (CRParser *a_this, + CRDocHandler *a_handler) ; + +enum CRStatus cr_parser_get_sac_handler (CRParser *a_this, + CRDocHandler **a_handler) ; + +enum CRStatus cr_parser_set_use_core_grammar (CRParser *a_this, + gboolean a_use_core_grammar) ; +enum CRStatus cr_parser_get_use_core_grammar (CRParser *a_this, + gboolean *a_use_core_grammar) ; + +enum CRStatus cr_parser_parse (CRParser *a_this) ; + +enum CRStatus cr_parser_parse_file (CRParser *a_this, + const guchar *a_file_uri, + enum CREncoding a_enc) ; + +enum CRStatus cr_parser_parse_buf (CRParser *a_this, const guchar *a_buf, + gulong a_len, enum CREncoding a_enc) ; + +enum CRStatus cr_parser_set_default_sac_handler (CRParser *a_this) ; + +enum CRStatus cr_parser_parse_term (CRParser *a_this, CRTerm **a_term) ; + +enum CRStatus cr_parser_parse_expr (CRParser *a_this, CRTerm **a_expr) ; + +enum CRStatus cr_parser_parse_prio (CRParser *a_this, CRString **a_prio) ; + +enum CRStatus cr_parser_parse_declaration (CRParser *a_this, CRString **a_property, + CRTerm **a_expr, gboolean *a_important) ; + +enum CRStatus cr_parser_parse_statement_core (CRParser *a_this) ; + +enum CRStatus cr_parser_parse_ruleset (CRParser *a_this) ; + +enum CRStatus cr_parser_parse_import (CRParser *a_this, GList ** a_media_list, + CRString **a_import_string, + CRParsingLocation *a_location) ; + +enum CRStatus cr_parser_parse_media (CRParser *a_this) ; + +enum CRStatus cr_parser_parse_page (CRParser *a_this) ; + +enum CRStatus cr_parser_parse_charset (CRParser *a_this, CRString **a_value, + CRParsingLocation *a_charset_sym_location) ; + +enum CRStatus cr_parser_parse_font_face (CRParser *a_this) ; + +void cr_parser_destroy (CRParser *a_this) ; + +G_END_DECLS + +#endif /*__CR_PARSER_H__*/ diff --git a/src/libcroco/cr-parsing-location.c b/src/libcroco/cr-parsing-location.c new file mode 100644 index 000000000..81b05f7c3 --- /dev/null +++ b/src/libcroco/cr-parsing-location.c @@ -0,0 +1,153 @@ +/* -*- Mode: C; indent-tabs-mode: ni; c-basic-offset: 8 -*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * Author: Dodji Seketeli. + * See the COPYRIGHTS file for copyright information. + */ + +#include +#include "cr-parsing-location.h" + +/** + *@file + *Definition of the #CRparsingLocation class. + */ + + +/** + *Instanciates a new parsing location. + *@return the newly instanciated #CRParsingLocation. + *Must be freed by cr_parsing_location_destroy() + */ +CRParsingLocation * +cr_parsing_location_new (void) +{ + CRParsingLocation * result = NULL ; + + result = g_try_malloc (sizeof (CRParsingLocation)) ; + if (!result) { + cr_utils_trace_info ("Out of memory error") ; + return NULL ; + } + cr_parsing_location_init (result) ; + return result ; +} + +/** + *Initializes the an instance of #CRparsingLocation. + *@param a_this the current instance of #CRParsingLocation. + *@return CR_OK upon + */ +enum CRStatus +cr_parsing_location_init (CRParsingLocation *a_this) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR) ; + + memset (a_this, 0, sizeof (CRParsingLocation)) ; + return CR_OK ; +} + +/** + *Copies an instance of CRParsingLocation into another one. + *@param a_to the destination of the copy. + *Must be allocated by the caller. + *@param a_from the source of the copy. + *@return CR_OK upon succesful completion, an error code + *otherwise. + */ +enum CRStatus +cr_parsing_location_copy (CRParsingLocation *a_to, + CRParsingLocation *a_from) +{ + g_return_val_if_fail (a_to && a_from, CR_BAD_PARAM_ERROR) ; + + memcpy (a_to, a_from, sizeof (CRParsingLocation)) ; + return CR_OK ; +} + +/** + *@param a_this the current instance of #CRParsingLocation. + *@param a_mask a bitmap that defines which parts of the + *parsing location are to be serialized (line, column or byte offset) + *@return the serialized string or NULL in case of an error. + */ +gchar * +cr_parsing_location_to_string (CRParsingLocation *a_this, + enum CRParsingLocationSerialisationMask a_mask) +{ + GString *result = NULL ; + gchar *str = NULL ; + + g_return_val_if_fail (a_this, NULL) ; + + if (!a_mask) { + a_mask = DUMP_LINE | DUMP_COLUMN | DUMP_BYTE_OFFSET ; + } + result =g_string_new (NULL) ; + if (!result) + return NULL ; + if (a_mask & DUMP_LINE) { + g_string_append_printf (result, "line:%d ", + a_this->line) ; + } + if (a_mask & DUMP_COLUMN) { + g_string_append_printf (result, "column:%d ", + a_this->column) ; + } + if (a_mask & DUMP_BYTE_OFFSET) { + g_string_append_printf (result, "byte offset:%d ", + a_this->byte_offset) ; + } + if (result->len) { + str = result->str ; + g_string_free (result, FALSE) ; + } else { + g_string_free (result, TRUE) ; + } + return str ; +} + +void +cr_parsing_location_dump (CRParsingLocation *a_this, + enum CRParsingLocationSerialisationMask a_mask, + FILE *a_fp) +{ + gchar *str = NULL ; + + g_return_if_fail (a_this && a_fp) ; + str = cr_parsing_location_to_string (a_this, a_mask) ; + if (str) { + fprintf (a_fp, "%s", str) ; + g_free (str) ; + str = NULL ; + } +} + +/** + *Destroys the current instance of #CRParsingLocation + *@param a_this the current instance of #CRParsingLocation. Must + *have been allocated with cr_parsing_location_new(). + */ +void +cr_parsing_location_destroy (CRParsingLocation *a_this) +{ + g_return_if_fail (a_this) ; + g_free (a_this) ; +} + diff --git a/src/libcroco/cr-parsing-location.h b/src/libcroco/cr-parsing-location.h new file mode 100644 index 000000000..877c0507f --- /dev/null +++ b/src/libcroco/cr-parsing-location.h @@ -0,0 +1,70 @@ +/* -*- Mode: C; indent-tabs-mode: ni; c-basic-offset: 8 -*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * Author: Dodji Seketeli. + * See the COPYRIGHTS file for copyright information. + */ + +#ifndef __CR_PARSING_LOCATION_H__ +#define __CR_PARSING_LOCATION_H__ + +#include "cr-utils.h" + +G_BEGIN_DECLS + +/** + *@file + *The declaration of the CRParsingLocation + *object. This object keeps track of line/column/byte offset/ + *at which the parsing of a given CSS construction appears. + */ + +typedef struct _CRParsingLocation CRParsingLocation; +struct _CRParsingLocation { + guint line ; + guint column ; + guint byte_offset ; +} ; + + +enum CRParsingLocationSerialisationMask { + DUMP_LINE = 1, + DUMP_COLUMN = 1 << 1, + DUMP_BYTE_OFFSET = 1 << 2 +} ; + +CRParsingLocation * cr_parsing_location_new (void) ; + +enum CRStatus cr_parsing_location_init (CRParsingLocation *a_this) ; + +enum CRStatus cr_parsing_location_copy (CRParsingLocation *a_to, + CRParsingLocation *a_from) ; + +gchar * cr_parsing_location_to_string (CRParsingLocation *a_this, + enum CRParsingLocationSerialisationMask a_mask) ; +void cr_parsing_location_dump (CRParsingLocation *a_this, + enum CRParsingLocationSerialisationMask a_mask, + FILE *a_fp) ; + +void cr_parsing_location_destroy (CRParsingLocation *a_this) ; + + + +G_END_DECLS +#endif diff --git a/src/libcroco/cr-prop-list.c b/src/libcroco/cr-prop-list.c new file mode 100644 index 000000000..4c56b9cd3 --- /dev/null +++ b/src/libcroco/cr-prop-list.c @@ -0,0 +1,360 @@ +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * Author: Dodji Seketeli + * See COPYRIGHTS file for copyrights information. + */ + +#include +#include "cr-prop-list.h" + +#define PRIVATE(a_obj) (a_obj)->priv + +struct _CRPropListPriv { + CRString *prop; + CRDeclaration *decl; + CRPropList *next; + CRPropList *prev; +}; + +static CRPropList *cr_prop_list_allocate (void); + +/** + *Default allocator of CRPropList + *@return the newly allocated CRPropList or NULL + *if an error arises. + */ +static CRPropList * +cr_prop_list_allocate (void) +{ + CRPropList *result = NULL; + + result = g_try_malloc (sizeof (CRPropList)); + if (!result) { + cr_utils_trace_info ("could not allocate CRPropList"); + return NULL; + } + memset (result, 0, sizeof (CRPropList)); + PRIVATE (result) = g_try_malloc (sizeof (CRPropListPriv)); + if (!result) { + cr_utils_trace_info ("could not allocate CRPropListPriv"); + g_free (result); + return NULL; + } + memset (PRIVATE (result), 0, sizeof (CRPropListPriv)); + return result; +} + +/**************** + *public methods + ***************/ + +/** + *Appends a property list to the current one. + *@param a_this the current instance of #CRPropList + *@param a_to_append the property list to append + *@return the resulting prop list, or NULL if an error + *occured + */ +CRPropList * +cr_prop_list_append (CRPropList * a_this, CRPropList * a_to_append) +{ + CRPropList *cur = NULL; + + g_return_val_if_fail (a_to_append, NULL); + + if (!a_this) + return a_to_append; + + /*go fetch the last element of the list */ + for (cur = a_this; + cur && PRIVATE (cur) && PRIVATE (cur)->next; + cur = PRIVATE (cur)->next) ; + g_return_val_if_fail (cur, NULL); + PRIVATE (cur)->next = a_to_append; + PRIVATE (a_to_append)->prev = cur; + return a_this; +} + +/** + *Appends a pair of prop/declaration to + *the current prop list. + *@param a_this the current instance of #CRPropList + *@param a_prop the property to consider + *@param a_decl the declaration to consider + *@return the resulting property list, or NULL in case + *of an error. + */ +CRPropList * +cr_prop_list_append2 (CRPropList * a_this, + CRString * a_prop, + CRDeclaration * a_decl) +{ + CRPropList *list = NULL, + *result = NULL; + + g_return_val_if_fail (a_prop && a_decl, NULL); + + list = cr_prop_list_allocate (); + g_return_val_if_fail (list && PRIVATE (list), NULL); + + PRIVATE (list)->prop = a_prop; + PRIVATE (list)->decl = a_decl; + + result = cr_prop_list_append (a_this, list); + return result; +} + +/** + *Prepends a list to the current list + *@param a_this the current instance of #CRPropList + *@param the new list to prepend. + */ +CRPropList * +cr_prop_list_prepend (CRPropList * a_this, CRPropList * a_to_prepend) +{ + CRPropList *cur = NULL; + + g_return_val_if_fail (a_to_prepend, NULL); + + if (!a_this) + return a_to_prepend; + + for (cur = a_to_prepend; cur && PRIVATE (cur)->next; + cur = PRIVATE (cur)->next) ; + g_return_val_if_fail (cur, NULL); + PRIVATE (cur)->next = a_this; + PRIVATE (a_this)->prev = cur; + return a_to_prepend; +} + +/** + *Prepends a list to the current list + *@param a_this the current instance of #CRPropList + *@param the new list to prepend. + */ +CRPropList * +cr_prop_list_prepend2 (CRPropList * a_this, + CRString * a_prop, CRDeclaration * a_decl) +{ + CRPropList *list = NULL, + *result = NULL; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && a_prop && a_decl, NULL); + + list = cr_prop_list_allocate (); + g_return_val_if_fail (list, NULL); + PRIVATE (list)->prop = a_prop; + PRIVATE (list)->decl = a_decl; + result = cr_prop_list_prepend (a_this, list); + return result; +} + +/** + *Sets the property of a CRPropList + *@param a_this the current instance of #CRPropList + *@param a_prop the property to set + */ +enum CRStatus +cr_prop_list_set_prop (CRPropList * a_this, CRString * a_prop) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this) + && a_prop, CR_BAD_PARAM_ERROR); + + PRIVATE (a_this)->prop = a_prop; + return CR_OK; +} + +/** + *Getter of the property associated to the current instance + *of #CRPropList + *@param a_this the current instance of #CRPropList + *@param a_prop out parameter. The returned property + *@return CR_OK upon successful completion, an error code + *otherwise. + */ +enum CRStatus +cr_prop_list_get_prop (CRPropList * a_this, CRString ** a_prop) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this) + && a_prop, CR_BAD_PARAM_ERROR); + + *a_prop = PRIVATE (a_this)->prop; + return CR_OK; +} + +enum CRStatus +cr_prop_list_set_decl (CRPropList * a_this, CRDeclaration * a_decl) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this) + && a_decl, CR_BAD_PARAM_ERROR); + + PRIVATE (a_this)->decl = a_decl; + return CR_OK; +} + +enum CRStatus +cr_prop_list_get_decl (CRPropList * a_this, CRDeclaration ** a_decl) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this) + && a_decl, CR_BAD_PARAM_ERROR); + + *a_decl = PRIVATE (a_this)->decl; + return CR_OK; +} + +/** + *Lookup a given property/declaration pair + *@param a_this the current instance of #CRPropList + *@param a_prop the property to lookup + *@param a_prop_list out parameter. The property/declaration + *pair found (if and only if the function returned code if CR_OK) + *@return CR_OK if a prop/decl pair has been found, + *CR_VALUE_NOT_FOUND_ERROR if not, or an error code if something + *bad happens. + */ +enum CRStatus +cr_prop_list_lookup_prop (CRPropList * a_this, + CRString * a_prop, CRPropList ** a_pair) +{ + CRPropList *cur = NULL; + + g_return_val_if_fail (a_prop && a_pair, CR_BAD_PARAM_ERROR); + + if (!a_this) + return CR_VALUE_NOT_FOUND_ERROR; + + g_return_val_if_fail (PRIVATE (a_this), CR_BAD_PARAM_ERROR); + + for (cur = a_this; cur; cur = PRIVATE (cur)->next) { + if (PRIVATE (cur)->prop + && PRIVATE (cur)->prop->stryng + && PRIVATE (cur)->prop->stryng->str + && a_prop->stryng + && a_prop->stryng->str + && !strcmp (PRIVATE (cur)->prop->stryng->str, + a_prop->stryng->str)) + break; + } + + if (cur) { + *a_pair = cur; + return CR_OK; + } + + return CR_VALUE_NOT_FOUND_ERROR; +} + +/** + *Gets the next prop/decl pair in the list + *@param a_this the current instance of CRPropList + *@param the next prop/decl pair, or NULL if we + *reached the end of the list. + *@return the next prop/declaration pair of the list, + *or NULL if we reached end of list (or if an error occurs) + */ +CRPropList * +cr_prop_list_get_next (CRPropList * a_this) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this), NULL); + + return PRIVATE (a_this)->next; +} + +/** + *Gets the previous prop/decl pair in the list + *@param a_this the current instance of CRPropList + *@param the previous prop/decl pair, or NULL if we + *reached the end of the list. + *@return the previous prop/declaration pair of the list, + *or NULL if we reached end of list (or if an error occurs) + */ +CRPropList * +cr_prop_list_get_prev (CRPropList * a_this) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this), NULL); + + return PRIVATE (a_this)->prev; +} + +/** + *Unlinks a prop/decl pair from the list + *@param a_this the current list of prop/decl pairs + *@param a_pair the prop/decl pair to unlink. + *@return the new list or NULL in case of an error. + */ +CRPropList * +cr_prop_list_unlink (CRPropList * a_this, CRPropList * a_pair) +{ + CRPropList *prev = NULL, + *next = NULL; + + g_return_val_if_fail (a_this && PRIVATE (a_this) && a_pair, NULL); + + /*some sanity checks */ + if (PRIVATE (a_pair)->next) { + next = PRIVATE (a_pair)->next; + g_return_val_if_fail (PRIVATE (next), NULL); + g_return_val_if_fail (PRIVATE (next)->prev == a_pair, NULL); + } + if (PRIVATE (a_pair)->prev) { + prev = PRIVATE (a_pair)->prev; + g_return_val_if_fail (PRIVATE (prev), NULL); + g_return_val_if_fail (PRIVATE (prev)->next == a_pair, NULL); + } + if (prev) { + PRIVATE (prev)->next = next; + } + if (next) { + PRIVATE (next)->prev = prev; + } + PRIVATE (a_pair)->prev = PRIVATE (a_pair)->next = NULL; + if (a_this == a_pair) { + if (next) + return next; + return NULL; + } + return a_this; +} + +void +cr_prop_list_destroy (CRPropList * a_this) +{ + CRPropList *tail = NULL, + *cur = NULL; + + g_return_if_fail (a_this && PRIVATE (a_this)); + + for (tail = a_this; + tail && PRIVATE (tail) && PRIVATE (tail)->next; + tail = cr_prop_list_get_next (tail)) ; + g_return_if_fail (tail); + + cur = tail; + + while (cur) { + tail = PRIVATE (cur)->prev; + if (tail && PRIVATE (tail)) + PRIVATE (tail)->next = NULL; + PRIVATE (cur)->prev = NULL; + g_free (PRIVATE (cur)); + PRIVATE (cur) = NULL; + g_free (cur); + cur = tail; + } +} diff --git a/src/libcroco/cr-prop-list.h b/src/libcroco/cr-prop-list.h new file mode 100644 index 000000000..a003be260 --- /dev/null +++ b/src/libcroco/cr-prop-list.h @@ -0,0 +1,80 @@ +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * Author: Dodji Seketeli + * See COPYRIGHTS file for copyrights information. + */ + +#ifndef __CR_PROP_LIST_H__ +#define __CR_PROP_LIST_H__ + +#include "cr-utils.h" +#include "cr-declaration.h" +#include "cr-string.h" + +G_BEGIN_DECLS + +typedef struct _CRPropList CRPropList ; +typedef struct _CRPropListPriv CRPropListPriv ; + +struct _CRPropList +{ + CRPropListPriv * priv; +} ; + +CRPropList * cr_prop_list_append (CRPropList *a_this, + CRPropList *a_to_append) ; + +CRPropList * cr_prop_list_append2 (CRPropList *a_this, + CRString *a_prop, + CRDeclaration *a_decl) ; + +CRPropList * cr_prop_list_prepend (CRPropList *a_this, + CRPropList *a_to_append) ; + +CRPropList * cr_prop_list_prepend2 (CRPropList *a_this, + CRString *a_prop, + CRDeclaration *a_decl) ; + +enum CRStatus cr_prop_list_set_prop (CRPropList *a_this, + CRString *a_prop) ; + +enum CRStatus cr_prop_list_get_prop (CRPropList *a_this, + CRString **a_prop) ; + +enum CRStatus cr_prop_list_lookup_prop (CRPropList *a_this, + CRString *a_prop, + CRPropList**a_pair) ; + +CRPropList * cr_prop_list_get_next (CRPropList *a_this) ; + +CRPropList * cr_prop_list_get_prev (CRPropList *a_this) ; + +enum CRStatus cr_prop_list_set_decl (CRPropList *a_this, + CRDeclaration *a_decl); + +enum CRStatus cr_prop_list_get_decl (CRPropList *a_this, + CRDeclaration **a_decl) ; + +CRPropList * cr_prop_list_unlink (CRPropList *a_this, + CRPropList *a_pair) ; + +void cr_prop_list_destroy (CRPropList *a_this) ; + +G_END_DECLS + +#endif /*__CR_PROP_LIST_H__*/ diff --git a/src/libcroco/cr-pseudo.c b/src/libcroco/cr-pseudo.c new file mode 100644 index 000000000..8e036a30f --- /dev/null +++ b/src/libcroco/cr-pseudo.c @@ -0,0 +1,153 @@ +/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * Author: Dodji Seketeli + * See COPYRIGHTS file for copyright information. + */ + +#include "cr-pseudo.h" + +/** + *@file + *The definition of the #CRPseudo class. + */ + +/** + *Constructor of the #CRPseudo class. + *@return the newly build instance. + */ +CRPseudo * +cr_pseudo_new (void) +{ + CRPseudo *result = NULL; + + result = g_malloc0 (sizeof (CRPseudo)); + + return result; +} + +guchar * +cr_pseudo_to_string (CRPseudo * a_this) +{ + guchar *result = NULL; + GString *str_buf = NULL; + + g_return_val_if_fail (a_this, NULL); + + str_buf = g_string_new (NULL); + + if (a_this->type == IDENT_PSEUDO) { + guchar *name = NULL; + + if (a_this->name == NULL) { + goto error; + } + + name = g_strndup (a_this->name->stryng->str, + a_this->name->stryng->len); + + if (name) { + g_string_append (str_buf, name); + g_free (name); + name = NULL; + } + } else if (a_this->type == FUNCTION_PSEUDO) { + guchar *name = NULL, + *arg = NULL; + + if (a_this->name == NULL) + goto error; + + name = g_strndup (a_this->name->stryng->str, + a_this->name->stryng->len); + + if (a_this->extra) { + arg = g_strndup (a_this->extra->stryng->str, + a_this->extra->stryng->len); + } + + if (name) { + g_string_append_printf (str_buf, "%s(", name); + g_free (name); + name = NULL; + + if (arg) { + g_string_append (str_buf, arg); + g_free (arg); + arg = NULL; + } + + g_string_append_c (str_buf, ')'); + } + } + + if (str_buf) { + result = str_buf->str; + g_string_free (str_buf, FALSE); + str_buf = NULL; + } + + return result; + + error: + g_string_free (str_buf, TRUE); + return NULL; +} + +/** + *Dumps the pseudo to a file. + *@param a_this the current instance of pseudo + *@param a_fp the destination file pointer. + */ +void +cr_pseudo_dump (CRPseudo * a_this, FILE * a_fp) +{ + guchar *tmp_str = NULL; + + if (a_this) { + tmp_str = cr_pseudo_to_string (a_this); + if (tmp_str) { + fprintf (a_fp, "%s", tmp_str); + g_free (tmp_str); + tmp_str = NULL; + } + } +} + +/** + *destructor of the #CRPseudo class. + *@param a_this the current instance to destroy. + */ +void +cr_pseudo_destroy (CRPseudo * a_this) +{ + g_return_if_fail (a_this); + + if (a_this->name) { + cr_string_destroy (a_this->name); + a_this->name = NULL; + } + + if (a_this->extra) { + cr_string_destroy (a_this->extra); + a_this->extra = NULL; + } + + g_free (a_this); +} diff --git a/src/libcroco/cr-pseudo.h b/src/libcroco/cr-pseudo.h new file mode 100644 index 000000000..6de6c9e21 --- /dev/null +++ b/src/libcroco/cr-pseudo.h @@ -0,0 +1,64 @@ +/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * See COPYRIGHTS file for copyright information + */ + +#ifndef __CR_PSEUDO_H__ +#define __CR_PSEUDO_H__ + +#include +#include +#include "cr-attr-sel.h" +#include "cr-parsing-location.h" + +G_BEGIN_DECLS + +enum CRPseudoType +{ + IDENT_PSEUDO = 0, + FUNCTION_PSEUDO +} ; + +typedef struct _CRPseudo CRPseudo ; + +/** + *The CRPseudo Class. + *Abstract a "pseudo" as defined by the css2 spec + *in appendix D.1 . + */ +struct _CRPseudo +{ + enum CRPseudoType type ; + CRString *name ; + CRString *extra ; + CRParsingLocation location ; +} ; + +CRPseudo * cr_pseudo_new (void) ; + +guchar * cr_pseudo_to_string (CRPseudo *a_this) ; + +void cr_pseudo_dump (CRPseudo *a_this, FILE *a_fp) ; + +void cr_pseudo_destroy (CRPseudo *a_this) ; + +G_END_DECLS + +#endif /*__CR_PSEUDO_H__*/ diff --git a/src/libcroco/cr-rgb.c b/src/libcroco/cr-rgb.c new file mode 100644 index 000000000..4bda1968e --- /dev/null +++ b/src/libcroco/cr-rgb.c @@ -0,0 +1,621 @@ +/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * Author: Dodji Seketeli + * See COPYRIGHTS file for copyrights information. + */ + + +#include +#include +#include "cr-rgb.h" +#include "cr-term.h" +#include "cr-parser.h" + +static CRRgb gv_standard_colors[] = { + {"aliceblue", 240, 248, 255, FALSE, FALSE, FALSE, {0,0,0}}, + {"antiquewhite", 250, 235, 215, FALSE, FALSE, FALSE, {0,0,0}}, + {"aqua", 0, 255, 255, FALSE, FALSE, FALSE, {0,0,0}}, + {"aquamarine", 127, 255, 212, FALSE, FALSE, FALSE, {0,0,0}}, + {"azure", 240, 255, 255, FALSE, FALSE, FALSE, {0,0,0}}, + {"beige", 245, 245, 220, FALSE, FALSE, FALSE, {0,0,0}}, + {"bisque", 255, 228, 196, FALSE, FALSE, FALSE, {0,0,0}}, + {"black", 0, 0, 0, FALSE, FALSE, FALSE, {0,0,0}}, + {"blanchedalmond", 255, 235, 205, FALSE, FALSE, FALSE, {0,0,0}}, + {"blue", 0, 0, 255, FALSE, FALSE, FALSE, {0,0,0}}, + {"blueviolet", 138, 43, 226, FALSE, FALSE, FALSE, {0,0,0}}, + {"brown", 165, 42, 42, FALSE, FALSE, FALSE, {0,0,0}}, + {"burlywood", 222, 184, 135, FALSE, FALSE, FALSE, {0,0,0}}, + {"cadetblue", 95, 158, 160, FALSE, FALSE, FALSE, {0,0,0}}, + {"chartreuse", 127, 255, 0, FALSE, FALSE, FALSE, {0,0,0}}, + {"chocolate", 210, 105, 30, FALSE, FALSE, FALSE, {0,0,0}}, + {"coral", 255, 127, 80, FALSE, FALSE, FALSE, {0,0,0}}, + {"cornflowerblue", 100, 149, 237, FALSE, FALSE, FALSE, {0,0,0}}, + {"cornsilk", 255, 248, 220, FALSE, FALSE, FALSE, {0,0,0}}, + {"crimson", 220, 20, 60, FALSE, FALSE, FALSE, {0,0,0}}, + {"cyan", 0, 255, 255, FALSE, FALSE, FALSE, {0,0,0}}, + {"darkblue", 0, 0, 139, FALSE, FALSE, FALSE, {0,0,0}}, + {"darkcyan", 0, 139, 139, FALSE, FALSE, FALSE, {0,0,0}}, + {"darkgoldenrod", 184, 134, 11, FALSE, FALSE, FALSE, {0,0,0}}, + {"darkgray", 169, 169, 169, FALSE, FALSE, FALSE, {0,0,0}}, + {"darkgreen", 0, 100, 0, FALSE, FALSE, FALSE, {0,0,0}}, + {"darkgrey", 169, 169, 169, FALSE, FALSE, FALSE, {0,0,0}}, + {"darkkhaki", 189, 183, 107, FALSE, FALSE, FALSE, {0,0,0}}, + {"darkmagenta", 139, 0, 139, FALSE, FALSE, FALSE, {0,0,0}}, + {"darkolivegreen", 85, 107, 47, FALSE, FALSE, FALSE, {0,0,0}}, + {"darkorange", 255, 140, 0, FALSE, FALSE, FALSE, {0,0,0}}, + {"darkorchid", 153, 50, 204, FALSE, FALSE, FALSE, {0,0,0}}, + {"darkred", 139, 0, 0, FALSE, FALSE, FALSE, {0,0,0}}, + {"darksalmon", 233, 150, 122, FALSE, FALSE, FALSE, {0,0,0}}, + {"darkseagreen", 143, 188, 143, FALSE, FALSE, FALSE, {0,0,0}}, + {"darkslateblue", 72, 61, 139, FALSE, FALSE, FALSE, {0,0,0}}, + {"darkslategray", 47, 79, 79, FALSE, FALSE, FALSE, {0,0,0}}, + {"darkslategrey", 47, 79, 79, FALSE, FALSE, FALSE, {0,0,0}}, + {"darkturquoise", 0, 206, 209, FALSE, FALSE, FALSE, {0,0,0}}, + {"darkviolet", 148, 0, 211, FALSE, FALSE, FALSE, {0,0,0}}, + {"deeppink", 255, 20, 147, FALSE, FALSE, FALSE, {0,0,0}}, + {"deepskyblue", 0, 191, 255, FALSE, FALSE, FALSE, {0,0,0}}, + {"dimgray", 105, 105, 105, FALSE, FALSE, FALSE, {0,0,0}}, + {"dimgrey", 105, 105, 105, FALSE, FALSE, FALSE, {0,0,0}}, + {"dodgerblue", 30, 144, 255, FALSE, FALSE, FALSE, {0,0,0}}, + {"firebrick", 178, 34, 34, FALSE, FALSE, FALSE, {0,0,0}}, + {"floralwhite", 255, 250, 240, FALSE, FALSE, FALSE, {0,0,0}}, + {"forestgreen", 34, 139, 34, FALSE, FALSE, FALSE, {0,0,0}}, + {"fuchsia", 255, 0, 255, FALSE, FALSE, FALSE, {0,0,0}}, + {"gainsboro", 220, 220, 220, FALSE, FALSE, FALSE, {0,0,0}}, + {"ghostwhite", 248, 248, 255, FALSE, FALSE, FALSE, {0,0,0}}, + {"gold", 255, 215, 0, FALSE, FALSE, FALSE, {0,0,0}}, + {"goldenrod", 218, 165, 32, FALSE, FALSE, FALSE, {0,0,0}}, + {"gray", 128, 128, 128, FALSE, FALSE, FALSE, {0,0,0}}, + {"grey", 128, 128, 128, FALSE, FALSE, FALSE, {0,0,0}}, + {"green", 0, 128, 0, FALSE, FALSE, FALSE, {0,0,0}}, + {"greenyellow", 173, 255, 47, FALSE, FALSE, FALSE, {0,0,0}}, + {"honeydew", 240, 255, 240, FALSE, FALSE, FALSE, {0,0,0}}, + {"hotpink", 255, 105, 180, FALSE, FALSE, FALSE, {0,0,0}}, + {"indianred", 205, 92, 92, FALSE, FALSE, FALSE, {0,0,0}}, + {"indigo", 75, 0, 130, FALSE, FALSE, FALSE, {0,0,0}}, + {"ivory", 255, 255, 240, FALSE, FALSE, FALSE, {0,0,0}}, + {"khaki", 240, 230, 140, FALSE, FALSE, FALSE, {0,0,0}}, + {"lavender", 230, 230, 250, FALSE, FALSE, FALSE, {0,0,0}}, + {"lavenderblush", 255, 240, 245, FALSE, FALSE, FALSE, {0,0,0}}, + {"lawngreen", 124, 252, 0, FALSE, FALSE, FALSE, {0,0,0}}, + {"lemonchiffon", 255, 250, 205, FALSE, FALSE, FALSE, {0,0,0}}, + {"lightblue", 173, 216, 230, FALSE, FALSE, FALSE, {0,0,0}}, + {"lightcoral", 240, 128, 128, FALSE, FALSE, FALSE, {0,0,0}}, + {"lightcyan", 224, 255, 255, FALSE, FALSE, FALSE, {0,0,0}}, + {"lightgoldenrodyellow", 250, 250, 210, FALSE, FALSE, FALSE, {0,0,0}}, + {"lightgray", 211, 211, 211, FALSE, FALSE, FALSE, {0,0,0}}, + {"lightgreen", 144, 238, 144, FALSE, FALSE, FALSE, {0,0,0}}, + {"lightgrey", 211, 211, 211, FALSE, FALSE, FALSE, {0,0,0}}, + {"lightpink", 255, 182, 193, FALSE, FALSE, FALSE, {0,0,0}}, + {"lightsalmon", 255, 160, 122, FALSE, FALSE, FALSE, {0,0,0}}, + {"lightseagreen", 32, 178, 170, FALSE, FALSE, FALSE, {0,0,0}}, + {"lightskyblue", 135, 206, 250, FALSE, FALSE, FALSE, {0,0,0}}, + {"lightslategray", 119, 136, 153, FALSE, FALSE, FALSE, {0,0,0}}, + {"lightslategrey", 119, 136, 153, FALSE, FALSE, FALSE, {0,0,0}}, + {"lightsteelblue", 176, 196, 222, FALSE, FALSE, FALSE, {0,0,0}}, + {"lightyellow", 255, 255, 224, FALSE, FALSE, FALSE, {0,0,0}}, + {"lime", 0, 255, 0, FALSE, FALSE, FALSE, {0,0,0}}, + {"limegreen", 50, 205, 50, FALSE, FALSE, FALSE, {0,0,0}}, + {"linen", 250, 240, 230, FALSE, FALSE, FALSE, {0,0,0}}, + {"magenta", 255, 0, 255, FALSE, FALSE, FALSE, {0,0,0}}, + {"maroon", 128, 0, 0, FALSE, FALSE, FALSE, {0,0,0}}, + {"mediumaquamarine", 102, 205, 170, FALSE, FALSE, FALSE, {0,0,0}}, + {"mediumblue", 0, 0, 205, FALSE, FALSE, FALSE, {0,0,0}}, + {"mediumorchid", 186, 85, 211, FALSE, FALSE, FALSE, {0,0,0}}, + {"mediumpurple", 147, 112, 219, FALSE, FALSE, FALSE, {0,0,0}}, + {"mediumseagreen", 60, 179, 113, FALSE, FALSE, FALSE, {0,0,0}}, + {"mediumslateblue", 123, 104, 238, FALSE, FALSE, FALSE, {0,0,0}}, + {"mediumspringgreen", 0, 250, 154, FALSE, FALSE, FALSE, {0,0,0}}, + {"mediumturquoise", 72, 209, 204, FALSE, FALSE, FALSE, {0,0,0}}, + {"mediumvioletred", 199, 21, 133, FALSE, FALSE, FALSE, {0,0,0}}, + {"midnightblue", 25, 25, 112, FALSE, FALSE, FALSE, {0,0,0}}, + {"mintcream", 245, 255, 250, FALSE, FALSE, FALSE, {0,0,0}}, + {"mistyrose", 255, 228, 225, FALSE, FALSE, FALSE, {0,0,0}}, + {"moccasin", 255, 228, 181, FALSE, FALSE, FALSE, {0,0,0}}, + {"navajowhite", 255, 222, 173, FALSE, FALSE, FALSE, {0,0,0}}, + {"navy", 0, 0, 128, FALSE, FALSE, FALSE, {0,0,0}}, + {"oldlace", 253, 245, 230, FALSE, FALSE, FALSE, {0,0,0}}, + {"olive", 128, 128, 0, FALSE, FALSE, FALSE, {0,0,0}}, + {"olivedrab", 107, 142, 35, FALSE, FALSE, FALSE, {0,0,0}}, + {"orange", 255, 165, 0, FALSE, FALSE, FALSE, {0,0,0}}, + {"orangered", 255, 69, 0, FALSE, FALSE, FALSE, {0,0,0}}, + {"orchid", 218, 112, 214, FALSE, FALSE, FALSE, {0,0,0}}, + {"palegoldenrod", 238, 232, 170, FALSE, FALSE, FALSE, {0,0,0}}, + {"palegreen", 152, 251, 152, FALSE, FALSE, FALSE, {0,0,0}}, + {"paleturquoise", 175, 238, 238, FALSE, FALSE, FALSE, {0,0,0}}, + {"palevioletred", 219, 112, 147, FALSE, FALSE, FALSE, {0,0,0}}, + {"papayawhip", 255, 239, 213, FALSE, FALSE, FALSE, {0,0,0}}, + {"peachpuff", 255, 218, 185, FALSE, FALSE, FALSE, {0,0,0}}, + {"peru", 205, 133, 63, FALSE, FALSE, FALSE, {0,0,0}}, + {"pink", 255, 192, 203, FALSE, FALSE, FALSE, {0,0,0}}, + {"plum", 221, 160, 221, FALSE, FALSE, FALSE, {0,0,0}}, + {"powderblue", 176, 224, 230, FALSE, FALSE, FALSE, {0,0,0}}, + {"purple", 128, 0, 128, FALSE, FALSE, FALSE, {0,0,0}}, + {"red", 255, 0, 0, FALSE, FALSE, FALSE, {0,0,0}}, + {"rosybrown", 188, 143, 143, FALSE, FALSE, FALSE, {0,0,0}}, + {"royalblue", 65, 105, 225, FALSE, FALSE, FALSE, {0,0,0}}, + {"saddlebrown", 139, 69, 19, FALSE, FALSE, FALSE, {0,0,0}}, + {"salmon", 250, 128, 114, FALSE, FALSE, FALSE, {0,0,0}}, + {"sandybrown", 244, 164, 96, FALSE, FALSE, FALSE, {0,0,0}}, + {"seagreen", 46, 139, 87, FALSE, FALSE, FALSE, {0,0,0}}, + {"seashell", 255, 245, 238, FALSE, FALSE, FALSE, {0,0,0}}, + {"sienna", 160, 82, 45, FALSE, FALSE, FALSE, {0,0,0}}, + {"silver", 192, 192, 192, FALSE, FALSE, FALSE, {0,0,0}}, + {"skyblue", 135, 206, 235, FALSE, FALSE, FALSE, {0,0,0}}, + {"slateblue", 106, 90, 205, FALSE, FALSE, FALSE, {0,0,0}}, + {"slategray", 112, 128, 144, FALSE, FALSE, FALSE, {0,0,0}}, + {"slategrey", 112, 128, 144, FALSE, FALSE, FALSE, {0,0,0}}, + {"snow", 255, 250, 250, FALSE, FALSE, FALSE, {0,0,0}}, + {"springgreen", 0, 255, 127, FALSE, FALSE, FALSE, {0,0,0}}, + {"steelblue", 70, 130, 180, FALSE, FALSE, FALSE, {0,0,0}}, + {"tan", 210, 180, 140, FALSE, FALSE, FALSE, {0,0,0}}, + {"teal", 0, 128, 128, FALSE, FALSE, FALSE, {0,0,0}}, + {"thistle", 216, 191, 216, FALSE, FALSE, FALSE, {0,0,0}}, + {"tomato", 255, 99, 71, FALSE, FALSE, FALSE, {0,0,0}}, + {"turquoise", 64, 224, 208, FALSE, FALSE, FALSE, {0,0,0}}, + {"violet", 238, 130, 238, FALSE, FALSE, FALSE, {0,0,0}}, + {"wheat", 245, 222, 179, FALSE, FALSE, FALSE, {0,0,0}}, + {"white", 255, 255, 255, FALSE, FALSE, FALSE, {0,0,0}}, + {"whitesmoke", 245, 245, 245, FALSE, FALSE, FALSE, {0,0,0}}, + {"yellow", 255, 255, 0, FALSE, FALSE, FALSE, {0,0,0}}, + {"yellowgreen", 154, 205, 50, FALSE, FALSE, FALSE, {0,0,0}}, + {"transparent", 255, 255, 255, FALSE, FALSE, TRUE, {0,0,0}} +}; + +/** + *The default constructor of #CRRgb. + *@return the newly built instance of #CRRgb + */ +CRRgb * +cr_rgb_new (void) +{ + CRRgb *result = NULL; + + result = g_try_malloc (sizeof (CRRgb)); + + if (result == NULL) { + cr_utils_trace_info ("No more memory"); + return NULL; + } + + memset (result, 0, sizeof (CRRgb)); + + return result; +} + +/** + *A constructor of #CRRgb. + *@param a_red the red component of the color. + *@param a_green the green component of the color. + *@param a_blue the blue component of the color. + *@param a_unit the unit of the rgb values. + *(either percentage or integer values) + *@return the newly built instance of #CRRgb. + */ +CRRgb * +cr_rgb_new_with_vals (gulong a_red, gulong a_green, + gulong a_blue, gboolean a_is_percentage) +{ + CRRgb *result = NULL; + + result = cr_rgb_new (); + + g_return_val_if_fail (result, NULL); + + result->red = a_red; + result->green = a_green; + result->blue = a_blue; + result->is_percentage = a_is_percentage; + + return result; +} + +/** + *Serializes the rgb into a zero terminated string. + *@param a_this the instance of #CRRgb to serialize. + *@return the zero terminated string containing the serialized + *rgb. MUST BE FREED by the caller using g_free(). + */ +guchar * +cr_rgb_to_string (CRRgb * a_this) +{ + guchar *result = NULL; + GString *str_buf = NULL; + + str_buf = g_string_new (NULL); + g_return_val_if_fail (str_buf, NULL); + + if (a_this->is_percentage == 1) { + g_string_append_printf (str_buf, "%ld", a_this->red); + + g_string_append (str_buf, "%, "); + + g_string_append_printf (str_buf, "%ld", a_this->green); + g_string_append (str_buf, "%, "); + + g_string_append_printf (str_buf, "%ld", a_this->blue); + g_string_append_c (str_buf, '%'); + } else { + g_string_append_printf (str_buf, "%ld", a_this->red); + g_string_append (str_buf, ", "); + + g_string_append_printf (str_buf, "%ld", a_this->green); + g_string_append (str_buf, ", "); + + g_string_append_printf (str_buf, "%ld", a_this->blue); + } + + if (str_buf) { + result = str_buf->str; + g_string_free (str_buf, FALSE); + } + + return result; +} + +/** + *Dumps the current instance of #CRRgb + *to a file. + *@param a_this the "this pointer" of + *the current instance of #CRRgb. + *@param a_fp the destination file pointer. + */ +void +cr_rgb_dump (CRRgb * a_this, FILE * a_fp) +{ + guchar *str = NULL; + + g_return_if_fail (a_this); + + str = cr_rgb_to_string (a_this); + + if (str) { + fprintf (a_fp, "%s", str); + g_free (str); + str = NULL; + } +} + +/** + *If the rgb values are expressed in percentage, + *compute their real value. + *@param a_this the current instance of #CRRgb + *@return + */ +enum CRStatus +cr_rgb_compute_from_percentage (CRRgb * a_this) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + if (a_this->is_percentage == FALSE) + return CR_OK; + a_this->red = a_this->red * 255 / 100; + a_this->green = a_this->green * 255 / 100; + a_this->blue = a_this->blue * 255 / 100; + a_this->is_percentage = FALSE; + return CR_OK; +} + +/** + *Sets rgb values to the RGB. + *@param a_this the current instance of #CRRgb. + *@param a_red the red value. + *@param a_green the green value. + *@param a_blue the blue value. + *@return CR_OK upon successful completion, an error code + *otherwise. + */ +enum CRStatus +cr_rgb_set (CRRgb * a_this, gulong a_red, + gulong a_green, gulong a_blue, gboolean a_is_percentage) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + if (a_is_percentage != FALSE) { + g_return_val_if_fail (a_red <= 100 + && a_green <= 100 + && a_blue <= 100, CR_BAD_PARAM_ERROR); + } + + a_this->is_percentage = a_is_percentage; + + a_this->red = a_red; + a_this->green = a_green; + a_this->blue = a_blue; + a_this->inherit = FALSE ; + a_this->is_transparent = FALSE ; + return CR_OK; +} + +/** + *sets the value of the rgb to inherit. + *Look at the css spec from chapter 6.1 to 6.2 to understand + *the meaning of "inherit". + *@param a_this the current instance of #CRRgb + * + */ +enum CRStatus +cr_rgb_set_to_inherit (CRRgb *a_this, gboolean a_inherit) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR) ; + + a_this->inherit = a_inherit ; + + return CR_OK ; +} + +gboolean +cr_rgb_is_set_to_inherit (CRRgb *a_this) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR) ; + + return a_this->inherit ; +} + +/** + *Tests if the the rgb is set to the + *value "transparent" or not. + *@param a_this the current instance of + *#CRRgb + *@return TRUE if the rgb has been set to + *transparent, FALSE otherwise. + */ +gboolean +cr_rgb_is_set_to_transparent (CRRgb *a_this) +{ + g_return_val_if_fail (a_this, FALSE) ; + return a_this->is_transparent ; +} + + +/** + *Sets the rgb to the "transparent" value (or not) + *@param a_this the current instance of #CRRgb + *@param a_is_transparent set to transparent or not. + */ +enum CRStatus +cr_rgb_set_to_transparent (CRRgb *a_this, + gboolean a_is_transparent) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR) ; + a_this->is_transparent = a_is_transparent ; + return CR_OK ; +} + +/** + *Sets the rgb from an other one. + *@param a_this the current instance of #CRRgb. + *@param a_rgb the rgb to "copy" + *@return CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_rgb_set_from_rgb (CRRgb * a_this, CRRgb * a_rgb) +{ + g_return_val_if_fail (a_this && a_rgb, CR_BAD_PARAM_ERROR); + + cr_rgb_copy (a_this, a_rgb) ; + + return CR_OK; +} + +enum CRStatus +cr_rgb_set_from_name (CRRgb * a_this, const guchar * a_color_name) +{ + gulong i = 0; + enum CRStatus status = CR_OK; + + g_return_val_if_fail (a_this && a_color_name, CR_BAD_PARAM_ERROR); + + for (i = 0; i < sizeof (gv_standard_colors); i++) { + if (!strcmp (a_color_name, gv_standard_colors[i].name)) { + cr_rgb_set_from_rgb (a_this, &gv_standard_colors[i]); + break; + } + } + + if (i < sizeof (gv_standard_colors)) + status = CR_OK; + else + status = CR_UNKNOWN_TYPE_ERROR; + + return status; +} + +enum CRStatus +cr_rgb_set_from_hex_str (CRRgb * a_this, const guchar * a_hex) +{ + enum CRStatus status = CR_OK; + gulong i = 0; + guchar colors[3] = { 0 }; + + g_return_val_if_fail (a_this && a_hex, CR_BAD_PARAM_ERROR); + + if (strlen (a_hex) == 3) { + for (i = 0; i < 3; i++) { + if (a_hex[i] >= '0' && a_hex[i] <= '9') { + colors[i] = a_hex[i] - '0'; + colors[i] = (colors[i] << 4) | colors[i]; + } else if (a_hex[i] >= 'a' && a_hex[i] <= 'z') { + colors[i] = 10 + a_hex[i] - 'a'; + colors[i] = (colors[i] << 4) | colors[i]; + } else if (a_hex[i] >= 'A' && a_hex[i] <= 'Z') { + colors[i] = 10 + a_hex[i] - 'A'; + colors[i] = (colors[i] << 4) | colors[i]; + } else { + status = CR_UNKNOWN_TYPE_ERROR; + } + } + } else if (strlen (a_hex) == 6) { + for (i = 0; i < 6; i++) { + if (a_hex[i] >= '0' && a_hex[i] <= '9') { + colors[i / 2] <<= 4; + colors[i / 2] |= a_hex[i] - '0'; + status = CR_OK; + } else if (a_hex[i] >= 'a' && a_hex[i] <= 'z') { + colors[i / 2] <<= 4; + colors[i / 2] |= 10 + a_hex[i] - 'a'; + status = CR_OK; + } else if (a_hex[i] >= 'A' && a_hex[i] <= 'Z') { + colors[i / 2] <<= 4; + colors[i / 2] |= 10 + a_hex[i] - 'A'; + status = CR_OK; + } else { + status = CR_UNKNOWN_TYPE_ERROR; + } + } + } else { + status = CR_UNKNOWN_TYPE_ERROR; + } + + if (status == CR_OK) { + status = cr_rgb_set (a_this, colors[0], + colors[1], colors[2], FALSE); + cr_rgb_set_to_transparent (a_this, FALSE) ; + } + return status; +} + +/** + *Set the rgb from a terminal symbol + *@param a_this the instance of #CRRgb to set + *@param a_value the terminal from which to set + */ +enum CRStatus +cr_rgb_set_from_term (CRRgb *a_this, const struct _CRTerm *a_value) +{ + enum CRStatus status = CR_OK ; + g_return_val_if_fail (a_this && a_value, + CR_BAD_PARAM_ERROR) ; + + switch(a_value->type) { + case TERM_RGB: + if (a_value->content.rgb) { + cr_rgb_set_from_rgb + (a_this, a_value->content.rgb) ; + } + break ; + case TERM_IDENT: + if (a_value->content.str + && a_value->content.str->stryng + && a_value->content.str->stryng->str) { + if (!strncmp ("inherit", + a_value->content.str->stryng->str, + sizeof ("inherit")-1)) { + a_this->inherit = TRUE; + a_this->is_transparent = FALSE ; + } else { + status = cr_rgb_set_from_name + (a_this, + a_value->content.str->stryng->str) ; + } + } else { + cr_utils_trace_info + ("a_value has NULL string value") ; + } + break ; + case TERM_HASH: + if (a_value->content.str + && a_value->content.str->stryng + && a_value->content.str->stryng->str) { + status = cr_rgb_set_from_hex_str + (a_this, + a_value->content.str->stryng->str) ; + } else { + cr_utils_trace_info + ("a_value has NULL string value") ; + } + break ; + default: + status = CR_UNKNOWN_TYPE_ERROR ; + } + return status ; +} + +enum CRStatus +cr_rgb_copy (CRRgb *a_dest, CRRgb*a_src) +{ + g_return_val_if_fail (a_dest && a_src, + CR_BAD_PARAM_ERROR) ; + + memcpy (a_dest, a_src, sizeof (CRRgb)) ; + return CR_OK ; +} + +/** + *Destructor of #CRRgb. + *@param a_this the "this pointer" of the + *current instance of #CRRgb. + */ +void +cr_rgb_destroy (CRRgb * a_this) +{ + g_return_if_fail (a_this); + g_free (a_this); +} + +/** + *Parses a text buffer that contains a rgb color + * + *@param a_str a string that contains a color description + *@param a_enc the encoding of a_str + *@return the parsed color, or NULL in case of error + */ +CRRgb *cr_rgb_parse_from_buf (const guchar *a_str, + enum CREncoding a_enc) +{ + enum CRStatus status = CR_OK ; + CRTerm *value = NULL ; + CRParser * parser = NULL; + CRRgb *result = NULL; + + g_return_val_if_fail (a_str, NULL); + + parser = cr_parser_new_from_buf ((guchar*)a_str, strlen (a_str), + a_enc, FALSE) ; + + g_return_val_if_fail (parser, NULL); + + status = cr_parser_try_to_skip_spaces_and_comments (parser) ; + if (status != CR_OK) + goto cleanup; + + status = cr_parser_parse_term (parser, &value); + if (status != CR_OK) + goto cleanup; + + result = cr_rgb_new (); + if (!result) + goto cleanup; + + status = cr_rgb_set_from_term (result, value); + +cleanup: + if (parser) { + cr_parser_destroy (parser); + parser = NULL; + } + if (value) { + cr_term_destroy(value); + value = NULL; + } + return result ; +} + + + diff --git a/src/libcroco/cr-rgb.h b/src/libcroco/cr-rgb.h new file mode 100644 index 000000000..f6b4e8aa1 --- /dev/null +++ b/src/libcroco/cr-rgb.h @@ -0,0 +1,94 @@ +/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * see COPYRIGHTS file for copyright information. + */ + +#ifndef __CR_RGB_H__ +#define __CR_RGB_H__ + +#include +#include +#include "cr-utils.h" +#include "cr-parsing-location.h" + +G_BEGIN_DECLS + + +typedef struct _CRRgb CRRgb ; +struct _CRRgb +{ + /* + *the unit of the rgb. + *Either NO_UNIT (integer) or + *UNIT_PERCENTAGE (percentage). + */ + const guchar *name ; + glong red ; + glong green ; + glong blue ; + gboolean is_percentage ; + gboolean inherit ; + gboolean is_transparent ; + CRParsingLocation location ; +} ; + +CRRgb * cr_rgb_new (void) ; + +CRRgb * cr_rgb_new_with_vals (gulong a_red, gulong a_green, + gulong a_blue, gboolean a_is_percentage) ; + +CRRgb *cr_rgb_parse_from_buf(const guchar *a_str, + enum CREncoding a_enc); + +enum CRStatus cr_rgb_compute_from_percentage (CRRgb *a_this) ; + +enum CRStatus cr_rgb_set (CRRgb *a_this, gulong a_red, + gulong a_green, gulong a_blue, + gboolean a_is_percentage) ; + +enum CRStatus cr_rgb_copy (CRRgb *a_dest, CRRgb*a_src) ; + +enum CRStatus cr_rgb_set_to_inherit (CRRgb *a_this, gboolean a_inherit) ; + +gboolean cr_rgb_is_set_to_inherit (CRRgb *a_this) ; + +gboolean cr_rgb_is_set_to_transparent (CRRgb *a_this) ; + +enum CRStatus cr_rgb_set_to_transparent (CRRgb *a_this, + gboolean a_is_transparent) ; +enum CRStatus cr_rgb_set_from_rgb (CRRgb *a_this, CRRgb *a_rgb) ; + +enum CRStatus cr_rgb_set_from_name (CRRgb *a_this, const guchar *a_color_name) ; + +enum CRStatus cr_rgb_set_from_hex_str (CRRgb *a_this, const guchar * a_hex_value) ; + +struct _CRTerm; + +enum CRStatus cr_rgb_set_from_term (CRRgb *a_this, const struct _CRTerm *a_value); + +guchar * cr_rgb_to_string (CRRgb *a_this) ; + +void cr_rgb_dump (CRRgb *a_this, FILE *a_fp) ; + +void cr_rgb_destroy (CRRgb *a_this) ; + +G_END_DECLS + +#endif /*__CR_RGB_H__*/ diff --git a/src/libcroco/cr-sel-eng.c b/src/libcroco/cr-sel-eng.c new file mode 100644 index 000000000..f010efea0 --- /dev/null +++ b/src/libcroco/cr-sel-eng.c @@ -0,0 +1,1541 @@ +/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser + * General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * See COPYRIGHTS file for copyright informations. + */ + +#include +#include "cr-sel-eng.h" +#include "cr-node-iface.h" + +/** + *@file: + *The definition of the #CRSelEng class. + *The #CRSelEng is actually the "Selection Engine" + *class. This is highly experimental for at the moment and + *its api is very likely to change in a near future. + */ + +#define PRIVATE(a_this) (a_this)->priv + +struct CRPseudoClassSelHandlerEntry { + char *name; + enum CRPseudoType type; + CRPseudoClassSelectorHandler handler; +}; + +struct _CRSelEngPriv { + /*not used yet */ + gboolean case_sensitive; + + CRNodeIface const *node_iface; + CRStyleSheet *sheet; + /** + *where to store the next statement + *to be visited so that we can remember + *it from one method call to another. + */ + CRStatement *cur_stmt; + GList *pcs_handlers; + gint pcs_handlers_size; +} ; + +static gboolean class_add_sel_matches_node (CRAdditionalSel * a_add_sel, + CRNodeIface const * a_node_iface, CRXMLNodePtr a_node); + +static gboolean id_add_sel_matches_node (CRAdditionalSel * a_add_sel, + CRNodeIface const * a_node_iface, CRXMLNodePtr a_node); + +static gboolean attr_add_sel_matches_node (CRAdditionalSel * a_add_sel, + CRNodeIface const * a_node_iface, CRXMLNodePtr a_node); + +static enum CRStatus sel_matches_node_real (CRSelEng * a_this, + CRSimpleSel * a_sel, + CRXMLNodePtr a_node, + gboolean * a_result, + gboolean a_eval_sel_list_from_end, + gboolean a_recurse); + +static enum CRStatus cr_sel_eng_get_matched_rulesets_real (CRSelEng * a_this, + CRStyleSheet * + a_stylesheet, + CRXMLNodePtr a_node, + CRStatement ** + a_rulesets, + gulong * a_len); + +static enum CRStatus put_css_properties_in_props_list (CRPropList ** a_props, + CRStatement * + a_ruleset); + +static gboolean pseudo_class_add_sel_matches_node (CRSelEng * a_this, + CRAdditionalSel * + a_add_sel, + CRXMLNodePtr a_node); + +static gboolean lang_pseudo_class_handler (CRSelEng * a_this, + CRAdditionalSel * a_sel, + CRXMLNodePtr a_node); + +static gboolean first_child_pseudo_class_handler (CRSelEng * a_this, + CRAdditionalSel * a_sel, + CRXMLNodePtr a_node); + +static CRXMLNodePtr get_next_element_node (CRNodeIface const * a_node_iface, CRXMLNodePtr a_node); + +static CRXMLNodePtr get_next_child_element_node (CRNodeIface const * a_node_iface, CRXMLNodePtr a_node); + +static CRXMLNodePtr get_prev_element_node (CRNodeIface const * a_node_iface, CRXMLNodePtr a_node); + +static CRXMLNodePtr get_next_parent_element_node (CRNodeIface const * a_node_iface, CRXMLNodePtr a_node); + +void +cr_sel_eng_set_node_iface (CRSelEng *const a_this, CRNodeIface const *const a_node_iface) +{ + /* Allow NULL: the caller may be just ensuring that the previous node_iface + value doesn't get used until next cr_sel_eng_set_node_iface call. */ + PRIVATE(a_this)->node_iface = a_node_iface; +} + +static gboolean +lang_pseudo_class_handler (CRSelEng *const a_this, + CRAdditionalSel * a_sel, CRXMLNodePtr a_node) +{ + CRNodeIface const *node_iface; + CRXMLNodePtr node = a_node; + gboolean result = FALSE; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && a_sel && a_sel->content.pseudo + && a_sel->content.pseudo + && a_sel->content.pseudo->name + && a_sel->content.pseudo->name->stryng + && a_node, FALSE); + + node_iface = PRIVATE(a_this)->node_iface; + + if (strncmp (a_sel->content.pseudo->name->stryng->str, + "lang", 4) + || !a_sel->content.pseudo->type == FUNCTION_PSEUDO) { + cr_utils_trace_info ("This handler is for :lang only"); + return FALSE; + } + /*lang code should exist and be at least of length 2 */ + if (!a_sel->content.pseudo->extra + || !a_sel->content.pseudo->extra->stryng + || a_sel->content.pseudo->extra->stryng->len < 2) + return FALSE; + for (; node; node = get_next_parent_element_node (node_iface, node)) { + char *val = node_iface->getProp (node, "lang"); + if (val) { + if (!strncmp (val, + a_sel->content.pseudo->extra->stryng->str, + a_sel->content.pseudo->extra->stryng->len)) { + result = TRUE; + break; + } + node_iface->freePropVal (val); + val = NULL; + } + } + + return result; +} + +static gboolean +first_child_pseudo_class_handler (CRSelEng *const a_this, + CRAdditionalSel * a_sel, CRXMLNodePtr const a_node) +{ + CRNodeIface const *node_iface = NULL; + CRXMLNodePtr node = NULL, parent = NULL; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && a_sel && a_sel->content.pseudo + && a_sel->content.pseudo + && a_sel->content.pseudo->name + && a_sel->content.pseudo->name->stryng + && a_node, FALSE); + + if (strcmp (a_sel->content.pseudo->name->stryng->str, + "first-child") + || !a_sel->content.pseudo->type == IDENT_PSEUDO) { + cr_utils_trace_info ("This handler is for :first-child only"); + return FALSE; + } + node_iface = PRIVATE(a_this)->node_iface; + parent = node_iface->getParentNode (a_node); + if (!parent) + return FALSE; + node = get_next_child_element_node (node_iface, parent); + return (node == a_node); +} + +static gboolean +pseudo_class_add_sel_matches_node (CRSelEng * a_this, + CRAdditionalSel * a_add_sel, + CRXMLNodePtr a_node) +{ + enum CRStatus status = CR_OK; + CRPseudoClassSelectorHandler handler = NULL; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && a_add_sel + && a_add_sel->content.pseudo + && a_add_sel->content.pseudo->name + && a_add_sel->content.pseudo->name->stryng + && a_add_sel->content.pseudo->name->stryng->str + && a_node, FALSE); + + status = cr_sel_eng_get_pseudo_class_selector_handler + (a_this, a_add_sel->content.pseudo->name->stryng->str, + a_add_sel->content.pseudo->type, &handler); + if (status != CR_OK || !handler) + return FALSE; + + return handler (a_this, a_add_sel, a_node); +} + +/** + *@param a_add_sel the class additional selector to consider. + *@param a_node the xml node to consider. + *@return TRUE if the class additional selector matches + *the xml node given in argument, FALSE otherwise. + */ +static gboolean +class_add_sel_matches_node (CRAdditionalSel * a_add_sel, + CRNodeIface const * a_node_iface, CRXMLNodePtr a_node) +{ + gboolean result = FALSE; + char *klass = NULL; + + g_return_val_if_fail (a_add_sel + && a_add_sel->type == CLASS_ADD_SELECTOR + && a_add_sel->content.class_name + && a_add_sel->content.class_name->stryng + && a_add_sel->content.class_name->stryng->str + && a_node, FALSE); + + klass = a_node_iface->getProp (a_node, "class"); + if (klass) { + char const *cur; + for (cur = klass; cur && *cur; cur++) { + while (cur && *cur + && cr_utils_is_white_space (*cur) + == TRUE) + cur++; + + if (!strncmp (cur, + a_add_sel->content.class_name->stryng->str, + a_add_sel->content.class_name->stryng->len)) { + cur += a_add_sel->content.class_name->stryng->len; + if ((cur && !*cur) + || cr_utils_is_white_space (*cur) == TRUE) + result = TRUE; + } + if (cur && !*cur) + break ; + } + a_node_iface->freePropVal (klass); + klass = NULL; + } + return result; + +} + +/** + *@return TRUE if the additional attribute selector matches + *the current xml node given in argument, FALSE otherwise. + *@param a_add_sel the additional attribute selector to consider. + *@param a_node the xml node to consider. + */ +static gboolean +id_add_sel_matches_node (CRAdditionalSel * a_add_sel, + CRNodeIface const * a_node_iface, CRXMLNodePtr a_node) +{ + gboolean result = FALSE; + char *id = NULL; + + g_return_val_if_fail (a_add_sel + && a_add_sel->type == ID_ADD_SELECTOR + && a_add_sel->content.id_name + && a_add_sel->content.id_name->stryng + && a_add_sel->content.id_name->stryng->str + && a_node, FALSE); + g_return_val_if_fail (a_add_sel + && a_add_sel->type == ID_ADD_SELECTOR + && a_node, FALSE); + + id = a_node_iface->getProp (a_node, "id"); + if (id) { + if (!strncmp (id, a_add_sel->content.id_name->stryng->str, + a_add_sel->content.id_name->stryng->len)) { + result = TRUE; + } + a_node_iface->freePropVal (id); + id = NULL; + } + return result; +} + +/** + *Returns TRUE if the instance of #CRAdditional selector matches + *the node given in parameter, FALSE otherwise. + *@param a_add_sel the additional selector to evaluate. + *@param a_node the xml node against whitch the selector is to + *be evaluated + *return TRUE if the additional selector matches the current xml node + *FALSE otherwise. + */ +static gboolean +attr_add_sel_matches_node (CRAdditionalSel * a_add_sel, + CRNodeIface const * a_node_iface, CRXMLNodePtr a_node) +{ + CRAttrSel *cur_sel = NULL; + + g_return_val_if_fail (a_add_sel + && a_add_sel->type == ATTRIBUTE_ADD_SELECTOR + && a_node, FALSE); + + for (cur_sel = a_add_sel->content.attr_sel; + cur_sel; cur_sel = cur_sel->next) { + if (!cur_sel->name + || !cur_sel->name->stryng + || !cur_sel->name->stryng->str) + return FALSE; + + char *const value = a_node_iface->getProp (a_node, cur_sel->name->stryng->str); + if (!value) + goto free_and_return_false; + + switch (cur_sel->match_way) { + case SET: + break; + + case EQUALS: + if (!cur_sel->value + || !cur_sel->value->stryng + || !cur_sel->value->stryng->str) { + goto free_and_return_false; + } + if (strcmp + (value, + cur_sel->value->stryng->str)) { + goto free_and_return_false; + } + break; + + case INCLUDES: + { + char const *ptr1 = NULL, + *ptr2 = NULL, + *cur = NULL; + gboolean found = FALSE; + + /* + *here, make sure value is a space + *separated list of "words", where one + *value is exactly cur_sel->value->str + */ + for (cur = value; *cur; cur++) { + /* + *set ptr1 to the first non white space + *char addr. + */ + while (cr_utils_is_white_space (*cur) + && *cur) + cur++; + if (!*cur) + break; + ptr1 = cur; + + /* + *set ptr2 to the end the word. + */ + while (!cr_utils_is_white_space (*cur) + && *cur) + cur++; + cur--; + ptr2 = cur; + + if (!strncmp + (ptr1, + cur_sel->value->stryng->str, + ptr2 - ptr1 + 1)) { + found = TRUE; + break; + } + ptr1 = ptr2 = NULL; + } + + if (!found) { + goto free_and_return_false; + } + } + break; + + case DASHMATCH: + { + char const *ptr1 = NULL, + *ptr2 = NULL, + *cur = NULL; + gboolean found = FALSE; + + /* + *here, make sure value is an hyphen + *separated list of "words", each of which + *starting with "cur_sel->value->str" + */ + for (cur = value; *cur; cur++) { + if (*cur == '-') + cur++; + ptr1 = cur; + + while (*cur != '-' && *cur) + cur++; + cur--; + ptr2 = cur; + + if (g_strstr_len + (ptr1, ptr2 - ptr1 + 1, + cur_sel->value->stryng->str) + == ptr1) { + found = TRUE; + break; + } + } + + if (!found) { + goto free_and_return_false; + } + } + break; + default: + goto free_and_return_false; + } + + a_node_iface->freePropVal (value); + continue; + + free_and_return_false: + a_node_iface->freePropVal (value); + return FALSE; + } + + return TRUE; +} + +/** + *Evaluates if a given additional selector matches an xml node. + *@param a_add_sel the additional selector to consider. + *@param a_node the xml node to consider. + *@return TRUE is a_add_sel matches a_node, FALSE otherwise. + */ +static gboolean +additional_selector_matches_node (CRSelEng * a_this, + CRAdditionalSel * a_add_sel, + CRXMLNodePtr a_node) +{ + CRAdditionalSel *cur_add_sel = NULL, *tail = NULL ; + gboolean evaluated = FALSE ; + + for (tail = a_add_sel ; + tail && tail->next; + tail = tail->next) ; + + g_return_val_if_fail (tail, FALSE) ; + + for (cur_add_sel = tail ; + cur_add_sel ; + cur_add_sel = cur_add_sel->prev) { + + evaluated = TRUE ; + if (cur_add_sel->type == NO_ADD_SELECTOR) { + return FALSE; + } + + if (cur_add_sel->type == CLASS_ADD_SELECTOR + && cur_add_sel->content.class_name + && cur_add_sel->content.class_name->stryng + && cur_add_sel->content.class_name->stryng->str) { + if (!class_add_sel_matches_node (cur_add_sel, + PRIVATE(a_this)->node_iface, + a_node)) { + return FALSE; + } + continue ; + } else if (cur_add_sel->type == ID_ADD_SELECTOR + && cur_add_sel->content.id_name + && cur_add_sel->content.id_name->stryng + && cur_add_sel->content.id_name->stryng->str) { + if (!id_add_sel_matches_node (cur_add_sel, + PRIVATE(a_this)->node_iface, + a_node)) { + return FALSE; + } + continue ; + } else if (cur_add_sel->type == ATTRIBUTE_ADD_SELECTOR + && cur_add_sel->content.attr_sel) { + /* + *here, call a function that does the match + *against an attribute additionnal selector + *and an xml node. + */ + if (!attr_add_sel_matches_node (cur_add_sel, + PRIVATE(a_this)->node_iface, + a_node)) { + return FALSE; + } + continue ; + } else if (cur_add_sel->type == PSEUDO_CLASS_ADD_SELECTOR + && cur_add_sel->content.pseudo) { + if (pseudo_class_add_sel_matches_node + (a_this, cur_add_sel, a_node)) { + return TRUE; + } + return FALSE; + } + } + if (evaluated == TRUE) + return TRUE; + return FALSE ; +} + +static CRXMLNodePtr +get_next_element_node (CRNodeIface const * a_node_iface, CRXMLNodePtr a_node) +{ + CRXMLNodePtr cur_node = a_node; + + g_return_val_if_fail (a_node, NULL); + + do { + cur_node = a_node_iface->getNextSibling (cur_node); + } while (cur_node && !a_node_iface->isElementNode(cur_node)); + return cur_node; +} + +/* TODO: Consider renaming this to get_first_child_element_node. + (cf get_first_parent_element_node, which does getParent until element node + rather than getNextSibling). */ +static CRXMLNodePtr +get_next_child_element_node (CRNodeIface const * a_node_iface, CRXMLNodePtr a_node) +{ + CRXMLNodePtr cur_node = NULL; + + g_return_val_if_fail (a_node, NULL); + + cur_node = a_node_iface->getFirstChild (a_node); + if (!cur_node) + return cur_node; + if (a_node_iface->isElementNode (cur_node)) + return cur_node; + return get_next_element_node (a_node_iface, cur_node); +} + +static CRXMLNodePtr +get_prev_element_node (CRNodeIface const * a_node_iface, CRXMLNodePtr a_node) +{ + CRXMLNodePtr cur_node = a_node; + + g_return_val_if_fail (a_node, NULL); + + do { + cur_node = a_node_iface->getPrevSibling (cur_node); + } while (cur_node && !a_node_iface->isElementNode(cur_node)); + return cur_node; +} + +static CRXMLNodePtr +get_next_parent_element_node (CRNodeIface const * a_node_iface, CRXMLNodePtr a_node) +{ + CRXMLNodePtr cur_node = a_node; + + g_return_val_if_fail (a_node, NULL); + + do { + cur_node = a_node_iface->getParentNode (cur_node); + } while (cur_node && !a_node_iface->isElementNode (cur_node)); + return cur_node; +} + +/** + *Evaluate a selector (a simple selectors list) and says + *if it matches the xml node given in parameter. + *The algorithm used here is the following: + *Walk the combinator separated list of simple selectors backward, starting + *from the end of the list. For each simple selector, looks if + *if matches the current node. + * + *@param a_this the selection engine. + *@param a_sel the simple selection list. + *@param a_node the xml node. + *@param a_result out parameter. Set to true if the + *selector matches the xml node, FALSE otherwise. + *@param a_recurse if set to TRUE, the function will walk to + *the next simple selector (after the evaluation of the current one) + *and recursively evaluate it. Must be usually set to TRUE unless you + *know what you are doing. + */ +static enum CRStatus +sel_matches_node_real (CRSelEng * a_this, CRSimpleSel * a_sel, + CRXMLNodePtr a_node, gboolean * a_result, + gboolean a_eval_sel_list_from_end, + gboolean a_recurse) +{ + CRSimpleSel *cur_sel = NULL; + CRXMLNodePtr cur_node = NULL; + CRNodeIface const *node_iface = NULL; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && a_this && a_node + && a_result, CR_BAD_PARAM_ERROR); + + node_iface = PRIVATE(a_this)->node_iface; + *a_result = FALSE; + + if (!node_iface->isElementNode(a_node)) + return CR_OK; + + if (a_eval_sel_list_from_end == TRUE) { + /*go and get the last simple selector of the list */ + for (cur_sel = a_sel; + cur_sel && cur_sel->next; cur_sel = cur_sel->next) ; + } else { + cur_sel = a_sel; + } + + for (cur_node = a_node; cur_sel; cur_sel = cur_sel->prev) { + if (((cur_sel->type_mask & TYPE_SELECTOR) + && (cur_sel->name + && cur_sel->name->stryng + && cur_sel->name->stryng->str) + && (!strcmp (cur_sel->name->stryng->str, + node_iface->getLocalName(cur_node)))) + || (cur_sel->type_mask & UNIVERSAL_SELECTOR)) { + /* + *this simple selector + *matches the current xml node + *Let's see if the preceding + *simple selectors also match + *their xml node counterpart. + */ + if (cur_sel->add_sel) { + if (additional_selector_matches_node (a_this, cur_sel->add_sel, + cur_node) == TRUE) { + goto walk_a_step_in_expr; + } else { + goto done; + } + } else { + goto walk_a_step_in_expr; + } + } + if (!(cur_sel->type_mask & TYPE_SELECTOR) + && !(cur_sel->type_mask & UNIVERSAL_SELECTOR)) { + if (!cur_sel->add_sel) { + goto done; + } + if (additional_selector_matches_node + (a_this, cur_sel->add_sel, cur_node) + == TRUE) { + goto walk_a_step_in_expr; + } else { + goto done; + } + } else { + goto done ; + } + + walk_a_step_in_expr: + if (a_recurse == FALSE) { + *a_result = TRUE; + goto done; + } + + /* + *here, depending on the combinator of cur_sel + *choose the axis of the xml tree traversal + *and walk one step in the xml tree. + */ + if (!cur_sel->prev) + break; + + switch (cur_sel->combinator) { + case NO_COMBINATOR: + break; + + case COMB_WS: /*descendant selector */ + { + CRXMLNodePtr n = NULL; + enum CRStatus status = CR_OK; + gboolean matches = FALSE; + + /* + *walk the xml tree upward looking for a parent + *node that matches the preceding selector. + */ + for (n = node_iface->getParentNode (cur_node); + n; + n = node_iface->getParentNode (n)) { + status = sel_matches_node_real + (a_this, cur_sel->prev, + n, &matches, FALSE, TRUE); + + if (status != CR_OK) + goto done; + + if (matches == TRUE) { + cur_node = n ; + break; + } + } + + if (!n) { + /* + *didn't find any ancestor that matches + *the previous simple selector. + */ + goto done; + } + /* + *in this case, the preceding simple sel + *will have been interpreted twice, which + *is a cpu and mem waste ... I need to find + *another way to do this. Anyway, this is + *my first attempt to write this function and + *I am a bit clueless. + */ + break; + } + + case COMB_PLUS: + cur_node = get_prev_element_node (node_iface, cur_node); + if (!cur_node) + goto done; + break; + + case COMB_GT: + cur_node = get_next_parent_element_node (node_iface, cur_node); + if (!cur_node) + goto done; + break; + + default: + goto done; + } + continue; + } + + /* + *if we reached this point, it means the selector matches + *the xml node. + */ + *a_result = TRUE; + + done: + return CR_OK; +} + + +/** + *Returns array of the ruleset statements that matches the + *given xml node. + *The engine keeps in memory the last statement he + *visited during the match. So, the next call + *to this function will eventually return a rulesets list starting + *from the last ruleset statement visited during the previous call. + *The enable users to get matching rulesets in an incremental way. + *Note that for each statement returned, + *the engine calculates the specificity of the selector + *that matched the xml node and stores it in the "specifity" field + *of the statement structure. + * + *@param a_sel_eng the current selection engine + *@param a_node the xml node for which the request + *is being made. + *@param a_sel_list the list of selectors to perform the search in. + *@param a_rulesets in/out parameter. A pointer to the + *returned array of rulesets statements that match the xml node + *given in parameter. The caller allocates the array before calling this + *function. + *@param a_len in/out parameter the length (in sizeof (#CRStatement*)) + *of the returned array. + *(the length of a_rulesets, more precisely). + *The caller must set it to the length of a_ruleset prior to calling this + *function. In return, the function sets it to the length + *(in sizeof (#CRStatement)) of the actually returned CRStatement array. + *@return CR_OUTPUT_TOO_SHORT_ERROR if found more rulesets than the size + *of the a_rulesets array. In this case, the first *a_len rulesets found + *are put in a_rulesets, and a further call will return the following + *ruleset(s) following the same principle. + *@return CR_OK if all the rulesets found have been returned. In this + *case, *a_len is set to the actual number of ruleset found. + *@return CR_BAD_PARAM_ERROR in case any of the given parameter are + *bad (e.g null pointer). + *@return CR_ERROR if any other error occured. + */ +static enum CRStatus +cr_sel_eng_get_matched_rulesets_real (CRSelEng * a_this, + CRStyleSheet * a_stylesheet, + CRXMLNodePtr a_node, + CRStatement ** a_rulesets, + gulong * a_len) +{ + CRStatement *cur_stmt = NULL; + CRSelector *sel_list = NULL, + *cur_sel = NULL; + gboolean matches = FALSE; + enum CRStatus status = CR_OK; + gulong i = 0; + + g_return_val_if_fail (a_this + && a_stylesheet + && a_node && a_rulesets, CR_BAD_PARAM_ERROR); + + if (!a_stylesheet->statements) { + *a_rulesets = NULL; + *a_len = 0; + return CR_OK; + } + + /* + *if this stylesheet is "new one" + *let's remember it for subsequent calls. + */ + if (PRIVATE (a_this)->sheet != a_stylesheet) { + PRIVATE (a_this)->sheet = a_stylesheet; + PRIVATE (a_this)->cur_stmt = a_stylesheet->statements; + } + + /* + *walk through the list of statements and, + *get the selectors list inside the statements that + *contain some, and try to match our xml node in these + *selectors lists. + */ + for (cur_stmt = PRIVATE (a_this)->cur_stmt, i = 0; + (PRIVATE (a_this)->cur_stmt = cur_stmt); + cur_stmt = cur_stmt->next) { + /* + *initialyze the selector list in which we will + *really perform the search. + */ + sel_list = NULL; + + /* + *get the the damn selector list in + *which we have to look + */ + switch (cur_stmt->type) { + case RULESET_STMT: + if (cur_stmt->kind.ruleset + && cur_stmt->kind.ruleset->sel_list) { + sel_list = cur_stmt->kind.ruleset->sel_list; + } + break; + + case AT_MEDIA_RULE_STMT: + if (cur_stmt->kind.media_rule + && cur_stmt->kind.media_rule->rulesets + && cur_stmt->kind.media_rule->rulesets-> + kind.ruleset + && cur_stmt->kind.media_rule->rulesets-> + kind.ruleset->sel_list) { + sel_list = + cur_stmt->kind.media_rule-> + rulesets->kind.ruleset->sel_list; + } + break; + + case AT_IMPORT_RULE_STMT: + /* + *some recursivity may be needed here. + *I don't like this :( + */ + break; + default: + break; + } + + if (!sel_list) + continue; + + /* + *now, we have a comma separated selector list to look in. + *let's walk it and try to match the xml_node + *on each item of the list. + */ + for (cur_sel = sel_list; cur_sel; cur_sel = cur_sel->next) { + if (!cur_sel->simple_sel) + continue; + + status = cr_sel_eng_matches_node + (a_this, cur_sel->simple_sel, + a_node, &matches); + + if (status == CR_OK && matches == TRUE) { + /* + *bingo!!! we found one ruleset that + *matches that fucking node. + *lets put it in the out array. + */ + + if (i < *a_len) { + a_rulesets[i] = cur_stmt; + i++; + + /* + *For the cascade computing algorithm + *(which is gonna take place later) + *we must compute the specificity + *(css2 spec chap 6.4.1) of the selector + *that matched the current xml node + *and store it in the css2 statement + *(statement == ruleset here). + */ + status = cr_simple_sel_compute_specificity (cur_sel->simple_sel); + + g_return_val_if_fail (status == CR_OK, + CR_ERROR); + cur_stmt->specificity = + cur_sel->simple_sel-> + specificity; + } else + { + *a_len = i; + return CR_OUTPUT_TOO_SHORT_ERROR; + } + } + } + } + + /* + *if we reached this point, it means + *we reached the end of stylesheet. + *no need to store any info about the stylesheet + *anymore. + */ + g_return_val_if_fail (!PRIVATE (a_this)->cur_stmt, CR_ERROR); + PRIVATE (a_this)->sheet = NULL; + *a_len = i; + return CR_OK; +} + +static enum CRStatus +put_css_properties_in_props_list (CRPropList ** a_props, CRStatement * a_stmt) +{ + CRPropList *props = NULL, + *pair = NULL, + *tmp_props = NULL; + CRDeclaration *cur_decl = NULL; + + g_return_val_if_fail (a_props && a_stmt + && a_stmt->type == RULESET_STMT + && a_stmt->kind.ruleset, CR_BAD_PARAM_ERROR); + + props = *a_props; + + for (cur_decl = a_stmt->kind.ruleset->decl_list; + cur_decl; cur_decl = cur_decl->next) { + CRDeclaration *decl; + + decl = NULL; + pair = NULL; + + if (!cur_decl->property + || !cur_decl->property->stryng + || !cur_decl->property->stryng->str) + continue; + /* + *First, test if the property is not + *already present in our properties list + *If yes, apply the cascading rules to + *compute the precedence. If not, insert + *the property into the list + */ + cr_prop_list_lookup_prop (props, + cur_decl->property, + &pair); + + if (!pair) { + tmp_props = cr_prop_list_append2 + (props, cur_decl->property, cur_decl); + if (tmp_props) { + props = tmp_props; + tmp_props = NULL; + } + continue; + } + + /* + *A property with the same name already exists. + *We must apply here + *some cascading rules + *to compute the precedence. + */ + cr_prop_list_get_decl (pair, &decl); + g_return_val_if_fail (decl, CR_ERROR); + + /* + *first, look at the origin. + *6.4.1 says: + *"for normal declarations, + *author style sheets override user + *style sheets which override + *the default style sheet." + */ + if (decl->parent_statement + && decl->parent_statement->parent_sheet + && (decl->parent_statement->parent_sheet->origin + < a_stmt->parent_sheet->origin)) { + /* + *if the already selected declaration + *is marked as being !important the current + *declaration must not overide it + *(unless the already selected declaration + *has an UA origin) + */ + if (decl->important == TRUE + && decl->parent_statement->parent_sheet->origin + != ORIGIN_UA) { + continue; + } + tmp_props = cr_prop_list_unlink (props, pair); + if (props) { + cr_prop_list_destroy (pair); + } + props = tmp_props; + tmp_props = NULL; + props = cr_prop_list_append2 + (props, cur_decl->property, cur_decl); + + continue; + } else if (decl->parent_statement + && decl->parent_statement->parent_sheet + && (decl->parent_statement-> + parent_sheet->origin + > a_stmt->parent_sheet->origin)) { + cr_utils_trace_info + ("We should not reach this line\n"); + continue; + } + + /* + *A property with the same + *name and the same origin already exists. + *shit. This is lasting longer than expected ... + *Luckily, the spec says in 6.4.1: + *"more specific selectors will override + *more general ones" + *and + *"if two rules have the same weight, + *origin and specificity, + *the later specified wins" + */ + if (a_stmt->specificity + >= decl->parent_statement->specificity) { + if (decl->important == TRUE) + continue; + props = cr_prop_list_unlink (props, pair); + if (pair) { + cr_prop_list_destroy (pair); + pair = NULL; + } + props = cr_prop_list_append2 (props, + cur_decl->property, + cur_decl); + } + } + /*TODO: this may leak. Check this out */ + *a_props = props; + + return CR_OK; +} + +static void +set_style_from_props (CRStyle * a_style, CRPropList * a_props) +{ + CRPropList *cur = NULL; + CRDeclaration *decl = NULL; + + for (cur = a_props; cur; cur = cr_prop_list_get_next (cur)) { + cr_prop_list_get_decl (cur, &decl); + cr_style_set_style_from_decl (a_style, decl); + decl = NULL; + } +} + +/**************************************** + *PUBLIC METHODS + ****************************************/ + +/** + *Creates a new instance of #CRSelEng. + *@return the newly built instance of #CRSelEng of + *NULL if an error occurs. + */ +CRSelEng * +cr_sel_eng_new (void) +{ + CRSelEng *result = NULL; + + result = (CRSelEng *) g_try_malloc (sizeof (CRSelEng)); + if (!result) { + cr_utils_trace_info ("Out of memory"); + return NULL; + } + memset (result, 0, sizeof (CRSelEng)); + + PRIVATE (result) = (CRSelEngPriv *) g_try_malloc (sizeof (CRSelEngPriv)); + if (!PRIVATE (result)) { + cr_utils_trace_info ("Out of memory"); + g_free (result); + return NULL; + } + memset (PRIVATE (result), 0, sizeof (CRSelEngPriv)); + cr_sel_eng_register_pseudo_class_sel_handler + (result, "first-child", + IDENT_PSEUDO, /*(CRPseudoClassSelectorHandler)*/ + first_child_pseudo_class_handler); + cr_sel_eng_register_pseudo_class_sel_handler + (result, "lang", + FUNCTION_PSEUDO, /*(CRPseudoClassSelectorHandler)*/ + lang_pseudo_class_handler); + + return result; +} + +/** + *Adds a new handler entry in the handlers entry table. + *@param a_this the current instance of #CRSelEng + *@param a_pseudo_class_sel_name the name of the pseudo class selector. + *@param a_pseudo_class_type the type of the pseudo class selector. + *@param a_handler the actual handler or callback to be called during + *the selector evaluation process. + *@return CR_OK, upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_sel_eng_register_pseudo_class_sel_handler (CRSelEng * a_this, + char * a_name, + enum CRPseudoType a_type, + CRPseudoClassSelectorHandler + a_handler) +{ + struct CRPseudoClassSelHandlerEntry *handler_entry = NULL; + GList *list = NULL; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && a_handler && a_name, CR_BAD_PARAM_ERROR); + + handler_entry = (struct CRPseudoClassSelHandlerEntry *) g_try_malloc + (sizeof (struct CRPseudoClassSelHandlerEntry)); + if (!handler_entry) { + return CR_OUT_OF_MEMORY_ERROR; + } + memset (handler_entry, 0, + sizeof (struct CRPseudoClassSelHandlerEntry)); + handler_entry->name = g_strdup (a_name); + handler_entry->type = a_type; + handler_entry->handler = a_handler; + list = g_list_append (PRIVATE (a_this)->pcs_handlers, handler_entry); + if (!list) { + return CR_OUT_OF_MEMORY_ERROR; + } + PRIVATE (a_this)->pcs_handlers = list; + return CR_OK; +} + +enum CRStatus +cr_sel_eng_unregister_pseudo_class_sel_handler (CRSelEng * a_this, + char * a_name, + enum CRPseudoType a_type) +{ + GList *elem = NULL, + *deleted_elem = NULL; + gboolean found = FALSE; + struct CRPseudoClassSelHandlerEntry *entry = NULL; + + g_return_val_if_fail (a_this && PRIVATE (a_this), CR_BAD_PARAM_ERROR); + + for (elem = PRIVATE (a_this)->pcs_handlers; + elem; elem = g_list_next (elem)) { + entry = (struct CRPseudoClassSelHandlerEntry *) elem->data; + if (!strcmp (entry->name, a_name) + && entry->type == a_type) { + found = TRUE; + break; + } + } + if (found == FALSE) + return CR_PSEUDO_CLASS_SEL_HANDLER_NOT_FOUND_ERROR; + PRIVATE (a_this)->pcs_handlers = g_list_delete_link + (PRIVATE (a_this)->pcs_handlers, elem); + entry = (struct CRPseudoClassSelHandlerEntry *) elem->data; + if (entry->name) { + g_free (entry->name); + entry->name = NULL; + } + g_free (elem); + g_list_free (deleted_elem); + + return CR_OK; +} + +/** + *Unregisters all the pseudo class sel handlers + *and frees all the associated allocated datastructures. + *@param a_this the current instance of #CRSelEng . + *@return CR_OK upon succesful completion, an error code + *otherwise. + */ +enum CRStatus +cr_sel_eng_unregister_all_pseudo_class_sel_handlers (CRSelEng * a_this) +{ + GList *elem = NULL; + struct CRPseudoClassSelHandlerEntry *entry = NULL; + + g_return_val_if_fail (a_this && PRIVATE (a_this), CR_BAD_PARAM_ERROR); + + if (!PRIVATE (a_this)->pcs_handlers) + return CR_OK; + for (elem = PRIVATE (a_this)->pcs_handlers; + elem; elem = g_list_next (elem)) { + entry = (struct CRPseudoClassSelHandlerEntry *) elem->data; + if (!entry) + continue; + if (entry->name) { + g_free (entry->name); + entry->name = NULL; + } + g_free (entry); + elem->data = NULL; + } + g_list_free (PRIVATE (a_this)->pcs_handlers); + PRIVATE (a_this)->pcs_handlers = NULL; + return CR_OK; +} + +enum CRStatus +cr_sel_eng_get_pseudo_class_selector_handler (CRSelEng * a_this, + char * a_name, + enum CRPseudoType a_type, + CRPseudoClassSelectorHandler * + a_handler) +{ + GList *elem = NULL; + struct CRPseudoClassSelHandlerEntry *entry = NULL; + gboolean found = FALSE; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && a_name, CR_BAD_PARAM_ERROR); + + for (elem = PRIVATE (a_this)->pcs_handlers; + elem; elem = g_list_next (elem)) { + entry = (struct CRPseudoClassSelHandlerEntry *) elem->data; + if (!strcmp (a_name, entry->name) + && entry->type == a_type) { + found = TRUE; + break; + } + } + + if (found == FALSE) + return CR_PSEUDO_CLASS_SEL_HANDLER_NOT_FOUND_ERROR; + *a_handler = entry->handler; + return CR_OK; +} + +/** + *Evaluates a chained list of simple selectors (known as a css2 selector). + *Says wheter if this selector matches the xml node given in parameter or + *not. + *@param a_this the selection engine. + *@param a_sel the simple selector against which the xml node + *is going to be matched. + *@param a_node the node against which the selector is going to be matched. + *@param a_result out parameter. The result of the match. Is set to + *TRUE if the selector matches the node, FALSE otherwise. This value + *is considered if and only if this functions returns CR_OK. + *@return the CR_OK if the selection ran correctly, an error code otherwise. + */ +enum CRStatus +cr_sel_eng_matches_node (CRSelEng * a_this, CRSimpleSel * a_sel, + CRXMLNodePtr a_node, gboolean * a_result) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this) + && a_this && a_node + && a_result, CR_BAD_PARAM_ERROR); + + if (!PRIVATE(a_this)->node_iface->isElementNode (a_node)) { + *a_result = FALSE; + return CR_OK; + } + + return sel_matches_node_real (a_this, a_sel, + a_node, a_result, + TRUE, TRUE); +} + +/** + *Returns an array of pointers to selectors that matches + *the xml node given in parameter. + * + *@param a_this the current instance of the selection engine. + *@param a_sheet the stylesheet that holds the selectors. + *@param a_node the xml node to consider during the walk thru + *the stylesheet. + *@param a_rulesets out parameter. A pointer to an array of + *rulesets statement pointers. *a_rulesets is allocated by + *this function and must be freed by the caller. However, the caller + *must not alter the rulesets statements pointer because they + *point to statements that are still in the css stylesheet. + *@param a_len the length of *a_ruleset. + *@return CR_OK upon sucessfull completion, an error code otherwise. + */ +enum CRStatus +cr_sel_eng_get_matched_rulesets (CRSelEng * a_this, + CRStyleSheet * a_sheet, + CRXMLNodePtr a_node, + CRStatement *** a_rulesets, gulong * a_len) +{ + CRStatement **stmts_tab = NULL; + enum CRStatus status = CR_OK; + gulong tab_size = 0, + tab_len = 0, + index = 0; + gushort stmts_chunck_size = 8; + + g_return_val_if_fail (a_this + && a_sheet + && a_node + && a_rulesets && *a_rulesets == NULL + && a_len, CR_BAD_PARAM_ERROR); + + stmts_tab = (CRStatement **) g_try_malloc (stmts_chunck_size * sizeof (CRStatement *)); + + if (!stmts_tab) { + cr_utils_trace_info ("Out of memory"); + status = CR_ERROR; + goto error; + } + memset (stmts_tab, 0, stmts_chunck_size * sizeof (CRStatement *)); + + tab_size = stmts_chunck_size; + tab_len = tab_size; + + while ((status = cr_sel_eng_get_matched_rulesets_real + (a_this, a_sheet, a_node, stmts_tab + index, &tab_len)) + == CR_OUTPUT_TOO_SHORT_ERROR) { + stmts_tab = (CRStatement **) g_try_realloc (stmts_tab, + (tab_size + stmts_chunck_size) + * sizeof (CRStatement *)); + if (!stmts_tab) { + cr_utils_trace_info ("Out of memory"); + status = CR_ERROR; + goto error; + } + tab_size += stmts_chunck_size; + index += tab_len; + tab_len = tab_size - index; + } + + tab_len = tab_size - stmts_chunck_size + tab_len; + *a_rulesets = stmts_tab; + *a_len = tab_len; + + return CR_OK; + + error: + + if (stmts_tab) { + g_free (stmts_tab); + stmts_tab = NULL; + + } + + *a_len = 0; + return status; +} + + +enum CRStatus +cr_sel_eng_get_matched_properties_from_cascade (CRSelEng * a_this, + CRCascade * a_cascade, + CRXMLNodePtr a_node, + CRPropList ** a_props) +{ + CRStatement **stmts_tab = NULL; + enum CRStatus status = CR_OK; + gulong tab_size = 0, + tab_len = 0, + i = 0, + index = 0; + enum CRStyleOrigin origin; + gushort stmts_chunck_size = 8; + CRStyleSheet *sheet = NULL; + + g_return_val_if_fail (a_this + && a_cascade + && a_node && a_props, CR_BAD_PARAM_ERROR); + + for (origin = ORIGIN_UA; origin < NB_ORIGINS; origin = (enum CRStyleOrigin) (origin + 1)) { + sheet = cr_cascade_get_sheet (a_cascade, origin); + if (!sheet) + continue; + if (tab_size - index < 1) { + stmts_tab = (CRStatement **) g_try_realloc + (stmts_tab, (tab_size + stmts_chunck_size) + * sizeof (CRStatement *)); + if (!stmts_tab) { + cr_utils_trace_info ("Out of memory"); + status = CR_ERROR; + goto cleanup; + } + tab_size += stmts_chunck_size; + /* + *compute the max size left for + *cr_sel_eng_get_matched_rulesets_real()'s output tab + */ + tab_len = tab_size - index; + } + while ((status = cr_sel_eng_get_matched_rulesets_real + (a_this, sheet, a_node, stmts_tab + index, &tab_len)) + == CR_OUTPUT_TOO_SHORT_ERROR) { + stmts_tab = (CRStatement **) g_try_realloc + (stmts_tab, (tab_size + stmts_chunck_size) + * sizeof (CRStatement *)); + if (!stmts_tab) { + cr_utils_trace_info ("Out of memory"); + status = CR_ERROR; + goto cleanup; + } + tab_size += stmts_chunck_size; + index += tab_len; + /* + *compute the max size left for + *cr_sel_eng_get_matched_rulesets_real()'s output tab + */ + tab_len = tab_size - index; + } + if (status != CR_OK) { + cr_utils_trace_info ("Error while running " + "selector engine"); + goto cleanup; + } + index += tab_len; + tab_len = tab_size - index; + } + + /* + *TODO, walk down the stmts_tab and build the + *property_name/declaration hashtable. + *Make sure one can walk from the declaration to + *the stylesheet. + */ + for (i = 0; i < index; i++) { + CRStatement *stmt = stmts_tab[i]; + + if (!stmt) + continue; + switch (stmt->type) { + case RULESET_STMT: + if (!stmt->parent_sheet) + continue; + status = put_css_properties_in_props_list + (a_props, stmt); + break; + default: + break; + } + + } + status = CR_OK ; + cleanup: + if (stmts_tab) { + g_free (stmts_tab); + stmts_tab = NULL; + } + + return status; +} + +enum CRStatus +cr_sel_eng_get_matched_style (CRSelEng * a_this, + CRCascade * a_cascade, + CRXMLNodePtr a_node, + CRStyle * a_parent_style, + CRStyle ** a_style, + gboolean a_set_props_to_initial_values) +{ + enum CRStatus status = CR_OK; + + CRPropList *props = NULL; + + g_return_val_if_fail (a_this && a_cascade + && a_node && a_style, CR_BAD_PARAM_ERROR); + + status = cr_sel_eng_get_matched_properties_from_cascade + (a_this, a_cascade, a_node, &props); + + g_return_val_if_fail (status == CR_OK, status); + if (props) { + if (!*a_style) { + *a_style = cr_style_new (a_set_props_to_initial_values) ; + g_return_val_if_fail (*a_style, CR_ERROR); + } else { + if (a_set_props_to_initial_values == TRUE) { + cr_style_set_props_to_initial_values (*a_style) ; + } else { + cr_style_set_props_to_default_values (*a_style); + } + } + (*a_style)->parent_style = a_parent_style; + + set_style_from_props (*a_style, props); + if (props) { + cr_prop_list_destroy (props); + props = NULL; + } + } + return CR_OK; +} + +/** + *The destructor of #CRSelEng + *@param a_this the current instance of the selection engine. + */ +void +cr_sel_eng_destroy (CRSelEng * a_this) +{ + g_return_if_fail (a_this); + + if (!PRIVATE (a_this)) + goto end ; + if (PRIVATE (a_this)->pcs_handlers) { + cr_sel_eng_unregister_all_pseudo_class_sel_handlers + (a_this) ; + PRIVATE (a_this)->pcs_handlers = NULL ; + } + g_free (PRIVATE (a_this)); + PRIVATE (a_this) = NULL; + end: + if (a_this) { + g_free (a_this); + } +} diff --git a/src/libcroco/cr-sel-eng.h b/src/libcroco/cr-sel-eng.h new file mode 100644 index 000000000..af6c84398 --- /dev/null +++ b/src/libcroco/cr-sel-eng.h @@ -0,0 +1,112 @@ +/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * Author: Dodji Seketeli + * See COPYRIGHTS file for copyrights information. + */ + +#ifndef __CR_SEL_ENG_H__ +#define __CR_SEL_ENG_H__ + +#include "cr-utils.h" +#include "cr-stylesheet.h" +#include "cr-cascade.h" +#include "cr-style.h" +#include "cr-prop-list.h" +#include "cr-node-iface.h" + + + +/** + *@file: + *The declaration of the #CRSelEng class. + *The #CRSelEng is actually the "Selection Engine" + *class. + */ + +G_BEGIN_DECLS + +typedef struct _CRSelEng CRSelEng ; +typedef struct _CRSelEngPriv CRSelEngPriv ; + +/** + *The Selection engine class. + *The main service provided by this class, is + *the ability to interpret a libcroco implementation + *of css2 selectors, and given an xml node, say if + *the selector matches the node or not. + */ +struct _CRSelEng +{ + CRSelEngPriv *priv ; +} ; + +void cr_sel_eng_set_node_iface(CRSelEng *a_this, CRNodeIface const *); + +typedef gboolean (*CRPseudoClassSelectorHandler) (CRSelEng* a_this, + CRAdditionalSel *a_add_sel, + CRXMLNodePtr a_node) ; +CRSelEng * cr_sel_eng_new (void) ; + +enum CRStatus cr_sel_eng_register_pseudo_class_sel_handler (CRSelEng *a_this, + char *a_pseudo_class_sel_name, + enum CRPseudoType a_pseudo_class_type, + CRPseudoClassSelectorHandler a_handler) ; + +enum CRStatus cr_sel_eng_unregister_pseudo_class_sel_handler (CRSelEng *a_this, + char *a_pseudo_class_sel_name, + enum CRPseudoType a_pseudo_class_type) ; + +enum CRStatus cr_sel_eng_unregister_all_pseudo_class_sel_handlers (CRSelEng *a_this) ; + +enum CRStatus cr_sel_eng_get_pseudo_class_selector_handler (CRSelEng *a_this, + char *a_pseudo_class_sel_name, + enum CRPseudoType a_pseudo_class_type, + CRPseudoClassSelectorHandler *a_handler) ; + +enum CRStatus cr_sel_eng_matches_node (CRSelEng *a_this, + CRSimpleSel *a_sel, + CRXMLNodePtr a_node, + gboolean *a_result) ; + +enum CRStatus cr_sel_eng_get_matched_rulesets (CRSelEng *a_this, + CRStyleSheet *a_sheet, + CRXMLNodePtr a_node, + CRStatement ***a_rulesets, + gulong *a_len) ; + +enum CRStatus +cr_sel_eng_get_matched_properties_from_cascade (CRSelEng *a_this, + CRCascade *a_cascade, + CRXMLNodePtr a_node, + CRPropList **a_props) ; + +enum CRStatus cr_sel_eng_get_matched_style (CRSelEng *a_this, + CRCascade *a_cascade, + CRXMLNodePtr a_node, + CRStyle *a_parent_style, + CRStyle **a_style, + gboolean a_set_props_to_initial_values) ; + +void cr_sel_eng_destroy (CRSelEng *a_this) ; + +G_END_DECLS + + +#endif/*__CR_SEL_ENG_H__*/ diff --git a/src/libcroco/cr-selector.c b/src/libcroco/cr-selector.c new file mode 100644 index 000000000..5f7316a00 --- /dev/null +++ b/src/libcroco/cr-selector.c @@ -0,0 +1,277 @@ +/* -*- Mode: C; indent-tabs-mode: ni; c-basic-offset: 8 -*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * See COPYRIGHTS file for copyright information. + */ + +#include +#include "cr-selector.h" +#include "cr-parser.h" + +/** + *Creates a new instance of #CRSelector. + *@param a_simple_sel the initial simple selector list + *of the current instance of #CRSelector. + *@return the newly built instance of #CRSelector, or + *NULL in case of failure. + */ +CRSelector * +cr_selector_new (CRSimpleSel * a_simple_sel) +{ + CRSelector *result = NULL; + + result = g_try_malloc (sizeof (CRSelector)); + if (!result) { + cr_utils_trace_info ("Out of memory"); + return NULL; + } + memset (result, 0, sizeof (CRSelector)); + result->simple_sel = a_simple_sel; + return result; +} + +CRSelector * +cr_selector_parse_from_buf (const guchar * a_char_buf, enum CREncoding a_enc) +{ + CRParser *parser = NULL; + + g_return_val_if_fail (a_char_buf, NULL); + + parser = cr_parser_new_from_buf ((guchar*)a_char_buf, strlen (a_char_buf), + a_enc, FALSE); + g_return_val_if_fail (parser, NULL); + + return NULL; +} + +/** + *Appends a new instance of #CRSelector to the current selector list. + *@param a_this the current instance of #CRSelector. + *@param a_new the instance of #CRSelector to be appended. + *@return the new list. + */ +CRSelector * +cr_selector_append (CRSelector * a_this, CRSelector * a_new) +{ + CRSelector *cur = NULL; + + if (!a_this) { + return a_new; + } + + /*walk forward the list headed by a_this to get the list tail */ + for (cur = a_this; cur && cur->next; cur = cur->next) ; + + cur->next = a_new; + a_new->prev = cur; + + return a_this; +} + +/** + *Prepends an element to the #CRSelector list. + *@param a_this the current instance of #CRSelector list. + *@param a_new the instance of #CRSelector. + *@return the new list. + */ +CRSelector * +cr_selector_prepend (CRSelector * a_this, CRSelector * a_new) +{ + CRSelector *cur = NULL; + + a_new->next = a_this; + a_this->prev = a_new; + + for (cur = a_new; cur && cur->prev; cur = cur->prev) ; + + return cur; +} + +/** + *append a simple selector to the current #CRSelector list. + *@param a_this the current instance of #CRSelector. + *@param a_simple_sel the simple selector to append. + *@return the new list or NULL in case of failure. + */ +CRSelector * +cr_selector_append_simple_sel (CRSelector * a_this, + CRSimpleSel * a_simple_sel) +{ + CRSelector *selector = NULL; + + selector = cr_selector_new (a_simple_sel); + g_return_val_if_fail (selector, NULL); + + return cr_selector_append (a_this, selector); +} + +guchar * +cr_selector_to_string (CRSelector * a_this) +{ + guchar *result = NULL; + GString *str_buf = NULL; + + str_buf = g_string_new (NULL); + g_return_val_if_fail (str_buf, NULL); + + if (a_this) { + CRSelector *cur = NULL; + + for (cur = a_this; cur; cur = cur->next) { + if (cur->simple_sel) { + guchar *tmp_str = NULL; + + tmp_str = cr_simple_sel_to_string + (cur->simple_sel); + + if (tmp_str) { + if (cur->prev) + g_string_append (str_buf, + ", "); + + g_string_append (str_buf, tmp_str); + + g_free (tmp_str); + tmp_str = NULL; + } + } + } + } + + if (str_buf) { + result = str_buf->str; + g_string_free (str_buf, FALSE); + str_buf = NULL; + } + + return result; +} + +/** + *Serializes the current instance of #CRSelector to a file. + *@param a_this the current instance of #CRSelector. + *@param a_fp the destination file. + */ +void +cr_selector_dump (CRSelector * a_this, FILE * a_fp) +{ + guchar *tmp_buf = NULL; + + if (a_this) { + tmp_buf = cr_selector_to_string (a_this); + if (tmp_buf) { + fprintf (a_fp, "%s", tmp_buf); + g_free (tmp_buf); + tmp_buf = NULL; + } + } +} + +/** + *Increments the ref count of the current instance + *of #CRSelector. + *@param a_this the current instance of #CRSelector. + */ +void +cr_selector_ref (CRSelector * a_this) +{ + g_return_if_fail (a_this); + + a_this->ref_count++; +} + +/** + *Decrements the ref count of the current instance of + *#CRSelector. + *If the ref count reaches zero, the current instance of + *#CRSelector is destroyed. + *@param a_this the current instance of #CRSelector. + *@return TRUE if this function destroyed the current instance + *of #CRSelector, FALSE otherwise. + */ +gboolean +cr_selector_unref (CRSelector * a_this) +{ + g_return_val_if_fail (a_this, FALSE); + + if (a_this->ref_count) { + a_this->ref_count--; + } + + if (a_this->ref_count == 0) { + cr_selector_destroy (a_this); + return TRUE; + } + + return FALSE; +} + +/** + *Destroys the selector list. + *@param a_this the current instance of #CRSelector. + */ +void +cr_selector_destroy (CRSelector * a_this) +{ + CRSelector *cur = NULL; + + g_return_if_fail (a_this); + + /* + *go and get the list tail. In the same time, free + *all the simple selectors contained in the list. + */ + for (cur = a_this; cur && cur->next; cur = cur->next) { + if (cur->simple_sel) { + cr_simple_sel_destroy (cur->simple_sel); + cur->simple_sel = NULL; + } + } + + if (cur) { + if (cur->simple_sel) { + cr_simple_sel_destroy (cur->simple_sel); + cur->simple_sel = NULL; + } + } + + /*in case the list has only one element */ + if (cur && !cur->prev) { + g_free (cur); + return; + } + + /*walk backward the list and free each "next element" */ + for (cur = cur->prev; cur && cur->prev; cur = cur->prev) { + if (cur->next) { + g_free (cur->next); + cur->next = NULL; + } + } + + if (!cur) + return; + + if (cur->next) { + g_free (cur->next); + cur->next = NULL; + } + + g_free (cur); +} diff --git a/src/libcroco/cr-selector.h b/src/libcroco/cr-selector.h new file mode 100644 index 000000000..6bf769733 --- /dev/null +++ b/src/libcroco/cr-selector.h @@ -0,0 +1,95 @@ +/* -*- Mode: C; indent-tabs-mode: ni; c-basic-offset: 8 -*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * + * Author: Dodji Seketeli + * See COPYRIGHTS file for copyright information. + */ + +#ifndef __CR_SELECTOR_H__ +#define __CR_SELECTOR_H__ + +#include +#include "cr-utils.h" +#include "cr-simple-sel.h" +#include "cr-parsing-location.h" + +/** + *@file + *The declaration file of the #CRSelector file. + */ + +G_BEGIN_DECLS + +typedef struct _CRSelector CRSelector ; + +/** + *Abstracts a CSS2 selector as defined in the right part + *of the 'ruleset" production in the appendix D.1 of the + *css2 spec. + *It is actually the abstraction of a comma separated list + *of simple selectors list. + *In a css2 file, a selector is a list of simple selectors + *separated by a comma. + *e.g: sel0, sel1, sel2 ... + *Each seln is a simple selector + */ +struct _CRSelector +{ + /** + *A Selection expression. + *It is a list of basic selectors. + *Each basic selector can be either an element + *selector, an id selector, a class selector, an + *attribute selector, an universal selector etc ... + */ + CRSimpleSel *simple_sel ; + + /**The next selector list element*/ + CRSelector *next ; + CRSelector *prev ; + CRParsingLocation location ; + glong ref_count ; +}; + +CRSelector* cr_selector_new (CRSimpleSel *a_sel_expr) ; + +CRSelector * cr_selector_parse_from_buf (const guchar * a_char_buf, + enum CREncoding a_enc) ; + +CRSelector* cr_selector_append (CRSelector *a_this, CRSelector *a_new) ; + +CRSelector* cr_selector_append_simple_sel (CRSelector *a_this, + CRSimpleSel *a_simple_sel) ; + +CRSelector* cr_selector_prepend (CRSelector *a_this, CRSelector *a_new) ; + +guchar * cr_selector_to_string (CRSelector *a_this) ; + +void cr_selector_dump (CRSelector *a_this, FILE *a_fp) ; + +void cr_selector_ref (CRSelector *a_this) ; + +gboolean cr_selector_unref (CRSelector *a_this) ; + +void cr_selector_destroy (CRSelector *a_this) ; + +G_END_DECLS + +#endif /*__CR_SELECTOR_H__*/ diff --git a/src/libcroco/cr-simple-sel.c b/src/libcroco/cr-simple-sel.c new file mode 100644 index 000000000..1b941dab5 --- /dev/null +++ b/src/libcroco/cr-simple-sel.c @@ -0,0 +1,308 @@ +/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * Author: Dodji Seketeli + * See COPYRIGHTS file for copyright information. + */ + +#include +#include +#include "cr-simple-sel.h" + +/** + *The constructor of #CRSimpleSel. + * + *@return the new instance of #CRSimpleSel. + */ +CRSimpleSel * +cr_simple_sel_new (void) +{ + CRSimpleSel *result = NULL; + + result = g_try_malloc (sizeof (CRSimpleSel)); + if (!result) { + cr_utils_trace_info ("Out of memory"); + return NULL; + } + memset (result, 0, sizeof (CRSimpleSel)); + + return result; +} + +/** + *Appends a simpe selector to the current list of simple selector. + * + *@param a_this the this pointer of the current instance of #CRSimpleSel. + *@param a_sel the simple selector to append. + *@return the new list upon successfull completion, an error code otherwise. + */ +CRSimpleSel * +cr_simple_sel_append_simple_sel (CRSimpleSel * a_this, CRSimpleSel * a_sel) +{ + CRSimpleSel *cur = NULL; + + g_return_val_if_fail (a_sel, NULL); + + if (a_this == NULL) + return a_sel; + + for (cur = a_this; cur->next; cur = cur->next) ; + + cur->next = a_sel; + a_sel->prev = cur; + + return a_this; +} + +/** + *Prepends a simple selector to the current list of simple selectors. + *@param a_this the this pointer of the current instance of #CRSimpleSel. + *@param a_sel the simple selector to prepend. + *@return the new list upon successfull completion, an error code otherwise. + */ +CRSimpleSel * +cr_simple_sel_prepend_simple_sel (CRSimpleSel * a_this, CRSimpleSel * a_sel) +{ + g_return_val_if_fail (a_sel, NULL); + + if (a_this == NULL) + return a_sel; + + a_sel->next = a_this; + a_this->prev = a_sel; + + return a_sel; +} + +guchar * +cr_simple_sel_to_string (CRSimpleSel * a_this) +{ + GString *str_buf = NULL; + guchar *result = NULL; + + CRSimpleSel *cur = NULL; + + g_return_val_if_fail (a_this, NULL); + + str_buf = g_string_new (NULL); + for (cur = a_this; cur; cur = cur->next) { + if (cur->name) { + guchar *str = g_strndup (cur->name->stryng->str, + cur->name->stryng->len); + + if (str) { + switch (cur->combinator) { + case COMB_WS: + g_string_append (str_buf, " "); + break; + + case COMB_PLUS: + g_string_append (str_buf, "+"); + break; + + case COMB_GT: + g_string_append (str_buf, ">"); + break; + + default: + break; + } + + g_string_append (str_buf, str); + g_free (str); + str = NULL; + } + } + + if (cur->add_sel) { + guchar *tmp_str = NULL; + + tmp_str = cr_additional_sel_to_string (cur->add_sel); + if (tmp_str) { + g_string_append (str_buf, tmp_str); + g_free (tmp_str); + tmp_str = NULL; + } + } + } + + if (str_buf) { + result = str_buf->str; + g_string_free (str_buf, FALSE); + str_buf = NULL; + } + + return result; +} + + +guchar * +cr_simple_sel_one_to_string (CRSimpleSel * a_this) +{ + GString *str_buf = NULL; + guchar *result = NULL; + + g_return_val_if_fail (a_this, NULL); + + str_buf = g_string_new (NULL); + if (a_this->name) { + guchar *str = g_strndup (a_this->name->stryng->str, + a_this->name->stryng->len); + + if (str) { + g_string_append_printf (str_buf, "%s", str); + g_free (str); + str = NULL; + } + } + + if (a_this->add_sel) { + guchar *tmp_str = NULL; + + tmp_str = cr_additional_sel_to_string (a_this->add_sel); + if (tmp_str) { + g_string_append_printf + (str_buf, "%s", tmp_str); + g_free (tmp_str); + tmp_str = NULL; + } + } + + if (str_buf) { + result = str_buf->str; + g_string_free (str_buf, FALSE); + str_buf = NULL; + } + + return result; +} + +/** + *Dumps the selector to a file. + *TODO: add the support of unicode in the dump. + * + *@param a_this the current instance of #CRSimpleSel. + *@param a_fp the destination file pointer. + *@return CR_OK upon successfull completion, an error code + *otherwise. + */ +enum CRStatus +cr_simple_sel_dump (CRSimpleSel * a_this, FILE * a_fp) +{ + guchar *tmp_str = NULL; + + g_return_val_if_fail (a_fp, CR_BAD_PARAM_ERROR); + + if (a_this) { + tmp_str = cr_simple_sel_to_string (a_this); + if (tmp_str) { + fprintf (a_fp, "%s", tmp_str); + g_free (tmp_str); + tmp_str = NULL; + } + } + + return CR_OK; +} + +/** + *Computes the selector (combinator separated list of simple selectors) + *as defined in the css2 spec in chapter 6.4.3 + *@param a_this the current instance of #CRSimpleSel + *@return CR_OK upon successfull completion, an error code otherwise. + */ +enum CRStatus +cr_simple_sel_compute_specificity (CRSimpleSel * a_this) +{ + CRAdditionalSel *cur_add_sel = NULL; + CRSimpleSel *cur_sel = NULL; + gulong a = 0, + b = 0, + c = 0; + + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + for (cur_sel = a_this; cur_sel; cur_sel = cur_sel->next) { + if (cur_sel->type_mask | TYPE_SELECTOR) { + c++; /*hmmh, is this a new language ? */ + } else if (!cur_sel->name + || !cur_sel->name->stryng + || !cur_sel->name->stryng->str) { + if (cur_sel->add_sel->type == + PSEUDO_CLASS_ADD_SELECTOR) { + /* + *this is a pseudo element, and + *the spec says, "ignore pseudo elements". + */ + continue; + } + } + + for (cur_add_sel = cur_sel->add_sel; + cur_add_sel; cur_add_sel = cur_add_sel->next) { + switch (cur_add_sel->type) { + case ID_ADD_SELECTOR: + a++; + break; + + case NO_ADD_SELECTOR: + continue; + + default: + b++; + break; + } + } + } + + /*we suppose a, b and c have 1 to 3 digits */ + a_this->specificity = a * 1000000 + b * 1000 + c; + + return CR_OK; +} + +/** + *The destructor of the current instance of + *#CRSimpleSel. + *@param a_this the this pointer of the current instance of #CRSimpleSel. + * + */ +void +cr_simple_sel_destroy (CRSimpleSel * a_this) +{ + g_return_if_fail (a_this); + + if (a_this->name) { + cr_string_destroy (a_this->name); + a_this->name = NULL; + } + + if (a_this->add_sel) { + cr_additional_sel_destroy (a_this->add_sel); + a_this->add_sel = NULL; + } + + if (a_this->next) { + cr_simple_sel_destroy (a_this->next); + } + + if (a_this) { + g_free (a_this); + } +} diff --git a/src/libcroco/cr-simple-sel.h b/src/libcroco/cr-simple-sel.h new file mode 100644 index 000000000..29033aff5 --- /dev/null +++ b/src/libcroco/cr-simple-sel.h @@ -0,0 +1,130 @@ +/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * Author: Dodji Seketeli + * See COPYRIGHTS file for copyright information. + */ + + +#ifndef __CR_SEL_H__ +#define __CR_SEL_H__ + +#include +#include +#include "cr-additional-sel.h" +#include "cr-parsing-location.h" + +G_BEGIN_DECLS + +/** + *@file + *the declaration of the #CRSimpleSel class. + * + */ +enum Combinator +{ + NO_COMBINATOR, + COMB_WS,/*whitesape*/ + COMB_PLUS, + COMB_GT/*greater than*/ +} ; + +enum SimpleSelectorType +{ + NO_SELECTOR_TYPE = 0, + UNIVERSAL_SELECTOR = 1, + TYPE_SELECTOR = 1 << 1 +} ; + +typedef struct _CRSimpleSel CRSimpleSel ; + +/** + *The abstraction of a css2 simple selection list + *as defined by the right part of the "selector" production in the + *appendix D.1 of the css2 spec. + *It is basically a list of simple selector, each + *simple selector being separated by a combinator. + * + *In the libcroco's implementation, each simple selector + *is made of at most two parts: + * + *1/An element name or 'type selector' (which can hold a '*' and + *then been called 'universal selector') + * + *2/An additional selector that "specializes" the preceding type or + *universal selector. The additionnal selector can be either + *an id selector, or a class selector, or an attribute selector. + */ +struct _CRSimpleSel +{ + enum SimpleSelectorType type_mask ; + gboolean is_case_sentive ; + CRString * name ; + /** + *The combinator that separates + *this simple selector from the previous + *one. + */ + enum Combinator combinator ; + + /** + *The additional selector list of the + *current simple selector. + *An additional selector may + *be a class selector, an id selector, + *or an attribute selector. + *Note that this field is a linked list. + */ + CRAdditionalSel *add_sel ; + + /* + *the specificity as specified by + *chapter 6.4.3 of the spec. + */ + gulong specificity ; + + CRSimpleSel *next ; + CRSimpleSel *prev ; + CRParsingLocation location ; +} ; + +CRSimpleSel * cr_simple_sel_new (void) ; + +CRSimpleSel * cr_simple_sel_append_simple_sel (CRSimpleSel *a_this, + CRSimpleSel *a_sel) ; + +CRSimpleSel * cr_simple_sel_prepend_simple_sel (CRSimpleSel *a_this, + CRSimpleSel *a_sel) ; + +guchar * cr_simple_sel_to_string (CRSimpleSel *a_this) ; + +guchar * cr_simple_sel_one_to_string (CRSimpleSel * a_this) ; + +enum CRStatus cr_simple_sel_dump (CRSimpleSel *a_this, FILE *a_fp) ; + +enum CRStatus cr_simple_sel_dump_attr_sel_list (CRSimpleSel *a_this) ; + +enum CRStatus cr_simple_sel_compute_specificity (CRSimpleSel *a_this) ; + +void cr_simple_sel_destroy (CRSimpleSel *a_this) ; + +G_END_DECLS + + +#endif /*__CR_SIMPLE_SEL_H__*/ diff --git a/src/libcroco/cr-statement.c b/src/libcroco/cr-statement.c new file mode 100644 index 000000000..c00da1546 --- /dev/null +++ b/src/libcroco/cr-statement.c @@ -0,0 +1,2608 @@ +/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * Author: Dodji Seketeli. + * See COPYRIGHTS files for copyrights information. + */ + +#include +#include "cr-statement.h" +#include "cr-parser.h" + +#define UNUSED(_param) ((void)(_param)) + +/** + *@file + *Definition of the #CRStatement class. + */ + +#define DECLARATION_INDENT_NB 2 + +static void cr_statement_clear (CRStatement * a_this); + +static void +parse_font_face_start_font_face_cb (CRDocHandler * a_this, + CRParsingLocation * a_location) +{ + CRStatement *stmt = NULL; + enum CRStatus status = CR_OK; + + UNUSED(a_location); + + stmt = cr_statement_new_at_font_face_rule (NULL, NULL); + g_return_if_fail (stmt); + + status = cr_doc_handler_set_ctxt (a_this, stmt); + g_return_if_fail (status == CR_OK); +} + +static void +parse_font_face_unrecoverable_error_cb (CRDocHandler * a_this) +{ + CRStatement *stmt = NULL; + CRStatement **stmtptr = NULL; + enum CRStatus status = CR_OK; + + g_return_if_fail (a_this); + + stmtptr = &stmt; + status = cr_doc_handler_get_ctxt (a_this, (gpointer *) stmtptr); + if (status != CR_OK) { + cr_utils_trace_info ("Couldn't get parsing context. " + "This may lead to some memory leaks."); + return; + } + if (stmt) { + cr_statement_destroy (stmt); + cr_doc_handler_set_ctxt (a_this, NULL); + return; + } +} + +static void +parse_font_face_property_cb (CRDocHandler * a_this, + CRString * a_name, + CRTerm * a_value, gboolean a_important) +{ + enum CRStatus status = CR_OK; + CRString *name = NULL; + CRDeclaration *decl = NULL; + CRStatement *stmt = NULL; + CRStatement **stmtptr = NULL; + + UNUSED(a_important); + + g_return_if_fail (a_this && a_name); + + stmtptr = &stmt; + status = cr_doc_handler_get_ctxt (a_this, (gpointer *) stmtptr); + g_return_if_fail (status == CR_OK && stmt); + g_return_if_fail (stmt->type == AT_FONT_FACE_RULE_STMT); + + name = cr_string_dup (a_name) ; + g_return_if_fail (name); + decl = cr_declaration_new (stmt, name, a_value); + if (!decl) { + cr_utils_trace_info ("cr_declaration_new () failed."); + goto error; + } + name = NULL; + + stmt->kind.font_face_rule->decl_list = + cr_declaration_append (stmt->kind.font_face_rule->decl_list, + decl); + if (!stmt->kind.font_face_rule->decl_list) + goto error; + decl = NULL; + + error: + if (decl) { + cr_declaration_unref (decl); + decl = NULL; + } + if (name) { + cr_string_destroy (name); + name = NULL; + } +} + +static void +parse_font_face_end_font_face_cb (CRDocHandler * a_this) +{ + CRStatement *result = NULL; + CRStatement **resultptr = NULL; + enum CRStatus status = CR_OK; + + g_return_if_fail (a_this); + + resultptr = &result; + status = cr_doc_handler_get_ctxt (a_this, (gpointer *) resultptr); + g_return_if_fail (status == CR_OK && result); + g_return_if_fail (result->type == AT_FONT_FACE_RULE_STMT); + + status = cr_doc_handler_set_result (a_this, result); + g_return_if_fail (status == CR_OK); +} + +static void +parse_page_start_page_cb (CRDocHandler * a_this, + CRString * a_name, + CRString * a_pseudo_page, + CRParsingLocation * a_location) +{ + CRStatement *stmt = NULL; + enum CRStatus status = CR_OK; + CRString *page_name = NULL, *pseudo_name = NULL ; + + UNUSED(a_location); + + if (a_name) + page_name = cr_string_dup (a_name) ; + if (a_pseudo_page) + pseudo_name = cr_string_dup (a_pseudo_page) ; + + stmt = cr_statement_new_at_page_rule (NULL, NULL, + page_name, + pseudo_name); + page_name = NULL ; + pseudo_name = NULL ; + g_return_if_fail (stmt); + status = cr_doc_handler_set_ctxt (a_this, stmt); + g_return_if_fail (status == CR_OK); +} + +static void +parse_page_unrecoverable_error_cb (CRDocHandler * a_this) +{ + CRStatement *stmt = NULL; + CRStatement **stmtptr = NULL; + enum CRStatus status = CR_OK; + + g_return_if_fail (a_this); + + stmtptr = &stmt; + status = cr_doc_handler_get_ctxt (a_this, (gpointer *) stmtptr); + if (status != CR_OK) { + cr_utils_trace_info ("Couldn't get parsing context. " + "This may lead to some memory leaks."); + return; + } + if (stmt) { + cr_statement_destroy (stmt); + stmt = NULL; + cr_doc_handler_set_ctxt (a_this, NULL); + } +} + +static void +parse_page_property_cb (CRDocHandler * a_this, + CRString * a_name, + CRTerm * a_expression, gboolean a_important) +{ + CRString *name = NULL; + CRStatement *stmt = NULL; + CRStatement **stmtptr = NULL; + CRDeclaration *decl = NULL; + enum CRStatus status = CR_OK; + + stmtptr = &stmt; + status = cr_doc_handler_get_ctxt (a_this, (gpointer *) stmtptr); + g_return_if_fail (status == CR_OK && stmt->type == AT_PAGE_RULE_STMT); + + name = cr_string_dup (a_name); + g_return_if_fail (name); + + decl = cr_declaration_new (stmt, name, a_expression); + g_return_if_fail (decl); + decl->important = a_important; + stmt->kind.page_rule->decl_list = + cr_declaration_append (stmt->kind.page_rule->decl_list, decl); + g_return_if_fail (stmt->kind.page_rule->decl_list); +} + +static void +parse_page_end_page_cb (CRDocHandler * a_this, + CRString * a_name, + CRString * a_pseudo_page) +{ + enum CRStatus status = CR_OK; + CRStatement *stmt = NULL; + CRStatement **stmtptr = NULL; + + UNUSED(a_name); + UNUSED(a_pseudo_page); + + stmtptr = &stmt; + status = cr_doc_handler_get_ctxt (a_this, (gpointer *) stmtptr); + g_return_if_fail (status == CR_OK && stmt); + g_return_if_fail (stmt->type == AT_PAGE_RULE_STMT); + + status = cr_doc_handler_set_result (a_this, stmt); + g_return_if_fail (status == CR_OK); +} + +static void +parse_at_media_start_media_cb (CRDocHandler * a_this, + GList * a_media_list, + CRParsingLocation * a_location) +{ + enum CRStatus status = CR_OK; + CRStatement *at_media = NULL; + GList *media_list = NULL; + + UNUSED(a_location); + + g_return_if_fail (a_this && a_this->priv); + + if (a_media_list) { + /*duplicate media list */ + media_list = cr_utils_dup_glist_of_cr_string + (a_media_list); + } + + g_return_if_fail (media_list); + + /*make sure cr_statement_new_at_media_rule works in this case. */ + at_media = cr_statement_new_at_media_rule (NULL, NULL, media_list); + + status = cr_doc_handler_set_ctxt (a_this, at_media); + g_return_if_fail (status == CR_OK); + status = cr_doc_handler_set_result (a_this, at_media); + g_return_if_fail (status == CR_OK); +} + +static void +parse_at_media_unrecoverable_error_cb (CRDocHandler * a_this) +{ + enum CRStatus status = CR_OK; + CRStatement *stmt = NULL; + CRStatement **stmtptr = NULL; + + g_return_if_fail (a_this); + + stmtptr = &stmt; + status = cr_doc_handler_get_result (a_this, (gpointer *) stmtptr); + if (status != CR_OK) { + cr_utils_trace_info ("Couldn't get parsing context. " + "This may lead to some memory leaks."); + return; + } + if (stmt) { + cr_statement_destroy (stmt); + stmt = NULL; + cr_doc_handler_set_ctxt (a_this, NULL); + cr_doc_handler_set_result (a_this, NULL); + } +} + +static void +parse_at_media_start_selector_cb (CRDocHandler * a_this, + CRSelector * a_sellist) +{ + enum CRStatus status = CR_OK; + CRStatement *at_media = NULL; + CRStatement **at_media_ptr = NULL; + CRStatement *ruleset = NULL; + + g_return_if_fail (a_this && a_this->priv && a_sellist); + + at_media_ptr = &at_media; + status = cr_doc_handler_get_ctxt (a_this, (gpointer *) at_media_ptr); + g_return_if_fail (status == CR_OK && at_media); + g_return_if_fail (at_media->type == AT_MEDIA_RULE_STMT); + ruleset = cr_statement_new_ruleset (NULL, a_sellist, NULL, at_media); + g_return_if_fail (ruleset); + status = cr_doc_handler_set_ctxt (a_this, ruleset); + g_return_if_fail (status == CR_OK); +} + +static void +parse_at_media_property_cb (CRDocHandler * a_this, + CRString * a_name, CRTerm * a_value, + gboolean a_important) +{ + enum CRStatus status = CR_OK; + + /* + *the current ruleset stmt, child of the + *current at-media being parsed. + */ + CRStatement *stmt = NULL; + CRStatement **stmtptr = NULL; + CRDeclaration *decl = NULL; + CRString *name = NULL; + + g_return_if_fail (a_this && a_name); + + name = cr_string_dup (a_name) ; + g_return_if_fail (name); + + stmtptr = &stmt; + status = cr_doc_handler_get_ctxt (a_this, + (gpointer *) stmtptr); + g_return_if_fail (status == CR_OK && stmt); + g_return_if_fail (stmt->type == RULESET_STMT); + + decl = cr_declaration_new (stmt, name, a_value); + g_return_if_fail (decl); + decl->important = a_important; + status = cr_statement_ruleset_append_decl (stmt, decl); + g_return_if_fail (status == CR_OK); +} + +static void +parse_at_media_end_selector_cb (CRDocHandler * a_this, + CRSelector * a_sellist) +{ + enum CRStatus status = CR_OK; + + /* + *the current ruleset stmt, child of the + *current at-media being parsed. + */ + CRStatement *stmt = NULL; + CRStatement **stmtptr = NULL; + + g_return_if_fail (a_this && a_sellist); + + stmtptr = &stmt; + status = cr_doc_handler_get_ctxt (a_this, (gpointer *) stmtptr); + g_return_if_fail (status == CR_OK && stmt + && stmt->type == RULESET_STMT); + g_return_if_fail (stmt->kind.ruleset->parent_media_rule); + + status = cr_doc_handler_set_ctxt + (a_this, stmt->kind.ruleset->parent_media_rule); + g_return_if_fail (status == CR_OK); +} + +static void +parse_at_media_end_media_cb (CRDocHandler * a_this, + GList * a_media_list) +{ + enum CRStatus status = CR_OK; + CRStatement *at_media = NULL; + CRStatement **at_media_ptr = NULL; + + UNUSED(a_media_list); + + g_return_if_fail (a_this && a_this->priv); + + at_media_ptr = &at_media; + status = cr_doc_handler_get_ctxt (a_this, + (gpointer *) at_media_ptr); + g_return_if_fail (status == CR_OK && at_media); + status = cr_doc_handler_set_result (a_this, at_media); +} + +static void +parse_ruleset_start_selector_cb (CRDocHandler * a_this, + CRSelector * a_sellist) +{ + CRStatement *ruleset = NULL; + + g_return_if_fail (a_this && a_this->priv && a_sellist); + + ruleset = cr_statement_new_ruleset (NULL, a_sellist, NULL, NULL); + g_return_if_fail (ruleset); + + cr_doc_handler_set_result (a_this, ruleset); +} + +static void +parse_ruleset_unrecoverable_error_cb (CRDocHandler * a_this) +{ + CRStatement *stmt = NULL; + CRStatement **stmtptr = NULL; + enum CRStatus status = CR_OK; + + stmtptr = &stmt; + status = cr_doc_handler_get_result (a_this, (gpointer *) stmtptr); + if (status != CR_OK) { + cr_utils_trace_info ("Couldn't get parsing context. " + "This may lead to some memory leaks."); + return; + } + if (stmt) { + cr_statement_destroy (stmt); + stmt = NULL; + cr_doc_handler_set_result (a_this, NULL); + } +} + +static void +parse_ruleset_property_cb (CRDocHandler * a_this, + CRString * a_name, + CRTerm * a_value, gboolean a_important) +{ + enum CRStatus status = CR_OK; + CRStatement *ruleset = NULL; + CRStatement **rulesetptr = NULL; + CRDeclaration *decl = NULL; + CRString *stringue = NULL; + + g_return_if_fail (a_this && a_this->priv && a_name); + + stringue = cr_string_dup (a_name); + g_return_if_fail (stringue); + + rulesetptr = &ruleset; + status = cr_doc_handler_get_result (a_this, (gpointer *) rulesetptr); + g_return_if_fail (status == CR_OK + && ruleset + && ruleset->type == RULESET_STMT); + + decl = cr_declaration_new (ruleset, stringue, a_value); + g_return_if_fail (decl); + decl->important = a_important; + status = cr_statement_ruleset_append_decl (ruleset, decl); + g_return_if_fail (status == CR_OK); +} + +static void +parse_ruleset_end_selector_cb (CRDocHandler * a_this, + CRSelector * a_sellist) +{ + CRStatement *result = NULL; + CRStatement **resultptr = NULL; + enum CRStatus status = CR_OK; + + g_return_if_fail (a_this && a_sellist); + + resultptr = &result; + status = cr_doc_handler_get_result (a_this, (gpointer *) resultptr); + + g_return_if_fail (status == CR_OK + && result + && result->type == RULESET_STMT); +} + +static void +cr_statement_clear (CRStatement * a_this) +{ + g_return_if_fail (a_this); + + switch (a_this->type) { + case AT_RULE_STMT: + break; + case RULESET_STMT: + if (!a_this->kind.ruleset) + return; + if (a_this->kind.ruleset->sel_list) { + cr_selector_unref (a_this->kind.ruleset->sel_list); + a_this->kind.ruleset->sel_list = NULL; + } + if (a_this->kind.ruleset->decl_list) { + cr_declaration_destroy + (a_this->kind.ruleset->decl_list); + a_this->kind.ruleset->decl_list = NULL; + } + g_free (a_this->kind.ruleset); + a_this->kind.ruleset = NULL; + break; + + case AT_IMPORT_RULE_STMT: + if (!a_this->kind.import_rule) + return; + if (a_this->kind.import_rule->url) { + cr_string_destroy + (a_this->kind.import_rule->url) ; + a_this->kind.import_rule->url = NULL; + } + g_free (a_this->kind.import_rule); + a_this->kind.import_rule = NULL; + break; + + case AT_MEDIA_RULE_STMT: + if (!a_this->kind.media_rule) + return; + if (a_this->kind.media_rule->rulesets) { + cr_statement_destroy + (a_this->kind.media_rule->rulesets); + a_this->kind.media_rule->rulesets = NULL; + } + if (a_this->kind.media_rule->media_list) { + GList *cur = NULL; + + for (cur = a_this->kind.media_rule->media_list; + cur; cur = cur->next) { + if (cur->data) { + cr_string_destroy ((CRString *) cur->data); + cur->data = NULL; + } + + } + g_list_free (a_this->kind.media_rule->media_list); + a_this->kind.media_rule->media_list = NULL; + } + g_free (a_this->kind.media_rule); + a_this->kind.media_rule = NULL; + break; + + case AT_PAGE_RULE_STMT: + if (!a_this->kind.page_rule) + return; + + if (a_this->kind.page_rule->decl_list) { + cr_declaration_destroy + (a_this->kind.page_rule->decl_list); + a_this->kind.page_rule->decl_list = NULL; + } + if (a_this->kind.page_rule->name) { + cr_string_destroy + (a_this->kind.page_rule->name); + a_this->kind.page_rule->name = NULL; + } + if (a_this->kind.page_rule->pseudo) { + cr_string_destroy + (a_this->kind.page_rule->pseudo); + a_this->kind.page_rule->pseudo = NULL; + } + g_free (a_this->kind.page_rule); + a_this->kind.page_rule = NULL; + break; + + case AT_CHARSET_RULE_STMT: + if (!a_this->kind.charset_rule) + return; + + if (a_this->kind.charset_rule->charset) { + cr_string_destroy + (a_this->kind.charset_rule->charset); + a_this->kind.charset_rule->charset = NULL; + } + g_free (a_this->kind.charset_rule); + a_this->kind.charset_rule = NULL; + break; + + case AT_FONT_FACE_RULE_STMT: + if (!a_this->kind.font_face_rule) + return; + + if (a_this->kind.font_face_rule->decl_list) { + cr_declaration_unref + (a_this->kind.font_face_rule->decl_list); + a_this->kind.font_face_rule->decl_list = NULL; + } + g_free (a_this->kind.font_face_rule); + a_this->kind.font_face_rule = NULL; + break; + + default: + break; + } +} + +/** + *Serializes the ruleset statement into a string + *@param a_this the current instance of #CRStatement + *@param a_indent the number of whitespace to use for indentation + *@return the newly allocated serialised string. Must be freed + *by the caller, using g_free(). + */ +static gchar * +cr_statement_ruleset_to_string (CRStatement * a_this, glong a_indent) +{ + GString *stringue = NULL; + gchar *tmp_str = NULL, + *result = NULL; + + g_return_val_if_fail (a_this && a_this->type == RULESET_STMT, NULL); + + stringue = g_string_new (NULL); + + if (a_this->kind.ruleset->sel_list) { + if (a_indent) + cr_utils_dump_n_chars2 (' ', stringue, a_indent); + + tmp_str = + cr_selector_to_string (a_this->kind.ruleset-> + sel_list); + if (tmp_str) { + g_string_append (stringue, tmp_str); + g_free (tmp_str); + tmp_str = NULL; + } + } + g_string_append (stringue, " {\n"); + if (a_this->kind.ruleset->decl_list) { + tmp_str = cr_declaration_list_to_string2 + (a_this->kind.ruleset->decl_list, + a_indent + DECLARATION_INDENT_NB, TRUE); + if (tmp_str) { + g_string_append (stringue, tmp_str); + g_free (tmp_str); + tmp_str = NULL; + } + g_string_append (stringue, "\n"); + cr_utils_dump_n_chars2 (' ', stringue, a_indent); + } + g_string_append (stringue, "}"); + result = stringue->str; + + if (stringue) { + g_string_free (stringue, FALSE); + stringue = NULL; + } + if (tmp_str) { + g_free (tmp_str); + tmp_str = NULL; + } + return result; +} + + +/** + *Serializes a font face rule statement into a string. + *@param a_this the current instance of #CRStatement to consider + *It must be a font face rule statement. + *@param a_indent the number of white spaces of indentation. + *@return the serialized string. Must be deallocated by the caller + *using g_free(). + */ +static gchar * +cr_statement_font_face_rule_to_string (CRStatement * a_this, + glong a_indent) +{ + gchar *result = NULL, *tmp_str = NULL ; + GString *stringue = NULL ; + + g_return_val_if_fail (a_this + && a_this->type == AT_FONT_FACE_RULE_STMT, + NULL); + + if (a_this->kind.font_face_rule->decl_list) { + stringue = g_string_new (NULL) ; + g_return_val_if_fail (stringue, NULL) ; + if (a_indent) + cr_utils_dump_n_chars2 (' ', stringue, + a_indent); + g_string_append (stringue, "@font-face {\n"); + tmp_str = cr_declaration_list_to_string2 + (a_this->kind.font_face_rule->decl_list, + a_indent + DECLARATION_INDENT_NB, TRUE) ; + if (tmp_str) { + g_string_append (stringue, + tmp_str) ; + g_free (tmp_str) ; + tmp_str = NULL ; + } + g_string_append (stringue, "\n}"); + } + if (stringue) { + result = stringue->str ; + g_string_free (stringue, FALSE) ; + stringue = NULL ; + } + return result ; +} + + +/** + *Serialises an @charset statement into a string. + *@param a_this the statement to serialize. + *@return the serialized charset statement. Must be + *freed by the caller using g_free(). + */ +static gchar * +cr_statement_charset_to_string (CRStatement *a_this, + gulong a_indent) +{ + gchar *str = NULL ; + GString *stringue = NULL ; + + g_return_val_if_fail (a_this + && a_this->type == AT_CHARSET_RULE_STMT, + NULL) ; + + if (a_this->kind.charset_rule + && a_this->kind.charset_rule->charset + && a_this->kind.charset_rule->charset->stryng + && a_this->kind.charset_rule->charset->stryng->str) { + str = g_strndup (a_this->kind.charset_rule->charset->stryng->str, + a_this->kind.charset_rule->charset->stryng->len); + g_return_val_if_fail (str, NULL); + stringue = g_string_new (NULL) ; + g_return_val_if_fail (stringue, NULL) ; + cr_utils_dump_n_chars2 (' ', stringue, a_indent); + g_string_append_printf (stringue, + "@charset \"%s\" ;", str); + if (str) { + g_free (str); + str = NULL; + } + } + if (stringue) { + str = stringue->str ; + g_string_free (stringue, FALSE) ; + } + return str ; +} + + +/** + *Serialises the at page rule statement into a string + *@param a_this the current instance of #CRStatement. Must + *be an "@page" rule statement. + *@return the serialized string. Must be freed by the caller + */ +static gchar * +cr_statement_at_page_rule_to_string (CRStatement *a_this, + gulong a_indent) +{ + GString *stringue = NULL; + gchar *result = NULL ; + + stringue = g_string_new (NULL) ; + + cr_utils_dump_n_chars2 (' ', stringue, a_indent) ; + g_string_append (stringue, "@page"); + if (a_this->kind.page_rule->name + && a_this->kind.page_rule->name->stryng) { + g_string_append_printf + (stringue, " %s", + a_this->kind.page_rule->name->stryng->str) ; + } else { + g_string_append (stringue, " "); + } + if (a_this->kind.page_rule->pseudo + && a_this->kind.page_rule->pseudo->stryng) { + g_string_append_printf + (stringue, " :%s", + a_this->kind.page_rule->pseudo->stryng->str) ; + } + if (a_this->kind.page_rule->decl_list) { + gchar *str = NULL ; + g_string_append (stringue, " {\n"); + str = cr_declaration_list_to_string2 + (a_this->kind.page_rule->decl_list, + a_indent + DECLARATION_INDENT_NB, TRUE) ; + if (str) { + g_string_append (stringue, str) ; + g_free (str) ; + str = NULL ; + } + g_string_append (stringue, "\n}\n"); + } + result = stringue->str ; + g_string_free (stringue, FALSE) ; + stringue = NULL ; + return result ; +} + + +/** + *Serializes an @media statement. + *@param a_this the current instance of #CRStatement + *@param a_indent the number of spaces of indentation. + *@return the serialized @media statement. Must be freed + *by the caller using g_free(). + */ +static gchar * +cr_statement_media_rule_to_string (CRStatement *a_this, + gulong a_indent) +{ + gchar *str = NULL ; + GString *stringue = NULL ; + GList *cur = NULL; + + g_return_val_if_fail (a_this->type == AT_MEDIA_RULE_STMT, + NULL); + + if (a_this->kind.media_rule) { + stringue = g_string_new (NULL) ; + cr_utils_dump_n_chars2 (' ', stringue, a_indent); + g_string_append (stringue, "@media"); + + for (cur = a_this->kind.media_rule->media_list; cur; + cur = cur->next) { + if (cur->data) { + guchar *str = cr_string_dup2 + ((CRString *) cur->data); + + if (str) { + if (cur->prev) { + g_string_append + (stringue, + ","); + } + g_string_append_printf + (stringue, + " %s", str); + g_free (str); + str = NULL; + } + } + } + g_string_append (stringue, " {\n"); + str = cr_statement_list_to_string + (a_this->kind.media_rule->rulesets, + a_indent + DECLARATION_INDENT_NB) ; + if (str) { + g_string_append (stringue, str) ; + g_free (str) ; + str = NULL ; + } + g_string_append (stringue, "\n}"); + } + if (stringue) { + str = stringue->str ; + g_string_free (stringue, FALSE) ; + } + return str ; +} + + +static gchar * +cr_statement_import_rule_to_string (CRStatement *a_this, + gulong a_indent) +{ + GString *stringue = NULL ; + guchar *str = NULL; + + g_return_val_if_fail (a_this + && a_this->type == AT_IMPORT_RULE_STMT + && a_this->kind.import_rule, + NULL) ; + + if (a_this->kind.import_rule->url + && a_this->kind.import_rule->url->stryng) { + stringue = g_string_new (NULL) ; + g_return_val_if_fail (stringue, NULL) ; + str = g_strndup (a_this->kind.import_rule->url->stryng->str, + a_this->kind.import_rule->url->stryng->len); + cr_utils_dump_n_chars2 (' ', stringue, a_indent); + if (str) { + g_string_append_printf (stringue, + "@import url(\"%s\")", + str); + g_free (str); + str = NULL ; + } else /*there is no url, so no import rule, get out! */ + return NULL; + + if (a_this->kind.import_rule->media_list) { + GList *cur = NULL; + + for (cur = a_this->kind.import_rule->media_list; + cur; cur = cur->next) { + if (cur->data) { + CRString *crstr = cur->data; + + if (cur->prev) { + g_string_append + (stringue, ", "); + } + if (crstr + && crstr->stryng + && crstr->stryng->str) { + g_string_append_len + (stringue, + crstr->stryng->str, + crstr->stryng->len) ; + } + } + } + } + g_string_append (stringue, " ;"); + } + if (stringue) { + str = stringue->str ; + g_string_free (stringue, FALSE) ; + stringue = NULL ; + } + return str ; +} + + +/******************* + *public functions + ******************/ + +/** + *Tries to parse a buffer and says whether if the content of the buffer + *is a css statement as defined by the "Core CSS Grammar" (chapter 4 of the + *css spec) or not. + *@param a_buf the buffer to parse. + *@param a_encoding the character encoding of a_buf. + *@return TRUE if the buffer parses against the core grammar, false otherwise. + */ +gboolean +cr_statement_does_buf_parses_against_core (const guchar * a_buf, + enum CREncoding a_encoding) +{ + CRParser *parser = NULL; + enum CRStatus status = CR_OK; + gboolean result = FALSE; + + parser = cr_parser_new_from_buf ((guchar*)a_buf, strlen (a_buf), + a_encoding, FALSE); + g_return_val_if_fail (parser, FALSE); + + status = cr_parser_set_use_core_grammar (parser, TRUE); + if (status != CR_OK) { + goto cleanup; + } + + status = cr_parser_parse_statement_core (parser); + if (status == CR_OK) { + result = TRUE; + } + + cleanup: + if (parser) { + cr_parser_destroy (parser); + } + + return result; +} + +/** + *Parses a buffer that contains a css statement and returns + *an instance of #CRStatement in case of successfull parsing. + *TODO: at support of "@import" rules. + *@param a_buf the buffer to parse. + *@param a_encoding the character encoding of a_buf. + *@return the newly built instance of #CRStatement in case + *of successfull parsing, NULL otherwise. + */ +CRStatement * +cr_statement_parse_from_buf (const guchar * a_buf, enum CREncoding a_encoding) +{ + CRStatement *result = NULL; + + /* + *The strategy of this function is "brute force". + *It tries to parse all the types of #CRStatement it knows about. + *I could do this a smarter way but I don't have the time now. + *I think I will revisit this when time of performances and + *pull based incremental parsing comes. + */ + + result = cr_statement_ruleset_parse_from_buf (a_buf, a_encoding); + if (!result) { + result = cr_statement_at_charset_rule_parse_from_buf + (a_buf, a_encoding); + } else { + goto out; + } + + if (!result) { + result = cr_statement_at_media_rule_parse_from_buf + (a_buf, a_encoding); + } else { + goto out; + } + + if (!result) { + result = cr_statement_at_charset_rule_parse_from_buf + (a_buf, a_encoding); + } else { + goto out; + } + + if (!result) { + result = cr_statement_font_face_rule_parse_from_buf + (a_buf, a_encoding); + + } else { + goto out; + } + + if (!result) { + result = cr_statement_at_page_rule_parse_from_buf + (a_buf, a_encoding); + } else { + goto out; + } + + if (!result) { + result = cr_statement_at_import_rule_parse_from_buf + (a_buf, a_encoding); + } else { + goto out; + } + + out: + return result; +} + +/** + *Parses a buffer that contains a ruleset statement and instanciates + *a #CRStatement of type RULESET_STMT. + *@param a_buf the buffer to parse. + *@param a_enc the character encoding of a_buf. + *@param the newly built instance of #CRStatement in case of successful parsing, + *NULL otherwise. + */ +CRStatement * +cr_statement_ruleset_parse_from_buf (const guchar * a_buf, + enum CREncoding a_enc) +{ + enum CRStatus status = CR_OK; + CRStatement *result = NULL; + CRStatement **resultptr = NULL; + CRParser *parser = NULL; + CRDocHandler *sac_handler = NULL; + + g_return_val_if_fail (a_buf, NULL); + + parser = cr_parser_new_from_buf ((guchar*)a_buf, strlen (a_buf), + a_enc, FALSE); + + g_return_val_if_fail (parser, NULL); + + sac_handler = cr_doc_handler_new (); + g_return_val_if_fail (sac_handler, NULL); + + sac_handler->start_selector = parse_ruleset_start_selector_cb; + sac_handler->end_selector = parse_ruleset_end_selector_cb; + sac_handler->property = parse_ruleset_property_cb; + sac_handler->unrecoverable_error = + parse_ruleset_unrecoverable_error_cb; + + cr_parser_set_sac_handler (parser, sac_handler); + cr_parser_try_to_skip_spaces_and_comments (parser); + status = cr_parser_parse_ruleset (parser); + if (status != CR_OK) { + goto cleanup; + } + + resultptr = &result; + status = cr_doc_handler_get_result (sac_handler, + (gpointer *) resultptr); + if (!((status == CR_OK) && result)) { + if (result) { + cr_statement_destroy (result); + result = NULL; + } + } + + cleanup: + if (parser) { + cr_parser_destroy (parser); + parser = NULL; + sac_handler = NULL ; + } + if (sac_handler) { + cr_doc_handler_unref (sac_handler); + sac_handler = NULL; + } + return result; +} + +/** + *Creates a new instance of #CRStatement of type + *#CRRulSet. + *@param a_sel_list the list of #CRSimpleSel (selectors) + *the rule applies to. + *@param a_decl_list the list of instances of #CRDeclaration + *that composes the ruleset. + *@param a_media_types a list of instances of GString that + *describe the media list this ruleset applies to. + *@return the new instance of #CRStatement or NULL if something + *went wrong. + */ +CRStatement * +cr_statement_new_ruleset (CRStyleSheet * a_sheet, + CRSelector * a_sel_list, + CRDeclaration * a_decl_list, + CRStatement * a_parent_media_rule) +{ + CRStatement *result = NULL; + + g_return_val_if_fail (a_sel_list, NULL); + + if (a_parent_media_rule) { + g_return_val_if_fail + (a_parent_media_rule->type == AT_MEDIA_RULE_STMT, + NULL); + g_return_val_if_fail (a_parent_media_rule->kind.media_rule, + NULL); + } + + result = g_try_malloc (sizeof (CRStatement)); + + if (!result) { + cr_utils_trace_info ("Out of memory"); + return NULL; + } + + memset (result, 0, sizeof (CRStatement)); + result->type = RULESET_STMT; + result->kind.ruleset = g_try_malloc (sizeof (CRRuleSet)); + + if (!result->kind.ruleset) { + cr_utils_trace_info ("Out of memory"); + if (result) + g_free (result); + return NULL; + } + + memset (result->kind.ruleset, 0, sizeof (CRRuleSet)); + result->kind.ruleset->sel_list = a_sel_list; + if (a_sel_list) + cr_selector_ref (a_sel_list); + result->kind.ruleset->decl_list = a_decl_list; + + if (a_parent_media_rule) { + result->kind.ruleset->parent_media_rule = a_parent_media_rule; + a_parent_media_rule->kind.media_rule->rulesets = + cr_statement_append + (a_parent_media_rule->kind.media_rule->rulesets, + result); + } + + cr_statement_set_parent_sheet (result, a_sheet); + + return result; +} + +/** + *Parses a buffer that contains an "@media" declaration + *and builds an @media css statement. + *@param a_buf the input to parse. + *@param a_enc the encoding of the buffer. + *@return the @media statement, or NULL if the buffer could not + *be successfully parsed. + */ +CRStatement * +cr_statement_at_media_rule_parse_from_buf (const guchar * a_buf, + enum CREncoding a_enc) +{ + CRParser *parser = NULL; + CRStatement *result = NULL; + CRStatement **resultptr = NULL; + CRDocHandler *sac_handler = NULL; + enum CRStatus status = CR_OK; + + parser = cr_parser_new_from_buf ((guchar*)a_buf, strlen (a_buf), + a_enc, FALSE); + if (!parser) { + cr_utils_trace_info ("Instanciation of the parser failed"); + goto cleanup; + } + + sac_handler = cr_doc_handler_new (); + if (!sac_handler) { + cr_utils_trace_info + ("Instanciation of the sac handler failed"); + goto cleanup; + } + + sac_handler->start_media = parse_at_media_start_media_cb; + sac_handler->start_selector = parse_at_media_start_selector_cb; + sac_handler->property = parse_at_media_property_cb; + sac_handler->end_selector = parse_at_media_end_selector_cb; + sac_handler->end_media = parse_at_media_end_media_cb; + sac_handler->unrecoverable_error = + parse_at_media_unrecoverable_error_cb; + + status = cr_parser_set_sac_handler (parser, sac_handler); + if (status != CR_OK) + goto cleanup; + + status = cr_parser_try_to_skip_spaces_and_comments (parser); + if (status != CR_OK) + goto cleanup; + + status = cr_parser_parse_media (parser); + if (status != CR_OK) + goto cleanup; + + resultptr = &result; + status = cr_doc_handler_get_result (sac_handler, + (gpointer *) resultptr); + if (status != CR_OK) + goto cleanup; + + cleanup: + + if (parser) { + cr_parser_destroy (parser); + parser = NULL; + sac_handler = NULL ; + } + if (sac_handler) { + cr_doc_handler_unref (sac_handler); + sac_handler = NULL; + } + + return result; +} + +/** + *Instanciates an instance of #CRStatement of type + *AT_MEDIA_RULE_STMT (@media ruleset). + *@param a_ruleset the ruleset statements contained + *in the @media rule. + *@param a_media, the media string list. A list of GString pointers. + */ +CRStatement * +cr_statement_new_at_media_rule (CRStyleSheet * a_sheet, + CRStatement * a_rulesets, GList * a_media) +{ + CRStatement *result = NULL, + *cur = NULL; + + if (a_rulesets) + g_return_val_if_fail (a_rulesets->type == RULESET_STMT, NULL); + + result = g_try_malloc (sizeof (CRStatement)); + + if (!result) { + cr_utils_trace_info ("Out of memory"); + return NULL; + } + + memset (result, 0, sizeof (CRStatement)); + result->type = AT_MEDIA_RULE_STMT; + + result->kind.media_rule = g_try_malloc (sizeof (CRAtMediaRule)); + if (!result->kind.media_rule) { + cr_utils_trace_info ("Out of memory"); + g_free (result); + return NULL; + } + memset (result->kind.media_rule, 0, sizeof (CRAtMediaRule)); + result->kind.media_rule->rulesets = a_rulesets; + for (cur = a_rulesets; cur; cur = cur->next) { + if (cur->type != RULESET_STMT || !cur->kind.ruleset) { + cr_utils_trace_info ("Bad parameter a_rulesets. " + "It should be a list of " + "correct ruleset statement only !"); + goto error; + } + cur->kind.ruleset->parent_media_rule = result; + } + + result->kind.media_rule->media_list = a_media; + if (a_sheet) { + cr_statement_set_parent_sheet (result, a_sheet); + } + + return result; + + error: + return NULL; +} + +/** + *Creates a new instance of #CRStatment of type + *#CRAtImportRule. + *@param a_url the url to connect to the get the file + *to be imported. + *@param a_sheet the imported parsed stylesheet. + *@return the newly built instance of #CRStatement. + */ +CRStatement * +cr_statement_new_at_import_rule (CRStyleSheet * a_container_sheet, + CRString * a_url, + GList * a_media_list, + CRStyleSheet * a_imported_sheet) +{ + CRStatement *result = NULL; + + result = g_try_malloc (sizeof (CRStatement)); + + if (!result) { + cr_utils_trace_info ("Out of memory"); + return NULL; + } + + memset (result, 0, sizeof (CRStatement)); + result->type = AT_IMPORT_RULE_STMT; + + result->kind.import_rule = g_try_malloc (sizeof (CRAtImportRule)); + + if (!result->kind.import_rule) { + cr_utils_trace_info ("Out of memory"); + g_free (result); + return NULL; + } + + memset (result->kind.import_rule, 0, sizeof (CRAtImportRule)); + result->kind.import_rule->url = a_url; + result->kind.import_rule->media_list = a_media_list; + result->kind.import_rule->sheet = a_imported_sheet; + if (a_container_sheet) + cr_statement_set_parent_sheet (result, a_container_sheet); + + return result; +} + +/** + *Parses a buffer that contains an "@import" rule and + *instanciate a #CRStatement of type AT_IMPORT_RULE_STMT + *@param a_buf the buffer to parse. + *@param a_encoding the encoding of a_buf. + *@return the newly built instance of #CRStatement in case of + *a successfull parsing, NULL otherwise. + */ +CRStatement * +cr_statement_at_import_rule_parse_from_buf (const guchar * a_buf, + enum CREncoding a_encoding) +{ + enum CRStatus status = CR_OK; + CRParser *parser = NULL; + CRStatement *result = NULL; + GList *media_list = NULL; + CRString *import_string = NULL; + CRParsingLocation location = {0,0,0} ; + + parser = cr_parser_new_from_buf ((guchar*)a_buf, strlen (a_buf), + a_encoding, FALSE); + if (!parser) { + cr_utils_trace_info ("Instanciation of parser failed."); + goto cleanup; + } + + status = cr_parser_try_to_skip_spaces_and_comments (parser); + if (status != CR_OK) + goto cleanup; + + status = cr_parser_parse_import (parser, + &media_list, + &import_string, + &location); + if (status != CR_OK || !import_string) + goto cleanup; + + result = cr_statement_new_at_import_rule (NULL, import_string, + media_list, NULL); + if (result) { + cr_parsing_location_copy (&result->location, + &location) ; + import_string = NULL; + media_list = NULL; + } + + cleanup: + if (parser) { + cr_parser_destroy (parser); + parser = NULL; + } + if (media_list) { + GList *cur = NULL; + + for (cur = media_list; media_list; + media_list = g_list_next (media_list)) { + if (media_list->data) { + cr_string_destroy ((CRString*)media_list->data); + media_list->data = NULL; + } + } + g_list_free (media_list); + media_list = NULL; + } + if (import_string) { + cr_string_destroy (import_string); + import_string = NULL; + } + + return result; +} + +/** + *Creates a new instance of #CRStatement of type + *#CRAtPageRule. + *@param a_decl_list a list of instances of #CRDeclarations + *which is actually the list of declarations that applies to + *this page rule. + *@param a_selector the page rule selector. + *@return the newly built instance of #CRStatement or NULL + *in case of error. + */ +CRStatement * +cr_statement_new_at_page_rule (CRStyleSheet * a_sheet, + CRDeclaration * a_decl_list, + CRString * a_name, CRString * a_pseudo) +{ + CRStatement *result = NULL; + + result = g_try_malloc (sizeof (CRStatement)); + + if (!result) { + cr_utils_trace_info ("Out of memory"); + return NULL; + } + + memset (result, 0, sizeof (CRStatement)); + result->type = AT_PAGE_RULE_STMT; + + result->kind.page_rule = g_try_malloc (sizeof (CRAtPageRule)); + + if (!result->kind.page_rule) { + cr_utils_trace_info ("Out of memory"); + g_free (result); + return NULL; + } + + memset (result->kind.page_rule, 0, sizeof (CRAtPageRule)); + if (a_decl_list) { + result->kind.page_rule->decl_list = a_decl_list; + cr_declaration_ref (a_decl_list); + } + result->kind.page_rule->name = a_name; + result->kind.page_rule->pseudo = a_pseudo; + if (a_sheet) + cr_statement_set_parent_sheet (result, a_sheet); + + return result; +} + +/** + *Parses a buffer that contains an "@page" production and, + *if the parsing succeeds, builds the page statement. + *@param a_buf the character buffer to parse. + *@param a_encoding the character encoding of a_buf. + *@return the newly built at page statement in case of successfull parsing, + *NULL otherwise. + */ +CRStatement * +cr_statement_at_page_rule_parse_from_buf (const guchar * a_buf, + enum CREncoding a_encoding) +{ + enum CRStatus status = CR_OK; + CRParser *parser = NULL; + CRDocHandler *sac_handler = NULL; + CRStatement *result = NULL; + CRStatement **resultptr = NULL; + + g_return_val_if_fail (a_buf, NULL); + + parser = cr_parser_new_from_buf ((guchar*)a_buf, strlen (a_buf), + a_encoding, FALSE); + if (!parser) { + cr_utils_trace_info ("Instanciation of the parser failed."); + goto cleanup; + } + + sac_handler = cr_doc_handler_new (); + if (!sac_handler) { + cr_utils_trace_info + ("Instanciation of the sac handler failed."); + goto cleanup; + } + + sac_handler->start_page = parse_page_start_page_cb; + sac_handler->property = parse_page_property_cb; + sac_handler->end_page = parse_page_end_page_cb; + sac_handler->unrecoverable_error = parse_page_unrecoverable_error_cb; + + status = cr_parser_set_sac_handler (parser, sac_handler); + if (status != CR_OK) + goto cleanup; + + /*Now, invoke the parser to parse the "@page production" */ + cr_parser_try_to_skip_spaces_and_comments (parser); + if (status != CR_OK) + goto cleanup; + status = cr_parser_parse_page (parser); + if (status != CR_OK) + goto cleanup; + + resultptr = &result; + status = cr_doc_handler_get_result (sac_handler, + (gpointer *) resultptr); + + cleanup: + + if (parser) { + cr_parser_destroy (parser); + parser = NULL; + sac_handler = NULL ; + } + if (sac_handler) { + cr_doc_handler_unref (sac_handler); + sac_handler = NULL; + } + return result; +} + +/** + *Creates a new instance of #CRStatement of type + *#CRAtCharsetRule. + *@param a_charset the string representing the charset. + *Note that the newly built instance of #CRStatement becomes + *the owner of a_charset. The caller must not free a_charset !!!. + *@return the newly built instance of #CRStatement or NULL + *if an error arises. + */ +CRStatement * +cr_statement_new_at_charset_rule (CRStyleSheet * a_sheet, + CRString * a_charset) +{ + CRStatement *result = NULL; + + g_return_val_if_fail (a_charset, NULL); + + result = g_try_malloc (sizeof (CRStatement)); + + if (!result) { + cr_utils_trace_info ("Out of memory"); + return NULL; + } + + memset (result, 0, sizeof (CRStatement)); + result->type = AT_CHARSET_RULE_STMT; + + result->kind.charset_rule = g_try_malloc (sizeof (CRAtCharsetRule)); + + if (!result->kind.charset_rule) { + cr_utils_trace_info ("Out of memory"); + g_free (result); + return NULL; + } + memset (result->kind.charset_rule, 0, sizeof (CRAtCharsetRule)); + result->kind.charset_rule->charset = a_charset; + cr_statement_set_parent_sheet (result, a_sheet); + + return result; +} + +/** + *Parses a buffer that contains an '@charset' rule and + *creates an instance of #CRStatement of type AT_CHARSET_RULE_STMT. + *@param a_buf the buffer to parse. + *@param the character encoding of the buffer. + *@return the newly built instance of #CRStatement. + */ +CRStatement * +cr_statement_at_charset_rule_parse_from_buf (const guchar * a_buf, + enum CREncoding a_encoding) +{ + enum CRStatus status = CR_OK; + CRParser *parser = NULL; + CRStatement *result = NULL; + CRString *charset = NULL; + + g_return_val_if_fail (a_buf, NULL); + + parser = cr_parser_new_from_buf ((guchar*)a_buf, strlen (a_buf), + a_encoding, FALSE); + if (!parser) { + cr_utils_trace_info ("Instanciation of the parser failed."); + goto cleanup; + } + + /*Now, invoke the parser to parse the "@charset production" */ + cr_parser_try_to_skip_spaces_and_comments (parser); + if (status != CR_OK) + goto cleanup; + status = cr_parser_parse_charset (parser, &charset, NULL); + if (status != CR_OK || !charset) + goto cleanup; + + result = cr_statement_new_at_charset_rule (NULL, charset); + if (result) + charset = NULL; + + cleanup: + + if (parser) { + cr_parser_destroy (parser); + parser = NULL; + } + if (charset) { + cr_string_destroy (charset); + } + + return result; +} + +/** + *Creates an instance of #CRStatement of type #CRAtFontFaceRule. + *@param a_font_decls a list of instances of #CRDeclaration. Each declaration + *is actually a font declaration. + *@return the newly built instance of #CRStatement. + */ +CRStatement * +cr_statement_new_at_font_face_rule (CRStyleSheet * a_sheet, + CRDeclaration * a_font_decls) +{ + CRStatement *result = NULL; + + result = g_try_malloc (sizeof (CRStatement)); + + if (!result) { + cr_utils_trace_info ("Out of memory"); + return NULL; + } + memset (result, 0, sizeof (CRStatement)); + result->type = AT_FONT_FACE_RULE_STMT; + + result->kind.font_face_rule = g_try_malloc + (sizeof (CRAtFontFaceRule)); + + if (!result->kind.font_face_rule) { + cr_utils_trace_info ("Out of memory"); + g_free (result); + return NULL; + } + memset (result->kind.font_face_rule, 0, sizeof (CRAtFontFaceRule)); + + result->kind.font_face_rule->decl_list = a_font_decls; + if (a_sheet) + cr_statement_set_parent_sheet (result, a_sheet); + + return result; +} + +/** + *Parses a buffer that contains an "@font-face" rule and builds + *an instance of #CRStatement of type AT_FONT_FACE_RULE_STMT out of it. + *@param a_buf the buffer to parse. + *@param a_encoding the character encoding of a_buf. + *@return the newly built instance of #CRStatement in case of successufull + *parsing, NULL otherwise. + */ +CRStatement * +cr_statement_font_face_rule_parse_from_buf (const guchar * a_buf, + enum CREncoding a_encoding) +{ + CRStatement *result = NULL; + CRStatement **resultptr = NULL; + CRParser *parser = NULL; + CRDocHandler *sac_handler = NULL; + enum CRStatus status = CR_OK; + + parser = cr_parser_new_from_buf ((guchar*)a_buf, strlen (a_buf), + a_encoding, FALSE); + if (!parser) + goto cleanup; + + sac_handler = cr_doc_handler_new (); + if (!sac_handler) + goto cleanup; + + /* + *set sac callbacks here + */ + sac_handler->start_font_face = parse_font_face_start_font_face_cb; + sac_handler->property = parse_font_face_property_cb; + sac_handler->end_font_face = parse_font_face_end_font_face_cb; + sac_handler->unrecoverable_error = + parse_font_face_unrecoverable_error_cb; + + status = cr_parser_set_sac_handler (parser, sac_handler); + if (status != CR_OK) + goto cleanup; + + /* + *cleanup spaces of comment that may be there before the real + *"@font-face" thing. + */ + status = cr_parser_try_to_skip_spaces_and_comments (parser); + if (status != CR_OK) + goto cleanup; + + status = cr_parser_parse_font_face (parser); + if (status != CR_OK) + goto cleanup; + + resultptr = &result; + status = cr_doc_handler_get_result (sac_handler, + (gpointer *) resultptr); + if (status != CR_OK || !result) + goto cleanup; + + cleanup: + if (parser) { + cr_parser_destroy (parser); + parser = NULL; + sac_handler = NULL ; + } + if (sac_handler) { + cr_doc_handler_unref (sac_handler); + sac_handler = NULL; + } + return result; +} + +/** + *Sets the container stylesheet. + *@param a_this the current instance of #CRStatement. + *@param a_sheet the sheet that contains the current statement. + *@return CR_OK upon successfull completion, an errror code otherwise. + */ +enum CRStatus +cr_statement_set_parent_sheet (CRStatement * a_this, CRStyleSheet * a_sheet) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + a_this->parent_sheet = a_sheet; + return CR_OK; +} + +/** + *Gets the sheets that contains the current statement. + *@param a_this the current #CRStatement. + *@param a_sheet out parameter. A pointer to the sheets that + *@return CR_OK upon successfull completion, an error code otherwise. + */ +enum CRStatus +cr_statement_get_parent_sheet (CRStatement * a_this, CRStyleSheet ** a_sheet) +{ + g_return_val_if_fail (a_this && a_sheet, CR_BAD_PARAM_ERROR); + *a_sheet = a_this->parent_sheet; + return CR_OK; +} + +/** + *Appends a new statement to the statement list. + *@param a_this the current instance of the statement list. + *@param a_this a_new the new instance of #CRStatement to append. + *@return the new list statement list, or NULL in cas of failure. + */ +CRStatement * +cr_statement_append (CRStatement * a_this, CRStatement * a_new) +{ + CRStatement *cur = NULL; + + g_return_val_if_fail (a_new, NULL); + + if (!a_this) { + return a_new; + } + + /*walk forward in the current list to find the tail list element */ + for (cur = a_this; cur && cur->next; cur = cur->next) ; + + cur->next = a_new; + a_new->prev = cur; + + return a_this; +} + +/** + *Prepends the an instance of #CRStatement to + *the current statement list. + *@param a_this the current instance of #CRStatement. + *@param a_new the new statement to prepend. + *@return the new list with the new statement prepended, + *or NULL in case of an error. + */ +CRStatement * +cr_statement_prepend (CRStatement * a_this, CRStatement * a_new) +{ + CRStatement *cur = NULL; + + g_return_val_if_fail (a_new, NULL); + + if (!a_this) + return a_new; + + a_new->next = a_this; + a_this->prev = a_new; + + /*walk backward in the prepended list to find the head list element */ + for (cur = a_new; cur && cur->prev; cur = cur->prev) ; + + return cur; +} + +/** + *Unlinks a statement from the statements list. + *@param a_this the current statements list. + *@param a_to_unlink the statement to unlink from the list. + *@return the new list where a_to_unlink has been unlinked + *from, or NULL in case of error. + */ +CRStatement * +cr_statement_unlink (CRStatement * a_stmt) +{ + CRStatement *result = a_stmt; + + g_return_val_if_fail (result, NULL); + + /** + *Some sanity checks first + */ + if (a_stmt->next) { + g_return_val_if_fail (a_stmt->next->prev == a_stmt, NULL); + } + if (a_stmt->prev) { + g_return_val_if_fail (a_stmt->prev->next == a_stmt, NULL); + } + + /** + *Now, the real unlinking job. + */ + if (a_stmt->next) { + a_stmt->next->prev = a_stmt->prev; + } + if (a_stmt->prev) { + a_stmt->prev->next = a_stmt->next; + } + + if (a_stmt->parent_sheet + && a_stmt->parent_sheet->statements == a_stmt) { + a_stmt->parent_sheet->statements = + a_stmt->parent_sheet->statements->next; + } + + a_stmt->next = NULL; + a_stmt->prev = NULL; + a_stmt->parent_sheet = NULL; + + return result; +} + +/** + *Return the number of rules in the statement list; + *@param a_this the current instance of #CRStatement. + *@return number of rules in the statement list. + */ +gint +cr_statement_nr_rules (CRStatement * a_this) +{ + CRStatement *cur = NULL; + int nr = 0; + + g_return_val_if_fail (a_this, -1); + + for (cur = a_this; cur; cur = cur->next) + nr++; + return nr; +} + +/** + *Use an index to get a CRStatement from the statement list. + *@param a_this the current instance of #CRStatement. + *@param itemnr the index into the statement list. + *@return CRStatement at position itemnr, if itemnr > number of statements - 1, + *it will return NULL. + */ +CRStatement * +cr_statement_get_from_list (CRStatement * a_this, int itemnr) +{ + CRStatement *cur = NULL; + int nr = 0; + + g_return_val_if_fail (a_this, NULL); + + for (cur = a_this; cur; cur = cur->next) + if (nr++ == itemnr) + return cur; + return NULL; +} + +/** + *Sets a selector list to a ruleset statement. + *@param a_this the current ruleset statement. + *@param a_sel_list the selector list to set. Note + *that this function increments the ref count of a_sel_list. + *The sel list will be destroyed at the destruction of the + *current instance of #CRStatement. + *@return CR_OK upon successfull completion, an error code otherwise. + */ +enum CRStatus +cr_statement_ruleset_set_sel_list (CRStatement * a_this, + CRSelector * a_sel_list) +{ + g_return_val_if_fail (a_this && a_this->type == RULESET_STMT, + CR_BAD_PARAM_ERROR); + + if (a_this->kind.ruleset->sel_list) + cr_selector_unref (a_this->kind.ruleset->sel_list); + + a_this->kind.ruleset->sel_list = a_sel_list; + + if (a_sel_list) + cr_selector_ref (a_sel_list); + + return CR_OK; +} + +/** + *Gets a pointer to the list of declaration contained + *in the ruleset statement. + *@param a_this the current instance of #CRStatement. + *@a_decl_list out parameter. A pointer to the the returned + *list of declaration. Must not be NULL. + *@return CR_OK upon successfull completion, an error code if something + *bad happened. + */ +enum CRStatus +cr_statement_ruleset_get_declarations (CRStatement * a_this, + CRDeclaration ** a_decl_list) +{ + g_return_val_if_fail (a_this + && a_this->type == RULESET_STMT + && a_this->kind.ruleset + && a_decl_list, CR_BAD_PARAM_ERROR); + + *a_decl_list = a_this->kind.ruleset->decl_list; + + return CR_OK; +} + +/** + *Gets a pointer to the selector list contained in + *the current ruleset statement. + *@param a_this the current ruleset statement. + *@param a_list out parameter. The returned selector list, + *if and only if the function returned CR_OK. + *@return CR_OK upon successfull completion, an error code otherwise. + */ +enum CRStatus +cr_statement_ruleset_get_sel_list (CRStatement * a_this, CRSelector ** a_list) +{ + g_return_val_if_fail (a_this && a_this->type == RULESET_STMT + && a_this->kind.ruleset, CR_BAD_PARAM_ERROR); + + *a_list = a_this->kind.ruleset->sel_list; + + return CR_OK; +} + +/** + *Sets a declaration list to the current ruleset statement. + *@param a_this the current ruleset statement. + *@param a_list the declaration list to be added to the current + *ruleset statement. + *@return CR_OK upon successfull completion, an error code otherwise. + */ +enum CRStatus +cr_statement_ruleset_set_decl_list (CRStatement * a_this, + CRDeclaration * a_list) +{ + g_return_val_if_fail (a_this && a_this->type == RULESET_STMT + && a_this->kind.ruleset, CR_BAD_PARAM_ERROR); + + if (a_this->kind.ruleset->decl_list == a_list) + return CR_OK; + + if (a_this->kind.ruleset->sel_list) { + cr_declaration_destroy (a_this->kind.ruleset->decl_list); + } + + a_this->kind.ruleset->sel_list = NULL; + + return CR_OK; +} + +/** + *Appends a declaration to the current ruleset statement. + *@param a_this the current statement. + *@param a_prop the property of the declaration. + *@param a_value the value of the declaration. + *@return CR_OK uppon successfull completion, an error code + *otherwise. + */ +enum CRStatus +cr_statement_ruleset_append_decl2 (CRStatement * a_this, + CRString * a_prop, + CRTerm * a_value) +{ + CRDeclaration *new_decls = NULL; + + g_return_val_if_fail (a_this && a_this->type == RULESET_STMT + && a_this->kind.ruleset, CR_BAD_PARAM_ERROR); + + new_decls = cr_declaration_append2 + (a_this->kind.ruleset->decl_list, + a_prop, a_value); + g_return_val_if_fail (new_decls, CR_ERROR); + a_this->kind.ruleset->decl_list = new_decls; + + return CR_OK; +} + +/** + *Appends a declaration to the current statement. + *@param a_this the current statement. + *@param a_declaration the declaration to append. + *@return CR_OK upon sucessfull completion, an error code + *otherwise. + */ +enum CRStatus +cr_statement_ruleset_append_decl (CRStatement * a_this, + CRDeclaration * a_decl) +{ + CRDeclaration *new_decls = NULL; + + g_return_val_if_fail (a_this && a_this->type == RULESET_STMT + && a_this->kind.ruleset, CR_BAD_PARAM_ERROR); + + new_decls = cr_declaration_append + (a_this->kind.ruleset->decl_list, a_decl); + g_return_val_if_fail (new_decls, CR_ERROR); + a_this->kind.ruleset->decl_list = new_decls; + + return CR_OK; +} + +/** + *Sets a stylesheet to the current @import rule. + *@param a_this the current @import rule. + *@param a_sheet the stylesheet. The stylesheet is owned + *by the current instance of #CRStatement, that is, the + *stylesheet will be destroyed when the current instance + *of #CRStatement will be destroyed. + *@return CR_OK upon successfull completion, an error code otherwise. + */ +enum CRStatus +cr_statement_at_import_rule_set_imported_sheet (CRStatement * a_this, + CRStyleSheet * a_sheet) +{ + g_return_val_if_fail (a_this + && a_this->type == AT_IMPORT_RULE_STMT + && a_this->kind.import_rule, + CR_BAD_PARAM_ERROR); + + a_this->kind.import_rule->sheet = a_sheet; + + return CR_OK; +} + +/** + *Gets the stylesheet contained by the @import rule statement. + *@param a_this the current @import rule statement. + *@param a_sheet out parameter. The returned stylesheet if and + *only if the function returns CR_OK. + *@return CR_OK upon sucessfull completion, an error code otherwise. + */ +enum CRStatus +cr_statement_at_import_rule_get_imported_sheet (CRStatement * a_this, + CRStyleSheet ** a_sheet) +{ + g_return_val_if_fail (a_this + && a_this->type == AT_IMPORT_RULE_STMT + && a_this->kind.import_rule, + CR_BAD_PARAM_ERROR); + *a_sheet = a_this->kind.import_rule->sheet; + return CR_OK; + +} + +/** + *Sets an url to the current @import rule statement. + *@param a_this the current @import rule statement. + *@param a_url the url to set. + *@return CR_OK upon successfull completion, an error code otherwise. + */ +enum CRStatus +cr_statement_at_import_rule_set_url (CRStatement * a_this, + CRString * a_url) +{ + g_return_val_if_fail (a_this + && a_this->type == AT_IMPORT_RULE_STMT + && a_this->kind.import_rule, + CR_BAD_PARAM_ERROR); + + if (a_this->kind.import_rule->url) { + cr_string_destroy (a_this->kind.import_rule->url); + } + + a_this->kind.import_rule->url = a_url; + + return CR_OK; +} + +/** + *Gets the url of the @import rule statement. + *@param the current @import rule statement. + *@param a_url out parameter. The returned url if + *and only if the function returned CR_OK. + */ +enum CRStatus +cr_statement_at_import_rule_get_url (CRStatement * a_this, + CRString ** a_url) +{ + g_return_val_if_fail (a_this + && a_this->type == AT_IMPORT_RULE_STMT + && a_this->kind.import_rule, + CR_BAD_PARAM_ERROR); + + *a_url = a_this->kind.import_rule->url; + + return CR_OK; +} + +/** + *Return the number of rules in the media rule; + *@param a_this the current instance of #CRStatement. + *@return number of rules in the media rule. + */ +int +cr_statement_at_media_nr_rules (CRStatement * a_this) +{ + g_return_val_if_fail (a_this + && a_this->type == AT_MEDIA_RULE_STMT + && a_this->kind.media_rule, CR_BAD_PARAM_ERROR); + + return cr_statement_nr_rules (a_this->kind.media_rule->rulesets); +} + +/** + *Use an index to get a CRStatement from the media rule list of rules. + *@param a_this the current instance of #CRStatement. + *@param itemnr the index into the media rule list of rules. + *@return CRStatement at position itemnr, if itemnr > number of rules - 1, + *it will return NULL. + */ +CRStatement * +cr_statement_at_media_get_from_list (CRStatement * a_this, int itemnr) +{ + g_return_val_if_fail (a_this + && a_this->type == AT_MEDIA_RULE_STMT + && a_this->kind.media_rule, NULL); + + return cr_statement_get_from_list (a_this->kind.media_rule->rulesets, + itemnr); +} + +/** + *Sets a declaration list to the current @page rule statement. + *@param a_this the current @page rule statement. + *@param a_decl_list the declaration list to add. Will be freed + *by the current instance of #CRStatement when it is destroyed. + *@return CR_OK upon successfull completion, an error code otherwise. + */ +enum CRStatus +cr_statement_at_page_rule_set_declarations (CRStatement * a_this, + CRDeclaration * a_decl_list) +{ + g_return_val_if_fail (a_this + && a_this->type == AT_PAGE_RULE_STMT + && a_this->kind.page_rule, CR_BAD_PARAM_ERROR); + + if (a_this->kind.page_rule->decl_list) { + cr_declaration_unref (a_this->kind.page_rule->decl_list); + } + + a_this->kind.page_rule->decl_list = a_decl_list; + + if (a_decl_list) { + cr_declaration_ref (a_decl_list); + } + + return CR_OK; +} + +/** + *Gets the declaration list associated to the current @page rule + *statement. + *@param a_this the current @page rule statement. + *@param a_decl_list out parameter. The returned declaration list. + *@return CR_OK upon successfull completion, an error code otherwise. + */ +enum CRStatus +cr_statement_at_page_rule_get_declarations (CRStatement * a_this, + CRDeclaration ** a_decl_list) +{ + g_return_val_if_fail (a_this + && a_this->type == AT_PAGE_RULE_STMT + && a_this->kind.page_rule, CR_BAD_PARAM_ERROR); + + *a_decl_list = a_this->kind.page_rule->decl_list; + + return CR_OK; +} + +/** + *Sets the charset of the current @charset rule statement. + *@param a_this the current @charset rule statement. + *@param a_charset the charset to set. + *@return CR_OK upon successfull completion, an error code otherwise. + */ +enum CRStatus +cr_statement_at_charset_rule_set_charset (CRStatement * a_this, + CRString * a_charset) +{ + g_return_val_if_fail (a_this + && a_this->type == AT_CHARSET_RULE_STMT + && a_this->kind.charset_rule, + CR_BAD_PARAM_ERROR); + + if (a_this->kind.charset_rule->charset) { + cr_string_destroy (a_this->kind.charset_rule->charset); + } + a_this->kind.charset_rule->charset = a_charset; + return CR_OK; +} + +/** + *Gets the charset string associated to the current + *@charset rule statement. + *@param a_this the current @charset rule statement. + *@param a_charset out parameter. The returned charset string if + *and only if the function returned CR_OK. + */ +enum CRStatus +cr_statement_at_charset_rule_get_charset (CRStatement * a_this, + CRString ** a_charset) +{ + g_return_val_if_fail (a_this + && a_this->type == AT_CHARSET_RULE_STMT + && a_this->kind.charset_rule, + CR_BAD_PARAM_ERROR); + + *a_charset = a_this->kind.charset_rule->charset; + + return CR_OK; +} + +/** + *Sets a declaration list to the current @font-face rule statement. + *@param a_this the current @font-face rule statement. + *@param a_decls the declarations list to set. + *@return CR_OK upon successfull completion, an error code otherwise. + */ +enum CRStatus +cr_statement_at_font_face_rule_set_decls (CRStatement * a_this, + CRDeclaration * a_decls) +{ + g_return_val_if_fail (a_this + && a_this->type == AT_FONT_FACE_RULE_STMT + && a_this->kind.font_face_rule, + CR_BAD_PARAM_ERROR); + + if (a_this->kind.font_face_rule->decl_list) { + cr_declaration_unref (a_this->kind.font_face_rule->decl_list); + } + + a_this->kind.font_face_rule->decl_list = a_decls; + cr_declaration_ref (a_decls); + + return CR_OK; +} + +/** + *Gets the declaration list associated to the current instance + *of @font-face rule statement. + *@param a_this the current @font-face rule statement. + *@param a_decls out parameter. The returned declaration list if + *and only if this function returns CR_OK. + *@return CR_OK upon successfull completion, an error code otherwise. + */ +enum CRStatus +cr_statement_at_font_face_rule_get_decls (CRStatement * a_this, + CRDeclaration ** a_decls) +{ + g_return_val_if_fail (a_this + && a_this->type == AT_FONT_FACE_RULE_STMT + && a_this->kind.font_face_rule, + CR_BAD_PARAM_ERROR); + + *a_decls = a_this->kind.font_face_rule->decl_list; + + return CR_OK; +} + +/** + *Adds a declaration to the current @font-face rule + *statement. + *@param a_this the current @font-face rule statement. + *@param a_prop the property of the declaration. + *@param a_value the value of the declaration. + *@return CR_OK upon successfull completion, an error code otherwise. + */ +enum CRStatus +cr_statement_at_font_face_rule_add_decl (CRStatement * a_this, + CRString * a_prop, CRTerm * a_value) +{ + CRDeclaration *decls = NULL; + + g_return_val_if_fail (a_this + && a_this->type == AT_FONT_FACE_RULE_STMT + && a_this->kind.font_face_rule, + CR_BAD_PARAM_ERROR); + + decls = cr_declaration_append2 + (a_this->kind.font_face_rule->decl_list, + a_prop, a_value); + + g_return_val_if_fail (decls, CR_ERROR); + + if (a_this->kind.font_face_rule->decl_list == NULL) + cr_declaration_ref (decls); + + a_this->kind.font_face_rule->decl_list = decls; + + return CR_OK; +} + +/** + *Serializes a css statement into a string + *@param a_this the current statement to serialize + *@param a_indent the number of white space of indentation. + *@return the serialized statement. Must be freed by the caller + *using g_free(). + */ +gchar * +cr_statement_to_string (CRStatement * a_this, gulong a_indent) +{ + gchar *str = NULL ; + + if (!a_this) + return NULL; + + switch (a_this->type) { + case RULESET_STMT: + str = cr_statement_ruleset_to_string + (a_this, a_indent); + break; + + case AT_FONT_FACE_RULE_STMT: + str = cr_statement_font_face_rule_to_string + (a_this, a_indent) ; + break; + + case AT_CHARSET_RULE_STMT: + str = cr_statement_charset_to_string + (a_this, a_indent); + break; + + case AT_PAGE_RULE_STMT: + str = cr_statement_at_page_rule_to_string + (a_this, a_indent); + break; + + case AT_MEDIA_RULE_STMT: + str = cr_statement_media_rule_to_string + (a_this, a_indent); + break; + + case AT_IMPORT_RULE_STMT: + str = cr_statement_import_rule_to_string + (a_this, a_indent); + break; + + default: + cr_utils_trace_info ("Statement unrecognized"); + break; + } + return str ; +} + +gchar* +cr_statement_list_to_string (CRStatement *a_this, gulong a_indent) +{ + CRStatement *cur_stmt = NULL ; + GString *stringue = NULL ; + gchar *str = NULL ; + + g_return_val_if_fail (a_this, NULL) ; + + stringue = g_string_new (NULL) ; + if (!stringue) { + cr_utils_trace_info ("Out of memory") ; + return NULL ; + } + for (cur_stmt = a_this ; cur_stmt; + cur_stmt = cur_stmt->next) { + str = cr_statement_to_string (cur_stmt, a_indent) ; + if (str) { + if (!cur_stmt->prev) { + g_string_append (stringue, str) ; + } else { + g_string_append_printf + (stringue, "\n%s", str) ; + } + g_free (str) ; + str = NULL ; + } + } + str = stringue->str ; + g_string_free (stringue, FALSE) ; + return str ; +} + +/** + *Dumps the css2 statement to a file. + *@param a_this the current css2 statement. + *@param a_fp the destination file pointer. + *@param a_indent the number of white space indentation characters. + */ +void +cr_statement_dump (CRStatement * a_this, FILE * a_fp, gulong a_indent) +{ + gchar *str = NULL ; + + if (!a_this) + return; + + str = cr_statement_to_string (a_this, a_indent) ; + if (str) { + fprintf (a_fp, "%s",str) ; + g_free (str) ; + str = NULL ; + } +} + +/** + *Dumps a ruleset statement to a file. + *@param a_this the current instance of #CRStatement. + *@param a_fp the destination file pointer. + *@param a_indent the number of indentation white spaces to add. + */ +void +cr_statement_dump_ruleset (CRStatement * a_this, FILE * a_fp, glong a_indent) +{ + guchar *str = NULL; + + g_return_if_fail (a_fp && a_this); + str = cr_statement_ruleset_to_string (a_this, a_indent); + if (str) { + fprintf (a_fp, str); + g_free (str); + str = NULL; + } +} + +/** + *Dumps a font face rule statement to a file. + *@param a_this the current instance of font face rule statement. + *@param a_fp the destination file pointer. + *@param a_indent the number of white space indentation. + */ +void +cr_statement_dump_font_face_rule (CRStatement * a_this, FILE * a_fp, + glong a_indent) +{ + gchar *str = NULL ; + g_return_if_fail (a_this + && a_this->type == AT_FONT_FACE_RULE_STMT); + + str = cr_statement_font_face_rule_to_string (a_this, + a_indent) ; + if (str) { + fprintf (a_fp, "%s", str) ; + g_free (str) ; + str = NULL ; + } +} + +/** + *Dumps an @charset rule statement to a file. + *@param a_this the current instance of the @charset rule statement. + *@param a_fp the destination file pointer. + *@param a_indent the number of indentation white spaces. + */ +void +cr_statement_dump_charset (CRStatement * a_this, FILE * a_fp, gulong a_indent) +{ + guchar *str = NULL; + + g_return_if_fail (a_this && a_this->type == AT_CHARSET_RULE_STMT); + + str = cr_statement_charset_to_string (a_this, + a_indent) ; + if (str) { + fprintf (a_fp, str) ; + g_free (str) ; + str = NULL ; + } +} + + +/** + *Dumps an @page rule statement on stdout. + *@param a_this the statement to dump on stdout. + *@param a_fp the destination file pointer. + *@param a_indent the number of indentation white spaces. + */ +void +cr_statement_dump_page (CRStatement * a_this, FILE * a_fp, gulong a_indent) +{ + guchar *str = NULL; + + g_return_if_fail (a_this + && a_this->type == AT_PAGE_RULE_STMT + && a_this->kind.page_rule); + + str = cr_statement_at_page_rule_to_string (a_this, a_indent) ; + if (str) { + fprintf (a_fp, str); + g_free (str) ; + str = NULL ; + } +} + + +/** + *Dumps an @media rule statement to a file. + *@param a_this the statement to dump. + *@param a_fp the destination file pointer + *@param a_indent the number of white spaces indentation. + */ +void +cr_statement_dump_media_rule (CRStatement * a_this, + FILE * a_fp, + gulong a_indent) +{ + gchar *str = NULL ; + g_return_if_fail (a_this->type == AT_MEDIA_RULE_STMT); + + str = cr_statement_media_rule_to_string (a_this, a_indent) ; + if (str) { + fprintf (a_fp, str) ; + g_free (str) ; + str = NULL ; + } +} + +/** + *Dumps an @import rule statement to a file. + *@param a_fp the destination file pointer. + *@param a_indent the number of white space indentations. + */ +void +cr_statement_dump_import_rule (CRStatement * a_this, FILE * a_fp, + gulong a_indent) +{ + gchar *str = NULL ; + g_return_if_fail (a_this + && a_this->type == AT_IMPORT_RULE_STMT + && a_fp + && a_this->kind.import_rule); + + str = cr_statement_import_rule_to_string (a_this, a_indent) ; + if (str) { + fprintf (a_fp, str) ; + g_free (str) ; + str = NULL ; + } +} + +/** + *Destructor of #CRStatement. + */ +void +cr_statement_destroy (CRStatement * a_this) +{ + CRStatement *cur = NULL; + + g_return_if_fail (a_this); + + /*go get the tail of the list */ + for (cur = a_this; cur && cur->next; cur = cur->next) { + cr_statement_clear (cur); + } + + if (cur) + cr_statement_clear (cur); + + if (cur->prev == NULL) { + g_free (a_this); + return; + } + + /*walk backward and free next element */ + for (cur = cur->prev; cur && cur->prev; cur = cur->prev) { + if (cur->next) { + g_free (cur->next); + cur->next = NULL; + } + } + + if (!cur) + return; + + /*free the one remaining list */ + if (cur->next) { + g_free (cur->next); + cur->next = NULL; + } + + g_free (cur); + cur = NULL; +} diff --git a/src/libcroco/cr-statement.h b/src/libcroco/cr-statement.h new file mode 100644 index 000000000..5639ab730 --- /dev/null +++ b/src/libcroco/cr-statement.h @@ -0,0 +1,440 @@ +/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * Author: Dodji Seketeli + * See COPYRIGHTS file for copyright information. + */ + +#include +#include "cr-utils.h" +#include "cr-term.h" +#include "cr-selector.h" +#include "cr-declaration.h" + +#ifndef __CR_STATEMENT_H__ +#define __CR_STATEMENT_H__ + +G_BEGIN_DECLS + +/** + *@file + *Declaration of the #CRStatement class. + */ + +/* + *forward declaration of CRStyleSheet which is defined in + *cr-stylesheet.h + */ + +struct _CRStatement ; + +/* + *typedef struct _CRStatement CRStatement ; + *this is forward declared in + *cr-declaration.h already. + */ + +struct _CRAtMediaRule ; +typedef struct _CRAtMediaRule CRAtMediaRule ; + +typedef struct _CRRuleSet CRRuleSet ; + +/** + *The abstraction of a css ruleset. + *A ruleset is made of a list of selectors, + *followed by a list of declarations. + */ +struct _CRRuleSet +{ + /**A list of instances of #CRSimpeSel*/ + CRSelector *sel_list ; + + /**A list of instances of #CRDeclaration*/ + CRDeclaration *decl_list ; + + /** + *The parent media rule, or NULL if + *no parent media rule exists. + */ + CRStatement *parent_media_rule ; +} ; + +/* + *a forward declaration of CRStylesheet. + *CRStylesheet is actually declared in + *cr-stylesheet.h + */ +struct _CRStyleSheet ; +typedef struct _CRStyleSheet CRStyleSheet; + + +/**The @import rule abstraction.*/ +typedef struct _CRAtImportRule CRAtImportRule ; +struct _CRAtImportRule +{ + /**the url of the import rule*/ + CRString *url ; + + GList *media_list ; + + /** + *the stylesheet fetched from the url, if any. + *this is not "owned" by #CRAtImportRule which means + *it is not destroyed by the destructor of #CRAtImportRule. + */ + CRStyleSheet * sheet; +}; + + +/**abstraction of an @media rule*/ +struct _CRAtMediaRule +{ + GList *media_list ; + CRStatement *rulesets ; +} ; + + +typedef struct _CRAtPageRule CRAtPageRule ; +/**The @page rule abstraction*/ +struct _CRAtPageRule +{ + /**a list of instances of #CRDeclaration*/ + CRDeclaration *decl_list ; + + /**page selector. Is a pseudo selector*/ + CRString *name ; + CRString *pseudo ; +} ; + +/**The @charset rule abstraction*/ +typedef struct _CRAtCharsetRule CRAtCharsetRule ; +struct _CRAtCharsetRule +{ + CRString * charset ; +}; + +/**The abstaction of the @font-face rule.*/ +typedef struct _CRAtFontFaceRule CRAtFontFaceRule ; +struct _CRAtFontFaceRule +{ + /*a list of instanaces of #CRDeclaration*/ + CRDeclaration *decl_list ; +} ; + + +/** + *The possible types of css2 statements. + */ +enum CRStatementType +{ + /** + *A generic css at-rule + *each unknown at-rule will + *be of this type. + */ + + /**A css at-rule*/ + AT_RULE_STMT = 0, + + /*A css ruleset*/ + RULESET_STMT, + + /**A css2 import rule*/ + AT_IMPORT_RULE_STMT, + + /**A css2 media rule*/ + AT_MEDIA_RULE_STMT, + + /**A css2 page rule*/ + AT_PAGE_RULE_STMT, + + /**A css2 charset rule*/ + AT_CHARSET_RULE_STMT, + + /**A css2 font face rule*/ + AT_FONT_FACE_RULE_STMT +} ; + + +/** + *The abstraction of css statement as defined + *in the chapter 4 and appendix D.1 of the css2 spec. + *A statement is actually a double chained list of + *statements.A statement can be a ruleset, an @import + *rule, an @page rule etc ... + */ +struct _CRStatement +{ + /** + *The type of the statement. + */ + enum CRStatementType type ; + + union + { + CRRuleSet *ruleset ; + CRAtImportRule *import_rule ; + CRAtMediaRule *media_rule ; + CRAtPageRule *page_rule ; + CRAtCharsetRule *charset_rule ; + CRAtFontFaceRule *font_face_rule ; + } kind ; + + /* + *the specificity of the selector + *that matched this statement. + *This is only used by the cascading + *order determination algorithm. + */ + gulong specificity ; + + /* + *the style sheet that contains + *this css statement. + */ + CRStyleSheet *parent_sheet ; + CRStatement *next ; + CRStatement *prev ; + + CRParsingLocation location ; + + /** + *a custom pointer useable by + *applications that use libcroco. + *libcroco itself will never modify + *this pointer. + */ + gpointer app_data ; + + /** + *a custom pointer used + *by the upper layers of libcroco. + *application should never use this + *pointer. + */ + gpointer croco_data ; + +} ; + + +gboolean +cr_statement_does_buf_parses_against_core (const guchar *a_buf, + enum CREncoding a_encoding) ; +CRStatement * +cr_statement_parse_from_buf (const guchar *a_buf, + enum CREncoding a_encoding) ; +CRStatement* +cr_statement_new_ruleset (CRStyleSheet *a_sheet, + CRSelector *a_sel_list, + CRDeclaration *a_decl_list, + CRStatement *a_media_rule) ; +CRStatement * +cr_statement_ruleset_parse_from_buf (const guchar * a_buf, + enum CREncoding a_enc) ; + +CRStatement* +cr_statement_new_at_import_rule (CRStyleSheet *a_container_sheet, + CRString *a_url, + GList *a_media_list, + CRStyleSheet *a_imported_sheet) ; + +CRStatement * +cr_statement_at_import_rule_parse_from_buf (const guchar * a_buf, + enum CREncoding a_encoding) ; + +CRStatement * +cr_statement_new_at_media_rule (CRStyleSheet *a_sheet, + CRStatement *a_ruleset, + GList *a_media) ; +CRStatement * +cr_statement_at_media_rule_parse_from_buf (const guchar *a_buf, + enum CREncoding a_enc) ; + +CRStatement * +cr_statement_new_at_charset_rule (CRStyleSheet *a_sheet, + CRString *a_charset) ; +CRStatement * +cr_statement_at_charset_rule_parse_from_buf (const guchar *a_buf, + enum CREncoding a_encoding); + + +CRStatement * +cr_statement_new_at_font_face_rule (CRStyleSheet *a_sheet, + CRDeclaration *a_font_decls) ; +CRStatement * +cr_statement_font_face_rule_parse_from_buf (const guchar *a_buf, + enum CREncoding a_encoding) ; + +CRStatement * +cr_statement_new_at_page_rule (CRStyleSheet *a_sheet, + CRDeclaration *a_decl_list, + CRString *a_name, + CRString *a_pseudo) ; +CRStatement * +cr_statement_at_page_rule_parse_from_buf (const guchar *a_buf, + enum CREncoding a_encoding) ; + +enum CRStatus +cr_statement_set_parent_sheet (CRStatement *a_this, + CRStyleSheet *a_sheet) ; + +enum CRStatus +cr_statement_get_parent_sheet (CRStatement *a_this, + CRStyleSheet **a_sheet) ; + +CRStatement * +cr_statement_append (CRStatement *a_this, + CRStatement *a_new) ; + +CRStatement* +cr_statement_prepend (CRStatement *a_this, + CRStatement *a_new) ; + +CRStatement * +cr_statement_unlink (CRStatement *a_stmt) ; + +enum CRStatus +cr_statement_ruleset_set_sel_list (CRStatement *a_this, + CRSelector *a_sel_list) ; + +enum CRStatus +cr_statement_ruleset_get_sel_list (CRStatement *a_this, + CRSelector **a_list) ; + +enum CRStatus +cr_statement_ruleset_set_decl_list (CRStatement *a_this, + CRDeclaration *a_list) ; + +enum CRStatus +cr_statement_ruleset_get_declarations (CRStatement *a_this, + CRDeclaration **a_decl_list) ; + +enum CRStatus +cr_statement_ruleset_append_decl2 (CRStatement *a_this, + CRString *a_prop, CRTerm *a_value) ; + +enum CRStatus +cr_statement_ruleset_append_decl (CRStatement *a_this, + CRDeclaration *a_decl) ; + +enum CRStatus +cr_statement_at_import_rule_set_imported_sheet (CRStatement *a_this, + CRStyleSheet *a_sheet) ; + +enum CRStatus +cr_statement_at_import_rule_get_imported_sheet (CRStatement *a_this, + CRStyleSheet **a_sheet) ; + +enum CRStatus +cr_statement_at_import_rule_set_url (CRStatement *a_this, + CRString *a_url) ; + +enum CRStatus +cr_statement_at_import_rule_get_url (CRStatement *a_this, + CRString **a_url) ; + +gint +cr_statement_at_media_nr_rules (CRStatement *a_this) ; + +CRStatement * +cr_statement_at_media_get_from_list (CRStatement *a_this, int itemnr) ; + +enum CRStatus +cr_statement_at_page_rule_set_sel (CRStatement *a_this, + CRSelector *a_sel) ; + +enum CRStatus +cr_statement_at_page_rule_get_sel (CRStatement *a_this, + CRSelector **a_sel) ; + +enum CRStatus +cr_statement_at_page_rule_set_declarations (CRStatement *a_this, + CRDeclaration *a_decl_list) ; + +enum CRStatus +cr_statement_at_page_rule_get_declarations (CRStatement *a_this, + CRDeclaration **a_decl_list) ; + +enum CRStatus +cr_statement_at_charset_rule_set_charset (CRStatement *a_this, + CRString *a_charset) ; + +enum CRStatus +cr_statement_at_charset_rule_get_charset (CRStatement *a_this, + CRString **a_charset) ; + +enum CRStatus +cr_statement_at_font_face_rule_set_decls (CRStatement *a_this, + CRDeclaration *a_decls) ; + +enum CRStatus +cr_statement_at_font_face_rule_get_decls (CRStatement *a_this, + CRDeclaration **a_decls) ; + +enum CRStatus +cr_statement_at_font_face_rule_add_decl (CRStatement *a_this, + CRString *a_prop, + CRTerm *a_value) ; + +gchar * +cr_statement_to_string (CRStatement * a_this, gulong a_indent) ; + +gchar* +cr_statement_list_to_string (CRStatement *a_this, gulong a_indent) ; + +void +cr_statement_dump (CRStatement *a_this, FILE *a_fp, gulong a_indent) ; + +void +cr_statement_dump_ruleset (CRStatement * a_this, FILE * a_fp, + glong a_indent) ; + +void +cr_statement_dump_font_face_rule (CRStatement * a_this, + FILE * a_fp, + glong a_indent) ; + +void +cr_statement_dump_page (CRStatement * a_this, FILE * a_fp, + gulong a_indent) ; + + +void +cr_statement_dump_media_rule (CRStatement * a_this, + FILE * a_fp, + gulong a_indent) ; + +void +cr_statement_dump_import_rule (CRStatement * a_this, FILE * a_fp, + gulong a_indent) ; +void +cr_statement_dump_charset (CRStatement * a_this, FILE * a_fp, + gulong a_indent) ; +gint +cr_statement_nr_rules (CRStatement *a_this) ; + +CRStatement * +cr_statement_get_from_list (CRStatement *a_this, int itemnr) ; + +void +cr_statement_destroy (CRStatement *a_this) ; + +G_END_DECLS + +#endif /*__CR_STATEMENT_H__*/ diff --git a/src/libcroco/cr-string.c b/src/libcroco/cr-string.c new file mode 100644 index 000000000..2529b72be --- /dev/null +++ b/src/libcroco/cr-string.c @@ -0,0 +1,168 @@ +/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * Author: Dodji Seketeli. + * See COPYRIGHTS file for copyright information. + */ + +#include +#include "cr-string.h" + +/** + *Instanciates a #CRString + *@return the newly instanciated #CRString + *Must be freed with cr_string_destroy(). + */ +CRString * +cr_string_new (void) +{ + CRString *result = NULL ; + + result = g_try_malloc (sizeof (CRString)) ; + if (!result) { + cr_utils_trace_info ("Out of memory") ; + return NULL ; + } + memset (result, 0, sizeof (CRString)) ; + result->stryng = g_string_new (NULL) ; + return result ; +} + +/** + *Instanciate a string and initialise it to + *a_string. + *@param a_string the initial string + *@return the newly instanciated string. + */ +CRString * +cr_string_new_from_string (const gchar * a_string) +{ + CRString *result = NULL ; + + result = cr_string_new () ; + if (!result) { + cr_utils_trace_info ("Out of memory") ; + return NULL ; + } + if (a_string) + g_string_append (result->stryng, a_string) ; + return result ; +} + +/** + *Instanciates a #CRString from an instance of GString. + *@param a_string the input string that will be copied into + *the newly instanciated #CRString + *@return the newly instanciated #CRString. + */ +CRString * +cr_string_new_from_gstring (GString *a_string) +{ + CRString *result = NULL ; + + result = cr_string_new () ; + if (!result) { + cr_utils_trace_info ("Out of memory") ; + return NULL ; + } + if (a_string) { + result->stryng = g_string_new_len + (a_string->str, a_string->len) ; + } else { + result->stryng = g_string_new (NULL) ; + } + return result ; +} + +CRString * +cr_string_dup (CRString *a_this) +{ + CRString *result = NULL ; + g_return_val_if_fail (a_this, NULL) ; + + result = cr_string_new_from_gstring (a_this->stryng) ; + if (!result) { + cr_utils_trace_info ("Out of memory") ; + return NULL ; + } + cr_parsing_location_copy (&result->location, + &a_this->location) ; + return result ; +} + +gchar * +cr_string_dup2 (CRString *a_this) +{ + gchar *result = NULL ; + + g_return_val_if_fail (a_this, NULL) ; + + if (a_this + && a_this->stryng + && a_this->stryng->str) { + result = g_strndup (a_this->stryng->str, + a_this->stryng->len) ; + } + return result ; +} + +/** + *Returns a pointer to the internal raw NULL terminated string + *of the current instance of #CRString. + *@param a_this the current instance of #CRString + */ +const gchar * +cr_string_peek_raw_str (CRString *a_this) +{ + g_return_val_if_fail (a_this, NULL) ; + + if (a_this->stryng && a_this->stryng->str) + return a_this->stryng->str ; + return NULL ; +} + +/** + *Returns the length of the internal raw NULL terminated + *string of the current instance of #CRString. + *@param a_this the current instance of #CRString. + *@return the len of the internal raw NULL termninated string, + *of -1 if no length can be returned. + */ +gint +cr_string_peek_raw_str_len (CRString *a_this) +{ + g_return_val_if_fail (a_this && a_this->stryng, + -1) ; + return a_this->stryng->len ; +} + +/** + *@param a_this the #CRString to destroy. + */ +void +cr_string_destroy (CRString *a_this) +{ + g_return_if_fail (a_this) ; + + if (a_this->stryng) { + g_string_free (a_this->stryng, TRUE) ; + a_this->stryng = NULL ; + } + g_free (a_this) ; +} diff --git a/src/libcroco/cr-string.h b/src/libcroco/cr-string.h new file mode 100644 index 000000000..256453451 --- /dev/null +++ b/src/libcroco/cr-string.h @@ -0,0 +1,76 @@ +/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * See COPYRIGHTS file for copyright information. + */ + +/** + *@file + *Declaration file of the #CRString class. + */ + +#ifndef __CR_STRING_H__ +#define __CR_STRING_H__ + +#include +#include "cr-utils.h" +#include "cr-parsing-location.h" + +G_BEGIN_DECLS + +typedef struct _CRString CRString ; + +/** + *This is a ship implementation of string based on GString. + *Actually, the aim of CRString is to store the parsing location + *(line,column,byte offset) at which a given string has been parsed + *in the input CSS. + *So this class has a gstring field of type GString that users can + *freely manipulate, and also a CRParginLocation type where the + *parsing location is store. If you don't want to deal with parsing + *location stuffs, then use GString instead. If we were in C++ for example, + *CRString would just inherit GString and just add accessors to + *the CRParsingLocation data ... but we are not and we still have + *to provide the parsing location information. + */ +struct _CRString { + /** + *The GString where all the string + *operation happen. + */ + GString *stryng ; + /** + *The parsing location storage area. + */ + CRParsingLocation location ; +} ; + +CRString * cr_string_new (void) ; + +CRString *cr_string_new_from_string (const gchar * a_string) ; +CRString * cr_string_new_from_gstring (GString *a_string) ; +CRString *cr_string_dup (CRString *a_this) ; +gchar *cr_string_dup2 (CRString *a_this) ; +const gchar *cr_string_peek_raw_str (CRString *a_this) ; +gint cr_string_peek_raw_str_len (CRString *a_this) ; +void cr_string_destroy (CRString *a_this) ; + +G_END_DECLS + +#endif diff --git a/src/libcroco/cr-style.c b/src/libcroco/cr-style.c new file mode 100644 index 000000000..789d68f42 --- /dev/null +++ b/src/libcroco/cr-style.c @@ -0,0 +1,2851 @@ +/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of + * the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the + * GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * Author: Dodji Seketeli. + * see COPYRIGTHS file for copyright information + */ + +#include +#include "cr-style.h" + +/** + *@file + *The definition of the #CRStyle class. + */ + +/** + *A property ID. + *Each supported css property has an ID which is + *an entry into a property "population" jump table. + *each entry of the property population jump table + *contains code to tranform the literal form of + *a property value into a strongly typed value. + */ +enum CRPropertyID { + PROP_ID_NOT_KNOWN = 0, + PROP_ID_PADDING_TOP, + PROP_ID_PADDING_RIGHT, + PROP_ID_PADDING_BOTTOM, + PROP_ID_PADDING_LEFT, + PROP_ID_PADDING, + PROP_ID_BORDER_TOP_WIDTH, + PROP_ID_BORDER_RIGHT_WIDTH, + PROP_ID_BORDER_BOTTOM_WIDTH, + PROP_ID_BORDER_LEFT_WIDTH, + PROP_ID_BORDER_WIDTH, + PROP_ID_BORDER_TOP_STYLE, + PROP_ID_BORDER_RIGHT_STYLE, + PROP_ID_BORDER_BOTTOM_STYLE, + PROP_ID_BORDER_LEFT_STYLE, + PROP_ID_BORDER_STYLE, + PROP_ID_BORDER_TOP_COLOR, + PROP_ID_BORDER_RIGHT_COLOR, + PROP_ID_BORDER_BOTTOM_COLOR, + PROP_ID_BORDER_LEFT_COLOR, + PROP_ID_BORDER_TOP, + PROP_ID_BORDER_RIGHT, + PROP_ID_BORDER_BOTTOM, + PROP_ID_BORDER_LEFT, + PROP_ID_BORDER, + PROP_ID_MARGIN_TOP, + PROP_ID_MARGIN_RIGHT, + PROP_ID_MARGIN_BOTTOM, + PROP_ID_MARGIN_LEFT, + PROP_ID_MARGIN, + PROP_ID_DISPLAY, + PROP_ID_POSITION, + PROP_ID_TOP, + PROP_ID_RIGHT, + PROP_ID_BOTTOM, + PROP_ID_LEFT, + PROP_ID_FLOAT, + PROP_ID_WIDTH, + PROP_ID_COLOR, + PROP_ID_BACKGROUND_COLOR, + PROP_ID_FONT_FAMILY, + PROP_ID_FONT_SIZE, + PROP_ID_FONT_STYLE, + PROP_ID_FONT_WEIGHT, + PROP_ID_WHITE_SPACE, + /*should be the last one. */ + NB_PROP_IDS +}; + +typedef struct _CRPropertyDesc CRPropertyDesc; + +struct _CRPropertyDesc { + const guchar *name; + enum CRPropertyID prop_id; +}; + +static CRPropertyDesc gv_prop_table[] = { + {"padding-top", PROP_ID_PADDING_TOP}, + {"padding-right", PROP_ID_PADDING_RIGHT}, + {"padding-bottom", PROP_ID_PADDING_BOTTOM}, + {"padding-left", PROP_ID_PADDING_LEFT}, + {"padding", PROP_ID_PADDING}, + {"border-top-width", PROP_ID_BORDER_TOP_WIDTH}, + {"border-right-width", PROP_ID_BORDER_RIGHT_WIDTH}, + {"border-bottom-width", PROP_ID_BORDER_BOTTOM_WIDTH}, + {"border-left-width", PROP_ID_BORDER_LEFT_WIDTH}, + {"border-width", PROP_ID_BORDER_WIDTH}, + {"border-top-style", PROP_ID_BORDER_TOP_STYLE}, + {"border-right-style", PROP_ID_BORDER_RIGHT_STYLE}, + {"border-bottom-style", PROP_ID_BORDER_BOTTOM_STYLE}, + {"border-left-style", PROP_ID_BORDER_LEFT_STYLE}, + {"border-style", PROP_ID_BORDER_STYLE}, + {"border-top", PROP_ID_BORDER_TOP}, + {"border-right", PROP_ID_BORDER_RIGHT}, + {"border-bottom", PROP_ID_BORDER_BOTTOM}, + {"border-left", PROP_ID_BORDER_LEFT}, + {"border", PROP_ID_BORDER}, + {"margin-top", PROP_ID_MARGIN_TOP}, + {"margin-right", PROP_ID_MARGIN_RIGHT}, + {"margin-bottom", PROP_ID_MARGIN_BOTTOM}, + {"margin-left", PROP_ID_MARGIN_LEFT}, + {"margin", PROP_ID_MARGIN}, + {"display", PROP_ID_DISPLAY}, + {"position", PROP_ID_POSITION}, + {"top", PROP_ID_TOP}, + {"right", PROP_ID_RIGHT}, + {"bottom", PROP_ID_BOTTOM}, + {"left", PROP_ID_LEFT}, + {"float", PROP_ID_FLOAT}, + {"width", PROP_ID_WIDTH}, + {"color", PROP_ID_COLOR}, + {"border-top-color", PROP_ID_BORDER_TOP_COLOR}, + {"border-right-color", PROP_ID_BORDER_RIGHT_COLOR}, + {"border-bottom-color", PROP_ID_BORDER_BOTTOM_COLOR}, + {"border-left-color", PROP_ID_BORDER_LEFT_COLOR}, + {"background-color", PROP_ID_BACKGROUND_COLOR}, + {"font-family", PROP_ID_FONT_FAMILY}, + {"font-size", PROP_ID_FONT_SIZE}, + {"font-style", PROP_ID_FONT_STYLE}, + {"font-weight", PROP_ID_FONT_WEIGHT}, + {"white-space", PROP_ID_WHITE_SPACE}, + /*must be the last one */ + {NULL, 0} +}; + +/** + *A the key/value pair of this hash table + *are: + *key => name of the the css propertie found in gv_prop_table + *value => matching property id found in gv_prop_table. + *So this hash table is here just to retrieval of a property id + *from a property name. + */ +static GHashTable *gv_prop_hash = NULL; + +/** + *incremented by each new instance of #CRStyle + *and decremented at the it destroy time. + *When this reaches zero, gv_prop_hash is destroyed. + */ +static gulong gv_prop_hash_ref_count = 0; + +struct CRNumPropEnumDumpInfo { + enum CRNumProp code; + const gchar *str; +}; + +static struct CRNumPropEnumDumpInfo gv_num_props_dump_infos[] = { + {NUM_PROP_TOP, "top"}, + {NUM_PROP_RIGHT, "right"}, + {NUM_PROP_BOTTOM, "bottom"}, + {NUM_PROP_LEFT, "left"}, + {NUM_PROP_PADDING_TOP, "padding-top"}, + {NUM_PROP_PADDING_RIGHT, "padding-right"}, + {NUM_PROP_PADDING_BOTTOM, "padding-bottom"}, + {NUM_PROP_PADDING_LEFT, "padding-left"}, + {NUM_PROP_BORDER_TOP, "border-top"}, + {NUM_PROP_BORDER_RIGHT, "border-right"}, + {NUM_PROP_BORDER_BOTTOM, "border-bottom"}, + {NUM_PROP_BORDER_LEFT, "border-left"}, + {NUM_PROP_MARGIN_TOP, "margin-top"}, + {NUM_PROP_MARGIN_RIGHT, "margin-right"}, + {NUM_PROP_MARGIN_BOTTOM, "margin-bottom"}, + {NUM_PROP_MARGIN_LEFT, "margin-left"}, + {NUM_PROP_WIDTH, "width"}, + {0, NULL} +}; + +struct CRRgbPropEnumDumpInfo { + enum CRRgbProp code; + const gchar *str; +}; + +static struct CRRgbPropEnumDumpInfo gv_rgb_props_dump_infos[] = { + {RGB_PROP_BORDER_TOP_COLOR, "border-top-color"}, + {RGB_PROP_BORDER_RIGHT_COLOR, "border-right-color"}, + {RGB_PROP_BORDER_BOTTOM_COLOR, "bottom-color"}, + {RGB_PROP_BORDER_LEFT_COLOR, "left-color"}, + {RGB_PROP_COLOR, "color"}, + {RGB_PROP_BACKGROUND_COLOR, "background-color"}, + {0, NULL} +}; + +struct CRBorderStylePropEnumDumpInfo { + enum CRBorderStyleProp code; + const gchar *str; + +}; + +static struct CRBorderStylePropEnumDumpInfo gv_border_style_props_dump_infos[] + = { + {BORDER_STYLE_PROP_TOP, "border-style-top"}, + {BORDER_STYLE_PROP_RIGHT, "border-style-right"}, + {BORDER_STYLE_PROP_BOTTOM, "boder-style-bottom"}, + {BORDER_STYLE_PROP_LEFT, "border-style-left"}, + {0, NULL} +}; + +static enum CRStatus + cr_style_init_properties (void); + +enum CRDirection { + DIR_TOP = 0, + DIR_RIGHT, + DIR_BOTTOM, + DIR_LEFT, + + /*must be the last one */ + NB_DIRS +}; + +static const gchar *num_prop_code_to_string (enum CRNumProp a_code); + +static const gchar *rgb_prop_code_to_string (enum CRRgbProp a_code); + +static const gchar *border_style_prop_code_to_string (enum CRBorderStyleProp + a_code); + +static enum CRStatus +set_prop_padding_x_from_value (CRStyle * a_style, + CRTerm * a_value, enum CRDirection a_dir); + +static enum CRStatus +set_prop_border_x_width_from_value (CRStyle * a_style, + CRTerm * a_value, + enum CRDirection a_dir); +static enum CRStatus +set_prop_border_width_from_value (CRStyle *a_style, + CRTerm *a_value) ; + +static enum CRStatus +set_prop_border_x_style_from_value (CRStyle * a_style, + CRTerm * a_value, + enum CRDirection a_dir); +static enum CRStatus +set_prop_border_style_from_value (CRStyle *a_style, + CRTerm *a_value) ; + +static enum CRStatus +set_prop_margin_x_from_value (CRStyle * a_style, CRTerm * a_value, + enum CRDirection a_dir); + +static enum CRStatus +set_prop_display_from_value (CRStyle * a_style, CRTerm * a_value); + +static enum CRStatus +set_prop_position_from_value (CRStyle * a_style, CRTerm * a_value); + +static enum CRStatus +set_prop_x_from_value (CRStyle * a_style, CRTerm * a_value, + enum CRDirection a_dir); + +static enum CRStatus +set_prop_float (CRStyle * a_style, CRTerm * a_value); + +static enum CRStatus +set_prop_width (CRStyle * a_style, CRTerm * a_value); + +static enum CRStatus +set_prop_color (CRStyle * a_style, CRTerm * a_value); + +static enum CRStatus +set_prop_background_color (CRStyle * a_style, CRTerm * a_value); + +static enum CRStatus +set_prop_border_x_color_from_value (CRStyle * a_style, CRTerm * a_value, + enum CRDirection a_dir); + +static enum CRStatus +set_prop_border_x_from_value (CRStyle * a_style, CRTerm * a_value, + enum CRDirection a_dir); + +static enum CRStatus +set_prop_border_from_value (CRStyle * a_style, CRTerm * a_value); + +static enum CRStatus +set_prop_padding_from_value (CRStyle * a_style, CRTerm * a_value); + +static enum CRStatus +set_prop_margin_from_value (CRStyle * a_style, CRTerm * a_value); + +static enum CRStatus +set_prop_font_family_from_value (CRStyle * a_style, CRTerm * a_value); + +static enum CRStatus +init_style_font_size_field (CRStyle * a_style); + +static enum CRStatus +set_prop_font_size_from_value (CRStyle * a_style, CRTerm * a_value); + +static enum CRStatus +set_prop_font_style_from_value (CRStyle * a_style, CRTerm * a_value); + +static enum CRStatus +set_prop_font_weight_from_value (CRStyle * a_style, CRTerm * a_value); + +static const gchar * +num_prop_code_to_string (enum CRNumProp a_code) +{ + unsigned const len = sizeof (gv_num_props_dump_infos) / + sizeof (struct CRNumPropEnumDumpInfo); + if (a_code >= len) { + cr_utils_trace_info ("A field has been added " + "to 'enum CRNumProp' and no matching" + " entry has been " + "added to gv_num_prop_dump_infos table.\n" + "Please add the missing matching entry"); + return NULL; + } + if (gv_num_props_dump_infos[a_code].code != a_code) { + cr_utils_trace_info ("mismatch between the order of fields in" + " 'enum CRNumProp' and " + "the order of entries in " + "the gv_num_prop_dump_infos table"); + return NULL; + } + return gv_num_props_dump_infos[a_code].str; +} + +static const gchar * +rgb_prop_code_to_string (enum CRRgbProp a_code) +{ + unsigned const len = sizeof (gv_rgb_props_dump_infos) / + sizeof (struct CRRgbPropEnumDumpInfo); + + if (a_code >= len) { + cr_utils_trace_info ("A field has been added " + "to 'enum CRRgbProp' and no matching" + " entry has been " + "added to gv_rgb_prop_dump_infos table.\n" + "Please add the missing matching entry"); + return NULL; + } + if (gv_rgb_props_dump_infos[a_code].code != a_code) { + cr_utils_trace_info ("mismatch between the order of fields in" + " 'enum CRRgbProp' and " + "the order of entries in " + "the gv_rgb_props_dump_infos table"); + return NULL; + } + return gv_rgb_props_dump_infos[a_code].str; +} + +static const gchar * +border_style_prop_code_to_string (enum CRBorderStyleProp a_code) +{ + unsigned const len = sizeof (gv_border_style_props_dump_infos) / + sizeof (struct CRBorderStylePropEnumDumpInfo); + + if (a_code >= len) { + cr_utils_trace_info ("A field has been added " + "to 'enum CRBorderStyleProp' and no matching" + " entry has been " + "added to gv_border_style_prop_dump_infos table.\n" + "Please add the missing matching entry"); + return NULL; + } + if (gv_border_style_props_dump_infos[a_code].code != a_code) { + cr_utils_trace_info ("mismatch between the order of fields in" + " 'enum CRBorderStyleProp' and " + "the order of entries in " + "the gv_border_style_props_dump_infos table"); + return NULL; + } + return gv_border_style_props_dump_infos[a_code].str; +} + +static enum CRStatus +cr_style_init_properties (void) +{ + + if (!gv_prop_hash) { + gulong i = 0; + + gv_prop_hash = g_hash_table_new (g_str_hash, g_str_equal); + if (!gv_prop_hash) { + cr_utils_trace_info ("Out of memory"); + return CR_ERROR; + } + + /*load gv_prop_hash from gv_prop_table */ + for (i = 0; gv_prop_table[i].name; i++) { + g_hash_table_insert + (gv_prop_hash, + (gpointer) gv_prop_table[i].name, + GINT_TO_POINTER (gv_prop_table[i].prop_id)); + } + } + + return CR_OK; +} + +static enum CRPropertyID +cr_style_get_prop_id (const guchar * a_prop) +{ + gpointer *raw_id = NULL; + + if (!gv_prop_hash) { + cr_style_init_properties (); + } + + raw_id = g_hash_table_lookup (gv_prop_hash, a_prop); + if (!raw_id) { + return PROP_ID_NOT_KNOWN; + } + return GPOINTER_TO_INT (raw_id); +} + +static enum CRStatus +set_prop_padding_x_from_value (CRStyle * a_style, + CRTerm * a_value, enum CRDirection a_dir) +{ + enum CRStatus status = CR_OK; + CRNum *num_val = NULL; + + g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR); + + if (a_value->type != TERM_NUMBER && a_value->type != TERM_IDENT) + return CR_BAD_PARAM_ERROR; + + switch (a_dir) { + case DIR_TOP: + num_val = &a_style->num_props[NUM_PROP_PADDING_TOP].sv; + break; + + case DIR_RIGHT: + num_val = &a_style->num_props[NUM_PROP_PADDING_RIGHT].sv; + break; + + case DIR_BOTTOM: + num_val = &a_style->num_props[NUM_PROP_PADDING_BOTTOM].sv; + break; + + case DIR_LEFT: + num_val = &a_style->num_props[NUM_PROP_PADDING_LEFT].sv; + break; + + default: + return CR_BAD_PARAM_ERROR; + } + + if (a_value->type == TERM_IDENT) { + if (a_value->content.str + && a_value->content.str->stryng + && a_value->content.str->stryng->str + && !strncmp ((guchar *) "inherit", + a_value->content.str->stryng->str, + sizeof ("inherit")-1)) { + status = cr_num_set (num_val, 0.0, NUM_INHERIT); + return CR_OK; + } else + return CR_UNKNOWN_TYPE_ERROR; + } + + g_return_val_if_fail (a_value->type == TERM_NUMBER + && a_value->content.num, CR_UNKNOWN_TYPE_ERROR); + + switch (a_value->content.num->type) { + case NUM_LENGTH_EM: + case NUM_LENGTH_EX: + case NUM_LENGTH_PX: + case NUM_LENGTH_IN: + case NUM_LENGTH_CM: + case NUM_LENGTH_MM: + case NUM_LENGTH_PT: + case NUM_LENGTH_PC: + case NUM_PERCENTAGE: + status = cr_num_copy (num_val, a_value->content.num); + break; + default: + status = CR_UNKNOWN_TYPE_ERROR; + break; + } + + return status; +} + +static enum CRStatus +set_prop_border_x_width_from_value (CRStyle * a_style, + CRTerm * a_value, + enum CRDirection a_dir) +{ + enum CRStatus status = CR_OK; + CRNum *num_val = NULL; + + g_return_val_if_fail (a_value && a_style, CR_BAD_PARAM_ERROR); + + switch (a_dir) { + case DIR_TOP: + num_val = &a_style->num_props[NUM_PROP_BORDER_TOP].sv; + break; + + case DIR_RIGHT: + num_val = &a_style->num_props[NUM_PROP_BORDER_RIGHT].sv; + break; + + case DIR_BOTTOM: + num_val = &a_style->num_props[NUM_PROP_BORDER_BOTTOM].sv; + break; + + case DIR_LEFT: + num_val = &a_style->num_props[NUM_PROP_BORDER_LEFT].sv; + break; + + default: + return CR_BAD_PARAM_ERROR; + break; + } + + if (a_value->type == TERM_IDENT) { + if (a_value->content.str + && a_value->content.str->stryng + && a_value->content.str->stryng->str) { + if (!strncmp ("thin", + a_value->content.str->stryng->str, + sizeof ("thin")-1)) { + cr_num_set (num_val, BORDER_THIN, + NUM_LENGTH_PX); + } else if (!strncmp + ("medium", + a_value->content.str->stryng->str, + sizeof ("medium")-1)) { + cr_num_set (num_val, BORDER_MEDIUM, + NUM_LENGTH_PX); + } else if (!strncmp ("thick", + a_value->content.str->stryng->str, + sizeof ("thick")-1)) { + cr_num_set (num_val, BORDER_THICK, + NUM_LENGTH_PX); + } else { + return CR_UNKNOWN_TYPE_ERROR; + } + } + } else if (a_value->type == TERM_NUMBER) { + if (a_value->content.num) { + cr_num_copy (num_val, a_value->content.num); + } + } else if (a_value->type != TERM_NUMBER + || a_value->content.num == NULL) { + return CR_UNKNOWN_TYPE_ERROR; + } + + return status; +} + +static enum CRStatus +set_prop_border_width_from_value (CRStyle *a_style, + CRTerm *a_value) +{ + CRTerm *cur_term = NULL ; + enum CRDirection direction = DIR_TOP ; + + g_return_val_if_fail (a_style && a_value, + CR_BAD_PARAM_ERROR) ; + cur_term = a_value ; + + if (!cur_term) + return CR_ERROR ; + + for (direction = DIR_TOP ; + direction < NB_DIRS ; direction ++) { + set_prop_border_x_width_from_value (a_style, + cur_term, + direction) ; + } + + cur_term = cur_term->next ; + if (!cur_term) + return CR_OK ; + set_prop_border_x_width_from_value (a_style, cur_term, + DIR_RIGHT) ; + set_prop_border_x_width_from_value (a_style, cur_term, + DIR_LEFT) ; + + cur_term = cur_term->next ; + if (!cur_term) + return CR_OK ; + set_prop_border_x_width_from_value (a_style, cur_term, + DIR_BOTTOM) ; + + cur_term = cur_term->next ; + if (!cur_term) + return CR_OK ; + set_prop_border_x_width_from_value (a_style, cur_term, + DIR_LEFT) ; + + return CR_OK ; +} + +static enum CRStatus +set_prop_border_x_style_from_value (CRStyle * a_style, + CRTerm * a_value, enum CRDirection a_dir) +{ + enum CRStatus status = CR_OK; + enum CRBorderStyle *border_style_ptr = NULL; + + g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR); + + switch (a_dir) { + case DIR_TOP: + border_style_ptr = &a_style-> + border_style_props[BORDER_STYLE_PROP_TOP]; + break; + + case DIR_RIGHT: + border_style_ptr = + &a_style->border_style_props[BORDER_STYLE_PROP_RIGHT]; + break; + + case DIR_BOTTOM: + border_style_ptr = &a_style-> + border_style_props[BORDER_STYLE_PROP_BOTTOM]; + break; + + case DIR_LEFT: + border_style_ptr = &a_style-> + border_style_props[BORDER_STYLE_PROP_LEFT]; + break; + + default: + break; + } + + if (a_value->type != TERM_IDENT || !a_value->content.str) { + return CR_UNKNOWN_TYPE_ERROR; + } + + if (!strncmp ("none", + a_value->content.str->stryng->str, + sizeof ("none")-1)) { + *border_style_ptr = BORDER_STYLE_NONE; + } else if (!strncmp ("hidden", + a_value->content.str->stryng->str, + sizeof ("hidden")-1)) { + *border_style_ptr = BORDER_STYLE_HIDDEN; + } else if (!strncmp ("dotted", + a_value->content.str->stryng->str, + sizeof ("dotted")-1)) { + *border_style_ptr = BORDER_STYLE_DOTTED; + } else if (!strncmp ("dashed", + a_value->content.str->stryng->str, sizeof ("dashed")-1)) { + *border_style_ptr = BORDER_STYLE_DASHED; + } else if (!strncmp ("solid", + a_value->content.str->stryng->str, sizeof ("solid")-1)) { + *border_style_ptr = BORDER_STYLE_SOLID; + } else if (!strncmp ("double", + a_value->content.str->stryng->str, sizeof ("double")-1)) { + *border_style_ptr = BORDER_STYLE_DOUBLE; + } else if (!strncmp ("groove", + a_value->content.str->stryng->str, sizeof ("groove")-1)) { + *border_style_ptr = BORDER_STYLE_GROOVE; + } else if (!strncmp ("ridge", + a_value->content.str->stryng->str, + sizeof ("ridge")-1)) { + *border_style_ptr = BORDER_STYLE_RIDGE; + } else if (!strncmp ("inset", + a_value->content.str->stryng->str, + sizeof ("inset")-1)) { + *border_style_ptr = BORDER_STYLE_INSET; + } else if (!strncmp ("outset", + a_value->content.str->stryng->str, + sizeof ("outset")-1)) { + *border_style_ptr = BORDER_STYLE_OUTSET; + } else if (!strncmp ("inherit", + a_value->content.str->stryng->str, + sizeof ("inherit")-1)) { + *border_style_ptr = BORDER_STYLE_INHERIT; + } else { + status = CR_UNKNOWN_TYPE_ERROR; + } + + return status; +} + +static enum CRStatus +set_prop_border_style_from_value (CRStyle *a_style, + CRTerm *a_value) +{ + CRTerm *cur_term = NULL ; + enum CRDirection direction = DIR_TOP ; + + g_return_val_if_fail (a_style && a_value, + CR_BAD_PARAM_ERROR) ; + + cur_term = a_value ; + if (!cur_term || cur_term->type != TERM_IDENT) { + return CR_ERROR ; + } + + for (direction = DIR_TOP ; + direction < NB_DIRS ; + direction ++) { + set_prop_border_x_style_from_value (a_style, + cur_term, + direction) ; + } + + cur_term = cur_term->next ; + if (!cur_term || cur_term->type != TERM_IDENT) { + return CR_OK ; + } + + set_prop_border_x_style_from_value (a_style, cur_term, + DIR_RIGHT) ; + set_prop_border_x_style_from_value (a_style, cur_term, + DIR_LEFT) ; + + cur_term = cur_term->next ; + if (!cur_term || cur_term->type != TERM_IDENT) { + return CR_OK ; + } + set_prop_border_x_style_from_value (a_style, cur_term, + DIR_BOTTOM) ; + + cur_term = cur_term->next ; + if (!cur_term || cur_term->type != TERM_IDENT) { + return CR_OK ; + } + set_prop_border_x_style_from_value (a_style, cur_term, + DIR_LEFT) ; + return CR_OK ; +} + +static enum CRStatus +set_prop_margin_x_from_value (CRStyle * a_style, CRTerm * a_value, + enum CRDirection a_dir) +{ + enum CRStatus status = CR_OK; + CRNum *num_val = NULL; + + g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR); + + switch (a_dir) { + case DIR_TOP: + num_val = &a_style->num_props[NUM_PROP_MARGIN_TOP].sv; + break; + + case DIR_RIGHT: + num_val = &a_style->num_props[NUM_PROP_MARGIN_RIGHT].sv; + break; + + case DIR_BOTTOM: + num_val = &a_style->num_props[NUM_PROP_MARGIN_BOTTOM].sv; + break; + + case DIR_LEFT: + num_val = &a_style->num_props[NUM_PROP_MARGIN_LEFT].sv; + break; + + default: + break; + } + + switch (a_value->type) { + case TERM_IDENT: + if (a_value->content.str + && a_value->content.str->stryng + && a_value->content.str->stryng->str + && !strcmp (a_value->content.str->stryng->str, + "inherit")) { + status = cr_num_set (num_val, 0.0, NUM_INHERIT); + } else if (a_value->content.str + && a_value->content.str->stryng + && !strcmp (a_value->content.str->stryng->str, + "auto")) { + status = cr_num_set (num_val, 0.0, NUM_AUTO); + } else { + status = CR_UNKNOWN_TYPE_ERROR; + } + break ; + + case TERM_NUMBER: + status = cr_num_copy (num_val, a_value->content.num); + break; + + default: + status = CR_UNKNOWN_TYPE_ERROR; + break; + } + + return status; +} + +struct CRPropDisplayValPair { + const guchar *prop_name; + enum CRDisplayType type; +}; + +static enum CRStatus +set_prop_display_from_value (CRStyle * a_style, CRTerm * a_value) +{ + static const struct CRPropDisplayValPair disp_vals_map[] = { + {"none", DISPLAY_NONE}, + {"inline", DISPLAY_INLINE}, + {"block", DISPLAY_BLOCK}, + {"run-in", DISPLAY_RUN_IN}, + {"compact", DISPLAY_COMPACT}, + {"marker", DISPLAY_MARKER}, + {"table", DISPLAY_TABLE}, + {"inline-table", DISPLAY_INLINE_TABLE}, + {"table-row-group", DISPLAY_TABLE_ROW_GROUP}, + {"table-header-group", DISPLAY_TABLE_HEADER_GROUP}, + {"table-footer-group", DISPLAY_TABLE_FOOTER_GROUP}, + {"table-row", DISPLAY_TABLE_ROW}, + {"table-column-group", DISPLAY_TABLE_COLUMN_GROUP}, + {"table-column", DISPLAY_TABLE_COLUMN}, + {"table-cell", DISPLAY_TABLE_CELL}, + {"table-caption", DISPLAY_TABLE_CAPTION}, + {"inherit", DISPLAY_INHERIT}, + {NULL, DISPLAY_NONE} + }; + + g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR); + + switch (a_value->type) { + case TERM_IDENT: + { + int i = 0; + + if (!a_value->content.str + || !a_value->content.str->stryng + || !a_value->content.str->stryng->str) + break; + + for (i = 0; disp_vals_map[i].prop_name; i++) { + if (!strncmp + (disp_vals_map[i].prop_name, + a_value->content.str->stryng->str, + strlen (disp_vals_map[i].prop_name))) { + a_style->display = + disp_vals_map[i].type; + break; + } + } + } + break; + + default: + break; + } + + return CR_OK; +} + +struct CRPropPositionValPair { + const guchar *name; + enum CRPositionType type; +}; + +static enum CRStatus +set_prop_position_from_value (CRStyle * a_style, CRTerm * a_value) +{ + enum CRStatus status = CR_UNKNOWN_PROP_VAL_ERROR; + static const struct CRPropPositionValPair position_vals_map[] = { + {"static", POSITION_STATIC}, + {"relative", POSITION_RELATIVE}, + {"absolute", POSITION_ABSOLUTE}, + {"fixed", POSITION_FIXED}, + {"inherit", POSITION_INHERIT}, + {NULL, POSITION_STATIC} + /*must alwas be the last one */ + }; + + g_return_val_if_fail (a_value, CR_BAD_PARAM_ERROR); + + switch (a_value->type) { + case TERM_IDENT: + { + int i = 0; + + if (!a_value->content.str + || !a_value->content.str->stryng + || !a_value->content.str->stryng->str) + break; + + for (i = 0; position_vals_map[i].name; i++) { + if (!strncmp (position_vals_map[i].name, + a_value->content.str->stryng->str, + strlen (position_vals_map[i]. + name))) { + a_style->position = + position_vals_map[i].type; + status = CR_OK; + break; + } + } + } + break; + + default: + break; + } + + return CR_OK; +} + +static enum CRStatus +set_prop_x_from_value (CRStyle * a_style, CRTerm * a_value, + enum CRDirection a_dir) +{ + CRNum *box_offset = NULL; + + g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR); + + if (!(a_value->type == TERM_NUMBER) + && !(a_value->type == TERM_IDENT)) { + return CR_UNKNOWN_PROP_VAL_ERROR; + } + + switch (a_dir) { + case DIR_TOP: + box_offset = &a_style->num_props[NUM_PROP_TOP].sv; + break; + + case DIR_RIGHT: + box_offset = &a_style->num_props[NUM_PROP_RIGHT].sv; + break; + + case DIR_BOTTOM: + box_offset = &a_style->num_props[NUM_PROP_BOTTOM].sv; + break; + case DIR_LEFT: + box_offset = &a_style->num_props[NUM_PROP_LEFT].sv; + break; + + default: + break; + } + + box_offset->type = NUM_AUTO; + + if (a_value->type == TERM_NUMBER && a_value->content.num) { + cr_num_copy (box_offset, a_value->content.num); + } else if (a_value->type == TERM_IDENT + && a_value->content.str + && a_value->content.str->stryng + && a_value->content.str->stryng->str) { + if (!strncmp ("inherit", + a_value->content.str->stryng->str, + sizeof ("inherit")-1)) { + cr_num_set (box_offset, 0.0, NUM_INHERIT); + } else if (!strncmp ("auto", + a_value->content.str->stryng->str, + sizeof ("auto")-1)) { + box_offset->type = NUM_AUTO; + } + } + + return CR_OK; +} + +static enum CRStatus +set_prop_float (CRStyle * a_style, CRTerm * a_value) +{ + g_return_val_if_fail (a_style && a_value, + CR_BAD_PARAM_ERROR); + + /*the default float type as specified by the css2 spec */ + a_style->float_type = FLOAT_NONE; + + if (a_value->type != TERM_IDENT + || !a_value->content.str + || !a_value->content.str->stryng + || !a_value->content.str->stryng->str) { + /*unknow type, the float type is set to it's default value */ + return CR_OK; + } + + if (!strncmp ("none", + a_value->content.str->stryng->str, + sizeof ("none")-1)) { + a_style->float_type = FLOAT_NONE; + } else if (!strncmp ("left", + a_value->content.str->stryng->str, + sizeof ("left")-1)) { + a_style->float_type = FLOAT_LEFT; + } else if (!strncmp ("right", + a_value->content.str->stryng->str, + sizeof ("right")-1)) { + a_style->float_type = FLOAT_RIGHT; + } else if (!strncmp ("inherit", + a_value->content.str->stryng->str, + sizeof ("inherit")-1)) { + a_style->float_type = FLOAT_INHERIT; + } + return CR_OK; +} + +static enum CRStatus +set_prop_width (CRStyle * a_style, CRTerm * a_value) +{ + CRNum *width = NULL; + g_return_val_if_fail (a_style + && a_value, + CR_BAD_PARAM_ERROR); + + width = &a_style->num_props[NUM_PROP_WIDTH].sv; + cr_num_set (width, 0.0, NUM_AUTO); + + if (a_value->type == TERM_IDENT) { + if (a_value->content.str + && a_value->content.str->stryng + && a_value->content.str->stryng->str) { + if (!strncmp ("auto", + a_value->content.str->stryng->str, + sizeof ("auto")-1)) { + cr_num_set (width, 0.0, NUM_AUTO); + } else if (!strncmp ("inherit", + a_value->content.str->stryng->str, + sizeof ("inherit")-1)) { + cr_num_set (width, 0.0, NUM_INHERIT); + } + } + } else if (a_value->type == TERM_NUMBER) { + if (a_value->content.num) { + cr_num_copy (&a_style->num_props[NUM_PROP_WIDTH].sv, + a_value->content.num); + } + } + return CR_OK; +} + +static enum CRStatus +set_prop_color (CRStyle * a_style, CRTerm * a_value) +{ + enum CRStatus status = CR_OK; + CRRgb *a_rgb = &a_style->rgb_props[RGB_PROP_COLOR].sv; + + g_return_val_if_fail (a_style + && a_value, CR_BAD_PARAM_ERROR); + + status = cr_rgb_set_from_term (a_rgb, a_value); + + return status; +} + +static enum CRStatus +set_prop_background_color (CRStyle * a_style, CRTerm * a_value) +{ + enum CRStatus status = CR_OK; + CRRgb *rgb = &a_style->rgb_props[RGB_PROP_BACKGROUND_COLOR].sv; + + g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR); + + status = cr_rgb_set_from_term (rgb, a_value); + return status; +} + +/** + *Sets border-top-color, border-right-color, + *border-bottom-color or border-left-color properties + *in the style structure. The value is taken from a + *css2 term of type IDENT or RGB. + *@param a_style the style structure to set. + *@param a_value the css2 term to take the color information from. + *@param a_dir the direction (TOP, LEFT, RIGHT, or BOTTOM). + *@return CR_OK upon successfull completion, an error code otherwise. + */ +static enum CRStatus +set_prop_border_x_color_from_value (CRStyle * a_style, CRTerm * a_value, + enum CRDirection a_dir) +{ + CRRgb *rgb_color = NULL; + enum CRStatus status = CR_OK; + + g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR); + + switch (a_dir) { + case DIR_TOP: + rgb_color = &a_style->rgb_props[RGB_PROP_BORDER_TOP_COLOR].sv; + break; + + case DIR_RIGHT: + rgb_color = + &a_style->rgb_props[RGB_PROP_BORDER_RIGHT_COLOR].sv; + break; + + case DIR_BOTTOM: + rgb_color = + &a_style->rgb_props[RGB_PROP_BORDER_BOTTOM_COLOR].sv; + break; + + case DIR_LEFT: + rgb_color = + &a_style->rgb_props[RGB_PROP_BORDER_LEFT_COLOR].sv; + break; + + default: + cr_utils_trace_info ("unknown DIR type"); + return CR_BAD_PARAM_ERROR; + } + + status = CR_UNKNOWN_PROP_VAL_ERROR; + + if (a_value->type == TERM_IDENT) { + if (a_value->content.str + && a_value->content.str->stryng + && a_value->content.str->stryng->str) { + status = cr_rgb_set_from_name + (rgb_color, + a_value->content.str->stryng->str); + + } + if (status != CR_OK) { + cr_rgb_set_from_name (rgb_color, "black"); + } + } else if (a_value->type == TERM_RGB) { + if (a_value->content.rgb) { + status = cr_rgb_set_from_rgb + (rgb_color, a_value->content.rgb); + } + } + return status; +} + +static enum CRStatus +set_prop_border_x_from_value (CRStyle * a_style, CRTerm * a_value, + enum CRDirection a_dir) +{ + CRTerm *cur_term = NULL; + + enum CRStatus status = CR_OK; + + g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR); + + for (cur_term = a_value; + cur_term; + cur_term = cur_term->next) { + status = set_prop_border_x_width_from_value (a_style, + cur_term, a_dir); + + if (status != CR_OK) { + status = set_prop_border_x_style_from_value + (a_style, cur_term, a_dir); + } + if (status != CR_OK) { + status = set_prop_border_x_color_from_value + (a_style, cur_term, a_dir); + } + } + return CR_OK; +} + +static enum CRStatus +set_prop_border_from_value (CRStyle * a_style, CRTerm * a_value) +{ + enum CRDirection direction = 0; + + g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR); + + for (direction = 0; direction < NB_DIRS; direction++) { + set_prop_border_x_from_value (a_style, + a_value, + direction); + } + + return CR_OK; +} + +static enum CRStatus +set_prop_padding_from_value (CRStyle * a_style, CRTerm * a_value) +{ + CRTerm *cur_term = NULL; + enum CRDirection direction = 0; + enum CRStatus status = CR_OK; + + g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR); + + cur_term = a_value; + + /*filter the eventual non NUMBER terms some user can have written here*/ + while (cur_term && cur_term->type != TERM_NUMBER) { + cur_term = cur_term->next; + } + if (!cur_term) + return CR_ERROR ; + + for (direction = 0; direction < NB_DIRS; direction++) { + set_prop_padding_x_from_value (a_style, cur_term, direction); + } + cur_term = cur_term->next; + + /*filter non NUMBER terms that some users can have written here...*/ + while (cur_term && cur_term->type != TERM_NUMBER) { + cur_term = cur_term->next; + } + /*the user can have just written padding: 1px*/ + if (!cur_term) + return CR_OK; + + set_prop_padding_x_from_value (a_style, cur_term, DIR_RIGHT); + set_prop_padding_x_from_value (a_style, cur_term, DIR_LEFT); + + while (cur_term && cur_term->type != TERM_NUMBER) { + cur_term = cur_term->next; + } + if (!cur_term) + return CR_OK; + + set_prop_padding_x_from_value (a_style, cur_term, DIR_BOTTOM); + + while (cur_term && cur_term->type != TERM_NUMBER) { + cur_term = cur_term->next; + } + if (!cur_term) + return CR_OK; + status = set_prop_padding_x_from_value (a_style, cur_term, DIR_LEFT); + return status; +} + +static enum CRStatus +set_prop_margin_from_value (CRStyle * a_style, CRTerm * a_value) +{ + CRTerm *cur_term = NULL; + enum CRDirection direction = 0; + enum CRStatus status = CR_OK; + + g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR); + + cur_term = a_value; + + while (cur_term && cur_term->type != TERM_NUMBER) { + cur_term = cur_term->next; + } + + if (!cur_term) + return CR_OK; + + for (direction = 0; direction < NB_DIRS; direction++) { + set_prop_margin_x_from_value (a_style, cur_term, direction); + } + cur_term = cur_term->next; + + while (cur_term && cur_term->type != TERM_NUMBER) { + cur_term = cur_term->next; + } + if (!cur_term) + return CR_OK; + + set_prop_margin_x_from_value (a_style, cur_term, DIR_RIGHT); + set_prop_margin_x_from_value (a_style, cur_term, DIR_LEFT); + + while (cur_term && cur_term->type != TERM_NUMBER) { + cur_term = cur_term->next; + } + if (!cur_term) + return CR_OK; + + set_prop_margin_x_from_value (a_style, cur_term, DIR_BOTTOM); + + while (cur_term && cur_term->type != TERM_NUMBER) { + cur_term = cur_term->next; + } + if (!cur_term) + return CR_OK; + + status = set_prop_margin_x_from_value (a_style, cur_term, DIR_LEFT); + + return status; +} + +static enum CRStatus +set_prop_font_family_from_value (CRStyle * a_style, CRTerm * a_value) +{ + CRTerm *cur_term = NULL; + CRFontFamily *font_family = NULL, + *cur_ff = NULL, + *cur_ff2 = NULL; + + g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR); + + if (a_value->type == TERM_IDENT && + a_value->content.str && + a_value->content.str->stryng && + a_value->content.str->stryng->str && + !strcmp ("inherit", a_value->content.str->stryng->str)) + { + font_family = cr_font_family_new (FONT_FAMILY_INHERIT, NULL); + goto out; + } + + for (cur_term = a_value; cur_term; cur_term = cur_term->next) { + switch (cur_term->type) { + case TERM_IDENT: + { + enum CRFontFamilyType font_type; + + if (cur_term->content.str + && cur_term->content.str->stryng + && cur_term->content.str->stryng->str + && !strcmp + (cur_term->content.str->stryng->str, + "sans-serif")) { + font_type = FONT_FAMILY_SANS_SERIF; + } else if (cur_term->content.str + && cur_term->content.str->stryng + && cur_term->content.str->stryng->str + && !strcmp + (cur_term->content.str->stryng->str, + "serif")) { + font_type = FONT_FAMILY_SERIF; + } else if (cur_term->content.str + && cur_term->content.str->stryng + && cur_term->content.str->stryng->str + && !strcmp (cur_term->content.str->stryng->str, + "cursive")) { + font_type = FONT_FAMILY_CURSIVE; + } else if (cur_term->content.str + && cur_term->content.str->stryng + && cur_term->content.str->stryng->str + && !strcmp (cur_term->content.str->stryng->str, + "fantasy")) { + font_type = FONT_FAMILY_FANTASY; + } else if (cur_term->content.str + && cur_term->content.str->stryng + && cur_term->content.str->stryng->str + && !strcmp (cur_term->content.str->stryng->str, + "monospace")) { + font_type = FONT_FAMILY_MONOSPACE; + } else { + /* + *unknown property value. + *ignore it. + */ + continue; + } + + cur_ff = cr_font_family_new (font_type, NULL); + } + break; + + case TERM_STRING: + { + if (cur_term->content.str + && cur_term->content.str->stryng + && cur_term->content.str->stryng->str) { + cur_ff = cr_font_family_new + (FONT_FAMILY_NON_GENERIC, + cur_term->content.str->stryng->str); + } + } + break; + + default: + break; + } + + cur_ff2 = cr_font_family_append (font_family, cur_ff); + if (cur_ff2) { + font_family = cur_ff2; + } + } + + out: + if (font_family) { + if (a_style->font_family) { + cr_font_family_destroy (a_style->font_family); + a_style->font_family = NULL ; + } + a_style->font_family = font_family; + font_family = NULL ; + } + + return CR_OK; +} + +static enum CRStatus +init_style_font_size_field (CRStyle * a_style) +{ + g_return_val_if_fail (a_style, CR_BAD_PARAM_ERROR); + + memset (&a_style->font_size, 0, + sizeof (CRFontSizeVal)) ; + /* + if (!a_style->font_size) { + a_style->font_size = cr_font_size_new (); + if (!a_style->font_size) { + return CR_INSTANCIATION_FAILED_ERROR; + } + } else { + cr_font_size_clear (a_style->font_size); + } + */ + return CR_OK; +} + +static enum CRStatus +set_prop_font_size_from_value (CRStyle * a_style, CRTerm * a_value) +{ + enum CRStatus status = CR_OK; + + g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR); + + switch (a_value->type) { + case TERM_IDENT: + if (a_value->content.str + && a_value->content.str->stryng + && a_value->content.str->stryng->str + && !strcmp (a_value->content.str->stryng->str, + "xx-small")) { + status = init_style_font_size_field (a_style); + g_return_val_if_fail (status == CR_OK, status); + + a_style->font_size.sv.type = + PREDEFINED_ABSOLUTE_FONT_SIZE; + a_style->font_size.sv.value.predefined = + FONT_SIZE_XX_SMALL; + + } else if (a_value->content.str + && a_value->content.str->stryng + && a_value->content.str->stryng->str + && !strcmp (a_value->content.str->stryng->str, + "x-small")) { + status = init_style_font_size_field (a_style); + g_return_val_if_fail (status == CR_OK, status); + + a_style->font_size.sv.type = + PREDEFINED_ABSOLUTE_FONT_SIZE; + a_style->font_size.sv.value.predefined = + FONT_SIZE_X_SMALL; + } else if (a_value->content.str + && a_value->content.str->stryng + && a_value->content.str->stryng->str + && !strcmp (a_value->content.str->stryng->str, + "small")) { + status = init_style_font_size_field (a_style); + g_return_val_if_fail (status == CR_OK, status); + + a_style->font_size.sv.type = + PREDEFINED_ABSOLUTE_FONT_SIZE; + a_style->font_size.sv.value.predefined = + FONT_SIZE_SMALL; + } else if (a_value->content.str + && a_value->content.str->stryng + && a_value->content.str->stryng->str + && !strcmp (a_value->content.str->stryng->str, "medium")) { + status = init_style_font_size_field (a_style); + g_return_val_if_fail (status == CR_OK, status); + + a_style->font_size.sv.type = + PREDEFINED_ABSOLUTE_FONT_SIZE; + a_style->font_size.sv.value.predefined = + FONT_SIZE_MEDIUM; + } else if (a_value->content.str + && a_value->content.str->stryng + && a_value->content.str->stryng->str + && !strcmp (a_value->content.str->stryng->str, + "large")) { + status = init_style_font_size_field (a_style); + g_return_val_if_fail (status == CR_OK, status); + + a_style->font_size.sv.type = + PREDEFINED_ABSOLUTE_FONT_SIZE; + a_style->font_size.sv.value.predefined = + FONT_SIZE_LARGE; + } else if (a_value->content.str + && a_value->content.str->stryng + && a_value->content.str->stryng->str + && !strcmp (a_value->content.str->stryng->str, + "x-large")) { + status = init_style_font_size_field (a_style); + g_return_val_if_fail (status == CR_OK, status); + + a_style->font_size.sv.type = + PREDEFINED_ABSOLUTE_FONT_SIZE; + a_style->font_size.sv.value.predefined = + FONT_SIZE_X_LARGE; + } else if (a_value->content.str + && a_value->content.str->stryng + && a_value->content.str->stryng->str + && !strcmp (a_value->content.str->stryng->str, + "xx-large")) { + status = init_style_font_size_field (a_style); + g_return_val_if_fail (status == CR_OK, status); + + a_style->font_size.sv.type = + PREDEFINED_ABSOLUTE_FONT_SIZE; + a_style->font_size.sv.value.predefined = + FONT_SIZE_XX_LARGE; + } else if (a_value->content.str + && a_value->content.str->stryng + && a_value->content.str->stryng->str + && !strcmp (a_value->content.str->stryng->str, + "larger")) { + status = init_style_font_size_field (a_style); + g_return_val_if_fail (status == CR_OK, status); + + a_style->font_size.sv.type = RELATIVE_FONT_SIZE; + a_style->font_size.sv.value.relative = FONT_SIZE_LARGER; + } else if (a_value->content.str + && a_value->content.str->stryng + && a_value->content.str->stryng->str + && !strcmp (a_value->content.str->stryng->str, + "smaller")) { + status = init_style_font_size_field (a_style); + g_return_val_if_fail (status == CR_OK, status); + + a_style->font_size.sv.type = RELATIVE_FONT_SIZE; + a_style->font_size.sv.value.relative = + FONT_SIZE_SMALLER; + } else if (a_value->content.str + && a_value->content.str->stryng + && a_value->content.str->stryng->str + && !strcmp (a_value->content.str->stryng->str, "inherit")) { + status = init_style_font_size_field (a_style); + g_return_val_if_fail (status == CR_OK, status); + a_style->font_size.sv.type = INHERITED_FONT_SIZE; + + } else { + cr_utils_trace_info ("Unknow value of font-size") ; + status = init_style_font_size_field (a_style); + return CR_UNKNOWN_PROP_VAL_ERROR; + } + break; + + case TERM_NUMBER: + if (a_value->content.num) { + status = init_style_font_size_field (a_style); + g_return_val_if_fail (status == CR_OK, status); + + a_style->font_size.sv.type = ABSOLUTE_FONT_SIZE; + cr_num_copy (&a_style->font_size.sv.value.absolute, + a_value->content.num) ; + } + break; + + default: + status = init_style_font_size_field (a_style); + return CR_UNKNOWN_PROP_VAL_ERROR; + } + return CR_OK; +} + +static enum CRStatus +set_prop_font_style_from_value (CRStyle * a_style, CRTerm * a_value) +{ + enum CRStatus status = CR_OK; + + g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR); + + switch (a_value->type) { + case TERM_IDENT: + if (a_value->content.str + && a_value->content.str->stryng + && a_value->content.str->stryng->str) { + if (!strcmp (a_value->content.str->stryng->str, "normal")) { + a_style->font_style = FONT_STYLE_NORMAL; + } else if (!strcmp + (a_value->content.str->stryng->str, + "italic")) { + a_style->font_style = FONT_STYLE_ITALIC; + } else if (!strcmp + (a_value->content.str->stryng->str, + "oblique")) { + a_style->font_style = FONT_STYLE_OBLIQUE; + } else if (!strcmp + (a_value->content.str->stryng->str, + "inherit")) { + a_style->font_style = FONT_STYLE_INHERIT; + } else { + status = CR_UNKNOWN_PROP_VAL_ERROR; + } + } + break; + + default: + status = CR_UNKNOWN_PROP_VAL_ERROR; + break; + } + + return status; +} + +static enum CRStatus +set_prop_font_weight_from_value (CRStyle * a_style, CRTerm * a_value) +{ + enum CRStatus status = CR_OK; + + g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR); + + switch (a_value->type) { + case TERM_IDENT: + if (a_value->content.str + && a_value->content.str->stryng + && a_value->content.str->stryng->str) { + if (!strcmp (a_value->content.str->stryng->str, + "normal")) { + a_style->font_weight = FONT_WEIGHT_NORMAL; + } else if (!strcmp (a_value->content.str->stryng->str, + "bold")) { + a_style->font_weight = FONT_WEIGHT_BOLD; + } else if (!strcmp (a_value->content.str->stryng->str, + "bolder")) { + a_style->font_weight = FONT_WEIGHT_BOLDER; + } else if (!strcmp (a_value->content.str->stryng->str, + "lighter")) { + a_style->font_weight = FONT_WEIGHT_LIGHTER; + } else if (!strcmp (a_value->content.str->stryng->str, + "inherit")) { + a_style->font_weight = FONT_WEIGHT_INHERIT; + + } else { + status = CR_UNKNOWN_PROP_VAL_ERROR; + } + + } + break; + + case TERM_NUMBER: + if (a_value->content.num + && (a_value->content.num->type == NUM_GENERIC + || a_value->content.num->type == NUM_AUTO)) { + if (a_value->content.num->val <= 150) { + a_style->font_weight = FONT_WEIGHT_100; + } else if (a_value->content.num->val <= 250) { + a_style->font_weight = FONT_WEIGHT_200; + } else if (a_value->content.num->val <= 350) { + a_style->font_weight = FONT_WEIGHT_300; + } else if (a_value->content.num->val <= 450) { + a_style->font_weight = FONT_WEIGHT_400; + } else if (a_value->content.num->val <= 550) { + a_style->font_weight = FONT_WEIGHT_500; + } else if (a_value->content.num->val <= 650) { + a_style->font_weight = FONT_WEIGHT_600; + } else if (a_value->content.num->val <= 750) { + a_style->font_weight = FONT_WEIGHT_700; + } else if (a_value->content.num->val <= 850) { + a_style->font_weight = FONT_WEIGHT_800; + } else { + a_style->font_weight = FONT_WEIGHT_900; + } + } + break; + + default: + status = CR_UNKNOWN_PROP_VAL_ERROR; + break; + } + + return status; +} + +static enum CRStatus +set_prop_white_space_from_value (CRStyle * a_style, CRTerm * a_value) +{ + enum CRStatus status = CR_OK; + + g_return_val_if_fail (a_style && a_value, CR_BAD_PARAM_ERROR); + + switch (a_value->type) { + case TERM_IDENT: + if (a_value->content.str && a_value->content.str->stryng) { + if (!strcmp (a_value->content.str->stryng->str, "normal")) { + a_style->white_space = WHITE_SPACE_NORMAL; + } else if (!strcmp (a_value->content.str->stryng->str, + "pre")) { + a_style->font_weight = WHITE_SPACE_PRE; + } else if (!strcmp (a_value->content.str->stryng->str, + "nowrap")) { + a_style->white_space = WHITE_SPACE_NOWRAP; + } else if (!strcmp (a_value->content.str->stryng->str, + "inherit")) { + a_style->white_space = WHITE_SPACE_INHERIT; + } else { + status = CR_UNKNOWN_PROP_VAL_ERROR; + } + } + break; + default: + status = CR_UNKNOWN_PROP_VAL_ERROR; + break; + } + + return status; +} + +/****************** + *Public methods + ******************/ + +/** + *Default constructor of #CRStyle. + *@param a_set_props_to_initial_values if TRUE, the style properties + *will be set to the default values. Only the style properties of the + *root box should be set to their initial values. + *Otherwise, the style values are set to their default value. + *Read the CSS2 spec, chapters 6.1.1 to 6.2. + */ +CRStyle * +cr_style_new (gboolean a_set_props_to_initial_values) +{ + CRStyle *result = NULL; + + result = g_try_malloc (sizeof (CRStyle)); + if (!result) { + cr_utils_trace_info ("Out of memory"); + return NULL; + } + memset (result, 0, sizeof (CRStyle)); + gv_prop_hash_ref_count++; + + if (a_set_props_to_initial_values == TRUE) { + cr_style_set_props_to_initial_values (result); + } else { + cr_style_set_props_to_default_values (result); + } + + return result; +} + +/** + *Sets the style properties to their default values according to the css2 spec + * i.e inherit if the property is inherited, its initial value otherwise. + *@param a_this the current instance of #CRStyle. + *@return CR_OK upon successfull completion, an error code otherwise. + */ +enum CRStatus +cr_style_set_props_to_default_values (CRStyle * a_this) +{ + glong i = 0; + + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + for (i = 0; i < NB_NUM_PROPS; i++) + { + switch (i) + { + case NUM_PROP_WIDTH: + case NUM_PROP_TOP: + case NUM_PROP_RIGHT: + case NUM_PROP_BOTTOM: + case NUM_PROP_LEFT: + cr_num_set (&a_this->num_props[i].sv, 0, NUM_AUTO); + break; + + case NUM_PROP_PADDING_TOP: + case NUM_PROP_PADDING_RIGHT: + case NUM_PROP_PADDING_BOTTOM: + case NUM_PROP_PADDING_LEFT: + case NUM_PROP_BORDER_TOP: + case NUM_PROP_BORDER_RIGHT: + case NUM_PROP_BORDER_BOTTOM: + case NUM_PROP_BORDER_LEFT: + case NUM_PROP_MARGIN_TOP: + case NUM_PROP_MARGIN_RIGHT: + case NUM_PROP_MARGIN_BOTTOM: + case NUM_PROP_MARGIN_LEFT: + cr_num_set (&a_this->num_props[i].sv, + 0, NUM_LENGTH_PX); + break; + + default: + cr_utils_trace_info ("Unknown property"); + break; + } + } + + for (i = 0; i < NB_RGB_PROPS; i++) { + + switch (i) { + /*default foreground color is black */ + case RGB_PROP_COLOR: + /* + *REVIEW: color is inherited and the default value is + *ua dependant. + */ + cr_rgb_set_to_inherit (&a_this->rgb_props[i].sv, + TRUE) ; + break; + + /*default background color is white */ + case RGB_PROP_BACKGROUND_COLOR: + /* TODO: the default value should be transparent */ + cr_rgb_set (&a_this->rgb_props[i].sv, + 255, 255, 255, FALSE); + cr_rgb_set_to_transparent (&a_this->rgb_props[i].sv, + TRUE) ; + break; + + default: + /* + *TODO: for BORDER_COLOR the initial value should + * be the same as COLOR + */ + cr_rgb_set (&a_this->rgb_props[i].sv, 0, 0, 0, + FALSE); + break; + } + } + + for (i = 0; i < NB_BORDER_STYLE_PROPS; i++) { + a_this->border_style_props[i] = BORDER_STYLE_NONE; + } + + a_this->display = DISPLAY_INLINE; + a_this->position = POSITION_STATIC; + a_this->float_type = FLOAT_NONE; + a_this->parent_style = NULL; + a_this->font_style = FONT_STYLE_INHERIT; + a_this->font_variant = FONT_VARIANT_INHERIT; + a_this->font_weight = FONT_WEIGHT_INHERIT; + a_this->font_family = NULL; + + cr_font_size_set_to_inherit (&a_this->font_size.sv) ; + cr_font_size_clear (&a_this->font_size.cv) ; + cr_font_size_clear (&a_this->font_size.av) ; + + /* To make the inheritance resolution possible and efficient */ + a_this->inherited_props_resolved = FALSE ; + return CR_OK; +} + +/** + *Sets the style properties to their initial value according to the css2 spec. + *This function should be used to initialize the style of the root element + *of an xml tree. + *Some properties are user agent dependant like font-family, and + *are not initialized, read the spec to make you renderer compliant. + *@param a_this the current instance of #CRStyle. + *@return CR_OK upon successfull completion, an error code otherwise. + */ +enum CRStatus +cr_style_set_props_to_initial_values (CRStyle *a_this) +{ + glong i = 0; + + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + for (i = 0; i < NB_NUM_PROPS; i++) { + switch (i) { + case NUM_PROP_WIDTH: + cr_num_set (&a_this->num_props[i].sv, 800, + NUM_LENGTH_PX) ; + break ; + case NUM_PROP_TOP: + case NUM_PROP_RIGHT: + case NUM_PROP_BOTTOM: + case NUM_PROP_LEFT: + cr_num_set (&a_this->num_props[i].sv, 0, NUM_AUTO); + break; + + case NUM_PROP_PADDING_TOP: + case NUM_PROP_PADDING_RIGHT: + case NUM_PROP_PADDING_BOTTOM: + case NUM_PROP_PADDING_LEFT: + case NUM_PROP_BORDER_TOP: + case NUM_PROP_BORDER_RIGHT: + case NUM_PROP_BORDER_BOTTOM: + case NUM_PROP_BORDER_LEFT: + case NUM_PROP_MARGIN_TOP: + case NUM_PROP_MARGIN_RIGHT: + case NUM_PROP_MARGIN_BOTTOM: + case NUM_PROP_MARGIN_LEFT: + cr_num_set (&a_this->num_props[i].sv, + 0, NUM_LENGTH_PX); + break; + + default: + cr_utils_trace_info ("Unknown property"); + break; + } + } + + for (i = 0; i < NB_RGB_PROPS; i++) { + + switch (i) { + /*default foreground color is black */ + case RGB_PROP_COLOR: + cr_rgb_set (&a_this->rgb_props[i].sv, 0, 0, 0, FALSE); + break; + + /*default background color is white */ + case RGB_PROP_BACKGROUND_COLOR: + cr_rgb_set (&a_this->rgb_props[i].sv, + 255, 255, 255, FALSE); + cr_rgb_set_to_transparent (&a_this->rgb_props[i].sv, + TRUE) ; + break; + default: + cr_rgb_set (&a_this->rgb_props[i].sv, 0, 0, 0, FALSE); + break; + } + } + + for (i = 0; i < NB_BORDER_STYLE_PROPS; i++) { + a_this->border_style_props[i] = BORDER_STYLE_NONE; + } + + a_this->display = DISPLAY_BLOCK; + a_this->position = POSITION_STATIC; + a_this->float_type = FLOAT_NONE; + a_this->font_style = FONT_STYLE_NORMAL; + a_this->font_variant = FONT_VARIANT_NORMAL; + a_this->font_weight = FONT_WEIGHT_NORMAL; + a_this->font_stretch = FONT_STRETCH_NORMAL; + a_this->white_space = WHITE_SPACE_NORMAL; + cr_font_size_set_predefined_absolute_font_size + (&a_this->font_size.sv, FONT_SIZE_MEDIUM) ; + a_this->inherited_props_resolved = FALSE ; + + return CR_OK; +} + +/** + *Resolves the inherited properties. + *The function sets the "inherited" properties to either the value of + *their parent properties. + *This function is *NOT* recursive. So the inherited properties of + *the parent style must have been resolved prior to calling this function. + *@param a_this the instance where + *@return CR_OK if a root node is found and the propagation is successful, + *an error code otherwise + */ +enum CRStatus +cr_style_resolve_inherited_properties (CRStyle *a_this) +{ + enum CRStatus ret = CR_OK; + glong i = 0; + + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + g_return_val_if_fail (a_this->parent_style, CR_BAD_PARAM_ERROR) ; + + if (a_this->inherited_props_resolved == TRUE) + return CR_OK ; + + for (i=0 ; i < NB_NUM_PROPS ;i++) { + if (a_this->num_props[i].sv.type == NUM_INHERIT) { + cr_num_copy (&a_this->num_props[i].cv, + &a_this->parent_style->num_props[i].cv); + } + } + for (i=0; i < NB_RGB_PROPS; i++) { + if (cr_rgb_is_set_to_inherit (&a_this->rgb_props[i].sv) == TRUE) { + cr_rgb_copy ( + &a_this->rgb_props[i].cv, + &a_this->parent_style->rgb_props[i].cv); + } + } + for (i = 0; i < NB_BORDER_STYLE_PROPS; i++) { + if (a_this->border_style_props[i] == BORDER_STYLE_INHERIT) { + a_this->border_style_props[i] = + a_this->parent_style->border_style_props[i]; + } + } + + if (a_this->display == DISPLAY_INHERIT) { + a_this->display = a_this->parent_style->display; + } + if (a_this->position == POSITION_INHERIT) { + a_this->position = a_this->parent_style->position; + } + if (a_this->float_type == FLOAT_INHERIT) { + a_this->float_type = a_this->parent_style->float_type; + } + if (a_this->font_style == FONT_STYLE_INHERIT) { + a_this->font_style = a_this->parent_style->font_style; + } + if (a_this->font_variant == FONT_VARIANT_INHERIT) { + a_this->font_variant = a_this->parent_style->font_variant; + } + if (a_this->font_weight == FONT_WEIGHT_INHERIT) { + a_this->font_weight = a_this->parent_style->font_weight; + } + if (a_this->font_stretch == FONT_STRETCH_INHERIT) { + a_this->font_stretch = a_this->parent_style->font_stretch; + } + /*NULL is inherit marker for font_famiy*/ + if (a_this->font_family == NULL) { + a_this->font_family = a_this->parent_style->font_family; + } + if (a_this->font_size.sv.type == INHERITED_FONT_SIZE) { + cr_font_size_copy (&a_this->font_size.cv, + &a_this->parent_style->font_size.cv) ; + } + a_this->inherited_props_resolved = TRUE ; + return ret; +} + +/** + *Walks through a css2 property declaration, and populated the + *according field(s) in the #CRStyle structure. + *If the properties or their value(s) are/is not known, + *sets the corresponding field(s) of #CRStyle to its/their default + *value(s) + *@param a_this the instance of #CRStyle to set. + *@param a_decl the declaration from which the #CRStyle fields are set. + *@return CR_OK upon successfull completion, an error code otherwise. + */ +enum CRStatus +cr_style_set_style_from_decl (CRStyle * a_this, CRDeclaration * a_decl) +{ + CRTerm *value = NULL; + enum CRStatus status = CR_OK; + + enum CRPropertyID prop_id = PROP_ID_NOT_KNOWN; + + g_return_val_if_fail (a_this && a_decl + && a_decl + && a_decl->property + && a_decl->property->stryng + && a_decl->property->stryng->str, + CR_BAD_PARAM_ERROR); + + prop_id = cr_style_get_prop_id + (a_decl->property->stryng->str); + + value = a_decl->value; + switch (prop_id) { + case PROP_ID_PADDING_TOP: + status = set_prop_padding_x_from_value + (a_this, value, DIR_TOP); + break; + + case PROP_ID_PADDING_RIGHT: + status = set_prop_padding_x_from_value + (a_this, value, DIR_RIGHT); + break; + case PROP_ID_PADDING_BOTTOM: + status = set_prop_padding_x_from_value + (a_this, value, DIR_BOTTOM); + break; + + case PROP_ID_PADDING_LEFT: + status = set_prop_padding_x_from_value + (a_this, value, DIR_LEFT); + break; + + case PROP_ID_PADDING: + status = set_prop_padding_from_value (a_this, value) ; + break; + + case PROP_ID_BORDER_TOP_WIDTH: + status = set_prop_border_x_width_from_value (a_this, value, + DIR_TOP); + break; + + case PROP_ID_BORDER_RIGHT_WIDTH: + status = set_prop_border_x_width_from_value (a_this, value, + DIR_RIGHT); + break; + + case PROP_ID_BORDER_BOTTOM_WIDTH: + status = set_prop_border_x_width_from_value (a_this, value, + DIR_BOTTOM); + break; + + case PROP_ID_BORDER_LEFT_WIDTH: + status = set_prop_border_x_width_from_value (a_this, value, + DIR_LEFT); + break; + + case PROP_ID_BORDER_WIDTH: + status = set_prop_border_width_from_value (a_this, value) ; + break ; + + case PROP_ID_BORDER_TOP_STYLE: + status = set_prop_border_x_style_from_value (a_this, value, + DIR_TOP); + break; + + case PROP_ID_BORDER_RIGHT_STYLE: + status = set_prop_border_x_style_from_value (a_this, value, + DIR_RIGHT); + break; + + case PROP_ID_BORDER_BOTTOM_STYLE: + status = set_prop_border_x_style_from_value (a_this, value, + DIR_BOTTOM); + break; + + case PROP_ID_BORDER_LEFT_STYLE: + status = set_prop_border_x_style_from_value (a_this, value, + DIR_LEFT); + break; + + case PROP_ID_BORDER_STYLE: + status = set_prop_border_style_from_value (a_this, value) ; + break ; + + case PROP_ID_BORDER_TOP_COLOR: + status = set_prop_border_x_color_from_value (a_this, value, + DIR_TOP); + break; + + case PROP_ID_BORDER_RIGHT_COLOR: + status = set_prop_border_x_color_from_value (a_this, value, + DIR_RIGHT); + break; + + case PROP_ID_BORDER_BOTTOM_COLOR: + status = set_prop_border_x_color_from_value (a_this, value, + DIR_BOTTOM); + break; + + case PROP_ID_BORDER_LEFT_COLOR: + status = set_prop_border_x_color_from_value (a_this, value, + DIR_BOTTOM); + break; + + case PROP_ID_BORDER_TOP: + status = set_prop_border_x_from_value (a_this, value, + DIR_TOP); + break; + + case PROP_ID_BORDER_RIGHT: + status = set_prop_border_x_from_value (a_this, value, + DIR_RIGHT); + break; + + case PROP_ID_BORDER_BOTTOM: + status = set_prop_border_x_from_value (a_this, value, + DIR_BOTTOM); + break; + + case PROP_ID_BORDER_LEFT: + status = set_prop_border_x_from_value (a_this, value, + DIR_LEFT); + break; + + case PROP_ID_MARGIN_TOP: + status = set_prop_margin_x_from_value (a_this, value, + DIR_TOP); + break; + + case PROP_ID_BORDER: + status = set_prop_border_from_value (a_this, value); + break; + + case PROP_ID_MARGIN_RIGHT: + status = set_prop_margin_x_from_value (a_this, value, + DIR_RIGHT); + break; + + case PROP_ID_MARGIN_BOTTOM: + status = set_prop_margin_x_from_value (a_this, value, + DIR_BOTTOM); + break; + + case PROP_ID_MARGIN_LEFT: + status = set_prop_margin_x_from_value (a_this, value, + DIR_LEFT); + break; + + case PROP_ID_MARGIN: + status = set_prop_margin_from_value (a_this, value); + break; + + case PROP_ID_DISPLAY: + status = set_prop_display_from_value (a_this, value); + break; + + case PROP_ID_POSITION: + status = set_prop_position_from_value (a_this, value); + break; + + case PROP_ID_TOP: + status = set_prop_x_from_value (a_this, value, DIR_TOP); + break; + + case PROP_ID_RIGHT: + status = set_prop_x_from_value (a_this, value, DIR_RIGHT); + break; + + case PROP_ID_BOTTOM: + status = set_prop_x_from_value (a_this, value, DIR_BOTTOM); + break; + + case PROP_ID_LEFT: + status = set_prop_x_from_value (a_this, value, DIR_LEFT); + break; + + case PROP_ID_FLOAT: + status = set_prop_float (a_this, value); + break; + + case PROP_ID_WIDTH: + status = set_prop_width (a_this, value); + break; + + case PROP_ID_COLOR: + status = set_prop_color (a_this, value); + break; + + case PROP_ID_BACKGROUND_COLOR: + status = set_prop_background_color (a_this, value); + break; + + case PROP_ID_FONT_FAMILY: + status = set_prop_font_family_from_value (a_this, value); + break; + + case PROP_ID_FONT_SIZE: + status = set_prop_font_size_from_value (a_this, value); + break; + + case PROP_ID_FONT_STYLE: + status = set_prop_font_style_from_value (a_this, value); + break; + + case PROP_ID_FONT_WEIGHT: + status = set_prop_font_weight_from_value (a_this, value); + break; + + case PROP_ID_WHITE_SPACE: + status = set_prop_white_space_from_value(a_this, value); + break; + + default: + return CR_UNKNOWN_TYPE_ERROR; + + } + + return status; +} + +/** + *Increases the reference count + *of the current instance of #CRStyle. + *@param a_this the current instance of #CRStyle. + *@return CR_OK upon successfull completion, an error code + *otherwise. + */ +enum CRStatus +cr_style_ref (CRStyle * a_this) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + a_this->ref_count++; + return CR_OK; +} + +/** + *Decreases the reference count of + *the current instance of #CRStyle. + *If the reference count reaches 0, the + *instance of #CRStyle is destoyed. + *@param a_this the current instance of #CRStyle. + *@return TRUE if the instance has been destroyed, FALSE + *otherwise. + */ +gboolean +cr_style_unref (CRStyle * a_this) +{ + g_return_val_if_fail (a_this, FALSE); + + if (a_this->ref_count) + a_this->ref_count--; + + if (!a_this->ref_count) { + cr_style_destroy (a_this); + return TRUE; + } + + return FALSE; +} + +/** + *Duplicates the current instance of #CRStyle . + *The newly created instance of #CRStyle must be + *freed using cr_style_destroy (). + *@param a_this the current instance of #CRStyle. + *@return the newly duplicated instance of #CRStyle. + */ +CRStyle * +cr_style_dup (CRStyle * a_this) +{ + CRStyle *result = NULL; + + g_return_val_if_fail (a_this, NULL); + + result = cr_style_new (FALSE); + if (!result) { + cr_utils_trace_info ("Out of memory"); + return NULL; + } + cr_style_copy (result, a_this); + return result; +} + +/** + *Copies a style data structure into another. + *TODO: this is actually broken because it's based + *on memcpy although some data stuctures of CRStyle should + *be properly duplicated. + *@param a_dest the destination style datastructure + *@param a_src the source style datastructure. + *@return CR_OK upon succesfull completion, an error code otherwise + */ +enum CRStatus +cr_style_copy (CRStyle * a_dest, CRStyle * a_src) +{ + g_return_val_if_fail (a_dest && a_src, CR_BAD_PARAM_ERROR); + + memcpy (a_dest, a_src, sizeof (CRStyle)); + return CR_OK; +} + +/** + *dump a CRNumpPropVal in a string. + *@param a_prop_val the numerical property value to dump + *@param a_str the string to dump the numerical propertie into. + *Note that the string value is appended to a_str. + *@param a_nb_indent the number white chars of indentation. + */ +enum CRStatus +cr_style_num_prop_val_to_string (CRNumPropVal * a_prop_val, + GString * a_str, guint a_nb_indent) +{ + enum CRStatus status = CR_OK; + guchar *tmp_str = NULL; + GString *str = NULL; + + g_return_val_if_fail (a_prop_val && a_str, CR_BAD_PARAM_ERROR); + + str = g_string_new (NULL); + cr_utils_dump_n_chars2 (' ', str, a_nb_indent); + g_string_append (str, "NumPropVal {"); + tmp_str = cr_num_to_string (&a_prop_val->sv); + if (!tmp_str) { + status = CR_ERROR; + goto cleanup; + } + g_string_append_printf (str, "sv: %s ", tmp_str); + g_free (tmp_str); + tmp_str = NULL; + + tmp_str = cr_num_to_string (&a_prop_val->cv); + if (!tmp_str) { + status = CR_ERROR; + goto cleanup; + } + g_string_append_printf (str, "cv: %s ", tmp_str); + g_free (tmp_str); + tmp_str = NULL; + + tmp_str = cr_num_to_string (&a_prop_val->av); + if (!tmp_str) { + status = CR_ERROR; + goto cleanup; + } + g_string_append_printf (str, "av: %s ", tmp_str); + g_free (tmp_str); + tmp_str = NULL; + g_string_append (str, "}"); + g_string_append (a_str, str->str); + status = CR_OK; + cleanup: + + if (tmp_str) { + g_free (tmp_str); + tmp_str = NULL; + } + if (str) { + g_string_free (str, TRUE); + } + return status; +} + +enum CRStatus +cr_style_rgb_prop_val_to_string (CRRgbPropVal * a_prop_val, + GString * a_str, guint a_nb_indent) +{ + enum CRStatus status = CR_OK; + guchar *tmp_str = NULL; + GString *str = NULL; + + g_return_val_if_fail (a_prop_val && a_str, CR_BAD_PARAM_ERROR); + + str = g_string_new (NULL); + + cr_utils_dump_n_chars2 (' ', str, a_nb_indent); + g_string_append (str, "RGBPropVal {"); + tmp_str = cr_rgb_to_string (&a_prop_val->sv); + if (!tmp_str) { + status = CR_ERROR; + goto cleanup; + } + g_string_append_printf (str, "sv: %s ", tmp_str); + g_free (tmp_str); + tmp_str = NULL; + tmp_str = cr_rgb_to_string (&a_prop_val->cv); + if (!tmp_str) { + status = CR_ERROR; + goto cleanup; + } + g_string_append_printf (str, "cv: %s ", tmp_str); + g_free (tmp_str); + tmp_str = NULL; + tmp_str = cr_rgb_to_string (&a_prop_val->av); + if (!tmp_str) { + status = CR_ERROR; + goto cleanup; + } + g_string_append_printf (str, "av: %s ", tmp_str); + g_free (tmp_str); + tmp_str = NULL; + + g_string_append (str, "}"); + g_string_append (a_str, str->str); + status = CR_OK; + cleanup: + + if (tmp_str) { + g_free (tmp_str); + tmp_str = NULL; + } + if (str) { + g_string_free (str, TRUE); + } + return status; +} + +enum CRStatus +cr_style_border_style_to_string (enum CRBorderStyle a_prop, + GString * a_str, guint a_nb_indent) +{ + gchar *str = NULL; + + g_return_val_if_fail (a_str, CR_BAD_PARAM_ERROR); + + switch (a_prop) { + case BORDER_STYLE_NONE: + str = (gchar *) "border-style-none"; + break; + case BORDER_STYLE_HIDDEN: + str = (gchar *) "border-style-hidden"; + break; + case BORDER_STYLE_DOTTED: + str = (gchar *) "border-style-dotted"; + break; + case BORDER_STYLE_DASHED: + str = (gchar *) "border-style-dashed"; + break; + case BORDER_STYLE_SOLID: + str = (gchar *) "border-style-solid"; + break; + case BORDER_STYLE_DOUBLE: + str = (gchar *) "border-style-double"; + break; + case BORDER_STYLE_GROOVE: + str = (gchar *) "border-style-groove"; + break; + case BORDER_STYLE_RIDGE: + str = (gchar *) "border-style-ridge"; + break; + case BORDER_STYLE_INSET: + str = (gchar *) "border-style-inset"; + break; + case BORDER_STYLE_OUTSET: + str = (gchar *) "border-style-outset"; + break; + default: + str = (gchar *) "unknown border style"; + break; + } + cr_utils_dump_n_chars2 (' ', a_str, a_nb_indent); + g_string_append (a_str, str); + return CR_OK; +} + +enum CRStatus +cr_style_display_type_to_string (enum CRDisplayType a_code, + GString * a_str, guint a_nb_indent) +{ + gchar *str = NULL; + + g_return_val_if_fail (a_str, CR_BAD_PARAM_ERROR); + + switch (a_code) { + case DISPLAY_NONE: + str = (gchar *) "display-none"; + break; + case DISPLAY_INLINE: + str = (gchar *) "display-inline"; + break; + case DISPLAY_BLOCK: + str = (gchar *) "display-block"; + break; + case DISPLAY_LIST_ITEM: + str = (gchar *) "display-list-item"; + break; + case DISPLAY_RUN_IN: + str = (gchar *) "display-run-in"; + break; + case DISPLAY_COMPACT: + str = (gchar *) "display-compact"; + break; + case DISPLAY_MARKER: + str = (gchar *) "display-marker"; + break; + case DISPLAY_TABLE: + str = (gchar *) "display-table"; + break; + case DISPLAY_INLINE_TABLE: + str = (gchar *) "display-inline-table"; + break; + case DISPLAY_TABLE_ROW_GROUP: + str = (gchar *) "display-table-row-group"; + break; + case DISPLAY_TABLE_HEADER_GROUP: + str = (gchar *) "display-table-header-group"; + break; + case DISPLAY_TABLE_FOOTER_GROUP: + str = (gchar *) "display-table-footer-group"; + break; + case DISPLAY_TABLE_ROW: + str = (gchar *) "display-table-row"; + break; + case DISPLAY_TABLE_COLUMN_GROUP: + str = (gchar *) "display-table-column-group"; + break; + case DISPLAY_TABLE_COLUMN: + str = (gchar *) "display-table-column"; + break; + case DISPLAY_TABLE_CELL: + str = (gchar *) "display-table-cell"; + break; + case DISPLAY_TABLE_CAPTION: + str = (gchar *) "display-table-caption"; + break; + case DISPLAY_INHERIT: + str = (gchar *) "display-inherit"; + break; + default: + str = (gchar *) "unknown display property"; + break; + } + cr_utils_dump_n_chars2 (' ', a_str, a_nb_indent); + g_string_append (a_str, str); + return CR_OK; + +} + +enum CRStatus +cr_style_position_type_to_string (enum CRPositionType a_code, + GString * a_str, guint a_nb_indent) +{ + gchar *str = NULL; + + g_return_val_if_fail (a_str, CR_BAD_PARAM_ERROR); + + switch (a_code) { + case POSITION_STATIC: + str = (gchar *) "position-static"; + break; + case POSITION_RELATIVE: + str = (gchar *) "position-relative"; + break; + case POSITION_ABSOLUTE: + str = (gchar *) "position-absolute"; + break; + case POSITION_FIXED: + str = (gchar *) "position-fixed"; + break; + case POSITION_INHERIT: + str = (gchar *) "position-inherit"; + break; + default: + str = (gchar *) "unknown static property"; + } + cr_utils_dump_n_chars2 (' ', a_str, a_nb_indent); + g_string_append (a_str, str); + return CR_OK; +} + +enum CRStatus +cr_style_float_type_to_string (enum CRFloatType a_code, + GString * a_str, guint a_nb_indent) +{ + gchar *str = NULL; + + g_return_val_if_fail (a_str, CR_BAD_PARAM_ERROR); + + switch (a_code) { + case FLOAT_NONE: + str = (gchar *) "float-none"; + break; + case FLOAT_LEFT: + str = (gchar *) "float-left"; + break; + case FLOAT_RIGHT: + str = (gchar *) "float-right"; + break; + case FLOAT_INHERIT: + str = (gchar *) "float-inherit"; + break; + default: + str = (gchar *) "unknown float property value"; + break; + } + cr_utils_dump_n_chars2 (' ', a_str, a_nb_indent); + g_string_append (a_str, str); + return CR_OK; +} + +enum CRStatus +cr_style_white_space_type_to_string (enum CRWhiteSpaceType a_code, + GString * a_str, guint a_nb_indent) +{ + gchar *str = NULL; + + g_return_val_if_fail (a_str, CR_BAD_PARAM_ERROR); + + switch (a_code) { + case WHITE_SPACE_NORMAL: + str = (gchar *) "normal"; + break; + case WHITE_SPACE_PRE: + str = (gchar *) "pre"; + break; + case WHITE_SPACE_NOWRAP: + str = (gchar *) "nowrap"; + break; + case WHITE_SPACE_INHERIT: + str = (gchar *) "inherited"; + break; + default: + str = (gchar *) "unknow white space property value"; + break; + } + cr_utils_dump_n_chars2 (' ', a_str, a_nb_indent); + g_string_append (a_str, str); + return CR_OK; +} + +/** + *Serializes in instance of #CRStyle into + *a string + *@param a_this the instance of #CRStyle to serialize + *@param a_str the string to serialise the style into. + *if *a_str is NULL, a new GString is instanciated, otherwise + *the style serialisation is appended to the existed *a_str + *@param the number of white space char to use for indentation. + *@return CR_OK upon successful completion, an error code otherwise. + */ +enum CRStatus +cr_style_to_string (CRStyle * a_this, GString ** a_str, guint a_nb_indent) +{ + const gint INTERNAL_INDENT = 2; + gint indent = a_nb_indent + INTERNAL_INDENT; + gchar *tmp_str = NULL; + GString *str = NULL; + gint i = 0; + + g_return_val_if_fail (a_this && a_str, CR_BAD_PARAM_ERROR); + + if (!*a_str) { + str = g_string_new (NULL); + } else { + str = *a_str; + } + cr_utils_dump_n_chars2 (' ', str, a_nb_indent); + g_string_append (str, "style {\n"); + + /*loop over the num_props and to_string() them */ + for (i = NUM_PROP_TOP; i < NB_NUM_PROPS; i++) { + /* + *to_string() the name of the num_prop + *(using num_prop_code_to_string) + *before outputing it value + */ + cr_utils_dump_n_chars2 (' ', str, indent); + tmp_str = (gchar *) num_prop_code_to_string (i); + if (tmp_str) { + g_string_append_printf (str, "%s: ", tmp_str); + } else { + g_string_append (str, "NULL"); + } + tmp_str = NULL; + cr_style_num_prop_val_to_string (&a_this->num_props[i], str, + a_nb_indent + + INTERNAL_INDENT); + g_string_append (str, "\n"); + } + /*loop over the rgb_props and to_string() them all */ + for (i = RGB_PROP_BORDER_TOP_COLOR; i < NB_RGB_PROPS; i++) { + tmp_str = (gchar *) rgb_prop_code_to_string (i); + cr_utils_dump_n_chars2 (' ', str, indent); + if (tmp_str) { + g_string_append_printf (str, "%s: ", tmp_str); + } else { + g_string_append (str, "NULL: "); + } + tmp_str = NULL; + cr_style_rgb_prop_val_to_string (&a_this->rgb_props[i], str, + a_nb_indent + + INTERNAL_INDENT); + g_string_append (str, "\n"); + } + /*loop over the border_style_props and to_string() them */ + for (i = BORDER_STYLE_PROP_TOP; i < NB_BORDER_STYLE_PROPS; i++) { + tmp_str = (gchar *) border_style_prop_code_to_string (i); + cr_utils_dump_n_chars2 (' ', str, indent); + if (tmp_str) { + g_string_append_printf (str, "%s: ", tmp_str); + } else { + g_string_append (str, "NULL: "); + } + tmp_str = NULL; + cr_style_border_style_to_string (a_this-> + border_style_props[i], str, + 0); + g_string_append (str, "\n"); + } + cr_utils_dump_n_chars2 (' ', str, indent); + g_string_append (str, "display: "); + cr_style_display_type_to_string (a_this->display, str, 0); + g_string_append (str, "\n"); + + cr_utils_dump_n_chars2 (' ', str, indent); + g_string_append (str, "position: "); + cr_style_position_type_to_string (a_this->position, str, 0); + g_string_append (str, "\n"); + + cr_utils_dump_n_chars2 (' ', str, indent); + g_string_append (str, "float-type: "); + cr_style_float_type_to_string (a_this->float_type, str, 0); + g_string_append (str, "\n"); + + cr_utils_dump_n_chars2 (' ', str, indent); + g_string_append (str, "white-space: "); + cr_style_white_space_type_to_string (a_this->white_space, str, 0); + g_string_append (str, "\n"); + + cr_utils_dump_n_chars2 (' ', str, indent); + g_string_append (str, "font-family: "); + tmp_str = cr_font_family_to_string (a_this->font_family, TRUE); + if (tmp_str) { + g_string_append (str, tmp_str); + g_free (tmp_str); + tmp_str = NULL; + } else { + g_string_append (str, "NULL"); + } + g_string_append (str, "\n"); + + cr_utils_dump_n_chars2 (' ', str, indent); + tmp_str = cr_font_size_to_string (&a_this->font_size.sv); + if (tmp_str) { + g_string_append_printf (str, "font-size {sv:%s, ", + tmp_str) ; + } else { + g_string_append (str, "font-size {sv:NULL, "); + } + tmp_str = cr_font_size_to_string (&a_this->font_size.cv); + if (tmp_str) { + g_string_append_printf (str, "cv:%s, ", tmp_str); + } else { + g_string_append (str, "cv:NULL, "); + } + tmp_str = cr_font_size_to_string (&a_this->font_size.av); + if (tmp_str) { + g_string_append_printf (str, "av:%s}", tmp_str); + } else { + g_string_append (str, "av:NULL}"); + } + + tmp_str = NULL; + g_string_append (str, "\n"); + + cr_utils_dump_n_chars2 (' ', str, indent); + tmp_str = cr_font_size_adjust_to_string (a_this->font_size_adjust); + if (tmp_str) { + g_string_append_printf (str, "font-size-adjust: %s", tmp_str); + } else { + g_string_append (str, "font-size-adjust: NULL"); + } + tmp_str = NULL; + g_string_append (str, "\n"); + + cr_utils_dump_n_chars2 (' ', str, indent); + tmp_str = (gchar *) cr_font_style_to_string (a_this->font_style); + if (tmp_str) { + g_string_append_printf (str, "font-style: %s", tmp_str); + } else { + g_string_append (str, "font-style: NULL"); + } + tmp_str = NULL; + g_string_append (str, "\n"); + + cr_utils_dump_n_chars2 (' ', str, indent); + tmp_str = (gchar *) cr_font_variant_to_string (a_this->font_variant); + if (tmp_str) { + g_string_append_printf (str, "font-variant: %s", tmp_str); + } else { + g_string_append (str, "font-variant: NULL"); + } + tmp_str = NULL; + g_string_append (str, "\n"); + + cr_utils_dump_n_chars2 (' ', str, indent); + tmp_str = (gchar *) cr_font_weight_to_string (a_this->font_weight); + if (tmp_str) { + g_string_append_printf (str, "font-weight: %s", tmp_str); + } else { + g_string_append (str, "font-weight: NULL"); + } + tmp_str = NULL; + g_string_append (str, "\n"); + + cr_utils_dump_n_chars2 (' ', str, indent); + tmp_str = (gchar *) cr_font_stretch_to_string (a_this->font_stretch); + if (tmp_str) { + g_string_append_printf (str, "font-stretch: %s", tmp_str); + } else { + g_string_append (str, "font-stretch: NULL"); + } + tmp_str = NULL; + g_string_append (str, "\n"); + + + cr_utils_dump_n_chars2 (' ', str, a_nb_indent); + g_string_append (str, "}"); + + return CR_OK; +} + +/** + *Destructor of the #CRStyle class. + *@param a_this the instance to destroy. + */ +void +cr_style_destroy (CRStyle * a_this) +{ + g_return_if_fail (a_this); + + g_free (a_this); +} + diff --git a/src/libcroco/cr-style.h b/src/libcroco/cr-style.h new file mode 100644 index 000000000..9abdef6b2 --- /dev/null +++ b/src/libcroco/cr-style.h @@ -0,0 +1,339 @@ +/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */ + +/* + * This file is part of The Croco Library + * + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * Author: Dodji Seketeli. + * See COPYRIGHTS file for copyright information. + */ + +#ifndef __CR_STYLE_H__ +#define __CR_STYLE_H__ + +#include "cr-utils.h" +#include "cr-statement.h" +#include "cr-fonts.h" + +/** + *@file + *The declaration of the #CRStyle class. + */ +G_BEGIN_DECLS + +typedef struct _CRStyle CRStyle ; + +enum CRBorderStyle +{ + BORDER_STYLE_NONE = 0, + BORDER_STYLE_HIDDEN, + BORDER_STYLE_DOTTED, + BORDER_STYLE_DASHED, + BORDER_STYLE_SOLID, + BORDER_STYLE_DOUBLE, + BORDER_STYLE_GROOVE, + BORDER_STYLE_RIDGE, + BORDER_STYLE_INSET, + BORDER_STYLE_OUTSET, + BORDER_STYLE_INHERIT +} ; + +enum CRDisplayType +{ + DISPLAY_NONE, + DISPLAY_INLINE, + DISPLAY_BLOCK, + DISPLAY_LIST_ITEM, + DISPLAY_RUN_IN, + DISPLAY_COMPACT, + DISPLAY_MARKER, + DISPLAY_TABLE, + DISPLAY_INLINE_TABLE, + DISPLAY_TABLE_ROW_GROUP, + DISPLAY_TABLE_HEADER_GROUP, + DISPLAY_TABLE_FOOTER_GROUP, + DISPLAY_TABLE_ROW, + DISPLAY_TABLE_COLUMN_GROUP, + DISPLAY_TABLE_COLUMN, + DISPLAY_TABLE_CELL, + DISPLAY_TABLE_CAPTION, + DISPLAY_INHERIT +} ; + +enum CRPositionType +{ + POSITION_STATIC, + POSITION_RELATIVE, + POSITION_ABSOLUTE, + POSITION_FIXED, + POSITION_INHERIT, +} ; + +enum CRFloatType +{ + FLOAT_NONE, + FLOAT_LEFT, + FLOAT_RIGHT, + FLOAT_INHERIT +} ; + +enum CRWhiteSpaceType +{ + WHITE_SPACE_NORMAL, + WHITE_SPACE_PRE, + WHITE_SPACE_NOWRAP, + WHITE_SPACE_INHERIT +} ; + + +#define BORDER_THIN 2 +#define BORDER_MEDIUM 4 +#define BORDER_THICK 6 + + +/** + *A numerical css property value. + *This data type is actually split in 3 parts: + *1/the specified value + *2/the computed value + *3/the actual value. + *To understand the semantic of these three parts, + *see css2 spec chap 6.1 ("Specified, computed and actual values."). + */ +typedef struct _CRNumPropVal CRNumPropVal ; +struct _CRNumPropVal +{ + /**specified value*/ + CRNum sv ; + /**computed value*/ + CRNum cv ; + /**actual value*/ + CRNum av ; +} ; + +/** + *An rgb css property value. + *This data type is actually split in 3 parts: + *1/the specified value + *2/the computed value + *3/the actual value. + *To understand the semantic of these three parts, + *see css2 spec chap 6.1 ("Specified, computed and actual values."). + */ +typedef struct _CRRgbPropVal CRRgbPropVal ; +struct _CRRgbPropVal +{ + /**specified value*/ + CRRgb sv ; + /**computed value*/ + CRRgb cv ; + /**actual value*/ + CRRgb av ; +} ; + + +enum CRNumProp +{ + NUM_PROP_TOP=0, + NUM_PROP_RIGHT, + NUM_PROP_BOTTOM, + NUM_PROP_LEFT,/*3*/ + + NUM_PROP_PADDING_TOP, + NUM_PROP_PADDING_RIGHT, + NUM_PROP_PADDING_BOTTOM, + NUM_PROP_PADDING_LEFT,/*7*/ + + NUM_PROP_BORDER_TOP, + NUM_PROP_BORDER_RIGHT, + NUM_PROP_BORDER_BOTTOM, + NUM_PROP_BORDER_LEFT,/*11*/ + + NUM_PROP_MARGIN_TOP, + NUM_PROP_MARGIN_RIGHT, + NUM_PROP_MARGIN_BOTTOM, + NUM_PROP_MARGIN_LEFT,/*15*/ + + NUM_PROP_WIDTH, + + /*must be last*/ + NB_NUM_PROPS +} ; + +enum CRRgbProp +{ + RGB_PROP_BORDER_TOP_COLOR = 0, + RGB_PROP_BORDER_RIGHT_COLOR, + RGB_PROP_BORDER_BOTTOM_COLOR, + RGB_PROP_BORDER_LEFT_COLOR, + RGB_PROP_COLOR, + RGB_PROP_BACKGROUND_COLOR, + + /*must be last*/ + NB_RGB_PROPS +} ; + + +enum CRBorderStyleProp +{ + BORDER_STYLE_PROP_TOP = 0, + BORDER_STYLE_PROP_RIGHT, + BORDER_STYLE_PROP_BOTTOM, + BORDER_STYLE_PROP_LEFT, + + /*must be last*/ + NB_BORDER_STYLE_PROPS +} ; + +enum CRBoxOffsetProp +{ + BOX_OFFSET_PROP_TOP = 0, + BOX_OFFSET_PROP_RIGHT, + BOX_OFFSET_PROP_BOTTOM, + BOX_OFFSET_PROP_LEFT, + + /*must be last*/ + NB_BOX_OFFSET_PROPS +} ; + +typedef struct _CRFontSizeVal CRFontSizeVal ; +struct _CRFontSizeVal { + /*specified value*/ + CRFontSize sv ; + /*computed value*/ + CRFontSize cv ; + /*actual value*/ + CRFontSize av ; +} ; + +/** + *The css2 style class. + *Contains computed and actual values + *inferred from the declarations found + *in the stylesheets. + *See css2 spec chapter 6. + */ +struct _CRStyle +{ + /** + *numerical properties. + *the properties are indexed by + *enum #CRNumProp. + */ + CRNumPropVal num_props[NB_NUM_PROPS] ; + + /** + *color properties. + *They are indexed by enum #CRRgbProp . + */ + CRRgbPropVal rgb_props[NB_RGB_PROPS] ; + + /** + *border style properties. + *They are indexed by enum #CRBorderStyleProp . + */ + enum CRBorderStyle border_style_props[NB_BORDER_STYLE_PROPS] ; + + /**box display type*/ + enum CRDisplayType display ; + + /**the positioning scheme*/ + enum CRPositionType position ; + + /**the float property*/ + enum CRFloatType float_type ; + + /* + *the 'font-family' property. + */ + CRFontFamily *font_family ; + + /** + *the 'font-size' property. + */ + CRFontSizeVal font_size ; + CRFontSizeAdjust *font_size_adjust ; + enum CRFontStyle font_style ; + enum CRFontVariant font_variant ; + enum CRFontWeight font_weight ; + enum CRFontStretch font_stretch ; + + /** + * the 'tex' properties + */ + enum CRWhiteSpaceType white_space; + + gboolean inherited_props_resolved ; + CRStyle *parent_style ; + gulong ref_count ; +} ; + +enum CRStatus cr_style_white_space_type_to_string (enum CRWhiteSpaceType a_code, + GString * a_str, guint a_nb_indent) ; + +enum CRStatus cr_style_num_prop_val_to_string (CRNumPropVal *a_prop_val, + GString *a_str, + guint a_nb_indent) ; + +enum CRStatus cr_style_rgb_prop_val_to_string (CRRgbPropVal *a_prop_val, + GString *a_str, + guint a_nb_indent) ; + +enum CRStatus cr_style_border_style_to_string (enum CRBorderStyle a_prop, + GString *a_str, + guint a_nb_indent) ; + +enum CRStatus cr_style_display_type_to_string (enum CRDisplayType a_code, + GString *a_str, + guint a_nb_indent) ; + +enum CRStatus cr_style_position_type_to_string (enum CRPositionType a_code, + GString *a_str, + guint a_nb_indent) ; + +enum CRStatus cr_style_float_type_to_string (enum CRFloatType a_code, + GString *a_str, + guint a_nb_indent) ; + +CRStyle * cr_style_new (gboolean a_set_props_to_initial_values) ; + +enum CRStatus cr_style_set_props_to_default_values (CRStyle *a_this) ; +enum CRStatus cr_style_set_props_to_initial_values (CRStyle *a_this) ; +enum CRStatus cr_style_resolve_inherited_properties (CRStyle *a_this) ; +enum CRStatus cr_style_propagate_from_parent (CRStyle *a_this); + +enum CRStatus cr_style_set_style_from_decl (CRStyle *a_this, + CRDeclaration *a_decl) ; + + +enum CRStatus cr_style_copy (CRStyle *a_dest, CRStyle *a_src) ; + +enum CRStatus cr_style_ref (CRStyle *a_this) ; + +gboolean cr_style_unref (CRStyle *a_this) ; + +void cr_style_destroy (CRStyle *a_this) ; + +CRStyle * cr_style_dup (CRStyle *a_this) ; + +enum CRStatus cr_style_to_string (CRStyle *a_this, + GString **a_str, + guint a_nb_indent) ; + +G_END_DECLS + +#endif /*__CR_STYLE_H__*/ diff --git a/src/libcroco/cr-stylesheet.c b/src/libcroco/cr-stylesheet.c new file mode 100644 index 000000000..9aeb551e4 --- /dev/null +++ b/src/libcroco/cr-stylesheet.c @@ -0,0 +1,178 @@ +/* -*- Mode: C; indent-tabs-mode: ni; c-basic-offset: 8 -*- */ + +/* + * This file is part of The Croco Library + * + * Copyright (C) 2002-2004 Dodji Seketeli + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + +#include "string.h" +#include "cr-stylesheet.h" + +/** + *@file + *The definition of the #CRStyleSheet class + */ + +/** + *Constructor of the #CRStyleSheet class. + *@param the initial list of css statements. + *@return the newly built css2 stylesheet, or NULL in case of error. + */ +CRStyleSheet * +cr_stylesheet_new (CRStatement * a_stmts) +{ + CRStyleSheet *result; + + result = g_try_malloc (sizeof (CRStyleSheet)); + if (!result) { + cr_utils_trace_info ("Out of memory"); + return NULL; + } + + memset (result, 0, sizeof (CRStyleSheet)); + + if (a_stmts) + result->statements = a_stmts; + + return result; +} + +/** + *@param a_this the current instance of #CRStyleSheet + *@return the serialized stylesheet. + */ +gchar * +cr_stylesheet_to_string (CRStyleSheet *a_this) +{ + gchar *str = NULL; + GString *stringue = NULL; + CRStatement *cur_stmt = NULL; + + g_return_val_if_fail (a_this, NULL); + + if (a_this->statements) { + stringue = g_string_new (NULL) ; + g_return_val_if_fail (stringue, NULL) ; + } + for (cur_stmt = a_this->statements; + cur_stmt; cur_stmt = cur_stmt->next) { + if (cur_stmt->prev) { + g_string_append (stringue, "\n\n") ; + } + str = cr_statement_to_string (cur_stmt, 0) ; + if (str) { + g_string_append (stringue, str) ; + g_free (str) ; + str = NULL ; + } + } + if (stringue) { + str = stringue->str ; + g_string_free (stringue, FALSE) ; + stringue = NULL ; + } + return str ; +} + +/** + *Dumps the current css2 stylesheet to a file. + *@param a_this the current instance of #CRStyleSheet. + *@param a_fp the destination file + */ +void +cr_stylesheet_dump (CRStyleSheet * a_this, FILE * a_fp) +{ + gchar *str = NULL ; + + g_return_if_fail (a_this); + + str = cr_stylesheet_to_string (a_this) ; + if (str) { + fprintf (a_fp, "%s", str) ; + g_free (str) ; + str = NULL ; + } +} + +/** + *Return the number of rules in the stylesheet. + *@param a_this the current instance of #CRStyleSheet. + *@return number of rules in the stylesheet. + */ +gint +cr_stylesheet_nr_rules (CRStyleSheet * a_this) +{ + g_return_val_if_fail (a_this, -1); + + return cr_statement_nr_rules (a_this->statements); +} + +/** + *Use an index to get a CRStatement from the rules in a given stylesheet. + *@param a_this the current instance of #CRStatement. + *@param itemnr the index into the rules. + *@return CRStatement at position itemnr, if itemnr > number of rules - 1, + *it will return NULL. + */ +CRStatement * +cr_stylesheet_statement_get_from_list (CRStyleSheet * a_this, int itemnr) +{ + g_return_val_if_fail (a_this, NULL); + + return cr_statement_get_from_list (a_this->statements, itemnr); +} + +void +cr_stylesheet_ref (CRStyleSheet * a_this) +{ + g_return_if_fail (a_this); + + a_this->ref_count++; +} + +gboolean +cr_stylesheet_unref (CRStyleSheet * a_this) +{ + g_return_val_if_fail (a_this, FALSE); + + if (a_this->ref_count) + a_this->ref_count--; + + if (!a_this->ref_count) { + cr_stylesheet_destroy (a_this); + return TRUE; + } + + return FALSE; +} + +/** + *Destructor of the #CRStyleSheet class. + *@param a_this the current instance of the #CRStyleSheet class. + */ +void +cr_stylesheet_destroy (CRStyleSheet * a_this) +{ + g_return_if_fail (a_this); + + if (a_this->statements) { + cr_statement_destroy (a_this->statements); + a_this->statements = NULL; + } + g_free (a_this); +} diff --git a/src/libcroco/cr-stylesheet.h b/src/libcroco/cr-stylesheet.h new file mode 100644 index 000000000..3766a284a --- /dev/null +++ b/src/libcroco/cr-stylesheet.h @@ -0,0 +1,102 @@ +/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * see COPYRIGHTS file for copyright information. + */ + + +#ifndef __CR_STYLESHEET_H__ +#define __CR_STYLESHEET_H__ + +#include "cr-utils.h" +#include "cr-statement.h" + +G_BEGIN_DECLS + +/** + *@file + *The declaration of the #CRStyleSheet class. + */ + + +enum CRStyleOrigin +{ + /*Please don't change the order of + *the values enumerated here ... + *New values should be added at the end, + *just before ORIGIN_END. + */ + ORIGIN_UA = 0, + ORIGIN_USER, + ORIGIN_AUTHOR, + + /*must always be the last one*/ + NB_ORIGINS +} ; + +/** + *An abstraction of a css stylesheet as defined + *by the css2 spec in chapter 4. + */ +struct _CRStyleSheet +{ + /**The css statements list*/ + CRStatement *statements ; + + enum CRStyleOrigin origin ; + + /*the parent import rule, if any.*/ + CRStatement *parent_import_rule ; + + /**custom data used by libcroco*/ + gpointer croco_data ; + + /** + *custom application data pointer + *Can be used by applications. + */ + gpointer app_data ; + + /** + *the reference count of this insance + *Please, don't never ever modify it + *directly. Use cr_stylesheet_ref() + *and cr_stylesheet_unref() instead. + */ + gulong ref_count ; +} ; + +CRStyleSheet * cr_stylesheet_new (CRStatement *a_stmts) ; + +gchar * cr_stylesheet_to_string (CRStyleSheet *a_this) ; +void cr_stylesheet_dump (CRStyleSheet *a_this, FILE *a_fp) ; + +gint cr_stylesheet_nr_rules (CRStyleSheet *a_this) ; + +CRStatement * cr_stylesheet_statement_get_from_list (CRStyleSheet *a_this, int itemnr) ; + +void cr_stylesheet_ref (CRStyleSheet *a_this) ; + +gboolean cr_stylesheet_unref (CRStyleSheet *a_this) ; + +void cr_stylesheet_destroy (CRStyleSheet *a_this) ; + +G_END_DECLS + +#endif /*__CR_STYLESHEET_H__*/ diff --git a/src/libcroco/cr-term.c b/src/libcroco/cr-term.c new file mode 100644 index 000000000..33eed40f9 --- /dev/null +++ b/src/libcroco/cr-term.c @@ -0,0 +1,791 @@ +/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * Author: Dodji Seketeli + * See COPYRIGHTS file for copyright information. + */ + +#include +#include +#include "cr-term.h" +#include "cr-num.h" +#include "cr-parser.h" + +/** + *@file + *Definition of the #CRTem class. + */ + +static void +cr_term_clear (CRTerm * a_this) +{ + g_return_if_fail (a_this); + + switch (a_this->type) { + case TERM_NUMBER: + if (a_this->content.num) { + cr_num_destroy (a_this->content.num); + a_this->content.num = NULL; + } + break; + + case TERM_FUNCTION: + if (a_this->ext_content.func_param) { + cr_term_destroy (a_this->ext_content.func_param); + a_this->ext_content.func_param = NULL; + } + case TERM_STRING: + case TERM_IDENT: + case TERM_URI: + case TERM_HASH: + if (a_this->content.str) { + cr_string_destroy (a_this->content.str); + a_this->content.str = NULL; + } + break; + + case TERM_RGB: + if (a_this->content.rgb) { + cr_rgb_destroy (a_this->content.rgb); + a_this->content.rgb = NULL; + } + break; + + case TERM_UNICODERANGE: + case TERM_NO_TYPE: + default: + break; + } + + a_this->type = TERM_NO_TYPE; +} + +/** + *Instanciate a #CRTerm. + *@return the newly build instance + *of #CRTerm. + */ +CRTerm * +cr_term_new (void) +{ + CRTerm *result = NULL; + + result = g_try_malloc (sizeof (CRTerm)); + if (!result) { + cr_utils_trace_info ("Out of memory"); + return NULL; + } + memset (result, 0, sizeof (CRTerm)); + return result; +} + +/** + *Parses an expresion as defined by the css2 spec + *and builds the expression as a list of terms. + *@param a_buf the buffer to parse. + *@return a pointer to the first term of the expression or + *NULL if parsing failed. + */ +CRTerm * +cr_term_parse_expression_from_buf (const guchar * a_buf, + enum CREncoding a_encoding) +{ + CRParser *parser = NULL; + CRTerm *result = NULL; + enum CRStatus status = CR_OK; + + g_return_val_if_fail (a_buf, NULL); + + parser = cr_parser_new_from_buf ((guchar*)a_buf, strlen (a_buf), + a_encoding, FALSE); + g_return_val_if_fail (parser, NULL); + + status = cr_parser_try_to_skip_spaces_and_comments (parser); + if (status != CR_OK) { + goto cleanup; + } + status = cr_parser_parse_expr (parser, &result); + if (status != CR_OK) { + if (result) { + cr_term_destroy (result); + result = NULL; + } + } + + cleanup: + if (parser) { + cr_parser_destroy (parser); + parser = NULL; + } + + return result; +} + +enum CRStatus +cr_term_set_number (CRTerm * a_this, CRNum * a_num) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + cr_term_clear (a_this); + + a_this->type = TERM_NUMBER; + a_this->content.num = a_num; + return CR_OK; +} + +enum CRStatus +cr_term_set_function (CRTerm * a_this, CRString * a_func_name, + CRTerm * a_func_param) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + cr_term_clear (a_this); + + a_this->type = TERM_FUNCTION; + a_this->content.str = a_func_name; + a_this->ext_content.func_param = a_func_param; + return CR_OK; +} + +enum CRStatus +cr_term_set_string (CRTerm * a_this, CRString * a_str) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + cr_term_clear (a_this); + + a_this->type = TERM_STRING; + a_this->content.str = a_str; + return CR_OK; +} + +enum CRStatus +cr_term_set_ident (CRTerm * a_this, CRString * a_str) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + cr_term_clear (a_this); + + a_this->type = TERM_IDENT; + a_this->content.str = a_str; + return CR_OK; +} + +enum CRStatus +cr_term_set_uri (CRTerm * a_this, CRString * a_str) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + cr_term_clear (a_this); + + a_this->type = TERM_URI; + a_this->content.str = a_str; + return CR_OK; +} + +enum CRStatus +cr_term_set_rgb (CRTerm * a_this, CRRgb * a_rgb) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + cr_term_clear (a_this); + + a_this->type = TERM_RGB; + a_this->content.rgb = a_rgb; + return CR_OK; +} + +enum CRStatus +cr_term_set_hash (CRTerm * a_this, CRString * a_str) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + cr_term_clear (a_this); + + a_this->type = TERM_HASH; + a_this->content.str = a_str; + return CR_OK; +} + +/** + *Appends a new term to the current list of #CRTerm. + * + *@param a_this the "this pointer" of the current instance + *of #CRTerm . + *@param a_new_term the term to append. + *@return the list of terms with the a_new_term appended to it. + */ +CRTerm * +cr_term_append_term (CRTerm * a_this, CRTerm * a_new_term) +{ + CRTerm *cur = NULL; + + g_return_val_if_fail (a_new_term, NULL); + + if (a_this == NULL) + return a_new_term; + + for (cur = a_this; cur->next; cur = cur->next) ; + + cur->next = a_new_term; + a_new_term->prev = cur; + + return a_this; +} + +/** + *Prepends a term to the list of terms represented by a_this. + * + *@param a_this the "this pointer" of the current instance of + *#CRTerm . + *@param a_new_term the term to prepend. + *@return the head of the new list. + */ +CRTerm * +cr_term_prepend_term (CRTerm * a_this, CRTerm * a_new_term) +{ + g_return_val_if_fail (a_this && a_new_term, NULL); + + a_new_term->next = a_this; + a_this->prev = a_new_term; + + return a_new_term; +} + +/** + *Serializes the expression represented by + *the chained instances of #CRterm. + *@param a_this the current instance of #CRTerm + *@return the zero terminated string containing the serialized + *form of #CRTerm. MUST BE FREED BY THE CALLER using g_free(). + */ +guchar * +cr_term_to_string (CRTerm * a_this) +{ + GString *str_buf = NULL; + CRTerm *cur = NULL; + guchar *result = NULL, + *content = NULL; + + g_return_val_if_fail (a_this, NULL); + + str_buf = g_string_new (NULL); + g_return_val_if_fail (str_buf, NULL); + + for (cur = a_this; cur; cur = cur->next) { + if ((cur->content.str == NULL) + && (cur->content.num == NULL) + && (cur->content.str == NULL) + && (cur->content.rgb == NULL)) + continue; + + switch (cur->the_operator) { + case DIVIDE: + g_string_append (str_buf, " / "); + break; + + case COMMA: + g_string_append (str_buf, ", "); + break; + + case NO_OP: + if (cur->prev) { + g_string_append (str_buf, " "); + } + break; + default: + + break; + } + + switch (cur->unary_op) { + case PLUS_UOP: + g_string_append (str_buf, "+"); + break; + + case MINUS_UOP: + g_string_append (str_buf, "-"); + break; + + default: + break; + } + + switch (cur->type) { + case TERM_NUMBER: + if (cur->content.num) { + content = cr_num_to_string (cur->content.num); + } + + if (content) { + g_string_append (str_buf, content); + g_free (content); + content = NULL; + } + + break; + + case TERM_FUNCTION: + if (cur->content.str) { + content = g_strndup + (cur->content.str->stryng->str, + cur->content.str->stryng->len); + } + + if (content) { + g_string_append_printf (str_buf, "%s(", + content); + + if (cur->ext_content.func_param) { + guchar *tmp_str = NULL; + + tmp_str = cr_term_to_string + (cur-> + ext_content.func_param); + + if (tmp_str) { + g_string_append (str_buf, + tmp_str); + g_free (tmp_str); + tmp_str = NULL; + } + + g_free (content); + content = NULL; + } + g_string_append (str_buf, ")"); + } + + break; + + case TERM_STRING: + if (cur->content.str) { + content = g_strndup + (cur->content.str->stryng->str, + cur->content.str->stryng->len); + } + + if (content) { + g_string_append_printf (str_buf, + "\"%s\"", content); + g_free (content); + content = NULL; + } + break; + + case TERM_IDENT: + if (cur->content.str) { + content = g_strndup + (cur->content.str->stryng->str, + cur->content.str->stryng->len); + } + + if (content) { + g_string_append (str_buf, content); + g_free (content); + content = NULL; + } + break; + + case TERM_URI: + if (cur->content.str) { + content = g_strndup + (cur->content.str->stryng->str, + cur->content.str->stryng->len); + } + + if (content) { + g_string_append_printf + (str_buf, "url(%s)", content); + g_free (content); + content = NULL; + } + break; + + case TERM_RGB: + if (cur->content.rgb) { + guchar *tmp_str = NULL; + + g_string_append (str_buf, "rgb("); + tmp_str = cr_rgb_to_string (cur->content.rgb); + + if (tmp_str) { + g_string_append (str_buf, tmp_str); + g_free (tmp_str); + tmp_str = NULL; + } + g_string_append (str_buf, ")"); + } + + break; + + case TERM_UNICODERANGE: + g_string_append + (str_buf, + "?found unicoderange: dump not supported yet?"); + break; + + case TERM_HASH: + if (cur->content.str) { + content = g_strndup + (cur->content.str->stryng->str, + cur->content.str->stryng->len); + } + + if (content) { + g_string_append_printf (str_buf, + "#%s", content); + g_free (content); + content = NULL; + } + break; + + default: + g_string_append (str_buf, + "Unrecognized Term type"); + break; + } + } + + if (str_buf) { + result = str_buf->str; + g_string_free (str_buf, FALSE); + str_buf = NULL; + } + + return result; +} + +guchar * +cr_term_one_to_string (CRTerm * a_this) +{ + GString *str_buf = NULL; + guchar *result = NULL, + *content = NULL; + + g_return_val_if_fail (a_this, NULL); + + str_buf = g_string_new (NULL); + g_return_val_if_fail (str_buf, NULL); + + if ((a_this->content.str == NULL) + && (a_this->content.num == NULL) + && (a_this->content.str == NULL) + && (a_this->content.rgb == NULL)) + return NULL ; + + switch (a_this->the_operator) { + case DIVIDE: + g_string_append_printf (str_buf, " / "); + break; + + case COMMA: + g_string_append_printf (str_buf, ", "); + break; + + case NO_OP: + if (a_this->prev) { + g_string_append_printf (str_buf, " "); + } + break; + default: + + break; + } + + switch (a_this->unary_op) { + case PLUS_UOP: + g_string_append_printf (str_buf, "+"); + break; + + case MINUS_UOP: + g_string_append_printf (str_buf, "-"); + break; + + default: + break; + } + + switch (a_this->type) { + case TERM_NUMBER: + if (a_this->content.num) { + content = cr_num_to_string (a_this->content.num); + } + + if (content) { + g_string_append (str_buf, content); + g_free (content); + content = NULL; + } + + break; + + case TERM_FUNCTION: + if (a_this->content.str) { + content = g_strndup + (a_this->content.str->stryng->str, + a_this->content.str->stryng->len); + } + + if (content) { + g_string_append_printf (str_buf, "%s(", + content); + + if (a_this->ext_content.func_param) { + guchar *tmp_str = NULL; + + tmp_str = cr_term_to_string + (a_this-> + ext_content.func_param); + + if (tmp_str) { + g_string_append_printf + (str_buf, + "%s", tmp_str); + g_free (tmp_str); + tmp_str = NULL; + } + + g_string_append_printf (str_buf, ")"); + g_free (content); + content = NULL; + } + } + + break; + + case TERM_STRING: + if (a_this->content.str) { + content = g_strndup + (a_this->content.str->stryng->str, + a_this->content.str->stryng->len); + } + + if (content) { + g_string_append_printf (str_buf, + "\"%s\"", content); + g_free (content); + content = NULL; + } + break; + + case TERM_IDENT: + if (a_this->content.str) { + content = g_strndup + (a_this->content.str->stryng->str, + a_this->content.str->stryng->len); + } + + if (content) { + g_string_append (str_buf, content); + g_free (content); + content = NULL; + } + break; + + case TERM_URI: + if (a_this->content.str) { + content = g_strndup + (a_this->content.str->stryng->str, + a_this->content.str->stryng->len); + } + + if (content) { + g_string_append_printf + (str_buf, "url(%s)", content); + g_free (content); + content = NULL; + } + break; + + case TERM_RGB: + if (a_this->content.rgb) { + guchar *tmp_str = NULL; + + g_string_append_printf (str_buf, "rgb("); + tmp_str = cr_rgb_to_string (a_this->content.rgb); + + if (tmp_str) { + g_string_append (str_buf, tmp_str); + g_free (tmp_str); + tmp_str = NULL; + } + g_string_append_printf (str_buf, ")"); + } + + break; + + case TERM_UNICODERANGE: + g_string_append_printf + (str_buf, + "?found unicoderange: dump not supported yet?"); + break; + + case TERM_HASH: + if (a_this->content.str) { + content = g_strndup + (a_this->content.str->stryng->str, + a_this->content.str->stryng->len); + } + + if (content) { + g_string_append_printf (str_buf, + "#%s", content); + g_free (content); + content = NULL; + } + break; + + default: + g_string_append_printf (str_buf, + "%s", + "Unrecognized Term type"); + break; + } + + if (str_buf) { + result = str_buf->str; + g_string_free (str_buf, FALSE); + str_buf = NULL; + } + + return result; +} + +/** + *Dumps the expression (a list of terms connected by operators) + *to a file. + *TODO: finish the dump. The dump of some type of terms have not yet been + *implemented. + *@param a_this the current instance of #CRTerm. + *@param a_fp the destination file pointer. + */ +void +cr_term_dump (CRTerm * a_this, FILE * a_fp) +{ + guchar *content = NULL; + + g_return_if_fail (a_this); + + content = cr_term_to_string (a_this); + + if (content) { + fprintf (a_fp, "%s", content); + g_free (content); + } +} + +/** + *Return the number of terms in the expression. + *@param a_this the current instance of #CRTerm. + *@return number of terms in the expression. + */ +int +cr_term_nr_values (CRTerm *a_this) +{ + CRTerm *cur = NULL ; + int nr = 0; + + g_return_val_if_fail (a_this, -1) ; + + for (cur = a_this ; cur ; cur = cur->next) + nr ++; + return nr; +} + +/** + *Use an index to get a CRTerm from the expression. + *@param a_this the current instance of #CRTerm. + *@param itemnr the index into the expression. + *@return CRTerm at position itemnr, if itemnr > number of terms - 1, + *it will return NULL. + */ +CRTerm * +cr_term_get_from_list (CRTerm *a_this, int itemnr) +{ + CRTerm *cur = NULL ; + int nr = 0; + + g_return_val_if_fail (a_this, NULL) ; + + for (cur = a_this ; cur ; cur = cur->next) + if (nr++ == itemnr) + return cur; + return NULL; +} + +/** + *Increments the reference counter of the current instance + *of #CRTerm.* + *@param a_this the current instance of #CRTerm. + */ +void +cr_term_ref (CRTerm * a_this) +{ + g_return_if_fail (a_this); + + a_this->ref_count++; +} + +/** + *Decrements the ref count of the current instance of + *#CRTerm. If the ref count reaches zero, the instance is + *destroyed. + *@param a_this the current instance of #CRTerm. + *@return TRUE if the current instance has been destroyed, FALSE otherwise. + */ +gboolean +cr_term_unref (CRTerm * a_this) +{ + g_return_val_if_fail (a_this, FALSE); + + if (a_this->ref_count) { + a_this->ref_count--; + } + + if (a_this->ref_count == 0) { + cr_term_destroy (a_this); + return TRUE; + } + + return FALSE; +} + +/** + *The destructor of the the #CRTerm class. + *@param a_this the "this pointer" of the current instance + *of #CRTerm. + */ +void +cr_term_destroy (CRTerm * a_this) +{ + g_return_if_fail (a_this); + + cr_term_clear (a_this); + + if (a_this->next) { + cr_term_destroy (a_this->next); + a_this->next = NULL; + } + + if (a_this) { + g_free (a_this); + } + +} diff --git a/src/libcroco/cr-term.h b/src/libcroco/cr-term.h new file mode 100644 index 000000000..ae8b234c5 --- /dev/null +++ b/src/libcroco/cr-term.h @@ -0,0 +1,190 @@ +/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * Author: Dodji Seketeli + * See COPYRIGHTS file for copyright information. + */ + +#include +#include +#include "cr-utils.h" +#include "cr-rgb.h" +#include "cr-num.h" +#include "cr-string.h" + +#ifndef __CR_TERM_H__ +#define __CR_TERM_H__ + +G_BEGIN_DECLS + +/** + *@file + *Declaration of the #CRTerm class. + */ + +enum CRTermType +{ + TERM_NO_TYPE = 0, + TERM_NUMBER, + TERM_FUNCTION, + TERM_STRING, + TERM_IDENT, + TERM_URI, + TERM_RGB, + TERM_UNICODERANGE, + TERM_HASH +} ; + + +enum UnaryOperator +{ + NO_UNARY_UOP = 0, + PLUS_UOP, + MINUS_UOP, + EMPTY_UNARY_UOP +} ; + +enum Operator +{ + NO_OP = 0, + DIVIDE, + COMMA +} ; + +struct _CRTerm ; +typedef struct _CRTerm CRTerm ; + +/** + *An abstraction of a css2 term as + *defined in the CSS2 spec in appendix D.1: + *term ::= + *[ NUMBER S* | PERCENTAGE S* | LENGTH S* | EMS S* | EXS S* + *| ANGLE S* | TIME S* | FREQ S* | function ] + * | STRING S* | IDENT S* | URI S* | RGB S* + *| UNICODERANGE S* | hexcolor + */ +struct _CRTerm +{ + /** + *The type of the term. + */ + enum CRTermType type ; + + /** + *The unary operator associated to + *the current term. + */ + enum UnaryOperator unary_op ; + + /** + *The operator associated to the current term. + */ + enum Operator the_operator ; + + + /** + *The content of the term. + *Depending of the type of the term, + *this holds either a number, a percentage ... + */ + union + { + CRNum *num ; + CRString * str ; + CRRgb * rgb ; + } content ; + + /** + *If the term is of type UNICODERANGE, + *this field holds the upper bound of the range. + *if the term is of type FUNCTION, this holds + *an instance of CRTerm that represents + * the expression which is the argument of the function. + */ + union + { + CRTerm *func_param ; + } ext_content ; + + /** + *A spare pointer, just in case. + *Can be used by the application. + */ + gpointer app_data ; + + glong ref_count ; + + /** + *A pointer to the next term, + *just in case this term is part of + *an expression. + */ + CRTerm *next ; + + /** + *A pointer to the previous + *term. + */ + CRTerm *prev ; + CRParsingLocation location ; +} ; + +CRTerm * cr_term_parse_expression_from_buf (const guchar *a_buf, + enum CREncoding a_encoding) ; +CRTerm * cr_term_new (void) ; + +enum CRStatus cr_term_set_number (CRTerm *a_this, CRNum *a_num) ; + +enum CRStatus cr_term_set_function (CRTerm *a_this, + CRString *a_func_name, + CRTerm *a_func_param) ; + +enum CRStatus cr_term_set_string (CRTerm *a_this, CRString *a_str) ; + +enum CRStatus cr_term_set_ident (CRTerm *a_this, CRString *a_str) ; + +enum CRStatus cr_term_set_uri (CRTerm *a_this, CRString *a_str) ; + +enum CRStatus cr_term_set_rgb (CRTerm *a_this, CRRgb *a_rgb) ; + +enum CRStatus cr_term_set_hash (CRTerm *a_this, CRString *a_str) ; + +CRTerm * cr_term_append_term (CRTerm *a_this, CRTerm *a_new_term) ; + +CRTerm * cr_term_prepend_term (CRTerm *a_this, CRTerm *a_new_term) ; + +guchar * cr_term_to_string (CRTerm *a_this) ; + +guchar * cr_term_one_to_string (CRTerm * a_this) ; + +void cr_term_dump (CRTerm *a_this, FILE *a_fp) ; + +int cr_term_nr_values (CRTerm *a_this) ; + +CRTerm * cr_term_get_from_list (CRTerm *a_this, int itemnr) ; + +void cr_term_ref (CRTerm *a_this) ; + +gboolean cr_term_unref (CRTerm *a_this) ; + +void cr_term_destroy (CRTerm * a_term) ; + +G_END_DECLS + +#endif /*__CR_TERM_H__*/ diff --git a/src/libcroco/cr-tknzr.c b/src/libcroco/cr-tknzr.c new file mode 100644 index 000000000..b591770f8 --- /dev/null +++ b/src/libcroco/cr-tknzr.c @@ -0,0 +1,2760 @@ +/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * Author: Dodji Seketeli + * See the COPYRIGHTS file for copyrights information. + */ + +/** + *@file + *The definition of the #CRTknzr (tokenizer) + *class. + */ + +#include "string.h" +#include "cr-tknzr.h" +#include "cr-doc-handler.h" + +struct _CRTknzrPriv { + /**The parser input stream of bytes*/ + CRInput *input; + + /** + *A cache where tknzr_unget_token() + *puts back the token. tknzr_get_next_token() + *first look in this cache, and if and + *only if it's empty, fetches the next token + *from the input stream. + */ + CRToken *token_cache; + + /** + *The position of the end of the previous token + *or char fetched. + */ + CRInputPos prev_pos; + + CRDocHandler *sac_handler; + + /** + *The reference count of the current instance + *of #CRTknzr. Is manipulated by cr_tknzr_ref() + *and cr_tknzr_unref(). + */ + glong ref_count; +}; + +#define PRIVATE(obj) ((obj)->priv) + +/** + *return TRUE if the character is a number ([0-9]), FALSE otherwise + *@param a_char the char to test. + */ +#define IS_NUM(a_char) (((a_char) >= '0' && (a_char) <= '9')?TRUE:FALSE) + +/** + *Checks if 'status' equals CR_OK. If not, goto the 'error' label. + * + *@param status the status (of type enum CRStatus) to test. + *@param is_exception if set to FALSE, the final status returned the + *current function will be CR_PARSING_ERROR. If set to TRUE, the + *current status will be the current value of the 'status' variable. + * + */ +#define CHECK_PARSING_STATUS(status, is_exception) \ +if ((status) != CR_OK) \ +{ \ + if (is_exception == FALSE) \ + { \ + status = CR_PARSING_ERROR ; \ + } \ + goto error ; \ +} + +/** + *Peeks the next char from the input stream of the current tokenizer. + *invokes CHECK_PARSING_STATUS on the status returned by + *cr_tknzr_input_peek_char(). + * + *@param the current instance of #CRTkzr. + *@param to_char a pointer to the char where to store the + *char peeked. + */ +#define PEEK_NEXT_CHAR(a_tknzr, a_to_char) \ +{\ +status = cr_tknzr_peek_char (a_tknzr, a_to_char) ; \ +CHECK_PARSING_STATUS (status, TRUE) \ +} + +/** + *Reads the next char from the input stream of the current parser. + *In case of error, jumps to the "error:" label located in the + *function where this macro is called. + *@param parser the curent instance of #CRTknzr + *@param to_char a pointer to the guint32 char where to store + *the character read. + */ +#define READ_NEXT_CHAR(a_tknzr, to_char) \ +status = cr_tknzr_read_char (a_tknzr, to_char) ;\ +CHECK_PARSING_STATUS (status, TRUE) + +/** + *Gets information about the current position in + *the input of the parser. + *In case of failure, this macro returns from the + *calling function and + *returns a status code of type enum #CRStatus. + *@param parser the current instance of #CRTknzr. + *@param pos out parameter. A pointer to the position + *inside the current parser input. Must + */ +#define RECORD_INITIAL_POS(a_tknzr, a_pos) \ +status = cr_input_get_cur_pos (PRIVATE \ +(a_tknzr)->input, a_pos) ; \ +g_return_val_if_fail (status == CR_OK, status) + +/** + *Gets the address of the current byte inside the + *parser input. + *@param parser the current instance of #CRTknzr. + *@param addr out parameter a pointer (guchar*) + *to where the address must be put. + */ +#define RECORD_CUR_BYTE_ADDR(a_tknzr, a_addr) \ +status = cr_input_get_cur_byte_addr \ + (PRIVATE (a_tknzr)->input, a_addr) ; \ +CHECK_PARSING_STATUS (status, TRUE) + +/** + *Peeks a byte from the topmost parser input at + *a given offset from the current position. + *If it fails, goto the "error:" label. + * + *@param a_parser the current instance of #CRTknzr. + *@param a_offset the offset of the byte to peek, the + *current byte having the offset '0'. + *@param a_byte_ptr out parameter a pointer (guchar*) to + *where the peeked char is to be stored. + */ +#define PEEK_BYTE(a_tknzr, a_offset, a_byte_ptr) \ +status = cr_tknzr_peek_byte (a_tknzr, \ + a_offset, \ + a_byte_ptr) ; \ +CHECK_PARSING_STATUS (status, TRUE) ; + +#define BYTE(a_input, a_n, a_eof) \ +cr_input_peek_byte2 (a_input, a_n, a_eof) + +/** + *Reads a byte from the topmost parser input + *steam. + *If it fails, goto the "error" label. + *@param a_parser the current instance of #CRTknzr. + *@param a_byte_ptr the guchar * where to put the read char. + */ +#define READ_NEXT_BYTE(a_tknzr, a_byte_ptr) \ +status = \ +cr_input_read_byte (PRIVATE (a_tknzr)->input, a_byte_ptr) ;\ +CHECK_PARSING_STATUS (status, TRUE) ; + +/** + *Skips a given number of byte in the topmost + *parser input. Don't update line and column number. + *In case of error, jumps to the "error:" label + *of the surrounding function. + *@param a_parser the current instance of #CRTknzr. + *@param a_nb_bytes the number of bytes to skip. + */ +#define SKIP_BYTES(a_tknzr, a_nb_bytes) \ +status = cr_input_seek_index (PRIVATE (a_tknzr)->input, \ + CR_SEEK_CUR, a_nb_bytes) ; \ +CHECK_PARSING_STATUS (status, TRUE) ; + +/** + *Skip utf8 encoded characters. + *Updates line and column numbers. + *@param a_parser the current instance of #CRTknzr. + *@param a_nb_chars the number of chars to skip. Must be of + *type glong. + */ +#define SKIP_CHARS(a_tknzr, a_nb_chars) \ +{ \ +glong nb_chars = a_nb_chars ; \ +status = cr_input_consume_chars \ + (PRIVATE (a_tknzr)->input,0, &nb_chars) ; \ +CHECK_PARSING_STATUS (status, TRUE) ; \ +} + +/** + *Tests the condition and if it is false, sets + *status to "CR_PARSING_ERROR" and goto the 'error' + *label. + *@param condition the condition to test. + */ +#define ENSURE_PARSING_COND(condition) \ +if (! (condition)) {status = CR_PARSING_ERROR; goto error ;} + +static enum CRStatus cr_tknzr_parse_nl (CRTknzr * a_this, + guchar ** a_start, + guchar ** a_end, + CRParsingLocation *a_location); + +static enum CRStatus cr_tknzr_parse_w (CRTknzr * a_this, + guchar ** a_start, + guchar ** a_end, + CRParsingLocation *a_location) ; + +static enum CRStatus cr_tknzr_parse_unicode_escape (CRTknzr * a_this, + guint32 * a_unicode, + CRParsingLocation *a_location) ; + +static enum CRStatus cr_tknzr_parse_escape (CRTknzr * a_this, + guint32 * a_esc_code, + CRParsingLocation *a_location); + +static enum CRStatus cr_tknzr_parse_string (CRTknzr * a_this, + CRString ** a_str); + +static enum CRStatus cr_tknzr_parse_comment (CRTknzr * a_this, + CRString ** a_comment); + +static enum CRStatus cr_tknzr_parse_nmstart (CRTknzr * a_this, + guint32 * a_char, + CRParsingLocation *a_location); + +static enum CRStatus cr_tknzr_parse_num (CRTknzr * a_this, + CRNum ** a_num); + +/********************************** + *PRIVATE methods + **********************************/ + +/** + *Parses a "w" as defined by the css spec at [4.1.1]: + * w ::= [ \t\r\n\f]* + * + *@param a_this the current instance of #CRTknzr. + *@param a_start out param. Upon successfull completion, points + *to the beginning of the parsed white space, points to NULL otherwise. + *Can also point to NULL is there is no white space actually. + *@param a_end out param. Upon successfull completion, points + *to the end of the parsed white space, points to NULL otherwise. + *Can also point to NULL is there is no white space actually. + */ +static enum CRStatus +cr_tknzr_parse_w (CRTknzr * a_this, + guchar ** a_start, + guchar ** a_end, + CRParsingLocation *a_location) +{ + guint32 cur_char = 0; + CRInputPos init_pos; + enum CRStatus status = CR_OK; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && PRIVATE (a_this)->input + && a_start && a_end, + CR_BAD_PARAM_ERROR); + + RECORD_INITIAL_POS (a_this, &init_pos); + + *a_start = NULL; + *a_end = NULL; + + READ_NEXT_CHAR (a_this, &cur_char); + + if (cr_utils_is_white_space (cur_char) == FALSE) { + status = CR_PARSING_ERROR; + goto error; + } + if (a_location) { + cr_tknzr_get_parsing_location (a_this, + a_location) ; + } + RECORD_CUR_BYTE_ADDR (a_this, a_start); + *a_end = *a_start; + + for (;;) { + gboolean is_eof = FALSE; + + cr_input_get_end_of_file (PRIVATE (a_this)->input, &is_eof); + if (is_eof) + break; + + status = cr_tknzr_peek_char (a_this, &cur_char); + if (status == CR_END_OF_INPUT_ERROR) { + status = CR_OK; + break; + } else if (status != CR_OK) { + goto error; + } + + if (cr_utils_is_white_space (cur_char) == TRUE) { + READ_NEXT_CHAR (a_this, &cur_char); + RECORD_CUR_BYTE_ADDR (a_this, a_end); + } else { + break; + } + } + + return CR_OK; + + error: + cr_tknzr_set_cur_pos (a_this, &init_pos); + + return status; +} + +/** + *Parses a newline as defined in the css2 spec: + * nl ::= \n|\r\n|\r|\f + * + *@param a_this the "this pointer" of the current instance of #CRTknzr. + *@param a_start a pointer to the first character of the successfully + *parsed string. + *@param a_end a pointer to the last character of the successfully parsed + *string. + *@result CR_OK uppon successfull completion, an error code otherwise. + */ +static enum CRStatus +cr_tknzr_parse_nl (CRTknzr * a_this, + guchar ** a_start, + guchar ** a_end, + CRParsingLocation *a_location) +{ + CRInputPos init_pos; + guchar next_chars[2] = { 0 }; + enum CRStatus status = CR_PARSING_ERROR; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && a_start && a_end, CR_BAD_PARAM_ERROR); + + RECORD_INITIAL_POS (a_this, &init_pos); + + PEEK_BYTE (a_this, 1, &next_chars[0]); + PEEK_BYTE (a_this, 2, &next_chars[1]); + + if ((next_chars[0] == '\r' && next_chars[1] == '\n')) { + SKIP_BYTES (a_this, 1); + if (a_location) { + cr_tknzr_get_parsing_location + (a_this, a_location) ; + } + SKIP_CHARS (a_this, 1); + + RECORD_CUR_BYTE_ADDR (a_this, a_end); + + status = CR_OK; + } else if (next_chars[0] == '\n' + || next_chars[0] == '\r' || next_chars[0] == '\f') { + SKIP_CHARS (a_this, 1); + if (a_location) { + cr_tknzr_get_parsing_location + (a_this, a_location) ; + } + RECORD_CUR_BYTE_ADDR (a_this, a_start); + *a_end = *a_start; + status = CR_OK; + } else { + status = CR_PARSING_ERROR; + goto error; + } + return CR_OK ; + + error: + cr_tknzr_set_cur_pos (a_this, &init_pos) ; + return status; +} + +/** + *Go ahead in the parser input, skipping all the spaces. + *If the next char if not a white space, this function does nothing. + *In any cases, it stops when it encounters a non white space character. + * + *@param a_this the current instance of #CRTknzr. + *@return CR_OK upon successfull completion, an error code otherwise. + */ +static enum CRStatus +cr_tknzr_try_to_skip_spaces (CRTknzr * a_this) +{ + enum CRStatus status = CR_ERROR; + guint32 cur_char = 0; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && PRIVATE (a_this)->input, CR_BAD_PARAM_ERROR); + + status = cr_input_peek_char (PRIVATE (a_this)->input, &cur_char); + + if (status != CR_OK) { + if (status == CR_END_OF_INPUT_ERROR) + return CR_OK; + return status; + } + + if (cr_utils_is_white_space (cur_char) == TRUE) { + glong nb_chars = -1; /*consume all spaces */ + + status = cr_input_consume_white_spaces + (PRIVATE (a_this)->input, &nb_chars); + } + + return status; +} + +/** + *Parses a "comment" as defined in the css spec at [4.1.1]: + *COMMENT ::= \/\*[^*]*\*+([^/][^*]*\*+)*\/ . + *This complex regexp is just to say that comments start + *with the two chars '/''*' and ends with the two chars '*''/'. + *It also means that comments cannot be nested. + *So based on that, I've just tried to implement the parsing function + *simply and in a straight forward manner. + */ +static enum CRStatus +cr_tknzr_parse_comment (CRTknzr * a_this, + CRString ** a_comment) +{ + enum CRStatus status = CR_OK; + CRInputPos init_pos; + guint32 cur_char = 0, next_char= 0; + CRString *comment = NULL; + CRParsingLocation loc = {0,0,0} ; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && PRIVATE (a_this)->input, + CR_BAD_PARAM_ERROR); + + RECORD_INITIAL_POS (a_this, &init_pos); + READ_NEXT_CHAR (a_this, &cur_char) ; + ENSURE_PARSING_COND (cur_char == '/'); + cr_tknzr_get_parsing_location (a_this, &loc) ; + + READ_NEXT_CHAR (a_this, &cur_char); + ENSURE_PARSING_COND (cur_char == '*'); + comment = cr_string_new (); + for (;;) { + READ_NEXT_CHAR (a_this, &cur_char); + + /*make sure there are no nested comments */ + if (cur_char == '/') { + READ_NEXT_CHAR (a_this, &cur_char); + ENSURE_PARSING_COND (cur_char != '*'); + g_string_append_c (comment->stryng, '/'); + g_string_append_unichar (comment->stryng, + cur_char); + continue; + } + + /*Detect the end of the comments region */ + if (cur_char == '*') { + PEEK_NEXT_CHAR (a_this, &next_char); + + if (next_char == '/') { + /* + *end of comments region + *Now, call the right SAC callback. + */ + SKIP_CHARS (a_this, 1) ; + status = CR_OK; + break; + } else { + g_string_append_c (comment->stryng, + '*'); + } + } + g_string_append_unichar (comment->stryng, cur_char); + } + + if (status == CR_OK) { + cr_parsing_location_copy (&comment->location, + &loc) ; + *a_comment = comment; + return CR_OK; + } + error: + + if (comment) { + cr_string_destroy (comment); + comment = NULL; + } + + cr_tknzr_set_cur_pos (a_this, &init_pos); + + return status; +} + +/** + *Parses an 'unicode' escape sequence defined + *in css spec at chap 4.1.1: + *unicode ::= \\[0-9a-f]{1,6}[ \n\r\t\f]? + *@param a_this the current instance of #CRTknzr. + *@param a_start out parameter. A pointer to the start + *of the unicode escape sequence. Must *NOT* be deleted by + *the caller. + *@param a_end out parameter. A pointer to the last character + *of the unicode escape sequence. Must *NOT* be deleted by the caller. + *@return CR_OK if parsing succeded, an error code otherwise. + *Error code can be either CR_PARSING_ERROR if the string + *parsed just doesn't + *respect the production or another error if a + *lower level error occured. + */ +static enum CRStatus +cr_tknzr_parse_unicode_escape (CRTknzr * a_this, + guint32 * a_unicode, + CRParsingLocation *a_location) +{ + guint32 cur_char; + CRInputPos init_pos; + glong occur = 0; + guint32 unicode = 0; + guchar *tmp_char_ptr1 = NULL, + *tmp_char_ptr2 = NULL; + enum CRStatus status = CR_OK; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && a_unicode, CR_BAD_PARAM_ERROR); + + /*first, let's backup the current position pointer */ + RECORD_INITIAL_POS (a_this, &init_pos); + + READ_NEXT_CHAR (a_this, &cur_char); + + if (cur_char != '\\') { + status = CR_PARSING_ERROR; + goto error; + } + if (a_location) { + cr_tknzr_get_parsing_location + (a_this, a_location) ; + } + PEEK_NEXT_CHAR (a_this, &cur_char); + + for (occur = 0, unicode = 0; ((cur_char >= '0' && cur_char <= '9') + || (cur_char >= 'a' && cur_char <= 'f') + || (cur_char >= 'A' && cur_char <= 'F')) + && occur < 6; occur++) { + gint cur_char_val = 0; + + READ_NEXT_CHAR (a_this, &cur_char); + + if ((cur_char >= '0' && cur_char <= '9')) { + cur_char_val = (cur_char - '0'); + } else if ((cur_char >= 'a' && cur_char <= 'f')) { + cur_char_val = 10 + (cur_char - 'a'); + } else if ((cur_char >= 'A' && cur_char <= 'F')) { + cur_char_val = 10 + (cur_char - 'A'); + } + + unicode = unicode * 10 + cur_char_val; + + PEEK_NEXT_CHAR (a_this, &cur_char); + } + + if (occur == 5) { + /* + *the unicode escape is 6 digit length + */ + + /* + *parse one space that may + *appear just after the unicode + *escape. + */ + cr_tknzr_parse_w (a_this, &tmp_char_ptr1, + &tmp_char_ptr2, NULL); + status = CR_OK; + } else { + /* + *The unicode escape is less than + *6 digit length. The character + *that comes right after the escape + *must be a white space. + */ + status = cr_tknzr_parse_w (a_this, &tmp_char_ptr1, + &tmp_char_ptr2, NULL); + } + + if (status == CR_OK) { + *a_unicode = unicode; + return CR_OK; + } + + error: + /* + *restore the initial position pointer backuped at + *the beginning of this function. + */ + cr_tknzr_set_cur_pos (a_this, &init_pos); + + return status; +} + +/** + *parses an escape sequence as defined by the css spec: + *escape ::= {unicode}|\\[ -~\200-\4177777] + *@param a_this the current instance of #CRTknzr . + */ +static enum CRStatus +cr_tknzr_parse_escape (CRTknzr * a_this, guint32 * a_esc_code, + CRParsingLocation *a_location) +{ + enum CRStatus status = CR_OK; + guint32 cur_char = 0; + CRInputPos init_pos; + guchar next_chars[2]; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && a_esc_code, CR_BAD_PARAM_ERROR); + + RECORD_INITIAL_POS (a_this, &init_pos); + + PEEK_BYTE (a_this, 1, &next_chars[0]); + PEEK_BYTE (a_this, 2, &next_chars[1]); + + if (next_chars[0] != '\\') { + status = CR_PARSING_ERROR; + goto error; + } + + if ((next_chars[1] >= '0' && next_chars[1] <= '9') + || (next_chars[1] >= 'a' && next_chars[1] <= 'f') + || (next_chars[1] >= 'A' && next_chars[1] <= 'F')) { + status = cr_tknzr_parse_unicode_escape (a_this, a_esc_code, + a_location); + } else { + /*consume the '\' char */ + READ_NEXT_CHAR (a_this, &cur_char); + if (a_location) { + cr_tknzr_get_parsing_location (a_this, + a_location) ; + } + /*then read the char after the '\' */ + READ_NEXT_CHAR (a_this, &cur_char); + + if (cur_char != ' ' && (cur_char < 200 || cur_char > 4177777)) { + status = CR_PARSING_ERROR; + goto error; + } + *a_esc_code = cur_char; + + } + if (status == CR_OK) { + return CR_OK; + } + error: + cr_tknzr_set_cur_pos (a_this, &init_pos); + return status; +} + +/** + *Parses a string type as defined in css spec [4.1.1]: + * + *string ::= {string1}|{string2} + *string1 ::= \"([\t !#$%&(-~]|\\{nl}|\'|{nonascii}|{escape})*\" + *string2 ::= \'([\t !#$%&(-~]|\\{nl}|\"|{nonascii}|{escape})*\' + * + *@param a_this the current instance of #CRTknzr. + *@param a_start out parameter. Upon successfull completion, + *points to the beginning of the string, points to an undefined value + *otherwise. + *@param a_end out parameter. Upon successfull completion, points to + *the beginning of the string, points to an undefined value otherwise. + *@return CR_OK upon successfull completion, an error code otherwise. + */ +static enum CRStatus +cr_tknzr_parse_string (CRTknzr * a_this, CRString ** a_str) +{ + guint32 cur_char = 0, + delim = 0; + CRInputPos init_pos; + enum CRStatus status = CR_OK; + CRString *str = NULL; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && PRIVATE (a_this)->input + && a_str, CR_BAD_PARAM_ERROR); + + RECORD_INITIAL_POS (a_this, &init_pos); + READ_NEXT_CHAR (a_this, &cur_char); + + if (cur_char == '"') + delim = '"'; + else if (cur_char == '\'') + delim = '\''; + else { + status = CR_PARSING_ERROR; + goto error; + } + str = cr_string_new (); + if (str) { + cr_tknzr_get_parsing_location + (a_this, &str->location) ; + } + for (;;) { + guchar next_chars[2] = { 0 }; + + PEEK_BYTE (a_this, 1, &next_chars[0]); + PEEK_BYTE (a_this, 2, &next_chars[1]); + + if (next_chars[0] == '\\') { + guchar *tmp_char_ptr1 = NULL, + *tmp_char_ptr2 = NULL; + guint32 esc_code = 0; + + if (next_chars[1] == '\'' || next_chars[1] == '"') { + g_string_append_unichar (str->stryng, + next_chars[1]); + SKIP_BYTES (a_this, 2); + status = CR_OK; + } else { + status = cr_tknzr_parse_escape + (a_this, &esc_code, NULL); + + if (status == CR_OK) { + g_string_append_unichar + (str->stryng, + esc_code); + } + } + + if (status != CR_OK) { + /* + *consume the '\' char, and try to parse + *a newline. + */ + READ_NEXT_CHAR (a_this, &cur_char); + + status = cr_tknzr_parse_nl + (a_this, &tmp_char_ptr1, + &tmp_char_ptr2, NULL); + } + + CHECK_PARSING_STATUS (status, FALSE); + } else if (strchr ("\t !#$%&", next_chars[0]) + || (next_chars[0] >= '(' && next_chars[0] <= '~')) { + READ_NEXT_CHAR (a_this, &cur_char); + g_string_append_unichar (str->stryng, + cur_char); + status = CR_OK; + } + + else if (cr_utils_is_nonascii (next_chars[0])) { + READ_NEXT_CHAR (a_this, &cur_char); + g_string_append_unichar (str->stryng, cur_char); + } else if (next_chars[0] == delim) { + READ_NEXT_CHAR (a_this, &cur_char); + break; + } else { + status = CR_PARSING_ERROR; + goto error; + } + } + + if (status == CR_OK) { + if (*a_str == NULL) { + *a_str = str; + str = NULL; + } else { + (*a_str)->stryng = g_string_append_len + ((*a_str)->stryng, + str->stryng->str, + str->stryng->len); + cr_string_destroy (str); + } + return CR_OK; + } + + error: + + if (str) { + cr_string_destroy (str) ; + str = NULL; + } + cr_tknzr_set_cur_pos (a_this, &init_pos); + return status; +} + +/** + *Parses the an nmstart as defined by the css2 spec [4.1.1]: + * nmstart [a-zA-Z]|{nonascii}|{escape} + * + *@param a_this the current instance of #CRTknzr. + *@param a_start out param. A pointer to the starting point of + *the token. + *@param a_end out param. A pointer to the ending point of the + *token. + *@param a_char out param. The actual parsed nmchar. + *@return CR_OK upon successfull completion, + *an error code otherwise. + */ +static enum CRStatus +cr_tknzr_parse_nmstart (CRTknzr * a_this, + guint32 * a_char, + CRParsingLocation *a_location) +{ + CRInputPos init_pos; + enum CRStatus status = CR_OK; + guint32 cur_char = 0, + next_char = 0; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && PRIVATE (a_this)->input + && a_char, CR_BAD_PARAM_ERROR); + + RECORD_INITIAL_POS (a_this, &init_pos); + + PEEK_NEXT_CHAR (a_this, &next_char); + + if (next_char == '\\') { + status = cr_tknzr_parse_escape (a_this, a_char, + a_location); + + if (status != CR_OK) + goto error; + + } else if (cr_utils_is_nonascii (next_char) == TRUE + || ((next_char >= 'a') && (next_char <= 'z')) + || ((next_char >= 'A') && (next_char <= 'Z')) + ) { + READ_NEXT_CHAR (a_this, &cur_char); + if (a_location) { + cr_tknzr_get_parsing_location (a_this, + a_location) ; + } + *a_char = cur_char; + status = CR_OK; + } else { + status = CR_PARSING_ERROR; + goto error; + } + + return CR_OK; + + error: + cr_tknzr_set_cur_pos (a_this, &init_pos); + + return status; + +} + +/** + *Parses an nmchar as described in the css spec at + *chap 4.1.1: + *nmchar ::= [a-z0-9-]|{nonascii}|{escape} + * + *Humm, I have added the possibility for nmchar to + *contain upper case letters. + * + *@param a_this the current instance of #CRTknzr. + *@param a_start out param. A pointer to the starting point of + *the token. + *@param a_end out param. A pointer to the ending point of the + *token. + *@param a_char out param. The actual parsed nmchar. + *@return CR_OK upon successfull completion, + *an error code otherwise. + */ +static enum CRStatus +cr_tknzr_parse_nmchar (CRTknzr * a_this, guint32 * a_char, + CRParsingLocation *a_location) +{ + guint32 cur_char = 0, + next_char = 0; + enum CRStatus status = CR_OK; + CRInputPos init_pos; + + g_return_val_if_fail (a_this && PRIVATE (a_this) && a_char, + CR_BAD_PARAM_ERROR); + + RECORD_INITIAL_POS (a_this, &init_pos); + + status = cr_input_peek_char (PRIVATE (a_this)->input, + &next_char) ; + if (status != CR_OK) + goto error; + + if (next_char == '\\') { + status = cr_tknzr_parse_escape (a_this, a_char, + a_location); + + if (status != CR_OK) + goto error; + + } else if (cr_utils_is_nonascii (next_char) == TRUE + || ((next_char >= 'a') && (next_char <= 'z')) + || ((next_char >= 'A') && (next_char <= 'Z')) + || ((next_char >= '0') && (next_char <= '9')) + || (next_char == '-') + || (next_char == '_') /*'_' not allowed by the spec. */ + ) { + READ_NEXT_CHAR (a_this, &cur_char); + *a_char = cur_char; + status = CR_OK; + if (a_location) { + cr_tknzr_get_parsing_location + (a_this, a_location) ; + } + } else { + status = CR_PARSING_ERROR; + goto error; + } + return CR_OK; + + error: + cr_tknzr_set_cur_pos (a_this, &init_pos); + return status; +} + +/** + *Parses an "ident" as defined in css spec [4.1.1]: + *ident ::= {nmstart}{nmchar}* + * + *Actually parses it using the css3 grammar: + *ident ::= -?{nmstart}{nmchar}* + *@param a_this the currens instance of #CRTknzr. + * + *@param a_str a pointer to parsed ident. If *a_str is NULL, + *this function allocates a new instance of CRString. If not, + *the function just appends the parsed string to the one passed. + *In both cases it is up to the caller to free *a_str. + * + *@return CR_OK upon successfull completion, an error code + *otherwise. + */ +static enum CRStatus +cr_tknzr_parse_ident (CRTknzr * a_this, CRString ** a_str) +{ + guint32 tmp_char = 0; + CRString *stringue = NULL ; + CRInputPos init_pos; + enum CRStatus status = CR_OK; + gboolean location_is_set = FALSE ; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && PRIVATE (a_this)->input + && a_str, CR_BAD_PARAM_ERROR); + + RECORD_INITIAL_POS (a_this, &init_pos); + PEEK_NEXT_CHAR (a_this, &tmp_char) ; + stringue = cr_string_new () ; + g_return_val_if_fail (stringue, + CR_OUT_OF_MEMORY_ERROR) ; + + if (tmp_char == '-') { + READ_NEXT_CHAR (a_this, &tmp_char) ; + cr_tknzr_get_parsing_location + (a_this, &stringue->location) ; + location_is_set = TRUE ; + g_string_append_unichar (stringue->stryng, + tmp_char) ; + } + status = cr_tknzr_parse_nmstart (a_this, &tmp_char, NULL); + if (status != CR_OK) { + status = CR_PARSING_ERROR; + goto end ; + } + if (location_is_set == FALSE) { + cr_tknzr_get_parsing_location + (a_this, &stringue->location) ; + location_is_set = TRUE ; + } + g_string_append_unichar (stringue->stryng, tmp_char); + for (;;) { + status = cr_tknzr_parse_nmchar (a_this, + &tmp_char, + NULL); + if (status != CR_OK) { + status = CR_OK ; + break; + } + g_string_append_unichar (stringue->stryng, tmp_char); + } + if (status == CR_OK) { + if (!*a_str) { + *a_str = stringue ; + + } else { + g_string_append_len ((*a_str)->stryng, + stringue->stryng->str, + stringue->stryng->len) ; + cr_string_destroy (stringue) ; + } + stringue = NULL ; + } + + error: + end: + if (stringue) { + cr_string_destroy (stringue) ; + stringue = NULL ; + } + if (status != CR_OK ) { + cr_tknzr_set_cur_pos (a_this, &init_pos) ; + } + return status ; +} + + +/** + *Parses a "name" as defined by css spec [4.1.1]: + *name ::= {nmchar}+ + * + *@param a_this the current instance of #CRTknzr. + * + *@param a_str out parameter. A pointer to the successfully parsed + *name. If *a_str is set to NULL, this function allocates a new instance + *of CRString. If not, it just appends the parsed name to the passed *a_str. + *In both cases, it is up to the caller to free *a_str. + * + *@return CR_OK upon successfull completion, an error code otherwise. + */ +static enum CRStatus +cr_tknzr_parse_name (CRTknzr * a_this, + CRString ** a_str) +{ + guint32 tmp_char = 0; + CRInputPos init_pos; + enum CRStatus status = CR_OK; + gboolean str_needs_free = FALSE, + is_first_nmchar=TRUE ; + glong i = 0; + CRParsingLocation loc = {0,0,0} ; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && PRIVATE (a_this)->input + && a_str, + CR_BAD_PARAM_ERROR) ; + + RECORD_INITIAL_POS (a_this, &init_pos); + + if (*a_str == NULL) { + *a_str = cr_string_new (); + str_needs_free = TRUE; + } + for (i = 0;; i++) { + if (is_first_nmchar == TRUE) { + status = cr_tknzr_parse_nmchar + (a_this, &tmp_char, + &loc) ; + is_first_nmchar = FALSE ; + } else { + status = cr_tknzr_parse_nmchar + (a_this, &tmp_char, NULL) ; + } + if (status != CR_OK) + break; + g_string_append_unichar ((*a_str)->stryng, + tmp_char); + } + if (i > 0) { + cr_parsing_location_copy + (&(*a_str)->location, &loc) ; + return CR_OK; + } + if (str_needs_free == TRUE && *a_str) { + cr_string_destroy (*a_str); + *a_str = NULL; + } + cr_tknzr_set_cur_pos (a_this, &init_pos); + return CR_PARSING_ERROR; +} + +/** + *Parses a "hash" as defined by the css spec in [4.1.1]: + *HASH ::= #{name} + */ +static enum CRStatus +cr_tknzr_parse_hash (CRTknzr * a_this, CRString ** a_str) +{ + guint32 cur_char = 0; + CRInputPos init_pos; + enum CRStatus status = CR_OK; + gboolean str_needs_free = FALSE; + CRParsingLocation loc = {0,0,0} ; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && PRIVATE (a_this)->input, + CR_BAD_PARAM_ERROR); + + RECORD_INITIAL_POS (a_this, &init_pos); + READ_NEXT_CHAR (a_this, &cur_char); + if (cur_char != '#') { + status = CR_PARSING_ERROR; + goto error; + } + if (*a_str == NULL) { + *a_str = cr_string_new (); + str_needs_free = TRUE; + } + cr_tknzr_get_parsing_location (a_this, + &loc) ; + status = cr_tknzr_parse_name (a_this, a_str); + cr_parsing_location_copy (&(*a_str)->location, &loc) ; + if (status != CR_OK) { + goto error; + } + return CR_OK; + + error: + if (str_needs_free == TRUE && *a_str) { + cr_string_destroy (*a_str); + *a_str = NULL; + } + + cr_tknzr_set_cur_pos (a_this, &init_pos); + return status; +} + +/** + *Parses an uri as defined by the css spec [4.1.1]: + * URI ::= url\({w}{string}{w}\) + * |url\({w}([!#$%&*-~]|{nonascii}|{escape})*{w}\) + * + *@param a_this the current instance of #CRTknzr. + *@param a_str the successfully parsed url. + *@return CR_OK upon successfull completion, an error code otherwise. + */ +static enum CRStatus +cr_tknzr_parse_uri (CRTknzr * a_this, + CRString ** a_str) +{ + guint32 cur_char = 0; + CRInputPos init_pos; + enum CRStatus status = CR_PARSING_ERROR; + guchar tab[4] = { 0 }, *tmp_ptr1 = NULL, *tmp_ptr2 = NULL; + CRString *str = NULL; + CRParsingLocation location = {0,0,0} ; + + g_return_val_if_fail (a_this + && PRIVATE (a_this) + && PRIVATE (a_this)->input + && a_str, + CR_BAD_PARAM_ERROR); + + RECORD_INITIAL_POS (a_this, &init_pos); + + PEEK_BYTE (a_this, 1, &tab[0]); + PEEK_BYTE (a_this, 2, &tab[1]); + PEEK_BYTE (a_this, 3, &tab[2]); + PEEK_BYTE (a_this, 4, &tab[3]); + + if (tab[0] != 'u' || tab[1] != 'r' || tab[2] != 'l' || tab[3] != '(') { + status = CR_PARSING_ERROR; + goto error; + } + /* + *Here, we want to skip 4 bytes ('u''r''l''('). + *But we also need to keep track of the parsing location + *of the 'u'. So, we skip 1 byte, we record the parsing + *location, then we skip the 3 remaining bytes. + */ + SKIP_CHARS (a_this, 1); + cr_tknzr_get_parsing_location (a_this, &location) ; + SKIP_CHARS (a_this, 3); + cr_tknzr_try_to_skip_spaces (a_this); + status = cr_tknzr_parse_string (a_this, a_str); + + if (status == CR_OK) { + guint32 next_char = 0; + status = cr_tknzr_parse_w (a_this, &tmp_ptr1, + &tmp_ptr2, NULL); + cr_tknzr_try_to_skip_spaces (a_this); + PEEK_NEXT_CHAR (a_this, &next_char); + if (next_char == ')') { + READ_NEXT_CHAR (a_this, &cur_char); + status = CR_OK; + } else { + status = CR_PARSING_ERROR; + } + } + if (status != CR_OK) { + str = cr_string_new (); + for (;;) { + guint32 next_char = 0; + PEEK_NEXT_CHAR (a_this, &next_char); + if (strchr ("!#$%&", next_char) + || (next_char >= '*' && next_char <= '~') + || (cr_utils_is_nonascii (next_char) == TRUE)) { + READ_NEXT_CHAR (a_this, &cur_char); + g_string_append_unichar + (str->stryng, cur_char); + status = CR_OK; + } else { + guint32 esc_code = 0; + status = cr_tknzr_parse_escape + (a_this, &esc_code, NULL); + if (status == CR_OK) { + g_string_append_unichar + (str->stryng, + esc_code); + } else { + status = CR_OK; + break; + } + } + } + cr_tknzr_try_to_skip_spaces (a_this); + READ_NEXT_CHAR (a_this, &cur_char); + if (cur_char == ')') { + status = CR_OK; + } else { + status = CR_PARSING_ERROR; + goto error; + } + if (str) { + if (*a_str == NULL) { + *a_str = str; + str = NULL; + } else { + g_string_append_len + ((*a_str)->stryng, + str->stryng->str, + str->stryng->len); + cr_string_destroy (str); + } + } + } + + cr_parsing_location_copy + (&(*a_str)->location, + &location) ; + return CR_OK ; + error: + if (str) { + cr_string_destroy (str); + str = NULL; + } + cr_tknzr_set_cur_pos (a_this, &init_pos); + return status; +} + +/** + *parses an RGB as defined in the css2 spec. + *rgb: rgb '('S*{num}%?S* ',' {num}#?S*,S*{num}#?S*')' + * + *@param a_this the "this pointer" of the current instance of + *@param a_rgb out parameter the parsed rgb. + *@return CR_OK upon successfull completion, an error code otherwise. + */ +static enum CRStatus +cr_tknzr_parse_rgb (CRTknzr * a_this, CRRgb ** a_rgb) +{ + enum CRStatus status = CR_OK; + CRInputPos init_pos; + CRNum *num = NULL; + guchar next_bytes[3] = { 0 }, cur_byte = 0; + glong red = 0, + green = 0, + blue = 0, + i = 0; + gboolean is_percentage = FALSE; + CRParsingLocation location = {0,0,0} ; + + g_return_val_if_fail (a_this && PRIVATE (a_this), CR_BAD_PARAM_ERROR); + + RECORD_INITIAL_POS (a_this, &init_pos); + + PEEK_BYTE (a_this, 1, &next_bytes[0]); + PEEK_BYTE (a_this, 2, &next_bytes[1]); + PEEK_BYTE (a_this, 3, &next_bytes[2]); + + if (((next_bytes[0] == 'r') || (next_bytes[0] == 'R')) + && ((next_bytes[1] == 'g') || (next_bytes[1] == 'G')) + && ((next_bytes[2] == 'b') || (next_bytes[2] == 'B'))) { + SKIP_CHARS (a_this, 1); + cr_tknzr_get_parsing_location (a_this, &location) ; + SKIP_CHARS (a_this, 2); + } else { + status = CR_PARSING_ERROR; + goto error; + } + READ_NEXT_BYTE (a_this, &cur_byte); + ENSURE_PARSING_COND (cur_byte == '('); + + cr_tknzr_try_to_skip_spaces (a_this); + status = cr_tknzr_parse_num (a_this, &num); + ENSURE_PARSING_COND ((status == CR_OK) && (num != NULL)); + + red = num->val; + cr_num_destroy (num); + num = NULL; + + PEEK_BYTE (a_this, 1, &next_bytes[0]); + if (next_bytes[0] == '%') { + SKIP_CHARS (a_this, 1); + is_percentage = TRUE; + } + cr_tknzr_try_to_skip_spaces (a_this); + + for (i = 0; i < 2; i++) { + READ_NEXT_BYTE (a_this, &cur_byte); + ENSURE_PARSING_COND (cur_byte == ','); + + cr_tknzr_try_to_skip_spaces (a_this); + status = cr_tknzr_parse_num (a_this, &num); + ENSURE_PARSING_COND ((status == CR_OK) && (num != NULL)); + + PEEK_BYTE (a_this, 1, &next_bytes[0]); + if (next_bytes[0] == '%') { + SKIP_CHARS (a_this, 1); + is_percentage = 1; + } + + if (i == 0) { + green = num->val; + } else if (i == 1) { + blue = num->val; + } + + if (num) { + cr_num_destroy (num); + num = NULL; + } + cr_tknzr_try_to_skip_spaces (a_this); + } + + READ_NEXT_BYTE (a_this, &cur_byte); + if (*a_rgb == NULL) { + *a_rgb = cr_rgb_new_with_vals (red, green, blue, + is_percentage); + + if (*a_rgb == NULL) { + status = CR_ERROR; + goto error; + } + status = CR_OK; + } else { + (*a_rgb)->red = red; + (*a_rgb)->green = green; + (*a_rgb)->blue = blue; + (*a_rgb)->is_percentage = is_percentage; + + status = CR_OK; + } + + if (status == CR_OK) { + if (a_rgb && *a_rgb) { + cr_parsing_location_copy + (&(*a_rgb)->location, + &location) ; + } + return CR_OK; + } + + error: + if (num) { + cr_num_destroy (num); + num = NULL; + } + + cr_tknzr_set_cur_pos (a_this, &init_pos); + return CR_OK; +} + +/** + *Parses a atkeyword as defined by the css spec in [4.1.1]: + *ATKEYWORD ::= @{ident} + * + *@param a_this the "this pointer" of the current instance of + *#CRTknzr. + * + *@param a_str out parameter. The parsed atkeyword. If *a_str is + *set to NULL this function allocates a new instance of CRString and + *sets it to the parsed atkeyword. If not, this function just appends + *the parsed atkeyword to the end of *a_str. In both cases it is up to + *the caller to free *a_str. + * + *@return CR_OK upon successfull completion, an error code otherwise. + */ +static enum CRStatus +cr_tknzr_parse_atkeyword (CRTknzr * a_this, + CRString ** a_str) +{ + guint32 cur_char = 0; + CRInputPos init_pos; + gboolean str_needs_free = FALSE; + enum CRStatus status = CR_OK; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && PRIVATE (a_this)->input + && a_str, CR_BAD_PARAM_ERROR); + + RECORD_INITIAL_POS (a_this, &init_pos); + + READ_NEXT_CHAR (a_this, &cur_char); + + if (cur_char != '@') { + status = CR_PARSING_ERROR; + goto error; + } + + if (*a_str == NULL) { + *a_str = cr_string_new (); + str_needs_free = TRUE; + } + status = cr_tknzr_parse_ident (a_this, a_str); + if (status != CR_OK) { + goto error; + } + return CR_OK; + error: + + if (str_needs_free == TRUE && *a_str) { + cr_string_destroy (*a_str); + *a_str = NULL; + } + cr_tknzr_set_cur_pos (a_this, &init_pos); + return status; +} + +static enum CRStatus +cr_tknzr_parse_important (CRTknzr * a_this, + CRParsingLocation *a_location) +{ + guint32 cur_char = 0; + CRInputPos init_pos; + enum CRStatus status = CR_OK; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && PRIVATE (a_this)->input, + CR_BAD_PARAM_ERROR); + + RECORD_INITIAL_POS (a_this, &init_pos); + READ_NEXT_CHAR (a_this, &cur_char); + ENSURE_PARSING_COND (cur_char == '!'); + if (a_location) { + cr_tknzr_get_parsing_location (a_this, + a_location) ; + } + cr_tknzr_try_to_skip_spaces (a_this); + + if (BYTE (PRIVATE (a_this)->input, 1, NULL) == 'i' + && BYTE (PRIVATE (a_this)->input, 2, NULL) == 'm' + && BYTE (PRIVATE (a_this)->input, 3, NULL) == 'p' + && BYTE (PRIVATE (a_this)->input, 4, NULL) == 'o' + && BYTE (PRIVATE (a_this)->input, 5, NULL) == 'r' + && BYTE (PRIVATE (a_this)->input, 6, NULL) == 't' + && BYTE (PRIVATE (a_this)->input, 7, NULL) == 'a' + && BYTE (PRIVATE (a_this)->input, 8, NULL) == 'n' + && BYTE (PRIVATE (a_this)->input, 9, NULL) == 't') { + SKIP_BYTES (a_this, 9); + if (a_location) { + cr_tknzr_get_parsing_location (a_this, + a_location) ; + } + return CR_OK; + } else { + status = CR_PARSING_ERROR; + } + + error: + cr_tknzr_set_cur_pos (a_this, &init_pos); + + return status; +} + +/** + *Parses a num as defined in the css spec [4.1.1]: + *[0-9]+|[0-9]*\.[0-9]+ + *@param a_this the current instance of #CRTknzr. + *@param a_num out parameter. The parsed number. + *@return CR_OK upon successfull completion, + *an error code otherwise. + */ +static enum CRStatus +cr_tknzr_parse_num (CRTknzr * a_this, + CRNum ** a_num) +{ + enum CRStatus status = CR_PARSING_ERROR; + enum CRNumType val_type = NUM_GENERIC; + gboolean parsing_dec, /* true iff seen decimal point. */ + parsed; /* true iff the substring seen so far is a valid CSS + number, i.e. `[0-9]+|[0-9]*\.[0-9]+'. */ + guint32 cur_char = 0, + next_char = 0; + gdouble numerator, denominator = 1; + CRInputPos init_pos; + CRParsingLocation location = {0,0,0} ; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && PRIVATE (a_this)->input, + CR_BAD_PARAM_ERROR); + + RECORD_INITIAL_POS (a_this, &init_pos); + READ_NEXT_CHAR (a_this, &cur_char); + if (IS_NUM (cur_char)) { + numerator = (cur_char - '0'); + parsing_dec = FALSE; + parsed = TRUE; + } else if (cur_char == '.') { + numerator = 0; + parsing_dec = TRUE; + parsed = FALSE; + } else { + status = CR_PARSING_ERROR; + goto error; + } + cr_tknzr_get_parsing_location (a_this, &location) ; + + for (;;) { + status = cr_tknzr_peek_char (a_this, &next_char); + if (status != CR_OK) { + if (status == CR_END_OF_INPUT_ERROR) + status = CR_OK; + break; + } + if (next_char == '.') { + if (parsing_dec) { + status = CR_PARSING_ERROR; + goto error; + } + + READ_NEXT_CHAR (a_this, &cur_char); + parsing_dec = TRUE; + parsed = FALSE; /* In CSS, there must be at least + one digit after `.'. */ + } else if (IS_NUM (next_char)) { + READ_NEXT_CHAR (a_this, &cur_char); + parsed = TRUE; + + numerator = numerator * 10 + (cur_char - '0'); + if (parsing_dec) { + denominator *= 10; + } + } else { + break; + } + } + + if (!parsed) { + status = CR_PARSING_ERROR; + } + + /* + *Now, set the output param values. + */ + if (status == CR_OK) { + gdouble val = numerator / denominator; + if (*a_num == NULL) { + *a_num = cr_num_new_with_val (val, val_type); + + if (*a_num == NULL) { + status = CR_ERROR; + goto error; + } + } else { + (*a_num)->val = val; + (*a_num)->type = val_type; + } + cr_parsing_location_copy (&(*a_num)->location, + &location) ; + return CR_OK; + } + + error: + + cr_tknzr_set_cur_pos (a_this, &init_pos); + + return status; +} + +/********************************************* + *PUBLIC methods + ********************************************/ + +CRTknzr * +cr_tknzr_new (CRInput * a_input) +{ + CRTknzr *result = NULL; + + result = g_try_malloc (sizeof (CRTknzr)); + + if (result == NULL) { + cr_utils_trace_info ("Out of memory"); + return NULL; + } + + memset (result, 0, sizeof (CRTknzr)); + + result->priv = g_try_malloc (sizeof (CRTknzrPriv)); + + if (result->priv == NULL) { + cr_utils_trace_info ("Out of memory"); + + if (result) { + g_free (result); + result = NULL; + } + + return NULL; + } + memset (result->priv, 0, sizeof (CRTknzrPriv)); + if (a_input) + cr_tknzr_set_input (result, a_input); + return result; +} + +CRTknzr * +cr_tknzr_new_from_buf (guchar * a_buf, gulong a_len, + enum CREncoding a_enc, + gboolean a_free_at_destroy) +{ + CRTknzr *result = NULL; + CRInput *input = NULL; + + input = cr_input_new_from_buf (a_buf, a_len, a_enc, + a_free_at_destroy); + + g_return_val_if_fail (input != NULL, NULL); + + result = cr_tknzr_new (input); + + return result; +} + +CRTknzr * +cr_tknzr_new_from_uri (const guchar * a_file_uri, + enum CREncoding a_enc) +{ + CRTknzr *result = NULL; + CRInput *input = NULL; + + input = cr_input_new_from_uri (a_file_uri, a_enc); + g_return_val_if_fail (input != NULL, NULL); + + result = cr_tknzr_new (input); + + return result; +} + +void +cr_tknzr_ref (CRTknzr * a_this) +{ + g_return_if_fail (a_this && PRIVATE (a_this)); + + PRIVATE (a_this)->ref_count++; +} + +gboolean +cr_tknzr_unref (CRTknzr * a_this) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this), FALSE); + + if (PRIVATE (a_this)->ref_count > 0) { + PRIVATE (a_this)->ref_count--; + } + + if (PRIVATE (a_this)->ref_count == 0) { + cr_tknzr_destroy (a_this); + return TRUE; + } + + return FALSE; +} + +enum CRStatus +cr_tknzr_set_input (CRTknzr * a_this, CRInput * a_input) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this), CR_BAD_PARAM_ERROR); + + if (PRIVATE (a_this)->input) { + cr_input_unref (PRIVATE (a_this)->input); + } + + PRIVATE (a_this)->input = a_input; + + cr_input_ref (PRIVATE (a_this)->input); + + return CR_OK; +} + +enum CRStatus +cr_tknzr_get_input (CRTknzr * a_this, CRInput ** a_input) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this), CR_BAD_PARAM_ERROR); + + *a_input = PRIVATE (a_this)->input; + + return CR_OK; +} + +/********************************* + *Tokenizer input handling routines + *********************************/ + +/** + *Reads the next byte from the parser input stream. + *@param a_this the "this pointer" of the current instance of + *#CRParser. + *@param a_byte out parameter the place where to store the byte + *read. + *@return CR_OK upon successfull completion, an error + *code otherwise. + */ +enum CRStatus +cr_tknzr_read_byte (CRTknzr * a_this, guchar * a_byte) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this), CR_BAD_PARAM_ERROR); + + return cr_input_read_byte (PRIVATE (a_this)->input, a_byte); + +} + +/** + *Reads the next char from the parser input stream. + *@param a_this the current instance of #CRTknzr. + *@param a_char out parameter. The read char. + *@return CR_OK upon successfull completion, an error code + *otherwise. + */ +enum CRStatus +cr_tknzr_read_char (CRTknzr * a_this, guint32 * a_char) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this) + && PRIVATE (a_this)->input + && a_char, CR_BAD_PARAM_ERROR); + + if (PRIVATE (a_this)->token_cache) { + cr_input_set_cur_pos (PRIVATE (a_this)->input, + &PRIVATE (a_this)->prev_pos); + cr_token_destroy (PRIVATE (a_this)->token_cache); + PRIVATE (a_this)->token_cache = NULL; + } + + return cr_input_read_char (PRIVATE (a_this)->input, a_char); +} + +/** + *Peeks a char from the parser input stream. + *To "peek a char" means reads the next char without consuming it. + *Subsequent calls to this function return the same char. + *@param a_this the current instance of #CRTknzr. + *@param a_char out parameter. The peeked char uppon successfull completion. + *@return CR_OK upon successfull completion, an error code otherwise. + */ +enum CRStatus +cr_tknzr_peek_char (CRTknzr * a_this, guint32 * a_char) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this) + && PRIVATE (a_this)->input + && a_char, CR_BAD_PARAM_ERROR); + + if (PRIVATE (a_this)->token_cache) { + cr_input_set_cur_pos (PRIVATE (a_this)->input, + &PRIVATE (a_this)->prev_pos); + cr_token_destroy (PRIVATE (a_this)->token_cache); + PRIVATE (a_this)->token_cache = NULL; + } + + return cr_input_peek_char (PRIVATE (a_this)->input, a_char); +} + +/** + *Peeks a byte ahead at a given postion in the parser input stream. + *@param a_this the current instance of #CRTknzr. + *@param a_offset the offset of the peeked byte starting from the current + *byte in the parser input stream. + *@param a_byte out parameter. The peeked byte upon + *successfull completion. + *@return CR_OK upon successfull completion, an error code otherwise. + */ +enum CRStatus +cr_tknzr_peek_byte (CRTknzr * a_this, gulong a_offset, guchar * a_byte) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this) + && PRIVATE (a_this)->input && a_byte, + CR_BAD_PARAM_ERROR); + + if (PRIVATE (a_this)->token_cache) { + cr_input_set_cur_pos (PRIVATE (a_this)->input, + &PRIVATE (a_this)->prev_pos); + cr_token_destroy (PRIVATE (a_this)->token_cache); + PRIVATE (a_this)->token_cache = NULL; + } + + return cr_input_peek_byte (PRIVATE (a_this)->input, + CR_SEEK_CUR, a_offset, a_byte); +} + +/** + *Same as cr_tknzr_peek_byte() but this api returns the byte peeked. + *@param a_this the current instance of #CRTknzr. + *@param a_offset the offset of the peeked byte starting from the current + *byte in the parser input stream. + *@param a_eof out parameter. If not NULL, is set to TRUE if we reached end of + *file, FALE otherwise. If the caller sets it to NULL, this parameter + *is just ignored. + *@return the peeked byte. + */ +guchar +cr_tknzr_peek_byte2 (CRTknzr * a_this, gulong a_offset, gboolean * a_eof) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this) + && PRIVATE (a_this)->input, 0); + + return cr_input_peek_byte2 (PRIVATE (a_this)->input, a_offset, a_eof); +} + +/** + *Gets the number of bytes left in the topmost input stream + *associated to this parser. + *@param a_this the current instance of #CRTknzr + *@return the number of bytes left or -1 in case of error. + */ +glong +cr_tknzr_get_nb_bytes_left (CRTknzr * a_this) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this) + && PRIVATE (a_this)->input, CR_BAD_PARAM_ERROR); + + if (PRIVATE (a_this)->token_cache) { + cr_input_set_cur_pos (PRIVATE (a_this)->input, + &PRIVATE (a_this)->prev_pos); + cr_token_destroy (PRIVATE (a_this)->token_cache); + PRIVATE (a_this)->token_cache = NULL; + } + + return cr_input_get_nb_bytes_left (PRIVATE (a_this)->input); +} + +enum CRStatus +cr_tknzr_get_cur_pos (CRTknzr * a_this, CRInputPos * a_pos) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this) + && PRIVATE (a_this)->input + && a_pos, CR_BAD_PARAM_ERROR); + + if (PRIVATE (a_this)->token_cache) { + cr_input_set_cur_pos (PRIVATE (a_this)->input, + &PRIVATE (a_this)->prev_pos); + cr_token_destroy (PRIVATE (a_this)->token_cache); + PRIVATE (a_this)->token_cache = NULL; + } + + return cr_input_get_cur_pos (PRIVATE (a_this)->input, a_pos); +} + +enum CRStatus +cr_tknzr_get_parsing_location (CRTknzr *a_this, + CRParsingLocation *a_loc) +{ + g_return_val_if_fail (a_this + && PRIVATE (a_this) + && a_loc, + CR_BAD_PARAM_ERROR) ; + + return cr_input_get_parsing_location + (PRIVATE (a_this)->input, a_loc) ; +} + +enum CRStatus +cr_tknzr_get_cur_byte_addr (CRTknzr * a_this, guchar ** a_addr) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this) + && PRIVATE (a_this)->input, CR_BAD_PARAM_ERROR); + if (PRIVATE (a_this)->token_cache) { + cr_input_set_cur_pos (PRIVATE (a_this)->input, + &PRIVATE (a_this)->prev_pos); + cr_token_destroy (PRIVATE (a_this)->token_cache); + PRIVATE (a_this)->token_cache = NULL; + } + + return cr_input_get_cur_byte_addr (PRIVATE (a_this)->input, a_addr); +} + +enum CRStatus +cr_tknzr_seek_index (CRTknzr * a_this, enum CRSeekPos a_origin, gint a_pos) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this) + && PRIVATE (a_this)->input, CR_BAD_PARAM_ERROR); + + if (PRIVATE (a_this)->token_cache) { + cr_input_set_cur_pos (PRIVATE (a_this)->input, + &PRIVATE (a_this)->prev_pos); + cr_token_destroy (PRIVATE (a_this)->token_cache); + PRIVATE (a_this)->token_cache = NULL; + } + + return cr_input_seek_index (PRIVATE (a_this)->input, a_origin, a_pos); +} + +enum CRStatus +cr_tknzr_consume_chars (CRTknzr * a_this, guint32 a_char, glong * a_nb_char) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this) + && PRIVATE (a_this)->input, CR_BAD_PARAM_ERROR); + + if (PRIVATE (a_this)->token_cache) { + cr_input_set_cur_pos (PRIVATE (a_this)->input, + &PRIVATE (a_this)->prev_pos); + cr_token_destroy (PRIVATE (a_this)->token_cache); + PRIVATE (a_this)->token_cache = NULL; + } + + return cr_input_consume_chars (PRIVATE (a_this)->input, + a_char, a_nb_char); +} + +enum CRStatus +cr_tknzr_set_cur_pos (CRTknzr * a_this, CRInputPos * a_pos) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this) + && PRIVATE (a_this)->input, CR_BAD_PARAM_ERROR); + + if (PRIVATE (a_this)->token_cache) { + cr_token_destroy (PRIVATE (a_this)->token_cache); + PRIVATE (a_this)->token_cache = NULL; + } + + return cr_input_set_cur_pos (PRIVATE (a_this)->input, a_pos); +} + +enum CRStatus +cr_tknzr_unget_token (CRTknzr * a_this, CRToken * a_token) +{ + g_return_val_if_fail (a_this && PRIVATE (a_this) + && PRIVATE (a_this)->token_cache == NULL, + CR_BAD_PARAM_ERROR); + + PRIVATE (a_this)->token_cache = a_token; + + return CR_OK; +} + +/** + *Returns the next token of the input stream. + *This method is really central. Each parsing + *method calls it. + *@param a_this the current tokenizer. + *@param a_tk out parameter. The returned token. + *for the sake of mem leak avoidance, *a_tk must + *be NULL. + *@param CR_OK upon successfull completion, an error code + *otherwise. + */ +enum CRStatus +cr_tknzr_get_next_token (CRTknzr * a_this, CRToken ** a_tk) +{ + enum CRStatus status = CR_OK; + CRToken *token = NULL; + CRInputPos init_pos; + guint32 next_char = 0; + guchar next_bytes[4] = { 0 }; + gboolean reached_eof = FALSE; + CRInput *input = NULL; + CRString *str = NULL; + CRRgb *rgb = NULL; + CRParsingLocation location = {0,0,0} ; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && a_tk && *a_tk == NULL + && PRIVATE (a_this)->input, + CR_BAD_PARAM_ERROR); + + if (PRIVATE (a_this)->token_cache) { + *a_tk = PRIVATE (a_this)->token_cache; + PRIVATE (a_this)->token_cache = NULL; + return CR_OK; + } + + RECORD_INITIAL_POS (a_this, &init_pos); + + status = cr_input_get_end_of_file + (PRIVATE (a_this)->input, &reached_eof); + ENSURE_PARSING_COND (status == CR_OK); + + if (reached_eof == TRUE) { + status = CR_END_OF_INPUT_ERROR; + goto error; + } + + input = PRIVATE (a_this)->input; + + PEEK_NEXT_CHAR (a_this, &next_char); + token = cr_token_new (); + ENSURE_PARSING_COND (token); + + switch (next_char) { + case '@': + { + if (BYTE (input, 2, NULL) == 'f' + && BYTE (input, 3, NULL) == 'o' + && BYTE (input, 4, NULL) == 'n' + && BYTE (input, 5, NULL) == 't' + && BYTE (input, 6, NULL) == '-' + && BYTE (input, 7, NULL) == 'f' + && BYTE (input, 8, NULL) == 'a' + && BYTE (input, 9, NULL) == 'c' + && BYTE (input, 10, NULL) == 'e') { + SKIP_CHARS (a_this, 1); + cr_tknzr_get_parsing_location + (a_this, &location) ; + SKIP_CHARS (a_this, 9); + status = cr_token_set_font_face_sym (token); + CHECK_PARSING_STATUS (status, TRUE); + cr_parsing_location_copy (&token->location, + &location) ; + goto done; + } + + if (BYTE (input, 2, NULL) == 'c' + && BYTE (input, 3, NULL) == 'h' + && BYTE (input, 4, NULL) == 'a' + && BYTE (input, 5, NULL) == 'r' + && BYTE (input, 6, NULL) == 's' + && BYTE (input, 7, NULL) == 'e' + && BYTE (input, 8, NULL) == 't') { + SKIP_CHARS (a_this, 1); + cr_tknzr_get_parsing_location + (a_this, &location) ; + SKIP_CHARS (a_this, 7); + status = cr_token_set_charset_sym (token); + CHECK_PARSING_STATUS (status, TRUE); + cr_parsing_location_copy (&token->location, + &location) ; + goto done; + } + + if (BYTE (input, 2, NULL) == 'i' + && BYTE (input, 3, NULL) == 'm' + && BYTE (input, 4, NULL) == 'p' + && BYTE (input, 5, NULL) == 'o' + && BYTE (input, 6, NULL) == 'r' + && BYTE (input, 7, NULL) == 't') { + SKIP_CHARS (a_this, 1); + cr_tknzr_get_parsing_location + (a_this, &location) ; + SKIP_CHARS (a_this, 6); + status = cr_token_set_import_sym (token); + CHECK_PARSING_STATUS (status, TRUE); + cr_parsing_location_copy (&token->location, + &location) ; + goto done; + } + + if (BYTE (input, 2, NULL) == 'm' + && BYTE (input, 3, NULL) == 'e' + && BYTE (input, 4, NULL) == 'd' + && BYTE (input, 5, NULL) == 'i' + && BYTE (input, 6, NULL) == 'a') { + SKIP_CHARS (a_this, 1); + cr_tknzr_get_parsing_location (a_this, + &location) ; + SKIP_CHARS (a_this, 5); + status = cr_token_set_media_sym (token); + CHECK_PARSING_STATUS (status, TRUE); + cr_parsing_location_copy (&token->location, + &location) ; + goto done; + } + + if (BYTE (input, 2, NULL) == 'p' + && BYTE (input, 3, NULL) == 'a' + && BYTE (input, 4, NULL) == 'g' + && BYTE (input, 5, NULL) == 'e') { + SKIP_CHARS (a_this, 1); + cr_tknzr_get_parsing_location (a_this, + &location) ; + SKIP_CHARS (a_this, 4); + status = cr_token_set_page_sym (token); + CHECK_PARSING_STATUS (status, TRUE); + cr_parsing_location_copy (&token->location, + &location) ; + goto done; + } + status = cr_tknzr_parse_atkeyword (a_this, &str); + if (status == CR_OK) { + status = cr_token_set_atkeyword (token, str); + CHECK_PARSING_STATUS (status, TRUE); + if (str) { + cr_parsing_location_copy (&token->location, + &str->location) ; + } + goto done; + } + } + break; + + case 'u': + + if (BYTE (input, 2, NULL) == 'r' + && BYTE (input, 3, NULL) == 'l' + && BYTE (input, 4, NULL) == '(') { + CRString *str = NULL; + + status = cr_tknzr_parse_uri (a_this, &str); + if (status == CR_OK) { + status = cr_token_set_uri (token, str); + CHECK_PARSING_STATUS (status, TRUE); + if (str) { + cr_parsing_location_copy (&token->location, + &str->location) ; + } + goto done; + } + } else { + status = cr_tknzr_parse_ident (a_this, &str); + if (status == CR_OK && str) { + status = cr_token_set_ident (token, str); + CHECK_PARSING_STATUS (status, TRUE); + if (str) { + cr_parsing_location_copy (&token->location, + &str->location) ; + } + goto done; + } + } + break; + + case 'r': + if (BYTE (input, 2, NULL) == 'g' + && BYTE (input, 3, NULL) == 'b' + && BYTE (input, 4, NULL) == '(') { + status = cr_tknzr_parse_rgb (a_this, &rgb); + if (status == CR_OK && rgb) { + status = cr_token_set_rgb (token, rgb); + CHECK_PARSING_STATUS (status, TRUE); + if (rgb) { + cr_parsing_location_copy (&token->location, + &rgb->location) ; + } + rgb = NULL; + goto done; + } + + } else { + status = cr_tknzr_parse_ident (a_this, &str); + if (status == CR_OK) { + status = cr_token_set_ident (token, str); + CHECK_PARSING_STATUS (status, TRUE); + if (str) { + cr_parsing_location_copy (&token->location, + &str->location) ; + } + str = NULL; + goto done; + } + } + break; + + case '<': + if (BYTE (input, 2, NULL) == '-' + && BYTE (input, 3, NULL) == '-') { + SKIP_CHARS (a_this, 1); + cr_tknzr_get_parsing_location (a_this, + &location) ; + SKIP_CHARS (a_this, 2); + status = cr_token_set_cdo (token); + CHECK_PARSING_STATUS (status, TRUE); + cr_parsing_location_copy (&token->location, + &location) ; + goto done; + } + break; + + case '-': + if (BYTE (input, 2, NULL) == '-' + && BYTE (input, 3, NULL) == '>') { + SKIP_CHARS (a_this, 1); + cr_tknzr_get_parsing_location (a_this, + &location) ; + SKIP_CHARS (a_this, 2); + status = cr_token_set_cdc (token); + CHECK_PARSING_STATUS (status, TRUE); + cr_parsing_location_copy (&token->location, + &location) ; + goto done; + } else { + status = cr_tknzr_parse_ident + (a_this, &str); + if (status == CR_OK) { + cr_token_set_ident + (token, str); + if (str) { + cr_parsing_location_copy (&token->location, + &str->location) ; + } + goto done; + } + } + break; + + case '~': + if (BYTE (input, 2, NULL) == '=') { + SKIP_CHARS (a_this, 1); + cr_tknzr_get_parsing_location (a_this, + &location) ; + SKIP_CHARS (a_this, 1); + status = cr_token_set_includes (token); + CHECK_PARSING_STATUS (status, TRUE); + cr_parsing_location_copy (&token->location, + &location) ; + goto done; + } + break; + + case '|': + if (BYTE (input, 2, NULL) == '=') { + SKIP_CHARS (a_this, 1); + cr_tknzr_get_parsing_location (a_this, + &location) ; + SKIP_CHARS (a_this, 1); + status = cr_token_set_dashmatch (token); + CHECK_PARSING_STATUS (status, TRUE); + cr_parsing_location_copy (&token->location, + &location) ; + goto done; + } + break; + + case '/': + if (BYTE (input, 2, NULL) == '*') { + status = cr_tknzr_parse_comment (a_this, &str); + + if (status == CR_OK) { + status = cr_token_set_comment (token, str); + str = NULL; + CHECK_PARSING_STATUS (status, TRUE); + if (str) { + cr_parsing_location_copy (&token->location, + &str->location) ; + } + goto done; + } + } + break ; + + case ';': + SKIP_CHARS (a_this, 1); + cr_tknzr_get_parsing_location (a_this, + &location) ; + status = cr_token_set_semicolon (token); + CHECK_PARSING_STATUS (status, TRUE); + cr_parsing_location_copy (&token->location, + &location) ; + goto done; + + case '{': + SKIP_CHARS (a_this, 1); + cr_tknzr_get_parsing_location (a_this, + &location) ; + status = cr_token_set_cbo (token); + CHECK_PARSING_STATUS (status, TRUE); + cr_tknzr_get_parsing_location (a_this, + &location) ; + goto done; + + case '}': + SKIP_CHARS (a_this, 1); + cr_tknzr_get_parsing_location (a_this, + &location) ; + status = cr_token_set_cbc (token); + CHECK_PARSING_STATUS (status, TRUE); + cr_parsing_location_copy (&token->location, + &location) ; + goto done; + + case '(': + SKIP_CHARS (a_this, 1); + cr_tknzr_get_parsing_location (a_this, + &location) ; + status = cr_token_set_po (token); + CHECK_PARSING_STATUS (status, TRUE); + cr_parsing_location_copy (&token->location, + &location) ; + goto done; + + case ')': + SKIP_CHARS (a_this, 1); + cr_tknzr_get_parsing_location (a_this, + &location) ; + status = cr_token_set_pc (token); + CHECK_PARSING_STATUS (status, TRUE); + cr_parsing_location_copy (&token->location, + &location) ; + goto done; + + case '[': + SKIP_CHARS (a_this, 1); + cr_tknzr_get_parsing_location (a_this, + &location) ; + status = cr_token_set_bo (token); + CHECK_PARSING_STATUS (status, TRUE); + cr_parsing_location_copy (&token->location, + &location) ; + goto done; + + case ']': + SKIP_CHARS (a_this, 1); + cr_tknzr_get_parsing_location (a_this, + &location) ; + status = cr_token_set_bc (token); + CHECK_PARSING_STATUS (status, TRUE); + cr_parsing_location_copy (&token->location, + &location) ; + goto done; + + case ' ': + case '\t': + case '\n': + case '\f': + case '\r': + { + guchar *start = NULL, + *end = NULL; + + status = cr_tknzr_parse_w (a_this, &start, + &end, &location); + if (status == CR_OK) { + status = cr_token_set_s (token); + CHECK_PARSING_STATUS (status, TRUE); + cr_tknzr_get_parsing_location (a_this, + &location) ; + goto done; + } + } + break; + + case '#': + { + status = cr_tknzr_parse_hash (a_this, &str); + if (status == CR_OK && str) { + status = cr_token_set_hash (token, str); + CHECK_PARSING_STATUS (status, TRUE); + if (str) { + cr_parsing_location_copy (&token->location, + &str->location) ; + } + str = NULL; + goto done; + } + } + break; + + case '\'': + case '"': + status = cr_tknzr_parse_string (a_this, &str); + if (status == CR_OK && str) { + status = cr_token_set_string (token, str); + CHECK_PARSING_STATUS (status, TRUE); + if (str) { + cr_parsing_location_copy (&token->location, + &str->location) ; + } + str = NULL; + goto done; + } + break; + + case '!': + status = cr_tknzr_parse_important (a_this, &location); + if (status == CR_OK) { + status = cr_token_set_important_sym (token); + CHECK_PARSING_STATUS (status, TRUE); + cr_parsing_location_copy (&token->location, + &location) ; + goto done; + } + break; + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case '.': + { + CRNum *num = NULL; + + status = cr_tknzr_parse_num (a_this, &num); + if (status == CR_OK && num) { + next_bytes[0] = BYTE (input, 1, NULL); + next_bytes[1] = BYTE (input, 2, NULL); + next_bytes[2] = BYTE (input, 3, NULL); + next_bytes[3] = BYTE (input, 3, NULL); + + if (next_bytes[0] == 'e' + && next_bytes[1] == 'm') { + num->type = NUM_LENGTH_EM; + status = cr_token_set_ems (token, + num); + num = NULL; + SKIP_CHARS (a_this, 2); + } else if (next_bytes[0] == 'e' + && next_bytes[1] == 'x') { + num->type = NUM_LENGTH_EX; + status = cr_token_set_exs (token, + num); + num = NULL; + SKIP_CHARS (a_this, 2); + } else if (next_bytes[0] == 'p' + && next_bytes[1] == 'x') { + num->type = NUM_LENGTH_PX; + status = cr_token_set_length + (token, num, LENGTH_PX_ET); + num = NULL; + SKIP_CHARS (a_this, 2); + } else if (next_bytes[0] == 'c' + && next_bytes[1] == 'm') { + num->type = NUM_LENGTH_CM; + status = cr_token_set_length + (token, num, LENGTH_CM_ET); + num = NULL; + SKIP_CHARS (a_this, 2); + } else if (next_bytes[0] == 'm' + && next_bytes[1] == 'm') { + num->type = NUM_LENGTH_MM; + status = cr_token_set_length + (token, num, LENGTH_MM_ET); + num = NULL; + SKIP_CHARS (a_this, 2); + } else if (next_bytes[0] == 'i' + && next_bytes[1] == 'n') { + num->type = NUM_LENGTH_IN; + status = cr_token_set_length + (token, num, LENGTH_IN_ET); + num = NULL; + SKIP_CHARS (a_this, 2); + } else if (next_bytes[0] == 'p' + && next_bytes[1] == 't') { + num->type = NUM_LENGTH_PT; + status = cr_token_set_length + (token, num, LENGTH_PT_ET); + num = NULL; + SKIP_CHARS (a_this, 2); + } else if (next_bytes[0] == 'p' + && next_bytes[1] == 'c') { + num->type = NUM_LENGTH_PC; + status = cr_token_set_length + (token, num, LENGTH_PC_ET); + num = NULL; + SKIP_CHARS (a_this, 2); + } else if (next_bytes[0] == 'd' + && next_bytes[1] == 'e' + && next_bytes[2] == 'g') { + num->type = NUM_ANGLE_DEG; + status = cr_token_set_angle + (token, num, ANGLE_DEG_ET); + num = NULL; + SKIP_CHARS (a_this, 3); + } else if (next_bytes[0] == 'r' + && next_bytes[1] == 'a' + && next_bytes[2] == 'd') { + num->type = NUM_ANGLE_RAD; + status = cr_token_set_angle + (token, num, ANGLE_RAD_ET); + num = NULL; + SKIP_CHARS (a_this, 3); + } else if (next_bytes[0] == 'g' + && next_bytes[1] == 'r' + && next_bytes[2] == 'a' + && next_bytes[3] == 'd') { + num->type = NUM_ANGLE_GRAD; + status = cr_token_set_angle + (token, num, ANGLE_GRAD_ET); + num = NULL; + SKIP_CHARS (a_this, 4); + } else if (next_bytes[0] == 'm' + && next_bytes[1] == 's') { + num->type = NUM_TIME_MS; + status = cr_token_set_time + (token, num, TIME_MS_ET); + num = NULL; + SKIP_CHARS (a_this, 2); + } else if (next_bytes[0] == 's') { + num->type = NUM_TIME_S; + status = cr_token_set_time + (token, num, TIME_S_ET); + num = NULL; + SKIP_CHARS (a_this, 1); + } else if (next_bytes[0] == 'H' + && next_bytes[1] == 'z') { + num->type = NUM_FREQ_HZ; + status = cr_token_set_freq + (token, num, FREQ_HZ_ET); + num = NULL; + SKIP_CHARS (a_this, 2); + } else if (next_bytes[0] == 'k' + && next_bytes[1] == 'H' + && next_bytes[2] == 'z') { + num->type = NUM_FREQ_KHZ; + status = cr_token_set_freq + (token, num, FREQ_KHZ_ET); + num = NULL; + SKIP_CHARS (a_this, 3); + } else if (next_bytes[0] == '%') { + num->type = NUM_PERCENTAGE; + status = cr_token_set_percentage + (token, num); + num = NULL; + SKIP_CHARS (a_this, 1); + } else { + status = cr_tknzr_parse_ident (a_this, + &str); + if (status == CR_OK && str) { + num->type = NUM_UNKNOWN_TYPE; + status = cr_token_set_dimen + (token, num, str); + num = NULL; + CHECK_PARSING_STATUS (status, + TRUE); + str = NULL; + } else { + status = cr_token_set_number + (token, num); + num = NULL; + CHECK_PARSING_STATUS (status, CR_OK); + str = NULL; + } + } + if (token && token->u.num) { + cr_parsing_location_copy (&token->location, + &token->u.num->location) ; + } else { + status = CR_ERROR ; + } + goto done ; + } + } + break; + + default: + /*process the fallback cases here */ + + if (next_char == '\\' + || (cr_utils_is_nonascii (next_bytes[0]) == TRUE) + || ((next_char >= 'a') && (next_char <= 'z')) + || ((next_char >= 'A') && (next_char <= 'Z'))) { + status = cr_tknzr_parse_ident (a_this, &str); + if (status == CR_OK && str) { + guint32 next_c = 0; + + status = cr_input_peek_char + (PRIVATE (a_this)->input, &next_c); + + if (status == CR_OK && next_c == '(') { + + SKIP_CHARS (a_this, 1); + status = cr_token_set_function + (token, str); + CHECK_PARSING_STATUS (status, TRUE); + /*ownership is transfered + *to token by cr_token_set_function. + */ + if (str) { + cr_parsing_location_copy (&token->location, + &str->location) ; + } + str = NULL; + } else { + status = cr_token_set_ident (token, + str); + CHECK_PARSING_STATUS (status, TRUE); + if (str) { + cr_parsing_location_copy (&token->location, + &str->location) ; + } + str = NULL; + } + goto done; + } else { + if (str) { + cr_string_destroy (str); + str = NULL; + } + } + } + break; + } + + READ_NEXT_CHAR (a_this, &next_char); + cr_tknzr_get_parsing_location (a_this, + &location) ; + status = cr_token_set_delim (token, next_char); + CHECK_PARSING_STATUS (status, TRUE); + cr_parsing_location_copy (&token->location, + &location) ; + done: + + if (status == CR_OK && token) { + *a_tk = token; + /* + *store the previous position input stream pos. + */ + memmove (&PRIVATE (a_this)->prev_pos, + &init_pos, sizeof (CRInputPos)); + return CR_OK; + } + + error: + if (token) { + cr_token_destroy (token); + token = NULL; + } + + if (str) { + cr_string_destroy (str); + str = NULL; + } + cr_tknzr_set_cur_pos (a_this, &init_pos); + return status; + +} + +enum CRStatus +cr_tknzr_parse_token (CRTknzr * a_this, enum CRTokenType a_type, + enum CRTokenExtraType a_et, gpointer a_res, + gpointer a_extra_res) +{ + enum CRStatus status = CR_OK; + CRToken *token = NULL; + + g_return_val_if_fail (a_this && PRIVATE (a_this) + && PRIVATE (a_this)->input + && a_res, CR_BAD_PARAM_ERROR); + + status = cr_tknzr_get_next_token (a_this, &token); + if (status != CR_OK) + return status; + if (token == NULL) + return CR_PARSING_ERROR; + + if (token->type == a_type) { + switch (a_type) { + case NO_TK: + case S_TK: + case CDO_TK: + case CDC_TK: + case INCLUDES_TK: + case DASHMATCH_TK: + case IMPORT_SYM_TK: + case PAGE_SYM_TK: + case MEDIA_SYM_TK: + case FONT_FACE_SYM_TK: + case CHARSET_SYM_TK: + case IMPORTANT_SYM_TK: + status = CR_OK; + break; + + case STRING_TK: + case IDENT_TK: + case HASH_TK: + case ATKEYWORD_TK: + case FUNCTION_TK: + case COMMENT_TK: + case URI_TK: + *((CRString **) a_res) = token->u.str; + token->u.str = NULL; + status = CR_OK; + break; + + case EMS_TK: + case EXS_TK: + case PERCENTAGE_TK: + case NUMBER_TK: + *((CRNum **) a_res) = token->u.num; + token->u.num = NULL; + status = CR_OK; + break; + + case LENGTH_TK: + case ANGLE_TK: + case TIME_TK: + case FREQ_TK: + if (token->extra_type == a_et) { + *((CRNum **) a_res) = token->u.num; + token->u.num = NULL; + status = CR_OK; + } + break; + + case DIMEN_TK: + *((CRNum **) a_res) = token->u.num; + if (a_extra_res == NULL) { + status = CR_BAD_PARAM_ERROR; + goto error; + } + + *((CRString **) a_extra_res) = token->dimen; + token->u.num = NULL; + token->dimen = NULL; + status = CR_OK; + break; + + case DELIM_TK: + *((guint32 *) a_res) = token->u.unichar; + status = CR_OK; + break; + + case UNICODERANGE_TK: + default: + status = CR_PARSING_ERROR; + break; + } + + cr_token_destroy (token); + token = NULL; + } else { + cr_tknzr_unget_token (a_this, token); + token = NULL; + status = CR_PARSING_ERROR; + } + + return status; + + error: + + if (token) { + cr_tknzr_unget_token (a_this, token); + token = NULL; + } + + return status; +} + +void +cr_tknzr_destroy (CRTknzr * a_this) +{ + g_return_if_fail (a_this); + + if (PRIVATE (a_this) && PRIVATE (a_this)->input) { + if (cr_input_unref (PRIVATE (a_this)->input) + == TRUE) { + PRIVATE (a_this)->input = NULL; + } + } + + if (PRIVATE (a_this)->token_cache) { + cr_token_destroy (PRIVATE (a_this)->token_cache); + PRIVATE (a_this)->token_cache = NULL; + } + + if (PRIVATE (a_this)) { + g_free (PRIVATE (a_this)); + PRIVATE (a_this) = NULL; + } + + g_free (a_this); +} diff --git a/src/libcroco/cr-tknzr.h b/src/libcroco/cr-tknzr.h new file mode 100644 index 000000000..13985b30e --- /dev/null +++ b/src/libcroco/cr-tknzr.h @@ -0,0 +1,115 @@ +/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * Author: Dodji Seketeli + * See COPYRIGHTS file for coypyright information. + */ + +/** + *@file + *The declaration of the #CRTknzr (tokenizer) + *class. + */ + +#ifndef __CR_TKNZR_H__ +#define __CR_TKNZR_H__ + +#include "cr-utils.h" +#include "cr-input.h" +#include "cr-token.h" + +G_BEGIN_DECLS + + +typedef struct _CRTknzr CRTknzr ; +typedef struct _CRTknzrPriv CRTknzrPriv ; + +/** + *The tokenizer is the class that knows + *about all the css token. Its main job is + *to return the next token found in the character + *input stream. + */ +struct _CRTknzr +{ + /*the private data of the tokenizer.*/ + CRTknzrPriv *priv ; +} ; + +CRTknzr * cr_tknzr_new (CRInput *a_input) ; + +CRTknzr * cr_tknzr_new_from_uri (const guchar *a_file_uri, + enum CREncoding a_enc) ; + +CRTknzr * cr_tknzr_new_from_buf (guchar *a_buf, gulong a_len, + enum CREncoding a_enc, + gboolean a_free_at_destroy) ; + +gboolean cr_tknzr_unref (CRTknzr *a_this) ; + +void cr_tknzr_ref (CRTknzr *a_this) ; + +enum CRStatus cr_tknzr_read_byte (CRTknzr *a_this, guchar *a_byte) ; + +enum CRStatus cr_tknzr_read_char (CRTknzr *a_this, guint32 *a_char); + +enum CRStatus cr_tknzr_peek_char (CRTknzr *a_this, guint32 *a_char) ; + +enum CRStatus cr_tknzr_peek_byte (CRTknzr *a_this, gulong a_offset, + guchar *a_byte) ; + +guchar cr_tknzr_peek_byte2 (CRTknzr *a_this, gulong a_offset, + gboolean *a_eof) ; + +enum CRStatus cr_tknzr_set_cur_pos (CRTknzr *a_this, CRInputPos *a_pos) ; + +glong cr_tknzr_get_nb_bytes_left (CRTknzr *a_this) ; + +enum CRStatus cr_tknzr_get_cur_pos (CRTknzr *a_this, CRInputPos *a_pos) ; + +enum CRStatus cr_tknzr_get_parsing_location (CRTknzr *a_this, + CRParsingLocation *a_loc) ; + +enum CRStatus cr_tknzr_seek_index (CRTknzr *a_this, + enum CRSeekPos a_origin, + gint a_pos) ; + +enum CRStatus cr_tknzr_get_cur_byte_addr (CRTknzr *a_this, guchar **a_addr) ; + + +enum CRStatus cr_tknzr_consume_chars (CRTknzr *a_this, guint32 a_char, + glong *a_nb_char) ; + +enum CRStatus cr_tknzr_get_next_token (CRTknzr *a_this, CRToken ** a_tk) ; + +enum CRStatus cr_tknzr_unget_token (CRTknzr *a_this, CRToken *a_token) ; + + +enum CRStatus cr_tknzr_parse_token (CRTknzr *a_this, enum CRTokenType a_type, + enum CRTokenExtraType a_et, gpointer a_res, + gpointer a_extra_res) ; +enum CRStatus cr_tknzr_set_input (CRTknzr *a_this, CRInput *a_input) ; + +enum CRStatus cr_tknzr_get_input (CRTknzr *a_this, CRInput **a_input) ; + +void cr_tknzr_destroy (CRTknzr *a_this) ; + +G_END_DECLS + +#endif /*__CR_TKZNR_H__*/ diff --git a/src/libcroco/cr-token.c b/src/libcroco/cr-token.c new file mode 100644 index 000000000..d2bb492ef --- /dev/null +++ b/src/libcroco/cr-token.c @@ -0,0 +1,635 @@ +/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * Author: Dodji Seketeli + * see COPYRIGHTS file for copyright information. + */ + +/** + *@file + *The definition of the #CRToken class. + *Abstracts a css2 token. + */ +#include +#include "cr-token.h" + +/* + *TODO: write a CRToken::to_string() method. + */ + +/** + *Frees the attributes of the current instance + *of #CRtoken. + *@param a_this the current instance of #CRToken. + */ +static void +cr_token_clear (CRToken * a_this) +{ + g_return_if_fail (a_this); + + switch (a_this->type) { + case S_TK: + case CDO_TK: + case INCLUDES_TK: + case DASHMATCH_TK: + case PAGE_SYM_TK: + case MEDIA_SYM_TK: + case FONT_FACE_SYM_TK: + case CHARSET_SYM_TK: + case IMPORT_SYM_TK: + case IMPORTANT_SYM_TK: + case SEMICOLON_TK: + case NO_TK: + case DELIM_TK: + case CBO_TK: + case CBC_TK: + case BO_TK: + case BC_TK: + break; + + case STRING_TK: + case IDENT_TK: + case HASH_TK: + case URI_TK: + case FUNCTION_TK: + case COMMENT_TK: + case ATKEYWORD_TK: + if (a_this->u.str) { + cr_string_destroy (a_this->u.str); + a_this->u.str = NULL; + } + break; + + case EMS_TK: + case EXS_TK: + case LENGTH_TK: + case ANGLE_TK: + case TIME_TK: + case FREQ_TK: + case PERCENTAGE_TK: + case NUMBER_TK: + case PO_TK: + case PC_TK: + if (a_this->u.num) { + cr_num_destroy (a_this->u.num); + a_this->u.num = NULL; + } + break; + + case DIMEN_TK: + if (a_this->u.num) { + cr_num_destroy (a_this->u.num); + a_this->u.num = NULL; + } + + if (a_this->dimen) { + cr_string_destroy (a_this->dimen); + a_this->dimen = NULL; + } + + break; + + case RGB_TK: + if (a_this->u.rgb) { + cr_rgb_destroy (a_this->u.rgb) ; + a_this->u.rgb = NULL ; + } + break ; + + case UNICODERANGE_TK: + /*not supported yet. */ + break; + + default: + cr_utils_trace_info ("I don't know how to clear this token\n") ; + break; + } + + a_this->type = NO_TK; +} + +/** + *Default constructor of + *the #CRToken class. + *@return the newly built instance of #CRToken. + */ +CRToken * +cr_token_new (void) +{ + CRToken *result = NULL; + + result = g_try_malloc (sizeof (CRToken)); + + if (result == NULL) { + cr_utils_trace_info ("Out of memory"); + return NULL; + } + + memset (result, 0, sizeof (CRToken)); + + return result; +} + +/** + *Sets the type of curren instance of + *#CRToken to 'S_TK' (S in the css2 spec) + *@param a_this the current instance of #CRToken. + *@return CR_OK upon successfull completion, an error + *code otherwise. + */ +enum CRStatus +cr_token_set_s (CRToken * a_this) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + cr_token_clear (a_this); + + a_this->type = S_TK; + + return CR_OK; +} + +/** + *Sets the type of the current instance of + *#CRToken to 'CDO_TK' (CDO as said by the css2 spec) + *@param a_this the current instance of #CRToken. + *@return CR_OK upon successfull completion, an error + *code otherwise. + */ +enum CRStatus +cr_token_set_cdo (CRToken * a_this) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + cr_token_clear (a_this); + + a_this->type = CDO_TK; + + return CR_OK; +} + +/** + *Sets the type of the current token to + *CDC_TK (CDC as said by the css2 spec). + *@param a_this the current instance of #CRToken. + *@return CR_OK upon successfull completion, an error + *code otherwise. + */ +enum CRStatus +cr_token_set_cdc (CRToken * a_this) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + cr_token_clear (a_this); + + a_this->type = CDC_TK; + + return CR_OK; +} + +/** + *Sets the type of the current instance of + *#CRToken to INCLUDES_TK (INCLUDES as said by the css2 spec). + *@param a_this the current instance of #CRToken. + *@return CR_OK upon successfull completion, an error + *code otherwise. + */ +enum CRStatus +cr_token_set_includes (CRToken * a_this) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + cr_token_clear (a_this); + + a_this->type = INCLUDES_TK; + + return CR_OK; +} + +/** + *Sets the type of the current instance of + *#CRToken to DASHMATCH_TK (DASHMATCH as said by the css2 spec). + *@param a_this the current instance of #CRToken. + *@return CR_OK upon successfull completion, an error + *code otherwise. + */ +enum CRStatus +cr_token_set_dashmatch (CRToken * a_this) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + cr_token_clear (a_this); + + a_this->type = DASHMATCH_TK; + + return CR_OK; +} + +enum CRStatus +cr_token_set_comment (CRToken * a_this, CRString * a_str) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + cr_token_clear (a_this); + a_this->type = COMMENT_TK; + a_this->u.str = a_str ; + return CR_OK; +} + +enum CRStatus +cr_token_set_string (CRToken * a_this, CRString * a_str) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + cr_token_clear (a_this); + + a_this->type = STRING_TK; + + a_this->u.str = a_str ; + + return CR_OK; +} + +enum CRStatus +cr_token_set_ident (CRToken * a_this, CRString * a_ident) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + cr_token_clear (a_this); + a_this->type = IDENT_TK; + a_this->u.str = a_ident; + return CR_OK; +} + + +enum CRStatus +cr_token_set_function (CRToken * a_this, CRString * a_fun_name) +{ + g_return_val_if_fail (a_this, + CR_BAD_PARAM_ERROR); + + cr_token_clear (a_this); + a_this->type = FUNCTION_TK; + a_this->u.str = a_fun_name; + return CR_OK; +} + +enum CRStatus +cr_token_set_hash (CRToken * a_this, CRString * a_hash) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + cr_token_clear (a_this); + a_this->type = HASH_TK; + a_this->u.str = a_hash; + + return CR_OK; +} + +enum CRStatus +cr_token_set_rgb (CRToken * a_this, CRRgb * a_rgb) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + cr_token_clear (a_this); + a_this->type = RGB_TK; + a_this->u.rgb = a_rgb; + + return CR_OK; +} + +enum CRStatus +cr_token_set_import_sym (CRToken * a_this) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + cr_token_clear (a_this); + + a_this->type = IMPORT_SYM_TK; + + return CR_OK; +} + +enum CRStatus +cr_token_set_page_sym (CRToken * a_this) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + cr_token_clear (a_this); + + a_this->type = PAGE_SYM_TK; + + return CR_OK; +} + +enum CRStatus +cr_token_set_media_sym (CRToken * a_this) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + cr_token_clear (a_this); + + a_this->type = MEDIA_SYM_TK; + + return CR_OK; +} + +enum CRStatus +cr_token_set_font_face_sym (CRToken * a_this) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + cr_token_clear (a_this); + a_this->type = FONT_FACE_SYM_TK; + + return CR_OK; +} + +enum CRStatus +cr_token_set_charset_sym (CRToken * a_this) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + cr_token_clear (a_this); + a_this->type = CHARSET_SYM_TK; + + return CR_OK; +} + +enum CRStatus +cr_token_set_atkeyword (CRToken * a_this, CRString * a_atname) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + cr_token_clear (a_this); + a_this->type = ATKEYWORD_TK; + a_this->u.str = a_atname; + return CR_OK; +} + +enum CRStatus +cr_token_set_important_sym (CRToken * a_this) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + cr_token_clear (a_this); + a_this->type = IMPORTANT_SYM_TK; + return CR_OK; +} + +enum CRStatus +cr_token_set_ems (CRToken * a_this, CRNum * a_num) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + cr_token_clear (a_this); + a_this->type = EMS_TK; + a_this->u.num = a_num; + return CR_OK; +} + +enum CRStatus +cr_token_set_exs (CRToken * a_this, CRNum * a_num) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + cr_token_clear (a_this); + a_this->type = EXS_TK; + a_this->u.num = a_num; + return CR_OK; +} + +enum CRStatus +cr_token_set_length (CRToken * a_this, CRNum * a_num, + enum CRTokenExtraType a_et) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + cr_token_clear (a_this); + + a_this->type = LENGTH_TK; + a_this->extra_type = a_et; + a_this->u.num = a_num; + + return CR_OK; +} + +enum CRStatus +cr_token_set_angle (CRToken * a_this, CRNum * a_num, + enum CRTokenExtraType a_et) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + cr_token_clear (a_this); + + a_this->type = ANGLE_TK; + a_this->extra_type = a_et; + a_this->u.num = a_num; + + return CR_OK; +} + +enum CRStatus +cr_token_set_time (CRToken * a_this, CRNum * a_num, + enum CRTokenExtraType a_et) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + cr_token_clear (a_this); + + a_this->type = TIME_TK; + a_this->extra_type = a_et; + a_this->u.num = a_num; + + return CR_OK; +} + +enum CRStatus +cr_token_set_freq (CRToken * a_this, CRNum * a_num, + enum CRTokenExtraType a_et) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + cr_token_clear (a_this); + + a_this->type = FREQ_TK; + a_this->extra_type = a_et; + a_this->u.num = a_num; + + return CR_OK; +} + +enum CRStatus +cr_token_set_dimen (CRToken * a_this, CRNum * a_num, + CRString * a_dim) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + cr_token_clear (a_this); + a_this->type = DIMEN_TK; + a_this->u.num = a_num; + a_this->dimen = a_dim; + return CR_OK; + +} + +enum CRStatus +cr_token_set_percentage (CRToken * a_this, CRNum * a_num) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + cr_token_clear (a_this); + + a_this->type = PERCENTAGE_TK; + a_this->u.num = a_num; + + return CR_OK; +} + +enum CRStatus +cr_token_set_number (CRToken * a_this, CRNum * a_num) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + cr_token_clear (a_this); + + a_this->type = NUMBER_TK; + a_this->u.num = a_num; + return CR_OK; +} + +enum CRStatus +cr_token_set_uri (CRToken * a_this, CRString * a_uri) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + cr_token_clear (a_this); + + a_this->type = URI_TK; + a_this->u.str = a_uri; + + return CR_OK; +} + +enum CRStatus +cr_token_set_delim (CRToken * a_this, guint32 a_char) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + cr_token_clear (a_this); + + a_this->type = DELIM_TK; + a_this->u.unichar = a_char; + + return CR_OK; +} + +enum CRStatus +cr_token_set_semicolon (CRToken * a_this) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + cr_token_clear (a_this); + + a_this->type = SEMICOLON_TK; + + return CR_OK; +} + +enum CRStatus +cr_token_set_cbo (CRToken * a_this) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + cr_token_clear (a_this); + + a_this->type = CBO_TK; + + return CR_OK; +} + +enum CRStatus +cr_token_set_cbc (CRToken * a_this) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + cr_token_clear (a_this); + + a_this->type = CBC_TK; + + return CR_OK; +} + +enum CRStatus +cr_token_set_po (CRToken * a_this) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + cr_token_clear (a_this); + + a_this->type = PO_TK; + + return CR_OK; +} + +enum CRStatus +cr_token_set_pc (CRToken * a_this) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + cr_token_clear (a_this); + + a_this->type = PC_TK; + + return CR_OK; +} + +enum CRStatus +cr_token_set_bo (CRToken * a_this) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + cr_token_clear (a_this); + + a_this->type = BO_TK; + + return CR_OK; +} + +enum CRStatus +cr_token_set_bc (CRToken * a_this) +{ + g_return_val_if_fail (a_this, CR_BAD_PARAM_ERROR); + + cr_token_clear (a_this); + + a_this->type = BC_TK; + + return CR_OK; +} + +/** + *The destructor of the #CRToken class. + *@param a_this the current instance of #CRToken. + */ +void +cr_token_destroy (CRToken * a_this) +{ + g_return_if_fail (a_this); + + cr_token_clear (a_this); + + g_free (a_this); +} diff --git a/src/libcroco/cr-token.h b/src/libcroco/cr-token.h new file mode 100644 index 000000000..f1257b7a8 --- /dev/null +++ b/src/libcroco/cr-token.h @@ -0,0 +1,212 @@ +/* -*- Mode: C; indent-tabs-mode:nil; c-basic-offset: 8-*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * Author: Dodji Seketeli + * See COPYRIGHTS file for copyright information. + */ + +#ifndef __CR_TOKEN_H__ +#define __CR_TOKEN_H__ + +#include "cr-utils.h" +#include "cr-input.h" +#include "cr-num.h" +#include "cr-rgb.h" +#include "cr-string.h" +#include "cr-parsing-location.h" + +G_BEGIN_DECLS + +enum CRTokenType +{ + NO_TK, + S_TK, + CDO_TK, + CDC_TK, + INCLUDES_TK, + DASHMATCH_TK, + COMMENT_TK, + STRING_TK, + IDENT_TK, + HASH_TK, + IMPORT_SYM_TK, + PAGE_SYM_TK, + MEDIA_SYM_TK, + FONT_FACE_SYM_TK, + CHARSET_SYM_TK, + ATKEYWORD_TK, + IMPORTANT_SYM_TK, + EMS_TK, + EXS_TK, + LENGTH_TK, + ANGLE_TK, + TIME_TK, + FREQ_TK, + DIMEN_TK, + PERCENTAGE_TK, + NUMBER_TK, + RGB_TK, + URI_TK, + FUNCTION_TK, + UNICODERANGE_TK, + SEMICOLON_TK, + CBO_TK, /*opening curly bracket*/ + CBC_TK, /*closing curly bracket*/ + PO_TK, /*opening parenthesis*/ + PC_TK, /*closing parenthesis*/ + BO_TK, /*opening bracket*/ + BC_TK, /*closing bracket*/ + DELIM_TK +} ; + +enum CRTokenExtraType +{ + NO_ET = 0, + LENGTH_PX_ET, + LENGTH_CM_ET, + LENGTH_MM_ET, + LENGTH_IN_ET, + LENGTH_PT_ET, + LENGTH_PC_ET, + ANGLE_DEG_ET, + ANGLE_RAD_ET, + ANGLE_GRAD_ET, + TIME_MS_ET, + TIME_S_ET, + FREQ_HZ_ET, + FREQ_KHZ_ET +} ; + +typedef struct _CRToken CRToken ; + +/** + *This class abstracts a css2 token. + */ +struct _CRToken +{ + enum CRTokenType type ; + enum CRTokenExtraType extra_type ; + CRInputPos pos ; + + union + { + CRString *str ; + CRRgb *rgb ; + CRNum *num ; + guint32 unichar ; + } u ; + + CRString * dimen ; + CRParsingLocation location ; +} ; + +CRToken* cr_token_new (void) ; + +enum CRStatus cr_token_set_s (CRToken *a_this) ; + +enum CRStatus cr_token_set_cdo (CRToken *a_this) ; + +enum CRStatus cr_token_set_cdc (CRToken *a_this) ; + +enum CRStatus cr_token_set_includes (CRToken *a_this) ; + +enum CRStatus cr_token_set_dashmatch (CRToken *a_this) ; + +enum CRStatus cr_token_set_comment (CRToken *a_this, CRString *a_str) ; + +enum CRStatus cr_token_set_string (CRToken *a_this, CRString *a_str) ; + +enum CRStatus cr_token_set_ident (CRToken *a_this, CRString * a_ident) ; + +enum CRStatus cr_token_set_hash (CRToken *a_this, CRString *a_hash) ; + +enum CRStatus cr_token_set_rgb (CRToken *a_this, CRRgb *a_rgb) ; + +enum CRStatus cr_token_set_import_sym (CRToken *a_this) ; + +enum CRStatus cr_token_set_page_sym (CRToken *a_this) ; + +enum CRStatus cr_token_set_media_sym (CRToken *a_this) ; + +enum CRStatus cr_token_set_font_face_sym (CRToken *a_this) ; + +enum CRStatus cr_token_set_charset_sym (CRToken *a_this) ; + +enum CRStatus cr_token_set_atkeyword (CRToken *a_this, CRString *a_atname) ; + +enum CRStatus cr_token_set_important_sym (CRToken *a_this) ; + +enum CRStatus cr_token_set_ems (CRToken *a_this, CRNum *a_num) ; + +enum CRStatus cr_token_set_exs (CRToken *a_this, CRNum *a_num) ; + +enum CRStatus cr_token_set_length (CRToken *a_this, CRNum *a_num, + enum CRTokenExtraType a_et) ; + +enum CRStatus cr_token_set_angle (CRToken *a_this, CRNum *a_num, + enum CRTokenExtraType a_et) ; + +enum CRStatus cr_token_set_time (CRToken *a_this, CRNum *a_num, + enum CRTokenExtraType a_et) ; + +enum CRStatus cr_token_set_freq (CRToken *a_this, CRNum *a_num, + enum CRTokenExtraType a_et) ; + +enum CRStatus cr_token_set_dimen (CRToken *a_this, CRNum *a_num, + CRString *a_dim) ; + +enum CRStatus cr_token_set_percentage (CRToken *a_this, CRNum *a_num) ; + +enum CRStatus cr_token_set_number (CRToken *a_this, CRNum *a_num) ; + +enum CRStatus cr_token_set_uri (CRToken *a_this, CRString *a_uri) ; + +enum CRStatus cr_token_set_function (CRToken *a_this, + CRString *a_fun_name) ; + +enum CRStatus cr_token_set_bc (CRToken *a_this) ; + +enum CRStatus cr_token_set_bo (CRToken *a_this) ; + +enum CRStatus cr_token_set_po (CRToken *a_this) ; + +enum CRStatus cr_token_set_pc (CRToken *a_this) ; + +enum CRStatus cr_token_set_cbc (CRToken *a_this) ; + +enum CRStatus cr_token_set_cbo (CRToken *a_this) ; + +enum CRStatus cr_token_set_semicolon (CRToken *a_this) ; + +enum CRStatus cr_token_set_delim (CRToken *a_this, guint32 a_char) ; + + +/* + enum CRStatus + cr_token_set_unicoderange (CRToken *a_this, + CRUnicodeRange *a_range) ; +*/ + +void +cr_token_destroy (CRToken *a_this) ; + + +G_END_DECLS + +#endif /*__CR_TOKEN_H__*/ diff --git a/src/libcroco/cr-utils.c b/src/libcroco/cr-utils.c new file mode 100644 index 000000000..487cf4b95 --- /dev/null +++ b/src/libcroco/cr-utils.c @@ -0,0 +1,1343 @@ +/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * Author: Dodji Seketeli + * See COPYRIGHTS file for copyright information. + */ + +#include "cr-utils.h" +#include "cr-string.h" + +/** + *@file: + *Some misc utility functions used + *in the libcroco. + *Note that troughout this file I will + *refer to the CSS SPECIFICATIONS DOCUMENTATION + *written by the w3c guys. You can find that document + *at http://www.w3.org/TR/REC-CSS2/ . + */ + +/**************************** + *Encoding transformations and + *encoding helpers + ****************************/ + +/* + *Here is the correspondance between the ucs-4 charactere codes + *and there matching utf-8 encoding pattern as dscribed by RFC 2279: + * + *UCS-4 range (hex.) UTF-8 octet sequence (binary) + *------------------ ----------------------------- + *0000 0000-0000 007F 0xxxxxxx + *0000 0080-0000 07FF 110xxxxx 10xxxxxx + *0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx + *0001 0000-001F FFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx + *0020 0000-03FF FFFF 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx + *0400 0000-7FFF FFFF 1111110x 10xxxxxx ... 10xxxxxx + */ + +/** + *Given an utf8 string buffer, calculates + *the length of this string if it was encoded + *in ucs4. + *@param a_in_start a pointer to the begining of + *the input utf8 string. + *@param a_in_end a pointre to the end of the input + *utf8 string (points to the last byte of the buffer) + *@param a_len out parameter the calculated length. + *@return CR_OK upon succesfull completion, an error code + *otherwise. + */ +enum CRStatus +cr_utils_utf8_str_len_as_ucs4 (const guchar * a_in_start, + const guchar * a_in_end, gulong * a_len) +{ + guchar *byte_ptr = NULL; + gint len = 0; + + /* + *to store the final decoded + *unicode char + */ + guint c = 0; + + g_return_val_if_fail (a_in_start && a_in_end && a_len, + CR_BAD_PARAM_ERROR); + *a_len = 0; + + for (byte_ptr = (guchar *) a_in_start; + byte_ptr <= a_in_end; byte_ptr++) { + gint nb_bytes_2_decode = 0; + + if (*byte_ptr <= 0x7F) { + /* + *7 bits long char + *encoded over 1 byte: + * 0xxx xxxx + */ + c = *byte_ptr; + nb_bytes_2_decode = 1; + + } else if ((*byte_ptr & 0xE0) == 0xC0) { + /* + *up to 11 bits long char. + *encoded over 2 bytes: + *110x xxxx 10xx xxxx + */ + c = *byte_ptr & 0x1F; + nb_bytes_2_decode = 2; + + } else if ((*byte_ptr & 0xF0) == 0xE0) { + /* + *up to 16 bit long char + *encoded over 3 bytes: + *1110 xxxx 10xx xxxx 10xx xxxx + */ + c = *byte_ptr & 0x0F; + nb_bytes_2_decode = 3; + + } else if ((*byte_ptr & 0xF8) == 0xF0) { + /* + *up to 21 bits long char + *encoded over 4 bytes: + *1111 0xxx 10xx xxxx 10xx xxxx 10xx xxxx + */ + c = *byte_ptr & 0x7; + nb_bytes_2_decode = 4; + + } else if ((*byte_ptr & 0xFC) == 0xF8) { + /* + *up to 26 bits long char + *encoded over 5 bytes. + *1111 10xx 10xx xxxx 10xx xxxx + *10xx xxxx 10xx xxxx + */ + c = *byte_ptr & 3; + nb_bytes_2_decode = 5; + + } else if ((*byte_ptr & 0xFE) == 0xFC) { + /* + *up to 31 bits long char + *encoded over 6 bytes: + *1111 110x 10xx xxxx 10xx xxxx + *10xx xxxx 10xx xxxx 10xx xxxx + */ + c = *byte_ptr & 1; + nb_bytes_2_decode = 6; + + } else { + /* + *BAD ENCODING + */ + return CR_ENCODING_ERROR; + } + + /* + *Go and decode the remaining byte(s) + *(if any) to get the current character. + */ + for (; nb_bytes_2_decode > 1; nb_bytes_2_decode--) { + /*decode the next byte */ + byte_ptr++; + + /*byte pattern must be: 10xx xxxx */ + if ((*byte_ptr & 0xC0) != 0x80) { + return CR_ENCODING_ERROR; + } + + c = (c << 6) | (*byte_ptr & 0x3F); + } + + len++; + } + + *a_len = len; + + return CR_OK; +} + +/** + *Given an ucs4 string, this function + *returns the size (in bytes) this string + *would have occupied if it was encoded in utf-8. + *@param a_in_start a pointer to the beginning of the input + *buffer. + *@param a_in_end a pointer to the end of the input buffer. + *@param a_len out parameter. The computed length. + *@return CR_OK upon successfull completion, an error code otherwise. + */ +enum CRStatus +cr_utils_ucs4_str_len_as_utf8 (const guint32 * a_in_start, + const guint32 * a_in_end, gulong * a_len) +{ + gint len = 0; + guint32 *char_ptr = NULL; + + g_return_val_if_fail (a_in_start && a_in_end && a_len, + CR_BAD_PARAM_ERROR); + + for (char_ptr = (guint32 *) a_in_start; + char_ptr <= a_in_end; char_ptr++) { + if (*char_ptr <= 0x7F) { + /*the utf-8 char would take 1 byte */ + len += 1; + } else if (*char_ptr <= 0x7FF) { + /*the utf-8 char would take 2 bytes */ + len += 2; + } else if (*char_ptr <= 0xFFFF) { + len += 3; + } else if (*char_ptr <= 0x1FFFFF) { + len += 4; + } else if (*char_ptr <= 0x3FFFFFF) { + len += 5; + } else if (*char_ptr <= 0x7FFFFFFF) { + len += 6; + } + } + + *a_len = len; + return CR_OK; +} + +/** + *Given an ucsA string, this function + *returns the size (in bytes) this string + *would have occupied if it was encoded in utf-8. + *@param a_in_start a pointer to the beginning of the input + *buffer. + *@param a_in_end a pointer to the end of the input buffer. + *@param a_len out parameter. The computed length. + *@return CR_OK upon successfull completion, an error code otherwise. + */ +enum CRStatus +cr_utils_ucs1_str_len_as_utf8 (const guchar * a_in_start, + const guchar * a_in_end, gulong * a_len) +{ + gint len = 0; + guchar *char_ptr = NULL; + + g_return_val_if_fail (a_in_start && a_in_end && a_len, + CR_BAD_PARAM_ERROR); + + for (char_ptr = (guchar *) a_in_start; + char_ptr <= a_in_end; char_ptr++) { + if (*char_ptr <= 0x7F) { + /*the utf-8 char would take 1 byte */ + len += 1; + } else { + /*the utf-8 char would take 2 bytes */ + len += 2; + } + } + + *a_len = len; + return CR_OK; +} + +/** + *Converts an utf8 buffer into an ucs4 buffer. + * + *@param a_in the input utf8 buffer to convert. + *@param a_in_len in/out parameter. The size of the + *input buffer to convert. After return, this parameter contains + *the actual number of bytes consumed. + *@param a_out the output converted ucs4 buffer. Must be allocated by + *the caller. + *@param a_out_len in/out parameter. The size of the output buffer. + *If this size is actually smaller than the real needed size, the function + *just converts what it can and returns a success status. After return, + *this param points to the actual number of characters decoded. + *@return CR_OK upon successfull completion, an error code otherwise. + */ +enum CRStatus +cr_utils_utf8_to_ucs4 (const guchar * a_in, + gulong * a_in_len, guint32 * a_out, gulong * a_out_len) +{ + gulong in_len = 0, + out_len = 0, + in_index = 0, + out_index = 0; + enum CRStatus status = CR_OK; + + /* + *to store the final decoded + *unicode char + */ + guint c = 0; + + g_return_val_if_fail (a_in && a_in_len + && a_out && a_out_len, CR_BAD_PARAM_ERROR); + + if (*a_in_len < 1) { + status = CR_OK; + goto end; + } + + in_len = *a_in_len; + out_len = *a_out_len; + + for (in_index = 0, out_index = 0; + (in_index < in_len) && (out_index < out_len); + in_index++, out_index++) { + gint nb_bytes_2_decode = 0; + + if (a_in[in_index] <= 0x7F) { + /* + *7 bits long char + *encoded over 1 byte: + * 0xxx xxxx + */ + c = a_in[in_index]; + nb_bytes_2_decode = 1; + + } else if ((a_in[in_index] & 0xE0) == 0xC0) { + /* + *up to 11 bits long char. + *encoded over 2 bytes: + *110x xxxx 10xx xxxx + */ + c = a_in[in_index] & 0x1F; + nb_bytes_2_decode = 2; + + } else if ((a_in[in_index] & 0xF0) == 0xE0) { + /* + *up to 16 bit long char + *encoded over 3 bytes: + *1110 xxxx 10xx xxxx 10xx xxxx + */ + c = a_in[in_index] & 0x0F; + nb_bytes_2_decode = 3; + + } else if ((a_in[in_index] & 0xF8) == 0xF0) { + /* + *up to 21 bits long char + *encoded over 4 bytes: + *1111 0xxx 10xx xxxx 10xx xxxx 10xx xxxx + */ + c = a_in[in_index] & 0x7; + nb_bytes_2_decode = 4; + + } else if ((a_in[in_index] & 0xFC) == 0xF8) { + /* + *up to 26 bits long char + *encoded over 5 bytes. + *1111 10xx 10xx xxxx 10xx xxxx + *10xx xxxx 10xx xxxx + */ + c = a_in[in_index] & 3; + nb_bytes_2_decode = 5; + + } else if ((a_in[in_index] & 0xFE) == 0xFC) { + /* + *up to 31 bits long char + *encoded over 6 bytes: + *1111 110x 10xx xxxx 10xx xxxx + *10xx xxxx 10xx xxxx 10xx xxxx + */ + c = a_in[in_index] & 1; + nb_bytes_2_decode = 6; + + } else { + /*BAD ENCODING */ + goto end; + } + + /* + *Go and decode the remaining byte(s) + *(if any) to get the current character. + */ + for (; nb_bytes_2_decode > 1; nb_bytes_2_decode--) { + /*decode the next byte */ + in_index++; + + /*byte pattern must be: 10xx xxxx */ + if ((a_in[in_index] & 0xC0) != 0x80) { + goto end; + } + + c = (c << 6) | (a_in[in_index] & 0x3F); + } + + /* + *The decoded ucs4 char is now + *in c. + */ + + /************************ + *Some security tests + ***********************/ + + /*be sure c is a char */ + if (c == 0xFFFF || c == 0xFFFE) + goto end; + + /*be sure c is inferior to the max ucs4 char value */ + if (c > 0x10FFFF) + goto end; + + /* + *c must be less than UTF16 "lower surrogate begin" + *or higher than UTF16 "High surrogate end" + */ + if (c >= 0xD800 && c <= 0xDFFF) + goto end; + + /*Avoid characters that equals zero */ + if (c == 0) + goto end; + + a_out[out_index] = c; + } + + end: + *a_out_len = out_index + 1; + *a_in_len = in_index + 1; + + return status; +} + +/** + *Reads a character from an utf8 buffer. + *Actually decode the next character code (unicode character code) + *and returns it. + *@param a_in the starting address of the utf8 buffer. + *@param a_in_len the length of the utf8 buffer. + *@param a_out output parameter. The resulting read char. + *@param a_consumed the number of the bytes consumed to + *decode the returned character code. + *@return CR_OK upon successfull completion, an error code otherwise. + */ +enum CRStatus +cr_utils_read_char_from_utf8_buf (const guchar * a_in, + gulong a_in_len, + guint32 * a_out, gulong * a_consumed) +{ + gulong in_len = 0, + in_index = 0, + nb_bytes_2_decode = 0; + enum CRStatus status = CR_OK; + + /* + *to store the final decoded + *unicode char + */ + guint32 c = 0; + + g_return_val_if_fail (a_in && a_out && a_out + && a_consumed, CR_BAD_PARAM_ERROR); + + if (a_in_len < 1) { + status = CR_OK; + goto end; + } + + in_len = a_in_len; + + if (*a_in <= 0x7F) { + /* + *7 bits long char + *encoded over 1 byte: + * 0xxx xxxx + */ + c = *a_in; + nb_bytes_2_decode = 1; + + } else if ((*a_in & 0xE0) == 0xC0) { + /* + *up to 11 bits long char. + *encoded over 2 bytes: + *110x xxxx 10xx xxxx + */ + c = *a_in & 0x1F; + nb_bytes_2_decode = 2; + + } else if ((*a_in & 0xF0) == 0xE0) { + /* + *up to 16 bit long char + *encoded over 3 bytes: + *1110 xxxx 10xx xxxx 10xx xxxx + */ + c = *a_in & 0x0F; + nb_bytes_2_decode = 3; + + } else if ((*a_in & 0xF8) == 0xF0) { + /* + *up to 21 bits long char + *encoded over 4 bytes: + *1111 0xxx 10xx xxxx 10xx xxxx 10xx xxxx + */ + c = *a_in & 0x7; + nb_bytes_2_decode = 4; + + } else if ((*a_in & 0xFC) == 0xF8) { + /* + *up to 26 bits long char + *encoded over 5 bytes. + *1111 10xx 10xx xxxx 10xx xxxx + *10xx xxxx 10xx xxxx + */ + c = *a_in & 3; + nb_bytes_2_decode = 5; + + } else if ((*a_in & 0xFE) == 0xFC) { + /* + *up to 31 bits long char + *encoded over 6 bytes: + *1111 110x 10xx xxxx 10xx xxxx + *10xx xxxx 10xx xxxx 10xx xxxx + */ + c = *a_in & 1; + nb_bytes_2_decode = 6; + + } else { + /*BAD ENCODING */ + goto end; + } + + if (nb_bytes_2_decode > a_in_len) { + status = CR_END_OF_INPUT_ERROR; + goto end; + } + + /* + *Go and decode the remaining byte(s) + *(if any) to get the current character. + */ + for (in_index = 1; in_index < nb_bytes_2_decode; in_index++) { + /*byte pattern must be: 10xx xxxx */ + if ((a_in[in_index] & 0xC0) != 0x80) { + goto end; + } + + c = (c << 6) | (a_in[in_index] & 0x3F); + } + + /* + *The decoded ucs4 char is now + *in c. + */ + + /************************ + *Some security tests + ***********************/ + + /*be sure c is a char */ + if (c == 0xFFFF || c == 0xFFFE) + goto end; + + /*be sure c is inferior to the max ucs4 char value */ + if (c > 0x10FFFF) + goto end; + + /* + *c must be less than UTF16 "lower surrogate begin" + *or higher than UTF16 "High surrogate end" + */ + if (c >= 0xD800 && c <= 0xDFFF) + goto end; + + /*Avoid characters that equals zero */ + if (c == 0) + goto end; + + *a_out = c; + + end: + *a_consumed = nb_bytes_2_decode; + + return status; +} + +/** + * + */ +enum CRStatus +cr_utils_utf8_str_len_as_ucs1 (const guchar * a_in_start, + const guchar * a_in_end, gulong * a_len) +{ + /* + *Note: this function can be made shorter + *but it considers all the cases of the utf8 encoding + *to ease further extensions ... + */ + + guchar *byte_ptr = NULL; + gint len = 0; + + /* + *to store the final decoded + *unicode char + */ + guint c = 0; + + g_return_val_if_fail (a_in_start && a_in_end && a_len, + CR_BAD_PARAM_ERROR); + *a_len = 0; + + for (byte_ptr = (guchar *) a_in_start; + byte_ptr <= a_in_end; byte_ptr++) { + gint nb_bytes_2_decode = 0; + + if (*byte_ptr <= 0x7F) { + /* + *7 bits long char + *encoded over 1 byte: + * 0xxx xxxx + */ + c = *byte_ptr; + nb_bytes_2_decode = 1; + + } else if ((*byte_ptr & 0xE0) == 0xC0) { + /* + *up to 11 bits long char. + *encoded over 2 bytes: + *110x xxxx 10xx xxxx + */ + c = *byte_ptr & 0x1F; + nb_bytes_2_decode = 2; + + } else if ((*byte_ptr & 0xF0) == 0xE0) { + /* + *up to 16 bit long char + *encoded over 3 bytes: + *1110 xxxx 10xx xxxx 10xx xxxx + */ + c = *byte_ptr & 0x0F; + nb_bytes_2_decode = 3; + + } else if ((*byte_ptr & 0xF8) == 0xF0) { + /* + *up to 21 bits long char + *encoded over 4 bytes: + *1111 0xxx 10xx xxxx 10xx xxxx 10xx xxxx + */ + c = *byte_ptr & 0x7; + nb_bytes_2_decode = 4; + + } else if ((*byte_ptr & 0xFC) == 0xF8) { + /* + *up to 26 bits long char + *encoded over 5 bytes. + *1111 10xx 10xx xxxx 10xx xxxx + *10xx xxxx 10xx xxxx + */ + c = *byte_ptr & 3; + nb_bytes_2_decode = 5; + + } else if ((*byte_ptr & 0xFE) == 0xFC) { + /* + *up to 31 bits long char + *encoded over 6 bytes: + *1111 110x 10xx xxxx 10xx xxxx + *10xx xxxx 10xx xxxx 10xx xxxx + */ + c = *byte_ptr & 1; + nb_bytes_2_decode = 6; + + } else { + /* + *BAD ENCODING + */ + return CR_ENCODING_ERROR; + } + + /* + *Go and decode the remaining byte(s) + *(if any) to get the current character. + */ + for (; nb_bytes_2_decode > 1; nb_bytes_2_decode--) { + /*decode the next byte */ + byte_ptr++; + + /*byte pattern must be: 10xx xxxx */ + if ((*byte_ptr & 0xC0) != 0x80) { + return CR_ENCODING_ERROR; + } + + c = (c << 6) | (*byte_ptr & 0x3F); + } + + /* + *The decoded ucs4 char is now + *in c. + */ + + if (c <= 0xFF) { /*Add other conditions to support + *other char sets (ucs2, ucs3, ucs4). + */ + len++; + } else { + /*the char is too long to fit + *into the supposed charset len. + */ + return CR_ENCODING_ERROR; + } + } + + *a_len = len; + + return CR_OK; +} + +/** + *Converts an utf8 string into an ucs4 string. + *@param a_in the input string to convert. + *@param a_in_len in/out parameter. The length of the input + *string. After return, points to the actual number of bytes + *consumed. This can be usefull to debug the input stream in case + *of encoding error. + *@param a_out out parameter. Points to the output string. It is allocated + *by this function and must be freed by the caller. + *@param a_out_len out parameter. The length of the output string. + *@return CR_OK upon successfull completion, an error code otherwise. + * + */ +enum CRStatus +cr_utils_utf8_str_to_ucs4 (const guchar * a_in, + gulong * a_in_len, + guint32 ** a_out, gulong * a_out_len) +{ + enum CRStatus status = CR_OK; + + g_return_val_if_fail (a_in && a_in_len + && a_out && a_out_len, CR_BAD_PARAM_ERROR); + + status = cr_utils_utf8_str_len_as_ucs4 (a_in, + &a_in[*a_in_len - 1], + a_out_len); + + g_return_val_if_fail (status == CR_OK, status); + + *a_out = (guint32 *) g_malloc0 (*a_out_len * sizeof (guint32)); + + status = cr_utils_utf8_to_ucs4 (a_in, a_in_len, *a_out, a_out_len); + + return status; +} + +/** + *Converts an ucs4 buffer into an utf8 buffer. + * + *@param a_in the input ucs4 buffer to convert. + *@param a_in_len in/out parameter. The size of the + *input buffer to convert. After return, this parameter contains + *the actual number of characters consumed. + *@param a_out the output converted utf8 buffer. Must be allocated by + *the caller. + *@param a_out_len in/out parameter. The size of the output buffer. + *If this size is actually smaller than the real needed size, the function + *just converts what it can and returns a success status. After return, + *this param points to the actual number of bytes in the buffer. + *@return CR_OK upon successfull completion, an error code otherwise. + */ +enum CRStatus +cr_utils_ucs4_to_utf8 (const guint32 * a_in, + gulong * a_in_len, guchar * a_out, gulong * a_out_len) +{ + gulong in_len = 0, + in_index = 0, + out_index = 0; + enum CRStatus status = CR_OK; + + g_return_val_if_fail (a_in && a_in_len && a_out && a_out_len, + CR_BAD_PARAM_ERROR); + + if (*a_in_len < 1) { + status = CR_OK; + goto end; + } + + in_len = *a_in_len; + + for (in_index = 0; in_index < in_len; in_index++) { + /* + *FIXME: return whenever we encounter forbidden char values. + */ + + if (a_in[in_index] <= 0x7F) { + a_out[out_index] = a_in[in_index]; + out_index++; + } else if (a_in[in_index] <= 0x7FF) { + a_out[out_index] = (0xC0 | (a_in[in_index] >> 6)); + a_out[out_index + 1] = + (0x80 | (a_in[in_index] & 0x3F)); + out_index += 2; + } else if (a_in[in_index] <= 0xFFFF) { + a_out[out_index] = (0xE0 | (a_in[in_index] >> 12)); + a_out[out_index + 1] = + (0x80 | ((a_in[in_index] >> 6) & 0x3F)); + a_out[out_index + 2] = + (0x80 | (a_in[in_index] & 0x3F)); + out_index += 3; + } else if (a_in[in_index] <= 0x1FFFFF) { + a_out[out_index] = (0xF0 | (a_in[in_index] >> 18)); + a_out[out_index + 1] + = (0x80 | ((a_in[in_index] >> 12) & 0x3F)); + a_out[out_index + 2] + = (0x80 | ((a_in[in_index] >> 6) & 0x3F)); + a_out[out_index + 3] + = (0x80 | (a_in[in_index] & 0x3F)); + out_index += 4; + } else if (a_in[in_index] <= 0x3FFFFFF) { + a_out[out_index] = (0xF8 | (a_in[in_index] >> 24)); + a_out[out_index + 1] = + (0x80 | (a_in[in_index] >> 18)); + a_out[out_index + 2] + = (0x80 | ((a_in[in_index] >> 12) & 0x3F)); + a_out[out_index + 3] + = (0x80 | ((a_in[in_index] >> 6) & 0x3F)); + a_out[out_index + 4] + = (0x80 | (a_in[in_index] & 0x3F)); + out_index += 5; + } else if (a_in[in_index] <= 0x7FFFFFFF) { + a_out[out_index] = (0xFC | (a_in[in_index] >> 30)); + a_out[out_index + 1] = + (0x80 | (a_in[in_index] >> 24)); + a_out[out_index + 2] + = (0x80 | ((a_in[in_index] >> 18) & 0x3F)); + a_out[out_index + 3] + = (0x80 | ((a_in[in_index] >> 12) & 0x3F)); + a_out[out_index + 4] + = (0x80 | ((a_in[in_index] >> 6) & 0x3F)); + a_out[out_index + 4] + = (0x80 | (a_in[in_index] & 0x3F)); + out_index += 6; + } else { + status = CR_ENCODING_ERROR; + goto end; + } + } /*end for */ + + end: + *a_in_len = in_index + 1; + *a_out_len = out_index + 1; + + return status; +} + +/** + *Converts an ucs4 string into an utf8 string. + *@param a_in the input string to convert. + *@param a_in_len in/out parameter. The length of the input + *string. After return, points to the actual number of characters + *consumed. This can be usefull to debug the input string in case + *of encoding error. + *@param a_out out parameter. Points to the output string. It is allocated + *by this function and must be freed by the caller. + *@param a_out_len out parameter. The length (in bytes) of the output string. + *@return CR_OK upon successfull completion, an error code otherwise. + */ +enum CRStatus +cr_utils_ucs4_str_to_utf8 (const guint32 * a_in, + gulong * a_in_len, + guchar ** a_out, gulong * a_out_len) +{ + enum CRStatus status = CR_OK; + + g_return_val_if_fail (a_in && a_in_len && a_out + && a_out_len, CR_BAD_PARAM_ERROR); + + status = cr_utils_ucs4_str_len_as_utf8 (a_in, + &a_in[*a_out_len - 1], + a_out_len); + + g_return_val_if_fail (status == CR_OK, status); + + status = cr_utils_ucs4_to_utf8 (a_in, a_in_len, *a_out, a_out_len); + + return status; +} + +/** + *Converts an ucs1 buffer into an utf8 buffer. + *The caller must know the size of the resulting buffer and + *allocate it prior to calling this function. + * + *@param a_in the input ucs1 buffer. + * + *@param a_in_len in/out parameter. The length of the input buffer. + *After return, points to the number of bytes actually consumed even + *in case of encoding error. + * + *@param a_out out parameter. The output utf8 converted buffer. + * + *@param a_out_len in/out parameter. The size of the output buffer. + *If the output buffer size is shorter than the actual needed size, + *this function just convert what it can. + * + *@return CR_OK upon successfull completion, an error code otherwise. + * + */ +enum CRStatus +cr_utils_ucs1_to_utf8 (const guchar * a_in, + gulong * a_in_len, guchar * a_out, gulong * a_out_len) +{ + gulong out_index = 0, + in_index = 0, + in_len = 0, + out_len = 0; + enum CRStatus status = CR_OK; + + g_return_val_if_fail (a_in && a_in_len + && a_out_len, + CR_BAD_PARAM_ERROR); + + if (*a_in_len == 0) { + *a_out_len = 0 ; + return CR_OK ; + } + g_return_val_if_fail (a_out, CR_BAD_PARAM_ERROR) ; + + if (*a_in_len < 1) { + status = CR_OK; + goto end; + } + + in_len = *a_in_len; + out_len = *a_out_len; + + for (in_index = 0, out_index = 0; + (in_index < in_len) && (out_index < out_len); in_index++) { + /* + *FIXME: return whenever we encounter forbidden char values. + */ + + if (a_in[in_index] <= 0x7F) { + a_out[out_index] = a_in[in_index]; + out_index++; + } else { + a_out[out_index] = (0xC0 | (a_in[in_index] >> 6)); + a_out[out_index + 1] = + (0x80 | (a_in[in_index] & 0x3F)); + out_index += 2; + } + } /*end for */ + + end: + *a_in_len = in_index; + *a_out_len = out_index; + + return CR_OK; +} + +/** + *Converts an ucs1 string into an utf8 string. + *@param a_in_start the beginning of the input string to convert. + *@param a_in_end the end of the input string to convert. + *@param a_out out parameter. The converted string. + *@param a_out out parameter. The length of the converted string. + *@return CR_OK upon successfull completion, an error code otherwise. + * + */ +enum CRStatus +cr_utils_ucs1_str_to_utf8 (const guchar * a_in, + gulong * a_in_len, + guchar ** a_out, gulong * a_out_len) +{ + gulong in_len = 0, + out_len = 0; + enum CRStatus status = CR_OK; + + g_return_val_if_fail (a_in && a_in_len && a_out + && a_out_len, CR_BAD_PARAM_ERROR); + + if (*a_in_len < 1) { + *a_out_len = 0; + *a_out = NULL; + return CR_OK; + } + + status = cr_utils_ucs1_str_len_as_utf8 (a_in, &a_in[*a_in_len - 1], + &out_len); + + g_return_val_if_fail (status == CR_OK, status); + + in_len = *a_in_len; + + *a_out = (guchar *) g_malloc0 (out_len); + + status = cr_utils_ucs1_to_utf8 (a_in, a_in_len, *a_out, &out_len); + + *a_out_len = out_len; + + return status; +} + +/** + *Converts an utf8 buffer into an ucs1 buffer. + *The caller must know the size of the resulting + *converted buffer, and allocated it prior to calling this + *function. + * + *@param a_in the input utf8 buffer to convert. + * + *@param a_in_len in/out parameter. The size of the input utf8 buffer. + *After return, points to the number of bytes consumed + *by the function even in case of encoding error. + * + *@param a_out out parameter. Points to the resulting buffer. + *Must be allocated by the caller. If the size of a_out is shorter + *than its required size, this function converts what it can and return + *a successfull status. + * + *@param a_out_len in/out parameter. The size of the output buffer. + *After return, points to the number of bytes consumed even in case of + *encoding error. + * + *@return CR_OK upon successfull completion, an error code otherwise. + */ +enum CRStatus +cr_utils_utf8_to_ucs1 (const guchar * a_in, + gulong * a_in_len, guchar * a_out, gulong * a_out_len) +{ + gulong in_index = 0, + out_index = 0, + in_len = 0, + out_len = 0; + enum CRStatus status = CR_OK; + + /* + *to store the final decoded + *unicode char + */ + guint32 c = 0; + + g_return_val_if_fail (a_in && a_in_len + && a_out && a_out_len, CR_BAD_PARAM_ERROR); + + if (*a_in_len < 1) { + status = CR_OK; + goto end; + } + + in_len = *a_in_len; + out_len = *a_out_len; + + for (in_index = 0, out_index = 0; + (in_index < in_len) && (out_index < out_len); + in_index++, out_index++) { + gint nb_bytes_2_decode = 0; + + if (a_in[in_index] <= 0x7F) { + /* + *7 bits long char + *encoded over 1 byte: + * 0xxx xxxx + */ + c = a_in[in_index]; + nb_bytes_2_decode = 1; + + } else if ((a_in[in_index] & 0xE0) == 0xC0) { + /* + *up to 11 bits long char. + *encoded over 2 bytes: + *110x xxxx 10xx xxxx + */ + c = a_in[in_index] & 0x1F; + nb_bytes_2_decode = 2; + + } else if ((a_in[in_index] & 0xF0) == 0xE0) { + /* + *up to 16 bit long char + *encoded over 3 bytes: + *1110 xxxx 10xx xxxx 10xx xxxx + */ + c = a_in[in_index] & 0x0F; + nb_bytes_2_decode = 3; + + } else if ((a_in[in_index] & 0xF8) == 0xF0) { + /* + *up to 21 bits long char + *encoded over 4 bytes: + *1111 0xxx 10xx xxxx 10xx xxxx 10xx xxxx + */ + c = a_in[in_index] & 0x7; + nb_bytes_2_decode = 4; + + } else if ((a_in[in_index] & 0xFC) == 0xF8) { + /* + *up to 26 bits long char + *encoded over 5 bytes. + *1111 10xx 10xx xxxx 10xx xxxx + *10xx xxxx 10xx xxxx + */ + c = a_in[in_index] & 3; + nb_bytes_2_decode = 5; + + } else if ((a_in[in_index] & 0xFE) == 0xFC) { + /* + *up to 31 bits long char + *encoded over 6 bytes: + *1111 110x 10xx xxxx 10xx xxxx + *10xx xxxx 10xx xxxx 10xx xxxx + */ + c = a_in[in_index] & 1; + nb_bytes_2_decode = 6; + + } else { + /*BAD ENCODING */ + status = CR_ENCODING_ERROR; + goto end; + } + + /* + *Go and decode the remaining byte(s) + *(if any) to get the current character. + */ + if (in_index + nb_bytes_2_decode - 1 >= in_len) { + status = CR_OK; + goto end; + } + + for (; nb_bytes_2_decode > 1; nb_bytes_2_decode--) { + /*decode the next byte */ + in_index++; + + /*byte pattern must be: 10xx xxxx */ + if ((a_in[in_index] & 0xC0) != 0x80) { + status = CR_ENCODING_ERROR; + goto end; + } + + c = (c << 6) | (a_in[in_index] & 0x3F); + } + + /* + *The decoded ucs4 char is now + *in c. + */ + + if (c > 0xFF) { + status = CR_ENCODING_ERROR; + goto end; + } + + a_out[out_index] = c; + } + + end: + *a_out_len = out_index; + *a_in_len = in_index; + + return CR_OK; +} + +/** + *Converts an utf8 buffer into an + *ucs1 buffer. + *@param a_in_start the start of the input buffer. + *@param a_in_end the end of the input buffer. + *@param a_out out parameter. The resulting converted ucs4 buffer. + *Must be freed by the caller. + *@param a_out_len out parameter. The length of the converted buffer. + *@return CR_OK upon successfull completion, an error code otherwise. + *Note that out parameters are valid if and only if this function + *returns CR_OK. + */ +enum CRStatus +cr_utils_utf8_str_to_ucs1 (const guchar * a_in, + gulong * a_in_len, + guchar ** a_out, gulong * a_out_len) +{ + enum CRStatus status = CR_OK; + + g_return_val_if_fail (a_in && a_in_len + && a_out && a_out_len, CR_BAD_PARAM_ERROR); + + if (*a_in_len < 1) { + *a_out_len = 0; + *a_out = NULL; + return CR_OK; + } + + status = cr_utils_utf8_str_len_as_ucs4 (a_in, &a_in[*a_in_len - 1], + a_out_len); + + g_return_val_if_fail (status == CR_OK, status); + + *a_out = (guchar *) g_malloc0 (*a_out_len * sizeof (guint32)); + + status = cr_utils_utf8_to_ucs1 (a_in, a_in_len, *a_out, a_out_len); + return status; +} + +/***************************************** + *CSS basic types identification utilities + *****************************************/ + +/** + *Returns TRUE if a_char is a white space as + *defined in the css spec in chap 4.1.1. + * + *white-space ::= ' '| \t|\r|\n|\f + * + *@param a_char the character to test. + *return TRUE if is a white space, false otherwise. + */ +gboolean +cr_utils_is_white_space (guint32 a_char) +{ + switch (a_char) { + case ' ': + case '\t': + case '\r': + case '\n': + case '\f': + return TRUE; + break; + default: + return FALSE; + } +} + +/** + *Returns true if the character is a newline + *as defined in the css spec in the chap 4.1.1. + * + *nl ::= \n|\r\n|\r|\f + * + *@param a_char the character to test. + *@return TRUE if the character is a newline, FALSE otherwise. + */ +gboolean +cr_utils_is_newline (guint32 a_char) +{ + switch (a_char) { + case '\n': + case '\r': + case '\f': + return TRUE; + break; + default: + return FALSE; + } +} + +/** + *returns TRUE if the char is part of an hexa num char: + *i.e hexa_char ::= [0-9A-F] + */ +gboolean +cr_utils_is_hexa_char (guint32 a_char) +{ + if ((a_char >= '0' && a_char <= '9') + || (a_char >= 'A' && a_char <= 'F')) { + return TRUE; + } + return FALSE; +} + +/** + *Returns true if the character is a nonascii + *character (as defined in the css spec chap 4.1.1): + * + *nonascii ::= [^\0-\177] + * + *@param a_char the character to test. + *@return TRUE if the character is a nonascii char, + *FALSE otherwise. + */ +gboolean +cr_utils_is_nonascii (guint32 a_char) +{ + if (a_char <= 177) { + return FALSE; + } + + return TRUE; +} + +/** + *Dumps a character a_nb times on a file. + *@param a_char the char to dump + *@param a_fp the destination file pointer + *@param a_nb the number of times a_char is to be dumped. + */ +void +cr_utils_dump_n_chars (guchar a_char, FILE * a_fp, glong a_nb) +{ + glong i = 0; + + for (i = 0; i < a_nb; i++) { + fprintf (a_fp, "%c", a_char); + } +} + +void +cr_utils_dump_n_chars2 (guchar a_char, GString * a_string, glong a_nb) +{ + glong i = 0; + + g_return_if_fail (a_string); + + for (i = 0; i < a_nb; i++) { + g_string_append_printf (a_string, "%c", a_char); + } +} + +/** + *Duplicates a list of GString instances. + *@return the duplicated list of GString instances or NULL if + *something bad happened. + *@param a_list_of_strings the list of strings to be duplicated. + */ +GList * +cr_utils_dup_glist_of_string (GList * a_list_of_strings) +{ + GList *cur = NULL, + *result = NULL; + + g_return_val_if_fail (a_list_of_strings, NULL); + + for (cur = a_list_of_strings; cur; cur = cur->next) { + GString *str = NULL; + + str = g_string_new_len (((GString *) cur->data)->str, + ((GString *) cur->data)->len); + if (str) + result = g_list_append (result, str); + } + + return result; +} + +/** + *Duplicate a GList where the GList::data is a CRString. + *@param a_list_of_strings the list to duplicate + *@return the duplicated list, or NULL if something bad + *happened. + */ +GList * +cr_utils_dup_glist_of_cr_string (GList * a_list_of_strings) +{ + GList *cur = NULL, *result = NULL; + + g_return_val_if_fail (a_list_of_strings, NULL); + + for (cur = a_list_of_strings; cur; cur = cur->next) { + CRString *str = NULL; + + str = cr_string_dup ((CRString *) cur->data) ; + if (str) + result = g_list_append (result, str); + } + + return result; +} diff --git a/src/libcroco/cr-utils.h b/src/libcroco/cr-utils.h new file mode 100644 index 000000000..060842aef --- /dev/null +++ b/src/libcroco/cr-utils.h @@ -0,0 +1,249 @@ +/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ + +/* + * This file is part of The Croco Library + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * Author: Dodji Seketeli + * Look at file COPYRIGHTS for copyright information + */ + +#ifndef __CR_DEFS_H__ +#define __CR_DEFS_H__ + +#include +#include +/* + * We're disabling this #include for Inkscape: see comment in libcroco.h. +//#include "libcroco-config.h" + */ + +G_BEGIN_DECLS + +/** + *@file + *The Croco library basic types definitions + *And global definitions. + */ + +/** + *The status type returned + *by the methods of the croco library. + */ +enum CRStatus { + CR_OK, + CR_BAD_PARAM_ERROR, + CR_INSTANCIATION_FAILED_ERROR, + CR_UNKNOWN_TYPE_ERROR, + CR_UNKNOWN_PROP_ERROR, + CR_UNKNOWN_PROP_VAL_ERROR, + CR_UNEXPECTED_POSITION_SCHEME, + CR_START_OF_INPUT_ERROR, + CR_END_OF_INPUT_ERROR, + CR_OUTPUT_TOO_SHORT_ERROR, + CR_INPUT_TOO_SHORT_ERROR, + CR_OUT_OF_BOUNDS_ERROR, + CR_EMPTY_PARSER_INPUT_ERROR, + CR_ENCODING_ERROR, + CR_ENCODING_NOT_FOUND_ERROR, + CR_PARSING_ERROR, + CR_SYNTAX_ERROR, + CR_NO_ROOT_NODE_ERROR, + CR_NO_TOKEN, + CR_OUT_OF_MEMORY_ERROR, + CR_PSEUDO_CLASS_SEL_HANDLER_NOT_FOUND_ERROR, + CR_BAD_PSEUDO_CLASS_SEL_HANDLER_ERROR, + CR_ERROR, + CR_FILE_NOT_FOUND_ERROR, + CR_VALUE_NOT_FOUND_ERROR +} ; + +/** + *Values used by + *cr_input_seek_position() ; + */ +enum CRSeekPos { + CR_SEEK_CUR, + CR_SEEK_BEGIN, + CR_SEEK_END +} ; + +/** + *Encoding values. + */ +enum CREncoding +{ + CR_UCS_4 = 1/*Must be not NULL*/, + CR_UCS_1, + CR_ISO_8859_1, + CR_ASCII, + CR_UTF_8, + CR_UTF_16, + CR_AUTO/*should be the last one*/ +} ; + + + + +#define CROCO_LOG_DOMAIN "LIBCROCO" + +#ifdef __GNUC__ +#define cr_utils_trace(a_log_level, a_msg) \ +g_log (CROCO_LOG_DOMAIN, \ + G_LOG_LEVEL_CRITICAL, \ + "file %s: line %d (%s): %s\n", \ + __FILE__, \ + __LINE__, \ + __PRETTY_FUNCTION__, \ + a_msg) +#else /*__GNUC__*/ + +#define cr_utils_trace(a_log_level, a_msg) \ +g_log (CROCO_LOG_DOMAIN, \ + G_LOG_LEVEL_CRITICAL, \ + "file %s: line %d: %s\n", \ + __FILE__, \ + __LINE__, \ + a_msg) +#endif + +/** + *Traces an info message. + *The file, line and enclosing function + *of the message will be automatically + *added to the message. + *@param a_msg the msg to trace. + */ +#define cr_utils_trace_info(a_msg) \ +cr_utils_trace (G_LOG_LEVEL_INFO, a_msg) + +/** + *Trace a debug message. + *The file, line and enclosing function + *of the message will be automatically + *added to the message. + *@param a_msg the msg to trace. + */ +#define cr_utils_trace_debug(a_msg) \ +cr_utils_trace (G_LOG_LEVEL_DEBUG, a_msg) ; + + +/**************************** + *Encoding transformations and + *encoding helpers + ****************************/ + +enum CRStatus +cr_utils_read_char_from_utf8_buf (const guchar * a_in, gulong a_in_len, + guint32 *a_out, gulong *a_consumed) ; + +enum CRStatus +cr_utils_ucs1_to_utf8 (const guchar *a_in, gulong *a_in_len, + guchar *a_out, gulong *a_out_len) ; + +enum CRStatus +cr_utils_utf8_to_ucs1 (const guchar * a_in, gulong * a_in_len, + guchar *a_out, gulong *a_out_len) ; + +enum CRStatus +cr_utils_ucs4_to_utf8 (const guint32 *a_in, gulong *a_in_len, + guchar *a_out, gulong *a_out_len) ; + +enum CRStatus +cr_utils_utf8_str_len_as_ucs4 (const guchar *a_in_start, + const guchar *a_in_end, + gulong *a_len) ; +enum CRStatus +cr_utils_ucs1_str_len_as_utf8 (const guchar *a_in_start, + const guchar *a_in_end, + gulong *a_len) ; +enum CRStatus +cr_utils_utf8_str_len_as_ucs1 (const guchar *a_in_start, + const guchar *a_in_end, + gulong *a_len) ; +enum CRStatus +cr_utils_ucs4_str_len_as_utf8 (const guint32 *a_in_start, + const guint32 *a_in_end, + gulong *a_len) ; + +enum CRStatus +cr_utils_ucs1_str_to_utf8 (const guchar *a_in_start, + gulong *a_in_len, + guchar **a_out, + gulong *a_len) ; + +enum CRStatus +cr_utils_utf8_str_to_ucs1 (const guchar * a_in_start, + gulong * a_in_len, + guchar **a_out, + gulong *a_out_len) ; + +enum CRStatus +cr_utils_utf8_to_ucs4 (const guchar * a_in, + gulong * a_in_len, + guint32 *a_out, gulong *a_out_len) ; + +enum CRStatus +cr_utils_ucs4_str_to_utf8 (const guint32 *a_in, + gulong *a_in_len, + guchar **a_out, gulong *a_out_len) ; + +enum CRStatus +cr_utils_utf8_str_to_ucs4 (const guchar * a_in, + gulong *a_in_len, + guint32 **a_out, + gulong *a_out_len) ; + + +/***************************************** + *CSS basic types identification utilities + *****************************************/ + +gboolean +cr_utils_is_newline (guint32 a_char) ; + +gboolean +cr_utils_is_white_space (guint32 a_char) ; + +gboolean +cr_utils_is_nonascii (guint32 a_char) ; + +gboolean +cr_utils_is_hexa_char (guint32 a_char) ; + + +/********************************** + *Miscellaneous utility functions + ***********************************/ + +void +cr_utils_dump_n_chars (guchar a_char, + FILE *a_fp, + glong a_nb) ; + +void +cr_utils_dump_n_chars2 (guchar a_char, + GString *a_string, + glong a_nb) ; +GList * +cr_utils_dup_glist_of_string (GList *a_list) ; + +GList * +cr_utils_dup_glist_of_cr_string (GList * a_list_of_strings) ; + +G_END_DECLS + +#endif /*__CR_DEFS_H__*/ diff --git a/src/libcroco/libcroco.h b/src/libcroco/libcroco.h new file mode 100644 index 000000000..579715a6e --- /dev/null +++ b/src/libcroco/libcroco.h @@ -0,0 +1,48 @@ +/* + * This file is part of The Croco Library + * + * Copyright (C) 2002-2003 Dodji Seketeli + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2.1 of the GNU Lesser General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + +#ifndef __LIBCROCO_H__ +#define __LIBCROCO_H__ + +/* + * We're disabling this for inkscape: none of its macros are actually used anyway, + * so we might as well keep the build process simple. +//#include "libcroco-config.h" + */ + +#include "cr-utils.h" +#include "cr-pseudo.h" +#include "cr-term.h" +#include "cr-attr-sel.h" +#include "cr-simple-sel.h" +#include "cr-selector.h" +#include "cr-enc-handler.h" +#include "cr-doc-handler.h" +#include "cr-input.h" +#include "cr-parser.h" +#include "cr-statement.h" +#include "cr-stylesheet.h" +#include "cr-om-parser.h" +#include "cr-prop-list.h" +#include "cr-sel-eng.h" +#include "cr-style.h" +#include "cr-string.h" + +#endif /*__LIBCROCO_H__*/ diff --git a/src/libcroco/makefile.in b/src/libcroco/makefile.in new file mode 100644 index 000000000..618e88087 --- /dev/null +++ b/src/libcroco/makefile.in @@ -0,0 +1,17 @@ +# Convenience stub makefile to call the real Makefile. + +@SET_MAKE@ + +# Explicit so that it's the default rule. +all: + cd .. && $(MAKE) libcroco/all + +clean %.a %.o: + cd .. && $(MAKE) libcroco/$@ + +.PHONY: all clean + +OBJEXT = @OBJEXT@ + +.SUFFIXES: +.SUFFIXES: .a .$(OBJEXT) diff --git a/src/libnr/.cvsignore b/src/libnr/.cvsignore new file mode 100644 index 000000000..4191391ae --- /dev/null +++ b/src/libnr/.cvsignore @@ -0,0 +1,13 @@ +Makefile +Makefile.in +.deps +.libs +nr_config.h +testnr +gen_nr_config +makefile +.dirstamp +*-test +test-nr +test-nr.cpp +test-nr-main.cpp diff --git a/src/libnr/Makefile_insert b/src/libnr/Makefile_insert new file mode 100644 index 000000000..541432193 --- /dev/null +++ b/src/libnr/Makefile_insert @@ -0,0 +1,167 @@ +## Makefile.am fragment sourced by src/Makefile.am. + +libnr/all: libnr/libnr.a + +libnr/clean: + rm -f libnr/libnr.a libnr/libtest-nr.a $(libnr_libnr_a_OBJECTS) $(libnr_libtest_nr_a_OBJECTS) + +if USE_MMX +libnr_mmx_sources = \ + libnr/have_mmx.S \ + libnr/nr_mmx_R8G8B8A8_P_EMPTY_A8_RGBAP.S \ + libnr/nr_mmx_R8G8B8A8_P_R8G8B8A8_P_A8_RGBAP.S \ + libnr/nr_mmx_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_TRANSFORM.S \ + libnr/nr_mmx_R8G8B8_R8G8B8_R8G8B8A8_P.S +endif + +libnr_libnr_a_SOURCES = \ + libnr/in-svg-plane.h \ + libnr/n-art-bpath.h \ + libnr/nr-blit.cpp \ + libnr/nr-blit.h \ + libnr/nr-compose-transform.cpp \ + libnr/nr-compose-transform.h \ + libnr/nr-compose.cpp \ + libnr/nr-compose.h \ + libnr/nr-convex-hull.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-gradient.cpp \ + libnr/nr-gradient.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-div.cpp \ + libnr/nr-matrix-div.h \ + libnr/nr-matrix-fns.cpp \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix-ops.h \ + libnr/nr-matrix-rotate-ops.cpp \ + libnr/nr-matrix-rotate-ops.h \ + libnr/nr-matrix-scale-ops.cpp \ + libnr/nr-matrix-scale-ops.h \ + libnr/nr-matrix-translate-ops.cpp \ + libnr/nr-matrix-translate-ops.h \ + libnr/nr-matrix.cpp \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-object.cpp \ + libnr/nr-object.h \ + libnr/nr-path.cpp \ + libnr/nr-path.h \ + libnr/nr-path-code.h \ + libnr/nr-pixblock-line.cpp \ + libnr/nr-pixblock-line.h \ + libnr/nr-pixblock-pattern.cpp \ + libnr/nr-pixblock-pattern.h \ + libnr/nr-pixblock-pixel.cpp \ + libnr/nr-pixblock-pixel.h \ + libnr/nr-pixblock.cpp \ + libnr/nr-pixblock.h \ + libnr/nr-pixops.h \ + libnr/nr-point-fns.cpp \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.cpp \ + libnr/nr-rect-l.h \ + libnr/nr-rect.cpp \ + libnr/nr-rect.h \ + libnr/nr-rect-ops.h \ + libnr/nr-render.h \ + libnr/nr-rotate-fns.cpp \ + libnr/nr-rotate-fns.h \ + libnr/nr-rotate-ops.h \ + libnr/nr-rotate-matrix-ops.cpp \ + libnr/nr-rotate-matrix-ops.h \ + libnr/nr-rotate.h \ + libnr/nr-scale-matrix-ops.cpp \ + libnr/nr-scale-matrix-ops.h \ + libnr/nr-scale-translate-ops.cpp \ + libnr/nr-scale-translate-ops.h \ + libnr/nr-scale-ops.h \ + libnr/nr-scale.h \ + libnr/nr-svp-private.h \ + libnr/nr-svp-render.cpp \ + libnr/nr-svp-render.h \ + libnr/nr-svp.cpp \ + libnr/nr-svp.h \ + libnr/nr-translate-matrix-ops.cpp \ + libnr/nr-translate-matrix-ops.h \ + libnr/nr-translate-scale-ops.cpp \ + libnr/nr-translate-scale-ops.h \ + libnr/nr-translate-ops.h \ + libnr/nr-translate.h \ + libnr/nr-translate-rotate-ops.cpp \ + libnr/nr-translate-rotate-ops.h \ + libnr/nr-types.cpp \ + libnr/nr-types.h \ + libnr/nr-values.cpp \ + libnr/nr-values.h \ + $(libnr_mmx_sources) + +libnr_testnr_SOURCES = \ + libnr/testnr.cpp + +libnr_testnr_LDADD = \ + libnr/libnr.a \ + -lglib-2.0 + + +libnr/test-nr-main.cpp: libnr/test-nr.cpp + $(top_srcdir)/cxxtest/cxxtestgen.pl --error-printer -root -o libnr/test-nr-main.cpp $(libnr_test_nr_includes) + +libnr/test-nr.cpp: $(libnr_test_nr_includes) + $(top_srcdir)/cxxtest/cxxtestgen.pl -part -o libnr/test-nr.cpp $(libnr_test_nr_includes) + +libnr_test_nr_includes = \ + $(srcdir)/libnr/nr-types-test.h \ + $(srcdir)/libnr/nr-translate-test.h \ + $(srcdir)/libnr/nr-rotate-test.h \ + $(srcdir)/libnr/nr-scale-test.h \ + $(srcdir)/libnr/nr-point-fns-test.h \ + $(srcdir)/libnr/nr-rotate-fns-test.h \ + $(srcdir)/libnr/in-svg-plane-test.h \ + $(srcdir)/libnr/nr-matrix-test.h + +libnr_libtest_nr_a_SOURCES = \ + libnr/test-nr.cpp \ + $(libnr_test_nr_includes) + +libnr_test_nr_SOURCES = \ + libnr/test-nr-main.cpp \ + $(libnr_test_nr_includes) + +libnr_test_nr_LDADD = \ + libnr/libnr.a \ + libnr/libtest-nr.a \ + -lglib-2.0 + +# -L/usr/X11R6/lib +# -lX11 + +libnr_in_svg_plane_test_SOURCES = libnr/in-svg-plane-test.cpp +libnr_in_svg_plane_test_LDADD = libnr/libnr.a -lglib-2.0 + +libnr_nr_types_test_SOURCES = libnr/nr-types-test.cpp +libnr_nr_types_test_LDADD = libnr/libnr.a -lglib-2.0 + +libnr_nr_point_fns_test_SOURCES = libnr/nr-point-fns-test.cpp +libnr_nr_point_fns_test_LDADD = libnr/libnr.a -lglib-2.0 + +libnr_nr_matrix_test_SOURCES = libnr/nr-matrix-test.cpp +libnr_nr_matrix_test_LDADD = libnr/libnr.a -lglib-2.0 + +libnr_nr_rotate_test_SOURCES = libnr/nr-rotate-test.cpp +libnr_nr_rotate_test_LDADD = libnr/libnr.a -lglib-2.0 + +libnr_nr_rotate_fns_test_SOURCES = libnr/nr-rotate-fns-test.cpp +libnr_nr_rotate_fns_test_LDADD = libnr/libnr.a -lglib-2.0 + +libnr_nr_scale_test_SOURCES = libnr/nr-scale-test.cpp +libnr_nr_scale_test_LDADD = libnr/libnr.a -lglib-2.0 + +libnr_nr_translate_test_SOURCES = libnr/nr-translate-test.cpp +libnr_nr_translate_test_LDADD = libnr/libnr.a -lglib-2.0 diff --git a/src/libnr/have_mmx.S b/src/libnr/have_mmx.S new file mode 100644 index 000000000..d6428191e --- /dev/null +++ b/src/libnr/have_mmx.S @@ -0,0 +1,47 @@ + .file "have_mmx.S" + +# Ensure Inkscape is execshield protected + .section .note.GNU-stack + .previous + + .version "01.01" +gcc2_compiled.: +.text + .align 16 +.globl nr_have_mmx + .type nr_have_mmx,@function + +nr_have_mmx: + push %ebx + +# Check if bit 21 in flags word is writeable + + pushfl + popl %eax + movl %eax,%ebx + xorl $0x00200000, %eax + pushl %eax + popfl + pushfl + popl %eax + + cmpl %eax, %ebx + + je .notfound + +# OK, we have CPUID + + movl $1, %eax + cpuid + + test $0x00800000, %edx + jz .notfound + + movl $1, %eax + jmp .out + +.notfound: + movl $0, %eax +.out: + popl %ebx + ret diff --git a/src/libnr/in-svg-plane-test.cpp b/src/libnr/in-svg-plane-test.cpp new file mode 100644 index 000000000..f5620c32b --- /dev/null +++ b/src/libnr/in-svg-plane-test.cpp @@ -0,0 +1,58 @@ +#include +#include + +#include "libnr/in-svg-plane.h" +#include "utest/utest.h" +#include "isnan.h" + +int main(int argc, char *argv[]) +{ + utest_start("in-svg-plane.h"); + + NR::Point const p3n4(3.0, -4.0); + NR::Point const p0(0.0, 0.0); + double const small = pow(2.0, -1070); + double const inf = 1e400; + double const nan = inf - inf; + + NR::Point const small_left(-small, 0.0); + NR::Point const small_n3_4(-3.0 * small, 4.0 * small); + NR::Point const part_nan(3., nan); + + assert(isNaN(nan)); + assert(!isNaN(small)); + + UTEST_TEST("in_svg_plane") { + UTEST_ASSERT(in_svg_plane(p3n4)); + UTEST_ASSERT(in_svg_plane(p0)); + UTEST_ASSERT(in_svg_plane(small_left)); + UTEST_ASSERT(in_svg_plane(small_n3_4)); + UTEST_ASSERT(nan != nan); + UTEST_ASSERT(!in_svg_plane(NR::Point(nan, 3.))); + UTEST_ASSERT(!in_svg_plane(NR::Point(inf, nan))); + UTEST_ASSERT(!in_svg_plane(NR::Point(0., -inf))); + double const xs[] = {inf, -inf, nan, 1., -2., small, -small}; + for (unsigned i = 0; i < G_N_ELEMENTS(xs); ++i) { + for (unsigned j = 0; j < G_N_ELEMENTS(xs); ++j) { + UTEST_ASSERT( in_svg_plane(NR::Point(xs[i], xs[j])) + == (fabs(xs[i]) < inf && + fabs(xs[j]) < inf ) ); + } + } + } + + return ( utest_end() + ? EXIT_SUCCESS + : EXIT_FAILURE ); +} + +/* + 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:textwidth=99 : diff --git a/src/libnr/in-svg-plane-test.h b/src/libnr/in-svg-plane-test.h new file mode 100644 index 000000000..6cd29bd6a --- /dev/null +++ b/src/libnr/in-svg-plane-test.h @@ -0,0 +1,81 @@ +#include + +#include +#include + +#include "libnr/in-svg-plane.h" +#include "isnan.h" + +class InSvgPlaneTest : public CxxTest::TestSuite +{ +public: + + InSvgPlaneTest() : + setupValid(true), + p3n4( 3.0, -4.0 ), + p0(0.0, 0.0), + small( pow(2.0, -1070) ), + inf( 1e400 ), + nan( inf - inf ), + small_left( -small, 0.0 ), + small_n3_4( -3.0 * small, 4.0 * small ), + part_nan( 3., nan ) + { + setupValid &= isNaN(nan); + setupValid &= !isNaN(small); + } + virtual ~InSvgPlaneTest() {} + +// createSuite and destroySuite get us per-suite setup and teardown +// without us having to worry about static initialization order, etc. + static InSvgPlaneTest *createSuite() { return new InSvgPlaneTest(); } + static void destroySuite( InSvgPlaneTest *suite ) { delete suite; } + +// Called before each test in this suite + void setUp() + { + TS_ASSERT( setupValid ); + } + + bool setupValid; + NR::Point const p3n4; + NR::Point const p0; + double const small; + double const inf; + double const nan; + NR::Point const small_left; + NR::Point const small_n3_4; + NR::Point const part_nan; + + + void testInSvgPlane(void) + { + TS_ASSERT( in_svg_plane(p3n4) ); + TS_ASSERT( in_svg_plane(p0) ); + TS_ASSERT( in_svg_plane(small_left) ); + TS_ASSERT( in_svg_plane(small_n3_4) ); + TS_ASSERT_DIFFERS( nan, nan ); + TS_ASSERT( !in_svg_plane(NR::Point(nan, 3.)) ); + TS_ASSERT( !in_svg_plane(NR::Point(inf, nan)) ); + TS_ASSERT( !in_svg_plane(NR::Point(0., -inf)) ); + double const xs[] = {inf, -inf, nan, 1., -2., small, -small}; + for (unsigned i = 0; i < G_N_ELEMENTS(xs); ++i) { + for (unsigned j = 0; j < G_N_ELEMENTS(xs); ++j) { + TS_ASSERT_EQUALS( in_svg_plane(NR::Point(xs[i], xs[j])), + (fabs(xs[i]) < inf && + fabs(xs[j]) < inf ) ); + } + } + } +}; + +/* + 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:textwidth=99 : diff --git a/src/libnr/in-svg-plane.h b/src/libnr/in-svg-plane.h new file mode 100644 index 000000000..901fc748f --- /dev/null +++ b/src/libnr/in-svg-plane.h @@ -0,0 +1,33 @@ +#ifndef SEEN_LIBNR_IN_SVG_PLANE_H +#define SEEN_LIBNR_IN_SVG_PLANE_H + +#include "libnr/nr-point-fns.h" + + +/** + * Returns true iff the coordinates of \a p are finite, non-NaN, and "small enough". Currently we + * use the magic number 1e18 for determining "small enough", as this number has in the past been + * used in sodipodi code as a sort of "infinity" value. + * + * For SVG Tiny output, we might choose a smaller value corresponding to the range of valid numbers + * in SVG Tiny (which uses fixed-point arithmetic). + */ +inline bool +in_svg_plane(NR::Point const p) +{ + return NR::LInfty(p) < 1e18; +} + + +#endif /* !SEEN_LIBNR_IN_SVG_PLANE_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:encoding=utf-8:textwidth=99 : diff --git a/src/libnr/libnr.def b/src/libnr/libnr.def new file mode 100644 index 000000000..d8f224ca9 --- /dev/null +++ b/src/libnr/libnr.def @@ -0,0 +1,89 @@ +EXPORTS + nr_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_TRANSFORM + nr_R8G8B8A8_N_EMPTY_A8_RGBA32 + nr_R8G8B8A8_N_EMPTY_R8G8B8A8_N + nr_R8G8B8A8_N_EMPTY_R8G8B8A8_N_A8 + nr_R8G8B8A8_N_EMPTY_R8G8B8A8_P + nr_R8G8B8A8_N_EMPTY_R8G8B8A8_P_A8 + nr_R8G8B8A8_N_R8G8B8A8_N_A8_RGBA32 + nr_R8G8B8A8_N_R8G8B8A8_N_R8G8B8A8_N + nr_R8G8B8A8_N_R8G8B8A8_N_R8G8B8A8_N_A8 + nr_R8G8B8A8_N_R8G8B8A8_N_R8G8B8A8_N_TRANSFORM + nr_R8G8B8A8_N_R8G8B8A8_N_R8G8B8A8_P + nr_R8G8B8A8_N_R8G8B8A8_N_R8G8B8A8_P_A8 + nr_R8G8B8A8_P_EMPTY_A8_RGBA32 + nr_R8G8B8A8_P_EMPTY_R8G8B8A8_N + nr_R8G8B8A8_P_EMPTY_R8G8B8A8_N_A8 + nr_R8G8B8A8_P_EMPTY_R8G8B8A8_P + nr_R8G8B8A8_P_EMPTY_R8G8B8A8_P_A8 + nr_R8G8B8A8_P_R8G8B8A8_P_A8_RGBA32 + nr_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N + nr_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_A8 + nr_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_P + nr_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_P_A8 +; nr_R8G8B8_EMPTY_A8_RGBA32 + nr_R8G8B8_R8G8B8_A8_RGBA32 + nr_R8G8B8_R8G8B8_R8G8B8A8_N + nr_R8G8B8_R8G8B8_R8G8B8A8_P + nr_active_object_add_listener + nr_active_object_get_type + nr_active_object_remove_listener_by_data + nr_blit_pixblock_mask_rgba32 + nr_blit_pixblock_pixblock_alpha + nr_blit_pixblock_pixblock_mask + nr_compose_pixblock_pixblock_pixel + nr_emit_fail_warning + nr_flat_free_list + nr_flat_free_one + nr_flat_insert_sorted + nr_flat_new_full + nr_lgradient_renderer_setup + nr_matrix_invert + nr_matrix_set_rotate + nr_matrix_set_scale + nr_matrix_set_translate + nr_matrix_multiply + nr_object_check_instance_cast + nr_object_check_instance_type + nr_object_delete + nr_object_get_type + nr_object_new + nr_object_ref + nr_object_register_type + nr_object_release + nr_object_setup + nr_object_unref + nr_path_duplicate_transform + nr_path_matrix_bbox_nion + nr_path_matrix_point_bbox_wind_distance + nr_pixblock_draw_line_rgba32 + nr_pixblock_free + nr_pixblock_new + nr_pixblock_release + nr_pixblock_render_gray_noise + nr_pixblock_render_svp_mask_or + nr_pixblock_setup + nr_pixblock_setup_extern + nr_pixblock_setup_fast + nr_pixelstore_16K_free + nr_pixelstore_16K_new + nr_pixelstore_4K_free + nr_pixelstore_4K_new + nr_pixelstore_64K_free + nr_pixelstore_64K_new + nr_rect_d_intersect + nr_rect_d_matrix_transform + nr_rect_d_union + nr_rect_l_intersect + nr_rect_l_union + nr_rgradient_renderer_setup + nr_svp_bbox + nr_svp_free + nr_svp_point_distance + nr_svp_point_wind + nr_type_is_a + nr_vertex_free_list + nr_vertex_free_one + nr_vertex_new + nr_vertex_new_xy + nr_vertex_reverse_list diff --git a/src/libnr/makefile.in b/src/libnr/makefile.in new file mode 100644 index 000000000..8c80244ab --- /dev/null +++ b/src/libnr/makefile.in @@ -0,0 +1,17 @@ +# Convenience stub makefile to call the real Makefile. + +@SET_MAKE@ + +# Explicit so that it's the default rule. +all: + cd .. && $(MAKE) libnr/all + +clean %.a %.o: + cd .. && $(MAKE) libnr/$@ + +.PHONY: all clean + +OBJEXT = @OBJEXT@ + +.SUFFIXES: +.SUFFIXES: .a .$(OBJEXT) diff --git a/src/libnr/n-art-bpath.h b/src/libnr/n-art-bpath.h new file mode 100644 index 000000000..abce499e0 --- /dev/null +++ b/src/libnr/n-art-bpath.h @@ -0,0 +1,61 @@ +#ifndef SEEN_LIBNR_N_ART_BPATH_H +#define SEEN_LIBNR_N_ART_BPATH_H + +/** \file + * NArtBpath: old-style path segment. + */ + +#include "libnr/nr-point.h" +#include "libnr/nr-path-code.h" + +/** + * Old-style path segment. + * + * Arrays of paths segment start with a MOVETO or MOVETO_OPEN segment + * where the former indicates the beginning of a closed subpath. + * \see subpath_from_bpath() + */ +class NArtBpath { +public: + NRPathcode code; ///< Type of segment + double x1, y1; ///< Position of control point in case of NR_CURVETO + double x2, y2; ///< Position of control point in case of NR_CURVETO + double x3, y3; ///< Position of next point + + /// Convert i-th position data pair to Point object + /// \pre 1 <= i <= 3 + NR::Point c(unsigned const i) const { + switch (i) { + case 1: return NR::Point(x1, y1); + case 2: return NR::Point(x2, y2); + case 3: return NR::Point(x3, y3); + default: abort(); + } + } + + /// Set i-th position data pair from Point + /// \pre 1 <= i <= 3 + void setC(unsigned const i, NR::Point const &p) { + using NR::X; using NR::Y; + switch (i) { + case 1: x1 = p[X]; y1 = p[Y]; break; + case 2: x2 = p[X]; y2 = p[Y]; break; + case 3: x3 = p[X]; y3 = p[Y]; break; + default: abort(); + } + } +}; + + +#endif /* !SEEN_LIBNR_N_ART_BPATH_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 : diff --git a/src/libnr/nr-blit.cpp b/src/libnr/nr-blit.cpp new file mode 100644 index 000000000..2a93bc9bd --- /dev/null +++ b/src/libnr/nr-blit.cpp @@ -0,0 +1,300 @@ +#define __NR_BLIT_C__ + +/* + * Pixel buffer rendering library + * + * Authors: + * Lauris Kaplinski + * + * This code is in public domain + */ + +#include "nr-pixops.h" +#include "nr-compose.h" +#include "nr-blit.h" + +void +nr_blit_pixblock_pixblock_alpha (NRPixBlock *d, NRPixBlock *s, unsigned int alpha) +{ + NRRectL clip; + unsigned char *dpx, *spx; + int dbpp, sbpp; + int w, h; + + if (alpha == 0) return; + if (s->empty) return; + /* fixme: */ + if (s->mode == NR_PIXBLOCK_MODE_A8) return; + /* fixme: */ + if (s->mode == NR_PIXBLOCK_MODE_R8G8B8) return; + + /* + * Possible variants as of now: + * + * 0. SRC EP - DST EP * + * 1. SRC EP - DST EN * + * 2. SRC EP - DST P * + * 3. SRC EP - DST N * + * 4. SRC EN - DST EP * + * 5. SRC EN - DST EN * + * 6. SRC EN - DST P * + * 7. SRC EN - DST N * + * 8. SRC P - DST EP * + * 9. SRC P - DST EN * + * A. SRC P - DST P * + * B. SRC P - DST N * + * C. SRC N - DST EP * + * D. SRC N - DST EN * + * E. SRC N - DST P * + * F. SRC N - DST N * + * + */ + + nr_rect_l_intersect (&clip, &d->area, &s->area); + + if (nr_rect_l_test_empty (&clip)) return; + + /* Pointers */ + dbpp = NR_PIXBLOCK_BPP (d); + dpx = NR_PIXBLOCK_PX (d) + (clip.y0 - d->area.y0) * d->rs + dbpp * (clip.x0 - d->area.x0); + sbpp = NR_PIXBLOCK_BPP (s); + spx = NR_PIXBLOCK_PX (s) + (clip.y0 - s->area.y0) * s->rs + sbpp * (clip.x0 - s->area.x0); + w = clip.x1 - clip.x0; + h = clip.y1 - clip.y0; + + switch (d->mode) { + case NR_PIXBLOCK_MODE_A8: + /* No rendering into alpha at moment */ + break; + case NR_PIXBLOCK_MODE_R8G8B8: + if (s->mode == NR_PIXBLOCK_MODE_R8G8B8A8P) { + nr_R8G8B8_R8G8B8_R8G8B8A8_P (dpx, w, h, d->rs, spx, s->rs, alpha); + } else { + nr_R8G8B8_R8G8B8_R8G8B8A8_N (dpx, w, h, d->rs, spx, s->rs, alpha); + } + break; + case NR_PIXBLOCK_MODE_R8G8B8A8P: + if (d->empty) { + if (s->mode == NR_PIXBLOCK_MODE_R8G8B8A8P) { + /* Case 8 */ + nr_R8G8B8A8_P_EMPTY_R8G8B8A8_P (dpx, w, h, d->rs, spx, s->rs, alpha); + } else { + /* Case C */ + nr_R8G8B8A8_P_EMPTY_R8G8B8A8_N (dpx, w, h, d->rs, spx, s->rs, alpha); + } + } else { + if (s->mode == NR_PIXBLOCK_MODE_R8G8B8A8P) { + /* case A */ + nr_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_P (dpx, w, h, d->rs, spx, s->rs, alpha); + } else { + /* case E */ + nr_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N (dpx, w, h, d->rs, spx, s->rs, alpha); + } + } + break; + case NR_PIXBLOCK_MODE_R8G8B8A8N: + if (d->empty) { + if (s->mode == NR_PIXBLOCK_MODE_R8G8B8A8P) { + /* Case 9 */ + nr_R8G8B8A8_N_EMPTY_R8G8B8A8_P (dpx, w, h, d->rs, spx, s->rs, alpha); + } else { + /* Case D */ + nr_R8G8B8A8_N_EMPTY_R8G8B8A8_N (dpx, w, h, d->rs, spx, s->rs, alpha); + } + } else { + if (s->mode == NR_PIXBLOCK_MODE_R8G8B8A8P) { + /* case B */ + nr_R8G8B8A8_N_R8G8B8A8_N_R8G8B8A8_P (dpx, w, h, d->rs, spx, s->rs, alpha); + } else { + /* case F */ + nr_R8G8B8A8_N_R8G8B8A8_N_R8G8B8A8_N (dpx, w, h, d->rs, spx, s->rs, alpha); + } + } + break; + } +} + +void +nr_blit_pixblock_pixblock_mask (NRPixBlock *d, NRPixBlock *s, NRPixBlock *m) +{ + NRRectL clip; + unsigned char *dpx, *spx, *mpx; + int dbpp, sbpp; + int w, h; + + if (s->empty) return; + /* fixme: */ + if (s->mode == NR_PIXBLOCK_MODE_A8) return; + /* fixme: */ + if (s->mode == NR_PIXBLOCK_MODE_R8G8B8) return; + + /* + * Possible variants as of now: + * + * 0. SRC EP - DST EP * + * 1. SRC EP - DST EN * + * 2. SRC EP - DST P * + * 3. SRC EP - DST N * + * 4. SRC EN - DST EP * + * 5. SRC EN - DST EN * + * 6. SRC EN - DST P * + * 7. SRC EN - DST N * + * 8. SRC P - DST EP * + * 9. SRC P - DST EN * + * A. SRC P - DST P * + * B. SRC P - DST N * + * C. SRC N - DST EP * + * D. SRC N - DST EN * + * E. SRC N - DST P * + * F. SRC N - DST N * + * + */ + + nr_rect_l_intersect (&clip, &d->area, &s->area); + nr_rect_l_intersect (&clip, &clip, &m->area); + + if (nr_rect_l_test_empty (&clip)) return; + + /* Pointers */ + dbpp = NR_PIXBLOCK_BPP (d); + dpx = NR_PIXBLOCK_PX (d) + (clip.y0 - d->area.y0) * d->rs + dbpp * (clip.x0 - d->area.x0); + sbpp = NR_PIXBLOCK_BPP (s); + spx = NR_PIXBLOCK_PX (s) + (clip.y0 - s->area.y0) * s->rs + sbpp * (clip.x0 - s->area.x0); + mpx = NR_PIXBLOCK_PX (m) + (clip.y0 - m->area.y0) * m->rs + 1 * (clip.x0 - m->area.x0); + w = clip.x1 - clip.x0; + h = clip.y1 - clip.y0; + + switch (d->mode) { + case NR_PIXBLOCK_MODE_A8: + /* No rendering into alpha at moment */ + break; + case NR_PIXBLOCK_MODE_R8G8B8: + if (s->mode == NR_PIXBLOCK_MODE_R8G8B8A8P) { + nr_R8G8B8_R8G8B8_R8G8B8A8_P_A8 (dpx, w, h, d->rs, spx, s->rs, mpx, m->rs); + } else { + nr_R8G8B8_R8G8B8_R8G8B8A8_N_A8 (dpx, w, h, d->rs, spx, s->rs, mpx, m->rs); + } + break; + case NR_PIXBLOCK_MODE_R8G8B8A8P: + if (d->empty) { + if (s->mode == NR_PIXBLOCK_MODE_R8G8B8A8P) { + /* Case 8 */ + nr_R8G8B8A8_P_EMPTY_R8G8B8A8_P_A8 (dpx, w, h, d->rs, spx, s->rs, mpx, m->rs); + } else { + /* Case C */ + nr_R8G8B8A8_P_EMPTY_R8G8B8A8_N_A8 (dpx, w, h, d->rs, spx, s->rs, mpx, m->rs); + } + } else { + if (s->mode == NR_PIXBLOCK_MODE_R8G8B8A8P) { + /* case A */ + nr_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_P_A8 (dpx, w, h, d->rs, spx, s->rs, mpx, m->rs); + } else { + /* case E */ + nr_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_A8 (dpx, w, h, d->rs, spx, s->rs, mpx, m->rs); + } + } + break; + case NR_PIXBLOCK_MODE_R8G8B8A8N: + if (d->empty) { + if (s->mode == NR_PIXBLOCK_MODE_R8G8B8A8P) { + /* Case 9 */ + nr_R8G8B8A8_N_EMPTY_R8G8B8A8_P_A8 (dpx, w, h, d->rs, spx, s->rs, mpx, m->rs); + } else { + /* Case D */ + nr_R8G8B8A8_N_EMPTY_R8G8B8A8_N_A8 (dpx, w, h, d->rs, spx, s->rs, mpx, m->rs); + } + } else { + if (s->mode == NR_PIXBLOCK_MODE_R8G8B8A8P) { + /* case B */ + nr_R8G8B8A8_N_R8G8B8A8_N_R8G8B8A8_P_A8 (dpx, w, h, d->rs, spx, s->rs, mpx, m->rs); + } else { + /* case F */ + nr_R8G8B8A8_N_R8G8B8A8_N_R8G8B8A8_N_A8 (dpx, w, h, d->rs, spx, s->rs, mpx, m->rs); + } + } + break; + } +} + +void +nr_blit_pixblock_mask_rgba32 (NRPixBlock *d, NRPixBlock *m, unsigned long rgba) +{ + if (!(rgba & 0xff)) return; + + if (m) { + NRRectL clip; + unsigned char *dpx, *mpx; + int w, h; + + if (m->mode != NR_PIXBLOCK_MODE_A8) return; + + if (!nr_rect_l_test_intersect (&d->area, &m->area)) return; + + nr_rect_l_intersect (&clip, &d->area, &m->area); + + /* Pointers */ + dpx = NR_PIXBLOCK_PX (d) + (clip.y0 - d->area.y0) * d->rs + NR_PIXBLOCK_BPP (d) * (clip.x0 - d->area.x0); + mpx = NR_PIXBLOCK_PX (m) + (clip.y0 - m->area.y0) * m->rs + (clip.x0 - m->area.x0); + w = clip.x1 - clip.x0; + h = clip.y1 - clip.y0; + + if (d->empty) { + if (d->mode == NR_PIXBLOCK_MODE_R8G8B8) { + nr_R8G8B8_R8G8B8_A8_RGBA32 (dpx, w, h, d->rs, mpx, m->rs, rgba); + } else if (d->mode == NR_PIXBLOCK_MODE_R8G8B8A8P) { + nr_R8G8B8A8_P_EMPTY_A8_RGBA32 (dpx, w, h, d->rs, mpx, m->rs, rgba); + } else { + nr_R8G8B8A8_N_EMPTY_A8_RGBA32 (dpx, w, h, d->rs, mpx, m->rs, rgba); + } + d->empty = 0; + } else { + if (d->mode == NR_PIXBLOCK_MODE_R8G8B8) { + nr_R8G8B8_R8G8B8_A8_RGBA32 (dpx, w, h, d->rs, mpx, m->rs, rgba); + } else if (d->mode == NR_PIXBLOCK_MODE_R8G8B8A8P) { + nr_R8G8B8A8_P_R8G8B8A8_P_A8_RGBA32 (dpx, w, h, d->rs, mpx, m->rs, rgba); + } else { + nr_R8G8B8A8_N_R8G8B8A8_N_A8_RGBA32 (dpx, w, h, d->rs, mpx, m->rs, rgba); + } + } + } else { + unsigned int r, g, b, a; + int x, y; + r = NR_RGBA32_R (rgba); + g = NR_RGBA32_G (rgba); + b = NR_RGBA32_B (rgba); + a = NR_RGBA32_A (rgba); + for (y = d->area.y0; y < d->area.y1; y++) { + unsigned char *p; + p = NR_PIXBLOCK_PX (d) + (y - d->area.y0) * d->rs; + for (x = d->area.x0; x < d->area.x1; x++) { + unsigned int da; + switch (d->mode) { + case NR_PIXBLOCK_MODE_R8G8B8: + p[0] = NR_COMPOSEN11 (r, a, p[0]); + p[1] = NR_COMPOSEN11 (g, a, p[1]); + p[2] = NR_COMPOSEN11 (b, a, p[2]); + p += 3; + break; + case NR_PIXBLOCK_MODE_R8G8B8A8P: + p[0] = NR_COMPOSENPP (r, a, p[0], p[3]); + p[1] = NR_COMPOSENPP (g, a, p[1], p[3]); + p[2] = NR_COMPOSENPP (b, a, p[2], p[3]); + p[3] = (65025 - (255 - a) * (255 - p[3]) + 127) / 255; + p += 4; + break; + case NR_PIXBLOCK_MODE_R8G8B8A8N: + da = 65025 - (255 - a) * (255 - p[3]); + p[0] = NR_COMPOSENNN_A7 (r, a, p[0], p[3], da); + p[1] = NR_COMPOSENNN_A7 (g, a, p[1], p[3], da); + p[2] = NR_COMPOSENNN_A7 (b, a, p[2], p[3], da); + p[3] = (da + 127) / 255; + p += 4; + break; + default: + break; + } + } + } + } +} + diff --git a/src/libnr/nr-blit.h b/src/libnr/nr-blit.h new file mode 100644 index 000000000..3221c8187 --- /dev/null +++ b/src/libnr/nr-blit.h @@ -0,0 +1,32 @@ +#ifndef __NR_BLIT_H__ +#define __NR_BLIT_H__ + +/* + * Pixel buffer rendering library + * + * Authors: + * Lauris Kaplinski + * + * This code is in public domain + */ + +#include + +#define nr_blit_pixblock_pixblock(d,s) nr_blit_pixblock_pixblock_alpha (d, s, 255) + +void nr_blit_pixblock_pixblock_alpha (NRPixBlock *d, NRPixBlock *s, unsigned int alpha); +void nr_blit_pixblock_pixblock_mask (NRPixBlock *d, NRPixBlock *s, NRPixBlock *m); +void nr_blit_pixblock_mask_rgba32 (NRPixBlock *d, NRPixBlock *m, unsigned long rgba32); + +#endif + +/* + 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:textwidth=99 : diff --git a/src/libnr/nr-compose-transform.cpp b/src/libnr/nr-compose-transform.cpp new file mode 100644 index 000000000..bb5022a74 --- /dev/null +++ b/src/libnr/nr-compose-transform.cpp @@ -0,0 +1,360 @@ +#define __NR_COMPOSE_TRANSFORM_C__ + +/* + * Pixel buffer rendering library + * + * Authors: + * Lauris Kaplinski + * + * This code is in public domain + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "nr-pixops.h" +#include "nr-matrix.h" + + +#ifdef WITH_MMX +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ +/* fixme: */ +int nr_have_mmx (void); +void nr_mmx_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_TRANSFORM_0 (unsigned char *px, int w, int h, int rs, + const unsigned char *spx, int sw, int sh, int srs, + const long *FFd2s, unsigned int alpha); +void nr_mmx_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_TRANSFORM_n (unsigned char *px, int w, int h, int rs, + const unsigned char *spx, int sw, int sh, int srs, + const long *FFd2s, const long *FF_S, unsigned int alpha, int dbits); +#define NR_PIXOPS_MMX (1 && nr_have_mmx ()) +#ifdef __cplusplus +} +#endif //__cplusplus +#endif + +/* fixme: Implement missing (Lauris) */ +/* fixme: PREMUL colors before calculating average (Lauris) */ + +/* Fixed point precision */ +#define FBITS 12 + +void nr_R8G8B8A8_N_EMPTY_R8G8B8A8_N_TRANSFORM (unsigned char *px, int w, int h, int rs, + const unsigned char *spx, int sw, int sh, int srs, + const NR::Matrix &d2s, unsigned int alpha, int xd, int yd); +void nr_R8G8B8A8_N_EMPTY_R8G8B8A8_P_TRANSFORM (unsigned char *px, int w, int h, int rs, + const unsigned char *spx, int sw, int sh, int srs, + const NR::Matrix &d2s, unsigned int alpha, int xd, int yd); +void nr_R8G8B8A8_P_EMPTY_R8G8B8A8_N_TRANSFORM (unsigned char *px, int w, int h, int rs, + const unsigned char *spx, int sw, int sh, int srs, + const NR::Matrix &d2s, unsigned int alpha, int xd, int yd); +void nr_R8G8B8A8_P_EMPTY_R8G8B8A8_P_TRANSFORM (unsigned char *px, int w, int h, int rs, + const unsigned char *spx, int sw, int sh, int srs, + const NR::Matrix &d2s, unsigned int alpha, int xd, int yd); + +void +nr_R8G8B8A8_N_R8G8B8A8_N_R8G8B8A8_N_TRANSFORM (unsigned char *px, int w, int h, int rs, + const unsigned char *spx, int sw, int sh, int srs, + const NR::Matrix &d2s, unsigned int alpha, int xd, int yd) +{ + int xsize, ysize, size, dbits; + long FFs_x_x, FFs_x_y, FFs_y_x, FFs_y_y, FFs__x, FFs__y; + long FFs_x_x_S, FFs_x_y_S, FFs_y_x_S, FFs_y_y_S; + /* Subpixel positions */ + int FF_sx_S[256]; + int FF_sy_S[256]; + unsigned char *d0; + int FFsx0, FFsy0; + int x, y; + + if (alpha == 0) return; + + xsize = (1 << xd); + ysize = (1 << yd); + size = xsize * ysize; + dbits = xd + yd; + + /* Set up fixed point matrix */ + FFs_x_x = (long) (d2s[0] * (1 << FBITS) + 0.5); + FFs_x_y = (long) (d2s[1] * (1 << FBITS) + 0.5); + FFs_y_x = (long) (d2s[2] * (1 << FBITS) + 0.5); + FFs_y_y = (long) (d2s[3] * (1 << FBITS) + 0.5); + FFs__x = (long) (d2s[4] * (1 << FBITS) + 0.5); + FFs__y = (long) (d2s[5] * (1 << FBITS) + 0.5); + + FFs_x_x_S = FFs_x_x >> xd; + FFs_x_y_S = FFs_x_y >> xd; + FFs_y_x_S = FFs_y_x >> yd; + FFs_y_y_S = FFs_y_y >> yd; + + /* Set up subpixel matrix */ + /* fixme: We can calculate that in floating point (Lauris) */ + for (y = 0; y < ysize; y++) { + for (x = 0; x < xsize; x++) { + FF_sx_S[y * xsize + x] = FFs_x_x_S * x + FFs_y_x_S * y; + FF_sy_S[y * xsize + x] = FFs_x_y_S * x + FFs_y_y_S * y; + } + } + + d0 = px; + FFsx0 = FFs__x; + FFsy0 = FFs__y; + + for (y = 0; y < h; y++) { + unsigned char *d; + long FFsx, FFsy; + d = d0; + FFsx = FFsx0; + FFsy = FFsy0; + for (x = 0; x < w; x++) { + unsigned int r, g, b, a; + long sx, sy; + int i; + r = g = b = a = 0; + for (i = 0; i < size; i++) { + sx = (FFsx + FF_sx_S[i]) >> FBITS; + if ((sx >= 0) && (sx < sw)) { + sy = (FFsy + FF_sy_S[i]) >> FBITS; + if ((sy >= 0) && (sy < sh)) { + const unsigned char *s; + unsigned int ca; + s = spx + sy * srs + sx * 4; + ca = NR_PREMUL (s[3], alpha); + r += NR_PREMUL (s[0], ca); + g += NR_PREMUL (s[1], ca); + b += NR_PREMUL (s[2], ca); + a += ca; + } + } + } + a >>= dbits; + if (a != 0) { + r = r >> dbits; + g = g >> dbits; + b = b >> dbits; + if (a == 255) { + /* Transparent BG, premul src */ + d[0] = r; + d[1] = g; + d[2] = b; + d[3] = a; + } else { + unsigned int ca; + /* Full composition */ + ca = 65025 - (255 - a) * (255 - d[3]); + d[0] = NR_COMPOSENNN_A7 (r, a, d[0], d[3], ca); + d[1] = NR_COMPOSENNN_A7 (g, a, d[1], d[3], ca); + d[2] = NR_COMPOSENNN_A7 (b, a, d[2], d[3], ca); + d[3] = (ca + 127) / 255; + } + } + /* Advance pointers */ + FFsx += FFs_x_x; + FFsy += FFs_x_y; + d += 4; + } + FFsx0 += FFs_y_x; + FFsy0 += FFs_y_y; + d0 += rs; + } +} + +void nr_R8G8B8A8_N_R8G8B8A8_N_R8G8B8A8_P_TRANSFORM (unsigned char *px, int w, int h, int rs, + const unsigned char *spx, int sw, int sh, int srs, + const NR::Matrix &d2s, unsigned int alpha, int xd, int yd); + +static void +nr_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_TRANSFORM_0 (unsigned char *px, int w, int h, int rs, + const unsigned char *spx, int sw, int sh, int srs, + const long *FFd2s, unsigned int alpha) +{ + unsigned char *d0; + int FFsx0, FFsy0; + int x, y; + + d0 = px; + FFsx0 = FFd2s[4]; + FFsy0 = FFd2s[5]; + + for (y = 0; y < h; y++) { + unsigned char *d; + long FFsx, FFsy; + d = d0; + FFsx = FFsx0; + FFsy = FFsy0; + for (x = 0; x < w; x++) { + long sx, sy; + sx = FFsx >> FBITS; + if ((sx >= 0) && (sx < sw)) { + sy = FFsy >> FBITS; + if ((sy >= 0) && (sy < sh)) { + const unsigned char *s; + unsigned int a; + s = spx + sy * srs + sx * 4; + a = NR_PREMUL (s[3], alpha); + if (a != 0) { + if ((a == 255) || (d[3] == 0)) { + /* Transparent BG, premul src */ + d[0] = NR_PREMUL (s[0], a); + d[1] = NR_PREMUL (s[1], a); + d[2] = NR_PREMUL (s[2], a); + d[3] = a; + } else { + d[0] = NR_COMPOSENPP (s[0], a, d[0], d[3]); + d[1] = NR_COMPOSENPP (s[1], a, d[1], d[3]); + d[2] = NR_COMPOSENPP (s[2], a, d[2], d[3]); + d[3] = (65025 - (255 - a) * (255 - d[3]) + 127) / 255; + } + } + } + } + /* Advance pointers */ + FFsx += FFd2s[0]; + FFsy += FFd2s[1]; + d += 4; + } + FFsx0 += FFd2s[2]; + FFsy0 += FFd2s[3]; + d0 += rs; + } +} + +static void +nr_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_TRANSFORM_n (unsigned char *px, int w, int h, int rs, + const unsigned char *spx, int sw, int sh, int srs, + const long *FFd2s, const long *FF_S, unsigned int alpha, int dbits) +{ + int size; + unsigned char *d0; + int FFsx0, FFsy0; + int x, y; + + size = (1 << dbits); + unsigned alpha_rounding_fix = size * 255; + unsigned rgb_rounding_fix = size * (255 * 256); + if (alpha > 127) ++alpha; + + d0 = px; + FFsx0 = FFd2s[4]; + FFsy0 = FFd2s[5]; + + for (y = 0; y < h; y++) { + unsigned char *d; + long FFsx, FFsy; + d = d0; + FFsx = FFsx0; + FFsy = FFsy0; + for (x = 0; x < w; x++) { + unsigned int r, g, b, a; + int i; + r = g = b = a = 0; + for (i = 0; i < size; i++) { + long sx, sy; + sx = (FFsx + FF_S[2 * i]) >> FBITS; + if ((sx >= 0) && (sx < sw)) { + sy = (FFsy + FF_S[2 * i + 1]) >> FBITS; + if ((sy >= 0) && (sy < sh)) { + const unsigned char *s; + unsigned int ca; + s = spx + sy * srs + sx * 4; + ca = s[3] * alpha; + r += s[0] * ca; + g += s[1] * ca; + b += s[2] * ca; + a += ca; + } + } + } + a = (a + alpha_rounding_fix) >> (8 + dbits); + if (a != 0) { + r = (r + rgb_rounding_fix) >> (16 + dbits); + g = (g + rgb_rounding_fix) >> (16 + dbits); + b = (b + rgb_rounding_fix) >> (16 + dbits); + if ((a == 255) || (d[3] == 0)) { + /* Transparent BG, premul src */ + d[0] = r; + d[1] = g; + d[2] = b; + d[3] = a; + } else { + d[0] = NR_COMPOSEPPP (r, a, d[0], d[3]); + d[1] = NR_COMPOSEPPP (g, a, d[1], d[3]); + d[2] = NR_COMPOSEPPP (b, a, d[2], d[3]); + d[3] = (65025 - (255 - a) * (255 - d[3]) + 127) / 255; + } + } + /* Advance pointers */ + FFsx += FFd2s[0]; + FFsy += FFd2s[1]; + d += 4; + } + FFsx0 += FFd2s[2]; + FFsy0 += FFd2s[3]; + d0 += rs; + } +} + +void nr_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_TRANSFORM (unsigned char *px, int w, int h, int rs, + const unsigned char *spx, int sw, int sh, int srs, + const NR::Matrix &d2s, unsigned int alpha, int xd, int yd) +{ + int dbits; + long FFd2s[6]; + int i; + + if (alpha == 0) return; + + dbits = xd + yd; + + for (i = 0; i < 6; i++) { + FFd2s[i] = (long) (d2s[i] * (1 << FBITS) + 0.5); + } + + if (dbits == 0) { +#ifdef WITH_MMX + if (NR_PIXOPS_MMX) { + /* WARNING: MMX composer REQUIRES w > 0 and h > 0 */ + nr_mmx_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_TRANSFORM_0 (px, w, h, rs, spx, sw, sh, srs, FFd2s, alpha); + return; + } +#endif + nr_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_TRANSFORM_0 (px, w, h, rs, spx, sw, sh, srs, FFd2s, alpha); + } else { + int xsize, ysize; + long FFs_x_x_S, FFs_x_y_S, FFs_y_x_S, FFs_y_y_S; + long FF_S[2 * 256]; + int x, y; + + xsize = (1 << xd); + ysize = (1 << yd); + + FFs_x_x_S = FFd2s[0] >> xd; + FFs_x_y_S = FFd2s[1] >> xd; + FFs_y_x_S = FFd2s[2] >> yd; + FFs_y_y_S = FFd2s[3] >> yd; + + /* Set up subpixel matrix */ + /* fixme: We can calculate that in floating point (Lauris) */ + for (y = 0; y < ysize; y++) { + for (x = 0; x < xsize; x++) { + FF_S[2 * (y * xsize + x)] = FFs_x_x_S * x + FFs_y_x_S * y; + FF_S[2 * (y * xsize + x) + 1] = FFs_x_y_S * x + FFs_y_y_S * y; + } + } + +#ifdef WITH_MMX + if (NR_PIXOPS_MMX) { + /* WARNING: MMX composer REQUIRES w > 0 and h > 0 */ + nr_mmx_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_TRANSFORM_n (px, w, h, rs, spx, sw, sh, srs, FFd2s, FF_S, alpha, dbits); + return; + } +#endif + nr_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_TRANSFORM_n (px, w, h, rs, spx, sw, sh, srs, FFd2s, FF_S, alpha, dbits); + } +} + +void nr_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_P_TRANSFORM (unsigned char *px, int w, int h, int rs, + const unsigned char *spx, int sw, int sh, int srs, + const NR::Matrix &d2s, unsigned int alpha, int xd, int yd); diff --git a/src/libnr/nr-compose-transform.h b/src/libnr/nr-compose-transform.h new file mode 100644 index 000000000..7ffb20074 --- /dev/null +++ b/src/libnr/nr-compose-transform.h @@ -0,0 +1,43 @@ +#ifndef __NR_COMPOSE_TRANSFORM_H__ +#define __NR_COMPOSE_TRANSFORM_H__ + +/* + * Pixel buffer rendering library + * + * Authors: + * Lauris Kaplinski + * + * This code is in public domain + */ + +#include + +/* FINAL DST SRC */ + +void nr_R8G8B8A8_N_EMPTY_R8G8B8A8_N_TRANSFORM (unsigned char *px, int w, int h, int rs, + const unsigned char *spx, int sw, int sh, int srs, + const NR::Matrix &d2s, unsigned int alpha, int xd, int yd); +void nr_R8G8B8A8_N_EMPTY_R8G8B8A8_P_TRANSFORM (unsigned char *px, int w, int h, int rs, + const unsigned char *spx, int sw, int sh, int srs, + const NR::Matrix &d2s, unsigned int alpha, int xd, int yd); +void nr_R8G8B8A8_P_EMPTY_R8G8B8A8_N_TRANSFORM (unsigned char *px, int w, int h, int rs, + const unsigned char *spx, int sw, int sh, int srs, + const NR::Matrix &d2s, unsigned int alpha, int xd, int yd); +void nr_R8G8B8A8_P_EMPTY_R8G8B8A8_P_TRANSFORM (unsigned char *px, int w, int h, int rs, + const unsigned char *spx, int sw, int sh, int srs, + const NR::Matrix &d2s, unsigned int alpha, int xd, int yd); + +void nr_R8G8B8A8_N_R8G8B8A8_N_R8G8B8A8_N_TRANSFORM (unsigned char *px, int w, int h, int rs, + const unsigned char *spx, int sw, int sh, int srs, + const NR::Matrix &d2s, unsigned int alpha, int xd, int yd); +void nr_R8G8B8A8_N_R8G8B8A8_N_R8G8B8A8_P_TRANSFORM (unsigned char *px, int w, int h, int rs, + const unsigned char *spx, int sw, int sh, int srs, + const NR::Matrix &d2s, unsigned int alpha, int xd, int yd); +void nr_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_TRANSFORM (unsigned char *px, int w, int h, int rs, + const unsigned char *spx, int sw, int sh, int srs, + const NR::Matrix &d2s, unsigned int alpha, int xd, int yd); +void nr_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_P_TRANSFORM (unsigned char *px, int w, int h, int rs, + const unsigned char *spx, int sw, int sh, int srs, + const NR::Matrix &d2s, unsigned int alpha, int xd, int yd); + +#endif diff --git a/src/libnr/nr-compose.cpp b/src/libnr/nr-compose.cpp new file mode 100644 index 000000000..8eed6e84c --- /dev/null +++ b/src/libnr/nr-compose.cpp @@ -0,0 +1,986 @@ +#define __NR_COMPOSE_C__ + +/* + * Pixel buffer rendering library + * + * Authors: + * Lauris Kaplinski + * + * This code is in public domain + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include "nr-pixops.h" + +#ifdef WITH_MMX +/* fixme: */ +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ +int nr_have_mmx (void); +void nr_mmx_R8G8B8A8_P_EMPTY_A8_RGBAP (unsigned char *px, int w, int h, int rs, const unsigned char *spx, int srs, unsigned char *c); +void nr_mmx_R8G8B8A8_P_R8G8B8A8_P_A8_RGBAP (unsigned char *px, int w, int h, int rs, const unsigned char *spx, int srs, unsigned char *c); +void nr_mmx_R8G8B8_R8G8B8_R8G8B8A8_P (unsigned char *px, int w, int h, int rs, const unsigned char *spx, int srs, unsigned int alpha); +#define NR_PIXOPS_MMX nr_have_mmx () +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif + +void +nr_R8G8B8A8_N_EMPTY_R8G8B8A8_N (unsigned char *px, int w, int h, int rs, const unsigned char *spx, int srs, unsigned int alpha) +{ + int r, c; + + for (r = 0; r < h; r++) { + if (alpha == 0) { + memset (px, 0x0, 4 * w); + } else if (alpha == 255) { + memcpy (px, spx, 4 * w); + } else { + const unsigned char *s; + unsigned char *d; + d = px; + s = spx; + for (c = 0; c < w; c++) { + *d++ = *s++; + *d++ = *s++; + *d++ = *s++; + *d++ = NR_PREMUL (*s, alpha); + s++; + } + } + px += rs; + spx += srs; + } +} + +void +nr_R8G8B8A8_N_EMPTY_R8G8B8A8_P (unsigned char *px, int w, int h, int rs, const unsigned char *spx, int srs, unsigned int alpha) +{ + int r, c; + + for (r = 0; r < h; r++) { + if (alpha == 0) { + memset (px, 0x0, 4 * w); + } else { + const unsigned char *s; + unsigned char *d; + s = spx; + d = px; + for (c = 0; c < w; c++) { + unsigned int a; + a = NR_PREMUL (s[3], alpha); + d[0] = s[0]; + d[1] = s[1]; + d[2] = s[2]; + d[3] = a; + d += 4; + s += 4; + } + px += rs; + spx += srs; + } + } +} + +void +nr_R8G8B8A8_P_EMPTY_R8G8B8A8_N (unsigned char *px, int w, int h, int rs, const unsigned char *spx, int srs, unsigned int alpha) +{ + int r, c; + + for (r = 0; r < h; r++) { + unsigned char *d, *s; + d = (unsigned char *) px; + s = (unsigned char *) spx; + for (c = 0; c < w; c++) { + unsigned int a; + a = (s[3] * alpha + 127) / 255; + d[0] = (s[0] * a + 127) / 255; + d[1] = (s[1] * a + 127) / 255; + d[2] = (s[2] * a + 127) / 255; + d[3] = a; + d += 4; + s += 4; + } + px += rs; + spx += srs; + } +} + +void +nr_R8G8B8A8_P_EMPTY_R8G8B8A8_P (unsigned char *px, int w, int h, int rs, const unsigned char *spx, int srs, unsigned int alpha) +{ + int r, c; + + for (r = 0; r < h; r++) { + unsigned char *d, *s; + d = (unsigned char *) px; + s = (unsigned char *) spx; + for (c = 0; c < w; c++) { + if (alpha == 255) { + d[0] = s[0]; + d[1] = s[1]; + d[2] = s[2]; + d[3] = s[3]; + } else { + d[0] = NR_PREMUL (s[0], alpha); + d[1] = NR_PREMUL (s[1], alpha); + d[2] = NR_PREMUL (s[2], alpha); + d[3] = NR_PREMUL (s[3], alpha); + } + d += 4; + s += 4; + } + px += rs; + spx += srs; + } +} + +void +nr_R8G8B8A8_N_R8G8B8A8_N_R8G8B8A8_N (unsigned char *px, int w, int h, int rs, const unsigned char *spx, int srs, unsigned int alpha) +{ + int r, c; + + for (r = 0; r < h; r++) { + unsigned char *d, *s; + d = (unsigned char *) px; + s = (unsigned char *) spx; + for (c = 0; c < w; c++) { + unsigned int a; + a = NR_PREMUL (s[3], alpha); + if (a == 0) { + /* Transparent FG, NOP */ + } else if ((a == 255) || (d[3] == 0)) { + /* Full coverage, COPY */ + d[0] = s[0]; + d[1] = s[1]; + d[2] = s[2]; + d[3] = a; + } else { + unsigned int ca; + /* Full composition */ + ca = 65025 - (255 - a) * (255 - d[3]); + d[0] = NR_COMPOSENNN_A7 (s[0], a, d[0], d[3], ca); + d[1] = NR_COMPOSENNN_A7 (s[1], a, d[1], d[3], ca); + d[2] = NR_COMPOSENNN_A7 (s[2], a, d[2], d[3], ca); + d[3] = (ca + 127) / 255; + } + d += 4; + s += 4; + } + px += rs; + spx += srs; + } +} + +void +nr_R8G8B8A8_N_R8G8B8A8_N_R8G8B8A8_P (unsigned char *px, int w, int h, int rs, const unsigned char *spx, int srs, unsigned int alpha) +{ + int r, c; + + for (r = 0; r < h; r++) { + unsigned char *d, *s; + d = (unsigned char *) px; + s = (unsigned char *) spx; + for (c = 0; c < w; c++) { + unsigned int a; + a = NR_PREMUL (s[3], alpha); + if (a == 0) { + /* Transparent FG, NOP */ + } else if ((a == 255) || (d[3] == 0)) { + /* Full coverage, demul src */ + d[0] = (s[0] * 255 + (s[3] >> 1)) / s[3]; + d[1] = (s[1] * 255 + (s[3] >> 1)) / s[3]; + d[2] = (s[2] * 255 + (s[3] >> 1)) / s[3]; + d[3] = a; + } else { + if (alpha == 255) { + unsigned int ca; + /* Full composition */ + ca = 65025 - (255 - s[3]) * (255 - d[3]); + d[0] = NR_COMPOSEPNN_A7 (s[0], s[3], d[0], d[3], ca); + d[1] = NR_COMPOSEPNN_A7 (s[1], s[3], d[1], d[3], ca); + d[2] = NR_COMPOSEPNN_A7 (s[2], s[3], d[2], d[3], ca); + d[3] = (65025 - (255 - s[3]) * (255 - d[3]) + 127) / 255; + } else { + // calculate premultiplied from two premultiplieds: + d[0] = NR_COMPOSEPPP(NR_PREMUL (s[0], alpha), a, NR_PREMUL (d[0], d[3]), 0); // last parameter not used + d[1] = NR_COMPOSEPPP(NR_PREMUL (s[1], alpha), a, NR_PREMUL (d[1], d[3]), 0); + d[2] = NR_COMPOSEPPP(NR_PREMUL (s[2], alpha), a, NR_PREMUL (d[2], d[3]), 0); + // total opacity: + d[3] = (65025 - (255 - a) * (255 - d[3]) + 127) / 255; + // un-premultiply channels: + d[0] = d[0]*255/d[3]; + d[1] = d[1]*255/d[3]; + d[2] = d[2]*255/d[3]; + } + } + d += 4; + s += 4; + } + px += rs; + spx += srs; + } +} + +void +nr_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N (unsigned char *px, int w, int h, int rs, const unsigned char *spx, int srs, unsigned int alpha) +{ + int r, c; + + for (r = 0; r < h; r++) { + unsigned char *d, *s; + d = (unsigned char *) px; + s = (unsigned char *) spx; + for (c = 0; c < w; c++) { + unsigned int a; + a = NR_PREMUL (s[3], alpha); + if (a == 0) { + /* Transparent FG, NOP */ + } else if ((a == 255) || (d[3] == 0)) { + /* Transparent BG, premul src */ + d[0] = NR_PREMUL (s[0], a); + d[1] = NR_PREMUL (s[1], a); + d[2] = NR_PREMUL (s[2], a); + d[3] = a; + } else { + d[0] = NR_COMPOSENPP (s[0], a, d[0], d[3]); + d[1] = NR_COMPOSENPP (s[1], a, d[1], d[3]); + d[2] = NR_COMPOSENPP (s[2], a, d[2], d[3]); + d[3] = (65025 - (255 - a) * (255 - d[3]) + 127) / 255; + } + d += 4; + s += 4; + } + px += rs; + spx += srs; + } +} + +void +nr_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_P (unsigned char *px, int w, int h, int rs, const unsigned char *spx, int srs, unsigned int alpha) +{ + int r, c; + + for (r = 0; r < h; r++) { + unsigned char *d, *s; + d = (unsigned char *) px; + s = (unsigned char *) spx; + for (c = 0; c < w; c++) { + unsigned int a; + a = NR_PREMUL (s[3], alpha); + if (a == 0) { + /* Transparent FG, NOP */ + } else if ((a == 255) || (d[3] == 0)) { + /* Transparent BG, COPY */ + d[0] = NR_PREMUL (s[0], alpha); + d[1] = NR_PREMUL (s[1], alpha); + d[2] = NR_PREMUL (s[2], alpha); + d[3] = NR_PREMUL (s[3], alpha); + } else { + if (alpha == 255) { + /* Simple */ + d[0] = NR_COMPOSEPPP (s[0], s[3], d[0], d[3]); + d[1] = NR_COMPOSEPPP (s[1], s[3], d[1], d[3]); + d[2] = NR_COMPOSEPPP (s[2], s[3], d[2], d[3]); + d[3] = (65025 - (255 - s[3]) * (255 - d[3]) + 127) / 255; + } else { + unsigned int c; + c = NR_PREMUL (s[0], alpha); + d[0] = NR_COMPOSEPPP (c, a, d[0], d[3]); + c = NR_PREMUL (s[1], alpha); + d[1] = NR_COMPOSEPPP (c, a, d[1], d[3]); + c = NR_PREMUL (s[2], alpha); + d[2] = NR_COMPOSEPPP (c, a, d[2], d[3]); + d[3] = (65025 - (255 - a) * (255 - d[3]) + 127) / 255; + } + } + d += 4; + s += 4; + } + px += rs; + spx += srs; + } +} + +/* Masked operations */ + +void +nr_R8G8B8A8_N_EMPTY_R8G8B8A8_N_A8 (unsigned char *px, int w, int h, int rs, const unsigned char *spx, int srs, const unsigned char *mpx, int mrs) +{ + int x, y; + + for (y = 0; y < h; y++) { + unsigned char *d, *s, *m; + d = (unsigned char *) px; + s = (unsigned char *) spx; + m = (unsigned char *) mpx; + for (x = 0; x < w; x++) { + d[0] = s[0]; + d[1] = s[1]; + d[2] = s[2]; + d[3] = (s[3] * m[0] + 127) / 255; + d += 4; + s += 4; + m += 1; + } + px += rs; + spx += srs; + mpx += mrs; + } +} + +void +nr_R8G8B8A8_N_EMPTY_R8G8B8A8_P_A8 (unsigned char *px, int w, int h, int rs, const unsigned char *spx, int srs, const unsigned char *mpx, int mrs) +{ + int x, y; + + for (y = 0; y < h; y++) { + unsigned char *d, *s, *m; + d = (unsigned char *) px; + s = (unsigned char *) spx; + m = (unsigned char *) mpx; + for (x = 0; x < w; x++) { + unsigned int a; + a = NR_PREMUL (s[3], m[0]); + if (a == 0) { + d[3] = 0; + } else { + d[0] = (s[0] * 255 + (a >> 1)) / a; + d[1] = (s[1] * 255 + (a >> 1)) / a; + d[2] = (s[2] * 255 + (a >> 1)) / a; + d[3] = a; + } + d += 4; + s += 4; + m += 1; + } + px += rs; + spx += srs; + mpx += mrs; + } +} + +void +nr_R8G8B8A8_P_EMPTY_R8G8B8A8_N_A8 (unsigned char *px, int w, int h, int rs, const unsigned char *spx, int srs, const unsigned char *mpx, int mrs) +{ + int r, c; + + for (r = 0; r < h; r++) { + unsigned char *d, *s, *m; + d = (unsigned char *) px; + s = (unsigned char *) spx; + m = (unsigned char *) mpx; + for (c = 0; c < w; c++) { + unsigned int a; + a = NR_PREMUL (s[3], m[0]); + d[0] = NR_PREMUL (s[0], a); + d[1] = NR_PREMUL (s[1], a); + d[2] = NR_PREMUL (s[2], a); + d[3] = a; + d += 4; + s += 4; + m += 1; + } + px += rs; + spx += srs; + mpx += mrs; + } +} + +void +nr_R8G8B8A8_P_EMPTY_R8G8B8A8_P_A8 (unsigned char *px, int w, int h, int rs, const unsigned char *spx, int srs, const unsigned char *mpx, int mrs) +{ + int r, c; + + for (r = 0; r < h; r++) { + unsigned char *d, *s, *m; + d = (unsigned char *) px; + s = (unsigned char *) spx; + m = (unsigned char *) mpx; + for (c = 0; c < w; c++) { + if (m[0] == 255) { + d[0] = s[0]; + d[1] = s[1]; + d[2] = s[2]; + d[3] = s[3]; + } else { + d[0] = NR_PREMUL (s[0], m[0]); + d[1] = NR_PREMUL (s[1], m[0]); + d[2] = NR_PREMUL (s[2], m[0]); + d[3] = NR_PREMUL (s[3], m[0]); + } + d += 4; + s += 4; + m += 1; + } + px += rs; + spx += srs; + mpx += mrs; + } +} + +void +nr_R8G8B8A8_N_R8G8B8A8_N_R8G8B8A8_N_A8 (unsigned char *px, int w, int h, int rs, const unsigned char *spx, int srs, const unsigned char *mpx, int mrs) +{ + int r, c; + + for (r = 0; r < h; r++) { + unsigned char *d, *s, *m; + d = (unsigned char *) px; + s = (unsigned char *) spx; + m = (unsigned char *) mpx; + for (c = 0; c < w; c++) { + unsigned int a; + a = NR_PREMUL (s[3], m[0]); + if (a == 0) { + /* Transparent FG, NOP */ + } else if ((a == 255) || (d[3] == 0)) { + /* Full coverage, COPY */ + d[0] = s[0]; + d[1] = s[1]; + d[2] = s[2]; + d[3] = a; + } else { + unsigned int ca; + /* Full composition */ + ca = 65025 - (255 - a) * (255 - d[3]); + d[0] = NR_COMPOSENNN_A7 (s[0], a, d[0], d[3], ca); + d[1] = NR_COMPOSENNN_A7 (s[1], a, d[1], d[3], ca); + d[2] = NR_COMPOSENNN_A7 (s[2], a, d[2], d[3], ca); + d[3] = (ca + 127) / 255; + } + d += 4; + s += 4; + m += 1; + } + px += rs; + spx += srs; + mpx += mrs; + } +} + +void +nr_R8G8B8A8_N_R8G8B8A8_N_R8G8B8A8_P_A8 (unsigned char *px, int w, int h, int rs, const unsigned char *spx, int srs, const unsigned char *mpx, int mrs) +{ + int r, c; + + for (r = 0; r < h; r++) { + unsigned char *d, *s, *m; + d = (unsigned char *) px; + s = (unsigned char *) spx; + m = (unsigned char *) mpx; + for (c = 0; c < w; c++) { + unsigned int a; + a = NR_PREMUL (s[3], m[0]); + if (a == 0) { + /* Transparent FG, NOP */ + } else if ((a == 255) || (d[3] == 0)) { + /* Full coverage, demul src */ + d[0] = (s[0] * 255 + (s[3] >> 1)) / s[3]; + d[1] = (s[1] * 255 + (s[3] >> 1)) / s[3]; + d[2] = (s[2] * 255 + (s[3] >> 1)) / s[3]; + d[3] = a; + } else { + if (m[0] == 255) { + unsigned int ca; + /* Full composition */ + ca = 65025 - (255 - s[3]) * (255 - d[3]); + d[0] = NR_COMPOSEPNN_A7 (s[0], s[3], d[0], d[3], ca); + d[1] = NR_COMPOSEPNN_A7 (s[1], s[3], d[1], d[3], ca); + d[2] = NR_COMPOSEPNN_A7 (s[2], s[3], d[2], d[3], ca); + d[3] = (65025 - (255 - s[3]) * (255 - d[3]) + 127) / 255; + } else { + // calculate premultiplied from two premultiplieds: + d[0] = NR_COMPOSEPPP(NR_PREMUL (s[0], m[0]), a, NR_PREMUL (d[0], d[3]), 0); // last parameter not used + d[1] = NR_COMPOSEPPP(NR_PREMUL (s[1], m[0]), a, NR_PREMUL (d[1], d[3]), 0); + d[2] = NR_COMPOSEPPP(NR_PREMUL (s[2], m[0]), a, NR_PREMUL (d[2], d[3]), 0); + // total opacity: + d[3] = (65025 - (255 - a) * (255 - d[3]) + 127) / 255; + // un-premultiply channels: + d[0] = d[0]*255/d[3]; + d[1] = d[1]*255/d[3]; + d[2] = d[2]*255/d[3]; + } + } + d += 4; + s += 4; + m += 1; + } + px += rs; + spx += srs; + mpx += mrs; + } +} + +void +nr_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_A8 (unsigned char *px, int w, int h, int rs, const unsigned char *spx, int srs, const unsigned char *mpx, int mrs) +{ + int r, c; + + for (r = 0; r < h; r++) { + unsigned char *d, *s, *m; + d = (unsigned char *) px; + s = (unsigned char *) spx; + m = (unsigned char *) mpx; + for (c = 0; c < w; c++) { + unsigned int a; + a = NR_PREMUL (s[3], m[0]); + if (a == 0) { + /* Transparent FG, NOP */ + } else if ((a == 255) || (d[3] == 0)) { + /* Transparent BG, premul src */ + d[0] = NR_PREMUL (s[0], a); + d[1] = NR_PREMUL (s[1], a); + d[2] = NR_PREMUL (s[2], a); + d[3] = a; + } else { + d[0] = NR_COMPOSENPP (s[0], a, d[0], d[3]); + d[1] = NR_COMPOSENPP (s[1], a, d[1], d[3]); + d[2] = NR_COMPOSENPP (s[2], a, d[2], d[3]); + d[3] = (65025 - (255 - a) * (255 - d[3]) + 127) / 255; + } + d += 4; + s += 4; + m += 1; + } + px += rs; + spx += srs; + mpx += mrs; + } +} + +void +nr_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_P_A8 (unsigned char *px, int w, int h, int rs, const unsigned char *spx, int srs, const unsigned char *mpx, int mrs) +{ + int r, c; + + for (r = 0; r < h; r++) { + unsigned char *d, *s, *m; + d = (unsigned char *) px; + s = (unsigned char *) spx; + m = (unsigned char *) mpx; + for (c = 0; c < w; c++) { + unsigned int a; + a = NR_PREMUL (s[3], m[0]); + if (a == 0) { + /* Transparent FG, NOP */ + } else if ((a == 255) || (d[3] == 0)) { + /* Transparent BG, COPY */ + d[0] = NR_PREMUL (s[0], m[0]); + d[1] = NR_PREMUL (s[1], m[0]); + d[2] = NR_PREMUL (s[2], m[0]); + d[3] = NR_PREMUL (s[3], m[0]); + } else { + if (m[0] == 255) { + /* Simple */ + d[0] = NR_COMPOSEPPP (s[0], s[3], d[0], d[3]); + d[1] = NR_COMPOSEPPP (s[1], s[3], d[1], d[3]); + d[2] = NR_COMPOSEPPP (s[2], s[3], d[2], d[3]); + d[3] = NR_A7_NORMALIZED(s[3], d[3]); + } else { + unsigned int c; + c = NR_PREMUL (s[0], m[0]); + d[0] = NR_COMPOSEPPP (c, a, d[0], d[3]); + c = NR_PREMUL (s[1], m[0]); + d[1] = NR_COMPOSEPPP (c, a, d[1], d[3]); + c = NR_PREMUL (s[2], m[0]); + d[2] = NR_COMPOSEPPP (c, a, d[2], d[3]); + d[3] = NR_A7_NORMALIZED(a, d[3]); + } + } + d += 4; + s += 4; + m += 1; + } + px += rs; + spx += srs; + mpx += mrs; + } +} + +void +nr_R8G8B8A8_N_EMPTY_A8_RGBA32 (unsigned char *px, int w, int h, int rs, const unsigned char *spx, int srs, unsigned long rgba) +{ + unsigned int r, g, b, a; + int x, y; + + r = NR_RGBA32_R (rgba); + g = NR_RGBA32_G (rgba); + b = NR_RGBA32_B (rgba); + a = NR_RGBA32_A (rgba); + + if (a == 0) return; + + for (y = 0; y < h; y++) { + unsigned char *d, *s; + d = (unsigned char *) px; + s = (unsigned char *) spx; + for (x = 0; x < w; x++) { + d[0] = r; + d[1] = g; + d[2] = b; + d[3] = NR_PREMUL (s[0], a); + d += 4; + s += 1; + } + px += rs; + spx += srs; + } +} + +void +nr_R8G8B8A8_P_EMPTY_A8_RGBA32 (unsigned char *px, int w, int h, int rs, const unsigned char *spx, int srs, unsigned long rgba) +{ + unsigned int r, g, b, a; + int x, y; + + r = NR_RGBA32_R (rgba); + g = NR_RGBA32_G (rgba); + b = NR_RGBA32_B (rgba); + a = NR_RGBA32_A (rgba); + + if (a == 0) return; + +#ifdef WITH_MMX + if (NR_PIXOPS_MMX) { + unsigned char c[4]; + c[0] = NR_PREMUL (r, a); + c[1] = NR_PREMUL (g, a); + c[2] = NR_PREMUL (b, a); + c[3] = a; + /* WARNING: MMX composer REQUIRES w > 0 and h > 0 */ + nr_mmx_R8G8B8A8_P_EMPTY_A8_RGBAP (px, w, h, rs, spx, srs, c); + return; + } +#endif + + for (y = 0; y < h; y++) { + unsigned char *d, *s; + d = (unsigned char *) px; + s = (unsigned char *) spx; + for (x = 0; x < w; x++) { + unsigned int ca; + ca = s[0] * a; + d[0] = (r * ca + 32512) / 65025; + d[1] = (g * ca + 32512) / 65025; + d[2] = (b * ca + 32512) / 65025; + d[3] = (ca + 127) / 255; + d += 4; + s += 1; + } + px += rs; + spx += srs; + } +} + +void +nr_R8G8B8_R8G8B8_A8_RGBA32 (unsigned char *px, int w, int h, int rs, const unsigned char *mpx, int mrs, unsigned long rgba) +{ + unsigned int r, g, b, a; + int x, y; + + r = NR_RGBA32_R (rgba); + g = NR_RGBA32_G (rgba); + b = NR_RGBA32_B (rgba); + a = NR_RGBA32_A (rgba); + + if (a == 0) return; + + for (y = 0; y < h; y++) { + unsigned char *d, *m; + d = (unsigned char *) px; + m = (unsigned char *) mpx; + for (x = 0; x < w; x++) { + unsigned int alpha; + alpha = NR_PREMUL (a, m[0]); + d[0] = NR_COMPOSEN11 (r, alpha, d[0]); + d[1] = NR_COMPOSEN11 (g, alpha, d[1]); + d[2] = NR_COMPOSEN11 (b, alpha, d[2]); + d += 3; + m += 1; + } + px += rs; + mpx += mrs; + } +} + +void +nr_R8G8B8A8_N_R8G8B8A8_N_A8_RGBA32 (unsigned char *px, int w, int h, int rs, const unsigned char *spx, int srs, unsigned long rgba) +{ + unsigned int r, g, b, a; + int x, y; + + r = NR_RGBA32_R (rgba); + g = NR_RGBA32_G (rgba); + b = NR_RGBA32_B (rgba); + a = NR_RGBA32_A (rgba); + + if (a == 0) return; + + for (y = 0; y < h; y++) { + unsigned char *d, *s; + d = (unsigned char *) px; + s = (unsigned char *) spx; + for (x = 0; x < w; x++) { + unsigned int ca; + ca = NR_PREMUL (s[0], a); + if (ca == 0) { + /* Transparent FG, NOP */ + } else if ((ca == 255) || (d[3] == 0)) { + /* Full coverage, COPY */ + d[0] = r; + d[1] = g; + d[2] = b; + d[3] = ca; + } else { + unsigned int da; + /* Full composition */ + da = 65025 - (255 - ca) * (255 - d[3]); + d[0] = NR_COMPOSENNN_A7 (r, ca, d[0], d[3], da); + d[1] = NR_COMPOSENNN_A7 (g, ca, d[1], d[3], da); + d[2] = NR_COMPOSENNN_A7 (b, ca, d[2], d[3], da); + d[3] = (da + 127) / 255; + } + d += 4; + s += 1; + } + px += rs; + spx += srs; + } +} + +void +nr_R8G8B8A8_P_R8G8B8A8_P_A8_RGBA32 (unsigned char *px, int w, int h, int rs, const unsigned char *spx, int srs, unsigned long rgba) +{ + unsigned int r, g, b, a; + int x, y; + + if (!(rgba & 0xff)) return; + + r = NR_RGBA32_R (rgba); + g = NR_RGBA32_G (rgba); + b = NR_RGBA32_B (rgba); + a = NR_RGBA32_A (rgba); + +#ifdef WITH_MMX + if (NR_PIXOPS_MMX) { + unsigned char c[4]; + c[0] = NR_PREMUL (r, a); + c[1] = NR_PREMUL (g, a); + c[2] = NR_PREMUL (b, a); + c[3] = a; + /* WARNING: MMX composer REQUIRES w > 0 and h > 0 */ + nr_mmx_R8G8B8A8_P_R8G8B8A8_P_A8_RGBAP (px, w, h, rs, spx, srs, c); + return; + } +#endif + + for (y = 0; y < h; y++) { + unsigned char *d, *s; + d = (unsigned char *) px; + s = (unsigned char *) spx; + for (x = 0; x < w; x++) { + unsigned int ca; + ca = NR_PREMUL (s[0], a); + if (ca == 0) { + /* Transparent FG, NOP */ + } else if ((ca == 255) || (d[3] == 0)) { + /* Full coverage, COPY */ + d[0] = NR_PREMUL (r, ca); + d[1] = NR_PREMUL (g, ca); + d[2] = NR_PREMUL (b, ca); + d[3] = ca; + } else { + /* Full composition */ + d[0] = NR_COMPOSENPP (r, ca, d[0], d[3]); + d[1] = NR_COMPOSENPP (g, ca, d[1], d[3]); + d[2] = NR_COMPOSENPP (b, ca, d[2], d[3]); + d[3] = (65025 - (255 - ca) * (255 - d[3]) + 127) / 255; + } + d += 4; + s += 1; + } + px += rs; + spx += srs; + } +} + +/* RGB */ + +void +nr_R8G8B8_R8G8B8_R8G8B8A8_P (unsigned char *px, int w, int h, int rs, const unsigned char *spx, int srs, unsigned int alpha) +{ + int r, c; + + if (alpha == 0) return; + +#ifdef WITH_MMX + if (NR_PIXOPS_MMX) { + /* WARNING: MMX composer REQUIRES w > 0 and h > 0 */ + nr_mmx_R8G8B8_R8G8B8_R8G8B8A8_P (px, w, h, rs, spx, srs, alpha); + return; + } +#endif + + for (r = 0; r < h; r++) { + const unsigned char *s; + unsigned char *d; + if (alpha == 255) { + d = px; + s = spx; + for (c = 0; c < w; c++) { + if (s[3] == 0) { + /* NOP */ + } else if (s[3] == 255) { + d[0] = s[0]; + d[1] = s[1]; + d[2] = s[2]; + } else { + d[0] = NR_COMPOSEP11 (s[0], s[3], d[0]); + d[1] = NR_COMPOSEP11 (s[1], s[3], d[1]); + d[2] = NR_COMPOSEP11 (s[2], s[3], d[2]); + } + d += 3; + s += 4; + } + } else { + d = px; + s = spx; + for (c = 0; c < w; c++) { + unsigned int a; + a = NR_PREMUL (s[3], alpha); + if (a == 0) { + /* NOP */ + } else { + d[0] = NR_COMPOSEP11 (s[0], a, d[0]); + d[1] = NR_COMPOSEP11 (s[1], a, d[1]); + d[2] = NR_COMPOSEP11 (s[2], a, d[2]); + } + /* a == 255 is impossible, because alpha < 255 */ + d += 3; + s += 4; + } + } + px += rs; + spx += srs; + } +} + +void +nr_R8G8B8_R8G8B8_R8G8B8A8_N (unsigned char *px, int w, int h, int rs, const unsigned char *spx, int srs, unsigned int alpha) +{ + int r, c; + + for (r = 0; r < h; r++) { + const unsigned char *s; + unsigned char *d; + if (alpha == 0) { + /* NOP */ + } else if (alpha == 255) { + d = px; + s = spx; + for (c = 0; c < w; c++) { + if (s[3] == 0) { + /* NOP */ + } else if (s[3] == 255) { + d[0] = s[0]; + d[1] = s[1]; + d[2] = s[2]; + } else { + d[0] = NR_COMPOSEN11 (s[0], s[3], d[0]); + d[1] = NR_COMPOSEN11 (s[1], s[3], d[1]); + d[2] = NR_COMPOSEN11 (s[2], s[3], d[2]); + } + d += 3; + s += 4; + } + } else { + d = px; + s = spx; + for (c = 0; c < w; c++) { + unsigned int a; + a = NR_PREMUL (s[3], alpha); + if (a == 0) { + /* NOP */ + } else { + d[0] = NR_COMPOSEN11 (s[0], a, d[0]); + d[1] = NR_COMPOSEN11 (s[1], a, d[1]); + d[2] = NR_COMPOSEN11 (s[2], a, d[2]); + } + /* a == 255 is impossible, because alpha < 255 */ + d += 3; + s += 4; + } + } + px += rs; + spx += srs; + } +} + +void +nr_R8G8B8_R8G8B8_R8G8B8A8_P_A8 (unsigned char *px, int w, int h, int rs, const unsigned char *spx, int srs, const unsigned char *mpx, int mrs) +{ + int x, y; + + for (y = 0; y < h; y++) { + unsigned char *d, *s, *m; + d = (unsigned char *) px; + s = (unsigned char *) spx; + m = (unsigned char *) mpx; + for (x = 0; x < w; x++) { + unsigned int a; + a = NR_PREMUL (s[3], m[0]); + if (a != 0) { + unsigned int r, g, b; + r = NR_PREMUL (s[0], m[0]); + d[0] = NR_COMPOSEP11 (r, a, d[0]); + g = NR_PREMUL (s[1], m[0]); + d[1] = NR_COMPOSEP11 (g, a, d[1]); + b = NR_PREMUL (s[2], m[0]); + d[2] = NR_COMPOSEP11 (b, a, d[2]); + } + d += 3; + s += 4; + m += 1; + } + px += rs; + spx += srs; + mpx += mrs; + } +} + +void +nr_R8G8B8_R8G8B8_R8G8B8A8_N_A8 (unsigned char *px, int w, int h, int rs, const unsigned char *spx, int srs, const unsigned char *mpx, int mrs) +{ + int x, y; + + for (y = 0; y < h; y++) { + unsigned char *d, *s, *m; + d = (unsigned char *) px; + s = (unsigned char *) spx; + m = (unsigned char *) mpx; + for (x = 0; x < w; x++) { + unsigned int a; + a = NR_PREMUL (s[3], m[0]); + if (a != 0) { + d[0] = NR_COMPOSEP11 (s[0], a, d[0]); + d[1] = NR_COMPOSEP11 (s[1], a, d[1]); + d[2] = NR_COMPOSEP11 (s[2], a, d[2]); + } + d += 3; + s += 4; + m += 1; + } + px += rs; + spx += srs; + mpx += mrs; + } +} + + diff --git a/src/libnr/nr-compose.h b/src/libnr/nr-compose.h new file mode 100644 index 000000000..ccdb52cb0 --- /dev/null +++ b/src/libnr/nr-compose.h @@ -0,0 +1,69 @@ +#ifndef __NR_COMPOSE_H__ +#define __NR_COMPOSE_H__ + +/* + * Pixel buffer rendering library + * + * Authors: + * Lauris Kaplinski + * + * This code is in public domain + */ + +/* FINAL DST SRC */ + +void nr_R8G8B8A8_N_EMPTY_R8G8B8A8_N (unsigned char *px, int w, int h, int rs, const unsigned char *spx, int srs, unsigned int alpha); +void nr_R8G8B8A8_N_EMPTY_R8G8B8A8_P (unsigned char *px, int w, int h, int rs, const unsigned char *spx, int srs, unsigned int alpha); +void nr_R8G8B8A8_P_EMPTY_R8G8B8A8_N (unsigned char *px, int w, int h, int rs, const unsigned char *spx, int srs, unsigned int alpha); +void nr_R8G8B8A8_P_EMPTY_R8G8B8A8_P (unsigned char *px, int w, int h, int rs, const unsigned char *spx, int srs, unsigned int alpha); + +void nr_R8G8B8A8_N_R8G8B8A8_N_R8G8B8A8_N (unsigned char *px, int w, int h, int rs, const unsigned char *spx, int srs, unsigned int alpha); +void nr_R8G8B8A8_N_R8G8B8A8_N_R8G8B8A8_P (unsigned char *px, int w, int h, int rs, const unsigned char *spx, int srs, unsigned int alpha); +void nr_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N (unsigned char *px, int w, int h, int rs, const unsigned char *spx, int srs, unsigned int alpha); +void nr_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_P (unsigned char *px, int w, int h, int rs, const unsigned char *spx, int srs, unsigned int alpha); + +/* FINAL DST SRC MASK */ + +void nr_R8G8B8A8_N_EMPTY_R8G8B8A8_N_A8 (unsigned char *px, int w, int h, int rs, + const unsigned char *spx, int srs, + const unsigned char *mpx, int mrs); +void nr_R8G8B8A8_N_EMPTY_R8G8B8A8_P_A8 (unsigned char *px, int w, int h, int rs, + const unsigned char *spx, int srs, + const unsigned char *mpx, int mrs); +void nr_R8G8B8A8_P_EMPTY_R8G8B8A8_N_A8 (unsigned char *px, int w, int h, int rs, + const unsigned char *spx, int srs, + const unsigned char *mpx, int mrs); +void nr_R8G8B8A8_P_EMPTY_R8G8B8A8_P_A8 (unsigned char *px, int w, int h, int rs, + const unsigned char *spx, int srs, + const unsigned char *mpx, int mrs); + +void nr_R8G8B8A8_N_R8G8B8A8_N_R8G8B8A8_N_A8 (unsigned char *p, int w, int h, int rs, + const unsigned char *s, int srs, + const unsigned char *m, int mrs); +void nr_R8G8B8A8_N_R8G8B8A8_N_R8G8B8A8_P_A8 (unsigned char *p, int w, int h, int rs, + const unsigned char *s, int srs, + const unsigned char *m, int mrs); +void nr_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_A8 (unsigned char *p, int w, int h, int rs, + const unsigned char *s, int srs, + const unsigned char *m, int mrs); +void nr_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_P_A8 (unsigned char *p, int w, int h, int rs, + const unsigned char *s, int srs, + const unsigned char *m, int mrs); + +/* FINAL DST MASK COLOR */ + +void nr_R8G8B8A8_N_EMPTY_A8_RGBA32 (unsigned char *px, int w, int h, int rs, const unsigned char *mpx, int mrs, unsigned long rgba); +void nr_R8G8B8A8_P_EMPTY_A8_RGBA32 (unsigned char *px, int w, int h, int rs, const unsigned char *mpx, int mrs, unsigned long rgba); + +void nr_R8G8B8_R8G8B8_A8_RGBA32 (unsigned char *px, int w, int h, int rs, const unsigned char *spx, int srs, unsigned long rgba); +void nr_R8G8B8A8_N_R8G8B8A8_N_A8_RGBA32 (unsigned char *px, int w, int h, int rs, const unsigned char *spx, int srs, unsigned long rgba); +void nr_R8G8B8A8_P_R8G8B8A8_P_A8_RGBA32 (unsigned char *px, int w, int h, int rs, const unsigned char *spx, int srs, unsigned long rgba); + +/* RGB */ + +void nr_R8G8B8_R8G8B8_R8G8B8A8_P (unsigned char *px, int w, int h, int rs, const unsigned char *spx, int srs, unsigned int alpha); +void nr_R8G8B8_R8G8B8_R8G8B8A8_N (unsigned char *px, int w, int h, int rs, const unsigned char *spx, int srs, unsigned int alpha); +void nr_R8G8B8_R8G8B8_R8G8B8A8_P_A8 (unsigned char *px, int w, int h, int rs, const unsigned char *spx, int srs, const unsigned char *mpx, int mrs); +void nr_R8G8B8_R8G8B8_R8G8B8A8_N_A8 (unsigned char *px, int w, int h, int rs, const unsigned char *spx, int srs, const unsigned char *mpx, int mrs); + +#endif diff --git a/src/libnr/nr-convex-hull-ops.h b/src/libnr/nr-convex-hull-ops.h new file mode 100644 index 000000000..2e96bf367 --- /dev/null +++ b/src/libnr/nr-convex-hull-ops.h @@ -0,0 +1,29 @@ +#ifndef SEEN_NR_CONVEX_HULL_FNS_H +#define SEEN_NR_CONVEX_HULL_FNS_H + +/* ex:set et ts=4 sw=4: */ + +/* + * A class representing the convex hull of a set of points. + * + * Copyright 2004 MenTaLguY + * + * This code is licensed under the GNU GPL; see COPYING for more information. + */ + +#include +#include + +namespace NR { + +ConvexHull operator*(const Rect &r, const Matrix &m) { + ConvexHull points(r.corner(0)); + for ( unsigned i = 1 ; i < 4 ; i++ ) { + points.add(r.corner(i)); + } + return points; +} + +} /* namespace NR */ + +#endif diff --git a/src/libnr/nr-convex-hull.h b/src/libnr/nr-convex-hull.h new file mode 100644 index 000000000..28cde376d --- /dev/null +++ b/src/libnr/nr-convex-hull.h @@ -0,0 +1,49 @@ +#ifndef SEEN_NR_CONVEX_HULL_H +#define SEEN_NR_CONVEX_HULL_H + +/* ex:set et ts=4 sw=4: */ + +/* + * A class representing the convex hull of a set of points. + * + * Copyright 2004 MenTaLguY + * + * This code is licensed under the GNU GPL; see COPYING for more information. + */ + +#include + +namespace NR { + +class ConvexHull { +public: + explicit ConvexHull(Point const &p) : _bounds(p, p) {} + + Point midpoint() const { + return _bounds.midpoint(); + } + + void add(Point const &p) { + _bounds.expandTo(p); + } + void add(Rect const &p) { + // Note that this is a hack. when convexhull actually works + // you will need to add all four points. + _bounds.expandTo(p.min()); + _bounds.expandTo(p.max()); + } + void add(ConvexHull const &h) { + _bounds.expandTo(h._bounds); + } + + Rect const &bounds() const { + return _bounds; + } + +private: + Rect _bounds; +}; + +} /* namespace NR */ + +#endif diff --git a/src/libnr/nr-coord.h b/src/libnr/nr-coord.h new file mode 100644 index 000000000..668e2b460 --- /dev/null +++ b/src/libnr/nr-coord.h @@ -0,0 +1,29 @@ +#ifndef SEEN_NR_COORD_H +#define SEEN_NR_COORD_H + +namespace NR { + +/** + * A "real" type with sufficient precision for coordinates. + * + * You may safely assume that double (or even float) provides enough precision for storing + * on-canvas points, and hence that double provides enough precision for dot products of + * differences of on-canvas points. + */ +typedef double Coord; + +} /* namespace NR */ + + +#endif /* !SEEN_NR_COORD_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:encoding=utf-8:textwidth=99 : diff --git a/src/libnr/nr-dim2.h b/src/libnr/nr-dim2.h new file mode 100644 index 000000000..d06fd4227 --- /dev/null +++ b/src/libnr/nr-dim2.h @@ -0,0 +1,22 @@ +#ifndef SEEN_NR_DIM2_H +#define SEEN_NR_DIM2_H + +namespace NR { + +enum Dim2 { X=0, Y }; + +} /* namespace NR */ + + +#endif /* !SEEN_NR_DIM2_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:encoding=utf-8:textwidth=99 : diff --git a/src/libnr/nr-forward.h b/src/libnr/nr-forward.h new file mode 100644 index 000000000..cbc4d8eec --- /dev/null +++ b/src/libnr/nr-forward.h @@ -0,0 +1,42 @@ +#ifndef __NR_FORWARD_H__ +#define __NR_FORWARD_H__ + +/* + * Pixel buffer rendering library + * + * Authors: + * Lauris Kaplinski + * + * This code is in public domain + */ + +namespace NR { +class Matrix; +class Point; +class Rect; +class rotate; +class scale; +class translate; +} + +class NArtBpath; +struct NRBPath; +struct NRPixBlock; +struct NRMatrix; +struct NRPoint; +struct NRRect; +struct NRRectL; + + +#endif + +/* + 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:textwidth=99 : diff --git a/src/libnr/nr-gradient.cpp b/src/libnr/nr-gradient.cpp new file mode 100644 index 000000000..fa4f9f91f --- /dev/null +++ b/src/libnr/nr-gradient.cpp @@ -0,0 +1,317 @@ +#define __NR_GRADIENT_C__ + +/* + * Pixel buffer rendering library + * + * Authors: + * Lauris Kaplinski + * + * This code is in public domain + */ + +#include +#include +#include +#include + +#define NRG_MASK (NR_GRADIENT_VECTOR_LENGTH - 1) +#define NRG_2MASK ((long long) ((NR_GRADIENT_VECTOR_LENGTH << 1) - 1)) + +/* Radial */ + +static void nr_rgradient_render_block_symmetric(NRRenderer *r, NRPixBlock *pb, NRPixBlock *m); +static void nr_rgradient_render_block_optimized(NRRenderer *r, NRPixBlock *pb, NRPixBlock *m); +static void nr_rgradient_render_block_end(NRRenderer *r, NRPixBlock *pb, NRPixBlock *m); +static void nr_rgradient_render_generic_symmetric(NRRGradientRenderer *rgr, NRPixBlock *pb); +static void nr_rgradient_render_generic_optimized(NRRGradientRenderer *rgr, NRPixBlock *pb); + +NRRenderer * +nr_rgradient_renderer_setup(NRRGradientRenderer *rgr, + unsigned char const *cv, + unsigned spread, + NRMatrix const *gs2px, + float cx, float cy, + float fx, float fy, + float r) +{ + rgr->vector = cv; + rgr->spread = spread; + + if (r < NR_EPSILON) { + rgr->renderer.render = nr_rgradient_render_block_end; + } else if (NR_DF_TEST_CLOSE(cx, fx, NR_EPSILON) && + NR_DF_TEST_CLOSE(cy, fy, NR_EPSILON)) { + rgr->renderer.render = nr_rgradient_render_block_symmetric; + + nr_matrix_invert(&rgr->px2gs, gs2px); + rgr->px2gs.c[0] *= (NR_GRADIENT_VECTOR_LENGTH / r); + rgr->px2gs.c[1] *= (NR_GRADIENT_VECTOR_LENGTH / r); + rgr->px2gs.c[2] *= (NR_GRADIENT_VECTOR_LENGTH / r); + rgr->px2gs.c[3] *= (NR_GRADIENT_VECTOR_LENGTH / r); + rgr->px2gs.c[4] -= cx; + rgr->px2gs.c[5] -= cy; + rgr->px2gs.c[4] *= (NR_GRADIENT_VECTOR_LENGTH / r); + rgr->px2gs.c[5] *= (NR_GRADIENT_VECTOR_LENGTH / r); + + rgr->cx = 0.0; + rgr->cy = 0.0; + rgr->fx = rgr->cx; + rgr->fy = rgr->cy; + rgr->r = 1.0; + } else { + rgr->renderer.render = nr_rgradient_render_block_optimized; + + NR::Coord const df = hypot(fx - cx, fy - cy); + if (df >= r) { + fx = cx + (fx - cx ) * r / (float) df; + fy = cy + (fy - cy ) * r / (float) df; + } + + NRMatrix n2gs; + n2gs.c[0] = cx - fx; + n2gs.c[1] = cy - fy; + n2gs.c[2] = cy - fy; + n2gs.c[3] = fx - cx; + n2gs.c[4] = fx; + n2gs.c[5] = fy; + + NRMatrix n2px; + nr_matrix_multiply(&n2px, &n2gs, gs2px); + nr_matrix_invert(&rgr->px2gs, &n2px); + + rgr->cx = 1.0; + rgr->cy = 0.0; + rgr->fx = 0.0; + rgr->fy = 0.0; + rgr->r = r / (float) hypot(fx - cx, fy - cy); + rgr->C = 1.0F - rgr->r * rgr->r; + /* INVARIANT: C < 0 */ + rgr->C = MIN(rgr->C, -NR_EPSILON); + } + + return (NRRenderer *) rgr; +} + +static void +nr_rgradient_render_block_symmetric(NRRenderer *r, NRPixBlock *pb, NRPixBlock *m) +{ + NRRGradientRenderer *rgr = (NRRGradientRenderer *) r; + nr_rgradient_render_generic_symmetric(rgr, pb); +} + +static void +nr_rgradient_render_block_optimized(NRRenderer *r, NRPixBlock *pb, NRPixBlock *m) +{ + NRRGradientRenderer *rgr = (NRRGradientRenderer *) r; + nr_rgradient_render_generic_optimized(rgr, pb); +} + +static void +nr_rgradient_render_block_end(NRRenderer *r, NRPixBlock *pb, NRPixBlock *m) +{ + unsigned char const *c = ((NRRGradientRenderer *) r)->vector + 4 * (NR_GRADIENT_VECTOR_LENGTH - 1); + + nr_blit_pixblock_mask_rgba32(pb, m, (c[0] << 24) | (c[1] << 16) | (c[2] << 8) | c[3]); +} + +/* + * The archetype is following + * + * gx gy - pixel coordinates + * Px Py - coordinates, where Fx Fy - gx gy line intersects with circle + * + * (1) (gx - fx) * (Py - fy) = (gy - fy) * (Px - fx) + * (2) (Px - cx) * (Px - cx) + (Py - cy) * (Py - cy) = r * r + * + * (3) Py = (Px - fx) * (gy - fy) / (gx - fx) + fy + * (4) (gy - fy) / (gx - fx) = D + * (5) Py = D * Px - D * fx + fy + * + * (6) D * fx - fy + cy = N + * (7) Px * Px - 2 * Px * cx + cx * cx + (D * Px) * (D * Px) - 2 * (D * Px) * N + N * N = r * r + * (8) (D * D + 1) * (Px * Px) - 2 * (cx + D * N) * Px + cx * cx + N * N = r * r + * + * (9) A = D * D + 1 + * (10) B = -2 * (cx + D * N) + * (11) C = cx * cx + N * N - r * r + * + * (12) Px = (-B +- SQRT(B * B - 4 * A * C)) / 2 * A + */ + +static void +nr_rgradient_render_generic_symmetric(NRRGradientRenderer *rgr, NRPixBlock *pb) +{ + NR::Coord const dx = rgr->px2gs.c[0]; + NR::Coord const dy = rgr->px2gs.c[1]; + + if (pb->mode == NR_PIXBLOCK_MODE_R8G8B8A8P) { + for (int y = pb->area.y0; y < pb->area.y1; y++) { + unsigned char *d = NR_PIXBLOCK_PX(pb) + (y - pb->area.y0) * pb->rs; + NR::Coord gx = rgr->px2gs.c[0] * pb->area.x0 + rgr->px2gs.c[2] * y + rgr->px2gs.c[4]; + NR::Coord gy = rgr->px2gs.c[1] * pb->area.x0 + rgr->px2gs.c[3] * y + rgr->px2gs.c[5]; + for (int x = pb->area.x0; x < pb->area.x1; x++) { + NR::Coord const pos = hypot(gx, gy); + int idx; + if (rgr->spread == NR_GRADIENT_SPREAD_REFLECT) { + idx = (int) ((long long) pos & NRG_2MASK); + if (idx > NRG_MASK) idx = NRG_2MASK - idx; + } else if (rgr->spread == NR_GRADIENT_SPREAD_REPEAT) { + idx = (int) ((long long) pos & NRG_MASK); + } else { + idx = (int) CLAMP(pos, 0, (double) NRG_MASK); + } + unsigned char const *s = rgr->vector + 4 * idx; + d[0] = NR_COMPOSENPP(s[0], s[3], d[0], d[3]); + d[1] = NR_COMPOSENPP(s[1], s[3], d[1], d[3]); + d[2] = NR_COMPOSENPP(s[2], s[3], d[2], d[3]); + d[3] = (255*255 - (255 - s[3]) * (255 - d[3]) + 127) / 255; + d += 4; + gx += dx; + gy += dy; + } + } + } else if (pb->mode == NR_PIXBLOCK_MODE_R8G8B8A8N) { + for (int y = pb->area.y0; y < pb->area.y1; y++) { + unsigned char *d = NR_PIXBLOCK_PX(pb) + (y - pb->area.y0) * pb->rs; + NR::Coord gx = rgr->px2gs.c[0] * pb->area.x0 + rgr->px2gs.c[2] * y + rgr->px2gs.c[4]; + NR::Coord gy = rgr->px2gs.c[1] * pb->area.x0 + rgr->px2gs.c[3] * y + rgr->px2gs.c[5]; + for (int x = pb->area.x0; x < pb->area.x1; x++) { + NR::Coord const pos = hypot(gx, gy); + int idx; + if (rgr->spread == NR_GRADIENT_SPREAD_REFLECT) { + idx = (int) ((long long) pos & NRG_2MASK); + if (idx > NRG_MASK) idx = NRG_2MASK - idx; + } else if (rgr->spread == NR_GRADIENT_SPREAD_REPEAT) { + idx = (int) ((long long) pos & NRG_MASK); + } else { + idx = (int) CLAMP(pos, 0, (double) NRG_MASK); + } + unsigned char const *s = rgr->vector + 4 * idx; + if (s[3] == 255) { + d[0] = s[0]; + d[1] = s[1]; + d[2] = s[2]; + d[3] = 255; + } else if (s[3] != 0) { + unsigned ca = 255*255 - (255 - s[3]) * (255 - d[3]); + d[0] = NR_COMPOSENNN_A7(s[0], s[3], d[0], d[3], ca); + d[1] = NR_COMPOSENNN_A7(s[1], s[3], d[1], d[3], ca); + d[2] = NR_COMPOSENNN_A7(s[2], s[3], d[2], d[3], ca); + d[3] = (ca + 127) / 255; + } + d += 4; + gx += dx; + gy += dy; + } + } + } else { + NRPixBlock spb; + nr_pixblock_setup_extern(&spb, NR_PIXBLOCK_MODE_R8G8B8A8N, 0, 0, NR_GRADIENT_VECTOR_LENGTH, 1, + (unsigned char *) rgr->vector, + 4 * NR_GRADIENT_VECTOR_LENGTH, + 0, 0); + int const bpp = ( pb->mode == NR_PIXBLOCK_MODE_A8 + ? 1 + : pb->mode == NR_PIXBLOCK_MODE_R8G8B8 + ? 3 + : 4 ); + + for (int y = pb->area.y0; y < pb->area.y1; y++) { + unsigned char *d = NR_PIXBLOCK_PX(pb) + (y - pb->area.y0) * pb->rs; + NR::Coord gx = rgr->px2gs.c[0] * pb->area.x0 + rgr->px2gs.c[2] * y + rgr->px2gs.c[4]; + NR::Coord gy = rgr->px2gs.c[1] * pb->area.x0 + rgr->px2gs.c[3] * y + rgr->px2gs.c[5]; + for (int x = pb->area.x0; x < pb->area.x1; x++) { + NR::Coord const pos = hypot(gx, gy); + int idx; + if (rgr->spread == NR_GRADIENT_SPREAD_REFLECT) { + idx = (int) ((long long) pos & NRG_2MASK); + if (idx > NRG_MASK) idx = NRG_2MASK - idx; + } else if (rgr->spread == NR_GRADIENT_SPREAD_REPEAT) { + idx = (int) ((long long) pos & NRG_MASK); + } else { + idx = (int) CLAMP(pos, 0, (double) NRG_MASK); + } + unsigned char const *s = rgr->vector + 4 * idx; + nr_compose_pixblock_pixblock_pixel(pb, d, &spb, s); + d += bpp; + gx += dx; + gy += dy; + } + } + + nr_pixblock_release(&spb); + } +} + +static void +nr_rgradient_render_generic_optimized(NRRGradientRenderer *rgr, NRPixBlock *pb) +{ + int const x0 = pb->area.x0; + int const y0 = pb->area.y0; + int const x1 = pb->area.x1; + int const y1 = pb->area.y1; + int const rs = pb->rs; + + NRPixBlock spb; + nr_pixblock_setup_extern(&spb, NR_PIXBLOCK_MODE_R8G8B8A8N, 0, 0, NR_GRADIENT_VECTOR_LENGTH, 1, + (unsigned char *) rgr->vector, + 4 * NR_GRADIENT_VECTOR_LENGTH, + 0, 0); + int const bpp = ( pb->mode == NR_PIXBLOCK_MODE_A8 + ? 1 + : pb->mode == NR_PIXBLOCK_MODE_R8G8B8 + ? 3 + : 4 ); + + for (int y = y0; y < y1; y++) { + unsigned char *d = NR_PIXBLOCK_PX(pb) + (y - y0) * rs; + NR::Coord gx = rgr->px2gs.c[0] * x0 + rgr->px2gs.c[2] * y + rgr->px2gs.c[4]; + NR::Coord gy = rgr->px2gs.c[1] * x0 + rgr->px2gs.c[3] * y + rgr->px2gs.c[5]; + NR::Coord const dx = rgr->px2gs.c[0]; + NR::Coord const dy = rgr->px2gs.c[1]; + for (int x = x0; x < x1; x++) { + NR::Coord const gx2 = gx * gx; + NR::Coord const gxy2 = gx2 + gy * gy; + NR::Coord const qgx2_4 = gx2 - rgr->C * gxy2; + /* INVARIANT: qgx2_4 >= 0.0 */ + /* qgx2_4 = MAX(qgx2_4, 0.0); */ + NR::Coord const pxgx = gx + sqrt(qgx2_4); + /* We can safely divide by 0 here */ + /* If we are sure pxgx cannot be -0 */ + NR::Coord const pos = gxy2 / pxgx * NR_GRADIENT_VECTOR_LENGTH; + int idx; + if (pos < (1U << 31)) { + if (rgr->spread == NR_GRADIENT_SPREAD_REFLECT) { + idx = (int) ((long long) pos & NRG_2MASK); + if (idx > NRG_MASK) idx = NRG_2MASK - idx; + } else if (rgr->spread == NR_GRADIENT_SPREAD_REPEAT) { + idx = (int) ((long long) pos & NRG_MASK); + } else { + idx = (int) CLAMP(pos, 0, (double) (NR_GRADIENT_VECTOR_LENGTH - 1)); + } + } else { + idx = NR_GRADIENT_VECTOR_LENGTH - 1; + } + unsigned char const *s = rgr->vector + 4 * idx; + nr_compose_pixblock_pixblock_pixel(pb, d, &spb, s); + d += bpp; + + gx += dx; + gy += dy; + } + } + + nr_pixblock_release(&spb); +} + + +/* + 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:textwidth=99 : diff --git a/src/libnr/nr-gradient.h b/src/libnr/nr-gradient.h new file mode 100644 index 000000000..f9cb1ba45 --- /dev/null +++ b/src/libnr/nr-gradient.h @@ -0,0 +1,47 @@ +#ifndef __NR_GRADIENT_H__ +#define __NR_GRADIENT_H__ + +/* + * Pixel buffer rendering library + * + * Authors: + * Lauris Kaplinski + * + * This code is in public domain + */ + +#include +#include + +#define NR_GRADIENT_VECTOR_LENGTH 1024 + +enum { + NR_GRADIENT_SPREAD_PAD, + NR_GRADIENT_SPREAD_REFLECT, + NR_GRADIENT_SPREAD_REPEAT +}; + +/* Radial */ + +struct NRRGradientRenderer { + NRRenderer renderer; + const unsigned char *vector; + unsigned int spread; + NRMatrix px2gs; + float cx, cy; + float fx, fy; + float r; + float C; +}; + +NRRenderer *nr_rgradient_renderer_setup (NRRGradientRenderer *rgr, + const unsigned char *cv, + unsigned int spread, + const NRMatrix *gs2px, + float cx, float cy, + float fx, float fy, + float r); + + + +#endif diff --git a/src/libnr/nr-i-coord.h b/src/libnr/nr-i-coord.h new file mode 100644 index 000000000..f87dea3d5 --- /dev/null +++ b/src/libnr/nr-i-coord.h @@ -0,0 +1,25 @@ +#ifndef SEEN_NR_I_COORD_H +#define SEEN_NR_I_COORD_H + +#include + +namespace NR { + +/** An integer type with sufficient precision for coordinates. */ +typedef gint32 ICoord; + +} /* namespace NR */ + + +#endif /* !SEEN_NR_I_COORD_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:encoding=utf-8:textwidth=99 : diff --git a/src/libnr/nr-macros.h b/src/libnr/nr-macros.h new file mode 100644 index 000000000..74a627ae7 --- /dev/null +++ b/src/libnr/nr-macros.h @@ -0,0 +1,71 @@ +#ifndef __NR_MACROS_H__ +#define __NR_MACROS_H__ + +/* + * Pixel buffer rendering library + * + * Authors: + * Lauris Kaplinski + * + * This code is in public domain + */ + +#include + +#if HAVE_STDLIB_H +#include +#endif +#include + +#define nr_new(t,n) ((t *) malloc ((n) * sizeof (t))) +#define nr_free free +#define nr_renew(p,t,n) ((t *) realloc (p, (n) * sizeof (t))) + +#ifndef TRUE +#define TRUE (!0) +#endif +#ifndef FALSE +#define FALSE 0 +#endif +#ifndef MAX +#define MAX(a,b) (((a) < (b)) ? (b) : (a)) +#endif +#ifndef MIN +#define MIN(a,b) (((a) > (b)) ? (b) : (a)) +#endif + +#ifndef CLAMP +/** Returns v bounded to within [a, b]. If v is NaN then returns a. + * + * \pre \a a \<= \a b. + */ +# define CLAMP(v,a,b) \ + (assert (a <= b), \ + ((v) >= (a)) \ + ? (((v) > (b)) \ + ? (b) \ + : (v)) \ + : (a)) +#endif + +#define NR_DF_TEST_CLOSE(a,b,e) (fabs ((a) - (b)) <= (e)) + +// Todo: move these into nr-matrix.h +#define NR_MATRIX_DF_TEST_TRANSFORM_CLOSE(a,b,e) (NR_DF_TEST_CLOSE ((*(a))[0], (*(b))[0], e) && \ + NR_DF_TEST_CLOSE ((*(a))[1], (*(b))[1], e) && \ + NR_DF_TEST_CLOSE ((*(a))[2], (*(b))[2], e) && \ + NR_DF_TEST_CLOSE ((*(a))[3], (*(b))[3], e)) +#define NR_MATRIX_DF_TEST_TRANSLATE_CLOSE(a,b,e) (NR_DF_TEST_CLOSE ((*(a))[4], (*(b))[4], e) && \ + NR_DF_TEST_CLOSE ((*(a))[5], (*(b))[5], e)) +#define NR_MATRIX_DF_TEST_CLOSE(a,b,e) (NR_MATRIX_DF_TEST_TRANSLATE_CLOSE (a, b, e) && \ + NR_MATRIX_DF_TEST_TRANSFORM_CLOSE (a, b, e)) + +#define NR_RECT_DFLS_TEST_EMPTY(a) (((a)->x0 >= (a)->x1) || ((a)->y0 >= (a)->y1)) +#define NR_RECT_DFLS_TEST_INTERSECT(a,b) (((a)->x0 < (b)->x1) && ((a)->x1 > (b)->x0) && ((a)->y0 < (b)->y1) && ((a)->y1 > (b)->y0)) +#define NR_RECT_DF_POINT_DF_TEST_INSIDE(r,p) (((p)->x >= (r)->x0) && ((p)->x < (r)->x1) && ((p)->y >= (r)->y0) && ((p)->y < (r)->y1)) +#define NR_RECT_LS_POINT_LS_TEST_INSIDE(r,p) (((p)->x >= (r)->x0) && ((p)->x < (r)->x1) && ((p)->y >= (r)->y0) && ((p)->y < (r)->y1)) + +#define NR_MATRIX_D_TO_DOUBLE(m) ((m)->c) +#define NR_MATRIX_D_FROM_DOUBLE(d) ((NRMatrix *) &(d)[0]) + +#endif diff --git a/src/libnr/nr-matrix-div.cpp b/src/libnr/nr-matrix-div.cpp new file mode 100644 index 000000000..d6fb598b8 --- /dev/null +++ b/src/libnr/nr-matrix-div.cpp @@ -0,0 +1,22 @@ +#include "libnr/nr-matrix-ops.h" +#include "libnr/nr-point-matrix-ops.h" + +NR::Point operator/(NR::Point const &p, NR::Matrix const &m) { + return p * m.inverse(); +} + +NR::Matrix operator/(NR::Matrix const &a, NR::Matrix const &b) { + return a * b.inverse(); +} + + +/* + 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 : diff --git a/src/libnr/nr-matrix-div.h b/src/libnr/nr-matrix-div.h new file mode 100644 index 000000000..8669e2ce2 --- /dev/null +++ b/src/libnr/nr-matrix-div.h @@ -0,0 +1,21 @@ +#ifndef SEEN_LIBNR_NR_MATRIX_DIV_H +#define SEEN_LIBNR_NR_MATRIX_DIV_H + +#include "libnr/nr-forward.h" + +NR::Point operator/(NR::Point const &, NR::Matrix const &); + +NR::Matrix operator/(NR::Matrix const &, NR::Matrix const &); + +#endif /* !SEEN_LIBNR_NR_MATRIX_DIV_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 : diff --git a/src/libnr/nr-matrix-fns.cpp b/src/libnr/nr-matrix-fns.cpp new file mode 100644 index 000000000..f392f3213 --- /dev/null +++ b/src/libnr/nr-matrix-fns.cpp @@ -0,0 +1,54 @@ +#include + +namespace NR { + +Matrix elliptic_quadratic_form(Matrix const &m) { + double const od = m[0] * m[1] + m[2] * m[3]; + return Matrix((m[0]*m[0] + m[1]*m[1]), od, + od, (m[2]*m[2] + m[3]*m[3]), + 0, 0); +/* def quadratic_form((a, b), (c, d)): + return ((a*a + c*c), a*c+b*d),(a*c+b*d, (b*b + d*d)) */ +} + +Eigen::Eigen(Matrix const &m) { + double const B = -m[0] - m[3]; + double const C = m[0]*m[3] - m[1]*m[2]; + double const center = -B/2.0; + double const delta = sqrt(B*B-4*C)/2.0; + values = Point(center + delta, center - delta); + for (int i = 0; i < 2; i++) { + vectors[i] = unit_vector(rot90(Point(m[0]-values[i], m[1]))); + } +} + +/** Returns just the scale/rotate/skew part of the matrix without the translation part. */ +Matrix transform(Matrix const &m) { + Matrix const ret(m[0], m[1], + m[2], m[3], + 0, 0); + return ret; +} + +translate get_translation(Matrix const &m) { + return translate(m[4], m[5]); +} + +void matrix_print(const gchar *say, Matrix const &m) +{ + printf ("%s %g %g %g %g %g %g\n", say, m[0], m[1], m[2], m[3], m[4], m[5]); +} + +} // namespace NR + + +/* + 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 : diff --git a/src/libnr/nr-matrix-fns.h b/src/libnr/nr-matrix-fns.h new file mode 100644 index 000000000..208366746 --- /dev/null +++ b/src/libnr/nr-matrix-fns.h @@ -0,0 +1,50 @@ +#ifndef SEEN_NR_MATRIX_FNS_H +#define SEEN_NR_MATRIX_FNS_H + +#include "nr-matrix.h" + +namespace NR { + +/** Given a matrix m such that unit_circle = m*x, this returns the + * quadratic form x*A*x = 1. */ +Matrix elliptic_quadratic_form(Matrix const &m); + +/** Given a matrix (ignoring the translation) this returns the eigen + * values and vectors. */ +class Eigen{ +public: + Point vectors[2]; + Point values; + Eigen(Matrix const &m); +}; + +// Matrix factories +Matrix from_basis(const Point x_basis, const Point y_basis, const Point offset=Point(0,0)); + +Matrix identity(); + +double expansion(Matrix const &m); + +bool transform_equalp(Matrix const &m0, Matrix const &m1, NR::Coord const epsilon); +bool translate_equalp(Matrix const &m0, Matrix const &m1, NR::Coord const epsilon); +bool matrix_equalp(Matrix const &m0, Matrix const &m1, NR::Coord const epsilon); + +Matrix transform(Matrix const &m); +translate get_translation(Matrix const &m); + +void matrix_print(const gchar *say, Matrix const &m); + +} // namespace NR + +#endif /* !SEEN_NR_MATRIX_FNS_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 : diff --git a/src/libnr/nr-matrix-ops.h b/src/libnr/nr-matrix-ops.h new file mode 100644 index 000000000..02fb28d0c --- /dev/null +++ b/src/libnr/nr-matrix-ops.h @@ -0,0 +1,45 @@ +/* operator functions for NR::Matrix. */ +#ifndef SEEN_NR_MATRIX_OPS_H +#define SEEN_NR_MATRIX_OPS_H + +#include + +namespace NR { + +inline bool operator==(Matrix const &a, Matrix const &b) +{ + for(unsigned i = 0; i < 6; ++i) { + if ( a[i] != b[i] ) { + return false; + } + } + return true; +} + +inline bool operator!=(Matrix const &a, Matrix const &b) +{ + return !( a == b ); +} + +Matrix operator*(Matrix const &a, Matrix const &b); + +inline Matrix operator*(Matrix const &a, NRMatrix const &b) +{ + return a * NR::Matrix(b); +} + +} /* namespace NR */ + + +#endif /* !SEEN_NR_MATRIX_OPS_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:encoding=utf-8:textwidth=99 : diff --git a/src/libnr/nr-matrix-rotate-ops.cpp b/src/libnr/nr-matrix-rotate-ops.cpp new file mode 100644 index 000000000..625291575 --- /dev/null +++ b/src/libnr/nr-matrix-rotate-ops.cpp @@ -0,0 +1,18 @@ +#include "libnr/nr-matrix-ops.h" + +NR::Matrix operator*(NR::Matrix const &m, NR::rotate const &r) +{ + return m * NR::Matrix(r); +} + + +/* + 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:textwidth=99 : diff --git a/src/libnr/nr-matrix-rotate-ops.h b/src/libnr/nr-matrix-rotate-ops.h new file mode 100644 index 000000000..44d9c8726 --- /dev/null +++ b/src/libnr/nr-matrix-rotate-ops.h @@ -0,0 +1,20 @@ +#ifndef SEEN_LIBNR_NR_MATRIX_ROTATE_OPS_H +#define SEEN_LIBNR_NR_MATRIX_ROTATE_OPS_H + +#include "libnr/nr-forward.h" + +NR::Matrix operator*(NR::Matrix const &m, NR::rotate const &r); + + +#endif /* !SEEN_LIBNR_NR_MATRIX_ROTATE_OPS_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:encoding=utf-8:textwidth=99 : diff --git a/src/libnr/nr-matrix-scale-ops.cpp b/src/libnr/nr-matrix-scale-ops.cpp new file mode 100644 index 000000000..90cbaf585 --- /dev/null +++ b/src/libnr/nr-matrix-scale-ops.cpp @@ -0,0 +1,37 @@ +#include "libnr/nr-matrix-ops.h" + +NR::Matrix +operator/(NR::Matrix const &m, NR::scale const &s) +{ + using NR::X; using NR::Y; + NR::Matrix ret(m); + ret[0] /= s[X]; ret[1] /= s[Y]; + ret[2] /= s[X]; ret[3] /= s[Y]; + ret[4] /= s[X]; ret[5] /= s[Y]; + assert_close( ret, m * NR::Matrix(s.inverse()) ); + return ret; +} + +NR::Matrix +operator*(NR::Matrix const &m, NR::scale const &s) +{ + using NR::X; using NR::Y; + NR::Matrix ret(m); + ret[0] *= s[X]; ret[1] *= s[Y]; + ret[2] *= s[X]; ret[3] *= s[Y]; + ret[4] *= s[X]; ret[5] *= s[Y]; + assert_close( ret, m * NR::Matrix(s) ); + return ret; +} + + +/* + 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:textwidth=99 : diff --git a/src/libnr/nr-matrix-scale-ops.h b/src/libnr/nr-matrix-scale-ops.h new file mode 100644 index 000000000..dee275182 --- /dev/null +++ b/src/libnr/nr-matrix-scale-ops.h @@ -0,0 +1,14 @@ +#ifndef SEEN_LIBNR_NR_MATRIX_SCALE_OPS_H +#define SEEN_LIBNR_NR_MATRIX_SCALE_OPS_H +/** \file + * Declarations (and definition if inline) of operator blah (NR::Matrix, NR::scale). + */ + +#include "libnr/nr-forward.h" + +NR::Matrix operator/(NR::Matrix const &m, NR::scale const &s); + +NR::Matrix operator*(NR::Matrix const &m, NR::scale const &s); + + +#endif /* !SEEN_LIBNR_NR_MATRIX_SCALE_OPS_H */ diff --git a/src/libnr/nr-matrix-test.cpp b/src/libnr/nr-matrix-test.cpp new file mode 100644 index 000000000..b7f064e48 --- /dev/null +++ b/src/libnr/nr-matrix-test.cpp @@ -0,0 +1,197 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +using NR::Matrix; +using NR::X; +using NR::Y; + +inline bool point_equalp(NR::Point const &a, NR::Point const &b) +{ + return ( NR_DF_TEST_CLOSE(a[X], b[X], 1e-5) && + NR_DF_TEST_CLOSE(a[Y], b[Y], 1e-5) ); +} + +int main(int argc, char *argv[]) +{ + int rc = EXIT_SUCCESS; + + Matrix const m_id(NR::identity()); + NR::rotate const r_id(NR::Point(1, 0)); + NR::translate const t_id(0, 0); + + utest_start("Matrix"); + + Matrix const c16(1.0, 2.0, + 3.0, 4.0, + 5.0, 6.0); + UTEST_TEST("basic constructors, operator=") { + Matrix const c16_copy(c16); + Matrix c16_eq(m_id); + c16_eq = c16; + for(unsigned i = 0; i < 6; ++i) { + UTEST_ASSERT( c16[i] == 1.0 + i ); + UTEST_ASSERT( c16[i] == c16_copy[i] ); + UTEST_ASSERT( c16[i] == c16_eq[i] ); + UTEST_ASSERT( m_id[i] == double( i == 0 || i == 3 ) ); + } + } + + UTEST_TEST("scale constructor") { + NR::scale const s(2.0, 3.0); + NR::Matrix const ms(s); + NR::Point const p(5.0, 7.0); + UTEST_ASSERT( p * s == NR::Point(10.0, 21.0) ); + UTEST_ASSERT( p * ms == NR::Point(10.0, 21.0) ); + } + + NR::rotate const r86(NR::Point(.8, .6)); + NR::Matrix const mr86(r86); + UTEST_TEST("rotate constructor") { + NR::Point const p0(1.0, 0.0); + NR::Point const p90(0.0, 1.0); + UTEST_ASSERT( p0 * r86 == NR::Point(.8, .6) ); + UTEST_ASSERT( p0 * mr86 == NR::Point(.8, .6) ); + UTEST_ASSERT( p90 * r86 == NR::Point(-.6, .8) ); + UTEST_ASSERT( p90 * mr86 == NR::Point(-.6, .8) ); + UTEST_ASSERT(matrix_equalp(Matrix( r86 * r86 ), + mr86 * mr86, + 1e-14)); + } + + NR::translate const t23(2.0, 3.0); + UTEST_TEST("translate constructor") { + NR::Matrix const mt23(t23); + NR::Point const b(-2.0, 3.0); + UTEST_ASSERT( b * t23 == b * mt23 ); + } + + NR::scale const s_id(1.0, 1.0); + UTEST_TEST("test_identity") { + UTEST_ASSERT(m_id.test_identity()); + UTEST_ASSERT(Matrix(t_id).test_identity()); + UTEST_ASSERT(!(Matrix(NR::translate(-2, 3)).test_identity())); + UTEST_ASSERT(Matrix(r_id).test_identity()); + NR::rotate const rot180(NR::Point(-1, 0)); + UTEST_ASSERT(!(Matrix(rot180).test_identity())); + UTEST_ASSERT(Matrix(s_id).test_identity()); + UTEST_ASSERT(!(Matrix(NR::scale(1.0, 0.0)).test_identity())); + UTEST_ASSERT(!(Matrix(NR::scale(0.0, 1.0)).test_identity())); + UTEST_ASSERT(!(Matrix(NR::scale(1.0, -1.0)).test_identity())); + UTEST_ASSERT(!(Matrix(NR::scale(-1.0, -1.0)).test_identity())); + } + + UTEST_TEST("inverse") { + UTEST_ASSERT( m_id.inverse() == m_id ); + UTEST_ASSERT( Matrix(t23).inverse() == Matrix(NR::translate(-2.0, -3.0)) ); + NR::scale const s2(-4.0, 2.0); + NR::scale const sp5(-.25, .5); + UTEST_ASSERT( Matrix(s2).inverse() == Matrix(sp5) ); + } + + UTEST_TEST("nr_matrix_invert") { + NRMatrix const nr_m_id(m_id); + Matrix const m_s2(NR::scale(-4.0, 2.0)); + NRMatrix const nr_s2(m_s2); + Matrix const m_sp5(NR::scale(-.25, .5)); + NRMatrix const nr_sp5(m_sp5); + Matrix const m_t23(t23); + NRMatrix const nr_t23(m_t23); + NRMatrix inv; + nr_matrix_invert(&inv, &nr_m_id); + UTEST_ASSERT( Matrix(inv) == m_id ); + nr_matrix_invert(&inv, &nr_t23); + UTEST_ASSERT( Matrix(inv) == Matrix(NR::translate(-2.0, -3.0)) ); + nr_matrix_invert(&inv, &nr_s2); + UTEST_ASSERT( Matrix(inv) == Matrix(nr_sp5) ); + nr_matrix_invert(&inv, &nr_sp5); + UTEST_ASSERT( Matrix(inv) == Matrix(nr_s2) ); + + /* Test that nr_matrix_invert handles src == dest. */ + inv = nr_s2; + nr_matrix_invert(&inv, &inv); + UTEST_ASSERT( Matrix(inv) == Matrix(nr_sp5) ); + inv = nr_t23; + nr_matrix_invert(&inv, &inv); + UTEST_ASSERT( Matrix(inv) == Matrix(NR::translate(-2.0, -3.0)) ); + } + + UTEST_TEST("elliptic quadratic form") { + NR::Matrix const aff(1.0, 1.0, + 0.0, 1.0, + 5.0, 6.0); + NR::Matrix const invaff = aff.inverse(); + UTEST_ASSERT( invaff[1] == -1.0 ); + + NR::Matrix const ef(elliptic_quadratic_form(invaff)); + NR::Matrix const exp_ef(2, -1, + -1, 1, + 0, 0); + UTEST_ASSERT( ef == exp_ef ); + } + + UTEST_TEST("Matrix * rotate") { + NR::Matrix const ma(2.0, -1.0, + 4.0, 4.0, + -0.5, 2.0); + NR::Matrix const a_r86( ma * r86 ); + NR::Matrix const ma1( a_r86 * r86.inverse() ); + UTEST_ASSERT(matrix_equalp(ma1, ma, 1e-12)); + NR::Matrix const exp_a_r86( 2*.8 + -1*-.6, 2*.6 + -1*.8, + 4*.8 + 4*-.6, 4*.6 + 4*.8, + -.5*.8 + 2*-.6, -.5*.6 + 2*.8 ); + UTEST_ASSERT(matrix_equalp(a_r86, exp_a_r86, 1e-12)); + } + + UTEST_TEST("translate*scale, scale*translate") { + NR::translate const t2n4(2, -4); + NR::scale const sn2_8(-2, 8); + NR::Matrix const exp_ts(-2, 0, + 0, 8, + -4, -32); + NR::Matrix const exp_st(-2, 0, + 0, 8, + 2, -4); + UTEST_ASSERT( exp_ts == t2n4 * sn2_8 ); + UTEST_ASSERT( exp_st == sn2_8 * t2n4 ); + } + + UTEST_TEST("Matrix * scale") { + NR::Matrix const ma(2.0, -1.0, + 4.0, 4.0, + -0.5, 2.0); + NR::scale const sn2_8(-2, 8); + NR::Matrix const exp_as(-4, -8, + -8, 32, + 1, 16); + UTEST_ASSERT( ma * sn2_8 == exp_as ); + } + + if (!utest_end()) { + rc = EXIT_FAILURE; + } + + return rc; +} + + +/* + 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:textwidth=99 : diff --git a/src/libnr/nr-matrix-test.h b/src/libnr/nr-matrix-test.h new file mode 100644 index 000000000..476852890 --- /dev/null +++ b/src/libnr/nr-matrix-test.h @@ -0,0 +1,221 @@ +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +using NR::Matrix; +using NR::X; +using NR::Y; + +inline bool point_equalp(NR::Point const &a, NR::Point const &b) +{ + return ( NR_DF_TEST_CLOSE(a[X], b[X], 1e-5) && + NR_DF_TEST_CLOSE(a[Y], b[Y], 1e-5) ); +} + +class NrMatrixTest : public CxxTest::TestSuite +{ +public: + + NrMatrixTest() : + m_id( NR::identity() ), + r_id( NR::Point(1, 0) ), + t_id( 0, 0 ), + c16( 1.0, 2.0, + 3.0, 4.0, + 5.0, 6.0), + r86( NR::Point(.8, .6) ), + mr86( r86 ), + t23( 2.0, 3.0 ), + s_id( 1.0, 1.0 ) + { + } + virtual ~NrMatrixTest() {} + +// createSuite and destroySuite get us per-suite setup and teardown +// without us having to worry about static initialization order, etc. + static NrMatrixTest *createSuite() { return new NrMatrixTest(); } + static void destroySuite( NrMatrixTest *suite ) { delete suite; } + + Matrix const m_id; + NR::rotate const r_id; + NR::translate const t_id; + Matrix const c16; + NR::rotate const r86; + NR::Matrix const mr86; + NR::translate const t23; + NR::scale const s_id; + + + + + void testCtorsAssignmentOp(void) + { + Matrix const c16_copy(c16); + Matrix c16_eq(m_id); + c16_eq = c16; + for(unsigned i = 0; i < 6; ++i) { + TS_ASSERT_EQUALS( c16[i], 1.0 + i ); + TS_ASSERT_EQUALS( c16[i], c16_copy[i] ); + TS_ASSERT_EQUALS( c16[i], c16_eq[i] ); + TS_ASSERT_EQUALS( m_id[i], double( i == 0 || i == 3 ) ); + } + } + + void testScaleCtor(void) + { + NR::scale const s(2.0, 3.0); + NR::Matrix const ms(s); + NR::Point const p(5.0, 7.0); + TS_ASSERT_EQUALS( p * s, NR::Point(10.0, 21.0) ); + TS_ASSERT_EQUALS( p * ms, NR::Point(10.0, 21.0) ); + } + + void testRotateCtor(void) + { + NR::Point const p0(1.0, 0.0); + NR::Point const p90(0.0, 1.0); + TS_ASSERT_EQUALS( p0 * r86, NR::Point(.8, .6) ); + TS_ASSERT_EQUALS( p0 * mr86, NR::Point(.8, .6) ); + TS_ASSERT_EQUALS( p90 * r86, NR::Point(-.6, .8) ); + TS_ASSERT_EQUALS( p90 * mr86, NR::Point(-.6, .8) ); + TS_ASSERT( matrix_equalp(Matrix( r86 * r86 ), + mr86 * mr86, + 1e-14) ); + } + + void testTranslateCtor(void) + { + NR::Matrix const mt23(t23); + NR::Point const b(-2.0, 3.0); + TS_ASSERT_EQUALS( b * t23, b * mt23 ); + } + + void testIdentity(void) + { + TS_ASSERT( m_id.test_identity() ); + TS_ASSERT( Matrix(t_id).test_identity() ); + TS_ASSERT( !(Matrix(NR::translate(-2, 3)).test_identity()) ); + TS_ASSERT( Matrix(r_id).test_identity() ); + NR::rotate const rot180(NR::Point(-1, 0)); + TS_ASSERT( !(Matrix(rot180).test_identity()) ); + TS_ASSERT( Matrix(s_id).test_identity() ); + TS_ASSERT( !(Matrix(NR::scale(1.0, 0.0)).test_identity()) ); + TS_ASSERT( !(Matrix(NR::scale(0.0, 1.0)).test_identity()) ); + TS_ASSERT( !(Matrix(NR::scale(1.0, -1.0)).test_identity()) ); + TS_ASSERT( !(Matrix(NR::scale(-1.0, -1.0)).test_identity()) ); + } + + void testInverse(void) + { + TS_ASSERT_EQUALS( m_id.inverse(), m_id ); + TS_ASSERT_EQUALS( Matrix(t23).inverse(), Matrix(NR::translate(-2.0, -3.0)) ); + NR::scale const s2(-4.0, 2.0); + NR::scale const sp5(-.25, .5); + TS_ASSERT_EQUALS( Matrix(s2).inverse(), Matrix(sp5) ); + } + + void testNrMatrixInvert(void) + { + NRMatrix const nr_m_id(m_id); + Matrix const m_s2(NR::scale(-4.0, 2.0)); + NRMatrix const nr_s2(m_s2); + Matrix const m_sp5(NR::scale(-.25, .5)); + NRMatrix const nr_sp5(m_sp5); + Matrix const m_t23(t23); + NRMatrix const nr_t23(m_t23); + NRMatrix inv; + nr_matrix_invert(&inv, &nr_m_id); + TS_ASSERT_EQUALS( Matrix(inv), m_id ); + nr_matrix_invert(&inv, &nr_t23); + TS_ASSERT_EQUALS( Matrix(inv), Matrix(NR::translate(-2.0, -3.0)) ); + nr_matrix_invert(&inv, &nr_s2); + TS_ASSERT_EQUALS( Matrix(inv), Matrix(nr_sp5) ); + nr_matrix_invert(&inv, &nr_sp5); + TS_ASSERT_EQUALS( Matrix(inv), Matrix(nr_s2) ); + + /* Test that nr_matrix_invert handles src == dest. */ + inv = nr_s2; + nr_matrix_invert(&inv, &inv); + TS_ASSERT_EQUALS( Matrix(inv), Matrix(nr_sp5) ); + inv = nr_t23; + nr_matrix_invert(&inv, &inv); + TS_ASSERT_EQUALS( Matrix(inv), Matrix(NR::translate(-2.0, -3.0)) ); + } + + void testEllipticQuadraticForm(void) + { + NR::Matrix const aff(1.0, 1.0, + 0.0, 1.0, + 5.0, 6.0); + NR::Matrix const invaff = aff.inverse(); + TS_ASSERT_EQUALS( invaff[1], -1.0 ); + + NR::Matrix const ef(elliptic_quadratic_form(invaff)); + NR::Matrix const exp_ef(2, -1, + -1, 1, + 0, 0); + TS_ASSERT_EQUALS( ef, exp_ef ); + } + + void testMatrixStarRotate(void) + { + NR::Matrix const ma(2.0, -1.0, + 4.0, 4.0, + -0.5, 2.0); + NR::Matrix const a_r86( ma * r86 ); + NR::Matrix const ma1( a_r86 * r86.inverse() ); + TS_ASSERT( matrix_equalp(ma1, ma, 1e-12) ); + NR::Matrix const exp_a_r86( 2*.8 + -1*-.6, 2*.6 + -1*.8, + 4*.8 + 4*-.6, 4*.6 + 4*.8, + -.5*.8 + 2*-.6, -.5*.6 + 2*.8 ); + TS_ASSERT( matrix_equalp(a_r86, exp_a_r86, 1e-12) ); + } + + void testTranslateStarScale_ScaleStarTranslate(void) + { + NR::translate const t2n4(2, -4); + NR::scale const sn2_8(-2, 8); + NR::Matrix const exp_ts(-2, 0, + 0, 8, + -4, -32); + NR::Matrix const exp_st(-2, 0, + 0, 8, + 2, -4); + TS_ASSERT_EQUALS( exp_ts, t2n4 * sn2_8 ); + TS_ASSERT_EQUALS( exp_st, sn2_8 * t2n4 ); + } + + void testMatrixStarScale(void) + { + NR::Matrix const ma(2.0, -1.0, + 4.0, 4.0, + -0.5, 2.0); + NR::scale const sn2_8(-2, 8); + NR::Matrix const exp_as(-4, -8, + -8, 32, + 1, 16); + TS_ASSERT_EQUALS( ma * sn2_8, exp_as ); + } +}; + +/* + 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:textwidth=99 : diff --git a/src/libnr/nr-matrix-translate-ops.cpp b/src/libnr/nr-matrix-translate-ops.cpp new file mode 100644 index 000000000..0ccdcf9ce --- /dev/null +++ b/src/libnr/nr-matrix-translate-ops.cpp @@ -0,0 +1,26 @@ +#include "libnr/nr-matrix-ops.h" + +namespace NR { + +Matrix +operator*(Matrix const &m, translate const &t) +{ + Matrix ret(m); + ret[4] += t[X]; + ret[5] += t[Y]; + assert_close( ret, m * Matrix(t) ); + return ret; +} + +} // namespace NR + +/* + 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:textwidth=99 : diff --git a/src/libnr/nr-matrix-translate-ops.h b/src/libnr/nr-matrix-translate-ops.h new file mode 100644 index 000000000..f51bccaa1 --- /dev/null +++ b/src/libnr/nr-matrix-translate-ops.h @@ -0,0 +1,36 @@ +#ifndef SEEN_LIBNR_NR_MATRIX_TRANSLATE_OPS_H +#define SEEN_LIBNR_NR_MATRIX_TRANSLATE_OPS_H + +/** \file + * Declarations (and definition if inline) of operator + * blah (NR::Matrix, NR::translate). + */ + +#include "libnr/nr-matrix.h" +#include "libnr/nr-translate.h" + +//NR::Matrix operator*(NR::Matrix const &m, NR::translate const &t); + +namespace NR { +Matrix operator*(Matrix const &m, translate const &t); +} + +inline NR::Matrix +operator/(NR::Matrix const &numer, NR::translate const &denom) +{ + return numer * NR::translate(-denom.offset); +} + + +#endif /* !SEEN_LIBNR_NR_MATRIX_TRANSLATE_OPS_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:encoding=utf-8:textwidth=99 : diff --git a/src/libnr/nr-matrix.cpp b/src/libnr/nr-matrix.cpp new file mode 100644 index 000000000..24fa2e206 --- /dev/null +++ b/src/libnr/nr-matrix.cpp @@ -0,0 +1,607 @@ +#define __NR_MATRIX_C__ + +/** \file + * Various matrix routines. Currently includes some NR::rotate etc. routines too. + */ + +/* + * Authors: + * Lauris Kaplinski + * + * This code is in public domain + */ + +#include "nr-matrix.h" + + + +/** + * Multiply two NRMatrices together, storing the result in d. + */ +NRMatrix * +nr_matrix_multiply(NRMatrix *d, NRMatrix const *m0, NRMatrix const *m1) +{ + if (m0) { + if (m1) { + NR::Coord d0 = m0->c[0] * m1->c[0] + m0->c[1] * m1->c[2]; + NR::Coord d1 = m0->c[0] * m1->c[1] + m0->c[1] * m1->c[3]; + NR::Coord d2 = m0->c[2] * m1->c[0] + m0->c[3] * m1->c[2]; + NR::Coord d3 = m0->c[2] * m1->c[1] + m0->c[3] * m1->c[3]; + NR::Coord d4 = m0->c[4] * m1->c[0] + m0->c[5] * m1->c[2] + m1->c[4]; + NR::Coord d5 = m0->c[4] * m1->c[1] + m0->c[5] * m1->c[3] + m1->c[5]; + + NR::Coord *dest = d->c; + *dest++ = d0; + *dest++ = d1; + *dest++ = d2; + *dest++ = d3; + *dest++ = d4; + *dest = d5; + } else { + *d = *m0; + } + } else { + if (m1) { + *d = *m1; + } else { + nr_matrix_set_identity(d); + } + } + + return d; +} + + + + +/** + * Store the inverted value of Matrix m in d + */ +NRMatrix * +nr_matrix_invert(NRMatrix *d, NRMatrix const *m) +{ + if (m) { + NR::Coord const det = m->c[0] * m->c[3] - m->c[1] * m->c[2]; + if (!NR_DF_TEST_CLOSE(det, 0.0, NR_EPSILON)) { + + NR::Coord const idet = 1.0 / det; + NR::Coord *dest = d->c; + + /* Cache m->c[0] and m->c[4] in case d == m. */ + NR::Coord const m_c0(m->c[0]); + NR::Coord const m_c4(m->c[4]); + + /*0*/ *dest++ = m->c[3] * idet; + /*1*/ *dest++ = -m->c[1] * idet; + /*2*/ *dest++ = -m->c[2] * idet; + /*3*/ *dest++ = m_c0 * idet; + /*4*/ *dest++ = -m_c4 * d->c[0] - m->c[5] * d->c[2]; + /*5*/ *dest = -m_c4 * d->c[1] - m->c[5] * d->c[3]; + + } else { + nr_matrix_set_identity(d); + } + } else { + nr_matrix_set_identity(d); + } + + return d; +} + + + + + +/** + * Set this matrix to a translation of x and y + */ +NRMatrix * +nr_matrix_set_translate(NRMatrix *m, NR::Coord const x, NR::Coord const y) +{ + NR::Coord *dest = m->c; + + *dest++ = 1.0; //0 + *dest++ = 0.0; //1 + *dest++ = 0.0; //2 + *dest++ = 1.0; //3 + *dest++ = x; //4 + *dest = y; //5 + + return m; +} + + + + + +/** + * Set this matrix to a scaling transform in sx and sy + */ +NRMatrix * +nr_matrix_set_scale(NRMatrix *m, NR::Coord const sx, NR::Coord const sy) +{ + NR::Coord *dest = m->c; + + *dest++ = sx; //0 + *dest++ = 0.0; //1 + *dest++ = 0.0; //2 + *dest++ = sy; //3 + *dest++ = 0.0; //4 + *dest = 0.0; //5 + + return m; +} + + + + + +/** + * Set this matrix to a rotating transform of angle 'theta' radians + */ +NRMatrix * +nr_matrix_set_rotate(NRMatrix *m, NR::Coord const theta) +{ + NR::Coord const s = sin(theta); + NR::Coord const c = cos(theta); + + NR::Coord *dest = m->c; + + *dest++ = c; //0 + *dest++ = s; //1 + *dest++ = -s; //2 + *dest++ = c; //3 + *dest++ = 0.0; //4 + *dest = 0.0; //5 + + return m; +} + + + + + + + + + +/** + * Implement NR functions and methods + */ +namespace NR { + + + + + +/** + * Constructor. Assign to nr if not null, else identity + */ +Matrix::Matrix(NRMatrix const *nr) +{ + if (nr) { + assign(nr->c); + } else { + set_identity(); + } +} + + + + + +/** + * Multiply two matrices together + */ +Matrix operator*(Matrix const &m0, Matrix const &m1) +{ + NR::Coord const d0 = m0[0] * m1[0] + m0[1] * m1[2]; + NR::Coord const d1 = m0[0] * m1[1] + m0[1] * m1[3]; + NR::Coord const d2 = m0[2] * m1[0] + m0[3] * m1[2]; + NR::Coord const d3 = m0[2] * m1[1] + m0[3] * m1[3]; + NR::Coord const d4 = m0[4] * m1[0] + m0[5] * m1[2] + m1[4]; + NR::Coord const d5 = m0[4] * m1[1] + m0[5] * m1[3] + m1[5]; + + Matrix ret( d0, d1, d2, d3, d4, d5 ); + + return ret; +} + + + + + +/** + * Multiply a matrix by another + */ +Matrix &Matrix::operator*=(Matrix const &o) +{ + *this = *this * o; + return *this; +} + + + + + +/** + * Multiply by a scaling matrix + */ +Matrix &Matrix::operator*=(scale const &other) +{ + /* This loop is massive overkill. Let's unroll. + * o _c[] goes from 0..5 + * o other[] alternates between 0 and 1 + */ + /* + * for (unsigned i = 0; i < 3; ++i) { + * for (unsigned j = 0; j < 2; ++j) { + * this->_c[i * 2 + j] *= other[j]; + * } + * } + */ + + NR::Coord const xscale = other[0]; + NR::Coord const yscale = other[1]; + NR::Coord *dest = _c; + + /*i=0 j=0*/ *dest++ *= xscale; + /*i=0 j=1*/ *dest++ *= yscale; + /*i=1 j=0*/ *dest++ *= xscale; + /*i=1 j=1*/ *dest++ *= yscale; + /*i=2 j=0*/ *dest++ *= xscale; + /*i=2 j=1*/ *dest *= yscale; + + return *this; +} + + + + + +/** + * Return the inverse of this matrix. If an inverse is not defined, + * then return the identity matrix. + */ +Matrix Matrix::inverse() const +{ + Matrix d(0.0, 0.0, 0.0, 0.0, 0.0, 0.0); + + NR::Coord const det = _c[0] * _c[3] - _c[1] * _c[2]; + if (!NR_DF_TEST_CLOSE(det, 0.0, NR_EPSILON)) { + + NR::Coord const idet = 1.0 / det; + NR::Coord *dest = d._c; + + /*0*/ *dest++ = _c[3] * idet; + /*1*/ *dest++ = -_c[1] * idet; + /*2*/ *dest++ = -_c[2] * idet; + /*3*/ *dest++ = _c[0] * idet; + /*4*/ *dest++ = -_c[4] * d._c[0] - _c[5] * d._c[2]; + /*5*/ *dest = -_c[4] * d._c[1] - _c[5] * d._c[3]; + + } else { + d.set_identity(); + } + + return d; +} + + + + + +/** + * Set this matrix to Identity + */ +void Matrix::set_identity() +{ + NR::Coord *dest = _c; + + *dest++ = 1.0; //0 + *dest++ = 0.0; //1 + *dest++ = 0.0; //2 + *dest++ = 1.0; //3 + // translation + *dest++ = 0.0; //4 + *dest = 0.0; //5 +} + + + + + +/** + * return an Identity matrix + */ +Matrix identity() +{ + Matrix ret(1.0, 0.0, + 0.0, 1.0, + 0.0, 0.0); + return ret; +} + + + + + +/** + * + */ +Matrix from_basis(Point const x_basis, Point const y_basis, Point const offset) +{ + Matrix const ret(x_basis[X], y_basis[X], + x_basis[Y], y_basis[Y], + offset[X], offset[Y]); + return ret; +} + + + + +/** + * Returns a rotation matrix corresponding by the specified angle (in radians) about the origin. + * + * \see NR::rotate_degrees + * + * Angle direction in Inkscape code: If you use the traditional mathematics convention that y + * increases upwards, then positive angles are anticlockwise as per the mathematics convention. If + * you take the common non-mathematical convention that y increases downwards, then positive angles + * are clockwise, as is common outside of mathematics. + */ +rotate::rotate(NR::Coord const theta) : + vec(cos(theta), + sin(theta)) +{ +} + + + + + +/** + * Return the determinant of the Matrix + */ +NR::Coord Matrix::det() const +{ + return _c[0] * _c[3] - _c[1] * _c[2]; +} + + + + + +/** + * Return the scalar of the descriminant of the Matrix + */ +NR::Coord Matrix::descrim2() const +{ + return fabs(det()); +} + + + + + +/** + * Return the descriminant of the Matrix + */ +NR::Coord Matrix::descrim() const +{ + return sqrt(descrim2()); +} + + + + + +/** + * Assign a matrix to a given coordinate array + */ +Matrix &Matrix::assign(Coord const *array) +{ + assert(array != NULL); + + Coord const *src = array; + Coord *dest = _c; + + *dest++ = *src++; //0 + *dest++ = *src++; //1 + *dest++ = *src++; //2 + *dest++ = *src++; //3 + *dest++ = *src++; //4 + *dest = *src ; //5 + + return *this; +} + + + + + +/** + * Copy this matrix's value to a NRMatrix + */ +NRMatrix *Matrix::copyto(NRMatrix *nrm) const { + + assert(nrm != NULL); + + Coord const *src = _c; + Coord *dest = nrm->c; + + *dest++ = *src++; //0 + *dest++ = *src++; //1 + *dest++ = *src++; //2 + *dest++ = *src++; //3 + *dest++ = *src++; //4 + *dest = *src ; //5 + + return nrm; +} + + + + +/** + * Copy this matrix's values to an array + */ +NR::Coord *Matrix::copyto(NR::Coord *array) const { + + assert(array != NULL); + + Coord const *src = _c; + Coord *dest = array; + + *dest++ = *src++; //0 + *dest++ = *src++; //1 + *dest++ = *src++; //2 + *dest++ = *src++; //3 + *dest++ = *src++; //4 + *dest = *src ; //5 + + return array; +} + + + + + +/** + * + */ +double expansion(Matrix const &m) { + return sqrt(fabs(m.det())); +} + + + + + +/** + * + */ +double Matrix::expansion() const { + return sqrt(fabs(det())); +} + + + + + +/** + * + */ +double Matrix::expansionX() const { + return sqrt(_c[0] * _c[0] + _c[1] * _c[1]); +} + + + + + +/** + * + */ +double Matrix::expansionY() const { + return sqrt(_c[2] * _c[2] + _c[3] * _c[3]); +} + + + + + +/** + * + */ +bool Matrix::is_translation(Coord const eps) const { + return ( fabs(_c[0] - 1.0) < eps && + fabs(_c[3] - 1.0) < eps && + fabs(_c[1]) < eps && + fabs(_c[2]) < eps ); +} + + + + + +/** + * + */ +bool Matrix::test_identity() const { + return NR_MATRIX_DF_TEST_CLOSE(this, &NR_MATRIX_IDENTITY, NR_EPSILON); +} + + + + + +/** + * + */ +bool transform_equalp(Matrix const &m0, Matrix const &m1, NR::Coord const epsilon) { + return NR_MATRIX_DF_TEST_TRANSFORM_CLOSE(&m0, &m1, epsilon); +} + + + + + +/** + * + */ +bool translate_equalp(Matrix const &m0, Matrix const &m1, NR::Coord const epsilon) { + return NR_MATRIX_DF_TEST_TRANSLATE_CLOSE(&m0, &m1, epsilon); +} + + + + + +/** + * + */ +bool matrix_equalp(Matrix const &m0, Matrix const &m1, NR::Coord const epsilon) +{ + return ( NR_MATRIX_DF_TEST_TRANSFORM_CLOSE(&m0, &m1, epsilon) && + NR_MATRIX_DF_TEST_TRANSLATE_CLOSE(&m0, &m1, epsilon) ); +} + + + + + +/** + * A home-made assertion. Stop if the two matrixes are not 'close' to + * each other. + */ +void assert_close(Matrix const &a, Matrix const &b) +{ + if (!matrix_equalp(a, b, 1e-3)) { + fprintf(stderr, + "a = | %g %g |,\tb = | %g %g |\n" + " | %g %g | \t | %g %g |\n" + " | %g %g | \t | %g %g |\n", + a[0], a[1], b[0], b[1], + a[2], a[3], b[2], b[3], + a[4], a[5], b[4], b[5]); + abort(); + } +} + + + +} //namespace NR + + + +/* + 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:textwidth=99 : diff --git a/src/libnr/nr-matrix.h b/src/libnr/nr-matrix.h new file mode 100644 index 000000000..47196137e --- /dev/null +++ b/src/libnr/nr-matrix.h @@ -0,0 +1,453 @@ +#ifndef __NR_MATRIX_H__ +#define __NR_MATRIX_H__ + +/** \file + * Definition of NRMatrix and NR::Matrix types. + * + * \note Operator functions (e.g. Matrix * Matrix etc.) are mostly in + * libnr/nr-matrix-ops.h. See end of file for discussion. + * + * Main authors: + * Lauris Kaplinski : + * Original NRMatrix definition and related macros. + * + * Nathan Hurst : + * NR::Matrix class version of the above. + * + * This code is in public domain. + */ + +#include + +#include "libnr/nr-coord.h" +#include "libnr/nr-values.h" +#include +#include +#include + +/// NRMatrix is the obsolete form of NR::Matrix. +/// It consists of six NR::Coord values. +struct NRMatrix { + NR::Coord c[6]; + + NR::Coord &operator[](int i) { return c[i]; } + NR::Coord operator[](int i) const { return c[i]; } +}; + +#define nr_matrix_set_identity(m) (*(m) = NR_MATRIX_IDENTITY) + +#define nr_matrix_test_identity(m,e) (!(m) || NR_MATRIX_DF_TEST_CLOSE(m, &NR_MATRIX_IDENTITY, e)) + +#define nr_matrix_test_equal(m0,m1,e) ((!(m0) && !(m1)) || ((m0) && (m1) && NR_MATRIX_DF_TEST_CLOSE(m0, m1, e))) +#define nr_matrix_test_transform_equal(m0,m1,e) ((!(m0) && !(m1)) || ((m0) && (m1) && NR_MATRIX_DF_TEST_TRANSFORM_CLOSE(m0, m1, e))) +#define nr_matrix_test_translate_equal(m0,m1,e) ((!(m0) && !(m1)) || ((m0) && (m1) && NR_MATRIX_DF_TEST_TRANSLATE_CLOSE(m0, m1, e))) + +NRMatrix *nr_matrix_invert(NRMatrix *d, NRMatrix const *m); + +/* d,m0,m1 needn't be distinct in any of these multiply routines. */ + +NRMatrix *nr_matrix_multiply(NRMatrix *d, NRMatrix const *m0, NRMatrix const *m1); + +NRMatrix *nr_matrix_set_translate(NRMatrix *m, NR::Coord const x, NR::Coord const y); + +NRMatrix *nr_matrix_set_scale(NRMatrix *m, NR::Coord const sx, NR::Coord const sy); + +NRMatrix *nr_matrix_set_rotate(NRMatrix *m, NR::Coord const theta); + +#define NR_MATRIX_DF_TRANSFORM_X(m,x,y) ((*(m))[0] * (x) + (*(m))[2] * (y) + (*(m))[4]) +#define NR_MATRIX_DF_TRANSFORM_Y(m,x,y) ((*(m))[1] * (x) + (*(m))[3] * (y) + (*(m))[5]) + +#define NR_MATRIX_DF_EXPANSION2(m) (fabs((*(m))[0] * (*(m))[3] - (*(m))[1] * (*(m))[2])) +#define NR_MATRIX_DF_EXPANSION(m) (sqrt(NR_MATRIX_DF_EXPANSION2(m))) + +namespace NR { + +/** + * The Matrix class. + * + * For purposes of multiplication, points should be thought of as row vectors + * + * p = ( p[X] p[Y] 1 ) + * + * to be right-multiplied by transformation matrices + * \verbatim + c[] = | c[0] c[1] 0 | + | c[2] c[3] 0 | + | c[4] c[5] 1 | \endverbatim + * + * (so the columns of the matrix correspond to the columns (elements) of the result, + * and the rows of the matrix correspond to columns (elements) of the "input"). + */ +class Matrix { + + + public: + + /** + * Various forms of constructor + */ + + /** + * + */ + explicit Matrix() { } + + + /** + * + */ + Matrix(Matrix const &m) { + + NR::Coord const *src = m._c; + NR::Coord *dest = _c; + + *dest++ = *src++; //0 + *dest++ = *src++; //1 + *dest++ = *src++; //2 + *dest++ = *src++; //3 + *dest++ = *src++; //4 + *dest = *src ; //5 + + } + + + + + /** + * + */ + Matrix(NRMatrix const &m) { + + NR::Coord const *src = m.c; + NR::Coord *dest = _c; + + *dest++ = *src++; //0 + *dest++ = *src++; //1 + *dest++ = *src++; //2 + *dest++ = *src++; //3 + *dest++ = *src++; //4 + *dest = *src ; //5 + + } + + + + + /** + * + */ + Matrix(double c0, double c1, + double c2, double c3, + double c4, double c5) { + + NR::Coord *dest = _c; + + *dest++ = c0; //0 + *dest++ = c1; //1 + *dest++ = c2; //2 + *dest++ = c3; //3 + *dest++ = c4; //4 + *dest = c5; //5 + + } + + + + /** + * + */ + Matrix &operator=(Matrix const &m) { + + NR::Coord const *src = m._c; + NR::Coord *dest = _c; + + *dest++ = *src++; //0 + *dest++ = *src++; //1 + *dest++ = *src++; //2 + *dest++ = *src++; //3 + *dest++ = *src++; //4 + *dest = *src ; //5 + + return *this; + } + + + + + /** + * + */ + explicit Matrix(scale const &sm) { + + NR::Coord *dest = _c; + + *dest++ = sm[X]; //0 + *dest++ = 0.0; //1 + *dest++ = 0.0; //2 + *dest++ = sm[Y]; //3 + *dest++ = 0.0; //4 + *dest = 0.0; //5 + + } + + + + + + + /** + * + */ + explicit Matrix(rotate const &r) { + + NR::Coord *dest = _c; + + *dest++ = r.vec[X]; //0 + *dest++ = r.vec[Y]; //1 + *dest++ = -r.vec[Y]; //2 + *dest++ = r.vec[X]; //3 + *dest++ = 0.0; //4 + *dest = 0.0; //5 + + } + + + + + /** + * + */ + explicit Matrix(translate const &tm) { + + NR::Coord *dest = _c; + + *dest++ = 1.0; //0 + *dest++ = 0.0; //1 + *dest++ = 0.0; //2 + *dest++ = 1.0; //3 + *dest++ = tm[X]; //4 + *dest = tm[Y]; //5 + } + + + + /** + * + */ + Matrix(NRMatrix const *nr); + + + /** + * + */ + bool test_identity() const; + + + /** + * + */ + bool is_translation(Coord const eps = 1e-6) const; + + + /** + * + */ + Matrix inverse() const; + + + /** + * + */ + Matrix &operator*=(Matrix const &other); + + + /** + * + */ + Matrix &operator*=(scale const &other); + + + + /** + * + */ + Matrix &operator*=(translate const &other) { + _c[4] += other[X]; + _c[5] += other[Y]; + return *this; + } + + + + /** + * + */ + inline Coord &operator[](int const i) { + return _c[i]; + } + + + + /** + * + */ + inline Coord operator[](int const i) const { + return _c[i]; + } + + + /** + * + */ + void set_identity(); + + /** + * + */ + Coord det() const; + + + /** + * + */ + Coord descrim2() const; + + + /** + * + */ + Coord descrim() const; + + + /** + * + */ + double expansion() const; + + + /** + * + */ + double expansionX() const; + + + /** + * + */ + double expansionY() const; + + // legacy + + + /** + * + */ + Matrix &assign(Coord const *array); + + + /** + * + */ + NRMatrix *copyto(NRMatrix* nrm) const; + + + /** + * + */ + Coord *copyto(Coord *array) const; + + + + /** + * + */ + operator NRMatrix&() { + g_assert(sizeof(_c) == sizeof(NRMatrix)); + return *reinterpret_cast(_c); + } + + + + /** + * + */ + operator NRMatrix const&() const { + g_assert(sizeof(_c) == sizeof(NRMatrix)); + return *reinterpret_cast(_c); + } + + + + /** + * + */ + operator NRMatrix*() { + g_assert(sizeof(_c) == sizeof(NRMatrix)); + return reinterpret_cast(_c); + } + + + /** + * + */ + operator NRMatrix const*() const { + g_assert(sizeof(_c) == sizeof(NRMatrix)); + return reinterpret_cast(_c); + } + + + private: + + + NR::Coord _c[6]; +}; + +/** A function to print out the Matrix (for debugging) */ +inline std::ostream &operator<< (std::ostream &out_file, const NR::Matrix &m) { + out_file << "A: " << m[0] << " C: " << m[2] << " E: " << m[4] << "\n"; + out_file << "B: " << m[1] << " D: " << m[3] << " F: " << m[5] << "\n"; + return out_file; +} + +extern void assert_close(Matrix const &a, Matrix const &b); + +} /* namespace NR */ + + + + + + + +/** \note + * Discussion of splitting up nr-matrix.h into lots of little files: + * + * Advantages: + * + * - Reducing amount of recompilation necessary when anything changes. + * + * - Hopefully also reducing compilation time by reducing the number of inline + * function definitions encountered by the compiler for a given .o file. + * (No timing comparisons done yet. On systems without much memory available + * for caching, this may be outweighed by additional I/O costs.) + * + * Disadvantages: + * + * - More #include lines necessary per file. If a compile fails due to + * not having all the necessary #include lines, then the developer needs + * to spend some time working out what #include to add. + */ + +#endif /* !__NR_MATRIX_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:encoding=utf-8:textwidth=99 : diff --git a/src/libnr/nr-maybe.h b/src/libnr/nr-maybe.h new file mode 100644 index 000000000..6eed01ec1 --- /dev/null +++ b/src/libnr/nr-maybe.h @@ -0,0 +1,140 @@ +#ifndef __NR_MAYBE_H__ +#define __NR_MAYBE_H__ + +/* + * Functionalesque "Maybe" class + * + * Copyright 2004 MenTaLguY + * + * Authors: + * MenTaLguY + * + * This code is licensed under the GNU GPL; see COPYING for more information. + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +namespace NR { + +/** An exception class for run-time type errors */ +template +class IsNot : public std::domain_error { +public: + IsNot() : domain_error(std::string("Is not ") + typeid(T).name()) {} +}; + +/** A type with only one value, which (in principle) is only equal to itself. + * + * Types that may (at runtime) pretend to be Nothing need only provide an + * operator bool operator==(Type, Nothing); the rest of the operator + * definitions will be taken care of automatically. + * + * Such types should also provide a casting operator to Nothing, obviously. + */ +struct Nothing { + bool operator==(Nothing n) { return true; } + bool operator!=(Nothing n) { return false; } + template + bool operator==(T t) { return t == *this; } + template + bool operator!=(T t) { return t != *this; } +}; + +template +bool operator==(T t, Nothing n) { return false; } +template +bool operator!=(T t, Nothing n) { return !( t == n ); } + +template +struct MaybeTraits; + +template +class Maybe { +public: + typedef MaybeTraits traits; + typedef typename traits::storage storage; + typedef typename traits::reference reference; + + Maybe(Nothing n) : _is_nothing(true), _t() {} + + Maybe(const Maybe &m) : _is_nothing(m._is_nothing), _t(m._t) {} + + template + Maybe(const Maybe &m) + : _is_nothing(m._is_nothing), + _t(traits::to_storage(MaybeTraits::from_storage(m._t))) {} + + template + Maybe(T2 t) : _is_nothing(false), _t(traits::to_storage(t)) {} + + reference assume() const throw(IsNot) { + if (_is_nothing) { + throw IsNot(); + } else { + return traits::from_storage(_t); + } + } + + operator reference() const throw(IsNot) { + if (_is_nothing) { + throw IsNot(); + } else { + return traits::from_storage(_t); + } + } + operator Nothing() const throw(IsNot) { + if (!_is_nothing) { + throw IsNot(); + } else { + return Nothing(); + } + } + + bool operator==(Nothing n) { return _is_nothing; } + bool operator==(reference r) { + return traits::from_storage(_t) == r; + } + +private: + bool _is_nothing; + storage _t; +}; + +/* traits classes used by Maybe */ + +template +struct MaybeTraits { + typedef T const storage; + typedef T const &reference; + static reference to_storage(reference t) { return t; } + static reference from_storage(reference t) { return t; } +}; + +template +struct MaybeTraits { + typedef T *storage; + typedef T &reference; + static storage to_storage(reference t) { return &t; } + static reference from_storage(storage t) { return *t; } +}; + +} /* namespace NR */ + +#endif + +/* + 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:textwidth=99 : diff --git a/src/libnr/nr-object.cpp b/src/libnr/nr-object.cpp new file mode 100644 index 000000000..b18685d11 --- /dev/null +++ b/src/libnr/nr-object.cpp @@ -0,0 +1,295 @@ +#define __NR_OBJECT_C__ + +/* + * RGBA display list system for inkscape + * + * Authors: + * Lauris Kaplinski + * MenTaLguY + * + * This code is in public domain + */ + +#include +#include + +#include + +#include "nr-object.h" + +unsigned int nr_emit_fail_warning(const gchar *file, unsigned int line, const gchar *method, const gchar *expr) +{ + fprintf (stderr, "File %s line %d (%s): Assertion %s failed\n", file, line, method, expr); + return 1; +} + +/* NRObject */ + +static NRObjectClass **classes = NULL; +static unsigned int classes_len = 0; +static unsigned int classes_size = 0; + +NRType nr_type_is_a(NRType type, NRType test) +{ + nr_return_val_if_fail(type < classes_len, FALSE); + nr_return_val_if_fail(test < classes_len, FALSE); + + NRObjectClass *c = classes[type]; + + while (c) { + if (c->type == test) { + return TRUE; + } + c = c->parent; + } + + return FALSE; +} + +void const *nr_object_check_instance_cast(void const *ip, NRType tc) +{ + nr_return_val_if_fail(ip != NULL, NULL); + nr_return_val_if_fail(nr_type_is_a(((NRObject const *) ip)->klass->type, tc), ip); + return ip; +} + +unsigned int nr_object_check_instance_type(void const *ip, NRType tc) +{ + if (ip == NULL) { + return FALSE; + } + + return nr_type_is_a(((NRObject const *) ip)->klass->type, tc); +} + +NRType nr_object_register_type(NRType parent, + gchar const *name, + unsigned int csize, + unsigned int isize, + void (* cinit) (NRObjectClass *), + void (* iinit) (NRObject *)) +{ + if (classes_len >= classes_size) { + classes_size += 32; + classes = nr_renew (classes, NRObjectClass *, classes_size); + if (classes_len == 0) { + classes[0] = NULL; + classes_len = 1; + } + } + + NRType const type = classes_len; + classes_len += 1; + + classes[type] = (NRObjectClass*) new char[csize]; + NRObjectClass *c = classes[type]; + + /* FIXME: is this necessary? */ + memset(c, 0, csize); + + if (classes[parent]) { + memcpy(c, classes[parent], classes[parent]->csize); + } + + c->type = type; + c->parent = classes[parent]; + c->name = strdup(name); + c->csize = csize; + c->isize = isize; + c->cinit = cinit; + c->iinit = iinit; + + c->cinit(c); + + return type; +} + +static void nr_object_class_init (NRObjectClass *klass); +static void nr_object_init (NRObject *object); +static void nr_object_finalize (NRObject *object); + +NRType nr_object_get_type() +{ + static NRType type = 0; + + if (!type) { + type = nr_object_register_type (0, + "NRObject", + sizeof (NRObjectClass), + sizeof (NRObject), + (void (*) (NRObjectClass *)) nr_object_class_init, + (void (*) (NRObject *)) nr_object_init); + } + + return type; +} + +static void nr_object_class_init(NRObjectClass *c) +{ + c->finalize = nr_object_finalize; + c->cpp_ctor = NRObject::invoke_ctor; +} + +static void nr_object_init (NRObject *object) +{ +} + +static void nr_object_finalize (NRObject *object) +{ +} + +/* Dynamic lifecycle */ + +static void nr_class_tree_object_invoke_init(NRObjectClass *c, NRObject *object) +{ + if (c->parent) { + nr_class_tree_object_invoke_init(c->parent, object); + } + c->iinit (object); +} + +namespace { + +void finalize_object(void *base, void *) +{ + NRObject *object = reinterpret_cast(base); + object->klass->finalize(object); + object->~NRObject(); +} + +} + +NRObject *NRObject::alloc(NRType type) +{ + nr_return_val_if_fail (type < classes_len, NULL); + + NRObjectClass *c = classes[type]; + + if ( c->parent && c->cpp_ctor == c->parent->cpp_ctor ) { + g_error("Cannot instantiate NRObject class %s which has not registered a C++ constructor\n", c->name); + } + + NRObject *object = reinterpret_cast( + ::operator new(c->isize, Inkscape::GC::SCANNED, Inkscape::GC::AUTO, + &finalize_object, NULL) + ); + memset(object, 0xf0, c->isize); + + object->klass = c; + c->cpp_ctor(object); + nr_class_tree_object_invoke_init (c, object); + + return object; +} + +/* NRActiveObject */ + +static void nr_active_object_class_init(NRActiveObjectClass *c); +static void nr_active_object_init(NRActiveObject *object); +static void nr_active_object_finalize(NRObject *object); + +static NRObjectClass *parent_class; + +NRType nr_active_object_get_type() +{ + static NRType type = 0; + if (!type) { + type = nr_object_register_type (NR_TYPE_OBJECT, + "NRActiveObject", + sizeof (NRActiveObjectClass), + sizeof (NRActiveObject), + (void (*) (NRObjectClass *)) nr_active_object_class_init, + (void (*) (NRObject *)) nr_active_object_init); + } + return type; +} + +static void nr_active_object_class_init(NRActiveObjectClass *c) +{ + NRObjectClass *object_class = (NRObjectClass *) c; + + parent_class = object_class->parent; + + object_class->finalize = nr_active_object_finalize; + object_class->cpp_ctor = NRObject::invoke_ctor; +} + +static void nr_active_object_init(NRActiveObject *object) +{ +} + +static void nr_active_object_finalize(NRObject *object) +{ + NRActiveObject *aobject = (NRActiveObject *) object; + + if (aobject->callbacks) { + for (unsigned int i = 0; i < aobject->callbacks->length; i++) { + NRObjectListener *listener = aobject->callbacks->listeners + i; + if ( listener->vector->dispose ) { + listener->vector->dispose(object, listener->data); + } + } + free (aobject->callbacks); + } + + ((NRObjectClass *) (parent_class))->finalize(object); +} + +void nr_active_object_add_listener(NRActiveObject *object, + const NRObjectEventVector *vector, + unsigned int size, + void *data) +{ + if (!object->callbacks) { + object->callbacks = (NRObjectCallbackBlock*) malloc(sizeof(NRObjectCallbackBlock)); + object->callbacks->size = 1; + object->callbacks->length = 0; + } + + if (object->callbacks->length >= object->callbacks->size) { + int newsize = object->callbacks->size << 1; + object->callbacks = (NRObjectCallbackBlock *) + realloc(object->callbacks, sizeof(NRObjectCallbackBlock) + (newsize - 1) * sizeof (NRObjectListener)); + object->callbacks->size = newsize; + } + + NRObjectListener *listener = object->callbacks->listeners + object->callbacks->length; + listener->vector = vector; + listener->size = size; + listener->data = data; + object->callbacks->length += 1; +} + +void nr_active_object_remove_listener_by_data(NRActiveObject *object, void *data) +{ + if (object->callbacks == NULL) { + return; + } + + for (unsigned i = 0; i < object->callbacks->length; i++) { + NRObjectListener *listener = object->callbacks->listeners + i; + if ( listener->data == data ) { + object->callbacks->length -= 1; + if ( object->callbacks->length < 1 ) { + free(object->callbacks); + object->callbacks = NULL; + } else if ( object->callbacks->length != i ) { + *listener = object->callbacks->listeners[object->callbacks->length]; + } + return; + } + } +} + + + +/* + 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 : diff --git a/src/libnr/nr-object.h b/src/libnr/nr-object.h new file mode 100644 index 000000000..f39814b0d --- /dev/null +++ b/src/libnr/nr-object.h @@ -0,0 +1,157 @@ +#ifndef __NR_OBJECT_H__ +#define __NR_OBJECT_H__ + +/* + * RGBA display list system for inkscape + * + * Authors: + * Lauris Kaplinski + * MenTaLguY + * + * This code is in public domain + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include "gc-managed.h" +#include "gc-finalized.h" +#include "gc-anchored.h" + +typedef guint32 NRType; + +struct NRObject; +struct NRObjectClass; + +#define NR_TYPE_OBJECT (nr_object_get_type ()) +#define NR_OBJECT(o) (NR_CHECK_INSTANCE_CAST ((o), NR_TYPE_OBJECT, NRObject)) +#define NR_IS_OBJECT(o) (NR_CHECK_INSTANCE_TYPE ((o), NR_TYPE_OBJECT)) + +#define NR_TYPE_ACTIVE_OBJECT (nr_active_object_get_type ()) +#define NR_ACTIVE_OBJECT(o) (NR_CHECK_INSTANCE_CAST ((o), NR_TYPE_ACTIVE_OBJECT, NRActiveObject)) +#define NR_IS_ACTIVE_OBJECT(o) (NR_CHECK_INSTANCE_TYPE ((o), NR_TYPE_ACTIVE_OBJECT)) + +#define nr_return_if_fail(expr) if (!(expr) && nr_emit_fail_warning (__FILE__, __LINE__, "?", #expr)) return +#define nr_return_val_if_fail(expr,val) if (!(expr) && nr_emit_fail_warning (__FILE__, __LINE__, "?", #expr)) return (val) + +unsigned int nr_emit_fail_warning (const gchar *file, unsigned int line, const gchar *method, const gchar *expr); + +#ifndef NR_DISABLE_CAST_CHECKS +#define NR_CHECK_INSTANCE_CAST(ip, tc, ct) ((ct *) nr_object_check_instance_cast (ip, tc)) +#else +#define NR_CHECK_INSTANCE_CAST(ip, tc, ct) ((ct *) ip) +#endif + +#define NR_CHECK_INSTANCE_TYPE(ip, tc) nr_object_check_instance_type (ip, tc) +#define NR_OBJECT_GET_CLASS(ip) (((NRObject *) ip)->klass) + +NRType nr_type_is_a (NRType type, NRType test); + +void const *nr_object_check_instance_cast(void const *ip, NRType tc); +unsigned int nr_object_check_instance_type(void const *ip, NRType tc); + +NRType nr_object_register_type (NRType parent, + gchar const *name, + unsigned int csize, + unsigned int isize, + void (* cinit) (NRObjectClass *), + void (* iinit) (NRObject *)); + +/* NRObject */ + +class NRObject : public Inkscape::GC::Managed<>, + public Inkscape::GC::Finalized, + public Inkscape::GC::Anchored +{ +public: + NRObjectClass *klass; + + static NRObject *alloc(NRType type); + + template + static void invoke_ctor(NRObject *object) { + new (object) T(); + } + + /* these can go away eventually */ + NRObject *reference() { + return Inkscape::GC::anchor(this); + } + NRObject *unreference() { + Inkscape::GC::release(this); + return NULL; + } + +protected: + NRObject() {} + +private: + NRObject(NRObject const &); // no copy + void operator=(NRObject const &); // no assign + + void *operator new(size_t size, void *placement) { return placement; } +}; + +struct NRObjectClass { + NRType type; + NRObjectClass *parent; + + gchar *name; + unsigned int csize; + unsigned int isize; + void (* cinit) (NRObjectClass *); + void (* iinit) (NRObject *); + void (* finalize) (NRObject *object); + void (*cpp_ctor)(NRObject *object); +}; + +NRType nr_object_get_type (void); + +/* Dynamic lifecycle */ + +inline NRObject *nr_object_new (NRType type) { + return NRObject::alloc(type); +} + +inline NRObject *nr_object_ref (NRObject *object) { + return object->reference(); +} +inline NRObject *nr_object_unref (NRObject *object) { + return object->unreference(); +} + +/* NRActiveObject */ + +struct NRObjectEventVector { + void (* dispose) (NRObject *object, void *data); +}; + +struct NRObjectListener { + const NRObjectEventVector *vector; + unsigned int size; + void *data; +}; + +struct NRObjectCallbackBlock { + unsigned int size; + unsigned int length; + NRObjectListener listeners[1]; +}; + +struct NRActiveObject : public NRObject { + NRActiveObject() : callbacks(NULL) {} + NRObjectCallbackBlock *callbacks; +}; + +struct NRActiveObjectClass : public NRObjectClass { +}; + +NRType nr_active_object_get_type (void); + +void nr_active_object_add_listener (NRActiveObject *object, const NRObjectEventVector *vector, unsigned int size, void *data); +void nr_active_object_remove_listener_by_data (NRActiveObject *object, void *data); + +#endif + diff --git a/src/libnr/nr-path-code.h b/src/libnr/nr-path-code.h new file mode 100644 index 000000000..cc174d73b --- /dev/null +++ b/src/libnr/nr-path-code.h @@ -0,0 +1,28 @@ +#ifndef SEEN_LIBNR_NR_PATH_CODE_H +#define SEEN_LIBNR_NR_PATH_CODE_H + +/** \file + * NRPathcode enum definition + */ + +typedef enum { + NR_MOVETO, ///< Start of closed subpath + NR_MOVETO_OPEN, ///< Start of open subpath + NR_CURVETO, ///< Bezier curve segment + NR_LINETO, ///< Line segment + NR_END ///< End record +} NRPathcode; + + +#endif /* !SEEN_LIBNR_NR_PATH_CODE_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 : diff --git a/src/libnr/nr-path.cpp b/src/libnr/nr-path.cpp new file mode 100644 index 000000000..6ce2f5f99 --- /dev/null +++ b/src/libnr/nr-path.cpp @@ -0,0 +1,461 @@ +#define __NR_PATH_C__ + +/* + * Pixel buffer rendering library + * + * Authors: + * Lauris Kaplinski + * + * This code is in public domain + */ + +#include "n-art-bpath.h" +#include "nr-rect.h" +#include "nr-path.h" + +static void nr_curve_bbox (NR::Coord x000, NR::Coord y000, NR::Coord x001, NR::Coord y001, NR::Coord x011, NR::Coord y011, NR::Coord x111, NR::Coord y111, NRRect *bbox); + +static void nr_curve_bbox(NR::Point const p000, NR::Point const p001, + NR::Point const p011, NR::Point const p111, + NRRect *bbox); + +NRBPath *nr_path_duplicate_transform(NRBPath *d, NRBPath *s, NRMatrix const *transform) +{ + int i; + + if (!s->path) { + d->path = NULL; + return d; + } + + i = 0; + while (s->path[i].code != NR_END) i += 1; + + d->path = nr_new (NArtBpath, i + 1); + + i = 0; + while (s->path[i].code != NR_END) { + d->path[i].code = s->path[i].code; + if (s->path[i].code == NR_CURVETO) { + d->path[i].x1 = NR_MATRIX_DF_TRANSFORM_X (transform, s->path[i].x1, s->path[i].y1); + d->path[i].y1 = NR_MATRIX_DF_TRANSFORM_Y (transform, s->path[i].x1, s->path[i].y1); + d->path[i].x2 = NR_MATRIX_DF_TRANSFORM_X (transform, s->path[i].x2, s->path[i].y2); + d->path[i].y2 = NR_MATRIX_DF_TRANSFORM_Y (transform, s->path[i].x2, s->path[i].y2); + } + d->path[i].x3 = NR_MATRIX_DF_TRANSFORM_X (transform, s->path[i].x3, s->path[i].y3); + d->path[i].y3 = NR_MATRIX_DF_TRANSFORM_Y (transform, s->path[i].x3, s->path[i].y3); + i += 1; + } + d->path[i].code = NR_END; + + return d; +} + +NRBPath *nr_path_duplicate_transform(NRBPath *d, NRBPath *s, NR::Matrix const transform) { + NRMatrix tr = transform; + return nr_path_duplicate_transform(d, s, &tr); +} + +NArtBpath* nr_artpath_affine(NArtBpath *s, NR::Matrix const &aff) { + NRBPath bp, abp; + bp.path = s; + nr_path_duplicate_transform(&abp, &bp, aff); + return abp.path; +} + +static void +nr_line_wind_distance (NR::Coord x0, NR::Coord y0, NR::Coord x1, NR::Coord y1, NR::Point &pt, int *wind, NR::Coord *best) +{ + NR::Coord Ax, Ay, Bx, By, Dx, Dy, s; + NR::Coord dist2; + + /* Find distance */ + Ax = x0; + Ay = y0; + Bx = x1; + By = y1; + Dx = x1 - x0; + Dy = y1 - y0; + const NR::Coord Px = pt[NR::X]; + const NR::Coord Py = pt[NR::Y]; + + if (best) { + s = ((Px - Ax) * Dx + (Py - Ay) * Dy) / (Dx * Dx + Dy * Dy); + if (s <= 0.0) { + dist2 = (Px - Ax) * (Px - Ax) + (Py - Ay) * (Py - Ay); + } else if (s >= 1.0) { + dist2 = (Px - Bx) * (Px - Bx) + (Py - By) * (Py - By); + } else { + NR::Coord Qx, Qy; + Qx = Ax + s * Dx; + Qy = Ay + s * Dy; + dist2 = (Px - Qx) * (Px - Qx) + (Py - Qy) * (Py - Qy); + } + + if (dist2 < (*best * *best)) *best = sqrt (dist2); + } + + if (wind) { + /* Find wind */ + if ((Ax >= Px) && (Bx >= Px)) return; + if ((Ay >= Py) && (By >= Py)) return; + if ((Ay < Py) && (By < Py)) return; + if (Ay == By) return; + /* Ctach upper y bound */ + if (Ay == Py) { + if (Ax < Px) *wind -= 1; + return; + } else if (By == Py) { + if (Bx < Px) *wind += 1; + return; + } else { + NR::Coord Qx; + /* Have to calculate intersection */ + Qx = Ax + Dx * (Py - Ay) / Dy; + if (Qx < Px) { + *wind += (Dy > 0.0) ? 1 : -1; + } + } + } +} + +static void +nr_curve_bbox_wind_distance (NR::Coord x000, NR::Coord y000, + NR::Coord x001, NR::Coord y001, + NR::Coord x011, NR::Coord y011, + NR::Coord x111, NR::Coord y111, + NR::Point &pt, + NRRect *bbox, int *wind, NR::Coord *best, + NR::Coord tolerance) +{ + NR::Coord x0, y0, x1, y1, len2; + int needdist, needwind, needline; + + const NR::Coord Px = pt[NR::X]; + const NR::Coord Py = pt[NR::Y]; + + needdist = 0; + needwind = 0; + needline = 0; + + if (bbox) nr_curve_bbox (x000, y000, x001, y001, x011, y011, x111, y111, bbox); + + x0 = MIN (x000, x001); + x0 = MIN (x0, x011); + x0 = MIN (x0, x111); + y0 = MIN (y000, y001); + y0 = MIN (y0, y011); + y0 = MIN (y0, y111); + x1 = MAX (x000, x001); + x1 = MAX (x1, x011); + x1 = MAX (x1, x111); + y1 = MAX (y000, y001); + y1 = MAX (y1, y011); + y1 = MAX (y1, y111); + + if (best) { + /* Quicly adjust to endpoints */ + len2 = (x000 - Px) * (x000 - Px) + (y000 - Py) * (y000 - Py); + if (len2 < (*best * *best)) *best = (NR::Coord) sqrt (len2); + len2 = (x111 - Px) * (x111 - Px) + (y111 - Py) * (y111 - Py); + if (len2 < (*best * *best)) *best = (NR::Coord) sqrt (len2); + + if (((x0 - Px) < *best) && ((y0 - Py) < *best) && ((Px - x1) < *best) && ((Py - y1) < *best)) { + /* Point is inside sloppy bbox */ + /* Now we have to decide, whether subdivide */ + /* fixme: (Lauris) */ + if (((y1 - y0) > 5.0) || ((x1 - x0) > 5.0)) { + needdist = 1; + } else { + needline = 1; + } + } + } + if (!needdist && wind) { + if ((y1 >= Py) && (y0 < Py) && (x0 < Px)) { + /* Possible intersection at the left */ + /* Now we have to decide, whether subdivide */ + /* fixme: (Lauris) */ + if (((y1 - y0) > 5.0) || ((x1 - x0) > 5.0)) { + needwind = 1; + } else { + needline = 1; + } + } + } + + if (needdist || needwind) { + NR::Coord x00t, x0tt, xttt, x1tt, x11t, x01t; + NR::Coord y00t, y0tt, yttt, y1tt, y11t, y01t; + NR::Coord s, t; + + t = 0.5; + s = 1 - t; + + x00t = s * x000 + t * x001; + x01t = s * x001 + t * x011; + x11t = s * x011 + t * x111; + x0tt = s * x00t + t * x01t; + x1tt = s * x01t + t * x11t; + xttt = s * x0tt + t * x1tt; + + y00t = s * y000 + t * y001; + y01t = s * y001 + t * y011; + y11t = s * y011 + t * y111; + y0tt = s * y00t + t * y01t; + y1tt = s * y01t + t * y11t; + yttt = s * y0tt + t * y1tt; + + nr_curve_bbox_wind_distance (x000, y000, x00t, y00t, x0tt, y0tt, xttt, yttt, pt, NULL, wind, best, tolerance); + nr_curve_bbox_wind_distance (xttt, yttt, x1tt, y1tt, x11t, y11t, x111, y111, pt, NULL, wind, best, tolerance); + } else if (1 || needline) { + nr_line_wind_distance (x000, y000, x111, y111, pt, wind, best); + } +} + +void +nr_path_matrix_point_bbox_wind_distance (NRBPath *bpath, NR::Matrix const &m, NR::Point &pt, + NRRect *bbox, int *wind, NR::Coord *dist, + NR::Coord tolerance) +{ + NR::Coord x0, y0, x3, y3; + const NArtBpath *p; + + if (!bpath->path) { + if (wind) *wind = 0; + if (dist) *dist = NR_HUGE; + return; + } + + x0 = y0 = 0.0; + x3 = y3 = 0.0; + + for (p = bpath->path; p->code != NR_END; p+= 1) { + switch (p->code) { + case NR_MOVETO_OPEN: + case NR_MOVETO: + x0 = m[0] * p->x3 + m[2] * p->y3 + m[4]; + y0 = m[1] * p->x3 + m[3] * p->y3 + m[5]; + if (bbox) { + bbox->x0 = (NR::Coord) MIN (bbox->x0, x0); + bbox->y0 = (NR::Coord) MIN (bbox->y0, y0); + bbox->x1 = (NR::Coord) MAX (bbox->x1, x0); + bbox->y1 = (NR::Coord) MAX (bbox->y1, y0); + } + break; + case NR_LINETO: + x3 = m[0] * p->x3 + m[2] * p->y3 + m[4]; + y3 = m[1] * p->x3 + m[3] * p->y3 + m[5]; + if (bbox) { + bbox->x0 = (NR::Coord) MIN (bbox->x0, x3); + bbox->y0 = (NR::Coord) MIN (bbox->y0, y3); + bbox->x1 = (NR::Coord) MAX (bbox->x1, x3); + bbox->y1 = (NR::Coord) MAX (bbox->y1, y3); + } + if (dist || wind) { + nr_line_wind_distance (x0, y0, x3, y3, pt, wind, dist); + } + x0 = x3; + y0 = y3; + break; + case NR_CURVETO: + x3 = m[0] * p->x3 + m[2] * p->y3 + m[4]; + y3 = m[1] * p->x3 + m[3] * p->y3 + m[5]; + nr_curve_bbox_wind_distance (x0, y0, + m[0] * p->x1 + m[2] * p->y1 + m[4], + m[1] * p->x1 + m[3] * p->y1 + m[5], + m[0] * p->x2 + m[2] * p->y2 + m[4], + m[1] * p->x2 + m[3] * p->y2 + m[5], + x3, y3, + pt, + bbox, wind, dist, tolerance); + x0 = x3; + y0 = y3; + break; + default: + break; + } + } +} + +static void +nr_curve_bbox(NR::Point const p000, NR::Point const p001, + NR::Point const p011, NR::Point const p111, + NRRect *bbox) +{ + using NR::X; + using NR::Y; + + nr_curve_bbox(p000[X], p000[Y], + p001[X], p001[Y], + p011[X], p011[Y], + p111[X], p111[Y], + bbox); +} + +/* Fast bbox calculation */ +/* Thanks to Nathan Hurst for suggesting it */ + +static void +nr_curve_bbox (NR::Coord x000, NR::Coord y000, NR::Coord x001, NR::Coord y001, NR::Coord x011, NR::Coord y011, NR::Coord x111, NR::Coord y111, NRRect *bbox) +{ + NR::Coord a, b, c, D; + + bbox->x0 = (NR::Coord) MIN (bbox->x0, x111); + bbox->y0 = (NR::Coord) MIN (bbox->y0, y111); + bbox->x1 = (NR::Coord) MAX (bbox->x1, x111); + bbox->y1 = (NR::Coord) MAX (bbox->y1, y111); + + /* + * xttt = s * (s * (s * x000 + t * x001) + t * (s * x001 + t * x011)) + t * (s * (s * x001 + t * x011) + t * (s * x011 + t * x111)) + * xttt = s * (s2 * x000 + s * t * x001 + t * s * x001 + t2 * x011) + t * (s2 * x001 + s * t * x011 + t * s * x011 + t2 * x111) + * xttt = s * (s2 * x000 + 2 * st * x001 + t2 * x011) + t * (s2 * x001 + 2 * st * x011 + t2 * x111) + * xttt = s3 * x000 + 2 * s2t * x001 + st2 * x011 + s2t * x001 + 2st2 * x011 + t3 * x111 + * xttt = s3 * x000 + 3s2t * x001 + 3st2 * x011 + t3 * x111 + * xttt = s3 * x000 + (1 - s) 3s2 * x001 + (1 - s) * (1 - s) * 3s * x011 + (1 - s) * (1 - s) * (1 - s) * x111 + * xttt = s3 * x000 + (3s2 - 3s3) * x001 + (3s - 6s2 + 3s3) * x011 + (1 - 2s + s2 - s + 2s2 - s3) * x111 + * xttt = (x000 - 3 * x001 + 3 * x011 - x111) * s3 + + * ( 3 * x001 - 6 * x011 + 3 * x111) * s2 + + * ( 3 * x011 - 3 * x111) * s + + * ( x111) + * xttt' = (3 * x000 - 9 * x001 + 9 * x011 - 3 * x111) * s2 + + * ( 6 * x001 - 12 * x011 + 6 * x111) * s + + * ( 3 * x011 - 3 * x111) + */ + + a = 3 * x000 - 9 * x001 + 9 * x011 - 3 * x111; + b = 6 * x001 - 12 * x011 + 6 * x111; + c = 3 * x011 - 3 * x111; + + /* + * s = (-b +/- sqrt (b * b - 4 * a * c)) / 2 * a; + */ + if (fabs (a) < NR_EPSILON) { + /* s = -c / b */ + if (fabs (b) > NR_EPSILON) { + double s, t, xttt; + s = -c / b; + if ((s > 0.0) && (s < 1.0)) { + t = 1.0 - s; + xttt = s * s * s * x000 + 3 * s * s * t * x001 + 3 * s * t * t * x011 + t * t * t * x111; + bbox->x0 = (float) MIN (bbox->x0, xttt); + bbox->x1 = (float) MAX (bbox->x1, xttt); + } + } + } else { + /* s = (-b +/- sqrt (b * b - 4 * a * c)) / 2 * a; */ + D = b * b - 4 * a * c; + if (D >= 0.0) { + NR::Coord d, s, t, xttt; + /* Have solution */ + d = sqrt (D); + s = (-b + d) / (2 * a); + if ((s > 0.0) && (s < 1.0)) { + t = 1.0 - s; + xttt = s * s * s * x000 + 3 * s * s * t * x001 + 3 * s * t * t * x011 + t * t * t * x111; + bbox->x0 = (NR::Coord) MIN (bbox->x0, xttt); + bbox->x1 = (NR::Coord) MAX (bbox->x1, xttt); + } + s = (-b - d) / (2 * a); + if ((s > 0.0) && (s < 1.0)) { + t = 1.0 - s; + xttt = s * s * s * x000 + 3 * s * s * t * x001 + 3 * s * t * t * x011 + t * t * t * x111; + bbox->x0 = (NR::Coord) MIN (bbox->x0, xttt); + bbox->x1 = (NR::Coord) MAX (bbox->x1, xttt); + } + } + } + + a = 3 * y000 - 9 * y001 + 9 * y011 - 3 * y111; + b = 6 * y001 - 12 * y011 + 6 * y111; + c = 3 * y011 - 3 * y111; + + if (fabs (a) < NR_EPSILON) { + /* s = -c / b */ + if (fabs (b) > NR_EPSILON) { + double s, t, yttt; + s = -c / b; + if ((s > 0.0) && (s < 1.0)) { + t = 1.0 - s; + yttt = s * s * s * y000 + 3 * s * s * t * y001 + 3 * s * t * t * y011 + t * t * t * y111; + bbox->y0 = (float) MIN (bbox->y0, yttt); + bbox->y1 = (float) MAX (bbox->y1, yttt); + } + } + } else { + /* s = (-b +/- sqrt (b * b - 4 * a * c)) / 2 * a; */ + D = b * b - 4 * a * c; + if (D >= 0.0) { + NR::Coord d, s, t, yttt; + /* Have solution */ + d = sqrt (D); + s = (-b + d) / (2 * a); + if ((s > 0.0) && (s < 1.0)) { + t = 1.0 - s; + yttt = s * s * s * y000 + 3 * s * s * t * y001 + 3 * s * t * t * y011 + t * t * t * y111; + bbox->y0 = (NR::Coord) MIN (bbox->y0, yttt); + bbox->y1 = (NR::Coord) MAX (bbox->y1, yttt); + } + s = (-b - d) / (2 * a); + if ((s > 0.0) && (s < 1.0)) { + t = 1.0 - s; + yttt = s * s * s * y000 + 3 * s * s * t * y001 + 3 * s * t * t * y011 + t * t * t * y111; + bbox->y0 = (NR::Coord) MIN (bbox->y0, yttt); + bbox->y1 = (NR::Coord) MAX (bbox->y1, yttt); + } + } + } +} + +void +nr_path_matrix_bbox_union(NRBPath const *bpath, NR::Matrix const &m, + NRRect *bbox) +{ + using NR::X; + using NR::Y; + + if (!bpath->path) { + return; + } + + NR::Point prev0(0, 0); + for (NArtBpath const *p = bpath->path; p->code != NR_END; ++p) { + switch (p->code) { + case NR_MOVETO_OPEN: + case NR_MOVETO: { + NR::Point const c3(p->x3, + p->y3); + prev0 = c3 * m; + nr_rect_union_pt(bbox, prev0); + break; + } + + case NR_LINETO: { + NR::Point const c3(p->x3, + p->y3); + NR::Point const endPt( c3 * m ); + nr_rect_union_pt(bbox, endPt); + prev0 = endPt; + break; + } + + case NR_CURVETO: { + NR::Point const c1(p->x1, p->y1); + NR::Point const c2(p->x2, p->y2); + NR::Point const c3(p->x3, p->y3); + NR::Point const endPt( c3 * m ); + nr_curve_bbox(prev0, + c1 * m, + c2 * m, + endPt, + bbox); + prev0 = endPt; + break; + } + + default: + break; + } + } +} + diff --git a/src/libnr/nr-path.h b/src/libnr/nr-path.h new file mode 100644 index 000000000..625a0e498 --- /dev/null +++ b/src/libnr/nr-path.h @@ -0,0 +1,62 @@ +#ifndef __NR_PATH_H__ +#define __NR_PATH_H__ + +/* + * NArtBpath: Curve component. Adapted from libart. + */ + +/* + * libart_lgpl/art_bpath.h copyright information: + * + * Copyright (C) 1998 Raph Levien + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + + +#include +#include + +NArtBpath* nr_artpath_affine(NArtBpath *s, NR::Matrix const &transform); + +//ArtBpath* nr_artpath_to_art_bpath(NArtBpath *s); // this lives in src/extension/internal/gnome.cpp to avoid requiring libart everywhere + +struct NRBPath { + NArtBpath *path; +}; + +NRBPath *nr_path_duplicate_transform(NRBPath *d, NRBPath *s, NRMatrix const *transform); + +NRBPath *nr_path_duplicate_transform(NRBPath *d, NRBPath *s, NR::Matrix const transform); + +void nr_path_matrix_point_bbox_wind_distance (NRBPath *bpath, NR::Matrix const &m, NR::Point &pt, + NRRect *bbox, int *wind, NR::Coord *dist, + NR::Coord tolerance); + +void nr_path_matrix_bbox_union(NRBPath const *bpath, NR::Matrix const &m, NRRect *bbox); + +#endif + +/* + 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 : diff --git a/src/libnr/nr-pixblock-line.cpp b/src/libnr/nr-pixblock-line.cpp new file mode 100644 index 000000000..5e025c7eb --- /dev/null +++ b/src/libnr/nr-pixblock-line.cpp @@ -0,0 +1,92 @@ +#define __NR_PIXBLOCK_LINE_C__ + +/* + * Pixel buffer rendering library + * + * Authors: + * Lauris Kaplinski + * + * This code is in public domain + */ + +#include +#include + +void +nr_pixblock_draw_line_rgba32 (NRPixBlock *d, long x0, long y0, long x1, long y1, short first, unsigned long rgba) +{ + long deltax, deltay, xinc1, xinc2, yinc1, yinc2; + long den, num, numadd, numpixels; + long x, y, curpixel; + /* Pixblock */ + int dbpp; + NRPixBlock spb; + unsigned char *spx; + + if (x1 >= x0) { + deltax = x1 - x0; + xinc1 = 1; + xinc2 = 1; + } else { + deltax = x0 - x1; + xinc1 = -1; + xinc2 = -1; + } + + if (y1 >= y0) { + deltay = y1 - y0; + yinc1 = 1; + yinc2 = 1; + } else { + deltay = y0 - y1; + yinc1 = -1; + yinc2 = -1; + } + + if (deltax >= deltay) { + xinc1 = 0; + yinc2 = 0; + den = deltax; + num = deltax / 2; + numadd = deltay; + numpixels = deltax; + } else { + xinc2 = 0; + yinc1 = 0; + den = deltay; + num = deltay / 2; + numadd = deltax; + numpixels = deltay; + } + + /* We can be quite sure 1x1 pixblock is TINY */ + nr_pixblock_setup_fast (&spb, NR_PIXBLOCK_MODE_R8G8B8A8N, 0, 0, 1, 1, 0); + spb.empty = 0; + spx = NR_PIXBLOCK_PX (&spb); + spx[0] = NR_RGBA32_R (rgba); + spx[1] = NR_RGBA32_G (rgba); + spx[2] = NR_RGBA32_B (rgba); + spx[3] = NR_RGBA32_A (rgba); + + dbpp = NR_PIXBLOCK_BPP (d); + + x = x0; + y = y0; + + for (curpixel = 0; curpixel <= numpixels; curpixel++) { + if ((x >= d->area.x0) && (y >= d->area.y0) && (x < d->area.x1) && (y < d->area.y1)) { + nr_compose_pixblock_pixblock_pixel (d, NR_PIXBLOCK_PX (d) + (y - d->area.y0) * d->rs + (x - d->area.x0) * dbpp, &spb, spx); + } + num += numadd; + if (num >= den) { + num -= den; + x += xinc1; + y += yinc1; + } + x += xinc2; + y += yinc2; + } + + nr_pixblock_release (&spb); +} + diff --git a/src/libnr/nr-pixblock-line.h b/src/libnr/nr-pixblock-line.h new file mode 100644 index 000000000..7fd58a0ab --- /dev/null +++ b/src/libnr/nr-pixblock-line.h @@ -0,0 +1,28 @@ +#ifndef __NR_PIXBLOCK_LINE_H__ +#define __NR_PIXBLOCK_LINE_H__ + +/* + * Pixel buffer rendering library + * + * Authors: + * Lauris Kaplinski + * + * This code is in public domain + */ + +#include + +void nr_pixblock_draw_line_rgba32 (NRPixBlock *d, long x0, long y0, long x1, long y1, short first, unsigned long rgba); + +#endif + +/* + 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:textwidth=99 : diff --git a/src/libnr/nr-pixblock-pattern.cpp b/src/libnr/nr-pixblock-pattern.cpp new file mode 100644 index 000000000..03bd688ba --- /dev/null +++ b/src/libnr/nr-pixblock-pattern.cpp @@ -0,0 +1,126 @@ +#define __NR_PIXBLOCK_PATTERN_C__ + +/* + * Pixel buffer rendering library + * + * Authors: + * Lauris Kaplinski + * + * This code is in public domain + */ + + +#include "nr-pixops.h" +#include "nr-pixblock-pattern.h" + +#define NR_NOISE_SIZE 1024 + +void +nr_pixblock_render_gray_noise (NRPixBlock *pb, NRPixBlock *mask) +{ + static unsigned char *noise = NULL; + static unsigned int seed = 0; + unsigned int v; + NRRectL clip; + int x, y, bpp; + + if (mask) { + if (mask->empty) return; + nr_rect_l_intersect (&clip, &pb->area, &mask->area); + if (nr_rect_l_test_empty (&clip)) return; + } else { + clip = pb->area; + } + + if (!noise) { + int i; + noise = nr_new (unsigned char, NR_NOISE_SIZE); + for (i = 0; i < NR_NOISE_SIZE; i++) noise[i] = (rand () / (RAND_MAX >> 8)) & 0xff; + } + + bpp = NR_PIXBLOCK_BPP (pb); + + v = (rand () / (RAND_MAX >> 8)) & 0xff; + + if (mask) { + for (y = clip.y0; y < clip.y1; y++) { + unsigned char *d, *m; + d = NR_PIXBLOCK_PX (pb) + (y - pb->area.y0) * pb->rs + (clip.x0 - pb->area.x0) * bpp; + m = NR_PIXBLOCK_PX (mask) + (y - mask->area.y0) * pb->rs + (clip.x0 - mask->area.x0); + for (x = clip.x0; x < clip.x1; x++) { + v = v ^ noise[seed]; + switch (pb->mode) { + case NR_PIXBLOCK_MODE_A8: + d[0] = (65025 - (255 - m[0]) * (255 - d[0]) + 127) / 255; + break; + case NR_PIXBLOCK_MODE_R8G8B8: + d[0] = NR_COMPOSEN11 (v, m[0], d[0]); + d[1] = NR_COMPOSEN11 (v, m[0], d[1]); + d[2] = NR_COMPOSEN11 (v, m[0], d[2]); + break; + case NR_PIXBLOCK_MODE_R8G8B8A8N: + if (m[0] != 0) { + unsigned int ca; + ca = NR_A7 (m[0], d[3]); + d[0] = NR_COMPOSENNN_A7 (v, m[0], d[0], d[3], ca); + d[1] = NR_COMPOSENNN_A7 (v, m[0], d[1], d[3], ca); + d[2] = NR_COMPOSENNN_A7 (v, m[0], d[2], d[3], ca); + d[3] = (ca + 127) / 255; + } + break; + case NR_PIXBLOCK_MODE_R8G8B8A8P: + d[0] = NR_COMPOSENPP (v, m[0], d[0], d[3]); + d[1] = NR_COMPOSENPP (v, m[0], d[1], d[3]); + d[2] = NR_COMPOSENPP (v, m[0], d[2], d[3]); + d[3] = (NR_A7 (d[3], m[0]) + 127) / 255; + break; + default: + break; + } + d += bpp; + m += 1; + if (++seed >= NR_NOISE_SIZE) { + int i; + i = (rand () / (RAND_MAX / NR_NOISE_SIZE)) % NR_NOISE_SIZE; + noise[i] ^= v; + seed = i % (NR_NOISE_SIZE >> 2); + } + } + } + } else { + for (y = clip.y0; y < clip.y1; y++) { + unsigned char *d; + d = NR_PIXBLOCK_PX (pb) + (y - pb->area.y0) * pb->rs + (clip.x0 - pb->area.x0) * bpp; + for (x = clip.x0; x < clip.x1; x++) { + v = v ^ noise[seed]; + switch (pb->mode) { + case NR_PIXBLOCK_MODE_A8: + d[0] = 255; + break; + case NR_PIXBLOCK_MODE_R8G8B8: + d[0] = v; + d[1] = v; + d[2] = v; + break; + case NR_PIXBLOCK_MODE_R8G8B8A8N: + case NR_PIXBLOCK_MODE_R8G8B8A8P: + d[0] = v; + d[1] = v; + d[2] = v; + d[3] = 255; + default: + break; + } + d += bpp; + if (++seed >= NR_NOISE_SIZE) { + int i; + i = (rand () / (RAND_MAX / NR_NOISE_SIZE)) % NR_NOISE_SIZE; + noise[i] ^= v; + seed = i % (NR_NOISE_SIZE >> 2); + } + } + } + } + + pb->empty = 0; +} diff --git a/src/libnr/nr-pixblock-pattern.h b/src/libnr/nr-pixblock-pattern.h new file mode 100644 index 000000000..463a24379 --- /dev/null +++ b/src/libnr/nr-pixblock-pattern.h @@ -0,0 +1,28 @@ +#ifndef __NR_PIXBLOCK_PATTERN_H__ +#define __NR_PIXBLOCK_PATTERN_H__ + +/* + * Pixel buffer rendering library + * + * Authors: + * Lauris Kaplinski + * + * This code is in public domain + */ + +#include + +void nr_pixblock_render_gray_noise (NRPixBlock *pb, NRPixBlock *mask); + +#endif + +/* + 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:textwidth=99 : diff --git a/src/libnr/nr-pixblock-pixel.cpp b/src/libnr/nr-pixblock-pixel.cpp new file mode 100644 index 000000000..c778c0c7f --- /dev/null +++ b/src/libnr/nr-pixblock-pixel.cpp @@ -0,0 +1,230 @@ +#define __NR_PIXBLOCK_PIXEL_C__ + +/* + * Pixel buffer rendering library + * + * Authors: + * Lauris Kaplinski + * + * This code is in public domain + */ + +#include "nr-pixops.h" +#include "nr-pixblock-pixel.h" + +void +nr_compose_pixblock_pixblock_pixel (NRPixBlock *dpb, unsigned char *d, const NRPixBlock *spb, const unsigned char *s) +{ + if (spb->empty) return; + + if (dpb->empty) { + /* Empty destination */ + switch (dpb->mode) { + case NR_PIXBLOCK_MODE_A8: + switch (spb->mode) { + case NR_PIXBLOCK_MODE_A8: + break; + case NR_PIXBLOCK_MODE_R8G8B8: + d[0] = 255; + break; + case NR_PIXBLOCK_MODE_R8G8B8A8N: + d[0] = s[3]; + break; + case NR_PIXBLOCK_MODE_R8G8B8A8P: + d[0] = s[3]; + break; + default: + break; + } + break; + case NR_PIXBLOCK_MODE_R8G8B8: + switch (spb->mode) { + case NR_PIXBLOCK_MODE_A8: + break; + case NR_PIXBLOCK_MODE_R8G8B8: + d[0] = s[0]; + d[1] = s[1]; + d[2] = s[2]; + break; + case NR_PIXBLOCK_MODE_R8G8B8A8N: + d[0] = NR_COMPOSEN11 (s[0], s[3], 255); + d[1] = NR_COMPOSEN11 (s[1], s[3], 255); + d[2] = NR_COMPOSEN11 (s[2], s[3], 255); + break; + case NR_PIXBLOCK_MODE_R8G8B8A8P: + d[0] = NR_COMPOSEP11 (s[0], s[3], 255); + d[1] = NR_COMPOSEP11 (s[1], s[3], 255); + d[2] = NR_COMPOSEP11 (s[2], s[3], 255); + break; + default: + break; + } + break; + case NR_PIXBLOCK_MODE_R8G8B8A8N: + switch (spb->mode) { + case NR_PIXBLOCK_MODE_A8: + break; + case NR_PIXBLOCK_MODE_R8G8B8: + d[0] = s[0]; + d[1] = s[1]; + d[2] = s[2]; + d[3] = 255; + break; + case NR_PIXBLOCK_MODE_R8G8B8A8N: + d[0] = s[0]; + d[1] = s[1]; + d[2] = s[2]; + d[3] = s[3]; + break; + case NR_PIXBLOCK_MODE_R8G8B8A8P: + if (s[3] == 0) { + d[0] = 255; + d[1] = 255; + d[2] = 255; + } else { + d[0] = (s[0] * 255) / s[3]; + d[1] = (s[1] * 255) / s[3]; + d[2] = (s[2] * 255) / s[3]; + } + d[3] = s[3]; + break; + default: + break; + } + break; + case NR_PIXBLOCK_MODE_R8G8B8A8P: + switch (spb->mode) { + case NR_PIXBLOCK_MODE_A8: + break; + case NR_PIXBLOCK_MODE_R8G8B8: + d[0] = s[0]; + d[1] = s[1]; + d[2] = s[2]; + d[3] = 255; + break; + case NR_PIXBLOCK_MODE_R8G8B8A8N: + d[0] = NR_PREMUL (s[0], s[3]); + d[1] = NR_PREMUL (s[1], s[3]); + d[2] = NR_PREMUL (s[2], s[3]); + d[3] = s[3]; + break; + case NR_PIXBLOCK_MODE_R8G8B8A8P: + d[0] = s[0]; + d[1] = s[1]; + d[2] = s[2]; + d[3] = s[3]; + break; + default: + break; + } + break; + default: + break; + } + } else { + /* Image destination */ + switch (dpb->mode) { + case NR_PIXBLOCK_MODE_A8: + switch (spb->mode) { + case NR_PIXBLOCK_MODE_A8: + break; + case NR_PIXBLOCK_MODE_R8G8B8: + d[0] = 255; + break; + case NR_PIXBLOCK_MODE_R8G8B8A8N: + d[0] = NR_A7_NORMALIZED(s[3],d[0]); + break; + case NR_PIXBLOCK_MODE_R8G8B8A8P: + d[0] = NR_A7_NORMALIZED(s[3],d[0]); + break; + default: + break; + } + break; + case NR_PIXBLOCK_MODE_R8G8B8: + switch (spb->mode) { + case NR_PIXBLOCK_MODE_A8: + break; + case NR_PIXBLOCK_MODE_R8G8B8: + d[0] = s[0]; + d[1] = s[1]; + d[2] = s[2]; + break; + case NR_PIXBLOCK_MODE_R8G8B8A8N: + d[0] = NR_COMPOSEN11 (s[0], s[3], d[0]); + d[1] = NR_COMPOSEN11 (s[1], s[3], d[1]); + d[2] = NR_COMPOSEN11 (s[2], s[3], d[2]); + break; + case NR_PIXBLOCK_MODE_R8G8B8A8P: + d[0] = NR_COMPOSEP11 (s[0], s[3], d[0]); + d[1] = NR_COMPOSEP11 (s[1], s[3], d[1]); + d[2] = NR_COMPOSEP11 (s[2], s[3], d[2]); + break; + default: + break; + } + break; + case NR_PIXBLOCK_MODE_R8G8B8A8N: + switch (spb->mode) { + case NR_PIXBLOCK_MODE_A8: + break; + case NR_PIXBLOCK_MODE_R8G8B8: + d[0] = s[0]; + d[1] = s[1]; + d[2] = s[2]; + break; + case NR_PIXBLOCK_MODE_R8G8B8A8N: + if (s[3] != 0) { + unsigned int ca; + ca = NR_A7 (s[3], d[3]); + d[0] = NR_COMPOSENNN_A7 (s[0], s[3], d[0], d[3], ca); + d[1] = NR_COMPOSENNN_A7 (s[1], s[3], d[1], d[3], ca); + d[2] = NR_COMPOSENNN_A7 (s[2], s[3], d[2], d[3], ca); + d[3] = (ca + 127) / 255; + } + break; + case NR_PIXBLOCK_MODE_R8G8B8A8P: + if (s[3] != 0) { + unsigned int ca; + ca = NR_A7 (s[3], d[3]); + d[0] = NR_COMPOSEPNN_A7 (s[0], s[3], d[0], d[3], ca); + d[1] = NR_COMPOSEPNN_A7 (s[1], s[3], d[0], d[3], ca); + d[2] = NR_COMPOSEPNN_A7 (s[2], s[3], d[0], d[3], ca); + d[3] = (ca + 127) / 255; + } + break; + default: + break; + } + break; + case NR_PIXBLOCK_MODE_R8G8B8A8P: + switch (spb->mode) { + case NR_PIXBLOCK_MODE_A8: + break; + case NR_PIXBLOCK_MODE_R8G8B8: + d[0] = s[0]; + d[1] = s[1]; + d[2] = s[2]; + break; + case NR_PIXBLOCK_MODE_R8G8B8A8N: + d[0] = NR_COMPOSENPP (s[0], s[3], d[0], d[3]); + d[1] = NR_COMPOSENPP (s[1], s[3], d[1], d[3]); + d[2] = NR_COMPOSENPP (s[2], s[3], d[2], d[3]); + d[3] = NR_A7_NORMALIZED(s[3],d[3]); + break; + case NR_PIXBLOCK_MODE_R8G8B8A8P: + d[0] = NR_COMPOSEPPP (s[0], s[3], d[0], d[3]); + d[1] = NR_COMPOSEPPP (s[1], s[3], d[1], d[3]); + d[2] = NR_COMPOSEPPP (s[2], s[3], d[2], d[3]); + d[3] = NR_A7_NORMALIZED(s[3],d[3]); + break; + default: + break; + } + break; + default: + break; + } + } +} + diff --git a/src/libnr/nr-pixblock-pixel.h b/src/libnr/nr-pixblock-pixel.h new file mode 100644 index 000000000..d989f53cf --- /dev/null +++ b/src/libnr/nr-pixblock-pixel.h @@ -0,0 +1,28 @@ +#ifndef __NR_PIXBLOCK_PIXEL_H__ +#define __NR_PIXBLOCK_PIXEL_H__ + +/* + * Pixel buffer rendering library + * + * Authors: + * Lauris Kaplinski + * + * This code is in public domain + */ + +#include + +void nr_compose_pixblock_pixblock_pixel (NRPixBlock *dpb, unsigned char *d, const NRPixBlock *spb, const unsigned char *s); + +#endif + +/* + 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:textwidth=99 : diff --git a/src/libnr/nr-pixblock.cpp b/src/libnr/nr-pixblock.cpp new file mode 100644 index 000000000..9b1ff2752 --- /dev/null +++ b/src/libnr/nr-pixblock.cpp @@ -0,0 +1,411 @@ +#define __NR_PIXBLOCK_C__ + +/** \file + * \brief Allocation/Setup of NRPixBlock objects. Pixel store functions. + * + * Authors: + * (C) 1999-2002 Lauris Kaplinski + * + * This code is in the Public Domain + */ + +#include "nr-pixblock.h" + +/// Size of buffer that needs no allocation (default 4). +#define NR_TINY_MAX sizeof (unsigned char *) + +/** + * Pixbuf initialisation using homegrown memory handling ("pixelstore"). + * + * Pixbuf sizes are differentiated into tiny, <4K, <16K, <64K, and more, + * with each type having its own method of memory handling. After allocating + * memory, the buffer is cleared if the clear flag is set. Intended to + * reduce memory fragmentation. + * \param pb Pointer to the pixbuf struct. + * \param mode Indicates grayscale/RGB/RGBA. + * \param clear True if buffer should be cleared. + * \pre x1>=x0 && y1>=y0 && pb!=NULL + */ +void +nr_pixblock_setup_fast (NRPixBlock *pb, NR_PIXBLOCK_MODE mode, int x0, int y0, int x1, int y1, bool clear) +{ + int w, h, bpp; + size_t size; + + w = x1 - x0; + h = y1 - y0; + bpp = (mode == NR_PIXBLOCK_MODE_A8) ? 1 : (mode == NR_PIXBLOCK_MODE_R8G8B8) ? 3 : 4; + + size = bpp * w * h; + + if (size <= NR_TINY_MAX) { + pb->size = NR_PIXBLOCK_SIZE_TINY; + if (clear) memset (pb->data.p, 0x0, size); + } else if (size <= 4096) { + pb->size = NR_PIXBLOCK_SIZE_4K; + pb->data.px = nr_pixelstore_4K_new (clear, 0x0); + } else if (size <= 16384) { + pb->size = NR_PIXBLOCK_SIZE_16K; + pb->data.px = nr_pixelstore_16K_new (clear, 0x0); + } else if (size <= 65536) { + pb->size = NR_PIXBLOCK_SIZE_64K; + pb->data.px = nr_pixelstore_64K_new (clear, 0x0); + } else if (size <= 262144) { + pb->size = NR_PIXBLOCK_SIZE_256K; + pb->data.px = nr_pixelstore_256K_new (clear, 0x0); + } else if (size <= 1048576) { + pb->size = NR_PIXBLOCK_SIZE_1M; + pb->data.px = nr_pixelstore_1M_new (clear, 0x0); + } else { + pb->size = NR_PIXBLOCK_SIZE_BIG; + pb->data.px = nr_new (unsigned char, size); + if (clear) memset (pb->data.px, 0x0, size); + } + + pb->mode = mode; + pb->empty = 1; + pb->area.x0 = x0; + pb->area.y0 = y0; + pb->area.x1 = x1; + pb->area.y1 = y1; + pb->rs = bpp * w; +} + +/** + * Pixbuf initialisation using nr_new. + * + * After allocating memory, the buffer is cleared if the clear flag is set. + * \param pb Pointer to the pixbuf struct. + * \param mode Indicates grayscale/RGB/RGBA. + * \param clear True if buffer should be cleared. + * \pre x1>=x0 && y1>=y0 && pb!=NULL + */ +void +nr_pixblock_setup (NRPixBlock *pb, NR_PIXBLOCK_MODE mode, int x0, int y0, int x1, int y1, bool clear) +{ + int w, h, bpp; + size_t size; + + w = x1 - x0; + h = y1 - y0; + bpp = (mode == NR_PIXBLOCK_MODE_A8) ? 1 : (mode == NR_PIXBLOCK_MODE_R8G8B8) ? 3 : 4; + + size = bpp * w * h; + + if (size <= NR_TINY_MAX) { + pb->size = NR_PIXBLOCK_SIZE_TINY; + if (clear) memset (pb->data.p, 0x0, size); + } else { + pb->size = NR_PIXBLOCK_SIZE_BIG; + pb->data.px = nr_new (unsigned char, size); + if (clear) memset (pb->data.px, 0x0, size); + } + + pb->mode = mode; + pb->empty = 1; + pb->area.x0 = x0; + pb->area.y0 = y0; + pb->area.x1 = x1; + pb->area.y1 = y1; + pb->rs = bpp * w; +} + +/** + * Pixbuf initialisation with preset values. + * + * After copying all parameters into the NRPixBlock struct, the pixel buffer is cleared if the clear flag is set. + * \param pb Pointer to the pixbuf struct. + * \param mode Indicates grayscale/RGB/RGBA. + * \param clear True if buffer should be cleared. + * \pre x1>=x0 && y1>=y0 && pb!=NULL + */ +void +nr_pixblock_setup_extern (NRPixBlock *pb, NR_PIXBLOCK_MODE mode, int x0, int y0, int x1, int y1, unsigned char *px, int rs, bool empty, bool clear) +{ + int w, bpp; + + w = x1 - x0; + bpp = (mode == NR_PIXBLOCK_MODE_A8) ? 1 : (mode == NR_PIXBLOCK_MODE_R8G8B8) ? 3 : 4; + + pb->size = NR_PIXBLOCK_SIZE_STATIC; + pb->mode = mode; + pb->empty = empty; + pb->area.x0 = x0; + pb->area.y0 = y0; + pb->area.x1 = x1; + pb->area.y1 = y1; + pb->data.px = px; + pb->rs = rs; + + g_assert (pb->data.px != NULL); + if (clear) { + if (rs == bpp * w) { + /// \todo How do you recognise if + /// px was an uncleared tiny buffer? + if (pb->data.px) + memset (pb->data.px, 0x0, bpp * (y1 - y0) * w); + } else { + int y; + for (y = y0; y < y1; y++) { + memset (pb->data.px + (y - y0) * rs, 0x0, bpp * w); + } + } + } +} + +/** + * Frees memory taken by pixel data in NRPixBlock. + * \param pb Pointer to pixblock. + * \pre pb and pb->data.px point to valid addresses. + * + * According to pb->size, one of the functions for freeing the pixelstore + * is called. May be called regardless of how pixbuf was set up. + */ +void +nr_pixblock_release (NRPixBlock *pb) +{ + switch (pb->size) { + case NR_PIXBLOCK_SIZE_TINY: + break; + case NR_PIXBLOCK_SIZE_4K: + nr_pixelstore_4K_free (pb->data.px); + break; + case NR_PIXBLOCK_SIZE_16K: + nr_pixelstore_16K_free (pb->data.px); + break; + case NR_PIXBLOCK_SIZE_64K: + nr_pixelstore_64K_free (pb->data.px); + break; + case NR_PIXBLOCK_SIZE_256K: + nr_pixelstore_256K_free (pb->data.px); + break; + case NR_PIXBLOCK_SIZE_1M: + nr_pixelstore_1M_free (pb->data.px); + break; + case NR_PIXBLOCK_SIZE_BIG: + nr_free (pb->data.px); + break; + case NR_PIXBLOCK_SIZE_STATIC: + break; + default: + break; + } +} + +/** + * Allocates NRPixBlock and sets it up. + * + * \return Pointer to fresh pixblock. + * Calls nr_new() and nr_pixblock_setup(). + */ +NRPixBlock * +nr_pixblock_new (NR_PIXBLOCK_MODE mode, int x0, int y0, int x1, int y1, bool clear) +{ + NRPixBlock *pb; + + pb = nr_new (NRPixBlock, 1); + + nr_pixblock_setup (pb, mode, x0, y0, x1, y1, clear); + + return pb; +} + +/** + * Frees all memory taken by pixblock. + * + * \return NULL + */ +NRPixBlock * +nr_pixblock_free (NRPixBlock *pb) +{ + nr_pixblock_release (pb); + + nr_free (pb); + + return NULL; +} + +/* PixelStore operations */ + +#define NR_4K_BLOCK 32 +static unsigned char **nr_4K_px = NULL; +static unsigned int nr_4K_len = 0; +static unsigned int nr_4K_size = 0; + +unsigned char * +nr_pixelstore_4K_new (bool clear, unsigned char val) +{ + unsigned char *px; + + if (nr_4K_len != 0) { + nr_4K_len -= 1; + px = nr_4K_px[nr_4K_len]; + } else { + px = nr_new (unsigned char, 4096); + } + + if (clear) memset (px, val, 4096); + + return px; +} + +void +nr_pixelstore_4K_free (unsigned char *px) +{ + if (nr_4K_len == nr_4K_size) { + nr_4K_size += NR_4K_BLOCK; + nr_4K_px = nr_renew (nr_4K_px, unsigned char *, nr_4K_size); + } + + nr_4K_px[nr_4K_len] = px; + nr_4K_len += 1; +} + +#define NR_16K_BLOCK 32 +static unsigned char **nr_16K_px = NULL; +static unsigned int nr_16K_len = 0; +static unsigned int nr_16K_size = 0; + +unsigned char * +nr_pixelstore_16K_new (bool clear, unsigned char val) +{ + unsigned char *px; + + if (nr_16K_len != 0) { + nr_16K_len -= 1; + px = nr_16K_px[nr_16K_len]; + } else { + px = nr_new (unsigned char, 16384); + } + + if (clear) memset (px, val, 16384); + + return px; +} + +void +nr_pixelstore_16K_free (unsigned char *px) +{ + if (nr_16K_len == nr_16K_size) { + nr_16K_size += NR_16K_BLOCK; + nr_16K_px = nr_renew (nr_16K_px, unsigned char *, nr_16K_size); + } + + nr_16K_px[nr_16K_len] = px; + nr_16K_len += 1; +} + +#define NR_64K_BLOCK 32 +static unsigned char **nr_64K_px = NULL; +static unsigned int nr_64K_len = 0; +static unsigned int nr_64K_size = 0; + +unsigned char * +nr_pixelstore_64K_new (bool clear, unsigned char val) +{ + unsigned char *px; + + if (nr_64K_len != 0) { + nr_64K_len -= 1; + px = nr_64K_px[nr_64K_len]; + } else { + px = nr_new (unsigned char, 65536); + } + + if (clear) memset (px, val, 65536); + + return px; +} + +void +nr_pixelstore_64K_free (unsigned char *px) +{ + if (nr_64K_len == nr_64K_size) { + nr_64K_size += NR_64K_BLOCK; + nr_64K_px = nr_renew (nr_64K_px, unsigned char *, nr_64K_size); + } + + nr_64K_px[nr_64K_len] = px; + nr_64K_len += 1; +} + +#define NR_256K_BLOCK 32 +#define NR_256K 262144 +static unsigned char **nr_256K_px = NULL; +static unsigned int nr_256K_len = 0; +static unsigned int nr_256K_size = 0; + +unsigned char * +nr_pixelstore_256K_new (bool clear, unsigned char val) +{ + unsigned char *px; + + if (nr_256K_len != 0) { + nr_256K_len -= 1; + px = nr_256K_px[nr_256K_len]; + } else { + px = nr_new (unsigned char, NR_256K); + } + + if (clear) memset (px, val, NR_256K); + + return px; +} + +void +nr_pixelstore_256K_free (unsigned char *px) +{ + if (nr_256K_len == nr_256K_size) { + nr_256K_size += NR_256K_BLOCK; + nr_256K_px = nr_renew (nr_256K_px, unsigned char *, nr_256K_size); + } + + nr_256K_px[nr_256K_len] = px; + nr_256K_len += 1; +} + +#define NR_1M_BLOCK 32 +#define NR_1M 1048576 +static unsigned char **nr_1M_px = NULL; +static unsigned int nr_1M_len = 0; +static unsigned int nr_1M_size = 0; + +unsigned char * +nr_pixelstore_1M_new (bool clear, unsigned char val) +{ + unsigned char *px; + + if (nr_1M_len != 0) { + nr_1M_len -= 1; + px = nr_1M_px[nr_1M_len]; + } else { + px = nr_new (unsigned char, NR_1M); + } + + if (clear) memset (px, val, NR_1M); + + return px; +} + +void +nr_pixelstore_1M_free (unsigned char *px) +{ + if (nr_1M_len == nr_1M_size) { + nr_1M_size += NR_1M_BLOCK; + nr_1M_px = nr_renew (nr_1M_px, unsigned char *, nr_1M_size); + } + + nr_1M_px[nr_1M_len] = px; + nr_1M_len += 1; +} + +/* + 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:textwidth=99 : diff --git a/src/libnr/nr-pixblock.h b/src/libnr/nr-pixblock.h new file mode 100644 index 000000000..2a13dd921 --- /dev/null +++ b/src/libnr/nr-pixblock.h @@ -0,0 +1,95 @@ +#ifndef __NR_PIXBLOCK_H__ +#define __NR_PIXBLOCK_H__ + +/** \file + * \brief Pixel block structure. Used for low-level rendering. + * + * Authors: + * (C) 1999-2002 Lauris Kaplinski + * (C) 2005 Ralf Stephan (some cleanup) + * + * This code is in the Public Domain. + */ + +#include +#include + +/// Size indicator. Hardcoded to max. 3 bits. +typedef enum { + NR_PIXBLOCK_SIZE_TINY, ///< Fits in (unsigned char *) + NR_PIXBLOCK_SIZE_4K, ///< Pixelstore + NR_PIXBLOCK_SIZE_16K, ///< Pixelstore + NR_PIXBLOCK_SIZE_64K, ///< Pixelstore + NR_PIXBLOCK_SIZE_256K, ///< Pixelstore + NR_PIXBLOCK_SIZE_1M, ///< Pixelstore + NR_PIXBLOCK_SIZE_BIG, ///< Normally allocated + NR_PIXBLOCK_SIZE_STATIC ///< Externally managed +} NR_PIXBLOCK_SIZE; + +/// Mode indicator. Hardcoded to max. 2 bits. +typedef enum { + NR_PIXBLOCK_MODE_A8, ///< Grayscale + NR_PIXBLOCK_MODE_R8G8B8, ///< 8 bit RGB + NR_PIXBLOCK_MODE_R8G8B8A8N, ///< Normal 8 bit RGBA + NR_PIXBLOCK_MODE_R8G8B8A8P ///< Premultiplied 8 bit RGBA +} NR_PIXBLOCK_MODE; + +/// The pixel block struct. +struct NRPixBlock { + NR_PIXBLOCK_SIZE size : 3; ///< Size indicator + NR_PIXBLOCK_MODE mode : 2; ///< Mode indicator + bool empty : 1; ///< Empty flag + unsigned int rs; ///< Size of line in bytes + NRRectL area; + union { + unsigned char *px; ///< Pointer to buffer + unsigned char p[sizeof (unsigned char *)]; ///< Tiny buffer + } data; +}; + +/// Returns number of bytes per pixel (1, 3, or 4). +inline int +NR_PIXBLOCK_BPP (NRPixBlock *pb) +{ + return ((pb->mode == NR_PIXBLOCK_MODE_A8) ? 1 : + (pb->mode == NR_PIXBLOCK_MODE_R8G8B8) ? 3 : 4); +} + +/// Returns pointer to pixel data. +inline unsigned char* +NR_PIXBLOCK_PX (NRPixBlock *pb) +{ + return ((pb->size == NR_PIXBLOCK_SIZE_TINY) ? + pb->data.p : pb->data.px); +} + +void nr_pixblock_setup (NRPixBlock *pb, NR_PIXBLOCK_MODE mode, int x0, int y0, int x1, int y1, bool clear); +void nr_pixblock_setup_fast (NRPixBlock *pb, NR_PIXBLOCK_MODE mode, int x0, int y0, int x1, int y1, bool clear); +void nr_pixblock_setup_extern (NRPixBlock *pb, NR_PIXBLOCK_MODE mode, int x0, int y0, int x1, int y1, unsigned char *px, int rs, bool empty, bool clear); +void nr_pixblock_release (NRPixBlock *pb); + +NRPixBlock *nr_pixblock_new (NR_PIXBLOCK_MODE mode, int x0, int y0, int x1, int y1, bool clear); +NRPixBlock *nr_pixblock_free (NRPixBlock *pb); + +unsigned char *nr_pixelstore_4K_new (bool clear, unsigned char val); +void nr_pixelstore_4K_free (unsigned char *px); +unsigned char *nr_pixelstore_16K_new (bool clear, unsigned char val); +void nr_pixelstore_16K_free (unsigned char *px); +unsigned char *nr_pixelstore_64K_new (bool clear, unsigned char val); +void nr_pixelstore_64K_free (unsigned char *px); +unsigned char *nr_pixelstore_256K_new (bool clear, unsigned char val); +void nr_pixelstore_256K_free (unsigned char *px); +unsigned char *nr_pixelstore_1M_new (bool clear, unsigned char val); +void nr_pixelstore_1M_free (unsigned char *px); + +#endif +/* + 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:textwidth=99 : diff --git a/src/libnr/nr-pixops.h b/src/libnr/nr-pixops.h new file mode 100644 index 000000000..32fc1e1cd --- /dev/null +++ b/src/libnr/nr-pixops.h @@ -0,0 +1,46 @@ +#ifndef __NR_PIXOPS_H__ +#define __NR_PIXOPS_H__ + +/* + * Pixel buffer rendering library + * + * Authors: + * Lauris Kaplinski + * bulia byak + * + * This code is in public domain + */ + +#define NR_RGBA32_R(v) (unsigned char) (((v) >> 24) & 0xff) +#define NR_RGBA32_G(v) (unsigned char) (((v) >> 16) & 0xff) +#define NR_RGBA32_B(v) (unsigned char) (((v) >> 8) & 0xff) +#define NR_RGBA32_A(v) (unsigned char) ((v) & 0xff) + +#define FAST_DIVIDE_BY_255(v) ((((v) << 8) + (v) + 257) >> 16) +#define NR_PREMUL(c,a) (FAST_DIVIDE_BY_255(((c) * (a) + 127))) +#define NR_PREMUL_SINGLE(c) (FAST_DIVIDE_BY_255((c) + 127)) +#define NR_A7(fa,ba) (65025 - (255 - fa) * (255 - ba)) +#define NR_A7_NORMALIZED(fa,ba) (FAST_DIVIDE_BY_255((65025 - (255 - (fa)) * (255 - (ba))) + 127)) +#define NR_COMPOSENNN_A7(fc,fa,bc,ba,a) (((255 - (fa)) * (bc) * (ba) + (fa) * (fc) * 255 + 127) / a) +#define NR_COMPOSEPNN_A7(fc,fa,bc,ba,a) (((255 - (fa)) * (bc) * (ba) + (fc) * 65025 + 127) / a) +#define NR_COMPOSENNP(fc,fa,bc,ba) (((255 - (fa)) * (bc) * (ba) + (fa) * (fc) * 255 + 32512) / 65025) +#define NR_COMPOSEPNP(fc,fa,bc,ba) (((255 - (fa)) * (bc) * (ba) + (fc) * 65025 + 32512) / 65025) +#define NR_COMPOSENPP(fc,fa,bc,ba) (FAST_DIVIDE_BY_255((255 - (fa)) * (bc) + (fa) * (fc) + 127)) +#define NR_COMPOSEPPP(fc,fa,bc,ba) (FAST_DIVIDE_BY_255((255 - (fa)) * (bc) + (fc) * 255 + 127)) +#define NR_COMPOSEP11(fc,fa,bc) (FAST_DIVIDE_BY_255((255 - (fa)) * (bc) + (fc) * 255 + 127)) +#define NR_COMPOSEN11(fc,fa,bc) (FAST_DIVIDE_BY_255((255 - (fa)) * (bc) + (fc) * (fa) + 127)) + +#define INK_COMPOSE(f,a,b) ( ( ((guchar) b) * ((guchar) (0xff - a)) + ((guchar) ((b ^ ~f) + b/4 - (b>127? 63 : 0))) * ((guchar) a) ) >>8) + +#endif + +/* + 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:textwidth=99 : diff --git a/src/libnr/nr-point-fns-test.cpp b/src/libnr/nr-point-fns-test.cpp new file mode 100644 index 000000000..11181436b --- /dev/null +++ b/src/libnr/nr-point-fns-test.cpp @@ -0,0 +1,107 @@ +#include +#include +#include +#include + +#include "utest/utest.h" +#include "libnr/nr-point-fns.h" +#include "isnan.h" + +using NR::Point; + +int main(int argc, char *argv[]) +{ + utest_start("nr-point-fns"); + + Point const p3n4(3.0, -4.0); + Point const p0(0.0, 0.0); + double const small = pow(2.0, -1070); + double const inf = 1e400; + double const nan = inf - inf; + + Point const small_left(-small, 0.0); + Point const small_n3_4(-3.0 * small, 4.0 * small); + Point const part_nan(3., nan); + Point const inf_left(-inf, 5.0); + + assert(isNaN(nan)); + assert(!isNaN(small)); + + UTEST_TEST("L1") { + UTEST_ASSERT( NR::L1(p0) == 0.0 ); + UTEST_ASSERT( NR::L1(p3n4) == 7.0 ); + UTEST_ASSERT( NR::L1(small_left) == small ); + UTEST_ASSERT( NR::L1(inf_left) == inf ); + UTEST_ASSERT( NR::L1(small_n3_4) == 7.0 * small ); + UTEST_ASSERT(isNaN(NR::L1(part_nan))); + } + + UTEST_TEST("L2") { + UTEST_ASSERT( NR::L2(p0) == 0.0 ); + UTEST_ASSERT( NR::L2(p3n4) == 5.0 ); + UTEST_ASSERT( NR::L2(small_left) == small ); + UTEST_ASSERT( NR::L2(inf_left) == inf ); + UTEST_ASSERT( NR::L2(small_n3_4) == 5.0 * small ); + UTEST_ASSERT(isNaN(NR::L2(part_nan))); + } + + UTEST_TEST("LInfty") { + UTEST_ASSERT( NR::LInfty(p0) == 0.0 ); + UTEST_ASSERT( NR::LInfty(p3n4) == 4.0 ); + UTEST_ASSERT( NR::LInfty(small_left) == small ); + UTEST_ASSERT( NR::LInfty(inf_left) == inf ); + UTEST_ASSERT( NR::LInfty(small_n3_4) == 4.0 * small ); + UTEST_ASSERT(isNaN(NR::LInfty(part_nan))); + } + + UTEST_TEST("is_zero") { + UTEST_ASSERT(NR::is_zero(p0)); + UTEST_ASSERT(!NR::is_zero(p3n4)); + UTEST_ASSERT(!NR::is_zero(small_left)); + UTEST_ASSERT(!NR::is_zero(inf_left)); + UTEST_ASSERT(!NR::is_zero(small_n3_4)); + UTEST_ASSERT(!NR::is_zero(part_nan)); + } + + UTEST_TEST("atan2") { + UTEST_ASSERT( NR::atan2(p3n4) == atan2(-4.0, 3.0) ); + UTEST_ASSERT( NR::atan2(small_left) == atan2(0.0, -1.0) ); + UTEST_ASSERT( NR::atan2(small_n3_4) == atan2(4.0, -3.0) ); + } + + UTEST_TEST("unit_vector") { + UTEST_ASSERT( NR::unit_vector(p3n4) == Point(.6, -0.8) ); + UTEST_ASSERT( NR::unit_vector(small_left) == Point(-1.0, 0.0) ); + UTEST_ASSERT( NR::unit_vector(small_n3_4) == Point(-.6, 0.8) ); + } + + UTEST_TEST("is_unit_vector") { + UTEST_ASSERT(!NR::is_unit_vector(p3n4)); + UTEST_ASSERT(!NR::is_unit_vector(small_left)); + UTEST_ASSERT(!NR::is_unit_vector(small_n3_4)); + UTEST_ASSERT(!NR::is_unit_vector(part_nan)); + UTEST_ASSERT(!NR::is_unit_vector(inf_left)); + UTEST_ASSERT(!NR::is_unit_vector(Point(.5, 0.5))); + UTEST_ASSERT(NR::is_unit_vector(Point(.6, -0.8))); + UTEST_ASSERT(NR::is_unit_vector(Point(-.6, 0.8))); + UTEST_ASSERT(NR::is_unit_vector(Point(-1.0, 0.0))); + UTEST_ASSERT(NR::is_unit_vector(Point(1.0, 0.0))); + UTEST_ASSERT(NR::is_unit_vector(Point(0.0, -1.0))); + UTEST_ASSERT(NR::is_unit_vector(Point(0.0, 1.0))); + } + + return ( utest_end() + ? EXIT_SUCCESS + : EXIT_FAILURE ); +} + +/* + 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:textwidth=99 : diff --git a/src/libnr/nr-point-fns-test.h b/src/libnr/nr-point-fns-test.h new file mode 100644 index 000000000..509d9d2fa --- /dev/null +++ b/src/libnr/nr-point-fns-test.h @@ -0,0 +1,141 @@ +// nr-point-fns-test.h +#include + +#include +#include +#include +#include + +#include "libnr/nr-point-fns.h" +#include "isnan.h" + +using NR::Point; + +class NrPointFnsTest : public CxxTest::TestSuite +{ +public: + NrPointFnsTest() : + setupValid(true), + p3n4( 3.0, -4.0 ), + p0( 0.0, 0.0 ), + small( pow( 2.0, -1070 ) ), + inf( 1e400 ), + nan( inf - inf ), + small_left( -small, 0.0 ), + small_n3_4( -3.0 * small, 4.0 * small ), + part_nan( 3., nan ), + inf_left( -inf, 5.0 ) + { + TS_ASSERT( isNaN(nan) ); + TS_ASSERT( !isNaN(small) ); + + setupValid &= isNaN(nan); + setupValid &= !isNaN(small); + } + virtual ~NrPointFnsTest() {} + +// createSuite and destroySuite get us per-suite setup and teardown +// without us having to worry about static initialization order, etc. + static NrPointFnsTest *createSuite() { return new NrPointFnsTest(); } + static void destroySuite( NrPointFnsTest *suite ) { delete suite; } + +// Called before each test in this suite + void setUp() + { + TS_ASSERT( setupValid ); + } + + bool setupValid; + Point const p3n4; + Point const p0; + double const small; + double const inf; + double const nan; + + Point const small_left; + Point const small_n3_4; + Point const part_nan; + Point const inf_left; + + + void testL1(void) + { + TS_ASSERT_EQUALS( NR::L1(p0), 0.0 ); + TS_ASSERT_EQUALS( NR::L1(p3n4), 7.0 ); + TS_ASSERT_EQUALS( NR::L1(small_left), small ); + TS_ASSERT_EQUALS( NR::L1(inf_left), inf ); + TS_ASSERT_EQUALS( NR::L1(small_n3_4), 7.0 * small ); + TS_ASSERT(isNaN(NR::L1(part_nan))); + } + + void testL2(void) + { + TS_ASSERT_EQUALS( NR::L2(p0), 0.0 ); + TS_ASSERT_EQUALS( NR::L2(p3n4), 5.0 ); + TS_ASSERT_EQUALS( NR::L2(small_left), small ); + TS_ASSERT_EQUALS( NR::L2(inf_left), inf ); + TS_ASSERT_EQUALS( NR::L2(small_n3_4), 5.0 * small ); + TS_ASSERT( isNaN(NR::L2(part_nan)) ); + } + + void testLInfty(void) + { + TS_ASSERT_EQUALS( NR::LInfty(p0), 0.0 ); + TS_ASSERT_EQUALS( NR::LInfty(p3n4), 4.0 ); + TS_ASSERT_EQUALS( NR::LInfty(small_left), small ); + TS_ASSERT_EQUALS( NR::LInfty(inf_left), inf ); + TS_ASSERT_EQUALS( NR::LInfty(small_n3_4), 4.0 * small ); + TS_ASSERT( isNaN(NR::LInfty(part_nan)) ); + } + + void testIsZero(void) + { + TS_ASSERT( NR::is_zero(p0) ); + TS_ASSERT( !NR::is_zero(p3n4) ); + TS_ASSERT( !NR::is_zero(small_left) ); + TS_ASSERT( !NR::is_zero(inf_left) ); + TS_ASSERT( !NR::is_zero(small_n3_4) ); + TS_ASSERT( !NR::is_zero(part_nan) ); + } + + void testAtan2(void) + { + TS_ASSERT_EQUALS( NR::atan2(p3n4), atan2(-4.0, 3.0) ); + TS_ASSERT_EQUALS( NR::atan2(small_left), atan2(0.0, -1.0) ); + TS_ASSERT_EQUALS( NR::atan2(small_n3_4), atan2(4.0, -3.0) ); + } + + void testUnitVector(void) + { + TS_ASSERT_EQUALS( NR::unit_vector(p3n4), Point(.6, -0.8) ); + TS_ASSERT_EQUALS( NR::unit_vector(small_left), Point(-1.0, 0.0) ); + TS_ASSERT_EQUALS( NR::unit_vector(small_n3_4), Point(-.6, 0.8) ); + } + + void testIsUnitVector(void) + { + TS_ASSERT( !NR::is_unit_vector(p3n4) ); + TS_ASSERT( !NR::is_unit_vector(small_left) ); + TS_ASSERT( !NR::is_unit_vector(small_n3_4) ); + TS_ASSERT( !NR::is_unit_vector(part_nan) ); + TS_ASSERT( !NR::is_unit_vector(inf_left) ); + TS_ASSERT( !NR::is_unit_vector(Point(.5, 0.5)) ); + TS_ASSERT( NR::is_unit_vector(Point(.6, -0.8)) ); + TS_ASSERT( NR::is_unit_vector(Point(-.6, 0.8)) ); + TS_ASSERT( NR::is_unit_vector(Point(-1.0, 0.0)) ); + TS_ASSERT( NR::is_unit_vector(Point(1.0, 0.0)) ); + TS_ASSERT( NR::is_unit_vector(Point(0.0, -1.0)) ); + TS_ASSERT( NR::is_unit_vector(Point(0.0, 1.0)) ); + } +}; + +/* + 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:textwidth=99 : diff --git a/src/libnr/nr-point-fns.cpp b/src/libnr/nr-point-fns.cpp new file mode 100644 index 000000000..a92c2b00b --- /dev/null +++ b/src/libnr/nr-point-fns.cpp @@ -0,0 +1,74 @@ +#include +#include + +using NR::Point; + +/** Compute the L infinity, or maximum, norm of \a p. */ +NR::Coord NR::LInfty(Point const &p) { + NR::Coord const a(fabs(p[0])); + NR::Coord const b(fabs(p[1])); + return ( a < b || isNaN(b) + ? b + : a ); +} + +/** Returns true iff p is a zero vector, i.e.\ Point(0, 0). + * + * (NaN is considered non-zero.) + */ +bool +NR::is_zero(Point const &p) +{ + return ( p[0] == 0 && + p[1] == 0 ); +} + +bool +NR::is_unit_vector(Point const &p) +{ + return fabs(1.0 - L2(p)) <= 1e-4; + /* The tolerance of 1e-4 is somewhat arbitrary. NR::Point::normalize is believed to return + points well within this tolerance. I'm not aware of any callers that want a small + tolerance; most callers would be ok with a tolerance of 0.25. */ +} + +NR::Coord NR::atan2(Point const p) { + return std::atan2(p[NR::Y], p[NR::X]); +} + +/** Returns a version of \a a scaled to be a unit vector (within rounding error). + * + * The current version tries to handle infinite coordinates gracefully, + * but it's not clear that any callers need that. + * + * \pre a != Point(0, 0). + * \pre Neither coordinate is NaN. + * \post L2(ret) very near 1.0. + */ +Point NR::unit_vector(Point const &a) +{ + Point ret(a); + ret.normalize(); + return ret; +} + +NR::Point abs(NR::Point const &b) +{ + NR::Point ret; + for ( int i = 0 ; i < 2 ; i++ ) { + ret[i] = fabs(b[i]); + } + return ret; +} + + +/* + 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:textwidth=99 : diff --git a/src/libnr/nr-point-fns.h b/src/libnr/nr-point-fns.h new file mode 100644 index 000000000..9f9a8f9e2 --- /dev/null +++ b/src/libnr/nr-point-fns.h @@ -0,0 +1,104 @@ +#ifndef __NR_POINT_OPS_H__ +#define __NR_POINT_OPS_H__ + +#include +#include +#include + +namespace NR { + +/** Compute the L1 norm, or manhattan distance, of \a p. */ +inline Coord L1(Point const &p) { + Coord d = 0; + for ( int i = 0 ; i < 2 ; i++ ) { + d += fabs(p[i]); + } + return d; +} + +/** Compute the L2, or euclidean, norm of \a p. */ +inline Coord L2(Point const &p) { + return hypot(p[0], p[1]); +} + +extern double LInfty(Point const &p); + +bool is_zero(Point const &p); + +bool is_unit_vector(Point const &p); + +extern double atan2(Point const p); + +inline bool point_equalp(Point const &a, Point const &b, double const eps) +{ + return ( NR_DF_TEST_CLOSE(a[X], b[X], eps) && + NR_DF_TEST_CLOSE(a[Y], b[Y], eps) ); +} + +/** Returns p * NR::rotate_degrees(90), but more efficient. + * + * Angle direction in Inkscape code: If you use the traditional mathematics convention that y + * increases upwards, then positive angles are anticlockwise as per the mathematics convention. If + * you take the common non-mathematical convention that y increases downwards, then positive angles + * are clockwise, as is common outside of mathematics. + * + * There is no rot_neg90 function: use -rot90(p) instead. + */ +inline Point rot90(Point const &p) +{ + return Point(-p[Y], p[X]); +} + +/** Given two points and a parameter t \in [0, 1], return a point + * proportionally from a to b by t. */ +inline Point Lerp(double const t, Point const a, Point const b) +{ + return ( ( 1 - t ) * a + + t * b ); +} + +Point unit_vector(Point const &a); + +inline Coord dot(Point const &a, Point const &b) +{ + Coord ret = 0; + for ( int i = 0 ; i < 2 ; i++ ) { + ret += a[i] * b[i]; + } + return ret; +} + +inline Coord distance (Point const &a, Point const &b) +{ + Coord ret = 0; + for ( int i = 0 ; i < 2 ; i++ ) { + ret += (a[i] - b[i]) * (a[i] - b[i]); + } + return sqrt (ret); +} + +/** Defined as dot(a, b.cw()). */ +inline Coord cross(Point const &a, Point const &b) +{ + Coord ret = 0; + ret -= a[0] * b[1]; + ret += a[1] * b[0]; + return ret; +} + +Point abs(Point const &b); + +} /* namespace NR */ + +#endif /* !__NR_POINT_OPS_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:encoding=utf-8:textwidth=99 : diff --git a/src/libnr/nr-point-l.h b/src/libnr/nr-point-l.h new file mode 100644 index 000000000..8ddfd5e6f --- /dev/null +++ b/src/libnr/nr-point-l.h @@ -0,0 +1,95 @@ +#ifndef SEEN_NR_POINT_L_H +#define SEEN_NR_POINT_L_H + +#include +#include +#include + +struct NRPointL { + NR::ICoord x, y; +}; + +namespace NR { + +class IPoint { +public: + IPoint() + { } + + IPoint(ICoord x, ICoord y) { + _pt[X] = x; + _pt[Y] = y; + } + + IPoint(NRPointL const &p) { + _pt[X] = p.x; + _pt[Y] = p.y; + } + + IPoint(IPoint const &p) { + for (unsigned i = 0; i < 2; ++i) { + _pt[i] = p._pt[i]; + } + } + + IPoint &operator=(IPoint const &p) { + for (unsigned i = 0; i < 2; ++i) { + _pt[i] = p._pt[i]; + } + return *this; + } + + operator Point() { + return Point(_pt[X], _pt[Y]); + } + + ICoord operator[](unsigned i) const throw(std::out_of_range) { + if ( i > Y ) { + throw std::out_of_range("index out of range"); + } + return _pt[i]; + } + + ICoord &operator[](unsigned i) throw(std::out_of_range) { + if ( i > Y ) { + throw std::out_of_range("index out of range"); + } + return _pt[i]; + } + + ICoord operator[](Dim2 d) const throw() { return _pt[d]; } + ICoord &operator[](Dim2 d) throw() { return _pt[d]; } + + IPoint &operator+=(IPoint const &o) { + for ( unsigned i = 0 ; i < 2 ; ++i ) { + _pt[i] += o._pt[i]; + } + return *this; + } + + IPoint &operator-=(IPoint const &o) { + for ( unsigned i = 0 ; i < 2 ; ++i ) { + _pt[i] -= o._pt[i]; + } + return *this; + } + +private: + ICoord _pt[2]; +}; + + +} // namespace NR + +#endif /* !SEEN_NR_POINT_L_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:encoding=utf-8:textwidth=99 : diff --git a/src/libnr/nr-point-matrix-ops.h b/src/libnr/nr-point-matrix-ops.h new file mode 100644 index 000000000..58e06fc6d --- /dev/null +++ b/src/libnr/nr-point-matrix-ops.h @@ -0,0 +1,47 @@ +/** \file operator functions over (NR::Point, NR::Matrix). */ +#ifndef SEEN_NR_POINT_MATRIX_OPS_H +#define SEEN_NR_POINT_MATRIX_OPS_H + +#include "libnr/nr-point.h" +#include "libnr/nr-matrix.h" + +namespace NR { + +inline Point operator*(Point const &v, Matrix const &m) +{ +#if 1 /* Which code makes it easier to see what's happening? */ + NR::Point const xform_col0(m[0], + m[2]); + NR::Point const xform_col1(m[1], + m[3]); + NR::Point const xlate(m[4], m[5]); + return ( Point(dot(v, xform_col0), + dot(v, xform_col1)) + + xlate ); +#else + return Point(v[X] * m[0] + v[Y] * m[2] + m[4], + v[X] * m[1] + v[Y] * m[3] + m[5]); +#endif +} + +inline Point &Point::operator*=(Matrix const &m) +{ + *this = *this * m; + return *this; +} + +} /* namespace NR */ + + +#endif /* !SEEN_NR_POINT_MATRIX_OPS_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:encoding=utf-8:textwidth=99 : diff --git a/src/libnr/nr-point-ops.h b/src/libnr/nr-point-ops.h new file mode 100644 index 000000000..03d61fb15 --- /dev/null +++ b/src/libnr/nr-point-ops.h @@ -0,0 +1,88 @@ +/* operator functions for NR::Point. */ +#ifndef SEEN_NR_POINT_OPS_H +#define SEEN_NR_POINT_OPS_H + +#include + +namespace NR { + +inline Point operator+(Point const &a, Point const &b) +{ + Point ret; + for (int i = 0; i < 2; i++) { + ret[i] = a[i] + b[i]; + } + return ret; +} + +inline Point operator-(Point const &a, Point const &b) +{ + Point ret; + for (int i = 0; i < 2; i++) { + ret[i] = a[i] - b[i]; + } + return ret; +} + +/** This is a rotation (sort of). */ +inline Point operator^(Point const &a, Point const &b) +{ + Point const ret(a[0] * b[0] - a[1] * b[1], + a[1] * b[0] + a[0] * b[1]); + return ret; +} + +inline Point operator-(Point const &a) +{ + Point ret; + for(unsigned i = 0; i < 2; i++) { + ret[i] = -a[i]; + } + return ret; +} + +inline Point operator*(double const s, Point const &b) +{ + Point ret; + for(int i = 0; i < 2; i++) { + ret[i] = s * b[i]; + } + return ret; +} + +inline Point operator/(Point const &b, double const d) +{ + Point ret; + for(int i = 0; i < 2; i++) { + ret[i] = b[i] / d; + } + return ret; +} + + +inline bool operator==(Point const &a, Point const &b) +{ + return ( ( a[X] == b[X] ) && ( a[Y] == b[Y] ) ); +} + +inline bool operator!=(Point const &a, Point const &b) +{ + return ( ( a[X] != b[X] ) || ( a[Y] != b[Y] ) ); +} + + +} /* namespace NR */ + + +#endif /* !SEEN_NR_POINT_OPS_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:encoding=utf-8:textwidth=99 : diff --git a/src/libnr/nr-point.h b/src/libnr/nr-point.h new file mode 100644 index 000000000..f67a66800 --- /dev/null +++ b/src/libnr/nr-point.h @@ -0,0 +1,159 @@ +#ifndef SEEN_NR_POINT_H +#define SEEN_NR_POINT_H + +/** \file + * Cartesian point class. + */ + +//#include +//#include +#include +//#include + +#include +#include + +//#include "round.h" +#include "decimal-round.h" + +/// A NRPoint consists of x and y coodinates. +/// \todo +/// This class appears to be obsoleted out in favour of NR::Point. +struct NRPoint { + NR::Coord x, y; +}; + +namespace NR { + +class Matrix; + +/// Cartesian point. +class Point { +public: + inline Point() + { _pt[X] = _pt[Y] = 0; } + + inline Point(Coord x, Coord y) { + _pt[X] = x; + _pt[Y] = y; + } + + inline Point(NRPoint const &p) { + _pt[X] = p.x; + _pt[Y] = p.y; + } + + inline Point(Point const &p) { + for (unsigned i = 0; i < 2; ++i) { + _pt[i] = p._pt[i]; + } + } + + inline Point &operator=(Point const &p) { + for (unsigned i = 0; i < 2; ++i) { + _pt[i] = p._pt[i]; + } + return *this; + } + + inline Coord operator[](unsigned i) const { + return _pt[i]; + } + + inline Coord &operator[](unsigned i) { + return _pt[i]; + } + + Coord operator[](Dim2 d) const throw() { return _pt[d]; } + Coord &operator[](Dim2 d) throw() { return _pt[d]; } + + /** Return a point like this point but rotated -90 degrees. + (If the y axis grows downwards and the x axis grows to the + right, then this is 90 degrees counter-clockwise.) + **/ + Point ccw() const { + return Point(_pt[Y], -_pt[X]); + } + + /** Return a point like this point but rotated +90 degrees. + (If the y axis grows downwards and the x axis grows to the + right, then this is 90 degrees clockwise.) + **/ + Point cw() const { + return Point(-_pt[Y], _pt[X]); + } + + /** + \brief A function to lower the precision of the point + \param places The number of decimal places that should be in + the final number. + */ + inline void round (int places = 0) { + _pt[X] = (Coord)(Inkscape::decimal_round((double)_pt[X], places)); + _pt[Y] = (Coord)(Inkscape::decimal_round((double)_pt[Y], places)); + return; + } + + void normalize(); + + inline Point &operator+=(Point const &o) { + for ( unsigned i = 0 ; i < 2 ; ++i ) { + _pt[i] += o._pt[i]; + } + return *this; + } + + inline Point &operator-=(Point const &o) { + for ( unsigned i = 0 ; i < 2 ; ++i ) { + _pt[i] -= o._pt[i]; + } + return *this; + } + + inline Point &operator/=(double const s) { + for ( unsigned i = 0 ; i < 2 ; ++i ) { + _pt[i] /= s; + } + return *this; + } + + inline Point &operator*=(double const s) { + for ( unsigned i = 0 ; i < 2 ; ++i ) { + _pt[i] *= s; + } + return *this; + } + + Point &operator*=(Matrix const &m); + + inline int operator == (const Point &in_pnt) { + return ((_pt[X] == in_pnt[X]) && (_pt[Y] == in_pnt[Y])); + } + + friend inline std::ostream &operator<< (std::ostream &out_file, const NR::Point &in_pnt); + +private: + Coord _pt[2]; +}; + +/** A function to print out the Point. It just prints out the coords + on the given output stream */ +inline std::ostream &operator<< (std::ostream &out_file, const NR::Point &in_pnt) { + out_file << "X: " << in_pnt[X] << " Y: " << in_pnt[Y]; + return out_file; +} + +} /* namespace NR */ + +#endif /* !SEEN_NR_POINT_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:encoding=utf-8:textwidth=99 : diff --git a/src/libnr/nr-rect-l.cpp b/src/libnr/nr-rect-l.cpp new file mode 100644 index 000000000..40db67a1e --- /dev/null +++ b/src/libnr/nr-rect-l.cpp @@ -0,0 +1,22 @@ +#include + +namespace NR { + +IRect::IRect(Rect const &r) : + _min(int(floor(r.min()[X])), int(floor(r.min()[Y]))), + _max(int(ceil(r.min()[X])), int(ceil(r.min()[Y]))) +{ +} + +} + +/* + 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:textwidth=99 : diff --git a/src/libnr/nr-rect-l.h b/src/libnr/nr-rect-l.h new file mode 100644 index 000000000..756a537b0 --- /dev/null +++ b/src/libnr/nr-rect-l.h @@ -0,0 +1,131 @@ +#ifndef SEEN_NR_RECT_L_H +#define SEEN_NR_RECT_L_H + +#include + +struct NRRectL { + NR::ICoord x0, y0, x1, y1; +}; + +#include +#include + +namespace NR { + + +class IRect { +public: + IRect(const NRRectL& r) : _min(r.x0, r.y0), _max(r.x1, r.y1) {} + IRect(const IRect& r) : _min(r._min), _max(r._max) {} + IRect(const IPoint &p0, const IPoint &p1); + + /** as not all Rects are representable by IRects this gives the smallest IRect that contains + * r. */ + IRect(const Rect& r); + + operator Rect() { + return Rect(Point(_min), Point(_max)); + } + + const IPoint &min() const { return _min; } + const IPoint &max() const { return _max; } + + /** returns a vector from min to max. */ + IPoint dimensions() const; + + /** does this rectangle have zero area? */ + bool isEmpty() const { + return isEmpty() && isEmpty(); + } + + bool intersects(const IRect &r) const { + return intersects(r) && intersects(r); + } + bool contains(const IRect &r) const { + return contains(r) && contains(r); + } + bool contains(const IPoint &p) const { + return contains(p) && contains(p); + } + + ICoord maxExtent() const { + return MAX(extent(), extent()); + } + + ICoord extent(Dim2 axis) const { + switch (axis) { + case X: return extent(); + case Y: return extent(); + }; + } + + ICoord extent(unsigned i) const throw(std::out_of_range) { + switch (i) { + case 0: return extent(); + case 1: return extent(); + default: throw std::out_of_range("Dimension out of range"); + }; + } + + /** Translates the rectangle by p. */ + void offset(IPoint p); + + /** Makes this rectangle large enough to include the point p. */ + void expandTo(IPoint p); + + /** Makes this rectangle large enough to include the rectangle r. */ + void expandTo(const IRect &r); + + /** Returns the set of points shared by both rectangles. */ + static Maybe intersection(const IRect &a, const IRect &b); + + /** Returns the smallest rectangle that encloses both rectangles. */ + static IRect union_bounds(const IRect &a, const IRect &b); + +private: + IRect() {} + + template + ICoord extent() const { + return _max[axis] - _min[axis]; + } + + template + bool isEmpty() const { + return !( _min[axis] < _max[axis] ); + } + + template + bool intersects(const IRect &r) const { + return _max[axis] >= r._min[axis] && _min[axis] <= r._max[axis]; + } + + template + bool contains(const IRect &r) const { + return contains(r._min) && contains(r._max); + } + + template + bool contains(const IPoint &p) const { + return p[axis] >= _min[axis] && p[axis] <= _max[axis]; + } + + IPoint _min, _max; +}; + + + +} // namespace NR + +#endif /* !SEEN_NR_RECT_L_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:encoding=utf-8:textwidth=99 : diff --git a/src/libnr/nr-rect-ops.h b/src/libnr/nr-rect-ops.h new file mode 100644 index 000000000..870091a94 --- /dev/null +++ b/src/libnr/nr-rect-ops.h @@ -0,0 +1,51 @@ +#ifndef SEEN_NR_RECT_OPS_H +#define SEEN_NR_RECT_OPS_H + +/* + * Rect operators + * + * Copyright 2004 MenTaLguY , + * bulia byak + * + * This code is licensed under the GNU GPL; see COPYING for more information. + */ + +#include + +namespace NR { + +inline Rect expand(Rect const &r, double by) { + NR::Point const p(by, by); + return Rect(r.min() + p, r.max() - p); +} + +inline Rect expand(Rect const &r, NR::Point by) { + return Rect(r.min() + by, r.max() - by); +} + +#if 0 +inline ConvexHull operator*(Rect const &r, Matrix const &m) { + /* FIXME: no mention of m. Should probably be made non-inline. */ + ConvexHull points(r.corner(0)); + for ( unsigned i = 1 ; i < 4 ; i++ ) { + points.add(r.corner(i)); + } + return points; +} +#endif + +} /* namespace NR */ + + +#endif /* !SEEN_NR_RECT_OPS_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 : diff --git a/src/libnr/nr-rect.cpp b/src/libnr/nr-rect.cpp new file mode 100644 index 000000000..0a8287bde --- /dev/null +++ b/src/libnr/nr-rect.cpp @@ -0,0 +1,233 @@ +#define __NR_RECT_C__ + +/* + * Pixel buffer rendering library + * + * Authors: + * Lauris Kaplinski + * + * This code is in public domain + */ + +#include "nr-rect-l.h" + +/** + * \param r0 Rectangle. + * \param r1 Another rectangle. + * \param d Filled in with the intersection of r0 and r1. + * \return d. + */ + +NRRectL *nr_rect_l_intersect(NRRectL *d, const NRRectL *r0, const NRRectL *r1) +{ + NR::ICoord t; + t = std::max(r0->x0, r1->x0); + d->x1 = std::min(r0->x1, r1->x1); + d->x0 = t; + t = std::max(r0->y0, r1->y0); + d->y1 = std::min(r0->y1, r1->y1); + d->y0 = t; + + return d; +} + +NRRect * +nr_rect_d_intersect (NRRect *d, const NRRect *r0, const NRRect *r1) +{ + NR::Coord t; + t = MAX (r0->x0, r1->x0); + d->x1 = MIN (r0->x1, r1->x1); + d->x0 = t; + t = MAX (r0->y0, r1->y0); + d->y1 = MIN (r0->y1, r1->y1); + d->y0 = t; + + return d; +} + +NRRect * +nr_rect_d_union (NRRect *d, const NRRect *r0, const NRRect *r1) +{ + if (NR_RECT_DFLS_TEST_EMPTY (r0)) { + if (NR_RECT_DFLS_TEST_EMPTY (r1)) { + nr_rect_d_set_empty (d); + } else { + *d = *r1; + } + } else { + if (NR_RECT_DFLS_TEST_EMPTY (r1)) { + *d = *r0; + } else { + NR::Coord t; + t = MIN (r0->x0, r1->x0); + d->x1 = MAX (r0->x1, r1->x1); + d->x0 = t; + t = MIN (r0->y0, r1->y0); + d->y1 = MAX (r0->y1, r1->y1); + d->y0 = t; + } + } + return d; +} + +NRRectL * +nr_rect_l_union (NRRectL *d, const NRRectL *r0, const NRRectL *r1) +{ + if (NR_RECT_DFLS_TEST_EMPTY (r0)) { + if (NR_RECT_DFLS_TEST_EMPTY (r1)) { + nr_rect_l_set_empty (d); + } else { + *d = *r1; + } + } else { + if (NR_RECT_DFLS_TEST_EMPTY (r1)) { + *d = *r0; + } else { + NR::ICoord t; + t = MIN (r0->x0, r1->x0); + d->x1 = MAX (r0->x1, r1->x1); + d->x0 = t; + t = MIN (r0->y0, r1->y0); + d->y1 = MAX (r0->y1, r1->y1); + d->y0 = t; + } + } + return d; +} + +NRRect * +nr_rect_union_pt(NRRect *dst, NR::Point const &p) +{ + using NR::X; + using NR::Y; + + return nr_rect_d_union_xy(dst, p[X], p[Y]); +} + +NRRect * +nr_rect_d_union_xy (NRRect *d, NR::Coord x, NR::Coord y) +{ + if ((d->x0 <= d->x1) && (d->y0 <= d->y1)) { + d->x0 = MIN (d->x0, x); + d->y0 = MIN (d->y0, y); + d->x1 = MAX (d->x1, x); + d->y1 = MAX (d->y1, y); + } else { + d->x0 = d->x1 = x; + d->y0 = d->y1 = y; + } + return d; +} + +NRRect * +nr_rect_d_matrix_transform(NRRect *d, NRRect const *const s, NR::Matrix const &m) +{ + using NR::X; + using NR::Y; + + if (nr_rect_d_test_empty(s)) { + nr_rect_d_set_empty(d); + } else { + NR::Point const c00(NR::Point(s->x0, s->y0) * m); + NR::Point const c01(NR::Point(s->x0, s->y1) * m); + NR::Point const c10(NR::Point(s->x1, s->y0) * m); + NR::Point const c11(NR::Point(s->x1, s->y1) * m); + d->x0 = std::min(std::min(c00[X], c01[X]), + std::min(c10[X], c11[X])); + d->y0 = std::min(std::min(c00[Y], c01[Y]), + std::min(c10[Y], c11[Y])); + d->x1 = std::max(std::max(c00[X], c01[X]), + std::max(c10[X], c11[X])); + d->y1 = std::max(std::max(c00[Y], c01[Y]), + std::max(c10[Y], c11[Y])); + } + return d; +} + +NRRect * +nr_rect_d_matrix_transform(NRRect *d, NRRect const *s, NRMatrix const *m) +{ + return nr_rect_d_matrix_transform(d, s, *m); +} + +namespace NR { + +Rect::Rect(const Point &p0, const Point &p1) +: _min(MIN(p0[X], p1[X]), MIN(p0[Y], p1[Y])), + _max(MAX(p0[X], p1[X]), MAX(p0[Y], p1[Y])) {} + +/** returns the four corners of the rectangle in the correct winding order */ +Point Rect::corner(unsigned i) const { + switch (i % 4) { + case 0: + return _min; + case 1: + return Point(_max[X], _min[Y]); + case 2: + return _max; + default: /* i.e. 3 */ + return Point(_min[X], _max[Y]); + } +} + +/** returns the midpoint of this rectangle */ +Point Rect::midpoint() const { + return ( _min + _max ) / 2; +} + +/** returns a vector from topleft to bottom right. */ +Point Rect::dimensions() const { + return _max - _min; +} + +/** Translates the rectangle by p. */ +void Rect::offset(Point p) { + _min += p; + _max += p; +} + +/** Makes this rectangle large enough to include the point p. */ +void Rect::expandTo(Point p) { + for ( int i=0 ; i < 2 ; i++ ) { + _min[i] = MIN(_min[i], p[i]); + _max[i] = MAX(_max[i], p[i]); + } +} + +/** Returns the set of points shared by both rectangles. */ +Maybe Rect::intersection(const Rect &a, const Rect &b) { + Rect r; + for ( int i=0 ; i < 2 ; i++ ) { + r._min[i] = MAX(a._min[i], b._min[i]); + r._max[i] = MIN(a._max[i], b._max[i]); + + if ( r._min[i] > r._max[i] ) { + return Nothing(); + } + } + return r; +} + +/** returns the smallest rectangle containing both rectangles */ +Rect Rect::union_bounds(const Rect &a, const Rect &b) { + Rect r; + for ( int i=0; i < 2 ; i++ ) { + r._min[i] = MIN(a._min[i], b._min[i]); + r._max[i] = MAX(a._max[i], b._max[i]); + } + return r; +} + +} // namespace NR + + +/* + 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 : diff --git a/src/libnr/nr-rect.h b/src/libnr/nr-rect.h new file mode 100644 index 000000000..219fbd1ac --- /dev/null +++ b/src/libnr/nr-rect.h @@ -0,0 +1,255 @@ +#ifndef LIBNR_NR_RECT_H_SEEN +#define LIBNR_NR_RECT_H_SEEN + +/** \file + * Definitions of NRRect and NR::Rect types, and some associated functions \& macros. + */ +/* + * Authors: + * Lauris Kaplinski + * Nathan Hurst + * MenTaLguY + * + * This code is in public domain + */ + + +#include + +#include "libnr/nr-values.h" +#include +#include +#include +#include +#include +#include + +struct NRMatrix; +namespace NR { + struct Matrix; +} + +/* NULL rect is infinite */ + +struct NRRect { + NR::Coord x0, y0, x1, y1; +}; + +inline bool empty(NRRect const &r) +{ + return ( ( r.x0 > r.x1 ) || + ( r.y0 > r.y1 ) ); +} + +#define nr_rect_d_set_empty(r) (*(r) = NR_RECT_EMPTY) +#define nr_rect_l_set_empty(r) (*(r) = NR_RECT_L_EMPTY) + +#define nr_rect_d_test_empty(r) ((r) && NR_RECT_DFLS_TEST_EMPTY(r)) +#define nr_rect_l_test_empty(r) ((r) && NR_RECT_DFLS_TEST_EMPTY(r)) + +#define nr_rect_d_test_intersect(r0,r1) \ + (!nr_rect_d_test_empty(r0) && !nr_rect_d_test_empty(r1) && \ + !((r0) && (r1) && !NR_RECT_DFLS_TEST_INTERSECT(r0, r1))) +#define nr_rect_l_test_intersect(r0,r1) \ + (!nr_rect_l_test_empty(r0) && !nr_rect_l_test_empty(r1) && \ + !((r0) && (r1) && !NR_RECT_DFLS_TEST_INTERSECT(r0, r1))) + +#define nr_rect_d_point_d_test_inside(r,p) ((p) && (!(r) || (!NR_RECT_DF_TEST_EMPTY(r) && NR_RECT_DF_POINT_DF_TEST_INSIDE(r,p)))) + +/* NULL values are OK for r0 and r1, but not for d */ +NRRect *nr_rect_d_intersect(NRRect *d, NRRect const *r0, NRRect const *r1); +NRRectL *nr_rect_l_intersect(NRRectL *d, NRRectL const *r0, NRRectL const *r1); + +NRRect *nr_rect_d_union(NRRect *d, NRRect const *r0, NRRect const *r1); +NRRectL *nr_rect_l_union(NRRectL *d, NRRectL const *r0, NRRectL const *r1); + +NRRect *nr_rect_union_pt(NRRect *dst, NR::Point const &p); +NRRect *nr_rect_d_union_xy(NRRect *d, NR::Coord x, NR::Coord y); +NRRectL *nr_rect_l_union_xy(NRRectL *d, NR::ICoord x, NR::ICoord y); + +NRRect *nr_rect_d_matrix_transform(NRRect *d, NRRect const *s, NR::Matrix const &m); +NRRect *nr_rect_d_matrix_transform(NRRect *d, NRRect const *s, NRMatrix const *m); + +namespace NR { + +/** A rectangle is always aligned to the X and Y axis. This means it + * can be defined using only 4 coordinates, and determining + * intersection is very efficient. The points inside a rectangle are + * min[dim] <= _pt[dim] <= max[dim]. Emptiness, however, is defined + * as having zero area, meaning an empty rectangle may still contain + * points. Infinities are also permitted. */ +class Rect { +public: + Rect(NRRect const &r) : _min(r.x0, r.y0), _max(r.x1, r.y1) {} + Rect(Rect const &r) : _min(r._min), _max(r._max) {} + Rect(Point const &p0, Point const &p1); + + Point const &min() const { return _min; } + Point const &max() const { return _max; } + + /** returns the four corners of the rectangle in order + * (clockwise if +Y is up, anticlockwise if +Y is down) */ + Point corner(unsigned i) const; + + /** returns a vector from min to max. */ + Point dimensions() const; + + /** returns the midpoint of this rect. */ + Point midpoint() const; + + /** does this rectangle have zero area? */ + bool isEmpty() const { + return isEmpty() || isEmpty(); + } + + bool intersects(Rect const &r) const { + return intersects(r) && intersects(r); + } + bool contains(Rect const &r) const { + return contains(r) && contains(r); + } + bool contains(Point const &p) const { + return contains(p) && contains(p); + } + + double area() const { + return extent() * extent(); + } + + double maxExtent() const { + return MAX(extent(), extent()); + } + + double extent(Dim2 const axis) const { + switch (axis) { + case X: return extent(); + case Y: return extent(); + default: g_error("invalid axis value %d", (int) axis); return 0; + }; + } + + double extent(unsigned i) const throw(std::out_of_range) { + switch (i) { + case 0: return extent(); + case 1: return extent(); + default: throw std::out_of_range("Dimension out of range"); + }; + } + + /** + \brief Remove some precision from the Rect + \param places The number of decimal places left in the end + + This function just calls round on the \c _min and \c _max points. + */ + inline void round(int places = 0) { + _min.round(places); + _max.round(places); + return; + } + + /** Translates the rectangle by p. */ + void offset(Point p); + + /** Makes this rectangle large enough to include the point p. */ + void expandTo(Point p); + + /** Makes this rectangle large enough to include the rectangle r. */ + void expandTo(Rect const &r); + + inline void move_left (gdouble by) { + _min[NR::X] += by; + } + inline void move_right (gdouble by) { + _max[NR::X] += by; + } + inline void move_top (gdouble by) { + _min[NR::Y] += by; + } + inline void move_bottom (gdouble by) { + _max[NR::Y] += by; + } + + /** Returns the set of points shared by both rectangles. */ + static Maybe intersection(Rect const &a, Rect const &b); + + /** Returns the smallest rectangle that encloses both rectangles. */ + static Rect union_bounds(Rect const &a, Rect const &b); + + /** Scales the rect by s, with origin at 0, 0 */ + inline Rect operator*(double const s) const { + return Rect(s * min(), s * max()); + } + + /** Transforms the rect by m. Note that it gives correct results only for scales and translates */ + inline Rect operator*(Matrix const m) const { + return Rect(_min * m, _max * m); + } + + inline bool operator==(Rect const &in_rect) { + return ((this->min() == in_rect.min()) && (this->max() == in_rect.max())); + } + + friend inline std::ostream &operator<<(std::ostream &out_file, NR::Rect const &in_rect); + +private: + Rect() {} + + template + double extent() const { + return _max[axis] - _min[axis]; + } + + template + bool isEmpty() const { + return !( _min[axis] < _max[axis] ); + } + + template + bool intersects(Rect const &r) const { + return _max[axis] >= r._min[axis] && _min[axis] <= r._max[axis]; + } + + template + bool contains(Rect const &r) const { + return contains(r._min) && contains(r._max); + } + + template + bool contains(Point const &p) const { + return p[axis] >= _min[axis] && p[axis] <= _max[axis]; + } + + Point _min, _max; + + /* evil, but temporary */ + friend class Maybe; +}; + +/** A function to print out the rectange if sent to an output + stream. */ +inline std::ostream +&operator<<(std::ostream &out_file, NR::Rect const &in_rect) +{ + out_file << "Rectangle:\n"; + out_file << "\tMin Point -> " << in_rect.min() << "\n"; + out_file << "\tMax Point -> " << in_rect.max() << "\n"; + + return out_file; +} + +} /* namespace NR */ + + +#endif /* !LIBNR_NR_RECT_H_SEEN */ + +/* + 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:textwidth=99 : diff --git a/src/libnr/nr-render.h b/src/libnr/nr-render.h new file mode 100644 index 000000000..84215b7a3 --- /dev/null +++ b/src/libnr/nr-render.h @@ -0,0 +1,25 @@ +#ifndef __NR_RENDER_H__ +#define __NR_RENDER_H__ + +/* + * Pixel buffer rendering library + * + * Authors: + * Lauris Kaplinski + * + * This code is in public domain + */ + +#include + +struct NRRenderer; + +typedef void (* NRRenderFunc) (NRRenderer *r, NRPixBlock *pb, NRPixBlock *m); + +struct NRRenderer { + NRRenderFunc render; +}; + +#define nr_render(r,pb,m) ((NRRenderer *) (r))->render ((NRRenderer *) (r), (pb), (m)) + +#endif diff --git a/src/libnr/nr-rotate-fns-test.cpp b/src/libnr/nr-rotate-fns-test.cpp new file mode 100644 index 000000000..45b2450e0 --- /dev/null +++ b/src/libnr/nr-rotate-fns-test.cpp @@ -0,0 +1,43 @@ +#include +#include + +#include +#include + +int main(int argc, char *argv[]) +{ + utest_start("rotate-fns"); + + UTEST_TEST("rotate_degrees") { + double const d[] = { + 0, 90, 180, 270, 360, 45, 45.01, 44.99, 134, 135, 136, 314, 315, 317, 359, 361 + }; + for (unsigned i = 0; i < G_N_ELEMENTS(d); ++i) { + double const degrees = d[i]; + NR::rotate const rot(rotate_degrees(degrees)); + NR::rotate const rot_approx( M_PI * ( degrees / 180. ) ); + UTEST_ASSERT(rotate_equalp(rot, rot_approx, 1e-12)); + + NR::rotate const rot_inv(rotate_degrees(-degrees)); + NR::rotate const rot_compl(rotate_degrees(360 - degrees)); + UTEST_ASSERT(rotate_equalp(rot_inv, rot_compl, 1e-12)); + + UTEST_ASSERT(!rotate_equalp(rot, rotate_degrees(degrees + 1), 1e-5)); + } + } + + return ( utest_end() + ? EXIT_SUCCESS + : EXIT_FAILURE ); +} + +/* + 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 : diff --git a/src/libnr/nr-rotate-fns-test.h b/src/libnr/nr-rotate-fns-test.h new file mode 100644 index 000000000..e3bfe3043 --- /dev/null +++ b/src/libnr/nr-rotate-fns-test.h @@ -0,0 +1,54 @@ +#include + +#include +#include + +#include + +class NrRotateFnsTest : public CxxTest::TestSuite +{ +public: + + NrRotateFnsTest() + { + } + virtual ~NrRotateFnsTest() {} + +// createSuite and destroySuite get us per-suite setup and teardown +// without us having to worry about static initialization order, etc. + static NrRotateFnsTest *createSuite() { return new NrRotateFnsTest(); } + static void destroySuite( NrRotateFnsTest *suite ) { delete suite; } + + + + void testRotateDegrees(void) + { + double const d[] = { + 0, 90, 180, 270, 360, 45, 45.01, 44.99, 134, 135, 136, 314, 315, 317, 359, 361 + }; + for ( unsigned i = 0; i < G_N_ELEMENTS(d); ++i ) { + double const degrees = d[i]; + NR::rotate const rot(rotate_degrees(degrees)); + NR::rotate const rot_approx( M_PI * ( degrees / 180. ) ); + TS_ASSERT( rotate_equalp(rot, rot_approx, 1e-12) ); + + NR::rotate const rot_inv(rotate_degrees(-degrees)); + NR::rotate const rot_compl(rotate_degrees(360 - degrees)); + TS_ASSERT( rotate_equalp(rot_inv, rot_compl, 1e-12) ); + + TS_ASSERT( !rotate_equalp(rot, rotate_degrees(degrees + 1), 1e-5) ); + } + } + +}; + +/* + 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:textwidth=99 : diff --git a/src/libnr/nr-rotate-fns.cpp b/src/libnr/nr-rotate-fns.cpp new file mode 100644 index 000000000..f2669c20c --- /dev/null +++ b/src/libnr/nr-rotate-fns.cpp @@ -0,0 +1,66 @@ +/** \file + * Functions to/from NR::rotate. + */ +#include +#include "libnr/nr-rotate-ops.h" +#include "libnr/nr-rotate-fns.h" + +/** + * Returns a rotation matrix corresponding by the specified angle about the origin. + * + * Angle direction in Inkscape code: If you use the traditional mathematics convention that y + * increases upwards, then positive angles are anticlockwise as per the mathematics convention. If + * you take the common non-mathematical convention that y increases downwards, then positive angles + * are clockwise, as is common outside of mathematics. + */ +NR::rotate +rotate_degrees(double degrees) +{ + if (degrees < 0) { + return rotate_degrees(-degrees).inverse(); + } + + double const degrees0 = degrees; + if (degrees >= 360) { + degrees = fmod(degrees, 360); + } + + NR::rotate ret(1., 0.); + + if (degrees >= 180) { + NR::rotate const rot180(-1., 0.); + degrees -= 180; + ret = rot180; + } + + if (degrees >= 90) { + NR::rotate const rot90(0., 1.); + degrees -= 90; + ret *= rot90; + } + + if (degrees == 45) { + NR::rotate const rot45(M_SQRT1_2, M_SQRT1_2); + ret *= rot45; + } else { + double const radians = M_PI * ( degrees / 180 ); + ret *= NR::rotate(cos(radians), sin(radians)); + } + + NR::rotate const raw_ret( M_PI * ( degrees0 / 180 ) ); + g_return_val_if_fail(rotate_equalp(ret, raw_ret, 1e-8), + raw_ret); + return ret; +} + + +/* + 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 : diff --git a/src/libnr/nr-rotate-fns.h b/src/libnr/nr-rotate-fns.h new file mode 100644 index 000000000..bd075114c --- /dev/null +++ b/src/libnr/nr-rotate-fns.h @@ -0,0 +1,29 @@ +#ifndef SEEN_NR_ROTATE_FNS_H +#define SEEN_NR_ROTATE_FNS_H + +/** \file + * Declarations for rotation functions. + */ + +#include +#include + +inline bool rotate_equalp(NR::rotate const &a, NR::rotate const &b, double const eps) +{ + return point_equalp(a.vec, b.vec, eps); +} + +NR::rotate rotate_degrees(double degrees); + +#endif /* !SEEN_NR_ROTATE_FNS_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 : diff --git a/src/libnr/nr-rotate-matrix-ops.cpp b/src/libnr/nr-rotate-matrix-ops.cpp new file mode 100644 index 000000000..dd3851643 --- /dev/null +++ b/src/libnr/nr-rotate-matrix-ops.cpp @@ -0,0 +1,19 @@ +#include + +NR::Matrix +operator*(NR::rotate const &a, NR::Matrix const &b) +{ + return NR::Matrix(a) * b; +} + + +/* + 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:textwidth=99 : diff --git a/src/libnr/nr-rotate-matrix-ops.h b/src/libnr/nr-rotate-matrix-ops.h new file mode 100644 index 000000000..d2f0eadba --- /dev/null +++ b/src/libnr/nr-rotate-matrix-ops.h @@ -0,0 +1,21 @@ +#ifndef SEEN_LIBNR_NR_ROTATE_MATRIX_OPS_H +#define SEEN_LIBNR_NR_ROTATE_MATRIX_OPS_H + +#include + + +NR::Matrix operator*(NR::rotate const &a, NR::Matrix const &b); + + +#endif /* !SEEN_LIBNR_NR_ROTATE_MATRIX_OPS_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:encoding=utf-8:textwidth=99 : diff --git a/src/libnr/nr-rotate-ops.h b/src/libnr/nr-rotate-ops.h new file mode 100644 index 000000000..4b60b9d0c --- /dev/null +++ b/src/libnr/nr-rotate-ops.h @@ -0,0 +1,43 @@ +#ifndef SEEN_NR_ROTATE_OPS_H +#define SEEN_NR_ROTATE_OPS_H +#include + +namespace NR { + +inline Point operator*(Point const &v, rotate const &r) +{ + return Point(r.vec[X] * v[X] - r.vec[Y] * v[Y], + r.vec[Y] * v[X] + r.vec[X] * v[Y]); +} + +inline rotate operator*(rotate const &a, rotate const &b) +{ + return rotate( a.vec * b ); +} + +inline rotate &rotate::operator*=(rotate const &b) +{ + *this = *this * b; + return *this; +} + +inline rotate operator/(rotate const &numer, rotate const &denom) +{ + return numer * denom.inverse(); +} + +} /* namespace NR */ + + +#endif /* !SEEN_NR_ROTATE_OPS_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:encoding=utf-8:textwidth=99 : diff --git a/src/libnr/nr-rotate-test.cpp b/src/libnr/nr-rotate-test.cpp new file mode 100644 index 000000000..63b9d1737 --- /dev/null +++ b/src/libnr/nr-rotate-test.cpp @@ -0,0 +1,89 @@ +#include +#include +#include +#include /* identity, matrix_equalp */ +#include +#include +#include +#include +#include +#include +using NR::X; +using NR::Y; + +int main(int argc, char *argv[]) +{ + utest_start("rotate"); + + NR::Matrix const m_id(NR::identity()); + NR::rotate const r_id(0.0); + NR::rotate const rot234(.234); + UTEST_TEST("constructors, comparisons") { + UTEST_ASSERT( r_id == r_id ); + UTEST_ASSERT( rot234 == rot234 ); + UTEST_ASSERT( rot234 != r_id ); + UTEST_ASSERT( r_id == NR::rotate(NR::Point(1.0, 0.0)) ); + UTEST_ASSERT( NR::Matrix(r_id) == m_id ); + UTEST_ASSERT( NR::Matrix(r_id).test_identity() ); + + UTEST_ASSERT(rotate_equalp(rot234, NR::rotate(NR::Point(cos(.234), sin(.234))), 1e-12)); + } + + UTEST_TEST("operator=") { + NR::rotate rot234_eq(r_id); + rot234_eq = rot234; + UTEST_ASSERT( rot234 == rot234_eq ); + UTEST_ASSERT( rot234_eq != r_id ); + } + + UTEST_TEST("inverse") { + UTEST_ASSERT( r_id.inverse() == r_id ); + UTEST_ASSERT( rot234.inverse() == NR::rotate(-.234) ); + } + + NR::Point const b(-2.0, 3.0); + NR::rotate const rot180(NR::Point(-1.0, 0.0)); + UTEST_TEST("operator*(Point, rotate)") { + UTEST_ASSERT( b * r_id == b ); + UTEST_ASSERT( b * rot180 == -b ); + UTEST_ASSERT( b * rot234 == b * NR::Matrix(rot234) ); + UTEST_ASSERT(point_equalp(b * NR::rotate(M_PI / 2), + NR::rot90(b), + 1e-14)); + UTEST_ASSERT( b * rotate_degrees(90.) == NR::rot90(b) ); + } + + UTEST_TEST("operator*(rotate, rotate)") { + UTEST_ASSERT( r_id * r_id == r_id ); + UTEST_ASSERT( rot180 * rot180 == r_id ); + UTEST_ASSERT( rot234 * r_id == rot234 ); + UTEST_ASSERT( r_id * rot234 == rot234 ); + UTEST_ASSERT(rotate_equalp(rot234 * rot234.inverse(), r_id, 1e-14)); + UTEST_ASSERT(rotate_equalp(rot234.inverse() * rot234, r_id, 1e-14)); + UTEST_ASSERT(rotate_equalp(( NR::rotate(0.25) * NR::rotate(.5) ), + NR::rotate(.75), + 1e-10)); + } + + UTEST_TEST("operator/(rotate, rotate)") { + UTEST_ASSERT( rot234 / r_id == rot234 ); + UTEST_ASSERT( rot234 / rot180 == rot234 * rot180 ); + UTEST_ASSERT(rotate_equalp(rot234 / rot234, r_id, 1e-14)); + UTEST_ASSERT(rotate_equalp(r_id / rot234, rot234.inverse(), 1e-14)); + } + + return ( utest_end() + ? EXIT_SUCCESS + : EXIT_FAILURE ); +} + +/* + 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:textwidth=99 : diff --git a/src/libnr/nr-rotate-test.h b/src/libnr/nr-rotate-test.h new file mode 100644 index 000000000..252b25022 --- /dev/null +++ b/src/libnr/nr-rotate-test.h @@ -0,0 +1,112 @@ +#include + +#include +#include +#include +#include /* identity, matrix_equalp */ +#include +#include +#include +#include +using NR::X; +using NR::Y; + + +class NrRotateTest : public CxxTest::TestSuite +{ +public: + + NrRotateTest() : + m_id( NR::identity() ), + r_id( 0.0 ), + rot234( .234 ), + b( -2.0, 3.0 ), + rot180( NR::Point(-1.0, 0.0) ) + { + } + virtual ~NrRotateTest() {} + +// createSuite and destroySuite get us per-suite setup and teardown +// without us having to worry about static initialization order, etc. + static NrRotateTest *createSuite() { return new NrRotateTest(); } + static void destroySuite( NrRotateTest *suite ) { delete suite; } + + NR::Matrix const m_id; + NR::rotate const r_id; + NR::rotate const rot234; + NR::Point const b; + NR::rotate const rot180; + + + + + void testCtorsCompares(void) + { + TS_ASSERT_EQUALS( r_id, r_id ); + TS_ASSERT_EQUALS( rot234, rot234 ); + TS_ASSERT_DIFFERS( rot234, r_id ); + TS_ASSERT_EQUALS( r_id, NR::rotate(NR::Point(1.0, 0.0)) ); + TS_ASSERT_EQUALS( NR::Matrix(r_id), m_id ); + TS_ASSERT( NR::Matrix(r_id).test_identity() ); + + TS_ASSERT(rotate_equalp(rot234, NR::rotate(NR::Point(cos(.234), sin(.234))), 1e-12)); + } + + void testAssignmentOp(void) + { + NR::rotate rot234_eq(r_id); + rot234_eq = rot234; + TS_ASSERT_EQUALS( rot234, rot234_eq ); + TS_ASSERT_DIFFERS( rot234_eq, r_id ); + } + + void testInverse(void) + { + TS_ASSERT_EQUALS( r_id.inverse(), r_id ); + TS_ASSERT_EQUALS( rot234.inverse(), NR::rotate(-.234) ); + } + + void testOpStarPointRotate(void) + { + TS_ASSERT_EQUALS( b * r_id, b ); + TS_ASSERT_EQUALS( b * rot180, -b ); + TS_ASSERT_EQUALS( b * rot234, b * NR::Matrix(rot234) ); + TS_ASSERT(point_equalp(b * NR::rotate(M_PI / 2), + NR::rot90(b), + 1e-14)); + TS_ASSERT_EQUALS( b * rotate_degrees(90.), NR::rot90(b) ); + } + + void testOpStarRotateRotate(void) + { + TS_ASSERT_EQUALS( r_id * r_id, r_id ); + TS_ASSERT_EQUALS( rot180 * rot180, r_id ); + TS_ASSERT_EQUALS( rot234 * r_id, rot234 ); + TS_ASSERT_EQUALS( r_id * rot234, rot234 ); + TS_ASSERT( rotate_equalp(rot234 * rot234.inverse(), r_id, 1e-14) ); + TS_ASSERT( rotate_equalp(rot234.inverse() * rot234, r_id, 1e-14) ); + TS_ASSERT( rotate_equalp(( NR::rotate(0.25) * NR::rotate(.5) ), + NR::rotate(.75), + 1e-10) ); + } + + void testOpDivRotateRotate(void) + { + TS_ASSERT_EQUALS( rot234 / r_id, rot234 ); + TS_ASSERT_EQUALS( rot234 / rot180, rot234 * rot180 ); + TS_ASSERT( rotate_equalp(rot234 / rot234, r_id, 1e-14) ); + TS_ASSERT( rotate_equalp(r_id / rot234, rot234.inverse(), 1e-14) ); + } + +}; + +/* + 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:textwidth=99 : diff --git a/src/libnr/nr-rotate.h b/src/libnr/nr-rotate.h new file mode 100644 index 000000000..051372ce6 --- /dev/null +++ b/src/libnr/nr-rotate.h @@ -0,0 +1,66 @@ +#ifndef SEEN_NR_ROTATE_H +#define SEEN_NR_ROTATE_H + +/** \file + * Rotation about the origin. + */ + +#include +#include +#include + +namespace NR { + +/** Notionally an NR::Matrix corresponding to rotation about the origin. + Behaves like NR::Matrix for multiplication. +**/ +class rotate { +public: + Point vec; + +private: + rotate(); + +public: + explicit rotate(Coord theta); + explicit rotate(Point const &p) : vec(p) {} + explicit rotate(Coord const x, Coord const y) : vec(x, y) {} + + bool operator==(rotate const &o) const { + return vec == o.vec; + } + + bool operator!=(rotate const &o) const { + return vec != o.vec; + } + + inline rotate &operator*=(rotate const &b); + /* Defined in nr-rotate-ops.h. */ + + rotate inverse() const { + /** \todo + * In the usual case that vec is a unit vector (within rounding error), + * dividing by len_sq is either a noop or numerically harmful. + * Make a unit_rotate class (or the like) that knows its length is 1. + */ + double const len_sq = dot(vec, vec); + return rotate( Point(vec[X], -vec[Y]) + / len_sq ); + } +}; + +} /* namespace NR */ + + +#endif /* !SEEN_NR_ROTATE_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:encoding=utf-8:textwidth=99 : diff --git a/src/libnr/nr-scale-matrix-ops.cpp b/src/libnr/nr-scale-matrix-ops.cpp new file mode 100644 index 000000000..ce5120079 --- /dev/null +++ b/src/libnr/nr-scale-matrix-ops.cpp @@ -0,0 +1,26 @@ +#include "libnr/nr-matrix-ops.h" + +NR::Matrix +operator*(NR::scale const &s, NR::Matrix const &m) +{ + using NR::X; using NR::Y; + NR::Matrix ret(m); + ret[0] *= s[X]; + ret[1] *= s[X]; + ret[2] *= s[Y]; + ret[3] *= s[Y]; + assert_close( ret, NR::Matrix(s) * m ); + return ret; +} + + +/* + 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:textwidth=99 : diff --git a/src/libnr/nr-scale-matrix-ops.h b/src/libnr/nr-scale-matrix-ops.h new file mode 100644 index 000000000..bf1b498c9 --- /dev/null +++ b/src/libnr/nr-scale-matrix-ops.h @@ -0,0 +1,13 @@ +#ifndef SEEN_LIBNR_NR_SCALE_MATRIX_OPS_H +#define SEEN_LIBNR_NR_SCALE_MATRIX_OPS_H +/** \file + * Declarations (and definition if inline) of operator + * blah (NR::scale, NR::Matrix). + */ + +#include "libnr/nr-forward.h" + +NR::Matrix operator*(NR::scale const &s, NR::Matrix const &m); + + +#endif /* !SEEN_LIBNR_NR_SCALE_MATRIX_OPS_H */ diff --git a/src/libnr/nr-scale-ops.h b/src/libnr/nr-scale-ops.h new file mode 100644 index 000000000..da1fea64c --- /dev/null +++ b/src/libnr/nr-scale-ops.h @@ -0,0 +1,40 @@ +#ifndef SEEN_NR_SCALE_OPS_H +#define SEEN_NR_SCALE_OPS_H + +#include + +namespace NR { + +inline Point operator*(Point const &p, scale const &s) +{ + return Point(p[X] * s[X], + p[Y] * s[Y]); +} + +inline scale operator*(scale const &a, scale const &b) +{ + return scale(a[X] * b[X], + a[Y] * b[Y]); +} + +inline scale operator/(scale const &numer, scale const &denom) +{ + return scale(numer[X] / denom[X], + numer[Y] / denom[Y]); +} + +} /* namespace NR */ + + +#endif /* !SEEN_NR_SCALE_OPS_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:encoding=utf-8:textwidth=99 : diff --git a/src/libnr/nr-scale-test.cpp b/src/libnr/nr-scale-test.cpp new file mode 100644 index 000000000..cc255d02a --- /dev/null +++ b/src/libnr/nr-scale-test.cpp @@ -0,0 +1,71 @@ +#include +#include +#include +using NR::X; +using NR::Y; + +int main(int argc, char *argv[]) +{ + utest_start("NR::scale"); + + NR::scale const sa(1.5, 2.0); + UTEST_TEST("x,y constructor and operator[] const") { + UTEST_ASSERT(sa[X] == 1.5); + UTEST_ASSERT(sa[Y] == 2.0); + UTEST_ASSERT(sa[0u] == 1.5); + UTEST_ASSERT(sa[1u] == 2.0); + } + + NR::Point const b(-2.0, 3.0); + NR::scale const sb(b); + + UTEST_TEST("copy constructor, operator==, operator!=") { + NR::scale const sa_copy(sa); + UTEST_ASSERT( sa == sa_copy ); + UTEST_ASSERT(!( sa != sa_copy )); + UTEST_ASSERT( sa != sb ); + } + + UTEST_TEST("operator=") { + NR::scale sa_eq(sb); + sa_eq = sa; + UTEST_ASSERT( sa == sa_eq ); + } + + UTEST_TEST("point constructor") { + UTEST_ASSERT(sb[X] == b[X]); + UTEST_ASSERT(sb[Y] == b[Y]); + } + + UTEST_TEST("operator*(Point, scale)") { + NR::Point const ab( b * sa ); + UTEST_ASSERT( ab == NR::Point(-3.0, 6.0) ); + } + + UTEST_TEST("operator*(scale, scale)") { + NR::scale const sab( sa * sb ); + UTEST_ASSERT( sab == NR::scale(-3.0, 6.0) ); + } + + UTEST_TEST("operator/(scale, scale)") { + NR::scale const sa_b( sa / sb ); + NR::scale const exp_sa_b(-0.75, 2./3.); + UTEST_ASSERT( sa_b[0] == exp_sa_b[0] ); + UTEST_ASSERT( fabs( sa_b[1] - exp_sa_b[1] ) < 1e-10 ); + } + + return ( utest_end() + ? EXIT_SUCCESS + : EXIT_FAILURE ); +} + +/* + 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:textwidth=99 : diff --git a/src/libnr/nr-scale-test.h b/src/libnr/nr-scale-test.h new file mode 100644 index 000000000..dc5e6ef28 --- /dev/null +++ b/src/libnr/nr-scale-test.h @@ -0,0 +1,92 @@ +#include + +#include +#include +using NR::X; +using NR::Y; + +class NrScaleTest : public CxxTest::TestSuite +{ +public: + + NrScaleTest() : + sa( 1.5, 2.0 ), + b( -2.0, 3.0 ), + sb( b ) + { + } + virtual ~NrScaleTest() {} + +// createSuite and destroySuite get us per-suite setup and teardown +// without us having to worry about static initialization order, etc. + static NrScaleTest *createSuite() { return new NrScaleTest(); } + static void destroySuite( NrScaleTest *suite ) { delete suite; } + + NR::scale const sa; + NR::Point const b; + NR::scale const sb; + + + + void testXY_CtorArrayOperator(void) + { + TS_ASSERT_EQUALS( sa[X], 1.5 ); + TS_ASSERT_EQUALS( sa[Y], 2.0 ); + TS_ASSERT_EQUALS( sa[0u], 1.5 ); + TS_ASSERT_EQUALS( sa[1u], 2.0 ); + } + + + void testCopyCtor_AssignmentOp_NotEquals(void) + { + NR::scale const sa_copy(sa); + TS_ASSERT_EQUALS( sa, sa_copy ); + TS_ASSERT(!( sa != sa_copy )); + TS_ASSERT( sa != sb ); + } + + void testAssignmentOp(void) + { + NR::scale sa_eq(sb); + sa_eq = sa; + TS_ASSERT_EQUALS( sa, sa_eq ); + } + + void testPointCtor(void) + { + TS_ASSERT_EQUALS( sb[X], b[X] ); + TS_ASSERT_EQUALS( sb[Y], b[Y] ); + } + + void testOpStarPointScale(void) + { + NR::Point const ab( b * sa ); + TS_ASSERT_EQUALS( ab, NR::Point(-3.0, 6.0) ); + } + + void testOpStarScaleScale(void) + { + NR::scale const sab( sa * sb ); + TS_ASSERT_EQUALS( sab, NR::scale(-3.0, 6.0) ); + } + + void testOpDivScaleScale(void) + { + NR::scale const sa_b( sa / sb ); + NR::scale const exp_sa_b(-0.75, 2./3.); + TS_ASSERT_EQUALS( sa_b[0], exp_sa_b[0] ); +// TS_ASSERT_EQUALS( fabs( sa_b[1] - exp_sa_b[1] ) < 1e-10 ); + TS_ASSERT_DELTA( sa_b[1], exp_sa_b[1], 1e-10 ); + } +}; + +/* + 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:textwidth=99 : diff --git a/src/libnr/nr-scale-translate-ops.cpp b/src/libnr/nr-scale-translate-ops.cpp new file mode 100644 index 000000000..911c92e5b --- /dev/null +++ b/src/libnr/nr-scale-translate-ops.cpp @@ -0,0 +1,19 @@ +#include "libnr/nr-matrix-translate-ops.h" + +NR::Matrix +operator*(NR::scale const &s, NR::translate const &t) +{ + return NR::Matrix(s) * t; +} + + +/* + 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:textwidth=99 : diff --git a/src/libnr/nr-scale-translate-ops.h b/src/libnr/nr-scale-translate-ops.h new file mode 100644 index 000000000..2f6f23c2c --- /dev/null +++ b/src/libnr/nr-scale-translate-ops.h @@ -0,0 +1,20 @@ +#ifndef SEEN_LIBNR_NR_SCALE_TRANSLATE_OPS_H +#define SEEN_LIBNR_NR_SCALE_TRANSLATE_OPS_H + +#include "libnr/nr-forward.h" + +NR::Matrix operator*(NR::scale const &s, NR::translate const &t); + + +#endif /* !SEEN_LIBNR_NR_SCALE_TRANSLATE_OPS_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:encoding=utf-8:textwidth=99 : diff --git a/src/libnr/nr-scale.h b/src/libnr/nr-scale.h new file mode 100644 index 000000000..c9de871de --- /dev/null +++ b/src/libnr/nr-scale.h @@ -0,0 +1,50 @@ +#ifndef SEEN_NR_SCALE_H +#define SEEN_NR_SCALE_H +#include +#include + +namespace NR { + +class scale { +private: + Point _p; + +private: + scale(); + +public: + explicit scale(Point const &p) : _p(p) {} + scale(double const x, double const y) : _p(x, y) {} + explicit scale(double const s) : _p(s, s) {} + inline Coord operator[](Dim2 const d) const { return _p[d]; } + inline Coord operator[](unsigned const d) const { return _p[d]; } + inline Coord &operator[](Dim2 const d) { return _p[d]; } + inline Coord &operator[](unsigned const d) { return _p[d]; } + + bool operator==(scale const &o) const { + return _p == o._p; + } + + bool operator!=(scale const &o) const { + return _p != o._p; + } + scale inverse() const { + return scale(1/_p[0], 1/_p[1]); + } +}; + +} /* namespace NR */ + + +#endif /* !SEEN_NR_SCALE_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:encoding=utf-8:textwidth=99 : diff --git a/src/libnr/nr-svp-private.h b/src/libnr/nr-svp-private.h new file mode 100644 index 000000000..dbddcd7ca --- /dev/null +++ b/src/libnr/nr-svp-private.h @@ -0,0 +1,30 @@ +#ifndef __NR_SVP_PRIVATE_H__ +#define __NR_SVP_PRIVATE_H__ + +/* + * Pixel buffer rendering library + * + * Authors: + * Lauris Kaplinski + * + * This code is in public domain + */ + +#include + +#define NR_QUANT_X 16.0F +#define NR_QUANT_Y 16.0F +#define NR_COORD_X_FROM_ART(v) (floor (NR_QUANT_X * (v) + 0.5F) / NR_QUANT_X) +#define NR_COORD_Y_FROM_ART(v) (floor (NR_QUANT_Y * (v) + 0.5F) / NR_QUANT_Y) +#define NR_COORD_TO_ART(v) (v) + +/* NRVertex */ + +NRVertex *nr_vertex_new (void); +NRVertex *nr_vertex_new_xy (NR::Coord x, NR::Coord y); +void nr_vertex_free_one (NRVertex *v); +void nr_vertex_free_list (NRVertex *v); + +NRVertex *nr_vertex_reverse_list (NRVertex *v); + +#endif diff --git a/src/libnr/nr-svp-render.cpp b/src/libnr/nr-svp-render.cpp new file mode 100644 index 000000000..0c3b391d5 --- /dev/null +++ b/src/libnr/nr-svp-render.cpp @@ -0,0 +1,615 @@ +#define __NR_SVP_RENDER_C__ + +/* + * Pixel buffer rendering library + * + * Authors: + * Lauris Kaplinski + * + * This code is in public domain + */ + +#define NR_SVPSEG_Y0(s,i) ((s)->points[(s)->segments[i].start].y) +#define NR_SVPSEG_Y1(s,i) ((s)->points[(s)->segments[i].start + (s)->segments[i].length - 1].y) + +#define noNR_VERBOSE + +#include "nr-svp-render.h" + +static void nr_svp_render (NRSVP *svp, unsigned char *px, unsigned int bpp, unsigned int rs, int x0, int y0, int x1, int y1, + void (* run) (unsigned char *px, int len, int c0_24, int s0_24, void *data), void *data); + +static void nr_svp_run_A8_OR (unsigned char *d, int len, int c0_24, int s0_24, void *data); + +/* Renders graymask of svl into buffer */ + +void +nr_pixblock_render_svp_mask_or (NRPixBlock *d, NRSVP *svp) +{ + nr_svp_render (svp, NR_PIXBLOCK_PX (d), 1, d->rs, + d->area.x0, d->area.y0, d->area.x1, d->area.y1, + nr_svp_run_A8_OR, NULL); +} + +static void +nr_svp_run_A8_OR (unsigned char *d, int len, int c0_24, int s0_24, void *data) +{ + if ((c0_24 >= 0xff0000) && (s0_24 == 0x0)) { + /* Simple copy */ + while (len > 0) { + d[0] = 255; + d += 1; + len -= 1; + } + } else { + while (len > 0) { + unsigned int ca, da; + /* Draw */ + ca = c0_24 >> 16; + da = 65025 - (255 - ca) * (255 - d[0]); + d[0] = (da + 127) / 255; + d += 1; + c0_24 += s0_24; + c0_24 = CLAMP (c0_24, 0, 16777216); + len -= 1; + } + } +} + + +struct NRRun { + NRRun *next; + NR::Coord x0, y0, x1, y1; + float step; + float final; + NR::Coord x; + NR::Coord value; +}; + +static NRRun *nr_run_new (NR::Coord x0, NR::Coord y0, NR::Coord x1, NR::Coord y1, int wind); +static NRRun *nr_run_free_one (NRRun *run); +static void nr_run_free_list (NRRun *run); +static NRRun *nr_run_insort (NRRun *start, NRRun *run); + +struct NRSlice { + NRSlice *next; + int wind; + NRPoint *points; + unsigned int current; + unsigned int last; + NR::Coord x; + NR::Coord y; + NR::Coord stepx; +}; + +static NRSlice *nr_slice_new (int wind, NRPoint *points, unsigned int length, NR::Coord y); +static NRSlice *nr_slice_free_one (NRSlice *s); +static void nr_slice_free_list (NRSlice *s); +static NRSlice *nr_slice_insort (NRSlice *start, NRSlice *slice); +static int nr_slice_compare (NRSlice *l, NRSlice *r); + +static void +nr_svp_render (NRSVP *svp, unsigned char *px, unsigned int bpp, unsigned int rs, int iX0, int iY0, int iX1, int iY1, + void (* run) (unsigned char *px, int len, int c0_24, int s0_24, void *data), void *data) +{ + NR::Coord dX0, dY0, dX1, dY1; + NRSlice *slices; + unsigned int sidx; + int ystart; + unsigned char *rowbuffer; + int iy0; + + if (!svp || !svp->length) return; + + /* Find starting pixel row */ + /* g_assert (svl->bbox.y0 == svl->vertex->y); */ + sidx = 0; + while (NR_SVPSEG_IS_FLAT (svp, sidx) && (sidx < svp->length)) sidx += 1; + if (sidx >= svp->length) return; + ystart = (int) floor (NR_SVPSEG_Y0 (svp, sidx)); + if (ystart > iY0) { + if (ystart >= iY1) return; + px += (ystart - iY0) * rs; + iY0 = ystart; + } + + dX0 = iX0; + dY0 = iY0; + dX1 = iX1; + dY1 = iY1; + + /* Construct initial slice list */ + slices = NULL; + while (sidx < svp->length) { + if (!NR_SVPSEG_IS_FLAT (svp, sidx)) { + NRSVPSegment *seg; + /* It is real renderable segment */ + /* Postpone if starts above initial slice */ + if (NR_SVPSEG_Y0 (svp, sidx) > dY0) break; + seg = svp->segments + sidx; + if (seg->wind && (NR_SVPSEG_Y1 (svp, sidx) > dY0)) { + /* We are renderable and cross initial slice */ + NRSlice *newslice; + newslice = nr_slice_new (seg->wind, svp->points + seg->start, seg->length, dY0); + slices = nr_slice_insort (slices, newslice); + } + } + sidx += 1; + } + if (!slices && (sidx >= svp->length)) return; + + /* Row buffer */ + /* fixme: not needed */ + rowbuffer = px; + + /* Main iteration */ + for (iy0 = iY0; iy0 < iY1; iy0 += 1) { + NR::Coord dy0, dy1; + NRSlice *ss, *cs; + NRRun *runs; + int xstart; + float globalval; + unsigned char *d; + int ix0; + + dy0 = iy0; + dy1 = dy0 + 1.0; + + /* Add possible new svls to slice list */ + while (sidx < svp->length) { + if (!NR_SVPSEG_IS_FLAT (svp, sidx)) { + NRSVPSegment *seg; + /* It is real renderable segment */ + /* Postpone if starts above ending slice */ + if (NR_SVPSEG_Y0 (svp, sidx) > dy1) break; + seg = svp->segments + sidx; + if (seg->wind) { + NR::Coord y; + NRSlice *newslice; + /* We are renderable */ + /* fixme: we should use safely nsvl->vertex->y here */ + y = MAX (dy0, NR_SVPSEG_Y0 (svp, sidx)); + newslice = nr_slice_new (seg->wind, svp->points + seg->start, seg->length, y); + slices = nr_slice_insort (slices, newslice); + } + } + sidx += 1; + } + /* Construct runs, stretching slices */ + /* fixme: This step can be optimized by continuing long runs and adding only new ones (Lauris) */ + runs = NULL; + ss = NULL; + cs = slices; + while (cs) { + /* g_assert (cs->y >= y0); */ + /* g_assert (cs->y < (y + 1)); */ + while ((cs->y < dy1) && (cs->current < cs->last)) { + NR::Coord rx0, ry0, rx1, ry1; + NRRun * newrun; + rx0 = cs->x; + ry0 = cs->y; + if (cs->points[cs->current + 1].y > dy1) { + /* The same slice continues */ + rx1 = rx0 + (dy1 - ry0) * cs->stepx; + ry1 = dy1; + cs->x = rx1; + cs->y = ry1; + } else { + /* Subpixel height run */ + cs->current += 1; + rx1 = cs->points[cs->current].x; + ry1 = cs->points[cs->current].y; + cs->x = rx1; + cs->y = ry1; + if (cs->current < cs->last) { + cs->stepx = (cs->points[cs->current + 1].x - rx1) / (cs->points[cs->current + 1].y - ry1); + } + } + newrun = nr_run_new (rx0, ry0, rx1, ry1, cs->wind); + /* fixme: we should use walking forward/backward instead */ + runs = nr_run_insort (runs, newrun); + } + if (cs->current < cs->last) { + ss = cs; + cs = cs->next; + } else { + /* Slice is exhausted */ + cs = nr_slice_free_one (cs); + if (ss) { + ss->next = cs; + } else { + slices = cs; + } + } + } + /* Slices are expanded to next scanline */ + /* Run list is generated */ + /* Globalval is the sum of all finished runs */ + globalval = 0.0; + if ((runs) && (dX0 < runs->x0)) { + /* First run starts right from x0 */ + xstart = (int) floor (runs->x0); + } else { + NRRun *sr, *cr; + /* First run starts left from x0 */ + xstart = iX0; + sr = NULL; + cr = runs; + while ((cr) && (cr->x0 < dX0)) { + if (cr->x1 <= dX0) { + globalval += cr->final; + /* Remove exhausted current run */ + cr = nr_run_free_one (cr); + if (sr) { + sr->next = cr; + } else { + runs = cr; + } + } else { + cr->x = dX0; + cr->value = (dX0 - cr->x0) * cr->step; + sr = cr; + cr = cr->next; + } + } + } + + /* Running buffer */ + d = rowbuffer + bpp * (xstart - iX0); + + for (ix0 = xstart; (runs) && (ix0 < iX1); ix0++) { + NR::Coord dx0, dx1; + int ix1; + NRRun *sr, *cr; + float localval; + unsigned int fill; + float fillstep; + int rx1; + int c24; + + dx0 = ix0; + dx1 = dx0 + 1.0; + ix1 = ix0 + 1; + + /* process runs */ + localval = globalval; + sr = NULL; + cr = runs; + fill = TRUE; + fillstep = 0.0; + rx1 = iX1; + while ((cr) && (cr->x0 < dx1)) { + if (cr->x1 <= dx1) { + /* Run ends here */ + /* No fill */ + fill = FALSE; + /* Continue with final value */ + globalval += cr->final; + /* Add initial trapezoid */ + localval += (float) (0.5 * (cr->x1 - cr->x) * (cr->value + cr->final)); + /* Add final rectangle */ + localval += (float) ((dx1 - cr->x1) * cr->final); + /* Remove exhausted run */ + cr = nr_run_free_one (cr); + if (sr) { + sr->next = cr; + } else { + runs = cr; + } + } else { + /* Run continues through xnext */ + if (fill) { + if (cr->x0 > ix0) { + fill = FALSE; + } else { + rx1 = MIN (rx1, (int) floor (cr->x1)); + fillstep += cr->step; + } + } + localval += (float) ((dx1 - cr->x) * (cr->value + (dx1 - cr->x) * cr->step / 2.0)); + cr->x = dx1; + cr->value = (dx1 - cr->x0) * cr->step; + sr = cr; + cr = cr->next; + } + } + if (fill) { + if (cr) rx1 = MIN (rx1, (int) floor (cr->x0)); + } +#ifdef NR_VERBOSE + if ((localval < -0.01) || (localval > 1.01)) { + printf ("Weird localval %g : gv %g\n", localval, globalval); // localizing ok + } +#endif + localval = CLAMP (localval, 0.0F, 1.0F); + c24 = (int) floor (16777215 * localval + 0.5); + if (fill && (rx1 > ix1)) { + NRRun *r; + int s24; + s24 = (int) floor (16777215 * fillstep + 0.5); + if ((s24 != 0) || (c24 > 65535)) { + run (d, rx1 - ix0, c24, s24, data); + } + /* We have to rewind run positions as well */ + for (r = runs; r && (r->x0 < dx1); r = r->next) { + r->x = rx1; + r->value = (rx1 - r->x0) * r->step; + } + d += bpp * (rx1 - ix0); + ix0 = rx1 - 1; + } else { + run (d, 1, c24, 0, data); + d += bpp; + } + } + nr_run_free_list (runs); + rowbuffer += rs; + } + if (slices) nr_slice_free_list (slices); +} + +/* Slices */ + +#define NR_SLICE_ALLOC_SIZE 32 +static NRSlice *ffslice = NULL; + +static NRSlice * +nr_slice_new (int wind, NRPoint *points, unsigned int length, NR::Coord y) +{ + NRSlice *s; + NRPoint *p; + + /* g_assert (svl); */ + /* g_assert (svl->vertex); */ + /* fixme: not sure, whether correct */ + /* g_assert (y == NR_COORD_SNAP (y)); */ + /* Slices startpoints are included, endpoints excluded */ + /* g_return_val_if_fail (y >= svl->bbox.y0, NULL); */ + /* g_return_val_if_fail (y < svl->bbox.y1, NULL); */ + + s = ffslice; + + if (s == NULL) { + int i; + s = nr_new (NRSlice, NR_SLICE_ALLOC_SIZE); + for (i = 1; i < (NR_SLICE_ALLOC_SIZE - 1); i++) s[i].next = &s[i + 1]; + s[NR_SLICE_ALLOC_SIZE - 1].next = NULL; + ffslice = s + 1; + } else { + ffslice = s->next; + } + + s->next = NULL; + s->wind = wind; + s->points = points; + s->current = 0; + s->last = length - 1; + + while ((s->current < s->last) && (s->points[s->current + 1].y <= y)) s->current += 1; + p = s->points + s->current; + + if (s->points[s->current].y == y) { + s->x = p[0].x; + } else { + s->x = p[0].x + (p[1].x - p[0].x) * (y - p[0].y) / (p[1].y - p[0].y); + } + s->y = y; + s->stepx = (p[1].x - p[0].x) / (p[1].y - p[0].y); + + return s; +} + +static NRSlice * +nr_slice_free_one (NRSlice *slice) +{ + NRSlice *next; + next = slice->next; + slice->next = ffslice; + ffslice = slice; + return next; +} + +static void +nr_slice_free_list (NRSlice *slice) +{ + NRSlice *l; + + if (!slice) return; + + for (l = slice; l->next != NULL; l = l->next); + + l->next = ffslice; + ffslice = slice; +} + +static NRSlice * +nr_slice_insort (NRSlice * start, NRSlice * slice) +{ + NRSlice * s, * l; + + if (!start) return slice; + if (!slice) return start; + + if (nr_slice_compare (slice, start) <= 0) { + slice->next = start; + return slice; + } + + s = start; + for (l = start->next; l != NULL; l = l->next) { + if (nr_slice_compare (slice, l) <= 0) { + slice->next = l; + s->next = slice; + return start; + } + s = l; + } + + slice->next = NULL; + s->next = slice; + + return start; +} + +static int +nr_slice_compare (NRSlice *l, NRSlice *r) +{ + if (l->y == r->y) { + if (l->x < r->x) return -1; + if (l->x > r->x) return 1; + if (l->stepx < r->stepx) return -1; + if (l->stepx > r->stepx) return 1; + } else if (l->y > r->y) { + unsigned int pidx; + NRPoint *p; + NR::Coord x, ldx, rdx; + /* This is bitch - we have to determine r values at l->y */ + pidx = 0; + while ((pidx < r->last) && (r->points[pidx + 1].y <= l->y)) pidx += 1; + /* If v is last vertex, r ends before l starts */ + if (pidx >= r->last) return 1; + p = r->points + pidx; + if (p[0].y == l->y) { + x = p[0].x; + } else { + x = p[0].x + (p[1].x - p[0].x) * (l->y - p[0].y) / (p[1].y - p[0].y); + } + if (l->x < x) return -1; + if (l->x > x) return 1; + ldx = l->stepx * (p[1].y - p[0].y); + rdx = p[1].x - p[0].x; + if (ldx < rdx) return -1; + if (ldx > rdx) return 1; + } else { + unsigned int pidx; + NRPoint *p; + NR::Coord x, ldx, rdx; + /* This is bitch - we have to determine l value at r->y */ + pidx = 0; + while ((pidx < l->last) && (l->points[pidx + 1].y <= r->y)) pidx += 1; + /* If v is last vertex, l ends before r starts */ + if (pidx >= l->last) return 1; + p = l->points + pidx; + if (p[0].y == r->y) { + x = p[0].x; + } else { + x = p[0].x + (p[1].x - p[0].x) * (r->y - p[0].y) / (p[1].y - p[0].y); + } + if (x < r->x) return -1; + if (x > r->x) return 1; + ldx = l->stepx * (p[1].y - p[0].y); + rdx = p[1].x - p[0].x; + if (ldx < rdx) return -1; + if (ldx > rdx) return 1; + } + return 0; +} + +/* + * Memory management stuff follows (remember goals?) + */ + +#define NR_RUN_ALLOC_SIZE 32 +static NRRun *ffrun = NULL; + +static NRRun * +nr_run_new (NR::Coord x0, NR::Coord y0, NR::Coord x1, NR::Coord y1, int wind) +{ + NRRun * r; + + r = ffrun; + + if (r == NULL) { + int i; + r = nr_new (NRRun, NR_RUN_ALLOC_SIZE); + for (i = 1; i < (NR_RUN_ALLOC_SIZE - 1); i++) (r + i)->next = (r + i + 1); + (r + NR_RUN_ALLOC_SIZE - 1)->next = NULL; + ffrun = r + 1; + } else { + ffrun = r->next; + } + + r->next = NULL; + + if (x0 <= x1) { + r->x0 = x0; + r->x1 = x1; + r->y0 = y0; + r->y1 = y1; + r->step = (x0 == x1) ? 0.0F : (float) (wind * (y1 - y0) / (x1 - x0)); + } else { + r->x0 = x1; + r->x1 = x0; + r->y0 = y1; + r->y1 = y0; + r->step = (float) (wind * (y1 - y0) / (x0 - x1)); + } + + r->final = (float) (wind * (y1 - y0)); + + r->value = 0.0; + r->x = r->x0; + + return r; +} + +static NRRun * +nr_run_free_one (NRRun *run) +{ + NRRun *next; + next = run->next; + run->next = ffrun; + ffrun = run; + return next; +} + +static void +nr_run_free_list (NRRun * run) +{ + NRRun * l; + + if (!run) return; + + for (l = run; l->next != NULL; l = l->next); + l->next = ffrun; + ffrun = run; +} + +static NRRun * +nr_run_insort (NRRun * start, NRRun * run) +{ + NRRun * s, * l; + + if (!start) return run; + if (!run) return start; + + if (run->x0 < start->x0) { + run->next = start; + return run; + } + + s = start; + for (l = start->next; l != NULL; l = l->next) { + if (run->x0 < l->x0) { + run->next = l; + s->next = run; + return start; + } + s = l; + } + + s->next = run; + + return start; +} + +/* + 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:textwidth=99 : diff --git a/src/libnr/nr-svp-render.h b/src/libnr/nr-svp-render.h new file mode 100644 index 000000000..1638fb286 --- /dev/null +++ b/src/libnr/nr-svp-render.h @@ -0,0 +1,30 @@ +#ifndef __NR_SVP_RENDER_H__ +#define __NR_SVP_RENDER_H__ + +/* + * Pixel buffer rendering library + * + * Authors: + * Lauris Kaplinski + * + * This code is in public domain + */ + +#include +#include + +/* Renders graymask of svp into buffer */ +void nr_pixblock_render_svp_mask_or (NRPixBlock *d, NRSVP *svp); + +#endif + +/* + 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:textwidth=99 : diff --git a/src/libnr/nr-svp.cpp b/src/libnr/nr-svp.cpp new file mode 100644 index 000000000..a1484397a --- /dev/null +++ b/src/libnr/nr-svp.cpp @@ -0,0 +1,180 @@ +#define __NR_SVP_C__ + +/* + * Pixel buffer rendering library + * + * Authors: + * Lauris Kaplinski + * + * This code is in public domain + */ + +#define noNR_VERBOSE + +#define NR_SVP_LENGTH_MAX 128 + +#ifdef HAVE_CONFIG_H +# include +#endif + +#ifdef HAVE_IEEEFP_H +# include +#endif + +#include "nr-rect.h" +#include "nr-svp-private.h" + +/* Sorted vector paths */ + +void +nr_svp_free (NRSVP *svp) +{ + if (svp->points) nr_free (svp->points); + free (svp); +} + +void +nr_svp_bbox (NRSVP *svp, NRRect *bbox, unsigned int clear) +{ + unsigned int sidx; + float x0, y0, x1, y1; + + x0 = y0 = NR_HUGE; + x1 = y1 = -NR_HUGE; + + for (sidx = 0; sidx < svp->length; sidx++) { + NRSVPSegment *seg; + seg = svp->segments + sidx; + if (seg->length) { + x0 = MIN (x0, seg->x0); + y0 = MIN (y0, svp->points[seg->start].y); + x1 = MAX (x1, seg->x1); + y1 = MAX (y1, svp->points[seg->start + seg->length - 1].y); + } + } + + if ((x1 > x0) && (y1 > y0)) { + if (clear || (bbox->x1 <= bbox->x0) || (bbox->y1 <= bbox->y0)) { + bbox->x0 = x0; + bbox->y0 = y0; + bbox->x1 = x1; + bbox->y1 = y1; + } else { + bbox->x0 = MIN (bbox->x0, x0); + bbox->y0 = MIN (bbox->y0, y0); + bbox->x1 = MAX (bbox->x1, x1); + bbox->y1 = MAX (bbox->y1, y1); + } + } +} + +/* NRVertex */ + +#define NR_VERTEX_ALLOC_SIZE 4096 +static NRVertex *ffvertex = NULL; + +NRVertex * +nr_vertex_new (void) +{ + NRVertex * v; +#ifndef NR_VERTEX_ALLOC + + v = ffvertex; + + if (v == NULL) { + int i; + v = nr_new (NRVertex, NR_VERTEX_ALLOC_SIZE); + for (i = 1; i < (NR_VERTEX_ALLOC_SIZE - 1); i++) v[i].next = &v[i + 1]; + v[NR_VERTEX_ALLOC_SIZE - 1].next = NULL; + ffvertex = v + 1; + } else { + ffvertex = v->next; + } +#else + v = nr_new (NRVertex, 1); +#endif + + v->next = NULL; + + return v; +} + +NRVertex * +nr_vertex_new_xy (NR::Coord x, NR::Coord y) +{ + NRVertex * v; + + if (!finite(x) || !finite(y)) { + g_critical("nr_vertex_new_xy: BUG: Coordinates are not finite"); + x = y = 0; + } else if (!( fabs(x) < 1e17 && fabs(y) < 1e17 )) { + g_critical("nr_vertex_new_xy: Coordinates out of range"); + x = y = 0; + } + + v = nr_vertex_new (); + + v->x = x; + v->y = y; + + return v; +} + +void +nr_vertex_free_one (NRVertex * v) +{ +#ifndef NR_VERTEX_ALLOC + v->next = ffvertex; + ffvertex = v; +#else + nr_free (v); +#endif +} + +void +nr_vertex_free_list (NRVertex * v) +{ +#ifndef NR_VERTEX_ALLOC + NRVertex * l; + for (l = v; l->next != NULL; l = l->next); + l->next = ffvertex; + ffvertex = v; +#else + NRVertex *l, *n; + l = v; + while (l) { + n = l->next; + nr_free (l); + l = n; + } +#endif +} + +NRVertex * +nr_vertex_reverse_list (NRVertex * v) +{ + NRVertex * p; + + p = NULL; + + while (v) { + NRVertex * n; + n = v->next; + v->next = p; + p = v; + v = n; + } + + return p; +} + +/* + 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:textwidth=99 : diff --git a/src/libnr/nr-svp.h b/src/libnr/nr-svp.h new file mode 100644 index 000000000..ca1521f29 --- /dev/null +++ b/src/libnr/nr-svp.h @@ -0,0 +1,65 @@ +#ifndef __NR_SVP_H__ +#define __NR_SVP_H__ + +/* + * Pixel buffer rendering library + * + * Authors: + * Lauris Kaplinski + * + * This code is in public domain + */ + +/* Sorted vector paths */ + +#include +#include + +struct NRPoint; + +struct NRSVPSegment { + gint16 wind; + guint16 length; + guint32 start; + float x0, x1; +}; + +struct NRSVPFlat { + gint16 wind; + guint16 length; + float y; + float x0, x1; +}; + +struct NRSVP { + unsigned int length; + NRPoint *points; + NRSVPSegment segments[1]; +}; + +#define NR_SVPSEG_IS_FLAT(s,i) (!(s)->segments[i].length) + +void nr_svp_free (NRSVP *svp); + +void nr_svp_bbox (NRSVP *svp, NRRect *bbox, unsigned int clear); + +/* Sorted vertex lists */ + +struct NRVertex { + NRVertex *next; + NR::Coord x, y; +}; + + +#endif + +/* + 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:textwidth=99 : diff --git a/src/libnr/nr-translate-matrix-ops.cpp b/src/libnr/nr-translate-matrix-ops.cpp new file mode 100644 index 000000000..d03caf4ff --- /dev/null +++ b/src/libnr/nr-translate-matrix-ops.cpp @@ -0,0 +1,27 @@ +#include "libnr/nr-matrix-ops.h" + +namespace NR { + +Matrix +operator*(translate const &t, Matrix const &m) +{ + Matrix ret(m); + ret[4] += m[0] * t[X] + m[2] * t[Y]; + ret[5] += m[1] * t[X] + m[3] * t[Y]; + assert_close( ret, Matrix(t) * m ); + return ret; +} + +} /* namespace NR */ + + +/* + 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:textwidth=99 : diff --git a/src/libnr/nr-translate-matrix-ops.h b/src/libnr/nr-translate-matrix-ops.h new file mode 100644 index 000000000..aceb123d1 --- /dev/null +++ b/src/libnr/nr-translate-matrix-ops.h @@ -0,0 +1,22 @@ +#ifndef SEEN_LIBNR_NR_TRANSLATE_MATRIX_OPS_H +#define SEEN_LIBNR_NR_TRANSLATE_MATRIX_OPS_H + +#include "libnr/nr-forward.h" + +namespace NR { +Matrix operator*(translate const &t, Matrix const &m); +} + + +#endif /* !SEEN_LIBNR_NR_TRANSLATE_MATRIX_OPS_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:encoding=utf-8:textwidth=99 : diff --git a/src/libnr/nr-translate-ops.h b/src/libnr/nr-translate-ops.h new file mode 100644 index 000000000..14ab6d1ed --- /dev/null +++ b/src/libnr/nr-translate-ops.h @@ -0,0 +1,43 @@ +#ifndef SEEN_NR_TRANSLATE_OPS_H +#define SEEN_NR_TRANSLATE_OPS_H + +#include +#include + +namespace NR { + +inline bool operator==(translate const &a, translate const &b) +{ + return a.offset == b.offset; +} + +inline bool operator!=(translate const &a, translate const &b) +{ + return !( a == b ); +} + +inline translate operator*(translate const &a, translate const &b) +{ + return translate( a.offset + b.offset ); +} + +inline Point operator*(Point const &v, translate const &t) +{ + return t.offset + v; +} + +} /* namespace NR */ + + +#endif /* !SEEN_NR_TRANSLATE_OPS_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:encoding=utf-8:textwidth=99 : diff --git a/src/libnr/nr-translate-rotate-ops.cpp b/src/libnr/nr-translate-rotate-ops.cpp new file mode 100644 index 000000000..35f60c10d --- /dev/null +++ b/src/libnr/nr-translate-rotate-ops.cpp @@ -0,0 +1,20 @@ +#include +#include + +NR::Matrix +operator*(NR::translate const &a, NR::rotate const &b) +{ + return NR::Matrix(b) * NR::translate(a.offset * b); +} + + +/* + 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:textwidth=99 : diff --git a/src/libnr/nr-translate-rotate-ops.h b/src/libnr/nr-translate-rotate-ops.h new file mode 100644 index 000000000..0716f21cc --- /dev/null +++ b/src/libnr/nr-translate-rotate-ops.h @@ -0,0 +1,21 @@ +#ifndef SEEN_LIBNR_NR_TRANSLATE_ROTATE_OPS_H +#define SEEN_LIBNR_NR_TRANSLATE_ROTATE_OPS_H + +#include + + +NR::Matrix operator*(NR::translate const &a, NR::rotate const &b); + + +#endif /* !SEEN_LIBNR_NR_TRANSLATE_ROTATE_OPS_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:encoding=utf-8:textwidth=99 : diff --git a/src/libnr/nr-translate-scale-ops.cpp b/src/libnr/nr-translate-scale-ops.cpp new file mode 100644 index 000000000..b995bbad5 --- /dev/null +++ b/src/libnr/nr-translate-scale-ops.cpp @@ -0,0 +1,25 @@ +#include "libnr/nr-matrix-ops.h" + +NR::Matrix +operator*(NR::translate const &t, NR::scale const &s) +{ + using NR::X; using NR::Y; + + NR::Matrix ret(s); + ret[4] = t[X] * s[X]; + ret[5] = t[Y] * s[Y]; + assert_close( ret, NR::Matrix(t) * NR::Matrix(s) ); + return ret; +} + + +/* + 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:textwidth=99 : diff --git a/src/libnr/nr-translate-scale-ops.h b/src/libnr/nr-translate-scale-ops.h new file mode 100644 index 000000000..c72665857 --- /dev/null +++ b/src/libnr/nr-translate-scale-ops.h @@ -0,0 +1,20 @@ +#ifndef SEEN_LIBNR_NR_TRANSLATE_SCALE_OPS_H +#define SEEN_LIBNR_NR_TRANSLATE_SCALE_OPS_H + +#include "libnr/nr-forward.h" + +NR::Matrix operator*(NR::translate const &t, NR::scale const &s); + + +#endif /* !SEEN_LIBNR_NR_TRANSLATE_SCALE_OPS_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:encoding=utf-8:textwidth=99 : diff --git a/src/libnr/nr-translate-test.cpp b/src/libnr/nr-translate-test.cpp new file mode 100644 index 000000000..9e1ef1166 --- /dev/null +++ b/src/libnr/nr-translate-test.cpp @@ -0,0 +1,65 @@ +#include +#include +#include +#include +#include +#include +#include +#include +using NR::X; +using NR::Y; + + +int main(int argc, char *argv[]) +{ + utest_start("translate"); + + NR::Point const b(-2.0, 3.0); + NR::translate const tb(b); + NR::translate const tc(-3.0, -2.0); + UTEST_TEST("constructors, operator[]") { + UTEST_ASSERT( tc[X] == -3.0 && tc[Y] == -2.0 ); + UTEST_ASSERT( tb[0] == b[X] && tb[1] == b[Y] ); + } + + UTEST_TEST("operator=") { + NR::translate tb_eq(tc); + tb_eq = tb; + UTEST_ASSERT( tb == tb_eq ); + UTEST_ASSERT( tb_eq != tc ); + } + + NR::translate const tbc( tb * tc ); + UTEST_TEST("operator*(translate, translate)") { + UTEST_ASSERT( tbc.offset == NR::Point(-5.0, 1.0) ); + UTEST_ASSERT( tbc.offset == ( tc * tb ).offset ); + UTEST_ASSERT( NR::Matrix(tbc) == NR::Matrix(tb) * NR::Matrix(tc) ); + } + + UTEST_TEST("operator*(Point, translate)") { + UTEST_ASSERT( tbc.offset == b * tc ); + UTEST_ASSERT( b * tc == b * NR::Matrix(tc) ); + } + + NR::translate const t_id(0.0, 0.0); + NR::Matrix const m_id(NR::identity()); + UTEST_TEST("identity") { + UTEST_ASSERT( b * t_id == b ); + UTEST_ASSERT( NR::Matrix(t_id) == m_id ); + } + + return ( utest_end() + ? EXIT_SUCCESS + : EXIT_FAILURE ); +} + +/* + 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:textwidth=99 : diff --git a/src/libnr/nr-translate-test.h b/src/libnr/nr-translate-test.h new file mode 100644 index 000000000..20b537a45 --- /dev/null +++ b/src/libnr/nr-translate-test.h @@ -0,0 +1,87 @@ +#include + +#include +#include +#include +#include +#include +#include +#include +using NR::X; +using NR::Y; + +class NrTranslateTest : public CxxTest::TestSuite +{ +public: + + NrTranslateTest() : + b( -2.0, 3.0 ), + tb( b ), + tc( -3.0, -2.0 ), + tbc( tb * tc ), + t_id( 0.0, 0.0 ), + m_id( NR::identity() ) + { + } + virtual ~NrTranslateTest() {} + +// createSuite and destroySuite get us per-suite setup and teardown +// without us having to worry about static initialization order, etc. + static NrTranslateTest *createSuite() { return new NrTranslateTest(); } + static void destroySuite( NrTranslateTest *suite ) { delete suite; } + + NR::Point const b; + NR::translate const tb; + NR::translate const tc; + NR::translate const tbc; + NR::translate const t_id; + NR::Matrix const m_id; + + + void testCtorsArrayOperator(void) + { + TS_ASSERT_EQUALS( tc[X], -3.0 ); + TS_ASSERT_EQUALS( tc[Y], -2.0 ); + + TS_ASSERT_EQUALS( tb[0], b[X] ); + TS_ASSERT_EQUALS( tb[1], b[Y] ); + } + + void testAssignmentOperator(void) + { + NR::translate tb_eq(tc); + tb_eq = tb; + TS_ASSERT_EQUALS( tb, tb_eq ); + TS_ASSERT_DIFFERS( tb_eq, tc ); + } + + void testOpStarTranslateTranslate(void) + { + TS_ASSERT_EQUALS( tbc.offset, NR::Point(-5.0, 1.0) ); + TS_ASSERT_EQUALS( tbc.offset, ( tc * tb ).offset ); + TS_ASSERT_EQUALS( NR::Matrix(tbc), NR::Matrix(tb) * NR::Matrix(tc) ); + } + + void testOpStarPointTranslate(void) + { + TS_ASSERT_EQUALS( tbc.offset, b * tc ); + TS_ASSERT_EQUALS( b * tc, b * NR::Matrix(tc) ); + } + + void testIdentity(void) + { + TS_ASSERT_EQUALS( b * t_id, b ); + TS_ASSERT_EQUALS( NR::Matrix(t_id), m_id ); + } +}; + +/* + 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:textwidth=99 : diff --git a/src/libnr/nr-translate.h b/src/libnr/nr-translate.h new file mode 100644 index 000000000..c1ea927e0 --- /dev/null +++ b/src/libnr/nr-translate.h @@ -0,0 +1,34 @@ +#ifndef SEEN_NR_TRANSLATE_H +#define SEEN_NR_TRANSLATE_H + +#include + +namespace NR { + +class translate { +public: + Point offset; +private: + translate(); +public: + explicit translate(Point const &p) : offset(p) {} + explicit translate(Coord const x, Coord const y) : offset(x, y) {} + Coord operator[](Dim2 const dim) const { return offset[dim]; } + Coord operator[](unsigned const dim) const { return offset[dim]; } +}; + +} /* namespace NR */ + + +#endif /* !SEEN_NR_TRANSLATE_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:encoding=utf-8:textwidth=99 : diff --git a/src/libnr/nr-types-test.cpp b/src/libnr/nr-types-test.cpp new file mode 100644 index 000000000..87a35fc68 --- /dev/null +++ b/src/libnr/nr-types-test.cpp @@ -0,0 +1,105 @@ +#include "../utest/utest.h" +#include +#include +#include +using NR::Point; +using NR::X; +using NR::Y; + + +int main(int argc, char *argv[]) { + utest_start("Basic NR::Point operations"); + + UTEST_TEST("X,Y values") { + UTEST_ASSERT(X == 0); + UTEST_ASSERT(Y == 1); + } + + NR::Point const a(1.5, 2.0); + UTEST_TEST("x,y constructor and operator[] const") { + UTEST_ASSERT(a[X] == 1.5); + UTEST_ASSERT(a[Y] == 2.0); + } + + NR::Point const b(-2.0, 3.0); + + UTEST_TEST("copy constructor") { + NR::Point a_copy(a); + UTEST_ASSERT(a == a_copy); + UTEST_ASSERT(!(a != a_copy)); + } + + UTEST_TEST("non-const operator[]") { + NR::Point a_copy(a); + a_copy[X] = -2.0; + UTEST_ASSERT(a_copy != a); + UTEST_ASSERT(a_copy != b); + a_copy[Y] = 3.0; + UTEST_ASSERT(a_copy == b); + } + + NR::Point const ab(-0.5, 5.0); + UTEST_TEST("binary +, -") { + UTEST_ASSERT(a != b); + UTEST_ASSERT(a + b == ab); + UTEST_ASSERT(ab - a == b); + UTEST_ASSERT(ab - b == a); + UTEST_ASSERT(ab + a != b); + } + + UTEST_TEST("unary-") { + UTEST_ASSERT(-a == Point(-a[X], -a[Y])); + } + + UTEST_TEST("scale, divide") { + UTEST_ASSERT(-a == -1.0 * a); + UTEST_ASSERT(a + a + a == 3.0 * a); + UTEST_ASSERT(a / .5 == 2.0 * a); + } + + UTEST_TEST("dot") { + UTEST_ASSERT( dot(a, b) == ( a[X] * b[X] + + a[Y] * b[Y] ) ); + UTEST_ASSERT( dot(a, NR::rot90(a)) == 0.0 ); + UTEST_ASSERT( dot(-a, NR::rot90(a)) == 0.0 ); + } + + double const small = pow(2.0, -1070); + + Point const small_left(-small, 0.0); + Point const smallish_3_neg4(3.0 * small, -4.0 * small); + + UTEST_TEST("L1, L2, LInfty norms") { + UTEST_ASSERT(L1(small_left) == small); + UTEST_ASSERT(L2(small_left) == small); + UTEST_ASSERT(LInfty(small_left) == small); + + UTEST_ASSERT(L1(smallish_3_neg4) == 7.0 * small); + UTEST_ASSERT(L2(smallish_3_neg4) == 5.0 * small); + UTEST_ASSERT(LInfty(smallish_3_neg4) == 4.0 * small); + } + + UTEST_TEST("operator+=") { + Point x(a); + x += b; + UTEST_ASSERT(x == ab); + } + + UTEST_TEST("operator/=") { + Point x(a); + x /= .5; + UTEST_ASSERT(x == a + a); + } + + UTEST_TEST("normalize") { + Point x(small_left); + x.normalize(); + UTEST_ASSERT(x == Point(-1.0, 0.0)); + + x = smallish_3_neg4; + x.normalize(); + UTEST_ASSERT(x == Point(0.6, -0.8)); + } + + return utest_end() ? 0 : 1; +} diff --git a/src/libnr/nr-types-test.h b/src/libnr/nr-types-test.h new file mode 100644 index 000000000..d51db1be7 --- /dev/null +++ b/src/libnr/nr-types-test.h @@ -0,0 +1,145 @@ +// nr-types-test.h +#include + +#include "libnr/nr-types.h" +#include "libnr/nr-point-fns.h" +#include +using NR::Point; +using NR::X; +using NR::Y; + +class NrTypesTest : public CxxTest::TestSuite +{ +public: + NrTypesTest() : + a( 1.5, 2.0 ), + b(-2.0, 3.0), + ab(-0.5, 5.0), + small(pow(2.0, -1070)), + small_left(-small, 0.0), + smallish_3_neg4(3.0 * small, -4.0 * small) + {} + virtual ~NrTypesTest() {} + +// createSuite and destroySuite get us per-suite setup and teardown +// without us having to worry about static initialization order, etc. + static NrTypesTest *createSuite() { return new NrTypesTest(); } + static void destroySuite( NrTypesTest *suite ) { delete suite; } + + NR::Point const a; + NR::Point const b; + NR::Point const ab; + double const small; + Point const small_left; + Point const smallish_3_neg4; + + + void testXYValues( void ) + { + TS_ASSERT_EQUALS( X, 0 ); + TS_ASSERT_EQUALS( Y, 1 ); + } + + void testXYCtorAndArrayConst(void) + { + TS_ASSERT_EQUALS( a[X], 1.5 ); + TS_ASSERT_EQUALS( a[Y], 2.0 ); + } + + void testCopyCtor(void) + { + NR::Point a_copy(a); + + TS_ASSERT_EQUALS( a, a_copy ); + TS_ASSERT( !(a != a_copy) ); + } + + void testNonConstArrayOperator(void) + { + NR::Point a_copy(a); + a_copy[X] = -2.0; + TS_ASSERT_DIFFERS( a_copy, a ); + TS_ASSERT_DIFFERS( a_copy, b ); + a_copy[Y] = 3.0; + TS_ASSERT_EQUALS( a_copy, b ); + } + + void testBinaryPlusMinus(void) + { + TS_ASSERT_DIFFERS( a, b ); + TS_ASSERT_EQUALS( a + b, ab ); + TS_ASSERT_EQUALS( ab - a, b ); + TS_ASSERT_EQUALS( ab - b, a ); + TS_ASSERT_DIFFERS( ab + a, b ); + } + + void testUnaryMinus(void) + { + TS_ASSERT_EQUALS( -a, Point(-a[X], -a[Y]) ); + } + + void tetScaleDivide(void) + { + TS_ASSERT_EQUALS( -a, -1.0 * a ); + TS_ASSERT_EQUALS( a + a + a, 3.0 * a ); + TS_ASSERT_EQUALS( a / .5, 2.0 * a ); + } + + void testDot(void) + { + TS_ASSERT_EQUALS( dot(a, b), ( a[X] * b[X] + + a[Y] * b[Y] ) ); + TS_ASSERT_EQUALS( dot(a, NR::rot90(a)), 0.0 ); + TS_ASSERT_EQUALS( dot(-a, NR::rot90(a)), 0.0 ); + } + + void testL1L2LInftyNorms(void) + { + // TODO look at TS_ASSERT_DELTA + + TS_ASSERT_EQUALS( L1(small_left), small ); + TS_ASSERT_EQUALS( L2(small_left), small ); + TS_ASSERT_EQUALS( LInfty(small_left), small ); + + TS_ASSERT_EQUALS( L1(smallish_3_neg4), 7.0 * small ); + TS_ASSERT_EQUALS( L2(smallish_3_neg4), 5.0 * small ); + TS_ASSERT_EQUALS( LInfty(smallish_3_neg4), 4.0 * small ); + } + + void testOperatorPlusEquals(void) + { + Point x(a); + x += b; + TS_ASSERT_EQUALS( x, ab ); + } + + void tetOperatorDivEquals(void) + { + Point x(a); + x /= .5; + TS_ASSERT_EQUALS( x, a + a ); + } + + void testNormalize(void) + { + Point x(small_left); + x.normalize(); + TS_ASSERT_EQUALS( x, Point(-1.0, 0.0) ); + + x = smallish_3_neg4; + x.normalize(); + TS_ASSERT_EQUALS( x, Point(0.6, -0.8) ); + } + +}; + +/* + 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:textwidth=99 : diff --git a/src/libnr/nr-types.cpp b/src/libnr/nr-types.cpp new file mode 100644 index 000000000..98054a551 --- /dev/null +++ b/src/libnr/nr-types.cpp @@ -0,0 +1,68 @@ +/** \file + * Implements NR::Point::normalize() + */ + +#include + +#include "isnan.h" //temporary fix for isnan() + +/** Scales this vector to make it a unit vector (within rounding error). + * + * The current version tries to handle infinite coordinates gracefully, + * but it's not clear that any callers need that. + * + * \pre *this != Point(0, 0). + * \pre Neither coordinate is NaN. + * \post L2(*this) very near 1.0. + */ +void NR::Point::normalize() { + double len = hypot(_pt[0], _pt[1]); + g_return_if_fail(len != 0); + g_return_if_fail(!isNaN(len)); + static double const inf = 1e400; + if(len != inf) { + *this /= len; + } else { + unsigned n_inf_coords = 0; + /* Delay updating pt in case neither coord is infinite. */ + NR::Point tmp; + for ( unsigned i = 0 ; i < 2 ; ++i ) { + if ( _pt[i] == inf ) { + ++n_inf_coords; + tmp[i] = 1.0; + } else if ( _pt[i] == -inf ) { + ++n_inf_coords; + tmp[i] = -1.0; + } else { + tmp[i] = 0.0; + } + } + switch (n_inf_coords) { + case 0: + /* Can happen if both coords are near +/-DBL_MAX. */ + *this /= 4.0; + len = hypot(_pt[0], _pt[1]); + g_assert(len != inf); + *this /= len; + break; + + case 1: + *this = tmp; + break; + + case 2: + *this = sqrt(0.5) * tmp; + break; + } + } +} +/* + 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:textwidth=99 : diff --git a/src/libnr/nr-types.h b/src/libnr/nr-types.h new file mode 100644 index 000000000..4802f5e0c --- /dev/null +++ b/src/libnr/nr-types.h @@ -0,0 +1,47 @@ +#ifndef __NR_TYPES_H__ +#define __NR_TYPES_H__ + +/* + * Pixel buffer rendering library + * + * Authors: + * Lauris Kaplinski + * Class-ifying NRPoint, Nathan Hurst + * + * This code is in public domain + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace NR { + +class Rect; +class Matrix; + +} /* namespace NR */ + + +#endif /* !__NR_TYPES_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:encoding=utf-8:textwidth=99 : diff --git a/src/libnr/nr-values.cpp b/src/libnr/nr-values.cpp new file mode 100644 index 000000000..bb310cc49 --- /dev/null +++ b/src/libnr/nr-values.cpp @@ -0,0 +1,23 @@ +#define __NR_VALUES_C__ + +#include + + +/* +The following predefined objects are for reference +and comparison. +*/ +NRMatrix NR_MATRIX_IDENTITY = + {{1.0, 0.0, 0.0, 1.0, 0.0, 0.0}}; +NRRect NR_RECT_EMPTY = + {NR_HUGE, NR_HUGE, -NR_HUGE, -NR_HUGE}; +NRRectL NR_RECT_L_EMPTY = + {NR_HUGE_L, NR_HUGE_L, -NR_HUGE_L, -NR_HUGE_L}; +NRRectL NR_RECT_S_EMPTY = + {NR_HUGE_S, NR_HUGE_S, -NR_HUGE_S, -NR_HUGE_S}; + +/** component_vectors[i] is like $e_i$ in common mathematical usage; + or equivalently $I_i$ (where $I$ is the identity matrix). */ +NR::Point const component_vectors[] = {NR::Point(1., 0.), + NR::Point(0., 1.)}; + diff --git a/src/libnr/nr-values.h b/src/libnr/nr-values.h new file mode 100644 index 000000000..7fa00d809 --- /dev/null +++ b/src/libnr/nr-values.h @@ -0,0 +1,45 @@ +#ifndef __NR_VALUES_H__ +#define __NR_VALUES_H__ + +/* + * Pixel buffer rendering library + * + * Authors: + * Lauris Kaplinski + * + * This code is in public domain + */ + +#include + +#define NR_EPSILON 1e-18 + +#define NR_HUGE 1e18 +#define NR_HUGE_L (0x7fffffff) +#define NR_HUGE_S (0x7fff) + +/* +The following predefined objects are for reference +and comparison. They are defined in nr-values.cpp +*/ +extern NRMatrix NR_MATRIX_IDENTITY; +extern NRRect NR_RECT_EMPTY; +extern NRRectL NR_RECT_L_EMPTY; +extern NRRectL NR_RECT_S_EMPTY; + +/** component_vectors[i] has 1.0 at position i, and 0.0 elsewhere + (i.e. in the other position). */ +extern NR::Point const component_vectors[2]; + +#endif + +/* + 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:textwidth=99 : diff --git a/src/libnr/nr_config.h.mingw b/src/libnr/nr_config.h.mingw new file mode 100644 index 000000000..6992cc6fc --- /dev/null +++ b/src/libnr/nr_config.h.mingw @@ -0,0 +1,12 @@ +#define NR_SIZEOF_CHAR 1 +#define NR_SIZEOF_SHORT 2 +#define NR_SIZEOF_INT 4 +#define NR_SIZEOF_LONG 4 + +typedef signed char NRByte; +typedef unsigned char NRUByte; +typedef signed short NRShort; +typedef unsigned short NRUShort; +typedef signed int NRLong; +typedef unsigned long NRULong; + diff --git a/src/libnr/nr_config.h.win32 b/src/libnr/nr_config.h.win32 new file mode 100644 index 000000000..e0bfbda3f --- /dev/null +++ b/src/libnr/nr_config.h.win32 @@ -0,0 +1,14 @@ +#define NR_SIZEOF_CHAR 1 +#define NR_SIZEOF_SHORT 2 +#define NR_SIZEOF_INT 4 +#define NR_SIZEOF_LONG 4 + +typedef signed char NRByte; +typedef unsigned char NRUByte; +typedef signed short NRShort; +typedef unsigned short NRUShort; +typedef signed int NRLong; +typedef unsigned long NRULong; + + + diff --git a/src/libnr/nr_mmx_R8G8B8A8_P_EMPTY_A8_RGBAP.S b/src/libnr/nr_mmx_R8G8B8A8_P_EMPTY_A8_RGBAP.S new file mode 100644 index 000000000..db2cbec5a --- /dev/null +++ b/src/libnr/nr_mmx_R8G8B8A8_P_EMPTY_A8_RGBAP.S @@ -0,0 +1,125 @@ + .file "nr-compose.c" + +# Ensure Inkscape is execshield protected + .section .note.GNU-stack + .previous + + .text + .align 2 +.globl nr_mmx_R8G8B8A8_P_EMPTY_A8_RGBAP + .type nr_mmx_R8G8B8A8_P_EMPTY_A8_RGBAP,@function + +/* + * This code is in public domain + * + * c 32(%ebp) + * srs 28(%ebp) + * spx 24(%ebp) + * rs 20(%ebp) + * h 16(%ebp) + * w 12(%ebp) + * px 8(%ebp) + * r -8(%ebp) + * g -12(%ebp) + * b -16(%ebp) + * a -20(%ebp) + * s -24(%ebp) -> %esi + * d -28(%ebp) -> %edi + * x -32(%ebp) -> %ebx + * y -36(%ebp) + * ca -40(%ebp) + * + * mm0 Fg + * mm1 FgA + * mm2 FgPre + * mm3 + * mm4 + * mm5 + * mm6 128 + * mm7 0 + * +*/ + +nr_mmx_R8G8B8A8_P_EMPTY_A8_RGBAP: + pushl %ebp + movl %esp, %ebp + pushl %ebx + subl $36, %esp + pushl %edi + pushl %esi + +/* Load %mm7 with [0 0 0 0] */ + movl $0, %eax + movd %eax, %mm7 + +/* Load %mm6 with [128 128 128 128] */ + movl $0x80808080, %eax + movd %eax, %mm6 + punpcklbw %mm7, %mm6 + +/* FgC -> %mm0 */ + movl 32(%ebp), %eax + movd (%eax), %mm0 + punpcklbw %mm7, %mm0 + +/* for (y = ...) */ + movl 16(%ebp), %ecx +.fory: + +/* d = px */ +/* s = spx */ + movl 8(%ebp), %edi + movl 24(%ebp), %esi + +/* for (x = ...) */ + movl 12(%ebp), %ebx +.forx: + +/* [m m m m] -> %mm1 */ + movzbl (%esi), %eax + testb $0xff, %al + jz .clip + movd %eax, %mm1 + punpcklwd %mm1, %mm1 + punpckldq %mm1, %mm1 + +/* Fg -> mm2 */ + movq %mm0, %mm2 + pmullw %mm1, %mm2 + paddw %mm6, %mm2 + movq %mm2, %mm3 + psrlw $8, %mm3 + paddw %mm3, %mm2 + psrlw $8, %mm2 + +/* Store pixel */ + packuswb %mm2, %mm2 + movd %mm2, (%edi) + +.clip: + addl $4, %edi + incl %esi + + decl %ebx + jnz .forx + + movl 20(%ebp), %eax + addl %eax, 8(%ebp) + movl 28(%ebp), %eax + addl %eax, 24(%ebp) + + decl %ecx + jnz .fory + +.exit: + emms + popl %esi + popl %edi + addl $36, %esp + popl %ebx + popl %ebp + ret + +.Lfe1: + .size nr_mmx_R8G8B8A8_P_EMPTY_A8_RGBAP,.Lfe1-nr_mmx_R8G8B8A8_P_EMPTY_A8_RGBAP + .ident "GCC: (GNU) 3.2" diff --git a/src/libnr/nr_mmx_R8G8B8A8_P_R8G8B8A8_P_A8_RGBAP.S b/src/libnr/nr_mmx_R8G8B8A8_P_R8G8B8A8_P_A8_RGBAP.S new file mode 100644 index 000000000..fe1d9be57 --- /dev/null +++ b/src/libnr/nr_mmx_R8G8B8A8_P_R8G8B8A8_P_A8_RGBAP.S @@ -0,0 +1,231 @@ + .file "nr-compose.c" + +# Ensure Inkscape is execshield protected + .section .note.GNU-stack + .previous + + .text + .align 2 +.globl nr_mmx_R8G8B8A8_P_R8G8B8A8_P_A8_RGBAP + .type nr_mmx_R8G8B8A8_P_R8G8B8A8_P_A8_RGBAP,@function + +/* + * This code is in public domain + * + * c 32(%ebp) + * srs 28(%ebp) + * spx 24(%ebp) + * rs 20(%ebp) + * h 16(%ebp) + * w 12(%ebp) + * px 8(%ebp) + * r -8(%ebp) + * g -12(%ebp) + * b -16(%ebp) + * a -20(%ebp) + * s -24(%ebp) -> %esi + * d -28(%ebp) -> %edi + * x -32(%ebp) -> %ebx + * y -36(%ebp) + * ca -40(%ebp) + * + * mm0 Fg + * mm1 MMMM + * mm2 FgM + * mm3 + * mm4 + * mm5 255 + * mm6 128 + * mm7 0 + * +*/ + +nr_mmx_R8G8B8A8_P_R8G8B8A8_P_A8_RGBAP: + pushl %ebp + movl %esp, %ebp + pushl %ebx + subl $36, %esp + pushl %edi + pushl %esi + +/* Load %mm7 with [0 0 0 0] */ + movl $0, %eax + movd %eax, %mm7 + +/* Load %mm6 with [128 128 128 128] */ + movl $0x80808080, %eax + movd %eax, %mm6 + punpcklbw %mm7, %mm6 + +/* Load %mm5 with [255 255 255 255] */ + movl $0xffffffff, %eax + movd %eax, %mm5 + punpcklbw %mm7, %mm5 + +/* FgC -> %mm0 */ + movl 32(%ebp), %eax + movd (%eax), %mm0 + punpcklbw %mm7, %mm0 + +/* Check full opacity */ + cmpb $0xff, %al + jz .opaque + +/* for (y = ...) */ + movl 16(%ebp), %ecx +.fory: + +/* d = px */ +/* s = spx */ + movl 8(%ebp), %edi + movl 24(%ebp), %esi + +/* for (x = ...) */ + movl 12(%ebp), %ebx +.forx: + +/* [m m m m] -> %mm1 */ + movzbl (%esi), %eax + testb $0xff, %al + jz .clip + movd %eax, %mm1 + punpcklwd %mm1, %mm1 + punpckldq %mm1, %mm1 + +/* Fg -> mm2 */ + movq %mm0, %mm2 + pmullw %mm1, %mm2 + paddw %mm6, %mm2 + movq %mm2, %mm3 + psrlw $8, %mm3 + paddw %mm3, %mm2 + psrlw $8, %mm2 + +/* [255 - FgA] -> mm1 */ + movq %mm2, %mm1 + punpckhwd %mm1, %mm1 + punpckhdq %mm1, %mm1 + pxor %mm5, %mm1 + +/* Bg -> mm3 */ + movd (%edi), %mm3 + punpcklbw %mm7, %mm3 + +/* Fg + ((255 - FgA) * Bg) / 255 */ + pmullw %mm1, %mm3 + paddw %mm6, %mm3 + movq %mm3, %mm4 + psrlw $8, %mm4 + paddw %mm4, %mm3 + psrlw $8, %mm3 + paddw %mm2, %mm3 + +/* Store pixel */ + packuswb %mm3, %mm3 + movd %mm3, (%edi) + +.clip: + addl $4, %edi + incl %esi + + decl %ebx + jnz .forx + + movl 20(%ebp), %eax + addl %eax, 8(%ebp) + movl 28(%ebp), %eax + addl %eax, 24(%ebp) + + decl %ecx + jnz .fory + +.exit: + emms + popl %esi + popl %edi + addl $36, %esp + popl %ebx + popl %ebp + ret + +.opaque: +/* for (y = ...) */ + movl 16(%ebp), %ecx +.o_fory: + +/* d = px */ +/* s = spx */ + movl 8(%ebp), %edi + movl 24(%ebp), %esi + +/* for (x = ...) */ + movl 12(%ebp), %ebx +.o_forx: + +/* [m m m m] -> %mm1 */ + movzbl (%esi), %eax + testb $0xff, %al + jz .o_clip + cmpb $0xff, %al + jz .o_full + movd %eax, %mm1 + punpcklwd %mm1, %mm1 + punpckldq %mm1, %mm1 + +/* Fg -> mm2 */ + movq %mm0, %mm2 + pmullw %mm1, %mm2 + paddw %mm6, %mm2 + movq %mm2, %mm3 + psrlw $8, %mm3 + paddw %mm3, %mm2 + psrlw $8, %mm2 + +/* [255 - FgA] -> mm1 */ + movq %mm2, %mm1 + punpckhwd %mm1, %mm1 + punpckhdq %mm1, %mm1 + pxor %mm5, %mm1 + +/* Bg -> mm3 */ + movd (%edi), %mm3 + punpcklbw %mm7, %mm3 + +/* Fg + ((255 - FgA) * Bg) / 255 */ + pmullw %mm1, %mm3 + paddw %mm6, %mm3 + movq %mm3, %mm4 + psrlw $8, %mm4 + paddw %mm4, %mm3 + psrlw $8, %mm3 + paddw %mm2, %mm3 + + jmp .o_store + +.o_full: + movq %mm0, %mm3 + +.o_store: +/* Store pixel */ + packuswb %mm3, %mm3 + movd %mm3, (%edi) + +.o_clip: + addl $4, %edi + incl %esi + + decl %ebx + jnz .o_forx + + movl 20(%ebp), %eax + addl %eax, 8(%ebp) + movl 28(%ebp), %eax + addl %eax, 24(%ebp) + + decl %ecx + jnz .o_fory + jmp .exit + +.Lfe1: + .size nr_mmx_R8G8B8A8_P_R8G8B8A8_P_A8_RGBAP,.Lfe1-nr_mmx_R8G8B8A8_P_R8G8B8A8_P_A8_RGBAP + .ident "GCC: (GNU) 3.2" diff --git a/src/libnr/nr_mmx_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_TRANSFORM.S b/src/libnr/nr_mmx_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_TRANSFORM.S new file mode 100644 index 000000000..e30056af2 --- /dev/null +++ b/src/libnr/nr_mmx_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_TRANSFORM.S @@ -0,0 +1,414 @@ + .file "nr-compose-transform.c" + +# Ensure Inkscape is execshield protected + .section .note.GNU-stack + .previous + + .text + .align 2 +.globl nr_mmx_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_TRANSFORM_0 + .type nr_mmx_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_TRANSFORM_0,@function + +/* + * This code is in public domain + * + */ + +nr_mmx_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_TRANSFORM_0: + pushl %ebp + movl %esp, %ebp + pushl %ebx + subl $48, %esp + pushl %edi + pushl %esi + +/* Load %mm7 with [0 0 0 0] */ + movl $0, %eax + movd %eax, %mm7 + +/* Load %mm6 with [128 128 128 128] */ + movl $0x80808080, %eax + movd %eax, %mm6 + punpcklbw %mm7, %mm6 + +/* Load %mm5 with [255 255 255 255] */ + movl $0xffffffff, %eax + movd %eax, %mm5 + punpcklbw %mm7, %mm5 + +/* Load %mm0 with [a a a a] */ + movzbl 44(%ebp), %eax + movd %eax, %mm0 + punpcklwd %mm0, %mm0 + punpckldq %mm0, %mm0 + + movl 8(%ebp), %eax + movl %eax, -8(%ebp) + movl 40(%ebp), %eax + addl $16, %eax + movl (%eax), %eax + movl %eax, -12(%ebp) + movl 40(%ebp), %eax + addl $20, %eax + movl (%eax), %eax + movl %eax, -16(%ebp) + movl $0, -24(%ebp) +.L29: + movl -24(%ebp), %eax + cmpl 16(%ebp), %eax + jl .L32 + jmp .L28 +.L32: + movl -8(%ebp), %edi + + movl -12(%ebp), %eax + movl %eax, %esi + movl -16(%ebp), %eax + movl %eax, -36(%ebp) + + movl 12(%ebp), %ebx +.for_x_0: + + movl %esi, %ecx + cmpl $0, %ecx + js .clip_0 + sarl $12, %ecx + cmpl 28(%ebp), %ecx + jge .clip_0 + shll $2, %ecx + + movl -36(%ebp), %eax + cmpl $0, %eax + js .clip_0 + sarl $12, %eax + cmpl 32(%ebp), %eax + jge .clip_0 + imull 36(%ebp), %eax + + addl %ecx, %eax + addl 24(%ebp), %eax + +/* Fg -> %mm1 */ + movl (%eax), %eax + testl $0xff000000, %eax + jz .clip_0 + movd %eax, %mm1 + punpcklbw %mm7, %mm1 + +/* [a a a 255] -> %mm3 */ + shrl $24, %eax + movl $0x10101, %edx + mull %edx + orl $0xff000000, %eax + movd %eax, %mm3 + punpcklbw %mm7, %mm3 + +/* [Fg * a] -> mm1 */ + pmullw %mm3, %mm1 + paddw %mm6, %mm1 + movq %mm1, %mm4 + psrlw $8, %mm4 + paddw %mm4, %mm1 + psrlw $8, %mm1 + +/* Multiply by alpha */ + pmullw %mm0, %mm1 + paddw %mm6, %mm1 + movq %mm1, %mm4 + psrlw $8, %mm4 + paddw %mm4, %mm1 + psrlw $8, %mm1 + +/* [255 - FgA] -> mm2 */ + movq %mm1, %mm2 + punpckhwd %mm2, %mm2 + punpckhdq %mm2, %mm2 + pxor %mm5, %mm2 + +/* Bg -> mm3 */ + movd (%edi), %mm3 + punpcklbw %mm7, %mm3 + +/* Fg + ((255 - FgA) * Bg) / 255 */ + + pmullw %mm2, %mm3 + paddw %mm6, %mm3 + movq %mm3, %mm4 + psrlw $8, %mm4 + paddw %mm4, %mm3 + psrlw $8, %mm3 + paddw %mm1, %mm3 + +/* Store pixel */ + packuswb %mm3, %mm3 + movd %mm3, (%edi) + +.clip_0: +.L37: + movl 40(%ebp), %ecx + movl (%ecx), %edx + addl %edx, %esi + movl 4(%ecx), %edx + addl %edx, -36(%ebp) + + addl $4, %edi + + decl %ebx + jnz .for_x_0 + +.L34: + movl 8(%ecx), %edx + addl %edx, -12(%ebp) + movl 12(%ecx), %edx + addl %edx, -16(%ebp) + + movl 20(%ebp), %edx + leal -8(%ebp), %eax + addl %edx, (%eax) + leal -24(%ebp), %eax + incl (%eax) + jmp .L29 +.L28: + emms + popl %esi + popl %edi + addl $48, %esp + popl %ebx + popl %ebp + ret +.Lfe2: + .size nr_mmx_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_TRANSFORM_0,.Lfe2-nr_mmx_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_TRANSFORM_0 + +/* + * + * dbits 52(%ebp) + * alpha 48(%ebp) + * FF_S 44(%ebp) + * + * d -32(%ebp) -> %edi + * i -60(%ebp) -> %esi + * sx -64(%ebp) -> %ebx + * sy -68(%ebp) + * s -72(%ebp) + * + * %mm0 a a a a + * %mm1 FgA + * %mm2 SumFgA + * %mm3 a a a 255 + * %mm4 +*/ + + .align 2 +.globl nr_mmx_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_TRANSFORM_n + .type nr_mmx_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_TRANSFORM_n,@function +nr_mmx_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_TRANSFORM_n: + pushl %ebp + movl %esp, %ebp + pushl %ebx + subl $72, %esp + pushl %edi + pushl %esi + +/* Load %mm7 with [0 0 0 0] */ + movl $0, %eax + movd %eax, %mm7 + +/* Load %mm6 with [128 128 128 128] */ + movl $0x80808080, %eax + movd %eax, %mm6 + punpcklbw %mm7, %mm6 + +/* Load %mm5 with [255 255 255 255] */ + movl $0xffffffff, %eax + movd %eax, %mm5 + punpcklbw %mm7, %mm5 + +/* Load %mm0 with [a a a a] */ + movzbl 48(%ebp), %eax + movd %eax, %mm0 + punpcklwd %mm0, %mm0 + punpckldq %mm0, %mm0 + + movl $1, %eax + movzbl 52(%ebp), %ecx + sall %cl, %eax + movl %eax, -8(%ebp) + movl 8(%ebp), %eax + movl %eax, -12(%ebp) + movl 40(%ebp), %eax + addl $16, %eax + movl (%eax), %eax + movl %eax, -16(%ebp) + movl 40(%ebp), %eax + addl $20, %eax + movl (%eax), %eax + movl %eax, -20(%ebp) + movl $0, -28(%ebp) +.L44: + movl -28(%ebp), %eax + cmpl 16(%ebp), %eax + jl .L47 + jmp .exit_n +.L47: + movl -12(%ebp), %eax + movl %eax, -32(%ebp) + movl -16(%ebp), %eax + movl %eax, -36(%ebp) + movl -20(%ebp), %eax + movl %eax, -40(%ebp) + movl $0, -24(%ebp) +.L48: + movl -24(%ebp), %eax + cmpl 12(%ebp), %eax + jl .L51 + jmp .L49 +.L51: + +/* Zero accumulator */ + movq %mm7, %mm2 + +/* Set i to dptr (size - 1) */ + movl -8(%ebp), %esi + sub $1, %esi + shll $3, %esi + + movl 44(%ebp), %edi + movl -36(%ebp), %ecx + +.for_i_n: + movl (%edi,%esi), %ebx + addl %ecx, %ebx +/* Test negative before shift */ + cmpl $0, %ebx + js .next_i_n + sarl $12, %ebx + cmpl 28(%ebp), %ebx + jge .next_i_n +/* We multiply sx by 4 here */ + shll $2, %ebx + + movl 4(%edi,%esi), %eax + addl -40(%ebp), %eax +/* Test negative before shift */ + cmpl $0, %eax + js .next_i_n + sarl $12, %eax + cmpl 32(%ebp), %eax + jge .next_i_n +/* We multiply sy by srs here */ + imull 36(%ebp), %eax + + addl %ebx, %eax + addl 24(%ebp), %eax + +/* Fg -> %mm1 */ + movl (%eax), %eax + testl $0xff000000, %eax + jz .next_i_n + movd %eax, %mm1 + punpcklbw %mm7, %mm1 + +/* [a a a 255] -> %mm3 */ + shrl $24, %eax + movl $0x10101, %edx + mull %edx + orl $0xff000000, %eax + movd %eax, %mm3 + punpcklbw %mm7, %mm3 + +/* [Fg * a] -> mm1 */ + pmullw %mm3, %mm1 + paddw %mm6, %mm1 + movq %mm1, %mm4 + psrlw $8, %mm4 + paddw %mm4, %mm1 + psrlw $8, %mm1 + +/* Add to accumulator */ + paddw %mm1, %mm2 + +.next_i_n: + subl $8, %esi + jnb .for_i_n + +/* Divide components by sample size */ + movd 52(%ebp), %mm3 + psrlw %mm3, %mm2 + +/* Multiply by alpha */ + pmullw %mm0, %mm2 + paddw %mm6, %mm2 + movq %mm2, %mm4 + psrlw $8, %mm4 + paddw %mm4, %mm2 + psrlw $8, %mm2 + +/* [255 - FgA] -> mm1 */ + movq %mm2, %mm1 + punpckhwd %mm1, %mm1 + punpckhdq %mm1, %mm1 + pxor %mm5, %mm1 + + movl -32(%ebp), %edi +/* Bg -> mm3 */ + movd (%edi), %mm3 + punpcklbw %mm7, %mm3 + +/* Fg + ((255 - FgA) * Bg) / 255 */ + + pmullw %mm1, %mm3 + paddw %mm6, %mm3 + movq %mm3, %mm4 + psrlw $8, %mm4 + paddw %mm4, %mm3 + psrlw $8, %mm3 + paddw %mm2, %mm3 + +/* Store pixel */ + packuswb %mm3, %mm3 + movd %mm3, (%edi) + +.L58: + movl 40(%ebp), %eax + movl (%eax), %edx + leal -36(%ebp), %eax + addl %edx, (%eax) + movl 40(%ebp), %eax + addl $4, %eax + movl (%eax), %edx + leal -40(%ebp), %eax + addl %edx, (%eax) + leal -32(%ebp), %eax + addl $4, (%eax) + leal -24(%ebp), %eax + incl (%eax) + jmp .L48 +.L49: + movl 40(%ebp), %eax + addl $8, %eax + movl (%eax), %edx + leal -16(%ebp), %eax + addl %edx, (%eax) + movl 40(%ebp), %eax + addl $12, %eax + movl (%eax), %edx + leal -20(%ebp), %eax + addl %edx, (%eax) + movl 20(%ebp), %edx + leal -12(%ebp), %eax + addl %edx, (%eax) + leal -28(%ebp), %eax + incl (%eax) + jmp .L44 + +.exit_n: + emms + popl %esi + popl %edi + addl $72, %esp + popl %ebx + popl %ebp + ret +.Lfe3: + .size nr_mmx_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_TRANSFORM_n,.Lfe3-nr_mmx_R8G8B8A8_P_R8G8B8A8_P_R8G8B8A8_N_TRANSFORM_n + .ident "GCC: (GNU) 3.2" diff --git a/src/libnr/nr_mmx_R8G8B8_R8G8B8_R8G8B8A8_P.S b/src/libnr/nr_mmx_R8G8B8_R8G8B8_R8G8B8A8_P.S new file mode 100644 index 000000000..37261e572 --- /dev/null +++ b/src/libnr/nr_mmx_R8G8B8_R8G8B8_R8G8B8A8_P.S @@ -0,0 +1,227 @@ + .file "nr-compose.c" + +# Ensure Inkscape is execshield protected + .section .note.GNU-stack + .previous + + .text + .align 2 +.globl nr_mmx_R8G8B8_R8G8B8_R8G8B8A8_P + .type nr_mmx_R8G8B8_R8G8B8_R8G8B8A8_P,@function + +/* + * This code is in public domain + * + * alpha 32(%ebp) + * srs 28(%ebp) + * spx 24(%ebp) + * rs 20(%ebp) + * h 16(%ebp) + * w 12(%ebp) + * px 8(%ebp) + * r -8(%ebp) + * g -12(%ebp) + * b -16(%ebp) + * a -20(%ebp) + * s -24(%ebp) -> %esi + * d -28(%ebp) -> %edi + * x -32(%ebp) -> %ebx + * y -36(%ebp) + * ca -40(%ebp) + * + * mm0 A + * mm1 FgA + * mm2 FgPre + * mm3 + * mm4 + * mm5 255 + * mm6 128 + * mm7 0 + * +*/ + +nr_mmx_R8G8B8_R8G8B8_R8G8B8A8_P: + pushl %ebp + movl %esp, %ebp + pushl %ebx + subl $36, %esp + pushl %edi + pushl %esi + +/* Load %mm7 with [0 0 0 0] */ + movl $0, %eax + movd %eax, %mm7 + +/* Load %mm6 with [128 128 128 128] */ + movl $0x80808080, %eax + movd %eax, %mm6 + punpcklbw %mm7, %mm6 + +/* Load %mm5 with [255 255 255 255] */ + movl $0xffffffff, %eax + movd %eax, %mm5 + punpcklbw %mm7, %mm5 + +/* Load %mm0 with [a a a a] */ +/* Check full opacity */ + movzbl 32(%ebp), %eax + cmpb $0xff, %al + jz .opaque + movd %eax, %mm0 + punpcklwd %mm0, %mm0 + punpckldq %mm0, %mm0 + +/* for (y = ...) */ + movl 16(%ebp), %ecx +.fory: + +/* d = px */ +/* s = spx */ + movl 8(%ebp), %edi + movl 24(%ebp), %esi + +/* for (x = ...) */ + movl 12(%ebp), %ebx +.forx: + +/* Fg -> %mm1 */ +/* fixme: Do we have to bother about alignment here? (Lauris) */ + movl (%esi), %eax + testl $0xff000000, %eax + jz .clip + movd %eax, %mm1 + punpcklbw %mm7, %mm1 + +/* [Fg * a] -> mm1 */ + pmullw %mm0, %mm1 + paddw %mm6, %mm1 + movq %mm1, %mm2 + psrlw $8, %mm2 + paddw %mm2, %mm1 + psrlw $8, %mm1 + +/* [255 - FgA] -> mm2 */ + movq %mm1, %mm2 + punpckhwd %mm2, %mm2 + punpckhdq %mm2, %mm2 + pxor %mm5, %mm2 + +/* Bg -> mm3 */ + movd (%edi), %mm3 + punpcklbw %mm7, %mm3 + +/* Fg + ((255 - FgA) * Bg) / 255 */ + pmullw %mm2, %mm3 + paddw %mm6, %mm3 + movq %mm3, %mm4 + psrlw $8, %mm4 + paddw %mm4, %mm3 + psrlw $8, %mm3 + paddw %mm1, %mm3 + +/* Store pixel */ + packuswb %mm3, %mm3 + movd %mm3, %eax + movb %al, 0(%edi) + shrl $8, %eax + movb %al, 1(%edi) + shrl $8, %eax + movb %al, 2(%edi) + +.clip: + addl $3, %edi + addl $4, %esi + + decl %ebx + jnz .forx + + movl 20(%ebp), %eax + addl %eax, 8(%ebp) + movl 28(%ebp), %eax + addl %eax, 24(%ebp) + + decl %ecx + jnz .fory + +.exit: + emms + popl %esi + popl %edi + addl $36, %esp + popl %ebx + popl %ebp + ret + +.opaque: +/* for (y = ...) */ + movl 16(%ebp), %ecx +.o_fory: + +/* d = px */ +/* s = spx */ + movl 8(%ebp), %edi + movl 24(%ebp), %esi + +/* for (x = ...) */ + movl 12(%ebp), %ebx +.o_forx: + +/* Fg -> %mm1 */ +/* fixme: Do we have to bother about alignment here? (Lauris) */ + movl (%esi), %eax + testl $0xff000000, %eax + jz .o_clip + cmpl $0xff000000, %eax + jnb .o_store + movd %eax, %mm1 + punpcklbw %mm7, %mm1 + +/* [255 - FgA] -> mm2 */ + movq %mm1, %mm2 + punpckhwd %mm2, %mm2 + punpckhdq %mm2, %mm2 + pxor %mm5, %mm2 + +/* Bg -> mm3 */ + movd (%edi), %mm3 + punpcklbw %mm7, %mm3 + +/* Fg + ((255 - FgA) * Bg) / 255 */ + pmullw %mm2, %mm3 + paddw %mm6, %mm3 + movq %mm3, %mm4 + psrlw $8, %mm4 + paddw %mm4, %mm3 + psrlw $8, %mm3 + paddw %mm1, %mm3 + +/* Store pixel */ + packuswb %mm3, %mm3 + movd %mm3, %eax +.o_store: + movb %al, 0(%edi) + shrl $8, %eax + movb %al, 1(%edi) + shrl $8, %eax + movb %al, 2(%edi) + +.o_clip: + addl $3, %edi + addl $4, %esi + + decl %ebx + jnz .o_forx + + movl 20(%ebp), %eax + addl %eax, 8(%ebp) + movl 28(%ebp), %eax + addl %eax, 24(%ebp) + + decl %ecx + jnz .o_fory + + jmp .exit + +.Lfe1: + .size nr_mmx_R8G8B8_R8G8B8_R8G8B8A8_P,.Lfe1-nr_mmx_R8G8B8_R8G8B8_R8G8B8A8_P + .ident "GCC: (GNU) 3.2" diff --git a/src/libnr/testnr.cpp b/src/libnr/testnr.cpp new file mode 100644 index 000000000..12dce4c52 --- /dev/null +++ b/src/libnr/testnr.cpp @@ -0,0 +1,92 @@ +#define __TESTNR_C__ + +/* + * Pixel buffer rendering library + * + * Authors: + * Lauris Kaplinski + * + * This code is in public domain + */ + +#if defined (_WIN32) || defined (__WIN32__) +# include +#include +#endif + + +#include "nr-blit.h" + +static double +get_time (void) +{ + GTimeVal tv; + g_get_current_time (&tv); + return tv.tv_sec + 1e-6 * tv.tv_usec; +} + +static unsigned int +rand_byte (void) +{ + return (int) (256.0 * rand () / (RAND_MAX + 1.0)); +} + +int +main (int argc, const char **argv) +{ + double start, end; + NRPixBlock d, m[16]; + int count, i; + + srand (time (NULL)); + + printf ("Initializing buffers\n"); + + /* Destination */ + nr_pixblock_setup_fast (&d, NR_PIXBLOCK_MODE_R8G8B8A8P, 0, 0, 64, 64, 1); + d.empty = 0; + + /* Masks */ + for (i = 0; i < 16; i++) { + int r, b, c; + nr_pixblock_setup_fast (&m[i], NR_PIXBLOCK_MODE_A8, 0, 0, 64, 64, 0); + for (r = 0; r < 64; r++) { + unsigned int q; + unsigned char *p; + p = NR_PIXBLOCK_PX (&m[i]) + r * m[i].rs; + for (b = 0; b < 8; b++) { + q = rand_byte (); + if (q < 120) { + for (c = 0; c < 8; c++) *p++ = 0; + } else if (q < 240) { + for (c = 0; c < 8; c++) *p++ = 255; + } else { + for (c = 0; c < 8; c++) *p++ = rand_byte (); + } + } + } + m[i].empty = 0; + } + + printf ("Random transparency\n"); + count = 0; + start = end = get_time (); + while ((end - start) < 5.0) { + unsigned char r, g, b, a; + r = rand_byte (); + g = rand_byte (); + b = rand_byte (); + a = rand_byte (); + + for (i = 0; i < 16; i++) { + nr_blit_pixblock_mask_rgba32 (&d, &m[i], (a << 24) | (g << 16) | (b << 8) | a); + count += 1; + } + end = get_time (); + } + printf ("Did %d [64x64] random buffers in %f sec\n", count, end - start); // localizing ok + printf ("%f buffers per second\n", count / (end - start)); // localizing ok + printf ("%f pixels per second\n", count * (64 * 64) / (end - start)); // localizing ok + + return 0; +} diff --git a/src/libnrtype/.cvsignore b/src/libnrtype/.cvsignore new file mode 100644 index 000000000..e8014d011 --- /dev/null +++ b/src/libnrtype/.cvsignore @@ -0,0 +1,5 @@ +Makefile +Makefile.in +.deps +makefile +.dirstamp diff --git a/src/libnrtype/FontFactory.cpp b/src/libnrtype/FontFactory.cpp new file mode 100644 index 000000000..5fc7e0b3b --- /dev/null +++ b/src/libnrtype/FontFactory.cpp @@ -0,0 +1,630 @@ +/* + * FontFactory.cpp + * testICU + * + * Authors: + * fred + * bulia byak + * + */ + +#include "FontFactory.h" +#include + + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include // _() + +/* Freetype2 */ +# include + + +// need to avoid using the size field +size_t font_descr_hash::operator()( PangoFontDescription *const &x) const { + int h = 0; + h *= 1128467; + char const *theF = pango_font_description_get_family(x); + h += (theF)?g_str_hash(theF):0; + h *= 1128467; + h += (int)pango_font_description_get_style(x); + h *= 1128467; + h += (int)pango_font_description_get_variant(x); + h *= 1128467; + h += (int)pango_font_description_get_weight(x); + h *= 1128467; + h += (int)pango_font_description_get_stretch(x); + return h; +} +bool font_descr_equal::operator()( PangoFontDescription *const&a, PangoFontDescription *const &b) { + //if ( pango_font_description_equal(a,b) ) return true; + char const *fa = pango_font_description_get_family(a); + char const *fb = pango_font_description_get_family(b); + if ( ( fa && fb == NULL ) || ( fb && fa == NULL ) ) return false; + if ( fa && fb && strcmp(fa,fb) != 0 ) return false; + if ( pango_font_description_get_style(a) != pango_font_description_get_style(b) ) return false; + if ( pango_font_description_get_variant(a) != pango_font_description_get_variant(b) ) return false; + if ( pango_font_description_get_weight(a) != pango_font_description_get_weight(b) ) return false; + if ( pango_font_description_get_stretch(a) != pango_font_description_get_stretch(b) ) return false; + return true; +} + +/////////////////// helper functions + +/** + * A wrapper for strcasestr that also provides an implementation for Win32. + */ +static bool +ink_strstr(char const *haystack, char const *pneedle) +{ + // windows has no strcasestr implementation, so here is ours... + // stolen from nmap + /* FIXME: This is broken for e.g. ink_strstr("aab", "ab"). Report to nmap. + * + * Also, suggest use of g_ascii_todown instead of buffer stuff, and g_ascii_tolower instead + * of tolower. Given that haystack is a font name (i.e. fairly short), it should be ok to + * do g_ascii_strdown on both haystack and pneedle, and do normal strstr. + * + * Rather than fixing in inkscape, consider getting rid of this routine, instead using + * strdown and plain strstr at caller. We have control over the needle values, so we can + * modify the callers rather than calling strdown there. + */ + char buf[512]; + register char const *p; + char *needle, *q, *foundto; + if (!*pneedle) return true; + if (!haystack) return false; + + needle = buf; + p = pneedle; q = needle; + while ((*q++ = tolower(*p++))) + ; + p = haystack - 1; foundto = needle; + while (*++p) { + if (tolower(*p) == *foundto) { + if (!*++foundto) { + /* Yeah, we found it */ + return true; + } + } else foundto = needle; + } + return false; +} + +/** + * Regular fonts are 'Regular', 'Roman', 'Normal', or 'Plain' + */ +// FIXME: make this UTF8, add non-English style names +static bool +is_regular(char const *s) +{ + if (ink_strstr(s, "Regular")) return true; + if (ink_strstr(s, "Roman")) return true; + if (ink_strstr(s, "Normal")) return true; + if (ink_strstr(s, "Plain")) return true; + return false; +} + +/** + * Non-bold fonts are 'Medium' or 'Book' + */ +static bool +is_nonbold(char const *s) +{ + if (ink_strstr(s, "Medium")) return true; + if (ink_strstr(s, "Book")) return true; + return false; +} + +/** + * Italic fonts are 'Italic', 'Oblique', or 'Slanted' + */ +static bool +is_italic(char const *s) +{ + if (ink_strstr(s, "Italic")) return true; + if (ink_strstr(s, "Oblique")) return true; + if (ink_strstr(s, "Slanted")) return true; + return false; +} + +/** + * Bold fonts are 'Bold' + */ +static bool +is_bold(char const *s) +{ + if (ink_strstr(s, "Bold")) return true; + return false; +} + +/** + * Caps fonts are 'Caps' + */ +static bool +is_caps(char const *s) +{ + if (ink_strstr(s, "Caps")) return true; + return false; +} + +#if 0 /* FIXME: These are all unused. Please delete them or use them (presumably in +* style_name_compare). */ +/** + * Monospaced fonts are 'Mono' + */ +static bool +is_mono(char const *s) +{ + if (ink_strstr(s, "Mono")) return true; + return false; +} + +/** + * Rounded fonts are 'Round' + */ +static bool +is_round(char const *s) +{ + if (ink_strstr(s, "Round")) return true; + return false; +} + +/** + * Outline fonts are 'Outline' + */ +static bool +is_outline(char const *s) +{ + if (ink_strstr(s, "Outline")) return true; + return false; +} + +/** + * Swash fonts are 'Swash' + */ +static bool +is_swash(char const *s) +{ + if (ink_strstr(s, "Swash")) return true; + return false; +} +#endif + +/** + * Determines if two style names match. This allows us to match + * based on the type of style rather than simply doing string matching, + * because for instance 'Plain' and 'Normal' mean the same thing. + * + * Q: Shouldn't this include the other tests such as is_outline, etc.? + * Q: Is there a problem with strcasecmp on Win32? Should it use stricmp? + */ +static int +style_name_compare(void const *aa, void const *bb) +{ + char const *a = (char const *) aa; + char const *b = (char const *) bb; + + if (is_regular(a) && !is_regular(b)) return -1; + if (is_regular(b) && !is_regular(a)) return 1; + + if (is_bold(a) && !is_bold(b)) return 1; + if (is_bold(b) && !is_bold(a)) return -1; + + if (is_italic(a) && !is_italic(b)) return 1; + if (is_italic(b) && !is_italic(a)) return -1; + + if (is_nonbold(a) && !is_nonbold(b)) return 1; + if (is_nonbold(b) && !is_nonbold(a)) return -1; + + if (is_caps(a) && !is_caps(b)) return 1; + if (is_caps(b) && !is_caps(a)) return -1; + + return strcasecmp(a, b); +} + +static int +style_record_compare(void const *aa, void const *bb) +{ + NRStyleRecord const *a = (NRStyleRecord const *) aa; + NRStyleRecord const *b = (NRStyleRecord const *) bb; + + return (style_name_compare(a->name, b->name)); +} + +static void font_factory_name_list_destructor(NRNameList *list) +{ + for (unsigned int i = 0; i < list->length; i++) + free(list->names[i]); + if ( list->names ) nr_free(list->names); +} + +static void font_factory_style_list_destructor(NRStyleList *list) +{ + for (unsigned int i = 0; i < list->length; i++) { + free((void *) (list->records)[i].name); + free((void *) (list->records)[i].descr); + } + if ( list->records ) nr_free(list->records); +} + +/** + * On Win32 performs a stricmp(a,b), otherwise does a strcasecmp(a,b) + */ +static int +family_name_compare(void const *a, void const *b) +{ +#ifndef WIN32 + return strcasecmp((*((char const **) a)), (*((char const **) b))); +#else + return stricmp((*((char const **) a)), (*((char const **) b))); +#endif +} + +void noop(...) {} +//#define PANGO_DEBUG g_print +#define PANGO_DEBUG noop + + + +///////////////////// FontFactory +#ifndef USE_PANGO_WIN32 +// the substitute function to tell fontconfig to enforce outline fonts +void FactorySubstituteFunc(FcPattern *pattern,gpointer /*data*/) +{ + FcPatternAddBool(pattern, "FC_OUTLINE",FcTrue); + //char *fam = NULL; + //FcPatternGetString(pattern, "FC_FAMILY",0, &fam); + //printf("subst_f on %s\n",fam); +} +#endif + + +font_factory *font_factory::lUsine = NULL; + +font_factory *font_factory::Default(void) +{ + if ( lUsine == NULL ) lUsine = new font_factory; + return lUsine; +} + +font_factory::font_factory(void) +{ + fontSize = 512; + nbEnt = 0; + maxEnt = 32; + ents = (font_entry*)malloc(maxEnt*sizeof(font_entry)); + +#ifdef USE_PANGO_WIN32 + hScreenDC = pango_win32_get_dc(); + fontServer = pango_win32_font_map_for_display(); + fontContext = pango_win32_get_context(); + pangoFontCache = pango_win32_font_map_get_font_cache(fontServer); +#else + fontServer = pango_ft2_font_map_new(); + pango_ft2_font_map_set_resolution((PangoFT2FontMap*)fontServer, 72, 72); + fontContext = pango_ft2_font_map_create_context((PangoFT2FontMap*)fontServer); + pango_ft2_font_map_set_default_substitute((PangoFT2FontMap*)fontServer,FactorySubstituteFunc,this,NULL); +#endif +} + +font_factory::~font_factory(void) +{ + for (int i = 0;i < nbEnt;i++) ents[i].f->Unref(); + if ( ents ) free(ents); + + g_object_unref(fontServer); +#ifdef USE_PANGO_WIN32 + pango_win32_shutdown_display(); +#else + //pango_ft2_shutdown_display(); +#endif + //g_object_unref(fontContext); +} + +font_instance *font_factory::FaceFromDescr(char const *family, char const *style) +{ + PangoFontDescription *temp_descr = pango_font_description_from_string(style); + pango_font_description_set_family(temp_descr,family); + font_instance *res = Face(temp_descr); + pango_font_description_free(temp_descr); + return res; +} + +font_instance *font_factory::Face(PangoFontDescription *descr, bool canFail) +{ +#ifdef USE_PANGO_WIN32 + // damn Pango fudges the size, so we need to unfudge. See source of pango_win32_font_map_init() + pango_font_description_set_size(descr, (int) (fontSize*PANGO_SCALE*72/GetDeviceCaps(pango_win32_get_dc(),LOGPIXELSY))); // mandatory huge size (hinting workaround) +#else + pango_font_description_set_size(descr, (int) (fontSize*PANGO_SCALE)); // mandatory huge size (hinting workaround) +#endif + + font_instance *res = NULL; + + if ( loadedFaces.find(descr) == loadedFaces.end() ) { + // not yet loaded + PangoFont *nFace = NULL; + + // workaround for bug #1025565. + // fonts without families blow up Pango. + if (pango_font_description_get_family(descr) != NULL) { + nFace = pango_font_map_load_font(fontServer,fontContext,descr); + } + else { + g_warning(_("Ignoring font without family that will crash Pango")); + } + + if ( nFace ) { + // duplicate FcPattern, the hard way + res = new font_instance(); + // store the descr of the font we asked for, since this is the key where we intend to put the font_instance at + // in the hash_map. the descr of the returned pangofont may differ from what was asked, so we don't know (at this + // point) whether loadedFaces[that_descr] is free or not (and overwriting an entry will bring deallocation problems) + res->descr = pango_font_description_copy(descr); + res->daddy = this; + res->InstallFace(nFace); + if ( res->pFont == NULL ) { + // failed to install face -> bitmap font + // printf("face failed\n"); + res->daddy = NULL; + delete res; + res = NULL; + if ( canFail ) { + char *tc = pango_font_description_to_string(descr); + PANGO_DEBUG("falling back from %s to Sans because InstallFace failed\n",tc); + free(tc); + pango_font_description_set_family(descr,"Sans"); + res = Face(descr,false); + } + } else { + loadedFaces[res->descr]=res; + res->Ref(); + AddInCache(res); + } + } else { + // no match + if ( canFail ) { + PANGO_DEBUG("falling back to Sans\n"); + pango_font_description_set_family(descr,"Sans"); + res = Face(descr,false); + } + } + } else { + // already here + res = loadedFaces[descr]; + res->Ref(); + AddInCache(res); + } + res->InitTheFace(); + return res; +} + +font_instance *font_factory::Face(char const *family, int variant, int style, int weight, int stretch, int /*size*/, int /*spacing*/) +{ + PangoFontDescription *temp_descr = pango_font_description_new(); + pango_font_description_set_family(temp_descr,family); + pango_font_description_set_weight(temp_descr,(PangoWeight)weight); + pango_font_description_set_stretch(temp_descr,(PangoStretch)stretch); + pango_font_description_set_style(temp_descr,(PangoStyle)style); + pango_font_description_set_variant(temp_descr,(PangoVariant)variant); + font_instance *res = Face(temp_descr); + pango_font_description_free(temp_descr); + return res; +} + +font_instance *font_factory::Face(char const *family, NRTypePosDef apos) +{ + PangoFontDescription *temp_descr = pango_font_description_new(); + + pango_font_description_set_family(temp_descr, family); + + if ( apos.variant == NR_POS_VARIANT_SMALLCAPS ) { + pango_font_description_set_variant(temp_descr, PANGO_VARIANT_SMALL_CAPS); + } else { + pango_font_description_set_variant(temp_descr, PANGO_VARIANT_NORMAL); + } + + if ( apos.italic ) { + pango_font_description_set_style(temp_descr, PANGO_STYLE_ITALIC); + } else if ( apos.oblique ) { + pango_font_description_set_style(temp_descr, PANGO_STYLE_OBLIQUE); + } else { + pango_font_description_set_style(temp_descr, PANGO_STYLE_NORMAL); + } + + if ( apos.weight <= NR_POS_WEIGHT_ULTRA_LIGHT ) { + pango_font_description_set_weight(temp_descr, PANGO_WEIGHT_ULTRALIGHT); + } else if ( apos.weight <= NR_POS_WEIGHT_LIGHT ) { + pango_font_description_set_weight(temp_descr, PANGO_WEIGHT_LIGHT); + } else if ( apos.weight <= NR_POS_WEIGHT_NORMAL ) { + pango_font_description_set_weight(temp_descr, PANGO_WEIGHT_NORMAL); + } else if ( apos.weight <= NR_POS_WEIGHT_BOLD ) { + pango_font_description_set_weight(temp_descr, PANGO_WEIGHT_BOLD); + } else if ( apos.weight <= NR_POS_WEIGHT_ULTRA_BOLD ) { + pango_font_description_set_weight(temp_descr, PANGO_WEIGHT_ULTRABOLD); + } else { + pango_font_description_set_weight(temp_descr, PANGO_WEIGHT_HEAVY); + } + + if ( apos.stretch <= NR_POS_STRETCH_ULTRA_CONDENSED ) { + pango_font_description_set_stretch(temp_descr, PANGO_STRETCH_EXTRA_CONDENSED); + } else if ( apos.stretch <= NR_POS_STRETCH_CONDENSED ) { + pango_font_description_set_stretch(temp_descr, PANGO_STRETCH_CONDENSED); + } else if ( apos.stretch <= NR_POS_STRETCH_SEMI_CONDENSED ) { + pango_font_description_set_stretch(temp_descr, PANGO_STRETCH_SEMI_CONDENSED); + } else if ( apos.stretch <= NR_POS_WEIGHT_NORMAL ) { + pango_font_description_set_stretch(temp_descr, PANGO_STRETCH_NORMAL); + } else if ( apos.stretch <= NR_POS_STRETCH_SEMI_EXPANDED ) { + pango_font_description_set_stretch(temp_descr, PANGO_STRETCH_SEMI_EXPANDED); + } else if ( apos.stretch <= NR_POS_STRETCH_EXPANDED ) { + pango_font_description_set_stretch(temp_descr, PANGO_STRETCH_EXPANDED); + } else { + pango_font_description_set_stretch(temp_descr, PANGO_STRETCH_EXTRA_EXPANDED); + } + + font_instance *res = Face(temp_descr); + pango_font_description_free(temp_descr); + return res; +} + +void font_factory::UnrefFace(font_instance *who) +{ + if ( who == NULL ) return; + if ( loadedFaces.find(who->descr) == loadedFaces.end() ) { + // not found + char *tc = pango_font_description_to_string(who->descr); + g_warning("unrefFace %p=%s: failed\n",who,tc); + free(tc); + } else { + loadedFaces.erase(loadedFaces.find(who->descr)); + // printf("unrefFace %p: success\n",who); + } +} + +NRNameList *font_factory::Families(NRNameList *flist) +{ + PangoFontFamily** fams = NULL; + int nbFam = 0; + pango_font_map_list_families(fontServer, &fams, &nbFam); + + PANGO_DEBUG("got %d families\n", nbFam); + + flist->length = nbFam; + flist->names = (guchar **)malloc(nbFam*sizeof(guchar*)); + flist->destructor = font_factory_name_list_destructor; + + for (int i = 0;i < nbFam;i++) { +// Note: on Windows, pango_font_family_get_name always returns lowercase name. +// As a result the list of fonts in the dialog is lowercase. +// We could work around by loading the font and taking pango_font_description_get_family from its descr (that gives correct case), +// but this is slow, and it's better to fix Pango instead. + flist->names[i]=(guchar*)strdup(pango_font_family_get_name(fams[i])); + } + + qsort(flist->names, nbFam, sizeof(guchar *), family_name_compare); + + g_free(fams); + + return flist; +} + +NRStyleList *font_factory::Styles(gchar const *family, NRStyleList *slist) +{ + PangoFontFamily *theFam = NULL; + + // search available families + { + PangoFontFamily** fams = NULL; + int nbFam = 0; + pango_font_map_list_families(fontServer, &fams, &nbFam); + + for (int i = 0;i < nbFam;i++) { + char const *fname = pango_font_family_get_name(fams[i]); + if ( fname && strcmp(family,fname) == 0 ) { + theFam = fams[i]; + break; + } + } + + g_free(fams); + } + + // nothing found + if ( theFam == NULL ) { + slist->length = 0; + slist->records = NULL; + slist->destructor = NULL; + return slist; + } + + // search faces in the found family + PangoFontFace** faces = NULL; + int nFaces = 0; + pango_font_family_list_faces(theFam, &faces, &nFaces); + + slist->records = (NRStyleRecord *) malloc(nFaces * sizeof(NRStyleRecord)); + slist->destructor = font_factory_style_list_destructor; + + int nr = 0; + for (int i = 0; i < nFaces; i++) { + + // no unnamed faces + if (pango_font_face_get_face_name(faces[i]) == NULL) + continue; + PangoFontDescription *nd = pango_font_face_describe(faces[i]); + if (nd == NULL) + continue; + char const *descr = pango_font_description_to_string(nd); + if (descr == NULL) { + pango_font_description_free(nd); + continue; + } + + char const *name = g_strdup(pango_font_face_get_face_name(faces[i])); + pango_font_description_free(nd); + + slist->records[nr].name = name; + slist->records[nr].descr = descr; + nr ++; + } + + slist->length = nr; + + qsort(slist->records, slist->length, sizeof(NRStyleRecord), style_record_compare); + /* effic: Consider doing strdown and all the is_italic etc. tests once off and store the + * results in a table, rather than having the sort invoke multiple is_italic tests per + * record. + */ + + g_free(faces); + + return slist; +} + +void font_factory::AddInCache(font_instance *who) +{ + if ( who == NULL ) return; + for (int i = 0;i < nbEnt;i++) ents[i].age *= 0.9; + for (int i = 0;i < nbEnt;i++) { + if ( ents[i].f == who ) { + // printf("present\n"); + ents[i].age += 1.0; + return; + } + } + if ( nbEnt > maxEnt ) { + printf("cache sur-plein?\n"); + return; + } + who->Ref(); + if ( nbEnt == maxEnt ) { + int bi = 0; + double ba = ents[bi].age; + for (int i = 1;i < nbEnt;i++) { + if ( ents[i].age < ba ) { + bi = i; + ba = ents[bi].age; + } + } + ents[bi].f->Unref(); + ents[bi]=ents[--nbEnt]; + } + ents[nbEnt].f = who; + ents[nbEnt].age = 1.0; + nbEnt++; +} + + +/* + 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:textwidth=99 : diff --git a/src/libnrtype/FontFactory.h b/src/libnrtype/FontFactory.h new file mode 100644 index 000000000..2b4c6be0f --- /dev/null +++ b/src/libnrtype/FontFactory.h @@ -0,0 +1,112 @@ +/* + * FontFactory.h + * testICU + * + */ + +#ifndef my_font_factory +#define my_font_factory + +#include +#include +#include + +#ifdef HAVE_CONFIG_H +# include +#endif +#ifdef _WIN32 +#define USE_PANGO_WIN32 +#endif + +#include +#include "nr-type-primitives.h" +#include "nr-type-pos-def.h" +#include + +/* Freetype */ +#ifdef USE_PANGO_WIN32 +#include +#else +#include +#include +#endif + +// the font_factory keeps a hashmap of all the loaded font_instances, and uses the PangoFontDescription +// as index (nota: since pango already does that, using the PangoFont could work too) +struct font_descr_hash : public std::unary_function { + size_t operator()(PangoFontDescription *const &x) const; +}; +struct font_descr_equal : public std::binary_function { + bool operator()(PangoFontDescription *const &a, PangoFontDescription *const &b); +}; + +class font_factory { +public: + static font_factory *lUsine; /**< The default font_factory; i cannot think of why we would + * need more than one. + * + * ("l'usine" is french for "the factory".) + */ + + /** A little cache for fonts, so that you don't loose your time looking up fonts in the font list + * each font in the cache is refcounted once (and deref'd when removed from the cache). */ + struct font_entry { + font_instance *f; + double age; + }; + int nbEnt; ///< Number of entries. + int maxEnt; ///< Cache size. + font_entry *ents; + + // Pango data. Backend-specific structures are cast to these opaque types. + PangoFontMap *fontServer; + PangoContext *fontContext; +#ifdef USE_PANGO_WIN32 + PangoWin32FontCache *pangoFontCache; + HDC hScreenDC; +#endif + double fontSize; /**< The huge fontsize used as workaround for hinting. + * Different between freetype and win32. */ + + __gnu_cxx::hash_map loadedFaces; + + font_factory(); + ~font_factory(); + + /// Returns the default font_factory. + static font_factory* Default(); + + // Various functions to get a font_instance from different descriptions. + font_instance* FaceFromDescr(char const *family, char const *style); + font_instance* Face(PangoFontDescription *descr, bool canFail=true); + font_instance* Face(char const *family, + int variant=PANGO_VARIANT_NORMAL, int style=PANGO_STYLE_NORMAL, + int weight=PANGO_WEIGHT_NORMAL, int stretch=PANGO_STRETCH_NORMAL, + int size=10, int spacing=0); + font_instance* Face(char const *family, NRTypePosDef apos); + + /// Semi-private: tells the font_factory taht the font_instance 'who' has died and should be removed from loadedFaces + void UnrefFace(font_instance* who); + + // Queries for the font-selector. + NRNameList* Families(NRNameList *flist); + NRStyleList* Styles(const gchar *family, NRStyleList *slist); + + // internal + void AddInCache(font_instance *who); +}; + + +#endif /* my_font_factory */ + + +/* + 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:textwidth=99 : diff --git a/src/libnrtype/FontInstance.cpp b/src/libnrtype/FontInstance.cpp new file mode 100644 index 000000000..d2b19d0f2 --- /dev/null +++ b/src/libnrtype/FontInstance.cpp @@ -0,0 +1,763 @@ +/* + * FontInstance.cpp + * testICU + * + * Authors: + * fred + * bulia byak + * + */ + +#ifdef HAVE_CONFIG_H +# include +#endif +#include +#include +#include + +/* #include */ + +#include + +#include "RasterFont.h" + +/* Freetype 2 */ +# include +# include +# include +# include +# include +# include + + + +size_t font_style_hash::operator()(const font_style &x) const { + int h=0,n; + for (int i=0;i<6;i++) { + n=(int)floor(100*x.transform[i]); + h*=12186; + h+=n; + } + n=(int)floor(100*x.stroke_width); + h*=12186; + h+=n; + n=(x.vertical)?1:0; + h*=12186; + h+=n; + if ( x.stroke_width >= 0.01 ) { + n=x.stroke_cap*10+x.stroke_join+(int)(x.stroke_miter_limit*100); + h*=12186; + h+=n; + if ( x.nbDash > 0 ) { + n=x.nbDash; + h*=12186; + h+=n; + n=(int)floor(100*x.dash_offset); + h*=12186; + h+=n; + for (int i=0;i 0.01 && b.stroke_width <= 0.01 ) return false; + if ( a.stroke_width <= 0.01 && b.stroke_width > 0.01 ) return false; + if ( a.stroke_width <= 0.01 && b.stroke_width <= 0.01 ) return true; + + if ( a.stroke_cap != b.stroke_cap ) return false; + if ( a.stroke_join != b.stroke_join ) return false; + if ( fabs(a.stroke_miter_limit-b.stroke_miter_limit) > 0.01) return false; + if ( a.nbDash != b.nbDash ) return false; + if ( a.nbDash <= 0 ) return true; + if ( fabs(a.dash_offset-b.dash_offset) < 0.01 ) { + for (int i=0;i= 0.01 ) return false; + } + } else { + return false; + } + return true; +} + +#ifndef USE_PANGO_WIN32 +/* + * Outline extraction + */ +typedef struct ft2_to_liv { + Path* theP; + double scale; + NR::Point last; +} ft2_to_liv; + +// outline as returned by freetype -> livarot Path +// see nr-type-ft2.cpp for the freetype -> artBPath on which this code is based +static int ft2_move_to (FT_Vector * to, void * i_user) { + ft2_to_liv* user=(ft2_to_liv*)i_user; + NR::Point p(user->scale*to->x,user->scale*to->y); + // printf("m t=%f %f\n",p[0],p[1]); + user->theP->MoveTo(p); + user->last=p; + return 0; +} + +static int ft2_line_to (FT_Vector * to, void * i_user) +{ + ft2_to_liv* user=(ft2_to_liv*)i_user; + NR::Point p(user->scale*to->x,user->scale*to->y); + // printf("l t=%f %f\n",p[0],p[1]); + user->theP->LineTo(p); + user->last=p; + return 0; +} + +static int ft2_conic_to (FT_Vector * control, FT_Vector * to, void * i_user) +{ + ft2_to_liv* user=(ft2_to_liv*)i_user; + NR::Point p(user->scale*to->x,user->scale*to->y),c(user->scale*control->x,user->scale*control->y); + // printf("b c=%f %f t=%f %f\n",c[0],c[1],p[0],p[1]); + user->theP->BezierTo(p); + user->theP->IntermBezierTo(c); + user->theP->EndBezierTo(); + user->last=p; + return 0; +} + +static int ft2_cubic_to (FT_Vector * control1, FT_Vector * control2, FT_Vector * to, void * i_user) +{ + ft2_to_liv* user=(ft2_to_liv*)i_user; + NR::Point p(user->scale*to->x,user->scale*to->y), + c1(user->scale*control1->x,user->scale*control1->y), + c2(user->scale*control2->x,user->scale*control2->y); + // printf("c c1=%f %f c2=%f %f t=%f %f\n",c1[0],c1[1],c2[0],c2[1],p[0],p[1]); + user->theP->CubicTo(p,3*(c1-user->last),3*(p-c2)); + user->last=p; + return 0; +} +#endif + +/* + * + */ + +font_instance::font_instance(void) +{ + //printf("font instance born\n"); + descr=NULL; + pFont=NULL; + refCount=0; + daddy=NULL; + nbGlyph=maxGlyph=0; + glyphs=NULL; + theFace=NULL; +} + +font_instance::~font_instance(void) +{ + if ( daddy ) daddy->UnrefFace(this); + //printf("font instance death\n"); + if ( pFont ) g_object_unref(pFont); + pFont=NULL; + if ( descr ) pango_font_description_free(descr); + descr=NULL; + // if ( theFace ) FT_Done_Face(theFace); // owned by pFont. don't touch + theFace=NULL; + + for (int i=0;iUnrefFace(this); + daddy=NULL; + delete this; + } +} + +unsigned int font_instance::Name(gchar *str, unsigned int size) +{ + return Attribute("name", str, size); +} + +unsigned int font_instance::Family(gchar *str, unsigned int size) +{ + return Attribute("family", str, size); +} + +unsigned int font_instance::PSName(gchar *str, unsigned int size) +{ + return Attribute("psname", str, size); +} + +unsigned int font_instance::Attribute(const gchar *key, gchar *str, unsigned int size) +{ + if ( descr == NULL ) { + if ( size > 0 ) str[0]=0; + return 0; + } + char* res=NULL; + bool free_res=false; + + if ( strcmp(key,"name") == 0 ) { + PangoFontDescription* td=pango_font_description_copy(descr); + pango_font_description_unset_fields (td, PANGO_FONT_MASK_SIZE); + res=pango_font_description_to_string (td); + pango_font_description_free(td); + free_res=true; + } else if ( strcmp(key,"psname") == 0 ) { +#ifndef USE_PANGO_WIN32 + res = (char *) FT_Get_Postscript_Name (theFace); // that's the main method, seems to always work +#endif + free_res=false; + if (res == NULL) { // a very limited workaround, only bold, italic, and oblique will work + PangoStyle style=pango_font_description_get_style(descr); + bool i = (style == PANGO_STYLE_ITALIC); + bool o = (style == PANGO_STYLE_OBLIQUE); + PangoWeight weight=pango_font_description_get_weight(descr); + bool b = (weight >= PANGO_WEIGHT_BOLD); + + res = g_strdup_printf ("%s%s%s%s", + pango_font_description_get_family(descr), + (b || i || o) ? "-" : "", + (b) ? "Bold" : "", + (i) ? "Italic" : ((o) ? "Oblique" : "") ); + free_res = true; + } + } else if ( strcmp(key,"family") == 0 ) { + res=(char*)pango_font_description_get_family(descr); + free_res=false; + } else if ( strcmp(key,"style") == 0 ) { + PangoStyle v=pango_font_description_get_style(descr); + if ( v == PANGO_STYLE_ITALIC ) { + res="italic"; + } else if ( v == PANGO_STYLE_OBLIQUE ) { + res="oblique"; + } else { + res="normal"; + } + free_res=false; + } else if ( strcmp(key,"weight") == 0 ) { + PangoWeight v=pango_font_description_get_weight(descr); + if ( v <= PANGO_WEIGHT_ULTRALIGHT ) { + res="200"; + } else if ( v <= PANGO_WEIGHT_LIGHT ) { + res="300"; + } else if ( v <= PANGO_WEIGHT_NORMAL ) { + res="normal"; + } else if ( v <= PANGO_WEIGHT_BOLD ) { + res="bold"; + } else { + res="800"; + } + free_res=false; + } else if ( strcmp(key,"stretch") == 0 ) { + PangoStretch v=pango_font_description_get_stretch(descr); + if ( v <= PANGO_STRETCH_EXTRA_CONDENSED ) { + res="extra-condensed"; + } else if ( v <= PANGO_STRETCH_CONDENSED ) { + res="condensed"; + } else if ( v <= PANGO_STRETCH_SEMI_CONDENSED ) { + res="semi-condensed"; + } else if ( v <= PANGO_STRETCH_NORMAL ) { + res="normal"; + } else if ( v <= PANGO_STRETCH_SEMI_EXPANDED ) { + res="semi-expanded"; + } else if ( v <= PANGO_STRETCH_EXPANDED ) { + res="expanded"; + } else { + res="extra-expanded"; + } + free_res=false; + } else if ( strcmp(key,"variant") == 0 ) { + PangoVariant v=pango_font_description_get_variant(descr); + if ( v == PANGO_VARIANT_SMALL_CAPS ) { + res="small-caps"; + } else { + res="normal"; + } + free_res=false; + } else { + res = NULL; + free_res=false; + } + if ( res == NULL ) { + if ( size > 0 ) str[0]=0; + return 0; + } + + if (res) { + unsigned int len=strlen(res); + unsigned int rlen=(size-1 0 ) memcpy(str,res,rlen); + if ( size > 0 ) str[rlen]=0; + } + if (free_res) free(res); + return len; + } + return 0; +} + +void font_instance::InitTheFace() +{ +#ifdef USE_PANGO_WIN32 + if ( !theFace ) { + LOGFONT *lf=pango_win32_font_logfont(pFont); + g_assert(lf != NULL); + theFace=pango_win32_font_cache_load(daddy->pangoFontCache,lf); + g_free(lf); + } + XFORM identity = {1.0, 0.0, 0.0, 1.0, 0.0, 0.0}; + SetWorldTransform(daddy->hScreenDC, &identity); + SetGraphicsMode(daddy->hScreenDC, GM_COMPATIBLE); + SelectObject(daddy->hScreenDC,theFace); +#else + theFace=pango_ft2_font_get_face(pFont); + FT_Select_Charmap(theFace,ft_encoding_unicode) && FT_Select_Charmap(theFace,ft_encoding_symbol); +#endif +} + +void font_instance::FreeTheFace() +{ +#ifdef USE_PANGO_WIN32 + SelectObject(daddy->hScreenDC,GetStockObject(SYSTEM_FONT)); + pango_win32_font_cache_unload(daddy->pangoFontCache,theFace); +#endif + theFace=NULL; +} + +void font_instance::InstallFace(PangoFont* iFace) +{ + if ( !iFace ) + return; + pFont=iFace; + + InitTheFace(); + + if ( pFont && IsOutlineFont() == false ) { + FreeTheFace(); + if ( pFont ) g_object_unref(pFont); + pFont=NULL; + } +} + +bool font_instance::IsOutlineFont(void) +{ + if ( pFont == NULL ) return false; + InitTheFace(); +#ifdef USE_PANGO_WIN32 + TEXTMETRIC tm; + return GetTextMetrics(daddy->hScreenDC,&tm) && tm.tmPitchAndFamily&TMPF_TRUETYPE; +#else + return FT_IS_SCALABLE(theFace); +#endif +} + +int font_instance::MapUnicodeChar(gunichar c) +{ + if ( pFont == NULL ) return 0; +#ifdef USE_PANGO_WIN32 + return pango_win32_font_get_glyph_index(pFont,c); +#else + int res=0; + theFace=pango_ft2_font_get_face(pFont); + if ( c > 0xf0000 ) { + res=CLAMP(c,0xf0000,0x1fffff)-0xf0000; + } else { + res=FT_Get_Char_Index(theFace, c); + } + return res; +#endif +} + + +#ifdef USE_PANGO_WIN32 +static inline NR::Point pointfx_to_nrpoint(const POINTFX &p, double scale) +{ + return NR::Point(*(long*)&p.x / 65536.0 * scale, + *(long*)&p.y / 65536.0 * scale); +} +#endif + +void font_instance::LoadGlyph(int glyph_id) +{ + if ( pFont == NULL ) return; + InitTheFace(); +#ifndef USE_PANGO_WIN32 + if ( theFace->units_per_EM == 0 ) return; // bitmap font +#endif + + if ( id_to_no.find(glyph_id) == id_to_no.end() ) { + if ( nbGlyph >= maxGlyph ) { + maxGlyph=2*nbGlyph+1; + glyphs=(font_glyph*)realloc(glyphs,maxGlyph*sizeof(font_glyph)); + } + font_glyph n_g; + n_g.outline=NULL; + n_g.artbpath=NULL; + n_g.bbox[0]=n_g.bbox[1]=n_g.bbox[2]=n_g.bbox[3]=0; + bool doAdd=false; + +#ifdef USE_PANGO_WIN32 + MAT2 identity = {{0,1},{0,0},{0,0},{0,1}}; + OUTLINETEXTMETRIC otm; + GetOutlineTextMetrics(daddy->hScreenDC, sizeof(otm), &otm); + GLYPHMETRICS metrics; + DWORD bufferSize=GetGlyphOutline (daddy->hScreenDC, glyph_id, GGO_GLYPH_INDEX | GGO_NATIVE | GGO_UNHINTED, &metrics, 0, NULL, &identity); + double scale=1.0/daddy->fontSize; + n_g.h_advance=metrics.gmCellIncX*scale; + n_g.v_advance=otm.otmTextMetrics.tmHeight*scale; + n_g.h_width=metrics.gmBlackBoxX*scale; + n_g.v_width=metrics.gmBlackBoxY*scale; + n_g.outline=NULL; + if ( bufferSize == GDI_ERROR) { + // shit happened + } else if ( bufferSize == 0) { + // character has no visual representation, but is valid (eg whitespace) + doAdd=true; + } else { + std::auto_ptr buffer(new char[bufferSize]); + if ( GetGlyphOutline (daddy->hScreenDC, glyph_id, GGO_GLYPH_INDEX | GGO_NATIVE | GGO_UNHINTED, &metrics, bufferSize, buffer.get(), &identity) <= 0 ) { + // shit happened + } else { + // Platform SDK is rubbish, read KB87115 instead + n_g.outline=new Path; + DWORD polyOffset=0; + while ( polyOffset < bufferSize ) { + TTPOLYGONHEADER const *polyHeader=(TTPOLYGONHEADER const *)(buffer.get()+polyOffset); + if (polyOffset+polyHeader->cb > bufferSize) break; + + if (polyHeader->dwType == TT_POLYGON_TYPE) { + n_g.outline->MoveTo(pointfx_to_nrpoint(polyHeader->pfxStart, scale)); + DWORD curveOffset=polyOffset+sizeof(TTPOLYGONHEADER); + + while ( curveOffset < polyOffset+polyHeader->cb ) { + TTPOLYCURVE const *polyCurve=(TTPOLYCURVE const *)(buffer.get()+curveOffset); + POINTFX const *p=polyCurve->apfx; + POINTFX const *endp=p+polyCurve->cpfx; + + switch (polyCurve->wType) { + case TT_PRIM_LINE: + while ( p != endp ) + n_g.outline->LineTo(pointfx_to_nrpoint(*p++, scale)); + break; + + case TT_PRIM_QSPLINE: + { + g_assert(polyCurve->cpfx >= 2); + endp -= 2; + NR::Point this_mid=pointfx_to_nrpoint(p[0], scale); + while ( p != endp ) { + NR::Point next_mid=pointfx_to_nrpoint(p[1], scale); + n_g.outline->BezierTo((next_mid+this_mid)/2); + n_g.outline->IntermBezierTo(this_mid); + n_g.outline->EndBezierTo(); + ++p; + this_mid=next_mid; + } + n_g.outline->BezierTo(pointfx_to_nrpoint(p[1], scale)); + n_g.outline->IntermBezierTo(this_mid); + n_g.outline->EndBezierTo(); + break; + } + + case 3: // TT_PRIM_CSPLINE + g_assert(polyCurve->cpfx % 3 == 0); + while ( p != endp ) { + n_g.outline->CubicTo(pointfx_to_nrpoint(p[2], scale), pointfx_to_nrpoint(p[0], scale), pointfx_to_nrpoint(p[1], scale)); + p += 3; + } + break; + } + curveOffset += sizeof(TTPOLYCURVE)+sizeof(POINTFX)*(polyCurve->cpfx-1); + } + n_g.outline->Close(); + } + polyOffset += polyHeader->cb; + } + doAdd=true; + } + } +#else + if (FT_Load_Glyph (theFace, glyph_id, FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP)) { + // shit happened + } else { + if ( FT_HAS_HORIZONTAL(theFace) ) { + n_g.h_advance=((double)theFace->glyph->metrics.horiAdvance)/((double)theFace->units_per_EM); + n_g.h_width=((double)theFace->glyph->metrics.width)/((double)theFace->units_per_EM); + } else { + n_g.h_width=n_g.h_advance=((double)(theFace->bbox.xMax-theFace->bbox.xMin))/((double)theFace->units_per_EM); + } + if ( FT_HAS_VERTICAL(theFace) ) { + n_g.v_advance=((double)theFace->glyph->metrics.vertAdvance)/((double)theFace->units_per_EM); + n_g.v_width=((double)theFace->glyph->metrics.height)/((double)theFace->units_per_EM); + } else { + n_g.v_width=n_g.v_advance=((double)theFace->height)/((double)theFace->units_per_EM); + } + if ( theFace->glyph->format == ft_glyph_format_outline ) { + FT_Outline_Funcs ft2_outline_funcs = { + ft2_move_to, + ft2_line_to, + ft2_conic_to, + ft2_cubic_to, + 0, 0 + }; + n_g.outline=new Path; + ft2_to_liv tData; + tData.theP=n_g.outline; + tData.scale=1.0/((double)theFace->units_per_EM); + tData.last=NR::Point(0,0); + FT_Outline_Decompose (&theFace->glyph->outline, &ft2_outline_funcs, &tData); + } + doAdd=true; + } +#endif + + if ( doAdd ) { + if ( n_g.outline ) { + n_g.outline->FastBBox(n_g.bbox[0],n_g.bbox[1],n_g.bbox[2],n_g.bbox[3]); + n_g.artbpath=n_g.outline->MakeArtBPath(); + } + glyphs[nbGlyph]=n_g; + id_to_no[glyph_id]=nbGlyph; + nbGlyph++; + } + } else { + } +} + +bool font_instance::FontMetrics(double &ascent,double &descent,double &leading) +{ + if ( pFont == NULL ) return false; + InitTheFace(); + if ( theFace == NULL ) return false; +#ifdef USE_PANGO_WIN32 + OUTLINETEXTMETRIC otm; + if ( !GetOutlineTextMetrics(daddy->hScreenDC,sizeof(otm),&otm) ) return false; + double scale=1.0/daddy->fontSize; + ascent=fabs(otm.otmAscent*scale); + descent=fabs(otm.otmDescent*scale); + leading=fabs(otm.otmLineGap*scale); +#else + if ( theFace->units_per_EM == 0 ) return false; // bitmap font + ascent=fabs(((double)theFace->ascender)/((double)theFace->units_per_EM)); + descent=fabs(((double)theFace->descender)/((double)theFace->units_per_EM)); + leading=fabs(((double)theFace->height)/((double)theFace->units_per_EM)); + leading-=ascent+descent; +#endif + return true; +} + +bool font_instance::FontSlope(double &run, double &rise) +{ + run = 0.0; + rise = 1.0; + + if ( pFont == NULL ) return false; + InitTheFace(); + if ( theFace == NULL ) return false; + +#ifdef USE_PANGO_WIN32 + OUTLINETEXTMETRIC otm; + if ( !GetOutlineTextMetrics(daddy->hScreenDC,sizeof(otm),&otm) ) return false; + run=otm.otmsCharSlopeRun; + rise=otm.otmsCharSlopeRise; +#else + if ( theFace->units_per_EM == 0 ) return false; // bitmap font + + TT_HoriHeader *hhea = (TT_HoriHeader*)FT_Get_Sfnt_Table(theFace, ft_sfnt_hhea); + if (hhea == NULL) return false; + run = hhea->caret_Slope_Run; + rise = hhea->caret_Slope_Rise; +#endif + return true; +} + +NR::Rect font_instance::BBox(int glyph_id) +{ + int no=-1; + if ( id_to_no.find(glyph_id) == id_to_no.end() ) { + LoadGlyph(glyph_id); + if ( id_to_no.find(glyph_id) == id_to_no.end() ) { + // didn't load + } else { + no=id_to_no[glyph_id]; + } + } else { + no=id_to_no[glyph_id]; + } + if ( no < 0 ) return NR::Rect(NR::Point(0,0),NR::Point(0,0)); + NR::Point rmin(glyphs[no].bbox[0],glyphs[no].bbox[1]); + NR::Point rmax(glyphs[no].bbox[2],glyphs[no].bbox[3]); + NR::Rect res(rmin,rmax); + return res; +} + +Path* font_instance::Outline(int glyph_id,Path* copyInto) +{ + int no=-1; + if ( id_to_no.find(glyph_id) == id_to_no.end() ) { + LoadGlyph(glyph_id); + if ( id_to_no.find(glyph_id) == id_to_no.end() ) { + // didn't load + } else { + no=id_to_no[glyph_id]; + } + } else { + no=id_to_no[glyph_id]; + } + if ( no < 0 ) return NULL; + Path* src_o=glyphs[no].outline; + if ( copyInto ) { + copyInto->Reset(); + copyInto->Copy(src_o); + return copyInto; + } + return src_o; +} + +void* font_instance::ArtBPath(int glyph_id) +{ + int no=-1; + if ( id_to_no.find(glyph_id) == id_to_no.end() ) { + LoadGlyph(glyph_id); + if ( id_to_no.find(glyph_id) == id_to_no.end() ) { + // didn't load + } else { + no=id_to_no[glyph_id]; + } + } else { + no=id_to_no[glyph_id]; + } + if ( no < 0 ) return NULL; + return glyphs[no].artbpath; +} + +double font_instance::Advance(int glyph_id,bool vertical) +{ + int no=-1; + if ( id_to_no.find(glyph_id) == id_to_no.end() ) { + LoadGlyph(glyph_id); + if ( id_to_no.find(glyph_id) == id_to_no.end() ) { + // didn't load + } else { + no=id_to_no[glyph_id]; + } + } else { + no=id_to_no[glyph_id]; + } + if ( no >= 0 ) { + if ( vertical ) { + return glyphs[no].v_advance; + } else { + return glyphs[no].h_advance; + } + } + return 0; +} + + +raster_font* font_instance::RasterFont(const NR::Matrix &trs,double stroke_width,bool vertical,JoinType stroke_join,ButtType stroke_cap,float miter_limit) +{ + font_style nStyle; + nStyle.transform=trs; + nStyle.vertical=vertical; + nStyle.stroke_width=stroke_width; + nStyle.stroke_cap=stroke_cap; + nStyle.stroke_join=stroke_join; + nStyle.nbDash=0; + nStyle.dash_offset=0; + nStyle.dashes=NULL; + return RasterFont(nStyle); +} + +raster_font* font_instance::RasterFont(const font_style &inStyle) +{ + raster_font *res=NULL; + double *savDashes=NULL; + font_style nStyle=inStyle; + // for some evil reason font_style doesn't have a copy ctor, so the + // stuff that should be done there is done here instead (because the + // raster_font ctor copies nStyle). + if ( nStyle.stroke_width > 0 && nStyle.nbDash > 0 && nStyle.dashes ) { + savDashes=nStyle.dashes; + nStyle.dashes=(double*)malloc(nStyle.nbDash*sizeof(double)); + memcpy(nStyle.dashes,savDashes,nStyle.nbDash*sizeof(double)); + } + if ( loadedStyles.find(nStyle) == loadedStyles.end() ) { + raster_font *nR = new raster_font(nStyle); + nR->Ref(); + nR->daddy=this; + loadedStyles[nStyle]=nR; + res=nR; + if ( res ) Ref(); + } else { + res=loadedStyles[nStyle]; + res->Ref(); + if ( nStyle.dashes ) free(nStyle.dashes); // since they're not taken by a new rasterfont + } + nStyle.dashes=savDashes; + return res; +} + +void font_instance::RemoveRasterFont(raster_font* who) +{ + if ( who == NULL ) return; + if ( loadedStyles.find(who->style) == loadedStyles.end() ) { + //g_print("RemoveRasterFont failed \n"); + // not found + } else { + loadedStyles.erase(loadedStyles.find(who->style)); + //g_print("RemoveRasterFont\n"); + Unref(); + } +} + + + +/* + 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 : diff --git a/src/libnrtype/Layout-TNG-Compute.cpp b/src/libnrtype/Layout-TNG-Compute.cpp new file mode 100755 index 000000000..0fbbb6f0c --- /dev/null +++ b/src/libnrtype/Layout-TNG-Compute.cpp @@ -0,0 +1,1514 @@ +/* + * Inkscape::Text::Layout::Calculator - text layout engine meaty bits + * + * Authors: + * Richard Hughes + * + * Copyright (C) 2005 Richard Hughes + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ +#include "Layout-TNG.h" +#include "style.h" +#include "font-instance.h" +#include "svg/svg-length.h" +#include "sp-object.h" +#include "Layout-TNG-Scanline-Maker.h" + +namespace Inkscape { +namespace Text { + +//#define IFTRACE(_code) _code +//#define TRACE(_args) g_print _args +#define IFTRACE(_code) +#define TRACE(_args) + +// ******* enum conversion tables +static Layout::EnumConversionItem const enum_convert_spstyle_direction_to_pango_direction[] = { + {SP_CSS_WRITING_MODE_LR_TB, PANGO_DIRECTION_LTR}, + {SP_CSS_WRITING_MODE_RL_TB, PANGO_DIRECTION_RTL}, + {SP_CSS_WRITING_MODE_TB_LR, PANGO_DIRECTION_LTR}}; // this is correct + +static Layout::EnumConversionItem const enum_convert_spstyle_direction_to_my_direction[] = { + {SP_CSS_WRITING_MODE_LR_TB, Layout::LEFT_TO_RIGHT}, + {SP_CSS_WRITING_MODE_RL_TB, Layout::RIGHT_TO_LEFT}, + {SP_CSS_WRITING_MODE_TB_LR, Layout::LEFT_TO_RIGHT}}; // this is correct + +/** \brief private to Layout. Does the real work of text flowing. + +This class does a standard greedy paragraph wrapping algorithm. + +Very high-level overview: + +
+foreach(paragraph) {
+  call pango_itemize() (_buildPangoItemizationForPara())
+  break into spans, without dealing with wrapping (_buildSpansForPara())
+  foreach(line in flow shape) {
+    foreach(chunk in flow shape) {   (in _buildChunksInScanRun())
+      // this inner loop in _measureUnbrokenSpan()
+      if the line height changed discard the line and start again
+      keep adding characters until we run out of space in the chunk, then back up to the last word boundary
+      (do sensible things if there is no previous word break)
+    }
+    push all the glyphs, chars, spans, chunks and line to output (not completely trivial because we must draw rtl in character order) (in _outputLine())
+  }
+  push the paragraph (in calculate())
+}
+
+ +...and all of that needs to work vertically too, and with all the little details that make life annoying +*/ +class Layout::Calculator +{ + class SpanPosition; + friend class SpanPosition; + + Layout &_flow; + + ScanlineMaker *_scanline_maker; + + unsigned _current_shape_index; /// index into Layout::_input_wrap_shapes + + PangoContext *_pango_context; + + Direction _block_progression; + + /** for y= attributes in tspan elements et al, we do the adjustment by moving each + glyph individually by this number. The spec means that this is maintained across + paragraphs. */ + double _y_offset; + + /** to stop pango from hinting its output, the font factory creates all fonts very large. + All numbers returned from pango have to be divided by this number \em and divided by + PANGO_SCALE. See font_factory::font_factory(). */ + double _font_factory_size_multiplier; + + /** Temporary storage associated with each item in Layout::_input_stream. */ + struct InputItemInfo { + bool in_sub_flow; + Layout *sub_flow; // this is only set for the first input item in a sub-flow + + InputItemInfo() : in_sub_flow(false), sub_flow(NULL) {} + void free(); + }; + + /** Temporary storage associated with each item returned by the call to + pango_itemize(). */ + struct PangoItemInfo { + PangoItem *item; + font_instance *font; + + PangoItemInfo() : item(NULL), font(NULL) {} + void free(); + }; + + /** These spans have approximately the same definition as that used for + Layout::Span (constant font, direction, etc), except that they are from + before we have located the line breaks, so bear no relation to chunks. + They are guaranteed to be in at most one PangoItem (spans with no text in + them will not have an associated PangoItem), exactly one input source and + will only have one change of x, y, dx, dy or rotate attribute, which will + be at the beginning. An UnbrokenSpan can cross a chunk boundary, c.f. + BrokenSpan. */ + struct UnbrokenSpan { + PangoGlyphString *glyph_string; + int pango_item_index; /// index into _para.pango_items, or -1 if this is style only + unsigned input_index; /// index into Layout::_input_stream + Glib::ustring::const_iterator input_stream_first_character; + double font_size; + LineHeight line_height; + double line_height_multiplier; /// calculated from the font-height css property + unsigned text_bytes; + unsigned char_index_in_para; /// the index of the first character in this span in the paragraph, for looking up char_attributes + SVGLength x, y, dx, dy, rotate; // these are reoriented copies of the attributes. We change span when we encounter one. + + UnbrokenSpan() : glyph_string(NULL) {} + void free() {if (glyph_string) pango_glyph_string_free(glyph_string); glyph_string = NULL;} + }; + + /** a useful little iterator for moving char-by-char across spans. */ + struct UnbrokenSpanPosition { + std::vector::iterator iter_span; + unsigned char_byte; + unsigned char_index; + + void increment(); ///< Step forward by one character. + + inline bool operator== (UnbrokenSpanPosition const &other) const + {return char_byte == other.char_byte && iter_span == other.iter_span;} + inline bool operator!= (UnbrokenSpanPosition const &other) const + {return char_byte != other.char_byte || iter_span != other.iter_span;} + }; + + /** The line breaking algorithm will convert each UnbrokenSpan into one + or more of these. A BrokenSpan will never cross a chunk boundary, c.f. + UnbrokenSpan. */ + struct BrokenSpan { + UnbrokenSpanPosition start; + UnbrokenSpanPosition end; // the end of this will always be the same as the start of the next + unsigned start_glyph_index; + unsigned end_glyph_index; + double width; + unsigned whitespace_count; + bool ends_with_whitespace; + double each_whitespace_width; + void setZero(); + }; + + /** The definition of a chunk used here is the same as that used in Layout. */ + struct ChunkInfo { + std::vector broken_spans; + double scanrun_width; + double text_width; ///< Total width used by the text (excluding justification). + double x; + int whitespace_count; + }; + + /** Used to provide storage for anything that applies to the current + paragraph only. Since we're only processing one paragraph at a time, + there's only one instantiation of this struct, on the stack of + calculate(). */ + struct ParagraphInfo { + unsigned first_input_index; ///< Index into Layout::_input_stream. + Direction direction; + Alignment alignment; + std::vector input_items; + std::vector pango_items; + std::vector char_attributes; ///< For every character in the paragraph. + std::vector unbroken_spans; + + template static void free_sequence(T &seq); + void free(); + }; + +/* *********************************************************************************************************/ +// Initialisation of ParagraphInfo structure + + +#if 0 /* unused */ + void _initialiseInputItems(ParagraphInfo *para) const; +#endif + + void _buildPangoItemizationForPara(ParagraphInfo *para) const; + + static void _computeFontLineHeight(font_instance *font, double font_size, + SPStyle const *style, LineHeight *line_height, + double *line_height_multiplier); + + unsigned _buildSpansForPara(ParagraphInfo *para) const; + +/* *********************************************************************************************************/ +// Per-line functions + + + bool _goToNextWrapShape(); + + bool _findChunksForLine(ParagraphInfo const ¶, UnbrokenSpanPosition *start_span_pos, + std::vector *chunk_info, LineHeight *line_height); + + static inline PangoLogAttr const &_charAttributes(ParagraphInfo const ¶, + UnbrokenSpanPosition const &span_pos) + { + return para.char_attributes[span_pos.iter_span->char_index_in_para + span_pos.char_index]; + } + + bool _buildChunksInScanRun(ParagraphInfo const ¶, + UnbrokenSpanPosition const &start_span_pos, + ScanlineMaker::ScanRun const &scan_run, + std::vector *chunk_info, + LineHeight *line_height) const; + + /** computes the width of a single UnbrokenSpan (pointed to by span->start.iter_span) + and outputs its vital statistics into the other fields of \a span. + Measuring will stop if maximum_width is reached and in that case the + function will return false. In other cases where a line break must be + done immediately the function will also return false. On return + \a last_break_span will contain the vital statistics for the span only + up to the last line breaking change. If there are no line breaking + characters in the span then \a last_break_span will not be altered. + Similarly, \a last_emergency_break_span will contain the vital + statistics for the span up to the last inter-character boundary, + or will be unaltered if there is none. */ + bool _measureUnbrokenSpan(ParagraphInfo const ¶, BrokenSpan *span, BrokenSpan *last_break_span, BrokenSpan *last_emergency_break_span, double maximum_width) const + { + span->setZero(); + + if (span->start.iter_span->dx._set && span->start.char_byte == 0) + span->width += span->start.iter_span->dx.computed; + + if (span->start.iter_span->pango_item_index == -1) { + // if this is a style-only span there's no text in it + // so we don't need to do very much at all + span->end.iter_span++; + return true; + } + + if (_flow._input_stream[span->start.iter_span->input_index]->Type() == CONTROL_CODE) { + InputStreamControlCode const *control_code = static_cast(_flow._input_stream[span->start.iter_span->input_index]); + if (control_code->code == SHAPE_BREAK || control_code->code == PARAGRAPH_BREAK) { + *last_emergency_break_span = *last_break_span = *span; + return false; + } + if (control_code->code == ARBITRARY_GAP) { + if (span->width + control_code->width > maximum_width) + return false; + TRACE(("fitted control code, width = %f\n", control_code->width)); + span->width += control_code->width; + span->end.increment(); + } + return true; + + } + + if (_flow._input_stream[span->start.iter_span->input_index]->Type() != TEXT_SOURCE) + return true; // never happens + + InputStreamTextSource const *text_source = static_cast(_flow._input_stream[span->start.iter_span->input_index]); + + if (_directions_are_orthogonal(_block_progression, text_source->styleGetBlockProgression())) { + // TODO: block-progression altered in the middle + // Measure the precomputed flow from para.input_items + span->end.iter_span++; // for now, skip to the next span + return true; + } + + // a normal span going with a normal block-progression + double font_size_multiplier = span->start.iter_span->font_size / (PANGO_SCALE * _font_factory_size_multiplier); + double soft_hyphen_glyph_width = 0.0; + bool soft_hyphen_in_word = false; + bool is_soft_hyphen = false; + IFTRACE(int char_count = 0); + + // if we're not at the start of the span we need to pre-init glyph_index + span->start_glyph_index = 0; + while (span->start_glyph_index < (unsigned)span->start.iter_span->glyph_string->num_glyphs + && span->start.iter_span->glyph_string->log_clusters[span->start_glyph_index] < (int)span->start.char_byte) + span->start_glyph_index++; + span->end_glyph_index = span->start_glyph_index; + + // go char-by-char summing the width, while keeping track of the previous break point + do { + PangoLogAttr const &char_attributes = _charAttributes(para, span->end); + + if (char_attributes.is_mandatory_break) { + *last_emergency_break_span = *last_break_span = *span; + TRACE(("span %d end of para; width = %f chars = %d\n", span->start.iter_span - para.unbroken_spans.begin(), span->width, char_count)); + return false; + } + + if (char_attributes.is_line_break) { + // a suitable position to break at, record where we are + *last_emergency_break_span = *last_break_span = *span; + if (soft_hyphen_in_word) { + // if there was a previous soft hyphen we're not going to need it any more so we can remove it + span->width -= soft_hyphen_glyph_width; + if (!is_soft_hyphen) + soft_hyphen_in_word = false; + } + } else if (char_attributes.is_char_break) { + *last_emergency_break_span = *span; + } + // todo: break between chars if necessary (ie no word breaks present) when doing rectangular flowing + + // sum the glyph widths, letter spacing and word spacing to get the character width + double char_width = 0.0; + while (span->end_glyph_index < (unsigned)span->end.iter_span->glyph_string->num_glyphs + && span->end.iter_span->glyph_string->log_clusters[span->end_glyph_index] <= (int)span->end.char_byte) { + if (_block_progression == LEFT_TO_RIGHT || _block_progression == RIGHT_TO_LEFT) + char_width += span->start.iter_span->font_size * para.pango_items[span->end.iter_span->pango_item_index].font->Advance(span->end.iter_span->glyph_string->glyphs[span->end_glyph_index].glyph, true); + else + char_width += font_size_multiplier * span->end.iter_span->glyph_string->glyphs[span->end_glyph_index].geometry.width; + span->end_glyph_index++; + } + if (char_attributes.is_cursor_position) + char_width += text_source->style->letter_spacing.computed; + if (char_attributes.is_white) + char_width += text_source->style->word_spacing.computed; + span->width += char_width; + IFTRACE(char_count++); + + if (char_attributes.is_white) { + span->whitespace_count++; + span->each_whitespace_width = char_width; + } + span->ends_with_whitespace = char_attributes.is_white; + + is_soft_hyphen = (UNICODE_SOFT_HYPHEN == *Glib::ustring::const_iterator(span->end.iter_span->input_stream_first_character.base() + span->end.char_byte)); + if (is_soft_hyphen) + soft_hyphen_glyph_width = char_width; + + span->end.increment(); + + if (span->width > maximum_width && !char_attributes.is_white) { // whitespaces don't matter, we can put as many as we want at eol + TRACE(("span %d exceeded scanrun; width = %f chars = %d\n", span->start.iter_span - para.unbroken_spans.begin(), span->width, char_count)); + return false; + } + + } while (span->end.char_byte != 0); // while we haven't wrapped to the next span + TRACE(("fitted span %d width = %f chars = %d\n", span->start.iter_span - para.unbroken_spans.begin(), span->width, char_count)); + return true; + } + +/* *********************************************************************************************************/ +// Per-line functions (output) + + /** Uses the paragraph alignment and the chunk information to work out + where the actual left of the final chunk must be. Also sets + \a add_to_each_whitespace to be the amount of x to add at each + whitespace character to make full justification work. */ + double _getChunkLeftWithAlignment(ParagraphInfo const ¶, std::vector::const_iterator it_chunk, double *add_to_each_whitespace) const + { + *add_to_each_whitespace = 0.0; + if (_flow._input_wrap_shapes.empty()) { + switch (para.alignment) { + case FULL: + case LEFT: + default: + return it_chunk->x; + case RIGHT: + return it_chunk->x - it_chunk->text_width; + case CENTER: + return it_chunk->x - it_chunk->text_width / 2; + } + } + + switch (para.alignment) { + case FULL: + if (!it_chunk->broken_spans.empty() + && it_chunk->broken_spans.back().end.iter_span != para.unbroken_spans.end()) { // don't justify the last chunk in the para + if (it_chunk->whitespace_count) + *add_to_each_whitespace = (it_chunk->scanrun_width - it_chunk->text_width) / it_chunk->whitespace_count; + //else + //add_to_each_charspace = something + } + return it_chunk->x; + case LEFT: + default: + return it_chunk->x; + case RIGHT: + return it_chunk->x + it_chunk->scanrun_width - it_chunk->text_width; + case CENTER: + return it_chunk->x + (it_chunk->scanrun_width - it_chunk->text_width) / 2; + } + } + + /** Once we've got here we have finished making changes to the line and + are ready to output the final result to #_flow. This method takes its + input parameters and does that. + */ + void _outputLine(ParagraphInfo const ¶, LineHeight const &line_height, std::vector const &chunk_info) + { + if (chunk_info.empty()) { + TRACE(("line too short to fit anything on it, go to next\n")); + return; + } + + // we've finished fiddling about with ascents and descents: create the output + TRACE(("found line fit; creating output\n")); + Layout::Line new_line; + new_line.in_paragraph = _flow._paragraphs.size() - 1; + new_line.baseline_y = _scanline_maker->yCoordinate() + line_height.ascent; + new_line.in_shape = _current_shape_index; + _flow._lines.push_back(new_line); + + for (std::vector::const_iterator it_chunk = chunk_info.begin() ; it_chunk != chunk_info.end() ; it_chunk++) { + + double add_to_each_whitespace; + // add the chunk to the list + Layout::Chunk new_chunk; + new_chunk.in_line = _flow._lines.size() - 1; + new_chunk.left_x = _getChunkLeftWithAlignment(para, it_chunk, &add_to_each_whitespace); + // we may also have y move orders to deal with here (dx, dy and rotate are done per span) + if (!it_chunk->broken_spans.empty() // this one only happens for empty paragraphs + && it_chunk->broken_spans.front().start.char_byte == 0 + && it_chunk->broken_spans.front().start.iter_span->y._set) { + // if this is the start of a line, we should change the baseline rather than each glyph individually + if (_flow._characters.empty() || _flow._characters.back().chunk(&_flow).in_line != _flow._lines.size() - 1) { + new_line.baseline_y = it_chunk->broken_spans.front().start.iter_span->y.computed; + _flow._lines.back().baseline_y = new_line.baseline_y; + _y_offset = 0.0; + _scanline_maker->setNewYCoordinate(new_line.baseline_y - line_height.ascent); + } else + _y_offset = it_chunk->broken_spans.front().start.iter_span->y.computed - new_line.baseline_y; + } + _flow._chunks.push_back(new_chunk); + + double x; + double direction_sign; + Direction previous_direction = para.direction; + double counter_directional_width_remaining = 0.0; + float glyph_rotate = 0.0; + if (para.direction == LEFT_TO_RIGHT) { + direction_sign = +1.0; + x = 0.0; + } else { + direction_sign = -1.0; + if (para.alignment == FULL && !_flow._input_wrap_shapes.empty()) + x = it_chunk->scanrun_width; + else + x = it_chunk->text_width; + } + + for (std::vector::const_iterator it_span = it_chunk->broken_spans.begin() ; it_span != it_chunk->broken_spans.end() ; it_span++) { + // begin adding spans to the list + UnbrokenSpan const &unbroken_span = *it_span->start.iter_span; + + if (it_span->start.char_byte == 0) { + // start of an unbroken span, we might have dx, dy or rotate still to process (x and y are done per chunk) + if (unbroken_span.dx._set) x += unbroken_span.dx.computed; + if (unbroken_span.dy._set) _y_offset += unbroken_span.dy.computed; + if (unbroken_span.rotate._set) glyph_rotate = unbroken_span.rotate.computed * (M_PI/180); + } + + if (_flow._input_stream[unbroken_span.input_index]->Type() == TEXT_SOURCE + && unbroken_span.pango_item_index == -1) { + // style only, nothing to output + continue; + } + + Layout::Span new_span; + double x_in_span = 0.0; + + new_span.in_chunk = _flow._chunks.size() - 1; + new_span.line_height = unbroken_span.line_height; + new_span.in_input_stream_item = unbroken_span.input_index; + new_span.baseline_shift = _y_offset; + new_span.block_progression = _block_progression; + if (_flow._input_stream[unbroken_span.input_index]->Type() == TEXT_SOURCE) { + new_span.font = para.pango_items[unbroken_span.pango_item_index].font; + new_span.font->Ref(); + new_span.font_size = unbroken_span.font_size; + new_span.direction = para.pango_items[unbroken_span.pango_item_index].item->analysis.level & 1 ? RIGHT_TO_LEFT : LEFT_TO_RIGHT; + new_span.input_stream_first_character = Glib::ustring::const_iterator(unbroken_span.input_stream_first_character.base() + it_span->start.char_byte); + } else { // a control code + new_span.font = NULL; + new_span.font_size = new_span.line_height.ascent + new_span.line_height.descent; + new_span.direction = para.direction; + } + + if (new_span.direction == para.direction) { + x -= counter_directional_width_remaining; + counter_directional_width_remaining = 0.0; + } else if (new_span.direction != previous_direction) { + // measure width of spans we need to switch round + counter_directional_width_remaining = 0.0; + std::vector::const_iterator it_following_span; + for (it_following_span = it_span ; it_following_span != it_chunk->broken_spans.end() ; it_following_span++) { + Layout::Direction following_span_progression = static_cast(_flow._input_stream[it_following_span->start.iter_span->input_index])->styleGetBlockProgression(); + if (!Layout::_directions_are_orthogonal(following_span_progression, _block_progression)) { + if (it_following_span->start.iter_span->pango_item_index == -1) { // when the span came from a control code + if (new_span.direction != para.direction) break; + } else + if (new_span.direction != (para.pango_items[it_following_span->start.iter_span->pango_item_index].item->analysis.level & 1 ? RIGHT_TO_LEFT : LEFT_TO_RIGHT)) break; + } + counter_directional_width_remaining += direction_sign * (it_following_span->width + it_following_span->whitespace_count * add_to_each_whitespace); + } + x += counter_directional_width_remaining; + counter_directional_width_remaining = 0.0; // we want to go increasingly negative + } + new_span.x_start = x; + + if (_flow._input_stream[unbroken_span.input_index]->Type() == TEXT_SOURCE) { + // the span is set up, push the glyphs and chars + InputStreamTextSource const *text_source = static_cast(_flow._input_stream[unbroken_span.input_index]); + Glib::ustring::const_iterator iter_source_text = Glib::ustring::const_iterator(unbroken_span.input_stream_first_character.base() + it_span->start.char_byte) ; + unsigned char_index_in_unbroken_span = it_span->start.char_index; + unsigned cluster_start_char_index = _flow._characters.size(); + double font_size_multiplier = new_span.font_size / (PANGO_SCALE * _font_factory_size_multiplier); + + for (unsigned glyph_index = it_span->start_glyph_index ; glyph_index < it_span->end_glyph_index ; glyph_index++) { + unsigned char_byte = iter_source_text.base() - unbroken_span.input_stream_first_character.base(); + if (unbroken_span.glyph_string->glyphs[glyph_index].attr.is_cluster_start) + cluster_start_char_index = _flow._characters.size(); + + if (unbroken_span.glyph_string->log_clusters[glyph_index] < (int)unbroken_span.text_bytes + && *iter_source_text == UNICODE_SOFT_HYPHEN + && it_span + 1 != it_chunk->broken_spans.end() + && glyph_index + 1 != it_span->end_glyph_index) { + // if we're looking at a soft hyphen and it's not the last glyph in the + // chunk we don't draw the glyph but we still need to add to _characters + Layout::Character new_character; + new_character.in_span = _flow._spans.size(); // the span hasn't been added yet, so no -1 + new_character.char_attributes = para.char_attributes[unbroken_span.char_index_in_para + char_index_in_unbroken_span]; + new_character.in_glyph = -1; + _flow._characters.push_back(new_character); + iter_source_text++; + char_index_in_unbroken_span++; + while (glyph_index < (unsigned)unbroken_span.glyph_string->num_glyphs + && unbroken_span.glyph_string->log_clusters[glyph_index] == (int)char_byte) + glyph_index++; + glyph_index--; + continue; + } + + // create the Layout::Glyph + Layout::Glyph new_glyph; + new_glyph.glyph = unbroken_span.glyph_string->glyphs[glyph_index].glyph; + new_glyph.in_character = cluster_start_char_index; + new_glyph.rotation = glyph_rotate; + + /* put something like this back in when we do glyph-rotation-horizontal/vertical + if (new_span.block_progression == LEFT_TO_RIGHT || new_span.block_progression == RIGHT_TO_LEFT) { + new_glyph.x += new_span.line_height.ascent; + new_glyph.y -= unbroken_span.glyph_string->glyphs[glyph_index].geometry.width * font_size_multiplier * 0.5; + new_glyph.width = new_span.line_height.ascent + new_span.line_height.descent; + } else */ + + if (_block_progression == LEFT_TO_RIGHT || _block_progression == RIGHT_TO_LEFT) { + new_glyph.x = x + unbroken_span.glyph_string->glyphs[glyph_index].geometry.x_offset * font_size_multiplier + new_span.line_height.ascent; + new_glyph.y = _y_offset + (unbroken_span.glyph_string->glyphs[glyph_index].geometry.y_offset - unbroken_span.glyph_string->glyphs[glyph_index].geometry.width * 0.5) * font_size_multiplier; + new_glyph.width = new_span.font_size * para.pango_items[unbroken_span.pango_item_index].font->Advance(unbroken_span.glyph_string->glyphs[glyph_index].glyph, true); + } else { + new_glyph.x = x + unbroken_span.glyph_string->glyphs[glyph_index].geometry.x_offset * font_size_multiplier; + new_glyph.y = _y_offset + unbroken_span.glyph_string->glyphs[glyph_index].geometry.y_offset * font_size_multiplier; + new_glyph.width = unbroken_span.glyph_string->glyphs[glyph_index].geometry.width * font_size_multiplier; + if (new_glyph.width == 0) + new_glyph.width = new_span.font_size * para.pango_items[unbroken_span.pango_item_index].font->Advance(unbroken_span.glyph_string->glyphs[glyph_index].glyph, false); + // for some reason pango returns zero width for invalid glyph characters (those empty boxes), so go to freetype for the info + } + if (new_span.direction == RIGHT_TO_LEFT) { + // pango wanted to give us glyphs in visual order but we refused, so we need to work + // out where the cluster start is ourselves + double cluster_width = 0.0; + for (unsigned rtl_index = glyph_index; rtl_index < it_span->end_glyph_index ; rtl_index++) { + if (unbroken_span.glyph_string->glyphs[rtl_index].attr.is_cluster_start && rtl_index != glyph_index) + break; + if (_block_progression == LEFT_TO_RIGHT || _block_progression == RIGHT_TO_LEFT) + cluster_width += new_span.font_size * para.pango_items[unbroken_span.pango_item_index].font->Advance(unbroken_span.glyph_string->glyphs[rtl_index].glyph, true); + else + cluster_width += font_size_multiplier * unbroken_span.glyph_string->glyphs[rtl_index].geometry.width; + } + new_glyph.x -= cluster_width; + } + _flow._glyphs.push_back(new_glyph); + + // create the Layout::Character(s) + double advance_width = new_glyph.width; + unsigned end_byte; + if (glyph_index == (unsigned)unbroken_span.glyph_string->num_glyphs - 1) + end_byte = it_span->start.iter_span->text_bytes; + else { + // output chars for the whole cluster that is commenced by this glyph + if (unbroken_span.glyph_string->glyphs[glyph_index].attr.is_cluster_start) { + int next_cluster_glyph_index = glyph_index + 1; + while (next_cluster_glyph_index < unbroken_span.glyph_string->num_glyphs + && !unbroken_span.glyph_string->glyphs[next_cluster_glyph_index].attr.is_cluster_start) + next_cluster_glyph_index++; + if (next_cluster_glyph_index < unbroken_span.glyph_string->num_glyphs) + end_byte = unbroken_span.glyph_string->log_clusters[next_cluster_glyph_index]; + else + end_byte = it_span->start.iter_span->text_bytes; + } else + end_byte = char_byte; // don't output any chars if we're not at the start of a cluster + } + while (char_byte < end_byte) { + Layout::Character new_character; + new_character.in_span = _flow._spans.size(); + new_character.x = x_in_span; + new_character.char_attributes = para.char_attributes[unbroken_span.char_index_in_para + char_index_in_unbroken_span]; + new_character.in_glyph = _flow._glyphs.size() - 1; + _flow._characters.push_back(new_character); + if (new_character.char_attributes.is_white) + advance_width += text_source->style->word_spacing.computed + add_to_each_whitespace; // justification + if (new_character.char_attributes.is_cursor_position) + advance_width += text_source->style->letter_spacing.computed; + iter_source_text++; + char_index_in_unbroken_span++; + char_byte = iter_source_text.base() - unbroken_span.input_stream_first_character.base(); + glyph_rotate = 0.0; + } + + advance_width *= direction_sign; + if (new_span.direction != para.direction) { + counter_directional_width_remaining -= advance_width; + x -= advance_width; + x_in_span -= advance_width; + } else { + x += advance_width; + x_in_span += advance_width; + } + } + } else if (_flow._input_stream[unbroken_span.input_index]->Type() == CONTROL_CODE) { + x += static_cast(_flow._input_stream[unbroken_span.input_index])->width; + } + + new_span.x_end = new_span.x_start + x_in_span; + _flow._spans.push_back(new_span); + previous_direction = new_span.direction; + } + // end adding spans to the list, on to the next chunk... + } + TRACE(("output done\n")); + } + +/* *********************************************************************************************************/ +// Setup and top-level functions + + /** initialises the ScanlineMaker for the first shape in the flow, or + the infinite version if we're not doing wrapping. */ + void _createFirstScanlineMaker() + { + _current_shape_index = 0; + if (_flow._input_wrap_shapes.empty()) { + // create the special no-wrapping infinite scanline maker + double initial_x = 0, initial_y = 0; + InputStreamTextSource const *text_source = static_cast(_flow._input_stream.front()); + if (!text_source->x.empty()) + initial_x = text_source->x.front().computed; + if (!text_source->y.empty()) + initial_y = text_source->y.front().computed; + _scanline_maker = new InfiniteScanlineMaker(initial_x, initial_y, _block_progression); + TRACE((" wrapping disabled\n")); + } + else { + _scanline_maker = new ShapeScanlineMaker(_flow._input_wrap_shapes[_current_shape_index].shape, _block_progression); + TRACE((" begin wrap shape 0\n")); + } + } + +public: + Calculator(Layout *text_flow) + : _flow(*text_flow) {} + + bool calculate(); +}; + +/* fixme: I don't like the fact that InputItemInfo etc. use the default copy constructor and + * operator= (and thus don't involve incrementing reference counts), yet they provide a free method + * that does delete or Unref. + * + * I suggest using the garbage collector to manage deletion. + */ +void Layout::Calculator::InputItemInfo::free() +{ + if (sub_flow) { + delete sub_flow; + sub_flow = NULL; + } +} + +void Layout::Calculator::PangoItemInfo::free() +{ + if (item) { + pango_item_free(item); + item = NULL; + } + if (font) { + font->Unref(); + font = NULL; + } +} + +void Layout::Calculator::UnbrokenSpanPosition::increment() +{ + gchar const *text_base = &*iter_span->input_stream_first_character.base(); + char_byte = g_utf8_next_char(text_base + char_byte) - text_base; + char_index++; + if (char_byte == iter_span->text_bytes) { + iter_span++; + char_index = char_byte = 0; + } +} + +void Layout::Calculator::BrokenSpan::setZero() +{ + end = start; + width = 0.0; + whitespace_count = 0; + end_glyph_index = start_glyph_index = 0; + ends_with_whitespace = false; + each_whitespace_width = 0.0; +} + +template void Layout::Calculator::ParagraphInfo::free_sequence(T &seq) +{ + for (typename T::iterator it(seq.begin()); it != seq.end(); ++it) { + it->free(); + } + seq.clear(); +} + +void Layout::Calculator::ParagraphInfo::free() +{ + free_sequence(input_items); + free_sequence(pango_items); + free_sequence(unbroken_spans); +} + +///** +// * For sections of text with a block-progression different to the rest +// * of the flow, the best thing to do is to detect them in advance and +// * create child TextFlow objects with just the rotated text. In the +// * parent we then effectively use ARBITRARY_GAP fields during the +// * flowing (because we don't allow wrapping when the block-progression +// * changes) and copy the actual text in during the output phase. +// * +// * NB: this code not enabled yet. +// */ +//void Layout::Calculator::_initialiseInputItems(ParagraphInfo *para) const +//{ +// Direction prev_block_progression = _block_progression; +// int run_start_input_index = para->first_input_index; +// +// para->free_sequence(para->input_items); +// for(int input_index = para->first_input_index ; input_index < (int)_flow._input_stream.size() ; input_index++) { +// InputItemInfo input_item; +// +// input_item.in_sub_flow = false; +// input_item.sub_flow = NULL; +// if (_flow._input_stream[input_index]->Type() == CONTROL_CODE) { +// Layout::InputStreamControlCode const *control_code = static_cast(_flow._input_stream[input_index]); +// if ( control_code->code == SHAPE_BREAK +// || control_code->code == PARAGRAPH_BREAK) +// break; // stop at the end of the paragraph +// // all other control codes we'll pick up later +// +// } else if (_flow._input_stream[input_index]->Type() == TEXT_SOURCE) { +// Layout::InputStreamTextSource *text_source = static_cast(_flow._input_stream[input_index]); +// Direction this_block_progression = text_source->styleGetBlockProgression(); +// if (this_block_progression != prev_block_progression) { +// if (prev_block_progression != _block_progression) { +// // need to back up so that control codes belong outside the block-progression change +// int run_end_input_index = input_index - 1; +// while (run_end_input_index > run_start_input_index +// && _flow._input_stream[run_end_input_index]->Type() != TEXT_SOURCE) +// run_end_input_index--; +// // now create the sub-flow +// input_item.sub_flow = new Layout; +// for (int sub_input_index = run_start_input_index ; sub_input_index <= run_end_input_index ; sub_input_index++) { +// input_item.in_sub_flow = true; +// if (_flow._input_stream[sub_input_index]->Type() == CONTROL_CODE) { +// Layout::InputStreamControlCode const *control_code = static_cast(_flow._input_stream[sub_input_index]); +// input_item.sub_flow->appendControlCode(control_code->code, control_code->source_cookie, control_code->width, control_code->ascent, control_code->descent); +// } else if (_flow._input_stream[sub_input_index]->Type() == TEXT_SOURCE) { +// Layout::InputStreamTextSource *text_source = static_cast(_flow._input_stream[sub_input_index]); +// input_item.sub_flow->appendText(*text_source->text, text_source->style, text_source->source_cookie, NULL, 0, text_source->text_begin, text_source->text_end); +// Layout::InputStreamTextSource *sub_flow_text_source = static_cast(input_item.sub_flow->_input_stream.back()); +// sub_flow_text_source->x = text_source->x; // this is easier than going via optionalattrs for the appendText() call +// sub_flow_text_source->y = text_source->y; // should these actually be allowed anyway? You'll almost never get the results you expect +// sub_flow_text_source->dx = text_source->dx; // (not that it's very clear what you should expect, anyway) +// sub_flow_text_source->dy = text_source->dy; +// sub_flow_text_source->rotate = text_source->rotate; +// } +// } +// input_item.sub_flow->calculateFlow(); +// } +// run_start_input_index = input_index; +// } +// prev_block_progression = this_block_progression; +// } +// para->input_items.push_back(input_item); +// } +//} + +/** + * Take all the text from \a _para.first_input_index to the end of the + * paragraph and stitch it together so that pango_itemize() can be called on + * the whole thing. + * + * Input: para.first_input_index. + * Output: para.direction, para.pango_items, para.char_attributes. + */ +void Layout::Calculator::_buildPangoItemizationForPara(ParagraphInfo *para) const +{ + Glib::ustring para_text; + PangoAttrList *attributes_list; + unsigned input_index; + + para->free_sequence(para->pango_items); + para->char_attributes.clear(); + + TRACE(("itemizing para, first input %d\n", para->first_input_index)); + + attributes_list = pango_attr_list_new(); + for(input_index = para->first_input_index ; input_index < _flow._input_stream.size() ; input_index++) { + if (_flow._input_stream[input_index]->Type() == CONTROL_CODE) { + Layout::InputStreamControlCode const *control_code = static_cast(_flow._input_stream[input_index]); + if ( control_code->code == SHAPE_BREAK + || control_code->code == PARAGRAPH_BREAK) + break; // stop at the end of the paragraph + // all other control codes we'll pick up later + + } else if (_flow._input_stream[input_index]->Type() == TEXT_SOURCE) { + Layout::InputStreamTextSource *text_source = static_cast(_flow._input_stream[input_index]); + + // create the font_instance + font_instance *font = text_source->styleGetFontInstance(); + if (font == NULL) + continue; // bad news: we'll have to ignore all this text because we know of no font to render it + + PangoAttribute *attribute_font_description = pango_attr_font_desc_new(font->descr); + attribute_font_description->start_index = para_text.bytes(); + para_text.append(&*text_source->text_begin.base(), text_source->text_length); // build the combined text + attribute_font_description->end_index = para_text.bytes(); + pango_attr_list_insert(attributes_list, attribute_font_description); + // ownership of attribute is assumed by the list + } + } + + TRACE(("whole para: \"%s\"\n", para_text.data())); + TRACE(("%d input sources used\n", input_index - para->first_input_index)); + + // do the pango_itemize() + GList *pango_items_glist = NULL; + if (_flow._input_stream[para->first_input_index]->Type() == TEXT_SOURCE) { + Layout::InputStreamTextSource const *text_source = static_cast(_flow._input_stream[para->first_input_index]); + if (text_source->style->direction.set) { + PangoDirection pango_direction = (PangoDirection)_enum_converter(text_source->style->direction.computed, enum_convert_spstyle_direction_to_pango_direction, sizeof(enum_convert_spstyle_direction_to_pango_direction)/sizeof(enum_convert_spstyle_direction_to_pango_direction[0])); + pango_items_glist = pango_itemize_with_base_dir(_pango_context, pango_direction, para_text.data(), 0, para_text.bytes(), attributes_list, NULL); + para->direction = (Layout::Direction)_enum_converter(text_source->style->direction.computed, enum_convert_spstyle_direction_to_my_direction, sizeof(enum_convert_spstyle_direction_to_my_direction)/sizeof(enum_convert_spstyle_direction_to_my_direction[0])); + } + } + if (pango_items_glist == NULL) { // no direction specified, guess it + pango_items_glist = pango_itemize(_pango_context, para_text.data(), 0, para_text.bytes(), attributes_list, NULL); + + // I think according to the css spec this is wrong and we're never allowed to guess the directionality + // of a paragraph. Need to talk to an rtl speaker. + if (pango_items_glist == NULL || pango_items_glist->data == NULL) para->direction = LEFT_TO_RIGHT; + else para->direction = (((PangoItem*)pango_items_glist->data)->analysis.level & 1) ? RIGHT_TO_LEFT : LEFT_TO_RIGHT; + } + pango_attr_list_unref(attributes_list); + + // convert the GList to our vector<> and make the font_instance for each PangoItem at the same time + para->pango_items.reserve(g_list_length(pango_items_glist)); + TRACE(("para itemizes to %d sections\n", g_list_length(pango_items_glist))); + for (GList *current_pango_item = pango_items_glist ; current_pango_item != NULL ; current_pango_item = current_pango_item->next) { + PangoItemInfo new_item; + new_item.item = (PangoItem*)current_pango_item->data; + PangoFontDescription *font_description = pango_font_describe(new_item.item->analysis.font); + new_item.font = (font_factory::Default())->Face(font_description); + pango_font_description_free(font_description); // Face() makes a copy + para->pango_items.push_back(new_item); + } + g_list_free(pango_items_glist); + + // and get the character attributes on everything + para->char_attributes.resize(para_text.length() + 1); + pango_get_log_attrs(para_text.data(), para_text.bytes(), -1, NULL, &*para->char_attributes.begin(), para->char_attributes.size()); + + TRACE(("end para itemize, direction = %d\n", para->direction)); +} + +/** + * Gets the ascent, descent and leading for a font and the alteration that has to be performed + * according to the value specified by the line-height css property. The result of multiplying + * \a line_height by \a line_height_multiplier is the inline box height as specified in css2 + * section 10.8. + */ +void Layout::Calculator::_computeFontLineHeight(font_instance *font, double font_size, + SPStyle const *style, LineHeight *line_height, + double *line_height_multiplier) +{ + if (font == NULL) { + line_height->setZero(); + *line_height_multiplier = 1.0; + } + font->FontMetrics(line_height->ascent, line_height->descent, line_height->leading); + *line_height *= font_size; + + // yet another borked SPStyle member that we're going to have to fix ourselves + for ( ; ; ) { + if (style->line_height.set && !style->line_height.inherit) { + if (style->line_height.normal) + break; + switch (style->line_height.unit) { + case SP_CSS_UNIT_NONE: + *line_height_multiplier = style->line_height.computed * font_size / line_height->total(); + return; + case SP_CSS_UNIT_EX: + *line_height_multiplier = style->line_height.value * 0.5 * font_size / line_height->total(); + // 0.5 is an approximation of the x-height. Fixme. + return; + case SP_CSS_UNIT_EM: + case SP_CSS_UNIT_PERCENT: + *line_height_multiplier = style->line_height.value * font_size / line_height->total(); + return; + default: // absolute values + *line_height_multiplier = style->line_height.computed / line_height->total(); + return; + } + break; + } + if (style->object->parent == NULL) break; + style = style->object->parent->style; + if (style == NULL) break; + } + *line_height_multiplier = LINE_HEIGHT_NORMAL * font_size / line_height->total(); +} + +/** + * Split the paragraph into spans. Also call pango_shape() on them. + * + * Input: para->first_input_index, para->pango_items + * Output: para->spans + * Returns: the index of the beginning of the following paragraph in _flow._input_stream + */ +unsigned Layout::Calculator::_buildSpansForPara(ParagraphInfo *para) const +{ + unsigned pango_item_index = 0; + unsigned char_index_in_para = 0; + unsigned byte_index_in_para = 0; + unsigned input_index; + + TRACE(("build spans\n")); + para->free_sequence(para->unbroken_spans); + + for(input_index = para->first_input_index ; input_index < _flow._input_stream.size() ; input_index++) { + if (_flow._input_stream[input_index]->Type() == CONTROL_CODE) { + Layout::InputStreamControlCode const *control_code = static_cast(_flow._input_stream[input_index]); + if ( control_code->code == SHAPE_BREAK + || control_code->code == PARAGRAPH_BREAK) + break; // stop at the end of the paragraph + else if (control_code->code == ARBITRARY_GAP) { + UnbrokenSpan new_span; + new_span.pango_item_index = -1; + new_span.input_index = input_index; + new_span.line_height.ascent = control_code->ascent; + new_span.line_height.descent = control_code->descent; + new_span.line_height.leading = 0.0; + new_span.text_bytes = 0; + new_span.char_index_in_para = char_index_in_para; + para->unbroken_spans.push_back(new_span); + TRACE(("add gap span %d\n", para->unbroken_spans.size() - 1)); + } + } else if (_flow._input_stream[input_index]->Type() == TEXT_SOURCE && pango_item_index < para->pango_items.size()) { + Layout::InputStreamTextSource const *text_source = static_cast(_flow._input_stream[input_index]); + unsigned char_index_in_source = 0; + + unsigned span_start_byte_in_source = 0; + // we'll need to make several spans from each text source, based on the rules described about the UnbrokenSpan definition + for ( ; ; ) { + /* we need to change spans at every change of PangoItem, source stream change, + or change in one of the attributes altering position/rotation. */ + + unsigned const pango_item_bytes = ( pango_item_index >= para->pango_items.size() + ? 0 + : ( para->pango_items[pango_item_index].item->offset + + para->pango_items[pango_item_index].item->length + - byte_index_in_para ) ); + unsigned const text_source_bytes = ( text_source->text_end.base() + - text_source->text_begin.base() + - span_start_byte_in_source ); + UnbrokenSpan new_span; + new_span.text_bytes = std::min(text_source_bytes, pango_item_bytes); + new_span.input_stream_first_character = Glib::ustring::const_iterator(text_source->text_begin.base() + span_start_byte_in_source); + new_span.char_index_in_para = char_index_in_para + char_index_in_source; + new_span.input_index = input_index; + + // cut at attribute changes as well + new_span.x._set = false; + new_span.y._set = false; + new_span.dx._set = false; + new_span.dy._set = false; + new_span.rotate._set = false; + if (_block_progression == TOP_TO_BOTTOM || _block_progression == BOTTOM_TO_TOP) { + if (text_source->x.size() > char_index_in_source) new_span.x = text_source->x[char_index_in_source]; + if (text_source->y.size() > char_index_in_source) new_span.y = text_source->y[char_index_in_source]; + if (text_source->dx.size() > char_index_in_source) new_span.dx = text_source->dx[char_index_in_source]; + if (text_source->dy.size() > char_index_in_source) new_span.dy = text_source->dy[char_index_in_source]; + } else { + if (text_source->x.size() > char_index_in_source) new_span.y = text_source->x[char_index_in_source]; + if (text_source->y.size() > char_index_in_source) new_span.x = text_source->y[char_index_in_source]; + if (text_source->dx.size() > char_index_in_source) new_span.dy = text_source->dx[char_index_in_source]; + if (text_source->dy.size() > char_index_in_source) new_span.dx = text_source->dy[char_index_in_source]; + } + if (text_source->rotate.size() > char_index_in_source) new_span.rotate = text_source->rotate[char_index_in_source]; + if (input_index == 0 && para->unbroken_spans.empty() && !new_span.y._set && _flow._input_wrap_shapes.empty()) { + // if we don't set an explicit y some of the automatic wrapping code takes over and moves the text vertically + // so that the top of the letters is at zero, not the baseline + new_span.y = 0.0; + } + Glib::ustring::const_iterator iter_text = new_span.input_stream_first_character; + iter_text++; + for (unsigned i = char_index_in_source + 1 ; ; i++, iter_text++) { + if (iter_text >= text_source->text_end) break; + if (iter_text.base() - new_span.input_stream_first_character.base() >= (int)new_span.text_bytes) break; + if ( i >= text_source->x.size() && i >= text_source->y.size() + && i >= text_source->dx.size() && i >= text_source->dy.size() + && i >= text_source->rotate.size()) break; + if ( (text_source->x.size() > i && text_source->x[i]._set) + || (text_source->y.size() > i && text_source->y[i]._set) + || (text_source->dx.size() > i && text_source->dx[i]._set && text_source->dx[i].computed != 0.0) + || (text_source->dy.size() > i && text_source->dy[i]._set && text_source->dy[i].computed != 0.0) + || (text_source->rotate.size() > i && text_source->rotate[i]._set + && (i == 0 || text_source->rotate[i].computed != text_source->rotate[i - 1].computed))) { + new_span.text_bytes = iter_text.base() - new_span.input_stream_first_character.base(); + break; + } + } + + // now we know the length, do some final calculations and add the UnbrokenSpan to the list + new_span.font_size = text_source->styleComputeFontSize(); + if (new_span.text_bytes) { + int const original_bidi_level = para->pango_items[pango_item_index].item->analysis.level; + para->pango_items[pango_item_index].item->analysis.level = 0; + // pango_shape() will reorder glyphs in rtl sections which messes us up because + // the svg spec requires us to draw glyphs in character order + new_span.glyph_string = pango_glyph_string_new(); + /* Some assertions intended to help diagnose bug #1277746. */ + g_assert( 0 < new_span.text_bytes ); + g_assert( span_start_byte_in_source < text_source->text->bytes() ); + g_assert( span_start_byte_in_source + new_span.text_bytes <= text_source->text->bytes() ); + g_assert( memchr(text_source->text->data() + span_start_byte_in_source, '\0', static_cast(new_span.text_bytes)) + == NULL ); + pango_shape(text_source->text->data() + span_start_byte_in_source, + new_span.text_bytes, + ¶->pango_items[pango_item_index].item->analysis, + new_span.glyph_string); + para->pango_items[pango_item_index].item->analysis.level = original_bidi_level; + new_span.pango_item_index = pango_item_index; + _computeFontLineHeight(para->pango_items[pango_item_index].font, new_span.font_size, text_source->style, &new_span.line_height, &new_span.line_height_multiplier); + // TODO: metrics for vertical text + TRACE(("add text span %d \"%s\"\n", para->unbroken_spans.size(), text_source->text->raw().substr(span_start_byte_in_source, new_span.text_bytes).c_str())); + TRACE((" %d glyphs\n", new_span.glyph_string->num_glyphs)); + } else { + // if there's no text we still need to initialise the styles + new_span.pango_item_index = -1; + font_instance *font = text_source->styleGetFontInstance(); + if (font) { + _computeFontLineHeight(font, new_span.font_size, text_source->style, &new_span.line_height, &new_span.line_height_multiplier); + font->Unref(); + } else { + new_span.line_height.setZero(); + new_span.line_height_multiplier = 1.0; + } + TRACE(("add style init span %d\n", para->unbroken_spans.size())); + } + para->unbroken_spans.push_back(new_span); + + // calculations for moving to the next UnbrokenSpan + byte_index_in_para += new_span.text_bytes; + char_index_in_source += g_utf8_strlen(&*new_span.input_stream_first_character.base(), new_span.text_bytes); + + if (new_span.text_bytes >= pango_item_bytes) { // end of pango item + pango_item_index++; + if (pango_item_index == para->pango_items.size()) break; // end of paragraph + } + if (new_span.text_bytes == text_source_bytes) + break; // end of source + // else attribute changed + span_start_byte_in_source += new_span.text_bytes; + } + char_index_in_para += char_index_in_source; + } + } + TRACE(("end build spans\n")); + return input_index; +} + +/** + * Reinitialises the variables required on completion of one shape and + * moving on to the next. Returns false if there are no more shapes to wrap + * in to. + */ +bool Layout::Calculator::_goToNextWrapShape() +{ + delete _scanline_maker; + _scanline_maker = NULL; + _current_shape_index++; + if (_current_shape_index == _flow._input_wrap_shapes.size()) return false; + _scanline_maker = new ShapeScanlineMaker(_flow._input_wrap_shapes[_current_shape_index].shape, _block_progression); + TRACE(("begin wrap shape %d\n", _current_shape_index)); + return true; +} + +/** + * Given \a para filled in and \a start_span_pos set, keeps trying to + * find somewhere it can fit the next line of text. The process of finding + * the text that fits will involve creating one or more entries in + * \a chunk_info describing the bounds of the fitted text and several + * bits of information that will prove useful when we come to output the + * line to #_flow. Returns with \a start_span_pos set to the end of the + * text that was fitted, \a chunk_info completely filled out and + * \a line_height set to the largest line box on the line. The return + * value is false only if we've run out of shapes to wrap inside (and + * hence couldn't create any chunks). + */ +bool Layout::Calculator::_findChunksForLine(ParagraphInfo const ¶, + UnbrokenSpanPosition *start_span_pos, + std::vector *chunk_info, + LineHeight *line_height) +{ + // init the initial line_height + if (start_span_pos->iter_span == para.unbroken_spans.end()) { + if (_flow._spans.empty()) { + // empty first para: create a font for the sole purpose of measuring it + InputStreamTextSource const *text_source = static_cast(_flow._input_stream.front()); + font_instance *font = text_source->styleGetFontInstance(); + if (font) { + double font_size = text_source->styleComputeFontSize(); + double multiplier; + _computeFontLineHeight(font, font_size, text_source->style, line_height, &multiplier); + font->Unref(); + *line_height *= multiplier; + _scanline_maker->setNewYCoordinate(_scanline_maker->yCoordinate() - line_height->ascent); + } + } + // else empty subsequent para: keep the old line height + } else { + if (_flow._input_wrap_shapes.empty()) { + // if we're not wrapping set the line_height big and negative so we can use negative line height + line_height->ascent = -1.0e10; + line_height->descent = -1.0e10; + line_height->leading = -1.0e10; + } + else + line_height->setZero(); + } + + UnbrokenSpanPosition span_pos; + for( ; ; ) { + std::vector scan_runs; + scan_runs = _scanline_maker->makeScanline(*line_height); + while (scan_runs.empty()) { + if (!_goToNextWrapShape()) return false; // no more shapes to wrap in to + scan_runs = _scanline_maker->makeScanline(*line_height); + } + + TRACE(("finding line fit y=%f, %d scan runs\n", scan_runs.front().y, scan_runs.size())); + chunk_info->clear(); + chunk_info->reserve(scan_runs.size()); + if (para.direction == RIGHT_TO_LEFT) std::reverse(scan_runs.begin(), scan_runs.end()); + unsigned scan_run_index; + span_pos = *start_span_pos; + for (scan_run_index = 0 ; scan_run_index < scan_runs.size() ; scan_run_index++) { + if (!_buildChunksInScanRun(para, span_pos, scan_runs[scan_run_index], chunk_info, line_height)) + break; + if (!chunk_info->empty() && !chunk_info->back().broken_spans.empty()) + span_pos = chunk_info->back().broken_spans.back().end; + } + if (scan_run_index == scan_runs.size()) break; // ie when buildChunksInScanRun() succeeded + } + *start_span_pos = span_pos; + return true; +} + +/** + * Given a scan run and a first character, append one or more chunks to + * the \a chunk_info vector that describe all the spans and other detail + * necessary to output the greatest amount of text that will fit on this scan + * line (greedy line breaking algorithm). Each chunk contains one or more + * BrokenSpan structures that link back to UnbrokenSpan structures that link + * to the text itself. Normally there will be either one or zero (if the + * scanrun is too short to fit any text) chunk added to \a chunk_info by + * each call to this method, but we will add more than one if an x or y + * attribute has been set on a tspan. \a line_height must be set on input, + * and if it needs to be made larger and the #_scanline_maker can't do + * an in-situ resize then it will be set to the required value and the + * method will return false. + */ +bool Layout::Calculator::_buildChunksInScanRun(ParagraphInfo const ¶, + UnbrokenSpanPosition const &start_span_pos, + ScanlineMaker::ScanRun const &scan_run, + std::vector *chunk_info, + LineHeight *line_height) const +{ + ChunkInfo new_chunk; + new_chunk.text_width = 0.0; + new_chunk.whitespace_count = 0; + new_chunk.scanrun_width = scan_run.width(); + new_chunk.x = scan_run.x_start; + + // we haven't done anything yet so the last valid break position is the beginning + BrokenSpan last_span_at_break, last_span_at_emergency_break; + last_span_at_break.start = start_span_pos; + last_span_at_break.setZero(); + last_span_at_emergency_break.start = start_span_pos; + last_span_at_emergency_break.setZero(); + + TRACE(("trying chunk from %f to %g\n", scan_run.x_start, scan_run.x_end)); + BrokenSpan new_span; + new_span.end = start_span_pos; + while (new_span.end.iter_span != para.unbroken_spans.end()) { // this loops once for each UnbrokenSpan + + new_span.start = new_span.end; + + // force a chunk change at x or y attribute change + if ((new_span.start.iter_span->x._set || new_span.start.iter_span->y._set) && new_span.start.char_byte == 0) { + + if (new_span.start.iter_span != start_span_pos.iter_span) + chunk_info->push_back(new_chunk); + + new_chunk.x += new_chunk.text_width; + new_chunk.text_width = 0.0; + new_chunk.whitespace_count = 0; + new_chunk.broken_spans.clear(); + if (new_span.start.iter_span->x._set) new_chunk.x = new_span.start.iter_span->x.computed; + // y doesn't need to be done until output time + } + + // see if this span is too tall to fit on the current line + LineHeight total_height = new_span.start.iter_span->line_height; + total_height *= new_span.start.iter_span->line_height_multiplier; + /* floating point 80-bit/64-bit rounding problems require epsilon. See + discussion http://inkscape.gristle.org/2005-03-16.txt around 22:00 */ + if ( total_height.ascent > line_height->ascent + FLT_EPSILON + || total_height.descent > line_height->descent + FLT_EPSILON + || total_height.leading > line_height->leading + FLT_EPSILON) { + line_height->max(total_height); + if (!_scanline_maker->canExtendCurrentScanline(*line_height)) + return false; + } + + bool span_fitted = _measureUnbrokenSpan(para, &new_span, &last_span_at_break, &last_span_at_emergency_break, new_chunk.scanrun_width - new_chunk.text_width); + + new_chunk.text_width += new_span.width; + new_chunk.whitespace_count += new_span.whitespace_count; + new_chunk.broken_spans.push_back(new_span); // if !span_fitted we'll correct ourselves below + + if (!span_fitted) break; + + if (new_span.end.iter_span == para.unbroken_spans.end()) { + last_span_at_break = new_span; + break; + } + } + + TRACE(("chunk complete, used %f width (%d whitespaces, %d brokenspans)\n", new_chunk.text_width, new_chunk.whitespace_count, new_chunk.broken_spans.size())); + chunk_info->push_back(new_chunk); + + if (scan_run.width() >= 4.0 * line_height->total() && last_span_at_break.end == start_span_pos) { + /* **non-SVG spec bit**: See bug #1191102 + If the user types a very long line with no spaces, the way the spec + is written at the moment means that when the length of the text + exceeds the available width of all remaining areas, the text is + completely hidden. This condition alters that behaviour so that if + the length of the line is greater than four times the line-height + and there are no spaces, it'll be emergency-wrapped at the last + character. One could read the SVG Tiny 1.2 draft as permitting this + sort of behaviour, but it's still a bit dodgy. The hard-coding of + 4x is not nice, either. */ + last_span_at_break = last_span_at_emergency_break; + } + + if (!chunk_info->back().broken_spans.empty() && last_span_at_break.end != chunk_info->back().broken_spans.back().end) { + // need to back out spans until we come to the one with the last break in it + while (!chunk_info->empty() && last_span_at_break.start.iter_span != chunk_info->back().broken_spans.back().start.iter_span) { + chunk_info->back().text_width -= chunk_info->back().broken_spans.back().width; + chunk_info->back().whitespace_count -= chunk_info->back().broken_spans.back().whitespace_count; + chunk_info->back().broken_spans.pop_back(); + if (chunk_info->back().broken_spans.empty()) + chunk_info->pop_back(); + } + if (!chunk_info->empty()) { + chunk_info->back().text_width -= chunk_info->back().broken_spans.back().width; + chunk_info->back().whitespace_count -= chunk_info->back().broken_spans.back().whitespace_count; + if (last_span_at_break.start == last_span_at_break.end) { + chunk_info->back().broken_spans.pop_back(); // last break was at an existing boundary + if (chunk_info->back().broken_spans.empty()) + chunk_info->pop_back(); + } else { + chunk_info->back().broken_spans.back() = last_span_at_break; + chunk_info->back().text_width += last_span_at_break.width; + chunk_info->back().whitespace_count += last_span_at_break.whitespace_count; + } + TRACE(("correction: fitted span %d width = %f\n", last_span_at_break.start.iter_span - para.unbroken_spans.begin(), last_span_at_break.width)); + } + } + + if (!chunk_info->empty() && !chunk_info->back().broken_spans.empty() && chunk_info->back().broken_spans.back().ends_with_whitespace) { + // for justification we need to discard space occupied by the single whitespace at the end of the chunk + chunk_info->back().broken_spans.back().ends_with_whitespace = false; + chunk_info->back().broken_spans.back().width -= chunk_info->back().broken_spans.back().each_whitespace_width; + chunk_info->back().broken_spans.back().whitespace_count--; + chunk_info->back().text_width -= chunk_info->back().broken_spans.back().each_whitespace_width; + chunk_info->back().whitespace_count--; + } + + return true; +} + +/** The management function to start the whole thing off. */ +bool Layout::Calculator::calculate() +{ + if (_flow._input_stream.empty()) + return false; + g_assert(_flow._input_stream.front()->Type() == TEXT_SOURCE); + if (_flow._input_stream.front()->Type() != TEXT_SOURCE) + return false; + + TRACE(("begin calculateFlow()\n")); + + _flow._clearOutputObjects(); + + _pango_context = (font_factory::Default())->fontContext; + _font_factory_size_multiplier = (font_factory::Default())->fontSize; + + _block_progression = _flow._blockProgression(); + _y_offset = 0.0; + _createFirstScanlineMaker(); + + ParagraphInfo para; + LineHeight line_height; // needs to be maintained across paragraphs to be able to deal with blank paras (this is wrong) + for(para.first_input_index = 0 ; para.first_input_index < _flow._input_stream.size() ; ) { + // jump to the next wrap shape if this is a SHAPE_BREAK control code + if (_flow._input_stream[para.first_input_index]->Type() == CONTROL_CODE) { + InputStreamControlCode const *control_code = static_cast(_flow._input_stream[para.first_input_index]); + if (control_code->code == SHAPE_BREAK) { + TRACE(("shape break control code\n")); + if (!_goToNextWrapShape()) break; + continue; + } + } + if (_scanline_maker == NULL) + break; // we're trying to flow past the last wrap shape + + _buildPangoItemizationForPara(¶); + unsigned para_end_input_index = _buildSpansForPara(¶); + + if (_flow._input_stream[para.first_input_index]->Type() == TEXT_SOURCE) + para.alignment = static_cast(_flow._input_stream[para.first_input_index])->styleGetAlignment(para.direction, !_flow._input_wrap_shapes.empty()); + else + para.alignment = para.direction == LEFT_TO_RIGHT ? LEFT : RIGHT; + + TRACE(("para prepared, adding as #%d\n", _flow._paragraphs.size())); + Layout::Paragraph new_paragraph; + new_paragraph.base_direction = para.direction; + new_paragraph.alignment = para.alignment; + _flow._paragraphs.push_back(new_paragraph); + + // start scanning lines + UnbrokenSpanPosition span_pos; + span_pos.iter_span = para.unbroken_spans.begin(); + span_pos.char_byte = 0; + span_pos.char_index = 0; + + do { // for each line in the paragraph + TRACE(("begin line\n")); + std::vector line_chunk_info; + if (!_findChunksForLine(para, &span_pos, &line_chunk_info, &line_height)) + break; // out of shapes to wrap in to + + _outputLine(para, line_height, line_chunk_info); + _scanline_maker->completeLine(); + } while (span_pos.iter_span != para.unbroken_spans.end()); + + TRACE(("para %d end\n\n", _flow._paragraphs.size() - 1)); + if (_scanline_maker != NULL) { + bool is_empty_para = _flow._characters.empty() || _flow._characters.back().line(&_flow).in_paragraph != _flow._paragraphs.size() - 1; + if ((is_empty_para && para_end_input_index + 1 >= _flow._input_stream.size()) + || para_end_input_index + 1 < _flow._input_stream.size()) { + // we need a span just for the para if it's either an empty last para or a break in the middle + Layout::Span new_span; + if (_flow._spans.empty()) { + new_span.font = NULL; + new_span.font_size = line_height.ascent + line_height.descent; + new_span.line_height = line_height; + new_span.x_end = 0.0; + } else { + new_span = _flow._spans.back(); + if (_flow._chunks[new_span.in_chunk].in_line != _flow._lines.size() - 1) + new_span.x_end = 0.0; + } + new_span.in_chunk = _flow._chunks.size() - 1; + if (new_span.font) + new_span.font->Ref(); + new_span.x_start = new_span.x_end; + new_span.baseline_shift = 0.0; + new_span.direction = para.direction; + new_span.block_progression = _block_progression; + if (para_end_input_index == _flow._input_stream.size()) + new_span.in_input_stream_item = _flow._input_stream.size() - 1; + else + new_span.in_input_stream_item = para_end_input_index; + _flow._spans.push_back(new_span); + } + if (para_end_input_index + 1 < _flow._input_stream.size()) { + // we've got to add an invisible character between paragraphs so that we can position iterators + // (and hence cursors) both before and after the paragraph break + Layout::Character new_character; + new_character.in_span = _flow._spans.size() - 1; + new_character.char_attributes.is_line_break = 1; + new_character.char_attributes.is_mandatory_break = 1; + new_character.char_attributes.is_char_break = 1; + new_character.char_attributes.is_white = 1; + new_character.char_attributes.is_cursor_position = 1; + new_character.char_attributes.is_word_start = 0; + new_character.char_attributes.is_word_end = 1; + new_character.char_attributes.is_sentence_start = 0; + new_character.char_attributes.is_sentence_end = 1; + new_character.char_attributes.is_sentence_boundary = 1; + new_character.char_attributes.backspace_deletes_character = 1; + new_character.x = _flow._spans.back().x_end - _flow._spans.back().x_start; + new_character.in_glyph = -1; + _flow._characters.push_back(new_character); + } + } + para.free(); + para.first_input_index = para_end_input_index + 1; + } + + para.free(); + if (_scanline_maker) + delete _scanline_maker; + + return true; +} + +void Layout::_calculateCursorShapeForEmpty() +{ + _empty_cursor_shape.position = NR::Point(0, 0); + _empty_cursor_shape.height = 0.0; + _empty_cursor_shape.rotation = 0.0; + if (_input_stream.empty() || _input_stream.front()->Type() != TEXT_SOURCE) + return; + + InputStreamTextSource const *text_source = static_cast(_input_stream.front()); + + font_instance *font = text_source->styleGetFontInstance(); + double font_size = text_source->styleComputeFontSize(); + double caret_slope_run = 0.0, caret_slope_rise = 1.0; + LineHeight line_height; + if (font) { + const_cast(font)->FontSlope(caret_slope_run, caret_slope_rise); + font->FontMetrics(line_height.ascent, line_height.descent, line_height.leading); + line_height *= font_size; + font->Unref(); + } else { + line_height.ascent = font_size * 0.85; // random guesses + line_height.descent = font_size * 0.15; + line_height.leading = 0.0; + } + double caret_slope = atan2(caret_slope_run, caret_slope_rise); + _empty_cursor_shape.height = font_size / cos(caret_slope); + _empty_cursor_shape.rotation = caret_slope; + + if (_input_wrap_shapes.empty()) { + _empty_cursor_shape.position = NR::Point(text_source->x.empty() || !text_source->x.front()._set ? 0.0 : text_source->x.front().computed, + text_source->y.empty() || !text_source->y.front()._set ? 0.0 : text_source->y.front().computed); + } else { + Direction block_progression = text_source->styleGetBlockProgression(); + ShapeScanlineMaker scanline_maker(_input_wrap_shapes.front().shape, block_progression); + std::vector scan_runs = scanline_maker.makeScanline(line_height); + if (!scan_runs.empty()) { + if (block_progression == LEFT_TO_RIGHT || block_progression == RIGHT_TO_LEFT) + _empty_cursor_shape.position = NR::Point(scan_runs.front().y + font_size, scan_runs.front().x_start); + else + _empty_cursor_shape.position = NR::Point(scan_runs.front().x_start, scan_runs.front().y + font_size); + } + } +} + +bool Layout::calculateFlow() +{ + bool result = Calculator(this).calculate(); + if (_characters.empty()) + _calculateCursorShapeForEmpty(); + return result; +} + +}//namespace Text +}//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:textwidth=99 : diff --git a/src/libnrtype/Layout-TNG-Input.cpp b/src/libnrtype/Layout-TNG-Input.cpp new file mode 100755 index 000000000..8b695af04 --- /dev/null +++ b/src/libnrtype/Layout-TNG-Input.cpp @@ -0,0 +1,270 @@ +/* + * Inkscape::Text::Layout - text layout engine input functions + * + * Authors: + * Richard Hughes + * + * Copyright (C) 2005 Richard Hughes + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ +#include "Layout-TNG.h" +#include "style.h" +#include "svg/svg-length.h" +#include "sp-object.h" +#include "FontFactory.h" + +namespace Inkscape { +namespace Text { + +void Layout::_clearInputObjects() +{ + for(std::vector::iterator it = _input_stream.begin() ; it != _input_stream.end() ; it++) + delete *it; + _input_stream.clear(); + _input_wrap_shapes.clear(); +} + +// this function does nothing more than store all its parameters for future reference +void Layout::appendText(Glib::ustring const &text, SPStyle *style, void *source_cookie, OptionalTextTagAttrs const *optional_attributes, unsigned optional_attributes_offset, Glib::ustring::const_iterator text_begin, Glib::ustring::const_iterator text_end) +{ + if (style == NULL) return; + + InputStreamTextSource *new_source = new InputStreamTextSource; + + new_source->source_cookie = source_cookie; + new_source->text = &text; + new_source->text_begin = text_begin; + new_source->text_end = text_end; + new_source->style = style; + sp_style_ref(style); + + new_source->text_length = 0; + for ( ; text_begin != text_end && text_begin != text.end() ; text_begin++) + new_source->text_length++; // save this because calculating the length of a UTF-8 string is expensive + + if (optional_attributes) { + // we need to fill in x and y even if the text is empty so that empty paragraphs can be positioned correctly + _copyInputVector(optional_attributes->x, optional_attributes_offset, &new_source->x, std::max(1, new_source->text_length)); + _copyInputVector(optional_attributes->y, optional_attributes_offset, &new_source->y, std::max(1, new_source->text_length)); + _copyInputVector(optional_attributes->dx, optional_attributes_offset, &new_source->dx, new_source->text_length); + _copyInputVector(optional_attributes->dy, optional_attributes_offset, &new_source->dy, new_source->text_length); + _copyInputVector(optional_attributes->rotate, optional_attributes_offset, &new_source->rotate, new_source->text_length); + } + + _input_stream.push_back(new_source); +} + +void Layout::_copyInputVector(std::vector const &input_vector, unsigned input_offset, std::vector *output_vector, size_t max_length) +{ + output_vector->clear(); + if (input_offset >= input_vector.size()) return; + output_vector->reserve(std::min(max_length, input_vector.size() - input_offset)); + while (input_offset < input_vector.size() && max_length != 0) { + if (!input_vector[input_offset]._set) + break; + output_vector->push_back(input_vector[input_offset]); + input_offset++; + max_length--; + } +} + +// just save what we've been given, really +void Layout::appendControlCode(TextControlCode code, void *source_cookie, double width, double ascent, double descent) +{ + InputStreamControlCode *new_code = new InputStreamControlCode; + + new_code->source_cookie = source_cookie; + new_code->code = code; + new_code->width = width; + new_code->ascent = ascent; + new_code->descent = descent; + + _input_stream.push_back(new_code); +} + +// more saving of the parameters +void Layout::appendWrapShape(Shape const *shape, DisplayAlign display_align) +{ + _input_wrap_shapes.push_back(InputWrapShape()); + _input_wrap_shapes.back().shape = shape; + _input_wrap_shapes.back().display_align = display_align; +} + +int Layout::_enum_converter(int input, EnumConversionItem const *conversion_table, unsigned conversion_table_size) +{ + for (unsigned i = 0 ; i < conversion_table_size ; i++) + if (conversion_table[i].input == input) + return conversion_table[i].output; + return conversion_table[0].output; +} + +// ***** the style format interface +// this doesn't include all accesses to SPStyle, only the ones that are non-trivial + +static const float medium_font_size = 12.0; // more of a default if all else fails than anything else +float Layout::InputStreamTextSource::styleComputeFontSize() const +{ + return style->font_size.computed; + + // in case the computed value's not good enough, here's some manual code held in reserve: + SPStyle const *this_style = style; + float inherit_multiplier = 1.0; + + for ( ; ; ) { + if (this_style->font_size.set && !this_style->font_size.inherit) { + switch (this_style->font_size.type) { + case SP_FONT_SIZE_LITERAL: { + switch(this_style->font_size.value) { // these multipliers are straight out of the CSS spec + case SP_CSS_FONT_SIZE_XX_SMALL: return medium_font_size * inherit_multiplier * (3.0/5.0); + case SP_CSS_FONT_SIZE_X_SMALL: return medium_font_size * inherit_multiplier * (3.0/4.0); + case SP_CSS_FONT_SIZE_SMALL: return medium_font_size * inherit_multiplier * (8.0/9.0); + default: + case SP_CSS_FONT_SIZE_MEDIUM: return medium_font_size * inherit_multiplier; + case SP_CSS_FONT_SIZE_LARGE: return medium_font_size * inherit_multiplier * (6.0/5.0); + case SP_CSS_FONT_SIZE_X_LARGE: return medium_font_size * inherit_multiplier * (3.0/2.0); + case SP_CSS_FONT_SIZE_XX_LARGE: return medium_font_size * inherit_multiplier * 2.0; + case SP_CSS_FONT_SIZE_SMALLER: inherit_multiplier *= 0.84; break; //not exactly according to spec + case SP_CSS_FONT_SIZE_LARGER: inherit_multiplier *= 1.26; break; //not exactly according to spec + } + break; + } + case SP_FONT_SIZE_PERCENTAGE: { // 'em' units should be in here, but aren't. Fix in style.cpp. + inherit_multiplier *= this_style->font_size.value; + break; + } + case SP_FONT_SIZE_LENGTH: { + return this_style->font_size.value * inherit_multiplier; + } + } + } + if (this_style->object->parent == NULL) break; + this_style = this_style->object->parent->style; + if (this_style == NULL) break; + } + return medium_font_size * inherit_multiplier; +} + +static const Layout::EnumConversionItem enum_convert_spstyle_block_progression_to_direction[] = { + {SP_CSS_BLOCK_PROGRESSION_TB, Layout::TOP_TO_BOTTOM}, + {SP_CSS_BLOCK_PROGRESSION_LR, Layout::LEFT_TO_RIGHT}, + {SP_CSS_BLOCK_PROGRESSION_RL, Layout::RIGHT_TO_LEFT}}; + +static const Layout::EnumConversionItem enum_convert_spstyle_writing_mode_to_direction[] = { + {SP_CSS_WRITING_MODE_LR_TB, Layout::TOP_TO_BOTTOM}, + {SP_CSS_WRITING_MODE_RL_TB, Layout::TOP_TO_BOTTOM}, + {SP_CSS_WRITING_MODE_TB_RL, Layout::RIGHT_TO_LEFT}, + {SP_CSS_WRITING_MODE_TB_LR, Layout::LEFT_TO_RIGHT}}; + +Layout::Direction Layout::InputStreamTextSource::styleGetBlockProgression() const +{ + // this function shouldn't be necessary, but since style.cpp doesn't support + // shorthand properties yet, it is. + SPStyle const *this_style = style; + + for ( ; ; ) { + if (this_style->block_progression.set) + return (Layout::Direction)_enum_converter(this_style->block_progression.computed, enum_convert_spstyle_block_progression_to_direction, sizeof(enum_convert_spstyle_block_progression_to_direction)/sizeof(enum_convert_spstyle_block_progression_to_direction[0])); + if (this_style->writing_mode.set) + return (Layout::Direction)_enum_converter(this_style->writing_mode.computed, enum_convert_spstyle_writing_mode_to_direction, sizeof(enum_convert_spstyle_writing_mode_to_direction)/sizeof(enum_convert_spstyle_writing_mode_to_direction[0])); + if (this_style->object->parent == NULL) break; + this_style = this_style->object->parent->style; + if (this_style == NULL) break; + } + return TOP_TO_BOTTOM; + +} + +static Layout::Alignment text_anchor_to_alignment(unsigned anchor, Layout::Direction para_direction) +{ + switch (anchor) { + default: + case SP_CSS_TEXT_ANCHOR_START: return para_direction == Layout::LEFT_TO_RIGHT ? Layout::LEFT : Layout::RIGHT; + case SP_CSS_TEXT_ANCHOR_MIDDLE: return Layout::CENTER; + case SP_CSS_TEXT_ANCHOR_END: return para_direction == Layout::LEFT_TO_RIGHT ? Layout::RIGHT : Layout::LEFT; + } +} + +Layout::Alignment Layout::InputStreamTextSource::styleGetAlignment(Layout::Direction para_direction, bool try_text_align) const +{ + if (!try_text_align) + return text_anchor_to_alignment(style->text_anchor.computed, para_direction); + + // there's no way to tell the difference between text-anchor set higher up the cascade to the default and + // text-anchor never set anywhere in the cascade, so in order to detect which of text-anchor or text-align + // to use we'll have to run up the style tree ourselves. + SPStyle const *this_style = style; + + for ( ; ; ) { + // If both text-align and text-anchor are set at the same level, text-align takes + // precedence because it is the most expressive. + if (this_style->text_align.set) { + switch (style->text_align.computed) { + default: + case SP_CSS_TEXT_ALIGN_START: return para_direction == LEFT_TO_RIGHT ? LEFT : RIGHT; + case SP_CSS_TEXT_ALIGN_END: return para_direction == LEFT_TO_RIGHT ? RIGHT : LEFT; + case SP_CSS_TEXT_ALIGN_LEFT: return LEFT; + case SP_CSS_TEXT_ALIGN_RIGHT: return RIGHT; + case SP_CSS_TEXT_ALIGN_CENTER: return CENTER; + case SP_CSS_TEXT_ALIGN_JUSTIFY: return FULL; + } + } + if (this_style->text_anchor.set) + return text_anchor_to_alignment(this_style->text_anchor.computed, para_direction); + if (this_style->object->parent == NULL) break; + this_style = this_style->object->parent->style; + if (this_style == NULL) break; + } + return para_direction == LEFT_TO_RIGHT ? LEFT : RIGHT; +} + +static const Layout::EnumConversionItem enum_convert_spstyle_style_to_pango_style[] = { + {SP_CSS_FONT_STYLE_NORMAL, PANGO_STYLE_NORMAL}, + {SP_CSS_FONT_STYLE_ITALIC, PANGO_STYLE_ITALIC}, + {SP_CSS_FONT_STYLE_OBLIQUE, PANGO_STYLE_OBLIQUE}}; + +static const Layout::EnumConversionItem enum_convert_spstyle_weight_to_pango_weight[] = { + {SP_CSS_FONT_WEIGHT_NORMAL, PANGO_WEIGHT_NORMAL}, + {SP_CSS_FONT_WEIGHT_100, PANGO_WEIGHT_ULTRALIGHT}, + {SP_CSS_FONT_WEIGHT_200, PANGO_WEIGHT_ULTRALIGHT}, + {SP_CSS_FONT_WEIGHT_300, PANGO_WEIGHT_LIGHT}, + {SP_CSS_FONT_WEIGHT_400, PANGO_WEIGHT_NORMAL}, + {SP_CSS_FONT_WEIGHT_500, PANGO_WEIGHT_SEMIBOLD}, + {SP_CSS_FONT_WEIGHT_600, PANGO_WEIGHT_BOLD}, + {SP_CSS_FONT_WEIGHT_BOLD,PANGO_WEIGHT_BOLD}, + {SP_CSS_FONT_WEIGHT_700, PANGO_WEIGHT_BOLD}, + {SP_CSS_FONT_WEIGHT_800, PANGO_WEIGHT_ULTRABOLD}, + {SP_CSS_FONT_WEIGHT_900, PANGO_WEIGHT_HEAVY}}; + +static const Layout::EnumConversionItem enum_convert_spstyle_stretch_to_pango_stretch[] = { + {SP_CSS_FONT_STRETCH_NORMAL, PANGO_STRETCH_NORMAL}, + {SP_CSS_FONT_STRETCH_ULTRA_CONDENSED, PANGO_STRETCH_ULTRA_CONDENSED}, + {SP_CSS_FONT_STRETCH_EXTRA_CONDENSED, PANGO_STRETCH_EXTRA_CONDENSED}, + {SP_CSS_FONT_STRETCH_CONDENSED, PANGO_STRETCH_CONDENSED}, + {SP_CSS_FONT_STRETCH_SEMI_CONDENSED, PANGO_STRETCH_SEMI_CONDENSED}, + {SP_CSS_FONT_STRETCH_SEMI_EXPANDED, PANGO_STRETCH_SEMI_EXPANDED}, + {SP_CSS_FONT_STRETCH_EXPANDED, PANGO_STRETCH_EXPANDED}, + {SP_CSS_FONT_STRETCH_EXTRA_EXPANDED, PANGO_STRETCH_EXTRA_EXPANDED}, + {SP_CSS_FONT_STRETCH_ULTRA_EXPANDED, PANGO_STRETCH_ULTRA_EXPANDED}}; + +static const Layout::EnumConversionItem enum_convert_spstyle_variant_to_pango_variant[] = { + {SP_CSS_FONT_VARIANT_NORMAL, PANGO_VARIANT_NORMAL}, + {SP_CSS_FONT_VARIANT_SMALL_CAPS, PANGO_VARIANT_SMALL_CAPS}}; + +font_instance *Layout::InputStreamTextSource::styleGetFontInstance() const +{ + if (style->text == NULL) return NULL; + return (font_factory::Default())->Face(style->text->font_family.value, + _enum_converter(style->font_variant.computed, enum_convert_spstyle_variant_to_pango_variant, sizeof(enum_convert_spstyle_variant_to_pango_variant)/sizeof(enum_convert_spstyle_variant_to_pango_variant[0])), + _enum_converter(style->font_style.computed, enum_convert_spstyle_style_to_pango_style, sizeof(enum_convert_spstyle_style_to_pango_style)/sizeof(enum_convert_spstyle_style_to_pango_style[0])), + _enum_converter(style->font_weight.computed, enum_convert_spstyle_weight_to_pango_weight, sizeof(enum_convert_spstyle_weight_to_pango_weight)/sizeof(enum_convert_spstyle_weight_to_pango_weight[0])), + _enum_converter(style->font_stretch.computed, enum_convert_spstyle_stretch_to_pango_stretch, sizeof(enum_convert_spstyle_stretch_to_pango_stretch)/sizeof(enum_convert_spstyle_stretch_to_pango_stretch[0]))); +} + +Layout::InputStreamTextSource::~InputStreamTextSource() +{ + sp_style_unref(style); +} + +}//namespace Text +}//namespace Inkscape diff --git a/src/libnrtype/Layout-TNG-OutIter.cpp b/src/libnrtype/Layout-TNG-OutIter.cpp new file mode 100755 index 000000000..3dd043a68 --- /dev/null +++ b/src/libnrtype/Layout-TNG-OutIter.cpp @@ -0,0 +1,994 @@ +/* + * Inkscape::Text::Layout - text layout engine output functions using iterators + * + * Authors: + * Richard Hughes + * + * Copyright (C) 2005 Richard Hughes + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ +#include "Layout-TNG.h" +#include "livarot/Path.h" +#include "font-instance.h" +#include "svg/svg-length.h" +#include "libnr/nr-matrix-translate-ops.h" +#include "libnr/nr-translate-rotate-ops.h" +#include "style.h" + +namespace Inkscape { +namespace Text { + +Layout::iterator Layout::_cursorXOnLineToIterator(unsigned line_index, double local_x) const +{ + unsigned char_index = _lineToCharacter(line_index); + int best_char_index = -1; + double best_x_difference = DBL_MAX; + + if (char_index == _characters.size()) return end(); + for ( ; char_index < _characters.size() ; char_index++) { + if (_characters[char_index].chunk(this).in_line != line_index) break; + if (_characters[char_index].char_attributes.is_mandatory_break) break; + if (!_characters[char_index].char_attributes.is_cursor_position) continue; + double this_x_difference = fabs(_characters[char_index].x + _characters[char_index].span(this).x_start + _characters[char_index].chunk(this).left_x - local_x); + if (this_x_difference < best_x_difference) { + best_char_index = char_index; + best_x_difference = this_x_difference; + } + } + // also try the very end of a para (not lines though because the space wraps) + if (char_index == _characters.size() || _characters[char_index].char_attributes.is_mandatory_break) { + double this_x_difference; + if (char_index == 0) this_x_difference = fabs(_spans.front().x_end + _chunks.front().left_x - local_x); + else this_x_difference = fabs(_characters[char_index - 1].span(this).x_end + _characters[char_index - 1].chunk(this).left_x - local_x); + if (this_x_difference < best_x_difference) { + best_char_index = char_index; + best_x_difference = this_x_difference; + } + } + if (best_char_index == -1) return iterator(this, char_index); + return iterator(this, best_char_index); +} + +double Layout::_getChunkWidth(unsigned chunk_index) const +{ + double chunk_width = 0.0; + unsigned span_index; + if (chunk_index) { + span_index = _lineToSpan(_chunks[chunk_index].in_line); + for ( ; span_index < _spans.size() && _spans[span_index].in_chunk < chunk_index ; span_index++); + } else + span_index = 0; + for ( ; span_index < _spans.size() && _spans[span_index].in_chunk == chunk_index ; span_index++) + chunk_width = std::max(chunk_width, (double)std::max(_spans[span_index].x_start, _spans[span_index].x_end)); + return chunk_width; +} + +/* getting the cursor position for a mouse click is not as simple as it might +seem. The two major problems are flows set up in multiple columns and large +dy adjustments such that text does not belong to the line it appears to. In +the worst case it's possible to have two characters on top of each other, in +which case the one we pick is arbitrary. + +This is a 3-stage (2 pass) algorithm: +1) search all the spans to see if the point is contained in one, if so take + that. Note that this will collect all clicks from the current UI because + of how the hit detection of nrarena objects works. +2) if that fails, run through all the chunks finding a best guess of the one + the user wanted. This is the one whose y coordinate is nearest, or if + there's a tie, the x. +3) search in that chunk using x-coordinate only to find the position. +*/ +Layout::iterator Layout::getNearestCursorPositionTo(double x, double y) const +{ + if (_lines.empty()) return begin(); + double local_x = x; + double local_y = y; + + if (_path_fitted) { + Path::cut_position position = const_cast(_path_fitted)->PointToCurvilignPosition(NR::Point(x, y)); + local_x = const_cast(_path_fitted)->PositionToLength(position.piece, position.t); + return _cursorXOnLineToIterator(0, local_x + _chunks.front().left_x); + } + + if (_directions_are_orthogonal(_blockProgression(), TOP_TO_BOTTOM)) { + local_x = y; + local_y = x; + } + // stage 1: + for (unsigned span_index = 0 ; span_index < _spans.size() ; span_index++) { + double span_left, span_right; + if (_spans[span_index].x_start < _spans[span_index].x_end) { + span_left = _spans[span_index].x_start; + span_right = _spans[span_index].x_end; + } else { + span_left = _spans[span_index].x_end; + span_right = _spans[span_index].x_start; + } + if ( local_x >= _chunks[_spans[span_index].in_chunk].left_x + span_left + && local_x <= _chunks[_spans[span_index].in_chunk].left_x + span_right + && local_y >= _spans[span_index].line(this).baseline_y + _spans[span_index].baseline_shift - _spans[span_index].line_height.ascent + && local_y <= _spans[span_index].line(this).baseline_y + _spans[span_index].baseline_shift + _spans[span_index].line_height.descent) { + return _cursorXOnLineToIterator(_chunks[_spans[span_index].in_chunk].in_line, local_x); + } + } + + // stage 2: + unsigned span_index = 0; + unsigned chunk_index; + int best_chunk_index = -1; + double best_y_range = DBL_MAX; + double best_x_range = DBL_MAX; + for (chunk_index = 0 ; chunk_index < _chunks.size() ; chunk_index++) { + LineHeight line_height = {0.0, 0.0, 0.0}; + double chunk_width = 0.0; + for ( ; span_index < _spans.size() && _spans[span_index].in_chunk == chunk_index ; span_index++) { + line_height.max(_spans[span_index].line_height); + chunk_width = std::max(chunk_width, (double)std::max(_spans[span_index].x_start, _spans[span_index].x_end)); + } + double this_y_range; + if (local_y < _lines[_chunks[chunk_index].in_line].baseline_y - line_height.ascent) + this_y_range = _lines[_chunks[chunk_index].in_line].baseline_y - line_height.ascent - local_y; + else if (local_y > _lines[_chunks[chunk_index].in_line].baseline_y + line_height.descent) + this_y_range = local_y - (_lines[_chunks[chunk_index].in_line].baseline_y + line_height.descent); + else + this_y_range = 0.0; + if (this_y_range <= best_y_range) { + if (this_y_range < best_y_range) best_x_range = DBL_MAX; + double this_x_range; + if (local_x < _chunks[chunk_index].left_x) + this_x_range = _chunks[chunk_index].left_x - local_y; + else if (local_x > _chunks[chunk_index].left_x + chunk_width) + this_x_range = local_x - (_chunks[chunk_index].left_x + chunk_width); + else + this_x_range = 0.0; + if (this_x_range < best_x_range) { + best_y_range = this_y_range; + best_x_range = this_x_range; + best_chunk_index = chunk_index; + } + } + } + + // stage 3: + if (best_chunk_index == -1) return begin(); // never happens + return _cursorXOnLineToIterator(_chunks[best_chunk_index].in_line, local_x); +} + +Layout::iterator Layout::getLetterAt(double x, double y) const +{ + NR::Point point(x, y); + + double rotation; + for (iterator it = begin() ; it != end() ; it.nextCharacter()) { + NR::Rect box = characterBoundingBox(it, &rotation); + // todo: rotation + if (box.contains(point)) return it; + } + return end(); +} + +Layout::iterator Layout::sourceToIterator(void *source_cookie, Glib::ustring::const_iterator text_iterator) const +{ + unsigned source_index; + if (_characters.empty()) return end(); + for (source_index = 0 ; source_index < _input_stream.size() ; source_index++) + if (_input_stream[source_index]->source_cookie == source_cookie) break; + if (source_index == _input_stream.size()) return end(); + + unsigned char_index = _sourceToCharacter(source_index); + + if (_input_stream[source_index]->Type() != TEXT_SOURCE) + return iterator(this, char_index); + + InputStreamTextSource const *text_source = static_cast(_input_stream[source_index]); + if (text_iterator <= text_source->text_begin) return iterator(this, char_index); + if (text_iterator >= text_source->text_end) { + if (source_index == _input_stream.size() - 1) return end(); + return iterator(this, _sourceToCharacter(source_index + 1)); + } + Glib::ustring::const_iterator iter_text = text_source->text_begin; + for ( ; char_index < _characters.size() ; char_index++) { + if (iter_text == text_iterator) + return iterator(this, char_index); + iter_text++; + } + return end(); // never happens +} + +Layout::iterator Layout::sourceToIterator(void *source_cookie) const +{ + return sourceToIterator(source_cookie, Glib::ustring::const_iterator(std::string::const_iterator(NULL))); +} + +NR::Rect Layout::glyphBoundingBox(iterator const &it, double *rotation) const +{ + if (rotation) *rotation = _glyphs[it._glyph_index].rotation; + return _glyphs[it._glyph_index].span(this).font->BBox(_glyphs[it._glyph_index].glyph); +} + +NR::Point Layout::characterAnchorPoint(iterator const &it) const +{ + if (_characters.empty()) + return _empty_cursor_shape.position; + if (it._char_index == _characters.size()) { + return NR::Point(_chunks.back().left_x + _spans.back().x_end, _lines.back().baseline_y + _spans.back().baseline_shift); + } else { + return NR::Point(_characters[it._char_index].chunk(this).left_x + + _spans[_characters[it._char_index].in_span].x_start + + _characters[it._char_index].x, + _characters[it._char_index].line(this).baseline_y + + _characters[it._char_index].span(this).baseline_shift); + } +} + +NR::Point Layout::chunkAnchorPoint(iterator const &it) const +{ + unsigned chunk_index; + + if (_chunks.empty()) + return NR::Point(0.0, 0.0); + + if (_characters.empty()) + chunk_index = 0; + else if (it._char_index == _characters.size()) + chunk_index = _chunks.size() - 1; + else chunk_index = _characters[it._char_index].span(this).in_chunk; + + Alignment alignment = _paragraphs[_lines[_chunks[chunk_index].in_line].in_paragraph].alignment; + if (alignment == LEFT || alignment == FULL) + return NR::Point(_chunks[chunk_index].left_x, _lines[chunk_index].baseline_y); + + double chunk_width = _getChunkWidth(chunk_index); + if (alignment == RIGHT) + return NR::Point(_chunks[chunk_index].left_x + chunk_width, _lines[chunk_index].baseline_y); + //centre + return NR::Point(_chunks[chunk_index].left_x + chunk_width * 0.5, _lines[chunk_index].baseline_y); +} + +NR::Rect Layout::characterBoundingBox(iterator const &it, double *rotation) const +{ + NR::Point top_left, bottom_right; + unsigned char_index = it._char_index; + + if (_path_fitted) { + double cluster_half_width = 0.0; + for (int glyph_index = _characters[char_index].in_glyph ; _glyphs[glyph_index].in_character == char_index ; glyph_index++) + cluster_half_width += _glyphs[glyph_index].width; + cluster_half_width *= 0.5; + + double midpoint_offset = _characters[char_index].span(this).x_start + _characters[char_index].x + cluster_half_width; + int unused = 0; + Path::cut_position *midpoint_otp = const_cast(_path_fitted)->CurvilignToPosition(1, &midpoint_offset, unused); + if (midpoint_offset >= 0.0 && midpoint_otp != NULL && midpoint_otp[0].piece >= 0) { + NR::Point midpoint; + NR::Point tangent; + Span const &span = _characters[char_index].span(this); + double top = span.baseline_shift - span.line_height.ascent; + double bottom = span.baseline_shift + span.line_height.descent; + + const_cast(_path_fitted)->PointAndTangentAt(midpoint_otp[0].piece, midpoint_otp[0].t, midpoint, tangent); + top_left[NR::X] = midpoint[NR::X] - cluster_half_width; + top_left[NR::Y] = midpoint[NR::Y] + top; + bottom_right[NR::X] = midpoint[NR::X] + cluster_half_width; + bottom_right[NR::Y] = midpoint[NR::Y] + bottom; + if (rotation) + *rotation = atan2(tangent[1], tangent[0]); + } + g_free(midpoint_otp); + } else { + if (it._char_index == _characters.size()) { + top_left[NR::X] = bottom_right[NR::X] = _chunks.back().left_x + _spans.back().x_end; + char_index--; + } else { + double span_x = _spans[_characters[it._char_index].in_span].x_start + _characters[it._char_index].chunk(this).left_x; + top_left[NR::X] = span_x + _characters[it._char_index].x; + if (it._char_index + 1 == _characters.size() || _characters[it._char_index + 1].in_span != _characters[it._char_index].in_span) + bottom_right[NR::X] = _spans[_characters[it._char_index].in_span].x_end + _characters[it._char_index].chunk(this).left_x; + else + bottom_right[NR::X] = span_x + _characters[it._char_index + 1].x; + } + + double baseline_y = _characters[char_index].line(this).baseline_y + _characters[char_index].span(this).baseline_shift; + if (_directions_are_orthogonal(_blockProgression(), TOP_TO_BOTTOM)) { + double span_height = _spans[_characters[char_index].in_span].line_height.ascent + _spans[_characters[char_index].in_span].line_height.descent; + top_left[NR::Y] = top_left[NR::X]; + top_left[NR::X] = baseline_y - span_height * 0.5; + bottom_right[NR::Y] = bottom_right[NR::X]; + bottom_right[NR::X] = baseline_y + span_height * 0.5; + } else { + top_left[NR::Y] = baseline_y - _spans[_characters[char_index].in_span].line_height.ascent; + bottom_right[NR::Y] = baseline_y + _spans[_characters[char_index].in_span].line_height.descent; + } + + if (rotation) { + if (it._glyph_index == -1) + *rotation = 0.0; + else if (it._glyph_index == (int)_glyphs.size()) + *rotation = _glyphs.back().rotation; + else + *rotation = _glyphs[it._glyph_index].rotation; + } + } + + return NR::Rect(top_left, bottom_right); +} + +std::vector Layout::createSelectionShape(iterator const &it_start, iterator const &it_end, NR::Matrix const &transform) const +{ + std::vector quads; + unsigned char_index; + unsigned end_char_index; + + if (it_start._char_index < it_end._char_index) { + char_index = it_start._char_index; + end_char_index = it_end._char_index; + } else { + char_index = it_end._char_index; + end_char_index = it_start._char_index; + } + for ( ; char_index < end_char_index ; ) { + if (_characters[char_index].in_glyph == -1) { + char_index++; + continue; + } + double char_rotation = _glyphs[_characters[char_index].in_glyph].rotation; + unsigned span_index = _characters[char_index].in_span; + + NR::Point top_left, bottom_right; + if (_path_fitted || char_rotation != 0.0) { + NR::Rect box = characterBoundingBox(iterator(this, char_index), &char_rotation); + top_left = box.min(); + bottom_right = box.max(); + char_index++; + } else { // for straight text we can be faster by combining all the character boxes in a span into one box + double span_x = _spans[span_index].x_start + _spans[span_index].chunk(this).left_x; + top_left[NR::X] = span_x + _characters[char_index].x; + while (char_index < end_char_index && _characters[char_index].in_span == span_index) + char_index++; + if (char_index == _characters.size() || _characters[char_index].in_span != span_index) + bottom_right[NR::X] = _spans[span_index].x_end + _spans[span_index].chunk(this).left_x; + else + bottom_right[NR::X] = span_x + _characters[char_index].x; + + double baseline_y = _spans[span_index].line(this).baseline_y + _spans[span_index].baseline_shift; + if (_directions_are_orthogonal(_blockProgression(), TOP_TO_BOTTOM)) { + double span_height = _spans[span_index].line_height.ascent + _spans[span_index].line_height.descent; + top_left[NR::Y] = top_left[NR::X]; + top_left[NR::X] = baseline_y - span_height * 0.5; + bottom_right[NR::Y] = bottom_right[NR::X]; + bottom_right[NR::X] = baseline_y + span_height * 0.5; + } else { + top_left[NR::Y] = baseline_y - _spans[span_index].line_height.ascent; + bottom_right[NR::Y] = baseline_y + _spans[span_index].line_height.descent; + } + } + + NR::Rect char_box(top_left, bottom_right); + if (char_box.extent(NR::X) == 0.0 || char_box.extent(NR::Y) == 0.0) + continue; + NR::Point center_of_rotation((top_left[NR::X] + bottom_right[NR::X]) * 0.5, + top_left[NR::Y] + _spans[span_index].line_height.ascent); + NR::Matrix total_transform = NR::translate(-center_of_rotation) * NR::rotate(char_rotation) * NR::translate(center_of_rotation) * transform; + for(int i = 0; i < 4; i ++) + quads.push_back(char_box.corner(i) * total_transform); + } + return quads; +} + +void Layout::queryCursorShape(iterator const &it, NR::Point *position, double *height, double *rotation) const +{ + if (_characters.empty()) { + *position = _empty_cursor_shape.position; + *height = _empty_cursor_shape.height; + *rotation = _empty_cursor_shape.rotation; + } else { + // we want to cursor to be positioned where the left edge of a character that is about to be typed will be. + // this means x & rotation are the current values but y & height belong to the previous character. + // this isn't quite right because dx attributes will be moved along, but it's good enough + Span const *span; + if (_path_fitted) { + // text on a path + double x; + if (it._char_index >= _characters.size()) { + span = &_spans.back(); + x = span->x_end + _chunks.back().left_x - _chunks[0].left_x; + } else { + span = &_spans[_characters[it._char_index].in_span]; + x = _chunks[span->in_chunk].left_x + span->x_start + _characters[it._char_index].x - _chunks[0].left_x; + if (it._char_index != 0) + span = &_spans[_characters[it._char_index - 1].in_span]; + } + double path_length = const_cast(_path_fitted)->Length(); + double x_on_path = x; + if (x_on_path < 0.0) x_on_path = 0.0; + + int unused = 0; + // as far as I know these functions are const, they're just not marked as such + Path::cut_position *path_parameter_list = const_cast(_path_fitted)->CurvilignToPosition(1, &x_on_path, unused); + Path::cut_position path_parameter; + if (path_parameter_list != NULL && path_parameter_list[0].piece >= 0) + path_parameter = path_parameter_list[0]; + else { + path_parameter.piece = _path_fitted->descr_cmd.size() - 1; + path_parameter.t = 0.9999; // 1.0 will get the wrong tangent + } + g_free(path_parameter_list); + + NR::Point point; + NR::Point tangent; + const_cast(_path_fitted)->PointAndTangentAt(path_parameter.piece, path_parameter.t, point, tangent); + if (x < 0.0) + point += x * tangent; + if (x > path_length ) + point += (x - path_length) * tangent; + *rotation = atan2(tangent); + (*position)[NR::X] = point[NR::X] - tangent[NR::Y] * span->baseline_shift; + (*position)[NR::Y] = point[NR::Y] + tangent[NR::X] * span->baseline_shift; + } else { + // text is not on a path + if (it._char_index >= _characters.size()) { + span = &_spans.back(); + (*position)[NR::X] = _chunks[span->in_chunk].left_x + span->x_end; + *rotation = _glyphs.empty() ? 0.0 : _glyphs.back().rotation; + } else { + span = &_spans[_characters[it._char_index].in_span]; + (*position)[NR::X] = _chunks[span->in_chunk].left_x + span->x_start + _characters[it._char_index].x; + if (it._glyph_index == -1) *rotation = 0.0; + else if(it._glyph_index == 0) *rotation = _glyphs[0].rotation; + else *rotation = _glyphs[it._glyph_index - 1].rotation; + // the first char in a line wants to have the y of the new line, so in that case we don't switch to the previous span + if (it._char_index != 0 && _characters[it._char_index - 1].chunk(this).in_line == _chunks[span->in_chunk].in_line) + span = &_spans[_characters[it._char_index - 1].in_span]; + } + (*position)[NR::Y] = span->line(this).baseline_y + span->baseline_shift; + } + // up to now *position is the baseline point, not the final point which will be the bottom of the descent + if (_directions_are_orthogonal(_blockProgression(), TOP_TO_BOTTOM)) { + *height = span->line_height.ascent + span->line_height.descent; + *rotation += M_PI / 2; + std::swap((*position)[NR::X], (*position)[NR::Y]); + (*position)[NR::X] -= sin(*rotation) * *height * 0.5; + (*position)[NR::Y] += cos(*rotation) * *height * 0.5; + } else { + double caret_slope_run = 0.0, caret_slope_rise = 1.0; + if (span->font) + const_cast(span->font)->FontSlope(caret_slope_run, caret_slope_rise); + double caret_slope = atan2(caret_slope_run, caret_slope_rise); + *height = (span->line_height.ascent + span->line_height.descent) / cos(caret_slope); + *rotation += caret_slope; + (*position)[NR::X] -= sin(*rotation) * span->line_height.descent; + (*position)[NR::Y] += cos(*rotation) * span->line_height.descent; + } + } +} + +void Layout::getSourceOfCharacter(iterator const &it, void **source_cookie, Glib::ustring::iterator *text_iterator) const +{ + if (it._char_index == _characters.size()) { + *source_cookie = NULL; + return; + } + InputStreamItem *stream_item = _input_stream[_spans[_characters[it._char_index].in_span].in_input_stream_item]; + *source_cookie = stream_item->source_cookie; + if (text_iterator && stream_item->Type() == TEXT_SOURCE) { + InputStreamTextSource const *text_source = static_cast(stream_item); + Glib::ustring::const_iterator text_iter_const = text_source->text_begin; + unsigned char_index = it._char_index; + unsigned original_input_source_index = _spans[_characters[char_index].in_span].in_input_stream_item; + // confusing algorithm because the iterator goes forwards while the index goes backwards. + // It's just that it's faster doing it that way + while (char_index && _spans[_characters[char_index - 1].in_span].in_input_stream_item == original_input_source_index) { + ++text_iter_const; + char_index--; + } + text_source->text->begin().base() + (text_iter_const.base() - text_source->text->begin().base()); + *text_iterator = Glib::ustring::iterator(std::string::iterator(const_cast(&*text_source->text->begin().base() + (text_iter_const.base() - text_source->text->begin().base())))); + // the caller owns the string, so they're going to want a non-const iterator + } +} + +void Layout::simulateLayoutUsingKerning(iterator const &from, iterator const &to, OptionalTextTagAttrs *result) const +{ + SVGLength zero_length; + zero_length = 0.0; + + result->x.clear(); + result->y.clear(); + result->dx.clear(); + result->dy.clear(); + result->rotate.clear(); + if (to._char_index <= from._char_index) + return; + result->dx.reserve(to._char_index - from._char_index); + result->dy.reserve(to._char_index - from._char_index); + result->rotate.reserve(to._char_index - from._char_index); + for (unsigned char_index = from._char_index ; char_index < to._char_index ; char_index++) { + if (!_characters[char_index].char_attributes.is_char_break) + continue; + if (char_index == 0) + continue; + if (_characters[char_index].chunk(this).in_line != _characters[char_index - 1].chunk(this).in_line) + continue; + + unsigned prev_cluster_char_index; + for (prev_cluster_char_index = char_index - 1 ; + prev_cluster_char_index != 0 && !_characters[prev_cluster_char_index].char_attributes.is_cursor_position ; + prev_cluster_char_index--); + if (_characters[char_index].span(this).in_chunk == _characters[char_index - 1].span(this).in_chunk) { + // dx is zero for the first char in a chunk + // this algorithm works by comparing the summed widths of the glyphs with the observed + // difference in x coordinates of characters, and subtracting the two to produce the x kerning. + double glyphs_width = 0.0; + if (_characters[prev_cluster_char_index].in_glyph != -1) + for (int glyph_index = _characters[prev_cluster_char_index].in_glyph ; glyph_index < _characters[char_index].in_glyph ; glyph_index++) + glyphs_width += _glyphs[glyph_index].width; + if (_characters[char_index].span(this).direction == RIGHT_TO_LEFT) + glyphs_width = -glyphs_width; + + double dx = (_characters[char_index].x + _characters[char_index].span(this).x_start + - _characters[prev_cluster_char_index].x - _characters[prev_cluster_char_index].span(this).x_start) + - glyphs_width; + + + InputStreamItem *input_item = _input_stream[_characters[char_index].span(this).in_input_stream_item]; + if (input_item->Type() == TEXT_SOURCE) { + SPStyle const *style = static_cast(input_item)->style; + if (_characters[char_index].char_attributes.is_white) + dx -= style->word_spacing.computed; + if (_characters[char_index].char_attributes.is_cursor_position) + dx -= style->letter_spacing.computed; + } + + if (fabs(dx) > 0.0001) { + result->dx.resize(char_index - from._char_index + 1, zero_length); + result->dx.back() = dx; + } + } + double dy = _characters[char_index].span(this).baseline_shift - _characters[prev_cluster_char_index].span(this).baseline_shift; + if (fabs(dy) > 0.0001) { + result->dy.resize(char_index - from._char_index + 1, zero_length); + result->dy.back() = dy; + } + if (_characters[char_index].in_glyph != -1 && _glyphs[_characters[char_index].in_glyph].rotation != 0.0) { + result->rotate.resize(char_index - from._char_index + 1, zero_length); + result->rotate.back() = _glyphs[_characters[char_index].in_glyph].rotation; + } + } +} + +#define PREV_START_OF_ITEM(this_func) \ + { \ + _cursor_moving_vertically = false; \ + if (_char_index == 0) return false; \ + _char_index--; \ + return this_func(); \ + } +// end of macro + +#define THIS_START_OF_ITEM(item_getter) \ + { \ + _cursor_moving_vertically = false; \ + if (_char_index == 0) return false; \ + unsigned original_item; \ + if (_char_index == _parent_layout->_characters.size()) { \ + _char_index--; \ + original_item = item_getter; \ + } else { \ + original_item = item_getter; \ + _char_index--; \ + } \ + while (item_getter == original_item) { \ + if (_char_index == 0) { \ + _glyph_index = _parent_layout->_characters[_char_index].in_glyph; \ + return true; \ + } \ + _char_index--; \ + } \ + _char_index++; \ + _glyph_index = _parent_layout->_characters[_char_index].in_glyph; \ + return true; \ + } +// end of macro + +#define NEXT_START_OF_ITEM(item_getter) \ + { \ + _cursor_moving_vertically = false; \ + if (_char_index == _parent_layout->_characters.size()) return false; \ + unsigned original_item = item_getter; \ + for( ; ; ) { \ + _char_index++; \ + if (_char_index == _parent_layout->_characters.size()) { \ + _glyph_index = _parent_layout->_glyphs.size(); \ + return false; \ + } \ + if (item_getter != original_item) break; \ + } \ + _glyph_index = _parent_layout->_characters[_char_index].in_glyph; \ + return true; \ + } +// end of macro + +bool Layout::iterator::prevStartOfSpan() + PREV_START_OF_ITEM(thisStartOfSpan); + +bool Layout::iterator::thisStartOfSpan() + THIS_START_OF_ITEM(_parent_layout->_characters[_char_index].in_span); + +bool Layout::iterator::nextStartOfSpan() + NEXT_START_OF_ITEM(_parent_layout->_characters[_char_index].in_span); + + +bool Layout::iterator::prevStartOfChunk() + PREV_START_OF_ITEM(thisStartOfChunk); + +bool Layout::iterator::thisStartOfChunk() + THIS_START_OF_ITEM(_parent_layout->_characters[_char_index].span(_parent_layout).in_chunk); + +bool Layout::iterator::nextStartOfChunk() + NEXT_START_OF_ITEM(_parent_layout->_characters[_char_index].span(_parent_layout).in_chunk); + + +bool Layout::iterator::prevStartOfLine() + PREV_START_OF_ITEM(thisStartOfLine); + +bool Layout::iterator::thisStartOfLine() + THIS_START_OF_ITEM(_parent_layout->_characters[_char_index].chunk(_parent_layout).in_line); + +bool Layout::iterator::nextStartOfLine() + NEXT_START_OF_ITEM(_parent_layout->_characters[_char_index].chunk(_parent_layout).in_line); + + +bool Layout::iterator::prevStartOfShape() + PREV_START_OF_ITEM(thisStartOfShape); + +bool Layout::iterator::thisStartOfShape() + THIS_START_OF_ITEM(_parent_layout->_characters[_char_index].line(_parent_layout).in_shape); + +bool Layout::iterator::nextStartOfShape() + NEXT_START_OF_ITEM(_parent_layout->_characters[_char_index].line(_parent_layout).in_shape); + + +bool Layout::iterator::prevStartOfParagraph() + PREV_START_OF_ITEM(thisStartOfParagraph); + +bool Layout::iterator::thisStartOfParagraph() + THIS_START_OF_ITEM(_parent_layout->_characters[_char_index].line(_parent_layout).in_paragraph); + +bool Layout::iterator::nextStartOfParagraph() + NEXT_START_OF_ITEM(_parent_layout->_characters[_char_index].line(_parent_layout).in_paragraph); + + +bool Layout::iterator::prevStartOfSource() + PREV_START_OF_ITEM(thisStartOfSource); + +bool Layout::iterator::thisStartOfSource() + THIS_START_OF_ITEM(_parent_layout->_characters[_char_index].span(_parent_layout).in_input_stream_item); + +bool Layout::iterator::nextStartOfSource() + NEXT_START_OF_ITEM(_parent_layout->_characters[_char_index].span(_parent_layout).in_input_stream_item); + + +bool Layout::iterator::thisEndOfLine() +{ + if (_char_index == _parent_layout->_characters.size()) return false; + if (nextStartOfLine()) + { + if (_char_index && _parent_layout->_characters[_char_index - 1].char_attributes.is_white) + return prevCursorPosition(); + return true; + } + if (_char_index && _parent_layout->_characters[_char_index - 1].chunk(_parent_layout).in_line != _parent_layout->_lines.size() - 1) + return prevCursorPosition(); // for when the last paragraph is empty + return false; +} + +void Layout::iterator::beginCursorUpDown() +{ + if (_char_index == _parent_layout->_characters.size()) + _x_coordinate = _parent_layout->_chunks.back().left_x + _parent_layout->_spans.back().x_end; + else + _x_coordinate = _parent_layout->_characters[_char_index].x + _parent_layout->_characters[_char_index].span(_parent_layout).x_start + _parent_layout->_characters[_char_index].chunk(_parent_layout).left_x; + _cursor_moving_vertically = true; +} + +bool Layout::iterator::nextLineCursor() +{ + if (!_cursor_moving_vertically) + beginCursorUpDown(); + if (_char_index == _parent_layout->_characters.size()) + return false; + unsigned line_index = _parent_layout->_characters[_char_index].chunk(_parent_layout).in_line; + if (line_index == _parent_layout->_lines.size() - 1) return false; + if (_parent_layout->_lines[line_index + 1].in_shape != _parent_layout->_lines[line_index].in_shape) { + // switching between shapes: adjust the stored x to compensate + _x_coordinate += _parent_layout->_chunks[_parent_layout->_spans[_parent_layout->_lineToSpan(line_index + 1)].in_chunk].left_x + - _parent_layout->_chunks[_parent_layout->_spans[_parent_layout->_lineToSpan(line_index)].in_chunk].left_x; + } + _char_index = _parent_layout->_cursorXOnLineToIterator(line_index + 1, _x_coordinate)._char_index; + _glyph_index = _parent_layout->_characters[_char_index].in_glyph; + return true; +} + +bool Layout::iterator::prevLineCursor() +{ + if (!_cursor_moving_vertically) + beginCursorUpDown(); + unsigned line_index; + if (_char_index == _parent_layout->_characters.size()) + line_index = _parent_layout->_lines.size() - 1; + else + line_index = _parent_layout->_characters[_char_index].chunk(_parent_layout).in_line; + if (line_index == 0) return false; + if (_parent_layout->_lines[line_index - 1].in_shape != _parent_layout->_lines[line_index].in_shape) { + // switching between shapes: adjust the stored x to compensate + _x_coordinate += _parent_layout->_chunks[_parent_layout->_spans[_parent_layout->_lineToSpan(line_index - 1)].in_chunk].left_x + - _parent_layout->_chunks[_parent_layout->_spans[_parent_layout->_lineToSpan(line_index)].in_chunk].left_x; + } + _char_index = _parent_layout->_cursorXOnLineToIterator(line_index - 1, _x_coordinate)._char_index; + _glyph_index = _parent_layout->_characters[_char_index].in_glyph; + return true; +} + +#define NEXT_WITH_ATTRIBUTE_SET(attr) \ + { \ + _cursor_moving_vertically = false; \ + for ( ; ; ) { \ + if (_char_index + 1 >= _parent_layout->_characters.size()) { \ + _char_index = _parent_layout->_characters.size(); \ + _glyph_index = _parent_layout->_glyphs.size(); \ + return false; \ + } \ + _char_index++; \ + if (_parent_layout->_characters[_char_index].char_attributes.attr) break; \ + } \ + _glyph_index = _parent_layout->_characters[_char_index].in_glyph; \ + return true; \ + } +// end of macro + +#define PREV_WITH_ATTRIBUTE_SET(attr) \ + { \ + _cursor_moving_vertically = false; \ + for ( ; ; ) { \ + if (_char_index == 0) { \ + _glyph_index = 0; \ + return true; \ + } \ + _char_index--; \ + if (_parent_layout->_characters[_char_index].char_attributes.attr) break; \ + } \ + _glyph_index = _parent_layout->_characters[_char_index].in_glyph; \ + return true; \ + } +// end of macro + +bool Layout::iterator::nextCursorPosition() + NEXT_WITH_ATTRIBUTE_SET(is_cursor_position); + +bool Layout::iterator::prevCursorPosition() + PREV_WITH_ATTRIBUTE_SET(is_cursor_position); + +bool Layout::iterator::nextStartOfWord() + NEXT_WITH_ATTRIBUTE_SET(is_word_start); + +bool Layout::iterator::prevStartOfWord() + PREV_WITH_ATTRIBUTE_SET(is_word_start); + +bool Layout::iterator::nextEndOfWord() + NEXT_WITH_ATTRIBUTE_SET(is_word_end); + +bool Layout::iterator::prevEndOfWord() + PREV_WITH_ATTRIBUTE_SET(is_word_end); + +bool Layout::iterator::nextStartOfSentence() + NEXT_WITH_ATTRIBUTE_SET(is_sentence_start); + +bool Layout::iterator::prevStartOfSentence() + PREV_WITH_ATTRIBUTE_SET(is_sentence_start); + +bool Layout::iterator::nextEndOfSentence() + NEXT_WITH_ATTRIBUTE_SET(is_sentence_end); + +bool Layout::iterator::prevEndOfSentence() + PREV_WITH_ATTRIBUTE_SET(is_sentence_end); + +bool Layout::iterator::_cursorLeftOrRightLocalX(Direction direction) +{ + // the only reason this function is so complicated is to enable visual cursor + // movement moving in to or out of counterdirectional runs + if (_parent_layout->_characters.empty()) return false; + unsigned old_span_index; + Direction old_span_direction; + if (_char_index == _parent_layout->_characters.size()) + old_span_index = _parent_layout->_spans.size() - 1; + else + old_span_index = _parent_layout->_characters[_char_index].in_span; + old_span_direction = _parent_layout->_spans[old_span_index].direction; + Direction para_direction = _parent_layout->_spans[old_span_index].paragraph(_parent_layout).base_direction; + + int scan_direction; + unsigned old_char_index = _char_index; + if (old_span_direction != para_direction + && ((_char_index == 0 && direction == para_direction) + || (_char_index == _parent_layout->_characters.size() && direction != para_direction))) { + // the end of the text is actually in the middle because of reordering. Do cleverness + scan_direction = direction == para_direction ? +1 : -1; + } else { + if (direction == old_span_direction) { + if (!nextCursorPosition()) return false; + } else { + if (!prevCursorPosition()) return false; + } + + unsigned new_span_index = _parent_layout->_characters[_char_index].in_span; + if (new_span_index == old_span_index) return true; + if (old_span_direction != _parent_layout->_spans[new_span_index].direction) { + // we must jump to the other end of a counterdirectional run + scan_direction = direction == para_direction ? +1 : -1; + } else if (_parent_layout->_spans[old_span_index].in_chunk != _parent_layout->_spans[new_span_index].in_chunk) { + // we might have to do a weird jump when we would have crossed a chunk/line break + if (_parent_layout->_spans[old_span_index].line(_parent_layout).in_paragraph != _parent_layout->_spans[new_span_index].line(_parent_layout).in_paragraph) + return true; + if (old_span_direction == para_direction) + return true; + scan_direction = direction == para_direction ? +1 : -1; + } else + return true; // same direction, same chunk: no cleverness required + } + + unsigned new_span_index = old_span_index; + for ( ; ; ) { + if (scan_direction > 0) { + if (new_span_index == _parent_layout->_spans.size() - 1) { + if (_parent_layout->_spans[new_span_index].direction == old_span_direction) { + _char_index = old_char_index; + return false; // the visual end is in the logical middle + } + break; + } + new_span_index++; + } else { + if (new_span_index == 0) { + if (_parent_layout->_spans[new_span_index].direction == old_span_direction) { + _char_index = old_char_index; + return false; // the visual end is in the logical middle + } + break; + } + new_span_index--; + } + if (_parent_layout->_spans[new_span_index].direction == para_direction) { + if (para_direction == old_span_direction) + new_span_index -= scan_direction; + break; + } + if (_parent_layout->_spans[new_span_index].in_chunk != _parent_layout->_spans[old_span_index].in_chunk) { + if (_parent_layout->_spans[old_span_index].line(_parent_layout).in_paragraph == _parent_layout->_spans[new_span_index].line(_parent_layout).in_paragraph + && para_direction == old_span_direction) + new_span_index -= scan_direction; + break; + } + } + + // found the correct span, now find the correct character + if (_parent_layout->_spans[old_span_index].line(_parent_layout).in_paragraph != _parent_layout->_spans[new_span_index].line(_parent_layout).in_paragraph) { + if (new_span_index > old_span_index) + _char_index = _parent_layout->_spanToCharacter(new_span_index); + else + _char_index = _parent_layout->_spanToCharacter(new_span_index + 1) - 1; + } else { + if (_parent_layout->_spans[new_span_index].direction != direction) { + if (new_span_index >= _parent_layout->_spans.size() - 1) + _char_index = _parent_layout->_characters.size(); + else + _char_index = _parent_layout->_spanToCharacter(new_span_index + 1) - 1; + } else + _char_index = _parent_layout->_spanToCharacter(new_span_index); + } + if (_char_index == _parent_layout->_characters.size()) { + _glyph_index = _parent_layout->_glyphs.size(); + return false; + } + _glyph_index = _parent_layout->_characters[_char_index].in_glyph; + return _char_index != 0; +} + +bool Layout::iterator::_cursorLeftOrRightLocalXByWord(Direction direction) +{ + bool r; + while ((r = _cursorLeftOrRightLocalX(direction)) + && !_parent_layout->_characters[_char_index].char_attributes.is_word_start); + return r; +} + +bool Layout::iterator::cursorUp() +{ + Direction block_progression = _parent_layout->_blockProgression(); + if(block_progression == TOP_TO_BOTTOM) + return prevLineCursor(); + else if(block_progression == BOTTOM_TO_TOP) + return nextLineCursor(); + else + return _cursorLeftOrRightLocalX(RIGHT_TO_LEFT); +} + +bool Layout::iterator::cursorDown() +{ + Direction block_progression = _parent_layout->_blockProgression(); + if(block_progression == TOP_TO_BOTTOM) + return nextLineCursor(); + else if(block_progression == BOTTOM_TO_TOP) + return prevLineCursor(); + else + return _cursorLeftOrRightLocalX(LEFT_TO_RIGHT); +} + +bool Layout::iterator::cursorLeft() +{ + Direction block_progression = _parent_layout->_blockProgression(); + if(block_progression == LEFT_TO_RIGHT) + return prevLineCursor(); + else if(block_progression == RIGHT_TO_LEFT) + return nextLineCursor(); + else + return _cursorLeftOrRightLocalX(RIGHT_TO_LEFT); +} + +bool Layout::iterator::cursorRight() +{ + Direction block_progression = _parent_layout->_blockProgression(); + if(block_progression == LEFT_TO_RIGHT) + return nextLineCursor(); + else if(block_progression == RIGHT_TO_LEFT) + return prevLineCursor(); + else + return _cursorLeftOrRightLocalX(LEFT_TO_RIGHT); +} + +bool Layout::iterator::cursorUpWithControl() +{ + Direction block_progression = _parent_layout->_blockProgression(); + if(block_progression == TOP_TO_BOTTOM) + return prevStartOfParagraph(); + else if(block_progression == BOTTOM_TO_TOP) + return nextStartOfParagraph(); + else + return _cursorLeftOrRightLocalXByWord(RIGHT_TO_LEFT); +} + +bool Layout::iterator::cursorDownWithControl() +{ + Direction block_progression = _parent_layout->_blockProgression(); + if(block_progression == TOP_TO_BOTTOM) + return nextStartOfParagraph(); + else if(block_progression == BOTTOM_TO_TOP) + return prevStartOfParagraph(); + else + return _cursorLeftOrRightLocalXByWord(LEFT_TO_RIGHT); +} + +bool Layout::iterator::cursorLeftWithControl() +{ + Direction block_progression = _parent_layout->_blockProgression(); + if(block_progression == LEFT_TO_RIGHT) + return prevStartOfParagraph(); + else if(block_progression == RIGHT_TO_LEFT) + return nextStartOfParagraph(); + else + return _cursorLeftOrRightLocalXByWord(RIGHT_TO_LEFT); +} + +bool Layout::iterator::cursorRightWithControl() +{ + Direction block_progression = _parent_layout->_blockProgression(); + if(block_progression == LEFT_TO_RIGHT) + return nextStartOfParagraph(); + else if(block_progression == RIGHT_TO_LEFT) + return prevStartOfParagraph(); + else + return _cursorLeftOrRightLocalXByWord(LEFT_TO_RIGHT); +} + +}//namespace Text +}//namespace Inkscape diff --git a/src/libnrtype/Layout-TNG-Output.cpp b/src/libnrtype/Layout-TNG-Output.cpp new file mode 100755 index 000000000..08eb403db --- /dev/null +++ b/src/libnrtype/Layout-TNG-Output.cpp @@ -0,0 +1,469 @@ +/* + * Inkscape::Text::Layout - text layout engine output functions + * + * Authors: + * Richard Hughes + * + * Copyright (C) 2005 Richard Hughes + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ +#include "Layout-TNG.h" +#include "display/nr-arena-glyphs.h" +#include "style.h" +#include "print.h" +#include "extension/print.h" +#include "livarot/Path.h" +#include "libnr/nr-scale-matrix-ops.h" +#include "font-instance.h" +#include "svg/svg-length.h" + +namespace Inkscape { +namespace Text { + +void Layout::_clearOutputObjects() +{ + _paragraphs.clear(); + _lines.clear(); + _chunks.clear(); + for (std::vector::iterator it_span = _spans.begin() ; it_span != _spans.end() ; it_span++) + if (it_span->font) it_span->font->Unref(); + _spans.clear(); + _characters.clear(); + _glyphs.clear(); + _path_fitted = NULL; +} + +void Layout::LineHeight::max(LineHeight const &other) +{ + if (other.ascent > ascent) ascent = other.ascent; + if (other.descent > descent) descent = other.descent; + if (other.leading > leading) leading = other.leading; +} + +void Layout::_getGlyphTransformMatrix(int glyph_index, NRMatrix *matrix) const +{ + Span const &span = _glyphs[glyph_index].span(this); + double sin_rotation = sin(_glyphs[glyph_index].rotation); + double cos_rotation = cos(_glyphs[glyph_index].rotation); + (*matrix)[0] = span.font_size * cos_rotation; + (*matrix)[1] = span.font_size * sin_rotation; + (*matrix)[2] = span.font_size * sin_rotation; + (*matrix)[3] = -span.font_size * cos_rotation; + if (span.block_progression == LEFT_TO_RIGHT || span.block_progression == RIGHT_TO_LEFT) { + (*matrix)[4] = _lines[_chunks[span.in_chunk].in_line].baseline_y + _glyphs[glyph_index].y; + (*matrix)[5] = _chunks[span.in_chunk].left_x + _glyphs[glyph_index].x; + } else { + (*matrix)[4] = _chunks[span.in_chunk].left_x + _glyphs[glyph_index].x; + (*matrix)[5] = _lines[_chunks[span.in_chunk].in_line].baseline_y + _glyphs[glyph_index].y; + } +} + +void Layout::show(NRArenaGroup *in_arena, NRRect const *paintbox) const +{ + int glyph_index = 0; + for (unsigned span_index = 0 ; span_index < _spans.size() ; span_index++) { + if (_input_stream[_spans[span_index].in_input_stream_item]->Type() != TEXT_SOURCE) continue; + InputStreamTextSource const *text_source = static_cast(_input_stream[_spans[span_index].in_input_stream_item]); + NRArenaGlyphsGroup *nr_group = NRArenaGlyphsGroup::create(in_arena->arena); + nr_arena_item_add_child(in_arena, nr_group, NULL); + nr_arena_item_unref(nr_group); + + nr_arena_glyphs_group_set_style(nr_group, text_source->style); + while (glyph_index < (int)_glyphs.size() && _characters[_glyphs[glyph_index].in_character].in_span == span_index) { + if (_characters[_glyphs[glyph_index].in_character].in_glyph != -1) { + NRMatrix glyph_matrix; + _getGlyphTransformMatrix(glyph_index, &glyph_matrix); + nr_arena_glyphs_group_add_component(nr_group, _spans[span_index].font, _glyphs[glyph_index].glyph, &glyph_matrix); + } + glyph_index++; + } + nr_arena_glyphs_group_set_paintbox(NR_ARENA_GLYPHS_GROUP(nr_group), paintbox); + } + nr_arena_item_request_update(NR_ARENA_ITEM(in_arena), NR_ARENA_ITEM_STATE_ALL, FALSE); +} + +void Layout::getBoundingBox(NRRect *bounding_box, NR::Matrix const &transform) const +{ + for (unsigned glyph_index = 0 ; glyph_index < _glyphs.size() ; glyph_index++) { + if (_characters[_glyphs[glyph_index].in_character].in_glyph == -1) continue; + // this could be faster + NRMatrix glyph_matrix; + _getGlyphTransformMatrix(glyph_index, &glyph_matrix); + NR::Matrix total_transform = glyph_matrix; + total_transform *= transform; + NR::Rect glyph_rect = _glyphs[glyph_index].span(this).font->BBox(_glyphs[glyph_index].glyph); + NR::Point bmi = glyph_rect.min(), bma = glyph_rect.max(); + NR::Point tlp(bmi[0],bmi[1]), trp(bma[0],bmi[1]), blp(bmi[0],bma[1]), brp(bma[0],bma[1]); + tlp *= total_transform; + trp *= total_transform; + blp *= total_transform; + brp *= total_transform; + glyph_rect = NR::Rect(tlp,trp); + glyph_rect.expandTo(blp); + glyph_rect.expandTo(brp); + if ( (glyph_rect.min())[0] < bounding_box->x0 ) bounding_box->x0=(glyph_rect.min())[0]; + if ( (glyph_rect.max())[0] > bounding_box->x1 ) bounding_box->x1=(glyph_rect.max())[0]; + if ( (glyph_rect.min())[1] < bounding_box->y0 ) bounding_box->y0=(glyph_rect.min())[1]; + if ( (glyph_rect.max())[1] > bounding_box->y1 ) bounding_box->y1=(glyph_rect.max())[1]; + } +} + +void Layout::print(SPPrintContext *ctx, + NRRect const *pbox, NRRect const *dbox, NRRect const *bbox, + NRMatrix const &ctm) const +{ + if (_input_stream.empty()) return; + + Direction block_progression = _blockProgression(); + bool text_to_path = ctx->module->textToPath(); + for (unsigned glyph_index = 0 ; glyph_index < _glyphs.size() ; ) { + if (_characters[_glyphs[glyph_index].in_character].in_glyph == -1) { + // invisible glyphs + unsigned same_character = _glyphs[glyph_index].in_character; + while (_glyphs[glyph_index].in_character == same_character) + glyph_index++; + continue; + } + NRMatrix glyph_matrix; + Span const &span = _spans[_characters[_glyphs[glyph_index].in_character].in_span]; + InputStreamTextSource const *text_source = static_cast(_input_stream[span.in_input_stream_item]); + if (text_to_path || _path_fitted) { + NRBPath bpath; + bpath.path = (NArtBpath*)span.font->ArtBPath(_glyphs[glyph_index].glyph); + if (bpath.path) { + NRBPath abp; + _getGlyphTransformMatrix(glyph_index, &glyph_matrix); + abp.path = nr_artpath_affine(bpath.path, glyph_matrix); + if (text_source->style->fill.type != SP_PAINT_TYPE_NONE) + sp_print_fill(ctx, &abp, &ctm, text_source->style, pbox, dbox, bbox); + if (text_source->style->stroke.type != SP_PAINT_TYPE_NONE) + sp_print_stroke(ctx, &abp, &ctm, text_source->style, pbox, dbox, bbox); + nr_free(abp.path); + } + glyph_index++; + } else { + NR::Point g_pos(0,0); // all strings are output at (0,0) because we do the translation using the matrix + glyph_matrix = NR::Matrix(NR::scale(1.0, -1.0) * NR::Matrix(NR::rotate(_glyphs[glyph_index].rotation))); + if (block_progression == LEFT_TO_RIGHT || block_progression == RIGHT_TO_LEFT) { + glyph_matrix.c[4] = span.line(this).baseline_y + span.baseline_shift; + // since we're outputting character codes, not glyphs, we want the character x + glyph_matrix.c[5] = span.chunk(this).left_x + span.x_start + _characters[_glyphs[glyph_index].in_character].x; + } else { + glyph_matrix.c[4] = span.chunk(this).left_x + span.x_start + _characters[_glyphs[glyph_index].in_character].x; + glyph_matrix.c[5] = span.line(this).baseline_y + span.baseline_shift; + } + Glib::ustring::const_iterator span_iter = span.input_stream_first_character; + unsigned char_index = _glyphs[glyph_index].in_character; + unsigned original_span = _characters[char_index].in_span; + while (char_index && _characters[char_index - 1].in_span == original_span) { + char_index--; + span_iter++; + } + + // try to output as many characters as possible in one go by detecting kerning and stopping when we encounter it + Glib::ustring span_string; + double char_x = _characters[_glyphs[glyph_index].in_character].x; + unsigned this_span_index = _characters[_glyphs[glyph_index].in_character].in_span; + do { + span_string += *span_iter; + span_iter++; + + unsigned same_character = _glyphs[glyph_index].in_character; + while (glyph_index < _glyphs.size() && _glyphs[glyph_index].in_character == same_character) { + char_x += _glyphs[glyph_index].width; + glyph_index++; + } + } while (glyph_index < _glyphs.size() + && _path_fitted == NULL + && _characters[_glyphs[glyph_index].in_character].in_span == this_span_index + && fabs(char_x - _characters[_glyphs[glyph_index].in_character].x) < 1e-5); + sp_print_bind(ctx, glyph_matrix, 1.0); + sp_print_text(ctx, span_string.c_str(), g_pos, text_source->style); + sp_print_release(ctx); + } + } +} + +// these functions are for dumpAsText() only. No need to translate +static char const *direction_to_text(Layout::Direction d) +{ + switch (d) { + case Layout::LEFT_TO_RIGHT: return "ltr"; + case Layout::RIGHT_TO_LEFT: return "rtl"; + case Layout::TOP_TO_BOTTOM: return "ttb"; + case Layout::BOTTOM_TO_TOP: return "btt"; + } + return "???"; +} + +static char const *style_to_text(PangoStyle s) +{ + switch (s) { + case PANGO_STYLE_NORMAL: return "upright"; + case PANGO_STYLE_ITALIC: return "italic"; + case PANGO_STYLE_OBLIQUE: return "oblique"; + } + return "???"; +} + +static char const *weight_to_text(PangoWeight w) +{ + switch (w) { + case PANGO_WEIGHT_ULTRALIGHT: return "ultralight"; + case PANGO_WEIGHT_LIGHT : return "light"; + case PANGO_WEIGHT_SEMIBOLD : return "semibold"; + case PANGO_WEIGHT_NORMAL : return "normalweight"; + case PANGO_WEIGHT_BOLD : return "bold"; + case PANGO_WEIGHT_ULTRABOLD : return "ultrabold"; + case PANGO_WEIGHT_HEAVY : return "heavy"; + } + return "???"; +} + +Glib::ustring Layout::dumpAsText() const +{ + Glib::ustring result; + + for (unsigned span_index = 0 ; span_index < _spans.size() ; span_index++) { + char line[256]; + snprintf(line, sizeof(line), "==== span %d\n", span_index); + result += line; + snprintf(line, sizeof(line), " in para %d (direction=%s)\n", _lines[_chunks[_spans[span_index].in_chunk].in_line].in_paragraph, + direction_to_text(_paragraphs[_lines[_chunks[_spans[span_index].in_chunk].in_line].in_paragraph].base_direction)); + result += line; + snprintf(line, sizeof(line), " in source %d (type=%d, cookie=%p)\n", _spans[span_index].in_input_stream_item, + _input_stream[_spans[span_index].in_input_stream_item]->Type(), + _input_stream[_spans[span_index].in_input_stream_item]->source_cookie); + result += line; + snprintf(line, sizeof(line), " in line %d (baseline=%f, shape=%d)\n", _chunks[_spans[span_index].in_chunk].in_line, + _lines[_chunks[_spans[span_index].in_chunk].in_line].baseline_y, + _lines[_chunks[_spans[span_index].in_chunk].in_line].in_shape); + result += line; + snprintf(line, sizeof(line), " in chunk %d (x=%f, baselineshift=%f)\n", _spans[span_index].in_chunk, _chunks[_spans[span_index].in_chunk].left_x, _spans[span_index].baseline_shift); + result += line; + if (_spans[span_index].font) { + snprintf(line, sizeof(line), " font '%s' %f %s %s\n", pango_font_description_get_family(_spans[span_index].font->descr), _spans[span_index].font_size, style_to_text(pango_font_description_get_style(_spans[span_index].font->descr)), weight_to_text(pango_font_description_get_weight(_spans[span_index].font->descr))); + result += line; + } + snprintf(line, sizeof(line), " x_start = %f, x_end = %f\n", _spans[span_index].x_start, _spans[span_index].x_end); + result += line; + snprintf(line, sizeof(line), " line height: ascent %f, descent %f leading %f\n", _spans[span_index].line_height.ascent, _spans[span_index].line_height.descent, _spans[span_index].line_height.leading); + result += line; + snprintf(line, sizeof(line), " direction %s, block-progression %s\n", direction_to_text(_spans[span_index].direction), direction_to_text(_spans[span_index].block_progression)); + result += line; + result += " ** characters:\n"; + Glib::ustring::const_iterator iter_char = _spans[span_index].input_stream_first_character; + // very inefficent code. what the hell, it's only debug stuff. + for (unsigned char_index = 0 ; char_index < _characters.size() ; char_index++) { + if (_characters[char_index].in_span != span_index) continue; + if (_input_stream[_spans[span_index].in_input_stream_item]->Type() != TEXT_SOURCE) { + snprintf(line, sizeof(line), " %d: control x=%f flags=%03x glyph=%d\n", char_index, _characters[char_index].x, *(unsigned*)&_characters[char_index].char_attributes, _characters[char_index].in_glyph); + } else { + snprintf(line, sizeof(line), " %d: '%c' x=%f flags=%03x glyph=%d\n", char_index, *iter_char, _characters[char_index].x, *(unsigned*)&_characters[char_index].char_attributes, _characters[char_index].in_glyph); + iter_char++; + } + result += line; + } + result += " ** glyphs:\n"; + for (unsigned glyph_index = 0 ; glyph_index < _glyphs.size() ; glyph_index++) { + if (_characters[_glyphs[glyph_index].in_character].in_span != span_index) continue; + snprintf(line, sizeof(line), " %d: %d (%f,%f) rot=%f cx=%f char=%d\n", glyph_index, _glyphs[glyph_index].glyph, _glyphs[glyph_index].x, _glyphs[glyph_index].y, _glyphs[glyph_index].rotation, _glyphs[glyph_index].width, _glyphs[glyph_index].in_character); + result += line; + } + result += "\n"; + } + result += "EOT\n"; + return result; +} + +void Layout::fitToPathAlign(SVGLength const &startOffset, Path const &path) +{ + double offset = 0.0; + + if (startOffset._set) { + if (startOffset.unit == SVGLength::PERCENT) + offset = startOffset.computed * const_cast(path).Length(); + else + offset = startOffset.computed; + } + + switch (_paragraphs.front().alignment) { + case CENTER: + offset -= _getChunkWidth(0) * 0.5; + break; + case RIGHT: + offset -= _getChunkWidth(0); + break; + default: + break; + } + + if (_characters.empty()) { + int unused = 0; + Path::cut_position *point_otp = const_cast(path).CurvilignToPosition(1, &offset, unused); + if (offset >= 0.0 && point_otp != NULL && point_otp[0].piece >= 0) { + NR::Point point; + NR::Point tangent; + const_cast(path).PointAndTangentAt(point_otp[0].piece, point_otp[0].t, point, tangent); + _empty_cursor_shape.position = point; + _empty_cursor_shape.rotation = atan2(tangent[NR::Y], tangent[NR::X]); + } + } + + for (unsigned char_index = 0 ; char_index < _characters.size() ; ) { + int next_cluster_glyph_index; + unsigned next_cluster_char_index; + double character_advance; + Span const &span = _characters[char_index].span(this); + + for (next_cluster_char_index = char_index + 1 ; + next_cluster_char_index < _characters.size() && !_characters[next_cluster_char_index].char_attributes.is_cursor_position; + next_cluster_char_index++); + + if (next_cluster_char_index == _characters.size()) { + next_cluster_glyph_index = _glyphs.size(); + character_advance = 0.0; // arbitrary because we're not going to advance + } else { + next_cluster_glyph_index = _characters[next_cluster_char_index].in_glyph; + character_advance = (_glyphs[next_cluster_glyph_index].x + _glyphs[next_cluster_glyph_index].chunk(this).left_x) + - (_glyphs[_characters[char_index].in_glyph].x + span.chunk(this).left_x); + } + + double start_offset = offset + span.x_start + _characters[char_index].x; + double cluster_width = 0.0; + for (int glyph_index = _characters[char_index].in_glyph ; glyph_index < next_cluster_glyph_index ; glyph_index++) + cluster_width += _glyphs[glyph_index].width; + if (span.direction == RIGHT_TO_LEFT) + start_offset -= cluster_width; + double end_offset = start_offset + cluster_width; + + int unused = 0; + double midpoint_offset = (start_offset + end_offset) * 0.5; + // as far as I know these functions are const, they're just not marked as such + Path::cut_position *midpoint_otp = const_cast(path).CurvilignToPosition(1, &midpoint_offset, unused); + if (midpoint_offset >= 0.0 && midpoint_otp != NULL && midpoint_otp[0].piece >= 0) { + NR::Point midpoint; + NR::Point tangent; + + const_cast(path).PointAndTangentAt(midpoint_otp[0].piece, midpoint_otp[0].t, midpoint, tangent); + + if (start_offset >= 0.0 && end_offset >= 0.0) { + Path::cut_position *start_otp = const_cast(path).CurvilignToPosition(1, &start_offset, unused); + if (start_otp != NULL && start_otp[0].piece >= 0) { + Path::cut_position *end_otp = const_cast(path).CurvilignToPosition(1, &end_offset, unused); + if (end_otp != NULL && end_otp[0].piece >= 0) { + bool on_same_subpath = true; + for (size_t i = 0 ; i < path.pts.size() ; i++) { + if (path.pts[i].piece <= start_otp[0].piece) continue; + if (path.pts[i].piece >= end_otp[0].piece) break; + if (path.pts[i].isMoveTo == polyline_moveto) { + on_same_subpath = false; + break; + } + } + if (on_same_subpath) { + // both points were on the same subpath (without this test the angle is very weird) + NR::Point startpoint, endpoint; + const_cast(path).PointAt(start_otp[0].piece, start_otp[0].t, startpoint); + const_cast(path).PointAt(end_otp[0].piece, end_otp[0].t, endpoint); + if (endpoint != startpoint) { + tangent = endpoint - startpoint; + tangent.normalize(); + } else { + tangent = NR::Point (0,0); + } + } + g_free(end_otp); + } + g_free(start_otp); + } + } + + double rotation = atan2(tangent[1], tangent[0]); + for (int glyph_index = _characters[char_index].in_glyph ; glyph_index < next_cluster_glyph_index ; glyph_index++) { + double tangent_shift = -cluster_width * 0.5 + _glyphs[glyph_index].x - (_characters[char_index].x + span.x_start); + double normal_shift = _glyphs[glyph_index].y; + if (span.direction == RIGHT_TO_LEFT) + tangent_shift += cluster_width; + _glyphs[glyph_index].x = midpoint[0] - span.chunk(this).left_x + tangent[0] * tangent_shift - tangent[1] * normal_shift; + _glyphs[glyph_index].y = midpoint[1] - _lines.front().baseline_y + tangent[1] * tangent_shift + tangent[0] * normal_shift; + _glyphs[glyph_index].rotation += rotation; + } + } else { // outside the bounds of the path: hide the glyphs + _characters[char_index].in_glyph = -1; + } + g_free(midpoint_otp); + + char_index = next_cluster_char_index; + } + + for (unsigned span_index = 0 ; span_index < _spans.size() ; span_index++) { + _spans[span_index].x_start += offset; + _spans[span_index].x_end += offset; + } + + _path_fitted = &path; +} + +SPCurve *Layout::convertToCurves(iterator const &from_glyph, iterator const &to_glyph) const +{ + GSList *cc = NULL; + + for (int glyph_index = from_glyph._glyph_index ; glyph_index < to_glyph._glyph_index ; glyph_index++) { + NRMatrix glyph_matrix; + Span const &span = _glyphs[glyph_index].span(this); + _getGlyphTransformMatrix(glyph_index, &glyph_matrix); + + NRBPath bpath; + bpath.path = (NArtBpath*)span.font->ArtBPath(_glyphs[glyph_index].glyph); + if (bpath.path) { + NArtBpath *abp = nr_artpath_affine(bpath.path, glyph_matrix); + SPCurve *c = sp_curve_new_from_bpath(abp); + if (c) cc = g_slist_prepend(cc, c); + } + } + cc = g_slist_reverse(cc); + + SPCurve *curve; + if ( cc ) { + curve = sp_curve_concat(cc); + } else { + curve = sp_curve_new(); + } + + while (cc) { + /* fixme: This is dangerous, as we are mixing art_alloc and g_new */ + sp_curve_unref((SPCurve *) cc->data); + cc = g_slist_remove(cc, cc->data); + } + + return curve; +} + +void Layout::transform(NR::Matrix const &transform) +{ + // this is all massively oversimplified + // I can't actually think of anybody who'll want to use it at the moment, so it'll stay simple + for (unsigned glyph_index = 0 ; glyph_index < _glyphs.size() ; glyph_index++) { + NR::Point point(_glyphs[glyph_index].x, _glyphs[glyph_index].y); + point *= transform; + _glyphs[glyph_index].x = point[0]; + _glyphs[glyph_index].y = point[1]; + } +} + +}//namespace Text +}//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:textwidth=99 : diff --git a/src/libnrtype/Layout-TNG-Scanline-Maker.h b/src/libnrtype/Layout-TNG-Scanline-Maker.h new file mode 100755 index 000000000..3865e2c12 --- /dev/null +++ b/src/libnrtype/Layout-TNG-Scanline-Maker.h @@ -0,0 +1,169 @@ +/* + * Inkscape::Text::Layout::ScanlineMaker - text layout engine shape measurers + * + * Authors: + * Richard Hughes + * + * Copyright (C) 2005 Richard Hughes + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ +#ifndef __LAYOUT_TNG_SCANLINE_MAKER_H__ +#define __LAYOUT_TNG_SCANLINE_MAKER_H__ + +#include +#include +#include "libnrtype/Layout-TNG.h" + +class Shape; + +namespace Inkscape { +namespace Text { + +/** \brief private to Layout. Generates lists of chunks within a shape. + +This is the abstract base class for taking a given shape and scanning through +it line-by-line to get the horizontal extents of each chunk for a line of a +given height. There are two specialisations: One for real shapes and one that +turns off wrapping by simulating an infinite shape. In due course there will +be a further specialisation to optimise for the common case where the shape +is a rectangle. +*/ +class Layout::ScanlineMaker +{ +public: + virtual ~ScanlineMaker() {} + + struct ScanRun { + double y; /// that's the top of the scan run, not the baseline + double x_start; // these are not flipped according to the text direction + double x_end; + inline double width() const {return std::abs(x_start - x_end);} + }; + + /** Returns a list of chunks on the current line which can fit text with + the given properties. It is up to the caller to discard any chunks which + are too narrow for its needs. This function may change the y coordinate + between calls if the new height too big to fit in the space remaining in + this shape. Returns an empty vector if there is no space left in the + current shape. */ + virtual std::vector makeScanline(Layout::LineHeight const &line_height) =0; + + /** Indicates that the caller has successfully filled the current line + and hence that the next call to makeScanline() should return lines on + the next lower line. There is no error return, the next call to + makeScanline() will give an error if there is no more space. */ + virtual void completeLine() =0; + + /** Returns the y coordinate of the top of the scanline that will be + returned by the next call to makeScanline(). */ + virtual double yCoordinate() = 0; + + /** Forces an arbitrary change in the stored y coordinate of the object. + The next call to makeScanline() will return runs whose top is at + the new coordinate. */ + virtual void setNewYCoordinate(double new_y) =0; + + /** Tests whether the caller can fit a new line with the given metrics + into exactly the space returned by the previous call to makeScanline(). + This saves the caller from having to discard its wrapping solution and + starting at the beginning of the line again when a larger font is seen. + The metrics given here are considered to be the ones that are being + used now, and hence is the line advance height used by completeLine(). + */ + virtual bool canExtendCurrentScanline(Layout::LineHeight const &line_height) =0; +}; + +/** \brief private to Layout. Generates infinite scanlines for when you don't want wrapping + +This is a 'fake' scanline maker which will always return infinite results, +effectively turning off wrapping. It's a very simple implementation. + +It does have the curious property, however, that the input coordinates are +'real' x and y, but the outputs are rotated according to the +\a block_progression. +*/ +class Layout::InfiniteScanlineMaker : public Layout::ScanlineMaker +{ +public: + InfiniteScanlineMaker(double initial_x, double initial_y, Layout::Direction block_progression); + ~InfiniteScanlineMaker(); + + /** Returns a single infinite run at the current location */ + virtual std::vector makeScanline(Layout::LineHeight const &line_height); + + /** Increments the current y by the current line height */ + virtual void completeLine(); + + virtual double yCoordinate() + {return _y;} + + /** Just changes y */ + virtual void setNewYCoordinate(double new_y); + + /** Always true, but has to save the new height */ + virtual bool canExtendCurrentScanline(Layout::LineHeight const &line_height); + +private: + double _x, _y; + Layout::LineHeight _current_line_height; + bool _negative_block_progression; /// if true, indicates that completeLine() should decrement rather than increment, ie block-progression is either rl or bt +}; + +/** \brief private to Layout. Generates scanlines inside an arbitrary shape + +This is the 'perfect', and hence slowest, implementation of a +Layout::ScanlineMaker, which will return exact bounds for any given +input shape. +*/ +class Layout::ShapeScanlineMaker : public Layout::ScanlineMaker +{ +public: + ShapeScanlineMaker(Shape const *shape, Layout::Direction block_progression); + ~ShapeScanlineMaker(); + + virtual std::vector makeScanline(Layout::LineHeight const &line_height); + + virtual void completeLine(); + + virtual double yCoordinate(); + + virtual void setNewYCoordinate(double new_y); + + /** never true */ + virtual bool canExtendCurrentScanline(Layout::LineHeight const &line_height); +private: + /** To generate scanlines for top-to-bottom text it is easiest if we + simply rotate the given shape by a multiple of 90 degrees. This stores + that. If no rotation was needed we can simply store the pointer we were + given and set shape_needs_freeing appropriately. */ + Shape *_rotated_shape; + + /// see #rotated_shape; + bool _shape_needs_freeing; + + // Shape::BeginRaster() needs floats rather than doubles + float _bounding_box_top, _bounding_box_bottom; + float _y; + float _rasterizer_y; + int _current_rasterization_point; + float _current_line_height; + + bool _negative_block_progression; /// if true, indicates that completeLine() should decrement rather than increment, ie block-progression is either rl or bt +}; + +}//namespace Text +}//namespace Inkscape + +#endif + +/* + 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:textwidth=99 : diff --git a/src/libnrtype/Layout-TNG-Scanline-Makers.cpp b/src/libnrtype/Layout-TNG-Scanline-Makers.cpp new file mode 100755 index 000000000..73b4dd6fa --- /dev/null +++ b/src/libnrtype/Layout-TNG-Scanline-Makers.cpp @@ -0,0 +1,189 @@ +/* + * Inkscape::Text::Layout::ScanlineMaker - text layout engine shape measurers + * + * Authors: + * Richard Hughes + * + * Copyright (C) 2005 Richard Hughes + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ +#include "Layout-TNG-Scanline-Maker.h" +#include "livarot/Shape.h" +#include "livarot/float-line.h" + +namespace Inkscape { +namespace Text { + +// *********************** infinite version + +Layout::InfiniteScanlineMaker::InfiniteScanlineMaker(double initial_x, double initial_y, Layout::Direction block_progression) +{ + _current_line_height.ascent = 0.0; + _current_line_height.descent = 0.0; + _current_line_height.leading = 0.0; + switch (block_progression) { + case LEFT_TO_RIGHT: + case RIGHT_TO_LEFT: + _x = initial_y; + _y = initial_x; + break; + default: + _x = initial_x; + _y = initial_y; + break; + } + _negative_block_progression = block_progression == RIGHT_TO_LEFT || block_progression == BOTTOM_TO_TOP; + +} + +Layout::InfiniteScanlineMaker::~InfiniteScanlineMaker() +{ +} + +std::vector Layout::InfiniteScanlineMaker::makeScanline(Layout::LineHeight const &line_height) +{ + std::vector runs(1); + runs[0].x_start = _x; + runs[0].x_end = FLT_MAX; // we could use DBL_MAX, but this just seems safer + runs[0].y = _y; + _current_line_height = line_height; + return runs; +} + +void Layout::InfiniteScanlineMaker::completeLine() +{ + if (_negative_block_progression) + _y -= _current_line_height.total(); + else + _y += _current_line_height.total(); + _current_line_height.ascent = 0.0; + _current_line_height.descent = 0.0; + _current_line_height.leading = 0.0; +} + +void Layout::InfiniteScanlineMaker::setNewYCoordinate(double new_y) +{ + _y = new_y; +} + +bool Layout::InfiniteScanlineMaker::canExtendCurrentScanline(Layout::LineHeight const &line_height) +{ + _current_line_height = line_height; + return true; +} + +// *********************** real shapes version + +Layout::ShapeScanlineMaker::ShapeScanlineMaker(Shape const *shape, Layout::Direction block_progression) +{ + if (block_progression == TOP_TO_BOTTOM) { + _rotated_shape = const_cast(shape); + _shape_needs_freeing = false; + } else { + Shape *temp_rotated_shape = new Shape; + _shape_needs_freeing = true; + temp_rotated_shape->Copy(const_cast(shape)); + switch (block_progression) { + case BOTTOM_TO_TOP: temp_rotated_shape->Transform(NR::Matrix(1.0, 0.0, 0.0, -1.0, 0.0, 0.0)); break; // reflect about x axis + case LEFT_TO_RIGHT: temp_rotated_shape->Transform(NR::Matrix(0.0, 1.0, 1.0, 0.0, 0.0, 0.0)); break; // reflect about y=x + case RIGHT_TO_LEFT: temp_rotated_shape->Transform(NR::Matrix(0.0, -1.0, 1.0, 0.0, 0.0, 0.0)); break; // reflect about y=-x + default: break; + } + _rotated_shape = new Shape; + _rotated_shape->ConvertToShape(temp_rotated_shape); + delete temp_rotated_shape; + } + _rotated_shape->CalcBBox(true); + _bounding_box_top = _rotated_shape->topY; + _bounding_box_bottom = _rotated_shape->bottomY; + _y = _rasterizer_y = _bounding_box_top; + _current_rasterization_point = 0; + _rotated_shape->BeginRaster(_y, _current_rasterization_point); + _negative_block_progression = block_progression == RIGHT_TO_LEFT || block_progression == BOTTOM_TO_TOP; +} + + +Layout::ShapeScanlineMaker::~ShapeScanlineMaker() +{ + _rotated_shape->EndRaster(); + if (_shape_needs_freeing) + delete _rotated_shape; +} + +std::vector Layout::ShapeScanlineMaker::makeScanline(Layout::LineHeight const &line_height) +{ + FloatLigne line_rasterization; + FloatLigne line_decent_length_runs; + float line_text_height = (float)(line_height.ascent + line_height.descent); + + if (_y > _bounding_box_bottom) + return std::vector(); + + if (_y < _bounding_box_top) + _y = _bounding_box_top; + + if (line_text_height == 0.0) + line_text_height = 0.001; // Scan() doesn't work for zero height so this will have to do + + _current_line_height = (float)line_height.total(); + + // I think what's going on here is that we're moving the top of the scanline to the given position... + _rotated_shape->Scan(_rasterizer_y, _current_rasterization_point, _y, line_text_height); + // ...then actually retreiving the scanline (which alters the first two parameters) + _rotated_shape->Scan(_rasterizer_y, _current_rasterization_point, _y + line_text_height , &line_rasterization, true, line_text_height); + // sanitise the raw rasterisation, which could have weird overlaps + line_rasterization.Flatten(); + // cut out runs that cover less than 90% of the line + line_decent_length_runs.Over(&line_rasterization, 0.9 * line_text_height); + + if (line_decent_length_runs.runs.empty()) + { + if (line_rasterization.runs.empty()) + return std::vector(); // stop the flow + // make up a pointless run: anything that's not an empty vector + std::vector result(1); + result[0].x_start = line_rasterization.runs[0].st; + result[0].x_end = line_rasterization.runs[0].st; + result[0].y = _negative_block_progression ? -_current_line_height - _y : _y; + return result; + } + + // convert the FloatLigne to what we use: vector + std::vector result(line_decent_length_runs.runs.size()); + for (unsigned i = 0 ; i < result.size() ; i++) { + result[i].x_start = line_decent_length_runs.runs[i].st; + result[i].x_end = line_decent_length_runs.runs[i].en; + result[i].y = _negative_block_progression ? -_current_line_height - _y : _y; + } + + return result; +} + +void Layout::ShapeScanlineMaker::completeLine() +{ + _y += _current_line_height; +} + +double Layout::ShapeScanlineMaker::yCoordinate() +{ + if (_negative_block_progression) return -_current_line_height - _y; + return _y; +} + +void Layout::ShapeScanlineMaker::setNewYCoordinate(double new_y) +{ + _y = (float)new_y; + if (_negative_block_progression) _y = -_current_line_height - _y; + // what will happen with the rasteriser if we move off the shape? + // it's not an important question because doesn't have a y attribute +} + +bool Layout::ShapeScanlineMaker::canExtendCurrentScanline(Layout::LineHeight const &line_height) +{ + //we actually could return true if only the leading changed, but that's too much effort for something that rarely happens + return false; +} + +}//namespace Text +}//namespace Inkscape diff --git a/src/libnrtype/Layout-TNG.cpp b/src/libnrtype/Layout-TNG.cpp new file mode 100755 index 000000000..bda0d1697 --- /dev/null +++ b/src/libnrtype/Layout-TNG.cpp @@ -0,0 +1,45 @@ +/* + * Inkscape::Text::Layout - text layout engine misc + * + * Authors: + * Richard Hughes + * + * Copyright (C) 2005 Richard Hughes + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ +#include "Layout-TNG.h" + +namespace Inkscape { +namespace Text { + +const gunichar Layout::UNICODE_SOFT_HYPHEN = 0x00AD; +const double Layout::LINE_HEIGHT_NORMAL = 1.25; + +Layout::Layout() +{ + _path_fitted = NULL; +} + +Layout::~Layout() +{ + clear(); +} + +void Layout::clear() +{ + _clearInputObjects(); + _clearOutputObjects(); +} + +bool Layout::_directions_are_orthogonal(Direction d1, Direction d2) +{ + if (d1 == BOTTOM_TO_TOP) d1 = TOP_TO_BOTTOM; + if (d2 == BOTTOM_TO_TOP) d2 = TOP_TO_BOTTOM; + if (d1 == RIGHT_TO_LEFT) d1 = LEFT_TO_RIGHT; + if (d2 == RIGHT_TO_LEFT) d2 = LEFT_TO_RIGHT; + return d1 != d2; +} + +}//namespace Text +}//namespace Inkscape diff --git a/src/libnrtype/Layout-TNG.h b/src/libnrtype/Layout-TNG.h new file mode 100755 index 000000000..6400ee77b --- /dev/null +++ b/src/libnrtype/Layout-TNG.h @@ -0,0 +1,1029 @@ +/* + * Inkscape::Text::Layout - text layout engine + * + * Authors: + * Richard Hughes + * + * Copyright (C) 2005 Richard Hughes + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ +#ifndef __LAYOUT_TNG_H__ +#define __LAYOUT_TNG_H__ + +#include "libnr/nr-rect.h" +#include "libnr/nr-matrix.h" +#include "libnr/nr-matrix-ops.h" +#include "libnr/nr-rotate-ops.h" +#include +#include +#include + +class SPStyle; +class Shape; +class NRArenaGroup; +class SPPrintContext; +class SVGLength; +class Path; +class SPCurve; +class font_instance; + +namespace Inkscape { +namespace Text { + +/** \brief Generates the layout for either wrapped or non-wrapped text and stores the result + +Use this class for all your text output needs. It takes text with formatting +markup as input and turns that into the glyphs and their necessary positions. +It stores the glyphs internally, but maintains enough information to both +retrieve your own rendering information if you wish and to perform visual +text editing where the output refers back to where it came from. + +Usage: +-# Construct +-# Set the text using appendText() and appendControlCode() +-# If you want text wrapping, call appendWrapShape() a few times +-# Call calculateFlow() +-# You can go several directions from here, but the most interesting + things start with creating a Layout::iterator with begin() or end(). + +Terminology, in descending order of size: +- Flow: Not often used, but when it is it means all the text +- Shape: A Shape object which is used to represent one of the regions inside + which to flow the text. Can overlap with... +- Paragraph: Err...A paragraph. Contains one or more... +- Line: An entire horizontal line with a common baseline. Contains one or + more... +- Chunk: You only get more than one of these when a shape is sufficiently + complex that the text has to flow either side of some obstruction in + the middle. A chunk is the base unit for wrapping. Contains one or more... +- Span: A convenient subset of a chunk with the same font, style, + directionality, block progression and input stream. Fill and outline + need not be constant because that's a later rendering stage. +- This is where it gets weird because a span will contain one or more + elements of both of the following, which can overlap with each other in + any way: + - Character: a single Unicode codepoint from an input stream. Many arabic + characters contain multiple glyphs + - Glyph: a rendering primitive for font engines. A ligature glyph will + represent multiple characters. + +Other terminology: +- Input stream: An object representing a single call to appendText() or + appendControlCode(). +- Control code: Metadata in the text stream to signify items that occupy + real space (unlike style changes) but don't belong in the text string. + Paragraph breaks are in this category. See Layout::TextControlCode. +- SVG1.1: The W3C Recommendation "Scalable Vector Graphics (SVG) 1.1" + http://www.w3.org/TR/SVG11/ +- 'left', 'down', etc: These terms are generally used to mean what they + mean in left-to-right, top-to-bottom text but rotated or reflected for + the current directionality. Thus, the 'width' of a ttb line is actually + its height, and the (internally stored) y coordinate of a glyph is + actually its x coordinate. Confusing to the reader but much simpler in + the code. All public methods use real x and y. + +Comments: +- There's a strong emphasis on international support in this class, but + that's primarily because once you can display all the insane things + required by various languages, simple things like styling text are + almost trivial. +- There are a few places (appendText() is one) where pointers are held to + caller-owned objects and used for quite a long time. This is messy but + is safe for our usage scenario and in many cases the cost of copying the + objects is quite high. +- "Why isn't foo here?": Ask yourself if it's possible to implement foo + externally using iterators. However this may not mean that it doesn't + belong as a member, though. +- I've used floats rather than doubles to store relative distances in some + places (internal only) where it would save significant amounts of memory. + The SVG spec allows you to do this as long as intermediate calculations + are done double. Very very long lines might not finish precisely where + you want, but that's to be expected with any typesetting. Also, + SVGLength only uses floats. +- If you look at the six arrays for holding the output data you'll realise + that there's no O(1) way to drill down from a paragraph to find its + starting glyph. This was a conscious decision to reduce complexity and + to save memory. Drilling down isn't actually that slow because a binary + chop will work nicely. Add this to the realisation that most of the + times you do this will be in response to user actions and hence you only + need to be faster than the user and I think the design makes sense. +- There are a massive number of functions acting on Layout::iterator. A + large number are trivial and will be inline, but is it really necessary + to have all these, especially when some can be implemented by the caller + using the others? +- The separation of methods between Layout and Layout::iterator is a + bit arbitrary, because many methods could go in either. I've used the STL + model where the iterator itself can only move around; the base class is + required to do anything interesting. +- I use Pango internally, not Pangomm. The reason for this is lots of + Pangomm methods take Glib::ustrings as input and then output byte offsets + within the strings. There's simply no way to use byte offsets with + ustrings without some very entertaining reinterpret_cast<>s. The Pangomm + docs seem to be lacking quite a lot of things mentioned in the Pango + docs, too. +*/ +class Layout { +public: + class iterator; + friend class iterator; + class Calculator; + friend class Calculator; + class ScanlineMaker; + class InfiniteScanlineMaker; + class ShapeScanlineMaker; + + Layout(); + virtual ~Layout(); + + /** Used to specify any particular text direction required. Used for + both the 'direction' and 'block-progression' CSS attributes. */ + enum Direction {LEFT_TO_RIGHT, RIGHT_TO_LEFT, TOP_TO_BOTTOM, BOTTOM_TO_TOP}; + + /** Display alignment for shapes. See appendWrapShape(). */ + enum DisplayAlign {DISPLAY_ALIGN_BEFORE, DISPLAY_ALIGN_CENTER, DISPLAY_ALIGN_AFTER}; + + /** The optional attributes which can be applied to a SVG text or + related tag. See appendText(). See SVG1.1 section 10.4 for the + definitions of all these members. See sp_svg_length_list_read() for + the standard way to make these vectors. It is the responsibility of + the caller to deal with the inheritance of these values using its + knowledge of the parse tree. */ + struct OptionalTextTagAttrs { + std::vector x; + std::vector y; + std::vector dx; + std::vector dy; + std::vector rotate; + }; + + /** Control codes which can be embedded in the text to be flowed. See + appendControlCode(). */ + enum TextControlCode { + PARAGRAPH_BREAK, /// forces the flow to move on to the next line + SHAPE_BREAK, /// forces the flow to ignore the remainder of the current shape (from #flow_inside_shapes) and continue at the top of the one after. + ARBITRARY_GAP /// inserts an arbitrarily-sized hole in the flow in line with the current text. + }; + + /** For expressing paragraph alignment. These values are rotated in the + case of vertical text, but are not dependent on whether the paragraph is + rtl or ltr, thus LEFT is always either left or top. */ + enum Alignment {LEFT, CENTER, RIGHT, FULL}; + + /** The CSS spec allows line-height:normal to be whatever the user agent + thinks will look good. This is our value, as a multiple of font-size. */ + static const double LINE_HEIGHT_NORMAL; + + // ************************** describing the stuff to flow ************************* + + /** \name Input + Methods for describing the text you want to flow, its style, and the + shapes to flow in to. + */ + //@{ + + /** Empties everything stored in this class and resets it to its + original state, like when it was created. All iterators on this + object will be invalidated (but can be revalidated using + validateIterator(). */ + void clear(); + + /** Queries whether any calls have been made to appendText() or + appendControlCode() since the object was last cleared. */ + bool inputExists() const + {return !_input_stream.empty();} + + /** adds a new piece of text to the end of the current list of text to + be processed. This method can only add text of a consistent style. + To add lots of different styles, call it lots of times. + \param text The text. \b Note: only a \em pointer is stored. Do not + mess with the text until after you have called + calculateFlow(). + \param style The font style. Layout will hold a reference to this + object for the duration of its ownership, ie until you + call clear() or the class is destroyed. Must not be NULL. + \param source_cookie This pointer is treated as opaque by Layout + but will be passed through the flowing process intact so + that callers can use it to refer to the original object + that generated a particular glyph. See Layout::iterator. + Implementation detail: currently all callers put an + SPString in here. + \param optional_attributes A structure containing additional options + for this text. See OptionalTextTagAttrs. The values are + copied to internal storage before this method returns. + \param optional_attributes_offset It is convenient for callers to be + able to use the same \a optional_attributes structure for + several sequential text fields, in which case the vectors + will need to be offset. This parameter causes the nth + element of all the vectors to be read as if it were the + first. + \param text_begin Used for selecting only a substring of \a text + to process. + \param text_end Used for selecting only a substring of \a text + to process. + */ + void appendText(Glib::ustring const &text, SPStyle *style, void *source_cookie, OptionalTextTagAttrs const *optional_attributes, unsigned optional_attributes_offset, Glib::ustring::const_iterator text_begin, Glib::ustring::const_iterator text_end); + inline void appendText(Glib::ustring const &text, SPStyle *style, void *source_cookie, OptionalTextTagAttrs const *optional_attributes = NULL, unsigned optional_attributes_offset = 0) + {appendText(text, style, source_cookie, optional_attributes, optional_attributes_offset, text.begin(), text.end());} + + /** Control codes are metadata in the text stream to signify items + that occupy real space (unlike style changes) but don't belong in the + text string. See TextControlCode for the types available. + + A control code \em cannot be the first item in the input stream. Use + appendText() with an empty string to set up the paragraph properties. + \param code A member of the TextFlowControlCode enumeration. + \param width The width in pixels that this item occupies. + \param ascent The number of pixels above the text baseline that this + control code occupies. + \param descent The number of pixels below the text baseline that this + control code occupies. + \param source_cookie This pointer is treated as opaque by Layout + but will be passed through the flowing process intact so + that callers can use it to refer to the original object + that generated a particular area. See Layout::iterator. + Implementation detail: currently all callers put an + SPObject in here. + Note that for some control codes (eg tab) the values of the \a width, + \a ascender and \a descender are implied by the surrounding text (and + in the case of tabs, the values set in tab_stops) so the values you pass + here are ignored. + */ + void appendControlCode(TextControlCode code, void *source_cookie, double width = 0.0, double ascent = 0.0, double descent = 0.0); + + /** Stores another shape inside which to flow the text. If this method + is never called then no automatic wrapping is done and lines will + continue to infinity if necessary. Text can be flowed inside multiple + shapes in sequence, like with frames in a DTP package. If the text flows + past the end of the last shape all remaining text is ignored. + + \param shape The Shape to use next in the flow. The storage for this + is managed by the caller, and need only be valid for + the duration of the call to calculateFlow(). + \param display_align The vertical alignment of the text within this + shape. See XSL1.0 section 7.13.4. The behaviour of + settings other than DISPLAY_ALIGN_BEFORE when using + non-rectangular shapes is undefined. + */ + void appendWrapShape(Shape const *shape, DisplayAlign display_align = DISPLAY_ALIGN_BEFORE); + + //@} + + // ************************** doing the actual flowing ************************* + + /** \name Processing + The method to do the actual work of converting text into glyphs. + */ + //@{ + + /** Takes all the stuff you set with the members above here and creates + a load of glyphs for use with the members below here. All iterators on + this object will be invalidated (but can be fixed with validateIterator(). + The implementation just creates a new Layout::Calculator and calls its + Calculator::Calculate() method, so if you want more details on the + internals, go there. + \return false on failure. + */ + bool calculateFlow(); + + //@} + + // ************************** operating on the output glyphs ************************* + + /** \name Output + Methods for reading and interpreting the output glyphs. See also + Layout::iterator. + */ + //@{ + + /** Returns true if there are some glyphs in this object, ie whether + computeFlow() has been called on a non-empty input since the object was + created or the last call to clear(). */ + inline bool outputExists() const + {return !_characters.empty();} + + /** Adds all the output glyphs to \a in_arena using the given \a paintbox. + \param in_arena The arena to add the glyphs group to + \param paintbox The current rendering tile + */ + void show(NRArenaGroup *in_arena, NRRect const *paintbox) const; + + /** Calculates the smallest rectangle completely enclosing all the + glyphs. + \param bounding_box Where to store the box + \param transform The transform to be applied to the entire object + prior to calculating its bounds. + */ + void getBoundingBox(NRRect *bounding_box, NR::Matrix const &transform) const; + + /** Sends all the glyphs to the given print context. + \param ctx I have + \param pbox no idea + \param dbox what these + \param bbox parameters + \param ctm do yet + */ + void print(SPPrintContext *ctx, NRRect const *pbox, NRRect const *dbox, NRRect const *bbox, NRMatrix const &ctm) const; + + /** debug and unit test method. Creates a textual representation of the + contents of this object. The output is designed to be both human-readable + and comprehensible when diffed with a known-good dump. */ + Glib::ustring dumpAsText() const; + + /** Moves all the glyphs in the structure so that the baseline of all + the characters sits neatly along the path specified. If the text has + more than one line the results are undefined. The 'align' means to + use the SVG align method as documented in SVG1.1 section 10.13.2. + NB: njh has suggested that it would be cool if we could flow from + shape to path and back again. This is possible, so this method will be + removed at some point. + A pointer to \a path is retained by the class for use by the cursor + positioning functions. */ + void fitToPathAlign(SVGLength const &startOffset, Path const &path); + + /** Convert the specified range of characters into their bezier + outlines. + */ + SPCurve* convertToCurves(iterator const &from_glyph, iterator const &to_glyph) const; + inline SPCurve* convertToCurves() const; + + /** Apply the given transform to all the output presently stored in + this object. This only transforms the glyph positions, The glyphs + themselves will not be transformed. */ + void transform(NR::Matrix const &transform); + + //@} + + // ********** + + /** \name Output (Iterators) + Methods for operating with the Layout::iterator class. The method + names ending with 'Index' return 0-based offsets of the number of + items since the beginning of the flow. + */ + //@{ + + /** Returns an iterator pointing at the first glyph of the flowed output. + The first glyph is also the first character, line, paragraph, etc. */ + inline iterator begin() const; + + /** Returns an iterator pointing just past the end of the last glyph, + which is also just past the end of the last chunk, span, etc, etc. */ + inline iterator end() const; + + /** Returns an iterator pointing at the given character index. This + index should be related to the result from a prior call to + iteratorToCharIndex(). */ + inline iterator charIndexToIterator(int char_index) const; + + /** Returns the character index from the start of the flow represented + by the given iterator. This number isn't very useful, except for when + editing text it will stay valid across calls to computeFlow() and will + change in predictable ways when characters are added and removed. It's + also useful when transitioning old code. */ + inline int iteratorToCharIndex(iterator const &it) const; + + /** Checks the validity of the given iterator over the current layout. + If it points to a position out of the bounds for this layout it will + be corrected to the nearest valid position. If you pass an iterator + belonging to a different layout it will be converted to one for this + layout. */ + inline void validateIterator(iterator *it) const; + + /** Returns an iterator pointing to the cursor position for a mouse + click at the given coordinates. */ + iterator getNearestCursorPositionTo(double x, double y) const; + inline iterator getNearestCursorPositionTo(NR::Point &point) const; + + /** Returns an iterator pointing to the letter whose bounding box contains + the given coordinates. end() if the point is not over any letter. The + iterator will \em not point at the specific glyph within the character. */ + iterator getLetterAt(double x, double y) const; + inline iterator getLetterAt(NR::Point &point) const; + + /** Returns an iterator pointing to the character in the output which + was created from the given input. If the character at the given byte + offset was removed (soft hyphens, for example) the next character after + it is returned. If no input was added with the given cookie, end() is + returned. If more than one input has the same cookie, the first will + be used regardless of the value of \a text_iterator. If + \a text_iterator is out of bounds, the first or last character belonging + to the given input will be returned accordingly. */ + iterator sourceToIterator(void *source_cookie, Glib::ustring::const_iterator text_iterator) const; + + /** Returns an iterator pointing to the first character in the output + which was created from the given source. If \a source_cookie is invalid, + end() is returned. If more than one input has the same cookie, the + first one will be used. */ + iterator sourceToIterator(void *source_cookie) const; + + // many functions acting on iterators, most of which are obvious + // also most of them don't check that \a it != end(). Be careful. + + /** Returns the bounding box of the given glyph, and its rotation. + The centre of rotation is the horizontal centre of the box at the + text baseline. */ + NR::Rect glyphBoundingBox(iterator const &it, double *rotation) const; + + /** Returns the zero-based line number of the character pointed to by + \a it. */ + inline unsigned lineIndex(iterator const &it) const; + + /** Returns the zero-based number of the shape which contains the + character pointed to by \a it. */ + inline unsigned shapeIndex(iterator const &it) const; + + /** Returns true if the character at \a it is a whitespace, as defined + by Pango. This is not meant to be used for picking out words from the + output, use iterator::nextStartOfWord() and friends instead. */ + inline bool isWhitespace(iterator const &it) const; + + /** Returns the unicode character code of the character pointed to by + \a it. If \a it == end() the result is undefined. */ + inline int characterAt(iterator const &it) const; + + /** Discovers where the character pointed to by \a it came from, by + retrieving the cookie that was passed to the call to appendText() or + appendControlCode() which generated that output. If \a it == end() + then NULL is returned as the cookie. If the character was generated + from a call to appendText() then the optional \a text_iterator + parameter is set to point to the actual character, otherwise + \a text_iterator is unaltered. */ + void getSourceOfCharacter(iterator const &it, void **source_cookie, Glib::ustring::iterator *text_iterator = NULL) const; + + /** For latin text, the left side of the character, on the baseline */ + NR::Point characterAnchorPoint(iterator const &it) const; + + /** This is that value to apply to the x,y attributes of tspan role=line + elements, and hence it takes alignment into account. */ + NR::Point chunkAnchorPoint(iterator const &it) const; + + /** Returns the box extents (not ink extents) of the given character. + The centre of rotation is at the horizontal centre of the box on the + text baseline. */ + NR::Rect characterBoundingBox(iterator const &it, double *rotation = NULL) const; + + /** Basically uses characterBoundingBox() on all the characters from + \a start to \a end and returns the union of these boxes. The return value + is a list of zero or more quadrilaterals specified by a group of four + points for each, thus size() is always a multiple of four. */ + std::vector createSelectionShape(iterator const &it_start, iterator const &it_end, NR::Matrix const &transform) const; + + /** Returns true if \a it points to a character which is a valid cursor + position, as defined by Pango. */ + inline bool isCursorPosition(iterator const &it) const; + + /** Gets the ideal cursor shape for a given iterator. The result is + undefined if \a it is not at a valid cursor position. + \param it The location in the output + \param position The pixel location of the centre of the 'bottom' of + the cursor. + \param height The height in pixels of the surrounding text + \param rotation The angle to draw from \a position. Radians, zero up, + increasing clockwise. + */ + void queryCursorShape(iterator const &it, NR::Point *position, double *height, double *rotation) const; + + /** Returns true if \a it points to a character which is a the start of + a word, as defined by Pango. */ + inline bool isStartOfWord(iterator const &it) const; + + /** Returns true if \a it points to a character which is a the end of + a word, as defined by Pango. */ + inline bool isEndOfWord(iterator const &it) const; + + /** Returns true if \a it points to a character which is a the start of + a sentence, as defined by Pango. */ + inline bool isStartOfSentence(iterator const &it) const; + + /** Returns true if \a it points to a character which is a the end of + a sentence, as defined by Pango. */ + inline bool isEndOfSentence(iterator const &it) const; + + /** Returns the zero-based number of the paragraph containing the + character pointed to by \a it. */ + inline unsigned paragraphIndex(iterator const &it) const; + + /** Returns the actual alignment used for the paragraph containing + the character pointed to by \a it. This means that the CSS 'start' + and 'end' are correctly translated into LEFT or RIGHT according to + the paragraph's directionality. For vertical text, LEFT is top + alignment and RIGHT is bottom. */ + inline Alignment paragraphAlignment(iterator const &it) const; + + /** Returns kerning information which could cause the current output + to be exactly reproduced if the letter and word spacings were zero and + full justification was not used. The x and y arrays are not used, but + they are cleared. The dx applied to the first character in a chunk + will always be zero. If the region between \a from and \a to crosses + a line break then the results may be surprising, and are undefined. + Trailing zeros on the returned arrays will be trimmed. */ + void simulateLayoutUsingKerning(iterator const &from, iterator const &to, OptionalTextTagAttrs *result) const; + + //@} + + /// it's useful for this to be public so that ScanlineMaker can use it + struct LineHeight { + double ascent; + double descent; + double leading; + inline double total() const {return ascent + descent + leading;} + inline void setZero() {ascent = descent = leading = 0.0;} + inline LineHeight& operator*=(double x) {ascent *= x; descent *= x; leading *= x; return *this;} + void max(LineHeight const &other); /// makes this object contain the largest of all three members between this object and other + }; + + /// see _enum_converter() + struct EnumConversionItem { + int input, output; + }; + +private: + /** Erases all the stuff set by the owner as input, ie #_input_stream + and #_input_wrap_shapes. */ + void _clearInputObjects(); + + /** Erases all the stuff output by computeFlow(). Glyphs and things. */ + void _clearOutputObjects(); + + static const gunichar UNICODE_SOFT_HYPHEN; + + // ******************* input flow + + enum InputStreamItemType {TEXT_SOURCE, CONTROL_CODE}; + + class InputStreamItem { + public: + virtual ~InputStreamItem() {} + virtual InputStreamItemType Type() =0; + void *source_cookie; + }; + + /** Represents a text item in the input stream. See #_input_stream. + Most of the members are copies of the values passed to appendText(). */ + class InputStreamTextSource : public InputStreamItem { + public: + virtual InputStreamItemType Type() {return TEXT_SOURCE;} + virtual ~InputStreamTextSource(); + Glib::ustring const *text; /// owned by the caller + Glib::ustring::const_iterator text_begin, text_end; + int text_length; /// in characters, from text_start to text_end only + SPStyle *style; + /** These vectors can (often will) be shorter than the text + in this source, but never longer. */ + std::vector x; + std::vector y; + std::vector dx; + std::vector dy; + std::vector rotate; + + // a few functions for some of the more complicated style accesses + float styleComputeFontSize() const; + font_instance *styleGetFontInstance() const; + Direction styleGetBlockProgression() const; + Alignment styleGetAlignment(Direction para_direction, bool try_text_align) const; + }; + + /** Represents a control code item in the input stream. See + #_input_streams. All the members are copies of the values passed to + appendControlCode(). */ + class InputStreamControlCode : public InputStreamItem { + public: + virtual InputStreamItemType Type() {return CONTROL_CODE;} + TextControlCode code; + double ascent; + double descent; + double width; + }; + + /** This is our internal storage for all the stuff passed to the + appendText() and appendControlCode() functions. */ + std::vector _input_stream; + + /** The parameters to appendText() are allowed to be a little bit + complex. This copies them to be the right length and starting at zero. + We also don't want to write five bits of identical code just with + different variable names. */ + static void _copyInputVector(std::vector const &input_vector, unsigned input_offset, std::vector *output_vector, size_t max_length); + + /** There are a few cases where we have different sets of enums meaning + the same thing, eg Pango font styles vs. SPStyle font styles. These need + converting. */ + static int _enum_converter(int input, EnumConversionItem const *conversion_table, unsigned conversion_table_size); + + /** The overall block-progression of the whole flow. */ + inline Direction _blockProgression() const + {return static_cast(_input_stream.front())->styleGetBlockProgression();} + + /** so that LEFT_TO_RIGHT == RIGHT_TO_LEFT but != TOP_TO_BOTTOM */ + static bool _directions_are_orthogonal(Direction d1, Direction d2); + + /** If the output is empty callers still want to be able to call + queryCursorShape() and get a valid answer so, while #_input_wrap_shapes + can still be considered valid, we need to precompute the cursor shape + for this case. */ + void _calculateCursorShapeForEmpty(); + + struct CursorShape { + NR::Point position; + double height; + double rotation; + } _empty_cursor_shape; + + // ******************* input shapes + + struct InputWrapShape { + Shape const *shape; /// as passed to Layout::appendWrapShape() + DisplayAlign display_align; /// as passed to Layout::appendWrapShape() + }; + std::vector _input_wrap_shapes; + + // ******************* output + + /** as passed to fitToPathAlign() */ + Path const *_path_fitted; + + struct Glyph; + struct Character; + struct Span; + struct Chunk; + struct Line; + struct Paragraph; + + struct Glyph { + int glyph; + unsigned in_character; + float x; /// relative to the start of the chunk + float y; /// relative to the current line's baseline + float rotation; /// absolute, modulo any object transforms, which we don't know about + float width; + inline Span const & span(Layout const *l) const {return l->_spans[l->_characters[in_character].in_span];} + inline Chunk const & chunk(Layout const *l) const {return l->_chunks[l->_spans[l->_characters[in_character].in_span].in_chunk];} + inline Line const & line(Layout const *l) const {return l->_lines[l->_chunks[l->_spans[l->_characters[in_character].in_span].in_chunk].in_line];} + }; + struct Character { + unsigned in_span; + float x; /// relative to the start of the *span* (so we can do block-progression) + PangoLogAttr char_attributes; + int in_glyph; /// will be -1 if this character has no visual representation + inline Span const & span(Layout const *l) const {return l->_spans[in_span];} + inline Chunk const & chunk(Layout const *l) const {return l->_chunks[l->_spans[in_span].in_chunk];} + inline Line const & line(Layout const *l) const {return l->_lines[l->_chunks[l->_spans[in_span].in_chunk].in_line];} + inline Paragraph const & paragraph(Layout const *l) const {return l->_paragraphs[l->_lines[l->_chunks[l->_spans[in_span].in_chunk].in_line].in_paragraph];} + // to get the advance width of a character, subtract the x values if it's in the middle of a span, or use span.x_end if it's at the end + }; + struct Span { + unsigned in_chunk; + font_instance *font; + float font_size; + float x_start; /// relative to the start of the chunk + float x_end; /// relative to the start of the chunk + LineHeight line_height; + double baseline_shift; /// relative to the line's baseline + Direction direction; /// See CSS3 section 3.2. Either rtl or ltr + Direction block_progression; /// See CSS3 section 3.2. The direction in which lines go. + unsigned in_input_stream_item; + Glib::ustring::const_iterator input_stream_first_character; + inline Chunk const & chunk(Layout const *l) const {return l->_chunks[in_chunk];} + inline Line const & line(Layout const *l) const {return l->_lines[l->_chunks[in_chunk].in_line];} + inline Paragraph const & paragraph(Layout const *l) const {return l->_paragraphs[l->_lines[l->_chunks[in_chunk].in_line].in_paragraph];} + }; + struct Chunk { + unsigned in_line; + double left_x; + }; + struct Line { + unsigned in_paragraph; + double baseline_y; + unsigned in_shape; + }; + struct Paragraph { + Direction base_direction; /// can be overridden by child Span objects + Alignment alignment; + }; + std::vector _paragraphs; + std::vector _lines; + std::vector _chunks; + std::vector _spans; + std::vector _characters; + std::vector _glyphs; + + /** gets the overall matrix that transforms the given glyph from local + space to world space. */ + void _getGlyphTransformMatrix(int glyph_index, NRMatrix *matrix) const; + + // loads of functions to drill down the object tree, all of them + // annoyingly similar and all of them requiring predicate functors. + // I'll be buggered if I can find a way to make it work with + // functions or with a templated functor, so macros it is. +#define EMIT_PREDICATE(name, object_type, index_generator) \ + class name { \ + Layout const * const _flow; \ + public: \ + inline name(Layout const *flow) : _flow(flow) {} \ + inline bool operator()(object_type const &object, unsigned index) \ + {return index_generator < index;} \ + } +// end of macro + EMIT_PREDICATE(PredicateLineToSpan, Span, _flow->_chunks[object.in_chunk].in_line); + EMIT_PREDICATE(PredicateLineToCharacter, Character, _flow->_chunks[_flow->_spans[object.in_span].in_chunk].in_line); + EMIT_PREDICATE(PredicateSpanToCharacter, Character, object.in_span); + EMIT_PREDICATE(PredicateSourceToCharacter, Character, _flow->_spans[object.in_span].in_input_stream_item); + + inline unsigned _lineToSpan(unsigned line_index) const + {return std::lower_bound(_spans.begin(), _spans.end(), line_index, PredicateLineToSpan(this)) - _spans.begin();} + inline unsigned _lineToCharacter(unsigned line_index) const + {return std::lower_bound(_characters.begin(), _characters.end(), line_index, PredicateLineToCharacter(this)) - _characters.begin();} + inline unsigned _spanToCharacter(unsigned span_index) const + {return std::lower_bound(_characters.begin(), _characters.end(), span_index, PredicateSpanToCharacter(this)) - _characters.begin();} + inline unsigned _sourceToCharacter(unsigned source_index) const + {return std::lower_bound(_characters.begin(), _characters.end(), source_index, PredicateSourceToCharacter(this)) - _characters.begin();} + + /** given an x coordinate and a line number, returns an iterator + pointing to the closest cursor position on that line to the + coordinate. */ + iterator _cursorXOnLineToIterator(unsigned line_index, double local_x) const; + + /** calculates the width of a chunk, which is the largest x + coordinate (start or end) of the spans contained within it. */ + double _getChunkWidth(unsigned chunk_index) const; +}; + +/** \brief Holds a position within the glyph output of Layout. + +Used to access the output of a Layout, query information and generally +move around in it. See Layout for a glossary of the names of functions. + +I'm not going to document all the methods because most of their names make +their function self-evident. + +A lot of the functions would do the same thing in a naive implementation +for latin-only text, for example nextCharacter(), nextCursorPosition() and +cursorRight(). Generally it's fairly obvious which one you should use in a +given situation, but sometimes you might need to put some thought in to it. + +All the methods return false if the requested action would have caused the +current position to move out of bounds. In this case the position is moved +to either begin() or end(), depending on which direction you were going. + +Note that some characters do not have a glyph representation (eg line +breaks), so if you try using prev/nextGlyph() from one of these you're +heading for a crash. +*/ +class Layout::iterator { +public: + friend class Layout; + // this is just so you can create uninitialised iterators - don't actually try to use one + iterator() : _parent_layout(NULL) {} + // no copy constructor required, the default does what we want + bool operator== (iterator const &other) const + {return _glyph_index == other._glyph_index && _char_index == other._char_index;} + bool operator!= (iterator const &other) const + {return _glyph_index != other._glyph_index || _char_index != other._char_index;} + + /* mustn't compare _glyph_index in these operators because for characters + that don't have glyphs (line breaks, elided soft hyphens, etc), the glyph + index is -1 which makes them not well-ordered. To be honest, interating by + glyphs is not very useful and should be avoided. */ + bool operator< (iterator const &other) const + {return _char_index < other._char_index;} + bool operator<= (iterator const &other) const + {return _char_index <= other._char_index;} + bool operator> (iterator const &other) const + {return _char_index > other._char_index;} + bool operator>= (iterator const &other) const + {return _char_index >= other._char_index;} + + /* **** visual-oriented methods **** */ + + //glyphs + inline bool prevGlyph(); + inline bool nextGlyph(); + + //span + bool prevStartOfSpan(); + bool thisStartOfSpan(); + bool nextStartOfSpan(); + + //chunk + bool prevStartOfChunk(); + bool thisStartOfChunk(); + bool nextStartOfChunk(); + + //line + bool prevStartOfLine(); + bool thisStartOfLine(); + bool nextStartOfLine(); + bool thisEndOfLine(); + + //shape + bool prevStartOfShape(); + bool thisStartOfShape(); + bool nextStartOfShape(); + + /* **** text-oriented methods **** */ + + //characters + inline bool nextCharacter(); + inline bool prevCharacter(); + + bool nextCursorPosition(); + bool prevCursorPosition(); + bool nextLineCursor(); + bool prevLineCursor(); + + //words + bool nextStartOfWord(); + bool prevStartOfWord(); + bool nextEndOfWord(); + bool prevEndOfWord(); + + //sentences + bool nextStartOfSentence(); + bool prevStartOfSentence(); + bool nextEndOfSentence(); + bool prevEndOfSentence(); + + //paragraphs + bool prevStartOfParagraph(); + bool thisStartOfParagraph(); + bool nextStartOfParagraph(); + //no endOfPara methods because that's just the previous char + + //sources + bool prevStartOfSource(); + bool thisStartOfSource(); + bool nextStartOfSource(); + + //logical cursor movement + bool cursorUp(); + bool cursorDown(); + bool cursorLeft(); + bool cursorRight(); + + //logical cursor movement (by word or paragraph) + bool cursorUpWithControl(); + bool cursorDownWithControl(); + bool cursorLeftWithControl(); + bool cursorRightWithControl(); + +private: + Layout const *_parent_layout; + int _glyph_index; /// index into Layout::glyphs, or -1 + unsigned _char_index; /// index into Layout::character + bool _cursor_moving_vertically; + /** for cursor up/down movement we must maintain the x position where + we started so the cursor doesn't 'drift' left or right with the repeated + quantization to character boundaries. */ + double _x_coordinate; + + inline iterator(Layout const *p, unsigned c, int g) + : _parent_layout(p), _glyph_index(g), _char_index(c), _cursor_moving_vertically(false), _x_coordinate(0.0) {} + inline iterator(Layout const *p, unsigned c) + : _parent_layout(p), _glyph_index(p->_characters[c].in_glyph), _char_index(c), _cursor_moving_vertically(false), _x_coordinate(0.0) {} + // no dtor required + void beginCursorUpDown(); /// stores the current x coordinate so that the cursor won't drift. See #_x_coordinate + + /** moves forward or backwards one cursor position according to the + directionality of the current paragraph, but ignoring block progression. + Helper for the cursor*() functions. */ + bool _cursorLeftOrRightLocalX(Direction direction); + + /** moves forward or backwards by until the next character with + is_word_start according to the directionality of the current paragraph, + but ignoring block progression. Helper for the cursor*WithControl() + functions. */ + bool _cursorLeftOrRightLocalXByWord(Direction direction); +}; + +// ************************** inline methods + +inline SPCurve* Layout::convertToCurves() const + {return convertToCurves(begin(), end());} + +inline Layout::iterator Layout::begin() const + {return iterator(this, 0, 0);} + +inline Layout::iterator Layout::end() const + {return iterator(this, _characters.size(), _glyphs.size());} + +inline Layout::iterator Layout::charIndexToIterator(int char_index) const +{ + if (char_index < 0) return begin(); + if (char_index >= (int)_characters.size()) return end(); + return iterator(this, char_index); +} + +inline int Layout::iteratorToCharIndex(Layout::iterator const &it) const + {return it._char_index;} + +inline void Layout::validateIterator(Layout::iterator *it) const +{ + it->_parent_layout = this; + if (it->_char_index >= _characters.size()) { + it->_char_index = _characters.size(); + it->_glyph_index = _glyphs.size(); + } else + it->_glyph_index = _characters[it->_char_index].in_glyph; +} + +inline Layout::iterator Layout::getNearestCursorPositionTo(NR::Point &point) const + {return getNearestCursorPositionTo(point[0], point[1]);} + +inline Layout::iterator Layout::getLetterAt(NR::Point &point) const + {return getLetterAt(point[0], point[1]);} + +inline unsigned Layout::lineIndex(iterator const &it) const + {return it._char_index == _characters.size() ? _lines.size() - 1 : _characters[it._char_index].chunk(this).in_line;} + +inline unsigned Layout::shapeIndex(iterator const &it) const + {return it._char_index == _characters.size() ? _input_wrap_shapes.size() - 1 : _characters[it._char_index].line(this).in_shape;} + +inline bool Layout::isWhitespace(iterator const &it) const + {return it._char_index == _characters.size() || _characters[it._char_index].char_attributes.is_white;} + +inline int Layout::characterAt(iterator const &it) const +{ + void *unused; + Glib::ustring::iterator text_iter; + getSourceOfCharacter(it, &unused, &text_iter); + return *text_iter; +} + +inline bool Layout::isCursorPosition(iterator const &it) const + {return it._char_index == _characters.size() || _characters[it._char_index].char_attributes.is_cursor_position;} + +inline bool Layout::isStartOfWord(iterator const &it) const + {return it._char_index != _characters.size() && _characters[it._char_index].char_attributes.is_word_start;} + +inline bool Layout::isEndOfWord(iterator const &it) const + {return it._char_index == _characters.size() || _characters[it._char_index].char_attributes.is_word_end;} + +inline bool Layout::isStartOfSentence(iterator const &it) const + {return it._char_index != _characters.size() && _characters[it._char_index].char_attributes.is_sentence_start;} + +inline bool Layout::isEndOfSentence(iterator const &it) const + {return it._char_index == _characters.size() || _characters[it._char_index].char_attributes.is_sentence_end;} + +inline unsigned Layout::paragraphIndex(iterator const &it) const + {return it._char_index == _characters.size() ? _paragraphs.size() - 1 : _characters[it._char_index].line(this).in_paragraph;} + +inline Layout::Alignment Layout::paragraphAlignment(iterator const &it) const + {return _paragraphs[paragraphIndex(it)].alignment;} + +inline bool Layout::iterator::nextGlyph() +{ + _cursor_moving_vertically = false; + if (_glyph_index >= (int)_parent_layout->_glyphs.size() - 1) { + if (_glyph_index == (int)_parent_layout->_glyphs.size()) return false; + _char_index = _parent_layout->_characters.size(); + _glyph_index = _parent_layout->_glyphs.size(); + } + else _char_index = _parent_layout->_glyphs[++_glyph_index].in_character; + return true; +} + +inline bool Layout::iterator::prevGlyph() +{ + _cursor_moving_vertically = false; + if (_glyph_index == 0) return false; + _char_index = _parent_layout->_glyphs[--_glyph_index].in_character; + return true; +} + +inline bool Layout::iterator::nextCharacter() +{ + _cursor_moving_vertically = false; + if (_char_index + 1 >= _parent_layout->_characters.size()) { + if (_char_index == _parent_layout->_characters.size()) return false; + _char_index = _parent_layout->_characters.size(); + _glyph_index = _parent_layout->_glyphs.size(); + } + else _glyph_index = _parent_layout->_characters[++_char_index].in_glyph; + return true; +} + +inline bool Layout::iterator::prevCharacter() +{ + _cursor_moving_vertically = false; + if (_char_index == 0) return false; + _glyph_index = _parent_layout->_characters[--_char_index].in_glyph; + return true; +} + +}//namespace Text +}//namespace Inkscape + +#endif + + +/* + 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:textwidth=99 : diff --git a/src/libnrtype/Makefile_insert b/src/libnrtype/Makefile_insert new file mode 100644 index 000000000..218cbad6b --- /dev/null +++ b/src/libnrtype/Makefile_insert @@ -0,0 +1,42 @@ +## Makefile.am fragment sourced by src/Makefile.am. + +libnrtype/all: libnrtype/libnrtype.a + +libnrtype/clean: + rm -f libnrtype/libnrtype.a $(libnrtype_libnrtype_a_OBJECTS) + +libnrtype_libnrtype_a_SOURCES = \ + libnrtype/boundary-type.h \ + libnrtype/font-style-to-pos.cpp \ + libnrtype/font-style-to-pos.h \ + libnrtype/font-glyph.h \ + libnrtype/font-instance.h \ + libnrtype/font-style.h \ + libnrtype/nr-type-pos-def.cpp \ + libnrtype/nr-type-pos-def.h \ + libnrtype/nr-type-primitives.cpp \ + libnrtype/nr-type-primitives.h \ + libnrtype/nrtype-forward.h \ + libnrtype/FontFactory.cpp \ + libnrtype/FontFactory.h \ + libnrtype/FontInstance.cpp \ + libnrtype/one-box.h \ + libnrtype/one-glyph.h \ + libnrtype/one-para.h \ + libnrtype/RasterFont.cpp \ + libnrtype/RasterFont.h \ + libnrtype/raster-glyph.h \ + libnrtype/raster-position.h \ + libnrtype/text-boundary.h \ + libnrtype/TextWrapper.cpp \ + libnrtype/TextWrapper.h \ + libnrtype/Layout-TNG-Compute.cpp \ + libnrtype/Layout-TNG-Input.cpp \ + libnrtype/Layout-TNG-OutIter.cpp \ + libnrtype/Layout-TNG-Output.cpp \ + libnrtype/Layout-TNG-Scanline-Maker.h \ + libnrtype/Layout-TNG-Scanline-Makers.cpp \ + libnrtype/Layout-TNG.cpp \ + libnrtype/Layout-TNG.h + + diff --git a/src/libnrtype/RasterFont.cpp b/src/libnrtype/RasterFont.cpp new file mode 100644 index 000000000..68ecb2e4d --- /dev/null +++ b/src/libnrtype/RasterFont.cpp @@ -0,0 +1,431 @@ +/* + * RasterFont.cpp + * testICU + * + */ + +#ifdef HAVE_CONFIG_H +# include +#endif +#include "RasterFont.h" + +#include +#include +#include +#include +#include +#include +#include +#include + + +static void glyph_run_A8_OR (raster_info &dest,void */*data*/,int st,float vst,int en,float ven); + +void font_style::Apply(Path* src,Shape* dest) { + src->Convert(1); + if ( stroke_width > 0 ) { + if ( nbDash > 0 ) { + double dlen = 0.0; + const float scale = 1/*NR_MATRIX_DF_EXPANSION (&transform)*/; + for (int i = 0; i < nbDash; i++) dlen += dashes[i] * scale; + if (dlen >= 0.01) { + float sc_offset = dash_offset * scale; + float *tdashs=(float*)malloc((nbDash+1)*sizeof(float)); + while ( sc_offset >= dlen ) sc_offset-=dlen; + tdashs[0]=dashes[0] * scale; + for (int i=1;iDashPolyline(0.0,0.0,dlen,nbDash,tdashs,true,sc_offset); + free(tdashs); + } + } + src->Stroke(dest, false, 0.5*stroke_width, stroke_join, stroke_cap, 0.5*stroke_width*stroke_miter_limit); + } else { + src->Fill(dest,0); + } +} + +raster_font::raster_font(font_style const &fstyle) : + daddy(NULL), + refCount(0), + style(fstyle), + glyph_id_to_raster_glyph_no(), + nbBase(0), + maxBase(0), + bases(NULL) +{ + // printf("raster font born\n"); +} + +raster_font::~raster_font(void) +{ +// printf("raster font death\n"); + if ( daddy ) daddy->RemoveRasterFont(this); + daddy=NULL; + if ( style.dashes ) free(style.dashes); + style.dashes=NULL; + for (int i=0;iRemoveRasterFont(this); + daddy=NULL; + delete this; + } +} +void raster_font::Ref(void) +{ + refCount++; +// printf("raster %x ref'd %i\n",this,refCount); +} +raster_glyph* raster_font::GetGlyph(int glyph_id) +{ + raster_glyph *res=NULL; + if ( glyph_id_to_raster_glyph_no.find(glyph_id) == glyph_id_to_raster_glyph_no.end() ) { + LoadRasterGlyph(glyph_id); + if ( glyph_id_to_raster_glyph_no.find(glyph_id) == glyph_id_to_raster_glyph_no.end() ) { // recheck + } else { + res=bases[glyph_id_to_raster_glyph_no[glyph_id]]; + } + } else { + res=bases[glyph_id_to_raster_glyph_no[glyph_id]]; + } + return res; +} +NR::Point raster_font::Advance(int glyph_id) +{ + if ( daddy == NULL ) return NR::Point(0,0); + double a=daddy->Advance(glyph_id,style.vertical); + NR::Point f_a=(style.vertical)?NR::Point(0,a):NR::Point(a,0); + return f_a*style.transform; +} +void raster_font::BBox(int glyph_id,NRRect *area) +{ + area->x0=area->y0=area->x1=area->y1=0; + if ( daddy == NULL ) return; + NR::Rect res=daddy->BBox(glyph_id); + NR::Point bmi=res.min(),bma=res.max(); + NR::Point tlp(bmi[0],bmi[1]),trp(bma[0],bmi[1]),blp(bmi[0],bma[1]),brp(bma[0],bma[1]); + tlp=tlp*style.transform; + trp=trp*style.transform; + blp=blp*style.transform; + brp=brp*style.transform; + res=NR::Rect(tlp,trp); + res.expandTo(blp); + res.expandTo(brp); + area->x0=(res.min())[0]; + area->y0=(res.min())[1]; + area->x1=(res.max())[0]; + area->y1=(res.max())[1]; +} + +void raster_font::LoadRasterGlyph(int glyph_id) +{ + raster_glyph *res=NULL; + if ( glyph_id_to_raster_glyph_no.find(glyph_id) == glyph_id_to_raster_glyph_no.end() ) { + res=new raster_glyph(); + res->daddy=this; + res->glyph_id=glyph_id; + if ( nbBase >= maxBase ) { + maxBase=2*nbBase+1; + bases=(raster_glyph**)realloc(bases,maxBase*sizeof(raster_glyph*)); + } + bases[nbBase]=res; + glyph_id_to_raster_glyph_no[glyph_id]=nbBase; + nbBase++; + } else { + res=bases[glyph_id_to_raster_glyph_no[glyph_id]]; + } + if ( res == NULL ) return; + if ( res->polygon ) return; + if ( res->outline == NULL ) { + if ( daddy == NULL ) return; + Path* outline=daddy->Outline(glyph_id,NULL); + res->outline=new Path; + if ( outline ) { + res->outline->Copy(outline); + } + res->outline->Transform(style.transform); + } + Shape* temp=new Shape; + res->polygon=new Shape; + style.Apply(res->outline,temp); + if ( style.stroke_width > 0 ) { + res->polygon->ConvertToShape(temp,fill_nonZero); + } else { + res->polygon->ConvertToShape(temp,fill_oddEven); + } + delete temp; + + res->SetSubPixelPositionning(4); +} +void raster_font::RemoveRasterGlyph(raster_glyph* who) +{ + if ( who == NULL ) return; + int glyph_id=who->glyph_id; + if ( glyph_id_to_raster_glyph_no.find(glyph_id) == glyph_id_to_raster_glyph_no.end() ) { + int no=glyph_id_to_raster_glyph_no[glyph_id]; + if ( no >= nbBase-1 ) { + } else { + bases[no]=bases[--nbBase]; + glyph_id_to_raster_glyph_no[bases[no]->glyph_id]=no; + } + glyph_id_to_raster_glyph_no.erase(glyph_id_to_raster_glyph_no.find(glyph_id)); + } else { + // not here + } +} + +/*int top,bottom; // baseline is y=0 + int* run_on_line; // array of size (bottom-top+1): run_on_line[i] gives the number of runs on line top+i + int nbRun; + float_ligne_run* runs;*/ + +raster_position::raster_position(void) +{ + top=0; + bottom=-1; + run_on_line=NULL; + nbRun=0; + runs=NULL; +} +raster_position::~raster_position(void) +{ + if ( run_on_line ) free(run_on_line); + if ( runs ) free(runs); +} + +void raster_position::AppendRuns(std::vector const &r,int y) +{ + if ( top > bottom ) { + top=bottom=y; + if ( run_on_line ) free(run_on_line); + run_on_line=(int*)malloc(sizeof(int)); + run_on_line[0]=0; + } else { + if ( y < top ) { + // printf("wtf?\n"); + return; + } else if ( y > bottom ) { + int ob=bottom; + bottom=y; + run_on_line=(int*)realloc(run_on_line,(bottom-top+1)*sizeof(int)); + for (int i=ob+1;i<=bottom;i++) run_on_line[i-top]=0; + } + } + + if ( r.empty() == false) { + run_on_line[y - top] = r.size(); + runs = (float_ligne_run *) realloc(runs, (nbRun + r.size()) * sizeof(float_ligne_run)); + + for (int i = 0; i < int(r.size()); i++) { + runs[nbRun + i] = r[i]; + } + + nbRun += r.size(); + } +} +void raster_position::Blit(float ph,int pv,NRPixBlock &over) +{ + int base_y=top+pv; + int first_y=top+pv,last_y=bottom+pv; + if ( first_y < over.area.y0 ) first_y=over.area.y0; + if ( last_y >= over.area.y1 ) last_y=over.area.y1-1; + if ( first_y > last_y ) return; + IntLigne *theIL=new IntLigne(); + FloatLigne *theI=new FloatLigne(); + + char* mdata=(char*)over.data.px; + if ( over.size == NR_PIXBLOCK_SIZE_TINY ) mdata=(char*)over.data.p; + + for (int y=first_y;y<=last_y;y++) { + int first_r=0,last_r=0; + for (int i=base_y;iReset(); + for (int i=first_r;i<=last_r;i++) theI->AddRun(runs[i].st+ph,runs[i].en+ph,runs[i].vst,runs[i].ven,runs[i].pente); +// for (int i=first_r;i<=last_r;i++) {runs[i].st+=ph;runs[i].en+=ph;} +// theI->nbRun=theI->maxRun=last_r-first_r+1; +// theI->runs=runs+first_r; + + theIL->Copy(theI); + raster_info dest; + dest.startPix=over.area.x0; + dest.endPix=over.area.x1; + dest.sth=over.area.x0; + dest.stv=y; + dest.buffer=((uint32_t*)(mdata+(over.rs*(y-over.area.y0)))); + theIL->Raster(dest,NULL,glyph_run_A8_OR); + +// theI->nbRun=theI->maxRun=0; +// theI->runs=NULL; +// for (int i=first_r;i<=last_r;i++) {runs[i].st-=ph;runs[i].en-=ph;} + } + } + delete theIL; + delete theI; +} + + +/* raster_font* daddy; + int glyph_id; + + Path* outline; + Shape* polygon; + + int nb_sub_pixel; + raster_position* sub_pixel;*/ + +raster_glyph::raster_glyph(void) +{ + daddy=NULL; + glyph_id=0; + outline=NULL; + polygon=NULL; + nb_sub_pixel=0; + sub_pixel=NULL; +} +raster_glyph::~raster_glyph(void) +{ + if ( outline ) delete outline; + if ( polygon ) delete polygon; + if ( sub_pixel ) delete [] sub_pixel; +} + + +void raster_glyph::SetSubPixelPositionning(int nb_pos) +{ + nb_sub_pixel=nb_pos; + if ( nb_sub_pixel <= 0 ) nb_sub_pixel=0; + if ( sub_pixel ) delete [] sub_pixel; + sub_pixel=NULL; + if ( nb_sub_pixel > 0 ) { + sub_pixel=new raster_position[nb_pos]; + if ( polygon ) { + for (int i=0;i= nb_sub_pixel ) return; + if ( sub_pixel[no].top <= sub_pixel[no].bottom ) return; + if ( polygon == NULL ) { + if ( daddy == NULL ) return; + daddy->LoadRasterGlyph(glyph_id); + if ( polygon == NULL ) return; + } + + float sub_delta=((float)no)/((float)nb_sub_pixel); + + polygon->CalcBBox(); + + float l=polygon->leftX,r=polygon->rightX,t=polygon->topY,b=polygon->bottomY; + int il,ir,it,ib; + il=(int)floor(l); + ir=(int)ceil(r); + it=(int)floor(t); + ib=(int)ceil(b); + + // version par FloatLigne + int curPt; + float curY; + polygon->BeginQuickRaster(curY, curPt); + + FloatLigne* theI=new FloatLigne(); + + polygon->DirectQuickScan(curY,curPt,(float)(it-1)+sub_delta,true,1.0); + + for (int y=it-1;yReset(); + polygon->QuickScan(curY,curPt,((float)(y+1))+sub_delta,theI,1.0); + theI->Flatten(); + + sub_pixel[no].AppendRuns(theI->runs, y); + } + polygon->EndQuickRaster(); + delete theI; +} + +void raster_glyph::Blit(const NR::Point &at,NRPixBlock &over) +{ + if ( nb_sub_pixel <= 0 ) return; + int pv=(int)ceil(at[1]); + double dec=4*(ceil(at[1])-at[1]); + int no=(int)floor(dec); + sub_pixel[no].Blit(at[0],pv,over); +} + + + +static void +glyph_run_A8_OR (raster_info &dest,void */*data*/,int st,float vst,int en,float ven) +{ + if ( st >= en ) return; + if ( vst < 0 ) vst=0; + if ( vst > 1 ) vst=1; + if ( ven < 0 ) ven=0; + if ( ven > 1 ) ven=1; + float sv=vst; + float dv=ven-vst; + int len=en-st; + unsigned char* d=(unsigned char*)dest.buffer; + d+=(st-dest.startPix); + if ( fabs(dv) < 0.001 ) { + if ( vst > 0.999 ) { + /* Simple copy */ + while (len > 0) { + d[0] = 255; + d += 1; + len -= 1; + } + } else { + sv*=256; + unsigned int c0_24=(int)sv; + c0_24&=0xFF; + while (len > 0) { + unsigned int da; + /* Draw */ + da = 65025 - (255 - c0_24) * (255 - d[0]); + d[0] = (da + 127) / 255; + d += 1; + len -= 1; + } + } + } else { + if ( en <= st+1 ) { + sv=0.5*(vst+ven); + sv*=256; + unsigned int c0_24=(int)sv; + c0_24&=0xFF; + unsigned int da; + /* Draw */ + da = 65025 - (255 - c0_24) * (255 - d[0]); + d[0] = (da + 127) / 255; + } else { + dv/=len; + sv+=0.5*dv; // correction trapezoidale + sv*=16777216; + dv*=16777216; + int c0_24 = static_cast(CLAMP(sv, 0, 16777216)); + int s0_24 = static_cast(dv); + while (len > 0) { + unsigned int ca, da; + /* Draw */ + ca = c0_24 >> 16; + if ( ca > 255 ) ca=255; + da = 65025 - (255 - ca) * (255 - d[0]); + d[0] = (da + 127) / 255; + d += 1; + c0_24 += s0_24; + c0_24 = CLAMP (c0_24, 0, 16777216); + len -= 1; + } + } + } +} diff --git a/src/libnrtype/RasterFont.h b/src/libnrtype/RasterFont.h new file mode 100644 index 000000000..03665c69a --- /dev/null +++ b/src/libnrtype/RasterFont.h @@ -0,0 +1,66 @@ +/* + * RasterFont.h + * testICU + * + */ + +#ifndef my_raster_font +#define my_raster_font + +#include + +#include +#include +#include + +// one rasterfont is one way to draw a font on the screen +// the way it's drawn is stored in style +class raster_font { +public: + font_instance* daddy; + int refCount; + + font_style style; + + __gnu_cxx::hash_map glyph_id_to_raster_glyph_no; + // an array of glyphs in this rasterfont. + // it's a bit redundant with the one in the daddy font_instance, but these glyphs + // contains the real rasterization data + int nbBase,maxBase; + raster_glyph** bases; + + explicit raster_font(font_style const &fstyle); + ~raster_font(void); + + void Unref(void); + void Ref(void); + + // utility functions + NR::Point Advance(int glyph_id); + void BBox(int glyph_id,NRRect *area); + + // attempts to load a glyph and return a raster_glyph on which you can call Blit + raster_glyph* GetGlyph(int glyph_id); + // utility + void LoadRasterGlyph(int glyph_id); // refreshes outline/polygon if needed + void RemoveRasterGlyph(raster_glyph* who); + +private: + /* Disable the default copy constructor and operator=: they do the wrong thing for refCount. */ + raster_font(raster_font const &); + raster_font &operator=(raster_font const &); +}; + +#endif + + +/* + 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 : diff --git a/src/libnrtype/TextWrapper.cpp b/src/libnrtype/TextWrapper.cpp new file mode 100644 index 000000000..ce8797322 --- /dev/null +++ b/src/libnrtype/TextWrapper.cpp @@ -0,0 +1,937 @@ +/* + * TextWrapper.cpp + * testICU + * + */ + +#ifdef HAVE_CONFIG_H +# include +#endif +#include "TextWrapper.h" + +#include +#include "libnrtype/text-boundary.h" +#include "libnrtype/one-glyph.h" +#include "libnrtype/one-box.h" +#include "libnrtype/one-para.h" + +#include + +text_wrapper::text_wrapper(void) +{ + // voids everything + utf8_text = NULL; + uni32_text = NULL; + glyph_text = NULL; + utf8_length = 0; + uni32_length = 0; + glyph_length = 0; + utf8_codepoint = NULL; + uni32_codepoint = NULL; + default_font = NULL; + bounds = NULL; + nbBound = maxBound = 0; + boxes = NULL; + nbBox = maxBox = 0; + paras = NULL; + nbPara = maxPara = 0; + kern_x = kern_y = NULL; + last_addition = -1; + // inits the pangolayout with default params + font_factory *font_src = font_factory::Default(); + pLayout = pango_layout_new(font_src->fontContext); + pango_layout_set_single_paragraph_mode(pLayout, true); + pango_layout_set_width(pLayout, -1); +} +text_wrapper::~text_wrapper(void) +{ + // frees everything + //printf("delete\n"); + g_object_unref(pLayout); + if ( utf8_text ) free(utf8_text); + if ( uni32_text ) free(uni32_text); + if ( glyph_text ) free(glyph_text); + if ( utf8_codepoint ) free(utf8_codepoint); + if ( uni32_codepoint ) free(uni32_codepoint); + if ( default_font ) default_font->Unref(); + if ( boxes ) free(boxes); + if ( paras ) free(paras); + if ( kern_x ) free(kern_x); + if ( kern_y ) free(kern_y); + for (unsigned i = 0; i < nbBound; i++) { + switch ( bounds[i].type ) { + default: + break; + } + } + if ( bounds ) free(bounds); + default_font = NULL; + +} + +void text_wrapper::SetDefaultFont(font_instance *iFont) +{ + // refcounts the font for our internal uses + if ( iFont ) iFont->Ref(); + if ( default_font ) default_font->Unref(); + default_font = iFont; +} + +void text_wrapper::AppendUTF8(char const *text, int len) +{ + // appends text to what needs to be handled + if ( utf8_length <= 0 ) { + // a first check to prevent the text from containing a leading line return (which + // is probably a bug anyway) + if ( text[0] == '\n' || text[0] == '\r' ) { + /* fixme: Should the below be `0 <= len' ? The existing code looks wrong + * for the case that len==0. + * TODO: Document the meaning of the len parameter. */ + if ( len > 0 ) { + while ( len > 0 && ( *text == '\n' || *text == '\r' ) ) {text++; len--;} + } else { + while ( *text == '\n' || *text == '\r' ) text++; + } + } + } + if ( len == 0 || text == NULL || *text == 0 ) return; + g_return_if_fail(g_utf8_validate(text, len, NULL)); + + // compute the length + int const nlen = ( len < 0 + ? strlen(text) + : len ); + /* effic: Use g_utf8_validate's last param to do this. */ + + // prepare to store the additional text + /* effic: (Not an issue for the sole caller at the time of writing.) This implementation + takes quadratic time if the text is composed of n appends. Use a proper data structure. + STL vector would suffice. */ + utf8_text = (char*)realloc(utf8_text, (utf8_length + nlen + 1) * sizeof(char)); + uni32_codepoint = (int*)realloc(uni32_codepoint, (utf8_length + nlen + 1) * sizeof(int)); + + // copy the source text in the newly lengthened array + memcpy(utf8_text + utf8_length, text, nlen * sizeof(char)); + utf8_length += nlen; + utf8_text[utf8_length] = 0; + // remember where the text ended, before we recompute it, for the dx/dy we'll add after that (if any) + last_addition = uni32_length; + // free old uni32 structures (instead of incrementally putting the text) + if ( uni32_text ) free(uni32_text); + if ( utf8_codepoint ) free(utf8_codepoint); + uni32_text = NULL; + utf8_codepoint = NULL; + uni32_length = 0; + { + // recompute length of uni32 text + char *p = utf8_text; + while ( *p ) { + p = g_utf8_next_char(p); // since we validated the input text, we can use this 'fast' macro + uni32_length++; + } + } + // realloc the arrays + uni32_text = (gunichar*)malloc((uni32_length + 1) * sizeof(gunichar)); + utf8_codepoint = (int*)malloc((uni32_length + 1) * sizeof(int)); + { + // read the utf8 string and compute codepoints positions + char *p = utf8_text; + int i = 0; + int l_o = 0; + while ( *p ) { + // get the new codepoint + uni32_text[i] = g_utf8_get_char(p); + // compute the offset in the utf8_string + unsigned int n_o = (unsigned int)(p - utf8_text); + // record the codepoint's start + utf8_codepoint[i] = n_o; + // record the codepoint's correspondance in the utf8 string + for (unsigned int j = l_o; j < n_o; j++) uni32_codepoint[j] = i - 1; + // and move on + l_o = n_o; + p = g_utf8_next_char(p); + i++; + } + // the termination of the loop + for (int j = l_o; j < utf8_length; j++) uni32_codepoint[j] = uni32_length - 1; + uni32_codepoint[utf8_length] = uni32_length; + uni32_text[uni32_length] = 0; + utf8_codepoint[uni32_length] = utf8_length; + } + // if needed, fill the dx/dy arrays with 0 for the newly created part + // these will be filled by a KernXForLastAddition() right after this function + // note that the SVG spec doesn't require you to give a dx for each codepoint, + // so setting the dx to 0 is mandatory + if ( uni32_length > last_addition ) { + if ( kern_x ) { + kern_x = (double*)realloc(kern_x, (uni32_length + 1) * sizeof(double)); + for (int i = last_addition; i <= uni32_length; i++) kern_x[i] = 0; + } + if ( kern_y ) { + kern_y = (double*)realloc(kern_y, (uni32_length + 1) * sizeof(double)); + for (int i = last_addition; i <= uni32_length; i++) kern_y[i] = 0; + } + } +} + +void text_wrapper::DoLayout(void) +{ + // THE function + // first some sanity checks + if ( default_font == NULL ) return; + if ( uni32_length <= 0 || utf8_length <= 0 ) return; + // prepare the pangolayout object + { + //char *tc = pango_font_description_to_string(default_font->descr); + //printf("layout with %s\n", tc); + //free(tc); + } + pango_layout_set_font_description(pLayout, default_font->descr); + pango_layout_set_text(pLayout, utf8_text, utf8_length); + // reset the glyph string + if ( glyph_text ) free(glyph_text); + glyph_text = NULL; + glyph_length = 0; + + double pango_to_ink = (1.0 / ((double)PANGO_SCALE)); // utility + int max_g = 0; + PangoLayoutIter *pIter = pango_layout_get_iter(pLayout); // and go! + do { + PangoLayoutLine *pLine = pango_layout_iter_get_line(pIter); // no need for unref + int plOffset = pLine->start_index; // start of the line in the uni32_text + PangoRectangle ink_r, log_r; + pango_layout_iter_get_line_extents(pIter, &ink_r, &log_r); + double plY = (1.0 / ((double)PANGO_SCALE)) * ((double)log_r.y); // start position of this line of the layout + double plX = (1.0 / ((double)PANGO_SCALE)) * ((double)log_r.x); + GSList *curR = pLine->runs; // get ready to iterate over the runs of this line + while ( curR ) { + PangoLayoutRun *pRun = (PangoLayoutRun*)curR->data; + int prOffset = pRun->item->offset; // start of the run in the line + if ( pRun ) { + // a run has uniform font/directionality/etc... + int o_g_l = glyph_length; // save the index of the first glyph we'll add + for (int i = 0; i < pRun->glyphs->num_glyphs; i++) { // add glyph sequentially, reading them from the run + // realloc the structures + if ( glyph_length >= max_g ) { + max_g = 2 * glyph_length + 1; + glyph_text = (one_glyph*)realloc(glyph_text, (max_g + 1) * sizeof(one_glyph)); + } + // fill the glyph info + glyph_text[glyph_length].font = pRun->item->analysis.font; + glyph_text[glyph_length].gl = pRun->glyphs->glyphs[i].glyph; + glyph_text[glyph_length].uni_st = plOffset + prOffset + pRun->glyphs->log_clusters[i]; + // depending on the directionality, the last uni32 codepoint for this glyph is the first of the next char + // or the first of the previous + if ( pRun->item->analysis.level == 1 ) { + // rtl + if ( i < pRun->glyphs->num_glyphs - 1 ) { + glyph_text[glyph_length + 1].uni_en = glyph_text[glyph_length].uni_st; + } + glyph_text[glyph_length].uni_dir = 1; + glyph_text[glyph_length + 1].uni_dir = 1; // set the directionality for the next too, so that the last glyph in + // the array has the correct direction + } else { + // ltr + if ( i > 0 ) { + glyph_text[glyph_length - 1].uni_en = glyph_text[glyph_length].uni_st; + } + glyph_text[glyph_length].uni_dir = 0; + glyph_text[glyph_length + 1].uni_dir = 0; + } + // set the position + // the layout is an infinite line + glyph_text[glyph_length].x = plX + pango_to_ink * ((double)pRun->glyphs->glyphs[i].geometry.x_offset); + glyph_text[glyph_length].y = plY + pango_to_ink * ((double)pRun->glyphs->glyphs[i].geometry.y_offset); + // advance to the next glyph + plX += pango_to_ink * ((double)pRun->glyphs->glyphs[i].geometry.width); + // and set the next glyph's position, in case it's the terminating glyph + glyph_text[glyph_length + 1].x = plX; + glyph_text[glyph_length + 1].y = plY; + glyph_length++; + } + // and finish filling the info + // notably, the uni_en of the last char in ltr text and the uni_en of the first in rtl are still not set + if ( pRun->item->analysis.level == 1 ) { + // rtl + if ( glyph_length > o_g_l ) glyph_text[o_g_l].uni_en = plOffset + prOffset + pRun->item->length; + } else { + if ( glyph_length > 0 ) glyph_text[glyph_length - 1].uni_en = plOffset + prOffset + pRun->item->length; + } + // the terminating glyph has glyph_id=0 because it means 'no glyph' + glyph_text[glyph_length].gl = 0; + // and is associated with no text (but you cannot set uni_st=uni_en=0, because the termination + // is expected to be the glyph for the termination of the uni32_text) + glyph_text[glyph_length].uni_st = glyph_text[glyph_length].uni_en = plOffset + prOffset + pRun->item->length; + } + curR = curR->next; + } + } while ( pango_layout_iter_next_line(pIter) ); + pango_layout_iter_free(pIter); + + // grunt work done. now some additional info for layout: computing letters, mostly (one letter = several glyphs sometimes) + PangoLogAttr *pAttrs = NULL; + int nbAttr = 0; + // get the layout attrs, they hold the boundaries pango computed + pango_layout_get_log_attrs(pLayout, &pAttrs, &nbAttr); + // feed to MakeTextBoundaries which knows what to do with these + MakeTextBoundaries(pAttrs, nbAttr); + // the array of boundaries is full, but out-of-order + SortBoundaries(); + // boundary array is ready to be used, call chunktext to fill the *_start fields of the glyphs, and compute + // the boxed version of the text for sp-typeset + ChunkText(); + // get rid of the attributes + if ( pAttrs ) g_free(pAttrs); + + // cleaning up + for (int i = 0; i < glyph_length; i++) { + glyph_text[i].uni_st = uni32_codepoint[glyph_text[i].uni_st]; + glyph_text[i].uni_en = uni32_codepoint[glyph_text[i].uni_en]; + glyph_text[i].x /= 512; // why is this not default_font->daddy->fontsize? + glyph_text[i].y /= 512; + } + if ( glyph_length > 0 ) { + glyph_text[glyph_length].x /= 512; + glyph_text[glyph_length].y /= 512; + } +} + +void text_wrapper::ChunkText(void) +{ + int c_st = -1, c_en = -1; + for (int i = 0; i < glyph_length; i++) { + int g_st = glyph_text[i].uni_st, g_en = glyph_text[i].uni_en; + glyph_text[i].char_start = false; + glyph_text[i].word_start = false; + glyph_text[i].para_start = false; + // boundaries depend on the directionality + // letter boundaries correspond to the glyphs starting one letter when you read them left to right (always) + // because that's the order they are stored into in the glyph_text array + if ( glyph_text[i].uni_dir == 0 ) { + if ( IsBound(bnd_char, g_st, c_st) ) { // check if there is a charcater (=letter in pango speak) at this position + // can be a 'start' boundary or a 'end' boundary, doesn't matter, as long + // as you get from one letter to the next at this position + if ( g_st == bounds[c_st].uni_pos ) glyph_text[i].char_start = true; + } + if ( IsBound(bnd_word, g_st, c_st) ) { + if ( g_st == bounds[c_st].uni_pos ) glyph_text[i].word_start = true; + } + if ( IsBound(bnd_para, g_st, c_st) ) { + if ( g_st == bounds[c_st].uni_pos ) glyph_text[i].para_start = true; + } + } else { + if ( IsBound(bnd_char, g_en, c_en) ) { + if ( g_en == bounds[c_en].uni_pos ) glyph_text[i].char_start = true; + } + if ( IsBound(bnd_word, g_en, c_en) ) { + if ( g_en == bounds[c_en].uni_pos ) glyph_text[i].word_start = true; + } + if ( IsBound(bnd_para, g_en, c_en) ) { + if ( g_en == bounds[c_en].uni_pos ) glyph_text[i].para_start = true; + } + } + } + + if ( glyph_length > 0 ) { + glyph_text[glyph_length].char_start = true; + glyph_text[glyph_length].word_start = true; + glyph_text[glyph_length].para_start = true; + } + { + // doing little boxes + int g_st = -1, g_en = -1; + while ( NextWord(g_st, g_en) ) { + // check uniformity of fonts + if ( g_st < g_en ) { + int n_st = g_st; + int n_en = g_st; + bool first = true; + do { + n_st = n_en; + PangoFont *curPF = glyph_text[n_st].font; + do { + n_en++; + } while ( n_en < g_en && glyph_text[n_en].font == curPF ); + if ( nbBox >= maxBox ) { + maxBox = 2 * nbBox + 1; + boxes = (one_box*)realloc(boxes, maxBox * sizeof(one_box)); + } + boxes[nbBox].g_st = n_st; + boxes[nbBox].g_en = n_en; + boxes[nbBox].word_start = first; + boxes[nbBox].word_end = (n_en >= g_en); + nbBox++; + first = false; + } while ( n_en < g_en ); + } + } + } + { + // doing little paras + int g_st = -1, g_en = -1; + while ( NextPara(g_st, g_en) ) { + int b_st = 0; + while ( b_st < nbBox && boxes[b_st].g_st < g_st ) b_st++; + if ( b_st < nbBox && boxes[b_st].g_st == g_st ) { + int b_en = b_st; + while ( b_en < nbBox && boxes[b_en].g_en < g_en ) b_en++; + if ( b_en < nbBox && boxes[b_en].g_en == g_en ) { + if ( nbPara >= maxPara ) { + maxPara = 2 * nbPara + 1; + paras = (one_para*)realloc(paras, maxPara * sizeof(one_para)); + } + paras[nbPara].b_st = b_st; + paras[nbPara].b_en = b_en; + nbPara++; + } + } + } + } +} + +void text_wrapper::MakeVertical(void) +{ + if ( glyph_length <= 0 ) return; + font_factory *font_src = font_factory::Default(); + + // explanation: when laying out text vertically, you must keep the glyphs of a single letter together + double baseY = glyph_text[0].y; + double lastY = baseY; + int g_st = 0, g_en = 0; + int nbLetter = 0; + PangoFont *curPF = NULL; + font_instance *curF = NULL; + do { + // move to the next letter boundary + g_st = g_en; + do { + g_en++; + } while ( g_en < glyph_length && glyph_text[g_en].char_start == false ); + // got a letter + if ( g_st < g_en && g_en <= glyph_length ) { + // we need to compute the letter's width (in case sometimes we implement the flushleft and flushright) + // and the total height for this letter. for example accents usually have 0 width, so this is not + // stupid + double n_adv = 0; + double minX = glyph_text[g_st].x, maxX = glyph_text[g_st].x; + for (int i = g_st; i < g_en; i++) { + if ( glyph_text[i].font != curPF ) { // font is not the same as the one of the previous glyph + // so we need to update curF + if ( curF ) curF->Unref(); + curF = NULL; + curPF = glyph_text[i].font; + if ( curPF ) { + PangoFontDescription *pfd = pango_font_describe(curPF); + curF = font_src->Face(pfd); + pango_font_description_free(pfd); + } + } + double x = ( curF + ? curF->Advance(glyph_text[i].gl, true) + : 0 ); + if ( x > n_adv ) n_adv = x; + if ( glyph_text[i].x < minX ) minX = glyph_text[i].x; + if ( glyph_text[i].x > maxX ) maxX = glyph_text[i].x; + } + lastY += n_adv; + // and put the glyphs of this letter at their new position + for (int i = g_st; i < g_en; i++) { + glyph_text[i].x -= minX; + glyph_text[i].y += lastY; + } + g_st = g_en; + } + nbLetter++; + } while ( g_st < glyph_length ); + if ( curF ) curF->Unref(); +} + +void text_wrapper::MergeWhiteSpace(void) +{ + if ( glyph_length <= 0 ) return; + // scans the glyphs and shifts them accordingly + double delta_x = 0, delta_y = 0; + bool inWhite = true; + int wpos = 0, rpos = 0; // wpos is the position where we read glyphs, rpos is the position where we write them back + // since we only eat whitespace, wpos <= rpos + for (rpos = 0; rpos < glyph_length; rpos++) { + // copy the glyph at its new position + glyph_text[wpos].gl = glyph_text[rpos].gl; + glyph_text[wpos].uni_st = glyph_text[rpos].uni_st; + glyph_text[wpos].uni_en = glyph_text[rpos].uni_en; + glyph_text[wpos].font = glyph_text[rpos].font; + glyph_text[wpos].x = glyph_text[rpos].x - delta_x; + glyph_text[wpos].y = glyph_text[rpos].y - delta_y; + wpos++; // move the write position + if ( g_unichar_isspace(uni32_text[glyph_text[rpos].uni_st]) ) { + if ( inWhite ) { + // eat me: 2 steps: first add the shift in position to the cumulated shift + delta_x += glyph_text[rpos + 1].x - glyph_text[rpos].x; + delta_y += glyph_text[rpos + 1].y - glyph_text[rpos].y; + // then move the write position back. this way, we'll overwrite the previous whitespace with the new glyph + // since this is only done after the first whitespace, we only keep the first whitespace + wpos--; + } + inWhite = true; + } else { + inWhite = false; + } + } + // and the terminating glyph (we should probably copy the rest of the glyph's info, too) + glyph_text[wpos].x = glyph_text[rpos].x - delta_x; + glyph_text[wpos].y = glyph_text[rpos].y - delta_y; + // sets the new length + glyph_length = wpos; +} + +// utility: computes the number of letters in the layout +int text_wrapper::NbLetter(int g_st, int g_en) +{ + if ( glyph_length <= 0 ) return 0; + if ( g_st < 0 || g_st >= g_en ) { + g_st = 0; + g_en = glyph_length; + } + int nbLetter = 0; + for (int i = g_st; i < g_en; i++) { + if ( glyph_text[i].char_start ) nbLetter++; + } + return nbLetter; +} + +void text_wrapper::AddLetterSpacing(double dx, double dy, int g_st, int g_en) +{ + if ( glyph_length <= 0 ) return; + if ( g_st < 0 || g_st >= g_en ) { + g_st = 0; + g_en = glyph_length; + } + int nbLetter = 0; + + // letterspacing means: add 'dx * (nbLetter - 1)' to the x position + // so we just scan the glyph string + for (int i = g_st; i < g_en; i++) { + if ( i > g_st && glyph_text[i].char_start ) nbLetter++; + glyph_text[i].x += dx * nbLetter; + glyph_text[i].y += dy * nbLetter; + } + if ( glyph_text[g_en].char_start ) nbLetter++; + glyph_text[g_en].x += dx * nbLetter; + glyph_text[g_en].y += dy * nbLetter; +} + +/** @name Movement commands + * Miscellaneous functions for moving about glyphs. + * \a st and \en are start and end glyph indices. + * The three methods differ only in whether they look for .char_start, .word_start or .para_start. + * \return True iff a next character was found. (False iff we've already reached the end.) + */ +//@{ +bool text_wrapper::NextChar(int &st, int &en) const +{ + if ( st < 0 || en < 0 ) {st = 0; en = 0;} + if ( st >= en ) en = st; + if ( st >= glyph_length || en >= glyph_length ) return false; // finished + st = en; + do { + en++; + } while ( en < glyph_length && glyph_text[en].char_start == false ); + return true; +} +bool text_wrapper::NextWord(int &st, int &en) const +{ + if ( st < 0 || en < 0 ) {st = 0; en = 0;} + if ( st >= en ) en = st; + if ( st >= glyph_length || en >= glyph_length ) return false; // finished + st = en; + do { + en++; + } while ( en < glyph_length && glyph_text[en].word_start == false ); + return true; +} +bool text_wrapper::NextPara(int &st, int &en) const +{ + if ( st < 0 || en < 0 ) {st = 0; en = 0;} + if ( st >= en ) en = st; + if ( st >= glyph_length || en >= glyph_length ) return false; // finished + st = en; + do { + en++; + } while ( en < glyph_length && glyph_text[en].para_start == false ); + return true; +} +//@} + +// boundary handling +/** + * Append \a ib to our bounds array. + * \return The index of the new element. + */ +unsigned text_wrapper::AddBoundary(text_boundary const &ib) +{ + if ( nbBound >= maxBound ) { + maxBound = 2 * nbBound + 1; + bounds = (text_boundary*)realloc(bounds, maxBound * sizeof(text_boundary)); + } + unsigned const ix = nbBound++; + bounds[ix] = ib; + return ix; +} + +/** + * Add the start \& end boundaries \a is \& \a ie to bounds. + */ +void text_wrapper::AddTwinBoundaries(text_boundary const &is, text_boundary const &ie) +{ + unsigned const ns = AddBoundary(is); + unsigned const ne = AddBoundary(ie); + bounds[ns].start = true; + bounds[ns].other = ne; + bounds[ne].start = false; + bounds[ne].other = ns; +} + +static int CmpBound(void const *a, void const *b) { + text_boundary const &ta = *reinterpret_cast(a); + text_boundary const &tb = *reinterpret_cast(b); + if ( ta.uni_pos < tb.uni_pos ) return -1; + if ( ta.uni_pos > tb.uni_pos ) return 1; + /* TODO: I'd guess that for a given uni_pos it would be better for the end boundary to precede the start boundary. */ + if ( ta.start && !tb.start ) return -1; + if ( !ta.start && tb.start ) return 1; + return 0; +} +/** + * Sort this.bounds by b.uni_pos, updating the .other index values appropriately. + */ +void text_wrapper::SortBoundaries(void) +{ + /* effic: If this function (including descendents such as the qsort calll) ever takes + * non-negligible time, then we can fairly easily improve it by changing MakeBoundaries add in + * sorted order. It would just have to remember for itself the index of each start boundary + * for updating the .other fields appropriately. + * + * A simpler speedup is just to change qsort to std::sort, which can inline the comparison + * function. + */ + + /* The 'other' field needs to be updated after sorting by qsort, so we build the inverse + * permutation. */ + for (unsigned i = 0; i < nbBound; i++) { + bounds[i].old_ix = i; + } + qsort(bounds, nbBound, sizeof(text_boundary), CmpBound); + unsigned *const old2new = g_new(unsigned, nbBound); + for (unsigned new_ix = 0; new_ix < nbBound; new_ix++) { // compute inverse permutation + old2new[bounds[new_ix].old_ix] = new_ix; + } + for (unsigned i = 0; i < nbBound; i++) { // update 'other' + if ( bounds[i].other < nbBound ) { + bounds[i].other = old2new[bounds[i].other]; + } + } + g_free(old2new); +} +void text_wrapper::MakeTextBoundaries(PangoLogAttr *pAttrs, int nAttr) +{ + if ( pAttrs == NULL || nAttr <= 0 || uni32_length <= 0 ) return; + if ( nAttr > uni32_length + 1 ) nAttr = uni32_length + 1; + int last_c_st = -1; + int last_w_st = -1; + int last_s_st = -1; + int last_p_st = 0; + // reads the text and adds a pair of boundaries each time we encounter a stop + // last_* are used to keep track of the start of new text chunk + for (int i = 0; i <= nAttr; i++) { + text_boundary nbs; + text_boundary nbe; + nbs.uni_pos = i; + nbs.start = true; + nbe.uni_pos = i; + nbe.start = false; + // letters + if ( i == nAttr || pAttrs[i].is_cursor_position ) { + if ( last_c_st >= 0 ) { + nbs.type = nbe.type = bnd_char; + nbs.uni_pos = last_c_st; + nbe.uni_pos = i; + AddTwinBoundaries(nbs, nbe); + } + last_c_st = i; + } + // words + if ( i == nAttr || pAttrs[i].is_word_start ) { + if ( last_w_st >= 0 ) { + nbs.type = nbe.type = bnd_word; + nbs.uni_pos = last_w_st; + nbe.uni_pos = i; + nbs.data.i = nbe.data.i = ( pAttrs[last_w_st].is_white ? 1 : 0 ); + AddTwinBoundaries(nbs, nbe); + } + last_w_st = i; + } + if ( i < nAttr && pAttrs[i].is_word_end ) { + if ( last_w_st >= 0 ) { + nbs.type = nbe.type = bnd_word; + nbs.uni_pos = last_w_st; + nbe.uni_pos = i; + nbs.data.i = nbe.data.i = ( pAttrs[last_w_st].is_white ? 1 : 0 ); + AddTwinBoundaries(nbs, nbe); + } + last_w_st = i; + } + // sentences + if ( i == nAttr || pAttrs[i].is_sentence_boundary ) { + if ( last_s_st >= 0 ) { + nbs.type = nbe.type = bnd_sent; + nbs.uni_pos = last_s_st; + nbe.uni_pos = i; + AddTwinBoundaries(nbs, nbe); + } + last_s_st = i; + } + // paragraphs + if ( uni32_text[i] == '\n' || uni32_text[i] == '\r' || i == nAttr ) { // too simple to be true? + nbs.type = nbe.type = bnd_para; + nbs.uni_pos = last_p_st; + nbe.uni_pos = i + 1; + AddTwinBoundaries(nbs, nbe); + last_p_st = i + 1; + } + } +} + +bool text_wrapper::IsBound(BoundaryType const bnd_type, int g_st, int &c_st) +{ + if ( c_st < 0 ) c_st = 0; + int scan_dir = 0; + while ( unsigned(c_st) < nbBound ) { + if ( bounds[c_st].uni_pos == g_st && bounds[c_st].type == bnd_type ) { + return true; + } + if ( bounds[c_st].uni_pos < g_st ) { + if ( scan_dir < 0 ) break; + c_st++; + scan_dir = 1; + } else if ( bounds[c_st].uni_pos > g_st ) { + if ( scan_dir > 0 ) break; + c_st--; + scan_dir = -1; + } else { + // good pos, wrong type + while ( c_st > 0 && bounds[c_st].uni_pos == g_st ) { + c_st--; + } + if ( bounds[c_st].uni_pos < g_st ) c_st++; + while ( unsigned(c_st) < nbBound && bounds[c_st].uni_pos == g_st ) { + if ( bounds[c_st].type == bnd_type ) { + return true; + } + c_st++; + } + break; + } + } + return false; +} + +/* Unused. Retained only because I haven't asked cyreve (Richard Hughes) whether he intends ever + * to use it. You can probably safely remove it. */ +//bool text_wrapper::Contains(BoundaryType const bnd_type, int g_st, int g_en, int &c_st, int &c_en) +//{ +// if ( c_st < 0 ) c_st = 0; +// bool found = false; +// int scan_dir = 0; +// while ( unsigned(c_st) < nbBound ) { +// if ( bounds[c_st].type == bnd_type ) { +// if ( bounds[c_st].start ) { +// c_en = bounds[c_st].other; +// } else { +// } +// } +// if ( bounds[c_st].type == bnd_type && unsigned(c_en) == bounds[c_st].other ) { +// if ( g_st >= bounds[c_st].uni_pos && g_en <= bounds[c_en].uni_pos ) { +// // character found +// found = true; +// break; +// } +// } +// if ( bounds[c_st].uni_pos < g_st ) { +// if ( scan_dir < 0 ) break; +// c_st++; +// scan_dir = 1; +// } else if ( bounds[c_st].uni_pos > g_st ) { +// if ( scan_dir > 0 ) break; +// c_st--; +// scan_dir = -1; +// } else { +// // good pos, wrong type +// while ( c_st > 0 && bounds[c_st].uni_pos == g_st ) { +// c_st--; +// } +// if ( bounds[c_st].uni_pos < g_st ) c_st++; +// while ( unsigned(c_st) < nbBound && bounds[c_st].uni_pos == g_st ) { +// if ( bounds[c_st].type == bnd_type ) { +// if ( bounds[c_st].start ) { +// c_en = bounds[c_st].other; +// } else { +// } +// } +// if ( bounds[c_st].type == bnd_type && unsigned(c_en) == bounds[c_st].other ) { +// if ( g_st >= bounds[c_st].uni_pos && g_en <= bounds[c_en].uni_pos ) { +// // character found +// return true; +// } +// } +// c_st++; +// } +// +// break; +// } +// } +// return found; +//} + +void text_wrapper::MeasureBoxes(void) +{ + font_factory *f_src = font_factory::Default(); + for (int i = 0; i < nbBox; i++) { + boxes[i].ascent = 0; + boxes[i].descent = 0; + boxes[i].leading = 0; + boxes[i].width = 0; + + PangoFont *curPF = glyph_text[boxes[i].g_st].font; + if ( curPF ) { + PangoFontDescription *pfd = pango_font_describe(curPF); + font_instance *curF = f_src->Face(pfd); + if ( curF ) { + curF->FontMetrics(boxes[i].ascent, boxes[i].descent, boxes[i].leading); + curF->Unref(); + } + pango_font_description_free(pfd); + boxes[i].width = glyph_text[boxes[i].g_en].x - glyph_text[boxes[i].g_st].x; + } + } +} + + +void text_wrapper::KernXForLastAddition(double *i_kern_x, int i_len, double scale) +{ + if ( i_kern_x == NULL || i_len <= 0 || last_addition < 0 || last_addition >= uni32_length || uni32_length <= 0 ) return; + if ( kern_x == NULL ) { + kern_x = (double*)malloc((uni32_length + 1) * sizeof(double)); + for (int i = 0; i <= uni32_length; i++) kern_x[i] = 0; + } + int last_len = uni32_length - last_addition; + if ( i_len > last_len ) i_len = last_len; + for (int i = 0; i < i_len; i++) kern_x[last_addition + i] = i_kern_x[i] * scale; +} + +void text_wrapper::KernYForLastAddition(double *i_kern_y, int i_len, double scale) +{ + if ( i_kern_y == NULL || i_len <= 0 || last_addition < 0 || last_addition >= uni32_length || uni32_length <= 0 ) return; + if ( kern_y == NULL ) { + kern_y = (double*)malloc((uni32_length + 1) * sizeof(double)); + for (int i = 0; i <= uni32_length; i++) kern_y[i] = 0; + } + int last_len = uni32_length - last_addition; + if ( i_len > last_len ) i_len = last_len; + for (int i = 0; i < i_len; i++) kern_y[last_addition + i] = i_kern_y[i] * scale; +} + +void text_wrapper::KernXForLastAddition(GList *i_kern_x, double scale) +{ + if ( i_kern_x == NULL || last_addition < 0 || last_addition >= uni32_length || uni32_length <= 0 ) return; + if ( kern_x == NULL ) { + kern_x = (double*)malloc((uni32_length + 1) * sizeof(double)); + for (int i = 0; i <= uni32_length; i++) kern_x[i] = 0; + } + int last_len = uni32_length - last_addition; + GList *l = i_kern_x; + for (int i = 0; i < last_len && l && l->data; i++, l = l->next) { + kern_x[last_addition + i] = ((SVGLength *) l->data)->computed * scale; + } +} + +void text_wrapper::KernYForLastAddition(GList *i_kern_y, double scale) +{ + if ( i_kern_y == NULL || last_addition < 0 || last_addition >= uni32_length || uni32_length <= 0 ) return; + if ( kern_y == NULL ) { + kern_y = (double*)malloc((uni32_length + 1) * sizeof(double)); + for (int i = 0; i <= uni32_length; i++) kern_y[i] = 0; + } + int last_len = uni32_length - last_addition; + GList *l = i_kern_y; + for (int i = 0; i < last_len && l && l->data; i++, l = l->next) { + kern_y[last_addition + i] = ((SVGLength *) l->data)->computed * scale; + } +} + + +void text_wrapper::AddDxDy(void) +{ + if ( glyph_length <= 0 ) return; + if ( kern_x ) { + double sum = 0; + int l_pos = -1; + for (int i = 0; i < glyph_length; i++) { + int n_pos = glyph_text[i].uni_st; + if ( l_pos < n_pos ) { + for (int j = l_pos + 1; j <= n_pos; j++) sum += kern_x[j]; + } else if ( l_pos > n_pos ) { + for (int j = l_pos; j > n_pos; j--) sum -= kern_x[j]; + } + l_pos = n_pos; + + glyph_text[i].x += sum; + } + { + int n_pos = uni32_length; + if ( l_pos < n_pos ) { + for (int j = l_pos + 1; j <= n_pos; j++) sum += kern_x[j]; + } else if ( l_pos > n_pos ) { + for (int j = l_pos; j > n_pos; j--) sum -= kern_x[j]; + } + l_pos = n_pos; + glyph_text[glyph_length].x += sum; + } + } + if ( kern_y ) { + double sum = 0; + int l_pos = -1; + for (int i = 0; i < glyph_length; i++) { + int n_pos = glyph_text[i].uni_st; + if ( l_pos < n_pos ) { + for (int j = l_pos + 1; j <= n_pos; j++) sum += kern_y[j]; + } else if ( l_pos > n_pos ) { + for (int j = l_pos; j > n_pos; j--) sum -= kern_y[j]; + } + l_pos = n_pos; + + glyph_text[i].y += sum; + } + { + int n_pos = uni32_length; + if ( l_pos < n_pos ) { + for (int j = l_pos + 1; j <= n_pos; j++) sum += kern_y[j]; + } else if ( l_pos > n_pos ) { + for (int j = l_pos; j > n_pos; j--) sum -= kern_y[j]; + } + l_pos = n_pos; + glyph_text[glyph_length].y += sum; + } + } +} + + +/* + 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:textwidth=99 : diff --git a/src/libnrtype/TextWrapper.h b/src/libnrtype/TextWrapper.h new file mode 100644 index 000000000..188f04ee1 --- /dev/null +++ b/src/libnrtype/TextWrapper.h @@ -0,0 +1,139 @@ +/* + * TextWrapper.h + * testICU + * + */ + +#ifndef my_text_wrapper +#define my_text_wrapper + +#include +#include +#include + +#include + +#include +#include "libnrtype/boundary-type.h" + +// miscanellous but useful data for a given text: chunking into logical pieces +// pieces include sentence/word, needed for example for the word-spacing property, +// and more important stuff like letter (ie visual letters) + +struct text_boundary; +struct one_glyph; +struct one_box; +struct one_para; + +class text_wrapper { +public: + char *utf8_text; // source text + gunichar *uni32_text; // ucs4 text computed from utf8_text + one_glyph *glyph_text; // glyph string computed for uni32_text + + // maps between the 2 + // These should most definitely be size_t, not int. + // I am quite sure (but not bored enough to actually test it + // on a 500MHz machine with 256MB RAM ) that this will crash + // for text longer than 2GB on architectures where + // sizeof(size_t) != sizeof(int) + int utf8_length; // utf8_text length + int uni32_length; // uni32_text length + int glyph_length; /**< Number of glyph in the glyph_text array. + * The size of the array is (glyph_length+1) in fact; the last glyph is kind of a '0' char. */ + int *uni32_codepoint; // uni32_codepoint[i] is the index in uni32_text corresponding to utf8_text[i] + int *utf8_codepoint; // utf8_codepoint[i] is the index in utf8_text of the beginning of uni32_text[i] + + // layout + font_instance *default_font; // font set as the default font (would need at least one alternate per language) + PangoLayout *pLayout; // private structure + + // kerning additions + int last_addition; // index in uni32_text of the beginning of the text added by the last AppendUTF8 call + double *kern_x; // dx[i] is the dx for the ith unicode char + double *kern_y; + + // boundaries, in an array + unsigned nbBound, maxBound; + text_boundary *bounds; + + // text organization + int nbBox, maxBox; + one_box *boxes; + int nbPara, maxPara; + one_para *paras; + + text_wrapper(void); + ~text_wrapper(void); + + // filling the structure with input data + void SetDefaultFont(font_instance *iFont); + + /** + * Append the specified text to utf8_text and uni32_codepoint. + * + * Note: Despite the name, the current implementation is primarily suited for a single + * call to set the text, rather than repeated calls to AppendUTF8: the implementation is + * Omega(n) in the new total length of the string, rather than just in the length of the + * text being appended. This can probably be addressed fairly easily (see comments in + * code) if this is an issue for new callers. + * + * \pre text is valid UTF-8, or null. + * Formally: text==NULL || g_utf8_validate(text, len, NULL). + * + * \param len Our sole existing caller (widgets/font_selector.cpp) uses len=-1. N.B. The current + * implementation may be buggy for non-negative len, especially for len==0. + */ + void AppendUTF8(char const *text, int len); + + // adds dx or dy for the text added by the last AppendUTF8() call + void KernXForLastAddition(double *i_kern_x, int i_len, double scale = 1.0); + void KernYForLastAddition(double *i_kern_y, int i_len, double scale = 1.0); + void KernXForLastAddition(GList *i_kern_x, double scale = 1.0); + void KernYForLastAddition(GList *i_kern_y, double scale = 1.0); + // compute the layout and stuff + void DoLayout(void); + // semi-private: computes boundaries in the input text + void ChunkText(void); + // utility function to move to the next element + bool NextChar(int &st, int &en) const; + bool NextWord(int &st, int &en) const; + bool NextPara(int &st, int &en) const; + + // post-processing after the initial layout + // for the xml-space property: merges consecutive whitespace, and eats leading whitespace in the text + void MergeWhiteSpace(void); + // makes vertical 'x' and 'y' fields in the glyph_text based on the computed positions + void MakeVertical(void); + // as the names says... + void AddLetterSpacing(double dx, double dy, int g_st = -1, int g_en = -1); + // adds the kerning specified by the KernXForLastAddition call to the layout + void AddDxDy(void); + + // boundary handling +private: + unsigned AddBoundary(text_boundary const &ib); +public: + void AddTwinBoundaries(text_boundary const &is, text_boundary const &ie); + void SortBoundaries(void); + void MakeTextBoundaries(PangoLogAttr *pAttrs, int nAttr); + //bool Contains(BoundaryType type, int g_st, int g_en, int &c_st, int &c_en); + bool IsBound(BoundaryType type, int g_st, int &c_st); + + void MeasureBoxes(void); + int NbLetter(int g_st, int g_en); +}; + +#endif + + +/* + 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:textwidth=99 : diff --git a/src/libnrtype/boundary-type.h b/src/libnrtype/boundary-type.h new file mode 100644 index 000000000..7f8ecea90 --- /dev/null +++ b/src/libnrtype/boundary-type.h @@ -0,0 +1,31 @@ +#ifndef LIBNRTYPE_BOUNDARY_TYPE_H_INKSCAPE +#define LIBNRTYPE_BOUNDARY_TYPE_H_INKSCAPE + +/** \file Definition of the BoundaryType enum. */ + +/** + * The different kinds of semantic boundaries in text; or rather, + * the different things that may be delimited by a text_boundary. + */ +enum BoundaryType { + bnd_none = 0, + bnd_char, + bnd_word, + bnd_sent, /**< Sentence. Not currently used, and pango (1.8) does a bad job of determining + * sentence boundaries anyway. */ + bnd_para +}; + + +#endif /* !LIBNRTYPE_BOUNDARY_TYPE_H_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:textwidth=99 : diff --git a/src/libnrtype/font-glyph.h b/src/libnrtype/font-glyph.h new file mode 100644 index 000000000..c79888c12 --- /dev/null +++ b/src/libnrtype/font-glyph.h @@ -0,0 +1,29 @@ +#ifndef SEEN_LIBNRTYPE_FONT_GLYPH_H +#define SEEN_LIBNRTYPE_FONT_GLYPH_H + +#include +#include + +// the info for a glyph in a font. it's totally resolution- and fontsize-independent +struct font_glyph { + double h_advance, h_width; // width != advance because of kerning adjustements + double v_advance, v_width; + double bbox[4]; // bbox of the path (and the artbpath), not the bbox of the glyph + // as the fonts sometimes contain + Path* outline; // outline as a livarot Path + void* artbpath; // outline as a artbpath, for text->curve stuff (should be unified with livarot) +}; + + +#endif /* !SEEN_LIBNRTYPE_FONT_GLYPH_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 : diff --git a/src/libnrtype/font-instance.h b/src/libnrtype/font-instance.h new file mode 100644 index 000000000..5d57ff549 --- /dev/null +++ b/src/libnrtype/font-instance.h @@ -0,0 +1,121 @@ +#ifndef SEEN_LIBNRTYPE_FONT_INSTANCE_H +#define SEEN_LIBNRTYPE_FONT_INSTANCE_H + +#include +#include +#include +#include +#include "FontFactory.h" + +#include +#include +#include +#include + +// the font_instance are the template of several raster_font; they provide metrics and outlines +// that are drawn by the raster_font, so the raster_font needs info relative to the way the +// font need to be drawn. note that fontsize is a scale factor in the transform matrix +// of the style +// the various raster_font in use at a given time are held in a hash_map whose indices are the +// styles, hence the 2 following 'classes' +struct font_style_hash : public std::unary_function { + size_t operator()(font_style const &x) const; +}; + +struct font_style_equal : public std::binary_function { + bool operator()(font_style const &a, font_style const &b); +}; + +class font_instance { +public: + // hashmap to get the raster_font for a given style + __gnu_cxx::hash_map loadedStyles; + // the real source of the font + PangoFont* pFont; + // depending on the rendering backend, different temporary data + + // that's the font's fingerprint; this particular PangoFontDescription gives the entry at which this font_instance + // resides in the font_factory loadedFaces hash_map + PangoFontDescription* descr; + // refcount + int refCount; + // font_factory owning this font_instance + font_factory* daddy; + + // common glyph definitions for all the rasterfonts + __gnu_cxx::hash_map id_to_no; + int nbGlyph, maxGlyph; + font_glyph* glyphs; + + font_instance(void); + ~font_instance(void); + + void Ref(void); + void Unref(void); + + bool IsOutlineFont(void); // utility + void InstallFace(PangoFont* iFace); // utility; should reset the pFont field if loading failed + // in case the PangoFont is a bitmap font, for example. that way, the calling function + // will be able to check the validity of the font before installing it in loadedFaces + void InitTheFace(); + + int MapUnicodeChar(gunichar c); // calls the relevant unicode->glyph index function + void LoadGlyph(int glyph_id); // the main backend-dependent function + // loads the given glyph's info + + // nota: all coordinates returned by these functions are on a [0..1] scale; you need to multiply + // by the fontsize to get the real sizes + Path* Outline(int glyph_id, Path *copyInto=NULL); + // queries the outline of the glyph (in livarot Path form), and copies it into copyInto instead + // of allocating a new Path if copyInto != NULL + void* ArtBPath(int glyph_id); + // returns the artbpath for this glyph. no refcounting needed, it's deallocated when the + // font_instance dies + double Advance(int glyph_id, bool vertical); + // nominal advance of the font. + bool FontMetrics(double &ascent, double &descent, double &leading); + bool FontSlope(double &run, double &rise); + // for generating slanted cursors for oblique fonts + NR::Rect BBox(int glyph_id); + + // creates a rasterfont for the given style + raster_font* RasterFont(NR::Matrix const &trs, double stroke_width, + bool vertical = false, JoinType stroke_join = join_straight, + ButtType stroke_cap = butt_straight, float miter_limit = 4.0); + // the dashes array in iStyle is copied + raster_font* RasterFont(font_style const &iStyle); + // private use: tells the font_instance that the raster_font 'who' has died + void RemoveRasterFont(raster_font *who); + + // attribute queries + unsigned Name(gchar *str, unsigned size); + unsigned PSName(gchar *str, unsigned size); + unsigned Family(gchar *str, unsigned size); + unsigned Attribute(gchar const *key, gchar *str, unsigned size); + +private: + void FreeTheFace(); + +#ifdef USE_PANGO_WIN32 + HFONT theFace; +#else + FT_Face theFace; + // it's a pointer in fact; no worries to ref/unref it, pango does its magic + // as long as pFont is valid, theFace is too +#endif + +}; + + +#endif /* !SEEN_LIBNRTYPE_FONT_INSTANCE_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 : diff --git a/src/libnrtype/font-style-to-pos.cpp b/src/libnrtype/font-style-to-pos.cpp new file mode 100644 index 000000000..02f5ef37c --- /dev/null +++ b/src/libnrtype/font-style-to-pos.cpp @@ -0,0 +1,120 @@ +#include "font-style-to-pos.h" +#include + +/* 'lighter' and 'darker' have to be resolved earlier */ +/** +Given a style struct (CSS representation), sets the corresponding fields in a NRTypePosDef. + */ +NRTypePosDef +font_style_to_pos (SPStyle const &style) +{ + NRTypePosDef ret; + + switch (style.font_weight.computed) { + case SP_CSS_FONT_WEIGHT_100: + ret.weight = NR_POS_WEIGHT_CSS100; + break; + + case SP_CSS_FONT_WEIGHT_200: + ret.weight = NR_POS_WEIGHT_CSS200; + break; + + case SP_CSS_FONT_WEIGHT_300: + ret.weight = NR_POS_WEIGHT_CSS300; + break; + + case SP_CSS_FONT_WEIGHT_400: + case SP_CSS_FONT_WEIGHT_NORMAL: + ret.weight = NR_POS_WEIGHT_CSS400; + break; + + case SP_CSS_FONT_WEIGHT_500: + ret.weight = NR_POS_WEIGHT_CSS500; + break; + + case SP_CSS_FONT_WEIGHT_600: + ret.weight = NR_POS_WEIGHT_CSS600; + break; + + case SP_CSS_FONT_WEIGHT_700: + case SP_CSS_FONT_WEIGHT_BOLD: + ret.weight = NR_POS_WEIGHT_CSS700; + break; + + case SP_CSS_FONT_WEIGHT_800: + ret.weight = NR_POS_WEIGHT_CSS800; + break; + + case SP_CSS_FONT_WEIGHT_900: + ret.weight = NR_POS_WEIGHT_CSS900; + break; + + case SP_CSS_FONT_WEIGHT_LIGHTER: + case SP_CSS_FONT_WEIGHT_BOLDER: + default: + g_warning("Unrecognized font_weight.computed value"); + ret.weight = NR_POS_WEIGHT_NORMAL; + break; + } + + switch (style.font_style.computed) { + case SP_CSS_FONT_STYLE_ITALIC: + ret.italic = 1; + break; + + case SP_CSS_FONT_STYLE_OBLIQUE: + ret.oblique = 1; + break; + + case SP_CSS_FONT_STYLE_NORMAL: + default: + ret.italic = 0; + ret.oblique = 0; + break; + } + + switch (style.font_stretch.computed) { + case SP_CSS_FONT_STRETCH_ULTRA_CONDENSED: + case SP_CSS_FONT_STRETCH_EXTRA_CONDENSED: + ret.stretch = NR_POS_STRETCH_EXTRA_CONDENSED; + break; + + case SP_CSS_FONT_STRETCH_CONDENSED: + case SP_CSS_FONT_STRETCH_NARROWER: + ret.stretch = NR_POS_STRETCH_CONDENSED; + break; + + case SP_CSS_FONT_STRETCH_SEMI_CONDENSED: + ret.stretch = NR_POS_STRETCH_SEMI_CONDENSED; + break; + + case SP_CSS_FONT_STRETCH_SEMI_EXPANDED: + ret.stretch = NR_POS_STRETCH_SEMI_EXPANDED; + break; + + case SP_CSS_FONT_STRETCH_EXPANDED: + case SP_CSS_FONT_STRETCH_WIDER: + ret.stretch = NR_POS_STRETCH_EXPANDED; + break; + + case SP_CSS_FONT_STRETCH_EXTRA_EXPANDED: + case SP_CSS_FONT_STRETCH_ULTRA_EXPANDED: + ret.stretch = NR_POS_STRETCH_EXTRA_EXPANDED; + break; + + default: + ret.stretch = NR_POS_STRETCH_NORMAL; + break; + } + + switch (style.font_variant.computed) { + case SP_CSS_FONT_VARIANT_SMALL_CAPS: + ret.variant = NR_POS_VARIANT_SMALLCAPS; + break; + default: + ret.variant = NR_POS_VARIANT_NORMAL; + break; + } + + return ret; +} diff --git a/src/libnrtype/font-style-to-pos.h b/src/libnrtype/font-style-to-pos.h new file mode 100644 index 000000000..f58fdda3f --- /dev/null +++ b/src/libnrtype/font-style-to-pos.h @@ -0,0 +1,20 @@ +#ifndef __FONT_STYLE_TO_POS_H__ +#define __FONT_STYLE_TO_POS_H__ + +#include /* SPStyle */ +#include + +NRTypePosDef font_style_to_pos (SPStyle const &style); + +#endif /* __FONT_STYLE_TO_POS_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:encoding=utf-8:textwidth=99 : diff --git a/src/libnrtype/font-style.h b/src/libnrtype/font-style.h new file mode 100644 index 000000000..748d2020a --- /dev/null +++ b/src/libnrtype/font-style.h @@ -0,0 +1,38 @@ +#ifndef SEEN_LIBNRTYPE_FONT_STYLE_H +#define SEEN_LIBNRTYPE_FONT_STYLE_H + +#include +#include +#include + +// structure that holds data describing how to render glyphs of a font + +// Different raster styles. +struct font_style { + NR::Matrix transform; // the ctm. contains the font-size + bool vertical; // should be rendered vertically or not? + // good font support would take the glyph alternates for vertical mode, when present + double stroke_width; // if 0, the glyph is filled; otherwise stroked + JoinType stroke_join; + ButtType stroke_cap; + float stroke_miter_limit; + int nbDash; + double dash_offset; + double* dashes; + + void Apply(Path *src, Shape *dst); // utility: applies the style to the path and stores the result in the shape +}; + + +#endif /* !SEEN_LIBNRTYPE_FONT_STYLE_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 : diff --git a/src/libnrtype/libnrtype.def b/src/libnrtype/libnrtype.def new file mode 100644 index 000000000..34051de2d --- /dev/null +++ b/src/libnrtype/libnrtype.def @@ -0,0 +1,59 @@ +EXPORTS + nr_font_generic_free + nr_font_generic_glyph_advance_get + nr_font_generic_glyph_area_get + nr_font_generic_glyph_outline_get + nr_font_generic_glyph_outline_unref + nr_font_generic_new + nr_font_generic_rasterfont_free + nr_font_generic_rasterfont_new + nr_font_glyph_advance_get + nr_font_glyph_area_get + nr_font_glyph_outline_get + nr_font_glyph_outline_unref + nr_font_new_default + nr_font_ref + nr_font_unref + nr_name_list_release + nr_rasterfont_generic_free + nr_rasterfont_generic_glyph_advance_get + nr_rasterfont_generic_glyph_area_get + nr_rasterfont_generic_glyph_mask_render + nr_rasterfont_generic_new + nr_rasterfont_glyph_advance_get + nr_rasterfont_glyph_area_get + nr_rasterfont_glyph_mask_render + nr_rasterfont_new + nr_rasterfont_ref + nr_rasterfont_unref + nr_type_dict_insert + nr_type_dict_lookup + nr_type_dict_new + nr_type_directory_family_list_get + nr_type_directory_forget_face + nr_type_directory_lookup + nr_type_directory_lookup_fuzzy + nr_type_directory_style_list_get + nr_type_empty_build_def + nr_type_ft2_build_def +; nr_type_gnome_build_def +; nr_type_gnome_families_get +; nr_type_gnome_typefaces_get + nr_type_w32_build_def + nr_type_w32_families_get + nr_type_w32_typefaces_get +; nr_type_xft_build_def +; nr_type_xft_families_get +; nr_type_xft_typefaces_get + nr_typeface_attribute_get + nr_typeface_family_name_get + nr_typeface_ft2_get_type + nr_typeface_get_type + nr_typeface_glyph_advance_get + nr_typeface_glyph_outline_get + nr_typeface_glyph_outline_unref +; nr_typeface_gnome_get_type + nr_typeface_lookup_default + nr_typeface_name_get + nr_typeface_new + nr_typeface_w32_get_type diff --git a/src/libnrtype/makefile.in b/src/libnrtype/makefile.in new file mode 100644 index 000000000..fbebd763d --- /dev/null +++ b/src/libnrtype/makefile.in @@ -0,0 +1,17 @@ +# Convenience stub makefile to call the real Makefile. + +@SET_MAKE@ + +# Explicit so that it's the default rule. +all: + cd .. && $(MAKE) libnrtype/all + +clean %.a %.o: + cd .. && $(MAKE) libnrtype/$@ + +.PHONY: all clean + +OBJEXT = @OBJEXT@ + +.SUFFIXES: +.SUFFIXES: .a .$(OBJEXT) diff --git a/src/libnrtype/nr-type-pos-def.cpp b/src/libnrtype/nr-type-pos-def.cpp new file mode 100644 index 000000000..fef04039e --- /dev/null +++ b/src/libnrtype/nr-type-pos-def.cpp @@ -0,0 +1,268 @@ +#include "nr-type-pos-def.h" +#include +#include + +/** + * Given a font name or style name, returns a constant describing its + * apparent style (normal/italic/oblique). +*/ +int +parse_name_for_style (char const *cc) +{ + g_assert ( cc != NULL ); + gchar *c = g_ascii_strdown (cc, -1); + + gint style; + // first dab at i18n... french and german + if (strstr (c, "italic") || strstr (c, "italique") || strstr (c, "kursiv")) { + style = NR_POS_STYLE_ITALIC; + } else if (strstr (c, "oblique")) { + style = NR_POS_STYLE_OBLIQUE; + } else { + style = NR_POS_STYLE_NORMAL; + } + + g_free (c); + return style; +} + + +/** + * Given a font name or style name, returns a constant describing its + * apparent weight. +*/ +int +parse_name_for_weight (char const *cc) +{ + g_assert ( cc != NULL ); + gchar *c = g_ascii_strdown (cc, -1); + + gint weight; + if (strstr (c, "thin")) { + weight = NR_POS_WEIGHT_THIN; + } else if (strstr (c, "extra light")) { + weight = NR_POS_WEIGHT_EXTRA_LIGHT; + } else if (strstr (c, "ultra light")) { + weight = NR_POS_WEIGHT_ULTRA_LIGHT; + } else if (strstr (c, "light")) { + weight = NR_POS_WEIGHT_LIGHT; + } else if (strstr (c, "book")) { + weight = NR_POS_WEIGHT_BOOK; + } else if (strstr (c, "medium")) { + weight = NR_POS_WEIGHT_MEDIUM; + } else if (strstr (c, "semi bold")) { + weight = NR_POS_WEIGHT_SEMIBOLD; + } else if (strstr (c, "semibold")) { + weight = NR_POS_WEIGHT_SEMIBOLD; + } else if (strstr (c, "demi bold")) { + weight = NR_POS_WEIGHT_DEMIBOLD; + } else if (strstr (c, "demibold") || strstr (c, "demi")) { + weight = NR_POS_WEIGHT_DEMIBOLD; + } else if (strstr (c, "ultra bold")) { + weight = NR_POS_WEIGHT_ULTRA_BOLD; + } else if (strstr (c, "extra bold") || strstr (c, "xbold") || strstr (c, "xtrabold")) { + weight = NR_POS_WEIGHT_EXTRA_BOLD; + } else if (strstr (c, "black") || strstr (c, "heavy")) { + weight = NR_POS_WEIGHT_BLACK; + } else if (strstr (c, "bold")) { + /* Must come after the checks for `blah bold'. */ + weight = NR_POS_WEIGHT_BOLD; + } else { + weight = NR_POS_WEIGHT_NORMAL; + } + + g_free (c); + return weight; +} + +/** + * Given a font name or style name, returns a constant describing its + * apparent stretch. +*/ +int +parse_name_for_stretch (char const *cc) +{ + g_assert ( cc != NULL ); + gchar *c = g_ascii_strdown (cc, -1); + + gint stretch; + if (strstr (c, "ultra narrow") || strstr (c, "ultra condensed") || strstr (c, "extra condensed")) { + stretch = NR_POS_STRETCH_EXTRA_CONDENSED; + } else if (strstr (c, "ultra wide") || strstr (c, "ultra expanded") || strstr (c, "ultra extended") || strstr (c, "extra expanded")) { + stretch = NR_POS_STRETCH_EXTRA_EXPANDED; + } else if (strstr (c, "semi condensed") || strstr (c, "semicondensed")) { + stretch = NR_POS_STRETCH_SEMI_CONDENSED; + } else if (strstr (c, "semi extended") || strstr (c, "semiextended")) { + stretch = NR_POS_STRETCH_SEMI_EXPANDED; + } else if (strstr (c, "narrow") || strstr (c, "condensed")) { + stretch = NR_POS_STRETCH_CONDENSED; + } else if (strstr (c, "wide") || strstr (c, "expanded") || strstr (c, "extended")) { + stretch = NR_POS_STRETCH_EXPANDED; + } else { + stretch = NR_POS_STRETCH_NORMAL; + } + + g_free (c); + return stretch; +} + +/** + * Given a font name or style name, returns a constant describing its + * apparent variant (normal/smallcaps). +*/ +int +parse_name_for_variant (char const *cc) +{ + g_assert ( cc != NULL ); + gchar *c = g_ascii_strdown (cc, -1); + + gint variant; + if (strstr (c, "small caps") || strstr (c, "smallcaps") || strstr (c, "caps")) { + variant = NR_POS_VARIANT_SMALLCAPS; + } else { + variant = NR_POS_VARIANT_NORMAL; + } + + g_free (c); + return variant; +} + +/** + * Given a style constant, returns the CSS value for font-style. +*/ +const char * +style_to_css (int style) +{ + switch (style) { + case NR_POS_STYLE_NORMAL: + return "normal"; + break; + case NR_POS_STYLE_ITALIC: + return "italic"; + break; + case NR_POS_STYLE_OBLIQUE: + return "oblique"; + break; + default: + break; + } + return NULL; +} + + +/** + * Given a weight constant, returns the CSS value for font-weight. +*/ +const char * +weight_to_css (int weight) +{ + switch (weight) { + case NR_POS_WEIGHT_THIN: + return "100"; + break; + case NR_POS_WEIGHT_EXTRA_LIGHT: + return "200"; + break; + case NR_POS_WEIGHT_LIGHT: + return "300"; + break; + case NR_POS_WEIGHT_BOOK: + return "normal"; + break; + case NR_POS_WEIGHT_MEDIUM: + return "500"; + break; + case NR_POS_WEIGHT_SEMIBOLD: + return "600"; + break; + case NR_POS_WEIGHT_BOLD: + return "bold"; + break; + case NR_POS_WEIGHT_EXTRA_BOLD: + return "800"; + break; + case NR_POS_WEIGHT_BLACK: + return "900"; + break; + default: + break; + } + return NULL; +} + +/** + * Given a stretch constant, returns the CSS value for font-stretch. +*/ +const char * +stretch_to_css (int stretch) +{ + switch (stretch) { + case NR_POS_STRETCH_EXTRA_CONDENSED: + return "extra-condensed"; + break; + case NR_POS_STRETCH_CONDENSED: + return "condensed"; + break; + case NR_POS_STRETCH_SEMI_CONDENSED: + return "semi-condensed"; + break; + case NR_POS_STRETCH_NORMAL: + return "normal"; + break; + case NR_POS_STRETCH_SEMI_EXPANDED: + return "semi-expanded"; + break; + case NR_POS_STRETCH_EXPANDED: + return "expanded"; + break; + case NR_POS_STRETCH_EXTRA_EXPANDED: + return "extra-expanded"; + break; + default: + break; + } + return NULL; +} + +/** + * Given a variant constant, returns the CSS value for font-variant. +*/ +const char * +variant_to_css (int stretch) +{ + switch (stretch) { + case NR_POS_VARIANT_SMALLCAPS: + return "small-caps"; + break; + case NR_POS_VARIANT_NORMAL: + return "normal"; + break; + default: + break; + } + return NULL; +} + + +/** + * Constructor for NRTypePostDef. Sets the italic, oblique, weight, + * stretch, and variant. + */ +NRTypePosDef::NRTypePosDef(char const *description) { + // we cannot use strcasestr, it's linux only... so we must lowercase the string first + g_assert ( description != NULL ); + gchar *c = g_ascii_strdown (description, -1); + + /* copied from nr-type-directory.cpp:nr_type_calculate_position. */ + + italic = (strstr (c, "italic") != NULL); + oblique = (strstr (c, "oblique") != NULL); + + weight = parse_name_for_weight (c); + + stretch = parse_name_for_stretch (c); + + variant = parse_name_for_variant (c); + + g_free (c); +} diff --git a/src/libnrtype/nr-type-pos-def.h b/src/libnrtype/nr-type-pos-def.h new file mode 100644 index 000000000..ab9f5b45c --- /dev/null +++ b/src/libnrtype/nr-type-pos-def.h @@ -0,0 +1,102 @@ +#ifndef __NR_TYPE_POS_DEF_H__ +#define __NR_TYPE_POS_DEF_H__ + +#define NR_POS_STYLE_NORMAL 0 +#define NR_POS_STYLE_ITALIC 1 +#define NR_POS_STYLE_OBLIQUE 2 + +#define NR_POS_WEIGHT_THIN 32 +#define NR_POS_WEIGHT_EXTRA_LIGHT 64 +#define NR_POS_WEIGHT_ULTRA_LIGHT 64 +#define NR_POS_WEIGHT_LIGHT 96 +#define NR_POS_WEIGHT_BOOK 128 +#define NR_POS_WEIGHT_NORMAL 128 +#define NR_POS_WEIGHT_MEDIUM 144 +#define NR_POS_WEIGHT_SEMIBOLD 160 +#define NR_POS_WEIGHT_DEMIBOLD 160 +#define NR_POS_WEIGHT_BOLD 192 +#define NR_POS_WEIGHT_ULTRA_BOLD 224 +#define NR_POS_WEIGHT_EXTRA_BOLD 224 +#define NR_POS_WEIGHT_BLACK 255 + +#define NR_POS_STRETCH_ULTRA_CONDENSED 48 +#define NR_POS_STRETCH_EXTRA_CONDENSED 48 +#define NR_POS_STRETCH_CONDENSED 88 +#define NR_POS_STRETCH_SEMI_CONDENSED 108 +#define NR_POS_STRETCH_NORMAL 128 +#define NR_POS_STRETCH_SEMI_EXPANDED 148 +#define NR_POS_STRETCH_EXPANDED 168 +#define NR_POS_STRETCH_EXTRA_EXPANDED 228 +#define NR_POS_STRETCH_ULTRA_EXPANDED 228 + +// This is an enumerate, rather than on/off property, +// for I sincerely hope the vocabulary of this property will be +// extended by the W3C in the future to allow for more fancy fonts +#define NR_POS_VARIANT_NORMAL 0 +#define NR_POS_VARIANT_SMALLCAPS 1 + +/* Mapping from CSS weight numbers. + + for i in `seq 9`; do + if [ $i -le 4 ]; then w=$((32 * $i)); + elif [ $i = 5 ]; then w=144; + elif [ $i -lt 9 ]; then w=$((32 * $(($i - 1)))); + else w=255; + fi; + printf '#define NR_POS_WEIGHT_CSS%d00\t\t%3d\n' $i $w; + done + + This calculation approximately matches the old to-and-from-text code, + I don't claim it to be reasonable. ("approximately": some of the old + code wrote strings like "semi" and "heavy" that weren't being parsed + at the other end, and it had CSS100 darker than CSS200.) + */ +#define NR_POS_WEIGHT_CSS100 32 +#define NR_POS_WEIGHT_CSS200 64 +#define NR_POS_WEIGHT_CSS300 96 +#define NR_POS_WEIGHT_CSS400 128 +#define NR_POS_WEIGHT_CSS500 144 +#define NR_POS_WEIGHT_CSS600 160 +#define NR_POS_WEIGHT_CSS700 192 +#define NR_POS_WEIGHT_CSS800 224 +#define NR_POS_WEIGHT_CSS900 255 + + +class NRTypePosDef { +public: + unsigned int italic : 1; + unsigned int oblique : 1; + unsigned int weight : 8; + unsigned int stretch : 8; + unsigned int variant : 8; + /* These can probably be made sensible sizes rather than bitfields; for the moment we'll + keep the old definition. */ + +public: + NRTypePosDef() : + italic(0), + oblique(0), + weight(NR_POS_WEIGHT_NORMAL), + stretch(NR_POS_STRETCH_NORMAL), + variant(NR_POS_VARIANT_NORMAL) + { } + + NRTypePosDef(char const *description); + + bool signature() {return this->italic + + this->oblique * 255 + + this->weight * 255 * 255 + + this->stretch * 255 * 255 * 255 + + this->variant * 255 * 255 * 255 * 255;}; +}; + +int parse_name_for_style (char const *c); +int parse_name_for_weight (char const *c); +int parse_name_for_stretch (char const *c); +int parse_name_for_variant (char const *c); +const char *style_to_css (int style); +const char *weight_to_css (int weight); +const char *stretch_to_css (int stretch); +const char *variant_to_css (int variant); + +#endif /* __NR_TYPE_POS_DEF_H__ */ diff --git a/src/libnrtype/nr-type-primitives.cpp b/src/libnrtype/nr-type-primitives.cpp new file mode 100644 index 000000000..616134383 --- /dev/null +++ b/src/libnrtype/nr-type-primitives.cpp @@ -0,0 +1,167 @@ +#define __NR_TYPE_PRIMITIVES_C__ + +/* + * Typeface and script library + * + * Authors: + * Lauris Kaplinski + * + * This code is in public domain + */ + +/* This should be enough for approximately 10000 fonts */ +#define NR_DICTSIZE 2777 + +#include +#include +#include +#include "nr-type-primitives.h" + +/** + * An entry in a list of key->value pairs + */ +struct NRTDEntry { + NRTDEntry *next; + const gchar *key; + void *val; +}; + +/** + * Type Dictionary, consisting of size number of key-value entries + */ +struct NRTypeDict { + unsigned int size; + NRTDEntry **entries; +}; + +static NRTDEntry *nr_td_entry_new (void); + +/** + * Calls the destructor for each item in list + */ +void +nr_name_list_release (NRNameList *list) +{ + if (list->destructor) { + list->destructor (list); + } +} + +void +nr_style_list_release (NRStyleList *list) +{ + if (list->destructor) { + list->destructor (list); + } +} + +/** + * Creates a new typeface dictionary of size NR_DICTSIZE + * and initalizes all the entries to NULL + */ +NRTypeDict * +nr_type_dict_new (void) +{ + NRTypeDict *td; + int i; + + td = nr_new (NRTypeDict, 1); + + td->size = NR_DICTSIZE; + td->entries = nr_new (NRTDEntry *, td->size); + for (i = 0; i < NR_DICTSIZE; i++) { + td->entries[i] = NULL; + } + + return td; +} + +/** + * Hashes a string and returns the int + */ +static unsigned int +nr_str_hash (const gchar *p) +{ + unsigned int h; + + h = *p; + + if (h != 0) { + for (p += 1; *p; p++) h = (h << 5) - h + *p; + } + + return h; +} + +/** + * Inserts a key/value into a typeface dictionary + */ +void +nr_type_dict_insert (NRTypeDict *td, const gchar *key, void *val) +{ + if (key) { + NRTDEntry *tde; + unsigned int hval; + + hval = nr_str_hash (key) % td->size; + + for (tde = td->entries[hval]; tde; tde = tde->next) { + if (!strcmp (key, tde->key)) { + tde->val = val; + return; + } + } + + tde = nr_td_entry_new (); + tde->next = td->entries[hval]; + tde->key = key; + tde->val = val; + td->entries[hval] = tde; + } +} + +/** + * Looks up the given key from the typeface dictionary + */ +void * +nr_type_dict_lookup (NRTypeDict *td, const gchar *key) +{ + if (key) { + NRTDEntry *tde; + unsigned int hval; + hval = nr_str_hash (key) % td->size; + for (tde = td->entries[hval]; tde; tde = tde->next) { + if (!strcmp (key, tde->key)) return tde->val; + } + } + + return NULL; +} + +#define NR_TDE_BLOCK_SIZE 32 + +static NRTDEntry *nr_tde_free_list; + +/** + * Creates a new TDEntry + */ +static NRTDEntry * +nr_td_entry_new (void) +{ + NRTDEntry *tde; + + if (!nr_tde_free_list) { + int i; + nr_tde_free_list = nr_new (NRTDEntry, NR_TDE_BLOCK_SIZE); + for (i = 0; i < (NR_TDE_BLOCK_SIZE - 1); i++) { + nr_tde_free_list[i].next = nr_tde_free_list + i + 1; + } + nr_tde_free_list[i].next = NULL; + } + + tde = nr_tde_free_list; + nr_tde_free_list = tde->next; + + return tde; +} + diff --git a/src/libnrtype/nr-type-primitives.h b/src/libnrtype/nr-type-primitives.h new file mode 100644 index 000000000..9bb181c4b --- /dev/null +++ b/src/libnrtype/nr-type-primitives.h @@ -0,0 +1,50 @@ +#ifndef __NR_TYPE_PRIMITIVES_H__ +#define __NR_TYPE_PRIMITIVES_H__ + +/* + * Typeface and script library + * + * Authors: + * Lauris Kaplinski + * g++ port: Nathan Hurst + * + * This code is in public domain + */ + +#include + +struct NRNameList; +struct NRStyleList; +struct NRTypeDict; + +typedef void (* NRNameListDestructor) (NRNameList *list); +typedef void (* NRStyleListDestructor) (NRStyleList *list); + +struct NRNameList { + guint length; + guchar **names; + guchar **families; + NRNameListDestructor destructor; +}; + +struct NRStyleRecord { + const char *name; + const char *descr; +}; + +struct NRStyleList { + guint length; + NRStyleRecord *records; + NRStyleListDestructor destructor; +}; + +void nr_name_list_release (NRNameList *list); +void nr_style_list_release (NRStyleList *list); + +NRTypeDict *nr_type_dict_new (void); + +void nr_type_dict_insert (NRTypeDict *td, const gchar *key, void *val); + +void *nr_type_dict_lookup (NRTypeDict *td, const gchar *key); + +#endif diff --git a/src/libnrtype/nrtype-forward.h b/src/libnrtype/nrtype-forward.h new file mode 100644 index 000000000..f3344f2fd --- /dev/null +++ b/src/libnrtype/nrtype-forward.h @@ -0,0 +1,23 @@ +#ifndef SEEN_LIBNRTYPE_NRTYPE_FORWARD_H +#define SEEN_LIBNRTYPE_NRTYPE_FORWARD_H + +class font_factory; +struct font_glyph; +class font_instance; +struct font_style; +class raster_font; +class raster_glyph; +class raster_position; + +#endif /* !SEEN_LIBNRTYPE_NRTYPE_FORWARD_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 : diff --git a/src/libnrtype/one-box.h b/src/libnrtype/one-box.h new file mode 100644 index 000000000..1040e2be9 --- /dev/null +++ b/src/libnrtype/one-box.h @@ -0,0 +1,28 @@ +/** \file Definition of struct one_box. */ + +#ifndef LIBNRTYPE_ONE_BOX_H_INKSCAPE +#define LIBNRTYPE_ONE_BOX_H_INKSCAPE + +// text chunking 2, the comeback +// this time for sp-typeset +struct one_box { + int g_st, g_en; ///< First and last glyph of this word. + double ascent, descent, leading; + double width; + bool word_start, word_end; +}; + + +#endif /* !LIBNRTYPE_ONE_BOX_H_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:textwidth=99 : + diff --git a/src/libnrtype/one-glyph.h b/src/libnrtype/one-glyph.h new file mode 100644 index 000000000..667c7743b --- /dev/null +++ b/src/libnrtype/one-glyph.h @@ -0,0 +1,46 @@ +/** \file Definition of struct one_glyph. */ + +/* + * License: May be redistributed with or without modifications under the terms of the Gnu General + * Public License as published by the Free Software Foundation, version 2 or (at your option) any + * later version. + */ + +#ifndef LIBNRTYPE_ONE_GLYPH_H_INKSCAPE +#define LIBNRTYPE_ONE_GLYPH_H_INKSCAPE + +#include + +/** + * Information for a single glyph. + * + * Pango converts the text into glyphs, but scatters the info for a given glyph; here is a + * structure holding what inkscape needs to know. + */ +struct one_glyph { + int gl; ///< glyph_id + double x, y; ///< glyph position in the layout (nominal sizes, in the [0..1] range). + bool char_start; /**< Whether this glyph is the beginning of a letter. (RTL is taken in + * account.) */ + bool word_start; ///< Whether this glyph is the beginning of a word. + bool para_start; ///< Whether this glyph is the beginning of a paragraph (for indentation). + char uni_dir; ///< BiDi orientation of the run containing this glyph. + int uni_st, uni_en; /**< Start and end positions of the text corresponding to this glyph. + * You always have uni_st < uni_en. */ + PangoFont *font; /**< Font this glyph uses. (For bidi text, you need several fonts.) + * When rendering glyphs, check if this font is the one you're using. */ +}; + + +#endif /* !LIBNRTYPE_ONE_GLYPH_H_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:textwidth=99 : diff --git a/src/libnrtype/one-para.h b/src/libnrtype/one-para.h new file mode 100644 index 000000000..60e59531f --- /dev/null +++ b/src/libnrtype/one-para.h @@ -0,0 +1,20 @@ +#ifndef LIBNRTYPE_ONE_PARA_H_INKSCAPE +#define LIBNRTYPE_ONE_PARA_H_INKSCAPE + +struct one_para { + int b_st, b_en; +}; + + +#endif /* !LIBNRTYPE_ONE_PARA_H_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:textwidth=99 : diff --git a/src/libnrtype/raster-glyph.h b/src/libnrtype/raster-glyph.h new file mode 100644 index 000000000..e39cc4e41 --- /dev/null +++ b/src/libnrtype/raster-glyph.h @@ -0,0 +1,49 @@ +#ifndef SEEN_LIBNRTYPE_RASTER_GLYPH_H +#define SEEN_LIBNRTYPE_RASTER_GLYPH_H + +#include +#include +#include + +// a little utility class that holds data to render a styled glyph +// ie. it's like a polygon. its function is to wrap the subpixel positionning +class raster_glyph { +public: + // raster_font that created me + raster_font* daddy; + // the glyph i am (the style is in daddy) + int glyph_id; + // internal structure: the styled path, and the associated uncrossed polygon + // they could be removed after the raster_position have been computed + Path* outline; // transformed by the matrix in style (may be factorized, but is small) + Shape* polygon; + // subpixel positions + // nb_sub_pixel is set to 4 when the glyph is created (it's hardcoded) + int nb_sub_pixel; + raster_position* sub_pixel; + + raster_glyph(void); + ~raster_glyph(void); + + // utility + void SetSubPixelPositionning(int nb_pos); + void LoadSubPixelPosition(int no); + + // the interesting function: blits the glyph onto over + // over should be a mask, ie a NRPixBlock with one 8bit plane + void Blit(NR::Point const &at, NRPixBlock &over); // alpha only +}; + + +#endif /* !SEEN_LIBNRTYPE_RASTER_GLYPH_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 : diff --git a/src/libnrtype/raster-position.h b/src/libnrtype/raster-position.h new file mode 100644 index 000000000..ef12b93ec --- /dev/null +++ b/src/libnrtype/raster-position.h @@ -0,0 +1,46 @@ +#ifndef SEEN_LIBNRTYPE_RASTER_POSITION_H +#define SEEN_LIBNRTYPE_RASTER_POSITION_H + +#include + +#include +#include +#include + +// one subpixel position +// it's basically a set of trapezoids (=float_ligne_run) representing the black areas of the glyph +// all trapezoids are in the same array, hence the run_on_line array to give the number of +// trapezoids on each line +// trapezoids store the x-positions as float, and are shifted to the x blit position +// so it's "exact" in the x direction and subpixel in the y direction +class raster_position { +public: + int top, bottom; // baseline is y=0 + // top is the first pixel, bottom is the last + int* run_on_line; // array of size (bottom-top+1): run_on_line[i] gives the number of runs on line top+i + int nbRun; + float_ligne_run* runs; + +public: + raster_position(); + ~raster_position(); + + // stuff runs into the structure + void AppendRuns(std::vector const &r, int y); + // blits the trapezoids. + void Blit(float ph, int pv, NRPixBlock &over); +}; + + +#endif /* !SEEN_LIBNRTYPE_RASTER_POSITION_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 : diff --git a/src/libnrtype/text-boundary.h b/src/libnrtype/text-boundary.h new file mode 100644 index 000000000..83a825b55 --- /dev/null +++ b/src/libnrtype/text-boundary.h @@ -0,0 +1,49 @@ +#ifndef TEXT_BOUNDARY_H_INKSCAPE +#define TEXT_BOUNDARY_H_INKSCAPE + +/** \file Definition of text_boundary. */ + +/* + * License: May be redistributed with or without modifications under the terms of the Gnu General + * Public License as published by the Free Software Foundation, version 2 or (at your option) any + * later version. + */ + +#include "libnrtype/boundary-type.h" + + +/** + * A character/word/paragraph boundary in the text, used by TextWrapper. + * + * (Boundaries are paired.) + */ +struct text_boundary { + /** Index of the boundary in the text: first char of the text chunk if 'start' boundary, char + * right after the boundary otherwise. + */ + int uni_pos; + BoundaryType type; ///< Kind of boundary. + bool start; ///< Indicates whether this marks the beginning or end of a chunk. + unsigned other; ///< Index in bounds[] of the corresponding end/beginning boundary. + unsigned old_ix; ///< Temporary storage used solely SortBoundaries. + /// Data for this boundary; usually, one int is enough. + union { + int i; + double f; + void *p; + } data; +}; + + +#endif /* !TEXT_BOUNDARY_H_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:textwidth=99 : diff --git a/src/line-snapper.cpp b/src/line-snapper.cpp new file mode 100644 index 000000000..383c1fb96 --- /dev/null +++ b/src/line-snapper.cpp @@ -0,0 +1,80 @@ +#include "libnr/nr-values.h" +#include "libnr/nr-point-fns.h" +#include "geom.h" +#include "line-snapper.h" + +Inkscape::LineSnapper::LineSnapper(SPNamedView const *nv, NR::Coord const d) : Snapper(nv, d) +{ + +} + +Inkscape::SnappedPoint Inkscape::LineSnapper::_doFreeSnap(NR::Point const &p, + std::list const &it) const +{ + /* Snap along x (ie to vertical lines) */ + Inkscape::SnappedPoint const v = _doConstrainedSnap(p, component_vectors[NR::X], it); + /* Snap along y (ie to horizontal lines) */ + Inkscape::SnappedPoint const h = _doConstrainedSnap(p, component_vectors[NR::Y], it); + + /* If we snapped to both, combine the two results. This is so that, for example, + ** we snap nicely to the intersection of two guidelines. + */ + if (v.getDistance() < NR_HUGE && h.getDistance() < NR_HUGE) { + return SnappedPoint(NR::Point(v.getPoint()[NR::X], h.getPoint()[NR::Y]), hypot(v.getDistance(), h.getDistance())); + } + + /* If we snapped to a vertical line, return that */ + if (v.getDistance() < NR_HUGE) { + return v; + } + + /* Otherwise just return any horizontal snap; if we didn't snap to that either + ** we haven't snapped to anything. + */ + return h; +} + +Inkscape::SnappedPoint Inkscape::LineSnapper::_doConstrainedSnap(NR::Point const &p, + NR::Point const &c, + std::list const &it) const +{ + Inkscape::SnappedPoint s = SnappedPoint(p, NR_HUGE); + + NR::Point const v = NR::unit_vector(c); + + /* Get the lines that we will try to snap to */ + const LineList lines = _getSnapLines(p); + + for (LineList::const_iterator i = lines.begin(); i != lines.end(); i++) { + + /* Normal to the line we're trying to snap along */ + NR::Point const n(NR::rot90(v)); + + /* Hence constant term of the line we're trying to snap along */ + NR::Coord const q = dot(n, p); + + /* Try to intersect this line with the target line */ + NR::Point t = p; + IntersectorKind const k = intersector_line_intersection(n, q, component_vectors[i->first], i->second, t); + + if (k == INTERSECTS) { + const NR::Coord dist = L2(t - p); + if (dist < getDistance() && dist < s.getDistance() ) { + s = SnappedPoint(t, dist); + } + } + } + + return s; +} + +/* + 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 : diff --git a/src/line-snapper.h b/src/line-snapper.h new file mode 100644 index 000000000..581466d33 --- /dev/null +++ b/src/line-snapper.h @@ -0,0 +1,44 @@ +#ifndef SEEN_LINE_SNAPPER_H +#define SEEN_LINE_SNAPPER_H + +/** + * \file src/line-snapper.h + * \brief Superclass for snappers to horizontal and vertical lines. + * + * Authors: + * Carl Hetherington + * + * Released under GNU GPL, read the file 'COPYING' for more information. + */ + +#include "snapper.h" + +namespace Inkscape +{ + +class LineSnapper : public Snapper +{ +public: + LineSnapper(SPNamedView const *nv, NR::Coord const d); + +protected: + typedef std::list > LineList; + +private: + SnappedPoint _doFreeSnap(NR::Point const &p, + std::list const &it) const; + + SnappedPoint _doConstrainedSnap(NR::Point const &p, + NR::Point const &c, + std::list const &it) const; + + /** + * \param p Point that we are trying to snap. + * \return List of lines that we should try snapping to. + */ + virtual LineList _getSnapLines(NR::Point const &p) const = 0; +}; + +} + +#endif /* !SEEN_LINE_SNAPPER_H */ diff --git a/src/livarot/.cvsignore b/src/livarot/.cvsignore new file mode 100644 index 000000000..ef34ceff5 --- /dev/null +++ b/src/livarot/.cvsignore @@ -0,0 +1,7 @@ +*~ +.deps +.dirstamp +.libs +Makefile +Makefile.in +makefile diff --git a/src/livarot/AVL.cpp b/src/livarot/AVL.cpp new file mode 100644 index 000000000..5ddbe8070 --- /dev/null +++ b/src/livarot/AVL.cpp @@ -0,0 +1,965 @@ +/* + * AVL.cpp + * nlivarot + * + * Created by fred on Mon Jun 16 2003. + * + */ + +#include "AVL.h" + +/* + * the algorithm explanation for this code comes from purists.org, which seems to have disappeared since + * it's a classic AVL tree rebalancing, nothing fancy + */ + +AVLTree::AVLTree() +{ + MakeNew(); +} + +AVLTree::~AVLTree() +{ + MakeDelete(); +} + +void AVLTree::MakeNew() +{ + for (int i = 0; i < 2; i++) + { + elem[i] = NULL; + son[i] = NULL; + } + + dad = NULL; + balance = 0; +} + +void AVLTree::MakeDelete() +{ + for (int i = 0; i < 2; i++) { + if (elem[i]) { + elem[i]->elem[1 - i] = elem[1 - i]; + } + elem[i] = NULL; + } +} + +AVLTree *AVLTree::Leftmost() +{ + return leafFromDad(NULL, LEFT); +} + +AVLTree *AVLTree::leaf(AVLTree *from, Side s) +{ + if (from == son[1 - s]) { + if (son[s]) { + return son[s]->leafFromDad(this, s); + } + else if (dad) { + return dad->leaf(this, s); + } + } + else if (from == son[s]) { + if (dad) { + return dad->leaf(this, s); + } + } + + return NULL; +} + +AVLTree *AVLTree::leafFromDad(AVLTree *from, Side s) +{ + if (son[s]) { + return son[s]->leafFromDad(this, s); + } + + return this; +} + +int +AVLTree::RestoreBalances (AVLTree * from, AVLTree * &racine) +{ + if (from == NULL) + { + if (dad) + return dad->RestoreBalances (this, racine); + } + else + { + if (balance == 0) + { + if (from == son[LEFT]) + balance = 1; + if (from == son[RIGHT]) + balance = -1; + if (dad) + return dad->RestoreBalances (this, racine); + return avl_no_err; + } + else if (balance > 0) + { + if (from == son[RIGHT]) + { + balance = 0; + return avl_no_err; + } + if (son[LEFT] == NULL) + { +// cout << "mierda\n"; + return avl_bal_err; + } + AVLTree *a = this; + AVLTree *b = son[LEFT]; + AVLTree *e = son[RIGHT]; + AVLTree *c = son[LEFT]->son[LEFT]; + AVLTree *d = son[LEFT]->son[RIGHT]; + if (son[LEFT]->balance > 0) + { + AVLTree *r = dad; + + a->dad = b; + b->son[RIGHT] = a; + a->son[RIGHT] = e; + if (e) + e->dad = a; + a->son[LEFT] = d; + if (d) + d->dad = a; + b->son[LEFT] = c; + if (c) + c->dad = b; + b->dad = r; + if (r) + { + if (r->son[LEFT] == a) + r->son[LEFT] = b; + if (r->son[RIGHT] == a) + r->son[RIGHT] = b; + } + if (racine == a) + racine = b; + + a->balance = 0; + b->balance = 0; + return avl_no_err; + } + else + { + if (son[LEFT]->son[RIGHT] == NULL) + { + // cout << "mierda\n"; + return avl_bal_err; + } + AVLTree *f = son[LEFT]->son[RIGHT]->son[LEFT]; + AVLTree *g = son[LEFT]->son[RIGHT]->son[RIGHT]; + AVLTree *r = dad; + + a->dad = d; + d->son[RIGHT] = a; + b->dad = d; + d->son[LEFT] = b; + a->son[LEFT] = g; + if (g) + g->dad = a; + a->son[RIGHT] = e; + if (e) + e->dad = a; + b->son[LEFT] = c; + if (c) + c->dad = b; + b->son[RIGHT] = f; + if (f) + f->dad = b; + + d->dad = r; + if (r) + { + if (r->son[LEFT] == a) + r->son[LEFT] = d; + if (r->son[RIGHT] == a) + r->son[RIGHT] = d; + } + if (racine == a) + racine = d; + + int old_bal = d->balance; + d->balance = 0; + if (old_bal == 0) + { + a->balance = 0; + b->balance = 0; + } + else if (old_bal > 0) + { + a->balance = -1; + b->balance = 0; + } + else if (old_bal < 0) + { + a->balance = 0; + b->balance = 1; + } + return avl_no_err; + } + } + else if (balance < 0) + { + if (from == son[LEFT]) + { + balance = 0; + return avl_no_err; + } + if (son[RIGHT] == NULL) + { +// cout << "mierda\n"; + return avl_bal_err; + } + AVLTree *a = this; + AVLTree *b = son[RIGHT]; + AVLTree *e = son[LEFT]; + AVLTree *c = son[RIGHT]->son[RIGHT]; + AVLTree *d = son[RIGHT]->son[LEFT]; + AVLTree *r = dad; + if (son[RIGHT]->balance < 0) + { + + a->dad = b; + b->son[LEFT] = a; + a->son[LEFT] = e; + if (e) + e->dad = a; + a->son[RIGHT] = d; + if (d) + d->dad = a; + b->son[RIGHT] = c; + if (c) + c->dad = b; + b->dad = r; + if (r) + { + if (r->son[LEFT] == a) + r->son[LEFT] = b; + if (r->son[RIGHT] == a) + r->son[RIGHT] = b; + } + if (racine == a) + racine = b; + a->balance = 0; + b->balance = 0; + return avl_no_err; + } + else + { + if (son[RIGHT]->son[LEFT] == NULL) + { +// cout << "mierda\n"; + return avl_bal_err; + } + AVLTree *f = son[RIGHT]->son[LEFT]->son[RIGHT]; + AVLTree *g = son[RIGHT]->son[LEFT]->son[LEFT]; + + a->dad = d; + d->son[LEFT] = a; + b->dad = d; + d->son[RIGHT] = b; + a->son[RIGHT] = g; + if (g) + g->dad = a; + a->son[LEFT] = e; + if (e) + e->dad = a; + b->son[RIGHT] = c; + if (c) + c->dad = b; + b->son[LEFT] = f; + if (f) + f->dad = b; + + d->dad = r; + if (r) + { + if (r->son[LEFT] == a) + r->son[LEFT] = d; + if (r->son[RIGHT] == a) + r->son[RIGHT] = d; + } + if (racine == a) + racine = d; + int old_bal = d->balance; + d->balance = 0; + if (old_bal == 0) + { + a->balance = 0; + b->balance = 0; + } + else if (old_bal > 0) + { + a->balance = 0; + b->balance = -1; + } + else if (old_bal < 0) + { + a->balance = 1; + b->balance = 0; + } + return avl_no_err; + } + } + } + return avl_no_err; +} + +int +AVLTree::RestoreBalances (int diff, AVLTree * &racine) +{ + if (balance > 0) + { + if (diff < 0) + { + balance = 0; + if (dad) + { + if (this == dad->son[RIGHT]) + return dad->RestoreBalances (1, racine); + if (this == dad->son[LEFT]) + return dad->RestoreBalances (-1, racine); + } + return avl_no_err; + } + else if (diff == 0) + { + } + else if (diff > 0) + { + if (son[LEFT] == NULL) + { +// cout << "un probleme\n"; + return avl_bal_err; + } + AVLTree *r = dad; + AVLTree *a = this; + AVLTree *b = son[RIGHT]; + AVLTree *e = son[LEFT]; + AVLTree *f = e->son[RIGHT]; + AVLTree *g = e->son[LEFT]; + if (e->balance > 0) + { + e->son[RIGHT] = a; + e->son[LEFT] = g; + a->son[RIGHT] = b; + a->son[LEFT] = f; + if (a) + a->dad = e; + if (g) + g->dad = e; + if (b) + b->dad = a; + if (f) + f->dad = a; + e->dad = r; + if (r) + { + if (r->son[LEFT] == a) + r->son[LEFT] = e; + if (r->son[RIGHT] == a) + r->son[RIGHT] = e; + } + if (racine == this) + racine = e; + e->balance = 0; + a->balance = 0; + if (r) + { + if (e == r->son[RIGHT]) + return r->RestoreBalances (1, racine); + if (e == r->son[LEFT]) + return r->RestoreBalances (-1, racine); + } + return avl_no_err; + } + else if (e->balance == 0) + { + e->son[RIGHT] = a; + e->son[LEFT] = g; + a->son[RIGHT] = b; + a->son[LEFT] = f; + if (a) + a->dad = e; + if (g) + g->dad = e; + if (b) + b->dad = a; + if (f) + f->dad = a; + e->dad = r; + if (r) + { + if (r->son[LEFT] == a) + r->son[LEFT] = e; + if (r->son[RIGHT] == a) + r->son[RIGHT] = e; + } + if (racine == this) + racine = e; + e->balance = -1; + a->balance = 1; + return avl_no_err; + } + else if (e->balance < 0) + { + if (son[LEFT]->son[RIGHT] == NULL) + { +// cout << "un probleme\n"; + return avl_bal_err; + } + AVLTree *i = son[LEFT]->son[RIGHT]->son[RIGHT]; + AVLTree *j = son[LEFT]->son[RIGHT]->son[LEFT]; + + f->son[RIGHT] = a; + f->son[LEFT] = e; + a->son[RIGHT] = b; + a->son[LEFT] = i; + e->son[RIGHT] = j; + e->son[LEFT] = g; + if (b) + b->dad = a; + if (i) + i->dad = a; + if (g) + g->dad = e; + if (j) + j->dad = e; + if (a) + a->dad = f; + if (e) + e->dad = f; + f->dad = r; + if (r) + { + if (r->son[LEFT] == a) + r->son[LEFT] = f; + if (r->son[RIGHT] == a) + r->son[RIGHT] = f; + } + if (racine == this) + racine = f; + int oBal = f->balance; + f->balance = 0; + if (oBal > 0) + { + a->balance = -1; + e->balance = 0; + } + else if (oBal == 0) + { + a->balance = 0; + e->balance = 0; + } + else if (oBal < 0) + { + a->balance = 0; + e->balance = 1; + } + if (r) + { + if (f == r->son[RIGHT]) + return r->RestoreBalances (1, racine); + if (f == r->son[LEFT]) + return r->RestoreBalances (-1, racine); + } + return avl_no_err; + } + } + } + else if (balance == 0) + { + if (diff < 0) + { + balance = -1; + } + else if (diff == 0) + { + } + else if (diff > 0) + { + balance = 1; + } + return avl_no_err; + } + else if (balance < 0) + { + if (diff < 0) + { + if (son[RIGHT] == NULL) + { +// cout << "un probleme\n"; + return avl_bal_err; + } + AVLTree *r = dad; + AVLTree *a = this; + AVLTree *b = son[LEFT]; + AVLTree *e = son[RIGHT]; + AVLTree *f = e->son[LEFT]; + AVLTree *g = e->son[RIGHT]; + if (e->balance < 0) + { + e->son[LEFT] = a; + e->son[RIGHT] = g; + a->son[LEFT] = b; + a->son[RIGHT] = f; + if (a) + a->dad = e; + if (g) + g->dad = e; + if (b) + b->dad = a; + if (f) + f->dad = a; + e->dad = r; + if (r) + { + if (r->son[LEFT] == a) + r->son[LEFT] = e; + if (r->son[RIGHT] == a) + r->son[RIGHT] = e; + } + if (racine == this) + racine = e; + e->balance = 0; + a->balance = 0; + if (r) + { + if (e == r->son[RIGHT]) + return r->RestoreBalances (1, racine); + if (e == r->son[LEFT]) + return r->RestoreBalances (-1, racine); + } + return avl_no_err; + } + else if (e->balance == 0) + { + e->son[LEFT] = a; + e->son[RIGHT] = g; + a->son[LEFT] = b; + a->son[RIGHT] = f; + if (a) + a->dad = e; + if (g) + g->dad = e; + if (b) + b->dad = a; + if (f) + f->dad = a; + e->dad = r; + if (r) + { + if (r->son[LEFT] == a) + r->son[LEFT] = e; + if (r->son[RIGHT] == a) + r->son[RIGHT] = e; + } + if (racine == this) + racine = e; + e->balance = 1; + a->balance = -1; + return avl_no_err; + } + else if (e->balance > 0) + { + if (son[RIGHT]->son[LEFT] == NULL) + { +// cout << "un probleme\n"; + return avl_bal_err; + } + AVLTree *i = son[RIGHT]->son[LEFT]->son[LEFT]; + AVLTree *j = son[RIGHT]->son[LEFT]->son[RIGHT]; + + f->son[LEFT] = a; + f->son[RIGHT] = e; + a->son[LEFT] = b; + a->son[RIGHT] = i; + e->son[LEFT] = j; + e->son[RIGHT] = g; + if (b) + b->dad = a; + if (i) + i->dad = a; + if (g) + g->dad = e; + if (j) + j->dad = e; + if (a) + a->dad = f; + if (e) + e->dad = f; + f->dad = r; + if (r) + { + if (r->son[LEFT] == a) + r->son[LEFT] = f; + if (r->son[RIGHT] == a) + r->son[RIGHT] = f; + } + if (racine == this) + racine = f; + int oBal = f->balance; + f->balance = 0; + if (oBal > 0) + { + a->balance = 0; + e->balance = -1; + } + else if (oBal == 0) + { + a->balance = 0; + e->balance = 0; + } + else if (oBal < 0) + { + a->balance = 1; + e->balance = 0; + } + if (r) + { + if (f == r->son[RIGHT]) + return r->RestoreBalances (1, racine); + if (f == r->son[LEFT]) + return r->RestoreBalances (-1, racine); + } + return avl_no_err; + } + } + else if (diff == 0) + { + } + else if (diff > 0) + { + balance = 0; + if (dad) + { + if (this == dad->son[RIGHT]) + return dad->RestoreBalances (1, racine); + if (this == dad->son[LEFT]) + return dad->RestoreBalances (-1, racine); + } + return avl_no_err; + } + } + return avl_no_err; +} + +/* + * removal + */ +int +AVLTree::Remove (AVLTree * &racine, bool rebalance) +{ + AVLTree *startNode = NULL; + int remDiff = 0; + int res = Remove (racine, startNode, remDiff); + if (res == avl_no_err && rebalance && startNode) + res = startNode->RestoreBalances (remDiff, racine); + return res; +} + +int +AVLTree::Remove (AVLTree * &racine, AVLTree * &startNode, int &diff) +{ + if (elem[LEFT]) + elem[LEFT]->elem[RIGHT] = elem[RIGHT]; + if (elem[RIGHT]) + elem[RIGHT]->elem[LEFT] = elem[LEFT]; + elem[LEFT] = elem[RIGHT] = NULL; + + if (son[LEFT] && son[RIGHT]) + { + AVLTree *newMe = son[LEFT]->leafFromDad(this, RIGHT); + if (newMe == NULL || newMe->son[RIGHT]) + { +// cout << "pas normal\n"; + return avl_rm_err; + } + if (newMe == son[LEFT]) + { + startNode = newMe; + diff = -1; + newMe->son[RIGHT] = son[RIGHT]; + son[RIGHT]->dad = newMe; + newMe->dad = dad; + if (dad) + { + if (dad->son[LEFT] == this) + dad->son[LEFT] = newMe; + if (dad->son[RIGHT] == this) + dad->son[RIGHT] = newMe; + } + } + else + { + AVLTree *oDad = newMe->dad; + startNode = oDad; + diff = 1; + + oDad->son[RIGHT] = newMe->son[LEFT]; + if (newMe->son[LEFT]) + newMe->son[LEFT]->dad = oDad; + + newMe->dad = dad; + newMe->son[LEFT] = son[LEFT]; + newMe->son[RIGHT] = son[RIGHT]; + if (dad) + { + if (dad->son[LEFT] == this) + dad->son[LEFT] = newMe; + if (dad->son[RIGHT] == this) + dad->son[RIGHT] = newMe; + } + if (son[LEFT]) + son[LEFT]->dad = newMe; + if (son[RIGHT]) + son[RIGHT]->dad = newMe; + } + newMe->balance = balance; + if (racine == this) + racine = newMe; + } + else if (son[LEFT]) + { + startNode = dad; + diff = 0; + if (dad) + { + if (this == dad->son[LEFT]) + diff = -1; + if (this == dad->son[RIGHT]) + diff = 1; + } + if (dad) + { + if (dad->son[LEFT] == this) + dad->son[LEFT] = son[LEFT]; + if (dad->son[RIGHT] == this) + dad->son[RIGHT] = son[LEFT]; + } + if (son[LEFT]->dad == this) + son[LEFT]->dad = dad; + if (racine == this) + racine = son[LEFT]; + } + else if (son[RIGHT]) + { + startNode = dad; + diff = 0; + if (dad) + { + if (this == dad->son[LEFT]) + diff = -1; + if (this == dad->son[RIGHT]) + diff = 1; + } + if (dad) + { + if (dad->son[LEFT] == this) + dad->son[LEFT] = son[RIGHT]; + if (dad->son[RIGHT] == this) + dad->son[RIGHT] = son[RIGHT]; + } + if (son[RIGHT]->dad == this) + son[RIGHT]->dad = dad; + if (racine == this) + racine = son[RIGHT]; + } + else + { + startNode = dad; + diff = 0; + if (dad) + { + if (this == dad->son[LEFT]) + diff = -1; + if (this == dad->son[RIGHT]) + diff = 1; + } + if (dad) + { + if (dad->son[LEFT] == this) + dad->son[LEFT] = NULL; + if (dad->son[RIGHT] == this) + dad->son[RIGHT] = NULL; + } + if (racine == this) + racine = NULL; + } + dad = son[RIGHT] = son[LEFT] = NULL; + balance = 0; + return avl_no_err; +} + +/* + * insertion + */ +int +AVLTree::Insert (AVLTree * &racine, int insertType, AVLTree * insertL, + AVLTree * insertR, bool rebalance) +{ + int res = Insert (racine, insertType, insertL, insertR); + if (res == avl_no_err && rebalance) + res = RestoreBalances ((AVLTree *) NULL, racine); + return res; +} + +int +AVLTree::Insert (AVLTree * &racine, int insertType, AVLTree * insertL, + AVLTree * insertR) +{ + if (racine == NULL) + { + racine = this; + return avl_no_err; + } + else + { + if (insertType == not_found) + { +// cout << "pb avec l'arbre de raster\n"; + return avl_ins_err; + } + else if (insertType == found_on_left) + { + if (insertR == NULL || insertR->son[LEFT]) + { +// cout << "ngou?\n"; + return avl_ins_err; + } + insertR->son[LEFT] = this; + dad = insertR; + insertOn(LEFT, insertR); + } + else if (insertType == found_on_right) + { + if (insertL == NULL || insertL->son[RIGHT]) + { +// cout << "ngou?\n"; + return avl_ins_err; + } + insertL->son[RIGHT] = this; + dad = insertL; + insertOn(RIGHT, insertL); + } + else if (insertType == found_between) + { + if (insertR == NULL || insertL == NULL + || (insertR->son[LEFT] != NULL && insertL->son[RIGHT] != NULL)) + { +// cout << "ngou?\n"; + return avl_ins_err; + } + if (insertR->son[LEFT] == NULL) + { + insertR->son[LEFT] = this; + dad = insertR; + } + else if (insertL->son[RIGHT] == NULL) + { + insertL->son[RIGHT] = this; + dad = insertL; + } + insertBetween (insertL, insertR); + } + else if (insertType == found_exact) + { + if (insertL == NULL) + { +// cout << "ngou?\n"; + return avl_ins_err; + } + // et on insere + + if (insertL->son[RIGHT]) + { + insertL = insertL->son[RIGHT]->leafFromDad(insertL, LEFT); + if (insertL->son[LEFT]) + { +// cout << "ngou?\n"; + return avl_ins_err; + } + insertL->son[LEFT] = this; + this->dad = insertL; + insertBetween (insertL->elem[LEFT], insertL); + } + else + { + insertL->son[RIGHT] = this; + dad = insertL; + insertBetween (insertL, insertL->elem[RIGHT]); + } + } + else + { + // cout << "code incorrect\n"; + return avl_ins_err; + } + } + return avl_no_err; +} + +void +AVLTree::Relocate (AVLTree * to) +{ + if (elem[LEFT]) + elem[LEFT]->elem[RIGHT] = to; + if (elem[RIGHT]) + elem[RIGHT]->elem[LEFT] = to; + to->elem[LEFT] = elem[LEFT]; + to->elem[RIGHT] = elem[RIGHT]; + + if (dad) + { + if (dad->son[LEFT] == this) + dad->son[LEFT] = to; + if (dad->son[RIGHT] == this) + dad->son[RIGHT] = to; + } + if (son[RIGHT]) + { + son[RIGHT]->dad = to; + } + if (son[LEFT]) + { + son[LEFT]->dad = to; + } + to->dad = dad; + to->son[RIGHT] = son[RIGHT]; + to->son[LEFT] = son[LEFT]; +} + + +void AVLTree::insertOn(Side s, AVLTree *of) +{ + elem[1 - s] = of; + if (of) + of->elem[s] = this; +} + +void AVLTree::insertBetween(AVLTree *l, AVLTree *r) +{ + if (l) + l->elem[RIGHT] = this; + if (r) + r->elem[LEFT] = this; + elem[LEFT] = l; + elem[RIGHT] = r; +} + +/* + 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:textwidth=99 : diff --git a/src/livarot/AVL.h b/src/livarot/AVL.h new file mode 100644 index 000000000..257c39c72 --- /dev/null +++ b/src/livarot/AVL.h @@ -0,0 +1,95 @@ +/* + * AVL.h + * nlivarot + * + * Created by fred on Mon Jun 16 2003. + * + */ + +#ifndef my_avl +#define my_avl + +#include +#include "LivarotDefs.h" + +/* + * base class providing AVL tree functionnality, that is binary balanced tree + * there is no Find() function because the class only deal with topological info + * subclasses of this class have to implement a Find(), and most certainly to + * override the Insert() function + */ + +class AVLTree +{ +public: + + AVLTree *elem[2]; + + // left most node (ie, with smallest key) in the subtree of this node + AVLTree *Leftmost(); + +protected: + + AVLTree *son[2]; + + AVLTree(); + ~AVLTree(); + + // constructor/destructor meant to be called for an array of AVLTree created by malloc + void MakeNew(); + void MakeDelete(); + + // insertion of the present node in the tree + // insertType is the insertion type (defined in LivarotDefs.h: not_found, found_exact, found_on_left, etc) + // insertL is the node in the tree that is immediatly before the current one, NULL is the present node goes to the + // leftmost position. if insertType == found_exact, insertL should be the node with ak key + // equal to that of the present node + int Insert(AVLTree * &racine, int insertType, AVLTree *insertL, + AVLTree * insertR, bool rebalance); + + // called when this node is relocated to a new position in memory, to update pointers to him + void Relocate(AVLTree *to); + + // removal of the present element racine is the tree's root; it's a reference because if the + // node is the root, removal of the node will change the root + // rebalance==true if rebalancing is needed + int Remove(AVLTree * &racine, bool rebalance = true); + +private: + + AVLTree *dad; + + int balance; + + // insertion gruntwork. + int Insert(AVLTree * &racine, int insertType, AVLTree *insertL, AVLTree *insertR); + + // rebalancing functions. both are recursive, but the depth of the trees we'll use should not be a problem + // this one is for rebalancing after insertions + int RestoreBalances(AVLTree *from, AVLTree * &racine); + // this one is for removals + int RestoreBalances(int diff, AVLTree * &racine); + + // startNode is the node where the rebalancing starts; rebalancing then moves up the tree to the root + // diff is the change in "subtree height", as needed for the rebalancing + // racine is the reference to the root, since rebalancing can change it too + int Remove(AVLTree * &racine, AVLTree * &startNode, int &diff); + + void insertOn(Side s, AVLTree *of); + void insertBetween(AVLTree *l, AVLTree *r); + AVLTree *leaf(AVLTree *from, Side s); + AVLTree *leafFromDad(AVLTree *from, Side s); +}; + +#endif + +/* + 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:textwidth=99 : diff --git a/src/livarot/AlphaLigne.cpp b/src/livarot/AlphaLigne.cpp new file mode 100644 index 000000000..fa128e1a7 --- /dev/null +++ b/src/livarot/AlphaLigne.cpp @@ -0,0 +1,304 @@ +/* + * AlphaLigne.cpp + * nlivarot + * + * Created by fred on Fri Jul 25 2003. + * public domain + * + */ + +#include "AlphaLigne.h" +//#include "Buffer.h" + +#include +#include + +AlphaLigne::AlphaLigne(int iMin,int iMax) +{ + min=iMin; + max=iMax; + if ( max < min+1 ) max=min+1; + steps=NULL; + nbStep=maxStep=0; + before.x=min-1; + before.delta=0; + after.x=max+1; + after.delta=0; +} +AlphaLigne::~AlphaLigne(void) +{ + g_free(steps); + steps=NULL; + nbStep=maxStep=0; +} +void AlphaLigne::Affiche(void) +{ + printf("%i steps\n",nbStep); + for (int i=0;i %f %f / %f\n",spos,sval,epos,eval,tPente); + if ( sval == eval ) return 0; + // compute the footprint of [spos,epos] on the line of pixels + float curStF=floor(spos); + float curEnF=floor(epos); + int curSt=(int)curStF; + int curEn=(int)curEnF; + + // update curMin and curMax + if ( curSt > max ) { + // we're on the right of the visible portion of the line: bail out! + if ( eval < sval ) curMax=max; + return 0; + } + if ( curSt < curMin ) curMin=curSt; + if ( ceil(epos) > curMax ) curMax=(int)ceil(epos); + + // clamp the changed portion to [min,max], no need for bigger + if ( curMax > max ) curMax=max; + if ( curMin < min ) curMin=min; + + // total amount of change in pixel coverage from before the right to after the run + float needed=eval-sval; + float needC=/*(int)ldexpf(*/needed/*,24)*/; + + if ( curEn < min ) { + // the added portion is entirely on the left, so we only have to change the initial coverage for the line + before.delta+=needC; + return 0; + } + + // add the steps + // the pixels from [curSt..curEn] (included) intersect with [spos;epos] + // since we're dealing with delta in the coverage, there is also a curEn+1 delta, since the curEn pixel intersect + // with [spos;epos] and thus has some delta with respect to its next pixel + // lots of different cases... ugly + if ( curSt == curEn ) { + if ( curSt+1 < min ) { + before.delta+=needC; + } else { + if ( nbStep+2 >= maxStep ) { + maxStep=2*nbStep+2; + steps=(alpha_step*)g_realloc(steps,maxStep*sizeof(alpha_step)); + } + float stC=/*(int)ldexpf(*/(eval-sval)*(0.5*(epos-spos)+curStF+1-epos)/*,24)*/; + steps[nbStep].x=curSt; + steps[nbStep].delta=stC; + nbStep++; + steps[nbStep].x=curSt+1; + steps[nbStep].delta=needC-stC; // au final, on a toujours le bon delta, meme avec une arete completement verticale + nbStep++; + } + } else if ( curEn == curSt+1 ) { + if ( curSt+2 < min ) { + before.delta+=needC; + } else { + if ( nbStep+3 >= maxStep ) { + maxStep=2*nbStep+3; + steps=(alpha_step*)g_realloc(steps,maxStep*sizeof(alpha_step)); + } + float stC=/*(int)ldexpf(*/0.5*tPente*(curEnF-spos)*(curEnF-spos)/*,24)*/; + float enC=/*(int)ldexpf(*/tPente-0.5*tPente*((spos-curStF)*(spos-curStF)+(curEnF+1.0-epos)*(curEnF+1.0-epos))/*,24)*/; + steps[nbStep].x=curSt; + steps[nbStep].delta=stC; + nbStep++; + steps[nbStep].x=curEn; + steps[nbStep].delta=enC; + nbStep++; + steps[nbStep].x=curEn+1; + steps[nbStep].delta=needC-stC-enC; + nbStep++; + } + } else { + float stC=/*(int)ldexpf(*/0.5*tPente*(curStF+1-spos)*(curStF+1-spos)/*,24)*/; + float stFC=/*(int)ldexpf(*/tPente-0.5*tPente*(spos-curStF)*(spos-curStF)/*,24)*/; + float enC=/*(int)ldexpf(*/tPente-0.5*tPente*(curEnF+1.0-epos)*(curEnF+1.0-epos)/*,24)*/; + float miC=/*(int)ldexpf(*/tPente/*,24)*/; + if ( curSt < min ) { + if ( curEn > max ) { + if ( nbStep+(max-min) >= maxStep ) { + maxStep=2*nbStep+(max-min); + steps=(alpha_step*)g_realloc(steps,maxStep*sizeof(alpha_step)); + } + float bfd=min-curSt-1; + bfd*=miC; + before.delta+=stC+bfd; + for (int i=min;i= maxStep ) { + maxStep=2*nbStep+(curEn-min)+2; + steps=(alpha_step*)g_realloc(steps,maxStep*sizeof(alpha_step)); + } + float bfd=min-curSt-1; + bfd*=miC; + before.delta+=stC+bfd; + for (int i=min;i max ) { + if ( nbStep+3+(max-curSt) >= maxStep ) { + maxStep=2*nbStep+3+(curEn-curSt); + steps=(alpha_step*)g_realloc(steps,maxStep*sizeof(alpha_step)); + } + steps[nbStep].x=curSt; + steps[nbStep].delta=stC; + nbStep++; + steps[nbStep].x=curSt+1; + steps[nbStep].delta=stFC; + nbStep++; + for (int i=curSt+2;i= maxStep ) { + maxStep=2*nbStep+3+(curEn-curSt); + steps=(alpha_step*)g_realloc(steps,maxStep*sizeof(alpha_step)); + } + steps[nbStep].x=curSt; + steps[nbStep].delta=stC; + nbStep++; + steps[nbStep].x=curSt+1; + steps[nbStep].delta=stFC; + nbStep++; + for (int i=curSt+2;i max ) { + if ( eval < sval ) curMax=max; + return 0; // en dehors des limites (attention a ne pas faire ca avec curEn) + } + if ( curEn < min ) { + before.delta+=eval-sval; + return 0; // en dehors des limites (attention a ne pas faire ca avec curEn) + } + + if ( curSt < curMin ) curMin=curSt; +// int curEn=(int)curEnF; + if ( ceil(epos) > curMax-1 ) curMax=1+(int)ceil(epos); + if ( curSt < min ) { + before.delta+=eval-sval; + } else { + AddRun(curSt,/*(int)ldexpf(*/(((float)(curSt+1))-spos)*tPente/*,24)*/); + AddRun(curSt+1,/*(int)ldexpf(*/(spos-((float)(curSt)))*tPente/*,24)*/); + } + return 0; +} + +void AlphaLigne::Flatten(void) +{ + // just sort + if ( nbStep > 0 ) qsort(steps,nbStep,sizeof(alpha_step),CmpStep); +} +void AlphaLigne::AddRun(int st,float pente) +{ + if ( nbStep >= maxStep ) { + maxStep=2*nbStep+1; + steps=(alpha_step*)g_realloc(steps,maxStep*sizeof(alpha_step)); + } + int nStep=nbStep++; + steps[nStep].x=st; + steps[nStep].delta=pente; +} + +void AlphaLigne::Raster(raster_info &dest,void* color,RasterInRunFunc worker) +{ + // start by checking if there are actually pixels in need of rasterization + if ( curMax <= curMin ) return; + if ( dest.endPix <= curMin || dest.startPix >= curMax ) return; + + int nMin=curMin,nMax=curMax; + float alpSum=before.delta; // alpSum will be the pixel coverage value, so we start at before.delta + int curStep=0; + + // first add all the deltas up to the first pixel in need of rasterization + while ( curStep < nbStep && steps[curStep].x < nMin ) { + alpSum+=steps[curStep].delta; + curStep++; + } + // just in case, if the line bounds are greater than the buffer bounds. + if ( nMin < dest.startPix ) { + for (;( curStep < nbStep && steps[curStep].x < dest.startPix) ;curStep++) alpSum+=steps[curStep].delta; + nMin=dest.startPix; + } + if ( nMax > dest.endPix ) nMax=dest.endPix; + + // raster! + int curPos=dest.startPix; + for (;curStep 0 && steps[curStep].x > curPos ) { + // we're going to change the pixel position curPos, and alpSum is > 0: rasterization needed from + // the last position (curPos) up to the pixel we're moving to (steps[curStep].x) + int nst=curPos,nen=steps[curStep].x; +//Buffer::RasterRun(dest,color,nst,alpSum,nen,alpSum); + (worker)(dest,color,nst,alpSum,nen,alpSum); + } + // add coverage deltas + alpSum+=steps[curStep].delta; + curPos=steps[curStep].x; + if ( curPos >= nMax ) break; + } + // if we ended the line with alpSum > 0, we need to raster from curPos to the right edge + if ( alpSum > 0 && curPos < nMax ) { + int nst=curPos,nen=max; + (worker)(dest,color,nst,alpSum,nen,alpSum); +//Buffer::RasterRun(dest,color,nst,alpSum,nen,alpSum); + } +} diff --git a/src/livarot/AlphaLigne.h b/src/livarot/AlphaLigne.h new file mode 100644 index 000000000..b2686f6ba --- /dev/null +++ b/src/livarot/AlphaLigne.h @@ -0,0 +1,90 @@ +/* + * AlphaLigne.h + * nlivarot + * + * Created by fred on Fri Jul 25 2003. + * public domain + * + */ + +#ifndef my_alpha_ligne +#define my_alpha_ligne + +#include +#include +#include +#include +//#include + +#include "LivarotDefs.h" + +/* + * pixel coverage of a line, libart style: each pixel coverage is obtained from the coverage of the previous one by + * adding a delta given by a step. the goal is to have only a limited number of positions where the delta != 0, so that + * you only have to store a limited number of steps. + */ + +// a step +typedef struct alpha_step { + int x; // position + float delta; // increase or decrease in pixel coverage with respect to the coverage of the previous pixel +} alpha_step; + + +class AlphaLigne { +public: + // bounds of the line + // necessary since the visible portion of the canvas is bounded, and you need to compute + // the value of the pixel "just before the visible portion of the line" + int min,max; + int length; + + // before is the step containing the delta relative to a pixel infinitely far on the left of the line + // thus the initial pixel coverage is before.delta + alpha_step before,after; + // array of steps + int nbStep,maxStep; + alpha_step* steps; + + // bounds of the portion of the line that has received some coverage + int curMin,curMax; + + // iMin and iMax are the bounds of the visible portion of the line + AlphaLigne(int iMin,int iMax); + ~AlphaLigne(void); + + // empties the line + void Reset(void); + + // add some coverage. + // pente is (eval-sval)/(epos-spos), because you can compute it once per edge, and thus spare the + // CPU some potentially costly divisions + int AddBord(float spos,float sval,float epos,float eval,float iPente); + // version where you don't have the pente parameter + int AddBord(float spos,float sval,float epos,float eval); + + // sorts the steps in increasing order. needed before you raster the line + void Flatten(void); + + // debug dump of the steps + void Affiche(void); + + // private + void AddRun(int st,float pente); + + // raster the line in the buffer given in "dest", with the rasterization primitive worker + // worker() is given the color parameter each time it is called. the type of the function is + // defined in LivarotDefs.h + void Raster(raster_info &dest,void* color,RasterInRunFunc worker); + + // also private. that's the comparison function given to qsort() + static int CmpStep(const void * p1, const void * p2) { + alpha_step* d1=(alpha_step*)p1; + alpha_step* d2=(alpha_step*)p2; + return d1->x - d2->x ; + }; +}; + + +#endif + diff --git a/src/livarot/BitLigne.cpp b/src/livarot/BitLigne.cpp new file mode 100644 index 000000000..52870f699 --- /dev/null +++ b/src/livarot/BitLigne.cpp @@ -0,0 +1,172 @@ +/* + * BitLigne.cpp + * nlivarot + * + * Created by fred on Wed Jul 23 2003. + * public domain + * + */ + +#include "BitLigne.h" + +#include +#include + +BitLigne::BitLigne(int ist,int ien,float iScale) +{ + scale=iScale; + invScale=1/iScale; + st=ist; + en=ien; + if ( en <= st ) en=st+1; + stBit=(int)floor(((float)st)*invScale); // round to pixel boundaries in the canvas + enBit=(int)ceil(((float)en)*invScale); + int nbBit=enBit-stBit; + if ( nbBit&31 ) { + nbInt=nbBit/32+1; + } else { + nbInt=nbBit/32; + } + nbInt+=1; + fullB=(uint32_t*)g_malloc(nbInt*sizeof(uint32_t)); + partB=(uint32_t*)g_malloc(nbInt*sizeof(uint32_t)); + + curMin=en; + curMax=st; +} +BitLigne::~BitLigne(void) +{ + g_free(fullB); + g_free(partB); +} + +void BitLigne::Reset(void) +{ + curMin=en; + curMax=st+1; + memset(fullB,0,nbInt*sizeof(uint32_t)); + memset(partB,0,nbInt*sizeof(uint32_t)); +} +int BitLigne::AddBord(float spos,float epos,bool full) +{ + if ( spos >= epos ) return 0; + + // separation of full and not entirely full bits is a bit useless + // the goal is to obtain a set of bits that are "on the edges" of the polygon, so that their coverage + // will be 1/2 on the average. in practice it's useless for anything but the even-odd fill rule + int ffBit,lfBit; // first and last bit of the portion of the line that is entirely covered + ffBit=(int)(ceil(invScale*spos)); + lfBit=(int)(floor(invScale*epos)); + int fpBit,lpBit; // first and last bit of the portion of the line that is not entirely but partially covered + fpBit=(int)(floor(invScale*spos)); + lpBit=(int)(ceil(invScale*epos)); + + // update curMin and curMax to reflect the start and end pixel that need to be updated on the canvas + if ( floor(spos) < curMin ) curMin=(int)floor(spos); + if ( ceil(epos) > curMax ) curMax=(int)ceil(epos); + + // clamp to the line + if ( ffBit < stBit ) ffBit=stBit; + if ( ffBit > enBit ) ffBit=enBit; + if ( lfBit < stBit ) lfBit=stBit; + if ( lfBit > enBit ) lfBit=enBit; + if ( fpBit < stBit ) fpBit=stBit; + if ( fpBit > enBit ) fpBit=enBit; + if ( lpBit < stBit ) lpBit=stBit; + if ( lpBit > enBit ) lpBit=enBit; + + // offset to get actual bit position in the array + ffBit-=stBit; + lfBit-=stBit; + fpBit-=stBit; + lpBit-=stBit; + + // get the end and start indices of the elements of fullB and partB that will receives coverage + int ffPos=ffBit>>5; + int lfPos=lfBit>>5; + int fpPos=fpBit>>5; + int lpPos=lpBit>>5; + // get bit numbers in the last and first changed elements of the fullB and partB arrays + int ffRem=ffBit&31; + int lfRem=lfBit&31; + int fpRem=fpBit&31; + int lpRem=lpBit&31; + // add the coverage + // note that the "full" bits are always a subset of the "not empty" bits, ie of the partial bits + // the function is a bit lame: since there is at most one bit that is partial but not full, or no full bit, + // it does 2 times the optimal amount of work when the coverage is full. but i'm too lazy to change that... + if ( fpPos == lpPos ) { // only one element of the arrays is modified + // compute the vector of changed bits in the element + uint32_t add=0xFFFFFFFF; + if ( lpRem < 32 ) {add>>=32-lpRem;add<<=32-lpRem; } + if ( lpRem <= 0 ) add=0; + if ( fpRem > 0) {add<<=fpRem;add>>=fpRem;} + // and put it in the line + fullB[fpPos]&=~(add); // partial is exclusive from full, so partial bits are removed from fullB + partB[fpPos]|=add; // and added to partB + if ( full ) { // if the coverage is full, add the vector of full bits + if ( ffBit <= lfBit ) { + add=0xFFFFFFFF; + if ( lfRem < 32 ) {add>>=32-lfRem;add<<=32-lfRem;} + if ( lfRem <= 0 ) add=0; + if ( ffRem > 0 ) {add<<=ffRem;add>>=ffRem;} + fullB[ffPos]|=add; + partB[ffPos]&=~(add); + } + } + } else { + // first and last elements are differents, so add what appropriate to each + uint32_t add=0xFFFFFFFF; + if ( fpRem > 0 ) {add<<=fpRem;add>>=fpRem;} + fullB[fpPos]&=~(add); + partB[fpPos]|=add; + + add=0xFFFFFFFF; + if ( lpRem < 32 ) {add>>=32-lpRem;add<<=32-lpRem;} + if ( lpRem <= 0 ) add=0; + fullB[lpPos]&=~(add); + partB[lpPos]|=add; + + // and fill what's in between with partial bits + if ( lpPos > fpPos+1 ) memset(fullB+(fpPos+1),0x00,(lpPos-fpPos-1)*sizeof(uint32_t)); + if ( lpPos > fpPos+1 ) memset(partB+(fpPos+1),0xFF,(lpPos-fpPos-1)*sizeof(uint32_t)); + + if ( full ) { // is the coverage is full, do your magic + if ( ffBit <= lfBit ) { + if ( ffPos == lfPos ) { + add=0xFFFFFFFF; + if ( lfRem < 32 ) {add>>=32-lfRem;add<<=32-lfRem;} + if ( lfRem <= 0 ) add=0; + if ( ffRem > 0 ) {add<<=ffRem;add>>=ffRem;} + fullB[ffPos]|=add; + partB[ffPos]&=~(add); + } else { + add=0xFFFFFFFF; + if ( ffRem > 0 ) {add<<=ffRem;add>>=ffRem;} + fullB[ffPos]|=add; + partB[ffPos]&=~add; + + add=0xFFFFFFFF; + if ( lfRem < 32 ) {add>>=32-lfRem;add<<=32-lfRem;} + if ( lfRem <= 0 ) add=0; + fullB[lfPos]|=add; + partB[lfPos]&=~add; + + if ( lfPos > ffPos+1 ) memset(fullB+(ffPos+1),0xFF,(lfPos-ffPos-1)*sizeof(uint32_t)); + if ( lfPos > ffPos+1 ) memset(partB+(ffPos+1),0x00,(lfPos-ffPos-1)*sizeof(uint32_t)); + } + } + } + } + return 0; +} + + +void BitLigne::Affiche(void) +{ + for (int i=0;i +#include +#include +#include + +#include "LivarotDefs.h" + +/* + * a line of bits used for rasterizations of polygons + * the Scan() and QuickScan() functions fill the line with bits; after that you can use the Copy() function + * of the IntLigne class to have a set of pixel coverage runs + */ + +class BitLigne { +public: + // start and end pixels of the line + int st,en; + // start and end bits of the line + int stBit,enBit; + // size of the fullB and partB arrays + int nbInt; + // arrays of uint32_t used to store the bits + // bits of fullB mean "this pixel/bit is entirely covered" + // bits of partB mean "this pixel/bit is not entirely covered" (a better use would be: "this pixel is at least partially covered) + // so it's in fact a triage mask + uint32_t* fullB; + uint32_t* partB; + + // when adding bits, these 2 values are updated to reflect which portion of the line has received coverage + int curMin,curMax; + // invScale is: canvas -> bit in the line + // scale is: bit -> canvas, ie the size (width) of a bit + float scale,invScale; + + BitLigne(int ist,int ien,float iScale=0.25); // default scale is 1/4 for 4x4 supersampling + ~BitLigne(void); + + // reset the line to full empty + void Reset(void); + + // put coverage from spos to epos (in canvas coordinates) + // full==true means that the bits from (fractional) position spos to epos are entirely covered + // full==false means the bits are not entirely covered, ie this is an edge + // see the Scan() and AvanceEdge() functions to see the difference + int AddBord(float spos,float epos,bool full); + + // debug dump + void Affiche(void); + +}; + +#endif + + diff --git a/src/livarot/Livarot.h b/src/livarot/Livarot.h new file mode 100644 index 000000000..0218e0127 --- /dev/null +++ b/src/livarot/Livarot.h @@ -0,0 +1,34 @@ +/* + * Livarot.h + * nlivarot + * + * Created by fred on Sun Jul 27 2003. + * + */ + +#include "LivarotDefs.h" + +#include "Shape.h" +#include "Path.h" +#include "Buffer.h" + +#include "Ligne.h" +#include "AlphaLigne.h" +#include "BitLigne.h" + +#include "Bounding.h" +#include "Region.h" + +#include "VoronoiGraph.h" +#include "VoronoiConstr.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:encoding=utf-8:textwidth=99 : diff --git a/src/livarot/LivarotDefs.h b/src/livarot/LivarotDefs.h new file mode 100644 index 000000000..bdb50b563 --- /dev/null +++ b/src/livarot/LivarotDefs.h @@ -0,0 +1,170 @@ +/* + * LivarotDefs.h + * nlivarot + * + * Created by fred on Tue Jun 17 2003. + * + */ + +#ifndef my_defs +#define my_defs +#include + +// error codes (mostly obsolete) +enum +{ + avl_no_err = 0, // 0 is the error code for "everything OK" + avl_bal_err = 1, + avl_rm_err = 2, + avl_ins_err = 3, + shape_euler_err = 4, // computations result in a non-eulerian graph, thus the function cannot do a proper polygon + // despite the rounding sheme, this still happen with uber-complex graphs + // note that coordinates are stored in double => double precision for the computation is not even + // enough to get exact results (need quadruple precision, i think). + shape_input_err = 5 // the function was given an incorrect input (not a polygon, or not eulerian) +}; + +// return codes for the find function in the AVL tree (private) +enum +{ + not_found = 0, + found_exact = 1, + found_on_left = 2, + found_on_right = 3, + found_between = 4 +}; + +// boolean operation +enum bool_op +{ + bool_op_union, // A OR B + bool_op_inters, // A AND B + bool_op_diff, // A \ B + bool_op_symdiff, // A XOR B + bool_op_cut, // coupure (pleines) + bool_op_slice // coupure (contour) +}; +typedef enum bool_op BooleanOp; + +// types of cap for stroking polylines +enum butt_typ +{ + butt_straight, // straight line + butt_square, // half square + butt_round, // half circle + butt_pointy // a little pointy hat +}; +// types of joins for stroking paths +enum join_typ +{ + join_straight, // a straight line + join_round, // arc of circle (in fact, one or two quadratic bezier curve chunks) + join_pointy // a miter join (uses the miter parameter) +}; +typedef enum butt_typ ButtType; +typedef enum join_typ JoinType; + +enum fill_typ +{ + fill_oddEven = 0, + fill_nonZero = 1, + fill_positive = 2, + fill_justDont = 3 +}; +typedef enum fill_typ FillRule; + +// stupid version of dashes: in dash x is plain, dash x+1 must be empty, so the gap field is extremely redundant +typedef struct one_dash +{ + bool gap; + double length; +} +one_dash; + +// color definition structures for the rasterizations primitives (not present here) +typedef struct std_color +{ + uint32_t uCol; + uint16_t iColA, iColR, iColG, iColB; + double fColA, fColR, fColG, fColB; + uint32_t iColATab[256]; +} +std_color; + +typedef struct grad_stop +{ + double at; + double ca, cr, cg, cb; + double iSize; +} +grad_stop; + +// linear gradient for filling polygons +typedef struct lin_grad +{ + int type; // 0= gradient appears once + // 1= repeats itself start-end/start-end/start-end... + // 2= repeats itself start-end/end-start/start-end... + double u, v, w; // u*x+v*y+w = position in the gradient (clipped to [0;1]) +// double caa,car,cag,cab; // color at gradient position 0 +// double cba,cbr,cbg,cbb; // color at gradient position 1 + int nbStop; + grad_stop stops[2]; +} +lin_grad; + +// radial gradient (color is funciton of r^2, need to be corrected with a sqrt() to be r) +typedef struct rad_grad +{ + int type; // 0= gradient appears once + // 1= repeats itself start-end/start-end/start-end... + // 2= repeats itself start-end/end-start/start-end... + double mh, mv; // center + double rxx, rxy, ryx, ryy; // 1/radius + int nbStop; + grad_stop stops[2]; +} +rad_grad; + +// functions types for an arbitrary filling shader +typedef void (*InitColorFunc) (int ph, int pv, void *); // init for position ph,pv; the last parameter is a pointer + // on the gen_color structure +typedef void (*NextPixelColorFunc) (void *); // go to next pixel and update the color +typedef void (*NextLigneColorFunc) (void *); // go to next line (the h-coordinate must be the ph passed in + // the InitColorFunc) +typedef void (*GotoPixelColorFunc) (int ph, void *); // move to h-coordinate ph +typedef void (*GotoLigneColorFunc) (int pv, void *); // move to v-coordinate pv (the h-coordinate must be the ph passed + // in the InitColorFunc) + +// an arbitrary shader +typedef struct gen_color +{ + double colA, colR, colG, colB; + InitColorFunc iFunc; + NextPixelColorFunc npFunc; + NextLigneColorFunc nlFunc; + GotoPixelColorFunc gpFunc; + GotoLigneColorFunc glFunc; +} +gen_color; + +// info for a run of pixel to fill +typedef struct raster_info { + int startPix,endPix; // start and end pixel from the polygon POV + int sth,stv; // coordinates for the first pixel in the run, in (possibly another) POV + uint32_t* buffer; // pointer to the first pixel in the run +} raster_info; +typedef void (*RasterInRunFunc) (raster_info &dest,void *data,int nst,float vst,int nen,float ven); // init for position ph,pv; the last parameter is a pointer + + +enum Side { + LEFT = 0, + RIGHT = 1 +}; + +enum FirstOrLast { + FIRST = 0, + LAST = 1 +}; + +#endif diff --git a/src/livarot/Makefile_insert b/src/livarot/Makefile_insert new file mode 100644 index 000000000..6982d0a98 --- /dev/null +++ b/src/livarot/Makefile_insert @@ -0,0 +1,45 @@ +## Makefile.am fragment sourced by src/Makefile.am. + +livarot/all: livarot/libvarot.a + +livarot/clean: + rm -f livarot/libvarot.a $(livarot_libvarot_a_OBJECTS) + +livarot_libvarot_a_SOURCES = \ + livarot/AVL.cpp \ + livarot/AVL.h \ + livarot/AlphaLigne.cpp \ + livarot/AlphaLigne.h \ + livarot/BitLigne.cpp \ + livarot/BitLigne.h \ + livarot/float-line.cpp \ + livarot/float-line.h \ + livarot/int-line.cpp \ + livarot/int-line.h \ + livarot/LivarotDefs.h \ + livarot/MyMath.h \ + livarot/MySeg.cpp \ + livarot/MySeg.h \ + livarot/Path.cpp \ + livarot/Path.h \ + livarot/PathConversion.cpp \ + livarot/PathCutting.cpp \ + livarot/PathOutline.cpp \ + livarot/PathSimplify.cpp \ + livarot/PathStroke.cpp \ + livarot/Shape.cpp \ + livarot/Shape.h \ + livarot/ShapeDraw.cpp \ + livarot/ShapeMisc.cpp \ + livarot/ShapeRaster.cpp \ + livarot/ShapeSweep.cpp \ + livarot/sweep-tree-list.cpp \ + livarot/sweep-tree-list.h \ + livarot/sweep-tree.cpp \ + livarot/sweep-tree.h \ + livarot/sweep-event.cpp \ + livarot/sweep-event.h \ + livarot/sweep-event-queue.h \ + livarot/livarot-forward.h \ + livarot/path-description.h \ + livarot/path-description.cpp diff --git a/src/livarot/MyMath.h b/src/livarot/MyMath.h new file mode 100644 index 000000000..27e8089ec --- /dev/null +++ b/src/livarot/MyMath.h @@ -0,0 +1,281 @@ +/* + * MyMath.h + * nlivarot + * + * Created by fred on Wed Jun 18 2003. + * + */ + +#ifndef my_math +#define my_math + +#include +#include +#include +#include +//#include + + +typedef struct vec2 +{ + double x, y; +} vec2; + + +typedef struct mat2 +{ + double xx, xy, yx, yy; +} mat2; + + +typedef struct vec2d +{ + double x, y; +} vec2d; + + +typedef struct mat2d +{ + double xx, xy, yx, yy; +} mat2d; + + +#define RotCCW(a) {\ + double t = (a).x;\ + (a).x = (a).y;\ + (a).y = -t;\ +} + +#define RotCCWTo(a,d) {\ + (d).x = (a).y;\ + (d).y = -(a).x;\ +} + +#define RotCW(a) {\ + double t = (a).x;\ + (a).x = -(a).y;\ + (a).y = t;\ +} + +#define RotCWTo(a,d) {\ + (d).x = -(a).y;\ + (d).y = (a).x;\ +} + +#define Normalize(a) { \ + double _le = (a).x*(a).x+(a).y*(a).y; \ + if ( _le > 0.0001 ) { \ + _le = 1.0 / sqrt(_le); \ + (a).x *= _le; \ + (a).y *= _le; \ + } \ +} + +#define L_VEC_Set(a,u,v) { \ + a.x = u; \ + a.y = v; \ +} + + +#define L_VEC_Length(a,l) { \ + l = sqrt(a.x*a.x+a.y*a.y); \ +} + +#define L_VEC_Add(a,b,r) { \ + r.x = a.x+b.x; \ + r.y = a.y+b.y; \ +} + +#define L_VEC_Sub(a,b,r) { \ + r.x = a.x-b.x; \ + r.y = a.y-b.y; \ +} + +#define L_VEC_Mul(a,b,r) { \ + r.x = a.x*b.x; \ + r.y = a.y*b.y; \ +} + +#define L_VEC_Div(a,b,r) { \ + r.x = a.x/b.x; \ + r.y = a.y/b.y; \ +} + +#define L_VEC_AddMul(a,b,c,r) { \ + r.x = a.x+b.x*c.x; \ + r.y = a.y+b.y*c.y; \ +} + +#define L_VEC_SubMul(a,b,c,r) { \ + r.x = a.x-b.x*c.x; \ + r.y = a.y-b.y*c.y; \ +} + + +#define L_VEC_MulC(a,b,r) { \ + r.x = a.x*(b); \ + r.y = a.y*(b); \ +} + +#define L_VEC_DivC(a,b,r) { \ + r.x = a.x/(b); \ + r.y = a.y/(b); \ +} + +#define L_VEC_AddMulC(a,b,c,r) { \ + r.x = a.x+b.x*c; \ + r.y = a.y+b.y*c; \ +} + +#define L_VEC_SubMulC(a,b,c,r) { \ + r.x = a.x-b.x*c; \ + r.y = a.y-b.y*c; \ +} + +#define L_VEC_Cmp(a,b) ((fabs(a.y-b.y)<0.0000001)? \ + ((fabs(a.x-b.x)<0.0000001)?0:((a.x > b.x)?1:-1)): \ + ((a.y > b.y)?1:-1)) + +#define L_VAL_Cmp(a,b) ((fabs(a-b)<0.0000001)?0:((a>b)?1:-1)) + +#define L_VEC_Normalize(d) { \ + double l=sqrt(d.x*d.x+d.y*d.y); \ + if ( l < 0.00000001 ) { \ + d.x=d.y=0; \ + } else { \ + d.x/=l; \ + d.y/=l; \ + } \ +} + +#define L_VEC_Distance(a,b,d) { \ + double dx = a.x-b.x; \ + double dy = a.y-b.y; \ + d = sqrt(dx*dx + dy*dy); \ +} + +#define L_VEC_Neg(d) { \ + d.x=d.x; d.y=-d.y; \ +} + +#define L_VEC_RotCW(d) { \ + double t=d.x; d.x=d.y; d.y=-t; \ +} \ + +#define L_VEC_RotCCW(d) { \ + double t=d.x; d.x=-d.y; d.y=t; \ +} + +#define L_VAL_Zero(a) ((fabs(a)<0.00000001)?0:((a>0)?1:-1)) + +#define L_VEC_Cross(a,b,r) { \ + r = a.x*b.x+a.y*b.y; \ +} + +#define L_VEC_Dot(a,b,r) { \ + r = a.x*b.y-a.y*b.x; \ +} + + +#define L_MAT(m,a,b) { \ + c[0][0].Set(ica.x); c[0][1].Set(icb.x); c[1][0].Set(ica.y); c[1][1].Set(icb.y); \ +} + +#define L_MAT_Set(m,a00,a10,a01,a11) {m.xx = a00; m.xy = a01; m.yx = a10; m.yy = a11;} + +#define L_MAT_SetC(m,a,b) {m.xx = a.x; m.xy = b.x; m.yx = a.y; m.yy = b.y;} + +#define L_MAT_SetL(m,a,b) {m.xx = a.x; m.xy = a.y;m.yx = b.x; m.yy = b.y;} + +#define L_MAT_Init(m) {m.xx=m.xy=m.yx=m.yy=0;} + +#define L_MAT_Col(m,no,r) { \ + if ( no == 0 ) { \ + r.x = m.xx; \ + r.y = m.yx; \ + } \ + if ( no == 0 ) { \ + r.x = m.xy; \ + r.y = m.yy; \ + } \ +} + +#define L_MAT_Row(m,no,r) { \ + if ( no == 0 ) { \ + r.x = m.xx; \ + r.y = m.xy; \ + } \ + if ( no == 0 ) { \ + r.x = m.yx; \ + r.y = m.yy; \ + } \ +} + +#define L_MAT_Det(m,d) {d=m.xx*m.yy-m.xy*m.yx;} + +#define L_MAT_Neg(m) {m.xx=-m.xx; m.xy=-m.xy; m.yx=-m.yx; m.yy=-m.yy;} + +#define L_MAT_Trs(m) {double t=m.xy; m.xy=m.yx; m.yx=t;} + +#define L_MAT_Inv(m) { \ + double d; \ + L_MAT_Det(m,d); \ + m.yx =- m.yx; \ + m.xy =- m.xy; \ + double t=m.xx;m.xx=m.yy;m.yy=t; \ + double inv_d = 1.0/d; \ + m.xx *= inv_d; \ + m.xy *= inv_d; \ + m.yx *= inv_d; \ + m.yy *= inv_d; \ +} + +#define L_MAT_Cof(m) { \ + m.yx =- m.yx; \ + m.xy =- m.xy; \ + double t=m.xx; m.xx=m.yy; m.yy=t; \ +} + +#define L_MAT_Add(u,v,m) { \ + m.xx=u.xx+v.xx; m.xy=u.xy+v.xy; m.yx=u.yx+v.yx; m.yy=u.yy+v.yy; \ +} + +#define L_MAT_Sub(u,v,m) { \ + m.xx=u.xx-v.xx; m.xy=u.xy-v.xy; m.yx=u.yx-v.yx; m.yy=u.yy-v.yy; \ +} + +#define L_MAT_Mul(u,v,m) { \ + mat2d r; \ + r.xx = u.xx*v.xx+u.xy*v.yx; \ + r.yx = u.yx*v.xx+u.yy*y.yx; \ + r.xy = u.xx*v.xy+u.xy*v.yy; \ + r.yy = u.yx*v.xy+u.yy*v.yy; \ + m=r; \ +} + +#define L_MAT_MulC(u,v,m) { \ + m.xx=u.xx*v; m.xy=u.xy*v; m.yx=u.yx*v; m.yy=u.yy*v; \ +} + +#define L_MAT_DivC(u,v,m) { \ + double iv = 1.0/v; \ + m.xx = u.xx*iv; m.xy=u.xy*iv; m.yx=u.yx*iv; m.yy=u.yy*iv; \ +} + +#define L_MAT_MulV(m,v,r) { \ + vec2d t; \ + t.x = m.xx*v.x+m.xy*v.y; \ + t.y = m.yx*v.x+m.yy*v.y; \ + r=t; \ +} + +#define L_MAT_TMulV(m,v,r) { \ + vec2d t; \ + t.x = m.xx*v.x+m.yx*v.y; \ + t.y = m.xy*v.x+m.yy*v.y; \ + r=t; \ +} + + + +#endif diff --git a/src/livarot/MySeg.cpp b/src/livarot/MySeg.cpp new file mode 100644 index 000000000..4a2d58dfd --- /dev/null +++ b/src/livarot/MySeg.cpp @@ -0,0 +1,867 @@ +/* + * MySeg.cpp + * nlivarot + * + * Created by fred on Wed Nov 12 2003. + * Copyright (c) 2003 __MyCompanyName__. All rights reserved. + * + */ + +#include "MySeg.h" +#include + +void +L_SEG::Distance (L_SEG & is, double &di, int mode) +{ + if (mode == inters_seg_seg) + { + double ms, me, os, oe; + + vec2d en = is.p; + L_VEC_Add (en, is.d, en); + + Distance (is.p, os, inters_seg_pt); + Distance (en, oe, inters_seg_pt); + + en = p; + L_VEC_Add (en, d, en); + + is.Distance (p, ms, inters_orseg_pt); + is.Distance (en, me, inters_orseg_pt); + if (L_VAL_Zero (ms) < 0 || L_VAL_Zero (me) < 0) + { + di = 1000000; + return; + } + if (L_VAL_Cmp (oe, os) < 0) + os = oe; + if (L_VAL_Cmp (me, ms) < 0) + ms = me; + if (L_VAL_Cmp (ms, os) < 0) + os = ms; + di = os; + } + else if (mode == inters_seg_dmd) + { + } + else if (mode == inters_seg_dr) + { + } +} + +void +L_SEG::Distance (vec2d & iv, double &di, int mode) +{ + if (L_VAL_Zero (d.x) == 0 && L_VAL_Zero (d.y) == 0) + { + L_VEC_Distance (p, iv, di); + return; + } + double dd, sqd; + vec2d nd = d; + L_VEC_RotCW (nd); + L_VEC_Cross (nd, nd, dd); + sqd = sqrt (dd); + vec2d diff = iv; + L_VEC_Sub (diff, p, diff); + if (mode == inters_dr_pt) + { + double cp; + L_VEC_Cross (diff, nd, cp); + di = cp / sqd; + if (di < 0) + di = -di; + } + else if (mode == inters_dmd_pt) + { + double cp; + L_VEC_Cross (diff, d, cp); + if (cp < 0) + { + L_VEC_Distance (p, iv, di); + return; + } + L_VEC_Cross (diff, nd, cp); + di = cp / sqd; + if (di < 0) + di = -di; + } + else if (mode == inters_seg_pt) + { + double cp; + L_VEC_Cross (diff, d, cp); + if (cp < 0) + { + L_VEC_Distance (p, iv, di); + return; + } + if (cp > dd) + { + vec2d se = p; + L_VEC_Add (se, d, se); + L_VEC_Distance (se, iv, di); + return; + } + L_VEC_Cross (diff, nd, cp); + di = cp / sqd; + if (di < 0) + di = -di; + } + else if (mode == inters_orseg_pt) + { + double cp; + L_VEC_Cross (diff, d, cp); + if (cp < 0) + { + L_VEC_Distance (p, iv, di); + L_VEC_Dot (diff, d, cp); + if (L_VAL_Zero (cp) < 0) + di = -di; + return; + } + if (cp > dd) + { + vec2d se = p; + L_VEC_Add (se, d, se); + L_VEC_Distance (se, iv, di); + + L_VEC_Dot (diff, d, cp); + if (cp < 0) + di = -di; + return; + } + L_VEC_Cross (diff, nd, cp); + di = cp / sqd; +// if ( diL_VAL_Zero() < 0 ) di.Neg(); + } +} + +int +L_SEG::Intersect (L_SEG & iu, L_SEG & iv, int mode) +{ + double iudd, ivdd; + L_VEC_Cross (iu.d, iu.d, iudd); + L_VEC_Cross (iv.d, iv.d, ivdd); + if (L_VAL_Zero (iudd) <= 0) + return 0; // cas illicite + if (L_VAL_Zero (ivdd) <= 0) + return 0; // cas illicite + + vec2d usvs, uevs, usve, ueve; + L_VEC_Sub (iv.p, iu.p, usvs); + L_VEC_Sub (usvs, iu.d, uevs); + L_VEC_Add (usvs, iv.d, usve); + L_VEC_Sub (usve, iu.d, ueve); + double usvsl, uevsl, usvel, uevel; + L_VEC_Cross (usvs, usvs, usvsl); + L_VEC_Cross (uevs, uevs, uevsl); + L_VEC_Cross (usve, usve, usvel); + L_VEC_Cross (ueve, ueve, uevel); + + double dd; + L_VEC_Cross (iu.d, iv.d, dd); + + if (L_VAL_Zero (usvsl) <= 0) + { + if (mode == inters_dr_dr || mode == inters_dmd_dr + || mode == inters_seg_dr) + { + return inters_colinear + inters_a_st + inters_b_st; + } + else if (mode == inters_dmd_dmd || mode == inters_seg_dmd + || mode == inters_seg_seg) + { + if (L_VAL_Zero (dd) > 0) + { + return inters_colinear + inters_a_st + inters_b_st; + } + else + { + return inters_a_st + inters_b_st; + } + } + return 0; + } + if (L_VAL_Zero (uevsl) <= 0) + { + if (mode == inters_dr_dr || mode == inters_dmd_dr + || mode == inters_seg_dr) + { + return inters_colinear + inters_a_en + inters_b_st; + } + else if (mode == inters_dmd_dmd) + { + return inters_colinear + inters_a_en + inters_b_st; + } + else if (mode == inters_seg_dmd || mode == inters_seg_seg) + { + if (L_VAL_Zero (dd) > 0) + { + return inters_a_en + inters_b_st; + } + else + { + return inters_colinear + inters_a_en + inters_b_st; + } + } + return 0; + } + if (L_VAL_Zero (usvel) <= 0) + { + if (mode == inters_dr_dr || mode == inters_dmd_dr + || mode == inters_seg_dr) + { + return inters_colinear + inters_a_st + inters_b_en; + } + else if (mode == inters_dmd_dmd || mode == inters_seg_dmd) + { + return inters_colinear + inters_a_st + inters_b_en; + } + else if (mode == inters_seg_seg) + { + if (L_VAL_Zero (dd) > 0) + { + return inters_a_st + inters_b_en; + } + else + { + return inters_colinear + inters_a_st + inters_b_en; + } + } + return 0; + } + if (L_VAL_Zero (uevel) <= 0) + { + if (mode == inters_dr_dr || mode == inters_dmd_dr + || mode == inters_seg_dr) + { + return inters_colinear + inters_a_en + inters_b_en; + } + else if (mode == inters_dmd_dmd || mode == inters_seg_dmd) + { + return inters_colinear + inters_a_en + inters_b_en; + } + else if (mode == inters_seg_seg) + { + if (L_VAL_Zero (dd) > 0) + { + return inters_colinear + inters_a_en + inters_b_en; + } + else + { + return inters_a_en + inters_b_en; + } + } + return 0; + } + + // plus d'extremites en commun a partir de ce point + + mat2d m; + L_MAT_SetC (m, iu.d, iv.d); + double det; + L_MAT_Det (m, det); + + if (L_VAL_Zero (det) == 0) + { // ces couillons de vecteurs sont colineaires + vec2d iudp; + iudp.x = iu.d.y; + iudp.y = -iu.d.x; + double dist; + L_VEC_Cross (iudp, usvs, dist); + if (L_VAL_Zero (dist) == 0) + { + if (mode == inters_dr_dr || mode == inters_dmd_dr + || mode == inters_seg_dr) + { + return inters_colinear; + } + else if (mode == inters_dmd_dmd) + { + if (L_VAL_Zero (dd) > 0) + return inters_colinear; + double ts; + L_VEC_Cross (iu.d, usvs, ts); + if (L_VAL_Zero (ts) > 0) + return inters_colinear; + return 0; + } + else if (mode == inters_seg_dmd) + { + if (L_VAL_Zero (dd) > 0) + { + double ts; + L_VEC_Cross (iv.d, uevs, ts); + if (L_VAL_Zero (ts) < 0) + return inters_colinear; + return 0; + } + else + { + double ts; + L_VEC_Cross (iv.d, usvs, ts); + if (L_VAL_Zero (ts) < 0) + return inters_colinear; + return 0; + } + } + else if (mode == inters_seg_seg) + { + double ts, te; + L_VEC_Cross (iu.d, usvs, ts); + L_VEC_Cross (iu.d, uevs, te); + if (L_VAL_Zero (ts) > 0 && L_VAL_Zero (te) < 0) + return inters_colinear; + L_VEC_Cross (iu.d, usve, ts); + L_VEC_Cross (iu.d, ueve, te); + if (L_VAL_Zero (ts) > 0 && L_VAL_Zero (te) < 0) + return inters_colinear; + L_VEC_Cross (iv.d, usvs, ts); + L_VEC_Cross (iv.d, usve, te); + if (L_VAL_Zero (ts) < 0 && L_VAL_Zero (te) > 0) + return inters_colinear; + L_VEC_Cross (iv.d, uevs, ts); + L_VEC_Cross (iv.d, ueve, te); + if (L_VAL_Zero (ts) < 0 && L_VAL_Zero (te) > 0) + return inters_colinear; + return 0; + } + } + else + { + return 0; // paralleles + } + } + + // plus de colinearite ni d'extremites en commun + L_MAT_Inv (m); + vec2d res; + L_MAT_MulV (m, usvs, res); + + if (mode == inters_dr_dr) + { + return inters_a_mi + inters_b_mi; + } + else if (mode == inters_dmd_dr) + { + int i = L_VAL_Zero (res.x); + if (i == 0) + return inters_a_st + inters_b_mi; + if (i > 0) + return inters_a_mi + inters_b_mi; + return 0; + } + else if (mode == inters_seg_dr) + { + int i = L_VAL_Zero (res.x); + int j = L_VAL_Cmp (res.x, 1); + if (i == 0) + return inters_a_st + inters_b_mi; + if (j == 0) + return inters_a_en + inters_b_mi; + if (i > 0 && j < 0) + return inters_a_mi + inters_b_mi; + return 0; + } + else if (mode == inters_dmd_dmd) + { + int i = L_VAL_Zero (res.x); + int j = -(L_VAL_Zero (res.y)); + // nota : i=0 et j=0 a ete elimine au debut + if (i == 0 && j > 0) + return inters_a_st + inters_b_mi; + if (j == 0 && i > 0) + return inters_a_mi + inters_b_st; + if (i > 0 && j > 0) + return inters_a_mi + inters_b_mi; + return 0; + } + else if (mode == inters_seg_dmd) + { + int i = L_VAL_Zero (res.x); + int j = L_VAL_Cmp (res.x, 1); + int k = -(L_VAL_Zero (res.y)); + // nota : i=0 et j=0 a ete elimine au debut + if (i == 0 && k > 0) + return inters_a_st + inters_b_mi; + if (j == 0 && k > 0) + return inters_a_en + inters_b_mi; + if (i > 0 && j < 0 && k == 0) + return inters_a_mi + inters_b_st; + if (i > 0 && j < 0 && k > 0) + return inters_a_mi + inters_b_mi; + return 0; + } + else if (mode == inters_seg_seg) + { + int i = L_VAL_Zero (res.x); + int j = L_VAL_Cmp (res.x, 1); + int k = -(L_VAL_Zero (res.y)); + int l = -(L_VAL_Cmp (res.y, 1)); + // nota : i=0 et j=0 a ete elimine au debut + if (i == 0 && k > 0 && l < 0) + return inters_a_st + inters_b_mi; + if (j == 0 && k > 0 && l < 0) + return inters_a_en + inters_b_mi; + if (k == 0 && i > 0 && j < 0) + return inters_a_mi + inters_b_st; + if (l == 0 && i > 0 && j < 0) + return inters_a_mi + inters_b_en; + if (k > 0 && l < 0 && i > 0 && j < 0) + return inters_a_mi + inters_b_mi; + return 0; + } + + return 0; +} + +int +L_SEG::Intersect (L_SEG & iu, L_SEG & iv, vec2d & at, int mode) +{ + double iudd, ivdd; + L_VEC_Cross (iu.d, iu.d, iudd); + L_VEC_Cross (iv.d, iv.d, ivdd); + if (L_VAL_Zero (iudd) <= 0) + return 0; // cas illicite + if (L_VAL_Zero (ivdd) <= 0) + return 0; // cas illicite + + vec2d usvs, uevs, usve, ueve; + L_VEC_Sub (iv.p, iu.p, usvs); + L_VEC_Sub (usvs, iu.d, uevs); + L_VEC_Add (usvs, iv.d, usve); + L_VEC_Sub (usve, iu.d, ueve); + double usvsl, uevsl, usvel, uevel; + L_VEC_Cross (usvs, usvs, usvsl); + L_VEC_Cross (uevs, uevs, uevsl); + L_VEC_Cross (usve, usve, usvel); + L_VEC_Cross (ueve, ueve, uevel); + + double dd; + L_VEC_Cross (iu.d, iv.d, dd); + + if (L_VAL_Zero (usvsl) <= 0) + { + at = iu.p; + if (mode == inters_dr_dr || mode == inters_dmd_dr + || mode == inters_seg_dr) + { + return inters_colinear + inters_a_st + inters_b_st; + } + else if (mode == inters_dmd_dmd || mode == inters_seg_dmd + || mode == inters_seg_seg) + { + if (L_VAL_Zero (dd) > 0) + { + return inters_colinear + inters_a_st + inters_b_st; + } + else + { + return inters_a_st + inters_b_st; + } + } + return 0; + } + if (L_VAL_Zero (uevsl) <= 0) + { + at = iv.p; + if (mode == inters_dr_dr || mode == inters_dmd_dr + || mode == inters_seg_dr) + { + return inters_colinear + inters_a_en + inters_b_st; + } + else if (mode == inters_dmd_dmd) + { + return inters_colinear + inters_a_en + inters_b_st; + } + else if (mode == inters_seg_dmd || mode == inters_seg_seg) + { + if (L_VAL_Zero (dd) > 0) + { + return inters_a_en + inters_b_st; + } + else + { + return inters_colinear + inters_a_en + inters_b_st; + } + } + return 0; + } + if (L_VAL_Zero (usvel) <= 0) + { + at = iu.p; + if (mode == inters_dr_dr || mode == inters_dmd_dr + || mode == inters_seg_dr) + { + return inters_colinear + inters_a_st + inters_b_en; + } + else if (mode == inters_dmd_dmd || mode == inters_seg_dmd) + { + return inters_colinear + inters_a_st + inters_b_en; + } + else if (mode == inters_seg_seg) + { + if (L_VAL_Zero (dd) > 0) + { + return inters_a_st + inters_b_en; + } + else + { + return inters_colinear + inters_a_st + inters_b_en; + } + } + return 0; + } + if (L_VAL_Zero (uevel) <= 0) + { + at = iu.p; + L_VEC_Add (at, iu.d, at); + if (mode == inters_dr_dr || mode == inters_dmd_dr + || mode == inters_seg_dr) + { + return inters_colinear + inters_a_en + inters_b_en; + } + else if (mode == inters_dmd_dmd || mode == inters_seg_dmd) + { + return inters_colinear + inters_a_en + inters_b_en; + } + else if (mode == inters_seg_seg) + { + if (L_VAL_Zero (dd) > 0) + { + return inters_colinear + inters_a_en + inters_b_en; + } + else + { + return inters_a_en + inters_b_en; + } + } + return 0; + } + + // plus d'extremites en commun a partir de ce point + + mat2d m; + L_MAT_SetC (m, iu.d, iv.d); + double det; + L_MAT_Det (m, det); + + if (L_VAL_Zero (det) == 0) + { // ces couillons de vecteurs sont colineaires + vec2d iudp; + iudp.x = iu.d.y; + iudp.y = -iu.d.x; + double dist; + L_VEC_Cross (iudp, usvs, dist); + if (L_VAL_Zero (dist) == 0) + { + if (mode == inters_dr_dr || mode == inters_dmd_dr + || mode == inters_seg_dr) + { + return inters_colinear; + } + else if (mode == inters_dmd_dmd) + { + if (L_VAL_Zero (dd) > 0) + return inters_colinear; + double ts; + L_VEC_Cross (iu.d, usvs, ts); + if (L_VAL_Zero (ts) > 0) + return inters_colinear; + return 0; + } + else if (mode == inters_seg_dmd) + { + if (L_VAL_Zero (dd) > 0) + { + double ts; + L_VEC_Cross (iv.d, uevs, ts); + if (L_VAL_Zero (ts) < 0) + return inters_colinear; + return 0; + } + else + { + double ts; + L_VEC_Cross (iv.d, usvs, ts); + if (L_VAL_Zero (ts) < 0) + return inters_colinear; + return 0; + } + } + else if (mode == inters_seg_seg) + { + double ts, te; + L_VEC_Cross (iu.d, usvs, ts); + L_VEC_Cross (iu.d, uevs, te); + if (L_VAL_Zero (ts) > 0 && L_VAL_Zero (te) < 0) + return inters_colinear; + L_VEC_Cross (iu.d, usve, ts); + L_VEC_Cross (iu.d, ueve, te); + if (L_VAL_Zero (ts) > 0 && L_VAL_Zero (te) < 0) + return inters_colinear; + L_VEC_Cross (iv.d, usvs, ts); + L_VEC_Cross (iv.d, usve, te); + if (L_VAL_Zero (ts) < 0 && L_VAL_Zero (te) > 0) + return inters_colinear; + L_VEC_Cross (iv.d, uevs, ts); + L_VEC_Cross (iv.d, ueve, te); + if (L_VAL_Zero (ts) < 0 && L_VAL_Zero (te) > 0) + return inters_colinear; + return 0; + } + } + else + { + return 0; // paralleles + } + } + + // plus de colinearite ni d'extremites en commun + L_MAT_Inv (m); + vec2d res; + L_MAT_MulV (m, usvs, res); + + // l'intersection + L_VEC_MulC (iu.d, res.x, at); + L_VEC_Add (at, iu.p, at); + + if (mode == inters_dr_dr) + { + return inters_a_mi + inters_b_mi; + } + else if (mode == inters_dmd_dr) + { + int i = L_VAL_Zero (res.x); + if (i == 0) + return inters_a_st + inters_b_mi; + if (i > 0) + return inters_a_mi + inters_b_mi; + return 0; + } + else if (mode == inters_seg_dr) + { + int i = L_VAL_Zero (res.x); + int j = L_VAL_Cmp (res.x, 1); + if (i == 0) + return inters_a_st + inters_b_mi; + if (j == 0) + return inters_a_en + inters_b_mi; + if (i > 0 && j < 0) + return inters_a_mi + inters_b_mi; + return 0; + } + else if (mode == inters_dmd_dmd) + { + int i = L_VAL_Zero (res.x); + int j = -(L_VAL_Zero (res.y)); + // nota : i=0 et j=0 a ete elimine au debut + if (i == 0 && j > 0) + return inters_a_st + inters_b_mi; + if (j == 0 && i > 0) + return inters_a_mi + inters_b_st; + if (i > 0 && j > 0) + return inters_a_mi + inters_b_mi; + return 0; + } + else if (mode == inters_seg_dmd) + { + int i = L_VAL_Zero (res.x); + int j = L_VAL_Cmp (res.x, 1); + int k = -(L_VAL_Zero (res.y)); + // nota : i=0 et j=0 a ete elimine au debut + if (i == 0 && k > 0) + return inters_a_st + inters_b_mi; + if (j == 0 && k > 0) + return inters_a_en + inters_b_mi; + if (i > 0 && j < 0 && k == 0) + return inters_a_mi + inters_b_st; + if (i > 0 && j < 0 && k > 0) + return inters_a_mi + inters_b_mi; + return 0; + } + else if (mode == inters_seg_seg) + { + int i = L_VAL_Zero (res.x); + int j = L_VAL_Cmp (res.x, 1); + int k = -(L_VAL_Zero (res.y)); // la coordonnée sur iv est inversee + int l = -(L_VAL_Cmp (res.y, -1)); + // nota : i=0 et j=0 a ete elimine au debut + if (i == 0 && k > 0 && l < 0) + return inters_a_st + inters_b_mi; + if (j == 0 && k > 0 && l < 0) + return inters_a_en + inters_b_mi; + if (k == 0 && i > 0 && j < 0) + return inters_a_mi + inters_b_st; + if (l == 0 && i > 0 && j < 0) + return inters_a_mi + inters_b_en; + if (k > 0 && l < 0 && i > 0 && j < 0) + return inters_a_mi + inters_b_mi; + return 0; + } + + return 0; +} + +int +L_SEG::IntersectGeneral (L_SEG & iu, L_SEG & iv, vec2d & at, int mode) +{ + + vec2d usvs; + L_VEC_Sub (iv.p, iu.p, usvs); + + double dd; + L_VEC_Cross (iu.d, iv.d, dd); + + + mat2d m; + L_MAT_SetC (m, iu.d, iv.d); + double det; + L_MAT_Det (m, det); + + if (L_VAL_Zero (det)) + { // ces couillons de vecteurs sont colineaires + return 0; // paralleles + } + + // plus de colinearite ni d'extremites en commun + L_MAT_Inv (m); + vec2d res; + L_MAT_MulV (m, usvs, res); + + // l'intersection + L_VEC_MulC (iu.d, res.x, at); + L_VEC_Add (at, iu.p, at); + + if (mode == inters_dr_dr) + { + return inters_a_mi + inters_b_mi; + } + else if (mode == inters_dmd_dr) + { + int i = L_VAL_Zero (res.x); + if (i == 0) + return inters_a_st + inters_b_mi; + if (i > 0) + return inters_a_mi + inters_b_mi; + return 0; + } + else if (mode == inters_seg_dr) + { + int i = L_VAL_Zero (res.x); + int j = L_VAL_Cmp (res.x, 1); + if (i == 0) + return inters_a_st + inters_b_mi; + if (j == 0) + return inters_a_en + inters_b_mi; + if (i > 0 && j < 0) + return inters_a_mi + inters_b_mi; + return 0; + } + else if (mode == inters_dmd_dmd) + { + int i = L_VAL_Zero (res.x); + int j = -(L_VAL_Zero (res.y)); + // nota : i=0 et j=0 a ete elimine au debut + if (i == 0 && j > 0) + return inters_a_st + inters_b_mi; + if (j == 0 && i > 0) + return inters_a_mi + inters_b_st; + if (i > 0 && j > 0) + return inters_a_mi + inters_b_mi; + return 0; + } + else if (mode == inters_seg_dmd) + { + int i = L_VAL_Zero (res.x); + int j = L_VAL_Cmp (res.x, 1); + int k = -(L_VAL_Zero (res.y)); + // nota : i=0 et j=0 a ete elimine au debut + if (i == 0 && k > 0) + return inters_a_st + inters_b_mi; + if (j == 0 && k > 0) + return inters_a_en + inters_b_mi; + if (i > 0 && j < 0 && k == 0) + return inters_a_mi + inters_b_st; + if (i > 0 && j < 0 && k > 0) + return inters_a_mi + inters_b_mi; + return 0; + } + else if (mode == inters_seg_seg) + { + int i = L_VAL_Zero (res.x); + int j = L_VAL_Cmp (res.x, 1); + int k = -(L_VAL_Zero (res.y)); // la coordonnée sur iv est inversee + int l = -(L_VAL_Cmp (res.y, -1)); + // nota : i=0 et j=0 a ete elimine au debut + if (i == 0 && k > 0 && l < 0) + return inters_a_st + inters_b_mi; + if (j == 0 && k > 0 && l < 0) + return inters_a_en + inters_b_mi; + if (k == 0 && i > 0 && j < 0) + return inters_a_mi + inters_b_st; + if (l == 0 && i > 0 && j < 0) + return inters_a_mi + inters_b_en; + if (k > 0 && l < 0 && i > 0 && j < 0) + return inters_a_mi + inters_b_mi; + return 0; + } + + return 0; +} + +int +L_SEG::Contains (vec2d & pos, int mode) +{ + vec2d sp, ep; + L_VEC_Sub (pos, p, sp); + L_VEC_Sub (sp, d, ep); + double spl, epl; + L_VEC_Cross (sp, sp, spl); + L_VEC_Cross (ep, ep, epl); + if (L_VAL_Zero (spl) == 0) + { + if (mode == inters_dr_pt) + return inters_a_mi; + return inters_a_st; + } + if (L_VAL_Zero (epl) == 0) + { + if (mode == inters_dr_pt || mode == inters_dmd_pt) + return inters_a_mi; + return inters_a_en; + } + + vec2d perp = d; + L_VEC_RotCW (perp); + + double dd, ps; + L_VEC_Cross (d, d, dd); + L_VEC_Cross (perp, sp, ps); + if (L_VAL_Zero (ps) == 0) + { // sur la droite + if (mode == inters_dr_pt) + return inters_a_mi; + L_VEC_Cross (d, sp, ps); + // ps != 0 car le cas est traité avant + if (mode == inters_dmd_pt) + { + if (L_VAL_Zero (ps) > 0) + { + return inters_a_mi; + } + } + else + { + if (L_VAL_Zero (ps) > 0) + { + if (L_VAL_Cmp (ps, dd) < 0) + { + return inters_a_mi; + } + } + } + } + + return 0; +} diff --git a/src/livarot/MySeg.h b/src/livarot/MySeg.h new file mode 100644 index 000000000..8183b7d46 --- /dev/null +++ b/src/livarot/MySeg.h @@ -0,0 +1,147 @@ +/* + * MySeg.h + * nlivarot + * + * Created by fred on Wed Nov 12 2003. + * + */ + +#ifndef my_math_seg +#define my_math_seg + +#include "MyMath.h" + +// codes for the intersections computations +// pt = point +// seg = segment +// dmd = half line +// dr = infinite line +enum +{ + inters_seg_seg, // intersection between 2 segments + inters_seg_dmd, // intersection between one segment (parameter no 1) and one half-line (parameter no 2) + inters_seg_dr, // .... + inters_dmd_dmd, + inters_dmd_dr, + inters_dr_dr, + + inters_seg_pt, // "intersection" between segment and point= "does the segment contain the point?" + inters_dmd_pt, + inters_dr_pt, + + inters_orseg_pt // don't use +}; + +// return codes for the intersection computations; build as a concatenation of +// _a = first parameter +// _b = second parameter +// _st = start of the segment/half-line (lines don't have starts) +// _en = end of thz segment (half-lines and lines don't have ends) +// _mi = inside of the segment/half-line/line +// _colinear = this flag is set if the intersection of the 2 parameter is more than a point +// the first 2 bits of the return code contain the position of the intersection on the first parameter (_st, _mi or _en) +// the next 2 bits of the return code contain the position of the intersection on the second parameter (_st, _mi or _en) +// the 5th bit is set if the parameters are colinear +enum +{ + inters_a_st = 1, + inters_a_mi = 2, + inters_a_en = 3, + inters_b_st = 4, + inters_b_mi = 8, + inters_b_en = 12, + inters_colinear = 16 +}; + + +// +// a class to describe a segment: defined by its startpoint p and its direction d +// if the object is considered as a segment: p+xd, where x ranges from 0 to 1 +// if the object is considered as an half-line, the length of the direction vector doesn't matter: +// p+xd, where x ranges from 0 to +infinity +// if the object is considered as a line: p+xd, where x ranges from -infinity to +infinity +// +class L_SEG +{ +public: + vec2d p, d; + + // constructors + L_SEG (vec2d & st, vec2d & dir):p (st), d (dir) + { + }; // by default, you give one startpoint and one direction + L_SEG (void) + { + }; + ~L_SEG (void) + { + }; + + // assignations + void Set (L_SEG * s) + { + p = s->p; + d = s->d; + }; + void Set (L_SEG & s) + { + p = s.p; + d = s.d; + }; + // 2 specific assignations: + // assignation where you give the startpoint and the direction (like in the constructor): + void SetSD (vec2d & st, vec2d & dir) + { + p = st; + d = dir; + }; + // assignation where you give the startpoint and the endpoint: + void SetSE (vec2d & st, vec2d & en) + { + p = st; + d.x = en.x - st.x; + d.y = en.y - st.y; + }; + + // reverses the segment + void Rev (void) + { + p.x += d.x; + p.y += d.y; + d.x = -d.x; + d.y = -d.y; + }; + // transitibve version: the reversed segment is stored in s + void Rev (L_SEG & s) + { + s.p.x = p.x + d.x; + s.p.y = p.y + d.y; + s.d.x = -d.x; + s.d.y = -d.y; + }; + + // distance of the point iv to the segment/half-line/line + // the mode parameter specifies how the caller instance should be handled: + // inters_seg_pt : segment + // inters_dmd_pt : half-line + // inters_dr_pt : line + void Distance (vec2d & iv, double &d, int mode = inters_dr_pt); + // distance between 2 segments + // mode parameter specifies how the segments have to be treated (just like above) + void Distance (L_SEG & is, double &d, int mode = inters_seg_seg); + + // tests if the segment contains the point pos + // mode is as in the Distance function + int Contains (vec2d & pos, int mode); + + // intersection between 2 lines/half-lines/segments + // mode specifies how the L_SEG instances have to be considered; codes at the beginning of this file + // the "at" parameter stores the intersection point, if it exists and is unique + static int Intersect (L_SEG & iu, L_SEG & iv, int mode); + static int Intersect (L_SEG & iu, L_SEG & iv, vec2d & at, int mode); + // specific version, when you can garantuee the colinearity case won't occur + static int IntersectGeneral (L_SEG & iu, L_SEG & iv, vec2d & at, int mode); +}; + + +#endif diff --git a/src/livarot/Path.cpp b/src/livarot/Path.cpp new file mode 100644 index 000000000..32c100310 --- /dev/null +++ b/src/livarot/Path.cpp @@ -0,0 +1,908 @@ +/* + * Path.cpp + * nlivarot + * + * Created by fred on Tue Jun 17 2003. + * + */ + +#include +#include "Path.h" +#include "livarot/path-description.h" +#include + +/* + * manipulation of the path data: path description and polyline + * grunt work... + * at the end of this file, 2 utilitary functions to get the point and tangent to path associated with a (command no;abcissis) + */ + + +Path::Path() +{ + descr_flags = 0; + pending_bezier_cmd = -1; + pending_moveto_cmd = -1; + + back = false; +} + +Path::~Path() +{ + for (std::vector::iterator i = descr_cmd.begin(); i != descr_cmd.end(); i++) { + delete *i; + } +} + +// debug function do dump the path contents on stdout +void Path::Affiche() +{ + std::cout << "path: " << descr_cmd.size() << " commands." << std::endl; + for (std::vector::const_iterator i = descr_cmd.begin(); i != descr_cmd.end(); i++) { + (*i)->dump(std::cout); + std::cout << std::endl; + } + + std::cout << std::endl; +} + +void Path::Reset() +{ + for (std::vector::iterator i = descr_cmd.begin(); i != descr_cmd.end(); i++) { + delete *i; + } + + descr_cmd.clear(); + pending_bezier_cmd = -1; + pending_moveto_cmd = -1; + descr_flags = 0; +} + +void Path::Copy(Path * who) +{ + ResetPoints(); + + for (std::vector::iterator i = descr_cmd.begin(); i != descr_cmd.end(); i++) { + delete *i; + } + + descr_cmd.clear(); + + for (std::vector::const_iterator i = who->descr_cmd.begin(); + i != who->descr_cmd.end(); + i++) + { + descr_cmd.push_back((*i)->clone()); + } +} + +void Path::CloseSubpath() +{ + descr_flags &= ~(descr_doing_subpath); + pending_moveto_cmd = -1; +} + +int Path::ForcePoint() +{ + if (descr_flags & descr_adding_bezier) { + EndBezierTo (); + } + + if ( (descr_flags & descr_doing_subpath) == 0 ) { + return -1; + } + + if (descr_cmd.empty()) { + return -1; + } + + descr_cmd.push_back(new PathDescrForced); + return descr_cmd.size() - 1; +} + + +void Path::InsertForcePoint(int at) +{ + if ( at < 0 || at > int(descr_cmd.size()) ) { + return; + } + + if ( at == int(descr_cmd.size()) ) { + ForcePoint(); + return; + } + + descr_cmd.insert(descr_cmd.begin() + at, new PathDescrForced); +} + +int Path::Close() +{ + if ( descr_flags & descr_adding_bezier ) { + CancelBezier(); + } + if ( descr_flags & descr_doing_subpath ) { + CloseSubpath(); + } else { + // Nothing to close. + return -1; + } + + descr_cmd.push_back(new PathDescrClose); + + descr_flags &= ~(descr_doing_subpath); + pending_moveto_cmd = -1; + + return descr_cmd.size() - 1; +} + +int Path::MoveTo(NR::Point const &iPt) +{ + if ( descr_flags & descr_adding_bezier ) { + EndBezierTo(iPt); + } + if ( descr_flags & descr_doing_subpath ) { + CloseSubpath(); + } + pending_moveto_cmd = descr_cmd.size(); + + descr_cmd.push_back(new PathDescrMoveTo(iPt)); + + descr_flags |= descr_doing_subpath; + return descr_cmd.size() - 1; +} + +void Path::InsertMoveTo(NR::Point const &iPt, int at) +{ + if ( at < 0 || at > int(descr_cmd.size()) ) { + return; + } + + if ( at == int(descr_cmd.size()) ) { + MoveTo(iPt); + return; + } + + descr_cmd.insert(descr_cmd.begin() + at, new PathDescrMoveTo(iPt)); +} + +int Path::LineTo(NR::Point const &iPt) +{ + if (descr_flags & descr_adding_bezier) { + EndBezierTo (iPt); + } + if (!( descr_flags & descr_doing_subpath )) { + return MoveTo (iPt); + } + + descr_cmd.push_back(new PathDescrLineTo(iPt)); + return descr_cmd.size() - 1; +} + +void Path::InsertLineTo(NR::Point const &iPt, int at) +{ + if ( at < 0 || at > int(descr_cmd.size()) ) { + return; + } + + if ( at == int(descr_cmd.size()) ) { + LineTo(iPt); + return; + } + + descr_cmd.insert(descr_cmd.begin() + at, new PathDescrLineTo(iPt)); +} + +int Path::CubicTo(NR::Point const &iPt, NR::Point const &iStD, NR::Point const &iEnD) +{ + if (descr_flags & descr_adding_bezier) { + EndBezierTo(iPt); + } + if ( (descr_flags & descr_doing_subpath) == 0) { + return MoveTo (iPt); + } + + descr_cmd.push_back(new PathDescrCubicTo(iPt, iStD, iEnD)); + return descr_cmd.size() - 1; +} + + +void Path::InsertCubicTo(NR::Point const &iPt, NR::Point const &iStD, NR::Point const &iEnD, int at) +{ + if ( at < 0 || at > int(descr_cmd.size()) ) { + return; + } + + if ( at == int(descr_cmd.size()) ) { + CubicTo(iPt,iStD,iEnD); + return; + } + + descr_cmd.insert(descr_cmd.begin() + at, new PathDescrCubicTo(iPt, iStD, iEnD)); +} + +int Path::ArcTo(NR::Point const &iPt, double iRx, double iRy, double angle, + bool iLargeArc, bool iClockwise) +{ + if (descr_flags & descr_adding_bezier) { + EndBezierTo(iPt); + } + if ( (descr_flags & descr_doing_subpath) == 0 ) { + return MoveTo(iPt); + } + + descr_cmd.push_back(new PathDescrArcTo(iPt, iRx, iRy, angle, iLargeArc, iClockwise)); + return descr_cmd.size() - 1; +} + + +void Path::InsertArcTo(NR::Point const &iPt, double iRx, double iRy, double angle, + bool iLargeArc, bool iClockwise, int at) +{ + if ( at < 0 || at > int(descr_cmd.size()) ) { + return; + } + + if ( at == int(descr_cmd.size()) ) { + ArcTo(iPt, iRx, iRy, angle, iLargeArc, iClockwise); + return; + } + + descr_cmd.insert(descr_cmd.begin() + at, new PathDescrArcTo(iPt, iRx, iRy, + angle, iLargeArc, iClockwise)); +} + +int Path::TempBezierTo() +{ + if (descr_flags & descr_adding_bezier) { + CancelBezier(); + } + if ( (descr_flags & descr_doing_subpath) == 0) { + // No starting point -> bad. + return -1; + } + pending_bezier_cmd = descr_cmd.size(); + + descr_cmd.push_back(new PathDescrBezierTo(NR::Point(0, 0), 0)); + descr_flags |= descr_adding_bezier; + descr_flags |= descr_delayed_bezier; + return descr_cmd.size() - 1; +} + +void Path::CancelBezier() +{ + descr_flags &= ~(descr_adding_bezier); + descr_flags &= ~(descr_delayed_bezier); + if (pending_bezier_cmd < 0) { + return; + } + + /* FIXME: I think there's a memory leak here */ + descr_cmd.resize(pending_bezier_cmd); + pending_bezier_cmd = -1; +} + +int Path::EndBezierTo() +{ + if (descr_flags & descr_delayed_bezier) { + CancelBezier (); + } else { + pending_bezier_cmd = -1; + descr_flags &= ~(descr_adding_bezier); + descr_flags &= ~(descr_delayed_bezier); + } + return -1; +} + +int Path::EndBezierTo(NR::Point const &iPt) +{ + if ( (descr_flags & descr_adding_bezier) == 0 ) { + return LineTo(iPt); + } + if ( (descr_flags & descr_doing_subpath) == 0 ) { + return MoveTo(iPt); + } + if ( (descr_flags & descr_delayed_bezier) == 0 ) { + return EndBezierTo(); + } + PathDescrBezierTo *nData = dynamic_cast(descr_cmd[pending_bezier_cmd]); + nData->p = iPt; + pending_bezier_cmd = -1; + descr_flags &= ~(descr_adding_bezier); + descr_flags &= ~(descr_delayed_bezier); + return -1; +} + + +int Path::IntermBezierTo(NR::Point const &iPt) +{ + if ( (descr_flags & descr_adding_bezier) == 0 ) { + return LineTo (iPt); + } + + if ( (descr_flags & descr_doing_subpath) == 0) { + return MoveTo (iPt); + } + + descr_cmd.push_back(new PathDescrIntermBezierTo(iPt)); + + PathDescrBezierTo *nBData = dynamic_cast(descr_cmd[pending_bezier_cmd]); + nBData->nb++; + return descr_cmd.size() - 1; +} + + +void Path::InsertIntermBezierTo(NR::Point const &iPt, int at) +{ + if ( at < 0 || at > int(descr_cmd.size()) ) { + return; + } + + if ( at == int(descr_cmd.size()) ) { + IntermBezierTo(iPt); + return; + } + + descr_cmd.insert(descr_cmd.begin() + at, new PathDescrIntermBezierTo(iPt)); +} + + +int Path::BezierTo(NR::Point const &iPt) +{ + if ( descr_flags & descr_adding_bezier ) { + EndBezierTo(iPt); + } + + if ( (descr_flags & descr_doing_subpath) == 0 ) { + return MoveTo (iPt); + } + + pending_bezier_cmd = descr_cmd.size(); + + descr_cmd.push_back(new PathDescrBezierTo(iPt, 0)); + descr_flags |= descr_adding_bezier; + descr_flags &= ~(descr_delayed_bezier); + return descr_cmd.size() - 1; +} + + +void Path::InsertBezierTo(NR::Point const &iPt, int iNb, int at) +{ + if ( at < 0 || at > int(descr_cmd.size()) ) { + return; + } + + if ( at == int(descr_cmd.size()) ) { + BezierTo(iPt); + return; + } + + descr_cmd.insert(descr_cmd.begin() + at, new PathDescrBezierTo(iPt, iNb)); +} + + +/* + * points de la polyligne + */ +void +Path::SetBackData (bool nVal) +{ + if (back == false) { + if (nVal == true && back == false) { + back = true; + ResetPoints(); + } else if (nVal == false && back == true) { + back = false; + ResetPoints(); + } + } else { + if (nVal == true && back == false) { + back = true; + ResetPoints(); + } else if (nVal == false && back == true) { + back = false; + ResetPoints(); + } + } +} + + +void Path::ResetPoints() +{ + pts.clear(); +} + + +int Path::AddPoint(NR::Point const &iPt, bool mvto) +{ + if (back) { + return AddPoint (iPt, -1, 0.0, mvto); + } + + if ( !mvto && pts.empty() == false && pts.back().p == iPt ) { + return -1; + } + + int const n = pts.size(); + pts.push_back(path_lineto(mvto ? polyline_moveto : polyline_lineto, iPt)); + return n; +} + + +int Path::AddPoint(NR::Point const &iPt, int ip, double it, bool mvto) +{ + if (back == false) { + return AddPoint (iPt, mvto); + } + + if ( !mvto && pts.empty() == false && pts.back().p == iPt ) { + return -1; + } + + int const n = pts.size(); + pts.push_back(path_lineto(mvto ? polyline_moveto : polyline_lineto, iPt, ip, it)); + return n; +} + +int Path::AddForcedPoint(NR::Point const &iPt) +{ + if (back) { + return AddForcedPoint (iPt, -1, 0.0); + } + + if ( pts.empty() || pts.back().isMoveTo != polyline_lineto ) { + return -1; + } + + int const n = pts.size(); + pts.push_back(path_lineto(polyline_forced, pts[n - 1].p)); + return n; +} + + +int Path::AddForcedPoint(NR::Point const &iPt, int /*ip*/, double /*it*/) +{ + /* FIXME: ip & it aren't used. Is this deliberate? */ + if (!back) { + return AddForcedPoint (iPt); + } + + if ( pts.empty() || pts.back().isMoveTo != polyline_lineto ) { + return -1; + } + + int const n = pts.size(); + pts.push_back(path_lineto(polyline_forced, pts[n - 1].p, pts[n - 1].piece, pts[n - 1].t)); + return n; +} + +void Path::PolylineBoundingBox(double &l, double &t, double &r, double &b) +{ + l = t = r = b = 0.0; + if ( pts.empty() ) { + return; + } + + std::vector::const_iterator i = pts.begin(); + l = r = i->p[NR::X]; + t = b = i->p[NR::Y]; + i++; + + for (; i != pts.end(); i++) { + r = std::max(r, i->p[NR::X]); + l = std::min(l, i->p[NR::X]); + b = std::max(b, i->p[NR::Y]); + t = std::min(t, i->p[NR::Y]); + } +} + + +/** + * \param piece Index of a one of our commands. + * \param at Distance along the segment that corresponds to `piece' (0 <= at <= 1) + * \param pos Filled in with the point at `at' on `piece'. + */ + +void Path::PointAt(int piece, double at, NR::Point &pos) +{ + if (piece < 0 || piece >= int(descr_cmd.size())) { + // this shouldn't happen: the piece we are asked for doesn't + // exist in the path + pos = NR::Point(0,0); + return; + } + + PathDescr const *theD = descr_cmd[piece]; + int const typ = theD->getType(); + NR::Point tgt; + double len; + double rad; + + if (typ == descr_moveto) { + + return PointAt (piece + 1, 0.0, pos); + + } else if (typ == descr_close || typ == descr_forced) { + + return PointAt (piece - 1, 1.0, pos); + + } else if (typ == descr_lineto) { + + PathDescrLineTo const *nData = dynamic_cast(theD); + TangentOnSegAt(at, PrevPoint (piece - 1), *nData, pos, tgt, len); + + } else if (typ == descr_arcto) { + + PathDescrArcTo const *nData = dynamic_cast(theD); + TangentOnArcAt(at,PrevPoint (piece - 1), *nData, pos, tgt, len, rad); + + } else if (typ == descr_cubicto) { + + PathDescrCubicTo const *nData = dynamic_cast(theD); + TangentOnCubAt(at, PrevPoint (piece - 1), *nData, false, pos, tgt, len, rad); + + } else if (typ == descr_bezierto || typ == descr_interm_bezier) { + + int bez_st = piece; + while (bez_st >= 0) { + int nt = descr_cmd[bez_st]->getType(); + if (nt == descr_bezierto) + break; + bez_st--; + } + if ( bez_st < 0 ) { + // Didn't find the beginning of the spline (bad). + // [pas trouvé le dubut de la spline (mauvais)] + return PointAt(piece - 1, 1.0, pos); + } + + PathDescrBezierTo *stB = dynamic_cast(descr_cmd[bez_st]); + if ( piece > bez_st + stB->nb ) { + // The spline goes past the authorized number of commands (bad). + // [la spline sort du nombre de commandes autorisé (mauvais)] + return PointAt(piece - 1, 1.0, pos); + } + + int k = piece - bez_st; + NR::Point const bStPt = PrevPoint(bez_st - 1); + if (stB->nb == 1 || k <= 0) { + PathDescrIntermBezierTo *nData = dynamic_cast(descr_cmd[bez_st + 1]); + TangentOnBezAt(at, bStPt, *nData, *stB, false, pos, tgt, len, rad); + } else { + // forcement plus grand que 1 + if (k == 1) { + PathDescrIntermBezierTo *nextI = dynamic_cast(descr_cmd[bez_st + 1]); + PathDescrIntermBezierTo *nnextI = dynamic_cast(descr_cmd[bez_st + 2]); + PathDescrBezierTo fin(0.5 * (nextI->p + nnextI->p), 1); + TangentOnBezAt(at, bStPt, *nextI, fin, false, pos, tgt, len, rad); + } else if (k == stB->nb) { + PathDescrIntermBezierTo *nextI = dynamic_cast(descr_cmd[bez_st + k]); + PathDescrIntermBezierTo *prevI = dynamic_cast(descr_cmd[bez_st + k - 1]); + NR::Point stP = 0.5 * ( prevI->p + nextI->p ); + TangentOnBezAt(at, stP, *nextI, *stB, false, pos, tgt, len, rad); + } else { + PathDescrIntermBezierTo *nextI = dynamic_cast(descr_cmd[bez_st + k]); + PathDescrIntermBezierTo *prevI = dynamic_cast(descr_cmd[bez_st + k - 1]); + PathDescrIntermBezierTo *nnextI = dynamic_cast(descr_cmd[bez_st + k + 1]); + NR::Point stP = 0.5 * ( prevI->p + nextI->p ); + PathDescrBezierTo fin(0.5 * (nextI->p + nnextI->p), 1); + TangentOnBezAt(at, stP, *nextI, fin, false, pos, tgt, len, rad); + } + } + } +} + + +void Path::PointAndTangentAt(int piece, double at, NR::Point &pos, NR::Point &tgt) +{ + if (piece < 0 || piece >= int(descr_cmd.size())) { + // this shouldn't happen: the piece we are asked for doesn't exist in the path + pos = NR::Point(0, 0); + return; + } + + PathDescr const *theD = descr_cmd[piece]; + int typ = theD->getType(); + double len; + double rad; + if (typ == descr_moveto) { + + return PointAndTangentAt(piece + 1, 0.0, pos, tgt); + + } else if (typ == descr_close ) { + + int cp = piece - 1; + while ( cp >= 0 && (descr_cmd[cp]->getType()) != descr_moveto ) { + cp--; + } + if ( cp >= 0 ) { + PathDescrMoveTo *nData = dynamic_cast(descr_cmd[cp]); + PathDescrLineTo dst(nData->p); + TangentOnSegAt(at, PrevPoint (piece - 1), dst, pos, tgt, len); + } + + } else if ( typ == descr_forced) { + + return PointAndTangentAt(piece - 1, 1.0, pos,tgt); + + } else if (typ == descr_lineto) { + + PathDescrLineTo const *nData = dynamic_cast(theD); + TangentOnSegAt(at, PrevPoint (piece - 1), *nData, pos, tgt, len); + + } else if (typ == descr_arcto) { + + PathDescrArcTo const *nData = dynamic_cast(theD); + TangentOnArcAt (at,PrevPoint (piece - 1), *nData, pos, tgt, len, rad); + + } else if (typ == descr_cubicto) { + + PathDescrCubicTo const *nData = dynamic_cast(theD); + TangentOnCubAt (at, PrevPoint (piece - 1), *nData, false, pos, tgt, len, rad); + + } else if (typ == descr_bezierto || typ == descr_interm_bezier) { + int bez_st = piece; + while (bez_st >= 0) { + int nt = descr_cmd[bez_st]->getType(); + if (nt == descr_bezierto) break; + bez_st--; + } + if ( bez_st < 0 ) { + return PointAndTangentAt(piece - 1, 1.0, pos, tgt); + // Didn't find the beginning of the spline (bad). + // [pas trouvé le dubut de la spline (mauvais)] + } + + PathDescrBezierTo* stB = dynamic_cast(descr_cmd[bez_st]); + if ( piece > bez_st + stB->nb ) { + return PointAndTangentAt(piece - 1, 1.0, pos, tgt); + // The spline goes past the number of authorized commands (bad). + // [la spline sort du nombre de commandes autorisé (mauvais)] + } + + int k = piece - bez_st; + NR::Point const bStPt(PrevPoint( bez_st - 1 )); + if (stB->nb == 1 || k <= 0) { + PathDescrIntermBezierTo* nData = dynamic_cast(descr_cmd[bez_st + 1]); + TangentOnBezAt (at, bStPt, *nData, *stB, false, pos, tgt, len, rad); + } else { + // forcement plus grand que 1 + if (k == 1) { + PathDescrIntermBezierTo *nextI = dynamic_cast(descr_cmd[bez_st + 1]); + PathDescrIntermBezierTo *nnextI = dynamic_cast(descr_cmd[bez_st + 2]); + PathDescrBezierTo fin(0.5 * (nextI->p + nnextI->p), 1); + TangentOnBezAt(at, bStPt, *nextI, fin, false, pos, tgt, len, rad); + } else if (k == stB->nb) { + PathDescrIntermBezierTo *prevI = dynamic_cast(descr_cmd[bez_st + k - 1]); + PathDescrIntermBezierTo *nextI = dynamic_cast(descr_cmd[bez_st + k]); + NR::Point stP = 0.5 * ( prevI->p + nextI->p ); + TangentOnBezAt(at, stP, *nextI, *stB, false, pos, tgt, len, rad); + } else { + PathDescrIntermBezierTo *prevI = dynamic_cast(descr_cmd[bez_st + k - 1]); + PathDescrIntermBezierTo *nextI = dynamic_cast(descr_cmd[bez_st + k]); + PathDescrIntermBezierTo *nnextI = dynamic_cast(descr_cmd[bez_st + k + 1]); + NR::Point stP = 0.5 * ( prevI->p + nextI->p ); + PathDescrBezierTo fin(0.5 * (nnextI->p + nnextI->p), 1); + TangentOnBezAt(at, stP, *nextI, fin, false, pos, tgt, len, rad); + } + } + } +} + +void Path::Transform(const NR::Matrix &trans) +{ + for (std::vector::iterator i = descr_cmd.begin(); i != descr_cmd.end(); i++) { + (*i)->transform(trans); + } +} + +void Path::FastBBox(double &l,double &t,double &r,double &b) +{ + l = t = r = b = 0; + bool empty = true; + NR::Point lastP(0, 0); + + for (int i = 0; i < int(descr_cmd.size()); i++) { + int const typ = descr_cmd[i]->getType(); + switch ( typ ) { + case descr_lineto: + { + PathDescrLineTo *nData = dynamic_cast(descr_cmd[i]); + if ( empty ) { + l = r = nData->p[NR::X]; + t = b = nData->p[NR::Y]; + empty = false; + } else { + if ( nData->p[NR::X] < l ) { + l = nData->p[NR::X]; + } + if ( nData->p[NR::X] > r ) { + r = nData->p[NR::X]; + } + if ( nData->p[NR::Y] < t ) { + t = nData->p[NR::Y]; + } + if ( nData->p[NR::Y] > b ) { + b = nData->p[NR::Y]; + } + } + lastP = nData->p; + } + break; + + case descr_moveto: + { + PathDescrMoveTo *nData = dynamic_cast(descr_cmd[i]); + if ( empty ) { + l = r = nData->p[NR::X]; + t = b = nData->p[NR::Y]; + empty = false; + } else { + if ( nData->p[NR::X] < l ) { + l = nData->p[NR::X]; + } + if ( nData->p[NR::X] > r ) { + r = nData->p[NR::X]; + } + if ( nData->p[NR::Y] < t ) { + t = nData->p[NR::Y]; + } + if ( nData->p[NR::Y] > b ) { + b = nData->p[NR::Y]; + } + } + lastP = nData->p; + } + break; + + case descr_arcto: + { + PathDescrArcTo *nData = dynamic_cast(descr_cmd[i]); + if ( empty ) { + l = r = nData->p[NR::X]; + t = b = nData->p[NR::Y]; + empty = false; + } else { + if ( nData->p[NR::X] < l ) { + l = nData->p[NR::X]; + } + if ( nData->p[NR::X] > r ) { + r = nData->p[NR::X]; + } + if ( nData->p[NR::Y] < t ) { + t = nData->p[NR::Y]; + } + if ( nData->p[NR::Y] > b ) { + b = nData->p[NR::Y]; + } + } + lastP = nData->p; + } + break; + + case descr_cubicto: + { + PathDescrCubicTo *nData = dynamic_cast(descr_cmd[i]); + if ( empty ) { + l = r = nData->p[NR::X]; + t = b = nData->p[NR::Y]; + empty = false; + } else { + if ( nData->p[NR::X] < l ) { + l = nData->p[NR::X]; + } + if ( nData->p[NR::X] > r ) { + r = nData->p[NR::X]; + } + if ( nData->p[NR::Y] < t ) { + t = nData->p[NR::Y]; + } + if ( nData->p[NR::Y] > b ) { + b = nData->p[NR::Y]; + } + } + + NR::Point np = nData->p - nData->end; + if ( np[NR::X] < l ) { + l = np[NR::X]; + } + if ( np[NR::X] > r ) { + r = np[NR::X]; + } + if ( np[NR::Y] < t ) { + t = np[NR::Y]; + } + if ( np[NR::Y] > b ) { + b = np[NR::Y]; + } + + np = lastP + nData->start; + if ( np[NR::X] < l ) { + l = np[NR::X]; + } + if ( np[NR::X] > r ) { + r = np[NR::X]; + } + if ( np[NR::Y] < t ) { + t = np[NR::Y]; + } + if ( np[NR::Y] > b ) { + b = np[NR::Y]; + } + lastP = nData->p; + } + break; + + case descr_bezierto: + { + PathDescrBezierTo *nData = dynamic_cast(descr_cmd[i]); + if ( empty ) { + l = r = nData->p[NR::X]; + t = b = nData->p[NR::Y]; + empty = false; + } else { + if ( nData->p[NR::X] < l ) { + l = nData->p[NR::X]; + } + if ( nData->p[NR::X] > r ) { + r = nData->p[NR::X]; + } + if ( nData->p[NR::Y] < t ) { + t = nData->p[NR::Y]; + } + if ( nData->p[NR::Y] > b ) { + b = nData->p[NR::Y]; + } + } + lastP = nData->p; + } + break; + + case descr_interm_bezier: + { + PathDescrIntermBezierTo *nData = dynamic_cast(descr_cmd[i]); + if ( empty ) { + l = r = nData->p[NR::X]; + t = b = nData->p[NR::Y]; + empty = false; + } else { + if ( nData->p[NR::X] < l ) { + l = nData->p[NR::X]; + } + if ( nData->p[NR::X] > r ) { + r = nData->p[NR::X]; + } + if ( nData->p[NR::Y] < t ) { + t = nData->p[NR::Y]; + } + if ( nData->p[NR::Y] > b ) { + b = nData->p[NR::Y]; + } + } + } + break; + } + } +} + +char *Path::svg_dump_path() const +{ + Inkscape::SVGOStringStream os; + + for (int i = 0; i < int(descr_cmd.size()); i++) { + NR::Point const p = (i == 0) ? NR::Point(0, 0) : PrevPoint(i - 1); + descr_cmd[i]->dumpSVG(os, p); + } + + return g_strdup (os.str().c_str()); +} + +/* + 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 : diff --git a/src/livarot/Path.h b/src/livarot/Path.h new file mode 100644 index 000000000..5b1df6294 --- /dev/null +++ b/src/livarot/Path.h @@ -0,0 +1,387 @@ +/* + * Path.h + * nlivarot + * + * Created by fred on Tue Jun 17 2003. + * + */ + +#ifndef my_path +#define my_path + +#include +#include "LivarotDefs.h" +#include "livarot/livarot-forward.h" +#include "libnr/nr-point.h" + +/* + * the Path class: a structure to hold path description and their polyline approximation (not kept in sync) + * the path description is built with regular commands like MoveTo() LineTo(), etc + * the polyline approximation is built by a call to Convert() or its variants + * another possibility would be to call directly the AddPoint() functions, but that is not encouraged + * the conversion to polyline can salvage data as to where on the path each polyline's point lies; use + * ConvertWithBackData() for this. after this call, it's easy to rewind the polyline: sequences of points + * of the same path command can be reassembled in a command + */ + +// polyline description commands +enum +{ + polyline_lineto = 0, // a lineto + polyline_moveto = 1, // a moveto + polyline_forced = 2 // a forced point, ie a point that was an angle or an intersection in a previous life + // or more realistically a control point in the path description that created the polyline + // forced points are used as "breakable" points for the polyline -> cubic bezier patch operations + // each time the bezier fitter encounters such a point in the polyline, it decreases its treshhold, + // so that it is more likely to cut the polyline at that position and produce a bezier patch +}; + +class Shape; + +// path creation: 2 phases: first the path is given as a succession of commands (MoveTo, LineTo, CurveTo...); then it +// is converted in a polyline +// a polylone can be stroked or filled to make a polygon +class Path +{ + friend class Shape; + +public: + + // flags for the path construction + enum + { + descr_ready = 0, + descr_adding_bezier = 1, // we're making a bezier spline, so you can expect pending_bezier_* to have a value + descr_doing_subpath = 2, // we're doing a path, so there is a moveto somewhere + descr_delayed_bezier = 4,// the bezier spline we're doing was initiated by a TempBezierTo(), so we'll need an endpoint + descr_dirty = 16 // the path description was modified + }; + + // some data for the construction: what's pending, and some flags + int descr_flags; + int pending_bezier_cmd; + int pending_bezier_data; + int pending_moveto_cmd; + int pending_moveto_data; + // the path description + std::vector descr_cmd; + + // polyline storage: a series of coordinates (and maybe weights) + // also back data: info on where this polyline's segment comes from, ie wich command in the path description: "piece" + // and what abcissis on the chunk of path for this command: "t" + // t=0 means it's at the start of the command's chunk, t=1 it's at the end + struct path_lineto + { + path_lineto(bool m, NR::Point pp) : isMoveTo(m), p(pp), piece(-1), t(0) {} + path_lineto(bool m, NR::Point pp, int pie, double tt) : isMoveTo(m), p(pp), piece(pie), t(tt) {} + + int isMoveTo; + NR::Point p; + int piece; + double t; + }; + + std::vector pts; + + bool back; + + Path(); + ~Path(); + + // creation of the path description + void Reset(); // reset to the empty description + void Copy (Path * who); + + // the commands... + int ForcePoint(); + int Close(); + int MoveTo ( NR::Point const &ip); + int LineTo ( NR::Point const &ip); + int CubicTo ( NR::Point const &ip, NR::Point const &iStD, NR::Point const &iEnD); + int ArcTo ( NR::Point const &ip, double iRx, double iRy, double angle, bool iLargeArc, bool iClockwise); + int IntermBezierTo ( NR::Point const &ip); // add a quadratic bezier spline control point + int BezierTo ( NR::Point const &ip); // quadratic bezier spline to this point (control points can be added after this) + int TempBezierTo(); // start a quadratic bezier spline (control points can be added after this) + int EndBezierTo(); + int EndBezierTo ( NR::Point const &ip); // ends a quadratic bezier spline (for curves started with TempBezierTo) + + // transforms a description in a polyline (for stroking and filling) + // treshhold is the max length^2 (sort of) + void Convert (double treshhold); + void ConvertEvenLines (double treshhold); // decomposes line segments too, for later recomposition + // same function for use when you want to later recompose the curves from the polyline + void ConvertWithBackData (double treshhold); + + // creation of the polyline (you can tinker with these function if you want) + void SetBackData (bool nVal); // has back data? + void ResetPoints(); // resets to the empty polyline + int AddPoint ( NR::Point const &iPt, bool mvto = false); // add point + int AddPoint ( NR::Point const &iPt, int ip, double it, bool mvto = false); + int AddForcedPoint ( NR::Point const &iPt); // add point + int AddForcedPoint ( NR::Point const &iPt, int ip, double it); + + // transform in a polygon (in a graph, in fact; a subsequent call to ConvertToShape is needed) + // - fills the polyline; justAdd=true doesn't reset the Shape dest, but simply adds the polyline into it + // closeIfNeeded=false prevent the function from closing the path (resulting in a non-eulerian graph + // pathID is a identification number for the path, and is used for recomposing curves from polylines + // give each different Path a different ID, and feed the appropriate orig[] to the ConvertToForme() function + void Fill(Shape *dest, int pathID = -1, bool justAdd = false, + bool closeIfNeeded = true, bool invert = false); + + // - stroke the path; usual parameters: type of cap=butt, type of join=join and miter (see LivarotDefs.h) + // doClose treat the path as closed (ie a loop) + void Stroke(Shape *dest, bool doClose, double width, JoinType join, + ButtType butt, double miter, bool justAdd = false); + + // build a Path that is the outline of the Path instance's description (the result is stored in dest) + // it doesn't compute the exact offset (it's way too complicated, but an approximation made of cubic bezier patches + // and segments. the algorithm was found in a plugin for Impress (by Chris Cox), but i can't find it back... + void Outline(Path *dest, double width, JoinType join, ButtType butt, + double miter); + + // half outline with edges having the same direction as the original + void OutsideOutline(Path *dest, double width, JoinType join, ButtType butt, + double miter); + + // half outline with edges having the opposite direction as the original + void InsideOutline (Path * dest, double width, JoinType join, ButtType butt, + double miter); + + // polyline to cubic bezier patches + void Simplify (double treshhold); + + // description simplification + void Coalesce (double tresh); + + // utilities + // piece is a command no in the command list + // "at" is an abcissis on the path portion associated with this command + // 0=beginning of portion, 1=end of portion. + void PointAt (int piece, double at, NR::Point & pos); + void PointAndTangentAt (int piece, double at, NR::Point & pos, NR::Point & tgt); + + // last control point before the command i (i included) + // used when dealing with quadratic bezier spline, cause these can contain arbitrarily many commands + const NR::Point PrevPoint (const int i) const; + + // dash the polyline + // the result is stored in the polyline, so you lose the original. make a copy before if needed + void DashPolyline(float head,float tail,float body,int nbD,float *dashs,bool stPlain,float stOffset); + + //utilitaire pour inkscape + void LoadArtBPath(void *iP,NR::Matrix const &tr,bool doTransformation); + void* MakeArtBPath(); + + void Transform(const NR::Matrix &trans); + + // decompose le chemin en ses sous-chemin + // killNoSurf=true -> oublie les chemins de surface nulle + Path** SubPaths(int &outNb,bool killNoSurf); + // pour recuperer les trous + // nbNest= nombre de contours + // conts= debut de chaque contour + // nesting= parent de chaque contour + Path** SubPathsWithNesting(int &outNb,bool killNoSurf,int nbNest,int* nesting,int* conts); + // surface du chemin (considere comme ferme) + double Surface(); + void PolylineBoundingBox(double &l,double &t,double &r,double &b); + void FastBBox(double &l,double &t,double &r,double &b); + // longueur (totale des sous-chemins) + double Length(); + + void ConvertForcedToMoveTo(); + void ConvertForcedToVoid(); + struct cut_position { + int piece; + double t; + }; + cut_position* CurvilignToPosition(int nbCv,double* cvAbs,int &nbCut); + cut_position PointToCurvilignPosition(NR::Point const &pos) const; + //Should this take a cut_position as a param? + double PositionToLength(int piece, double t); + + // caution: not tested on quadratic b-splines, most certainly buggy + void ConvertPositionsToMoveTo(int nbPos,cut_position* poss); + void ConvertPositionsToForced(int nbPos,cut_position* poss); + + void Affiche(); + char *svg_dump_path() const; + + private: + // utilitary functions for the path contruction + void CancelBezier (); + void CloseSubpath(); + void InsertMoveTo (NR::Point const &iPt,int at); + void InsertForcePoint (int at); + void InsertLineTo (NR::Point const &iPt,int at); + void InsertArcTo (NR::Point const &ip, double iRx, double iRy, double angle, bool iLargeArc, bool iClockwise,int at); + void InsertCubicTo (NR::Point const &ip, NR::Point const &iStD, NR::Point const &iEnD,int at); + void InsertBezierTo (NR::Point const &iPt,int iNb,int at); + void InsertIntermBezierTo (NR::Point const &iPt,int at); + + // creation of dashes: take the polyline given by spP (length spL) and dash it according to head, body, etc. put the result in + // the polyline of this instance + void DashSubPath(int spL, int spP, std::vector const &orig_pts, float head,float tail,float body,int nbD,float *dashs,bool stPlain,float stOffset); + + // Functions used by the conversion. + // they append points to the polyline + void DoArc ( NR::Point const &iS, NR::Point const &iE, double rx, double ry, + double angle, bool large, bool wise, double tresh); + void RecCubicTo ( NR::Point const &iS, NR::Point const &iSd, NR::Point const &iE, NR::Point const &iEd, double tresh, int lev, + double maxL = -1.0); + void RecBezierTo ( NR::Point const &iPt, NR::Point const &iS, NR::Point const &iE, double treshhold, int lev, double maxL = -1.0); + + void DoArc ( NR::Point const &iS, NR::Point const &iE, double rx, double ry, + double angle, bool large, bool wise, double tresh, int piece); + void RecCubicTo ( NR::Point const &iS, NR::Point const &iSd, NR::Point const &iE, NR::Point const &iEd, double tresh, int lev, + double st, double et, int piece); + void RecBezierTo ( NR::Point const &iPt, NR::Point const &iS, const NR::Point &iE, double treshhold, int lev, double st, double et, + int piece); + + // don't pay attention + struct offset_orig + { + Path *orig; + int piece; + double tSt, tEn; + double off_dec; + }; + void DoArc ( NR::Point const &iS, NR::Point const &iE, double rx, double ry, + double angle, bool large, bool wise, double tresh, int piece, + offset_orig & orig); + void RecCubicTo ( NR::Point const &iS, NR::Point const &iSd, NR::Point const &iE, NR::Point const &iEd, double tresh, int lev, + double st, double et, int piece, offset_orig & orig); + void RecBezierTo ( NR::Point const &iPt, NR::Point const &iS, NR::Point const &iE, double treshhold, int lev, double st, double et, + int piece, offset_orig & orig); + + static void ArcAngles ( NR::Point const &iS, NR::Point const &iE, double rx, + double ry, double angle, bool large, bool wise, + double &sang, double &eang); + static void QuadraticPoint (double t, NR::Point &oPt, NR::Point const &iS, NR::Point const &iM, NR::Point const &iE); + static void CubicTangent (double t, NR::Point &oPt, NR::Point const &iS, + NR::Point const &iSd, NR::Point const &iE, + NR::Point const &iEd); + + struct outline_callback_data + { + Path *orig; + int piece; + double tSt, tEn; + Path *dest; + double x1, y1, x2, y2; + union + { + struct + { + double dx1, dy1, dx2, dy2; + } + c; + struct + { + double mx, my; + } + b; + struct + { + double rx, ry, angle; + bool clock, large; + double stA, enA; + } + a; + } + d; + }; + + typedef void (outlineCallback) (outline_callback_data * data, double tol, double width); + struct outline_callbacks + { + outlineCallback *cubicto; + outlineCallback *bezierto; + outlineCallback *arcto; + }; + + void SubContractOutline (int off, int num_pd, + Path * dest, outline_callbacks & calls, + double tolerance, double width, JoinType join, + ButtType butt, double miter, bool closeIfNeeded, + bool skipMoveto, NR::Point & lastP, NR::Point & lastT); + void DoStroke(int off, int N, Shape *dest, bool doClose, double width, JoinType join, + ButtType butt, double miter, bool justAdd = false); + + static void TangentOnSegAt(double at, NR::Point const &iS, PathDescrLineTo const &fin, + NR::Point &pos, NR::Point &tgt, double &len); + static void TangentOnArcAt(double at, NR::Point const &iS, PathDescrArcTo const &fin, + NR::Point &pos, NR::Point &tgt, double &len, double &rad); + static void TangentOnCubAt (double at, NR::Point const &iS, PathDescrCubicTo const &fin, bool before, + NR::Point &pos, NR::Point &tgt, double &len, double &rad); + static void TangentOnBezAt (double at, NR::Point const &iS, + PathDescrIntermBezierTo & mid, + PathDescrBezierTo & fin, bool before, + NR::Point & pos, NR::Point & tgt, double &len, double &rad); + static void OutlineJoin (Path * dest, NR::Point pos, NR::Point stNor, NR::Point enNor, + double width, JoinType join, double miter); + + static bool IsNulCurve (std::vector const &cmd, int curD, NR::Point const &curX); + + static void RecStdCubicTo (outline_callback_data * data, double tol, + double width, int lev); + static void StdCubicTo (outline_callback_data * data, double tol, + double width); + static void StdBezierTo (outline_callback_data * data, double tol, + double width); + static void RecStdArcTo (outline_callback_data * data, double tol, + double width, int lev); + static void StdArcTo (outline_callback_data * data, double tol, double width); + + + // fonctions annexes pour le stroke + static void DoButt (Shape * dest, double width, ButtType butt, NR::Point pos, + NR::Point dir, int &leftNo, int &rightNo); + static void DoJoin (Shape * dest, double width, JoinType join, NR::Point pos, + NR::Point prev, NR::Point next, double miter, double prevL, + double nextL, int *stNo, int *enNo); + static void DoLeftJoin (Shape * dest, double width, JoinType join, NR::Point pos, + NR::Point prev, NR::Point next, double miter, double prevL, + double nextL, int &leftStNo, int &leftEnNo,int pathID=-1,int pieceID=0,double tID=0.0); + static void DoRightJoin (Shape * dest, double width, JoinType join, NR::Point pos, + NR::Point prev, NR::Point next, double miter, double prevL, + double nextL, int &rightStNo, int &rightEnNo,int pathID=-1,int pieceID=0,double tID=0.0); + static void RecRound (Shape * dest, int sNo, int eNo, + NR::Point const &iS, NR::Point const &iE, + NR::Point const &nS, NR::Point const &nE, + NR::Point &origine,float width); + + + void DoSimplify(int off, int N, double treshhold); + bool AttemptSimplify(int off, int N, double treshhold, PathDescrCubicTo &res, int &worstP); + static bool FitCubic(NR::Point const &start, + PathDescrCubicTo &res, + double *Xk, double *Yk, double *Qk, double *tk, int nbPt); + + struct fitting_tables { + int nbPt,maxPt,inPt; + double *Xk; + double *Yk; + double *Qk; + double *tk; + double *lk; + char *fk; + double totLen; + }; + bool AttemptSimplify (fitting_tables &data,double treshhold, PathDescrCubicTo & res,int &worstP); + bool ExtendFit(int off, int N, fitting_tables &data,double treshhold, PathDescrCubicTo & res,int &worstP); + double RaffineTk (NR::Point pt, NR::Point p0, NR::Point p1, NR::Point p2, NR::Point p3, double it); + void FlushPendingAddition(Path* dest,PathDescr *lastAddition,PathDescrCubicTo &lastCubic,int lastAD); +}; +#endif + +/* + 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:textwidth=99 : diff --git a/src/livarot/PathConversion.cpp b/src/livarot/PathConversion.cpp new file mode 100644 index 000000000..e6f7acb0c --- /dev/null +++ b/src/livarot/PathConversion.cpp @@ -0,0 +1,1575 @@ +/* + * PathConversion.cpp + * nlivarot + * + * Created by fred on Mon Nov 03 2003. + * + */ + +#include "Path.h" +#include "Shape.h" +#include "livarot/path-description.h" + +#include +#include +#include + +/* + * path description -> polyline + * and Path -> Shape (the Fill() function at the bottom) + * nathing fancy here: take each command and append an approximation of it to the polyline + */ + +void Path::ConvertWithBackData(double treshhold) +{ + if ( descr_flags & descr_adding_bezier ) { + CancelBezier(); + } + + if ( descr_flags & descr_doing_subpath ) { + CloseSubpath(); + } + + SetBackData(true); + ResetPoints(); + if ( descr_cmd.empty() ) { + return; + } + + NR::Point curX; + int curP = 1; + int lastMoveTo = -1; + + // The initial moveto. + { + int const firstTyp = descr_cmd[0]->getType(); + if ( firstTyp == descr_moveto ) { + curX = dynamic_cast(descr_cmd[0])->p; + } else { + curP = 0; + curX[NR::X] = curX[NR::Y] = 0; + } + lastMoveTo = AddPoint(curX, 0, 0.0, true); + } + + // And the rest, one by one. + while ( curP < int(descr_cmd.size()) ) { + + int const nType = descr_cmd[curP]->getType(); + NR::Point nextX; + + switch (nType) { + case descr_forced: { + AddForcedPoint(curX, curP, 1.0); + curP++; + break; + } + + case descr_moveto: { + PathDescrMoveTo *nData = dynamic_cast(descr_cmd[curP]); + nextX = nData->p; + lastMoveTo = AddPoint(nextX, curP, 0.0, true); + // et on avance + curP++; + break; + } + + case descr_close: { + nextX = pts[lastMoveTo].p; + AddPoint(nextX, curP, 1.0, false); + curP++; + break; + } + + case descr_lineto: { + PathDescrLineTo *nData = dynamic_cast(descr_cmd[curP]); + nextX = nData->p; + AddPoint(nextX,curP,1.0,false); + // et on avance + curP++; + break; + } + + case descr_cubicto: { + PathDescrCubicTo *nData = dynamic_cast(descr_cmd[curP]); + nextX = nData->p; + RecCubicTo(curX, nData->start, nextX, nData->end, treshhold, 8, 0.0, 1.0, curP); + AddPoint(nextX, curP, 1.0, false); + // et on avance + curP++; + break; + } + + case descr_arcto: { + PathDescrArcTo *nData = dynamic_cast(descr_cmd[curP]); + nextX = nData->p; + DoArc(curX, nextX, nData->rx, nData->ry, nData->angle, nData->large, nData->clockwise, treshhold, curP); + AddPoint(nextX, curP, 1.0, false); + // et on avance + curP++; + break; + } + + case descr_bezierto: { + PathDescrBezierTo *nBData = dynamic_cast(descr_cmd[curP]); + int nbInterm = nBData->nb; + nextX = nBData->p; + + int ip = curP + 1; + PathDescrIntermBezierTo *nData = dynamic_cast(descr_cmd[ip]); + + if ( nbInterm >= 1 ) { + NR::Point bx = curX; + NR::Point cx = curX; + NR::Point dx = curX; + + dx = nData->p; + ip++; + nData = dynamic_cast(descr_cmd[ip]); + + cx = 2 * bx - dx; + + for (int k = 0; k < nbInterm - 1; k++) { + bx = cx; + cx = dx; + + dx = nData->p; + ip++; + nData = dynamic_cast(descr_cmd[ip]); + + NR::Point stx; + stx = (bx + cx) / 2; + if ( k > 0 ) { + AddPoint(stx,curP - 1+k,1.0,false); + } + + { + NR::Point mx; + mx = (cx + dx) / 2; + RecBezierTo(cx, stx, mx, treshhold, 8, 0.0, 1.0, curP + k); + } + } + { + bx = cx; + cx = dx; + + dx = nextX; + dx = 2 * dx - cx; + + NR::Point stx; + stx = (bx + cx) / 2; + + if ( nbInterm > 1 ) { + AddPoint(stx, curP + nbInterm - 2, 1.0, false); + } + + { + NR::Point mx; + mx = (cx + dx) / 2; + RecBezierTo(cx, stx, mx, treshhold, 8, 0.0, 1.0, curP + nbInterm - 1); + } + } + + } + + + AddPoint(nextX, curP - 1 + nbInterm, 1.0, false); + + // et on avance + curP += 1 + nbInterm; + break; + } + } + curX = nextX; + } +} + + +void Path::Convert(double treshhold) +{ + if ( descr_flags & descr_adding_bezier ) { + CancelBezier(); + } + + if ( descr_flags & descr_doing_subpath ) { + CloseSubpath(); + } + + SetBackData(false); + ResetPoints(); + if ( descr_cmd.empty() ) { + return; + } + + NR::Point curX; + int curP = 1; + int lastMoveTo = 0; + + // le moveto + { + int const firstTyp = descr_cmd[0]->getType(); + if ( firstTyp == descr_moveto ) { + curX = dynamic_cast(descr_cmd[0])->p; + } else { + curP = 0; + curX[0] = curX[1] = 0; + } + lastMoveTo = AddPoint(curX, true); + } + descr_cmd[0]->associated = lastMoveTo; + + // et le reste, 1 par 1 + while ( curP < int(descr_cmd.size()) ) { + + int const nType = descr_cmd[curP]->getType(); + NR::Point nextX; + + switch (nType) { + case descr_forced: { + descr_cmd[curP]->associated = AddForcedPoint(curX); + curP++; + break; + } + + case descr_moveto: { + PathDescrMoveTo *nData = dynamic_cast(descr_cmd[curP]); + nextX = nData->p; + lastMoveTo = AddPoint(nextX, true); + descr_cmd[curP]->associated = lastMoveTo; + + // et on avance + curP++; + break; + } + + case descr_close: { + nextX = pts[lastMoveTo].p; + descr_cmd[curP]->associated = AddPoint(nextX, false); + if ( descr_cmd[curP]->associated < 0 ) { + if ( curP == 0 ) { + descr_cmd[curP]->associated = 0; + } else { + descr_cmd[curP]->associated = descr_cmd[curP - 1]->associated; + } + } + curP++; + break; + } + + case descr_lineto: { + PathDescrLineTo *nData = dynamic_cast(descr_cmd[curP]); + nextX = nData->p; + descr_cmd[curP]->associated = AddPoint(nextX, false); + if ( descr_cmd[curP]->associated < 0 ) { + if ( curP == 0 ) { + descr_cmd[curP]->associated = 0; + } else { + descr_cmd[curP]->associated = descr_cmd[curP - 1]->associated; + } + } + // et on avance + curP++; + break; + } + + case descr_cubicto: { + PathDescrCubicTo *nData = dynamic_cast(descr_cmd[curP]); + nextX = nData->p; + RecCubicTo(curX, nData->start, nextX, nData->end, treshhold, 8); + descr_cmd[curP]->associated = AddPoint(nextX,false); + if ( descr_cmd[curP]->associated < 0 ) { + if ( curP == 0 ) { + descr_cmd[curP]->associated = 0; + } else { + descr_cmd[curP]->associated = descr_cmd[curP - 1]->associated; + } + } + // et on avance + curP++; + break; + } + + case descr_arcto: { + PathDescrArcTo *nData = dynamic_cast(descr_cmd[curP]); + nextX = nData->p; + DoArc(curX, nextX, nData->rx, nData->ry, nData->angle, nData->large, nData->clockwise, treshhold); + descr_cmd[curP]->associated = AddPoint(nextX, false); + if ( descr_cmd[curP]->associated < 0 ) { + if ( curP == 0 ) { + descr_cmd[curP]->associated = 0; + } else { + descr_cmd[curP]->associated = descr_cmd[curP - 1]->associated; + } + } + // et on avance + curP++; + break; + } + + case descr_bezierto: { + PathDescrBezierTo *nBData = dynamic_cast(descr_cmd[curP]); + int nbInterm = nBData->nb; + nextX = nBData->p; + int curBD = curP; + + curP++; + int ip = curP; + PathDescrIntermBezierTo *nData = dynamic_cast(descr_cmd[ip]); + + if ( nbInterm == 1 ) { + NR::Point const midX = nData->p; + RecBezierTo(midX, curX, nextX, treshhold, 8); + } else if ( nbInterm > 1 ) { + NR::Point bx = curX; + NR::Point cx = curX; + NR::Point dx = curX; + + dx = nData->p; + ip++; + nData = dynamic_cast(descr_cmd[ip]); + + cx = 2 * bx - dx; + + for (int k = 0; k < nbInterm - 1; k++) { + bx = cx; + cx = dx; + + dx = nData->p; + ip++; + nData = dynamic_cast(descr_cmd[ip]); + + NR::Point stx = (bx + cx) / 2; + if ( k > 0 ) { + descr_cmd[ip - 2]->associated = AddPoint(stx, false); + if ( descr_cmd[ip - 2]->associated < 0 ) { + if ( curP == 0 ) { + descr_cmd[ip - 2]->associated = 0; + } else { + descr_cmd[ip - 2]->associated = descr_cmd[ip - 3]->associated; + } + } + } + + { + NR::Point const mx = (cx + dx) / 2; + RecBezierTo(cx, stx, mx, treshhold, 8); + } + } + + { + bx = cx; + cx = dx; + + dx = nextX; + dx = 2 * dx - cx; + + NR::Point stx = (bx + cx) / 2; + + descr_cmd[ip - 1]->associated = AddPoint(stx, false); + if ( descr_cmd[ip - 1]->associated < 0 ) { + if ( curP == 0 ) { + descr_cmd[ip - 1]->associated = 0; + } else { + descr_cmd[ip - 1]->associated = descr_cmd[ip - 2]->associated; + } + } + + { + NR::Point mx = (cx + dx) / 2; + RecBezierTo(cx, stx, mx, treshhold, 8); + } + } + } + + descr_cmd[curBD]->associated = AddPoint(nextX, false); + if ( descr_cmd[curBD]->associated < 0 ) { + if ( curP == 0 ) { + descr_cmd[curBD]->associated = 0; + } else { + descr_cmd[curBD]->associated = descr_cmd[curBD - 1]->associated; + } + } + + // et on avance + curP += nbInterm; + break; + } + } + + curX = nextX; + } +} + + + +void Path::ConvertEvenLines(double treshhold) +{ + if ( descr_flags & descr_adding_bezier ) { + CancelBezier(); + } + + if ( descr_flags & descr_doing_subpath ) { + CloseSubpath(); + } + + SetBackData(false); + ResetPoints(); + if ( descr_cmd.empty() ) { + return; + } + + NR::Point curX; + int curP = 1; + int lastMoveTo = 0; + + // le moveto + { + int const firstTyp = descr_cmd[0]->getType(); + if ( firstTyp == descr_moveto ) { + curX = dynamic_cast(descr_cmd[0])->p; + } else { + curP = 0; + curX[0] = curX[1] = 0; + } + lastMoveTo = AddPoint(curX, true); + } + descr_cmd[0]->associated = lastMoveTo; + + // et le reste, 1 par 1 + while ( curP < int(descr_cmd.size()) ) { + + int const nType = descr_cmd[curP]->getType(); + NR::Point nextX; + + switch (nType) { + case descr_forced: { + descr_cmd[curP]->associated = AddForcedPoint(curX); + curP++; + break; + } + + case descr_moveto: { + PathDescrMoveTo* nData = dynamic_cast(descr_cmd[curP]); + nextX = nData->p; + lastMoveTo = AddPoint(nextX,true); + descr_cmd[curP]->associated = lastMoveTo; + + // et on avance + curP++; + break; + } + + case descr_close: { + nextX = pts[lastMoveTo].p; + { + NR::Point nexcur; + nexcur = nextX - curX; + const double segL = NR::L2(nexcur); + if ( segL > treshhold ) { + for (double i = treshhold; i < segL; i += treshhold) { + NR::Point nX; + nX = (segL - i) * curX + i * nextX; + nX /= segL; + AddPoint(nX); + } + } + } + + descr_cmd[curP]->associated = AddPoint(nextX,false); + if ( descr_cmd[curP]->associated < 0 ) { + if ( curP == 0 ) { + descr_cmd[curP]->associated = 0; + } else { + descr_cmd[curP]->associated = descr_cmd[curP - 1]->associated; + } + } + + curP++; + break; + } + + case descr_lineto: { + PathDescrLineTo* nData = dynamic_cast(descr_cmd[curP]); + nextX = nData->p; + NR::Point nexcur = nextX - curX; + const double segL = L2(nexcur); + if ( segL > treshhold ) { + for (double i = treshhold; i < segL; i += treshhold) { + NR::Point nX = ((segL - i) * curX + i * nextX) / segL; + AddPoint(nX); + } + } + + descr_cmd[curP]->associated = AddPoint(nextX,false); + if ( descr_cmd[curP]->associated < 0 ) { + if ( curP == 0 ) { + descr_cmd[curP]->associated = 0; + } else { + descr_cmd[curP]->associated = descr_cmd[curP - 1]->associated; + } + } + // et on avance + curP++; + break; + } + + case descr_cubicto: { + PathDescrCubicTo *nData = dynamic_cast(descr_cmd[curP]); + nextX = nData->p; + RecCubicTo(curX, nData->start, nextX, nData->end, treshhold, 8, 4 * treshhold); + descr_cmd[curP]->associated = AddPoint(nextX, false); + if ( descr_cmd[curP]->associated < 0 ) { + if ( curP == 0 ) { + descr_cmd[curP]->associated = 0; + } else { + descr_cmd[curP]->associated = descr_cmd[curP - 1]->associated; + } + } + // et on avance + curP++; + break; + } + + case descr_arcto: { + PathDescrArcTo *nData = dynamic_cast(descr_cmd[curP]); + nextX = nData->p; + DoArc(curX, nextX, nData->rx, nData->ry, nData->angle, nData->large, nData->clockwise, treshhold); + descr_cmd[curP]->associated =AddPoint(nextX, false); + if ( descr_cmd[curP]->associated < 0 ) { + if ( curP == 0 ) { + descr_cmd[curP]->associated = 0; + } else { + descr_cmd[curP]->associated = descr_cmd[curP - 1]->associated; + } + } + + // et on avance + curP++; + break; + } + + case descr_bezierto: { + PathDescrBezierTo *nBData = dynamic_cast(descr_cmd[curP]); + int nbInterm = nBData->nb; + nextX = nBData->p; + int curBD = curP; + + curP++; + int ip = curP; + PathDescrIntermBezierTo *nData = dynamic_cast(descr_cmd[ip]); + + if ( nbInterm == 1 ) { + NR::Point const midX = nData->p; + RecBezierTo(midX, curX, nextX, treshhold, 8, 4 * treshhold); + } else if ( nbInterm > 1 ) { + NR::Point bx = curX; + NR::Point cx = curX; + NR::Point dx = curX; + + dx = nData->p; + ip++; + nData = dynamic_cast(descr_cmd[ip]); + + cx = 2 * bx - dx; + + for (int k = 0; k < nbInterm - 1; k++) { + bx = cx; + cx = dx; + dx = nData->p; + + ip++; + nData = dynamic_cast(descr_cmd[ip]); + + NR::Point stx = (bx+cx) / 2; + if ( k > 0 ) { + descr_cmd[ip - 2]->associated = AddPoint(stx, false); + if ( descr_cmd[ip - 2]->associated < 0 ) { + if ( curP == 0 ) { + descr_cmd[ip- 2]->associated = 0; + } else { + descr_cmd[ip - 2]->associated = descr_cmd[ip - 3]->associated; + } + } + } + + { + NR::Point const mx = (cx + dx) / 2; + RecBezierTo(cx, stx, mx, treshhold, 8, 4 * treshhold); + } + } + + { + bx = cx; + cx = dx; + + dx = nextX; + dx = 2 * dx - cx; + + NR::Point const stx = (bx + cx) / 2; + + descr_cmd[ip - 1]->associated = AddPoint(stx, false); + if ( descr_cmd[ip - 1]->associated < 0 ) { + if ( curP == 0 ) { + descr_cmd[ip - 1]->associated = 0; + } else { + descr_cmd[ip - 1]->associated = descr_cmd[ip - 2]->associated; + } + } + + { + NR::Point const mx = (cx + dx) / 2; + RecBezierTo(cx, stx, mx, treshhold, 8, 4 * treshhold); + } + } + } + + descr_cmd[curBD]->associated = AddPoint(nextX, false); + if ( descr_cmd[curBD]->associated < 0 ) { + if ( curP == 0 ) { + descr_cmd[curBD]->associated = 0; + } else { + descr_cmd[curBD]->associated = descr_cmd[curBD - 1]->associated; + } + } + + // et on avance + curP += nbInterm; + break; + } + } + if ( NR::LInfty(curX - nextX) > 0.00001 ) { + curX = nextX; + } + } +} + +const NR::Point Path::PrevPoint(int i) const +{ + /* TODO: I suspect this should assert `(unsigned) i < descr_nb'. We can probably change + the argument to unsigned. descr_nb should probably be changed to unsigned too. */ + g_assert( i >= 0 ); + switch ( descr_cmd[i]->getType() ) { + case descr_moveto: { + PathDescrMoveTo *nData = dynamic_cast(descr_cmd[i]); + return nData->p; + } + case descr_lineto: { + PathDescrLineTo *nData = dynamic_cast(descr_cmd[i]); + return nData->p; + } + case descr_arcto: { + PathDescrArcTo *nData = dynamic_cast(descr_cmd[i]); + return nData->p; + } + case descr_cubicto: { + PathDescrCubicTo *nData = dynamic_cast(descr_cmd[i]); + return nData->p; + } + case descr_bezierto: { + PathDescrBezierTo *nData = dynamic_cast(descr_cmd[i]); + return nData->p; + } + case descr_interm_bezier: + case descr_close: + case descr_forced: + return PrevPoint(i - 1); + default: + g_assert_not_reached(); + return NR::Point(0, 0); + } +} + +// utilitaries: given a quadratic bezier curve (start point, control point, end point, ie that's a clamped curve), +// and an abcissis on it, get the point with that abcissis. +// warning: it's NOT a curvilign abcissis (or whatever you call that in english), so "t" is NOT the length of "start point"->"result point" +void Path::QuadraticPoint(double t, NR::Point &oPt, + const NR::Point &iS, const NR::Point &iM, const NR::Point &iE) +{ + NR::Point const ax = iE - 2 * iM + iS; + NR::Point const bx = 2 * iM - 2 * iS; + NR::Point const cx = iS; + + oPt = t * t * ax + t * bx + cx; +} +// idem for cubic bezier patch +void Path::CubicTangent(double t, NR::Point &oPt, const NR::Point &iS, const NR::Point &isD, + const NR::Point &iE, const NR::Point &ieD) +{ + NR::Point const ax = ieD - 2 * iE + 2 * iS + isD; + NR::Point const bx = 3 * iE - ieD - 2 * isD - 3 * iS; + NR::Point const cx = isD; + + oPt = 3 * t * t * ax + 2 * t * bx + cx; +} + +// extract interesting info of a SVG arc description +static void ArcAnglesAndCenter(NR::Point const &iS, NR::Point const &iE, + double rx, double ry, double angle, + bool large, bool wise, + double &sang, double &eang, NR::Point &dr); + +void Path::ArcAngles(const NR::Point &iS, const NR::Point &iE, + double rx, double ry, double angle, bool large, bool wise, double &sang, double &eang) +{ + NR::Point dr; + ArcAnglesAndCenter(iS, iE, rx, ry, angle, large, wise, sang, eang, dr); +} + +/* N.B. If iS == iE then sang,eang,dr each become NaN. Probably a bug. */ +static void ArcAnglesAndCenter(NR::Point const &iS, NR::Point const &iE, + double rx, double ry, double angle, + bool large, bool wise, + double &sang, double &eang, NR::Point &dr) +{ + NR::Point se = iE - iS; + NR::Point ca(cos(angle), sin(angle)); + NR::Point cse(dot(se, ca), cross(se, ca)); + cse[0] /= rx; + cse[1] /= ry; + double const lensq = dot(cse,cse); + NR::Point csd = ( ( lensq < 4 + ? sqrt( 1/lensq - .25 ) + : 0.0 ) + * cse.ccw() ); + + NR::Point ra = -csd - 0.5 * cse; + if ( ra[0] <= -1 ) { + sang = M_PI; + } else if ( ra[0] >= 1 ) { + sang = 0; + } else { + sang = acos(ra[0]); + if ( ra[1] < 0 ) { + sang = 2 * M_PI - sang; + } + } + + ra = -csd + 0.5 * cse; + if ( ra[0] <= -1 ) { + eang = M_PI; + } else if ( ra[0] >= 1 ) { + eang = 0; + } else { + eang = acos(ra[0]); + if ( ra[1] < 0 ) { + eang = 2 * M_PI - eang; + } + } + + csd[0] *= rx; + csd[1] *= ry; + ca[1] = -ca[1]; // because it's the inverse rotation + + dr[0] = dot(csd, ca); + dr[1] = cross(csd, ca); + + ca[1] = -ca[1]; + + if ( wise ) { + + if (large) { + dr = -dr; + double swap = eang; + eang = sang; + sang = swap; + eang += M_PI; + sang += M_PI; + if ( eang >= 2*M_PI ) { + eang -= 2*M_PI; + } + if ( sang >= 2*M_PI ) { + sang -= 2*M_PI; + } + } + + } else { + if (!large) { + dr = -dr; + double swap = eang; + eang = sang; + sang = swap; + eang += M_PI; + sang += M_PI; + if ( eang >= 2*M_PI ) { + eang -= 2 * M_PI; + } + if ( sang >= 2*M_PI ) { + sang -= 2 * M_PI; + } + } + } + + dr += 0.5 * (iS + iE); +} + + + +void Path::DoArc(NR::Point const &iS, NR::Point const &iE, + double const rx, double const ry, double const angle, + bool const large, bool const wise, double const /*tresh*/) +{ + /* TODO: Check that our behaviour is standards-conformant if iS and iE are (much) further + apart than the diameter. Also check that we do the right thing for negative radius. + (Same for the other DoArc functions in this file.) */ + if ( rx <= 0.0001 || ry <= 0.0001 ) { + return; + // We always add a lineto afterwards, so this is fine. + // [on ajoute toujours un lineto apres, donc c bon] + } + + double sang; + double eang; + NR::Point dr; + ArcAnglesAndCenter(iS, iE, rx, ry, angle, large, wise, sang, eang, dr); + /* TODO: This isn't as good numerically as treating iS and iE as primary. E.g. consider + the case of low curvature (i.e. very large radius). */ + + NR::scale const ar(rx, ry); + NR::rotate cb( angle + sang ); + if (wise) { + + double const incr = -0.1; + if ( sang < eang ) { + sang += 2*M_PI; + } + NR::rotate const omega(incr); + for (double b = sang + incr ; b > eang ; b += incr) { + cb = omega * cb; + AddPoint( cb.vec * ar + dr ); + } + + } else { + + double const incr = 0.1; + if ( sang > eang ) { + sang -= 2*M_PI; + } + NR::rotate const omega(incr); + for (double b = sang + incr ; b < eang ; b += incr) { + cb = omega * cb; + AddPoint( cb.vec * ar + dr); + } + } +} + + +void Path::RecCubicTo( NR::Point const &iS, NR::Point const &isD, + NR::Point const &iE, NR::Point const &ieD, + double tresh, int lev, double maxL) +{ + NR::Point se = iE - iS; + const double dC = NR::L2(se); + if ( dC < 0.01 ) { + + const double sC = dot(isD,isD); + const double eC = dot(ieD,ieD); + if ( sC < tresh && eC < tresh ) { + return; + } + + } else { + const double sC = fabs(cross(se, isD)) / dC; + const double eC = fabs(cross(se, ieD)) / dC; + if ( sC < tresh && eC < tresh ) { + // presque tt droit -> attention si on nous demande de bien subdiviser les petits segments + if ( maxL > 0 && dC > maxL ) { + if ( lev <= 0 ) { + return; + } + NR::Point m = 0.5 * (iS + iE) + 0.125 * (isD - ieD); + NR::Point md = 0.75 * (iE - iS) - 0.125 * (isD + ieD); + + NR::Point hisD = 0.5 * isD; + NR::Point hieD = 0.5 * ieD; + + RecCubicTo(iS, hisD, m, md, tresh, lev - 1, maxL); + AddPoint(m); + RecCubicTo(m, md, iE, hieD, tresh, lev - 1,maxL); + } + return; + } + } + + if ( lev <= 0 ) { + return; + } + + { + NR::Point m = 0.5 * (iS + iE) + 0.125 * (isD - ieD); + NR::Point md = 0.75 * (iE - iS) - 0.125 * (isD + ieD); + + NR::Point hisD = 0.5 * isD; + NR::Point hieD = 0.5 * ieD; + + RecCubicTo(iS, hisD, m, md, tresh, lev - 1, maxL); + AddPoint(m); + RecCubicTo(m, md, iE, hieD, tresh, lev - 1,maxL); + } +} + + + +void Path::RecBezierTo(const NR::Point &iP, + const NR::Point &iS, + const NR::Point &iE, + double tresh, int lev, double maxL) +{ + if ( lev <= 0 ) { + return; + } + + NR::Point ps = iS - iP; + NR::Point pe = iE - iP; + NR::Point se = iE - iS; + double s = fabs(cross(pe, ps)); + if ( s < tresh ) { + const double l = L2(se); + if ( maxL > 0 && l > maxL ) { + const NR::Point m = 0.25 * (iS + iE + 2 * iP); + NR::Point md = 0.5 * (iS + iP); + RecBezierTo(md, iS, m, tresh, lev - 1, maxL); + AddPoint(m); + md = 0.5 * (iP + iE); + RecBezierTo(md, m, iE, tresh, lev - 1, maxL); + } + return; + } + + { + const NR::Point m = 0.25 * (iS + iE + 2 * iP); + NR::Point md = 0.5 * (iS + iP); + RecBezierTo(md, iS, m, tresh, lev - 1, maxL); + AddPoint(m); + md = 0.5 * (iP + iE); + RecBezierTo(md, m, iE, tresh, lev - 1, maxL); + } +} + + +void Path::DoArc(NR::Point const &iS, NR::Point const &iE, + double const rx, double const ry, double const angle, + bool const large, bool const wise, double const /*tresh*/, int const piece) +{ + /* TODO: Check that our behaviour is standards-conformant if iS and iE are (much) further + apart than the diameter. Also check that we do the right thing for negative radius. + (Same for the other DoArc functions in this file.) */ + if ( rx <= 0.0001 || ry <= 0.0001 ) { + return; + // We always add a lineto afterwards, so this is fine. + // [on ajoute toujours un lineto apres, donc c bon] + } + + double sang; + double eang; + NR::Point dr; + ArcAnglesAndCenter(iS, iE, rx, ry, angle, large, wise, sang, eang, dr); + /* TODO: This isn't as good numerically as treating iS and iE as primary. E.g. consider + the case of low curvature (i.e. very large radius). */ + + NR::scale const ar(rx, ry); + NR::rotate cb(angle + sang); + if (wise) { + + double const incr = -0.1; + if ( sang < eang ) { + sang += 2*M_PI; + } + NR::rotate const omega(incr); + for (double b = sang + incr; b > eang; b += incr) { + cb = omega * cb; + AddPoint(cb.vec * ar + dr, piece, (sang - b) / (sang - eang)); + } + + } else { + + double const incr = 0.1; + if ( sang > eang ) { + sang -= 2 * M_PI; + } + NR::rotate const omega(incr); + for (double b = sang + incr ; b < eang ; b += incr) { + cb = omega * cb; + AddPoint(cb.vec * ar + dr, piece, (b - sang) / (eang - sang)); + } + } +} + +void Path::RecCubicTo(NR::Point const &iS, NR::Point const &isD, + NR::Point const &iE, NR::Point const &ieD, + double tresh, int lev, double st, double et, int piece) +{ + const NR::Point se = iE - iS; + const double dC = NR::L2(se); + if ( dC < 0.01 ) { + const double sC = dot(isD, isD); + const double eC = dot(ieD, ieD); + if ( sC < tresh && eC < tresh ) { + return; + } + } else { + const double sC = fabs(cross(se, isD)) / dC; + const double eC = fabs(cross(se, ieD)) / dC; + if ( sC < tresh && eC < tresh ) { + return; + } + } + + if ( lev <= 0 ) { + return; + } + + NR::Point m = 0.5 * (iS + iE) + 0.125 * (isD - ieD); + NR::Point md = 0.75 * (iE - iS) - 0.125 * (isD + ieD); + double mt = (st + et) / 2; + + NR::Point hisD = 0.5 * isD; + NR::Point hieD = 0.5 * ieD; + + RecCubicTo(iS, hisD, m, md, tresh, lev - 1, st, mt, piece); + AddPoint(m, piece, mt); + RecCubicTo(m, md, iE, hieD, tresh, lev - 1, mt, et, piece); + +} + + + +void Path::RecBezierTo(NR::Point const &iP, + NR::Point const &iS, + NR::Point const &iE, + double tresh, int lev, double st, double et, int piece) +{ + if ( lev <= 0 ) { + return; + } + + NR::Point ps = iS - iP; + NR::Point pe = iE - iP; + const double s = fabs(cross(pe, ps)); + if ( s < tresh ) { + return; + } + + { + const double mt = (st + et) / 2; + const NR::Point m = 0.25 * (iS + iE + 2 * iP); + RecBezierTo(0.5 * (iS + iP), iS, m, tresh, lev - 1, st, mt, piece); + AddPoint(m, piece, mt); + RecBezierTo(0.5 * (iP + iE), m, iE, tresh, lev - 1, mt, et, piece); + } +} + + + +void Path::DoArc(NR::Point const &iS, NR::Point const &iE, + double const rx, double const ry, double const angle, + bool const large, bool const wise, double const /*tresh*/, + int const piece, offset_orig &/*orig*/) +{ + // Will never arrive here, as offsets are made of cubics. + // [on n'arrivera jamais ici, puisque les offsets sont fait de cubiques] + /* TODO: Check that our behaviour is standards-conformant if iS and iE are (much) further + apart than the diameter. Also check that we do the right thing for negative radius. + (Same for the other DoArc functions in this file.) */ + if ( rx <= 0.0001 || ry <= 0.0001 ) { + return; + // We always add a lineto afterwards, so this is fine. + // [on ajoute toujours un lineto apres, donc c bon] + } + + double sang; + double eang; + NR::Point dr; + ArcAnglesAndCenter(iS, iE, rx, ry, angle, large, wise, sang, eang, dr); + /* TODO: This isn't as good numerically as treating iS and iE as primary. E.g. consider + the case of low curvature (i.e. very large radius). */ + + NR::scale const ar(rx, ry); + NR::rotate cb(angle + sang); + if (wise) { + + double const incr = -0.1; + if ( sang < eang ) { + sang += 2*M_PI; + } + NR::rotate const omega(incr); + for (double b = sang + incr; b > eang ;b += incr) { + cb = omega * cb; + AddPoint(cb.vec * ar + dr, piece, (sang - b) / (sang - eang)); + } + + } else { + double const incr = 0.1; + if ( sang > eang ) { + sang -= 2*M_PI; + } + NR::rotate const omega(incr); + for (double b = sang + incr ; b < eang ; b += incr) { + cb = omega * cb; + AddPoint(cb.vec * ar + dr, piece, (b - sang) / (eang - sang)); + } + } +} + + +void Path::RecCubicTo(NR::Point const &iS, NR::Point const &isD, + NR::Point const &iE, NR::Point const &ieD, + double tresh, int lev, double st, double et, + int piece, offset_orig &orig) +{ + const NR::Point se = iE - iS; + const double dC = NR::L2(se); + bool doneSub = false; + if ( dC < 0.01 ) { + const double sC = dot(isD, isD); + const double eC = dot(ieD, ieD); + if ( sC < tresh && eC < tresh ) { + return; + } + } else { + const double sC = fabs(cross(se, isD)) / dC; + const double eC = fabs(cross(se, ieD)) / dC; + if ( sC < tresh && eC < tresh ) { + doneSub = true; + } + } + + if ( lev <= 0 ) { + doneSub = true; + } + + // test des inversions + bool stInv = false; + bool enInv = false; + { + NR::Point os_pos; + NR::Point os_tgt; + NR::Point oe_pos; + NR::Point oe_tgt; + + orig.orig->PointAndTangentAt(orig.piece, orig.tSt * (1 - st) + orig.tEn * st, os_pos, os_tgt); + orig.orig->PointAndTangentAt(orig.piece, orig.tSt * (1 - et) + orig.tEn * et, oe_pos, oe_tgt); + + + NR::Point n_tgt = isD; + double si = dot(n_tgt, os_tgt); + if ( si < 0 ) { + stInv = true; + } + n_tgt = ieD; + si = dot(n_tgt, oe_tgt); + if ( si < 0 ) { + enInv = true; + } + if ( stInv && enInv ) { + + AddPoint(os_pos, -1, 0.0); + AddPoint(iE, piece, et); + AddPoint(iS, piece, st); + AddPoint(oe_pos, -1, 0.0); + return; + + } else if ( ( stInv && !enInv ) || ( !stInv && enInv ) ) { + return; + } + + } + + if ( ( !stInv && !enInv && doneSub ) || lev <= 0 ) { + return; + } + + { + const NR::Point m = 0.5 * (iS+iE) + 0.125 * (isD - ieD); + const NR::Point md = 0.75 * (iE - iS) - 0.125 * (isD + ieD); + const double mt = (st + et) / 2; + const NR::Point hisD = 0.5 * isD; + const NR::Point hieD = 0.5 * ieD; + + RecCubicTo(iS, hisD, m, md, tresh, lev - 1, st, mt, piece, orig); + AddPoint(m, piece, mt); + RecCubicTo(m, md, iE, hieD, tresh, lev - 1, mt, et, piece, orig); + } +} + + + +void Path::RecBezierTo(NR::Point const &iP, NR::Point const &iS,NR::Point const &iE, + double tresh, int lev, double st, double et, + int piece, offset_orig& orig) +{ + bool doneSub = false; + if ( lev <= 0 ) { + return; + } + + const NR::Point ps = iS - iP; + const NR::Point pe = iE - iP; + const double s = fabs(cross(pe, ps)); + if ( s < tresh ) { + doneSub = true ; + } + + // test des inversions + bool stInv = false; + bool enInv = false; + { + NR::Point os_pos; + NR::Point os_tgt; + NR::Point oe_pos; + NR::Point oe_tgt; + NR::Point n_tgt; + NR::Point n_pos; + + double n_len; + double n_rad; + PathDescrIntermBezierTo mid(iP); + PathDescrBezierTo fin(iE, 1); + + TangentOnBezAt(0.0, iS, mid, fin, false, n_pos, n_tgt, n_len, n_rad); + orig.orig->PointAndTangentAt(orig.piece, orig.tSt * (1 - st) + orig.tEn * st, os_pos, os_tgt); + double si = dot(n_tgt, os_tgt); + if ( si < 0 ) { + stInv = true; + } + + TangentOnBezAt(1.0, iS, mid, fin, false, n_pos, n_tgt, n_len, n_rad); + orig.orig->PointAndTangentAt(orig.piece, orig.tSt * (1 - et) + orig.tEn * et, oe_pos, oe_tgt); + si = dot(n_tgt, oe_tgt); + if ( si < 0 ) { + enInv = true; + } + + if ( stInv && enInv ) { + AddPoint(os_pos, -1, 0.0); + AddPoint(iE, piece, et); + AddPoint(iS, piece, st); + AddPoint(oe_pos, -1, 0.0); + return; + } + } + + if ( !stInv && !enInv && doneSub ) { + return; + } + + { + double mt = (st + et) / 2; + NR::Point m = 0.25 * (iS + iE + 2 * iP); + NR::Point md = 0.5 * (iS + iP); + RecBezierTo(md, iS, m, tresh, lev - 1, st, mt, piece, orig); + AddPoint(m, piece, mt); + md = 0.5 * (iP + iE); + RecBezierTo(md, m, iE, tresh, lev - 1, mt, et, piece, orig); + } +} + + +/* + * put a polyline in a Shape instance, for further fun + * pathID is the ID you want this Path instance to be associated with, for when you're going to recompose the polyline + * in a path description ( you need to have prepared the back data for that, of course) + */ + +void Path::Fill(Shape* dest, int pathID, bool justAdd, bool closeIfNeeded, bool invert) +{ + if ( dest == NULL ) { + return; + } + + if ( justAdd == false ) { + dest->Reset(pts.size(), pts.size()); + } + + if ( pts.size() <= 1 ) { + return; + } + + int first = dest->numberOfPoints(); + + if ( back ) { + dest->MakeBackData(true); + } + + if ( invert ) { + if ( back ) { + { + // invert && back && !weighted + for (int i = 0; i < int(pts.size()); i++) { + dest->AddPoint(pts[i].p); + } + int lastM = 0; + int curP = 1; + int pathEnd = 0; + bool closed = false; + int lEdge = -1; + + while ( curP < int(pts.size()) ) { + int sbp = curP; + int lm = lastM; + int prp = pathEnd; + + if ( pts[sbp].isMoveTo == polyline_moveto ) { + + if ( closeIfNeeded ) { + if ( closed && lEdge >= 0 ) { + dest->DisconnectStart(lEdge); + dest->ConnectStart(first + lastM, lEdge); + } else { + lEdge = dest->AddEdge(first + lastM, first+pathEnd); + if ( lEdge >= 0 ) { + dest->ebData[lEdge].pathID = pathID; + dest->ebData[lEdge].pieceID = pts[lm].piece; + dest->ebData[lEdge].tSt = 1.0; + dest->ebData[lEdge].tEn = 0.0; + } + } + } + + lastM = curP; + pathEnd = curP; + closed = false; + lEdge = -1; + + } else { + + if ( NR::LInfty(pts[sbp].p - pts[prp].p) >= 0.00001 ) { + lEdge = dest->AddEdge(first + curP, first + pathEnd); + if ( lEdge >= 0 ) { + dest->ebData[lEdge].pathID = pathID; + dest->ebData[lEdge].pieceID = pts[sbp].piece; + if ( pts[sbp].piece == pts[prp].piece ) { + dest->ebData[lEdge].tSt = pts[sbp].t; + dest->ebData[lEdge].tEn = pts[prp].t; + } else { + dest->ebData[lEdge].tSt = pts[sbp].t; + dest->ebData[lEdge].tEn = 0.0; + } + } + pathEnd = curP; + if ( NR::LInfty(pts[sbp].p - pts[lm].p) < 0.00001 ) { + closed = true; + } else { + closed = false; + } + } + } + + curP++; + } + + if ( closeIfNeeded ) { + if ( closed && lEdge >= 0 ) { + dest->DisconnectStart(lEdge); + dest->ConnectStart(first + lastM, lEdge); + } else { + int lm = lastM; + lEdge = dest->AddEdge(first + lastM, first + pathEnd); + if ( lEdge >= 0 ) { + dest->ebData[lEdge].pathID = pathID; + dest->ebData[lEdge].pieceID = pts[lm].piece; + dest->ebData[lEdge].tSt = 1.0; + dest->ebData[lEdge].tEn = 0.0; + } + } + } + } + + } else { + + { + // invert && !back && !weighted + for (int i = 0; i < int(pts.size()); i++) { + dest->AddPoint(pts[i].p); + } + int lastM = 0; + int curP = 1; + int pathEnd = 0; + bool closed = false; + int lEdge = -1; + while ( curP < int(pts.size()) ) { + int sbp = curP; + int lm = lastM; + int prp = pathEnd; + if ( pts[sbp].isMoveTo == polyline_moveto ) { + if ( closeIfNeeded ) { + if ( closed && lEdge >= 0 ) { + dest->DisconnectStart(lEdge); + dest->ConnectStart(first + lastM, lEdge); + } else { + dest->AddEdge(first + lastM, first + pathEnd); + } + } + lastM = curP; + pathEnd = curP; + closed = false; + lEdge = -1; + } else { + if ( NR::LInfty(pts[sbp].p - pts[prp].p) >= 0.00001 ) { + lEdge = dest->AddEdge(first+curP, first+pathEnd); + pathEnd = curP; + if ( NR::LInfty(pts[sbp].p - pts[lm].p) < 0.00001 ) { + closed = true; + } else { + closed = false; + } + } + } + curP++; + } + + if ( closeIfNeeded ) { + if ( closed && lEdge >= 0 ) { + dest->DisconnectStart(lEdge); + dest->ConnectStart(first + lastM, lEdge); + } else { + dest->AddEdge(first + lastM, first + pathEnd); + } + } + + } + } + + } else { + + if ( back ) { + { + // !invert && back && !weighted + for (int i = 0; i < int(pts.size()); i++) { + dest->AddPoint(pts[i].p); + } + + int lastM = 0; + int curP = 1; + int pathEnd = 0; + bool closed = false; + int lEdge = -1; + while ( curP < int(pts.size()) ) { + int sbp = curP; + int lm = lastM; + int prp = pathEnd; + if ( pts[sbp].isMoveTo == polyline_moveto ) { + if ( closeIfNeeded ) { + if ( closed && lEdge >= 0 ) { + dest->DisconnectEnd(lEdge); + dest->ConnectEnd(first + lastM, lEdge); + } else { + lEdge = dest->AddEdge(first + pathEnd, first+lastM); + if ( lEdge >= 0 ) { + dest->ebData[lEdge].pathID = pathID; + dest->ebData[lEdge].pieceID = pts[lm].piece; + dest->ebData[lEdge].tSt = 0.0; + dest->ebData[lEdge].tEn = 1.0; + } + } + } + lastM = curP; + pathEnd = curP; + closed = false; + lEdge = -1; + } else { + if ( NR::LInfty(pts[sbp].p - pts[prp].p) >= 0.00001 ) { + lEdge = dest->AddEdge(first + pathEnd, first + curP); + dest->ebData[lEdge].pathID = pathID; + dest->ebData[lEdge].pieceID = pts[sbp].piece; + if ( pts[sbp].piece == pts[prp].piece ) { + dest->ebData[lEdge].tSt = pts[prp].t; + dest->ebData[lEdge].tEn = pts[sbp].t; + } else { + dest->ebData[lEdge].tSt = 0.0; + dest->ebData[lEdge].tEn = pts[sbp].t; + } + pathEnd = curP; + if ( NR::LInfty(pts[sbp].p - pts[lm].p) < 0.00001 ) { + closed = true; + } else { + closed = false; + } + } + } + curP++; + } + + if ( closeIfNeeded ) { + if ( closed && lEdge >= 0 ) { + dest->DisconnectEnd(lEdge); + dest->ConnectEnd(first + lastM, lEdge); + } else { + int lm = lastM; + lEdge = dest->AddEdge(first + pathEnd, first + lastM); + if ( lEdge >= 0 ) { + dest->ebData[lEdge].pathID = pathID; + dest->ebData[lEdge].pieceID = pts[lm].piece; + dest->ebData[lEdge].tSt = 0.0; + dest->ebData[lEdge].tEn = 1.0; + } + } + } + } + + } else { + { + // !invert && !back && !weighted + for (int i = 0;i < int(pts.size()); i++) { + dest->AddPoint(pts[i].p); + } + + int lastM = 0; + int curP = 1; + int pathEnd = 0; + bool closed = false; + int lEdge = -1; + while ( curP < int(pts.size()) ) { + int sbp = curP; + int lm = lastM; + int prp = pathEnd; + if ( pts[sbp].isMoveTo == polyline_moveto ) { + if ( closeIfNeeded ) { + if ( closed && lEdge >= 0 ) { + dest->DisconnectEnd(lEdge); + dest->ConnectEnd(first + lastM, lEdge); + } else { + dest->AddEdge(first + pathEnd, first + lastM); + } + } + lastM = curP; + pathEnd = curP; + closed = false; + lEdge = -1; + } else { + if ( NR::LInfty(pts[sbp].p - pts[prp].p) >= 0.00001 ) { + lEdge = dest->AddEdge(first+pathEnd, first+curP); + pathEnd = curP; + if ( NR::LInfty(pts[sbp].p - pts[lm].p) < 0.00001 ) { + closed = true; + } else { + closed = false; + } + } + } + curP++; + } + + if ( closeIfNeeded ) { + if ( closed && lEdge >= 0 ) { + dest->DisconnectEnd(lEdge); + dest->ConnectEnd(first + lastM, lEdge); + } else { + dest->AddEdge(first + pathEnd, first + lastM); + } + } + + } + } + } +} + +/* + 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 : diff --git a/src/livarot/PathCutting.cpp b/src/livarot/PathCutting.cpp new file mode 100644 index 000000000..2bcc3f244 --- /dev/null +++ b/src/livarot/PathCutting.cpp @@ -0,0 +1,1487 @@ +/* + * PathCutting.cpp + * nlivarot + * + * Created by fred on someday in 2004. + * public domain + * + */ + +#include "Path.h" +#include "livarot/path-description.h" +#include "libnr/n-art-bpath.h" +#include "libnr/nr-point-matrix-ops.h" + +void Path::DashPolyline(float head,float tail,float body,int nbD,float *dashs,bool stPlain,float stOffset) +{ + if ( nbD <= 0 || body <= 0.0001 ) return; // pas de tirets, en fait + + std::vector orig_pts = pts; + pts.clear(); + + int lastMI=-1; + int curP = 0; + int lastMP = -1; + + for (int i = 0; i < int(orig_pts.size()); i++) { + if ( orig_pts[curP].isMoveTo == polyline_moveto ) { + if ( lastMI >= 0 && lastMI < i-1 ) { // au moins 2 points + DashSubPath(i-lastMI,lastMP, orig_pts, head,tail,body,nbD,dashs,stPlain,stOffset); + } + lastMI=i; + lastMP=curP; + } + curP++; + } + if ( lastMI >= 0 && lastMI < int(orig_pts.size()) - 1 ) { + DashSubPath(orig_pts.size() - lastMI, lastMP, orig_pts, head, tail, body, nbD, dashs, stPlain, stOffset); + } +} + + + +void Path::DashSubPath(int spL, int spP, std::vector const &orig_pts, float head,float tail,float body,int nbD,float *dashs,bool stPlain,float stOffset) +{ + if ( spL <= 0 || spP == -1 ) return; + + double totLength=0; + NR::Point lastP; + lastP = orig_pts[spP].p; + for (int i=1;i 0.0001 ) { + totLength+=nl; + lastP=n; + } + } + + if ( totLength <= head+tail ) return; // tout mange par la tete et la queue + + double curLength=0; + double dashPos=0; + int dashInd=0; + bool dashPlain=false; + double lastT=0; + int lastPiece=-1; + lastP = orig_pts[spP].p; + for (int i=1;i 0.0001 ) { + double stLength=curLength; + double enLength=curLength+nl; + // couper les bouts en trop + if ( curLength <= head && curLength+nl > head ) { + nl-=head-curLength; + curLength=head; + dashInd=0; + dashPos=stOffset; + bool nPlain=stPlain; + while ( dashs[dashInd] < stOffset ) { + dashInd++; + nPlain=!(nPlain); + if ( dashInd >= nbD ) { + dashPos=0; + dashInd=0; + break; + } + } + if ( nPlain == true && dashPlain == false ) { + NR::Point p=(enLength-curLength)*lastP+(curLength-stLength)*n; + p/=(enLength-stLength); + if ( back ) { + double pT=0; + if ( nPiece == lastPiece ) { + pT=(lastT*(enLength-curLength)+nT*(curLength-stLength))/(enLength-stLength); + } else { + pT=(nPiece*(curLength-stLength))/(enLength-stLength); + } + AddPoint(p,nPiece,pT,true); + } else { + AddPoint(p,true); + } + } else if ( nPlain == false && dashPlain == true ) { + } + dashPlain=nPlain; + } + // faire les tirets + if ( curLength >= head /*&& curLength+nl <= totLength-tail*/ ) { + while ( curLength <= totLength-tail && nl > 0 ) { + if ( enLength <= totLength-tail ) nl=enLength-curLength; else nl=totLength-tail-curLength; + double leftInDash=body-dashPos; + if ( dashInd < nbD ) { + leftInDash=dashs[dashInd]-dashPos; + } + if ( leftInDash <= nl ) { + bool nPlain=false; + if ( dashInd < nbD ) { + dashPos=dashs[dashInd]; + dashInd++; + if ( dashPlain ) nPlain=false; else nPlain=true; + } else { + dashInd=0; + dashPos=0; + //nPlain=stPlain; + nPlain=dashPlain; + } + if ( nPlain == true && dashPlain == false ) { + NR::Point p=(enLength-curLength-leftInDash)*lastP+(curLength+leftInDash-stLength)*n; + p/=(enLength-stLength); + if ( back ) { + double pT=0; + if ( nPiece == lastPiece ) { + pT=(lastT*(enLength-curLength-leftInDash)+nT*(curLength+leftInDash-stLength))/(enLength-stLength); + } else { + pT=(nPiece*(curLength+leftInDash-stLength))/(enLength-stLength); + } + AddPoint(p,nPiece,pT,true); + } else { + AddPoint(p,true); + } + } else if ( nPlain == false && dashPlain == true ) { + NR::Point p=(enLength-curLength-leftInDash)*lastP+(curLength+leftInDash-stLength)*n; + p/=(enLength-stLength); + if ( back ) { + double pT=0; + if ( nPiece == lastPiece ) { + pT=(lastT*(enLength-curLength-leftInDash)+nT*(curLength+leftInDash-stLength))/(enLength-stLength); + } else { + pT=(nPiece*(curLength+leftInDash-stLength))/(enLength-stLength); + } + AddPoint(p,nPiece,pT,false); + } else { + AddPoint(p,false); + } + } + dashPlain=nPlain; + + curLength+=leftInDash; + nl-=leftInDash; + } else { + dashPos+=nl; + curLength+=nl; + nl=0; + } + } + if ( dashPlain ) { + if ( back ) { + AddPoint(n,nPiece,nT,false); + } else { + AddPoint(n,false); + } + } + nl=enLength-curLength; + } + if ( curLength <= totLength-tail && curLength+nl > totLength-tail ) { + nl=totLength-tail-curLength; + dashInd=0; + dashPos=0; + bool nPlain=false; + if ( nPlain == true && dashPlain == false ) { + } else if ( nPlain == false && dashPlain == true ) { + NR::Point p=(enLength-curLength)*lastP+(curLength-stLength)*n; + p/=(enLength-stLength); + if ( back ) { + double pT=0; + if ( nPiece == lastPiece ) { + pT=(lastT*(enLength-curLength)+nT*(curLength-stLength))/(enLength-stLength); + } else { + pT=(nPiece*(curLength-stLength))/(enLength-stLength); + } + AddPoint(p,nPiece,pT,false); + } else { + AddPoint(p,false); + } + } + dashPlain=nPlain; + } + // continuer + curLength=enLength; + lastP=n; + lastPiece=nPiece; + lastT=nT; + } + } +} +#include "../display/canvas-bpath.h" + +void* Path::MakeArtBPath(void) +{ + int nb_cmd=0,max_cmd=0; + NArtBpath* bpath=(NArtBpath*)g_malloc((max_cmd+1)*sizeof(NArtBpath)); + + NR::Point lastP,bezSt,bezEn,lastMP; + int lastM=-1,bezNb=0; + for (int i=0;igetType(); + switch ( typ ) { + case descr_close: + { + if ( lastM >= 0 ) { + bpath[lastM].code=NR_MOVETO; + if ( nb_cmd >= max_cmd ) { + max_cmd=2*nb_cmd+1; + bpath=(NArtBpath*)g_realloc(bpath,(max_cmd+1)*sizeof(NArtBpath)); + } + bpath[nb_cmd].code=NR_LINETO; + bpath[nb_cmd].x3=lastMP[0]; + bpath[nb_cmd].y3=lastMP[1]; + nb_cmd++; + } + lastM=-1; + } + break; + case descr_lineto: + { + PathDescrLineTo *nData = dynamic_cast(descr_cmd[i]); + if ( nb_cmd >= max_cmd ) { + max_cmd=2*nb_cmd+1; + bpath=(NArtBpath*)g_realloc(bpath,(max_cmd+1)*sizeof(NArtBpath)); + } + bpath[nb_cmd].code=NR_LINETO; + bpath[nb_cmd].x3=nData->p[0]; + bpath[nb_cmd].y3=nData->p[1]; + nb_cmd++; + lastP=nData->p; + } + break; + case descr_moveto: + { + PathDescrMoveTo *nData = dynamic_cast(descr_cmd[i]); + if ( nb_cmd >= max_cmd ) { + max_cmd=2*nb_cmd+1; + bpath=(NArtBpath*)g_realloc(bpath,(max_cmd+1)*sizeof(NArtBpath)); + } + bpath[nb_cmd].code=NR_MOVETO_OPEN; + bpath[nb_cmd].x3=nData->p[0]; + bpath[nb_cmd].y3=nData->p[1]; + lastM=nb_cmd; + nb_cmd++; + lastP=lastMP=nData->p; + } + break; + case descr_arcto: + { + PathDescrArcTo *nData = dynamic_cast(descr_cmd[i]); + lastP=nData->p; + } + break; + case descr_cubicto: + { + PathDescrCubicTo *nData = dynamic_cast(descr_cmd[i]); + if ( nb_cmd >= max_cmd ) { + max_cmd=2*nb_cmd+1; + bpath=(NArtBpath*)g_realloc(bpath,(max_cmd+1)*sizeof(NArtBpath)); + } + bpath[nb_cmd].code=NR_CURVETO; + bpath[nb_cmd].x1=lastP[0]+0.333333*nData->start[0]; + bpath[nb_cmd].y1=lastP[1]+0.333333*nData->start[1]; + bpath[nb_cmd].x2=nData->p[0]-0.333333*nData->end[0]; + bpath[nb_cmd].y2=nData->p[1]-0.333333*nData->end[1]; + bpath[nb_cmd].x3=nData->p[0]; + bpath[nb_cmd].y3=nData->p[1]; + nb_cmd++; + lastP=nData->p; + } + break; + case descr_bezierto: + { + PathDescrBezierTo *nData = dynamic_cast(descr_cmd[i]); + if ( nb_cmd >= max_cmd ) { + max_cmd=2*nb_cmd+1; + bpath=(NArtBpath*)g_realloc(bpath,(max_cmd+1)*sizeof(NArtBpath)); + } + if ( nData->nb <= 0 ) { + bpath[nb_cmd].code=NR_LINETO; + bpath[nb_cmd].x3=nData->p[0]; + bpath[nb_cmd].y3=nData->p[1]; + nb_cmd++; + bezNb=0; + } else if ( nData->nb == 1 ){ + PathDescrIntermBezierTo *iData = dynamic_cast(descr_cmd[i+1]); + bpath[nb_cmd].code=NR_CURVETO; + bpath[nb_cmd].x1=0.333333*(lastP[0]+2*iData->p[0]); + bpath[nb_cmd].y1=0.333333*(lastP[1]+2*iData->p[1]); + bpath[nb_cmd].x2=0.333333*(nData->p[0]+2*iData->p[0]); + bpath[nb_cmd].y2=0.333333*(nData->p[1]+2*iData->p[1]); + bpath[nb_cmd].x3=nData->p[0]; + bpath[nb_cmd].y3=nData->p[1]; + nb_cmd++; + bezNb=0; + } else { + bezSt=2*lastP-nData->p; + bezEn=nData->p; + bezNb=nData->nb; + } + lastP=nData->p; + } + break; + case descr_interm_bezier: + { + if ( bezNb > 0 ) { + PathDescrIntermBezierTo *nData = dynamic_cast(descr_cmd[i]); + NR::Point p_m=nData->p,p_s=0.5*(bezSt+p_m),p_e; + if ( bezNb > 1 ) { + PathDescrIntermBezierTo *iData = dynamic_cast(descr_cmd[i+1]); + p_e=0.5*(p_m+iData->p); + } else { + p_e=bezEn; + } + + if ( nb_cmd >= max_cmd ) { + max_cmd=2*nb_cmd+1; + bpath=(NArtBpath*)g_realloc(bpath,(max_cmd+1)*sizeof(NArtBpath)); + } + bpath[nb_cmd].code=NR_CURVETO; + NR::Point cp1=0.333333*(p_s+2*p_m),cp2=0.333333*(2*p_m+p_e); + bpath[nb_cmd].x1=cp1[0]; + bpath[nb_cmd].y1=cp1[1]; + bpath[nb_cmd].x2=cp2[0]; + bpath[nb_cmd].y2=cp2[1]; + bpath[nb_cmd].x3=p_e[0]; + bpath[nb_cmd].y3=p_e[1]; + nb_cmd++; + + bezNb--; + } + } + break; + } + } + bpath[nb_cmd].code=NR_END; + return bpath; +} + +void Path::LoadArtBPath(void *iV,NR::Matrix const &trans,bool doTransformation) +{ + if ( iV == NULL ) return; + NArtBpath *bpath = (NArtBpath*)iV; + + SetBackData (false); + Reset(); + { + int i; + bool closed = false; + NR::Point lastX(0,0); + + for (i = 0; bpath[i].code != NR_END; i++) + { + switch (bpath[i].code) + { + case NR_LINETO: + lastX[0] = bpath[i].x3; + lastX[1] = bpath[i].y3; + if ( doTransformation ) { + lastX*=trans; + } + LineTo (lastX); + break; + + case NR_CURVETO: + { + NR::Point tmp,tms(0,0),tme(0,0),tm1,tm2; + tmp[0]=bpath[i].x3; + tmp[1]=bpath[i].y3; + tm1[0]=bpath[i].x1; + tm1[1]=bpath[i].y1; + tm2[0]=bpath[i].x2; + tm2[1]=bpath[i].y2; + if ( doTransformation ) { + tmp*=trans; + tm1*=trans; + tm2*=trans; + } + tms=3 * (tm1 - lastX); + tme=3 * (tmp - tm2); + CubicTo (tmp,tms,tme); + } + lastX[0] = bpath[i].x3; + lastX[1] = bpath[i].y3; + if ( doTransformation ) { + lastX*=trans; + } + break; + + case NR_MOVETO_OPEN: + case NR_MOVETO: + if (closed) Close (); + closed = (bpath[i].code == NR_MOVETO); + lastX[0] = bpath[i].x3; + lastX[1] = bpath[i].y3; + if ( doTransformation ) { + lastX*=trans; + } + MoveTo (lastX); + break; + default: + break; + } + } + if (closed) Close (); + } +} + + +/** + * \return Length of the lines in the pts vector. + */ + +double Path::Length() +{ + if ( pts.empty() ) { + return 0; + } + + NR::Point lastP = pts[0].p; + + double len = 0; + for (std::vector::const_iterator i = pts.begin(); i != pts.end(); i++) { + + if ( i->isMoveTo != polyline_moveto ) { + len += NR::L2(i->p - lastP); + } + + lastP = i->p; + } + + return len; +} + + +double Path::Surface() +{ + if ( pts.empty() ) { + return 0; + } + + NR::Point lastM = pts[0].p; + NR::Point lastP = lastM; + + double surf = 0; + for (std::vector::const_iterator i = pts.begin(); i != pts.end(); i++) { + + if ( i->isMoveTo == polyline_moveto ) { + surf += NR::cross(lastM - lastP, lastM); + lastP = lastM = i->p; + } else { + surf += NR::cross(i->p - lastP, i->p); + lastP = i->p; + } + + } + + return surf; +} + + +Path** Path::SubPaths(int &outNb,bool killNoSurf) +{ + int nbRes=0; + Path** res=NULL; + Path* curAdd=NULL; + + for (int i=0;igetType(); + switch ( typ ) { + case descr_moveto: + if ( curAdd ) { + if ( curAdd->descr_cmd.size() > 1 ) { + curAdd->Convert(1.0); + double addSurf=curAdd->Surface(); + if ( fabs(addSurf) > 0.0001 || killNoSurf == false ) { + res=(Path**)g_realloc(res,(nbRes+1)*sizeof(Path*)); + res[nbRes++]=curAdd; + } else { + delete curAdd; + } + } else { + delete curAdd; + } + curAdd=NULL; + } + curAdd=new Path; + curAdd->SetBackData(false); + { + PathDescrMoveTo *nData = dynamic_cast(descr_cmd[i]); + curAdd->MoveTo(nData->p); + } + break; + case descr_close: + { + curAdd->Close(); + } + break; + case descr_lineto: + { + PathDescrLineTo *nData = dynamic_cast(descr_cmd[i]); + curAdd->LineTo(nData->p); + } + break; + case descr_cubicto: + { + PathDescrCubicTo *nData = dynamic_cast(descr_cmd[i]); + curAdd->CubicTo(nData->p,nData->start,nData->end); + } + break; + case descr_arcto: + { + PathDescrArcTo *nData = dynamic_cast(descr_cmd[i]); + curAdd->ArcTo(nData->p,nData->rx,nData->ry,nData->angle,nData->large,nData->clockwise); + } + break; + case descr_bezierto: + { + PathDescrBezierTo *nData = dynamic_cast(descr_cmd[i]); + curAdd->BezierTo(nData->p); + } + break; + case descr_interm_bezier: + { + PathDescrIntermBezierTo *nData = dynamic_cast(descr_cmd[i]); + curAdd->IntermBezierTo(nData->p); + } + break; + default: + break; + } + } + if ( curAdd ) { + if ( curAdd->descr_cmd.size() > 1 ) { + curAdd->Convert(1.0); + double addSurf=curAdd->Surface(); + if ( fabs(addSurf) > 0.0001 || killNoSurf == false ) { + res=(Path**)g_realloc(res,(nbRes+1)*sizeof(Path*)); + res[nbRes++]=curAdd; + } else { + delete curAdd; + } + } else { + delete curAdd; + } + } + curAdd=NULL; + + outNb=nbRes; + return res; +} +Path** Path::SubPathsWithNesting(int &outNb,bool killNoSurf,int nbNest,int* nesting,int* conts) +{ + int nbRes=0; + Path** res=NULL; + Path* curAdd=NULL; + bool increment=false; + + for (int i=0;igetType(); + switch ( typ ) { + case descr_moveto: + { + if ( curAdd && increment == false ) { + if ( curAdd->descr_cmd.size() > 1 ) { + // sauvegarder descr_cmd[0]->associated + int savA=curAdd->descr_cmd[0]->associated; + curAdd->Convert(1.0); + curAdd->descr_cmd[0]->associated=savA; // associated n'est pas utilise apres + double addSurf=curAdd->Surface(); + if ( fabs(addSurf) > 0.0001 || killNoSurf == false ) { + res=(Path**)g_realloc(res,(nbRes+1)*sizeof(Path*)); + res[nbRes++]=curAdd; + } else { + delete curAdd; + } + } else { + delete curAdd; + } + curAdd=NULL; + } + Path* hasDad=NULL; + for (int j=0;j= 0 ) { + int dadMvt=conts[nesting[j]]; + for (int k=0;kdescr_cmd.empty() == false && res[k]->descr_cmd[0]->associated == dadMvt ) { + hasDad=res[k]; + break; + } + } + } + if ( conts[j] > i ) break; + } + if ( hasDad ) { + curAdd=hasDad; + increment=true; + } else { + curAdd=new Path; + curAdd->SetBackData(false); + increment=false; + } + PathDescrMoveTo *nData = dynamic_cast(descr_cmd[i]); + int mNo=curAdd->MoveTo(nData->p); + curAdd->descr_cmd[mNo]->associated=i; + } + break; + case descr_close: + { + curAdd->Close(); + } + break; + case descr_lineto: + { + PathDescrLineTo *nData = dynamic_cast(descr_cmd[i]); + curAdd->LineTo(nData->p); + } + break; + case descr_cubicto: + { + PathDescrCubicTo *nData = dynamic_cast(descr_cmd[i]); + curAdd->CubicTo(nData->p,nData->start,nData->end); + } + break; + case descr_arcto: + { + PathDescrArcTo *nData = dynamic_cast(descr_cmd[i]); + curAdd->ArcTo(nData->p,nData->rx,nData->ry,nData->angle,nData->large,nData->clockwise); + } + break; + case descr_bezierto: + { + PathDescrBezierTo *nData = dynamic_cast(descr_cmd[i]); + curAdd->BezierTo(nData->p); + } + break; + case descr_interm_bezier: + { + PathDescrIntermBezierTo *nData = dynamic_cast(descr_cmd[i]); + curAdd->IntermBezierTo(nData->p); + } + break; + default: + break; + } + } + if ( curAdd && increment == false ) { + if ( curAdd->descr_cmd.size() > 1 ) { + curAdd->Convert(1.0); + double addSurf=curAdd->Surface(); + if ( fabs(addSurf) > 0.0001 || killNoSurf == false ) { + res=(Path**)g_realloc(res,(nbRes+1)*sizeof(Path*)); + res[nbRes++]=curAdd; + } else { + delete curAdd; + } + } else { + delete curAdd; + } + } + curAdd=NULL; + + outNb=nbRes; + return res; +} + + +void Path::ConvertForcedToVoid() +{ + for (int i=0; i < int(descr_cmd.size()); i++) { + if ( descr_cmd[i]->getType() == descr_forced) { + delete descr_cmd[i]; + descr_cmd.erase(descr_cmd.begin() + i); + } + } +} + + +void Path::ConvertForcedToMoveTo() +{ + NR::Point lastSeen(0, 0); + NR::Point lastMove(0, 0); + + { + NR::Point lastPos(0, 0); + for (int i = int(descr_cmd.size()) - 1; i >= 0; i--) { + int const typ = descr_cmd[i]->getType(); + switch ( typ ) { + case descr_forced: + { + PathDescrForced *d = dynamic_cast(descr_cmd[i]); + d->p = lastPos; + break; + } + case descr_close: + { + PathDescrClose *d = dynamic_cast(descr_cmd[i]); + d->p = lastPos; + break; + } + case descr_moveto: + { + PathDescrMoveTo *d = dynamic_cast(descr_cmd[i]); + lastPos = d->p; + break; + } + case descr_lineto: + { + PathDescrLineTo *d = dynamic_cast(descr_cmd[i]); + lastPos = d->p; + break; + } + case descr_arcto: + { + PathDescrArcTo *d = dynamic_cast(descr_cmd[i]); + lastPos = d->p; + break; + } + case descr_cubicto: + { + PathDescrCubicTo *d = dynamic_cast(descr_cmd[i]); + lastPos = d->p; + break; + } + case descr_bezierto: + { + PathDescrBezierTo *d = dynamic_cast(descr_cmd[i]); + lastPos = d->p; + break; + } + case descr_interm_bezier: + { + PathDescrIntermBezierTo *d = dynamic_cast(descr_cmd[i]); + lastPos = d->p; + break; + } + default: + break; + } + } + } + + bool hasMoved = false; + for (int i = 0; i < int(descr_cmd.size()); i++) { + int const typ = descr_cmd[i]->getType(); + switch ( typ ) { + case descr_forced: + if ( i < int(descr_cmd.size()) - 1 && hasMoved ) { // sinon il termine le chemin + + delete descr_cmd[i]; + descr_cmd[i] = new PathDescrMoveTo(lastSeen); + lastMove = lastSeen; + hasMoved = true; + } + break; + + case descr_moveto: + { + PathDescrMoveTo *nData = dynamic_cast(descr_cmd[i]); + lastMove = lastSeen = nData->p; + hasMoved = true; + } + break; + case descr_close: + { + lastSeen=lastMove; + } + break; + case descr_lineto: + { + PathDescrLineTo *nData = dynamic_cast(descr_cmd[i]); + lastSeen=nData->p; + } + break; + case descr_cubicto: + { + PathDescrCubicTo *nData = dynamic_cast(descr_cmd[i]); + lastSeen=nData->p; + } + break; + case descr_arcto: + { + PathDescrArcTo *nData = dynamic_cast(descr_cmd[i]); + lastSeen=nData->p; + } + break; + case descr_bezierto: + { + PathDescrBezierTo *nData = dynamic_cast(descr_cmd[i]); + lastSeen=nData->p; + } + break; + case descr_interm_bezier: + { + PathDescrIntermBezierTo *nData = dynamic_cast(descr_cmd[i]); + lastSeen=nData->p; + } + break; + default: + break; + } + } +} +static int CmpPosition(const void * p1, const void * p2) { + Path::cut_position *cp1=(Path::cut_position*)p1; + Path::cut_position *cp2=(Path::cut_position*)p2; + if ( cp1->piece < cp2->piece ) return -1; + if ( cp1->piece > cp2->piece ) return 1; + if ( cp1->t < cp2->t ) return -1; + if ( cp1->t > cp2->t ) return 1; + return 0; +} +static int CmpCurv(const void * p1, const void * p2) { + double *cp1=(double*)p1; + double *cp2=(double*)p2; + if ( *cp1 < *cp2 ) return -1; + if ( *cp1 > *cp2 ) return 1; + return 0; +} + + +Path::cut_position* Path::CurvilignToPosition(int nbCv, double *cvAbs, int &nbCut) +{ + if ( nbCv <= 0 || pts.empty() || back == false ) { + return NULL; + } + + qsort(cvAbs, nbCv, sizeof(double), CmpCurv); + + cut_position *res = NULL; + nbCut = 0; + int curCv = 0; + + double len = 0; + double lastT = 0; + int lastPiece = -1; + + NR::Point lastM = pts[0].p; + NR::Point lastP = lastM; + + for (std::vector::const_iterator i = pts.begin(); i != pts.end(); i++) { + + if ( i->isMoveTo == polyline_moveto ) { + + lastP = lastM = i->p; + lastT = i->t; + lastPiece = i->piece; + + } else { + + double const add = NR::L2(i->p - lastP); + double curPos = len; + double curAdd = add; + + while ( curAdd > 0.0001 && curCv < nbCv && curPos + curAdd >= cvAbs[curCv] ) { + double const theta = (cvAbs[curCv] - len) / add; + res = (cut_position*) g_realloc(res, (nbCut + 1) * sizeof(cut_position)); + res[nbCut].piece = i->piece; + res[nbCut].t = theta * i->t + (1 - theta) * ( (lastPiece != i->piece) ? 0 : lastT); + nbCut++; + curAdd -= cvAbs[curCv] - curPos; + curPos = cvAbs[curCv]; + curCv++; + } + + len += add; + lastPiece = i->piece; + lastP = i->p; + lastT = i->t; + } + } + + return res; +} + +/* +Moved from Layout-TNG-OutIter.cpp +TODO: clean up uses of the original function and remove + +Original Comment: +"this function really belongs to Path. I'll probably move it there eventually, +hence the Path-esque coding style" + +*/ +template inline static T square(T x) {return x*x;} +Path::cut_position Path::PointToCurvilignPosition(NR::Point const &pos) const +{ + unsigned bestSeg = 0; + double bestRangeSquared = DBL_MAX; + double bestT = 0.0; // you need a sentinel, or make sure that you prime with correct values. + + for (unsigned i = 1 ; i < pts.size() ; i++) { + if (pts[i].isMoveTo == polyline_moveto) continue; + NR::Point p1, p2, localPos; + double thisRangeSquared; + double t; + + if (pts[i - 1].p == pts[i].p) { + thisRangeSquared = square(pts[i].p[NR::X] - pos[NR::X]) + square(pts[i].p[NR::Y] - pos[NR::Y]); + t = 0.0; + } else { + // we rotate all our coordinates so we're always looking at a mostly vertical line. + if (fabs(pts[i - 1].p[NR::X] - pts[i].p[NR::X]) < fabs(pts[i - 1].p[NR::Y] - pts[i].p[NR::Y])) { + p1 = pts[i - 1].p; + p2 = pts[i].p; + localPos = pos; + } else { + p1 = pts[i - 1].p.cw(); + p2 = pts[i].p.cw(); + localPos = pos.cw(); + } + double gradient = (p2[NR::X] - p1[NR::X]) / (p2[NR::Y] - p1[NR::Y]); + double intersection = p1[NR::X] - gradient * p1[NR::Y]; + /* + orthogonalGradient = -1.0 / gradient; // you are going to have numerical problems here. + orthogonalIntersection = localPos[NR::X] - orthogonalGradient * localPos[NR::Y]; + nearestY = (orthogonalIntersection - intersection) / (gradient - orthogonalGradient); + + expand out nearestY fully : + nearestY = (localPos[NR::X] - (-1.0 / gradient) * localPos[NR::Y] - intersection) / (gradient - (-1.0 / gradient)); + + multiply top and bottom by gradient: + nearestY = (localPos[NR::X] * gradient - (-1.0) * localPos[NR::Y] - intersection * gradient) / (gradient * gradient - (-1.0)); + + and simplify to get: + */ + double nearestY = (localPos[NR::X] * gradient + localPos[NR::Y] - intersection * gradient) + / (gradient * gradient + 1.0); + t = (nearestY - p1[NR::Y]) / (p2[NR::Y] - p1[NR::Y]); + if (t <= 0.0) thisRangeSquared = square(p1[NR::X] - localPos[NR::X]) + square(p1[NR::Y] - localPos[NR::Y]); + else if (t >= 1.0) thisRangeSquared = square(p2[NR::X] - localPos[NR::X]) + square(p2[NR::Y] - localPos[NR::Y]); + else thisRangeSquared = square(nearestY * gradient + intersection - localPos[NR::X]) + square(nearestY - localPos[NR::Y]); + } + + if (thisRangeSquared < bestRangeSquared) { + bestSeg = i; + bestRangeSquared = thisRangeSquared; + bestT = t; + } + } + Path::cut_position result; + if (bestSeg == 0) { + result.piece = 0; + result.t = 0.0; + } else { + result.piece = pts[bestSeg].piece; + if (result.piece == pts[bestSeg - 1].piece) + result.t = pts[bestSeg - 1].t * (1.0 - bestT) + pts[bestSeg].t * bestT; + else + result.t = pts[bestSeg].t * bestT; + } + return result; +} +/* + this one also belongs to Path + returns the length of the path up to the position indicated by t (0..1) + + TODO: clean up uses of the original function and remove + + should this take a cut_position as a parameter? +*/ +double Path::PositionToLength(int piece, double t) +{ + double length = 0.0; + for (unsigned i = 1 ; i < pts.size() ; i++) { + if (pts[i].isMoveTo == polyline_moveto) continue; + if (pts[i].piece == piece && t < pts[i].t) { + length += NR::L2((t - pts[i - 1].t) / (pts[i].t - pts[i - 1].t) * (pts[i].p - pts[i - 1].p)); + break; + } + length += NR::L2(pts[i].p - pts[i - 1].p); + } + return length; +} + +void Path::ConvertPositionsToForced(int nbPos, cut_position *poss) +{ + if ( nbPos <= 0 ) { + return; + } + + { + NR::Point lastPos(0, 0); + for (int i = int(descr_cmd.size()) - 1; i >= 0; i--) { + int const typ = descr_cmd[i]->getType(); + switch ( typ ) { + + case descr_forced: + { + PathDescrForced *d = dynamic_cast(descr_cmd[i]); + d->p = lastPos; + break; + } + + case descr_close: + { + delete descr_cmd[i]; + descr_cmd[i] = new PathDescrLineTo(NR::Point(0, 0)); + + int fp = i - 1; + while ( fp >= 0 && (descr_cmd[fp]->getType()) != descr_moveto ) { + fp--; + } + + if ( fp >= 0 ) { + PathDescrMoveTo *oData = dynamic_cast(descr_cmd[fp]); + dynamic_cast(descr_cmd[i])->p = oData->p; + } + } + break; + + case descr_bezierto: + { + PathDescrBezierTo *nData = dynamic_cast(descr_cmd[i]); + NR::Point theP = nData->p; + if ( nData->nb == 0 ) { + lastPos = theP; + } + } + break; + + case descr_moveto: + { + PathDescrMoveTo *d = dynamic_cast(descr_cmd[i]); + lastPos = d->p; + break; + } + case descr_lineto: + { + PathDescrLineTo *d = dynamic_cast(descr_cmd[i]); + lastPos = d->p; + break; + } + case descr_arcto: + { + PathDescrArcTo *d = dynamic_cast(descr_cmd[i]); + lastPos = d->p; + break; + } + case descr_cubicto: + { + PathDescrCubicTo *d = dynamic_cast(descr_cmd[i]); + lastPos = d->p; + break; + } + case descr_interm_bezier: + { + PathDescrIntermBezierTo *d = dynamic_cast(descr_cmd[i]); + lastPos = d->p; + break; + } + default: + break; + } + } + } + + qsort(poss, nbPos, sizeof(cut_position), CmpPosition); + + for (int curP=0;curP= int(descr_cmd.size()) ) break; + float ct=poss[curP].t; + if ( ct < 0 ) continue; + if ( ct > 1 ) continue; + + int const typ = descr_cmd[cp]->getType(); + if ( typ == descr_moveto || typ == descr_forced || typ == descr_close ) { + // ponctuel= rien a faire + } else if ( typ == descr_lineto || typ == descr_arcto || typ == descr_cubicto ) { + // facile: creation d'un morceau et d'un forced -> 2 commandes + NR::Point theP; + NR::Point theT; + NR::Point startP; + startP=PrevPoint(cp-1); + if ( typ == descr_cubicto ) { + double len,rad; + NR::Point stD,enD,endP; + { + PathDescrCubicTo *oData = dynamic_cast(descr_cmd[cp]); + stD=oData->start; + enD=oData->end; + endP=oData->p; + TangentOnCubAt (ct, startP, *oData,true, theP,theT,len,rad); + } + + theT*=len; + + InsertCubicTo(endP,(1-ct)*theT,(1-ct)*enD,cp+1); + InsertForcePoint(cp+1); + { + PathDescrCubicTo *nData = dynamic_cast(descr_cmd[cp]); + nData->start=ct*stD; + nData->end=ct*theT; + nData->p=theP; + } + // decalages dans le tableau des positions de coupe + for (int j=curP+1;j(descr_cmd[cp]); + endP=oData->p; + } + + theP=ct*endP+(1-ct)*startP; + + InsertLineTo(endP,cp+1); + InsertForcePoint(cp+1); + { + PathDescrLineTo *nData = dynamic_cast(descr_cmd[cp]); + nData->p=theP; + } + // decalages dans le tableau des positions de coupe + for (int j=curP+1;j(descr_cmd[cp]); + endP=oData->p; + rx=oData->rx; + ry=oData->ry; + angle=oData->angle; + clockw=oData->clockwise; + large=oData->large; + } + { + double sang,eang; + ArcAngles(startP,endP,rx,ry,angle,large,clockw,sang,eang); + + if (clockw) { + if ( sang < eang ) sang += 2*M_PI; + delta=eang-sang; + } else { + if ( sang > eang ) sang -= 2*M_PI; + delta=eang-sang; + } + if ( delta < 0 ) delta=-delta; + } + + PointAt (cp,ct, theP); + + if ( delta*(1-ct) > M_PI ) { + InsertArcTo(endP,rx,ry,angle,true,clockw,cp+1); + } else { + InsertArcTo(endP,rx,ry,angle,false,clockw,cp+1); + } + InsertForcePoint(cp+1); + { + PathDescrArcTo *nData = dynamic_cast(descr_cmd[cp]); + nData->p=theP; + if ( delta*ct > M_PI ) { + nData->clockwise=true; + } else { + nData->clockwise=false; + } + } + // decalages dans le tableau des positions de coupe + for (int j=curP+1;j= 0 && (descr_cmd[theBDI]->getType()) != descr_bezierto ) theBDI--; + if ( (descr_cmd[theBDI]->getType()) == descr_bezierto ) { + PathDescrBezierTo theBD=*(dynamic_cast(descr_cmd[theBDI])); + if ( cp >= theBDI && cp < theBDI+theBD.nb ) { + if ( theBD.nb == 1 ) { + NR::Point endP=theBD.p; + NR::Point midP; + NR::Point startP; + startP=PrevPoint(theBDI-1); + { + PathDescrIntermBezierTo *nData = dynamic_cast(descr_cmd[theBDI+1]); + midP=nData->p; + } + NR::Point aP=ct*midP+(1-ct)*startP; + NR::Point bP=ct*endP+(1-ct)*midP; + NR::Point knotP=ct*bP+(1-ct)*aP; + + InsertIntermBezierTo(bP,theBDI+2); + InsertBezierTo(knotP,1,theBDI+2); + InsertForcePoint(theBDI+2); + { + PathDescrIntermBezierTo *nData = dynamic_cast(descr_cmd[theBDI+1]); + nData->p=aP; + } + { + PathDescrBezierTo *nData = dynamic_cast(descr_cmd[theBDI]); + nData->p=knotP; + } + // decalages dans le tableau des positions de coupe + for (int j=curP+1;j theBDI ) { + NR::Point pcP,ncP; + { + PathDescrIntermBezierTo *nData = dynamic_cast(descr_cmd[cp]); + pcP=nData->p; + } + { + PathDescrIntermBezierTo *nData = dynamic_cast(descr_cmd[cp+1]); + ncP=nData->p; + } + NR::Point knotP=0.5*(pcP+ncP); + + InsertBezierTo(knotP,theBD.nb-(cp-theBDI),cp+1); + { + PathDescrBezierTo *nData = dynamic_cast(descr_cmd[theBDI]); + nData->nb=cp-theBDI; + } + + // decalages dans le tableau des positions de coupe + for (int j=curP;j(descr_cmd[cp+1]); + pcP=nData->p; + } + { + PathDescrIntermBezierTo *nData = dynamic_cast(descr_cmd[cp+2]); + ncP=nData->p; + } + NR::Point knotP=0.5*(pcP+ncP); + + InsertBezierTo(knotP,theBD.nb-1,cp+2); + { + PathDescrBezierTo *nData = dynamic_cast(descr_cmd[theBDI]); + nData->nb=1; + } + + // decalages dans le tableau des positions de coupe + for (int j=curP;jgetType(); + if ( typ == descr_moveto ) { + NR::Point np; + { + PathDescrMoveTo *nData = dynamic_cast(descr_cmd[i]); + np=nData->p; + } + NR::Point endP; + bool hasClose=false; + int hasForced=-1; + bool doesClose=false; + int j=i+1; + for (;jgetType(); + if ( ntyp == descr_moveto ) { + j--; + break; + } else if ( ntyp == descr_forced ) { + if ( hasForced < 0 ) hasForced=j; + } else if ( ntyp == descr_close ) { + hasClose=true; + break; + } else if ( ntyp == descr_lineto ) { + PathDescrLineTo *nData = dynamic_cast(descr_cmd[j]); + endP=nData->p; + } else if ( ntyp == descr_arcto ) { + PathDescrArcTo *nData = dynamic_cast(descr_cmd[j]); + endP=nData->p; + } else if ( ntyp == descr_cubicto ) { + PathDescrCubicTo *nData = dynamic_cast(descr_cmd[j]); + endP=nData->p; + } else if ( ntyp == descr_bezierto ) { + PathDescrBezierTo *nData = dynamic_cast(descr_cmd[j]); + endP=nData->p; + } else { + } + } + if ( NR::LInfty(endP-np) < 0.00001 ) { + doesClose=true; + } + if ( ( doesClose || hasClose ) && hasForced >= 0 ) { + // printf("nasty i=%i j=%i frc=%i\n",i,j,hasForced); + // aghhh. + NR::Point nMvtP=PrevPoint(hasForced); + res->MoveTo(nMvtP); + NR::Point nLastP=nMvtP; + for (int k = hasForced + 1; k < j; k++) { + int ntyp=descr_cmd[k]->getType(); + if ( ntyp == descr_moveto ) { + // ne doit pas arriver + } else if ( ntyp == descr_forced ) { + res->MoveTo(nLastP); + } else if ( ntyp == descr_close ) { + // rien a faire ici; de plus il ne peut y en avoir qu'un + } else if ( ntyp == descr_lineto ) { + PathDescrLineTo *nData = dynamic_cast(descr_cmd[k]); + res->LineTo(nData->p); + nLastP=nData->p; + } else if ( ntyp == descr_arcto ) { + PathDescrArcTo *nData = dynamic_cast(descr_cmd[k]); + res->ArcTo(nData->p,nData->rx,nData->ry,nData->angle,nData->large,nData->clockwise); + nLastP=nData->p; + } else if ( ntyp == descr_cubicto ) { + PathDescrCubicTo *nData = dynamic_cast(descr_cmd[k]); + res->CubicTo(nData->p,nData->start,nData->end); + nLastP=nData->p; + } else if ( ntyp == descr_bezierto ) { + PathDescrBezierTo *nData = dynamic_cast(descr_cmd[k]); + res->BezierTo(nData->p); + nLastP=nData->p; + } else if ( ntyp == descr_interm_bezier ) { + PathDescrIntermBezierTo *nData = dynamic_cast(descr_cmd[k]); + res->IntermBezierTo(nData->p); + } else { + } + } + if ( doesClose == false ) res->LineTo(np); + nLastP=np; + for (int k=i+1;kgetType(); + if ( ntyp == descr_moveto ) { + // ne doit pas arriver + } else if ( ntyp == descr_forced ) { + res->MoveTo(nLastP); + } else if ( ntyp == descr_close ) { + // rien a faire ici; de plus il ne peut y en avoir qu'un + } else if ( ntyp == descr_lineto ) { + PathDescrLineTo *nData = dynamic_cast(descr_cmd[k]); + res->LineTo(nData->p); + nLastP=nData->p; + } else if ( ntyp == descr_arcto ) { + PathDescrArcTo *nData = dynamic_cast(descr_cmd[k]); + res->ArcTo(nData->p,nData->rx,nData->ry,nData->angle,nData->large,nData->clockwise); + nLastP=nData->p; + } else if ( ntyp == descr_cubicto ) { + PathDescrCubicTo *nData = dynamic_cast(descr_cmd[k]); + res->CubicTo(nData->p,nData->start,nData->end); + nLastP=nData->p; + } else if ( ntyp == descr_bezierto ) { + PathDescrBezierTo *nData = dynamic_cast(descr_cmd[k]); + res->BezierTo(nData->p); + nLastP=nData->p; + } else if ( ntyp == descr_interm_bezier ) { + PathDescrIntermBezierTo *nData = dynamic_cast(descr_cmd[k]); + res->IntermBezierTo(nData->p); + } else { + } + } + lastP=nMvtP; + i=j; + } else { + // regular, just move on + res->MoveTo(np); + lastP=np; + } + } else if ( typ == descr_close ) { + res->Close(); + } else if ( typ == descr_forced ) { + res->MoveTo(lastP); + } else if ( typ == descr_lineto ) { + PathDescrLineTo *nData = dynamic_cast(descr_cmd[i]); + res->LineTo(nData->p); + lastP=nData->p; + } else if ( typ == descr_arcto ) { + PathDescrArcTo *nData = dynamic_cast(descr_cmd[i]); + res->ArcTo(nData->p,nData->rx,nData->ry,nData->angle,nData->large,nData->clockwise); + lastP=nData->p; + } else if ( typ == descr_cubicto ) { + PathDescrCubicTo *nData = dynamic_cast(descr_cmd[i]); + res->CubicTo(nData->p,nData->start,nData->end); + lastP=nData->p; + } else if ( typ == descr_bezierto ) { + PathDescrBezierTo *nData = dynamic_cast(descr_cmd[i]); + res->BezierTo(nData->p); + lastP=nData->p; + } else if ( typ == descr_interm_bezier ) { + PathDescrIntermBezierTo *nData = dynamic_cast(descr_cmd[i]); + res->IntermBezierTo(nData->p); + } else { + } + } + + Copy(res); + delete res; + return; +} + +/* + 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:textwidth=99 : diff --git a/src/livarot/PathOutline.cpp b/src/livarot/PathOutline.cpp new file mode 100644 index 000000000..ee656f900 --- /dev/null +++ b/src/livarot/PathOutline.cpp @@ -0,0 +1,1493 @@ +/* + * PathOutline.cpp + * nlivarot + * + * Created by fred on Fri Nov 28 2003. + * + */ + +#include "livarot/Path.h" +#include "livarot/path-description.h" +#include + +/* + * the "outliner" + * takes a sequence of path commands and produces a set of commands that approximates the offset + * result is stored in dest (that paremeter is handed to all the subfunctions) + * not that the result is in general not mathematically correct; you can end up with unwanted holes in your + * beautiful offset. a better way is to do path->polyline->polygon->offset of polygon->polyline(=contours of the polygon)->path + * but computing offsets of the path is faster... + */ + +// outline of a path. +// computed by making 2 offsets, one of the "left" side of the path, one of the right side, and then glueing the two +// the left side has to be reversed to make a contour +void Path::Outline(Path *dest, double width, JoinType join, ButtType butt, double miter) +{ + if ( descr_flags & descr_adding_bezier ) { + CancelBezier(); + } + if ( descr_flags & descr_doing_subpath ) { + CloseSubpath(); + } + if ( descr_cmd.size() <= 1 ) { + return; + } + if ( dest == NULL ) { + return; + } + + dest->Reset(); + dest->SetBackData(false); + + outline_callbacks calls; + NR::Point endButt; + NR::Point endPos; + calls.cubicto = StdCubicTo; + calls.bezierto = StdBezierTo; + calls.arcto = StdArcTo; + + Path *rev = new Path; + + // we repeat the offset contour creation for each subpath + int curP = 0; + do { + int lastM = curP; + do { + curP++; + if (curP >= int(descr_cmd.size())) { + break; + } + int typ = descr_cmd[curP]->getType(); + if (typ == descr_moveto) { + break; + } + } while (curP < int(descr_cmd.size())); + + if (curP >= int(descr_cmd.size())) { + curP = descr_cmd.size(); + } + + if (curP > lastM + 1) { + // we have isolated a subpath, now we make a reversed version of it + // we do so by taking the subpath in the reverse and constructing a path as appropriate + // the construct is stored in "rev" + int curD = curP - 1; + NR::Point curX; + NR::Point nextX; + int firstTyp = descr_cmd[curD]->getType(); + bool const needClose = (firstTyp == descr_close); + while (curD > lastM && descr_cmd[curD]->getType() == descr_close) { + curD--; + } + + int realP = curD + 1; + if (curD > lastM) { + curX = PrevPoint(curD); + rev->Reset (); + rev->MoveTo(curX); + while (curD > lastM) { + int const typ = descr_cmd[curD]->getType(); + if (typ == descr_moveto) { + // rev->Close(); + curD--; + } else if (typ == descr_forced) { + // rev->Close(); + curD--; + } else if (typ == descr_lineto) { + nextX = PrevPoint (curD - 1); + rev->LineTo (nextX); + curX = nextX; + curD--; + } else if (typ == descr_cubicto) { + PathDescrCubicTo* nData = dynamic_cast(descr_cmd[curD]); + nextX = PrevPoint (curD - 1); + NR::Point isD=-nData->start; + NR::Point ieD=-nData->end; + rev->CubicTo (nextX, ieD,isD); + curX = nextX; + curD--; + } else if (typ == descr_arcto) { + PathDescrArcTo* nData = dynamic_cast(descr_cmd[curD]); + nextX = PrevPoint (curD - 1); + rev->ArcTo (nextX, nData->rx,nData->ry,nData->angle,nData->large,nData->clockwise); + curX = nextX; + curD--; + } else if (typ == descr_bezierto) { + nextX = PrevPoint (curD - 1); + rev->LineTo (nextX); + curX = nextX; + curD--; + } else if (typ == descr_interm_bezier) { + int nD = curD - 1; + while (nD > lastM && descr_cmd[nD]->getType() != descr_bezierto) nD--; + if ((descr_cmd[nD]->getType()) != descr_bezierto) { + // pas trouve le debut!? + // Not find the start?! + nextX = PrevPoint (nD); + rev->LineTo (nextX); + curX = nextX; + } else { + nextX = PrevPoint (nD - 1); + rev->BezierTo (nextX); + for (int i = curD; i > nD; i--) { + PathDescrIntermBezierTo* nData = dynamic_cast(descr_cmd[i]); + rev->IntermBezierTo (nData->p); + } + rev->EndBezierTo (); + curX = nextX; + } + curD = nD - 1; + } else { + curD--; + } + } + + // offset the paths and glue everything + // actual offseting is done in SubContractOutline() + if (needClose) { + rev->Close (); + rev->SubContractOutline (0, rev->descr_cmd.size(), + dest, calls, 0.0025 * width * width, width, + join, butt, miter, true, false, endPos, endButt); + SubContractOutline (lastM, realP + 1 - lastM, + dest, calls, 0.0025 * width * width, + width, join, butt, miter, true, false, endPos, endButt); + } else { + rev->SubContractOutline (0, rev->descr_cmd.size(), + dest, calls, 0.0025 * width * width, width, + join, butt, miter, false, false, endPos, endButt); + NR::Point endNor=endButt.ccw(); + if (butt == butt_round) { + dest->ArcTo (endPos+width*endNor, 1.0001 * width, 1.0001 * width, 0.0, true, true); + } else if (butt == butt_square) { + dest->LineTo (endPos-width*endNor+width*endButt); + dest->LineTo (endPos+width*endNor+width*endButt); + dest->LineTo (endPos+width*endNor); + } else if (butt == butt_pointy) { + dest->LineTo (endPos+width*endButt); + dest->LineTo (endPos+width*endNor); + } else { + dest->LineTo (endPos+width*endNor); + } + SubContractOutline (lastM, realP - lastM, + dest, calls, 0.0025 * width * width, width, join, butt, + miter, false, true, endPos, endButt); + + endNor=endButt.ccw(); + if (butt == butt_round) { + dest->ArcTo (endPos+width*endNor, 1.0001 * width, 1.0001 * width, 0.0, true, true); + } else if (butt == butt_square) { + dest->LineTo (endPos-width*endNor+width*endButt); + dest->LineTo (endPos+width*endNor+width*endButt); + dest->LineTo (endPos+width*endNor); + } else if (butt == butt_pointy) { + dest->LineTo (endPos+width*endButt); + dest->LineTo (endPos+width*endNor); + } else { + dest->LineTo (endPos+width*endNor); + } + dest->Close (); + } + } // if (curD > lastM) + } // if (curP > lastM + 1) + + } while (curP < int(descr_cmd.size())); + + delete rev; +} + +// versions for outlining closed path: they only make one side of the offset contour +void +Path::OutsideOutline (Path * dest, double width, JoinType join, ButtType butt, + double miter) +{ + if (descr_flags & descr_adding_bezier) { + CancelBezier(); + } + if (descr_flags & descr_doing_subpath) { + CloseSubpath(); + } + if (int(descr_cmd.size()) <= 1) return; + if (dest == NULL) return; + dest->Reset (); + dest->SetBackData (false); + + outline_callbacks calls; + NR::Point endButt, endPos; + calls.cubicto = StdCubicTo; + calls.bezierto = StdBezierTo; + calls.arcto = StdArcTo; + SubContractOutline (0, descr_cmd.size(), + dest, calls, 0.0025 * width * width, width, join, butt, + miter, true, false, endPos, endButt); +} + +void +Path::InsideOutline (Path * dest, double width, JoinType join, ButtType butt, + double miter) +{ + if ( descr_flags & descr_adding_bezier ) { + CancelBezier(); + } + if ( descr_flags & descr_doing_subpath ) { + CloseSubpath(); + } + if (int(descr_cmd.size()) <= 1) return; + if (dest == NULL) return; + dest->Reset (); + dest->SetBackData (false); + + outline_callbacks calls; + NR::Point endButt, endPos; + calls.cubicto = StdCubicTo; + calls.bezierto = StdBezierTo; + calls.arcto = StdArcTo; + + Path *rev = new Path; + + int curP = 0; + do { + int lastM = curP; + do { + curP++; + if (curP >= int(descr_cmd.size())) break; + int typ = descr_cmd[curP]->getType(); + if (typ == descr_moveto) break; + } while (curP < int(descr_cmd.size())); + if (curP >= int(descr_cmd.size())) curP = descr_cmd.size(); + if (curP > lastM + 1) { + // Otherwise there's only one point. (tr: or "only a point") + // [sinon il n'y a qu'un point] + int curD = curP - 1; + NR::Point curX; + NR::Point nextX; + while (curD > lastM && (descr_cmd[curD]->getType()) == descr_close) curD--; + if (curD > lastM) { + curX = PrevPoint (curD); + rev->Reset (); + rev->MoveTo (curX); + while (curD > lastM) { + int typ = descr_cmd[curD]->getType(); + if (typ == descr_moveto) { + rev->Close (); + curD--; + } else if (typ == descr_forced) { + curD--; + } else if (typ == descr_lineto) { + nextX = PrevPoint (curD - 1); + rev->LineTo (nextX); + curX = nextX; + curD--; + } else if (typ == descr_cubicto) { + PathDescrCubicTo *nData = dynamic_cast(descr_cmd[curD]); + nextX = PrevPoint (curD - 1); + NR::Point isD=-nData->start; + NR::Point ieD=-nData->end; + rev->CubicTo (nextX, ieD,isD); + curX = nextX; + curD--; + } else if (typ == descr_arcto) { + PathDescrArcTo* nData = dynamic_cast(descr_cmd[curD]); + nextX = PrevPoint (curD - 1); + rev->ArcTo (nextX, nData->rx,nData->ry,nData->angle,nData->large,nData->clockwise); + curX = nextX; + curD--; + } else if (typ == descr_bezierto) { + nextX = PrevPoint (curD - 1); + rev->LineTo (nextX); + curX = nextX; + curD--; + } else if (typ == descr_interm_bezier) { + int nD = curD - 1; + while (nD > lastM && (descr_cmd[nD]->getType()) != descr_bezierto) nD--; + if (descr_cmd[nD]->getType() != descr_bezierto) { + // pas trouve le debut!? + nextX = PrevPoint (nD); + rev->LineTo (nextX); + curX = nextX; + } else { + nextX = PrevPoint (nD - 1); + rev->BezierTo (nextX); + for (int i = curD; i > nD; i--) { + PathDescrIntermBezierTo* nData = dynamic_cast(descr_cmd[i]); + rev->IntermBezierTo (nData->p); + } + rev->EndBezierTo (); + curX = nextX; + } + curD = nD - 1; + } else { + curD--; + } + } + rev->Close (); + rev->SubContractOutline (0, rev->descr_cmd.size(), + dest, calls, 0.0025 * width * width, + width, join, butt, miter, true, false, + endPos, endButt); + } + } + } while (curP < int(descr_cmd.size())); + + delete rev; +} + + +// the offset +// take each command and offset it. +// the bezier spline is split in a sequence of bezier curves, and these are transformed in cubic bezier (which is +// not hard since they are quadratic bezier) +// joins are put where needed +void Path::SubContractOutline(int off, int num_pd, + Path *dest, outline_callbacks & calls, + double tolerance, double width, JoinType join, + ButtType butt, double miter, bool closeIfNeeded, + bool skipMoveto, NR::Point &lastP, NR::Point &lastT) +{ + outline_callback_data callsData; + + callsData.orig = this; + callsData.dest = dest; + int curP = 1; + + // le moveto + NR::Point curX; + { + int firstTyp = descr_cmd[off]->getType(); + if ( firstTyp != descr_moveto ) { + curX[0] = curX[1] = 0; + curP = 0; + } else { + PathDescrMoveTo* nData = dynamic_cast(descr_cmd[off]); + curX = nData->p; + } + } + NR::Point curT(0, 0); + + bool doFirst = true; + NR::Point firstP(0, 0); + NR::Point firstT(0, 0); + + // et le reste, 1 par 1 + while (curP < num_pd) + { + int curD = off + curP; + int nType = descr_cmd[curD]->getType(); + NR::Point nextX; + NR::Point stPos, enPos, stTgt, enTgt, stNor, enNor; + double stRad, enRad, stTle, enTle; + if (nType == descr_forced) { + curP++; + } else if (nType == descr_moveto) { + PathDescrMoveTo* nData = dynamic_cast(descr_cmd[curD]); + nextX = nData->p; + // et on avance + if (doFirst) { + } else { + if (closeIfNeeded) { + if ( NR::LInfty (curX- firstP) < 0.0001 ) { + OutlineJoin (dest, firstP, curT, firstT, width, join, + miter); + dest->Close (); + } else { + PathDescrLineTo temp(firstP); + + TangentOnSegAt (0.0, curX, temp, stPos, stTgt, + stTle); + TangentOnSegAt (1.0, curX, temp, enPos, enTgt, + enTle); + stNor=stTgt.cw(); + enNor=enTgt.cw(); + + // jointure + { + NR::Point pos; + pos = curX; + OutlineJoin (dest, pos, curT, stNor, width, join, + miter); + } + dest->LineTo (enPos+width*enNor); + + // jointure + { + NR::Point pos; + pos = firstP; + OutlineJoin (dest, enPos, enNor, firstT, width, join, + miter); + dest->Close (); + } + } + } + } + firstP = nextX; + curP++; + } + else if (nType == descr_close) + { + if (doFirst == false) + { + if (NR::LInfty (curX - firstP) < 0.0001) + { + OutlineJoin (dest, firstP, curT, firstT, width, join, + miter); + dest->Close (); + } + else + { + PathDescrLineTo temp(firstP); + nextX = firstP; + + TangentOnSegAt (0.0, curX, temp, stPos, stTgt, stTle); + TangentOnSegAt (1.0, curX, temp, enPos, enTgt, enTle); + stNor=stTgt.cw(); + enNor=enTgt.cw(); + + // jointure + { + OutlineJoin (dest, stPos, curT, stNor, width, join, + miter); + } + + dest->LineTo (enPos+width*enNor); + + // jointure + { + OutlineJoin (dest, enPos, enNor, firstT, width, join, + miter); + dest->Close (); + } + } + } + doFirst = true; + curP++; + } + else if (nType == descr_lineto) + { + PathDescrLineTo* nData = dynamic_cast(descr_cmd[curD]); + nextX = nData->p; + // test de nullité du segment + if (IsNulCurve (descr_cmd, curD, curX)) + { + curP++; + continue; + } + // et on avance + TangentOnSegAt (0.0, curX, *nData, stPos, stTgt, stTle); + TangentOnSegAt (1.0, curX, *nData, enPos, enTgt, enTle); + stNor=stTgt.cw(); + enNor=enTgt.cw(); + + lastP = enPos; + lastT = enTgt; + + if (doFirst) + { + doFirst = false; + firstP = stPos; + firstT = stNor; + if (skipMoveto) + { + skipMoveto = false; + } + else + dest->MoveTo (curX+width*stNor); + } + else + { + // jointure + NR::Point pos; + pos = curX; + OutlineJoin (dest, pos, curT, stNor, width, join, miter); + } + + int n_d = dest->LineTo (nextX+width*enNor); + if (n_d >= 0) + { + dest->descr_cmd[n_d]->associated = curP; + dest->descr_cmd[n_d]->tSt = 0.0; + dest->descr_cmd[n_d]->tEn = 1.0; + } + curP++; + } + else if (nType == descr_cubicto) + { + PathDescrCubicTo* nData = dynamic_cast(descr_cmd[curD]); + nextX = nData->p; + // test de nullite du segment + if (IsNulCurve (descr_cmd, curD, curX)) + { + curP++; + continue; + } + // et on avance + TangentOnCubAt (0.0, curX, *nData, false, stPos, stTgt, + stTle, stRad); + TangentOnCubAt (1.0, curX, *nData, true, enPos, enTgt, + enTle, enRad); + stNor=stTgt.cw(); + enNor=enTgt.cw(); + + lastP = enPos; + lastT = enTgt; + + if (doFirst) + { + doFirst = false; + firstP = stPos; + firstT = stNor; + if (skipMoveto) + { + skipMoveto = false; + } + else + dest->MoveTo (curX+width*stNor); + } + else + { + // jointure + NR::Point pos; + pos = curX; + OutlineJoin (dest, pos, curT, stNor, width, join, miter); + } + + callsData.piece = curP; + callsData.tSt = 0.0; + callsData.tEn = 1.0; + callsData.x1 = curX[0]; + callsData.y1 = curX[1]; + callsData.x2 = nextX[0]; + callsData.y2 = nextX[1]; + callsData.d.c.dx1 = nData->start[0]; + callsData.d.c.dy1 = nData->start[1]; + callsData.d.c.dx2 = nData->end[0]; + callsData.d.c.dy2 = nData->end[1]; + (calls.cubicto) (&callsData, tolerance, width); + + curP++; + } + else if (nType == descr_arcto) + { + PathDescrArcTo* nData = dynamic_cast(descr_cmd[curD]); + nextX = nData->p; + // test de nullité du segment + if (IsNulCurve (descr_cmd, curD, curX)) + { + curP++; + continue; + } + // et on avance + TangentOnArcAt (0.0, curX, *nData, stPos, stTgt, stTle, + stRad); + TangentOnArcAt (1.0, curX, *nData, enPos, enTgt, enTle, + enRad); + stNor=stTgt.cw(); + enNor=enTgt.cw(); + + lastP = enPos; + lastT = enTgt; // tjs definie + + if (doFirst) + { + doFirst = false; + firstP = stPos; + firstT = stNor; + if (skipMoveto) + { + skipMoveto = false; + } + else + dest->MoveTo (curX+width*stNor); + } + else + { + // jointure + NR::Point pos; + pos = curX; + OutlineJoin (dest, pos, curT, stNor, width, join, miter); + } + + callsData.piece = curP; + callsData.tSt = 0.0; + callsData.tEn = 1.0; + callsData.x1 = curX[0]; + callsData.y1 = curX[1]; + callsData.x2 = nextX[0]; + callsData.y2 = nextX[1]; + callsData.d.a.rx = nData->rx; + callsData.d.a.ry = nData->ry; + callsData.d.a.angle = nData->angle; + callsData.d.a.clock = nData->clockwise; + callsData.d.a.large = nData->large; + (calls.arcto) (&callsData, tolerance, width); + + curP++; + } + else if (nType == descr_bezierto) + { + PathDescrBezierTo* nBData = dynamic_cast(descr_cmd[curD]); + int nbInterm = nBData->nb; + nextX = nBData->p; + + if (IsNulCurve (descr_cmd, curD, curX)) { + curP += nbInterm + 1; + continue; + } + + curP++; + + curD = off + curP; + int ip = curD; + PathDescrIntermBezierTo* nData = dynamic_cast(descr_cmd[ip]); + + if (nbInterm <= 0) { + // et on avance + PathDescrLineTo temp(nextX); + TangentOnSegAt (0.0, curX, temp, stPos, stTgt, stTle); + TangentOnSegAt (1.0, curX, temp, enPos, enTgt, enTle); + stNor=stTgt.cw(); + enNor=enTgt.cw(); + + lastP = enPos; + lastT = enTgt; + + if (doFirst) { + doFirst = false; + firstP = stPos; + firstT = stNor; + if (skipMoveto) { + skipMoveto = false; + } else dest->MoveTo (curX+width*stNor); + } else { + // jointure + NR::Point pos; + pos = curX; + if (stTle > 0) OutlineJoin (dest, pos, curT, stNor, width, join, miter); + } + int n_d = dest->LineTo (nextX+width*enNor); + if (n_d >= 0) { + dest->descr_cmd[n_d]->associated = curP - 1; + dest->descr_cmd[n_d]->tSt = 0.0; + dest->descr_cmd[n_d]->tEn = 1.0; + } + } else if (nbInterm == 1) { + NR::Point midX; + midX = nData->p; + // et on avance + TangentOnBezAt (0.0, curX, *nData, *nBData, false, stPos, stTgt, stTle, stRad); + TangentOnBezAt (1.0, curX, *nData, *nBData, true, enPos, enTgt, enTle, enRad); + stNor=stTgt.cw(); + enNor=enTgt.cw(); + + lastP = enPos; + lastT = enTgt; + + if (doFirst) { + doFirst = false; + firstP = stPos; + firstT = stNor; + if (skipMoveto) { + skipMoveto = false; + } else dest->MoveTo (curX+width*stNor); + } else { + // jointure + NR::Point pos; + pos = curX; + OutlineJoin (dest, pos, curT, stNor, width, join, miter); + } + + callsData.piece = curP; + callsData.tSt = 0.0; + callsData.tEn = 1.0; + callsData.x1 = curX[0]; + callsData.y1 = curX[1]; + callsData.x2 = nextX[0]; + callsData.y2 = nextX[1]; + callsData.d.b.mx = midX[0]; + callsData.d.b.my = midX[1]; + (calls.bezierto) (&callsData, tolerance, width); + + } else if (nbInterm > 1) { + NR::Point bx=curX; + NR::Point cx=curX; + NR::Point dx=curX; + + dx = nData->p; + TangentOnBezAt (0.0, curX, *nData, *nBData, false, stPos, stTgt, stTle, stRad); + stNor=stTgt.cw(); + + ip++; + nData = dynamic_cast(descr_cmd[ip]); + // et on avance + if (stTle > 0) { + if (doFirst) { + doFirst = false; + firstP = stPos; + firstT = stNor; + if (skipMoveto) { + skipMoveto = false; + } else dest->MoveTo (curX+width*stNor); + } else { + // jointure + NR::Point pos=curX; + OutlineJoin (dest, pos, stTgt, stNor, width, join, miter); + // dest->LineTo(curX+width*stNor.x,curY+width*stNor.y); + } + } + + cx = 2 * bx - dx; + + for (int k = 0; k < nbInterm - 1; k++) { + bx = cx; + cx = dx; + + dx = nData->p; + ip++; + nData = dynamic_cast(descr_cmd[ip]); + NR::Point stx = (bx + cx) / 2; + // double stw=(bw+cw)/2; + + PathDescrBezierTo tempb((cx + dx) / 2, 1); + PathDescrIntermBezierTo tempi(cx); + TangentOnBezAt (1.0, stx, tempi, tempb, true, enPos, enTgt, enTle, enRad); + enNor=enTgt.cw(); + + lastP = enPos; + lastT = enTgt; + + callsData.piece = curP + k; + callsData.tSt = 0.0; + callsData.tEn = 1.0; + callsData.x1 = stx[0]; + callsData.y1 = stx[1]; + callsData.x2 = (cx[0] + dx[0]) / 2; + callsData.y2 = (cx[1] + dx[1]) / 2; + callsData.d.b.mx = cx[0]; + callsData.d.b.my = cx[1]; + (calls.bezierto) (&callsData, tolerance, width); + } + { + bx = cx; + cx = dx; + + dx = nextX; + dx = 2 * dx - cx; + + NR::Point stx = (bx + cx) / 2; + // double stw=(bw+cw)/2; + + PathDescrBezierTo tempb((cx + dx) / 2, 1); + PathDescrIntermBezierTo tempi(cx); + TangentOnBezAt (1.0, stx, tempi, tempb, true, enPos, + enTgt, enTle, enRad); + enNor=enTgt.cw(); + + lastP = enPos; + lastT = enTgt; + + callsData.piece = curP + nbInterm - 1; + callsData.tSt = 0.0; + callsData.tEn = 1.0; + callsData.x1 = stx[0]; + callsData.y1 = stx[1]; + callsData.x2 = (cx[0] + dx[0]) / 2; + callsData.y2 = (cx[1] + dx[1]) / 2; + callsData.d.b.mx = cx[0]; + callsData.d.b.my = cx[1]; + (calls.bezierto) (&callsData, tolerance, width); + + } + } + + // et on avance + curP += nbInterm; + } + curX = nextX; + curT = enNor; // sera tjs bien definie + } + if (closeIfNeeded) + { + if (doFirst == false) + { + } + } + +} + +/* + * + * utilitaires pour l'outline + * + */ + +// like the name says: check whether the path command is actually more than a dumb point. +bool +Path::IsNulCurve (std::vector const &cmd, int curD, NR::Point const &curX) +{ + switch(cmd[curD]->getType()) { + case descr_lineto: + { + PathDescrLineTo *nData = dynamic_cast(cmd[curD]); + if (NR::LInfty(nData->p - curX) < 0.00001) { + return true; + } + return false; + } + case descr_cubicto: + { + PathDescrCubicTo *nData = dynamic_cast(cmd[curD]); + NR::Point A = nData->start + nData->end + 2*(curX - nData->p); + NR::Point B = 3*(nData->p - curX) - 2*nData->start - nData->end; + NR::Point C = nData->start; + if (NR::LInfty(A) < 0.0001 + && NR::LInfty(B) < 0.0001 + && NR::LInfty (C) < 0.0001) { + return true; + } + return false; + } + case descr_arcto: + { + PathDescrArcTo* nData = dynamic_cast(cmd[curD]); + if ( NR::LInfty(nData->p - curX) < 0.00001) { + if ((nData->large == false) + || (fabs (nData->rx) < 0.00001 + || fabs (nData->ry) < 0.00001)) { + return true; + } + } + return false; + } + case descr_bezierto: + { + PathDescrBezierTo* nBData = dynamic_cast(cmd[curD]); + if (nBData->nb <= 0) + { + if (NR::LInfty(nBData->p - curX) < 0.00001) { + return true; + } + return false; + } + else if (nBData->nb == 1) + { + if (NR::LInfty(nBData->p - curX) < 0.00001) { + int ip = curD + 1; + PathDescrIntermBezierTo* nData = dynamic_cast(cmd[ip]); + if (NR::LInfty(nData->p - curX) < 0.00001) { + return true; + } + } + return false; + } else if (NR::LInfty(nBData->p - curX) < 0.00001) { + for (int i = 1; i <= nBData->nb; i++) { + int ip = curD + i; + PathDescrIntermBezierTo* nData = dynamic_cast(cmd[ip]); + if (NR::LInfty(nData->p - curX) > 0.00001) { + return false; + } + } + return true; + } + } + default: + return true; + } +} + +// tangents and cuvarture computing, for the different path command types. +// the need for tangent is obvious: it gives the normal, along which we offset points +// curvature is used to do strength correction on the length of the tangents to the offset (see +// cubic offset) + +/** + * \param at Distance along a tangent (0 <= at <= 1). + * \param iS Start point. + * \param fin LineTo description containing end point. + * \param pos Filled in with the position of `at' on the segment. + * \param tgt Filled in with the normalised tangent vector. + * \param len Filled in with the length of the segment. + */ + +void Path::TangentOnSegAt(double at, NR::Point const &iS, PathDescrLineTo const &fin, + NR::Point &pos, NR::Point &tgt, double &len) +{ + NR::Point const iE = fin.p; + NR::Point const seg = iE - iS; + double const l = L2(seg); + if (l <= 0.000001) { + pos = iS; + tgt = NR::Point(0, 0); + len = 0; + } else { + tgt = seg / l; + pos = (1 - at) * iS + at * iE; // in other words, pos = iS + at * seg + len = l; + } +} + +// barf +void Path::TangentOnArcAt(double at, const NR::Point &iS, PathDescrArcTo const &fin, + NR::Point &pos, NR::Point &tgt, double &len, double &rad) +{ + NR::Point const iE = fin.p; + double const rx = fin.rx; + double const ry = fin.ry; + double const angle = fin.angle; + bool const large = fin.large; + bool const wise = fin.clockwise; + + pos = iS; + tgt[0] = tgt[1] = 0; + if (rx <= 0.0001 || ry <= 0.0001) + return; + + double const sex = iE[0] - iS[0], sey = iE[1] - iS[1]; + double const ca = cos (angle), sa = sin (angle); + double csex = ca * sex + sa * sey; + double csey = -sa * sex + ca * sey; + csex /= rx; + csey /= ry; + double l = csex * csex + csey * csey; + if (l >= 4) + return; + double const d = sqrt(std::max(1 - l / 4, 0.0)); + double csdx = csey; + double csdy = -csex; + l = sqrt(l); + csdx /= l; + csdy /= l; + csdx *= d; + csdy *= d; + + double sang; + double eang; + double rax = -csdx - csex / 2; + double ray = -csdy - csey / 2; + if (rax < -1) + { + sang = M_PI; + } + else if (rax > 1) + { + sang = 0; + } + else + { + sang = acos (rax); + if (ray < 0) + sang = 2 * M_PI - sang; + } + rax = -csdx + csex / 2; + ray = -csdy + csey / 2; + if (rax < -1) + { + eang = M_PI; + } + else if (rax > 1) + { + eang = 0; + } + else + { + eang = acos (rax); + if (ray < 0) + eang = 2 * M_PI - eang; + } + + csdx *= rx; + csdy *= ry; + double drx = ca * csdx - sa * csdy; + double dry = sa * csdx + ca * csdy; + + if (wise) + { + if (large == true) + { + drx = -drx; + dry = -dry; + double swap = eang; + eang = sang; + sang = swap; + eang += M_PI; + sang += M_PI; + if (eang >= 2 * M_PI) + eang -= 2 * M_PI; + if (sang >= 2 * M_PI) + sang -= 2 * M_PI; + } + } + else + { + if (large == false) + { + drx = -drx; + dry = -dry; + double swap = eang; + eang = sang; + sang = swap; + eang += M_PI; + sang += M_PI; + if (eang >= 2 * M_PI) + eang -= 2 * M_PI; + if (sang >= 2 * M_PI) + sang -= 2 * M_PI; + } + } + drx += (iS[0] + iE[0]) / 2; + dry += (iS[1] + iE[1]) / 2; + + if (wise) { + if (sang < eang) + sang += 2 * M_PI; + double b = sang * (1 - at) + eang * at; + double cb = cos (b), sb = sin (b); + pos[0] = drx + ca * rx * cb - sa * ry * sb; + pos[1] = dry + sa * rx * cb + ca * ry * sb; + tgt[0] = ca * rx * sb + sa * ry * cb; + tgt[1] = sa * rx * sb - ca * ry * cb; + NR::Point dtgt; + dtgt[0] = -ca * rx * cb + sa * ry * sb; + dtgt[1] = -sa * rx * cb - ca * ry * sb; + len = L2(tgt); + rad = len * dot(tgt, tgt) / (tgt[0] * dtgt[1] - tgt[1] * dtgt[0]); + tgt /= len; + } + else + { + if (sang > eang) + sang -= 2 * M_PI; + double b = sang * (1 - at) + eang * at; + double cb = cos (b), sb = sin (b); + pos[0] = drx + ca * rx * cb - sa * ry * sb; + pos[1] = dry + sa * rx * cb + ca * ry * sb; + tgt[0] = ca * rx * sb + sa * ry * cb; + tgt[1] = sa * rx * sb - ca * ry * cb; + NR::Point dtgt; + dtgt[0] = -ca * rx * cb + sa * ry * sb; + dtgt[1] = -sa * rx * cb - ca * ry * sb; + len = L2(tgt); + rad = len * dot(tgt, tgt) / (tgt[0] * dtgt[1] - tgt[1] * dtgt[0]); + tgt /= len; + } +} +void +Path::TangentOnCubAt (double at, NR::Point const &iS, PathDescrCubicTo const &fin, bool before, + NR::Point &pos, NR::Point &tgt, double &len, double &rad) +{ + const NR::Point E = fin.p; + const NR::Point Sd = fin.start; + const NR::Point Ed = fin.end; + + pos = iS; + tgt = NR::Point(0,0); + len = rad = 0; + + const NR::Point A = Sd + Ed - 2*E + 2*iS; + const NR::Point B = 0.5*(Ed - Sd); + const NR::Point C = 0.25*(6*E - 6*iS - Sd - Ed); + const NR::Point D = 0.125*(4*iS + 4*E - Ed + Sd); + const double atb = at - 0.5; + pos = (atb * atb * atb)*A + (atb * atb)*B + atb*C + D; + const NR::Point der = (3 * atb * atb)*A + (2 * atb)*B + C; + const NR::Point dder = (6 * atb)*A + 2*B; + const NR::Point ddder = 6 * A; + + double l = NR::L2 (der); + // lots of nasty cases. inversion points are sadly too common... + if (l <= 0.0001) { + len = 0; + l = L2(dder); + if (l <= 0.0001) { + l = L2(ddder); + if (l <= 0.0001) { + // pas de segment.... + return; + } + rad = 100000000; + tgt = ddder / l; + if (before) { + tgt = -tgt; + } + return; + } + rad = -l * (dot(dder,dder)) / (cross(ddder,dder)); + tgt = dder / l; + if (before) { + tgt = -tgt; + } + return; + } + len = l; + + rad = -l * (dot(der,der)) / (cross(dder,der)); + + tgt = der / l; +} + +void +Path::TangentOnBezAt (double at, NR::Point const &iS, + PathDescrIntermBezierTo & mid, + PathDescrBezierTo & fin, bool before, NR::Point & pos, + NR::Point & tgt, double &len, double &rad) +{ + pos = iS; + tgt = NR::Point(0,0); + len = rad = 0; + + const NR::Point A = fin.p + iS - 2*mid.p; + const NR::Point B = 2*mid.p - 2 * iS; + const NR::Point C = iS; + + pos = at * at * A + at * B + C; + const NR::Point der = 2 * at * A + B; + const NR::Point dder = 2 * A; + double l = NR::L2(der); + + if (l <= 0.0001) { + l = NR::L2(dder); + if (l <= 0.0001) { + // pas de segment.... + // Not a segment. + return; + } + rad = 100000000; // Why this number? + tgt = dder / l; + if (before) { + tgt = -tgt; + } + return; + } + len = l; + rad = -l * (dot(der,der)) / (cross(dder,der)); + + tgt = der / l; +} + +void +Path::OutlineJoin (Path * dest, NR::Point pos, NR::Point stNor, NR::Point enNor, double width, + JoinType join, double miter) +{ + const double angSi = cross (enNor,stNor); + const double angCo = dot (stNor, enNor); + // 1/1000 is very big/ugly, but otherwise it stuffs things up a little... + // 1/1000 est tres grossier, mais sinon ca merde tout azimut + if ((width >= 0 && angSi > -0.001) + || (width < 0 && angSi < 0.001)) { + if (angCo > 0.999) { + // straight ahead + // tout droit + } else if (angCo < -0.999) { + // half turn + // demit-tour + dest->LineTo (pos + width*enNor); + } else { + dest->LineTo (pos); + dest->LineTo (pos + width*enNor); + } + } else { + if (join == join_round) { + // Use the ends of the cubic: approximate the arc at the + // point where .., and support better the rounding of + // coordinates of the end points. + + // utiliser des bouts de cubique: approximation de l'arc (au point ou on en est...), et supporte mieux + // l'arrondi des coordonnees des extremites + /* double angle=acos(angCo); + if ( angCo >= 0 ) { + NR::Point stTgt,enTgt; + RotCCWTo(stNor,stTgt); + RotCCWTo(enNor,enTgt); + dest->CubicTo(pos.x+width*enNor.x,pos.y+width*enNor.y, + angle*width*stTgt.x,angle*width*stTgt.y, + angle*width*enTgt.x,angle*width*enTgt.y); + } else { + NR::Point biNor; + NR::Point stTgt,enTgt,biTgt; + biNor.x=stNor.x+enNor.x; + biNor.y=stNor.y+enNor.y; + double biL=sqrt(biNor.x*biNor.x+biNor.y*biNor.y); + biNor.x/=biL; + biNor.y/=biL; + RotCCWTo(stNor,stTgt); + RotCCWTo(enNor,enTgt); + RotCCWTo(biNor,biTgt); + dest->CubicTo(pos.x+width*biNor.x,pos.y+width*biNor.y, + angle*width*stTgt.x,angle*width*stTgt.y, + angle*width*biTgt.x,angle*width*biTgt.y); + dest->CubicTo(pos.x+width*enNor.x,pos.y+width*enNor.y, + angle*width*biTgt.x,angle*width*biTgt.y, + angle*width*enTgt.x,angle*width*enTgt.y); + }*/ + if (width > 0) { + dest->ArcTo (pos + width*enNor, + 1.0001 * width, 1.0001 * width, 0.0, false, true); + } else { + dest->ArcTo (pos + width*enNor, + -1.0001 * width, -1.0001 * width, 0.0, false, + false); + } + } else if (join == join_pointy) { + NR::Point const biss = unit_vector(NR::rot90( stNor - enNor )); + double c2 = NR::dot (biss, enNor); + double l = width / c2; + if ( fabs(l) > miter) { + dest->LineTo (pos + width*enNor); + } else { + dest->LineTo (pos+l*biss); + dest->LineTo (pos+width*enNor); + } + } else { + dest->LineTo (pos + width*enNor); + } + } +} + +// les callbacks + +// see http://www.home.unix-ag.org/simon/sketch/pathstroke.py to understand what's happening here + +void +Path::RecStdCubicTo (outline_callback_data * data, double tol, double width, + int lev) +{ + NR::Point stPos, miPos, enPos; + NR::Point stTgt, enTgt, miTgt, stNor, enNor, miNor; + double stRad, miRad, enRad; + double stTle, miTle, enTle; + // un cubic + { + PathDescrCubicTo temp(NR::Point(data->x2, data->y2), + NR::Point(data->d.c.dx1, data->d.c.dy1), + NR::Point(data->d.c.dx2, data->d.c.dy2)); + + NR::Point initial_point(data->x1, data->y1); + TangentOnCubAt (0.0, initial_point, temp, false, stPos, stTgt, stTle, + stRad); + TangentOnCubAt (0.5, initial_point, temp, false, miPos, miTgt, miTle, + miRad); + TangentOnCubAt (1.0, initial_point, temp, true, enPos, enTgt, enTle, + enRad); + stNor=stTgt.cw(); + miNor=miTgt.cw(); + enNor=enTgt.cw(); + } + + double stGue = 1, miGue = 1, enGue = 1; + // correction of the lengths of the tangent to the offset + // if you don't see why i wrote that, draw a little figure and everything will be clear + if (fabs (stRad) > 0.01) + stGue += width / stRad; + if (fabs (miRad) > 0.01) + miGue += width / miRad; + if (fabs (enRad) > 0.01) + enGue += width / enRad; + stGue *= stTle; + miGue *= miTle; + enGue *= enTle; + + + if (lev <= 0) { + int n_d = data->dest->CubicTo (enPos + width*enNor, + stGue*stTgt, + enGue*enTgt); + if (n_d >= 0) { + data->dest->descr_cmd[n_d]->associated = data->piece; + data->dest->descr_cmd[n_d]->tSt = data->tSt; + data->dest->descr_cmd[n_d]->tEn = data->tEn; + } + return; + } + + NR::Point chk; + const NR::Point req = miPos + width * miNor; + { + PathDescrCubicTo temp(enPos + width * enNor, + stGue * stTgt, + enGue * enTgt); + double chTle, chRad; + NR::Point chTgt; + TangentOnCubAt (0.5, stPos+width*stNor, + temp, false, chk, chTgt, chTle, chRad); + } + const NR::Point diff = req - chk; + const double err = dot(diff,diff); + if (err <= tol ) { // tolerance is given as a quadratic value, no need to use tol*tol here +// printf("%f <= %f %i\n",err,tol,lev); + int n_d = data->dest->CubicTo (enPos + width*enNor, + stGue*stTgt, + enGue*enTgt); + if (n_d >= 0) { + data->dest->descr_cmd[n_d]->associated = data->piece; + data->dest->descr_cmd[n_d]->tSt = data->tSt; + data->dest->descr_cmd[n_d]->tEn = data->tEn; + } + } else { + outline_callback_data desc = *data; + + desc.tSt = data->tSt; + desc.tEn = (data->tSt + data->tEn) / 2; + desc.x1 = data->x1; + desc.y1 = data->y1; + desc.x2 = miPos[0]; + desc.y2 = miPos[1]; + desc.d.c.dx1 = 0.5 * stTle * stTgt[0]; + desc.d.c.dy1 = 0.5 * stTle * stTgt[1]; + desc.d.c.dx2 = 0.5 * miTle * miTgt[0]; + desc.d.c.dy2 = 0.5 * miTle * miTgt[1]; + RecStdCubicTo (&desc, tol, width, lev - 1); + + desc.tSt = (data->tSt + data->tEn) / 2; + desc.tEn = data->tEn; + desc.x1 = miPos[0]; + desc.y1 = miPos[1]; + desc.x2 = data->x2; + desc.y2 = data->y2; + desc.d.c.dx1 = 0.5 * miTle * miTgt[0]; + desc.d.c.dy1 = 0.5 * miTle * miTgt[1]; + desc.d.c.dx2 = 0.5 * enTle * enTgt[0]; + desc.d.c.dy2 = 0.5 * enTle * enTgt[1]; + RecStdCubicTo (&desc, tol, width, lev - 1); + } +} + +void +Path::StdCubicTo (Path::outline_callback_data * data, double tol, double width) +{ +// fflush (stdout); + RecStdCubicTo (data, tol, width, 8); +} + +void +Path::StdBezierTo (Path::outline_callback_data * data, double tol, double width) +{ + PathDescrBezierTo tempb(NR::Point(data->x2, data->y2), 1); + PathDescrIntermBezierTo tempi(NR::Point(data->d.b.mx, data->d.b.my)); + NR::Point stPos, enPos, stTgt, enTgt; + double stRad, enRad, stTle, enTle; + NR::Point tmp(data->x1,data->y1); + TangentOnBezAt (0.0, tmp, tempi, tempb, false, stPos, stTgt, + stTle, stRad); + TangentOnBezAt (1.0, tmp, tempi, tempb, true, enPos, enTgt, + enTle, enRad); + data->d.c.dx1 = stTle * stTgt[0]; + data->d.c.dy1 = stTle * stTgt[1]; + data->d.c.dx2 = enTle * enTgt[0]; + data->d.c.dy2 = enTle * enTgt[1]; + RecStdCubicTo (data, tol, width, 8); +} + +void +Path::RecStdArcTo (outline_callback_data * data, double tol, double width, + int lev) +{ + NR::Point stPos, miPos, enPos; + NR::Point stTgt, enTgt, miTgt, stNor, enNor, miNor; + double stRad, miRad, enRad; + double stTle, miTle, enTle; + // un cubic + { + PathDescrArcTo temp(NR::Point(data->x2, data->y2), + data->d.a.rx, data->d.a.ry, + data->d.a.angle, data->d.a.large, data->d.a.clock); + + NR::Point tmp(data->x1,data->y1); + TangentOnArcAt (data->d.a.stA, tmp, temp, stPos, stTgt, + stTle, stRad); + TangentOnArcAt ((data->d.a.stA + data->d.a.enA) / 2, tmp, + temp, miPos, miTgt, miTle, miRad); + TangentOnArcAt (data->d.a.enA, tmp, temp, enPos, enTgt, + enTle, enRad); + stNor=stTgt.cw(); + miNor=miTgt.cw(); + enNor=enTgt.cw(); + } + + double stGue = 1, miGue = 1, enGue = 1; + if (fabs (stRad) > 0.01) + stGue += width / stRad; + if (fabs (miRad) > 0.01) + miGue += width / miRad; + if (fabs (enRad) > 0.01) + enGue += width / enRad; + stGue *= stTle; + miGue *= miTle; + enGue *= enTle; + double sang, eang; + { + NR::Point tms(data->x1,data->y1),tme(data->x2,data->y2); + ArcAngles (tms,tme, data->d.a.rx, + data->d.a.ry, data->d.a.angle, data->d.a.large, !data->d.a.clock, + sang, eang); + } + double scal = eang - sang; + if (scal < 0) + scal += 2 * M_PI; + if (scal > 2 * M_PI) + scal -= 2 * M_PI; + scal *= data->d.a.enA - data->d.a.stA; + + if (lev <= 0) + { + int n_d = data->dest->CubicTo (enPos + width*enNor, + stGue*scal*stTgt, + enGue*scal*enTgt); + if (n_d >= 0) { + data->dest->descr_cmd[n_d]->associated = data->piece; + data->dest->descr_cmd[n_d]->tSt = data->d.a.stA; + data->dest->descr_cmd[n_d]->tEn = data->d.a.enA; + } + return; + } + + NR::Point chk; + const NR::Point req = miPos + width*miNor; + { + PathDescrCubicTo temp(enPos + width * enNor, stGue * scal * stTgt, enGue * scal * enTgt); + double chTle, chRad; + NR::Point chTgt; + TangentOnCubAt (0.5, stPos+width*stNor, + temp, false, chk, chTgt, chTle, chRad); + } + const NR::Point diff = req - chk; + const double err = (dot(diff,diff)); + if (err <= tol * tol) + { + int n_d = data->dest->CubicTo (enPos + width*enNor, + stGue*scal*stTgt, + enGue*scal*enTgt); + if (n_d >= 0) { + data->dest->descr_cmd[n_d]->associated = data->piece; + data->dest->descr_cmd[n_d]->tSt = data->d.a.stA; + data->dest->descr_cmd[n_d]->tEn = data->d.a.enA; + } + } else { + outline_callback_data desc = *data; + + desc.d.a.stA = data->d.a.stA; + desc.d.a.enA = (data->d.a.stA + data->d.a.enA) / 2; + RecStdArcTo (&desc, tol, width, lev - 1); + + desc.d.a.stA = (data->d.a.stA + data->d.a.enA) / 2; + desc.d.a.enA = data->d.a.enA; + RecStdArcTo (&desc, tol, width, lev - 1); + } +} + +void +Path::StdArcTo (Path::outline_callback_data * data, double tol, double width) +{ + data->d.a.stA = 0.0; + data->d.a.enA = 1.0; + RecStdArcTo (data, tol, width, 8); +} + +/* + 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 : diff --git a/src/livarot/PathSimplify.cpp b/src/livarot/PathSimplify.cpp new file mode 100644 index 000000000..44b138263 --- /dev/null +++ b/src/livarot/PathSimplify.cpp @@ -0,0 +1,1397 @@ +/* + * PathSimplify.cpp + * nlivarot + * + * Created by fred on Fri Dec 12 2003. + * + */ + +#include +#include +#include "livarot/Path.h" +#include "livarot/path-description.h" + +/* + * Reassembling polyline segments into cubic bezier patches + * thes functions do not need the back data. but they are slower than recomposing + * path descriptions when you have said back data (it's always easier with a model) + * there's a bezier fitter in bezier-utils.cpp too. the main difference is the way bezier patch are split + * here: walk on the polyline, trying to extend the portion you can fit by respecting the treshhold, split when + * treshhold is exceeded. when encountering a "forced" point, lower the treshhold to favor splitting at that point + * in bezier-utils: fit the whole polyline, get the position with the higher deviation to the fitted curve, split + * there and recurse + */ + + +// algo d'origine: http://www.cs.mtu.edu/~shene/COURSES/cs3621/NOTES/INT-APP/CURVE-APP-global.html + +// need the b-spline basis for cubic splines +// pas oublier que c'est une b-spline clampee +// et que ca correspond a une courbe de bezier normale +#define N03(t) ((1.0-t)*(1.0-t)*(1.0-t)) +#define N13(t) (3*t*(1.0-t)*(1.0-t)) +#define N23(t) (3*t*t*(1.0-t)) +#define N33(t) (t*t*t) +// quadratic b-splines (jsut in case) +#define N02(t) ((1.0-t)*(1.0-t)) +#define N12(t) (2*t*(1.0-t)) +#define N22(t) (t*t) +// linear interpolation b-splines +#define N01(t) ((1.0-t)) +#define N11(t) (t) + + + +void Path::Simplify(double treshhold) +{ + if (pts.size() <= 1) { + return; + } + + Reset(); + + int lastM = 0; + while (lastM < int(pts.size())) { + int lastP = lastM + 1; + while (lastP < int(pts.size()) + && (pts[lastP].isMoveTo == polyline_lineto + || pts[lastP].isMoveTo == polyline_forced)) + { + lastP++; + } + + DoSimplify(lastM, lastP - lastM, treshhold); + + lastM = lastP; + } +} + + +// dichomtomic method to get distance to curve approximation +// a real polynomial solver would get the minimum more efficiently, but since the polynom +// would likely be of degree >= 5, that would imply using some generic solver, liek using the sturm metod +double RecDistanceToCubic(NR::Point const &iS, NR::Point const &isD, + NR::Point const &iE, NR::Point const &ieD, + NR::Point &pt, double current, int lev, double st, double et) +{ + if ( lev <= 0 ) { + return current; + } + + NR::Point const m = 0.5 * (iS + iE) + 0.125 * (isD - ieD); + NR::Point const md = 0.75 * (iE - iS) - 0.125 * (isD + ieD); + double const mt = (st + et) / 2; + + NR::Point const hisD = 0.5 * isD; + NR::Point const hieD = 0.5 * ieD; + + NR::Point const mp = pt - m; + double nle = NR::dot(mp, mp); + + if ( nle < current ) { + + current = nle; + nle = RecDistanceToCubic(iS, hisD, m, md, pt, current, lev - 1, st, mt); + if ( nle < current ) { + current = nle; + } + nle = RecDistanceToCubic(m, md, iE, hieD, pt, current, lev - 1, mt, et); + if ( nle < current ) { + current = nle; + } + + } else if ( nle < 2 * current ) { + + nle = RecDistanceToCubic(iS, hisD, m, md, pt, current, lev - 1, st, mt); + if ( nle < current ) { + current = nle; + } + nle = RecDistanceToCubic(m, md, iE, hieD, pt, current, lev - 1, mt, et); + if ( nle < current ) { + current = nle; + } + } + + return current; +} + + +double DistanceToCubic(NR::Point const &start, PathDescrCubicTo res, NR::Point &pt) +{ + NR::Point const sp = pt - start; + NR::Point const ep = pt - res.p; + double nle = NR::dot(sp, sp); + double nnle = NR::dot(ep, ep); + if ( nnle < nle ) { + nle = nnle; + } + + NR::Point seg = res.p - start; + nnle = NR::cross(seg, sp); + nnle *= nnle; + nnle /= NR::dot(seg, seg); + if ( nnle < nle ) { + if ( NR::dot(sp,seg) >= 0 ) { + seg = start - res.p; + if ( NR::dot(ep,seg) >= 0 ) { + nle = nnle; + } + } + } + + return nle; +} + + +/** + * Simplification on a subpath. + */ + +void Path::DoSimplify(int off, int N, double treshhold) +{ + // non-dichotomic method: grow an interval of points approximated by a curve, until you reach the treshhold, and repeat + if (N <= 1) { + return; + } + + int curP = 0; + + fitting_tables data; + data.Xk = data.Yk = data.Qk = NULL; + data.tk = data.lk = NULL; + data.fk = NULL; + data.totLen = 0; + data.nbPt = data.maxPt = data.inPt = 0; + + NR::Point const moveToPt = pts[off].p; + MoveTo(moveToPt); + NR::Point endToPt = moveToPt; + + while (curP < N - 1) { + + int lastP = curP + 1; + int M = 2; + + // remettre a zero + data.inPt = data.nbPt = 0; + + PathDescrCubicTo res(NR::Point(0, 0), NR::Point(0, 0), NR::Point(0, 0)); + bool contains_forced = false; + int step = 64; + + while ( step > 0 ) { + int forced_pt = -1; + int worstP = -1; + + do { + if (pts[off + lastP].isMoveTo == polyline_forced) { + contains_forced = true; + } + forced_pt = lastP; + lastP += step; + M += step; + } while (lastP < N && ExtendFit(off + curP, M, data, + (contains_forced) ? 0.05 * treshhold : treshhold, + res, worstP) ); + if (lastP >= N) { + + lastP -= step; + M -= step; + + } else { + // le dernier a echoue + lastP -= step; + M -= step; + + if ( contains_forced ) { + lastP = forced_pt; + M = lastP - curP + 1; + } + + AttemptSimplify(off + curP, M, treshhold, res, worstP); // ca passe forcement + } + step /= 2; + } + + endToPt = pts[off + lastP].p; + if (M <= 2) { + LineTo(endToPt); + } else { + CubicTo(endToPt, res.start, res.end); + } + + curP = lastP; + } + + if (NR::LInfty(endToPt - moveToPt) < 0.00001) { + Close(); + } + + g_free(data.Xk); + g_free(data.Yk); + g_free(data.Qk); + g_free(data.tk); + g_free(data.lk); + g_free(data.fk); +} + + +// warning: slow +// idea behing this feature: splotches appear when trying to fit a small number of points: you can +// get a cubic bezier that fits the points very well but doesn't fit the polyline itself +// so we add a bit of the error at the middle of each segment of the polyline +// also we restrict this to <=20 points, to avoid unnecessary computations +#define with_splotch_killer + +// primitive= calc the cubic bezier patche that fits Xk and Yk best +// Qk est deja alloue +// retourne false si probleme (matrice non-inversible) +bool Path::FitCubic(NR::Point const &start, PathDescrCubicTo &res, + double *Xk, double *Yk, double *Qk, double *tk, int nbPt) +{ + NR::Point const end = res.p; + + // la matrice tNN + NR::Matrix M(0, 0, 0, 0, 0, 0); + for (int i = 1; i < nbPt - 1; i++) { + M[0] += N13(tk[i]) * N13(tk[i]); + M[1] += N23(tk[i]) * N13(tk[i]); + M[2] += N13(tk[i]) * N23(tk[i]); + M[3] += N23(tk[i]) * N23(tk[i]); + } + + double const det = M.det(); + if (fabs(det) < 0.000001) { + res.start[0]=res.start[1]=0.0; + res.end[0]=res.end[1]=0.0; + return false; + } + + NR::Matrix const iM = M.inverse(); + M = iM; + + // phase 1: abcisses + // calcul des Qk + Xk[0] = start[0]; + Yk[0] = start[1]; + Xk[nbPt - 1] = end[0]; + Yk[nbPt - 1] = end[1]; + + for (int i = 1; i < nbPt - 1; i++) { + Qk[i] = Xk[i] - N03 (tk[i]) * Xk[0] - N33 (tk[i]) * Xk[nbPt - 1]; + } + + // le vecteur Q + NR::Point Q(0, 0); + for (int i = 1; i < nbPt - 1; i++) { + Q[0] += N13 (tk[i]) * Qk[i]; + Q[1] += N23 (tk[i]) * Qk[i]; + } + + NR::Point P = Q * M; + NR::Point cp1; + NR::Point cp2; + cp1[NR::X] = P[NR::X]; + cp2[NR::X] = P[NR::Y]; + + // phase 2: les ordonnees + for (int i = 1; i < nbPt - 1; i++) { + Qk[i] = Yk[i] - N03 (tk[i]) * Yk[0] - N33 (tk[i]) * Yk[nbPt - 1]; + } + + // le vecteur Q + Q = NR::Point(0, 0); + for (int i = 1; i < nbPt - 1; i++) { + Q[0] += N13 (tk[i]) * Qk[i]; + Q[1] += N23 (tk[i]) * Qk[i]; + } + + P = Q * M; + cp1[NR::Y] = P[NR::X]; + cp2[NR::Y] = P[NR::Y]; + + res.start = 3.0 * (cp1 - start); + res.end = 3.0 * (end - cp2 ); + + return true; +} + + +bool Path::ExtendFit(int off, int N, fitting_tables &data, double treshhold, PathDescrCubicTo &res, int &worstP) +{ + if ( N >= data.maxPt ) { + data.maxPt = 2 * N + 1; + data.Xk = (double *) g_realloc(data.Xk, data.maxPt * sizeof(double)); + data.Yk = (double *) g_realloc(data.Yk, data.maxPt * sizeof(double)); + data.Qk = (double *) g_realloc(data.Qk, data.maxPt * sizeof(double)); + data.tk = (double *) g_realloc(data.tk, data.maxPt * sizeof(double)); + data.lk = (double *) g_realloc(data.lk, data.maxPt * sizeof(double)); + data.fk = (char *) g_realloc(data.fk, data.maxPt * sizeof(char)); + } + + if ( N > data.inPt ) { + for (int i = data.inPt; i < N; i++) { + data.Xk[i] = pts[off + i].p[NR::X]; + data.Yk[i] = pts[off + i].p[NR::Y]; + data.fk[i] = ( pts[off + i].isMoveTo == polyline_forced ) ? 0x01 : 0x00; + } + data.lk[0] = 0; + data.tk[0] = 0; + + double prevLen = 0; + for (int i = 0; i < data.inPt; i++) { + prevLen += data.lk[i]; + } + data.totLen = prevLen; + + for (int i = ( (data.inPt > 0) ? data.inPt : 1); i < N; i++) { + NR::Point diff; + diff[NR::X] = data.Xk[i] - data.Xk[i - 1]; + diff[NR::Y] = data.Yk[i] - data.Yk[i - 1]; + data.lk[i] = NR::L2(diff); + data.totLen += data.lk[i]; + data.tk[i] = data.totLen; + } + + for (int i = 0; i < data.inPt; i++) { + data.tk[i] *= prevLen; + data.tk[i] /= data.totLen; + } + + for (int i = data.inPt; i < N; i++) { + data.tk[i] /= data.totLen; + } + data.inPt = N; + } + + if ( N < data.nbPt ) { + // on est allŽ trop loin + // faut recalculer les tk + data.totLen = 0; + data.tk[0] = 0; + data.lk[0] = 0; + for (int i = 1; i < N; i++) { + data.totLen += data.lk[i]; + data.tk[i] = data.totLen; + } + + for (int i = 1; i < N; i++) { + data.tk[i] /= data.totLen; + } + } + + data.nbPt = N; + + if ( data.nbPt <= 0 ) { + return false; + } + + res.p[0] = data.Xk[data.nbPt - 1]; + res.p[1] = data.Yk[data.nbPt - 1]; + res.start[0] = res.start[1] = 0; + res.end[0] = res.end[1] = 0; + worstP = 1; + if ( N <= 2 ) { + return true; + } + + if ( data.totLen < 0.0001 ) { + double worstD = 0; + NR::Point start; + worstP = -1; + start[0] = data.Xk[0]; + start[1] = data.Yk[0]; + for (int i = 1; i < N; i++) { + NR::Point nPt; + bool isForced = data.fk[i]; + nPt[0] = data.Xk[i]; + nPt[1] = data.Yk[i]; + + double nle = DistanceToCubic(start, res, nPt); + if ( isForced ) { + // forced points are favored for splitting the recursion; we do this by increasing their distance + if ( worstP < 0 || 2*nle > worstD ) { + worstP = i; + worstD = 2*nle; + } + } else { + if ( worstP < 0 || nle > worstD ) { + worstP = i; + worstD = nle; + } + } + } + + return true; + } + + return AttemptSimplify(data, treshhold, res, worstP); +} + + +// fit a polyline to a bezier patch, return true is treshhold not exceeded (ie: you can continue) +// version that uses tables from the previous iteration, to minimize amount of work done +bool Path::AttemptSimplify (fitting_tables &data,double treshhold, PathDescrCubicTo & res,int &worstP) +{ + NR::Point start,end; + // pour une coordonnee + NR::Point cp1, cp2; + + worstP = 1; + if (pts.size() == 2) { + return true; + } + + start[0] = data.Xk[0]; + start[1] = data.Yk[0]; + cp1[0] = data.Xk[1]; + cp1[1] = data.Yk[1]; + end[0] = data.Xk[data.nbPt - 1]; + end[1] = data.Yk[data.nbPt - 1]; + cp2 = cp1; + + if (pts.size() == 3) { + // start -> cp1 -> end + res.start = cp1 - start; + res.end = end - cp1; + worstP = 1; + return true; + } + + if ( FitCubic(start, res, data.Xk, data.Yk, data.Qk, data.tk, data.nbPt) ) { + cp1 = start + res.start / 3; + cp2 = end - res.end / 3; + } else { + // aie, non-inversible + double worstD = 0; + worstP = -1; + for (int i = 1; i < data.nbPt; i++) { + NR::Point nPt; + nPt[NR::X] = data.Xk[i]; + nPt[NR::Y] = data.Yk[i]; + double nle = DistanceToCubic(start, res, nPt); + if ( data.fk[i] ) { + // forced points are favored for splitting the recursion; we do this by increasing their distance + if ( worstP < 0 || 2 * nle > worstD ) { + worstP = i; + worstD = 2 * nle; + } + } else { + if ( worstP < 0 || nle > worstD ) { + worstP = i; + worstD = nle; + } + } + } + return false; + } + + // calcul du delta= pondere par les longueurs des segments + double delta = 0; + { + double worstD = 0; + worstP = -1; + NR::Point prevAppP; + NR::Point prevP; + double prevDist; + prevP[NR::X] = data.Xk[0]; + prevP[NR::Y] = data.Yk[0]; + prevAppP = prevP; // le premier seulement + prevDist = 0; +#ifdef with_splotch_killer + if ( data.nbPt <= 20 ) { + for (int i = 1; i < data.nbPt - 1; i++) { + NR::Point curAppP; + NR::Point curP; + double curDist; + NR::Point midAppP; + NR::Point midP; + double midDist; + + curAppP[NR::X] = N13(data.tk[i]) * cp1[NR::X] + + N23(data.tk[i]) * cp2[NR::X] + + N03(data.tk[i]) * data.Xk[0] + + N33(data.tk[i]) * data.Xk[data.nbPt - 1]; + + curAppP[NR::Y] = N13(data.tk[i]) * cp1[NR::Y] + + N23(data.tk[i]) * cp2[NR::Y] + + N03(data.tk[i]) * data.Yk[0] + + N33(data.tk[i]) * data.Yk[data.nbPt - 1]; + + curP[NR::X] = data.Xk[i]; + curP[NR::Y] = data.Yk[i]; + double mtk = 0.5 * (data.tk[i] + data.tk[i - 1]); + + midAppP[NR::X] = N13(mtk) * cp1[NR::X] + + N23(mtk) * cp2[NR::X] + + N03(mtk) * data.Xk[0] + + N33(mtk) * data.Xk[data.nbPt - 1]; + + midAppP[NR::Y] = N13(mtk) * cp1[NR::Y] + + N23(mtk) * cp2[NR::Y] + + N03(mtk) * data.Yk[0] + + N33(mtk) * data.Yk[data.nbPt - 1]; + + midP = 0.5 * (curP + prevP); + + NR::Point diff = curAppP - curP; + curDist = dot(diff, diff); + diff = midAppP - midP; + midDist = dot(diff, diff); + + delta += 0.3333 * (curDist + prevDist + midDist) * data.lk[i]; + if ( curDist > worstD ) { + worstD = curDist; + worstP = i; + } else if ( data.fk[i] && 2 * curDist > worstD ) { + worstD = 2*curDist; + worstP = i; + } + prevP = curP; + prevAppP = curAppP; + prevDist = curDist; + } + delta /= data.totLen; + + } else { +#endif + for (int i = 1; i < data.nbPt - 1; i++) { + NR::Point curAppP; + NR::Point curP; + double curDist; + + curAppP[NR::X] = N13(data.tk[i]) * cp1[NR::X] + + N23(data.tk[i]) * cp2[NR::X] + + N03(data.tk[i]) * data.Xk[0] + + N33(data.tk[i]) * data.Xk[data.nbPt - 1]; + + curAppP[NR::Y] = N13(data.tk[i]) * cp1[NR::Y] + + N23(data.tk[i]) * cp2[NR::Y] + + N03(data.tk[i]) * data.Yk[0] + + N33(data.tk[i]) * data.Yk[data.nbPt - 1]; + + curP[NR::X] = data.Xk[i]; + curP[NR::Y] = data.Yk[i]; + + NR::Point diff = curAppP-curP; + curDist = dot(diff, diff); + delta += curDist; + + if ( curDist > worstD ) { + worstD = curDist; + worstP = i; + } else if ( data.fk[i] && 2 * curDist > worstD ) { + worstD = 2*curDist; + worstP = i; + } + prevP = curP; + prevAppP = curAppP; + prevDist = curDist; + } +#ifdef with_splotch_killer + } +#endif + } + + if (delta < treshhold * treshhold) { + // premier jet + + // Refine a little. + for (int i = 1; i < data.nbPt - 1; i++) { + NR::Point pt(data.Xk[i], data.Yk[i]); + data.tk[i] = RaffineTk(pt, start, cp1, cp2, end, data.tk[i]); + if (data.tk[i] < data.tk[i - 1]) { + // Force tk to be monotonic non-decreasing. + data.tk[i] = data.tk[i - 1]; + } + } + + if ( FitCubic(start, res, data.Xk, data.Yk, data.Qk, data.tk, data.nbPt) == false) { + // ca devrait jamais arriver, mais bon + res.start = 3.0 * (cp1 - start); + res.end = 3.0 * (end - cp2 ); + return true; + } + + double ndelta = 0; + { + double worstD = 0; + worstP = -1; + NR::Point prevAppP; + NR::Point prevP(data.Xk[0], data.Yk[0]); + double prevDist = 0; + prevAppP = prevP; // le premier seulement +#ifdef with_splotch_killer + if ( data.nbPt <= 20 ) { + for (int i = 1; i < data.nbPt - 1; i++) { + NR::Point curAppP; + NR::Point curP; + double curDist; + NR::Point midAppP; + NR::Point midP; + double midDist; + + curAppP[NR::X] = N13(data.tk[i]) * cp1[NR::X] + + N23(data.tk[i]) * cp2[NR::X] + + N03(data.tk[i]) * data.Xk[0] + + N33(data.tk[i]) * data.Xk[data.nbPt - 1]; + + curAppP[NR::Y] = N13(data.tk[i]) * cp1[NR::Y] + + N23(data.tk[i]) * cp2[NR::Y] + + N03(data.tk[i]) * data.Yk[0] + + N33(data.tk[i]) * data.Yk[data.nbPt - 1]; + + curP[NR::X] = data.Xk[i]; + curP[NR::Y] = data.Yk[i]; + double mtk = 0.5 * (data.tk[i] + data.tk[i - 1]); + + midAppP[NR::X] = N13(mtk) * cp1[NR::X] + + N23(mtk) * cp2[NR::X] + + N03(mtk) * data.Xk[0] + + N33(mtk) * data.Xk[data.nbPt - 1]; + + midAppP[NR::Y] = N13(mtk) * cp1[NR::Y] + + N23(mtk) * cp2[NR::Y] + + N03(mtk) * data.Yk[0] + + N33(mtk) * data.Yk[data.nbPt - 1]; + + midP = 0.5 * (curP + prevP); + + NR::Point diff = curAppP - curP; + curDist = dot(diff, diff); + + diff = midAppP - midP; + midDist = dot(diff, diff); + + ndelta += 0.3333 * (curDist + prevDist + midDist) * data.lk[i]; + + if ( curDist > worstD ) { + worstD = curDist; + worstP = i; + } else if ( data.fk[i] && 2 * curDist > worstD ) { + worstD = 2*curDist; + worstP = i; + } + + prevP = curP; + prevAppP = curAppP; + prevDist = curDist; + } + ndelta /= data.totLen; + } else { +#endif + for (int i = 1; i < data.nbPt - 1; i++) { + NR::Point curAppP; + NR::Point curP; + double curDist; + + curAppP[NR::X] = N13(data.tk[i]) * cp1[NR::X] + + N23(data.tk[i]) * cp2[NR::X] + + N03(data.tk[i]) * data.Xk[0] + + N33(data.tk[i]) * data.Xk[data.nbPt - 1]; + + curAppP[NR::Y] = N13(data.tk[i]) * cp1[NR::Y] + + N23(data.tk[i]) * cp2[1] + + N03(data.tk[i]) * data.Yk[0] + + N33(data.tk[i]) * data.Yk[data.nbPt - 1]; + + curP[NR::X] = data.Xk[i]; + curP[NR::Y] = data.Yk[i]; + + NR::Point diff = curAppP - curP; + curDist = dot(diff, diff); + + ndelta += curDist; + + if ( curDist > worstD ) { + worstD = curDist; + worstP = i; + } else if ( data.fk[i] && 2 * curDist > worstD ) { + worstD = 2 * curDist; + worstP = i; + } + prevP = curP; + prevAppP = curAppP; + prevDist = curDist; + } +#ifdef with_splotch_killer + } +#endif + } + + if (ndelta < delta + 0.00001) { + return true; + } else { + // nothing better to do + res.start = 3.0 * (cp1 - start); + res.end = 3.0 * (end - cp2 ); + } + + return true; + } + + return false; +} + + +bool Path::AttemptSimplify(int off, int N, double treshhold, PathDescrCubicTo &res,int &worstP) +{ + NR::Point start; + NR::Point end; + + // pour une coordonnee + double *Xk; // la coordonnee traitee (x puis y) + double *Yk; // la coordonnee traitee (x puis y) + double *lk; // les longueurs de chaque segment + double *tk; // les tk + double *Qk; // les Qk + char *fk; // si point force + + NR::Point cp1; + NR::Point cp2; + + if (N == 2) { + worstP = 1; + return true; + } + + start = pts[off].p; + cp1 = pts[off + 1].p; + end = pts[off + N - 1].p; + + res.p = end; + res.start[0] = res.start[1] = 0; + res.end[0] = res.end[1] = 0; + if (N == 3) { + // start -> cp1 -> end + res.start = cp1 - start; + res.end = end - cp1; + worstP = 1; + return true; + } + + // Totally inefficient, allocates & deallocates all the time. + tk = (double *) g_malloc(N * sizeof(double)); + Qk = (double *) g_malloc(N * sizeof(double)); + Xk = (double *) g_malloc(N * sizeof(double)); + Yk = (double *) g_malloc(N * sizeof(double)); + lk = (double *) g_malloc(N * sizeof(double)); + fk = (char *) g_malloc(N * sizeof(char)); + + // chord length method + tk[0] = 0.0; + lk[0] = 0.0; + { + NR::Point prevP = start; + for (int i = 1; i < N; i++) { + Xk[i] = pts[off + i].p[NR::X]; + Yk[i] = pts[off + i].p[NR::Y]; + + if ( pts[off + i].isMoveTo == polyline_forced ) { + fk[i] = 0x01; + } else { + fk[i] = 0; + } + + NR::Point diff(Xk[i] - prevP[NR::X], Yk[i] - prevP[1]); + prevP[0] = Xk[i]; + prevP[1] = Yk[i]; + lk[i] = NR::L2(diff); + tk[i] = tk[i - 1] + lk[i]; + } + } + + if (tk[N - 1] < 0.00001) { + // longueur nulle + res.start[0] = res.start[1] = 0; + res.end[0] = res.end[1] = 0; + double worstD = 0; + worstP = -1; + for (int i = 1; i < N; i++) { + NR::Point nPt; + bool isForced = fk[i]; + nPt[0] = Xk[i]; + nPt[1] = Yk[i]; + + double nle = DistanceToCubic(start, res, nPt); + if ( isForced ) { + // forced points are favored for splitting the recursion; we do this by increasing their distance + if ( worstP < 0 || 2 * nle > worstD ) { + worstP = i; + worstD = 2 * nle; + } + } else { + if ( worstP < 0 || nle > worstD ) { + worstP = i; + worstD = nle; + } + } + } + + g_free(tk); + g_free(Qk); + g_free(Xk); + g_free(Yk); + g_free(fk); + g_free(lk); + + return false; + } + + double totLen = tk[N - 1]; + for (int i = 1; i < N - 1; i++) { + tk[i] /= totLen; + } + + res.p = end; + if ( FitCubic(start, res, Xk, Yk, Qk, tk, N) ) { + cp1 = start + res.start / 3; + cp2 = end + res.end / 3; + } else { + // aie, non-inversible + res.start[0] = res.start[1] = 0; + res.end[0] = res.end[1] = 0; + double worstD = 0; + worstP = -1; + for (int i = 1; i < N; i++) { + NR::Point nPt(Xk[i], Yk[i]); + bool isForced = fk[i]; + double nle = DistanceToCubic(start, res, nPt); + if ( isForced ) { + // forced points are favored for splitting the recursion; we do this by increasing their distance + if ( worstP < 0 || 2 * nle > worstD ) { + worstP = i; + worstD = 2 * nle; + } + } else { + if ( worstP < 0 || nle > worstD ) { + worstP = i; + worstD = nle; + } + } + } + + g_free(tk); + g_free(Qk); + g_free(Xk); + g_free(Yk); + g_free(fk); + g_free(lk); + return false; + } + + // calcul du delta= pondere par les longueurs des segments + double delta = 0; + { + double worstD = 0; + worstP = -1; + NR::Point prevAppP; + NR::Point prevP; + double prevDist; + prevP[0] = Xk[0]; + prevP[1] = Yk[0]; + prevAppP = prevP; // le premier seulement + prevDist = 0; +#ifdef with_splotch_killer + if ( N <= 20 ) { + for (int i = 1; i < N - 1; i++) + { + NR::Point curAppP; + NR::Point curP; + double curDist; + NR::Point midAppP; + NR::Point midP; + double midDist; + + curAppP[0] = N13 (tk[i]) * cp1[0] + N23 (tk[i]) * cp2[0] + N03 (tk[i]) * Xk[0] + N33 (tk[i]) * Xk[N - 1]; + curAppP[1] = N13 (tk[i]) * cp1[1] + N23 (tk[i]) * cp2[1] + N03 (tk[i]) * Yk[0] + N33 (tk[i]) * Yk[N - 1]; + curP[0] = Xk[i]; + curP[1] = Yk[i]; + midAppP[0] = N13 (0.5*(tk[i]+tk[i-1])) * cp1[0] + N23 (0.5*(tk[i]+tk[i-1])) * cp2[0] + N03 (0.5*(tk[i]+tk[i-1])) * Xk[0] + N33 (0.5*(tk[i]+tk[i-1])) * Xk[N - 1]; + midAppP[1] = N13 (0.5*(tk[i]+tk[i-1])) * cp1[1] + N23 (0.5*(tk[i]+tk[i-1])) * cp2[1] + N03 (0.5*(tk[i]+tk[i-1])) * Yk[0] + N33 (0.5*(tk[i]+tk[i-1])) * Yk[N - 1]; + midP=0.5*(curP+prevP); + + NR::Point diff; + diff = curAppP-curP; + curDist = dot(diff,diff); + + diff = midAppP-midP; + midDist = dot(diff,diff); + + delta+=0.3333*(curDist+prevDist+midDist)/**lk[i]*/; + + if ( curDist > worstD ) { + worstD = curDist; + worstP = i; + } else if ( fk[i] && 2*curDist > worstD ) { + worstD = 2*curDist; + worstP = i; + } + prevP = curP; + prevAppP = curAppP; + prevDist = curDist; + } + delta/=totLen; + } else { +#endif + for (int i = 1; i < N - 1; i++) + { + NR::Point curAppP; + NR::Point curP; + double curDist; + + curAppP[0] = N13 (tk[i]) * cp1[0] + N23 (tk[i]) * cp2[0] + N03 (tk[i]) * Xk[0] + N33 (tk[i]) * Xk[N - 1]; + curAppP[1] = N13 (tk[i]) * cp1[1] + N23 (tk[i]) * cp2[1] + N03 (tk[i]) * Yk[0] + N33 (tk[i]) * Yk[N - 1]; + curP[0] = Xk[i]; + curP[1] = Yk[i]; + + NR::Point diff; + diff = curAppP-curP; + curDist = dot(diff,diff); + delta += curDist; + if ( curDist > worstD ) { + worstD = curDist; + worstP = i; + } else if ( fk[i] && 2*curDist > worstD ) { + worstD = 2*curDist; + worstP = i; + } + prevP = curP; + prevAppP = curAppP; + prevDist = curDist; + } +#ifdef with_splotch_killer + } +#endif + } + + if (delta < treshhold * treshhold) + { + // premier jet + res.start = 3.0 * (cp1 - start); + res.end = -3.0 * (cp2 - end); + res.p = end; + + // Refine a little. + for (int i = 1; i < N - 1; i++) + { + NR::Point + pt; + pt[0] = Xk[i]; + pt[1] = Yk[i]; + tk[i] = RaffineTk (pt, start, cp1, cp2, end, tk[i]); + if (tk[i] < tk[i - 1]) + { + // Force tk to be monotonic non-decreasing. + tk[i] = tk[i - 1]; + } + } + + if ( FitCubic(start,res,Xk,Yk,Qk,tk,N) ) { + } else { + // ca devrait jamais arriver, mais bon + res.start = 3.0 * (cp1 - start); + res.end = -3.0 * (cp2 - end); + g_free(tk); + g_free(Qk); + g_free(Xk); + g_free(Yk); + g_free(fk); + g_free(lk); + return true; + } + double ndelta = 0; + { + double worstD = 0; + worstP = -1; + NR::Point prevAppP; + NR::Point prevP; + double prevDist; + prevP[0] = Xk[0]; + prevP[1] = Yk[0]; + prevAppP = prevP; // le premier seulement + prevDist = 0; +#ifdef with_splotch_killer + if ( N <= 20 ) { + for (int i = 1; i < N - 1; i++) + { + NR::Point curAppP; + NR::Point curP; + double curDist; + NR::Point midAppP; + NR::Point midP; + double midDist; + + curAppP[0] = N13 (tk[i]) * cp1[0] + N23 (tk[i]) * cp2[0] + N03 (tk[i]) * Xk[0] + N33 (tk[i]) * Xk[N - 1]; + curAppP[1] = N13 (tk[i]) * cp1[1] + N23 (tk[i]) * cp2[1] + N03 (tk[i]) * Yk[0] + N33 (tk[i]) * Yk[N - 1]; + curP[0] = Xk[i]; + curP[1] = Yk[i]; + midAppP[0] = N13 (0.5*(tk[i]+tk[i-1])) * cp1[0] + N23 (0.5*(tk[i]+tk[i-1])) * cp2[0] + N03 (0.5*(tk[i]+tk[i-1])) * Xk[0] + N33 (0.5*(tk[i]+tk[i-1])) * Xk[N - 1]; + midAppP[1] = N13 (0.5*(tk[i]+tk[i-1])) * cp1[1] + N23 (0.5*(tk[i]+tk[i-1])) * cp2[1] + N03 (0.5*(tk[i]+tk[i-1])) * Yk[0] + N33 (0.5*(tk[i]+tk[i-1])) * Yk[N - 1]; + midP = 0.5*(curP+prevP); + + NR::Point diff; + diff = curAppP-curP; + curDist = dot(diff,diff); + diff = midAppP-midP; + midDist = dot(diff,diff); + + ndelta+=0.3333*(curDist+prevDist+midDist)/**lk[i]*/; + + if ( curDist > worstD ) { + worstD = curDist; + worstP = i; + } else if ( fk[i] && 2*curDist > worstD ) { + worstD = 2*curDist; + worstP = i; + } + prevP = curP; + prevAppP = curAppP; + prevDist = curDist; + } + ndelta /= totLen; + } else { +#endif + for (int i = 1; i < N - 1; i++) + { + NR::Point curAppP; + NR::Point curP; + double curDist; + + curAppP[0] = N13 (tk[i]) * cp1[0] + N23 (tk[i]) * cp2[0] + N03 (tk[i]) * Xk[0] + N33 (tk[i]) * Xk[N - 1]; + curAppP[1] = N13 (tk[i]) * cp1[1] + N23 (tk[i]) * cp2[1] + N03 (tk[i]) * Yk[0] + N33 (tk[i]) * Yk[N - 1]; + curP[0]=Xk[i]; + curP[1]=Yk[i]; + + NR::Point diff; + diff=curAppP-curP; + curDist=dot(diff,diff); + ndelta+=curDist; + + if ( curDist > worstD ) { + worstD=curDist; + worstP=i; + } else if ( fk[i] && 2*curDist > worstD ) { + worstD=2*curDist; + worstP=i; + } + prevP=curP; + prevAppP=curAppP; + prevDist=curDist; + } +#ifdef with_splotch_killer + } +#endif + } + + g_free(tk); + g_free(Qk); + g_free(Xk); + g_free(Yk); + g_free(fk); + g_free(lk); + + if (ndelta < delta + 0.00001) + { + return true; + } else { + // nothing better to do + res.start = 3.0 * (cp1 - start); + res.end = -3.0 * (cp2 - end); + } + return true; + } else { + // nothing better to do + } + + g_free(tk); + g_free(Qk); + g_free(Xk); + g_free(Yk); + g_free(fk); + g_free(lk); + return false; +} + +double Path::RaffineTk (NR::Point pt, NR::Point p0, NR::Point p1, NR::Point p2, NR::Point p3, double it) +{ + // Refinement of the tk values. + // Just one iteration of Newtow Raphson, given that we're approaching the curve anyway. + // [fr: vu que de toute facon la courbe est approchC)e] + double const Ax = pt[NR::X] - + p0[NR::X] * N03(it) - + p1[NR::X] * N13(it) - + p2[NR::X] * N23(it) - + p3[NR::X] * N33(it); + + double const Bx = (p1[NR::X] - p0[NR::X]) * N02(it) + + (p2[NR::X] - p1[NR::X]) * N12(it) + + (p3[NR::X] - p2[NR::X]) * N22(it); + + double const Cx = (p0[NR::X] - 2 * p1[NR::X] + p2[NR::X]) * N01(it) + + (p3[NR::X] - 2 * p2[NR::X] + p1[NR::X]) * N11(it); + + double const Ay = pt[NR::Y] - + p0[NR::Y] * N03(it) - + p1[NR::Y] * N13(it) - + p2[NR::Y] * N23(it) - + p3[NR::Y] * N33(it); + + double const By = (p1[NR::Y] - p0[NR::Y]) * N02(it) + + (p2[NR::Y] - p1[NR::Y]) * N12(it) + + (p3[NR::Y] - p2[NR::Y]) * N22(it); + + double const Cy = (p0[NR::Y] - 2 * p1[NR::Y] + p2[NR::Y]) * N01(it) + + (p3[NR::Y] - 2 * p2[NR::Y] + p1[NR::Y]) * N11(it); + + double const dF = -6 * (Ax * Bx + Ay * By); + double const ddF = 18 * (Bx * Bx + By * By) - 12 * (Ax * Cx + Ay * Cy); + if (fabs (ddF) > 0.0000001) { + return it - dF / ddF; + } + + return it; +} + +// variation on the fitting theme: try to merge path commands into cubic bezier patches +// the goal was to reduce the number of path commands, especially when ooperations on path produce +// lots of small path elements; ideally you could get rid of very small segments at reduced visual cost +void Path::Coalesce(double tresh) +{ + if ( descr_flags & descr_adding_bezier ) { + CancelBezier(); + } + + if ( descr_flags & descr_doing_subpath ) { + CloseSubpath(); + } + + if (descr_cmd.size() <= 2) { + return; + } + + SetBackData(false); + Path* tempDest = new Path(); + tempDest->SetBackData(false); + + ConvertEvenLines(0.25*tresh); + + int lastP = 0; + int lastAP = -1; + // As the elements are stored in a separate tableau, it's no longer worth optimizing + // the rewriting in the same tableau. + // [[comme les elements sont stockes dans un tableau a part, plus la peine d'optimiser + // la rŽŽcriture dans la meme tableau]] + + int lastA = descr_cmd[0]->associated; + int prevA = lastA; + NR::Point firstP; + + /* FIXME: the use of this variable probably causes a leak or two. + ** It's a hack anyway, and probably only needs to be a type rather than + ** a full PathDescr. + */ + PathDescr *lastAddition = new PathDescrMoveTo(NR::Point(0, 0)); + bool containsForced = false; + PathDescrCubicTo pending_cubic(NR::Point(0, 0), NR::Point(0, 0), NR::Point(0, 0)); + + for (int curP = 0; curP < int(descr_cmd.size()); curP++) { + int typ = descr_cmd[curP]->getType(); + int nextA = lastA; + + if (typ == descr_moveto) { + + if (lastAddition->flags != descr_moveto) { + FlushPendingAddition(tempDest,lastAddition,pending_cubic,lastAP); + } + lastAddition = descr_cmd[curP]; + lastAP = curP; + FlushPendingAddition(tempDest, lastAddition, pending_cubic, lastAP); + // Added automatically (too bad about multiple moveto's). + // [fr: (tant pis pour les moveto multiples)] + containsForced = false; + + PathDescrMoveTo *nData = dynamic_cast(descr_cmd[curP]); + firstP = nData->p; + lastA = descr_cmd[curP]->associated; + prevA = lastA; + lastP = curP; + + } else if (typ == descr_close) { + nextA = descr_cmd[curP]->associated; + if (lastAddition->flags != descr_moveto) { + + PathDescrCubicTo res(NR::Point(0, 0), NR::Point(0, 0), NR::Point(0, 0)); + int worstP = -1; + if (AttemptSimplify(lastA, nextA - lastA + 1, (containsForced) ? 0.05 * tresh : tresh, res, worstP)) { + lastAddition = new PathDescrCubicTo(NR::Point(0, 0), + NR::Point(0, 0), + NR::Point(0, 0)); + pending_cubic = res; + lastAP = -1; + } + + FlushPendingAddition(tempDest, lastAddition, pending_cubic, lastAP); + FlushPendingAddition(tempDest, descr_cmd[curP], pending_cubic, curP); + + } else { + FlushPendingAddition(tempDest,descr_cmd[curP],pending_cubic,curP); + } + + containsForced = false; + lastAddition = new PathDescrMoveTo(NR::Point(0, 0)); + prevA = lastA = nextA; + lastP = curP; + lastAP = curP; + + } else if (typ == descr_forced) { + + nextA = descr_cmd[curP]->associated; + if (lastAddition->flags != descr_moveto) { + + PathDescrCubicTo res(NR::Point(0, 0), NR::Point(0, 0), NR::Point(0, 0)); + int worstP = -1; + if (AttemptSimplify(lastA, nextA - lastA + 1, 0.05 * tresh, res, worstP)) { + // plus sensible parce que point force + // ca passe + containsForced = true; + } else { + // on force l'addition + FlushPendingAddition(tempDest, lastAddition, pending_cubic, lastAP); + lastAddition = new PathDescrMoveTo(NR::Point(0, 0)); + prevA = lastA = nextA; + lastP = curP; + lastAP = curP; + containsForced = false; + } + } + + } else if (typ == descr_lineto || typ == descr_cubicto || typ == descr_arcto) { + + nextA = descr_cmd[curP]->associated; + if (lastAddition->flags != descr_moveto) { + + PathDescrCubicTo res(NR::Point(0, 0), NR::Point(0, 0), NR::Point(0, 0)); + int worstP = -1; + if (AttemptSimplify(lastA, nextA - lastA + 1, tresh, res, worstP)) { + lastAddition = new PathDescrCubicTo(NR::Point(0, 0), + NR::Point(0, 0), + NR::Point(0, 0)); + pending_cubic = res; + lastAddition->associated = lastA; + lastP = curP; + lastAP = -1; + } else { + lastA = descr_cmd[lastP]->associated; // pourrait etre surecrit par la ligne suivante + FlushPendingAddition(tempDest, lastAddition, pending_cubic, lastAP); + lastAddition = descr_cmd[curP]; + if ( typ == descr_cubicto ) { + pending_cubic = *(dynamic_cast(descr_cmd[curP])); + } + lastAP = curP; + containsForced = false; + } + + } else { + lastA = prevA /*descr_cmd[curP-1]->associated */ ; + lastAddition = descr_cmd[curP]; + if ( typ == descr_cubicto ) { + pending_cubic = *(dynamic_cast(descr_cmd[curP])); + } + lastAP = curP; + containsForced = false; + } + prevA = nextA; + + } else if (typ == descr_bezierto) { + + if (lastAddition->flags != descr_moveto) { + FlushPendingAddition(tempDest, lastAddition, pending_cubic, lastAP); + lastAddition = new PathDescrMoveTo(NR::Point(0, 0)); + } + lastAP = -1; + lastA = descr_cmd[curP]->associated; + lastP = curP; + PathDescrBezierTo *nBData = dynamic_cast(descr_cmd[curP]); + for (int i = 1; i <= nBData->nb; i++) { + FlushPendingAddition(tempDest, descr_cmd[curP + i], pending_cubic, curP + i); + } + curP += nBData->nb; + prevA = nextA; + + } else if (typ == descr_interm_bezier) { + continue; + } else { + continue; + } + } + + if (lastAddition->flags != descr_moveto) { + FlushPendingAddition(tempDest, lastAddition, pending_cubic, lastAP); + } + + Copy(tempDest); + delete tempDest; +} + + +void Path::FlushPendingAddition(Path *dest, PathDescr *lastAddition, + PathDescrCubicTo &lastCubic, int lastAP) +{ + switch (lastAddition->getType()) { + + case descr_moveto: + if ( lastAP >= 0 ) { + PathDescrMoveTo* nData = dynamic_cast(descr_cmd[lastAP]); + dest->MoveTo(nData->p); + } + break; + + case descr_close: + dest->Close(); + break; + + case descr_cubicto: + dest->CubicTo(lastCubic.p, lastCubic.start, lastCubic.end); + break; + + case descr_lineto: + if ( lastAP >= 0 ) { + PathDescrLineTo *nData = dynamic_cast(descr_cmd[lastAP]); + dest->LineTo(nData->p); + } + break; + + case descr_arcto: + if ( lastAP >= 0 ) { + PathDescrArcTo *nData = dynamic_cast(descr_cmd[lastAP]); + dest->ArcTo(nData->p, nData->rx, nData->ry, nData->angle, nData->large, nData->clockwise); + } + break; + + case descr_bezierto: + if ( lastAP >= 0 ) { + PathDescrBezierTo *nData = dynamic_cast(descr_cmd[lastAP]); + dest->BezierTo(nData->p); + } + break; + + case descr_interm_bezier: + if ( lastAP >= 0 ) { + PathDescrIntermBezierTo *nData = dynamic_cast(descr_cmd[lastAP]); + dest->IntermBezierTo(nData->p); + } + break; + } +} + +/* + 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:textwidth=99 : diff --git a/src/livarot/PathStroke.cpp b/src/livarot/PathStroke.cpp new file mode 100644 index 000000000..c182b93aa --- /dev/null +++ b/src/livarot/PathStroke.cpp @@ -0,0 +1,756 @@ +/* + * PathStroke.cpp + * nlivarot + * + * Created by fred on Tue Jun 17 2003. + * + */ + +#include "Path.h" +#include "Shape.h" +#include + +/* + * stroking polylines into a Shape instance + * grunt work. + * if the goal is to raster the stroke, polyline stroke->polygon->uncrossed polygon->raster is grossly + * inefficient (but reuse the intersector, so that's what a lazy programmer like me does). the correct way would be + * to set up a supersampled buffer, raster each polyline stroke's part (one part per segment in the polyline, plus + * each join) because these are all convex polygons, then transform in alpha values + */ + +// until i find something better +NR::Point StrokeNormalize(const NR::Point value) { + double length = L2(value); + if ( length < 0.0000001 ) { + return NR::Point(0, 0); + } else { + return value/length; + } +} + +// faster version if length is known +NR::Point StrokeNormalize(const NR::Point value, double length) { + if ( length < 0.0000001 ) { + return NR::Point(0, 0); + } else { + return value/length; + } +} + +void Path::Stroke(Shape *dest, bool doClose, double width, JoinType join, + ButtType butt, double miter, bool justAdd) +{ + if (dest == NULL) { + return; + } + + if (justAdd == false) { + dest->Reset(3 * pts.size(), 3 * pts.size()); + } + + dest->MakeBackData(false); + + int lastM = 0; + while (lastM < int(pts.size())) { + + int lastP = lastM + 1; + while (lastP < int(pts.size()) // select one subpath + && (pts[lastP].isMoveTo == polyline_lineto + || pts[lastP].isMoveTo == polyline_forced)) + { + lastP++; + } + + if ( lastP > lastM+1 ) { + NR::Point sbStart = pts[lastM].p; + NR::Point sbEnd = pts[lastP - 1].p; + if ( NR::LInfty(sbEnd-sbStart) < 0.00001 ) { // why close lines that shouldn't be closed? + // ah I see, because close is defined here for + // a whole path and should be defined per subpath. + // debut==fin => ferme (on devrait garder un element pour les close(), mais tant pis) + DoStroke(lastM, lastP - lastM, dest, true, width, join, butt, miter, true); + } else { + DoStroke(lastM, lastP - lastM, dest, doClose, width, join, butt, miter, true); + } + } else if (butt == butt_round) { // special case: zero length round butt is a circle + int last[2] = { -1, -1 }; + NR::Point dir; + dir[0] = 1; + dir[1] = 0; + NR::Point pos = pts[lastM].p; + DoButt(dest, width, butt, pos, dir, last[RIGHT], last[LEFT]); + int end[2]; + dir = -dir; + DoButt(dest, width, butt, pos, dir, end[LEFT], end[RIGHT]); + dest->AddEdge (end[LEFT], last[LEFT]); + dest->AddEdge (last[RIGHT], end[RIGHT]); + } + lastM = lastP; + } +} + +void Path::DoStroke(int off, int N, Shape *dest, bool doClose, double width, JoinType join, + ButtType butt, double miter, bool justAdd) +{ + if (N <= 1) { + return; + } + + NR::Point prevP, nextP; + int prevI, nextI; + int upTo; + + int curI = 0; + NR::Point curP = pts[off].p; + + if (doClose) { + + prevI = N - 1; + while (prevI > 0) { + prevP = pts[off + prevI].p; + NR::Point diff = curP - prevP; + double dist = dot(diff, diff); + if (dist > 0.001) { + break; + } + prevI--; + } + if (prevI <= 0) { + return; + } + upTo = prevI; + + } else { + + prevP = curP; + prevI = curI; + upTo = N - 1; + } + + { + nextI = 1; + while (nextI <= upTo) { + nextP = pts[off + nextI].p; + NR::Point diff = curP - nextP; + double dist = dot(diff, diff); + if (dist > 0.0) { // more tolerance for the first distance, to give the cap the right direction + break; + } + nextI++; + } + if (nextI > upTo) { + if (butt == butt_round) { // special case: zero length round butt is a circle + int last[2] = { -1, -1 }; + NR::Point dir; + dir[0] = 1; + dir[1] = 0; + DoButt(dest, width, butt, curP, dir, last[RIGHT], last[LEFT]); + int end[2]; + dir = -dir; + DoButt(dest, width, butt, curP, dir, end[LEFT], end[RIGHT]); + dest->AddEdge (end[LEFT], last[LEFT]); + dest->AddEdge (last[RIGHT], end[RIGHT]); + } + return; + } + } + + int start[2] = { -1, -1 }; + int last[2] = { -1, -1 }; + NR::Point prevD = curP - prevP; + NR::Point nextD = nextP - curP; + double prevLe = NR::L2(prevD); + double nextLe = NR::L2(nextD); + prevD = StrokeNormalize(prevD, prevLe); + nextD = StrokeNormalize(nextD, nextLe); + + if (doClose) { + DoJoin(dest, width, join, curP, prevD, nextD, miter, prevLe, nextLe, start, last); + } else { + nextD = -nextD; + DoButt(dest, width, butt, curP, nextD, last[RIGHT], last[LEFT]); + nextD = -nextD; + } + + do { + prevP = curP; + prevI = curI; + curP = nextP; + curI = nextI; + prevD = nextD; + prevLe = nextLe; + nextI++; + while (nextI <= upTo) { + nextP = pts[off + nextI].p; + NR::Point diff = curP - nextP; + double dist = dot(diff, diff); + if (dist > 0.001 || (nextI == upTo && dist > 0.0)) { // more tolerance for the last distance too, for the right cap direction + break; + } + nextI++; + } + if (nextI > upTo) { + break; + } + + nextD = nextP - curP; + nextLe = NR::L2(nextD); + nextD = StrokeNormalize(nextD, nextLe); + int nSt[2] = { -1, -1 }; + int nEn[2] = { -1, -1 }; + DoJoin(dest, width, join, curP, prevD, nextD, miter, prevLe, nextLe, nSt, nEn); + dest->AddEdge(nSt[LEFT], last[LEFT]); + last[LEFT] = nEn[LEFT]; + dest->AddEdge(last[RIGHT], nSt[RIGHT]); + last[RIGHT] = nEn[RIGHT]; + } while (nextI <= upTo); + + if (doClose) { + /* prevP=curP; + prevI=curI; + curP=nextP; + curI=nextI; + prevD=nextD;*/ + nextP = pts[off].p; + + nextD = nextP - curP; + nextLe = NR::L2(nextD); + nextD = StrokeNormalize(nextD, nextLe); + int nSt[2] = { -1, -1 }; + int nEn[2] = { -1, -1 }; + DoJoin(dest, width, join, curP, prevD, nextD, miter, prevLe, nextLe, nSt, nEn); + dest->AddEdge (nSt[LEFT], last[LEFT]); + last[LEFT] = nEn[LEFT]; + dest->AddEdge (last[RIGHT], nSt[RIGHT]); + last[RIGHT] = nEn[RIGHT]; + + dest->AddEdge (start[LEFT], last[LEFT]); + dest->AddEdge (last[RIGHT], start[RIGHT]); + + } else { + + int end[2]; + DoButt (dest, width, butt, curP, prevD, end[LEFT], end[RIGHT]); + dest->AddEdge (end[LEFT], last[LEFT]); + dest->AddEdge (last[RIGHT], end[RIGHT]); + } +} + + +void Path::DoButt(Shape *dest, double width, ButtType butt, NR::Point pos, NR::Point dir, + int &leftNo, int &rightNo) +{ + NR::Point nor; + nor = dir.ccw(); + + if (butt == butt_square) + { + NR::Point x; + x = pos + width * dir + width * nor; + int bleftNo = dest->AddPoint (x); + x = pos + width * dir - width * nor; + int brightNo = dest->AddPoint (x); + x = pos + width * nor; + leftNo = dest->AddPoint (x); + x = pos - width * nor; + rightNo = dest->AddPoint (x); + dest->AddEdge (rightNo, brightNo); + dest->AddEdge (brightNo, bleftNo); + dest->AddEdge (bleftNo, leftNo); + } + else if (butt == butt_pointy) + { + leftNo = dest->AddPoint (pos + width * nor); + rightNo = dest->AddPoint (pos - width * nor); + int mid = dest->AddPoint (pos + width * dir); + dest->AddEdge (rightNo, mid); + dest->AddEdge (mid, leftNo); + } + else if (butt == butt_round) + { + const NR::Point sx = pos + width * nor; + const NR::Point ex = pos - width * nor; + leftNo = dest->AddPoint (sx); + rightNo = dest->AddPoint (ex); + + RecRound (dest, rightNo, leftNo, ex, sx, -nor, nor, pos, width); + } + else + { + leftNo = dest->AddPoint (pos + width * nor); + rightNo = dest->AddPoint (pos - width * nor); + dest->AddEdge (rightNo, leftNo); + } +} + + +void Path::DoJoin (Shape *dest, double width, JoinType join, NR::Point pos, NR::Point prev, + NR::Point next, double miter, double prevL, double nextL, + int *stNo, int *enNo) +{ + NR::Point pnor = prev.ccw(); + NR::Point nnor = next.ccw(); + double angSi = cross(next, prev); + + /* FIXED: this special case caused bug 1028953 */ + if (angSi > -0.0001 && angSi < 0.0001) { + double angCo = dot (prev, next); + if (angCo > 0.9999) { + // tout droit + stNo[LEFT] = enNo[LEFT] = dest->AddPoint(pos + width * pnor); + stNo[RIGHT] = enNo[RIGHT] = dest->AddPoint(pos - width * pnor); + } else { + // demi-tour + const NR::Point sx = pos + width * pnor; + const NR::Point ex = pos - width * pnor; + stNo[LEFT] = enNo[RIGHT] = dest->AddPoint (sx); + stNo[RIGHT] = enNo[LEFT] = dest->AddPoint (ex); + if (join == join_round) { + RecRound (dest, enNo[LEFT], stNo[LEFT], ex, sx, -pnor, pnor, pos, width); + dest->AddEdge(stNo[RIGHT], enNo[RIGHT]); + } else { + dest->AddEdge(enNo[LEFT], stNo[LEFT]); + dest->AddEdge(stNo[RIGHT], enNo[RIGHT]); // two times because both are crossing each other + } + } + return; + } + + if (angSi < 0) { + int midNo = dest->AddPoint(pos); + stNo[LEFT] = dest->AddPoint(pos + width * pnor); + enNo[LEFT] = dest->AddPoint(pos + width * nnor); + dest->AddEdge(enNo[LEFT], midNo); + dest->AddEdge(midNo, stNo[LEFT]); + + if (join == join_pointy) { + + stNo[RIGHT] = dest->AddPoint(pos - width * pnor); + enNo[RIGHT] = dest->AddPoint(pos - width * nnor); + + const NR::Point biss = StrokeNormalize(prev - next); + double c2 = dot(biss, nnor); + double l = width / c2; + double emiter = width * c2; + if (emiter < miter) { + emiter = miter; + } + + if (fabs(l) < miter) { + int const n = dest->AddPoint(pos - l * biss); + dest->AddEdge(stNo[RIGHT], n); + dest->AddEdge(n, enNo[RIGHT]); + } else { + dest->AddEdge(stNo[RIGHT], enNo[RIGHT]); + } + + } else if (join == join_round) { + NR::Point sx = pos - width * pnor; + stNo[RIGHT] = dest->AddPoint(sx); + NR::Point ex = pos - width * nnor; + enNo[RIGHT] = dest->AddPoint(ex); + + RecRound(dest, stNo[RIGHT], enNo[RIGHT], + sx, ex, -pnor, -nnor, pos, width); + + } else { + stNo[RIGHT] = dest->AddPoint(pos - width * pnor); + enNo[RIGHT] = dest->AddPoint(pos - width * nnor); + dest->AddEdge(stNo[RIGHT], enNo[RIGHT]); + } + + } else { + + int midNo = dest->AddPoint(pos); + stNo[RIGHT] = dest->AddPoint(pos - width * pnor); + enNo[RIGHT] = dest->AddPoint(pos - width * nnor); + dest->AddEdge(stNo[RIGHT], midNo); + dest->AddEdge(midNo, enNo[RIGHT]); + + if (join == join_pointy) { + + stNo[LEFT] = dest->AddPoint(pos + width * pnor); + enNo[LEFT] = dest->AddPoint(pos + width * nnor); + + const NR::Point biss = StrokeNormalize(next - prev); + double c2 = dot(biss, nnor); + double l = width / c2; + double emiter = width * c2; + if (emiter < miter) { + emiter = miter; + } + if ( fabs(l) < miter) { + int const n = dest->AddPoint (pos + l * biss); + dest->AddEdge (enNo[LEFT], n); + dest->AddEdge (n, stNo[LEFT]); + } + else + { + dest->AddEdge (enNo[LEFT], stNo[LEFT]); + } + + } else if (join == join_round) { + + NR::Point sx = pos + width * pnor; + stNo[LEFT] = dest->AddPoint(sx); + NR::Point ex = pos + width * nnor; + enNo[LEFT] = dest->AddPoint(ex); + + RecRound(dest, enNo[LEFT], stNo[LEFT], + ex, sx, nnor, pnor, pos, width); + + } else { + stNo[LEFT] = dest->AddPoint(pos + width * pnor); + enNo[LEFT] = dest->AddPoint(pos + width * nnor); + dest->AddEdge(enNo[LEFT], stNo[LEFT]); + } + } +} + + void +Path::DoLeftJoin (Shape * dest, double width, JoinType join, NR::Point pos, + NR::Point prev, NR::Point next, double miter, double prevL, double nextL, + int &leftStNo, int &leftEnNo,int pathID,int pieceID,double tID) +{ + NR::Point pnor=prev.ccw(); + NR::Point nnor=next.ccw(); + double angSi = cross (next, prev); + if (angSi > -0.0001 && angSi < 0.0001) + { + double angCo = dot (prev, next); + if (angCo > 0.9999) + { + // tout droit + leftEnNo = leftStNo = dest->AddPoint (pos + width * pnor); + } + else + { + // demi-tour + leftStNo = dest->AddPoint (pos + width * pnor); + leftEnNo = dest->AddPoint (pos - width * pnor); + int nEdge=dest->AddEdge (leftEnNo, leftStNo); + if ( dest->hasBackData() ) { + dest->ebData[nEdge].pathID=pathID; + dest->ebData[nEdge].pieceID=pieceID; + dest->ebData[nEdge].tSt=dest->ebData[nEdge].tEn=tID; + } + } + return; + } + if (angSi < 0) + { + /* NR::Point biss; + biss.x=next.x-prev.x; + biss.y=next.y-prev.y; + double c2=cross(biss,next); + double l=width/c2; + double projn=l*(dot(biss,next)); + double projp=-l*(dot(biss,prev)); + if ( projp <= 0.5*prevL && projn <= 0.5*nextL ) { + double x,y; + x=pos.x+l*biss.x; + y=pos.y+l*biss.y; + leftEnNo=leftStNo=dest->AddPoint(x,y); + } else {*/ + leftStNo = dest->AddPoint (pos + width * pnor); + leftEnNo = dest->AddPoint (pos + width * nnor); + int midNo = dest->AddPoint (pos); + int nEdge=dest->AddEdge (leftEnNo, midNo); + if ( dest->hasBackData() ) { + dest->ebData[nEdge].pathID=pathID; + dest->ebData[nEdge].pieceID=pieceID; + dest->ebData[nEdge].tSt=dest->ebData[nEdge].tEn=tID; + } + nEdge=dest->AddEdge (midNo, leftStNo); + if ( dest->hasBackData() ) { + dest->ebData[nEdge].pathID=pathID; + dest->ebData[nEdge].pieceID=pieceID; + dest->ebData[nEdge].tSt=dest->ebData[nEdge].tEn=tID; + } + // } + } + else + { + if (join == join_pointy) + { + leftStNo = dest->AddPoint (pos + width * pnor); + leftEnNo = dest->AddPoint (pos + width * nnor); + + const NR::Point biss = StrokeNormalize (pnor + nnor); + double c2 = dot (biss, nnor); + double l = width / c2; + double emiter = width * c2; + if (emiter < miter) + emiter = miter; + if (l <= emiter) + { + int nleftStNo = dest->AddPoint (pos + l * biss); + int nEdge=dest->AddEdge (leftEnNo, nleftStNo); + if ( dest->hasBackData() ) { + dest->ebData[nEdge].pathID=pathID; + dest->ebData[nEdge].pieceID=pieceID; + dest->ebData[nEdge].tSt=dest->ebData[nEdge].tEn=tID; + } + nEdge=dest->AddEdge (nleftStNo, leftStNo); + if ( dest->hasBackData() ) { + dest->ebData[nEdge].pathID=pathID; + dest->ebData[nEdge].pieceID=pieceID; + dest->ebData[nEdge].tSt=dest->ebData[nEdge].tEn=tID; + } + } + else + { + double s2 = cross (biss, nnor); + double dec = (l - emiter) * c2 / s2; + const NR::Point tbiss=biss.ccw(); + + int nleftStNo = dest->AddPoint (pos + emiter * biss + dec * tbiss); + int nleftEnNo = dest->AddPoint (pos + emiter * biss - dec * tbiss); + int nEdge=dest->AddEdge (nleftEnNo, nleftStNo); + if ( dest->hasBackData() ) { + dest->ebData[nEdge].pathID=pathID; + dest->ebData[nEdge].pieceID=pieceID; + dest->ebData[nEdge].tSt=dest->ebData[nEdge].tEn=tID; + } + nEdge=dest->AddEdge (leftEnNo, nleftEnNo); + if ( dest->hasBackData() ) { + dest->ebData[nEdge].pathID=pathID; + dest->ebData[nEdge].pieceID=pieceID; + dest->ebData[nEdge].tSt=dest->ebData[nEdge].tEn=tID; + } + nEdge=dest->AddEdge (nleftStNo, leftStNo); + if ( dest->hasBackData() ) { + dest->ebData[nEdge].pathID=pathID; + dest->ebData[nEdge].pieceID=pieceID; + dest->ebData[nEdge].tSt=dest->ebData[nEdge].tEn=tID; + } + } + } + else if (join == join_round) + { + const NR::Point sx = pos + width * pnor; + leftStNo = dest->AddPoint (sx); + const NR::Point ex = pos + width * nnor; + leftEnNo = dest->AddPoint (ex); + + RecRound(dest, leftEnNo, leftStNo, + sx, ex, pnor, nnor ,pos, width); + + } + else + { + leftStNo = dest->AddPoint (pos + width * pnor); + leftEnNo = dest->AddPoint (pos + width * nnor); + int nEdge=dest->AddEdge (leftEnNo, leftStNo); + if ( dest->hasBackData() ) { + dest->ebData[nEdge].pathID=pathID; + dest->ebData[nEdge].pieceID=pieceID; + dest->ebData[nEdge].tSt=dest->ebData[nEdge].tEn=tID; + } + } + } +} + void +Path::DoRightJoin (Shape * dest, double width, JoinType join, NR::Point pos, + NR::Point prev, NR::Point next, double miter, double prevL, + double nextL, int &rightStNo, int &rightEnNo,int pathID,int pieceID,double tID) +{ + const NR::Point pnor=prev.ccw(); + const NR::Point nnor=next.ccw(); + double angSi = cross (next,prev); + if (angSi > -0.0001 && angSi < 0.0001) + { + double angCo = dot (prev, next); + if (angCo > 0.9999) + { + // tout droit + rightEnNo = rightStNo = dest->AddPoint (pos - width*pnor); + } + else + { + // demi-tour + rightEnNo = dest->AddPoint (pos + width*pnor); + rightStNo = dest->AddPoint (pos - width*pnor); + int nEdge=dest->AddEdge (rightStNo, rightEnNo); + if ( dest->hasBackData() ) { + dest->ebData[nEdge].pathID=pathID; + dest->ebData[nEdge].pieceID=pieceID; + dest->ebData[nEdge].tSt=dest->ebData[nEdge].tEn=tID; + } + } + return; + } + if (angSi < 0) + { + if (join == join_pointy) + { + rightStNo = dest->AddPoint (pos - width*pnor); + rightEnNo = dest->AddPoint (pos - width*nnor); + + const NR::Point biss = StrokeNormalize (pnor + nnor); + double c2 = dot (biss, nnor); + double l = width / c2; + double emiter = width * c2; + if (emiter < miter) + emiter = miter; + if (l <= emiter) + { + int nrightStNo = dest->AddPoint (pos - l * biss); + int nEdge=dest->AddEdge (rightStNo, nrightStNo); + if ( dest->hasBackData() ) { + dest->ebData[nEdge].pathID=pathID; + dest->ebData[nEdge].pieceID=pieceID; + dest->ebData[nEdge].tSt=dest->ebData[nEdge].tEn=tID; + } + nEdge=dest->AddEdge (nrightStNo, rightEnNo); + if ( dest->hasBackData() ) { + dest->ebData[nEdge].pathID=pathID; + dest->ebData[nEdge].pieceID=pieceID; + dest->ebData[nEdge].tSt=dest->ebData[nEdge].tEn=tID; + } + } + else + { + double s2 = cross (biss, nnor); + double dec = (l - emiter) * c2 / s2; + const NR::Point tbiss=biss.ccw(); + + int nrightStNo = dest->AddPoint (pos - emiter*biss - dec*tbiss); + int nrightEnNo = dest->AddPoint (pos - emiter*biss + dec*tbiss); + int nEdge=dest->AddEdge (rightStNo, nrightStNo); + if ( dest->hasBackData() ) { + dest->ebData[nEdge].pathID=pathID; + dest->ebData[nEdge].pieceID=pieceID; + dest->ebData[nEdge].tSt=dest->ebData[nEdge].tEn=tID; + } + nEdge=dest->AddEdge (nrightStNo, nrightEnNo); + if ( dest->hasBackData() ) { + dest->ebData[nEdge].pathID=pathID; + dest->ebData[nEdge].pieceID=pieceID; + dest->ebData[nEdge].tSt=dest->ebData[nEdge].tEn=tID; + } + nEdge=dest->AddEdge (nrightEnNo, rightEnNo); + if ( dest->hasBackData() ) { + dest->ebData[nEdge].pathID=pathID; + dest->ebData[nEdge].pieceID=pieceID; + dest->ebData[nEdge].tSt=dest->ebData[nEdge].tEn=tID; + } + } + } + else if (join == join_round) + { + const NR::Point sx = pos - width * pnor; + rightStNo = dest->AddPoint (sx); + const NR::Point ex = pos - width * nnor; + rightEnNo = dest->AddPoint (ex); + + RecRound(dest, rightStNo, rightEnNo, + sx, ex, -pnor, -nnor ,pos, width); + } + else + { + rightStNo = dest->AddPoint (pos - width * pnor); + rightEnNo = dest->AddPoint (pos - width * nnor); + int nEdge=dest->AddEdge (rightStNo, rightEnNo); + if ( dest->hasBackData() ) { + dest->ebData[nEdge].pathID=pathID; + dest->ebData[nEdge].pieceID=pieceID; + dest->ebData[nEdge].tSt=dest->ebData[nEdge].tEn=tID; + } + } + } + else + { + /* NR::Point biss; + biss=next.x-prev.x; + biss.y=next.y-prev.y; + double c2=cross(next,biss); + double l=width/c2; + double projn=l*(dot(biss,next)); + double projp=-l*(dot(biss,prev)); + if ( projp <= 0.5*prevL && projn <= 0.5*nextL ) { + double x,y; + x=pos.x+l*biss.x; + y=pos.y+l*biss.y; + rightEnNo=rightStNo=dest->AddPoint(x,y); + } else {*/ + rightStNo = dest->AddPoint (pos - width*pnor); + rightEnNo = dest->AddPoint (pos - width*nnor); + int midNo = dest->AddPoint (pos); + int nEdge=dest->AddEdge (rightStNo, midNo); + if ( dest->hasBackData() ) { + dest->ebData[nEdge].pathID=pathID; + dest->ebData[nEdge].pieceID=pieceID; + dest->ebData[nEdge].tSt=dest->ebData[nEdge].tEn=tID; + } + nEdge=dest->AddEdge (midNo, rightEnNo); + if ( dest->hasBackData() ) { + dest->ebData[nEdge].pathID=pathID; + dest->ebData[nEdge].pieceID=pieceID; + dest->ebData[nEdge].tSt=dest->ebData[nEdge].tEn=tID; + } + // } + } +} + + +// a very ugly way to produce round joins: doing one (or two, depend on the angle of the join) quadratic bezier curves +// but since most joins are going to be small, nobody will notice -- but somebody noticed and now the ugly stuff is gone! so: + +// a very nice way to produce round joins, caps or dots +void Path::RecRound(Shape *dest, int sNo, int eNo, // start and end index + NR::Point const &iS, NR::Point const &iE, // start and end point + NR::Point const &nS, NR::Point const &nE, // start and end normal vector + NR::Point &origine, float width) // center and radius of round +{ + //NR::Point diff = iS - iE; + //double dist = dot(diff, diff); + if (width < 0.5 || dot(iS - iE, iS - iE)/width < 2.0) { + dest->AddEdge(sNo, eNo); + return; + } + double ang, sia, lod; + if (nS == -nE) { + ang = M_PI; + sia = 1; + } else { + double coa = dot(nS, nE); + sia = cross(nS, nE); + ang = acos(coa); + if ( coa >= 1 ) { + ang = 0; + } + if ( coa <= -1 ) { + ang = M_PI; + } + } + lod = 0.02 + 10 / (10 + width); // limit detail to about 2 degrees (180 * 0.02/Pi degrees) + ang /= lod; + + int nbS = (int) floor(ang); + NR::rotate omega(((sia > 0) ? -lod : lod)); + NR::Point cur = iS - origine; + // StrokeNormalize(cur); + // cur*=width; + int lastNo = sNo; + for (int i = 0; i < nbS; i++) { + cur = cur * omega; + NR::Point m = origine + cur; + int mNo = dest->AddPoint(m); + dest->AddEdge(lastNo, mNo); + lastNo = mNo; + } + dest->AddEdge(lastNo, eNo); +} + +/* + Local Variables: +mode:c++ +c-file-style:"stroustrup" +c-file-offsets:((innamespace . 0)(inline-open . 0)) +indent-tabs-mode:nil +fill-column:99 +End: + */ +// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/livarot/Shape.cpp b/src/livarot/Shape.cpp new file mode 100644 index 000000000..eead99225 --- /dev/null +++ b/src/livarot/Shape.cpp @@ -0,0 +1,2282 @@ +/* + * Shape.cpp + * nlivarot + * + * Created by fred on Thu Jun 12 2003. + * + */ + +#include +#include "Shape.h" +#include "livarot/sweep-event-queue.h" +#include "livarot/sweep-tree-list.h" +#include + +/* + * Shape instances handling. + * never (i repeat: never) modify edges and points links; use Connect() and Disconnect() instead + * the graph is stored as a set of points and edges, with edges in a doubly-linked list for each point. + */ + +Shape::Shape() + : iData(NULL), + sTree(NULL), + sEvts(NULL), + _need_points_sorting(false), + _need_edges_sorting(false), + _has_points_data(false), + _has_edges_data(false), + _has_sweep_src_data(false), + _has_sweep_dest_data(false), + _has_raster_data(false), + _has_quick_raster_data(false), + _has_back_data(false), + _has_voronoi_data(false) +{ + leftX = topY = rightX = bottomY = 0; + maxPt = 0; + maxAr = 0; + + type = shape_polygon; +} +Shape::~Shape (void) +{ + maxPt = 0; + maxAr = 0; +} + +void Shape::Affiche(void) +{ + /* + printf("sh=%p nbPt=%i nbAr=%i\n",this,nbPt,nbAr); // localizing ok + for (int i=0;inumberOfPoints(), who->numberOfEdges()); + type = who->type; + _need_points_sorting = who->_need_points_sorting; + _need_edges_sorting = who->_need_edges_sorting; + _has_points_data = false; + _has_edges_data = false; + _has_sweep_src_data = false; + _has_sweep_dest_data = false; + _has_raster_data = false; + _has_quick_raster_data = false; + _has_back_data = false; + _has_voronoi_data = false; + + _pts = who->_pts; + _aretes = who->_aretes; +} + +void +Shape::Reset (int n, int m) +{ + _pts.clear(); + _aretes.clear(); + + type = shape_polygon; + if (n > maxPt) + { + maxPt = n; + if (_has_points_data) + pData.resize(maxPt); + if (_has_voronoi_data) + vorpData.resize(maxPt); + } + if (m > maxAr) + { + maxAr = m; + if (_has_edges_data) + eData.resize(maxAr); + if (_has_sweep_dest_data) + swdData.resize(maxAr); + if (_has_sweep_src_data) + swsData.resize(maxAr); + if (_has_back_data) + ebData.resize(maxAr); + if (_has_voronoi_data) + voreData.resize(maxAr); + } + _need_points_sorting = false; + _need_edges_sorting = false; +} + +int +Shape::AddPoint (const NR::Point x) +{ + if (numberOfPoints() >= maxPt) + { + maxPt = 2 * numberOfPoints() + 1; + if (_has_points_data) + pData.resize(maxPt); + if (_has_voronoi_data) + vorpData.resize(maxPt); + } + + dg_point p; + p.x = x; + p.dI = p.dO = 0; + p.incidentEdge[FIRST] = p.incidentEdge[LAST] = -1; + p.oldDegree = -1; + _pts.push_back(p); + int const n = _pts.size() - 1; + + if (_has_points_data) + { + pData[n].pending = 0; + pData[n].edgeOnLeft = -1; + pData[n].nextLinkedPoint = -1; + pData[n].askForWindingS = NULL; + pData[n].askForWindingB = -1; + } + if (_has_voronoi_data) + { + vorpData[n].value = 0.0; + vorpData[n].winding = -2; + } + _need_points_sorting = true; + + return n; +} + +void +Shape::SubPoint (int p) +{ + if (p < 0 || p >= numberOfPoints()) + return; + _need_points_sorting = true; + int cb; + cb = getPoint(p).incidentEdge[FIRST]; + while (cb >= 0 && cb < numberOfEdges()) + { + if (getEdge(cb).st == p) + { + int ncb = getEdge(cb).nextS; + _aretes[cb].nextS = _aretes[cb].prevS = -1; + _aretes[cb].st = -1; + cb = ncb; + } + else if (getEdge(cb).en == p) + { + int ncb = getEdge(cb).nextE; + _aretes[cb].nextE = _aretes[cb].prevE = -1; + _aretes[cb].en = -1; + cb = ncb; + } + else + { + break; + } + } + _pts[p].incidentEdge[FIRST] = _pts[p].incidentEdge[LAST] = -1; + if (p < numberOfPoints() - 1) + SwapPoints (p, numberOfPoints() - 1); + _pts.pop_back(); +} + +void +Shape::SwapPoints (int a, int b) +{ + if (a == b) + return; + if (getPoint(a).totalDegree() == 2 && getPoint(b).totalDegree() == 2) + { + int cb = getPoint(a).incidentEdge[FIRST]; + if (getEdge(cb).st == a) + { + _aretes[cb].st = numberOfPoints(); + } + else if (getEdge(cb).en == a) + { + _aretes[cb].en = numberOfPoints(); + } + cb = getPoint(a).incidentEdge[LAST]; + if (getEdge(cb).st == a) + { + _aretes[cb].st = numberOfPoints(); + } + else if (getEdge(cb).en == a) + { + _aretes[cb].en = numberOfPoints(); + } + + cb = getPoint(b).incidentEdge[FIRST]; + if (getEdge(cb).st == b) + { + _aretes[cb].st = a; + } + else if (getEdge(cb).en == b) + { + _aretes[cb].en = a; + } + cb = getPoint(b).incidentEdge[LAST]; + if (getEdge(cb).st == b) + { + _aretes[cb].st = a; + } + else if (getEdge(cb).en == b) + { + _aretes[cb].en = a; + } + + cb = getPoint(a).incidentEdge[FIRST]; + if (getEdge(cb).st == numberOfPoints()) + { + _aretes[cb].st = b; + } + else if (getEdge(cb).en == numberOfPoints()) + { + _aretes[cb].en = b; + } + cb = getPoint(a).incidentEdge[LAST]; + if (getEdge(cb).st == numberOfPoints()) + { + _aretes[cb].st = b; + } + else if (getEdge(cb).en == numberOfPoints()) + { + _aretes[cb].en = b; + } + + } + else + { + int cb; + cb = getPoint(a).incidentEdge[FIRST]; + while (cb >= 0) + { + int ncb = NextAt (a, cb); + if (getEdge(cb).st == a) + { + _aretes[cb].st = numberOfPoints(); + } + else if (getEdge(cb).en == a) + { + _aretes[cb].en = numberOfPoints(); + } + cb = ncb; + } + cb = getPoint(b).incidentEdge[FIRST]; + while (cb >= 0) + { + int ncb = NextAt (b, cb); + if (getEdge(cb).st == b) + { + _aretes[cb].st = a; + } + else if (getEdge(cb).en == b) + { + _aretes[cb].en = a; + } + cb = ncb; + } + cb = getPoint(a).incidentEdge[FIRST]; + while (cb >= 0) + { + int ncb = NextAt (numberOfPoints(), cb); + if (getEdge(cb).st == numberOfPoints()) + { + _aretes[cb].st = b; + } + else if (getEdge(cb).en == numberOfPoints()) + { + _aretes[cb].en = b; + } + cb = ncb; + } + } + { + dg_point swap = getPoint(a); + _pts[a] = getPoint(b); + _pts[b] = swap; + } + if (_has_points_data) + { + point_data swad = pData[a]; + pData[a] = pData[b]; + pData[b] = swad; + // pData[pData[a].oldInd].newInd=a; + // pData[pData[b].oldInd].newInd=b; + } + if (_has_voronoi_data) + { + voronoi_point swav = vorpData[a]; + vorpData[a] = vorpData[b]; + vorpData[b] = swav; + } +} +void +Shape::SwapPoints (int a, int b, int c) +{ + if (a == b || b == c || a == c) + return; + SwapPoints (a, b); + SwapPoints (b, c); +} + +void +Shape::SortPoints (void) +{ + if (_need_points_sorting && hasPoints()) + SortPoints (0, numberOfPoints() - 1); + _need_points_sorting = false; +} + +void +Shape::SortPointsRounded (void) +{ + if (hasPoints()) + SortPointsRounded (0, numberOfPoints() - 1); +} + +void +Shape::SortPoints (int s, int e) +{ + if (s >= e) + return; + if (e == s + 1) + { + if (getPoint(s).x[1] > getPoint(e).x[1] + || (getPoint(s).x[1] == getPoint(e).x[1] && getPoint(s).x[0] > getPoint(e).x[0])) + SwapPoints (s, e); + return; + } + + int ppos = (s + e) / 2; + int plast = ppos; + double pvalx = getPoint(ppos).x[0]; + double pvaly = getPoint(ppos).x[1]; + + int le = s, ri = e; + while (le < ppos || ri > plast) + { + if (le < ppos) + { + do + { + int test = 0; + if (getPoint(le).x[1] > pvaly) + { + test = 1; + } + else if (getPoint(le).x[1] == pvaly) + { + if (getPoint(le).x[0] > pvalx) + { + test = 1; + } + else if (getPoint(le).x[0] == pvalx) + { + test = 0; + } + else + { + test = -1; + } + } + else + { + test = -1; + } + if (test == 0) + { + // on colle les valeurs egales au pivot ensemble + if (le < ppos - 1) + { + SwapPoints (le, ppos - 1, ppos); + ppos--; + continue; // sans changer le + } + else if (le == ppos - 1) + { + ppos--; + break; + } + else + { + // oupsie + break; + } + } + if (test > 0) + { + break; + } + le++; + } + while (le < ppos); + } + if (ri > plast) + { + do + { + int test = 0; + if (getPoint(ri).x[1] > pvaly) + { + test = 1; + } + else if (getPoint(ri).x[1] == pvaly) + { + if (getPoint(ri).x[0] > pvalx) + { + test = 1; + } + else if (getPoint(ri).x[0] == pvalx) + { + test = 0; + } + else + { + test = -1; + } + } + else + { + test = -1; + } + if (test == 0) + { + // on colle les valeurs egales au pivot ensemble + if (ri > plast + 1) + { + SwapPoints (ri, plast + 1, plast); + plast++; + continue; // sans changer ri + } + else if (ri == plast + 1) + { + plast++; + break; + } + else + { + // oupsie + break; + } + } + if (test < 0) + { + break; + } + ri--; + } + while (ri > plast); + } + if (le < ppos) + { + if (ri > plast) + { + SwapPoints (le, ri); + le++; + ri--; + } + else + { + if (le < ppos - 1) + { + SwapPoints (ppos - 1, plast, le); + ppos--; + plast--; + } + else if (le == ppos - 1) + { + SwapPoints (plast, le); + ppos--; + plast--; + } + } + } + else + { + if (ri > plast + 1) + { + SwapPoints (plast + 1, ppos, ri); + ppos++; + plast++; + } + else if (ri == plast + 1) + { + SwapPoints (ppos, ri); + ppos++; + plast++; + } + else + { + break; + } + } + } + SortPoints (s, ppos - 1); + SortPoints (plast + 1, e); +} + +void +Shape::SortPointsByOldInd (int s, int e) +{ + if (s >= e) + return; + if (e == s + 1) + { + if (getPoint(s).x[1] > getPoint(e).x[1] || (getPoint(s).x[1] == getPoint(e).x[1] && getPoint(s).x[0] > getPoint(e).x[0]) + || (getPoint(s).x[1] == getPoint(e).x[1] && getPoint(s).x[0] == getPoint(e).x[0] + && pData[s].oldInd > pData[e].oldInd)) + SwapPoints (s, e); + return; + } + + int ppos = (s + e) / 2; + int plast = ppos; + double pvalx = getPoint(ppos).x[0]; + double pvaly = getPoint(ppos).x[1]; + int pvali = pData[ppos].oldInd; + + int le = s, ri = e; + while (le < ppos || ri > plast) + { + if (le < ppos) + { + do + { + int test = 0; + if (getPoint(le).x[1] > pvaly) + { + test = 1; + } + else if (getPoint(le).x[1] == pvaly) + { + if (getPoint(le).x[0] > pvalx) + { + test = 1; + } + else if (getPoint(le).x[0] == pvalx) + { + if (pData[le].oldInd > pvali) + { + test = 1; + } + else if (pData[le].oldInd == pvali) + { + test = 0; + } + else + { + test = -1; + } + } + else + { + test = -1; + } + } + else + { + test = -1; + } + if (test == 0) + { + // on colle les valeurs egales au pivot ensemble + if (le < ppos - 1) + { + SwapPoints (le, ppos - 1, ppos); + ppos--; + continue; // sans changer le + } + else if (le == ppos - 1) + { + ppos--; + break; + } + else + { + // oupsie + break; + } + } + if (test > 0) + { + break; + } + le++; + } + while (le < ppos); + } + if (ri > plast) + { + do + { + int test = 0; + if (getPoint(ri).x[1] > pvaly) + { + test = 1; + } + else if (getPoint(ri).x[1] == pvaly) + { + if (getPoint(ri).x[0] > pvalx) + { + test = 1; + } + else if (getPoint(ri).x[0] == pvalx) + { + if (pData[ri].oldInd > pvali) + { + test = 1; + } + else if (pData[ri].oldInd == pvali) + { + test = 0; + } + else + { + test = -1; + } + } + else + { + test = -1; + } + } + else + { + test = -1; + } + if (test == 0) + { + // on colle les valeurs egales au pivot ensemble + if (ri > plast + 1) + { + SwapPoints (ri, plast + 1, plast); + plast++; + continue; // sans changer ri + } + else if (ri == plast + 1) + { + plast++; + break; + } + else + { + // oupsie + break; + } + } + if (test < 0) + { + break; + } + ri--; + } + while (ri > plast); + } + if (le < ppos) + { + if (ri > plast) + { + SwapPoints (le, ri); + le++; + ri--; + } + else + { + if (le < ppos - 1) + { + SwapPoints (ppos - 1, plast, le); + ppos--; + plast--; + } + else if (le == ppos - 1) + { + SwapPoints (plast, le); + ppos--; + plast--; + } + } + } + else + { + if (ri > plast + 1) + { + SwapPoints (plast + 1, ppos, ri); + ppos++; + plast++; + } + else if (ri == plast + 1) + { + SwapPoints (ppos, ri); + ppos++; + plast++; + } + else + { + break; + } + } + } + SortPointsByOldInd (s, ppos - 1); + SortPointsByOldInd (plast + 1, e); +} + +void +Shape::SortPointsRounded (int s, int e) +{ + if (s >= e) + return; + if (e == s + 1) + { + if (pData[s].rx[1] > pData[e].rx[1] + || (pData[s].rx[1] == pData[e].rx[1] && pData[s].rx[0] > pData[e].rx[0])) + SwapPoints (s, e); + return; + } + + int ppos = (s + e) / 2; + int plast = ppos; + double pvalx = pData[ppos].rx[0]; + double pvaly = pData[ppos].rx[1]; + + int le = s, ri = e; + while (le < ppos || ri > plast) + { + if (le < ppos) + { + do + { + int test = 0; + if (pData[le].rx[1] > pvaly) + { + test = 1; + } + else if (pData[le].rx[1] == pvaly) + { + if (pData[le].rx[0] > pvalx) + { + test = 1; + } + else if (pData[le].rx[0] == pvalx) + { + test = 0; + } + else + { + test = -1; + } + } + else + { + test = -1; + } + if (test == 0) + { + // on colle les valeurs egales au pivot ensemble + if (le < ppos - 1) + { + SwapPoints (le, ppos - 1, ppos); + ppos--; + continue; // sans changer le + } + else if (le == ppos - 1) + { + ppos--; + break; + } + else + { + // oupsie + break; + } + } + if (test > 0) + { + break; + } + le++; + } + while (le < ppos); + } + if (ri > plast) + { + do + { + int test = 0; + if (pData[ri].rx[1] > pvaly) + { + test = 1; + } + else if (pData[ri].rx[1] == pvaly) + { + if (pData[ri].rx[0] > pvalx) + { + test = 1; + } + else if (pData[ri].rx[0] == pvalx) + { + test = 0; + } + else + { + test = -1; + } + } + else + { + test = -1; + } + if (test == 0) + { + // on colle les valeurs egales au pivot ensemble + if (ri > plast + 1) + { + SwapPoints (ri, plast + 1, plast); + plast++; + continue; // sans changer ri + } + else if (ri == plast + 1) + { + plast++; + break; + } + else + { + // oupsie + break; + } + } + if (test < 0) + { + break; + } + ri--; + } + while (ri > plast); + } + if (le < ppos) + { + if (ri > plast) + { + SwapPoints (le, ri); + le++; + ri--; + } + else + { + if (le < ppos - 1) + { + SwapPoints (ppos - 1, plast, le); + ppos--; + plast--; + } + else if (le == ppos - 1) + { + SwapPoints (plast, le); + ppos--; + plast--; + } + } + } + else + { + if (ri > plast + 1) + { + SwapPoints (plast + 1, ppos, ri); + ppos++; + plast++; + } + else if (ri == plast + 1) + { + SwapPoints (ppos, ri); + ppos++; + plast++; + } + else + { + break; + } + } + } + SortPointsRounded (s, ppos - 1); + SortPointsRounded (plast + 1, e); +} + +/* + * + */ +int +Shape::AddEdge (int st, int en) +{ + if (st == en) + return -1; + if (st < 0 || en < 0) + return -1; + type = shape_graph; + if (numberOfEdges() >= maxAr) + { + maxAr = 2 * numberOfEdges() + 1; + if (_has_edges_data) + eData.resize(maxAr); + if (_has_sweep_src_data) + swsData.resize(maxAr); + if (_has_sweep_dest_data) + swdData.resize(maxAr); + if (_has_raster_data) + swrData.resize(maxAr); + if (_has_back_data) + ebData.resize(maxAr); + if (_has_voronoi_data) + voreData.resize(maxAr); + } + + dg_arete a; + a.dx = NR::Point(0, 0); + a.st = a.en = -1; + a.prevS = a.nextS = -1; + a.prevE = a.nextE = -1; + if (st >= 0 && en >= 0) { + a.dx = getPoint(en).x - getPoint(st).x; + } + + _aretes.push_back(a); + int const n = numberOfEdges() - 1; + + ConnectStart (st, n); + ConnectEnd (en, n); + if (_has_edges_data) + { + eData[n].weight = 1; + eData[n].rdx = getEdge(n).dx; + } + if (_has_sweep_src_data) + { + swsData[n].misc = NULL; + swsData[n].firstLinkedPoint = -1; + } + if (_has_back_data) + { + ebData[n].pathID = -1; + ebData[n].pieceID = -1; + ebData[n].tSt = ebData[n].tEn = 0; + } + if (_has_voronoi_data) + { + voreData[n].leF = -1; + voreData[n].riF = -1; + } + _need_edges_sorting = true; + return n; +} + +int +Shape::AddEdge (int st, int en, int leF, int riF) +{ + if (st == en) + return -1; + if (st < 0 || en < 0) + return -1; + { + int cb = getPoint(st).incidentEdge[FIRST]; + while (cb >= 0) + { + if (getEdge(cb).st == st && getEdge(cb).en == en) + return -1; // doublon + if (getEdge(cb).st == en && getEdge(cb).en == st) + return -1; // doublon + cb = NextAt (st, cb); + } + } + type = shape_graph; + if (numberOfEdges() >= maxAr) + { + maxAr = 2 * numberOfEdges() + 1; + if (_has_edges_data) + eData.resize(maxAr); + if (_has_sweep_src_data) + swsData.resize(maxAr); + if (_has_sweep_dest_data) + swdData.resize(maxAr); + if (_has_raster_data) + swrData.resize(maxAr); + if (_has_back_data) + ebData.resize(maxAr); + if (_has_voronoi_data) + voreData.resize(maxAr); + } + + dg_arete a; + a.dx = NR::Point(0, 0); + a.st = a.en = -1; + a.prevS = a.nextS = -1; + a.prevE = a.nextE = -1; + if (st >= 0 && en >= 0) { + a.dx = getPoint(en).x - getPoint(st).x; + } + + _aretes.push_back(a); + int const n = numberOfEdges() - 1; + + ConnectStart (st, n); + ConnectEnd (en, n); + if (_has_edges_data) + { + eData[n].weight = 1; + eData[n].rdx = getEdge(n).dx; + } + if (_has_sweep_src_data) + { + swsData[n].misc = NULL; + swsData[n].firstLinkedPoint = -1; + } + if (_has_back_data) + { + ebData[n].pathID = -1; + ebData[n].pieceID = -1; + ebData[n].tSt = ebData[n].tEn = 0; + } + if (_has_voronoi_data) + { + voreData[n].leF = leF; + voreData[n].riF = riF; + } + _need_edges_sorting = true; + return n; +} + +void +Shape::SubEdge (int e) +{ + if (e < 0 || e >= numberOfEdges()) + return; + type = shape_graph; + DisconnectStart (e); + DisconnectEnd (e); + if (e < numberOfEdges() - 1) + SwapEdges (e, numberOfEdges() - 1); + _aretes.pop_back(); + _need_edges_sorting = true; +} + +void +Shape::SwapEdges (int a, int b) +{ + if (a == b) + return; + if (getEdge(a).prevS >= 0 && getEdge(a).prevS != b) + { + if (getEdge(getEdge(a).prevS).st == getEdge(a).st) + { + _aretes[getEdge(a).prevS].nextS = b; + } + else if (getEdge(getEdge(a).prevS).en == getEdge(a).st) + { + _aretes[getEdge(a).prevS].nextE = b; + } + } + if (getEdge(a).nextS >= 0 && getEdge(a).nextS != b) + { + if (getEdge(getEdge(a).nextS).st == getEdge(a).st) + { + _aretes[getEdge(a).nextS].prevS = b; + } + else if (getEdge(getEdge(a).nextS).en == getEdge(a).st) + { + _aretes[getEdge(a).nextS].prevE = b; + } + } + if (getEdge(a).prevE >= 0 && getEdge(a).prevE != b) + { + if (getEdge(getEdge(a).prevE).st == getEdge(a).en) + { + _aretes[getEdge(a).prevE].nextS = b; + } + else if (getEdge(getEdge(a).prevE).en == getEdge(a).en) + { + _aretes[getEdge(a).prevE].nextE = b; + } + } + if (getEdge(a).nextE >= 0 && getEdge(a).nextE != b) + { + if (getEdge(getEdge(a).nextE).st == getEdge(a).en) + { + _aretes[getEdge(a).nextE].prevS = b; + } + else if (getEdge(getEdge(a).nextE).en == getEdge(a).en) + { + _aretes[getEdge(a).nextE].prevE = b; + } + } + if (getEdge(a).st >= 0) + { + if (getPoint(getEdge(a).st).incidentEdge[FIRST] == a) + _pts[getEdge(a).st].incidentEdge[FIRST] = numberOfEdges(); + if (getPoint(getEdge(a).st).incidentEdge[LAST] == a) + _pts[getEdge(a).st].incidentEdge[LAST] = numberOfEdges(); + } + if (getEdge(a).en >= 0) + { + if (getPoint(getEdge(a).en).incidentEdge[FIRST] == a) + _pts[getEdge(a).en].incidentEdge[FIRST] = numberOfEdges(); + if (getPoint(getEdge(a).en).incidentEdge[LAST] == a) + _pts[getEdge(a).en].incidentEdge[LAST] = numberOfEdges(); + } + + + if (getEdge(b).prevS >= 0 && getEdge(b).prevS != a) + { + if (getEdge(getEdge(b).prevS).st == getEdge(b).st) + { + _aretes[getEdge(b).prevS].nextS = a; + } + else if (getEdge(getEdge(b).prevS).en == getEdge(b).st) + { + _aretes[getEdge(b).prevS].nextE = a; + } + } + if (getEdge(b).nextS >= 0 && getEdge(b).nextS != a) + { + if (getEdge(getEdge(b).nextS).st == getEdge(b).st) + { + _aretes[getEdge(b).nextS].prevS = a; + } + else if (getEdge(getEdge(b).nextS).en == getEdge(b).st) + { + _aretes[getEdge(b).nextS].prevE = a; + } + } + if (getEdge(b).prevE >= 0 && getEdge(b).prevE != a) + { + if (getEdge(getEdge(b).prevE).st == getEdge(b).en) + { + _aretes[getEdge(b).prevE].nextS = a; + } + else if (getEdge(getEdge(b).prevE).en == getEdge(b).en) + { + _aretes[getEdge(b).prevE].nextE = a; + } + } + if (getEdge(b).nextE >= 0 && getEdge(b).nextE != a) + { + if (getEdge(getEdge(b).nextE).st == getEdge(b).en) + { + _aretes[getEdge(b).nextE].prevS = a; + } + else if (getEdge(getEdge(b).nextE).en == getEdge(b).en) + { + _aretes[getEdge(b).nextE].prevE = a; + } + } + + + for (int i = 0; i < 2; i++) { + int p = getEdge(b).st; + if (p >= 0) { + if (getPoint(p).incidentEdge[i] == b) { + _pts[p].incidentEdge[i] = a; + } + } + + p = getEdge(b).en; + if (p >= 0) { + if (getPoint(p).incidentEdge[i] == b) { + _pts[p].incidentEdge[i] = a; + } + } + + p = getEdge(a).st; + if (p >= 0) { + if (getPoint(p).incidentEdge[i] == numberOfEdges()) { + _pts[p].incidentEdge[i] = b; + } + } + + p = getEdge(a).en; + if (p >= 0) { + if (getPoint(p).incidentEdge[i] == numberOfEdges()) { + _pts[p].incidentEdge[i] = b; + } + } + + } + + if (getEdge(a).prevS == b) + _aretes[a].prevS = a; + if (getEdge(a).prevE == b) + _aretes[a].prevE = a; + if (getEdge(a).nextS == b) + _aretes[a].nextS = a; + if (getEdge(a).nextE == b) + _aretes[a].nextE = a; + if (getEdge(b).prevS == a) + _aretes[a].prevS = b; + if (getEdge(b).prevE == a) + _aretes[a].prevE = b; + if (getEdge(b).nextS == a) + _aretes[a].nextS = b; + if (getEdge(b).nextE == a) + _aretes[a].nextE = b; + + dg_arete swap = getEdge(a); + _aretes[a] = getEdge(b); + _aretes[b] = swap; + if (_has_edges_data) + { + edge_data swae = eData[a]; + eData[a] = eData[b]; + eData[b] = swae; + } + if (_has_sweep_src_data) + { + sweep_src_data swae = swsData[a]; + swsData[a] = swsData[b]; + swsData[b] = swae; + } + if (_has_sweep_dest_data) + { + sweep_dest_data swae = swdData[a]; + swdData[a] = swdData[b]; + swdData[b] = swae; + } + if (_has_raster_data) + { + raster_data swae = swrData[a]; + swrData[a] = swrData[b]; + swrData[b] = swae; + } + if (_has_back_data) + { + back_data swae = ebData[a]; + ebData[a] = ebData[b]; + ebData[b] = swae; + } + if (_has_voronoi_data) + { + voronoi_edge swav = voreData[a]; + voreData[a] = voreData[b]; + voreData[b] = swav; + } +} +void +Shape::SwapEdges (int a, int b, int c) +{ + if (a == b || b == c || a == c) + return; + SwapEdges (a, b); + SwapEdges (b, c); +} + +void +Shape::SortEdges (void) +{ + if (_need_edges_sorting == false) { + return; + } + _need_edges_sorting = false; + + edge_list *list = (edge_list *) g_malloc(numberOfEdges() * sizeof (edge_list)); + for (int p = 0; p < numberOfPoints(); p++) + { + int const d = getPoint(p).totalDegree(); + if (d > 1) + { + int cb; + cb = getPoint(p).incidentEdge[FIRST]; + int nb = 0; + while (cb >= 0) + { + int n = nb++; + list[n].no = cb; + if (getEdge(cb).st == p) + { + list[n].x = getEdge(cb).dx; + list[n].starting = true; + } + else + { + list[n].x = -getEdge(cb).dx; + list[n].starting = false; + } + cb = NextAt (p, cb); + } + SortEdgesList (list, 0, nb - 1); + _pts[p].incidentEdge[FIRST] = list[0].no; + _pts[p].incidentEdge[LAST] = list[nb - 1].no; + for (int i = 0; i < nb; i++) + { + if (list[i].starting) + { + if (i > 0) + { + _aretes[list[i].no].prevS = list[i - 1].no; + } + else + { + _aretes[list[i].no].prevS = -1; + } + if (i < nb - 1) + { + _aretes[list[i].no].nextS = list[i + 1].no; + } + else + { + _aretes[list[i].no].nextS = -1; + } + } + else + { + if (i > 0) + { + _aretes[list[i].no].prevE = list[i - 1].no; + } + else + { + _aretes[list[i].no].prevE = -1; + } + if (i < nb - 1) + { + _aretes[list[i].no].nextE = list[i + 1].no; + } + else + { + _aretes[list[i].no].nextE = -1; + } + } + } + } + } + g_free(list); +} + +int +Shape::CmpToVert (NR::Point ax, NR::Point bx,bool as,bool bs) +{ + int tstAX = 0; + int tstAY = 0; + int tstBX = 0; + int tstBY = 0; + if (ax[0] > 0) + tstAX = 1; + if (ax[0] < 0) + tstAX = -1; + if (ax[1] > 0) + tstAY = 1; + if (ax[1] < 0) + tstAY = -1; + if (bx[0] > 0) + tstBX = 1; + if (bx[0] < 0) + tstBX = -1; + if (bx[1] > 0) + tstBY = 1; + if (bx[1] < 0) + tstBY = -1; + + int quadA = 0, quadB = 0; + if (tstAX < 0) + { + if (tstAY < 0) + { + quadA = 7; + } + else if (tstAY == 0) + { + quadA = 6; + } + else if (tstAY > 0) + { + quadA = 5; + } + } + else if (tstAX == 0) + { + if (tstAY < 0) + { + quadA = 0; + } + else if (tstAY == 0) + { + quadA = -1; + } + else if (tstAY > 0) + { + quadA = 4; + } + } + else if (tstAX > 0) + { + if (tstAY < 0) + { + quadA = 1; + } + else if (tstAY == 0) + { + quadA = 2; + } + else if (tstAY > 0) + { + quadA = 3; + } + } + if (tstBX < 0) + { + if (tstBY < 0) + { + quadB = 7; + } + else if (tstBY == 0) + { + quadB = 6; + } + else if (tstBY > 0) + { + quadB = 5; + } + } + else if (tstBX == 0) + { + if (tstBY < 0) + { + quadB = 0; + } + else if (tstBY == 0) + { + quadB = -1; + } + else if (tstBY > 0) + { + quadB = 4; + } + } + else if (tstBX > 0) + { + if (tstBY < 0) + { + quadB = 1; + } + else if (tstBY == 0) + { + quadB = 2; + } + else if (tstBY > 0) + { + quadB = 3; + } + } + if (quadA < quadB) + return 1; + if (quadA > quadB) + return -1; + + NR::Point av, bv; + av = ax; + bv = bx; + double si = cross (bv, av); + int tstSi = 0; + if (si > 0.000001) tstSi = 1; + if (si < -0.000001) tstSi = -1; + if ( tstSi == 0 ) { + if ( as == true && bs == false ) return -1; + if ( as == false && bs == true ) return 1; + } + return tstSi; +} + +void +Shape::SortEdgesList (edge_list * list, int s, int e) +{ + if (s >= e) + return; + if (e == s + 1) { + int cmpval=CmpToVert (list[e].x, list[s].x,list[e].starting,list[s].starting); + if ( cmpval > 0 ) { // priorite aux sortants + edge_list swap = list[s]; + list[s] = list[e]; + list[e] = swap; + } + return; + } + + int ppos = (s + e) / 2; + int plast = ppos; + NR::Point pvalx = list[ppos].x; + bool pvals = list[ppos].starting; + + int le = s, ri = e; + while (le < ppos || ri > plast) + { + if (le < ppos) + { + do + { + int test = CmpToVert (pvalx, list[le].x,pvals,list[le].starting); + if (test == 0) + { + // on colle les valeurs egales au pivot ensemble + if (le < ppos - 1) + { + edge_list swap = list[le]; + list[le] = list[ppos - 1]; + list[ppos - 1] = list[ppos]; + list[ppos] = swap; + ppos--; + continue; // sans changer le + } + else if (le == ppos - 1) + { + ppos--; + break; + } + else + { + // oupsie + break; + } + } + if (test > 0) + { + break; + } + le++; + } + while (le < ppos); + } + if (ri > plast) + { + do + { + int test = CmpToVert (pvalx, list[ri].x,pvals,list[ri].starting); + if (test == 0) + { + // on colle les valeurs egales au pivot ensemble + if (ri > plast + 1) + { + edge_list swap = list[ri]; + list[ri] = list[plast + 1]; + list[plast + 1] = list[plast]; + list[plast] = swap; + plast++; + continue; // sans changer ri + } + else if (ri == plast + 1) + { + plast++; + break; + } + else + { + // oupsie + break; + } + } + if (test < 0) + { + break; + } + ri--; + } + while (ri > plast); + } + + if (le < ppos) + { + if (ri > plast) + { + edge_list swap = list[le]; + list[le] = list[ri]; + list[ri] = swap; + le++; + ri--; + } + else if (le < ppos - 1) + { + edge_list swap = list[ppos - 1]; + list[ppos - 1] = list[plast]; + list[plast] = list[le]; + list[le] = swap; + ppos--; + plast--; + } + else if (le == ppos - 1) + { + edge_list swap = list[plast]; + list[plast] = list[le]; + list[le] = swap; + ppos--; + plast--; + } + else + { + break; + } + } + else + { + if (ri > plast + 1) + { + edge_list swap = list[plast + 1]; + list[plast + 1] = list[ppos]; + list[ppos] = list[ri]; + list[ri] = swap; + ppos++; + plast++; + } + else if (ri == plast + 1) + { + edge_list swap = list[ppos]; + list[ppos] = list[ri]; + list[ri] = swap; + ppos++; + plast++; + } + else + { + break; + } + } + } + SortEdgesList (list, s, ppos - 1); + SortEdgesList (list, plast + 1, e); + +} + + + +/* + * + */ +void +Shape::ConnectStart (int p, int b) +{ + if (getEdge(b).st >= 0) + DisconnectStart (b); + + _aretes[b].st = p; + _pts[p].dO++; + _aretes[b].nextS = -1; + _aretes[b].prevS = getPoint(p).incidentEdge[LAST]; + if (getPoint(p).incidentEdge[LAST] >= 0) + { + if (getEdge(getPoint(p).incidentEdge[LAST]).st == p) + { + _aretes[getPoint(p).incidentEdge[LAST]].nextS = b; + } + else if (getEdge(getPoint(p).incidentEdge[LAST]).en == p) + { + _aretes[getPoint(p).incidentEdge[LAST]].nextE = b; + } + } + _pts[p].incidentEdge[LAST] = b; + if (getPoint(p).incidentEdge[FIRST] < 0) + _pts[p].incidentEdge[FIRST] = b; +} + +void +Shape::ConnectEnd (int p, int b) +{ + if (getEdge(b).en >= 0) + DisconnectEnd (b); + _aretes[b].en = p; + _pts[p].dI++; + _aretes[b].nextE = -1; + _aretes[b].prevE = getPoint(p).incidentEdge[LAST]; + if (getPoint(p).incidentEdge[LAST] >= 0) + { + if (getEdge(getPoint(p).incidentEdge[LAST]).st == p) + { + _aretes[getPoint(p).incidentEdge[LAST]].nextS = b; + } + else if (getEdge(getPoint(p).incidentEdge[LAST]).en == p) + { + _aretes[getPoint(p).incidentEdge[LAST]].nextE = b; + } + } + _pts[p].incidentEdge[LAST] = b; + if (getPoint(p).incidentEdge[FIRST] < 0) + _pts[p].incidentEdge[FIRST] = b; +} + +void +Shape::DisconnectStart (int b) +{ + if (getEdge(b).st < 0) + return; + _pts[getEdge(b).st].dO--; + if (getEdge(b).prevS >= 0) + { + if (getEdge(getEdge(b).prevS).st == getEdge(b).st) + { + _aretes[getEdge(b).prevS].nextS = getEdge(b).nextS; + } + else if (getEdge(getEdge(b).prevS).en == getEdge(b).st) + { + _aretes[getEdge(b).prevS].nextE = getEdge(b).nextS; + } + } + if (getEdge(b).nextS >= 0) + { + if (getEdge(getEdge(b).nextS).st == getEdge(b).st) + { + _aretes[getEdge(b).nextS].prevS = getEdge(b).prevS; + } + else if (getEdge(getEdge(b).nextS).en == getEdge(b).st) + { + _aretes[getEdge(b).nextS].prevE = getEdge(b).prevS; + } + } + if (getPoint(getEdge(b).st).incidentEdge[FIRST] == b) + _pts[getEdge(b).st].incidentEdge[FIRST] = getEdge(b).nextS; + if (getPoint(getEdge(b).st).incidentEdge[LAST] == b) + _pts[getEdge(b).st].incidentEdge[LAST] = getEdge(b).prevS; + _aretes[b].st = -1; +} + +void +Shape::DisconnectEnd (int b) +{ + if (getEdge(b).en < 0) + return; + _pts[getEdge(b).en].dI--; + if (getEdge(b).prevE >= 0) + { + if (getEdge(getEdge(b).prevE).st == getEdge(b).en) + { + _aretes[getEdge(b).prevE].nextS = getEdge(b).nextE; + } + else if (getEdge(getEdge(b).prevE).en == getEdge(b).en) + { + _aretes[getEdge(b).prevE].nextE = getEdge(b).nextE; + } + } + if (getEdge(b).nextE >= 0) + { + if (getEdge(getEdge(b).nextE).st == getEdge(b).en) + { + _aretes[getEdge(b).nextE].prevS = getEdge(b).prevE; + } + else if (getEdge(getEdge(b).nextE).en == getEdge(b).en) + { + _aretes[getEdge(b).nextE].prevE = getEdge(b).prevE; + } + } + if (getPoint(getEdge(b).en).incidentEdge[FIRST] == b) + _pts[getEdge(b).en].incidentEdge[FIRST] = getEdge(b).nextE; + if (getPoint(getEdge(b).en).incidentEdge[LAST] == b) + _pts[getEdge(b).en].incidentEdge[LAST] = getEdge(b).prevE; + _aretes[b].en = -1; +} + + +void +Shape::Inverse (int b) +{ + int swap; + swap = getEdge(b).st; + _aretes[b].st = getEdge(b).en; + _aretes[b].en = swap; + swap = getEdge(b).prevE; + _aretes[b].prevE = getEdge(b).prevS; + _aretes[b].prevS = swap; + swap = getEdge(b).nextE; + _aretes[b].nextE = getEdge(b).nextS; + _aretes[b].nextS = swap; + _aretes[b].dx = -getEdge(b).dx; + if (getEdge(b).st >= 0) + { + _pts[getEdge(b).st].dO++; + _pts[getEdge(b).st].dI--; + } + if (getEdge(b).en >= 0) + { + _pts[getEdge(b).en].dO--; + _pts[getEdge(b).en].dI++; + } + if (_has_edges_data) + eData[b].weight = -eData[b].weight; + if (_has_sweep_dest_data) + { + int swap = swdData[b].leW; + swdData[b].leW = swdData[b].riW; + swdData[b].riW = swap; + } + if (_has_back_data) + { + double swat = ebData[b].tSt; + ebData[b].tSt = ebData[b].tEn; + ebData[b].tEn = swat; + } + if (_has_voronoi_data) + { + int swai = voreData[b].leF; + voreData[b].leF = voreData[b].riF; + voreData[b].riF = swai; + } +} +void +Shape::CalcBBox (bool strict_degree) +{ + if (hasPoints() == false) + { + leftX = rightX = topY = bottomY = 0; + return; + } + leftX = rightX = getPoint(0).x[0]; + topY = bottomY = getPoint(0).x[1]; + bool not_set=true; + for (int i = 0; i < numberOfPoints(); i++) + { + if ( strict_degree == false || getPoint(i).dI > 0 || getPoint(i).dO > 0 ) { + if ( not_set ) { + leftX = rightX = getPoint(i).x[0]; + topY = bottomY = getPoint(i).x[1]; + not_set=false; + } else { + if ( getPoint(i).x[0] < leftX) leftX = getPoint(i).x[0]; + if ( getPoint(i).x[0] > rightX) rightX = getPoint(i).x[0]; + if ( getPoint(i).x[1] < topY) topY = getPoint(i).x[1]; + if ( getPoint(i).x[1] > bottomY) bottomY = getPoint(i).x[1]; + } + } + } +} + +// winding of a point with respect to the Shape +// 0= outside +// 1= inside (or -1, that usually the same) +// other=depends on your fill rule +// if the polygon is uncrossed, it's all the same, usually +int +Shape::PtWinding (const NR::Point px) const +{ + int lr = 0, ll = 0, rr = 0; + + for (int i = 0; i < numberOfEdges(); i++) + { + NR::Point const adir = getEdge(i).dx; + + NR::Point const ast = getPoint(getEdge(i).st).x; + NR::Point const aen = getPoint(getEdge(i).en).x; + + //int const nWeight = eData[i].weight; + int const nWeight = 1; + + if (ast[0] < aen[0]) { + if (ast[0] > px[0]) continue; + if (aen[0] < px[0]) continue; + } else { + if (ast[0] < px[0]) continue; + if (aen[0] > px[0]) continue; + } + if (ast[0] == px[0]) { + if (ast[1] >= px[1]) continue; + if (aen[0] == px[0]) continue; + if (aen[0] < px[0]) ll += nWeight; else rr -= nWeight; + continue; + } + if (aen[0] == px[0]) { + if (aen[1] >= px[1]) continue; + if (ast[0] == px[0]) continue; + if (ast[0] < px[0]) ll -= nWeight; else rr += nWeight; + continue; + } + + if (ast[1] < aen[1]) { + if (ast[1] >= px[1]) continue; + } else { + if (aen[1] >= px[1]) continue; + } + + NR::Point const diff = px - ast; + double const cote = cross(diff, adir); + if (cote == 0) continue; + if (cote < 0) { + if (ast[0] > px[0]) lr += nWeight; + } else { + if (ast[0] < px[0]) lr -= nWeight; + } + } + return lr + (ll + rr) / 2; +} + + +void Shape::initialisePointData() +{ + int const N = numberOfPoints(); + + for (int i = 0; i < N; i++) { + pData[i].pending = 0; + pData[i].edgeOnLeft = -1; + pData[i].nextLinkedPoint = -1; + pData[i].rx[0] = Round(getPoint(i).x[0]); + pData[i].rx[1] = Round(getPoint(i).x[1]); + } +} + +void Shape::initialiseEdgeData() +{ + int const N = numberOfEdges(); + + for (int i = 0; i < N; i++) { + eData[i].rdx = pData[getEdge(i).en].rx - pData[getEdge(i).st].rx; + eData[i].length = dot(eData[i].rdx, eData[i].rdx); + eData[i].ilength = 1 / eData[i].length; + eData[i].sqlength = sqrt(eData[i].length); + eData[i].isqlength = 1 / eData[i].sqlength; + eData[i].siEd = eData[i].rdx[1] * eData[i].isqlength; + eData[i].coEd = eData[i].rdx[0] * eData[i].isqlength; + + if (eData[i].siEd < 0) { + eData[i].siEd = -eData[i].siEd; + eData[i].coEd = -eData[i].coEd; + } + + swsData[i].misc = NULL; + swsData[i].firstLinkedPoint = -1; + swsData[i].stPt = swsData[i].enPt = -1; + swsData[i].leftRnd = swsData[i].rightRnd = -1; + swsData[i].nextSh = NULL; + swsData[i].nextBo = -1; + swsData[i].curPoint = -1; + swsData[i].doneTo = -1; + } +} + + +void Shape::clearIncidenceData() +{ + g_free(iData); + iData = NULL; + nbInc = maxInc = 0; +} + + + +/** + * A directed graph is Eulerian iff every vertex has equal indegree and outdegree. + * http://mathworld.wolfram.com/EulerianGraph.html + * + * \param s Directed shape. + * \return true if s is Eulerian. + */ + +bool directedEulerian(Shape const *s) +{ + for (int i = 0; i < s->numberOfPoints(); i++) { + if (s->getPoint(i).dI != s->getPoint(i).dO) { + return false; + } + } + + return true; +} + + + +/** + * \param s Shape. + * \param p Point. + * \return Minimum distance from p to any of the points or edges of s. + */ + +double distance(Shape const *s, NR::Point const &p) +{ + if ( s->hasPoints() == false) { + return 0.0; + } + + /* Find the minimum distance from p to one of the points on s. + ** Computing the dot product of the difference vector gives + ** us the distance squared; we can leave the square root + ** until the end. + */ + double bdot = NR::dot(p - s->getPoint(0).x, p - s->getPoint(0).x); + + for (int i = 0; i < s->numberOfPoints(); i++) { + NR::Point const offset( p - s->getPoint(i).x ); + double ndot = NR::dot(offset, offset); + if ( ndot < bdot ) { + bdot = ndot; + } + } + + for (int i = 0; i < s->numberOfEdges(); i++) { + if ( s->getEdge(i).st >= 0 && s->getEdge(i).en >= 0 ) { + /* The edge has start and end points */ + NR::Point const st(s->getPoint(s->getEdge(i).st).x); // edge start + NR::Point const en(s->getPoint(s->getEdge(i).en).x); // edge end + + NR::Point const d(p - st); // vector between p and edge start + NR::Point const e(en - st); // vector of the edge + double const el = NR::dot(e, e); // edge length + + /* Update bdot if appropriate */ + if ( el > 0.001 ) { + double const npr = NR::dot(d, e); + if ( npr > 0 && npr < el ) { + double const nl = fabs( NR::cross(d, e) ); + double ndot = nl * nl / el; + if ( ndot < bdot ) { + bdot = ndot; + } + } + } + } + } + + return sqrt(bdot); +} + + + +/** + * Returns true iff the L2 distance from \a thePt to this shape is <= \a max_l2. + * Distance = the min of distance to its points and distance to its edges. + * Points without edges are considered, which is maybe unwanted... + * + * This is largely similar to distance(). + * + * \param s Shape. + * \param p Point. + * \param max_l2 L2 distance. + */ + +bool distanceLessThanOrEqual(Shape const *s, NR::Point const &p, double const max_l2) +{ + if ( s->hasPoints() == false ) { + return false; + } + + /* TODO: Consider using bbox to return early, perhaps conditional on nbPt or nbAr. */ + + /* TODO: Efficiency: In one test case (scribbling with the freehand tool to create a small number of long + ** path elements), changing from a Distance method to a DistanceLE method reduced this + ** function's CPU time from about 21% of total inkscape CPU time to 14-15% of total inkscape + ** CPU time, due to allowing early termination. I don't know how much the L1 test helps, it + ** may well be a case of premature optimization. Consider testing dot(offset, offset) + ** instead. + */ + + double const max_l1 = max_l2 * M_SQRT2; + for (int i = 0; i < s->numberOfPoints(); i++) { + NR::Point const offset( p - s->getPoint(i).x ); + double const l1 = NR::L1(offset); + if ( (l1 <= max_l2) || ((l1 <= max_l1) && (NR::L2(offset) <= max_l2)) ) { + return true; + } + } + + for (int i = 0; i < s->numberOfEdges(); i++) { + if ( s->getEdge(i).st >= 0 && s->getEdge(i).en >= 0 ) { + NR::Point const st(s->getPoint(s->getEdge(i).st).x); + NR::Point const en(s->getPoint(s->getEdge(i).en).x); + NR::Point const d(p - st); + NR::Point const e(en - st); + double const el = NR::L2(e); + if ( el > 0.001 ) { + NR::Point const e_unit(e / el); + double const npr = NR::dot(d, e_unit); + if ( npr > 0 && npr < el ) { + double const nl = fabs(NR::cross(d, e_unit)); + if ( nl <= max_l2 ) { + return true; + } + } + } + } + } + + return false; +} + +//}; + diff --git a/src/livarot/Shape.h b/src/livarot/Shape.h new file mode 100644 index 000000000..dad27e17b --- /dev/null +++ b/src/livarot/Shape.h @@ -0,0 +1,562 @@ +/* + * Digraph.h + * nlivarot + * + * Created by fred on Thu Jun 12 2003. + * + */ + +#ifndef my_shape +#define my_shape + +#include +#include +#include +#include +#include +#include + +#include "libnr/nr-point.h" +#include "livarot/livarot-forward.h" +#include "livarot/LivarotDefs.h" + +struct SweepTree; +struct SweepTreeList; +struct SweepEventQueue; + +/* + * the Shape class (was the Digraph class, as the header says) stores digraphs (no kidding!) of which + * a very interesting kind are polygons. + * the main use of this class is the ConvertToShape() (or Booleen(), quite the same) function, which + * removes all problems a polygon can present: duplicate points or edges, self-intersection. you end up with a + * full-fledged polygon + */ + +// possible values for the "type" field in the Shape class: +enum +{ + shape_graph = 0, // it's just a graph; a bunch of edges, maybe intersections + shape_polygon = 1, // a polygon: intersection-free, edges oriented so that the inside is on their left + shape_polypatch = 2 // a graph without intersection; each face is a polygon (not yet used) +}; + +class IntLigne; +class BitLigne; +class AlphaLigne; + +class Shape +{ +public: + + struct back_data + { + int pathID, pieceID; + double tSt, tEn; + }; + + struct voronoi_point + { // info for points treated as points of a voronoi diagram (obtained by MakeShape()) + double value; // distance to source + int winding; // winding relatively to source + }; + + struct voronoi_edge + { // info for edges, treated as approximation of edges of the voronoi diagram + int leF, riF; // left and right site + double leStX, leStY, riStX, riStY; // on the left side: (leStX,leStY) is the smallest vector from the source to st + // etc... + double leEnX, leEnY, riEnX, riEnY; + }; + + struct quick_raster_data + { + double x; // x-position on the sweepline + int bord; // index of the edge + int ind; // index of qrsData elem for edge (ie inverse of the bord) + int next,prev; // dbl linkage + }; + + enum sTreeChangeType + { + EDGE_INSERTED = 0, + EDGE_REMOVED = 1, + INTERSECTION = 2 + }; + + struct sTreeChange + { + sTreeChangeType type; // type of modification to the sweepline: + int ptNo; // point at which the modification takes place + + Shape *src; // left edge (or unique edge if not an intersection) involved in the event + int bord; + Shape *osrc; // right edge (if intersection) + int obord; + Shape *lSrc; // edge directly on the left in the sweepline at the moment of the event + int lBrd; + Shape *rSrc; // edge directly on the right + int rBrd; + }; + + struct incidenceData + { + int nextInc; // next incidence in the linked list + int pt; // point incident to the edge (there is one list per edge) + double theta; // coordinate of the incidence on the edge + }; + + Shape(); + ~Shape(); + + void MakeBackData(bool nVal); + void MakeVoronoiData(bool nVal); + + void Affiche(); + + // insertion/deletion/movement of elements in the graph + void Copy(Shape *a); + // -reset the graph, and ensure there's room for n points and m edges + void Reset(int n = 0, int m = 0); + // -points: + int AddPoint(const NR::Point x); // as the function name says + // returns the index at which the point has been added in the array + void SubPoint(int p); // removes the point at index p + // nota: this function relocates the last point to the index p + // so don't trust point indices if you use SubPoint + void SwapPoints(int a, int b); // swaps 2 points at indices a and b + void SwapPoints(int a, int b, int c); // swaps 3 points: c <- a <- b <- c + void SortPoints(); // sorts the points if needed (checks the need_points_sorting flag) + + // -edges: + // add an edge between points of indices st and en + int AddEdge(int st, int en); + // return the edge index in the array + + // add an edge between points of indices st and en + int AddEdge(int st, int en, int leF, int riF); + // return the edge index in the array + + // version for the voronoi (with faces IDs) + void SubEdge(int e); // removes the edge at index e (same remarks as for SubPoint) + void SwapEdges(int a, int b); // swaps 2 edges + void SwapEdges(int a, int b, int c); // swaps 3 edges + void SortEdges(); // sort the edges if needed (checks the need_edges_sorting falg) + + // primitives for topological manipulations + + // endpoint of edge at index b that is different from the point p + inline int Other(int p, int b) const + { + if (getEdge(b).st == p) { + return getEdge(b).en; + } + return getEdge(b).st; + } + + // next edge (after edge b) in the double-linked list at point p + inline int NextAt(int p, int b) const + { + if (p == getEdge(b).st) { + return getEdge(b).nextS; + } + else if (p == getEdge(b).en) { + return getEdge(b).nextE; + } + + return -1; + } + + // previous edge + inline int PrevAt(int p, int b) const + { + if (p == getEdge(b).st) { + return getEdge(b).prevS; + } + else if (p == getEdge(b).en) { + return getEdge(b).prevE; + } + + return -1; + } + + // same as NextAt, but the list is considered circular + inline int CycleNextAt(int p, int b) const + { + if (p == getEdge(b).st) { + if (getEdge(b).nextS < 0) { + return getPoint(p).incidentEdge[FIRST]; + } + return getEdge(b).nextS; + } else if (p == getEdge(b).en) { + if (getEdge(b).nextE < 0) { + return getPoint(p).incidentEdge[FIRST]; + } + + return getEdge(b).nextE; + } + + return -1; + } + + // same as PrevAt, but the list is considered circular + inline int CyclePrevAt(int p, int b) const + { + if (p == getEdge(b).st) { + if (getEdge(b).prevS < 0) { + return getPoint(p).incidentEdge[LAST]; + } + return getEdge(b).prevS; + } else if (p == getEdge(b).en) { + if (getEdge(b).prevE < 0) { + return getPoint(p).incidentEdge[LAST]; + } + return getEdge(b).prevE; + } + + return -1; + } + + void ConnectStart(int p, int b); // set the point p as the start of edge b + void ConnectEnd(int p, int b); // set the point p as the end of edge b + void DisconnectStart(int b); // disconnect edge b from its start point + void DisconnectEnd(int b); // disconnect edge b from its end point + + // reverses edge b (start <-> end) + void Inverse(int b); + // calc bounding box and sets leftX,rightX,topY and bottomY to their values + void CalcBBox(bool strict_degree = false); + + // debug function: plots the graph (mac only) + void Plot(double ix, double iy, double ir, double mx, double my, bool doPoint, + bool edgesNo, bool pointNo, bool doDir, char *fileName); + + // transforms a polygon in a "forme" structure, ie a set of contours, which can be holes (see ShapeUtils.h) + // return NULL in case it's not possible + void ConvertToForme(Path *dest); + + // version to use when conversion was done with ConvertWithBackData(): will attempt to merge segment belonging to + // the same curve + // nota: apparently the function doesn't like very small segments of arc + void ConvertToForme(Path *dest, int nbP, Path **orig, bool splitWhenForced = false); + // version trying to recover the nesting of subpaths (ie: holes) + void ConvertToFormeNested(Path *dest, int nbP, Path **orig, int wildPath, int &nbNest, + int *&nesting, int *&contStart, bool splitWhenForced = false); + + // sweeping a digraph to produce a intersection-free polygon + // return 0 if everything is ok and a return code otherwise (see LivarotDefs.h) + // the input is the Shape "a" + // directed=true <=> non-zero fill rule + int ConvertToShape(Shape *a, FillRule directed = fill_nonZero, bool invert = false); + // directed=false <=> even-odd fill rule + // invert=true: make as if you inverted all edges in the source + int Reoriente(Shape *a); // subcase of ConvertToShape: the input a is already intersection-free + // all that's missing are the correct directions of the edges + // Reoriented is equivalent to ConvertToShape(a,false,false) , but faster sicne + // it doesn't computes interections nor adjacencies + void ForceToPolygon(); // force the Shape to believe it's a polygon (eulerian+intersection-free+no + // duplicate edges+no duplicate points) + // be careful when using this function + + // the coordinate rounding function + inline static double Round(double x) + { + return ldexp(rint(ldexp(x, 5)), -5); + } + + // 2 miscannellous variations on it, to scale to and back the rounding grid + inline static double HalfRound(double x) + { + return ldexp(x, -5); + } + + inline static double IHalfRound(double x) + { + return ldexp(x, 5); + } + + // boolean operations on polygons (requests intersection-free poylygons) + // boolean operation types are defined in LivarotDefs.h + // same return code as ConvertToShape + int Booleen(Shape *a, Shape *b, BooleanOp mod, int cutPathID = -1); + + // create a graph that is an offseted version of the graph "of" + // the offset is dec, with joins between edges of type "join" (see LivarotDefs.h) + // the result is NOT a polygon; you need a subsequent call to ConvertToShape to get a real polygon + int MakeOffset(Shape *of, double dec, JoinType join, double miter); + + int PtWinding(const NR::Point px) const; // plus rapide + int Winding(const NR::Point px) const; + + // rasterization + void BeginRaster(float &pos, int &curPt); + void EndRaster(); + void BeginQuickRaster(float &pos, int &curPt); + void EndQuickRaster(); + + void Scan(float &pos, int &curP, float to, float step); + void QuickScan(float &pos, int &curP, float to, bool doSort, float step); + void DirectScan(float &pos, int &curP, float to, float step); + void DirectQuickScan(float &pos, int &curP, float to, bool doSort, float step); + + void Scan(float &pos, int &curP, float to, FloatLigne *line, bool exact, float step); + void Scan(float &pos, int &curP, float to, FillRule directed, BitLigne *line, bool exact, float step); + void Scan(float &pos, int &curP, float to, AlphaLigne *line, bool exact, float step); + + void QuickScan(float &pos, int &curP, float to, FloatLigne* line, float step); + void QuickScan(float &pos, int &curP, float to, FillRule directed, BitLigne* line, float step); + void QuickScan(float &pos, int &curP, float to, AlphaLigne* line, float step); + + void Transform(NR::Matrix const &tr) + {for(std::vector::iterator it=_pts.begin();it!=_pts.end();it++) it->x*=tr;} + + std::vector ebData; + std::vector vorpData; + std::vector voreData; + + int nbQRas; + int firstQRas; + int lastQRas; + std::vector qrsData; + + std::vector chgts; + int nbInc; + int maxInc; + + incidenceData *iData; + // these ones are allocated at the beginning of each sweep and freed at the end of the sweep + SweepTreeList *sTree; + SweepEventQueue *sEvts; + + // bounding box stuff + double leftX, topY, rightX, bottomY; + + // topological information: who links who? + struct dg_point + { + NR::Point x; // position + int dI, dO; // indegree and outdegree + int incidentEdge[2]; // first and last incident edge + int oldDegree; + + int totalDegree() const { return dI + dO; } + }; + + struct dg_arete + { + NR::Point dx; // edge vector + int st, en; // start and end points of the edge + int nextS, prevS; // next and previous edge in the double-linked list at the start point + int nextE, prevE; // next and previous edge in the double-linked list at the end point + }; + + // lists of the nodes and edges + int maxPt; // [FIXME: remove this] + int maxAr; // [FIXME: remove this] + + // flags + int type; + + inline int numberOfPoints() const { return _pts.size(); } + inline bool hasPoints() const { return (_pts.empty() == false); } + inline int numberOfEdges() const { return _aretes.size(); } + inline bool hasEdges() const { return (_aretes.empty() == false); } + + inline void needPointsSorting() { _need_points_sorting = true; } + inline void needEdgesSorting() { _need_edges_sorting = true; } + + inline bool hasBackData() const { return _has_back_data; } + + inline dg_point const &getPoint(int n) const { return _pts[n]; } + inline dg_arete const &getEdge(int n) const { return _aretes[n]; } + +private: + + friend class SweepTree; + friend class SweepEvent; + friend class SweepEventQueue; + + // temporary data for the various algorithms + struct edge_data + { + int weight; // weight of the edge (to handle multiple edges) + NR::Point rdx; // rounded edge vector + double length, sqlength, ilength, isqlength; // length^2, length, 1/length^2, 1/length + double siEd, coEd; // siEd=abs(rdy/length) and coEd=rdx/length + edge_data() : weight(0), length(0.0), sqlength(0.0), ilength(0.0), isqlength(0.0), siEd(0.0), coEd(0.0) {} + // used to determine the "most horizontal" edge between 2 edges + }; + + struct sweep_src_data + { + void *misc; // pointer to the SweepTree* in the sweepline + int firstLinkedPoint; // not used + int stPt, enPt; // start- end end- points for this edge in the resulting polygon + int ind; // for the GetAdjacencies function: index in the sliceSegs array (for quick deletions) + int leftRnd, rightRnd; // leftmost and rightmost points (in the result polygon) that are incident to + // the edge, for the current sweep position + // not set if the edge doesn't start/end or intersect at the current sweep position + Shape *nextSh; // nextSh and nextBo identify the next edge in the list + int nextBo; // they are used to maintain a linked list of edge that start/end or intersect at + // the current sweep position + int curPoint, doneTo; + double curT; + }; + + struct sweep_dest_data + { + void *misc; // used to check if an edge has already been seen during the depth-first search + int suivParc, precParc; // previous and current next edge in the depth-first search + int leW, riW; // left and right winding numbers for this edge + int ind; // order of the edges during the depth-first search + }; + + struct raster_data + { + SweepTree *misc; // pointer to the associated SweepTree* in the sweepline + double lastX, lastY, curX, curY; // curX;curY is the current intersection of the edge with the sweepline + // lastX;lastY is the intersection with the previous sweepline + bool sens; // true if the edge goes down, false otherwise + double calcX; // horizontal position of the intersection of the edge with the + // previous sweepline + double dxdy, dydx; // horizontal change per unit vertical move of the intersection with the sweepline + int guess; + }; + + struct point_data + { + int oldInd, newInd; // back and forth indices used when sorting the points, to know where they have + // been relocated in the array + int pending; // number of intersection attached to this edge, and also used when sorting arrays + int edgeOnLeft; // not used (should help speeding up winding calculations) + int nextLinkedPoint; // not used + Shape *askForWindingS; + int askForWindingB; + NR::Point rx; // rounded coordinates of the point + }; + + + struct edge_list + { // temporary array of edges for easier sorting + int no; + bool starting; + NR::Point x; + }; + + void initialisePointData(); + void initialiseEdgeData(); + void clearIncidenceData(); + + void _countUpDown(int P, int *numberUp, int *numberDown, int *upEdge, int *downEdge) const; + void _countUpDownTotalDegree2(int P, int *numberUp, int *numberDown, int *upEdge, int *downEdge) const; + void _updateIntersection(int e, int p); + + // activation/deactivation of the temporary data arrays + void MakePointData(bool nVal); + void MakeEdgeData(bool nVal); + void MakeSweepSrcData(bool nVal); + void MakeSweepDestData(bool nVal); + void MakeRasterData(bool nVal); + void MakeQuickRasterData(bool nVal); + + void SortPoints(int s, int e); + void SortPointsByOldInd(int s, int e); + + // fonctions annexes pour ConvertToShape et Booleen + void ResetSweep(); // allocates sweep structures + void CleanupSweep(); // deallocates them + + // edge sorting function + void SortEdgesList(edge_list *edges, int s, int e); + + void TesteIntersection(SweepTree *t, Side s, bool onlyDiff); // test if there is an intersection + bool TesteIntersection(SweepTree *iL, SweepTree *iR, NR::Point &atx, double &atL, double &atR, bool onlyDiff); + bool TesteIntersection(Shape *iL, Shape *iR, int ilb, int irb, + NR::Point &atx, double &atL, double &atR, + bool onlyDiff); + bool TesteAdjacency(Shape *iL, int ilb, const NR::Point atx, int nPt, + bool push); + int PushIncidence(Shape *a, int cb, int pt, double theta); + int CreateIncidence(Shape *a, int cb, int pt); + void AssemblePoints(Shape *a); + int AssemblePoints(int st, int en); + void AssembleAretes(FillRule directed = fill_nonZero); + void AddChgt(int lastPointNo, int lastChgtPt, Shape *&shapeHead, + int &edgeHead, sTreeChangeType type, Shape *lS, int lB, Shape *rS, + int rB); + void CheckAdjacencies(int lastPointNo, int lastChgtPt, Shape *shapeHead, int edgeHead); + void CheckEdges(int lastPointNo, int lastChgtPt, Shape *a, Shape *b, BooleanOp mod); + void Avance(int lastPointNo, int lastChgtPt, Shape *iS, int iB, Shape *a, Shape *b, BooleanOp mod); + void DoEdgeTo(Shape *iS, int iB, int iTo, bool direct, bool sens); + void GetWindings(Shape *a, Shape *b = NULL, BooleanOp mod = bool_op_union, bool brutal = false); + + void Validate(); + + int Winding(int nPt) const; + void SortPointsRounded(); + void SortPointsRounded(int s, int e); + + void CreateEdge(int no, float to, float step); + void AvanceEdge(int no, float to, bool exact, float step); + void DestroyEdge(int no, float to, FloatLigne *line); + void AvanceEdge(int no, float to, FloatLigne *line, bool exact, float step); + void DestroyEdge(int no, BitLigne *line); + void AvanceEdge(int no, float to, BitLigne *line, bool exact, float step); + void DestroyEdge(int no, AlphaLigne *line); + void AvanceEdge(int no, float to, AlphaLigne *line, bool exact, float step); + + void AddContour(Path * dest, int nbP, Path **orig, int startBord, + int curBord, bool splitWhenForced); + int ReFormeLineTo(int bord, int curBord, Path *dest, Path *orig); + int ReFormeArcTo(int bord, int curBord, Path *dest, Path *orig); + int ReFormeCubicTo(int bord, int curBord, Path *dest, Path *orig); + int ReFormeBezierTo(int bord, int curBord, Path *dest, Path *orig); + void ReFormeBezierChunk(const NR::Point px, const NR::Point nx, + Path *dest, int inBezier, int nbInterm, + Path *from, int p, double ts, double te); + + int QuickRasterChgEdge(int oBord, int nbord, double x); + int QuickRasterAddEdge(int bord, double x, int guess); + void QuickRasterSubEdge(int bord); + void QuickRasterSwapEdge(int a, int b); + void QuickRasterSort(); + + bool _need_points_sorting; ///< points have been added or removed: we need to sort the points again + bool _need_edges_sorting; ///< edges have been added: maybe they are not ordered clockwise + ///< nota: if you remove an edge, the clockwise order still holds + bool _has_points_data; ///< the pData array is allocated + bool _has_edges_data; ///< the eData array is allocated + bool _has_sweep_src_data; ///< the swsData array is allocated + bool _has_sweep_dest_data; ///< the swdData array is allocated + bool _has_raster_data; ///< the swrData array is allocated + bool _has_quick_raster_data;///< the swrData array is allocated + bool _has_back_data; //< the ebData array is allocated + bool _has_voronoi_data; + + std::vector _pts; + std::vector _aretes; + + // the arrays of temporary data + // these ones are dynamically kept at a length of maxPt or maxAr + std::vector eData; + std::vector swsData; + std::vector swdData; + std::vector swrData; + std::vector pData; + + static int CmpQRs(const quick_raster_data &p1, const quick_raster_data &p2) { + if ( fabs(p1.x - p2.x) < 0.00001 ) { + return 0; + } + + return ( ( p1.x < p2.x ) ? -1 : 1 ); + }; + + // edge direction comparison function + static int CmpToVert(const NR::Point ax, const NR::Point bx, bool as, bool bs); +}; + +bool directedEulerian(Shape const *s); +double distance(Shape const *s, NR::Point const &p); +bool distanceLessThanOrEqual(Shape const *s, NR::Point const &p, double const max_l2); + +#endif diff --git a/src/livarot/ShapeDraw.cpp b/src/livarot/ShapeDraw.cpp new file mode 100644 index 000000000..07e46afc7 --- /dev/null +++ b/src/livarot/ShapeDraw.cpp @@ -0,0 +1,103 @@ +/* + * ShapeDraw.cpp + * nlivarot + * + * Created by fred on Mon Jun 16 2003. + * + */ + +#include "Shape.h" +//#include + +// debug routine for vizualizing the polygons +void +Shape::Plot (double ix, double iy, double ir, double mx, double my, bool doPoint, + bool edgesNo, bool pointsNo, bool doDir,char* fileName) +{ + FILE* outFile=fopen(fileName,"w+"); +// fprintf(outFile,"\n\n\n"); + fprintf(outFile,"\n"); + fprintf(outFile,"\n"); + fprintf(outFile,"\n"); + fprintf(outFile," \n"); + fprintf(outFile," \n"); + + if ( doPoint ) { + for (int i=0;i\n",ph,pv); // localizing ok + } + } + if ( pointsNo ) { + for (int i=0;i\n",ph-2,pv+1); // localizing ok + fprintf(outFile,"%i\n",i); + fprintf(outFile," \n"); + } + } + { + for (int i=0;i\n",sh,sv,endh,endv); // localizing ok + } else { + fprintf(outFile," \n",sh,sv,eh,ev); // localizing ok + } + } + } + if ( edgesNo ) { + for (int i=0;i\n",(sh+eh)/2+2,(sv+ev)/2); // localizing ok + fprintf(outFile,"%i\n",i); + fprintf(outFile," \n"); + } + } + + fprintf(outFile,"\n"); + fclose(outFile); + +} diff --git a/src/livarot/ShapeMisc.cpp b/src/livarot/ShapeMisc.cpp new file mode 100644 index 000000000..d9bb665f0 --- /dev/null +++ b/src/livarot/ShapeMisc.cpp @@ -0,0 +1,1228 @@ +/* + * ShapeMisc.cpp + * nlivarot + * + * Created by fred on Sun Jul 20 2003. + * + */ + +#include "livarot/Shape.h" +#include +#include "livarot/Path.h" +#include "livarot/path-description.h" +#include + +/* + * polygon offset and polyline to path reassembling (when using back data) + */ + +// until i find something better +#define MiscNormalize(v) {\ + double _l=sqrt(dot(v,v)); \ + if ( _l < 0.0000001 ) { \ + v[0]=v[1]=0; \ + } else { \ + v/=_l; \ + }\ +} + +// extracting the contour of an uncrossed polygon: a mere depth first search +// more precisely that's extracting an eulerian path from a graph, but here we want to split +// the polygon into contours and avoid holes. so we take a "next counter-clockwise edge first" approach +// (make a checkboard and extract its contours to see the difference) +void +Shape::ConvertToForme (Path * dest) +{ + if (numberOfPoints() <= 1 || numberOfEdges() <= 1) + return; + if (directedEulerian(this) == false) + return; + + // prepare + dest->Reset (); + + MakePointData (true); + MakeEdgeData (true); + MakeSweepDestData (true); + + for (int i = 0; i < numberOfPoints(); i++) + { + pData[i].rx[0] = Round (getPoint(i).x[0]); + pData[i].rx[1] = Round (getPoint(i).x[1]); + } + for (int i = 0; i < numberOfEdges(); i++) + { + eData[i].rdx = pData[getEdge(i).en].rx - pData[getEdge(i).st].rx; + } + + // sort edge clockwise, with the closest after midnight being first in the doubly-linked list + // that's vital to the algorithm... + SortEdges (); + + // depth-first search implies: we make a stack of edges traversed. + // precParc: previous in the stack + // suivParc: next in the stack + for (int i = 0; i < numberOfEdges(); i++) + { + swdData[i].misc = 0; + swdData[i].precParc = swdData[i].suivParc = -1; + } + + int searchInd = 0; + + int lastPtUsed = 0; + do + { + // first get a starting point, and a starting edge + // -> take the upper left point, and take its first edge + // points traversed have swdData[].misc != 0, so it's easy + int startBord = -1; + { + int fi = 0; + for (fi = lastPtUsed; fi < numberOfPoints(); fi++) + { + if (getPoint(fi).incidentEdge[FIRST] >= 0 && swdData[getPoint(fi).incidentEdge[FIRST]].misc == 0) + break; + } + lastPtUsed = fi + 1; + if (fi < numberOfPoints()) + { + int bestB = getPoint(fi).incidentEdge[FIRST]; + while (bestB >= 0 && getEdge(bestB).st != fi) + bestB = NextAt (fi, bestB); + if (bestB >= 0) + { + startBord = bestB; + dest->MoveTo (getPoint(getEdge(startBord).en).x); + } + } + } + // and walk the graph, doing contours when needed + if (startBord >= 0) + { + // parcours en profondeur pour mettre les leF et riF a leurs valeurs + swdData[startBord].misc = (void *) 1; + // printf("part de %d\n",startBord); + int curBord = startBord; + bool back = false; + swdData[curBord].precParc = -1; + swdData[curBord].suivParc = -1; + do + { + int cPt = getEdge(curBord).en; + int nb = curBord; + // printf("de curBord= %d au point %i -> ",curBord,cPt); + // get next edge + do + { + int nnb = CycleNextAt (cPt, nb); + if (nnb == nb) + { + // cul-de-sac + nb = -1; + break; + } + nb = nnb; + if (nb < 0 || nb == curBord) + break; + } + while (swdData[nb].misc != 0 || getEdge(nb).st != cPt); + + if (nb < 0 || nb == curBord) + { + // no next edge: end of this contour, we get back + if (back == false) + dest->Close (); + back = true; + // retour en arriere + curBord = swdData[curBord].precParc; + // printf("retour vers %d\n",curBord); + if (curBord < 0) + break; + } + else + { + // new edge, maybe for a new contour + if (back) + { + // we were backtracking, so if we have a new edge, that means we're creating a new contour + dest->MoveTo (getPoint(cPt).x); + back = false; + } + swdData[nb].misc = (void *) 1; + swdData[nb].ind = searchInd++; + swdData[nb].precParc = curBord; + swdData[curBord].suivParc = nb; + curBord = nb; + // printf("suite %d\n",curBord); + { + // add that edge + dest->LineTo (getPoint(getEdge(nb).en).x); + } + } + } + while (1 /*swdData[curBord].precParc >= 0 */ ); + // fin du cas non-oriente + } + } + while (lastPtUsed < numberOfPoints()); + + MakePointData (false); + MakeEdgeData (false); + MakeSweepDestData (false); +} + +// same as before, but each time we have a contour, try to reassemble the segments on it to make chunks of +// the original(s) path(s) +// originals are in the orig array, whose size is nbP +void +Shape::ConvertToForme (Path * dest, int nbP, Path * *orig, bool splitWhenForced) +{ + if (numberOfPoints() <= 1 || numberOfEdges() <= 1) + return; +// if (Eulerian (true) == false) +// return; + + if (_has_back_data == false) + { + ConvertToForme (dest); + return; + } + + dest->Reset (); + + MakePointData (true); + MakeEdgeData (true); + MakeSweepDestData (true); + + for (int i = 0; i < numberOfPoints(); i++) + { + pData[i].rx[0] = Round (getPoint(i).x[0]); + pData[i].rx[1] = Round (getPoint(i).x[1]); + } + for (int i = 0; i < numberOfEdges(); i++) + { + eData[i].rdx = pData[getEdge(i).en].rx - pData[getEdge(i).st].rx; + } + + SortEdges (); + + for (int i = 0; i < numberOfEdges(); i++) + { + swdData[i].misc = 0; + swdData[i].precParc = swdData[i].suivParc = -1; + } + + int searchInd = 0; + + int lastPtUsed = 0; + do + { + int startBord = -1; + { + int fi = 0; + for (fi = lastPtUsed; fi < numberOfPoints(); fi++) + { + if (getPoint(fi).incidentEdge[FIRST] >= 0 && swdData[getPoint(fi).incidentEdge[FIRST]].misc == 0) + break; + } + lastPtUsed = fi + 1; + if (fi < numberOfPoints()) + { + int bestB = getPoint(fi).incidentEdge[FIRST]; + while (bestB >= 0 && getEdge(bestB).st != fi) + bestB = NextAt (fi, bestB); + if (bestB >= 0) + { + startBord = bestB; + } + } + } + if (startBord >= 0) + { + // parcours en profondeur pour mettre les leF et riF a leurs valeurs + swdData[startBord].misc = (void *) 1; + //printf("part de %d\n",startBord); + int curBord = startBord; + bool back = false; + swdData[curBord].precParc = -1; + swdData[curBord].suivParc = -1; + int curStartPt=getEdge(curBord).st; + do + { + int cPt = getEdge(curBord).en; + int nb = curBord; + //printf("de curBord= %d au point %i -> ",curBord,cPt); + do + { + int nnb = CycleNextAt (cPt, nb); + if (nnb == nb) + { + // cul-de-sac + nb = -1; + break; + } + nb = nnb; + if (nb < 0 || nb == curBord) + break; + } + while (swdData[nb].misc != 0 || getEdge(nb).st != cPt); + + if (nb < 0 || nb == curBord) + { + if (back == false) + { + if (curBord == startBord || curBord < 0) + { + // probleme -> on vire le moveto + // dest->descr_nb--; + } + else + { + swdData[curBord].suivParc = -1; + AddContour (dest, nbP, orig, startBord, curBord,splitWhenForced); + } + // dest->Close(); + } + back = true; + // retour en arriere + curBord = swdData[curBord].precParc; + //printf("retour vers %d\n",curBord); + if (curBord < 0) + break; + } + else + { + if (back) + { + back = false; + startBord = nb; + curStartPt=getEdge(nb).st; + } else { + if ( getEdge(curBord).en == curStartPt ) { + //printf("contour %i ",curStartPt); + swdData[curBord].suivParc = -1; + AddContour (dest, nbP, orig, startBord, curBord,splitWhenForced); + startBord=nb; + } + } + swdData[nb].misc = (void *) 1; + swdData[nb].ind = searchInd++; + swdData[nb].precParc = curBord; + swdData[curBord].suivParc = nb; + curBord = nb; + //printf("suite %d\n",curBord); + } + } + while (1 /*swdData[curBord].precParc >= 0 */ ); + // fin du cas non-oriente + } + } + while (lastPtUsed < numberOfPoints()); + + MakePointData (false); + MakeEdgeData (false); + MakeSweepDestData (false); +} +void +Shape::ConvertToFormeNested (Path * dest, int nbP, Path * *orig, int wildPath,int &nbNest,int *&nesting,int *&contStart,bool splitWhenForced) +{ + nesting=NULL; + contStart=NULL; + nbNest=0; + + if (numberOfPoints() <= 1 || numberOfEdges() <= 1) + return; + // if (Eulerian (true) == false) + // return; + + if (_has_back_data == false) + { + ConvertToForme (dest); + return; + } + + dest->Reset (); + +// MakePointData (true); + MakeEdgeData (true); + MakeSweepDestData (true); + + for (int i = 0; i < numberOfPoints(); i++) + { + pData[i].rx[0] = Round (getPoint(i).x[0]); + pData[i].rx[1] = Round (getPoint(i).x[1]); + } + for (int i = 0; i < numberOfEdges(); i++) + { + eData[i].rdx = pData[getEdge(i).en].rx - pData[getEdge(i).st].rx; + } + + SortEdges (); + + for (int i = 0; i < numberOfEdges(); i++) + { + swdData[i].misc = 0; + swdData[i].precParc = swdData[i].suivParc = -1; + } + + int searchInd = 0; + + int lastPtUsed = 0; + do + { + int dadContour=-1; + int startBord = -1; + { + int fi = 0; + for (fi = lastPtUsed; fi < numberOfPoints(); fi++) + { + if (getPoint(fi).incidentEdge[FIRST] >= 0 && swdData[getPoint(fi).incidentEdge[FIRST]].misc == 0) + break; + } + { + int askTo = pData[fi].askForWindingB; + if (askTo < 0 || askTo >= numberOfEdges() ) { + dadContour=-1; + } else { + dadContour = GPOINTER_TO_INT(swdData[askTo].misc); + dadContour-=1; // pour compenser le decalage + } + } + lastPtUsed = fi + 1; + if (fi < numberOfPoints()) + { + int bestB = getPoint(fi).incidentEdge[FIRST]; + while (bestB >= 0 && getEdge(bestB).st != fi) + bestB = NextAt (fi, bestB); + if (bestB >= 0) + { + startBord = bestB; + } + } + } + if (startBord >= 0) + { + // parcours en profondeur pour mettre les leF et riF a leurs valeurs + swdData[startBord].misc = (void *) (1+nbNest); + //printf("part de %d\n",startBord); + int curBord = startBord; + bool back = false; + swdData[curBord].precParc = -1; + swdData[curBord].suivParc = -1; + int curStartPt=getEdge(curBord).st; + do + { + int cPt = getEdge(curBord).en; + int nb = curBord; + //printf("de curBord= %d au point %i -> ",curBord,cPt); + do + { + int nnb = CycleNextAt (cPt, nb); + if (nnb == nb) + { + // cul-de-sac + nb = -1; + break; + } + nb = nnb; + if (nb < 0 || nb == curBord) + break; + } + while (swdData[nb].misc != 0 || getEdge(nb).st != cPt); + + if (nb < 0 || nb == curBord) + { + if (back == false) + { + if (curBord == startBord || curBord < 0) + { + // probleme -> on vire le moveto + // dest->descr_nb--; + } + else + { + bool escapePath=false; + int tb=curBord; + while ( tb >= 0 && tb < numberOfEdges() ) { + if ( ebData[tb].pathID == wildPath ) { + escapePath=true; + break; + } + tb=swdData[tb].precParc; + } + nesting=(int*)g_realloc(nesting,(nbNest+1)*sizeof(int)); + contStart=(int*)g_realloc(contStart,(nbNest+1)*sizeof(int)); + contStart[nbNest]=dest->descr_cmd.size(); + if ( escapePath ) { + nesting[nbNest++]=-1; // contient des bouts de coupure -> a part + } else { + nesting[nbNest++]=dadContour; + } + swdData[curBord].suivParc = -1; + AddContour (dest, nbP, orig, startBord, curBord,splitWhenForced); + } + // dest->Close(); + } + back = true; + // retour en arriere + curBord = swdData[curBord].precParc; + //printf("retour vers %d\n",curBord); + if (curBord < 0) + break; + } + else + { + if (back) + { + back = false; + startBord = nb; + curStartPt=getEdge(nb).st; + } else { + if ( getEdge(curBord).en == curStartPt ) { + //printf("contour %i ",curStartPt); + + bool escapePath=false; + int tb=curBord; + while ( tb >= 0 && tb < numberOfEdges() ) { + if ( ebData[tb].pathID == wildPath ) { + escapePath=true; + break; + } + tb=swdData[tb].precParc; + } + nesting=(int*)g_realloc(nesting,(nbNest+1)*sizeof(int)); + contStart=(int*)g_realloc(contStart,(nbNest+1)*sizeof(int)); + contStart[nbNest]=dest->descr_cmd.size(); + if ( escapePath ) { + nesting[nbNest++]=-1; // contient des bouts de coupure -> a part + } else { + nesting[nbNest++]=dadContour; + } + + swdData[curBord].suivParc = -1; + AddContour (dest, nbP, orig, startBord, curBord,splitWhenForced); + startBord=nb; + } + } + swdData[nb].misc = (void *) (1+nbNest); + swdData[nb].ind = searchInd++; + swdData[nb].precParc = curBord; + swdData[curBord].suivParc = nb; + curBord = nb; + //printf("suite %d\n",curBord); + } + } + while (1 /*swdData[curBord].precParc >= 0 */ ); + // fin du cas non-oriente + } + } + while (lastPtUsed < numberOfPoints()); + + MakePointData (false); + MakeEdgeData (false); + MakeSweepDestData (false); +} + +// offsets +// take each edge, offset it, and make joins with previous at edge start and next at edge end (previous and +// next being with respect to the clockwise order) +// you gotta be very careful with the join, has anything but the right one will fuck everything up +// see PathStroke.cpp for the "right" joins +int +Shape::MakeOffset (Shape * a, double dec, JoinType join, double miter) +{ + Reset (0, 0); + MakeBackData(a->_has_back_data); + + if (dec == 0) + { + _pts = a->_pts; + if (numberOfPoints() > maxPt) + { + maxPt = numberOfPoints(); + if (_has_points_data) + pData.resize(maxPt); + } + + _aretes = a->_aretes; + if (numberOfEdges() > maxAr) + { + maxAr = numberOfEdges(); + if (_has_edges_data) + eData.resize(maxAr); + if (_has_sweep_src_data) + swsData.resize(maxAr); + if (_has_sweep_dest_data) + swdData.resize(maxAr); + if (_has_raster_data) + swrData.resize(maxAr); + if (_has_back_data) + ebData.resize(maxAr); + } + return 0; + } + if (a->numberOfPoints() <= 1 || a->numberOfEdges() <= 1 || a->type != shape_polygon) + return shape_input_err; + + a->SortEdges (); + + a->MakeSweepDestData (true); + a->MakeSweepSrcData (true); + + for (int i = 0; i < a->numberOfEdges(); i++) + { + // int stP=a->swsData[i].stPt/*,enP=a->swsData[i].enPt*/; + int stB = -1, enB = -1; + if (dec > 0) + { + stB = a->CycleNextAt (a->getEdge(i).st, i); + enB = a->CyclePrevAt (a->getEdge(i).en, i); + } + else + { + stB = a->CyclePrevAt (a->getEdge(i).st, i); + enB = a->CycleNextAt (a->getEdge(i).en, i); + } + + NR::Point stD, seD, enD; + double stL, seL, enL; + stD = a->getEdge(stB).dx; + seD = a->getEdge(i).dx; + enD = a->getEdge(enB).dx; + + stL = sqrt (dot(stD,stD)); + seL = sqrt (dot(seD,seD)); + enL = sqrt (dot(enD,enD)); + MiscNormalize (stD); + MiscNormalize (enD); + MiscNormalize (seD); + + NR::Point ptP; + int stNo, enNo; + ptP = a->getPoint(a->getEdge(i).st).x; + int usePathID=-1; + int usePieceID=0; + double useT=0.0; + if ( a->_has_back_data ) { + if ( a->ebData[i].pathID >= 0 && a->ebData[stB].pathID == a->ebData[i].pathID && a->ebData[stB].pieceID == a->ebData[i].pieceID + && a->ebData[stB].tEn == a->ebData[i].tSt ) { + usePathID=a->ebData[i].pathID; + usePieceID=a->ebData[i].pieceID; + useT=a->ebData[i].tSt; + } else { + usePathID=a->ebData[i].pathID; + usePieceID=0; + useT=0; + } + } + if (dec > 0) + { + Path::DoRightJoin (this, dec, join, ptP, stD, seD, miter, stL, seL, + stNo, enNo,usePathID,usePieceID,useT); + a->swsData[i].stPt = enNo; + a->swsData[stB].enPt = stNo; + } + else + { + Path::DoLeftJoin (this, -dec, join, ptP, stD, seD, miter, stL, seL, + stNo, enNo,usePathID,usePieceID,useT); + a->swsData[i].stPt = enNo; + a->swsData[stB].enPt = stNo; + } + } + if (dec < 0) + { + for (int i = 0; i < numberOfEdges(); i++) + Inverse (i); + } + if ( _has_back_data ) { + for (int i = 0; i < a->numberOfEdges(); i++) + { + int nEd=AddEdge (a->swsData[i].stPt, a->swsData[i].enPt); + ebData[nEd]=a->ebData[i]; + } + } else { + for (int i = 0; i < a->numberOfEdges(); i++) + { + AddEdge (a->swsData[i].stPt, a->swsData[i].enPt); + } + } + a->MakeSweepSrcData (false); + a->MakeSweepDestData (false); + + return 0; +} + +// we found a contour, now reassemble the edges on it, instead of dumping them in the Path "dest" as a +// polyline. since it was a DFS, the precParc and suivParc make a nice doubly-linked list of the edges in +// the contour. the first and last edges of the contour are startBord and curBord +void +Shape::AddContour (Path * dest, int nbP, Path * *orig, int startBord, int curBord, bool splitWhenForced) +{ + int bord = startBord; + + { + dest->MoveTo (getPoint(getEdge(bord).st).x); + } + + while (bord >= 0) + { + int nPiece = ebData[bord].pieceID; + int nPath = ebData[bord].pathID; + + if (nPath < 0 || nPath >= nbP || orig[nPath] == NULL) + { + // segment batard + dest->LineTo (getPoint(getEdge(bord).en).x); + bord = swdData[bord].suivParc; + } + else + { + Path *from = orig[nPath]; + if (nPiece < 0 || nPiece >= int(from->descr_cmd.size())) + { + // segment batard + dest->LineTo (getPoint(getEdge(bord).en).x); + bord = swdData[bord].suivParc; + } + else + { + int nType = from->descr_cmd[nPiece]->getType(); + if (nType == descr_close || nType == descr_moveto + || nType == descr_forced) + { + // devrait pas arriver + dest->LineTo (getPoint(getEdge(bord).en).x); + bord = swdData[bord].suivParc; + } + else if (nType == descr_lineto) + { + bord = ReFormeLineTo (bord, curBord, dest, from); + } + else if (nType == descr_arcto) + { + bord = ReFormeArcTo (bord, curBord, dest, from); + } + else if (nType == descr_cubicto) + { + bord = ReFormeCubicTo (bord, curBord, dest, from); + } + else if (nType == descr_bezierto) + { + PathDescrBezierTo* nBData = + dynamic_cast(from->descr_cmd[nPiece]); + + if (nBData->nb == 0) + { + bord = ReFormeLineTo (bord, curBord, dest, from); + } + else + { + bord = ReFormeBezierTo (bord, curBord, dest, from); + } + } + else if (nType == descr_interm_bezier) + { + bord = ReFormeBezierTo (bord, curBord, dest, from); + } + else + { + // devrait pas arriver non plus + dest->LineTo (getPoint(getEdge(bord).en).x); + bord = swdData[bord].suivParc; + } + if (bord >= 0 && getPoint(getEdge(bord).st).totalDegree() > 2 ) { + dest->ForcePoint (); + } else if ( bord >= 0 && getPoint(getEdge(bord).st).oldDegree > 2 && getPoint(getEdge(bord).st).totalDegree() == 2) { + if ( splitWhenForced ) { + // pour les coupures + dest->ForcePoint (); + } else { + if ( _has_back_data ) { + int prevEdge=getPoint(getEdge(bord).st).incidentEdge[FIRST]; + int nextEdge=getPoint(getEdge(bord).st).incidentEdge[LAST]; + if ( getEdge(prevEdge).en != getEdge(bord).st ) { + int swai=prevEdge;prevEdge=nextEdge;nextEdge=swai; + } + if ( ebData[prevEdge].pieceID == ebData[nextEdge].pieceID && ebData[prevEdge].pathID == ebData[nextEdge].pathID ) { + if ( fabs(ebData[prevEdge].tEn-ebData[nextEdge].tSt) < 0.05 ) { + } else { + dest->ForcePoint (); + } + } else { + dest->ForcePoint (); + } + } else { + dest->ForcePoint (); + } + } + } + } + } + } + dest->Close (); +} + +int +Shape::ReFormeLineTo (int bord, int curBord, Path * dest, Path * orig) +{ + int nPiece = ebData[bord].pieceID; + int nPath = ebData[bord].pathID; + double /*ts=ebData[bord].tSt, */ te = ebData[bord].tEn; + NR::Point nx = getPoint(getEdge(bord).en).x; + bord = swdData[bord].suivParc; + while (bord >= 0) + { + if (getPoint(getEdge(bord).st).totalDegree() > 2 + || getPoint(getEdge(bord).st).oldDegree > 2) + { + break; + } + if (ebData[bord].pieceID == nPiece && ebData[bord].pathID == nPath) + { + if (fabs (te - ebData[bord].tSt) > 0.0001) + break; + nx = getPoint(getEdge(bord).en).x; + te = ebData[bord].tEn; + } + else + { + break; + } + bord = swdData[bord].suivParc; + } + { + dest->LineTo (nx); + } + return bord; +} + +int +Shape::ReFormeArcTo (int bord, int curBord, Path * dest, Path * from) +{ + int nPiece = ebData[bord].pieceID; + int nPath = ebData[bord].pathID; + double ts = ebData[bord].tSt, te = ebData[bord].tEn; + // double px=pts[getEdge(bord).st].x,py=pts[getEdge(bord).st].y; + NR::Point nx = getPoint(getEdge(bord).en).x; + bord = swdData[bord].suivParc; + while (bord >= 0) + { + if (getPoint(getEdge(bord).st).totalDegree() > 2 + || getPoint(getEdge(bord).st).oldDegree > 2) + { + break; + } + if (ebData[bord].pieceID == nPiece && ebData[bord].pathID == nPath) + { + if (fabs (te - ebData[bord].tSt) > 0.0001) + { + break; + } + nx = getPoint(getEdge(bord).en).x; + te = ebData[bord].tEn; + } + else + { + break; + } + bord = swdData[bord].suivParc; + } + double sang, eang; + PathDescrArcTo* nData = dynamic_cast(from->descr_cmd[nPiece]); + bool nLarge = nData->large; + bool nClockwise = nData->clockwise; + Path::ArcAngles (from->PrevPoint (nPiece - 1), nData->p,nData->rx,nData->ry,nData->angle, nLarge, nClockwise, sang, eang); + if (nClockwise) + { + if (sang < eang) + sang += 2 * M_PI; + } + else + { + if (sang > eang) + sang -= 2 * M_PI; + } + double delta = eang - sang; + double ndelta = delta * (te - ts); + if (ts > te) + nClockwise = !nClockwise; + if (ndelta < 0) + ndelta = -ndelta; + if (ndelta > M_PI) + nLarge = true; + else + nLarge = false; + /* if ( delta < 0 ) delta=-delta; + if ( ndelta < 0 ) ndelta=-ndelta; + if ( ( delta < M_PI && ndelta < M_PI ) || ( delta >= M_PI && ndelta >= M_PI ) ) { + if ( ts < te ) { + } else { + nClockwise=!(nClockwise); + } + } else { + // nLarge=!(nLarge); + nLarge=false; // c'est un sous-segment -> l'arc ne peut que etre plus petit + if ( ts < te ) { + } else { + nClockwise=!(nClockwise); + } + }*/ + { + PathDescrArcTo *nData = dynamic_cast(from->descr_cmd[nPiece]); + dest->ArcTo (nx, nData->rx,nData->ry,nData->angle, nLarge, nClockwise); + } + return bord; +} + +int +Shape::ReFormeCubicTo (int bord, int curBord, Path * dest, Path * from) +{ + int nPiece = ebData[bord].pieceID; + int nPath = ebData[bord].pathID; + double ts = ebData[bord].tSt, te = ebData[bord].tEn; + NR::Point nx = getPoint(getEdge(bord).en).x; + bord = swdData[bord].suivParc; + while (bord >= 0) + { + if (getPoint(getEdge(bord).st).totalDegree() > 2 + || getPoint(getEdge(bord).st).oldDegree > 2) + { + break; + } + if (ebData[bord].pieceID == nPiece && ebData[bord].pathID == nPath) + { + if (fabs (te - ebData[bord].tSt) > 0.0001) + { + break; + } + nx = getPoint(getEdge(bord).en).x; + te = ebData[bord].tEn; + } + else + { + break; + } + bord = swdData[bord].suivParc; + } + NR::Point prevx = from->PrevPoint (nPiece - 1); + + NR::Point sDx, eDx; + { + PathDescrCubicTo *nData = dynamic_cast(from->descr_cmd[nPiece]); + Path::CubicTangent (ts, sDx, prevx,nData->start,nData->p,nData->end); + Path::CubicTangent (te, eDx, prevx,nData->start,nData->p,nData->end); + } + sDx *= (te - ts); + eDx *= (te - ts); + { + dest->CubicTo (nx,sDx,eDx); + } + return bord; +} + +int +Shape::ReFormeBezierTo (int bord, int curBord, Path * dest, Path * from) +{ + int nPiece = ebData[bord].pieceID; + int nPath = ebData[bord].pathID; + double ts = ebData[bord].tSt, te = ebData[bord].tEn; + int ps = nPiece, pe = nPiece; + NR::Point px = getPoint(getEdge(bord).st).x; + NR::Point nx = getPoint(getEdge(bord).en).x; + int inBezier = -1, nbInterm = -1; + int typ; + typ = from->descr_cmd[nPiece]->getType(); + PathDescrBezierTo *nBData = NULL; + if (typ == descr_bezierto) + { + nBData = dynamic_cast(from->descr_cmd[nPiece]); + inBezier = nPiece; + nbInterm = nBData->nb; + } + else + { + int n = nPiece - 1; + while (n > 0) + { + typ = from->descr_cmd[n]->getType(); + if (typ == descr_bezierto) + { + inBezier = n; + nBData = dynamic_cast(from->descr_cmd[n]); + nbInterm = nBData->nb; + break; + } + n--; + } + if (inBezier < 0) + { + bord = swdData[bord].suivParc; + dest->LineTo (nx); + return bord; + } + } + bord = swdData[bord].suivParc; + while (bord >= 0) + { + if (getPoint(getEdge(bord).st).totalDegree() > 2 + || getPoint(getEdge(bord).st).oldDegree > 2) + { + break; + } + if (ebData[bord].pathID == nPath) + { + if (ebData[bord].pieceID < inBezier + || ebData[bord].pieceID >= inBezier + nbInterm) + break; + if (ebData[bord].pieceID == pe + && fabs (te - ebData[bord].tSt) > 0.0001) + break; + if (ebData[bord].pieceID != pe + && (ebData[bord].tSt > 0.0001 && ebData[bord].tSt < 0.9999)) + break; + if (ebData[bord].pieceID != pe && (te > 0.0001 && te < 0.9999)) + break; + nx = getPoint(getEdge(bord).en).x; + te = ebData[bord].tEn; + pe = ebData[bord].pieceID; + } + else + { + break; + } + bord = swdData[bord].suivParc; + } + + g_return_val_if_fail(nBData != NULL, 0); + + if (pe == ps) + { + ReFormeBezierChunk (px, nx, dest, inBezier, nbInterm, from, ps, + ts, te); + } + else if (ps < pe) + { + if (ts < 0.0001) + { + if (te > 0.9999) + { + dest->BezierTo (nx); + for (int i = ps; i <= pe; i++) + { + PathDescrIntermBezierTo *nData = dynamic_cast(from->descr_cmd[i+1]); + dest->IntermBezierTo (nData->p); + } + dest->EndBezierTo (); + } + else + { + NR::Point tx; + { + PathDescrIntermBezierTo* psData = dynamic_cast(from->descr_cmd[pe]); + PathDescrIntermBezierTo* pnData = dynamic_cast(from->descr_cmd[pe+1]); + tx = (pnData->p + psData->p) / 2; + } + dest->BezierTo (tx); + for (int i = ps; i < pe; i++) + { + PathDescrIntermBezierTo* nData = dynamic_cast(from->descr_cmd[i+1]); + dest->IntermBezierTo (nData->p); + } + dest->EndBezierTo (); + ReFormeBezierChunk (tx, nx, dest, inBezier, nbInterm, + from, pe, 0.0, te); + } + } + else + { + if (te > 0.9999) + { + NR::Point tx; + { + PathDescrIntermBezierTo* psData = dynamic_cast(from->descr_cmd[ps+1]); + PathDescrIntermBezierTo* pnData = dynamic_cast(from->descr_cmd[ps+2]); + tx = (psData->p + pnData->p) / 2; + } + ReFormeBezierChunk (px, tx, dest, inBezier, nbInterm, + from, ps, ts, 1.0); + dest->BezierTo (nx); + for (int i = ps + 1; i <= pe; i++) + { + PathDescrIntermBezierTo *nData = dynamic_cast(from->descr_cmd[i+1]); + dest->IntermBezierTo (nData->p); + } + dest->EndBezierTo (); + } + else + { + NR::Point tx; + { + PathDescrIntermBezierTo* psData = dynamic_cast(from->descr_cmd[ps+1]); + PathDescrIntermBezierTo* pnData = dynamic_cast(from->descr_cmd[ps+2]); + tx = (pnData->p + psData->p) / 2; + } + ReFormeBezierChunk (px, tx, dest, inBezier, nbInterm, + from, ps, ts, 1.0); + { + PathDescrIntermBezierTo* psData = dynamic_cast(from->descr_cmd[pe]); + PathDescrIntermBezierTo* pnData = dynamic_cast(from->descr_cmd[pe+1]); + tx = (pnData->p + psData->p) / 2; + } + dest->BezierTo (tx); + for (int i = ps + 1; i <= pe; i++) + { + PathDescrIntermBezierTo* nData = dynamic_cast(from->descr_cmd[i+1]); + dest->IntermBezierTo (nData->p); + } + dest->EndBezierTo (); + ReFormeBezierChunk (tx, nx, dest, inBezier, nbInterm, + from, pe, 0.0, te); + } + } + } + else + { + if (ts > 0.9999) + { + if (te < 0.0001) + { + dest->BezierTo (nx); + for (int i = ps; i >= pe; i--) + { + PathDescrIntermBezierTo* nData = dynamic_cast(from->descr_cmd[i+1]); + dest->IntermBezierTo (nData->p); + } + dest->EndBezierTo (); + } + else + { + NR::Point tx; + { + PathDescrIntermBezierTo* psData = dynamic_cast(from->descr_cmd[pe+1]); + PathDescrIntermBezierTo* pnData = dynamic_cast(from->descr_cmd[pe+2]); + tx = (pnData->p + psData->p) / 2; + } + dest->BezierTo (tx); + for (int i = ps; i > pe; i--) + { + PathDescrIntermBezierTo* nData = dynamic_cast(from->descr_cmd[i+1]); + dest->IntermBezierTo (nData->p); + } + dest->EndBezierTo (); + ReFormeBezierChunk (tx, nx, dest, inBezier, nbInterm, + from, pe, 1.0, te); + } + } + else + { + if (te < 0.0001) + { + NR::Point tx; + { + PathDescrIntermBezierTo* psData = dynamic_cast(from->descr_cmd[ps]); + PathDescrIntermBezierTo* pnData = dynamic_cast(from->descr_cmd[ps+1]); + tx = (pnData->p + psData->p) / 2; + } + ReFormeBezierChunk (px, tx, dest, inBezier, nbInterm, + from, ps, ts, 0.0); + dest->BezierTo (nx); + for (int i = ps + 1; i >= pe; i--) + { + PathDescrIntermBezierTo* nData = dynamic_cast(from->descr_cmd[i]); + dest->IntermBezierTo (nData->p); + } + dest->EndBezierTo (); + } + else + { + NR::Point tx; + { + PathDescrIntermBezierTo* psData = dynamic_cast(from->descr_cmd[ps]); + PathDescrIntermBezierTo* pnData = dynamic_cast(from->descr_cmd[ps+1]); + tx = (pnData->p + psData->p) / 2; + } + ReFormeBezierChunk (px, tx, dest, inBezier, nbInterm, + from, ps, ts, 0.0); + { + PathDescrIntermBezierTo* psData = dynamic_cast(from->descr_cmd[pe+1]); + PathDescrIntermBezierTo* pnData = dynamic_cast(from->descr_cmd[pe+2]); + tx = (pnData->p + psData->p) / 2; + } + dest->BezierTo (tx); + for (int i = ps + 1; i > pe; i--) + { + PathDescrIntermBezierTo* nData = dynamic_cast(from->descr_cmd[i]); + dest->IntermBezierTo (nData->p); + } + dest->EndBezierTo (); + ReFormeBezierChunk (tx, nx, dest, inBezier, nbInterm, + from, pe, 1.0, te); + } + } + } + return bord; +} + +void +Shape::ReFormeBezierChunk (NR::Point px, NR::Point nx, + Path * dest, int inBezier, int nbInterm, + Path * from, int p, double ts, double te) +{ + PathDescrBezierTo* nBData = dynamic_cast(from->descr_cmd[inBezier]); + NR::Point bstx = from->PrevPoint (inBezier - 1); + NR::Point benx = nBData->p; + + NR::Point mx; + if (p == inBezier) + { + // premier bout + if (nbInterm <= 1) + { + // seul bout de la spline + PathDescrIntermBezierTo *nData = dynamic_cast(from->descr_cmd[inBezier+1]); + mx = nData->p; + } + else + { + // premier bout d'une spline qui en contient plusieurs + PathDescrIntermBezierTo *nData = dynamic_cast(from->descr_cmd[inBezier+1]); + mx = nData->p; + nData = dynamic_cast(from->descr_cmd[inBezier+2]); + benx = (nData->p + mx) / 2; + } + } + else if (p == inBezier + nbInterm - 1) + { + // dernier bout + // si nbInterm == 1, le cas a deja ete traite + // donc dernier bout d'une spline qui en contient plusieurs + PathDescrIntermBezierTo* nData = dynamic_cast(from->descr_cmd[inBezier+nbInterm]); + mx = nData->p; + nData = dynamic_cast(from->descr_cmd[inBezier+nbInterm-1]); + bstx = (nData->p + mx) / 2; + } + else + { + // la spline contient forcément plusieurs bouts, et ce n'est ni le premier ni le dernier + PathDescrIntermBezierTo *nData = dynamic_cast(from->descr_cmd[p+1]); + mx = nData->p; + nData = dynamic_cast(from->descr_cmd[p]); + bstx = (nData->p + mx) / 2; + nData = dynamic_cast(from->descr_cmd[p+2]); + benx = (nData->p + mx) / 2; + } + NR::Point cx; + { + Path::QuadraticPoint ((ts + te) / 2, cx, bstx, mx, benx); + } + cx = 2 * cx - (px + nx) / 2; + { + dest->BezierTo (nx); + dest->IntermBezierTo (cx); + dest->EndBezierTo (); + } +} + +#undef MiscNormalize diff --git a/src/livarot/ShapeRaster.cpp b/src/livarot/ShapeRaster.cpp new file mode 100644 index 000000000..4e762396e --- /dev/null +++ b/src/livarot/ShapeRaster.cpp @@ -0,0 +1,2009 @@ +/* + * ShapeRaster.cpp + * nlivarot + * + * Created by fred on Sat Jul 19 2003. + * + */ + +#include "Shape.h" + +#include "livarot/float-line.h" +#include "AlphaLigne.h" +#include "BitLigne.h" + +#include +#include "livarot/sweep-event-queue.h" +#include "livarot/sweep-tree-list.h" +#include "livarot/sweep-tree.h" + +/* + * polygon rasterization: the sweepline algorithm in all its glory + * nothing unusual in this implementation, so nothing special to say + * the *Quick*() functions are not useful. forget about them + */ + +void Shape::BeginRaster(float &pos, int &curPt) +{ + if ( numberOfPoints() <= 1 || numberOfEdges() <= 1 ) { + curPt = 0; + pos = 0; + return; + } + + MakeRasterData(true); + MakePointData(true); + MakeEdgeData(true); + + if (sTree == NULL) { + sTree = new SweepTreeList(numberOfEdges()); + } + if (sEvts == NULL) { + sEvts = new SweepEventQueue(numberOfEdges()); + } + + SortPoints(); + + curPt = 0; + pos = getPoint(0).x[1] - 1.0; + + for (int i = 0; i < numberOfPoints(); i++) { + pData[i].pending = 0; + pData[i].edgeOnLeft = -1; + pData[i].nextLinkedPoint = -1; + pData[i].rx[0] = /*Round(*/getPoint(i).x[0]/*)*/; + pData[i].rx[1] = /*Round(*/getPoint(i).x[1]/*)*/; + } + + for (int i = 0;i < numberOfEdges(); i++) { + swrData[i].misc = NULL; + eData[i].rdx=pData[getEdge(i).en].rx - pData[getEdge(i).st].rx; + } +} + + +void Shape::EndRaster() +{ + delete sTree; + sTree = NULL; + delete sEvts; + sEvts = NULL; + + MakePointData(false); + MakeEdgeData(false); + MakeRasterData(false); +} + + +void Shape::BeginQuickRaster(float &pos, int &curPt) +{ + if ( numberOfPoints() <= 1 || numberOfEdges() <= 1 ) { + curPt = 0; + pos = 0; + return; + } + + MakeRasterData(true); + MakeQuickRasterData(true); + nbQRas = 0; + firstQRas = lastQRas = -1; + MakePointData(true); + MakeEdgeData(true); + + curPt = 0; + pos = getPoint(0).x[1] - 1.0; + + initialisePointData(); + + for (int i=0;i 0 && getPoint(curPt - 1).x[1] >= to) ) + { + int nPt = (d == DOWNWARDS) ? curPt++ : --curPt; + + // treat a new point: remove and add edges incident to it + int nbUp; + int nbDn; + int upNo; + int dnNo; + _countUpDown(nPt, &nbUp, &nbDn, &upNo, &dnNo); + + if ( d == DOWNWARDS ) { + if ( nbDn <= 0 ) { + upNo = -1; + } + if ( upNo >= 0 && swrData[upNo].misc == NULL ) { + upNo = -1; + } + } else { + if ( nbUp <= 0 ) { + dnNo = -1; + } + if ( dnNo >= 0 && swrData[dnNo].misc == NULL ) { + dnNo = -1; + } + } + + if ( ( d == DOWNWARDS && nbUp > 0 ) || ( d == UPWARDS && nbDn > 0 ) ) { + // first remove edges coming from above or below, as appropriate + int cb = getPoint(nPt).incidentEdge[FIRST]; + while ( cb >= 0 && cb < numberOfEdges() ) { + + Shape::dg_arete const &e = getEdge(cb); + if ( (d == DOWNWARDS && nPt == std::max(e.st, e.en)) || + (d == UPWARDS && nPt == std::min(e.st, e.en)) ) + { + if ( ( d == DOWNWARDS && cb != upNo ) || ( d == UPWARDS && cb != dnNo ) ) { + // we salvage the edge upNo to plug the edges we'll be addingat its place + // but the other edge don't have this chance + SweepTree *node = swrData[cb].misc; + if ( node ) { + swrData[cb].misc = NULL; + node->Remove(*sTree, *sEvts, true); + } + } + } + cb = NextAt(nPt, cb); + } + } + + // if there is one edge going down and one edge coming from above, we don't Insert() the new edge, + // but replace the upNo edge by the new one (faster) + SweepTree* insertionNode = NULL; + if ( dnNo >= 0 ) { + if ( upNo >= 0 ) { + int rmNo=(d == DOWNWARDS) ? upNo:dnNo; + int neNo=(d == DOWNWARDS) ? dnNo:upNo; + SweepTree* node = swrData[rmNo].misc; + swrData[rmNo].misc = NULL; + + int const P = (d == DOWNWARDS) ? nPt : Other(nPt, neNo); + node->ConvertTo(this, neNo, 1, P); + + swrData[neNo].misc = node; + insertionNode = node; + CreateEdge(neNo, to, step); + } else { + // always DOWNWARDS + SweepTree* node = sTree->add(this, dnNo, 1, nPt, this); + swrData[dnNo].misc = node; + node->Insert(*sTree, *sEvts, this, nPt, true); + //if (d == UPWARDS) { + // node->startPoint = Other(nPt, dnNo); + //} + insertionNode = node; + CreateEdge(dnNo,to,step); + } + } else { + if ( upNo >= 0 ) { + // always UPWARDS + SweepTree* node = sTree->add(this, upNo, 1, nPt, this); + swrData[upNo].misc = node; + node->Insert(*sTree, *sEvts, this, nPt, true); + //if (d == UPWARDS) { + node->startPoint = Other(nPt, upNo); + //} + insertionNode = node; + CreateEdge(upNo,to,step); + } + } + + // add the remaining edges + if ( ( d == DOWNWARDS && nbDn > 1 ) || ( d == UPWARDS && nbUp > 1 ) ) { + // si nbDn == 1 , alors dnNo a deja ete traite + int cb = getPoint(nPt).incidentEdge[FIRST]; + while ( cb >= 0 && cb < numberOfEdges() ) { + Shape::dg_arete const &e = getEdge(cb); + if ( nPt == std::min(e.st, e.en) ) { + if ( cb != dnNo && cb != upNo ) { + SweepTree *node = sTree->add(this, cb, 1, nPt, this); + swrData[cb].misc = node; + node->InsertAt(*sTree, *sEvts, this, insertionNode, nPt, true); + if (d == UPWARDS) { + node->startPoint = Other(nPt, cb); + } + CreateEdge(cb, to, step); + } + } + cb = NextAt(nPt,cb); + } + } + } + + curP = curPt; + if ( curPt > 0 ) { + pos = getPoint(curPt - 1).x[1]; + } else { + pos = to; + } + + // the final touch: edges intersecting the sweepline must be update so that their intersection with + // said sweepline is correct. + pos = to; + if ( sTree->racine ) { + SweepTree* curS = static_cast(sTree->racine->Leftmost()); + while ( curS ) { + int cb = curS->bord; + AvanceEdge(cb, to, true, step); + curS = static_cast(curS->elem[RIGHT]); + } + } +} + + + +void Shape::QuickScan(float &pos,int &curP, float to, bool doSort, float step) +{ + if ( numberOfEdges() <= 1 ) { + return; + } + + if ( pos == to ) { + return; + } + + enum Direction { + DOWNWARDS, + UPWARDS + }; + + Direction const d = (pos < to) ? DOWNWARDS : UPWARDS; + + int curPt = curP; + while ( (d == DOWNWARDS && curPt < numberOfPoints() && getPoint(curPt ).x[1] <= to) || + (d == UPWARDS && curPt > 0 && getPoint(curPt - 1).x[1] >= to) ) + { + int nPt = (d == DOWNWARDS) ? curPt++ : --curPt; + + int nbUp; + int nbDn; + int upNo; + int dnNo; + _countUpDown(nPt, &nbUp, &nbDn, &upNo, &dnNo); + + if ( nbDn <= 0 ) { + upNo = -1; + } + if ( upNo >= 0 && swrData[upNo].misc == NULL ) { + upNo = -1; + } + + if ( nbUp > 0 ) { + int cb = getPoint(nPt).incidentEdge[FIRST]; + while ( cb >= 0 && cb < numberOfEdges() ) { + Shape::dg_arete const &e = getEdge(cb); + if ( (d == DOWNWARDS && nPt == std::max(e.st, e.en)) || + (d == UPWARDS && nPt == std::min(e.st, e.en)) ) + { + if ( cb != upNo ) { + QuickRasterSubEdge(cb); + } + } + cb = NextAt(nPt,cb); + } + } + + // traitement du "upNo devient dnNo" + int ins_guess = -1; + if ( dnNo >= 0 ) { + if ( upNo >= 0 ) { + ins_guess = QuickRasterChgEdge(upNo, dnNo, getPoint(nPt).x[0]); + } else { + ins_guess = QuickRasterAddEdge(dnNo, getPoint(nPt).x[0], ins_guess); + } + CreateEdge(dnNo, to, step); + } + + if ( nbDn > 1 ) { // si nbDn == 1 , alors dnNo a deja ete traite + int cb = getPoint(nPt).incidentEdge[FIRST]; + while ( cb >= 0 && cb < numberOfEdges() ) { + Shape::dg_arete const &e = getEdge(cb); + if ( (d == DOWNWARDS && nPt == std::min(e.st, e.en)) || + (d == UPWARDS && nPt == std::max(e.st, e.en)) ) + { + if ( cb != dnNo ) { + ins_guess = QuickRasterAddEdge(cb, getPoint(nPt).x[0], ins_guess); + CreateEdge(cb, to, step); + } + } + cb = NextAt(nPt,cb); + } + } + + + curP = curPt; + if ( curPt > 0 ) { + pos = getPoint(curPt-1).x[1]; + } else { + pos = to; + } + } + + pos = to; + + for (int i=0; i < nbQRas; i++) { + int cb = qrsData[i].bord; + AvanceEdge(cb, to, true, step); + qrsData[i].x=swrData[cb].curX; + } + + QuickRasterSort(); +} + + + +int Shape::QuickRasterChgEdge(int oBord, int nBord, double x) +{ + if ( oBord == nBord ) { + return -1; + } + + int no = qrsData[oBord].ind; + if ( no >= 0 ) { + qrsData[no].bord = nBord; + qrsData[no].x = x; + qrsData[oBord].ind = -1; + qrsData[nBord].ind = no; + } + + return no; +} + + + +int Shape::QuickRasterAddEdge(int bord, double x, int guess) +{ + int no = nbQRas++; + qrsData[no].bord = bord; + qrsData[no].x = x; + qrsData[bord].ind = no; + qrsData[no].prev = -1; + qrsData[no].next = -1; + + if ( no < 0 || no >= nbQRas ) { + return -1; + } + + if ( firstQRas < 0 ) { + firstQRas = lastQRas = no; + qrsData[no].prev = -1; + qrsData[no].next = -1; + return no; + } + + if ( guess < 0 || guess >= nbQRas ) { + + int c = firstQRas; + while ( c >= 0 && c < nbQRas && CmpQRs(qrsData[c],qrsData[no]) < 0 ) { + c = qrsData[c].next; + } + + if ( c < 0 || c >= nbQRas ) { + qrsData[no].prev = lastQRas; + qrsData[lastQRas].next = no; + lastQRas = no; + } else { + qrsData[no].prev = qrsData[c].prev; + if ( qrsData[no].prev >= 0 ) { + qrsData[qrsData[no].prev].next=no; + } else { + firstQRas = no; + } + + qrsData[no].next = c; + qrsData[c].prev = no; + } + + } else { + int c = guess; + int stTst = CmpQRs(qrsData[c],qrsData[no]); + if ( stTst == 0 ) { + + qrsData[no].prev = qrsData[c].prev; + if ( qrsData[no].prev >= 0 ) { + qrsData[qrsData[no].prev].next = no; + } else { + firstQRas = no; + } + + qrsData[no].next = c; + qrsData[c].prev = no; + + } else if ( stTst > 0 ) { + + while ( c >= 0 && c < nbQRas && CmpQRs(qrsData[c],qrsData[no]) > 0 ) { + c = qrsData[c].prev; + } + + if ( c < 0 || c >= nbQRas ) { + qrsData[no].next = firstQRas; + qrsData[firstQRas].prev = no; // firstQRas != -1 + firstQRas = no; + } else { + qrsData[no].next = qrsData[c].next; + if ( qrsData[no].next >= 0 ) { + qrsData[qrsData[no].next].prev = no; + } else { + lastQRas = no; + } + qrsData[no].prev = c; + qrsData[c].next = no; + } + + } else { + + while ( c >= 0 && c < nbQRas && CmpQRs(qrsData[c],qrsData[no]) < 0 ) { + c = qrsData[c].next; + } + + if ( c < 0 || c >= nbQRas ) { + qrsData[no].prev = lastQRas; + qrsData[lastQRas].next = no; + lastQRas = no; + } else { + qrsData[no].prev = qrsData[c].prev; + if ( qrsData[no].prev >= 0 ) { + qrsData[qrsData[no].prev].next = no; + } else { + firstQRas = no; + } + + qrsData[no].next = c; + qrsData[c].prev = no; + } + } + } + + return no; +} + + + +void Shape::QuickRasterSubEdge(int bord) +{ + int no = qrsData[bord].ind; + if ( no < 0 || no >= nbQRas ) { + return; // euuhHHH + } + + if ( qrsData[no].prev >= 0 ) { + qrsData[qrsData[no].prev].next=qrsData[no].next; + } + + if ( qrsData[no].next >= 0 ) { + qrsData[qrsData[no].next].prev = qrsData[no].prev; + } + + if ( no == firstQRas ) { + firstQRas = qrsData[no].next; + } + + if ( no == lastQRas ) { + lastQRas = qrsData[no].prev; + } + + qrsData[no].prev = qrsData[no].next = -1; + + int savInd = qrsData[no].ind; + qrsData[no] = qrsData[--nbQRas]; + qrsData[no].ind = savInd; + qrsData[qrsData[no].bord].ind = no; + qrsData[bord].ind = -1; + + if ( nbQRas > 0 ) { + if ( firstQRas == nbQRas ) { + firstQRas = no; + } + if ( lastQRas == nbQRas ) { + lastQRas = no; + } + if ( qrsData[no].prev >= 0 ) { + qrsData[qrsData[no].prev].next = no; + } + if ( qrsData[no].next >= 0 ) { + qrsData[qrsData[no].next].prev = no; + } + } +} + + + +void Shape::QuickRasterSwapEdge(int a, int b) +{ + if ( a == b ) { + return; + } + + int na = qrsData[a].ind; + int nb = qrsData[b].ind; + if ( na < 0 || na >= nbQRas || nb < 0 || nb >= nbQRas ) { + return; // errrm + } + + qrsData[na].bord = b; + qrsData[nb].bord = a; + qrsData[a].ind = nb; + qrsData[b].ind = na; + + double swd = qrsData[na].x; + qrsData[na].x = qrsData[nb].x; + qrsData[nb].x = swd; +} + + +void Shape::QuickRasterSort() +{ + if ( nbQRas <= 1 ) { + return; + } + + int cb = qrsData[firstQRas].bord; + + while ( cb >= 0 ) { + int bI = qrsData[cb].ind; + int nI = qrsData[bI].next; + + if ( nI < 0 ) { + break; + } + + int ncb = qrsData[nI].bord; + if ( CmpQRs(qrsData[nI], qrsData[bI]) < 0 ) { + QuickRasterSwapEdge(cb, ncb); + int pI = qrsData[bI].prev; // ca reste bI, puisqu'on a juste echange les contenus + if ( pI < 0 ) { + cb = ncb; // en fait inutile; mais bon... + } else { + int pcb = qrsData[pI].bord; + cb = pcb; + } + } else { + cb = ncb; + } + } +} + + +// direct scan to a given position. goes through the edge list to keep only the ones intersecting the target sweepline +// good for initial setup of scanline algo, bad for incremental changes +void Shape::DirectScan(float &pos, int &curP, float to, float step) +{ + if ( numberOfEdges() <= 1 ) { + return; + } + + if ( pos == to ) { + return; + } + + if ( pos < to ) { + // we're moving downwards + // points of the polygon are sorted top-down, so we take them in order, starting with the one at index curP, + // until we reach the wanted position to. + // don't forget to update curP and pos when we're done + int curPt = curP; + while ( curPt < numberOfPoints() && getPoint(curPt).x[1] <= to ) { + curPt++; + } + + for (int i=0;iRemove(*sTree, *sEvts, true); + } + } + + for (int i=0; i < numberOfEdges(); i++) { + Shape::dg_arete const &e = getEdge(i); + if ( ( e.st < curPt && e.en >= curPt ) || ( e.en < curPt && e.st >= curPt )) { + // crosses sweepline + int nPt = (e.st < curPt) ? e.st : e.en; + SweepTree* node = sTree->add(this, i, 1, nPt, this); + swrData[i].misc = node; + node->Insert(*sTree, *sEvts, this, nPt, true); + CreateEdge(i, to, step); + } + } + + curP = curPt; + if ( curPt > 0 ) { + pos = getPoint(curPt - 1).x[1]; + } else { + pos = to; + } + + } else { + + // same thing, but going up. so the sweepSens is inverted for the Find() function + int curPt=curP; + while ( curPt > 0 && getPoint(curPt-1).x[1] >= to ) { + curPt--; + } + + for (int i = 0; i < numberOfEdges(); i++) { + if ( swrData[i].misc ) { + SweepTree* node = swrData[i].misc; + swrData[i].misc = NULL; + node->Remove(*sTree, *sEvts, true); + } + } + + for (int i=0;i curPt - 1 && e.en <= curPt - 1 ) || ( e.en > curPt - 1 && e.st <= curPt - 1 )) { + // crosses sweepline + int nPt = (e.st > curPt) ? e.st : e.en; + SweepTree* node = sTree->add(this, i, 1, nPt, this); + swrData[i].misc = node; + node->Insert(*sTree, *sEvts, this, nPt, false); + node->startPoint = Other(nPt, i); + CreateEdge(i, to, step); + } + } + + curP = curPt; + if ( curPt > 0 ) { + pos = getPoint(curPt - 1).x[1]; + } else { + pos = to; + } + } + + // the final touch: edges intersecting the sweepline must be update so that their intersection with + // said sweepline is correct. + pos = to; + if ( sTree->racine ) { + SweepTree* curS=static_cast(sTree->racine->Leftmost()); + while ( curS ) { + int cb = curS->bord; + AvanceEdge(cb, to, true, step); + curS = static_cast(curS->elem[RIGHT]); + } + } +} + + + +void Shape::DirectQuickScan(float &pos, int &curP, float to, bool doSort, float step) +{ + if ( numberOfEdges() <= 1 ) { + return; + } + + if ( pos == to ) { + return; + } + + if ( pos < to ) { + // we're moving downwards + // points of the polygon are sorted top-down, so we take them in order, starting with the one at index curP, + // until we reach the wanted position to. + // don't forget to update curP and pos when we're done + int curPt=curP; + while ( curPt < numberOfPoints() && getPoint(curPt).x[1] <= to ) { + curPt++; + } + + for (int i = 0; i < numberOfEdges(); i++) { + if ( qrsData[i].ind < 0 ) { + QuickRasterSubEdge(i); + } + } + + for (int i = 0; i < numberOfEdges(); i++) { + Shape::dg_arete const &e = getEdge(i); + if ( ( e.st < curPt && e.en >= curPt ) || ( e.en < curPt && e.st >= curPt )) { + // crosses sweepline + int nPt = (e.st < e.en) ? e.st : e.en; + QuickRasterAddEdge(i, getPoint(nPt).x[0], -1); + CreateEdge(i, to, step); + } + } + + curP = curPt; + if ( curPt > 0 ) { + pos=getPoint(curPt-1).x[1]; + } else { + pos = to; + } + + } else { + + // same thing, but going up. so the sweepSens is inverted for the Find() function + int curPt=curP; + while ( curPt > 0 && getPoint(curPt-1).x[1] >= to ) { + curPt--; + } + + for (int i = 0; i < numberOfEdges(); i++) { + if ( qrsData[i].ind < 0 ) { + QuickRasterSubEdge(i); + } + } + + for (int i=0;i= curPt-1 ) || ( e.en < curPt-1 && e.st >= curPt-1 )) { + // crosses sweepline + int nPt = (e.st > e.en) ? e.st : e.en; + QuickRasterAddEdge(i, getPoint(nPt).x[0], -1); + CreateEdge(i, to, step); + } + } + + curP = curPt; + if ( curPt > 0 ) { + pos = getPoint(curPt-1).x[1]; + } else { + pos = to; + } + + } + + pos = to; + for (int i = 0; i < nbQRas; i++) { + int cb = qrsData[i].bord; + AvanceEdge(cb, to, true, step); + qrsData[i].x = swrData[cb].curX; + } + + QuickRasterSort(); +} + + +// scan and compute coverage, FloatLigne version coverage of the line is bult in 2 parts: first a +// set of rectangles of height the height of the line (here: "step") one rectangle for each portion +// of the sweepline that is in the polygon at the beginning of the scan. then a set ot trapezoids +// are added or removed to these rectangles, one trapezoid for each edge destroyed or edge crossing +// the entire line. think of it as a refinement of the coverage by rectangles + +void Shape::Scan(float &pos, int &curP, float to, FloatLigne *line, bool exact, float step) +{ + if ( numberOfEdges() <= 1 ) { + return; + } + + if ( pos >= to ) { + return; + } + + // first step: the rectangles since we read the sweepline left to right, we know the + // boundaries of the rectangles are appended in a list, hence the AppendBord(). we salvage + // the guess value for the trapezoids the edges will induce + + if ( sTree->racine ) { + SweepTree *curS = static_cast(sTree->racine->Leftmost()); + while ( curS ) { + + int lastGuess = -1; + int cb = curS->bord; + + if ( swrData[cb].sens == false && curS->elem[LEFT] ) { + + int lb = (static_cast(curS->elem[LEFT]))->bord; + + lastGuess = line->AppendBord(swrData[lb].curX, + to - swrData[lb].curY, + swrData[cb].curX, + to - swrData[cb].curY,0.0); + + swrData[lb].guess = lastGuess - 1; + swrData[cb].guess = lastGuess; + } else { + int lb = curS->bord; + swrData[lb].guess = -1; + } + + curS=static_cast (curS->elem[RIGHT]); + } + } + + int curPt = curP; + while ( curPt < numberOfPoints() && getPoint(curPt).x[1] <= to ) { + + int nPt = curPt++; + + // same thing as the usual Scan(), just with a hardcoded "indegree+outdegree=2" case, since + // it's the most common one + + int nbUp; + int nbDn; + int upNo; + int dnNo; + if ( getPoint(nPt).totalDegree() == 2 ) { + _countUpDownTotalDegree2(nPt, &nbUp, &nbDn, &upNo, &dnNo); + } else { + _countUpDown(nPt, &nbUp, &nbDn, &upNo, &dnNo); + } + + if ( nbDn <= 0 ) { + upNo = -1; + } + if ( upNo >= 0 && swrData[upNo].misc == NULL ) { + upNo = -1; + } + + if ( nbUp > 1 || ( nbUp == 1 && upNo < 0 ) ) { + int cb = getPoint(nPt).incidentEdge[FIRST]; + while ( cb >= 0 && cb < numberOfEdges() ) { + Shape::dg_arete const &e = getEdge(cb); + if ( nPt == std::max(e.st, e.en) ) { + if ( cb != upNo ) { + SweepTree* node = swrData[cb].misc; + if ( node ) { + _updateIntersection(cb, nPt); + // create trapezoid for the chunk of edge intersecting with the line + DestroyEdge(cb, to, line); + node->Remove(*sTree, *sEvts, true); + } + } + } + + cb = NextAt(nPt,cb); + } + } + + // traitement du "upNo devient dnNo" + SweepTree *insertionNode = NULL; + if ( dnNo >= 0 ) { + if ( upNo >= 0 ) { + SweepTree* node = swrData[upNo].misc; + _updateIntersection(upNo, nPt); + DestroyEdge(upNo, to, line); + + node->ConvertTo(this, dnNo, 1, nPt); + + swrData[dnNo].misc = node; + insertionNode = node; + CreateEdge(dnNo, to, step); + swrData[dnNo].guess = swrData[upNo].guess; + } else { + SweepTree *node = sTree->add(this, dnNo, 1, nPt, this); + swrData[dnNo].misc = node; + node->Insert(*sTree, *sEvts, this, nPt, true); + insertionNode = node; + CreateEdge(dnNo, to, step); + } + } + + if ( nbDn > 1 ) { // si nbDn == 1 , alors dnNo a deja ete traite + int cb = getPoint(nPt).incidentEdge[FIRST]; + while ( cb >= 0 && cb < numberOfEdges() ) { + Shape::dg_arete const &e = getEdge(cb); + if ( nPt == std::min(e.st, e.en) ) { + if ( cb != dnNo ) { + SweepTree *node = sTree->add(this, cb, 1, nPt, this); + swrData[cb].misc = node; + node->InsertAt(*sTree, *sEvts, this, insertionNode, nPt, true); + CreateEdge(cb, to, step); + } + } + cb = NextAt(nPt,cb); + } + } + } + + curP = curPt; + if ( curPt > 0 ) { + pos = getPoint(curPt - 1).x[1]; + } else { + pos = to; + } + + // update intersections with the sweepline, and add trapezoids for edges crossing the line + pos = to; + if ( sTree->racine ) { + SweepTree* curS = static_cast(sTree->racine->Leftmost()); + while ( curS ) { + int cb = curS->bord; + AvanceEdge(cb, to, line, exact, step); + curS = static_cast(curS->elem[RIGHT]); + } + } +} + + + + +void Shape::Scan(float &pos, int &curP, float to, FillRule directed, BitLigne *line, bool exact, float step) +{ + if ( numberOfEdges() <= 1 ) { + return; + } + + if ( pos >= to ) { + return; + } + + if ( sTree->racine ) { + int curW = 0; + float lastX = 0; + SweepTree* curS = static_cast(sTree->racine->Leftmost()); + + if ( directed == fill_oddEven ) { + + while ( curS ) { + int cb = curS->bord; + curW++; + curW &= 0x00000001; + if ( curW == 0 ) { + line->AddBord(lastX,swrData[cb].curX,true); + } else { + lastX = swrData[cb].curX; + } + curS = static_cast(curS->elem[RIGHT]); + } + + } else if ( directed == fill_positive ) { + + // doesn't behave correctly; no way i know to do this without a ConvertToShape() + while ( curS ) { + int cb = curS->bord; + int oW = curW; + if ( swrData[cb].sens ) { + curW++; + } else { + curW--; + } + + if ( curW <= 0 && oW > 0) { + line->AddBord(lastX, swrData[cb].curX, true); + } else if ( curW > 0 && oW <= 0 ) { + lastX = swrData[cb].curX; + } + + curS = static_cast(curS->elem[RIGHT]); + } + + } else if ( directed == fill_nonZero ) { + + while ( curS ) { + int cb = curS->bord; + int oW = curW; + if ( swrData[cb].sens ) { + curW++; + } else { + curW--; + } + + if ( curW == 0 && oW != 0) { + line->AddBord(lastX,swrData[cb].curX,true); + } else if ( curW != 0 && oW == 0 ) { + lastX=swrData[cb].curX; + } + curS = static_cast(curS->elem[RIGHT]); + } + } + + } + + int curPt = curP; + while ( curPt < numberOfPoints() && getPoint(curPt).x[1] <= to ) { + int nPt = curPt++; + + int cb; + int nbUp; + int nbDn; + int upNo; + int dnNo; + + if ( getPoint(nPt).totalDegree() == 2 ) { + _countUpDownTotalDegree2(nPt, &nbUp, &nbDn, &upNo, &dnNo); + } else { + _countUpDown(nPt, &nbUp, &nbDn, &upNo, &dnNo); + } + + if ( nbDn <= 0 ) { + upNo = -1; + } + if ( upNo >= 0 && swrData[upNo].misc == NULL ) { + upNo = -1; + } + + if ( nbUp > 1 || ( nbUp == 1 && upNo < 0 ) ) { + int cb = getPoint(nPt).incidentEdge[FIRST]; + while ( cb >= 0 && cb < numberOfEdges() ) { + Shape::dg_arete const &e = getEdge(cb); + if ( nPt == std::max(e.st, e.en) ) { + if ( cb != upNo ) { + SweepTree* node=swrData[cb].misc; + if ( node ) { + _updateIntersection(cb, nPt); + DestroyEdge(cb, line); + node->Remove(*sTree,*sEvts,true); + } + } + } + cb = NextAt(nPt,cb); + } + } + + // traitement du "upNo devient dnNo" + SweepTree* insertionNode = NULL; + if ( dnNo >= 0 ) { + if ( upNo >= 0 ) { + SweepTree* node = swrData[upNo].misc; + _updateIntersection(upNo, nPt); + DestroyEdge(upNo, line); + + node->ConvertTo(this, dnNo, 1, nPt); + + swrData[dnNo].misc = node; + insertionNode = node; + CreateEdge(dnNo, to, step); + + } else { + + SweepTree* node = sTree->add(this,dnNo,1,nPt,this); + swrData[dnNo].misc = node; + node->Insert(*sTree, *sEvts, this, nPt, true); + insertionNode = node; + CreateEdge(dnNo, to, step); + } + } + + if ( nbDn > 1 ) { // si nbDn == 1 , alors dnNo a deja ete traite + cb = getPoint(nPt).incidentEdge[FIRST]; + while ( cb >= 0 && cb < numberOfEdges() ) { + Shape::dg_arete const &e = getEdge(cb); + if ( nPt == std::min(e.st, e.en) ) { + if ( cb != dnNo ) { + SweepTree* node = sTree->add(this, cb, 1, nPt, this); + swrData[cb].misc = node; + node->InsertAt(*sTree, *sEvts, this, insertionNode, nPt, true); + CreateEdge(cb, to, step); + } + } + cb = NextAt(nPt, cb); + } + } + } + + curP = curPt; + if ( curPt > 0 ) { + pos = getPoint(curPt - 1).x[1]; + } else { + pos = to; + } + + pos = to; + if ( sTree->racine ) { + SweepTree* curS = static_cast(sTree->racine->Leftmost()); + while ( curS ) { + int cb = curS->bord; + AvanceEdge(cb, to, line, exact, step); + curS = static_cast(curS->elem[RIGHT]); + } + } +} + + +void Shape::Scan(float &pos, int &curP, float to, AlphaLigne *line, bool exact, float step) +{ + if ( numberOfEdges() <= 1 ) { + return; + } + + if ( pos >= to ) { + return; + } + + int curPt = curP; + while ( curPt < numberOfPoints() && getPoint(curPt).x[1] <= to ) { + int nPt = -1; + nPt = curPt++; + + int nbUp; + int nbDn; + int upNo; + int dnNo; + if ( getPoint(nPt).totalDegree() == 2 ) { + _countUpDownTotalDegree2(nPt, &nbUp, &nbDn, &upNo, &dnNo); + } else { + _countUpDown(nPt, &nbUp, &nbDn, &upNo, &dnNo); + } + + if ( nbDn <= 0 ) { + upNo=-1; + } + if ( upNo >= 0 && swrData[upNo].misc == NULL ) { + upNo=-1; + } + + if ( nbUp > 1 || ( nbUp == 1 && upNo < 0 ) ) { + int cb = getPoint(nPt).incidentEdge[FIRST]; + while ( cb >= 0 && cb < numberOfEdges() ) { + Shape::dg_arete const &e = getEdge(cb); + if ( nPt == std::max(e.st, e.en) ) { + if ( cb != upNo ) { + SweepTree* node = swrData[cb].misc; + if ( node ) { + _updateIntersection(cb, nPt); + DestroyEdge(cb, line); + node->Remove(*sTree, *sEvts, true); + } + } + } + + cb = NextAt(nPt,cb); + } + } + + // traitement du "upNo devient dnNo" + SweepTree* insertionNode = NULL; + if ( dnNo >= 0 ) { + if ( upNo >= 0 ) { + SweepTree* node = swrData[upNo].misc; + _updateIntersection(upNo, nPt); + DestroyEdge(upNo, line); + + node->ConvertTo(this, dnNo, 1, nPt); + + swrData[dnNo].misc = node; + insertionNode = node; + CreateEdge(dnNo, to, step); + swrData[dnNo].guess = swrData[upNo].guess; + } else { + SweepTree* node = sTree->add(this, dnNo, 1, nPt, this); + swrData[dnNo].misc = node; + node->Insert(*sTree, *sEvts, this, nPt, true); + insertionNode = node; + CreateEdge(dnNo, to, step); + } + } + + if ( nbDn > 1 ) { // si nbDn == 1 , alors dnNo a deja ete traite + int cb = getPoint(nPt).incidentEdge[FIRST]; + while ( cb >= 0 && cb < numberOfEdges() ) { + Shape::dg_arete const &e = getEdge(cb); + if ( nPt == std::min(e.st, e.en) ) { + if ( cb != dnNo ) { + SweepTree* node = sTree->add(this, cb, 1, nPt, this); + swrData[cb].misc = node; + node->InsertAt(*sTree, *sEvts, this, insertionNode, nPt, true); + CreateEdge(cb, to, step); + } + } + cb = NextAt(nPt,cb); + } + } + } + + curP = curPt; + if ( curPt > 0 ) { + pos = getPoint(curPt - 1).x[1]; + } else { + pos = to; + } + + pos = to; + if ( sTree->racine ) { + SweepTree* curS = static_cast(sTree->racine->Leftmost()); + while ( curS ) { + int cb = curS->bord; + AvanceEdge(cb, to, line, exact, step); + curS = static_cast(curS->elem[RIGHT]); + } + } +} + + + +void Shape::QuickScan(float &pos, int &curP, float to, FloatLigne* line, float step) +{ + if ( numberOfEdges() <= 1 ) { + return; + } + + if ( pos >= to ) { + return; + } + + if ( nbQRas > 1 ) { + int curW = 0; + float lastX = 0; + float lastY = 0; + int lastGuess = -1; + int lastB = -1; + + for (int i = firstQRas; i >= 0 && i < nbQRas; i = qrsData[i].next) { + int cb = qrsData[i].bord; + int oW = curW; + if ( swrData[cb].sens ) { + curW++; + } else { + curW--; + } + + if ( curW % 2 == 0 && oW % 2 != 0) { + + lastGuess = line->AppendBord(swrData[lastB].curX, + to - swrData[lastB].curY, + swrData[cb].curX, + to - swrData[cb].curY, + 0.0); + + swrData[cb].guess = lastGuess; + if ( lastB >= 0 ) { + swrData[lastB].guess = lastGuess - 1; + } + + } else if ( curW%2 != 0 && oW%2 == 0 ) { + + lastX = swrData[cb].curX; + lastY = swrData[cb].curY; + lastB = cb; + swrData[cb].guess = -1; + + } else { + swrData[cb].guess = -1; + } + } + } + + int curPt = curP; + while ( curPt < numberOfPoints() && getPoint(curPt).x[1] <= to ) { + int nPt = curPt++; + + int nbUp; + int nbDn; + int upNo; + int dnNo; + if ( getPoint(nPt).totalDegree() == 2 ) { + _countUpDownTotalDegree2(nPt, &nbUp, &nbDn, &upNo, &dnNo); + } else { + _countUpDown(nPt, &nbUp, &nbDn, &upNo, &dnNo); + } + + if ( nbDn <= 0 ) { + upNo = -1; + } + if ( upNo >= 0 && swrData[upNo].misc == NULL ) { + upNo = -1; + } + + if ( nbUp > 1 || ( nbUp == 1 && upNo < 0 ) ) { + int cb = getPoint(nPt).incidentEdge[FIRST]; + while ( cb >= 0 && cb < numberOfEdges() ) { + Shape::dg_arete const &e = getEdge(cb); + if ( nPt == std::max(e.st, e.en) ) { + if ( cb != upNo ) { + QuickRasterSubEdge(cb); + _updateIntersection(cb, nPt); + DestroyEdge(cb, to, line); + } + } + cb = NextAt(nPt, cb); + } + } + + // traitement du "upNo devient dnNo" + int ins_guess=-1; + if ( dnNo >= 0 ) { + if ( upNo >= 0 ) { + ins_guess = QuickRasterChgEdge(upNo ,dnNo, getPoint(nPt).x[0]); + _updateIntersection(upNo, nPt); + DestroyEdge(upNo, to, line); + + CreateEdge(dnNo, to, step); + swrData[dnNo].guess = swrData[upNo].guess; + } else { + ins_guess = QuickRasterAddEdge(dnNo, getPoint(nPt).x[0], ins_guess); + CreateEdge(dnNo, to, step); + } + } + + if ( nbDn > 1 ) { // si nbDn == 1 , alors dnNo a deja ete traite + int cb = getPoint(nPt).incidentEdge[FIRST]; + while ( cb >= 0 && cb < numberOfEdges() ) { + Shape::dg_arete const &e = getEdge(cb); + if ( nPt == std::min(e.st, e.en) ) { + if ( cb != dnNo ) { + ins_guess = QuickRasterAddEdge(cb, getPoint(nPt).x[0], ins_guess); + CreateEdge(cb, to, step); + } + } + cb = NextAt(nPt, cb); + } + } + } + + curP = curPt; + if ( curPt > 0 ) { + pos = getPoint(curPt-1).x[1]; + } else { + pos=to; + } + + pos = to; + for (int i=0; i < nbQRas; i++) { + int cb = qrsData[i].bord; + AvanceEdge(cb, to, line, true, step); + qrsData[i].x = swrData[cb].curX; + } + + QuickRasterSort(); +} + + + + +void Shape::QuickScan(float &pos, int &curP, float to, FillRule directed, BitLigne* line, float step) +{ + if ( numberOfEdges() <= 1 ) { + return; + } + + if ( pos >= to ) { + return; + } + + if ( nbQRas > 1 ) { + int curW = 0; + float lastX = 0; + + if ( directed == fill_oddEven ) { + + for (int i = firstQRas; i >= 0 && i < nbQRas; i = qrsData[i].next) { + int cb = qrsData[i].bord; + curW++; + curW &= 1; + if ( curW == 0 ) { + line->AddBord(lastX, swrData[cb].curX, true); + } else { + lastX = swrData[cb].curX; + } + } + + } else if ( directed == fill_positive ) { + // doesn't behave correctly; no way i know to do this without a ConvertToShape() + for (int i = firstQRas; i >= 0 && i < nbQRas; i = qrsData[i].next) { + int cb = qrsData[i].bord; + int oW = curW; + if ( swrData[cb].sens ) { + curW++; + } else { + curW--; + } + + if ( curW <= 0 && oW > 0) { + line->AddBord(lastX, swrData[cb].curX, true); + } else if ( curW > 0 && oW <= 0 ) { + lastX = swrData[cb].curX; + } + } + + } else if ( directed == fill_nonZero ) { + for (int i = firstQRas; i >= 0 && i < nbQRas; i = qrsData[i].next) { + int cb = qrsData[i].bord; + int oW = curW; + if ( swrData[cb].sens ) { + curW++; + } else { + curW--; + } + + if ( curW == 0 && oW != 0) { + line->AddBord(lastX, swrData[cb].curX, true); + } else if ( curW != 0 && oW == 0 ) { + lastX = swrData[cb].curX; + } + } + } + } + + int curPt = curP; + while ( curPt < numberOfPoints() && getPoint(curPt).x[1] <= to ) { + int nPt = -1; + nPt = curPt++; + + int nbUp; + int nbDn; + int upNo; + int dnNo; + if ( getPoint(nPt).totalDegree() == 2 ) { + _countUpDownTotalDegree2(nPt, &nbUp, &nbDn, &upNo, &dnNo); + } else { + _countUpDown(nPt, &nbUp, &nbDn, &upNo, &dnNo); + } + + if ( nbDn <= 0 ) { + upNo = -1; + } + + if ( upNo >= 0 && swrData[upNo].misc == NULL ) { + upNo = -1; + } + + if ( nbUp > 1 || ( nbUp == 1 && upNo < 0 ) ) { + int cb = getPoint(nPt).incidentEdge[FIRST]; + while ( cb >= 0 && cb < numberOfEdges() ) { + Shape::dg_arete const &e = getEdge(cb); + if ( nPt == std::max(e.st, e.en) ) { + if ( cb != upNo ) { + QuickRasterSubEdge(cb); + _updateIntersection(cb, nPt); + DestroyEdge(cb, line); + } + } + cb = NextAt(nPt, cb); + } + } + + // traitement du "upNo devient dnNo" + int ins_guess = -1; + if ( dnNo >= 0 ) { + if ( upNo >= 0 ) { + ins_guess = QuickRasterChgEdge(upNo, dnNo, getPoint(nPt).x[0]); + _updateIntersection(upNo, nPt); + DestroyEdge(upNo, line); + + CreateEdge(dnNo, to, step); + } else { + ins_guess = QuickRasterAddEdge(dnNo, getPoint(nPt).x[0], ins_guess); + CreateEdge(dnNo, to, step); + } + } + + if ( nbDn > 1 ) { // si nbDn == 1 , alors dnNo a deja ete traite + int cb = getPoint(nPt).incidentEdge[FIRST]; + while ( cb >= 0 && cb < numberOfEdges() ) { + Shape::dg_arete const &e = getEdge(cb); + if ( nPt == std::min(e.st, e.en) ) { + if ( cb != dnNo ) { + ins_guess = QuickRasterAddEdge(cb, getPoint(nPt).x[0], ins_guess); + CreateEdge(cb, to, step); + } + } + cb = NextAt(nPt,cb); + } + } + } + + curP = curPt; + if ( curPt > 0 ) { + pos=getPoint(curPt - 1).x[1]; + } else { + pos = to; + } + + pos = to; + for (int i = 0; i < nbQRas; i++) { + int cb = qrsData[i].bord; + AvanceEdge(cb, to, line, true, step); + qrsData[i].x = swrData[cb].curX; + } + + QuickRasterSort(); +} + + + +void Shape::QuickScan(float &pos, int &curP, float to, AlphaLigne* line, float step) +{ + if ( numberOfEdges() <= 1 ) { + return; + } + if ( pos >= to ) { + return; + } + + int curPt = curP; + while ( curPt < numberOfPoints() && getPoint(curPt).x[1] <= to ) { + int nPt = curPt++; + + int nbUp; + int nbDn; + int upNo; + int dnNo; + if ( getPoint(nPt).totalDegree() == 2 ) { + _countUpDownTotalDegree2(nPt, &nbUp, &nbDn, &upNo, &dnNo); + } else { + _countUpDown(nPt, &nbUp, &nbDn, &upNo, &dnNo); + } + + if ( nbDn <= 0 ) { + upNo = -1; + } + if ( upNo >= 0 && swrData[upNo].misc == NULL ) { + upNo = -1; + } + + if ( nbUp > 1 || ( nbUp == 1 && upNo < 0 ) ) { + int cb = getPoint(nPt).incidentEdge[FIRST]; + while ( cb >= 0 && cb < numberOfEdges() ) { + Shape::dg_arete const &e = getEdge(cb); + if ( nPt == std::max(e.st, e.en) ) { + if ( cb != upNo ) { + QuickRasterSubEdge(cb); + _updateIntersection(cb, nPt); + DestroyEdge(cb, line); + } + } + cb = NextAt(nPt,cb); + } + } + + // traitement du "upNo devient dnNo" + int ins_guess = -1; + if ( dnNo >= 0 ) { + if ( upNo >= 0 ) { + ins_guess = QuickRasterChgEdge(upNo, dnNo, getPoint(nPt).x[0]); + _updateIntersection(upNo, nPt); + DestroyEdge(upNo, line); + + CreateEdge(dnNo, to, step); + swrData[dnNo].guess = swrData[upNo].guess; + } else { + ins_guess = QuickRasterAddEdge(dnNo, getPoint(nPt).x[0], ins_guess); + CreateEdge(dnNo, to, step); + } + } + + if ( nbDn > 1 ) { // si nbDn == 1 , alors dnNo a deja ete traite + int cb = getPoint(nPt).incidentEdge[FIRST]; + while ( cb >= 0 && cb < numberOfEdges() ) { + Shape::dg_arete const &e = getEdge(cb); + if ( nPt == std::min(e.st, e.en) ) { + if ( cb != dnNo ) { + ins_guess = QuickRasterAddEdge(cb,getPoint(nPt).x[0], ins_guess); + CreateEdge(cb, to, step); + } + } + cb = NextAt(nPt,cb); + } + } + } + + curP = curPt; + if ( curPt > 0 ) { + pos = getPoint(curPt-1).x[1]; + } else { + pos = to; + } + + pos = to; + for (int i = 0; i < nbQRas; i++) { + int cb = qrsData[i].bord; + AvanceEdge(cb, to, line, true, step); + qrsData[i].x = swrData[cb].curX; + } + + QuickRasterSort(); +} + + +/* + * operations de bases pour la rasterization + * + */ +void Shape::CreateEdge(int no, float to, float step) +{ + int cPt; + NR::Point dir; + if ( getEdge(no).st < getEdge(no).en ) { + cPt = getEdge(no).st; + swrData[no].sens = true; + dir = getEdge(no).dx; + } else { + cPt = getEdge(no).en; + swrData[no].sens = false; + dir = -getEdge(no).dx; + } + + swrData[no].lastX = swrData[no].curX = getPoint(cPt).x[0]; + swrData[no].lastY = swrData[no].curY = getPoint(cPt).x[1]; + + if ( fabs(dir[1]) < 0.000001 ) { + swrData[no].dxdy = 0; + } else { + swrData[no].dxdy = dir[0]/dir[1]; + } + + if ( fabs(dir[0]) < 0.000001 ) { + swrData[no].dydx = 0; + } else { + swrData[no].dydx = dir[1]/dir[0]; + } + + swrData[no].calcX = swrData[no].curX + (to - step - swrData[no].curY) * swrData[no].dxdy; + swrData[no].guess = -1; +} + + +void Shape::AvanceEdge(int no, float to, bool exact, float step) +{ + if ( exact ) { + NR::Point dir; + NR::Point stp; + if ( swrData[no].sens ) { + stp = getPoint(getEdge(no).st).x; + dir = getEdge(no).dx; + } else { + stp = getPoint(getEdge(no).en).x; + dir = -getEdge(no).dx; + } + + if ( fabs(dir[1]) < 0.000001 ) { + swrData[no].calcX = stp[0] + dir[0]; + } else { + swrData[no].calcX = stp[0] + ((to - stp[1]) * dir[0]) / dir[1]; + } + } else { + swrData[no].calcX += step * swrData[no].dxdy; + } + + swrData[no].lastX = swrData[no].curX; + swrData[no].lastY = swrData[no].curY; + swrData[no].curX = swrData[no].calcX; + swrData[no].curY = to; +} + +/* + * specialisation par type de structure utilise + */ + +void Shape::DestroyEdge(int no, float to, FloatLigne* line) +{ + if ( swrData[no].sens ) { + + if ( swrData[no].curX < swrData[no].lastX ) { + + swrData[no].guess = line->AddBordR(swrData[no].curX, + to - swrData[no].curY, + swrData[no].lastX, + to - swrData[no].lastY, + -swrData[no].dydx, + swrData[no].guess); + + } else if ( swrData[no].curX > swrData[no].lastX ) { + + swrData[no].guess = line->AddBord(swrData[no].lastX, + -(to - swrData[no].lastY), + swrData[no].curX, + -(to - swrData[no].curY), + swrData[no].dydx, + swrData[no].guess); + } + + } else { + + if ( swrData[no].curX < swrData[no].lastX ) { + + swrData[no].guess = line->AddBordR(swrData[no].curX, + -(to - swrData[no].curY), + swrData[no].lastX, + -(to - swrData[no].lastY), + swrData[no].dydx, + swrData[no].guess); + + } else if ( swrData[no].curX > swrData[no].lastX ) { + + swrData[no].guess = line->AddBord(swrData[no].lastX, + to - swrData[no].lastY, + swrData[no].curX, + to - swrData[no].curY, + -swrData[no].dydx, + swrData[no].guess); + } + } +} + + + +void Shape::AvanceEdge(int no, float to, FloatLigne *line, bool exact, float step) +{ + AvanceEdge(no,to,exact,step); + + if ( swrData[no].sens ) { + + if ( swrData[no].curX < swrData[no].lastX ) { + + swrData[no].guess = line->AddBordR(swrData[no].curX, + to - swrData[no].curY, + swrData[no].lastX, + to - swrData[no].lastY, + -swrData[no].dydx, + swrData[no].guess); + + } else if ( swrData[no].curX > swrData[no].lastX ) { + + swrData[no].guess = line->AddBord(swrData[no].lastX, + -(to - swrData[no].lastY), + swrData[no].curX, + -(to - swrData[no].curY), + swrData[no].dydx, + swrData[no].guess); + } + + } else { + + if ( swrData[no].curX < swrData[no].lastX ) { + + swrData[no].guess = line->AddBordR(swrData[no].curX, + -(to - swrData[no].curY), + swrData[no].lastX, + -(to - swrData[no].lastY), + swrData[no].dydx, + swrData[no].guess); + + } else if ( swrData[no].curX > swrData[no].lastX ) { + + swrData[no].guess = line->AddBord(swrData[no].lastX, + to - swrData[no].lastY, + swrData[no].curX, + to - swrData[no].curY, + -swrData[no].dydx, + swrData[no].guess); + } + } +} + + +void Shape::DestroyEdge(int no, BitLigne *line) +{ + if ( swrData[no].sens ) { + + if ( swrData[no].curX < swrData[no].lastX ) { + + line->AddBord(swrData[no].curX, swrData[no].lastX, false); + + } else if ( swrData[no].curX > swrData[no].lastX ) { + + line->AddBord(swrData[no].lastX,swrData[no].curX,false); + } + + } else { + + if ( swrData[no].curX < swrData[no].lastX ) { + + line->AddBord(swrData[no].curX, swrData[no].lastX, false); + + } else if ( swrData[no].curX > swrData[no].lastX ) { + + line->AddBord(swrData[no].lastX, swrData[no].curX, false); + + } + } +} + + +void Shape::AvanceEdge(int no, float to, BitLigne *line, bool exact, float step) +{ + AvanceEdge(no, to, exact, step); + + if ( swrData[no].sens ) { + + if ( swrData[no].curX < swrData[no].lastX ) { + + line->AddBord(swrData[no].curX, swrData[no].lastX, false); + + } else if ( swrData[no].curX > swrData[no].lastX ) { + + line->AddBord(swrData[no].lastX, swrData[no].curX, false); + } + + } else { + + if ( swrData[no].curX < swrData[no].lastX ) { + + line->AddBord(swrData[no].curX, swrData[no].lastX, false); + + } else if ( swrData[no].curX > swrData[no].lastX ) { + + line->AddBord(swrData[no].lastX, swrData[no].curX, false); + } + } +} + + +void Shape::DestroyEdge(int no, AlphaLigne* line) +{ + if ( swrData[no].sens ) { + + if ( swrData[no].curX <= swrData[no].lastX ) { + + line->AddBord(swrData[no].curX, + 0, + swrData[no].lastX, + swrData[no].curY - swrData[no].lastY, + -swrData[no].dydx); + + } else if ( swrData[no].curX > swrData[no].lastX ) { + + line->AddBord(swrData[no].lastX, + 0, + swrData[no].curX, + swrData[no].curY - swrData[no].lastY, + swrData[no].dydx); + } + + } else { + + if ( swrData[no].curX <= swrData[no].lastX ) { + + line->AddBord(swrData[no].curX, + 0, + swrData[no].lastX, + swrData[no].lastY - swrData[no].curY, + swrData[no].dydx); + + } else if ( swrData[no].curX > swrData[no].lastX ) { + + line->AddBord(swrData[no].lastX, + 0, + swrData[no].curX, + swrData[no].lastY - swrData[no].curY, + -swrData[no].dydx); + } + } +} + + +void Shape::AvanceEdge(int no, float to, AlphaLigne *line, bool exact, float step) +{ + AvanceEdge(no,to,exact,step); + + if ( swrData[no].sens ) { + + if ( swrData[no].curX <= swrData[no].lastX ) { + + line->AddBord(swrData[no].curX, + 0, + swrData[no].lastX, + swrData[no].curY - swrData[no].lastY, + -swrData[no].dydx); + + } else if ( swrData[no].curX > swrData[no].lastX ) { + + line->AddBord(swrData[no].lastX, + 0, + swrData[no].curX, + swrData[no].curY - swrData[no].lastY, + swrData[no].dydx); + } + + } else { + + if ( swrData[no].curX <= swrData[no].lastX ) { + + line->AddBord(swrData[no].curX, + 0, + swrData[no].lastX, + swrData[no].lastY - swrData[no].curY, + swrData[no].dydx); + + } else if ( swrData[no].curX > swrData[no].lastX ) { + + line->AddBord(swrData[no].lastX, + 0, + swrData[no].curX, + swrData[no].lastY - swrData[no].curY, + -swrData[no].dydx); + } + } +} + +/** + * \param P point index. + * \param numberUp Filled in with the number of edges coming into P from above. + * \param numberDown Filled in with the number of edges coming exiting P to go below. + * \param upEdge One of the numberUp edges, or -1. + * \param downEdge One of the numberDown edges, or -1. + */ + +void Shape::_countUpDown(int P, int *numberUp, int *numberDown, int *upEdge, int *downEdge) const +{ + *numberUp = 0; + *numberDown = 0; + *upEdge = -1; + *downEdge = -1; + + int i = getPoint(P).incidentEdge[FIRST]; + + while ( i >= 0 && i < numberOfEdges() ) { + Shape::dg_arete const &e = getEdge(i); + if ( P == std::max(e.st, e.en) ) { + *upEdge = i; + (*numberUp)++; + } + if ( P == std::min(e.st, e.en) ) { + *downEdge = i; + (*numberDown)++; + } + i = NextAt(P, i); + } + +} + + + +/** + * Version of Shape::_countUpDown optimised for the case when getPoint(P).totalDegree() == 2. + */ + +void Shape::_countUpDownTotalDegree2(int P, + int *numberUp, int *numberDown, int *upEdge, int *downEdge) const +{ + *numberUp = 0; + *numberDown = 0; + *upEdge = -1; + *downEdge = -1; + + for (int i = 0; i < 2; i++) { + int const j = getPoint(P).incidentEdge[i]; + Shape::dg_arete const &e = getEdge(j); + if ( P == std::max(e.st, e.en) ) { + *upEdge = j; + (*numberUp)++; + } + if ( P == std::min(e.st, e.en) ) { + *downEdge = j; + (*numberDown)++; + } + } +} + + +void Shape::_updateIntersection(int e, int p) +{ + swrData[e].lastX = swrData[e].curX; + swrData[e].lastY = swrData[e].curY; + swrData[e].curX = getPoint(p).x[0]; + swrData[e].curY = getPoint(p).x[1]; + swrData[e].misc = NULL; +} + + +/* + 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 : diff --git a/src/livarot/ShapeSweep.cpp b/src/livarot/ShapeSweep.cpp new file mode 100644 index 000000000..3e5a3bcaf --- /dev/null +++ b/src/livarot/ShapeSweep.cpp @@ -0,0 +1,3327 @@ +/* + * ShapeSweep.cpp + * nlivarot + * + * Created by fred on Thu Jun 19 2003. + * + */ + +#include +#include "Shape.h" +#include "livarot/sweep-event-queue.h" +#include "livarot/sweep-tree-list.h" +#include "livarot/sweep-tree.h" + +#include "libnr/nr-matrix.h" + +//int doDebug=0; + +/* + * El Intersector. + * algorithm: 1) benley ottman to get intersections of all the polygon's edges + * 2) rounding of the points of the polygon, Hooby's algorithm + * 3) DFS with clockwise choice of the edge to compute the windings + * 4) choose edges according to winding numbers and fill rule + * some additional nastyness: step 2 needs a seed winding number for the upper-left point of each + * connex subgraph of the graph. computing these brutally is O(n^3): baaaad. so during the sweeping in 1) + * we keep for each point the edge of the resulting graph (not the original) that lies just on its left; + * when the time comes for the point to get its winding number computed, that edge must have been treated, + * because its upper end lies above the aforementioned point, meaning we know the winding number of the point. + * only, there is a catch: since we're sweeping the polygon, the edge we want to link the point to has not yet been + * added (that would be too easy...). so the points are put on a linked list on the original shape's edge, and the list + * is flushed when the edge is added. + * rounding: to do the rounding, we need to find which edges cross the surrounding of the rounded points (at + * each sweepline position). grunt method tries all combination of "rounded points in the sweepline"x"edges crossing + * the sweepline". That's bad (and that's what polyboolean does, if i am not mistaken). so for each point + * rounded in a given sweepline, keep immediate left and right edges at the time the point is treated. + * when edges/points crossing are searched, walk the edge list (in the sweepline at the end of the batch) starting + * from the rounded points' left and right from that time. may sound strange, but it works because edges that + * end or start in the batch have at least one end in the batch. + * all these are the cause of the numerous linked lists of points and edges maintained in the sweeping + */ + +void +Shape::ResetSweep (void) +{ + MakePointData (true); + MakeEdgeData (true); + MakeSweepSrcData (true); +} + +void +Shape::CleanupSweep (void) +{ + MakePointData (false); + MakeEdgeData (false); + MakeSweepSrcData (false); +} + +void +Shape::ForceToPolygon (void) +{ + type = shape_polygon; +} + +int +Shape::Reoriente (Shape * a) +{ + Reset (0, 0); + if (a->numberOfPoints() <= 1 || a->numberOfEdges() <= 1) + return 0; + if (directedEulerian(a) == false) + return shape_input_err; + + _pts = a->_pts; + if (numberOfPoints() > maxPt) + { + maxPt = numberOfPoints(); + if (_has_points_data) + pData.resize(maxPt); + } + + _aretes = a->_aretes; + if (numberOfEdges() > maxAr) + { + maxAr = numberOfEdges(); + if (_has_edges_data) + eData.resize(maxAr); + if (_has_sweep_src_data) + swsData.resize(maxAr); + if (_has_sweep_dest_data) + swdData.resize(maxAr); + if (_has_raster_data) + swrData.resize(maxAr); + } + + MakePointData (true); + MakeEdgeData (true); + MakeSweepDestData (true); + + initialisePointData(); + + for (int i = 0; i < numberOfPoints(); i++) { + _pts[i].x = pData[i].rx; + _pts[i].oldDegree = getPoint(i).totalDegree(); + } + + for (int i = 0; i < a->numberOfEdges(); i++) + { + eData[i].rdx = pData[getEdge(i).en].rx - pData[getEdge(i).st].rx; + eData[i].weight = 1; + _aretes[i].dx = eData[i].rdx; + } + + SortPointsRounded (); + + _need_edges_sorting = true; + GetWindings (this, NULL, bool_op_union, true); + +// Plot(341,56,8,400,400,true,true,false,true); + for (int i = 0; i < numberOfEdges(); i++) + { + swdData[i].leW %= 2; + swdData[i].riW %= 2; + if (swdData[i].leW < 0) + swdData[i].leW = -swdData[i].leW; + if (swdData[i].riW < 0) + swdData[i].riW = -swdData[i].riW; + if (swdData[i].leW > 0 && swdData[i].riW <= 0) + { + eData[i].weight = 1; + } + else if (swdData[i].leW <= 0 && swdData[i].riW > 0) + { + Inverse (i); + eData[i].weight = 1; + } + else + { + eData[i].weight = 0; + SubEdge (i); + i--; + } + } + + MakePointData (false); + MakeEdgeData (false); + MakeSweepDestData (false); + + if (directedEulerian(this) == false) + { +// printf( "pas euclidian2"); + _pts.clear(); + _aretes.clear(); + return shape_euler_err; + } + + type = shape_polygon; + return 0; +} + +int +Shape::ConvertToShape (Shape * a, FillRule directed, bool invert) +{ + Reset (0, 0); + + if (a->numberOfPoints() <= 1 || a->numberOfEdges() <= 1) { + return 0; + } + + if ( directed != fill_justDont && directedEulerian(a) == false ) { + return shape_input_err; + } + + a->ResetSweep(); + + if (sTree == NULL) { + sTree = new SweepTreeList(a->numberOfEdges()); + } + if (sEvts == NULL) { + sEvts = new SweepEventQueue(a->numberOfEdges()); + } + + MakePointData(true); + MakeEdgeData(true); + MakeSweepSrcData(true); + MakeSweepDestData(true); + MakeBackData(a->_has_back_data); + + a->initialisePointData(); + a->initialiseEdgeData(); + + a->SortPointsRounded(); + + chgts.clear(); + + double lastChange = a->pData[0].rx[1] - 1.0; + int lastChgtPt = 0; + int edgeHead = -1; + Shape *shapeHead = NULL; + + clearIncidenceData(); + + int curAPt = 0; + + while (curAPt < a->numberOfPoints() || sEvts->size() > 0) { + NR::Point ptX; + double ptL, ptR; + SweepTree *intersL = NULL; + SweepTree *intersR = NULL; + int nPt = -1; + Shape *ptSh = NULL; + bool isIntersection = false; + if (sEvts->peek(intersL, intersR, ptX, ptL, ptR)) + { + if (a->pData[curAPt].pending > 0 + || (a->pData[curAPt].rx[1] > ptX[1] + || (a->pData[curAPt].rx[1] == ptX[1] + && a->pData[curAPt].rx[0] > ptX[0]))) + { + /* FIXME: could just be pop? */ + sEvts->extract(intersL, intersR, ptX, ptL, ptR); + isIntersection = true; + } + else + { + nPt = curAPt++; + ptSh = a; + ptX = ptSh->pData[nPt].rx; + isIntersection = false; + } + } + else + { + nPt = curAPt++; + ptSh = a; + ptX = ptSh->pData[nPt].rx; + isIntersection = false; + } + + if (isIntersection == false) + { + if (ptSh->getPoint(nPt).dI == 0 && ptSh->getPoint(nPt).dO == 0) + continue; + } + + NR::Point rPtX; + rPtX[0]= Round (ptX[0]); + rPtX[1]= Round (ptX[1]); + int lastPointNo = -1; + lastPointNo = AddPoint (rPtX); + pData[lastPointNo].rx = rPtX; + + if (rPtX[1] > lastChange) + { + int lastI = AssemblePoints (lastChgtPt, lastPointNo); + + Shape *curSh = shapeHead; + int curBo = edgeHead; + while (curSh) + { + curSh->swsData[curBo].leftRnd = + pData[curSh->swsData[curBo].leftRnd].newInd; + curSh->swsData[curBo].rightRnd = + pData[curSh->swsData[curBo].rightRnd].newInd; + + Shape *neSh = curSh->swsData[curBo].nextSh; + curBo = curSh->swsData[curBo].nextBo; + curSh = neSh; + } + + for (unsigned int i = 0; i < chgts.size(); i++) + { + chgts[i].ptNo = pData[chgts[i].ptNo].newInd; + if (chgts[i].type == 0) + { + if (chgts[i].src->getEdge(chgts[i].bord).st < + chgts[i].src->getEdge(chgts[i].bord).en) + { + chgts[i].src->swsData[chgts[i].bord].stPt = + chgts[i].ptNo; + } + else + { + chgts[i].src->swsData[chgts[i].bord].enPt = + chgts[i].ptNo; + } + } + else if (chgts[i].type == 1) + { + if (chgts[i].src->getEdge(chgts[i].bord).st > + chgts[i].src->getEdge(chgts[i].bord).en) + { + chgts[i].src->swsData[chgts[i].bord].stPt = + chgts[i].ptNo; + } + else + { + chgts[i].src->swsData[chgts[i].bord].enPt = + chgts[i].ptNo; + } + } + } + + CheckAdjacencies (lastI, lastChgtPt, shapeHead, edgeHead); + + CheckEdges (lastI, lastChgtPt, a, NULL, bool_op_union); + + for (int i = lastChgtPt; i < lastI; i++) { + if (pData[i].askForWindingS) { + Shape *windS = pData[i].askForWindingS; + int windB = pData[i].askForWindingB; + pData[i].nextLinkedPoint = windS->swsData[windB].firstLinkedPoint; + windS->swsData[windB].firstLinkedPoint = i; + } + } + + if (lastI < lastPointNo) { + _pts[lastI] = getPoint(lastPointNo); + pData[lastI] = pData[lastPointNo]; + } + lastPointNo = lastI; + _pts.resize(lastI + 1); + + lastChgtPt = lastPointNo; + lastChange = rPtX[1]; + chgts.clear(); + edgeHead = -1; + shapeHead = NULL; + } + + + if (isIntersection) + { +// printf("(%i %i [%i %i]) ",intersL->bord,intersR->bord,intersL->startPoint,intersR->startPoint); + intersL->RemoveEvent (*sEvts, LEFT); + intersR->RemoveEvent (*sEvts, RIGHT); + + AddChgt (lastPointNo, lastChgtPt, shapeHead, edgeHead, INTERSECTION, + intersL->src, intersL->bord, intersR->src, intersR->bord); + + intersL->SwapWithRight (*sTree, *sEvts); + + TesteIntersection (intersL, LEFT, false); + TesteIntersection (intersR, RIGHT, false); + } + else + { + int cb; + + int nbUp = 0, nbDn = 0; + int upNo = -1, dnNo = -1; + cb = ptSh->getPoint(nPt).incidentEdge[FIRST]; + while (cb >= 0 && cb < ptSh->numberOfEdges()) + { + if ((ptSh->getEdge(cb).st < ptSh->getEdge(cb).en + && nPt == ptSh->getEdge(cb).en) + || (ptSh->getEdge(cb).st > ptSh->getEdge(cb).en + && nPt == ptSh->getEdge(cb).st)) + { + upNo = cb; + nbUp++; + } + if ((ptSh->getEdge(cb).st > ptSh->getEdge(cb).en + && nPt == ptSh->getEdge(cb).en) + || (ptSh->getEdge(cb).st < ptSh->getEdge(cb).en + && nPt == ptSh->getEdge(cb).st)) + { + dnNo = cb; + nbDn++; + } + cb = ptSh->NextAt (nPt, cb); + } + + if (nbDn <= 0) + { + upNo = -1; + } + if (upNo >= 0 && (SweepTree *) ptSh->swsData[upNo].misc == NULL) + { + upNo = -1; + } + + bool doWinding = true; + + if (nbUp > 0) + { + cb = ptSh->getPoint(nPt).incidentEdge[FIRST]; + while (cb >= 0 && cb < ptSh->numberOfEdges()) + { + if ((ptSh->getEdge(cb).st < ptSh->getEdge(cb).en + && nPt == ptSh->getEdge(cb).en) + || (ptSh->getEdge(cb).st > ptSh->getEdge(cb).en + && nPt == ptSh->getEdge(cb).st)) + { + if (cb != upNo) + { + SweepTree *node = + (SweepTree *) ptSh->swsData[cb].misc; + if (node == NULL) + { + } + else + { + AddChgt (lastPointNo, lastChgtPt, shapeHead, + edgeHead, EDGE_REMOVED, node->src, node->bord, + NULL, -1); + ptSh->swsData[cb].misc = NULL; + + int onLeftB = -1, onRightB = -1; + Shape *onLeftS = NULL; + Shape *onRightS = NULL; + if (node->elem[LEFT]) + { + onLeftB = + (static_cast < + SweepTree * >(node->elem[LEFT]))->bord; + onLeftS = + (static_cast < + SweepTree * >(node->elem[LEFT]))->src; + } + if (node->elem[RIGHT]) + { + onRightB = + (static_cast < + SweepTree * >(node->elem[RIGHT]))->bord; + onRightS = + (static_cast < + SweepTree * >(node->elem[RIGHT]))->src; + } + + node->Remove (*sTree, *sEvts, true); + if (onLeftS && onRightS) + { + SweepTree *onLeft = + (SweepTree *) onLeftS->swsData[onLeftB]. + misc; + if (onLeftS == ptSh + && (onLeftS->getEdge(onLeftB).en == nPt + || onLeftS->getEdge(onLeftB).st == + nPt)) + { + } + else + { + if (onRightS == ptSh + && (onRightS->getEdge(onRightB).en == + nPt + || onRightS->getEdge(onRightB). + st == nPt)) + { + } + else + { + TesteIntersection (onLeft, RIGHT, false); + } + } + } + } + } + } + cb = ptSh->NextAt (nPt, cb); + } + } + + // traitement du "upNo devient dnNo" + SweepTree *insertionNode = NULL; + if (dnNo >= 0) + { + if (upNo >= 0) + { + SweepTree *node = (SweepTree *) ptSh->swsData[upNo].misc; + + AddChgt (lastPointNo, lastChgtPt, shapeHead, edgeHead, EDGE_REMOVED, + node->src, node->bord, NULL, -1); + + ptSh->swsData[upNo].misc = NULL; + + node->RemoveEvents (*sEvts); + node->ConvertTo (ptSh, dnNo, 1, lastPointNo); + ptSh->swsData[dnNo].misc = node; + TesteIntersection (node, RIGHT, false); + TesteIntersection (node, LEFT, false); + insertionNode = node; + + ptSh->swsData[dnNo].curPoint = lastPointNo; + AddChgt (lastPointNo, lastChgtPt, shapeHead, edgeHead, EDGE_INSERTED, + node->src, node->bord, NULL, -1); + } + else + { + SweepTree *node = sTree->add(ptSh, dnNo, 1, lastPointNo, this); + ptSh->swsData[dnNo].misc = node; + node->Insert (*sTree, *sEvts, this, lastPointNo, true); + if (doWinding) + { + SweepTree *myLeft = + static_cast < SweepTree * >(node->elem[LEFT]); + if (myLeft) + { + pData[lastPointNo].askForWindingS = myLeft->src; + pData[lastPointNo].askForWindingB = myLeft->bord; + } + else + { + pData[lastPointNo].askForWindingB = -1; + } + doWinding = false; + } + TesteIntersection (node, RIGHT, false); + TesteIntersection (node, LEFT, false); + insertionNode = node; + + ptSh->swsData[dnNo].curPoint = lastPointNo; + AddChgt (lastPointNo, lastChgtPt, shapeHead, edgeHead, EDGE_INSERTED, + node->src, node->bord, NULL, -1); + } + } + + if (nbDn > 1) + { // si nbDn == 1 , alors dnNo a deja ete traite + cb = ptSh->getPoint(nPt).incidentEdge[FIRST]; + while (cb >= 0 && cb < ptSh->numberOfEdges()) + { + if ((ptSh->getEdge(cb).st > ptSh->getEdge(cb).en + && nPt == ptSh->getEdge(cb).en) + || (ptSh->getEdge(cb).st < ptSh->getEdge(cb).en + && nPt == ptSh->getEdge(cb).st)) + { + if (cb != dnNo) + { + SweepTree *node = sTree->add(ptSh, cb, 1, lastPointNo, this); + ptSh->swsData[cb].misc = node; + node->InsertAt (*sTree, *sEvts, this, insertionNode, + nPt, true); + if (doWinding) + { + SweepTree *myLeft = + static_cast < SweepTree * >(node->elem[LEFT]); + if (myLeft) + { + pData[lastPointNo].askForWindingS = + myLeft->src; + pData[lastPointNo].askForWindingB = + myLeft->bord; + } + else + { + pData[lastPointNo].askForWindingB = -1; + } + doWinding = false; + } + TesteIntersection (node, RIGHT, false); + TesteIntersection (node, LEFT, false); + + ptSh->swsData[cb].curPoint = lastPointNo; + AddChgt (lastPointNo, lastChgtPt, shapeHead, + edgeHead, EDGE_INSERTED, node->src, node->bord, NULL, + -1); + } + } + cb = ptSh->NextAt (nPt, cb); + } + } + } + } + { + int lastI = AssemblePoints (lastChgtPt, numberOfPoints()); + + + Shape *curSh = shapeHead; + int curBo = edgeHead; + while (curSh) + { + curSh->swsData[curBo].leftRnd = + pData[curSh->swsData[curBo].leftRnd].newInd; + curSh->swsData[curBo].rightRnd = + pData[curSh->swsData[curBo].rightRnd].newInd; + + Shape *neSh = curSh->swsData[curBo].nextSh; + curBo = curSh->swsData[curBo].nextBo; + curSh = neSh; + } + + for (unsigned int i = 0; i < chgts.size(); i++) + { + chgts[i].ptNo = pData[chgts[i].ptNo].newInd; + if (chgts[i].type == 0) + { + if (chgts[i].src->getEdge(chgts[i].bord).st < + chgts[i].src->getEdge(chgts[i].bord).en) + { + chgts[i].src->swsData[chgts[i].bord].stPt = chgts[i].ptNo; + } + else + { + chgts[i].src->swsData[chgts[i].bord].enPt = chgts[i].ptNo; + } + } + else if (chgts[i].type == 1) + { + if (chgts[i].src->getEdge(chgts[i].bord).st > + chgts[i].src->getEdge(chgts[i].bord).en) + { + chgts[i].src->swsData[chgts[i].bord].stPt = chgts[i].ptNo; + } + else + { + chgts[i].src->swsData[chgts[i].bord].enPt = chgts[i].ptNo; + } + } + } + + CheckAdjacencies (lastI, lastChgtPt, shapeHead, edgeHead); + + CheckEdges (lastI, lastChgtPt, a, NULL, bool_op_union); + + for (int i = lastChgtPt; i < lastI; i++) + { + if (pData[i].askForWindingS) + { + Shape *windS = pData[i].askForWindingS; + int windB = pData[i].askForWindingB; + pData[i].nextLinkedPoint = windS->swsData[windB].firstLinkedPoint; + windS->swsData[windB].firstLinkedPoint = i; + } + } + + _pts.resize(lastI); + + edgeHead = -1; + shapeHead = NULL; + } + + chgts.clear(); + +// Plot (98.0, 112.0, 8.0, 400.0, 400.0, true, true, true, true); +// Plot(200.0,200.0,2.0,400.0,400.0,true,true,true,true); + + // AssemblePoints(a); + +// GetAdjacencies(a); + +// MakeAretes(a); + clearIncidenceData(); + + AssembleAretes (directed); + +// Plot (98.0, 112.0, 8.0, 400.0, 400.0, true, true, true, true); + + for (int i = 0; i < numberOfPoints(); i++) + { + _pts[i].oldDegree = getPoint(i).totalDegree(); + } +// Validate(); + + _need_edges_sorting = true; + if ( directed == fill_justDont ) { + SortEdges(); + } else { + GetWindings (a); + } +// Plot (98.0, 112.0, 8.0, 400.0, 400.0, true, true, true, true); +// if ( doDebug ) { +// a->CalcBBox(); +// a->Plot(a->leftX,a->topY,32.0,0.0,0.0,true,true,true,true,"orig.svg"); +// Plot(a->leftX,a->topY,32.0,0.0,0.0,true,true,true,true,"winded.svg"); +// } + if (directed == fill_positive) + { + if (invert) + { + for (int i = 0; i < numberOfEdges(); i++) + { + if (swdData[i].leW < 0 && swdData[i].riW >= 0) + { + eData[i].weight = 1; + } + else if (swdData[i].leW >= 0 && swdData[i].riW < 0) + { + Inverse (i); + eData[i].weight = 1; + } + else + { + eData[i].weight = 0; + SubEdge (i); + i--; + } + } + } + else + { + for (int i = 0; i < numberOfEdges(); i++) + { + if (swdData[i].leW > 0 && swdData[i].riW <= 0) + { + eData[i].weight = 1; + } + else if (swdData[i].leW <= 0 && swdData[i].riW > 0) + { + Inverse (i); + eData[i].weight = 1; + } + else + { + eData[i].weight = 0; + SubEdge (i); + i--; + } + } + } + } + else if (directed == fill_nonZero) + { + if (invert) + { + for (int i = 0; i < numberOfEdges(); i++) + { + if (swdData[i].leW < 0 && swdData[i].riW == 0) + { + eData[i].weight = 1; + } + else if (swdData[i].leW > 0 && swdData[i].riW == 0) + { + eData[i].weight = 1; + } + else if (swdData[i].leW == 0 && swdData[i].riW < 0) + { + Inverse (i); + eData[i].weight = 1; + } + else if (swdData[i].leW == 0 && swdData[i].riW > 0) + { + Inverse (i); + eData[i].weight = 1; + } + else + { + eData[i].weight = 0; + SubEdge (i); + i--; + } + } + } + else + { + for (int i = 0; i < numberOfEdges(); i++) + { + if (swdData[i].leW > 0 && swdData[i].riW == 0) + { + eData[i].weight = 1; + } + else if (swdData[i].leW < 0 && swdData[i].riW == 0) + { + eData[i].weight = 1; + } + else if (swdData[i].leW == 0 && swdData[i].riW > 0) + { + Inverse (i); + eData[i].weight = 1; + } + else if (swdData[i].leW == 0 && swdData[i].riW < 0) + { + Inverse (i); + eData[i].weight = 1; + } + else + { + eData[i].weight = 0; + SubEdge (i); + i--; + } + } + } + } + else if (directed == fill_oddEven) + { + for (int i = 0; i < numberOfEdges(); i++) + { + swdData[i].leW %= 2; + swdData[i].riW %= 2; + if (swdData[i].leW < 0) + swdData[i].leW = -swdData[i].leW; + if (swdData[i].riW < 0) + swdData[i].riW = -swdData[i].riW; + if (swdData[i].leW > 0 && swdData[i].riW <= 0) + { + eData[i].weight = 1; + } + else if (swdData[i].leW <= 0 && swdData[i].riW > 0) + { + Inverse (i); + eData[i].weight = 1; + } + else + { + eData[i].weight = 0; + SubEdge (i); + i--; + } + } + } else if ( directed == fill_justDont ) { + for (int i=0;iCleanupSweep (); + _pts.clear(); + _aretes.clear(); + return shape_euler_err; + } + } + MakePointData (false); + MakeEdgeData (false); + MakeSweepSrcData (false); + MakeSweepDestData (false); + a->CleanupSweep (); + type = shape_polygon; + return 0; +} + +// technically it's just a ConvertToShape() on 2 polygons at the same time, and different rules +// for choosing the edges according to their winding numbers. +// probably one of the biggest function i ever wrote. +int +Shape::Booleen (Shape * a, Shape * b, BooleanOp mod,int cutPathID) +{ + if (a == b || a == NULL || b == NULL) + return shape_input_err; + Reset (0, 0); + if (a->numberOfPoints() <= 1 || a->numberOfEdges() <= 1) + return 0; + if (b->numberOfPoints() <= 1 || b->numberOfEdges() <= 1) + return 0; + if ( mod == bool_op_cut ) { + } else if ( mod == bool_op_slice ) { + } else { + if (a->type != shape_polygon) + return shape_input_err; + if (b->type != shape_polygon) + return shape_input_err; + } + + a->ResetSweep (); + b->ResetSweep (); + + if (sTree == NULL) { + sTree = new SweepTreeList(a->numberOfEdges() + b->numberOfEdges()); + } + if (sEvts == NULL) { + sEvts = new SweepEventQueue(a->numberOfEdges() + b->numberOfEdges()); + } + + MakePointData (true); + MakeEdgeData (true); + MakeSweepSrcData (true); + MakeSweepDestData (true); + if (a->hasBackData () && b->hasBackData ()) + { + MakeBackData (true); + } + else + { + MakeBackData (false); + } + + a->initialisePointData(); + b->initialisePointData(); + + a->initialiseEdgeData(); + b->initialiseEdgeData(); + + a->SortPointsRounded (); + b->SortPointsRounded (); + + chgts.clear(); + + double lastChange = + (a->pData[0].rx[1] < + b->pData[0].rx[1]) ? a->pData[0].rx[1] - 1.0 : b->pData[0].rx[1] - 1.0; + int lastChgtPt = 0; + int edgeHead = -1; + Shape *shapeHead = NULL; + + clearIncidenceData(); + + int curAPt = 0; + int curBPt = 0; + + while (curAPt < a->numberOfPoints() || curBPt < b->numberOfPoints() || sEvts->size() > 0) + { +/* for (int i=0;ibord,sEvts.events[i].rightSweep->bord); // localizing ok + } + // cout << endl; + if ( sTree.racine ) { + SweepTree* ct=static_cast (sTree.racine->Leftmost()); + while ( ct ) { + printf("%i %i [%i\n",ct->bord,ct->startPoint,(ct->src==a)?1:0); + ct=static_cast (ct->elem[RIGHT]); + } + } + printf("\n");*/ + + NR::Point ptX; + double ptL, ptR; + SweepTree *intersL = NULL; + SweepTree *intersR = NULL; + int nPt = -1; + Shape *ptSh = NULL; + bool isIntersection = false; + + if (sEvts->peek(intersL, intersR, ptX, ptL, ptR)) + { + if (curAPt < a->numberOfPoints()) + { + if (curBPt < b->numberOfPoints()) + { + if (a->pData[curAPt].rx[1] < b->pData[curBPt].rx[1] + || (a->pData[curAPt].rx[1] == b->pData[curBPt].rx[1] + && a->pData[curAPt].rx[0] < b->pData[curBPt].rx[0])) + { + if (a->pData[curAPt].pending > 0 + || (a->pData[curAPt].rx[1] > ptX[1] + || (a->pData[curAPt].rx[1] == ptX[1] + && a->pData[curAPt].rx[0] > ptX[0]))) + { + /* FIXME: could be pop? */ + sEvts->extract(intersL, intersR, ptX, ptL, ptR); + isIntersection = true; + } + else + { + nPt = curAPt++; + ptSh = a; + ptX = ptSh->pData[nPt].rx; + isIntersection = false; + } + } + else + { + if (b->pData[curBPt].pending > 0 + || (b->pData[curBPt].rx[1] > ptX[1] + || (b->pData[curBPt].rx[1] == ptX[1] + && b->pData[curBPt].rx[0] > ptX[0]))) + { + /* FIXME: could be pop? */ + sEvts->extract(intersL, intersR, ptX, ptL, ptR); + isIntersection = true; + } + else + { + nPt = curBPt++; + ptSh = b; + ptX = ptSh->pData[nPt].rx; + isIntersection = false; + } + } + } + else + { + if (a->pData[curAPt].pending > 0 + || (a->pData[curAPt].rx[1] > ptX[1] + || (a->pData[curAPt].rx[1] == ptX[1] + && a->pData[curAPt].rx[0] > ptX[0]))) + { + /* FIXME: could be pop? */ + sEvts->extract(intersL, intersR, ptX, ptL, ptR); + isIntersection = true; + } + else + { + nPt = curAPt++; + ptSh = a; + ptX = ptSh->pData[nPt].rx; + isIntersection = false; + } + } + } + else + { + if (b->pData[curBPt].pending > 0 + || (b->pData[curBPt].rx[1] > ptX[1] + || (b->pData[curBPt].rx[1] == ptX[1] + && b->pData[curBPt].rx[0] > ptX[0]))) + { + /* FIXME: could be pop? */ + sEvts->extract(intersL, intersR, ptX, ptL, ptR); + isIntersection = true; + } + else + { + nPt = curBPt++; + ptSh = b; + ptX = ptSh->pData[nPt].rx; + isIntersection = false; + } + } + } + else + { + if (curAPt < a->numberOfPoints()) + { + if (curBPt < b->numberOfPoints()) + { + if (a->pData[curAPt].rx[1] < b->pData[curBPt].rx[1] + || (a->pData[curAPt].rx[1] == b->pData[curBPt].rx[1] + && a->pData[curAPt].rx[0] < b->pData[curBPt].rx[0])) + { + nPt = curAPt++; + ptSh = a; + } + else + { + nPt = curBPt++; + ptSh = b; + } + } + else + { + nPt = curAPt++; + ptSh = a; + } + } + else + { + nPt = curBPt++; + ptSh = b; + } + ptX = ptSh->pData[nPt].rx; + isIntersection = false; + } + + if (isIntersection == false) + { + if (ptSh->getPoint(nPt).dI == 0 && ptSh->getPoint(nPt).dO == 0) + continue; + } + + NR::Point rPtX; + rPtX[0]= Round (ptX[0]); + rPtX[1]= Round (ptX[1]); + int lastPointNo = -1; + lastPointNo = AddPoint (rPtX); + pData[lastPointNo].rx = rPtX; + + if (rPtX[1] > lastChange) + { + int lastI = AssemblePoints (lastChgtPt, lastPointNo); + + + Shape *curSh = shapeHead; + int curBo = edgeHead; + while (curSh) + { + curSh->swsData[curBo].leftRnd = + pData[curSh->swsData[curBo].leftRnd].newInd; + curSh->swsData[curBo].rightRnd = + pData[curSh->swsData[curBo].rightRnd].newInd; + + Shape *neSh = curSh->swsData[curBo].nextSh; + curBo = curSh->swsData[curBo].nextBo; + curSh = neSh; + } + + for (unsigned int i = 0; i < chgts.size(); i++) + { + chgts[i].ptNo = pData[chgts[i].ptNo].newInd; + if (chgts[i].type == 0) + { + if (chgts[i].src->getEdge(chgts[i].bord).st < + chgts[i].src->getEdge(chgts[i].bord).en) + { + chgts[i].src->swsData[chgts[i].bord].stPt = + chgts[i].ptNo; + } + else + { + chgts[i].src->swsData[chgts[i].bord].enPt = + chgts[i].ptNo; + } + } + else if (chgts[i].type == 1) + { + if (chgts[i].src->getEdge(chgts[i].bord).st > + chgts[i].src->getEdge(chgts[i].bord).en) + { + chgts[i].src->swsData[chgts[i].bord].stPt = + chgts[i].ptNo; + } + else + { + chgts[i].src->swsData[chgts[i].bord].enPt = + chgts[i].ptNo; + } + } + } + + CheckAdjacencies (lastI, lastChgtPt, shapeHead, edgeHead); + + CheckEdges (lastI, lastChgtPt, a, b, mod); + + for (int i = lastChgtPt; i < lastI; i++) + { + if (pData[i].askForWindingS) + { + Shape *windS = pData[i].askForWindingS; + int windB = pData[i].askForWindingB; + pData[i].nextLinkedPoint = + windS->swsData[windB].firstLinkedPoint; + windS->swsData[windB].firstLinkedPoint = i; + } + } + + if (lastI < lastPointNo) + { + _pts[lastI] = getPoint(lastPointNo); + pData[lastI] = pData[lastPointNo]; + } + lastPointNo = lastI; + _pts.resize(lastI + 1); + + lastChgtPt = lastPointNo; + lastChange = rPtX[1]; + chgts.clear(); + edgeHead = -1; + shapeHead = NULL; + } + + + if (isIntersection) + { + // les 2 events de part et d'autre de l'intersection + // (celui de l'intersection a deja ete depile) + intersL->RemoveEvent (*sEvts, LEFT); + intersR->RemoveEvent (*sEvts, RIGHT); + + AddChgt (lastPointNo, lastChgtPt, shapeHead, edgeHead, INTERSECTION, + intersL->src, intersL->bord, intersR->src, intersR->bord); + + intersL->SwapWithRight (*sTree, *sEvts); + + TesteIntersection (intersL, LEFT, true); + TesteIntersection (intersR, RIGHT, true); + } + else + { + int cb; + + int nbUp = 0, nbDn = 0; + int upNo = -1, dnNo = -1; + cb = ptSh->getPoint(nPt).incidentEdge[FIRST]; + while (cb >= 0 && cb < ptSh->numberOfEdges()) + { + if ((ptSh->getEdge(cb).st < ptSh->getEdge(cb).en + && nPt == ptSh->getEdge(cb).en) + || (ptSh->getEdge(cb).st > ptSh->getEdge(cb).en + && nPt == ptSh->getEdge(cb).st)) + { + upNo = cb; + nbUp++; + } + if ((ptSh->getEdge(cb).st > ptSh->getEdge(cb).en + && nPt == ptSh->getEdge(cb).en) + || (ptSh->getEdge(cb).st < ptSh->getEdge(cb).en + && nPt == ptSh->getEdge(cb).st)) + { + dnNo = cb; + nbDn++; + } + cb = ptSh->NextAt (nPt, cb); + } + + if (nbDn <= 0) + { + upNo = -1; + } + if (upNo >= 0 && (SweepTree *) ptSh->swsData[upNo].misc == NULL) + { + upNo = -1; + } + +// upNo=-1; + + bool doWinding = true; + + if (nbUp > 0) + { + cb = ptSh->getPoint(nPt).incidentEdge[FIRST]; + while (cb >= 0 && cb < ptSh->numberOfEdges()) + { + if ((ptSh->getEdge(cb).st < ptSh->getEdge(cb).en + && nPt == ptSh->getEdge(cb).en) + || (ptSh->getEdge(cb).st > ptSh->getEdge(cb).en + && nPt == ptSh->getEdge(cb).st)) + { + if (cb != upNo) + { + SweepTree *node = + (SweepTree *) ptSh->swsData[cb].misc; + if (node == NULL) + { + } + else + { + AddChgt (lastPointNo, lastChgtPt, shapeHead, + edgeHead, EDGE_REMOVED, node->src, node->bord, + NULL, -1); + ptSh->swsData[cb].misc = NULL; + + int onLeftB = -1, onRightB = -1; + Shape *onLeftS = NULL; + Shape *onRightS = NULL; + if (node->elem[LEFT]) + { + onLeftB = + (static_cast < + SweepTree * >(node->elem[LEFT]))->bord; + onLeftS = + (static_cast < + SweepTree * >(node->elem[LEFT]))->src; + } + if (node->elem[RIGHT]) + { + onRightB = + (static_cast < + SweepTree * >(node->elem[RIGHT]))->bord; + onRightS = + (static_cast < + SweepTree * >(node->elem[RIGHT]))->src; + } + + node->Remove (*sTree, *sEvts, true); + if (onLeftS && onRightS) + { + SweepTree *onLeft = + (SweepTree *) onLeftS->swsData[onLeftB]. + misc; +// SweepTree* onRight=(SweepTree*)onRightS->swsData[onRightB].misc; + if (onLeftS == ptSh + && (onLeftS->getEdge(onLeftB).en == nPt + || onLeftS->getEdge(onLeftB).st == + nPt)) + { + } + else + { + if (onRightS == ptSh + && (onRightS->getEdge(onRightB).en == + nPt + || onRightS->getEdge(onRightB). + st == nPt)) + { + } + else + { + TesteIntersection (onLeft, RIGHT, true); + } + } + } + } + } + } + cb = ptSh->NextAt (nPt, cb); + } + } + + // traitement du "upNo devient dnNo" + SweepTree *insertionNode = NULL; + if (dnNo >= 0) + { + if (upNo >= 0) + { + SweepTree *node = (SweepTree *) ptSh->swsData[upNo].misc; + + AddChgt (lastPointNo, lastChgtPt, shapeHead, edgeHead, EDGE_REMOVED, + node->src, node->bord, NULL, -1); + + ptSh->swsData[upNo].misc = NULL; + + node->RemoveEvents (*sEvts); + node->ConvertTo (ptSh, dnNo, 1, lastPointNo); + ptSh->swsData[dnNo].misc = node; + TesteIntersection (node, RIGHT, true); + TesteIntersection (node, LEFT, true); + insertionNode = node; + + ptSh->swsData[dnNo].curPoint = lastPointNo; + + AddChgt (lastPointNo, lastChgtPt, shapeHead, edgeHead, EDGE_INSERTED, + node->src, node->bord, NULL, -1); + } + else + { + SweepTree *node = sTree->add(ptSh, dnNo, 1, lastPointNo, this); + ptSh->swsData[dnNo].misc = node; + node->Insert (*sTree, *sEvts, this, lastPointNo, true); + + if (doWinding) + { + SweepTree *myLeft = + static_cast < SweepTree * >(node->elem[LEFT]); + if (myLeft) + { + pData[lastPointNo].askForWindingS = myLeft->src; + pData[lastPointNo].askForWindingB = myLeft->bord; + } + else + { + pData[lastPointNo].askForWindingB = -1; + } + doWinding = false; + } + + TesteIntersection (node, RIGHT, true); + TesteIntersection (node, LEFT, true); + insertionNode = node; + + ptSh->swsData[dnNo].curPoint = lastPointNo; + + AddChgt (lastPointNo, lastChgtPt, shapeHead, edgeHead, EDGE_INSERTED, + node->src, node->bord, NULL, -1); + } + } + + if (nbDn > 1) + { // si nbDn == 1 , alors dnNo a deja ete traite + cb = ptSh->getPoint(nPt).incidentEdge[FIRST]; + while (cb >= 0 && cb < ptSh->numberOfEdges()) + { + if ((ptSh->getEdge(cb).st > ptSh->getEdge(cb).en + && nPt == ptSh->getEdge(cb).en) + || (ptSh->getEdge(cb).st < ptSh->getEdge(cb).en + && nPt == ptSh->getEdge(cb).st)) + { + if (cb != dnNo) + { + SweepTree *node = sTree->add(ptSh, cb, 1, lastPointNo, this); + ptSh->swsData[cb].misc = node; +// node->Insert(sTree,*sEvts,this,lastPointNo,true); + node->InsertAt (*sTree, *sEvts, this, insertionNode, + nPt, true); + + if (doWinding) + { + SweepTree *myLeft = + static_cast < SweepTree * >(node->elem[LEFT]); + if (myLeft) + { + pData[lastPointNo].askForWindingS = + myLeft->src; + pData[lastPointNo].askForWindingB = + myLeft->bord; + } + else + { + pData[lastPointNo].askForWindingB = -1; + } + doWinding = false; + } + + TesteIntersection (node, RIGHT, true); + TesteIntersection (node, LEFT, true); + + ptSh->swsData[cb].curPoint = lastPointNo; + + AddChgt (lastPointNo, lastChgtPt, shapeHead, + edgeHead, EDGE_INSERTED, node->src, node->bord, NULL, + -1); + } + } + cb = ptSh->NextAt (nPt, cb); + } + } + } + } + { + int lastI = AssemblePoints (lastChgtPt, numberOfPoints()); + + + Shape *curSh = shapeHead; + int curBo = edgeHead; + while (curSh) + { + curSh->swsData[curBo].leftRnd = + pData[curSh->swsData[curBo].leftRnd].newInd; + curSh->swsData[curBo].rightRnd = + pData[curSh->swsData[curBo].rightRnd].newInd; + + Shape *neSh = curSh->swsData[curBo].nextSh; + curBo = curSh->swsData[curBo].nextBo; + curSh = neSh; + } + + /* FIXME: this kind of code seems to appear frequently */ + for (unsigned int i = 0; i < chgts.size(); i++) + { + chgts[i].ptNo = pData[chgts[i].ptNo].newInd; + if (chgts[i].type == 0) + { + if (chgts[i].src->getEdge(chgts[i].bord).st < + chgts[i].src->getEdge(chgts[i].bord).en) + { + chgts[i].src->swsData[chgts[i].bord].stPt = chgts[i].ptNo; + } + else + { + chgts[i].src->swsData[chgts[i].bord].enPt = chgts[i].ptNo; + } + } + else if (chgts[i].type == 1) + { + if (chgts[i].src->getEdge(chgts[i].bord).st > + chgts[i].src->getEdge(chgts[i].bord).en) + { + chgts[i].src->swsData[chgts[i].bord].stPt = chgts[i].ptNo; + } + else + { + chgts[i].src->swsData[chgts[i].bord].enPt = chgts[i].ptNo; + } + } + } + + CheckAdjacencies (lastI, lastChgtPt, shapeHead, edgeHead); + + CheckEdges (lastI, lastChgtPt, a, b, mod); + + for (int i = lastChgtPt; i < lastI; i++) + { + if (pData[i].askForWindingS) + { + Shape *windS = pData[i].askForWindingS; + int windB = pData[i].askForWindingB; + pData[i].nextLinkedPoint = windS->swsData[windB].firstLinkedPoint; + windS->swsData[windB].firstLinkedPoint = i; + } + } + + _pts.resize(lastI); + + edgeHead = -1; + shapeHead = NULL; + } + + chgts.clear(); + clearIncidenceData(); + +// Plot(190,70,6,400,400,true,false,true,true); + + if ( mod == bool_op_cut ) { + AssembleAretes (fill_justDont); + // dupliquer les aretes de la coupure + int i=numberOfEdges()-1; + for (;i>=0;i--) { + if ( ebData[i].pathID == cutPathID ) { + // on duplique + int nEd=AddEdge(getEdge(i).en,getEdge(i).st); + ebData[nEd].pathID=cutPathID; + ebData[nEd].pieceID=ebData[i].pieceID; + ebData[nEd].tSt=ebData[i].tEn; + ebData[nEd].tEn=ebData[i].tSt; + eData[nEd].weight=eData[i].weight; + // lui donner les firstlinkedpoitn si besoin + if ( getEdge(i).en >= getEdge(i).st ) { + int cp = swsData[i].firstLinkedPoint; + while (cp >= 0) { + pData[cp].askForWindingB = nEd; + cp = pData[cp].nextLinkedPoint; + } + swsData[nEd].firstLinkedPoint = swsData[i].firstLinkedPoint; + swsData[i].firstLinkedPoint=-1; + } + } + } + } else if ( mod == bool_op_slice ) { + } else { + AssembleAretes (); + } + + for (int i = 0; i < numberOfPoints(); i++) + { + _pts[i].oldDegree = getPoint(i).totalDegree(); + } + + _need_edges_sorting = true; + if ( mod == bool_op_slice ) { + } else { + GetWindings (a, b, mod, false); + } +// Plot(190,70,6,400,400,true,true,true,true); + + if (mod == bool_op_symdiff) + { + for (int i = 0; i < numberOfEdges(); i++) + { + swdData[i].leW = swdData[i].leW % 2; + if (swdData[i].leW < 0) + swdData[i].leW = -swdData[i].leW; + swdData[i].riW = swdData[i].riW; + if (swdData[i].riW < 0) + swdData[i].riW = -swdData[i].riW; + + if (swdData[i].leW > 0 && swdData[i].riW <= 0) + { + eData[i].weight = 1; + } + else if (swdData[i].leW <= 0 && swdData[i].riW > 0) + { + Inverse (i); + eData[i].weight = 1; + } + else + { + eData[i].weight = 0; + SubEdge (i); + i--; + } + } + } + else if (mod == bool_op_union || mod == bool_op_diff) + { + for (int i = 0; i < numberOfEdges(); i++) + { + if (swdData[i].leW > 0 && swdData[i].riW <= 0) + { + eData[i].weight = 1; + } + else if (swdData[i].leW <= 0 && swdData[i].riW > 0) + { + Inverse (i); + eData[i].weight = 1; + } + else + { + eData[i].weight = 0; + SubEdge (i); + i--; + } + } + } + else if (mod == bool_op_inters) + { + for (int i = 0; i < numberOfEdges(); i++) + { + if (swdData[i].leW > 1 && swdData[i].riW <= 1) + { + eData[i].weight = 1; + } + else if (swdData[i].leW <= 1 && swdData[i].riW > 1) + { + Inverse (i); + eData[i].weight = 1; + } + else + { + eData[i].weight = 0; + SubEdge (i); + i--; + } + } + } else if ( mod == bool_op_cut ) { + // inverser les aretes de la coupe au besoin + for (int i=0;i= 0) { + pData[cp].askForWindingB = i; + cp = pData[cp].nextLinkedPoint; + } + } + SwapEdges(i,numberOfEdges()-1); + SubEdge(numberOfEdges()-1); +// SubEdge(i); + i--; + } else if ( ebData[i].pathID == cutPathID ) { + swdData[i].leW=swdData[i].leW%2; + swdData[i].riW=swdData[i].riW%2; + if ( swdData[i].leW < swdData[i].riW ) { + Inverse(i); + } + } + } + } else if ( mod == bool_op_slice ) { + // supprimer les aretes de la coupe + int i=numberOfEdges()-1; + for (;i>=0;i--) { + if ( ebData[i].pathID == cutPathID || getEdge(i).st < 0 || getEdge(i).en < 0 ) { + SubEdge(i); + } + } + } + else + { + for (int i = 0; i < numberOfEdges(); i++) + { + if (swdData[i].leW > 0 && swdData[i].riW <= 0) + { + eData[i].weight = 1; + } + else if (swdData[i].leW <= 0 && swdData[i].riW > 0) + { + Inverse (i); + eData[i].weight = 1; + } + else + { + eData[i].weight = 0; + SubEdge (i); + i--; + } + } + } + + delete sTree; + sTree = NULL; + delete sEvts; + sEvts = NULL; + + if ( mod == bool_op_cut ) { + // on garde le askForWinding + } else { + MakePointData (false); + } + MakeEdgeData (false); + MakeSweepSrcData (false); + MakeSweepDestData (false); + a->CleanupSweep (); + b->CleanupSweep (); + + if (directedEulerian(this) == false) + { +// printf( "pas euclidian2"); + _pts.clear(); + _aretes.clear(); + return shape_euler_err; + } + type = shape_polygon; + return 0; +} + +// frontend to the TesteIntersection() below +void Shape::TesteIntersection(SweepTree *t, Side s, bool onlyDiff) +{ + SweepTree *tt = static_cast(t->elem[s]); + if (tt == NULL) { + return; + } + + SweepTree *a = (s == LEFT) ? tt : t; + SweepTree *b = (s == LEFT) ? t : tt; + + NR::Point atx; + double atl; + double atr; + if (TesteIntersection(a, b, atx, atl, atr, onlyDiff)) { + sEvts->add(a, b, atx, atl, atr); + } +} + +// a crucial piece of code: computing intersections between segments +bool +Shape::TesteIntersection (SweepTree * iL, SweepTree * iR, NR::Point &atx, double &atL, double &atR, bool onlyDiff) +{ + int lSt = iL->src->getEdge(iL->bord).st, lEn = iL->src->getEdge(iL->bord).en; + int rSt = iR->src->getEdge(iR->bord).st, rEn = iR->src->getEdge(iR->bord).en; + NR::Point ldir, rdir; + ldir = iL->src->eData[iL->bord].rdx; + rdir = iR->src->eData[iR->bord].rdx; + // first, a round of checks to quickly dismiss edge which obviously dont intersect, + // such as having disjoint bounding boxes + if (lSt < lEn) + { + } + else + { + int swap = lSt; + lSt = lEn; + lEn = swap; + ldir = -ldir; + } + if (rSt < rEn) + { + } + else + { + int swap = rSt; + rSt = rEn; + rEn = swap; + rdir = -rdir; + } + + if (iL->src->pData[lSt].rx[0] < iL->src->pData[lEn].rx[0]) + { + if (iR->src->pData[rSt].rx[0] < iR->src->pData[rEn].rx[0]) + { + if (iL->src->pData[lSt].rx[0] > iR->src->pData[rEn].rx[0]) + return false; + if (iL->src->pData[lEn].rx[0] < iR->src->pData[rSt].rx[0]) + return false; + } + else + { + if (iL->src->pData[lSt].rx[0] > iR->src->pData[rSt].rx[0]) + return false; + if (iL->src->pData[lEn].rx[0] < iR->src->pData[rEn].rx[0]) + return false; + } + } + else + { + if (iR->src->pData[rSt].rx[0] < iR->src->pData[rEn].rx[0]) + { + if (iL->src->pData[lEn].rx[0] > iR->src->pData[rEn].rx[0]) + return false; + if (iL->src->pData[lSt].rx[0] < iR->src->pData[rSt].rx[0]) + return false; + } + else + { + if (iL->src->pData[lEn].rx[0] > iR->src->pData[rSt].rx[0]) + return false; + if (iL->src->pData[lSt].rx[0] < iR->src->pData[rEn].rx[0]) + return false; + } + } + + double ang = cross (rdir, ldir); +// ang*=iL->src->eData[iL->bord].isqlength; +// ang*=iR->src->eData[iR->bord].isqlength; + if (ang <= 0) return false; // edges in opposite directions: <-left ... right -> + // they can't intersect + + // d'abord tester les bords qui partent d'un meme point + if (iL->src == iR->src && lSt == rSt) + { + if (iL->src == iR->src && lEn == rEn) + return false; // c'est juste un doublon + atx = iL->src->pData[lSt].rx; + atR = atL = -1; + return true; // l'ordre est mauvais + } + if (iL->src == iR->src && lEn == rEn) + return false; // rien a faire=ils vont terminer au meme endroit + + // tester si on est dans une intersection multiple + + if (onlyDiff && iL->src == iR->src) + return false; + + // on reprend les vrais points + lSt = iL->src->getEdge(iL->bord).st; + lEn = iL->src->getEdge(iL->bord).en; + rSt = iR->src->getEdge(iR->bord).st; + rEn = iR->src->getEdge(iR->bord).en; + + // compute intersection (if there is one) + // Boissonat anr Preparata said in one paper that double precision floats were sufficient for get single precision + // coordinates for the intersection, if the endpoints are single precision. i hope they're right... + { + NR::Point sDiff, eDiff; + double slDot, elDot; + double srDot, erDot; + sDiff = iL->src->pData[lSt].rx - iR->src->pData[rSt].rx; + eDiff = iL->src->pData[lEn].rx - iR->src->pData[rSt].rx; + srDot = cross (sDiff,rdir); + erDot = cross (eDiff,rdir); + sDiff = iR->src->pData[rSt].rx - iL->src->pData[lSt].rx; + eDiff = iR->src->pData[rEn].rx - iL->src->pData[lSt].rx; + slDot = cross (sDiff,ldir); + elDot = cross (eDiff,ldir); + + if ((srDot >= 0 && erDot >= 0) || (srDot <= 0 && erDot <= 0)) + { + if (srDot == 0) + { + if (lSt < lEn) + { + atx = iL->src->pData[lSt].rx; + atL = 0; + atR = slDot / (slDot - elDot); + return true; + } + else + { + return false; + } + } + else if (erDot == 0) + { + if (lSt > lEn) + { + atx = iL->src->pData[lEn].rx; + atL = 1; + atR = slDot / (slDot - elDot); + return true; + } + else + { + return false; + } + } + if (srDot > 0 && erDot > 0) + { + if (rEn < rSt) + { + if (srDot < erDot) + { + if (lSt < lEn) + { + atx = iL->src->pData[lSt].rx; + atL = 0; + atR = slDot / (slDot - elDot); + return true; + } + } + else + { + if (lEn < lSt) + { + atx = iL->src->pData[lEn].rx; + atL = 1; + atR = slDot / (slDot - elDot); + return true; + } + } + } + } + if (srDot < 0 && erDot < 0) + { + if (rEn > rSt) + { + if (srDot > erDot) + { + if (lSt < lEn) + { + atx = iL->src->pData[lSt].rx; + atL = 0; + atR = slDot / (slDot - elDot); + return true; + } + } + else + { + if (lEn < lSt) + { + atx = iL->src->pData[lEn].rx; + atL = 1; + atR = slDot / (slDot - elDot); + return true; + } + } + } + } + return false; + } + if ((slDot >= 0 && elDot >= 0) || (slDot <= 0 && elDot <= 0)) + { + if (slDot == 0) + { + if (rSt < rEn) + { + atx = iR->src->pData[rSt].rx; + atR = 0; + atL = srDot / (srDot - erDot); + return true; + } + else + { + return false; + } + } + else if (elDot == 0) + { + if (rSt > rEn) + { + atx = iR->src->pData[rEn].rx; + atR = 1; + atL = srDot / (srDot - erDot); + return true; + } + else + { + return false; + } + } + if (slDot > 0 && elDot > 0) + { + if (lEn > lSt) + { + if (slDot < elDot) + { + if (rSt < rEn) + { + atx = iR->src->pData[rSt].rx; + atR = 0; + atL = srDot / (srDot - erDot); + return true; + } + } + else + { + if (rEn < rSt) + { + atx = iR->src->pData[rEn].rx; + atR = 1; + atL = srDot / (srDot - erDot); + return true; + } + } + } + } + if (slDot < 0 && elDot < 0) + { + if (lEn < lSt) + { + if (slDot > elDot) + { + if (rSt < rEn) + { + atx = iR->src->pData[rSt].rx; + atR = 0; + atL = srDot / (srDot - erDot); + return true; + } + } + else + { + if (rEn < rSt) + { + atx = iR->src->pData[rEn].rx; + atR = 1; + atL = srDot / (srDot - erDot); + return true; + } + } + } + } + return false; + } + +/* double slb=slDot-elDot,srb=srDot-erDot; + if ( slb < 0 ) slb=-slb; + if ( srb < 0 ) srb=-srb;*/ + if (iL->src->eData[iL->bord].siEd > iR->src->eData[iR->bord].siEd) + { + atx = + (slDot * iR->src->pData[rEn].rx - + elDot * iR->src->pData[rSt].rx) / (slDot - elDot); + } + else + { + atx = + (srDot * iL->src->pData[lEn].rx - + erDot * iL->src->pData[lSt].rx) / (srDot - erDot); + } + atL = srDot / (srDot - erDot); + atR = slDot / (slDot - elDot); + return true; + } + + return true; +} + +int +Shape::PushIncidence (Shape * a, int cb, int pt, double theta) +{ + if (theta < 0 || theta > 1) + return -1; + + if (nbInc >= maxInc) + { + maxInc = 2 * nbInc + 1; + iData = + (incidenceData *) g_realloc(iData, maxInc * sizeof (incidenceData)); + } + int n = nbInc++; + iData[n].nextInc = a->swsData[cb].firstLinkedPoint; + iData[n].pt = pt; + iData[n].theta = theta; + a->swsData[cb].firstLinkedPoint = n; + return n; +} + +int +Shape::CreateIncidence (Shape * a, int no, int nPt) +{ + NR::Point adir, diff; + adir = a->eData[no].rdx; + diff = getPoint(nPt).x - a->pData[a->getEdge(no).st].rx; + double t = dot (diff, adir); + t *= a->eData[no].ilength; + return PushIncidence (a, no, nPt, t); +} + +int +Shape::Winding (int nPt) const +{ + int askTo = pData[nPt].askForWindingB; + if (askTo < 0 || askTo >= numberOfEdges()) + return 0; + if (getEdge(askTo).st < getEdge(askTo).en) + { + return swdData[askTo].leW; + } + else + { + return swdData[askTo].riW; + } + return 0; +} + +int +Shape::Winding (const NR::Point px) const +{ + int lr = 0, ll = 0, rr = 0; + + for (int i = 0; i < numberOfEdges(); i++) + { + NR::Point adir, diff, ast, aen; + adir = eData[i].rdx; + + ast = pData[getEdge(i).st].rx; + aen = pData[getEdge(i).en].rx; + + int nWeight = eData[i].weight; + + if (ast[0] < aen[0]) + { + if (ast[0] > px[0]) + continue; + if (aen[0] < px[0]) + continue; + } + else + { + if (ast[0] < px[0]) + continue; + if (aen[0] > px[0]) + continue; + } + if (ast[0] == px[0]) + { + if (ast[1] >= px[1]) + continue; + if (aen[0] == px[0]) + continue; + if (aen[0] < px[0]) + ll += nWeight; + else + rr -= nWeight; + continue; + } + if (aen[0] == px[0]) + { + if (aen[1] >= px[1]) + continue; + if (ast[0] == px[0]) + continue; + if (ast[0] < px[0]) + ll -= nWeight; + else + rr += nWeight; + continue; + } + + if (ast[1] < aen[1]) + { + if (ast[1] >= px[1]) + continue; + } + else + { + if (aen[1] >= px[1]) + continue; + } + + diff = px - ast; + double cote = cross (diff,adir); + if (cote == 0) + continue; + if (cote < 0) + { + if (ast[0] > px[0]) + lr += nWeight; + } + else + { + if (ast[0] < px[0]) + lr -= nWeight; + } + } + return lr + (ll + rr) / 2; +} + +// merging duplicate points and edges +int +Shape::AssemblePoints (int st, int en) +{ + if (en > st) { + for (int i = st; i < en; i++) pData[i].oldInd = i; +// SortPoints(st,en-1); + SortPointsByOldInd (st, en - 1); // SortPointsByOldInd() is required here, because of the edges we have + // associated with the point for later computation of winding numbers. + // specifically, we need the first point we treated, it's the only one with a valid + // associated edge (man, that was a nice bug). + for (int i = st; i < en; i++) pData[pData[i].oldInd].newInd = i; + + int lastI = st; + for (int i = st; i < en; i++) { + pData[i].pending = lastI++; + if (i > st && getPoint(i - 1).x[0] == getPoint(i).x[0] && getPoint(i - 1).x[1] == getPoint(i).x[1]) { + pData[i].pending = pData[i - 1].pending; + if (pData[pData[i].pending].askForWindingS == NULL) { + pData[pData[i].pending].askForWindingS = pData[i].askForWindingS; + pData[pData[i].pending].askForWindingB = pData[i].askForWindingB; + } else { + if (pData[pData[i].pending].askForWindingS == pData[i].askForWindingS + && pData[pData[i].pending].askForWindingB == pData[i].askForWindingB) { + // meme bord, c bon + } else { + // meme point, mais pas le meme bord: ouille! + // il faut prendre le bord le plus a gauche + // en pratique, n'arrive que si 2 maxima sont dans la meme case -> le mauvais choix prend une arete incidente + // au bon choix +// printf("doh"); + } + } + lastI--; + } else { + if (i > pData[i].pending) { + _pts[pData[i].pending].x = getPoint(i).x; + pData[pData[i].pending].rx = getPoint(i).x; + pData[pData[i].pending].askForWindingS = pData[i].askForWindingS; + pData[pData[i].pending].askForWindingB = pData[i].askForWindingB; + } + } + } + for (int i = st; i < en; i++) pData[i].newInd = pData[pData[i].newInd].pending; + return lastI; + } + return en; +} + +void +Shape::AssemblePoints (Shape * a) +{ + if (hasPoints()) + { + int lastI = AssemblePoints (0, numberOfPoints()); + + for (int i = 0; i < a->numberOfEdges(); i++) + { + a->swsData[i].stPt = pData[a->swsData[i].stPt].newInd; + a->swsData[i].enPt = pData[a->swsData[i].enPt].newInd; + } + for (int i = 0; i < nbInc; i++) + iData[i].pt = pData[iData[i].pt].newInd; + + _pts.resize(lastI); + } +} +void +Shape::AssembleAretes (FillRule directed) +{ + if ( directed == fill_justDont && _has_back_data == false ) { + directed=fill_nonZero; + } + + for (int i = 0; i < numberOfPoints(); i++) { + if (getPoint(i).totalDegree() == 2) { + int cb, cc; + cb = getPoint(i).incidentEdge[FIRST]; + cc = getPoint(i).incidentEdge[LAST]; + bool doublon=false; + if ((getEdge(cb).st == getEdge(cc).st && getEdge(cb).en == getEdge(cc).en) + || (getEdge(cb).st == getEdge(cc).en && getEdge(cb).en == getEdge(cc).en)) doublon=true; + if ( directed == fill_justDont ) { + if ( doublon ) { + if ( ebData[cb].pathID > ebData[cc].pathID ) { + cc = getPoint(i).incidentEdge[FIRST]; // on swappe pour enlever cc + cb = getPoint(i).incidentEdge[LAST]; + } else if ( ebData[cb].pathID == ebData[cc].pathID ) { + if ( ebData[cb].pieceID > ebData[cc].pieceID ) { + cc = getPoint(i).incidentEdge[FIRST]; // on swappe pour enlever cc + cb = getPoint(i).incidentEdge[LAST]; + } else if ( ebData[cb].pieceID == ebData[cc].pieceID ) { + if ( ebData[cb].tSt > ebData[cc].tSt ) { + cc = getPoint(i).incidentEdge[FIRST]; // on swappe pour enlever cc + cb = getPoint(i).incidentEdge[LAST]; + } + } + } + } + if ( doublon ) eData[cc].weight = 0; + } else { + } + if ( doublon ) { + if (getEdge(cb).st == getEdge(cc).st) { + eData[cb].weight += eData[cc].weight; + } else { + eData[cb].weight -= eData[cc].weight; + } + eData[cc].weight = 0; + + if (swsData[cc].firstLinkedPoint >= 0) { + int cp = swsData[cc].firstLinkedPoint; + while (cp >= 0) { + pData[cp].askForWindingB = cb; + cp = pData[cp].nextLinkedPoint; + } + if (swsData[cb].firstLinkedPoint < 0) { + swsData[cb].firstLinkedPoint = swsData[cc].firstLinkedPoint; + } else { + int ncp = swsData[cb].firstLinkedPoint; + while (pData[ncp].nextLinkedPoint >= 0) { + ncp = pData[ncp].nextLinkedPoint; + } + pData[ncp].nextLinkedPoint = swsData[cc].firstLinkedPoint; + } + } + + DisconnectStart (cc); + DisconnectEnd (cc); + if (numberOfEdges() > 1) { + int cp = swsData[numberOfEdges() - 1].firstLinkedPoint; + while (cp >= 0) { + pData[cp].askForWindingB = cc; + cp = pData[cp].nextLinkedPoint; + } + } + SwapEdges (cc, numberOfEdges() - 1); + if (cb == numberOfEdges() - 1) { + cb = cc; + } + _aretes.pop_back(); + } + } else { + int cb; + cb = getPoint(i).incidentEdge[FIRST]; + while (cb >= 0 && cb < numberOfEdges()) { + int other = Other (i, cb); + int cc; + cc = getPoint(i).incidentEdge[FIRST]; + while (cc >= 0 && cc < numberOfEdges()) { + int ncc = NextAt (i, cc); + bool doublon=false; + if (cc != cb && Other (i, cc) == other ) doublon=true; + if ( directed == fill_justDont ) { + if ( doublon ) { + if ( ebData[cb].pathID > ebData[cc].pathID ) { + doublon=false; + } else if ( ebData[cb].pathID == ebData[cc].pathID ) { + if ( ebData[cb].pieceID > ebData[cc].pieceID ) { + doublon=false; + } else if ( ebData[cb].pieceID == ebData[cc].pieceID ) { + if ( ebData[cb].tSt > ebData[cc].tSt ) { + doublon=false; + } + } + } + } + if ( doublon ) eData[cc].weight = 0; + } else { + } + if ( doublon ) { +// if (cc != cb && Other (i, cc) == other) { + // doublon + if (getEdge(cb).st == getEdge(cc).st) { + eData[cb].weight += eData[cc].weight; + } else { + eData[cb].weight -= eData[cc].weight; + } + eData[cc].weight = 0; + + if (swsData[cc].firstLinkedPoint >= 0) { + int cp = swsData[cc].firstLinkedPoint; + while (cp >= 0) { + pData[cp].askForWindingB = cb; + cp = pData[cp].nextLinkedPoint; + } + if (swsData[cb].firstLinkedPoint < 0) { + swsData[cb].firstLinkedPoint = swsData[cc].firstLinkedPoint; + } else { + int ncp = swsData[cb].firstLinkedPoint; + while (pData[ncp].nextLinkedPoint >= 0) { + ncp = pData[ncp].nextLinkedPoint; + } + pData[ncp].nextLinkedPoint = swsData[cc].firstLinkedPoint; + } + } + + DisconnectStart (cc); + DisconnectEnd (cc); + if (numberOfEdges() > 1) { + int cp = swsData[numberOfEdges() - 1].firstLinkedPoint; + while (cp >= 0) { + pData[cp].askForWindingB = cc; + cp = pData[cp].nextLinkedPoint; + } + } + SwapEdges (cc, numberOfEdges() - 1); + if (cb == numberOfEdges() - 1) { + cb = cc; + } + if (ncc == numberOfEdges() - 1) { + ncc = cc; + } + _aretes.pop_back(); + } + cc = ncc; + } + cb = NextAt (i, cb); + } + } + } + + if ( directed == fill_justDont ) { + for (int i = 0; i < numberOfEdges(); i++) { + if (eData[i].weight == 0) { +// SubEdge(i); + // i--; + } else { + if (eData[i].weight < 0) Inverse (i); + } + } + } else { + for (int i = 0; i < numberOfEdges(); i++) { + if (eData[i].weight == 0) { + // SubEdge(i); + // i--; + } else { + if (eData[i].weight < 0) Inverse (i); + } + } + } +} +void +Shape::GetWindings (Shape * a, Shape * b, BooleanOp mod, bool brutal) +{ + // preparation du parcours + for (int i = 0; i < numberOfEdges(); i++) + { + swdData[i].misc = 0; + swdData[i].precParc = swdData[i].suivParc = -1; + } + + // chainage + SortEdges (); + + int searchInd = 0; + + int lastPtUsed = 0; + do + { + int startBord = -1; + int outsideW = 0; + { + int fi = 0; + for (fi = lastPtUsed; fi < numberOfPoints(); fi++) + { + if (getPoint(fi).incidentEdge[FIRST] >= 0 && swdData[getPoint(fi).incidentEdge[FIRST]].misc == 0) + break; + } + lastPtUsed = fi + 1; + if (fi < numberOfPoints()) + { + int bestB = getPoint(fi).incidentEdge[FIRST]; + if (bestB >= 0) + { + startBord = bestB; + if (fi == 0) + { + outsideW = 0; + } + else + { + if (brutal) + { + outsideW = Winding (getPoint(fi).x); + } + else + { + outsideW = Winding (fi); + } + } + if ( getPoint(fi).totalDegree() == 1 ) { + if ( fi == getEdge(startBord).en ) { + if ( eData[startBord].weight == 0 ) { + // on se contente d'inverser + Inverse(startBord); + } else { + // on passe le askForWinding (sinon ca va rester startBord) + pData[getEdge(startBord).st].askForWindingB=pData[getEdge(startBord).en].askForWindingB; + } + } + } + if (getEdge(startBord).en == fi) + outsideW += eData[startBord].weight; + } + } + } + if (startBord >= 0) + { + // parcours en profondeur pour mettre les leF et riF a leurs valeurs + swdData[startBord].misc = (void *) 1; + swdData[startBord].leW = outsideW; + swdData[startBord].riW = outsideW - eData[startBord].weight; +// if ( doDebug ) printf("part de %d\n",startBord); + int curBord = startBord; + bool curDir = true; + swdData[curBord].precParc = -1; + swdData[curBord].suivParc = -1; + do + { + int cPt; + if (curDir) + cPt = getEdge(curBord).en; + else + cPt = getEdge(curBord).st; + int nb = curBord; +// if ( doDebug ) printf("de curBord= %d avec leF= %d et riF= %d -> ",curBord,swdData[curBord].leW,swdData[curBord].riW); + do + { + int nnb = -1; + if (getEdge(nb).en == cPt) + { + outsideW = swdData[nb].riW; + nnb = CyclePrevAt (cPt, nb); + } + else + { + outsideW = swdData[nb].leW; + nnb = CyclePrevAt (cPt, nb); + } + if (nnb == nb) + { + // cul-de-sac + nb = -1; + break; + } + nb = nnb; + } + while (nb >= 0 && nb != curBord && swdData[nb].misc != 0); + if (nb < 0 || nb == curBord) + { + // retour en arriere + int oPt; + if (curDir) + oPt = getEdge(curBord).st; + else + oPt = getEdge(curBord).en; + curBord = swdData[curBord].precParc; +// if ( doDebug ) printf("retour vers %d\n",curBord); + if (curBord < 0) + break; + if (oPt == getEdge(curBord).en) + curDir = true; + else + curDir = false; + } + else + { + swdData[nb].misc = (void *) 1; + swdData[nb].ind = searchInd++; + if (cPt == getEdge(nb).st) + { + swdData[nb].riW = outsideW; + swdData[nb].leW = outsideW + eData[nb].weight; + } + else + { + swdData[nb].leW = outsideW; + swdData[nb].riW = outsideW - eData[nb].weight; + } + swdData[nb].precParc = curBord; + swdData[curBord].suivParc = nb; + curBord = nb; +// if ( doDebug ) printf("suite %d\n",curBord); + if (cPt == getEdge(nb).en) + curDir = false; + else + curDir = true; + } + } + while (1 /*swdData[curBord].precParc >= 0 */ ); + // fin du cas non-oriente + } + } + while (lastPtUsed < numberOfPoints()); +// fflush(stdout); +} + +bool +Shape::TesteIntersection (Shape * ils, Shape * irs, int ilb, int irb, + NR::Point &atx, double &atL, double &atR, + bool onlyDiff) +{ + int lSt = ils->getEdge(ilb).st, lEn = ils->getEdge(ilb).en; + int rSt = irs->getEdge(irb).st, rEn = irs->getEdge(irb).en; + if (lSt == rSt || lSt == rEn) + { + return false; + } + if (lEn == rSt || lEn == rEn) + { + return false; + } + + NR::Point ldir, rdir; + ldir = ils->eData[ilb].rdx; + rdir = irs->eData[irb].rdx; + + double il = ils->pData[lSt].rx[0], it = ils->pData[lSt].rx[1], ir = + ils->pData[lEn].rx[0], ib = ils->pData[lEn].rx[1]; + if (il > ir) + { + double swf = il; + il = ir; + ir = swf; + } + if (it > ib) + { + double swf = it; + it = ib; + ib = swf; + } + double jl = irs->pData[rSt].rx[0], jt = irs->pData[rSt].rx[1], jr = + irs->pData[rEn].rx[0], jb = irs->pData[rEn].rx[1]; + if (jl > jr) + { + double swf = jl; + jl = jr; + jr = swf; + } + if (jt > jb) + { + double swf = jt; + jt = jb; + jb = swf; + } + + if (il > jr || it > jb || ir < jl || ib < jt) + return false; + + // pre-test + { + NR::Point sDiff, eDiff; + double slDot, elDot; + double srDot, erDot; + sDiff = ils->pData[lSt].rx - irs->pData[rSt].rx; + eDiff = ils->pData[lEn].rx - irs->pData[rSt].rx; + srDot = cross (sDiff,rdir ); + erDot = cross (eDiff,rdir ); + if ((srDot >= 0 && erDot >= 0) || (srDot <= 0 && erDot <= 0)) + return false; + + sDiff = irs->pData[rSt].rx - ils->pData[lSt].rx; + eDiff = irs->pData[rEn].rx - ils->pData[lSt].rx; + slDot = cross (sDiff,ldir ); + elDot = cross (eDiff,ldir); + if ((slDot >= 0 && elDot >= 0) || (slDot <= 0 && elDot <= 0)) + return false; + + double slb = slDot - elDot, srb = srDot - erDot; + if (slb < 0) + slb = -slb; + if (srb < 0) + srb = -srb; + if (slb > srb) + { + atx = + (slDot * irs->pData[rEn].rx - elDot * irs->pData[rSt].rx) / (slDot - + elDot); + } + else + { + atx = + (srDot * ils->pData[lEn].rx - erDot * ils->pData[lSt].rx) / (srDot - + erDot); + } + atL = srDot / (srDot - erDot); + atR = slDot / (slDot - elDot); + return true; + } + + // a mettre en double precision pour des resultats exacts + NR::Point usvs; + usvs = irs->pData[rSt].rx - ils->pData[lSt].rx; + + // pas sur de l'ordre des coefs de m + NR::Matrix m(ldir[0], ldir[1], + rdir[0], rdir[1], + 0, 0); + double det = m.det(); + + double tdet = det * ils->eData[ilb].isqlength * irs->eData[irb].isqlength; + + if (tdet > -0.0001 && tdet < 0.0001) + { // ces couillons de vecteurs sont colineaires + NR::Point sDiff, eDiff; + double sDot, eDot; + sDiff = ils->pData[lSt].rx - irs->pData[rSt].rx; + eDiff = ils->pData[lEn].rx - irs->pData[rSt].rx; + sDot = cross (sDiff,rdir ); + eDot = cross (eDiff,rdir); + + atx = + (sDot * irs->pData[lEn].rx - eDot * irs->pData[lSt].rx) / (sDot - + eDot); + atL = sDot / (sDot - eDot); + + sDiff = irs->pData[rSt].rx - ils->pData[lSt].rx; + eDiff = irs->pData[rEn].rx - ils->pData[lSt].rx; + sDot = cross (sDiff,ldir ); + eDot = cross (eDiff,ldir ); + + atR = sDot / (sDot - eDot); + + return true; + } + + // plus de colinearite ni d'extremites en commun + m[1] = -m[1]; + m[2] = -m[2]; + { + double swap = m[0]; + m[0] = m[3]; + m[3] = swap; + } + + atL = (m[0]* usvs[0] + m[1] * usvs[1]) / det; + atR = -(m[2] * usvs[0] + m[3] * usvs[1]) / det; + atx = ils->pData[lSt].rx + atL * ldir; + + + return true; +} + +bool +Shape::TesteAdjacency (Shape * a, int no, const NR::Point atx, int nPt, + bool push) +{ + if (nPt == a->swsData[no].stPt || nPt == a->swsData[no].enPt) + return false; + + NR::Point adir, diff, ast, aen, diff1, diff2, diff3, diff4; + + ast = a->pData[a->getEdge(no).st].rx; + aen = a->pData[a->getEdge(no).en].rx; + + adir = a->eData[no].rdx; + + double sle = a->eData[no].length; + double ile = a->eData[no].ilength; + + diff = atx - ast; + + double e = IHalfRound ((cross (diff,adir)) * a->eData[no].isqlength); + if (-3 < e && e < 3) + { + double rad = HalfRound (0.501); // when using single precision, 0.505 is better (0.5 would be the correct value, + // but it produces lots of bugs) + diff1[0] = diff[0] - rad; + diff1[1] = diff[1] - rad; + diff2[0] = diff[0] + rad; + diff2[1] = diff[1] - rad; + diff3[0] = diff[0] + rad; + diff3[1] = diff[1] + rad; + diff4[0] = diff[0] - rad; + diff4[1] = diff[1] + rad; + double di1, di2; + bool adjacent = false; + di1 = cross (diff1,adir); + di2 = cross (diff3,adir); + if ((di1 < 0 && di2 > 0) || (di1 > 0 && di2 < 0)) + { + adjacent = true; + } + else + { + di1 = cross ( diff2,adir); + di2 = cross (diff4,adir); + if ((di1 < 0 && di2 > 0) || (di1 > 0 && di2 < 0)) + { + adjacent = true; + } + } + if (adjacent) + { + double t = dot (diff, adir); + if (t > 0 && t < sle) + { + if (push) + { + t *= ile; + PushIncidence (a, no, nPt, t); + } + return true; + } + } + } + return false; +} + +void +Shape::CheckAdjacencies (int lastPointNo, int lastChgtPt, Shape * shapeHead, + int edgeHead) +{ + for (unsigned int cCh = 0; cCh < chgts.size(); cCh++) + { + int chLeN = chgts[cCh].ptNo; + int chRiN = chgts[cCh].ptNo; + if (chgts[cCh].src) + { + Shape *lS = chgts[cCh].src; + int lB = chgts[cCh].bord; + int lftN = lS->swsData[lB].leftRnd; + int rgtN = lS->swsData[lB].rightRnd; + if (lftN < chLeN) + chLeN = lftN; + if (rgtN > chRiN) + chRiN = rgtN; +// for (int n=lftN;n<=rgtN;n++) CreateIncidence(lS,lB,n); + for (int n = lftN - 1; n >= lastChgtPt; n--) + { + if (TesteAdjacency (lS, lB, getPoint(n).x, n, false) == + false) + break; + lS->swsData[lB].leftRnd = n; + } + for (int n = rgtN + 1; n < lastPointNo; n++) + { + if (TesteAdjacency (lS, lB, getPoint(n).x, n, false) == + false) + break; + lS->swsData[lB].rightRnd = n; + } + } + if (chgts[cCh].osrc) + { + Shape *rS = chgts[cCh].osrc; + int rB = chgts[cCh].obord; + int lftN = rS->swsData[rB].leftRnd; + int rgtN = rS->swsData[rB].rightRnd; + if (lftN < chLeN) + chLeN = lftN; + if (rgtN > chRiN) + chRiN = rgtN; +// for (int n=lftN;n<=rgtN;n++) CreateIncidence(rS,rB,n); + for (int n = lftN - 1; n >= lastChgtPt; n--) + { + if (TesteAdjacency (rS, rB, getPoint(n).x, n, false) == + false) + break; + rS->swsData[rB].leftRnd = n; + } + for (int n = rgtN + 1; n < lastPointNo; n++) + { + if (TesteAdjacency (rS, rB, getPoint(n).x, n, false) == + false) + break; + rS->swsData[rB].rightRnd = n; + } + } + if (chgts[cCh].lSrc) + { + if (chgts[cCh].lSrc->swsData[chgts[cCh].lBrd].leftRnd < lastChgtPt) + { + Shape *nSrc = chgts[cCh].lSrc; + int nBrd = chgts[cCh].lBrd /*,nNo=chgts[cCh].ptNo */ ; + bool hit; + + do + { + hit = false; + for (int n = chRiN; n >= chLeN; n--) + { + if (TesteAdjacency + (nSrc, nBrd, getPoint(n).x, n, false)) + { + if (nSrc->swsData[nBrd].leftRnd < lastChgtPt) + { + nSrc->swsData[nBrd].leftRnd = n; + nSrc->swsData[nBrd].rightRnd = n; + } + else + { + if (n < nSrc->swsData[nBrd].leftRnd) + nSrc->swsData[nBrd].leftRnd = n; + if (n > nSrc->swsData[nBrd].rightRnd) + nSrc->swsData[nBrd].rightRnd = n; + } + hit = true; + } + } + for (int n = chLeN - 1; n >= lastChgtPt; n--) + { + if (TesteAdjacency + (nSrc, nBrd, getPoint(n).x, n, false) == false) + break; + if (nSrc->swsData[nBrd].leftRnd < lastChgtPt) + { + nSrc->swsData[nBrd].leftRnd = n; + nSrc->swsData[nBrd].rightRnd = n; + } + else + { + if (n < nSrc->swsData[nBrd].leftRnd) + nSrc->swsData[nBrd].leftRnd = n; + if (n > nSrc->swsData[nBrd].rightRnd) + nSrc->swsData[nBrd].rightRnd = n; + } + hit = true; + } + if (hit) + { + SweepTree *node = + static_cast < SweepTree * >(nSrc->swsData[nBrd].misc); + if (node == NULL) + break; + node = static_cast < SweepTree * >(node->elem[LEFT]); + if (node == NULL) + break; + nSrc = node->src; + nBrd = node->bord; + if (nSrc->swsData[nBrd].leftRnd >= lastChgtPt) + break; + } + } + while (hit); + + } + } + if (chgts[cCh].rSrc) + { + if (chgts[cCh].rSrc->swsData[chgts[cCh].rBrd].leftRnd < lastChgtPt) + { + Shape *nSrc = chgts[cCh].rSrc; + int nBrd = chgts[cCh].rBrd /*,nNo=chgts[cCh].ptNo */ ; + bool hit; + do + { + hit = false; + for (int n = chLeN; n <= chRiN; n++) + { + if (TesteAdjacency + (nSrc, nBrd, getPoint(n).x, n, false)) + { + if (nSrc->swsData[nBrd].leftRnd < lastChgtPt) + { + nSrc->swsData[nBrd].leftRnd = n; + nSrc->swsData[nBrd].rightRnd = n; + } + else + { + if (n < nSrc->swsData[nBrd].leftRnd) + nSrc->swsData[nBrd].leftRnd = n; + if (n > nSrc->swsData[nBrd].rightRnd) + nSrc->swsData[nBrd].rightRnd = n; + } + hit = true; + } + } + for (int n = chRiN + 1; n < lastPointNo; n++) + { + if (TesteAdjacency + (nSrc, nBrd, getPoint(n).x, n, false) == false) + break; + if (nSrc->swsData[nBrd].leftRnd < lastChgtPt) + { + nSrc->swsData[nBrd].leftRnd = n; + nSrc->swsData[nBrd].rightRnd = n; + } + else + { + if (n < nSrc->swsData[nBrd].leftRnd) + nSrc->swsData[nBrd].leftRnd = n; + if (n > nSrc->swsData[nBrd].rightRnd) + nSrc->swsData[nBrd].rightRnd = n; + } + hit = true; + } + if (hit) + { + SweepTree *node = + static_cast < SweepTree * >(nSrc->swsData[nBrd].misc); + if (node == NULL) + break; + node = static_cast < SweepTree * >(node->elem[RIGHT]); + if (node == NULL) + break; + nSrc = node->src; + nBrd = node->bord; + if (nSrc->swsData[nBrd].leftRnd >= lastChgtPt) + break; + } + } + while (hit); + } + } + } +} + + +void Shape::AddChgt(int lastPointNo, int lastChgtPt, Shape * &shapeHead, + int &edgeHead, sTreeChangeType type, Shape * lS, int lB, Shape * rS, + int rB) +{ + sTreeChange c; + c.ptNo = lastPointNo; + c.type = type; + c.src = lS; + c.bord = lB; + c.osrc = rS; + c.obord = rB; + chgts.push_back(c); + const int nCh = chgts.size() - 1; + + /* FIXME: this looks like a cut and paste job */ + + if (lS) { + SweepTree *lE = static_cast < SweepTree * >(lS->swsData[lB].misc); + if (lE && lE->elem[LEFT]) { + SweepTree *llE = static_cast < SweepTree * >(lE->elem[LEFT]); + chgts[nCh].lSrc = llE->src; + chgts[nCh].lBrd = llE->bord; + } else { + chgts[nCh].lSrc = NULL; + chgts[nCh].lBrd = -1; + } + + if (lS->swsData[lB].leftRnd < lastChgtPt) { + lS->swsData[lB].leftRnd = lastPointNo; + lS->swsData[lB].nextSh = shapeHead; + lS->swsData[lB].nextBo = edgeHead; + edgeHead = lB; + shapeHead = lS; + } else { + int old = lS->swsData[lB].leftRnd; + if (getPoint(old).x[0] > getPoint(lastPointNo).x[0]) { + lS->swsData[lB].leftRnd = lastPointNo; + } + } + if (lS->swsData[lB].rightRnd < lastChgtPt) { + lS->swsData[lB].rightRnd = lastPointNo; + } else { + int old = lS->swsData[lB].rightRnd; + if (getPoint(old).x[0] < getPoint(lastPointNo).x[0]) + lS->swsData[lB].rightRnd = lastPointNo; + } + } + + if (rS) { + SweepTree *rE = static_cast < SweepTree * >(rS->swsData[rB].misc); + if (rE->elem[RIGHT]) { + SweepTree *rrE = static_cast < SweepTree * >(rE->elem[RIGHT]); + chgts[nCh].rSrc = rrE->src; + chgts[nCh].rBrd = rrE->bord; + } else { + chgts[nCh].rSrc = NULL; + chgts[nCh].rBrd = -1; + } + + if (rS->swsData[rB].leftRnd < lastChgtPt) { + rS->swsData[rB].leftRnd = lastPointNo; + rS->swsData[rB].nextSh = shapeHead; + rS->swsData[rB].nextBo = edgeHead; + edgeHead = rB; + shapeHead = rS; + } else { + int old = rS->swsData[rB].leftRnd; + if (getPoint(old).x[0] > getPoint(lastPointNo).x[0]) { + rS->swsData[rB].leftRnd = lastPointNo; + } + } + if (rS->swsData[rB].rightRnd < lastChgtPt) { + rS->swsData[rB].rightRnd = lastPointNo; + } else { + int old = rS->swsData[rB].rightRnd; + if (getPoint(old).x[0] < getPoint(lastPointNo).x[0]) + rS->swsData[rB].rightRnd = lastPointNo; + } + } else { + SweepTree *lE = static_cast < SweepTree * >(lS->swsData[lB].misc); + if (lE && lE->elem[RIGHT]) { + SweepTree *rlE = static_cast < SweepTree * >(lE->elem[RIGHT]); + chgts[nCh].rSrc = rlE->src; + chgts[nCh].rBrd = rlE->bord; + } else { + chgts[nCh].rSrc = NULL; + chgts[nCh].rBrd = -1; + } + } +} + +// is this a debug function? It's calling localized "printf" ... +void +Shape::Validate (void) +{ + for (int i = 0; i < numberOfPoints(); i++) + { + pData[i].rx = getPoint(i).x; + } + for (int i = 0; i < numberOfEdges(); i++) + { + eData[i].rdx = getEdge(i).dx; + } + for (int i = 0; i < numberOfEdges(); i++) + { + for (int j = i + 1; j < numberOfEdges(); j++) + { + NR::Point atx; + double atL, atR; + if (TesteIntersection (this, this, i, j, atx, atL, atR, false)) + { + printf ("%i %i %f %f di=%f %f dj=%f %f\n", i, j, atx[0],atx[1],getEdge(i).dx[0],getEdge(i).dx[1],getEdge(j).dx[0],getEdge(j).dx[1]); + } + } + } + fflush (stdout); +} + +void +Shape::CheckEdges (int lastPointNo, int lastChgtPt, Shape * a, Shape * b, + BooleanOp mod) +{ + + for (unsigned int cCh = 0; cCh < chgts.size(); cCh++) + { + if (chgts[cCh].type == 0) + { + Shape *lS = chgts[cCh].src; + int lB = chgts[cCh].bord; + lS->swsData[lB].curPoint = chgts[cCh].ptNo; + } + } + for (unsigned int cCh = 0; cCh < chgts.size(); cCh++) + { +// int chLeN=chgts[cCh].ptNo; +// int chRiN=chgts[cCh].ptNo; + if (chgts[cCh].src) + { + Shape *lS = chgts[cCh].src; + int lB = chgts[cCh].bord; + Avance (lastPointNo, lastChgtPt, lS, lB, a, b, mod); + } + if (chgts[cCh].osrc) + { + Shape *rS = chgts[cCh].osrc; + int rB = chgts[cCh].obord; + Avance (lastPointNo, lastChgtPt, rS, rB, a, b, mod); + } + if (chgts[cCh].lSrc) + { + Shape *nSrc = chgts[cCh].lSrc; + int nBrd = chgts[cCh].lBrd; + while (nSrc->swsData[nBrd].leftRnd >= + lastChgtPt /*&& nSrc->swsData[nBrd].doneTo < lastChgtPt */ ) + { + Avance (lastPointNo, lastChgtPt, nSrc, nBrd, a, b, mod); + + SweepTree *node = + static_cast < SweepTree * >(nSrc->swsData[nBrd].misc); + if (node == NULL) + break; + node = static_cast < SweepTree * >(node->elem[LEFT]); + if (node == NULL) + break; + nSrc = node->src; + nBrd = node->bord; + } + } + if (chgts[cCh].rSrc) + { + Shape *nSrc = chgts[cCh].rSrc; + int nBrd = chgts[cCh].rBrd; + while (nSrc->swsData[nBrd].rightRnd >= + lastChgtPt /*&& nSrc->swsData[nBrd].doneTo < lastChgtPt */ ) + { + Avance (lastPointNo, lastChgtPt, nSrc, nBrd, a, b, mod); + + SweepTree *node = + static_cast < SweepTree * >(nSrc->swsData[nBrd].misc); + if (node == NULL) + break; + node = static_cast < SweepTree * >(node->elem[RIGHT]); + if (node == NULL) + break; + nSrc = node->src; + nBrd = node->bord; + } + } + } +} + +void +Shape::Avance (int lastPointNo, int lastChgtPt, Shape * lS, int lB, Shape * a, + Shape * b, BooleanOp mod) +{ + double dd = HalfRound (1); + bool avoidDiag = false; +// if ( lastChgtPt > 0 && pts[lastChgtPt-1].y+dd == pts[lastChgtPt].y ) avoidDiag=true; + + bool direct = true; + if (lS == b && (mod == bool_op_diff || mod == bool_op_symdiff)) + direct = false; + int lftN = lS->swsData[lB].leftRnd; + int rgtN = lS->swsData[lB].rightRnd; + if (lS->swsData[lB].doneTo < lastChgtPt) + { + int lp = lS->swsData[lB].curPoint; + if (lp >= 0 && getPoint(lp).x[1] + dd == getPoint(lastChgtPt).x[1]) + avoidDiag = true; + if (lS->eData[lB].rdx[1] == 0) + { + // tjs de gauche a droite et pas de diagonale + if (lS->eData[lB].rdx[0] >= 0) + { + for (int p = lftN; p <= rgtN; p++) + { + DoEdgeTo (lS, lB, p, direct, true); + lp = p; + } + } + else + { + for (int p = lftN; p <= rgtN; p++) + { + DoEdgeTo (lS, lB, p, direct, false); + lp = p; + } + } + } + else if (lS->eData[lB].rdx[1] > 0) + { + if (lS->eData[lB].rdx[0] >= 0) + { + + for (int p = lftN; p <= rgtN; p++) + { + if (avoidDiag && p == lftN && getPoint(lftN).x[0] == getPoint(lp).x[0] + dd) + { + if (lftN > 0 && lftN - 1 >= lastChgtPt + && getPoint(lftN - 1).x[0] == getPoint(lp).x[0]) + { + DoEdgeTo (lS, lB, lftN - 1, direct, true); + DoEdgeTo (lS, lB, lftN, direct, true); + } + else + { + DoEdgeTo (lS, lB, lftN, direct, true); + } + } + else + { + DoEdgeTo (lS, lB, p, direct, true); + } + lp = p; + } + } + else + { + + for (int p = rgtN; p >= lftN; p--) + { + if (avoidDiag && p == rgtN && getPoint(rgtN).x[0] == getPoint(lp).x[0] - dd) + { + if (rgtN < numberOfPoints() && rgtN + 1 < lastPointNo + && getPoint(rgtN + 1).x[0] == getPoint(lp).x[0]) + { + DoEdgeTo (lS, lB, rgtN + 1, direct, true); + DoEdgeTo (lS, lB, rgtN, direct, true); + } + else + { + DoEdgeTo (lS, lB, rgtN, direct, true); + } + } + else + { + DoEdgeTo (lS, lB, p, direct, true); + } + lp = p; + } + } + } + else + { + if (lS->eData[lB].rdx[0] >= 0) + { + + for (int p = rgtN; p >= lftN; p--) + { + if (avoidDiag && p == rgtN && getPoint(rgtN).x[0] == getPoint(lp).x[0] - dd) + { + if (rgtN < numberOfPoints() && rgtN + 1 < lastPointNo + && getPoint(rgtN + 1).x[0] == getPoint(lp).x[0]) + { + DoEdgeTo (lS, lB, rgtN + 1, direct, false); + DoEdgeTo (lS, lB, rgtN, direct, false); + } + else + { + DoEdgeTo (lS, lB, rgtN, direct, false); + } + } + else + { + DoEdgeTo (lS, lB, p, direct, false); + } + lp = p; + } + } + else + { + + for (int p = lftN; p <= rgtN; p++) + { + if (avoidDiag && p == lftN && getPoint(lftN).x[0] == getPoint(lp).x[0] + dd) + { + if (lftN > 0 && lftN - 1 >= lastChgtPt + && getPoint(lftN - 1).x[0] == getPoint(lp).x[0]) + { + DoEdgeTo (lS, lB, lftN - 1, direct, false); + DoEdgeTo (lS, lB, lftN, direct, false); + } + else + { + DoEdgeTo (lS, lB, lftN, direct, false); + } + } + else + { + DoEdgeTo (lS, lB, p, direct, false); + } + lp = p; + } + } + } + lS->swsData[lB].curPoint = lp; + } + lS->swsData[lB].doneTo = lastPointNo - 1; +} + +void +Shape::DoEdgeTo (Shape * iS, int iB, int iTo, bool direct, bool sens) +{ + int lp = iS->swsData[iB].curPoint; + int ne = -1; + if (sens) + { + if (direct) + ne = AddEdge (lp, iTo); + else + ne = AddEdge (iTo, lp); + } + else + { + if (direct) + ne = AddEdge (iTo, lp); + else + ne = AddEdge (lp, iTo); + } + if (ne >= 0 && _has_back_data) + { + ebData[ne].pathID = iS->ebData[iB].pathID; + ebData[ne].pieceID = iS->ebData[iB].pieceID; + if (iS->eData[iB].length < 0.00001) + { + ebData[ne].tSt = ebData[ne].tEn = iS->ebData[iB].tSt; + } + else + { + double bdl = iS->eData[iB].ilength; + NR::Point bpx = iS->pData[iS->getEdge(iB).st].rx; + NR::Point bdx = iS->eData[iB].rdx; + NR::Point psx = getPoint(getEdge(ne).st).x; + NR::Point pex = getPoint(getEdge(ne).en).x; + NR::Point psbx=psx-bpx; + NR::Point pebx=pex-bpx; + double pst = dot(psbx,bdx) * bdl; + double pet = dot(pebx,bdx) * bdl; + pst = iS->ebData[iB].tSt * (1 - pst) + iS->ebData[iB].tEn * pst; + pet = iS->ebData[iB].tSt * (1 - pet) + iS->ebData[iB].tEn * pet; + ebData[ne].tEn = pet; + ebData[ne].tSt = pst; + } + } + iS->swsData[iB].curPoint = iTo; + if (ne >= 0) + { + int cp = iS->swsData[iB].firstLinkedPoint; + swsData[ne].firstLinkedPoint = iS->swsData[iB].firstLinkedPoint; + while (cp >= 0) + { + pData[cp].askForWindingB = ne; + cp = pData[cp].nextLinkedPoint; + } + iS->swsData[iB].firstLinkedPoint = -1; + } +} diff --git a/src/livarot/float-line.cpp b/src/livarot/float-line.cpp new file mode 100644 index 000000000..afa3b6032 --- /dev/null +++ b/src/livarot/float-line.cpp @@ -0,0 +1,918 @@ +/** + * \file livarot/float-line.cpp + * + * Implementation of coverage with floating-point values. + * + * \author Fred + * + * public domain + * + */ + +#ifdef faster_flatten +# include // std::abs(float) +#endif +#include "livarot/float-line.h" +#include "livarot/int-line.h" + +FloatLigne::FloatLigne() +{ + s_first = s_last = -1; +} + + +FloatLigne::~FloatLigne() +{ + +} + +/// Reset the line to empty (boundaries and runs). +void FloatLigne::Reset() +{ + bords.clear(); + runs.clear(); + s_first = s_last = -1; +} + +/** + * Add a coverage portion. + * + * \param guess Position from where we should try to insert the first + * boundary, or -1 if we don't have a clue. + */ +int FloatLigne::AddBord(float spos, float sval, float epos, float eval, int guess) +{ +// if ( showCopy ) printf("b= %f %f -> %f %f \n",spos,sval,epos,eval); + if ( spos >= epos ) { + return -1; + } + + float pente = (eval - sval) / (epos - spos); + +#ifdef faster_flatten + if ( std::abs(epos - spos) < 0.001 || std::abs(pente) > 1000 ) { + return -1; + epos = spos; + pente = 0; + } +#endif + + if ( guess >= int(bords.size()) ) { + guess = -1; + } + + // add the left boundary + float_ligne_bord b; + int n = bords.size(); + b.pos = spos; + b.val = sval; + b.start = true; + b.other = n + 1; + b.pente = pente; + b.s_prev = b.s_next = -1; + bords.push_back(b); + + // insert it in the doubly-linked list + InsertBord(n, spos, guess); + + // add the right boundary + n = bords.size(); + b.pos = epos; + b.val = eval; + b.start = false; + b.other = n-1; + b.pente = pente; + b.s_prev = b.s_next = -1; + bords.push_back(b); + + // insert it in the doubly-linked list, knowing that boundary at index n-1 is not too far before me + InsertBord(n, epos, n - 1); + + return n; +} + +/** + * Add a coverage portion. + * + * \param guess Position from where we should try to insert the first + * boundary, or -1 if we don't have a clue. + */ +int FloatLigne::AddBord(float spos, float sval, float epos, float eval, float pente, int guess) +{ +// if ( showCopy ) printf("b= %f %f -> %f %f \n",spos,sval,epos,eval); + if ( spos >= epos ) { + return -1; + } + +#ifdef faster_flatten + if ( std::abs(epos - spos) < 0.001 || std::abs(pente) > 1000 ) { + return -1; + epos = spos; + pente = 0; + } +#endif + + if ( guess >= int(bords.size()) ) { + guess=-1; + } + + float_ligne_bord b; + int n = bords.size(); + b.pos = spos; + b.val = sval; + b.start = true; + b.other = n + 1; + b.pente = pente; + b.s_prev = b.s_next = -1; + bords.push_back(b); + + n = bords.size(); + b.pos = epos; + b.val = eval; + b.start = false; + b.other = n - 1; + b.pente = pente; + b.s_prev = b.s_next = -1; + bords.push_back(b); + + InsertBord(n - 1, spos, guess); + InsertBord(n, epos, n - 1); +/* if ( bords[n-1].s_next < 0 ) { + bords[n].s_next=-1; + s_last=n; + + bords[n].s_prev=n-1; + bords[n-1].s_next=n; + } else if ( bords[bords[n-1].s_next].pos >= epos ) { + bords[n].s_next=bords[n-1].s_next; + bords[bords[n].s_next].s_prev=n; + + bords[n].s_prev=n-1; + bords[n-1].s_next=n; + } else { + int c=bords[bords[n-1].s_next].s_next; + while ( c >= 0 && bords[c].pos < epos ) c=bords[c].s_next; + if ( c < 0 ) { + bords[n].s_prev=s_last; + bords[s_last].s_next=n; + s_last=n; + } else { + bords[n].s_prev=bords[c].s_prev; + bords[bords[n].s_prev].s_next=n; + + bords[n].s_next=c; + bords[c].s_prev=n; + } + + }*/ + return n; +} + +/** + * Add a coverage portion. + * + * \param guess Position from where we should try to insert the last + * boundary, or -1 if we don't have a clue. + */ +int FloatLigne::AddBordR(float spos, float sval, float epos, float eval, float pente, int guess) +{ +// if ( showCopy ) printf("br= %f %f -> %f %f \n",spos,sval,epos,eval); +// return AddBord(spos,sval,epos,eval,pente,guess); + if ( spos >= epos ){ + return -1; + } + +#ifdef faster_flatten + if ( std::abs(epos - spos) < 0.001 || std::abs(pente) > 1000 ) { + return -1; + epos = spos; + pente = 0; + } +#endif + + if ( guess >= int(bords.size()) ) { + guess=-1; + } + + float_ligne_bord b; + int n = bords.size(); + b.pos = spos; + b.val = sval; + b.start = true; + b.other = n + 1; + b.pente = pente; + b.s_prev = b.s_next = -1; + bords.push_back(b); + + n = bords.size(); + b.pos = epos; + b.val = eval; + b.start = false; + b.other = n - 1; + b.pente = pente; + b.s_prev = b.s_next = -1; + bords.push_back(b); + + InsertBord(n, epos, guess); + InsertBord(n - 1, spos, n); + +/* if ( bords[n].s_prev < 0 ) { + bords[n-1].s_prev=-1; + s_first=n-1; + + bords[n-1].s_next=n; + bords[n].s_prev=n-1; + } else if ( bords[bords[n].s_prev].pos <= spos ) { + bords[n-1].s_prev=bords[n].s_prev; + bords[bords[n-1].s_prev].s_next=n-1; + + bords[n-1].s_next=n; + bords[n].s_prev=n-1; + } else { + int c=bords[bords[n].s_prev].s_prev; + while ( c >= 0 && bords[c].pos > spos ) c=bords[c].s_prev; + if ( c < 0 ) { + bords[n-1].s_next=s_first; + bords[s_first].s_prev=n-1; + s_first=n-1; + } else { + bords[n-1].s_next=bords[c].s_next; + bords[bords[n-1].s_next].s_prev=n-1; + + bords[n-1].s_prev=c; + bords[c].s_next=n-1; + } + + }*/ + return n - 1; +} + +/** + * Add a coverage portion by appending boundaries at the end of the list. + * + * This works because we know they are on the right. + */ +int FloatLigne::AppendBord(float spos, float sval, float epos, float eval, float pente) +{ +// if ( showCopy ) printf("b= %f %f -> %f %f \n",spos,sval,epos,eval); +// return AddBord(spos,sval,epos,eval,pente,s_last); + if ( spos >= epos ) { + return -1; + } + +#ifdef faster_flatten + if ( std::abs(epos - spos) < 0.001 || std::abs(pente) > 1000 ) { + return -1; + epos = spos; + pente = 0; + } +#endif + + int n = bords.size(); + float_ligne_bord b; + b.pos = spos; + b.val = sval; + b.start = true; + b.other = n + 1; + b.pente = pente; + b.s_prev = s_last; + b.s_next = n + 1; + bords.push_back(b); + + if ( s_last >= 0 ) { + bords[s_last].s_next = n; + } + + if ( s_first < 0 ) { + s_first = n; + } + + n = bords.size(); + b.pos = epos; + b.val = eval; + b.start = false; + b.other = n - 1; + b.pente = pente; + b.s_prev = n - 1; + b.s_next = -1; + bords.push_back(b); + + s_last = n; + + return n; +} + + + +// insertion in a boubly-linked list. nothing interesting here +void FloatLigne::InsertBord(int no, float p, int guess) +{ + if ( no < 0 || no >= int(bords.size()) ) { + return; + } + + if ( s_first < 0 ) { + s_first = s_last = no; + bords[no].s_prev = -1; + bords[no].s_next = -1; + return; + } + + if ( guess < 0 || guess >= int(bords.size()) ) { + int c = s_first; + while ( c >= 0 && c < int(bords.size()) && CmpBord(bords[c], bords[no]) < 0 ) { + c = bords[c].s_next; + } + + if ( c < 0 || c >= int(bords.size()) ) { + bords[no].s_prev = s_last; + bords[s_last].s_next = no; + s_last = no; + } else { + bords[no].s_prev = bords[c].s_prev; + if ( bords[no].s_prev >= 0 ) { + bords[bords[no].s_prev].s_next = no; + } else { + s_first = no; + } + bords[no].s_next = c; + bords[c].s_prev = no; + } + } else { + int c = guess; + int stTst = CmpBord(bords[c], bords[no]); + + if ( stTst == 0 ) { + + bords[no].s_prev = bords[c].s_prev; + if ( bords[no].s_prev >= 0 ) { + bords[bords[no].s_prev].s_next = no; + } else { + s_first = no; + } + bords[no].s_next = c; + bords[c].s_prev = no; + + } else if ( stTst > 0 ) { + + while ( c >= 0 && c < int(bords.size()) && CmpBord(bords[c], bords[no]) > 0 ) { + c = bords[c].s_prev; + } + + if ( c < 0 || c >= int(bords.size()) ) { + bords[no].s_next = s_first; + bords[s_first].s_prev =no; // s_first != -1 + s_first = no; + } else { + bords[no].s_next = bords[c].s_next; + if ( bords[no].s_next >= 0 ) { + bords[bords[no].s_next].s_prev = no; + } else { + s_last = no; + } + bords[no].s_prev = c; + bords[c].s_next = no; + } + + } else { + + while ( c >= 0 && c < int(bords.size()) && CmpBord(bords[c],bords[no]) < 0 ) { + c = bords[c].s_next; + } + + if ( c < 0 || c >= int(bords.size()) ) { + bords[no].s_prev = s_last; + bords[s_last].s_next = no; + s_last = no; + } else { + bords[no].s_prev = bords[c].s_prev; + if ( bords[no].s_prev >= 0 ) { + bords[bords[no].s_prev].s_next = no; + } else { + s_first = no; + } + bords[no].s_next = c; + bords[c].s_prev = no; + } + } + } +} + +/** + * Computes the sum of the coverages of the runs currently being scanned, + * of which there are "pending". + */ +float FloatLigne::RemainingValAt(float at, int pending) +{ + float sum = 0; +/* int no=firstAc; + while ( no >= 0 && no < bords.size() ) { + int nn=bords[no].other; + sum+=bords[nn].val+(at-bords[nn].pos)*bords[nn].pente; +// sum+=((at-bords[nn].pos)*bords[no].val+(bords[no].pos-at)*bords[nn].val)/(bords[no].pos-bords[nn].pos); +// sum+=ValAt(at,bords[nn].pos,bords[no].pos,bords[nn].val,bords[no].val); + no=bords[no].next; + }*/ + // for each portion being scanned, compute coverage at position "at" and sum. + // we could simply compute the sum of portion coverages as a "f(x)=ux+y" and evaluate it at "x=at", + // but there are numerical problems with this approach, and it produces ugly lines of incorrectly + // computed alpha values, so i reverted to this "safe but slow" version + + for (int i=0; i < pending; i++) { + int const nn = bords[i].pend_ind; + sum += bords[nn].val + (at - bords[nn].pos) * bords[nn].pente; + } + + return sum; +} + + +/** + * Extract a set of non-overlapping runs from the boundaries. + * + * We scan the boundaries left to right, maintaining a set of coverage + * portions currently being scanned. For each such portion, the function + * will add the index of its first boundary in an array; but instead of + * allocating another array, it uses a field in float_ligne_bord: pend_ind. + * The outcome is that an array of float_ligne_run is produced. + */ +void FloatLigne::Flatten() +{ + if ( int(bords.size()) <= 1 ) { + Reset(); + return; + } + + runs.clear(); + +// qsort(bords,bords.size(),sizeof(float_ligne_bord),FloatLigne::CmpBord); +// SortBords(0,bords.size()-1); + + float totPente = 0; + float totStart = 0; + float totX = bords[0].pos; + + bool startExists = false; + float lastStart = 0; + float lastVal = 0; + int pending = 0; + +// for (int i=0;i=0 && i < int(bords.size()) ;) { + + float cur = bords[i].pos; // position of the current boundary (there may be several boundaries at this position) + float leftV = 0; // deltas in coverage value at this position + float rightV = 0; + float leftP = 0; // deltas in coverage increase per unit length at this position + float rightP = 0; + + // more precisely, leftV is the sum of decreases of coverage value, + // while rightV is the sum of increases, so that leftV+rightV is the delta. + // idem for leftP and rightP + + // start by scanning all boundaries that end a portion at this position + while ( i >= 0 && i < int(bords.size()) && bords[i].pos == cur && bords[i].start == false ) { + leftV += bords[i].val; + leftP += bords[i].pente; + +#ifndef faster_flatten + // we need to remove the boundary that started this coverage portion for the pending list + if ( bords[i].other >= 0 && bords[i].other < int(bords.size()) ) { + // so we use the pend_inv "array" + int const k = bords[bords[i].other].pend_inv; + if ( k >= 0 && k < pending ) { + // and update the pend_ind array and its inverse pend_inv + bords[k].pend_ind = bords[pending - 1].pend_ind; + bords[bords[k].pend_ind].pend_inv = k; + } + } +#endif + + // one less portion pending + pending--; + // and we move to the next boundary in the doubly linked list + i=bords[i].s_next; + //i++; + } + + // then scan all boundaries that start a portion at this position + while ( i >= 0 && i < int(bords.size()) && bords[i].pos == cur && bords[i].start == true ) { + rightV += bords[i].val; + rightP += bords[i].pente; +#ifndef faster_flatten + bords[pending].pend_ind=i; + bords[i].pend_inv=pending; +#endif + pending++; + i = bords[i].s_next; + //i++; + } + + // coverage value at end of the run will be "start coverage"+"delta per unit length"*"length" + totStart = totStart + totPente * (cur - totX); + + if ( startExists ) { + // add that run + AddRun(lastStart, cur, lastVal, totStart, totPente); + } + // update "delta coverage per unit length" + totPente += rightP - leftP; + // not really needed here + totStart += rightV - leftV; + // update position + totX = cur; + if ( pending > 0 ) { + startExists = true; + +#ifndef faster_flatten + // to avoid accumulation of numerical errors, we compute an accurate coverage for this position "cur" + totStart = RemainingValAt(cur, pending); +#endif + lastVal = totStart; + lastStart = cur; + } else { + startExists = false; + totStart = 0; + totPente = 0; + } + } +} + + +/// Debug dump of the instance. +void FloatLigne::Affiche() +{ + printf("%lu : \n", (long unsigned int) bords.size()); + for (int i = 0; i < int(bords.size()); i++) { + printf("(%f %f %f %i) ",bords[i].pos,bords[i].val,bords[i].pente,(bords[i].start?1:0)); // localization ok + } + + printf("\n"); + printf("%lu : \n", (long unsigned int) runs.size()); + + for (int i = 0; i < int(runs.size()); i++) { + printf("(%f %f -> %f %f / %f)", + runs[i].st, runs[i].vst, runs[i].en, runs[i].ven, runs[i].pente); // localization ok + } + + printf("\n"); +} + + +int FloatLigne::AddRun(float st, float en, float vst, float ven) +{ + return AddRun(st, en, vst, ven, (ven - vst) / (en - st)); +} + + +int FloatLigne::AddRun(float st, float en, float vst, float ven, float pente) +{ + if ( st >= en ) { + return -1; + } + + int const n = runs.size(); + float_ligne_run r; + r.st = st; + r.en = en; + r.vst = vst; + r.ven = ven; + r.pente = pente; + runs.push_back(r); + + return n; +} + +void FloatLigne::Copy(FloatLigne *a) +{ + if ( a->runs.empty() ) { + Reset(); + return; + } + + bords.clear(); + runs = a->runs; +} + +void FloatLigne::Copy(IntLigne *a) +{ + if ( a->nbRun ) { + Reset(); + return; + } + + bords.clear(); + runs.resize(a->nbRun); + + for (int i = 0; i < int(runs.size()); i++) { + runs[i].st = a->runs[i].st; + runs[i].en = a->runs[i].en; + runs[i].vst = a->runs[i].vst; + runs[i].ven = a->runs[i].ven; + } +} + +/// Cuts the parts having less than tresh coverage. +void FloatLigne::Min(FloatLigne *a, float tresh, bool addIt) +{ + Reset(); + if ( a->runs.empty() ) { + return; + } + + bool startExists = false; + float lastStart=0; + float lastEnd = 0; + + for (int i = 0; i < int(a->runs.size()); i++) { + float_ligne_run runA = a->runs[i]; + if ( runA.vst <= tresh ) { + if ( runA.ven <= tresh ) { + if ( startExists ) { + if ( lastEnd >= runA.st - 0.00001 ) { + lastEnd = runA.en; + } else { + if ( addIt ) { + AddRun(lastStart, lastEnd, tresh, tresh); + } + lastStart = runA.st; + lastEnd = runA.en; + } + } else { + lastStart = runA.st; + lastEnd = runA.en; + } + startExists = true; + } else { + float cutPos = (runA.st * (tresh - runA.ven) + runA.en * (runA.vst - tresh)) / (runA.vst - runA.ven); + if ( startExists ) { + if ( lastEnd >= runA.st - 0.00001 ) { + if ( addIt ) { + AddRun(lastStart, cutPos, tresh, tresh); + } + AddRun(cutPos,runA.en, tresh, runA.ven); + } else { + if ( addIt ) { + AddRun(lastStart, lastEnd, tresh, tresh); + } + if ( addIt ) { + AddRun(runA.st, cutPos, tresh, tresh); + } + AddRun(cutPos, runA.en, tresh, runA.ven); + } + } else { + if ( addIt ) { + AddRun(runA.st, cutPos, tresh, tresh); + } + AddRun(cutPos, runA.en, tresh, runA.ven); + } + startExists = false; + } + + } else { + + if ( runA.ven <= tresh ) { + float cutPos = (runA.st * (runA.ven - tresh) + runA.en * (tresh - runA.vst)) / (runA.ven - runA.vst); + if ( startExists ) { + if ( addIt ) { + AddRun(lastStart, lastEnd, tresh, tresh); + } + } + AddRun(runA.st, cutPos, runA.vst, tresh); + startExists = true; + lastStart = cutPos; + lastEnd = runA.en; + } else { + if ( startExists ) { + if ( addIt ) { + AddRun(lastStart, lastEnd, tresh, tresh); + } + } + startExists = false; + AddRun(runA.st, runA.en, runA.vst, runA.ven); + } + } + } + + if ( startExists ) { + if ( addIt ) { + AddRun(lastStart, lastEnd, tresh, tresh); + } + } +} + +/** + * Cuts the coverage a in 2 parts. + * + * over will receive the parts where coverage > tresh, while the present + * FloatLigne will receive the parts where coverage <= tresh. + */ +void FloatLigne::Split(FloatLigne *a, float tresh, FloatLigne *over) +{ + Reset(); + if ( a->runs.empty() ) { + return; + } + + for (int i = 0; i < int(a->runs.size()); i++) { + float_ligne_run runA = a->runs[i]; + if ( runA.vst >= tresh ) { + if ( runA.ven >= tresh ) { + if ( over ) { + over->AddRun(runA.st, runA.en, runA.vst, runA.ven); + } + } else { + float cutPos = (runA.st * (tresh - runA.ven) + runA.en * (runA.vst - tresh)) / (runA.vst - runA.ven); + if ( over ) { + over->AddRun(runA.st, cutPos, runA.vst, tresh); + } + AddRun(cutPos, runA.en, tresh, runA.ven); + } + } else { + if ( runA.ven >= tresh ) { + float cutPos = (runA.st * (runA.ven - tresh) + runA.en * (tresh-runA.vst)) / (runA.ven - runA.vst); + AddRun(runA.st, cutPos, runA.vst, tresh); + if ( over ) { + over->AddRun(cutPos, runA.en, tresh, runA.ven); + } + } else { + AddRun(runA.st, runA.en, runA.vst, runA.ven); + } + } + } +} + +/** + * Clips the coverage runs to tresh. + * + * If addIt == false, it only leaves the parts that are not entirely under + * tresh. If addIt == true, it's the coverage clamped to tresh. + */ +void FloatLigne::Max(FloatLigne *a, float tresh, bool addIt) +{ + Reset(); + if ( a->runs.empty() <= 0 ) { + return; + } + + bool startExists = false; + float lastStart = 0; + float lastEnd = 0; + for (int i = 0; i < int(a->runs.size()); i++) { + float_ligne_run runA = a->runs[i]; + if ( runA.vst >= tresh ) { + if ( runA.ven >= tresh ) { + if ( startExists ) { + if ( lastEnd >= runA.st-0.00001 ) { + lastEnd = runA.en; + } else { + if ( addIt ) { + AddRun(lastStart,lastEnd,tresh,tresh); + } + lastStart = runA.st; + lastEnd = runA.en; + } + } else { + lastStart = runA.st; + lastEnd = runA.en; + } + startExists = true; + } else { + float cutPos = (runA.st * (tresh - runA.ven) + runA.en * (runA.vst - tresh)) / (runA.vst - runA.ven); + if ( startExists ) { + if ( lastEnd >= runA.st-0.00001 ) { + if ( addIt ) { + AddRun(lastStart, cutPos, tresh, tresh); + } + AddRun(cutPos, runA.en, tresh, runA.ven); + } else { + if ( addIt ) { + AddRun(lastStart, lastEnd, tresh, tresh); + } + if ( addIt ) { + AddRun(runA.st, cutPos, tresh, tresh); + } + AddRun(cutPos, runA.en, tresh, runA.ven); + } + } else { + if ( addIt ) { + AddRun(runA.st, cutPos, tresh, tresh); + } + AddRun(cutPos, runA.en, tresh, runA.ven); + } + startExists = false; + } + + } else { + + if ( runA.ven >= tresh ) { + float cutPos = (runA.st * (runA.ven - tresh) + runA.en * (tresh - runA.vst)) / (runA.ven - runA.vst); + if ( startExists ) { + if ( addIt ) { + AddRun(lastStart,lastEnd,tresh,tresh); + } + } + AddRun(runA.st, cutPos, runA.vst, tresh); + startExists = true; + lastStart = cutPos; + lastEnd = runA.en; + } else { + if ( startExists ) { + if ( addIt ) { + AddRun(lastStart,lastEnd,tresh,tresh); + } + } + startExists = false; + AddRun(runA.st, runA.en, runA.vst, runA.ven); + } + } + } + + if ( startExists ) { + if ( addIt ) { + AddRun(lastStart, lastEnd, tresh, tresh); + } + } +} + +/// Extract the parts where coverage > tresh. +void FloatLigne::Over(FloatLigne *a, float tresh) +{ + Reset(); + if ( a->runs.empty() ) { + return; + } + + bool startExists = false; + float lastStart = 0; + float lastEnd = 0; + + for (int i = 0; i < int(a->runs.size()); i++) { + float_ligne_run runA = a->runs[i]; + if ( runA.vst >= tresh ) { + if ( runA.ven >= tresh ) { + if ( startExists ) { + if ( lastEnd >= runA.st - 0.00001 ) { + lastEnd = runA.en; + } else { + AddRun(lastStart, lastEnd, tresh, tresh); + lastStart = runA.st; + lastEnd = runA.en; + } + } else { + lastStart = runA.st; + lastEnd = runA.en; + } + startExists = true; + + } else { + + float cutPos = (runA.st * (tresh - runA.ven) + runA.en * (runA.vst - tresh)) / (runA.vst - runA.ven); + if ( startExists ) { + if ( lastEnd >= runA.st - 0.00001 ) { + AddRun(lastStart, cutPos, tresh, tresh); + } else { + AddRun(lastStart, lastEnd, tresh, tresh); + AddRun(runA.st, cutPos, tresh, tresh); + } + } else { + AddRun(runA.st, cutPos, tresh, tresh); + } + startExists = false; + } + + } else { + if ( runA.ven >= tresh ) { + float cutPos = (runA.st * (runA.ven - tresh) + runA.en * (tresh - runA.vst)) / (runA.ven - runA.vst); + if ( startExists ) { + AddRun(lastStart, lastEnd, tresh, tresh); + } + startExists = true; + lastStart = cutPos; + lastEnd = runA.en; + } else { + if ( startExists ) { + AddRun(lastStart, lastEnd, tresh, tresh); + } + startExists = false; + } + } + } + + if ( startExists ) { + AddRun(lastStart, lastEnd, tresh, tresh); + } +} + + +/* + 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:textwidth=99 : diff --git a/src/livarot/float-line.h b/src/livarot/float-line.h new file mode 100644 index 000000000..ef4f2c398 --- /dev/null +++ b/src/livarot/float-line.h @@ -0,0 +1,136 @@ +#ifndef INKSCAPE_LIVAROT_FLOAT_LINE_H +#define INKSCAPE_LIVAROT_FLOAT_LINE_H + +/** \file + * Coverage with floating-point boundaries. + */ + +#include +#include "livarot/LivarotDefs.h" + +class IntLigne; +class BitLigne; + +/// A coverage portion ("run") with floating point boundaries. +struct float_ligne_run { + float st; + float en; + float vst; + float ven; + float pente; ///< (ven-vst)/(en-st) +}; + +/** + * A floating-point boundary. + * + * Each float_ligne_bord is a boundary of some coverage. + * The Flatten() function will extract non-overlapping runs and produce an + * array of float_ligne_run. The float_ligne_bord are stored in an array, but + * linked like a doubly-linked list. + * + * The idea behind that is that a given edge produces one float_ligne_bord at + * the beginning of Scan() and possibly another in AvanceEdge() and + * DestroyEdge(); but that second float_ligne_bord will not be far away in + * the list from the first, so it's faster to salvage the index of the first + * float_ligne_bord and try to insert the second from that salvaged position. + */ +struct float_ligne_bord { + float pos; ///< position of the boundary + bool start; ///< is the beginning of the coverage portion? + float val; ///< amount of coverage (ie vst if start==true, and ven if start==false) + float pente; ///< (ven-vst)/(en-st) + int other; ///< index, in the array of float_ligne_bord, of the other boundary associated to this one + int s_prev; ///< index of the previous bord in the doubly-linked list + int s_next; ///< index of the next bord in the doubly-linked list + int pend_ind; ///< bords[i].pend_ind is the index of the float_ligne_bord that is the start of the + ///< coverage portion being scanned (in the Flatten() ) + int pend_inv; ///< inverse of pend_ind, for faster handling of insertion/removal in the "pending" array +}; + +/** + * Coverage with floating-point boundaries. + * + * The goal is to salvage exact coverage info in the sweepline performed by + * Scan() or QuickScan(), then clean up a bit, convert floating point bounds + * to integer bounds, because pixel have integer bounds, and then raster runs + * of the type: + * \verbatim + position on the (pixel) line: st en + | | + coverage value (0=empty, 1=full) vst -> ven \endverbatim + */ +class FloatLigne { +public: + std::vector bords; ///< vector of coverage boundaries + std::vector runs; ///< vector of runs + + /// first boundary in the doubly-linked list + int s_first; + /// last boundary in the doubly-linked list + int s_last; + + FloatLigne(); + ~FloatLigne(); + + void Reset(); + + int AddBord(float spos, float sval, float epos, float eval, int guess = -1); + int AddBord(float spos, float sval, float epos, float eval, float pente, int guess = -1); + int AddBordR(float spos, float sval, float epos, float eval, float pente, int guess = -1); + int AppendBord(float spos, float sval, float epos, float eval, float pente); + + void Flatten(); + + void Affiche(); + + void Max(FloatLigne *a, float tresh, bool addIt); + + void Min(FloatLigne *a, float tresh, bool addIt); + + void Split(FloatLigne *a, float tresh, FloatLigne *over); + + void Over(FloatLigne *a, float tresh); + + void Copy(IntLigne *a); + void Copy(FloatLigne *a); + + float RemainingValAt(float at, int pending); + + static int CmpBord(float_ligne_bord const &d1, float_ligne_bord const &d2) { + if ( d1.pos == d2.pos ) { + if ( d1.start && !(d2.start) ) { + return 1; + } + if ( !(d1.start) && d2.start ) { + return -1; + } + return 0; + } + + return (( d1.pos < d2.pos ) ? -1 : 1); + }; + + int AddRun(float st, float en, float vst, float ven, float pente); + +private: + void InsertBord(int no, float p, int guess); + int AddRun(float st, float en, float vst, float ven); + + inline float ValAt(float at, float ps, float pe, float vs, float ve) { + return ((at - ps) * ve + (pe - at) * vs) / (pe - ps); + }; +}; + +#endif + + +/* + 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:textwidth=99 : diff --git a/src/livarot/int-line.cpp b/src/livarot/int-line.cpp new file mode 100644 index 000000000..fabe8d01c --- /dev/null +++ b/src/livarot/int-line.cpp @@ -0,0 +1,1066 @@ +/** + * \file livarot/int-line.cpp + * + * Implementation of coverage with integer boundaries. + * + * \author Fred + * + * public domain + * + */ + +#include +#include +#include "livarot/int-line.h" +#include "livarot/float-line.h" +#include "livarot/BitLigne.h" + +IntLigne::IntLigne() +{ + nbBord = maxBord = 0; + bords = NULL; + + nbRun = maxRun = 0; + runs = NULL; + + firstAc = lastAc = -1; +} + + +IntLigne::~IntLigne() +{ + if ( maxBord > 0 ) { + g_free(bords); + nbBord = maxBord = 0; + bords = NULL; + } + if ( maxRun > 0 ) { + g_free(runs); + nbRun = maxRun = 0; + runs = NULL; + } +} + +void IntLigne::Reset() +{ + nbBord = 0; + nbRun = 0; + firstAc = lastAc = -1; +} + +int IntLigne::AddBord(int spos, float sval, int epos, float eval) +{ + if ( nbBord + 1 >= maxBord ) { + maxBord = 2 * nbBord + 2; + bords = (int_ligne_bord *) g_realloc(bords, maxBord * sizeof(int_ligne_bord)); + + } + + int n = nbBord++; + bords[n].pos = spos; + bords[n].val = sval; + bords[n].start = true; + bords[n].other = n+1; + bords[n].prev = bords[n].next = -1; + + n = nbBord++; + bords[n].pos = epos; + bords[n].val = eval; + bords[n].start = false; + bords[n].other = n-1; + bords[n].prev = bords[n].next = -1; + + return n - 1; +} + + +float IntLigne::RemainingValAt(int at) +{ + int no = firstAc; + float sum = 0; + while ( no >= 0 ) { + int nn = bords[no].other; + sum += ValAt(at, bords[nn].pos, bords[no].pos, bords[nn].val, bords[no].val); + no = bords[no].next; + } + return sum; +} + +void IntLigne::Flatten() +{ + if ( nbBord <= 1 ) { + Reset(); + return; + } + + nbRun = 0; + firstAc = lastAc = -1; + + for (int i = 0; i < nbBord; i++) { + bords[i].prev = i; + } + + qsort(bords, nbBord, sizeof(int_ligne_bord), IntLigne::CmpBord); + for (int i = 0; i < nbBord; i++) { + bords[bords[i].prev].next = i; + } + + for (int i = 0; i < nbBord; i++) { + bords[i].other = bords[bords[i].other].next; + } + + int lastStart = 0; + float lastVal = 0; + bool startExists = false; + + for (int i = 0; i < nbBord; ) { + int cur = bords[i].pos; + float leftV = 0; + float rightV = 0; + float midV = 0; + while ( i < nbBord && bords[i].pos == cur && bords[i].start == false ) { + Dequeue(i); + leftV += bords[i].val; + i++; + } + midV = RemainingValAt(cur); + while ( i < nbBord && bords[i].pos == cur && bords[i].start == true ) { + rightV += bords[i].val; + Enqueue(bords[i].other); + i++; + } + + if ( startExists ) { + AddRun(lastStart, cur, lastVal, leftV + midV); + } + if ( firstAc >= 0 ) { + startExists = true; + lastVal = midV + rightV; + lastStart = cur; + } else { + startExists = false; + } + } +} + + +void IntLigne::Affiche() +{ + printf("%i : \n", nbRun); + for (int i = 0; i < nbRun;i++) { + printf("(%i %f -> %i %f) ", runs[i].st, runs[i].vst, runs[i].en, runs[i].ven); // localization ok + } + printf("\n"); +} + +int IntLigne::AddRun(int st, int en, float vst, float ven) +{ + if ( st >= en ) { + return -1; + } + + if ( nbRun >= maxRun ) { + maxRun = 2 * nbRun + 1; + runs = (int_ligne_run *) g_realloc(runs, maxRun * sizeof(int_ligne_run)); + } + + int n = nbRun++; + runs[n].st = st; + runs[n].en = en; + runs[n].vst = vst; + runs[n].ven = ven; + return n; +} + +void IntLigne::Booleen(IntLigne *a, IntLigne *b, BooleanOp mod) +{ + Reset(); + if ( a->nbRun <= 0 && b->nbRun <= 0 ) { + return; + } + + if ( a->nbRun <= 0 ) { + if ( mod == bool_op_union || mod == bool_op_symdiff ) { + Copy(b); + } + return; + } + + if ( b->nbRun <= 0 ) { + if ( mod == bool_op_union || mod == bool_op_diff || mod == bool_op_symdiff ) { + Copy(a); + } + return; + } + + int curA = 0; + int curB = 0; + int curPos = (a->runs[0].st < b->runs[0].st) ? a->runs[0].st : b->runs[0].st; + int nextPos = curPos; + float valA = 0; + float valB = 0; + if ( curPos == a->runs[0].st ) { + valA = a->runs[0].vst; + } + if ( curPos == b->runs[0].st ) { + valB = b->runs[0].vst; + } + + while ( curA < a->nbRun && curB < b->nbRun ) { + int_ligne_run runA = a->runs[curA]; + int_ligne_run runB = b->runs[curB]; + const bool inA = ( curPos >= runA.st && curPos < runA.en ); + const bool inB = ( curPos >= runB.st && curPos < runB.en ); + + bool startA = false; + bool startB = false; + bool endA = false; + bool endB = false; + + if ( curPos < runA.st ) { + if ( curPos < runB.st ) { + startA = runA.st <= runB.st; + startB = runA.st >= runB.st; + nextPos = startA ? runA.st : runB.st; + } else if ( curPos >= runB.st ) { + startA = runA.st <= runB.en; + endB = runA.st >= runB.en; + nextPos = startA ? runA.st : runB.en; + } + } else if ( curPos == runA.st ) { + if ( curPos < runB.st ) { + endA = runA.en <= runB.st; + startB = runA.en >= runB.st; + nextPos = startB ? runB.en : runA.st; + } else if ( curPos == runB.st ) { + endA = runA.en <= runB.en; + endB = runA.en >= runB.en; + nextPos = endA? runA.en : runB.en; + } else { + endA = runA.en <= runB.en; + endB = runA.en >= runB.en; + nextPos = endA ? runA.en : runB.en; + } + } else { + if ( curPos < runB.st ) { + endA = runA.en <= runB.st; + startB = runA.en >= runB.st; + nextPos = startB ? runB.st : runA.en; + } else if ( curPos == runB.st ) { + endA = runA.en <= runB.en; + endB = runA.en >= runB.en; + nextPos = endA ? runA.en : runB.en; + } else { + endA = runA.en <= runB.en; + endB = runA.en >= runB.en; + nextPos = endA ? runA.en : runB.en; + } + } + + float oValA = valA; + float oValB = valB; + valA = inA ? ValAt(nextPos, runA.st, runA.en, runA.vst, runA.ven) : 0; + valB = inB ? ValAt(nextPos, runB.st, runB.en, runB.vst, runB.ven) : 0; + + if ( mod == bool_op_union ) { + + if ( inA || inB ) { + AddRun(curPos, nextPos, oValA + oValB, valA + valB); + } + + } else if ( mod == bool_op_inters ) { + + if ( inA && inB ) { + AddRun(curPos, nextPos, oValA * oValB, valA * valB); + } + + } else if ( mod == bool_op_diff ) { + + if ( inA ) { + AddRun(curPos, nextPos, oValA - oValB, valA - valB); + } + + } else if ( mod == bool_op_symdiff ) { + if ( inA && !(inB) ) { + AddRun(curPos, nextPos, oValA - oValB, valA - valB); + } + if ( !(inA) && inB ) { + AddRun(curPos, nextPos, oValB - oValA, valB - valA); + } + } + + curPos = nextPos; + if ( startA ) { + // inA=true; these are never used + valA = runA.vst; + } + if ( startB ) { + //inB=true; + valB = runB.vst; + } + if ( endA ) { + //inA=false; + valA = 0; + curA++; + if ( curA < a->nbRun && a->runs[curA].st == curPos ) { + valA = a->runs[curA].vst; + } + } + if ( endB ) { + //inB=false; + valB = 0; + curB++; + if ( curB < b->nbRun && b->runs[curB].st == curPos ) { + valB = b->runs[curB].vst; + } + } + } + + while ( curA < a->nbRun ) { + int_ligne_run runA = a->runs[curA]; + const bool inA = ( curPos >= runA.st && curPos < runA.en ); + const bool inB = false; + + bool startA = false; + bool endA = false; + if ( curPos < runA.st ) { + nextPos = runA.st; + startA = true; + } else if ( curPos >= runA.st ) { + nextPos = runA.en; + endA = true; + } + + float oValA = valA; + float oValB = valB; + valA = inA ? ValAt(nextPos,runA.st, runA.en, runA.vst, runA.ven) : 0; + valB = 0; + + if ( mod == bool_op_union ) { + if ( inA || inB ) { + AddRun(curPos, nextPos, oValA + oValB, valA + valB); + } + } else if ( mod == bool_op_inters ) { + if ( inA && inB ) { + AddRun(curPos, nextPos, oValA * oValB, valA * valB); + } + } else if ( mod == bool_op_diff ) { + if ( inA ) { + AddRun(curPos, nextPos, oValA - oValB, valA - valB); + } + } else if ( mod == bool_op_symdiff ) { + if ( inA && !(inB) ) { + AddRun(curPos, nextPos, oValA - oValB, valA - valB); + } + if ( !(inA) && inB ) { + AddRun(curPos,nextPos,oValB-oValA,valB-valA); + } + } + + curPos = nextPos; + if ( startA ) { + //inA=true; + valA = runA.vst; + } + if ( endA ) { + //inA=false; + valA = 0; + curA++; + if ( curA < a->nbRun && a->runs[curA].st == curPos ) { + valA = a->runs[curA].vst; + } + } + } + + while ( curB < b->nbRun ) { + int_ligne_run runB = b->runs[curB]; + const bool inB = ( curPos >= runB.st && curPos < runB.en ); + const bool inA = false; + + bool startB = false; + bool endB = false; + if ( curPos < runB.st ) { + nextPos = runB.st; + startB = true; + } else if ( curPos >= runB.st ) { + nextPos = runB.en; + endB = true; + } + + float oValA = valA; + float oValB = valB; + valB = inB ? ValAt(nextPos, runB.st, runB.en, runB.vst, runB.ven) : 0; + valA = 0; + + if ( mod == bool_op_union ) { + if ( inA || inB ) { + AddRun(curPos, nextPos, oValA + oValB,valA + valB); + } + } else if ( mod == bool_op_inters ) { + if ( inA && inB ) { + AddRun(curPos, nextPos, oValA * oValB, valA * valB); + } + } else if ( mod == bool_op_diff ) { + if ( inA ) { + AddRun(curPos, nextPos, oValA - oValB, valA - valB); + } + } else if ( mod == bool_op_symdiff ) { + if ( inA && !(inB) ) { + AddRun(curPos, nextPos, oValA - oValB,valA - valB); + } + if ( !(inA) && inB ) { + AddRun(curPos, nextPos, oValB - oValA, valB - valA); + } + } + + curPos = nextPos; + if ( startB ) { + //inB=true; + valB = runB.vst; + } + if ( endB ) { + //inB=false; + valB = 0; + curB++; + if ( curB < b->nbRun && b->runs[curB].st == curPos ) { + valB = b->runs[curB].vst; + } + } + } +} + +/** + * Transform a line of bits into pixel coverage values. + * + * This is where you go from supersampled data to alpha values. + * \see IntLigne::Copy(int nbSub,BitLigne* *a). + */ +void IntLigne::Copy(BitLigne* a) +{ + if ( a->curMax <= a->curMin ) { + Reset(); + return; + } + + if ( a->curMin < a->st ) { + a->curMin = a->st; + } + + if ( a->curMax < a->st ) { + Reset(); + return; + } + + if ( a->curMin > a->en ) { + Reset(); + return; + } + + if ( a->curMax > a->en ) { + a->curMax=a->en; + } + + nbBord = 0; + nbRun = 0; + + int lastVal = 0; + int lastStart = 0; + bool startExists = false; + + int masks[] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 }; + + uint32_t c_full = a->fullB[(a->curMin-a->st) >> 3]; + uint32_t c_part = a->partB[(a->curMin-a->st) >> 3]; + c_full <<= 4 * ((a->curMin - a->st) & 0x00000007); + c_part <<= 4 * ((a->curMin - a->st) & 0x00000007); + for (int i = a->curMin; i <= a->curMax; i++) { + int nbBit = masks[c_full >> 28] + masks[c_part >> 28]; + + if ( nbBit > 0 ) { + if ( startExists ) { + if ( lastVal == nbBit ) { + // on continue le run + } else { + AddRun(lastStart, i, ((float) lastVal) / 4, ((float) lastVal) / 4); + lastStart = i; + lastVal = nbBit; + } + } else { + lastStart = i; + lastVal = nbBit; + startExists = true; + } + } else { + if ( startExists ) { + AddRun(lastStart, i, ((float) lastVal) / 4, ((float) lastVal) / 4); + } + startExists = false; + } + int chg = (i + 1 - a->st) & 0x00000007; + if ( chg == 0 ) { + c_full = a->fullB[(i + 1 - a->st) >> 3]; + c_part = a->partB[(i + 1 - a->st) >> 3]; + } else { + c_full <<= 4; + c_part <<= 4; + } + } + if ( startExists ) { + AddRun(lastStart, a->curMax + 1, ((float) lastVal) / 4, ((float) lastVal) / 4); + } +} + +/** + * Transform a line of bits into pixel coverage values. + * + * Alpha values are computed from supersampled data, so we have to scan the + * BitLigne left to right, summing the bits in each pixel. The alpha value + * is then "number of bits"/(nbSub*nbSub)". Full bits and partial bits are + * treated as equals because the method produces ugly results otherwise. + * + * \param nbSub Number of BitLigne in the array "a". + */ +void IntLigne::Copy(int nbSub, BitLigne **as) +{ + if ( nbSub <= 0 ) { + Reset(); + return; + } + + if ( nbSub == 1 ) { + Copy(as[0]); + return; + } + + // compute the min-max of the pixels to be rasterized from the min-max of the inpur bitlignes + int curMin = as[0]->curMin; + int curMax = as[0]->curMax; + for (int i = 1; i < nbSub; i++) { + if ( as[i]->curMin < curMin ) { + curMin = as[i]->curMin; + } + if ( as[i]->curMax > curMax ) { + curMax = as[i]->curMax; + } + } + + if ( curMin < as[0]->st ) { + curMin = as[0]->st; + } + + if ( curMax > as[0]->en ) { + curMax = as[0]->en; + } + + if ( curMax <= curMin ) { + Reset(); + return; + } + + nbBord = 0; + nbRun = 0; + + int lastVal = 0; + int lastStart = 0; + bool startExists = false; + float spA; + int masks[16] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4}; + + int theSt = as[0]->st; + if ( nbSub == 4 ) { + // special case for 4*4 supersampling, to avoid a few loops + uint32_t c_full[4]; + c_full[0] = as[0]->fullB[(curMin - theSt) >> 3] | as[0]->partB[(curMin - theSt) >> 3]; + c_full[0] <<= 4 * ((curMin - theSt) & 7); + c_full[1] = as[1]->fullB[(curMin - theSt) >> 3] | as[1]->partB[(curMin - theSt) >> 3]; + c_full[1] <<= 4 * ((curMin - theSt) & 7); + c_full[2] = as[2]->fullB[(curMin - theSt) >> 3] | as[2]->partB[(curMin - theSt) >> 3]; + c_full[2] <<= 4* ((curMin - theSt) & 7); + c_full[3] = as[3]->fullB[(curMin - theSt) >> 3] | as[3]->partB[(curMin - theSt) >> 3]; + c_full[3] <<= 4* ((curMin - theSt) & 7); + + spA = 1.0 / (4 * 4); + for (int i = curMin; i <= curMax; i++) { + int nbBit = 0; + + if ( c_full[0] == 0 && c_full[1] == 0 && c_full[2] == 0 && c_full[3] == 0 ) { + + if ( startExists ) { + AddRun(lastStart, i, ((float) lastVal) * spA, ((float) lastVal) * spA); + } + startExists = false; + i = theSt + (((i - theSt) & (~7) ) + 7); + + } else if ( c_full[0] == 0xFFFFFFFF && c_full[1] == 0xFFFFFFFF && + c_full[2] == 0xFFFFFFFF && c_full[3] == 0xFFFFFFFF ) { + + if ( startExists ) { + if ( lastVal == 4*4) { + } else { + AddRun(lastStart, i, ((float) lastVal) * spA, ((float) lastVal) * spA); + lastStart = i; + } + } else { + lastStart = i; + } + lastVal = 4*4; + startExists = true; + i = theSt + (((i - theSt) & (~7) ) + 7); + + } else { + nbBit += masks[c_full[0] >> 28]; + nbBit += masks[c_full[1] >> 28]; + nbBit += masks[c_full[2] >> 28]; + nbBit += masks[c_full[3] >> 28]; + + if ( nbBit > 0 ) { + if ( startExists ) { + if ( lastVal == nbBit ) { + // on continue le run + } else { + AddRun(lastStart, i, ((float) lastVal) * spA, ((float) lastVal) * spA); + lastStart = i; + lastVal = nbBit; + } + } else { + lastStart = i; + lastVal = nbBit; + startExists = true; + } + } else { + if ( startExists ) { + AddRun(lastStart, i, ((float) lastVal) * spA, ((float) lastVal) * spA); + } + startExists = false; + } + } + int chg = (i + 1 - theSt) & 7; + if ( chg == 0 ) { + if ( i < curMax ) { + c_full[0] = as[0]->fullB[(i + 1 - theSt) >> 3] | as[0]->partB[(i + 1 - theSt) >> 3]; + c_full[1] = as[1]->fullB[(i + 1 - theSt) >> 3] | as[1]->partB[(i + 1 - theSt) >> 3]; + c_full[2] = as[2]->fullB[(i + 1 - theSt) >> 3] | as[2]->partB[(i + 1 - theSt) >> 3]; + c_full[3] = as[3]->fullB[(i + 1 - theSt) >> 3] | as[3]->partB[(i + 1 - theSt) >> 3]; + } else { + // end of line. byebye + } + } else { + c_full[0] <<= 4; + c_full[1] <<= 4; + c_full[2] <<= 4; + c_full[3] <<= 4; + } + } + + } else { + + uint32_t c_full[16]; // we take nbSub < 16, since 16*16 supersampling makes a 1/256 precision in alpha values + // and that's the max of what 32bit argb can represent + // in fact, we'll treat it as 4*nbSub supersampling, so that's a half truth and a full lazyness from me + // uint32_t c_part[16]; + // start by putting the bits of the nbSub BitLignes in as[] in their respective c_full + + for (int i = 0; i < nbSub; i++) { + // fullB and partB treated equally + c_full[i] = as[i]->fullB[(curMin - theSt) >> 3] | as[i]->partB[(curMin - theSt) >> 3]; + c_full[i] <<= 4 * ((curMin - theSt) & 7); + /* c_part[i]=as[i]->partB[(curMin-theSt)>>3]; + c_part[i]<<=4*((curMin-theSt)&7);*/ + } + + spA = 1.0 / (4 * nbSub); // contribution to the alpha value of a single bit of the supersampled data + for (int i = curMin; i <= curMax;i++) { + int nbBit = 0; + // int nbPartBit=0; + // a little acceleration: if the lines only contain full or empty bits, we can flush + // what's remaining in the c_full at best we flush an entire c_full, ie 32 bits, or 32/4=8 pixels + bool allEmpty = true; + bool allFull = true; + for (int j = 0; j < nbSub; j++) { + if ( c_full[j] != 0 /*|| c_part[j] != 0*/ ) { + allEmpty=false; + break; + } + } + + if ( allEmpty ) { + // the remaining bits in c_full[] are empty: flush + if ( startExists ) { + AddRun(lastStart, i, ((float) lastVal) * spA, ((float) lastVal) * spA); + } + startExists = false; + i = theSt + (((i - theSt) & (~7) ) + 7); + } else { + for (int j = 0; j < nbSub; j++) { + if ( c_full[j] != 0xFFFFFFFF ) { + allFull=false; + break; + } + } + + if ( allFull ) { + // the remaining bits in c_full[] are empty: flush + if ( startExists ) { + if ( lastVal == 4 * nbSub) { + } else { + AddRun(lastStart, i, ((float) lastVal) * spA,((float) lastVal) * spA); + lastStart = i; + } + } else { + lastStart = i; + } + lastVal = 4 * nbSub; + startExists = true; + i = theSt + (((i - theSt) & (~7) ) + 7); + } else { + // alpha values will be between 0 and 1, so we have more work to do + // compute how many bit this pixel holds + for (int j = 0; j < nbSub; j++) { + nbBit += masks[c_full[j] >> 28]; +// nbPartBit+=masks[c_part[j]>>28]; + } + // and add a single-pixel run if needed, or extend the current run if the alpha value hasn't changed + if ( nbBit > 0 ) { + if ( startExists ) { + if ( lastVal == nbBit ) { + // alpha value hasn't changed: we continue + } else { + // alpha value did change: put the run that was being done,... + AddRun(lastStart, i, ((float) lastVal) * spA, ((float) lastVal) * spA); + // ... and start a new one + lastStart = i; + lastVal = nbBit; + } + } else { + // alpha value was 0, so we "create" a new run with alpha nbBit + lastStart = i; + lastVal = nbBit; + startExists = true; + } + } else { + if ( startExists ) { + AddRun(lastStart, i, ((float) lastVal) * spA,((float) lastVal) * spA); + } + startExists = false; + } + } + } + // move to the right: shift bits in the c_full[], and if we shifted everything, load the next c_full[] + int chg = (i + 1 - theSt) & 7; + if ( chg == 0 ) { + if ( i < curMax ) { + for (int j = 0; j < nbSub; j++) { + c_full[j] = as[j]->fullB[(i + 1 - theSt) >> 3] | as[j]->partB[(i + 1 - theSt) >> 3]; + // c_part[j]=as[j]->partB[(i+1-theSt)>>3]; + } + } else { + // end of line. byebye + } + } else { + for (int j = 0; j < nbSub; j++) { + c_full[j]<<=4; + // c_part[j]<<=4; + } + } + } + } + + if ( startExists ) { + AddRun(lastStart, curMax + 1, ((float) lastVal) * spA,((float) lastVal) * spA); + } +} + +/// Copy another IntLigne +void IntLigne::Copy(IntLigne *a) +{ + if ( a->nbRun <= 0 ) { + Reset(); + return; + } + + nbBord = 0; + nbRun = a->nbRun; + if ( nbRun > maxRun ) { + maxRun = nbRun; + runs = (int_ligne_run*) g_realloc(runs, maxRun * sizeof(int_ligne_run)); + } + memcpy(runs, a->runs, nbRun * sizeof(int_ligne_run)); +} + + +/** + * Copy a FloatLigne's runs. + * + * Compute non-overlapping runs with integer boundaries from a set of runs + * with floating-point boundaries. This involves replacing floating-point + * boundaries that are not integer by single-pixel runs, so this function + * contains plenty of rounding and float->integer conversion (read: + * time-consuming). + * + * \todo + * Optimization Questions: Why is this called so often compared with the + * other Copy() routines? How does AddRun() look for optimization potential? + */ +void IntLigne::Copy(FloatLigne* a) +{ + if ( a->runs.empty() ) { + Reset(); + return; + } + + /* if ( showCopy ) { + printf("\nfloatligne:\n"); + a->Affiche(); + }*/ + + nbBord = 0; + nbRun = 0; + firstAc = lastAc = -1; + bool pixExists = false; + int curPos = (int) floor(a->runs[0].st) - 1; + float lastSurf = 0; + float tolerance = 0.00001; + + // we take each run of the FloatLigne in sequence and make single-pixel runs of its boundaries as needed + // since the float_ligne_runs are non-overlapping, when a single-pixel run intersects with another runs, + // it must intersect with the single-pixel run created for the end of that run. so instead of creating a new + // int_ligne_run, we just add the coverage to that run. + for (int i = 0; i < int(a->runs.size()); i++) { + float_ligne_run runA = a->runs[i]; + float curStF = floor(runA.st); + float curEnF = floor(runA.en); + int curSt = (int) curStF; + int curEn = (int) curEnF; + + // stEx: start boundary is not integer -> create single-pixel run for it + // enEx: end boundary is not integer -> create single-pixel run for it + // miEx: the runs minus the eventual single-pixel runs is not empty + bool stEx = true; + bool miEx = true; + bool enEx = true; + int miSt = curSt; + float miStF = curStF; + float msv; + float mev; + if ( runA.en - curEnF < tolerance ) { + enEx = false; + } + + // msv and mev are the start and end value of the middle section of the run, that is the run minus the + // single-pixel runs creaed for its boundaries + if ( runA.st-curStF < tolerance /*miSt == runA.st*/ ) { + stEx = false; + msv = runA.vst; + } else { + miSt += 1; + miStF += 1.0; + if ( enEx == false && miSt == curEn ) { + msv = runA.ven; + } else { + // msv=a->ValAt(miSt,runA.st,runA.en,runA.vst,runA.ven); + msv = runA.vst + (miStF-runA.st) * runA.pente; + } + } + + if ( miSt >= curEn ) { + miEx = false; + } + if ( stEx == false && miEx == false /*curEn == runA.st*/ ) { + mev = runA.vst; + } else if ( enEx == false /*curEn == runA.en*/ ) { + mev = runA.ven; + } else { + // mev=a->ValAt(curEn,runA.st,runA.en,runA.vst,runA.ven); + mev = runA.vst + (curEnF-runA.st) * runA.pente; + } + + // check the different cases + if ( stEx && enEx ) { + // stEx && enEx + if ( curEn > curSt ) { + if ( pixExists ) { + if ( curPos < curSt ) { + AddRun(curPos,curPos+1,lastSurf,lastSurf); + lastSurf=0.5*(msv+a->runs[i].vst)*(miStF-a->runs[i].st); + AddRun(curSt,curSt+1,lastSurf,lastSurf); + } else { + lastSurf+=0.5*(msv+a->runs[i].vst)*(miStF-a->runs[i].st); + AddRun(curSt,curSt+1,lastSurf,lastSurf); + } + pixExists=false; + } else { + lastSurf=0.5*(msv+a->runs[i].vst)*(miStF-a->runs[i].st); + AddRun(curSt,curSt+1,lastSurf,lastSurf); + } + } else if ( pixExists ) { + if ( curPos < curSt ) { + AddRun(curPos,curPos+1,lastSurf,lastSurf); + lastSurf=0.5*(a->runs[i].ven+a->runs[i].vst)*(a->runs[i].en-a->runs[i].st); + curPos=curSt; + } else { + lastSurf += 0.5 * (a->runs[i].ven+a->runs[i].vst)*(a->runs[i].en-a->runs[i].st); + } + } else { + lastSurf=0.5*(a->runs[i].ven+a->runs[i].vst)*(a->runs[i].en-a->runs[i].st); + curPos=curSt; + pixExists=true; + } + } else if ( pixExists ) { + if ( curPos < curSt ) { + AddRun(curPos,curPos+1,lastSurf,lastSurf); + lastSurf = 0.5 * (msv+a->runs[i].vst) * (miStF-a->runs[i].st); + AddRun(curSt,curSt+1,lastSurf,lastSurf); + } else { + lastSurf += 0.5 * (msv+a->runs[i].vst) * (miStF-a->runs[i].st); + AddRun(curSt,curSt+1,lastSurf,lastSurf); + } + pixExists=false; + } else { + lastSurf = 0.5 * (msv+a->runs[i].vst) * (miStF-a->runs[i].st); + AddRun(curSt,curSt+1,lastSurf,lastSurf); + } + if ( miEx ) { + if ( pixExists && curPos < miSt ) { + AddRun(curPos,curPos+1,lastSurf,lastSurf); + } + pixExists=false; + AddRun(miSt,curEn,msv,mev); + } + if ( enEx ) { + if ( curEn > curSt ) { + lastSurf=0.5*(mev+a->runs[i].ven)*(a->runs[i].en-curEnF); + pixExists=true; + curPos=curEn; + } else if ( ! stEx ) { + if ( pixExists ) { + AddRun(curPos,curPos+1,lastSurf,lastSurf); + } + lastSurf=0.5*(mev+a->runs[i].ven)*(a->runs[i].en-curEnF); + pixExists=true; + curPos=curEn; + } + } + } + if ( pixExists ) { + AddRun(curPos,curPos+1,lastSurf,lastSurf); + } + /* if ( showCopy ) { + printf("-> intligne:\n"); + Affiche(); + }*/ +} + + +void IntLigne::Enqueue(int no) +{ + if ( firstAc < 0 ) { + firstAc = lastAc = no; + bords[no].prev = bords[no].next = -1; + } else { + bords[no].next = -1; + bords[no].prev = lastAc; + bords[lastAc].next = no; + lastAc = no; + } +} + + +void IntLigne::Dequeue(int no) +{ + if ( no == firstAc ) { + if ( no == lastAc ) { + firstAc = lastAc = -1; + } else { + firstAc = bords[no].next; + } + } else if ( no == lastAc ) { + lastAc = bords[no].prev; + } else { + } + if ( bords[no].prev >= 0 ) { + bords[bords[no].prev].next = bords[no].next; + } + if ( bords[no].next >= 0 ) { + bords[bords[no].next].prev = bords[no].prev; + } + + bords[no].prev = bords[no].next = -1; +} + +/** + * Rasterization. + * + * The parameters have the same meaning as in the AlphaLigne class. + */ +void IntLigne::Raster(raster_info &dest, void *color, RasterInRunFunc worker) +{ + if ( nbRun <= 0 ) { + return; + } + + int min = runs[0].st; + int max = runs[nbRun-1].en; + if ( dest.endPix <= min || dest.startPix >= max ) { + return; + } + + int curRun = -1; + for (curRun = 0; curRun < nbRun; curRun++) { + if ( runs[curRun].en > dest.startPix ) { + break; + } + } + + if ( curRun >= nbRun ) { + return; + } + + if ( runs[curRun].st < dest.startPix ) { + int nst = runs[curRun].st; + int nen = runs[curRun].en; + float vst = runs[curRun].vst; + float ven = runs[curRun].ven; + float nvst = (vst * (nen - dest.startPix) + ven * (dest.startPix - nst)) / ((float) (nen - nst)); + if ( runs[curRun].en <= dest.endPix ) { + (worker)(dest, color, dest.startPix, nvst, runs[curRun].en, runs[curRun].ven); + } else { + float nven = (vst * (nen - dest.endPix) + ven * (dest.endPix - nst)) / ((float)(nen - nst)); + (worker)(dest, color, dest.startPix, nvst, dest.endPix, nven); + return; + } + curRun++; + } + + for (; (curRun < nbRun && runs[curRun].en <= dest.endPix); curRun++) { + (worker)(dest, color, runs[curRun].st, runs[curRun].vst, runs[curRun].en, runs[curRun].ven); +//Buffer::RasterRun(*dest,color,runs[curRun].st,runs[curRun].vst,runs[curRun].en,runs[curRun].ven); + } + + if ( curRun >= nbRun ) { + return; + } + + if ( runs[curRun].st < dest.endPix && runs[curRun].en > dest.endPix ) { + int const nst = runs[curRun].st; + int const nen = runs[curRun].en; + float const vst = runs[curRun].vst; + float const ven = runs[curRun].ven; + float const nven = (vst * (nen - dest.endPix) + ven * (dest.endPix - nst)) / ((float)(nen - nst)); + + (worker)(dest,color,runs[curRun].st,runs[curRun].vst,dest.endPix,nven); + curRun++; + } +} + + + +/* + 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 : diff --git a/src/livarot/int-line.h b/src/livarot/int-line.h new file mode 100644 index 000000000..6ed011c04 --- /dev/null +++ b/src/livarot/int-line.h @@ -0,0 +1,107 @@ +#ifndef INKSCAPE_LIVAROT_INT_LINE_H +#define INKSCAPE_LIVAROT_INT_LINE_H + +#include "livarot/livarot-forward.h" +#include "livarot/LivarotDefs.h" + +/** \file + * Coverage with integer boundaries. + */ + +/// A run with integer boundaries. +struct int_ligne_run { + int st; + int en; + float vst; + float ven; +}; + +/// Integer boundary. +struct int_ligne_bord { + int pos; + bool start; + float val; + int other; + int prev; + int next; +}; + +/** + * Coverage with integer boundaries. + * + * This is what we want for actual rasterization. It contains the same + * stuff as FloatLigne, but technically only the Copy() functions are used. + */ +class IntLigne { +public: + + int nbBord; + int maxBord; + int_ligne_bord* bords; + + int nbRun; + int maxRun; + int_ligne_run* runs; + + int firstAc; + int lastAc; + + IntLigne(); + ~IntLigne(); + + void Reset(); + int AddBord(int spos, float sval, int epos, float eval); + + void Flatten(); + + void Affiche(); + + int AddRun(int st, int en, float vst, float ven); + + void Booleen(IntLigne* a, IntLigne* b, BooleanOp mod); + + void Copy(IntLigne* a); + void Copy(FloatLigne* a); + void Copy(BitLigne* a); + void Copy(int nbSub,BitLigne **a); + + void Enqueue(int no); + void Dequeue(int no); + float RemainingValAt(int at); + + static int CmpBord(void const *p1, void const *p2) { + int_ligne_bord const *d1 = reinterpret_cast(p1); + int_ligne_bord const *d2 = reinterpret_cast(p2); + + if ( d1->pos == d2->pos ) { + if ( d1->start && !(d2->start) ) { + return 1; + } + if ( !(d1->start) && d2->start ) { + return -1; + } + return 0; + } + return (( d1->pos < d2->pos ) ? -1 : 1); + }; + + inline float ValAt(int at, int ps, int pe, float vs, float ve) { + return ((at - ps) * ve + (pe - at) * vs) / (pe - ps); + }; + + void Raster(raster_info &dest, void *color, RasterInRunFunc worker); +}; + + +#endif + +/* + 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:textwidth=99 : diff --git a/src/livarot/livarot-forward.h b/src/livarot/livarot-forward.h new file mode 100644 index 000000000..9705b18e0 --- /dev/null +++ b/src/livarot/livarot-forward.h @@ -0,0 +1,28 @@ +#ifndef SEEN_LIVAROT_FORWARD_H +#define SEEN_LIVAROT_FORWARD_H + +class Path; +class Shape; +struct float_ligne_run; +class FloatLigne; +class BitLigne; +class PathDescr; +class PathDescrLineTo; +class PathDescrArcTo; +class PathDescrCubicTo; +class PathDescrBezierTo; +class PathDescrIntermBezierTo; + + +#endif /* !SEEN_LIVAROT_FORWARD_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 : diff --git a/src/livarot/makefile.in b/src/livarot/makefile.in new file mode 100644 index 000000000..09b4789b9 --- /dev/null +++ b/src/livarot/makefile.in @@ -0,0 +1,17 @@ +# Convenience stub makefile to call the real Makefile. + +@SET_MAKE@ + +# Explicit so that it's the default rule. +all: + cd .. && $(MAKE) livarot/all + +clean %.a %.o: + cd .. && $(MAKE) livarot/$@ + +.PHONY: all clean + +OBJEXT = @OBJEXT@ + +.SUFFIXES: +.SUFFIXES: .a .$(OBJEXT) diff --git a/src/livarot/path-description.cpp b/src/livarot/path-description.cpp new file mode 100644 index 000000000..96cd81ee6 --- /dev/null +++ b/src/livarot/path-description.cpp @@ -0,0 +1,171 @@ +#include "libnr/nr-point-matrix-ops.h" +#include "livarot/path-description.h" + +PathDescr *PathDescrMoveTo::clone() const +{ + return new PathDescrMoveTo(*this); +} + +void PathDescrMoveTo::dumpSVG(Inkscape::SVGOStringStream& s, NR::Point const &last) const +{ + s << "M " << p[NR::X] << " " << p[NR::Y] << " "; +} + +void PathDescrMoveTo::transform(NR::Matrix const& t) +{ + p = p * t; +} + +void PathDescrMoveTo::dump(std::ostream &s) const +{ + /* localizing ok */ + s << " m " << p[NR::X] << " " << p[NR::Y]; +} + +void PathDescrLineTo::dumpSVG(Inkscape::SVGOStringStream& s, NR::Point const &last) const +{ + s << "L " << p[NR::X] << " " << p[NR::Y] << " "; +} + +PathDescr *PathDescrLineTo::clone() const +{ + return new PathDescrLineTo(*this); +} + +void PathDescrLineTo::transform(NR::Matrix const& t) +{ + p = p * t; +} + +void PathDescrLineTo::dump(std::ostream &s) const +{ + /* localizing ok */ + s << " l " << p[NR::X] << " " << p[NR::Y]; +} + +PathDescr *PathDescrBezierTo::clone() const +{ + return new PathDescrBezierTo(*this); +} + +void PathDescrBezierTo::transform(NR::Matrix const& t) +{ + p = p * t; +} + +void PathDescrBezierTo::dump(std::ostream &s) const +{ + /* localizing ok */ + s << " b " << p[NR::X] << " " << p[NR::Y] << " " << nb; +} + +PathDescr *PathDescrIntermBezierTo::clone() const +{ + return new PathDescrIntermBezierTo(*this); +} + +void PathDescrIntermBezierTo::transform(NR::Matrix const& t) +{ + p = p * t; +} + +void PathDescrIntermBezierTo::dump(std::ostream &s) const +{ + /* localizing ok */ + s << " i " << p[NR::X] << " " << p[NR::Y]; +} + +void PathDescrCubicTo::dumpSVG(Inkscape::SVGOStringStream& s, NR::Point const &last) const +{ + s << "C " + << last[NR::X] + start[0] / 3 << " " + << last[NR::Y] + start[1] / 3 << " " + << p[NR::X] - end[0] / 3 << " " + << p[NR::Y] - end[1] / 3 << " " + << p[NR::X] << " " + << p[NR::Y] << " "; +} + +PathDescr *PathDescrCubicTo::clone() const +{ + return new PathDescrCubicTo(*this); +} + +void PathDescrCubicTo::dump(std::ostream &s) const +{ + /* localizing ok */ + s << " c " + << p[NR::X] << " " << p[NR::Y] << " " + << start[NR::X] << " " << start[NR::Y] << " " + << end[NR::X] << " " << end[NR::Y] << " "; +} + +void PathDescrCubicTo::transform(NR::Matrix const& t) +{ + NR::Matrix tr = t; + tr[4] = tr[5] = 0; + start = start * tr; + end = end * tr; + + p = p * t; +} + +void PathDescrArcTo::dumpSVG(Inkscape::SVGOStringStream& s, NR::Point const &last) const +{ + s << "A " + << rx << " " + << ry << " " + << angle << " " + << (large ? "1" : "0") << " " + << (clockwise ? "0" : "1") << " " + << p[NR::X] << " " + << p[NR::Y] << " "; +} + +PathDescr *PathDescrArcTo::clone() const +{ + return new PathDescrArcTo(*this); +} + +void PathDescrArcTo::transform(NR::Matrix const& t) +{ + p = p * t; +} + +void PathDescrArcTo::dump(std::ostream &s) const +{ + /* localizing ok */ + s << " a " + << p[NR::X] << " " << p[NR::Y] << " " + << rx << " " << ry << " " + << angle << " " + << (clockwise ? 1 : 0) << " " + << (large ? 1 : 0); +} + +PathDescr *PathDescrForced::clone() const +{ + return new PathDescrForced(*this); +} + +void PathDescrClose::dumpSVG(Inkscape::SVGOStringStream& s, NR::Point const &last) const +{ + s << "z "; +} + +PathDescr *PathDescrClose::clone() const +{ + return new PathDescrClose(*this); +} + + +/* + 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 : diff --git a/src/livarot/path-description.h b/src/livarot/path-description.h new file mode 100644 index 000000000..0086d86b1 --- /dev/null +++ b/src/livarot/path-description.h @@ -0,0 +1,165 @@ +#ifndef SEEN_INKSCAPE_LIVAROT_PATH_DESCRIPTION_H +#define SEEN_INKSCAPE_LIVAROT_PATH_DESCRIPTION_H + +#include "svg/stringstream.h" +#include "libnr/nr-point.h" + +// path description commands +/* FIXME: these should be unnecessary once the refactoring of the path +** description stuff is finished. +*/ +enum +{ + descr_moveto = 0, // a moveto + descr_lineto = 1, // a (guess what) lineto + descr_cubicto = 2, + descr_bezierto = 3, // "beginning" of a quadratic bezier spline, will contain its endpoint (i know, it's bad...) + descr_arcto = 4, + descr_close = 5, + descr_interm_bezier = 6, // control point of the bezier spline + descr_forced = 7, + + descr_type_mask = 15 // the command no will be stored in a "flags" field, potentially with other info, so we need + // a mask to AND the field and extract the command +}; + +struct PathDescr +{ + PathDescr() : flags(0), associated(-1), tSt(0), tEn(1) {} + PathDescr(int f) : flags(f), associated(-1), tSt(0), tEn(1) {} + virtual ~PathDescr() {} + + int getType() const { return flags & descr_type_mask; } + void setType(int t) { + flags &= ~descr_type_mask; + flags |= t; + } + + virtual void dumpSVG(Inkscape::SVGOStringStream &s, NR::Point const &last) const {} + virtual PathDescr *clone() const = 0; + virtual void transform(NR::Matrix const &t) {} + virtual void dump(std::ostream &s) const {} + + int flags; // most notably contains the path command no + int associated; // index in the polyline of the point that ends the path portion of this command + double tSt; + double tEn; +}; + +struct PathDescrMoveTo : public PathDescr +{ + PathDescrMoveTo(NR::Point const &pp) + : PathDescr(descr_moveto), p(pp) {} + + void dumpSVG(Inkscape::SVGOStringStream &s, NR::Point const &last) const; + PathDescr *clone() const; + void transform(NR::Matrix const &t); + void dump(std::ostream &s) const; + + NR::Point p; +}; + +struct PathDescrLineTo : public PathDescr +{ + PathDescrLineTo(NR::Point const &pp) + : PathDescr(descr_lineto), p(pp) {} + + void dumpSVG(Inkscape::SVGOStringStream &s, NR::Point const &last) const; + PathDescr *clone() const; + void transform(NR::Matrix const &t); + void dump(std::ostream &s) const; + + NR::Point p; +}; + +// quadratic bezier curves: a set of control points, and an endpoint +struct PathDescrBezierTo : public PathDescr +{ + PathDescrBezierTo(NR::Point const &pp, int n) + : PathDescr(descr_bezierto), p(pp), nb(n) {} + + PathDescr *clone() const; + void transform(NR::Matrix const &t); + void dump(std::ostream &s) const; + + NR::Point p; // the endpoint's coordinates + int nb; // number of control points, stored in the next path description commands +}; + +/* FIXME: I don't think this should be necessary */ +struct PathDescrIntermBezierTo : public PathDescr +{ + PathDescrIntermBezierTo() + : PathDescr(descr_interm_bezier) , p(0, 0) {} + PathDescrIntermBezierTo(NR::Point const &pp) + : PathDescr(descr_interm_bezier), p(pp) {} + + PathDescr *clone() const; + void transform(NR::Matrix const &t); + void dump(std::ostream &s) const; + + NR::Point p; // control point coordinates +}; + +// cubic spline curve: 2 tangents and one endpoint +struct PathDescrCubicTo : public PathDescr +{ + PathDescrCubicTo(NR::Point const &pp, NR::Point const &s, NR::Point const& e) + : PathDescr(descr_cubicto), p(pp), start(s), end(e) {} + + void dumpSVG(Inkscape::SVGOStringStream &s, NR::Point const &last) const; + PathDescr *clone() const; + void transform(NR::Matrix const &t); + void dump(std::ostream &s) const; + + NR::Point p; + NR::Point start; + NR::Point end; +}; + +// arc: endpoint, 2 radii and one angle, plus 2 booleans to choose the arc (svg style) +struct PathDescrArcTo : public PathDescr +{ + PathDescrArcTo(NR::Point const &pp, double x, double y, double a, bool l, bool c) + : PathDescr(descr_arcto), p(pp), rx(x), ry(y), angle(a), large(l), clockwise(c) {} + + void dumpSVG(Inkscape::SVGOStringStream &s, NR::Point const &last) const; + PathDescr *clone() const; + void transform(NR::Matrix const &t); + void dump(std::ostream &s) const; + + NR::Point p; + double rx; + double ry; + double angle; + bool large; + bool clockwise; +}; + +struct PathDescrForced : public PathDescr +{ + PathDescrForced() : PathDescr(descr_forced), p(0, 0) {} + + PathDescr *clone() const; + + /* FIXME: not sure whether _forced should have a point associated with it; + ** Path::ConvertForcedToMoveTo suggests that maybe it should. + */ + NR::Point p; +}; + +struct PathDescrClose : public PathDescr +{ + PathDescrClose() : PathDescr(descr_close) {} + + void dumpSVG(Inkscape::SVGOStringStream &s, NR::Point const &last) const; + PathDescr *clone() const; + + /* FIXME: not sure whether _forced should have a point associated with it; + ** Path::ConvertForcedToMoveTo suggests that maybe it should. + */ + NR::Point p; +}; + +#endif + diff --git a/src/livarot/sweep-event-queue.h b/src/livarot/sweep-event-queue.h new file mode 100644 index 000000000..b3cdd4c9d --- /dev/null +++ b/src/livarot/sweep-event-queue.h @@ -0,0 +1,54 @@ +#ifndef SEEN_LIVAROT_SWEEP_EVENT_QUEUE_H +#define SEEN_LIVAROT_SWEEP_EVENT_QUEUE_H +/** \file + * A container of intersection events. + */ + +#include +class SweepEvent; +class SweepTree; + + +/** + * The structure to hold the intersections events encountered during the sweep. It's an array of + * SweepEvent (not allocated with "new SweepEvent[n]" but with a malloc). There's a list of + * indices because it's a binary heap: inds[i] tell that events[inds[i]] has position i in the + * heap. Each SweepEvent has a field to store its index in the heap, too. + */ +class SweepEventQueue +{ +public: + SweepEventQueue(int s); + ~SweepEventQueue(); + + int size() const { return nbEvt; } + + /// Look for the topmost intersection in the heap + bool peek(SweepTree * &iLeft, SweepTree * &iRight, NR::Point &oPt, double &itl, double &itr); + /// Extract the topmost intersection from the heap + bool extract(SweepTree * &iLeft, SweepTree * &iRight, NR::Point &oPt, double &itl, double &itr); + /// Add one intersection in the binary heap + SweepEvent *add(SweepTree *iLeft, SweepTree *iRight, NR::Point &iPt, double itl, double itr); + + void remove(SweepEvent *e); + void relocate(SweepEvent *e, int to); + +private: + int nbEvt; ///< Number of events currently in the heap. + int maxEvt; ///< Allocated size of the heap. + int *inds; ///< Indices. + SweepEvent *events; ///< Sweep events. +}; + +#endif /* !SEEN_LIVAROT_SWEEP_EVENT_QUEUE_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:encoding=utf-8:textwidth=99 : diff --git a/src/livarot/sweep-event.cpp b/src/livarot/sweep-event.cpp new file mode 100644 index 000000000..e84048a07 --- /dev/null +++ b/src/livarot/sweep-event.cpp @@ -0,0 +1,275 @@ +#include +#include "livarot/sweep-event-queue.h" +#include "livarot/sweep-tree.h" +#include "livarot/sweep-event.h" +#include "livarot/Shape.h" + +SweepEventQueue::SweepEventQueue(int s) : nbEvt(0), maxEvt(s) +{ + /* FIXME: use new[] for this, but this causes problems when delete[] + ** calls the SweepEvent destructors. + */ + events = (SweepEvent *) g_malloc(maxEvt * sizeof(SweepEvent)); + inds = new int[maxEvt]; +} + +SweepEventQueue::~SweepEventQueue() +{ + g_free(events); + delete []inds; +} + +SweepEvent *SweepEventQueue::add(SweepTree *iLeft, SweepTree *iRight, NR::Point &px, double itl, double itr) +{ + if (nbEvt > maxEvt) { + return NULL; + } + + int const n = nbEvt++; + events[n].MakeNew (iLeft, iRight, px, itl, itr); + + SweepTree *t[2] = { iLeft, iRight }; + for (int i = 0; i < 2; i++) { + Shape *s = t[i]->src; + Shape::dg_arete const &e = s->getEdge(t[i]->bord); + int const n = std::max(e.st, e.en); + s->pData[n].pending++;; + } + + events[n].ind = n; + inds[n] = n; + + int curInd = n; + while (curInd > 0) { + int const half = (curInd - 1) / 2; + int const no = inds[half]; + if (px[1] < events[no].posx[1] + || (px[1] == events[no].posx[1] && px[0] < events[no].posx[0])) + { + events[n].ind = half; + events[no].ind = curInd; + inds[half] = n; + inds[curInd] = no; + } else { + break; + } + + curInd = half; + } + + return events + n; +} + + + +bool SweepEventQueue::peek(SweepTree * &iLeft, SweepTree * &iRight, NR::Point &px, double &itl, double &itr) +{ + if (nbEvt <= 0) { + return false; + } + + SweepEvent const &e = events[inds[0]]; + + iLeft = e.sweep[LEFT]; + iRight = e.sweep[RIGHT]; + px = e.posx; + itl = e.tl; + itr = e.tr; + + return true; +} + +bool SweepEventQueue::extract(SweepTree * &iLeft, SweepTree * &iRight, NR::Point &px, double &itl, double &itr) +{ + if (nbEvt <= 0) { + return false; + } + + SweepEvent &e = events[inds[0]]; + + iLeft = e.sweep[LEFT]; + iRight = e.sweep[RIGHT]; + px = e.posx; + itl = e.tl; + itr = e.tr; + remove(&e); + + return true; +} + + +void SweepEventQueue::remove(SweepEvent *e) +{ + if (nbEvt <= 1) { + e->MakeDelete (); + nbEvt = 0; + return; + } + + int const n = e->ind; + int to = inds[n]; + e->MakeDelete(); + relocate(&events[--nbEvt], to); + + int const moveInd = nbEvt; + if (moveInd == n) { + return; + } + + to = inds[moveInd]; + + events[to].ind = n; + inds[n] = to; + + int curInd = n; + NR::Point const px = events[to].posx; + bool didClimb = false; + while (curInd > 0) { + int const half = (curInd - 1) / 2; + int const no = inds[half]; + if (px[1] < events[no].posx[1] + || (px[1] == events[no].posx[1] && px[0] < events[no].posx[0])) + { + events[to].ind = half; + events[no].ind = curInd; + inds[half] = to; + inds[curInd] = no; + didClimb = true; + } else { + break; + } + curInd = half; + } + + if (didClimb) { + return; + } + + while (2 * curInd + 1 < nbEvt) { + int const son1 = 2 * curInd + 1; + int const son2 = son1 + 1; + int const no1 = inds[son1]; + int const no2 = inds[son2]; + if (son2 < nbEvt) { + if (px[1] > events[no1].posx[1] + || (px[1] == events[no1].posx[1] + && px[0] > events[no1].posx[0])) + { + if (events[no2].posx[1] > events[no1].posx[1] + || (events[no2].posx[1] == events[no1].posx[1] + && events[no2].posx[0] > events[no1].posx[0])) + { + events[to].ind = son1; + events[no1].ind = curInd; + inds[son1] = to; + inds[curInd] = no1; + curInd = son1; + } else { + events[to].ind = son2; + events[no2].ind = curInd; + inds[son2] = to; + inds[curInd] = no2; + curInd = son2; + } + } else { + if (px[1] > events[no2].posx[1] + || (px[1] == events[no2].posx[1] + && px[0] > events[no2].posx[0])) + { + events[to].ind = son2; + events[no2].ind = curInd; + inds[son2] = to; + inds[curInd] = no2; + curInd = son2; + } else { + break; + } + } + } else { + if (px[1] > events[no1].posx[1] + || (px[1] == events[no1].posx[1] + && px[0] > events[no1].posx[0])) + { + events[to].ind = son1; + events[no1].ind = curInd; + inds[son1] = to; + inds[curInd] = no1; + } + + break; + } + } +} + + + + +void SweepEventQueue::relocate(SweepEvent *e, int to) +{ + if (inds[e->ind] == to) { + return; // j'y suis deja + } + + events[to] = *e; + + e->sweep[LEFT]->evt[RIGHT] = events + to; + e->sweep[RIGHT]->evt[LEFT] = events + to; + inds[e->ind] = to; +} + + +/* + * a simple binary heap + * it only contains intersection events + * the regular benley-ottman stuffs the segment ends in it too, but that not needed here since theses points + * are already sorted. and the binary heap is much faster with only intersections... + * the code sample on which this code is based comes from purists.org + */ +SweepEvent::SweepEvent() +{ + MakeNew (NULL, NULL, NR::Point(0, 0), 0, 0); +} + +SweepEvent::~SweepEvent() +{ + MakeDelete(); +} + +void SweepEvent::MakeNew(SweepTree *iLeft, SweepTree *iRight, NR::Point const &px, double itl, double itr) +{ + ind = -1; + posx = px; + tl = itl; + tr = itr; + sweep[LEFT] = iLeft; + sweep[RIGHT] = iRight; + sweep[LEFT]->evt[RIGHT] = this; + sweep[RIGHT]->evt[LEFT] = this; +} + +void SweepEvent::MakeDelete() +{ + for (int i = 0; i < 2; i++) { + if (sweep[i]) { + Shape *s = sweep[i]->src; + Shape::dg_arete const &e = s->getEdge(sweep[i]->bord); + int const n = std::max(e.st, e.en); + s->pData[n].pending--; + } + + sweep[i]->evt[1 - i] = NULL; + sweep[i] = NULL; + } +} + + +/* + 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:textwidth=99 : diff --git a/src/livarot/sweep-event.h b/src/livarot/sweep-event.h new file mode 100644 index 000000000..7231dd01d --- /dev/null +++ b/src/livarot/sweep-event.h @@ -0,0 +1,45 @@ +#ifndef INKSCAPE_LIVAROT_SWEEP_EVENT_H +#define INKSCAPE_LIVAROT_SWEEP_EVENT_H +/** \file + * Intersection events. + */ + +#include +class SweepTree; + + +/** One intersection event. */ +class SweepEvent +{ +public: + SweepTree *sweep[2]; ///< Sweep element associated with the left and right edge of the intersection. + + NR::Point posx; ///< Coordinates of the intersection. + double tl, tr; ///< Coordinates of the intersection on the left edge (tl) and on the right edge (tr). + + int ind; ///< Index in the binary heap. + + SweepEvent(); // not used. + ~SweepEvent(); // not used. + + /// Initialize a SweepEvent structure. + void MakeNew (SweepTree * iLeft, SweepTree * iRight, NR::Point const &iPt, + double itl, double itr); + + /// Void a SweepEvent structure. + void MakeDelete (void); +}; + + +#endif /* !INKSCAPE_LIVAROT_SWEEP_EVENT_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:encoding=utf-8:textwidth=99 : diff --git a/src/livarot/sweep-tree-list.cpp b/src/livarot/sweep-tree-list.cpp new file mode 100644 index 000000000..d59728e42 --- /dev/null +++ b/src/livarot/sweep-tree-list.cpp @@ -0,0 +1,47 @@ +#include +#include "livarot/sweep-tree.h" +#include "livarot/sweep-tree-list.h" + + +SweepTreeList::SweepTreeList(int s) : + nbTree(0), + maxTree(s), + trees((SweepTree *) g_malloc(s * sizeof(SweepTree))), + racine(NULL) +{ + /* FIXME: Use new[] for trees initializer above, but watch out for bad things happening when + * SweepTree::~SweepTree is called. + */ +} + + +SweepTreeList::~SweepTreeList() +{ + g_free(trees); + trees = NULL; +} + + +SweepTree *SweepTreeList::add(Shape *iSrc, int iBord, int iWeight, int iStartPoint, Shape *iDst) +{ + if (nbTree >= maxTree) { + return NULL; + } + + int const n = nbTree++; + trees[n].MakeNew(iSrc, iBord, iWeight, iStartPoint); + + return trees + n; +} + + +/* + 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:textwidth=99 : diff --git a/src/livarot/sweep-tree-list.h b/src/livarot/sweep-tree-list.h new file mode 100644 index 000000000..730b1cc55 --- /dev/null +++ b/src/livarot/sweep-tree-list.h @@ -0,0 +1,37 @@ +#ifndef INKSCAPE_LIVAROT_SWEEP_TREE_LIST_H +#define INKSCAPE_LIVAROT_SWEEP_TREE_LIST_H +/** \file SweepTreeList definition. */ + +class Shape; +class SweepTree; + +/** + * The sweepline: a set of edges intersecting the current sweepline + * stored as an AVL tree. + */ +class SweepTreeList { +public: + int nbTree; ///< Number of nodes in the tree. + int const maxTree; ///< Max number of nodes in the tree. + SweepTree *trees; ///< The array of nodes. + SweepTree *racine; ///< Root of the tree. + + SweepTreeList(int s); + ~SweepTreeList(); + + SweepTree *add(Shape *iSrc, int iBord, int iWeight, int iStartPoint, Shape *iDst); +}; + + +#endif /* !INKSCAPE_LIVAROT_SWEEP_TREE_LIST_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:encoding=utf-8:textwidth=99 : diff --git a/src/livarot/sweep-tree.cpp b/src/livarot/sweep-tree.cpp new file mode 100644 index 000000000..0e4567663 --- /dev/null +++ b/src/livarot/sweep-tree.cpp @@ -0,0 +1,558 @@ +#include "libnr/nr-point-fns.h" +#include "livarot/sweep-event-queue.h" +#include "livarot/sweep-tree-list.h" +#include "livarot/sweep-tree.h" +#include "livarot/sweep-event.h" +#include "livarot/Shape.h" + + +/* + * the AVL tree holding the edges intersecting the sweepline + * that structure is very sensitive to anything + * you have edges stored in nodes, the nodes are sorted in increasing x-order of intersection + * with the sweepline, you have the 2 potential intersections of the edge in the node with its + * neighbours, plus the fact that it's stored in an array that's realloc'd + */ + +SweepTree::SweepTree() +{ + src = NULL; + bord = -1; + startPoint = -1; + evt[LEFT] = evt[RIGHT] = NULL; + sens = true; + //invDirLength=1; +} + +SweepTree::~SweepTree() +{ + MakeDelete(); +} + +void +SweepTree::MakeNew(Shape *iSrc, int iBord, int iWeight, int iStartPoint) +{ + AVLTree::MakeNew(); + ConvertTo(iSrc, iBord, iWeight, iStartPoint); +} + +void +SweepTree::ConvertTo(Shape *iSrc, int iBord, int iWeight, int iStartPoint) +{ + src = iSrc; + bord = iBord; + evt[LEFT] = evt[RIGHT] = NULL; + startPoint = iStartPoint; + if (src->getEdge(bord).st < src->getEdge(bord).en) { + if (iWeight >= 0) + sens = true; + else + sens = false; + } else { + if (iWeight >= 0) + sens = false; + else + sens = true; + } + //invDirLength=src->eData[bord].isqlength; + //invDirLength=1/sqrt(src->getEdge(bord).dx*src->getEdge(bord).dx+src->getEdge(bord).dy*src->getEdge(bord).dy); +} + + +void SweepTree::MakeDelete() +{ + for (int i = 0; i < 2; i++) { + if (evt[i]) { + evt[i]->sweep[1 - i] = NULL; + } + evt[i] = NULL; + } + + AVLTree::MakeDelete(); +} + + +// find the position at which node "newOne" should be inserted in the subtree rooted here +// we want to order with respect to the order of intersections with the sweepline, currently +// lying at y=px[1]. +// px is the upper endpoint of newOne +int +SweepTree::Find(NR::Point const &px, SweepTree *newOne, SweepTree *&insertL, + SweepTree *&insertR, bool sweepSens) +{ + // get the edge associated with this node: one point+one direction + // since we're dealing with line, the direction (bNorm) is taken downwards + NR::Point bOrig, bNorm; + bOrig = src->pData[src->getEdge(bord).st].rx; + bNorm = src->eData[bord].rdx; + if (src->getEdge(bord).st > src->getEdge(bord).en) { + bNorm = -bNorm; + } + // rotate to get the normal to the edge + bNorm=bNorm.ccw(); + + NR::Point diff; + diff = px - bOrig; + + // compute (px-orig)^dir to know on which side of this edge the point px lies + double y = 0; + //if ( startPoint == newOne->startPoint ) { + // y=0; + //} else { + y = dot(bNorm, diff); + //} + //y*=invDirLength; + if (fabs(y) < 0.000001) { + // that damn point px lies on me, so i need to consider to direction of the edge in + // newOne to know if it goes toward my left side or my right side + // sweepSens is needed (actually only used by the Scan() functions) because if the sweepline goes upward, + // signs change + // prendre en compte les directions + NR::Point nNorm; + nNorm = newOne->src->eData[newOne->bord].rdx; + if (newOne->src->getEdge(newOne->bord).st > + newOne->src->getEdge(newOne->bord).en) + { + nNorm = -nNorm; + } + nNorm=nNorm.ccw(); + + if (sweepSens) { + y = cross(nNorm, bNorm); + } else { + y = cross(bNorm, nNorm); + } + if (y == 0) { + y = dot(bNorm, nNorm); + if (y == 0) { + insertL = this; + insertR = static_cast(elem[RIGHT]); + return found_exact; + } + } + } + if (y < 0) { + if (son[LEFT]) { + return (static_cast(son[LEFT]))->Find(px, newOne, + insertL, insertR, + sweepSens); + } else { + insertR = this; + insertL = static_cast(elem[LEFT]); + if (insertL) { + return found_between; + } else { + return found_on_left; + } + } + } else { + if (son[RIGHT]) { + return (static_cast(son[RIGHT]))->Find(px, newOne, + insertL, insertR, + sweepSens); + } else { + insertL = this; + insertR = static_cast(elem[RIGHT]); + if (insertR) { + return found_between; + } else { + return found_on_right; + } + } + } + return not_found; +} + +// only find a point's position +int +SweepTree::Find(NR::Point const &px, SweepTree * &insertL, + SweepTree * &insertR) +{ + NR::Point bOrig, bNorm; + bOrig = src->pData[src->getEdge(bord).st].rx; + bNorm = src->eData[bord].rdx; + if (src->getEdge(bord).st > src->getEdge(bord).en) + { + bNorm = -bNorm; + } + bNorm=bNorm.ccw(); + + NR::Point diff; + diff = px - bOrig; + + double y = 0; + y = dot(bNorm, diff); + if (y == 0) + { + insertL = this; + insertR = static_cast(elem[RIGHT]); + return found_exact; + } + if (y < 0) + { + if (son[LEFT]) + { + return (static_cast(son[LEFT]))->Find(px, insertL, + insertR); + } + else + { + insertR = this; + insertL = static_cast(elem[LEFT]); + if (insertL) + { + return found_between; + } + else + { + return found_on_left; + } + } + } + else + { + if (son[RIGHT]) + { + return (static_cast(son[RIGHT]))->Find(px, insertL, + insertR); + } + else + { + insertL = this; + insertR = static_cast(elem[RIGHT]); + if (insertR) + { + return found_between; + } + else + { + return found_on_right; + } + } + } + return not_found; +} + +void +SweepTree::RemoveEvents(SweepEventQueue & queue) +{ + RemoveEvent(queue, LEFT); + RemoveEvent(queue, RIGHT); +} + +void SweepTree::RemoveEvent(SweepEventQueue &queue, Side s) +{ + if (evt[s]) { + queue.remove(evt[s]); + evt[s] = NULL; + } +} + +int +SweepTree::Remove(SweepTreeList &list, SweepEventQueue &queue, + bool rebalance) +{ + RemoveEvents(queue); + AVLTree *tempR = static_cast(list.racine); + int err = AVLTree::Remove(tempR, rebalance); + list.racine = static_cast(tempR); + MakeDelete(); + if (list.nbTree <= 1) + { + list.nbTree = 0; + list.racine = NULL; + } + else + { + if (list.racine == list.trees + (list.nbTree - 1)) + list.racine = this; + list.trees[--list.nbTree].Relocate(this); + } + return err; +} + +int +SweepTree::Insert(SweepTreeList &list, SweepEventQueue &queue, + Shape *iDst, int iAtPoint, bool rebalance, bool sweepSens) +{ + if (list.racine == NULL) + { + list.racine = this; + return avl_no_err; + } + SweepTree *insertL = NULL; + SweepTree *insertR = NULL; + int insertion = + list.racine->Find(iDst->getPoint(iAtPoint).x, this, + insertL, insertR, sweepSens); + + if (insertion == found_exact) { + if (insertR) { + insertR->RemoveEvent(queue, LEFT); + } + if (insertL) { + insertL->RemoveEvent(queue, RIGHT); + } + + } else if (insertion == found_between) { + insertR->RemoveEvent(queue, LEFT); + insertL->RemoveEvent(queue, RIGHT); + } + + AVLTree *tempR = static_cast(list.racine); + int err = + AVLTree::Insert(tempR, insertion, static_cast(insertL), + static_cast(insertR), rebalance); + list.racine = static_cast(tempR); + return err; +} + +// insertAt() is a speedup on the regular sweepline: if the polygon contains a point of high degree, you +// get a set of edge that are to be added in the same position. thus you insert one edge with a regular insert(), +// and then insert all the other in a doubly-linked list fashion. this avoids the Find() call, but is O(d^2) worst-case +// where d is the number of edge to add in this fashion. hopefully d remains small + +int +SweepTree::InsertAt(SweepTreeList &list, SweepEventQueue &queue, + Shape *iDst, SweepTree *insNode, int fromPt, + bool rebalance, bool sweepSens) +{ + if (list.racine == NULL) + { + list.racine = this; + return avl_no_err; + } + + NR::Point fromP; + fromP = src->pData[fromPt].rx; + NR::Point nNorm; + nNorm = src->getEdge(bord).dx; + if (src->getEdge(bord).st > src->getEdge(bord).en) + { + nNorm = -nNorm; + } + if (sweepSens == false) + { + nNorm = -nNorm; + } + + NR::Point bNorm; + bNorm = insNode->src->getEdge(insNode->bord).dx; + if (insNode->src->getEdge(insNode->bord).st > + insNode->src->getEdge(insNode->bord).en) + { + bNorm = -bNorm; + } + + SweepTree *insertL = NULL; + SweepTree *insertR = NULL; + double ang = cross(nNorm, bNorm); + if (ang == 0) + { + insertL = insNode; + insertR = static_cast(insNode->elem[RIGHT]); + } + else if (ang > 0) + { + insertL = insNode; + insertR = static_cast(insNode->elem[RIGHT]); + + while (insertL) + { + if (insertL->src == src) + { + if (insertL->src->getEdge(insertL->bord).st != fromPt + && insertL->src->getEdge(insertL->bord).en != fromPt) + { + break; + } + } + else + { + int ils = insertL->src->getEdge(insertL->bord).st; + int ile = insertL->src->getEdge(insertL->bord).en; + if ((insertL->src->pData[ils].rx[0] != fromP[0] + || insertL->src->pData[ils].rx[1] != fromP[1]) + && (insertL->src->pData[ile].rx[0] != fromP[0] + || insertL->src->pData[ile].rx[1] != fromP[1])) + { + break; + } + } + bNorm = insertL->src->getEdge(insertL->bord).dx; + if (insertL->src->getEdge(insertL->bord).st > + insertL->src->getEdge(insertL->bord).en) + { + bNorm = -bNorm; + } + ang = cross(nNorm, bNorm); + if (ang <= 0) + { + break; + } + insertR = insertL; + insertL = static_cast(insertR->elem[LEFT]); + } + } + else if (ang < 0) + { + insertL = insNode; + insertR = static_cast(insNode->elem[RIGHT]); + + while (insertR) + { + if (insertR->src == src) + { + if (insertR->src->getEdge(insertR->bord).st != fromPt + && insertR->src->getEdge(insertR->bord).en != fromPt) + { + break; + } + } + else + { + int ils = insertR->src->getEdge(insertR->bord).st; + int ile = insertR->src->getEdge(insertR->bord).en; + if ((insertR->src->pData[ils].rx[0] != fromP[0] + || insertR->src->pData[ils].rx[1] != fromP[1]) + && (insertR->src->pData[ile].rx[0] != fromP[0] + || insertR->src->pData[ile].rx[1] != fromP[1])) + { + break; + } + } + bNorm = insertR->src->getEdge(insertR->bord).dx; + if (insertR->src->getEdge(insertR->bord).st > + insertR->src->getEdge(insertR->bord).en) + { + bNorm = -bNorm; + } + ang = cross(nNorm, bNorm); + if (ang > 0) + { + break; + } + insertL = insertR; + insertR = static_cast(insertL->elem[RIGHT]); + } + } + + int insertion = found_between; + + if (insertL == NULL) { + insertion = found_on_left; + } + if (insertR == NULL) { + insertion = found_on_right; + } + + if (insertion == found_exact) { + /* FIXME: surely this can never be called? */ + if (insertR) { + insertR->RemoveEvent(queue, LEFT); + } + if (insertL) { + insertL->RemoveEvent(queue, RIGHT); + } + } else if (insertion == found_between) { + insertR->RemoveEvent(queue, LEFT); + insertL->RemoveEvent(queue, RIGHT); + } + + AVLTree *tempR = static_cast(list.racine); + int err = + AVLTree::Insert(tempR, insertion, static_cast(insertL), + static_cast(insertR), rebalance); + list.racine = static_cast(tempR); + return err; +} + +void +SweepTree::Relocate(SweepTree * to) +{ + if (this == to) + return; + AVLTree::Relocate(to); + to->src = src; + to->bord = bord; + to->sens = sens; + to->evt[LEFT] = evt[LEFT]; + to->evt[RIGHT] = evt[RIGHT]; + to->startPoint = startPoint; + if (unsigned(bord) < src->swsData.size()) + src->swsData[bord].misc = to; + if (unsigned(bord) < src->swrData.size()) + src->swrData[bord].misc = to; + if (evt[LEFT]) + evt[LEFT]->sweep[RIGHT] = to; + if (evt[RIGHT]) + evt[RIGHT]->sweep[LEFT] = to; +} + +void +SweepTree::SwapWithRight(SweepTreeList &list, SweepEventQueue &queue) +{ + SweepTree *tL = this; + SweepTree *tR = static_cast(elem[RIGHT]); + + tL->src->swsData[tL->bord].misc = tR; + tR->src->swsData[tR->bord].misc = tL; + + { + Shape *swap = tL->src; + tL->src = tR->src; + tR->src = swap; + } + { + int swap = tL->bord; + tL->bord = tR->bord; + tR->bord = swap; + } + { + int swap = tL->startPoint; + tL->startPoint = tR->startPoint; + tR->startPoint = swap; + } + //{double swap=tL->invDirLength;tL->invDirLength=tR->invDirLength;tR->invDirLength=swap;} + { + bool swap = tL->sens; + tL->sens = tR->sens; + tR->sens = swap; + } +} + +void +SweepTree::Avance(Shape *dstPts, int curPoint, Shape *a, Shape *b) +{ + return; +/* if ( curPoint != startPoint ) { + int nb=-1; + if ( sens ) { +// nb=dstPts->AddEdge(startPoint,curPoint); + } else { +// nb=dstPts->AddEdge(curPoint,startPoint); + } + if ( nb >= 0 ) { + dstPts->swsData[nb].misc=(void*)((src==b)?1:0); + int wp=waitingPoint; + dstPts->eData[nb].firstLinkedPoint=waitingPoint; + waitingPoint=-1; + while ( wp >= 0 ) { + dstPts->pData[wp].edgeOnLeft=nb; + wp=dstPts->pData[wp].nextLinkedPoint; + } + } + startPoint=curPoint; + }*/ +} + +/* + 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:textwidth=99 : diff --git a/src/livarot/sweep-tree.h b/src/livarot/sweep-tree.h new file mode 100644 index 000000000..80a1a8273 --- /dev/null +++ b/src/livarot/sweep-tree.h @@ -0,0 +1,82 @@ +#ifndef INKSCAPE_LIVAROT_SWEEP_TREE_H +#define INKSCAPE_LIVAROT_SWEEP_TREE_H + +#include "libnr/nr-point.h" +#include "livarot/AVL.h" + +class Shape; +class SweepEvent; +class SweepEventQueue; +class SweepTreeList; + + +/** + * One node in the AVL tree of edges. + * Note that these nodes will be stored in a dynamically allocated array, hence the Relocate() function. + */ +class SweepTree:public AVLTree +{ +public: + SweepEvent *evt[2]; ///< Intersection with the edge on the left and right (if any). + + Shape *src; /**< Shape from which the edge comes. (When doing boolean operation on polygons, + * edges can come from 2 different polygons.) + */ + int bord; ///< Edge index in the Shape. + bool sens; ///< true= top->bottom; false= bottom->top. + int startPoint; ///< point index in the result Shape associated with the upper end of the edge + + SweepTree(); + ~SweepTree(); + + // Inits a brand new node. + void MakeNew(Shape *iSrc, int iBord, int iWeight, int iStartPoint); + // changes the edge associated with this node + // goal: reuse the node when an edge follows another, which is the most common case + void ConvertTo(Shape *iSrc, int iBord, int iWeight, int iStartPoint); + + // Delete the contents of node. + void MakeDelete(); + + // utilites + + // the find function that was missing in the AVLTrree class + // the return values are defined in LivarotDefs.h + int Find(NR::Point const &iPt, SweepTree *newOne, SweepTree *&insertL, + SweepTree *&insertR, bool sweepSens = true); + int Find(NR::Point const &iPt, SweepTree *&insertL, SweepTree *&insertR); + + /// Remove sweepevents attached to this node. + void RemoveEvents(SweepEventQueue &queue); + + void RemoveEvent(SweepEventQueue &queue, Side s); + + // overrides of the AVLTree functions, to account for the sorting in the tree + // and some other stuff + int Remove(SweepTreeList &list, SweepEventQueue &queue, bool rebalance = true); + int Insert(SweepTreeList &list, SweepEventQueue &queue, Shape *iDst, + int iAtPoint, bool rebalance = true, bool sweepSens = true); + int InsertAt(SweepTreeList &list, SweepEventQueue &queue, Shape *iDst, + SweepTree *insNode, int fromPt, bool rebalance = true, bool sweepSens = true); + + /// Swap nodes, or more exactly, swap the edges in them. + void SwapWithRight(SweepTreeList &list, SweepEventQueue &queue); + + void Avance(Shape *dst, int nPt, Shape *a, Shape *b); + + void Relocate(SweepTree *to); +}; + + +#endif /* !INKSCAPE_LIVAROT_SWEEP_TREE_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:encoding=utf-8:textwidth=99 : diff --git a/src/macros.h b/src/macros.h new file mode 100644 index 000000000..d43dbc692 --- /dev/null +++ b/src/macros.h @@ -0,0 +1,54 @@ +#ifndef __MACROS_H__ +#define __MACROS_H__ + +/* + * Useful macros for inkscape + * + * Author: + * Lauris Kaplinski + * + * Copyright (C) 2002 Lauris Kaplinski + * + * Released under GNU GPL + */ + +#ifdef SP_MACROS_SILENT +#define SP_PRINT_MATRIX(s,m) +#define SP_PRINT_TRANSFORM(s,t) +#define SP_PRINT_DRECT(s,r) +#define SP_PRINT_DRECT_WH(s,r) +#define SP_PRINT_IRECT(s,r) +#define SP_PRINT_IRECT_WH(s,r) +#else +#define SP_PRINT_MATRIX(s,m) g_print("%s (%g %g %g %g %g %g)\n", (s), (m)->c[0], (m)->c[1], (m)->c[2], (m)->c[3], (m)->c[4], (m)->c[5]) +#define SP_PRINT_TRANSFORM(s,t) g_print("%s (%g %g %g %g %g %g)\n", (s), (t)[0], (t)[1], (t)[2], (t)[3], (t)[4], (t)[5]) +#define SP_PRINT_DRECT(s,r) g_print("%s (%g %g %g %g)\n", (s), (r)->x0, (r)->y0, (r)->x1, (r)->y1) +#define SP_PRINT_DRECT_WH(s,r) g_print("%s (%g %g %g %g)\n", (s), (r)->x0, (r)->y0, (r)->x1 - (r)->x0, (r)->y1 - (r)->y0) +#define SP_PRINT_IRECT(s,r) g_print("%s (%d %d %d %d)\n", (s), (r)->x0, (r)->y0, (r)->x1, (r)->y1) +#define SP_PRINT_IRECT_WH(s,r) g_print("%s (%d %d %d %d)\n", (s), (r)->x0, (r)->y0, (r)->x1 - (r)->x0, (r)->y1 - (r)->y0) +#endif + +#define sp_signal_disconnect_by_data(o,d) g_signal_handlers_disconnect_matched(o, G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, d) + +#define sp_round(v,m) (((v) < 0.0) ? ((ceil((v) / (m) - 0.5)) * (m)) : ((floor((v) / (m) + 0.5)) * (m))) + +#endif + +// keyboard modifiers in an event +#define MOD__SHIFT (event->key.state & GDK_SHIFT_MASK) +#define MOD__CTRL (event->key.state & GDK_CONTROL_MASK) +#define MOD__ALT (event->key.state & GDK_MOD1_MASK) +#define MOD__SHIFT_ONLY ((event->key.state & GDK_SHIFT_MASK) && !(event->key.state & GDK_CONTROL_MASK) && !(event->key.state & GDK_MOD1_MASK)) +#define MOD__CTRL_ONLY (!(event->key.state & GDK_SHIFT_MASK) && (event->key.state & GDK_CONTROL_MASK) && !(event->key.state & GDK_MOD1_MASK)) +#define MOD__ALT_ONLY (!(event->key.state & GDK_SHIFT_MASK) && !(event->key.state & GDK_CONTROL_MASK) && (event->key.state & GDK_MOD1_MASK)) + +/* + 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:textwidth=99 : diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 000000000..165316cd2 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,1543 @@ +#define __MAIN_C__ + +/** \file + * Inkscape - an ambitious vector drawing program + * + * Authors: + * Lauris Kaplinski + * Frank Felfe + * Davide Puricelli + * Mitsuru Oka + * Masatake YAMATO + * F.J.Franklin + * Michael Meeks + * Chema Celorio + * Pawel Palucha + * Bryce Harrington + * ... and various people who have worked with various projects + * + * Copyright (C) 1999-2004 authors + * Copyright (C) 2001-2002 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +// Putting the following in main.cpp appears a natural choice. + +/** \mainpage The Inkscape Source Code Documentation + * While the standard doxygen documentation can be accessed through the links + * in the header, the following documents are additionally available to the + * interested reader. + * + * \section groups Main directory documentation + * Inkscape's classes and files in the main directory can be grouped into + * the following categories: + * + * - \subpage ObjectTree - inkscape's SVG canvas + * - \subpage Tools - the tools UI + * - \subpage UI - inkscape's user interface + * - \subpage XmlTree - XML backbone of the document + * - \subpage Rendering - rendering and buffering + * - \subpage OtherServices - what doesn't fit in the above + * + * See also the
other directories until doxygen + * allows setting links to those doc files. + * + * \section extlinks Links to external documentation + * + * \subsection liblinks External documentation on libraries used in inkscape + * + * Gtkmm + * atkmm + * gdkmm + * pangomm + * libsigc++ + * GTK+ + * gdk-pixbuf + * GObject + * atk + * pango + * GnomeVFS + * libsigc + * ORBit + * bonobo + * bonobo-activation + * libxslt + * libxml2 + * + * \subsection stdlinks External standards documentation + * + * SVG1.1 + * SVG1.2 + * SVGMobile + * SVGTest + * PNG + * XSLT + * PS + * Gnome-HIG + */ + +/** \page ObjectTree Object Tree Classes and Files + * Inkscape::ObjectHierarchy [\ref object-hierarchy.cpp, \ref object-hierarchy.h] + * - SPObject [\ref sp-object.cpp, \ref sp-object.h, \ref object-edit.cpp, \ref sp-object-repr.cpp] + * - SPDefs [\ref sp-defs.cpp, \ref sp-defs.h] + * - SPFlowline [\ref sp-flowdiv.cpp, \ref sp-flowdiv.h] + * - SPFlowregionbreak [\ref sp-flowdiv.cpp, \ref sp-flowdiv.h] + * - SPGuide [\ref sp-guide.cpp, \ref sp-guide.h] + * - SPItem [\ref sp-item.cpp, \ref sp-item.h, \ref sp-item-notify-moveto.cpp, \ref sp-item-rm-unsatisfied-cns.cpp, \ref sp-item-transform.cpp, \ref sp-item-update-cns.cpp, ] + * - SPFlowdiv [\ref sp-flowdiv.cpp, \ref sp-flowdiv.h] + * - SPFlowpara [\ref sp-flowdiv.cpp, \ref sp-flowdiv.h] + * - SPFlowregion [\ref sp-flowregion.cpp, \ref sp-flowregion.h] + * - SPFlowregionExclude [\ref sp-flowregion.cpp, \ref sp-flowregion.h] + * - SPFlowtext [\ref sp-flowtext.cpp, \ref sp-flowtext.h] + * - SPFlowtspan [\ref sp-flowdiv.cpp, \ref sp-flowdiv.h] + * - SPGroup [\ref sp-item-group.cpp, \ref sp-item-group.h] + * - SPAnchor [\ref sp-anchor.cpp, \ref sp-anchor.h] + * - SPMarker [\ref sp-marker.cpp, \ref sp-marker.h] + * - SPRoot [\ref sp-root.cpp, \ref sp-root.h] + * - SPSymbol [\ref sp-symbol.cpp, \ref sp-symbol.h] + * - SPImage [\ref sp-image.cpp, \ref sp-image.h] + * - SPShape [\ref sp-shape.cpp, \ref sp-shape.h, \ref marker-status.cpp] + * - SPGenericEllipse [\ref sp-ellipse.cpp, \ref sp-ellipse.h] + * - SPArc + * - SPCircle + * - SPEllipse + * - SPLine [\ref sp-line.cpp, \ref sp-line.h] + * - SPOffset [\ref sp-offset.cpp, \ref sp-offset.h] + * - SPPath [\ref sp-path.cpp, \ref sp-path.h, \ref path-chemistry.cpp, \ref nodepath.cpp, \ref nodepath.h, \ref splivarot.cpp] + * - SPPolygon [\ref sp-polygon.cpp, \ref sp-polygon.h] + * - SPStar [\ref sp-star.cpp, \ref sp-star.h] + * - SPPolyLine [\ref sp-polyline.cpp, \ref sp-polyline.h] + * - SPRect [\ref sp-rect.cpp, \ref sp-rect.h] + * - SPSpiral [\ref sp-spiral.cpp, \ref sp-spiral.h] + * - SPText [\ref sp-text.cpp, \ref sp-text.h, \ref text-chemistry.cpp, \ref text-editing.cpp] + * - SPTextPath [\ref sp-tspan.cpp, \ref sp-tspan.h] + * - SPTSpan [\ref sp-tspan.cpp, \ref sp-tspan.h] + * - SPUse [\ref sp-use.cpp, \ref sp-use.h] + * - SPMetadata [\ref sp-metadata.cpp, \ref sp-metadata.h] + * - SPObjectGroup [\ref sp-object-group.cpp, \ref sp-object-group.h] + * - SPClipPath [\ref sp-clippath.cpp, \ref sp-clippath.h] + * - SPMask [\ref sp-mask.cpp, \ref sp-mask.h] + * - SPNamedView [\ref sp-namedview.cpp, \ref sp-namedview.h] + * - SPPaintServer [\ref sp-paint-server.cpp, \ref sp-paint-server.h] + * - SPGradient [\ref sp-gradient.cpp, \ref sp-gradient.h, \ref gradient-chemistry.cpp, \ref sp-gradient-reference.h, \ref sp-gradient-spread.h, \ref sp-gradient-units.h, \ref sp-gradient-vector.h] + * - SPLinearGradient + * - SPRadialGradient + * - SPPattern [\ref sp-pattern.cpp, \ref sp-pattern.h] + * - SPSkeleton [\ref sp-skeleton.cpp, \ref sp-skeleton.h] + * - SPStop [\ref sp-stop.h] + * - SPString [\ref sp-string.cpp, \ref sp-string.h] + * - SPStyleElem [\ref sp-style-elem.cpp, \ref sp-style-elem.h] + * + */ +/** \page Tools Tools Related Classes and Files + * + * SelCue [\ref selcue.cpp, \ref selcue.h, \ref rubberband.cpp] + * Inkscape::Selection [\ref selection.cpp, \ref selection.h, \ref selection-chemistry.cpp] + * SPSelTrans [\ref seltrans.cpp, \ref seltrans.h] + * + * \section Event Context Class Hierarchy + * + *- SPEventContext[\ref event-context.cpp, \ref event-context.h] + * - SPArcContext [\ref arc-context.cpp, \ref arc-context.h] + * - SPDrawContext [\ref draw-context.cpp, \ref draw-context.h] + * - SPPenContext [\ref pen-context.cpp, \ref pen-context.h] + * - SPPencilContext [\ref pencil-context.cpp, \ref pencil-context.h] + * - SPConnectorContext [\ref connector-context.cpp, \ref connector-context.h, \ref sp-conn-end.cpp, \ref sp-conn-end-pair.cpp] + * - SPGradientContext [\ref gradient-context.cpp, \ref gradient-context.h, \ref gradient-drag.cpp, \ref gradient-toolbar.cpp] + * - SPRectContext [\ref rect-context.cpp, \ref rect-context.h] + * - SPSelectContext [\ref select-context.cpp, \ref select-context.h] + * - SPSpiralContext [\ref spiral-context.cpp, \ref spiral-context.h] + * - SPStarContext [\ref star-context.cpp, \ref star-context.h] + * + * SPNodeContext [\ref node-context.cpp, \ref node-context.h] + * + * SPZoomContext [\ref zoom-context.cpp, \ref zoom-context.h] + * + * SPDynaDrawContext [\ref dyna-draw-context.cpp, \ref dyna-draw-context.h] + * + * SPDropperContext [\ref dropper-context.cpp, \ref dropper-context.h] + */ +/** \page UI User Interface Classes and Files + * + * - Inkscape::UI::View::View [\ref ui/view/view.cpp, \ref ui/view/view.h] + * - Inkscape::UI::View::Edit [\ref ui/view/edit.cpp, \ref ui/view/edit.h] + * - SPDesktop [\ref desktop.cpp, \ref desktop-affine.cpp, \ref desktop-events.cpp, \ref desktop-handles.cpp, \ref desktop-style.cpp, \ref desktop.h, \ref desktop-affine.h, \ref desktop-events.h, \ref desktop-handles.h, \ref desktop-style.h] + * - SPSVGView [\ref svg-view.cpp, \ref svg-view.h] + * + * SPDesktopWidget [\ref desktop-widget.h] SPSVGSPViewWidget [\ref svg-view.cpp] + * SPDocument [\ref document.cpp, \ref document.h] + * + * SPDrawAnchor [\ref draw-anchor.cpp, \ref draw-anchor.h] + * SPKnot [\ref knot.cpp, \ref knot.h, \ref knot-enums.h] + * SPKnotHolder [\ref knotholder.cpp, \ref knotholder.h, \ref knot-holder-entity.h] + * + * [\ref layer-fns.cpp, \ref selection-describer.h] + * Inkscape::MessageContext [\ref message-context.h] + * Inkscape::MessageStack [\ref message-stack.h, \ref message.h] + * + * Snapper, GridSnapper, GuideSnapper [\ref snap.cpp, \ref snap.h] + * + * SPGuide [\ref sp-guide.cpp, \ref sp-guide.h, \ref satisfied-guide-cns.cpp, \ref sp-guide-attachment.h, \ref sp-guide-constraint.h] + * + * [\ref help.cpp] [\ref inkscape.cpp] [\ref inkscape-stock.cpp] + * [\ref interface.cpp, \ref memeq.h] [\ref main.cpp, \ref winmain.cpp] + * [\ref menus-skeleton.h, \ref preferences-skeleton.h] + * [\ref object-ui.cpp] [\ref select-toolbar.cpp] [\ref shortcuts.cpp] + * [\ref sp-cursor.cpp] [\ref text-edit.cpp] [\ref toolbox.cpp, \ref ui/widget/toolbox.cpp] + * Inkscape::Verb [\ref verbs.h] + * + */ +/** \page XmlTree CSS/XML Tree Classes and Files + * + * SPStyle [\ref style.cpp, \ref style.h] + * Media [\ref media.cpp, \ref media.h] + * [\ref attributes.cpp, \ref attributes.h] + * + * - Inkscape::URIReference [\ref uri-references.cpp, \ref uri-references.h] + * - SPClipPathReference [\ref sp-clippath.h] + * - SPGradientReference [\ref sp-gradient-reference.h] + * - SPMarkerReference [\ref sp-marker.h] + * - SPMaskReference [\ref sp-mask.h] + * - SPUseReference [\ref sp-use-reference.h] + * - SPUsePath + */ +/** \page Rendering Rendering Related Classes and Files + * + * SPColor [\ref color.cpp, \ref color.h, \ref color-rgba.h] + * [\ref geom.cpp] [\ref isnan.h] [\ref mod360.cpp] + */ +/** \page OtherServices Classes and Files From Other Services + * [\ref inkview.cpp, \ref slideshow.cpp] [\ref sp-animation.cpp] + * + * Inkscape::GC + * + * [\ref sp-metrics.cpp, \ref sp-metrics.h] + * + * [\ref prefs-utils.cpp] [\ref print.cpp] + * + * - Inkscape::GZipBuffer [\ref streams-gzip.h] + * - Inkscape::JarBuffer [\ref streams-jar.h] + * - Inkscape::ZlibBuffer [\ref streams-zlib.h] + * - Inkscape::URIHandle [\ref streams-handles.h] + * - Inkscape::FileHandle + * [\ref dir-util.cpp] [\ref file.cpp] + * Inkscape::URI [\ref uri.h, \ref extract-uri.cpp, \ref uri-references.cpp] + * Inkscape::BadURIException [\ref bad-uri-exception.h] + * + * Inkscape::Whiteboard::UndoStackObserver [\ref undo-stack-observer.cpp, \ref composite-undo-stack-observer.cpp] + * [\ref document-undo.cpp] + * + * {\ref dialogs/} [\ref approx-equal.h] [\ref decimal-round.h] [\ref enums.h] [\ref unit-constants.h] + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif +#include "path-prefix.h" + +#include + +#ifdef HAVE_IEEEFP_H +#include +#endif +#include +#include + +#include +#ifndef POPT_TABLEEND +#define POPT_TABLEEND { NULL, '\0', 0, 0, 0, NULL, NULL } +#endif /* Not def: POPT_TABLEEND */ + +#include +#include +#include +#include +#include +#include + +#include + +#include "gc-core.h" + +#include "macros.h" +#include "file.h" +#include "document.h" +#include "sp-object.h" +#include "interface.h" +#include "print.h" +#include "slideshow.h" +#include "color.h" +#include "sp-item.h" +#include "sp-root.h" +#include "unit-constants.h" + +#include "svg/svg.h" +#include "svg/stringstream.h" + +#include "inkscape-private.h" +#include "inkscape-stock.h" +#include "inkscape_version.h" + +#include "sp-namedview.h" +#include "sp-guide.h" +#include "sp-object-repr.h" +#include "xml/repr.h" + +#include "io/sys.h" + +#include "debug/logger.h" + +#include +#include +#include +#include + +#ifdef WIN32 +//#define REPLACEARGS_ANSI +//#define REPLACEARGS_DEBUG + +#include "registrytool.h" + +#include "extension/internal/win32.h" +using Inkscape::Extension::Internal::PrintWin32; + +#endif // WIN32 + +#include "extension/init.h" + +#include +#include + +#ifndef HAVE_BIND_TEXTDOMAIN_CODESET +#define bind_textdomain_codeset(p,c) +#endif + +#include "application/application.h" + +enum { + SP_ARG_NONE, + SP_ARG_NOGUI, + SP_ARG_GUI, + SP_ARG_FILE, + SP_ARG_PRINT, + SP_ARG_EXPORT_PNG, + SP_ARG_EXPORT_DPI, + SP_ARG_EXPORT_AREA, + SP_ARG_EXPORT_AREA_DRAWING, + SP_ARG_EXPORT_AREA_SNAP, + SP_ARG_EXPORT_WIDTH, + SP_ARG_EXPORT_HEIGHT, + SP_ARG_EXPORT_ID, + SP_ARG_EXPORT_ID_ONLY, + SP_ARG_EXPORT_USE_HINTS, + SP_ARG_EXPORT_BACKGROUND, + SP_ARG_EXPORT_BACKGROUND_OPACITY, + SP_ARG_EXPORT_SVG, + SP_ARG_EXPORT_PS, + SP_ARG_EXPORT_EPS, + SP_ARG_EXPORT_TEXT_TO_PATH, + SP_ARG_EXPORT_BBOX_PAGE, + SP_ARG_EXTENSIONDIR, + SP_ARG_SLIDESHOW, + SP_ARG_QUERY_X, + SP_ARG_QUERY_Y, + SP_ARG_QUERY_WIDTH, + SP_ARG_QUERY_HEIGHT, + SP_ARG_QUERY_ID, + SP_ARG_VERSION, + SP_ARG_NEW_GUI, + SP_ARG_VACUUM_DEFS, + SP_ARG_LAST +}; + +int sp_main_gui(int argc, char const **argv); +int sp_main_console(int argc, char const **argv); +static void sp_do_export_png(SPDocument *doc); +static void do_export_ps(SPDocument* doc, gchar const* uri, char const *mime); +static void do_query_dimension (SPDocument *doc, bool extent, NR::Dim2 const axis, const gchar *id); + + +static gchar *sp_global_printer = NULL; +static gboolean sp_global_slideshow = FALSE; +static gchar *sp_export_png = NULL; +static gchar *sp_export_dpi = NULL; +static gchar *sp_export_area = NULL; +static gboolean sp_export_area_drawing = FALSE; +static gchar *sp_export_width = NULL; +static gchar *sp_export_height = NULL; +static gchar *sp_export_id = NULL; +static gchar *sp_export_background = NULL; +static gchar *sp_export_background_opacity = NULL; +static gboolean sp_export_area_snap = FALSE; +static gboolean sp_export_use_hints = FALSE; +static gboolean sp_export_id_only = FALSE; +static gchar *sp_export_svg = NULL; +static gchar *sp_export_ps = NULL; +static gchar *sp_export_eps = NULL; +static gboolean sp_export_text_to_path = FALSE; +static gboolean sp_export_bbox_page = FALSE; +static gboolean sp_query_x = FALSE; +static gboolean sp_query_y = FALSE; +static gboolean sp_query_width = FALSE; +static gboolean sp_query_height = FALSE; +static gchar *sp_query_id = NULL; +static int sp_new_gui = FALSE; +static gboolean sp_vacuum_defs = FALSE; + +static gchar *sp_export_png_utf8 = NULL; +static gchar *sp_export_svg_utf8 = NULL; +static gchar *sp_global_printer_utf8 = NULL; + +#ifdef WIN32 +static bool replaceArgs( int& argc, char**& argv ); +#endif +static GSList *sp_process_args(poptContext ctx); +struct poptOption options[] = { + {"version", 'V', + POPT_ARG_NONE, NULL, SP_ARG_VERSION, + N_("Print the Inkscape version number"), + NULL}, + + {"without-gui", 'z', + POPT_ARG_NONE, NULL, SP_ARG_NOGUI, + N_("Do not use X server (only process files from console)"), + NULL}, + + {"with-gui", 'g', + POPT_ARG_NONE, NULL, SP_ARG_GUI, + N_("Try to use X server (even if $DISPLAY is not set)"), + NULL}, + + {"file", 'f', + POPT_ARG_STRING, NULL, SP_ARG_FILE, + N_("Open specified document(s) (option string may be excluded)"), + N_("FILENAME")}, + + {"print", 'p', + POPT_ARG_STRING, &sp_global_printer, SP_ARG_PRINT, + N_("Print document(s) to specified output file (use '| program' for pipe)"), + N_("FILENAME")}, + + {"export-png", 'e', + POPT_ARG_STRING, &sp_export_png, SP_ARG_EXPORT_PNG, + N_("Export document to a PNG file"), + N_("FILENAME")}, + + {"export-dpi", 'd', + POPT_ARG_STRING, &sp_export_dpi, SP_ARG_EXPORT_DPI, + N_("The resolution used for exporting SVG into bitmap (default 90)"), + N_("DPI")}, + + {"export-area", 'a', + POPT_ARG_STRING, &sp_export_area, SP_ARG_EXPORT_AREA, + N_("Exported area in SVG user units (default is the canvas; 0,0 is lower-left corner)"), + N_("x0:y0:x1:y1")}, + + {"export-area-drawing", 'D', + POPT_ARG_NONE, &sp_export_area_drawing, SP_ARG_EXPORT_AREA_DRAWING, + N_("Exported area is the entire drawing (not canvas)"), + NULL}, + + {"export-area-snap", 0, + POPT_ARG_NONE, &sp_export_area_snap, SP_ARG_EXPORT_AREA_SNAP, + N_("Snap the bitmap export area outwards to the nearest integer values (in SVG user units)"), + NULL}, + + {"export-width", 'w', + POPT_ARG_STRING, &sp_export_width, SP_ARG_EXPORT_WIDTH, + N_("The width of exported bitmap in pixels (overrides export-dpi)"), + N_("WIDTH")}, + + {"export-height", 'h', + POPT_ARG_STRING, &sp_export_height, SP_ARG_EXPORT_HEIGHT, + N_("The height of exported bitmap in pixels (overrides export-dpi)"), + N_("HEIGHT")}, + + {"export-id", 'i', + POPT_ARG_STRING, &sp_export_id, SP_ARG_EXPORT_ID, + N_("The ID of the object to export (overrides export-area)"), + N_("ID")}, + + {"export-id-only", 'j', + POPT_ARG_NONE, &sp_export_id_only, SP_ARG_EXPORT_ID_ONLY, + // TRANSLATORS: this means: "Only export the object whose id is given in --export-id". + // See "man inkscape" for details. + N_("Export just the object with export-id, hide all others (only with export-id)"), + NULL}, + + {"export-use-hints", 't', + POPT_ARG_NONE, &sp_export_use_hints, SP_ARG_EXPORT_USE_HINTS, + N_("Use stored filename and DPI hints when exporting (only with export-id)"), + NULL}, + + {"export-background", 'b', + POPT_ARG_STRING, &sp_export_background, SP_ARG_EXPORT_BACKGROUND, + N_("Background color of exported bitmap (any SVG-supported color string)"), + N_("COLOR")}, + + {"export-background-opacity", 'y', + POPT_ARG_STRING, &sp_export_background_opacity, SP_ARG_EXPORT_BACKGROUND_OPACITY, + N_("Background opacity of exported bitmap (either 0.0 to 1.0, or 1 to 255)"), + N_("VALUE")}, + + {"export-plain-svg", 'l', + POPT_ARG_STRING, &sp_export_svg, SP_ARG_EXPORT_SVG, + N_("Export document to plain SVG file (no sodipodi or inkscape namespaces)"), + N_("FILENAME")}, + + {"export-ps", 'P', + POPT_ARG_STRING, &sp_export_ps, SP_ARG_EXPORT_PS, + N_("Export document to a PS file"), + N_("FILENAME")}, + + {"export-eps", 'E', + POPT_ARG_STRING, &sp_export_eps, SP_ARG_EXPORT_EPS, + N_("Export document to an EPS file"), + N_("FILENAME")}, + + {"export-text-to-path", 'T', + POPT_ARG_NONE, &sp_export_text_to_path, SP_ARG_EXPORT_TEXT_TO_PATH, + N_("Convert text object to paths on export (EPS)"), + NULL}, + + {"export-bbox-page", 'B', + POPT_ARG_NONE, &sp_export_bbox_page, SP_ARG_EXPORT_BBOX_PAGE, + N_("Export files with the bounding box set to the page size (EPS)"), + NULL}, + + {"query-x", 'X', + POPT_ARG_NONE, &sp_query_x, SP_ARG_QUERY_X, + // TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" + N_("Query the X coordinate of the drawing or, if specified, of the object with --query-id"), + NULL}, + + {"query-y", 'Y', + POPT_ARG_NONE, &sp_query_y, SP_ARG_QUERY_Y, + // TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" + N_("Query the Y coordinate of the drawing or, if specified, of the object with --query-id"), + NULL}, + + {"query-width", 'W', + POPT_ARG_NONE, &sp_query_width, SP_ARG_QUERY_WIDTH, + // TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" + N_("Query the width of the drawing or, if specified, of the object with --query-id"), + NULL}, + + {"query-height", 'H', + POPT_ARG_NONE, &sp_query_height, SP_ARG_QUERY_HEIGHT, + // TRANSLATORS: "--query-id" is an Inkscape command line option; see "inkscape --help" + N_("Query the height of the drawing or, if specified, of the object with --query-id"), + NULL}, + + {"query-id", 'I', + POPT_ARG_STRING, &sp_query_id, SP_ARG_QUERY_ID, + N_("The ID of the object whose dimensions are queried"), + N_("ID")}, + + {"extension-directory", 'x', + POPT_ARG_NONE, NULL, SP_ARG_EXTENSIONDIR, + // TRANSLATORS: this option makes Inkscape print the name (path) of the extension directory + N_("Print out the extension directory and exit"), + NULL}, + + {"slideshow", 's', + POPT_ARG_NONE, &sp_global_slideshow, SP_ARG_SLIDESHOW, + N_("Show given files one-by-one, switch to next on any key/mouse event"), + NULL}, + + {"new-gui", 'G', + POPT_ARG_NONE, &sp_new_gui, SP_ARG_NEW_GUI, + N_("Use the new Gtkmm GUI interface"), + NULL}, + + {"vacuum-defs", 0, + POPT_ARG_NONE, &sp_vacuum_defs, SP_ARG_VACUUM_DEFS, + N_("Remove unused definitions from the defs section(s) of the document"), + NULL}, + + POPT_AUTOHELP POPT_TABLEEND +}; + +static bool needToRecodeParams = true; +gchar* blankParam = ""; + +int +main(int argc, char **argv) +{ +#ifdef HAVE_FPSETMASK + /* This is inherited from Sodipodi code, where it was in #ifdef __FreeBSD__. It's probably + safe to remove: the default mask is already 0 in C99, and in current FreeBSD according to + the fenv man page on www.freebsd.org, and in glibc according to (libc)FP Exceptions. */ + fpsetmask(fpgetmask() & ~(FP_X_DZ | FP_X_INV)); +#endif + +#ifdef ENABLE_NLS +#ifdef WIN32 + RegistryTool rt; + rt.setPathInfo(); + gchar *pathBuf = g_strconcat(g_path_get_dirname(argv[0]), "\\", PACKAGE_LOCALE_DIR, NULL); + bindtextdomain(GETTEXT_PACKAGE, pathBuf); + g_free(pathBuf); +#else +#ifdef ENABLE_BINRELOC + bindtextdomain(GETTEXT_PACKAGE, BR_LOCALEDIR("")); +#else + bindtextdomain(GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR); +#endif +#endif +#endif + + bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8"); + +#ifdef ENABLE_NLS + textdomain(GETTEXT_PACKAGE); +#endif + + LIBXML_TEST_VERSION + + Inkscape::GC::init(); + + Inkscape::Debug::Logger::init(); + + gboolean use_gui; +#ifndef WIN32 + use_gui = (getenv("DISPLAY") != NULL); +#else + /* + Set the current directory to the directory of the + executable. This seems redundant, but is needed for + when inkscape.exe is executed from another directory. + We use relative paths on win32. + HKCR\svgfile\shell\open\command is a good example + */ + /// \todo FIXME BROKEN - non-UTF-8 sneaks in here. + char *homedir = g_path_get_dirname(argv[0]); + SetCurrentDirectory(homedir); + g_free(homedir); + + use_gui = TRUE; +#endif + /* Test whether with/without GUI is forced */ + for (int i = 1; i < argc; i++) { + if (!strcmp(argv[i], "-z") + || !strcmp(argv[i], "--without-gui") + || !strcmp(argv[i], "-p") + || !strncmp(argv[i], "--print", 7) + || !strcmp(argv[i], "-e") + || !strncmp(argv[i], "--export-png", 12) + || !strcmp(argv[i], "-l") + || !strncmp(argv[i], "--export-plain-svg", 12) + || !strcmp(argv[i], "-i") + || !strncmp(argv[i], "--export-area-drawing", 21) + || !strcmp(argv[i], "-D") + || !strncmp(argv[i], "--export-id", 12) + || !strcmp(argv[i], "-P") + || !strncmp(argv[i], "--export-ps", 11) + || !strcmp(argv[i], "-E") + || !strncmp(argv[i], "--export-eps", 12) + || !strcmp(argv[i], "-W") + || !strncmp(argv[i], "--query-width", 13) + || !strcmp(argv[i], "-H") + || !strncmp(argv[i], "--query-height", 14) + || !strcmp(argv[i], "-X") + || !strncmp(argv[i], "--query-x", 13) + || !strcmp(argv[i], "-Y") + || !strncmp(argv[i], "--query-y", 14) + || !strcmp(argv[i], "--vacuum-defs") + ) + { + /* main_console handles any exports -- not the gui */ + use_gui = FALSE; + break; + } else if (!strcmp(argv[i], "-g") || !strcmp(argv[i], "--with-gui")) { + use_gui = TRUE; + break; + } else if (!strcmp(argv[i], "-G") || !strcmp(argv[i], "--new-gui")) { + sp_new_gui = TRUE; + break; + } + } + +#ifdef WIN32 +#ifndef REPLACEARGS_ANSI + if ( PrintWin32::is_os_wide() ) +#endif // REPLACEARGS_ANSI + { + // If the call fails, we'll need to convert charsets + needToRecodeParams = !replaceArgs( argc, argv ); + } +#endif // WIN32 + + /// \todo Should this be a static object (see inkscape.cpp)? + Inkscape::NSApplication::Application app(argc, argv, use_gui, sp_new_gui); + + return app.run(); +} + +void fixupSingleFilename( gchar **orig, gchar **spare ) +{ + if ( orig && *orig && **orig ) { + GError *error = NULL; + gchar *newFileName = Inkscape::IO::locale_to_utf8_fallback(*orig, -1, NULL, NULL, &error); + if ( newFileName ) + { + *orig = newFileName; + if ( spare ) { + *spare = newFileName; + } +// g_message("Set a replacement fixup"); + } + } +} + +GSList *fixupFilenameEncoding( GSList* fl ) +{ + GSList *newFl = NULL; + while ( fl ) { + gchar *fn = static_cast(fl->data); + fl = g_slist_remove( fl, fl->data ); + gchar *newFileName = Inkscape::IO::locale_to_utf8_fallback(fn, -1, NULL, NULL, NULL); + if ( newFileName ) { + + if ( 0 ) + { + gchar *safeFn = Inkscape::IO::sanitizeString(fn); + gchar *safeNewFn = Inkscape::IO::sanitizeString(newFileName); + GtkWidget *w = gtk_message_dialog_new( NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_WARNING, GTK_BUTTONS_OK, + "Note: Converted '%s' to '%s'", safeFn, safeNewFn ); + gtk_dialog_run (GTK_DIALOG (w)); + gtk_widget_destroy (w); + g_free(safeNewFn); + g_free(safeFn); + } + + g_free( fn ); + fn = newFileName; + newFileName = 0; + } + else + if ( 0 ) + { + gchar *safeFn = Inkscape::IO::sanitizeString(fn); + GtkWidget *w = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_WARNING, GTK_BUTTONS_OK, "Error: Unable to convert '%s'", safeFn ); + gtk_dialog_run (GTK_DIALOG (w)); + gtk_widget_destroy (w); + g_free(safeFn); + } + newFl = g_slist_append( newFl, fn ); + } + return newFl; +} + +int sp_common_main( int argc, char const **argv, GSList **flDest ) +{ + /// \todo fixme: Move these to some centralized location (Lauris) + sp_object_type_register("sodipodi:namedview", SP_TYPE_NAMEDVIEW); + sp_object_type_register("sodipodi:guide", SP_TYPE_GUIDE); + + + // temporarily switch gettext encoding to locale, so that help messages can be output properly + gchar const *charset; + g_get_charset(&charset); + + bind_textdomain_codeset(GETTEXT_PACKAGE, charset); + + poptContext ctx = poptGetContext(NULL, argc, argv, options, 0); + poptSetOtherOptionHelp(ctx, _("[OPTIONS...] [FILE...]\n\nAvailable options:")); + g_return_val_if_fail(ctx != NULL, 1); + + /* Collect own arguments */ + GSList *fl = sp_process_args(ctx); + poptFreeContext(ctx); + + // now switch gettext back to UTF-8 (for GUI) + bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8"); + + // Now let's see if the file list still holds up + if ( needToRecodeParams ) + { + fl = fixupFilenameEncoding( fl ); + } + + // Check the globals for filename-fixup + if ( needToRecodeParams ) + { + fixupSingleFilename( &sp_export_png, &sp_export_png_utf8 ); + fixupSingleFilename( &sp_export_svg, &sp_export_svg_utf8 ); + fixupSingleFilename( &sp_global_printer, &sp_global_printer_utf8 ); + } + else + { + if ( sp_export_png ) + sp_export_png_utf8 = g_strdup( sp_export_png ); + if ( sp_export_svg ) + sp_export_svg_utf8 = g_strdup( sp_export_svg ); + if ( sp_global_printer ) + sp_global_printer_utf8 = g_strdup( sp_global_printer ); + } + + // Return the list if wanted, else free it up. + if ( flDest ) { + *flDest = fl; + fl = 0; + } else { + while ( fl ) { + g_free( fl->data ); + fl = g_slist_remove( fl, fl->data ); + } + } + return 0; +} + +int +sp_main_gui(int argc, char const **argv) +{ + Gtk::Main main_instance (&argc, const_cast(&argv)); + + GSList *fl = NULL; + int retVal = sp_common_main( argc, argv, &fl ); + g_return_val_if_fail(retVal == 0, 1); + + inkscape_gtk_stock_init(); + + /* Set default icon */ + gchar *filename = (gchar *) g_build_filename (INKSCAPE_APPICONDIR, "inkscape.png", NULL); + if (Inkscape::IO::file_test(filename, (GFileTest)(G_FILE_TEST_IS_REGULAR | G_FILE_TEST_IS_SYMLINK))) { + gtk_window_set_default_icon_from_file(filename, NULL); + } + g_free (filename); + filename = 0; + + if (!sp_global_slideshow) { + gboolean create_new = TRUE; + + /// \todo FIXME BROKEN - non-UTF-8 sneaks in here. + inkscape_application_init(argv[0], true); + + while (fl) { + if (sp_file_open((gchar *)fl->data,NULL)) { + create_new=FALSE; + } + fl = g_slist_remove(fl, fl->data); + } + if (create_new) { + sp_file_new_default(); + } + } else { + if (fl) { + GtkWidget *ss; + /// \todo FIXME BROKEN - non-UTF-8 sneaks in here. + inkscape_application_init(argv[0], true); + ss = sp_slideshow_new(fl); + if (ss) gtk_widget_show(ss); + } else { + g_warning ("No slides to display"); + exit(0); + } + } + + main_instance.run(); + +#ifdef WIN32 + //We might not need anything here + //sp_win32_finish(); <-- this is a NOP func +#endif + + return 0; +} + +int +sp_main_console(int argc, char const **argv) +{ + /* We are started in text mode */ + + /* Do this g_type_init(), so that we can use Xft/Freetype2 (Pango) + * in a non-Gtk environment. Used in libnrtype's + * FontInstance.cpp and FontFactory.cpp. + * http://mail.gnome.org/archives/gtk-list/2003-December/msg00063.html + */ + g_type_init(); + char **argv2 = const_cast(argv); + gtk_init_check( &argc, &argv2 ); + //setlocale(LC_ALL, ""); + + GSList *fl = NULL; + int retVal = sp_common_main( argc, argv, &fl ); + g_return_val_if_fail(retVal == 0, 1); + + if (fl == NULL) { + g_print("Nothing to do!\n"); + exit(0); + } + + inkscape_application_init(argv[0], false); + + while (fl) { + SPDocument *doc; + + doc = Inkscape::Extension::open(NULL, (gchar *)fl->data); + if (doc == NULL) { + doc = Inkscape::Extension::open(Inkscape::Extension::db.get(SP_MODULE_KEY_INPUT_SVG), (gchar *)fl->data); + } + if (doc == NULL) { + g_warning("Specified document %s cannot be opened (is it valid SVG file?)", (gchar *) fl->data); + } else { + if (sp_vacuum_defs) { + vacuum_document(doc); + } + if (sp_vacuum_defs && !sp_export_svg) { + // save under the name given in the command line + sp_repr_save_file(doc->rdoc, (gchar *)fl->data, SP_SVG_NS_URI); + } + if (sp_global_printer) { + sp_print_document_to_file(doc, sp_global_printer); + } + if (sp_export_png || sp_export_id || sp_export_area_drawing) { + sp_do_export_png(doc); + } + if (sp_export_svg) { + Inkscape::XML::Document *rdoc; + Inkscape::XML::Node *repr; + rdoc = sp_repr_document_new("svg:svg"); + repr = rdoc->root(); + repr = sp_document_root(doc)->updateRepr(repr, SP_OBJECT_WRITE_BUILD); + sp_repr_save_file(repr->document(), sp_export_svg, SP_SVG_NS_URI); + } + if (sp_export_ps) { + do_export_ps(doc, sp_export_ps, "image/x-postscript"); + } + if (sp_export_eps) { + do_export_ps(doc, sp_export_eps, "image/x-e-postscript"); + } + if (sp_query_width || sp_query_height) { + do_query_dimension (doc, true, sp_query_width? NR::X : NR::Y, sp_query_id); + } else if (sp_query_x || sp_query_y) { + do_query_dimension (doc, false, sp_query_x? NR::X : NR::Y, sp_query_id); + } + } + fl = g_slist_remove(fl, fl->data); + } + + inkscape_unref(); + + return 0; +} + +static void +do_query_dimension (SPDocument *doc, bool extent, NR::Dim2 const axis, const gchar *id) +{ + SPObject *o = NULL; + + if (id) { + o = doc->getObjectById(id); + if (o) { + if (!SP_IS_ITEM (o)) { + g_warning("Object with id=\"%s\" is not a visible item. Cannot query dimensions.", id); + return; + } + } else { + g_warning("Object with id=\"%s\" is not found. Cannot query dimensions.", id); + return; + } + } else { + o = SP_DOCUMENT_ROOT(doc); + } + + if (o) { + sp_document_ensure_up_to_date (doc); + NR::Rect area = sp_item_bbox_desktop((SPItem *) o); + + Inkscape::SVGOStringStream os; + if (extent) { + os << area.extent(axis); + } else { + os << area.min()[axis]; + } + g_print ("%s\n", os.str().c_str()); + } +} + + +static void +sp_do_export_png(SPDocument *doc) +{ + const gchar *filename = NULL; + gdouble dpi = 0.0; + + if (sp_export_use_hints && (!sp_export_id && !sp_export_area_drawing)) { + g_warning ("--export-use-hints can only be used with --export-id or --export-area-drawing; ignored."); + } + + GSList *items = NULL; + + NRRect area; + if (sp_export_id || sp_export_area_drawing) { + + SPObject *o = NULL; + if (sp_export_id) { + o = doc->getObjectById(sp_export_id); + } else if (sp_export_area_drawing) { + o = SP_DOCUMENT_ROOT (doc); + } + + if (o) { + if (!SP_IS_ITEM (o)) { + g_warning("Object with id=\"%s\" is not a visible item. Nothing exported.", sp_export_id); + return; + } + if (sp_export_area) { + g_warning ("Object with id=\"%s\" is being exported; --export-area is ignored.", sp_export_id); + } + + items = g_slist_prepend (items, SP_ITEM(o)); + + if (sp_export_id_only) { + g_print("Exporting only object with id=\"%s\"; all other objects hidden\n", sp_export_id); + } + + if (sp_export_use_hints) { + + // retrieve export filename hint + const gchar *fn_hint = SP_OBJECT_REPR(o)->attribute("inkscape:export-filename"); + if (fn_hint) { + if (sp_export_png) { + g_warning ("Using export filename from the command line (--export-png). Filename hint %s is ignored.", fn_hint); + filename = sp_export_png; + } else { + filename = fn_hint; + } + } else { + g_warning ("Export filename hint not found for the object."); + filename = sp_export_png; + } + + // retrieve export dpi hints + const gchar *dpi_hint = SP_OBJECT_REPR(o)->attribute("inkscape:export-xdpi"); // only xdpi, ydpi is always the same now + if (dpi_hint) { + if (sp_export_dpi || sp_export_width || sp_export_height) { + g_warning ("Using bitmap dimensions from the command line (--export-dpi, --export-width, or --export-height). DPI hint %s is ignored.", dpi_hint); + } else { + dpi = atof(dpi_hint); + } + } else { + g_warning ("Export DPI hint not found for the object."); + } + + } + + // write object bbox to area + sp_document_ensure_up_to_date (doc); + sp_item_invoke_bbox((SPItem *) o, &area, sp_item_i2r_affine((SPItem *) o), TRUE); + } else { + g_warning("Object with id=\"%s\" was not found in the document. Nothing exported.", sp_export_id); + return; + } + } else if (sp_export_area) { + /* Try to parse area (given in SVG pixels) */ + if (!sscanf(sp_export_area, "%lg:%lg:%lg:%lg", &area.x0, &area.y0, &area.x1, &area.y1) == 4) { + g_warning("Cannot parse export area '%s'; use 'x0:y0:x1:y1'. Nothing exported.", sp_export_area); + return; + } + if ((area.x0 >= area.x1) || (area.y0 >= area.y1)) { + g_warning("Export area '%s' has negative width or height. Nothing exported.", sp_export_area); + return; + } + } else { + /* Export the whole canvas */ + sp_document_ensure_up_to_date (doc); + area.x0 = SP_ROOT(doc->root)->x.computed; + area.y0 = SP_ROOT(doc->root)->y.computed; + area.x1 = area.x0 + sp_document_width (doc); + area.y1 = area.y0 + sp_document_height (doc); + } + + // set filename and dpi from options, if not yet set from the hints + if (!filename) { + if (!sp_export_png) { + g_warning ("No export filename given and no filename hint. Nothing exported."); + return; + } + filename = sp_export_png; + } + + if (sp_export_dpi && dpi == 0.0) { + dpi = atof(sp_export_dpi); + if ((dpi < 0.1) || (dpi > 10000.0)) { + g_warning("DPI value %s out of range [0.1 - 10000.0]. Nothing exported.", sp_export_dpi); + return; + } + g_print("DPI: %g\n", dpi); + } + + if (sp_export_area_snap) { + area.x0 = std::floor (area.x0); + area.y0 = std::floor (area.y0); + area.x1 = std::ceil (area.x1); + area.y1 = std::ceil (area.y1); + } + + // default dpi + if (dpi == 0.0) + dpi = PX_PER_IN; + + gint width = 0; + gint height = 0; + + if (sp_export_width) { + width = atoi(sp_export_width); + if ((width < 1) || (width > 65536)) { + g_warning("Export width %d out of range (1 - 65536). Nothing exported.", width); + return; + } + dpi = (gdouble) width * PX_PER_IN / (area.x1 - area.x0); + } + + if (sp_export_height) { + height = atoi(sp_export_height); + if ((height < 1) || (height > 65536)) { + g_warning("Export height %d out of range (1 - 65536). Nothing exported.", width); + return; + } + dpi = (gdouble) height * PX_PER_IN / (area.y1 - area.y0); + } + + if (!sp_export_width) { + width = (gint) ((area.x1 - area.x0) * dpi / PX_PER_IN + 0.5); + } + + if (!sp_export_height) { + height = (gint) ((area.y1 - area.y0) * dpi / PX_PER_IN + 0.5); + } + + guint32 bgcolor = 0x00000000; + if (sp_export_background) { + // override the page color + bgcolor = sp_svg_read_color(sp_export_background, 0xffffff00); + bgcolor |= 0xff; // default is no opacity + } else { + // read from namedview + Inkscape::XML::Node *nv = sp_repr_lookup_name (doc->rroot, "sodipodi:namedview"); + if (nv && nv->attribute("pagecolor")) + bgcolor = sp_svg_read_color(nv->attribute("pagecolor"), 0xffffff00); + if (nv && nv->attribute("inkscape:pageopacity")) + bgcolor |= SP_COLOR_F_TO_U(sp_repr_get_double_attribute (nv, "inkscape:pageopacity", 1.0)); + } + + if (sp_export_background_opacity) { + // override opacity + gfloat value; + if (sp_svg_number_read_f (sp_export_background_opacity, &value)) { + if (value > 1.0) { + value = CLAMP (value, 1.0f, 255.0f); + bgcolor &= (guint32) 0xffffff00; + bgcolor |= (guint32) floor(value); + } else { + value = CLAMP (value, 0.0f, 1.0f); + bgcolor &= (guint32) 0xffffff00; + bgcolor |= SP_COLOR_F_TO_U(value); + } + } + } + + g_print("Background RRGGBBAA: %08x\n", bgcolor); + + g_print("Area %g:%g:%g:%g exported to %d x %d pixels (%g dpi)\n", area.x0, area.y0, area.x1, area.y1, width, height, dpi); + + g_print("Bitmap saved as: %s\n", filename); + + if ((width >= 1) && (height >= 1) && (width < 65536) && (height < 65536)) { + sp_export_png_file(doc, filename, area.x0, area.y0, area.x1, area.y1, width, height, bgcolor, NULL, NULL, true, sp_export_id_only ? items : NULL); + } else { + g_warning("Calculated bitmap dimensions %d %d are out of range (1 - 65535). Nothing exported.", width, height); + } + + g_slist_free (items); +} + + +/** + * Perform an export of either PS or EPS. + * + * \param doc Document to export. + * \param uri URI to export to. + * \param mime MIME type to export as. + */ + +static void do_export_ps(SPDocument* doc, gchar const* uri, char const* mime) +{ + /** \todo + * FIXME: I've no idea if this is the `proper' way to do this. + * If anyone feels qualified to say that it is, perhaps they + * could remove this comment. + */ + + Inkscape::Extension::DB::OutputList o; + Inkscape::Extension::db.get_output_list(o); + Inkscape::Extension::DB::OutputList::const_iterator i = o.begin(); + while (i != o.end() && strcmp( (*i)->get_mimetype(), mime ) != 0) { + i++; + } + + if (i == o.end()) + { + g_warning ("Could not find an extension to export this file."); + return; + } + + bool old_text_to_path = false; + bool old_bbox_page = false; + + try { + old_text_to_path = (*i)->get_param_bool("textToPath"); + (*i)->set_param_bool("textToPath", sp_export_text_to_path); + } + catch (...) { + g_warning ("Could not set export-text-to-path option for this export."); + } + + try { + old_bbox_page = (*i)->get_param_bool("pageBoundingBox"); + (*i)->set_param_bool("pageBoundingBox", sp_export_bbox_page); + } + catch (...) { + g_warning ("Could not set export-bbox-page option for this export."); + } + + (*i)->save(doc, uri); + + try { + (*i)->set_param_bool("textToPath", old_text_to_path); + (*i)->set_param_bool("pageBoundingBox", old_bbox_page); + } + catch (...) { + + } +} + +#ifdef WIN32 +bool replaceArgs( int& argc, char**& argv ) +{ + bool worked = false; + +#ifdef REPLACEARGS_DEBUG + MessageBoxA( NULL, "GetCommandLineW() getting called", "GetCommandLineW", MB_OK | MB_ICONINFORMATION ); +#endif // REPLACEARGS_DEBUG + + wchar_t* line = GetCommandLineW(); + if ( line ) + { +#ifdef REPLACEARGS_DEBUG + { + gchar* utf8Line = g_utf16_to_utf8( (gunichar2*)line, -1, NULL, NULL, NULL ); + if ( utf8Line ) + { + gchar *safe = Inkscape::IO::sanitizeString(utf8Line); + { + char tmp[strlen(safe) + 32]; + snprintf( tmp, sizeof(tmp), "GetCommandLineW() = '%s'", safe ); + MessageBoxA( NULL, tmp, "GetCommandLineW", MB_OK | MB_ICONINFORMATION ); + } + } + } +#endif // REPLACEARGS_DEBUG + + int numArgs = 0; + wchar_t** parsed = CommandLineToArgvW( line, &numArgs ); + +#ifdef REPLACEARGS_ANSI +// test code for trying things on Win95/98/ME + if ( !parsed ) + { +#ifdef REPLACEARGS_DEBUG + MessageBoxA( NULL, "Unable to process command-line. Faking it", "CommandLineToArgvW", MB_OK | MB_ICONINFORMATION ); +#endif // REPLACEARGS_DEBUG + int lineLen = wcslen(line) + 1; + wchar_t* lineDup = new wchar_t[lineLen]; + wcsncpy( lineDup, line, lineLen ); + + int pos = 0; + bool inQuotes = false; + bool inWhitespace = true; + std::vector places; + while ( lineDup[pos] ) + { + if ( inQuotes ) + { + if ( lineDup[pos] == L'"' ) + { + inQuotes = false; + } + } + else if ( lineDup[pos] == L'"' ) + { + inQuotes = true; + inWhitespace = false; + places.push_back(pos); + } + else if ( lineDup[pos] == L' ' || lineDup[pos] == L'\t' ) + { + if ( !inWhitespace ) + { + inWhitespace = true; + lineDup[pos] = 0; + } + } + else if ( inWhitespace && (lineDup[pos] != L' ' && lineDup[pos] != L'\t') ) + { + inWhitespace = false; + places.push_back(pos); + } + else + { + // consume + } + pos++; + } +#ifdef REPLACEARGS_DEBUG + { + char tmp[256]; + snprintf( tmp, sizeof(tmp), "Counted %d args", places.size() ); + MessageBoxA( NULL, tmp, "CommandLineToArgvW", MB_OK | MB_ICONINFORMATION ); + } +#endif // REPLACEARGS_DEBUG + + wchar_t** block = new wchar_t*[places.size()]; + int i = 0; + for ( std::vector::iterator it = places.begin(); it != places.end(); it++ ) + { + block[i++] = &lineDup[*it]; + } + parsed = block; + numArgs = places.size(); + } +#endif // REPLACEARGS_ANSI + + if ( parsed ) + { + std::vectorexpandedArgs; + if ( numArgs > 0 ) + { + expandedArgs.push_back( parsed[0] ); + } + + for ( int i1 = 1; i1 < numArgs; i1++ ) + { + bool wildcarded = (wcschr(parsed[i1], L'?') != NULL) || (wcschr(parsed[i1], L'*') != NULL); + wildcarded &= parsed[i1][0] != L'"'; + wildcarded &= parsed[i1][0] != L'-'; + if ( wildcarded ) + { +#ifdef REPLACEARGS_ANSI + WIN32_FIND_DATAA data = {0}; +#else + WIN32_FIND_DATAW data = {0}; +#endif // REPLACEARGS_ANSI + + int baseLen = wcslen(parsed[i1]) + 2; + wchar_t* base = new wchar_t[baseLen]; + wcsncpy( base, parsed[i1], baseLen ); + wchar_t* last = wcsrchr( base, L'\\' ); + if ( last ) + { + last[1] = 0; + } + else + { + base[0] = 0; + } + baseLen = wcslen( base ); + +#ifdef REPLACEARGS_ANSI + char target[MAX_PATH]; + if ( WideCharToMultiByte( CP_ACP, 0, parsed[i1], -1, target, sizeof(target), NULL, NULL) ) + { + HANDLE hf = FindFirstFileA( target, &data ); +#else + HANDLE hf = FindFirstFileW( parsed[i1], &data ); +#endif // REPLACEARGS_ANSI + if ( hf != INVALID_HANDLE_VALUE ) + { + BOOL found = TRUE; + do + { +#ifdef REPLACEARGS_ANSI + int howMany = MultiByteToWideChar( CP_ACP, 0, data.cFileName, -1, NULL, 0 ); + if ( howMany > 0 ) + { + howMany += baseLen; + wchar_t* tmp = new wchar_t[howMany + 1]; + wcsncpy( tmp, base, howMany + 1 ); + MultiByteToWideChar( CP_ACP, 0, data.cFileName, -1, tmp + baseLen, howMany + 1 - baseLen ); + expandedArgs.push_back( tmp ); + found = FindNextFileA( hf, &data ); + } +#else + int howMany = wcslen(data.cFileName) + baseLen; + wchar_t* tmp = new wchar_t[howMany + 1]; + wcsncpy( tmp, base, howMany + 1 ); + wcsncat( tmp, data.cFileName, howMany + 1 ); + expandedArgs.push_back( tmp ); + found = FindNextFileW( hf, &data ); +#endif // REPLACEARGS_ANSI + } while ( found ); + + FindClose( hf ); + } + else + { + expandedArgs.push_back( parsed[i1] ); + } +#ifdef REPLACEARGS_ANSI + } +#endif // REPLACEARGS_ANSI + + delete[] base; + } + else + { + expandedArgs.push_back( parsed[i1] ); + } + } + + { + wchar_t** block = new wchar_t*[expandedArgs.size()]; + int iz = 0; + for ( std::vector::iterator it = expandedArgs.begin(); it != expandedArgs.end(); it++ ) + { + block[iz++] = *it; + } + parsed = block; + numArgs = expandedArgs.size(); + } + + std::vector newArgs; + for ( int i = 0; i < numArgs; i++ ) + { + gchar* replacement = g_utf16_to_utf8( (gunichar2*)parsed[i], -1, NULL, NULL, NULL ); + if ( replacement ) + { +#ifdef REPLACEARGS_DEBUG + gchar *safe2 = Inkscape::IO::sanitizeString(replacement); + + if ( safe2 ) + { + { + char tmp[1024]; + snprintf( tmp, sizeof(tmp), " [%2d] = '%s'", i, safe2 ); + MessageBoxA( NULL, tmp, "GetCommandLineW", MB_OK | MB_ICONINFORMATION ); + } + g_free( safe2 ); + } +#endif // REPLACEARGS_DEBUG + + newArgs.push_back( replacement ); + } + else + { + newArgs.push_back( blankParam ); + } + } + + // Now push our munged params to be the new argv and argc + { + char** block = new char*[newArgs.size()]; + int iz = 0; + for ( std::vector::iterator it = newArgs.begin(); it != newArgs.end(); it++ ) + { + block[iz++] = *it; + } + argv = block; + argc = newArgs.size(); + worked = true; + } + } +#ifdef REPLACEARGS_DEBUG + else + { + MessageBoxA( NULL, "Unable to process command-line", "CommandLineToArgvW", MB_OK | MB_ICONINFORMATION ); + } +#endif // REPLACEARGS_DEBUG + } +#ifdef REPLACEARGS_DEBUG + else + { + { + MessageBoxA( NULL, "Unable to fetch result from GetCommandLineW()", "GetCommandLineW", MB_OK | MB_ICONINFORMATION ); + } + + char* line2 = GetCommandLineA(); + if ( line2 ) + { + gchar *safe = Inkscape::IO::sanitizeString(line2); + { + { + char tmp[strlen(safe) + 32]; + snprintf( tmp, sizeof(tmp), "GetCommandLineA() = '%s'", safe ); + MessageBoxA( NULL, tmp, "GetCommandLineA", MB_OK | MB_ICONINFORMATION ); + } + } + } + else + { + MessageBoxA( NULL, "Unable to fetch result from GetCommandLineA()", "GetCommandLineA", MB_OK | MB_ICONINFORMATION ); + } + } +#endif // REPLACEARGS_DEBUG + + return worked; +} +#endif // WIN32 + +static GSList * +sp_process_args(poptContext ctx) +{ + GSList *fl = NULL; + + gint a; + while ((a = poptGetNextOpt(ctx)) >= 0) { + switch (a) { + case SP_ARG_FILE: { + gchar const *fn = poptGetOptArg(ctx); + if (fn != NULL) { + fl = g_slist_append(fl, g_strdup(fn)); + } + break; + } + case SP_ARG_VERSION: { + printf("Inkscape %s (%s)\n", INKSCAPE_VERSION, __DATE__); + exit(0); + break; + } + case SP_ARG_EXTENSIONDIR: { + printf("%s\n", INKSCAPE_EXTENSIONDIR); + exit(0); + break; + } + default: { + break; + } + } + } + + gchar const ** const args = poptGetArgs(ctx); + if (args != NULL) { + for (unsigned i = 0; args[i] != NULL; i++) { + fl = g_slist_append(fl, g_strdup(args[i])); + } + } + + return fl; +} + + +/* + 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 : diff --git a/src/make.dep b/src/make.dep new file mode 100644 index 000000000..f9cea8860 --- /dev/null +++ b/src/make.dep @@ -0,0 +1,19683 @@ +######################################################## +## File: make.dep +## Purpose: Dependency listing for use by Makefiles +## Generated by mkdep.pl at :Sun Jan 15 07:06:29 2006 +## Do not edit this file! Changes will be lost. +######################################################## + +application/app-prototype.o: \ + application/app-prototype.cpp \ + application/app-prototype.h + +application/application.o: \ + application/application.cpp \ + application/app-prototype.h \ + application/application.h \ + application/editor.h \ + preferences.h + +application/editor.o: \ + application/editor.cpp \ + application/app-prototype.h \ + application/application.h \ + application/editor.h \ + decimal-round.h \ + desktop-handles.h \ + desktop.h \ + display/display-forward.h \ + document.h \ + enums.h \ + event-context.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + grid-snapper.h \ + guide-snapper.h \ + helper/action.h \ + helper/helper-forward.h \ + io/sys.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-convex-hull.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-object.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + line-snapper.h \ + message.h \ + object-snapper.h \ + path-prefix.h \ + preferences.h \ + prefix.h \ + require-config.h \ + round.h \ + selection.h \ + snapped-point.h \ + snapper.h \ + sp-guide-attachment.h \ + sp-guide.h \ + sp-metric.h \ + sp-namedview.h \ + sp-object-group.h \ + sp-object-repr.h \ + sp-object.h \ + traits/reference.h \ + ui/dialog/dialog-manager.h \ + ui/dialog/dialog.h \ + ui/view/edit-widget-interface.h \ + ui/view/edit-widget.h \ + ui/view/view.h \ + ui/widget/button.h \ + ui/widget/handlebox.h \ + ui/widget/ruler.h \ + ui/widget/selected-style.h \ + ui/widget/svg-canvas.h \ + ui/widget/toolbox.h \ + ui/widget/zoom-status.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + widgets/layer-selector.h + +arc-context.o: \ + arc-context.cpp \ + arc-context.h \ + context-fns.h \ + decimal-round.h \ + desktop-handles.h \ + desktop-style.h \ + desktop.h \ + display/display-forward.h \ + display/nr-arena-forward.h \ + display/sp-canvas.h \ + document.h \ + event-context.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + grid-snapper.h \ + guide-snapper.h \ + helper/helper-forward.h \ + knot-enums.h \ + knotholder.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-convex-hull.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + line-snapper.h \ + macros.h \ + message-context.h \ + message.h \ + object-edit.h \ + object-snapper.h \ + prefs-utils.h \ + round.h \ + selection.h \ + snap.h \ + snapped-point.h \ + snapper.h \ + sp-ellipse.h \ + sp-item.h \ + sp-marker-loc.h \ + sp-metric.h \ + sp-metrics.h \ + sp-namedview.h \ + sp-object-group.h \ + sp-object.h \ + sp-shape.h \ + svg/svg-length.h \ + traits/reference.h \ + ui/view/edit-widget-interface.h \ + ui/view/view.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/node-event-vector.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +attributes-test.o: \ + attributes-test.cpp \ + attributes.h \ + streq.h + +attributes.o: \ + attributes.cpp \ + attributes.h + +color.o: \ + color.cpp \ + color.h + +composite-undo-stack-observer.o: \ + composite-undo-stack-observer.cpp \ + composite-undo-stack-observer.h \ + debug/event.h \ + undo-stack-observer.h \ + util/shared-c-string-ptr.h + +conn-avoid-ref.o: \ + conn-avoid-ref.cpp \ + conn-avoid-ref.h \ + debug/event-tracker.h \ + debug/event.h \ + debug/logger.h \ + decimal-round.h \ + display/nr-arena-forward.h \ + document.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libavoid/geometry.h \ + libavoid/geomtypes.h \ + libavoid/incremental.h \ + libavoid/polyutil.h \ + libavoid/shape.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-ops.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + round.h \ + sp-item.h \ + sp-object.h \ + traits/reference.h \ + util/forward-pointer-iterator.h \ + util/list-container.h \ + util/list.h \ + util/shared-c-string-ptr.h \ + version.h \ + xml/attribute-record.h \ + xml/composite-node-observer.h \ + xml/node-event-vector.h \ + xml/node-fns.h \ + xml/node-observer.h \ + xml/node.h \ + xml/repr.h \ + xml/simple-node.cpp \ + xml/simple-node.h \ + xml/sp-css-attr.h \ + xml/transaction-logger.h + +connector-context.o: \ + connector-context.cpp \ + bad-uri-exception.h \ + conn-avoid-ref.h \ + connector-context.h \ + context-fns.h \ + decimal-round.h \ + desktop-affine.h \ + desktop-handles.h \ + desktop-style.h \ + desktop.h \ + display/canvas-bpath.h \ + display/curve.h \ + display/display-forward.h \ + display/nr-arena-forward.h \ + display/sodipodi-ctrl.h \ + display/sp-canvas.h \ + document.h \ + dom/css.h \ + dom/dom.h \ + dom/domstring.h \ + dom/events.h \ + dom/smil.h \ + dom/stylesheets.h \ + dom/svg.h \ + dom/svgtypes.h \ + dom/views.h \ + event-context.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + inkscape.h \ + knot-enums.h \ + knot.h \ + libavoid/connector.h \ + libavoid/geometry.h \ + libavoid/geomtypes.h \ + libavoid/shape.h \ + libavoid/vertices.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-convex-hull.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + message-context.h \ + message-stack.h \ + message.h \ + prefs-utils.h \ + round.h \ + selection.h \ + snap.h \ + snapped-point.h \ + snapper.h \ + sp-conn-end-pair.h \ + sp-conn-end.h \ + sp-item.h \ + sp-marker-loc.h \ + sp-object.h \ + sp-path.h \ + sp-shape.h \ + sp-use-reference.h \ + traits/reference.h \ + ui/view/edit-widget-interface.h \ + ui/view/view.h \ + uri-references.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/node-event-vector.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +context-fns.o: \ + context-fns.cpp \ + context-fns.h \ + decimal-round.h \ + desktop-affine.h \ + desktop.h \ + display/nr-arena-forward.h \ + event-context.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + message-context.h \ + message-stack.h \ + message.h \ + round.h \ + snap.h \ + snapped-point.h \ + snapper.h \ + sp-item.h \ + sp-object.h \ + traits/reference.h \ + ui/view/edit-widget-interface.h \ + ui/view/view.h \ + util/forward-pointer-iterator.h \ + version.h + +debug/heap.o: \ + debug/heap.cpp \ + debug/gc-heap.h \ + debug/heap.h \ + debug/sysv-heap.h \ + gc-alloc.h \ + gc-core.h \ + util/shared-c-string-ptr.h + +debug/logger.o: \ + debug/logger.cpp \ + debug/event.h \ + debug/logger.h \ + debug/simple-event.h \ + gc-alloc.h \ + gc-core.h \ + util/shared-c-string-ptr.h + +debug/sysv-heap.o: \ + debug/sysv-heap.cpp \ + debug/heap.h \ + debug/sysv-heap.h \ + util/shared-c-string-ptr.h + +desktop-affine.o: \ + desktop-affine.cpp \ + decimal-round.h \ + desktop.h \ + display/nr-arena-forward.h \ + document.h \ + enums.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix-ops.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + message.h \ + round.h \ + sp-item-group.h \ + sp-item.h \ + sp-object.h \ + sp-root.h \ + svg/svg-length.h \ + traits/reference.h \ + ui/view/edit-widget-interface.h \ + ui/view/view.h \ + util/forward-pointer-iterator.h \ + version.h + +desktop-events.o: \ + desktop-events.cpp \ + decimal-round.h \ + desktop-handles.h \ + desktop.h \ + dialogs/dialog-events.h \ + display/display-forward.h \ + display/guideline.h \ + display/sp-canvas.h \ + document.h \ + event-context.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + grid-snapper.h \ + guide-snapper.h \ + helper/helper-forward.h \ + helper/unit-menu.h \ + helper/units.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + line-snapper.h \ + message-context.h \ + message.h \ + object-snapper.h \ + round.h \ + snapped-point.h \ + snapper.h \ + sp-guide-attachment.h \ + sp-guide.h \ + sp-metric.h \ + sp-metrics.h \ + sp-namedview.h \ + sp-object-group.h \ + sp-object.h \ + traits/reference.h \ + ui/view/edit-widget-interface.h \ + ui/view/view-widget.h \ + ui/view/view.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + widgets/desktop-widget.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +desktop-handles.o: \ + desktop-handles.cpp \ + decimal-round.h \ + desktop.h \ + display/sp-canvas.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + message.h \ + round.h \ + ui/view/edit-widget-interface.h \ + ui/view/view.h + +desktop-style.o: \ + desktop-style.cpp \ + bad-uri-exception.h \ + color-rgba.h \ + color.h \ + decimal-round.h \ + desktop-style.h \ + desktop.h \ + display/nr-arena-forward.h \ + document.h \ + dom/css.h \ + dom/dom.h \ + dom/domstring.h \ + dom/events.h \ + dom/smil.h \ + dom/stylesheets.h \ + dom/svg.h \ + dom/svgtypes.h \ + dom/views.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + inkscape.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-convex-hull.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix-ops.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-pixblock.h \ + libnr/nr-pixops.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate-ops.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + libnrtype/Layout-TNG.h \ + libnrtype/font-style-to-pos.h \ + libnrtype/nr-type-pos-def.h \ + message.h \ + prefs-utils.h \ + round.h \ + selection.h \ + sp-flowdiv.h \ + sp-flowregion.h \ + sp-flowtext.h \ + sp-gradient-fns.h \ + sp-gradient-spread.h \ + sp-gradient-units.h \ + sp-gradient-vector.h \ + sp-gradient.h \ + sp-item.h \ + sp-linear-gradient-fns.h \ + sp-linear-gradient.h \ + sp-marker-loc.h \ + sp-object.h \ + sp-paint-server.h \ + sp-pattern.h \ + sp-radial-gradient-fns.h \ + sp-radial-gradient.h \ + sp-string.h \ + sp-text.h \ + sp-textpath.h \ + sp-tspan.h \ + sp-use.h \ + style.h \ + svg/css-ostringstream.h \ + svg/svg-length.h \ + text-tag-attributes.h \ + traits/reference.h \ + ui/view/edit-widget-interface.h \ + ui/view/view.h \ + uri-references.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +desktop.o: \ + desktop.cpp \ + color.h \ + decimal-round.h \ + desktop-events.h \ + desktop-handles.h \ + desktop.h \ + display/canvas-arena.h \ + display/display-forward.h \ + display/gnome-canvas-acetate.h \ + display/nr-arena-forward.h \ + display/nr-arena-item.h \ + display/nr-arena.h \ + display/sodipodi-ctrlrect.h \ + display/sp-canvas-util.h \ + display/sp-canvas.h \ + document.h \ + event-context.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + grid-snapper.h \ + guide-snapper.h \ + helper/helper-forward.h \ + helper/units.h \ + inkscape-private.h \ + inkscape.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-convex-hull.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-div.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-object.h \ + libnr/nr-pixblock.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect-ops.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + line-snapper.h \ + macros.h \ + message-context.h \ + message-stack.h \ + message.h \ + object-hierarchy.h \ + object-snapper.h \ + prefs-utils.h \ + round.h \ + select-context.h \ + selection.h \ + snapped-point.h \ + snapper.h \ + sp-item-group.h \ + sp-item.h \ + sp-metric.h \ + sp-namedview.h \ + sp-object-group.h \ + sp-object.h \ + sp-paint-server.h \ + traits/reference.h \ + ui/dialog/dialog-manager.h \ + ui/dialog/dialog.h \ + ui/view/edit-widget-interface.h \ + ui/view/view.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +dialogs/clonetiler.o: \ + dialogs/clonetiler.cpp \ + application/app-prototype.h \ + application/application.h \ + application/editor.h \ + color.h \ + decimal-round.h \ + desktop-handles.h \ + dialogs/dialog-events.h \ + dialogs/unclump.h \ + display/display-forward.h \ + display/nr-arena-forward.h \ + display/nr-arena-item.h \ + display/nr-arena.h \ + document.h \ + dom/css.h \ + dom/dom.h \ + dom/domstring.h \ + dom/events.h \ + dom/smil.h \ + dom/stylesheets.h \ + dom/svg.h \ + dom/svgtypes.h \ + dom/views.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + grid-snapper.h \ + guide-snapper.h \ + helper/helper-forward.h \ + helper/unit-menu.h \ + helper/units.h \ + helper/window.h \ + inkscape.h \ + interface.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-convex-hull.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix-ops.h \ + libnr/nr-matrix-translate-ops.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-object.h \ + libnr/nr-pixblock.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate-ops.h \ + libnr/nr-translate-rotate-ops.h \ + libnr/nr-translate-scale-ops.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + line-snapper.h \ + macros.h \ + message-stack.h \ + message.h \ + object-snapper.h \ + prefs-utils.h \ + require-config.h \ + round.h \ + selection.h \ + snapped-point.h \ + snapper.h \ + sp-item.h \ + sp-marker-loc.h \ + sp-metric.h \ + sp-namedview.h \ + sp-object-group.h \ + sp-object.h \ + sp-paint-server.h \ + sp-use.h \ + style.h \ + svg/svg-length.h \ + traits/reference.h \ + ui/widget/button.h \ + ui/widget/color-picker.h \ + ui/widget/color-preview.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + verbs.h \ + version.h \ + widgets/icon.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +dialogs/debugdialog.o: \ + dialogs/debugdialog.cpp \ + dialogs/debugdialog.h \ + ui/dialog/dialog.h \ + ui/widget/button.h + +dialogs/dialog-events.o: \ + dialogs/dialog-events.cpp \ + decimal-round.h \ + desktop.h \ + dialogs/dialog-events.h \ + event-context.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + inkscape-private.h \ + inkscape.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + macros.h \ + message.h \ + prefs-utils.h \ + round.h \ + ui/view/edit-widget-interface.h \ + ui/view/view.h + +dialogs/display-settings.o: \ + dialogs/display-settings.cpp \ + color.h \ + decimal-round.h \ + desktop-handles.h \ + desktop.h \ + dialogs/dialog-events.h \ + display/display-forward.h \ + document.h \ + enums.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + helper/helper-forward.h \ + helper/window.h \ + inkscape.h \ + interface.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-convex-hull.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + macros.h \ + message-stack.h \ + message.h \ + prefs-utils.h \ + require-config.h \ + round.h \ + selcue.h \ + selection-chemistry.h \ + selection.h \ + sp-marker-loc.h \ + style.h \ + traits/reference.h \ + ui/view/edit-widget-interface.h \ + ui/view/view.h \ + ui/widget/button.h \ + ui/widget/style-swatch.h \ + unit-constants.h \ + util/list.h \ + verbs.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +dialogs/eek-preview.o: \ + dialogs/eek-preview.cpp \ + dialogs/eek-preview.h + +dialogs/export.o: \ + dialogs/export.cpp \ + decimal-round.h \ + desktop-handles.h \ + dialogs/dialog-events.h \ + display/display-forward.h \ + display/nr-arena-forward.h \ + document.h \ + extension/db.h \ + extension/extension-forward.h \ + extension/extension.h \ + extension/output.h \ + file.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + grid-snapper.h \ + guide-snapper.h \ + helper/helper-forward.h \ + helper/unit-menu.h \ + helper/units.h \ + helper/window.h \ + inkscape-private.h \ + inkscape.h \ + interface.h \ + io/sys.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-convex-hull.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + line-snapper.h \ + macros.h \ + object-snapper.h \ + prefs-utils.h \ + require-config.h \ + round.h \ + selection.h \ + snapped-point.h \ + snapper.h \ + sp-item.h \ + sp-metric.h \ + sp-namedview.h \ + sp-object-group.h \ + sp-object.h \ + traits/reference.h \ + unit-constants.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + verbs.h \ + version.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +dialogs/extensions.o: \ + dialogs/extensions.cpp \ + dialogs/extensions.h \ + document.h \ + extension/db.h \ + extension/extension-forward.h \ + extension/extension.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-forward.h \ + traits/reference.h \ + ui/previewable.h \ + ui/previewfillable.h \ + ui/widget/button.h \ + ui/widget/panel.h \ + util/list.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +dialogs/filedialog.o: \ + dialogs/filedialog.cpp \ + dialogs/dialog-events.h \ + dialogs/filedialog.h \ + dialogs/input.h \ + display/display-forward.h \ + document.h \ + extension/db.h \ + extension/extension-forward.h \ + extension/extension.h \ + extension/output.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + inkscape.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-forward.h \ + prefs-utils.h \ + svg-view-widget.h \ + traits/reference.h \ + ui/stock.h \ + ui/view/view-widget.h \ + util/list.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +dialogs/fill-style.o: \ + dialogs/fill-style.cpp \ + bad-uri-exception.h \ + color.h \ + composite-undo-stack-observer.h \ + decimal-round.h \ + desktop-handles.h \ + desktop-style.h \ + display/display-forward.h \ + display/nr-arena-forward.h \ + document-private.h \ + document.h \ + enums.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + gradient-chemistry.h \ + inkscape.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-convex-hull.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-pixblock.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + round.h \ + selection.h \ + sp-defs.h \ + sp-gradient-fns.h \ + sp-gradient-spread.h \ + sp-gradient-units.h \ + sp-gradient-vector.h \ + sp-gradient.h \ + sp-item-group.h \ + sp-item.h \ + sp-linear-gradient-fns.h \ + sp-linear-gradient.h \ + sp-marker-loc.h \ + sp-object.h \ + sp-paint-server.h \ + sp-pattern.h \ + sp-radial-gradient-fns.h \ + sp-radial-gradient.h \ + sp-root.h \ + style.h \ + svg/svg-length.h \ + traits/reference.h \ + undo-stack-observer.h \ + uri-references.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + widgets/paint-selector.h \ + widgets/sp-widget.h \ + xml/event-fns.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +dialogs/find.o: \ + dialogs/find.cpp \ + decimal-round.h \ + desktop-handles.h \ + desktop.h \ + dialogs/dialog-events.h \ + display/display-forward.h \ + display/nr-arena-forward.h \ + document.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + helper/helper-forward.h \ + helper/window.h \ + inkscape.h \ + interface.h \ + libavoid/connector.h \ + libavoid/geometry.h \ + libavoid/geomtypes.h \ + libavoid/shape.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-convex-hull.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix-ops.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate-ops.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + libnrtype/Layout-TNG.h \ + macros.h \ + message-stack.h \ + message.h \ + prefs-utils.h \ + require-config.h \ + round.h \ + selection-chemistry.h \ + selection.h \ + sp-conn-end-pair.h \ + sp-defs.h \ + sp-ellipse.h \ + sp-flowtext.h \ + sp-image.h \ + sp-item-group.h \ + sp-item.h \ + sp-line.h \ + sp-marker-loc.h \ + sp-object.h \ + sp-offset.h \ + sp-path.h \ + sp-polygon.h \ + sp-polyline.h \ + sp-rect.h \ + sp-shape.h \ + sp-spiral.h \ + sp-star.h \ + sp-string.h \ + sp-text.h \ + sp-tspan.h \ + sp-use.h \ + svg/svg-length.h \ + text-editing.h \ + text-tag-attributes.h \ + traits/reference.h \ + ui/view/edit-widget-interface.h \ + ui/view/view.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + verbs.h \ + version.h \ + widgets/icon.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +dialogs/iconpreview.o: \ + dialogs/iconpreview.cpp \ + decimal-round.h \ + desktop-handles.h \ + desktop.h \ + dialogs/iconpreview.h \ + display/display-forward.h \ + display/nr-arena-forward.h \ + display/nr-arena.h \ + document.h \ + enums.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + inkscape.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-convex-hull.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-object.h \ + libnr/nr-pixblock.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + message.h \ + prefs-utils.h \ + round.h \ + selection.h \ + sp-item-group.h \ + sp-item.h \ + sp-object.h \ + sp-paint-server.h \ + sp-root.h \ + svg/svg-length.h \ + traits/reference.h \ + ui/previewable.h \ + ui/previewfillable.h \ + ui/stock.h \ + ui/view/edit-widget-interface.h \ + ui/view/view.h \ + ui/widget/button.h \ + ui/widget/panel.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +dialogs/in-dt-coordsys.o: \ + dialogs/in-dt-coordsys.cpp \ + decimal-round.h \ + display/nr-arena-forward.h \ + enums.h \ + forward.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + round.h \ + sp-item-group.h \ + sp-item.h \ + sp-object.h \ + sp-root.h \ + svg/svg-length.h \ + traits/reference.h \ + util/forward-pointer-iterator.h \ + version.h + +dialogs/input.o: \ + dialogs/input.cpp \ + dialogs/dialog-events.h \ + document.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + helper/helper-forward.h \ + inkscape.h \ + interface.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-forward.h \ + macros.h \ + prefs-utils.h \ + require-config.h \ + traits/reference.h \ + util/list.h \ + verbs.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +dialogs/item-properties.o: \ + dialogs/item-properties.cpp \ + decimal-round.h \ + desktop-handles.h \ + dialogs/dialog-events.h \ + display/display-forward.h \ + display/nr-arena-forward.h \ + document.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + helper/helper-forward.h \ + helper/window.h \ + inkscape.h \ + interface.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-convex-hull.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + macros.h \ + prefs-utils.h \ + require-config.h \ + round.h \ + selection.h \ + sp-item.h \ + sp-object.h \ + traits/reference.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + verbs.h \ + version.h \ + widgets/sp-widget.h + +dialogs/layer-properties.o: \ + dialogs/layer-properties.cpp \ + decimal-round.h \ + desktop-handles.h \ + desktop.h \ + dialogs/layer-properties.h \ + display/display-forward.h \ + document.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + inkscape.h \ + layer-fns.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-convex-hull.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + message-stack.h \ + message.h \ + round.h \ + selection.h \ + sp-object.h \ + traits/reference.h \ + ui/dialog/dialog.h \ + ui/stock.h \ + ui/view/edit-widget-interface.h \ + ui/view/view.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h + +dialogs/object-attributes.o: \ + dialogs/object-attributes.cpp \ + decimal-round.h \ + dialogs/sp-attribute-widget.h \ + display/nr-arena-forward.h \ + forward.h \ + helper/window.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + macros.h \ + round.h \ + sp-anchor.h \ + sp-item-group.h \ + sp-item.h \ + sp-object.h \ + traits/reference.h \ + util/forward-pointer-iterator.h \ + version.h + +dialogs/object-properties.o: \ + dialogs/object-properties.cpp \ + color.h \ + decimal-round.h \ + desktop-handles.h \ + desktop-style.h \ + dialogs/dialog-events.h \ + dialogs/fill-style.h \ + dialogs/stroke-style.h \ + display/canvas-bpath.h \ + display/display-forward.h \ + display/sp-canvas.h \ + document.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + helper/helper-forward.h \ + helper/window.h \ + inkscape-stock.h \ + inkscape.h \ + interface.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + macros.h \ + prefs-utils.h \ + require-config.h \ + round.h \ + sp-marker-loc.h \ + style.h \ + svg/css-ostringstream.h \ + traits/reference.h \ + util/list.h \ + verbs.h \ + widgets/icon.h \ + widgets/sp-widget.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +dialogs/rdf.o: \ + dialogs/rdf.cpp \ + decimal-round.h \ + dialogs/rdf.h \ + display/nr-arena-forward.h \ + document.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + round.h \ + sp-item-group.h \ + sp-item.h \ + sp-object.h \ + traits/reference.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +dialogs/sp-attribute-widget.o: \ + dialogs/sp-attribute-widget.cpp \ + dialogs/sp-attribute-widget.h \ + document.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-forward.h \ + macros.h \ + sp-object.h \ + traits/reference.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +dialogs/stroke-style.o: \ + dialogs/stroke-style.cpp \ + bad-uri-exception.h \ + color.h \ + composite-undo-stack-observer.h \ + decimal-round.h \ + desktop-handles.h \ + desktop-style.h \ + dialogs/dialog-events.h \ + dialogs/stroke-style.h \ + display/canvas-bpath.h \ + display/display-forward.h \ + display/nr-arena-forward.h \ + display/nr-arena-item.h \ + display/nr-arena.h \ + display/sp-canvas.h \ + document-private.h \ + document.h \ + enums.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + gradient-chemistry.h \ + grid-snapper.h \ + guide-snapper.h \ + helper/helper-forward.h \ + helper/stock-items.h \ + helper/unit-menu.h \ + helper/units.h \ + inkscape-stock.h \ + inkscape.h \ + io/sys.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-convex-hull.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-ops.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-object.h \ + libnr/nr-pixblock.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate-ops.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + libnrtype/Layout-TNG.h \ + line-snapper.h \ + object-snapper.h \ + path-prefix.h \ + prefix.h \ + require-config.h \ + round.h \ + selection.h \ + snapped-point.h \ + snapper.h \ + sp-defs.h \ + sp-gradient-fns.h \ + sp-gradient-spread.h \ + sp-gradient-units.h \ + sp-gradient-vector.h \ + sp-gradient.h \ + sp-item-group.h \ + sp-item.h \ + sp-linear-gradient-fns.h \ + sp-linear-gradient.h \ + sp-marker-loc.h \ + sp-marker.h \ + sp-metric.h \ + sp-namedview.h \ + sp-object-group.h \ + sp-object.h \ + sp-paint-server.h \ + sp-pattern.h \ + sp-radial-gradient-fns.h \ + sp-radial-gradient.h \ + sp-rect.h \ + sp-root.h \ + sp-shape.h \ + sp-string.h \ + sp-text.h \ + style.h \ + svg/css-ostringstream.h \ + svg/svg-length.h \ + text-tag-attributes.h \ + traits/reference.h \ + undo-stack-observer.h \ + uri-references.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + widgets/dash-selector.h \ + widgets/icon.h \ + widgets/paint-selector.h \ + widgets/sp-widget.h \ + widgets/spw-utilities.h \ + xml/event-fns.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +dialogs/swatches.o: \ + dialogs/swatches.cpp \ + desktop-handles.h \ + desktop-style.h \ + dialogs/eek-preview.h \ + dialogs/swatches.h \ + display/display-forward.h \ + document.h \ + dom/css.h \ + dom/dom.h \ + dom/domstring.h \ + dom/events.h \ + dom/smil.h \ + dom/stylesheets.h \ + dom/svg.h \ + dom/svgtypes.h \ + dom/views.h \ + extension/db.h \ + extension/extension-forward.h \ + extension/extension.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + inkscape.h \ + io/sys.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-forward.h \ + path-prefix.h \ + prefix.h \ + require-config.h \ + traits/reference.h \ + ui/previewable.h \ + ui/previewfillable.h \ + ui/previewholder.h \ + ui/widget/button.h \ + ui/widget/panel.h \ + util/list.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +dialogs/text-edit.o: \ + dialogs/text-edit.cpp \ + color.h \ + decimal-round.h \ + desktop-handles.h \ + desktop-style.h \ + dialogs/dialog-events.h \ + display/display-forward.h \ + display/nr-arena-forward.h \ + document.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + helper/helper-forward.h \ + helper/window.h \ + inkscape-stock.h \ + inkscape.h \ + interface.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-convex-hull.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-ops.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate-ops.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + libnrtype/FontFactory.h \ + libnrtype/Layout-TNG.h \ + libnrtype/font-instance.h \ + libnrtype/font-style-to-pos.h \ + libnrtype/font-style.h \ + libnrtype/nr-type-pos-def.h \ + libnrtype/nr-type-primitives.h \ + libnrtype/nrtype-forward.h \ + livarot/LivarotDefs.h \ + livarot/livarot-forward.h \ + macros.h \ + prefs-utils.h \ + require-config.h \ + round.h \ + selection.h \ + sp-flowtext.h \ + sp-item.h \ + sp-marker-loc.h \ + sp-object.h \ + sp-string.h \ + sp-text.h \ + style.h \ + svg/css-ostringstream.h \ + svg/svg-length.h \ + text-editing.h \ + text-tag-attributes.h \ + traits/reference.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + verbs.h \ + version.h \ + widgets/font-selector.h \ + widgets/icon.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +dialogs/tiledialog.o: \ + dialogs/tiledialog.cpp \ + decimal-round.h \ + desktop-handles.h \ + dialogs/tiledialog.h \ + display/display-forward.h \ + display/nr-arena-forward.h \ + document.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + helper/helper-forward.h \ + inkscape.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-convex-hull.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-ops.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + prefs-utils.h \ + require-config.h \ + round.h \ + selection.h \ + sp-item.h \ + sp-object.h \ + traits/reference.h \ + ui/dialog/dialog.h \ + ui/stock.h \ + ui/widget/button.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + verbs.h \ + version.h \ + widgets/icon.h + +dialogs/unclump.o: \ + dialogs/unclump.cpp \ + decimal-round.h \ + display/nr-arena-forward.h \ + forward.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-ops.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + round.h \ + sp-item.h \ + sp-object.h \ + traits/reference.h \ + util/forward-pointer-iterator.h \ + version.h + +dialogs/xml-tree.o: \ + dialogs/xml-tree.cpp \ + decimal-round.h \ + desktop-handles.h \ + desktop.h \ + dialogs/dialog-events.h \ + dialogs/in-dt-coordsys.h \ + display/display-forward.h \ + display/nr-arena-forward.h \ + document.h \ + enums.h \ + event-context.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + helper/helper-forward.h \ + helper/window.h \ + inkscape-stock.h \ + inkscape.h \ + interface.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-convex-hull.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix-ops.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate-ops.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + libnrtype/Layout-TNG.h \ + macros.h \ + message-context.h \ + message-stack.h \ + message.h \ + prefs-utils.h \ + require-config.h \ + round.h \ + selection.h \ + shortcuts.h \ + sp-item-group.h \ + sp-item.h \ + sp-object.h \ + sp-root.h \ + sp-string.h \ + sp-tspan.h \ + svg/svg-length.h \ + text-tag-attributes.h \ + traits/reference.h \ + ui/view/edit-widget-interface.h \ + ui/view/view.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + verbs.h \ + version.h \ + widgets/icon.h \ + widgets/sp-xmlview-attr-list.h \ + widgets/sp-xmlview-content.h \ + widgets/sp-xmlview-tree.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +dir-util-test.o: \ + dir-util-test.cpp \ + dir-util.h \ + streq.h + +dir-util.o: \ + dir-util.cpp + +display/bezier-utils.o: \ + display/bezier-utils.cpp \ + decimal-round.h \ + display/bezier-utils.h \ + isnan.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-macros.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + round.h + +display/canvas-arena.o: \ + display/canvas-arena.cpp \ + decimal-round.h \ + display/canvas-arena.h \ + display/display-forward.h \ + display/nr-arena-forward.h \ + display/nr-arena-group.h \ + display/nr-arena-item.h \ + display/nr-arena.h \ + display/sp-canvas-util.h \ + display/sp-canvas.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + helper/sp-marshal.h \ + libnr/nr-blit.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-object.h \ + libnr/nr-pixblock.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + round.h \ + sp-object.h \ + sp-paint-server.h \ + traits/reference.h \ + util/forward-pointer-iterator.h \ + version.h + +display/canvas-bpath.o: \ + display/canvas-bpath.cpp \ + decimal-round.h \ + display/canvas-bpath.h \ + display/curve.h \ + display/display-forward.h \ + display/sp-canvas-util.h \ + display/sp-canvas.h \ + libavoid/geometry.h \ + libavoid/geomtypes.h \ + libavoid/shape.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-pixops.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + livarot/BitLigne.h \ + livarot/LivarotDefs.h \ + livarot/Path.h \ + livarot/int-line.h \ + livarot/livarot-forward.h \ + round.h + +display/canvas-grid.o: \ + display/canvas-grid.cpp \ + decimal-round.h \ + display/canvas-grid.h \ + display/display-forward.h \ + display/sp-canvas-util.h \ + display/sp-canvas.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-pixops.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + round.h + +display/curve.o: \ + display/curve.cpp \ + decimal-round.h \ + display/curve.h \ + libnr/n-art-bpath.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-path-code.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate-ops.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + round.h + +display/gnome-canvas-acetate.o: \ + display/gnome-canvas-acetate.cpp \ + decimal-round.h \ + display/display-forward.h \ + display/gnome-canvas-acetate.h \ + display/sp-canvas.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + round.h + +display/guideline.o: \ + display/guideline.cpp \ + decimal-round.h \ + display/display-forward.h \ + display/guideline.h \ + display/sp-canvas-util.h \ + display/sp-canvas.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-pixops.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + round.h + +display/nr-arena-glyphs.o: \ + display/nr-arena-glyphs.cpp \ + color.h \ + decimal-round.h \ + display/canvas-bpath.h \ + display/curve.h \ + display/nr-arena-forward.h \ + display/nr-arena-glyphs.h \ + display/nr-arena-group.h \ + display/nr-arena-item.h \ + display/nr-arena.h \ + display/sp-canvas.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libnr/nr-blit.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-object.h \ + libnr/nr-path.h \ + libnr/nr-pixblock.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + libnrtype/FontFactory.h \ + libnrtype/RasterFont.h \ + libnrtype/font-instance.h \ + libnrtype/font-style.h \ + libnrtype/nr-type-pos-def.h \ + libnrtype/nr-type-primitives.h \ + libnrtype/nrtype-forward.h \ + libnrtype/raster-glyph.h \ + livarot/LivarotDefs.h \ + livarot/livarot-forward.h \ + require-config.h \ + round.h \ + sp-marker-loc.h \ + sp-object.h \ + sp-paint-server.h \ + style.h \ + traits/reference.h \ + util/forward-pointer-iterator.h \ + version.h + +display/nr-arena-group.o: \ + display/nr-arena-group.cpp \ + decimal-round.h \ + display/nr-arena-forward.h \ + display/nr-arena-group.h \ + display/nr-arena-item.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-object.h \ + libnr/nr-pixblock.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + round.h + +display/nr-arena-image.o: \ + display/nr-arena-image.cpp \ + decimal-round.h \ + display/nr-arena-forward.h \ + display/nr-arena-image.h \ + display/nr-arena-item.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libnr/nr-compose-transform.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-object.h \ + libnr/nr-pixblock.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + prefs-utils.h \ + round.h + +display/nr-arena-item.o: \ + display/nr-arena-item.cpp \ + decimal-round.h \ + display/nr-arena-forward.h \ + display/nr-arena-item.h \ + display/nr-arena.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libnr/nr-blit.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-object.h \ + libnr/nr-pixblock.h \ + libnr/nr-pixops.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + round.h \ + sp-object.h \ + sp-paint-server.h \ + traits/reference.h \ + util/forward-pointer-iterator.h \ + version.h + +display/nr-arena-shape.o: \ + display/nr-arena-shape.cpp \ + color.h \ + decimal-round.h \ + display/canvas-bpath.h \ + display/curve.h \ + display/nr-arena-forward.h \ + display/nr-arena-item.h \ + display/nr-arena-shape.h \ + display/nr-arena.h \ + display/sp-canvas.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libavoid/geometry.h \ + libavoid/geomtypes.h \ + libavoid/shape.h \ + libnr/n-art-bpath.h \ + libnr/nr-blit.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-ops.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-object.h \ + libnr/nr-path-code.h \ + libnr/nr-path.h \ + libnr/nr-pixblock.h \ + libnr/nr-pixops.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + livarot/LivarotDefs.h \ + livarot/Path.h \ + livarot/float-line.h \ + livarot/int-line.h \ + livarot/livarot-forward.h \ + round.h \ + sp-marker-loc.h \ + sp-object.h \ + sp-paint-server.h \ + style.h \ + traits/reference.h \ + util/forward-pointer-iterator.h \ + version.h + +display/nr-arena.o: \ + display/nr-arena.cpp \ + decimal-round.h \ + display/nr-arena-forward.h \ + display/nr-arena-item.h \ + display/nr-arena.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libnr/nr-blit.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-object.h \ + libnr/nr-pixblock.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + round.h \ + sp-object.h \ + sp-paint-server.h \ + traits/reference.h \ + util/forward-pointer-iterator.h \ + version.h + +display/nr-gradient-gpl.o: \ + display/nr-gradient-gpl.cpp \ + decimal-round.h \ + display/nr-gradient-gpl.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-gradient.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-pixblock-pixel.h \ + libnr/nr-pixblock.h \ + libnr/nr-pixops.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-render.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + round.h + +display/nr-plain-stuff-gdk.o: \ + display/nr-plain-stuff-gdk.cpp \ + decimal-round.h \ + display/nr-plain-stuff-gdk.h \ + display/nr-plain-stuff.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-pixblock-pattern.h \ + libnr/nr-pixblock.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + round.h + +display/nr-plain-stuff.o: \ + display/nr-plain-stuff.cpp \ + display/nr-plain-stuff.h \ + libnr/nr-pixops.h + +display/sodipodi-ctrl.o: \ + display/sodipodi-ctrl.cpp \ + decimal-round.h \ + display/display-forward.h \ + display/sodipodi-ctrl.h \ + display/sp-canvas-util.h \ + display/sp-canvas.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + round.h + +display/sodipodi-ctrlrect.o: \ + display/sodipodi-ctrlrect.cpp \ + decimal-round.h \ + display/display-forward.h \ + display/sodipodi-ctrlrect.h \ + display/sp-canvas-util.h \ + display/sp-canvas.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + round.h + +display/sp-canvas-util.o: \ + display/sp-canvas-util.cpp \ + decimal-round.h \ + display/sp-canvas-util.h \ + display/sp-canvas.h \ + libavoid/geometry.h \ + libavoid/geomtypes.h \ + libavoid/shape.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-div.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-pixops.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + livarot/BitLigne.h \ + livarot/LivarotDefs.h \ + livarot/int-line.h \ + livarot/livarot-forward.h \ + round.h + +display/sp-canvas.o: \ + display/sp-canvas.cpp \ + decimal-round.h \ + display/display-forward.h \ + display/sp-canvas.h \ + helper/sp-marshal.h \ + libnr/nr-convex-hull.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix-ops.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-pixblock.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + round.h + +display/sp-ctrlline.o: \ + display/sp-ctrlline.cpp \ + decimal-round.h \ + display/display-forward.h \ + display/sp-canvas-util.h \ + display/sp-canvas.h \ + display/sp-ctrlline.h \ + libavoid/geometry.h \ + libavoid/geomtypes.h \ + libavoid/shape.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + livarot/LivarotDefs.h \ + livarot/Path.h \ + livarot/livarot-forward.h \ + round.h + +display/sp-ctrlquadr.o: \ + display/sp-ctrlquadr.cpp \ + decimal-round.h \ + display/display-forward.h \ + display/sp-canvas-util.h \ + display/sp-canvas.h \ + display/sp-ctrlquadr.h \ + libavoid/geometry.h \ + libavoid/geomtypes.h \ + libavoid/shape.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + livarot/LivarotDefs.h \ + livarot/Path.h \ + livarot/livarot-forward.h \ + round.h + +document-undo.o: \ + document-undo.cpp \ + composite-undo-stack-observer.h \ + debug/event-tracker.h \ + debug/event.h \ + debug/logger.h \ + debug/simple-event.h \ + decimal-round.h \ + display/nr-arena-forward.h \ + document-private.h \ + document.h \ + enums.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + inkscape.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + round.h \ + sp-defs.h \ + sp-item-group.h \ + sp-item.h \ + sp-object.h \ + sp-root.h \ + svg/svg-length.h \ + traits/reference.h \ + undo-stack-observer.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + util/shared-c-string-ptr.h \ + version.h \ + xml/event-fns.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +document.o: \ + document.cpp \ + application/app-prototype.h \ + application/application.h \ + application/editor.h \ + composite-undo-stack-observer.h \ + decimal-round.h \ + dialogs/rdf.h \ + dir-util.h \ + display/nr-arena-forward.h \ + display/nr-arena-item.h \ + document-private.h \ + document.h \ + enums.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + helper/units.h \ + inkscape-private.h \ + inkscape.h \ + inkscape_version.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-object.h \ + libnr/nr-pixblock.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + prefs-utils.h \ + round.h \ + sp-defs.h \ + sp-item-group.h \ + sp-item.h \ + sp-metric.h \ + sp-object-repr.h \ + sp-object.h \ + sp-root.h \ + svg/svg-length.h \ + traits/reference.h \ + undo-stack-observer.h \ + unit-constants.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/event-fns.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +dom/charclass.o: \ + dom/charclass.cpp \ + dom/charclass.h + +dom/cssparser.o: \ + dom/cssparser.cpp \ + dom/charclass.h \ + dom/css.h \ + dom/cssparser.h \ + dom/dom.h \ + dom/domstring.h \ + dom/stylesheets.h \ + dom/views.h + +dom/domimpl.o: \ + dom/domimpl.cpp \ + dom/dom.h \ + dom/domimpl.h \ + dom/domstring.h + +dom/domstream.o: \ + dom/domstream.cpp \ + dom/dom.h \ + dom/domstream.h \ + dom/domstring.h + +dom/domstring.o: \ + dom/domstring.cpp \ + dom/domstring.h + +dom/js/fdlibm/e_acos.o: \ + dom/js/fdlibm/e_acos.c \ + dom/js/fdlibm/fdlibm.h + +dom/js/fdlibm/e_acosh.o: \ + dom/js/fdlibm/e_acosh.c \ + dom/js/fdlibm/fdlibm.h + +dom/js/fdlibm/e_asin.o: \ + dom/js/fdlibm/e_asin.c \ + dom/js/fdlibm/fdlibm.h + +dom/js/fdlibm/e_atan2.o: \ + dom/js/fdlibm/e_atan2.c \ + dom/js/fdlibm/fdlibm.h + +dom/js/fdlibm/e_atanh.o: \ + dom/js/fdlibm/e_atanh.c \ + dom/js/fdlibm/fdlibm.h + +dom/js/fdlibm/e_cosh.o: \ + dom/js/fdlibm/e_cosh.c \ + dom/js/fdlibm/fdlibm.h + +dom/js/fdlibm/e_exp.o: \ + dom/js/fdlibm/e_exp.c \ + dom/js/fdlibm/fdlibm.h + +dom/js/fdlibm/e_fmod.o: \ + dom/js/fdlibm/e_fmod.c \ + dom/js/fdlibm/fdlibm.h + +dom/js/fdlibm/e_gamma.o: \ + dom/js/fdlibm/e_gamma.c \ + dom/js/fdlibm/fdlibm.h + +dom/js/fdlibm/e_gamma_r.o: \ + dom/js/fdlibm/e_gamma_r.c \ + dom/js/fdlibm/fdlibm.h + +dom/js/fdlibm/e_hypot.o: \ + dom/js/fdlibm/e_hypot.c \ + dom/js/fdlibm/fdlibm.h + +dom/js/fdlibm/e_j0.o: \ + dom/js/fdlibm/e_j0.c \ + dom/js/fdlibm/fdlibm.h + +dom/js/fdlibm/e_j1.o: \ + dom/js/fdlibm/e_j1.c \ + dom/js/fdlibm/fdlibm.h + +dom/js/fdlibm/e_jn.o: \ + dom/js/fdlibm/e_jn.c \ + dom/js/fdlibm/fdlibm.h + +dom/js/fdlibm/e_lgamma.o: \ + dom/js/fdlibm/e_lgamma.c \ + dom/js/fdlibm/fdlibm.h + +dom/js/fdlibm/e_lgamma_r.o: \ + dom/js/fdlibm/e_lgamma_r.c \ + dom/js/fdlibm/fdlibm.h + +dom/js/fdlibm/e_log.o: \ + dom/js/fdlibm/e_log.c \ + dom/js/fdlibm/fdlibm.h + +dom/js/fdlibm/e_log10.o: \ + dom/js/fdlibm/e_log10.c \ + dom/js/fdlibm/fdlibm.h + +dom/js/fdlibm/e_pow.o: \ + dom/js/fdlibm/e_pow.c \ + dom/js/fdlibm/fdlibm.h + +dom/js/fdlibm/e_rem_pio2.o: \ + dom/js/fdlibm/e_rem_pio2.c \ + dom/js/fdlibm/fdlibm.h + +dom/js/fdlibm/e_remainder.o: \ + dom/js/fdlibm/e_remainder.c \ + dom/js/fdlibm/fdlibm.h + +dom/js/fdlibm/e_scalb.o: \ + dom/js/fdlibm/e_scalb.c \ + dom/js/fdlibm/fdlibm.h + +dom/js/fdlibm/e_sinh.o: \ + dom/js/fdlibm/e_sinh.c \ + dom/js/fdlibm/fdlibm.h + +dom/js/fdlibm/e_sqrt.o: \ + dom/js/fdlibm/e_sqrt.c \ + dom/js/fdlibm/fdlibm.h + +dom/js/fdlibm/k_cos.o: \ + dom/js/fdlibm/k_cos.c \ + dom/js/fdlibm/fdlibm.h + +dom/js/fdlibm/k_rem_pio2.o: \ + dom/js/fdlibm/k_rem_pio2.c \ + dom/js/fdlibm/fdlibm.h + +dom/js/fdlibm/k_sin.o: \ + dom/js/fdlibm/k_sin.c \ + dom/js/fdlibm/fdlibm.h + +dom/js/fdlibm/k_standard.o: \ + dom/js/fdlibm/k_standard.c \ + dom/js/fdlibm/fdlibm.h + +dom/js/fdlibm/k_tan.o: \ + dom/js/fdlibm/k_tan.c \ + dom/js/fdlibm/fdlibm.h + +dom/js/fdlibm/s_asinh.o: \ + dom/js/fdlibm/s_asinh.c \ + dom/js/fdlibm/fdlibm.h + +dom/js/fdlibm/s_atan.o: \ + dom/js/fdlibm/s_atan.c \ + dom/js/fdlibm/fdlibm.h + +dom/js/fdlibm/s_cbrt.o: \ + dom/js/fdlibm/s_cbrt.c \ + dom/js/fdlibm/fdlibm.h + +dom/js/fdlibm/s_ceil.o: \ + dom/js/fdlibm/s_ceil.c \ + dom/js/fdlibm/fdlibm.h + +dom/js/fdlibm/s_copysign.o: \ + dom/js/fdlibm/s_copysign.c \ + dom/js/fdlibm/fdlibm.h + +dom/js/fdlibm/s_cos.o: \ + dom/js/fdlibm/s_cos.c \ + dom/js/fdlibm/fdlibm.h + +dom/js/fdlibm/s_erf.o: \ + dom/js/fdlibm/s_erf.c \ + dom/js/fdlibm/fdlibm.h + +dom/js/fdlibm/s_expm1.o: \ + dom/js/fdlibm/s_expm1.c \ + dom/js/fdlibm/fdlibm.h + +dom/js/fdlibm/s_fabs.o: \ + dom/js/fdlibm/s_fabs.c \ + dom/js/fdlibm/fdlibm.h + +dom/js/fdlibm/s_finite.o: \ + dom/js/fdlibm/s_finite.c \ + dom/js/fdlibm/fdlibm.h + +dom/js/fdlibm/s_floor.o: \ + dom/js/fdlibm/s_floor.c \ + dom/js/fdlibm/fdlibm.h + +dom/js/fdlibm/s_frexp.o: \ + dom/js/fdlibm/s_frexp.c \ + dom/js/fdlibm/fdlibm.h + +dom/js/fdlibm/s_ilogb.o: \ + dom/js/fdlibm/s_ilogb.c \ + dom/js/fdlibm/fdlibm.h + +dom/js/fdlibm/s_isnan.o: \ + dom/js/fdlibm/s_isnan.c \ + dom/js/fdlibm/fdlibm.h + +dom/js/fdlibm/s_ldexp.o: \ + dom/js/fdlibm/s_ldexp.c \ + dom/js/fdlibm/fdlibm.h + +dom/js/fdlibm/s_lib_version.o: \ + dom/js/fdlibm/s_lib_version.c \ + dom/js/fdlibm/fdlibm.h + +dom/js/fdlibm/s_log1p.o: \ + dom/js/fdlibm/s_log1p.c \ + dom/js/fdlibm/fdlibm.h + +dom/js/fdlibm/s_logb.o: \ + dom/js/fdlibm/s_logb.c \ + dom/js/fdlibm/fdlibm.h + +dom/js/fdlibm/s_matherr.o: \ + dom/js/fdlibm/s_matherr.c \ + dom/js/fdlibm/fdlibm.h + +dom/js/fdlibm/s_modf.o: \ + dom/js/fdlibm/s_modf.c \ + dom/js/fdlibm/fdlibm.h + +dom/js/fdlibm/s_nextafter.o: \ + dom/js/fdlibm/s_nextafter.c \ + dom/js/fdlibm/fdlibm.h + +dom/js/fdlibm/s_rint.o: \ + dom/js/fdlibm/s_rint.c \ + dom/js/fdlibm/fdlibm.h + +dom/js/fdlibm/s_scalbn.o: \ + dom/js/fdlibm/s_scalbn.c \ + dom/js/fdlibm/fdlibm.h + +dom/js/fdlibm/s_signgam.o: \ + dom/js/fdlibm/s_signgam.c \ + dom/js/fdlibm/fdlibm.h + +dom/js/fdlibm/s_significand.o: \ + dom/js/fdlibm/s_significand.c \ + dom/js/fdlibm/fdlibm.h + +dom/js/fdlibm/s_sin.o: \ + dom/js/fdlibm/s_sin.c \ + dom/js/fdlibm/fdlibm.h + +dom/js/fdlibm/s_tan.o: \ + dom/js/fdlibm/s_tan.c \ + dom/js/fdlibm/fdlibm.h + +dom/js/fdlibm/s_tanh.o: \ + dom/js/fdlibm/s_tanh.c \ + dom/js/fdlibm/fdlibm.h + +dom/js/fdlibm/w_acos.o: \ + dom/js/fdlibm/w_acos.c \ + dom/js/fdlibm/fdlibm.h + +dom/js/fdlibm/w_acosh.o: \ + dom/js/fdlibm/w_acosh.c \ + dom/js/fdlibm/fdlibm.h + +dom/js/fdlibm/w_asin.o: \ + dom/js/fdlibm/w_asin.c \ + dom/js/fdlibm/fdlibm.h + +dom/js/fdlibm/w_atan2.o: \ + dom/js/fdlibm/w_atan2.c \ + dom/js/fdlibm/fdlibm.h + +dom/js/fdlibm/w_atanh.o: \ + dom/js/fdlibm/w_atanh.c \ + dom/js/fdlibm/fdlibm.h + +dom/js/fdlibm/w_cosh.o: \ + dom/js/fdlibm/w_cosh.c \ + dom/js/fdlibm/fdlibm.h + +dom/js/fdlibm/w_exp.o: \ + dom/js/fdlibm/w_exp.c \ + dom/js/fdlibm/fdlibm.h + +dom/js/fdlibm/w_fmod.o: \ + dom/js/fdlibm/w_fmod.c \ + dom/js/fdlibm/fdlibm.h + +dom/js/fdlibm/w_gamma.o: \ + dom/js/fdlibm/w_gamma.c \ + dom/js/fdlibm/fdlibm.h + +dom/js/fdlibm/w_gamma_r.o: \ + dom/js/fdlibm/w_gamma_r.c \ + dom/js/fdlibm/fdlibm.h + +dom/js/fdlibm/w_hypot.o: \ + dom/js/fdlibm/w_hypot.c \ + dom/js/fdlibm/fdlibm.h + +dom/js/fdlibm/w_j0.o: \ + dom/js/fdlibm/w_j0.c \ + dom/js/fdlibm/fdlibm.h + +dom/js/fdlibm/w_j1.o: \ + dom/js/fdlibm/w_j1.c \ + dom/js/fdlibm/fdlibm.h + +dom/js/fdlibm/w_jn.o: \ + dom/js/fdlibm/w_jn.c \ + dom/js/fdlibm/fdlibm.h + +dom/js/fdlibm/w_lgamma.o: \ + dom/js/fdlibm/w_lgamma.c \ + dom/js/fdlibm/fdlibm.h + +dom/js/fdlibm/w_lgamma_r.o: \ + dom/js/fdlibm/w_lgamma_r.c \ + dom/js/fdlibm/fdlibm.h + +dom/js/fdlibm/w_log.o: \ + dom/js/fdlibm/w_log.c \ + dom/js/fdlibm/fdlibm.h + +dom/js/fdlibm/w_log10.o: \ + dom/js/fdlibm/w_log10.c \ + dom/js/fdlibm/fdlibm.h + +dom/js/fdlibm/w_pow.o: \ + dom/js/fdlibm/w_pow.c \ + dom/js/fdlibm/fdlibm.h + +dom/js/fdlibm/w_remainder.o: \ + dom/js/fdlibm/w_remainder.c \ + dom/js/fdlibm/fdlibm.h + +dom/js/fdlibm/w_scalb.o: \ + dom/js/fdlibm/w_scalb.c \ + dom/js/fdlibm/fdlibm.h + +dom/js/fdlibm/w_sinh.o: \ + dom/js/fdlibm/w_sinh.c \ + dom/js/fdlibm/fdlibm.h + +dom/js/fdlibm/w_sqrt.o: \ + dom/js/fdlibm/w_sqrt.c \ + dom/js/fdlibm/fdlibm.h + +dom/js/js.o: \ + dom/js/js.c \ + dom/js/jsapi.h \ + dom/js/jsarena.h \ + dom/js/jsatom.h \ + dom/js/jsautocfg.h \ + dom/js/jsclist.h \ + dom/js/jscntxt.h \ + dom/js/jscompat.h \ + dom/js/jsconfig.h \ + dom/js/jscpucfg.h \ + dom/js/jsdbgapi.h \ + dom/js/jsdhash.h \ + dom/js/jsemit.h \ + dom/js/jsfun.h \ + dom/js/jsgc.h \ + dom/js/jshash.h \ + dom/js/jsinterp.h \ + dom/js/jslock.h \ + dom/js/jslong.h \ + dom/js/jsobj.h \ + dom/js/jsopcode.h \ + dom/js/jsosdep.h \ + dom/js/jsotypes.h \ + dom/js/jsparse.h \ + dom/js/jsprf.h \ + dom/js/jsprvtd.h \ + dom/js/jspubtd.h \ + dom/js/jsregexp.h \ + dom/js/jsscan.h \ + dom/js/jsscope.h \ + dom/js/jsscript.h \ + dom/js/jsstddef.h \ + dom/js/jsstr.h \ + dom/js/jstypes.h \ + dom/js/jsutil.h + +dom/js/jsapi.o: \ + dom/js/jsapi.c \ + dom/js/jsapi.h \ + dom/js/jsarena.h \ + dom/js/jsarray.h \ + dom/js/jsatom.h \ + dom/js/jsautocfg.h \ + dom/js/jsbool.h \ + dom/js/jsclist.h \ + dom/js/jscntxt.h \ + dom/js/jscompat.h \ + dom/js/jsconfig.h \ + dom/js/jscpucfg.h \ + dom/js/jsdate.h \ + dom/js/jsdhash.h \ + dom/js/jsdtoa.h \ + dom/js/jsemit.h \ + dom/js/jsexn.h \ + dom/js/jsfile.h \ + dom/js/jsfun.h \ + dom/js/jsgc.h \ + dom/js/jshash.h \ + dom/js/jsinterp.h \ + dom/js/jslock.h \ + dom/js/jslong.h \ + dom/js/jsmath.h \ + dom/js/jsnum.h \ + dom/js/jsobj.h \ + dom/js/jsopcode.h \ + dom/js/jsosdep.h \ + dom/js/jsotypes.h \ + dom/js/jsparse.h \ + dom/js/jsprf.h \ + dom/js/jsprvtd.h \ + dom/js/jspubtd.h \ + dom/js/jsregexp.h \ + dom/js/jsscan.h \ + dom/js/jsscope.h \ + dom/js/jsscript.h \ + dom/js/jsstddef.h \ + dom/js/jsstr.h \ + dom/js/jstypes.h \ + dom/js/jsutil.h \ + dom/js/prmjtime.h + +dom/js/jsarena.o: \ + dom/js/jsarena.c \ + dom/js/jsarena.h \ + dom/js/jsautocfg.h \ + dom/js/jsbit.h \ + dom/js/jscompat.h \ + dom/js/jscpucfg.h \ + dom/js/jshash.h \ + dom/js/jslock.h \ + dom/js/jslong.h \ + dom/js/jsobj.h \ + dom/js/jsosdep.h \ + dom/js/jsotypes.h \ + dom/js/jsprvtd.h \ + dom/js/jspubtd.h \ + dom/js/jsscope.h \ + dom/js/jsstddef.h \ + dom/js/jstypes.h \ + dom/js/jsutil.h + +dom/js/jsarray.o: \ + dom/js/jsarray.c \ + dom/js/jsapi.h \ + dom/js/jsarena.h \ + dom/js/jsarray.h \ + dom/js/jsatom.h \ + dom/js/jsautocfg.h \ + dom/js/jsclist.h \ + dom/js/jscntxt.h \ + dom/js/jscompat.h \ + dom/js/jsconfig.h \ + dom/js/jscpucfg.h \ + dom/js/jsdhash.h \ + dom/js/jsfun.h \ + dom/js/jsgc.h \ + dom/js/jshash.h \ + dom/js/jsinterp.h \ + dom/js/jslock.h \ + dom/js/jslong.h \ + dom/js/jsnum.h \ + dom/js/jsobj.h \ + dom/js/jsosdep.h \ + dom/js/jsotypes.h \ + dom/js/jsprvtd.h \ + dom/js/jspubtd.h \ + dom/js/jsregexp.h \ + dom/js/jsscope.h \ + dom/js/jsstddef.h \ + dom/js/jsstr.h \ + dom/js/jstypes.h \ + dom/js/jsutil.h + +dom/js/jsatom.o: \ + dom/js/jsatom.c \ + dom/js/jsapi.h \ + dom/js/jsarena.h \ + dom/js/jsatom.h \ + dom/js/jsautocfg.h \ + dom/js/jsclist.h \ + dom/js/jscntxt.h \ + dom/js/jscompat.h \ + dom/js/jsconfig.h \ + dom/js/jscpucfg.h \ + dom/js/jsdhash.h \ + dom/js/jsgc.h \ + dom/js/jshash.h \ + dom/js/jsinterp.h \ + dom/js/jslock.h \ + dom/js/jslong.h \ + dom/js/jsnum.h \ + dom/js/jsobj.h \ + dom/js/jsopcode.h \ + dom/js/jsosdep.h \ + dom/js/jsotypes.h \ + dom/js/jsprf.h \ + dom/js/jsprvtd.h \ + dom/js/jspubtd.h \ + dom/js/jsregexp.h \ + dom/js/jsscope.h \ + dom/js/jsstddef.h \ + dom/js/jsstr.h \ + dom/js/jstypes.h \ + dom/js/jsutil.h + +dom/js/jsbool.o: \ + dom/js/jsbool.c \ + dom/js/jsapi.h \ + dom/js/jsarena.h \ + dom/js/jsatom.h \ + dom/js/jsautocfg.h \ + dom/js/jsbool.h \ + dom/js/jsclist.h \ + dom/js/jscntxt.h \ + dom/js/jscompat.h \ + dom/js/jsconfig.h \ + dom/js/jscpucfg.h \ + dom/js/jsdhash.h \ + dom/js/jsgc.h \ + dom/js/jshash.h \ + dom/js/jsinterp.h \ + dom/js/jslock.h \ + dom/js/jslong.h \ + dom/js/jsnum.h \ + dom/js/jsobj.h \ + dom/js/jsosdep.h \ + dom/js/jsotypes.h \ + dom/js/jsprf.h \ + dom/js/jsprvtd.h \ + dom/js/jspubtd.h \ + dom/js/jsregexp.h \ + dom/js/jsscope.h \ + dom/js/jsstddef.h \ + dom/js/jsstr.h \ + dom/js/jstypes.h \ + dom/js/jsutil.h + +dom/js/jscntxt.o: \ + dom/js/jscntxt.c \ + dom/js/jsapi.h \ + dom/js/jsarena.h \ + dom/js/jsatom.h \ + dom/js/jsautocfg.h \ + dom/js/jsclist.h \ + dom/js/jscntxt.h \ + dom/js/jscompat.h \ + dom/js/jsconfig.h \ + dom/js/jscpucfg.h \ + dom/js/jsdbgapi.h \ + dom/js/jsdhash.h \ + dom/js/jsexn.h \ + dom/js/jsgc.h \ + dom/js/jshash.h \ + dom/js/jsinterp.h \ + dom/js/jslock.h \ + dom/js/jslong.h \ + dom/js/jsnum.h \ + dom/js/jsobj.h \ + dom/js/jsopcode.h \ + dom/js/jsosdep.h \ + dom/js/jsotypes.h \ + dom/js/jsprf.h \ + dom/js/jsprvtd.h \ + dom/js/jspubtd.h \ + dom/js/jsregexp.h \ + dom/js/jsscan.h \ + dom/js/jsscope.h \ + dom/js/jsscript.h \ + dom/js/jsstddef.h \ + dom/js/jsstr.h \ + dom/js/jstypes.h \ + dom/js/jsutil.h + +dom/js/jscpucfg.o: \ + dom/js/jscpucfg.c + +dom/js/jsdate.o: \ + dom/js/jsdate.c \ + dom/js/jsapi.h \ + dom/js/jsarena.h \ + dom/js/jsatom.h \ + dom/js/jsautocfg.h \ + dom/js/jsclist.h \ + dom/js/jscntxt.h \ + dom/js/jscompat.h \ + dom/js/jsconfig.h \ + dom/js/jscpucfg.h \ + dom/js/jsdate.h \ + dom/js/jsdhash.h \ + dom/js/jsdtoa.h \ + dom/js/jsgc.h \ + dom/js/jshash.h \ + dom/js/jsinterp.h \ + dom/js/jslock.h \ + dom/js/jslong.h \ + dom/js/jsnum.h \ + dom/js/jsobj.h \ + dom/js/jsosdep.h \ + dom/js/jsotypes.h \ + dom/js/jsprf.h \ + dom/js/jsprvtd.h \ + dom/js/jspubtd.h \ + dom/js/jsregexp.h \ + dom/js/jsscope.h \ + dom/js/jsstddef.h \ + dom/js/jsstr.h \ + dom/js/jstypes.h \ + dom/js/jsutil.h \ + dom/js/prmjtime.h + +dom/js/jsdbgapi.o: \ + dom/js/jsdbgapi.c \ + dom/js/jsapi.h \ + dom/js/jsarena.h \ + dom/js/jsatom.h \ + dom/js/jsautocfg.h \ + dom/js/jsclist.h \ + dom/js/jscntxt.h \ + dom/js/jscompat.h \ + dom/js/jsconfig.h \ + dom/js/jscpucfg.h \ + dom/js/jsdbgapi.h \ + dom/js/jsdhash.h \ + dom/js/jsemit.h \ + dom/js/jsfun.h \ + dom/js/jsgc.h \ + dom/js/jshash.h \ + dom/js/jsinterp.h \ + dom/js/jslock.h \ + dom/js/jslong.h \ + dom/js/jsobj.h \ + dom/js/jsopcode.h \ + dom/js/jsosdep.h \ + dom/js/jsotypes.h \ + dom/js/jsprvtd.h \ + dom/js/jspubtd.h \ + dom/js/jsregexp.h \ + dom/js/jsscope.h \ + dom/js/jsscript.h \ + dom/js/jsstddef.h \ + dom/js/jsstr.h \ + dom/js/jstypes.h \ + dom/js/jsutil.h + +dom/js/jsdhash.o: \ + dom/js/jsdhash.c \ + dom/js/jsautocfg.h \ + dom/js/jsbit.h \ + dom/js/jscpucfg.h \ + dom/js/jsdhash.h \ + dom/js/jsosdep.h \ + dom/js/jsotypes.h \ + dom/js/jstypes.h \ + dom/js/jsutil.h + +dom/js/jsdtoa.o: \ + dom/js/jsdtoa.c \ + dom/js/jsautocfg.h \ + dom/js/jscompat.h \ + dom/js/jsconfig.h \ + dom/js/jscpucfg.h \ + dom/js/jsdtoa.h \ + dom/js/jslibmath.h \ + dom/js/jslong.h \ + dom/js/jsnum.h \ + dom/js/jsosdep.h \ + dom/js/jsotypes.h \ + dom/js/jsprf.h \ + dom/js/jspubtd.h \ + dom/js/jsstddef.h \ + dom/js/jstypes.h \ + dom/js/jsutil.h + +dom/js/jsemit.o: \ + dom/js/jsemit.c \ + dom/js/jsapi.h \ + dom/js/jsarena.h \ + dom/js/jsatom.h \ + dom/js/jsautocfg.h \ + dom/js/jsbit.h \ + dom/js/jsclist.h \ + dom/js/jscntxt.h \ + dom/js/jscompat.h \ + dom/js/jsconfig.h \ + dom/js/jscpucfg.h \ + dom/js/jsdhash.h \ + dom/js/jsemit.h \ + dom/js/jsfun.h \ + dom/js/jsgc.h \ + dom/js/jshash.h \ + dom/js/jsinterp.h \ + dom/js/jslock.h \ + dom/js/jslong.h \ + dom/js/jsnum.h \ + dom/js/jsobj.h \ + dom/js/jsopcode.h \ + dom/js/jsosdep.h \ + dom/js/jsotypes.h \ + dom/js/jsparse.h \ + dom/js/jsprf.h \ + dom/js/jsprvtd.h \ + dom/js/jspubtd.h \ + dom/js/jsregexp.h \ + dom/js/jsscan.h \ + dom/js/jsscope.h \ + dom/js/jsscript.h \ + dom/js/jsstddef.h \ + dom/js/jsstr.h \ + dom/js/jstypes.h \ + dom/js/jsutil.h \ + ui/dialog/dialog.h \ + ui/dialog/memory.h + +dom/js/jsexn.o: \ + dom/js/jsexn.c \ + dom/js/jsapi.h \ + dom/js/jsarena.h \ + dom/js/jsatom.h \ + dom/js/jsautocfg.h \ + dom/js/jsbit.h \ + dom/js/jsclist.h \ + dom/js/jscntxt.h \ + dom/js/jscompat.h \ + dom/js/jsconfig.h \ + dom/js/jscpucfg.h \ + dom/js/jsdhash.h \ + dom/js/jsexn.h \ + dom/js/jsfun.h \ + dom/js/jsgc.h \ + dom/js/jshash.h \ + dom/js/jsinterp.h \ + dom/js/jslock.h \ + dom/js/jslong.h \ + dom/js/jsnum.h \ + dom/js/jsobj.h \ + dom/js/jsopcode.h \ + dom/js/jsosdep.h \ + dom/js/jsotypes.h \ + dom/js/jsprf.h \ + dom/js/jsprvtd.h \ + dom/js/jspubtd.h \ + dom/js/jsregexp.h \ + dom/js/jsscope.h \ + dom/js/jsscript.h \ + dom/js/jsstddef.h \ + dom/js/jsstr.h \ + dom/js/jstypes.h \ + dom/js/jsutil.h + +dom/js/jsfile.o: \ + dom/js/jsfile.c \ + dom/js/jsapi.h \ + dom/js/jsarena.h \ + dom/js/jsatom.h \ + dom/js/jsautocfg.h \ + dom/js/jsclist.h \ + dom/js/jscntxt.h \ + dom/js/jscompat.h \ + dom/js/jsconfig.h \ + dom/js/jscpucfg.h \ + dom/js/jsdate.h \ + dom/js/jsdbgapi.h \ + dom/js/jsdhash.h \ + dom/js/jsemit.h \ + dom/js/jsfun.h \ + dom/js/jsgc.h \ + dom/js/jshash.h \ + dom/js/jsinterp.h \ + dom/js/jslock.h \ + dom/js/jslong.h \ + dom/js/jsobj.h \ + dom/js/jsopcode.h \ + dom/js/jsosdep.h \ + dom/js/jsotypes.h \ + dom/js/jsparse.h \ + dom/js/jsprvtd.h \ + dom/js/jspubtd.h \ + dom/js/jsregexp.h \ + dom/js/jsscan.h \ + dom/js/jsscope.h \ + dom/js/jsscript.h \ + dom/js/jsstddef.h \ + dom/js/jsstr.h \ + dom/js/jstypes.h \ + dom/js/jsutil.h + +dom/js/jsfun.o: \ + dom/js/jsfun.c \ + dom/js/jsapi.h \ + dom/js/jsarena.h \ + dom/js/jsarray.h \ + dom/js/jsatom.h \ + dom/js/jsautocfg.h \ + dom/js/jsbit.h \ + dom/js/jsclist.h \ + dom/js/jscntxt.h \ + dom/js/jscompat.h \ + dom/js/jsconfig.h \ + dom/js/jscpucfg.h \ + dom/js/jsdbgapi.h \ + dom/js/jsdhash.h \ + dom/js/jsexn.h \ + dom/js/jsfun.h \ + dom/js/jsgc.h \ + dom/js/jshash.h \ + dom/js/jsinterp.h \ + dom/js/jslock.h \ + dom/js/jslong.h \ + dom/js/jsnum.h \ + dom/js/jsobj.h \ + dom/js/jsopcode.h \ + dom/js/jsosdep.h \ + dom/js/jsotypes.h \ + dom/js/jsparse.h \ + dom/js/jsprvtd.h \ + dom/js/jspubtd.h \ + dom/js/jsregexp.h \ + dom/js/jsscan.h \ + dom/js/jsscope.h \ + dom/js/jsscript.h \ + dom/js/jsstddef.h \ + dom/js/jsstr.h \ + dom/js/jstypes.h \ + dom/js/jsutil.h \ + dom/js/jsxdrapi.h + +dom/js/jsgc.o: \ + dom/js/jsgc.c \ + dom/js/jsapi.h \ + dom/js/jsarena.h \ + dom/js/jsatom.h \ + dom/js/jsautocfg.h \ + dom/js/jsclist.h \ + dom/js/jscntxt.h \ + dom/js/jscompat.h \ + dom/js/jsconfig.h \ + dom/js/jscpucfg.h \ + dom/js/jsdbgapi.h \ + dom/js/jsdhash.h \ + dom/js/jsfun.h \ + dom/js/jsgc.h \ + dom/js/jshash.h \ + dom/js/jsinterp.h \ + dom/js/jslock.h \ + dom/js/jslong.h \ + dom/js/jsnum.h \ + dom/js/jsobj.h \ + dom/js/jsopcode.h \ + dom/js/jsosdep.h \ + dom/js/jsotypes.h \ + dom/js/jsprf.h \ + dom/js/jsprvtd.h \ + dom/js/jspubtd.h \ + dom/js/jsregexp.h \ + dom/js/jsscope.h \ + dom/js/jsscript.h \ + dom/js/jsstddef.h \ + dom/js/jsstr.h \ + dom/js/jstypes.h \ + dom/js/jsutil.h + +dom/js/jshash.o: \ + dom/js/jshash.c \ + dom/js/jsautocfg.h \ + dom/js/jsbit.h \ + dom/js/jscompat.h \ + dom/js/jscpucfg.h \ + dom/js/jshash.h \ + dom/js/jslong.h \ + dom/js/jsosdep.h \ + dom/js/jsotypes.h \ + dom/js/jsstddef.h \ + dom/js/jstypes.h \ + dom/js/jsutil.h + +dom/js/jsinterp.o: \ + dom/js/jsinterp.c \ + dom/js/jsapi.h \ + dom/js/jsarena.h \ + dom/js/jsarray.h \ + dom/js/jsatom.h \ + dom/js/jsautocfg.h \ + dom/js/jsbool.h \ + dom/js/jsclist.h \ + dom/js/jscntxt.h \ + dom/js/jscompat.h \ + dom/js/jsconfig.h \ + dom/js/jscpucfg.h \ + dom/js/jsdbgapi.h \ + dom/js/jsdhash.h \ + dom/js/jsfun.h \ + dom/js/jsgc.h \ + dom/js/jshash.h \ + dom/js/jsinterp.h \ + dom/js/jslock.h \ + dom/js/jslong.h \ + dom/js/jsnum.h \ + dom/js/jsobj.h \ + dom/js/jsopcode.h \ + dom/js/jsosdep.h \ + dom/js/jsotypes.h \ + dom/js/jsprf.h \ + dom/js/jsprvtd.h \ + dom/js/jspubtd.h \ + dom/js/jsregexp.h \ + dom/js/jsscope.h \ + dom/js/jsscript.h \ + dom/js/jsstddef.h \ + dom/js/jsstr.h \ + dom/js/jstypes.h \ + dom/js/jsutil.h + +dom/js/jslock.o: \ + dom/js/jslock.c \ + dom/js/jsapi.h \ + dom/js/jsarena.h \ + dom/js/jsatom.h \ + dom/js/jsautocfg.h \ + dom/js/jsbit.h \ + dom/js/jsclist.h \ + dom/js/jscntxt.h \ + dom/js/jscompat.h \ + dom/js/jsconfig.h \ + dom/js/jscpucfg.h \ + dom/js/jsdhash.h \ + dom/js/jsdtoa.h \ + dom/js/jsgc.h \ + dom/js/jshash.h \ + dom/js/jsinterp.h \ + dom/js/jslock.h \ + dom/js/jslong.h \ + dom/js/jsobj.h \ + dom/js/jsosdep.h \ + dom/js/jsotypes.h \ + dom/js/jsprvtd.h \ + dom/js/jspubtd.h \ + dom/js/jsregexp.h \ + dom/js/jsscope.h \ + dom/js/jsstddef.h \ + dom/js/jsstr.h \ + dom/js/jstypes.h \ + dom/js/jsutil.h \ + ui/dialog/dialog.h \ + ui/dialog/memory.h + +dom/js/jslog2.o: \ + dom/js/jslog2.c \ + dom/js/jsautocfg.h \ + dom/js/jsbit.h \ + dom/js/jscpucfg.h \ + dom/js/jsosdep.h \ + dom/js/jsotypes.h \ + dom/js/jsstddef.h \ + dom/js/jstypes.h + +dom/js/jslong.o: \ + dom/js/jslong.c \ + dom/js/jsautocfg.h \ + dom/js/jscpucfg.h \ + dom/js/jslong.h \ + dom/js/jsosdep.h \ + dom/js/jsotypes.h \ + dom/js/jsstddef.h \ + dom/js/jstypes.h + +dom/js/jsmath.o: \ + dom/js/jsmath.c \ + dom/js/jsapi.h \ + dom/js/jsarena.h \ + dom/js/jsatom.h \ + dom/js/jsautocfg.h \ + dom/js/jsclist.h \ + dom/js/jscntxt.h \ + dom/js/jscompat.h \ + dom/js/jsconfig.h \ + dom/js/jscpucfg.h \ + dom/js/jsdhash.h \ + dom/js/jsgc.h \ + dom/js/jshash.h \ + dom/js/jsinterp.h \ + dom/js/jslibmath.h \ + dom/js/jslock.h \ + dom/js/jslong.h \ + dom/js/jsmath.h \ + dom/js/jsnum.h \ + dom/js/jsobj.h \ + dom/js/jsosdep.h \ + dom/js/jsotypes.h \ + dom/js/jsprvtd.h \ + dom/js/jspubtd.h \ + dom/js/jsregexp.h \ + dom/js/jsscope.h \ + dom/js/jsstddef.h \ + dom/js/jsstr.h \ + dom/js/jstypes.h \ + dom/js/prmjtime.h + +dom/js/jsnum.o: \ + dom/js/jsnum.c \ + dom/js/jsapi.h \ + dom/js/jsarena.h \ + dom/js/jsatom.h \ + dom/js/jsautocfg.h \ + dom/js/jsclist.h \ + dom/js/jscntxt.h \ + dom/js/jscompat.h \ + dom/js/jsconfig.h \ + dom/js/jscpucfg.h \ + dom/js/jsdhash.h \ + dom/js/jsdtoa.h \ + dom/js/jsgc.h \ + dom/js/jshash.h \ + dom/js/jsinterp.h \ + dom/js/jslock.h \ + dom/js/jslong.h \ + dom/js/jsnum.h \ + dom/js/jsobj.h \ + dom/js/jsopcode.h \ + dom/js/jsosdep.h \ + dom/js/jsotypes.h \ + dom/js/jsprf.h \ + dom/js/jsprvtd.h \ + dom/js/jspubtd.h \ + dom/js/jsregexp.h \ + dom/js/jsscope.h \ + dom/js/jsstddef.h \ + dom/js/jsstr.h \ + dom/js/jstypes.h \ + dom/js/jsutil.h + +dom/js/jsobj.o: \ + dom/js/jsobj.c \ + dom/js/jsapi.h \ + dom/js/jsarena.h \ + dom/js/jsarray.h \ + dom/js/jsatom.h \ + dom/js/jsautocfg.h \ + dom/js/jsbool.h \ + dom/js/jsclist.h \ + dom/js/jscntxt.h \ + dom/js/jscompat.h \ + dom/js/jsconfig.h \ + dom/js/jscpucfg.h \ + dom/js/jsdbgapi.h \ + dom/js/jsdhash.h \ + dom/js/jsfun.h \ + dom/js/jsgc.h \ + dom/js/jshash.h \ + dom/js/jsinterp.h \ + dom/js/jslock.h \ + dom/js/jslong.h \ + dom/js/jsnum.h \ + dom/js/jsobj.h \ + dom/js/jsopcode.h \ + dom/js/jsosdep.h \ + dom/js/jsotypes.h \ + dom/js/jsprf.h \ + dom/js/jsprvtd.h \ + dom/js/jspubtd.h \ + dom/js/jsregexp.h \ + dom/js/jsscope.h \ + dom/js/jsscript.h \ + dom/js/jsstddef.h \ + dom/js/jsstr.h \ + dom/js/jstypes.h \ + dom/js/jsutil.h \ + dom/js/jsxdrapi.h + +dom/js/jsopcode.o: \ + dom/js/jsopcode.c \ + dom/js/jsapi.h \ + dom/js/jsarena.h \ + dom/js/jsarray.h \ + dom/js/jsatom.h \ + dom/js/jsautocfg.h \ + dom/js/jsclist.h \ + dom/js/jscntxt.h \ + dom/js/jscompat.h \ + dom/js/jsconfig.h \ + dom/js/jscpucfg.h \ + dom/js/jsdbgapi.h \ + dom/js/jsdhash.h \ + dom/js/jsdtoa.h \ + dom/js/jsemit.h \ + dom/js/jsfun.h \ + dom/js/jsgc.h \ + dom/js/jshash.h \ + dom/js/jsinterp.h \ + dom/js/jslock.h \ + dom/js/jslong.h \ + dom/js/jsobj.h \ + dom/js/jsopcode.h \ + dom/js/jsosdep.h \ + dom/js/jsotypes.h \ + dom/js/jsprf.h \ + dom/js/jsprvtd.h \ + dom/js/jspubtd.h \ + dom/js/jsregexp.h \ + dom/js/jsscope.h \ + dom/js/jsscript.h \ + dom/js/jsstddef.h \ + dom/js/jsstr.h \ + dom/js/jstypes.h \ + dom/js/jsutil.h \ + ui/dialog/dialog.h \ + ui/dialog/memory.h + +dom/js/jsparse.o: \ + dom/js/jsparse.c \ + dom/js/jsapi.h \ + dom/js/jsarena.h \ + dom/js/jsatom.h \ + dom/js/jsautocfg.h \ + dom/js/jsclist.h \ + dom/js/jscntxt.h \ + dom/js/jscompat.h \ + dom/js/jsconfig.h \ + dom/js/jscpucfg.h \ + dom/js/jsdhash.h \ + dom/js/jsemit.h \ + dom/js/jsfun.h \ + dom/js/jsgc.h \ + dom/js/jshash.h \ + dom/js/jsinterp.h \ + dom/js/jslock.h \ + dom/js/jslong.h \ + dom/js/jsnum.h \ + dom/js/jsobj.h \ + dom/js/jsopcode.h \ + dom/js/jsosdep.h \ + dom/js/jsotypes.h \ + dom/js/jsparse.h \ + dom/js/jsprvtd.h \ + dom/js/jspubtd.h \ + dom/js/jsregexp.h \ + dom/js/jsscan.h \ + dom/js/jsscope.h \ + dom/js/jsscript.h \ + dom/js/jsstddef.h \ + dom/js/jsstr.h \ + dom/js/jstypes.h \ + dom/js/jsutil.h + +dom/js/jsprf.o: \ + dom/js/jsprf.c \ + dom/js/jsautocfg.h \ + dom/js/jscpucfg.h \ + dom/js/jslong.h \ + dom/js/jsosdep.h \ + dom/js/jsotypes.h \ + dom/js/jsprf.h \ + dom/js/jsstddef.h \ + dom/js/jstypes.h \ + dom/js/jsutil.h + +dom/js/jsregexp.o: \ + dom/js/jsregexp.c \ + dom/js/jsapi.h \ + dom/js/jsarena.h \ + dom/js/jsarray.h \ + dom/js/jsatom.h \ + dom/js/jsautocfg.h \ + dom/js/jsclist.h \ + dom/js/jscntxt.h \ + dom/js/jscompat.h \ + dom/js/jsconfig.h \ + dom/js/jscpucfg.h \ + dom/js/jsdhash.h \ + dom/js/jsfun.h \ + dom/js/jsgc.h \ + dom/js/jshash.h \ + dom/js/jsinterp.h \ + dom/js/jslock.h \ + dom/js/jslong.h \ + dom/js/jsnum.h \ + dom/js/jsobj.h \ + dom/js/jsopcode.h \ + dom/js/jsosdep.h \ + dom/js/jsotypes.h \ + dom/js/jsprvtd.h \ + dom/js/jspubtd.h \ + dom/js/jsregexp.h \ + dom/js/jsscan.h \ + dom/js/jsscope.h \ + dom/js/jsstddef.h \ + dom/js/jsstr.h \ + dom/js/jstypes.h \ + dom/js/jsutil.h \ + dom/js/jsxdrapi.h + +dom/js/jsscan.o: \ + dom/js/jsscan.c \ + dom/js/jsapi.h \ + dom/js/jsarena.h \ + dom/js/jsatom.h \ + dom/js/jsautocfg.h \ + dom/js/jsclist.h \ + dom/js/jscntxt.h \ + dom/js/jscompat.h \ + dom/js/jsconfig.h \ + dom/js/jscpucfg.h \ + dom/js/jsdhash.h \ + dom/js/jsdtoa.h \ + dom/js/jsemit.h \ + dom/js/jsexn.h \ + dom/js/jsgc.h \ + dom/js/jshash.h \ + dom/js/jsinterp.h \ + dom/js/jslock.h \ + dom/js/jslong.h \ + dom/js/jsnum.h \ + dom/js/jsobj.h \ + dom/js/jsopcode.h \ + dom/js/jsosdep.h \ + dom/js/jsotypes.h \ + dom/js/jsprf.h \ + dom/js/jsprvtd.h \ + dom/js/jspubtd.h \ + dom/js/jsregexp.h \ + dom/js/jsscan.h \ + dom/js/jsscope.h \ + dom/js/jsstddef.h \ + dom/js/jsstr.h \ + dom/js/jstypes.h \ + dom/js/jsutil.h \ + ui/dialog/dialog.h \ + ui/dialog/memory.h + +dom/js/jsscope.o: \ + dom/js/jsscope.c \ + dom/js/jsapi.h \ + dom/js/jsarena.h \ + dom/js/jsatom.h \ + dom/js/jsautocfg.h \ + dom/js/jsbit.h \ + dom/js/jsclist.h \ + dom/js/jscntxt.h \ + dom/js/jscompat.h \ + dom/js/jsconfig.h \ + dom/js/jscpucfg.h \ + dom/js/jsdbgapi.h \ + dom/js/jsdhash.h \ + dom/js/jsgc.h \ + dom/js/jshash.h \ + dom/js/jsinterp.h \ + dom/js/jslock.h \ + dom/js/jslong.h \ + dom/js/jsnum.h \ + dom/js/jsobj.h \ + dom/js/jsopcode.h \ + dom/js/jsosdep.h \ + dom/js/jsotypes.h \ + dom/js/jsprvtd.h \ + dom/js/jspubtd.h \ + dom/js/jsregexp.h \ + dom/js/jsscope.h \ + dom/js/jsstddef.h \ + dom/js/jsstr.h \ + dom/js/jstypes.h \ + dom/js/jsutil.h + +dom/js/jsscript.o: \ + dom/js/jsscript.c \ + dom/js/jsapi.h \ + dom/js/jsarena.h \ + dom/js/jsatom.h \ + dom/js/jsautocfg.h \ + dom/js/jsclist.h \ + dom/js/jscntxt.h \ + dom/js/jscompat.h \ + dom/js/jsconfig.h \ + dom/js/jscpucfg.h \ + dom/js/jsdbgapi.h \ + dom/js/jsdhash.h \ + dom/js/jsemit.h \ + dom/js/jsfun.h \ + dom/js/jsgc.h \ + dom/js/jshash.h \ + dom/js/jsinterp.h \ + dom/js/jslock.h \ + dom/js/jslong.h \ + dom/js/jsnum.h \ + dom/js/jsobj.h \ + dom/js/jsopcode.h \ + dom/js/jsosdep.h \ + dom/js/jsotypes.h \ + dom/js/jsprf.h \ + dom/js/jsprvtd.h \ + dom/js/jspubtd.h \ + dom/js/jsregexp.h \ + dom/js/jsscope.h \ + dom/js/jsscript.h \ + dom/js/jsstddef.h \ + dom/js/jsstr.h \ + dom/js/jstypes.h \ + dom/js/jsutil.h \ + dom/js/jsxdrapi.h + +dom/js/jsstr.o: \ + dom/js/jsstr.c \ + dom/js/jsapi.h \ + dom/js/jsarena.h \ + dom/js/jsarray.h \ + dom/js/jsatom.h \ + dom/js/jsautocfg.h \ + dom/js/jsbool.h \ + dom/js/jsclist.h \ + dom/js/jscntxt.h \ + dom/js/jscompat.h \ + dom/js/jsconfig.h \ + dom/js/jscpucfg.h \ + dom/js/jsdhash.h \ + dom/js/jsgc.h \ + dom/js/jshash.h \ + dom/js/jsinterp.h \ + dom/js/jslock.h \ + dom/js/jslong.h \ + dom/js/jsnum.h \ + dom/js/jsobj.h \ + dom/js/jsopcode.h \ + dom/js/jsosdep.h \ + dom/js/jsotypes.h \ + dom/js/jsprf.h \ + dom/js/jsprvtd.h \ + dom/js/jspubtd.h \ + dom/js/jsregexp.h \ + dom/js/jsscope.h \ + dom/js/jsstddef.h \ + dom/js/jsstr.h \ + dom/js/jstypes.h \ + dom/js/jsutil.h + +dom/js/jsutil.o: \ + dom/js/jsutil.c \ + dom/js/jsautocfg.h \ + dom/js/jscpucfg.h \ + dom/js/jsosdep.h \ + dom/js/jsotypes.h \ + dom/js/jsprf.h \ + dom/js/jsstddef.h \ + dom/js/jstypes.h \ + dom/js/jsutil.h + +dom/js/jsxdrapi.o: \ + dom/js/jsxdrapi.c \ + dom/js/jsapi.h \ + dom/js/jsarena.h \ + dom/js/jsatom.h \ + dom/js/jsautocfg.h \ + dom/js/jsclist.h \ + dom/js/jscntxt.h \ + dom/js/jscompat.h \ + dom/js/jsconfig.h \ + dom/js/jscpucfg.h \ + dom/js/jsdhash.h \ + dom/js/jsgc.h \ + dom/js/jshash.h \ + dom/js/jsinterp.h \ + dom/js/jslock.h \ + dom/js/jslong.h \ + dom/js/jsobj.h \ + dom/js/jsosdep.h \ + dom/js/jsotypes.h \ + dom/js/jsprf.h \ + dom/js/jsprvtd.h \ + dom/js/jspubtd.h \ + dom/js/jsregexp.h \ + dom/js/jsscope.h \ + dom/js/jsscript.h \ + dom/js/jsstddef.h \ + dom/js/jsstr.h \ + dom/js/jstypes.h \ + dom/js/jsutil.h \ + dom/js/jsxdrapi.h + +dom/js/prmjtime.o: \ + dom/js/prmjtime.c \ + dom/js/jsautocfg.h \ + dom/js/jscompat.h \ + dom/js/jscpucfg.h \ + dom/js/jslong.h \ + dom/js/jsosdep.h \ + dom/js/jsotypes.h \ + dom/js/jsprf.h \ + dom/js/jsstddef.h \ + dom/js/jstypes.h \ + dom/js/jsutil.h \ + dom/js/prmjtime.h \ + extension/extension-forward.h \ + extension/timer.h + +dom/lsimpl.o: \ + dom/lsimpl.cpp \ + dom/dom.h \ + dom/domimpl.h \ + dom/domstream.h \ + dom/domstring.h \ + dom/events.h \ + dom/ls.h \ + dom/lsimpl.h \ + dom/traversal.h \ + dom/views.h \ + dom/xmlreader.h + +dom/prop-css.o: \ + dom/prop-css.cpp + +dom/prop-css2.o: \ + dom/prop-css2.cpp + +dom/prop-svg.o: \ + dom/prop-svg.cpp + +dom/smilimpl.o: \ + dom/smilimpl.cpp \ + dom/dom.h \ + dom/domimpl.h \ + dom/domstring.h \ + dom/events.h \ + dom/smil.h \ + dom/smilimpl.h \ + dom/views.h + +dom/stringstream.o: \ + dom/stringstream.cpp \ + dom/dom.h \ + dom/domstream.h \ + dom/domstring.h \ + dom/stringstream.h + +dom/svgimpl.o: \ + dom/svgimpl.cpp \ + dom/css.h \ + dom/dom.h \ + dom/domimpl.h \ + dom/domstring.h \ + dom/events.h \ + dom/smil.h \ + dom/smilimpl.h \ + dom/stylesheets.h \ + dom/svg.h \ + dom/svgimpl.h \ + dom/svgtypes.h \ + dom/views.h + +dom/svglsimpl.o: \ + dom/svglsimpl.cpp \ + dom/css.h \ + dom/dom.h \ + dom/domimpl.h \ + dom/domstream.h \ + dom/domstring.h \ + dom/events.h \ + dom/ls.h \ + dom/lsimpl.h \ + dom/smil.h \ + dom/smilimpl.h \ + dom/stylesheets.h \ + dom/svg.h \ + dom/svgimpl.h \ + dom/svglsimpl.h \ + dom/svgparser.h \ + dom/svgtypes.h \ + dom/traversal.h \ + dom/views.h \ + dom/xmlreader.h + +dom/svgparser.o: \ + dom/svgparser.cpp \ + dom/charclass.h \ + dom/css.h \ + dom/cssparser.h \ + dom/dom.h \ + dom/domimpl.h \ + dom/domstring.h \ + dom/events.h \ + dom/smil.h \ + dom/smilimpl.h \ + dom/stylesheets.h \ + dom/svg.h \ + dom/svgimpl.h \ + dom/svgparser.h \ + dom/svgtypes.h \ + dom/views.h + +dom/uri.o: \ + dom/uri.cpp \ + dom/dom.h \ + dom/domstring.h \ + dom/uri.h + +dom/uristream.o: \ + dom/uristream.cpp \ + dom/dom.h \ + dom/domstream.h \ + dom/domstring.h \ + dom/uri.h \ + dom/uristream.h + +dom/uritest.o: \ + dom/uritest.cpp \ + dom/dom.h \ + dom/domstream.h \ + dom/domstring.h \ + dom/uri.h \ + dom/uristream.h + +dom/xmlreader.o: \ + dom/xmlreader.cpp \ + dom/css.h \ + dom/dom.h \ + dom/domimpl.h \ + dom/domstring.h \ + dom/events.h \ + dom/smil.h \ + dom/smilimpl.h \ + dom/stylesheets.h \ + dom/svg.h \ + dom/svgimpl.h \ + dom/svgtypes.h \ + dom/views.h \ + dom/xmlreader.h + +dom/xpathimpl.o: \ + dom/xpathimpl.cpp \ + dom/dom.h \ + dom/domimpl.h \ + dom/domstring.h \ + dom/xpath.h \ + dom/xpathimpl.h + +dom/xpathparser.o: \ + dom/xpathparser.cpp \ + dom/charclass.h \ + dom/dom.h \ + dom/domstring.h \ + dom/xpathparser.h + +draw-anchor.o: \ + draw-anchor.cpp \ + decimal-round.h \ + desktop-handles.h \ + desktop.h \ + display/display-forward.h \ + display/sodipodi-ctrl.h \ + display/sp-canvas.h \ + draw-anchor.h \ + event-context.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + message.h \ + round.h \ + ui/view/edit-widget-interface.h \ + ui/view/view.h + +draw-context.o: \ + draw-context.cpp \ + decimal-round.h \ + desktop-affine.h \ + desktop-handles.h \ + desktop-style.h \ + desktop.h \ + display/canvas-bpath.h \ + display/curve.h \ + display/display-forward.h \ + display/nr-arena-forward.h \ + display/sp-canvas.h \ + document.h \ + dom/css.h \ + dom/dom.h \ + dom/domstring.h \ + dom/events.h \ + dom/smil.h \ + dom/stylesheets.h \ + dom/svg.h \ + dom/svgtypes.h \ + dom/views.h \ + draw-anchor.h \ + draw-context.h \ + event-context.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libavoid/connector.h \ + libavoid/geometry.h \ + libavoid/geomtypes.h \ + libavoid/shape.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/n-art-bpath.h \ + libnr/nr-convex-hull.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-path-code.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + macros.h \ + message-stack.h \ + message.h \ + pen-context.h \ + prefs-utils.h \ + round.h \ + selection-chemistry.h \ + selection.h \ + snap.h \ + snapped-point.h \ + snapper.h \ + sp-conn-end-pair.h \ + sp-item.h \ + sp-marker-loc.h \ + sp-object.h \ + sp-path.h \ + sp-shape.h \ + traits/reference.h \ + ui/view/edit-widget-interface.h \ + ui/view/view.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +dropper-context.o: \ + dropper-context.cpp \ + color-rgba.h \ + color.h \ + decimal-round.h \ + desktop-handles.h \ + desktop-style.h \ + desktop.h \ + display/canvas-arena.h \ + display/canvas-bpath.h \ + display/curve.h \ + display/display-forward.h \ + display/nr-arena-forward.h \ + display/nr-arena-item.h \ + display/sp-canvas.h \ + document.h \ + dom/css.h \ + dom/dom.h \ + dom/domstring.h \ + dom/events.h \ + dom/smil.h \ + dom/stylesheets.h \ + dom/svg.h \ + dom/svgtypes.h \ + dom/views.h \ + dropper-context.h \ + event-context.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + grid-snapper.h \ + guide-snapper.h \ + helper/helper-forward.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/n-art-bpath.h \ + libnr/nr-convex-hull.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-object.h \ + libnr/nr-path-code.h \ + libnr/nr-pixblock.h \ + libnr/nr-pixops.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale-translate-ops.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + line-snapper.h \ + macros.h \ + message-context.h \ + message.h \ + object-snapper.h \ + prefs-utils.h \ + round.h \ + selection.h \ + snapped-point.h \ + snapper.h \ + sp-metric.h \ + sp-namedview.h \ + sp-object-group.h \ + sp-object.h \ + traits/reference.h \ + ui/view/edit-widget-interface.h \ + ui/view/view.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h + +dyna-draw-context.o: \ + dyna-draw-context.cpp \ + context-fns.h \ + decimal-round.h \ + desktop-affine.h \ + desktop-events.h \ + desktop-handles.h \ + desktop-style.h \ + desktop.h \ + display/bezier-utils.h \ + display/canvas-bpath.h \ + display/curve.h \ + display/display-forward.h \ + display/nr-arena-forward.h \ + display/sp-canvas.h \ + document.h \ + dom/css.h \ + dom/dom.h \ + dom/domstring.h \ + dom/events.h \ + dom/smil.h \ + dom/stylesheets.h \ + dom/svg.h \ + dom/svgtypes.h \ + dom/views.h \ + dyna-draw-context.h \ + event-context.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/n-art-bpath.h \ + libnr/nr-convex-hull.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-path-code.h \ + libnr/nr-path.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + macros.h \ + message-context.h \ + message.h \ + round.h \ + selection.h \ + sp-item.h \ + sp-object.h \ + traits/reference.h \ + ui/view/edit-widget-interface.h \ + ui/view/view.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +event-context.o: \ + event-context.cpp \ + attributes.h \ + decimal-round.h \ + desktop-handles.h \ + desktop.h \ + display/display-forward.h \ + display/sp-canvas.h \ + event-context.h \ + extension/extension-forward.h \ + file.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + gradient-drag.h \ + interface.h \ + knot-enums.h \ + knotholder.h \ + libnr/nr-convex-hull.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + macros.h \ + message-context.h \ + message.h \ + object-edit.h \ + prefs-utils.h \ + round.h \ + rubberband.h \ + selcue.h \ + selection.h \ + shortcuts.h \ + sp-cursor.h \ + tools-switch.h \ + traits/reference.h \ + ui/view/edit-widget-interface.h \ + ui/view/view.h \ + util/list.h \ + xml/node-event-vector.h \ + xml/node.h + +extension/db.o: \ + extension/db.cpp \ + dialogs/input.h \ + document.h \ + extension/db.h \ + extension/effect.h \ + extension/extension-forward.h \ + extension/extension.h \ + extension/output.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + helper/helper-forward.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-forward.h \ + require-config.h \ + traits/reference.h \ + util/list.h \ + verbs.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +extension/dependency.o: \ + extension/dependency.cpp \ + document.h \ + extension/db.h \ + extension/dependency.h \ + extension/extension-forward.h \ + extension/extension.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-forward.h \ + path-prefix.h \ + prefix.h \ + require-config.h \ + traits/reference.h \ + util/list.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +extension/effect.o: \ + extension/effect.cpp \ + decimal-round.h \ + document.h \ + extension/effect.h \ + extension/extension-forward.h \ + extension/extension.h \ + extension/implementation/implementation.h \ + extension/prefdialog.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + helper/action.h \ + helper/helper-forward.h \ + inkscape-private.h \ + inkscape.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-object.h \ + libnr/nr-point.h \ + message.h \ + require-config.h \ + round.h \ + traits/reference.h \ + ui/dialog/dialog.h \ + ui/view/view.h \ + util/list.h \ + verbs.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +extension/error-file.o: \ + extension/error-file.cpp \ + dialogs/extensions.h \ + document.h \ + extension/error-file.h \ + extension/extension-forward.h \ + extension/extension.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + inkscape.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-forward.h \ + prefs-utils.h \ + traits/reference.h \ + ui/previewable.h \ + ui/previewfillable.h \ + ui/widget/button.h \ + ui/widget/panel.h \ + util/list.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +extension/extension.o: \ + extension/extension.cpp \ + decimal-round.h \ + document.h \ + extension/db.h \ + extension/dependency.h \ + extension/extension-forward.h \ + extension/extension.h \ + extension/implementation/implementation.h \ + extension/parameter.h \ + extension/timer.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + inkscape.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-point.h \ + round.h \ + traits/reference.h \ + util/list.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +extension/implementation/implementation.o: \ + extension/implementation/implementation.cpp \ + decimal-round.h \ + dialogs/input.h \ + document.h \ + extension/effect.h \ + extension/extension-forward.h \ + extension/extension.h \ + extension/implementation/implementation.h \ + extension/output.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + helper/helper-forward.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-point.h \ + require-config.h \ + round.h \ + traits/reference.h \ + util/list.h \ + verbs.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +extension/implementation/plugin.o: \ + extension/implementation/plugin.cpp \ + decimal-round.h \ + document.h \ + extension/extension-forward.h \ + extension/extension.h \ + extension/implementation/implementation.h \ + extension/implementation/plugin-link.h \ + extension/implementation/plugin.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-point.h \ + path-prefix.h \ + prefix.h \ + require-config.h \ + round.h \ + traits/reference.h \ + util/list.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +extension/implementation/script.o: \ + extension/implementation/script.cpp \ + decimal-round.h \ + desktop-handles.h \ + display/display-forward.h \ + document.h \ + extension/db.h \ + extension/effect.h \ + extension/extension-forward.h \ + extension/extension.h \ + extension/implementation/implementation.h \ + extension/implementation/script.h \ + extension/system.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + grid-snapper.h \ + guide-snapper.h \ + helper/helper-forward.h \ + io/sys.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-convex-hull.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + line-snapper.h \ + message.h \ + object-snapper.h \ + prefs-utils.h \ + require-config.h \ + round.h \ + selection.h \ + snapped-point.h \ + snapper.h \ + sp-metric.h \ + sp-namedview.h \ + sp-object-group.h \ + sp-object.h \ + traits/reference.h \ + ui/view/view.h \ + util/forward-pointer-iterator.h \ + util/glib-list-iterators.h \ + util/list.h \ + verbs.h \ + version.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +extension/init.o: \ + extension/init.cpp \ + decimal-round.h \ + document.h \ + dom/css.h \ + dom/dom.h \ + dom/domstream.h \ + dom/domstring.h \ + dom/events.h \ + dom/smil.h \ + dom/stringstream.h \ + dom/stylesheets.h \ + dom/svg.h \ + dom/svgtypes.h \ + dom/views.h \ + extension/db.h \ + extension/extension-forward.h \ + extension/extension.h \ + extension/implementation/implementation.h \ + extension/internal/bluredge.h \ + extension/internal/eps-out.h \ + extension/internal/gdkpixbuf-input.h \ + extension/internal/gimpgrad.h \ + extension/internal/gnome.h \ + extension/internal/grid.h \ + extension/internal/latex-pstricks-out.h \ + extension/internal/latex-pstricks.h \ + extension/internal/pov-out.h \ + extension/internal/ps-out.h \ + extension/internal/ps.h \ + extension/internal/svgz.h \ + extension/internal/win32.h \ + extension/system.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + inkscape.h \ + io/sys.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-path.h \ + libnr/nr-point.h \ + path-prefix.h \ + prefix.h \ + prefs-utils.h \ + require-config.h \ + round.h \ + traits/reference.h \ + util/list.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +extension/input.o: \ + extension/input.cpp \ + dialogs/dialog-events.h \ + document.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + helper/helper-forward.h \ + inkscape.h \ + interface.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-forward.h \ + macros.h \ + prefs-utils.h \ + require-config.h \ + traits/reference.h \ + util/list.h \ + verbs.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +extension/internal/bluredge.o: \ + extension/internal/bluredge.cpp \ + decimal-round.h \ + desktop.h \ + display/nr-arena-forward.h \ + document.h \ + extension/effect.h \ + extension/extension-forward.h \ + extension/extension.h \ + extension/implementation/implementation.h \ + extension/internal/bluredge.h \ + extension/system.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + helper/action.h \ + helper/helper-forward.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-convex-hull.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-object.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + message.h \ + path-chemistry.h \ + prefs-utils.h \ + require-config.h \ + round.h \ + selection.h \ + sp-item.h \ + sp-object.h \ + traits/reference.h \ + ui/view/edit-widget-interface.h \ + ui/view/view.h \ + util/forward-pointer-iterator.h \ + util/glib-list-iterators.h \ + util/list.h \ + verbs.h \ + version.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +extension/internal/eps-out.o: \ + extension/internal/eps-out.cpp \ + decimal-round.h \ + display/nr-arena-forward.h \ + document.h \ + extension/db.h \ + extension/extension-forward.h \ + extension/extension.h \ + extension/implementation/implementation.h \ + extension/internal/eps-out.h \ + extension/output.h \ + extension/print.h \ + extension/system.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-path.h \ + libnr/nr-point.h \ + round.h \ + traits/reference.h \ + util/list.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +extension/internal/gdkpixbuf-input.o: \ + extension/internal/gdkpixbuf-input.cpp \ + composite-undo-stack-observer.h \ + decimal-round.h \ + dir-util.h \ + display/nr-arena-forward.h \ + document-private.h \ + document.h \ + enums.h \ + extension/extension-forward.h \ + extension/extension.h \ + extension/implementation/implementation.h \ + extension/internal/gdkpixbuf-input.h \ + extension/system.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + prefs-utils.h \ + round.h \ + sp-defs.h \ + sp-item-group.h \ + sp-item.h \ + sp-object.h \ + sp-root.h \ + svg/svg-length.h \ + traits/reference.h \ + undo-stack-observer.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/event-fns.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +extension/internal/gimpgrad.o: \ + extension/internal/gimpgrad.cpp \ + color-rgba.h \ + decimal-round.h \ + document.h \ + extension/extension-forward.h \ + extension/extension.h \ + extension/implementation/implementation.h \ + extension/internal/gimpgrad.h \ + extension/system.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + io/sys.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-pixops.h \ + libnr/nr-point.h \ + round.h \ + traits/reference.h \ + util/list.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +extension/internal/grid.o: \ + extension/internal/grid.cpp \ + decimal-round.h \ + desktop.h \ + document.h \ + extension/effect.h \ + extension/extension-forward.h \ + extension/extension.h \ + extension/implementation/implementation.h \ + extension/internal/grid.h \ + extension/system.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + helper/helper-forward.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-convex-hull.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + message.h \ + require-config.h \ + round.h \ + selection.h \ + sp-object.h \ + traits/reference.h \ + ui/view/edit-widget-interface.h \ + ui/view/view.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + verbs.h \ + version.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +extension/internal/latex-pstricks-out.o: \ + extension/internal/latex-pstricks-out.cpp \ + decimal-round.h \ + display/display-forward.h \ + display/nr-arena-forward.h \ + display/nr-arena-item.h \ + display/nr-arena.h \ + document.h \ + extension/db.h \ + extension/extension-forward.h \ + extension/extension.h \ + extension/implementation/implementation.h \ + extension/internal/latex-pstricks-out.h \ + extension/print.h \ + extension/system.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libavoid/connector.h \ + libavoid/geometry.h \ + libavoid/geomtypes.h \ + libavoid/shape.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-object.h \ + libnr/nr-path.h \ + libnr/nr-pixblock.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + round.h \ + sp-conn-end-pair.h \ + sp-item.h \ + sp-marker-loc.h \ + sp-object.h \ + sp-paint-server.h \ + sp-path.h \ + sp-shape.h \ + traits/reference.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +extension/internal/latex-pstricks.o: \ + extension/internal/latex-pstricks.cpp \ + color.h \ + decimal-round.h \ + display/nr-arena-forward.h \ + document.h \ + dom/dom.h \ + dom/domstream.h \ + dom/domstring.h \ + dom/stringstream.h \ + extension/extension-forward.h \ + extension/extension.h \ + extension/implementation/implementation.h \ + extension/internal/latex-pstricks.h \ + extension/print.h \ + extension/system.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + io/sys.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/n-art-bpath.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-path-code.h \ + libnr/nr-path.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + round.h \ + sp-item.h \ + sp-marker-loc.h \ + sp-object.h \ + style.h \ + traits/reference.h \ + unit-constants.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +extension/internal/pov-out.o: \ + extension/internal/pov-out.cpp \ + color.h \ + decimal-round.h \ + display/curve.h \ + display/display-forward.h \ + display/nr-arena-forward.h \ + document.h \ + extension/extension-forward.h \ + extension/extension.h \ + extension/implementation/implementation.h \ + extension/internal/pov-out.h \ + extension/system.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + inkscape.h \ + io/sys.h \ + libavoid/connector.h \ + libavoid/geometry.h \ + libavoid/geomtypes.h \ + libavoid/shape.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/n-art-bpath.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-path-code.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + round.h \ + sp-conn-end-pair.h \ + sp-item.h \ + sp-marker-loc.h \ + sp-object.h \ + sp-path.h \ + sp-shape.h \ + style.h \ + traits/reference.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +extension/internal/ps-out.o: \ + extension/internal/ps-out.cpp \ + decimal-round.h \ + display/nr-arena-forward.h \ + document.h \ + extension/db.h \ + extension/extension-forward.h \ + extension/extension.h \ + extension/implementation/implementation.h \ + extension/internal/ps-out.h \ + extension/output.h \ + extension/print.h \ + extension/system.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-path.h \ + libnr/nr-point.h \ + round.h \ + traits/reference.h \ + util/list.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +extension/internal/ps.o: \ + extension/internal/ps.cpp \ + color.h \ + decimal-round.h \ + display/canvas-bpath.h \ + display/nr-arena-forward.h \ + display/nr-arena-item.h \ + display/sp-canvas.h \ + document.h \ + dom/dom.h \ + dom/domstream.h \ + dom/domstring.h \ + dom/stringstream.h \ + extension/extension-forward.h \ + extension/extension.h \ + extension/implementation/implementation.h \ + extension/internal/ps.h \ + extension/print.h \ + extension/system.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + io/sys.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/n-art-bpath.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-object.h \ + libnr/nr-path-code.h \ + libnr/nr-path.h \ + libnr/nr-pixblock.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + libnrtype/FontFactory.h \ + libnrtype/font-instance.h \ + libnrtype/font-style-to-pos.h \ + libnrtype/font-style.h \ + libnrtype/nr-type-pos-def.h \ + libnrtype/nr-type-primitives.h \ + libnrtype/nrtype-forward.h \ + livarot/LivarotDefs.h \ + livarot/livarot-forward.h \ + require-config.h \ + round.h \ + sp-gradient-fns.h \ + sp-gradient-spread.h \ + sp-gradient-units.h \ + sp-gradient-vector.h \ + sp-gradient.h \ + sp-item.h \ + sp-linear-gradient-fns.h \ + sp-linear-gradient.h \ + sp-marker-loc.h \ + sp-object.h \ + sp-paint-server.h \ + sp-radial-gradient-fns.h \ + sp-radial-gradient.h \ + style.h \ + svg/svg-length.h \ + traits/reference.h \ + unit-constants.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +extension/internal/svg.o: \ + extension/internal/svg.cpp \ + document.h \ + dom/css.h \ + dom/dom.h \ + dom/domstring.h \ + dom/events.h \ + dom/smil.h \ + dom/stylesheets.h \ + dom/svg.h \ + dom/svgtypes.h \ + dom/views.h \ + extension/extension-forward.h \ + extension/extension.h \ + extension/output.h \ + extension/system.h \ + file.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-forward.h \ + sp-object.h \ + traits/reference.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +extension/internal/svgz.o: \ + extension/internal/svgz.cpp \ + document.h \ + dom/css.h \ + dom/dom.h \ + dom/domstring.h \ + dom/events.h \ + dom/smil.h \ + dom/stylesheets.h \ + dom/svg.h \ + dom/svgtypes.h \ + dom/views.h \ + extension/extension-forward.h \ + extension/extension.h \ + extension/internal/svgz.h \ + extension/system.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-forward.h \ + traits/reference.h \ + util/list.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +extension/internal/win32.o: \ + extension/internal/win32.cpp \ + decimal-round.h \ + display/nr-arena-forward.h \ + display/nr-arena-item.h \ + display/nr-arena.h \ + document.h \ + extension/extension-forward.h \ + extension/extension.h \ + extension/implementation/implementation.h \ + extension/internal/win32.h \ + extension/print.h \ + extension/system.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-object.h \ + libnr/nr-path.h \ + libnr/nr-pixblock.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + round.h \ + sp-object.h \ + sp-paint-server.h \ + traits/reference.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +extension/output.o: \ + extension/output.cpp \ + decimal-round.h \ + document.h \ + extension/extension-forward.h \ + extension/extension.h \ + extension/implementation/implementation.h \ + extension/output.h \ + extension/prefdialog.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-point.h \ + round.h \ + traits/reference.h \ + ui/dialog/dialog.h \ + util/list.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +extension/parameter.o: \ + extension/parameter.cpp \ + document.h \ + extension/extension-forward.h \ + extension/extension.h \ + extension/parameter.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-forward.h \ + prefs-utils.h \ + traits/reference.h \ + util/list.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +extension/prefdialog.o: \ + extension/prefdialog.cpp \ + dialogs/dialog-events.h \ + extension/prefdialog.h \ + forward.h \ + ui/dialog/dialog.h \ + ui/stock.h + +extension/print.o: \ + extension/print.cpp \ + decimal-round.h \ + display/nr-arena-forward.h \ + document.h \ + extension/extension-forward.h \ + extension/extension.h \ + extension/implementation/implementation.h \ + extension/print.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-path.h \ + libnr/nr-point.h \ + round.h \ + traits/reference.h \ + util/list.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +extension/script/InkscapeBinding.o: \ + extension/script/InkscapeBinding.cpp \ + extension/script/InkscapeBinding.h \ + help.h + +extension/script/InkscapeInterpreter.o: \ + extension/script/InkscapeInterpreter.cpp \ + extension/script/InkscapeInterpreter.h + +extension/script/InkscapePerl.o: \ + extension/script/InkscapePerl.cpp \ + extension/script/InkscapeInterpreter.h \ + extension/script/InkscapePerl.h \ + extension/script/inkscape_perl.pm.h + +extension/script/InkscapePython.o: \ + extension/script/InkscapePython.cpp \ + extension/script/InkscapeInterpreter.h \ + extension/script/InkscapePython.h \ + extension/script/inkscape_py.py.h + +extension/script/InkscapeScript.o: \ + extension/script/InkscapeScript.cpp \ + extension/script/InkscapeInterpreter.h \ + extension/script/InkscapePerl.h \ + extension/script/InkscapePython.h \ + extension/script/InkscapeScript.h + +extension/script/inkscape_perl_wrap.o: \ + extension/script/inkscape_perl_wrap.cpp \ + extension/script/InkscapeBinding.h + +extension/script/inkscape_py_wrap.o: \ + extension/script/inkscape_py_wrap.cpp \ + extension/script/InkscapeBinding.h + +extension/system.o: \ + extension/system.cpp \ + decimal-round.h \ + dialogs/input.h \ + display/nr-arena-forward.h \ + document.h \ + extension/db.h \ + extension/effect.h \ + extension/extension-forward.h \ + extension/extension.h \ + extension/implementation/implementation.h \ + extension/implementation/script.h \ + extension/output.h \ + extension/print.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + helper/helper-forward.h \ + interface.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-path.h \ + libnr/nr-point.h \ + require-config.h \ + round.h \ + traits/reference.h \ + util/list.h \ + verbs.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +extension/timer.o: \ + extension/timer.cpp \ + document.h \ + extension/extension-forward.h \ + extension/extension.h \ + extension/timer.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-forward.h \ + traits/reference.h \ + util/list.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +extract-uri.o: \ + extract-uri.cpp + +file.o: \ + file.cpp \ + application/app-prototype.h \ + application/application.h \ + application/editor.h \ + color.h \ + composite-undo-stack-observer.h \ + decimal-round.h \ + desktop-handles.h \ + desktop.h \ + dialogs/export.h \ + dialogs/filedialog.h \ + dialogs/input.h \ + dir-util.h \ + display/display-forward.h \ + display/nr-arena-forward.h \ + display/nr-arena-item.h \ + display/nr-arena.h \ + document-private.h \ + document.h \ + dom/dom.h \ + dom/domstring.h \ + dom/uri.h \ + enums.h \ + extension/db.h \ + extension/extension-forward.h \ + extension/extension.h \ + extension/output.h \ + extension/print.h \ + extension/system.h \ + file.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + grid-snapper.h \ + guide-snapper.h \ + helper/helper-forward.h \ + helper/png-write.h \ + inkscape.h \ + interface.h \ + io/sys.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-convex-hull.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-object.h \ + libnr/nr-path.h \ + libnr/nr-pixblock.h \ + libnr/nr-pixops.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + line-snapper.h \ + message-stack.h \ + message.h \ + object-snapper.h \ + path-prefix.h \ + prefix.h \ + prefs-utils.h \ + require-config.h \ + round.h \ + selection-chemistry.h \ + selection.h \ + snapped-point.h \ + snapper.h \ + sp-defs.h \ + sp-item-group.h \ + sp-item.h \ + sp-marker-loc.h \ + sp-metric.h \ + sp-namedview.h \ + sp-object-group.h \ + sp-object.h \ + sp-paint-server.h \ + sp-root.h \ + style.h \ + svg/svg-length.h \ + traits/reference.h \ + ui/view/edit-widget-interface.h \ + ui/view/view-widget.h \ + ui/view/view.h \ + undo-stack-observer.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/event-fns.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +fixes.o: \ + fixes.cpp + +fontsize-expansion.o: \ + fontsize-expansion.cpp \ + decimal-round.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-ops.h \ + libnr/nr-matrix.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + round.h + +gc-anchored.o: \ + gc-anchored.cpp \ + gc-anchored.h \ + gc-core.h \ + gc-managed.h + +gc.o: \ + gc.cpp \ + gc-core.h + +geom.o: \ + geom.cpp \ + decimal-round.h \ + geom.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-macros.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + round.h + +gradient-chemistry.o: \ + gradient-chemistry.cpp \ + bad-uri-exception.h \ + color.h \ + composite-undo-stack-observer.h \ + decimal-round.h \ + desktop-style.h \ + display/nr-arena-forward.h \ + document-private.h \ + document.h \ + dom/css.h \ + dom/dom.h \ + dom/domstring.h \ + dom/events.h \ + dom/smil.h \ + dom/stylesheets.h \ + dom/svg.h \ + dom/svgtypes.h \ + dom/views.h \ + enums.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix-ops.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-pixblock.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate-ops.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + libnrtype/Layout-TNG.h \ + round.h \ + sp-defs.h \ + sp-gradient-fns.h \ + sp-gradient-reference.h \ + sp-gradient-spread.h \ + sp-gradient-units.h \ + sp-gradient-vector.h \ + sp-gradient.h \ + sp-item-group.h \ + sp-item.h \ + sp-linear-gradient-fns.h \ + sp-linear-gradient.h \ + sp-marker-loc.h \ + sp-object.h \ + sp-paint-server.h \ + sp-radial-gradient-fns.h \ + sp-radial-gradient.h \ + sp-root.h \ + sp-stop-fns.h \ + sp-stop.h \ + sp-string.h \ + sp-text.h \ + sp-tspan.h \ + style.h \ + svg/svg-length.h \ + text-tag-attributes.h \ + traits/reference.h \ + undo-stack-observer.h \ + uri-references.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + widgets/gradient-vector.h \ + xml/event-fns.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +gradient-context.o: \ + gradient-context.cpp \ + color.h \ + decimal-round.h \ + desktop-handles.h \ + desktop.h \ + display/display-forward.h \ + display/nr-arena-forward.h \ + document.h \ + event-context.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + gradient-chemistry.h \ + gradient-context.h \ + gradient-drag.h \ + knot-enums.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-convex-hull.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-pixblock.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + macros.h \ + message-context.h \ + message-stack.h \ + message.h \ + prefs-utils.h \ + round.h \ + selection.h \ + sp-gradient-fns.h \ + sp-gradient-spread.h \ + sp-gradient-units.h \ + sp-gradient-vector.h \ + sp-gradient.h \ + sp-item.h \ + sp-object.h \ + sp-paint-server.h \ + traits/reference.h \ + ui/view/edit-widget-interface.h \ + ui/view/view.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +gradient-drag.o: \ + gradient-drag.cpp \ + color.h \ + decimal-round.h \ + desktop-handles.h \ + desktop-style.h \ + desktop.h \ + display/display-forward.h \ + display/nr-arena-forward.h \ + display/sp-canvas.h \ + display/sp-ctrlline.h \ + document.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + gradient-chemistry.h \ + gradient-drag.h \ + knot-enums.h \ + knot.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-convex-hull.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-pixblock.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + message.h \ + prefs-utils.h \ + round.h \ + selection.h \ + sp-gradient-fns.h \ + sp-gradient-spread.h \ + sp-gradient-units.h \ + sp-gradient-vector.h \ + sp-gradient.h \ + sp-item.h \ + sp-linear-gradient-fns.h \ + sp-linear-gradient.h \ + sp-marker-loc.h \ + sp-object.h \ + sp-paint-server.h \ + sp-radial-gradient-fns.h \ + sp-radial-gradient.h \ + style.h \ + svg/svg-length.h \ + traits/reference.h \ + ui/view/edit-widget-interface.h \ + ui/view/view.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +grid-snapper.o: \ + grid-snapper.cpp \ + decimal-round.h \ + display/canvas-grid.h \ + display/sp-canvas.h \ + forward.h \ + grid-snapper.h \ + guide-snapper.h \ + helper/helper-forward.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + line-snapper.h \ + object-snapper.h \ + round.h \ + snapped-point.h \ + snapper.h \ + sp-metric.h \ + sp-namedview.h \ + sp-object-group.h \ + sp-object.h \ + traits/reference.h \ + util/forward-pointer-iterator.h \ + version.h + +guide-snapper.o: \ + guide-snapper.cpp \ + decimal-round.h \ + display/display-forward.h \ + forward.h \ + grid-snapper.h \ + guide-snapper.h \ + helper/helper-forward.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-macros.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-values.h \ + line-snapper.h \ + object-snapper.h \ + round.h \ + snapped-point.h \ + snapper.h \ + sp-guide-attachment.h \ + sp-guide.h \ + sp-metric.h \ + sp-namedview.h \ + sp-object-group.h \ + sp-object.h \ + traits/reference.h \ + util/forward-pointer-iterator.h \ + version.h + +help.o: \ + help.cpp \ + extension/extension-forward.h \ + file.h \ + forward.h \ + help.h \ + path-prefix.h \ + prefix.h \ + require-config.h \ + ui/dialog/aboutbox.h \ + ui/dialog/dialog.h + +helper/action.o: \ + helper/action.cpp \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + helper/action.h \ + helper/helper-forward.h \ + libnr/nr-object.h + +helper/gnome-utils.o: \ + helper/gnome-utils.cpp + +helper/png-write.o: \ + helper/png-write.cpp \ + helper/png-write.h \ + io/sys.h + +helper/sp-marshal.o: \ + helper/sp-marshal.cpp \ + helper/sp-marshal.h + +helper/stock-items.o: \ + helper/stock-items.cpp \ + bad-uri-exception.h \ + composite-undo-stack-observer.h \ + decimal-round.h \ + desktop-handles.h \ + display/display-forward.h \ + display/nr-arena-forward.h \ + document-private.h \ + document.h \ + enums.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + inkscape.h \ + io/sys.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-pixblock.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + path-prefix.h \ + prefix.h \ + require-config.h \ + round.h \ + sp-defs.h \ + sp-gradient-fns.h \ + sp-gradient-spread.h \ + sp-gradient-units.h \ + sp-item-group.h \ + sp-item.h \ + sp-marker-loc.h \ + sp-marker.h \ + sp-object.h \ + sp-paint-server.h \ + sp-pattern.h \ + sp-root.h \ + svg/svg-length.h \ + traits/reference.h \ + undo-stack-observer.h \ + uri-references.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/event-fns.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +helper/unit-menu.o: \ + helper/unit-menu.cpp \ + helper/helper-forward.h \ + helper/sp-marshal.h \ + helper/unit-menu.h \ + helper/units.h \ + sp-metric.h \ + widgets/spw-utilities.h + +helper/units.o: \ + helper/units.cpp \ + helper/units.h \ + sp-metric.h \ + svg/svg-length.h \ + unit-constants.h + +helper/window.o: \ + helper/window.cpp \ + decimal-round.h \ + desktop.h \ + event-context.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + inkscape.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + message.h \ + round.h \ + shortcuts.h \ + ui/view/edit-widget-interface.h \ + ui/view/view.h + +inkjar/jar.o: \ + inkjar/jar.cpp \ + inkjar/jar.h + +inkscape-stock.o: \ + inkscape-stock.cpp + +inkscape.o: \ + inkscape.cpp \ + application/app-prototype.h \ + application/application.h \ + application/editor.h \ + debug/event-tracker.h \ + debug/event.h \ + debug/logger.h \ + debug/simple-event.h \ + decimal-round.h \ + desktop-handles.h \ + desktop.h \ + dialogs/debugdialog.h \ + display/display-forward.h \ + document.h \ + event-context.h \ + extension/extension-forward.h \ + extension/extension.h \ + extension/implementation/implementation.h \ + extension/init.h \ + extension/internal/win32.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + helper/sp-marshal.h \ + inkscape-private.h \ + inkscape.h \ + inkscape_version.h \ + io/sys.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-convex-hull.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + menus-skeleton.h \ + message.h \ + preferences.h \ + prefs-utils.h \ + round.h \ + selection.h \ + traits/reference.h \ + ui/view/edit-widget-interface.h \ + ui/view/view.h \ + util/list.h \ + util/shared-c-string-ptr.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +interface.o: \ + interface.cpp \ + decimal-round.h \ + desktop-handles.h \ + desktop.h \ + dialogs/dialog-events.h \ + display/display-forward.h \ + display/nr-arena-forward.h \ + document.h \ + dom/dom.h \ + dom/domstream.h \ + dom/domstring.h \ + dom/stringstream.h \ + extension/effect.h \ + extension/extension-forward.h \ + extension/extension.h \ + file.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + grid-snapper.h \ + guide-snapper.h \ + helper/action.h \ + helper/gnome-utils.h \ + helper/helper-forward.h \ + helper/window.h \ + inkscape-private.h \ + inkscape.h \ + interface.h \ + io/base64stream.h \ + io/inkscapestream.h \ + io/sys.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-convex-hull.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-object.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + line-snapper.h \ + message-context.h \ + message.h \ + object-snapper.h \ + object-ui.h \ + path-prefix.h \ + prefix.h \ + prefs-utils.h \ + require-config.h \ + round.h \ + selection-chemistry.h \ + selection.h \ + shortcuts.h \ + snapped-point.h \ + snapper.h \ + sp-item-group.h \ + sp-item.h \ + sp-metric.h \ + sp-namedview.h \ + sp-object-group.h \ + sp-object.h \ + svg-view-widget.h \ + traits/reference.h \ + ui/view/edit-widget-interface.h \ + ui/view/view-widget.h \ + ui/view/view.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + verbs.h \ + version.h \ + widgets/desktop-widget.h \ + widgets/icon.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +io/base64stream.o: \ + io/base64stream.cpp \ + io/base64stream.h \ + io/inkscapestream.h + +io/ftos.o: \ + io/ftos.cpp \ + io/ftos.h + +io/gzipstream.o: \ + io/gzipstream.cpp \ + io/gzipstream.h \ + io/inkscapestream.h + +io/inkscapestream.o: \ + io/inkscapestream.cpp \ + io/inkscapestream.h + +io/simple-sax.o: \ + io/simple-sax.cpp \ + io/simple-sax.h + +io/stringstream.o: \ + io/stringstream.cpp \ + dom/dom.h \ + dom/domstream.h \ + dom/domstring.h \ + dom/stringstream.h + +io/sys.o: \ + io/sys.cpp \ + decimal-round.h \ + document.h \ + extension/extension-forward.h \ + extension/extension.h \ + extension/implementation/implementation.h \ + extension/internal/win32.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + io/sys.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-point.h \ + prefs-utils.h \ + round.h \ + traits/reference.h \ + util/list.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +io/uristream.o: \ + io/uristream.cpp \ + dom/dom.h \ + dom/domstream.h \ + dom/domstring.h \ + dom/uri.h \ + dom/uristream.h + +io/xsltstream.o: \ + io/xsltstream.cpp \ + dom/dom.h \ + dom/domstream.h \ + dom/domstring.h \ + dom/stringstream.h \ + io/inkscapestream.h \ + io/xsltstream.h + +knot.o: \ + knot.cpp \ + decimal-round.h \ + desktop-handles.h \ + desktop.h \ + display/display-forward.h \ + display/sodipodi-ctrl.h \ + display/sp-canvas.h \ + document.h \ + event-context.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + helper/sp-marshal.h \ + knot-enums.h \ + knot.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + message-context.h \ + message-stack.h \ + message.h \ + prefs-utils.h \ + round.h \ + ui/view/edit-widget-interface.h \ + ui/view/view.h + +knotholder.o: \ + knotholder.cpp \ + decimal-round.h \ + display/display-forward.h \ + display/nr-arena-forward.h \ + document.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + knot-enums.h \ + knot-holder-entity.h \ + knot.h \ + knotholder.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-div.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + round.h \ + sp-item.h \ + sp-marker-loc.h \ + sp-object.h \ + sp-shape.h \ + traits/reference.h \ + util/forward-pointer-iterator.h \ + version.h + +layer-fns.o: \ + layer-fns.cpp \ + algorithms/find-last-if.h \ + decimal-round.h \ + display/nr-arena-forward.h \ + document.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + round.h \ + sp-item-group.h \ + sp-item.h \ + sp-object.h \ + traits/reference.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +libavoid/connector.o: \ + libavoid/connector.cpp \ + libavoid/connector.h \ + libavoid/debug.h \ + libavoid/geometry.h \ + libavoid/geomtypes.h \ + libavoid/graph.h \ + libavoid/makepath.h \ + libavoid/shape.h \ + libavoid/vertices.h \ + libavoid/visibility.h + +libavoid/geometry.o: \ + libavoid/geometry.cpp \ + libavoid/geometry.h \ + libavoid/geomtypes.h \ + libavoid/graph.h \ + libavoid/polyutil.h \ + libavoid/shape.h \ + libavoid/vertices.h + +libavoid/graph.o: \ + libavoid/graph.cpp \ + extension/extension-forward.h \ + extension/timer.h \ + libavoid/connector.h \ + libavoid/debug.h \ + libavoid/geometry.h \ + libavoid/geomtypes.h \ + libavoid/graph.h \ + libavoid/polyutil.h \ + libavoid/shape.h \ + libavoid/vertices.h + +libavoid/incremental.o: \ + libavoid/incremental.cpp \ + libavoid/connector.h \ + libavoid/geometry.h \ + libavoid/geomtypes.h \ + libavoid/graph.h \ + libavoid/shape.h \ + libavoid/vertices.h \ + libavoid/visibility.h + +libavoid/makepath.o: \ + libavoid/makepath.cpp \ + libavoid/connector.h \ + libavoid/geometry.h \ + libavoid/geomtypes.h \ + libavoid/graph.h \ + libavoid/shape.h \ + libavoid/vertices.h + +libavoid/polyutil.o: \ + libavoid/polyutil.cpp \ + libavoid/geometry.h \ + libavoid/geomtypes.h \ + libavoid/shape.h + +libavoid/shape.o: \ + libavoid/shape.cpp \ + libavoid/geometry.h \ + libavoid/geomtypes.h \ + libavoid/graph.h \ + libavoid/polyutil.h \ + libavoid/shape.h \ + libavoid/vertices.h + +libavoid/static.o: \ + libavoid/static.cpp \ + libavoid/connector.h \ + libavoid/geometry.h \ + libavoid/geomtypes.h \ + libavoid/shape.h \ + libavoid/vertices.h \ + libavoid/visibility.h + +libavoid/timer.o: \ + libavoid/timer.cpp \ + document.h \ + extension/extension-forward.h \ + extension/extension.h \ + extension/timer.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-forward.h \ + traits/reference.h \ + util/list.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +libavoid/vertices.o: \ + libavoid/vertices.cpp \ + libavoid/debug.h \ + libavoid/geometry.h \ + libavoid/geomtypes.h \ + libavoid/graph.h \ + libavoid/vertices.h + +libavoid/visibility.o: \ + libavoid/visibility.cpp \ + libavoid/debug.h \ + libavoid/geometry.h \ + libavoid/geomtypes.h \ + libavoid/graph.h \ + libavoid/shape.h \ + libavoid/vertices.h \ + libavoid/visibility.h + +libcroco/cr-additional-sel.o: \ + libcroco/cr-additional-sel.c \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-string.h \ + libcroco/cr-utils.h + +libcroco/cr-attr-sel.o: \ + libcroco/cr-attr-sel.c \ + libcroco/cr-attr-sel.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-string.h \ + libcroco/cr-utils.h + +libcroco/cr-cascade.o: \ + libcroco/cr-cascade.c \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h + +libcroco/cr-declaration.o: \ + libcroco/cr-declaration.c \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-declaration.h \ + libcroco/cr-doc-handler.h \ + libcroco/cr-input.h \ + libcroco/cr-num.h \ + libcroco/cr-parser.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-tknzr.h \ + libcroco/cr-token.h \ + libcroco/cr-utils.h + +libcroco/cr-doc-handler.o: \ + libcroco/cr-doc-handler.c \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-declaration.h \ + libcroco/cr-doc-handler.h \ + libcroco/cr-input.h \ + libcroco/cr-num.h \ + libcroco/cr-parser.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-tknzr.h \ + libcroco/cr-token.h \ + libcroco/cr-utils.h + +libcroco/cr-enc-handler.o: \ + libcroco/cr-enc-handler.c \ + libcroco/cr-enc-handler.h \ + libcroco/cr-utils.h + +libcroco/cr-fonts.o: \ + libcroco/cr-fonts.c \ + libcroco/cr-fonts.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-utils.h + +libcroco/cr-input.o: \ + libcroco/cr-input.c \ + libcroco/cr-enc-handler.h \ + libcroco/cr-input.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-utils.h + +libcroco/cr-libxml-node-iface.o: \ + libcroco/cr-libxml-node-iface.c \ + libcroco/cr-libxml-node-iface.h \ + libcroco/cr-node-iface.h + +libcroco/cr-num.o: \ + libcroco/cr-num.c \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-utils.h + +libcroco/cr-om-parser.o: \ + libcroco/cr-om-parser.c \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-doc-handler.h \ + libcroco/cr-input.h \ + libcroco/cr-num.h \ + libcroco/cr-om-parser.h \ + libcroco/cr-parser.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-tknzr.h \ + libcroco/cr-token.h \ + libcroco/cr-utils.h + +libcroco/cr-parser.o: \ + libcroco/cr-parser.c \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-declaration.h \ + libcroco/cr-doc-handler.h \ + libcroco/cr-input.h \ + libcroco/cr-num.h \ + libcroco/cr-parser.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-tknzr.h \ + libcroco/cr-token.h \ + libcroco/cr-utils.h + +libcroco/cr-parsing-location.o: \ + libcroco/cr-parsing-location.c \ + libcroco/cr-parsing-location.h \ + libcroco/cr-utils.h + +libcroco/cr-prop-list.o: \ + libcroco/cr-prop-list.c \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-prop-list.h \ + libcroco/cr-rgb.h \ + libcroco/cr-string.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h + +libcroco/cr-pseudo.o: \ + libcroco/cr-pseudo.c \ + libcroco/cr-attr-sel.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-string.h \ + libcroco/cr-utils.h + +libcroco/cr-rgb.o: \ + libcroco/cr-rgb.c \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-declaration.h \ + libcroco/cr-doc-handler.h \ + libcroco/cr-input.h \ + libcroco/cr-num.h \ + libcroco/cr-parser.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-tknzr.h \ + libcroco/cr-token.h \ + libcroco/cr-utils.h + +libcroco/cr-sel-eng.o: \ + libcroco/cr-sel-eng.c \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-fonts.h \ + libcroco/cr-node-iface.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-prop-list.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-sel-eng.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-style.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h + +libcroco/cr-selector.o: \ + libcroco/cr-selector.c \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-declaration.h \ + libcroco/cr-doc-handler.h \ + libcroco/cr-input.h \ + libcroco/cr-num.h \ + libcroco/cr-parser.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-tknzr.h \ + libcroco/cr-token.h \ + libcroco/cr-utils.h + +libcroco/cr-simple-sel.o: \ + libcroco/cr-simple-sel.c \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-string.h \ + libcroco/cr-utils.h + +libcroco/cr-statement.o: \ + libcroco/cr-statement.c \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-declaration.h \ + libcroco/cr-doc-handler.h \ + libcroco/cr-input.h \ + libcroco/cr-num.h \ + libcroco/cr-parser.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-tknzr.h \ + libcroco/cr-token.h \ + libcroco/cr-utils.h + +libcroco/cr-string.o: \ + libcroco/cr-string.c \ + libcroco/cr-parsing-location.h \ + libcroco/cr-string.h \ + libcroco/cr-utils.h + +libcroco/cr-style.o: \ + libcroco/cr-style.c \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-declaration.h \ + libcroco/cr-fonts.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-style.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h + +libcroco/cr-stylesheet.o: \ + libcroco/cr-stylesheet.c \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h + +libcroco/cr-term.o: \ + libcroco/cr-term.c \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-declaration.h \ + libcroco/cr-doc-handler.h \ + libcroco/cr-input.h \ + libcroco/cr-num.h \ + libcroco/cr-parser.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-tknzr.h \ + libcroco/cr-token.h \ + libcroco/cr-utils.h + +libcroco/cr-tknzr.o: \ + libcroco/cr-tknzr.c \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-declaration.h \ + libcroco/cr-doc-handler.h \ + libcroco/cr-input.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-tknzr.h \ + libcroco/cr-token.h \ + libcroco/cr-utils.h + +libcroco/cr-token.o: \ + libcroco/cr-token.c \ + libcroco/cr-input.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-rgb.h \ + libcroco/cr-string.h \ + libcroco/cr-token.h \ + libcroco/cr-utils.h + +libcroco/cr-utils.o: \ + libcroco/cr-utils.c \ + libcroco/cr-parsing-location.h \ + libcroco/cr-string.h \ + libcroco/cr-utils.h + +libnr/nr-blit.o: \ + libnr/nr-blit.cpp \ + decimal-round.h \ + libnr/nr-blit.h \ + libnr/nr-compose.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-pixblock.h \ + libnr/nr-pixops.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + round.h + +libnr/nr-compose-transform.o: \ + libnr/nr-compose-transform.cpp \ + decimal-round.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-pixops.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + round.h + +libnr/nr-compose.o: \ + libnr/nr-compose.cpp \ + libnr/nr-pixops.h + +libnr/nr-gradient.o: \ + libnr/nr-gradient.cpp \ + decimal-round.h \ + libnr/nr-blit.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-gradient.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-pixblock-pixel.h \ + libnr/nr-pixblock.h \ + libnr/nr-pixops.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-render.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + round.h + +libnr/nr-matrix-div.o: \ + libnr/nr-matrix-div.cpp \ + decimal-round.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-ops.h \ + libnr/nr-matrix.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + round.h + +libnr/nr-matrix-fns.o: \ + libnr/nr-matrix-fns.cpp \ + decimal-round.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + round.h + +libnr/nr-matrix-rotate-ops.o: \ + libnr/nr-matrix-rotate-ops.cpp \ + decimal-round.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-ops.h \ + libnr/nr-matrix.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + round.h + +libnr/nr-matrix-scale-ops.o: \ + libnr/nr-matrix-scale-ops.cpp \ + decimal-round.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-ops.h \ + libnr/nr-matrix.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + round.h + +libnr/nr-matrix-translate-ops.o: \ + libnr/nr-matrix-translate-ops.cpp \ + decimal-round.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-ops.h \ + libnr/nr-matrix.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + round.h + +libnr/nr-matrix.o: \ + libnr/nr-matrix.cpp \ + decimal-round.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + round.h + +libnr/nr-object.o: \ + libnr/nr-object.cpp \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libnr/nr-macros.h \ + libnr/nr-object.h + +libnr/nr-path.o: \ + libnr/nr-path.cpp \ + decimal-round.h \ + libnr/n-art-bpath.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-path-code.h \ + libnr/nr-path.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + round.h + +libnr/nr-pixblock-line.o: \ + libnr/nr-pixblock-line.cpp \ + decimal-round.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-pixblock-pixel.h \ + libnr/nr-pixblock.h \ + libnr/nr-pixops.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + round.h + +libnr/nr-pixblock-pattern.o: \ + libnr/nr-pixblock-pattern.cpp \ + decimal-round.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-pixblock-pattern.h \ + libnr/nr-pixblock.h \ + libnr/nr-pixops.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + round.h + +libnr/nr-pixblock-pixel.o: \ + libnr/nr-pixblock-pixel.cpp \ + decimal-round.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-pixblock-pixel.h \ + libnr/nr-pixblock.h \ + libnr/nr-pixops.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + round.h + +libnr/nr-pixblock.o: \ + libnr/nr-pixblock.cpp \ + decimal-round.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-pixblock.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + round.h + +libnr/nr-point-fns.o: \ + libnr/nr-point-fns.cpp \ + decimal-round.h \ + isnan.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-macros.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + round.h + +libnr/nr-rect-l.o: \ + libnr/nr-rect-l.cpp \ + decimal-round.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + round.h + +libnr/nr-rect.o: \ + libnr/nr-rect.cpp \ + decimal-round.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + round.h + +libnr/nr-rotate-fns.o: \ + libnr/nr-rotate-fns.cpp \ + decimal-round.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-macros.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rotate-fns.h \ + libnr/nr-rotate-ops.h \ + libnr/nr-rotate.h \ + round.h + +libnr/nr-rotate-matrix-ops.o: \ + libnr/nr-rotate-matrix-ops.cpp \ + decimal-round.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-ops.h \ + libnr/nr-matrix.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + round.h + +libnr/nr-scale-matrix-ops.o: \ + libnr/nr-scale-matrix-ops.cpp \ + decimal-round.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-ops.h \ + libnr/nr-matrix.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + round.h + +libnr/nr-scale-translate-ops.o: \ + libnr/nr-scale-translate-ops.cpp \ + decimal-round.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-translate-ops.h \ + libnr/nr-matrix.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + round.h + +libnr/nr-svp-render.o: \ + libnr/nr-svp-render.cpp \ + decimal-round.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-pixblock.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-svp-render.h \ + libnr/nr-svp.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + round.h + +libnr/nr-svp.o: \ + libnr/nr-svp.cpp \ + decimal-round.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-svp-private.h \ + libnr/nr-svp.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + round.h + +libnr/nr-translate-matrix-ops.o: \ + libnr/nr-translate-matrix-ops.cpp \ + decimal-round.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-ops.h \ + libnr/nr-matrix.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + round.h + +libnr/nr-translate-rotate-ops.o: \ + libnr/nr-translate-rotate-ops.cpp \ + decimal-round.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-translate-ops.h \ + libnr/nr-matrix.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rotate-ops.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + round.h + +libnr/nr-translate-scale-ops.o: \ + libnr/nr-translate-scale-ops.cpp \ + decimal-round.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-ops.h \ + libnr/nr-matrix.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + round.h + +libnr/nr-types.o: \ + libnr/nr-types.cpp \ + decimal-round.h \ + isnan.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-types.h \ + libnr/nr-values.h \ + round.h + +libnr/nr-values.o: \ + libnr/nr-values.cpp \ + decimal-round.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + round.h + +libnr/testnr.o: \ + libnr/testnr.cpp \ + decimal-round.h \ + libnr/nr-blit.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-pixblock.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + round.h + +libnrtype/FontFactory.o: \ + libnrtype/FontFactory.cpp \ + decimal-round.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + libnrtype/FontFactory.h \ + libnrtype/font-instance.h \ + libnrtype/font-style.h \ + libnrtype/nr-type-pos-def.h \ + libnrtype/nr-type-primitives.h \ + libnrtype/nrtype-forward.h \ + livarot/LivarotDefs.h \ + livarot/livarot-forward.h \ + require-config.h \ + round.h + +libnrtype/FontInstance.o: \ + libnrtype/FontInstance.cpp \ + decimal-round.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + libnrtype/FontFactory.h \ + libnrtype/RasterFont.h \ + libnrtype/font-glyph.h \ + libnrtype/font-instance.h \ + libnrtype/font-style.h \ + libnrtype/nr-type-pos-def.h \ + libnrtype/nr-type-primitives.h \ + libnrtype/nrtype-forward.h \ + livarot/LivarotDefs.h \ + livarot/Path.h \ + livarot/livarot-forward.h \ + require-config.h \ + round.h + +libnrtype/Layout-TNG-Compute.o: \ + libnrtype/Layout-TNG-Compute.cpp \ + color.h \ + decimal-round.h \ + forward.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-ops.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate-ops.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + libnrtype/FontFactory.h \ + libnrtype/Layout-TNG-Scanline-Maker.h \ + libnrtype/Layout-TNG.h \ + libnrtype/font-instance.h \ + libnrtype/font-style.h \ + libnrtype/nr-type-pos-def.h \ + libnrtype/nr-type-primitives.h \ + libnrtype/nrtype-forward.h \ + livarot/LivarotDefs.h \ + livarot/livarot-forward.h \ + require-config.h \ + round.h \ + sp-marker-loc.h \ + sp-object.h \ + style.h \ + svg/svg-length.h \ + traits/reference.h \ + util/forward-pointer-iterator.h \ + version.h + +libnrtype/Layout-TNG-Input.o: \ + libnrtype/Layout-TNG-Input.cpp \ + color.h \ + decimal-round.h \ + forward.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-ops.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate-ops.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + libnrtype/FontFactory.h \ + libnrtype/Layout-TNG.h \ + libnrtype/nr-type-pos-def.h \ + libnrtype/nr-type-primitives.h \ + libnrtype/nrtype-forward.h \ + round.h \ + sp-marker-loc.h \ + sp-object.h \ + style.h \ + svg/svg-length.h \ + traits/reference.h \ + util/forward-pointer-iterator.h \ + version.h + +libnrtype/Layout-TNG-OutIter.o: \ + libnrtype/Layout-TNG-OutIter.cpp \ + color.h \ + decimal-round.h \ + forward.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-ops.h \ + libnr/nr-matrix-translate-ops.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate-ops.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate-rotate-ops.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + libnrtype/FontFactory.h \ + libnrtype/Layout-TNG.h \ + libnrtype/font-instance.h \ + libnrtype/font-style.h \ + libnrtype/nr-type-pos-def.h \ + libnrtype/nr-type-primitives.h \ + libnrtype/nrtype-forward.h \ + livarot/LivarotDefs.h \ + livarot/Path.h \ + livarot/livarot-forward.h \ + require-config.h \ + round.h \ + sp-marker-loc.h \ + style.h \ + svg/svg-length.h + +libnrtype/Layout-TNG-Output.o: \ + libnrtype/Layout-TNG-Output.cpp \ + color.h \ + decimal-round.h \ + display/curve.h \ + display/nr-arena-forward.h \ + display/nr-arena-glyphs.h \ + display/nr-arena-group.h \ + display/nr-arena-item.h \ + document.h \ + extension/extension-forward.h \ + extension/extension.h \ + extension/print.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-ops.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-object.h \ + libnr/nr-path.h \ + libnr/nr-pixblock.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate-ops.h \ + libnr/nr-rotate.h \ + libnr/nr-scale-matrix-ops.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + libnrtype/FontFactory.h \ + libnrtype/Layout-TNG.h \ + libnrtype/font-instance.h \ + libnrtype/font-style.h \ + libnrtype/nr-type-pos-def.h \ + libnrtype/nr-type-primitives.h \ + libnrtype/nrtype-forward.h \ + livarot/LivarotDefs.h \ + livarot/Path.h \ + livarot/livarot-forward.h \ + require-config.h \ + round.h \ + sp-marker-loc.h \ + sp-object.h \ + sp-paint-server.h \ + style.h \ + svg/svg-length.h \ + traits/reference.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +libnrtype/Layout-TNG-Scanline-Makers.o: \ + libnrtype/Layout-TNG-Scanline-Makers.cpp \ + decimal-round.h \ + libavoid/geometry.h \ + libavoid/geomtypes.h \ + libavoid/shape.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-ops.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate-ops.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + libnrtype/Layout-TNG-Scanline-Maker.h \ + libnrtype/Layout-TNG.h \ + livarot/LivarotDefs.h \ + livarot/float-line.h \ + round.h + +libnrtype/Layout-TNG.o: \ + libnrtype/Layout-TNG.cpp \ + decimal-round.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-ops.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate-ops.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + libnrtype/Layout-TNG.h \ + round.h + +libnrtype/RasterFont.o: \ + libnrtype/RasterFont.cpp \ + decimal-round.h \ + libavoid/geometry.h \ + libavoid/geomtypes.h \ + libavoid/shape.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-pixblock.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + libnrtype/FontFactory.h \ + libnrtype/RasterFont.h \ + libnrtype/font-instance.h \ + libnrtype/font-style.h \ + libnrtype/nr-type-pos-def.h \ + libnrtype/nr-type-primitives.h \ + libnrtype/nrtype-forward.h \ + libnrtype/raster-glyph.h \ + libnrtype/raster-position.h \ + livarot/LivarotDefs.h \ + livarot/Path.h \ + livarot/float-line.h \ + livarot/int-line.h \ + livarot/livarot-forward.h \ + require-config.h \ + round.h + +libnrtype/TextWrapper.o: \ + libnrtype/TextWrapper.cpp \ + decimal-round.h \ + dom/css.h \ + dom/dom.h \ + dom/domstring.h \ + dom/events.h \ + dom/smil.h \ + dom/stylesheets.h \ + dom/svg.h \ + dom/svgtypes.h \ + dom/views.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + libnrtype/FontFactory.h \ + libnrtype/TextWrapper.h \ + libnrtype/boundary-type.h \ + libnrtype/font-instance.h \ + libnrtype/font-style.h \ + libnrtype/nr-type-pos-def.h \ + libnrtype/nr-type-primitives.h \ + libnrtype/nrtype-forward.h \ + libnrtype/one-box.h \ + libnrtype/one-glyph.h \ + libnrtype/one-para.h \ + libnrtype/text-boundary.h \ + livarot/LivarotDefs.h \ + livarot/livarot-forward.h \ + require-config.h \ + round.h + +libnrtype/font-style-to-pos.o: \ + libnrtype/font-style-to-pos.cpp \ + color.h \ + forward.h \ + libnrtype/font-style-to-pos.h \ + libnrtype/nr-type-pos-def.h \ + sp-marker-loc.h \ + style.h + +libnrtype/nr-type-pos-def.o: \ + libnrtype/nr-type-pos-def.cpp \ + libnrtype/nr-type-pos-def.h + +libnrtype/nr-type-primitives.o: \ + libnrtype/nr-type-primitives.cpp \ + libnr/nr-macros.h \ + libnrtype/nr-type-primitives.h + +line-snapper.o: \ + line-snapper.cpp \ + decimal-round.h \ + geom.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-macros.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-values.h \ + line-snapper.h \ + round.h \ + snapped-point.h \ + snapper.h + +livarot/AVL.o: \ + livarot/AVL.cpp \ + livarot/AVL.h \ + livarot/LivarotDefs.h + +livarot/AlphaLigne.o: \ + livarot/AlphaLigne.cpp \ + livarot/AlphaLigne.h \ + livarot/LivarotDefs.h + +livarot/BitLigne.o: \ + livarot/BitLigne.cpp \ + livarot/BitLigne.h \ + livarot/LivarotDefs.h + +livarot/MySeg.o: \ + livarot/MySeg.cpp \ + livarot/MyMath.h \ + livarot/MySeg.h + +livarot/Path.o: \ + livarot/Path.cpp \ + decimal-round.h \ + dom/dom.h \ + dom/domstream.h \ + dom/domstring.h \ + dom/stringstream.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-ops.h \ + libnr/nr-matrix.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + livarot/LivarotDefs.h \ + livarot/Path.h \ + livarot/livarot-forward.h \ + livarot/path-description.h \ + round.h + +livarot/PathConversion.o: \ + livarot/PathConversion.cpp \ + decimal-round.h \ + dom/dom.h \ + dom/domstream.h \ + dom/domstring.h \ + dom/stringstream.h \ + libavoid/geometry.h \ + libavoid/geomtypes.h \ + libavoid/shape.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rotate-ops.h \ + libnr/nr-rotate.h \ + libnr/nr-scale-ops.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + livarot/LivarotDefs.h \ + livarot/Path.h \ + livarot/livarot-forward.h \ + livarot/path-description.h \ + round.h + +livarot/PathCutting.o: \ + livarot/PathCutting.cpp \ + decimal-round.h \ + display/canvas-bpath.h \ + display/sp-canvas.h \ + dom/dom.h \ + dom/domstream.h \ + dom/domstring.h \ + dom/stringstream.h \ + libnr/n-art-bpath.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-path-code.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + livarot/LivarotDefs.h \ + livarot/Path.h \ + livarot/livarot-forward.h \ + livarot/path-description.h \ + round.h + +livarot/PathOutline.o: \ + livarot/PathOutline.cpp \ + decimal-round.h \ + dom/dom.h \ + dom/domstream.h \ + dom/domstring.h \ + dom/stringstream.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-macros.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + livarot/LivarotDefs.h \ + livarot/Path.h \ + livarot/livarot-forward.h \ + livarot/path-description.h \ + round.h + +livarot/PathSimplify.o: \ + livarot/PathSimplify.cpp \ + decimal-round.h \ + dom/dom.h \ + dom/domstream.h \ + dom/domstring.h \ + dom/stringstream.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + livarot/LivarotDefs.h \ + livarot/Path.h \ + livarot/livarot-forward.h \ + livarot/path-description.h \ + round.h + +livarot/PathStroke.o: \ + livarot/PathStroke.cpp \ + decimal-round.h \ + libavoid/geometry.h \ + libavoid/geomtypes.h \ + libavoid/shape.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-macros.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rotate-ops.h \ + libnr/nr-rotate.h \ + livarot/LivarotDefs.h \ + livarot/Path.h \ + livarot/livarot-forward.h \ + round.h + +livarot/Shape.o: \ + livarot/Shape.cpp \ + libavoid/geometry.h \ + libavoid/geomtypes.h \ + libavoid/graph.h \ + libavoid/polyutil.h \ + libavoid/shape.h \ + libavoid/vertices.h + +livarot/ShapeDraw.o: \ + livarot/ShapeDraw.cpp \ + libavoid/geometry.h \ + libavoid/geomtypes.h \ + libavoid/shape.h + +livarot/ShapeMisc.o: \ + livarot/ShapeMisc.cpp \ + decimal-round.h \ + dom/dom.h \ + dom/domstream.h \ + dom/domstring.h \ + dom/stringstream.h \ + libavoid/geometry.h \ + libavoid/geomtypes.h \ + libavoid/shape.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-macros.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + livarot/LivarotDefs.h \ + livarot/Path.h \ + livarot/livarot-forward.h \ + livarot/path-description.h \ + round.h + +livarot/ShapeRaster.o: \ + livarot/ShapeRaster.cpp \ + decimal-round.h \ + libavoid/geometry.h \ + libavoid/geomtypes.h \ + libavoid/shape.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-macros.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + livarot/AVL.h \ + livarot/AlphaLigne.h \ + livarot/BitLigne.h \ + livarot/LivarotDefs.h \ + livarot/float-line.h \ + livarot/sweep-event-queue.h \ + livarot/sweep-tree-list.h \ + livarot/sweep-tree.h \ + round.h + +livarot/ShapeSweep.o: \ + livarot/ShapeSweep.cpp \ + decimal-round.h \ + libavoid/geometry.h \ + libavoid/geomtypes.h \ + libavoid/shape.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + livarot/AVL.h \ + livarot/LivarotDefs.h \ + livarot/sweep-event-queue.h \ + livarot/sweep-tree-list.h \ + livarot/sweep-tree.h \ + round.h + +livarot/float-line.o: \ + livarot/float-line.cpp \ + livarot/LivarotDefs.h \ + livarot/float-line.h \ + livarot/int-line.h \ + livarot/livarot-forward.h + +livarot/int-line.o: \ + livarot/int-line.cpp \ + livarot/BitLigne.h \ + livarot/LivarotDefs.h \ + livarot/float-line.h \ + livarot/int-line.h \ + livarot/livarot-forward.h + +livarot/path-description.o: \ + livarot/path-description.cpp \ + decimal-round.h \ + dom/dom.h \ + dom/domstream.h \ + dom/domstring.h \ + dom/stringstream.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + livarot/path-description.h \ + round.h + +livarot/sweep-event.o: \ + livarot/sweep-event.cpp \ + decimal-round.h \ + libavoid/geometry.h \ + libavoid/geomtypes.h \ + libavoid/shape.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-point.h \ + livarot/AVL.h \ + livarot/LivarotDefs.h \ + livarot/sweep-event-queue.h \ + livarot/sweep-event.h \ + livarot/sweep-tree.h \ + round.h + +livarot/sweep-tree-list.o: \ + livarot/sweep-tree-list.cpp \ + decimal-round.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-point.h \ + livarot/AVL.h \ + livarot/LivarotDefs.h \ + livarot/sweep-tree-list.h \ + livarot/sweep-tree.h \ + round.h + +livarot/sweep-tree.o: \ + livarot/sweep-tree.cpp \ + decimal-round.h \ + libavoid/geometry.h \ + libavoid/geomtypes.h \ + libavoid/shape.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-macros.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + livarot/AVL.h \ + livarot/LivarotDefs.h \ + livarot/sweep-event-queue.h \ + livarot/sweep-event.h \ + livarot/sweep-tree-list.h \ + livarot/sweep-tree.h \ + round.h + +marker-status.o: \ + marker-status.cpp + +media.o: \ + media.cpp \ + media.h + +message-context.o: \ + message-context.cpp \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + message-context.h \ + message-stack.h \ + message.h + +message-stack.o: \ + message-stack.cpp \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + message-stack.h \ + message.h + +mod360.o: \ + mod360.cpp + +node-context.o: \ + node-context.cpp \ + color.h \ + decimal-round.h \ + desktop-handles.h \ + desktop.h \ + display/display-forward.h \ + display/nr-arena-forward.h \ + display/sp-canvas-util.h \ + display/sp-canvas.h \ + event-context.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + knot-enums.h \ + knotholder.h \ + libavoid/connector.h \ + libavoid/geometry.h \ + libavoid/geomtypes.h \ + libavoid/shape.h \ + libnr/nr-convex-hull.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-path-code.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + livarot/LivarotDefs.h \ + livarot/Path.h \ + livarot/livarot-forward.h \ + macros.h \ + message-context.h \ + message.h \ + node-context.h \ + nodepath.h \ + object-edit.h \ + path-chemistry.h \ + prefs-utils.h \ + round.h \ + rubberband.h \ + selection.h \ + sp-conn-end-pair.h \ + sp-item.h \ + sp-marker-loc.h \ + sp-object.h \ + sp-path.h \ + sp-shape.h \ + splivarot.h \ + style.h \ + traits/reference.h \ + ui/view/edit-widget-interface.h \ + ui/view/view.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/node-event-vector.h \ + xml/node.h + +nodepath.o: \ + nodepath.cpp \ + decimal-round.h \ + desktop-handles.h \ + desktop.h \ + display/curve.h \ + display/display-forward.h \ + display/nr-arena-forward.h \ + display/sodipodi-ctrl.h \ + display/sp-canvas.h \ + display/sp-ctrlline.h \ + document.h \ + dom/css.h \ + dom/dom.h \ + dom/domstring.h \ + dom/events.h \ + dom/smil.h \ + dom/stylesheets.h \ + dom/svg.h \ + dom/svgtypes.h \ + dom/views.h \ + event-context.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + grid-snapper.h \ + guide-snapper.h \ + helper/helper-forward.h \ + helper/stlport.h \ + helper/units.h \ + inkscape.h \ + knot-enums.h \ + knot.h \ + libavoid/connector.h \ + libavoid/geometry.h \ + libavoid/geomtypes.h \ + libavoid/shape.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/n-art-bpath.h \ + libnr/nr-convex-hull.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix-ops.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-path-code.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + line-snapper.h \ + livarot/LivarotDefs.h \ + livarot/Path.h \ + livarot/livarot-forward.h \ + message-context.h \ + message-stack.h \ + message.h \ + node-context.h \ + nodepath.h \ + object-snapper.h \ + prefs-utils.h \ + round.h \ + selection-chemistry.h \ + selection.h \ + snap.h \ + snapped-point.h \ + snapper.h \ + sp-conn-end-pair.h \ + sp-item.h \ + sp-marker-loc.h \ + sp-metric.h \ + sp-metrics.h \ + sp-namedview.h \ + sp-object-group.h \ + sp-object.h \ + sp-path.h \ + sp-shape.h \ + splivarot.h \ + traits/reference.h \ + ui/view/edit-widget-interface.h \ + ui/view/view.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +object-edit.o: \ + object-edit.cpp \ + bad-uri-exception.h \ + color.h \ + decimal-round.h \ + desktop-affine.h \ + desktop.h \ + display/display-forward.h \ + display/nr-arena-forward.h \ + document.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + inkscape.h \ + isnan.h \ + knot-enums.h \ + knotholder.h \ + libavoid/connector.h \ + libavoid/geometry.h \ + libavoid/geomtypes.h \ + libavoid/shape.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix-ops.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-pixblock.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate-ops.h \ + libnr/nr-rotate.h \ + libnr/nr-scale-ops.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + libnrtype/Layout-TNG.h \ + message.h \ + object-edit.h \ + prefs-utils.h \ + round.h \ + snap.h \ + snapped-point.h \ + snapper.h \ + sp-conn-end-pair.h \ + sp-ellipse.h \ + sp-flowtext.h \ + sp-item.h \ + sp-marker-loc.h \ + sp-object.h \ + sp-offset.h \ + sp-paint-server.h \ + sp-path.h \ + sp-pattern.h \ + sp-polygon.h \ + sp-rect.h \ + sp-shape.h \ + sp-spiral.h \ + sp-star.h \ + style.h \ + svg/svg-length.h \ + traits/reference.h \ + ui/view/edit-widget-interface.h \ + ui/view/view.h \ + uri-references.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +object-hierarchy.o: \ + object-hierarchy.cpp \ + forward.h \ + object-hierarchy.h \ + sp-object.h \ + traits/reference.h \ + util/forward-pointer-iterator.h \ + version.h + +object-snapper.o: \ + object-snapper.cpp \ + decimal-round.h \ + desktop.h \ + display/curve.h \ + display/display-forward.h \ + display/nr-arena-forward.h \ + document.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + grid-snapper.h \ + guide-snapper.h \ + helper/helper-forward.h \ + inkscape.h \ + libavoid/connector.h \ + libavoid/geometry.h \ + libavoid/geomtypes.h \ + libavoid/shape.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/n-art-bpath.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-path-code.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-ops.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + line-snapper.h \ + livarot/LivarotDefs.h \ + livarot/Path.h \ + livarot/livarot-forward.h \ + message.h \ + object-snapper.h \ + round.h \ + snapped-point.h \ + snapper.h \ + sp-conn-end-pair.h \ + sp-item.h \ + sp-marker-loc.h \ + sp-metric.h \ + sp-namedview.h \ + sp-object-group.h \ + sp-object.h \ + sp-path.h \ + sp-shape.h \ + splivarot.h \ + traits/reference.h \ + ui/view/edit-widget-interface.h \ + ui/view/view.h \ + util/forward-pointer-iterator.h \ + version.h + +object-ui.o: \ + object-ui.cpp \ + decimal-round.h \ + desktop-handles.h \ + dialogs/item-properties.h \ + dialogs/object-attributes.h \ + dialogs/object-properties.h \ + display/display-forward.h \ + display/nr-arena-forward.h \ + document.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libavoid/connector.h \ + libavoid/geometry.h \ + libavoid/geomtypes.h \ + libavoid/shape.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-convex-hull.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + object-ui.h \ + round.h \ + selection.h \ + sp-anchor.h \ + sp-conn-end-pair.h \ + sp-image.h \ + sp-item-group.h \ + sp-item.h \ + sp-marker-loc.h \ + sp-object.h \ + sp-path.h \ + sp-shape.h \ + svg/svg-length.h \ + traits/reference.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +path-chemistry.o: \ + path-chemistry.cpp \ + color.h \ + decimal-round.h \ + desktop-handles.h \ + display/curve.h \ + display/display-forward.h \ + display/nr-arena-forward.h \ + document.h \ + dom/css.h \ + dom/dom.h \ + dom/domstring.h \ + dom/events.h \ + dom/smil.h \ + dom/stylesheets.h \ + dom/svg.h \ + dom/svgtypes.h \ + dom/views.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + inkscape.h \ + libavoid/connector.h \ + libavoid/geometry.h \ + libavoid/geomtypes.h \ + libavoid/shape.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-convex-hull.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-ops.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-path.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate-ops.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + libnrtype/Layout-TNG.h \ + message-stack.h \ + message.h \ + round.h \ + selection.h \ + sp-conn-end-pair.h \ + sp-flowtext.h \ + sp-item.h \ + sp-marker-loc.h \ + sp-object.h \ + sp-path.h \ + sp-shape.h \ + sp-string.h \ + sp-text.h \ + style.h \ + svg/svg-length.h \ + text-editing.h \ + text-tag-attributes.h \ + traits/reference.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +pen-context.o: \ + pen-context.cpp \ + context-fns.h \ + decimal-round.h \ + desktop-handles.h \ + desktop.h \ + display/canvas-bpath.h \ + display/curve.h \ + display/display-forward.h \ + display/nr-arena-forward.h \ + display/sodipodi-ctrl.h \ + display/sp-canvas.h \ + display/sp-ctrlline.h \ + draw-anchor.h \ + draw-context.h \ + event-context.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + grid-snapper.h \ + guide-snapper.h \ + helper/helper-forward.h \ + helper/units.h \ + libavoid/connector.h \ + libavoid/geometry.h \ + libavoid/geomtypes.h \ + libavoid/shape.h \ + libnr/n-art-bpath.h \ + libnr/nr-convex-hull.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-path-code.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + line-snapper.h \ + macros.h \ + message-context.h \ + message-stack.h \ + message.h \ + object-snapper.h \ + pen-context.h \ + prefs-utils.h \ + round.h \ + selection.h \ + snapped-point.h \ + snapper.h \ + sp-conn-end-pair.h \ + sp-item.h \ + sp-marker-loc.h \ + sp-metric.h \ + sp-metrics.h \ + sp-namedview.h \ + sp-object-group.h \ + sp-object.h \ + sp-path.h \ + sp-shape.h \ + traits/reference.h \ + ui/view/edit-widget-interface.h \ + ui/view/view.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h + +pencil-context.o: \ + pencil-context.cpp \ + context-fns.h \ + decimal-round.h \ + desktop-handles.h \ + desktop.h \ + display/bezier-utils.h \ + display/canvas-bpath.h \ + display/curve.h \ + display/display-forward.h \ + display/nr-arena-forward.h \ + display/sp-canvas.h \ + draw-anchor.h \ + draw-context.h \ + event-context.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libavoid/connector.h \ + libavoid/geometry.h \ + libavoid/geomtypes.h \ + libavoid/shape.h \ + libnr/in-svg-plane.h \ + libnr/n-art-bpath.h \ + libnr/nr-convex-hull.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-path-code.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + message-context.h \ + message-stack.h \ + message.h \ + modifier-fns.h \ + pencil-context.h \ + prefs-utils.h \ + round.h \ + selection.h \ + snap.h \ + snapped-point.h \ + snapper.h \ + sp-conn-end-pair.h \ + sp-item.h \ + sp-marker-loc.h \ + sp-object.h \ + sp-path.h \ + sp-shape.h \ + traits/reference.h \ + ui/view/edit-widget-interface.h \ + ui/view/view.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h + +preferences.o: \ + preferences.cpp \ + dialogs/input.h \ + document.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + inkscape.h \ + inkscape_version.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-forward.h \ + preferences-skeleton.h \ + preferences.h \ + traits/reference.h \ + util/list.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +prefix.o: \ + prefix.cpp \ + prefix.h + +prefs-utils.o: \ + prefs-utils.cpp \ + document.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + inkscape.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-forward.h \ + traits/reference.h \ + util/list.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +print.o: \ + print.cpp \ + decimal-round.h \ + display/nr-arena-forward.h \ + document.h \ + extension/extension-forward.h \ + extension/extension.h \ + extension/implementation/implementation.h \ + extension/print.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-path.h \ + libnr/nr-point.h \ + round.h \ + traits/reference.h \ + util/list.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +rect-context.o: \ + rect-context.cpp \ + context-fns.h \ + decimal-round.h \ + desktop-handles.h \ + desktop-style.h \ + desktop.h \ + display/display-forward.h \ + display/nr-arena-forward.h \ + display/sp-canvas.h \ + document.h \ + event-context.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + grid-snapper.h \ + guide-snapper.h \ + helper/helper-forward.h \ + knot-enums.h \ + knotholder.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-convex-hull.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + line-snapper.h \ + macros.h \ + message-context.h \ + message.h \ + object-edit.h \ + object-snapper.h \ + prefs-utils.h \ + rect-context.h \ + round.h \ + selection.h \ + snap.h \ + snapped-point.h \ + snapper.h \ + sp-item.h \ + sp-marker-loc.h \ + sp-metric.h \ + sp-metrics.h \ + sp-namedview.h \ + sp-object-group.h \ + sp-object.h \ + sp-rect.h \ + sp-shape.h \ + svg/svg-length.h \ + traits/reference.h \ + ui/view/edit-widget-interface.h \ + ui/view/view.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/node-event-vector.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +registrytool.o: \ + registrytool.cpp \ + registrytool.h + +removeoverlap/block.o: \ + removeoverlap/block.cpp \ + removeoverlap/block.h \ + removeoverlap/blocks.h \ + removeoverlap/constraint.h \ + removeoverlap/pairingheap/PairingHeap.cpp \ + removeoverlap/pairingheap/PairingHeap.h \ + removeoverlap/pairingheap/dsexceptions.h \ + removeoverlap/variable.h + +removeoverlap/blocks.o: \ + removeoverlap/blocks.cpp \ + removeoverlap/block.h \ + removeoverlap/blocks.h \ + removeoverlap/constraint.h \ + removeoverlap/variable.h + +removeoverlap/constraint.o: \ + removeoverlap/constraint.cpp \ + removeoverlap/constraint.h \ + removeoverlap/variable.h + +removeoverlap/generate-constraints.o: \ + removeoverlap/generate-constraints.cpp \ + isnan.h \ + removeoverlap/constraint.h \ + removeoverlap/generate-constraints.h \ + removeoverlap/variable.h + +removeoverlap/pairingheap/PairingHeap.o: \ + removeoverlap/pairingheap/PairingHeap.cpp \ + removeoverlap/pairingheap/PairingHeap.cpp \ + removeoverlap/pairingheap/PairingHeap.h \ + removeoverlap/pairingheap/dsexceptions.h + +removeoverlap/remove_rectangle_overlap.o: \ + removeoverlap/remove_rectangle_overlap.cpp \ + removeoverlap/constraint.h \ + removeoverlap/generate-constraints.h \ + removeoverlap/solve_VPSC.h \ + removeoverlap/variable.h + +removeoverlap/removeoverlap.o: \ + removeoverlap/removeoverlap.cpp \ + decimal-round.h \ + display/nr-arena-forward.h \ + forward.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + removeoverlap/generate-constraints.h \ + removeoverlap/remove_rectangle_overlap.h \ + round.h \ + sp-item-transform.h \ + sp-item.h \ + sp-object.h \ + traits/reference.h \ + util/forward-pointer-iterator.h \ + util/glib-list-iterators.h \ + version.h + +removeoverlap/solve_VPSC.o: \ + removeoverlap/solve_VPSC.cpp \ + removeoverlap/block.h \ + removeoverlap/blocks.h \ + removeoverlap/constraint.h \ + removeoverlap/solve_VPSC.h \ + removeoverlap/variable.h + +removeoverlap/variable.o: \ + removeoverlap/variable.cpp \ + removeoverlap/block.h \ + removeoverlap/variable.h + +rubberband.o: \ + rubberband.cpp \ + decimal-round.h \ + desktop-handles.h \ + desktop.h \ + display/display-forward.h \ + display/sodipodi-ctrlrect.h \ + display/sp-canvas.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + message.h \ + round.h \ + rubberband.h \ + ui/view/edit-widget-interface.h \ + ui/view/view.h + +satisfied-guide-cns.o: \ + satisfied-guide-cns.cpp \ + approx-equal.h \ + decimal-round.h \ + desktop-handles.h \ + display/display-forward.h \ + forward.h \ + grid-snapper.h \ + guide-snapper.h \ + helper/helper-forward.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-macros.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + line-snapper.h \ + object-snapper.h \ + round.h \ + snapped-point.h \ + snapper.h \ + sp-guide-attachment.h \ + sp-guide-constraint.h \ + sp-guide.h \ + sp-metric.h \ + sp-namedview.h \ + sp-object-group.h \ + sp-object.h \ + traits/reference.h \ + util/forward-pointer-iterator.h \ + version.h + +selcue.o: \ + selcue.cpp \ + decimal-round.h \ + desktop-handles.h \ + display/display-forward.h \ + display/nr-arena-forward.h \ + display/sodipodi-ctrl.h \ + display/sodipodi-ctrlrect.h \ + display/sp-canvas-util.h \ + display/sp-canvas.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libnr/nr-convex-hull.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-ops.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate-ops.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + libnrtype/Layout-TNG.h \ + prefs-utils.h \ + round.h \ + selcue.h \ + selection.h \ + sp-flowtext.h \ + sp-item.h \ + sp-object.h \ + sp-string.h \ + sp-text.h \ + svg/svg-length.h \ + text-editing.h \ + text-tag-attributes.h \ + traits/reference.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h + +select-context.o: \ + select-context.cpp \ + decimal-round.h \ + desktop-handles.h \ + desktop.h \ + display/display-forward.h \ + display/nr-arena-forward.h \ + display/sodipodi-ctrl.h \ + display/sp-canvas.h \ + document.h \ + enums.h \ + event-context.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-convex-hull.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + macros.h \ + message-context.h \ + message-stack.h \ + message.h \ + prefs-utils.h \ + round.h \ + rubberband.h \ + selcue.h \ + select-context.h \ + selection-chemistry.h \ + selection-describer.h \ + selection.h \ + seltrans-handles.h \ + seltrans.h \ + sp-cursor.h \ + sp-item-group.h \ + sp-item.h \ + sp-object.h \ + sp-root.h \ + svg/svg-length.h \ + tools-switch.h \ + traits/reference.h \ + ui/view/edit-widget-interface.h \ + ui/view/view.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h + +selection-chemistry.o: \ + selection-chemistry.cpp \ + bad-uri-exception.h \ + color.h \ + composite-undo-stack-observer.h \ + context-fns.h \ + decimal-round.h \ + desktop-handles.h \ + desktop-style.h \ + desktop.h \ + display/display-forward.h \ + display/nr-arena-forward.h \ + document-private.h \ + document.h \ + dom/css.h \ + dom/dom.h \ + dom/domstring.h \ + dom/events.h \ + dom/smil.h \ + dom/stylesheets.h \ + dom/svg.h \ + dom/svgtypes.h \ + dom/views.h \ + dropper-context.h \ + enums.h \ + event-context.h \ + extension/extension-forward.h \ + file.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + grid-snapper.h \ + guide-snapper.h \ + helper/helper-forward.h \ + inkscape.h \ + layer-fns.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-convex-hull.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix-ops.h \ + libnr/nr-matrix-rotate-ops.h \ + libnr/nr-matrix-translate-ops.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-pixblock.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate-fns.h \ + libnr/nr-rotate-ops.h \ + libnr/nr-rotate.h \ + libnr/nr-scale-ops.h \ + libnr/nr-scale-translate-ops.h \ + libnr/nr-scale.h \ + libnr/nr-translate-matrix-ops.h \ + libnr/nr-translate-scale-ops.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + libnrtype/Layout-TNG.h \ + line-snapper.h \ + message-stack.h \ + message.h \ + object-snapper.h \ + prefs-utils.h \ + round.h \ + selection-chemistry.h \ + selection.h \ + snapped-point.h \ + snapper.h \ + sp-defs.h \ + sp-flowregion.h \ + sp-flowtext.h \ + sp-gradient-fns.h \ + sp-gradient-reference.h \ + sp-gradient-spread.h \ + sp-gradient-units.h \ + sp-gradient-vector.h \ + sp-gradient.h \ + sp-item-group.h \ + sp-item-transform.h \ + sp-item.h \ + sp-linear-gradient-fns.h \ + sp-marker-loc.h \ + sp-marker.h \ + sp-metric.h \ + sp-namedview.h \ + sp-object-group.h \ + sp-object.h \ + sp-offset.h \ + sp-paint-server.h \ + sp-pattern.h \ + sp-radial-gradient-fns.h \ + sp-root.h \ + sp-shape.h \ + sp-string.h \ + sp-text.h \ + sp-textpath.h \ + sp-tspan.h \ + sp-use.h \ + style.h \ + svg/svg-length.h \ + text-context.h \ + text-editing.h \ + text-tag-attributes.h \ + tools-switch.h \ + traits/reference.h \ + ui/view/edit-widget-interface.h \ + ui/view/view.h \ + undo-stack-observer.h \ + uri-references.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/event-fns.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +selection-describer.o: \ + selection-describer.cpp \ + decimal-round.h \ + desktop.h \ + display/display-forward.h \ + display/nr-arena-forward.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libnr/nr-convex-hull.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix-ops.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate-ops.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + libnrtype/Layout-TNG.h \ + message-context.h \ + message.h \ + round.h \ + selection-describer.h \ + selection.h \ + sp-flowtext.h \ + sp-item.h \ + sp-marker-loc.h \ + sp-object.h \ + sp-offset.h \ + sp-shape.h \ + sp-string.h \ + sp-text.h \ + sp-textpath.h \ + sp-use.h \ + svg/svg-length.h \ + text-tag-attributes.h \ + traits/reference.h \ + ui/view/edit-widget-interface.h \ + ui/view/view.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/quote.h + +selection.o: \ + selection.cpp \ + decimal-round.h \ + desktop-handles.h \ + desktop.h \ + display/display-forward.h \ + display/nr-arena-forward.h \ + document.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + inkscape-private.h \ + inkscape.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-convex-hull.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + macros.h \ + message.h \ + round.h \ + selection.h \ + sp-item.h \ + sp-marker-loc.h \ + sp-object.h \ + sp-shape.h \ + traits/reference.h \ + ui/view/edit-widget-interface.h \ + ui/view/view.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +seltrans-handles.o: \ + seltrans-handles.cpp \ + decimal-round.h \ + display/sodipodi-ctrl.h \ + display/sp-canvas.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + round.h \ + seltrans-handles.h + +seltrans.o: \ + seltrans.cpp \ + decimal-round.h \ + desktop-handles.h \ + desktop-style.h \ + desktop.h \ + display/display-forward.h \ + display/nr-arena-forward.h \ + display/sodipodi-ctrl.h \ + display/sp-canvas.h \ + display/sp-ctrlline.h \ + document.h \ + event-context.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + grid-snapper.h \ + guide-snapper.h \ + helper/helper-forward.h \ + isnan.h \ + knot-enums.h \ + knot.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-convex-hull.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix-ops.h \ + libnr/nr-matrix-translate-ops.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate-ops.h \ + libnr/nr-rotate.h \ + libnr/nr-scale-ops.h \ + libnr/nr-scale.h \ + libnr/nr-translate-matrix-ops.h \ + libnr/nr-translate-ops.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + line-snapper.h \ + message-context.h \ + message.h \ + object-snapper.h \ + prefs-utils.h \ + round.h \ + selcue.h \ + select-context.h \ + selection-chemistry.h \ + selection.h \ + seltrans-handles.h \ + seltrans.h \ + snap.h \ + snapped-point.h \ + snapper.h \ + sp-item-transform.h \ + sp-item.h \ + sp-metric.h \ + sp-metrics.h \ + sp-namedview.h \ + sp-object-group.h \ + sp-object.h \ + traits/reference.h \ + ui/view/edit-widget-interface.h \ + ui/view/view.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +shortcuts-default-xml.o: \ + shortcuts-default-xml.cpp + +shortcuts.o: \ + shortcuts.cpp \ + document.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + helper/action.h \ + helper/helper-forward.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-forward.h \ + libnr/nr-object.h \ + require-config.h \ + shortcuts.h \ + traits/reference.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + verbs.h \ + xml/node-iterators.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +slideshow.o: \ + slideshow.cpp \ + display/display-forward.h \ + document.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-forward.h \ + message.h \ + svg-view-widget.h \ + svg-view.h \ + ui/view/view-widget.h \ + ui/view/view.h + +snap.o: \ + snap.cpp \ + decimal-round.h \ + forward.h \ + grid-snapper.h \ + guide-snapper.h \ + helper/helper-forward.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-macros.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-scale-ops.h \ + libnr/nr-scale.h \ + libnr/nr-values.h \ + line-snapper.h \ + object-snapper.h \ + round.h \ + snap.h \ + snapped-point.h \ + snapper.h \ + sp-metric.h \ + sp-namedview.h \ + sp-object-group.h \ + sp-object.h \ + traits/reference.h \ + util/forward-pointer-iterator.h \ + version.h + +snapped-point.o: \ + snapped-point.cpp \ + decimal-round.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-point.h \ + round.h \ + snapped-point.h + +snapper.o: \ + snapper.cpp \ + decimal-round.h \ + forward.h \ + grid-snapper.h \ + guide-snapper.h \ + helper/helper-forward.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-point.h \ + libnr/nr-values.h \ + line-snapper.h \ + object-snapper.h \ + round.h \ + snapped-point.h \ + snapper.h \ + sp-metric.h \ + sp-namedview.h \ + sp-object-group.h \ + sp-object.h \ + traits/reference.h \ + util/forward-pointer-iterator.h \ + version.h + +sp-anchor.o: \ + sp-anchor.cpp \ + attributes.h \ + decimal-round.h \ + display/nr-arena-forward.h \ + document.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + message.h \ + round.h \ + sp-anchor.h \ + sp-item-group.h \ + sp-item.h \ + sp-object.h \ + traits/reference.h \ + ui/view/view.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/node.h \ + xml/quote.h \ + xml/repr.h \ + xml/sp-css-attr.h + +sp-animation.o: \ + sp-animation.cpp \ + forward.h \ + sp-animation.h \ + sp-object.h \ + traits/reference.h \ + util/forward-pointer-iterator.h \ + version.h + +sp-clippath.o: \ + sp-clippath.cpp \ + attributes.h \ + bad-uri-exception.h \ + decimal-round.h \ + display/nr-arena-forward.h \ + display/nr-arena-group.h \ + display/nr-arena-item.h \ + display/nr-arena.h \ + document.h \ + enums.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-object.h \ + libnr/nr-pixblock.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + round.h \ + sp-clippath.h \ + sp-item.h \ + sp-object-group.h \ + sp-object.h \ + sp-paint-server.h \ + traits/reference.h \ + uri-references.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +sp-conn-end-pair.o: \ + sp-conn-end-pair.cpp \ + attributes.h \ + bad-uri-exception.h \ + decimal-round.h \ + display/curve.h \ + display/display-forward.h \ + display/nr-arena-forward.h \ + document.h \ + dom/dom.h \ + dom/domstring.h \ + dom/uri.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libavoid/connector.h \ + libavoid/geometry.h \ + libavoid/geomtypes.h \ + libavoid/shape.h \ + libavoid/vertices.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + round.h \ + sp-conn-end-pair.h \ + sp-conn-end.h \ + sp-item.h \ + sp-marker-loc.h \ + sp-object.h \ + sp-path.h \ + sp-shape.h \ + sp-use-reference.h \ + traits/reference.h \ + uri-references.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +sp-conn-end.o: \ + sp-conn-end.cpp \ + bad-uri-exception.h \ + decimal-round.h \ + display/curve.h \ + display/display-forward.h \ + display/nr-arena-forward.h \ + document.h \ + dom/dom.h \ + dom/domstring.h \ + dom/uri.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libavoid/connector.h \ + libavoid/geometry.h \ + libavoid/geomtypes.h \ + libavoid/shape.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-div.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + round.h \ + sp-conn-end-pair.h \ + sp-conn-end.h \ + sp-item.h \ + sp-marker-loc.h \ + sp-object.h \ + sp-path.h \ + sp-shape.h \ + sp-use-reference.h \ + traits/reference.h \ + uri-references.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +sp-cursor.o: \ + sp-cursor.cpp \ + sp-cursor.h + +sp-defs.o: \ + sp-defs.cpp \ + document.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-forward.h \ + sp-defs.h \ + sp-object.h \ + traits/reference.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +sp-ellipse.o: \ + sp-ellipse.cpp \ + attributes.h \ + color.h \ + decimal-round.h \ + display/curve.h \ + display/display-forward.h \ + display/nr-arena-forward.h \ + document.h \ + dom/css.h \ + dom/dom.h \ + dom/domstream.h \ + dom/domstring.h \ + dom/events.h \ + dom/smil.h \ + dom/stringstream.h \ + dom/stylesheets.h \ + dom/svg.h \ + dom/svgtypes.h \ + dom/views.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/n-art-bpath.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-path-code.h \ + libnr/nr-path.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + prefs-utils.h \ + round.h \ + sp-ellipse.h \ + sp-item.h \ + sp-marker-loc.h \ + sp-object.h \ + sp-shape.h \ + style.h \ + svg/svg-length.h \ + traits/reference.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +sp-flowdiv.o: \ + sp-flowdiv.cpp \ + decimal-round.h \ + display/nr-arena-forward.h \ + document.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-ops.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + round.h \ + sp-flowdiv.h \ + sp-item.h \ + sp-object.h \ + sp-string.h \ + traits/reference.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +sp-flowregion.o: \ + sp-flowregion.cpp \ + color.h \ + decimal-round.h \ + display/canvas-bpath.h \ + display/curve.h \ + display/display-forward.h \ + display/nr-arena-forward.h \ + display/sp-canvas.h \ + document.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libavoid/geometry.h \ + libavoid/geomtypes.h \ + libavoid/shape.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-ops.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate-ops.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + libnrtype/Layout-TNG.h \ + livarot/LivarotDefs.h \ + livarot/Path.h \ + livarot/livarot-forward.h \ + round.h \ + sp-flowregion.h \ + sp-item.h \ + sp-marker-loc.h \ + sp-object.h \ + sp-shape.h \ + sp-string.h \ + sp-text.h \ + sp-use.h \ + style.h \ + svg/svg-length.h \ + text-tag-attributes.h \ + traits/reference.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +sp-flowtext.o: \ + sp-flowtext.cpp \ + attributes.h \ + color.h \ + decimal-round.h \ + desktop-affine.h \ + desktop-handles.h \ + desktop.h \ + display/curve.h \ + display/display-forward.h \ + display/nr-arena-forward.h \ + display/nr-arena-glyphs.h \ + display/nr-arena-group.h \ + display/nr-arena-item.h \ + document.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + inkscape.h \ + libavoid/geometry.h \ + libavoid/geomtypes.h \ + libavoid/shape.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-convex-hull.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix-ops.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-object.h \ + libnr/nr-pixblock.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate-ops.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + libnrtype/Layout-TNG.h \ + libnrtype/nrtype-forward.h \ + message.h \ + round.h \ + selection.h \ + sp-flowdiv.h \ + sp-flowregion.h \ + sp-flowtext.h \ + sp-item.h \ + sp-marker-loc.h \ + sp-object.h \ + sp-paint-server.h \ + sp-rect.h \ + sp-shape.h \ + sp-string.h \ + sp-use.h \ + style.h \ + svg/svg-length.h \ + text-tag-attributes.h \ + traits/reference.h \ + ui/view/edit-widget-interface.h \ + ui/view/view.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +sp-gradient-reference.o: \ + sp-gradient-reference.cpp \ + bad-uri-exception.h \ + forward.h \ + libnr/nr-forward.h \ + sp-gradient-fns.h \ + sp-gradient-reference.h \ + sp-gradient-spread.h \ + sp-gradient-units.h \ + uri-references.h + +sp-gradient.o: \ + sp-gradient.cpp \ + attributes.h \ + bad-uri-exception.h \ + color.h \ + composite-undo-stack-observer.h \ + decimal-round.h \ + display/nr-arena-forward.h \ + display/nr-gradient-gpl.h \ + document-private.h \ + document.h \ + dom/css.h \ + dom/dom.h \ + dom/domstring.h \ + dom/events.h \ + dom/smil.h \ + dom/stylesheets.h \ + dom/svg.h \ + dom/svgtypes.h \ + dom/uri.h \ + dom/views.h \ + enums.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + gradient-chemistry.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-gradient.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-div.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix-ops.h \ + libnr/nr-matrix-scale-ops.h \ + libnr/nr-matrix-translate-ops.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-pixblock.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-render.h \ + libnr/nr-rotate.h \ + libnr/nr-scale-translate-ops.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + macros.h \ + round.h \ + sp-defs.h \ + sp-gradient-fns.h \ + sp-gradient-reference.h \ + sp-gradient-spread.h \ + sp-gradient-units.h \ + sp-gradient-vector.h \ + sp-gradient.h \ + sp-item-group.h \ + sp-item.h \ + sp-linear-gradient-fns.h \ + sp-linear-gradient.h \ + sp-object.h \ + sp-paint-server.h \ + sp-radial-gradient-fns.h \ + sp-radial-gradient.h \ + sp-root.h \ + sp-stop-fns.h \ + sp-stop.h \ + streq.h \ + svg/css-ostringstream.h \ + svg/svg-length.h \ + traits/reference.h \ + undo-stack-observer.h \ + uri-references.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/event-fns.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +sp-guide.o: \ + sp-guide.cpp \ + attributes.h \ + decimal-round.h \ + display/display-forward.h \ + display/guideline.h \ + display/nr-arena-forward.h \ + display/sp-canvas.h \ + document.h \ + dom/css.h \ + dom/dom.h \ + dom/domstring.h \ + dom/events.h \ + dom/smil.h \ + dom/stylesheets.h \ + dom/svg.h \ + dom/svgtypes.h \ + dom/views.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + remove-last.h \ + round.h \ + sp-guide-attachment.h \ + sp-guide-constraint.h \ + sp-guide.h \ + sp-item-notify-moveto.h \ + sp-item.h \ + sp-object.h \ + traits/reference.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +sp-image.o: \ + sp-image.cpp \ + attributes.h \ + decimal-round.h \ + display/nr-arena-forward.h \ + display/nr-arena-image.h \ + display/nr-arena-item.h \ + document.h \ + enums.h \ + extension/extension-forward.h \ + extension/extension.h \ + extension/print.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + io/sys.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-object.h \ + libnr/nr-path.h \ + libnr/nr-pixblock.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + round.h \ + sp-image.h \ + sp-item.h \ + sp-object.h \ + svg/svg-length.h \ + traits/reference.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/node.h \ + xml/quote.h \ + xml/repr.h \ + xml/sp-css-attr.h + +sp-item-group.o: \ + sp-item-group.cpp \ + attributes.h \ + color.h \ + decimal-round.h \ + display/nr-arena-forward.h \ + display/nr-arena-group.h \ + display/nr-arena-item.h \ + document.h \ + dom/css.h \ + dom/dom.h \ + dom/domstring.h \ + dom/events.h \ + dom/smil.h \ + dom/stylesheets.h \ + dom/svg.h \ + dom/svgtypes.h \ + dom/views.h \ + enums.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix-ops.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-object.h \ + libnr/nr-pixblock.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + prefs-utils.h \ + round.h \ + sp-item-group.h \ + sp-item.h \ + sp-marker-loc.h \ + sp-object.h \ + sp-root.h \ + sp-use.h \ + style.h \ + svg/svg-length.h \ + traits/reference.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +sp-item-notify-moveto.o: \ + sp-item-notify-moveto.cpp \ + decimal-round.h \ + display/display-forward.h \ + display/nr-arena-forward.h \ + forward.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-translate-ops.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + round.h \ + sp-guide-attachment.h \ + sp-guide.h \ + sp-item-rm-unsatisfied-cns.h \ + sp-item.h \ + sp-object.h \ + traits/reference.h \ + util/forward-pointer-iterator.h \ + version.h + +sp-item-rm-unsatisfied-cns.o: \ + sp-item-rm-unsatisfied-cns.cpp \ + approx-equal.h \ + decimal-round.h \ + display/display-forward.h \ + display/nr-arena-forward.h \ + forward.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + remove-last.h \ + round.h \ + sp-guide-attachment.h \ + sp-guide-constraint.h \ + sp-guide.h \ + sp-item.h \ + sp-object.h \ + traits/reference.h \ + util/forward-pointer-iterator.h \ + version.h + +sp-item-transform.o: \ + sp-item-transform.cpp \ + decimal-round.h \ + display/nr-arena-forward.h \ + forward.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-ops.h \ + libnr/nr-matrix-rotate-ops.h \ + libnr/nr-matrix-scale-ops.h \ + libnr/nr-matrix-translate-ops.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + round.h \ + sp-item.h \ + sp-object.h \ + traits/reference.h \ + util/forward-pointer-iterator.h \ + version.h + +sp-item-update-cns.o: \ + sp-item-update-cns.cpp \ + decimal-round.h \ + display/display-forward.h \ + display/nr-arena-forward.h \ + forward.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + round.h \ + satisfied-guide-cns.h \ + sp-guide-attachment.h \ + sp-guide-constraint.h \ + sp-guide.h \ + sp-item.h \ + sp-object.h \ + traits/reference.h \ + util/forward-pointer-iterator.h \ + version.h + +sp-item.o: \ + sp-item.cpp \ + algorithms/find-last-if.h \ + attributes.h \ + bad-uri-exception.h \ + color.h \ + conn-avoid-ref.h \ + decimal-round.h \ + display/display-forward.h \ + display/nr-arena-forward.h \ + display/nr-arena-item.h \ + display/nr-arena.h \ + document.h \ + dom/css.h \ + dom/dom.h \ + dom/domstring.h \ + dom/events.h \ + dom/smil.h \ + dom/stylesheets.h \ + dom/svg.h \ + dom/svgtypes.h \ + dom/uri.h \ + dom/views.h \ + enums.h \ + extension/extension-forward.h \ + extension/extension.h \ + extension/print.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + gradient-chemistry.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-div.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix-ops.h \ + libnr/nr-matrix-scale-ops.h \ + libnr/nr-matrix-translate-ops.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-object.h \ + libnr/nr-path.h \ + libnr/nr-pixblock.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate-ops.h \ + libnr/nr-rotate.h \ + libnr/nr-scale-translate-ops.h \ + libnr/nr-scale.h \ + libnr/nr-translate-scale-ops.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + libnrtype/Layout-TNG.h \ + prefs-utils.h \ + round.h \ + sp-clippath.h \ + sp-gradient-fns.h \ + sp-gradient-spread.h \ + sp-gradient-units.h \ + sp-gradient-vector.h \ + sp-gradient.h \ + sp-item-group.h \ + sp-item-rm-unsatisfied-cns.h \ + sp-item.h \ + sp-marker-loc.h \ + sp-mask.h \ + sp-object-group.h \ + sp-object.h \ + sp-paint-server.h \ + sp-pattern.h \ + sp-rect.h \ + sp-root.h \ + sp-shape.h \ + sp-string.h \ + sp-text.h \ + sp-use.h \ + style.h \ + svg/svg-length.h \ + text-tag-attributes.h \ + traits/copy.h \ + traits/list-copy.h \ + traits/reference.h \ + uri-references.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + util/reverse-list.h \ + version.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +sp-line.o: \ + sp-line.cpp \ + attributes.h \ + color.h \ + decimal-round.h \ + display/curve.h \ + display/display-forward.h \ + display/nr-arena-forward.h \ + document.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + round.h \ + sp-item.h \ + sp-line.h \ + sp-marker-loc.h \ + sp-object.h \ + sp-shape.h \ + style.h \ + svg/svg-length.h \ + traits/reference.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +sp-marker.o: \ + sp-marker.cpp \ + attributes.h \ + bad-uri-exception.h \ + decimal-round.h \ + display/nr-arena-forward.h \ + display/nr-arena-group.h \ + display/nr-arena-item.h \ + document.h \ + dom/css.h \ + dom/dom.h \ + dom/domstring.h \ + dom/events.h \ + dom/smil.h \ + dom/stylesheets.h \ + dom/svg.h \ + dom/svgtypes.h \ + dom/views.h \ + enums.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix-ops.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-object.h \ + libnr/nr-pixblock.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate-fns.h \ + libnr/nr-rotate.h \ + libnr/nr-scale-matrix-ops.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + round.h \ + sp-item-group.h \ + sp-item.h \ + sp-marker-loc.h \ + sp-marker.h \ + sp-object.h \ + svg/svg-length.h \ + traits/reference.h \ + uri-references.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +sp-mask.o: \ + sp-mask.cpp \ + attributes.h \ + bad-uri-exception.h \ + decimal-round.h \ + display/nr-arena-forward.h \ + display/nr-arena-group.h \ + display/nr-arena-item.h \ + display/nr-arena.h \ + document.h \ + enums.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-object.h \ + libnr/nr-pixblock.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + round.h \ + sp-item.h \ + sp-mask.h \ + sp-object-group.h \ + sp-object.h \ + sp-paint-server.h \ + traits/reference.h \ + uri-references.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +sp-metadata.o: \ + sp-metadata.cpp \ + decimal-round.h \ + display/nr-arena-forward.h \ + document.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + round.h \ + sp-item-group.h \ + sp-item.h \ + sp-metadata.h \ + sp-object.h \ + traits/reference.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/node-iterators.h \ + xml/node.h + +sp-metrics.o: \ + sp-metrics.cpp \ + sp-metric.h \ + sp-metrics.h \ + unit-constants.h + +sp-namedview.o: \ + sp-namedview.cpp \ + attributes.h \ + decimal-round.h \ + desktop-events.h \ + desktop-handles.h \ + desktop.h \ + display/canvas-grid.h \ + display/display-forward.h \ + display/nr-arena-forward.h \ + display/sp-canvas.h \ + document.h \ + dom/css.h \ + dom/dom.h \ + dom/domstring.h \ + dom/events.h \ + dom/smil.h \ + dom/stylesheets.h \ + dom/svg.h \ + dom/svgtypes.h \ + dom/views.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + grid-snapper.h \ + guide-snapper.h \ + helper/helper-forward.h \ + helper/units.h \ + isnan.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + line-snapper.h \ + message.h \ + object-snapper.h \ + prefs-utils.h \ + round.h \ + snapped-point.h \ + snapper.h \ + sp-guide-attachment.h \ + sp-guide.h \ + sp-item-group.h \ + sp-item.h \ + sp-metric.h \ + sp-namedview.h \ + sp-object-group.h \ + sp-object.h \ + traits/reference.h \ + ui/view/edit-widget-interface.h \ + ui/view/view.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +sp-object-group.o: \ + sp-object-group.cpp \ + document.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-forward.h \ + sp-object-group.h \ + sp-object.h \ + traits/reference.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +sp-object-repr.o: \ + sp-object-repr.cpp \ + bad-uri-exception.h \ + decimal-round.h \ + display/display-forward.h \ + display/nr-arena-forward.h \ + document.h \ + enums.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libavoid/connector.h \ + libavoid/geometry.h \ + libavoid/geomtypes.h \ + libavoid/shape.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-ops.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-pixblock.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate-ops.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + libnrtype/Layout-TNG.h \ + media.h \ + round.h \ + sp-anchor.h \ + sp-clippath.h \ + sp-conn-end-pair.h \ + sp-defs.h \ + sp-ellipse.h \ + sp-flowdiv.h \ + sp-flowregion.h \ + sp-flowtext.h \ + sp-image.h \ + sp-item-group.h \ + sp-item.h \ + sp-line.h \ + sp-linear-gradient-fns.h \ + sp-marker-loc.h \ + sp-marker.h \ + sp-mask.h \ + sp-metadata.h \ + sp-object-group.h \ + sp-object.h \ + sp-offset.h \ + sp-paint-server.h \ + sp-path.h \ + sp-pattern.h \ + sp-polygon.h \ + sp-polyline.h \ + sp-radial-gradient-fns.h \ + sp-rect.h \ + sp-root.h \ + sp-shape.h \ + sp-spiral.h \ + sp-star.h \ + sp-stop-fns.h \ + sp-string.h \ + sp-style-elem.h \ + sp-symbol.h \ + sp-text.h \ + sp-textpath.h \ + sp-tspan.h \ + sp-use.h \ + svg/svg-length.h \ + text-tag-attributes.h \ + traits/reference.h \ + uri-references.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +sp-object.o: \ + sp-object.cpp \ + algorithms/longest-common-suffix.h \ + attributes.h \ + color.h \ + debug/event-tracker.h \ + debug/event.h \ + debug/logger.h \ + decimal-round.h \ + display/nr-arena-forward.h \ + document.h \ + enums.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + helper/sp-marshal.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + round.h \ + sp-item-group.h \ + sp-item.h \ + sp-marker-loc.h \ + sp-object-repr.h \ + sp-object.h \ + sp-root.h \ + streq.h \ + strneq.h \ + style.h \ + svg/svg-length.h \ + traits/reference.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + util/shared-c-string-ptr.h \ + version.h \ + xml/node-event-vector.h \ + xml/node-fns.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +sp-offset.o: \ + sp-offset.cpp \ + attributes.h \ + bad-uri-exception.h \ + decimal-round.h \ + display/curve.h \ + display/display-forward.h \ + display/nr-arena-forward.h \ + document.h \ + dom/css.h \ + dom/dom.h \ + dom/domstring.h \ + dom/events.h \ + dom/smil.h \ + dom/stylesheets.h \ + dom/svg.h \ + dom/svgtypes.h \ + dom/uri.h \ + dom/views.h \ + enums.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libavoid/geometry.h \ + libavoid/geomtypes.h \ + libavoid/shape.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/n-art-bpath.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix-ops.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-path-code.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate-ops.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + libnrtype/Layout-TNG.h \ + livarot/LivarotDefs.h \ + livarot/Path.h \ + livarot/livarot-forward.h \ + prefs-utils.h \ + round.h \ + sp-item.h \ + sp-marker-loc.h \ + sp-object.h \ + sp-offset.h \ + sp-shape.h \ + sp-string.h \ + sp-text.h \ + sp-use-reference.h \ + svg/svg-length.h \ + text-tag-attributes.h \ + traits/reference.h \ + uri-references.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +sp-paint-server.o: \ + sp-paint-server.cpp \ + decimal-round.h \ + forward.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-pixblock-pattern.h \ + libnr/nr-pixblock.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + round.h \ + sp-object.h \ + sp-paint-server.h \ + traits/reference.h \ + util/forward-pointer-iterator.h \ + version.h + +sp-path.o: \ + sp-path.cpp \ + attributes.h \ + decimal-round.h \ + display/curve.h \ + display/display-forward.h \ + display/nr-arena-forward.h \ + document.h \ + dom/css.h \ + dom/dom.h \ + dom/domstring.h \ + dom/events.h \ + dom/smil.h \ + dom/stylesheets.h \ + dom/svg.h \ + dom/svgtypes.h \ + dom/views.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libavoid/connector.h \ + libavoid/geometry.h \ + libavoid/geomtypes.h \ + libavoid/shape.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/n-art-bpath.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-path-code.h \ + libnr/nr-path.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + round.h \ + sp-conn-end-pair.h \ + sp-item.h \ + sp-marker-loc.h \ + sp-object.h \ + sp-path.h \ + sp-shape.h \ + traits/reference.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +sp-pattern.o: \ + sp-pattern.cpp \ + attributes.h \ + bad-uri-exception.h \ + composite-undo-stack-observer.h \ + decimal-round.h \ + display/nr-arena-forward.h \ + display/nr-arena-group.h \ + display/nr-arena-item.h \ + display/nr-arena.h \ + document-private.h \ + document.h \ + dom/css.h \ + dom/dom.h \ + dom/domstring.h \ + dom/events.h \ + dom/smil.h \ + dom/stylesheets.h \ + dom/svg.h \ + dom/svgtypes.h \ + dom/uri.h \ + dom/views.h \ + enums.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix-ops.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-object.h \ + libnr/nr-pixblock.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate-matrix-ops.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + macros.h \ + round.h \ + sp-defs.h \ + sp-item-group.h \ + sp-item.h \ + sp-object.h \ + sp-paint-server.h \ + sp-pattern.h \ + sp-root.h \ + svg/svg-length.h \ + traits/reference.h \ + undo-stack-observer.h \ + uri-references.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/event-fns.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +sp-polygon.o: \ + sp-polygon.cpp \ + attributes.h \ + decimal-round.h \ + display/curve.h \ + display/display-forward.h \ + display/nr-arena-forward.h \ + document.h \ + dom/dom.h \ + dom/domstream.h \ + dom/domstring.h \ + dom/stringstream.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/n-art-bpath.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-path-code.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + round.h \ + sp-item.h \ + sp-marker-loc.h \ + sp-object.h \ + sp-polygon.h \ + sp-shape.h \ + traits/reference.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +sp-polyline.o: \ + sp-polyline.cpp \ + attributes.h \ + decimal-round.h \ + display/curve.h \ + display/display-forward.h \ + display/nr-arena-forward.h \ + document.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + round.h \ + sp-item.h \ + sp-marker-loc.h \ + sp-object.h \ + sp-polyline.h \ + sp-shape.h \ + traits/reference.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +sp-rect.o: \ + sp-rect.cpp \ + attributes.h \ + color.h \ + decimal-round.h \ + display/curve.h \ + display/display-forward.h \ + display/nr-arena-forward.h \ + document.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-div.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + round.h \ + sp-item.h \ + sp-marker-loc.h \ + sp-object.h \ + sp-rect.h \ + sp-shape.h \ + style.h \ + svg/svg-length.h \ + traits/reference.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +sp-root.o: \ + sp-root.cpp \ + attributes.h \ + decimal-round.h \ + display/nr-arena-forward.h \ + display/nr-arena-group.h \ + display/nr-arena-item.h \ + document.h \ + dom/css.h \ + dom/dom.h \ + dom/domstream.h \ + dom/domstring.h \ + dom/events.h \ + dom/smil.h \ + dom/stringstream.h \ + dom/stylesheets.h \ + dom/svg.h \ + dom/svgtypes.h \ + dom/views.h \ + enums.h \ + extension/extension-forward.h \ + extension/extension.h \ + extension/print.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + inkscape_version.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix-ops.h \ + libnr/nr-matrix-translate-ops.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-object.h \ + libnr/nr-path.h \ + libnr/nr-pixblock.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale-ops.h \ + libnr/nr-scale.h \ + libnr/nr-translate-scale-ops.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + round.h \ + sp-defs.h \ + sp-item-group.h \ + sp-item.h \ + sp-object.h \ + sp-root.h \ + svg/svg-length.h \ + traits/reference.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +sp-shape.o: \ + sp-shape.cpp \ + bad-uri-exception.h \ + color.h \ + decimal-round.h \ + display/canvas-bpath.h \ + display/curve.h \ + display/display-forward.h \ + display/nr-arena-forward.h \ + display/nr-arena-item.h \ + display/nr-arena-shape.h \ + display/sp-canvas.h \ + document.h \ + enums.h \ + extension/extension-forward.h \ + extension/extension.h \ + extension/print.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + gnuc-attribute.h \ + libavoid/connector.h \ + libavoid/geometry.h \ + libavoid/geomtypes.h \ + libavoid/shape.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/n-art-bpath.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix-ops.h \ + libnr/nr-matrix-translate-ops.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-object.h \ + libnr/nr-path-code.h \ + libnr/nr-path.h \ + libnr/nr-pixblock.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale-matrix-ops.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + macros.h \ + marker-status.h \ + prefs-utils.h \ + round.h \ + sp-conn-end-pair.h \ + sp-item-group.h \ + sp-item.h \ + sp-marker-loc.h \ + sp-marker.h \ + sp-object.h \ + sp-paint-server.h \ + sp-path.h \ + sp-shape.h \ + style.h \ + svg/svg-length.h \ + traits/reference.h \ + uri-references.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +sp-skeleton.o: \ + sp-skeleton.cpp \ + attributes.h \ + document.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-forward.h \ + sp-object.h \ + sp-skeleton.h \ + traits/reference.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +sp-spiral.o: \ + sp-spiral.cpp \ + attributes.h \ + decimal-round.h \ + display/bezier-utils.h \ + display/curve.h \ + display/display-forward.h \ + display/nr-arena-forward.h \ + document.h \ + dom/css.h \ + dom/dom.h \ + dom/domstring.h \ + dom/events.h \ + dom/smil.h \ + dom/stylesheets.h \ + dom/svg.h \ + dom/svgtypes.h \ + dom/views.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + round.h \ + sp-item.h \ + sp-marker-loc.h \ + sp-object.h \ + sp-shape.h \ + sp-spiral.h \ + traits/reference.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +sp-star.o: \ + sp-star.cpp \ + attributes.h \ + decimal-round.h \ + display/curve.h \ + display/display-forward.h \ + display/nr-arena-forward.h \ + document.h \ + dom/css.h \ + dom/dom.h \ + dom/domstring.h \ + dom/events.h \ + dom/smil.h \ + dom/stylesheets.h \ + dom/svg.h \ + dom/svgtypes.h \ + dom/views.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + round.h \ + sp-item.h \ + sp-marker-loc.h \ + sp-object.h \ + sp-polygon.h \ + sp-shape.h \ + sp-star.h \ + traits/reference.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +sp-string.o: \ + sp-string.cpp \ + document.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-forward.h \ + sp-object.h \ + sp-string.h \ + traits/reference.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +sp-style-elem-test.o: \ + sp-style-elem-test.cpp \ + attributes.h \ + document.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + inkscape-private.h \ + inkscape.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-forward.h \ + media.h \ + sp-object.h \ + sp-style-elem.h \ + streq.h \ + traits/reference.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +sp-style-elem.o: \ + sp-style-elem.cpp \ + attributes.h \ + document.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-doc-handler.h \ + libcroco/cr-input.h \ + libcroco/cr-num.h \ + libcroco/cr-parser.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-tknzr.h \ + libcroco/cr-token.h \ + libcroco/cr-utils.h \ + libnr/nr-forward.h \ + media.h \ + sp-object.h \ + sp-style-elem.h \ + traits/reference.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/node-event-vector.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +sp-symbol.o: \ + sp-symbol.cpp \ + attributes.h \ + decimal-round.h \ + display/nr-arena-forward.h \ + display/nr-arena-group.h \ + display/nr-arena-item.h \ + document.h \ + enums.h \ + extension/extension-forward.h \ + extension/extension.h \ + extension/print.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix-ops.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-object.h \ + libnr/nr-path.h \ + libnr/nr-pixblock.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + round.h \ + sp-item-group.h \ + sp-item.h \ + sp-object.h \ + sp-symbol.h \ + svg/svg-length.h \ + traits/reference.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +sp-text.o: \ + sp-text.cpp \ + attributes.h \ + color.h \ + decimal-round.h \ + desktop-handles.h \ + display/curve.h \ + display/display-forward.h \ + display/nr-arena-forward.h \ + display/nr-arena-glyphs.h \ + display/nr-arena-group.h \ + display/nr-arena-item.h \ + document.h \ + dom/css.h \ + dom/dom.h \ + dom/domstream.h \ + dom/domstring.h \ + dom/events.h \ + dom/smil.h \ + dom/stringstream.h \ + dom/stylesheets.h \ + dom/svg.h \ + dom/svgtypes.h \ + dom/views.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + grid-snapper.h \ + guide-snapper.h \ + helper/helper-forward.h \ + inkscape.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix-ops.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-object.h \ + libnr/nr-pixblock.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate-ops.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + libnrtype/FontFactory.h \ + libnrtype/Layout-TNG.h \ + libnrtype/font-instance.h \ + libnrtype/font-style-to-pos.h \ + libnrtype/font-style.h \ + libnrtype/nr-type-pos-def.h \ + libnrtype/nr-type-primitives.h \ + libnrtype/nrtype-forward.h \ + line-snapper.h \ + livarot/LivarotDefs.h \ + livarot/livarot-forward.h \ + mod360.h \ + object-snapper.h \ + require-config.h \ + round.h \ + snapped-point.h \ + snapper.h \ + sp-item.h \ + sp-marker-loc.h \ + sp-metric.h \ + sp-metrics.h \ + sp-namedview.h \ + sp-object-group.h \ + sp-object.h \ + sp-paint-server.h \ + sp-string.h \ + sp-text.h \ + sp-textpath.h \ + sp-tspan.h \ + style.h \ + svg/svg-length.h \ + text-editing.h \ + text-tag-attributes.h \ + traits/reference.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/node.h \ + xml/quote.h \ + xml/repr.h \ + xml/sp-css-attr.h + +sp-tspan.o: \ + sp-tspan.cpp \ + attributes.h \ + bad-uri-exception.h \ + decimal-round.h \ + display/nr-arena-forward.h \ + document.h \ + dom/dom.h \ + dom/domstream.h \ + dom/domstring.h \ + dom/stringstream.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-ops.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate-ops.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + libnrtype/Layout-TNG.h \ + livarot/LivarotDefs.h \ + livarot/Path.h \ + livarot/livarot-forward.h \ + round.h \ + sp-item.h \ + sp-object.h \ + sp-string.h \ + sp-text.h \ + sp-textpath.h \ + sp-tspan.h \ + sp-use-reference.h \ + svg/svg-length.h \ + text-tag-attributes.h \ + traits/reference.h \ + uri-references.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +sp-use-reference.o: \ + sp-use-reference.cpp \ + bad-uri-exception.h \ + decimal-round.h \ + display/curve.h \ + display/display-forward.h \ + display/nr-arena-forward.h \ + dom/dom.h \ + dom/domstring.h \ + dom/uri.h \ + enums.h \ + forward.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-ops.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate-ops.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + libnrtype/Layout-TNG.h \ + livarot/LivarotDefs.h \ + livarot/Path.h \ + livarot/livarot-forward.h \ + prefs-utils.h \ + round.h \ + sp-item.h \ + sp-marker-loc.h \ + sp-object.h \ + sp-shape.h \ + sp-string.h \ + sp-text.h \ + sp-use-reference.h \ + svg/svg-length.h \ + text-tag-attributes.h \ + traits/reference.h \ + uri-references.h \ + util/forward-pointer-iterator.h \ + version.h + +sp-use.o: \ + sp-use.cpp \ + attributes.h \ + bad-uri-exception.h \ + color.h \ + decimal-round.h \ + display/nr-arena-forward.h \ + display/nr-arena-group.h \ + display/nr-arena-item.h \ + document.h \ + dom/dom.h \ + dom/domstring.h \ + dom/uri.h \ + enums.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix-ops.h \ + libnr/nr-matrix-translate-ops.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-object.h \ + libnr/nr-pixblock.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + prefs-utils.h \ + round.h \ + sp-flowregion.h \ + sp-item-group.h \ + sp-item.h \ + sp-marker-loc.h \ + sp-object-repr.h \ + sp-object.h \ + sp-symbol.h \ + sp-use-reference.h \ + sp-use.h \ + style.h \ + svg/svg-length.h \ + traits/reference.h \ + uri-references.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +spiral-context.o: \ + spiral-context.cpp \ + context-fns.h \ + decimal-round.h \ + desktop-affine.h \ + desktop-handles.h \ + desktop-style.h \ + desktop.h \ + display/display-forward.h \ + display/nr-arena-forward.h \ + display/sp-canvas.h \ + document.h \ + event-context.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + grid-snapper.h \ + guide-snapper.h \ + helper/helper-forward.h \ + knot-enums.h \ + knotholder.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-convex-hull.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + line-snapper.h \ + macros.h \ + message-context.h \ + message.h \ + object-edit.h \ + object-snapper.h \ + prefs-utils.h \ + round.h \ + selection.h \ + snap.h \ + snapped-point.h \ + snapper.h \ + sp-item.h \ + sp-marker-loc.h \ + sp-metric.h \ + sp-metrics.h \ + sp-namedview.h \ + sp-object-group.h \ + sp-object.h \ + sp-shape.h \ + sp-spiral.h \ + spiral-context.h \ + traits/reference.h \ + ui/view/edit-widget-interface.h \ + ui/view/view.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/node-event-vector.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +splivarot.o: \ + splivarot.cpp \ + color.h \ + decimal-round.h \ + desktop-handles.h \ + desktop.h \ + display/canvas-bpath.h \ + display/curve.h \ + display/display-forward.h \ + display/nr-arena-forward.h \ + display/sp-canvas.h \ + document.h \ + dom/css.h \ + dom/dom.h \ + dom/domstring.h \ + dom/events.h \ + dom/smil.h \ + dom/stylesheets.h \ + dom/svg.h \ + dom/svgtypes.h \ + dom/views.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + inkscape.h \ + libavoid/connector.h \ + libavoid/geometry.h \ + libavoid/geomtypes.h \ + libavoid/shape.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/n-art-bpath.h \ + libnr/nr-convex-hull.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix-ops.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-path-code.h \ + libnr/nr-path.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate-ops.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + libnrtype/Layout-TNG.h \ + livarot/LivarotDefs.h \ + livarot/Path.h \ + livarot/livarot-forward.h \ + message-stack.h \ + message.h \ + prefs-utils.h \ + round.h \ + selection.h \ + sp-conn-end-pair.h \ + sp-item-group.h \ + sp-item.h \ + sp-marker-loc.h \ + sp-object.h \ + sp-path.h \ + sp-shape.h \ + sp-string.h \ + sp-text.h \ + style.h \ + svg/svg-length.h \ + text-tag-attributes.h \ + traits/reference.h \ + ui/view/edit-widget-interface.h \ + ui/view/view.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/node.h \ + xml/repr-sorting.h \ + xml/repr.h \ + xml/sp-css-attr.h + +star-context.o: \ + star-context.cpp \ + context-fns.h \ + decimal-round.h \ + desktop-affine.h \ + desktop-handles.h \ + desktop-style.h \ + desktop.h \ + display/display-forward.h \ + display/nr-arena-forward.h \ + display/sp-canvas.h \ + document.h \ + event-context.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + grid-snapper.h \ + guide-snapper.h \ + helper/helper-forward.h \ + knot-enums.h \ + knotholder.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-convex-hull.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + line-snapper.h \ + macros.h \ + message-context.h \ + message.h \ + object-edit.h \ + object-snapper.h \ + prefs-utils.h \ + round.h \ + selection.h \ + snap.h \ + snapped-point.h \ + snapper.h \ + sp-item.h \ + sp-marker-loc.h \ + sp-metric.h \ + sp-metrics.h \ + sp-namedview.h \ + sp-object-group.h \ + sp-object.h \ + sp-polygon.h \ + sp-shape.h \ + sp-star.h \ + star-context.h \ + traits/reference.h \ + ui/view/edit-widget-interface.h \ + ui/view/view.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/node-event-vector.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +streams-gzip.o: \ + streams-gzip.cpp \ + forward.h \ + streams-gzip.h \ + streams-handles.h \ + streams-zlib.h + +streams-handles.o: \ + streams-handles.cpp \ + dom/dom.h \ + dom/domstring.h \ + dom/uri.h \ + forward.h \ + streams-handles.h + +streams-jar.o: \ + streams-jar.cpp \ + forward.h \ + streams-handles.h \ + streams-jar.h \ + streams-zlib.h + +streams-zlib.o: \ + streams-zlib.cpp \ + forward.h \ + streams-handles.h \ + streams-zlib.h + +style-test.o: \ + style-test.cpp \ + color.h \ + forward.h \ + sp-marker-loc.h \ + streq.h \ + strneq.h \ + style.h + +style.o: \ + style.cpp \ + attributes.h \ + bad-uri-exception.h \ + color.h \ + decimal-round.h \ + display/canvas-bpath.h \ + display/sp-canvas.h \ + document.h \ + dom/css.h \ + dom/dom.h \ + dom/domstring.h \ + dom/events.h \ + dom/smil.h \ + dom/stylesheets.h \ + dom/svg.h \ + dom/svgtypes.h \ + dom/views.h \ + extract-uri.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + gnuc-attribute.h \ + isnan.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-fonts.h \ + libcroco/cr-node-iface.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-prop-list.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-sel-eng.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-style.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-pixblock.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + marker-status.h \ + round.h \ + sp-marker-loc.h \ + sp-object.h \ + sp-paint-server.h \ + streq.h \ + strneq.h \ + style.h \ + svg/css-ostringstream.h \ + traits/reference.h \ + unit-constants.h \ + uri-references.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/croco-node-iface.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +svg-view-widget.o: \ + svg-view-widget.cpp \ + decimal-round.h \ + display/canvas-arena.h \ + display/display-forward.h \ + display/nr-arena-forward.h \ + display/nr-arena-item.h \ + display/sp-canvas.h \ + document.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-object.h \ + libnr/nr-pixblock.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + message.h \ + round.h \ + svg-view-widget.h \ + svg-view.h \ + ui/view/view-widget.h \ + ui/view/view.h + +svg-view.o: \ + svg-view.cpp \ + decimal-round.h \ + display/canvas-arena.h \ + display/display-forward.h \ + display/nr-arena-forward.h \ + display/nr-arena-item.h \ + display/sp-canvas.h \ + document.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-object.h \ + libnr/nr-pixblock.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + message.h \ + round.h \ + sp-item.h \ + sp-object.h \ + svg-view.h \ + traits/reference.h \ + ui/view/view.h \ + util/forward-pointer-iterator.h \ + version.h + +svg/css-ostringstream.o: \ + svg/css-ostringstream.cpp \ + svg/css-ostringstream.h \ + svg/strip-trailing-zeros.h + +svg/gnome-canvas-bpath-util.o: \ + svg/gnome-canvas-bpath-util.cpp \ + decimal-round.h \ + libnr/n-art-bpath.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-path-code.h \ + libnr/nr-point.h \ + round.h \ + svg/gnome-canvas-bpath-util.h + +svg/itos.o: \ + svg/itos.cpp + +svg/round.o: \ + svg/round.cpp + +svg/stringstream.o: \ + svg/stringstream.cpp \ + dom/dom.h \ + dom/domstream.h \ + dom/domstring.h \ + dom/stringstream.h + +svg/strip-trailing-zeros.o: \ + svg/strip-trailing-zeros.cpp \ + svg/strip-trailing-zeros.h + +svg/svg-affine.o: \ + svg/svg-affine.cpp \ + decimal-round.h \ + dom/css.h \ + dom/dom.h \ + dom/domstring.h \ + dom/events.h \ + dom/smil.h \ + dom/stylesheets.h \ + dom/svg.h \ + dom/svgtypes.h \ + dom/views.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix-ops.h \ + libnr/nr-matrix-translate-ops.h \ + libnr/nr-matrix.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rotate-fns.h \ + libnr/nr-rotate-matrix-ops.h \ + libnr/nr-rotate.h \ + libnr/nr-scale-matrix-ops.h \ + libnr/nr-scale.h \ + libnr/nr-translate-matrix-ops.h \ + libnr/nr-translate-rotate-ops.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + round.h + +svg/svg-color.o: \ + svg/svg-color.cpp \ + dom/css.h \ + dom/dom.h \ + dom/domstring.h \ + dom/events.h \ + dom/smil.h \ + dom/stylesheets.h \ + dom/svg.h \ + dom/svgtypes.h \ + dom/views.h + +svg/svg-length.o: \ + svg/svg-length.cpp \ + dom/css.h \ + dom/dom.h \ + dom/domstream.h \ + dom/domstring.h \ + dom/events.h \ + dom/smil.h \ + dom/stringstream.h \ + dom/stylesheets.h \ + dom/svg.h \ + dom/svgtypes.h \ + dom/views.h \ + unit-constants.h + +svg/svg-path.o: \ + svg/svg-path.cpp \ + decimal-round.h \ + dom/dom.h \ + dom/domstream.h \ + dom/domstring.h \ + dom/stringstream.h \ + libnr/n-art-bpath.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-path-code.h \ + libnr/nr-point.h \ + round.h \ + svg/gnome-canvas-bpath-util.h + +text-chemistry.o: \ + text-chemistry.cpp \ + decimal-round.h \ + desktop-handles.h \ + display/display-forward.h \ + display/nr-arena-forward.h \ + document.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + inkscape.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-convex-hull.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix-ops.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate-ops.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + libnrtype/Layout-TNG.h \ + message-stack.h \ + message.h \ + round.h \ + selection.h \ + sp-flowdiv.h \ + sp-flowregion.h \ + sp-flowtext.h \ + sp-item.h \ + sp-marker-loc.h \ + sp-object.h \ + sp-rect.h \ + sp-shape.h \ + sp-string.h \ + sp-text.h \ + sp-textpath.h \ + svg/svg-length.h \ + text-editing.h \ + text-tag-attributes.h \ + traits/reference.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +text-context.o: \ + text-context.cpp \ + color.h \ + context-fns.h \ + decimal-round.h \ + desktop-affine.h \ + desktop-handles.h \ + desktop-style.h \ + desktop.h \ + display/display-forward.h \ + display/nr-arena-forward.h \ + display/sodipodi-ctrlrect.h \ + display/sp-canvas.h \ + display/sp-ctrlline.h \ + display/sp-ctrlquadr.h \ + document.h \ + event-context.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + grid-snapper.h \ + guide-snapper.h \ + helper/helper-forward.h \ + knot-enums.h \ + knotholder.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-convex-hull.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix-ops.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate-ops.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + libnrtype/Layout-TNG.h \ + line-snapper.h \ + macros.h \ + message-context.h \ + message-stack.h \ + message.h \ + object-edit.h \ + object-snapper.h \ + prefs-utils.h \ + round.h \ + rubberband.h \ + selection.h \ + snapped-point.h \ + snapper.h \ + sp-flowtext.h \ + sp-item.h \ + sp-marker-loc.h \ + sp-metric.h \ + sp-metrics.h \ + sp-namedview.h \ + sp-object-group.h \ + sp-object.h \ + sp-string.h \ + sp-text.h \ + style.h \ + svg/svg-length.h \ + text-context.h \ + text-editing.h \ + text-tag-attributes.h \ + traits/reference.h \ + ui/view/edit-widget-interface.h \ + ui/view/view.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/node-event-vector.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +text-editing.o: \ + text-editing.cpp \ + color.h \ + decimal-round.h \ + desktop.h \ + display/nr-arena-forward.h \ + document.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix-ops.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate-ops.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + libnrtype/Layout-TNG.h \ + message.h \ + round.h \ + sp-flowdiv.h \ + sp-flowregion.h \ + sp-flowtext.h \ + sp-item.h \ + sp-marker-loc.h \ + sp-object.h \ + sp-string.h \ + sp-text.h \ + sp-textpath.h \ + sp-tspan.h \ + style.h \ + svg/svg-length.h \ + text-editing.h \ + text-tag-attributes.h \ + traits/reference.h \ + ui/view/edit-widget-interface.h \ + ui/view/view.h \ + unit-constants.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + util/shared-c-string-ptr.h \ + version.h \ + xml/attribute-record.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +tools-switch.o: \ + tools-switch.cpp \ + arc-context.h \ + connector-context.h \ + decimal-round.h \ + desktop-handles.h \ + desktop.h \ + display/curve.h \ + display/display-forward.h \ + display/nr-arena-forward.h \ + document.h \ + draw-context.h \ + dropper-context.h \ + dyna-draw-context.h \ + event-context.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + gradient-context.h \ + inkscape-private.h \ + inkscape.h \ + libavoid/connector.h \ + libavoid/geometry.h \ + libavoid/geomtypes.h \ + libavoid/shape.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix-ops.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-path-code.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate-ops.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + libnrtype/Layout-TNG.h \ + message-context.h \ + message.h \ + node-context.h \ + nodepath.h \ + pen-context.h \ + pencil-context.h \ + rect-context.h \ + round.h \ + select-context.h \ + sp-conn-end-pair.h \ + sp-ellipse.h \ + sp-flowtext.h \ + sp-item.h \ + sp-marker-loc.h \ + sp-object.h \ + sp-path.h \ + sp-polygon.h \ + sp-rect.h \ + sp-shape.h \ + sp-spiral.h \ + sp-star.h \ + sp-string.h \ + sp-text.h \ + spiral-context.h \ + star-context.h \ + svg/svg-length.h \ + text-context.h \ + text-tag-attributes.h \ + tools-switch.h \ + traits/reference.h \ + ui/view/edit-widget-interface.h \ + ui/view/view.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h \ + zoom-context.h + +trace/filterset.o: \ + trace/filterset.cpp \ + trace/filterset.h \ + trace/imagemap-gdk.h \ + trace/imagemap.h + +trace/imagemap-gdk.o: \ + trace/imagemap-gdk.cpp \ + trace/imagemap-gdk.h \ + trace/imagemap.h + +trace/imagemap.o: \ + trace/imagemap.cpp \ + io/sys.h \ + trace/imagemap.h + +trace/potrace/curve.o: \ + trace/potrace/curve.cpp \ + decimal-round.h \ + display/curve.h \ + libnr/n-art-bpath.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-path-code.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate-ops.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + round.h + +trace/potrace/decompose.o: \ + trace/potrace/decompose.cpp \ + decimal-round.h \ + display/curve.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-point.h \ + round.h \ + trace/potrace/bitmap.h \ + trace/potrace/decompose.h \ + trace/potrace/lists.h \ + trace/potrace/potracelib.h \ + trace/potrace/progress.h + +trace/potrace/greymap.o: \ + trace/potrace/greymap.cpp \ + trace/potrace/greymap.h + +trace/potrace/inkscape-potrace.o: \ + trace/potrace/inkscape-potrace.cpp \ + decimal-round.h \ + desktop-handles.h \ + display/curve.h \ + display/display-forward.h \ + display/nr-arena-forward.h \ + dom/dom.h \ + dom/domstream.h \ + dom/domstring.h \ + dom/stringstream.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + inkscape.h \ + libavoid/connector.h \ + libavoid/geometry.h \ + libavoid/geomtypes.h \ + libavoid/shape.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + message-stack.h \ + message.h \ + round.h \ + sp-conn-end-pair.h \ + sp-item.h \ + sp-marker-loc.h \ + sp-object.h \ + sp-path.h \ + sp-shape.h \ + trace/filterset.h \ + trace/imagemap-gdk.h \ + trace/imagemap.h \ + trace/potrace/bitmap.h \ + trace/potrace/inkscape-potrace.h \ + trace/potrace/potracelib.h \ + trace/potrace/progress.h \ + trace/potrace/trace.h \ + traits/reference.h \ + util/forward-pointer-iterator.h \ + version.h + +trace/potrace/potracelib.o: \ + trace/potrace/potracelib.cpp \ + decimal-round.h \ + display/curve.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-point.h \ + round.h \ + trace/potrace/decompose.h \ + trace/potrace/potracelib.h \ + trace/potrace/progress.h \ + trace/potrace/trace.h + +trace/potrace/render.o: \ + trace/potrace/render.cpp \ + trace/potrace/auxiliary.h \ + trace/potrace/greymap.h \ + trace/potrace/potracelib.h \ + trace/potrace/render.h + +trace/potrace/trace.o: \ + trace/potrace/trace.cpp \ + decimal-round.h \ + display/curve.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-point.h \ + round.h \ + trace/potrace/lists.h \ + trace/potrace/progress.h + +trace/trace.o: \ + trace/trace.cpp \ + decimal-round.h \ + display/curve.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-point.h \ + round.h \ + trace/potrace/lists.h \ + trace/potrace/progress.h + +ui/dialog/aboutbox.o: \ + ui/dialog/aboutbox.cpp \ + decimal-round.h \ + display/display-forward.h \ + display/nr-arena-forward.h \ + document.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + inkscape_version.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-ops.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate-ops.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + libnrtype/Layout-TNG.h \ + path-prefix.h \ + prefix.h \ + require-config.h \ + round.h \ + sp-item.h \ + sp-object.h \ + sp-string.h \ + sp-text.h \ + svg-view-widget.h \ + svg/svg-length.h \ + text-editing.h \ + text-tag-attributes.h \ + traits/reference.h \ + ui/dialog/aboutbox.h \ + ui/dialog/dialog.h \ + ui/stock.h \ + ui/view/view-widget.h \ + util/forward-pointer-iterator.h \ + version.h + +ui/dialog/align-and-distribute.o: \ + ui/dialog/align-and-distribute.cpp \ + decimal-round.h \ + desktop-handles.h \ + dialogs/unclump.h \ + display/display-forward.h \ + display/nr-arena-forward.h \ + document.h \ + enums.h \ + event-context.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + helper/helper-forward.h \ + inkscape.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-convex-hull.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-ops.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-path-code.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate-ops.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + libnrtype/Layout-TNG.h \ + macros.h \ + node-context.h \ + nodepath.h \ + prefs-utils.h \ + removeoverlap/removeoverlap.h \ + require-config.h \ + round.h \ + selection.h \ + sp-flowtext.h \ + sp-item-transform.h \ + sp-item.h \ + sp-object.h \ + sp-string.h \ + sp-text.h \ + svg/svg-length.h \ + text-editing.h \ + text-tag-attributes.h \ + tools-switch.h \ + traits/reference.h \ + ui/dialog/align-and-distribute.h \ + ui/dialog/dialog.h \ + ui/widget/notebook-page.h \ + util/forward-pointer-iterator.h \ + util/glib-list-iterators.h \ + util/list.h \ + verbs.h \ + version.h \ + widgets/icon.h + +ui/dialog/dialog-manager.o: \ + ui/dialog/dialog-manager.cpp \ + application/application.h \ + decimal-round.h \ + dialogs/export.h \ + dialogs/find.h \ + dialogs/tiledialog.h \ + forward.h \ + helper/helper-forward.h \ + helper/unit-menu.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + require-config.h \ + round.h \ + ui/dialog/align-and-distribute.h \ + ui/dialog/dialog-manager.h \ + ui/dialog/dialog.h \ + ui/dialog/document-metadata.h \ + ui/dialog/document-properties.h \ + ui/dialog/extension-editor.h \ + ui/dialog/fill-and-stroke.h \ + ui/dialog/inkscape-preferences.h \ + ui/dialog/layer-editor.h \ + ui/dialog/memory.h \ + ui/dialog/messages.h \ + ui/dialog/scriptdialog.h \ + ui/dialog/session-player.h \ + ui/dialog/text-properties.h \ + ui/dialog/tracedialog.h \ + ui/dialog/transformation.h \ + ui/dialog/whiteboard-connect.h \ + ui/dialog/whiteboard-sharewithchat.h \ + ui/dialog/whiteboard-sharewithuser.h \ + ui/dialog/xml-editor.h \ + ui/widget/button.h \ + ui/widget/icon-widget.h \ + ui/widget/imageicon.h \ + ui/widget/labelled.h \ + ui/widget/licensor.h \ + ui/widget/notebook-page.h \ + ui/widget/page-sizer.h \ + ui/widget/preferences-widget.h \ + ui/widget/registered-widget.h \ + ui/widget/registry.h \ + ui/widget/scalar-unit.h \ + ui/widget/scalar.h \ + ui/widget/tolerance-slider.h \ + verbs.h + +ui/dialog/dialog.o: \ + ui/dialog/dialog.cpp \ + application/app-prototype.h \ + application/application.h \ + application/editor.h \ + decimal-round.h \ + desktop-handles.h \ + desktop.h \ + dialogs/dialog-events.h \ + display/display-forward.h \ + event-context.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + helper/helper-forward.h \ + inkscape.h \ + interface.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + message.h \ + prefs-utils.h \ + require-config.h \ + round.h \ + shortcuts.h \ + ui/dialog/dialog-manager.h \ + ui/dialog/dialog.h \ + ui/stock.h \ + ui/view/edit-widget-interface.h \ + ui/view/view.h \ + verbs.h + +ui/dialog/document-metadata.o: \ + ui/dialog/document-metadata.cpp \ + decimal-round.h \ + desktop-handles.h \ + desktop.h \ + dialogs/rdf.h \ + display/display-forward.h \ + document.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + grid-snapper.h \ + guide-snapper.h \ + helper/helper-forward.h \ + inkscape.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + line-snapper.h \ + message.h \ + object-snapper.h \ + require-config.h \ + round.h \ + snapped-point.h \ + snapper.h \ + sp-metric.h \ + sp-namedview.h \ + sp-object-group.h \ + sp-object.h \ + traits/reference.h \ + ui/dialog/dialog.h \ + ui/dialog/document-metadata.h \ + ui/view/edit-widget-interface.h \ + ui/view/view.h \ + ui/widget/entity-entry.h \ + ui/widget/licensor.h \ + ui/widget/notebook-page.h \ + ui/widget/registry.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + verbs.h \ + version.h \ + xml/node-event-vector.h \ + xml/node.h + +ui/dialog/document-properties.o: \ + ui/dialog/document-properties.cpp \ + decimal-round.h \ + desktop-handles.h \ + desktop.h \ + display/display-forward.h \ + document.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + grid-snapper.h \ + guide-snapper.h \ + helper/helper-forward.h \ + helper/unit-menu.h \ + helper/units.h \ + inkscape.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + line-snapper.h \ + message.h \ + object-snapper.h \ + require-config.h \ + round.h \ + snapped-point.h \ + snapper.h \ + sp-metric.h \ + sp-namedview.h \ + sp-object-group.h \ + sp-object.h \ + traits/reference.h \ + ui/dialog/dialog.h \ + ui/dialog/document-properties.h \ + ui/view/edit-widget-interface.h \ + ui/view/view.h \ + ui/widget/button.h \ + ui/widget/color-picker.h \ + ui/widget/color-preview.h \ + ui/widget/labelled.h \ + ui/widget/notebook-page.h \ + ui/widget/page-sizer.h \ + ui/widget/registered-widget.h \ + ui/widget/registry.h \ + ui/widget/scalar-unit.h \ + ui/widget/scalar.h \ + ui/widget/tolerance-slider.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + verbs.h \ + version.h \ + xml/node-event-vector.h \ + xml/node.h + +ui/dialog/export.o: \ + ui/dialog/export.cpp \ + decimal-round.h \ + desktop-handles.h \ + dialogs/dialog-events.h \ + display/display-forward.h \ + display/nr-arena-forward.h \ + document.h \ + extension/db.h \ + extension/extension-forward.h \ + extension/extension.h \ + extension/output.h \ + file.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + grid-snapper.h \ + guide-snapper.h \ + helper/helper-forward.h \ + helper/unit-menu.h \ + helper/units.h \ + helper/window.h \ + inkscape-private.h \ + inkscape.h \ + interface.h \ + io/sys.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-convex-hull.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + line-snapper.h \ + macros.h \ + object-snapper.h \ + prefs-utils.h \ + require-config.h \ + round.h \ + selection.h \ + snapped-point.h \ + snapper.h \ + sp-item.h \ + sp-metric.h \ + sp-namedview.h \ + sp-object-group.h \ + sp-object.h \ + traits/reference.h \ + unit-constants.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + verbs.h \ + version.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +ui/dialog/extension-editor.o: \ + ui/dialog/extension-editor.cpp \ + forward.h \ + helper/helper-forward.h \ + require-config.h \ + ui/dialog/dialog.h \ + ui/dialog/extension-editor.h \ + verbs.h + +ui/dialog/fill-and-stroke.o: \ + ui/dialog/fill-and-stroke.cpp \ + forward.h \ + helper/helper-forward.h \ + require-config.h \ + ui/dialog/dialog.h \ + ui/dialog/fill-and-stroke.h \ + ui/widget/notebook-page.h \ + verbs.h + +ui/dialog/find.o: \ + ui/dialog/find.cpp \ + decimal-round.h \ + desktop-handles.h \ + desktop.h \ + dialogs/dialog-events.h \ + display/display-forward.h \ + display/nr-arena-forward.h \ + document.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + helper/helper-forward.h \ + helper/window.h \ + inkscape.h \ + interface.h \ + libavoid/connector.h \ + libavoid/geometry.h \ + libavoid/geomtypes.h \ + libavoid/shape.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-convex-hull.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix-ops.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate-ops.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + libnrtype/Layout-TNG.h \ + macros.h \ + message-stack.h \ + message.h \ + prefs-utils.h \ + require-config.h \ + round.h \ + selection-chemistry.h \ + selection.h \ + sp-conn-end-pair.h \ + sp-defs.h \ + sp-ellipse.h \ + sp-flowtext.h \ + sp-image.h \ + sp-item-group.h \ + sp-item.h \ + sp-line.h \ + sp-marker-loc.h \ + sp-object.h \ + sp-offset.h \ + sp-path.h \ + sp-polygon.h \ + sp-polyline.h \ + sp-rect.h \ + sp-shape.h \ + sp-spiral.h \ + sp-star.h \ + sp-string.h \ + sp-text.h \ + sp-tspan.h \ + sp-use.h \ + svg/svg-length.h \ + text-editing.h \ + text-tag-attributes.h \ + traits/reference.h \ + ui/view/edit-widget-interface.h \ + ui/view/view.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + verbs.h \ + version.h \ + widgets/icon.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +ui/dialog/inkscape-preferences.o: \ + ui/dialog/inkscape-preferences.cpp \ + color.h \ + decimal-round.h \ + desktop-handles.h \ + display/display-forward.h \ + document.h \ + enums.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + helper/helper-forward.h \ + inkscape.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-convex-hull.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + message-stack.h \ + message.h \ + prefs-utils.h \ + require-config.h \ + round.h \ + selcue.h \ + selection-chemistry.h \ + selection.h \ + sp-marker-loc.h \ + style.h \ + traits/reference.h \ + ui/dialog/dialog.h \ + ui/dialog/inkscape-preferences.h \ + ui/widget/preferences-widget.h \ + util/list.h \ + verbs.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +ui/dialog/layer-editor.o: \ + ui/dialog/layer-editor.cpp \ + forward.h \ + helper/helper-forward.h \ + require-config.h \ + ui/dialog/dialog.h \ + ui/dialog/layer-editor.h \ + verbs.h + +ui/dialog/memory.o: \ + ui/dialog/memory.cpp \ + debug/heap.h \ + forward.h \ + gc-core.h \ + helper/helper-forward.h \ + require-config.h \ + ui/dialog/dialog.h \ + ui/dialog/memory.h \ + util/shared-c-string-ptr.h \ + verbs.h + +ui/dialog/messages.o: \ + ui/dialog/messages.cpp \ + forward.h \ + helper/helper-forward.h \ + require-config.h \ + ui/dialog/dialog.h \ + ui/dialog/messages.h \ + ui/widget/button.h \ + verbs.h + +ui/dialog/scriptdialog.o: \ + ui/dialog/scriptdialog.cpp \ + extension/script/InkscapeScript.h \ + forward.h \ + helper/helper-forward.h \ + require-config.h \ + ui/dialog/dialog.h \ + ui/dialog/scriptdialog.h \ + verbs.h + +ui/dialog/text-properties.o: \ + ui/dialog/text-properties.cpp \ + forward.h \ + helper/helper-forward.h \ + require-config.h \ + ui/dialog/dialog.h \ + ui/dialog/text-properties.h \ + ui/widget/notebook-page.h \ + verbs.h + +ui/dialog/tracedialog.o: \ + ui/dialog/tracedialog.cpp \ + forward.h \ + helper/helper-forward.h \ + require-config.h \ + trace/imagemap.h \ + trace/potrace/inkscape-potrace.h \ + trace/potrace/potracelib.h \ + trace/potrace/progress.h \ + trace/potrace/trace.h \ + ui/dialog/dialog.h \ + ui/dialog/tracedialog.h \ + ui/stock.h \ + verbs.h + +ui/dialog/transformation.o: \ + ui/dialog/transformation.cpp \ + application/application.h \ + decimal-round.h \ + desktop-handles.h \ + display/display-forward.h \ + display/nr-arena-forward.h \ + document.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + helper/helper-forward.h \ + helper/unit-menu.h \ + inkscape.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-convex-hull.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-ops.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + macros.h \ + prefs-utils.h \ + require-config.h \ + round.h \ + selection-chemistry.h \ + selection.h \ + sp-item-transform.h \ + sp-item.h \ + sp-object.h \ + traits/reference.h \ + ui/dialog/dialog.h \ + ui/dialog/transformation.h \ + ui/stock.h \ + ui/widget/button.h \ + ui/widget/imageicon.h \ + ui/widget/labelled.h \ + ui/widget/notebook-page.h \ + ui/widget/scalar-unit.h \ + ui/widget/scalar.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + verbs.h \ + version.h + +ui/dialog/tree-editor.o: \ + ui/dialog/tree-editor.cpp \ + forward.h \ + helper/helper-forward.h \ + require-config.h \ + ui/dialog/dialog.h \ + ui/dialog/tree-editor.h \ + verbs.h + +ui/dialog/xml-editor.o: \ + ui/dialog/xml-editor.cpp \ + forward.h \ + helper/helper-forward.h \ + require-config.h \ + ui/dialog/dialog.h \ + ui/dialog/xml-editor.h \ + verbs.h + +ui/icons.o: \ + ui/icons.cpp \ + path-prefix.h \ + prefix.h \ + require-config.h \ + ui/stock.h + +ui/previewholder.o: \ + ui/previewholder.cpp \ + ui/previewable.h \ + ui/previewfillable.h \ + ui/previewholder.h + +ui/stock-items.o: \ + ui/stock-items.cpp \ + bad-uri-exception.h \ + composite-undo-stack-observer.h \ + decimal-round.h \ + desktop-handles.h \ + display/display-forward.h \ + display/nr-arena-forward.h \ + document-private.h \ + document.h \ + enums.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + inkscape.h \ + io/sys.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-pixblock.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + path-prefix.h \ + prefix.h \ + require-config.h \ + round.h \ + sp-defs.h \ + sp-gradient-fns.h \ + sp-gradient-spread.h \ + sp-gradient-units.h \ + sp-item-group.h \ + sp-item.h \ + sp-marker-loc.h \ + sp-marker.h \ + sp-object.h \ + sp-paint-server.h \ + sp-pattern.h \ + sp-root.h \ + svg/svg-length.h \ + traits/reference.h \ + undo-stack-observer.h \ + uri-references.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/event-fns.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +ui/stock.o: \ + ui/stock.cpp \ + ui/stock.h + +ui/view/desktop-affine.o: \ + ui/view/desktop-affine.cpp \ + decimal-round.h \ + desktop.h \ + display/nr-arena-forward.h \ + document.h \ + enums.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix-ops.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + message.h \ + round.h \ + sp-item-group.h \ + sp-item.h \ + sp-object.h \ + sp-root.h \ + svg/svg-length.h \ + traits/reference.h \ + ui/view/edit-widget-interface.h \ + ui/view/view.h \ + util/forward-pointer-iterator.h \ + version.h + +ui/view/desktop-events.o: \ + ui/view/desktop-events.cpp \ + decimal-round.h \ + desktop-handles.h \ + desktop.h \ + dialogs/dialog-events.h \ + display/display-forward.h \ + display/guideline.h \ + display/sp-canvas.h \ + document.h \ + event-context.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + grid-snapper.h \ + guide-snapper.h \ + helper/helper-forward.h \ + helper/unit-menu.h \ + helper/units.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + line-snapper.h \ + message-context.h \ + message.h \ + object-snapper.h \ + round.h \ + snapped-point.h \ + snapper.h \ + sp-guide-attachment.h \ + sp-guide.h \ + sp-metric.h \ + sp-metrics.h \ + sp-namedview.h \ + sp-object-group.h \ + sp-object.h \ + traits/reference.h \ + ui/view/edit-widget-interface.h \ + ui/view/view-widget.h \ + ui/view/view.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + widgets/desktop-widget.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +ui/view/desktop-handles.o: \ + ui/view/desktop-handles.cpp \ + decimal-round.h \ + desktop.h \ + display/sp-canvas.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + message.h \ + round.h \ + ui/view/edit-widget-interface.h \ + ui/view/view.h + +ui/view/desktop-style.o: \ + ui/view/desktop-style.cpp \ + bad-uri-exception.h \ + color-rgba.h \ + color.h \ + decimal-round.h \ + desktop-style.h \ + desktop.h \ + display/nr-arena-forward.h \ + document.h \ + dom/css.h \ + dom/dom.h \ + dom/domstring.h \ + dom/events.h \ + dom/smil.h \ + dom/stylesheets.h \ + dom/svg.h \ + dom/svgtypes.h \ + dom/views.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + inkscape.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-convex-hull.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix-ops.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-pixblock.h \ + libnr/nr-pixops.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate-ops.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + libnrtype/Layout-TNG.h \ + libnrtype/font-style-to-pos.h \ + libnrtype/nr-type-pos-def.h \ + message.h \ + prefs-utils.h \ + round.h \ + selection.h \ + sp-flowdiv.h \ + sp-flowregion.h \ + sp-flowtext.h \ + sp-gradient-fns.h \ + sp-gradient-spread.h \ + sp-gradient-units.h \ + sp-gradient-vector.h \ + sp-gradient.h \ + sp-item.h \ + sp-linear-gradient-fns.h \ + sp-linear-gradient.h \ + sp-marker-loc.h \ + sp-object.h \ + sp-paint-server.h \ + sp-pattern.h \ + sp-radial-gradient-fns.h \ + sp-radial-gradient.h \ + sp-string.h \ + sp-text.h \ + sp-textpath.h \ + sp-tspan.h \ + sp-use.h \ + style.h \ + svg/css-ostringstream.h \ + svg/svg-length.h \ + text-tag-attributes.h \ + traits/reference.h \ + ui/view/edit-widget-interface.h \ + ui/view/view.h \ + uri-references.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +ui/view/desktop.o: \ + ui/view/desktop.cpp \ + color.h \ + decimal-round.h \ + desktop-events.h \ + desktop-handles.h \ + desktop.h \ + display/canvas-arena.h \ + display/display-forward.h \ + display/gnome-canvas-acetate.h \ + display/nr-arena-forward.h \ + display/nr-arena-item.h \ + display/nr-arena.h \ + display/sodipodi-ctrlrect.h \ + display/sp-canvas-util.h \ + display/sp-canvas.h \ + document.h \ + event-context.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + grid-snapper.h \ + guide-snapper.h \ + helper/helper-forward.h \ + helper/units.h \ + inkscape-private.h \ + inkscape.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-convex-hull.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-div.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-object.h \ + libnr/nr-pixblock.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect-ops.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + line-snapper.h \ + macros.h \ + message-context.h \ + message-stack.h \ + message.h \ + object-hierarchy.h \ + object-snapper.h \ + prefs-utils.h \ + round.h \ + select-context.h \ + selection.h \ + snapped-point.h \ + snapper.h \ + sp-item-group.h \ + sp-item.h \ + sp-metric.h \ + sp-namedview.h \ + sp-object-group.h \ + sp-object.h \ + sp-paint-server.h \ + traits/reference.h \ + ui/dialog/dialog-manager.h \ + ui/dialog/dialog.h \ + ui/view/edit-widget-interface.h \ + ui/view/view.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +ui/view/edit-widget.o: \ + ui/view/edit-widget.cpp \ + application/app-prototype.h \ + application/editor.h \ + decimal-round.h \ + desktop.h \ + display/nr-arena-forward.h \ + display/sodipodi-ctrlrect.h \ + display/sp-canvas.h \ + document.h \ + enums.h \ + event-context.h \ + extension/db.h \ + extension/extension-forward.h \ + extension/extension.h \ + file.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + grid-snapper.h \ + guide-snapper.h \ + helper/action.h \ + helper/helper-forward.h \ + helper/stock-items.h \ + helper/units.h \ + interface.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-object.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + line-snapper.h \ + macros.h \ + message.h \ + object-snapper.h \ + path-prefix.h \ + prefix.h \ + prefs-utils.h \ + require-config.h \ + round.h \ + shortcuts.h \ + snapped-point.h \ + snapper.h \ + sp-item.h \ + sp-metric.h \ + sp-namedview.h \ + sp-object-group.h \ + sp-object.h \ + traits/reference.h \ + ui/dialog/dialog-manager.h \ + ui/dialog/dialog.h \ + ui/dialog/whiteboard-connect.h \ + ui/dialog/whiteboard-sharewithchat.h \ + ui/dialog/whiteboard-sharewithuser.h \ + ui/icons.h \ + ui/stock.h \ + ui/view/edit-widget-interface.h \ + ui/view/edit-widget.h \ + ui/view/view.h \ + ui/widget/button.h \ + ui/widget/handlebox.h \ + ui/widget/ruler.h \ + ui/widget/selected-style.h \ + ui/widget/svg-canvas.h \ + ui/widget/toolbox.h \ + ui/widget/zoom-status.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + verbs.h \ + version.h \ + widgets/layer-selector.h \ + widgets/spw-utilities.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +ui/view/edit.o: \ + ui/view/edit.cpp + +ui/view/view-widget.o: \ + ui/view/view-widget.cpp \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + message.h \ + ui/view/view-widget.h \ + ui/view/view.h + +ui/view/view.o: \ + ui/view/view.cpp \ + decimal-round.h \ + document.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + helper/helper-forward.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-point.h \ + message-context.h \ + message-stack.h \ + message.h \ + require-config.h \ + round.h \ + ui/view/view.h \ + verbs.h + +ui/widget/button.o: \ + ui/widget/button.cpp \ + ui/widget/button.h + +ui/widget/color-picker.o: \ + ui/widget/color-picker.cpp \ + color.h \ + desktop-handles.h \ + display/display-forward.h \ + document.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + inkscape.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-forward.h \ + ui/dialog/dialog.h \ + ui/widget/button.h \ + ui/widget/color-picker.h \ + ui/widget/color-preview.h \ + widgets/sp-color-notebook.h \ + widgets/sp-color-selector.h + +ui/widget/color-preview.o: \ + ui/widget/color-preview.cpp \ + display/nr-plain-stuff-gdk.h \ + ui/widget/color-preview.h + +ui/widget/combo-text.o: \ + ui/widget/combo-text.cpp \ + ui/widget/combo-text.h + +ui/widget/entity-entry.o: \ + ui/widget/entity-entry.cpp \ + dialogs/rdf.h \ + document.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + inkscape.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-forward.h \ + ui/widget/entity-entry.h \ + ui/widget/registry.h + +ui/widget/handlebox.o: \ + ui/widget/handlebox.cpp \ + ui/widget/handlebox.h + +ui/widget/icon-widget.o: \ + ui/widget/icon-widget.cpp \ + ui/widget/icon-widget.h + +ui/widget/imageicon.o: \ + ui/widget/imageicon.cpp \ + display/display-forward.h \ + document.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + inkscape.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-forward.h \ + svg-view-widget.h \ + ui/view/view-widget.h \ + ui/widget/imageicon.h + +ui/widget/labelled.o: \ + ui/widget/labelled.cpp \ + ui/widget/labelled.h \ + widgets/icon.h + +ui/widget/licensor.o: \ + ui/widget/licensor.cpp \ + dialogs/rdf.h \ + document.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + inkscape.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-forward.h \ + ui/widget/entity-entry.h \ + ui/widget/licensor.h \ + ui/widget/registry.h + +ui/widget/notebook-page.o: \ + ui/widget/notebook-page.cpp \ + ui/widget/notebook-page.h + +ui/widget/page-sizer.o: \ + ui/widget/page-sizer.cpp \ + desktop-handles.h \ + display/display-forward.h \ + document.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + helper/helper-forward.h \ + helper/unit-menu.h \ + helper/units.h \ + inkscape.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-forward.h \ + sp-metric.h \ + ui/widget/labelled.h \ + ui/widget/page-sizer.h \ + ui/widget/registered-widget.h \ + ui/widget/registry.h \ + ui/widget/scalar-unit.h \ + ui/widget/scalar.h + +ui/widget/panel.o: \ + ui/widget/panel.cpp \ + prefs-utils.h \ + ui/previewable.h \ + ui/previewfillable.h \ + ui/widget/button.h \ + ui/widget/panel.h + +ui/widget/preferences-widget.o: \ + ui/widget/preferences-widget.cpp \ + color.h \ + decimal-round.h \ + desktop-handles.h \ + display/display-forward.h \ + document.h \ + enums.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + helper/helper-forward.h \ + inkscape.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-convex-hull.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + message-stack.h \ + message.h \ + prefs-utils.h \ + require-config.h \ + round.h \ + selcue.h \ + selection-chemistry.h \ + selection.h \ + sp-marker-loc.h \ + style.h \ + traits/reference.h \ + ui/widget/preferences-widget.h \ + util/list.h \ + verbs.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +ui/widget/registered-widget.o: \ + ui/widget/registered-widget.cpp \ + decimal-round.h \ + desktop-handles.h \ + display/display-forward.h \ + document.h \ + dom/css.h \ + dom/dom.h \ + dom/domstream.h \ + dom/domstring.h \ + dom/events.h \ + dom/smil.h \ + dom/stringstream.h \ + dom/stylesheets.h \ + dom/svg.h \ + dom/svgtypes.h \ + dom/views.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + grid-snapper.h \ + guide-snapper.h \ + helper/helper-forward.h \ + helper/unit-menu.h \ + helper/units.h \ + inkscape.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-point.h \ + line-snapper.h \ + object-snapper.h \ + round.h \ + snapped-point.h \ + snapper.h \ + sp-metric.h \ + sp-namedview.h \ + sp-object-group.h \ + sp-object.h \ + traits/reference.h \ + ui/widget/button.h \ + ui/widget/color-picker.h \ + ui/widget/color-preview.h \ + ui/widget/labelled.h \ + ui/widget/registered-widget.h \ + ui/widget/registry.h \ + ui/widget/scalar-unit.h \ + ui/widget/scalar.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +ui/widget/registry.o: \ + ui/widget/registry.cpp \ + ui/widget/registry.h + +ui/widget/ruler.o: \ + ui/widget/ruler.cpp \ + decimal-round.h \ + desktop-handles.h \ + desktop.h \ + display/display-forward.h \ + display/guideline.h \ + display/sp-canvas.h \ + document.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + grid-snapper.h \ + guide-snapper.h \ + helper/helper-forward.h \ + helper/units.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + line-snapper.h \ + message.h \ + object-snapper.h \ + round.h \ + snapped-point.h \ + snapper.h \ + sp-metric.h \ + sp-namedview.h \ + sp-object-group.h \ + sp-object.h \ + traits/reference.h \ + ui/view/edit-widget-interface.h \ + ui/view/view.h \ + ui/widget/ruler.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +ui/widget/scalar-unit.o: \ + ui/widget/scalar-unit.cpp \ + helper/helper-forward.h \ + helper/unit-menu.h \ + ui/widget/labelled.h \ + ui/widget/scalar-unit.h \ + ui/widget/scalar.h + +ui/widget/scalar.o: \ + ui/widget/scalar.cpp \ + ui/widget/labelled.h \ + ui/widget/scalar.h + +ui/widget/selected-style.o: \ + ui/widget/selected-style.cpp \ + bad-uri-exception.h \ + color.h \ + decimal-round.h \ + desktop-handles.h \ + desktop-style.h \ + desktop.h \ + dialogs/object-properties.h \ + display/display-forward.h \ + document.h \ + dom/css.h \ + dom/dom.h \ + dom/domstring.h \ + dom/events.h \ + dom/smil.h \ + dom/stylesheets.h \ + dom/svg.h \ + dom/svgtypes.h \ + dom/views.h \ + enums.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + helper/units.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-convex-hull.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-pixblock.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + message.h \ + round.h \ + selection.h \ + sp-linear-gradient-fns.h \ + sp-marker-loc.h \ + sp-metric.h \ + sp-object.h \ + sp-paint-server.h \ + sp-pattern.h \ + sp-radial-gradient-fns.h \ + style.h \ + svg/css-ostringstream.h \ + svg/svg-length.h \ + traits/reference.h \ + ui/view/edit-widget-interface.h \ + ui/view/view.h \ + ui/widget/button.h \ + ui/widget/color-preview.h \ + ui/widget/selected-style.h \ + uri-references.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + widgets/spinbutton-events.h \ + widgets/spw-utilities.h \ + widgets/widget-sizes.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +ui/widget/style-swatch.o: \ + ui/widget/style-swatch.cpp \ + bad-uri-exception.h \ + color.h \ + decimal-round.h \ + desktop.h \ + document.h \ + enums.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + helper/units.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-pixblock.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + message.h \ + round.h \ + sp-linear-gradient-fns.h \ + sp-marker-loc.h \ + sp-metric.h \ + sp-object.h \ + sp-paint-server.h \ + sp-pattern.h \ + sp-radial-gradient-fns.h \ + style.h \ + svg/svg-length.h \ + traits/reference.h \ + ui/view/edit-widget-interface.h \ + ui/view/view.h \ + ui/widget/button.h \ + ui/widget/color-preview.h \ + ui/widget/style-swatch.h \ + uri-references.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + widgets/spw-utilities.h \ + widgets/widget-sizes.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +ui/widget/svg-canvas.o: \ + ui/widget/svg-canvas.cpp \ + decimal-round.h \ + desktop-events.h \ + desktop.h \ + display/canvas-arena.h \ + display/display-forward.h \ + display/nr-arena-forward.h \ + display/nr-arena-item.h \ + display/sp-canvas.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-object.h \ + libnr/nr-pixblock.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + message.h \ + round.h \ + ui/view/edit-widget-interface.h \ + ui/view/view.h \ + ui/widget/svg-canvas.h + +ui/widget/tolerance-slider.o: \ + ui/widget/tolerance-slider.cpp \ + decimal-round.h \ + desktop-handles.h \ + display/display-forward.h \ + document.h \ + dom/dom.h \ + dom/domstream.h \ + dom/domstring.h \ + dom/stringstream.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + grid-snapper.h \ + guide-snapper.h \ + helper/helper-forward.h \ + inkscape.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-point.h \ + line-snapper.h \ + object-snapper.h \ + round.h \ + snapped-point.h \ + snapper.h \ + sp-metric.h \ + sp-namedview.h \ + sp-object-group.h \ + sp-object.h \ + traits/reference.h \ + ui/widget/registry.h \ + ui/widget/tolerance-slider.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +ui/widget/toolbox.o: \ + ui/widget/toolbox.cpp \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + helper/action.h \ + helper/helper-forward.h \ + libnr/nr-object.h \ + path-prefix.h \ + prefix.h \ + require-config.h \ + ui/widget/handlebox.h \ + ui/widget/toolbox.h + +ui/widget/unit-menu.o: \ + ui/widget/unit-menu.cpp \ + helper/helper-forward.h \ + helper/sp-marshal.h \ + helper/unit-menu.h \ + helper/units.h \ + sp-metric.h \ + widgets/spw-utilities.h + +ui/widget/zoom-status.o: \ + ui/widget/zoom-status.cpp \ + decimal-round.h \ + desktop-handles.h \ + desktop.h \ + display/display-forward.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + message.h \ + round.h \ + ui/view/edit-widget-interface.h \ + ui/view/view.h \ + ui/widget/zoom-status.h \ + widgets/spw-utilities.h + +uri-references.o: \ + uri-references.cpp \ + bad-uri-exception.h \ + document.h \ + dom/dom.h \ + dom/domstring.h \ + dom/uri.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-forward.h \ + sp-object.h \ + traits/reference.h \ + uri-references.h \ + util/forward-pointer-iterator.h \ + version.h + +uri.o: \ + uri.cpp \ + dom/dom.h \ + dom/domstring.h \ + dom/uri.h + +util/list-container-test.o: \ + util/list-container-test.cpp \ + gc-core.h \ + gc-managed.h \ + traits/reference.h \ + util/list-container.h \ + util/list.h + +util/shared-c-string-ptr.o: \ + util/shared-c-string-ptr.cpp \ + gc-core.h \ + util/shared-c-string-ptr.h + +util/units.o: \ + util/units.cpp \ + helper/units.h \ + sp-metric.h \ + svg/svg-length.h \ + unit-constants.h + +verbs.o: \ + verbs.cpp \ + decimal-round.h \ + desktop-handles.h \ + desktop.h \ + dialogs/clonetiler.h \ + dialogs/display-settings.h \ + dialogs/extensions.h \ + dialogs/find.h \ + dialogs/iconpreview.h \ + dialogs/input.h \ + dialogs/item-properties.h \ + dialogs/layer-properties.h \ + dialogs/object-properties.h \ + dialogs/swatches.h \ + dialogs/text-edit.h \ + dialogs/xml-tree.h \ + display/display-forward.h \ + display/nr-arena-forward.h \ + document.h \ + event-context.h \ + extension/effect.h \ + extension/extension-forward.h \ + extension/extension.h \ + file.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + grid-snapper.h \ + guide-snapper.h \ + help.h \ + helper/action.h \ + helper/helper-forward.h \ + inkscape-private.h \ + inkscape.h \ + interface.h \ + layer-fns.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-convex-hull.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix-ops.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-object.h \ + libnr/nr-path-code.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate-ops.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + libnrtype/Layout-TNG.h \ + line-snapper.h \ + livarot/LivarotDefs.h \ + livarot/Path.h \ + livarot/livarot-forward.h \ + message-stack.h \ + message.h \ + node-context.h \ + nodepath.h \ + object-snapper.h \ + path-chemistry.h \ + prefs-utils.h \ + require-config.h \ + round.h \ + selection-chemistry.h \ + selection.h \ + snapped-point.h \ + snapper.h \ + sp-flowtext.h \ + sp-item.h \ + sp-metric.h \ + sp-namedview.h \ + sp-object-group.h \ + sp-object.h \ + splivarot.h \ + text-chemistry.h \ + tools-switch.h \ + traits/reference.h \ + ui/dialog/dialog-manager.h \ + ui/dialog/dialog.h \ + ui/dialog/whiteboard-connect.h \ + ui/dialog/whiteboard-sharewithchat.h \ + ui/dialog/whiteboard-sharewithuser.h \ + ui/previewable.h \ + ui/previewfillable.h \ + ui/previewholder.h \ + ui/stock.h \ + ui/view/edit-widget-interface.h \ + ui/view/view.h \ + ui/widget/button.h \ + ui/widget/panel.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + verbs.h \ + version.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +version.o: \ + version.cpp \ + version.h + +widgets/button.o: \ + widgets/button.cpp \ + ui/widget/button.h + +widgets/dash-selector.o: \ + widgets/dash-selector.cpp \ + color.h \ + dialogs/dialog-events.h \ + document.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-forward.h \ + libnr/nr-macros.h \ + sp-marker-loc.h \ + style.h \ + traits/reference.h \ + util/list.h \ + widgets/dash-selector.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +widgets/desktop-widget.o: \ + widgets/desktop-widget.cpp \ + decimal-round.h \ + desktop-events.h \ + desktop-handles.h \ + desktop.h \ + dialogs/swatches.h \ + display/canvas-arena.h \ + display/display-forward.h \ + display/nr-arena-forward.h \ + display/nr-arena-item.h \ + display/sp-canvas.h \ + document.h \ + enums.h \ + extension/db.h \ + extension/extension-forward.h \ + extension/extension.h \ + file.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + grid-snapper.h \ + guide-snapper.h \ + helper/action.h \ + helper/helper-forward.h \ + helper/units.h \ + inkscape-private.h \ + inkscape.h \ + interface.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-object.h \ + libnr/nr-pixblock.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + line-snapper.h \ + macros.h \ + message.h \ + object-snapper.h \ + prefs-utils.h \ + round.h \ + snapped-point.h \ + snapper.h \ + sp-item.h \ + sp-metric.h \ + sp-namedview.h \ + sp-object-group.h \ + sp-object.h \ + traits/reference.h \ + ui/previewable.h \ + ui/previewfillable.h \ + ui/previewholder.h \ + ui/view/edit-widget-interface.h \ + ui/view/view-widget.h \ + ui/view/view.h \ + ui/widget/button.h \ + ui/widget/handlebox.h \ + ui/widget/panel.h \ + ui/widget/ruler.h \ + ui/widget/selected-style.h \ + ui/widget/toolbox.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + widgets/desktop-widget.h \ + widgets/layer-selector.h \ + widgets/spinbutton-events.h \ + widgets/spw-utilities.h \ + widgets/widget-sizes.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +widgets/font-selector.o: \ + widgets/font-selector.cpp \ + decimal-round.h \ + display/nr-plain-stuff-gdk.h \ + libnr/nr-blit.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-pixblock.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + libnrtype/FontFactory.h \ + libnrtype/RasterFont.h \ + libnrtype/TextWrapper.h \ + libnrtype/boundary-type.h \ + libnrtype/font-instance.h \ + libnrtype/font-style.h \ + libnrtype/nr-type-pos-def.h \ + libnrtype/nr-type-primitives.h \ + libnrtype/nrtype-forward.h \ + libnrtype/one-glyph.h \ + libnrtype/raster-glyph.h \ + livarot/LivarotDefs.h \ + livarot/livarot-forward.h \ + require-config.h \ + round.h \ + widgets/font-selector.h + +widgets/gradient-image.o: \ + widgets/gradient-image.cpp \ + decimal-round.h \ + display/nr-plain-stuff-gdk.h \ + display/nr-plain-stuff.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-pixblock-pattern.h \ + libnr/nr-pixblock.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + macros.h \ + round.h \ + sp-gradient-fns.h \ + sp-gradient-spread.h \ + sp-gradient-units.h \ + widgets/gradient-image.h + +widgets/gradient-selector.o: \ + widgets/gradient-selector.cpp \ + color.h \ + composite-undo-stack-observer.h \ + decimal-round.h \ + display/nr-arena-forward.h \ + document-private.h \ + document.h \ + enums.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + gradient-chemistry.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-pixblock.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + round.h \ + sp-defs.h \ + sp-gradient-fns.h \ + sp-gradient-spread.h \ + sp-gradient-units.h \ + sp-gradient-vector.h \ + sp-gradient.h \ + sp-item-group.h \ + sp-item.h \ + sp-object.h \ + sp-paint-server.h \ + sp-root.h \ + svg/svg-length.h \ + traits/reference.h \ + undo-stack-observer.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + widgets/gradient-selector.h \ + widgets/gradient-vector.h \ + xml/event-fns.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +widgets/gradient-toolbar.o: \ + widgets/gradient-toolbar.cpp \ + color.h \ + composite-undo-stack-observer.h \ + decimal-round.h \ + desktop-handles.h \ + desktop.h \ + display/display-forward.h \ + display/nr-arena-forward.h \ + document-private.h \ + document.h \ + enums.h \ + event-context.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + gradient-chemistry.h \ + gradient-context.h \ + gradient-drag.h \ + helper/action.h \ + helper/helper-forward.h \ + knot-enums.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-convex-hull.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-object.h \ + libnr/nr-pixblock.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + macros.h \ + message.h \ + prefs-utils.h \ + round.h \ + selection.h \ + sp-defs.h \ + sp-gradient-fns.h \ + sp-gradient-spread.h \ + sp-gradient-units.h \ + sp-gradient-vector.h \ + sp-gradient.h \ + sp-item-group.h \ + sp-item.h \ + sp-linear-gradient-fns.h \ + sp-linear-gradient.h \ + sp-marker-loc.h \ + sp-object.h \ + sp-paint-server.h \ + sp-radial-gradient-fns.h \ + sp-radial-gradient.h \ + sp-root.h \ + style.h \ + svg/svg-length.h \ + traits/reference.h \ + ui/view/edit-widget-interface.h \ + ui/view/view.h \ + ui/widget/button.h \ + ui/widget/handlebox.h \ + ui/widget/toolbox.h \ + undo-stack-observer.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + widgets/gradient-image.h \ + widgets/gradient-vector.h \ + widgets/spinbutton-events.h \ + widgets/spw-utilities.h \ + widgets/widget-sizes.h \ + xml/event-fns.h + +widgets/gradient-vector.o: \ + widgets/gradient-vector.cpp \ + color.h \ + composite-undo-stack-observer.h \ + decimal-round.h \ + dialogs/dialog-events.h \ + display/nr-arena-forward.h \ + document-private.h \ + document.h \ + dom/css.h \ + dom/dom.h \ + dom/domstring.h \ + dom/events.h \ + dom/smil.h \ + dom/stylesheets.h \ + dom/svg.h \ + dom/svgtypes.h \ + dom/views.h \ + enums.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + gradient-chemistry.h \ + helper/window.h \ + inkscape.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-pixblock.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + macros.h \ + prefs-utils.h \ + round.h \ + sp-defs.h \ + sp-gradient-fns.h \ + sp-gradient-spread.h \ + sp-gradient-units.h \ + sp-gradient-vector.h \ + sp-gradient.h \ + sp-item-group.h \ + sp-item.h \ + sp-object.h \ + sp-paint-server.h \ + sp-root.h \ + sp-stop-fns.h \ + sp-stop.h \ + svg/css-ostringstream.h \ + svg/svg-length.h \ + traits/reference.h \ + undo-stack-observer.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + widgets/gradient-image.h \ + widgets/gradient-vector.h \ + widgets/sp-color-notebook.h \ + widgets/sp-color-preview.h \ + widgets/sp-color-selector.h \ + widgets/widget-sizes.h \ + xml/event-fns.h \ + xml/node-event-vector.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +widgets/icon.o: \ + widgets/icon.cpp \ + decimal-round.h \ + display/nr-arena-forward.h \ + display/nr-arena-item.h \ + display/nr-arena.h \ + document.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + inkscape.h \ + io/sys.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-object.h \ + libnr/nr-pixblock.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + path-prefix.h \ + prefix.h \ + prefs-utils.h \ + require-config.h \ + round.h \ + sp-item.h \ + sp-object.h \ + sp-paint-server.h \ + traits/reference.h \ + util/forward-pointer-iterator.h \ + version.h \ + widgets/icon.h + +widgets/layer-selector.o: \ + widgets/layer-selector.cpp \ + decimal-round.h \ + desktop-handles.h \ + desktop.h \ + dialogs/layer-properties.h \ + display/display-forward.h \ + display/nr-arena-forward.h \ + document.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-convex-hull.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + message.h \ + round.h \ + selection.h \ + sp-item.h \ + sp-object.h \ + traits/copy.h \ + traits/list-copy.h \ + traits/reference.h \ + ui/dialog/dialog.h \ + ui/view/edit-widget-interface.h \ + ui/view/view.h \ + util/filter-list.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + util/reverse-list.h \ + version.h \ + widgets/icon.h \ + widgets/layer-selector.h \ + widgets/shrink-wrap-button.h \ + xml/node-event-vector.h \ + xml/node.h + +widgets/paint-selector.o: \ + widgets/paint-selector.cpp \ + bad-uri-exception.h \ + color.h \ + composite-undo-stack-observer.h \ + decimal-round.h \ + desktop-style.h \ + display/nr-arena-forward.h \ + document-private.h \ + document.h \ + dom/css.h \ + dom/dom.h \ + dom/domstring.h \ + dom/events.h \ + dom/smil.h \ + dom/stylesheets.h \ + dom/svg.h \ + dom/svgtypes.h \ + dom/views.h \ + enums.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + inkscape-stock.h \ + inkscape.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-pixblock.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + round.h \ + sp-defs.h \ + sp-gradient-fns.h \ + sp-gradient-spread.h \ + sp-gradient-units.h \ + sp-gradient-vector.h \ + sp-gradient.h \ + sp-item-group.h \ + sp-item.h \ + sp-linear-gradient-fns.h \ + sp-marker-loc.h \ + sp-object.h \ + sp-paint-server.h \ + sp-pattern.h \ + sp-radial-gradient-fns.h \ + sp-root.h \ + style.h \ + svg/css-ostringstream.h \ + svg/svg-length.h \ + traits/reference.h \ + undo-stack-observer.h \ + uri-references.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + widgets/gradient-selector.h \ + widgets/icon.h \ + widgets/paint-selector.h \ + widgets/sp-color-notebook.h \ + widgets/sp-color-selector.h \ + widgets/widget-sizes.h \ + xml/event-fns.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +widgets/ruler.o: \ + widgets/ruler.cpp \ + decimal-round.h \ + desktop-handles.h \ + desktop.h \ + display/display-forward.h \ + display/guideline.h \ + display/sp-canvas.h \ + document.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + grid-snapper.h \ + guide-snapper.h \ + helper/helper-forward.h \ + helper/units.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-l.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect-l.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + line-snapper.h \ + message.h \ + object-snapper.h \ + round.h \ + snapped-point.h \ + snapper.h \ + sp-metric.h \ + sp-namedview.h \ + sp-object-group.h \ + sp-object.h \ + traits/reference.h \ + ui/view/edit-widget-interface.h \ + ui/view/view.h \ + ui/widget/ruler.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +widgets/select-toolbar.o: \ + widgets/select-toolbar.cpp \ + decimal-round.h \ + desktop-handles.h \ + desktop-style.h \ + desktop.h \ + display/display-forward.h \ + document.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + grid-snapper.h \ + guide-snapper.h \ + helper/action.h \ + helper/helper-forward.h \ + helper/unit-menu.h \ + helper/units.h \ + inkscape.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-convex-hull.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-object.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + line-snapper.h \ + message-stack.h \ + message.h \ + object-snapper.h \ + prefs-utils.h \ + require-config.h \ + round.h \ + selection-chemistry.h \ + selection.h \ + snapped-point.h \ + snapper.h \ + sp-item-transform.h \ + sp-metric.h \ + sp-namedview.h \ + sp-object-group.h \ + sp-object.h \ + traits/reference.h \ + ui/view/edit-widget-interface.h \ + ui/view/view.h \ + ui/widget/button.h \ + ui/widget/handlebox.h \ + ui/widget/toolbox.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + verbs.h \ + version.h \ + widgets/sp-widget.h \ + widgets/spinbutton-events.h \ + widgets/spw-utilities.h \ + widgets/widget-sizes.h + +widgets/shrink-wrap-button.o: \ + widgets/shrink-wrap-button.cpp \ + ui/widget/button.h + +widgets/sp-color-gtkselector.o: \ + widgets/sp-color-gtkselector.cpp \ + color.h \ + widgets/sp-color-gtkselector.h \ + widgets/sp-color-selector.h + +widgets/sp-color-notebook.o: \ + widgets/sp-color-notebook.cpp \ + color.h \ + dialogs/dialog-events.h \ + forward.h \ + prefs-utils.h \ + widgets/sp-color-notebook.h \ + widgets/sp-color-scales.h \ + widgets/sp-color-selector.h \ + widgets/sp-color-slider.h \ + widgets/sp-color-wheel-selector.h \ + widgets/sp-color-wheel.h \ + widgets/spw-utilities.h + +widgets/sp-color-preview.o: \ + widgets/sp-color-preview.cpp \ + display/nr-plain-stuff-gdk.h \ + widgets/sp-color-preview.h + +widgets/sp-color-scales.o: \ + widgets/sp-color-scales.cpp \ + color.h \ + dialogs/dialog-events.h \ + forward.h \ + widgets/sp-color-scales.h \ + widgets/sp-color-selector.h \ + widgets/sp-color-slider.h + +widgets/sp-color-selector.o: \ + widgets/sp-color-selector.cpp \ + color.h \ + widgets/sp-color-selector.h + +widgets/sp-color-slider.o: \ + widgets/sp-color-slider.cpp \ + color.h \ + widgets/sp-color-scales.h \ + widgets/sp-color-selector.h \ + widgets/sp-color-slider.h + +widgets/sp-color-wheel-selector.o: \ + widgets/sp-color-wheel-selector.cpp \ + color.h \ + dialogs/dialog-events.h \ + forward.h \ + widgets/sp-color-scales.h \ + widgets/sp-color-selector.h \ + widgets/sp-color-slider.h \ + widgets/sp-color-wheel-selector.h \ + widgets/sp-color-wheel.h + +widgets/sp-color-wheel.o: \ + widgets/sp-color-wheel.cpp \ + color.h \ + decimal-round.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-macros.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rotate-ops.h \ + libnr/nr-rotate.h \ + round.h \ + widgets/sp-color-wheel.h + +widgets/sp-widget.o: \ + widgets/sp-widget.cpp \ + document.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-forward.h \ + macros.h \ + widgets/sp-widget.h + +widgets/sp-xmlview-attr-list.o: \ + widgets/sp-xmlview-attr-list.cpp \ + document.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + helper/sp-marshal.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-forward.h \ + traits/reference.h \ + util/list.h \ + widgets/sp-xmlview-attr-list.h \ + xml/node-event-vector.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +widgets/sp-xmlview-content.o: \ + widgets/sp-xmlview-content.cpp \ + composite-undo-stack-observer.h \ + decimal-round.h \ + desktop-handles.h \ + display/display-forward.h \ + display/nr-arena-forward.h \ + document-private.h \ + document.h \ + enums.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + inkscape.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + round.h \ + sp-defs.h \ + sp-item-group.h \ + sp-item.h \ + sp-object.h \ + sp-root.h \ + svg/svg-length.h \ + traits/reference.h \ + undo-stack-observer.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + version.h \ + widgets/sp-xmlview-content.h \ + xml/event-fns.h \ + xml/node-event-vector.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +widgets/sp-xmlview-tree.o: \ + widgets/sp-xmlview-tree.cpp \ + document.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-forward.h \ + traits/reference.h \ + util/list.h \ + widgets/sp-xmlview-tree.h \ + xml/node-event-vector.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +widgets/spinbutton-events.o: \ + widgets/spinbutton-events.cpp \ + event-context.h \ + forward.h \ + widgets/sp-widget.h \ + widgets/widget-sizes.h + +widgets/spw-utilities.o: \ + widgets/spw-utilities.cpp \ + decimal-round.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + helper/helper-forward.h \ + helper/unit-menu.h \ + libnr/nr-convex-hull.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + round.h \ + selection.h \ + traits/reference.h \ + util/list.h + +widgets/toolbox.o: \ + widgets/toolbox.cpp \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + helper/action.h \ + helper/helper-forward.h \ + libnr/nr-object.h \ + path-prefix.h \ + prefix.h \ + require-config.h \ + ui/widget/handlebox.h \ + ui/widget/toolbox.h + +xml/composite-node-observer.o: \ + xml/composite-node-observer.cpp \ + algorithms/find-if-before.h \ + debug/event-tracker.h \ + debug/event.h \ + debug/logger.h \ + debug/simple-event.h \ + gc-anchored.h \ + gc-core.h \ + gc-managed.h \ + traits/reference.h \ + util/list-container.h \ + util/list.h \ + util/shared-c-string-ptr.h \ + xml/composite-node-observer.h \ + xml/node-event-vector.h \ + xml/node-observer.h \ + xml/node.h + +xml/croco-node-iface.o: \ + xml/croco-node-iface.cpp \ + gc-anchored.h \ + gc-core.h \ + gc-managed.h \ + libcroco/cr-node-iface.h \ + traits/reference.h \ + util/list.h \ + xml/croco-node-iface.h \ + xml/node.h + +xml/event.o: \ + xml/event.cpp \ + debug/event-tracker.h \ + debug/event.h \ + debug/logger.h \ + debug/simple-event.h \ + document.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-forward.h \ + traits/copy.h \ + traits/list-copy.h \ + traits/reference.h \ + util/list.h \ + util/reverse-list.h \ + util/shared-c-string-ptr.h \ + xml/event-fns.h \ + xml/node-observer.h + +xml/log-builder.o: \ + xml/log-builder.cpp \ + debug/event.h \ + gc-core.h \ + gc-managed.h \ + util/shared-c-string-ptr.h \ + xml/event-fns.h \ + xml/log-builder.h \ + xml/node-observer.h + +xml/node-fns.o: \ + xml/node-fns.cpp \ + algorithms/find-if-before.h \ + gc-anchored.h \ + gc-core.h \ + gc-managed.h \ + traits/reference.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + xml/node-iterators.h \ + xml/node.h + +xml/quote.o: \ + xml/quote.cpp + +xml/repr-css.o: \ + xml/repr-css.cpp \ + document.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-forward.h \ + traits/reference.h \ + util/list-container.h \ + util/list.h \ + util/shared-c-string-ptr.h \ + xml/attribute-record.h \ + xml/composite-node-observer.h \ + xml/node-observer.h \ + xml/node.h \ + xml/repr.h \ + xml/simple-node.h \ + xml/sp-css-attr.h \ + xml/transaction-logger.h + +xml/repr-io.o: \ + xml/repr-io.cpp \ + document.h \ + dom/dom.h \ + dom/domstream.h \ + dom/domstring.h \ + dom/uri.h \ + dom/uristream.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + io/gzipstream.h \ + io/inkscapestream.h \ + io/sys.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-forward.h \ + traits/reference.h \ + util/list.h \ + util/shared-c-string-ptr.h \ + xml/attribute-record.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +xml/repr-sorting.o: \ + xml/repr-sorting.cpp \ + algorithms/longest-common-suffix.h \ + document.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-forward.h \ + traits/reference.h \ + util/forward-pointer-iterator.h \ + util/list.h \ + xml/node-iterators.h \ + xml/node.h \ + xml/repr.h \ + xml/sp-css-attr.h + +xml/repr-util.o: \ + xml/repr-util.cpp \ + document.h \ + dom/dom.h \ + dom/domstream.h \ + dom/domstring.h \ + dom/stringstream.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-forward.h \ + svg/css-ostringstream.h \ + traits/reference.h \ + util/list.h \ + xml/node.h \ + xml/repr-sorting.h \ + xml/repr.h \ + xml/sp-css-attr.h + +xml/repr.o: \ + xml/repr.cpp \ + document.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-forward.h \ + traits/reference.h \ + util/list-container.h \ + util/list.h \ + util/shared-c-string-ptr.h \ + xml/attribute-record.h \ + xml/comment-node.h \ + xml/composite-node-observer.h \ + xml/element-node.h \ + xml/node-observer.h \ + xml/node.h \ + xml/repr.h \ + xml/simple-document.h \ + xml/simple-node.h \ + xml/sp-css-attr.h \ + xml/text-node.h \ + xml/transaction-logger.h + +xml/simple-document.o: \ + xml/simple-document.cpp \ + document.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-forward.h \ + traits/reference.h \ + util/list-container.h \ + util/list.h \ + util/shared-c-string-ptr.h \ + xml/attribute-record.h \ + xml/composite-node-observer.h \ + xml/log-builder.h \ + xml/node-observer.h \ + xml/node.h \ + xml/session.h \ + xml/simple-document.h \ + xml/simple-node.h \ + xml/simple-session.h \ + xml/transaction-logger.h + +xml/simple-node.o: \ + xml/simple-node.cpp \ + debug/event-tracker.h \ + debug/event.h \ + debug/logger.h \ + document.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libcroco/cr-additional-sel.h \ + libcroco/cr-attr-sel.h \ + libcroco/cr-cascade.h \ + libcroco/cr-declaration.h \ + libcroco/cr-num.h \ + libcroco/cr-parsing-location.h \ + libcroco/cr-pseudo.h \ + libcroco/cr-rgb.h \ + libcroco/cr-selector.h \ + libcroco/cr-simple-sel.h \ + libcroco/cr-statement.h \ + libcroco/cr-string.h \ + libcroco/cr-stylesheet.h \ + libcroco/cr-term.h \ + libcroco/cr-utils.h \ + libnr/nr-forward.h \ + traits/reference.h \ + util/list-container.h \ + util/list.h \ + util/shared-c-string-ptr.h \ + xml/attribute-record.h \ + xml/composite-node-observer.h \ + xml/node-event-vector.h \ + xml/node-fns.h \ + xml/node-observer.h \ + xml/node.h \ + xml/repr.h \ + xml/simple-node.h \ + xml/sp-css-attr.h \ + xml/transaction-logger.h + +xml/simple-session.o: \ + xml/simple-session.cpp \ + gc-anchored.h \ + gc-core.h \ + gc-managed.h \ + traits/reference.h \ + util/list-container.h \ + util/list.h \ + util/shared-c-string-ptr.h \ + xml/attribute-record.h \ + xml/comment-node.h \ + xml/composite-node-observer.h \ + xml/element-node.h \ + xml/event-fns.h \ + xml/log-builder.h \ + xml/node-observer.h \ + xml/node.h \ + xml/session.h \ + xml/simple-node.h \ + xml/simple-session.h \ + xml/text-node.h \ + xml/transaction-logger.h + +zoom-context.o: \ + zoom-context.cpp \ + decimal-round.h \ + desktop.h \ + event-context.h \ + forward.h \ + gc-anchored.h \ + gc-core.h \ + gc-finalized.h \ + gc-managed.h \ + libnr/nr-coord.h \ + libnr/nr-dim2.h \ + libnr/nr-forward.h \ + libnr/nr-i-coord.h \ + libnr/nr-macros.h \ + libnr/nr-matrix-fns.h \ + libnr/nr-matrix.h \ + libnr/nr-maybe.h \ + libnr/nr-point-fns.h \ + libnr/nr-point-matrix-ops.h \ + libnr/nr-point-ops.h \ + libnr/nr-point.h \ + libnr/nr-rect.h \ + libnr/nr-rotate.h \ + libnr/nr-scale.h \ + libnr/nr-translate.h \ + libnr/nr-values.h \ + macros.h \ + message.h \ + prefs-utils.h \ + round.h \ + rubberband.h \ + ui/view/edit-widget-interface.h \ + ui/view/view.h \ + zoom-context.h diff --git a/src/make.exclude b/src/make.exclude new file mode 100644 index 000000000..179863c6e --- /dev/null +++ b/src/make.exclude @@ -0,0 +1,80 @@ +###################################################################### +# File: make.exclude +# +# This is a list of files to exclude from +# building using the Makedep scheme. +# To use, run: +# perl mkfiles.pl +# then +# perl mkdep.pl +# +###################################################################### + + +ast +bonobo + +dialogs/filedialog-win32.cpp +display/testnr.cpp +display/bezier-utils-test.cpp +dom/testdom.cpp +dom/testsvg.cpp +dom/xpathtest.cpp +dom/xpathtests.cpp +extension/api.cpp +extension/dxf2svg +extension/internal/gnome.cpp +extension/script/js +extension/script/bindtest.cpp +extension/script/cpptest.cpp +extension/plugin +extract-uri-test.cpp +helper/units-test.cpp +inkview.cpp +libnr/in-svg-plane-test.cpp +libnr/nr-matrix-test.cpp +libnr/nr-point-fns-test.cpp +libnr/nr-rotate-fns-test.cpp +libnr/nr-rotate-test.cpp +libnr/nr-scale-test.cpp +libnr/nr-translate-test.cpp +libnr/nr-types-test.cpp +livarot/Path-test.cpp +main.cpp +mod360-test.cpp +trace/potrace/potest.cpp +round-test.cpp +sp-gradient-test.cpp +svg/ftos.cpp +utest +widgets/test-widgets.cpp +winmain.cpp +xml/quote-test.cpp +xml/repr-action-test.cpp +io/streamtest.cpp + + +############################################### +# Bob: +# Uncomment these to build Inkboard +# For the moment, DO NOT remove these from cvs +# until those files compile everywhere +############################################### +dialogs/whiteboard-connect-dialog.cpp +dialogs/whiteboard-common-dialog.cpp +dialogs/whiteboard-sharewithchat-dialog.cpp +dialogs/whiteboard-sharewithuser-dialog.cpp +jabber_whiteboard +ui/dialog/session-player.cpp +ui/dialog/whiteboard-connect.cpp +ui/dialog/whiteboard-sharewithchat.cpp +ui/dialog/whiteboard-sharewithuser.cpp + +############################################### +# Various test harnesses in removeoverlap +############################################### +removeoverlap/placement_SolveVPSC.cpp +removeoverlap/placement_SolveVPSC.h +removeoverlap/test.cpp +removeoverlap/remove_rectangle_overlap-test.cpp +removeoverlap/remove_rectangle_overlap-test.h \ No newline at end of file diff --git a/src/make.files b/src/make.files new file mode 100644 index 000000000..8d7a04f56 --- /dev/null +++ b/src/make.files @@ -0,0 +1,1339 @@ +######################################################## +## File: make.files +## Purpose: Used by mkdep.pl +## Generated by mkfiles.pl at :Sun Jan 15 07:06:12 2006 +######################################################## + +algorithms/find-if-before.h +algorithms/find-last-if.h +algorithms/longest-common-suffix.h +application/app-prototype.cpp +application/app-prototype.h +application/application.cpp +application/application.h +application/editor.cpp +application/editor.h +approx-equal.h +arc-context.cpp +arc-context.h +attributes-test.cpp +attributes.cpp +attributes.h +bad-uri-exception.h +color-rgba.h +color.cpp +color.h +composite-undo-stack-observer.cpp +composite-undo-stack-observer.h +conn-avoid-ref.cpp +conn-avoid-ref.h +connector-context.cpp +connector-context.h +context-fns.cpp +context-fns.h +debug/event-tracker.h +debug/event.h +debug/gc-heap.h +debug/heap.cpp +debug/heap.h +debug/logger.cpp +debug/logger.h +debug/simple-event.h +debug/sysv-heap.cpp +debug/sysv-heap.h +decimal-round.h +desktop-affine.cpp +desktop-affine.h +desktop-events.cpp +desktop-events.h +desktop-handles.cpp +desktop-handles.h +desktop-style.cpp +desktop-style.h +desktop.cpp +desktop.h +dialogs/clonetiler.cpp +dialogs/clonetiler.h +dialogs/debugdialog.cpp +dialogs/debugdialog.h +dialogs/dialog-events.cpp +dialogs/dialog-events.h +dialogs/display-settings.cpp +dialogs/display-settings.h +dialogs/eek-preview.cpp +dialogs/eek-preview.h +dialogs/export.cpp +dialogs/export.h +dialogs/extensions.cpp +dialogs/extensions.h +dialogs/filedialog.cpp +dialogs/filedialog.h +dialogs/fill-style.cpp +dialogs/fill-style.h +dialogs/find.cpp +dialogs/find.h +dialogs/iconpreview.cpp +dialogs/iconpreview.h +dialogs/in-dt-coordsys.cpp +dialogs/in-dt-coordsys.h +dialogs/input.cpp +dialogs/input.h +dialogs/item-properties.cpp +dialogs/item-properties.h +dialogs/layer-properties.cpp +dialogs/layer-properties.h +dialogs/object-attributes.cpp +dialogs/object-attributes.h +dialogs/object-properties.cpp +dialogs/object-properties.h +dialogs/rdf.cpp +dialogs/rdf.h +dialogs/sp-attribute-widget.cpp +dialogs/sp-attribute-widget.h +dialogs/stroke-style.cpp +dialogs/stroke-style.h +dialogs/swatches.cpp +dialogs/swatches.h +dialogs/text-edit.cpp +dialogs/text-edit.h +dialogs/tiledialog.cpp +dialogs/tiledialog.h +dialogs/unclump.cpp +dialogs/unclump.h +dialogs/xml-tree.cpp +dialogs/xml-tree.h +dir-util-test.cpp +dir-util.cpp +dir-util.h +display/bezier-utils.cpp +display/bezier-utils.h +display/canvas-arena.cpp +display/canvas-arena.h +display/canvas-bpath.cpp +display/canvas-bpath.h +display/canvas-grid.cpp +display/canvas-grid.h +display/curve.cpp +display/curve.h +display/display-forward.h +display/gnome-canvas-acetate.cpp +display/gnome-canvas-acetate.h +display/guideline.cpp +display/guideline.h +display/nr-arena-forward.h +display/nr-arena-glyphs.cpp +display/nr-arena-glyphs.h +display/nr-arena-group.cpp +display/nr-arena-group.h +display/nr-arena-image.cpp +display/nr-arena-image.h +display/nr-arena-item.cpp +display/nr-arena-item.h +display/nr-arena-shape.cpp +display/nr-arena-shape.h +display/nr-arena.cpp +display/nr-arena.h +display/nr-gradient-gpl.cpp +display/nr-gradient-gpl.h +display/nr-plain-stuff-gdk.cpp +display/nr-plain-stuff-gdk.h +display/nr-plain-stuff.cpp +display/nr-plain-stuff.h +display/sodipodi-ctrl.cpp +display/sodipodi-ctrl.h +display/sodipodi-ctrlrect.cpp +display/sodipodi-ctrlrect.h +display/sp-canvas-util.cpp +display/sp-canvas-util.h +display/sp-canvas.cpp +display/sp-canvas.h +display/sp-ctrlline.cpp +display/sp-ctrlline.h +display/sp-ctrlquadr.cpp +display/sp-ctrlquadr.h +document-private.h +document-undo.cpp +document.cpp +document.h +dom/Makefile.static +dom/charclass.cpp +dom/charclass.h +dom/css.h +dom/cssparser.cpp +dom/cssparser.h +dom/dom.h +dom/domimpl.cpp +dom/domimpl.h +dom/domstream.cpp +dom/domstream.h +dom/domstring.cpp +dom/domstring.h +dom/domstringimpl.h +dom/events.h +dom/js/fdlibm/e_acos.c +dom/js/fdlibm/e_acosh.c +dom/js/fdlibm/e_asin.c +dom/js/fdlibm/e_atan2.c +dom/js/fdlibm/e_atanh.c +dom/js/fdlibm/e_cosh.c +dom/js/fdlibm/e_exp.c +dom/js/fdlibm/e_fmod.c +dom/js/fdlibm/e_gamma.c +dom/js/fdlibm/e_gamma_r.c +dom/js/fdlibm/e_hypot.c +dom/js/fdlibm/e_j0.c +dom/js/fdlibm/e_j1.c +dom/js/fdlibm/e_jn.c +dom/js/fdlibm/e_lgamma.c +dom/js/fdlibm/e_lgamma_r.c +dom/js/fdlibm/e_log.c +dom/js/fdlibm/e_log10.c +dom/js/fdlibm/e_pow.c +dom/js/fdlibm/e_rem_pio2.c +dom/js/fdlibm/e_remainder.c +dom/js/fdlibm/e_scalb.c +dom/js/fdlibm/e_sinh.c +dom/js/fdlibm/e_sqrt.c +dom/js/fdlibm/fdlibm.h +dom/js/fdlibm/k_cos.c +dom/js/fdlibm/k_rem_pio2.c +dom/js/fdlibm/k_sin.c +dom/js/fdlibm/k_standard.c +dom/js/fdlibm/k_tan.c +dom/js/fdlibm/s_asinh.c +dom/js/fdlibm/s_atan.c +dom/js/fdlibm/s_cbrt.c +dom/js/fdlibm/s_ceil.c +dom/js/fdlibm/s_copysign.c +dom/js/fdlibm/s_cos.c +dom/js/fdlibm/s_erf.c +dom/js/fdlibm/s_expm1.c +dom/js/fdlibm/s_fabs.c +dom/js/fdlibm/s_finite.c +dom/js/fdlibm/s_floor.c +dom/js/fdlibm/s_frexp.c +dom/js/fdlibm/s_ilogb.c +dom/js/fdlibm/s_isnan.c +dom/js/fdlibm/s_ldexp.c +dom/js/fdlibm/s_lib_version.c +dom/js/fdlibm/s_log1p.c +dom/js/fdlibm/s_logb.c +dom/js/fdlibm/s_matherr.c +dom/js/fdlibm/s_modf.c +dom/js/fdlibm/s_nextafter.c +dom/js/fdlibm/s_rint.c +dom/js/fdlibm/s_scalbn.c +dom/js/fdlibm/s_signgam.c +dom/js/fdlibm/s_significand.c +dom/js/fdlibm/s_sin.c +dom/js/fdlibm/s_tan.c +dom/js/fdlibm/s_tanh.c +dom/js/fdlibm/w_acos.c +dom/js/fdlibm/w_acosh.c +dom/js/fdlibm/w_asin.c +dom/js/fdlibm/w_atan2.c +dom/js/fdlibm/w_atanh.c +dom/js/fdlibm/w_cosh.c +dom/js/fdlibm/w_exp.c +dom/js/fdlibm/w_fmod.c +dom/js/fdlibm/w_gamma.c +dom/js/fdlibm/w_gamma_r.c +dom/js/fdlibm/w_hypot.c +dom/js/fdlibm/w_j0.c +dom/js/fdlibm/w_j1.c +dom/js/fdlibm/w_jn.c +dom/js/fdlibm/w_lgamma.c +dom/js/fdlibm/w_lgamma_r.c +dom/js/fdlibm/w_log.c +dom/js/fdlibm/w_log10.c +dom/js/fdlibm/w_pow.c +dom/js/fdlibm/w_remainder.c +dom/js/fdlibm/w_scalb.c +dom/js/fdlibm/w_sinh.c +dom/js/fdlibm/w_sqrt.c +dom/js/js.c +dom/js/jsapi.c +dom/js/jsapi.h +dom/js/jsarena.c +dom/js/jsarena.h +dom/js/jsarray.c +dom/js/jsarray.h +dom/js/jsatom.c +dom/js/jsatom.h +dom/js/jsautocfg.h +dom/js/jsbit.h +dom/js/jsbool.c +dom/js/jsbool.h +dom/js/jsclist.h +dom/js/jscntxt.c +dom/js/jscntxt.h +dom/js/jscompat.h +dom/js/jsconfig.h +dom/js/jscpucfg.c +dom/js/jscpucfg.h +dom/js/jsdate.c +dom/js/jsdate.h +dom/js/jsdbgapi.c +dom/js/jsdbgapi.h +dom/js/jsdhash.c +dom/js/jsdhash.h +dom/js/jsdtoa.c +dom/js/jsdtoa.h +dom/js/jsemit.c +dom/js/jsemit.h +dom/js/jsexn.c +dom/js/jsexn.h +dom/js/jsfile.c +dom/js/jsfile.h +dom/js/jsfun.c +dom/js/jsfun.h +dom/js/jsgc.c +dom/js/jsgc.h +dom/js/jshash.c +dom/js/jshash.h +dom/js/jsinterp.c +dom/js/jsinterp.h +dom/js/jslibmath.h +dom/js/jslock.c +dom/js/jslock.h +dom/js/jslog2.c +dom/js/jslong.c +dom/js/jslong.h +dom/js/jsmath.c +dom/js/jsmath.h +dom/js/jsnum.c +dom/js/jsnum.h +dom/js/jsobj.c +dom/js/jsobj.h +dom/js/jsopcode.c +dom/js/jsopcode.h +dom/js/jsosdep.h +dom/js/jsotypes.h +dom/js/jsparse.c +dom/js/jsparse.h +dom/js/jsprf.c +dom/js/jsprf.h +dom/js/jsprvtd.h +dom/js/jspubtd.h +dom/js/jsregexp.c +dom/js/jsregexp.h +dom/js/jsscan.c +dom/js/jsscan.h +dom/js/jsscope.c +dom/js/jsscope.h +dom/js/jsscript.c +dom/js/jsscript.h +dom/js/jsstddef.h +dom/js/jsstr.c +dom/js/jsstr.h +dom/js/jstypes.h +dom/js/jsutil.c +dom/js/jsutil.h +dom/js/jsxdrapi.c +dom/js/jsxdrapi.h +dom/js/prmjtime.c +dom/js/prmjtime.h +dom/js/resource.h +dom/ls.h +dom/lsimpl.cpp +dom/lsimpl.h +dom/phoebedom.h +dom/prop-css.cpp +dom/prop-css2.cpp +dom/prop-svg.cpp +dom/smil.h +dom/smilimpl.cpp +dom/smilimpl.h +dom/stringstream.cpp +dom/stringstream.h +dom/stylesheets.h +dom/svg.h +dom/svgimpl.cpp +dom/svgimpl.h +dom/svglsimpl.cpp +dom/svglsimpl.h +dom/svgparser.cpp +dom/svgparser.h +dom/svgtypes.h +dom/traversal.h +dom/uri.cpp +dom/uri.h +dom/uristream.cpp +dom/uristream.h +dom/uritest.cpp +dom/views.h +dom/xmlreader.cpp +dom/xmlreader.h +dom/xpath.h +dom/xpathimpl.cpp +dom/xpathimpl.h +dom/xpathparser.cpp +dom/xpathparser.h +draw-anchor.cpp +draw-anchor.h +draw-context.cpp +draw-context.h +dropper-context.cpp +dropper-context.h +dyna-draw-context.cpp +dyna-draw-context.h +enums.h +event-context.cpp +event-context.h +extension/db.cpp +extension/db.h +extension/dependency.cpp +extension/dependency.h +extension/effect.cpp +extension/effect.h +extension/error-file.cpp +extension/error-file.h +extension/extension-forward.h +extension/extension.cpp +extension/extension.h +extension/implementation/implementation.cpp +extension/implementation/implementation.h +extension/implementation/plugin-link.h +extension/implementation/plugin.cpp +extension/implementation/plugin.h +extension/implementation/script.cpp +extension/implementation/script.h +extension/init.cpp +extension/init.h +extension/input.cpp +extension/input.h +extension/internal/bluredge.cpp +extension/internal/bluredge.h +extension/internal/eps-out.cpp +extension/internal/eps-out.h +extension/internal/gdkpixbuf-input.cpp +extension/internal/gdkpixbuf-input.h +extension/internal/gimpgrad.cpp +extension/internal/gimpgrad.h +extension/internal/gnome.h +extension/internal/grid.cpp +extension/internal/grid.h +extension/internal/latex-pstricks-out.cpp +extension/internal/latex-pstricks-out.h +extension/internal/latex-pstricks.cpp +extension/internal/latex-pstricks.h +extension/internal/pov-out.cpp +extension/internal/pov-out.h +extension/internal/ps-out.cpp +extension/internal/ps-out.h +extension/internal/ps.cpp +extension/internal/ps.h +extension/internal/svg.cpp +extension/internal/svg.h +extension/internal/svgz.cpp +extension/internal/svgz.h +extension/internal/win32.cpp +extension/internal/win32.h +extension/output.cpp +extension/output.h +extension/parameter.cpp +extension/parameter.h +extension/prefdialog.cpp +extension/prefdialog.h +extension/print.cpp +extension/print.h +extension/script/InkscapeBinding.cpp +extension/script/InkscapeBinding.h +extension/script/InkscapeInterpreter.cpp +extension/script/InkscapeInterpreter.h +extension/script/InkscapePerl.cpp +extension/script/InkscapePerl.h +extension/script/InkscapePython.cpp +extension/script/InkscapePython.h +extension/script/InkscapeScript.cpp +extension/script/InkscapeScript.h +extension/script/inkscape_perl.pm.h +extension/script/inkscape_perl_wrap.cpp +extension/script/inkscape_py.py.h +extension/script/inkscape_py_wrap.cpp +extension/script/wrap_swig_module.sh +extension/system.cpp +extension/system.h +extension/timer.cpp +extension/timer.h +extract-uri.cpp +extract-uri.h +file.cpp +file.h +fill-or-stroke.h +fixes.cpp +fontsize-expansion.cpp +fontsize-expansion.h +forward.h +gc-alloc.h +gc-anchored.cpp +gc-anchored.h +gc-core.h +gc-finalized.h +gc-managed.h +gc.cpp +geom.cpp +geom.h +gnuc-attribute.h +gradient-chemistry.cpp +gradient-chemistry.h +gradient-context.cpp +gradient-context.h +gradient-drag.cpp +gradient-drag.h +grid-snapper.cpp +grid-snapper.h +guide-snapper.cpp +guide-snapper.h +help.cpp +help.h +helper/action.cpp +helper/action.h +helper/gnome-utils.cpp +helper/gnome-utils.h +helper/helper-forward.h +helper/png-write.cpp +helper/png-write.h +helper/sp-marshal.cpp +helper/sp-marshal.h +helper/stlport.h +helper/stock-items.cpp +helper/stock-items.h +helper/unit-menu.cpp +helper/unit-menu.h +helper/units.cpp +helper/units.h +helper/window.cpp +helper/window.h +inkjar/jar.cpp +inkjar/jar.h +inkscape-private.h +inkscape-stock.cpp +inkscape-stock.h +inkscape.cpp +inkscape.h +inkscape.rc +inkscape_version.h +interface.cpp +interface.h +io/base64stream.cpp +io/base64stream.h +io/ftos.cpp +io/ftos.h +io/gzipstream.cpp +io/gzipstream.h +io/inkscapestream.cpp +io/inkscapestream.h +io/simple-sax.cpp +io/simple-sax.h +io/stringstream.cpp +io/stringstream.h +io/sys.cpp +io/sys.h +io/uristream.cpp +io/uristream.h +io/xsltstream.cpp +io/xsltstream.h +isnan.h +knot-enums.h +knot-holder-entity.h +knot.cpp +knot.h +knotholder.cpp +knotholder.h +layer-fns.cpp +layer-fns.h +libavoid/connector.cpp +libavoid/connector.h +libavoid/debug.h +libavoid/geometry.cpp +libavoid/geometry.h +libavoid/geomtypes.h +libavoid/graph.cpp +libavoid/graph.h +libavoid/incremental.cpp +libavoid/incremental.h +libavoid/libavoid.h +libavoid/makepath.cpp +libavoid/makepath.h +libavoid/polyutil.cpp +libavoid/polyutil.h +libavoid/shape.cpp +libavoid/shape.h +libavoid/static.cpp +libavoid/static.h +libavoid/timer.cpp +libavoid/timer.h +libavoid/vertices.cpp +libavoid/vertices.h +libavoid/visibility.cpp +libavoid/visibility.h +libcroco/cr-additional-sel.c +libcroco/cr-additional-sel.h +libcroco/cr-attr-sel.c +libcroco/cr-attr-sel.h +libcroco/cr-cascade.c +libcroco/cr-cascade.h +libcroco/cr-declaration.c +libcroco/cr-declaration.h +libcroco/cr-doc-handler.c +libcroco/cr-doc-handler.h +libcroco/cr-enc-handler.c +libcroco/cr-enc-handler.h +libcroco/cr-fonts.c +libcroco/cr-fonts.h +libcroco/cr-input.c +libcroco/cr-input.h +libcroco/cr-libxml-node-iface.c +libcroco/cr-libxml-node-iface.h +libcroco/cr-node-iface.h +libcroco/cr-num.c +libcroco/cr-num.h +libcroco/cr-om-parser.c +libcroco/cr-om-parser.h +libcroco/cr-parser.c +libcroco/cr-parser.h +libcroco/cr-parsing-location.c +libcroco/cr-parsing-location.h +libcroco/cr-prop-list.c +libcroco/cr-prop-list.h +libcroco/cr-pseudo.c +libcroco/cr-pseudo.h +libcroco/cr-rgb.c +libcroco/cr-rgb.h +libcroco/cr-sel-eng.c +libcroco/cr-sel-eng.h +libcroco/cr-selector.c +libcroco/cr-selector.h +libcroco/cr-simple-sel.c +libcroco/cr-simple-sel.h +libcroco/cr-statement.c +libcroco/cr-statement.h +libcroco/cr-string.c +libcroco/cr-string.h +libcroco/cr-style.c +libcroco/cr-style.h +libcroco/cr-stylesheet.c +libcroco/cr-stylesheet.h +libcroco/cr-term.c +libcroco/cr-term.h +libcroco/cr-tknzr.c +libcroco/cr-tknzr.h +libcroco/cr-token.c +libcroco/cr-token.h +libcroco/cr-utils.c +libcroco/cr-utils.h +libcroco/libcroco.h +libnr/in-svg-plane-test.h +libnr/in-svg-plane.h +libnr/n-art-bpath.h +libnr/nr-blit.cpp +libnr/nr-blit.h +libnr/nr-compose-transform.cpp +libnr/nr-compose-transform.h +libnr/nr-compose.cpp +libnr/nr-compose.h +libnr/nr-convex-hull-ops.h +libnr/nr-convex-hull.h +libnr/nr-coord.h +libnr/nr-dim2.h +libnr/nr-forward.h +libnr/nr-gradient.cpp +libnr/nr-gradient.h +libnr/nr-i-coord.h +libnr/nr-macros.h +libnr/nr-matrix-div.cpp +libnr/nr-matrix-div.h +libnr/nr-matrix-fns.cpp +libnr/nr-matrix-fns.h +libnr/nr-matrix-ops.h +libnr/nr-matrix-rotate-ops.cpp +libnr/nr-matrix-rotate-ops.h +libnr/nr-matrix-scale-ops.cpp +libnr/nr-matrix-scale-ops.h +libnr/nr-matrix-test.h +libnr/nr-matrix-translate-ops.cpp +libnr/nr-matrix-translate-ops.h +libnr/nr-matrix.cpp +libnr/nr-matrix.h +libnr/nr-maybe.h +libnr/nr-object.cpp +libnr/nr-object.h +libnr/nr-path-code.h +libnr/nr-path.cpp +libnr/nr-path.h +libnr/nr-pixblock-line.cpp +libnr/nr-pixblock-line.h +libnr/nr-pixblock-pattern.cpp +libnr/nr-pixblock-pattern.h +libnr/nr-pixblock-pixel.cpp +libnr/nr-pixblock-pixel.h +libnr/nr-pixblock.cpp +libnr/nr-pixblock.h +libnr/nr-pixops.h +libnr/nr-point-fns-test.h +libnr/nr-point-fns.cpp +libnr/nr-point-fns.h +libnr/nr-point-l.h +libnr/nr-point-matrix-ops.h +libnr/nr-point-ops.h +libnr/nr-point.h +libnr/nr-rect-l.cpp +libnr/nr-rect-l.h +libnr/nr-rect-ops.h +libnr/nr-rect.cpp +libnr/nr-rect.h +libnr/nr-render.h +libnr/nr-rotate-fns-test.h +libnr/nr-rotate-fns.cpp +libnr/nr-rotate-fns.h +libnr/nr-rotate-matrix-ops.cpp +libnr/nr-rotate-matrix-ops.h +libnr/nr-rotate-ops.h +libnr/nr-rotate-test.h +libnr/nr-rotate.h +libnr/nr-scale-matrix-ops.cpp +libnr/nr-scale-matrix-ops.h +libnr/nr-scale-ops.h +libnr/nr-scale-test.h +libnr/nr-scale-translate-ops.cpp +libnr/nr-scale-translate-ops.h +libnr/nr-scale.h +libnr/nr-svp-private.h +libnr/nr-svp-render.cpp +libnr/nr-svp-render.h +libnr/nr-svp.cpp +libnr/nr-svp.h +libnr/nr-translate-matrix-ops.cpp +libnr/nr-translate-matrix-ops.h +libnr/nr-translate-ops.h +libnr/nr-translate-rotate-ops.cpp +libnr/nr-translate-rotate-ops.h +libnr/nr-translate-scale-ops.cpp +libnr/nr-translate-scale-ops.h +libnr/nr-translate-test.h +libnr/nr-translate.h +libnr/nr-types-test.h +libnr/nr-types.cpp +libnr/nr-types.h +libnr/nr-values.cpp +libnr/nr-values.h +libnr/testnr.cpp +libnrtype/FontFactory.cpp +libnrtype/FontFactory.h +libnrtype/FontInstance.cpp +libnrtype/Layout-TNG-Compute.cpp +libnrtype/Layout-TNG-Input.cpp +libnrtype/Layout-TNG-OutIter.cpp +libnrtype/Layout-TNG-Output.cpp +libnrtype/Layout-TNG-Scanline-Maker.h +libnrtype/Layout-TNG-Scanline-Makers.cpp +libnrtype/Layout-TNG.cpp +libnrtype/Layout-TNG.h +libnrtype/RasterFont.cpp +libnrtype/RasterFont.h +libnrtype/TextWrapper.cpp +libnrtype/TextWrapper.h +libnrtype/boundary-type.h +libnrtype/font-glyph.h +libnrtype/font-instance.h +libnrtype/font-style-to-pos.cpp +libnrtype/font-style-to-pos.h +libnrtype/font-style.h +libnrtype/nr-type-pos-def.cpp +libnrtype/nr-type-pos-def.h +libnrtype/nr-type-primitives.cpp +libnrtype/nr-type-primitives.h +libnrtype/nrtype-forward.h +libnrtype/one-box.h +libnrtype/one-glyph.h +libnrtype/one-para.h +libnrtype/raster-glyph.h +libnrtype/raster-position.h +libnrtype/text-boundary.h +line-snapper.cpp +line-snapper.h +livarot/AVL.cpp +livarot/AVL.h +livarot/AlphaLigne.cpp +livarot/AlphaLigne.h +livarot/BitLigne.cpp +livarot/BitLigne.h +livarot/Livarot.h +livarot/LivarotDefs.h +livarot/MyMath.h +livarot/MySeg.cpp +livarot/MySeg.h +livarot/Path.cpp +livarot/Path.h +livarot/PathConversion.cpp +livarot/PathCutting.cpp +livarot/PathOutline.cpp +livarot/PathSimplify.cpp +livarot/PathStroke.cpp +livarot/Shape.cpp +livarot/Shape.h +livarot/ShapeDraw.cpp +livarot/ShapeMisc.cpp +livarot/ShapeRaster.cpp +livarot/ShapeSweep.cpp +livarot/float-line.cpp +livarot/float-line.h +livarot/int-line.cpp +livarot/int-line.h +livarot/livarot-forward.h +livarot/path-description.cpp +livarot/path-description.h +livarot/sweep-event-queue.h +livarot/sweep-event.cpp +livarot/sweep-event.h +livarot/sweep-tree-list.cpp +livarot/sweep-tree-list.h +livarot/sweep-tree.cpp +livarot/sweep-tree.h +macros.h +marker-status.cpp +marker-status.h +media.cpp +media.h +memeq.h +menus-skeleton.h +message-context.cpp +message-context.h +message-stack.cpp +message-stack.h +message.h +mod360.cpp +mod360.h +modifier-fns.h +node-context.cpp +node-context.h +nodepath.cpp +nodepath.h +object-edit.cpp +object-edit.h +object-hierarchy.cpp +object-hierarchy.h +object-snapper.cpp +object-snapper.h +object-ui.cpp +object-ui.h +path-chemistry.cpp +path-chemistry.h +path-prefix.h +pen-context.cpp +pen-context.h +pencil-context.cpp +pencil-context.h +preferences-skeleton.h +preferences.cpp +preferences.h +prefix.cpp +prefix.h +prefs-utils.cpp +prefs-utils.h +print.cpp +print.h +rect-context.cpp +rect-context.h +registrytool.cpp +registrytool.h +remove-last.h +removeoverlap/block.cpp +removeoverlap/block.h +removeoverlap/blocks.cpp +removeoverlap/blocks.h +removeoverlap/constraint.cpp +removeoverlap/constraint.h +removeoverlap/generate-constraints.cpp +removeoverlap/generate-constraints.h +removeoverlap/pairingheap/PairingHeap.cpp +removeoverlap/pairingheap/PairingHeap.h +removeoverlap/pairingheap/dsexceptions.h +removeoverlap/remove_rectangle_overlap.cpp +removeoverlap/remove_rectangle_overlap.h +removeoverlap/removeoverlap.cpp +removeoverlap/removeoverlap.h +removeoverlap/solve_VPSC.cpp +removeoverlap/solve_VPSC.h +removeoverlap/variable.cpp +removeoverlap/variable.h +require-config.h +round.h +rubberband.cpp +rubberband.h +satisfied-guide-cns.cpp +satisfied-guide-cns.h +selcue.cpp +selcue.h +select-context.cpp +select-context.h +selection-chemistry.cpp +selection-chemistry.h +selection-describer.cpp +selection-describer.h +selection.cpp +selection.h +seltrans-handles.cpp +seltrans-handles.h +seltrans.cpp +seltrans.h +shortcuts-default-xml.cpp +shortcuts.cpp +shortcuts.h +slideshow.cpp +slideshow.h +snap.cpp +snap.h +snapped-point.cpp +snapped-point.h +snapper.cpp +snapper.h +sp-anchor.cpp +sp-anchor.h +sp-animation.cpp +sp-animation.h +sp-clippath.cpp +sp-clippath.h +sp-conn-end-pair.cpp +sp-conn-end-pair.h +sp-conn-end.cpp +sp-conn-end.h +sp-cursor.cpp +sp-cursor.h +sp-defs.cpp +sp-defs.h +sp-ellipse.cpp +sp-ellipse.h +sp-flowdiv.cpp +sp-flowdiv.h +sp-flowregion.cpp +sp-flowregion.h +sp-flowtext.cpp +sp-flowtext.h +sp-gradient-fns.h +sp-gradient-reference.cpp +sp-gradient-reference.h +sp-gradient-spread.h +sp-gradient-units.h +sp-gradient-vector.h +sp-gradient.cpp +sp-gradient.h +sp-guide-attachment.h +sp-guide-constraint.h +sp-guide.cpp +sp-guide.h +sp-image.cpp +sp-image.h +sp-item-group.cpp +sp-item-group.h +sp-item-notify-moveto.cpp +sp-item-notify-moveto.h +sp-item-rm-unsatisfied-cns.cpp +sp-item-rm-unsatisfied-cns.h +sp-item-transform.cpp +sp-item-transform.h +sp-item-update-cns.cpp +sp-item-update-cns.h +sp-item.cpp +sp-item.h +sp-line.cpp +sp-line.h +sp-linear-gradient-fns.h +sp-linear-gradient.h +sp-marker-loc.h +sp-marker.cpp +sp-marker.h +sp-mask.cpp +sp-mask.h +sp-metadata.cpp +sp-metadata.h +sp-metric.h +sp-metrics.cpp +sp-metrics.h +sp-namedview.cpp +sp-namedview.h +sp-object-group.cpp +sp-object-group.h +sp-object-repr.cpp +sp-object-repr.h +sp-object.cpp +sp-object.h +sp-offset.cpp +sp-offset.h +sp-paint-server.cpp +sp-paint-server.h +sp-path.cpp +sp-path.h +sp-pattern.cpp +sp-pattern.h +sp-polygon.cpp +sp-polygon.h +sp-polyline.cpp +sp-polyline.h +sp-radial-gradient-fns.h +sp-radial-gradient.h +sp-rect.cpp +sp-rect.h +sp-root.cpp +sp-root.h +sp-shape.cpp +sp-shape.h +sp-skeleton.cpp +sp-skeleton.h +sp-spiral.cpp +sp-spiral.h +sp-star.cpp +sp-star.h +sp-stop-fns.h +sp-stop.h +sp-string.cpp +sp-string.h +sp-style-elem-test.cpp +sp-style-elem.cpp +sp-style-elem.h +sp-symbol.cpp +sp-symbol.h +sp-text.cpp +sp-text.h +sp-textpath.h +sp-tspan.cpp +sp-tspan.h +sp-use-reference.cpp +sp-use-reference.h +sp-use.cpp +sp-use.h +spiral-context.cpp +spiral-context.h +splivarot.cpp +splivarot.h +star-context.cpp +star-context.h +streams-gzip.cpp +streams-gzip.h +streams-handles.cpp +streams-handles.h +streams-jar.cpp +streams-jar.h +streams-zlib.cpp +streams-zlib.h +streq.h +strneq.h +style-test.cpp +style.cpp +style.h +svg-profile.h +svg-view-widget.cpp +svg-view-widget.h +svg-view.cpp +svg-view.h +svg/css-ostringstream-test.h +svg/css-ostringstream.cpp +svg/css-ostringstream.h +svg/ftos.h +svg/gnome-canvas-bpath-util.cpp +svg/gnome-canvas-bpath-util.h +svg/itos.cpp +svg/round.cpp +svg/stringstream-test.h +svg/stringstream.cpp +svg/stringstream.h +svg/strip-trailing-zeros.cpp +svg/strip-trailing-zeros.h +svg/svg-affine.cpp +svg/svg-color.cpp +svg/svg-length.cpp +svg/svg-length.h +svg/svg-path.cpp +svg/svg.h +text-chemistry.cpp +text-chemistry.h +text-context.cpp +text-context.h +text-editing.cpp +text-editing.h +text-tag-attributes.h +tools-switch.cpp +tools-switch.h +trace/filterset.cpp +trace/filterset.h +trace/imagemap-gdk.cpp +trace/imagemap-gdk.h +trace/imagemap.cpp +trace/imagemap.h +trace/potrace/auxiliary.h +trace/potrace/bitmap.h +trace/potrace/curve.cpp +trace/potrace/curve.h +trace/potrace/decompose.cpp +trace/potrace/decompose.h +trace/potrace/greymap.cpp +trace/potrace/greymap.h +trace/potrace/inkscape-potrace.cpp +trace/potrace/inkscape-potrace.h +trace/potrace/lists.h +trace/potrace/potracelib.cpp +trace/potrace/potracelib.h +trace/potrace/progress.h +trace/potrace/render.cpp +trace/potrace/render.h +trace/potrace/trace.cpp +trace/potrace/trace.h +trace/trace.cpp +trace/trace.h +traits/copy.h +traits/function.h +traits/list-copy.h +traits/reference.h +ui/dialog/aboutbox.cpp +ui/dialog/aboutbox.h +ui/dialog/align-and-distribute.cpp +ui/dialog/align-and-distribute.h +ui/dialog/dialog-manager.cpp +ui/dialog/dialog-manager.h +ui/dialog/dialog.cpp +ui/dialog/dialog.h +ui/dialog/document-metadata.cpp +ui/dialog/document-metadata.h +ui/dialog/document-properties.cpp +ui/dialog/document-properties.h +ui/dialog/export.cpp +ui/dialog/export.h +ui/dialog/extension-editor.cpp +ui/dialog/extension-editor.h +ui/dialog/fill-and-stroke.cpp +ui/dialog/fill-and-stroke.h +ui/dialog/find.cpp +ui/dialog/find.h +ui/dialog/inkscape-preferences.cpp +ui/dialog/inkscape-preferences.h +ui/dialog/layer-editor.cpp +ui/dialog/layer-editor.h +ui/dialog/memory.cpp +ui/dialog/memory.h +ui/dialog/messages.cpp +ui/dialog/messages.h +ui/dialog/scriptdialog.cpp +ui/dialog/scriptdialog.h +ui/dialog/session-player.h +ui/dialog/text-properties.cpp +ui/dialog/text-properties.h +ui/dialog/tracedialog.cpp +ui/dialog/tracedialog.h +ui/dialog/transformation.cpp +ui/dialog/transformation.h +ui/dialog/tree-editor.cpp +ui/dialog/tree-editor.h +ui/dialog/whiteboard-connect.h +ui/dialog/whiteboard-sharewithchat.h +ui/dialog/whiteboard-sharewithuser.h +ui/dialog/xml-editor.cpp +ui/dialog/xml-editor.h +ui/icons.cpp +ui/icons.h +ui/previewable.h +ui/previewfillable.h +ui/previewholder.cpp +ui/previewholder.h +ui/stock-items.cpp +ui/stock-items.h +ui/stock.cpp +ui/stock.h +ui/view/desktop-affine.cpp +ui/view/desktop-affine.h +ui/view/desktop-events.cpp +ui/view/desktop-events.h +ui/view/desktop-handles.cpp +ui/view/desktop-handles.h +ui/view/desktop-style.cpp +ui/view/desktop-style.h +ui/view/desktop.cpp +ui/view/desktop.h +ui/view/edit-widget-interface.h +ui/view/edit-widget.cpp +ui/view/edit-widget.h +ui/view/edit.cpp +ui/view/edit.h +ui/view/view-widget.cpp +ui/view/view-widget.h +ui/view/view.cpp +ui/view/view.h +ui/widget/button.cpp +ui/widget/button.h +ui/widget/color-picker.cpp +ui/widget/color-picker.h +ui/widget/color-preview.cpp +ui/widget/color-preview.h +ui/widget/combo-text.cpp +ui/widget/combo-text.h +ui/widget/entity-entry.cpp +ui/widget/entity-entry.h +ui/widget/handlebox.cpp +ui/widget/handlebox.h +ui/widget/icon-widget.cpp +ui/widget/icon-widget.h +ui/widget/imageicon.cpp +ui/widget/imageicon.h +ui/widget/labelled.cpp +ui/widget/labelled.h +ui/widget/licensor.cpp +ui/widget/licensor.h +ui/widget/notebook-page.cpp +ui/widget/notebook-page.h +ui/widget/page-sizer.cpp +ui/widget/page-sizer.h +ui/widget/panel.cpp +ui/widget/panel.h +ui/widget/preferences-widget.cpp +ui/widget/preferences-widget.h +ui/widget/registered-widget.cpp +ui/widget/registered-widget.h +ui/widget/registry.cpp +ui/widget/registry.h +ui/widget/ruler.cpp +ui/widget/ruler.h +ui/widget/scalar-unit.cpp +ui/widget/scalar-unit.h +ui/widget/scalar.cpp +ui/widget/scalar.h +ui/widget/selected-style.cpp +ui/widget/selected-style.h +ui/widget/style-swatch.cpp +ui/widget/style-swatch.h +ui/widget/svg-canvas.cpp +ui/widget/svg-canvas.h +ui/widget/tolerance-slider.cpp +ui/widget/tolerance-slider.h +ui/widget/toolbox.cpp +ui/widget/toolbox.h +ui/widget/unit-menu.cpp +ui/widget/unit-menu.h +ui/widget/zoom-status.cpp +ui/widget/zoom-status.h +undo-stack-observer.h +unit-constants.h +uri-references.cpp +uri-references.h +uri.cpp +uri.h +util/compose.hpp +util/filter-list.h +util/forward-pointer-iterator.h +util/glib-list-iterators.h +util/list-container-test.cpp +util/list-container.h +util/list.h +util/map-list.h +util/reverse-list.h +util/shared-c-string-ptr.cpp +util/shared-c-string-ptr.h +util/tuple.h +util/ucompose.hpp +util/units.cpp +util/units.h +verbs.cpp +verbs.h +version.cpp +version.h +widgets/button.cpp +widgets/button.h +widgets/dash-selector.cpp +widgets/dash-selector.h +widgets/desktop-widget.cpp +widgets/desktop-widget.h +widgets/font-selector.cpp +widgets/font-selector.h +widgets/gradient-image.cpp +widgets/gradient-image.h +widgets/gradient-selector.cpp +widgets/gradient-selector.h +widgets/gradient-toolbar.cpp +widgets/gradient-toolbar.h +widgets/gradient-vector.cpp +widgets/gradient-vector.h +widgets/icon.cpp +widgets/icon.h +widgets/layer-selector.cpp +widgets/layer-selector.h +widgets/paint-selector.cpp +widgets/paint-selector.h +widgets/ruler.cpp +widgets/ruler.h +widgets/select-toolbar.cpp +widgets/select-toolbar.h +widgets/shrink-wrap-button.cpp +widgets/shrink-wrap-button.h +widgets/sp-color-gtkselector.cpp +widgets/sp-color-gtkselector.h +widgets/sp-color-notebook.cpp +widgets/sp-color-notebook.h +widgets/sp-color-preview.cpp +widgets/sp-color-preview.h +widgets/sp-color-scales.cpp +widgets/sp-color-scales.h +widgets/sp-color-selector.cpp +widgets/sp-color-selector.h +widgets/sp-color-slider.cpp +widgets/sp-color-slider.h +widgets/sp-color-wheel-selector.cpp +widgets/sp-color-wheel-selector.h +widgets/sp-color-wheel.cpp +widgets/sp-color-wheel.h +widgets/sp-widget.cpp +widgets/sp-widget.h +widgets/sp-xmlview-attr-list.cpp +widgets/sp-xmlview-attr-list.h +widgets/sp-xmlview-content.cpp +widgets/sp-xmlview-content.h +widgets/sp-xmlview-tree.cpp +widgets/sp-xmlview-tree.h +widgets/spinbutton-events.cpp +widgets/spinbutton-events.h +widgets/spw-utilities.cpp +widgets/spw-utilities.h +widgets/toolbox.cpp +widgets/toolbox.h +widgets/widget-sizes.h +xml/attribute-record.h +xml/comment-node.h +xml/composite-node-observer.cpp +xml/composite-node-observer.h +xml/croco-node-iface.cpp +xml/croco-node-iface.h +xml/document.h +xml/element-node.h +xml/event-fns.h +xml/event.cpp +xml/event.h +xml/invalid-operation-exception.h +xml/log-builder.cpp +xml/log-builder.h +xml/node-event-vector.h +xml/node-fns.cpp +xml/node-fns.h +xml/node-iterators.h +xml/node-observer.h +xml/node.h +xml/quote-test.h +xml/quote.cpp +xml/quote.h +xml/repr-action-test.h +xml/repr-css.cpp +xml/repr-io.cpp +xml/repr-sorting.cpp +xml/repr-sorting.h +xml/repr-util.cpp +xml/repr.cpp +xml/repr.h +xml/session.h +xml/simple-document.cpp +xml/simple-document.h +xml/simple-node.cpp +xml/simple-node.h +xml/simple-session.cpp +xml/simple-session.h +xml/sp-css-attr.h +xml/text-node.h +xml/transaction-logger.h +zoom-context.cpp +zoom-context.h diff --git a/src/make.ofiles b/src/make.ofiles new file mode 100644 index 000000000..a20ac2bc0 --- /dev/null +++ b/src/make.ofiles @@ -0,0 +1,1307 @@ +######################################################## +## File: make.ofiles +## Purpose: Object file listing for use by Makefiles +## Generated by mkdep.pl at :Sun Jan 15 07:06:17 2006 +## Do not edit this file! Changes will be lost. +######################################################## + +OBJECTS = \ + application/app-prototype.o \ + application/application.o \ + application/editor.o \ + arc-context.o \ + attributes-test.o \ + attributes.o \ + color.o \ + composite-undo-stack-observer.o \ + conn-avoid-ref.o \ + connector-context.o \ + context-fns.o \ + debug/heap.o \ + debug/logger.o \ + debug/sysv-heap.o \ + desktop-affine.o \ + desktop-events.o \ + desktop-handles.o \ + desktop-style.o \ + desktop.o \ + dialogs/clonetiler.o \ + dialogs/debugdialog.o \ + dialogs/dialog-events.o \ + dialogs/display-settings.o \ + dialogs/eek-preview.o \ + dialogs/export.o \ + dialogs/extensions.o \ + dialogs/filedialog.o \ + dialogs/fill-style.o \ + dialogs/find.o \ + dialogs/iconpreview.o \ + dialogs/in-dt-coordsys.o \ + dialogs/input.o \ + dialogs/item-properties.o \ + dialogs/layer-properties.o \ + dialogs/object-attributes.o \ + dialogs/object-properties.o \ + dialogs/rdf.o \ + dialogs/sp-attribute-widget.o \ + dialogs/stroke-style.o \ + dialogs/swatches.o \ + dialogs/text-edit.o \ + dialogs/tiledialog.o \ + dialogs/unclump.o \ + dialogs/xml-tree.o \ + dir-util-test.o \ + dir-util.o \ + display/bezier-utils.o \ + display/canvas-arena.o \ + display/canvas-bpath.o \ + display/canvas-grid.o \ + display/curve.o \ + display/gnome-canvas-acetate.o \ + display/guideline.o \ + display/nr-arena-glyphs.o \ + display/nr-arena-group.o \ + display/nr-arena-image.o \ + display/nr-arena-item.o \ + display/nr-arena-shape.o \ + display/nr-arena.o \ + display/nr-gradient-gpl.o \ + display/nr-plain-stuff-gdk.o \ + display/nr-plain-stuff.o \ + display/sodipodi-ctrl.o \ + display/sodipodi-ctrlrect.o \ + display/sp-canvas-util.o \ + display/sp-canvas.o \ + display/sp-ctrlline.o \ + display/sp-ctrlquadr.o \ + document-undo.o \ + document.o \ + dom/charclass.o \ + dom/cssparser.o \ + dom/domimpl.o \ + dom/domstream.o \ + dom/domstring.o \ + dom/js/fdlibm/e_acos.o \ + dom/js/fdlibm/e_acosh.o \ + dom/js/fdlibm/e_asin.o \ + dom/js/fdlibm/e_atan2.o \ + dom/js/fdlibm/e_atanh.o \ + dom/js/fdlibm/e_cosh.o \ + dom/js/fdlibm/e_exp.o \ + dom/js/fdlibm/e_fmod.o \ + dom/js/fdlibm/e_gamma.o \ + dom/js/fdlibm/e_gamma_r.o \ + dom/js/fdlibm/e_hypot.o \ + dom/js/fdlibm/e_j0.o \ + dom/js/fdlibm/e_j1.o \ + dom/js/fdlibm/e_jn.o \ + dom/js/fdlibm/e_lgamma.o \ + dom/js/fdlibm/e_lgamma_r.o \ + dom/js/fdlibm/e_log.o \ + dom/js/fdlibm/e_log10.o \ + dom/js/fdlibm/e_pow.o \ + dom/js/fdlibm/e_rem_pio2.o \ + dom/js/fdlibm/e_remainder.o \ + dom/js/fdlibm/e_scalb.o \ + dom/js/fdlibm/e_sinh.o \ + dom/js/fdlibm/e_sqrt.o \ + dom/js/fdlibm/k_cos.o \ + dom/js/fdlibm/k_rem_pio2.o \ + dom/js/fdlibm/k_sin.o \ + dom/js/fdlibm/k_standard.o \ + dom/js/fdlibm/k_tan.o \ + dom/js/fdlibm/s_asinh.o \ + dom/js/fdlibm/s_atan.o \ + dom/js/fdlibm/s_cbrt.o \ + dom/js/fdlibm/s_ceil.o \ + dom/js/fdlibm/s_copysign.o \ + dom/js/fdlibm/s_cos.o \ + dom/js/fdlibm/s_erf.o \ + dom/js/fdlibm/s_expm1.o \ + dom/js/fdlibm/s_fabs.o \ + dom/js/fdlibm/s_finite.o \ + dom/js/fdlibm/s_floor.o \ + dom/js/fdlibm/s_frexp.o \ + dom/js/fdlibm/s_ilogb.o \ + dom/js/fdlibm/s_isnan.o \ + dom/js/fdlibm/s_ldexp.o \ + dom/js/fdlibm/s_lib_version.o \ + dom/js/fdlibm/s_log1p.o \ + dom/js/fdlibm/s_logb.o \ + dom/js/fdlibm/s_matherr.o \ + dom/js/fdlibm/s_modf.o \ + dom/js/fdlibm/s_nextafter.o \ + dom/js/fdlibm/s_rint.o \ + dom/js/fdlibm/s_scalbn.o \ + dom/js/fdlibm/s_signgam.o \ + dom/js/fdlibm/s_significand.o \ + dom/js/fdlibm/s_sin.o \ + dom/js/fdlibm/s_tan.o \ + dom/js/fdlibm/s_tanh.o \ + dom/js/fdlibm/w_acos.o \ + dom/js/fdlibm/w_acosh.o \ + dom/js/fdlibm/w_asin.o \ + dom/js/fdlibm/w_atan2.o \ + dom/js/fdlibm/w_atanh.o \ + dom/js/fdlibm/w_cosh.o \ + dom/js/fdlibm/w_exp.o \ + dom/js/fdlibm/w_fmod.o \ + dom/js/fdlibm/w_gamma.o \ + dom/js/fdlibm/w_gamma_r.o \ + dom/js/fdlibm/w_hypot.o \ + dom/js/fdlibm/w_j0.o \ + dom/js/fdlibm/w_j1.o \ + dom/js/fdlibm/w_jn.o \ + dom/js/fdlibm/w_lgamma.o \ + dom/js/fdlibm/w_lgamma_r.o \ + dom/js/fdlibm/w_log.o \ + dom/js/fdlibm/w_log10.o \ + dom/js/fdlibm/w_pow.o \ + dom/js/fdlibm/w_remainder.o \ + dom/js/fdlibm/w_scalb.o \ + dom/js/fdlibm/w_sinh.o \ + dom/js/fdlibm/w_sqrt.o \ + dom/js/js.o \ + dom/js/jsapi.o \ + dom/js/jsarena.o \ + dom/js/jsarray.o \ + dom/js/jsatom.o \ + dom/js/jsbool.o \ + dom/js/jscntxt.o \ + dom/js/jscpucfg.o \ + dom/js/jsdate.o \ + dom/js/jsdbgapi.o \ + dom/js/jsdhash.o \ + dom/js/jsdtoa.o \ + dom/js/jsemit.o \ + dom/js/jsexn.o \ + dom/js/jsfile.o \ + dom/js/jsfun.o \ + dom/js/jsgc.o \ + dom/js/jshash.o \ + dom/js/jsinterp.o \ + dom/js/jslock.o \ + dom/js/jslog2.o \ + dom/js/jslong.o \ + dom/js/jsmath.o \ + dom/js/jsnum.o \ + dom/js/jsobj.o \ + dom/js/jsopcode.o \ + dom/js/jsparse.o \ + dom/js/jsprf.o \ + dom/js/jsregexp.o \ + dom/js/jsscan.o \ + dom/js/jsscope.o \ + dom/js/jsscript.o \ + dom/js/jsstr.o \ + dom/js/jsutil.o \ + dom/js/jsxdrapi.o \ + dom/js/prmjtime.o \ + dom/lsimpl.o \ + dom/prop-css.o \ + dom/prop-css2.o \ + dom/prop-svg.o \ + dom/smilimpl.o \ + dom/stringstream.o \ + dom/svgimpl.o \ + dom/svglsimpl.o \ + dom/svgparser.o \ + dom/uri.o \ + dom/uristream.o \ + dom/uritest.o \ + dom/xmlreader.o \ + dom/xpathimpl.o \ + dom/xpathparser.o \ + draw-anchor.o \ + draw-context.o \ + dropper-context.o \ + dyna-draw-context.o \ + event-context.o \ + extension/db.o \ + extension/dependency.o \ + extension/effect.o \ + extension/error-file.o \ + extension/extension.o \ + extension/implementation/implementation.o \ + extension/implementation/plugin.o \ + extension/implementation/script.o \ + extension/init.o \ + extension/input.o \ + extension/internal/bluredge.o \ + extension/internal/eps-out.o \ + extension/internal/gdkpixbuf-input.o \ + extension/internal/gimpgrad.o \ + extension/internal/grid.o \ + extension/internal/latex-pstricks-out.o \ + extension/internal/latex-pstricks.o \ + extension/internal/pov-out.o \ + extension/internal/ps-out.o \ + extension/internal/ps.o \ + extension/internal/svg.o \ + extension/internal/svgz.o \ + extension/internal/win32.o \ + extension/output.o \ + extension/parameter.o \ + extension/prefdialog.o \ + extension/print.o \ + extension/script/InkscapeBinding.o \ + extension/script/InkscapeInterpreter.o \ + extension/script/InkscapePerl.o \ + extension/script/InkscapePython.o \ + extension/script/InkscapeScript.o \ + extension/script/inkscape_perl_wrap.o \ + extension/script/inkscape_py_wrap.o \ + extension/system.o \ + extension/timer.o \ + extract-uri.o \ + file.o \ + fixes.o \ + fontsize-expansion.o \ + gc-anchored.o \ + gc.o \ + geom.o \ + gradient-chemistry.o \ + gradient-context.o \ + gradient-drag.o \ + grid-snapper.o \ + guide-snapper.o \ + help.o \ + helper/action.o \ + helper/gnome-utils.o \ + helper/png-write.o \ + helper/sp-marshal.o \ + helper/stock-items.o \ + helper/unit-menu.o \ + helper/units.o \ + helper/window.o \ + inkjar/jar.o \ + inkscape-stock.o \ + inkscape.o \ + interface.o \ + io/base64stream.o \ + io/ftos.o \ + io/gzipstream.o \ + io/inkscapestream.o \ + io/simple-sax.o \ + io/stringstream.o \ + io/sys.o \ + io/uristream.o \ + io/xsltstream.o \ + knot.o \ + knotholder.o \ + layer-fns.o \ + libavoid/connector.o \ + libavoid/geometry.o \ + libavoid/graph.o \ + libavoid/incremental.o \ + libavoid/makepath.o \ + libavoid/polyutil.o \ + libavoid/shape.o \ + libavoid/static.o \ + libavoid/timer.o \ + libavoid/vertices.o \ + libavoid/visibility.o \ + libcroco/cr-additional-sel.o \ + libcroco/cr-attr-sel.o \ + libcroco/cr-cascade.o \ + libcroco/cr-declaration.o \ + libcroco/cr-doc-handler.o \ + libcroco/cr-enc-handler.o \ + libcroco/cr-fonts.o \ + libcroco/cr-input.o \ + libcroco/cr-libxml-node-iface.o \ + libcroco/cr-num.o \ + libcroco/cr-om-parser.o \ + libcroco/cr-parser.o \ + libcroco/cr-parsing-location.o \ + libcroco/cr-prop-list.o \ + libcroco/cr-pseudo.o \ + libcroco/cr-rgb.o \ + libcroco/cr-sel-eng.o \ + libcroco/cr-selector.o \ + libcroco/cr-simple-sel.o \ + libcroco/cr-statement.o \ + libcroco/cr-string.o \ + libcroco/cr-style.o \ + libcroco/cr-stylesheet.o \ + libcroco/cr-term.o \ + libcroco/cr-tknzr.o \ + libcroco/cr-token.o \ + libcroco/cr-utils.o \ + libnr/nr-blit.o \ + libnr/nr-compose-transform.o \ + libnr/nr-compose.o \ + libnr/nr-gradient.o \ + libnr/nr-matrix-div.o \ + libnr/nr-matrix-fns.o \ + libnr/nr-matrix-rotate-ops.o \ + libnr/nr-matrix-scale-ops.o \ + libnr/nr-matrix-translate-ops.o \ + libnr/nr-matrix.o \ + libnr/nr-object.o \ + libnr/nr-path.o \ + libnr/nr-pixblock-line.o \ + libnr/nr-pixblock-pattern.o \ + libnr/nr-pixblock-pixel.o \ + libnr/nr-pixblock.o \ + libnr/nr-point-fns.o \ + libnr/nr-rect-l.o \ + libnr/nr-rect.o \ + libnr/nr-rotate-fns.o \ + libnr/nr-rotate-matrix-ops.o \ + libnr/nr-scale-matrix-ops.o \ + libnr/nr-scale-translate-ops.o \ + libnr/nr-svp-render.o \ + libnr/nr-svp.o \ + libnr/nr-translate-matrix-ops.o \ + libnr/nr-translate-rotate-ops.o \ + libnr/nr-translate-scale-ops.o \ + libnr/nr-types.o \ + libnr/nr-values.o \ + libnr/testnr.o \ + libnrtype/FontFactory.o \ + libnrtype/FontInstance.o \ + libnrtype/Layout-TNG-Compute.o \ + libnrtype/Layout-TNG-Input.o \ + libnrtype/Layout-TNG-OutIter.o \ + libnrtype/Layout-TNG-Output.o \ + libnrtype/Layout-TNG-Scanline-Makers.o \ + libnrtype/Layout-TNG.o \ + libnrtype/RasterFont.o \ + libnrtype/TextWrapper.o \ + libnrtype/font-style-to-pos.o \ + libnrtype/nr-type-pos-def.o \ + libnrtype/nr-type-primitives.o \ + line-snapper.o \ + livarot/AVL.o \ + livarot/AlphaLigne.o \ + livarot/BitLigne.o \ + livarot/MySeg.o \ + livarot/Path.o \ + livarot/PathConversion.o \ + livarot/PathCutting.o \ + livarot/PathOutline.o \ + livarot/PathSimplify.o \ + livarot/PathStroke.o \ + livarot/Shape.o \ + livarot/ShapeDraw.o \ + livarot/ShapeMisc.o \ + livarot/ShapeRaster.o \ + livarot/ShapeSweep.o \ + livarot/float-line.o \ + livarot/int-line.o \ + livarot/path-description.o \ + livarot/sweep-event.o \ + livarot/sweep-tree-list.o \ + livarot/sweep-tree.o \ + marker-status.o \ + media.o \ + message-context.o \ + message-stack.o \ + mod360.o \ + node-context.o \ + nodepath.o \ + object-edit.o \ + object-hierarchy.o \ + object-snapper.o \ + object-ui.o \ + path-chemistry.o \ + pen-context.o \ + pencil-context.o \ + preferences.o \ + prefix.o \ + prefs-utils.o \ + print.o \ + rect-context.o \ + registrytool.o \ + removeoverlap/block.o \ + removeoverlap/blocks.o \ + removeoverlap/constraint.o \ + removeoverlap/generate-constraints.o \ + removeoverlap/pairingheap/PairingHeap.o \ + removeoverlap/remove_rectangle_overlap.o \ + removeoverlap/removeoverlap.o \ + removeoverlap/solve_VPSC.o \ + removeoverlap/variable.o \ + rubberband.o \ + satisfied-guide-cns.o \ + selcue.o \ + select-context.o \ + selection-chemistry.o \ + selection-describer.o \ + selection.o \ + seltrans-handles.o \ + seltrans.o \ + shortcuts-default-xml.o \ + shortcuts.o \ + slideshow.o \ + snap.o \ + snapped-point.o \ + snapper.o \ + sp-anchor.o \ + sp-animation.o \ + sp-clippath.o \ + sp-conn-end-pair.o \ + sp-conn-end.o \ + sp-cursor.o \ + sp-defs.o \ + sp-ellipse.o \ + sp-flowdiv.o \ + sp-flowregion.o \ + sp-flowtext.o \ + sp-gradient-reference.o \ + sp-gradient.o \ + sp-guide.o \ + sp-image.o \ + sp-item-group.o \ + sp-item-notify-moveto.o \ + sp-item-rm-unsatisfied-cns.o \ + sp-item-transform.o \ + sp-item-update-cns.o \ + sp-item.o \ + sp-line.o \ + sp-marker.o \ + sp-mask.o \ + sp-metadata.o \ + sp-metrics.o \ + sp-namedview.o \ + sp-object-group.o \ + sp-object-repr.o \ + sp-object.o \ + sp-offset.o \ + sp-paint-server.o \ + sp-path.o \ + sp-pattern.o \ + sp-polygon.o \ + sp-polyline.o \ + sp-rect.o \ + sp-root.o \ + sp-shape.o \ + sp-skeleton.o \ + sp-spiral.o \ + sp-star.o \ + sp-string.o \ + sp-style-elem-test.o \ + sp-style-elem.o \ + sp-symbol.o \ + sp-text.o \ + sp-tspan.o \ + sp-use-reference.o \ + sp-use.o \ + spiral-context.o \ + splivarot.o \ + star-context.o \ + streams-gzip.o \ + streams-handles.o \ + streams-jar.o \ + streams-zlib.o \ + style-test.o \ + style.o \ + svg-view-widget.o \ + svg-view.o \ + svg/css-ostringstream.o \ + svg/gnome-canvas-bpath-util.o \ + svg/itos.o \ + svg/round.o \ + svg/stringstream.o \ + svg/strip-trailing-zeros.o \ + svg/svg-affine.o \ + svg/svg-color.o \ + svg/svg-length.o \ + svg/svg-path.o \ + text-chemistry.o \ + text-context.o \ + text-editing.o \ + tools-switch.o \ + trace/filterset.o \ + trace/imagemap-gdk.o \ + trace/imagemap.o \ + trace/potrace/curve.o \ + trace/potrace/decompose.o \ + trace/potrace/greymap.o \ + trace/potrace/inkscape-potrace.o \ + trace/potrace/potracelib.o \ + trace/potrace/render.o \ + trace/potrace/trace.o \ + trace/trace.o \ + ui/dialog/aboutbox.o \ + ui/dialog/align-and-distribute.o \ + ui/dialog/dialog-manager.o \ + ui/dialog/dialog.o \ + ui/dialog/document-metadata.o \ + ui/dialog/document-properties.o \ + ui/dialog/export.o \ + ui/dialog/extension-editor.o \ + ui/dialog/fill-and-stroke.o \ + ui/dialog/find.o \ + ui/dialog/inkscape-preferences.o \ + ui/dialog/layer-editor.o \ + ui/dialog/memory.o \ + ui/dialog/messages.o \ + ui/dialog/scriptdialog.o \ + ui/dialog/text-properties.o \ + ui/dialog/tracedialog.o \ + ui/dialog/transformation.o \ + ui/dialog/tree-editor.o \ + ui/dialog/xml-editor.o \ + ui/icons.o \ + ui/previewholder.o \ + ui/stock-items.o \ + ui/stock.o \ + ui/view/desktop-affine.o \ + ui/view/desktop-events.o \ + ui/view/desktop-handles.o \ + ui/view/desktop-style.o \ + ui/view/desktop.o \ + ui/view/edit-widget.o \ + ui/view/edit.o \ + ui/view/view-widget.o \ + ui/view/view.o \ + ui/widget/button.o \ + ui/widget/color-picker.o \ + ui/widget/color-preview.o \ + ui/widget/combo-text.o \ + ui/widget/entity-entry.o \ + ui/widget/handlebox.o \ + ui/widget/icon-widget.o \ + ui/widget/imageicon.o \ + ui/widget/labelled.o \ + ui/widget/licensor.o \ + ui/widget/notebook-page.o \ + ui/widget/page-sizer.o \ + ui/widget/panel.o \ + ui/widget/preferences-widget.o \ + ui/widget/registered-widget.o \ + ui/widget/registry.o \ + ui/widget/ruler.o \ + ui/widget/scalar-unit.o \ + ui/widget/scalar.o \ + ui/widget/selected-style.o \ + ui/widget/style-swatch.o \ + ui/widget/svg-canvas.o \ + ui/widget/tolerance-slider.o \ + ui/widget/toolbox.o \ + ui/widget/unit-menu.o \ + ui/widget/zoom-status.o \ + uri-references.o \ + uri.o \ + util/list-container-test.o \ + util/shared-c-string-ptr.o \ + util/units.o \ + verbs.o \ + version.o \ + widgets/button.o \ + widgets/dash-selector.o \ + widgets/desktop-widget.o \ + widgets/font-selector.o \ + widgets/gradient-image.o \ + widgets/gradient-selector.o \ + widgets/gradient-toolbar.o \ + widgets/gradient-vector.o \ + widgets/icon.o \ + widgets/layer-selector.o \ + widgets/paint-selector.o \ + widgets/ruler.o \ + widgets/select-toolbar.o \ + widgets/shrink-wrap-button.o \ + widgets/sp-color-gtkselector.o \ + widgets/sp-color-notebook.o \ + widgets/sp-color-preview.o \ + widgets/sp-color-scales.o \ + widgets/sp-color-selector.o \ + widgets/sp-color-slider.o \ + widgets/sp-color-wheel-selector.o \ + widgets/sp-color-wheel.o \ + widgets/sp-widget.o \ + widgets/sp-xmlview-attr-list.o \ + widgets/sp-xmlview-content.o \ + widgets/sp-xmlview-tree.o \ + widgets/spinbutton-events.o \ + widgets/spw-utilities.o \ + widgets/toolbox.o \ + xml/composite-node-observer.o \ + xml/croco-node-iface.o \ + xml/event.o \ + xml/log-builder.o \ + xml/node-fns.o \ + xml/quote.o \ + xml/repr-css.o \ + xml/repr-io.o \ + xml/repr-sorting.o \ + xml/repr-util.o \ + xml/repr.o \ + xml/simple-document.o \ + xml/simple-node.o \ + xml/simple-session.o \ + zoom-context.o + +LINTS = \ + application/app-prototype.lint \ + application/application.lint \ + application/editor.lint \ + arc-context.lint \ + attributes-test.lint \ + attributes.lint \ + color.lint \ + composite-undo-stack-observer.lint \ + conn-avoid-ref.lint \ + connector-context.lint \ + context-fns.lint \ + debug/heap.lint \ + debug/logger.lint \ + debug/sysv-heap.lint \ + desktop-affine.lint \ + desktop-events.lint \ + desktop-handles.lint \ + desktop-style.lint \ + desktop.lint \ + dialogs/clonetiler.lint \ + dialogs/debugdialog.lint \ + dialogs/dialog-events.lint \ + dialogs/display-settings.lint \ + dialogs/eek-preview.lint \ + dialogs/export.lint \ + dialogs/extensions.lint \ + dialogs/filedialog.lint \ + dialogs/fill-style.lint \ + dialogs/find.lint \ + dialogs/iconpreview.lint \ + dialogs/in-dt-coordsys.lint \ + dialogs/input.lint \ + dialogs/item-properties.lint \ + dialogs/layer-properties.lint \ + dialogs/object-attributes.lint \ + dialogs/object-properties.lint \ + dialogs/rdf.lint \ + dialogs/sp-attribute-widget.lint \ + dialogs/stroke-style.lint \ + dialogs/swatches.lint \ + dialogs/text-edit.lint \ + dialogs/tiledialog.lint \ + dialogs/unclump.lint \ + dialogs/xml-tree.lint \ + dir-util-test.lint \ + dir-util.lint \ + display/bezier-utils.lint \ + display/canvas-arena.lint \ + display/canvas-bpath.lint \ + display/canvas-grid.lint \ + display/curve.lint \ + display/gnome-canvas-acetate.lint \ + display/guideline.lint \ + display/nr-arena-glyphs.lint \ + display/nr-arena-group.lint \ + display/nr-arena-image.lint \ + display/nr-arena-item.lint \ + display/nr-arena-shape.lint \ + display/nr-arena.lint \ + display/nr-gradient-gpl.lint \ + display/nr-plain-stuff-gdk.lint \ + display/nr-plain-stuff.lint \ + display/sodipodi-ctrl.lint \ + display/sodipodi-ctrlrect.lint \ + display/sp-canvas-util.lint \ + display/sp-canvas.lint \ + display/sp-ctrlline.lint \ + display/sp-ctrlquadr.lint \ + document-undo.lint \ + document.lint \ + dom/charclass.lint \ + dom/cssparser.lint \ + dom/domimpl.lint \ + dom/domstream.lint \ + dom/domstring.lint \ + dom/js/fdlibm/e_acos.lint \ + dom/js/fdlibm/e_acosh.lint \ + dom/js/fdlibm/e_asin.lint \ + dom/js/fdlibm/e_atan2.lint \ + dom/js/fdlibm/e_atanh.lint \ + dom/js/fdlibm/e_cosh.lint \ + dom/js/fdlibm/e_exp.lint \ + dom/js/fdlibm/e_fmod.lint \ + dom/js/fdlibm/e_gamma.lint \ + dom/js/fdlibm/e_gamma_r.lint \ + dom/js/fdlibm/e_hypot.lint \ + dom/js/fdlibm/e_j0.lint \ + dom/js/fdlibm/e_j1.lint \ + dom/js/fdlibm/e_jn.lint \ + dom/js/fdlibm/e_lgamma.lint \ + dom/js/fdlibm/e_lgamma_r.lint \ + dom/js/fdlibm/e_log.lint \ + dom/js/fdlibm/e_log10.lint \ + dom/js/fdlibm/e_pow.lint \ + dom/js/fdlibm/e_rem_pio2.lint \ + dom/js/fdlibm/e_remainder.lint \ + dom/js/fdlibm/e_scalb.lint \ + dom/js/fdlibm/e_sinh.lint \ + dom/js/fdlibm/e_sqrt.lint \ + dom/js/fdlibm/k_cos.lint \ + dom/js/fdlibm/k_rem_pio2.lint \ + dom/js/fdlibm/k_sin.lint \ + dom/js/fdlibm/k_standard.lint \ + dom/js/fdlibm/k_tan.lint \ + dom/js/fdlibm/s_asinh.lint \ + dom/js/fdlibm/s_atan.lint \ + dom/js/fdlibm/s_cbrt.lint \ + dom/js/fdlibm/s_ceil.lint \ + dom/js/fdlibm/s_copysign.lint \ + dom/js/fdlibm/s_cos.lint \ + dom/js/fdlibm/s_erf.lint \ + dom/js/fdlibm/s_expm1.lint \ + dom/js/fdlibm/s_fabs.lint \ + dom/js/fdlibm/s_finite.lint \ + dom/js/fdlibm/s_floor.lint \ + dom/js/fdlibm/s_frexp.lint \ + dom/js/fdlibm/s_ilogb.lint \ + dom/js/fdlibm/s_isnan.lint \ + dom/js/fdlibm/s_ldexp.lint \ + dom/js/fdlibm/s_lib_version.lint \ + dom/js/fdlibm/s_log1p.lint \ + dom/js/fdlibm/s_logb.lint \ + dom/js/fdlibm/s_matherr.lint \ + dom/js/fdlibm/s_modf.lint \ + dom/js/fdlibm/s_nextafter.lint \ + dom/js/fdlibm/s_rint.lint \ + dom/js/fdlibm/s_scalbn.lint \ + dom/js/fdlibm/s_signgam.lint \ + dom/js/fdlibm/s_significand.lint \ + dom/js/fdlibm/s_sin.lint \ + dom/js/fdlibm/s_tan.lint \ + dom/js/fdlibm/s_tanh.lint \ + dom/js/fdlibm/w_acos.lint \ + dom/js/fdlibm/w_acosh.lint \ + dom/js/fdlibm/w_asin.lint \ + dom/js/fdlibm/w_atan2.lint \ + dom/js/fdlibm/w_atanh.lint \ + dom/js/fdlibm/w_cosh.lint \ + dom/js/fdlibm/w_exp.lint \ + dom/js/fdlibm/w_fmod.lint \ + dom/js/fdlibm/w_gamma.lint \ + dom/js/fdlibm/w_gamma_r.lint \ + dom/js/fdlibm/w_hypot.lint \ + dom/js/fdlibm/w_j0.lint \ + dom/js/fdlibm/w_j1.lint \ + dom/js/fdlibm/w_jn.lint \ + dom/js/fdlibm/w_lgamma.lint \ + dom/js/fdlibm/w_lgamma_r.lint \ + dom/js/fdlibm/w_log.lint \ + dom/js/fdlibm/w_log10.lint \ + dom/js/fdlibm/w_pow.lint \ + dom/js/fdlibm/w_remainder.lint \ + dom/js/fdlibm/w_scalb.lint \ + dom/js/fdlibm/w_sinh.lint \ + dom/js/fdlibm/w_sqrt.lint \ + dom/js/js.lint \ + dom/js/jsapi.lint \ + dom/js/jsarena.lint \ + dom/js/jsarray.lint \ + dom/js/jsatom.lint \ + dom/js/jsbool.lint \ + dom/js/jscntxt.lint \ + dom/js/jscpucfg.lint \ + dom/js/jsdate.lint \ + dom/js/jsdbgapi.lint \ + dom/js/jsdhash.lint \ + dom/js/jsdtoa.lint \ + dom/js/jsemit.lint \ + dom/js/jsexn.lint \ + dom/js/jsfile.lint \ + dom/js/jsfun.lint \ + dom/js/jsgc.lint \ + dom/js/jshash.lint \ + dom/js/jsinterp.lint \ + dom/js/jslock.lint \ + dom/js/jslog2.lint \ + dom/js/jslong.lint \ + dom/js/jsmath.lint \ + dom/js/jsnum.lint \ + dom/js/jsobj.lint \ + dom/js/jsopcode.lint \ + dom/js/jsparse.lint \ + dom/js/jsprf.lint \ + dom/js/jsregexp.lint \ + dom/js/jsscan.lint \ + dom/js/jsscope.lint \ + dom/js/jsscript.lint \ + dom/js/jsstr.lint \ + dom/js/jsutil.lint \ + dom/js/jsxdrapi.lint \ + dom/js/prmjtime.lint \ + dom/lsimpl.lint \ + dom/prop-css.lint \ + dom/prop-css2.lint \ + dom/prop-svg.lint \ + dom/smilimpl.lint \ + dom/stringstream.lint \ + dom/svgimpl.lint \ + dom/svglsimpl.lint \ + dom/svgparser.lint \ + dom/uri.lint \ + dom/uristream.lint \ + dom/uritest.lint \ + dom/xmlreader.lint \ + dom/xpathimpl.lint \ + dom/xpathparser.lint \ + draw-anchor.lint \ + draw-context.lint \ + dropper-context.lint \ + dyna-draw-context.lint \ + event-context.lint \ + extension/db.lint \ + extension/dependency.lint \ + extension/effect.lint \ + extension/error-file.lint \ + extension/extension.lint \ + extension/implementation/implementation.lint \ + extension/implementation/plugin.lint \ + extension/implementation/script.lint \ + extension/init.lint \ + extension/input.lint \ + extension/internal/bluredge.lint \ + extension/internal/eps-out.lint \ + extension/internal/gdkpixbuf-input.lint \ + extension/internal/gimpgrad.lint \ + extension/internal/grid.lint \ + extension/internal/latex-pstricks-out.lint \ + extension/internal/latex-pstricks.lint \ + extension/internal/pov-out.lint \ + extension/internal/ps-out.lint \ + extension/internal/ps.lint \ + extension/internal/svg.lint \ + extension/internal/svgz.lint \ + extension/internal/win32.lint \ + extension/output.lint \ + extension/parameter.lint \ + extension/prefdialog.lint \ + extension/print.lint \ + extension/script/InkscapeBinding.lint \ + extension/script/InkscapeInterpreter.lint \ + extension/script/InkscapePerl.lint \ + extension/script/InkscapePython.lint \ + extension/script/InkscapeScript.lint \ + extension/script/inkscape_perl_wrap.lint \ + extension/script/inkscape_py_wrap.lint \ + extension/system.lint \ + extension/timer.lint \ + extract-uri.lint \ + file.lint \ + fixes.lint \ + fontsize-expansion.lint \ + gc-anchored.lint \ + gc.lint \ + geom.lint \ + gradient-chemistry.lint \ + gradient-context.lint \ + gradient-drag.lint \ + grid-snapper.lint \ + guide-snapper.lint \ + help.lint \ + helper/action.lint \ + helper/gnome-utils.lint \ + helper/png-write.lint \ + helper/sp-marshal.lint \ + helper/stock-items.lint \ + helper/unit-menu.lint \ + helper/units.lint \ + helper/window.lint \ + inkjar/jar.lint \ + inkscape-stock.lint \ + inkscape.lint \ + interface.lint \ + io/base64stream.lint \ + io/ftos.lint \ + io/gzipstream.lint \ + io/inkscapestream.lint \ + io/simple-sax.lint \ + io/stringstream.lint \ + io/sys.lint \ + io/uristream.lint \ + io/xsltstream.lint \ + knot.lint \ + knotholder.lint \ + layer-fns.lint \ + libavoid/connector.lint \ + libavoid/geometry.lint \ + libavoid/graph.lint \ + libavoid/incremental.lint \ + libavoid/makepath.lint \ + libavoid/polyutil.lint \ + libavoid/shape.lint \ + libavoid/static.lint \ + libavoid/timer.lint \ + libavoid/vertices.lint \ + libavoid/visibility.lint \ + libcroco/cr-additional-sel.lint \ + libcroco/cr-attr-sel.lint \ + libcroco/cr-cascade.lint \ + libcroco/cr-declaration.lint \ + libcroco/cr-doc-handler.lint \ + libcroco/cr-enc-handler.lint \ + libcroco/cr-fonts.lint \ + libcroco/cr-input.lint \ + libcroco/cr-libxml-node-iface.lint \ + libcroco/cr-num.lint \ + libcroco/cr-om-parser.lint \ + libcroco/cr-parser.lint \ + libcroco/cr-parsing-location.lint \ + libcroco/cr-prop-list.lint \ + libcroco/cr-pseudo.lint \ + libcroco/cr-rgb.lint \ + libcroco/cr-sel-eng.lint \ + libcroco/cr-selector.lint \ + libcroco/cr-simple-sel.lint \ + libcroco/cr-statement.lint \ + libcroco/cr-string.lint \ + libcroco/cr-style.lint \ + libcroco/cr-stylesheet.lint \ + libcroco/cr-term.lint \ + libcroco/cr-tknzr.lint \ + libcroco/cr-token.lint \ + libcroco/cr-utils.lint \ + libnr/nr-blit.lint \ + libnr/nr-compose-transform.lint \ + libnr/nr-compose.lint \ + libnr/nr-gradient.lint \ + libnr/nr-matrix-div.lint \ + libnr/nr-matrix-fns.lint \ + libnr/nr-matrix-rotate-ops.lint \ + libnr/nr-matrix-scale-ops.lint \ + libnr/nr-matrix-translate-ops.lint \ + libnr/nr-matrix.lint \ + libnr/nr-object.lint \ + libnr/nr-path.lint \ + libnr/nr-pixblock-line.lint \ + libnr/nr-pixblock-pattern.lint \ + libnr/nr-pixblock-pixel.lint \ + libnr/nr-pixblock.lint \ + libnr/nr-point-fns.lint \ + libnr/nr-rect-l.lint \ + libnr/nr-rect.lint \ + libnr/nr-rotate-fns.lint \ + libnr/nr-rotate-matrix-ops.lint \ + libnr/nr-scale-matrix-ops.lint \ + libnr/nr-scale-translate-ops.lint \ + libnr/nr-svp-render.lint \ + libnr/nr-svp.lint \ + libnr/nr-translate-matrix-ops.lint \ + libnr/nr-translate-rotate-ops.lint \ + libnr/nr-translate-scale-ops.lint \ + libnr/nr-types.lint \ + libnr/nr-values.lint \ + libnr/testnr.lint \ + libnrtype/FontFactory.lint \ + libnrtype/FontInstance.lint \ + libnrtype/Layout-TNG-Compute.lint \ + libnrtype/Layout-TNG-Input.lint \ + libnrtype/Layout-TNG-OutIter.lint \ + libnrtype/Layout-TNG-Output.lint \ + libnrtype/Layout-TNG-Scanline-Makers.lint \ + libnrtype/Layout-TNG.lint \ + libnrtype/RasterFont.lint \ + libnrtype/TextWrapper.lint \ + libnrtype/font-style-to-pos.lint \ + libnrtype/nr-type-pos-def.lint \ + libnrtype/nr-type-primitives.lint \ + line-snapper.lint \ + livarot/AVL.lint \ + livarot/AlphaLigne.lint \ + livarot/BitLigne.lint \ + livarot/MySeg.lint \ + livarot/Path.lint \ + livarot/PathConversion.lint \ + livarot/PathCutting.lint \ + livarot/PathOutline.lint \ + livarot/PathSimplify.lint \ + livarot/PathStroke.lint \ + livarot/Shape.lint \ + livarot/ShapeDraw.lint \ + livarot/ShapeMisc.lint \ + livarot/ShapeRaster.lint \ + livarot/ShapeSweep.lint \ + livarot/float-line.lint \ + livarot/int-line.lint \ + livarot/path-description.lint \ + livarot/sweep-event.lint \ + livarot/sweep-tree-list.lint \ + livarot/sweep-tree.lint \ + marker-status.lint \ + media.lint \ + message-context.lint \ + message-stack.lint \ + mod360.lint \ + node-context.lint \ + nodepath.lint \ + object-edit.lint \ + object-hierarchy.lint \ + object-snapper.lint \ + object-ui.lint \ + path-chemistry.lint \ + pen-context.lint \ + pencil-context.lint \ + preferences.lint \ + prefix.lint \ + prefs-utils.lint \ + print.lint \ + rect-context.lint \ + registrytool.lint \ + removeoverlap/block.lint \ + removeoverlap/blocks.lint \ + removeoverlap/constraint.lint \ + removeoverlap/generate-constraints.lint \ + removeoverlap/pairingheap/PairingHeap.lint \ + removeoverlap/remove_rectangle_overlap.lint \ + removeoverlap/removeoverlap.lint \ + removeoverlap/solve_VPSC.lint \ + removeoverlap/variable.lint \ + rubberband.lint \ + satisfied-guide-cns.lint \ + selcue.lint \ + select-context.lint \ + selection-chemistry.lint \ + selection-describer.lint \ + selection.lint \ + seltrans-handles.lint \ + seltrans.lint \ + shortcuts-default-xml.lint \ + shortcuts.lint \ + slideshow.lint \ + snap.lint \ + snapped-point.lint \ + snapper.lint \ + sp-anchor.lint \ + sp-animation.lint \ + sp-clippath.lint \ + sp-conn-end-pair.lint \ + sp-conn-end.lint \ + sp-cursor.lint \ + sp-defs.lint \ + sp-ellipse.lint \ + sp-flowdiv.lint \ + sp-flowregion.lint \ + sp-flowtext.lint \ + sp-gradient-reference.lint \ + sp-gradient.lint \ + sp-guide.lint \ + sp-image.lint \ + sp-item-group.lint \ + sp-item-notify-moveto.lint \ + sp-item-rm-unsatisfied-cns.lint \ + sp-item-transform.lint \ + sp-item-update-cns.lint \ + sp-item.lint \ + sp-line.lint \ + sp-marker.lint \ + sp-mask.lint \ + sp-metadata.lint \ + sp-metrics.lint \ + sp-namedview.lint \ + sp-object-group.lint \ + sp-object-repr.lint \ + sp-object.lint \ + sp-offset.lint \ + sp-paint-server.lint \ + sp-path.lint \ + sp-pattern.lint \ + sp-polygon.lint \ + sp-polyline.lint \ + sp-rect.lint \ + sp-root.lint \ + sp-shape.lint \ + sp-skeleton.lint \ + sp-spiral.lint \ + sp-star.lint \ + sp-string.lint \ + sp-style-elem-test.lint \ + sp-style-elem.lint \ + sp-symbol.lint \ + sp-text.lint \ + sp-tspan.lint \ + sp-use-reference.lint \ + sp-use.lint \ + spiral-context.lint \ + splivarot.lint \ + star-context.lint \ + streams-gzip.lint \ + streams-handles.lint \ + streams-jar.lint \ + streams-zlib.lint \ + style-test.lint \ + style.lint \ + svg-view-widget.lint \ + svg-view.lint \ + svg/css-ostringstream.lint \ + svg/gnome-canvas-bpath-util.lint \ + svg/itos.lint \ + svg/round.lint \ + svg/stringstream.lint \ + svg/strip-trailing-zeros.lint \ + svg/svg-affine.lint \ + svg/svg-color.lint \ + svg/svg-length.lint \ + svg/svg-path.lint \ + text-chemistry.lint \ + text-context.lint \ + text-editing.lint \ + tools-switch.lint \ + trace/filterset.lint \ + trace/imagemap-gdk.lint \ + trace/imagemap.lint \ + trace/potrace/curve.lint \ + trace/potrace/decompose.lint \ + trace/potrace/greymap.lint \ + trace/potrace/inkscape-potrace.lint \ + trace/potrace/potracelib.lint \ + trace/potrace/render.lint \ + trace/potrace/trace.lint \ + trace/trace.lint \ + ui/dialog/aboutbox.lint \ + ui/dialog/align-and-distribute.lint \ + ui/dialog/dialog-manager.lint \ + ui/dialog/dialog.lint \ + ui/dialog/document-metadata.lint \ + ui/dialog/document-properties.lint \ + ui/dialog/export.lint \ + ui/dialog/extension-editor.lint \ + ui/dialog/fill-and-stroke.lint \ + ui/dialog/find.lint \ + ui/dialog/inkscape-preferences.lint \ + ui/dialog/layer-editor.lint \ + ui/dialog/memory.lint \ + ui/dialog/messages.lint \ + ui/dialog/scriptdialog.lint \ + ui/dialog/text-properties.lint \ + ui/dialog/tracedialog.lint \ + ui/dialog/transformation.lint \ + ui/dialog/tree-editor.lint \ + ui/dialog/xml-editor.lint \ + ui/icons.lint \ + ui/previewholder.lint \ + ui/stock-items.lint \ + ui/stock.lint \ + ui/view/desktop-affine.lint \ + ui/view/desktop-events.lint \ + ui/view/desktop-handles.lint \ + ui/view/desktop-style.lint \ + ui/view/desktop.lint \ + ui/view/edit-widget.lint \ + ui/view/edit.lint \ + ui/view/view-widget.lint \ + ui/view/view.lint \ + ui/widget/button.lint \ + ui/widget/color-picker.lint \ + ui/widget/color-preview.lint \ + ui/widget/combo-text.lint \ + ui/widget/entity-entry.lint \ + ui/widget/handlebox.lint \ + ui/widget/icon-widget.lint \ + ui/widget/imageicon.lint \ + ui/widget/labelled.lint \ + ui/widget/licensor.lint \ + ui/widget/notebook-page.lint \ + ui/widget/page-sizer.lint \ + ui/widget/panel.lint \ + ui/widget/preferences-widget.lint \ + ui/widget/registered-widget.lint \ + ui/widget/registry.lint \ + ui/widget/ruler.lint \ + ui/widget/scalar-unit.lint \ + ui/widget/scalar.lint \ + ui/widget/selected-style.lint \ + ui/widget/style-swatch.lint \ + ui/widget/svg-canvas.lint \ + ui/widget/tolerance-slider.lint \ + ui/widget/toolbox.lint \ + ui/widget/unit-menu.lint \ + ui/widget/zoom-status.lint \ + uri-references.lint \ + uri.lint \ + util/list-container-test.lint \ + util/shared-c-string-ptr.lint \ + util/units.lint \ + verbs.lint \ + version.lint \ + widgets/button.lint \ + widgets/dash-selector.lint \ + widgets/desktop-widget.lint \ + widgets/font-selector.lint \ + widgets/gradient-image.lint \ + widgets/gradient-selector.lint \ + widgets/gradient-toolbar.lint \ + widgets/gradient-vector.lint \ + widgets/icon.lint \ + widgets/layer-selector.lint \ + widgets/paint-selector.lint \ + widgets/ruler.lint \ + widgets/select-toolbar.lint \ + widgets/shrink-wrap-button.lint \ + widgets/sp-color-gtkselector.lint \ + widgets/sp-color-notebook.lint \ + widgets/sp-color-preview.lint \ + widgets/sp-color-scales.lint \ + widgets/sp-color-selector.lint \ + widgets/sp-color-slider.lint \ + widgets/sp-color-wheel-selector.lint \ + widgets/sp-color-wheel.lint \ + widgets/sp-widget.lint \ + widgets/sp-xmlview-attr-list.lint \ + widgets/sp-xmlview-content.lint \ + widgets/sp-xmlview-tree.lint \ + widgets/spinbutton-events.lint \ + widgets/spw-utilities.lint \ + widgets/toolbox.lint \ + xml/composite-node-observer.lint \ + xml/croco-node-iface.lint \ + xml/event.lint \ + xml/log-builder.lint \ + xml/node-fns.lint \ + xml/quote.lint \ + xml/repr-css.lint \ + xml/repr-io.lint \ + xml/repr-sorting.lint \ + xml/repr-util.lint \ + xml/repr.lint \ + xml/simple-document.lint \ + xml/simple-node.lint \ + xml/simple-session.lint \ + zoom-context.lint + +INCLUDEPATH = \ + -Ialgorithms \ + -Iapplication \ + -Idebug \ + -Idialogs \ + -Idisplay \ + -Idom \ + -Idom/js/fdlibm \ + -Idom/js \ + -Idom \ + -Iextension \ + -Iextension/implementation \ + -Iextension \ + -Iextension/internal \ + -Iextension \ + -Iextension/script \ + -Iextension \ + -Ihelper \ + -Iinkjar \ + -Iio \ + -Ilibavoid \ + -Ilibcroco \ + -Ilibnr \ + -Ilibnrtype \ + -Ilivarot \ + -Iremoveoverlap \ + -Iremoveoverlap/pairingheap \ + -Iremoveoverlap \ + -Isvg \ + -Itrace \ + -Itrace/potrace \ + -Itrace \ + -Itraits \ + -Iui/dialog \ + -Iui \ + -Iui/view \ + -Iui/widget \ + -Iutil \ + -Iwidgets \ + -Ixml/ diff --git a/src/makedef.pl b/src/makedef.pl new file mode 100644 index 000000000..42ae3b08a --- /dev/null +++ b/src/makedef.pl @@ -0,0 +1,61 @@ +#! perl + +&doMakeDef(); +exit(0); + +sub doMakeDef() +{ + print "####### Generating 'inkscape.def' #######\n"; + + my $nmlines = (); #store lines read in hash, to remove dupes + my @lines; #output lines + my $line; #single line of input + my $datestr; #current date + local(*PIPE); #output of the 'nm' command + local(*OUTFILE); #output file - inkscape.def + + open (PIPE, "nm libinkscape.a |"); + while() + { + if ($_ =~ /\./) + { + next; + } + elsif ($_ =~ /T _/) + { + $line = $_; + $line =~ s/.* T _//; + $nmlines->{$line} = 1; + } + elsif ($_ =~ /B _/) + { + $line = $_; + $line =~ s/.* B _//; + $nmlines->{$line} = 1; + } + } + close (PIPE); + + foreach (keys(%{$nmlines})) + { + push @lines, $_; + } + + @lines = sort(@lines); + + $datestr = gmtime(); + open (OUTFILE, ">inkscape.def"); + print OUTFILE ";########################################################\n"; + print OUTFILE ";## File: inkscape.def\n"; + print OUTFILE ";## Purpose: Used by dllwrap to make inkscape.dll\n"; + print OUTFILE ";## Generated by makedef.pl at :$datestr\n"; + print OUTFILE ";########################################################\n\n"; + print OUTFILE "LIBRARY\tinkscape.dll\n"; + print OUTFILE "EXPORTS\n"; + foreach (<@lines>) + { + # print $_, "\n"; + print OUTFILE " ", $_, "\n"; + } + close (OUTFILE); +} diff --git a/src/marker-status.cpp b/src/marker-status.cpp new file mode 100644 index 000000000..d8b5e52ac --- /dev/null +++ b/src/marker-status.cpp @@ -0,0 +1,23 @@ + +void marker_status(char const *format, ...) +{ + /* Don't bother inlining this. Not called often, and eventually all + calls will be removed anyway. */ +#if 0 /* Bryce sets this to 1. */ + va_list args; + va_start(args, format); + g_logv(marker_status_INITIAL_ARGS, format, args); + va_end(args); +#endif +} + +/* + 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:textwidth=99 : diff --git a/src/marker-status.h b/src/marker-status.h new file mode 100644 index 000000000..102604985 --- /dev/null +++ b/src/marker-status.h @@ -0,0 +1,19 @@ +#ifndef SEEN_MARKER_DEBUG_H +#define SEEN_MARKER_DEBUG_H + +#include "gnuc-attribute.h" + +void marker_status(char const *format, ...) _gnuc_attribute((format(__printf__, 1, 2))); + +#endif /* !SEEN_MARKER_DEBUG_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:encoding=utf-8:textwidth=99 : diff --git a/src/media.cpp b/src/media.cpp new file mode 100644 index 000000000..8f9dfc18a --- /dev/null +++ b/src/media.cpp @@ -0,0 +1,27 @@ +#include "media.h" + +void +media_clear_all(Media &media) +{ + media.print = false; + media.screen = false; +} + +void +media_set_all(Media &media) +{ + media.print = true; + media.screen = true; +} + + +/* + 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:textwidth=99 : diff --git a/src/media.h b/src/media.h new file mode 100644 index 000000000..8ae374aa1 --- /dev/null +++ b/src/media.h @@ -0,0 +1,24 @@ +#ifndef INKSCAPE_MEDIA_H +#define INKSCAPE_MEDIA_H + +class Media { +public: + bool print; + bool screen; +}; + +void media_clear_all(Media &); +void media_set_all(Media &); + +#endif /* !INKSCAPE_MEDIA_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:encoding=utf-8:textwidth=99 : diff --git a/src/memeq.h b/src/memeq.h new file mode 100644 index 000000000..db348d3f5 --- /dev/null +++ b/src/memeq.h @@ -0,0 +1,25 @@ +#ifndef INKSCAPE_MEMEQ_H +#define INKSCAPE_MEMEQ_H + +#include + +/** Convenience/readability wrapper for memcmp(a,b,n)==0. */ +inline bool +memeq(void const *a, void const *b, size_t n) +{ + return std::memcmp(a, b, n) == 0; +} + + +#endif /* !INKSCAPE_MEMEQ_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:encoding=utf-8:textwidth=99 : diff --git a/src/menus-skeleton.h b/src/menus-skeleton.h new file mode 100644 index 000000000..0ecfb7cef --- /dev/null +++ b/src/menus-skeleton.h @@ -0,0 +1,252 @@ +#ifndef SEEN_MENUS_SKELETON_H +#define SEEN_MENUS_SKELETON_H + +#include + +#ifdef __cplusplus +#undef N_ +#define N_(x) x +#endif + +static char const menus_skeleton[] = +"\n" +"\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +/* These are ugly, but what needs to happen here is allowing users + to use the native PS support if they are using another print driver. + This is done through the "Print Direct" command. Which is inserted + here based on if those other drivers are being built. */ +#ifdef WITH_GNOME_PRINT +" \n" +#endif +#ifdef WIN32 +" \n" +#endif +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +#ifdef WITH_INKBOARD +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +#endif +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +//" \n" +" \n" +"\n"; + +#define MENUS_SKELETON_SIZE (sizeof(menus_skeleton) - 1) + + +#endif /* !SEEN_MENUS_SKELETON_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:encoding=utf-8:textwidth=99 : diff --git a/src/message-context.cpp b/src/message-context.cpp new file mode 100644 index 000000000..5055f4102 --- /dev/null +++ b/src/message-context.cpp @@ -0,0 +1,94 @@ +/* + * MessageContext - context for posting status messages + * + * Authors: + * MenTaLguY + * + * Copyright (C) 2004 MenTaLguY + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include +#include "message-context.h" +#include "message-stack.h" + +namespace Inkscape { + +MessageContext::MessageContext(MessageStack *stack) +: _stack(stack), _message_id(0), _flash_message_id(0) +{ + GC::anchor(_stack); +} + +MessageContext::~MessageContext() { + clear(); + GC::release(_stack); + _stack = NULL; +} + +void MessageContext::set(MessageType type, gchar const *message) { + if (_message_id) { + _stack->cancel(_message_id); + } + _message_id = _stack->push(type, message); +} + +void MessageContext::setF(MessageType type, gchar const *format, ...) +{ + va_list args; + va_start(args, format); + setVF(type, format, args); + va_end(args); +} + +void MessageContext::setVF(MessageType type, gchar const *format, va_list args) +{ + gchar *message=g_strdup_vprintf(format, args); + set(type, message); + g_free(message); +} + +void MessageContext::flash(MessageType type, gchar const *message) { + if (_flash_message_id) { + _stack->cancel(_flash_message_id); + } + _flash_message_id = _stack->flash(type, message); +} + +void MessageContext::flashF(MessageType type, gchar const *format, ...) { + va_list args; + va_start(args, format); + flashVF(type, format, args); + va_end(args); +} + +void MessageContext::flashVF(MessageType type, gchar const *format, va_list args) { + gchar *message=g_strdup_vprintf(format, args); + flash(type, message); + g_free(message); +} + +void MessageContext::clear() { + if (_message_id) { + _stack->cancel(_message_id); + _message_id = 0; + } + if (_flash_message_id) { + _stack->cancel(_flash_message_id); + _flash_message_id = 0; + } +} + +} + +/* + 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:textwidth=99 : diff --git a/src/message-context.h b/src/message-context.h new file mode 100644 index 000000000..241b38660 --- /dev/null +++ b/src/message-context.h @@ -0,0 +1,118 @@ +/** \file + * A convenience class for working with MessageStacks. + */ + +/* + * Authors: + * MenTaLguY + * + * Copyright (C) 2004 MenTaLguY + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifndef SEEN_INKSCAPE_MESSAGE_CONTEXT_H +#define SEEN_INKSCAPE_MESSAGE_CONTEXT_H + +#include +#include +#include "message.h" + +namespace Inkscape { + +class MessageStack; + +/** A convenience class for working with MessageStacks. + * + * In general, a particular piece of code will only want to display + * one status message at a time. This class takes care of tracking + * a "current" message id in a particular stack for us, and provides + * a convenient means to remove or replace it. + * + * @see Inkscape::MessageStack + */ +class MessageContext { +public: + /** Constructs an Inkscape::MessageContext referencing a particular + * Inkscape::MessageStack, which will be used for our messages + * + * MessageContexts retain references to the MessageStacks they use. + * + * @param stack the Inkscape::MessageStack to use for our messages + */ + MessageContext(MessageStack *stack); + ~MessageContext(); + + /** @brief pushes a message on the stack, replacing our old message + * + * @param type the message type + * @param message the message text + */ + void set(MessageType type, gchar const *message); + + /** @brief pushes a message on the stack using prinf-style formatting, + * and replacing our old message + * + * @param type the message type + * @param format a printf-style formatting string + */ + void setF(MessageType type, gchar const *format, ...); + + /** @brief pushes a message on the stack using printf-style formatting, + * and a stdarg argument list + * + * @param type the message type + * @param format a printf-style formatting string + * @param args printf-style arguments + */ + void setVF(MessageType type, gchar const *format, va_list args); + + /** @brief pushes a message onto the stack for a brief period of time + * without disturbing our "current" message + * + * @param type the message type + * @param message the message text + */ + void flash(MessageType type, gchar const *message); + + /** @brief pushes a message onto the stack for a brief period of time + * using printf-style formatting, without disturbing our current + * message + * + * @param type the message type + * @param format a printf-style formatting string + */ + void flashF(MessageType type, gchar const *format, ...); + + /** @brief pushes a message onto the stack for a brief period of time + * using printf-style formatting and a stdarg argument list; + * it does not disturb our "current" message + * + * @param type the message type + * @param format a printf-style formatting string + * @param args printf-style arguments + */ + void flashVF(MessageType type, gchar const *format, va_list args); + + /** @brief removes our current message from the stack */ + void clear(); + +private: + MessageStack *_stack; ///< the message stack to use + MessageId _message_id; ///< our current message id, or 0 + MessageId _flash_message_id; ///< current flashed message id, or 0 +}; + +} + +#endif +/* + 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:textwidth=99 : diff --git a/src/message-stack.cpp b/src/message-stack.cpp new file mode 100644 index 000000000..23ff1435f --- /dev/null +++ b/src/message-stack.cpp @@ -0,0 +1,160 @@ +/* + * MessageStack - context for posting status messages + * + * Authors: + * MenTaLguY + * + * Copyright (C) 2004 MenTaLguY + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include +#include "message-stack.h" + +namespace Inkscape { + +MessageStack::MessageStack() +: _messages(NULL), _next_id(1) +{ +} + +MessageStack::~MessageStack() +{ + while (_messages) { + _messages = _discard(_messages); + } +} + +MessageId MessageStack::push(MessageType type, gchar const *message) { + return _push(type, 0, message); +} + +MessageId MessageStack::pushF(MessageType type, gchar const *format, ...) +{ + va_list args; + va_start(args, format); + MessageId id=pushVF(type, format, args); + va_end(args); + return id; +} + +MessageId MessageStack::pushVF(MessageType type, gchar const *format, va_list args) +{ + MessageId id; + gchar *message=g_strdup_vprintf(format, args); + id = push(type, message); + g_free(message); + return id; +} + +void MessageStack::cancel(MessageId id) { + Message **ref; + for ( ref = &_messages ; *ref ; ref = &(*ref)->next ) { + if ( (*ref)->id == id ) { + *ref = _discard(*ref); + _emitChanged(); + break; + } + } +} + +MessageId MessageStack::flash(MessageType type, gchar const *message) { + switch (type) { + case INFORMATION_MESSAGE: // stay rather long so as to seem permanent, but eventually disappear + return _push(type, 6000 + 80*strlen(message), message); + break; + case ERROR_MESSAGE: // pretty important stuff, but temporary + return _push(type, 4000 + 60*strlen(message), message); + break; + case WARNING_MESSAGE: // a bit less important than error + return _push(type, 2000 + 40*strlen(message), message); + break; + case NORMAL_MESSAGE: // something ephemeral + default: + return _push(type, 1000 + 20*strlen(message), message); + break; + } +} + +MessageId MessageStack::flashF(MessageType type, gchar const *format, ...) { + va_list args; + va_start(args, format); + MessageId id = flashVF(type, format, args); + va_end(args); + return id; +} + +MessageId MessageStack::flashVF(MessageType type, gchar const *format, va_list args) +{ + gchar *message=g_strdup_vprintf(format, args); + MessageId id = flash(type, message); + g_free(message); + return id; +} + +MessageId MessageStack::_push(MessageType type, guint lifetime, gchar const *message) +{ + Message *m=new Message; + MessageId id=_next_id++; + + m->stack = this; + m->id = id; + m->type = type; + m->message = g_strdup(message); + + if (lifetime) { + m->timeout_id = g_timeout_add(lifetime, &MessageStack::_timeout, m); + } else { + m->timeout_id = 0; + } + + m->next = _messages; + _messages = m; + + _emitChanged(); + + return id; +} + +MessageStack::Message *MessageStack::_discard(MessageStack::Message *m) +{ + Message *next=m->next; + if (m->timeout_id) { + g_source_remove(m->timeout_id); + m->timeout_id = 0; + } + g_free(m->message); + m->message = NULL; + m->stack = NULL; + delete m; + return next; +} + +void MessageStack::_emitChanged() { + if (_messages) { + _changed_signal.emit(_messages->type, _messages->message); + } else { + _changed_signal.emit(NORMAL_MESSAGE, NULL); + } +} + +gboolean MessageStack::_timeout(gpointer data) { + Message *m=reinterpret_cast(data); + m->timeout_id = 0; + m->stack->cancel(m->id); + return FALSE; +} + +} + +/* + 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:textwidth=99 : diff --git a/src/message-stack.h b/src/message-stack.h new file mode 100644 index 000000000..4741cce1e --- /dev/null +++ b/src/message-stack.h @@ -0,0 +1,177 @@ +/** \file + * Managing current status messages. + */ + +/* + * Authors: + * MenTaLguY + * + * Copyright (C) 2004 MenTaLguY + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifndef SEEN_INKSCAPE_MESSAGE_STACK_H +#define SEEN_INKSCAPE_MESSAGE_STACK_H + +#include +#include +#include +#include "gc-managed.h" +#include "gc-finalized.h" +#include "gc-anchored.h" +#include "message.h" + +namespace Inkscape { + +/** + * A class which holds a stack of displayed messages. + * + * Messages can be pushed onto the top of the stack, and removed + * from any point in the stack by their id. + * + * Messages may also be "flashed", meaning that they will be + * automatically removed from the stack a fixed period of time + * after they are pushed. + * + * "Flashed" warnings and errors will persist longer than normal + * messages. + * + * There is no simple "pop" operation provided, since these + * stacks are intended to be shared by many different clients; + * assuming that the message you pushed is still on top is an + * invalid and unsafe assumption. + */ +class MessageStack : public GC::Managed<>, + public GC::Finalized, + public GC::Anchored +{ +public: + MessageStack(); + ~MessageStack(); + + /** @brief returns the type of message currently at the top of the stack */ + MessageType currentMessageType() { + return _messages ? _messages->type : NORMAL_MESSAGE; + } + /** @brief returns the text of the message currently at the top of + * the stack + */ + gchar const *currentMessage() { + return _messages ? _messages->message : NULL; + } + + /** @brief connects to the "changed" signal which is emitted whenever + * the topmost message on the stack changes. + */ + sigc::connection connectChanged(sigc::slot slot) + { + return _changed_signal.connect(slot); + } + + /** @brief pushes a message onto the stack + * + * @param type the message type + * @param message the message text + * + * @return the id of the pushed message + */ + MessageId push(MessageType type, gchar const *message); + + /** @brief pushes a message onto the stack using printf-like formatting + * + * @param type the message type + * @param format a printf-style format string + * + * @return the id of the pushed message + */ + MessageId pushF(MessageType type, gchar const *format, ...); + + /** @brief pushes a message onto the stack using printf-like formatting, + * using a stdarg argument list + * + * @param type the message type + * @param format a printf-style format string + * @param args the subsequent printf-style arguments + * + * @return the id of the pushed message + */ + MessageId pushVF(MessageType type, gchar const *format, va_list args); + + /** @brief removes a message from the stack, given its id + * + * This method will remove a message from the stack if it has not + * already been removed. It may be removed from any part of the stack. + * + * @param id the message id to remove + */ + void cancel(MessageId id); + + /** @brief temporarily pushes a message onto the stack + * + * @param type the message type + * @param message the message text + * + * @return the id of the pushed message + */ + MessageId flash(MessageType type, gchar const *message); + + /** @brief temporarily pushes a message onto the stack using + * printf-like formatting + * + * @param type the message type + * @param format a printf-style format string + * + * @return the id of the pushed message + */ + MessageId flashF(MessageType type, gchar const *format, ...); + + /** @brief temporarily pushes a message onto the stack using + * printf-like formatting, using a stdarg argument list + * + * @param type the message type + * @param format a printf-style format string + * @param args the printf-style arguments + * + * @return the id of the pushed message + */ + MessageId flashVF(MessageType type, gchar const *format, va_list args); + +private: + struct Message { + Message *next; + MessageStack *stack; + MessageId id; + MessageType type; + gchar *message; + guint timeout_id; + }; + + MessageStack(MessageStack const &); // no copy + void operator=(MessageStack const &); // no assign + + /// pushes a message onto the stack with an optional timeout + MessageId _push(MessageType type, guint lifetime, gchar const *message); + + Message *_discard(Message *m); ///< frees a message struct and returns the next such struct in the list + void _emitChanged(); ///< emits the "changed" signal + static gboolean _timeout(gpointer data); ///< callback to expire flashed messages + + sigc::signal _changed_signal; + Message *_messages; ///< the stack of messages as a linked list + MessageId _next_id; ///< the next message id to assign +}; + +} + +#endif +/* + 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:textwidth=99 : diff --git a/src/message.h b/src/message.h new file mode 100644 index 000000000..24a61fea7 --- /dev/null +++ b/src/message.h @@ -0,0 +1,49 @@ +/* + * status-message-related types + * + * Authors: + * MenTaLguY + * + * Copyright (C) 2004 MenTaLguY + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifndef SEEN_INKSCAPE_MESSAGE_H +#define SEEN_INKSCAPE_MESSAGE_H + +namespace Inkscape { + +/** + * A hint about the meaning of a message; is it an ordinary message, + * a message advising the user of some significant or unexpected condition, + * or a message indicating an unambiguous error. + */ +enum MessageType { + NORMAL_MESSAGE, + WARNING_MESSAGE, + ERROR_MESSAGE, + INFORMATION_MESSAGE +}; + +/** + * An integer ID which identifies a displayed message in a particular + * Inkscape::MessageStack + * + * @see Inkscape::MessageStack + */ +typedef unsigned long MessageId; + +} + +#endif +/* + 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:textwidth=99 : diff --git a/src/mkdep.pl b/src/mkdep.pl new file mode 100755 index 000000000..146641aa3 --- /dev/null +++ b/src/mkdep.pl @@ -0,0 +1,565 @@ +#!/usr/bin/perl +############################################################################ +# +# Creates make.dep - a list of all dependencies. +# Uses make.files as input; mkfiles.pl should be run before mkdep.pl. +# +############################################################################ + +$obj_ext = "o"; +$linebreak = "\\"; +$dir_sep = "/"; +$nodepend = 0; +$tolower = 1; # lowercase all filenames +$include_path = ""; + +# +# main - top level code +# + +if ( @ARGV ) { # parse command line args + foreach $a ( @ARGV ) { + if ( $a eq "-w" ) { + $warnon = 1; + } + elsif ( ( $a eq "-?" ) || ( $a eq "-h" ) ) { + print "usage: perl mkdep.pl includedirs...\"\n\n" . + "\"includedirs\" is any number of include directories that are located\n". + "outside of your project directory tree.\n\n". + "example:\n perl mkdep.pl s:\\ w:\\include\n"; + exit 1; + } + else { + push @extradirs, $a; + $include_path = $include_path . $a . ";"; + } + } + print "Includepath used: ".join(" ",@extradirs)."\n"; +} + +&make_files; +&make_dep; + +exit 0; + + +# +# make_files: read "make.files", create "make.ofiles" +# + +sub make_files { + + # create output file (now, to check for permissions) + open OFILES, ">make.ofiles" or + die("Can't create make.ofiles"); + + # read file list + #open FILES,"; + #close FILES; + + open FILES, ") + { + $line = $_; + #Trim whitespace from ends + $line =~ s/^\s|\t|\n//; + #Ignore if no text in line + next if ( length($line) < 1 ); + #Ignore if starts with '#' + next if ( $line =~ /^#/ ); + # print $line, "\n"; + push @lines, $line; + } + close FILES; + + # sort out header and source files + @hdr = sort grep(/\.(h|hpp|icc|ia)$/i,@lines); + @src = sort grep(/\.(c|cpp|cc|s)$/i,@lines); + + print STDERR scalar @lines ." files found (".scalar @src." sources and ".scalar @hdr." headers) in \"make.files\".\n"; + + # scan specified include dirs + for ( @extradirs ) { + push @extrafiles, &find_files($_,"\.*",1); + } + # add external includefiles to file list + push @lines, @extrafiles; + + print STDERR scalar @lines . " files found everywhere.\n"; + + # create @inc and %full_path + $last = ""; + for ( @lines ) { + m/^(.*\/)([^\/]*)$/ || m/^()(.*)$/; + $path = $1; + $filepart = $2; + if ( $path ne $last ) { + # store dir path + if (length($path) > 0) { + push (@inc, $path ); + } + $last = $path; + } + + # remove any newlines at end of line + $filepart =~ s/(.*)\n+$/$1/g; + + # store full path for all include files + if ( !defined $full_path{ lc $filepart } ) { + $full_path{lc $filepart} = $path.$filepart; + } + } + + $includes = join (" \\\n\t-I", @inc); + $includes =~ s/\/ \\/ \\/g; # remove trailing slashes + + # save source list for use by make_depend + $sourcelist = join(" ",@src); + + # create object list from source list + $objects = &Objects( $sourcelist ); + + # save object list for use by make_depend + $objectlist = $objects; + + # make a "lints" list for linting + $lints = $objects; + $lints =~ s/\.${obj_ext}/\.lint/g; + $lints =~ s/ / \\\n\t/g; + + # put newline+tab on all files (to make nice lists) + $objects =~ s/ / \\\n\t/g; + + # print file + $datestr = gmtime(); + print OFILES "########################################################\n"; + print OFILES "## File: make.ofiles\n"; + print OFILES "## Purpose: Object file listing for use by Makefiles\n"; + print OFILES "## Generated by mkdep.pl at :$datestr\n"; + print OFILES "## Do not edit this file! Changes will be lost.\n"; + print OFILES "########################################################\n\n"; + print OFILES "OBJECTS = \\\n\t" . $objects . "\n\n"; + print OFILES "LINTS = \\\n\t" . $lints . "\n\n"; + if ( $includes ne "" ) { + print OFILES "INCLUDEPATH = \\\n\t-I" . $includes . "\n"; + } + + close OFILES; +} + + + +# +# Finds files. +# +# Examples: +# find_files("/usr","\.cpp$",1) - finds .cpp files in /usr and below +# find_files("/tmp","^#",0) - finds #* files in /tmp +# + +sub find_files { + my($dir,$match,$descend) = @_; + my($file,$p,@files); + local(*D); + $dir =~ s=\\=/=g; + ($dir eq "") && ($dir = "."); + + if ( opendir(D,$dir) ) { + if ( $dir eq "." ) { + $dir = ""; + } else { + ($dir =~ /\/$/) || ($dir .= "/"); + } + foreach $file ( readdir(D) ) { + + next if ( $file =~ /^\.\.?$/ ); + $p = $dir . $file; +# ($file =~ /$match/i) && (push @files, ($tolower==0 ? $p : lc($p))); + ($file =~ /$match/i) && (push @files, $p ); + if ( $descend && -d $p && ! -l $p ) { + push @files, &find_files($p,$match,$descend); + } + } + closedir(D); + } + return @files; +} + + +# +# strip_project_val(tag) +# +# Strips white space from project value strings. +# + +sub strip_project_val { + my($v) = @_; + $v =~ s/^\s+//; # trim white space + $v =~ s/\s+$//; + return $v; +} + +# +# Objects(files) +# +# Replaces any extension with .o ($obj_ext). +# + +sub Objects { + local($_) = @_; + my(@a); + @a = split(/\s+/,$_); + foreach ( @a ) { + s-\.\w+$-.${obj_ext}-; + } + return join(" ",@a); +} + + +sub make_dep { + + $outfile = "make.dep"; + + print STDERR "Parsing source files...\n"; + + open(DEP,">" . fix_path($outfile)) or + die ("Can't create \"$outfile\""); + + &BuildObj( $objectlist, $sourcelist ); + + $datestr = gmtime(); + print DEP "########################################################\n"; + print DEP "## File: make.dep\n"; + print DEP "## Purpose: Dependency listing for use by Makefiles\n"; + print DEP "## Generated by mkdep.pl at :$datestr\n"; + print DEP "## Do not edit this file! Changes will be lost.\n"; + print DEP "########################################################\n\n"; + print DEP $text; + close DEP; + print STDERR "\n"; + + + if ( $warnon && (keys %missing) ) { + # print out missing files + if ( !open MISSING, ">makemiss.txt" ) { + print "Couldn't create \"makemiss.txt\": $!\n"; + print "Printing on screen.\n"; + *MISSING = *STDOUT; + } + + print MISSING "Missing files: (Note: only the first miss for each file is logged)\n\n"; + printf MISSING "%-32s %s\n","",""; + printf MISSING "%-32s %s\n","------","---------------"; + @missingfiles = sort @missingfiles; + foreach ( @missingfiles ) { + @a = split( ",", $_ ); + printf MISSING "%-32s %s\n",$a[0],$a[1]; + } + close MISSING; + + print STDOUT "(missing files written to \"makemiss.txt\")\n"; + } +} + + +# +# BuildObj(objects,sources) +# +# Builds the object files. +# + +sub uniq (@) { + if ($#_ <= 0) { + return @_; + } + my $prev = shift(@_); + my @ret = ($prev); + while(@_) { + my $curr = shift(@_); + if ($curr ne $prev) { + push @ret, $curr; + $prev = $curr; + } + } + return @ret; +} + +sub BuildObj { + my($obj,$src) = @_; + my(@objv,$srcv,$i,$s,$o,$d,$c,$comp,$cimp); + $text = ""; + @objv = split(/\s+/,$obj); + @srcv = split(/\s+/,$src); + $tot = $#objv; + + # fix dependpath + if ( ! $depend_path_fixed ) { + $depend_path_fixed = 1; + $depend_path = $include_path; + $count = 0; + + while ( $count < 100 ) { + if ( $depend_path =~ s/(\$[\{\(]?\w+[\}\)]?)/035/ ) { + $_ = $1; + s/[\$\{\}\(\)]//g; + $depend_path =~ s/035/$ENV{$_}/g; + } else { + $count = 100; + } + } + @dep_path = &split_path($depend_path); + unshift @dep_path, ""; # current dir first + } + + %missing = (); + # go through file list + for $i ( 0..$#objv ) { + $s = $srcv[$i]; + $o = $objv[$i]; + next if $s eq ""; + + if ( $warnon ) { + print STDERR "\r" . ($i+1) . " missing files: ". scalar keys %missing; + } + else { + print STDERR "\r" . ($i+1); + } + + @incfiles = (); + $d = &make_depend(lc $s); + + for ( @incfiles ) { + push @ifiles, $full_path{$n}; + } + + $text .= $o . ": ${linebreak}\n\t" . $s; + + @incpath = (); + for ( @incfiles ) { + if ( defined $full_path{$_} ) { + push @incpath, $full_path{$_}; + } + } + @incpath = uniq sort @incpath; + for ( @incpath ) { + $text .= " ${linebreak}\n\t" . $_; + } + $text .= "\n\n"; + + # ----------------------------- +# print "\n". $text; +# exit; + } + chop $text; +} + + +# +# build_dep() - Internal for make_depend() +# + +sub build_dep { + my($file) = @_; + my(@i,$a,$n); + $a = ""; + + if ( !defined $depend_dict{$file} ) { + return $a; + } + + @i = split(/ /,$depend_dict{$file}); +# print "INC2: ($file) ".$depend_dict{$file}."\n"; + + for $n ( @i ) { +# if ( (!defined $dep_dict{$n}) && defined($full_path{$n}) ) { + if ( !defined $dep_dict{$n} ) { + $dep_dict{$n} = 1; + push @incfiles, $n; +# $a .= $full_path{$n} . " " . &build_dep($n); + &build_dep($n); + } + } +# print "INCFILES ($file): ".@incfiles."\n"; + return $a; +} + + +# +# make_depend(file) +# +# Returns a list of included files. +# Uses the global $depend_path variable. +# + +sub make_depend { + my($file) = @_; + my($i,$count); + if ( $nodepend ) { + return ""; + } + + @cur_dep_path = @dep_path; + if ( $file =~ /(.*[\/\\])/ ) { + $dep_curdir = $1; + splice( @cur_dep_path, 0, 0, $dep_curdir ); + } else { + $dep_curdir = ""; + } + $dep_file = $file; + &canonical_dep($file); + %dep_dict = (); + + + $i = &build_dep($file); +# chop $i; + + $i =~ s=/=$dir_sep=g unless $is_unix; + $i =~ s=([a-zA-Z]):/=//$1/=g if (defined($gnuwin32) && $gnuwin32); +# @l = sort split(/ /,$i); + @l = split(/ /,$i); + return join(" ${linebreak}\n\t", @l ); +# return $i; # all on one line! +} + +# +# canonical_dep(file) - Internal for make_depend() +# +# Reads the file and all included files recursively. +# %depend_dict associates a file name to a list of included files. +# + +sub canonical_dep { + my($file) = @_; + my(@inc,$i); + push @sfile, $file; + # ----------------------------- +# print "FILE: $file\n"; + @inc = &scan_dep($file); + + if ( @inc ) { + $depend_dict{$file} = join(" ",@inc); + + # recursively scan all files not already scanned + for $i ( @inc ) { + if ( ! defined( $depend_dict{$i} ) ) { + &canonical_dep($i); + + # still nothing defined? + if ( ! defined( $depend_dict{$i} ) ) { + # insert dummy string, so we don't parse the file again + $depend_dict{$i} = ""; + } +# print "CACHE: $i: $depend_dict{$i}\n"; + } + } + } + pop @sfile, $file; +} + +# +# scan_dep(file) - Internal for make_depend() +# +# Returns an array of included files. +# + +sub scan_dep { + my($file) = @_; + my($dir,$path,$found,@allincs,@includes,%incs); + $path = ($file eq $dep_file) ? $file : $dep_curdir . $file; + @includes = (); + +# print STDERR "SCAN_DEP $file\n"; + + # replace backslash with regular slash + $file =~ s-\\-/-g; + + # look in the file list + if ( !defined $full_path{$file} ) { + # file not in list - some special case + + # handle explicit path'ed includes (such as #include "common/bsp821.h") + if ( $file =~ /[\/\\]([^\\\/]+)$/ ) { + $full_path{$file} = $full_path{$1}; + } + } + + $open = open TMP,fix_path( $full_path{$file} ); + + if ( $open ) { + @source = ; + + # find all lines with include as first text in line (no comments allowed) + @allincs = grep(/^\s*[\#\.]\s*include/,@source); + +# print "SCAN_ALLINC: $#allincs include lines found\n"; + + # iterate all include lines + foreach ( @allincs ) { + # parse out filename + if ( !(/\s*[\#\.]\s*include\s+[<\"]([^>\"]*)[>\"]/) || defined($incs{$1}) ) { + next; + } + push(@includes, ($tolower==0 ? $1 : lc($1))); + +# print "SCAN_INC: $1\n"; + + $incs{$1} = "1"; + } + + # ----------------------------- +# print "INC: ".join( ",", @includes)."\n"; + close(TMP); + } + else { + &add_missing( $file ); + } + $/ = "\n"; + return @includes; +} + + +sub add_missing { + my($file) = @_; + @s = @sfile; + pop @s; + push @missingfiles, $file.",".join(" -> ",@s); + $missing{$file} = 1; +} + +# +# split_path(path) +# +# Splits a path containing : (Unix) or ; (MSDOS, NT etc.) separators. +# Returns an array. +# + +sub split_path { + my($p) = @_; + return "" if !defined($p); + $p =~ s=:=;=g if $is_unix; + $p =~ s=[/\\]+=/=g; + $p =~ s=([^/:]);=$1/;=g; + $p =~ s=([^:;/])$=$1/=; + $p =~ s=/=$dir_sep=g unless $is_unix; + return split(/;/,$p); +} + +# +# fix_path(path) +# +# Converts all '\' to '/' if this really seems to be a Unix box. +# + +sub fix_path { + my($p) = @_; +# if ( $really_unix ) { +# $p =~ s-\\-/-g; +# } else { +# $p =~ s-/-\\-g; + $p =~ s-\\-/-g; +# } + return $p; +} diff --git a/src/mkfiles.pl b/src/mkfiles.pl new file mode 100755 index 000000000..e313f5af3 --- /dev/null +++ b/src/mkfiles.pl @@ -0,0 +1,226 @@ +#!/usr/bin/perl +############################################################################ +# +# Creates make.files - a list of all source files +# +############################################################################ + +# +# main - top level code +# + +if ( @ARGV ) { # parse command line args + print "usage: perl mkfiles.pl\n\n"; + exit 1; +} + +$tolower = 0; #Do we want to convert items in make.files to lower case? +$verbose = 1; #Do we want to list the files? + + + +print "###########################\n"; +print "## Generating make.files ##\n"; +print "###########################\n"; + +&doMakeFiles(); #Do your magic! + +print "###########################\n"; +print "## make.files done ##\n"; +print "###########################\n"; + +exit 0; + + + +############################################################################ +# +# Main routine. Read make.exclude, then search the current directory +# recursively for source code items, rejecting those listed in make.exclude +# +############################################################################ +sub doMakeFiles +{ + my $excludes; #list of files to exclude + my @excluded; #list of files that were actually excluded + my @irrelevant; #list of files in make.exclude that were not found + my $line; #current line from make.exclude + my $patterns; #The extensions for which to search + my @files; #Result of find_files() + my @codefiles; #Sorted list of @files + my $datestr; #Current date + local(*MAKE_DOT_EXCLUDE); + local(*MAKE_DOT_FILES); + + if ( -r "make.exclude" ) + { + open MAKE_DOT_EXCLUDE, "make.exclude" or + die "make.exclude: $!"; + while () + { + $line = $_; + #Trim whitespace from ends + $line =~ s/^\s|\t|\n//; + #Ignore if no text in line + next if ( length($line) < 1 ); + #Ignore if starts with '#' + next if ( $line =~ /^#/ ); + # print $line, "\n"; + $excludes->{$line} = 1; + } + close MAKE_DOT_EXCLUDE; + } + + #while ( my ($key, $value) = each(%{$excludes}) ) + # { + # print "$key => $value\n"; + # } + + $patterns = '.c$|.cpp$|.h$|.hpp$'; + + @files = &find_files(".", $patterns, $excludes, \@excluded); + + # Print the list of files excluded + print "###EXCLUDED: ", scalar(@excluded), " files/directories rejected by request\n"; + @excluded = sort(@excluded); + foreach (@excluded) + { + if ($verbose) + { + print " $_\n"; + } + #mark the item in the hash table , so we know it occurred + $excludes->{$_} = 0; + } + + # Count how many files in make.exclude were not used + foreach (keys(%{$excludes})) + { + #if still a 1, then it was not used + if ($excludes->{$_} !=0) + { + push @irrelevant, $_; + } + } + + # Print the list of file in make.exclude, but not used. + if (scalar(@irrelevant)>0) + { + @irrelevant = sort(@irrelevant); + print "###IRRELEVANT: ", scalar(@irrelevant), " entries in make.exclude that were not found\n"; + foreach (@irrelevant) + { + if ($verbose) + { + print " $_\n"; + } + } + } + + @codefiles = sort(@files); + + $datestr = gmtime(); + open MAKE_DOT_FILES, ">make.files" or + die("make.files: $!"); + print MAKE_DOT_FILES "########################################################\n"; + print MAKE_DOT_FILES "## File: make.files\n"; + print MAKE_DOT_FILES "## Purpose: Used by mkdep.pl\n"; + print MAKE_DOT_FILES "## Generated by mkfiles.pl at :$datestr\n"; + print MAKE_DOT_FILES "########################################################\n\n"; + foreach (@codefiles) + { + next if (length($_)<1); + print MAKE_DOT_FILES "$_\n"; + } + close MAKE_DOT_FILES; + +} # doMakeFiles + + + + +############################################################################ +# +# Search the current directory recursively, checking rejecting items from +# make.exclude, or adding those that match the extensions in $patterns. +# @param $dir the current directory being searched +# @param $patterns the file extensions for which we are searching +# @param $excludes a hash of the files which should be rejected +# @param $excluded an array in which to store a record of all files rejected +# +############################################################################ +sub find_files +{ + my($dir, $patterns, $excludes, $excluded) = @_; + my $file; + my $p; + my @files = (); + my @file_result; + local(*DIR); + + + $dir =~ s=\\=/=g; + + # Check for 0-length + if (length($dir)<1) + { + $dir = '.'; + } + + # Process a directory of files + if ( opendir(DIR,$dir) ) + { + # Remove leading . + if ( $dir eq '.' ) + { + $dir = ''; + } + + foreach $file ( readdir(DIR) ) + { + # Don't allow '..' + next if ( $file =~ /^\.\.?$/ ); + next if ( length($file)<1 ); + + if (length($dir)>0) + { + $p = $dir . '/' . $file; + } + else + { + $p = $file; + } + + if ($tolower != 0) + { + $p = lc($p); + } + + #print "File:$p\n"; + + # Check if it is an excluded file + if (defined($excludes->{$p})) + { + #print "EXCLUDED:$p\n"; + push @{$excluded}, $p; + next; + } + # Check for a desired extension + if ($p =~ /$patterns/i) + { + #print "match:$p\n"; + push @files, $p; + next; + } + #We have seen '0' inserted from a null result. This + #should avoid this problem + @file_result = &find_files($p, $patterns, $excludes, $excluded); + if (scalar(@file_result)>0) + { + push @files, @file_result; + } + } + closedir(DIR); + } + return @files; +} diff --git a/src/mod360-test.cpp b/src/mod360-test.cpp new file mode 100644 index 000000000..83f0feba7 --- /dev/null +++ b/src/mod360-test.cpp @@ -0,0 +1,70 @@ +#include +#include "mod360.h" +#include +#include + +/** Note: doesn't distinguish between 0.0 and -0.0. */ +static bool same_double(double const x, double const y) +{ + return ( ( isnan(x) && isnan(y) ) + || ( x == y ) ); +} + +int main(int argc, char **argv) +{ + double const inf = 1e400; + double const nan = inf - inf; + + utest_start("mod360.cpp"); + + UTEST_TEST("same_double") { + double const sd_cases[] = {inf, -inf, nan, 0.0, -1.0, 1.0, 8.0}; + for (unsigned i = 0; i < G_N_ELEMENTS(sd_cases); ++i) { + for (unsigned j = 0; j < G_N_ELEMENTS(sd_cases); ++j) { + UTEST_ASSERT( same_double(sd_cases[i], sd_cases[j]) + == ( i == j ) ); + } + } + } + + UTEST_TEST("mod360") { + struct Case { + double x; + double y; + } const cases[] = { + {0, 0}, + {10, 10}, + {360, 0}, + {361, 1}, + {-1, 359}, + {-359, 1}, + {-360, -0}, + {-361, 359}, + {inf, 0}, + {-inf, 0}, + {nan, 0}, + {720, 0}, + {-721, 359}, + {-1000, 80} + }; + for(unsigned i = 0; i < G_N_ELEMENTS(cases); ++i) { + Case const &c = cases[i]; + UTEST_ASSERT(same_double(mod360(c.x), c.y)); + } + } + + return ( utest_end() + ? EXIT_SUCCESS + : EXIT_FAILURE ); +} + +/* + 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:textwidth=99 : diff --git a/src/mod360.cpp b/src/mod360.cpp new file mode 100644 index 000000000..a30aa65a7 --- /dev/null +++ b/src/mod360.cpp @@ -0,0 +1,29 @@ +#include +#include + +/** Returns \a x wrapped around to between 0 and less than 360, + or 0 if \a x isn't finite. +**/ +double mod360(double const x) +{ + double const m = fmod(x, 360.0); + double const ret = ( isnan(m) + ? 0.0 + : ( m < 0 + ? m + 360 + : m ) ); + g_return_val_if_fail(0.0 <= ret && ret < 360.0, + 0.0); + return ret; +} + +/* + 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:textwidth=99 : diff --git a/src/mod360.h b/src/mod360.h new file mode 100644 index 000000000..378efab4b --- /dev/null +++ b/src/mod360.h @@ -0,0 +1,17 @@ +#ifndef SEEN_MOD360_H +#define SEEN_MOD360_H + +double mod360(double const x); + +#endif /* !SEEN_MOD360_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:encoding=utf-8:textwidth=99 : diff --git a/src/modifier-fns.h b/src/modifier-fns.h new file mode 100644 index 000000000..a3cab7d20 --- /dev/null +++ b/src/modifier-fns.h @@ -0,0 +1,64 @@ +#ifndef SEEN_MODIFIER_FNS_H +#define SEEN_MODIFIER_FNS_H + +/** \file + * Functions on GdkEventKey.state that test modifier keys. + * + * The MOD__SHIFT macro in macros.h is equivalent to mod_shift(event-\>key.state). + */ + +/* + * Hereby placed in public domain. + */ + +#include +#include + +inline bool +mod_shift(guint const state) +{ + return state & GDK_SHIFT_MASK; +} + +inline bool +mod_ctrl(guint const state) +{ + return state & GDK_CONTROL_MASK; +} + +inline bool +mod_alt(guint const state) +{ + return state & GDK_MOD1_MASK; +} + +inline bool +mod_shift_only(guint const state) +{ + return (state & GDK_SHIFT_MASK) && !(state & GDK_CONTROL_MASK) && !(state & GDK_MOD1_MASK); +} + +inline bool +mod_ctrl_only(guint const state) +{ + return !(state & GDK_SHIFT_MASK) && (state & GDK_CONTROL_MASK) && !(state & GDK_MOD1_MASK); +} + +inline bool +mod_alt_only(guint const state) +{ + return !(state & GDK_SHIFT_MASK) && !(state & GDK_CONTROL_MASK) && (state & GDK_MOD1_MASK); +} + +#endif /* !SEEN_MODIFIER_FNS_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:encoding=utf-8:textwidth=99 : diff --git a/src/node-context.cpp b/src/node-context.cpp new file mode 100644 index 000000000..747fa65b3 --- /dev/null +++ b/src/node-context.cpp @@ -0,0 +1,964 @@ +#define __SP_NODE_CONTEXT_C__ + +/* + * Node editing context + * + * Authors: + * Lauris Kaplinski + * bulia byak + * + * This code is in public domain, except stamping code, + * which is Copyright (C) Masatake Yamato 2002 + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif +#include +#include "macros.h" +#include +#include "display/sp-canvas-util.h" +#include "object-edit.h" +#include "sp-path.h" +#include "path-chemistry.h" +#include "rubberband.h" +#include "desktop.h" +#include "desktop-handles.h" +#include "selection.h" +#include "pixmaps/cursor-node.xpm" +#include "message-context.h" +#include "node-context.h" +#include "pixmaps/cursor-node-d.xpm" +#include "prefs-utils.h" +#include "xml/node-event-vector.h" +#include "style.h" +#include "splivarot.h" + +static void sp_node_context_class_init(SPNodeContextClass *klass); +static void sp_node_context_init(SPNodeContext *node_context); +static void sp_node_context_dispose(GObject *object); + +static void sp_node_context_setup(SPEventContext *ec); +static gint sp_node_context_root_handler(SPEventContext *event_context, GdkEvent *event); +static gint sp_node_context_item_handler(SPEventContext *event_context, + SPItem *item, GdkEvent *event); + +static void nodepath_event_attr_changed(Inkscape::XML::Node *repr, gchar const *name, + gchar const *old_value, gchar const *new_value, + bool is_interactive, gpointer data); + +static Inkscape::XML::NodeEventVector nodepath_repr_events = { + NULL, /* child_added */ + NULL, /* child_removed */ + nodepath_event_attr_changed, + NULL, /* content_changed */ + NULL /* order_changed */ +}; + +static SPEventContextClass *parent_class; + +static gchar *undo_label_1 = "dragcurve:1"; +static gchar *undo_label_2 = "dragcurve:2"; +static gchar *undo_label = undo_label_1; + +GType +sp_node_context_get_type() +{ + static GType type = 0; + if (!type) { + GTypeInfo info = { + sizeof(SPNodeContextClass), + NULL, NULL, + (GClassInitFunc) sp_node_context_class_init, + NULL, NULL, + sizeof(SPNodeContext), + 4, + (GInstanceInitFunc) sp_node_context_init, + NULL, /* value_table */ + }; + type = g_type_register_static(SP_TYPE_EVENT_CONTEXT, "SPNodeContext", &info, (GTypeFlags)0); + } + return type; +} + +static void +sp_node_context_class_init(SPNodeContextClass *klass) +{ + GObjectClass *object_class = (GObjectClass *) klass; + SPEventContextClass *event_context_class = (SPEventContextClass *) klass; + + parent_class = (SPEventContextClass*)g_type_class_peek_parent(klass); + + object_class->dispose = sp_node_context_dispose; + + event_context_class->setup = sp_node_context_setup; + event_context_class->root_handler = sp_node_context_root_handler; + event_context_class->item_handler = sp_node_context_item_handler; +} + +static void +sp_node_context_init(SPNodeContext *node_context) +{ + SPEventContext *event_context = SP_EVENT_CONTEXT(node_context); + + event_context->cursor_shape = cursor_node_xpm; + event_context->hot_x = 1; + event_context->hot_y = 1; + + node_context->leftalt = FALSE; + node_context->rightalt = FALSE; + node_context->leftctrl = FALSE; + node_context->rightctrl = FALSE; + + new (&node_context->sel_changed_connection) sigc::connection(); +} + +static void +sp_node_context_dispose(GObject *object) +{ + SPNodeContext *nc = SP_NODE_CONTEXT(object); + SPEventContext *ec = SP_EVENT_CONTEXT(object); + + ec->enableGrDrag(false); + + nc->sel_changed_connection.disconnect(); + nc->sel_changed_connection.~connection(); + + Inkscape::XML::Node *repr = NULL; + if (nc->nodepath) { + repr = nc->nodepath->repr; + } + if (!repr && ec->shape_knot_holder) { + repr = ec->shape_knot_holder->repr; + } + + if (repr) { + sp_repr_remove_listener_by_data(repr, ec); + Inkscape::GC::release(repr); + } + + if (nc->nodepath) { + sp_nodepath_destroy(nc->nodepath); + nc->nodepath = NULL; + } + + if (ec->shape_knot_holder) { + sp_knot_holder_destroy(ec->shape_knot_holder); + ec->shape_knot_holder = NULL; + } + + if (nc->_node_message_context) { + delete nc->_node_message_context; + } + + G_OBJECT_CLASS(parent_class)->dispose(object); +} + +static void +sp_node_context_setup(SPEventContext *ec) +{ + SPNodeContext *nc = SP_NODE_CONTEXT(ec); + + if (((SPEventContextClass *) parent_class)->setup) + ((SPEventContextClass *) parent_class)->setup(ec); + + nc->sel_changed_connection.disconnect(); + nc->sel_changed_connection = SP_DT_SELECTION(ec->desktop)->connectChanged(sigc::bind(sigc::ptr_fun(&sp_node_context_selection_changed), (gpointer)nc)); + + Inkscape::Selection *selection = SP_DT_SELECTION(ec->desktop); + SPItem *item = selection->singleItem(); + + nc->nodepath = NULL; + ec->shape_knot_holder = NULL; + + nc->rb_escaped = false; + + nc->cursor_drag = false; + + nc->added_node = false; + + if (item) { + nc->nodepath = sp_nodepath_new(ec->desktop, item); + if ( nc->nodepath) { + //point pack to parent in case nodepath is deleted + nc->nodepath->nodeContext = nc; + } + ec->shape_knot_holder = sp_item_knot_holder(item, ec->desktop); + + if (nc->nodepath || ec->shape_knot_holder) { + // setting listener + Inkscape::XML::Node *repr; + if (ec->shape_knot_holder) + repr = ec->shape_knot_holder->repr; + else + repr = SP_OBJECT_REPR(item); + if (repr) { + Inkscape::GC::anchor(repr); + sp_repr_add_listener(repr, &nodepath_repr_events, ec); + sp_repr_synthesize_events(repr, &nodepath_repr_events, ec); + } + } + } + + if (prefs_get_int_attribute("tools.nodes", "selcue", 0) != 0) { + ec->enableSelectionCue(); + } + + if (prefs_get_int_attribute("tools.nodes", "gradientdrag", 0) != 0) { + ec->enableGrDrag(); + } + + nc->_node_message_context = new Inkscape::MessageContext((ec->desktop)->messageStack()); + sp_nodepath_update_statusbar(nc->nodepath); +} + +/** +\brief Callback that processes the "changed" signal on the selection; +destroys old and creates new nodepath and reassigns listeners to the new selected item's repr +*/ +void +sp_node_context_selection_changed(Inkscape::Selection *selection, gpointer data) +{ + SPNodeContext *nc = SP_NODE_CONTEXT(data); + SPEventContext *ec = SP_EVENT_CONTEXT(nc); + + Inkscape::XML::Node *old_repr = NULL; + + if (nc->nodepath) { + old_repr = nc->nodepath->repr; + sp_nodepath_destroy(nc->nodepath); + } + if (ec->shape_knot_holder) { + old_repr = ec->shape_knot_holder->repr; + sp_knot_holder_destroy(ec->shape_knot_holder); + } + + if (old_repr) { // remove old listener + sp_repr_remove_listener_by_data(old_repr, ec); + Inkscape::GC::release(old_repr); + } + + SPItem *item = selection->singleItem(); + + SPDesktop *desktop = selection->desktop(); + nc->nodepath = NULL; + ec->shape_knot_holder = NULL; + if (item) { + nc->nodepath = sp_nodepath_new(desktop, item); + if (nc->nodepath) { + nc->nodepath->nodeContext = nc; + } + ec->shape_knot_holder = sp_item_knot_holder(item, desktop); + + if (nc->nodepath || ec->shape_knot_holder) { + // setting new listener + Inkscape::XML::Node *repr; + if (ec->shape_knot_holder) + repr = ec->shape_knot_holder->repr; + else + repr = SP_OBJECT_REPR(item); + if (repr) { + Inkscape::GC::anchor(repr); + sp_repr_add_listener(repr, &nodepath_repr_events, ec); + sp_repr_synthesize_events(repr, &nodepath_repr_events, ec); + } + } + } + sp_nodepath_update_statusbar(nc->nodepath); +} + +/** +\brief Regenerates nodepath when the item's repr was change outside of node edit +(e.g. by undo, or xml editor, or edited in another view). The item is assumed to be the same +(otherwise sp_node_context_selection_changed() would have been called), so repr and listeners +are not changed. +*/ +void +sp_nodepath_update_from_item(SPNodeContext *nc, SPItem *item) +{ + g_assert(nc); + SPEventContext *ec = ((SPEventContext *) nc); + + SPDesktop *desktop = SP_EVENT_CONTEXT_DESKTOP(SP_EVENT_CONTEXT(nc)); + g_assert(desktop); + + if (nc->nodepath) { + sp_nodepath_destroy(nc->nodepath); + } + + if (ec->shape_knot_holder) { + sp_knot_holder_destroy(ec->shape_knot_holder); + } + + Inkscape::Selection *selection = SP_DT_SELECTION(desktop); + item = selection->singleItem(); + + nc->nodepath = NULL; + ec->shape_knot_holder = NULL; + if (item) { + nc->nodepath = sp_nodepath_new(desktop, item); + if (nc->nodepath) { + nc->nodepath->nodeContext = nc; + } + ec->shape_knot_holder = sp_item_knot_holder(item, desktop); + } + sp_nodepath_update_statusbar(nc->nodepath); +} + +/** +\brief Callback that is fired whenever an attribute of the selected item (which we have in the nodepath) changes +*/ +static void +nodepath_event_attr_changed(Inkscape::XML::Node *repr, gchar const *name, + gchar const *old_value, gchar const *new_value, + bool is_interactive, gpointer data) +{ + SPItem *item = NULL; + char const *newd = NULL, *newtypestr = NULL; + gboolean changed = FALSE; + + g_assert(data); + SPNodeContext *nc = ((SPNodeContext *) data); + SPEventContext *ec = ((SPEventContext *) data); + g_assert(nc); + Inkscape::NodePath::Path *np = nc->nodepath; + SPKnotHolder *kh = ec->shape_knot_holder; + + if (np) { + item = SP_ITEM(np->path); + if (!strcmp(name, "d")) { + newd = new_value; + changed = nodepath_repr_d_changed(np, new_value); + } else if (!strcmp(name, "sodipodi:nodetypes")) { + newtypestr = new_value; + changed = nodepath_repr_typestr_changed(np, new_value); + } else { + return; + // With paths, we only need to act if one of the path-affecting attributes has changed. + } + } else if (kh) { + item = SP_ITEM(kh->item); + changed = !(kh->local_change); + kh->local_change = FALSE; + } + if (np && changed) { + GList *saved = NULL; + SPDesktop *desktop = np->desktop; + g_assert(desktop); + Inkscape::Selection *selection = desktop->selection; + g_assert(selection); + + saved = save_nodepath_selection(nc->nodepath); + sp_nodepath_update_from_item(nc, item); + if (nc->nodepath && saved) restore_nodepath_selection(nc->nodepath, saved); + + } else if (kh && changed) { + sp_nodepath_update_from_item(nc, item); + } + + sp_nodepath_update_statusbar(nc->nodepath); +} + +void +sp_node_context_show_modifier_tip(SPEventContext *event_context, GdkEvent *event) +{ + sp_event_show_modifier_tip + (event_context->defaultMessageContext(), event, + _("Ctrl: toggle node type, snap handle angle, move hor/vert; Ctrl+Alt: move along handles"), + _("Shift: toggle node selection, disable snapping, rotate both handles"), + _("Alt: lock handle length; Ctrl+Alt: move along handles")); +} + +bool +sp_node_context_is_over_stroke (SPNodeContext *nc, SPItem *item, NR::Point event_p, bool remember) +{ + SPDesktop *desktop = SP_EVENT_CONTEXT (nc)->desktop; + + //Translate click point into proper coord system + nc->curvepoint_doc = desktop->w2d(event_p); + nc->curvepoint_doc *= sp_item_dt2i_affine(item); + nc->curvepoint_doc *= sp_item_i2doc_affine(item); + + NR::Maybe position = get_nearest_position_on_Path(item, nc->curvepoint_doc); + NR::Point nearest = get_point_on_Path(item, position.assume().piece, position.assume().t); + NR::Point delta = nearest - nc->curvepoint_doc; + + delta = desktop->d2w(delta); + + double stroke_tolerance = + (SP_OBJECT_STYLE (item)->stroke.type != SP_PAINT_TYPE_NONE? + desktop->current_zoom() * + SP_OBJECT_STYLE (item)->stroke_width.computed * + sp_item_i2d_affine (item).expansion() * 0.5 + : 0.0) + + (double) SP_EVENT_CONTEXT(nc)->tolerance; + + bool close = (NR::L2 (delta) < stroke_tolerance); + + if (remember && close) { + nc->curvepoint_event[NR::X] = (gint) event_p [NR::X]; + nc->curvepoint_event[NR::Y] = (gint) event_p [NR::Y]; + nc->hit = true; + nc->grab_t = position.assume().t; + nc->grab_node = sp_nodepath_get_node_by_index(position.assume().piece); + } + + return close; +} + + +static gint +sp_node_context_item_handler(SPEventContext *event_context, SPItem *item, GdkEvent *event) +{ + gint ret = FALSE; + + SPDesktop *desktop = event_context->desktop; + Inkscape::Selection *selection = SP_DT_SELECTION (desktop); + + SPNodeContext *nc = SP_NODE_CONTEXT(event_context); + + switch (event->type) { + case GDK_2BUTTON_PRESS: + case GDK_BUTTON_RELEASE: + if (event->button.button == 1) { + if (!nc->drag) { + + // find out clicked item, disregarding groups, honoring Alt + SPItem *item_clicked = sp_event_context_find_item (desktop, + NR::Point(event->button.x, event->button.y), + (event->button.state & GDK_MOD1_MASK) && !(event->button.state & GDK_CONTROL_MASK), TRUE); + // find out if we're over the selected item, disregarding groups + SPItem *item_over = sp_event_context_over_item (desktop, selection->singleItem(), + NR::Point(event->button.x, event->button.y)); + bool over_stroke = false; + if (item_over && nc->nodepath) { + over_stroke = sp_node_context_is_over_stroke (nc, item_over, NR::Point(event->button.x, event->button.y), false); + } + + if (over_stroke || nc->added_node) { + switch (event->type) { + case GDK_BUTTON_RELEASE: + if (event->button.state & GDK_CONTROL_MASK && event->button.state & GDK_MOD1_MASK) { + //add a node + sp_nodepath_add_node_near_point(item_over, nc->curvepoint_doc); + } else { + if (nc->added_node) { // we just received double click, ignore release + nc->added_node = false; + break; + } + //select the segment + if (event->button.state & GDK_SHIFT_MASK) { + sp_nodepath_select_segment_near_point(item_over, nc->curvepoint_doc, true); + } else { + sp_nodepath_select_segment_near_point(item_over, nc->curvepoint_doc, false); + } + } + break; + case GDK_2BUTTON_PRESS: + //add a node + sp_nodepath_add_node_near_point(item_over, nc->curvepoint_doc); + nc->added_node = true; + break; + default: + break; + } + } else if (event->button.state & GDK_SHIFT_MASK) { + selection->toggle(item_clicked); + } else { + selection->set(item_clicked); + } + + ret = TRUE; + } + break; + } + break; + case GDK_BUTTON_PRESS: + if (event->button.button == 1 && !(event->button.state & GDK_SHIFT_MASK)) { + // save drag origin + event_context->xp = (gint) event->button.x; + event_context->yp = (gint) event->button.y; + event_context->within_tolerance = true; + nc->hit = false; + + if (!nc->drag) { + // find out if we're over the selected item, disregarding groups + SPItem *item_over = sp_event_context_over_item (desktop, selection->singleItem(), + NR::Point(event->button.x, event->button.y)); + + if (nc->nodepath && selection->single() && item_over) { + + // save drag origin + bool over_stroke = sp_node_context_is_over_stroke (nc, item_over, NR::Point(event->button.x, event->button.y), true); + //only dragging curves + if (over_stroke) { + sp_nodepath_select_segment_near_point(item_over, nc->curvepoint_doc, false); + ret = TRUE; + } else { + break; + } + } else { + break; + } + + ret = TRUE; + } + break; + } + break; + default: + break; + } + + if (!ret) { + if (((SPEventContextClass *) parent_class)->item_handler) + ret = ((SPEventContextClass *) parent_class)->item_handler(event_context, item, event); + } + + return ret; +} + +static gint +sp_node_context_root_handler(SPEventContext *event_context, GdkEvent *event) +{ + SPDesktop *desktop = event_context->desktop; + Inkscape::Selection *selection = SP_DT_SELECTION (desktop); + + SPNodeContext *nc = SP_NODE_CONTEXT(event_context); + double const nudge = prefs_get_double_attribute_limited("options.nudgedistance", "value", 2, 0, 1000); // in px + event_context->tolerance = prefs_get_int_attribute_limited("options.dragtolerance", "value", 0, 0, 100); // read every time, to make prefs changes really live + int const snaps = prefs_get_int_attribute("options.rotationsnapsperpi", "value", 12); + double const offset = prefs_get_double_attribute_limited("options.defaultscale", "value", 2, 0, 1000); + + gint ret = FALSE; + + switch (event->type) { + case GDK_BUTTON_PRESS: + if (event->button.button == 1) { + // save drag origin + event_context->xp = (gint) event->button.x; + event_context->yp = (gint) event->button.y; + event_context->within_tolerance = true; + nc->hit = false; + + NR::Point const button_w(event->button.x, + event->button.y); + NR::Point const button_dt(desktop->w2d(button_w)); + Inkscape::Rubberband::get()->start(desktop, button_dt); + ret = TRUE; + } + break; + case GDK_MOTION_NOTIFY: + if (event->motion.state & GDK_BUTTON1_MASK) { + + if ( event_context->within_tolerance + && ( abs( (gint) event->motion.x - event_context->xp ) < event_context->tolerance ) + && ( abs( (gint) event->motion.y - event_context->yp ) < event_context->tolerance ) ) { + break; // do not drag if we're within tolerance from origin + } + // Once the user has moved farther than tolerance from the original location + // (indicating they intend to move the object, not click), then always process the + // motion notify coordinates as given (no snapping back to origin) + event_context->within_tolerance = false; + + if (nc->nodepath && nc->hit) { + NR::Point const delta_w(event->motion.x - nc->curvepoint_event[NR::X], + event->motion.y - nc->curvepoint_event[NR::Y]); + NR::Point const delta_dt(desktop->w2d(delta_w)); + sp_nodepath_curve_drag (nc->grab_node, nc->grab_t, delta_dt, undo_label); + nc->curvepoint_event[NR::X] = (gint) event->motion.x; + nc->curvepoint_event[NR::Y] = (gint) event->motion.y; + gobble_motion_events(GDK_BUTTON1_MASK); + } else { + NR::Point const motion_w(event->motion.x, + event->motion.y); + NR::Point const motion_dt(desktop->w2d(motion_w)); + Inkscape::Rubberband::get()->move(motion_dt); + } + nc->drag = TRUE; + ret = TRUE; + } else { + if (!nc->nodepath || selection->singleItem() == NULL) { + break; + } + + SPItem *item_over = sp_event_context_over_item (desktop, selection->singleItem(), + NR::Point(event->motion.x, event->motion.y)); + bool over_stroke = false; + if (item_over && nc->nodepath) { + over_stroke = sp_node_context_is_over_stroke (nc, item_over, NR::Point(event->motion.x, event->motion.y), false); + } + + if (nc->cursor_drag && !over_stroke) { + event_context->cursor_shape = cursor_node_xpm; + event_context->hot_x = 1; + event_context->hot_y = 1; + sp_event_context_update_cursor(event_context); + nc->cursor_drag = false; + } else if (!nc->cursor_drag && over_stroke) { + event_context->cursor_shape = cursor_node_d_xpm; + event_context->hot_x = 1; + event_context->hot_y = 1; + sp_event_context_update_cursor(event_context); + nc->cursor_drag = true; + } + } + break; + case GDK_BUTTON_RELEASE: + event_context->xp = event_context->yp = 0; + if (event->button.button == 1) { + + NR::Maybe b = Inkscape::Rubberband::get()->getRectangle(); + + if (nc->hit && !event_context->within_tolerance) { //drag curve + if (undo_label == undo_label_1) + undo_label = undo_label_2; + else + undo_label = undo_label_1; + } else if (b != NR::Nothing() && !event_context->within_tolerance) { // drag to select + if (nc->nodepath) { + sp_nodepath_select_rect(nc->nodepath, b.assume(), event->button.state & GDK_SHIFT_MASK); + } + } else { + if (!(nc->rb_escaped)) { // unless something was cancelled + if (nc->nodepath && nc->nodepath->selected) + sp_nodepath_deselect(nc->nodepath); + else + SP_DT_SELECTION(desktop)->clear(); + } + } + ret = TRUE; + Inkscape::Rubberband::get()->stop(); + nc->rb_escaped = false; + nc->drag = FALSE; + nc->hit = false; + break; + } + break; + case GDK_KEY_PRESS: + switch (get_group0_keyval(&event->key)) { + case GDK_Insert: + case GDK_KP_Insert: + // with any modifiers + sp_node_selected_add_node(); + ret = TRUE; + break; + case GDK_Delete: + case GDK_KP_Delete: + case GDK_BackSpace: + // with any modifiers + sp_node_selected_delete(); + ret = TRUE; + break; + case GDK_C: + case GDK_c: + if (MOD__SHIFT_ONLY) { + sp_node_selected_set_type(Inkscape::NodePath::NODE_CUSP); + ret = TRUE; + } + break; + case GDK_S: + case GDK_s: + if (MOD__SHIFT_ONLY) { + sp_node_selected_set_type(Inkscape::NodePath::NODE_SMOOTH); + ret = TRUE; + } + break; + case GDK_Y: + case GDK_y: + if (MOD__SHIFT_ONLY) { + sp_node_selected_set_type(Inkscape::NodePath::NODE_SYMM); + ret = TRUE; + } + break; + case GDK_B: + case GDK_b: + if (MOD__SHIFT_ONLY) { + sp_node_selected_break(); + ret = TRUE; + } + break; + case GDK_J: + case GDK_j: + if (MOD__SHIFT_ONLY) { + sp_node_selected_join(); + ret = TRUE; + } + break; + case GDK_D: + case GDK_d: + if (MOD__SHIFT_ONLY) { + sp_node_selected_duplicate(); + ret = TRUE; + } + break; + case GDK_L: + case GDK_l: + if (MOD__SHIFT_ONLY) { + sp_node_selected_set_line_type(NR_LINETO); + ret = TRUE; + } + break; + case GDK_U: + case GDK_u: + if (MOD__SHIFT_ONLY) { + sp_node_selected_set_line_type(NR_CURVETO); + ret = TRUE; + } + break; + case GDK_R: + case GDK_r: + if (MOD__SHIFT_ONLY) { + // FIXME: add top panel button + sp_selected_path_reverse(); + ret = TRUE; + } + break; + case GDK_Left: // move selection left + case GDK_KP_Left: + case GDK_KP_4: + if (!MOD__CTRL) { // not ctrl + if (MOD__ALT) { // alt + if (MOD__SHIFT) sp_node_selected_move_screen(-10, 0); // shift + else sp_node_selected_move_screen(-1, 0); // no shift + } + else { // no alt + if (MOD__SHIFT) sp_node_selected_move(-10*nudge, 0); // shift + else sp_node_selected_move(-nudge, 0); // no shift + } + ret = TRUE; + } + break; + case GDK_Up: // move selection up + case GDK_KP_Up: + case GDK_KP_8: + if (!MOD__CTRL) { // not ctrl + if (MOD__ALT) { // alt + if (MOD__SHIFT) sp_node_selected_move_screen(0, 10); // shift + else sp_node_selected_move_screen(0, 1); // no shift + } + else { // no alt + if (MOD__SHIFT) sp_node_selected_move(0, 10*nudge); // shift + else sp_node_selected_move(0, nudge); // no shift + } + ret = TRUE; + } + break; + case GDK_Right: // move selection right + case GDK_KP_Right: + case GDK_KP_6: + if (!MOD__CTRL) { // not ctrl + if (MOD__ALT) { // alt + if (MOD__SHIFT) sp_node_selected_move_screen(10, 0); // shift + else sp_node_selected_move_screen(1, 0); // no shift + } + else { // no alt + if (MOD__SHIFT) sp_node_selected_move(10*nudge, 0); // shift + else sp_node_selected_move(nudge, 0); // no shift + } + ret = TRUE; + } + break; + case GDK_Down: // move selection down + case GDK_KP_Down: + case GDK_KP_2: + if (!MOD__CTRL) { // not ctrl + if (MOD__ALT) { // alt + if (MOD__SHIFT) sp_node_selected_move_screen(0, -10); // shift + else sp_node_selected_move_screen(0, -1); // no shift + } + else { // no alt + if (MOD__SHIFT) sp_node_selected_move(0, -10*nudge); // shift + else sp_node_selected_move(0, -nudge); // no shift + } + ret = TRUE; + } + break; + case GDK_Tab: // Tab - cycle selection forward + if (!(MOD__CTRL_ONLY || (MOD__CTRL && MOD__SHIFT))) { + sp_nodepath_select_next(nc->nodepath); + ret = TRUE; + } + break; + case GDK_ISO_Left_Tab: // Shift Tab - cycle selection backward + if (!(MOD__CTRL_ONLY || (MOD__CTRL && MOD__SHIFT))) { + sp_nodepath_select_prev(nc->nodepath); + ret = TRUE; + } + break; + case GDK_Escape: + { + NR::Maybe const b = Inkscape::Rubberband::get()->getRectangle(); + if (b != NR::Nothing()) { + Inkscape::Rubberband::get()->stop(); + nc->rb_escaped = true; + } else { + if (nc->nodepath && nc->nodepath->selected) { + sp_nodepath_deselect(nc->nodepath); + } else { + SP_DT_SELECTION(desktop)->clear(); + } + } + ret = TRUE; + break; + } + + case GDK_bracketleft: + if ( MOD__CTRL && !MOD__ALT && ( snaps != 0 ) ) { + if (nc->leftctrl) + sp_nodepath_selected_nodes_rotate (nc->nodepath, M_PI/snaps, -1, false); + if (nc->rightctrl) + sp_nodepath_selected_nodes_rotate (nc->nodepath, M_PI/snaps, 1, false); + } else if ( MOD__ALT && !MOD__CTRL ) { + if (nc->leftalt && nc->rightalt) + sp_nodepath_selected_nodes_rotate (nc->nodepath, 1, 0, true); + else { + if (nc->leftalt) + sp_nodepath_selected_nodes_rotate (nc->nodepath, 1, -1, true); + if (nc->rightalt) + sp_nodepath_selected_nodes_rotate (nc->nodepath, 1, 1, true); + } + } else if ( snaps != 0 ) { + sp_nodepath_selected_nodes_rotate (nc->nodepath, M_PI/snaps, 0, false); + } + ret = TRUE; + break; + case GDK_bracketright: + if ( MOD__CTRL && !MOD__ALT && ( snaps != 0 ) ) { + if (nc->leftctrl) + sp_nodepath_selected_nodes_rotate (nc->nodepath, -M_PI/snaps, -1, false); + if (nc->rightctrl) + sp_nodepath_selected_nodes_rotate (nc->nodepath, -M_PI/snaps, 1, false); + } else if ( MOD__ALT && !MOD__CTRL ) { + if (nc->leftalt && nc->rightalt) + sp_nodepath_selected_nodes_rotate (nc->nodepath, -1, 0, true); + else { + if (nc->leftalt) + sp_nodepath_selected_nodes_rotate (nc->nodepath, -1, -1, true); + if (nc->rightalt) + sp_nodepath_selected_nodes_rotate (nc->nodepath, -1, 1, true); + } + } else if ( snaps != 0 ) { + sp_nodepath_selected_nodes_rotate (nc->nodepath, -M_PI/snaps, 0, false); + } + ret = TRUE; + break; + case GDK_less: + case GDK_comma: + if (MOD__CTRL) { + if (nc->leftctrl) + sp_nodepath_selected_nodes_scale(nc->nodepath, -offset, -1); + if (nc->rightctrl) + sp_nodepath_selected_nodes_scale(nc->nodepath, -offset, 1); + } else if (MOD__ALT) { + if (nc->leftalt && nc->rightalt) + sp_nodepath_selected_nodes_scale_screen(nc->nodepath, -1, 0); + else { + if (nc->leftalt) + sp_nodepath_selected_nodes_scale_screen(nc->nodepath, -1, -1); + if (nc->rightalt) + sp_nodepath_selected_nodes_scale_screen(nc->nodepath, -1, 1); + } + } else { + sp_nodepath_selected_nodes_scale(nc->nodepath, -offset, 0); + } + ret = TRUE; + break; + case GDK_greater: + case GDK_period: + if (MOD__CTRL) { + if (nc->leftctrl) + sp_nodepath_selected_nodes_scale(nc->nodepath, offset, -1); + if (nc->rightctrl) + sp_nodepath_selected_nodes_scale(nc->nodepath, offset, 1); + } else if (MOD__ALT) { + if (nc->leftalt && nc->rightalt) + sp_nodepath_selected_nodes_scale_screen(nc->nodepath, 1, 0); + else { + if (nc->leftalt) + sp_nodepath_selected_nodes_scale_screen(nc->nodepath, 1, -1); + if (nc->rightalt) + sp_nodepath_selected_nodes_scale_screen(nc->nodepath, 1, 1); + } + } else { + sp_nodepath_selected_nodes_scale(nc->nodepath, offset, 0); + } + ret = TRUE; + break; + + case GDK_Alt_L: + nc->leftalt = TRUE; + sp_node_context_show_modifier_tip(event_context, event); + break; + case GDK_Alt_R: + nc->rightalt = TRUE; + sp_node_context_show_modifier_tip(event_context, event); + break; + case GDK_Control_L: + nc->leftctrl = TRUE; + sp_node_context_show_modifier_tip(event_context, event); + break; + case GDK_Control_R: + nc->rightctrl = TRUE; + sp_node_context_show_modifier_tip(event_context, event); + break; + case GDK_Shift_L: + case GDK_Shift_R: + case GDK_Meta_L: + case GDK_Meta_R: + sp_node_context_show_modifier_tip(event_context, event); + break; + default: + ret = node_key(event); + break; + } + break; + case GDK_KEY_RELEASE: + switch (get_group0_keyval(&event->key)) { + case GDK_Alt_L: + nc->leftalt = FALSE; + event_context->defaultMessageContext()->clear(); + break; + case GDK_Alt_R: + nc->rightalt = FALSE; + event_context->defaultMessageContext()->clear(); + break; + case GDK_Control_L: + nc->leftctrl = FALSE; + event_context->defaultMessageContext()->clear(); + break; + case GDK_Control_R: + nc->rightctrl = FALSE; + event_context->defaultMessageContext()->clear(); + break; + case GDK_Shift_L: + case GDK_Shift_R: + case GDK_Meta_L: + case GDK_Meta_R: + event_context->defaultMessageContext()->clear(); + break; + } + break; + default: + break; + } + + if (!ret) { + if (((SPEventContextClass *) parent_class)->root_handler) + ret = ((SPEventContextClass *) parent_class)->root_handler(event_context, event); + } + + return ret; +} + + +/* + 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:textwidth=99 : diff --git a/src/node-context.h b/src/node-context.h new file mode 100644 index 000000000..a9b4beb07 --- /dev/null +++ b/src/node-context.h @@ -0,0 +1,69 @@ +#ifndef __SP_NODE_CONTEXT_H__ +#define __SP_NODE_CONTEXT_H__ + +/* + * Node editing context + * + * Authors: + * Lauris Kaplinski + * bulia byak + * + * This code is in public domain + */ + +#include +#include "event-context.h" +#include "forward.h" +#include "nodepath.h" +struct SPKnotHolder; +namespace Inkscape { class Selection; } + +#define SP_TYPE_NODE_CONTEXT (sp_node_context_get_type ()) +#define SP_NODE_CONTEXT(obj) (GTK_CHECK_CAST ((obj), SP_TYPE_NODE_CONTEXT, SPNodeContext)) +#define SP_NODE_CONTEXT_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), SP_TYPE_NODE_CONTEXT, SPNodeContextClass)) +#define SP_IS_NODE_CONTEXT(obj) (GTK_CHECK_TYPE ((obj), SP_TYPE_NODE_CONTEXT)) +#define SP_IS_NODE_CONTEXT_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), SP_TYPE_NODE_CONTEXT)) + +class SPNodeContext; +class SPNodeContextClass; + +struct SPNodeContext { + SPEventContext event_context; + + guint drag : 1; + + Inkscape::NodePath::Path *nodepath; + + gboolean leftalt; + gboolean rightalt; + gboolean leftctrl; + gboolean rightctrl; + + /// If true, rubberband was cancelled by esc, so the next button release should not deselect. + bool rb_escaped; + + sigc::connection sel_changed_connection; + + Inkscape::MessageContext *_node_message_context; + + double grab_t; + Inkscape::NodePath::Node * grab_node; + bool hit; + NR::Point curvepoint_event; // int coords from event + NR::Point curvepoint_doc; // same, in doc coords + bool cursor_drag; + + bool added_node; +}; + +struct SPNodeContextClass { + SPEventContextClass parent_class; +}; + +/* Standard Gtk function */ + +GtkType sp_node_context_get_type (void); + +void sp_node_context_selection_changed (Inkscape::Selection * selection, gpointer data); + +#endif diff --git a/src/nodepath.cpp b/src/nodepath.cpp new file mode 100644 index 000000000..c28ca7b80 --- /dev/null +++ b/src/nodepath.cpp @@ -0,0 +1,3675 @@ +#define __SP_NODEPATH_C__ + +/** \file + * Path handler in node edit mode + * + * Authors: + * Lauris Kaplinski + * bulia byak + * + * This code is in public domain + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include "display/curve.h" +#include "display/sp-ctrlline.h" +#include "display/sodipodi-ctrl.h" +#include +#include "libnr/n-art-bpath.h" +#include "helper/units.h" +#include "knot.h" +#include "inkscape.h" +#include "document.h" +#include "sp-namedview.h" +#include "desktop.h" +#include "desktop-handles.h" +#include "snap.h" +#include "message-stack.h" +#include "message-context.h" +#include "node-context.h" +#include "selection-chemistry.h" +#include "selection.h" +#include "xml/repr.h" +#include "prefs-utils.h" +#include "sp-metrics.h" +#include "sp-path.h" +#include +#include "splivarot.h" +#include "svg/svg.h" + +class NR::Matrix; + +/// \todo +/// evil evil evil. FIXME: conflict of two different Path classes! +/// There is a conflict in the namespace between two classes named Path. +/// #include "sp-flowtext.h" +/// #include "sp-flowregion.h" + +#define SP_TYPE_FLOWREGION (sp_flowregion_get_type ()) +#define SP_IS_FLOWREGION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_FLOWREGION)) +GType sp_flowregion_get_type (void); +#define SP_TYPE_FLOWTEXT (sp_flowtext_get_type ()) +#define SP_IS_FLOWTEXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_FLOWTEXT)) +GType sp_flowtext_get_type (void); +// end evil workaround + +#include "helper/stlport.h" + + +/// \todo fixme: Implement these via preferences */ + +#define NODE_FILL 0xbfbfbf00 +#define NODE_STROKE 0x000000ff +#define NODE_FILL_HI 0xff000000 +#define NODE_STROKE_HI 0x000000ff +#define NODE_FILL_SEL 0x0000ffff +#define NODE_STROKE_SEL 0x000000ff +#define NODE_FILL_SEL_HI 0xff000000 +#define NODE_STROKE_SEL_HI 0x000000ff +#define KNOT_FILL 0xffffffff +#define KNOT_STROKE 0x000000ff +#define KNOT_FILL_HI 0xff000000 +#define KNOT_STROKE_HI 0x000000ff + +static GMemChunk *nodechunk = NULL; + +/* Creation from object */ + +static NArtBpath *subpath_from_bpath(Inkscape::NodePath::Path *np, NArtBpath *b, gchar const *t); +static gchar *parse_nodetypes(gchar const *types, gint length); + +/* Object updating */ + +static void stamp_repr(Inkscape::NodePath::Path *np); +static SPCurve *create_curve(Inkscape::NodePath::Path *np); +static gchar *create_typestr(Inkscape::NodePath::Path *np); + +static void sp_node_ensure_ctrls(Inkscape::NodePath::Node *node); + +static void sp_nodepath_node_select(Inkscape::NodePath::Node *node, gboolean incremental, gboolean override); + +static void sp_node_set_selected(Inkscape::NodePath::Node *node, gboolean selected); + +/* Control knot placement, if node or other knot is moved */ + +static void sp_node_adjust_knot(Inkscape::NodePath::Node *node, gint which_adjust); +static void sp_node_adjust_knots(Inkscape::NodePath::Node *node); + +/* Knot event handlers */ + +static void node_clicked(SPKnot *knot, guint state, gpointer data); +static void node_grabbed(SPKnot *knot, guint state, gpointer data); +static void node_ungrabbed(SPKnot *knot, guint state, gpointer data); +static gboolean node_request(SPKnot *knot, NR::Point *p, guint state, gpointer data); +static void node_ctrl_clicked(SPKnot *knot, guint state, gpointer data); +static void node_ctrl_grabbed(SPKnot *knot, guint state, gpointer data); +static void node_ctrl_ungrabbed(SPKnot *knot, guint state, gpointer data); +static gboolean node_ctrl_request(SPKnot *knot, NR::Point *p, guint state, gpointer data); +static void node_ctrl_moved(SPKnot *knot, NR::Point *p, guint state, gpointer data); + +/* Constructors and destructors */ + +static Inkscape::NodePath::SubPath *sp_nodepath_subpath_new(Inkscape::NodePath::Path *nodepath); +static void sp_nodepath_subpath_destroy(Inkscape::NodePath::SubPath *subpath); +static void sp_nodepath_subpath_close(Inkscape::NodePath::SubPath *sp); +static void sp_nodepath_subpath_open(Inkscape::NodePath::SubPath *sp,Inkscape::NodePath::Node *n); +static Inkscape::NodePath::Node * sp_nodepath_node_new(Inkscape::NodePath::SubPath *sp,Inkscape::NodePath::Node *next,Inkscape::NodePath::NodeType type, NRPathcode code, + NR::Point *ppos, NR::Point *pos, NR::Point *npos); +static void sp_nodepath_node_destroy(Inkscape::NodePath::Node *node); + +/* Helpers */ + +static Inkscape::NodePath::NodeSide *sp_node_get_side(Inkscape::NodePath::Node *node, gint which); +static Inkscape::NodePath::NodeSide *sp_node_opposite_side(Inkscape::NodePath::Node *node,Inkscape::NodePath::NodeSide *me); +static NRPathcode sp_node_path_code_from_side(Inkscape::NodePath::Node *node,Inkscape::NodePath::NodeSide *me); + +// active_node indicates mouseover node +static Inkscape::NodePath::Node *active_node = NULL; + +/** + * \brief Creates new nodepath from item + */ +Inkscape::NodePath::Path *sp_nodepath_new(SPDesktop *desktop, SPItem *item) +{ + Inkscape::XML::Node *repr = SP_OBJECT(item)->repr; + + /** \todo + * FIXME: remove this. We don't want to edit paths inside flowtext. + * Instead we will build our flowtext with cloned paths, so that the + * real paths are outside the flowtext and thus editable as usual. + */ + if (SP_IS_FLOWTEXT(item)) { + for (SPObject *child = sp_object_first_child(SP_OBJECT(item)) ; child != NULL; child = SP_OBJECT_NEXT(child) ) { + if SP_IS_FLOWREGION(child) { + SPObject *grandchild = sp_object_first_child(SP_OBJECT(child)); + if (grandchild && SP_IS_PATH(grandchild)) { + item = SP_ITEM(grandchild); + break; + } + } + } + } + + if (!SP_IS_PATH(item)) + return NULL; + SPPath *path = SP_PATH(item); + SPCurve *curve = sp_shape_get_curve(SP_SHAPE(path)); + if (curve == NULL) + return NULL; + + NArtBpath *bpath = sp_curve_first_bpath(curve); + gint length = curve->end; + if (length == 0) + return NULL; // prevent crash for one-node paths + + gchar const *nodetypes = repr->attribute("sodipodi:nodetypes"); + gchar *typestr = parse_nodetypes(nodetypes, length); + + //Create new nodepath + Inkscape::NodePath::Path *np = g_new(Inkscape::NodePath::Path, 1); + if (!np) + return NULL; + + // Set defaults + np->desktop = desktop; + np->path = path; + np->subpaths = NULL; + np->selected = NULL; + np->nodeContext = NULL; //Let the context that makes this set it + + // we need to update item's transform from the repr here, + // because they may be out of sync when we respond + // to a change in repr by regenerating nodepath --bb + sp_object_read_attr(SP_OBJECT(item), "transform"); + + np->i2d = sp_item_i2d_affine(SP_ITEM(path)); + np->d2i = np->i2d.inverse(); + np->repr = repr; + + /* Now the bitchy part (lauris) */ + + NArtBpath *b = bpath; + + while (b->code != NR_END) { + b = subpath_from_bpath(np, b, typestr + (b - bpath)); + } + + g_free(typestr); + sp_curve_unref(curve); + + return np; +} + +/** + * Destroys nodepath's subpaths, then itself, also tell context about it. + */ +void sp_nodepath_destroy(Inkscape::NodePath::Path *np) { + + if (!np) //soft fail, like delete + return; + + while (np->subpaths) { + sp_nodepath_subpath_destroy((Inkscape::NodePath::SubPath *) np->subpaths->data); + } + + //Inform the context that made me, if any, that I am gone. + if (np->nodeContext) + np->nodeContext->nodepath = NULL; + + g_assert(!np->selected); + + np->desktop = NULL; + + g_free(np); +} + + +/** + * Return the node count of a given NodeSubPath. + */ +static gint sp_nodepath_subpath_get_node_count(Inkscape::NodePath::SubPath *subpath) +{ + if (!subpath) + return 0; + gint nodeCount = g_list_length(subpath->nodes); + return nodeCount; +} + +/** + * Return the node count of a given NodePath. + */ +static gint sp_nodepath_get_node_count(Inkscape::NodePath::Path *np) +{ + if (!np) + return 0; + gint nodeCount = 0; + for (GList *item = np->subpaths ; item ; item=item->next) { + Inkscape::NodePath::SubPath *subpath = (Inkscape::NodePath::SubPath *)item->data; + nodeCount += g_list_length(subpath->nodes); + } + return nodeCount; +} + + +/** + * Clean up a nodepath after editing. + * + * Currently we are deleting trivial subpaths. + */ +static void sp_nodepath_cleanup(Inkscape::NodePath::Path *nodepath) +{ + GList *badSubPaths = NULL; + + //Check all subpaths to be >=2 nodes + for (GList *l = nodepath->subpaths; l ; l=l->next) { + Inkscape::NodePath::SubPath *sp = (Inkscape::NodePath::SubPath *)l->data; + if (sp_nodepath_subpath_get_node_count(sp)<2) + badSubPaths = g_list_append(badSubPaths, sp); + } + + //Delete them. This second step is because sp_nodepath_subpath_destroy() + //also removes the subpath from nodepath->subpaths + for (GList *l = badSubPaths; l ; l=l->next) { + Inkscape::NodePath::SubPath *sp = (Inkscape::NodePath::SubPath *)l->data; + sp_nodepath_subpath_destroy(sp); + } + + g_list_free(badSubPaths); +} + + + +/** + * \brief Returns true if the argument nodepath and the d attribute in + * its repr do not match. + * + * This may happen if repr was changed in, e.g., XML editor or by undo. + * + * \todo + * UGLY HACK, think how we can eliminate it. + */ +gboolean nodepath_repr_d_changed(Inkscape::NodePath::Path *np, char const *newd) +{ + g_assert(np); + + SPCurve *curve = create_curve(np); + + gchar *svgpath = sp_svg_write_path(curve->bpath); + + char const *attr_d = ( newd + ? newd + : SP_OBJECT(np->path)->repr->attribute("d") ); + + gboolean ret; + if (attr_d && svgpath) + ret = strcmp(attr_d, svgpath); + else + ret = TRUE; + + g_free(svgpath); + sp_curve_unref(curve); + + return ret; +} + +/** + * \brief Returns true if the argument nodepath and the sodipodi:nodetypes + * attribute in its repr do not match. + * + * This may happen if repr was changed in, e.g., the XML editor or by undo. + */ +gboolean nodepath_repr_typestr_changed(Inkscape::NodePath::Path *np, char const *newtypestr) +{ + g_assert(np); + gchar *typestr = create_typestr(np); + char const *attr_typestr = ( newtypestr + ? newtypestr + : SP_OBJECT(np->path)->repr->attribute("sodipodi:nodetypes") ); + gboolean const ret = (attr_typestr && strcmp(attr_typestr, typestr)); + + g_free(typestr); + + return ret; +} + +/** + * Create new nodepath from b, make it subpath of np. + * \param t The node type. + * \todo Fixme: t should be a proper type, rather than gchar + */ +static NArtBpath *subpath_from_bpath(Inkscape::NodePath::Path *np, NArtBpath *b, gchar const *t) +{ + NR::Point ppos, pos, npos; + + g_assert((b->code == NR_MOVETO) || (b->code == NR_MOVETO_OPEN)); + + Inkscape::NodePath::SubPath *sp = sp_nodepath_subpath_new(np); + bool const closed = (b->code == NR_MOVETO); + + pos = NR::Point(b->x3, b->y3) * np->i2d; + if (b[1].code == NR_CURVETO) { + npos = NR::Point(b[1].x1, b[1].y1) * np->i2d; + } else { + npos = pos; + } + Inkscape::NodePath::Node *n; + n = sp_nodepath_node_new(sp, NULL, (Inkscape::NodePath::NodeType) *t, NR_MOVETO, &pos, &pos, &npos); + g_assert(sp->first == n); + g_assert(sp->last == n); + + b++; + t++; + while ((b->code == NR_CURVETO) || (b->code == NR_LINETO)) { + pos = NR::Point(b->x3, b->y3) * np->i2d; + if (b->code == NR_CURVETO) { + ppos = NR::Point(b->x2, b->y2) * np->i2d; + } else { + ppos = pos; + } + if (b[1].code == NR_CURVETO) { + npos = NR::Point(b[1].x1, b[1].y1) * np->i2d; + } else { + npos = pos; + } + n = sp_nodepath_node_new(sp, NULL, (Inkscape::NodePath::NodeType)*t, b->code, &ppos, &pos, &npos); + b++; + t++; + } + + if (closed) sp_nodepath_subpath_close(sp); + + return b; +} + +/** + * Convert from sodipodi:nodetypes to new style type string. + */ +static gchar *parse_nodetypes(gchar const *types, gint length) +{ + g_assert(length > 0); + + gchar *typestr = g_new(gchar, length + 1); + + gint pos = 0; + + if (types) { + for (gint i = 0; types[i] && ( i < length ); i++) { + while ((types[i] > '\0') && (types[i] <= ' ')) i++; + if (types[i] != '\0') { + switch (types[i]) { + case 's': + typestr[pos++] =Inkscape::NodePath::NODE_SMOOTH; + break; + case 'z': + typestr[pos++] =Inkscape::NodePath::NODE_SYMM; + break; + case 'c': + typestr[pos++] =Inkscape::NodePath::NODE_CUSP; + break; + default: + typestr[pos++] =Inkscape::NodePath::NODE_NONE; + break; + } + } + } + } + + while (pos < length) typestr[pos++] =Inkscape::NodePath::NODE_NONE; + + return typestr; +} + +/** + * Make curve out of path and associate it with it. + */ +static void update_object(Inkscape::NodePath::Path *np) +{ + g_assert(np); + + SPCurve *curve = create_curve(np); + + sp_shape_set_curve(SP_SHAPE(np->path), curve, TRUE); + + sp_curve_unref(curve); +} + +/** + * Update XML path node with data from path object. + */ +static void update_repr_internal(Inkscape::NodePath::Path *np) +{ + g_assert(np); + + Inkscape::XML::Node *repr = SP_OBJECT(np->path)->repr; + + SPCurve *curve = create_curve(np); + gchar *typestr = create_typestr(np); + gchar *svgpath = sp_svg_write_path(curve->bpath); + + repr->setAttribute("d", svgpath); + repr->setAttribute("sodipodi:nodetypes", typestr); + + g_free(svgpath); + g_free(typestr); + sp_curve_unref(curve); +} + +/** + * Update XML path node with data from path object, commit changes forever. + */ +static void update_repr(Inkscape::NodePath::Path *np) +{ + update_repr_internal(np); + sp_document_done(SP_DT_DOCUMENT(np->desktop)); +} + +/** + * Update XML path node with data from path object, commit changes with undo. + */ +static void update_repr_keyed(Inkscape::NodePath::Path *np, gchar const *key) +{ + update_repr_internal(np); + sp_document_maybe_done(SP_DT_DOCUMENT(np->desktop), key); +} + +/** + * Make duplicate of path, replace corresponding XML node in tree, commit. + */ +static void stamp_repr(Inkscape::NodePath::Path *np) +{ + g_assert(np); + + Inkscape::XML::Node *old_repr = SP_OBJECT(np->path)->repr; + Inkscape::XML::Node *new_repr = old_repr->duplicate(); + + // remember the position of the item + gint pos = old_repr->position(); + // remember parent + Inkscape::XML::Node *parent = sp_repr_parent(old_repr); + + SPCurve *curve = create_curve(np); + gchar *typestr = create_typestr(np); + + gchar *svgpath = sp_svg_write_path(curve->bpath); + + new_repr->setAttribute("d", svgpath); + new_repr->setAttribute("sodipodi:nodetypes", typestr); + + // add the new repr to the parent + parent->appendChild(new_repr); + // move to the saved position + new_repr->setPosition(pos > 0 ? pos : 0); + + sp_document_done(SP_DT_DOCUMENT(np->desktop)); + + Inkscape::GC::release(new_repr); + g_free(svgpath); + g_free(typestr); + sp_curve_unref(curve); +} + +/** + * Create curve from path. + */ +static SPCurve *create_curve(Inkscape::NodePath::Path *np) +{ + SPCurve *curve = sp_curve_new(); + + for (GList *spl = np->subpaths; spl != NULL; spl = spl->next) { + Inkscape::NodePath::SubPath *sp = (Inkscape::NodePath::SubPath *) spl->data; + sp_curve_moveto(curve, + sp->first->pos * np->d2i); + Inkscape::NodePath::Node *n = sp->first->n.other; + while (n) { + NR::Point const end_pt = n->pos * np->d2i; + switch (n->code) { + case NR_LINETO: + sp_curve_lineto(curve, end_pt); + break; + case NR_CURVETO: + sp_curve_curveto(curve, + n->p.other->n.pos * np->d2i, + n->p.pos * np->d2i, + end_pt); + break; + default: + g_assert_not_reached(); + break; + } + if (n != sp->last) { + n = n->n.other; + } else { + n = NULL; + } + } + if (sp->closed) { + sp_curve_closepath(curve); + } + } + + return curve; +} + +/** + * Convert path type string to sodipodi:nodetypes style. + */ +static gchar *create_typestr(Inkscape::NodePath::Path *np) +{ + gchar *typestr = g_new(gchar, 32); + gint len = 32; + gint pos = 0; + + for (GList *spl = np->subpaths; spl != NULL; spl = spl->next) { + Inkscape::NodePath::SubPath *sp = (Inkscape::NodePath::SubPath *) spl->data; + + if (pos >= len) { + typestr = g_renew(gchar, typestr, len + 32); + len += 32; + } + + typestr[pos++] = 'c'; + + Inkscape::NodePath::Node *n; + n = sp->first->n.other; + while (n) { + gchar code; + + switch (n->type) { + case Inkscape::NodePath::NODE_CUSP: + code = 'c'; + break; + case Inkscape::NodePath::NODE_SMOOTH: + code = 's'; + break; + case Inkscape::NodePath::NODE_SYMM: + code = 'z'; + break; + default: + g_assert_not_reached(); + code = '\0'; + break; + } + + if (pos >= len) { + typestr = g_renew(gchar, typestr, len + 32); + len += 32; + } + + typestr[pos++] = code; + + if (n != sp->last) { + n = n->n.other; + } else { + n = NULL; + } + } + } + + if (pos >= len) { + typestr = g_renew(gchar, typestr, len + 1); + len += 1; + } + + typestr[pos++] = '\0'; + + return typestr; +} + +/** + * Returns current path in context. + */ +static Inkscape::NodePath::Path *sp_nodepath_current() +{ + if (!SP_ACTIVE_DESKTOP) { + return NULL; + } + + SPEventContext *event_context = (SP_ACTIVE_DESKTOP)->event_context; + + if (!SP_IS_NODE_CONTEXT(event_context)) { + return NULL; + } + + return SP_NODE_CONTEXT(event_context)->nodepath; +} + + + +/** + \brief Fills node and control positions for three nodes, splitting line + marked by end at distance t. + */ +static void sp_nodepath_line_midpoint(Inkscape::NodePath::Node *new_path,Inkscape::NodePath::Node *end, gdouble t) +{ + g_assert(new_path != NULL); + g_assert(end != NULL); + + g_assert(end->p.other == new_path); + Inkscape::NodePath::Node *start = new_path->p.other; + g_assert(start); + + if (end->code == NR_LINETO) { + new_path->type =Inkscape::NodePath::NODE_CUSP; + new_path->code = NR_LINETO; + new_path->pos = (t * start->pos + (1 - t) * end->pos); + } else { + new_path->type =Inkscape::NodePath::NODE_SMOOTH; + new_path->code = NR_CURVETO; + gdouble s = 1 - t; + for (int dim = 0; dim < 2; dim++) { + NR::Coord const f000 = start->pos[dim]; + NR::Coord const f001 = start->n.pos[dim]; + NR::Coord const f011 = end->p.pos[dim]; + NR::Coord const f111 = end->pos[dim]; + NR::Coord const f00t = s * f000 + t * f001; + NR::Coord const f01t = s * f001 + t * f011; + NR::Coord const f11t = s * f011 + t * f111; + NR::Coord const f0tt = s * f00t + t * f01t; + NR::Coord const f1tt = s * f01t + t * f11t; + NR::Coord const fttt = s * f0tt + t * f1tt; + start->n.pos[dim] = f00t; + new_path->p.pos[dim] = f0tt; + new_path->pos[dim] = fttt; + new_path->n.pos[dim] = f1tt; + end->p.pos[dim] = f11t; + } + } +} + +/** + * Adds new node on direct line between two nodes, activates handles of all + * three nodes. + */ +static Inkscape::NodePath::Node *sp_nodepath_line_add_node(Inkscape::NodePath::Node *end, gdouble t) +{ + g_assert(end); + g_assert(end->subpath); + g_assert(g_list_find(end->subpath->nodes, end)); + + Inkscape::NodePath::Node *start = end->p.other; + g_assert( start->n.other == end ); + Inkscape::NodePath::Node *newnode = sp_nodepath_node_new(end->subpath, + end, + Inkscape::NodePath::NODE_SMOOTH, + (NRPathcode)end->code, + &start->pos, &start->pos, &start->n.pos); + sp_nodepath_line_midpoint(newnode, end, t); + + sp_node_ensure_ctrls(start); + sp_node_ensure_ctrls(newnode); + sp_node_ensure_ctrls(end); + + return newnode; +} + +/** +\brief Break the path at the node: duplicate the argument node, start a new subpath with the duplicate, and copy all nodes after the argument node to it +*/ +static Inkscape::NodePath::Node *sp_nodepath_node_break(Inkscape::NodePath::Node *node) +{ + g_assert(node); + g_assert(node->subpath); + g_assert(g_list_find(node->subpath->nodes, node)); + + Inkscape::NodePath::SubPath *sp = node->subpath; + Inkscape::NodePath::Path *np = sp->nodepath; + + if (sp->closed) { + sp_nodepath_subpath_open(sp, node); + return sp->first; + } else { + // no break for end nodes + if (node == sp->first) return NULL; + if (node == sp->last ) return NULL; + + // create a new subpath + Inkscape::NodePath::SubPath *newsubpath = sp_nodepath_subpath_new(np); + + // duplicate the break node as start of the new subpath + Inkscape::NodePath::Node *newnode = sp_nodepath_node_new(newsubpath, NULL, (Inkscape::NodePath::NodeType)node->type, NR_MOVETO, &node->pos, &node->pos, &node->n.pos); + + while (node->n.other) { // copy the remaining nodes into the new subpath + Inkscape::NodePath::Node *n = node->n.other; + Inkscape::NodePath::Node *nn = sp_nodepath_node_new(newsubpath, NULL, (Inkscape::NodePath::NodeType)n->type, (NRPathcode)n->code, &n->p.pos, &n->pos, &n->n.pos); + if (n->selected) { + sp_nodepath_node_select(nn, TRUE, TRUE); //preserve selection + } + sp_nodepath_node_destroy(n); // remove the point on the original subpath + } + + return newnode; + } +} + +/** + * Duplicate node and connect to neighbours. + */ +static Inkscape::NodePath::Node *sp_nodepath_node_duplicate(Inkscape::NodePath::Node *node) +{ + g_assert(node); + g_assert(node->subpath); + g_assert(g_list_find(node->subpath->nodes, node)); + + Inkscape::NodePath::SubPath *sp = node->subpath; + + NRPathcode code = (NRPathcode) node->code; + if (code == NR_MOVETO) { // if node is the endnode, + node->code = NR_LINETO; // new one is inserted before it, so change that to line + } + + Inkscape::NodePath::Node *newnode = sp_nodepath_node_new(sp, node, (Inkscape::NodePath::NodeType)node->type, code, &node->p.pos, &node->pos, &node->n.pos); + + if (!node->n.other || !node->p.other) // if node is an endnode, select it + return node; + else + return newnode; // otherwise select the newly created node +} + +static void sp_node_control_mirror_n_to_p(Inkscape::NodePath::Node *node) +{ + node->p.pos = (node->pos + (node->pos - node->n.pos)); +} + +static void sp_node_control_mirror_p_to_n(Inkscape::NodePath::Node *node) +{ + node->n.pos = (node->pos + (node->pos - node->p.pos)); +} + +/** + * Change line type at node, with side effects on neighbours. + */ +static void sp_nodepath_set_line_type(Inkscape::NodePath::Node *end, NRPathcode code) +{ + g_assert(end); + g_assert(end->subpath); + g_assert(end->p.other); + + if (end->code == static_cast< guint > ( code ) ) + return; + + Inkscape::NodePath::Node *start = end->p.other; + + end->code = code; + + if (code == NR_LINETO) { + if (start->code == NR_LINETO) start->type =Inkscape::NodePath::NODE_CUSP; + if (end->n.other) { + if (end->n.other->code == NR_LINETO) end->type =Inkscape::NodePath::NODE_CUSP; + } + sp_node_adjust_knot(start, -1); + sp_node_adjust_knot(end, 1); + } else { + NR::Point delta = end->pos - start->pos; + start->n.pos = start->pos + delta / 3; + end->p.pos = end->pos - delta / 3; + sp_node_adjust_knot(start, 1); + sp_node_adjust_knot(end, -1); + } + + sp_node_ensure_ctrls(start); + sp_node_ensure_ctrls(end); +} + +/** + * Change node type, and its handles accordingly. + */ +static Inkscape::NodePath::Node *sp_nodepath_set_node_type(Inkscape::NodePath::Node *node,Inkscape::NodePath::NodeType type) +{ + g_assert(node); + g_assert(node->subpath); + + if (type == static_cast(static_cast< guint >(node->type) ) ) + return node; + + if ((node->p.other != NULL) && (node->n.other != NULL)) { + if ((node->code == NR_LINETO) && (node->n.other->code == NR_LINETO)) { + type =Inkscape::NodePath::NODE_CUSP; + } + } + + node->type = type; + + if (node->type == Inkscape::NodePath::NODE_CUSP) { + g_object_set(G_OBJECT(node->knot), "shape", SP_KNOT_SHAPE_DIAMOND, "size", 9, NULL); + } else { + g_object_set(G_OBJECT(node->knot), "shape", SP_KNOT_SHAPE_SQUARE, "size", 7, NULL); + } + + sp_node_adjust_knots(node); + + sp_nodepath_update_statusbar(node->subpath->nodepath); + + return node; +} + +/** + * Same as sp_nodepath_set_node_type(), but also converts, if necessary, + * adjacent segments from lines to curves. +*/ +void sp_nodepath_convert_node_type(Inkscape::NodePath::Node *node, Inkscape::NodePath::NodeType type) +{ + if (type == Inkscape::NodePath::NODE_SYMM || type == Inkscape::NodePath::NODE_SMOOTH) { + if ((node->p.other != NULL) && (node->code == NR_LINETO || node->pos == node->p.pos)) { + // convert adjacent segment BEFORE to curve + node->code = NR_CURVETO; + NR::Point delta; + if (node->n.other != NULL) + delta = node->n.other->pos - node->p.other->pos; + else + delta = node->pos - node->p.other->pos; + node->p.pos = node->pos - delta / 4; + sp_node_ensure_ctrls(node); + } + + if ((node->n.other != NULL) && (node->n.other->code == NR_LINETO || node->pos == node->n.pos)) { + // convert adjacent segment AFTER to curve + node->n.other->code = NR_CURVETO; + NR::Point delta; + if (node->p.other != NULL) + delta = node->p.other->pos - node->n.other->pos; + else + delta = node->pos - node->n.other->pos; + node->n.pos = node->pos - delta / 4; + sp_node_ensure_ctrls(node); + } + } + + sp_nodepath_set_node_type (node, type); +} + +/** + * Move node to point, and adjust its and neighbouring handles. + */ +void sp_node_moveto(Inkscape::NodePath::Node *node, NR::Point p) +{ + NR::Point delta = p - node->pos; + node->pos = p; + + node->p.pos += delta; + node->n.pos += delta; + + if (node->p.other) { + if (node->code == NR_LINETO) { + sp_node_adjust_knot(node, 1); + sp_node_adjust_knot(node->p.other, -1); + } + } + if (node->n.other) { + if (node->n.other->code == NR_LINETO) { + sp_node_adjust_knot(node, -1); + sp_node_adjust_knot(node->n.other, 1); + } + } + + sp_node_ensure_ctrls(node); +} + +/** + * Call sp_node_moveto() for node selection and handle possible snapping. + */ +static void sp_nodepath_selected_nodes_move(Inkscape::NodePath::Path *nodepath, NR::Coord dx, NR::Coord dy, + bool const snap = true) +{ + NR::Coord best[2] = { NR_HUGE, NR_HUGE }; + NR::Point delta(dx, dy); + NR::Point best_pt = delta; + + if (snap) { + for (GList *l = nodepath->selected; l != NULL; l = l->next) { + Inkscape::NodePath::Node *n = (Inkscape::NodePath::Node *) l->data; + NR::Point p = n->pos + delta; + for (int dim = 0; dim < 2; dim++) { + NR::Coord dist = namedview_dim_snap(nodepath->desktop->namedview, + Inkscape::Snapper::SNAP_POINT, p, + NR::Dim2(dim), nodepath->path); + if (dist < best[dim]) { + best[dim] = dist; + best_pt[dim] = p[dim] - n->pos[dim]; + } + } + } + } + + for (GList *l = nodepath->selected; l != NULL; l = l->next) { + Inkscape::NodePath::Node *n = (Inkscape::NodePath::Node *) l->data; + sp_node_moveto(n, n->pos + best_pt); + } + + update_object(nodepath); +} + +/** + * Move node selection to point, adjust its and neighbouring handles, + * handle possible snapping, and commit the change with possible undo. + */ +void +sp_node_selected_move(gdouble dx, gdouble dy) +{ + Inkscape::NodePath::Path *nodepath = sp_nodepath_current(); + if (!nodepath) return; + + sp_nodepath_selected_nodes_move(nodepath, dx, dy, false); + + if (dx == 0) { + update_repr_keyed(nodepath, "node:move:vertical"); + } else if (dy == 0) { + update_repr_keyed(nodepath, "node:move:horizontal"); + } else { + update_repr(nodepath); + } +} + +/** + * Move node selection off screen and commit the change. + */ +void +sp_node_selected_move_screen(gdouble dx, gdouble dy) +{ + // borrowed from sp_selection_move_screen in selection-chemistry.c + // we find out the current zoom factor and divide deltas by it + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + + gdouble zoom = desktop->current_zoom(); + gdouble zdx = dx / zoom; + gdouble zdy = dy / zoom; + + Inkscape::NodePath::Path *nodepath = sp_nodepath_current(); + if (!nodepath) return; + + sp_nodepath_selected_nodes_move(nodepath, zdx, zdy, false); + + if (dx == 0) { + update_repr_keyed(nodepath, "node:move:vertical"); + } else if (dy == 0) { + update_repr_keyed(nodepath, "node:move:horizontal"); + } else { + update_repr(nodepath); + } +} + +/** + * Ensure knot on side of node is visible/invisible. + */ +static void sp_node_ensure_knot(Inkscape::NodePath::Node *node, gint which, gboolean show_knot) +{ + g_assert(node != NULL); + + Inkscape::NodePath::NodeSide *side = sp_node_get_side(node, which); + NRPathcode code = sp_node_path_code_from_side(node, side); + + show_knot = show_knot && (code == NR_CURVETO) && (NR::L2(side->pos - node->pos) > 1e-6); + + if (show_knot) { + if (!SP_KNOT_IS_VISIBLE(side->knot)) { + sp_knot_show(side->knot); + } + + sp_knot_set_position(side->knot, &side->pos, 0); + sp_canvas_item_show(side->line); + + } else { + if (SP_KNOT_IS_VISIBLE(side->knot)) { + sp_knot_hide(side->knot); + } + sp_canvas_item_hide(side->line); + } +} + +/** + * Ensure handles on node and neighbours of node are visible if selected. + */ +static void sp_node_ensure_ctrls(Inkscape::NodePath::Node *node) +{ + g_assert(node != NULL); + + if (!SP_KNOT_IS_VISIBLE(node->knot)) { + sp_knot_show(node->knot); + } + + sp_knot_set_position(node->knot, &node->pos, 0); + + gboolean show_knots = node->selected; + if (node->p.other != NULL) { + if (node->p.other->selected) show_knots = TRUE; + } + if (node->n.other != NULL) { + if (node->n.other->selected) show_knots = TRUE; + } + + sp_node_ensure_knot(node, -1, show_knots); + sp_node_ensure_knot(node, 1, show_knots); +} + +/** + * Call sp_node_ensure_ctrls() for all nodes on subpath. + */ +static void sp_nodepath_subpath_ensure_ctrls(Inkscape::NodePath::SubPath *subpath) +{ + g_assert(subpath != NULL); + + for (GList *l = subpath->nodes; l != NULL; l = l->next) { + sp_node_ensure_ctrls((Inkscape::NodePath::Node *) l->data); + } +} + +/** + * Call sp_nodepath_subpath_ensure_ctrls() for all subpaths of nodepath. + */ +static void sp_nodepath_ensure_ctrls(Inkscape::NodePath::Path *nodepath) +{ + g_assert(nodepath != NULL); + + for (GList *l = nodepath->subpaths; l != NULL; l = l->next) { + sp_nodepath_subpath_ensure_ctrls((Inkscape::NodePath::SubPath *) l->data); + } +} + +/** + * Adds all selected nodes in nodepath to list. + */ +void Inkscape::NodePath::Path::selection(std::list &l) +{ + StlConv::list(l, selected); +/// \todo this adds a copying, rework when the selection becomes a stl list +} + +/** + * Align selected nodes on the specified axis. + */ +void sp_nodepath_selected_align(Inkscape::NodePath::Path *nodepath, NR::Dim2 axis) +{ + if ( !nodepath || !nodepath->selected ) { // no nodepath, or no nodes selected + return; + } + + if ( !nodepath->selected->next ) { // only one node selected + return; + } + Inkscape::NodePath::Node *pNode = reinterpret_cast(nodepath->selected->data); + NR::Point dest(pNode->pos); + for (GList *l = nodepath->selected; l != NULL; l = l->next) { + pNode = reinterpret_cast(l->data); + if (pNode) { + dest[axis] = pNode->pos[axis]; + sp_node_moveto(pNode, dest); + } + } + if (axis == NR::X) { + update_repr_keyed(nodepath, "node:move:vertical"); + } else { + update_repr_keyed(nodepath, "node:move:horizontal"); + } +} + +/// Helper struct. +struct NodeSort +{ + Inkscape::NodePath::Node *_node; + NR::Coord _coord; + /// \todo use vectorof pointers instead of calling copy ctor + NodeSort(Inkscape::NodePath::Node *node, NR::Dim2 axis) : + _node(node), _coord(node->pos[axis]) + {} + +}; + +static bool operator<(NodeSort const &a, NodeSort const &b) +{ + return (a._coord < b._coord); +} + +/** + * Distribute selected nodes on the specified axis. + */ +void sp_nodepath_selected_distribute(Inkscape::NodePath::Path *nodepath, NR::Dim2 axis) +{ + if ( !nodepath || !nodepath->selected ) { // no nodepath, or no nodes selected + return; + } + + if ( ! (nodepath->selected->next && nodepath->selected->next->next) ) { // less than 3 nodes selected + return; + } + + Inkscape::NodePath::Node *pNode = reinterpret_cast(nodepath->selected->data); + std::vector sorted; + for (GList *l = nodepath->selected; l != NULL; l = l->next) { + pNode = reinterpret_cast(l->data); + if (pNode) { + NodeSort n(pNode, axis); + sorted.push_back(n); + //dest[axis] = pNode->pos[axis]; + //sp_node_moveto(pNode, dest); + } + } + std::sort(sorted.begin(), sorted.end()); + unsigned int len = sorted.size(); + //overall bboxes span + float dist = (sorted.back()._coord - + sorted.front()._coord); + //new distance between each bbox + float step = (dist) / (len - 1); + float pos = sorted.front()._coord; + for ( std::vector ::iterator it(sorted.begin()); + it < sorted.end(); + it ++ ) + { + NR::Point dest((*it)._node->pos); + dest[axis] = pos; + sp_node_moveto((*it)._node, dest); + pos += step; + } + + if (axis == NR::X) { + update_repr_keyed(nodepath, "node:move:horizontal"); + } else { + update_repr_keyed(nodepath, "node:move:vertical"); + } +} + + +/** + * Call sp_nodepath_line_add_node() for all selected segments. + */ +void +sp_node_selected_add_node(void) +{ + Inkscape::NodePath::Path *nodepath = sp_nodepath_current(); + if (!nodepath) { + return; + } + + GList *nl = NULL; + + for (GList *l = nodepath->selected; l != NULL; l = l->next) { + Inkscape::NodePath::Node *t = (Inkscape::NodePath::Node *) l->data; + g_assert(t->selected); + if (t->p.other && t->p.other->selected) { + nl = g_list_prepend(nl, t); + } + } + + while (nl) { + Inkscape::NodePath::Node *t = (Inkscape::NodePath::Node *) nl->data; + Inkscape::NodePath::Node *n = sp_nodepath_line_add_node(t, 0.5); + sp_nodepath_node_select(n, TRUE, FALSE); + nl = g_list_remove(nl, t); + } + + /** \todo fixme: adjust ? */ + sp_nodepath_ensure_ctrls(nodepath); + + update_repr(nodepath); + + sp_nodepath_update_statusbar(nodepath); +} + +/** + * Select segment nearest to point + */ +void +sp_nodepath_select_segment_near_point(SPItem * item, NR::Point p, bool toggle) +{ + Inkscape::NodePath::Path *nodepath = sp_nodepath_current(); + if (!nodepath) { + return; + } + + Path::cut_position position = get_nearest_position_on_Path(item, p); + + //find segment to segment + Inkscape::NodePath::Node *e = sp_nodepath_get_node_by_index(position.piece); + + gboolean force = FALSE; + if (!(e->selected && e->p.other->selected)) { + force = TRUE; + } + sp_nodepath_node_select(e, (gboolean) toggle, force); + sp_nodepath_node_select(e->p.other, TRUE, force); + + sp_nodepath_ensure_ctrls(nodepath); + + sp_nodepath_update_statusbar(nodepath); +} + +/** + * Add a node nearest to point + */ +void +sp_nodepath_add_node_near_point(SPItem * item, NR::Point p) +{ + Inkscape::NodePath::Path *nodepath = sp_nodepath_current(); + if (!nodepath) { + return; + } + + Path::cut_position position = get_nearest_position_on_Path(item, p); + + //find segment to split + Inkscape::NodePath::Node *e = sp_nodepath_get_node_by_index(position.piece); + + //don't know why but t seems to flip for lines + if (sp_node_path_code_from_side(e, sp_node_get_side(e, -1)) == NR_LINETO) { + position.t = 1.0 - position.t; + } + Inkscape::NodePath::Node *n = sp_nodepath_line_add_node(e, position.t); + sp_nodepath_node_select(n, FALSE, TRUE); + + /* fixme: adjust ? */ + sp_nodepath_ensure_ctrls(nodepath); + + update_repr(nodepath); + + sp_nodepath_update_statusbar(nodepath); +} + +/* + * Adjusts a segment so that t moves by a certain delta for dragging + * converts lines to curves + * + * method and idea borrowed from Simon Budig and the GIMP + * cf. app/vectors/gimpbezierstroke.c, gimp_bezier_stroke_point_move_relative() + */ +void +sp_nodepath_curve_drag(Inkscape::NodePath::Node * e, double t, NR::Point delta, char * key) +{ + /* feel good is an arbitrary parameter that distributes the delta between handles + * if t of the drag point is less than 1/6 distance form the endpoint only + * the corresponding hadle is adjusted. This matches the behavior in GIMP + */ + double feel_good; + if (t <= 1.0 / 6.0) + feel_good = 0; + else if (t <= 0.5) + feel_good = (pow((6 * t - 1) / 2.0, 3)) / 2; + else if (t <= 5.0 / 6.0) + feel_good = (1 - pow((6 * (1-t) - 1) / 2.0, 3)) / 2 + 0.5; + else + feel_good = 1; + + //if we're dragging a line convert it to a curve + if (sp_node_path_code_from_side(e, sp_node_get_side(e, -1))==NR_LINETO) { + sp_nodepath_set_line_type(e, NR_CURVETO); + } + + NR::Point offsetcoord0 = ((1-feel_good)/(3*t*(1-t)*(1-t))) * delta; + NR::Point offsetcoord1 = (feel_good/(3*t*t*(1-t))) * delta; + e->p.other->n.pos += offsetcoord0; + e->p.pos += offsetcoord1; + + // adjust controls of adjacent segments where necessary + sp_node_adjust_knot(e,1); + sp_node_adjust_knot(e->p.other,-1); + + sp_nodepath_ensure_ctrls(e->subpath->nodepath); + + update_repr_keyed(e->subpath->nodepath, key); + + sp_nodepath_update_statusbar(e->subpath->nodepath); +} + + +/** + * Call sp_nodepath_break() for all selected segments. + */ +void sp_node_selected_break() +{ + Inkscape::NodePath::Path *nodepath = sp_nodepath_current(); + if (!nodepath) return; + + GList *temp = NULL; + for (GList *l = nodepath->selected; l != NULL; l = l->next) { + Inkscape::NodePath::Node *n = (Inkscape::NodePath::Node *) l->data; + Inkscape::NodePath::Node *nn = sp_nodepath_node_break(n); + if (nn == NULL) continue; // no break, no new node + temp = g_list_prepend(temp, nn); + } + + if (temp) { + sp_nodepath_deselect(nodepath); + } + for (GList *l = temp; l != NULL; l = l->next) { + sp_nodepath_node_select((Inkscape::NodePath::Node *) l->data, TRUE, TRUE); + } + + sp_nodepath_ensure_ctrls(nodepath); + + update_repr(nodepath); +} + +/** + * Duplicate the selected node(s). + */ +void sp_node_selected_duplicate() +{ + Inkscape::NodePath::Path *nodepath = sp_nodepath_current(); + if (!nodepath) { + return; + } + + GList *temp = NULL; + for (GList *l = nodepath->selected; l != NULL; l = l->next) { + Inkscape::NodePath::Node *n = (Inkscape::NodePath::Node *) l->data; + Inkscape::NodePath::Node *nn = sp_nodepath_node_duplicate(n); + if (nn == NULL) continue; // could not duplicate + temp = g_list_prepend(temp, nn); + } + + if (temp) { + sp_nodepath_deselect(nodepath); + } + for (GList *l = temp; l != NULL; l = l->next) { + sp_nodepath_node_select((Inkscape::NodePath::Node *) l->data, TRUE, TRUE); + } + + sp_nodepath_ensure_ctrls(nodepath); + + update_repr(nodepath); +} + +/** + * Join two nodes by merging them into one. + */ +void sp_node_selected_join() +{ + Inkscape::NodePath::Path *nodepath = sp_nodepath_current(); + if (!nodepath) return; // there's no nodepath when editing rects, stars, spirals or ellipses + + if (g_list_length(nodepath->selected) != 2) { + nodepath->desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("To join, you must have two endnodes selected.")); + return; + } + + Inkscape::NodePath::Node *a = (Inkscape::NodePath::Node *) nodepath->selected->data; + Inkscape::NodePath::Node *b = (Inkscape::NodePath::Node *) nodepath->selected->next->data; + + g_assert(a != b); + g_assert(a->p.other || a->n.other); + g_assert(b->p.other || b->n.other); + + if (((a->subpath->closed) || (b->subpath->closed)) || (a->p.other && a->n.other) || (b->p.other && b->n.other)) { + nodepath->desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("To join, you must have two endnodes selected.")); + return; + } + + /* a and b are endpoints */ + + NR::Point c = (a->pos + b->pos) / 2; + + if (a->subpath == b->subpath) { + Inkscape::NodePath::SubPath *sp = a->subpath; + sp_nodepath_subpath_close(sp); + + sp_nodepath_ensure_ctrls(sp->nodepath); + + update_repr(nodepath); + + return; + } + + /* a and b are separate subpaths */ + Inkscape::NodePath::SubPath *sa = a->subpath; + Inkscape::NodePath::SubPath *sb = b->subpath; + NR::Point p; + Inkscape::NodePath::Node *n; + NRPathcode code; + if (a == sa->first) { + p = sa->first->n.pos; + code = (NRPathcode)sa->first->n.other->code; + Inkscape::NodePath::SubPath *t = sp_nodepath_subpath_new(sa->nodepath); + n = sa->last; + sp_nodepath_node_new(t, NULL,Inkscape::NodePath::NODE_CUSP, NR_MOVETO, &n->n.pos, &n->pos, &n->p.pos); + n = n->p.other; + while (n) { + sp_nodepath_node_new(t, NULL, (Inkscape::NodePath::NodeType)n->type, (NRPathcode)n->n.other->code, &n->n.pos, &n->pos, &n->p.pos); + n = n->p.other; + if (n == sa->first) n = NULL; + } + sp_nodepath_subpath_destroy(sa); + sa = t; + } else if (a == sa->last) { + p = sa->last->p.pos; + code = (NRPathcode)sa->last->code; + sp_nodepath_node_destroy(sa->last); + } else { + code = NR_END; + g_assert_not_reached(); + } + + if (b == sb->first) { + sp_nodepath_node_new(sa, NULL,Inkscape::NodePath::NODE_CUSP, code, &p, &c, &sb->first->n.pos); + for (n = sb->first->n.other; n != NULL; n = n->n.other) { + sp_nodepath_node_new(sa, NULL, (Inkscape::NodePath::NodeType)n->type, (NRPathcode)n->code, &n->p.pos, &n->pos, &n->n.pos); + } + } else if (b == sb->last) { + sp_nodepath_node_new(sa, NULL,Inkscape::NodePath::NODE_CUSP, code, &p, &c, &sb->last->p.pos); + for (n = sb->last->p.other; n != NULL; n = n->p.other) { + sp_nodepath_node_new(sa, NULL, (Inkscape::NodePath::NodeType)n->type, (NRPathcode)n->n.other->code, &n->n.pos, &n->pos, &n->p.pos); + } + } else { + g_assert_not_reached(); + } + /* and now destroy sb */ + + sp_nodepath_subpath_destroy(sb); + + sp_nodepath_ensure_ctrls(sa->nodepath); + + update_repr(nodepath); + + sp_nodepath_update_statusbar(nodepath); +} + +/** + * Join two nodes by adding a segment between them. + */ +void sp_node_selected_join_segment() +{ + Inkscape::NodePath::Path *nodepath = sp_nodepath_current(); + if (!nodepath) return; // there's no nodepath when editing rects, stars, spirals or ellipses + + if (g_list_length(nodepath->selected) != 2) { + nodepath->desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("To join, you must have two endnodes selected.")); + return; + } + + Inkscape::NodePath::Node *a = (Inkscape::NodePath::Node *) nodepath->selected->data; + Inkscape::NodePath::Node *b = (Inkscape::NodePath::Node *) nodepath->selected->next->data; + + g_assert(a != b); + g_assert(a->p.other || a->n.other); + g_assert(b->p.other || b->n.other); + + if (((a->subpath->closed) || (b->subpath->closed)) || (a->p.other && a->n.other) || (b->p.other && b->n.other)) { + nodepath->desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("To join, you must have two endnodes selected.")); + return; + } + + if (a->subpath == b->subpath) { + Inkscape::NodePath::SubPath *sp = a->subpath; + + /*similar to sp_nodepath_subpath_close(sp), without the node destruction*/ + sp->closed = TRUE; + + sp->first->p.other = sp->last; + sp->last->n.other = sp->first; + + sp_node_control_mirror_p_to_n(sp->last); + sp_node_control_mirror_n_to_p(sp->first); + + sp->first->code = sp->last->code; + sp->first = sp->last; + + sp_nodepath_ensure_ctrls(sp->nodepath); + + update_repr(nodepath); + + return; + } + + /* a and b are separate subpaths */ + Inkscape::NodePath::SubPath *sa = a->subpath; + Inkscape::NodePath::SubPath *sb = b->subpath; + + Inkscape::NodePath::Node *n; + NR::Point p; + NRPathcode code; + if (a == sa->first) { + code = (NRPathcode) sa->first->n.other->code; + Inkscape::NodePath::SubPath *t = sp_nodepath_subpath_new(sa->nodepath); + n = sa->last; + sp_nodepath_node_new(t, NULL,Inkscape::NodePath::NODE_CUSP, NR_MOVETO, &n->n.pos, &n->pos, &n->p.pos); + for (n = n->p.other; n != NULL; n = n->p.other) { + sp_nodepath_node_new(t, NULL, (Inkscape::NodePath::NodeType)n->type, (NRPathcode)n->n.other->code, &n->n.pos, &n->pos, &n->p.pos); + } + sp_nodepath_subpath_destroy(sa); + sa = t; + } else if (a == sa->last) { + code = (NRPathcode)sa->last->code; + } else { + code = NR_END; + g_assert_not_reached(); + } + + if (b == sb->first) { + n = sb->first; + sp_node_control_mirror_p_to_n(sa->last); + sp_nodepath_node_new(sa, NULL,Inkscape::NodePath::NODE_CUSP, code, &n->p.pos, &n->pos, &n->n.pos); + sp_node_control_mirror_n_to_p(sa->last); + for (n = n->n.other; n != NULL; n = n->n.other) { + sp_nodepath_node_new(sa, NULL, (Inkscape::NodePath::NodeType)n->type, (NRPathcode)n->code, &n->p.pos, &n->pos, &n->n.pos); + } + } else if (b == sb->last) { + n = sb->last; + sp_node_control_mirror_p_to_n(sa->last); + sp_nodepath_node_new(sa, NULL,Inkscape::NodePath::NODE_CUSP, code, &p, &n->pos, &n->p.pos); + sp_node_control_mirror_n_to_p(sa->last); + for (n = n->p.other; n != NULL; n = n->p.other) { + sp_nodepath_node_new(sa, NULL, (Inkscape::NodePath::NodeType)n->type, (NRPathcode)n->n.other->code, &n->n.pos, &n->pos, &n->p.pos); + } + } else { + g_assert_not_reached(); + } + /* and now destroy sb */ + + sp_nodepath_subpath_destroy(sb); + + sp_nodepath_ensure_ctrls(sa->nodepath); + + update_repr(nodepath); +} + +/** + * Delete one or more selected nodes. + */ +void sp_node_selected_delete() +{ + Inkscape::NodePath::Path *nodepath = sp_nodepath_current(); + if (!nodepath) return; + if (!nodepath->selected) return; + + /** \todo fixme: do it the right way */ + while (nodepath->selected) { + Inkscape::NodePath::Node *node = (Inkscape::NodePath::Node *) nodepath->selected->data; + sp_nodepath_node_destroy(node); + } + + + //clean up the nodepath (such as for trivial subpaths) + sp_nodepath_cleanup(nodepath); + + sp_nodepath_ensure_ctrls(nodepath); + + // if the entire nodepath is removed, delete the selected object. + if (nodepath->subpaths == NULL || + sp_nodepath_get_node_count(nodepath) < 2) { + SPDocument *document = SP_DT_DOCUMENT (nodepath->desktop); + sp_nodepath_destroy(nodepath); + sp_selection_delete(); + sp_document_done (document); + return; + } + + update_repr(nodepath); + + sp_nodepath_update_statusbar(nodepath); +} + +/** + * Delete one or more segments between two selected nodes. + * This is the code for 'split'. + */ +void +sp_node_selected_delete_segment(void) +{ + Inkscape::NodePath::Node *start, *end; //Start , end nodes. not inclusive + Inkscape::NodePath::Node *curr, *next; //Iterators + + Inkscape::NodePath::Path *nodepath = sp_nodepath_current(); + if (!nodepath) return; // there's no nodepath when editing rects, stars, spirals or ellipses + + if (g_list_length(nodepath->selected) != 2) { + nodepath->desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE, + _("Select two non-endpoint nodes on a path between which to delete segments.")); + return; + } + + //Selected nodes, not inclusive + Inkscape::NodePath::Node *a = (Inkscape::NodePath::Node *) nodepath->selected->data; + Inkscape::NodePath::Node *b = (Inkscape::NodePath::Node *) nodepath->selected->next->data; + + if ( ( a==b) || //same node + (a->subpath != b->subpath ) || //not the same path + (!a->p.other || !a->n.other) || //one of a's sides does not have a segment + (!b->p.other || !b->n.other) ) //one of b's sides does not have a segment + { + nodepath->desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE, + _("Select two non-endpoint nodes on a path between which to delete segments.")); + return; + } + + //########################################### + //# BEGIN EDITS + //########################################### + //################################## + //# CLOSED PATH + //################################## + if (a->subpath->closed) { + + + gboolean reversed = FALSE; + + //Since we can go in a circle, we need to find the shorter distance. + // a->b or b->a + start = end = NULL; + int distance = 0; + int minDistance = 0; + for (curr = a->n.other ; curr && curr!=a ; curr=curr->n.other) { + if (curr==b) { + //printf("a to b:%d\n", distance); + start = a;//go from a to b + end = b; + minDistance = distance; + //printf("A to B :\n"); + break; + } + distance++; + } + + //try again, the other direction + distance = 0; + for (curr = b->n.other ; curr && curr!=b ; curr=curr->n.other) { + if (curr==a) { + //printf("b to a:%d\n", distance); + if (distance < minDistance) { + start = b; //we go from b to a + end = a; + reversed = TRUE; + //printf("B to A\n"); + } + break; + } + distance++; + } + + + //Copy everything from 'end' to 'start' to a new subpath + Inkscape::NodePath::SubPath *t = sp_nodepath_subpath_new(nodepath); + for (curr=end ; curr ; curr=curr->n.other) { + NRPathcode code = (NRPathcode) curr->code; + if (curr == end) + code = NR_MOVETO; + sp_nodepath_node_new(t, NULL, + (Inkscape::NodePath::NodeType)curr->type, code, + &curr->p.pos, &curr->pos, &curr->n.pos); + if (curr == start) + break; + } + sp_nodepath_subpath_destroy(a->subpath); + + + } + + + + //################################## + //# OPEN PATH + //################################## + else { + + //We need to get the direction of the list between A and B + //Can we walk from a to b? + start = end = NULL; + for (curr = a->n.other ; curr && curr!=a ; curr=curr->n.other) { + if (curr==b) { + start = a; //did it! we go from a to b + end = b; + //printf("A to B\n"); + break; + } + } + if (!start) {//didn't work? let's try the other direction + for (curr = b->n.other ; curr && curr!=b ; curr=curr->n.other) { + if (curr==a) { + start = b; //did it! we go from b to a + end = a; + //printf("B to A\n"); + break; + } + } + } + if (!start) { + nodepath->desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE, + _("Cannot find path between nodes.")); + return; + } + + + + //Copy everything after 'end' to a new subpath + Inkscape::NodePath::SubPath *t = sp_nodepath_subpath_new(nodepath); + for (curr=end ; curr ; curr=curr->n.other) { + sp_nodepath_node_new(t, NULL, (Inkscape::NodePath::NodeType)curr->type, (NRPathcode)curr->code, + &curr->p.pos, &curr->pos, &curr->n.pos); + } + + //Now let us do our deletion. Since the tail has been saved, go all the way to the end of the list + for (curr = start->n.other ; curr ; curr=next) { + next = curr->n.other; + sp_nodepath_node_destroy(curr); + } + + } + //########################################### + //# END EDITS + //########################################### + + //clean up the nodepath (such as for trivial subpaths) + sp_nodepath_cleanup(nodepath); + + sp_nodepath_ensure_ctrls(nodepath); + + update_repr(nodepath); + + // if the entire nodepath is removed, delete the selected object. + if (nodepath->subpaths == NULL || + sp_nodepath_get_node_count(nodepath) < 2) { + sp_nodepath_destroy(nodepath); + sp_selection_delete(); + return; + } + + sp_nodepath_update_statusbar(nodepath); +} + +/** + * Call sp_nodepath_set_line() for all selected segments. + */ +void +sp_node_selected_set_line_type(NRPathcode code) +{ + Inkscape::NodePath::Path *nodepath = sp_nodepath_current(); + if (nodepath == NULL) return; + + for (GList *l = nodepath->selected; l != NULL; l = l->next) { + Inkscape::NodePath::Node *n = (Inkscape::NodePath::Node *) l->data; + g_assert(n->selected); + if (n->p.other && n->p.other->selected) { + sp_nodepath_set_line_type(n, code); + } + } + + update_repr(nodepath); +} + +/** + * Call sp_nodepath_convert_node_type() for all selected nodes. + */ +void +sp_node_selected_set_type(Inkscape::NodePath::NodeType type) +{ + Inkscape::NodePath::Path *nodepath = sp_nodepath_current(); + if (nodepath == NULL) return; + + for (GList *l = nodepath->selected; l != NULL; l = l->next) { + sp_nodepath_convert_node_type((Inkscape::NodePath::Node *) l->data, type); + } + + update_repr(nodepath); +} + +/** + * Change select status of node, update its own and neighbour handles. + */ +static void sp_node_set_selected(Inkscape::NodePath::Node *node, gboolean selected) +{ + node->selected = selected; + + if (selected) { + g_object_set(G_OBJECT(node->knot), + "fill", NODE_FILL_SEL, + "fill_mouseover", NODE_FILL_SEL_HI, + "stroke", NODE_STROKE_SEL, + "stroke_mouseover", NODE_STROKE_SEL_HI, + "size", (node->type == Inkscape::NodePath::NODE_CUSP) ? 11 : 9, + NULL); + } else { + g_object_set(G_OBJECT(node->knot), + "fill", NODE_FILL, + "fill_mouseover", NODE_FILL_HI, + "stroke", NODE_STROKE, + "stroke_mouseover", NODE_STROKE_HI, + "size", (node->type == Inkscape::NodePath::NODE_CUSP) ? 9 : 7, + NULL); + } + + sp_node_ensure_ctrls(node); + if (node->n.other) sp_node_ensure_ctrls(node->n.other); + if (node->p.other) sp_node_ensure_ctrls(node->p.other); +} + +/** +\brief Select a node +\param node The node to select +\param incremental If true, add to selection, otherwise deselect others +\param override If true, always select this node, otherwise toggle selected status +*/ +static void sp_nodepath_node_select(Inkscape::NodePath::Node *node, gboolean incremental, gboolean override) +{ + Inkscape::NodePath::Path *nodepath = node->subpath->nodepath; + + if (incremental) { + if (override) { + if (!g_list_find(nodepath->selected, node)) { + nodepath->selected = g_list_append(nodepath->selected, node); + } + sp_node_set_selected(node, TRUE); + } else { // toggle + if (node->selected) { + g_assert(g_list_find(nodepath->selected, node)); + nodepath->selected = g_list_remove(nodepath->selected, node); + } else { + g_assert(!g_list_find(nodepath->selected, node)); + nodepath->selected = g_list_append(nodepath->selected, node); + } + sp_node_set_selected(node, !node->selected); + } + } else { + sp_nodepath_deselect(nodepath); + nodepath->selected = g_list_append(nodepath->selected, node); + sp_node_set_selected(node, TRUE); + } + + sp_nodepath_update_statusbar(nodepath); +} + + +/** +\brief Deselect all nodes in the nodepath +*/ +void +sp_nodepath_deselect(Inkscape::NodePath::Path *nodepath) +{ + if (!nodepath) return; // there's no nodepath when editing rects, stars, spirals or ellipses + + while (nodepath->selected) { + sp_node_set_selected((Inkscape::NodePath::Node *) nodepath->selected->data, FALSE); + nodepath->selected = g_list_remove(nodepath->selected, nodepath->selected->data); + } + sp_nodepath_update_statusbar(nodepath); +} + +/** +\brief Select or invert selection of all nodes in the nodepath +*/ +void +sp_nodepath_select_all(Inkscape::NodePath::Path *nodepath, bool invert) +{ + if (!nodepath) return; + + for (GList *spl = nodepath->subpaths; spl != NULL; spl = spl->next) { + Inkscape::NodePath::SubPath *subpath = (Inkscape::NodePath::SubPath *) spl->data; + for (GList *nl = subpath->nodes; nl != NULL; nl = nl->next) { + Inkscape::NodePath::Node *node = (Inkscape::NodePath::Node *) nl->data; + sp_nodepath_node_select(node, TRUE, invert? !node->selected : TRUE); + } + } +} + +/** + * If nothing selected, does the same as sp_nodepath_select_all(); + * otherwise selects/inverts all nodes in all subpaths that have selected nodes + * (i.e., similar to "select all in layer", with the "selected" subpaths + * being treated as "layers" in the path). + */ +void +sp_nodepath_select_all_from_subpath(Inkscape::NodePath::Path *nodepath, bool invert) +{ + if (!nodepath) return; + + if (g_list_length (nodepath->selected) == 0) { + sp_nodepath_select_all (nodepath, invert); + return; + } + + GList *copy = g_list_copy (nodepath->selected); // copy initial selection so that selecting in the loop does not affect us + GSList *subpaths = NULL; + + for (GList *l = copy; l != NULL; l = l->next) { + Inkscape::NodePath::Node *n = (Inkscape::NodePath::Node *) l->data; + Inkscape::NodePath::SubPath *subpath = n->subpath; + if (!g_slist_find (subpaths, subpath)) + subpaths = g_slist_prepend (subpaths, subpath); + } + + for (GSList *sp = subpaths; sp != NULL; sp = sp->next) { + Inkscape::NodePath::SubPath *subpath = (Inkscape::NodePath::SubPath *) sp->data; + for (GList *nl = subpath->nodes; nl != NULL; nl = nl->next) { + Inkscape::NodePath::Node *node = (Inkscape::NodePath::Node *) nl->data; + sp_nodepath_node_select(node, TRUE, invert? !g_list_find(copy, node) : TRUE); + } + } + + g_slist_free (subpaths); + g_list_free (copy); +} + +/** + * \brief Select the node after the last selected; if none is selected, + * select the first within path. + */ +void sp_nodepath_select_next(Inkscape::NodePath::Path *nodepath) +{ + if (!nodepath) return; // there's no nodepath when editing rects, stars, spirals or ellipses + + Inkscape::NodePath::Node *last = NULL; + if (nodepath->selected) { + for (GList *spl = nodepath->subpaths; spl != NULL; spl = spl->next) { + Inkscape::NodePath::SubPath *subpath, *subpath_next; + subpath = (Inkscape::NodePath::SubPath *) spl->data; + for (GList *nl = subpath->nodes; nl != NULL; nl = nl->next) { + Inkscape::NodePath::Node *node = (Inkscape::NodePath::Node *) nl->data; + if (node->selected) { + if (node->n.other == (Inkscape::NodePath::Node *) subpath->last) { + if (node->n.other == (Inkscape::NodePath::Node *) subpath->first) { // closed subpath + if (spl->next) { // there's a next subpath + subpath_next = (Inkscape::NodePath::SubPath *) spl->next->data; + last = subpath_next->first; + } else if (spl->prev) { // there's a previous subpath + last = NULL; // to be set later to the first node of first subpath + } else { + last = node->n.other; + } + } else { + last = node->n.other; + } + } else { + if (node->n.other) { + last = node->n.other; + } else { + if (spl->next) { // there's a next subpath + subpath_next = (Inkscape::NodePath::SubPath *) spl->next->data; + last = subpath_next->first; + } else if (spl->prev) { // there's a previous subpath + last = NULL; // to be set later to the first node of first subpath + } else { + last = (Inkscape::NodePath::Node *) subpath->first; + } + } + } + } + } + } + sp_nodepath_deselect(nodepath); + } + + if (last) { // there's at least one more node after selected + sp_nodepath_node_select((Inkscape::NodePath::Node *) last, TRUE, TRUE); + } else { // no more nodes, select the first one in first subpath + Inkscape::NodePath::SubPath *subpath = (Inkscape::NodePath::SubPath *) nodepath->subpaths->data; + sp_nodepath_node_select((Inkscape::NodePath::Node *) subpath->first, TRUE, TRUE); + } +} + +/** + * \brief Select the node before the first selected; if none is selected, + * select the last within path + */ +void sp_nodepath_select_prev(Inkscape::NodePath::Path *nodepath) +{ + if (!nodepath) return; // there's no nodepath when editing rects, stars, spirals or ellipses + + Inkscape::NodePath::Node *last = NULL; + if (nodepath->selected) { + for (GList *spl = g_list_last(nodepath->subpaths); spl != NULL; spl = spl->prev) { + Inkscape::NodePath::SubPath *subpath = (Inkscape::NodePath::SubPath *) spl->data; + for (GList *nl = g_list_last(subpath->nodes); nl != NULL; nl = nl->prev) { + Inkscape::NodePath::Node *node = (Inkscape::NodePath::Node *) nl->data; + if (node->selected) { + if (node->p.other == (Inkscape::NodePath::Node *) subpath->first) { + if (node->p.other == (Inkscape::NodePath::Node *) subpath->last) { // closed subpath + if (spl->prev) { // there's a prev subpath + Inkscape::NodePath::SubPath *subpath_prev = (Inkscape::NodePath::SubPath *) spl->prev->data; + last = subpath_prev->last; + } else if (spl->next) { // there's a next subpath + last = NULL; // to be set later to the last node of last subpath + } else { + last = node->p.other; + } + } else { + last = node->p.other; + } + } else { + if (node->p.other) { + last = node->p.other; + } else { + if (spl->prev) { // there's a prev subpath + Inkscape::NodePath::SubPath *subpath_prev = (Inkscape::NodePath::SubPath *) spl->prev->data; + last = subpath_prev->last; + } else if (spl->next) { // there's a next subpath + last = NULL; // to be set later to the last node of last subpath + } else { + last = (Inkscape::NodePath::Node *) subpath->last; + } + } + } + } + } + } + sp_nodepath_deselect(nodepath); + } + + if (last) { // there's at least one more node before selected + sp_nodepath_node_select((Inkscape::NodePath::Node *) last, TRUE, TRUE); + } else { // no more nodes, select the last one in last subpath + GList *spl = g_list_last(nodepath->subpaths); + Inkscape::NodePath::SubPath *subpath = (Inkscape::NodePath::SubPath *) spl->data; + sp_nodepath_node_select((Inkscape::NodePath::Node *) subpath->last, TRUE, TRUE); + } +} + +/** + * \brief Select all nodes that are within the rectangle. + */ +void sp_nodepath_select_rect(Inkscape::NodePath::Path *nodepath, NR::Rect const &b, gboolean incremental) +{ + if (!incremental) { + sp_nodepath_deselect(nodepath); + } + + for (GList *spl = nodepath->subpaths; spl != NULL; spl = spl->next) { + Inkscape::NodePath::SubPath *subpath = (Inkscape::NodePath::SubPath *) spl->data; + for (GList *nl = subpath->nodes; nl != NULL; nl = nl->next) { + Inkscape::NodePath::Node *node = (Inkscape::NodePath::Node *) nl->data; + + if (b.contains(node->pos)) { + sp_nodepath_node_select(node, TRUE, TRUE); + } + } + } +} + +/** +\brief Saves selected nodes in a nodepath into a list containing integer positions of all selected nodes +*/ +GList *save_nodepath_selection(Inkscape::NodePath::Path *nodepath) +{ + if (!nodepath->selected) { + return NULL; + } + + GList *r = NULL; + guint i = 0; + for (GList *spl = nodepath->subpaths; spl != NULL; spl = spl->next) { + Inkscape::NodePath::SubPath *subpath = (Inkscape::NodePath::SubPath *) spl->data; + for (GList *nl = subpath->nodes; nl != NULL; nl = nl->next) { + Inkscape::NodePath::Node *node = (Inkscape::NodePath::Node *) nl->data; + i++; + if (node->selected) { + r = g_list_append(r, GINT_TO_POINTER(i)); + } + } + } + return r; +} + +/** +\brief Restores selection by selecting nodes whose positions are in the list +*/ +void restore_nodepath_selection(Inkscape::NodePath::Path *nodepath, GList *r) +{ + sp_nodepath_deselect(nodepath); + + guint i = 0; + for (GList *spl = nodepath->subpaths; spl != NULL; spl = spl->next) { + Inkscape::NodePath::SubPath *subpath = (Inkscape::NodePath::SubPath *) spl->data; + for (GList *nl = subpath->nodes; nl != NULL; nl = nl->next) { + Inkscape::NodePath::Node *node = (Inkscape::NodePath::Node *) nl->data; + i++; + if (g_list_find(r, GINT_TO_POINTER(i))) { + sp_nodepath_node_select(node, TRUE, TRUE); + } + } + } + +} + +/** +\brief Adjusts control point according to node type and line code. +*/ +static void sp_node_adjust_knot(Inkscape::NodePath::Node *node, gint which_adjust) +{ + double len, otherlen, linelen; + + g_assert(node); + + Inkscape::NodePath::NodeSide *me = sp_node_get_side(node, which_adjust); + Inkscape::NodePath::NodeSide *other = sp_node_opposite_side(node, me); + + /** \todo fixme: */ + if (me->other == NULL) return; + if (other->other == NULL) return; + + /* I have line */ + + NRPathcode mecode, ocode; + if (which_adjust == 1) { + mecode = (NRPathcode)me->other->code; + ocode = (NRPathcode)node->code; + } else { + mecode = (NRPathcode)node->code; + ocode = (NRPathcode)other->other->code; + } + + if (mecode == NR_LINETO) return; + + /* I am curve */ + + if (other->other == NULL) return; + + /* Other has line */ + + if (node->type == Inkscape::NodePath::NODE_CUSP) return; + + NR::Point delta; + if (ocode == NR_LINETO) { + /* other is lineto, we are either smooth or symm */ + Inkscape::NodePath::Node *othernode = other->other; + len = NR::L2(me->pos - node->pos); + delta = node->pos - othernode->pos; + linelen = NR::L2(delta); + if (linelen < 1e-18) return; + + me->pos = node->pos + (len / linelen)*delta; + sp_knot_set_position(me->knot, &me->pos, 0); + + sp_node_ensure_ctrls(node); + return; + } + + if (node->type == Inkscape::NodePath::NODE_SYMM) { + + me->pos = 2 * node->pos - other->pos; + sp_knot_set_position(me->knot, &me->pos, 0); + + sp_node_ensure_ctrls(node); + return; + } + + /* We are smooth */ + + len = NR::L2(me->pos - node->pos); + delta = other->pos - node->pos; + otherlen = NR::L2(delta); + if (otherlen < 1e-18) return; + + me->pos = node->pos - (len / otherlen) * delta; + sp_knot_set_position(me->knot, &me->pos, 0); + + sp_node_ensure_ctrls(node); +} + +/** + \brief Adjusts control point according to node type and line code + */ +static void sp_node_adjust_knots(Inkscape::NodePath::Node *node) +{ + g_assert(node); + + if (node->type == Inkscape::NodePath::NODE_CUSP) return; + + /* we are either smooth or symm */ + + if (node->p.other == NULL) return; + + if (node->n.other == NULL) return; + + if (node->code == NR_LINETO) { + if (node->n.other->code == NR_LINETO) return; + sp_node_adjust_knot(node, 1); + sp_node_ensure_ctrls(node); + return; + } + + if (node->n.other->code == NR_LINETO) { + if (node->code == NR_LINETO) return; + sp_node_adjust_knot(node, -1); + sp_node_ensure_ctrls(node); + return; + } + + /* both are curves */ + + NR::Point const delta( node->n.pos - node->p.pos ); + + if (node->type == Inkscape::NodePath::NODE_SYMM) { + node->p.pos = node->pos - delta / 2; + node->n.pos = node->pos + delta / 2; + sp_node_ensure_ctrls(node); + return; + } + + /* We are smooth */ + + double plen = NR::L2(node->p.pos - node->pos); + if (plen < 1e-18) return; + double nlen = NR::L2(node->n.pos - node->pos); + if (nlen < 1e-18) return; + node->p.pos = node->pos - (plen / (plen + nlen)) * delta; + node->n.pos = node->pos + (nlen / (plen + nlen)) * delta; + sp_node_ensure_ctrls(node); +} + +/** + * Knot events handler callback. + */ +static gboolean node_event(SPKnot *knot, GdkEvent *event,Inkscape::NodePath::Node *n) +{ + gboolean ret = FALSE; + switch (event->type) { + case GDK_ENTER_NOTIFY: + active_node = n; + break; + case GDK_LEAVE_NOTIFY: + active_node = NULL; + break; + case GDK_KEY_PRESS: + switch (get_group0_keyval (&event->key)) { + case GDK_space: + if (event->key.state & GDK_BUTTON1_MASK) { + Inkscape::NodePath::Path *nodepath = n->subpath->nodepath; + stamp_repr(nodepath); + ret = TRUE; + } + break; + default: + break; + } + break; + default: + break; + } + + return ret; +} + +/** + * Handle keypress on node; directly called. + */ +gboolean node_key(GdkEvent *event) +{ + Inkscape::NodePath::Path *np; + + // there is no way to verify nodes so set active_node to nil when deleting!! + if (active_node == NULL) return FALSE; + + if ((event->type == GDK_KEY_PRESS) && !(event->key.state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK))) { + gint ret = FALSE; + switch (get_group0_keyval (&event->key)) { + /// \todo FIXME: this does not seem to work, the keys are stolen by tool contexts! + case GDK_BackSpace: + np = active_node->subpath->nodepath; + sp_nodepath_node_destroy(active_node); + update_repr(np); + active_node = NULL; + ret = TRUE; + break; + case GDK_c: + sp_nodepath_set_node_type(active_node,Inkscape::NodePath::NODE_CUSP); + ret = TRUE; + break; + case GDK_s: + sp_nodepath_set_node_type(active_node,Inkscape::NodePath::NODE_SMOOTH); + ret = TRUE; + break; + case GDK_y: + sp_nodepath_set_node_type(active_node,Inkscape::NodePath::NODE_SYMM); + ret = TRUE; + break; + case GDK_b: + sp_nodepath_node_break(active_node); + ret = TRUE; + break; + } + return ret; + } + return FALSE; +} + +/** + * Mouseclick on node callback. + */ +static void node_clicked(SPKnot *knot, guint state, gpointer data) +{ + Inkscape::NodePath::Node *n = (Inkscape::NodePath::Node *) data; + + if (state & GDK_CONTROL_MASK) { + Inkscape::NodePath::Path *nodepath = n->subpath->nodepath; + + if (!(state & GDK_MOD1_MASK)) { // ctrl+click: toggle node type + if (n->type == Inkscape::NodePath::NODE_CUSP) { + sp_nodepath_convert_node_type (n,Inkscape::NodePath::NODE_SMOOTH); + } else if (n->type == Inkscape::NodePath::NODE_SMOOTH) { + sp_nodepath_convert_node_type (n,Inkscape::NodePath::NODE_SYMM); + } else { + sp_nodepath_convert_node_type (n,Inkscape::NodePath::NODE_CUSP); + } + update_repr(nodepath); + sp_nodepath_update_statusbar(nodepath); + + } else { //ctrl+alt+click: delete node + sp_nodepath_node_destroy(n); + //clean up the nodepath (such as for trivial subpaths) + sp_nodepath_cleanup(nodepath); + + // if the entire nodepath is removed, delete the selected object. + if (nodepath->subpaths == NULL || + sp_nodepath_get_node_count(nodepath) < 2) { + SPDocument *document = SP_DT_DOCUMENT (nodepath->desktop); + sp_nodepath_destroy(nodepath); + sp_selection_delete(); + sp_document_done (document); + + } else { + sp_nodepath_ensure_ctrls(nodepath); + update_repr(nodepath); + sp_nodepath_update_statusbar(nodepath); + } + } + + } else { + sp_nodepath_node_select(n, (state & GDK_SHIFT_MASK), FALSE); + } +} + +/** + * Mouse grabbed node callback. + */ +static void node_grabbed(SPKnot *knot, guint state, gpointer data) +{ + Inkscape::NodePath::Node *n = (Inkscape::NodePath::Node *) data; + + n->origin = knot->pos; + + if (!n->selected) { + sp_nodepath_node_select(n, (state & GDK_SHIFT_MASK), FALSE); + } +} + +/** + * Mouse ungrabbed node callback. + */ +static void node_ungrabbed(SPKnot *knot, guint state, gpointer data) +{ + Inkscape::NodePath::Node *n = (Inkscape::NodePath::Node *) data; + + n->dragging_out = NULL; + + update_repr(n->subpath->nodepath); +} + +/** + * The point on a line, given by its angle, closest to the given point. + * \param p A point. + * \param a Angle of the line; it is assumed to go through coordinate origin. + * \param closest Pointer to the point struct where the result is stored. + * \todo FIXME: use dot product perhaps? + */ +static void point_line_closest(NR::Point *p, double a, NR::Point *closest) +{ + if (a == HUGE_VAL) { // vertical + *closest = NR::Point(0, (*p)[NR::Y]); + } else { + (*closest)[NR::X] = ( a * (*p)[NR::Y] + (*p)[NR::X]) / (a*a + 1); + (*closest)[NR::Y] = a * (*closest)[NR::X]; + } +} + +/** + * Distance from the point to a line given by its angle. + * \param p A point. + * \param a Angle of the line; it is assumed to go through coordinate origin. + */ +static double point_line_distance(NR::Point *p, double a) +{ + NR::Point c; + point_line_closest(p, a, &c); + return sqrt(((*p)[NR::X] - c[NR::X])*((*p)[NR::X] - c[NR::X]) + ((*p)[NR::Y] - c[NR::Y])*((*p)[NR::Y] - c[NR::Y])); +} + +/** + * Callback for node "request" signal. + * \todo fixme: This goes to "moved" event? (lauris) + */ +static gboolean +node_request(SPKnot *knot, NR::Point *p, guint state, gpointer data) +{ + double yn, xn, yp, xp; + double an, ap, na, pa; + double d_an, d_ap, d_na, d_pa; + gboolean collinear = FALSE; + NR::Point c; + NR::Point pr; + + Inkscape::NodePath::Node *n = (Inkscape::NodePath::Node *) data; + + // If either (Shift and some handle retracted), or (we're already dragging out a handle) + if (((state & GDK_SHIFT_MASK) && ((n->n.other && n->n.pos == n->pos) || (n->p.other && n->p.pos == n->pos))) || n->dragging_out) { + + NR::Point mouse = (*p); + + if (!n->dragging_out) { + // This is the first drag-out event; find out which handle to drag out + double appr_n = (n->n.other ? NR::L2(n->n.other->pos - n->pos) - NR::L2(n->n.other->pos - (*p)) : -HUGE_VAL); + double appr_p = (n->p.other ? NR::L2(n->p.other->pos - n->pos) - NR::L2(n->p.other->pos - (*p)) : -HUGE_VAL); + + if (appr_p == -HUGE_VAL && appr_n == -HUGE_VAL) // orphan node? + return FALSE; + + Inkscape::NodePath::NodeSide *opposite; + if (appr_p > appr_n) { // closer to p + n->dragging_out = &n->p; + opposite = &n->n; + n->code = NR_CURVETO; + } else if (appr_p < appr_n) { // closer to n + n->dragging_out = &n->n; + opposite = &n->p; + n->n.other->code = NR_CURVETO; + } else { // p and n nodes are the same + if (n->n.pos != n->pos) { // n handle already dragged, drag p + n->dragging_out = &n->p; + opposite = &n->n; + n->code = NR_CURVETO; + } else if (n->p.pos != n->pos) { // p handle already dragged, drag n + n->dragging_out = &n->n; + opposite = &n->p; + n->n.other->code = NR_CURVETO; + } else { // find out to which handle of the adjacent node we're closer; note that n->n.other == n->p.other + double appr_other_n = (n->n.other ? NR::L2(n->n.other->n.pos - n->pos) - NR::L2(n->n.other->n.pos - (*p)) : -HUGE_VAL); + double appr_other_p = (n->n.other ? NR::L2(n->n.other->p.pos - n->pos) - NR::L2(n->n.other->p.pos - (*p)) : -HUGE_VAL); + if (appr_other_p > appr_other_n) { // closer to other's p handle + n->dragging_out = &n->n; + opposite = &n->p; + n->n.other->code = NR_CURVETO; + } else { // closer to other's n handle + n->dragging_out = &n->p; + opposite = &n->n; + n->code = NR_CURVETO; + } + } + } + + // if there's another handle, make sure the one we drag out starts parallel to it + if (opposite->pos != n->pos) { + mouse = n->pos - NR::L2(mouse - n->pos) * NR::unit_vector(opposite->pos - n->pos); + } + } + + // pass this on to the handle-moved callback + node_ctrl_moved(n->dragging_out->knot, &mouse, state, (gpointer) n); + sp_node_ensure_ctrls(n); + return TRUE; + } + + if (state & GDK_CONTROL_MASK) { // constrained motion + + // calculate relative distances of handles + // n handle: + yn = n->n.pos[NR::Y] - n->pos[NR::Y]; + xn = n->n.pos[NR::X] - n->pos[NR::X]; + // if there's no n handle (straight line), see if we can use the direction to the next point on path + if ((n->n.other && n->n.other->code == NR_LINETO) || fabs(yn) + fabs(xn) < 1e-6) { + if (n->n.other) { // if there is the next point + if (L2(n->n.other->p.pos - n->n.other->pos) < 1e-6) // and the next point has no handle either + yn = n->n.other->pos[NR::Y] - n->origin[NR::Y]; // use origin because otherwise the direction will change as you drag + xn = n->n.other->pos[NR::X] - n->origin[NR::X]; + } + } + if (xn < 0) { xn = -xn; yn = -yn; } // limit the angle to between 0 and pi + if (yn < 0) { xn = -xn; yn = -yn; } + + // p handle: + yp = n->p.pos[NR::Y] - n->pos[NR::Y]; + xp = n->p.pos[NR::X] - n->pos[NR::X]; + // if there's no p handle (straight line), see if we can use the direction to the prev point on path + if (n->code == NR_LINETO || fabs(yp) + fabs(xp) < 1e-6) { + if (n->p.other) { + if (L2(n->p.other->n.pos - n->p.other->pos) < 1e-6) + yp = n->p.other->pos[NR::Y] - n->origin[NR::Y]; + xp = n->p.other->pos[NR::X] - n->origin[NR::X]; + } + } + if (xp < 0) { xp = -xp; yp = -yp; } // limit the angle to between 0 and pi + if (yp < 0) { xp = -xp; yp = -yp; } + + if (state & GDK_MOD1_MASK && !(xn == 0 && xp == 0)) { + // sliding on handles, only if at least one of the handles is non-vertical + // (otherwise it's the same as ctrl+drag anyway) + + // calculate angles of the control handles + if (xn == 0) { + if (yn == 0) { // no handle, consider it the continuation of the other one + an = 0; + collinear = TRUE; + } + else an = 0; // vertical; set the angle to horizontal + } else an = yn/xn; + + if (xp == 0) { + if (yp == 0) { // no handle, consider it the continuation of the other one + ap = an; + } + else ap = 0; // vertical; set the angle to horizontal + } else ap = yp/xp; + + if (collinear) an = ap; + + // angles of the perpendiculars; HUGE_VAL means vertical + if (an == 0) na = HUGE_VAL; else na = -1/an; + if (ap == 0) pa = HUGE_VAL; else pa = -1/ap; + + //g_print("an %g ap %g\n", an, ap); + + // mouse point relative to the node's original pos + pr = (*p) - n->origin; + + // distances to the four lines (two handles and two perpendiculars) + d_an = point_line_distance(&pr, an); + d_na = point_line_distance(&pr, na); + d_ap = point_line_distance(&pr, ap); + d_pa = point_line_distance(&pr, pa); + + // find out which line is the closest, save its closest point in c + if (d_an <= d_na && d_an <= d_ap && d_an <= d_pa) { + point_line_closest(&pr, an, &c); + } else if (d_ap <= d_an && d_ap <= d_na && d_ap <= d_pa) { + point_line_closest(&pr, ap, &c); + } else if (d_na <= d_an && d_na <= d_ap && d_na <= d_pa) { + point_line_closest(&pr, na, &c); + } else if (d_pa <= d_an && d_pa <= d_ap && d_pa <= d_na) { + point_line_closest(&pr, pa, &c); + } + + // move the node to the closest point + sp_nodepath_selected_nodes_move(n->subpath->nodepath, + n->origin[NR::X] + c[NR::X] - n->pos[NR::X], + n->origin[NR::Y] + c[NR::Y] - n->pos[NR::Y]); + + } else { // constraining to hor/vert + + if (fabs((*p)[NR::X] - n->origin[NR::X]) > fabs((*p)[NR::Y] - n->origin[NR::Y])) { // snap to hor + sp_nodepath_selected_nodes_move(n->subpath->nodepath, (*p)[NR::X] - n->pos[NR::X], n->origin[NR::Y] - n->pos[NR::Y]); + } else { // snap to vert + sp_nodepath_selected_nodes_move(n->subpath->nodepath, n->origin[NR::X] - n->pos[NR::X], (*p)[NR::Y] - n->pos[NR::Y]); + } + } + } else { // move freely + sp_nodepath_selected_nodes_move(n->subpath->nodepath, + (*p)[NR::X] - n->pos[NR::X], + (*p)[NR::Y] - n->pos[NR::Y], + (state & GDK_SHIFT_MASK) == 0); + } + + n->subpath->nodepath->desktop->scroll_to_point(p); + + return TRUE; +} + +/** + * Node handle clicked callback. + */ +static void node_ctrl_clicked(SPKnot *knot, guint state, gpointer data) +{ + Inkscape::NodePath::Node *n = (Inkscape::NodePath::Node *) data; + + if (state & GDK_CONTROL_MASK) { // "delete" handle + if (n->p.knot == knot) { + n->p.pos = n->pos; + } else if (n->n.knot == knot) { + n->n.pos = n->pos; + } + sp_node_ensure_ctrls(n); + Inkscape::NodePath::Path *nodepath = n->subpath->nodepath; + update_repr(nodepath); + sp_nodepath_update_statusbar(nodepath); + + } else { // just select or add to selection, depending in Shift + sp_nodepath_node_select(n, (state & GDK_SHIFT_MASK), FALSE); + } +} + +/** + * Node handle grabbed callback. + */ +static void node_ctrl_grabbed(SPKnot *knot, guint state, gpointer data) +{ + Inkscape::NodePath::Node *n = (Inkscape::NodePath::Node *) data; + + if (!n->selected) { + sp_nodepath_node_select(n, (state & GDK_SHIFT_MASK), FALSE); + } + + // remember the origin of the control + if (n->p.knot == knot) { + n->p.origin = n->p.pos - n->pos; + } else if (n->n.knot == knot) { + n->n.origin = n->n.pos - n->pos; + } else { + g_assert_not_reached(); + } + +} + +/** + * Node handle ungrabbed callback. + */ +static void node_ctrl_ungrabbed(SPKnot *knot, guint state, gpointer data) +{ + Inkscape::NodePath::Node *n = (Inkscape::NodePath::Node *) data; + + // forget origin and set knot position once more (because it can be wrong now due to restrictions) + if (n->p.knot == knot) { + n->p.origin.a = 0; + sp_knot_set_position(knot, &n->p.pos, state); + } else if (n->n.knot == knot) { + n->n.origin.a = 0; + sp_knot_set_position(knot, &n->n.pos, state); + } else { + g_assert_not_reached(); + } + + update_repr(n->subpath->nodepath); +} + +/** + * Node handle "request" signal callback. + */ +static gboolean node_ctrl_request(SPKnot *knot, NR::Point *p, guint state, gpointer data) +{ + Inkscape::NodePath::Node *n = (Inkscape::NodePath::Node *) data; + + Inkscape::NodePath::NodeSide *me, *opposite; + gint which; + if (n->p.knot == knot) { + me = &n->p; + opposite = &n->n; + which = -1; + } else if (n->n.knot == knot) { + me = &n->n; + opposite = &n->p; + which = 1; + } else { + me = opposite = NULL; + which = 0; + g_assert_not_reached(); + } + + NRPathcode const othercode = sp_node_path_code_from_side(n, opposite); + + SnapManager const m(n->subpath->nodepath->desktop->namedview); + + if (opposite->other && (n->type != Inkscape::NodePath::NODE_CUSP) && (othercode == NR_LINETO)) { + /* We are smooth node adjacent with line */ + NR::Point const delta = *p - n->pos; + NR::Coord const len = NR::L2(delta); + Inkscape::NodePath::Node *othernode = opposite->other; + NR::Point const ndelta = n->pos - othernode->pos; + NR::Coord const linelen = NR::L2(ndelta); + if (len > NR_EPSILON && linelen > NR_EPSILON) { + NR::Coord const scal = dot(delta, ndelta) / linelen; + (*p) = n->pos + (scal / linelen) * ndelta; + } + *p = m.constrainedSnap(Inkscape::Snapper::SNAP_POINT, *p, ndelta, NULL).getPoint(); + } else { + *p = m.freeSnap(Inkscape::Snapper::SNAP_POINT, *p, NULL).getPoint(); + } + + sp_node_adjust_knot(n, -which); + + return FALSE; +} + +/** + * Node handle moved callback. + */ +static void node_ctrl_moved(SPKnot *knot, NR::Point *p, guint state, gpointer data) +{ + Inkscape::NodePath::Node *n = (Inkscape::NodePath::Node *) data; + + Inkscape::NodePath::NodeSide *me; + Inkscape::NodePath::NodeSide *other; + if (n->p.knot == knot) { + me = &n->p; + other = &n->n; + } else if (n->n.knot == knot) { + me = &n->n; + other = &n->p; + } else { + me = NULL; + other = NULL; + g_assert_not_reached(); + } + + // calculate radial coordinates of the grabbed control, other control, and the mouse point + Radial rme(me->pos - n->pos); + Radial rother(other->pos - n->pos); + Radial rnew(*p - n->pos); + + if (state & GDK_CONTROL_MASK && rnew.a != HUGE_VAL) { + int const snaps = prefs_get_int_attribute("options.rotationsnapsperpi", "value", 12); + /* 0 interpreted as "no snapping". */ + + // The closest PI/snaps angle, starting from zero. + double const a_snapped = floor(rnew.a/(M_PI/snaps) + 0.5) * (M_PI/snaps); + if (me->origin.a == HUGE_VAL) { + // ortho doesn't exist: original control was zero length. + rnew.a = a_snapped; + } else { + /* The closest PI/2 angle, starting from original angle (i.e. snapping to original, + * its opposite and perpendiculars). */ + double const a_ortho = me->origin.a + floor((rnew.a - me->origin.a)/(M_PI/2) + 0.5) * (M_PI/2); + + // Snap to the closest. + rnew.a = ( fabs(a_snapped - rnew.a) < fabs(a_ortho - rnew.a) + ? a_snapped + : a_ortho ); + } + } + + if (state & GDK_MOD1_MASK) { + // lock handle length + rnew.r = me->origin.r; + } + + if (( n->type !=Inkscape::NodePath::NODE_CUSP || (state & GDK_SHIFT_MASK)) + && rme.a != HUGE_VAL && rnew.a != HUGE_VAL && fabs(rme.a - rnew.a) > 0.001) { + // rotate the other handle correspondingly, if both old and new angles exist and are not the same + rother.a += rnew.a - rme.a; + other->pos = NR::Point(rother) + n->pos; + sp_ctrlline_set_coords(SP_CTRLLINE(other->line), n->pos, other->pos); + sp_knot_set_position(other->knot, &other->pos, 0); + } + + me->pos = NR::Point(rnew) + n->pos; + sp_ctrlline_set_coords(SP_CTRLLINE(me->line), n->pos, me->pos); + + // this is what sp_knot_set_position does, but without emitting the signal: + // we cannot emit a "moved" signal because we're now processing it + if (me->knot->item) SP_CTRL(me->knot->item)->moveto(me->pos); + + knot->desktop->set_coordinate_status(me->pos); + + update_object(n->subpath->nodepath); + + /* status text */ + SPDesktop *desktop = n->subpath->nodepath->desktop; + if (!desktop) return; + SPEventContext *ec = desktop->event_context; + if (!ec) return; + Inkscape::MessageContext *mc = SP_NODE_CONTEXT (ec)->_node_message_context; + if (!mc) return; + + double degrees = 180 / M_PI * rnew.a; + if (degrees > 180) degrees -= 360; + if (degrees < -180) degrees += 360; + if (prefs_get_int_attribute("options.compassangledisplay", "value", 0) != 0) + degrees = angle_to_compass (degrees); + + GString *length = SP_PX_TO_METRIC_STRING(rnew.r, desktop->namedview->getDefaultMetric()); + + mc->setF(Inkscape::NORMAL_MESSAGE, + _("Node handle: angle %0.2f°, length %s; with Ctrl to snap angle; with Alt to lock length; with Shift to rotate both handles"), degrees, length->str); + + g_string_free(length, TRUE); +} + +/** + * Node handle event callback. + */ +static gboolean node_ctrl_event(SPKnot *knot, GdkEvent *event,Inkscape::NodePath::Node *n) +{ + gboolean ret = FALSE; + switch (event->type) { + case GDK_KEY_PRESS: + switch (get_group0_keyval (&event->key)) { + case GDK_space: + if (event->key.state & GDK_BUTTON1_MASK) { + Inkscape::NodePath::Path *nodepath = n->subpath->nodepath; + stamp_repr(nodepath); + ret = TRUE; + } + break; + default: + break; + } + break; + default: + break; + } + + return ret; +} + +static void node_rotate_one_internal(Inkscape::NodePath::Node const &n, gdouble const angle, + Radial &rme, Radial &rother, gboolean const both) +{ + rme.a += angle; + if ( both + || ( n.type == Inkscape::NodePath::NODE_SMOOTH ) + || ( n.type == Inkscape::NodePath::NODE_SYMM ) ) + { + rother.a += angle; + } +} + +static void node_rotate_one_internal_screen(Inkscape::NodePath::Node const &n, gdouble const angle, + Radial &rme, Radial &rother, gboolean const both) +{ + gdouble const norm_angle = angle / n.subpath->nodepath->desktop->current_zoom(); + + gdouble r; + if ( both + || ( n.type == Inkscape::NodePath::NODE_SMOOTH ) + || ( n.type == Inkscape::NodePath::NODE_SYMM ) ) + { + r = MAX(rme.r, rother.r); + } else { + r = rme.r; + } + + gdouble const weird_angle = atan2(norm_angle, r); +/* Bulia says norm_angle is just the visible distance that the + * object's end must travel on the screen. Left as 'angle' for want of + * a better name.*/ + + rme.a += weird_angle; + if ( both + || ( n.type == Inkscape::NodePath::NODE_SMOOTH ) + || ( n.type == Inkscape::NodePath::NODE_SYMM ) ) + { + rother.a += weird_angle; + } +} + +/** + * Rotate one node. + */ +static void node_rotate_one (Inkscape::NodePath::Node *n, gdouble angle, int which, gboolean screen) +{ + Inkscape::NodePath::NodeSide *me, *other; + bool both = false; + + double xn = n->n.other? n->n.other->pos[NR::X] : n->pos[NR::X]; + double xp = n->p.other? n->p.other->pos[NR::X] : n->pos[NR::X]; + + if (!n->n.other) { // if this is an endnode, select its single handle regardless of "which" + me = &(n->p); + other = &(n->n); + } else if (!n->p.other) { + me = &(n->n); + other = &(n->p); + } else { + if (which > 0) { // right handle + if (xn > xp) { + me = &(n->n); + other = &(n->p); + } else { + me = &(n->p); + other = &(n->n); + } + } else if (which < 0){ // left handle + if (xn <= xp) { + me = &(n->n); + other = &(n->p); + } else { + me = &(n->p); + other = &(n->n); + } + } else { // both handles + me = &(n->n); + other = &(n->p); + both = true; + } + } + + Radial rme(me->pos - n->pos); + Radial rother(other->pos - n->pos); + + if (screen) { + node_rotate_one_internal_screen (*n, angle, rme, rother, both); + } else { + node_rotate_one_internal (*n, angle, rme, rother, both); + } + + me->pos = n->pos + NR::Point(rme); + + if (both || n->type == Inkscape::NodePath::NODE_SMOOTH || n->type == Inkscape::NodePath::NODE_SYMM) { + other->pos = n->pos + NR::Point(rother); + } + + sp_node_ensure_ctrls(n); +} + +/** + * Rotate selected nodes. + */ +void sp_nodepath_selected_nodes_rotate(Inkscape::NodePath::Path *nodepath, gdouble angle, int which, bool screen) +{ + if (!nodepath || !nodepath->selected) return; + + if (g_list_length(nodepath->selected) == 1) { + Inkscape::NodePath::Node *n = (Inkscape::NodePath::Node *) nodepath->selected->data; + node_rotate_one (n, angle, which, screen); + } else { + // rotate as an object: + + Inkscape::NodePath::Node *n0 = (Inkscape::NodePath::Node *) nodepath->selected->data; + NR::Rect box (n0->pos, n0->pos); // originally includes the first selected node + for (GList *l = nodepath->selected; l != NULL; l = l->next) { + Inkscape::NodePath::Node *n = (Inkscape::NodePath::Node *) l->data; + box.expandTo (n->pos); // contain all selected nodes + } + + gdouble rot; + if (screen) { + gdouble const zoom = nodepath->desktop->current_zoom(); + gdouble const zmove = angle / zoom; + gdouble const r = NR::L2(box.max() - box.midpoint()); + rot = atan2(zmove, r); + } else { + rot = angle; + } + + NR::Matrix t = + NR::Matrix (NR::translate(-box.midpoint())) * + NR::Matrix (NR::rotate(rot)) * + NR::Matrix (NR::translate(box.midpoint())); + + for (GList *l = nodepath->selected; l != NULL; l = l->next) { + Inkscape::NodePath::Node *n = (Inkscape::NodePath::Node *) l->data; + n->pos *= t; + n->n.pos *= t; + n->p.pos *= t; + sp_node_ensure_ctrls(n); + } + } + + update_object(nodepath); + /// \todo fixme: use _keyed + update_repr(nodepath); +} + +/** + * Scale one node. + */ +static void node_scale_one (Inkscape::NodePath::Node *n, gdouble grow, int which) +{ + bool both = false; + Inkscape::NodePath::NodeSide *me, *other; + + double xn = n->n.other? n->n.other->pos[NR::X] : n->pos[NR::X]; + double xp = n->p.other? n->p.other->pos[NR::X] : n->pos[NR::X]; + + if (!n->n.other) { // if this is an endnode, select its single handle regardless of "which" + me = &(n->p); + other = &(n->n); + n->code = NR_CURVETO; + } else if (!n->p.other) { + me = &(n->n); + other = &(n->p); + if (n->n.other) + n->n.other->code = NR_CURVETO; + } else { + if (which > 0) { // right handle + if (xn > xp) { + me = &(n->n); + other = &(n->p); + if (n->n.other) + n->n.other->code = NR_CURVETO; + } else { + me = &(n->p); + other = &(n->n); + n->code = NR_CURVETO; + } + } else if (which < 0){ // left handle + if (xn <= xp) { + me = &(n->n); + other = &(n->p); + if (n->n.other) + n->n.other->code = NR_CURVETO; + } else { + me = &(n->p); + other = &(n->n); + n->code = NR_CURVETO; + } + } else { // both handles + me = &(n->n); + other = &(n->p); + both = true; + n->code = NR_CURVETO; + if (n->n.other) + n->n.other->code = NR_CURVETO; + } + } + + Radial rme(me->pos - n->pos); + Radial rother(other->pos - n->pos); + + rme.r += grow; + if (rme.r < 0) rme.r = 0; + if (rme.a == HUGE_VAL) { + if (me->other) { // if direction is unknown, initialize it towards the next node + Radial rme_next(me->other->pos - n->pos); + rme.a = rme_next.a; + } else { // if there's no next, initialize to 0 + rme.a = 0; + } + } + if (both || n->type == Inkscape::NodePath::NODE_SYMM) { + rother.r += grow; + if (rother.r < 0) rother.r = 0; + if (rother.a == HUGE_VAL) { + rother.a = rme.a + M_PI; + } + } + + me->pos = n->pos + NR::Point(rme); + + if (both || n->type == Inkscape::NodePath::NODE_SYMM) { + other->pos = n->pos + NR::Point(rother); + } + + sp_node_ensure_ctrls(n); +} + +/** + * Scale selected nodes. + */ +void sp_nodepath_selected_nodes_scale(Inkscape::NodePath::Path *nodepath, gdouble const grow, int const which) +{ + if (!nodepath || !nodepath->selected) return; + + if (g_list_length(nodepath->selected) == 1) { + // scale handles of the single selected node + Inkscape::NodePath::Node *n = (Inkscape::NodePath::Node *) nodepath->selected->data; + node_scale_one (n, grow, which); + } else { + // scale nodes as an "object": + + Inkscape::NodePath::Node *n0 = (Inkscape::NodePath::Node *) nodepath->selected->data; + NR::Rect box (n0->pos, n0->pos); // originally includes the first selected node + for (GList *l = nodepath->selected; l != NULL; l = l->next) { + Inkscape::NodePath::Node *n = (Inkscape::NodePath::Node *) l->data; + box.expandTo (n->pos); // contain all selected nodes + } + + double scale = (box.maxExtent() + grow)/box.maxExtent(); + + NR::Matrix t = + NR::Matrix (NR::translate(-box.midpoint())) * + NR::Matrix (NR::scale(scale, scale)) * + NR::Matrix (NR::translate(box.midpoint())); + + for (GList *l = nodepath->selected; l != NULL; l = l->next) { + Inkscape::NodePath::Node *n = (Inkscape::NodePath::Node *) l->data; + n->pos *= t; + n->n.pos *= t; + n->p.pos *= t; + sp_node_ensure_ctrls(n); + } + } + + update_object(nodepath); + /// \todo fixme: use _keyed + update_repr(nodepath); +} + +void sp_nodepath_selected_nodes_scale_screen(Inkscape::NodePath::Path *nodepath, gdouble const grow, int const which) +{ + if (!nodepath) return; + sp_nodepath_selected_nodes_scale(nodepath, grow / nodepath->desktop->current_zoom(), which); +} + +/** + * Flip selected nodes horizontally/vertically. + */ +void sp_nodepath_flip (Inkscape::NodePath::Path *nodepath, NR::Dim2 axis) +{ + if (!nodepath || !nodepath->selected) return; + + if (g_list_length(nodepath->selected) == 1) { + // flip handles of the single selected node + Inkscape::NodePath::Node *n = (Inkscape::NodePath::Node *) nodepath->selected->data; + double temp = n->p.pos[axis]; + n->p.pos[axis] = n->n.pos[axis]; + n->n.pos[axis] = temp; + sp_node_ensure_ctrls(n); + } else { + // scale nodes as an "object": + + Inkscape::NodePath::Node *n0 = (Inkscape::NodePath::Node *) nodepath->selected->data; + NR::Rect box (n0->pos, n0->pos); // originally includes the first selected node + for (GList *l = nodepath->selected; l != NULL; l = l->next) { + Inkscape::NodePath::Node *n = (Inkscape::NodePath::Node *) l->data; + box.expandTo (n->pos); // contain all selected nodes + } + + NR::Matrix t = + NR::Matrix (NR::translate(-box.midpoint())) * + NR::Matrix ((axis == NR::X)? NR::scale(-1, 1) : NR::scale(1, -1)) * + NR::Matrix (NR::translate(box.midpoint())); + + for (GList *l = nodepath->selected; l != NULL; l = l->next) { + Inkscape::NodePath::Node *n = (Inkscape::NodePath::Node *) l->data; + n->pos *= t; + n->n.pos *= t; + n->p.pos *= t; + sp_node_ensure_ctrls(n); + } + } + + update_object(nodepath); + /// \todo fixme: use _keyed + update_repr(nodepath); +} + +//----------------------------------------------- +/** + * Return new subpath under given nodepath. + */ +static Inkscape::NodePath::SubPath *sp_nodepath_subpath_new(Inkscape::NodePath::Path *nodepath) +{ + g_assert(nodepath); + g_assert(nodepath->desktop); + + Inkscape::NodePath::SubPath *s = g_new(Inkscape::NodePath::SubPath, 1); + + s->nodepath = nodepath; + s->closed = FALSE; + s->nodes = NULL; + s->first = NULL; + s->last = NULL; + + // do not use prepend here because: + // if you have a path like "subpath_1 subpath_2 ... subpath_k" in the svg, you end up with + // subpath_k -> ... ->subpath_1 in the nodepath structure. thus the i-th node of the svg is not + // the i-th node in the nodepath (only if there are multiple subpaths) + // note that the problem only arise when called from subpath_from_bpath(), since for all the other + // cases, the repr is updated after the call to sp_nodepath_subpath_new() + nodepath->subpaths = g_list_append /*g_list_prepend*/ (nodepath->subpaths, s); + + return s; +} + +/** + * Destroy nodes in subpath, then subpath itself. + */ +static void sp_nodepath_subpath_destroy(Inkscape::NodePath::SubPath *subpath) +{ + g_assert(subpath); + g_assert(subpath->nodepath); + g_assert(g_list_find(subpath->nodepath->subpaths, subpath)); + + while (subpath->nodes) { + sp_nodepath_node_destroy((Inkscape::NodePath::Node *) subpath->nodes->data); + } + + subpath->nodepath->subpaths = g_list_remove(subpath->nodepath->subpaths, subpath); + + g_free(subpath); +} + +/** + * Link head to tail in subpath. + */ +static void sp_nodepath_subpath_close(Inkscape::NodePath::SubPath *sp) +{ + g_assert(!sp->closed); + g_assert(sp->last != sp->first); + g_assert(sp->first->code == NR_MOVETO); + + sp->closed = TRUE; + + //Link the head to the tail + sp->first->p.other = sp->last; + sp->last->n.other = sp->first; + sp->last->n.pos = sp->first->n.pos; + sp->first = sp->last; + + //Remove the extra end node + sp_nodepath_node_destroy(sp->last->n.other); +} + +/** + * Open closed (loopy) subpath at node. + */ +static void sp_nodepath_subpath_open(Inkscape::NodePath::SubPath *sp,Inkscape::NodePath::Node *n) +{ + g_assert(sp->closed); + g_assert(n->subpath == sp); + g_assert(sp->first == sp->last); + + /* We create new startpoint, current node will become last one */ + + Inkscape::NodePath::Node *new_path = sp_nodepath_node_new(sp, n->n.other,Inkscape::NodePath::NODE_CUSP, NR_MOVETO, + &n->pos, &n->pos, &n->n.pos); + + + sp->closed = FALSE; + + //Unlink to make a head and tail + sp->first = new_path; + sp->last = n; + n->n.other = NULL; + new_path->p.other = NULL; +} + +/** + * Returns area in triangle given by points; may be negative. + */ +inline double +triangle_area (NR::Point p1, NR::Point p2, NR::Point p3) +{ + return (p1[NR::X]*p2[NR::Y] + p1[NR::Y]*p3[NR::X] + p2[NR::X]*p3[NR::Y] - p2[NR::Y]*p3[NR::X] - p1[NR::Y]*p2[NR::X] - p1[NR::X]*p3[NR::Y]); +} + +/** + * Return new node in subpath with given properties. + * \param pos Position of node. + * \param ppos Handle position in previous direction + * \param npos Handle position in previous direction + */ +Inkscape::NodePath::Node * +sp_nodepath_node_new(Inkscape::NodePath::SubPath *sp, Inkscape::NodePath::Node *next, Inkscape::NodePath::NodeType type, NRPathcode code, NR::Point *ppos, NR::Point *pos, NR::Point *npos) +{ + g_assert(sp); + g_assert(sp->nodepath); + g_assert(sp->nodepath->desktop); + + if (nodechunk == NULL) + nodechunk = g_mem_chunk_create(Inkscape::NodePath::Node, 32, G_ALLOC_AND_FREE); + + Inkscape::NodePath::Node *n = (Inkscape::NodePath::Node*)g_mem_chunk_alloc(nodechunk); + + n->subpath = sp; + + if (type != Inkscape::NodePath::NODE_NONE) { + // use the type from sodipodi:nodetypes + n->type = type; + } else { + if (fabs (triangle_area (*pos, *ppos, *npos)) < 1e-2) { + // points are (almost) collinear + if (NR::L2(*pos - *ppos) < 1e-6 || NR::L2(*pos - *npos) < 1e-6) { + // endnode, or a node with a retracted handle + n->type = Inkscape::NodePath::NODE_CUSP; + } else { + n->type = Inkscape::NodePath::NODE_SMOOTH; + } + } else { + n->type = Inkscape::NodePath::NODE_CUSP; + } + } + + n->code = code; + n->selected = FALSE; + n->pos = *pos; + n->p.pos = *ppos; + n->n.pos = *npos; + + n->dragging_out = NULL; + + Inkscape::NodePath::Node *prev; + if (next) { + g_assert(g_list_find(sp->nodes, next)); + prev = next->p.other; + } else { + prev = sp->last; + } + + if (prev) + prev->n.other = n; + else + sp->first = n; + + if (next) + next->p.other = n; + else + sp->last = n; + + n->p.other = prev; + n->n.other = next; + + n->knot = sp_knot_new(sp->nodepath->desktop); + sp_knot_set_position(n->knot, pos, 0); + g_object_set(G_OBJECT(n->knot), + "anchor", GTK_ANCHOR_CENTER, + "fill", NODE_FILL, + "fill_mouseover", NODE_FILL_HI, + "stroke", NODE_STROKE, + "stroke_mouseover", NODE_STROKE_HI, + "tip", _("Node: drag to edit the path; with Ctrl to snap to horizontal/vertical; with Ctrl+Alt to snap to handles' directions"), + NULL); + if (n->type == Inkscape::NodePath::NODE_CUSP) + g_object_set(G_OBJECT(n->knot), "shape", SP_KNOT_SHAPE_DIAMOND, "size", 9, NULL); + else + g_object_set(G_OBJECT(n->knot), "shape", SP_KNOT_SHAPE_SQUARE, "size", 7, NULL); + + g_signal_connect(G_OBJECT(n->knot), "event", G_CALLBACK(node_event), n); + g_signal_connect(G_OBJECT(n->knot), "clicked", G_CALLBACK(node_clicked), n); + g_signal_connect(G_OBJECT(n->knot), "grabbed", G_CALLBACK(node_grabbed), n); + g_signal_connect(G_OBJECT(n->knot), "ungrabbed", G_CALLBACK(node_ungrabbed), n); + g_signal_connect(G_OBJECT(n->knot), "request", G_CALLBACK(node_request), n); + sp_knot_show(n->knot); + + n->p.knot = sp_knot_new(sp->nodepath->desktop); + sp_knot_set_position(n->p.knot, ppos, 0); + g_object_set(G_OBJECT(n->p.knot), + "shape", SP_KNOT_SHAPE_CIRCLE, + "size", 7, + "anchor", GTK_ANCHOR_CENTER, + "fill", KNOT_FILL, + "fill_mouseover", KNOT_FILL_HI, + "stroke", KNOT_STROKE, + "stroke_mouseover", KNOT_STROKE_HI, + "tip", _("Node handle: drag to shape the curve; with Ctrl to snap angle; with Alt to lock length; with Shift to rotate both handles"), + NULL); + g_signal_connect(G_OBJECT(n->p.knot), "clicked", G_CALLBACK(node_ctrl_clicked), n); + g_signal_connect(G_OBJECT(n->p.knot), "grabbed", G_CALLBACK(node_ctrl_grabbed), n); + g_signal_connect(G_OBJECT(n->p.knot), "ungrabbed", G_CALLBACK(node_ctrl_ungrabbed), n); + g_signal_connect(G_OBJECT(n->p.knot), "request", G_CALLBACK(node_ctrl_request), n); + g_signal_connect(G_OBJECT(n->p.knot), "moved", G_CALLBACK(node_ctrl_moved), n); + g_signal_connect(G_OBJECT(n->p.knot), "event", G_CALLBACK(node_ctrl_event), n); + + sp_knot_hide(n->p.knot); + n->p.line = sp_canvas_item_new(SP_DT_CONTROLS(n->subpath->nodepath->desktop), + SP_TYPE_CTRLLINE, NULL); + sp_canvas_item_hide(n->p.line); + + n->n.knot = sp_knot_new(sp->nodepath->desktop); + sp_knot_set_position(n->n.knot, npos, 0); + g_object_set(G_OBJECT(n->n.knot), + "shape", SP_KNOT_SHAPE_CIRCLE, + "size", 7, + "anchor", GTK_ANCHOR_CENTER, + "fill", KNOT_FILL, + "fill_mouseover", KNOT_FILL_HI, + "stroke", KNOT_STROKE, + "stroke_mouseover", KNOT_STROKE_HI, + "tip", _("Node handle: drag to shape the curve; with Ctrl to snap angle; with Alt to lock length; with Shift to rotate the opposite handle in sync"), + NULL); + g_signal_connect(G_OBJECT(n->n.knot), "clicked", G_CALLBACK(node_ctrl_clicked), n); + g_signal_connect(G_OBJECT(n->n.knot), "grabbed", G_CALLBACK(node_ctrl_grabbed), n); + g_signal_connect(G_OBJECT(n->n.knot), "ungrabbed", G_CALLBACK(node_ctrl_ungrabbed), n); + g_signal_connect(G_OBJECT(n->n.knot), "request", G_CALLBACK(node_ctrl_request), n); + g_signal_connect(G_OBJECT(n->n.knot), "moved", G_CALLBACK(node_ctrl_moved), n); + g_signal_connect(G_OBJECT(n->n.knot), "event", G_CALLBACK(node_ctrl_event), n); + sp_knot_hide(n->n.knot); + n->n.line = sp_canvas_item_new(SP_DT_CONTROLS(n->subpath->nodepath->desktop), + SP_TYPE_CTRLLINE, NULL); + sp_canvas_item_hide(n->n.line); + + sp->nodes = g_list_prepend(sp->nodes, n); + + return n; +} + +/** + * Destroy node and its knots, link neighbors in subpath. + */ +static void sp_nodepath_node_destroy(Inkscape::NodePath::Node *node) +{ + g_assert(node); + g_assert(node->subpath); + g_assert(SP_IS_KNOT(node->knot)); + g_assert(SP_IS_KNOT(node->p.knot)); + g_assert(SP_IS_KNOT(node->n.knot)); + g_assert(g_list_find(node->subpath->nodes, node)); + + Inkscape::NodePath::SubPath *sp = node->subpath; + + if (node->selected) { // first, deselect + g_assert(g_list_find(node->subpath->nodepath->selected, node)); + node->subpath->nodepath->selected = g_list_remove(node->subpath->nodepath->selected, node); + } + + node->subpath->nodes = g_list_remove(node->subpath->nodes, node); + + g_object_unref(G_OBJECT(node->knot)); + g_object_unref(G_OBJECT(node->p.knot)); + g_object_unref(G_OBJECT(node->n.knot)); + + gtk_object_destroy(GTK_OBJECT(node->p.line)); + gtk_object_destroy(GTK_OBJECT(node->n.line)); + + if (sp->nodes) { // there are others nodes on the subpath + if (sp->closed) { + if (sp->first == node) { + g_assert(sp->last == node); + sp->first = node->n.other; + sp->last = sp->first; + } + node->p.other->n.other = node->n.other; + node->n.other->p.other = node->p.other; + } else { + if (sp->first == node) { + sp->first = node->n.other; + sp->first->code = NR_MOVETO; + } + if (sp->last == node) sp->last = node->p.other; + if (node->p.other) node->p.other->n.other = node->n.other; + if (node->n.other) node->n.other->p.other = node->p.other; + } + } else { // this was the last node on subpath + sp->nodepath->subpaths = g_list_remove(sp->nodepath->subpaths, sp); + } + + g_mem_chunk_free(nodechunk, node); +} + +/** + * Returns one of the node's two knots (node sides). + * \param which Indicates which side. + * \return Pointer to previous node side if which==-1, next if which==1. + */ +static Inkscape::NodePath::NodeSide *sp_node_get_side(Inkscape::NodePath::Node *node, gint which) +{ + g_assert(node); + + switch (which) { + case -1: + return &node->p; + case 1: + return &node->n; + default: + break; + } + + g_assert_not_reached(); + + return NULL; +} + +/** + * Return knot on other side of node. + */ +static Inkscape::NodePath::NodeSide *sp_node_opposite_side(Inkscape::NodePath::Node *node,Inkscape::NodePath::NodeSide *me) +{ + g_assert(node); + + if (me == &node->p) return &node->n; + if (me == &node->n) return &node->p; + + g_assert_not_reached(); + + return NULL; +} + +/** + * Return NRPathcode on this knot's side of the node. + */ +static NRPathcode sp_node_path_code_from_side(Inkscape::NodePath::Node *node,Inkscape::NodePath::NodeSide *me) +{ + g_assert(node); + + if (me == &node->p) { + if (node->p.other) return (NRPathcode)node->code; + return NR_MOVETO; + } + + if (me == &node->n) { + if (node->n.other) return (NRPathcode)node->n.other->code; + return NR_MOVETO; + } + + g_assert_not_reached(); + + return NR_END; +} + +/** + * Call sp_nodepath_line_add_node() at t on the segment denoted by piece + */ +Inkscape::NodePath::Node * +sp_nodepath_get_node_by_index(int index) +{ + Inkscape::NodePath::Node *e = NULL; + + Inkscape::NodePath::Path *nodepath = sp_nodepath_current(); + if (!nodepath) { + return e; + } + + //find segment + for (GList *l = nodepath->subpaths; l ; l=l->next) { + + Inkscape::NodePath::SubPath *sp = (Inkscape::NodePath::SubPath *)l->data; + int n = g_list_length(sp->nodes); + if (sp->closed) { + n++; + } + + //if the piece belongs to this subpath grab it + //otherwise move onto the next subpath + if (index < n) { + e = sp->first; + for (int i = 0; i < index; ++i) { + e = e->n.other; + } + break; + } else { + if (sp->closed) { + index -= (n+1); + } else { + index -= n; + } + } + } + + return e; +} + +/** + * Returns plain text meaning of node type. + */ +static gchar const *sp_node_type_description(Inkscape::NodePath::Node *node) +{ + unsigned retracted = 0; + bool endnode = false; + + for (int which = -1; which <= 1; which += 2) { + Inkscape::NodePath::NodeSide *side = sp_node_get_side(node, which); + if (side->other && NR::L2(side->pos - node->pos) < 1e-6) + retracted ++; + if (!side->other) + endnode = true; + } + + if (retracted == 0) { + if (endnode) { + // TRANSLATORS: "end" is an adjective here (NOT a verb) + return _("end node"); + } else { + switch (node->type) { + case Inkscape::NodePath::NODE_CUSP: + // TRANSLATORS: "cusp" means "sharp" (cusp node); see also the Advanced Tutorial + return _("cusp"); + case Inkscape::NodePath::NODE_SMOOTH: + // TRANSLATORS: "smooth" is an adjective here + return _("smooth"); + case Inkscape::NodePath::NODE_SYMM: + return _("symmetric"); + } + } + } else if (retracted == 1) { + if (endnode) { + // TRANSLATORS: "end" is an adjective here (NOT a verb) + return _("end node, handle retracted (drag with Shift to extend)"); + } else { + return _("one handle retracted (drag with Shift to extend)"); + } + } else { + return _("both handles retracted (drag with Shift to extend)"); + } + + return NULL; +} + +/** + * Handles content of statusbar as long as node tool is active. + */ +void +sp_nodepath_update_statusbar(Inkscape::NodePath::Path *nodepath) +{ + gchar const *when_selected = _("Drag nodes or node handles; arrow keys to move nodes"); + gchar const *when_selected_one = _("Drag the node or its handles; arrow keys to move the node"); + + gint total = 0; + gint selected = 0; + SPDesktop *desktop = NULL; + + if (nodepath) { + for (GList *spl = nodepath->subpaths; spl != NULL; spl = spl->next) { + Inkscape::NodePath::SubPath *subpath = (Inkscape::NodePath::SubPath *) spl->data; + total += g_list_length(subpath->nodes); + } + selected = g_list_length(nodepath->selected); + desktop = nodepath->desktop; + } else { + desktop = SP_ACTIVE_DESKTOP; + } + + SPEventContext *ec = desktop->event_context; + if (!ec) return; + Inkscape::MessageContext *mc = SP_NODE_CONTEXT (ec)->_node_message_context; + if (!mc) return; + + if (selected == 0) { + Inkscape::Selection *sel = desktop->selection; + if (!sel || sel->isEmpty()) { + mc->setF(Inkscape::NORMAL_MESSAGE, + _("Select a single object to edit its nodes or handles.")); + } else { + if (nodepath) { + mc->setF(Inkscape::NORMAL_MESSAGE, + ngettext("0 out of %i node selected. Click, Shift+click, or drag around nodes to select.", + "0 out of %i nodes selected. Click, Shift+click, or drag around nodes to select.", + total), + total); + } else { + if (g_slist_length((GSList *)sel->itemList()) == 1) { + mc->setF(Inkscape::NORMAL_MESSAGE, _("Drag the handles of the object to modify it.")); + } else { + mc->setF(Inkscape::NORMAL_MESSAGE, _("Select a single object to edit its nodes or handles.")); + } + } + } + } else if (nodepath && selected == 1) { + mc->setF(Inkscape::NORMAL_MESSAGE, + ngettext("%i of %i node selected; %s. %s.", + "%i of %i nodes selected; %s. %s.", + total), + selected, total, sp_node_type_description((Inkscape::NodePath::Node *) nodepath->selected->data), when_selected_one); + } else { + mc->setF(Inkscape::NORMAL_MESSAGE, + ngettext("%i of %i node selected. %s.", + "%i of %i nodes selected. %s.", + total), + selected, total, when_selected); + } +} + + +/* + 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:textwidth=99 : diff --git a/src/nodepath.h b/src/nodepath.h new file mode 100644 index 000000000..84c83be53 --- /dev/null +++ b/src/nodepath.h @@ -0,0 +1,266 @@ +#ifndef __SP_NODEPATH_H__ +#define __SP_NODEPATH_H__ + +/** \file + * Path handler in node edit mode + */ + +/* + * Authors: + * Lauris Kaplinski + * + * This code is in public domain + */ + +//#include "knot.h" +//#include "sp-path.h" +//#include "desktop-handles.h" +#include "libnr/nr-path-code.h" + +#include + +class SPDesktop; +class SPPath; +class SPKnot; + +namespace Inkscape { +namespace XML { +class Node; +} +} + + +/** + * Radial objects are represented by an angle and a distance from + * 0,0. 0,0 is represented by a == big_num. + */ +class Radial{ + public: +/** Radius */ + double r; +/** Amplitude */ + double a; + Radial() {} + // Radial(NR::Point const &p); // Convert a point to radial coordinates + Radial(Radial &p) : r(p.r),a(p.a) {} + // operator NR::Point() const; + +/** + * Construct Radial from NR::Point. + */ +Radial(NR::Point const &p) +{ + r = NR::L2(p); + if (r > 0) { + a = NR::atan2 (p); + } else { + a = HUGE_VAL; //undefined + } +} + +/** + * Cast Radial to cartesian NR::Point. + */ +operator NR::Point() const +{ + if (a == HUGE_VAL) { + return NR::Point(0,0); + } else { + return r*NR::Point(cos(a), sin(a)); + } +} + +}; + +/** defined in node-context.h */ +class SPNodeContext; + +namespace Inkscape { +namespace NodePath { + +/** + * This is a node on a subpath + */ +class Path; + +/** + * This is a subdivision of a NodePath + */ +class SubPath; + +class NodeSide; + +/** + * This is a node (point) along a subpath + */ +class Node; + + +/** + * This is a collection of subpaths which contain nodes + * + * In the following data model. Nodepaths are made up of subpaths which + * are comprised of nodes. + * + * Nodes are linked thus: + * \verbatim + n other + node -----> nodeside ------> node \endverbatim + */ +class Path { + public: +/** Pointer to the current desktop, for reporting purposes */ + SPDesktop * desktop; +/** The parent path of this nodepath */ + SPPath * path; +/** The context which created this nodepath. Important if this nodepath is deleted */ + SPNodeContext * nodeContext; +/** The subpaths which comprise this NodePath */ + GList * subpaths; +/** A list of nodes which are currently selected */ + GList * selected; +/** Transforms (userspace <---> virtual space? someone please describe ) + njh: I'd be guessing that these are item <-> desktop transforms.*/ + NR::Matrix i2d, d2i; +/** The DOM node which describes this NodePath */ + Inkscape::XML::Node *repr; + //STL compliant method to get the selected nodes + void selection(std::list &l); +}; + + +/** + * This is the lowest list item, a simple list of nodes. + */ +class SubPath { + public: +/** The parent of this subpath */ + Path * nodepath; +/** Is this path closed (no endpoints) or not?*/ + gboolean closed; +/** The nodes in this subpath. */ + GList * nodes; +/** The first node of the subpath (does not imply open/closed)*/ + Node * first; +/** The last node of the subpath */ + Node * last; +}; + + + +/** + * What kind of node is this? This is the value for the node->type + * field. NodeType indicates the degree of continuity required for + * the node. I think that the corresponding integer indicates which + * derivate is connected. (Thus 2 means that the node is continuous + * to the second derivative, i.e. has matching endpoints and tangents) + */ +typedef enum { +/** A normal node */ + NODE_NONE, +/** This node non-continuously joins two segments.*/ + NODE_CUSP, +/** This node continuously joins two segments. */ + NODE_SMOOTH, +/** This node is symmetric. */ + NODE_SYMM +} NodeType; + + + +/** + * A NodeSide is a datarecord which may be on either side (n or p) of a node, + * which describes the segment going to the next node. + */ +class NodeSide{ + public: +/** Pointer to the next node, */ + Node * other; +/** Position */ + NR::Point pos; +/** Knots are Inkscape's way of providing draggable points. This + * Knot is the point on the curve representing the control point in a + * bezier curve.*/ + SPKnot * knot; +/** What kind of rendering? */ + SPCanvasItem * line; +/** */ + Radial origin; +}; + +/** + * A node along a NodePath + */ +class Node { + public: +/** The parent subpath of this node */ + SubPath * subpath; +/** Type is selected from NodeType.*/ + guint type : 4; +/** Code refers to which ArtCode is used to represent the segment + * (which segment?).*/ + guint code : 4; +/** Boolean. Am I currently selected or not? */ + guint selected : 1; +/** */ + NR::Point pos; +/** */ + NR::Point origin; +/** Knots are Inkscape's way of providing draggable points. This + * Knot is the point on the curve representing the endpoint.*/ + SPKnot * knot; +/** The NodeSide in the 'next' direction */ + NodeSide n; +/** The NodeSide in the 'previous' direction */ + NodeSide p; + + /** The pointer to the nodeside which we are dragging out with Shift */ + NodeSide *dragging_out; +}; + +} // namespace NodePath +} // namespace Inkscape + +// Do function documentation in nodepath.cpp +Inkscape::NodePath::Path * sp_nodepath_new (SPDesktop * desktop, SPItem * item); +void sp_nodepath_destroy (Inkscape::NodePath::Path * nodepath); +void sp_nodepath_deselect (Inkscape::NodePath::Path *nodepath); +void sp_nodepath_select_all (Inkscape::NodePath::Path *nodepath, bool invert); +void sp_nodepath_select_all_from_subpath(Inkscape::NodePath::Path *nodepath, bool invert); +void sp_nodepath_select_next (Inkscape::NodePath::Path *nodepath); +void sp_nodepath_select_prev (Inkscape::NodePath::Path *nodepath); +void sp_nodepath_select_rect (Inkscape::NodePath::Path * nodepath, NR::Rect const &b, gboolean incremental); +GList *save_nodepath_selection (Inkscape::NodePath::Path *nodepath); +void restore_nodepath_selection (Inkscape::NodePath::Path *nodepath, GList *r); +gboolean nodepath_repr_d_changed (Inkscape::NodePath::Path * np, const char *newd); +gboolean nodepath_repr_typestr_changed (Inkscape::NodePath::Path * np, const char *newtypestr); +gboolean node_key (GdkEvent * event); +void sp_nodepath_update_statusbar (Inkscape::NodePath::Path *nodepath); +void sp_nodepath_selected_align(Inkscape::NodePath::Path *nodepath, NR::Dim2 axis); +void sp_nodepath_selected_distribute(Inkscape::NodePath::Path *nodepath, NR::Dim2 axis); +void sp_nodepath_select_segment_near_point(SPItem * item, NR::Point p, bool toggle); +void sp_nodepath_add_node_near_point(SPItem * item, NR::Point p); +void sp_nodepath_curve_drag(Inkscape::NodePath::Node * e, double t, NR::Point delta, char * key); +Inkscape::NodePath::Node * sp_nodepath_get_node_by_index(int index); +/* possibly private functions */ + +void sp_node_selected_add_node (void); +void sp_node_selected_break (void); +void sp_node_selected_duplicate (void); +void sp_node_selected_join (void); +void sp_node_selected_join_segment (void); +void sp_node_selected_delete (void); +void sp_node_selected_delete_segment (void); +void sp_node_selected_set_type (Inkscape::NodePath::NodeType type); +void sp_node_selected_set_line_type (NRPathcode code); +void sp_node_selected_move (gdouble dx, gdouble dy); +void sp_node_selected_move_screen (gdouble dx, gdouble dy); + +void sp_nodepath_selected_nodes_rotate (Inkscape::NodePath::Path * nodepath, gdouble angle, int which, bool screen); + +void sp_nodepath_selected_nodes_scale (Inkscape::NodePath::Path * nodepath, gdouble grow, int which); +void sp_nodepath_selected_nodes_scale_screen (Inkscape::NodePath::Path * nodepath, gdouble grow, int which); + +void sp_nodepath_flip (Inkscape::NodePath::Path *nodepath, NR::Dim2 axis); + +#endif diff --git a/src/object-edit.cpp b/src/object-edit.cpp new file mode 100644 index 000000000..3db0f0a21 --- /dev/null +++ b/src/object-edit.cpp @@ -0,0 +1,1074 @@ +#define __SP_OBJECT_EDIT_C__ + +/* + * Node editing extension to objects + * + * Authors: + * Lauris Kaplinski + * Mitsuru Oka + * + * Licensed under GNU GPL + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + + + +#include "sp-item.h" +#include "sp-rect.h" +#include "sp-ellipse.h" +#include "sp-star.h" +#include "sp-spiral.h" +#include "sp-offset.h" +#include "sp-flowtext.h" +#include "prefs-utils.h" +#include "inkscape.h" +#include "snap.h" +#include "desktop-affine.h" +#include +#include "desktop.h" + +#include "sp-pattern.h" +#include "sp-path.h" + +#include + +#include "object-edit.h" + +#include + + +#include "xml/repr.h" + +#include "isnan.h" + +#define sp_round(v,m) (((v) < 0.0) ? ((ceil((v) / (m) - 0.5)) * (m)) : ((floor((v) / (m) + 0.5)) * (m))) + +static SPKnotHolder *sp_rect_knot_holder(SPItem *item, SPDesktop *desktop); +static SPKnotHolder *sp_arc_knot_holder(SPItem *item, SPDesktop *desktop); +static SPKnotHolder *sp_star_knot_holder(SPItem *item, SPDesktop *desktop); +static SPKnotHolder *sp_spiral_knot_holder(SPItem *item, SPDesktop *desktop); +static SPKnotHolder *sp_offset_knot_holder(SPItem *item, SPDesktop *desktop); +static SPKnotHolder *sp_path_knot_holder(SPItem *item, SPDesktop *desktop); +static SPKnotHolder *sp_flowtext_knot_holder(SPItem *item, SPDesktop *desktop); +static void sp_pat_knot_holder(SPItem *item, SPKnotHolder *knot_holder); + +SPKnotHolder * +sp_item_knot_holder(SPItem *item, SPDesktop *desktop) +{ + if (SP_IS_RECT(item)) { + return sp_rect_knot_holder(item, desktop); + } else if (SP_IS_ARC(item)) { + return sp_arc_knot_holder(item, desktop); + } else if (SP_IS_STAR(item)) { + return sp_star_knot_holder(item, desktop); + } else if (SP_IS_SPIRAL(item)) { + return sp_spiral_knot_holder(item, desktop); + } else if (SP_IS_OFFSET(item)) { + return sp_offset_knot_holder(item, desktop); + } else if (SP_IS_PATH(item)) { + return sp_path_knot_holder(item, desktop); + } else if (SP_IS_FLOWTEXT(item) && SP_FLOWTEXT(item)->has_internal_frame()) { + return sp_flowtext_knot_holder(item, desktop); + } + + return NULL; +} + + +/* Pattern manipulation */ + +static gdouble sp_pattern_extract_theta(SPPattern *pat, gdouble scale) +{ + gdouble theta = asin(pat->patternTransform[1] / scale); + if (pat->patternTransform[0] < 0) theta = M_PI - theta ; + return theta; +} + +static gdouble sp_pattern_extract_scale(SPPattern *pat) +{ + gdouble s = pat->patternTransform[1]; + gdouble c = pat->patternTransform[0]; + gdouble xscale = sqrt(c * c + s * s); + return xscale; +} + +static NR::Point sp_pattern_extract_trans(SPPattern const *pat) +{ + return NR::Point(pat->patternTransform[4], pat->patternTransform[5]); +} + +static void +sp_pattern_xy_set(SPItem *item, NR::Point const &p, NR::Point const &origin, guint state) +{ + SPPattern *pat = SP_PATTERN(SP_STYLE_FILL_SERVER(SP_OBJECT(item)->style)); + + NR::Point p_snapped = p; + + if ( state & GDK_CONTROL_MASK ) { + if (fabs((p - origin)[NR::X]) > fabs((p - origin)[NR::Y])) { + p_snapped[NR::Y] = origin[NR::Y]; + } else { + p_snapped[NR::X] = origin[NR::X]; + } + } + + if (state) { + NR::Point const q = p_snapped - sp_pattern_extract_trans(pat); + sp_item_adjust_pattern(item, NR::Matrix(NR::translate(q))); + } + + item->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); +} + + +static NR::Point sp_pattern_xy_get(SPItem *item) +{ + SPPattern const *pat = SP_PATTERN(SP_STYLE_FILL_SERVER(SP_OBJECT(item)->style)); + return sp_pattern_extract_trans(pat); +} + +static NR::Point sp_pattern_angle_get(SPItem *item) +{ + SPPattern *pat = SP_PATTERN(SP_STYLE_FILL_SERVER(SP_OBJECT(item)->style)); + + gdouble x = (pattern_width(pat)*0.5); + gdouble y = 0; + NR::Point delta = NR::Point(x,y); + gdouble scale = sp_pattern_extract_scale(pat); + gdouble theta = sp_pattern_extract_theta(pat, scale); + delta = delta * NR::Matrix(NR::rotate(theta))*NR::Matrix(NR::scale(scale,scale)); + delta = delta + sp_pattern_extract_trans(pat); + return delta; +} + +static void +sp_pattern_angle_set(SPItem *item, NR::Point const &p, NR::Point const &origin, guint state) +{ + int const snaps = prefs_get_int_attribute("options.rotationsnapsperpi", "value", 12); + + SPPattern *pat = SP_PATTERN(SP_STYLE_FILL_SERVER(SP_OBJECT(item)->style)); + + // get the angle from pattern 0,0 to the cursor pos + NR::Point delta = p - sp_pattern_extract_trans(pat); + gdouble theta = atan2(delta); + + if ( state & GDK_CONTROL_MASK ) { + theta = sp_round(theta, M_PI/snaps); + } + + // get the scale from the current transform so we can keep it. + gdouble scl = sp_pattern_extract_scale(pat); + NR::Matrix rot = NR::Matrix(NR::rotate(theta)) * NR::Matrix(NR::scale(scl,scl)); + NR::Point const t = sp_pattern_extract_trans(pat); + rot[4] = t[NR::X]; + rot[5] = t[NR::Y]; + sp_item_adjust_pattern(item, rot, true); + item->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); +} + +static void +sp_pattern_scale_set(SPItem *item, NR::Point const &p, NR::Point const &origin, guint state) +{ + SPPattern *pat = SP_PATTERN(SP_STYLE_FILL_SERVER(SP_OBJECT(item)->style)); + + // Get the scale from the position of the knotholder, + NR::Point d = p - sp_pattern_extract_trans(pat); + gdouble s = NR::L2(d); + gdouble pat_x = pattern_width(pat) * 0.5; + gdouble pat_y = pattern_height(pat) * 0.5; + gdouble pat_h = hypot(pat_x, pat_y); + gdouble scl = s / pat_h; + + // get angle from current transform, (need get current scale first to calculate angle) + gdouble oldscale = sp_pattern_extract_scale(pat); + gdouble theta = sp_pattern_extract_theta(pat,oldscale); + + NR::Matrix rot = NR::Matrix(NR::rotate(theta)) * NR::Matrix(NR::scale(scl,scl)); + NR::Point const t = sp_pattern_extract_trans(pat); + rot[4] = t[NR::X]; + rot[5] = t[NR::Y]; + sp_item_adjust_pattern(item, rot, true); + item->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); +} + + +static NR::Point sp_pattern_scale_get(SPItem *item) +{ + SPPattern *pat = SP_PATTERN(SP_STYLE_FILL_SERVER(SP_OBJECT(item)->style)); + + gdouble x = pattern_width(pat)*0.5; + gdouble y = pattern_height(pat)*0.5; + NR::Point delta = NR::Point(x,y); + NR::Matrix a = pat->patternTransform; + a[4] = 0; + a[5] = 0; + delta = delta * a; + delta = delta + sp_pattern_extract_trans(pat); + return delta; +} + +/* SPRect */ + +static NR::Point sp_rect_rx_get(SPItem *item) +{ + SPRect *rect = SP_RECT(item); + + return NR::Point(rect->x.computed + rect->width.computed - rect->rx.computed, rect->y.computed); +} + +static void sp_rect_rx_set(SPItem *item, NR::Point const &p, NR::Point const &origin, guint state) +{ + SPRect *rect = SP_RECT(item); + + if (state & GDK_CONTROL_MASK) { + gdouble temp = MIN(rect->height.computed, rect->width.computed) / 2.0; + rect->rx.computed = rect->ry.computed = CLAMP(rect->x.computed + rect->width.computed - p[NR::X], 0.0, temp); + rect->rx._set = rect->ry._set = true; + + } else { + rect->rx.computed = CLAMP(rect->x.computed + rect->width.computed - p[NR::X], 0.0, rect->width.computed / 2.0); + rect->rx._set = true; + } + + ((SPObject*)rect)->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); +} + + +static NR::Point sp_rect_ry_get(SPItem *item) +{ + SPRect *rect = SP_RECT(item); + + return NR::Point(rect->x.computed + rect->width.computed, rect->y.computed + rect->ry.computed); +} + +static void sp_rect_ry_set(SPItem *item, NR::Point const &p, NR::Point const &origin, guint state) +{ + SPRect *rect = SP_RECT(item); + + if (state & GDK_CONTROL_MASK) { + gdouble temp = MIN(rect->height.computed, rect->width.computed) / 2.0; + rect->rx.computed = rect->ry.computed = CLAMP(p[NR::Y] - rect->y.computed, 0.0, temp); + rect->ry._set = rect->rx._set = true; + } else { + if (!rect->rx._set || rect->rx.computed == 0) { + rect->ry.computed = CLAMP(p[NR::Y] - rect->y.computed, + 0.0, + MIN(rect->height.computed / 2.0, rect->width.computed / 2.0)); + } else { + rect->ry.computed = CLAMP(p[NR::Y] - rect->y.computed, + 0.0, + rect->height.computed / 2.0); + } + + rect->ry._set = true; + } + + ((SPObject *)rect)->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); +} + +/** + * Remove rounding from a rectangle. + */ +static void rect_remove_rounding(SPRect *rect) +{ + SP_OBJECT_REPR(rect)->setAttribute("rx", NULL); + SP_OBJECT_REPR(rect)->setAttribute("ry", NULL); +} + +/** + * Called when the horizontal rounding radius knot is clicked. + */ +static void sp_rect_rx_knot_click(SPItem *item, guint state) +{ + SPRect *rect = SP_RECT(item); + + if (state & GDK_SHIFT_MASK) { + rect_remove_rounding(rect); + } else if (state & GDK_CONTROL_MASK) { + /* Ctrl-click sets the vertical rounding to be the same as the horizontal */ + SP_OBJECT_REPR(rect)->setAttribute("ry", SP_OBJECT_REPR(rect)->attribute("rx")); + } +} + +/** + * Called when the vertical rounding radius knot is clicked. + */ +static void sp_rect_ry_knot_click(SPItem *item, guint state) +{ + SPRect *rect = SP_RECT(item); + + if (state & GDK_SHIFT_MASK) { + rect_remove_rounding(rect); + } else if (state & GDK_CONTROL_MASK) { + /* Ctrl-click sets the vertical rounding to be the same as the horizontal */ + SP_OBJECT_REPR(rect)->setAttribute("rx", SP_OBJECT_REPR(rect)->attribute("ry")); + } +} + +#define SGN(x) ((x)>0?1:((x)<0?-1:0)) + +static void sp_rect_clamp_radii(SPRect *rect) +{ + // clamp rounding radii so that they do not exceed width/height + if (2 * rect->rx.computed > rect->width.computed) { + rect->rx.computed = 0.5 * rect->width.computed; + rect->rx._set = true; + } + if (2 * rect->ry.computed > rect->height.computed) { + rect->ry.computed = 0.5 * rect->height.computed; + rect->ry._set = true; + } +} + +static NR::Point sp_rect_wh_get(SPItem *item) +{ + SPRect *rect = SP_RECT(item); + + return NR::Point(rect->x.computed + rect->width.computed, rect->y.computed + rect->height.computed); +} + +static NR::Point rect_snap_knot_position(NR::Point const &p) +{ + SPDesktop const *desktop = inkscape_active_desktop(); + NR::Point s = sp_desktop_dt2root_xy_point(desktop, p); + SnapManager const m(desktop->namedview); + s = m.freeSnap(Inkscape::Snapper::BBOX_POINT | Inkscape::Snapper::SNAP_POINT, s, NULL).getPoint(); + return sp_desktop_root2dt_xy_point(desktop, s); +} + +static void sp_rect_wh_set_internal(SPRect *rect, NR::Point const &p, NR::Point const &origin, guint state) +{ + NR::Point const s = rect_snap_knot_position(p); + + if (state & GDK_CONTROL_MASK) { + // original width/height when drag started + gdouble const w_orig = (origin[NR::X] - rect->x.computed); + gdouble const h_orig = (origin[NR::Y] - rect->y.computed); + + //original ratio + gdouble const ratio = (w_orig / h_orig); + + // mouse displacement since drag started + gdouble const minx = s[NR::X] - origin[NR::X]; + gdouble const miny = s[NR::Y] - origin[NR::Y]; + + if (fabs(minx) > fabs(miny)) { + + // snap to horizontal or diagonal + rect->width.computed = MAX(w_orig + minx, 0); + if (minx != 0 && fabs(miny/minx) > 0.5 * 1/ratio && (SGN(minx) == SGN(miny))) { + // closer to the diagonal and in same-sign quarters, change both using ratio + rect->height.computed = MAX(h_orig + minx / ratio, 0); + } else { + // closer to the horizontal, change only width, height is h_orig + rect->height.computed = MAX(h_orig, 0); + } + + } else { + // snap to vertical or diagonal + rect->height.computed = MAX(h_orig + miny, 0); + if (miny != 0 && fabs(minx/miny) > 0.5 * ratio && (SGN(minx) == SGN(miny))) { + // closer to the diagonal and in same-sign quarters, change both using ratio + rect->width.computed = MAX(w_orig + miny * ratio, 0); + } else { + // closer to the vertical, change only height, width is w_orig + rect->width.computed = MAX(w_orig, 0); + } + } + + rect->width._set = rect->height._set = true; + + } else { + // move freely + rect->width.computed = MAX(s[NR::X] - rect->x.computed, 0); + rect->height.computed = MAX(s[NR::Y] - rect->y.computed, 0); + rect->width._set = rect->height._set = true; + } + + sp_rect_clamp_radii(rect); + + ((SPObject *)rect)->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); +} + +static void sp_rect_wh_set(SPItem *item, NR::Point const &p, NR::Point const &origin, guint state) +{ + SPRect *rect = SP_RECT(item); + + sp_rect_wh_set_internal(rect, p, origin, state); +} + +static NR::Point sp_rect_xy_get(SPItem *item) +{ + SPRect *rect = SP_RECT(item); + + return NR::Point(rect->x.computed, rect->y.computed); +} + +static void sp_rect_xy_set(SPItem *item, NR::Point const &p, NR::Point const &origin, guint state) +{ + SPRect *rect = SP_RECT(item); + + // opposite corner (unmoved) + gdouble opposite_x = (rect->x.computed + rect->width.computed); + gdouble opposite_y = (rect->y.computed + rect->height.computed); + + // original width/height when drag started + gdouble w_orig = opposite_x - origin[NR::X]; + gdouble h_orig = opposite_y - origin[NR::Y]; + + NR::Point const s = rect_snap_knot_position(p); + + // mouse displacement since drag started + gdouble minx = s[NR::X] - origin[NR::X]; + gdouble miny = s[NR::Y] - origin[NR::Y]; + + if (state & GDK_CONTROL_MASK) { + //original ratio + gdouble ratio = (w_orig / h_orig); + + if (fabs(minx) > fabs(miny)) { + + // snap to horizontal or diagonal + rect->x.computed = MIN(s[NR::X], opposite_x); + rect->width.computed = MAX(w_orig - minx, 0); + if (minx != 0 && fabs(miny/minx) > 0.5 * 1/ratio && (SGN(minx) == SGN(miny))) { + // closer to the diagonal and in same-sign quarters, change both using ratio + rect->y.computed = MIN(origin[NR::Y] + minx / ratio, opposite_y); + rect->height.computed = MAX(h_orig - minx / ratio, 0); + } else { + // closer to the horizontal, change only width, height is h_orig + rect->y.computed = MIN(origin[NR::Y], opposite_y); + rect->height.computed = MAX(h_orig, 0); + } + + } else { + + // snap to vertical or diagonal + rect->y.computed = MIN(s[NR::Y], opposite_y); + rect->height.computed = MAX(h_orig - miny, 0); + if (miny != 0 && fabs(minx/miny) > 0.5 *ratio && (SGN(minx) == SGN(miny))) { + // closer to the diagonal and in same-sign quarters, change both using ratio + rect->x.computed = MIN(origin[NR::X] + miny * ratio, opposite_x); + rect->width.computed = MAX(w_orig - miny * ratio, 0); + } else { + // closer to the vertical, change only height, width is w_orig + rect->x.computed = MIN(origin[NR::X], opposite_x); + rect->width.computed = MAX(w_orig, 0); + } + + } + + rect->width._set = rect->height._set = rect->x._set = rect->y._set = true; + + } else { + // move freely + rect->x.computed = MIN(s[NR::X], opposite_x); + rect->width.computed = MAX(w_orig - minx, 0); + rect->y.computed = MIN(s[NR::Y], opposite_y); + rect->height.computed = MAX(h_orig - miny, 0); + rect->width._set = rect->height._set = rect->x._set = rect->y._set = true; + } + + sp_rect_clamp_radii(rect); + + ((SPObject *)rect)->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); +} + +static SPKnotHolder *sp_rect_knot_holder(SPItem *item, SPDesktop *desktop) +{ + SPKnotHolder *knot_holder = sp_knot_holder_new(desktop, item, NULL); + + sp_knot_holder_add_full( + knot_holder, sp_rect_rx_set, sp_rect_rx_get, sp_rect_rx_knot_click, + SP_KNOT_SHAPE_CIRCLE, SP_KNOT_MODE_XOR, + _("Adjust the horizontal rounding radius; with Ctrl to make the vertical " + "radius the same")); + + sp_knot_holder_add_full( + knot_holder, sp_rect_ry_set, sp_rect_ry_get, sp_rect_ry_knot_click, + SP_KNOT_SHAPE_CIRCLE, SP_KNOT_MODE_XOR, + _("Adjust the vertical rounding radius; with Ctrl to make the horizontal " + "radius the same") + ); + + sp_knot_holder_add_full( + knot_holder, sp_rect_wh_set, sp_rect_wh_get, NULL, + SP_KNOT_SHAPE_SQUARE, SP_KNOT_MODE_XOR, + _("Adjust the width and height of the rectangle; with Ctrl to lock ratio " + "or stretch in one dimension only") + ); + + sp_knot_holder_add_full( + knot_holder, sp_rect_xy_set, sp_rect_xy_get, NULL, + SP_KNOT_SHAPE_SQUARE, SP_KNOT_MODE_XOR, + _("Adjust the width and height of the rectangle; with Ctrl to lock ratio " + "or stretch in one dimension only") + ); + + sp_pat_knot_holder(item, knot_holder); + return knot_holder; +} + +/* SPArc */ + +/* + * return values: + * 1 : inside + * 0 : on the curves + * -1 : outside + */ +static gint +sp_genericellipse_side(SPGenericEllipse *ellipse, NR::Point const &p) +{ + gdouble dx = (p[NR::X] - ellipse->cx.computed) / ellipse->rx.computed; + gdouble dy = (p[NR::Y] - ellipse->cy.computed) / ellipse->ry.computed; + + gdouble s = dx * dx + dy * dy; + if (s < 1.0) return 1; + if (s > 1.0) return -1; + return 0; +} + +static void +sp_arc_start_set(SPItem *item, NR::Point const &p, NR::Point const &origin, guint state) +{ + int snaps = prefs_get_int_attribute("options.rotationsnapsperpi", "value", 12); + + SPGenericEllipse *ge = SP_GENERICELLIPSE(item); + SPArc *arc = SP_ARC(item); + + ge->closed = (sp_genericellipse_side(ge, p) == -1) ? TRUE : FALSE; + + NR::Point delta = p - NR::Point(ge->cx.computed, ge->cy.computed); + NR::scale sc(ge->rx.computed, ge->ry.computed); + ge->start = atan2(delta * sc.inverse()); + if ( ( state & GDK_CONTROL_MASK ) + && snaps ) + { + ge->start = sp_round(ge->start, M_PI/snaps); + } + sp_genericellipse_normalize(ge); + ((SPObject *)arc)->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); +} + +static NR::Point sp_arc_start_get(SPItem *item) +{ + SPGenericEllipse *ge = SP_GENERICELLIPSE(item); + SPArc *arc = SP_ARC(item); + + return sp_arc_get_xy(arc, ge->start); +} + +static void +sp_arc_end_set(SPItem *item, NR::Point const &p, NR::Point const &origin, guint state) +{ + int snaps = prefs_get_int_attribute("options.rotationsnapsperpi", "value", 12); + + SPGenericEllipse *ge = SP_GENERICELLIPSE(item); + SPArc *arc = SP_ARC(item); + + ge->closed = (sp_genericellipse_side(ge, p) == -1) ? TRUE : FALSE; + + NR::Point delta = p - NR::Point(ge->cx.computed, ge->cy.computed); + NR::scale sc(ge->rx.computed, ge->ry.computed); + ge->end = atan2(delta * sc.inverse()); + if ( ( state & GDK_CONTROL_MASK ) + && snaps ) + { + ge->end = sp_round(ge->end, M_PI/snaps); + } + sp_genericellipse_normalize(ge); + ((SPObject *)arc)->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); +} + +static NR::Point sp_arc_end_get(SPItem *item) +{ + SPGenericEllipse *ge = SP_GENERICELLIPSE(item); + SPArc *arc = SP_ARC(item); + + return sp_arc_get_xy(arc, ge->end); +} + +static void +sp_arc_startend_click(SPItem *item, guint state) +{ + SPGenericEllipse *ge = SP_GENERICELLIPSE(item); + + if (state & GDK_SHIFT_MASK) { + ge->end = ge->start = 0; + ((SPObject *)ge)->updateRepr(); + } +} + + +static void +sp_arc_rx_set(SPItem *item, NR::Point const &p, NR::Point const &origin, guint state) +{ + SPGenericEllipse *ge = SP_GENERICELLIPSE(item); + SPArc *arc = SP_ARC(item); + + ge->rx.computed = fabs( ge->cx.computed - p[NR::X] ); + + if ( state & GDK_CONTROL_MASK ) { + ge->ry.computed = ge->rx.computed; + } + + ((SPObject *)arc)->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); +} + +static NR::Point sp_arc_rx_get(SPItem *item) +{ + SPGenericEllipse *ge = SP_GENERICELLIPSE(item); + + return (NR::Point(ge->cx.computed, ge->cy.computed) - NR::Point(ge->rx.computed, 0)); +} + +static void +sp_arc_ry_set(SPItem *item, NR::Point const &p, NR::Point const &origin, guint state) +{ + SPGenericEllipse *ge = SP_GENERICELLIPSE(item); + SPArc *arc = SP_ARC(item); + + ge->ry.computed = fabs( ge->cy.computed - p[NR::Y] ); + + if ( state & GDK_CONTROL_MASK ) { + ge->rx.computed = ge->ry.computed; + } + + ((SPObject *)arc)->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); +} + +static NR::Point sp_arc_ry_get(SPItem *item) +{ + SPGenericEllipse *ge = SP_GENERICELLIPSE(item); + + return (NR::Point(ge->cx.computed, ge->cy.computed) - NR::Point(0, ge->ry.computed)); +} + +static void +sp_arc_rx_click(SPItem *item, guint state) +{ + SPGenericEllipse *ge = SP_GENERICELLIPSE(item); + + if (state & GDK_CONTROL_MASK) { + ge->ry.computed = ge->rx.computed; + ((SPObject *)ge)->updateRepr(); + } +} + +static void +sp_arc_ry_click(SPItem *item, guint state) +{ + SPGenericEllipse *ge = SP_GENERICELLIPSE(item); + + if (state & GDK_CONTROL_MASK) { + ge->rx.computed = ge->ry.computed; + ((SPObject *)ge)->updateRepr(); + } +} + +static SPKnotHolder * +sp_arc_knot_holder(SPItem *item, SPDesktop *desktop) +{ + SPKnotHolder *knot_holder = sp_knot_holder_new(desktop, item, NULL); + + sp_knot_holder_add_full(knot_holder, sp_arc_rx_set, sp_arc_rx_get, sp_arc_rx_click, + SP_KNOT_SHAPE_SQUARE, SP_KNOT_MODE_XOR, + _("Adjust ellipse width, with Ctrl to make circle")); + sp_knot_holder_add_full(knot_holder, sp_arc_ry_set, sp_arc_ry_get, sp_arc_ry_click, + SP_KNOT_SHAPE_SQUARE, SP_KNOT_MODE_XOR, + _("Adjust ellipse height, with Ctrl to make circle")); + sp_knot_holder_add_full(knot_holder, sp_arc_start_set, sp_arc_start_get, sp_arc_startend_click, + SP_KNOT_SHAPE_CIRCLE, SP_KNOT_MODE_XOR, + _("Position the start point of the arc or segment; with Ctrl to snap angle; drag inside the ellipse for arc, outside for segment")); + sp_knot_holder_add_full(knot_holder, sp_arc_end_set, sp_arc_end_get, sp_arc_startend_click, + SP_KNOT_SHAPE_CIRCLE, SP_KNOT_MODE_XOR, + _("Position the end point of the arc or segment; with Ctrl to snap angle; drag inside the ellipse for arc, outside for segment")); + + sp_pat_knot_holder(item, knot_holder); + + return knot_holder; +} + +/* SPStar */ + +static void +sp_star_knot1_set(SPItem *item, NR::Point const &p, NR::Point const &origin, guint state) +{ + SPStar *star = SP_STAR(item); + + NR::Point d = p - star->center; + + double arg1 = atan2(d); + double darg1 = arg1 - star->arg[0]; + + if (state & GDK_MOD1_MASK) { + star->randomized = darg1/(star->arg[0] - star->arg[1]); + } else if (state & GDK_SHIFT_MASK) { + star->rounded = darg1/(star->arg[0] - star->arg[1]); + } else if (state & GDK_CONTROL_MASK) { + star->r[0] = L2(d); + } else { + star->r[0] = L2(d); + star->arg[0] = arg1; + star->arg[1] += darg1; + } + ((SPObject *)star)->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); +} + +static void +sp_star_knot2_set(SPItem *item, NR::Point const &p, NR::Point const &origin, guint state) +{ + SPStar *star = SP_STAR(item); + if (star->flatsided == false) { + NR::Point d = p - star->center; + + double arg1 = atan2(d); + double darg1 = arg1 - star->arg[1]; + + if (state & GDK_MOD1_MASK) { + star->randomized = darg1/(star->arg[0] - star->arg[1]); + } else if (state & GDK_SHIFT_MASK) { + star->rounded = fabs(darg1/(star->arg[0] - star->arg[1])); + } else if (state & GDK_CONTROL_MASK) { + star->r[1] = L2(d); + star->arg[1] = star->arg[0] + M_PI / star->sides; + } + else { + star->r[1] = L2(d); + star->arg[1] = atan2(d); + } + ((SPObject *)star)->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + } +} + +static NR::Point sp_star_knot1_get(SPItem *item) +{ + g_assert(item != NULL); + + SPStar *star = SP_STAR(item); + + return sp_star_get_xy(star, SP_STAR_POINT_KNOT1, 0); + +} + +static NR::Point sp_star_knot2_get(SPItem *item) +{ + g_assert(item != NULL); + + SPStar *star = SP_STAR(item); + + return sp_star_get_xy(star, SP_STAR_POINT_KNOT2, 0); +} + +static void +sp_star_knot_click(SPItem *item, guint state) +{ + SPStar *star = SP_STAR(item); + + if (state & GDK_MOD1_MASK) { + star->randomized = 0; + ((SPObject *)star)->updateRepr(); + } else if (state & GDK_SHIFT_MASK) { + star->rounded = 0; + ((SPObject *)star)->updateRepr(); + } else if (state & GDK_CONTROL_MASK) { + star->arg[1] = star->arg[0] + M_PI / star->sides; + ((SPObject *)star)->updateRepr(); + } +} + +static SPKnotHolder * +sp_star_knot_holder(SPItem *item, SPDesktop *desktop) +{ + /* we don't need to get parent knot_holder */ + SPKnotHolder *knot_holder = sp_knot_holder_new(desktop, item, NULL); + g_assert(item != NULL); + + SPStar *star = SP_STAR(item); + + sp_knot_holder_add(knot_holder, sp_star_knot1_set, sp_star_knot1_get, sp_star_knot_click, + _("Adjust the tip radius of the star or polygon; with Shift to round; with Alt to randomize")); + if (star->flatsided == false) + sp_knot_holder_add(knot_holder, sp_star_knot2_set, sp_star_knot2_get, sp_star_knot_click, + _("Adjust the base radius of the star; with Ctrl to keep star rays radial (no skew); with Shift to round; with Alt to randomize")); + + sp_pat_knot_holder(item, knot_holder); + + return knot_holder; +} + +/* SPSpiral */ + +/* + * set attributes via inner (t=t0) knot point: + * [default] increase/decrease inner point + * [shift] increase/decrease inner and outer arg synchronizely + * [control] constrain inner arg to round per PI/4 + */ +static void +sp_spiral_inner_set(SPItem *item, NR::Point const &p, NR::Point const &origin, guint state) +{ + int snaps = prefs_get_int_attribute("options.rotationsnapsperpi", "value", 12); + + SPSpiral *spiral = SP_SPIRAL(item); + + gdouble dx = p[NR::X] - spiral->cx; + gdouble dy = p[NR::Y] - spiral->cy; + + if (state & GDK_MOD1_MASK) { + // adjust divergence by vertical drag, relative to rad + double new_exp = (spiral->rad + dy)/(spiral->rad); + spiral->exp = new_exp > 0? new_exp : 0; + } else { + // roll/unroll from inside + gdouble arg_t0; + sp_spiral_get_polar(spiral, spiral->t0, NULL, &arg_t0); + + gdouble arg_tmp = atan2(dy, dx) - arg_t0; + gdouble arg_t0_new = arg_tmp - floor((arg_tmp+M_PI)/(2.0*M_PI))*2.0*M_PI + arg_t0; + spiral->t0 = (arg_t0_new - spiral->arg) / (2.0*M_PI*spiral->revo); + + /* round inner arg per PI/snaps, if CTRL is pressed */ + if ( ( state & GDK_CONTROL_MASK ) + && ( fabs(spiral->revo) > SP_EPSILON_2 ) + && ( snaps != 0 ) ) { + gdouble arg = 2.0*M_PI*spiral->revo*spiral->t0 + spiral->arg; + spiral->t0 = (sp_round(arg, M_PI/snaps) - spiral->arg)/(2.0*M_PI*spiral->revo); + } + + spiral->t0 = CLAMP(spiral->t0, 0.0, 0.999); + } + + ((SPObject *)spiral)->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); +} + +/* + * set attributes via outer (t=1) knot point: + * [default] increase/decrease revolution factor + * [control] constrain inner arg to round per PI/4 + */ +static void +sp_spiral_outer_set(SPItem *item, NR::Point const &p, NR::Point const &origin, guint state) +{ + int snaps = prefs_get_int_attribute("options.rotationsnapsperpi", "value", 12); + + SPSpiral *spiral = SP_SPIRAL(item); + + gdouble dx = p[NR::X] - spiral->cx; + gdouble dy = p[NR::Y] - spiral->cy; + + if (state & GDK_SHIFT_MASK) { // rotate without roll/unroll + spiral->arg = atan2(dy, dx) - 2.0*M_PI*spiral->revo; + if (!(state & GDK_MOD1_MASK)) { + // if alt not pressed, change also rad; otherwise it is locked + spiral->rad = MAX(hypot(dx, dy), 0.001); + } + if ( ( state & GDK_CONTROL_MASK ) + && snaps ) { + spiral->arg = sp_round(spiral->arg, M_PI/snaps); + } + } else { // roll/unroll + // arg of the spiral outer end + double arg_1; + sp_spiral_get_polar(spiral, 1, NULL, &arg_1); + + // its fractional part after the whole turns are subtracted + double arg_r = arg_1 - sp_round(arg_1, 2.0*M_PI); + + // arg of the mouse point relative to spiral center + double mouse_angle = atan2(dy, dx); + if (mouse_angle < 0) + mouse_angle += 2*M_PI; + + // snap if ctrl + if ( ( state & GDK_CONTROL_MASK ) && snaps ) { + mouse_angle = sp_round(mouse_angle, M_PI/snaps); + } + + // by how much we want to rotate the outer point + double diff = mouse_angle - arg_r; + if (diff > M_PI) + diff -= 2*M_PI; + else if (diff < -M_PI) + diff += 2*M_PI; + + // calculate the new rad; + // the value of t corresponding to the angle arg_1 + diff: + double t_temp = ((arg_1 + diff) - spiral->arg)/(2*M_PI*spiral->revo); + // the rad at that t: + double rad_new = 0; + if (t_temp > spiral->t0) + sp_spiral_get_polar(spiral, t_temp, &rad_new, NULL); + + // change the revo (converting diff from radians to the number of turns) + spiral->revo += diff/(2*M_PI); + if (spiral->revo < 1e-3) + spiral->revo = 1e-3; + + // if alt not pressed and the values are sane, change the rad + if (!(state & GDK_MOD1_MASK) && rad_new > 1e-3 && rad_new/spiral->rad < 2) { + // adjust t0 too so that the inner point stays unmoved + double r0; + sp_spiral_get_polar(spiral, spiral->t0, &r0, NULL); + spiral->rad = rad_new; + spiral->t0 = pow(r0 / spiral->rad, 1.0/spiral->exp); + } + if (!isFinite(spiral->t0)) spiral->t0 = 0.0; + spiral->t0 = CLAMP(spiral->t0, 0.0, 0.999); + } + + ((SPObject *)spiral)->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); +} + +static NR::Point sp_spiral_inner_get(SPItem *item) +{ + SPSpiral *spiral = SP_SPIRAL(item); + + return sp_spiral_get_xy(spiral, spiral->t0); +} + +static NR::Point sp_spiral_outer_get(SPItem *item) +{ + SPSpiral *spiral = SP_SPIRAL(item); + + return sp_spiral_get_xy(spiral, 1.0); +} + +static void +sp_spiral_inner_click(SPItem *item, guint state) +{ + SPSpiral *spiral = SP_SPIRAL(item); + + if (state & GDK_MOD1_MASK) { + spiral->exp = 1; + ((SPObject *)spiral)->updateRepr(); + } else if (state & GDK_SHIFT_MASK) { + spiral->t0 = 0; + ((SPObject *)spiral)->updateRepr(); + } +} + +static SPKnotHolder * +sp_spiral_knot_holder(SPItem *item, SPDesktop *desktop) +{ + SPKnotHolder *knot_holder = sp_knot_holder_new(desktop, item, NULL); + + sp_knot_holder_add(knot_holder, sp_spiral_inner_set, sp_spiral_inner_get, sp_spiral_inner_click, + _("Roll/unroll the spiral from inside; with Ctrl to snap angle; with Alt to converge/diverge")); + sp_knot_holder_add(knot_holder, sp_spiral_outer_set, sp_spiral_outer_get, NULL, + _("Roll/unroll the spiral from outside; with Ctrl to snap angle; with Shift to scale/rotate")); + + sp_pat_knot_holder(item, knot_holder); + + return knot_holder; +} + +/* SPOffset */ + +static void +sp_offset_offset_set(SPItem *item, NR::Point const &p, NR::Point const &origin, guint state) +{ + SPOffset *offset = SP_OFFSET(item); + + offset->rad = sp_offset_distance_to_original(offset, p); + offset->knot = p; + offset->knotSet = true; + + ((SPObject *)offset)->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); +} + + +static NR::Point sp_offset_offset_get(SPItem *item) +{ + SPOffset *offset = SP_OFFSET(item); + + NR::Point np; + sp_offset_top_point(offset,&np); + return np; +} + +static SPKnotHolder * +sp_offset_knot_holder(SPItem *item, SPDesktop *desktop) +{ + SPKnotHolder *knot_holder = sp_knot_holder_new(desktop, item, NULL); + + sp_knot_holder_add(knot_holder, sp_offset_offset_set, sp_offset_offset_get, NULL, + _("Adjust the offset distance")); + + sp_pat_knot_holder(item, knot_holder); + + return knot_holder; +} + +static SPKnotHolder * +sp_path_knot_holder(SPItem *item, SPDesktop *desktop) // FIXME: eliminate, instead make a pattern-drag similar to gradient-drag +{ + if ((SP_OBJECT(item)->style->fill.type == SP_PAINT_TYPE_PAINTSERVER) + && SP_IS_PATTERN(SP_STYLE_FILL_SERVER(SP_OBJECT(item)->style))) + { + SPKnotHolder *knot_holder = sp_knot_holder_new(desktop, item, NULL); + + sp_pat_knot_holder(item, knot_holder); + + return knot_holder; + } + return NULL; +} + +static void +sp_pat_knot_holder(SPItem *item, SPKnotHolder *knot_holder) +{ + if ((SP_OBJECT(item)->style->fill.type == SP_PAINT_TYPE_PAINTSERVER) + && SP_IS_PATTERN(SP_STYLE_FILL_SERVER(SP_OBJECT(item)->style))) + { + sp_knot_holder_add_full(knot_holder, sp_pattern_xy_set, sp_pattern_xy_get, NULL, SP_KNOT_SHAPE_CROSS, SP_KNOT_MODE_XOR, + // TRANSLATORS: This refers to the pattern that's inside the object + _("Move the pattern fill inside the object")); + sp_knot_holder_add_full(knot_holder, sp_pattern_scale_set, sp_pattern_scale_get, NULL, SP_KNOT_SHAPE_SQUARE, SP_KNOT_MODE_XOR, + _("Scale the pattern fill uniformly")); + sp_knot_holder_add_full(knot_holder, sp_pattern_angle_set, sp_pattern_angle_get, NULL, SP_KNOT_SHAPE_CIRCLE, SP_KNOT_MODE_XOR, + _("Rotate the pattern fill; with Ctrl to snap angle")); + } +} + +static NR::Point sp_flowtext_corner_get(SPItem *item) +{ + SPRect *rect = SP_RECT(item); + + return NR::Point(rect->x.computed + rect->width.computed, rect->y.computed + rect->height.computed); +} + +static void +sp_flowtext_corner_set(SPItem *item, NR::Point const &p, NR::Point const &origin, guint state) +{ + SPRect *rect = SP_RECT(item); + + sp_rect_wh_set_internal(rect, p, origin, state); +} + +static SPKnotHolder * +sp_flowtext_knot_holder(SPItem *item, SPDesktop *desktop) +{ + SPKnotHolder *knot_holder = sp_knot_holder_new(desktop, SP_FLOWTEXT(item)->get_frame(NULL), NULL); + + sp_knot_holder_add(knot_holder, sp_flowtext_corner_set, sp_flowtext_corner_get, NULL, + _("Drag to resize the flowed text frame")); + + return knot_holder; +} + + +/* + 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:textwidth=99 : diff --git a/src/object-edit.h b/src/object-edit.h new file mode 100644 index 000000000..9fdc2365f --- /dev/null +++ b/src/object-edit.h @@ -0,0 +1,29 @@ +#ifndef __SP_OBJECT_EDIT_H__ +#define __SP_OBJECT_EDIT_H__ + +/* + * Node editing extension to objects + * + * Authors: + * Lauris Kaplinski + * Mitsuru Oka + * + * Licensed under GNU GPL + */ + +#include "knotholder.h" + +SPKnotHolder *sp_item_knot_holder (SPItem *item, SPDesktop *desktop); + +#endif + +/* + 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:textwidth=99 : diff --git a/src/object-hierarchy.cpp b/src/object-hierarchy.cpp new file mode 100644 index 000000000..30f13e49a --- /dev/null +++ b/src/object-hierarchy.cpp @@ -0,0 +1,213 @@ +/** \file + * Object hierarchy implementation. + * + * Authors: + * MenTaLguY + * + * Copyright (C) 2004 MenTaLguY + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "sp-object.h" +#include "object-hierarchy.h" + +namespace Inkscape { + +/** + * Create new object hierarchy. + * \param top The first entry if non-NULL. + */ +ObjectHierarchy::ObjectHierarchy(SPObject *top) { + if (top) { + _addBottom(top); + } +} + +ObjectHierarchy::~ObjectHierarchy() { + _clear(); +} + +/** + * Remove all entries. + */ +void ObjectHierarchy::clear() { + _clear(); + _changed_signal.emit(NULL, NULL); +} + +/** + * Trim or expand hierarchy on top such that object becomes top entry. + */ +void ObjectHierarchy::setTop(SPObject *object) { + g_return_if_fail(object != NULL); + + if ( top() == object ) { + return; + } + + if (!top()) { + _addTop(object); + } else if (object->isAncestorOf(top())) { + _addTop(object, top()); + } else if ( object == bottom() || object->isAncestorOf(bottom()) ) { + _trimAbove(object); + } else { + _clear(); + _addTop(object); + } + + _changed_signal.emit(top(), bottom()); +} + +/** + * Add hierarchy from junior's parent to senior to this + * hierarchy's top. + */ +void ObjectHierarchy::_addTop(SPObject *senior, SPObject *junior) { + g_assert(junior != NULL); + g_assert(senior != NULL); + + SPObject *object=SP_OBJECT_PARENT(junior); + do { + _addTop(object); + object = SP_OBJECT_PARENT(object); + } while ( object != senior ); +} + +/** + * Add object to top of hierarchy. + * \pre object!=NULL + */ +void ObjectHierarchy::_addTop(SPObject *object) { + g_assert(object != NULL); + _hierarchy.push_back(_attach(object)); + _added_signal.emit(object); +} + +/** + * Remove all objects above limit from hierarchy. + */ +void ObjectHierarchy::_trimAbove(SPObject *limit) { + while ( !_hierarchy.empty() && _hierarchy.back().object != limit ) { + SPObject *object=_hierarchy.back().object; + + sp_object_ref(object, NULL); + _detach(_hierarchy.back()); + _hierarchy.pop_back(); + _removed_signal.emit(object); + sp_object_unref(object, NULL); + } +} + +/** + * Trim or expand hierarchy at bottom such that object becomes bottom entry. + */ +void ObjectHierarchy::setBottom(SPObject *object) { + g_return_if_fail(object != NULL); + + if ( bottom() == object ) { + return; + } + + if (!top()) { + _addBottom(object); + } else if (bottom()->isAncestorOf(object)) { + _addBottom(bottom(), object); + } else if ( top() == object ) { + _trimBelow(top()); + } else if (top()->isAncestorOf(object)) { + if (object->isAncestorOf(bottom())) { + _trimBelow(object); + } else { // object is a sibling or cousin of bottom() + SPObject *saved_top=top(); + sp_object_ref(saved_top, NULL); + _clear(); + _addBottom(saved_top); + _addBottom(saved_top, object); + sp_object_unref(saved_top, NULL); + } + } else { + _clear(); + _addBottom(object); + } + + _changed_signal.emit(top(), bottom()); +} + +/** + * Remove all objects under given object. + * \param limit If NULL, remove all. + */ +void ObjectHierarchy::_trimBelow(SPObject *limit) { + while ( !_hierarchy.empty() && _hierarchy.front().object != limit ) { + SPObject *object=_hierarchy.front().object; + sp_object_ref(object, NULL); + _detach(_hierarchy.front()); + _hierarchy.pop_front(); + _removed_signal.emit(object); + sp_object_unref(object, NULL); + } +} + +/** + * Add hierarchy from senior to junior to this hierarchy's bottom. + */ +void ObjectHierarchy::_addBottom(SPObject *senior, SPObject *junior) { + g_assert(junior != NULL); + g_assert(senior != NULL); + + if ( junior != senior ) { + _addBottom(senior, SP_OBJECT_PARENT(junior)); + _addBottom(junior); + } +} + +/** + * Add object at bottom of hierarchy. + * \pre object!=NULL + */ +void ObjectHierarchy::_addBottom(SPObject *object) { + g_assert(object != NULL); + _hierarchy.push_front(_attach(object)); + _added_signal.emit(object); +} + +void ObjectHierarchy::_trim_for_release(SPObject *object, ObjectHierarchy *hier) +{ + hier->_trimBelow(object); + g_assert(!hier->_hierarchy.empty()); + g_assert(hier->_hierarchy.front().object == object); + + sp_object_ref(object, NULL); + hier->_detach(hier->_hierarchy.front()); + hier->_hierarchy.pop_front(); + hier->_removed_signal.emit(object); + sp_object_unref(object, NULL); + + hier->_changed_signal.emit(hier->top(), hier->bottom()); +} + +ObjectHierarchy::Record ObjectHierarchy::_attach(SPObject *object) { + sp_object_ref(object, NULL); + gulong id = g_signal_connect(G_OBJECT(object), "release", GCallback(&ObjectHierarchy::_trim_for_release), this); + return Record(object, id); +} + +void ObjectHierarchy::_detach(ObjectHierarchy::Record const &rec) { + g_signal_handler_disconnect(G_OBJECT(rec.object), rec.handler_id); + sp_object_unref(rec.object, NULL); +} + +} + +/* + 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:textwidth=99 : diff --git a/src/object-hierarchy.h b/src/object-hierarchy.h new file mode 100644 index 000000000..92da163ea --- /dev/null +++ b/src/object-hierarchy.h @@ -0,0 +1,119 @@ +/** \file + * Inkscape::ObjectHierarchy - tracks a hierarchy of active SPObjects + * + * Authors: + * MenTaLguY + * + * Copyright (C) 2004 MenTaLguY + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifndef SEEN_INKSCAPE_OBJECT_HIERARCHY_H +#define SEEN_INKSCAPE_OBJECT_HIERARCHY_H + +#include +#include +#include +#include +#include + +class SPObject; + +namespace Inkscape { + +/** + * An Inkscape::ObjectHierarchy is useful for situations where one wishes + * to keep a reference to an SPObject, but fall back on one of its ancestors + * when that object is removed. + * + * That cannot be accomplished simply by hooking the "release" signal of the + * SPObject, as by the time that signal is emitted, the object's parent + * field has already been cleared. + * + * There are also some subtle refcounting issues to take into account. + * + * @see SPObject + */ + +class ObjectHierarchy { +public: + ObjectHierarchy(SPObject *top=NULL); + ~ObjectHierarchy(); + + bool contains(SPObject *object); + + sigc::connection connectAdded(const sigc::slot &slot) { + return _added_signal.connect(slot); + } + sigc::connection connectRemoved(const sigc::slot &slot) { + return _removed_signal.connect(slot); + } + sigc::connection connectChanged(const sigc::slot &slot) + { + return _changed_signal.connect(slot); + } + + void clear(); + + SPObject *top() { + return !_hierarchy.empty() ? _hierarchy.back().object : NULL; + } + void setTop(SPObject *object); + + SPObject *bottom() { + return !_hierarchy.empty() ? _hierarchy.front().object : NULL; + } + void setBottom(SPObject *object); + +private: + struct Record { + Record(SPObject *o, gulong id) : object(o), handler_id(id) {} + + SPObject *object; + gulong handler_id; + }; + + ObjectHierarchy(ObjectHierarchy const &); // no copy + void operator=(ObjectHierarchy const &); // no assign + + /// @brief adds objects in range [senior, junior) to the top + void _addTop(SPObject *senior, SPObject *junior); + /// @brief adds one object to the top + void _addTop(SPObject *object); + /// @brief removes all objects above the limit object + void _trimAbove(SPObject *limit); + + /// @brief adds objects in range (senior, junior] to the bottom + void _addBottom(SPObject *senior, SPObject *junior); + /// @brief adds one object to the bottom + void _addBottom(SPObject *object); + /// @brief removes all objects below the limit object + void _trimBelow(SPObject *limit); + + Record _attach(SPObject *object); + void _detach(Record const &record); + + void _clear() { _trimBelow(NULL); } + + static void _trim_for_release(SPObject *released, ObjectHierarchy *hier); + + std::list _hierarchy; + sigc::signal _added_signal; + sigc::signal _removed_signal; + sigc::signal _changed_signal; +}; + +} + +#endif +/* + 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:textwidth=99 : diff --git a/src/object-snapper.cpp b/src/object-snapper.cpp new file mode 100644 index 000000000..6552cea96 --- /dev/null +++ b/src/object-snapper.cpp @@ -0,0 +1,176 @@ +/** + * \file object-snapper.cpp + * \brief Snapping things to objects. + * + * Authors: + * Carl Hetherington + * + * Copyright (C) 2005 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "libnr/n-art-bpath.h" +#include "libnr/nr-rect-ops.h" +#include "document.h" +#include "sp-namedview.h" +#include "sp-path.h" +#include "display/curve.h" +#include "desktop.h" +#include "inkscape.h" +#include "splivarot.h" + + +Inkscape::ObjectSnapper::ObjectSnapper(SPNamedView const *nv, NR::Coord const d) + : Snapper(nv, d), _snap_to_nodes(true), _snap_to_paths(true) +{ + +} + + +/** + * \param p Point we are trying to snap (desktop coordinates) + */ + +void Inkscape::ObjectSnapper::_findCandidates(std::list& c, + SPObject* r, + std::list const &it, + NR::Point const &p) const +{ + for (SPObject* o = r->children; o != NULL; o = o->next) { + if (SP_IS_ITEM(o)) { + + /* See if this item is on the ignore list */ + std::list::const_iterator i = it.begin(); + while (i != it.end() && *i != o) { + i++; + } + + if (i == it.end()) { + /* See if the item is within range */ + NR::Rect const b = NR::expand(sp_item_bbox_desktop(SP_ITEM(o)), -getDistance()); + if (b.contains(p)) { + c.push_back(SP_ITEM(o)); + } + } + } + + _findCandidates(c, o, it, p); + } +} + + +void Inkscape::ObjectSnapper::_snapNodes(Inkscape::SnappedPoint &s, + NR::Point const &p, + std::list const &cand) const +{ + /* FIXME: this seems like a hack. Perhaps Snappers should be + ** in SPDesktop rather than SPNamedView? + */ + SPDesktop const *desktop = SP_ACTIVE_DESKTOP; + + for (std::list::const_iterator i = cand.begin(); i != cand.end(); i++) { + if (SP_IS_SHAPE(*i)) { + + SPShape const *sh = SP_SHAPE(*i); + if (sh->curve) { + + int j = 0; + NR::Matrix const i2doc = sp_item_i2doc_affine(*i); + + while (sh->curve->bpath[j].code != NR_END) { + + /* Get this node in desktop coordinates */ + NArtBpath const &bp = sh->curve->bpath[j]; + NR::Point const n = desktop->doc2dt(bp.c(3) * i2doc); + + /* Try to snap to this node of the path */ + NR::Coord const dist = NR::L2(n - p); + if (dist < getDistance() && dist < s.getDistance()) { + s = SnappedPoint(n, dist); + } + + j++; + } + } + } + } +} + + +void Inkscape::ObjectSnapper::_snapPaths(Inkscape::SnappedPoint &s, + NR::Point const &p, + std::list const &cand) const +{ + /* FIXME: this seems like a hack. Perhaps Snappers should be + ** in SPDesktop rather than SPNamedView? + */ + SPDesktop const *desktop = SP_ACTIVE_DESKTOP; + + NR::Point const p_doc = desktop->dt2doc(p); + + for (std::list::const_iterator i = cand.begin(); i != cand.end(); i++) { + + /* Transform the requested snap point to this item's coordinates */ + NR::Matrix const i2doc = sp_item_i2doc_affine(*i); + NR::Point const p_it = p_doc * i2doc.inverse(); + + /* Look for the nearest position on this SPItem to our snap point */ + NR::Maybe const o = get_nearest_position_on_Path(*i, p_it); + if (o != NR::Nothing() && o.assume().t >= 0 && o.assume().t <= 1) { + + /* Convert the nearest point back to desktop coordinates */ + NR::Point const o_it = get_point_on_Path(*i, o.assume().piece, o.assume().t); + NR::Point const o_dt = desktop->doc2dt(o_it * i2doc); + + NR::Coord const dist = NR::L2(o_dt - p); + if (dist < getDistance() && dist < s.getDistance()) { + s = SnappedPoint(o_dt, dist); + } + } + } + +} + + +Inkscape::SnappedPoint Inkscape::ObjectSnapper::_doFreeSnap(NR::Point const &p, + std::list const &it) const +{ + /* Get a list of all the SPItems that we will try to snap to */ + std::list cand; + _findCandidates(cand, sp_document_root(_named_view->document), it, p); + + SnappedPoint s(p, NR_HUGE); + + if (_snap_to_nodes) { + _snapNodes(s, p, cand); + } + if (_snap_to_paths) { + _snapPaths(s, p, cand); + } + + return s; +} + + + +Inkscape::SnappedPoint Inkscape::ObjectSnapper::_doConstrainedSnap(NR::Point const &p, + NR::Point const &c, + std::list const &it) const +{ + /* FIXME: this needs implementing properly; I think we have to do the + ** intersection of c with the objects. + */ + return _doFreeSnap(p, it); +} + +/* + 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 : diff --git a/src/object-snapper.h b/src/object-snapper.h new file mode 100644 index 000000000..189e96e3e --- /dev/null +++ b/src/object-snapper.h @@ -0,0 +1,68 @@ +#ifndef SEEN_OBJECT_SNAPPER_H +#define SEEN_OBJECT_SNAPPER_H + +/** + * \file object-snapper.h + * \brief Snapping things to objects. + * + * Authors: + * Carl Hetherington + * + * Copyright (C) 2005 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "snapper.h" + +struct SPNamedView; +struct SPItem; +struct SPObject; + +namespace Inkscape +{ + +class ObjectSnapper : public Snapper +{ +public: + ObjectSnapper(SPNamedView const *nv, NR::Coord const d); + + void setSnapToNodes(bool s) { + _snap_to_nodes = s; + } + + bool getSnapToNodes() const { + return _snap_to_nodes; + } + + void setSnapToPaths(bool s) { + _snap_to_paths = s; + } + + bool getSnapToPaths() const { + return _snap_to_paths; + } + +private: + SnappedPoint _doFreeSnap(NR::Point const &p, + std::list const &it) const; + + SnappedPoint _doConstrainedSnap(NR::Point const &p, + NR::Point const &c, + std::list const &it) const; + + void _findCandidates(std::list& c, + SPObject* r, + std::list const &it, + NR::Point const &p) const; + + void _snapNodes(Inkscape::SnappedPoint &s, NR::Point const &p, std::list const &cand) const; + void _snapPaths(Inkscape::SnappedPoint &s, NR::Point const &p, std::list const &cand) const; + + bool _snap_to_nodes; + bool _snap_to_paths; +}; + +} + +#endif diff --git a/src/object-ui.cpp b/src/object-ui.cpp new file mode 100644 index 000000000..a55a8f500 --- /dev/null +++ b/src/object-ui.cpp @@ -0,0 +1,351 @@ +#define __SP_OBJECT_UI_C__ + +/* + * Unser-interface related object extension + * + * Authors: + * Lauris Kaplinski + * + * This code is in public domain + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "object-ui.h" +#include "xml/repr.h" + +static void sp_object_type_menu(GType type, SPObject *object, SPDesktop *desktop, GtkMenu *menu); + +/* Append object-specific part to context menu */ + +void +sp_object_menu(SPObject *object, SPDesktop *desktop, GtkMenu *menu) +{ + GObjectClass *klass; + klass = G_OBJECT_GET_CLASS(object); + while (G_TYPE_CHECK_CLASS_TYPE((klass), SP_TYPE_OBJECT)) { + GType type; + type = G_TYPE_FROM_CLASS(klass); + sp_object_type_menu(type, object, desktop, menu); + klass = (GObjectClass*)g_type_class_peek_parent(klass); + } +} + +/* Implementation */ + +#include + +#include + +#include "sp-anchor.h" +#include "sp-image.h" + +#include "document.h" +#include "desktop-handles.h" +#include "selection.h" + +#include "dialogs/item-properties.h" +#include "dialogs/object-attributes.h" +#include "dialogs/object-properties.h" + +#include "sp-path.h" + + +static void sp_item_menu(SPObject *object, SPDesktop *desktop, GtkMenu *menu); +static void sp_group_menu(SPObject *object, SPDesktop *desktop, GtkMenu *menu); +static void sp_anchor_menu(SPObject *object, SPDesktop *desktop, GtkMenu *menu); +static void sp_image_menu(SPObject *object, SPDesktop *desktop, GtkMenu *menu); +static void sp_shape_menu(SPObject *object, SPDesktop *desktop, GtkMenu *menu); + +static void +sp_object_type_menu(GType type, SPObject *object, SPDesktop *desktop, GtkMenu *menu) +{ + static GHashTable *t2m = NULL; + void (* handler)(SPObject *object, SPDesktop *desktop, GtkMenu *menu); + if (!t2m) { + t2m = g_hash_table_new(NULL, NULL); + g_hash_table_insert(t2m, GUINT_TO_POINTER(SP_TYPE_ITEM), (void*)sp_item_menu); + g_hash_table_insert(t2m, GUINT_TO_POINTER(SP_TYPE_GROUP), (void*)sp_group_menu); + g_hash_table_insert(t2m, GUINT_TO_POINTER(SP_TYPE_ANCHOR), (void*)sp_anchor_menu); + g_hash_table_insert(t2m, GUINT_TO_POINTER(SP_TYPE_IMAGE), (void*)sp_image_menu); + g_hash_table_insert(t2m, GUINT_TO_POINTER(SP_TYPE_SHAPE), (void*)sp_shape_menu); + } + handler = (void (*)(SPObject*, SPDesktop*, GtkMenu*))g_hash_table_lookup(t2m, GUINT_TO_POINTER(type)); + if (handler) handler(object, desktop, menu); +} + +/* SPItem */ + +static void sp_item_properties(GtkMenuItem *menuitem, SPItem *item); +static void sp_item_select_this(GtkMenuItem *menuitem, SPItem *item); +static void sp_item_create_link(GtkMenuItem *menuitem, SPItem *item); + +/* Generate context menu item section */ + +static void +sp_item_menu(SPObject *object, SPDesktop *desktop, GtkMenu *m) +{ + SPItem *item; + GtkWidget *w; + + item = (SPItem *) object; + + /* Item dialog */ + w = gtk_menu_item_new_with_mnemonic(_("Object _Properties")); + gtk_object_set_data(GTK_OBJECT(w), "desktop", desktop); + gtk_signal_connect(GTK_OBJECT(w), "activate", GTK_SIGNAL_FUNC(sp_item_properties), item); + gtk_widget_show(w); + gtk_menu_append(GTK_MENU(m), w); + /* Separator */ + w = gtk_menu_item_new(); + gtk_widget_show(w); + gtk_menu_append(GTK_MENU(m), w); + /* Select item */ + w = gtk_menu_item_new_with_mnemonic(_("_Select This")); + if (SP_DT_SELECTION(desktop)->includes(item)) { + gtk_widget_set_sensitive(w, FALSE); + } else { + gtk_object_set_data(GTK_OBJECT(w), "desktop", desktop); + gtk_signal_connect(GTK_OBJECT(w), "activate", GTK_SIGNAL_FUNC(sp_item_select_this), item); + } + gtk_widget_show(w); + gtk_menu_append(GTK_MENU(m), w); + /* Create link */ + w = gtk_menu_item_new_with_mnemonic(_("_Create Link")); + gtk_object_set_data(GTK_OBJECT(w), "desktop", desktop); + gtk_signal_connect(GTK_OBJECT(w), "activate", GTK_SIGNAL_FUNC(sp_item_create_link), item); + gtk_widget_set_sensitive(w, !SP_IS_ANCHOR(item)); + gtk_widget_show(w); + gtk_menu_append(GTK_MENU(m), w); +} + +static void +sp_item_properties(GtkMenuItem *menuitem, SPItem *item) +{ + SPDesktop *desktop; + + g_assert(SP_IS_ITEM(item)); + + desktop = (SPDesktop*)gtk_object_get_data(GTK_OBJECT(menuitem), "desktop"); + g_return_if_fail(desktop != NULL); + + SP_DT_SELECTION(desktop)->set(item); + + sp_item_dialog(); +} + +static void +sp_item_select_this(GtkMenuItem *menuitem, SPItem *item) +{ + SPDesktop *desktop; + + g_assert(SP_IS_ITEM(item)); + + desktop = (SPDesktop*)gtk_object_get_data(GTK_OBJECT(menuitem), "desktop"); + g_return_if_fail(desktop != NULL); + + SP_DT_SELECTION(desktop)->set(item); +} + +static void +sp_item_create_link(GtkMenuItem *menuitem, SPItem *item) +{ + g_assert(SP_IS_ITEM(item)); + g_assert(!SP_IS_ANCHOR(item)); + + SPDesktop *desktop = (SPDesktop*)gtk_object_get_data(GTK_OBJECT(menuitem), "desktop"); + g_return_if_fail(desktop != NULL); + + Inkscape::XML::Node *repr = sp_repr_new("svg:a"); + SP_OBJECT_REPR(SP_OBJECT_PARENT(item))->addChild(repr, SP_OBJECT_REPR(item)); + SPObject *object = SP_OBJECT_DOCUMENT(item)->getObjectByRepr(repr); + g_return_if_fail(SP_IS_ANCHOR(object)); + + const char *id = SP_OBJECT_REPR(item)->attribute("id"); + Inkscape::XML::Node *child = SP_OBJECT_REPR(item)->duplicate(); + SP_OBJECT(item)->deleteObject(false); + repr->addChild(child, NULL); + child->setAttribute("id", id); + sp_document_done(SP_OBJECT_DOCUMENT(object)); + + sp_object_attributes_dialog(object, "SPAnchor"); + + SP_DT_SELECTION(desktop)->set(SP_ITEM(object)); +} + +/* SPGroup */ + +static void sp_item_group_ungroup_activate(GtkMenuItem *menuitem, SPGroup *group); + +static void +sp_group_menu(SPObject *object, SPDesktop *desktop, GtkMenu *menu) +{ + SPItem *item=SP_ITEM(object); + GtkWidget *w; + + /* "Ungroup" */ + w = gtk_menu_item_new_with_mnemonic(_("_Ungroup")); + gtk_object_set_data(GTK_OBJECT(w), "desktop", desktop); + gtk_signal_connect(GTK_OBJECT(w), "activate", GTK_SIGNAL_FUNC(sp_item_group_ungroup_activate), item); + gtk_widget_show(w); + gtk_menu_append(GTK_MENU(menu), w); +} + +static void +sp_item_group_ungroup_activate(GtkMenuItem *menuitem, SPGroup *group) +{ + SPDesktop *desktop; + GSList *children; + + g_assert(SP_IS_GROUP(group)); + + desktop = (SPDesktop*)gtk_object_get_data(GTK_OBJECT(menuitem), "desktop"); + g_return_if_fail(desktop != NULL); + + children = NULL; + sp_item_group_ungroup(group, &children); + + SP_DT_SELECTION(desktop)->setList(children); + g_slist_free(children); +} + +/* SPAnchor */ + +static void sp_anchor_link_properties(GtkMenuItem *menuitem, SPAnchor *anchor); +static void sp_anchor_link_follow(GtkMenuItem *menuitem, SPAnchor *anchor); +static void sp_anchor_link_remove(GtkMenuItem *menuitem, SPAnchor *anchor); + +static void +sp_anchor_menu(SPObject *object, SPDesktop *desktop, GtkMenu *m) +{ + SPItem *item; + GtkWidget *w; + + item = (SPItem *) object; + + /* Link dialog */ + w = gtk_menu_item_new_with_mnemonic(_("Link _Properties")); + gtk_object_set_data(GTK_OBJECT(w), "desktop", desktop); + gtk_signal_connect(GTK_OBJECT(w), "activate", GTK_SIGNAL_FUNC(sp_anchor_link_properties), item); + gtk_widget_show(w); + gtk_menu_append(GTK_MENU(m), w); + /* Separator */ + w = gtk_menu_item_new(); + gtk_widget_show(w); + gtk_menu_append(GTK_MENU(m), w); + /* Select item */ + w = gtk_menu_item_new_with_mnemonic(_("_Follow Link")); + gtk_signal_connect(GTK_OBJECT(w), "activate", GTK_SIGNAL_FUNC(sp_anchor_link_follow), item); + gtk_widget_show(w); + gtk_menu_append(GTK_MENU(m), w); + /* Reset transformations */ + w = gtk_menu_item_new_with_mnemonic(_("_Remove Link")); + gtk_object_set_data(GTK_OBJECT(w), "desktop", desktop); + gtk_signal_connect(GTK_OBJECT(w), "activate", GTK_SIGNAL_FUNC(sp_anchor_link_remove), item); + gtk_widget_show(w); + gtk_menu_append(GTK_MENU(m), w); +} + +static void +sp_anchor_link_properties(GtkMenuItem *menuitem, SPAnchor *anchor) +{ + sp_object_attributes_dialog(SP_OBJECT(anchor), "Link"); +} + +static void +sp_anchor_link_follow(GtkMenuItem *menuitem, SPAnchor *anchor) +{ + g_return_if_fail(anchor != NULL); + g_return_if_fail(SP_IS_ANCHOR(anchor)); + + /* shell out to an external browser here */ +} + +static void +sp_anchor_link_remove(GtkMenuItem *menuitem, SPAnchor *anchor) +{ + GSList *children; + + g_return_if_fail(anchor != NULL); + g_return_if_fail(SP_IS_ANCHOR(anchor)); + + children = NULL; + sp_item_group_ungroup(SP_GROUP(anchor), &children); + + g_slist_free(children); +} + +/* Image */ + +static void sp_image_image_properties(GtkMenuItem *menuitem, SPAnchor *anchor); + +static void +sp_image_menu(SPObject *object, SPDesktop *desktop, GtkMenu *m) +{ + SPItem *item; + GtkWidget *w; + + item = (SPItem *) object; + + /* Link dialog */ + w = gtk_menu_item_new_with_mnemonic(_("Image _Properties")); + gtk_object_set_data(GTK_OBJECT(w), "desktop", desktop); + gtk_signal_connect(GTK_OBJECT(w), "activate", GTK_SIGNAL_FUNC(sp_image_image_properties), item); + gtk_widget_show(w); + gtk_menu_append(GTK_MENU(m), w); +} + +static void +sp_image_image_properties(GtkMenuItem *menuitem, SPAnchor *anchor) +{ + sp_object_attributes_dialog(SP_OBJECT(anchor), "Image"); +} + +/* SPShape */ + +static void +sp_shape_fill_settings(GtkMenuItem *menuitem, SPItem *item) +{ + SPDesktop *desktop; + + g_assert(SP_IS_ITEM(item)); + + desktop = (SPDesktop*)gtk_object_get_data(GTK_OBJECT(menuitem), "desktop"); + g_return_if_fail(desktop != NULL); + + if (SP_DT_SELECTION(desktop)->isEmpty()) { + SP_DT_SELECTION(desktop)->set(item); + } + + sp_object_properties_dialog(); +} + +static void +sp_shape_menu(SPObject *object, SPDesktop *desktop, GtkMenu *m) +{ + SPItem *item; + GtkWidget *w; + + item = (SPItem *) object; + + /* Item dialog */ + w = gtk_menu_item_new_with_mnemonic(_("_Fill and Stroke")); + gtk_object_set_data(GTK_OBJECT(w), "desktop", desktop); + gtk_signal_connect(GTK_OBJECT(w), "activate", GTK_SIGNAL_FUNC(sp_shape_fill_settings), item); + gtk_widget_show(w); + gtk_menu_append(GTK_MENU(m), w); +} + + +/* + 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:textwidth=99 : diff --git a/src/object-ui.h b/src/object-ui.h new file mode 100644 index 000000000..3624b4d2e --- /dev/null +++ b/src/object-ui.h @@ -0,0 +1,32 @@ +#ifndef __SP_OBJECT_UI_H__ +#define __SP_OBJECT_UI_H__ + +/* + * Unser-interface related object extension + * + * Authors: + * Lauris Kaplinski + * + * This code is in public domain + */ + +#include + +#include "forward.h" + +/* Append object-specific part to context menu */ + +void sp_object_menu (SPObject *object, SPDesktop *desktop, GtkMenu *menu); + +#endif + +/* + 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:textwidth=99 : diff --git a/src/path-chemistry.cpp b/src/path-chemistry.cpp new file mode 100644 index 000000000..6a5d876d6 --- /dev/null +++ b/src/path-chemistry.cpp @@ -0,0 +1,369 @@ +#define __SP_PATH_CHEMISTRY_C__ + +/* + * Here are handlers for modifying selections, specific to paths + * + * Authors: + * Lauris Kaplinski + * bulia byak + * + * Copyright (C) 1999-2004 Authors + * Copyright (C) 2001-2002 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifdef HAVE_CONFIG_H +# include +#endif +#include "xml/repr.h" +#include "svg/svg.h" +#include "display/curve.h" +#include +#include "sp-path.h" +#include "sp-text.h" +#include "sp-flowtext.h" +#include "libnr/nr-path.h" +#include "text-editing.h" +#include "style.h" +#include "inkscape.h" +#include "document.h" +#include "message-stack.h" +#include "selection.h" +#include "desktop-handles.h" + +/* Helper functions for sp_selected_path_to_curves */ +static void sp_selected_path_to_curves0 (gboolean do_document_done, guint32 text_grouping_policy); +static Inkscape::XML::Node * sp_selected_item_to_curved_repr(SPItem * item, guint32 text_grouping_policy); +enum { + /* Not used yet. This is the placeholder of Lauris's idea. */ + SP_TOCURVE_INTERACTIVE = 1 << 0, + SP_TOCURVE_GROUPING_BY_WORD = 1 << 1, + SP_TOCURVE_GROUPING_BY_LINE = 1 << 2, + SP_TOCURVE_GROUPING_BY_WHOLE = 1 << 3 +}; + +void +sp_selected_path_combine (void) +{ + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + + Inkscape::Selection *selection = SP_DT_SELECTION (desktop); + GSList *items = (GSList *) selection->itemList(); + + if (g_slist_length (items) < 2) { + SP_DT_MSGSTACK(desktop)->flash(Inkscape::WARNING_MESSAGE, _("Select at least two objects to combine.")); + return; + } + + for (GSList *i = items; i != NULL; i = i->next) { + SPItem *item = (SPItem *) i->data; + if (!SP_IS_SHAPE (item) && !SP_IS_TEXT(item)) { + SP_DT_MSGSTACK(desktop)->flash(Inkscape::WARNING_MESSAGE, _("At least one of the objects is not a path, cannot combine.")); + return; + } + } + + Inkscape::XML::Node *parent = SP_OBJECT_REPR ((SPItem *) items->data)->parent(); + for (GSList *i = items; i != NULL; i = i->next) { + if ( SP_OBJECT_REPR ((SPItem *) i->data)->parent() != parent ) { + SP_DT_MSGSTACK(desktop)->flash(Inkscape::ERROR_MESSAGE, _("You cannot combine objects from different groups or layers.")); + return; + } + } + + sp_selected_path_to_curves0 (FALSE, 0); + + items = (GSList *) selection->itemList(); + + items = g_slist_copy (items); + + items = g_slist_sort (items, (GCompareFunc) sp_item_repr_compare_position); + + // remember the position of the topmost object + gint topmost = (SP_OBJECT_REPR ((SPItem *) g_slist_last(items)->data))->position(); + + // remember the id of the bottomost object + const char *id = SP_OBJECT_REPR ((SPItem *) items->data)->attribute("id"); + + // FIXME: merge styles of combined objects instead of using the first one's style + gchar *style = g_strdup (SP_OBJECT_REPR ((SPItem *) items->data)->attribute("style")); + + GString *dstring = g_string_new(""); + for (GSList *i = items; i != NULL; i = i->next) { + + SPPath *path = (SPPath *) i->data; + SPCurve *c = sp_shape_get_curve (SP_SHAPE (path)); + + NArtBpath *abp = nr_artpath_affine(c->bpath, SP_ITEM(path)->transform); + sp_curve_unref (c); + gchar *str = sp_svg_write_path (abp); + nr_free (abp); + + dstring = g_string_append(dstring, str); + g_free (str); + + // if this is the bottommost object, + if (!strcmp (SP_OBJECT_REPR (path)->attribute("id"), id)) { + // delete it so that its clones don't get alerted; this object will be restored shortly, with the same id + SP_OBJECT (path)->deleteObject(false); + } else { + // delete the object for real, so that its clones can take appropriate action + SP_OBJECT (path)->deleteObject(); + } + + topmost --; + } + + g_slist_free (items); + + Inkscape::XML::Node *repr = sp_repr_new ("svg:path"); + + // restore id + repr->setAttribute("id", id); + + repr->setAttribute("style", style); + g_free (style); + + repr->setAttribute("d", dstring->str); + g_string_free (dstring, TRUE); + + // add the new group to the group members' common parent + parent->appendChild(repr); + + // move to the position of the topmost, reduced by the number of deleted items + repr->setPosition(topmost > 0 ? topmost + 1 : 0); + + sp_document_done (SP_DT_DOCUMENT (desktop)); + + selection->set(repr); + + Inkscape::GC::release(repr); +} + +void +sp_selected_path_break_apart (void) +{ + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + + Inkscape::Selection *selection = SP_DT_SELECTION (desktop); + + if (selection->isEmpty()) { + SP_DT_MSGSTACK(desktop)->flash(Inkscape::WARNING_MESSAGE, _("Select path(s) to break apart.")); + return; + } + + bool did = false; + + for (GSList *items = g_slist_copy((GSList *) selection->itemList()); + items != NULL; + items = items->next) { + + SPItem *item = (SPItem *) items->data; + + if (!SP_IS_PATH (item)) + continue; + + SPPath *path = SP_PATH (item); + + SPCurve *curve = sp_shape_get_curve (SP_SHAPE (path)); + if (curve == NULL) + continue; + + did = true; + + Inkscape::XML::Node *parent = SP_OBJECT_REPR (item)->parent(); + gint pos = SP_OBJECT_REPR (item)->position(); + const char *id = SP_OBJECT_REPR (item)->attribute("id"); + + gchar *style = g_strdup (SP_OBJECT (item)->repr->attribute("style")); + + NArtBpath *abp = nr_artpath_affine (curve->bpath, (SP_ITEM (path))->transform); + + sp_curve_unref (curve); + + // it's going to resurrect as one of the pieces, so we delete without advertisement + SP_OBJECT (item)->deleteObject(false); + + curve = sp_curve_new_from_bpath (abp); + g_assert (curve != NULL); + + GSList *list = sp_curve_split (curve); + + sp_curve_unref (curve); + + for (GSList *l = g_slist_reverse(list); l != NULL; l = l->next) { + curve = (SPCurve *) l->data; + + Inkscape::XML::Node *repr = sp_repr_new ("svg:path"); + repr->setAttribute("style", style); + + gchar *str = sp_svg_write_path (curve->bpath); + repr->setAttribute("d", str); + g_free (str); + + // add the new repr to the parent + parent->appendChild(repr); + + // move to the saved position + repr->setPosition(pos > 0 ? pos : 0); + + // if it's the first one, restore id + if (l == list) + repr->setAttribute("id", id); + + selection->add(repr); + + Inkscape::GC::release(repr); + } + + g_slist_free (list); + g_free (style); + + } + + if (did) { + sp_document_done (SP_DT_DOCUMENT (desktop)); + } else { + SP_DT_MSGSTACK(desktop)->flash(Inkscape::ERROR_MESSAGE, _("No path(s) to break apart in the selection.")); + return; + } +} + +/* This function is an entry point from GUI */ +void +sp_selected_path_to_curves (void) +{ + sp_selected_path_to_curves0(TRUE, SP_TOCURVE_INTERACTIVE); +} + +static void +sp_selected_path_to_curves0 (gboolean interactive, guint32 text_grouping_policy) +{ + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + + Inkscape::Selection *selection = SP_DT_SELECTION (desktop); + + if (selection->isEmpty()) { + if (interactive) + SP_DT_MSGSTACK(desktop)->flash(Inkscape::WARNING_MESSAGE, _("Select object(s) to convert to path.")); + return; + } + + bool did = false; + + for (GSList *items = g_slist_copy((GSList *) selection->itemList()); + items != NULL; + items = items->next) { + + SPItem *item = SP_ITEM (items->data); + + Inkscape::XML::Node *repr = sp_selected_item_to_curved_repr (item, 0); + if (!repr) + continue; + + did = true; + + // remember the position of the item + gint pos = SP_OBJECT_REPR (item)->position(); + // remember parent + Inkscape::XML::Node *parent = SP_OBJECT_REPR (item)->parent(); + // remember id + const char *id = SP_OBJECT_REPR (item)->attribute("id"); + + selection->remove(item); + + // it's going to resurrect, so we delete without advertisement + SP_OBJECT (item)->deleteObject(false); + + // restore id + repr->setAttribute("id", id); + // add the new repr to the parent + parent->appendChild(repr); + // move to the saved position + repr->setPosition(pos > 0 ? pos : 0); + + selection->add(repr); + Inkscape::GC::release(repr); + } + + if (interactive) { + if (did) { + sp_document_done (SP_DT_DOCUMENT (desktop)); + } else { + SP_DT_MSGSTACK(desktop)->flash(Inkscape::ERROR_MESSAGE, _("No objects to convert to path in the selection.")); + return; + } + } +} + +static Inkscape::XML::Node * +sp_selected_item_to_curved_repr(SPItem * item, guint32 text_grouping_policy) +{ + if (!item) + return NULL; + + SPCurve *curve = NULL; + if (SP_IS_SHAPE (item)) { + curve = sp_shape_get_curve (SP_SHAPE (item)); + } else if (SP_IS_TEXT (item) || SP_IS_FLOWTEXT (item)) { + curve = te_get_layout(item)->convertToCurves (); + } + + if (!curve) + return NULL; + + Inkscape::XML::Node *repr = sp_repr_new ("svg:path"); + /* Transformation */ + repr->setAttribute("transform", SP_OBJECT_REPR (item)->attribute("transform")); + /* Style */ + gchar *style_str = sp_style_write_difference (SP_OBJECT_STYLE (item), + SP_OBJECT_STYLE (SP_OBJECT_PARENT (item))); + repr->setAttribute("style", style_str); + g_free (style_str); + + /* Definition */ + gchar *def_str = sp_svg_write_path (curve->bpath); + repr->setAttribute("d", def_str); + g_free (def_str); + sp_curve_unref (curve); + return repr; +} + +void +sp_selected_path_reverse () +{ + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + + Inkscape::Selection *selection = SP_DT_SELECTION (desktop); + GSList *items = (GSList *) selection->itemList(); + + if (g_slist_length (items) == 0) { + SP_DT_MSGSTACK(desktop)->flash(Inkscape::WARNING_MESSAGE, _("Select path(s) to reverse.")); + return; + } + + + bool did = false; + for (GSList *i = items; i != NULL; i = i->next) { + + if (!SP_IS_SHAPE (items->data)) + continue; + + did = true; + SPShape *shape = SP_SHAPE (items->data); + + SPCurve *rcurve = sp_curve_reverse (shape->curve); + + char *str = sp_svg_write_path (rcurve->bpath); + SP_OBJECT_REPR (shape)->setAttribute("d", str); + + sp_curve_unref (rcurve); + } + + if (did) { + sp_document_done (SP_DT_DOCUMENT (desktop)); + } else { + SP_DT_MSGSTACK(desktop)->flash(Inkscape::ERROR_MESSAGE, _("No paths to reverse in the selection.")); + } +} diff --git a/src/path-chemistry.h b/src/path-chemistry.h new file mode 100644 index 000000000..41187bbe1 --- /dev/null +++ b/src/path-chemistry.h @@ -0,0 +1,35 @@ +#ifndef __PATH_CHEMISTRY_H__ +#define __PATH_CHEMISTRY_H__ + +/* + * Here are handlers for modifying selections, specific to paths + * + * Authors: + * Lauris Kaplinski + * + * Copyright (C) 1999-2002 authors + * Copyright (C) 2001-2002 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "forward.h" + +void sp_selected_path_combine (void); +void sp_selected_path_break_apart (void); +void sp_selected_path_to_curves (void); + +void sp_selected_path_reverse (); + +#endif + +/* + 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:textwidth=99 : diff --git a/src/path-prefix.h b/src/path-prefix.h new file mode 100644 index 000000000..89bc6309c --- /dev/null +++ b/src/path-prefix.h @@ -0,0 +1,83 @@ +/* + * Separate the inkscape paths from the prefix code, as that is kind of + * a separate package (binreloc) + * http://autopackage.org/downloads.html + * + * Since the directories set up by autoconf end up in config.h, we can't + * _change_ them, since config.h isn't protected by a set of + * one-time-include directives and is repeatedly re-included by some + * chains of .h files. As a result, nothing should refer to those + * define'd directories, and instead should use only the paths defined here. + * + */ +#ifndef _PATH_PREFIX_H_ +#define _PATH_PREFIX_H_ + +#include "require-config.h" // INKSCAPE_DATADIR +#include "prefix.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#ifdef ENABLE_BINRELOC +# define INKSCAPE_APPICONDIR BR_DATADIR( "/pixmaps" ) +# define INKSCAPE_EXTENSIONDIR BR_DATADIR( "/inkscape/extensions" ) +# define INKSCAPE_GRADIENTSDIR BR_DATADIR( "/inkscape/gradients" ) +# define INKSCAPE_PIXMAPDIR BR_DATADIR( "/inkscape/icons" ) +# define INKSCAPE_MARKERSDIR BR_DATADIR( "/inkscape/markers" ) +# define INKSCAPE_PALETTESDIR BR_DATADIR( "/inkscape/palettes" ) +# define INKSCAPE_PATTERNSDIR BR_DATADIR( "/inkscape/patterns" ) +# define INKSCAPE_SCREENSDIR BR_DATADIR( "/inkscape/screens" ) +# define INKSCAPE_TUTORIALSDIR BR_DATADIR( "/inkscape/tutorials" ) +# define INKSCAPE_PLUGINDIR BR_LIBDIR( "/inkscape/plugins" ) +# define INKSCAPE_TEMPLATESDIR BR_DATADIR( "/inkscape/templates" ) +# define INKSCAPE_UIDIR BR_DATADIR( "/inkscape/ui" ) +#else +# ifdef WIN32 +# define INKSCAPE_APPICONDIR "pixmaps" +# define INKSCAPE_EXTENSIONDIR "share\\extensions" +# define INKSCAPE_GRADIENTSDIR "share\\gradients" +# define INKSCAPE_PIXMAPDIR "share\\icons" +# define INKSCAPE_MARKERSDIR "share\\markers" +# define INKSCAPE_PALETTESDIR "share\\palettes" +# define INKSCAPE_PATTERNSDIR "share\\patterns" +# define INKSCAPE_SCREENSDIR "share\\screens" +# define INKSCAPE_TUTORIALSDIR "share\\tutorials" +# define INKSCAPE_PLUGINDIR "plugins" +# define INKSCAPE_TEMPLATESDIR "share\\templates" +# define INKSCAPE_UIDIR INKSCAPE_DATADIR "\\share\\ui" +# elif defined ENABLE_OSX_APP_LOCATIONS +# define INKSCAPE_APPICONDIR "Contents/Resources/pixmaps" +# define INKSCAPE_EXTENSIONDIR "Contents/Resources/extensions" +# define INKSCAPE_GRADIENTSDIR "Contents/Resources/gradients" +# define INKSCAPE_PIXMAPDIR "Contents/Resources/icons" +# define INKSCAPE_MARKERSDIR "Contents/Resources/markers" +# define INKSCAPE_PALETTESDIR "Contents/Resources/palettes" +# define INKSCAPE_PATTERNSDIR "Contents/Resources/patterns" +# define INKSCAPE_SCREENSDIR "Contents/Resources/screens" +# define INKSCAPE_TUTORIALSDIR "Contents/Resources/tutorials" +# define INKSCAPE_PLUGINDIR "Contents/Resources/plugins" +# define INKSCAPE_TEMPLATESDIR "Contents/Resources/templates" +# define INKSCAPE_UIDIR "Contents/Resources/ui" +# else +# define INKSCAPE_APPICONDIR INKSCAPE_DATADIR "/pixmaps" +# define INKSCAPE_EXTENSIONDIR INKSCAPE_DATADIR "/inkscape/extensions" +# define INKSCAPE_GRADIENTSDIR INKSCAPE_DATADIR "/inkscape/gradients" +# define INKSCAPE_PIXMAPDIR INKSCAPE_DATADIR "/inkscape/icons" +# define INKSCAPE_MARKERSDIR INKSCAPE_DATADIR "/inkscape/markers" +# define INKSCAPE_PALETTESDIR INKSCAPE_DATADIR "/inkscape/palettes" +# define INKSCAPE_PATTERNSDIR INKSCAPE_DATADIR "/inkscape/patterns" +# define INKSCAPE_SCREENSDIR INKSCAPE_DATADIR "/inkscape/screens" +# define INKSCAPE_TUTORIALSDIR INKSCAPE_DATADIR "/inkscape/tutorials" +# define INKSCAPE_PLUGINDIR INKSCAPE_LIBDIR "/inkscape/plugins" +# define INKSCAPE_TEMPLATESDIR INKSCAPE_DATADIR "/inkscape/templates" +# define INKSCAPE_UIDIR INKSCAPE_DATADIR "/inkscape/ui" +# endif +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _PATH_PREFIX_H_ */ diff --git a/src/pen-context.cpp b/src/pen-context.cpp new file mode 100644 index 000000000..95593f25b --- /dev/null +++ b/src/pen-context.cpp @@ -0,0 +1,1084 @@ +/** \file + * Pen event context implementation. + */ + +/* + * Authors: + * Lauris Kaplinski + * bulia byak + * + * Copyright (C) 2000 Lauris Kaplinski + * Copyright (C) 2000-2001 Ximian, Inc. + * Copyright (C) 2002 Lauris Kaplinski + * Copyright (C) 2004 Monash University + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include + +#include "pen-context.h" +#include "sp-namedview.h" +#include "sp-metrics.h" +#include "desktop.h" +#include "desktop-handles.h" +#include "selection.h" +#include "draw-anchor.h" +#include "message-stack.h" +#include "message-context.h" +#include "prefs-utils.h" +#include "sp-path.h" + +#include "pixmaps/cursor-pen.xpm" +#include "display/canvas-bpath.h" +#include "display/sp-ctrlline.h" +#include "display/sodipodi-ctrl.h" +#include +#include "libnr/n-art-bpath.h" +#include "helper/units.h" +#include "macros.h" +#include "context-fns.h" + + +static void sp_pen_context_class_init(SPPenContextClass *klass); +static void sp_pen_context_init(SPPenContext *pc); +static void sp_pen_context_dispose(GObject *object); + +static void sp_pen_context_setup(SPEventContext *ec); +static void sp_pen_context_finish(SPEventContext *ec); +static void sp_pen_context_set(SPEventContext *ec, gchar const *key, gchar const *val); +static gint sp_pen_context_root_handler(SPEventContext *ec, GdkEvent *event); + +static void spdc_pen_set_initial_point(SPPenContext *pc, NR::Point const p); +static void spdc_pen_set_subsequent_point(SPPenContext *pc, NR::Point const p, bool statusbar); +static void spdc_pen_set_ctrl(SPPenContext *pc, NR::Point const p, guint state); +static void spdc_pen_finish_segment(SPPenContext *pc, NR::Point p, guint state); + +static void spdc_pen_finish(SPPenContext *pc, gboolean closed); + +static gint pen_handle_button_press(SPPenContext *const pc, GdkEventButton const &bevent); +static gint pen_handle_motion_notify(SPPenContext *const pc, GdkEventMotion const &mevent); +static gint pen_handle_button_release(SPPenContext *const pc, GdkEventButton const &revent); +static gint pen_handle_2button_press(SPPenContext *const pc); +static gint pen_handle_key_press(SPPenContext *const pc, GdkEvent *event); +static void spdc_reset_colors(SPPenContext *pc); + + +static NR::Point pen_drag_origin_w(0, 0); +static bool pen_within_tolerance = false; + +static SPDrawContextClass *pen_parent_class; + +/** + * Register SPPenContext with Gdk and return its type. + */ +GType +sp_pen_context_get_type(void) +{ + static GType type = 0; + if (!type) { + GTypeInfo info = { + sizeof(SPPenContextClass), + NULL, NULL, + (GClassInitFunc) sp_pen_context_class_init, + NULL, NULL, + sizeof(SPPenContext), + 4, + (GInstanceInitFunc) sp_pen_context_init, + NULL, /* value_table */ + }; + type = g_type_register_static(SP_TYPE_DRAW_CONTEXT, "SPPenContext", &info, (GTypeFlags)0); + } + return type; +} + +/** + * Initialize the SPPenContext vtable. + */ +static void +sp_pen_context_class_init(SPPenContextClass *klass) +{ + GObjectClass *object_class; + SPEventContextClass *event_context_class; + + object_class = (GObjectClass *) klass; + event_context_class = (SPEventContextClass *) klass; + + pen_parent_class = (SPDrawContextClass*)g_type_class_peek_parent(klass); + + object_class->dispose = sp_pen_context_dispose; + + event_context_class->setup = sp_pen_context_setup; + event_context_class->finish = sp_pen_context_finish; + event_context_class->set = sp_pen_context_set; + event_context_class->root_handler = sp_pen_context_root_handler; +} + +/** + * Callback to initialize SPPenContext object. + */ +static void +sp_pen_context_init(SPPenContext *pc) +{ + + SPEventContext *event_context = SP_EVENT_CONTEXT(pc); + + event_context->cursor_shape = cursor_pen_xpm; + event_context->hot_x = 4; + event_context->hot_y = 4; + + pc->npoints = 0; + pc->mode = SP_PEN_CONTEXT_MODE_CLICK; + pc->state = SP_PEN_CONTEXT_POINT; + + pc->c0 = NULL; + pc->c1 = NULL; + pc->cl0 = NULL; + pc->cl1 = NULL; +} + +/** + * Callback to destroy the SPPenContext object's members and itself. + */ +static void +sp_pen_context_dispose(GObject *object) +{ + SPPenContext *pc; + + pc = SP_PEN_CONTEXT(object); + + if (pc->c0) { + gtk_object_destroy(GTK_OBJECT(pc->c0)); + pc->c0 = NULL; + } + if (pc->c1) { + gtk_object_destroy(GTK_OBJECT(pc->c1)); + pc->c1 = NULL; + } + if (pc->cl0) { + gtk_object_destroy(GTK_OBJECT(pc->cl0)); + pc->cl0 = NULL; + } + if (pc->cl1) { + gtk_object_destroy(GTK_OBJECT(pc->cl1)); + pc->cl1 = NULL; + } + + G_OBJECT_CLASS(pen_parent_class)->dispose(object); +} + +/** + * Callback to initialize SPPenContext object. + */ +static void +sp_pen_context_setup(SPEventContext *ec) +{ + SPPenContext *pc; + + pc = SP_PEN_CONTEXT(ec); + + if (((SPEventContextClass *) pen_parent_class)->setup) { + ((SPEventContextClass *) pen_parent_class)->setup(ec); + } + + /* Pen indicators */ + pc->c0 = sp_canvas_item_new(SP_DT_CONTROLS(SP_EVENT_CONTEXT_DESKTOP(ec)), SP_TYPE_CTRL, "shape", SP_CTRL_SHAPE_CIRCLE, + "size", 4.0, "filled", 0, "fill_color", 0xff00007f, "stroked", 1, "stroke_color", 0x0000ff7f, NULL); + pc->c1 = sp_canvas_item_new(SP_DT_CONTROLS(SP_EVENT_CONTEXT_DESKTOP(ec)), SP_TYPE_CTRL, "shape", SP_CTRL_SHAPE_CIRCLE, + "size", 4.0, "filled", 0, "fill_color", 0xff00007f, "stroked", 1, "stroke_color", 0x0000ff7f, NULL); + pc->cl0 = sp_canvas_item_new(SP_DT_CONTROLS(SP_EVENT_CONTEXT_DESKTOP(ec)), SP_TYPE_CTRLLINE, NULL); + sp_ctrlline_set_rgba32(SP_CTRLLINE(pc->cl0), 0x0000007f); + pc->cl1 = sp_canvas_item_new(SP_DT_CONTROLS(SP_EVENT_CONTEXT_DESKTOP(ec)), SP_TYPE_CTRLLINE, NULL); + sp_ctrlline_set_rgba32(SP_CTRLLINE(pc->cl1), 0x0000007f); + + sp_canvas_item_hide(pc->c0); + sp_canvas_item_hide(pc->c1); + sp_canvas_item_hide(pc->cl0); + sp_canvas_item_hide(pc->cl1); + + sp_event_context_read(ec, "mode"); + + pc->anchor_statusbar = false; + + if (prefs_get_int_attribute("tools.freehand.pen", "selcue", 0) != 0) { + ec->enableSelectionCue(); + } +} + +/** + * Finalization callback. + */ +static void +sp_pen_context_finish(SPEventContext *ec) +{ + spdc_pen_finish(SP_PEN_CONTEXT(ec), FALSE); + + if (((SPEventContextClass *) pen_parent_class)->finish) { + ((SPEventContextClass *) pen_parent_class)->finish(ec); + } +} + +/** + * Callback that sets key to value in pen context. + */ +static void +sp_pen_context_set(SPEventContext *ec, gchar const *key, gchar const *val) +{ + SPPenContext *pc = SP_PEN_CONTEXT(ec); + + if (!strcmp(key, "mode")) { + if ( val && !strcmp(val, "drag") ) { + pc->mode = SP_PEN_CONTEXT_MODE_DRAG; + } else { + pc->mode = SP_PEN_CONTEXT_MODE_CLICK; + } + } +} + +/** + * Snaps new node relative to the previous node. + */ +static void +spdc_endpoint_snap(SPPenContext const *const pc, NR::Point &p, guint const state) +{ + if (pc->npoints > 0) { + spdc_endpoint_snap_rotation(pc, p, pc->p[0], state); + } + + spdc_endpoint_snap_free(pc, p, state); +} + +/** + * Snaps new node's handle relative to the new node. + */ +static void +spdc_endpoint_snap_handle(SPPenContext const *const pc, NR::Point &p, guint const state) +{ + g_return_if_fail(( pc->npoints == 2 || + pc->npoints == 5 )); + + spdc_endpoint_snap_rotation(pc, p, pc->p[pc->npoints - 2], state); + spdc_endpoint_snap_free(pc, p, state); +} + +/** + * Callback to handle all pen events. + */ +static gint +sp_pen_context_root_handler(SPEventContext *ec, GdkEvent *event) +{ + SPPenContext *const pc = SP_PEN_CONTEXT(ec); + + gint ret = FALSE; + + switch (event->type) { + case GDK_BUTTON_PRESS: + ret = pen_handle_button_press(pc, event->button); + break; + + case GDK_MOTION_NOTIFY: + ret = pen_handle_motion_notify(pc, event->motion); + break; + + case GDK_BUTTON_RELEASE: + ret = pen_handle_button_release(pc, event->button); + break; + + case GDK_2BUTTON_PRESS: + ret = pen_handle_2button_press(pc); + break; + + case GDK_KEY_PRESS: + ret = pen_handle_key_press(pc, event); + break; + + default: + break; + } + + if (!ret) { + gint (*const parent_root_handler)(SPEventContext *, GdkEvent *) + = ((SPEventContextClass *) pen_parent_class)->root_handler; + if (parent_root_handler) { + ret = parent_root_handler(ec, event); + } + } + + return ret; +} + +/** + * Handle mouse button press event. + */ +static gint pen_handle_button_press(SPPenContext *const pc, GdkEventButton const &bevent) +{ + gint ret = FALSE; + if (bevent.button == 1) { + + SPDrawContext * const dc = SP_DRAW_CONTEXT(pc); + SPDesktop * const desktop = SP_EVENT_CONTEXT_DESKTOP(dc); + + if (Inkscape::have_viable_layer(desktop, dc->_message_context) == false) { + return TRUE; + } + + NR::Point const event_w(bevent.x, bevent.y); + pen_drag_origin_w = event_w; + pen_within_tolerance = true; + + /* Test whether we hit any anchor. */ + SPDrawAnchor * const anchor = spdc_test_inside(pc, event_w); + + NR::Point const event_dt(desktop->w2d(event_w)); + switch (pc->mode) { + case SP_PEN_CONTEXT_MODE_CLICK: + /* In click mode we add point on release */ + switch (pc->state) { + case SP_PEN_CONTEXT_POINT: + case SP_PEN_CONTEXT_CONTROL: + case SP_PEN_CONTEXT_CLOSE: + break; + case SP_PEN_CONTEXT_STOP: + /* This is allowed, if we just cancelled curve */ + pc->state = SP_PEN_CONTEXT_POINT; + break; + default: + break; + } + break; + case SP_PEN_CONTEXT_MODE_DRAG: + switch (pc->state) { + case SP_PEN_CONTEXT_STOP: + /* This is allowed, if we just cancelled curve */ + case SP_PEN_CONTEXT_POINT: + if (pc->npoints == 0) { + + /* Set start anchor */ + pc->sa = anchor; + NR::Point p; + if (anchor) { + + /* Adjust point to anchor if needed */ + p = anchor->dp; + desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Continuing selected path")); + + } else { + + // This is the first click of a new curve; deselect item so that + // this curve is not combined with it (unless it is drawn from its + // anchor, which is handled by the sibling branch above) + Inkscape::Selection * const selection = SP_DT_SELECTION(desktop); + if (!(bevent.state & GDK_SHIFT_MASK)) { + + selection->clear(); + desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Creating new path")); + + } else if (selection->singleItem() && SP_IS_PATH(selection->singleItem())) { + + desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Appending to selected path")); + } + + /* Create green anchor */ + p = event_dt; + spdc_endpoint_snap(pc, p, bevent.state); + pc->green_anchor = sp_draw_anchor_new(pc, pc->green_curve, TRUE, p); + } + spdc_pen_set_initial_point(pc, p); + } else { + + /* Set end anchor */ + pc->ea = anchor; + NR::Point p; + if (anchor) { + + p = anchor->dp; + // we hit an anchor, will finish the curve (either with or without closing) + // in release handler + pc->state = SP_PEN_CONTEXT_CLOSE; + + if (pc->green_anchor && pc->green_anchor->active) { + // we clicked on the current curve start, so close it even if + // we drag a handle away from it + dc->green_closed = TRUE; + } + ret = TRUE; + break; + + } else { + + p = event_dt; + spdc_endpoint_snap(pc, p, bevent.state); /* Snap node only if not hitting anchor. */ + spdc_pen_set_subsequent_point(pc, p, true); + } + + } + pc->state = SP_PEN_CONTEXT_CONTROL; + ret = TRUE; + break; + case SP_PEN_CONTEXT_CONTROL: + g_warning("Button down in CONTROL state"); + break; + case SP_PEN_CONTEXT_CLOSE: + g_warning("Button down in CLOSE state"); + break; + default: + break; + } + break; + default: + break; + } + } else if (bevent.button == 3) { + if (pc->npoints != 0) { + spdc_pen_finish(pc, FALSE); + ret = TRUE; + } + } + + return ret; +} + +/** + * Handle motion_notify event. + */ +static gint +pen_handle_motion_notify(SPPenContext *const pc, GdkEventMotion const &mevent) +{ + gint ret = FALSE; + + if (mevent.state & GDK_BUTTON2_MASK || mevent.state & GDK_BUTTON3_MASK) { + // allow middle-button scrolling + return FALSE; + } + + NR::Point const event_w(mevent.x, + mevent.y); + if (pen_within_tolerance) { + gint const tolerance = prefs_get_int_attribute_limited("options.dragtolerance", + "value", 0, 0, 100); + if ( NR::LInfty( event_w - pen_drag_origin_w ) < tolerance ) { + return FALSE; // Do not drag if we're within tolerance from origin. + } + } + // Once the user has moved farther than tolerance from the original location + // (indicating they intend to move the object, not click), then always process the + // motion notify coordinates as given (no snapping back to origin) + pen_within_tolerance = false; + + SPDesktop *const dt = pc->desktop; + if ( ( mevent.state & GDK_BUTTON1_MASK ) && !pc->grab ) { + /* Grab mouse, so release will not pass unnoticed */ + pc->grab = SP_CANVAS_ITEM(dt->acetate); + sp_canvas_item_grab(pc->grab, ( GDK_KEY_PRESS_MASK | GDK_BUTTON_PRESS_MASK | + GDK_BUTTON_RELEASE_MASK | + GDK_POINTER_MOTION_MASK ), + NULL, mevent.time); + } + + /* Find desktop coordinates */ + NR::Point p = dt->w2d(event_w); + + /* Test, whether we hit any anchor */ + SPDrawAnchor *anchor = spdc_test_inside(pc, event_w); + + switch (pc->mode) { + case SP_PEN_CONTEXT_MODE_CLICK: + switch (pc->state) { + case SP_PEN_CONTEXT_POINT: + if ( pc->npoints != 0 ) { + /* Only set point, if we are already appending */ + spdc_endpoint_snap(pc, p, mevent.state); + spdc_pen_set_subsequent_point(pc, p, true); + ret = TRUE; + } + break; + case SP_PEN_CONTEXT_CONTROL: + case SP_PEN_CONTEXT_CLOSE: + /* Placing controls is last operation in CLOSE state */ + spdc_endpoint_snap(pc, p, mevent.state); + spdc_pen_set_ctrl(pc, p, mevent.state); + ret = TRUE; + break; + case SP_PEN_CONTEXT_STOP: + /* This is perfectly valid */ + break; + default: + break; + } + break; + case SP_PEN_CONTEXT_MODE_DRAG: + switch (pc->state) { + case SP_PEN_CONTEXT_POINT: + if ( pc->npoints > 0 ) { + /* Only set point, if we are already appending */ + + if (!anchor) { /* Snap node only if not hitting anchor */ + spdc_endpoint_snap(pc, p, mevent.state); + } + + spdc_pen_set_subsequent_point(pc, p, !anchor); + + if (anchor && !pc->anchor_statusbar) { + pc->_message_context->set(Inkscape::NORMAL_MESSAGE, _("Click or click and drag to close and finish the path.")); + pc->anchor_statusbar = true; + } else if (!anchor && pc->anchor_statusbar) { + pc->_message_context->clear(); + pc->anchor_statusbar = false; + } + + ret = TRUE; + } else { + if (anchor && !pc->anchor_statusbar) { + pc->_message_context->set(Inkscape::NORMAL_MESSAGE, _("Click or click and drag to continue the path from this point.")); + pc->anchor_statusbar = true; + } else if (!anchor && pc->anchor_statusbar) { + pc->_message_context->clear(); + pc->anchor_statusbar = false; + } + } + break; + case SP_PEN_CONTEXT_CONTROL: + case SP_PEN_CONTEXT_CLOSE: + /* Placing controls is last operation in CLOSE state */ + + // snap the handle + spdc_endpoint_snap_handle(pc, p, mevent.state); + + spdc_pen_set_ctrl(pc, p, mevent.state); + ret = TRUE; + break; + case SP_PEN_CONTEXT_STOP: + /* This is perfectly valid */ + break; + default: + break; + } + break; + default: + break; + } + return ret; +} + +/** + * Handle mouse button release event. + */ +static gint +pen_handle_button_release(SPPenContext *const pc, GdkEventButton const &revent) +{ + gint ret = FALSE; + if ( revent.button == 1 ) { + + SPDrawContext *dc = SP_DRAW_CONTEXT (pc); + + NR::Point const event_w(revent.x, + revent.y); + /* Find desktop coordinates */ + NR::Point p = pc->desktop->w2d(event_w); + + /* Test whether we hit any anchor. */ + SPDrawAnchor *anchor = spdc_test_inside(pc, event_w); + + switch (pc->mode) { + case SP_PEN_CONTEXT_MODE_CLICK: + switch (pc->state) { + case SP_PEN_CONTEXT_POINT: + if ( pc->npoints == 0 ) { + /* Start new thread only with button release */ + if (anchor) { + p = anchor->dp; + } + pc->sa = anchor; + spdc_pen_set_initial_point(pc, p); + } else { + /* Set end anchor here */ + pc->ea = anchor; + if (anchor) { + p = anchor->dp; + } + } + pc->state = SP_PEN_CONTEXT_CONTROL; + ret = TRUE; + break; + case SP_PEN_CONTEXT_CONTROL: + /* End current segment */ + spdc_endpoint_snap(pc, p, revent.state); + spdc_pen_finish_segment(pc, p, revent.state); + pc->state = SP_PEN_CONTEXT_POINT; + ret = TRUE; + break; + case SP_PEN_CONTEXT_CLOSE: + /* End current segment */ + if (!anchor) { /* Snap node only if not hitting anchor */ + spdc_endpoint_snap(pc, p, revent.state); + } + spdc_pen_finish_segment(pc, p, revent.state); + spdc_pen_finish(pc, TRUE); + pc->state = SP_PEN_CONTEXT_POINT; + ret = TRUE; + break; + case SP_PEN_CONTEXT_STOP: + /* This is allowed, if we just cancelled curve */ + pc->state = SP_PEN_CONTEXT_POINT; + ret = TRUE; + break; + default: + break; + } + break; + case SP_PEN_CONTEXT_MODE_DRAG: + switch (pc->state) { + case SP_PEN_CONTEXT_POINT: + case SP_PEN_CONTEXT_CONTROL: + spdc_endpoint_snap(pc, p, revent.state); + spdc_pen_finish_segment(pc, p, revent.state); + break; + case SP_PEN_CONTEXT_CLOSE: + spdc_endpoint_snap(pc, p, revent.state); + spdc_pen_finish_segment(pc, p, revent.state); + if (pc->green_closed) { + // finishing at the start anchor, close curve + spdc_pen_finish(pc, TRUE); + } else { + // finishing at some other anchor, finish curve but not close + spdc_pen_finish(pc, FALSE); + } + break; + case SP_PEN_CONTEXT_STOP: + /* This is allowed, if we just cancelled curve */ + break; + default: + break; + } + pc->state = SP_PEN_CONTEXT_POINT; + ret = TRUE; + break; + default: + break; + } + + if (pc->grab) { + /* Release grab now */ + sp_canvas_item_ungrab(pc->grab, revent.time); + pc->grab = NULL; + } + + ret = TRUE; + + dc->green_closed = FALSE; + } + + return ret; +} + +static gint +pen_handle_2button_press(SPPenContext *const pc) +{ + gint ret = FALSE; + if (pc->npoints != 0) { + spdc_pen_finish(pc, FALSE); + ret = TRUE; + } + return ret; +} + +void +pen_lastpoint_move (SPPenContext *const pc, gdouble x, gdouble y) +{ + if (pc->npoints != 5) + return; + + // green + NArtBpath *const bpath = sp_curve_last_bpath(pc->green_curve); + if (bpath) { + if (bpath->code == NR_CURVETO) { + bpath->x2 += x; + bpath->y2 += y; + } + bpath->x3 += x; + bpath->y3 += y; + if (pc->green_bpaths && pc->green_bpaths->data) { + // remove old piecewise green canvasitems + while (pc->green_bpaths) { + gtk_object_destroy(GTK_OBJECT(pc->green_bpaths->data)); + pc->green_bpaths = g_slist_remove(pc->green_bpaths, pc->green_bpaths->data); + } + // one canvas bpath for all of green_curve + SPCanvasItem *cshape = sp_canvas_bpath_new(SP_DT_SKETCH(pc->desktop), pc->green_curve); + sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(cshape), pc->green_color, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); + sp_canvas_bpath_set_fill(SP_CANVAS_BPATH(cshape), 0, SP_WIND_RULE_NONZERO); + + pc->green_bpaths = g_slist_prepend(pc->green_bpaths, cshape); + } + } else { + // start anchor too + if (pc->green_anchor) { + pc->green_anchor->dp += NR::Point(x, y); + SP_CTRL(pc->green_anchor->ctrl)->moveto(pc->green_anchor->dp); + } + } + + // red + pc->p[0] += NR::Point(x, y); + pc->p[1] += NR::Point(x, y); + sp_curve_reset(pc->red_curve); + sp_curve_moveto(pc->red_curve, pc->p[0]); + sp_curve_curveto(pc->red_curve, pc->p[1], pc->p[2], pc->p[3]); + sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(pc->red_bpath), pc->red_curve); + + // handles + if (pc->p[0] != pc->p[1]) { + SP_CTRL(pc->c1)->moveto(pc->p[1]); + sp_ctrlline_set_coords(SP_CTRLLINE(pc->cl1), pc->p[0], pc->p[1]); + } + if (bpath && bpath->code == NR_CURVETO && NR::Point(bpath->x2, bpath->y2) != pc->p[0]) { + SP_CTRL(pc->c0)->moveto(NR::Point(bpath->x2, bpath->y2)); + sp_ctrlline_set_coords(SP_CTRLLINE(pc->cl0), NR::Point(bpath->x2, bpath->y2), pc->p[0]); + } +} + +void +pen_lastpoint_move_screen (SPPenContext *const pc, gdouble x, gdouble y) +{ + pen_lastpoint_move (pc, x / pc->desktop->current_zoom(), y / pc->desktop->current_zoom()); +} + +static gint +pen_handle_key_press(SPPenContext *const pc, GdkEvent *event) +{ + gint ret = FALSE; + gdouble const nudge = prefs_get_double_attribute_limited("options.nudgedistance", "value", 2, 0, 1000); // in px + + switch (get_group0_keyval (&event->key)) { + + case GDK_Left: // move last point left + case GDK_KP_Left: + case GDK_KP_4: + if (!MOD__CTRL) { // not ctrl + if (MOD__ALT) { // alt + if (MOD__SHIFT) pen_lastpoint_move_screen(pc, -10, 0); // shift + else pen_lastpoint_move_screen(pc, -1, 0); // no shift + } + else { // no alt + if (MOD__SHIFT) pen_lastpoint_move(pc, -10*nudge, 0); // shift + else pen_lastpoint_move(pc, -nudge, 0); // no shift + } + ret = TRUE; + } + break; + case GDK_Up: // move last point up + case GDK_KP_Up: + case GDK_KP_8: + if (!MOD__CTRL) { // not ctrl + if (MOD__ALT) { // alt + if (MOD__SHIFT) pen_lastpoint_move_screen(pc, 0, 10); // shift + else pen_lastpoint_move_screen(pc, 0, 1); // no shift + } + else { // no alt + if (MOD__SHIFT) pen_lastpoint_move(pc, 0, 10*nudge); // shift + else pen_lastpoint_move(pc, 0, nudge); // no shift + } + ret = TRUE; + } + break; + case GDK_Right: // move last point right + case GDK_KP_Right: + case GDK_KP_6: + if (!MOD__CTRL) { // not ctrl + if (MOD__ALT) { // alt + if (MOD__SHIFT) pen_lastpoint_move_screen(pc, 10, 0); // shift + else pen_lastpoint_move_screen(pc, 1, 0); // no shift + } + else { // no alt + if (MOD__SHIFT) pen_lastpoint_move(pc, 10*nudge, 0); // shift + else pen_lastpoint_move(pc, nudge, 0); // no shift + } + ret = TRUE; + } + break; + case GDK_Down: // move last point down + case GDK_KP_Down: + case GDK_KP_2: + if (!MOD__CTRL) { // not ctrl + if (MOD__ALT) { // alt + if (MOD__SHIFT) pen_lastpoint_move_screen(pc, 0, -10); // shift + else pen_lastpoint_move_screen(pc, 0, -1); // no shift + } + else { // no alt + if (MOD__SHIFT) pen_lastpoint_move(pc, 0, -10*nudge); // shift + else pen_lastpoint_move(pc, 0, -nudge); // no shift + } + ret = TRUE; + } + break; + + case GDK_Return: + case GDK_KP_Enter: + if (pc->npoints != 0) { + spdc_pen_finish(pc, FALSE); + ret = TRUE; + } + break; + case GDK_Escape: + if (pc->npoints != 0) { + // if drawing, cancel, otherwise pass it up for deselecting + pc->state = SP_PEN_CONTEXT_STOP; + spdc_reset_colors(pc); + sp_canvas_item_hide(pc->c0); + sp_canvas_item_hide(pc->c1); + sp_canvas_item_hide(pc->cl0); + sp_canvas_item_hide(pc->cl1); + ret = TRUE; + } + break; + case GDK_z: + case GDK_Z: + if (MOD__CTRL_ONLY && pc->npoints != 0) { + // if drawing, cancel, otherwise pass it up for undo + pc->state = SP_PEN_CONTEXT_STOP; + spdc_reset_colors(pc); + sp_canvas_item_hide(pc->c0); + sp_canvas_item_hide(pc->c1); + sp_canvas_item_hide(pc->cl0); + sp_canvas_item_hide(pc->cl1); + ret = TRUE; + } + break; + case GDK_BackSpace: + case GDK_Delete: + case GDK_KP_Delete: + if (sp_curve_is_empty(pc->green_curve)) { + /* Same as cancel */ + pc->state = SP_PEN_CONTEXT_STOP; + spdc_reset_colors(pc); + sp_canvas_item_hide(pc->c0); + sp_canvas_item_hide(pc->c1); + sp_canvas_item_hide(pc->cl0); + sp_canvas_item_hide(pc->cl1); + ret = TRUE; + } else { + /* Reset red curve */ + sp_curve_reset(pc->red_curve); + /* Destroy topmost green bpath */ + if (pc->green_bpaths) { + if (pc->green_bpaths->data) + gtk_object_destroy(GTK_OBJECT(pc->green_bpaths->data)); + pc->green_bpaths = g_slist_remove(pc->green_bpaths, pc->green_bpaths->data); + } + /* Get last segment */ + NArtBpath const *const p = SP_CURVE_BPATH(pc->green_curve); + gint const e = SP_CURVE_LENGTH(pc->green_curve); + if ( e < 2 ) { + g_warning("Green curve length is %d", e); + break; + } + pc->p[0] = p[e - 2].c(3); + pc->p[1] = p[e - 1].c(1); + NR::Point const pt(( pc->npoints < 4 + ? p[e - 1].c(3) + : pc->p[3] )); + pc->npoints = 2; + sp_curve_backspace(pc->green_curve); + sp_canvas_item_hide(pc->c0); + sp_canvas_item_hide(pc->c1); + sp_canvas_item_hide(pc->cl0); + sp_canvas_item_hide(pc->cl1); + pc->state = SP_PEN_CONTEXT_POINT; + spdc_pen_set_subsequent_point(pc, pt, true); + ret = TRUE; + } + break; + default: + break; + } + return ret; +} + +static void +spdc_reset_colors(SPPenContext *pc) +{ + /* Red */ + sp_curve_reset(pc->red_curve); + sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(pc->red_bpath), NULL); + /* Blue */ + sp_curve_reset(pc->blue_curve); + sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(pc->blue_bpath), NULL); + /* Green */ + while (pc->green_bpaths) { + gtk_object_destroy(GTK_OBJECT(pc->green_bpaths->data)); + pc->green_bpaths = g_slist_remove(pc->green_bpaths, pc->green_bpaths->data); + } + sp_curve_reset(pc->green_curve); + if (pc->green_anchor) { + pc->green_anchor = sp_draw_anchor_destroy(pc->green_anchor); + } + pc->sa = NULL; + pc->ea = NULL; + pc->npoints = 0; + pc->red_curve_is_valid = false; +} + + +static void +spdc_pen_set_initial_point(SPPenContext *const pc, NR::Point const p) +{ + g_assert( pc->npoints == 0 ); + + pc->p[0] = p; + pc->p[1] = p; + pc->npoints = 2; + sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(pc->red_bpath), NULL); +} + +static void +spdc_pen_set_subsequent_point(SPPenContext *const pc, NR::Point const p, bool statusbar) +{ + g_assert( pc->npoints != 0 ); + /* todo: Check callers to see whether 2 <= npoints is guaranteed. */ + + pc->p[2] = p; + pc->p[3] = p; + pc->p[4] = p; + pc->npoints = 5; + sp_curve_reset(pc->red_curve); + sp_curve_moveto(pc->red_curve, pc->p[0]); + bool is_curve; + if ( (pc->onlycurves) + || ( pc->p[1] != pc->p[0] ) ) + { + sp_curve_curveto(pc->red_curve, pc->p[1], p, p); + is_curve = true; + } else { + sp_curve_lineto(pc->red_curve, p); + is_curve = false; + } + sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(pc->red_bpath), pc->red_curve); + + if (statusbar) { + // status text + SPDesktop *desktop = SP_EVENT_CONTEXT(pc)->desktop; + NR::Point rel = p - pc->p[0]; + GString *dist = SP_PX_TO_METRIC_STRING(NR::L2(rel), desktop->namedview->getDefaultMetric()); + double angle = atan2(rel[NR::Y], rel[NR::X]) * 180 / M_PI; + if (prefs_get_int_attribute("options.compassangledisplay", "value", 0) != 0) + angle = angle_to_compass (angle); + pc->_message_context->setF(Inkscape::NORMAL_MESSAGE, _("%s: angle %3.2f°, distance %s; with Ctrl to snap angle, Enter to finish the path"), is_curve? "Curve segment" : "Line segment", angle, dist->str); + g_string_free(dist, FALSE); + } +} + +static void +spdc_pen_set_ctrl(SPPenContext *const pc, NR::Point const p, guint const state) +{ + sp_canvas_item_show(pc->c1); + sp_canvas_item_show(pc->cl1); + + if ( pc->npoints == 2 ) { + pc->p[1] = p; + sp_canvas_item_hide(pc->c0); + sp_canvas_item_hide(pc->cl0); + SP_CTRL(pc->c1)->moveto(pc->p[1]); + sp_ctrlline_set_coords(SP_CTRLLINE(pc->cl1), pc->p[0], pc->p[1]); + + // status text + SPDesktop *desktop = SP_EVENT_CONTEXT(pc)->desktop; + NR::Point rel = p - pc->p[0]; + GString *dist = SP_PX_TO_METRIC_STRING(NR::L2(rel), desktop->namedview->getDefaultMetric()); + double angle = atan2(rel[NR::Y], rel[NR::X]) * 180 / M_PI; + if (prefs_get_int_attribute("options.compassangledisplay", "value", 0) != 0) + angle = angle_to_compass (angle); + pc->_message_context->setF(Inkscape::NORMAL_MESSAGE, _("Curve handle: angle %3.2f°, length %s; with Ctrl to snap angle"), angle, dist->str); + g_string_free(dist, FALSE); + + } else if ( pc->npoints == 5 ) { + pc->p[4] = p; + sp_canvas_item_show(pc->c0); + sp_canvas_item_show(pc->cl0); + bool is_symm = false; + if ( ( ( pc->mode == SP_PEN_CONTEXT_MODE_CLICK ) && ( state & GDK_CONTROL_MASK ) ) || + ( ( pc->mode == SP_PEN_CONTEXT_MODE_DRAG ) && !( state & GDK_SHIFT_MASK ) ) ) { + NR::Point delta = p - pc->p[3]; + pc->p[2] = pc->p[3] - delta; + is_symm = true; + sp_curve_reset(pc->red_curve); + sp_curve_moveto(pc->red_curve, pc->p[0]); + sp_curve_curveto(pc->red_curve, pc->p[1], pc->p[2], pc->p[3]); + sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(pc->red_bpath), pc->red_curve); + } + SP_CTRL(pc->c0)->moveto(pc->p[2]); + sp_ctrlline_set_coords(SP_CTRLLINE(pc->cl0), pc->p[3], pc->p[2]); + SP_CTRL(pc->c1)->moveto(pc->p[4]); + sp_ctrlline_set_coords(SP_CTRLLINE(pc->cl1), pc->p[3], pc->p[4]); + + // status text + SPDesktop *desktop = SP_EVENT_CONTEXT(pc)->desktop; + NR::Point rel = p - pc->p[3]; + GString *dist = SP_PX_TO_METRIC_STRING(NR::L2(rel), desktop->namedview->getDefaultMetric()); + double angle = atan2(rel[NR::Y], rel[NR::X]) * 180 / M_PI; + if (prefs_get_int_attribute("options.compassangledisplay", "value", 0) != 0) + angle = angle_to_compass (angle); + pc->_message_context->setF(Inkscape::NORMAL_MESSAGE, _("%s: angle %3.2f°, length %s; with Ctrl to snap angle, with Shift to move this handle only"), is_symm? "Curve handle, symmetric" : "Curve handle", angle, dist->str); + g_string_free(dist, FALSE); + + } else { + g_warning("Something bad happened - npoints is %d", pc->npoints); + } +} + +static void +spdc_pen_finish_segment(SPPenContext *const pc, NR::Point const p, guint const state) +{ + if (!sp_curve_empty(pc->red_curve)) { + sp_curve_append_continuous(pc->green_curve, pc->red_curve, 0.0625); + SPCurve *curve = sp_curve_copy(pc->red_curve); + /// \todo fixme: + SPCanvasItem *cshape = sp_canvas_bpath_new(SP_DT_SKETCH(pc->desktop), curve); + sp_curve_unref(curve); + sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(cshape), pc->green_color, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); + + pc->green_bpaths = g_slist_prepend(pc->green_bpaths, cshape); + + pc->p[0] = pc->p[3]; + pc->p[1] = pc->p[4]; + pc->npoints = 2; + + sp_curve_reset(pc->red_curve); + } +} + +static void +spdc_pen_finish(SPPenContext *const pc, gboolean const closed) +{ + SPDesktop *const desktop = pc->desktop; + pc->_message_context->clear(); + desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Finishing pen")); + + sp_curve_reset(pc->red_curve); + spdc_concat_colors_and_flush(pc, closed); + pc->sa = NULL; + pc->ea = NULL; + + pc->npoints = 0; + pc->state = SP_PEN_CONTEXT_POINT; + + sp_canvas_item_hide(pc->c0); + sp_canvas_item_hide(pc->c1); + sp_canvas_item_hide(pc->cl0); + sp_canvas_item_hide(pc->cl1); + + if (pc->green_anchor) { + pc->green_anchor = sp_draw_anchor_destroy(pc->green_anchor); + } +} + + +/* + 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:textwidth=99 : diff --git a/src/pen-context.h b/src/pen-context.h new file mode 100644 index 000000000..d0392134b --- /dev/null +++ b/src/pen-context.h @@ -0,0 +1,62 @@ +#ifndef SEEN_PEN_CONTEXT_H +#define SEEN_PEN_CONTEXT_H + +/** \file + * SPPenContext: a context for pen tool events. + */ + +#include "draw-context.h" + + +#define SP_TYPE_PEN_CONTEXT (sp_pen_context_get_type()) +#define SP_PEN_CONTEXT(o) (G_TYPE_CHECK_INSTANCE_CAST((o), SP_TYPE_PEN_CONTEXT, SPPenContext)) +#define SP_PEN_CONTEXT_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), SP_TYPE_PEN_CONTEXT, SPPenContextClass)) +#define SP_IS_PEN_CONTEXT(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), SP_TYPE_PEN_CONTEXT)) +#define SP_IS_PEN_CONTEXT_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE((k), SP_TYPE_PEN_CONTEXT)) + +enum { + SP_PEN_CONTEXT_POINT, + SP_PEN_CONTEXT_CONTROL, + SP_PEN_CONTEXT_CLOSE, + SP_PEN_CONTEXT_STOP +}; + +enum { + SP_PEN_CONTEXT_MODE_CLICK, + SP_PEN_CONTEXT_MODE_DRAG +}; + +/** + * SPPenContext: a context for pen tool events. + */ +struct SPPenContext : public SPDrawContext { + NR::Point p[5]; + + /** \invar npoints in {0, 2, 5}. */ + gint npoints; + + unsigned int mode : 1; + unsigned int state : 2; + unsigned int onlycurves : 1; + + SPCanvasItem *c0, *c1, *cl0, *cl1; +}; + +/// The SPPenContext vtable (empty). +struct SPPenContextClass : public SPEventContextClass { }; + +GType sp_pen_context_get_type(); + + +#endif /* !SEEN_PEN_CONTEXT_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:encoding=utf-8:textwidth=99 : diff --git a/src/pencil-context.cpp b/src/pencil-context.cpp new file mode 100644 index 000000000..a75b4c561 --- /dev/null +++ b/src/pencil-context.cpp @@ -0,0 +1,591 @@ +/** \file + * Pencil event context implementation. + */ + +/* + * Authors: + * Lauris Kaplinski + * bulia byak + * + * Copyright (C) 2000 Lauris Kaplinski + * Copyright (C) 2000-2001 Ximian, Inc. + * Copyright (C) 2002 Lauris Kaplinski + * Copyright (C) 2004 Monash University + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include + +#include "pencil-context.h" +#include "desktop.h" +#include "desktop-handles.h" +#include "selection.h" +#include "draw-anchor.h" +#include "message-stack.h" +#include "message-context.h" +#include "modifier-fns.h" +#include "sp-path.h" +#include "prefs-utils.h" +#include "snap.h" +#include "pixmaps/cursor-pencil.xpm" +#include "display/bezier-utils.h" +#include "display/canvas-bpath.h" +#include +#include "libnr/in-svg-plane.h" +#include "libnr/n-art-bpath.h" +#include "context-fns.h" + +static void sp_pencil_context_class_init(SPPencilContextClass *klass); +static void sp_pencil_context_init(SPPencilContext *pc); +static void sp_pencil_context_setup(SPEventContext *ec); +static void sp_pencil_context_dispose(GObject *object); + +static gint sp_pencil_context_root_handler(SPEventContext *event_context, GdkEvent *event); +static gint pencil_handle_button_press(SPPencilContext *const pc, GdkEventButton const &bevent); +static gint pencil_handle_motion_notify(SPPencilContext *const pc, GdkEventMotion const &mevent); +static gint pencil_handle_button_release(SPPencilContext *const pc, GdkEventButton const &revent); +static gint pencil_handle_key_press(SPPencilContext *const pc, guint const keyval, guint const state); + +static void spdc_set_startpoint(SPPencilContext *pc, NR::Point const p); +static void spdc_set_endpoint(SPPencilContext *pc, NR::Point const p); +static void spdc_finish_endpoint(SPPencilContext *pc); +static void spdc_add_freehand_point(SPPencilContext *pc, NR::Point p, guint state); +static void fit_and_split(SPPencilContext *pc); + + +static SPDrawContextClass *pencil_parent_class; + +/** + * Register SPPencilContext class with Gdk and return its type number. + */ +GType +sp_pencil_context_get_type() +{ + static GType type = 0; + if (!type) { + GTypeInfo info = { + sizeof(SPPencilContextClass), + NULL, NULL, + (GClassInitFunc) sp_pencil_context_class_init, + NULL, NULL, + sizeof(SPPencilContext), + 4, + (GInstanceInitFunc) sp_pencil_context_init, + NULL, /* value_table */ + }; + type = g_type_register_static(SP_TYPE_DRAW_CONTEXT, "SPPencilContext", &info, (GTypeFlags)0); + } + return type; +} + +/** + * Initialize SPPencilContext vtable. + */ +static void +sp_pencil_context_class_init(SPPencilContextClass *klass) +{ + GObjectClass *object_class; + SPEventContextClass *event_context_class; + + object_class = (GObjectClass *) klass; + event_context_class = (SPEventContextClass *) klass; + + pencil_parent_class = (SPDrawContextClass*)g_type_class_peek_parent(klass); + + object_class->dispose = sp_pencil_context_dispose; + + event_context_class->setup = sp_pencil_context_setup; + event_context_class->root_handler = sp_pencil_context_root_handler; +} + +/** + * Callback to initialize SPPencilContext object. + */ +static void +sp_pencil_context_init(SPPencilContext *pc) +{ + SPEventContext *event_context = SP_EVENT_CONTEXT(pc); + + event_context->cursor_shape = cursor_pencil_xpm; + event_context->hot_x = 4; + event_context->hot_y = 4; + + pc->npoints = 0; + pc->state = SP_PENCIL_CONTEXT_IDLE; + pc->req_tangent = NR::Point(0, 0); +} + +/** + * Callback to setup SPPencilContext object. + */ +static void +sp_pencil_context_setup(SPEventContext *ec) +{ + if (prefs_get_int_attribute("tools.freehand.pencil", "selcue", 0) != 0) { + ec->enableSelectionCue(); + } + + if (((SPEventContextClass *) pencil_parent_class)->setup) { + ((SPEventContextClass *) pencil_parent_class)->setup(ec); + } + + SPPencilContext *const pc = SP_PENCIL_CONTEXT(ec); + pc->is_drawing = false; + + pc->anchor_statusbar = false; +} + +static void +sp_pencil_context_dispose(GObject *object) +{ + G_OBJECT_CLASS(pencil_parent_class)->dispose(object); +} + +/** Snaps new node relative to the previous node. */ +static void +spdc_endpoint_snap(SPPencilContext const *pc, NR::Point &p, guint const state) +{ + spdc_endpoint_snap_rotation(pc, p, pc->p[0], state); + spdc_endpoint_snap_free(pc, p, state); +} + +/** + * Callback for handling all pencil context events. + */ +gint +sp_pencil_context_root_handler(SPEventContext *const ec, GdkEvent *event) +{ + SPPencilContext *const pc = SP_PENCIL_CONTEXT(ec); + + gint ret = FALSE; + + switch (event->type) { + case GDK_BUTTON_PRESS: + ret = pencil_handle_button_press(pc, event->button); + break; + + case GDK_MOTION_NOTIFY: + ret = pencil_handle_motion_notify(pc, event->motion); + break; + + case GDK_BUTTON_RELEASE: + ret = pencil_handle_button_release(pc, event->button); + break; + + case GDK_KEY_PRESS: + ret = pencil_handle_key_press(pc, get_group0_keyval (&event->key), event->key.state); + break; + + default: + break; + } + + if (!ret) { + gint (*const parent_root_handler)(SPEventContext *, GdkEvent *) + = ((SPEventContextClass *) pencil_parent_class)->root_handler; + if (parent_root_handler) { + ret = parent_root_handler(ec, event); + } + } + + return ret; +} + +static gint +pencil_handle_button_press(SPPencilContext *const pc, GdkEventButton const &bevent) +{ + gint ret = FALSE; + if ( bevent.button == 1 ) { + + SPDrawContext *dc = SP_DRAW_CONTEXT (pc); + SPDesktop *desktop = SP_EVENT_CONTEXT_DESKTOP(dc); + Inkscape::Selection *selection = SP_DT_SELECTION(desktop); + + if (Inkscape::have_viable_layer(desktop, dc->_message_context) == false) { + return TRUE; + } + + NR::Point const button_w(bevent.x, bevent.y); + + /* Find desktop coordinates */ + NR::Point p = pc->desktop->w2d(button_w); + + /* Test whether we hit any anchor. */ + SPDrawAnchor *anchor = spdc_test_inside(pc, button_w); + + switch (pc->state) { + case SP_PENCIL_CONTEXT_ADDLINE: + /* Current segment will be finished with release */ + ret = TRUE; + break; + default: + /* Set first point of sequence */ + if (anchor) { + p = anchor->dp; + desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Continuing selected path")); + } else { + + if (!(bevent.state & GDK_SHIFT_MASK)) { + + // This is the first click of a new curve; deselect item so that + // this curve is not combined with it (unless it is drawn from its + // anchor, which is handled by the sibling branch above) + selection->clear(); + desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Creating new path")); + SnapManager const m(desktop->namedview); + p = m.freeSnap(Inkscape::Snapper::BBOX_POINT | Inkscape::Snapper::SNAP_POINT, p, NULL).getPoint(); + } else if (selection->singleItem() && SP_IS_PATH(selection->singleItem())) { + desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Appending to selected path")); + } + } + pc->sa = anchor; + spdc_set_startpoint(pc, p); + ret = TRUE; + break; + } + + pc->is_drawing = true; + } + return ret; +} + +static gint +pencil_handle_motion_notify(SPPencilContext *const pc, GdkEventMotion const &mevent) +{ + gint ret = FALSE; + SPDesktop *const dt = pc->desktop; + + if (mevent.state & GDK_BUTTON2_MASK || mevent.state & GDK_BUTTON3_MASK) { + // allow middle-button scrolling + return FALSE; + } + + if ( ( mevent.state & GDK_BUTTON1_MASK ) && !pc->grab && pc->is_drawing) { + /* Grab mouse, so release will not pass unnoticed */ + pc->grab = SP_CANVAS_ITEM(dt->acetate); + sp_canvas_item_grab(pc->grab, ( GDK_KEY_PRESS_MASK | GDK_BUTTON_PRESS_MASK | + GDK_BUTTON_RELEASE_MASK | + GDK_POINTER_MOTION_MASK ), + NULL, mevent.time); + } + + /* Find desktop coordinates */ + NR::Point p = dt->w2d(NR::Point(mevent.x, mevent.y)); + + /* Test whether we hit any anchor. */ + SPDrawAnchor *anchor = spdc_test_inside(pc, NR::Point(mevent.x, mevent.y)); + + switch (pc->state) { + case SP_PENCIL_CONTEXT_ADDLINE: + /* Set red endpoint */ + if (anchor) { + p = anchor->dp; + } else { + spdc_endpoint_snap(pc, p, mevent.state); + } + spdc_set_endpoint(pc, p); + ret = TRUE; + break; + default: + /* We may be idle or already freehand */ + if ( mevent.state & GDK_BUTTON1_MASK && pc->is_drawing ) { + pc->state = SP_PENCIL_CONTEXT_FREEHAND; + if ( !pc->sa && !pc->green_anchor ) { + /* Create green anchor */ + pc->green_anchor = sp_draw_anchor_new(pc, pc->green_curve, TRUE, pc->p[0]); + } + /** \todo + * fixme: I am not sure whether we want to snap to anchors + * in middle of freehand (Lauris) + */ + if (anchor) { + p = anchor->dp; + } else if ((mevent.state & GDK_SHIFT_MASK) == 0) { + SnapManager const m(dt->namedview); + p = m.freeSnap(Inkscape::Snapper::BBOX_POINT | Inkscape::Snapper::SNAP_POINT, p, NULL).getPoint(); + } + if ( pc->npoints != 0 ) { // buttonpress may have happened before we entered draw context! + spdc_add_freehand_point(pc, p, mevent.state); + ret = TRUE; + } + + if (anchor && !pc->anchor_statusbar) { + pc->_message_context->set(Inkscape::NORMAL_MESSAGE, _("Release here to close and finish the path.")); + pc->anchor_statusbar = true; + } else if (!anchor && pc->anchor_statusbar) { + pc->_message_context->clear(); + pc->anchor_statusbar = false; + } else if (!anchor) { + pc->_message_context->set(Inkscape::NORMAL_MESSAGE, _("Drawing a freehand path")); + } + + } else { + if (anchor && !pc->anchor_statusbar) { + pc->_message_context->set(Inkscape::NORMAL_MESSAGE, _("Drag to continue the path from this point.")); + pc->anchor_statusbar = true; + } else if (!anchor && pc->anchor_statusbar) { + pc->_message_context->clear(); + pc->anchor_statusbar = false; + } + } + break; + } + return ret; +} + +static gint +pencil_handle_button_release(SPPencilContext *const pc, GdkEventButton const &revent) +{ + gint ret = FALSE; + + if ( revent.button == 1 && pc->is_drawing) { + SPDesktop *const dt = pc->desktop; + + pc->is_drawing = false; + + /* Find desktop coordinates */ + NR::Point p = dt->w2d(NR::Point(revent.x, revent.y)); + + /* Test whether we hit any anchor. */ + SPDrawAnchor *anchor = spdc_test_inside(pc, NR::Point(revent.x, + revent.y)); + + switch (pc->state) { + case SP_PENCIL_CONTEXT_IDLE: + /* Releasing button in idle mode means single click */ + /* We have already set up start point/anchor in button_press */ + pc->state = SP_PENCIL_CONTEXT_ADDLINE; + ret = TRUE; + break; + case SP_PENCIL_CONTEXT_ADDLINE: + /* Finish segment now */ + if (anchor) { + p = anchor->dp; + } else { + spdc_endpoint_snap(pc, p, revent.state); + } + pc->ea = anchor; + spdc_set_endpoint(pc, p); + spdc_finish_endpoint(pc); + pc->state = SP_PENCIL_CONTEXT_IDLE; + ret = TRUE; + break; + case SP_PENCIL_CONTEXT_FREEHAND: + /* Finish segment now */ + /// \todo fixme: Clean up what follows (Lauris) + if (anchor) { + p = anchor->dp; + } + pc->ea = anchor; + /* Write curves to object */ + + dt->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Finishing freehand")); + + spdc_concat_colors_and_flush(pc, FALSE); + pc->sa = NULL; + pc->ea = NULL; + if (pc->green_anchor) { + pc->green_anchor = sp_draw_anchor_destroy(pc->green_anchor); + } + pc->state = SP_PENCIL_CONTEXT_IDLE; + ret = TRUE; + break; + default: + break; + } + + if (pc->grab) { + /* Release grab now */ + sp_canvas_item_ungrab(pc->grab, revent.time); + pc->grab = NULL; + } + + pc->grab = NULL; + ret = TRUE; + } + return ret; +} + +static gint +pencil_handle_key_press(SPPencilContext *const pc, guint const keyval, guint const state) +{ + gint ret = FALSE; + switch (keyval) { + case GDK_Up: + case GDK_Down: + case GDK_KP_Up: + case GDK_KP_Down: + // Prevent the zoom field from activation. + if (!mod_ctrl_only(state)) { + ret = TRUE; + } + break; + default: + break; + } + return ret; +} + +/** + * Reset points and set new starting point. + */ +static void +spdc_set_startpoint(SPPencilContext *const pc, NR::Point const p) +{ + pc->npoints = 0; + pc->red_curve_is_valid = false; + if (in_svg_plane(p)) { + pc->p[pc->npoints++] = p; + } +} + +/** + * Change moving endpoint position. + *
    + *
  • Ctrl constrains to moving to H/V direction, snapping in given direction. + *
  • Otherwise we snap freely to whatever attractors are available. + *
+ * + * Number of points is (re)set to 2 always, 2nd point is modified. + * We change RED curve. + */ +static void +spdc_set_endpoint(SPPencilContext *const pc, NR::Point const p) +{ + if (pc->npoints == 0) { + return; + /* May occur if first point wasn't in SVG plane (e.g. weird w2d transform, perhaps from bad + * zoom setting). + */ + } + g_return_if_fail( pc->npoints > 0 ); + + sp_curve_reset(pc->red_curve); + if ( ( p == pc->p[0] ) + || !in_svg_plane(p) ) + { + pc->npoints = 1; + } else { + pc->p[1] = p; + pc->npoints = 2; + + sp_curve_moveto(pc->red_curve, pc->p[0]); + sp_curve_lineto(pc->red_curve, pc->p[1]); + pc->red_curve_is_valid = true; + + sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(pc->red_bpath), pc->red_curve); + } +} + +/** + * Finalize addline. + * + * \todo + * fixme: I'd like remove red reset from concat colors (lauris). + * Still not sure, how it will make most sense. + */ +static void +spdc_finish_endpoint(SPPencilContext *const pc) +{ + if ( ( SP_CURVE_LENGTH(pc->red_curve) != 2 ) + || ( SP_CURVE_SEGMENT(pc->red_curve, 0)->c(3) == + SP_CURVE_SEGMENT(pc->red_curve, 1)->c(3) ) ) + { + sp_curve_reset(pc->red_curve); + sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(pc->red_bpath), NULL); + } else { + /* Write curves to object. */ + spdc_concat_colors_and_flush(pc, FALSE); + pc->sa = NULL; + pc->ea = NULL; + } +} + +static void +spdc_add_freehand_point(SPPencilContext *pc, NR::Point p, guint state) +{ + g_assert( pc->npoints > 0 ); + g_return_if_fail(unsigned(pc->npoints) < G_N_ELEMENTS(pc->p)); + + if ( ( p != pc->p[ pc->npoints - 1 ] ) + && in_svg_plane(p) ) + { + pc->p[pc->npoints++] = p; + fit_and_split(pc); + } +} + +static inline double +square(double const x) +{ + return x * x; +} + +static void +fit_and_split(SPPencilContext *pc) +{ + g_assert( pc->npoints > 1 ); + + double const tolerance_sq = square( NR::expansion(pc->desktop->w2d()) + * prefs_get_double_attribute_limited("tools.freehand.pencil", + "tolerance", 10.0, 1.0, 100.0) ); + + NR::Point b[4]; + g_assert(is_zero(pc->req_tangent) + || is_unit_vector(pc->req_tangent)); + NR::Point const tHatEnd(0, 0); + int const n_segs = sp_bezier_fit_cubic_full(b, NULL, pc->p, pc->npoints, + pc->req_tangent, tHatEnd, tolerance_sq, 1); + if ( n_segs > 0 + && unsigned(pc->npoints) < G_N_ELEMENTS(pc->p) ) + { + /* Fit and draw and reset state */ + sp_curve_reset(pc->red_curve); + sp_curve_moveto(pc->red_curve, b[0]); + sp_curve_curveto(pc->red_curve, b[1], b[2], b[3]); + sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(pc->red_bpath), pc->red_curve); + pc->red_curve_is_valid = true; + } else { + /* Fit and draw and copy last point */ + + g_assert(!sp_curve_empty(pc->red_curve)); + + /* Set up direction of next curve. */ + { + NArtBpath const &last_seg = *sp_curve_last_bpath(pc->red_curve); + pc->p[0] = last_seg.c(3); + pc->npoints = 1; + g_assert( last_seg.code == NR_CURVETO ); + /* Relevance: validity of last_seg.c(2). */ + NR::Point const req_vec( pc->p[0] - last_seg.c(2) ); + pc->req_tangent = ( ( NR::is_zero(req_vec) || !in_svg_plane(req_vec) ) + ? NR::Point(0, 0) + : NR::unit_vector(req_vec) ); + } + + sp_curve_append_continuous(pc->green_curve, pc->red_curve, 0.0625); + SPCurve *curve = sp_curve_copy(pc->red_curve); + + /// \todo fixme: + SPCanvasItem *cshape = sp_canvas_bpath_new(SP_DT_SKETCH(pc->desktop), curve); + sp_curve_unref(curve); + sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(cshape), pc->green_color, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT); + + pc->green_bpaths = g_slist_prepend(pc->green_bpaths, cshape); + + pc->red_curve_is_valid = false; + } +} + + +/* + 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:textwidth=99 : diff --git a/src/pencil-context.h b/src/pencil-context.h new file mode 100644 index 000000000..60519c269 --- /dev/null +++ b/src/pencil-context.h @@ -0,0 +1,52 @@ +#ifndef SEEN_PENCIL_CONTEXT_H +#define SEEN_PENCIL_CONTEXT_H + +/** \file + * SPPencilContext: a context for pencil tool events + */ + +#include "draw-context.h" + + +#define SP_TYPE_PENCIL_CONTEXT (sp_pencil_context_get_type()) +#define SP_PENCIL_CONTEXT(o) (G_TYPE_CHECK_INSTANCE_CAST((o), SP_TYPE_PENCIL_CONTEXT, SPPencilContext)) +#define SP_PENCIL_CONTEXT_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), SP_TYPE_PENCIL_CONTEXT, SPPencilContextClass)) +#define SP_IS_PENCIL_CONTEXT(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), SP_TYPE_PENCIL_CONTEXT)) +#define SP_IS_PENCIL_CONTEXT_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE((k), SP_TYPE_PENCIL_CONTEXT)) + +enum PencilState { + SP_PENCIL_CONTEXT_IDLE, + SP_PENCIL_CONTEXT_ADDLINE, + SP_PENCIL_CONTEXT_FREEHAND +}; + +/** + * SPPencilContext: a context for pencil tool events + */ +struct SPPencilContext : public SPDrawContext { + NR::Point p[16]; + gint npoints; + PencilState state; + NR::Point req_tangent; + + bool is_drawing; +}; + +/// The SPPencilContext vtable (empty). +struct SPPencilContextClass : public SPEventContextClass { }; + +GType sp_pencil_context_get_type(); + + +#endif /* !SEEN_PENCIL_CONTEXT_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:encoding=utf-8:textwidth=99 : diff --git a/src/pixmaps/cursor-arc.xpm b/src/pixmaps/cursor-arc.xpm new file mode 100644 index 000000000..37852a190 --- /dev/null +++ b/src/pixmaps/cursor-arc.xpm @@ -0,0 +1,38 @@ +/* XPM */ +static char * cursor_arc_xpm[] = { +"32 32 3 1", +" c None", +". c #FFFFFF", +"+ c #000000", +" ... ", +" .+. ", +" .+. ", +"....+.... ", +".+++ +++. ", +"....+.... ", +" .+. ", +" .+. ..... ", +" ... .+++.... ", +" .+..+++.. ", +" .+.....+.. ", +" .+......+.. ", +" ..+.......+. ", +" ...++.......+. ", +" ...++.........+. ", +" ...++..........+.. ", +" .++...........+.. ", +" ...++......+++.. ", +" ...++++++.... ", +" ........ ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" "}; diff --git a/src/pixmaps/cursor-arrow.xpm b/src/pixmaps/cursor-arrow.xpm new file mode 100644 index 000000000..e629d83d2 --- /dev/null +++ b/src/pixmaps/cursor-arrow.xpm @@ -0,0 +1,38 @@ +/* XPM */ +static char * cursor_arrow_xpm[] = { +"32 32 3 1", +" c None", +". c #FFFFFF", +"+ c #000000", +" .. ", +".++.. ", +".+ ++.. ", +" .+ ++.. ", +" .+ ++.. ", +" .+ ++. ", +" .+ +. ", +" .+ +. ", +" .+ +. ", +" .+ +. ", +" .+ + +. ", +" .++.+ +. ", +" .. .+ +. ", +" .+ +. ", +" .+ +. ", +" .+ +. ", +" .+ +. ", +" .+ +. ", +" .+. ", +" . ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" "}; diff --git a/src/pixmaps/cursor-calligraphy.xpm b/src/pixmaps/cursor-calligraphy.xpm new file mode 100644 index 000000000..ee0a5b876 --- /dev/null +++ b/src/pixmaps/cursor-calligraphy.xpm @@ -0,0 +1,38 @@ +/* XPM */ +static char * cursor_calligraphy_xpm[] = { +"32 32 3 1", +" c None", +". c #FFFFFF", +"+ c #000000", +" ... ", +" .+. ", +" .+. ", +"....+.... ", +".+++ +++. ", +"....+.... ", +" .+. . ", +" .+. .+. ", +" ... .+. ", +" .+. ", +" .+. ", +" .++. ", +" .++. ", +" .++. ... ", +" .++. ..+++. ", +" .+++. .++++++. ", +" .++++...+++++++. ", +" .++++++++++++++. ", +" .+++++++...++++. ", +" .++++++. .++++. ", +" .+++.. .++. ", +" ... .++. ", +" .++. ", +" .++. ", +" .++. ", +" .+. ", +" .+. ", +" .+. ", +" .+. ", +" . ", +" ", +" "}; diff --git a/src/pixmaps/cursor-connector.xpm b/src/pixmaps/cursor-connector.xpm new file mode 100644 index 000000000..ef35849ed --- /dev/null +++ b/src/pixmaps/cursor-connector.xpm @@ -0,0 +1,39 @@ +/* XPM */ +static char *cursor_connector_xpm[] = { +"32 32 3 1", +" c None", +". c #FFFFFF", +"+ c #000000", +". ", +".. ", +".+. ", +".++. ", +".+++. ", +".++++. ", +".+++++. ", +".++++++. ", +".+++++++. ", +".++++++++. ", +".+++++.... ", +".++.++. ", +".+. .++. ", +".. .++. ", +" .++. ", +" .++. ... ", +" .. .+. ", +" .+. ", +" .+. ", +" ...........+. ", +" .+++++++++++. ", +" .+........... ", +" .+. ", +" .+. ", +" ...+... ", +" .+++++. ", +" .+++. ", +" .+. ", +" . ", +" ", +" ", +" ", +}; diff --git a/src/pixmaps/cursor-dropper.xpm b/src/pixmaps/cursor-dropper.xpm new file mode 100644 index 000000000..ef0184697 --- /dev/null +++ b/src/pixmaps/cursor-dropper.xpm @@ -0,0 +1,38 @@ +/* XPM */ +static char * cursor_dropper_xpm[] = { +"32 32 3 1", +" c None", +". c #FFFFFF", +"+ c #000000", +" . ", +" .+. ", +" .+. ", +" .+. ", +" .+. ", +" .+. ", +" ..... ..... ", +".+++++ +++++. ", +" ..... ..... ", +" .+. ", +" .+. ", +" .+. ", +" .+. .... ", +" .+. .+++. ", +" . .+.++. ", +" .+..++. ", +" .+..++. ", +" .+..++. ", +" .+..++. ", +" .+..++. . ", +" .+..++.+. ", +" .+..++++. ", +" .+.++++. ", +" .++++++.. ", +" .+++++++++. ", +" .+..++++++. ", +" ..+.+++++. ", +" .+.++++. ", +" .+..++. ", +" .+++. ", +" ... ", +" "}; diff --git a/src/pixmaps/cursor-ellipse.xpm b/src/pixmaps/cursor-ellipse.xpm new file mode 100644 index 000000000..bdc175240 --- /dev/null +++ b/src/pixmaps/cursor-ellipse.xpm @@ -0,0 +1,38 @@ +/* XPM */ +static char * cursor_ellipse_xpm[] = { +"32 32 3 1", +" c None", +". c #FFFFFF", +"+ c #000000", +" ... ", +" .+. ", +" .+. ", +"....+.... ", +".+++ +++. ", +"....+.... ", +" .+. ", +" .+. ....... ", +" ... ....+++++.... ", +" ..+++.....+++.. ", +" ..+...........+.. ", +" ..+.............+.. ", +" .+...............+. ", +" .+...............+. ", +" .+...............+. ", +" ..+.............+.. ", +" ..+...........+.. ", +" ..+++.....+++.. ", +" ....+++++.... ", +" ....... ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" "}; diff --git a/src/pixmaps/cursor-gradient.xpm b/src/pixmaps/cursor-gradient.xpm new file mode 100644 index 000000000..b17873f58 --- /dev/null +++ b/src/pixmaps/cursor-gradient.xpm @@ -0,0 +1,38 @@ +/* XPM */ +static char * cursor_gradient_xpm[] = { +"32 32 3 1", +" c None", +". c #FFFFFF", +"+ c #000000", +" ... ", +" .+. ", +" .+. ", +"....+.... ", +".+++ +++. ", +"....+.... ", +" .+. ", +" .+. ..... ", +" ... .+++. ", +" .+.+. ", +" .+++. ", +" .+. ", +" .+. ", +" .+. ", +" .+. ", +" .+++. ", +" .+.+. ", +" .+++. ", +" ..... ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" "}; diff --git a/src/pixmaps/cursor-node-d.xpm b/src/pixmaps/cursor-node-d.xpm new file mode 100644 index 000000000..326b64105 --- /dev/null +++ b/src/pixmaps/cursor-node-d.xpm @@ -0,0 +1,38 @@ +/* XPM */ +static char * cursor_node_d_xpm[] = { +"32 32 3 1", +" g None", +". g #FFFFFF", +"+ g #000000", +" . ", +".+. ", +" .+. ", +" .++. ", +" .++. ", +" .+++. ", +" .+++. ", +" .++++. ", +" .++++. ", +" .+++++. ", +" .+++++. ", +" .++++++. ", +" .+++++. ", +" .+++.. ", +" .+. ++ ++ ", +" . +..+..+ ", +" ++..+..++ ", +" +.+..+..+.+ ", +" +.+..+..+.+ ", +" +.+..+..+.+ ", +" +.........+ ", +" +.........+ ", +" +........+ ", +" +........+ ", +" +......+ ", +" +......+ ", +" +.....+ ", +" +.....+ ", +" +++++++ ", +" ", +" ", +" "}; diff --git a/src/pixmaps/cursor-node-m.xpm b/src/pixmaps/cursor-node-m.xpm new file mode 100644 index 000000000..9b2479a28 --- /dev/null +++ b/src/pixmaps/cursor-node-m.xpm @@ -0,0 +1,38 @@ +/* XPM */ +static char * cursor_node_m_xpm[] = { +"32 32 3 1", +" g None", +". g #FFFFFF", +"+ g #000000", +" . ", +".+. ", +" .+. ", +" .++. ", +" .++. ", +" .+++. ", +" .+++. ", +" .++++. ", +" .++++. ", +" .+++++. ", +" .+++++. ", +" .++++++. ++++ ", +" .+++++. +.+..+ ", +" .+++.. +..+..++ ", +" .+. +..+..+.+ ", +" . + +..+..+..+ ", +" +.++..+..+..+ ", +" +..+..+..+..+ ", +" +..+..+..+..+ ", +" +..+..+..+..+ ", +" +...........+ ", +" +..........+ ", +" +.........+ ", +" +........+ ", +" +.......+ ", +" +......+ ", +" +.....+ ", +" +.....+ ", +" +++++++ ", +" ", +" ", +" "}; diff --git a/src/pixmaps/cursor-node.xpm b/src/pixmaps/cursor-node.xpm new file mode 100644 index 000000000..297dae6dd --- /dev/null +++ b/src/pixmaps/cursor-node.xpm @@ -0,0 +1,38 @@ +/* XPM */ +static char * cursor_node_xpm[] = { +"32 32 3 1", +" c None", +". c #FFFFFF", +"+ c #000000", +" . ", +".+. ", +" .+. ", +" .++. ", +" .++. ", +" .+++. ", +" .+++. ", +" .++++. ", +" .++++. ", +" .+++++. ", +" .+++++. ", +" .++++++. ", +" .+++++. ", +" .+++.. ", +" .+. ", +" . ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" "}; diff --git a/src/pixmaps/cursor-pen.xpm b/src/pixmaps/cursor-pen.xpm new file mode 100644 index 000000000..5bb565c42 --- /dev/null +++ b/src/pixmaps/cursor-pen.xpm @@ -0,0 +1,38 @@ +/* XPM */ +static char * cursor_pen_xpm[] = { +"32 32 3 1", +" c None", +". c #FFFFFF", +"+ c #000000", +" ... ", +" .+. ", +" .+. ", +"....+.... ", +".+++ +++. ", +"....+.... ", +" .+. ", +" .+. ", +" ... .. ", +" .++... ", +" .+.++++.. ", +" .++.+..++.. ", +" .++.+...++. ", +" .+.+.+....+. ", +" .+..+.++..+. ", +" .+..+..+..+. ", +" .+..+...+..+. ", +" .+..+.+...+.. ", +" .+...+.+..+.+. ", +" .++.......+.+. ", +" ..+.....++..+. ", +" .+++.++.+..+. ", +" ...++.+.++. ", +" .++++.++. ", +" .+++++. ", +" .+++. ", +" .+. ", +" . ", +" ", +" ", +" ", +" "}; diff --git a/src/pixmaps/cursor-pencil.xpm b/src/pixmaps/cursor-pencil.xpm new file mode 100644 index 000000000..ff00464f6 --- /dev/null +++ b/src/pixmaps/cursor-pencil.xpm @@ -0,0 +1,38 @@ +/* XPM */ +static char * cursor_pencil_xpm[] = { +"32 32 3 1", +" c None", +". c #FFFFFF", +"+ c #000000", +" ... ", +" .+. ", +" .+. ", +"....+.... ", +".+++ +++. ", +"....+.... ", +" .+. ", +" .+. ", +" ... ", +" .. ", +" .+...... ", +" .++++++. ", +" .++..+.+. ", +" .+..++..+. ", +" .+.+..+..+. ", +" .+++...+..+. ", +" .+..+...+..+. ", +" .+..+...+..+. ", +" .+..+...+..+. ", +" .+..+...+..+. ", +" .+..+...+.++. ", +" .+..+...+..+. ", +" .+..+.+...+. ", +" .+..+...+. ", +" .++...+. ", +" .+..+. ", +" .++. ", +" .. ", +" ", +" ", +" ", +" "}; diff --git a/src/pixmaps/cursor-rect.xpm b/src/pixmaps/cursor-rect.xpm new file mode 100644 index 000000000..508dd4b54 --- /dev/null +++ b/src/pixmaps/cursor-rect.xpm @@ -0,0 +1,38 @@ +/* XPM */ +static char * cursor_rect_xpm[] = { +"32 32 3 1", +" c None", +". c #FFFFFF", +"+ c #000000", +" ... ", +" .+. ", +" .+. ", +"....+.... ", +".+++ +++. ", +"....+.... ", +" .+. ", +" .+. ................. ", +" ... .+++++++++++++++. ", +" .+.............+. ", +" .+.............+. ", +" .+.............+. ", +" .+.............+. ", +" .+.............+. ", +" .+.............+. ", +" .+.............+. ", +" .+.............+. ", +" .+.............+. ", +" .+++++++++++++++. ", +" ................. ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" "}; diff --git a/src/pixmaps/cursor-select-d.xpm b/src/pixmaps/cursor-select-d.xpm new file mode 100644 index 000000000..fb37164e5 --- /dev/null +++ b/src/pixmaps/cursor-select-d.xpm @@ -0,0 +1,38 @@ +/* XPM */ +static char * cursor_select_d_xpm[] = { +"32 32 3 1", +" g None", +". g #FFFFFF", +"+ g #000000", +".. ", +".+. ", +".++. ", +".+++. ", +".++++. ", +".+++++. ", +".++++++. ", +".+++++++. ", +".++++++++. ", +".+++++++++. ", +".+++++.... ", +".++.++. ", +".+. .++. ", +" . .++. ", +" .++. ++ ++ ", +" .++. +..+..+ ", +" .. ++..+..++ ", +" +.+..+..+.+ ", +" +.+..+..+.+ ", +" +.+..+..+.+ ", +" +.........+ ", +" +.........+ ", +" +........+ ", +" +........+ ", +" +......+ ", +" +......+ ", +" +.....+ ", +" +.....+ ", +" +++++++ ", +" ", +" ", +" "}; diff --git a/src/pixmaps/cursor-select-m.xpm b/src/pixmaps/cursor-select-m.xpm new file mode 100644 index 000000000..29b0a5c3a --- /dev/null +++ b/src/pixmaps/cursor-select-m.xpm @@ -0,0 +1,38 @@ +/* XPM */ +static char * cursor_select_m_xpm[] = { +"32 32 3 1", +" g None", +". g #FFFFFF", +"+ g #000000", +".. ", +".+. ", +".++. ", +".+++. ", +".++++. ", +".+++++. ", +".++++++. ", +".+++++++. ", +".++++++++. ", +".+++++++++. ", +".+++++.... ", +".++.++. ++++ ", +".+. .++. +.+..+ ", +" . .++. +..+..++ ", +" .++. +..+..+.+ ", +" .++. + +..+..+..+ ", +" .. +.++..+..+..+ ", +" +..+..+..+..+ ", +" +..+..+..+..+ ", +" +..+..+..+..+ ", +" +...........+ ", +" +..........+ ", +" +.........+ ", +" +........+ ", +" +.......+ ", +" +......+ ", +" +.....+ ", +" +.....+ ", +" +++++++ ", +" ", +" ", +" "}; diff --git a/src/pixmaps/cursor-spiral.xpm b/src/pixmaps/cursor-spiral.xpm new file mode 100644 index 000000000..eefa8be70 --- /dev/null +++ b/src/pixmaps/cursor-spiral.xpm @@ -0,0 +1,38 @@ +/* XPM */ +static char * cursor_spiral_xpm[] = { +"32 32 3 1", +" c None", +". c #FFFFFF", +"+ c #000000", +" ... ", +" .+. ", +" .+. ", +"....+.... ", +".+++ +++. ", +"....+.... ", +" .+. ....... ", +" .+. ...+++++... ", +" ... ..++.....++.. ", +" .+.........+.. ", +" ..+...++++...+. ", +" .+...+....+..+.. ", +" .+..+......+..+. ", +" .+..+......+..+. ", +" .+..+...+..+..+. ", +" ..+..+++..+..+.. ", +" .+......+...+. ", +" ..++...+...+.. ", +" ...+++...+.. ", +" ......+.. ", +" .... ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" "}; diff --git a/src/pixmaps/cursor-star.xpm b/src/pixmaps/cursor-star.xpm new file mode 100644 index 000000000..25ff432a0 --- /dev/null +++ b/src/pixmaps/cursor-star.xpm @@ -0,0 +1,38 @@ +/* XPM */ +static char * cursor_star_xpm[] = { +"32 32 3 1", +" c None", +". c #FFFFFF", +"+ c #000000", +" ... ", +" .+. ", +" .+. ", +"....+.... ", +".+++ +++. ", +"....+.... .. ", +" .+. .++. ", +" .+. .++. ", +" ... .++. ", +" .+..+. ", +" ........+..+........ ", +" .++++++....++++++. ", +" .++..........++. ", +" ..++......++.. ", +" .+......+. ", +" .+......+. ", +" .+...++...+. ", +" .+.++..++.+. ", +" .+.+.. ..+.+. ", +" .++. .++. ", +" .+. .+. ", +" .. .. ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" "}; diff --git a/src/pixmaps/cursor-text-insert.xpm b/src/pixmaps/cursor-text-insert.xpm new file mode 100644 index 000000000..fc7708aea --- /dev/null +++ b/src/pixmaps/cursor-text-insert.xpm @@ -0,0 +1,38 @@ +/* XPM */ +static char * cursor_text_insert_xpm[] = { +"32 32 3 1", +" c None", +". c #FFFFFF", +"+ c #000000", +" ....... ", +" .+++.+++. ", +" ...+... ", +" .+. ", +" .+. ", +" .+. ", +" .+. ", +" .+. ", +" .+. ", +" .+. ", +" .+. ", +" .+. ", +" .+. ", +" .+. ", +" .+. ", +" .+. ", +" .+. ", +" ...+... ", +" .+++.+++. ", +" ....... ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" "}; diff --git a/src/pixmaps/cursor-text.xpm b/src/pixmaps/cursor-text.xpm new file mode 100644 index 000000000..cea25f2bc --- /dev/null +++ b/src/pixmaps/cursor-text.xpm @@ -0,0 +1,38 @@ +/* XPM */ +static char * cursor_text_xpm[] = { +"32 32 3 1", +" c None", +". c #FFFFFF", +"+ c #000000", +" . ", +" .+. ", +" .+. ", +" .+. ", +" .+. ", +" .+. ", +" ..... ..... ", +".+++++ +++++. ", +" ..... ..... ", +" .+. ", +" .+. ", +" .+. .... ", +" .+. .++++. ", +" .+. .++++. ", +" . .++++++. ", +" .++++++. ", +" .++++++. ", +" .+++..+++. ", +" .+++..+++. ", +" .++++++++. ", +" .++++++++++. ", +" .+++....+++. ", +" ... ... ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" "}; diff --git a/src/pixmaps/cursor-zoom-out.xpm b/src/pixmaps/cursor-zoom-out.xpm new file mode 100644 index 000000000..318406ebc --- /dev/null +++ b/src/pixmaps/cursor-zoom-out.xpm @@ -0,0 +1,38 @@ +/* XPM */ +static char * cursor_zoom_out_xpm[] = { +"32 32 3 1", +" c None", +". c #FFFFFF", +"+ c #000000", +" ... ", +" ..+++.. ", +" .++ ++. ", +" .+ +. ", +" .+ +. ", +".+ ..... +. ", +".+ +++++ +. ", +".+ ..... +. ", +" .+ +. ", +" .+ +. ", +" .++ ++.+.. ", +" ..+++..+.++. ", +" ... .+ +. ", +" .+ +. ", +" .+ +. ", +" .+ +. ", +" .+ +. ", +" .+ +. ", +" .++. ", +" .. ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" "}; diff --git a/src/pixmaps/cursor-zoom.xpm b/src/pixmaps/cursor-zoom.xpm new file mode 100644 index 000000000..88c83004d --- /dev/null +++ b/src/pixmaps/cursor-zoom.xpm @@ -0,0 +1,38 @@ +/* XPM */ +static char * cursor_zoom_xpm[] = { +"32 32 3 1", +" c None", +". c #FFFFFF", +"+ c #000000", +" ... ", +" ..+++.. ", +" .++ ++. ", +" .+ +. ", +" .+ .+. +. ", +".+ ..+.. +. ", +".+ +++++ +. ", +".+ ..+.. +. ", +" .+ .+. +. ", +" .+ +. ", +" .++ ++.+.. ", +" ..+++..+.++. ", +" ... .+ +. ", +" .+ +. ", +" .+ +. ", +" .+ +. ", +" .+ +. ", +" .+ +. ", +" .++. ", +" .. ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" "}; diff --git a/src/pixmaps/handles.xpm b/src/pixmaps/handles.xpm new file mode 100644 index 000000000..6ab68e7d3 --- /dev/null +++ b/src/pixmaps/handles.xpm @@ -0,0 +1,260 @@ +/* XPM */ +static char * handle_scale_nw_xpm[] = { +"13 13 3 1", +" c None", +". c #000000", +"+ c #FFFFFF", +" ", +" ....... ", +" .+++.. ", +" .++++. ", +" .+++++. ", +" ..+++++. . ", +" ...+++++... ", +" . .+++++.. ", +" .+++++. ", +" .++++. ", +" ..+++. ", +" ....... ", +" "}; + +/* XPM */ +static char * handle_scale_ne_xpm[] = { +"13 13 3 1", +" c None", +". c #000000", +"+ c #FFFFFF", +" ", +" ....... ", +" ..+++. ", +" .++++. ", +" .+++++. ", +" . .+++++.. ", +" ...+++++... ", +" ..+++++. . ", +" .+++++. ", +" .++++. ", +" .+++.. ", +" ....... ", +" "}; + +/* XPM */ +static char * handle_scale_h_xpm[] = { +"13 13 3 1", +" c None", +". c #000000", +"+ c #FFFFFF", +" ", +" ", +" . . ", +" .. .. ", +" ..+...+.. ", +" ..+++++++.. ", +"..+++++++++..", +" ..+++++++.. ", +" ..+...+.. ", +" .. .. ", +" . . ", +" ", +" "}; + +/* XPM */ +static char * handle_scale_v_xpm[] = { +"13 13 3 1", +" c None", +". c #000000", +"+ c #FFFFFF", +" . ", +" ... ", +" ..+.. ", +" ..+++.. ", +" ..+++++.. ", +" .+++. ", +" .+++. ", +" .+++. ", +" ..+++++.. ", +" ..+++.. ", +" ..+.. ", +" ... ", +" . "}; + +/* XPM */ +static char * handle_rotate_nw_xpm[] = { +"13 13 3 1", +" c None", +". c #000000", +"+ c #FFFFFF", +" . ", +" .. ", +" .... ", +" ...++.. ", +" .++++++..", +" .+++++++. ", +" .++++..+. ", +" .+++. . ", +"...+++. ", +" ..++++. ", +" ..++. ", +" ... ", +" . "}; + +/* XPM */ +static char * handle_rotate_n_xpm[] = { +"13 13 3 1", +" c None", +". c #000000", +"+ c #FFFFFF", +" . . ", +" .. .. ", +" ......... ", +" ..+++++++.. ", +"..+++++++++..", +" ..+++++++.. ", +" ......... ", +" .. .. ", +" . . ", +" ", +" ", +" ", +" "}; + +/* XPM */ +static char * handle_rotate_ne_xpm[] = { +"13 13 3 1", +" c None", +". c #000000", +"+ c #FFFFFF", +" . ", +" .. ", +" .... ", +" ..++... ", +"..++++++. ", +" .+++++++. ", +" .+..++++. ", +" . .+++. ", +" .+++...", +" .++++.. ", +" .++.. ", +" ... ", +" . "}; + +/* XPM */ +static char * handle_rotate_e_xpm[] = { +"13 13 3 1", +" c None", +". c #000000", +"+ c #FFFFFF", +" . ", +" ... ", +" ..+.. ", +" ..+++.. ", +" ...+++...", +" .+++. ", +" .+++. ", +" .+++. ", +" ...+++...", +" ..+++.. ", +" ..+.. ", +" ... ", +" . "}; + +/* XPM */ +static char * handle_rotate_se_xpm[] = { +"13 13 3 1", +" c None", +". c #000000", +"+ c #FFFFFF", +" . ", +" ... ", +" .++.. ", +" .++++.. ", +" .+++...", +" . .+++. ", +" .+..++++. ", +" .+++++++. ", +"..++++++. ", +" ..++... ", +" .... ", +" .. ", +" . "}; + + +/* XPM */ +static char * handle_rotate_s_xpm[] = { +"13 13 3 1", +" c None", +". c #000000", +"+ c #FFFFFF", +" ", +" ", +" ", +" ", +" . . ", +" .. .. ", +" ......... ", +" ..+++++++.. ", +"..+++++++++..", +" ..+++++++.. ", +" ......... ", +" .. .. ", +" . . "}; + +/* XPM */ +static char * handle_rotate_sw_xpm[] = { +"13 13 3 1", +" c None", +". c #000000", +"+ c #FFFFFF", +" . ", +" ... ", +" ..++. ", +" ..++++. ", +"...+++. ", +" .+++. . ", +" .++++..+. ", +" .+++++++. ", +" .++++++..", +" ...++.. ", +" .... ", +" .. ", +" . "}; + +/* XPM */ +static char * handle_rotate_w_xpm[] = { +"13 13 3 1", +" c None", +". c #000000", +"+ c #FFFFFF", +" . ", +" ... ", +" ..+.. ", +" ..+++.. ", +"...+++... ", +" .+++. ", +" .+++. ", +" .+++. ", +"...+++. . ", +" ..+++.. ", +" ..+.. ", +" ... ", +" . "}; + +/* XPM */ +static char * handle_center_xpm[] = { +"13 13 3 1", +" c None", +". c #000000", +"+ c #FFFFFF", +" ", +" . ", +" . ", +" . ", +" ++.++ ", +" ++.++ ", +" ..... ..... ", +" ++.++ ", +" ++.++ ", +" . ", +" . ", +" . ", +" "}; diff --git a/src/plugin.def b/src/plugin.def new file mode 100644 index 000000000..168e1e4a0 --- /dev/null +++ b/src/plugin.def @@ -0,0 +1,7 @@ +;######################################################## +;## File: plugin.def +;## Purpose: Used by dllwrap to make an inkscape plugin +;######################################################## + +EXPORTS + inkscape_plugin_table diff --git a/src/preferences-skeleton.h b/src/preferences-skeleton.h new file mode 100644 index 000000000..688a080fa --- /dev/null +++ b/src/preferences-skeleton.h @@ -0,0 +1,266 @@ +#ifndef SEEN_PREFERENCES_SKELETON_H +#define SEEN_PREFERENCES_SKELETON_H + +#include + +static char const preferences_skeleton[] = +"\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"\n" +" \n" +" \n" +" \n" +"\n" +" \n" +" \n" +" \n" +"\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"\n" +" " +" \n" +"\n" +" \n" +" \n" +"\n" +" \n" +" \n" +"\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +"\n" +"\n"; + +#define PREFERENCES_SKELETON_SIZE (sizeof(preferences_skeleton) - 1) + + +#endif /* !SEEN_PREFERENCES_SKELETON_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:encoding=utf-8:textwidth=99 : diff --git a/src/preferences.cpp b/src/preferences.cpp new file mode 100644 index 000000000..05701a2f6 --- /dev/null +++ b/src/preferences.cpp @@ -0,0 +1,92 @@ +/** \file + * \brief Prefs handling implementation + * + * Authors: + * Ralf Stephan + * + * Copyright (C) 2005 Authors + * + * Released under GNU GPL. Read the file 'COPYING' for more information. + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#include "preferences-skeleton.h" +#include "xml/repr.h" +#include "dialogs/input.h" +#include "inkscape.h" +#include "preferences.h" + +#define PREFERENCES_FILE "preferences.xml" + +static Inkscape::XML::Document *_preferences; +static bool _save_preferences; + +namespace Inkscape { + +void +Preferences::loadSkeleton() +{ + _preferences = sp_repr_read_mem (preferences_skeleton, PREFERENCES_SKELETON_SIZE, 0); +} + +Inkscape::XML::Document* +Preferences::get() +{ + return _preferences; +} + +/** + * Attempts to load the preferences file indicated by the global PREFERENCES_FILE + * parameter. If it cannot load it, the default preferences_skeleton will be used + * instead. + */ +void +Preferences::load() +{ + /// \todo this still uses old Gtk+ code which should be somewhere else + if (inkscape_load_config (PREFERENCES_FILE, + _preferences, + preferences_skeleton, + PREFERENCES_SKELETON_SIZE, + _("%s is not a regular file.\n%s"), + _("%s not a valid XML file, or\n" + "you don't have read permissions on it.\n%s"), + _("%s is not a valid preferences file.\n%s"), + _("Inkscape will run with default settings.\n" + "New settings will not be saved."))) + { + sp_input_load_from_preferences(); + _save_preferences = true; + } else + _save_preferences = false; +} + +void +Preferences::save() +{ + if (!_preferences || ! _save_preferences) + return; + + gchar *fn = profile_path (PREFERENCES_FILE); + (void) sp_repr_save_file (_preferences, fn); + g_free (fn); +} + + +} // namespace Inkscape + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)) + indent-tabs-mode:nil + fill-column:75 + End: +*/ +// vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/preferences.h b/src/preferences.h new file mode 100644 index 000000000..4a7659586 --- /dev/null +++ b/src/preferences.h @@ -0,0 +1,44 @@ +/** \file + * \brief Static class where all preferences handling happens. + * + * Authors: + * Ralf Stephan + * + * Copyright (C) 2005 Authors + * + * Released under GNU GPL. Read the file 'COPYING' for more information. + */ + +#ifndef INKSCAPE_PREFERENCES_H +#define INKSCAPE_PREFERENCES_H + +namespace Inkscape { + namespace XML { + class Document; + } + +class Preferences +{ +public: + static XML::Document *get(); + static void load(); + static void save(); + static void loadSkeleton(); + +private: +}; + +} // namespace Inkscape + +#endif // INKSCAPE_PREFERENCES_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:encoding=utf-8:textwidth=99 : diff --git a/src/prefix.cpp b/src/prefix.cpp new file mode 100644 index 000000000..3c9ec6cae --- /dev/null +++ b/src/prefix.cpp @@ -0,0 +1,427 @@ +/* + * BinReloc - a library for creating relocatable executables + * Written by: Mike Hearn + * Hongli Lai + * http://autopackage.org/ + * + * This source code is public domain. You can relicense this code + * under whatever license you want. + * + * NOTE: if you're using C++ and are getting "undefined reference + * to br_*", try renaming prefix.c to prefix.cpp + */ + +/* WARNING, BEFORE YOU MODIFY PREFIX.C: + * + * If you make changes to any of the functions in prefix.c, you MUST + * change the BR_NAMESPACE macro (in prefix.h). + * This way you can avoid symbol table conflicts with other libraries + * that also happen to use BinReloc. + * + * Example: + * #define BR_NAMESPACE(funcName) foobar_ ## funcName + * --> expands br_locate to foobar_br_locate + */ + +#ifndef _PREFIX_C_ +#define _PREFIX_C_ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + + +/* PLEASE NOTE: We use GThreads now for portability */ +/* @see http://developer.gnome.org/doc/API/2.0/glib/glib-Threads.html */ +#ifndef BR_THREADS + /* Change 1 to 0 if you don't want thread support */ + #define BR_THREADS 1 + #include //for GThreads +#endif /* BR_THREADS */ + +#include +#include +#include +#include +#include "prefix.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +#undef NULL +#define NULL ((void *) 0) + +#ifdef __GNUC__ + #define br_return_val_if_fail(expr,val) if (!(expr)) {fprintf (stderr, "** BinReloc (%s): assertion %s failed\n", __PRETTY_FUNCTION__, #expr); return val;} +#else + #define br_return_val_if_fail(expr,val) if (!(expr)) return val +#endif /* __GNUC__ */ + + +#ifdef ENABLE_BINRELOC + +#include +#include +#include +#include + +/** + * br_locate: + * symbol: A symbol that belongs to the app/library you want to locate. + * Returns: A newly allocated string containing the full path of the + * app/library that func belongs to, or NULL on error. This + * string should be freed when not when no longer needed. + * + * Finds out to which application or library symbol belongs, then locate + * the full path of that application or library. + * Note that symbol cannot be a pointer to a function. That will not work. + * + * Example: + * --> main.c + * #include "prefix.h" + * #include "libfoo.h" + * + * int main (int argc, char *argv[]) { + * printf ("Full path of this app: %s\n", br_locate (&argc)); + * libfoo_start (); + * return 0; + * } + * + * --> libfoo.c starts here + * #include "prefix.h" + * + * void libfoo_start () { + * --> "" is a symbol that belongs to libfoo (because it's called + * --> from libfoo_start()); that's why this works. + * printf ("libfoo is located in: %s\n", br_locate ("")); + * } + */ +char * +br_locate (void *symbol) +{ + char line[5000]; + FILE *f; + char *path; + + br_return_val_if_fail (symbol != NULL, NULL); + + f = fopen ("/proc/self/maps", "r"); + if (!f) + return NULL; + + while (!feof (f)) + { + unsigned long start, end; + + if (!fgets (line, sizeof (line), f)) + continue; + if (!strstr (line, " r-xp ") || !strchr (line, '/')) + continue; + + sscanf (line, "%lx-%lx ", &start, &end); + if (symbol >= (void *) start && symbol < (void *) end) + { + char *tmp; + size_t len; + + /* Extract the filename; it is always an absolute path */ + path = strchr (line, '/'); + + /* Get rid of the newline */ + tmp = strrchr (path, '\n'); + if (tmp) *tmp = 0; + + /* Get rid of "(deleted)" */ + len = strlen (path); + if (len > 10 && strcmp (path + len - 10, " (deleted)") == 0) + { + tmp = path + len - 10; + *tmp = 0; + } + + fclose(f); + return strdup (path); + } + } + + fclose (f); + return NULL; +} + + +/** + * br_locate_prefix: + * symbol: A symbol that belongs to the app/library you want to locate. + * Returns: A prefix. This string should be freed when no longer needed. + * + * Locates the full path of the app/library that symbol belongs to, and return + * the prefix of that path, or NULL on error. + * Note that symbol cannot be a pointer to a function. That will not work. + * + * Example: + * --> This application is located in /usr/bin/foo + * br_locate_prefix (&argc); --> returns: "/usr" + */ +char * +br_locate_prefix (void *symbol) +{ + char *path, *prefix; + + br_return_val_if_fail (symbol != NULL, NULL); + + path = br_locate (symbol); + if (!path) return NULL; + + prefix = br_extract_prefix (path); + free (path); + return prefix; +} + + +/** + * br_prepend_prefix: + * symbol: A symbol that belongs to the app/library you want to locate. + * path: The path that you want to prepend the prefix to. + * Returns: The new path, or NULL on error. This string should be freed when no + * longer needed. + * + * Gets the prefix of the app/library that symbol belongs to. Prepend that prefix to path. + * Note that symbol cannot be a pointer to a function. That will not work. + * + * Example: + * --> The application is /usr/bin/foo + * br_prepend_prefix (&argc, "/share/foo/data.png"); --> Returns "/usr/share/foo/data.png" + */ +char * +br_prepend_prefix (void *symbol, char *path) +{ + char *tmp, *newpath; + + br_return_val_if_fail (symbol != NULL, NULL); + br_return_val_if_fail (path != NULL, NULL); + + tmp = br_locate_prefix (symbol); + if (!tmp) return NULL; + + if (strcmp (tmp, "/") == 0) + newpath = strdup (path); + else + newpath = br_strcat (tmp, path); + + /* Get rid of compiler warning ("br_prepend_prefix never used") */ + if (0) br_prepend_prefix (NULL, NULL); + + free (tmp); + return newpath; +} + +#endif /* ENABLE_BINRELOC */ + + +/* Thread stuff for thread safetiness */ +#if BR_THREADS + +GPrivate* br_thread_key = (GPrivate *)NULL; + +/* + We do not need local store init() or fini(), because + g_private_new (g_free) will take care of all of that + for us. Isn't GLib wonderful? +*/ + +#else /* !BR_THREADS */ + +static char *br_last_value = (char*)NULL; + +static void +br_free_last_value () +{ + if (br_last_value) + free (br_last_value); +} + +#endif /* BR_THREADS */ + + +/** + * br_thread_local_store: + * str: A dynamically allocated string. + * Returns: str. This return value must not be freed. + * + * Store str in a thread-local variable and return str. The next + * you run this function, that variable is freed too. + * This function is created so you don't have to worry about freeing + * strings. + * + * Example: + * char *foo; + * foo = thread_local_store (strdup ("hello")); --> foo == "hello" + * foo = thread_local_store (strdup ("world")); --> foo == "world"; "hello" is now freed. + */ +const char * +br_thread_local_store (char *str) +{ + #if BR_THREADS + if (!g_thread_supported ()) + { + g_thread_init ((GThreadFunctions *)NULL); + br_thread_key = g_private_new (g_free); + } + + char *specific = (char *) g_private_get (br_thread_key); + if (specific) + free (specific); + g_private_set (br_thread_key, str); + + #else /* !BR_THREADS */ + static int initialized = 0; + + if (!initialized) + { + atexit (br_free_last_value); + initialized = 1; + } + + if (br_last_value) + free (br_last_value); + br_last_value = str; + #endif /* BR_THREADS */ + + return (const char *) str; +} + + +/** + * br_strcat: + * str1: A string. + * str2: Another string. + * Returns: A newly-allocated string. This string should be freed when no longer needed. + * + * Concatenate str1 and str2 to a newly allocated string. + */ +char * +br_strcat (const char *str1, const char *str2) +{ + char *result; + size_t len1, len2; + + if (!str1) str1 = ""; + if (!str2) str2 = ""; + + len1 = strlen (str1); + len2 = strlen (str2); + + result = (char *) malloc (len1 + len2 + 1); + memcpy (result, str1, len1); + memcpy (result + len1, str2, len2); + result[len1 + len2] = '\0'; + + return result; +} + + +/* Emulates glibc's strndup() */ +static char * +br_strndup (char *str, size_t size) +{ + char *result = (char*)NULL; + size_t len; + + br_return_val_if_fail (str != (char*)NULL, (char*)NULL); + + len = strlen (str); + if (!len) return strdup (""); + if (size > len) size = len; + + result = (char *) calloc (sizeof (char), len + 1); + memcpy (result, str, size); + return result; +} + + +/** + * br_extract_dir: + * path: A path. + * Returns: A directory name. This string should be freed when no longer needed. + * + * Extracts the directory component of path. Similar to g_dirname() or the dirname + * commandline application. + * + * Example: + * br_extract_dir ("/usr/local/foobar"); --> Returns: "/usr/local" + */ +char * +br_extract_dir (const char *path) +{ + char *end, *result; + + br_return_val_if_fail (path != (char*)NULL, (char*)NULL); + + end = strrchr (path, '/'); + if (!end) return strdup ("."); + + while (end > path && *end == '/') + end--; + result = br_strndup ((char *) path, end - path + 1); + if (!*result) + { + free (result); + return strdup ("/"); + } else + return result; +} + + +/** + * br_extract_prefix: + * path: The full path of an executable or library. + * Returns: The prefix, or NULL on error. This string should be freed when no longer needed. + * + * Extracts the prefix from path. This function assumes that your executable + * or library is installed in an LSB-compatible directory structure. + * + * Example: + * br_extract_prefix ("/usr/bin/gnome-panel"); --> Returns "/usr" + * br_extract_prefix ("/usr/local/lib/libfoo.so"); --> Returns "/usr/local" + * br_extract_prefix ("/usr/local/libfoo.so"); --> Returns "/usr" + */ +char * +br_extract_prefix (const char *path) +{ + char *end, *tmp, *result; + + br_return_val_if_fail (path != (char*)NULL, (char*)NULL); + + if (!*path) return strdup ("/"); + end = strrchr (path, '/'); + if (!end) return strdup (path); + + tmp = br_strndup ((char *) path, end - path); + if (!*tmp) + { + free (tmp); + return strdup ("/"); + } + end = strrchr (tmp, '/'); + if (!end) return tmp; + + result = br_strndup (tmp, end - tmp); + free (tmp); + + if (!*result) + { + free (result); + result = strdup ("/"); + } + + return result; +} + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _PREFIX_C */ diff --git a/src/prefix.h b/src/prefix.h new file mode 100644 index 000000000..0406f29f8 --- /dev/null +++ b/src/prefix.h @@ -0,0 +1,122 @@ +/* + * BinReloc - a library for creating relocatable executables + * Written by: Mike Hearn + * Hongli Lai + * http://autopackage.org/ + * + * This source code is public domain. You can relicense this code + * under whatever license you want. + * + * See http://autopackage.org/docs/binreloc/ for + * more information and how to use this. + * + * NOTE: if you're using C++ and are getting "undefined reference + * to br_*", try renaming prefix.c to prefix.cpp + */ + +#ifndef _PREFIX_H_ +#define _PREFIX_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* WARNING, BEFORE YOU MODIFY PREFIX.C: + * + * If you make changes to any of the functions in prefix.c, you MUST + * change the BR_NAMESPACE macro. + * This way you can avoid symbol table conflicts with other libraries + * that also happen to use BinReloc. + * + * Example: + * #define BR_NAMESPACE(funcName) foobar_ ## funcName + * --> expands br_locate to foobar_br_locate + */ +#undef BR_NAMESPACE +#define BR_NAMESPACE(funcName) funcName + + +#ifdef ENABLE_BINRELOC + +#define br_thread_local_store BR_NAMESPACE(br_thread_local_store) +#define br_locate BR_NAMESPACE(br_locate) +#define br_locate_prefix BR_NAMESPACE(br_locate_prefix) +#define br_prepend_prefix BR_NAMESPACE(br_prepend_prefix) + +#ifndef BR_NO_MACROS + /* These are convience macros that replace the ones usually used + in Autoconf/Automake projects */ + #undef SELFPATH + #undef PREFIX + #undef PREFIXDIR + #undef BINDIR + #undef SBINDIR + #undef DATADIR + #undef LIBDIR + #undef LIBEXECDIR + #undef ETCDIR + #undef SYSCONFDIR + #undef CONFDIR + #undef LOCALEDIR + + #define SELFPATH (br_thread_local_store (br_locate ((void *) ""))) + #define PREFIX (br_thread_local_store (br_locate_prefix ((void *) ""))) + #define PREFIXDIR (br_thread_local_store (br_locate_prefix ((void *) ""))) + #define BINDIR (br_thread_local_store (br_prepend_prefix ((void *) "", "/bin"))) + #define SBINDIR (br_thread_local_store (br_prepend_prefix ((void *) "", "/sbin"))) + #define DATADIR (br_thread_local_store (br_prepend_prefix ((void *) "", "/share"))) + #define LIBDIR (br_thread_local_store (br_prepend_prefix ((void *) "", "/lib"))) + #define LIBEXECDIR (br_thread_local_store (br_prepend_prefix ((void *) "", "/libexec"))) + #define ETCDIR (br_thread_local_store (br_prepend_prefix ((void *) "", "/etc"))) + #define SYSCONFDIR (br_thread_local_store (br_prepend_prefix ((void *) "", "/etc"))) + #define CONFDIR (br_thread_local_store (br_prepend_prefix ((void *) "", "/etc"))) + #define LOCALEDIR (br_thread_local_store (br_prepend_prefix ((void *) "", "/share/locale"))) +#endif /* BR_NO_MACROS */ + + +/* The following functions are used internally by BinReloc + and shouldn't be used directly in applications. */ + +const char *br_thread_local_store (char *str); +char *br_locate (void *symbol); +char *br_locate_prefix (void *symbol); +char *br_prepend_prefix (void *symbol, char *path); + + +#endif /* ENABLE_BINRELOC */ + + +/* These macros and functions are not guarded by the ENABLE_BINRELOC + * macro because they are portable. You can use these functions. + */ + +#define br_strcat BR_NAMESPACE(br_strcat) +#define br_extract_dir BR_NAMESPACE(br_extract_dir) +#define br_extract_prefix BR_NAMESPACE(br_extract_prefix) + +#ifndef BR_NO_MACROS + /* Convenience functions for concatenating paths */ + #define BR_SELFPATH(suffix) (br_thread_local_store (br_strcat (SELFPATH, suffix))) + #define BR_PREFIX(suffix) (br_thread_local_store (br_strcat (PREFIX, suffix))) + #define BR_PREFIXDIR(suffix) (br_thread_local_store (br_strcat (BR_PREFIX, suffix))) + #define BR_BINDIR(suffix) (br_thread_local_store (br_strcat (BINDIR, suffix))) + #define BR_SBINDIR(suffix) (br_thread_local_store (br_strcat (SBINDIR, suffix))) + #define BR_DATADIR(suffix) (br_thread_local_store (br_strcat (DATADIR, suffix))) + #define BR_LIBDIR(suffix) (br_thread_local_store (br_strcat (LIBDIR, suffix))) + #define BR_LIBEXECDIR(suffix) (br_thread_local_store (br_strcat (LIBEXECDIR, suffix))) + #define BR_ETCDIR(suffix) (br_thread_local_store (br_strcat (ETCDIR, suffix))) + #define BR_SYSCONFDIR(suffix) (br_thread_local_store (br_strcat (SYSCONFDIR, suffix))) + #define BR_CONFDIR(suffix) (br_thread_local_store (br_strcat (CONFDIR, suffix))) + #define BR_LOCALEDIR(suffix) (br_thread_local_store (br_strcat (LOCALEDIR, suffix))) +#endif + +char *br_strcat (const char *str1, const char *str2); +char *br_extract_dir (const char *path); +char *br_extract_prefix(const char *path); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _PREFIX_H_ */ diff --git a/src/prefs-utils.cpp b/src/prefs-utils.cpp new file mode 100644 index 000000000..54c83c1e9 --- /dev/null +++ b/src/prefs-utils.cpp @@ -0,0 +1,186 @@ +/* + * Utility functions for reading and setting preferences + * + * Authors: + * bulia byak + * + * Copyright (C) 2003 authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "inkscape.h" +#include "xml/repr.h" + + +void +prefs_set_int_attribute(gchar const *path, gchar const *attr, gint value) +{ + Inkscape::XML::Node *repr = inkscape_get_repr(INKSCAPE, path); + if (repr) { + sp_repr_set_int(repr, attr, value); + } +} + +gint +prefs_get_int_attribute(gchar const *path, gchar const *attr, gint def) +{ + Inkscape::XML::Node *repr = inkscape_get_repr(INKSCAPE, path); + if (repr) { + return sp_repr_get_int_attribute(repr, attr, def); + } else { + return def; + } +} + +/** +\brief Retrieves an int attribute guarding against screwed-up data; if the value is beyond limits, default is returned +*/ +gint +prefs_get_int_attribute_limited(gchar const *path, gchar const *attr, gint def, gint min, gint max) +{ + Inkscape::XML::Node *repr = inkscape_get_repr(INKSCAPE, path); + if (repr) { + gint const v = sp_repr_get_int_attribute(repr, attr, def); + if (v >= min && v <= max) { + return v; + } else { + return def; + } + } else { + return def; + } +} + +void +prefs_set_double_attribute(gchar const *path, gchar const *attr, double value) +{ + Inkscape::XML::Node *repr = inkscape_get_repr(INKSCAPE, path); + if (repr) { + sp_repr_set_svg_double(repr, attr, value); + } +} + +double +prefs_get_double_attribute(gchar const *path, gchar const *attr, double def) +{ + Inkscape::XML::Node *repr = inkscape_get_repr(INKSCAPE, path); + if (repr) { + return sp_repr_get_double_attribute(repr, attr, def); + } else { + return def; + } +} + +/** +\brief Retrieves an int attribute guarding against screwed-up data; if the value is beyond limits, default is returned +*/ +double +prefs_get_double_attribute_limited(gchar const *path, gchar const *attr, double def, double min, double max) +{ + Inkscape::XML::Node *repr = inkscape_get_repr(INKSCAPE, path); + if (repr) { + double const v = sp_repr_get_double_attribute(repr, attr, def); + if (v >= min && v <= max) { + return v; + } else { + return def; + } + } else { + return def; + } +} + +gchar const * +prefs_get_string_attribute(gchar const *path, gchar const *attr) +{ + Inkscape::XML::Node *repr = inkscape_get_repr(INKSCAPE, path); + if (repr) { + return (char *) repr->attribute(attr); + } + return NULL; +} + +void +prefs_set_string_attribute(gchar const *path, gchar const *attr, gchar const *value) +{ + Inkscape::XML::Node *repr = inkscape_get_repr(INKSCAPE, path); + if (repr) { + repr->setAttribute(attr, value); + } +} + +void +prefs_set_recent_file(gchar const *uri, gchar const *name) +{ + unsigned const max_documents = prefs_get_int_attribute("options.maxrecentdocuments", "value", 20); + + if (uri != NULL) { + Inkscape::XML::Node *recent = inkscape_get_repr(INKSCAPE, "documents.recent"); + if (recent) { + Inkscape::XML::Node *child = sp_repr_lookup_child(recent, "uri", uri); + if (child) { + recent->changeOrder(child, NULL); + } else { + if (recent->childCount() >= max_documents) { + child = recent->firstChild(); + // count to the last + for (unsigned i = 0; i + 2 < max_documents; ++i) { + child = child->next(); + } + // remove all after the last + while (child->next()) { + sp_repr_unparent(child->next()); + } + } + child = sp_repr_new("document"); + child->setAttribute("uri", uri); + recent->addChild(child, NULL); + } + child->setAttribute("name", name); + } + } +} + +gchar const ** +prefs_get_recent_files() +{ + Inkscape::XML::Node *recent = inkscape_get_repr(INKSCAPE, "documents.recent"); + if (recent) { + unsigned const docs = recent->childCount(); + gchar const **datalst = (gchar const **) g_malloc(sizeof(gchar *) * ((docs * 2) + 1)); + + gint i; + Inkscape::XML::Node *child; + for (i = 0, child = recent->firstChild(); + child != NULL; + child = child->next(), i += 2) + { + gchar const *uri = child->attribute("uri"); + gchar const *name = child->attribute("name"); + datalst[i] = uri; + datalst[i + 1] = name; + } + + datalst[i] = NULL; + return datalst; + } + + return NULL; +} + +/* + 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:textwidth=99 : diff --git a/src/prefs-utils.h b/src/prefs-utils.h new file mode 100644 index 000000000..3cd2998e5 --- /dev/null +++ b/src/prefs-utils.h @@ -0,0 +1,42 @@ +/* + * Utility functions for reading and setting preferences + * + * Authors: + * bulia byak + * + * Copyright (C) 2003 authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifndef SEEN_PREFS_UTILS_H +#define SEEN_PREFS_UTILS_H + +#include + +void prefs_set_int_attribute(gchar const *path, gchar const *attr, gint value); +gint prefs_get_int_attribute(gchar const *path, gchar const *attr, gint def); +gint prefs_get_int_attribute_limited(gchar const *path, gchar const *attr, gint def, gint min, gint max); + +void prefs_set_double_attribute(gchar const *path, gchar const *attr, double value); +double prefs_get_double_attribute(gchar const *path, gchar const *attr, double def); +double prefs_get_double_attribute_limited(gchar const *path, gchar const *attr, double def, double min, double max); + +gchar const *prefs_get_string_attribute(gchar const *path, gchar const *attr); +void prefs_set_string_attribute(gchar const *path, gchar const *attr, gchar const *value); + +void prefs_set_recent_file(const gchar * uri, const gchar * name); +const gchar ** prefs_get_recent_files(void); + +#endif /* !SEEN_PREFS_UTILS_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:encoding=utf-8:textwidth=99 : diff --git a/src/print.cpp b/src/print.cpp new file mode 100644 index 000000000..624021c9a --- /dev/null +++ b/src/print.cpp @@ -0,0 +1,228 @@ +#define __SP_PRINT_C__ + +/** \file + * Frontend to printing + */ +/* + * Author: + * Lauris Kaplinski + * + * This code is in public domain + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + + + +#include "sp-item.h" +#include "extension/print.h" +#include "extension/system.h" +#include "print.h" + +#if 0 +# include + +# ifdef WIN32 +# include +# endif + +# ifdef WITH_GNOME_PRINT +# include +# endif +#endif + +/* Identity typedef */ + +unsigned int sp_print_bind(SPPrintContext *ctx, NR::Matrix const &transform, float opacity) +{ + NRMatrix const ntransform(transform); + return sp_print_bind(ctx, &ntransform, opacity); +} + +unsigned int +sp_print_bind(SPPrintContext *ctx, NRMatrix const *transform, float opacity) +{ + return ctx->module->bind(transform, opacity); +} + +unsigned int +sp_print_release(SPPrintContext *ctx) +{ + return ctx->module->release(); +} + +unsigned int +sp_print_comment(SPPrintContext *ctx, char const *comment) +{ + return ctx->module->comment(comment); +} + +unsigned int +sp_print_fill(SPPrintContext *ctx, NRBPath const *bpath, NRMatrix const *ctm, SPStyle const *style, + NRRect const *pbox, NRRect const *dbox, NRRect const *bbox) +{ + return ctx->module->fill(bpath, ctm, style, pbox, dbox, bbox); +} + +unsigned int +sp_print_stroke(SPPrintContext *ctx, NRBPath const *bpath, NRMatrix const *ctm, SPStyle const *style, + NRRect const *pbox, NRRect const *dbox, NRRect const *bbox) +{ + return ctx->module->stroke(bpath, ctm, style, pbox, dbox, bbox); +} + +unsigned int +sp_print_image_R8G8B8A8_N(SPPrintContext *ctx, + guchar *px, unsigned int w, unsigned int h, unsigned int rs, + NRMatrix const *transform, SPStyle const *style) +{ + return ctx->module->image(px, w, h, rs, transform, style); +} + +unsigned int sp_print_text(SPPrintContext *ctx, char const *text, NR::Point p, + SPStyle const *style) +{ + return ctx->module->text(text, p, style); +} + +#include "display/nr-arena.h" +#include "display/nr-arena-item.h" + +/* UI */ + +void +sp_print_preview_document(SPDocument *doc) +{ + Inkscape::Extension::Print *mod; + unsigned int ret; + + sp_document_ensure_up_to_date(doc); + + mod = Inkscape::Extension::get_print(SP_MODULE_KEY_PRINT_DEFAULT); + + ret = mod->set_preview(); + + if (ret) { + SPPrintContext context; + context.module = mod; + + /* fixme: This has to go into module constructor somehow */ + /* Create new arena */ + mod->base = SP_ITEM(sp_document_root(doc)); + mod->arena = NRArena::create(); + mod->dkey = sp_item_display_key_new(1); + mod->root = sp_item_invoke_show(mod->base, mod->arena, mod->dkey, SP_ITEM_SHOW_DISPLAY); + /* Print document */ + ret = mod->begin(doc); + sp_item_invoke_print(mod->base, &context); + ret = mod->finish(); + /* Release arena */ + sp_item_invoke_hide(mod->base, mod->dkey); + mod->base = NULL; + nr_arena_item_unref(mod->root); + mod->root = NULL; + nr_object_unref((NRObject *) mod->arena); + mod->arena = NULL; + } + + return; +} + +void +sp_print_document(SPDocument *doc, unsigned int direct) +{ + Inkscape::Extension::Print *mod; + unsigned int ret; + + sp_document_ensure_up_to_date(doc); + + if (direct) { + mod = Inkscape::Extension::get_print(SP_MODULE_KEY_PRINT_PS); + } else { + mod = Inkscape::Extension::get_print(SP_MODULE_KEY_PRINT_DEFAULT); + } + + ret = mod->setup(); + + if (ret) { + SPPrintContext context; + context.module = mod; + + /* fixme: This has to go into module constructor somehow */ + /* Create new arena */ + mod->base = SP_ITEM(sp_document_root(doc)); + mod->arena = NRArena::create(); + mod->dkey = sp_item_display_key_new(1); + mod->root = sp_item_invoke_show(mod->base, mod->arena, mod->dkey, SP_ITEM_SHOW_DISPLAY); + /* Print document */ + ret = mod->begin(doc); + sp_item_invoke_print(mod->base, &context); + ret = mod->finish(); + /* Release arena */ + sp_item_invoke_hide(mod->base, mod->dkey); + mod->base = NULL; + nr_arena_item_unref(mod->root); + mod->root = NULL; + nr_object_unref((NRObject *) mod->arena); + mod->arena = NULL; + } + + return; +} + +void +sp_print_document_to_file(SPDocument *doc, gchar const *filename) +{ + Inkscape::Extension::Print *mod; + SPPrintContext context; + gchar const *oldconst; + gchar *oldoutput; + unsigned int ret; + + sp_document_ensure_up_to_date(doc); + + mod = Inkscape::Extension::get_print(SP_MODULE_KEY_PRINT_PS); + oldconst = mod->get_param_string("destination"); + oldoutput = g_strdup(oldconst); + mod->set_param_string("destination", (gchar *)filename); + +/* Start */ + context.module = mod; + /* fixme: This has to go into module constructor somehow */ + /* Create new arena */ + mod->base = SP_ITEM(sp_document_root(doc)); + mod->arena = NRArena::create(); + mod->dkey = sp_item_display_key_new(1); + mod->root = sp_item_invoke_show(mod->base, mod->arena, mod->dkey, SP_ITEM_SHOW_DISPLAY); + /* Print document */ + ret = mod->begin(doc); + sp_item_invoke_print(mod->base, &context); + ret = mod->finish(); + /* Release arena */ + sp_item_invoke_hide(mod->base, mod->dkey); + mod->base = NULL; + nr_arena_item_unref(mod->root); + mod->root = NULL; + nr_object_unref((NRObject *) mod->arena); + mod->arena = NULL; +/* end */ + + mod->set_param_string("destination", oldoutput); + g_free(oldoutput); + + return; +} + + +/* + 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:textwidth=99 : diff --git a/src/print.h b/src/print.h new file mode 100644 index 000000000..0ec3fb321 --- /dev/null +++ b/src/print.h @@ -0,0 +1,58 @@ +#ifndef PRINT_H_INKSCAPE +#define PRINT_H_INKSCAPE + +/** \file + * Frontend to printing + */ +/* + * Author: + * Lauris Kaplinski + * + * This code is in public domain + */ + +#include +#include "forward.h" +#include "extension/extension-forward.h" + +struct SPPrintContext { + Inkscape::Extension::Print *module; +}; + +unsigned int sp_print_bind(SPPrintContext *ctx, NR::Matrix const &transform, float opacity); +unsigned int sp_print_bind(SPPrintContext *ctx, NRMatrix const *transform, float opacity); +unsigned int sp_print_release(SPPrintContext *ctx); +unsigned int sp_print_comment(SPPrintContext *ctx, char const *comment); +unsigned int sp_print_fill(SPPrintContext *ctx, NRBPath const *bpath, NRMatrix const *ctm, SPStyle const *style, + NRRect const *pbox, NRRect const *dbox, NRRect const *bbox); +unsigned int sp_print_stroke(SPPrintContext *ctx, NRBPath const *bpath, NRMatrix const *transform, SPStyle const *style, + NRRect const *pbox, NRRect const *dbox, NRRect const *bbox); + +unsigned int sp_print_image_R8G8B8A8_N(SPPrintContext *ctx, + guchar *px, unsigned int w, unsigned int h, unsigned int rs, + NRMatrix const *transform, SPStyle const *style); + +unsigned int sp_print_text(SPPrintContext *ctx, char const *text, NR::Point p, + SPStyle const *style); + +void sp_print_get_param(SPPrintContext *ctx, gchar *name, bool *value); + + +/* UI */ +void sp_print_preview_document(SPDocument *doc); +void sp_print_document(SPDocument *doc, unsigned int direct); +void sp_print_document_to_file(SPDocument *doc, gchar const *filename); + + +#endif /* !PRINT_H_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:textwidth=99 : diff --git a/src/proofs b/src/proofs new file mode 100644 index 000000000..a3a22733f --- /dev/null +++ b/src/proofs @@ -0,0 +1,332 @@ +This file contains some loose proofs of a few properties. It's somewhat +ad-hoc. At least it gives an indication of what assert/g_assert calls have +been checked by a developer. If an assertion does trigger, then this file may +help in debugging that assertion failure. + +It's currently ordered by caller. + +(Re-ordering to avoid forward references in proofs might be a good idea, +though this would in some cases require splitting up the proofs for a routine, +e.g. proving preconditions of g called from f, then proving g's postcondition, +then using that to prove something else in f again. Furthermore it may not +even be possible to avoid forward references for recursive/looping code.) + + + +src/pencil-context.cpp:fit_and_split + +Very loose proof of !sp_curve_empty (pc->red_curve) assertion: +fit_and_split is called successively with its input varying only by appending a point. +For the n_segs > 0 && unsigned(pc->npoints) < G_N_ELEMENTS(pc->p) condition to fail, +we must have at least 3 distinct points, which means that a previous call had 2 distinct points, +in which case we'd have filled in pc->red_curve to a non-empty curve. + +Expansion of the above claim of at least 3 distinct points: We know n_segs <= 0 || +unsigned(dc->npoints) >= G_N_ELEMENTS(pc->p) from the negation of the containing `if' condition. +G_N_ELEMENTS(pc->p) is greater than 3 (in int arithmetic), from SPPencilContext::p array definition +in pencil-context.h. npoints grows by no more than one per fit_and_split invocation; we should be +able to establish that dc->npoints == G_N_ELEMENTS(pc->p) if unsigned(dc->npoints) >= +G_N_ELEMENTS(pc->p), in which case 3 <= dc->npoints in int arithmetic. We know that dc->npoints >= +2 from assertion at head of fit_and_split; in which case if n_segs <= 0 then fit_and_split has +failed, which implies that dc->npoints > 2 (since the fitter can always exactly fit 2 points, +i.e. it never fails if npoints == 2; TODO: add sp_bezier_fit_cubic postcondition for this). + + +src/pencil-context.cpp:fit_and_split + +Proof of precondition: The only caller is spdc_add_freehand_point (by +textual search in that file, and staticness). See proof for that +function. + + +src/pencil-context.cpp:spdc_add_freehand_point + +Proof of fit_and_split `pc->npoints > 1' requirement: +It initially unconditionally asserts `pc->npoints > 0'. There are no function calls or modifications +of pc or pc->npoints other than incrementing pc->npoints after that assertion. +We assume that integer overflow doesn't occur during that increment, +so we get pc->npoints > 1. + + +src/pencil-context.cpp:spdc_set_endpoint + +Very loose proof of npoints > 0: Should be preceded by spdc_set_startpoint(pc) according to state +transitions. spdc_set_startpoint sets pc->npoints to 0 (handled at beginning of function) or 1. + + +src/display/bezier-utils.cpp:compute_max_error + +Proof of postcondition: *splitPoint is set only from i, which goes from 1 to less than last. +i isn't written to in the loop body: only uses are indexing built-in arrays d and u +(and RHS of assignment). + + +src/display/bezier-utils.cpp:sp_bezier_fit_cubic_full + +Proof of `nsegs1 != 0' assertion: nsegs1 is const. Have already +returned in the (nsegs1 < 0) case, so !(nsegs1 < 0), i.e. nsegs1 >= 0 +(given that nsegs1 is gint). nsegs1 is set to +sp_bezier_fit_cubic_full(_, _, _, splitPoint + 1, ...). We will show +that sp_bezier_fit_cubic_full ensures len < 2 || ret != 0. splitPoint +> 0 from compute_max_error postcondition combined with error >= +precondition and thus having handled the compute_max_error returning 0 +case: if returned 0 for maxError then maxError <= error * 9.0 would be +true, and we recalculate splitPoint; if the renewed maxError is 0 then +the maxError <= error test will succeed and we return. If we don't +return, then the most recent compute_max_error must have returned +non-zero, which implies (through compute_max_error postcondition) that +splitPoint would have been set s.t. 0 < splitPoint. splitPoint is not +subsequently written to. (It is subsequently passed only to +sp_darray_center_tangent 2nd arg, which is a plain unsigned rather +than reference.) 0 < splitPoint < last guarantees splitPoint + 1 >= +2. (We know splitPoint + 1 won't overflow because last = len - 1 and +len is of the same type as splitPoint.) Passing splitPoint + 1 for +len of the call that sets nsegs1 ensures that nsegs1 is non-zero (from +the len < 2 || ret != 0 property that we show below). QED. + +Proof that len < 2 || (failed no-dups precondition) || ret != 0: All +returns are either -1, 0, 1, or nsegs1 + nsegs2. There are two +literal 0 cases: one conditional on len < 2, and the other for failed +precondition (non-uniqued data). For the nsegs1 + nsegs2 case, we've +already ruled out nsegs1 < 0 (through conditional return) and nsegs2 < +0 (same). The nsegs1 + nsegs2 case occurs only when we recurse; we've +already shown the desired property for non-recursive case. In the +nsegs1 non-recursive case, we have that nsegs1 != 0, which combined +with !(nsegs1 < 0) and !(nsegs2 < 0) implies that nsegs1 + nsegs2 +either overflows or is greater than 0. We should be able to show that +nsegs1 + nsegs2 < len even with exact arithmetic. (Very loose proof: +given that len >= 2 (from earlier conditional return), we can fit len +points using len-1 segments even using straight line segments.) +nsegs1 and nsegs2 are the same type as len, and we've shown that +nsegs1 + nsegs2 in exact arithmetic is >= 0 from each operand being +non-negative, so nsegs1 + nsegs2 doesn't overflow. Thus nsegs1 + +nsegs2 > 0. Thus we have shown for each return point that either the +return value is -1 or > 0 or occurs when len < 2 or in failure of +no-dups precondition. (We should also show that no-dups outer +precondition being met implies it being met for inner instances of +sp_bezier_fit_cubic_full, because we pass a subsequence of the data +array, and don't write to that array.) QED. + +We should also show that the recursion is finite for the inductive +proof to hold. The finiteness comes from inner calls having len > 0 +and len less than that of outer calls (from splitPoint calculation and +0 < splitPoint < last for recursive case and last < len and transitive +property of < for gint). If len < 2 then we don't recurse +(conditional return). + +We should go over this proof to make it clear that there are no +"forward references" other than for recursive case. We could also be +more formal in use of inductive proof (e.g. clearly stating what the +base and inductive premises are; namely the non-recursing and +recursing cases of sp_bezier_fit_cubic_full). + +Better proof sketch that nseg1 + nsegs2 < len: ret < len for each +recursive case other than where len > 0 precondition fails. nsegs1 is +calculated for inner len=splitPoint + 1, nsegs2 for inner len=len - +splitPoint. Assuming exact arithmetic we'll transform that to ret <= +len - 1. Implies that in exact arithmetic, nsegs1 + nsegs2 <= +(splitPoint + 1 - 1) + (len - splitPoint - 1). Simplifying RHS (using +exact arithmetic): nsegs1 + nsegs2 <= len - 1, i.e. nsegs1 + nsegs2 < +len. Presumably we can show that machine arithmetic gets the same +results as exact arithmetic from similar arguments used so far for +showing that overflow doesn't occur. For the recursive case the +return values are either nsegs1 + nsegs2 or -1. + +We should also show that inner preconditions hold, especially the len +> 0 precondition. (For nsegs1 call, we use 0 < splitPoint and that +splitPoint + 1 doesn't overflow. For nsegs2 call, we pass len - +splitPoint; combine with splitPoint < last, last = len - 1, and no +overflow.) We've already sketched a proof for no-dups precondition. +The others are fairly simple. + +For error >= 0: error is const, and we pass it to all recursions. + +For inner max_beziers >= 1: recursions are conditional on outer +1 < max_beziers before setting rec_max_beziers1 to max_beziers - 1, +and passing rec_max_beziers1 as inner max_beziers value, +so we have outer max_beziers >= 2 so inner max_beziers >= 1. +max_beziers and rec_max_beziers1 are both const. + + +src/display/bezier-utils.cpp:sp_darray_right_tangent(Point const[], unsigned) + +Proof of unit_vector precondition that a != Point(0, 0): our unequal precondition. + +Loose (incorrect) proof of unit_vector precondition that neither +coordinate is NaN: our in_svg_plane precondition, and fact that +in_svg_plane returns false if either argument is infinite. HOWEVER, +the unchecked in_svg_plane precondition isn't currently guaranteed, so +we're just relying on the input points never being infinity (which +might occur with strange zoom settings). + + +src/display/bezier-utils.cpp:sp_darray_right_tangent(Point const[], unsigned, double) + +Loose proof of unit_vector precondition that a != Point(0, 0) for first call to unit_vector: + +We've asserted that 0 <= tolerance_sq; combine with tolerance_sq < +distsq and transitivity of <=/< show that 0 < distsq. Definition of +dot should give us that t != 0.0, given that 0.0 * 0.0 == +0.0, and 0 +< +0.0 is false. + +Loose proof for the second unit_vector invocation: distsq != 0 from ?: +condition, which should give us that t != Point(0, 0) in the same way +as in the above proof. + +Proof of sp_darray_right_tangent(Point[], unsigned) preconditions: We +have the same preconditions, and pass the same arguments. d, *d and +len are const. + + + +src/extension/internal/ps.cpp:PrintPS::print_fill_style: + +Proof of the + g_return_if_fail( style->fill.type == SP_PAINT_TYPE_COLOR + || ( style->fill.type == SP_PAINT_TYPE_PAINTSERVER + && SP_IS_GRADIENT(SP_STYLE_FILL_SERVER(style)) ) ) +at beginning of function: + +rgrep print_fill_style reveals no callers in any other files. There are two calls in ps.cpp, both +inside an `if' test of that same condition (with no relevant lines between the test and the call). +Each call uses `style' as its second argument, and `style' in print_fill_style refers to its second +parameter. In both caller & callee, `style' is a const pointer to const, and there is very little +code between the two tests, so the relevant values are very unlikely to change between the two +tests. + + +Proof of + g_assert( style->fill.type == SP_PAINT_TYPE_PAINTSERVER + && SP_IS_GRADIENT(SP_STYLE_FILL_SERVER(style)) ) : + +The g_return_if_fail(style->fill.type == SP_PAINT_TYPE_COLOR + || ( style->fill.type == SP_PAINT_TYPE_PAINTSERVER + && SP_IS_GRADIENT(SP_STYLE_FILL_SERVER(style)) ) ) +call at the beginning of the function, and we're in the `else' branch of a test for +style->fill.type == SP_PAINT_TYPE_COLOR, and style is a const pointer to const, so it's likely that +style->fill and the gradient object have the same values throughout. + + + +src/extensions/internal/ps.cpp:PrintPS::fill: + +Proof of the two assertions + g_assert( style->fill.type == SP_PAINT_TYPE_PAINTSERVER + && SP_IS_GRADIENT(SP_STYLE_FILL_SERVER(style)) ) : + +Each is in the `else' branch of a test for `style->fill.type == SP_PAINT_TYPE_COLOR', +within a test for + ( style->fill.type == SP_PAINT_TYPE_COLOR + || ( style->fill.type == SP_PAINT_TYPE_PAINTSERVER + && SP_IS_GRADIENT(SP_STYLE_FILL_SERVER(style)) ) ). + +`style' is a const pointer to const, so the values are unlikely to have changed between the tests. + + + +src/seltrans.cpp:sp_sel_trans_update_handles + +Proof of requirements of sp_show_handles: + +sp_show_handles requirements: !arg1.empty. + +Before any call to sp_show_handles is a test `if (... || seltrans.empty) { ...; return; }' +(with no `break' etc. call preventing that `return'). +Each subsequent sp_show_handles call uses seltrans as arg1. +seltrans is a reference. There are no calls between that failing seltrans.empty test +and the sp_show_handles calls that pass seltrans. The sole call is sp_remove_handles, +probably doesn't have access to seltrans. + + + +src/seltrans.cpp:sp_show_handles + +Proof of precondition: + +sp_show_handles is static. Searching reveals calls only in sp_sel_trans_update_handles (proof above). + + + +src/sp-spiral.cpp:sp_spiral_fit_and_draw + +Proof of postcondition is_unit_vector(*hat2): + +hat2 is set by sp_spiral_get_tangent unconditionally, which Ensures is_unit_vector(*hat2). +We then negate *hat2, which doesn't affect its length. +We pass it only to sp_bezier_fit_cubic_full, which claims constness of *hat2. + +Proof of unconditionalness: Not inside if/for/while. No previous `return'. + + +src/sp-spiral.cpp:sp_spiral_set_shape + +Loose proof of requirements for sp_spiral_fit_and_draw: + + Proof of dstep > 0: + + SAMPLE_STEP equals .25. + spiral->revo is bounded to [0.05, 20.0] (and non-NaN) by various CLAMP calls. + (TODO: Add precondition, given that those CLAMP calls are outside of this function.) + SAMPLE_SIZE equals 8. + dstep is const and equals SAMPLE_STEP / spiral->revo / (SAMPLE_SIZE - 1), + == 1 / (4 * [.05, 20.0] * 7) + == 1 / [1.4, 560] + dstep in [.0018, .714]. + + Proof of is_unit_vector(hat1): + + Initially guaranteed by sp_spiral_get_tangent Ensures. + For subsequent calls, hat1 is set from negated hat2 as set by sp_spiral_fit_and_draw, + which Ensures is_unit_vector(hat2). + + + +src/style.cpp:sp_css_attr_from_style: + +Proof of sp_style_write_string pre `style != NULL': + +Passes style as style argument. style is const, and has already been checked against NULL. + + +src/style.cpp:sp_css_attr_from_object + +Proof of `flags in {IFSET, ALWAYS} precondition: + + $ grep sp_css_attr_from_object `sed 's,#.*,,' make.files ` + file.cpp: SPCSSAttr *style = sp_css_attr_from_object (SP_DOCUMENT_ROOT (doc)); + selection-chemistry.cpp: SPCSSAttr *css = sp_css_attr_from_object (SP_OBJECT(item), SP_STYLE_FLAG_ALWAYS); + selection-chemistry.cpp: SPCSSAttr *temp = sp_css_attr_from_object (last_element, SP_STYLE_FLAG_IFSET); + style.cpp:sp_css_attr_from_object (SPObject *object, guint flags) + style.h:SPCSSAttr *sp_css_attr_from_object(SPObject *object, guint flags = SP_STYLE_FLAG_IFSET); + + +src/style.cpp:sp_css_attr_from_style + +Proof of precondition `style != NULL': + +Callers are selection-chemistry.cpp and style.cpp: + + $ grep sp_css_attr_from_style `sed 's,#.*,,' make.files ` +selection-chemistry.cpp: SPCSSAttr *css = sp_css_attr_from_style (query, SP_STYLE_FLAG_ALWAYS); + style.cpp:sp_css_attr_from_style (SPStyle const *const style, guint flags) + style.cpp: return sp_css_attr_from_style (style, flags); + style.h:SPCSSAttr *sp_css_attr_from_style (SPStyle const *const style, guint flags); + +selection-chemistry.cpp caller: query is initialized from sp_style_new() +(which guarantees non-NULL), and is const. + +style.cpp caller: preceded by explicit test for NULL: + + $ grep -B2 sp_css_attr_from_style style.cpp|tail -3 + if (style == NULL) + return NULL; + return sp_css_attr_from_style (style, flags); + + + + +# Local Variables: +# mode:indented-text +# fill-column:99 +# End: +# vim: filetype=text:tabstop=8:encoding=utf-8:textwidth=99 : diff --git a/src/rect-context.cpp b/src/rect-context.cpp new file mode 100644 index 000000000..be56047f0 --- /dev/null +++ b/src/rect-context.cpp @@ -0,0 +1,501 @@ +#define __SP_RECT_CONTEXT_C__ + +/* + * Rectangle drawing context + * + * Author: + * Lauris Kaplinski + * bulia byak + * + * Copyright (C) 2000-2005 authors + * Copyright (C) 2000-2001 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "config.h" + +#include + +#include "macros.h" +#include "display/sp-canvas.h" +#include "sp-rect.h" +#include "document.h" +#include "sp-namedview.h" +#include "selection.h" +#include "desktop-handles.h" +#include "snap.h" +#include "desktop.h" +#include "desktop-style.h" +#include "message-context.h" +#include "pixmaps/cursor-rect.xpm" +#include "rect-context.h" +#include "sp-metrics.h" +#include +#include "object-edit.h" +#include "xml/repr.h" +#include "xml/node-event-vector.h" +#include "prefs-utils.h" +#include "context-fns.h" + +static void sp_rect_context_class_init(SPRectContextClass *klass); +static void sp_rect_context_init(SPRectContext *rect_context); +static void sp_rect_context_dispose(GObject *object); + +static void sp_rect_context_setup(SPEventContext *ec); +static void sp_rect_context_set(SPEventContext *ec, gchar const *key, gchar const *val); + +static gint sp_rect_context_root_handler(SPEventContext *event_context, GdkEvent *event); +static gint sp_rect_context_item_handler(SPEventContext *event_context, SPItem *item, GdkEvent *event); + +static void sp_rect_drag(SPRectContext &rc, NR::Point const pt, guint state); +static void sp_rect_finish(SPRectContext *rc); + +static SPEventContextClass *parent_class; + + +GtkType sp_rect_context_get_type() +{ + static GType type = 0; + if (!type) { + GTypeInfo info = { + sizeof(SPRectContextClass), + NULL, NULL, + (GClassInitFunc) sp_rect_context_class_init, + NULL, NULL, + sizeof(SPRectContext), + 4, + (GInstanceInitFunc) sp_rect_context_init, + NULL, /* value_table */ + }; + type = g_type_register_static(SP_TYPE_EVENT_CONTEXT, "SPRectContext", &info, (GTypeFlags) 0); + } + return type; +} + +static void sp_rect_context_class_init(SPRectContextClass *klass) +{ + GObjectClass *object_class = (GObjectClass *) klass; + SPEventContextClass *event_context_class = (SPEventContextClass *) klass; + + parent_class = (SPEventContextClass *) g_type_class_peek_parent(klass); + + object_class->dispose = sp_rect_context_dispose; + + event_context_class->setup = sp_rect_context_setup; + event_context_class->set = sp_rect_context_set; + event_context_class->root_handler = sp_rect_context_root_handler; + event_context_class->item_handler = sp_rect_context_item_handler; +} + +static void sp_rect_context_init(SPRectContext *rect_context) +{ + SPEventContext *event_context = SP_EVENT_CONTEXT(rect_context); + + event_context->cursor_shape = cursor_rect_xpm; + event_context->hot_x = 4; + event_context->hot_y = 4; + event_context->xp = 0; + event_context->yp = 0; + event_context->tolerance = 0; + event_context->within_tolerance = false; + event_context->item_to_select = NULL; + + event_context->shape_repr = NULL; + event_context->shape_knot_holder = NULL; + + rect_context->item = NULL; + + rect_context->rx = 0.0; + rect_context->ry = 0.0; + + new (&rect_context->sel_changed_connection) sigc::connection(); +} + +static void sp_rect_context_dispose(GObject *object) +{ + SPRectContext *rc = SP_RECT_CONTEXT(object); + SPEventContext *ec = SP_EVENT_CONTEXT(object); + + ec->enableGrDrag(false); + + rc->sel_changed_connection.disconnect(); + rc->sel_changed_connection.~connection(); + + /* fixme: This is necessary because we do not grab */ + if (rc->item) { + sp_rect_finish(rc); + } + + if (ec->shape_knot_holder) { + sp_knot_holder_destroy(ec->shape_knot_holder); + ec->shape_knot_holder = NULL; + } + + if (ec->shape_repr) { // remove old listener + sp_repr_remove_listener_by_data(ec->shape_repr, ec); + Inkscape::GC::release(ec->shape_repr); + ec->shape_repr = 0; + } + + if (rc->_message_context) { + delete rc->_message_context; + } + + G_OBJECT_CLASS(parent_class)->dispose(object); +} + +static Inkscape::XML::NodeEventVector ec_shape_repr_events = { + NULL, /* child_added */ + NULL, /* child_removed */ + ec_shape_event_attr_changed, + NULL, /* content_changed */ + NULL /* order_changed */ +}; + +/** +\brief Callback that processes the "changed" signal on the selection; +destroys old and creates new knotholder +*/ +void sp_rect_context_selection_changed(Inkscape::Selection *selection, gpointer data) +{ + SPRectContext *rc = SP_RECT_CONTEXT(data); + SPEventContext *ec = SP_EVENT_CONTEXT(rc); + + if (ec->shape_knot_holder) { // destroy knotholder + sp_knot_holder_destroy(ec->shape_knot_holder); + ec->shape_knot_holder = NULL; + } + + if (ec->shape_repr) { // remove old listener + sp_repr_remove_listener_by_data(ec->shape_repr, ec); + Inkscape::GC::release(ec->shape_repr); + ec->shape_repr = 0; + } + + SPItem *item = selection->singleItem(); + if (item) { + ec->shape_knot_holder = sp_item_knot_holder(item, ec->desktop); + Inkscape::XML::Node *shape_repr = SP_OBJECT_REPR(item); + if (shape_repr) { + ec->shape_repr = shape_repr; + Inkscape::GC::anchor(shape_repr); + sp_repr_add_listener(shape_repr, &ec_shape_repr_events, ec); + sp_repr_synthesize_events(shape_repr, &ec_shape_repr_events, ec); + } + } +} + +static void sp_rect_context_setup(SPEventContext *ec) +{ + SPRectContext *rc = SP_RECT_CONTEXT(ec); + + if (((SPEventContextClass *) parent_class)->setup) { + ((SPEventContextClass *) parent_class)->setup(ec); + } + + SPItem *item = SP_DT_SELECTION(ec->desktop)->singleItem(); + if (item) { + ec->shape_knot_holder = sp_item_knot_holder(item, ec->desktop); + Inkscape::XML::Node *shape_repr = SP_OBJECT_REPR(item); + if (shape_repr) { + ec->shape_repr = shape_repr; + Inkscape::GC::anchor(shape_repr); + sp_repr_add_listener(shape_repr, &ec_shape_repr_events, ec); + sp_repr_synthesize_events(shape_repr, &ec_shape_repr_events, ec); + } + } + + rc->sel_changed_connection.disconnect(); + rc->sel_changed_connection = SP_DT_SELECTION(ec->desktop)->connectChanged( + sigc::bind(sigc::ptr_fun(&sp_rect_context_selection_changed), (gpointer)rc) + ); + + sp_event_context_read(ec, "rx"); + sp_event_context_read(ec, "ry"); + + if (prefs_get_int_attribute("tools.shapes", "selcue", 0) != 0) { + ec->enableSelectionCue(); + } + + if (prefs_get_int_attribute("tools.shapes", "gradientdrag", 0) != 0) { + ec->enableGrDrag(); + } + + rc->_message_context = new Inkscape::MessageContext((ec->desktop)->messageStack()); +} + +static void sp_rect_context_set(SPEventContext *ec, gchar const *key, gchar const *val) +{ + SPRectContext *rc = SP_RECT_CONTEXT(ec); + + /* fixme: Proper error handling for non-numeric data. Use a locale-independent function like + * g_ascii_strtod (or a thin wrapper that does the right thing for invalid values inf/nan). */ + if ( strcmp(key, "rx") == 0 ) { + rc->rx = ( val + ? g_ascii_strtod (val, NULL) + : 0.0 ); + } else if ( strcmp(key, "ry") == 0 ) { + rc->ry = ( val + ? g_ascii_strtod (val, NULL) + : 0.0 ); + } +} + +static gint sp_rect_context_item_handler(SPEventContext *event_context, SPItem *item, GdkEvent *event) +{ + SPDesktop *desktop = event_context->desktop; + + gint ret = FALSE; + + switch (event->type) { + case GDK_BUTTON_PRESS: + if ( event->button.button == 1 ) { + Inkscape::setup_for_drag_start(desktop, event_context, event); + ret = TRUE; + } + break; + // motion and release are always on root (why?) + default: + break; + } + + if (((SPEventContextClass *) parent_class)->item_handler) { + ret = ((SPEventContextClass *) parent_class)->item_handler(event_context, item, event); + } + + return ret; +} + +static gint sp_rect_context_root_handler(SPEventContext *event_context, GdkEvent *event) +{ + static bool dragging; + + SPDesktop *desktop = event_context->desktop; + Inkscape::Selection *selection = SP_DT_SELECTION (desktop); + + SPRectContext *rc = SP_RECT_CONTEXT(event_context); + + event_context->tolerance = prefs_get_int_attribute_limited("options.dragtolerance", "value", 0, 0, 100); + + gint ret = FALSE; + switch (event->type) { + case GDK_BUTTON_PRESS: + if ( event->button.button == 1 ) { + NR::Point const button_w(event->button.x, + event->button.y); + + // save drag origin + event_context->xp = (gint) button_w[NR::X]; + event_context->yp = (gint) button_w[NR::Y]; + event_context->within_tolerance = true; + + // remember clicked item, disregarding groups, honoring Alt + event_context->item_to_select = sp_event_context_find_item (desktop, button_w, event->button.state & GDK_MOD1_MASK, TRUE); + + dragging = true; + + /* Position center */ + NR::Point const button_dt(desktop->w2d(button_w)); + + /* Snap center */ + SnapManager const m(desktop->namedview); + rc->center = m.freeSnap(Inkscape::Snapper::SNAP_POINT | Inkscape::Snapper::BBOX_POINT, + button_dt, rc->item).getPoint(); + + sp_canvas_item_grab(SP_CANVAS_ITEM(desktop->acetate), + ( GDK_KEY_PRESS_MASK | + GDK_BUTTON_RELEASE_MASK | + GDK_POINTER_MOTION_MASK | + GDK_POINTER_MOTION_HINT_MASK | + GDK_BUTTON_PRESS_MASK ), + NULL, event->button.time); + ret = TRUE; + } + break; + case GDK_MOTION_NOTIFY: + if ( dragging + && ( event->motion.state & GDK_BUTTON1_MASK ) ) + { + if ( event_context->within_tolerance + && ( abs( (gint) event->motion.x - event_context->xp ) < event_context->tolerance ) + && ( abs( (gint) event->motion.y - event_context->yp ) < event_context->tolerance ) ) { + break; // do not drag if we're within tolerance from origin + } + // Once the user has moved farther than tolerance from the original location + // (indicating they intend to draw, not click), then always process the + // motion notify coordinates as given (no snapping back to origin) + event_context->within_tolerance = false; + + NR::Point const motion_w(event->motion.x, + event->motion.y); + NR::Point const motion_dt(desktop->w2d(motion_w)); + sp_rect_drag(*rc, motion_dt, event->motion.state); + ret = TRUE; + } + break; + case GDK_BUTTON_RELEASE: + event_context->xp = event_context->yp = 0; + if ( event->button.button == 1 ) { + dragging = false; + + if (!event_context->within_tolerance) { + // we've been dragging, finish the rect + sp_rect_finish(rc); + } else if (event_context->item_to_select) { + // no dragging, select clicked item if any + if (event->button.state & GDK_SHIFT_MASK) { + selection->toggle(event_context->item_to_select); + } else { + selection->set(event_context->item_to_select); + } + } else { + // click in an empty space + selection->clear(); + } + + event_context->item_to_select = NULL; + ret = TRUE; + sp_canvas_item_ungrab(SP_CANVAS_ITEM(desktop->acetate), + event->button.time); + } + break; + case GDK_KEY_PRESS: + switch (get_group0_keyval (&event->key)) { + case GDK_Alt_L: + case GDK_Alt_R: + case GDK_Control_L: + case GDK_Control_R: + case GDK_Shift_L: + case GDK_Shift_R: + case GDK_Meta_L: // Meta is when you press Shift+Alt (at least on my machine) + case GDK_Meta_R: + sp_event_show_modifier_tip (event_context->defaultMessageContext(), event, + _("Ctrl: make square or integer-ratio rect, lock a rounded corner circular"), + _("Shift: draw around the starting point"), + NULL); + break; + case GDK_Up: + case GDK_Down: + case GDK_KP_Up: + case GDK_KP_Down: + // prevent the zoom field from activation + if (!MOD__CTRL_ONLY) + ret = TRUE; + break; + + case GDK_x: + case GDK_X: + if (MOD__ALT_ONLY) { + desktop->setToolboxFocusTo ("altx-rect"); + ret = TRUE; + } + break; + + case GDK_Escape: + SP_DT_SELECTION(desktop)->clear(); + //TODO: make dragging escapable by Esc + default: + break; + } + break; + case GDK_KEY_RELEASE: + switch (get_group0_keyval (&event->key)) { + case GDK_Alt_L: + case GDK_Alt_R: + case GDK_Control_L: + case GDK_Control_R: + case GDK_Shift_L: + case GDK_Shift_R: + case GDK_Meta_L: // Meta is when you press Shift+Alt + case GDK_Meta_R: + event_context->defaultMessageContext()->clear(); + break; + default: + break; + } + break; + default: + break; + } + + if (!ret) { + if (((SPEventContextClass *) parent_class)->root_handler) { + ret = ((SPEventContextClass *) parent_class)->root_handler(event_context, event); + } + } + + return ret; +} + +static void sp_rect_drag(SPRectContext &rc, NR::Point const pt, guint state) +{ + SPDesktop *desktop = SP_EVENT_CONTEXT(&rc)->desktop; + + if (!rc.item) { + + if (Inkscape::have_viable_layer(desktop, rc._message_context) == false) { + return; + } + + /* Create object */ + Inkscape::XML::Node *repr = sp_repr_new("svg:rect"); + + /* Set style */ + sp_desktop_apply_style_tool (desktop, repr, "tools.shapes.rect", false); + + rc.item = (SPItem *) desktop->currentLayer()->appendChildRepr(repr); + Inkscape::GC::release(repr); + rc.item->transform = SP_ITEM(desktop->currentRoot())->getRelativeTransform(desktop->currentLayer()); + rc.item->updateRepr(); + } + + NR::Rect const r = Inkscape::snap_rectangular_box(desktop, rc.item, pt, rc.center, state); + + sp_rect_position_set(SP_RECT(rc.item), r.min()[NR::X], r.min()[NR::Y], r.dimensions()[NR::X], r.dimensions()[NR::Y]); + if ( rc.rx != 0.0 ) { + sp_rect_set_rx (SP_RECT(rc.item), TRUE, rc.rx); + } + if ( rc.ry != 0.0 ) { + if (rc.rx == 0.0) + sp_rect_set_ry (SP_RECT(rc.item), TRUE, CLAMP(rc.ry, 0, MIN(r.dimensions()[NR::X], r.dimensions()[NR::Y])/2)); + else + sp_rect_set_ry (SP_RECT(rc.item), TRUE, CLAMP(rc.ry, 0, r.dimensions()[NR::Y])); + } + + // status text + GString *xs = SP_PX_TO_METRIC_STRING(r.dimensions()[NR::X], desktop->namedview->getDefaultMetric()); + GString *ys = SP_PX_TO_METRIC_STRING(r.dimensions()[NR::Y], desktop->namedview->getDefaultMetric()); + rc._message_context->setF(Inkscape::NORMAL_MESSAGE, _("Rectangle: %s × %s; with Ctrl to make square or integer-ratio rectangle; with Shift to draw around the starting point"), xs->str, ys->str); + g_string_free(xs, FALSE); + g_string_free(ys, FALSE); +} + +static void sp_rect_finish(SPRectContext *rc) +{ + rc->_message_context->clear(); + + if ( rc->item != NULL ) { + SPDesktop * dt; + + dt = SP_EVENT_CONTEXT_DESKTOP(rc); + + SP_OBJECT(rc->item)->updateRepr(); + + SP_DT_SELECTION(dt)->set(rc->item); + sp_document_done(SP_DT_DOCUMENT(dt)); + + rc->item = NULL; + } +} + +/* + 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:textwidth=99 : diff --git a/src/rect-context.h b/src/rect-context.h new file mode 100644 index 000000000..782102b73 --- /dev/null +++ b/src/rect-context.h @@ -0,0 +1,51 @@ +#ifndef __SP_RECT_CONTEXT_H__ +#define __SP_RECT_CONTEXT_H__ + +/* + * Rectangle drawing context + * + * Author: + * Lauris Kaplinski + * + * Copyright (C) 2000 Lauris Kaplinski + * Copyright (C) 2000-2001 Ximian, Inc. + * Copyright (C) 2002 Lauris Kaplinski + * + * Released under GNU GPL + */ + +#include +#include "event-context.h" +#include "libnr/nr-point.h" +struct SPKnotHolder; + +#define SP_TYPE_RECT_CONTEXT (sp_rect_context_get_type ()) +#define SP_RECT_CONTEXT(obj) (GTK_CHECK_CAST ((obj), SP_TYPE_RECT_CONTEXT, SPRectContext)) +#define SP_RECT_CONTEXT_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), SP_TYPE_RECT_CONTEXT, SPRectContextClass)) +#define SP_IS_RECT_CONTEXT(obj) (GTK_CHECK_TYPE ((obj), SP_TYPE_RECT_CONTEXT)) +#define SP_IS_RECT_CONTEXT_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), SP_TYPE_RECT_CONTEXT)) + +class SPRectContext; +class SPRectContextClass; + +struct SPRectContext : public SPEventContext { + SPItem *item; + NR::Point center; + + gdouble rx; /* roundness radius (x direction) */ + gdouble ry; /* roundness radius (y direction) */ + + sigc::connection sel_changed_connection; + + Inkscape::MessageContext *_message_context; +}; + +struct SPRectContextClass { + SPEventContextClass parent_class; +}; + +/* Standard Gtk function */ + +GtkType sp_rect_context_get_type (void); + +#endif diff --git a/src/registrytool.cpp b/src/registrytool.cpp new file mode 100644 index 000000000..6747a0dd8 --- /dev/null +++ b/src/registrytool.cpp @@ -0,0 +1,211 @@ +/** + * Inkscape Registry Tool + * + * This simple tool is intended for allowing Inkscape to append subdirectories + * to its path. This will allow extensions and other files to be accesses + * without explicit user intervention. + * + * Authors: + * Bob Jamison + * + * Copyright (C) 2005 Bob Jamison + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include + +#include "registrytool.h" + + +typedef struct +{ + HKEY key; + int strlen; + char *str; +} KeyTableEntry; + + + +KeyTableEntry keyTable[] = +{ + { HKEY_CLASSES_ROOT, 18, "HKEY_CLASSES_ROOT\\" }, + { HKEY_CURRENT_CONFIG, 20, "HKEY_CURRENT_CONFIG\\" }, + { HKEY_CURRENT_USER, 18, "HKEY_CURRENT_USER\\" }, + { HKEY_LOCAL_MACHINE, 19, "HKEY_LOCAL_MACHINE\\" }, + { HKEY_USERS, 11, "HKEY_USERS\\" }, + { NULL, 0, NULL } +}; + +bool RegistryTool::setStringValue(const std::string &keyNameArg, + const std::string &valueName, + const std::string &value) +{ + std::string keyName = keyNameArg; + + HKEY rootKey = HKEY_LOCAL_MACHINE; //default root + //Trim out the root key if necessary + for (KeyTableEntry *entry = keyTable; entry->key; entry++) + { + if (keyName.compare(0, entry->strlen, entry->str)==0) + { + rootKey = entry->key; + keyName = keyName.substr(entry->strlen); + } + } + //printf("trimmed string: '%s'\n", keyName.c_str()); + + //Get or create the key + HKEY key; + if (RegCreateKeyEx(rootKey, keyName.c_str(), + 0, NULL, REG_OPTION_NON_VOLATILE, + KEY_WRITE, NULL, &key, NULL)) + { + printf("RegistryTool: Could not create the registry key '%s'\n", keyName.c_str()); + return false; + } + + //Set the value + if (RegSetValueEx(key, valueName.c_str(), + 0, REG_SZ, (LPBYTE) value.c_str(), (DWORD) value.size())) + { + printf("RegistryTool: Could not set the value '%s'\n", value.c_str()); + RegCloseKey(key); + return false; + } + + + RegCloseKey(key); + + return true; +} + +bool RegistryTool::getExeInfo(std::string &fullPath, + std::string &path, + std::string &exeName) +{ + + char buf[MAX_PATH+1]; + if (!GetModuleFileName(NULL, buf, MAX_PATH)) + { + printf("Could not fetch executable file name\n"); + return false; + } + else + { + //printf("Executable file name: '%s'\n", buf); + } + + fullPath = buf; + path = ""; + exeName = ""; + std::string::size_type pos = fullPath.rfind('\\'); + if (pos != fullPath.npos) + { + path = fullPath.substr(0, pos); + exeName = fullPath.substr(pos+1); + } + + return true; +} + + +bool RegistryTool::setPathInfo() +{ + std::string fullPath; + std::string path; + std::string exeName; + + if (!getExeInfo(fullPath, path, exeName)) + return false; + + //printf("full:'%s' path:'%s' exe:'%s'\n", + // fullPath.c_str(), path.c_str(), exeName.c_str()); + + std::string keyName = + "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\"; + keyName.append(exeName); + + std::string valueName = ""; + std::string value = fullPath; + + if (!setStringValue(keyName, valueName, value)) + return false; + + //add our subdirectories + std::string appPath = path; + appPath.append("\\python;"); + appPath.append(path); + appPath.append("\\perl"); + valueName = "Path"; + value = appPath; + + if (!setStringValue(keyName, valueName, value)) + return false; + + return true; +} + + +#ifdef TESTREG + +void testReg() +{ + RegistryTool rt; + char *key = + "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\inkscape.exe"; + char *name = ""; + char *value = "c:\\inkscape\\inkscape.exe"; + if (!rt.setStringValue(key, name, value)) + { + printf("Test failed\n"); + } + else + { + printf("Test succeeded\n"); + } + name = "Path"; + value = "c:\\inkscape\\python"; + if (!rt.setStringValue(key, name, value)) + { + printf("Test failed\n"); + } + else + { + printf("Test succeeded\n"); + } +} + + +void testPath() +{ + RegistryTool rt; + rt.setPathInfo(); +} + + +int main(int argc, char **argv) +{ + //testReg(); + testPath(); + return 0; +} + +#endif /* TESTREG */ + +//######################################################################## +//# E N D O F F I L E +//######################################################################## diff --git a/src/registrytool.h b/src/registrytool.h new file mode 100644 index 000000000..9aa644189 --- /dev/null +++ b/src/registrytool.h @@ -0,0 +1,56 @@ +#ifndef __REGISTRYTOOL_H__ +#define __REGISTRYTOOL_H__ +/** + * Inkscape Registry Tool + * + * This simple tool is intended for allowing Inkscape to append subdirectories + * to its path. This will allow extensions and other files to be accesses + * without explicit user intervention. + * + * Authors: + * Bob Jamison + * + * Copyright (C) 2005 Bob Jamison + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +class RegistryTool +{ +public: + + RegistryTool() + {} + + virtual ~RegistryTool() + {} + + bool setStringValue(const std::string &key, + const std::string &valueName, + const std::string &value); + + bool getExeInfo(std::string &fullPath, + std::string &path, + std::string &exeName); + + bool setPathInfo(); + + +}; + +#endif /* __REGISTRYTOOL_H__ */ + diff --git a/src/remove-last.h b/src/remove-last.h new file mode 100644 index 000000000..4d5df3f54 --- /dev/null +++ b/src/remove-last.h @@ -0,0 +1,31 @@ +#ifndef __REMOVE_LAST_H__ +#define __REMOVE_LAST_H__ + +#include +#include + +template +inline void remove_last(std::vector &seq, T const &elem) +{ + using std::vector; + + typename vector::reverse_iterator i(find(seq.rbegin(), seq.rend(), elem)); + g_assert( i != seq.rend() ); + typename vector::iterator ii(&*i); + seq.erase(ii); +} + + +#endif /* !__REMOVE_LAST_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:encoding=utf-8:textwidth=99 : diff --git a/src/removeoverlap/.cvsignore b/src/removeoverlap/.cvsignore new file mode 100644 index 000000000..e8014d011 --- /dev/null +++ b/src/removeoverlap/.cvsignore @@ -0,0 +1,5 @@ +Makefile +Makefile.in +.deps +makefile +.dirstamp diff --git a/src/removeoverlap/Makefile_insert b/src/removeoverlap/Makefile_insert new file mode 100644 index 000000000..e28304431 --- /dev/null +++ b/src/removeoverlap/Makefile_insert @@ -0,0 +1,31 @@ +## Makefile.am fragment sourced by src/Makefile.am. + +removeoverlap/all: removeoverlap/libremoveoverlap.a + +removeoverlap/clean: + rm -f removeoverlap/libremoveoverlap.a $(removeoverlap_libremoveoverlap_a_OBJECTS) + +removeoverlap_libremoveoverlap_a_SOURCES = \ + removeoverlap/block.cpp \ + removeoverlap/block.h \ + removeoverlap/blocks.cpp \ + removeoverlap/blocks.h \ + removeoverlap/constraint.cpp \ + removeoverlap/constraint.h \ + removeoverlap/generate-constraints.cpp \ + removeoverlap/generate-constraints.h \ + removeoverlap/remove_rectangle_overlap.cpp \ + removeoverlap/remove_rectangle_overlap.h \ + removeoverlap/removeoverlap.cpp \ + removeoverlap/removeoverlap.h \ + removeoverlap/solve_VPSC.cpp \ + removeoverlap/solve_VPSC.h \ + removeoverlap/variable.cpp \ + removeoverlap/variable.h \ + removeoverlap/pairingheap/dsexceptions.h \ + removeoverlap/pairingheap/PairingHeap.cpp \ + removeoverlap/pairingheap/PairingHeap.h + +removeoverlap_remove_rectangle_overlap_test_SOURCES = \ + removeoverlap/remove_rectangle_overlap-test.cpp +removeoverlap_remove_rectangle_overlap_test_LDADD = removeoverlap/libremoveoverlap.a -lglib-2.0 diff --git a/src/removeoverlap/block.cpp b/src/removeoverlap/block.cpp new file mode 100644 index 000000000..799fa5d8e --- /dev/null +++ b/src/removeoverlap/block.cpp @@ -0,0 +1,279 @@ +/** + * \brief Remove overlaps function + * + * Authors: + * Tim Dwyer + * + * Copyright (C) 2005 Authors + * + * Released under GNU GPL. Read the file 'COPYING' for more information. + */ + + +#include "constraint.h" +#include "block.h" +#include "blocks.h" +#include "pairingheap/PairingHeap.h" +#ifdef RECTANGLE_OVERLAP_LOGGING +using std::ios; +using std::ofstream; +using std::endl; +#endif +using std::vector; + +void Block::addVariable(Variable *v) { + v->block=this; + vars->push_back(v); + weight+=v->weight; + wposn += v->weight * (v->desiredPosition - v->offset); + posn=wposn/weight; +} +Block::Block(Variable *v) { + timeStamp=0; + posn=weight=wposn=0; + in=NULL; + out=NULL; + deleted=false; + vars=new vector; + if(v!=NULL) { + v->offset=0; + addVariable(v); + } +} + +double Block::desiredWeightedPosition() { + double wp = 0; + for (vector::iterator v=vars->begin();v!=vars->end();v++) { + wp += ((*v)->desiredPosition - (*v)->offset) * (*v)->weight; + } + return wp; +} +Block::~Block(void) +{ + delete vars; + delete in; + delete out; +} +void Block::setUpInConstraints() { + setUpConstraintHeap(in,true); +} +void Block::setUpOutConstraints() { + setUpConstraintHeap(out,false); +} +void Block::setUpConstraintHeap(PairingHeap* &h,bool in) { + delete h; + h = new PairingHeap(&compareConstraints); + for (vector::iterator i=vars->begin();i!=vars->end();i++) { + Variable *v=*i; + vector *cs=in?&(v->in):&(v->out); + for (vector::iterator j=cs->begin();j!=cs->end();j++) { + Constraint *c=*j; + c->timeStamp=blockTimeCtr; + if (c->left->block != this && in || c->right->block != this && !in) { + h->insert(c); + } + } + } +} +/** + * Merges b into this block across c. Can be either a + * right merge or a left merge + * @param b block to merge into this + * @param c constraint being merged + * @param distance separation required to satisfy c + */ +void Block::merge(Block *b, Constraint *c, double dist) { + c->active=true; + wposn+=b->wposn-dist*b->weight; + weight+=b->weight; + posn=wposn/weight; + for(vector::iterator i=b->vars->begin();i!=b->vars->end();i++) { + Variable *v=*i; + v->block=this; + v->offset+=dist; + vars->push_back(v); + } +} + +void Block::mergeIn(Block *b) { +#ifdef RECTANGLE_OVERLAP_LOGGING + ofstream f(LOGFILE,ios::app); + f<<" merging constraint heaps... "<findMinInConstraint(); + in->merge(b->in); +} +void Block::mergeOut(Block *b) { + findMinOutConstraint(); + b->findMinOutConstraint(); + out->merge(b->out); +} +Constraint *Block::findMinInConstraint() { + Constraint *v = NULL; + vector outOfDate; + while (!in->isEmpty()) { + v = in->findMin(); + Block *lb=v->left->block; + Block *rb=v->right->block; + // rb may not be this if called between merge and mergeIn +#ifdef RECTANGLE_OVERLAP_LOGGING + ofstream f(LOGFILE,ios::app); + f<<" checking constraint ... "<<*v; + f<<" timestamps: left="<timeStamp<<" right="<timeStamp<<" constraint="<timeStamp<deleteMin(); +#ifdef RECTANGLE_OVERLAP_LOGGING + f<<" ... skipping internal constraint"<timeStamp > rb->timeStamp + && v->timeStamp < lb->timeStamp + || v->timeStamp < rb->timeStamp) { + // block at other end of constraint has been moved since this + in->deleteMin(); + outOfDate.push_back(v); +#ifdef RECTANGLE_OVERLAP_LOGGING + f<<" reinserting out of date constraint"<::iterator i=outOfDate.begin();i!=outOfDate.end();i++) { + v=*i; + v->timeStamp=blockTimeCtr; + in->insert(v); + } + if(in->isEmpty()) { + v=NULL; + } else { + v=in->findMin(); + } + return v; +} +Constraint *Block::findMinOutConstraint() { + if(out->isEmpty()) return NULL; + Constraint *v = out->findMin(); + while (v->left->block == v->right->block) { + out->deleteMin(); + if(out->isEmpty()) return NULL; + v = out->findMin(); + } + return v; +} +void Block::deleteMinInConstraint() { + in->deleteMin(); +} +void Block::deleteMinOutConstraint() { + out->deleteMin(); +} +inline bool Block::canFollowLeft(Constraint *c, Variable *last) { + return c->left->block==this && c->active && last!=c->left; +} +inline bool Block::canFollowRight(Constraint *c, Variable *last) { + return c->right->block==this && c->active && last!=c->right; +} + +// computes the derivative of v and the lagrange multipliers +// of v's out constraints (as the recursive sum of those below. +// Does not backtrack over u. +// also records the constraint with minimum lagrange multiplier +// in min_lm +double Block::compute_dfdv(Variable *v, Variable *u, Constraint *&min_lm) { + double dfdv=v->weight*(v->position() - v->desiredPosition); + for(vector::iterator it=v->out.begin();it!=v->out.end();it++) { + Constraint *c=*it; + if(canFollowRight(c,u)) { + dfdv+=c->lm=compute_dfdv(c->right,v,min_lm); + if(min_lm==NULL||c->lmlm) min_lm=c; + } + } + for(vector::iterator it=v->in.begin();it!=v->in.end();it++) { + Constraint *c=*it; + if(canFollowLeft(c,u)) { + dfdv-=c->lm=-compute_dfdv(c->left,v,min_lm); + if(min_lm==NULL||c->lmlm) min_lm=c; + } + } + return dfdv; +} + +// resets LMs for all active constraints to 0 by +// traversing active constraint tree starting from v, +// not back tracking over u +void Block::reset_active_lm(Variable *v, Variable *u) { + for(vector::iterator it=v->out.begin();it!=v->out.end();it++) { + Constraint *c=*it; + if(canFollowRight(c,u)) { + c->lm=0; + reset_active_lm(c->right,v); + } + } + for(vector::iterator it=v->in.begin();it!=v->in.end();it++) { + Constraint *c=*it; + if(canFollowLeft(c,u)) { + c->lm=0; + reset_active_lm(c->left,v); + } + } +} +/** + * finds the constraint with the minimum lagrange multiplier, that is, the constraint + * that most wants to split + */ +Constraint *Block::findMinLM() { + Constraint *min_lm=NULL; + reset_active_lm(vars->front(),NULL); + compute_dfdv(vars->front(),NULL,min_lm); + return min_lm; +} + +// populates block b by traversing the active constraint tree adding variables as they're +// visited. Starts from variable v and does not backtrack over variable u. +void Block::populateSplitBlock(Block *b, Variable *v, Variable *u) { + b->addVariable(v); + for (vector::iterator c=v->in.begin();c!=v->in.end();c++) { + if (canFollowLeft(*c,u)) + populateSplitBlock(b, (*c)->left, v); + } + for (vector::iterator c=v->out.begin();c!=v->out.end();c++) { + if (canFollowRight(*c,u)) + populateSplitBlock(b, (*c)->right, v); + } +} +/** + * Creates two new blocks, l and r, and splits this block across constraint c, + * placing the left subtree of constraints (and associated variables) into l + * and the right into r + */ +void Block::split(Block *&l, Block *&r, Constraint *c) { + c->active=false; + l=new Block(); + populateSplitBlock(l,c->left,c->right); + r=new Block(); + populateSplitBlock(r,c->right,c->left); +} + +/** + * Computes the cost (squared euclidean distance from desired positions) of the + * current positions for variables in this block + */ +double Block::cost() { + double c = 0; + for (vector::iterator v=vars->begin();v!=vars->end();v++) { + double diff = (*v)->position() - (*v)->desiredPosition; + c += (*v)->weight * diff * diff; + } + return c; +} +ostream& operator <<(ostream &os, const Block &b) +{ + os<<"Block:"; + for(vector::iterator v=b.vars->begin();v!=b.vars->end();v++) { + os<<" "<<**v; + } + return os; +} diff --git a/src/removeoverlap/block.h b/src/removeoverlap/block.h new file mode 100644 index 000000000..7905309bb --- /dev/null +++ b/src/removeoverlap/block.h @@ -0,0 +1,59 @@ +/** + * \brief Remove overlaps function + * + * Authors: + * Tim Dwyer + * + * Copyright (C) 2005 Authors + * + * Released under GNU GPL. Read the file 'COPYING' for more information. + */ + +#ifndef SEEN_REMOVEOVERLAP_BLOCK_H +#define SEEN_REMOVEOVERLAP_BLOCK_H + +#include +#include +class Variable; +class Constraint; +template class PairingHeap; +class StupidPriorityQueue; + +class Block +{ + friend std::ostream& operator <<(std::ostream &os,const Block &b); +public: + std::vector *vars; + double posn; + double weight; + double wposn; + Block(Variable *v=NULL); + ~Block(void); + Constraint *findMinLM(); + Constraint *findMinInConstraint(); + Constraint *findMinOutConstraint(); + void deleteMinInConstraint(); + void deleteMinOutConstraint(); + double desiredWeightedPosition(); + void merge(Block *b, Constraint *c, double dist); + void mergeIn(Block *b); + void mergeOut(Block *b); + void split(Block *&l, Block *&r, Constraint *c); + void setUpInConstraints(); + void setUpOutConstraints(); + double cost(); + bool deleted; + long timeStamp; + PairingHeap *in; + PairingHeap *out; +private: + void reset_active_lm(Variable *v, Variable *u); + double compute_dfdv(Variable *v, Variable *u, Constraint *&min_lm); + bool canFollowLeft(Constraint *c, Variable *last); + bool canFollowRight(Constraint *c, Variable *last); + void populateSplitBlock(Block *b, Variable *v, Variable *u); + void addVariable(Variable *v); + void setUpConstraintHeap(PairingHeap* &h,bool in); +}; + +#endif // SEEN_REMOVEOVERLAP_BLOCK_H diff --git a/src/removeoverlap/blocks.cpp b/src/removeoverlap/blocks.cpp new file mode 100644 index 000000000..45c479187 --- /dev/null +++ b/src/removeoverlap/blocks.cpp @@ -0,0 +1,190 @@ +/** + * \brief A block structure defined over the variables + * + * A block structure defined over the variables such that each block contains + * 1 or more variables, with the invariant that all constraints inside a block + * are satisfied by keeping the variables fixed relative to one another + * + * Authors: + * Tim Dwyer + * + * Copyright (C) 2005 Authors + * + * Released under GNU GPL. Read the file 'COPYING' for more information. + */ + +#include "blocks.h" +#include "block.h" +#include "constraint.h" +#ifdef RECTANGLE_OVERLAP_LOGGING +using std::ios; +using std::ofstream; +using std::endl; +#endif +using std::set; +using std::vector; +using std::iterator; +using std::list; +using std::copy; + +long blockTimeCtr; + +Blocks::Blocks(Variable *vs[], const int n) : vs(vs),nvs(n) { + blockTimeCtr=0; + for(int i=0;i::iterator i=begin();i!=end();i++) { + delete *i; + } + clear(); +} + +/** + * returns a list of variables with total ordering determined by the constraint + * DAG + */ +list *Blocks::totalOrder() { + list *order = new list; + for(int i=0;ivisited=false; + } + for(int i=0;iin.size()==0) { + dfsVisit(vs[i],order); + } + } + return order; +} +// Recursive depth first search giving total order by pushing nodes in the DAG +// onto the front of the list when we finish searching them +void Blocks::dfsVisit(Variable *v, list *order) { + v->visited=true; + vector::iterator it=v->out.begin(); + for(;it!=v->out.end();it++) { + Constraint *c=*it; + if(!c->right->visited) { + dfsVisit(c->right, order); + } + } + order->push_front(v); +} +/** + * Processes incoming constraints, most violated to least, merging with the + * neighbouring (left) block until no more violated constraints are found + */ +void Blocks::mergeLeft(Block *r) { +#ifdef RECTANGLE_OVERLAP_LOGGING + ofstream f(LOGFILE,ios::app); + f<<"mergeLeft called on "<<*r<timeStamp=++blockTimeCtr; + r->setUpInConstraints(); + Constraint *c=r->findMinInConstraint(); + while (c != NULL && c->slack()<0) { +#ifdef RECTANGLE_OVERLAP_LOGGING + f<<"mergeLeft on constraint: "<<*c<deleteMinInConstraint(); + Block *l = c->left->block; + if (l->in==NULL) l->setUpInConstraints(); + double dist = c->right->offset - c->left->offset - c->gap; + if (r->vars->size() < l->vars->size()) { + dist=-dist; + std::swap(l, r); + } + r->merge(l, c, dist); + r->mergeIn(l); + r->timeStamp=++blockTimeCtr; + removeBlock(l); + c=r->findMinInConstraint(); + } +#ifdef RECTANGLE_OVERLAP_LOGGING + f<<"merged "<<*r<setUpOutConstraints(); + Constraint *c = l->findMinOutConstraint(); + while (c != NULL && c->slack()<0) { +#ifdef RECTANGLE_OVERLAP_LOGGING + f<<"mergeRight on constraint: "<<*c<deleteMinOutConstraint(); + Block *r = c->right->block; + r->setUpOutConstraints(); + double dist = c->left->offset + c->gap - c->right->offset; + if (l->vars->size() > r->vars->size()) { + dist=-dist; + std::swap(l, r); + } + l->merge(r, c, dist); + l->mergeOut(r); + removeBlock(r); + c=l->findMinOutConstraint(); + } +#ifdef RECTANGLE_OVERLAP_LOGGING + f<<"merged "<<*l<deleted=true; + //erase(doomed); +} +void Blocks::cleanup() { + vector bcopy(size()); + copy(begin(),end(),bcopy.begin()); + for(vector::iterator i=bcopy.begin();i!=bcopy.end();i++) { + Block *b=*i; + if(b->deleted) { + erase(b); + delete b; + } + } +} +/** + * Splits block b across constraint c into two new blocks, l and r (c's left + * and right sides respectively) + */ +void Blocks::split(Block *b, Block *&l, Block *&r, Constraint *c) { + b->split(l,r,c); +#ifdef RECTANGLE_OVERLAP_LOGGING + ofstream f(LOGFILE,ios::app); + f<<"Split left: "<<*l<posn = b->posn; + r->wposn = r->posn * r->weight; + mergeLeft(l); + // r may have been merged! + r = c->right->block; + r->wposn = r->desiredWeightedPosition(); + r->posn = r->wposn / r->weight; + mergeRight(r); + removeBlock(b); + + insert(l); + insert(r); +} +/** + * returns the cost total squared distance of variables from their desired + * positions + */ +double Blocks::cost() { + double c = 0; + for(set::iterator i=begin();i!=end();i++) { + c += (*i)->cost(); + } + return c; +} + diff --git a/src/removeoverlap/blocks.h b/src/removeoverlap/blocks.h new file mode 100644 index 000000000..437af6310 --- /dev/null +++ b/src/removeoverlap/blocks.h @@ -0,0 +1,49 @@ +/** + * \brief Remove overlaps function + * + * Authors: + * Tim Dwyer + * + * Copyright (C) 2005 Authors + * + * Released under GNU GPL. Read the file 'COPYING' for more information. + */ + +#ifndef SEEN_REMOVEOVERLAP_BLOCKS_H +#define SEEN_REMOVEOVERLAP_BLOCKS_H + +#ifdef RECTANGLE_OVERLAP_LOGGING +#define LOGFILE "cRectangleOverlap.log" +#endif + +#include +#include + +class Block; +class Variable; +class Constraint; +/** + * A block structure defined over the variables such that each block contains + * 1 or more variables, with the invariant that all constraints inside a block + * are satisfied by keeping the variables fixed relative to one another + */ +class Blocks : public std::set +{ +public: + Blocks(Variable *vs[], const int n); + ~Blocks(void); + void mergeLeft(Block *r); + void mergeRight(Block *l); + void split(Block *b, Block *&l, Block *&r, Constraint *c); + std::list *totalOrder(); + void cleanup(); + double cost(); +private: + void dfsVisit(Variable *v, std::list *order); + void removeBlock(Block *doomed); + Variable **vs; + int nvs; +}; + +extern long blockTimeCtr; +#endif // SEEN_REMOVEOVERLAP_BLOCKS_H diff --git a/src/removeoverlap/constraint.cpp b/src/removeoverlap/constraint.cpp new file mode 100644 index 000000000..78c5f03ad --- /dev/null +++ b/src/removeoverlap/constraint.cpp @@ -0,0 +1,29 @@ +/** + * \brief Remove overlaps function + * + * Authors: + * Tim Dwyer + * + * Copyright (C) 2005 Authors + * + * Released under GNU GPL. Read the file 'COPYING' for more information. + */ + +#include "constraint.h" + +Constraint::Constraint(Variable *left, Variable *right, double gap) +{ + this->left=left; + left->out.push_back(this); + this->right=right; + right->in.push_back(this); + this->gap=gap; + active=false; + visited=false; + timeStamp=0; +} +std::ostream& operator <<(std::ostream &os, const Constraint &c) +{ + os<<*c.left<<"+"< + * + * Copyright (C) 2005 Authors + * + * Released under GNU GPL. Read the file 'COPYING' for more information. + */ + +#ifndef SEEN_REMOVEOVERLAP_CONSTRAINT_H +#define SEEN_REMOVEOVERLAP_CONSTRAINT_H + +#include +#include "variable.h" + +class Constraint +{ + friend std::ostream& operator <<(std::ostream &os,const Constraint &c); +public: + Variable *left; + Variable *right; + double gap; + double lm; + Constraint(Variable *left, Variable *right, double gap); + ~Constraint(void){}; + inline double Constraint::slack() const { return right->position() - gap - left->position(); } + //inline bool operator<(Constraint const &o) const { return slack() < o.slack(); } + long timeStamp; + bool active; + bool visited; +}; +#include +static inline bool compareConstraints(Constraint *&l, Constraint *&r) { + double sl = l->slack(); + double sr = r->slack(); + if(l->left->block==l->right->block) sl=DBL_MIN; + if(r->left->block==r->right->block) sr=DBL_MIN; + if(sl==sr) { + // arbitrary choice based on id + if(l->left->id==r->left->id) { + if(l->right->idright->id) return true; + return false; + } + if(l->left->idleft->id) return true; + return false; + } + return sl < sr; +} + +#endif // SEEN_REMOVEOVERLAP_CONSTRAINT_H diff --git a/src/removeoverlap/generate-constraints.cpp b/src/removeoverlap/generate-constraints.cpp new file mode 100644 index 000000000..3238a0ca9 --- /dev/null +++ b/src/removeoverlap/generate-constraints.cpp @@ -0,0 +1,302 @@ +/** + * \brief Remove overlaps function + * + * Authors: + * Tim Dwyer + * + * Copyright (C) 2005 Authors + * + * Released under GNU GPL. Read the file 'COPYING' for more information. + */ + +#include +#include +#include "generate-constraints.h" +#include "constraint.h" + +#include "isnan.h" /* Include last */ + +using std::set; +using std::vector; + +std::ostream& operator <<(std::ostream &os, const Rectangle &r) { + os << "{"< NodeSet; + +struct Node { + Variable *v; + Rectangle *r; + double pos; + Node *firstAbove, *firstBelow; + NodeSet *leftNeighbours, *rightNeighbours; + Node(Variable *v, Rectangle *r, double p) : v(v),r(r),pos(p) { + firstAbove=firstBelow=NULL; + leftNeighbours=rightNeighbours=NULL; + } + ~Node() { + delete leftNeighbours; + delete rightNeighbours; + } + void addLeftNeighbour(Node *u) { + leftNeighbours->insert(u); + } + void addRightNeighbour(Node *u) { + rightNeighbours->insert(u); + } + void setNeighbours(NodeSet *left, NodeSet *right) { + leftNeighbours=left; + rightNeighbours=right; + for(NodeSet::iterator i=left->begin();i!=left->end();i++) { + Node *v=*(i); + v->addRightNeighbour(this); + } + for(NodeSet::iterator i=right->begin();i!=right->end();i++) { + Node *v=*(i); + v->addLeftNeighbour(this); + } + } +}; +bool CmpNodePos::operator() (const Node* u, const Node* v) const { + if (u->pos < v->pos) { + return true; + } + if (v->pos < u->pos) { + return false; + } + if (isNaN(u->pos) != isNaN(v->pos)) { + return isNaN(u->pos); + } + return u < v; + + /* I don't know how important it is to handle NaN correctly + * (e.g. we probably handle it badly in other code anyway, and + * in any case the best we can hope for is to reduce the + * badness of other nodes). + * + * Nevertheless, we try to do the right thing here and in + * event comparison. The issue is that (on platforms with + * ieee floating point comparison) NaN compares neither less + * than nor greater than any other number, yet sort wants a + * well-defined ordering. In particular, we want to ensure + * transitivity of equivalence, which normally wouldn't be + * guaranteed if the "middle" item in the transitivity + * involves a NaN. (NaN is neither less than nor greater than + * other numbers, so tends to be considered as equal to all + * other numbers: even unequal numbers.) + */ +} + +NodeSet* getLeftNeighbours(NodeSet &scanline,Node *v) { + NodeSet *leftv = new NodeSet; + NodeSet::iterator i=scanline.find(v); + while(i--!=scanline.begin()) { + Node *u=*(i); + if(u->r->overlapX(v->r)<=0) { + leftv->insert(u); + return leftv; + } + if(u->r->overlapX(v->r)<=u->r->overlapY(v->r)) { + leftv->insert(u); + } + } + return leftv; +} +NodeSet* getRightNeighbours(NodeSet &scanline,Node *v) { + NodeSet *rightv = new NodeSet; + NodeSet::iterator i=scanline.find(v); + for(i++;i!=scanline.end(); i++) { + Node *u=*(i); + if(u->r->overlapX(v->r)<=0) { + rightv->insert(u); + return rightv; + } + if(u->r->overlapX(v->r)<=u->r->overlapY(v->r)) { + rightv->insert(u); + } + } + return rightv; +} + +typedef enum {Open, Close} EventType; +struct Event { + EventType type; + Node *v; + double pos; + Event(EventType t, Node *v, double p) : type(t),v(v),pos(p) {}; +}; +Event **events; +int compare_events(const void *a, const void *b) { + Event *ea=*(Event**)a; + Event *eb=*(Event**)b; + if(ea->pos > eb->pos) { + return 1; + } else if(ea->pos < eb->pos) { + return -1; + } else if(isNaN(ea->pos) != isNaN(ea->pos)) { + /* See comment in CmpNodePos. */ + return ( isNaN(ea->pos) + ? -1 + : 1 ); + } else if(ea->v->r==ea->v->r) { + // when comparing opening and closing from the same rect + // open must come first + if(ea->type==Open) return -1; + return 1; + } + return 0; +} + +/** + * Prepares variables and constraints in order to apply VPSC horizontally. + * useNeighbourLists determines whether or not a heuristic is used to deciding whether to resolve + * all overlap in the x pass, or leave some overlaps for the y pass. + */ +int generateXConstraints(Rectangle *rs[], double weights[], const int n, Variable **&vars, Constraint **&cs, bool useNeighbourLists) { + events=new Event*[2*n]; + int i,m,ctr=0; + vector constraints; + vars=new Variable*[n]; + for(i=0;igetCentreX(),weights[i]); + Node *v = new Node(vars[i],rs[i],rs[i]->getCentreX()); + events[ctr++]=new Event(Open,v,rs[i]->getMinY()); + events[ctr++]=new Event(Close,v,rs[i]->getMaxY()); + } + qsort((Event*)events, (size_t)2*n, sizeof(Event*), compare_events ); + NodeSet scanline; + for(i=0;i<2*n;i++) { + Event *e=events[i]; + Node *v=e->v; + if(e->type==Open) { + scanline.insert(v); + if(useNeighbourLists) { + v->setNeighbours( + getLeftNeighbours(scanline,v), + getRightNeighbours(scanline,v) + ); + } else { + NodeSet::iterator i=scanline.find(v); + if(i--!=scanline.begin()) { + Node *u=*i; + v->firstAbove=u; + u->firstBelow=v; + } + i=scanline.find(v); + if(++i!=scanline.end()) { + Node *u=*i; + v->firstBelow=u; + u->firstAbove=v; + } + } + } else { + // Close event + int r; + if(useNeighbourLists) { + for(NodeSet::iterator i=v->leftNeighbours->begin(); + i!=v->leftNeighbours->end();i++ + ) { + Node *u=*i; + double sep = (v->r->width()+u->r->width())/2.0; + constraints.push_back(new Constraint(u->v,v->v,sep)); + r=u->rightNeighbours->erase(v); + } + + for(NodeSet::iterator i=v->rightNeighbours->begin(); + i!=v->rightNeighbours->end();i++ + ) { + Node *u=*i; + double sep = (v->r->width()+u->r->width())/2.0; + constraints.push_back(new Constraint(v->v,u->v,sep)); + r=u->leftNeighbours->erase(v); + } + } else { + Node *l=v->firstAbove, *r=v->firstBelow; + if(l!=NULL) { + double sep = (v->r->width()+l->r->width())/2.0; + constraints.push_back(new Constraint(l->v,v->v,sep)); + l->firstBelow=v->firstBelow; + } + if(r!=NULL) { + double sep = (v->r->width()+r->r->width())/2.0; + constraints.push_back(new Constraint(v->v,r->v,sep)); + r->firstAbove=v->firstAbove; + } + } + r=scanline.erase(v); + delete v; + } + delete e; + } + delete [] events; + cs=new Constraint*[m=constraints.size()]; + for(i=0;i constraints; + vars=new Variable*[n]; + for(i=0;igetCentreY(),weights[i]); + Node *v = new Node(vars[i],rs[i],rs[i]->getCentreY()); + events[ctr++]=new Event(Open,v,rs[i]->getMinX()); + events[ctr++]=new Event(Close,v,rs[i]->getMaxX()); + } + qsort((Event*)events, (size_t)2*n, sizeof(Event*), compare_events ); + NodeSet scanline; + for(i=0;i<2*n;i++) { + Event *e=events[i]; + Node *v=e->v; + if(e->type==Open) { + scanline.insert(v); + NodeSet::iterator i=scanline.find(v); + if(i--!=scanline.begin()) { + Node *u=*i; + v->firstAbove=u; + u->firstBelow=v; + } + i=scanline.find(v); + if(++i!=scanline.end()) { + Node *u=*i; + v->firstBelow=u; + u->firstAbove=v; + } + } else { + // Close event + Node *l=v->firstAbove, *r=v->firstBelow; + if(l!=NULL) { + double sep = (v->r->height()+l->r->height())/2.0; + constraints.push_back(new Constraint(l->v,v->v,sep)); + l->firstBelow=v->firstBelow; + } + if(r!=NULL) { + double sep = (v->r->height()+r->r->height())/2.0; + constraints.push_back(new Constraint(v->v,r->v,sep)); + r->firstAbove=v->firstAbove; + } + scanline.erase(v); + delete v; + } + delete e; + } + delete [] events; + cs=new Constraint*[m=constraints.size()]; + for(i=0;i + * + * Copyright (C) 2005 Authors + * + * Released under GNU GPL. Read the file 'COPYING' for more information. + */ + +#ifndef SEEN_REMOVEOVERLAP_GENERATE_CONSTRAINTS_H +#define SEEN_REMOVEOVERLAP_GENERATE_CONSTRAINTS_H +#include + +class Rectangle { + friend std::ostream& operator <<(std::ostream &os, const Rectangle &r); +public: + static double xBorder,yBorder; + Rectangle(double x, double X, double y, double Y); + double getMaxX() const { return maxX+xBorder; } + double getMaxY() const { return maxY+yBorder; } + double getMinX() const { return minX; } + double getMinY() const { return minY; } + double getMinD(unsigned const d) const { + return ( d == 0 ? getMinX() : getMinY() ); + } + double getMaxD(unsigned const d) const { + return ( d == 0 ? getMaxX() : getMaxY() ); + } + double getCentreX() const { return minX+width()/2.0; } + double getCentreY() const { return minY+height()/2.0; } + double width() const { return getMaxX()-minX; } + double height() const { return getMaxY()-minY; } + static void setXBorder(double x) {xBorder=x;} + static void setYBorder(double y) {yBorder=y;} + void moveCentreX(double x) { + moveMinX(x-width()/2.0); + } + void moveCentreY(double y) { + moveMinY(y-height()/2.0); + } + void moveMinX(double x) { + maxX=x+width()-xBorder; + minX=x; + } + void moveMinY(double y) { + maxY=y+height()-yBorder; + minY=y; + } + inline double overlapX(Rectangle *r) const { + if (getCentreX() <= r->getCentreX() && r->minX < getMaxX()) + return getMaxX() - r->minX; + if (r->getCentreX() <= getCentreX() && minX < r->getMaxX()) + return r->getMaxX() - minX; + return 0; + } + inline double overlapY(Rectangle *r) const { + if (getCentreY() <= r->getCentreY() && r->minY < getMaxY()) + return getMaxY() - r->minY; + if (r->getCentreY() <= getCentreY() && minY < r->getMaxY()) + return r->getMaxY() - minY; + return 0; + } +private: + double minX,maxX,minY,maxY; +}; + + +class Variable; +class Constraint; + +// returns number of constraints generated +int generateXConstraints(Rectangle *rs[], double weights[], const int n, Variable **&vs, Constraint **&cs,bool useNeighbourLists); + +int generateYConstraints(Rectangle *rs[], double weights[], const int n, Variable **&vs, Constraint **&cs); + +#endif // SEEN_REMOVEOVERLAP_GENERATE_CONSTRAINTS_H diff --git a/src/removeoverlap/makefile.in b/src/removeoverlap/makefile.in new file mode 100644 index 000000000..480b25a90 --- /dev/null +++ b/src/removeoverlap/makefile.in @@ -0,0 +1,17 @@ +# Convenience stub makefile to call the real Makefile. + +@SET_MAKE@ + +# Explicit so that it's the default rule. +all: + cd .. && $(MAKE) removeoverlap/all + +clean %.a %.o: + cd .. && $(MAKE) removeoverlap/$@ + +.PHONY: all clean + +OBJEXT = @OBJEXT@ + +.SUFFIXES: +.SUFFIXES: .a .$(OBJEXT) diff --git a/src/removeoverlap/pairingheap/.cvsignore b/src/removeoverlap/pairingheap/.cvsignore new file mode 100644 index 000000000..e8014d011 --- /dev/null +++ b/src/removeoverlap/pairingheap/.cvsignore @@ -0,0 +1,5 @@ +Makefile +Makefile.in +.deps +makefile +.dirstamp diff --git a/src/removeoverlap/pairingheap/PairingHeap.cpp b/src/removeoverlap/pairingheap/PairingHeap.cpp new file mode 100644 index 000000000..9c67f44fa --- /dev/null +++ b/src/removeoverlap/pairingheap/PairingHeap.cpp @@ -0,0 +1,309 @@ +/** + * \brief Pairing heap datastructure implementation + * + * Based on example code in "Data structures and Algorithm Analysis in C++" + * by Mark Allen Weiss, used and released under the GPL by permission + * of the author. + * + * No promises about correctness. Use at your own risk! + * + * Authors: + * Mark Allen Weiss + * Tim Dwyer + * + * Copyright (C) 2005 Authors + * + * Released under GNU GPL. Read the file 'COPYING' for more information. + */ + +#include + +#include "dsexceptions.h" +#include "PairingHeap.h" + +#ifndef PAIRING_HEAP_CPP +#define PAIRING_HEAP_CPP +using namespace std; +/** +* Construct the pairing heap. +*/ +template +PairingHeap::PairingHeap( bool (*lessThan)(T &lhs, T &rhs) ) +{ + root = NULL; + counter=0; + this->lessThan=lessThan; +} + + +/** +* Copy constructor +*/ +template +PairingHeap::PairingHeap( const PairingHeap & rhs ) +{ + root = NULL; + counter=rhs->size(); + *this = rhs; +} + +/** +* Destroy the leftist heap. +*/ +template +PairingHeap::~PairingHeap( ) +{ + makeEmpty( ); +} + +/** +* Insert item x into the priority queue, maintaining heap order. +* Return a pointer to the node containing the new item. +*/ +template +PairNode * +PairingHeap::insert( const T & x ) +{ + PairNode *newNode = new PairNode( x ); + + if( root == NULL ) + root = newNode; + else + compareAndLink( root, newNode ); + counter++; + return newNode; +} +template +int PairingHeap::size() { + return counter; +} +/** +* Find the smallest item in the priority queue. +* Return the smallest item, or throw Underflow if empty. +*/ +template +const T & PairingHeap::findMin( ) const +{ + if( isEmpty( ) ) + throw Underflow( ); + return root->element; +} +/** + * Remove the smallest item from the priority queue. + * Throws Underflow if empty. + */ +template +void PairingHeap::deleteMin( ) +{ + if( isEmpty( ) ) + throw Underflow( ); + + PairNode *oldRoot = root; + + if( root->leftChild == NULL ) + root = NULL; + else + root = combineSiblings( root->leftChild ); + counter--; + delete oldRoot; +} + +/** +* Test if the priority queue is logically empty. +* Returns true if empty, false otherwise. +*/ +template +bool PairingHeap::isEmpty( ) const +{ + return root == NULL; +} + +/** +* Test if the priority queue is logically full. +* Returns false in this implementation. +*/ +template +bool PairingHeap::isFull( ) const +{ + return false; +} + +/** +* Make the priority queue logically empty. +*/ +template +void PairingHeap::makeEmpty( ) +{ + reclaimMemory( root ); + root = NULL; +} + +/** +* Deep copy. +*/ +template +const PairingHeap & +PairingHeap::operator=( const PairingHeap & rhs ) +{ + if( this != &rhs ) + { + makeEmpty( ); + root = clone( rhs.root ); + } + + return *this; +} + +/** +* Internal method to make the tree empty. +* WARNING: This is prone to running out of stack space. +*/ +template +void PairingHeap::reclaimMemory( PairNode * t ) const +{ + if( t != NULL ) + { + reclaimMemory( t->leftChild ); + reclaimMemory( t->nextSibling ); + delete t; + } +} + +/** +* Change the value of the item stored in the pairing heap. +* Does nothing if newVal is larger than currently stored value. +* p points to a node returned by insert. +* newVal is the new value, which must be smaller +* than the currently stored value. +*/ +template +void PairingHeap::decreaseKey( PairNode *p, + const T & newVal ) +{ + if( p->element < newVal ) + return; // newVal cannot be bigger + p->element = newVal; + if( p != root ) + { + if( p->nextSibling != NULL ) + p->nextSibling->prev = p->prev; + if( p->prev->leftChild == p ) + p->prev->leftChild = p->nextSibling; + else + p->prev->nextSibling = p->nextSibling; + + p->nextSibling = NULL; + compareAndLink( root, p ); + } +} + +/** +* Internal method that is the basic operation to maintain order. +* Links first and second together to satisfy heap order. +* first is root of tree 1, which may not be NULL. +* first->nextSibling MUST be NULL on entry. +* second is root of tree 2, which may be NULL. +* first becomes the result of the tree merge. +*/ +template +void PairingHeap:: +compareAndLink( PairNode * & first, + PairNode *second ) const +{ + if( second == NULL ) + return; + if( lessThan(second->element,first->element) ) + { + // Attach first as leftmost child of second + second->prev = first->prev; + first->prev = second; + first->nextSibling = second->leftChild; + if( first->nextSibling != NULL ) + first->nextSibling->prev = first; + second->leftChild = first; + first = second; + } + else + { + // Attach second as leftmost child of first + second->prev = first; + first->nextSibling = second->nextSibling; + if( first->nextSibling != NULL ) + first->nextSibling->prev = first; + second->nextSibling = first->leftChild; + if( second->nextSibling != NULL ) + second->nextSibling->prev = second; + first->leftChild = second; + } +} + +/** +* Internal method that implements two-pass merging. +* firstSibling the root of the conglomerate; +* assumed not NULL. +*/ +template +PairNode * +PairingHeap::combineSiblings( PairNode *firstSibling ) const +{ + if( firstSibling->nextSibling == NULL ) + return firstSibling; + + // Allocate the array + static vector *> treeArray( 5 ); + + // Store the subtrees in an array + int numSiblings = 0; + for( ; firstSibling != NULL; numSiblings++ ) + { + if( numSiblings == (int)treeArray.size( ) ) + treeArray.resize( numSiblings * 2 ); + treeArray[ numSiblings ] = firstSibling; + firstSibling->prev->nextSibling = NULL; // break links + firstSibling = firstSibling->nextSibling; + } + if( numSiblings == (int)treeArray.size( ) ) + treeArray.resize( numSiblings + 1 ); + treeArray[ numSiblings ] = NULL; + + // Combine subtrees two at a time, going left to right + int i = 0; + for( ; i + 1 < numSiblings; i += 2 ) + compareAndLink( treeArray[ i ], treeArray[ i + 1 ] ); + + int j = i - 2; + + // j has the result of last compareAndLink. + // If an odd number of trees, get the last one. + if( j == numSiblings - 3 ) + compareAndLink( treeArray[ j ], treeArray[ j + 2 ] ); + + // Now go right to left, merging last tree with + // next to last. The result becomes the new last. + for( ; j >= 2; j -= 2 ) + compareAndLink( treeArray[ j - 2 ], treeArray[ j ] ); + return treeArray[ 0 ]; +} + +/** +* Internal method to clone subtree. +* WARNING: This is prone to running out of stack space. +*/ +template +PairNode * +PairingHeap::clone( PairNode * t ) const +{ + if( t == NULL ) + return NULL; + else + { + PairNode *p = new PairNode( t->element ); + if( ( p->leftChild = clone( t->leftChild ) ) != NULL ) + p->leftChild->prev = p; + if( ( p->nextSibling = clone( t->nextSibling ) ) != NULL ) + p->nextSibling->prev = p; + return p; + } +} + +#endif diff --git a/src/removeoverlap/pairingheap/PairingHeap.h b/src/removeoverlap/pairingheap/PairingHeap.h new file mode 100644 index 000000000..586a591a8 --- /dev/null +++ b/src/removeoverlap/pairingheap/PairingHeap.h @@ -0,0 +1,111 @@ +/** + * \brief Pairing heap datastructure implementation + * + * Based on example code in "Data structures and Algorithm Analysis in C++" + * by Mark Allen Weiss, used and released under the GPL by permission + * of the author. + * + * No promises about correctness. Use at your own risk! + * + * Authors: + * Mark Allen Weiss + * Tim Dwyer + * + * Copyright (C) 2005 Authors + * + * Released under GNU GPL. Read the file 'COPYING' for more information. + */ +#ifndef PAIRING_HEAP_H_ +#define PAIRING_HEAP_H_ +#include +// Pairing heap class +// +// CONSTRUCTION: with no parameters +// +// ******************PUBLIC OPERATIONS********************* +// PairNode & insert( x ) --> Insert x +// deleteMin( minItem ) --> Remove (and optionally return) smallest item +// T findMin( ) --> Return smallest item +// bool isEmpty( ) --> Return true if empty; else false +// bool isFull( ) --> Return true if empty; else false +// void makeEmpty( ) --> Remove all items +// void decreaseKey( PairNode p, newVal ) +// --> Decrease value in node p +// ******************ERRORS******************************** +// Throws Underflow as warranted + + +// Node and forward declaration because g++ does +// not understand nested classes. +template +class PairingHeap; + +template +class PairNode +{ + T element; + PairNode *leftChild; + PairNode *nextSibling; + PairNode *prev; + + PairNode( const T & theElement ) : element( theElement ), + leftChild(NULL), nextSibling(NULL), prev(NULL) { } + friend class PairingHeap; +}; + +template +class Comparator +{ +public: + virtual bool isLessThan(const T &lhs, const T &rhs) const = 0; +}; + +template +class PairingHeap +{ +public: + PairingHeap( bool (*lessThan)(T &lhs, T &rhs) ); + PairingHeap( const PairingHeap & rhs ); + ~PairingHeap( ); + + bool isEmpty( ) const; + bool isFull( ) const; + int size(); + + PairNode *insert( const T & x ); + const T & findMin( ) const; + void deleteMin( ); + void makeEmpty( ); + void decreaseKey( PairNode *p, const T & newVal ); + void merge( PairingHeap *rhs ) + { + PairNode *broot=rhs->getRoot(); + if (root == NULL) { + if(broot != NULL) { + root = broot; + } + } else { + compareAndLink(root, broot); + } + counter+=rhs->size(); + } + + const PairingHeap & operator=( const PairingHeap & rhs ); +protected: + PairNode * getRoot() { + PairNode *r=root; + root=NULL; + return r; + } +private: + PairNode *root; + bool (*lessThan)(T &lhs, T &rhs); + int counter; + void reclaimMemory( PairNode *t ) const; + void compareAndLink( PairNode * & first, PairNode *second ) const; + PairNode * combineSiblings( PairNode *firstSibling ) const; + PairNode * clone( PairNode * t ) const; +}; + +#include "PairingHeap.cpp" +#endif diff --git a/src/removeoverlap/pairingheap/dsexceptions.h b/src/removeoverlap/pairingheap/dsexceptions.h new file mode 100644 index 000000000..bef2c78c5 --- /dev/null +++ b/src/removeoverlap/pairingheap/dsexceptions.h @@ -0,0 +1,9 @@ +#ifndef DSEXCEPTIONS_H_ +#define DSEXCEPTIONS_H_ + +class Underflow { }; +class Overflow { }; +class OutOfMemory { }; +class BadIterator { }; + +#endif diff --git a/src/removeoverlap/placement_SolveVPSC.cpp b/src/removeoverlap/placement_SolveVPSC.cpp new file mode 100755 index 000000000..a9f4344c8 --- /dev/null +++ b/src/removeoverlap/placement_SolveVPSC.cpp @@ -0,0 +1,130 @@ +#include +#include "placement_SolveVPSC.h" +#include +#include "solve_VPSC.h" +#include "variable.h" +#include "constraint.h" +#include "remove_rectangle_overlap.h" +#include "generate-constraints.h" +#include +#include +#define MaxSize 500 + +JNIEXPORT jdouble JNICALL Java_placement_SolveVPSC_solve + (JNIEnv *env, jobject obj, jobjectArray vName, jdoubleArray vWeight, jdoubleArray vDesPos, jintArray cLeft, jintArray cRight, jdoubleArray cGap, jdoubleArray vResult, jint mode) +{ + jsize n = env->GetArrayLength(vWeight); + jsize m = env->GetArrayLength(cLeft); + int i; + double *lvWeight = env->GetDoubleArrayElements(vWeight, 0); + double *lvDesPos = env->GetDoubleArrayElements(vDesPos, 0); + long *lcLeft = env->GetIntArrayElements(cLeft, 0); + long *lcRight = env->GetIntArrayElements(cRight, 0); + double *lcGap = env->GetDoubleArrayElements(cGap, 0); + Variable **vs=new Variable*[n]; + Constraint **cs=new Constraint*[m]; + for (i=0; iGetObjectArrayElement(vName, i); + const char *name = env->GetStringUTFChars(lvName, NULL); + // once upon a time variables had real names, now you'll have to + // track them by number. + vs[i]=new Variable(i,lvDesPos[i],lvWeight[i]); + } + for (i=0; iposition(); + env->SetDoubleArrayRegion(vResult, i,1,&p); + } + for (i=0; iReleaseIntArrayElements(cLeft, lcLeft, 0); + env->ReleaseIntArrayElements(cRight, lcRight, 0); + env->ReleaseDoubleArrayElements(cGap, lcGap, 0); + env->ReleaseDoubleArrayElements(vWeight, lvWeight, 0); + env->ReleaseDoubleArrayElements(vDesPos, lvDesPos, 0); + delete [] vs; + return cost; +} + +static Variable **vs; +static Constraint **cs; +static int m,n; +JNIEXPORT jint JNICALL Java_placement_SolveVPSC_generateXConstraints +(JNIEnv *env, jobject obj, jdoubleArray rMinX, jdoubleArray rMaxX, jdoubleArray rMinY, jdoubleArray rMaxY, jdoubleArray rWeight) { + n = (int)env->GetArrayLength(rWeight); + Rectangle **rs=new Rectangle*[n]; + double *ws = env->GetDoubleArrayElements(rWeight, 0); + double *minX = env->GetDoubleArrayElements(rMinX, 0); + double *maxX = env->GetDoubleArrayElements(rMaxX, 0); + double *minY = env->GetDoubleArrayElements(rMinY, 0); + double *maxY = env->GetDoubleArrayElements(rMaxY, 0); + for(int i=0;iGetArrayLength(rWeight); + Rectangle **rs=new Rectangle*[n]; + double *ws = env->GetDoubleArrayElements(rWeight, 0); + double *minX = env->GetDoubleArrayElements(rMinX, 0); + double *maxX = env->GetDoubleArrayElements(rMaxX, 0); + double *minY = env->GetDoubleArrayElements(rMinY, 0); + double *maxY = env->GetDoubleArrayElements(rMaxY, 0); + for(int i=0;i vmap; + for(int i=0;ileft]; + jint r=vmap[cs[i]->right]; + double g=cs[i]->gap; + env->SetIntArrayRegion(cLeft, i,1,&l); + env->SetIntArrayRegion(cRight, i,1,&r); + env->SetDoubleArrayRegion(cGap, i,1,&g); + } +} +JNIEXPORT void JNICALL Java_placement_SolveVPSC_removeOverlaps +(JNIEnv *env, jobject obj, jdoubleArray rMinX, jdoubleArray rMaxX, jdoubleArray rMinY, jdoubleArray rMaxY) { + //assert(1==2); //break for debugging + n = (int)env->GetArrayLength(rMinX); + Rectangle **rs=new Rectangle*[n]; + double *minX = env->GetDoubleArrayElements(rMinX, 0); + double *maxX = env->GetDoubleArrayElements(rMaxX, 0); + double *minY = env->GetDoubleArrayElements(rMinY, 0); + double *maxY = env->GetDoubleArrayElements(rMaxY, 0); + for(int i=0;igetMinX(); + double y=rs[i]->getMinY(); + env->SetDoubleArrayRegion(rMinX, i,1,&x); + env->SetDoubleArrayRegion(rMinY, i,1,&y); + } + delete [] rs; + env->ReleaseDoubleArrayElements(rMaxX, maxX, 0); + env->ReleaseDoubleArrayElements(rMaxY, maxY, 0); +} \ No newline at end of file diff --git a/src/removeoverlap/placement_SolveVPSC.h b/src/removeoverlap/placement_SolveVPSC.h new file mode 100755 index 000000000..9f1c10cda --- /dev/null +++ b/src/removeoverlap/placement_SolveVPSC.h @@ -0,0 +1,53 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class placement_SolveVPSC */ + +#ifndef _Included_placement_SolveVPSC +#define _Included_placement_SolveVPSC +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: placement_SolveVPSC + * Method: solve + * Signature: ([Ljava/lang/String;[D[D[I[I[D[DI)D + */ +JNIEXPORT jdouble JNICALL Java_placement_SolveVPSC_solve + (JNIEnv *, jobject, jobjectArray, jdoubleArray, jdoubleArray, jintArray, jintArray, jdoubleArray, jdoubleArray, jint); + +/* + * Class: placement_SolveVPSC + * Method: generateXConstraints + * Signature: ([D[D[D[D[D)I + */ +JNIEXPORT jint JNICALL Java_placement_SolveVPSC_generateXConstraints + (JNIEnv *, jobject, jdoubleArray, jdoubleArray, jdoubleArray, jdoubleArray, jdoubleArray); + +/* + * Class: placement_SolveVPSC + * Method: generateYConstraints + * Signature: ([D[D[D[D[D)I + */ +JNIEXPORT jint JNICALL Java_placement_SolveVPSC_generateYConstraints + (JNIEnv *, jobject, jdoubleArray, jdoubleArray, jdoubleArray, jdoubleArray, jdoubleArray); + +/* + * Class: placement_SolveVPSC + * Method: getConstraints + * Signature: ([I[I[D)V + */ +JNIEXPORT void JNICALL Java_placement_SolveVPSC_getConstraints + (JNIEnv *, jobject, jintArray, jintArray, jdoubleArray); + +/* + * Class: placement_SolveVPSC + * Method: removeOverlaps + * Signature: ([D[D[D[D)V + */ +JNIEXPORT void JNICALL Java_placement_SolveVPSC_removeOverlaps + (JNIEnv *, jobject, jdoubleArray, jdoubleArray, jdoubleArray, jdoubleArray); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/src/removeoverlap/remove_rectangle_overlap-test.cpp b/src/removeoverlap/remove_rectangle_overlap-test.cpp new file mode 100644 index 000000000..9999d027e --- /dev/null +++ b/src/removeoverlap/remove_rectangle_overlap-test.cpp @@ -0,0 +1,308 @@ +#include "removeoverlap/remove_rectangle_overlap.h" +#include // for alarm() +#include // for srand seed and clock(). +#include +#include +#include +#include +#include "removeoverlap/generate-constraints.h" +#include "utest/utest.h" +using std::abs; +using std::rand; + +static bool +possibly_eq(double const a, double const b) +{ + return abs(a - b) < 1e-13; +} + +static bool +possibly_le(double const a, double const b) +{ + return a - b < 1e-13; +} + +static void +show_rects(unsigned const n_rects, double const rect2coords[][4]) +{ + for (unsigned i = 0; i < n_rects; ++i) { + printf("{%g, %g, %g, %g},\n", + rect2coords[i][0], + rect2coords[i][1], + rect2coords[i][2], + rect2coords[i][3]); + } +} + +/** + * Returns the signum of x, but erring towards returning 0 if x is "not too far" from 0. ("Not too + * far from 0" means [-0.9, 0.9] in current version.) + */ +static int +sgn0(double const x) +{ + if (x <= -0.9) { + return -1; + } else if (0.9 <= x) { + return 1; + } else { + return 0; + } +} + +static void +test_case(unsigned const n_rects, double const rect2coords[][4]) +{ + Rectangle **rs = (Rectangle **) g_malloc(sizeof(Rectangle*) * n_rects); + for (unsigned i = 0; i < n_rects; ++i) { + rs[i] = new Rectangle(rect2coords[i][0], + rect2coords[i][1], + rect2coords[i][2], + rect2coords[i][3]); + } + removeRectangleOverlap(rs, n_rects, 0.0, 0.0); + for (unsigned i = 0; i < n_rects; ++i) { + UTEST_ASSERT(possibly_eq(rs[i]->width(), (rect2coords[i][1] - + rect2coords[i][0] ))); + UTEST_ASSERT(possibly_eq(rs[i]->height(), (rect2coords[i][3] - + rect2coords[i][2] ))); + for (unsigned j = 0; j < i; ++j) { + if (!( possibly_le(rs[i]->getMaxX(), rs[j]->getMinX()) || + possibly_le(rs[j]->getMaxX(), rs[i]->getMinX()) || + possibly_le(rs[i]->getMaxY(), rs[j]->getMinY()) || + possibly_le(rs[j]->getMaxY(), rs[i]->getMinY()) )) { + show_rects(n_rects, rect2coords); + char buf[32]; + sprintf(buf, "[%u],[%u] of %u", j, i, n_rects); + utest__fail("Found overlap among ", buf, " rectangles"); + } + } + + /* Optimality test. */ + { + bool found_block[2] = {false, false}; + int const desired_movement[2] = {sgn0(rect2coords[i][0] - rs[i]->getMinX()), + sgn0(rect2coords[i][2] - rs[i]->getMinY())}; + for (unsigned j = 0; j < n_rects; ++j) { + if (j == i) + continue; + for (unsigned d = 0; d < 2; ++d) { + if ( ( desired_movement[d] < 0 + ? abs(rs[j]->getMaxD(d) - rs[i]->getMinD(d)) + : abs(rs[i]->getMaxD(d) - rs[j]->getMinD(d)) ) + < .002 ) { + found_block[d] = true; + } + } + } + + for (unsigned d = 0; d < 2; ++d) { + if ( !found_block[d] + && desired_movement[d] != 0 ) { + show_rects(n_rects, rect2coords); + char buf[32]; + sprintf(buf, "%c in rectangle [%u] of %u", "XY"[d], i, n_rects); + utest__fail("Found clear non-optimality in ", buf, " rectangles"); + } + } + } + } + for (unsigned i = 0; i < n_rects; ++i) { + delete rs[i]; + } + g_free(rs); +} + +int main() +{ + srand(time(NULL)); + + /* Ensure that the program doesn't run for more than 30 seconds. */ + alarm(30); + + utest_start("removeRectangleOverlap(zero gaps)"); + + /* Derived from Bulia's initial test case. This used to crash. */ + UTEST_TEST("eg0") { + double case0[][4] = { + {-180.5, 69.072, 368.071, 629.071}, + {99.5, 297.644, 319.5, 449.071}, + {199.5, 483.358, 450.929, 571.929}, + {168.071, 277.644, 462.357, 623.357}, + {99.5, 99.751, 479.5, 674.786}, + {-111.929, 103.358, 453.786, 611.929}, + {-29.0714, 143.358, 273.786, 557.643}, + {122.357, 269.072, 322.357, 531.929}, + {256.643, 357.644, 396.643, 520.5} + }; + test_case(G_N_ELEMENTS(case0), case0); + } + +#if 0 /* This involves a zero-height rect, so we'll ignore for the moment. */ + UTEST_TEST("eg1") { + double case1[][4] = { + {5, 14, 9, 14}, + {6, 13, 6, 8}, + {11, 12, 5, 5}, + {5, 8, 5, 7}, + {12, 14, 14, 15}, + {12, 14, 1, 14}, + {1, 15, 14, 15}, + {5, 6, 13, 13} + }; + test_case(G_N_ELEMENTS(case1), case1); + } +#endif + + /* The next few examples used to result in overlaps. */ + UTEST_TEST("eg2") { + double case2[][4] = { + {3, 4, 6, 13}, + {0, 1, 0, 5}, + {0, 4, 1, 6}, + {2, 5, 0, 6}, + {0, 10, 9, 13}, + {5, 11, 1, 13}, + {1, 2, 3, 8} + }; + test_case(G_N_ELEMENTS(case2), case2); + } + + UTEST_TEST("eg3") { + double case3[][4] = { + {0, 5, 0, 3}, + {1, 2, 1, 3}, + {3, 7, 4, 7}, + {0, 9, 4, 5}, + {3, 7, 0, 3} + }; + test_case(G_N_ELEMENTS(case3), case3); + } + + UTEST_TEST("eg4") { + double case4[][4] = { + {0, 1, 2, 3}, + {0, 4, 0, 4}, + {1, 6, 0, 4}, + {2, 3, 4, 5}, + {0, 5, 4, 6} + }; + test_case(G_N_ELEMENTS(case4), case4); + } + + UTEST_TEST("eg5") { + double case5[][4] = { + {1, 5, 1, 2}, + {1, 6, 5, 7}, + {6, 8, 1, 2}, + {2, 3, 1, 4}, + {5, 8, 2, 6} + }; + test_case(G_N_ELEMENTS(case5), case5); + } + + /* This one causes overlap in 2005-12-19 04:00 UTC version. */ + UTEST_TEST("olap6") { + double case6[][4] = { + {7, 22, 39, 54}, + {7, 33, 0, 59}, + {3, 26, 16, 56}, + {7, 17, 18, 20}, + {1, 59, 11, 26}, + {19, 20, 13, 49}, + {1, 10, 0, 4}, + {47, 52, 1, 3} + }; + test_case(G_N_ELEMENTS(case6), case6); + } + + /* The next two examples caused loops in the version at 2005-12-07 04:00 UTC. */ + UTEST_TEST("loop0") { + double loop0[][4] = { + {13, 16, 6, 27}, + {0, 6, 0, 12}, + {11, 14, 1, 10}, + {12, 39, 5, 24}, + {14, 34, 4, 7}, + {1, 30, 20, 27}, + {1, 6, 1, 2}, + {19, 28, 10, 24}, + {4, 34, 15, 21}, + {7, 13, 13, 34} + }; + test_case(G_N_ELEMENTS(loop0), loop0); + } + + UTEST_TEST("loop1") { + double loop1[][4] = { + {6, 18, 9, 16}, + {8, 26, 10, 13}, + {3, 10, 0, 14}, + {0, 5, 16, 22}, + {1, 8, 11, 21}, + {1, 5, 0, 13}, + {24, 25, 0, 2} + }; + test_case(G_N_ELEMENTS(loop1), loop1); + } + + UTEST_TEST("loop2") { + double loop2[][4] = { + {16, 22, 9, 16}, + {8, 9, 14, 19}, + {17, 25, 8, 13}, + {10, 26, 26, 29}, + {14, 19, 9, 19}, + {0, 18, 3, 12}, + {7, 8, 14, 22}, + {14, 20, 25, 29} + }; + test_case(G_N_ELEMENTS(loop2), loop2); + } + + /* Random cases of up to 10 rectangles, with small non-neg int coords. */ + for (unsigned n = 0; n <= 10; ++n) { + char buf[64]; + sprintf(buf, "random ints with %u rectangles", n); + UTEST_TEST(buf) { + unsigned const fld_size = 8 * n; + double (*coords)[4] = (double (*)[4]) g_malloc(n * 4 * sizeof(double)); + clock_t const clock_stop = clock() + CLOCKS_PER_SEC; + for (unsigned repeat = (n == 0 ? 1 + : n == 1 ? 36 + : (1 << 16) ); repeat--;) { + for (unsigned i = 0; i < n; ++i) { + for (unsigned d = 0; d < 2; ++d) { + //unsigned const start = rand() % fld_size; + //unsigned const end = start + rand() % (fld_size - start); + unsigned const end = 1 + (rand() % (fld_size - 1)); + unsigned const start = rand() % end; + coords[i][2 * d] = start; + coords[i][2 * d + 1] = end; + } + } + test_case(n, coords); + if (clock() >= clock_stop) { + break; + } + } + g_free(coords); + } + } + + return ( utest_end() + ? EXIT_SUCCESS + : EXIT_FAILURE ); +} + + +/* + 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:textwidth=99 : diff --git a/src/removeoverlap/remove_rectangle_overlap.cpp b/src/removeoverlap/remove_rectangle_overlap.cpp new file mode 100755 index 000000000..30dbbaf9e --- /dev/null +++ b/src/removeoverlap/remove_rectangle_overlap.cpp @@ -0,0 +1,109 @@ +#include +#include +#include "generate-constraints.h" +#include "solve_VPSC.h" +#include "variable.h" +#include "constraint.h" +#ifdef RECTANGLE_OVERLAP_LOGGING +using std::ios; +using std::ofstream; +using std::endl; +#endif + +#define EXTRA_GAP 0.0001 + +double Rectangle::xBorder=0; +double Rectangle::yBorder=0; +/** + * Takes an array of n rectangles and moves them as little as possible + * such that rectangles are separated by at least xBorder horizontally + * and yBorder vertically + * + * Works in three passes: + * 1) removes some overlap horizontally + * 2) removes remaining overlap vertically + * 3) a last horizontal pass removes all overlap starting from original + * x-positions - this corrects the case where rectangles were moved + * too much in the first pass. + */ +void removeRectangleOverlap(Rectangle *rs[], int n, double xBorder, double yBorder) { + assert(0 <= n); + try { + // The extra gap avoids numerical imprecision problems + Rectangle::setXBorder(xBorder+EXTRA_GAP); + Rectangle::setYBorder(yBorder+EXTRA_GAP); + double *ws=new double[n]; + for(int i=0;idesiredPosition; + } + VPSC vpsc_x(vs,n,cs,m); +#ifdef RECTANGLE_OVERLAP_LOGGING + ofstream f(LOGFILE,ios::app); + f<<"Calling VPSC: Horizontal pass 1"<moveCentreX(vs[i]->position()); + delete vs[i]; + } + delete [] vs; + for(int i = 0; i < m; ++i) { + delete cs[i]; + } + delete [] cs; + // Removing the extra gap here ensures things that were moved to be adjacent to + // one another above are not considered overlapping + Rectangle::setXBorder(Rectangle::xBorder-EXTRA_GAP); + m=generateYConstraints(rs,ws,n,vs,cs); + VPSC vpsc_y(vs,n,cs,m); +#ifdef RECTANGLE_OVERLAP_LOGGING + f.open(LOGFILE,ios::app); + f<<"Calling VPSC: Vertical pass"<moveCentreY(vs[i]->position()); + rs[i]->moveCentreX(oldX[i]); + delete vs[i]; + } + delete [] vs; + delete [] oldX; + for(int i = 0; i < m; ++i) { + delete cs[i]; + } + delete [] cs; + Rectangle::setYBorder(Rectangle::yBorder-EXTRA_GAP); + m=generateXConstraints(rs,ws,n,vs,cs,false); + VPSC vpsc_x2(vs,n,cs,m); +#ifdef RECTANGLE_OVERLAP_LOGGING + f.open(LOGFILE,ios::app); + f<<"Calling VPSC: Horizontal pass 2"<moveCentreX(vs[i]->position()); + delete vs[i]; + } + delete [] vs; + for(int i = 0; i < m; ++i) { + delete cs[i]; + } + delete [] cs; + delete [] ws; + } catch (char *str) { + std::cerr< + * + * Copyright (C) 2005 Authors + * + * Released under GNU GPL. Read the file 'COPYING' for more information. + */ + +class Rectangle; + +void removeRectangleOverlap(Rectangle *rs[], int n, double xBorder, double yBorder); + + +#endif /* !REMOVE_RECTANGLE_OVERLAP_H_SEEN */ diff --git a/src/removeoverlap/removeoverlap.cpp b/src/removeoverlap/removeoverlap.cpp new file mode 100644 index 000000000..9d7beb45f --- /dev/null +++ b/src/removeoverlap/removeoverlap.cpp @@ -0,0 +1,80 @@ +/** \file + * Interface between Inkscape code (SPItem) and remove-overlaps function. + */ +/* +* Authors: +* Tim Dwyer +* +* Copyright (C) 2005 Authors +* +* Released under GNU GPL. Read the file 'COPYING' for more information. +*/ +#include "util/glib-list-iterators.h" +#include "sp-item.h" +#include "sp-item-transform.h" +#include "removeoverlap/generate-constraints.h" +#include "removeoverlap/remove_rectangle_overlap.h" + +/** +* Takes a list of inkscape items and moves them as little as possible +* such that rectangular bounding boxes are separated by at least xGap +* horizontally and yGap vertically +*/ +void removeoverlap(GSList const *const items, double const xGap, double const yGap) { + if(!items) { + return; + } + + using Inkscape::Util::GSListConstIterator; + std::list selected; + selected.insert >(selected.end(), items, NULL); + if (selected.empty()) return; + int n=selected.size(); + + //Check 2 or more selected objects + if (n < 2) return; + + Rectangle **rs = new Rectangle*[n]; + int i=0; + + NR::Point const gap(xGap, yGap); + for (std::list::iterator it(selected.begin()); + it != selected.end(); + ++it) + { + using NR::X; using NR::Y; + NR::Rect const item_box(sp_item_bbox_desktop(*it)); + + /* The current algorithm requires widths & heights to be strictly positive. */ + NR::Point min(item_box.min()); + NR::Point max(item_box.max()); + for (unsigned d = 0; d < 2; ++d) { + double const minsize = 1; // arbitrary positive number + if (max[d] - min[d] + gap[d] < minsize) { + double const mid = .5 * (min[d] + max[d]); + min[d] = mid - .5*minsize; + max[d] = mid + .5*minsize; + } else { + min[d] -= .5*gap[d]; + max[d] += .5*gap[d]; + } + } + rs[i++] = new Rectangle(min[X], max[X], + min[Y], max[Y]); + } + removeRectangleOverlap(rs, n, 0.0, 0.0); + i=0; + for (std::list::iterator it(selected.begin()); + it != selected.end(); + ++it) + { + NR::Rect const item_box(sp_item_bbox_desktop(*it)); + Rectangle *r = rs[i++]; + NR::Point const curr(item_box.midpoint()); + NR::Point const dest(r->getCentreX(), + r->getCentreY()); + sp_item_move_rel(*it, NR::translate(dest - curr)); + delete r; + } + delete [] rs; +} diff --git a/src/removeoverlap/removeoverlap.h b/src/removeoverlap/removeoverlap.h new file mode 100644 index 000000000..b904f52f1 --- /dev/null +++ b/src/removeoverlap/removeoverlap.h @@ -0,0 +1,17 @@ +/** + * \brief Remove overlaps function + * + * Authors: + * Tim Dwyer + * + * Copyright (C) 2005 Authors + * + * Released under GNU GPL. Read the file 'COPYING' for more information. + */ + +#ifndef SEEN_REMOVEOVERLAP_H +#define SEEN_REMOVEOVERLAP_H + +void removeoverlap(GSList const *items, double xGap, double yGap); + +#endif // SEEN_REMOVEOVERLAP_H diff --git a/src/removeoverlap/solve_VPSC.cpp b/src/removeoverlap/solve_VPSC.cpp new file mode 100644 index 000000000..296cc415b --- /dev/null +++ b/src/removeoverlap/solve_VPSC.cpp @@ -0,0 +1,265 @@ +/** + * \brief Remove overlaps function + * + * Authors: + * Tim Dwyer + * + * Copyright (C) 2005 Authors + * + * Released under GNU GPL. Read the file 'COPYING' for more information. + */ + +#include +#include "constraint.h" +#include "block.h" +#include "blocks.h" +#include "solve_VPSC.h" +#ifdef RECTANGLE_OVERLAP_LOGGING +using std::ios; +using std::ofstream; +using std::endl; +#endif + +using std::list; +using std::set; + +VPSC::VPSC(Variable *vs[], const int n, Constraint *cs[], const int m) : cs(cs), m(m) { + //assert(!constraintGraphIsCyclic(vs,n)); + bs=new Blocks(vs,n); +#ifdef RECTANGLE_OVERLAP_LOGGING + printBlocks(); +#endif +} +VPSC::~VPSC() { + delete bs; +} + +// useful in debugging +void VPSC::printBlocks() { +#ifdef RECTANGLE_OVERLAP_LOGGING + ofstream f(LOGFILE,ios::app); + for(set::iterator i=bs->begin();i!=bs->end();i++) { + Block *b=*i; + f<<" "<<*b< *vs=bs->totalOrder(); + for(list::iterator i=vs->begin();i!=vs->end();i++) { + Variable *v=*i; + if(!v->block->deleted) { + bs->mergeLeft(v->block); + } + } + bs->cleanup(); + for(int i=0;islack()<-0.0000001) { +#ifdef RECTANGLE_OVERLAP_LOGGING + ofstream f(LOGFILE,ios::app); + f<<"Error: Unsatisfied constraint: "<<*cs[i]<slack()>-0.0000001); + throw "Unsatisfied constraint"; + } + } + delete vs; +} + +void VPSC::refine() { + bool solved=false; + // Solve shouldn't loop indefinately + // ... but just to make sure we limit the number of iterations + int maxtries=100; + while(!solved&&maxtries>=0) { + solved=true; + maxtries--; + for(set::const_iterator i=bs->begin();i!=bs->end();i++) { + Block *b=*i; + b->setUpInConstraints(); + b->setUpOutConstraints(); + } + for(set::const_iterator i=bs->begin();i!=bs->end();i++) { + Block *b=*i; + Constraint *c=b->findMinLM(); + if(c!=NULL && c->lm<0) { +#ifdef RECTANGLE_OVERLAP_LOGGING + ofstream f(LOGFILE,ios::app); + f<<"Split on constraint: "<<*c<split(b,l,r,c); + bs->cleanup(); + // split alters the block set so we have to restart + solved=false; + break; + } + } + } + for(int i=0;islack()<-0.0000001) { + assert(cs[i]->slack()>-0.0000001); + throw "Unsatisfied constraint"; + } + } +} +/** + * Calculate the optimal solution. After using satisfy() to produce a + * feasible solution, refine() examines each block to see if further + * refinement is possible by splitting the block. This is done repeatedly + * until no further improvement is possible. + */ +void VPSC::solve() { + satisfy(); + refine(); +} + +/** + * incremental version of solve that should allow refinement after blocks are + * moved. Work in progress. + */ +void VPSC::move_and_split() { + //assert(!blockGraphIsCyclic()); + for(set::const_iterator i=bs->begin();i!=bs->end();i++) { + Block *b=*i; + if(!b->deleted) { + b->wposn = b->desiredWeightedPosition(); + b->posn = b->wposn / b->weight; + Variable *v=b->vars->front(); + bs->mergeLeft(b); + // b may be merged away, so get any new block from one of its members + bs->mergeRight(v->block); + } + } + bs->cleanup(); + // assert(!blockGraphIsCyclic()); + refine(); +} + +#include +using std::map; +using std::vector; +struct node { + set in; + set out; +}; +/* +// useful in debugging - cycles would be BAD +bool VPSC::constraintGraphIsCyclic(Variable *vs[], const int n) { + map varmap; + vector graph; + for(int i=0;i::iterator c=vs[i]->in.begin();c!=vs[i]->in.end();c++) { + Variable *l=(*c)->left; + varmap[vs[i]]->in.insert(varmap[l]); + } + + for(vector::iterator c=vs[i]->out.begin();c!=vs[i]->out.end();c++) { + Variable *r=(*c)->right; + varmap[vs[i]]->out.insert(varmap[r]); + } + } + while(graph.size()>0) { + node *u=NULL; + vector::iterator i=graph.begin(); + for(;i!=graph.end();i++) { + u=*i; + if(u->in.size()==0) { + break; + } + } + if(i==graph.end() && graph.size()>0) { + //cycle found! + return true; + } else { + graph.erase(i); + for(set::iterator j=u->out.begin();j!=u->out.end();j++) { + node *v=*j; + v->in.erase(u); + } + delete u; + } + } + for(unsigned i=0; i bmap; + vector graph; + for(set::const_iterator i=bs->begin();i!=bs->end();i++) { + Block *b=*i; + node *u=new node; + graph.push_back(u); + bmap[b]=u; + } + for(set::const_iterator i=bs->begin();i!=bs->end();i++) { + Block *b=*i; + b->setUpInConstraints(); + Constraint *c=b->findMinInConstraint(); + while(c!=NULL) { + Block *l=c->left->block; + bmap[b]->in.insert(bmap[l]); + b->deleteMinInConstraint(); + c=b->findMinInConstraint(); + } + + b->setUpOutConstraints(); + c=b->findMinOutConstraint(); + while(c!=NULL) { + Block *r=c->right->block; + bmap[b]->out.insert(bmap[r]); + b->deleteMinOutConstraint(); + c=b->findMinOutConstraint(); + } + } + while(graph.size()>0) { + node *u=NULL; + vector::iterator i=graph.begin(); + for(;i!=graph.end();i++) { + u=*i; + if(u->in.size()==0) { + break; + } + } + if(i==graph.end() && graph.size()>0) { + //cycle found! + return true; + } else { + graph.erase(i); + for(set::iterator j=u->out.begin();j!=u->out.end();j++) { + node *v=*j; + v->in.erase(u); + } + delete u; + } + } + for(unsigned i=0; i +* +* Copyright (C) 2005 Authors +* +* Released under GNU GPL. Read the file 'COPYING' for more information. +*/ + +#ifndef SEEN_REMOVEOVERLAP_SOLVE_VPSC_H +#define SEEN_REMOVEOVERLAP_SOLVE_VPSC_H + +class Variable; +class Constraint; +class Blocks; + +/** + * Variable Placement with Separation Constraints problem instance + */ +class VPSC { +public: + void satisfy(); + void solve(); + + void move_and_split(); + VPSC(Variable *vs[], const int n, Constraint *cs[], const int m); + ~VPSC(); +protected: + Blocks *bs; + void refine(); +private: + void printBlocks(); + bool constraintGraphIsCyclic(Variable *vs[], const int n); + bool blockGraphIsCyclic(); + Constraint **cs; + int m; +}; + +#endif // SEEN_REMOVEOVERLAP_SOLVE_VPSC_H diff --git a/src/removeoverlap/variable.cpp b/src/removeoverlap/variable.cpp new file mode 100644 index 000000000..0cf2e28a7 --- /dev/null +++ b/src/removeoverlap/variable.cpp @@ -0,0 +1,20 @@ +/** + * \brief Remove overlaps function + * + * Authors: + * Tim Dwyer + * + * Copyright (C) 2005 Authors + * + * Released under GNU GPL. Read the file 'COPYING' for more information. + */ +#include "variable.h" +std::ostream& operator <<(std::ostream &os, const Variable &v) { + os << "(" << v.id << "=" << v.position() << ")"; + return os; +} + +#include "block.h" +double Variable::position() const { + return block->posn+offset; +} diff --git a/src/removeoverlap/variable.h b/src/removeoverlap/variable.h new file mode 100644 index 000000000..492e7504a --- /dev/null +++ b/src/removeoverlap/variable.h @@ -0,0 +1,46 @@ +/** + * \brief Remove overlaps function + * + * Authors: + * Tim Dwyer + * + * Copyright (C) 2005 Authors + * + * Released under GNU GPL. Read the file 'COPYING' for more information. + */ + +#ifndef SEEN_REMOVEOVERLAP_VARIABLE_H +#define SEEN_REMOVEOVERLAP_VARIABLE_H + +#include +#include +class Block; +class Constraint; + +class Variable +{ + friend std::ostream& operator <<(std::ostream &os, const Variable &v); +public: + static const unsigned int _TOSTRINGBUFFSIZE=20; + const int id; // useful in log files + double desiredPosition; + const double weight; + double offset; + Block *block; + bool visited; + std::vector in; + std::vector out; + char *toString(); + inline Variable(const int id, const double desiredPos, const double weight) + : id(id) + , desiredPosition(desiredPos) + , weight(weight) + { + } + double position() const; + ~Variable(void){ + in.clear(); + out.clear(); + } +}; +#endif // SEEN_REMOVEOVERLAP_VARIABLE_H diff --git a/src/require-config.h b/src/require-config.h new file mode 100644 index 000000000..7c7ef0552 --- /dev/null +++ b/src/require-config.h @@ -0,0 +1,3 @@ +#ifndef PACKAGE_TARNAME /* random symbol defined by config.h */ +# error "Must #include config.h (ifdef HAVE_CONFIG_H) before anything else." +#endif diff --git a/src/round-test.cpp b/src/round-test.cpp new file mode 100644 index 000000000..efb4b3e83 --- /dev/null +++ b/src/round-test.cpp @@ -0,0 +1,91 @@ +#include +#include +#include + +#include +#include +#include + +static Case1 const nonneg_round_cases[] = { + { 5.0, 5.0 }, + { 0.0, 0.0 }, + { 5.4, 5.0 }, + { 5.6, 6.0 }, + { 1e-7, 0.0 }, + { 1e7 + .49, 1e7 }, + { 1e7 + .51, 1e7 + 1 }, + { 1e12 + .49, 1e12 }, + { 1e12 + .51, 1e12 + 1 }, + { 1e40, 1e40 } +}; + +static Case1 nonpos_round_cases[G_N_ELEMENTS(nonneg_round_cases)]; + +static void fill_nonpos_round_cases() +{ + assert(G_N_ELEMENTS(nonneg_round_cases) == G_N_ELEMENTS(nonpos_round_cases)); + for(unsigned i = 0; i < G_N_ELEMENTS(nonpos_round_cases); ++i) { + nonpos_round_cases[i].f_arg0 = -nonneg_round_cases[i].f_arg0; + nonpos_round_cases[i].valid_arg0 = -nonneg_round_cases[i].valid_arg0; + } +} + +static bool +test_round() +{ + utest_start("round"); + test_1ary_cases > + ("non-neg round", + Inkscape::round, + G_N_ELEMENTS(nonneg_round_cases), nonneg_round_cases); + + fill_nonpos_round_cases(); + + test_1ary_cases > + ("non-pos round", + Inkscape::round, + G_N_ELEMENTS(nonpos_round_cases), nonpos_round_cases); + +#if 0 + for(unsigned i = 0; i < G_N_ELEMENTS(round_cases); ++i) { + RoundCase const &c = round_cases[i]; + double const got = Inkscape::round(c.unrounded); + UTEST_ASSERT( got == c.exp_rounded ); + + double const neg_got = Inkscape::round(-c.unrounded); + UTEST_ASSERT( neg_got = -c.exp_rounded ); + } +#endif + return utest_end(); +} + +#if 0 +/* Deliberately down here just to ensure that correct behaviour of Inkscape::round doesn't depend + on #including decimal-round.h. (decimal-round.h already #includes round.h, so there's no point + checking the other way around.) */ +#include + +static void +test_decimal_round() +{ +} +#endif + +int main() +{ + int const ret = ( test_round() + ? EXIT_SUCCESS + : EXIT_FAILURE ); + return ret; +} + +/* + 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 : diff --git a/src/round.h b/src/round.h new file mode 100644 index 000000000..16d280566 --- /dev/null +++ b/src/round.h @@ -0,0 +1,32 @@ +#ifndef SEEN_ROUND_H +#define SEEN_ROUND_H + +#include + +namespace Inkscape { + +/** Returns x rounded to the nearest integer. It is unspecified what happens + if x is half way between two integers: we may in future use rint/round + on platforms that have them. If you depend on a particular rounding + behaviour, then please change this documentation accordingly. +**/ +inline double +round(double const x) +{ + return std::floor( x + .5 ); +} + +} + +#endif /* !SEEN_ROUND_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 : diff --git a/src/rubberband.cpp b/src/rubberband.cpp new file mode 100644 index 000000000..d44662c5b --- /dev/null +++ b/src/rubberband.cpp @@ -0,0 +1,82 @@ +#define __RUBBERBAND_C__ + +/** + * \file src/rubberband.cpp + * \brief Rubberbanding selector + * + * Author: + * Lauris Kaplinski + * + * Copyright (C) 1999-2002 Lauris Kaplinski + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "display/sodipodi-ctrlrect.h" +#include "desktop.h" +#include "desktop-handles.h" +#include "rubberband.h" + +Inkscape::Rubberband *Inkscape::Rubberband::_instance = NULL; + +Inkscape::Rubberband::Rubberband() + : _desktop(NULL), _canvas(NULL) +{ + +} + +void Inkscape::Rubberband::start(SPDesktop *d, NR::Point const &p) +{ + stop(); + _desktop = d; + _start = p; +} + +void Inkscape::Rubberband::stop() +{ + if (_canvas) { + gtk_object_destroy((GtkObject *) _canvas); + _canvas = NULL; + } +} + +void Inkscape::Rubberband::move(NR::Point const &p) +{ + if (_canvas == NULL) { + _canvas = static_cast(sp_canvas_item_new(SP_DT_CONTROLS(_desktop), SP_TYPE_CTRLRECT, NULL)); + } + + _desktop->scroll_to_point(&p); + _end = p; + + _canvas->setRectangle(NR::Rect(_start, _end)); +} + +NR::Maybe Inkscape::Rubberband::getRectangle() const +{ + if (_canvas == NULL) { + return NR::Nothing(); + } + + return NR::Rect(_start, _end); +} + +Inkscape::Rubberband *Inkscape::Rubberband::get() +{ + if (_instance == NULL) { + _instance = new Inkscape::Rubberband; + } + + return _instance; +} + +/* + 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:textwidth=99 : diff --git a/src/rubberband.h b/src/rubberband.h new file mode 100644 index 000000000..9dd0b6025 --- /dev/null +++ b/src/rubberband.h @@ -0,0 +1,64 @@ +#ifndef __RUBBERBAND_H__ +#define __RUBBERBAND_H__ + +/** + * \file src/rubberband.h + * \brief Rubberbanding selector + * + * Authors: + * Lauris Kaplinski + * Carl Hetherington + * + * Copyright (C) 1999-2002 Lauris Kaplinski + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "forward.h" +#include "libnr/nr-forward.h" +#include "libnr/nr-point.h" +#include "libnr/nr-maybe.h" + +/* fixme: do multidocument safe */ + +class CtrlRect; + +namespace Inkscape +{ + +class Rubberband +{ +public: + + void start(SPDesktop *desktop, NR::Point const &p); + void move(NR::Point const &p); + NR::Maybe getRectangle() const; + void stop(); + + static Rubberband* get(); + +private: + + Rubberband(); + static Rubberband* _instance; + + SPDesktop *_desktop; + NR::Point _start; + NR::Point _end; + CtrlRect *_canvas; +}; + +} + +#endif + +/* + 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:textwidth=99 : diff --git a/src/satisfied-guide-cns.cpp b/src/satisfied-guide-cns.cpp new file mode 100644 index 000000000..edbf32dbb --- /dev/null +++ b/src/satisfied-guide-cns.cpp @@ -0,0 +1,33 @@ +#include +#include +#include +#include +#include +#include + +void satisfied_guide_cns(SPDesktop const &desktop, + std::vector const &snappoints, + std::vector &cns) +{ + SPNamedView const &nv = *SP_DT_NAMEDVIEW(&desktop); + for (GSList const *l = nv.guides; l != NULL; l = l->next) { + SPGuide &g = *SP_GUIDE(l->data); + for (unsigned int i = 0; i < snappoints.size(); ++i) { + if (approx_equal(dot(g.normal, snappoints[i]), g.position)) { + cns.push_back(SPGuideConstraint(&g, i)); + } + } + } +} + + +/* + 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:textwidth=99 : diff --git a/src/satisfied-guide-cns.h b/src/satisfied-guide-cns.h new file mode 100644 index 000000000..93097e021 --- /dev/null +++ b/src/satisfied-guide-cns.h @@ -0,0 +1,25 @@ +#ifndef __SATISFIED_GUIDE_CNS_H__ +#define __SATISFIED_GUIDE_CNS_H__ + +#include +namespace NR { class Point; } +#include +class SPGuideConstraint; + +void satisfied_guide_cns(SPDesktop const &desktop, + std::vector const &snappoints, + std::vector &cns); + + +#endif /* !__SATISFIED_GUIDE_CNS_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:encoding=utf-8:textwidth=99 : diff --git a/src/selcue.cpp b/src/selcue.cpp new file mode 100644 index 000000000..845561d18 --- /dev/null +++ b/src/selcue.cpp @@ -0,0 +1,153 @@ +#define __SELCUE_C__ + +/* + * Helper object for showing selected items + * + * Authors: + * bulia byak + * Carl Hetherington + * + * Copyright (C) 2004 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "desktop-handles.h" +#include "selection.h" +#include "display/sp-canvas-util.h" +#include "display/sodipodi-ctrl.h" +#include "display/sodipodi-ctrlrect.h" +#include "libnrtype/Layout-TNG.h" +#include "text-editing.h" +#include "sp-text.h" +#include "sp-flowtext.h" +#include "prefs-utils.h" +#include "selcue.h" + +Inkscape::SelCue::SelCue(SPDesktop *desktop) + : _desktop(desktop) +{ + _selection = SP_DT_SELECTION(_desktop); + + _sel_changed_connection = _selection->connectChanged( + sigc::hide(sigc::mem_fun(*this, &Inkscape::SelCue::_updateItemBboxes)) + ); + + _sel_modified_connection = _selection->connectModified( + sigc::hide(sigc::hide(sigc::mem_fun(*this, &Inkscape::SelCue::_updateItemBboxes))) + ); + + _updateItemBboxes(); +} + +Inkscape::SelCue::~SelCue() +{ + _sel_changed_connection.disconnect(); + _sel_modified_connection.disconnect(); + + for (std::list::iterator i = _item_bboxes.begin(); i != _item_bboxes.end(); i++) { + gtk_object_destroy(*i); + } + _item_bboxes.clear(); + + for (std::list::iterator i = _text_baselines.begin(); i != _text_baselines.end(); i++) { + gtk_object_destroy(*i); + } + _text_baselines.clear(); +} + +void Inkscape::SelCue::_updateItemBboxes() +{ + for (std::list::iterator i = _item_bboxes.begin(); i != _item_bboxes.end(); i++) { + gtk_object_destroy(*i); + } + _item_bboxes.clear(); + + for (std::list::iterator i = _text_baselines.begin(); i != _text_baselines.end(); i++) { + gtk_object_destroy(*i); + } + _text_baselines.clear(); + + gint mode = prefs_get_int_attribute ("options.selcue", "value", MARK); + if (mode == NONE) { + return; + } + + g_return_if_fail(_selection != NULL); + + for (GSList const *l = _selection->itemList(); l != NULL; l = l->next) { + SPItem *item = (SPItem *) l->data; + + NR::Rect const b = sp_item_bbox_desktop(item); + + SPCanvasItem* box = NULL; + + if (mode == MARK) { + box = sp_canvas_item_new(SP_DT_CONTROLS(_desktop), + SP_TYPE_CTRL, + "mode", SP_CTRL_MODE_XOR, + "shape", SP_CTRL_SHAPE_DIAMOND, + "size", 5.0, + "filled", TRUE, + "fill_color", 0x000000ff, + "stroked", FALSE, + "stroke_color", 0x000000ff, + NULL); + sp_canvas_item_show(box); + SP_CTRL(box)->moveto(NR::Point(b.min()[NR::X], b.max()[NR::Y])); + + sp_canvas_item_move_to_z(box, 0); // just low enough to not get in the way of other draggable knots + + } else if (mode == BBOX) { + box = sp_canvas_item_new( + SP_DT_CONTROLS(_desktop), + SP_TYPE_CTRLRECT, + NULL + ); + + SP_CTRLRECT(box)->setRectangle(b); + SP_CTRLRECT(box)->setColor(0x000000a0, 0, 0); + SP_CTRLRECT(box)->setDashed(true); + + sp_canvas_item_move_to_z(box, 0); + } + + if (box) { + _item_bboxes.push_back(box); + } + + SPCanvasItem* baseline_point = NULL; + if (SP_IS_TEXT(item) || SP_IS_FLOWTEXT(item)) { // visualize baseline + Inkscape::Text::Layout const *layout = te_get_layout(item); + if (layout != NULL) { + NR::Point a = layout->characterAnchorPoint(layout->begin()) * sp_item_i2d_affine(item); + baseline_point = sp_canvas_item_new(SP_DT_CONTROLS(_desktop), SP_TYPE_CTRL, + "mode", SP_CTRL_MODE_XOR, + "size", 4.0, + "filled", 0, + "stroked", 1, + "stroke_color", 0x000000ff, + NULL); + + sp_canvas_item_show(baseline_point); + SP_CTRL(baseline_point)->moveto(a); + sp_canvas_item_move_to_z(baseline_point, 0); + } + } + + if (baseline_point) { + _text_baselines.push_back(baseline_point); + } + } +} + +/* + 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 : diff --git a/src/selcue.h b/src/selcue.h new file mode 100644 index 000000000..42ebc9878 --- /dev/null +++ b/src/selcue.h @@ -0,0 +1,64 @@ +#ifndef __SP_SELCUE_H__ +#define __SP_SELCUE_H__ + +/* + * Helper object for showing selected items + * + * Authors: + * bulia byak + * Carl Hetherington + * + * Copyright (C) 2004 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include +#include + +class SPDesktop; +class SPCanvasItem; + +namespace Inkscape { + +class Selection; + +class SelCue +{ +public: + SelCue(SPDesktop *desktop); + ~SelCue(); + + enum Type { + NONE, + MARK, + BBOX + }; + +private: + + void _updateItemBboxes(); + + SPDesktop *_desktop; + Selection *_selection; + sigc::connection _sel_changed_connection; + sigc::connection _sel_modified_connection; + std::list _item_bboxes; + std::list _text_baselines; +}; + +} + +#endif + + +/* + 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 : diff --git a/src/select-context.cpp b/src/select-context.cpp new file mode 100644 index 000000000..bda4012c7 --- /dev/null +++ b/src/select-context.cpp @@ -0,0 +1,823 @@ +#define __SP_SELECT_CONTEXT_C__ + +/* + * Selection and transformation context + * + * Author: + * Lauris Kaplinski + * bulia byak + * + * Copyright (C) 1999-2005 authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif +#include +#include "macros.h" +#include "rubberband.h" +#include "document.h" +#include "selection.h" +#include "seltrans-handles.h" +#include "sp-cursor.h" +#include "pixmaps/cursor-select-m.xpm" +#include "pixmaps/cursor-select-d.xpm" +#include "pixmaps/handles.xpm" +#include + +#include "select-context.h" +#include "selection-chemistry.h" +#include "desktop.h" +#include "desktop-handles.h" +#include "sp-root.h" +#include "prefs-utils.h" +#include "tools-switch.h" +#include "message-stack.h" +#include "selection-describer.h" +#include "seltrans.h" + +static void sp_select_context_class_init(SPSelectContextClass *klass); +static void sp_select_context_init(SPSelectContext *select_context); +static void sp_select_context_dispose(GObject *object); + +static void sp_select_context_setup(SPEventContext *ec); +static void sp_select_context_set(SPEventContext *ec, gchar const *key, gchar const *val); +static gint sp_select_context_root_handler(SPEventContext *event_context, GdkEvent *event); +static gint sp_select_context_item_handler(SPEventContext *event_context, SPItem *item, GdkEvent *event); + +static SPEventContextClass *parent_class; + +static GdkCursor *CursorSelectMouseover = NULL; +static GdkCursor *CursorSelectDragging = NULL; +GdkPixbuf *handles[13]; + +static gint rb_escaped = 0; // if non-zero, rubberband was canceled by esc, so the next button release should not deselect +static gint drag_escaped = 0; // if non-zero, drag was canceled by esc + +static gint xp = 0, yp = 0; // where drag started +static gint tolerance = 0; +static bool within_tolerance = false; + +GtkType +sp_select_context_get_type(void) +{ + static GType type = 0; + if (!type) { + GTypeInfo info = { + sizeof(SPSelectContextClass), + NULL, NULL, + (GClassInitFunc) sp_select_context_class_init, + NULL, NULL, + sizeof(SPSelectContext), + 4, + (GInstanceInitFunc) sp_select_context_init, + NULL, /* value_table */ + }; + type = g_type_register_static(SP_TYPE_EVENT_CONTEXT, "SPSelectContext", &info, (GTypeFlags)0); + } + return type; +} + +static void +sp_select_context_class_init(SPSelectContextClass *klass) +{ + GObjectClass *object_class = (GObjectClass *) klass; + SPEventContextClass *event_context_class = (SPEventContextClass *) klass; + + parent_class = (SPEventContextClass*)g_type_class_peek_parent(klass); + + object_class->dispose = sp_select_context_dispose; + + event_context_class->setup = sp_select_context_setup; + event_context_class->set = sp_select_context_set; + event_context_class->root_handler = sp_select_context_root_handler; + event_context_class->item_handler = sp_select_context_item_handler; + + // cursors in select context + CursorSelectMouseover = sp_cursor_new_from_xpm(cursor_select_m_xpm , 1, 1); + CursorSelectDragging = sp_cursor_new_from_xpm(cursor_select_d_xpm , 1, 1); + // selection handles + handles[0] = gdk_pixbuf_new_from_xpm_data((gchar const **)handle_scale_nw_xpm); + handles[1] = gdk_pixbuf_new_from_xpm_data((gchar const **)handle_scale_ne_xpm); + handles[2] = gdk_pixbuf_new_from_xpm_data((gchar const **)handle_scale_h_xpm); + handles[3] = gdk_pixbuf_new_from_xpm_data((gchar const **)handle_scale_v_xpm); + handles[4] = gdk_pixbuf_new_from_xpm_data((gchar const **)handle_rotate_nw_xpm); + handles[5] = gdk_pixbuf_new_from_xpm_data((gchar const **)handle_rotate_n_xpm); + handles[6] = gdk_pixbuf_new_from_xpm_data((gchar const **)handle_rotate_ne_xpm); + handles[7] = gdk_pixbuf_new_from_xpm_data((gchar const **)handle_rotate_e_xpm); + handles[8] = gdk_pixbuf_new_from_xpm_data((gchar const **)handle_rotate_se_xpm); + handles[9] = gdk_pixbuf_new_from_xpm_data((gchar const **)handle_rotate_s_xpm); + handles[10] = gdk_pixbuf_new_from_xpm_data((gchar const **)handle_rotate_sw_xpm); + handles[11] = gdk_pixbuf_new_from_xpm_data((gchar const **)handle_rotate_w_xpm); + handles[12] = gdk_pixbuf_new_from_xpm_data((gchar const **)handle_center_xpm); + +} + +static void +sp_select_context_init(SPSelectContext *sc) +{ + sc->dragging = FALSE; + sc->moved = FALSE; + sc->button_press_shift = false; + sc->button_press_ctrl = false; + sc->button_press_alt = false; + sc->_seltrans = NULL; + sc->_describer = NULL; +} + +static void +sp_select_context_dispose(GObject *object) +{ + SPSelectContext *sc = SP_SELECT_CONTEXT(object); + SPEventContext * ec = SP_EVENT_CONTEXT (object); + + ec->enableGrDrag(false); + + if (sc->grabbed) { + sp_canvas_item_ungrab(sc->grabbed, GDK_CURRENT_TIME); + sc->grabbed = NULL; + } + + delete sc->_seltrans; + sc->_seltrans = NULL; + delete sc->_describer; + sc->_describer = NULL; + + if (CursorSelectDragging) { + gdk_cursor_unref (CursorSelectDragging); + CursorSelectDragging = NULL; + } + if (CursorSelectMouseover) { + gdk_cursor_unref (CursorSelectMouseover); + CursorSelectMouseover = NULL; + } + + G_OBJECT_CLASS(parent_class)->dispose(object); +} + +static void +sp_select_context_setup(SPEventContext *ec) +{ + SPSelectContext *select_context = SP_SELECT_CONTEXT(ec); + + if (((SPEventContextClass *) parent_class)->setup) { + ((SPEventContextClass *) parent_class)->setup(ec); + } + + SPDesktop *desktop = ec->desktop; + + select_context->_describer = new Inkscape::SelectionDescriber(desktop->selection, desktop->messageStack()); + + select_context->_seltrans = new Inkscape::SelTrans(desktop); + + sp_event_context_read(ec, "show"); + sp_event_context_read(ec, "transform"); + + if (prefs_get_int_attribute("tools.select", "gradientdrag", 0) != 0) { + ec->enableGrDrag(); + } +} + +static void +sp_select_context_set(SPEventContext *ec, gchar const *key, gchar const *val) +{ + SPSelectContext *sc = SP_SELECT_CONTEXT(ec); + + if (!strcmp(key, "show")) { + if (val && !strcmp(val, "outline")) { + sc->_seltrans->setShow(Inkscape::SelTrans::SHOW_OUTLINE); + } else { + sc->_seltrans->setShow(Inkscape::SelTrans::SHOW_CONTENT); + } + } +} + +static bool +sp_select_context_abort(SPEventContext *event_context) +{ + SPDesktop *desktop = event_context->desktop; + SPSelectContext *sc = SP_SELECT_CONTEXT(event_context); + Inkscape::SelTrans *seltrans = sc->_seltrans; + + if (sc->dragging) { + if (sc->moved) { // cancel dragging an object + seltrans->ungrab(); + sc->moved = FALSE; + sc->dragging = FALSE; + drag_escaped = 1; + + if (sc->item) { + // only undo if the item is still valid + if (SP_OBJECT_DOCUMENT( SP_OBJECT(sc->item))) { + sp_document_undo(SP_DT_DOCUMENT(desktop)); + } + + sp_object_unref( SP_OBJECT(sc->item), NULL); + } else if (sc->button_press_ctrl) { + // NOTE: This is a workaround to a bug. + // When the ctrl key is held, sc->item is not defined + // so in this case (only), we skip the object doc check + sp_document_undo(SP_DT_DOCUMENT(desktop)); + } + sc->item = NULL; + + SP_EVENT_CONTEXT(sc)->desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Move canceled.")); + return true; + } + } else { + NR::Maybe const b = Inkscape::Rubberband::get()->getRectangle(); + if (b != NR::Nothing()) { + Inkscape::Rubberband::get()->stop(); + rb_escaped = 1; + SP_EVENT_CONTEXT(sc)->desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Selection canceled.")); + return true; + } + } + return false; +} + +bool +key_is_a_modifier (guint key) { + return (key == GDK_Alt_L || + key == GDK_Alt_R || + key == GDK_Control_L || + key == GDK_Control_R || + key == GDK_Shift_L || + key == GDK_Shift_R || + key == GDK_Meta_L || // Meta is when you press Shift+Alt (at least on my machine) + key == GDK_Meta_R); +} + +void +sp_select_context_up_one_layer(SPDesktop *desktop) +{ + /* Click in empty place, go up one level -- but don't leave a layer to root. + * + * (Rationale: we don't usually allow users to go to the root, since that + * detracts from the layer metaphor: objects at the root level can in front + * of or behind layers. Whereas it's fine to go to the root if editing + * a document that has no layers (e.g. a non-Inkscape document).) + * + * Once we support editing SVG "islands" (e.g. embedded in an xhtml + * document), we might consider further restricting the below to disallow + * leaving a layer to go to a non-layer. + */ + SPObject *const current_layer = desktop->currentLayer(); + if (current_layer) { + SPObject *const parent = SP_OBJECT_PARENT(current_layer); + if ( parent + && ( SP_OBJECT_PARENT(parent) + || !( SP_IS_GROUP(current_layer) + && ( SPGroup::LAYER + == SP_GROUP(current_layer)->layerMode() ) ) ) ) + { + desktop->setCurrentLayer(parent); + if (SP_IS_GROUP(current_layer) && SPGroup::LAYER != SP_GROUP(current_layer)->layerMode()) + SP_DT_SELECTION(desktop)->set(current_layer); + } + } +} + +static gint +sp_select_context_item_handler(SPEventContext *event_context, SPItem *item, GdkEvent *event) +{ + gint ret = FALSE; + + SPDesktop *desktop = event_context->desktop; + SPSelectContext *sc = SP_SELECT_CONTEXT(event_context); + Inkscape::SelTrans *seltrans = sc->_seltrans; + + tolerance = prefs_get_int_attribute_limited("options.dragtolerance", "value", 0, 0, 100); + + // make sure we still have valid objects to move around + if (sc->item && SP_OBJECT_DOCUMENT( SP_OBJECT(sc->item))==NULL) { + sp_select_context_abort(event_context); + } + + switch (event->type) { + case GDK_BUTTON_PRESS: + if (event->button.button == 1) { + /* Left mousebutton */ + + // save drag origin + xp = (gint) event->button.x; + yp = (gint) event->button.y; + within_tolerance = true; + + // remember what modifiers were on before button press + sc->button_press_shift = (event->button.state & GDK_SHIFT_MASK) ? true : false; + sc->button_press_ctrl = (event->button.state & GDK_CONTROL_MASK) ? true : false; + sc->button_press_alt = (event->button.state & GDK_MOD1_MASK) ? true : false; + + if (event->button.state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK)) { + // if shift or ctrl was pressed, do not move objects; + // pass the event to root handler which will perform rubberband, shift-click, ctrl-click, ctrl-drag + } else { + sc->dragging = TRUE; + sc->moved = FALSE; + + // remember the clicked item in sc->item: + sc->item = sp_event_context_find_item (desktop, + NR::Point(event->button.x, event->button.y), event->button.state & GDK_MOD1_MASK, FALSE); + sp_object_ref(sc->item, NULL); + + rb_escaped = drag_escaped = 0; + + sp_canvas_item_grab(SP_CANVAS_ITEM(desktop->drawing), + GDK_KEY_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_BUTTON_PRESS_MASK | + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK, + NULL, event->button.time); + sc->grabbed = SP_CANVAS_ITEM(desktop->drawing); + + ret = TRUE; + } + } else if (event->button.button == 3) { + // right click; do not eat it so that right-click menu can appear, but cancel dragging & rubberband + sp_select_context_abort(event_context); + } + break; + + case GDK_ENTER_NOTIFY: + { + GdkCursor *cursor = gdk_cursor_new(GDK_FLEUR); + gdk_window_set_cursor(GTK_WIDGET(SP_DT_CANVAS(desktop))->window, cursor); + gdk_cursor_destroy(cursor); + break; + } + + case GDK_LEAVE_NOTIFY: + gdk_window_set_cursor(GTK_WIDGET(SP_DT_CANVAS(desktop))->window, event_context->cursor); + break; + + case GDK_KEY_PRESS: + if (get_group0_keyval (&event->key) == GDK_space) { + if (sc->dragging && sc->grabbed) { + /* stamping mode: show content mode moving */ + seltrans->stamp(); + ret = TRUE; + } + } + break; + + default: + break; + } + + if (!ret) { + if (((SPEventContextClass *) parent_class)->item_handler) + ret = ((SPEventContextClass *) parent_class)->item_handler(event_context, item, event); + } + + return ret; +} + +static gint +sp_select_context_root_handler(SPEventContext *event_context, GdkEvent *event) +{ + SPItem *item = NULL; + SPItem *item_at_point = NULL, *group_at_point = NULL, *item_in_group = NULL; + gint ret = FALSE; + + SPDesktop *desktop = event_context->desktop; + SPSelectContext *sc = SP_SELECT_CONTEXT(event_context); + Inkscape::SelTrans *seltrans = sc->_seltrans; + Inkscape::Selection *selection = SP_DT_SELECTION(desktop); + gdouble const nudge = prefs_get_double_attribute_limited("options.nudgedistance", "value", 2, 0, 1000); // in px + gdouble const offset = prefs_get_double_attribute_limited("options.defaultscale", "value", 2, 0, 1000); + tolerance = prefs_get_int_attribute_limited("options.dragtolerance", "value", 0, 0, 100); + int const snaps = prefs_get_int_attribute("options.rotationsnapsperpi", "value", 12); + + // make sure we still have valid objects to move around + if (sc->item && SP_OBJECT_DOCUMENT( SP_OBJECT(sc->item))==NULL) { + sp_select_context_abort(event_context); + } + + switch (event->type) { + case GDK_2BUTTON_PRESS: + if (event->button.button == 1) { + if (!selection->isEmpty()) { + SPItem *clicked_item = (SPItem *) selection->itemList()->data; + if (SP_IS_GROUP (clicked_item)) { // enter group + desktop->setCurrentLayer(reinterpret_cast(clicked_item)); + SP_DT_SELECTION(desktop)->clear(); + sc->dragging = false; + } else { // switch tool + tools_switch_by_item (desktop, clicked_item); + } + } else { + sp_select_context_up_one_layer(desktop); + } + ret = TRUE; + } + break; + case GDK_BUTTON_PRESS: + if (event->button.button == 1) { + + // save drag origin + xp = (gint) event->button.x; + yp = (gint) event->button.y; + within_tolerance = true; + + NR::Point const button_pt(event->button.x, event->button.y); + NR::Point const p(desktop->w2d(button_pt)); + Inkscape::Rubberband::get()->start(desktop, p); + sp_canvas_item_grab(SP_CANVAS_ITEM(desktop->acetate), + GDK_KEY_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK | GDK_BUTTON_PRESS_MASK, + NULL, event->button.time); + sc->grabbed = SP_CANVAS_ITEM(desktop->acetate); + + // remember what modifiers were on before button press + sc->button_press_shift = (event->button.state & GDK_SHIFT_MASK) ? true : false; + sc->button_press_ctrl = (event->button.state & GDK_CONTROL_MASK) ? true : false; + sc->button_press_alt = (event->button.state & GDK_MOD1_MASK) ? true : false; + + sc->moved = FALSE; + + rb_escaped = drag_escaped = 0; + + ret = TRUE; + } else if (event->button.button == 3) { + // right click; do not eat it so that right-click menu can appear, but cancel dragging & rubberband + sp_select_context_abort(event_context); + } + break; + + case GDK_MOTION_NOTIFY: + if (event->motion.state & GDK_BUTTON1_MASK) { + NR::Point const motion_pt(event->motion.x, event->motion.y); + NR::Point const p(desktop->w2d(motion_pt)); + + if ( within_tolerance + && ( abs( (gint) event->motion.x - xp ) < tolerance ) + && ( abs( (gint) event->motion.y - yp ) < tolerance ) ) { + break; // do not drag if we're within tolerance from origin + } + // Once the user has moved farther than tolerance from the original location + // (indicating they intend to move the object, not click), then always process the + // motion notify coordinates as given (no snapping back to origin) + within_tolerance = false; + + if (sc->button_press_ctrl || sc->button_press_alt) // if ctrl or alt was pressed and it's not click, we want to drag rather than rubberband + sc->dragging = TRUE; + + if (sc->dragging) { + /* User has dragged fast, so we get events on root (lauris)*/ + // not only that; we will end up here when ctrl-dragging as well + // and also when we started within tolerance, but trespassed tolerance outside of item + Inkscape::Rubberband::get()->stop(); + item_at_point = desktop->item_at_point(NR::Point(event->button.x, event->button.y), FALSE); + if (!item_at_point) // if no item at this point, try at the click point (bug 1012200) + item_at_point = desktop->item_at_point(NR::Point(xp, yp), FALSE); + if (item_at_point || sc->moved || sc->button_press_alt) { + // drag only if starting from an item, or if something is already grabbed, or if alt-dragging + if (!sc->moved) { + item_in_group = desktop->item_at_point(NR::Point(event->button.x, event->button.y), TRUE); + group_at_point = desktop->group_at_point(NR::Point(event->button.x, event->button.y)); + // if neither a group nor an item (possibly in a group) at point are selected, set selection to the item at point + if ((!item_in_group || !selection->includes(item_in_group)) && + (!group_at_point || !selection->includes(group_at_point)) + && !sc->button_press_alt) { + // select what is under cursor + if (!seltrans->isEmpty()) { + seltrans->resetState(); + } + // when simply ctrl-dragging, we don't want to go into groups + if (item_at_point && !selection->includes(item_at_point)) + selection->set(item_at_point); + } // otherwise, do not change selection so that dragging selected-within-group items, as well as alt-dragging, is possible + seltrans->grab(p, -1, -1, FALSE); + sc->moved = TRUE; + } + if (!seltrans->isEmpty()) + seltrans->moveTo(p, event->button.state); + if (desktop->scroll_to_point(&p)) + // unfortunately in complex drawings, gobbling results in losing grab of the object, for some mysterious reason + ; //gobble_motion_events(GDK_BUTTON1_MASK); + ret = TRUE; + } else { + sc->dragging = FALSE; + } + } else { + Inkscape::Rubberband::get()->move(p); + gobble_motion_events(GDK_BUTTON1_MASK); + } + } + break; + case GDK_BUTTON_RELEASE: + xp = yp = 0; + if ((event->button.button == 1) && (sc->grabbed)) { + if (sc->dragging) { + if (sc->moved) { + // item has been moved + seltrans->ungrab(); + sc->moved = FALSE; + } else if (sc->item && !drag_escaped) { + // item has not been moved -> simply a click, do selecting + if (!selection->isEmpty()) { + if (event->button.state & GDK_SHIFT_MASK) { + // with shift, toggle selection + seltrans->resetState(); + selection->toggle(sc->item); + } else { + // without shift, increase state (i.e. toggle scale/rotation handles) + if (selection->includes(sc->item)) { + seltrans->increaseState(); + } else { + seltrans->resetState(); + selection->set(sc->item); + } + } + } else { // simple or shift click, no previous selection + seltrans->resetState(); + selection->set(sc->item); + } + } + sc->dragging = FALSE; + if (sc->item) { + sp_object_unref( SP_OBJECT(sc->item), NULL); + } + sc->item = NULL; + } else { + NR::Maybe const b = Inkscape::Rubberband::get()->getRectangle(); + if (b != NR::Nothing() && !within_tolerance) { + // this was a rubberband drag + Inkscape::Rubberband::get()->stop(); + seltrans->resetState(); + // find out affected items: + GSList *items = sp_document_items_in_box(SP_DT_DOCUMENT(desktop), desktop->dkey, b.assume()); + if (event->button.state & GDK_SHIFT_MASK) { + // with shift, add to selection + selection->addList (items); + } else { + // without shift, simply select anew + selection->setList (items); + } + g_slist_free (items); + } else { // it was just a click, or a too small rubberband + Inkscape::Rubberband::get()->stop(); + if (sc->button_press_shift && !rb_escaped && !drag_escaped) { + // this was a shift-click, select what was clicked upon + + sc->button_press_shift = false; + + if (sc->button_press_ctrl) { + // go into groups, honoring Alt + item = sp_event_context_find_item (desktop, + NR::Point(event->button.x, event->button.y), event->button.state & GDK_MOD1_MASK, TRUE); + sc->button_press_ctrl = FALSE; + } else { + // don't go into groups, honoring Alt + item = sp_event_context_find_item (desktop, + NR::Point(event->button.x, event->button.y), event->button.state & GDK_MOD1_MASK, FALSE); + } + + if (item) { + selection->toggle(item); + item = NULL; + } + + } else if (sc->button_press_ctrl && !rb_escaped && !drag_escaped) { // ctrl-click + + sc->button_press_ctrl = FALSE; + + item = sp_event_context_find_item (desktop, + NR::Point(event->button.x, event->button.y), event->button.state & GDK_MOD1_MASK, TRUE); + + if (item) { + if (selection->includes(item)) { + seltrans->increaseState(); + } else { + seltrans->resetState(); + selection->set(item); + } + item = NULL; + } + + } else { // click without shift, simply deselect, unless with Alt or something was cancelled + if (!selection->isEmpty()) { + if (!(rb_escaped) && !(drag_escaped) && !(event->button.state & GDK_MOD1_MASK)) + selection->clear(); + rb_escaped = 0; + ret = TRUE; + } + } + } + ret = TRUE; + } + if (sc->grabbed) { + sp_canvas_item_ungrab(sc->grabbed, event->button.time); + sc->grabbed = NULL; + } + } + sc->button_press_shift = false; + sc->button_press_ctrl = false; + sc->button_press_alt = false; + break; + + case GDK_KEY_PRESS: // keybindings for select context + + if (!key_is_a_modifier (get_group0_keyval (&event->key))) { + event_context->defaultMessageContext()->clear(); + } else { + sp_event_show_modifier_tip (event_context->defaultMessageContext(), event, + _("Ctrl: select in groups, move hor/vert"), + _("Shift: toggle select, force rubberband, disable snapping"), + _("Alt: select under, move selected")); + break; + } + + switch (get_group0_keyval (&event->key)) { + case GDK_Left: // move selection left + case GDK_KP_Left: + case GDK_KP_4: + if (!MOD__CTRL) { // not ctrl + if (MOD__ALT) { // alt + if (MOD__SHIFT) sp_selection_move_screen(-10, 0); // shift + else sp_selection_move_screen(-1, 0); // no shift + } + else { // no alt + if (MOD__SHIFT) sp_selection_move(-10*nudge, 0); // shift + else sp_selection_move(-nudge, 0); // no shift + } + ret = TRUE; + } + break; + case GDK_Up: // move selection up + case GDK_KP_Up: + case GDK_KP_8: + if (!MOD__CTRL) { // not ctrl + if (MOD__ALT) { // alt + if (MOD__SHIFT) sp_selection_move_screen(0, 10); // shift + else sp_selection_move_screen(0, 1); // no shift + } + else { // no alt + if (MOD__SHIFT) sp_selection_move(0, 10*nudge); // shift + else sp_selection_move(0, nudge); // no shift + } + ret = TRUE; + } + break; + case GDK_Right: // move selection right + case GDK_KP_Right: + case GDK_KP_6: + if (!MOD__CTRL) { // not ctrl + if (MOD__ALT) { // alt + if (MOD__SHIFT) sp_selection_move_screen(10, 0); // shift + else sp_selection_move_screen(1, 0); // no shift + } + else { // no alt + if (MOD__SHIFT) sp_selection_move(10*nudge, 0); // shift + else sp_selection_move(nudge, 0); // no shift + } + ret = TRUE; + } + break; + case GDK_Down: // move selection down + case GDK_KP_Down: + case GDK_KP_2: + if (!MOD__CTRL) { // not ctrl + if (MOD__ALT) { // alt + if (MOD__SHIFT) sp_selection_move_screen(0, -10); // shift + else sp_selection_move_screen(0, -1); // no shift + } + else { // no alt + if (MOD__SHIFT) sp_selection_move(0, -10*nudge); // shift + else sp_selection_move(0, -nudge); // no shift + } + ret = TRUE; + } + break; + case GDK_Escape: + if (!sp_select_context_abort(event_context)) + selection->clear(); + ret = TRUE; + break; + case GDK_a: + case GDK_A: + if (MOD__CTRL_ONLY) { + sp_edit_select_all(); + ret = TRUE; + } + break; + case GDK_Tab: // Tab - cycle selection forward + if (!(MOD__CTRL_ONLY || (MOD__CTRL && MOD__SHIFT))) { + sp_selection_item_next(); + ret = TRUE; + } + break; + case GDK_ISO_Left_Tab: // Shift Tab - cycle selection backward + if (!(MOD__CTRL_ONLY || (MOD__CTRL && MOD__SHIFT))) { + sp_selection_item_prev(); + ret = TRUE; + } + break; + case GDK_space: + /* stamping mode: show outline mode moving */ + /* FIXME: Is next condition ok? (lauris) */ + if (sc->dragging && sc->grabbed) { + seltrans->stamp(); + ret = TRUE; + } + break; + case GDK_x: + case GDK_X: + if (MOD__ALT_ONLY) { + desktop->setToolboxFocusTo ("altx"); + ret = TRUE; + } + break; + case GDK_bracketleft: + if (MOD__ALT) { + sp_selection_rotate_screen(selection, 1); + } else if (MOD__CTRL) { + sp_selection_rotate(selection, 90); + } else if (snaps) { + sp_selection_rotate(selection, 180/snaps); + } + ret = TRUE; + break; + case GDK_bracketright: + if (MOD__ALT) { + sp_selection_rotate_screen(selection, -1); + } else if (MOD__CTRL) { + sp_selection_rotate(selection, -90); + } else if (snaps) { + sp_selection_rotate(selection, -180/snaps); + } + ret = TRUE; + break; + case GDK_less: + case GDK_comma: + if (MOD__ALT) { + sp_selection_scale_screen(selection, -2); + } else if (MOD__CTRL) { + sp_selection_scale_times(selection, 0.5); + } else { + sp_selection_scale(selection, -offset); + } + ret = TRUE; + break; + case GDK_greater: + case GDK_period: + if (MOD__ALT) { + sp_selection_scale_screen(selection, 2); + } else if (MOD__CTRL) { + sp_selection_scale_times(selection, 2); + } else { + sp_selection_scale(selection, offset); + } + ret = TRUE; + break; + case GDK_Return: + if (MOD__CTRL_ONLY) { + if (selection->singleItem()) { + SPItem *clicked_item = selection->singleItem(); + if (SP_IS_GROUP (clicked_item)) { // enter group + desktop->setCurrentLayer(reinterpret_cast(clicked_item)); + SP_DT_SELECTION(desktop)->clear(); + } else { + SP_EVENT_CONTEXT(sc)->desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Selected object is not a group. Cannot enter.")); + } + } + ret = TRUE; + } + break; + case GDK_BackSpace: + if (MOD__CTRL_ONLY) { + sp_select_context_up_one_layer(desktop); + ret = TRUE; + } + break; + default: + break; + } + break; + case GDK_KEY_RELEASE: + if (key_is_a_modifier (get_group0_keyval (&event->key))) + event_context->defaultMessageContext()->clear(); + break; + default: + break; + } + + if (!ret) { + if (((SPEventContextClass *) parent_class)->root_handler) + ret = ((SPEventContextClass *) parent_class)->root_handler(event_context, event); + } + + return ret; +} + + +/* + 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 : diff --git a/src/select-context.h b/src/select-context.h new file mode 100644 index 000000000..b7e5748a0 --- /dev/null +++ b/src/select-context.h @@ -0,0 +1,52 @@ +#ifndef __SP_SELECT_CONTEXT_H__ +#define __SP_SELECT_CONTEXT_H__ + +/* + * Select tool + * + * Authors: + * Lauris Kaplinski + * + * Copyright (C) 1999-2002 authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "event-context.h" + +#define SP_TYPE_SELECT_CONTEXT (sp_select_context_get_type ()) +#define SP_SELECT_CONTEXT(obj) (GTK_CHECK_CAST ((obj), SP_TYPE_SELECT_CONTEXT, SPSelectContext)) +#define SP_SELECT_CONTEXT_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), SP_TYPE_SELECT_CONTEXT, SPSelectContextClass)) +#define SP_IS_SELECT_CONTEXT(obj) (GTK_CHECK_TYPE ((obj), SP_TYPE_SELECT_CONTEXT)) +#define SP_IS_SELECT_CONTEXT_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), SP_TYPE_SELECT_CONTEXT)) + +class SPSelectContext; +class SPSelectContextClass; + +namespace Inkscape { + class MessageContext; + class SelTrans; + class SelectionDescriber; +} + +struct SPSelectContext : public SPEventContext { + guint dragging : 1; + guint moved : 1; + bool button_press_shift; + bool button_press_ctrl; + bool button_press_alt; + SPItem *item; + SPCanvasItem *grabbed; + Inkscape::SelTrans *_seltrans; + Inkscape::SelectionDescriber *_describer; +}; + +struct SPSelectContextClass { + SPEventContextClass parent_class; +}; + +/* Standard Gtk function */ + +GtkType sp_select_context_get_type (void); + +#endif diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp new file mode 100644 index 000000000..ee64e87ec --- /dev/null +++ b/src/selection-chemistry.cpp @@ -0,0 +1,2217 @@ +#define __SP_SELECTION_CHEMISTRY_C__ + +/* + * Miscellanous operations on selected items + * + * Authors: + * Lauris Kaplinski + * Frank Felfe + * MenTaLguY + * bulia byak + * + * Copyright (C) 1999-2005 authors + * Copyright (C) 2001-2002 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include "svg/svg.h" +#include "inkscape.h" +#include "desktop.h" +#include "desktop-style.h" +#include "selection.h" +#include "tools-switch.h" +#include "desktop-handles.h" +#include "message-stack.h" +#include "sp-item-transform.h" +#include "sp-marker.h" +#include "sp-use.h" +#include "sp-textpath.h" +#include "sp-tspan.h" +#include "sp-flowtext.h" +#include "sp-flowregion.h" +#include "text-editing.h" +#include "text-context.h" +#include "dropper-context.h" +#include +#include "libnr/nr-matrix-rotate-ops.h" +#include "libnr/nr-matrix-translate-ops.h" +#include "libnr/nr-rotate-fns.h" +#include "libnr/nr-scale-ops.h" +#include "libnr/nr-scale-translate-ops.h" +#include "libnr/nr-translate-matrix-ops.h" +#include "libnr/nr-translate-scale-ops.h" +#include "xml/repr.h" +#include "style.h" +#include "document-private.h" +#include "sp-gradient.h" +#include "sp-gradient-reference.h" +#include "sp-linear-gradient-fns.h" +#include "sp-pattern.h" +#include "sp-radial-gradient-fns.h" +#include "sp-namedview.h" +#include "prefs-utils.h" +#include "sp-offset.h" +#include "file.h" +#include "layer-fns.h" +#include "context-fns.h" +using NR::X; +using NR::Y; + +#include "selection-chemistry.h" + +/* fixme: find a better place */ +GSList *clipboard = NULL; +GSList *defs_clipboard = NULL; +SPCSSAttr *style_clipboard = NULL; + +static void sp_copy_stuff_used_by_item(GSList **defs_clip, SPItem *item, const GSList *items); + +void sp_selection_copy_one (Inkscape::XML::Node *repr, NR::Matrix full_t, GSList **clip) +{ + Inkscape::XML::Node *copy = repr->duplicate(); + + // copy complete inherited style + SPCSSAttr *css = sp_repr_css_attr_inherited(repr, "style"); + sp_repr_css_set(copy, css, "style"); + sp_repr_css_attr_unref(css); + + // write the complete accummulated transform passed to us + // (we're dealing with unattached repr, so we write to its attr instead of using sp_item_set_transform) + gchar affinestr[80]; + if (sp_svg_transform_write(affinestr, 79, full_t)) { + copy->setAttribute("transform", affinestr); + } else { + copy->setAttribute("transform", NULL); + } + + *clip = g_slist_prepend(*clip, copy); +} + +void sp_selection_copy_impl (const GSList *items, GSList **clip, GSList **defs_clip, SPCSSAttr **style_clip) +{ + + // Copy stuff referenced by all items to defs_clip: + if (defs_clip) { + for (GSList *i = (GSList *) items; i != NULL; i = i->next) { + sp_copy_stuff_used_by_item (defs_clip, SP_ITEM (i->data), items); + } + *defs_clip = g_slist_reverse(*defs_clip); + } + + // Store style: + if (style_clip) { + SPItem *item = SP_ITEM (items->data); // take from the first selected item + *style_clip = take_style_from_item (item); + } + + if (clip) { + // Sort items: + GSList *sorted_items = g_slist_copy ((GSList *) items); + sorted_items = g_slist_sort((GSList *) sorted_items, (GCompareFunc) sp_object_compare_position); + + // Copy item reprs: + for (GSList *i = (GSList *) sorted_items; i != NULL; i = i->next) { + sp_selection_copy_one (SP_OBJECT_REPR (i->data), sp_item_i2doc_affine(SP_ITEM (i->data)), clip); + } + + *clip = g_slist_reverse(*clip); + g_slist_free ((GSList *) sorted_items); + } +} + +/** +Add gradients/patterns/markers referenced by copied objects to defs +*/ +void +paste_defs (GSList **defs_clip, SPDocument *doc) +{ + if (!defs_clip) + return; + + for (GSList *gl = *defs_clip; gl != NULL; gl = gl->next) { + SPDefs *defs= (SPDefs *) SP_DOCUMENT_DEFS(doc); + Inkscape::XML::Node *repr = (Inkscape::XML::Node *) gl->data; + gchar const *id = repr->attribute("id"); + if (!id || !doc->getObjectById(id)) { + Inkscape::XML::Node *copy = repr->duplicate(); + SP_OBJECT_REPR(defs)->addChild(copy, NULL); + Inkscape::GC::release(copy); + } + } +} + +GSList *sp_selection_paste_impl (SPDocument *document, SPObject *parent, GSList **clip, GSList **defs_clip) +{ + paste_defs (defs_clip, document); + + GSList *copied = NULL; + // add objects to document + for (GSList *l = *clip; l != NULL; l = l->next) { + Inkscape::XML::Node *repr = (Inkscape::XML::Node *) l->data; + Inkscape::XML::Node *copy = repr->duplicate(); + + // premultiply the item transform by the accumulated parent transform in the paste layer + NR::Matrix local = sp_item_i2doc_affine(SP_ITEM(parent)); + if (!local.test_identity()) { + gchar const *t_str = copy->attribute("transform"); + NR::Matrix item_t (NR::identity()); + if (t_str) + sp_svg_transform_read(t_str, &item_t); + item_t *= local.inverse(); + // (we're dealing with unattached repr, so we write to its attr instead of using sp_item_set_transform) + gchar affinestr[80]; + if (sp_svg_transform_write(affinestr, 79, item_t)) { + copy->setAttribute("transform", affinestr); + } else { + copy->setAttribute("transform", NULL); + } + } + + parent->appendChildRepr(copy); + copied = g_slist_prepend(copied, copy); + Inkscape::GC::release(copy); + } + return copied; +} + +void sp_selection_delete_impl(const GSList *items) +{ + for (const GSList *i = items ; i ; i = i->next ) { + sp_object_ref((SPObject *)i->data, NULL); + } + for (const GSList *i = items; i != NULL; i = i->next) { + SPItem *item = (SPItem *) i->data; + SP_OBJECT(item)->deleteObject(); + sp_object_unref((SPObject *)item, NULL); + } +} + + +void sp_selection_delete() +{ + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + if (desktop == NULL) { + return; + } + + if (tools_isactive (desktop, TOOLS_TEXT)) + if (sp_text_delete_selection(desktop->event_context)) { + sp_document_done(SP_DT_DOCUMENT(desktop)); + return; + } + + Inkscape::Selection *selection = SP_DT_SELECTION(desktop); + + // check if something is selected + if (selection->isEmpty()) { + desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Nothing was deleted.")); + return; + } + + const GSList *selected = g_slist_copy(const_cast(selection->itemList())); + selection->clear(); + sp_selection_delete_impl (selected); + g_slist_free ((GSList *) selected); + + /* a tool may have set up private information in it's selection context + * that depends on desktop items. I think the only sane way to deal with + * this currently is to reset the current tool, which will reset it's + * associated selection context. For example: deleting an object + * while moving it around the canvas. + */ + tools_switch ( desktop, tools_active ( desktop ) ); + + sp_document_done(SP_DT_DOCUMENT(desktop)); +} + +/* fixme: sequencing */ +void sp_selection_duplicate() +{ + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + if (desktop == NULL) + return; + + Inkscape::Selection *selection = SP_DT_SELECTION(desktop); + + // check if something is selected + if (selection->isEmpty()) { + desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select object(s) to duplicate.")); + return; + } + + GSList *reprs = g_slist_copy((GSList *) selection->reprList()); + + selection->clear(); + + // sorting items from different parents sorts each parent's subset without possibly mixing them, just what we need + reprs = g_slist_sort(reprs, (GCompareFunc) sp_repr_compare_position); + + GSList *newsel = NULL; + + while (reprs) { + Inkscape::XML::Node *parent = ((Inkscape::XML::Node *) reprs->data)->parent(); + Inkscape::XML::Node *copy = ((Inkscape::XML::Node *) reprs->data)->duplicate(); + + parent->appendChild(copy); + + newsel = g_slist_prepend(newsel, copy); + reprs = g_slist_remove(reprs, reprs->data); + Inkscape::GC::release(copy); + } + + sp_document_done(SP_DT_DOCUMENT(desktop)); + + selection->setReprList(newsel); + + g_slist_free(newsel); +} + +void sp_edit_clear_all() +{ + SPDesktop *dt = SP_ACTIVE_DESKTOP; + if (!dt) + return; + + SPDocument *doc = SP_DT_DOCUMENT(dt); + SP_DT_SELECTION(dt)->clear(); + + g_return_if_fail(SP_IS_GROUP(dt->currentLayer())); + GSList *items = sp_item_group_item_list(SP_GROUP(dt->currentLayer())); + + while (items) { + SP_OBJECT (items->data)->deleteObject(); + items = g_slist_remove(items, items->data); + } + + sp_document_done(doc); +} + +GSList * +get_all_items (GSList *list, SPObject *from, SPDesktop *desktop, bool onlyvisible, bool onlysensitive, const GSList *exclude) +{ + for (SPObject *child = sp_object_first_child(SP_OBJECT(from)) ; child != NULL; child = SP_OBJECT_NEXT(child) ) { + if (SP_IS_ITEM(child) && + !desktop->isLayer(SP_ITEM(child)) && + (!onlysensitive || !SP_ITEM(child)->isLocked()) && + (!onlyvisible || !desktop->itemIsHidden(SP_ITEM(child))) && + (!exclude || !g_slist_find ((GSList *) exclude, child)) + ) + { + list = g_slist_prepend (list, SP_ITEM(child)); + } + + if (SP_IS_ITEM(child) && desktop->isLayer(SP_ITEM(child))) { + list = get_all_items (list, child, desktop, onlyvisible, onlysensitive, exclude); + } + } + + return list; +} + +void sp_edit_select_all_full (bool force_all_layers, bool invert) +{ + SPDesktop *dt = SP_ACTIVE_DESKTOP; + if (!dt) + return; + + Inkscape::Selection *selection = SP_DT_SELECTION(dt); + + g_return_if_fail(SP_IS_GROUP(dt->currentLayer())); + + bool inlayer = prefs_get_int_attribute ("options.kbselection", "inlayer", 1); + bool onlyvisible = prefs_get_int_attribute ("options.kbselection", "onlyvisible", 1); + bool onlysensitive = prefs_get_int_attribute ("options.kbselection", "onlysensitive", 1); + + GSList *items = NULL; + + const GSList *exclude = NULL; + if (invert) { + exclude = selection->itemList(); + } + + if (inlayer && !force_all_layers) { + + if ( (onlysensitive && SP_ITEM(dt->currentLayer())->isLocked()) || + (onlyvisible && dt->itemIsHidden(SP_ITEM(dt->currentLayer()))) ) + return; + + GSList *all_items = sp_item_group_item_list(SP_GROUP(dt->currentLayer())); + + for (GSList *i = all_items; i; i = i->next) { + SPItem *item = SP_ITEM (i->data); + + if (item && (!onlysensitive || !item->isLocked())) { + if (!onlyvisible || !dt->itemIsHidden(item)) { + if (!dt->isLayer(item)) { + if (!invert || !g_slist_find ((GSList *) exclude, item)) { + items = g_slist_prepend (items, item); // leave it in the list + } + } + } + } + } + + g_slist_free (all_items); + + } else { + items = get_all_items (NULL, dt->currentRoot(), dt, onlyvisible, onlysensitive, exclude); + } + + selection->setList (items); + + if (items) { + g_slist_free (items); + } +} + +void sp_edit_select_all () +{ + sp_edit_select_all_full (false, false); +} + +void sp_edit_select_all_in_all_layers () +{ + sp_edit_select_all_full (true, false); +} + +void sp_edit_invert () +{ + sp_edit_select_all_full (false, true); +} + +void sp_edit_invert_in_all_layers () +{ + sp_edit_select_all_full (true, true); +} + +void sp_selection_group() +{ + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + if (desktop == NULL) + return; + + SPDocument *document = SP_DT_DOCUMENT (desktop); + + Inkscape::Selection *selection = SP_DT_SELECTION(desktop); + + // Check if something is selected. + if (selection->isEmpty()) { + desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select two or more objects to group.")); + return; + } + + GSList const *l = (GSList *) selection->reprList(); + + // Check if at least two objects are selected. + if (l->next == NULL) { + desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select at least two objects to group.")); + return; + } + + GSList *p = g_slist_copy((GSList *) l); + + selection->clear(); + + p = g_slist_sort(p, (GCompareFunc) sp_repr_compare_position); + + // Remember the position and parent of the topmost object. + gint topmost = ((Inkscape::XML::Node *) g_slist_last(p)->data)->position(); + Inkscape::XML::Node *topmost_parent = ((Inkscape::XML::Node *) g_slist_last(p)->data)->parent(); + + Inkscape::XML::Node *group = sp_repr_new("svg:g"); + + while (p) { + Inkscape::XML::Node *current = (Inkscape::XML::Node *) p->data; + + if (current->parent() == topmost_parent) { + Inkscape::XML::Node *spnew = current->duplicate(); + sp_repr_unparent(current); + group->appendChild(spnew); + Inkscape::GC::release(spnew); + topmost --; // only reduce count for those items deleted from topmost_parent + } else { // move it to topmost_parent first + GSList *temp_clip = NULL; + + // At this point, current may already have no item, due to its being a clone whose original is already moved away + // So we copy it artificially calculating the transform from its repr->attr("transform") and the parent transform + gchar const *t_str = current->attribute("transform"); + NR::Matrix item_t (NR::identity()); + if (t_str) + sp_svg_transform_read(t_str, &item_t); + item_t *= sp_item_i2doc_affine(SP_ITEM(document->getObjectByRepr(current->parent()))); + //FIXME: when moving both clone and original from a transformed group (either by + //grouping into another parent, or by cut/paste) the transform from the original's + //parent becomes embedded into original itself, and this affects its clones. Fix + //this by remembering the transform diffs we write to each item into an array and + //then, if this is clone, looking up its original in that array and pre-multiplying + //it by the inverse of that original's transform diff. + + sp_selection_copy_one (current, item_t, &temp_clip); + sp_repr_unparent(current); + + // paste into topmost_parent (temporarily) + GSList *copied = sp_selection_paste_impl (document, document->getObjectByRepr(topmost_parent), &temp_clip, NULL); + if (temp_clip) g_slist_free (temp_clip); + if (copied) { // if success, + // take pasted object (now in topmost_parent) + Inkscape::XML::Node *in_topmost = (Inkscape::XML::Node *) copied->data; + // make a copy + Inkscape::XML::Node *spnew = in_topmost->duplicate(); + // remove pasted + sp_repr_unparent(in_topmost); + // put its copy into group + group->appendChild(spnew); + Inkscape::GC::release(spnew); + g_slist_free (copied); + } + } + p = g_slist_remove(p, current); + } + + // Add the new group to the topmost members' parent + topmost_parent->appendChild(group); + + // Move to the position of the topmost, reduced by the number of items deleted from topmost_parent + group->setPosition(topmost + 1); + + sp_document_done(SP_DT_DOCUMENT(desktop)); + + selection->set(group); + Inkscape::GC::release(group); +} + +void sp_selection_ungroup() +{ + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + if (desktop == NULL) + return; + + Inkscape::Selection *selection = SP_DT_SELECTION(desktop); + + if (selection->isEmpty()) { + desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select a group to ungroup.")); + return; + } + + GSList *items = g_slist_copy((GSList *) selection->itemList()); + selection->clear(); + + // Get a copy of current selection. + GSList *new_select = NULL; + bool ungrouped = false; + for (GSList *i = items; + i != NULL; + i = i->next) + { + SPItem *group = (SPItem *) i->data; + + // when ungrouping cloned groups with their originals, some objects that were selected may no more exist due to unlinking + if (!SP_IS_OBJECT(group)) { + continue; + } + + /* We do not allow ungrouping etc. (lauris) */ + if (strcmp(SP_OBJECT_REPR(group)->name(), "svg:g") && strcmp(SP_OBJECT_REPR(group)->name(), "svg:switch")) { + // keep the non-group item in the new selection + selection->add(group); + continue; + } + + GSList *children = NULL; + /* This is not strictly required, but is nicer to rely on group ::destroy (lauris) */ + sp_item_group_ungroup(SP_GROUP(group), &children, false); + ungrouped = true; + // Add ungrouped items to the new selection. + new_select = g_slist_concat(new_select, children); + } + + if (new_select) { // Set new selection. + selection->addList(new_select); + g_slist_free(new_select); + } + if (!ungrouped) { + desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("No groups to ungroup in the selection.")); + } + + g_slist_free(items); + + sp_document_done(SP_DT_DOCUMENT(desktop)); +} + +static SPGroup * +sp_item_list_common_parent_group(const GSList *items) +{ + if (!items) { + return NULL; + } + SPObject *parent = SP_OBJECT_PARENT(items->data); + /* Strictly speaking this CAN happen, if user selects from XML editor */ + if (!SP_IS_GROUP(parent)) { + return NULL; + } + for (items = items->next; items; items = items->next) { + if (SP_OBJECT_PARENT(items->data) != parent) { + return NULL; + } + } + + return SP_GROUP(parent); +} + +/** Finds out the minimum common bbox of the selected items + */ +NR::Rect +enclose_items(const GSList *items) +{ + g_assert(items != NULL); + + NR::Rect r = sp_item_bbox_desktop((SPItem *) items->data); + + for (GSList *i = items->next; i; i = i->next) { + r = NR::Rect::union_bounds(r, sp_item_bbox_desktop((SPItem *) i->data)); + } + + return r; +} + +SPObject * +prev_sibling(SPObject *child) +{ + SPObject *parent = SP_OBJECT_PARENT(child); + if (!SP_IS_GROUP(parent)) { + return NULL; + } + for ( SPObject *i = sp_object_first_child(parent) ; i; i = SP_OBJECT_NEXT(i) ) { + if (i->next == child) + return i; + } + return NULL; +} + +void +sp_selection_raise() +{ + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + if (!desktop) + return; + + Inkscape::Selection *selection = SP_DT_SELECTION(desktop); + + GSList const *items = (GSList *) selection->itemList(); + if (!items) { + desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select object(s) to raise.")); + return; + } + + SPGroup const *group = sp_item_list_common_parent_group(items); + if (!group) { + desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("You cannot raise/lower objects from different groups or layers.")); + return; + } + + Inkscape::XML::Node *grepr = SP_OBJECT_REPR(group); + + /* construct reverse-ordered list of selected children */ + GSList *rev = g_slist_copy((GSList *) items); + rev = g_slist_sort(rev, (GCompareFunc) sp_item_repr_compare_position); + + // find out the common bbox of the selected items + NR::Rect selected = enclose_items(items); + + // for all objects in the selection (starting from top) + while (rev) { + SPObject *child = SP_OBJECT(rev->data); + // for each selected object, find the next sibling + for (SPObject *newref = child->next; newref; newref = newref->next) { + // if the sibling is an item AND overlaps our selection, + if (SP_IS_ITEM(newref) && selected.intersects(sp_item_bbox_desktop(SP_ITEM(newref)))) { + // AND if it's not one of our selected objects, + if (!g_slist_find((GSList *) items, newref)) { + // move the selected object after that sibling + grepr->changeOrder(SP_OBJECT_REPR(child), SP_OBJECT_REPR(newref)); + } + break; + } + } + rev = g_slist_remove(rev, child); + } + + sp_document_done(SP_DT_DOCUMENT(desktop)); +} + +void sp_selection_raise_to_top() +{ + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + if (desktop == NULL) + return; + + SPDocument *document = SP_DT_DOCUMENT(desktop); + Inkscape::Selection *selection = SP_DT_SELECTION(desktop); + + if (selection->isEmpty()) { + desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select object(s) to raise to top.")); + return; + } + + GSList const *items = (GSList *) selection->itemList(); + + SPGroup const *group = sp_item_list_common_parent_group(items); + if (!group) { + desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("You cannot raise/lower objects from different groups or layers.")); + return; + } + + GSList *rl = g_slist_copy((GSList *) selection->reprList()); + rl = g_slist_sort(rl, (GCompareFunc) sp_repr_compare_position); + + for (GSList *l = rl; l != NULL; l = l->next) { + Inkscape::XML::Node *repr = (Inkscape::XML::Node *) l->data; + repr->setPosition(-1); + } + + g_slist_free(rl); + + sp_document_done(document); +} + +void +sp_selection_lower() +{ + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + if (desktop == NULL) + return; + + Inkscape::Selection *selection = SP_DT_SELECTION(desktop); + + GSList const *items = (GSList *) selection->itemList(); + if (!items) { + desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select object(s) to lower.")); + return; + } + + SPGroup const *group = sp_item_list_common_parent_group(items); + if (!group) { + desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("You cannot raise/lower objects from different groups or layers.")); + return; + } + + Inkscape::XML::Node *grepr = SP_OBJECT_REPR(group); + + // find out the common bbox of the selected items + NR::Rect selected = enclose_items(items); + + /* construct direct-ordered list of selected children */ + GSList *rev = g_slist_copy((GSList *) items); + rev = g_slist_sort(rev, (GCompareFunc) sp_item_repr_compare_position); + rev = g_slist_reverse(rev); + + // for all objects in the selection (starting from top) + while (rev) { + SPObject *child = SP_OBJECT(rev->data); + // for each selected object, find the prev sibling + for (SPObject *newref = prev_sibling(child); newref; newref = prev_sibling(newref)) { + // if the sibling is an item AND overlaps our selection, + if (SP_IS_ITEM(newref) && selected.intersects(sp_item_bbox_desktop(SP_ITEM(newref)))) { + // AND if it's not one of our selected objects, + if (!g_slist_find((GSList *) items, newref)) { + // move the selected object before that sibling + SPObject *put_after = prev_sibling(newref); + if (put_after) + grepr->changeOrder(SP_OBJECT_REPR(child), SP_OBJECT_REPR(put_after)); + else + SP_OBJECT_REPR(child)->setPosition(0); + } + break; + } + } + rev = g_slist_remove(rev, child); + } + + sp_document_done(SP_DT_DOCUMENT(desktop)); + +} + +void sp_selection_lower_to_bottom() +{ + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + if (desktop == NULL) + return; + + SPDocument *document = SP_DT_DOCUMENT(desktop); + Inkscape::Selection *selection = SP_DT_SELECTION(desktop); + + if (selection->isEmpty()) { + desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select object(s) to lower to bottom.")); + return; + } + + GSList const *items = (GSList *) selection->itemList(); + + SPGroup const *group = sp_item_list_common_parent_group(items); + if (!group) { + desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("You cannot raise/lower objects from different groups or layers.")); + return; + } + + GSList *rl; + rl = g_slist_copy((GSList *) selection->reprList()); + rl = g_slist_sort(rl, (GCompareFunc) sp_repr_compare_position); + rl = g_slist_reverse(rl); + + for (GSList *l = rl; l != NULL; l = l->next) { + gint minpos; + SPObject *pp, *pc; + Inkscape::XML::Node *repr = (Inkscape::XML::Node *) l->data; + pp = document->getObjectByRepr(sp_repr_parent(repr)); + minpos = 0; + g_assert(SP_IS_GROUP(pp)); + pc = sp_object_first_child(pp); + while (!SP_IS_ITEM(pc)) { + minpos += 1; + pc = pc->next; + } + repr->setPosition(minpos); + } + + g_slist_free(rl); + + sp_document_done(document); +} + +void +sp_undo(SPDesktop *desktop, SPDocument *doc) +{ + if (!sp_document_undo(SP_DT_DOCUMENT(desktop))) + desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Nothing to undo.")); +} + +void +sp_redo(SPDesktop *desktop, SPDocument *doc) +{ + if (!sp_document_redo(SP_DT_DOCUMENT(desktop))) + desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Nothing to redo.")); +} + +void sp_selection_cut() +{ + sp_selection_copy(); + sp_selection_delete(); +} + +void sp_copy_gradient (GSList **defs_clip, SPGradient *gradient) +{ + SPGradient *ref = gradient; + + while (ref) { + // climb up the refs, copying each one in the chain + Inkscape::XML::Node *grad_repr = SP_OBJECT_REPR(ref)->duplicate(); + *defs_clip = g_slist_prepend (*defs_clip, grad_repr); + + ref = ref->ref->getObject(); + } +} + +void sp_copy_pattern (GSList **defs_clip, SPPattern *pattern) +{ + SPPattern *ref = pattern; + + while (ref) { + // climb up the refs, copying each one in the chain + Inkscape::XML::Node *pattern_repr = SP_OBJECT_REPR(ref)->duplicate(); + *defs_clip = g_slist_prepend (*defs_clip, pattern_repr); + + // items in the pattern may also use gradients and other patterns, so we need to recurse here as well + for (SPObject *child = sp_object_first_child(SP_OBJECT(ref)) ; child != NULL; child = SP_OBJECT_NEXT(child) ) { + if (!SP_IS_ITEM (child)) + continue; + sp_copy_stuff_used_by_item (defs_clip, (SPItem *) child, NULL); + } + + ref = ref->ref->getObject(); + } +} + +void sp_copy_marker (GSList **defs_clip, SPMarker *marker) +{ + Inkscape::XML::Node *marker_repr = SP_OBJECT_REPR(marker)->duplicate(); + *defs_clip = g_slist_prepend (*defs_clip, marker_repr); +} + + +void sp_copy_textpath_path (GSList **defs_clip, SPTextPath *tp, const GSList *items) +{ + SPItem *path = sp_textpath_get_path_item (tp); + if (!path) + return; + if (items && g_slist_find ((GSList *) items, path)) // do not copy it to defs if it is already in the list of items copied + return; + Inkscape::XML::Node *repr = SP_OBJECT_REPR(path)->duplicate(); + *defs_clip = g_slist_prepend (*defs_clip, repr); +} + +void sp_copy_stuff_used_by_item (GSList **defs_clip, SPItem *item, const GSList *items) +{ + SPStyle *style = SP_OBJECT_STYLE (item); + + if (style && (style->fill.type == SP_PAINT_TYPE_PAINTSERVER)) { + SPObject *server = SP_OBJECT_STYLE_FILL_SERVER(item); + if (SP_IS_LINEARGRADIENT (server) || SP_IS_RADIALGRADIENT (server)) + sp_copy_gradient (defs_clip, SP_GRADIENT(server)); + if (SP_IS_PATTERN (server)) + sp_copy_pattern (defs_clip, SP_PATTERN(server)); + } + + if (style && (style->stroke.type == SP_PAINT_TYPE_PAINTSERVER)) { + SPObject *server = SP_OBJECT_STYLE_STROKE_SERVER(item); + if (SP_IS_LINEARGRADIENT (server) || SP_IS_RADIALGRADIENT (server)) + sp_copy_gradient (defs_clip, SP_GRADIENT(server)); + if (SP_IS_PATTERN (server)) + sp_copy_pattern (defs_clip, SP_PATTERN(server)); + } + + if (SP_IS_SHAPE (item)) { + SPShape *shape = SP_SHAPE (item); + for (int i = 0 ; i < SP_MARKER_LOC_QTY ; i++) { + if (shape->marker[i]) { + sp_copy_marker (defs_clip, SP_MARKER (shape->marker[i])); + } + } + } + + if (SP_IS_TEXT_TEXTPATH (item)) { + sp_copy_textpath_path (defs_clip, SP_TEXTPATH(sp_object_first_child(SP_OBJECT(item))), items); + } + + // recurse + for (SPObject *o = SP_OBJECT(item)->children; o != NULL; o = o->next) { + if (SP_IS_ITEM(o)) + sp_copy_stuff_used_by_item (defs_clip, SP_ITEM (o), items); + } +} + +/** + * \pre item != NULL + */ +SPCSSAttr * +take_style_from_item (SPItem *item) +{ + // write the complete cascaded style, context-free + SPCSSAttr *css = sp_css_attr_from_object (SP_OBJECT(item), SP_STYLE_FLAG_ALWAYS); + if (css == NULL) + return NULL; + + if ((SP_IS_GROUP(item) && SP_OBJECT(item)->children) || + (SP_IS_TEXT (item) && SP_OBJECT(item)->children && SP_OBJECT(item)->children->next == NULL)) { + // if this is a text with exactly one tspan child, merge the style of that tspan as well + // If this is a group, merge the style of its topmost (last) child with style + for (SPObject *last_element = item->lastChild(); last_element != NULL; last_element = SP_OBJECT_PREV (last_element)) { + if (SP_OBJECT_STYLE (last_element) != NULL) { + SPCSSAttr *temp = sp_css_attr_from_object (last_element, SP_STYLE_FLAG_IFSET); + if (temp) { + sp_repr_css_merge (css, temp); + sp_repr_css_attr_unref (temp); + } + break; + } + } + } + if (!(SP_IS_TEXT (item) || SP_IS_TSPAN (item) || SP_IS_STRING (item))) { + // do not copy text properties from non-text objects, it's confusing + css = sp_css_attr_unset_text (css); + } + + // FIXME: also transform gradient/pattern fills, by forking? NO, this must be nondestructive + double ex = NR::expansion(sp_item_i2doc_affine(item)); + if (ex != 1.0) { + css = sp_css_attr_scale (css, ex); + } + + return css; +} + + +void sp_selection_copy() +{ + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + if (desktop == NULL) + return; + + Inkscape::Selection *selection = SP_DT_SELECTION(desktop); + + if (tools_isactive (desktop, TOOLS_DROPPER)) { + sp_dropper_context_copy(desktop->event_context); + return; // copied color under cursor, nothing else to do + } + + // check if something is selected + if (selection->isEmpty()) { + desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Nothing was copied.")); + return; + } + + const GSList *items = g_slist_copy ((GSList *) selection->itemList()); + + // 0. Copy text to system clipboard + // FIXME: for non-texts, put serialized XML as text to the clipboard; + //for this sp_repr_write_stream needs to be rewritten with iostream instead of FILE + Glib::ustring text; + if (tools_isactive (desktop, TOOLS_TEXT)) { + text = sp_text_get_selected_text(desktop->event_context); + } + + if (text.empty()) { + guint texts = 0; + for (GSList *i = (GSList *) items; i; i = i->next) { + SPItem *item = SP_ITEM (i->data); + if (SP_IS_TEXT (item) || SP_IS_FLOWTEXT(item)) { + if (texts > 0) // if more than one text object is copied, separate them by spaces + text += " "; + gchar *this_text = sp_te_get_string_multiline (item); + if (this_text) { + text += this_text; + g_free(this_text); + } + texts++; + } + } + } + if (!text.empty()) { + Glib::RefPtr refClipboard = Gtk::Clipboard::get(); + refClipboard->set_text(text); + } + + // clear old defs clipboard + while (defs_clipboard) { + Inkscape::GC::release((Inkscape::XML::Node *) defs_clipboard->data); + defs_clipboard = g_slist_remove (defs_clipboard, defs_clipboard->data); + } + + // clear style clipboard + if (style_clipboard) { + sp_repr_css_attr_unref (style_clipboard); + style_clipboard = NULL; + } + + //clear main clipboard + while (clipboard) { + Inkscape::GC::release((Inkscape::XML::Node *) clipboard->data); + clipboard = g_slist_remove(clipboard, clipboard->data); + } + + sp_selection_copy_impl (items, &clipboard, &defs_clipboard, &style_clipboard); + + if (tools_isactive (desktop, TOOLS_TEXT)) { // take style from cursor/text selection, overwriting the style just set by copy_impl + SPStyle *const query = sp_style_new(); + if (sp_desktop_query_style_all (desktop, query)) { + SPCSSAttr *css = sp_css_attr_from_style (query, SP_STYLE_FLAG_ALWAYS); + if (css != NULL) { + // clear style clipboard + if (style_clipboard) { + sp_repr_css_attr_unref (style_clipboard); + style_clipboard = NULL; + } + //sp_repr_css_print (css); + style_clipboard = css; + } + } + g_free (query); + } + + g_slist_free ((GSList *) items); +} + +void sp_selection_paste(bool in_place) +{ + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + + if (desktop == NULL) { + return; + } + + SPDocument *document = SP_DT_DOCUMENT(desktop); + + if (Inkscape::have_viable_layer(desktop, desktop->messageStack()) == false) { + return; + } + + Inkscape::Selection *selection = SP_DT_SELECTION(desktop); + + if (tools_isactive (desktop, TOOLS_TEXT)) { + if (sp_text_paste_inline(desktop->event_context)) + return; // pasted from system clipboard into text, nothing else to do + } + + // check if something is in the clipboard + if (clipboard == NULL) { + desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Nothing on the clipboard.")); + return; + } + + GSList *copied = sp_selection_paste_impl(document, desktop->currentLayer(), &clipboard, &defs_clipboard); + // add pasted objects to selection + selection->setReprList((GSList const *) copied); + g_slist_free (copied); + + if (!in_place) { + sp_document_ensure_up_to_date(document); + + NR::Point m( desktop->point() - selection->bounds().midpoint() ); + + /* Snap the offset of the new item(s) to the grid */ + /* FIXME: this gridsnap fiddling is a hack. */ + Inkscape::GridSnapper &s = desktop->namedview->grid_snapper; + gdouble const curr_gridsnap = s.getDistance(); + s.setDistance(NR_HUGE); + m = s.freeSnap(Inkscape::Snapper::SNAP_POINT, m, NULL).getPoint(); + s.setDistance(curr_gridsnap); + sp_selection_move_relative(selection, m); + } + + sp_document_done(document); +} + +void sp_selection_paste_style() +{ + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + if (desktop == NULL) return; + + Inkscape::Selection *selection = SP_DT_SELECTION(desktop); + + // check if something is in the clipboard + if (clipboard == NULL) { + desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Nothing on the clipboard.")); + return; + } + + // check if something is selected + if (selection->isEmpty()) { + desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select object(s) to paste style to.")); + return; + } + + paste_defs (&defs_clipboard, SP_DT_DOCUMENT(desktop)); + + sp_desktop_set_style (desktop, style_clipboard); + + sp_document_done(SP_DT_DOCUMENT (desktop)); +} + +void sp_selection_to_next_layer () +{ + SPDesktop *dt = SP_ACTIVE_DESKTOP; + + Inkscape::Selection *selection = SP_DT_SELECTION(dt); + + // check if something is selected + if (selection->isEmpty()) { + dt->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select object(s) to move to the layer above.")); + return; + } + + const GSList *items = g_slist_copy ((GSList *) selection->itemList()); + + SPObject *next=Inkscape::next_layer(dt->currentRoot(), dt->currentLayer()); + if (next) { + GSList *temp_clip = NULL; + sp_selection_copy_impl (items, &temp_clip, NULL, NULL); // we're in the same doc, so no need to copy defs + sp_selection_delete_impl (items); + GSList *copied = sp_selection_paste_impl (SP_DT_DOCUMENT (dt), next, &temp_clip, NULL); + selection->setReprList((GSList const *) copied); + g_slist_free (copied); + if (temp_clip) g_slist_free (temp_clip); + dt->setCurrentLayer(next); + sp_document_done(SP_DT_DOCUMENT (dt)); + } else { + dt->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("No more layers above.")); + } + + g_slist_free ((GSList *) items); +} + +void sp_selection_to_prev_layer () +{ + SPDesktop *dt = SP_ACTIVE_DESKTOP; + + Inkscape::Selection *selection = SP_DT_SELECTION(dt); + + // check if something is selected + if (selection->isEmpty()) { + dt->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select object(s) to move to the layer below.")); + return; + } + + const GSList *items = g_slist_copy ((GSList *) selection->itemList()); + + SPObject *next=Inkscape::previous_layer(dt->currentRoot(), dt->currentLayer()); + if (next) { + GSList *temp_clip = NULL; + sp_selection_copy_impl (items, &temp_clip, NULL, NULL); // we're in the same doc, so no need to copy defs + sp_selection_delete_impl (items); + GSList *copied = sp_selection_paste_impl (SP_DT_DOCUMENT (dt), next, &temp_clip, NULL); + selection->setReprList((GSList const *) copied); + g_slist_free (copied); + if (temp_clip) g_slist_free (temp_clip); + dt->setCurrentLayer(next); + sp_document_done(SP_DT_DOCUMENT (dt)); + } else { + dt->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("No more layers below.")); + } + + g_slist_free ((GSList *) items); +} + +void sp_selection_apply_affine(Inkscape::Selection *selection, NR::Matrix const &affine, bool set_i2d) +{ + if (selection->isEmpty()) + return; + + for (GSList const *l = selection->itemList(); l != NULL; l = l->next) { + SPItem *item = SP_ITEM(l->data); + +#if 0 /* Re-enable this once persistent guides have a graphical indication. + At the time of writing, this is the only place to re-enable. */ + sp_item_update_cns(*item, selection->desktop()); +#endif + + // we're moving both a clone and its original + bool transform_clone_with_original = (SP_IS_USE(item) && selection->includes( sp_use_get_original (SP_USE(item)) )); + bool transform_textpath_with_path = (SP_IS_TEXT_TEXTPATH(item) && selection->includes( sp_textpath_get_path_item (SP_TEXTPATH(sp_object_first_child(SP_OBJECT(item)))) )); + bool transform_flowtext_with_frame = (SP_IS_FLOWTEXT(item) && selection->includes( SP_FLOWTEXT(item)->get_frame (NULL))); // only the first frame so far + bool transform_offset_with_source = (SP_IS_OFFSET(item) && SP_OFFSET (item)->sourceHref) && selection->includes( sp_offset_get_source (SP_OFFSET(item)) ); + + // "clones are unmoved when original is moved" preference + int compensation = prefs_get_int_attribute("options.clonecompensation", "value", SP_CLONE_COMPENSATION_UNMOVED); + bool prefs_unmoved = (compensation == SP_CLONE_COMPENSATION_UNMOVED); + bool prefs_parallel = (compensation == SP_CLONE_COMPENSATION_PARALLEL); + + // If this is a clone and it's selected along with its original, do not move it; it will feel the + // transform of its original and respond to it itself. Without this, a clone is doubly + // transformed, very unintuitive. + // Same for textpath if we are also doing ANY transform to its path: do not touch textpath, + // letters cannot be squeezed or rotated anyway, they only refill the changed path. + // Same for linked offset if we are also moving its source: do not move it. + if (transform_textpath_with_path || transform_offset_with_source) { + // restore item->transform field from the repr, in case it was changed by seltrans + sp_object_read_attr (SP_OBJECT (item), "transform"); + + } else if (transform_flowtext_with_frame) { + // apply the inverse of the region's transform to the so that the flow remains + // the same (even though the output itself gets transformed) + for (SPObject *region = item->firstChild() ; region ; region = SP_OBJECT_NEXT(region)) { + if (!SP_IS_FLOWREGION(region) && !SP_IS_FLOWREGIONEXCLUDE(region)) + continue; + for (SPObject *use = region->firstChild() ; use ; use = SP_OBJECT_NEXT(use)) { + if (!SP_IS_USE(use)) continue; + sp_item_write_transform(SP_USE(use), SP_OBJECT_REPR(use), item->transform.inverse(), NULL); + } + } + } else if (transform_clone_with_original) { + // We are transforming a clone along with its original. The below matrix juggling is + // necessary to ensure that they transform as a whole, i.e. the clone's induced + // transform and its move compensation are both cancelled out. + + // restore item->transform field from the repr, in case it was changed by seltrans + sp_object_read_attr (SP_OBJECT (item), "transform"); + + // calculate the matrix we need to apply to the clone to cancel its induced transform from its original + NR::Matrix t = matrix_to_desktop (matrix_from_desktop (affine, item), item); + NR::Matrix t_inv = matrix_to_desktop (matrix_from_desktop (affine.inverse(), item), item); + NR::Matrix result = t_inv * item->transform * t; + + if ((prefs_parallel || prefs_unmoved) && affine.is_translation()) { + // we need to cancel out the move compensation, too + + // find out the clone move, same as in sp_use_move_compensate + NR::Matrix parent = sp_use_get_parent_transform (SP_USE(item)); + NR::Matrix clone_move = parent.inverse() * t * parent; + + if (prefs_parallel) { + NR::Matrix move = result * clone_move * t_inv; + sp_item_write_transform(item, SP_OBJECT_REPR(item), move, &move); + + } else if (prefs_unmoved) { + if (SP_IS_USE(sp_use_get_original(SP_USE(item)))) + clone_move = NR::identity(); + NR::Matrix move = result * clone_move; + sp_item_write_transform(item, SP_OBJECT_REPR(item), move, &move); + } + + } else { + // just apply the result + sp_item_write_transform(item, SP_OBJECT_REPR(item), result, &result); + } + + } else { + if (set_i2d) { + sp_item_set_i2d_affine(item, sp_item_i2d_affine(item) * affine); + } + sp_item_write_transform(item, SP_OBJECT_REPR(item), item->transform, NULL); + } + } +} + +void sp_selection_remove_transform() +{ + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + if (desktop == NULL) + return; + + Inkscape::Selection *selection = SP_DT_SELECTION(desktop); + + GSList const *l = (GSList *) selection->reprList(); + while (l != NULL) { + sp_repr_set_attr((Inkscape::XML::Node*)l->data, "transform", NULL); + l = l->next; + } + + sp_document_done(SP_DT_DOCUMENT(desktop)); +} + +void +sp_selection_scale_absolute(Inkscape::Selection *selection, + double const x0, double const x1, + double const y0, double const y1) +{ + if (selection->isEmpty()) + return; + + NR::Rect const bbox(selection->bounds()); + if (bbox.isEmpty()) { + return; + } + + NR::translate const p2o(-bbox.min()); + + NR::scale const newSize(x1 - x0, + y1 - y0); + NR::scale const scale( newSize / NR::scale(bbox.dimensions()) ); + NR::translate const o2n(x0, y0); + NR::Matrix const final( p2o * scale * o2n ); + + sp_selection_apply_affine(selection, final); +} + + +void sp_selection_scale_relative(Inkscape::Selection *selection, NR::Point const &align, NR::scale const &scale) +{ + if (selection->isEmpty()) + return; + + NR::Rect const bbox(selection->bounds()); + + if (bbox.isEmpty()) { + return; + } + + // FIXME: ARBITRARY LIMIT: don't try to scale above 1 Mpx, it won't display properly and will crash sooner or later anyway + if ( bbox.extent(NR::X) * scale[NR::X] > 1e6 || + bbox.extent(NR::Y) * scale[NR::Y] > 1e6 ) + { + return; + } + + NR::translate const n2d(-align); + NR::translate const d2n(align); + NR::Matrix const final( n2d * scale * d2n ); + sp_selection_apply_affine(selection, final); +} + +void +sp_selection_rotate_relative(Inkscape::Selection *selection, NR::Point const ¢er, gdouble const angle_degrees) +{ + NR::translate const d2n(center); + NR::translate const n2d(-center); + NR::rotate const rotate(rotate_degrees(angle_degrees)); + NR::Matrix const final( NR::Matrix(n2d) * rotate * d2n ); + sp_selection_apply_affine(selection, final); +} + +void +sp_selection_skew_relative(Inkscape::Selection *selection, NR::Point const &align, double dx, double dy) +{ + NR::translate const d2n(align); + NR::translate const n2d(-align); + NR::Matrix const skew(1, dy, + dx, 1, + 0, 0); + NR::Matrix const final( n2d * skew * d2n ); + sp_selection_apply_affine(selection, final); +} + +void sp_selection_move_relative(Inkscape::Selection *selection, NR::Point const &move) +{ + sp_selection_apply_affine(selection, NR::Matrix(NR::translate(move))); +} + +void sp_selection_move_relative(Inkscape::Selection *selection, double dx, double dy) +{ + sp_selection_apply_affine(selection, NR::Matrix(NR::translate(dx, dy))); +} + + +/** + * \brief sp_selection_rotate_90 + * + * This function rotates selected objects 90 degrees clockwise. + * + */ + +void sp_selection_rotate_90_cw() +{ + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + + Inkscape::Selection *selection = SP_DT_SELECTION(desktop); + + if (selection->isEmpty()) + return; + + GSList const *l = selection->itemList(); + NR::rotate const rot_neg_90(NR::Point(0, -1)); + for (GSList const *l2 = l ; l2 != NULL ; l2 = l2->next) { + SPItem *item = SP_ITEM(l2->data); + sp_item_rotate_rel(item, rot_neg_90); + } + + sp_document_done(SP_DT_DOCUMENT(desktop)); +} + + +/** + * \brief sp_selection_rotate_90_ccw + * + * This function rotates selected objects 90 degrees counter-clockwise. + * + */ + +void sp_selection_rotate_90_ccw() +{ + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + + Inkscape::Selection *selection = SP_DT_SELECTION(desktop); + + if (selection->isEmpty()) + return; + + GSList const *l = selection->itemList(); + NR::rotate const rot_neg_90(NR::Point(0, 1)); + for (GSList const *l2 = l ; l2 != NULL ; l2 = l2->next) { + SPItem *item = SP_ITEM(l2->data); + sp_item_rotate_rel(item, rot_neg_90); + } + + sp_document_done(SP_DT_DOCUMENT(desktop)); +} + +void +sp_selection_rotate(Inkscape::Selection *selection, gdouble const angle_degrees) +{ + if (selection->isEmpty()) + return; + + NR::Point const center(selection->bounds().midpoint()); + + sp_selection_rotate_relative(selection, center, angle_degrees); + + sp_document_maybe_done(SP_DT_DOCUMENT(selection->desktop()), + ( ( angle_degrees > 0 ) + ? "selector:rotate:ccw" + : "selector:rotate:cw" )); +} + +/** +\param angle the angle in "angular pixels", i.e. how many visible pixels must move the outermost point of the rotated object +*/ +void +sp_selection_rotate_screen(Inkscape::Selection *selection, gdouble angle) +{ + if (selection->isEmpty()) + return; + + NR::Rect const bbox(selection->bounds()); + NR::Point const center(bbox.midpoint()); + + gdouble const zoom = selection->desktop()->current_zoom(); + gdouble const zmove = angle / zoom; + gdouble const r = NR::L2(bbox.max() - center); + + gdouble const zangle = 180 * atan2(zmove, r) / M_PI; + + sp_selection_rotate_relative(selection, center, zangle); + + sp_document_maybe_done(SP_DT_DOCUMENT(selection->desktop()), + ( (angle > 0) + ? "selector:rotate:ccw" + : "selector:rotate:cw" )); +} + +void +sp_selection_scale(Inkscape::Selection *selection, gdouble grow) +{ + if (selection->isEmpty()) + return; + + NR::Rect const bbox(selection->bounds()); + NR::Point const center(bbox.midpoint()); + double const max_len = bbox.maxExtent(); + + // you can't scale "do nizhe pola" (below zero) + if ( max_len + grow <= 1e-3 ) { + return; + } + + double const times = 1.0 + grow / max_len; + sp_selection_scale_relative(selection, center, NR::scale(times, times)); + + sp_document_maybe_done(SP_DT_DOCUMENT(selection->desktop()), + ( (grow > 0) + ? "selector:scale:larger" + : "selector:scale:smaller" )); +} + +void +sp_selection_scale_screen(Inkscape::Selection *selection, gdouble grow_pixels) +{ + sp_selection_scale(selection, + grow_pixels / selection->desktop()->current_zoom()); +} + +void +sp_selection_scale_times(Inkscape::Selection *selection, gdouble times) +{ + if (selection->isEmpty()) + return; + + NR::Point const center(selection->bounds().midpoint()); + sp_selection_scale_relative(selection, center, NR::scale(times, times)); + sp_document_done(SP_DT_DOCUMENT(selection->desktop())); +} + +void +sp_selection_move(gdouble dx, gdouble dy) +{ + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + Inkscape::Selection *selection = SP_DT_SELECTION(desktop); + if (selection->isEmpty()) { + return; + } + + sp_selection_move_relative(selection, dx, dy); + + if (dx == 0) { + sp_document_maybe_done(SP_DT_DOCUMENT(desktop), "selector:move:vertical"); + } else if (dy == 0) { + sp_document_maybe_done(SP_DT_DOCUMENT(desktop), "selector:move:horizontal"); + } else { + sp_document_done(SP_DT_DOCUMENT(desktop)); + } +} + +void +sp_selection_move_screen(gdouble dx, gdouble dy) +{ + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + + Inkscape::Selection *selection = SP_DT_SELECTION(desktop); + if (selection->isEmpty()) { + return; + } + + // same as sp_selection_move but divide deltas by zoom factor + gdouble const zoom = desktop->current_zoom(); + gdouble const zdx = dx / zoom; + gdouble const zdy = dy / zoom; + sp_selection_move_relative(selection, zdx, zdy); + + if (dx == 0) { + sp_document_maybe_done(SP_DT_DOCUMENT(desktop), "selector:move:vertical"); + } else if (dy == 0) { + sp_document_maybe_done(SP_DT_DOCUMENT(desktop), "selector:move:horizontal"); + } else { + sp_document_done(SP_DT_DOCUMENT(desktop)); + } +} + +namespace { + +template +SPItem *next_item(SPDesktop *desktop, GSList *path, SPObject *root, + bool only_in_viewport, bool inlayer, bool onlyvisible, bool onlysensitive); + +template +SPItem *next_item_from_list(SPDesktop *desktop, GSList const *items, SPObject *root, + bool only_in_viewport, bool inlayer, bool onlyvisible, bool onlysensitive); + +struct Forward { + typedef SPObject *Iterator; + + static Iterator children(SPObject *o) { return sp_object_first_child(o); } + static Iterator siblings_after(SPObject *o) { return SP_OBJECT_NEXT(o); } + static void dispose(Iterator i) {} + + static SPObject *object(Iterator i) { return i; } + static Iterator next(Iterator i) { return SP_OBJECT_NEXT(i); } +}; + +struct Reverse { + typedef GSList *Iterator; + + static Iterator children(SPObject *o) { + return make_list(o->firstChild(), NULL); + } + static Iterator siblings_after(SPObject *o) { + return make_list(SP_OBJECT_PARENT(o)->firstChild(), o); + } + static void dispose(Iterator i) { + g_slist_free(i); + } + + static SPObject *object(Iterator i) { + return reinterpret_cast(i->data); + } + static Iterator next(Iterator i) { return i->next; } + +private: + static GSList *make_list(SPObject *object, SPObject *limit) { + GSList *list=NULL; + while ( object != limit ) { + list = g_slist_prepend(list, object); + object = SP_OBJECT_NEXT(object); + } + return list; + } +}; + +} + +void +sp_selection_item_next(void) +{ + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + g_return_if_fail(desktop != NULL); + Inkscape::Selection *selection = SP_DT_SELECTION(desktop); + + bool inlayer = prefs_get_int_attribute ("options.kbselection", "inlayer", 1); + bool onlyvisible = prefs_get_int_attribute ("options.kbselection", "onlyvisible", 1); + bool onlysensitive = prefs_get_int_attribute ("options.kbselection", "onlysensitive", 1); + + SPObject *root; + if (inlayer) { + root = desktop->currentLayer(); + } else { + root = desktop->currentRoot(); + } + + SPItem *item=next_item_from_list(desktop, selection->itemList(), root, SP_CYCLING == SP_CYCLE_VISIBLE, inlayer, onlyvisible, onlysensitive); + + if (item) { + selection->set(item); + if ( SP_CYCLING == SP_CYCLE_FOCUS ) { + scroll_to_show_item(desktop, item); + } + } +} + +void +sp_selection_item_prev(void) +{ + SPDocument *document = SP_ACTIVE_DOCUMENT; + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + g_return_if_fail(document != NULL); + g_return_if_fail(desktop != NULL); + Inkscape::Selection *selection = SP_DT_SELECTION(desktop); + + bool inlayer = prefs_get_int_attribute ("options.kbselection", "inlayer", 1); + bool onlyvisible = prefs_get_int_attribute ("options.kbselection", "onlyvisible", 1); + bool onlysensitive = prefs_get_int_attribute ("options.kbselection", "onlysensitive", 1); + + SPObject *root; + if (inlayer) { + root = desktop->currentLayer(); + } else { + root = desktop->currentRoot(); + } + + SPItem *item=next_item_from_list(desktop, selection->itemList(), root, SP_CYCLING == SP_CYCLE_VISIBLE, inlayer, onlyvisible, onlysensitive); + + if (item) { + selection->set(item); + if ( SP_CYCLING == SP_CYCLE_FOCUS ) { + scroll_to_show_item(desktop, item); + } + } +} + +namespace { + +template +SPItem *next_item_from_list(SPDesktop *desktop, GSList const *items, + SPObject *root, bool only_in_viewport, bool inlayer, bool onlyvisible, bool onlysensitive) +{ + SPObject *current=root; + while (items) { + SPItem *item=SP_ITEM(items->data); + if ( root->isAncestorOf(item) && + ( !only_in_viewport || desktop->isWithinViewport(item) ) ) + { + current = item; + break; + } + items = items->next; + } + + GSList *path=NULL; + while ( current != root ) { + path = g_slist_prepend(path, current); + current = SP_OBJECT_PARENT(current); + } + + SPItem *next; + // first, try from the current object + next = next_item(desktop, path, root, only_in_viewport, inlayer, onlyvisible, onlysensitive); + g_slist_free(path); + + if (!next) { // if we ran out of objects, start over at the root + next = next_item(desktop, NULL, root, only_in_viewport, inlayer, onlyvisible, onlysensitive); + } + + return next; +} + +template +SPItem *next_item(SPDesktop *desktop, GSList *path, SPObject *root, + bool only_in_viewport, bool inlayer, bool onlyvisible, bool onlysensitive) +{ + typename D::Iterator children; + typename D::Iterator iter; + + SPItem *found=NULL; + + if (path) { + SPObject *object=reinterpret_cast(path->data); + g_assert(SP_OBJECT_PARENT(object) == root); + if (desktop->isLayer(object)) { + found = next_item(desktop, path->next, object, only_in_viewport, inlayer, onlyvisible, onlysensitive); + } + iter = children = D::siblings_after(object); + } else { + iter = children = D::children(root); + } + + while ( iter && !found ) { + SPObject *object=D::object(iter); + if (desktop->isLayer(object)) { + if (!inlayer) { // recurse into sublayers + found = next_item(desktop, NULL, object, only_in_viewport, inlayer, onlyvisible, onlysensitive); + } + } else if ( SP_IS_ITEM(object) && + ( !only_in_viewport || desktop->isWithinViewport(SP_ITEM(object)) ) && + ( !onlyvisible || !desktop->itemIsHidden(SP_ITEM(object))) && + ( !onlysensitive || !SP_ITEM(object)->isLocked()) && + !desktop->isLayer(SP_ITEM(object)) ) + { + found = SP_ITEM(object); + } + iter = D::next(iter); + } + + D::dispose(children); + + return found; +} + +} + +/** + * If \a item is not entirely visible then adjust visible area to centre on the centre on of + * \a item. + */ +void scroll_to_show_item(SPDesktop *desktop, SPItem *item) +{ + NR::Rect dbox = desktop->get_display_area(); + NR::Rect sbox = sp_item_bbox_desktop(item); + + if (dbox.contains(sbox) == false) { + NR::Point const s_dt = sbox.midpoint(); + NR::Point const s_w = desktop->d2w(s_dt); + NR::Point const d_dt = dbox.midpoint(); + NR::Point const d_w = desktop->d2w(d_dt); + NR::Point const moved_w( d_w - s_w ); + gint const dx = (gint) moved_w[X]; + gint const dy = (gint) moved_w[Y]; + desktop->scroll_world(dx, dy); + } +} + + +void +sp_selection_clone() +{ + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + if (desktop == NULL) + return; + + Inkscape::Selection *selection = SP_DT_SELECTION(desktop); + + // check if something is selected + if (selection->isEmpty()) { + desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select an object to clone.")); + return; + } + + // Check if more than one object is selected. + if (g_slist_length((GSList *) selection->itemList()) > 1) { + desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("If you want to clone several objects, group them and clone the group.")); + return; + } + + Inkscape::XML::Node *sel_repr = SP_OBJECT_REPR(selection->singleItem()); + Inkscape::XML::Node *parent = sp_repr_parent(sel_repr); + + Inkscape::XML::Node *clone = sp_repr_new("svg:use"); + clone->setAttribute("x", "0"); + clone->setAttribute("y", "0"); + clone->setAttribute("xlink:href", g_strdup_printf("#%s", sel_repr->attribute("id"))); + + // add the new clone to the top of the original's parent + parent->appendChild(clone); + + sp_document_done(SP_DT_DOCUMENT(desktop)); + + selection->set(clone); + Inkscape::GC::release(clone); +} + +void +sp_selection_unlink() +{ + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + if (!desktop) + return; + + Inkscape::Selection *selection = SP_DT_SELECTION(desktop); + + if (selection->isEmpty()) { + desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select a clone to unlink.")); + return; + } + + // Get a copy of current selection. + GSList *new_select = NULL; + bool unlinked = false; + for (GSList *items = g_slist_copy((GSList *) selection->itemList()); + items != NULL; + items = items->next) + { + SPItem *use = (SPItem *) items->data; + + if (!SP_IS_USE(use)) { + // keep the non-yse item in the new selection + new_select = g_slist_prepend(new_select, use); + continue; + } + + SPItem *unlink = sp_use_unlink(SP_USE(use)); + unlinked = true; + // Add ungrouped items to the new selection. + new_select = g_slist_prepend(new_select, unlink); + } + + if (new_select) { // set new selection + selection->clear(); + selection->setList(new_select); + g_slist_free(new_select); + } + if (!unlinked) { + desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("No clones to unlink in the selection.")); + } + + sp_document_done(SP_DT_DOCUMENT(desktop)); +} + +void +sp_select_clone_original() +{ + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + if (desktop == NULL) + return; + + Inkscape::Selection *selection = SP_DT_SELECTION(desktop); + + SPItem *item = selection->singleItem(); + + const gchar *error = _("Select a clone to go to its original. Select a linked offset to go to its source. Select a text on path to go to the path. Select a flowed text to go to its frame."); + + // Check if other than two objects are selected + if (g_slist_length((GSList *) selection->itemList()) != 1 || !item) { + desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, error); + return; + } + + SPItem *original = NULL; + if (SP_IS_USE(item)) { + original = sp_use_get_original (SP_USE(item)); + } else if (SP_IS_OFFSET(item) && SP_OFFSET (item)->sourceHref) { + original = sp_offset_get_source (SP_OFFSET(item)); + } else if (SP_IS_TEXT_TEXTPATH(item)) { + original = sp_textpath_get_path_item (SP_TEXTPATH(sp_object_first_child(SP_OBJECT(item)))); + } else if (SP_IS_FLOWTEXT(item)) { + original = SP_FLOWTEXT(item)->get_frame (NULL); // first frame only + } else { // it's an object that we don't know what to do with + desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, error); + return; + } + + if (!original) { + desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("Cannot find the object to select (orphaned clone, offset, textpath, flowed text?)")); + return; + } + + for (SPObject *o = original; o && !SP_IS_ROOT(o); o = SP_OBJECT_PARENT (o)) { + if (SP_IS_DEFS (o)) { + desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("The object you're trying to select is not visible (it is in <defs>)")); + return; + } + } + + if (original) { + selection->clear(); + selection->set(original); + if (SP_CYCLING == SP_CYCLE_FOCUS) { + scroll_to_show_item(desktop, original); + } + } +} + +void +sp_selection_tile(bool apply) +{ + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + if (desktop == NULL) + return; + + SPDocument *document = SP_DT_DOCUMENT(desktop); + + Inkscape::Selection *selection = SP_DT_SELECTION(desktop); + + // check if something is selected + if (selection->isEmpty()) { + desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select object(s) to convert to pattern.")); + return; + } + + sp_document_ensure_up_to_date(document); + NR::Rect r = selection->bounds(); + if (r.isEmpty()) { + return; + } + + // calculate the transform to be applied to objects to move them to 0,0 + NR::Point move_p = NR::Point(0, sp_document_height(document)) - (r.min() + NR::Point (0, r.extent(NR::Y))); + move_p[NR::Y] = -move_p[NR::Y]; + NR::Matrix move = NR::Matrix (NR::translate (move_p)); + + GSList *items = g_slist_copy((GSList *) selection->itemList()); + + items = g_slist_sort (items, (GCompareFunc) sp_object_compare_position); + + // bottommost object, after sorting + SPObject *parent = SP_OBJECT_PARENT (items->data); + + // remember the position of the first item + gint pos = SP_OBJECT_REPR (items->data)->position(); + + // create a list of duplicates + GSList *repr_copies = NULL; + for (GSList *i = items; i != NULL; i = i->next) { + Inkscape::XML::Node *dup = (SP_OBJECT_REPR (i->data))->duplicate(); + repr_copies = g_slist_prepend (repr_copies, dup); + } + + NR::Rect bounds(desktop->dt2doc(r.min()), desktop->dt2doc(r.max())); + + if (apply) { + // delete objects so that their clones don't get alerted; this object will be restored shortly + for (GSList *i = items; i != NULL; i = i->next) { + SPObject *item = SP_OBJECT (i->data); + item->deleteObject (false); + } + } + + // Hack: Temporarily set clone compensation to unmoved, so that we can move clone-originals + // without disturbing clones. + // See ActorAlign::on_button_click() in src/ui/dialog/align-and-distribute.cpp + int saved_compensation = prefs_get_int_attribute("options.clonecompensation", "value", SP_CLONE_COMPENSATION_UNMOVED); + prefs_set_int_attribute("options.clonecompensation", "value", SP_CLONE_COMPENSATION_UNMOVED); + + const gchar *pat_id = pattern_tile (repr_copies, bounds, document, + NR::Matrix(NR::translate(desktop->dt2doc(NR::Point(r.min()[NR::X], r.max()[NR::Y])))), move); + + // restore compensation setting + prefs_set_int_attribute("options.clonecompensation", "value", saved_compensation); + + if (apply) { + Inkscape::XML::Node *rect = sp_repr_new ("svg:rect"); + rect->setAttribute("style", g_strdup_printf("stroke:none;fill:url(#%s)", pat_id)); + sp_repr_set_svg_double(rect, "width", bounds.extent(NR::X)); + sp_repr_set_svg_double(rect, "height", bounds.extent(NR::Y)); + sp_repr_set_svg_double(rect, "x", bounds.min()[NR::X]); + sp_repr_set_svg_double(rect, "y", bounds.min()[NR::Y]); + + // restore parent and position + SP_OBJECT_REPR (parent)->appendChild(rect); + rect->setPosition(pos > 0 ? pos : 0); + SPItem *rectangle = (SPItem *) SP_DT_DOCUMENT (desktop)->getObjectByRepr(rect); + + Inkscape::GC::release(rect); + + selection->clear(); + selection->set(rectangle); + } + + g_slist_free (items); + + sp_document_done (document); +} + +void +sp_selection_untile() +{ + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + if (desktop == NULL) + return; + + SPDocument *document = SP_DT_DOCUMENT(desktop); + + Inkscape::Selection *selection = SP_DT_SELECTION(desktop); + + // check if something is selected + if (selection->isEmpty()) { + desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select an object with pattern fill to extract objects from.")); + return; + } + + GSList *new_select = NULL; + + bool did = false; + + for (GSList *items = g_slist_copy((GSList *) selection->itemList()); + items != NULL; + items = items->next) { + + SPItem *item = (SPItem *) items->data; + + SPStyle *style = SP_OBJECT_STYLE (item); + + if (!style || style->fill.type != SP_PAINT_TYPE_PAINTSERVER) + continue; + + SPObject *server = SP_OBJECT_STYLE_FILL_SERVER(item); + + if (!SP_IS_PATTERN(server)) + continue; + + did = true; + + SPPattern *pattern = pattern_getroot (SP_PATTERN (server)); + + NR::Matrix pat_transform = pattern_patternTransform (SP_PATTERN (server)); + pat_transform *= item->transform; + + for (SPObject *child = sp_object_first_child(SP_OBJECT(pattern)) ; child != NULL; child = SP_OBJECT_NEXT(child) ) { + Inkscape::XML::Node *copy = SP_OBJECT_REPR(child)->duplicate(); + SPItem *i = SP_ITEM (desktop->currentLayer()->appendChildRepr(copy)); + + // FIXME: relink clones to the new canvas objects + // use SPObject::setid when mental finishes it to steal ids of + + // this is needed to make sure the new item has curve (simply requestDisplayUpdate does not work) + sp_document_ensure_up_to_date (document); + + NR::Matrix transform( i->transform * pat_transform ); + sp_item_write_transform(i, SP_OBJECT_REPR(i), transform); + + new_select = g_slist_prepend(new_select, i); + } + + SPCSSAttr *css = sp_repr_css_attr_new (); + sp_repr_css_set_property (css, "fill", "none"); + sp_repr_css_change (SP_OBJECT_REPR (item), css, "style"); + } + + if (!did) { + desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("No pattern fills in the selection.")); + } else { + sp_document_done(SP_DT_DOCUMENT(desktop)); + selection->setList(new_select); + } +} + +void +sp_selection_create_bitmap_copy () +{ + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + if (desktop == NULL) + return; + + SPDocument *document = SP_DT_DOCUMENT(desktop); + + Inkscape::Selection *selection = SP_DT_SELECTION(desktop); + + // check if something is selected + if (selection->isEmpty()) { + desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select object(s) to make a bitmap copy.")); + return; + } + + // Get the bounding box of the selection + NRRect bbox; + sp_document_ensure_up_to_date (document); + selection->bounds(&bbox); + if (NR_RECT_DFLS_TEST_EMPTY(&bbox)) { + return; // exceptional situation, so not bother with a translatable error message, just quit quietly + } + + // List of the items to show; all others will be hidden + GSList *items = g_slist_copy ((GSList *) selection->itemList()); + + // Sort items so that the topmost comes last + items = g_slist_sort(items, (GCompareFunc) sp_item_repr_compare_position); + + // Generate a random value from the current time (you may create bitmap from the same object(s) + // multiple times, and this is done so that they don't clash) + GTimeVal cu; + g_get_current_time (&cu); + guint current = (int) (cu.tv_sec * 1000000 + cu.tv_usec) % 1024; + + // Create the filename + gchar *filename = g_strdup_printf ("%s-%s-%u.png", document->name, SP_OBJECT_REPR(items->data)->attribute("id"), current); + // Imagemagick is known not to handle spaces in filenames, so we replace anything but letters, + // digits, and a few other chars, with "_" + filename = g_strcanon (filename, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.=+~$#@^&!?", '_'); + // Build the complete path by adding document->base if set + gchar *filepath = g_build_filename (document->base?document->base:"", filename, NULL); + + //g_print ("%s\n", filepath); + + // Remember parent and z-order of the topmost one + gint pos = SP_OBJECT_REPR(g_slist_last(items)->data)->position(); + SPObject *parent_object = SP_OBJECT_PARENT(g_slist_last(items)->data); + Inkscape::XML::Node *parent = SP_OBJECT_REPR(parent_object); + + // Calculate resolution + double res; + int const prefs_res = prefs_get_int_attribute ("options.createbitmap", "resolution", 0); + if (0 < prefs_res) { + // If it's given explicitly in prefs, take it + res = prefs_res; + } else { + // Otherwise look up minimum bitmap size (default 250 pixels) and calculate resolution from it + int const prefs_min = prefs_get_int_attribute ("options.createbitmap", "minsize", 250); + res = prefs_min / MIN ((bbox.x1 - bbox.x0), (bbox.y1 - bbox.y0)); + } + + // The width and height of the bitmap in pixels + unsigned width = (unsigned) floor ((bbox.x1 - bbox.x0) * res); + unsigned height =(unsigned) floor ((bbox.y1 - bbox.y0) * res); + + // Find out if we have to run a filter + const gchar *run = NULL; + const gchar *filter = prefs_get_string_attribute ("options.createbitmap", "filter"); + if (filter) { + // filter command is given; + // see if we have a parameter to pass to it + const gchar *param1 = prefs_get_string_attribute ("options.createbitmap", "filter_param1"); + if (param1) { + if (param1[strlen(param1) - 1] == '%') { + // if the param string ends with %, interpret it as a percentage of the image's max dimension + gchar p1[256]; + g_ascii_dtostr (p1, 256, ceil (g_ascii_strtod (param1, NULL) * MAX(width, height) / 100)); + // the first param is always the image filename, the second is param1 + run = g_strdup_printf ("%s \"%s\" %s", filter, filepath, p1); + } else { + // otherwise pass the param1 unchanged + run = g_strdup_printf ("%s \"%s\" %s", filter, filepath, param1); + } + } else { + // run without extra parameter + run = g_strdup_printf ("%s \"%s\"", filter, filepath); + } + } + + // Calculate the matrix that will be applied to the image so that it exactly overlaps the source objects + NR::Matrix eek = sp_item_i2d_affine (SP_ITEM(parent_object)); + NR::Matrix t = NR::scale (1/res, -1/res) * NR::translate (bbox.x0, bbox.y1) * eek.inverse(); + + // Do the export + sp_export_png_file(document, filepath, + bbox.x0, bbox.y0, bbox.x1, bbox.y1, + width, height, + (guint32) 0xffffff00, + NULL, NULL, + true, /*bool force_overwrite,*/ + items); + + g_slist_free (items); + + // Run filter, if any + if (run) { + g_print ("Running external filter: %s\n", run); + system (run); + } + + // Import the image back + GdkPixbuf *pb = gdk_pixbuf_new_from_file (filepath, NULL); + if (pb) { + // Create the repr for the image + Inkscape::XML::Node * repr = sp_repr_new ("svg:image"); + repr->setAttribute("xlink:href", filename); + repr->setAttribute("sodipodi:absref", filepath); + sp_repr_set_svg_double(repr, "width", gdk_pixbuf_get_width(pb)); + sp_repr_set_svg_double(repr, "height", gdk_pixbuf_get_height(pb)); + + // Write transform + gchar c[256]; + if (sp_svg_transform_write(c, 256, t)) { + repr->setAttribute("transform", c); + } + + // add the new repr to the parent + parent->appendChild(repr); + + // move to the saved position + repr->setPosition(pos > 0 ? pos + 1 : 1); + + // Set selection to the new image + selection->clear(); + selection->add(repr); + + // Clean up + Inkscape::GC::release(repr); + gdk_pixbuf_unref (pb); + + // Complete undoable transaction + sp_document_done (document); + } + + g_free (filename); + g_free (filepath); +} + + +/* + 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 : diff --git a/src/selection-chemistry.h b/src/selection-chemistry.h new file mode 100644 index 000000000..9fbeaa9ec --- /dev/null +++ b/src/selection-chemistry.h @@ -0,0 +1,108 @@ +#ifndef __SP_SELECTION_CHEMISTRY_H__ +#define __SP_SELECTION_CHEMISTRY_H__ + +/* + * Miscellanous operations on selected items + * + * Authors: + * Lauris Kaplinski + * Frank Felfe + * bulia byak + * + * Copyright (C) 1999-2005 authors + * Copyright (C) 2001-2002 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "forward.h" +#include "libnr/nr-forward.h" + +namespace Inkscape { class Selection; } + +class SPCSSAttr; + +void sp_selection_delete(); +void sp_selection_duplicate(); +void sp_edit_clear_all(); + +void sp_edit_select_all(); +void sp_edit_select_all_in_all_layers (); +void sp_edit_invert (); +void sp_edit_invert_in_all_layers (); + +void sp_selection_clone(); +void sp_selection_unlink(); +void sp_select_clone_original (); + +void sp_selection_tile(bool apply = true); +void sp_selection_untile(); + +void sp_selection_group(); +void sp_selection_ungroup(); + +void sp_selection_raise(); +void sp_selection_raise_to_top(); +void sp_selection_lower(); +void sp_selection_lower_to_bottom(); + +SPCSSAttr *take_style_from_item (SPItem *item); + +void sp_selection_cut(); +void sp_selection_copy(); +void sp_selection_paste(bool in_place); +void sp_selection_paste_style(); + +void sp_selection_to_next_layer (); +void sp_selection_to_prev_layer (); + +void sp_selection_apply_affine(Inkscape::Selection *selection, NR::Matrix const &affine, bool set_i2d = true); +void sp_selection_remove_transform (void); +void sp_selection_scale_absolute (Inkscape::Selection *selection, double x0, double x1, double y0, double y1); +void sp_selection_scale_relative(Inkscape::Selection *selection, NR::Point const &align, NR::scale const &scale); +void sp_selection_rotate_relative (Inkscape::Selection *selection, NR::Point const ¢er, gdouble angle); +void sp_selection_skew_relative (Inkscape::Selection *selection, NR::Point const &align, double dx, double dy); +void sp_selection_move_relative (Inkscape::Selection *selection, NR::Point const &move); +void sp_selection_move_relative (Inkscape::Selection *selection, double dx, double dy); + +void sp_selection_rotate_90_cw (void); +void sp_selection_rotate_90_ccw (void); +void sp_selection_rotate (Inkscape::Selection *selection, gdouble angle); +void sp_selection_rotate_screen (Inkscape::Selection *selection, gdouble angle); + +void sp_selection_scale (Inkscape::Selection *selection, gdouble grow); +void sp_selection_scale_screen (Inkscape::Selection *selection, gdouble grow_pixels); +void sp_selection_scale_times (Inkscape::Selection *selection, gdouble times); + +void sp_selection_move (gdouble dx, gdouble dy); +void sp_selection_move_screen (gdouble dx, gdouble dy); + +void sp_selection_item_next (void); +void sp_selection_item_prev (void); + +void scroll_to_show_item(SPDesktop *desktop, SPItem *item); + +void sp_undo (SPDesktop *desktop, SPDocument *doc); +void sp_redo (SPDesktop *desktop, SPDocument *doc); + +void sp_selection_create_bitmap_copy (); + +/* selection cycling */ + +typedef enum +{ + SP_CYCLE_SIMPLE, + SP_CYCLE_VISIBLE, /* cycle only visible items */ + SP_CYCLE_FOCUS /* readjust visible area to view selected item */ +} SPCycleType; + +/* fixme: This should be moved into preference repr */ +#ifndef __SP_SELECTION_CHEMISTRY_C__ +extern SPCycleType SP_CYCLING; +#else +SPCycleType SP_CYCLING = SP_CYCLE_FOCUS; +#endif + +#endif + + diff --git a/src/selection-describer.cpp b/src/selection-describer.cpp new file mode 100644 index 000000000..9d484b293 --- /dev/null +++ b/src/selection-describer.cpp @@ -0,0 +1,121 @@ +/* + * Inkscape::SelectionDescriber - shows messages describing selection + * + * Authors: + * MenTaLguY + * bulia byak + * + * Copyright (C) 2004 MenTaLguY + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include "xml/quote.h" +#include "selection.h" +#include "selection-describer.h" +#include "desktop.h" +#include "sp-textpath.h" +#include "sp-offset.h" +#include "sp-flowtext.h" +#include "sp-use.h" + +namespace Inkscape { + +SelectionDescriber::SelectionDescriber(Inkscape::Selection *selection, MessageStack *stack) +: _context(stack) +{ + selection->connectChanged(sigc::mem_fun(*this, &SelectionDescriber::_updateMessageFromSelection)); + _updateMessageFromSelection(selection); +} + +void SelectionDescriber::_updateMessageFromSelection(Inkscape::Selection *selection) { + GSList const *items = selection->itemList(); + + char const *when_selected = _("Click selection to toggle scale/rotation handles"); + if (!items) { // no items + _context.set(Inkscape::NORMAL_MESSAGE, _("No objects selected. Click, Shift+click, or drag around objects to select.")); + } else { + SPItem *item = SP_ITEM(items->data); + SPObject *layer = selection->desktop()->layerForObject (SP_OBJECT (item)); + SPObject *root = selection->desktop()->currentRoot(); + gchar *layer_phrase; + if (layer == root) { + layer_phrase = g_strdup(""); // for simplicity + } else { + char const *name, *fmt; + if (layer && layer->label()) { + name = layer->label(); + fmt = _(" in layer %s"); + } else { + name = layer->defaultLabel(); + fmt = _(" in layer %s"); + } + char *quoted_name = xml_quote_strdup(name); + layer_phrase = g_strdup_printf(fmt, quoted_name); + g_free(quoted_name); + } + + if (!items->next) { // one item + char *item_desc = sp_item_description(item); + if (SP_IS_USE(item) || (SP_IS_OFFSET(item) && SP_OFFSET (item)->sourceHref)) { + _context.setF(Inkscape::NORMAL_MESSAGE, "%s%s. %s. %s.", + item_desc, layer_phrase, + _("Use Shift+D to look up original"), when_selected); + } else if (SP_IS_TEXT_TEXTPATH(item)) { + _context.setF(Inkscape::NORMAL_MESSAGE, "%s%s. %s. %s.", + item_desc, layer_phrase, + _("Use Shift+D to look up path"), when_selected); + } else if (SP_IS_FLOWTEXT(item) && !SP_FLOWTEXT(item)->has_internal_frame()) { + _context.setF(Inkscape::NORMAL_MESSAGE, "%s%s. %s. %s.", + item_desc, layer_phrase, + _("Use Shift+D to look up frame"), when_selected); + } else { + _context.setF(Inkscape::NORMAL_MESSAGE, "%s%s. %s.", + item_desc, layer_phrase, when_selected); + } + g_free(item_desc); + } else { // multiple items + int object_count = g_slist_length((GSList *)items); + const gchar *object_count_str = NULL; + object_count_str = g_strdup_printf ( + ngettext("%i object selected", + "%i objects selected", + object_count), + object_count); + + if (selection->numberOfLayers() == 1) { + _context.setF(Inkscape::NORMAL_MESSAGE, _("%s%s. %s."), + object_count_str, layer_phrase, when_selected); + } else { + _context.setF(Inkscape::NORMAL_MESSAGE, + ngettext("%s in %i layer. %s.", + "%s in %i layers. %s.", + selection->numberOfLayers()), + object_count_str, selection->numberOfLayers(), when_selected); + } + + if (object_count_str) + g_free ((gchar *) object_count_str); + } + + g_free(layer_phrase); + } +} + +} + +/* + 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:textwidth=99 : diff --git a/src/selection-describer.h b/src/selection-describer.h new file mode 100644 index 000000000..cd892bd14 --- /dev/null +++ b/src/selection-describer.h @@ -0,0 +1,46 @@ +/* + * Inkscape::SelectionDescriber - shows messages describing selection + * + * Authors: + * MenTaLguY + * + * Copyright (C) 2004 MenTaLguY + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifndef SEEN_INKSCAPE_SELECTION_DESCRIPTION_HANDLER_H +#define SEEN_INKSCAPE_SELECTION_DESCRIPTION_HANDLER_H + +#include +#include "message-context.h" + +namespace Inkscape { class Selection; } + +namespace Inkscape { + +class MessageStack; + +class SelectionDescriber : public sigc::trackable { +public: + SelectionDescriber(Inkscape::Selection *selection, MessageStack *stack); + +private: + void _updateMessageFromSelection(Inkscape::Selection *selection); + + MessageContext _context; +}; + +} + +#endif +/* + 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:textwidth=99 : diff --git a/src/selection.cpp b/src/selection.cpp new file mode 100644 index 000000000..4c99885eb --- /dev/null +++ b/src/selection.cpp @@ -0,0 +1,450 @@ +/** \file + * Per-desktop selection container + * + * Authors: + * Lauris Kaplinski + * MenTaLguY + * bulia byak + * + * Copyright (C) 2004-2005 MenTaLguY + * Copyright (C) 1999-2002 Lauris Kaplinski + * Copyright (C) 2001-2002 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifdef HAVE_CONFIG_H +# include +#endif +#include "macros.h" +#include "inkscape-private.h" +#include "desktop.h" +#include "desktop-handles.h" +#include "document.h" +#include "selection.h" +#include "xml/repr.h" + +#include "sp-shape.h" + + +#define SP_SELECTION_UPDATE_PRIORITY (G_PRIORITY_HIGH_IDLE + 1) + +namespace Inkscape { + +Selection::Selection(SPDesktop *desktop) : + _objs(NULL), + _reprs(NULL), + _items(NULL), + _desktop(desktop), + _flags(0), + _idle(0) +{ + clearOnceInaccessible(&_desktop); +} + +Selection::~Selection() { + _clear(); + _desktop = NULL; + if (_idle) { + g_source_remove(_idle); + _idle = 0; + } +} + +void +Selection::_release(SPObject *obj, Selection *selection) +{ + selection->remove(obj); +} + +/* Handler for selected objects "modified" signal */ + +void +Selection::_schedule_modified(SPObject *obj, guint flags, Selection *selection) +{ + if (!selection->_idle) { + /* Request handling to be run in _idle loop */ + selection->_idle = g_idle_add_full(SP_SELECTION_UPDATE_PRIORITY, GSourceFunc(&Selection::_emit_modified), selection, NULL); + } + + /* Collect all flags */ + selection->_flags |= flags; +} + +gboolean +Selection::_emit_modified(Selection *selection) +{ + /* force new handler to be created if requested before we return */ + selection->_idle = 0; + guint flags = selection->_flags; + selection->_flags = 0; + + selection->_emitModified(flags); + + /* drop this handler */ + return FALSE; +} + +void Selection::_emitModified(guint flags) { + inkscape_selection_modified(this, flags); + _modified_signal.emit(this, flags); +} + +void Selection::_emitChanged() { + inkscape_selection_changed(this); + _changed_signal.emit(this); +} + +void Selection::_invalidateCachedLists() { + g_slist_free(_items); + _items = NULL; + + g_slist_free(_reprs); + _reprs = NULL; +} + +void Selection::_clear() { + _invalidateCachedLists(); + while (_objs) { + SPObject *obj=reinterpret_cast(_objs->data); + sp_signal_disconnect_by_data(obj, this); + _objs = g_slist_remove(_objs, obj); + } +} + +bool Selection::includes(SPObject *obj) const { + if (obj == NULL) + return FALSE; + + g_return_val_if_fail(SP_IS_OBJECT(obj), FALSE); + + return ( g_slist_find(_objs, obj) != NULL ); +} + +void Selection::add(SPObject *obj) { + g_return_if_fail(obj != NULL); + g_return_if_fail(SP_IS_OBJECT(obj)); + + if (includes(obj)) { + return; + } + + _invalidateCachedLists(); + _add(obj); + _emitChanged(); +} + +void Selection::_add(SPObject *obj) { + // unselect any of the item's ancestors and descendants which may be selected + // (to prevent double-selection) + _removeObjectDescendants(obj); + _removeObjectAncestors(obj); + + _objs = g_slist_prepend(_objs, obj); + g_signal_connect(G_OBJECT(obj), "release", + G_CALLBACK(&Selection::_release), this); + g_signal_connect(G_OBJECT(obj), "modified", + G_CALLBACK(&Selection::_schedule_modified), this); + + /* + if (!SP_IS_SHAPE(obj)) { + printf("This is not a shape\n"); + } + */ +} + +void Selection::set(SPObject *object) { + _clear(); + add(object); +} + +void Selection::toggle(SPObject *obj) { + if (includes (obj)) { + remove (obj); + } else { + add(obj); + } +} + +void Selection::remove(SPObject *obj) { + g_return_if_fail(obj != NULL); + g_return_if_fail(SP_IS_OBJECT(obj)); + g_return_if_fail(includes(obj)); + + _invalidateCachedLists(); + _remove(obj); + _emitChanged(); +} + +void Selection::_remove(SPObject *obj) { + sp_signal_disconnect_by_data(obj, this); + _objs = g_slist_remove(_objs, obj); +} + +void Selection::setList(GSList const *list) { + _clear(); + + if ( list != NULL ) { + for ( GSList const *iter = list ; iter != NULL ; iter = iter->next ) { + _add(reinterpret_cast(iter->data)); + } + } + + _emitChanged(); +} + +void Selection::addList(GSList const *list) { + + if (list == NULL) + return; + + _invalidateCachedLists(); + + for ( GSList const *iter = list ; iter != NULL ; iter = iter->next ) { + SPObject *obj = reinterpret_cast(iter->data); + if (includes(obj)) { + continue; + } + _add (obj); + } + + _emitChanged(); +} + +void Selection::setReprList(GSList const *list) { + _clear(); + + for ( GSList const *iter = list ; iter != NULL ; iter = iter->next ) { + SPObject *obj=_objectForXMLNode(reinterpret_cast(iter->data)); + if (obj) { + _add(obj); + } + } + + _emitChanged(); +} + +void Selection::clear() { + _clear(); + _emitChanged(); +} + +GSList const *Selection::list() { + return _objs; +} + +GSList const *Selection::itemList() { + if (_items) { + return _items; + } + + for ( GSList const *iter=_objs ; iter != NULL ; iter = iter->next ) { + SPObject *obj=reinterpret_cast(iter->data); + if (SP_IS_ITEM(obj)) { + _items = g_slist_prepend(_items, SP_ITEM(obj)); + } + } + _items = g_slist_reverse(_items); + + return _items; +} + +GSList const *Selection::reprList() { + if (_reprs) { return _reprs; } + + for ( GSList const *iter=itemList() ; iter != NULL ; iter = iter->next ) { + SPObject *obj=reinterpret_cast(iter->data); + _reprs = g_slist_prepend(_reprs, SP_OBJECT_REPR(obj)); + } + _reprs = g_slist_reverse(_reprs); + + return _reprs; +} + +SPObject *Selection::single() { + if ( _objs != NULL && _objs->next == NULL ) { + return reinterpret_cast(_objs->data); + } else { + return NULL; + } +} + +SPItem *Selection::singleItem() { + GSList const *items=itemList(); + if ( items != NULL && items->next == NULL ) { + return reinterpret_cast(items->data); + } else { + return NULL; + } +} + +Inkscape::XML::Node *Selection::singleRepr() { + SPObject *obj=single(); + return obj ? SP_OBJECT_REPR(obj) : NULL; +} + +NRRect *Selection::bounds(NRRect *bbox) const +{ + g_return_val_if_fail (bbox != NULL, NULL); + NR::Rect const b = bounds(); + bbox->x0 = b.min()[NR::X]; + bbox->y0 = b.min()[NR::Y]; + bbox->x1 = b.max()[NR::X]; + bbox->x1 = b.max()[NR::Y]; + return bbox; +} + +NR::Rect Selection::bounds() const +{ + GSList const *items = const_cast(this)->itemList(); + if (!items) { + return NR::Rect(NR::Point(0, 0), NR::Point(0, 0)); + } + + GSList const *i = items; + NR::Rect bbox = sp_item_bbox_desktop(SP_ITEM(i->data)); + + while (i != NULL) { + bbox = NR::Rect::union_bounds(bbox, sp_item_bbox_desktop(SP_ITEM(i->data))); + i = i->next; + } + + return bbox; +} + +NRRect *Selection::boundsInDocument(NRRect *bbox) const { + g_return_val_if_fail (bbox != NULL, NULL); + + GSList const *items=const_cast(this)->itemList(); + if (!items) { + bbox->x0 = bbox->y0 = bbox->x1 = bbox->y1 = 0.0; + return bbox; + } + + bbox->x0 = bbox->y0 = 1e18; + bbox->x1 = bbox->y1 = -1e18; + + for ( GSList const *iter=items ; iter != NULL ; iter = iter->next ) { + SPItem *item=SP_ITEM(iter->data); + NR::Matrix const i2doc(sp_item_i2doc_affine(item)); + sp_item_invoke_bbox(item, bbox, i2doc, FALSE); + } + + return bbox; +} + +NR::Rect Selection::boundsInDocument() const { + NRRect r; + return NR::Rect(*boundsInDocument(&r)); +} + +/** + * Compute the list of points in the selection that are to be considered for snapping. + */ +std::vector Selection::getSnapPoints() const { + GSList const *items = const_cast(this)->itemList(); + std::vector p; + for (GSList const *iter = items; iter != NULL; iter = iter->next) { + sp_item_snappoints(SP_ITEM(iter->data), SnapPointsIter(p)); + } + + return p; +} + +std::vector Selection::getSnapPointsConvexHull() const { + GSList const *items = const_cast(this)->itemList(); + std::vector p; + for (GSList const *iter = items; iter != NULL; iter = iter->next) { + sp_item_snappoints(SP_ITEM(iter->data), SnapPointsIter(p)); + } + + std::vector::iterator i; + NR::ConvexHull cvh(*(p.begin())); + for (i = p.begin(); i != p.end(); i++) { + // these are the points we get back + cvh.add(*i); + } + + NR::Rect rHull = cvh.bounds(); + std::vector pHull(4); + pHull[0] = rHull.corner(0); + pHull[1] = rHull.corner(1); + pHull[2] = rHull.corner(2); + pHull[3] = rHull.corner(3); + + return pHull; +} + +std::vector Selection::getBBoxPoints() const { + GSList const *items = const_cast(this)->itemList(); + std::vector p; + for (GSList const *iter = items; iter != NULL; iter = iter->next) { + NR::Rect b = sp_item_bbox_desktop(SP_ITEM(iter->data)); + p.push_back(b.min()); + p.push_back(b.max()); + } + + return p; +} + +void Selection::_removeObjectDescendants(SPObject *obj) { + GSList *iter, *next; + for ( iter = _objs ; iter ; iter = next ) { + next = iter->next; + SPObject *sel_obj=reinterpret_cast(iter->data); + SPObject *parent=SP_OBJECT_PARENT(sel_obj); + while (parent) { + if ( parent == obj ) { + _remove(sel_obj); + break; + } + parent = SP_OBJECT_PARENT(parent); + } + } +} + +void Selection::_removeObjectAncestors(SPObject *obj) { + SPObject *parent=SP_OBJECT_PARENT(obj); + while (parent) { + if (includes(parent)) { + _remove(parent); + } + parent = SP_OBJECT_PARENT(parent); + } +} + +SPObject *Selection::_objectForXMLNode(Inkscape::XML::Node *repr) const { + g_return_val_if_fail(repr != NULL, NULL); + gchar const *id = repr->attribute("id"); + g_return_val_if_fail(id != NULL, NULL); + SPObject *object=SP_DT_DOCUMENT(_desktop)->getObjectById(id); + g_return_val_if_fail(object != NULL, NULL); + return object; +} + +guint Selection::numberOfLayers() { + GSList const *items = const_cast(this)->itemList(); + GSList *layers = NULL; + for (GSList const *iter = items; iter != NULL; iter = iter->next) { + SPObject *layer = desktop()->layerForObject(SP_OBJECT(iter->data)); + if (g_slist_find (layers, layer) == NULL) { + layers = g_slist_prepend (layers, layer); + } + } + guint ret = g_slist_length (layers); + g_slist_free (layers); + return ret; +} + +} + +/* + 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:textwidth=99 : diff --git a/src/selection.h b/src/selection.h new file mode 100644 index 000000000..48d1112a8 --- /dev/null +++ b/src/selection.h @@ -0,0 +1,347 @@ +#ifndef SEEN_INKSCAPE_SELECTION_H +#define SEEN_INKSCAPE_SELECTION_H + +/** \file + * Inkscape::Selection: per-desktop selection container + * + * Authors: + * Lauris Kaplinski + * MenTaLguY + * bulia byak + * + * Copyright (C) 2004-2005 MenTaLguY + * Copyright (C) 1999-2002 Lauris Kaplinski + * Copyright (C) 2001-2002 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include +#include + +#include "libnr/nr-rect.h" +#include "libnr/nr-convex-hull.h" +#include "forward.h" +#include "gc-managed.h" +#include "gc-finalized.h" +#include "gc-anchored.h" +#include "util/list.h" + +class SPItem; + +namespace Inkscape { +namespace XML { +class Node; +} +} + +namespace Inkscape { + +/** + * @brief The set of selected SPObjects for a given desktop. + * + * This class represents the set of selected SPItems for a given + * SPDesktop. + * + * An SPObject and its parent cannot be simultaneously selected; + * selecting an SPObjects has the side-effect of unselecting any of + * its children which might have been selected. + * + * This is a per-desktop object that keeps the list of selected objects + * at the given desktop. Both SPItem and SPRepr lists can be retrieved + * from the selection. Many actions operate on the selection, so it is + * widely used throughout the code. + * It also implements its own asynchronous notification signals that + * UI elements can listen to. + */ +class Selection : public Inkscape::GC::Managed<>, + public Inkscape::GC::Finalized, + public Inkscape::GC::Anchored +{ +public: + /** + * Constructs an selection object, bound to a particular + * SPDesktop + * + * @param desktop the desktop in question + */ + Selection(SPDesktop *desktop); + ~Selection(); + + /** + * @brief Returns the desktop the seoection is bound to + * + * @return the desktop the selection is bound to + */ + SPDesktop *desktop() { return _desktop; } + + /** + * @brief Add an SPObject to the set of selected objects + * + * @param obj the SPObject to add + */ + void add(SPObject *obj); + + /** + * @brief Add an XML node's SPObject to the set of selected objects + * + * @param the xml node of the item to add + */ + void add(XML::Node *repr) { add(_objectForXMLNode(repr)); } + + /** + * @brief Set the selection to a single specific object + * + * @param obj the object to select + */ + void set(SPObject *obj); + + /** + * @brief Set the selection to an XML node's SPObject + * + * @param repr the xml node of the item to select + */ + void set(XML::Node *repr) { set(_objectForXMLNode(repr)); } + + /** + * @brief Removes an item from the set of selected objects + * + * It is ok to call this method for an unselected item. + * + * @param item the item to unselect + */ + void remove(SPObject *obj); + + /** + * @brief Removes an item if selected, adds otherwise + * + * @param item the item to unselect + */ + void toggle(SPObject *obj); + + /** + * @brief Removes an item from the set of selected objects + * + * It is ok to call this method for an unselected item. + * + * @param repr the xml node of the item to remove + */ + void remove(XML::Node *repr) { remove(_objectForXMLNode(repr)); } + + /** + * @brief Selects exactly the specified objects + * + * @param objs the objects to select + */ + void setList(GSList const *objs); + + /** + * @brief Adds the specified objects to selection, without deselecting first + * + * @param objs the objects to select + */ + void addList(GSList const *objs); + + /** + * @brief Clears the selection and selects the specified objects + * + * @param repr a list of xml nodes for the items to select + */ + void setReprList(GSList const *reprs); + + /** \brief Add items from an STL iterator range to the selection + * \param from the begin iterator + * \param to the end iterator + */ + template + void add(InputIterator from, InputIterator to) { + _invalidateCachedLists(); + while ( from != to ) { + _add(*from); + ++from; + } + _emitChanged(); + } + + /** + * @brief Unselects all selected objects. + */ + void clear(); + + /** + * @brief Returns true if no items are selected + */ + bool isEmpty() const { return _objs == NULL; } + + /** + * @brief Returns true if the given object is selected + */ + bool includes(SPObject *obj) const; + + /** + * @brief Returns true if the given item is selected + */ + bool includes(XML::Node *repr) const { + return includes(_objectForXMLNode(repr)); + } + + /** + * @brief Returns a single selected object + * + * @return NULL unless exactly one object is selected + */ + SPObject *single(); + + /** + * @brief Returns a single selected item + * + * @return NULL unless exactly one object is selected + */ + SPItem *singleItem(); + + /** + * @brief Returns a single selected object's xml node + * + * @return NULL unless exactly one object is selected + */ + XML::Node *singleRepr(); + + /** @brief Returns the list of selected objects */ + GSList const *list(); + /** @brief Returns the list of selected SPItems */ + GSList const *itemList(); + /** @brief Returns a list of the xml nodes of all selected objects */ + /// \todo only returns reprs of SPItems currently; need a separate + /// method for that + GSList const *reprList(); + + /** @brief Returns the number of layers in which there are selected objects */ + guint numberOfLayers(); + + /** @brief Returns the bounding rectangle of the selection */ + NRRect *bounds(NRRect *dest) const; + /** @brief Returns the bounding rectangle of the selection */ + NR::Rect bounds() const; + + /** + * @brief Returns the bounding rectangle of the selection + * + * \todo how is this different from bounds()? + */ + NRRect *boundsInDocument(NRRect *dest) const; + + /** + * @brief Returns the bounding rectangle of the selection + * + * \todo how is this different from bounds()? + */ + NR::Rect boundsInDocument() const; + + /** + * @brief Gets the selection's snap points. + * @return Selection's snap points + */ + std::vector getSnapPoints() const; + + /** + * @brief Gets the snap points of a selection that form a convex hull. + * @return Selection's convex hull points + */ + std::vector getSnapPointsConvexHull() const; + + /** + * @return A vector containing the top-left and bottom-right + * corners of each selected object's bounding box. + */ + std::vector getBBoxPoints() const; + + /** + * @brief Connects a slot to be notified of selection changes + * + * This method connects the given slot such that it will + * be called upon any change in the set of selected objects. + * + * @param slot the slot to connect + * + * @return the resulting connection + */ + sigc::connection connectChanged(sigc::slot const &slot) { + return _changed_signal.connect(slot); + } + + /** + * @brief Connects a slot to be notified of selected + * object modifications + * + * This method connects the given slot such that it will + * receive notifications whenever any selected item is + * modified. + * + * @param slot the slot to connect + * + * @return the resulting connection + * + */ + sigc::connection connectModified(sigc::slot const &slot) + { + return _modified_signal.connect(slot); + } + +private: + /** @brief no copy */ + Selection(Selection const &); + /** @brief no assign */ + void operator=(Selection const &); + + /** @brief Issues modification notification signals */ + static gboolean _emit_modified(Selection *selection); + /** @brief Schedules an item modification signal to be sent */ + static void _schedule_modified(SPObject *obj, guint flags, Selection *selection); + /** @brief Releases a selected object that is being removed */ + static void _release(SPObject *obj, Selection *selection); + + /** @brief Issues modified selection signal */ + void _emitModified(guint flags); + /** @brief Issues changed selection signal */ + void _emitChanged(); + + void _invalidateCachedLists(); + + /** @brief unselect all descendants of the given item */ + void _removeObjectDescendants(SPObject *obj); + /** @brief unselect all ancestors of the given item */ + void _removeObjectAncestors(SPObject *obj); + /** @brief clears the selection (without issuing a notification) */ + void _clear(); + /** @brief adds an object (without issuing a notification) */ + void _add(SPObject *obj); + /** @brief removes an object (without issuing a notification) */ + void _remove(SPObject *obj); + /** @brief returns the SPObject corresponding to an xml node (if any) */ + SPObject *_objectForXMLNode(XML::Node *repr) const; + + mutable GSList *_objs; + mutable GSList *_reprs; + mutable GSList *_items; + + SPDesktop *_desktop; + guint _flags; + guint _idle; + + sigc::signal _changed_signal; + sigc::signal _modified_signal; +}; + +} + +#endif +/* + 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:textwidth=99 : diff --git a/src/seltrans-handles.cpp b/src/seltrans-handles.cpp new file mode 100644 index 000000000..95b680c5e --- /dev/null +++ b/src/seltrans-handles.cpp @@ -0,0 +1,42 @@ +#define SP_SELTRANS_HANDLES_C + +#include "seltrans-handles.h" + + +SPSelTransHandle const handles_scale[] = { +//anchor cursor control action request x y + {GTK_ANCHOR_SE, GDK_TOP_LEFT_CORNER, 0, sp_sel_trans_scale, sp_sel_trans_scale_request, 0, 1}, + {GTK_ANCHOR_S, GDK_TOP_SIDE, 3, sp_sel_trans_stretch, sp_sel_trans_stretch_request, 0.5, 1}, + {GTK_ANCHOR_SW, GDK_TOP_RIGHT_CORNER, 1, sp_sel_trans_scale, sp_sel_trans_scale_request, 1, 1}, + {GTK_ANCHOR_W, GDK_RIGHT_SIDE, 2, sp_sel_trans_stretch, sp_sel_trans_stretch_request, 1, 0.5}, + {GTK_ANCHOR_NW, GDK_BOTTOM_RIGHT_CORNER, 0, sp_sel_trans_scale, sp_sel_trans_scale_request, 1, 0}, + {GTK_ANCHOR_N, GDK_BOTTOM_SIDE, 3, sp_sel_trans_stretch, sp_sel_trans_stretch_request, 0.5, 0}, + {GTK_ANCHOR_NE, GDK_BOTTOM_LEFT_CORNER, 1, sp_sel_trans_scale, sp_sel_trans_scale_request, 0, 0}, + {GTK_ANCHOR_E, GDK_LEFT_SIDE, 2, sp_sel_trans_stretch, sp_sel_trans_stretch_request, 0, 0.5} +}; + +SPSelTransHandle const handles_rotate[] = { + {GTK_ANCHOR_SE, GDK_EXCHANGE, 4, sp_sel_trans_rotate, sp_sel_trans_rotate_request, 0, 1}, + {GTK_ANCHOR_S, GDK_SB_H_DOUBLE_ARROW, 5, sp_sel_trans_skew, sp_sel_trans_skew_request, 0.5, 1}, + {GTK_ANCHOR_SW, GDK_EXCHANGE, 6, sp_sel_trans_rotate, sp_sel_trans_rotate_request, 1, 1}, + {GTK_ANCHOR_W, GDK_SB_V_DOUBLE_ARROW, 7, sp_sel_trans_skew, sp_sel_trans_skew_request, 1, 0.5}, + {GTK_ANCHOR_NW, GDK_EXCHANGE, 8, sp_sel_trans_rotate, sp_sel_trans_rotate_request, 1, 0}, + {GTK_ANCHOR_N, GDK_SB_H_DOUBLE_ARROW, 9, sp_sel_trans_skew, sp_sel_trans_skew_request, 0.5, 0}, + {GTK_ANCHOR_NE, GDK_EXCHANGE, 10, sp_sel_trans_rotate, sp_sel_trans_rotate_request, 0, 0}, + {GTK_ANCHOR_E, GDK_SB_V_DOUBLE_ARROW, 11, sp_sel_trans_skew, sp_sel_trans_skew_request, 0, 0.5} +}; + +SPSelTransHandle const handle_center = + {GTK_ANCHOR_CENTER, GDK_CROSSHAIR, 12, sp_sel_trans_center, sp_sel_trans_center_request, 0.5, 0.5}; + + +/* + 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:textwidth=99 : diff --git a/src/seltrans-handles.h b/src/seltrans-handles.h new file mode 100644 index 000000000..0afa552ea --- /dev/null +++ b/src/seltrans-handles.h @@ -0,0 +1,57 @@ +#ifndef __SP_SELTRANS_HANDLES_H__ +#define __SP_SELTRANS_HANDLES_H__ + +/* + * Seltrans knots + * + * Authors: + * Lauris Kaplinski + * + * Copyright (C) 1999-2002 authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "display/sodipodi-ctrl.h" + +namespace Inkscape +{ + class SelTrans; +} + +class SPSelTransHandle; + +// request handlers +gboolean sp_sel_trans_scale_request(Inkscape::SelTrans *seltrans, + SPSelTransHandle const &handle, NR::Point &p, guint state); +gboolean sp_sel_trans_stretch_request(Inkscape::SelTrans *seltrans, + SPSelTransHandle const &handle, NR::Point &p, guint state); +gboolean sp_sel_trans_skew_request(Inkscape::SelTrans *seltrans, + SPSelTransHandle const &handle, NR::Point &p, guint state); +gboolean sp_sel_trans_rotate_request(Inkscape::SelTrans *seltrans, + SPSelTransHandle const &handle, NR::Point &p, guint state); +gboolean sp_sel_trans_center_request(Inkscape::SelTrans *seltrans, + SPSelTransHandle const &handle, NR::Point &p, guint state); + +// action handlers +void sp_sel_trans_scale(Inkscape::SelTrans *seltrans, SPSelTransHandle const &handle, NR::Point &p, guint state); +void sp_sel_trans_stretch(Inkscape::SelTrans *seltrans, SPSelTransHandle const &handle, NR::Point &p, guint state); +void sp_sel_trans_skew(Inkscape::SelTrans *seltrans, SPSelTransHandle const &handle, NR::Point &p, guint state); +void sp_sel_trans_rotate(Inkscape::SelTrans *seltrans, SPSelTransHandle const &handle, NR::Point &p, guint state); +void sp_sel_trans_center(Inkscape::SelTrans *seltrans, SPSelTransHandle const &handle, NR::Point &p, guint state); + +struct SPSelTransHandle { + GtkAnchorType anchor; + GdkCursorType cursor; + guint control; + void (* action) (Inkscape::SelTrans *seltrans, SPSelTransHandle const &handle, NR::Point &p, guint state); + gboolean (* request) (Inkscape::SelTrans *seltrans, SPSelTransHandle const &handle, NR::Point &p, guint state); + gdouble x, y; +}; + +extern SPSelTransHandle const handles_scale[8]; +extern SPSelTransHandle const handles_rotate[8]; +extern SPSelTransHandle const handle_center; + +#endif + diff --git a/src/seltrans.cpp b/src/seltrans.cpp new file mode 100644 index 000000000..ca65b5d76 --- /dev/null +++ b/src/seltrans.cpp @@ -0,0 +1,1332 @@ +#define __SELTRANS_C__ + +/* + * Helper object for transforming selected items + * + * Author: + * Lauris Kaplinski + * bulia byak + * Carl Hetherington + * + * Copyright (C) 1999-2002 Lauris Kaplinski + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include "document.h" +#include "sp-namedview.h" +#include "desktop.h" +#include "desktop-handles.h" +#include "desktop-style.h" +#include "knot.h" +#include "snap.h" +#include "selection.h" +#include "select-context.h" +#include "sp-item.h" +#include "sp-item-transform.h" +#include "seltrans-handles.h" +#include "seltrans.h" +#include "selection-chemistry.h" +#include "sp-metrics.h" +#include +#include "display/sp-ctrlline.h" +#include "prefs-utils.h" +#include "xml/repr.h" + +#include "isnan.h" //temp fix. make sure included last + +static void sp_remove_handles(SPKnot *knot[], gint num); + +static void sp_sel_trans_handle_grab(SPKnot *knot, guint state, gpointer data); +static void sp_sel_trans_handle_ungrab(SPKnot *knot, guint state, gpointer data); +static void sp_sel_trans_handle_new_event(SPKnot *knot, NR::Point *position, guint32 state, gpointer data); +static gboolean sp_sel_trans_handle_request(SPKnot *knot, NR::Point *p, guint state, gboolean *data); + +extern GdkPixbuf *handles[]; + +static gboolean sp_seltrans_handle_event(SPKnot *knot, GdkEvent *event, gpointer) +{ + switch (event->type) { + case GDK_MOTION_NOTIFY: + break; + case GDK_KEY_PRESS: + if (get_group0_keyval (&event->key) == GDK_space) { + /* stamping mode: both mode(show content and outline) operation with knot */ + if (!SP_KNOT_IS_GRABBED(knot)) { + return FALSE; + } + SPDesktop *desktop = knot->desktop; + Inkscape::SelTrans *seltrans = SP_SELECT_CONTEXT(desktop->event_context)->_seltrans; + seltrans->stamp(); + return TRUE; + } + break; + default: + break; + } + + return FALSE; +} + +Inkscape::SelTrans::SelTrans(SPDesktop *desktop) : + _desktop(desktop), + _selcue(desktop), + _state(STATE_SCALE), + _show(SHOW_CONTENT), + _grabbed(false), + _show_handles(true), + _box(NR::Point(0,0), NR::Point(0,0)), + _chandle(NULL), + _stamp_cache(NULL), + _message_context(desktop->messageStack()) +{ + g_return_if_fail(desktop != NULL); + + for (int i = 0; i < 8; i++) { + _shandle[i] = NULL; + _rhandle[i] = NULL; + } + + _updateVolatileState(); + + _center = _box.midpoint(); + + _updateHandles(); + + _selection = SP_DT_SELECTION(desktop); + + _norm = sp_canvas_item_new(SP_DT_CONTROLS(desktop), + SP_TYPE_CTRL, + "anchor", GTK_ANCHOR_CENTER, + "mode", SP_CTRL_MODE_COLOR, + "shape", SP_CTRL_SHAPE_BITMAP, + "size", 13.0, + "filled", TRUE, + "fill_color", 0x00000000, + "stroked", TRUE, + "stroke_color", 0x000000a0, + "pixbuf", handles[12], + NULL); + + _grip = sp_canvas_item_new(SP_DT_CONTROLS(desktop), + SP_TYPE_CTRL, + "anchor", GTK_ANCHOR_CENTER, + "mode", SP_CTRL_MODE_XOR, + "shape", SP_CTRL_SHAPE_CROSS, + "size", 7.0, + "filled", TRUE, + "fill_color", 0xffffff7f, + "stroked", TRUE, + "stroke_color", 0xffffffff, + "pixbuf", handles[12], + NULL); + + sp_canvas_item_hide(_grip); + sp_canvas_item_hide(_norm); + + for (int i = 0; i < 4; i++) { + _l[i] = sp_canvas_item_new(SP_DT_CONTROLS(desktop), SP_TYPE_CTRLLINE, NULL); + sp_canvas_item_hide(_l[i]); + } + + _sel_changed_connection = _selection->connectChanged( + sigc::mem_fun(*this, &Inkscape::SelTrans::_selChanged) + ); + + _sel_modified_connection = _selection->connectModified( + sigc::mem_fun(*this, &Inkscape::SelTrans::_selModified) + ); +} + +Inkscape::SelTrans::~SelTrans() +{ + _sel_changed_connection.disconnect(); + _sel_modified_connection.disconnect(); + + for (unsigned int i = 0; i < 8; i++) { + if (_shandle[i]) { + g_object_unref(G_OBJECT(_shandle[i])); + _shandle[i] = NULL; + } + if (_rhandle[i]) { + g_object_unref(G_OBJECT(_rhandle[i])); + _rhandle[i] = NULL; + } + } + if (_chandle) { + g_object_unref(G_OBJECT(_chandle)); + _chandle = NULL; + } + + if (_norm) { + gtk_object_destroy(GTK_OBJECT(_norm)); + _norm = NULL; + } + if (_grip) { + gtk_object_destroy(GTK_OBJECT(_grip)); + _grip = NULL; + } + for (int i = 0; i < 4; i++) { + if (_l[i]) { + gtk_object_destroy(GTK_OBJECT(_l[i])); + _l[i] = NULL; + } + } + + for (unsigned i = 0; i < _items.size(); i++) { + sp_object_unref(SP_OBJECT(_items[i].first), NULL); + } + + _items.clear(); +} + +void Inkscape::SelTrans::resetState() +{ + _state = STATE_SCALE; +} + +void Inkscape::SelTrans::increaseState() +{ + if (_state == STATE_SCALE) { + _state = STATE_ROTATE; + } else { + _state = STATE_SCALE; + } + + _updateHandles(); +} + +void Inkscape::SelTrans::setCenter(NR::Point const &p) +{ + _center = p; + _updateHandles(); +} + +void Inkscape::SelTrans::grab(NR::Point const &p, gdouble x, gdouble y, bool show_handles) +{ + Inkscape::Selection *selection = SP_DT_SELECTION(_desktop); + + g_return_if_fail(!_grabbed); + + _grabbed = true; + _show_handles = show_handles; + _updateVolatileState(); + + _changed = false; + + if (_empty) { + return; + } + + for (GSList const *l = selection->itemList(); l; l = l->next) { + SPItem *it = (SPItem*)sp_object_ref(SP_OBJECT(l->data), NULL); + _items.push_back(std::pair(it, sp_item_i2d_affine(it))); + } + + _current.set_identity(); + + _point = p; + + _snap_points = selection->getSnapPoints(); + _bbox_points = selection->getBBoxPoints(); + + gchar const *scale_origin = prefs_get_string_attribute("tools.select", "scale_origin"); + bool const origin_on_bbox = (scale_origin == NULL || !strcmp(scale_origin, "bbox")); + NR::Rect op_box = _box; + if (origin_on_bbox == false && _snap_points.empty() == false) { + std::vector::iterator i = _snap_points.begin(); + op_box = NR::Rect(*i, *i); + i++; + while (i != _snap_points.end()) { + op_box.expandTo(*i); + i++; + } + } + + _opposite = ( op_box.min() + ( op_box.dimensions() * NR::scale(1-x, 1-y) ) ); + + if ((x != -1) && (y != -1)) { + sp_canvas_item_show(_norm); + sp_canvas_item_show(_grip); + } + + if (_show == SHOW_OUTLINE) { + for (int i = 0; i < 4; i++) + sp_canvas_item_show(_l[i]); + } + + + _updateHandles(); + g_return_if_fail(_stamp_cache == NULL); +} + +void Inkscape::SelTrans::transform(NR::Matrix const &rel_affine, NR::Point const &norm) +{ + g_return_if_fail(_grabbed); + g_return_if_fail(!_empty); + + NR::Matrix const affine( NR::translate(-norm) * rel_affine * NR::translate(norm) ); + + if (_show == SHOW_CONTENT) { + // update the content + for (unsigned i = 0; i < _items.size(); i++) { + SPItem &item = *_items[i].first; + NR::Matrix const &prev_transform = _items[i].second; + sp_item_set_i2d_affine(&item, prev_transform * affine); + } + } else { + NR::Point p[4]; + /* update the outline */ + for (unsigned i = 0 ; i < 4 ; i++) { + p[i] = _box.corner(i) * affine; + } + for (unsigned i = 0 ; i < 4 ; i++) { + sp_ctrlline_set_coords(SP_CTRLLINE(_l[i]), p[i], p[(i+1)%4]); + } + } + + _current = affine; + _changed = true; + _updateHandles(); +} + +void Inkscape::SelTrans::_centreTrans(Inkscape::XML::Node *current) const +{ + for ( Inkscape::XML::Node *child = sp_repr_children(current) ; child ; child = sp_repr_next(child) ) { + _centreTrans(child); + } + double const cx = sp_repr_get_double_attribute(current, "inkscape:c_rx", 9999999); + double const cy = sp_repr_get_double_attribute(current, "inkscape:c_ry", 9999999); + if (cx != 9999999) { + NR::Point object_centre = NR::Point(cx, cy) * _current; + sp_repr_set_svg_double(current, "inkscape:c_rx", object_centre[NR::X]); + sp_repr_set_svg_double(current, "inkscape:c_ry", object_centre[NR::Y]); + } + } + + + + +void Inkscape::SelTrans::ungrab() +{ + g_return_if_fail(_grabbed); + + Inkscape::Selection *selection = SP_DT_SELECTION(_desktop); + + bool updh = true; + if (!_empty && _changed) { + sp_selection_apply_affine(selection, _current, (_show == SHOW_OUTLINE)? true : false); + _center *= _current; + sp_document_done(SP_DT_DOCUMENT(_desktop)); + updh = false; + } + + for (unsigned i = 0; i < _items.size(); i++) + { + Inkscape::XML::Node *current = SP_OBJECT_REPR(_items[i].first); + if (current != NULL) { + _centreTrans(current); + } + + sp_object_unref(SP_OBJECT(_items[i].first), NULL); + } + _items.clear(); + + _grabbed = false; + _show_handles = true; + + sp_canvas_item_hide(_norm); + sp_canvas_item_hide(_grip); + + if (_show == SHOW_OUTLINE) { + for (int i = 0; i < 4; i++) + sp_canvas_item_hide(_l[i]); + } + + _updateVolatileState(); + if (updh) { + _updateHandles(); + } + if (_stamp_cache) { + g_slist_free(_stamp_cache); + _stamp_cache = NULL; + } + + _message_context.clear(); +} + +/* fixme: This is really bad, as we compare positions for each stamp (Lauris) */ +/* fixme: IMHO the best way to keep sort cache would be to implement timestamping at last */ + +void Inkscape::SelTrans::stamp() +{ + Inkscape::Selection *selection = SP_DT_SELECTION(_desktop); + + /* stamping mode */ + if (!_empty) { + GSList *l; + if (_stamp_cache) { + l = _stamp_cache; + } else { + /* Build cache */ + l = g_slist_copy((GSList *) selection->itemList()); + l = g_slist_sort(l, (GCompareFunc) sp_object_compare_position); + _stamp_cache = l; + } + + while (l) { + SPItem *original_item = SP_ITEM(l->data); + Inkscape::XML::Node *original_repr = SP_OBJECT_REPR(original_item); + + // remember the position of the item + gint pos = original_repr->position(); + // remember parent + Inkscape::XML::Node *parent = sp_repr_parent(original_repr); + + Inkscape::XML::Node *copy_repr = original_repr->duplicate(); + + // add the new repr to the parent + parent->appendChild(copy_repr); + // move to the saved position + copy_repr->setPosition(pos > 0 ? pos : 0); + + SPItem *copy_item = (SPItem *) SP_DT_DOCUMENT(_desktop)->getObjectByRepr(copy_repr); + + NR::Matrix const *new_affine; + if (_show == SHOW_OUTLINE) { + NR::Matrix const i2d(sp_item_i2d_affine(original_item)); + NR::Matrix const i2dnew( i2d * _current ); + sp_item_set_i2d_affine(copy_item, i2dnew); + new_affine = ©_item->transform; + } else { + new_affine = &original_item->transform; + } + + sp_item_write_transform(copy_item, copy_repr, *new_affine); + + Inkscape::GC::release(copy_repr); + l = l->next; + } + sp_document_done(SP_DT_DOCUMENT(_desktop)); + } +} + +void Inkscape::SelTrans::_updateHandles() +{ + if ( !_show_handles || _empty ) + { + sp_remove_handles(_shandle, 8); + sp_remove_handles(_rhandle, 8); + sp_remove_handles(&_chandle, 1); + return; + } + + // center handle + if ( _chandle == NULL ) { + _chandle = sp_knot_new(_desktop); + g_object_set(G_OBJECT(_chandle), + "anchor", handle_center.anchor, + "shape", SP_CTRL_SHAPE_BITMAP, + "size", 13, + "mode", SP_CTRL_MODE_XOR, + "fill", 0x00000000, + "fill_mouseover", 0x00000000, + "stroke", 0x000000ff, + "stroke_mouseover", 0xff0000b0, + "pixbuf", handles[handle_center.control], + "tip", _("Center of rotation and skewing: drag to reposition; scaling with Shift also uses this center"), + NULL); + g_signal_connect(G_OBJECT(_chandle), "request", + G_CALLBACK(sp_sel_trans_handle_request), (gpointer) &handle_center); + g_signal_connect(G_OBJECT(_chandle), "moved", + G_CALLBACK(sp_sel_trans_handle_new_event), (gpointer) &handle_center); + g_signal_connect(G_OBJECT(_chandle), "grabbed", + G_CALLBACK(sp_sel_trans_handle_grab), (gpointer) &handle_center); + g_signal_connect(G_OBJECT(_chandle), "ungrabbed", + G_CALLBACK(sp_sel_trans_handle_ungrab), (gpointer) &handle_center); + } + + sp_remove_handles(&_chandle, 1); + if ( _state == STATE_SCALE ) { + sp_remove_handles(_rhandle, 8); + _showHandles(_shandle, handles_scale, 8, + _("Squeeze or stretch selection; with Ctrl to scale uniformly; with Shift to scale around rotation center"), + _("Scale selection; with Ctrl to scale uniformly; with Shift to scale around rotation center")); + } else { + sp_remove_handles(_shandle, 8); + _showHandles(_rhandle, handles_rotate, 8, + _("Skew selection; with Ctrl to snap angle; with Shift to skew around the opposite side"), + _("Rotate selection; with Ctrl to snap angle; with Shift to rotate around the opposite corner")); + } + if ( _state == STATE_SCALE ) { + sp_knot_hide(_chandle); + } else { + Inkscape::Selection *selection = _desktop->selection; + Inkscape::XML::Node *current = selection->singleRepr(); + if (current != NULL && sp_repr_get_double_attribute(current, "inkscape:c_rx", 99999999) != 99999999) { + double cx = sp_repr_get_double_attribute(current, "inkscape:c_rx", _center[NR::X]); + double cy = sp_repr_get_double_attribute(current, "inkscape:c_ry", _center[NR::Y]); + _center = NR::Point(cx, cy); + } + sp_knot_show(_chandle); + sp_knot_moveto(_chandle, &_center); + } +} + +void Inkscape::SelTrans::_updateVolatileState() +{ + Inkscape::Selection *selection = SP_DT_SELECTION(_desktop); + _empty = selection->isEmpty(); + + if (_empty) { + return; + } + + _box = selection->bounds(); + if (_box.isEmpty()) { + _empty = true; + return; + } + + _strokewidth = stroke_average_width (selection->itemList()); + + _current.set_identity(); +} + +static void sp_remove_handles(SPKnot *knot[], gint num) +{ + for (int i = 0; i < num; i++) { + if (knot[i] != NULL) { + sp_knot_hide(knot[i]); + } + } +} + +void Inkscape::SelTrans::_showHandles(SPKnot *knot[], SPSelTransHandle const handle[], gint num, + gchar const *even_tip, gchar const *odd_tip) +{ + g_return_if_fail( !_empty ); + + for (int i = 0; i < num; i++) { + if (knot[i] == NULL) { + knot[i] = sp_knot_new(_desktop); + g_object_set(G_OBJECT(knot[i]), + "anchor", handle[i].anchor, + "shape", SP_CTRL_SHAPE_BITMAP, + "size", 13, + "mode", SP_KNOT_MODE_XOR, + "fill", 0x000000ff, // inversion + "fill_mouseover", 0x00ff6600, // green + "stroke", 0x000000ff, // inversion + "stroke_mouseover", 0x000000ff, // inversion + "pixbuf", handles[handle[i].control], + "tip", i % 2 ? even_tip : odd_tip, + NULL); + + g_signal_connect(G_OBJECT(knot[i]), "request", + G_CALLBACK(sp_sel_trans_handle_request), (gpointer) &handle[i]); + g_signal_connect(G_OBJECT(knot[i]), "moved", + G_CALLBACK(sp_sel_trans_handle_new_event), (gpointer) &handle[i]); + g_signal_connect(G_OBJECT(knot[i]), "grabbed", + G_CALLBACK(sp_sel_trans_handle_grab), (gpointer) &handle[i]); + g_signal_connect(G_OBJECT(knot[i]), "ungrabbed", + G_CALLBACK(sp_sel_trans_handle_ungrab), (gpointer) &handle[i]); + g_signal_connect(G_OBJECT(knot[i]), "event", G_CALLBACK(sp_seltrans_handle_event), (gpointer) &handle[i]); + } + sp_knot_show(knot[i]); + + NR::Point const handle_pt(handle[i].x, handle[i].y); + NR::Point p( _box.min() + + ( _box.dimensions() + * NR::scale(handle_pt) ) ); + + sp_knot_moveto(knot[i], &p); + } +} + +static void sp_sel_trans_handle_grab(SPKnot *knot, guint state, gpointer data) +{ + SP_SELECT_CONTEXT(knot->desktop->event_context)->_seltrans->handleGrab( + knot, state, *(SPSelTransHandle const *) data + ); +} + +static void sp_sel_trans_handle_ungrab(SPKnot *knot, guint state, gpointer data) +{ + SP_SELECT_CONTEXT(knot->desktop->event_context)->_seltrans->ungrab(); +} + +static void sp_sel_trans_handle_new_event(SPKnot *knot, NR::Point *position, guint state, gpointer data) +{ + SP_SELECT_CONTEXT(knot->desktop->event_context)->_seltrans->handleNewEvent( + knot, position, state, *(SPSelTransHandle const *) data + ); +} + +static gboolean sp_sel_trans_handle_request(SPKnot *knot, NR::Point *position, guint state, gboolean *data) +{ + return SP_SELECT_CONTEXT(knot->desktop->event_context)->_seltrans->handleRequest( + knot, position, state, *(SPSelTransHandle const *) data + ); +} + +void Inkscape::SelTrans::handleGrab(SPKnot *knot, guint state, SPSelTransHandle const &handle) +{ + switch (handle.anchor) { + case GTK_ANCHOR_CENTER: + g_object_set(G_OBJECT(_grip), + "shape", SP_CTRL_SHAPE_BITMAP, + "size", 13.0, + NULL); + sp_canvas_item_show(_grip); + break; + default: + g_object_set(G_OBJECT(_grip), + "shape", SP_CTRL_SHAPE_CROSS, + "size", 7.0, + NULL); + sp_canvas_item_show(_norm); + sp_canvas_item_show(_grip); + + break; + } + + grab(sp_knot_position(knot), handle.x, handle.y, FALSE); +} + + +void Inkscape::SelTrans::handleNewEvent(SPKnot *knot, NR::Point *position, guint state, SPSelTransHandle const &handle) +{ + if (!SP_KNOT_IS_GRABBED(knot)) { + return; + } + + // in case items have been unhooked from the document, don't + // try to continue processing events for them. + for (unsigned int i = 0; i < _items.size(); i++) { + if (!SP_OBJECT_DOCUMENT(SP_OBJECT(_items[i].first)) ) { + return; + } + } + + handle.action(this, handle, *position, state); +} + + +gboolean Inkscape::SelTrans::handleRequest(SPKnot *knot, NR::Point *position, guint state, SPSelTransHandle const &handle) +{ + if (!SP_KNOT_IS_GRABBED(knot)) { + return TRUE; + } + + knot->desktop->set_coordinate_status(*position); + knot->desktop->setPosition(*position); + + + if (state & GDK_MOD1_MASK) { + *position = _point + ( *position - _point ) / 10; + } + + if (!(state & GDK_SHIFT_MASK) == !(_state == STATE_ROTATE)) { + _origin = _opposite; + } else { + _origin = _center; + } + if (handle.request(this, handle, *position, state)) { + sp_knot_set_position(knot, position, state); + SP_CTRL(_grip)->moveto(*position); + SP_CTRL(_norm)->moveto(_origin); + } + + return TRUE; +} + + +void Inkscape::SelTrans::_selChanged(Inkscape::Selection *selection) +{ + if (!_grabbed) { + _updateVolatileState(); + _center = _box.midpoint(); + _updateHandles(); + } +} + +void Inkscape::SelTrans::_selModified(Inkscape::Selection *selection, guint flags) +{ + if (!_grabbed) { + _updateVolatileState(); + + if ( + (flags != (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG)) && + (flags != SP_OBJECT_PARENT_MODIFIED_FLAG) && + (flags != SP_OBJECT_CHILD_MODIFIED_FLAG) && + !_changed) { + // Only reset center if object itself is modified (not style, parent or child), + // and this is not a local change by seltrans + // (still annoyingly recenters on keyboard transforms, fixme) + _center = _box.midpoint(); + } + + // reset internal flag + _changed = false; + + _updateHandles(); + } +} + +/* + * handlers for handle move-request + */ + +/** Returns -1 or 1 according to the sign of x. Returns 1 for 0 and NaN. */ +static double sign(double const x) +{ + return ( x < 0 + ? -1 + : 1 ); +} + +gboolean sp_sel_trans_scale_request(Inkscape::SelTrans *seltrans, + SPSelTransHandle const &, NR::Point &pt, guint state) +{ + return seltrans->scaleRequest(pt, state); +} + +gboolean sp_sel_trans_stretch_request(Inkscape::SelTrans *seltrans, + SPSelTransHandle const &handle, NR::Point &pt, guint state) +{ + return seltrans->stretchRequest(handle, pt, state); +} + +gboolean sp_sel_trans_skew_request(Inkscape::SelTrans *seltrans, + SPSelTransHandle const &handle, NR::Point &pt, guint state) +{ + return seltrans->skewRequest(handle, pt, state); +} + +gboolean sp_sel_trans_rotate_request(Inkscape::SelTrans *seltrans, + SPSelTransHandle const &, NR::Point &pt, guint state) +{ + return seltrans->rotateRequest(pt, state); +} + +gboolean sp_sel_trans_center_request(Inkscape::SelTrans *seltrans, + SPSelTransHandle const &, NR::Point &pt, guint state) +{ + return seltrans->centerRequest(pt, state); +} + +gboolean Inkscape::SelTrans::scaleRequest(NR::Point &pt, guint state) +{ + using NR::X; + using NR::Y; + + NR::Point d = _point - _origin; + NR::scale s(0, 0); + + /* Work out the new scale factors `s' */ + for ( unsigned int i = 0 ; i < 2 ; i++ ) { + if ( fabs(d[i]) > 0.001 ) { + s[i] = ( pt[i] - _origin[i] ) / d[i]; + if ( fabs(s[i]) < 1e-9 ) { + s[i] = 1e-9; + } + } + } + + /* Get a STL list of the selected items. + ** FIXME: this should probably be done by Inkscape::Selection. + */ + std::list it; + for (GSList const *i = _selection->itemList(); i != NULL; i = i->next) { + it.push_back(reinterpret_cast(i->data)); + } + + if ((state & GDK_CONTROL_MASK) || _desktop->isToolboxButtonActive ("lock")) { + /* Scale is locked to a 1:1 aspect ratio, so that s[X] must be made to equal s[Y] */ + + NR::Dim2 locked_dim; + + /* Lock aspect ratio, using the smaller of the x and y factors */ + if (fabs(s[NR::X]) > fabs(s[NR::Y])) { + s[NR::X] = fabs(s[NR::Y]) * sign(s[NR::X]); + locked_dim = NR::X; + } else { + s[NR::Y] = fabs(s[NR::X]) * sign(s[NR::Y]); + locked_dim = NR::Y; + } + + /* Snap the scale factor */ + std::pair bb = namedview_vector_snap_list(_desktop->namedview, + Snapper::BBOX_POINT, _bbox_points, + _origin, s, it); + std::pair sn = namedview_vector_snap_list(_desktop->namedview, + Snapper::SNAP_POINT, _snap_points, + _origin, s, it); + + double bd = bb.second ? fabs(bb.first - s[locked_dim]) : NR_HUGE; + double sd = sn.second ? fabs(sn.first - s[locked_dim]) : NR_HUGE; + double r = (bd < sd) ? bb.first : sn.first; + + for ( unsigned int i = 0 ; i < 2 ; i++ ) { + s[i] = r * sign(s[i]); + } + + } else { + /* Scale aspect ratio is unlocked */ + for ( unsigned int i = 0 ; i < 2 ; i++ ) { + std::pair bb = namedview_dim_snap_list_scale(_desktop->namedview, + Snapper::BBOX_POINT, _bbox_points, + _origin, s[i], NR::Dim2(i), it); + std::pair sn = namedview_dim_snap_list_scale(_desktop->namedview, + Snapper::SNAP_POINT, _snap_points, + _origin, s[i], NR::Dim2(i), it); + + /* Pick the snap that puts us closest to the original scale */ + NR::Coord bd = bb.second ? fabs(bb.first - s[i]) : NR_HUGE; + NR::Coord sd = sn.second ? fabs(sn.first - s[i]) : NR_HUGE; + s[i] = (bd < sd) ? bb.first : sn.first; + } + } + + /* Update the knot position */ + pt = ( _point - _origin ) * s + _origin; + + /* Status text */ + _message_context.setF(Inkscape::NORMAL_MESSAGE, + _("Scale: %0.2f%% x %0.2f%%; with Ctrl to lock ratio"), + 100 * s[NR::X], 100 * s[NR::Y]); + + return TRUE; +} + +gboolean Inkscape::SelTrans::stretchRequest(SPSelTransHandle const &handle, NR::Point &pt, guint state) +{ + using NR::X; + using NR::Y; + + NR::Dim2 axis, perp; + + switch (handle.cursor) { + case GDK_TOP_SIDE: + case GDK_BOTTOM_SIDE: + axis = NR::Y; + perp = NR::X; + break; + case GDK_LEFT_SIDE: + case GDK_RIGHT_SIDE: + axis = NR::X; + perp = NR::Y; + break; + default: + g_assert_not_reached(); + return TRUE; + }; + + if ( fabs( _point[axis] - _origin[axis] ) < 1e-15 ) { + return FALSE; + } + + NR::scale s(1, 1); + s[axis] = ( ( pt[axis] - _origin[axis] ) + / ( _point[axis] - _origin[axis] ) ); + if ( fabs(s[axis]) < 1e-15 ) { + s[axis] = 1e-15; + } + + /* Get a STL list of the selected items. + ** FIXME: this should probably be done by Inkscape::Selection. + */ + std::list it; + for (GSList const *i = _selection->itemList(); i != NULL; i = i->next) { + it.push_back(reinterpret_cast(i->data)); + } + + if ( state & GDK_CONTROL_MASK ) { + s[perp] = fabs(s[axis]); + + std::pair sn = namedview_vector_snap_list(_desktop->namedview, + Snapper::BBOX_POINT, + _bbox_points, _origin, s, it); + std::pair bb = namedview_vector_snap_list(_desktop->namedview, + Snapper::SNAP_POINT, + _snap_points, _origin, s, it); + + double bd = bb.second ? fabs(bb.first - s[axis]) : NR_HUGE; + double sd = sn.second ? fabs(sn.first - s[axis]) : NR_HUGE; + double ratio = (bd < sd) ? bb.first : sn.first; + + s[axis] = fabs(ratio) * sign(s[axis]); + s[perp] = fabs(s[axis]); + } else { + std::pair bb = namedview_dim_snap_list_scale(_desktop->namedview, Snapper::BBOX_POINT, + _bbox_points, _origin, + s[axis], axis, it); + std::pair sn = namedview_dim_snap_list_scale(_desktop->namedview, Snapper::SNAP_POINT, + _snap_points, _origin, + s[axis], axis, it); + + /* Pick the snap that puts us closest to the original scale */ + NR::Coord bd = bb.second ? fabs(bb.first - s[axis]) : NR_HUGE; + NR::Coord sd = sn.second ? fabs(sn.first - s[axis]) : NR_HUGE; + s[axis] = (bd < sd) ? bb.first : sn.first; + } + + pt = ( _point - _origin ) * NR::scale(s) + _origin; + if (isNaN(pt[X] + pt[Y])) { + g_warning("point=(%g, %g), norm=(%g, %g), s=(%g, %g)\n", + _point[X], _point[Y], _origin[X], _origin[Y], s[X], s[Y]); + } + + // status text + _message_context.setF(Inkscape::NORMAL_MESSAGE, + _("Scale: %0.2f%% x %0.2f%%; with Ctrl to lock ratio"), + 100 * s[NR::X], 100 * s[NR::Y]); + + return TRUE; +} + +gboolean Inkscape::SelTrans::skewRequest(SPSelTransHandle const &handle, NR::Point &pt, guint state) +{ + using NR::X; + using NR::Y; + + if (handle.cursor != GDK_SB_V_DOUBLE_ARROW && handle.cursor != GDK_SB_H_DOUBLE_ARROW) { + return FALSE; + } + + NR::Dim2 dim_a; + NR::Dim2 dim_b; + if (handle.cursor == GDK_SB_V_DOUBLE_ARROW) { + dim_a = X; + dim_b = Y; + } else { + dim_a = Y; + dim_b = X; + } + + double skew[2]; + double s[2] = { 1.0, 1.0 }; + + if (fabs(_point[dim_a] - _origin[dim_a]) < NR_EPSILON) { + return FALSE; + } + + skew[dim_a] = ( pt[dim_b] - _point[dim_b] ) / ( _point[dim_a] - _origin[dim_a] ); + + s[dim_a] = ( pt[dim_a] - _origin[dim_a] ) / ( _point[dim_a] - _origin[dim_a] ); + + if ( fabs(s[dim_a]) < 1 ) { + s[dim_a] = sign(s[dim_a]); + } else { + s[dim_a] = floor( s[dim_a] + 0.5 ); + } + + double radians = atan(skew[dim_a] / s[dim_a]); + + if (state & GDK_CONTROL_MASK) { + + int snaps = prefs_get_int_attribute("options.rotationsnapsperpi", "value", 12); + + if (snaps) { + double sections = floor( radians * snaps / M_PI + .5 ); + if (fabs(sections) >= snaps / 2) sections = sign(sections) * (snaps / 2 - 1); + radians = ( M_PI / snaps ) * sections; + } + skew[dim_a] = tan(radians) * s[dim_a]; + } else { + skew[dim_a] = namedview_dim_snap_list_skew(_desktop->namedview, + Snapper::SNAP_POINT, _snap_points, + _origin, skew[dim_a], dim_b); + } + + pt[dim_b] = ( _point[dim_a] - _origin[dim_a] ) * skew[dim_a] + _point[dim_b]; + pt[dim_a] = ( _point[dim_a] - _origin[dim_a] ) * s[dim_a] + _origin[dim_a]; + + /* status text */ + double degrees = 180 / M_PI * radians; + if (degrees > 180) degrees -= 360; + if (degrees < -180) degrees += 360; + + _message_context.setF(Inkscape::NORMAL_MESSAGE, + // TRANSLATORS: don't modify the first ";" + // (it will NOT be displayed as ";" - only the second one will be) + _("Skew: %0.2f°; with Ctrl to snap angle"), + degrees); + + return TRUE; +} + +gboolean Inkscape::SelTrans::rotateRequest(NR::Point &pt, guint state) +{ + int snaps = prefs_get_int_attribute("options.rotationsnapsperpi", "value", 12); + + // rotate affine in rotate + NR::Point const d1 = _point - _origin; + NR::Point const d2 = pt - _origin; + + NR::Coord const h1 = NR::L2(d1); + if (h1 < 1e-15) return FALSE; + NR::Point q1 = d1 / h1; + NR::Coord const h2 = NR::L2(d2); + if (fabs(h2) < 1e-15) return FALSE; + NR::Point q2 = d2 / h2; + + double radians; + if (state & GDK_CONTROL_MASK) { + /* Have to restrict movement. */ + double cos_t = NR::dot(q1, q2); + double sin_t = NR::dot(NR::rot90(q1), q2); + radians = atan2(sin_t, cos_t); + if (snaps) { + radians = ( M_PI / snaps ) * floor( radians * snaps / M_PI + .5 ); + } + q1 = NR::Point(1, 0); + q2 = NR::Point(cos(radians), sin(radians)); + } else { + radians = atan2(NR::dot(NR::rot90(d1), d2), + NR::dot(d1, d2)); + } + + NR::rotate const r1(q1); + NR::rotate const r2(q2); + pt = _point * NR::translate(-_origin) * ( r2 / r1 ) * NR::translate(_origin); + + /* status text */ + double degrees = 180 / M_PI * radians; + if (degrees > 180) degrees -= 360; + if (degrees < -180) degrees += 360; + + _message_context.setF(Inkscape::NORMAL_MESSAGE, + // TRANSLATORS: don't modify the first ";" + // (it will NOT be displayed as ";" - only the second one will be) + _("Rotate: %0.2f°; with Ctrl to snap angle"), degrees); + + return TRUE; +} + +gboolean Inkscape::SelTrans::centerRequest(NR::Point &pt, guint state) +{ + using NR::X; + using NR::Y; + + SnapManager const m(_desktop->namedview); + pt = m.freeSnap(Snapper::SNAP_POINT, pt, NULL).getPoint(); + + if (state & GDK_CONTROL_MASK) { + if ( fabs(_point[X] - pt[X]) > fabs(_point[Y] - pt[Y]) ) { + pt[Y] = _point[Y]; + } else { + pt[X] = _point[X]; + } + } + + Inkscape::Selection *selection = _desktop->selection; + Inkscape::XML::Node *current = selection->singleRepr(); + if (current != NULL){ + sp_repr_set_svg_double(current, "inkscape:c_rx", pt[X]); + sp_repr_set_svg_double(current, "inkscape:c_ry", pt[Y]); + + } + + if (!(state & GDK_SHIFT_MASK)) { + // screen pixels to snap center to bbox +#define SNAP_DIST 5 + // FIXME: take from prefs + double snap_dist = SNAP_DIST / _desktop->current_zoom(); + + for (int i = 0; i < 2; i++) { + + if (fabs(pt[i] - _box.min()[i]) < snap_dist) { + pt[i] = _box.min()[i]; + } + if (fabs(pt[i] - _box.midpoint()[i]) < snap_dist) { + pt[i] = _box.midpoint()[i]; + } + if (fabs(pt[i] - _box.max()[i]) < snap_dist) { + pt[i] = _box.max()[i]; + } + } + } + + // status text + GString *xs = SP_PX_TO_METRIC_STRING(pt[X], _desktop->namedview->getDefaultMetric()); + GString *ys = SP_PX_TO_METRIC_STRING(pt[Y], _desktop->namedview->getDefaultMetric()); + _message_context.setF(Inkscape::NORMAL_MESSAGE, _("Move center to %s, %s"), xs->str, ys->str); + g_string_free(xs, FALSE); + g_string_free(ys, FALSE); + + return TRUE; +} + +/* + * handlers for handle movement + * + */ + +void sp_sel_trans_stretch(Inkscape::SelTrans *seltrans, SPSelTransHandle const &handle, NR::Point &pt, guint state) +{ + seltrans->stretch(handle, pt, state); +} + +void sp_sel_trans_scale(Inkscape::SelTrans *seltrans, SPSelTransHandle const &, NR::Point &pt, guint state) +{ + seltrans->scale(pt, state); +} + +void sp_sel_trans_skew(Inkscape::SelTrans *seltrans, SPSelTransHandle const &handle, NR::Point &pt, guint state) +{ + seltrans->skew(handle, pt, state); +} + +void sp_sel_trans_rotate(Inkscape::SelTrans *seltrans, SPSelTransHandle const &, NR::Point &pt, guint state) +{ + seltrans->rotate(pt, state); +} + +void Inkscape::SelTrans::stretch(SPSelTransHandle const &handle, NR::Point &pt, guint state) +{ + using NR::X; + using NR::Y; + + NR::Dim2 dim; + switch (handle.cursor) { + case GDK_LEFT_SIDE: + case GDK_RIGHT_SIDE: + dim = X; + break; + case GDK_TOP_SIDE: + case GDK_BOTTOM_SIDE: + dim = Y; + break; + default: + g_assert_not_reached(); + abort(); + break; + } + + NR::Point const scale_origin(_origin); + double const offset = _point[dim] - scale_origin[dim]; + if (!( fabs(offset) >= 1e-15 )) { + return; + } + NR::scale s(1, 1); + s[dim] = ( pt[dim] - scale_origin[dim] ) / offset; + if (isNaN(s[dim])) { + g_warning("s[dim]=%g, pt[dim]=%g, scale_origin[dim]=%g, point[dim]=%g\n", + s[dim], pt[dim], scale_origin[dim], _point[dim]); + } + if (!( fabs(s[dim]) >= 1e-15 )) { + s[dim] = 1e-15; + } + if (state & GDK_CONTROL_MASK) { + /* Preserve aspect ratio, but never flip in the dimension not being edited. */ + s[!dim] = fabs(s[dim]); + } + + NR::Rect new_bbox = _box * (NR::translate(-scale_origin) * NR::Matrix(s) * NR::translate(scale_origin)); + + int transform_stroke = prefs_get_int_attribute ("options.transform", "stroke", 1); + NR::Matrix scaler = get_scale_transform_with_stroke (_box, _strokewidth, transform_stroke, + new_bbox.min()[NR::X], new_bbox.min()[NR::Y], new_bbox.max()[NR::X], new_bbox.max()[NR::Y]); + + transform(scaler, NR::Point(0, 0)); // we have already accounted for origin, so pass 0,0 +} + +void Inkscape::SelTrans::scale(NR::Point &pt, guint state) +{ + NR::Point const offset = _point - _origin; + + NR::scale s (1, 1); + for (int i = NR::X; i <= NR::Y; i++) { + if (fabs(offset[i]) > 1e-9) + s[i] = (pt[i] - _origin[i]) / offset[i]; + if (fabs(s[i]) < 1e-9) + s[i] = 1e-9; + } + NR::Rect new_bbox = _box * (NR::translate(-_origin) * NR::Matrix(s) * NR::translate(_origin)); + + int transform_stroke = prefs_get_int_attribute ("options.transform", "stroke", 1); + NR::Matrix scaler = get_scale_transform_with_stroke (_box, _strokewidth, transform_stroke, + new_bbox.min()[NR::X], new_bbox.min()[NR::Y], new_bbox.max()[NR::X], new_bbox.max()[NR::Y]); + + transform(scaler, NR::Point(0, 0)); // we have already accounted for origin, so pass 0,0 +} + +void Inkscape::SelTrans::skew(SPSelTransHandle const &handle, NR::Point &pt, guint state) +{ + NR::Point const offset = _point - _origin; + + unsigned dim; + switch (handle.cursor) { + case GDK_SB_H_DOUBLE_ARROW: + dim = NR::Y; + break; + case GDK_SB_V_DOUBLE_ARROW: + dim = NR::X; + break; + default: + g_assert_not_reached(); + abort(); + break; + } + if (fabs(offset[dim]) < 1e-15) { + return; + } + NR::Matrix skew = NR::identity(); + skew[2*dim + dim] = (pt[dim] - _origin[dim]) / offset[dim]; + skew[2*dim + (1-dim)] = (pt[1-dim] - _point[1-dim]) / offset[dim]; + skew[2*(1-dim) + (dim)] = 0; + skew[2*(1-dim) + (1-dim)] = 1; + + for (int i = 0; i < 2; i++) { + if (fabs(skew[3*i]) < 1e-15) { + skew[3*i] = 1e-15; + } + } + transform(skew, _origin); +} + +void Inkscape::SelTrans::rotate(NR::Point &pt, guint state) +{ + NR::Point const offset = _point - _origin; + + NR::Coord const h1 = NR::L2(offset); + if (h1 < 1e-15) { + return; + } + NR::Point const q1 = offset / h1; + NR::Coord const h2 = NR::L2( pt - _origin ); + if (h2 < 1e-15) { + return; + } + NR::Point const q2 = (pt - _origin) / h2; + NR::rotate const r1(q1); + NR::rotate const r2(q2); + + NR::Matrix rotate( r2 / r1 ); + transform(rotate, _origin); +} + +void sp_sel_trans_center(Inkscape::SelTrans *seltrans, SPSelTransHandle const &, NR::Point &pt, guint state) +{ + seltrans->setCenter(pt); +} + + +void Inkscape::SelTrans::moveTo(NR::Point const &xy, guint state) +{ + SnapManager const m(_desktop->namedview); + + /* The amount that we've moved by during this drag */ + NR::Point dxy = xy - _point; + + /* Get a STL list of the selected items. + ** FIXME: this should probably be done by Inkscape::Selection. + */ + std::list it; + for (GSList const *i = _selection->itemList(); i != NULL; i = i->next) { + it.push_back(reinterpret_cast(i->data)); + } + + bool const alt = (state & GDK_MOD1_MASK); + bool const control = (state & GDK_CONTROL_MASK); + bool const shift = (state & GDK_SHIFT_MASK); + + if (alt) { + + /* Alt pressed means keep offset: snap the moved distance to the grid. + ** FIXME: this will snap to more than just the grid, nowadays. + */ + + dxy = m.freeSnap(Snapper::SNAP_POINT, dxy, NULL).getPoint(); + + } else if (!shift) { + + /* We're snapping to things, possibly with a constraint to horizontal or + ** vertical movement. Obtain a list of possible translations and then + ** pick the smallest. + */ + + /* This will be our list of possible translations */ + std::list > s; + + if (control) { + + /* Snap to things, and also constrain to horizontal or vertical movement */ + + for (unsigned int dim = 0; dim < 2; dim++) { + s.push_back(m.constrainedSnapTranslation(Inkscape::Snapper::BBOX_POINT, + _bbox_points, + component_vectors[dim], it, dxy)); + s.push_back(m.constrainedSnapTranslation(Inkscape::Snapper::SNAP_POINT, + _snap_points, + component_vectors[dim], it, dxy)); + } + + } else { + + /* Snap to things with no constraint */ + + s.push_back(m.freeSnapTranslation(Inkscape::Snapper::BBOX_POINT, + _bbox_points, it, dxy)); + s.push_back(m.freeSnapTranslation(Inkscape::Snapper::SNAP_POINT, + _snap_points, it, dxy)); + } + + /* Pick one */ + NR::Coord best = NR_HUGE; + for (std::list >::const_iterator i = s.begin(); i != s.end(); i++) { + if (i->second) { + NR::Coord const m = NR::L2(i->first); + if (m < best) { + best = m; + dxy = i->first; + } + } + } + } + + if (control) { + /* Ensure that the horizontal and vertical constraint has been applied */ + if (fabs(dxy[NR::X]) > fabs(dxy[NR::Y])) { + dxy[NR::Y] = 0; + } else { + dxy[NR::X] = 0; + } + } + + NR::Matrix const move((NR::translate(dxy))); + NR::Point const norm(0, 0); + transform(move, norm); + + // status text + GString *xs = SP_PX_TO_METRIC_STRING(dxy[NR::X], _desktop->namedview->getDefaultMetric()); + GString *ys = SP_PX_TO_METRIC_STRING(dxy[NR::Y], _desktop->namedview->getDefaultMetric()); + _message_context.setF(Inkscape::NORMAL_MESSAGE, _("Move by %s, %s; with Ctrl to restrict to horizontal/vertical; with Shift to disable snapping"), xs->str, ys->str); + g_string_free(xs, TRUE); + g_string_free(ys, TRUE); +} + + +/* + 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 : diff --git a/src/seltrans.h b/src/seltrans.h new file mode 100644 index 000000000..30be58eeb --- /dev/null +++ b/src/seltrans.h @@ -0,0 +1,151 @@ +#ifndef __SELTRANS_H__ +#define __SELTRANS_H__ + +/* + * Helper object for transforming selected items + * + * Author: + * Lauris Kaplinski + * Carl Hetherington + * + * Copyright (C) 1999-2002 Lauris Kaplinski + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include +#include +#include +#include +#include "forward.h" +#include "selcue.h" +#include "message-context.h" +#include + +struct SPKnot; +class SPDesktop; +class SPCanvasItem; +class SPSelTransHandle; + +namespace Inkscape +{ + +namespace XML +{ + class Node; +} + +class SelTrans +{ +public: + SelTrans(SPDesktop *desktop); + ~SelTrans(); + + Inkscape::MessageContext &messageContext() { + return _message_context; + } + + void increaseState(); + void resetState(); + void setCenter(NR::Point const &p); + void grab(NR::Point const &p, gdouble x, gdouble y, bool show_handles); + void transform(NR::Matrix const &rel_affine, NR::Point const &norm); + void ungrab(); + void stamp(); + void moveTo(NR::Point const &xy, guint state); + void stretch(SPSelTransHandle const &handle, NR::Point &pt, guint state); + void scale(NR::Point &pt, guint state); + void skew(SPSelTransHandle const &handle, NR::Point &pt, guint state); + void rotate(NR::Point &pt, guint state); + gboolean scaleRequest(NR::Point &pt, guint state); + gboolean stretchRequest(SPSelTransHandle const &handle, NR::Point &pt, guint state); + gboolean skewRequest(SPSelTransHandle const &handle, NR::Point &pt, guint state); + gboolean rotateRequest(NR::Point &pt, guint state); + gboolean centerRequest(NR::Point &pt, guint state); + + gboolean handleRequest(SPKnot *knot, NR::Point *position, guint state, SPSelTransHandle const &handle); + void handleGrab(SPKnot *knot, guint state, SPSelTransHandle const &handle); + void handleNewEvent(SPKnot *knot, NR::Point *position, guint state, SPSelTransHandle const &handle); + + enum Show + { + SHOW_CONTENT, + SHOW_OUTLINE + }; + + void setShow(Show s) { + _show = s; + } + bool isEmpty() { + return _empty; + } + +private: + void _updateHandles(); + void _updateVolatileState(); + void _selChanged(Inkscape::Selection *selection); + void _selModified(Inkscape::Selection *selection, guint flags); + void _showHandles(SPKnot *knot[], SPSelTransHandle const handle[], gint num, + gchar const *even_tip, gchar const *odd_tip); + void _centreTrans(Inkscape::XML::Node *current) const; + + enum State { + STATE_SCALE, + STATE_ROTATE + }; + + SPDesktop *_desktop; + + std::vector > _items; + + std::vector _snap_points; + std::vector _bbox_points; + + Inkscape::SelCue _selcue; + + Inkscape::Selection *_selection; + State _state; + Show _show; + + bool _grabbed; + bool _show_handles; + bool _empty; + bool _changed; + + NR::Rect _box; + gdouble _strokewidth; + NR::Matrix _current; + NR::Point _opposite; ///< opposite point to where a scale is taking place + NR::Point _center; + SPKnot *_shandle[8]; + SPKnot *_rhandle[8]; + SPKnot *_chandle; + SPCanvasItem *_norm; + SPCanvasItem *_grip; + SPCanvasItem *_l[4]; + guint _sel_changed_id; + guint _sel_modified_id; + GSList *_stamp_cache; + + NR::Point _origin; ///< position of origin for transforms + NR::Point _point; ///< original position of the knot being used for the current transform + Inkscape::MessageContext _message_context; + SigC::Connection _sel_changed_connection; + SigC::Connection _sel_modified_connection; +}; + +} + +#endif + + +/* + 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 : diff --git a/src/shortcuts-default-xml.cpp b/src/shortcuts-default-xml.cpp new file mode 100644 index 000000000..e91f435e2 --- /dev/null +++ b/src/shortcuts-default-xml.cpp @@ -0,0 +1,243 @@ +extern char const shortcuts_default_xml[]= +"\n" +"\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +""; diff --git a/src/shortcuts.cpp b/src/shortcuts.cpp new file mode 100644 index 000000000..047928071 --- /dev/null +++ b/src/shortcuts.cpp @@ -0,0 +1,195 @@ +#define __SP_SHORTCUTS_C__ + +/** \file + * Keyboard shortcut processing. + */ +/* + * Authors: + * Lauris Kaplinski + * MenTaLguY + * bulia byak + * Peter Moulder + * + * Copyright (C) 2005 Monash University + * Copyright (C) 2005 MenTaLguY + * + * You may redistribute and/or modify this file under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include + +#include "helper/action.h" +#include "shortcuts.h" +#include "verbs.h" +#include "xml/node-iterators.h" +#include "xml/repr.h" + +using namespace Inkscape; + +static void sp_shortcut_set(unsigned int const shortcut, Inkscape::Verb *const verb, bool const is_primary); + +static void set_shortcuts_xml(XML::Document const *doc); + +/* Returns true if action was performed */ + +bool +sp_shortcut_invoke(unsigned int shortcut, Inkscape::UI::View::View *view) +{ + Inkscape::Verb *verb = sp_shortcut_get_verb(shortcut); + if (verb) { + SPAction *action = verb->get_action(view); + if (action) { + sp_action_perform(action, NULL); + return true; + } + } + return false; +} + +static GHashTable *verbs = NULL; +static GHashTable *primary_shortcuts = NULL; + +extern char const shortcuts_default_xml[]; + +static void +sp_shortcut_init() +{ + verbs = g_hash_table_new(NULL, NULL); + primary_shortcuts = g_hash_table_new(NULL, NULL); + + XML::Document *shortcuts=sp_repr_read_mem(shortcuts_default_xml, strlen(shortcuts_default_xml), NULL); + if (shortcuts) { + set_shortcuts_xml(shortcuts); + GC::release(shortcuts); + } else { + g_error("Unable to parse default shortcuts"); + } +} + +static void set_shortcuts_xml(XML::Document const *doc) { + XML::Node const *root=doc->root(); + g_return_if_fail(!strcmp(root->name(), "keybindings")); + XML::NodeConstSiblingIterator iter=root->firstChild(); + for ( ; iter ; ++iter ) { + bool is_primary; + + if (!strcmp(iter->name(), "primary")) { + is_primary = true; + } else if (!strcmp(iter->name(), "secondary")) { + is_primary = false; + } else { + g_warning("Unknown key binding type %s", iter->name()); + continue; + } + + gchar const *verb_name=iter->attribute("verb"); + if (!verb_name) { + g_warning("Missing verb name for shortcut"); + continue; + } + + gchar const *keyval_name=iter->attribute("keyval"); + if (!keyval_name) { + g_warning("Missing keyval for %s", verb_name); + continue; + } + guint keyval=gdk_keyval_from_name(keyval_name); + if (keyval == GDK_VoidSymbol) { + g_warning("Unknown keyval %s for %s", keyval_name, verb_name); + continue; + } + + guint modifiers=0; + + gchar const *modifiers_string=iter->attribute("modifiers"); + if (modifiers_string) { + gchar const *iter=modifiers_string; + while (*iter) { + size_t length=strcspn(iter, ","); + gchar *mod=g_strndup(iter, length); + if (!strcmp(mod, "control")) { + modifiers |= SP_SHORTCUT_CONTROL_MASK; + } else if (!strcmp(mod, "shift")) { + modifiers |= SP_SHORTCUT_SHIFT_MASK; + } else if (!strcmp(mod, "alt")) { + modifiers |= SP_SHORTCUT_ALT_MASK; + } else { + g_warning("Unknown modifier %s for %s", mod, verb_name); + } + g_free(mod); + iter += length; + if (*iter) iter++; + } + } + + sp_shortcut_set(keyval | modifiers, + Inkscape::Verb::getbyid(verb_name), + is_primary); + } +} + +/** + * Adds a keyboard shortcut for the given verb. + * (Removes any existing binding for the given shortcut, including appropriately + * adjusting sp_shortcut_get_primary if necessary.) + * + * \param is_primary True iff this is the shortcut to be written in menu items or buttons. + * + * \post sp_shortcut_get_verb(shortcut) == verb. + * \post !is_primary or sp_shortcut_get_primary(verb) == shortcut. + */ +static void +sp_shortcut_set(unsigned int const shortcut, Inkscape::Verb *const verb, bool const is_primary) +{ + if (!verbs) sp_shortcut_init(); + + Inkscape::Verb *old_verb = (Inkscape::Verb *)(g_hash_table_lookup(verbs, GINT_TO_POINTER(shortcut))); + g_hash_table_insert(verbs, GINT_TO_POINTER(shortcut), (gpointer)(verb)); + + /* Maintain the invariant that sp_shortcut_get_primary(v) returns either 0 or a valid shortcut for v. */ + if (old_verb && old_verb != verb) { + unsigned int const old_primary = (unsigned int)GPOINTER_TO_INT(g_hash_table_lookup(primary_shortcuts, (gpointer)old_verb)); + + if (old_primary == shortcut) { + g_hash_table_insert(primary_shortcuts, (gpointer)old_verb, GINT_TO_POINTER(0)); + } + } + + if (is_primary) { + g_hash_table_insert(primary_shortcuts, (gpointer)(verb), GINT_TO_POINTER(shortcut)); + } +} + +Inkscape::Verb * +sp_shortcut_get_verb(unsigned int shortcut) +{ + if (!verbs) sp_shortcut_init(); + return (Inkscape::Verb *)(g_hash_table_lookup(verbs, GINT_TO_POINTER(shortcut))); +} + +unsigned int +sp_shortcut_get_primary(Inkscape::Verb *verb) +{ + if (!primary_shortcuts) sp_shortcut_init(); + return (unsigned int)GPOINTER_TO_INT(g_hash_table_lookup(primary_shortcuts, + (gpointer)(verb))); +} + + +/* + 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:textwidth=99 : diff --git a/src/shortcuts.h b/src/shortcuts.h new file mode 100644 index 000000000..8ce0f7685 --- /dev/null +++ b/src/shortcuts.h @@ -0,0 +1,39 @@ +#ifndef __SP_SHORTCUTS_H__ +#define __SP_SHORTCUTS_H__ + +/* + * Keyboard shortcut processing + * + * Author: + * Lauris Kaplinski + * + * This code is in public domain + */ + +#include + + +/* We define high-bit mask for packing into single int */ + +#define SP_SHORTCUT_SHIFT_MASK (1 << 24) +#define SP_SHORTCUT_CONTROL_MASK (1 << 25) +#define SP_SHORTCUT_ALT_MASK (1 << 26) + +/* Returns true if action was performed */ +bool sp_shortcut_invoke (unsigned int shortcut, Inkscape::UI::View::View *view); + +Inkscape::Verb * sp_shortcut_get_verb (unsigned int shortcut); +unsigned int sp_shortcut_get_primary (Inkscape::Verb * verb); + +#endif + +/* + 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:textwidth=99 : diff --git a/src/slideshow.cpp b/src/slideshow.cpp new file mode 100644 index 000000000..d2bb39790 --- /dev/null +++ b/src/slideshow.cpp @@ -0,0 +1,105 @@ +#define __SLIDESHOW_C__ + +/* + * Help/About window + * + * Authors: + * Lauris Kaplinski + * + * Copyright (C) 1999-2003 authors + * Copyright (C) 2000-2002 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include + +#include +#include "document.h" +#include "svg-view-widget.h" +#include "svg-view.h" + +static gint +sp_slideshow_event (SPViewWidget *vw, GdkEvent *event, GtkWidget *window) +{ + GSList *slides; + const gchar *fname, *nname; + int idx; + + slides = (GSList*)g_object_get_data (G_OBJECT (window), "slides"); + fname = (const gchar*)g_object_get_data (G_OBJECT (window), "current"); + idx = g_slist_index (slides, fname); + + switch (event->type) { + case GDK_KEY_PRESS: + switch (event->key.keyval) { + case GDK_BackSpace: + case GDK_Delete: + case GDK_Left: + idx -= 1; + break; + case GDK_Escape: + gtk_widget_destroy (window); + return TRUE; + break; + default: + idx += 1; + break; + } + break; + case GDK_BUTTON_PRESS: + idx += 1; + break; + default: + break; + } + + nname = (const gchar*)g_slist_nth_data (slides, idx); + g_print ("Old %s new %s\n", fname, nname); + + if (nname && (nname != fname)) { + SPDocument *doc; + g_print ("Trying to load\n"); + doc = sp_document_new (nname, TRUE); + if (doc) { + reinterpret_cast(SP_VIEW_WIDGET_VIEW (vw))->setDocument (doc); + sp_document_unref (doc); + } + g_object_set_data (G_OBJECT (window), "current", (gpointer) nname); + } + + return TRUE; +} + +GtkWidget * +sp_slideshow_new (const GSList *files) +{ + SPDocument *doc; + GtkWidget *w, *v; + + doc = sp_document_new ((const gchar*)files->data, TRUE); + g_return_val_if_fail (doc != NULL, NULL); + + w = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_window_set_title (GTK_WINDOW (w), _("Inkscape slideshow")); + gtk_window_set_default_size (GTK_WINDOW (w), 480, 360); + gtk_window_set_policy (GTK_WINDOW (w), TRUE, TRUE, FALSE); + + v = sp_svg_view_widget_new (doc); + sp_svg_view_widget_set_resize (SP_SVG_VIEW_WIDGET (v), FALSE, sp_document_width (doc), sp_document_height (doc)); + sp_document_unref (doc); + gtk_widget_show (v); + gtk_container_add (GTK_CONTAINER (w), v); + + g_object_set_data (G_OBJECT (w), "slides", (gpointer) files); + g_object_set_data (G_OBJECT (w), "current", files->data); + + g_signal_connect (G_OBJECT (v), "event", G_CALLBACK (sp_slideshow_event), w); + + return w; +} diff --git a/src/slideshow.h b/src/slideshow.h new file mode 100644 index 000000000..0aa236bcc --- /dev/null +++ b/src/slideshow.h @@ -0,0 +1,31 @@ +#ifndef __SP_SLIDESHOW_H__ +#define __SP_SLIDESHOW_H__ + +/* + * Slideshow/About window + * + * Authors: + * Lauris Kaplinski + * + * Copyright (C) 1999-2003 authors + * Copyright (C) 2000-2002 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include + +GtkWidget *sp_slideshow_new (const GSList *files); + +#endif + +/* + 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:textwidth=99 : diff --git a/src/snap.cpp b/src/snap.cpp new file mode 100644 index 000000000..b14549db3 --- /dev/null +++ b/src/snap.cpp @@ -0,0 +1,406 @@ +#define __SP_DESKTOP_SNAP_C__ + +/** + * \file snap.cpp + * + * \brief Various snapping methods + * + * Authors: + * Lauris Kaplinski + * Frank Felfe + * Carl Hetherington + * + * Copyright (C) 1999-2002 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "sp-namedview.h" +#include "snap.h" +#include +#include +#include + + +/** + * \return true if one of the snappers will try to snap something. + */ +bool SnapManager::willSnapSomething() const +{ + SPNamedView::SnapperList s = namedview->getSnappers(); + SPNamedView::SnapperList::const_iterator i = s.begin(); + while (i != s.end() && (*i)->willSnapSomething() == false) { + i++; + } + + return (i != s.end()); +} + + +/* FIXME: lots of cut-and-paste here. This needs some +** functor voodoo to cut it all down a bit. +*/ + +Inkscape::SnappedPoint SnapManager::freeSnap(Inkscape::Snapper::PointType t, + NR::Point const &p, + SPItem const *it) const + +{ + std::list lit; + lit.push_back(it); + return freeSnap(t, p, lit); +} + + +Inkscape::SnappedPoint SnapManager::freeSnap(Inkscape::Snapper::PointType t, + NR::Point const &p, + std::list const &it) const +{ + Inkscape::SnappedPoint r(p, NR_HUGE); + + SPNamedView::SnapperList snappers = namedview->getSnappers(); + for (SPNamedView::SnapperList::const_iterator i = snappers.begin(); i != snappers.end(); i++) { + Inkscape::SnappedPoint const s = (*i)->freeSnap(t, p, it); + if (s.getDistance() < r.getDistance()) { + r = s; + } + } + + return r; +} + + +Inkscape::SnappedPoint SnapManager::constrainedSnap(Inkscape::Snapper::PointType t, + NR::Point const &p, + NR::Point const &c, + SPItem const *it) const +{ + std::list lit; + lit.push_back(it); + return constrainedSnap(t, p, c, lit); +} + + +Inkscape::SnappedPoint SnapManager::constrainedSnap(Inkscape::Snapper::PointType t, + NR::Point const &p, + NR::Point const &c, + std::list const &it) const +{ + Inkscape::SnappedPoint r(p, NR_HUGE); + + SPNamedView::SnapperList snappers = namedview->getSnappers(); + for (SPNamedView::SnapperList::const_iterator i = snappers.begin(); i != snappers.end(); i++) { + Inkscape::SnappedPoint const s = (*i)->constrainedSnap(t, p, c, it); + if (s.getDistance() < r.getDistance()) { + r = s; + } + } + + return r; +} + + +std::pair SnapManager::freeSnapTranslation(Inkscape::Snapper::PointType t, + std::vector const &p, + std::list const &it, + NR::Point const &tr) const +{ + if (willSnapSomething() == false) { + return std::make_pair(tr, false); + } + + NR::Point best_translation = tr; + NR::Coord best_distance = NR_HUGE; + + for (std::vector::const_iterator i = p.begin(); i != p.end(); i++) { + /* Translated version of this point */ + NR::Point const q = *i + tr; + /* Snap it */ + Inkscape::SnappedPoint s = freeSnap(t, q, it); + if (s.getDistance() < NR_HUGE) { + /* Resulting translation */ + NR::Point const r = s.getPoint() - *i; + NR::Coord const d = NR::L2(r); + if (d < best_distance) { + best_distance = d; + best_translation = r; + } + } + } + + return std::make_pair(best_translation, best_distance < NR_HUGE); +} + + + +std::pair SnapManager::constrainedSnapTranslation(Inkscape::Snapper::PointType t, + std::vector const &p, + NR::Point const &c, + std::list const &it, + NR::Point const &tr) const +{ + if (willSnapSomething() == false) { + return std::make_pair(tr, false); + } + + NR::Point best_translation = tr; + NR::Coord best_distance = NR_HUGE; + + for (std::vector::const_iterator i = p.begin(); i != p.end(); i++) { + /* Translated version of this point */ + NR::Point const q = *i + tr; + /* Snap it */ + Inkscape::SnappedPoint s = constrainedSnap(t, q, c, it); + if (s.getDistance() < NR_HUGE) { + /* Resulting translation */ + NR::Point const r = s.getPoint() - *i; + NR::Coord const d = NR::L2(r); + if (d < best_distance) { + best_distance = d; + best_translation = r; + } + } + } + + return std::make_pair(best_translation, best_distance < NR_HUGE); +} + + + + + + +/// Minimal distance to norm before point is considered for snap. +static const double MIN_DIST_NORM = 1.0; + +/** + * Try to snap \a req in one dimension. + * + * \param nv NamedView to use. + * \param req Point to snap; updated to the snapped point if a snap occurred. + * \param dim Dimension to snap in. + * \return Distance to the snap point along the \a dim axis, or \c NR_HUGE + * if no snap occurred. + */ +NR::Coord namedview_dim_snap(SPNamedView const *nv, Inkscape::Snapper::PointType t, NR::Point &req, + NR::Dim2 const dim, SPItem const *it) +{ + return namedview_vector_snap(nv, t, req, component_vectors[dim], it); +} + +NR::Coord namedview_dim_snap(SPNamedView const *nv, Inkscape::Snapper::PointType t, NR::Point &req, + NR::Dim2 const dim, std::list const &it) +{ + return namedview_vector_snap(nv, t, req, component_vectors[dim], it); +} + + +NR::Coord namedview_vector_snap(SPNamedView const *nv, Inkscape::Snapper::PointType t, + NR::Point &req, NR::Point const &d, + SPItem const *it) +{ + std::list lit; + lit.push_back(it); + return namedview_vector_snap(nv, t, req, d, lit); +} + +/** + * Look for snap point along the line described by the point \a req + * and the direction vector \a d. + * Modifies req to the snap point, if one is found. + * \return The distance from \a req to the snap point along the vector \a d, + * or \c NR_HUGE if no snap point was found. + * + * \pre d â‰  (0, 0). + */ +NR::Coord namedview_vector_snap(SPNamedView const *nv, Inkscape::Snapper::PointType t, + NR::Point &req, NR::Point const &d, + std::list const &it) +{ + g_assert(nv != NULL); + g_assert(SP_IS_NAMEDVIEW(nv)); + + SPNamedView::SnapperList snappers = nv->getSnappers(); + + NR::Coord best = NR_HUGE; + for (SPNamedView::SnapperList::const_iterator i = snappers.begin(); i != snappers.end(); i++) { + Inkscape::SnappedPoint const s = (*i)->constrainedSnap(t, req, d, it); + if (s.getDistance() < best) { + req = s.getPoint(); + best = s.getDistance(); + } + } + + return best; +} + + +/* + * functions for lists of points + * + * All functions take a list of NR::Point and parameter indicating the proposed transformation. + * They return the updated transformation parameter. + */ + +/** + * Snap list of points in one dimension. + * \return Coordinate difference. + */ +std::pair namedview_dim_snap_list(SPNamedView const *nv, Inkscape::Snapper::PointType t, + const std::vector &p, + NR::Coord const dx, NR::Dim2 const dim, + std::list const &it + ) +{ + NR::Coord dist = NR_HUGE; + NR::Coord xdist = dx; + + SnapManager const m(nv); + + if (m.willSnapSomething()) { + for (std::vector::const_iterator i = p.begin(); i != p.end(); i++) { + NR::Point q = *i; + NR::Coord const pre = q[dim]; + q[dim] += dx; + NR::Coord const d = namedview_dim_snap(nv, t, q, dim, it); + if (d < dist) { + xdist = q[dim] - pre; + dist = d; + } + } + } + + return std::make_pair(xdist, dist < NR_HUGE); +} + +/** + * Snap list of points in two dimensions. + */ +std::pair namedview_vector_snap_list(SPNamedView const *nv, Inkscape::Snapper::PointType t, + const std::vector &p, NR::Point const &norm, + NR::scale const &s, std::list const &it) +{ + using NR::X; + using NR::Y; + + SnapManager const m(nv); + + if (m.willSnapSomething() == false) { + return std::make_pair(s[X], false); + } + + NR::Coord dist = NR_HUGE; + double ratio = fabs(s[X]); + for (std::vector::const_iterator i = p.begin(); i != p.end(); i++) { + NR::Point const &q = *i; + NR::Point check = ( q - norm ) * s + norm; + if (NR::LInfty( q - norm ) > MIN_DIST_NORM) { + NR::Coord d = namedview_vector_snap(nv, t, check, check - norm, it); + if (d < dist) { + dist = d; + NR::Dim2 const dominant = ( ( fabs( q[X] - norm[X] ) > + fabs( q[Y] - norm[Y] ) ) + ? X + : Y ); + ratio = ( ( check[dominant] - norm[dominant] ) + / ( q[dominant] - norm[dominant] ) ); + } + } + } + + return std::make_pair(ratio, dist < NR_HUGE); +} + + +/** + * Try to snap points in \a p after they have been scaled by \a sx with respect to + * the origin \a norm. The best snap is the one that changes the scale least. + * + * \return Pair containing snapped scale and a flag which is true if a snap was made. + */ +std::pair namedview_dim_snap_list_scale(SPNamedView const *nv, Inkscape::Snapper::PointType t, + const std::vector &p, NR::Point const &norm, + double const sx, NR::Dim2 dim, + std::list const &it) +{ + SnapManager const m(nv); + if (m.willSnapSomething() == false) { + return std::make_pair(sx, false); + } + + g_assert(dim < 2); + + NR::Coord dist = NR_HUGE; + double scale = sx; + + for (std::vector::const_iterator i = p.begin(); i != p.end(); i++) { + NR::Point q = *i; + NR::Point check = q; + + /* Scaled version of the point we are looking at */ + check[dim] = (sx * (q - norm) + norm)[dim]; + + if (fabs (q[dim] - norm[dim]) > MIN_DIST_NORM) { + /* Snap this point */ + const NR::Coord d = namedview_dim_snap (nv, t, check, dim, it); + /* Work out the resulting scale factor */ + double snapped_scale = (check[dim] - norm[dim]) / (q[dim] - norm[dim]); + + if (dist == NR_HUGE || fabs(snapped_scale - sx) < fabs(scale - sx)) { + /* This is either the first point, or the snapped scale + ** is the closest yet to the original. + */ + scale = snapped_scale; + dist = d; + } + } + } + + return std::make_pair(scale, dist < NR_HUGE); +} + +/** + * Try to snap points after they have been skewed. + */ +double namedview_dim_snap_list_skew(SPNamedView const *nv, Inkscape::Snapper::PointType t, + const std::vector &p, NR::Point const &norm, + double const sx, NR::Dim2 const dim) +{ + SnapManager const m(nv); + + if (m.willSnapSomething() == false) { + return sx; + } + + g_assert(dim < 2); + + gdouble dist = NR_HUGE; + gdouble skew = sx; + + for (std::vector::const_iterator i = p.begin(); i != p.end(); i++) { + NR::Point q = *i; + NR::Point check = q; + // apply shear + check[dim] += sx * (q[!dim] - norm[!dim]); + if (fabs (q[!dim] - norm[!dim]) > MIN_DIST_NORM) { + const gdouble d = namedview_dim_snap (nv, t, check, dim, NULL); + if (d < fabs (dist)) { + dist = d; + skew = (check[dim] - q[dim]) / (q[!dim] - norm[!dim]); + } + } + } + + return skew; +} + +/* + 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:textwidth=99 : diff --git a/src/snap.h b/src/snap.h new file mode 100644 index 000000000..6b94fb4c2 --- /dev/null +++ b/src/snap.h @@ -0,0 +1,114 @@ +#ifndef SEEN_SNAP_H +#define SEEN_SNAP_H + +/** + * \file snap.h + * \brief Various snapping methods. + * + * Authors: + * Lauris Kaplinski + * Frank Felfe + * Carl Hetherington + * + * Copyright (C) 2000-2002 Lauris Kaplinski + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include + +#include +#include +#include +#include "snapper.h" + +class SPNamedView; + +class SnapManager +{ +public: + SnapManager(SPNamedView const *v) : namedview(v) {} + + bool willSnapSomething() const; + + Inkscape::SnappedPoint freeSnap(Inkscape::Snapper::PointType t, + NR::Point const &p, + SPItem const *it) const; + + Inkscape::SnappedPoint freeSnap(Inkscape::Snapper::PointType t, + NR::Point const &p, + std::list const &it) const; + + Inkscape::SnappedPoint constrainedSnap(Inkscape::Snapper::PointType t, + NR::Point const &p, + NR::Point const &c, + SPItem const *it) const; + + Inkscape::SnappedPoint constrainedSnap(Inkscape::Snapper::PointType t, + NR::Point const &p, + NR::Point const &c, + std::list const &it) const; + + std::pair freeSnapTranslation(Inkscape::Snapper::PointType t, + std::vector const &p, + std::list const &it, + NR::Point const &tr) const; + + std::pair constrainedSnapTranslation(Inkscape::Snapper::PointType t, + std::vector const &p, + NR::Point const &c, + std::list const &it, + NR::Point const &tr) const; + +private: + SPNamedView const *namedview; +}; + + +/* Single point methods */ +NR::Coord namedview_vector_snap(SPNamedView const *nv, Inkscape::Snapper::PointType t, NR::Point &req, + NR::Point const &d, std::list const &it); +NR::Coord namedview_vector_snap(SPNamedView const *nv, Inkscape::Snapper::PointType t, NR::Point &req, + NR::Point const &d, SPItem const *it); +NR::Coord namedview_dim_snap(SPNamedView const *nv, Inkscape::Snapper::PointType t, NR::Point& req, + NR::Dim2 const dim, SPItem const *it); +NR::Coord namedview_dim_snap(SPNamedView const *nv, Inkscape::Snapper::PointType t, NR::Point& req, + NR::Dim2 const dim, std::list const &it); + +/* List of points methods */ + +std::pair namedview_vector_snap_list(SPNamedView const *nv, + Inkscape::Snapper::PointType t, const std::vector &p, + NR::Point const &norm, NR::scale const &s, + std::list const &it + ); + +std::pair namedview_dim_snap_list(SPNamedView const *nv, + Inkscape::Snapper::PointType t, const std::vector &p, + double const dx, NR::Dim2 const dim, + std::list const &it + ); + +std::pair namedview_dim_snap_list_scale(SPNamedView const *nv, + Inkscape::Snapper::PointType t, const std::vector &p, + NR::Point const &norm, double const sx, + NR::Dim2 const dim, + std::list const &it); + +NR::Coord namedview_dim_snap_list_skew(SPNamedView const *nv, Inkscape::Snapper::PointType t, + const std::vector &p, + NR::Point const &norm, double const sx, NR::Dim2 const dim); + + +#endif /* !SEEN_SNAP_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 : diff --git a/src/snapped-point.cpp b/src/snapped-point.cpp new file mode 100644 index 000000000..3aebb086a --- /dev/null +++ b/src/snapped-point.cpp @@ -0,0 +1,61 @@ +/** + * \file src/snapped-point.cpp + * \brief SnappedPoint class. + * + * Authors: + * Mathieu Dimanche + * + * Released under GNU GPL, read the file 'COPYING' for more information. + */ + +#include "snapped-point.h" + +Inkscape::SnappedPoint::SnappedPoint(NR::Point p, NR::Coord d) + : _distance(d), _point(p) +{ + +} + +Inkscape::SnappedPoint::~SnappedPoint() +{ + /// TODO : empty the _hightlight_groups vector and destroy the + /// HighlightGroup items it holds +} + + +void Inkscape::SnappedPoint::addHighlightGroup(HighlightGroup *group) +{ + /// TODO +} + +void Inkscape::SnappedPoint::addHighlightGroups(std::vector *groups) +{ + /// TODO +} + +NR::Coord Inkscape::SnappedPoint::getDistance() const +{ + return _distance; +} + +NR::Point Inkscape::SnappedPoint::getPoint() const +{ + return _point; +} + +std::vector Inkscape::SnappedPoint::getHighlightGroups() const +{ + return _hightlight_groups; +} + + +/* + 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 : diff --git a/src/snapped-point.h b/src/snapped-point.h new file mode 100644 index 000000000..89eceb991 --- /dev/null +++ b/src/snapped-point.h @@ -0,0 +1,56 @@ +#ifndef SEEN_SNAPPEDPOINT_H +#define SEEN_SNAPPEDPOINT_H + +/** + * \file src/snapped-point.h + * \brief SnappedPoint class. + * + * Authors: + * Mathieu Dimanche + * + * Released under GNU GPL, read the file 'COPYING' for more information. + */ + +#include +#include "libnr/nr-coord.h" +#include "libnr/nr-point.h" + +namespace Inkscape +{ + +class HighlightGroup; + +/// Class describing the result of an attempt to snap. +class SnappedPoint +{ +public: + SnappedPoint() {} + SnappedPoint(NR::Point p, NR::Coord d); + ~SnappedPoint(); + + void addHighlightGroup(HighlightGroup *group); + void addHighlightGroups(std::vector *groups); + + NR::Coord getDistance() const; + NR::Point getPoint() const; + std::vector getHighlightGroups() const; + +private: + NR::Coord _distance; + NR::Point _point; + std::vector _hightlight_groups; +}; + +} +#endif /* !SEEN_SNAPPEDPOINT_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 : diff --git a/src/snapper.cpp b/src/snapper.cpp new file mode 100644 index 000000000..27531b50b --- /dev/null +++ b/src/snapper.cpp @@ -0,0 +1,180 @@ +/** + * \file src/snapper.cpp + * \brief Snapper class. + * + * Authors: + * Carl Hetherington + * + * Released under GNU GPL, read the file 'COPYING' for more information. + */ + +#include "libnr/nr-values.h" +#include "sp-namedview.h" + +Inkscape::Snapper::PointType const Inkscape::Snapper::BBOX_POINT = 0x1; +Inkscape::Snapper::PointType const Inkscape::Snapper::SNAP_POINT = 0x2; + +/** + * Construct new Snapper for named view. + * \param nv Named view. + * \param d Snap distance. + */ +Inkscape::Snapper::Snapper(SPNamedView const *nv, NR::Coord const d) : _named_view(nv), _distance(d) +{ + g_assert(_named_view != NULL); + g_assert(SP_IS_NAMEDVIEW(_named_view)); + + setSnapTo(BBOX_POINT, true); +} + +/** + * Set snap distance. + * \param d New snap distance (desktop coordinates) + */ +void Inkscape::Snapper::setDistance(NR::Coord const d) +{ + _distance = d; +} + +/** + * \return Snap distance (desktop coordinates) + */ +NR::Coord Inkscape::Snapper::getDistance() const +{ + return _distance; +} + +/** + * Turn on/off snapping of specific point types. + * \param t Point type. + * \param s true to snap to this point type, otherwise false; + */ +void Inkscape::Snapper::setSnapTo(PointType t, bool s) +{ + if (s) { + _snap_to |= t; + } else { + _snap_to &= ~t; + } +} + +/** + * \param t Point type. + * \return true if snapper will snap this type of point, otherwise false. + */ +bool Inkscape::Snapper::getSnapTo(PointType t) const +{ + return (_snap_to & t); +} + +/** + * \return true if this Snapper will snap at least one kind of point. + */ +bool Inkscape::Snapper::willSnapSomething() const +{ + return (_snap_to != 0); +} + + + +/** + * Try to snap a point to whatever this snapper is interested in. Any + * snap that occurs will be to the nearest "interesting" thing (e.g. a + * grid or guide line) + * + * \param t Point type. + * \param p Point to snap (desktop coordinates). + * \param it Item that should not be snapped to. + * \return Snapped point. + */ + +Inkscape::SnappedPoint Inkscape::Snapper::freeSnap(PointType t, + NR::Point const &p, + SPItem const *it) const +{ + std::list lit; + lit.push_back(it); + return freeSnap(t, p, lit); +} + + +/** + * Try to snap a point to whatever this snapper is interested in. Any + * snap that occurs will be to the nearest "interesting" thing (e.g. a + * grid or guide line) + * + * \param t Point type. + * \param p Point to snap (desktop coordinates). + * \param it Items that should not be snapped to. + * \return Snapped point. + */ + +Inkscape::SnappedPoint Inkscape::Snapper::freeSnap(PointType t, + NR::Point const &p, + std::list const &it) const +{ + if (getSnapTo(t) == false) { + return SnappedPoint(p, NR_HUGE); + } + + return _doFreeSnap(p, it); +} + + + + +/** + * Try to snap a point to whatever this snapper is interested in, where + * the snap point is constrained to lie along a specified vector from the + * original point. + * + * \param p Point to snap (desktop coordinates). + * \param c Vector to constrain the snap to. + * \param it Items that should not be snapped to. + * \return Snapped point. + */ + +Inkscape::SnappedPoint Inkscape::Snapper::constrainedSnap(PointType t, + NR::Point const &p, + NR::Point const &c, + SPItem const *it) const +{ + std::list lit; + lit.push_back(it); + return constrainedSnap(t, p, c, lit); +} + + +/** + * Try to snap a point to whatever this snapper is interested in, where + * the snap point is constrained to lie along a specified vector from the + * original point. + * + * \param p Point to snap (desktop coordinates). + * \param c Vector to constrain the snap to. + * \param it Items that should not be snapped to. + * \return Snapped point. + */ + +Inkscape::SnappedPoint Inkscape::Snapper::constrainedSnap(PointType t, + NR::Point const &p, + NR::Point const &c, + std::list const &it) const +{ + if (getSnapTo(t) == false) { + return SnappedPoint(p, NR_HUGE); + } + + return _doConstrainedSnap(p, c, it); +} + +/* + 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 : diff --git a/src/snapper.h b/src/snapper.h new file mode 100644 index 000000000..4c71be7f2 --- /dev/null +++ b/src/snapper.h @@ -0,0 +1,113 @@ +#ifndef SEEN_SNAPPER_H +#define SEEN_SNAPPER_H + +/** + * \file src/snapper.h + * \brief Snapper class. + * + * Authors: + * Carl Hetherington + * + * Released under GNU GPL, read the file 'COPYING' for more information. + */ + +#include +#include +#include "libnr/nr-coord.h" +#include "libnr/nr-point.h" +#include "snapped-point.h" + +struct SPNamedView; +struct SPItem; + +namespace Inkscape +{ + +/// Parent for classes that can snap points to something +class Snapper +{ +public: + Snapper(SPNamedView const *nv, NR::Coord const d); + virtual ~Snapper() {} + + /// Point types to snap. + typedef int PointType; + static const PointType SNAP_POINT; + static const PointType BBOX_POINT; + + typedef std::pair PointWithType; + + void setSnapTo(PointType t, bool s); + void setDistance(NR::Coord d); + + bool getSnapTo(PointType t) const; + NR::Coord getDistance() const; + + bool willSnapSomething() const; + + SnappedPoint freeSnap(PointType t, + NR::Point const &p, + SPItem const *it) const; + + SnappedPoint freeSnap(PointType t, + NR::Point const &p, + std::list const &it) const; + + SnappedPoint constrainedSnap(PointType t, + NR::Point const &p, + NR::Point const &c, + SPItem const *it) const; + + SnappedPoint constrainedSnap(PointType t, + NR::Point const &p, + NR::Point const &c, + std::list const &it) const; +protected: + SPNamedView const *_named_view; + +private: + + /** + * Try to snap a point to whatever this snapper is interested in. Any + * snap that occurs will be to the nearest "interesting" thing (e.g. a + * grid or guide line) + * + * \param p Point to snap (desktop coordinates). + * \param it Items that should not be snapped to. + * \return Snapped point. + */ + virtual SnappedPoint _doFreeSnap(NR::Point const &p, + std::list const &it) const = 0; + + /** + * Try to snap a point to whatever this snapper is interested in, where + * the snap point is constrained to lie along a specified vector from the + * original point. + * + * \param p Point to snap (desktop coordinates). + * \param c Vector to constrain the snap to. + * \param it Items that should not be snapped to. + * \return Snapped point. + */ + virtual SnappedPoint _doConstrainedSnap(NR::Point const &p, + NR::Point const &c, + std::list const &it) const = 0; + + NR::Coord _distance; ///< snap distance (desktop coordinates) + int _snap_to; ///< bitmap of point types that we will snap to +}; + +} + +#endif /* !SEEN_SNAPPER_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 : diff --git a/src/sp-anchor.cpp b/src/sp-anchor.cpp new file mode 100644 index 000000000..5d61d543b --- /dev/null +++ b/src/sp-anchor.cpp @@ -0,0 +1,220 @@ +#define __SP_ANCHOR_C__ + +/* + * SVG element implementation + * + * Author: + * Lauris Kaplinski + * + * Copyright (C) 2001-2002 Lauris Kaplinski + * Copyright (C) 2001 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#define noSP_ANCHOR_VERBOSE + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include "xml/quote.h" +#include "xml/repr.h" +#include "attributes.h" +#include "sp-anchor.h" +#include "ui/view/view.h" + +static void sp_anchor_class_init(SPAnchorClass *ac); +static void sp_anchor_init(SPAnchor *anchor); + +static void sp_anchor_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr); +static void sp_anchor_release(SPObject *object); +static void sp_anchor_set(SPObject *object, unsigned int key, const gchar *value); +static Inkscape::XML::Node *sp_anchor_write(SPObject *object, Inkscape::XML::Node *repr, guint flags); + +static gchar *sp_anchor_description(SPItem *item); +static gint sp_anchor_event(SPItem *item, SPEvent *event); + +static SPGroupClass *parent_class; + +GType sp_anchor_get_type(void) +{ + static GType type = 0; + + if (!type) { + GTypeInfo info = { + sizeof(SPAnchorClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) sp_anchor_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof(SPAnchor), + 16, /* n_preallocs */ + (GInstanceInitFunc) sp_anchor_init, + NULL, /* value_table */ + }; + type = g_type_register_static(SP_TYPE_GROUP, "SPAnchor", &info, (GTypeFlags) 0); + } + + return type; +} + +static void sp_anchor_class_init(SPAnchorClass *ac) +{ + SPObjectClass *sp_object_class = (SPObjectClass *) ac; + SPItemClass *item_class = (SPItemClass *) ac; + + parent_class = (SPGroupClass *) g_type_class_ref(SP_TYPE_GROUP); + + sp_object_class->build = sp_anchor_build; + sp_object_class->release = sp_anchor_release; + sp_object_class->set = sp_anchor_set; + sp_object_class->write = sp_anchor_write; + + item_class->description = sp_anchor_description; + item_class->event = sp_anchor_event; +} + +static void sp_anchor_init(SPAnchor *anchor) +{ + anchor->href = NULL; +} + +static void sp_anchor_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr) +{ + if (((SPObjectClass *) (parent_class))->build) { + ((SPObjectClass *) (parent_class))->build(object, document, repr); + } + + sp_object_read_attr(object, "xlink:type"); + sp_object_read_attr(object, "xlink:role"); + sp_object_read_attr(object, "xlink:arcrole"); + sp_object_read_attr(object, "xlink:title"); + sp_object_read_attr(object, "xlink:show"); + sp_object_read_attr(object, "xlink:actuate"); + sp_object_read_attr(object, "xlink:href"); + sp_object_read_attr(object, "target"); +} + +static void sp_anchor_release(SPObject *object) +{ + SPAnchor *anchor = SP_ANCHOR(object); + + if (anchor->href) { + g_free(anchor->href); + anchor->href = NULL; + } + + if (((SPObjectClass *) parent_class)->release) { + ((SPObjectClass *) parent_class)->release(object); + } +} + +static void sp_anchor_set(SPObject *object, unsigned int key, const gchar *value) +{ + SPAnchor *anchor = SP_ANCHOR(object); + + switch (key) { + case SP_ATTR_XLINK_HREF: + g_free(anchor->href); + anchor->href = g_strdup(value); + object->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_XLINK_TYPE: + case SP_ATTR_XLINK_ROLE: + case SP_ATTR_XLINK_ARCROLE: + case SP_ATTR_XLINK_TITLE: + case SP_ATTR_XLINK_SHOW: + case SP_ATTR_XLINK_ACTUATE: + case SP_ATTR_TARGET: + object->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + default: + if (((SPObjectClass *) (parent_class))->set) { + ((SPObjectClass *) (parent_class))->set(object, key, value); + } + break; + } +} + + +#define COPY_ATTR(rd,rs,key) (rd)->setAttribute((key), rs->attribute(key)); + +static Inkscape::XML::Node *sp_anchor_write(SPObject *object, Inkscape::XML::Node *repr, guint flags) +{ + SPAnchor *anchor = SP_ANCHOR(object); + + if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { + repr = sp_repr_new("svg:a"); + } + + repr->setAttribute("xlink:href", anchor->href); + + if (repr != SP_OBJECT_REPR(object)) { + COPY_ATTR(repr, object->repr, "xlink:type"); + COPY_ATTR(repr, object->repr, "xlink:role"); + COPY_ATTR(repr, object->repr, "xlink:arcrole"); + COPY_ATTR(repr, object->repr, "xlink:title"); + COPY_ATTR(repr, object->repr, "xlink:show"); + COPY_ATTR(repr, object->repr, "xlink:actuate"); + COPY_ATTR(repr, object->repr, "target"); + } + + if (((SPObjectClass *) (parent_class))->write) { + ((SPObjectClass *) (parent_class))->write(object, repr, flags); + } + + return repr; +} + +static gchar *sp_anchor_description(SPItem *item) +{ + SPAnchor *anchor = SP_ANCHOR(item); + if (anchor->href) { + char *quoted_href = xml_quote_strdup(anchor->href); + char *ret = g_strdup_printf(_("Link to %s"), quoted_href); + g_free(quoted_href); + return ret; + } else { + return g_strdup (_("Link without URI")); + } +} + +/* fixme: We should forward event to appropriate container/view */ + +static gint sp_anchor_event(SPItem *item, SPEvent *event) +{ + SPAnchor *anchor = SP_ANCHOR(item); + + switch (event->type) { + case SP_EVENT_ACTIVATE: + if (anchor->href) { + g_print("Activated xlink:href=\"%s\"\n", anchor->href); + return TRUE; + } + break; + case SP_EVENT_MOUSEOVER: + (static_cast(event->data))->mouseover(); + break; + case SP_EVENT_MOUSEOUT: + (static_cast(event->data))->mouseout(); + break; + default: + break; + } + + return FALSE; +} + +/* + 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 : diff --git a/src/sp-anchor.h b/src/sp-anchor.h new file mode 100644 index 000000000..3c6481d94 --- /dev/null +++ b/src/sp-anchor.h @@ -0,0 +1,34 @@ +#ifndef __SP_ANCHOR_H__ +#define __SP_ANCHOR_H__ + +/* + * SVG element implementation + * + * Author: + * Lauris Kaplinski + * + * Copyright (C) 2001-2002 Lauris Kaplinski + * Copyright (C) 2001 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "sp-item-group.h" + +#define SP_TYPE_ANCHOR (sp_anchor_get_type ()) +#define SP_ANCHOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SP_TYPE_ANCHOR, SPAnchor)) +#define SP_ANCHOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SP_TYPE_ANCHOR, SPAnchorClass)) +#define SP_IS_ANCHOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_ANCHOR)) +#define SP_IS_ANCHOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SP_TYPE_ANCHOR)) + +struct SPAnchor : public SPGroup { + gchar *href; +}; + +struct SPAnchorClass { + SPGroupClass parent_class; +}; + +GType sp_anchor_get_type (void); + +#endif diff --git a/src/sp-animation.cpp b/src/sp-animation.cpp new file mode 100644 index 000000000..8a2a02bdc --- /dev/null +++ b/src/sp-animation.cpp @@ -0,0 +1,290 @@ +#define __SP_ANIMATION_C__ + +/** \file + * SVG implementation. + * + * N.B. This file is currently just a stub file with no meaningful implementation. + */ +/* + * Authors: + * Lauris Kaplinski + * + * Copyright (C) 2002 Lauris Kaplinski + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "sp-animation.h" + +#if 0 +/* Feel free to remove this function and its calls. */ +static void +log_set_attr(char const *const classname, unsigned int const key, char const *const value) +{ + unsigned char const *const attr_name = sp_attribute_name(key); + if (value) { + g_print("%s: Set %s=%s\n", classname, attr_name, value); + } else { + g_print("%s: unset %s.\n", classname, attr_name); + } +} +#else +# define log_set_attr(_classname, _key, _value) static_cast(0) +#endif + +/* Animation base class */ + +static void sp_animation_class_init(SPAnimationClass *klass); +static void sp_animation_init(SPAnimation *animation); + +static void sp_animation_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr); +static void sp_animation_release(SPObject *object); +static void sp_animation_set(SPObject *object, unsigned int key, gchar const *value); + +static SPObjectClass *animation_parent_class; + +GType +sp_animation_get_type(void) +{ + static GType animation_type = 0; + + if (!animation_type) { + GTypeInfo animation_info = { + sizeof(SPAnimationClass), + NULL, NULL, + (GClassInitFunc) sp_animation_class_init, + NULL, NULL, + sizeof(SPAnimation), + 16, + (GInstanceInitFunc) sp_animation_init, + NULL, /* value_table */ + }; + animation_type = g_type_register_static(SP_TYPE_OBJECT, "SPAnimation", &animation_info, (GTypeFlags)0); + } + return animation_type; +} + +static void +sp_animation_class_init(SPAnimationClass *klass) +{ + //GObjectClass *gobject_class = (GObjectClass *) klass; + SPObjectClass *sp_object_class = (SPObjectClass *) klass; + + animation_parent_class = (SPObjectClass*)g_type_class_peek_parent(klass); + + sp_object_class->build = sp_animation_build; + sp_object_class->release = sp_animation_release; + sp_object_class->set = sp_animation_set; +} + +static void +sp_animation_init(SPAnimation *animation) +{ +} + + +static void +sp_animation_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr) +{ + if (((SPObjectClass *) animation_parent_class)->build) + ((SPObjectClass *) animation_parent_class)->build(object, document, repr); + + sp_object_read_attr(object, "xlink:href"); + sp_object_read_attr(object, "attributeName"); + sp_object_read_attr(object, "attributeType"); + sp_object_read_attr(object, "begin"); + sp_object_read_attr(object, "dur"); + sp_object_read_attr(object, "end"); + sp_object_read_attr(object, "min"); + sp_object_read_attr(object, "max"); + sp_object_read_attr(object, "restart"); + sp_object_read_attr(object, "repeatCount"); + sp_object_read_attr(object, "repeatDur"); + sp_object_read_attr(object, "fill"); +} + +static void +sp_animation_release(SPObject *object) +{ +} + +static void +sp_animation_set(SPObject *object, unsigned int key, gchar const *value) +{ + //SPAnimation *animation = SP_ANIMATION(object); + + log_set_attr("SPAnimation", key, value); + + if (((SPObjectClass *) animation_parent_class)->set) + ((SPObjectClass *) animation_parent_class)->set(object, key, value); +} + +/* Interpolated animation base class */ + +static void sp_ianimation_class_init(SPIAnimationClass *klass); +static void sp_ianimation_init(SPIAnimation *animation); + +static void sp_ianimation_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr); +static void sp_ianimation_release(SPObject *object); +static void sp_ianimation_set(SPObject *object, unsigned int key, gchar const *value); + +static SPObjectClass *ianimation_parent_class; + +GType +sp_ianimation_get_type(void) +{ + static GType type = 0; + + if (!type) { + GTypeInfo info = { + sizeof(SPIAnimationClass), + NULL, NULL, + (GClassInitFunc) sp_ianimation_class_init, + NULL, NULL, + sizeof(SPIAnimation), + 16, + (GInstanceInitFunc) sp_ianimation_init, + NULL, /* value_table */ + }; + type = g_type_register_static(SP_TYPE_OBJECT, "SPIAnimation", &info, (GTypeFlags)0); + } + return type; +} + +static void +sp_ianimation_class_init(SPIAnimationClass *klass) +{ + //GObjectClass *gobject_class = (GObjectClass *) klass; + SPObjectClass *sp_object_class = (SPObjectClass *) klass; + + ianimation_parent_class = (SPObjectClass*)g_type_class_peek_parent(klass); + + sp_object_class->build = sp_ianimation_build; + sp_object_class->release = sp_ianimation_release; + sp_object_class->set = sp_ianimation_set; +} + +static void +sp_ianimation_init(SPIAnimation *animation) +{ +} + + +static void +sp_ianimation_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr) +{ + if (((SPObjectClass *) ianimation_parent_class)->build) + ((SPObjectClass *) ianimation_parent_class)->build(object, document, repr); + + sp_object_read_attr(object, "calcMode"); + sp_object_read_attr(object, "values"); + sp_object_read_attr(object, "keyTimes"); + sp_object_read_attr(object, "keySplines"); + sp_object_read_attr(object, "from"); + sp_object_read_attr(object, "to"); + sp_object_read_attr(object, "by"); + sp_object_read_attr(object, "additive"); + sp_object_read_attr(object, "accumulate"); +} + +static void +sp_ianimation_release(SPObject *object) +{ +} + +static void +sp_ianimation_set(SPObject *object, unsigned int key, gchar const *value) +{ + //SPIAnimation *ianimation = SP_IANIMATION(object); + + log_set_attr("SPIAnimation", key, value); + + if (((SPObjectClass *) ianimation_parent_class)->set) + ((SPObjectClass *) ianimation_parent_class)->set(object, key, value); +} + +/* SVG */ + +static void sp_animate_class_init(SPAnimateClass *klass); +static void sp_animate_init(SPAnimate *animate); + +static void sp_animate_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr); +static void sp_animate_release(SPObject *object); +static void sp_animate_set(SPObject *object, unsigned int key, gchar const *value); + +static SPIAnimationClass *animate_parent_class; + +GType +sp_animate_get_type(void) +{ + static GType type = 0; + + if (!type) { + GTypeInfo info = { + sizeof(SPAnimateClass), + NULL, NULL, + (GClassInitFunc) sp_animate_class_init, + NULL, NULL, + sizeof(SPAnimate), + 16, + (GInstanceInitFunc) sp_animate_init, + NULL, /* value_table */ + }; + type = g_type_register_static(SP_TYPE_IANIMATION, "SPAnimate", &info, (GTypeFlags)0); + } + return type; +} + +static void +sp_animate_class_init(SPAnimateClass *klass) +{ + //GObjectClass *gobject_class = (GObjectClass *) klass; + SPObjectClass *sp_object_class = (SPObjectClass *) klass; + + animate_parent_class = (SPIAnimationClass*)g_type_class_peek_parent(klass); + + sp_object_class->build = sp_animate_build; + sp_object_class->release = sp_animate_release; + sp_object_class->set = sp_animate_set; +} + +static void +sp_animate_init(SPAnimate *animate) +{ +} + + +static void +sp_animate_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr) +{ + if (((SPObjectClass *) animate_parent_class)->build) + ((SPObjectClass *) animate_parent_class)->build(object, document, repr); +} + +static void +sp_animate_release(SPObject *object) +{ +} + +static void +sp_animate_set(SPObject *object, unsigned int key, gchar const *value) +{ + //SPAnimate *animate = SP_ANIMATE(object); + + log_set_attr("SPAnimate", key, value); + + if (((SPObjectClass *) animate_parent_class)->set) + ((SPObjectClass *) animate_parent_class)->set(object, key, value); +} + + +/* + 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:textwidth=99 : diff --git a/src/sp-animation.h b/src/sp-animation.h new file mode 100644 index 000000000..407419f5b --- /dev/null +++ b/src/sp-animation.h @@ -0,0 +1,75 @@ +#ifndef __SP_ANIMATION_H__ +#define __SP_ANIMATION_H__ + +/* + * SVG implementation + * + * Authors: + * Lauris Kaplinski + * + * Copyright (C) 2002 Lauris Kaplinski + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "sp-object.h" + + + +/* Animation base class */ + +#define SP_TYPE_ANIMATION (sp_animation_get_type ()) +#define SP_ANIMATION(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), SP_TYPE_ANIMATION, SPAnimation)) +#define SP_IS_ANIMATION(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), SP_TYPE_ANIMATION)) + +class SPAnimation; +class SPAnimationClass; + +struct SPAnimation : public SPObject { +}; + +struct SPAnimationClass { + SPObjectClass parent_class; +}; + +GType sp_animation_get_type (void); + +/* Interpolated animation base class */ + +#define SP_TYPE_IANIMATION (sp_ianimation_get_type ()) +#define SP_IANIMATION(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), SP_TYPE_IANIMATION, SPIAnimation)) +#define SP_IS_IANIMATION(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), SP_TYPE_IANIMATION)) + +class SPIAnimation; +class SPIAnimationClass; + +struct SPIAnimation : public SPAnimation { +}; + +struct SPIAnimationClass { + SPAnimationClass parent_class; +}; + +GType sp_ianimation_get_type (void); + +/* SVG */ + +#define SP_TYPE_ANIMATE (sp_animate_get_type ()) +#define SP_ANIMATE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), SP_TYPE_ANIMATE, SPAnimate)) +#define SP_IS_ANIMATE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), SP_TYPE_ANIMATE)) + +class SPAnimate; +class SPAnimateClass; + +struct SPAnimate : public SPIAnimation { +}; + +struct SPAnimateClass { + SPIAnimationClass parent_class; +}; + +GType sp_animate_get_type (void); + + + +#endif diff --git a/src/sp-clippath.cpp b/src/sp-clippath.cpp new file mode 100644 index 000000000..d8d2acc9f --- /dev/null +++ b/src/sp-clippath.cpp @@ -0,0 +1,408 @@ +#define __SP_CLIPPATH_C__ + +/* + * SVG implementation + * + * Authors: + * Lauris Kaplinski + * + * Copyright (C) 2001-2002 authors + * Copyright (C) 2001 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + + + +#include "display/nr-arena.h" +#include "display/nr-arena-group.h" +#include "xml/repr.h" + +#include "enums.h" +#include "attributes.h" +#include "document.h" +#include "sp-item.h" + +#include "sp-clippath.h" + +struct SPClipPathView { + SPClipPathView *next; + unsigned int key; + NRArenaItem *arenaitem; + NRRect bbox; +}; + +static void sp_clippath_class_init(SPClipPathClass *klass); +static void sp_clippath_init(SPClipPath *clippath); + +static void sp_clippath_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr); +static void sp_clippath_release(SPObject * object); +static void sp_clippath_set(SPObject *object, unsigned int key, gchar const *value); +static void sp_clippath_child_added(SPObject *object, Inkscape::XML::Node *child, Inkscape::XML::Node *ref); +static void sp_clippath_update(SPObject *object, SPCtx *ctx, guint flags); +static void sp_clippath_modified(SPObject *object, guint flags); +static Inkscape::XML::Node *sp_clippath_write(SPObject *object, Inkscape::XML::Node *repr, guint flags); + +SPClipPathView *sp_clippath_view_new_prepend(SPClipPathView *list, unsigned int key, NRArenaItem *arenaitem); +SPClipPathView *sp_clippath_view_list_remove(SPClipPathView *list, SPClipPathView *view); + +static SPObjectGroupClass *parent_class; + +GType +sp_clippath_get_type(void) +{ + static GType type = 0; + if (!type) { + GTypeInfo info = { + sizeof(SPClipPathClass), + NULL, NULL, + (GClassInitFunc) sp_clippath_class_init, + NULL, NULL, + sizeof(SPClipPath), + 16, + (GInstanceInitFunc) sp_clippath_init, + NULL, /* value_table */ + }; + type = g_type_register_static(SP_TYPE_OBJECTGROUP, "SPClipPath", &info, (GTypeFlags)0); + } + return type; +} + +static void +sp_clippath_class_init(SPClipPathClass *klass) +{ + GObjectClass *gobject_class; + SPObjectClass *sp_object_class; + + gobject_class = (GObjectClass *) klass; + sp_object_class = (SPObjectClass *) klass; + + parent_class = (SPObjectGroupClass*)g_type_class_ref(SP_TYPE_OBJECTGROUP); + + sp_object_class->build = sp_clippath_build; + sp_object_class->release = sp_clippath_release; + sp_object_class->set = sp_clippath_set; + sp_object_class->child_added = sp_clippath_child_added; + sp_object_class->update = sp_clippath_update; + sp_object_class->modified = sp_clippath_modified; + sp_object_class->write = sp_clippath_write; +} + +static void +sp_clippath_init(SPClipPath *cp) +{ + cp->clipPathUnits_set = FALSE; + cp->clipPathUnits = SP_CONTENT_UNITS_USERSPACEONUSE; + + cp->display = NULL; +} + +static void +sp_clippath_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr) +{ + SPClipPath *cp; + + cp = SP_CLIPPATH(object); + + if (((SPObjectClass *) parent_class)->build) + ((SPObjectClass *) parent_class)->build(object, document, repr); + + sp_object_read_attr(object, "clipPathUnits"); + + /* Register ourselves */ + sp_document_add_resource(document, "clipPath", object); +} + +static void +sp_clippath_release(SPObject * object) +{ + SPClipPath *cp; + + cp = SP_CLIPPATH(object); + + if (SP_OBJECT_DOCUMENT(object)) { + /* Unregister ourselves */ + sp_document_remove_resource(SP_OBJECT_DOCUMENT(object), "clipPath", object); + } + + while (cp->display) { + /* We simply unref and let item to manage this in handler */ + cp->display = sp_clippath_view_list_remove(cp->display, cp->display); + } + + if (((SPObjectClass *) (parent_class))->release) + ((SPObjectClass *) parent_class)->release(object); +} + +static void +sp_clippath_set(SPObject *object, unsigned int key, gchar const *value) +{ + SPClipPath *cp; + + cp = SP_CLIPPATH(object); + + switch (key) { + case SP_ATTR_CLIPPATHUNITS: + cp->clipPathUnits = SP_CONTENT_UNITS_USERSPACEONUSE; + cp->clipPathUnits_set = FALSE; + if (value) { + if (!strcmp(value, "userSpaceOnUse")) { + cp->clipPathUnits_set = TRUE; + } else if (!strcmp(value, "objectBoundingBox")) { + cp->clipPathUnits = SP_CONTENT_UNITS_OBJECTBOUNDINGBOX; + cp->clipPathUnits_set = TRUE; + } + } + object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + break; + default: + if (((SPObjectClass *) parent_class)->set) + ((SPObjectClass *) parent_class)->set(object, key, value); + break; + } +} + +static void +sp_clippath_child_added(SPObject *object, Inkscape::XML::Node *child, Inkscape::XML::Node *ref) +{ + SPClipPath *cp; + SPObject *ochild; + + cp = SP_CLIPPATH(object); + + /* Invoke SPObjectGroup implementation */ + ((SPObjectClass *) (parent_class))->child_added(object, child, ref); + + /* Show new object */ + ochild = SP_OBJECT_DOCUMENT(object)->getObjectByRepr(child); + if (SP_IS_ITEM(ochild)) { + SPClipPathView *v; + for (v = cp->display; v != NULL; v = v->next) { + NRArenaItem *ac; + ac = sp_item_invoke_show(SP_ITEM(ochild), NR_ARENA_ITEM_ARENA(v->arenaitem), v->key, SP_ITEM_REFERENCE_FLAGS); + if (ac) { + nr_arena_item_add_child(v->arenaitem, ac, NULL); + nr_arena_item_unref(ac); + } + } + } +} + +static void +sp_clippath_update(SPObject *object, SPCtx *ctx, guint flags) +{ + SPObjectGroup *og; + SPClipPath *cp; + SPObject *child; + SPClipPathView *v; + GSList *l; + + og = SP_OBJECTGROUP(object); + cp = SP_CLIPPATH(object); + + if (flags & SP_OBJECT_MODIFIED_FLAG) flags |= SP_OBJECT_PARENT_MODIFIED_FLAG; + flags &= SP_OBJECT_MODIFIED_CASCADE; + + l = NULL; + for (child = sp_object_first_child(SP_OBJECT(og)); child != NULL; child = SP_OBJECT_NEXT(child)) { + g_object_ref(G_OBJECT(child)); + l = g_slist_prepend(l, child); + } + l = g_slist_reverse(l); + while (l) { + child = SP_OBJECT(l->data); + l = g_slist_remove(l, child); + if (flags || (child->uflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { + child->updateDisplay(ctx, flags); + } + g_object_unref(G_OBJECT(child)); + } + + for (v = cp->display; v != NULL; v = v->next) { + if (cp->clipPathUnits == SP_CONTENT_UNITS_OBJECTBOUNDINGBOX) { + NRMatrix t; + nr_matrix_set_scale(&t, v->bbox.x1 - v->bbox.x0, v->bbox.y1 - v->bbox.y0); + t.c[4] = v->bbox.x0; + t.c[5] = v->bbox.y0; + nr_arena_group_set_child_transform(NR_ARENA_GROUP(v->arenaitem), &t); + } else { + nr_arena_group_set_child_transform(NR_ARENA_GROUP(v->arenaitem), NULL); + } + } +} + +static void +sp_clippath_modified(SPObject *object, guint flags) +{ + SPObjectGroup *og; + SPClipPath *cp; + SPObject *child; + GSList *l; + + og = SP_OBJECTGROUP(object); + cp = SP_CLIPPATH(object); + + if (flags & SP_OBJECT_MODIFIED_FLAG) flags |= SP_OBJECT_PARENT_MODIFIED_FLAG; + flags &= SP_OBJECT_MODIFIED_CASCADE; + + l = NULL; + for (child = sp_object_first_child(SP_OBJECT(og)); child != NULL; child = SP_OBJECT_NEXT(child)) { + g_object_ref(G_OBJECT(child)); + l = g_slist_prepend(l, child); + } + l = g_slist_reverse(l); + while (l) { + child = SP_OBJECT(l->data); + l = g_slist_remove(l, child); + if (flags || (child->mflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { + child->emitModified(flags); + } + g_object_unref(G_OBJECT(child)); + } +} + +static Inkscape::XML::Node * +sp_clippath_write(SPObject *object, Inkscape::XML::Node *repr, guint flags) +{ + SPClipPath *cp; + + cp = SP_CLIPPATH(object); + + if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { + repr = sp_repr_new("svg:clipPath"); + } + + if (((SPObjectClass *) (parent_class))->write) + ((SPObjectClass *) (parent_class))->write(object, repr, flags); + + return repr; +} + +NRArenaItem * +sp_clippath_show(SPClipPath *cp, NRArena *arena, unsigned int key) +{ + NRArenaItem *ai, *ac; + SPObject *child; + + g_return_val_if_fail(cp != NULL, NULL); + g_return_val_if_fail(SP_IS_CLIPPATH(cp), NULL); + g_return_val_if_fail(arena != NULL, NULL); + g_return_val_if_fail(NR_IS_ARENA(arena), NULL); + + ai = NRArenaGroup::create(arena); + cp->display = sp_clippath_view_new_prepend(cp->display, key, ai); + + for (child = sp_object_first_child(SP_OBJECT(cp)) ; child != NULL; child = SP_OBJECT_NEXT(child)) { + if (SP_IS_ITEM(child)) { + ac = sp_item_invoke_show(SP_ITEM(child), arena, key, SP_ITEM_REFERENCE_FLAGS); + if (ac) { + /* The order is not important in clippath */ + nr_arena_item_add_child(ai, ac, NULL); + nr_arena_item_unref(ac); + } + } + } + + if (cp->clipPathUnits == SP_CONTENT_UNITS_OBJECTBOUNDINGBOX) { + NRMatrix t; + nr_matrix_set_scale(&t, cp->display->bbox.x1 - cp->display->bbox.x0, cp->display->bbox.y1 - cp->display->bbox.y0); + t.c[4] = cp->display->bbox.x0; + t.c[5] = cp->display->bbox.y0; + nr_arena_group_set_child_transform(NR_ARENA_GROUP(ai), &t); + } + + return ai; +} + +void +sp_clippath_hide(SPClipPath *cp, unsigned int key) +{ + SPClipPathView *v; + SPObject *child; + + g_return_if_fail(cp != NULL); + g_return_if_fail(SP_IS_CLIPPATH(cp)); + + for (child = sp_object_first_child(SP_OBJECT(cp)) ; child != NULL; child = SP_OBJECT_NEXT(child)) { + if (SP_IS_ITEM(child)) { + sp_item_invoke_hide(SP_ITEM(child), key); + } + } + + for (v = cp->display; v != NULL; v = v->next) { + if (v->key == key) { + /* We simply unref and let item to manage this in handler */ + cp->display = sp_clippath_view_list_remove(cp->display, v); + return; + } + } + + g_assert_not_reached(); +} + +void +sp_clippath_set_bbox(SPClipPath *cp, unsigned int key, NRRect *bbox) +{ + SPClipPathView *v; + + for (v = cp->display; v != NULL; v = v->next) { + if (v->key == key) { + if (!NR_DF_TEST_CLOSE(v->bbox.x0, bbox->x0, NR_EPSILON) || + !NR_DF_TEST_CLOSE(v->bbox.y0, bbox->y0, NR_EPSILON) || + !NR_DF_TEST_CLOSE(v->bbox.x1, bbox->x1, NR_EPSILON) || + !NR_DF_TEST_CLOSE(v->bbox.y1, bbox->y1, NR_EPSILON)) { + v->bbox = *bbox; + SP_OBJECT(cp)->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + } + break; + } + } +} + +/* ClipPath views */ + +SPClipPathView * +sp_clippath_view_new_prepend(SPClipPathView *list, unsigned int key, NRArenaItem *arenaitem) +{ + SPClipPathView *new_path_view; + + new_path_view = g_new(SPClipPathView, 1); + + new_path_view->next = list; + new_path_view->key = key; + new_path_view->arenaitem = nr_arena_item_ref(arenaitem); + new_path_view->bbox.x0 = new_path_view->bbox.x1 = 0.0; + new_path_view->bbox.y0 = new_path_view->bbox.y1 = 0.0; + + return new_path_view; +} + +SPClipPathView * +sp_clippath_view_list_remove(SPClipPathView *list, SPClipPathView *view) +{ + if (view == list) { + list = list->next; + } else { + SPClipPathView *prev; + prev = list; + while (prev->next != view) prev = prev->next; + prev->next = view->next; + } + + nr_arena_item_unref(view->arenaitem); + g_free(view); + + return list; +} + + +/* + 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:textwidth=99 : diff --git a/src/sp-clippath.h b/src/sp-clippath.h new file mode 100644 index 000000000..1f5571cc1 --- /dev/null +++ b/src/sp-clippath.h @@ -0,0 +1,61 @@ +#ifndef __SP_CLIPPATH_H__ +#define __SP_CLIPPATH_H__ + +/* + * SVG implementation + * + * Authors: + * Lauris Kaplinski + * + * Copyright (C) 2001-2002 authors + * Copyright (C) 2001 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#define SP_TYPE_CLIPPATH (sp_clippath_get_type ()) +#define SP_CLIPPATH(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SP_TYPE_CLIPPATH, SPClipPath)) +#define SP_CLIPPATH_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SP_TYPE_CLIPPATH, SPClipPathClass)) +#define SP_IS_CLIPPATH(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_CLIPPATH)) +#define SP_IS_CLIPPATH_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SP_TYPE_CLIPPATH)) + +class SPClipPathView; + +#include "display/nr-arena-forward.h" +#include "sp-object-group.h" +#include "uri-references.h" +#include + +struct SPClipPath : public SPObjectGroup { + class Reference; + + unsigned int clipPathUnits_set : 1; + unsigned int clipPathUnits : 1; + + SPClipPathView *display; +}; + +struct SPClipPathClass { + SPObjectGroupClass parent_class; +}; + +GType sp_clippath_get_type (void); + +class SPClipPathReference : public Inkscape::URIReference { +public: + SPClipPathReference(SPObject *obj) : URIReference(obj) {} + SPClipPath *getObject() const { + return (SPClipPath *)URIReference::getObject(); + } +protected: + virtual bool _acceptObject(SPObject *obj) const { + return SP_IS_CLIPPATH(obj); + } +}; + +NRArenaItem *sp_clippath_show(SPClipPath *cp, NRArena *arena, unsigned int key); +void sp_clippath_hide(SPClipPath *cp, unsigned int key); + +void sp_clippath_set_bbox(SPClipPath *cp, unsigned int key, NRRect *bbox); + +#endif diff --git a/src/sp-conn-end-pair.cpp b/src/sp-conn-end-pair.cpp new file mode 100644 index 000000000..ff1005a16 --- /dev/null +++ b/src/sp-conn-end-pair.cpp @@ -0,0 +1,275 @@ +/* + * A class for handling connector endpoint movement and libavoid interaction. + * + * Authors: + * Peter Moulder + * Michael Wybrow + * + * * Copyright (C) 2004-2005 Monash University + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "attributes.h" +#include "sp-conn-end.h" +#include "uri.h" +#include "display/curve.h" +#include "xml/repr.h" +#include "sp-path.h" +#include "libavoid/vertices.h" + + +SPConnEndPair::SPConnEndPair(SPPath *const owner) + : _invalid_path_connection() + , _path(owner) + , _connRef(NULL) + , _connType(SP_CONNECTOR_NOAVOID) + , _transformed_connection() +{ + for (unsigned handle_ix = 0; handle_ix <= 1; ++handle_ix) { + this->_connEnd[handle_ix] = new SPConnEnd(SP_OBJECT(owner)); + this->_connEnd[handle_ix]->_changed_connection + = this->_connEnd[handle_ix]->ref.changedSignal() + .connect(sigc::bind(sigc::ptr_fun(sp_conn_end_href_changed), + this->_connEnd[handle_ix], owner, handle_ix)); + } +} + +SPConnEndPair::~SPConnEndPair() +{ + for (unsigned handle_ix = 0; handle_ix < 2; ++handle_ix) { + delete this->_connEnd[handle_ix]; + this->_connEnd[handle_ix] = NULL; + } + if (_connRef) { + _connRef->removeFromGraph(); + delete _connRef; + _connRef = NULL; + } + + _invalid_path_connection.disconnect(); + _transformed_connection.disconnect(); +} + +void +SPConnEndPair::release() +{ + for (unsigned handle_ix = 0; handle_ix < 2; ++handle_ix) { + this->_connEnd[handle_ix]->_changed_connection.disconnect(); + this->_connEnd[handle_ix]->_delete_connection.disconnect(); + this->_connEnd[handle_ix]->_transformed_connection.disconnect(); + g_free(this->_connEnd[handle_ix]->href); + this->_connEnd[handle_ix]->href = NULL; + this->_connEnd[handle_ix]->ref.detach(); + } +} + +void +sp_conn_end_pair_build(SPObject *object) +{ + sp_object_read_attr(object, "inkscape:connector-type"); + sp_object_read_attr(object, "inkscape:connection-start"); + sp_object_read_attr(object, "inkscape:connection-end"); +} + + +static void +avoid_conn_move(NR::Matrix const *mp, SPItem *moved_item) +{ + // Detach from objects if attached. + sp_conn_end_detach(moved_item, 0); + sp_conn_end_detach(moved_item, 1); + // Reroute connector + SPPath *path = SP_PATH(moved_item); + path->connEndPair.makePathInvalid(); + sp_conn_adjust_invalid_path(path); +} + + +void +SPConnEndPair::setAttr(unsigned const key, gchar const *const value) +{ + if (key == SP_ATTR_CONNECTOR_TYPE) { + if (value && (strcmp(value, "polyline") == 0)) { + _connType = SP_CONNECTOR_POLYLINE; + + GQuark itemID = g_quark_from_string(SP_OBJECT(_path)->id); + _connRef = new Avoid::ConnRef(itemID); + _invalid_path_connection = connectInvalidPath( + sigc::ptr_fun(&sp_conn_adjust_invalid_path)); + _transformed_connection = _path->connectTransformed( + sigc::ptr_fun(&avoid_conn_move)); + } + else { + _connType = SP_CONNECTOR_NOAVOID; + + if (_connRef) { + _connRef->removeFromGraph(); + delete _connRef; + _connRef = NULL; + _invalid_path_connection.disconnect(); + _transformed_connection.disconnect(); + } + } + return; + + } + + unsigned const handle_ix = key - SP_ATTR_CONNECTION_START; + g_assert( handle_ix <= 1 ); + this->_connEnd[handle_ix]->setAttacherHref(value); +} + +void +SPConnEndPair::writeRepr(Inkscape::XML::Node *const repr) const +{ + for (unsigned handle_ix = 0; handle_ix < 2; ++handle_ix) { + if (this->_connEnd[handle_ix]->ref.getURI()) { + char const * const attr_strs[] = {"inkscape:connection-start", + "inkscape:connection-end"}; + gchar *uri_string = this->_connEnd[handle_ix]->ref.getURI()->toString(); + repr->setAttribute(attr_strs[handle_ix], uri_string); + g_free(uri_string); + } + } +} + +void +SPConnEndPair::getAttachedItems(SPItem *h2attItem[2]) const { + for (unsigned h = 0; h < 2; ++h) { + h2attItem[h] = this->_connEnd[h]->ref.getObject(); + } +} + +void +SPConnEndPair::getEndpoints(NR::Point endPts[]) const { + SPCurve *curve = _path->curve; + SPItem *h2attItem[2]; + getAttachedItems(h2attItem); + + for (unsigned h = 0; h < 2; ++h) { + if ( h2attItem[h] ) { + NR::Rect const bbox = h2attItem[h]->invokeBbox(sp_item_i2doc_affine(h2attItem[h])); + endPts[h] = bbox.midpoint(); + } + else + { + if (h == 0) { + endPts[h] = sp_curve_first_point(curve); + } + else { + endPts[h] = sp_curve_last_point(curve); + } + } + } +} + +sigc::connection +SPConnEndPair::connectInvalidPath(sigc::slot slot) +{ + return _invalid_path_signal.connect(slot); +} + +static void emitPathInvalidationNotification(void *ptr) +{ + // We emit a signal here rather than just calling the reroute function + // since this allows all the movement action computation to happen, + // then all connectors (that require it) will be rerouted. Otherwise, + // one connector could get rerouted several times as a result of + // dragging a couple of shapes. + + SPPath *path = SP_PATH(ptr); + path->connEndPair._invalid_path_signal.emit(path); +} + +void +SPConnEndPair::rerouteFromManipulation(void) +{ + _connRef->makePathInvalid(); + sp_conn_adjust_path(_path); +} + +void +SPConnEndPair::reroute(void) +{ + sp_conn_adjust_path(_path); +} + +// Called from sp_path_update to initialise the endpoints. +void +SPConnEndPair::update(void) +{ + if (_connType != SP_CONNECTOR_NOAVOID) { + g_assert(_connRef != NULL); + if (!(_connRef->isInitialised())) { + NR::Point endPt[2]; + getEndpoints(endPt); + + Avoid::Point src = { endPt[0][NR::X], endPt[0][NR::Y] }; + Avoid::Point dst = { endPt[1][NR::X], endPt[1][NR::Y] }; + + _connRef->lateSetup(src, dst); + _connRef->setCallback(&emitPathInvalidationNotification, _path); + } + } +} + + +bool +SPConnEndPair::isAutoRoutingConn(void) +{ + if (_connType != SP_CONNECTOR_NOAVOID) { + return true; + } + return false; +} + +void +SPConnEndPair::makePathInvalid(void) +{ + _connRef->makePathInvalid(); +} + +void +SPConnEndPair::reroutePath(void) +{ + if (!isAutoRoutingConn()) { + // Do nothing + return; + } + + SPCurve *curve = _path->curve; + + NR::Point endPt[2]; + getEndpoints(endPt); + + Avoid::Point src = { endPt[0][NR::X], endPt[0][NR::Y] }; + Avoid::Point dst = { endPt[1][NR::X], endPt[1][NR::Y] }; + + _connRef->updateEndPoint(Avoid::VertID::src, src); + _connRef->updateEndPoint(Avoid::VertID::tar, dst); + + _connRef->generatePath(src, dst); + + Avoid::PolyLine route = _connRef->route(); + _connRef->calcRouteDist(); + + sp_curve_reset(curve); + sp_curve_moveto(curve, endPt[0]); + + for (int i = 1; i < route.pn; ++i) { + NR::Point p(route.ps[i].x, route.ps[i].y); + sp_curve_lineto(curve, p); + } +} + +/* + 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 : diff --git a/src/sp-conn-end-pair.h b/src/sp-conn-end-pair.h new file mode 100644 index 000000000..9807b4f14 --- /dev/null +++ b/src/sp-conn-end-pair.h @@ -0,0 +1,91 @@ +#ifndef SEEN_SP_CONN_END_PAIR +#define SEEN_SP_CONN_END_PAIR + +/* + * A class for handling connector endpoint movement and libavoid interaction. + * + * Authors: + * Peter Moulder + * + * * Copyright (C) 2004 Monash University + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ +#include + +#include "forward.h" +#include "libnr/nr-point.h" +#include +#include +#include +#include "libavoid/connector.h" + + +class SPConnEnd; +namespace Inkscape { +namespace XML { +class Node; +} +} + + +class SPConnEndPair { +public: + SPConnEndPair(SPPath *); + ~SPConnEndPair(); + void release(); + void setAttr(unsigned const key, gchar const *const value); + void writeRepr(Inkscape::XML::Node *const repr) const; + void getAttachedItems(SPItem *[2]) const; + void getEndpoints(NR::Point endPts[]) const; + void reroutePath(void); + void makePathInvalid(void); + void update(void); + bool isAutoRoutingConn(void); + void rerouteFromManipulation(void); + void reroute(void); + sigc::connection connectInvalidPath(sigc::slot slot); + + // A signal emited by a call back from libavoid. Used to let + // connectors know when they need to reroute themselves. + sigc::signal _invalid_path_signal; + // A sigc connection to listen for connector path invalidation. + sigc::connection _invalid_path_connection; + +private: + SPConnEnd *_connEnd[2]; + + SPPath *_path; + + // libavoid's internal representation of the item. + Avoid::ConnRef *_connRef; + + int _connType; + + // A sigc connection for transformed signal. + sigc::connection _transformed_connection; +}; + + +void sp_conn_end_pair_build(SPObject *object); + + +// _connType options: +enum { + SP_CONNECTOR_NOAVOID, // Basic connector - a straight line. + SP_CONNECTOR_POLYLINE // Object avoiding polyline. +}; + + +#endif /* !SEEN_SP_CONN_END_PAIR */ + +/* + 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 : diff --git a/src/sp-conn-end.cpp b/src/sp-conn-end.cpp new file mode 100644 index 000000000..af8692358 --- /dev/null +++ b/src/sp-conn-end.cpp @@ -0,0 +1,298 @@ + +#include "display/curve.h" +#include "libnr/nr-matrix-div.h" +#include "libnr/nr-matrix-fns.h" +#include "xml/repr.h" +#include "sp-conn-end.h" +#include "sp-path.h" +#include "uri.h" +#include "document.h" + + +static void change_endpts(SPCurve *const curve, NR::Point const h2endPt[2]); +static NR::Point calc_bbox_conn_pt(NR::Rect const &bbox, NR::Point const &p); +static double signed_one(double const x); + +SPConnEnd::SPConnEnd(SPObject *const owner) : + ref(owner), + href(NULL), + _changed_connection(), + _delete_connection(), + _transformed_connection() +{ +} + +static SPObject const * +get_nearest_common_ancestor(SPObject const *const obj, SPItem const *const objs[2]) { + SPObject const *anc_sofar = obj; + for (unsigned i = 0; i < 2; ++i) { + if ( objs[i] != NULL ) { + anc_sofar = anc_sofar->nearestCommonAncestor(objs[i]); + } + } + return anc_sofar; +} + +static void +sp_conn_end_move_compensate(NR::Matrix const *mp, SPItem *moved_item, + SPPath *const path, + bool const updatePathRepr = true) +{ + // TODO: SPItem::invokeBbox gives the wrong result for some objects + // that have internal representations that are updated later + // by the sp_*_update functions, e.g., text. + sp_document_ensure_up_to_date(path->document); + + // Get the new route around obstacles. + path->connEndPair.reroutePath(); + + SPItem *h2attItem[2]; + path->connEndPair.getAttachedItems(h2attItem); + if ( !h2attItem[0] && !h2attItem[1] ) { + if (updatePathRepr) { + path->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + path->updateRepr(); + } + return; + } + + SPItem const *const path_item = SP_ITEM(path); + SPObject const *const ancestor = get_nearest_common_ancestor(path_item, h2attItem); + NR::Matrix const path2anc(i2anc_affine(path_item, ancestor)); + + if (h2attItem[0] != NULL && h2attItem[1] != NULL) { + /* Initial end-points: centre of attached object. */ + NR::Point h2endPt_icoordsys[2]; + NR::Matrix h2i2anc[2]; + NR::Rect h2bbox_icoordsys[2] = { + h2attItem[0]->invokeBbox(NR::identity()), + h2attItem[1]->invokeBbox(NR::identity()) + }; + NR::Point last_seg_endPt[2] = { + sp_curve_second_point(path->curve), + sp_curve_penultimate_point(path->curve) + }; + for (unsigned h = 0; h < 2; ++h) { + h2i2anc[h] = i2anc_affine(h2attItem[h], ancestor); + h2endPt_icoordsys[h] = h2bbox_icoordsys[h].midpoint(); + } + + // For each attached object, change the corresponding point to be + // on the edge of the bbox. + NR::Point h2endPt_pcoordsys[2]; + for (unsigned h = 0; h < 2; ++h) { + h2endPt_icoordsys[h] = calc_bbox_conn_pt(h2bbox_icoordsys[h], + ( last_seg_endPt[h] / h2i2anc[h] )); + h2endPt_pcoordsys[h] = h2endPt_icoordsys[h] * h2i2anc[h] / path2anc; + } + change_endpts(path->curve, h2endPt_pcoordsys); + } else { + // We leave the unattached endpoint where it is, and adjust the + // position of the attached endpoint to be on the edge of the bbox. + unsigned ind; + NR::Point other_endpt; + NR::Point last_seg_pt; + if (h2attItem[0] != NULL) { + other_endpt = sp_curve_last_point(path->curve); + last_seg_pt = sp_curve_second_point(path->curve); + ind = 0; + } + else { + other_endpt = sp_curve_first_point(path->curve); + last_seg_pt = sp_curve_penultimate_point(path->curve); + ind = 1; + } + NR::Point h2endPt_icoordsys[2]; + NR::Matrix h2i2anc; + + NR::Rect otherpt_rect = NR::Rect(other_endpt, other_endpt); + NR::Rect h2bbox_icoordsys[2] = { otherpt_rect, otherpt_rect }; + h2bbox_icoordsys[ind] = h2attItem[ind]->invokeBbox(NR::identity()); + + h2i2anc = i2anc_affine(h2attItem[ind], ancestor); + h2endPt_icoordsys[ind] = h2bbox_icoordsys[ind].midpoint(); + + h2endPt_icoordsys[!ind] = other_endpt; + + // For the attached object, change the corresponding point to be + // on the edge of the bbox. + NR::Point h2endPt_pcoordsys[2]; + h2endPt_icoordsys[ind] = calc_bbox_conn_pt(h2bbox_icoordsys[ind], + ( last_seg_pt / h2i2anc )); + h2endPt_pcoordsys[ind] = h2endPt_icoordsys[ind] * h2i2anc / path2anc; + + // Leave the other where it is. + h2endPt_pcoordsys[!ind] = other_endpt; + + change_endpts(path->curve, h2endPt_pcoordsys); + } + if (updatePathRepr) { + path->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + path->updateRepr(); + } +} + +// TODO: This triggering of makeInvalidPath could be cleaned up to be +// another option passed to move_compensate. +static void +sp_conn_end_shape_move_compensate(NR::Matrix const *mp, SPItem *moved_item, + SPPath *const path) +{ + if (path->connEndPair.isAutoRoutingConn()) { + path->connEndPair.makePathInvalid(); + } + sp_conn_end_move_compensate(mp, moved_item, path); +} + + +void +sp_conn_adjust_invalid_path(SPPath *const path) +{ + sp_conn_end_move_compensate(NULL, NULL, path); +} + +void +sp_conn_adjust_path(SPPath *const path) +{ + if (path->connEndPair.isAutoRoutingConn()) { + path->connEndPair.makePathInvalid(); + } + // Don't update the path repr or else connector dragging is slowed by + // constant update of values to the xml editor, and each step is also + // needlessly remembered by undo/redo. + bool const updatePathRepr = false; + sp_conn_end_move_compensate(NULL, NULL, path, updatePathRepr); +} + +static NR::Point +calc_bbox_conn_pt(NR::Rect const &bbox, NR::Point const &p) +{ + using NR::X; + using NR::Y; + NR::Point const ctr(bbox.midpoint()); + NR::Point const lengths(bbox.dimensions()); + if ( ctr == p ) { + /* Arbitrarily choose centre of right edge. */ + return NR::Point(ctr[X] + .5 * lengths[X], + ctr[Y]); + } + NR::Point const cp( p - ctr ); + NR::Dim2 const edgeDim = ( ( fabs(lengths[Y] * cp[X]) < + fabs(lengths[X] * cp[Y]) ) + ? Y + : X ); + NR::Dim2 const otherDim = (NR::Dim2) !edgeDim; + NR::Point offset; + offset[edgeDim] = (signed_one(cp[edgeDim]) + * lengths[edgeDim]); + offset[otherDim] = (lengths[edgeDim] + * cp[otherDim] + / fabs(cp[edgeDim])); + g_assert((offset[otherDim] >= 0) == (cp[otherDim] >= 0)); +#ifndef NDEBUG + for (unsigned d = 0; d < 2; ++d) { + g_assert(fabs(offset[d]) <= lengths[d] + .125); + } +#endif + return ctr + .5 * offset; +} + +static double signed_one(double const x) +{ + return (x < 0 + ? -1. + : 1.); +} + +static void +change_endpts(SPCurve *const curve, NR::Point const h2endPt[2]) +{ +#if 0 + sp_curve_reset(curve); + sp_curve_moveto(curve, h2endPt[0]); + sp_curve_lineto(curve, h2endPt[1]); +#else + sp_curve_move_endpoints(curve, h2endPt[0], h2endPt[1]); +#endif +} + +static void +sp_conn_end_deleted(SPObject *, SPObject *const owner, unsigned const handle_ix) +{ + // todo: The first argument is the deleted object, or just NULL if + // called by sp_conn_end_detach. + g_return_if_fail(handle_ix < 2); + char const *const attr_str[] = {"inkscape:connection-start", + "inkscape:connection-end"}; + SP_OBJECT_REPR(owner)->setAttribute(attr_str[handle_ix], NULL); + /* I believe this will trigger sp_conn_end_href_changed. */ +} + +void +sp_conn_end_detach(SPObject *const owner, unsigned const handle_ix) +{ + sp_conn_end_deleted(NULL, owner, handle_ix); +} + +void +SPConnEnd::setAttacherHref(gchar const *value) +{ + if ( value && href && ( strcmp(value, href) == 0 ) ) { + /* No change, do nothing. */ + } else { + g_free(href); + href = NULL; + if (value) { + // First, set the href field, because sp_conn_end_href_changed will need it. + href = g_strdup(value); + + // Now do the attaching, which emits the changed signal. + try { + ref.attach(Inkscape::URI(value)); + } catch (Inkscape::BadURIException &e) { + /* TODO: Proper error handling as per + * http://www.w3.org/TR/SVG11/implnote.html#ErrorProcessing. (Also needed for + * sp-use.) */ + g_warning("%s", e.what()); + ref.detach(); + } + } else { + ref.detach(); + } + } +} + +void +sp_conn_end_href_changed(SPObject *old_ref, SPObject *ref, + SPConnEnd *connEndPtr, SPPath *const path, unsigned const handle_ix) +{ + g_return_if_fail(connEndPtr != NULL); + SPConnEnd &connEnd = *connEndPtr; + connEnd._delete_connection.disconnect(); + connEnd._transformed_connection.disconnect(); + + if (connEnd.href) { + SPObject *refobj = connEnd.ref.getObject(); + if (refobj) { + connEnd._delete_connection + = SP_OBJECT(refobj)->connectDelete(sigc::bind(sigc::ptr_fun(&sp_conn_end_deleted), + SP_OBJECT(path), handle_ix)); + connEnd._transformed_connection + = SP_ITEM(refobj)->connectTransformed(sigc::bind(sigc::ptr_fun(&sp_conn_end_shape_move_compensate), + path)); + } + } +} + + + +/* + 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 : diff --git a/src/sp-conn-end.h b/src/sp-conn-end.h new file mode 100644 index 000000000..a565b6404 --- /dev/null +++ b/src/sp-conn-end.h @@ -0,0 +1,51 @@ +#ifndef SEEN_SP_CONN_END +#define SEEN_SP_CONN_END + +#include +#include + +#include "sp-use-reference.h" + + +class SPConnEnd { +public: + SPConnEnd(SPObject *owner); + + SPUseReference ref; + gchar *href; + + /** Change of href string (not a modification of the attributes of the referrent). */ + sigc::connection _changed_connection; + + /** Called when the attached object gets deleted. */ + sigc::connection _delete_connection; + + /** A sigc connection for transformed signal, used to do move compensation. */ + sigc::connection _transformed_connection; + + void setAttacherHref(gchar const *); + +private: + SPConnEnd(SPConnEnd const &); + SPConnEnd &operator=(SPConnEnd const &); +}; + +void sp_conn_end_href_changed(SPObject *old_ref, SPObject *ref, + SPConnEnd *connEnd, SPPath *path, unsigned const handle_ix); +void sp_conn_adjust_invalid_path(SPPath *const path); +void sp_conn_adjust_path(SPPath *const path); +void sp_conn_end_detach(SPObject *const owner, unsigned const handle_ix); + + +#endif /* !SEEN_SP_CONN_END */ + +/* + 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 : diff --git a/src/sp-cursor.cpp b/src/sp-cursor.cpp new file mode 100644 index 000000000..f59c63487 --- /dev/null +++ b/src/sp-cursor.cpp @@ -0,0 +1,115 @@ +#define __SP_CURSOR_C__ + +/* + * Some convenience stuff + * + * Authors: + * Lauris Kaplinski + * + * Copyright (C) 1999-2002 authors + * Copyright (C) 2001-2002 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include +#include +#include "sp-cursor.h" + +void sp_cursor_bitmap_and_mask_from_xpm (GdkBitmap **bitmap, GdkBitmap **mask, gchar **xpm) +{ + int height; + int width; + int colors; + int pix; + sscanf(xpm[0], "%d %d %d %d", &height, &width, &colors, &pix); + + g_return_if_fail (height == 32); + g_return_if_fail (width == 32); + g_return_if_fail (colors >= 3); + + int transparent_color = ' '; + int black_color = '.'; + + char pixmap_buffer[(32 * 32)/8]; + char mask_buffer[(32 * 32)/8]; + + for (int i = 0; i < colors; i++) { + + char const *p = xpm[1 + i]; + char const ccode = *p; + + p++; + while (isspace(*p)) { + p++; + } + p++; + while (isspace(*p)) { + p++; + } + + if (strcmp(p, "None") == 0) { + transparent_color = ccode; + } + + if (strcmp(p, "#000000") == 0) { + black_color = ccode; + } + } + + for (int y = 0; y < 32; y++) { + for (int x = 0; x < 32; ) { + + char value = 0; + char maskv = 0; + + for (int pix = 0; pix < 8; pix++, x++){ + if (xpm [4+y][x] != transparent_color) { + maskv |= 1 << pix; + + if (xpm [4+y][x] == black_color) { + value |= 1 << pix; + } + } + } + + pixmap_buffer[(y * 4 + x/8)-1] = value; + mask_buffer[(y * 4 + x/8)-1] = maskv; + } + } + + *bitmap = gdk_bitmap_create_from_data(NULL, pixmap_buffer, 32, 32); + *mask = gdk_bitmap_create_from_data(NULL, mask_buffer, 32, 32); +} + +GdkCursor *sp_cursor_new_from_xpm (gchar **xpm, gint hot_x, gint hot_y) +{ + GdkColor const fg = { 0, 0, 0, 0 }; + GdkColor const bg = { 0, 65535, 65535, 65535 }; + + GdkBitmap *bitmap = NULL; + GdkBitmap *mask = NULL; + + sp_cursor_bitmap_and_mask_from_xpm (&bitmap, &mask, xpm); + if ( bitmap != NULL && mask != NULL ) { + GdkCursor *new_cursor = gdk_cursor_new_from_pixmap (bitmap, mask, + &fg, &bg, + hot_x, hot_y); + g_object_unref (bitmap); + g_object_unref (mask); + return new_cursor; + } + + return NULL; +} + +/* + 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 : diff --git a/src/sp-cursor.h b/src/sp-cursor.h new file mode 100644 index 000000000..36468aae8 --- /dev/null +++ b/src/sp-cursor.h @@ -0,0 +1,20 @@ +#ifndef SP_CURSOR_H +#define SP_CURSOR_H + +#include + +void sp_cursor_bitmap_and_mask_from_xpm(GdkBitmap **bitmap, GdkBitmap **mask, gchar **xpm); +GdkCursor *sp_cursor_new_from_xpm(gchar **xpm, gint hot_x, gint hot_y); + +#endif + +/* + 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:textwidth=99 : diff --git a/src/sp-defs.cpp b/src/sp-defs.cpp new file mode 100644 index 000000000..ad6cfc578 --- /dev/null +++ b/src/sp-defs.cpp @@ -0,0 +1,172 @@ +#define __SP_DEFS_C__ + +/* + * SVG implementation + * + * Authors: + * Lauris Kaplinski + * + * Copyright (C) 2000-2002 authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +/* + * fixme: We should really check childrens validity - currently everything + * flips in + */ + +#include "sp-defs.h" +#include "xml/repr.h" + +static void sp_defs_class_init(SPDefsClass *dc); +static void sp_defs_init(SPDefs *defs); + +static void sp_defs_release(SPObject *object); +static void sp_defs_update(SPObject *object, SPCtx *ctx, guint flags); +static void sp_defs_modified(SPObject *object, guint flags); +static Inkscape::XML::Node *sp_defs_write(SPObject *object, Inkscape::XML::Node *repr, guint flags); + +static SPObjectClass *parent_class; + +GType sp_defs_get_type(void) +{ + static GType defs_type = 0; + + if (!defs_type) { + GTypeInfo defs_info = { + sizeof(SPDefsClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) sp_defs_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof(SPDefs), + 16, /* n_preallocs */ + (GInstanceInitFunc) sp_defs_init, + NULL, /* value_table */ + }; + defs_type = g_type_register_static(SP_TYPE_OBJECT, "SPDefs", &defs_info, (GTypeFlags) 0); + } + + return defs_type; +} + +static void sp_defs_class_init(SPDefsClass *dc) +{ + parent_class = (SPObjectClass *) g_type_class_ref(SP_TYPE_OBJECT); + SPObjectClass *sp_object_class = (SPObjectClass *) dc; + + sp_object_class->release = sp_defs_release; + sp_object_class->update = sp_defs_update; + sp_object_class->modified = sp_defs_modified; + sp_object_class->write = sp_defs_write; +} + +static void sp_defs_init(SPDefs *defs) +{ + +} + +static void sp_defs_release(SPObject *object) +{ + if (((SPObjectClass *) (parent_class))->release) { + ((SPObjectClass *) (parent_class))->release(object); + } +} + +static void sp_defs_update(SPObject *object, SPCtx *ctx, guint flags) +{ + if (flags & SP_OBJECT_MODIFIED_FLAG) { + flags |= SP_OBJECT_PARENT_MODIFIED_FLAG; + } + + flags &= SP_OBJECT_MODIFIED_CASCADE; + + GSList *l = NULL; + for ( SPObject *child = sp_object_first_child(object) ; child != NULL; child = SP_OBJECT_NEXT(child) ) { + g_object_ref(G_OBJECT(child)); + l = g_slist_prepend(l, child); + } + + l = g_slist_reverse(l); + + while (l) { + SPObject *child = SP_OBJECT(l->data); + l = g_slist_remove(l, child); + if (flags || (child->uflags & SP_OBJECT_MODIFIED_FLAG)) { + child->updateDisplay(ctx, flags); + } + g_object_unref(G_OBJECT(child)); + } +} + +static void sp_defs_modified(SPObject *object, guint flags) +{ + if (flags & SP_OBJECT_MODIFIED_FLAG) { + flags |= SP_OBJECT_PARENT_MODIFIED_FLAG; + } + + flags &= SP_OBJECT_MODIFIED_CASCADE; + + GSList *l = NULL; + for ( SPObject *child = sp_object_first_child(object) ; child != NULL; child = SP_OBJECT_NEXT(child) ) { + g_object_ref(G_OBJECT(child)); + l = g_slist_prepend(l, child); + } + + l = g_slist_reverse(l); + + while (l) { + SPObject *child = SP_OBJECT(l->data); + l = g_slist_remove(l, child); + if (flags || (child->mflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { + child->emitModified(flags); + } + g_object_unref(G_OBJECT (child)); + } +} + +static Inkscape::XML::Node *sp_defs_write(SPObject *object, Inkscape::XML::Node *repr, guint flags) +{ + if (flags & SP_OBJECT_WRITE_BUILD) { + + if (!repr) { + repr = sp_repr_new("svg:defs"); + } + + GSList *l = NULL; + for ( SPObject *child = sp_object_first_child(object) ; child != NULL; child = SP_OBJECT_NEXT(child) ) { + Inkscape::XML::Node *crepr = child->updateRepr(NULL, flags); + if (crepr) l = g_slist_prepend(l, crepr); + } + + while (l) { + repr->addChild((Inkscape::XML::Node *) l->data, NULL); + Inkscape::GC::release((Inkscape::XML::Node *) l->data); + l = g_slist_remove(l, l->data); + } + + } else { + for ( SPObject *child = sp_object_first_child(object) ; child != NULL; child = SP_OBJECT_NEXT(child) ) { + child->updateRepr(flags); + } + } + + if (((SPObjectClass *) (parent_class))->write) { + (* ((SPObjectClass *) (parent_class))->write)(object, repr, flags); + } + + return repr; +} + +/* + 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 : diff --git a/src/sp-defs.h b/src/sp-defs.h new file mode 100644 index 000000000..4b6f7a5b7 --- /dev/null +++ b/src/sp-defs.h @@ -0,0 +1,44 @@ +#ifndef SEEN_SP_DEFS_H +#define SEEN_SP_DEFS_H + +/* + * SVG implementation + * + * Authors: + * Lauris Kaplinski + * + * Copyright (C) 2000-2002 authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "sp-object.h" + +#define SP_TYPE_DEFS (sp_defs_get_type()) +#define SP_DEFS(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), SP_TYPE_DEFS, SPDefs)) +#define SP_DEFS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), SP_TYPE_DEFS, SPDefsClass)) +#define SP_IS_DEFS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), SP_TYPE_DEFS)) +#define SP_IS_DEFS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), SP_TYPE_DEFS)) + +struct SPDefs : public SPObject { +}; + +struct SPDefsClass { + SPObjectClass parent_class; +}; + +GType sp_defs_get_type(void); + + +#endif /* !SEEN_SP_DEFS_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 : diff --git a/src/sp-ellipse.cpp b/src/sp-ellipse.cpp new file mode 100644 index 000000000..b2b0f7b05 --- /dev/null +++ b/src/sp-ellipse.cpp @@ -0,0 +1,863 @@ +#define __SP_ELLIPSE_C__ + +/* + * SVG and related implementations + * + * Authors: + * Lauris Kaplinski + * Mitsuru Oka + * bulia byak + * + * Copyright (C) 1999-2002 Lauris Kaplinski + * Copyright (C) 2000-2001 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + + +#include "libnr/n-art-bpath.h" +#include "libnr/nr-path.h" +#include "libnr/nr-matrix-fns.h" +#include "svg/svg.h" +#include "svg/stringstream.h" +#include "xml/repr.h" +#include "attributes.h" +#include "style.h" +#include "display/curve.h" +#include + +#include "sp-ellipse.h" + +#include "prefs-utils.h" + +/* Common parent class */ + +#define noELLIPSE_VERBOSE + +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +#define SP_2PI (2 * M_PI) + +#if 1 +/* Hmmm... shouldn't this also qualify */ +/* Whether it is faster or not, well, nobody knows */ +#define sp_round(v,m) (((v) < 0.0) ? ((ceil((v) / (m) - 0.5)) * (m)) : ((floor((v) / (m) + 0.5)) * (m))) +#else +/* we do not use C99 round(3) function yet */ +static double sp_round(double x, double y) +{ + double remain; + + g_assert(y > 0.0); + + /* return round(x/y) * y; */ + + remain = fmod(x, y); + + if (remain >= 0.5*y) + return x - remain + y; + else + return x - remain; +} +#endif + +static void sp_genericellipse_class_init(SPGenericEllipseClass *klass); +static void sp_genericellipse_init(SPGenericEllipse *ellipse); + +static void sp_genericellipse_update(SPObject *object, SPCtx *ctx, guint flags); + +static void sp_genericellipse_snappoints(SPItem const *item, SnapPointsIter p); + +static void sp_genericellipse_set_shape(SPShape *shape); +static Inkscape::XML::Node *sp_genericellipse_write(SPObject *object, Inkscape::XML::Node *repr, + guint flags); + +static gboolean sp_arc_set_elliptical_path_attribute(SPArc *arc, Inkscape::XML::Node *repr); + +static SPShapeClass *ge_parent_class; + +GType +sp_genericellipse_get_type(void) +{ + static GType type = 0; + if (!type) { + GTypeInfo info = { + sizeof(SPGenericEllipseClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) sp_genericellipse_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof(SPGenericEllipse), + 16, /* n_preallocs */ + (GInstanceInitFunc) sp_genericellipse_init, + NULL, /* value_table */ + }; + type = g_type_register_static(SP_TYPE_SHAPE, "SPGenericEllipse", &info, (GTypeFlags)0); + } + return type; +} + +static void sp_genericellipse_class_init(SPGenericEllipseClass *klass) +{ + SPObjectClass *sp_object_class = (SPObjectClass *) klass; + SPItemClass *item_class = (SPItemClass *) klass; + SPShapeClass *shape_class = (SPShapeClass *) klass; + + ge_parent_class = (SPShapeClass*) g_type_class_ref(SP_TYPE_SHAPE); + + sp_object_class->update = sp_genericellipse_update; + sp_object_class->write = sp_genericellipse_write; + + item_class->snappoints = sp_genericellipse_snappoints; + + shape_class->set_shape = sp_genericellipse_set_shape; +} + +static void +sp_genericellipse_init(SPGenericEllipse *ellipse) +{ + ellipse->cx.unset(); + ellipse->cy.unset(); + ellipse->rx.unset(); + ellipse->ry.unset(); + + ellipse->start = 0.0; + ellipse->end = SP_2PI; + ellipse->closed = TRUE; +} + +static void +sp_genericellipse_update(SPObject *object, SPCtx *ctx, guint flags) +{ + if (flags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG)) { + SPGenericEllipse *ellipse = (SPGenericEllipse *) object; + SPStyle const *style = object->style; + double const d = 1.0 / NR::expansion(((SPItemCtx const *) ctx)->i2vp); + double const em = style->font_size.computed; + double const ex = em * 0.5; // fixme: get from pango or libnrtype + ellipse->cx.update(em, ex, d); + ellipse->cy.update(em, ex, d); + ellipse->rx.update(em, ex, d); + ellipse->ry.update(em, ex, d); + sp_shape_set_shape((SPShape *) object); + } + + if (((SPObjectClass *) ge_parent_class)->update) + ((SPObjectClass *) ge_parent_class)->update(object, ctx, flags); +} + +#define C1 0.552 + +/* fixme: Think (Lauris) */ + +static void sp_genericellipse_set_shape(SPShape *shape) +{ + double cx, cy, rx, ry, s, e; + double x0, y0, x1, y1, x2, y2, x3, y3; + double len; + gint slice = FALSE; + gint i; + + SPGenericEllipse *ellipse = (SPGenericEllipse *) shape; + + if ((ellipse->rx.computed < 1e-18) || (ellipse->ry.computed < 1e-18)) return; + if (fabs(ellipse->end - ellipse->start) < 1e-9) return; + + sp_genericellipse_normalize(ellipse); + + cx = 0.0; + cy = 0.0; + rx = ellipse->rx.computed; + ry = ellipse->ry.computed; + + // figure out if we have a slice, guarding against rounding errors + len = fmod(ellipse->end - ellipse->start, SP_2PI); + if (len < 0.0) len += SP_2PI; + if (fabs(len) < 1e-8 || fabs(len - SP_2PI) < 1e-8) { + slice = FALSE; + ellipse->end = ellipse->start + SP_2PI; + } else { + slice = TRUE; + } + + NR::Matrix aff = NR::Matrix(NR::scale(rx, ry)); + aff[4] = ellipse->cx.computed; + aff[5] = ellipse->cy.computed; + + NArtBpath bpath[16]; + i = 0; + if (ellipse->closed) { + bpath[i].code = NR_MOVETO; + } else { + bpath[i].code = NR_MOVETO_OPEN; + } + bpath[i].x3 = cos(ellipse->start); + bpath[i].y3 = sin(ellipse->start); + i++; + + for (s = ellipse->start; s < ellipse->end; s += M_PI_2) { + e = s + M_PI_2; + if (e > ellipse->end) + e = ellipse->end; + len = C1 * (e - s) / M_PI_2; + x0 = cos(s); + y0 = sin(s); + x1 = x0 + len * cos(s + M_PI_2); + y1 = y0 + len * sin(s + M_PI_2); + x3 = cos(e); + y3 = sin(e); + x2 = x3 + len * cos(e - M_PI_2); + y2 = y3 + len * sin(e - M_PI_2); +#ifdef ELLIPSE_VERBOSE + g_print("step %d s %f e %f coords %f %f %f %f %f %f\n", + i, s, e, x1, y1, x2, y2, x3, y3); +#endif + bpath[i].code = NR_CURVETO; + bpath[i].x1 = x1; + bpath[i].y1 = y1; + bpath[i].x2 = x2; + bpath[i].y2 = y2; + bpath[i].x3 = x3; + bpath[i].y3 = y3; + i++; + } + + if (slice && ellipse->closed) { + bpath[i].code = NR_LINETO; + bpath[i].x3 = 0.0; + bpath[i].y3 = 0.0; + i++; + bpath[i].code = NR_LINETO; + bpath[i].x3 = bpath[0].x3; + bpath[i].y3 = bpath[0].y3; + i++; + } else if (ellipse->closed) { + bpath[i-1].x3 = bpath[0].x3; + bpath[i-1].y3 = bpath[0].y3; + } + + bpath[i].code = NR_END; + SPCurve *c = sp_curve_new_from_bpath(nr_artpath_affine(bpath, aff)); + g_assert(c != NULL); + + sp_shape_set_curve_insync((SPShape *) ellipse, c, TRUE); + sp_curve_unref(c); +} + +static void sp_genericellipse_snappoints(SPItem const *item, SnapPointsIter p) +{ + SPGenericEllipse const *ge = SP_GENERICELLIPSE(item); + + NR::Matrix const i2d = sp_item_i2d_affine(item); + + /* Add the centre */ + *p = NR::Point(ge->cx.computed, ge->cy.computed) * i2d; + + // TODO: add the ends of radii +} + +void +sp_genericellipse_normalize(SPGenericEllipse *ellipse) +{ + ellipse->start = fmod(ellipse->start, SP_2PI); + ellipse->end = fmod(ellipse->end, SP_2PI); + + if (ellipse->start < 0.0) + ellipse->start += SP_2PI; + double diff = ellipse->start - ellipse->end; + if (diff >= 0.0) + ellipse->end += diff - fmod(diff, SP_2PI) + SP_2PI; + + /* Now we keep: 0 <= start < end <= 2*PI */ +} + +static Inkscape::XML::Node *sp_genericellipse_write(SPObject *object, Inkscape::XML::Node *repr, guint flags) +{ + SPGenericEllipse *ellipse = SP_GENERICELLIPSE(object); + + if (flags & SP_OBJECT_WRITE_EXT) { + if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { + repr = sp_repr_new("svg:path"); + } + + sp_repr_set_svg_double(repr, "sodipodi:cx", ellipse->cx.computed); + sp_repr_set_svg_double(repr, "sodipodi:cy", ellipse->cy.computed); + sp_repr_set_svg_double(repr, "sodipodi:rx", ellipse->rx.computed); + sp_repr_set_svg_double(repr, "sodipodi:ry", ellipse->ry.computed); + + if (SP_IS_ARC(ellipse)) + sp_arc_set_elliptical_path_attribute(SP_ARC(object), SP_OBJECT_REPR(object)); + } + + if (((SPObjectClass *) ge_parent_class)->write) + ((SPObjectClass *) ge_parent_class)->write(object, repr, flags); + + return repr; +} + +/* SVG element */ + +static void sp_ellipse_class_init(SPEllipseClass *klass); +static void sp_ellipse_init(SPEllipse *ellipse); + +static void sp_ellipse_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr); +static Inkscape::XML::Node *sp_ellipse_write(SPObject *object, Inkscape::XML::Node *repr, guint flags); +static void sp_ellipse_set(SPObject *object, unsigned int key, gchar const *value); +static gchar *sp_ellipse_description(SPItem *item); + +static SPGenericEllipseClass *ellipse_parent_class; + +GType +sp_ellipse_get_type(void) +{ + static GType type = 0; + if (!type) { + GTypeInfo info = { + sizeof(SPEllipseClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) sp_ellipse_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof(SPEllipse), + 16, /* n_preallocs */ + (GInstanceInitFunc) sp_ellipse_init, + NULL, /* value_table */ + }; + type = g_type_register_static(SP_TYPE_GENERICELLIPSE, "SPEllipse", &info, (GTypeFlags)0); + } + return type; +} + +static void sp_ellipse_class_init(SPEllipseClass *klass) +{ + SPObjectClass *sp_object_class = (SPObjectClass *) klass; + SPItemClass *item_class = (SPItemClass *) klass; + + ellipse_parent_class = (SPGenericEllipseClass*) g_type_class_ref(SP_TYPE_GENERICELLIPSE); + + sp_object_class->build = sp_ellipse_build; + sp_object_class->write = sp_ellipse_write; + sp_object_class->set = sp_ellipse_set; + + item_class->description = sp_ellipse_description; +} + +static void +sp_ellipse_init(SPEllipse *ellipse) +{ + /* Nothing special */ +} + +static void +sp_ellipse_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr) +{ + if (((SPObjectClass *) ellipse_parent_class)->build) + (* ((SPObjectClass *) ellipse_parent_class)->build) (object, document, repr); + + sp_object_read_attr(object, "cx"); + sp_object_read_attr(object, "cy"); + sp_object_read_attr(object, "rx"); + sp_object_read_attr(object, "ry"); +} + +static Inkscape::XML::Node * +sp_ellipse_write(SPObject *object, Inkscape::XML::Node *repr, guint flags) +{ + SPGenericEllipse *ellipse; + + ellipse = SP_GENERICELLIPSE(object); + + if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { + repr = sp_repr_new("svg:ellipse"); + } + + sp_repr_set_svg_double(repr, "cx", ellipse->cx.computed); + sp_repr_set_svg_double(repr, "cy", ellipse->cy.computed); + sp_repr_set_svg_double(repr, "rx", ellipse->rx.computed); + sp_repr_set_svg_double(repr, "ry", ellipse->ry.computed); + + if (((SPObjectClass *) ellipse_parent_class)->write) + (* ((SPObjectClass *) ellipse_parent_class)->write) (object, repr, flags); + + return repr; +} + +static void +sp_ellipse_set(SPObject *object, unsigned int key, gchar const *value) +{ + SPGenericEllipse *ellipse; + + ellipse = SP_GENERICELLIPSE(object); + + switch (key) { + case SP_ATTR_CX: + ellipse->cx.readOrUnset(value); + object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_CY: + ellipse->cy.readOrUnset(value); + object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_RX: + if (!ellipse->rx.read(value) || (ellipse->rx.value <= 0.0)) { + ellipse->rx.unset(); + } + object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_RY: + if (!ellipse->ry.read(value) || (ellipse->ry.value <= 0.0)) { + ellipse->ry.unset(); + } + object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + break; + default: + if (((SPObjectClass *) ellipse_parent_class)->set) + ((SPObjectClass *) ellipse_parent_class)->set(object, key, value); + break; + } +} + +static gchar *sp_ellipse_description(SPItem *item) +{ + return g_strdup(_("Ellipse")); +} + + +void +sp_ellipse_position_set(SPEllipse *ellipse, gdouble x, gdouble y, gdouble rx, gdouble ry) +{ + SPGenericEllipse *ge; + + g_return_if_fail(ellipse != NULL); + g_return_if_fail(SP_IS_ELLIPSE(ellipse)); + + ge = SP_GENERICELLIPSE(ellipse); + + ge->cx.computed = x; + ge->cy.computed = y; + ge->rx.computed = rx; + ge->ry.computed = ry; + + ((SPObject *)ge)->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); +} + +/* SVG element */ + +static void sp_circle_class_init(SPCircleClass *klass); +static void sp_circle_init(SPCircle *circle); + +static void sp_circle_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr); +static Inkscape::XML::Node *sp_circle_write(SPObject *object, Inkscape::XML::Node *repr, guint flags); +static void sp_circle_set(SPObject *object, unsigned int key, gchar const *value); +static gchar *sp_circle_description(SPItem *item); + +static SPGenericEllipseClass *circle_parent_class; + +GType +sp_circle_get_type(void) +{ + static GType type = 0; + if (!type) { + GTypeInfo info = { + sizeof(SPCircleClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) sp_circle_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof(SPCircle), + 16, /* n_preallocs */ + (GInstanceInitFunc) sp_circle_init, + NULL, /* value_table */ + }; + type = g_type_register_static(SP_TYPE_GENERICELLIPSE, "SPCircle", &info, (GTypeFlags)0); + } + return type; +} + +static void +sp_circle_class_init(SPCircleClass *klass) +{ + SPObjectClass *sp_object_class = (SPObjectClass *) klass; + SPItemClass *item_class = (SPItemClass *) klass; + + circle_parent_class = (SPGenericEllipseClass*) g_type_class_ref(SP_TYPE_GENERICELLIPSE); + + sp_object_class->build = sp_circle_build; + sp_object_class->write = sp_circle_write; + sp_object_class->set = sp_circle_set; + + item_class->description = sp_circle_description; +} + +static void +sp_circle_init(SPCircle *circle) +{ + /* Nothing special */ +} + +static void +sp_circle_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr) +{ + if (((SPObjectClass *) circle_parent_class)->build) + (* ((SPObjectClass *) circle_parent_class)->build)(object, document, repr); + + sp_object_read_attr(object, "cx"); + sp_object_read_attr(object, "cy"); + sp_object_read_attr(object, "r"); +} + +static Inkscape::XML::Node * +sp_circle_write(SPObject *object, Inkscape::XML::Node *repr, guint flags) +{ + SPGenericEllipse *ellipse; + + ellipse = SP_GENERICELLIPSE(object); + + if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { + repr = sp_repr_new("svg:circle"); + } + + sp_repr_set_svg_double(repr, "cx", ellipse->cx.computed); + sp_repr_set_svg_double(repr, "cy", ellipse->cy.computed); + sp_repr_set_svg_double(repr, "r", ellipse->rx.computed); + + if (((SPObjectClass *) circle_parent_class)->write) + ((SPObjectClass *) circle_parent_class)->write(object, repr, flags); + + return repr; +} + +static void +sp_circle_set(SPObject *object, unsigned int key, gchar const *value) +{ + SPGenericEllipse *ge; + + ge = SP_GENERICELLIPSE(object); + + switch (key) { + case SP_ATTR_CX: + ge->cx.readOrUnset(value); + object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_CY: + ge->cy.readOrUnset(value); + object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_R: + if (!ge->rx.read(value) || ge->rx.value <= 0.0) { + ge->rx.unset(); + } + ge->ry = ge->rx; + object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + break; + default: + if (((SPObjectClass *) circle_parent_class)->set) + ((SPObjectClass *) circle_parent_class)->set(object, key, value); + break; + } +} + +static gchar *sp_circle_description(SPItem *item) +{ + return g_strdup(_("Circle")); +} + +/* element */ + +static void sp_arc_class_init(SPArcClass *klass); +static void sp_arc_init(SPArc *arc); + +static void sp_arc_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr); +static Inkscape::XML::Node *sp_arc_write(SPObject *object, Inkscape::XML::Node *repr, guint flags); +static void sp_arc_set(SPObject *object, unsigned int key, gchar const *value); +static void sp_arc_modified(SPObject *object, guint flags); + +static gchar *sp_arc_description(SPItem *item); + +static SPGenericEllipseClass *arc_parent_class; + +GType +sp_arc_get_type(void) +{ + static GType type = 0; + if (!type) { + GTypeInfo info = { + sizeof(SPArcClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) sp_arc_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof(SPArc), + 16, /* n_preallocs */ + (GInstanceInitFunc) sp_arc_init, + NULL, /* value_table */ + }; + type = g_type_register_static(SP_TYPE_GENERICELLIPSE, "SPArc", &info, (GTypeFlags)0); + } + return type; +} + +static void +sp_arc_class_init(SPArcClass *klass) +{ + SPObjectClass *sp_object_class = (SPObjectClass *) klass; + SPItemClass *item_class = (SPItemClass *) klass; + + arc_parent_class = (SPGenericEllipseClass*) g_type_class_ref(SP_TYPE_GENERICELLIPSE); + + sp_object_class->build = sp_arc_build; + sp_object_class->write = sp_arc_write; + sp_object_class->set = sp_arc_set; + sp_object_class->modified = sp_arc_modified; + + item_class->description = sp_arc_description; +} + +static void +sp_arc_init(SPArc *arc) +{ + /* Nothing special */ +} + +static void +sp_arc_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr) +{ + if (((SPObjectClass *) arc_parent_class)->build) + (* ((SPObjectClass *) arc_parent_class)->build) (object, document, repr); + + Inkscape::Version version = sp_object_get_sodipodi_version(object); + + sp_object_read_attr(object, "sodipodi:cx"); + sp_object_read_attr(object, "sodipodi:cy"); + sp_object_read_attr(object, "sodipodi:rx"); + sp_object_read_attr(object, "sodipodi:ry"); + + sp_object_read_attr(object, "sodipodi:start"); + sp_object_read_attr(object, "sodipodi:end"); + sp_object_read_attr(object, "sodipodi:open"); +} + +/* + * sp_arc_set_elliptical_path_attribute: + * + * Convert center to endpoint parameterization and set it to repr. + * + * See SVG 1.0 Specification W3C Recommendation + * ``F.6 Ellptical arc implementation notes'' for more detail. + */ +static gboolean +sp_arc_set_elliptical_path_attribute(SPArc *arc, Inkscape::XML::Node *repr) +{ + gint fa, fs; + gdouble dt; + Inkscape::SVGOStringStream os; + + SPGenericEllipse *ge = SP_GENERICELLIPSE(arc); + + NR::Point p1 = sp_arc_get_xy(arc, ge->start); + NR::Point p2 = sp_arc_get_xy(arc, ge->end); + + dt = fmod(ge->end - ge->start, SP_2PI); + if (fabs(dt) < 1e-6) { + NR::Point ph = sp_arc_get_xy(arc, (ge->start + ge->end) / 2.0); + os << "M " << p1[NR::X] << " " << p1[NR::Y] + << " A " << ge->rx.computed << " " << ge->ry.computed + << " 0 1 1 " << " " << ph[NR::X] << "," << ph[NR::Y] + << " A " << ge->rx.computed << " " << ge->ry.computed + << " 0 1 1 " << " " << p2[NR::X] << " " << p2[NR::Y] << " z"; + } else { + fa = (fabs(dt) > M_PI) ? 1 : 0; + fs = (dt > 0) ? 1 : 0; +#ifdef ARC_VERBOSE + g_print("start:%g end:%g fa=%d fs=%d\n", ge->start, ge->end, fa, fs); +#endif + if (ge->closed) { + os << "M " << p1[NR::X] << "," << p1[NR::Y] + << " A " << ge->rx.computed << "," << ge->ry.computed + << " 0 " << fa << " " << fs << " " << p2[NR::X] << "," << p2[NR::Y] + << " L " << ge->cx.computed << "," << ge->cy.computed << " z"; + } else { + os << "M " << p1[NR::X] << "," << p1[NR::Y] + << " A " << ge->rx.computed << "," << ge->ry.computed + << " 0 " << fa << " " << fs << " " << p2[NR::X] << "," << p2[NR::Y]; + + } + } + repr->setAttribute("d", os.str().c_str()); + return true; +} + +static Inkscape::XML::Node * +sp_arc_write(SPObject *object, Inkscape::XML::Node *repr, guint flags) +{ + SPGenericEllipse *ge = SP_GENERICELLIPSE(object); + SPArc *arc = SP_ARC(object); + + if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { + repr = sp_repr_new("svg:path"); + } + + if (flags & SP_OBJECT_WRITE_EXT) { + repr->setAttribute("sodipodi:type", "arc"); + sp_repr_set_svg_double(repr, "sodipodi:cx", ge->cx.computed); + sp_repr_set_svg_double(repr, "sodipodi:cy", ge->cy.computed); + sp_repr_set_svg_double(repr, "sodipodi:rx", ge->rx.computed); + sp_repr_set_svg_double(repr, "sodipodi:ry", ge->ry.computed); + + // write start and end only if they are non-trivial; otherwise remove + gdouble len = fmod(ge->end - ge->start, SP_2PI); + if (len < 0.0) len += SP_2PI; + if (!(fabs(len) < 1e-8 || fabs(len - SP_2PI) < 1e-8)) { + sp_repr_set_svg_double(repr, "sodipodi:start", ge->start); + sp_repr_set_svg_double(repr, "sodipodi:end", ge->end); + repr->setAttribute("sodipodi:open", (!ge->closed) ? "true" : NULL); + } else { + repr->setAttribute("sodipodi:end", NULL); + repr->setAttribute("sodipodi:start", NULL); + repr->setAttribute("sodipodi:open", NULL); + } + } + + // write d= + sp_arc_set_elliptical_path_attribute(arc, repr); + + if (((SPObjectClass *) arc_parent_class)->write) + ((SPObjectClass *) arc_parent_class)->write(object, repr, flags); + + return repr; +} + +static void +sp_arc_set(SPObject *object, unsigned int key, gchar const *value) +{ + SPGenericEllipse *ge = SP_GENERICELLIPSE(object); + + switch (key) { + case SP_ATTR_SODIPODI_CX: + ge->cx.readOrUnset(value); + object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_SODIPODI_CY: + ge->cy.readOrUnset(value); + object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_SODIPODI_RX: + if (!ge->rx.read(value) || ge->rx.computed <= 0.0) { + ge->rx.unset(); + } + object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_SODIPODI_RY: + if (!ge->ry.read(value) || ge->ry.computed <= 0.0) { + ge->ry.unset(); + } + object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_SODIPODI_START: + if (value) { + sp_svg_number_read_d(value, &ge->start); + } else { + ge->start = 0; + } + object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_SODIPODI_END: + if (value) { + sp_svg_number_read_d(value, &ge->end); + } else { + ge->end = 2 * M_PI; + } + object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_SODIPODI_OPEN: + ge->closed = (!value); + object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + break; + default: + if (((SPObjectClass *) arc_parent_class)->set) + ((SPObjectClass *) arc_parent_class)->set(object, key, value); + break; + } +} + +static void +sp_arc_modified(SPObject *object, guint flags) +{ + if (flags & SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG) { + sp_shape_set_shape((SPShape *) object); + } + + if (((SPObjectClass *) arc_parent_class)->modified) + ((SPObjectClass *) arc_parent_class)->modified(object, flags); +} + +static gchar *sp_arc_description(SPItem *item) +{ + SPGenericEllipse *ge = SP_GENERICELLIPSE(item); + + gdouble len = fmod(ge->end - ge->start, SP_2PI); + if (len < 0.0) len += SP_2PI; + if (!(fabs(len) < 1e-8 || fabs(len - SP_2PI) < 1e-8)) { + if (ge->closed) { + return g_strdup(_("Segment")); + } else { + return g_strdup(_("Arc")); + } + } else { + return g_strdup(_("Ellipse")); + } +} + +void +sp_arc_position_set(SPArc *arc, gdouble x, gdouble y, gdouble rx, gdouble ry) +{ + g_return_if_fail(arc != NULL); + g_return_if_fail(SP_IS_ARC(arc)); + + SPGenericEllipse *ge = SP_GENERICELLIPSE(arc); + + ge->cx.computed = x; + ge->cy.computed = y; + ge->rx.computed = rx; + ge->ry.computed = ry; + if (prefs_get_double_attribute("tools.shapes.arc", "start", 0.0) != 0) + ge->start = prefs_get_double_attribute("tools.shapes.arc", "start", 0.0); + if (prefs_get_double_attribute("tools.shapes.arc", "end", 0.0) != 0) + ge->end = prefs_get_double_attribute("tools.shapes.arc", "end", 0.0); + if (!prefs_get_string_attribute("tools.shapes.arc", "open")) + ge->closed = 1; + else + ge->closed = 0; + + ((SPObject *)arc)->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); +} + +NR::Point sp_arc_get_xy(SPArc *arc, gdouble arg) +{ + SPGenericEllipse *ge = SP_GENERICELLIPSE(arc); + + return NR::Point(ge->rx.computed * cos(arg) + ge->cx.computed, + ge->ry.computed * sin(arg) + ge->cy.computed); +} + + +/* + 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:textwidth=99 : diff --git a/src/sp-ellipse.h b/src/sp-ellipse.h new file mode 100644 index 000000000..a1f79e6f5 --- /dev/null +++ b/src/sp-ellipse.h @@ -0,0 +1,105 @@ +#ifndef __SP_ELLIPSE_H__ +#define __SP_ELLIPSE_H__ + +/* + * SVG and related implementations + * + * Authors: + * Lauris Kaplinski + * Mitsuru Oka + * + * Copyright (C) 1999-2002 Lauris Kaplinski + * Copyright (C) 2000-2001 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "svg/svg-length.h" +#include "sp-shape.h" + +/* Common parent class */ + +#define SP_TYPE_GENERICELLIPSE (sp_genericellipse_get_type ()) +#define SP_GENERICELLIPSE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SP_TYPE_GENERICELLIPSE, SPGenericEllipse)) +#define SP_GENERICELLIPSE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SP_TYPE_GENERICELLIPSE, SPGenericEllipseClass)) +#define SP_IS_GENERICELLIPSE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_GENERICELLIPSE)) +#define SP_IS_GENERICELLIPSE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SP_TYPE_GENERICELLIPSE)) + +class SPGenericEllipse; +class SPGenericEllipseClass; + +struct SPGenericEllipse : public SPShape { + SVGLength cx; + SVGLength cy; + SVGLength rx; + SVGLength ry; + + unsigned int closed : 1; + double start, end; +}; + +struct SPGenericEllipseClass { + SPShapeClass parent_class; +}; + +GType sp_genericellipse_get_type (void); + +/* This is technically priate by we need this in object edit (Lauris) */ +void sp_genericellipse_normalize (SPGenericEllipse *ellipse); + +/* SVG element */ + +#define SP_TYPE_ELLIPSE (sp_ellipse_get_type ()) +#define SP_ELLIPSE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SP_TYPE_ELLIPSE, SPEllipse)) +#define SP_ELLIPSE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SP_TYPE_ELLIPSE, SPEllipseClass)) +#define SP_IS_ELLIPSE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_ELLIPSE)) +#define SP_IS_ELLIPSE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SP_TYPE_ELLIPSE)) + +struct SPEllipse : public SPGenericEllipse { +}; + +struct SPEllipseClass { + SPGenericEllipseClass parent_class; +}; + +GType sp_ellipse_get_type (void); + +void sp_ellipse_position_set (SPEllipse * ellipse, gdouble x, gdouble y, gdouble rx, gdouble ry); + +/* SVG element */ + +#define SP_TYPE_CIRCLE (sp_circle_get_type ()) +#define SP_CIRCLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SP_TYPE_CIRCLE, SPCircle)) +#define SP_CIRCLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SP_TYPE_CIRCLE, SPCircleClass)) +#define SP_IS_CIRCLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_CIRCLE)) +#define SP_IS_CIRCLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SP_TYPE_CIRCLE)) + +struct SPCircle : public SPGenericEllipse { +}; + +struct SPCircleClass { + SPGenericEllipseClass parent_class; +}; + +GType sp_circle_get_type (void); + +/* element */ + +#define SP_TYPE_ARC (sp_arc_get_type ()) +#define SP_ARC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SP_TYPE_ARC, SPArc)) +#define SP_ARC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SP_TYPE_ARC, SPArcClass)) +#define SP_IS_ARC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_ARC)) +#define SP_IS_ARC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SP_TYPE_ARC)) + +struct SPArc : public SPGenericEllipse { +}; + +struct SPArcClass { + SPGenericEllipseClass parent_class; +}; + +GType sp_arc_get_type (void); +void sp_arc_position_set (SPArc * arc, gdouble x, gdouble y, gdouble rx, gdouble ry); +NR::Point sp_arc_get_xy (SPArc *ge, gdouble arg); + +#endif diff --git a/src/sp-flowdiv.cpp b/src/sp-flowdiv.cpp new file mode 100644 index 000000000..61a5ec430 --- /dev/null +++ b/src/sp-flowdiv.cpp @@ -0,0 +1,730 @@ +#define __SP_FLOWDIV_C__ + +/* + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "libnr/nr-matrix-ops.h" +#include "xml/repr.h" +//#include "svg/svg.h" + +//#include "style.h" + +#include "sp-flowdiv.h" +#include "sp-string.h" + +static void sp_flowdiv_class_init (SPFlowdivClass *klass); +static void sp_flowdiv_init (SPFlowdiv *group); +static void sp_flowdiv_release (SPObject *object); +static Inkscape::XML::Node *sp_flowdiv_write (SPObject *object, Inkscape::XML::Node *repr, guint flags); +static void sp_flowdiv_update (SPObject *object, SPCtx *ctx, unsigned int flags); +static void sp_flowdiv_modified (SPObject *object, guint flags); +static void sp_flowdiv_build (SPObject *object, SPDocument *doc, Inkscape::XML::Node *repr); +static void sp_flowdiv_set (SPObject *object, unsigned int key, const gchar *value); + +static void sp_flowtspan_class_init (SPFlowtspanClass *klass); +static void sp_flowtspan_init (SPFlowtspan *group); +static void sp_flowtspan_release (SPObject *object); +static Inkscape::XML::Node *sp_flowtspan_write (SPObject *object, Inkscape::XML::Node *repr, guint flags); +static void sp_flowtspan_update (SPObject *object, SPCtx *ctx, unsigned int flags); +static void sp_flowtspan_modified (SPObject *object, guint flags); +static void sp_flowtspan_build (SPObject *object, SPDocument *doc, Inkscape::XML::Node *repr); +static void sp_flowtspan_set (SPObject *object, unsigned int key, const gchar *value); + +static void sp_flowpara_class_init (SPFlowparaClass *klass); +static void sp_flowpara_init (SPFlowpara *group); +static void sp_flowpara_release (SPObject *object); +static Inkscape::XML::Node *sp_flowpara_write (SPObject *object, Inkscape::XML::Node *repr, guint flags); +static void sp_flowpara_update (SPObject *object, SPCtx *ctx, unsigned int flags); +static void sp_flowpara_modified (SPObject *object, guint flags); +static void sp_flowpara_build (SPObject *object, SPDocument *doc, Inkscape::XML::Node *repr); +static void sp_flowpara_set (SPObject *object, unsigned int key, const gchar *value); + +static void sp_flowline_class_init (SPFlowlineClass *klass); +static void sp_flowline_release (SPObject *object); +static void sp_flowline_init (SPFlowline *group); +static Inkscape::XML::Node *sp_flowline_write (SPObject *object, Inkscape::XML::Node *repr, guint flags); +static void sp_flowline_modified (SPObject *object, guint flags); + +static void sp_flowregionbreak_class_init (SPFlowregionbreakClass *klass); +static void sp_flowregionbreak_release (SPObject *object); +static void sp_flowregionbreak_init (SPFlowregionbreak *group); +static Inkscape::XML::Node *sp_flowregionbreak_write (SPObject *object, Inkscape::XML::Node *repr, guint flags); +static void sp_flowregionbreak_modified (SPObject *object, guint flags); + +static SPItemClass * flowdiv_parent_class; +static SPItemClass * flowtspan_parent_class; +static SPItemClass * flowpara_parent_class; +static SPObjectClass * flowline_parent_class; +static SPObjectClass * flowregionbreak_parent_class; + +GType +sp_flowdiv_get_type (void) +{ + static GType group_type = 0; + if (!group_type) { + GTypeInfo group_info = { + sizeof (SPFlowdivClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) sp_flowdiv_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (SPFlowdiv), + 16, /* n_preallocs */ + (GInstanceInitFunc) sp_flowdiv_init, + NULL, /* value_table */ + }; + group_type = g_type_register_static (SP_TYPE_ITEM, "SPFlowdiv", &group_info, (GTypeFlags)0); + } + return group_type; +} + +static void +sp_flowdiv_class_init (SPFlowdivClass *klass) +{ + GObjectClass * object_class; + SPObjectClass * sp_object_class; + + object_class = (GObjectClass *) klass; + sp_object_class = (SPObjectClass *) klass; + + flowdiv_parent_class = (SPItemClass *)g_type_class_ref (SP_TYPE_ITEM); + + sp_object_class->build = sp_flowdiv_build; + sp_object_class->set = sp_flowdiv_set; + sp_object_class->release = sp_flowdiv_release; + sp_object_class->write = sp_flowdiv_write; + sp_object_class->update = sp_flowdiv_update; + sp_object_class->modified = sp_flowdiv_modified; +} + +static void +sp_flowdiv_init (SPFlowdiv *group) +{ +} + +static void +sp_flowdiv_release (SPObject *object) +{ + if (((SPObjectClass *) flowdiv_parent_class)->release) + ((SPObjectClass *) flowdiv_parent_class)->release (object); +} +static void +sp_flowdiv_update (SPObject *object, SPCtx *ctx, unsigned int flags) +{ + SPItemCtx *ictx=(SPItemCtx *) ctx; + SPItemCtx cctx=*ictx; + + if (((SPObjectClass *) (flowdiv_parent_class))->update) + ((SPObjectClass *) (flowdiv_parent_class))->update (object, ctx, flags); + + if (flags & SP_OBJECT_MODIFIED_FLAG) flags |= SP_OBJECT_PARENT_MODIFIED_FLAG; + flags &= SP_OBJECT_MODIFIED_CASCADE; + + GSList* l = NULL; + for (SPObject *child = sp_object_first_child(object) ; child != NULL ; child = SP_OBJECT_NEXT(child) ) { + g_object_ref (G_OBJECT (child)); + l = g_slist_prepend (l, child); + } + l = g_slist_reverse (l); + while (l) { + SPObject *child = SP_OBJECT (l->data); + l = g_slist_remove (l, child); + if (flags || (child->uflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { + if (SP_IS_ITEM (child)) { + SPItem const &chi = *SP_ITEM(child); + cctx.i2doc = chi.transform * ictx->i2doc; + cctx.i2vp = chi.transform * ictx->i2vp; + child->updateDisplay((SPCtx *)&cctx, flags); + } else { + child->updateDisplay(ctx, flags); + } + } + g_object_unref (G_OBJECT (child)); + } +} +static void +sp_flowdiv_modified (SPObject *object, guint flags) +{ + SPObject *child; + GSList *l; + + if (((SPObjectClass *) (flowdiv_parent_class))->modified) + ((SPObjectClass *) (flowdiv_parent_class))->modified (object, flags); + + if (flags & SP_OBJECT_MODIFIED_FLAG) flags |= SP_OBJECT_PARENT_MODIFIED_FLAG; + flags &= SP_OBJECT_MODIFIED_CASCADE; + + l = NULL; + for (child = sp_object_first_child(object) ; child != NULL ; child = SP_OBJECT_NEXT(child) ) { + g_object_ref (G_OBJECT (child)); + l = g_slist_prepend (l, child); + } + l = g_slist_reverse (l); + while (l) { + child = SP_OBJECT (l->data); + l = g_slist_remove (l, child); + if (flags || (child->mflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { + child->emitModified(flags); + } + g_object_unref (G_OBJECT (child)); + } +} + +static void +sp_flowdiv_build (SPObject *object, SPDocument *doc, Inkscape::XML::Node *repr) +{ + object->_requireSVGVersion(Inkscape::Version(1, 2)); + + if (((SPObjectClass *) flowdiv_parent_class)->build) + ((SPObjectClass *) flowdiv_parent_class)->build (object, doc, repr); +} + +static void +sp_flowdiv_set (SPObject *object, unsigned int key, const gchar *value) +{ + if (((SPObjectClass *) flowdiv_parent_class)->set) + (((SPObjectClass *) flowdiv_parent_class)->set) (object, key, value); +} + +static Inkscape::XML::Node * +sp_flowdiv_write (SPObject *object, Inkscape::XML::Node *repr, guint flags) +{ +// SPFlowdiv *group = SP_FLOWDIV (object); + + if ( flags&SP_OBJECT_WRITE_BUILD ) { + if ( repr == NULL ) repr = sp_repr_new ("svg:flowDiv"); + GSList *l = NULL; + for (SPObject* child = sp_object_first_child(object) ; child != NULL ; child = SP_OBJECT_NEXT(child) ) { + Inkscape::XML::Node* c_repr=NULL; + if ( SP_IS_FLOWTSPAN (child) ) { + c_repr = child->updateRepr(NULL, flags); + } else if ( SP_IS_FLOWPARA(child) ) { + c_repr = child->updateRepr(NULL, flags); + } else if ( SP_IS_STRING(child) ) { + c_repr = sp_repr_new_text(SP_STRING(child)->string.c_str()); + } + if ( c_repr ) l = g_slist_prepend (l, c_repr); + } + while ( l ) { + repr->addChild((Inkscape::XML::Node *) l->data, NULL); + Inkscape::GC::release((Inkscape::XML::Node *) l->data); + l = g_slist_remove (l, l->data); + } + } else { + for (SPObject* child = sp_object_first_child(object) ; child != NULL ; child = SP_OBJECT_NEXT(child) ) { + if ( SP_IS_FLOWTSPAN (child) ) { + child->updateRepr(flags); + } else if ( SP_IS_FLOWPARA(child) ) { + child->updateRepr(flags); + } else if ( SP_IS_STRING(child) ) { + SP_OBJECT_REPR (child)->setContent(SP_STRING(child)->string.c_str()); + } + } + } + + if (((SPObjectClass *) (flowdiv_parent_class))->write) + ((SPObjectClass *) (flowdiv_parent_class))->write (object, repr, flags); + + return repr; +} + + +/* + * + */ + +GType +sp_flowtspan_get_type (void) +{ + static GType group_type = 0; + if (!group_type) { + GTypeInfo group_info = { + sizeof (SPFlowtspanClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) sp_flowtspan_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (SPFlowtspan), + 16, /* n_preallocs */ + (GInstanceInitFunc) sp_flowtspan_init, + NULL, /* value_table */ + }; + group_type = g_type_register_static (SP_TYPE_ITEM, "SPFlowtspan", &group_info, (GTypeFlags)0); + } + return group_type; +} + +static void +sp_flowtspan_class_init (SPFlowtspanClass *klass) +{ + GObjectClass * object_class; + SPObjectClass * sp_object_class; + + object_class = (GObjectClass *) klass; + sp_object_class = (SPObjectClass *) klass; + + flowtspan_parent_class = (SPItemClass *)g_type_class_ref (SP_TYPE_ITEM); + + sp_object_class->build = sp_flowtspan_build; + sp_object_class->set = sp_flowtspan_set; + sp_object_class->release = sp_flowtspan_release; + sp_object_class->write = sp_flowtspan_write; + sp_object_class->update = sp_flowtspan_update; + sp_object_class->modified = sp_flowtspan_modified; +} + +static void +sp_flowtspan_init (SPFlowtspan *group) +{ +} + +static void +sp_flowtspan_release (SPObject *object) +{ + if (((SPObjectClass *) flowtspan_parent_class)->release) + ((SPObjectClass *) flowtspan_parent_class)->release (object); +} +static void +sp_flowtspan_update (SPObject *object, SPCtx *ctx, unsigned int flags) +{ +// SPFlowtspan *group=SP_FLOWTSPAN (object); + SPItemCtx *ictx=(SPItemCtx *) ctx; + SPItemCtx cctx=*ictx; + + if (((SPObjectClass *) (flowtspan_parent_class))->update) + ((SPObjectClass *) (flowtspan_parent_class))->update (object, ctx, flags); + + if (flags & SP_OBJECT_MODIFIED_FLAG) flags |= SP_OBJECT_PARENT_MODIFIED_FLAG; + flags &= SP_OBJECT_MODIFIED_CASCADE; + + GSList* l = NULL; + for (SPObject *child = sp_object_first_child(object) ; child != NULL ; child = SP_OBJECT_NEXT(child) ) { + g_object_ref (G_OBJECT (child)); + l = g_slist_prepend (l, child); + } + l = g_slist_reverse (l); + while (l) { + SPObject *child = SP_OBJECT (l->data); + l = g_slist_remove (l, child); + if (flags || (child->uflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { + if (SP_IS_ITEM (child)) { + SPItem const &chi = *SP_ITEM(child); + cctx.i2doc = chi.transform * ictx->i2doc; + cctx.i2vp = chi.transform * ictx->i2vp; + child->updateDisplay((SPCtx *)&cctx, flags); + } else { + child->updateDisplay(ctx, flags); + } + } + g_object_unref (G_OBJECT (child)); + } +} +static void +sp_flowtspan_modified (SPObject *object, guint flags) +{ + SPObject *child; + GSList *l; + + if (((SPObjectClass *) (flowtspan_parent_class))->modified) + ((SPObjectClass *) (flowtspan_parent_class))->modified (object, flags); + + if (flags & SP_OBJECT_MODIFIED_FLAG) flags |= SP_OBJECT_PARENT_MODIFIED_FLAG; + flags &= SP_OBJECT_MODIFIED_CASCADE; + + l = NULL; + for (child = sp_object_first_child(object) ; child != NULL ; child = SP_OBJECT_NEXT(child) ) { + g_object_ref (G_OBJECT (child)); + l = g_slist_prepend (l, child); + } + l = g_slist_reverse (l); + while (l) { + child = SP_OBJECT (l->data); + l = g_slist_remove (l, child); + if (flags || (child->mflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { + child->emitModified(flags); + } + g_object_unref (G_OBJECT (child)); + } +} +static void +sp_flowtspan_build (SPObject *object, SPDocument *doc, Inkscape::XML::Node *repr) +{ + if (((SPObjectClass *) flowtspan_parent_class)->build) + ((SPObjectClass *) flowtspan_parent_class)->build (object, doc, repr); +} +static void +sp_flowtspan_set (SPObject *object, unsigned int key, const gchar *value) +{ + if (((SPObjectClass *) flowtspan_parent_class)->set) + (((SPObjectClass *) flowtspan_parent_class)->set) (object, key, value); +} +static Inkscape::XML::Node * +sp_flowtspan_write (SPObject *object, Inkscape::XML::Node *repr, guint flags) +{ + if ( flags&SP_OBJECT_WRITE_BUILD ) { + if ( repr == NULL ) repr = sp_repr_new ("svg:flowSpan"); + GSList *l = NULL; + for (SPObject* child = sp_object_first_child(object) ; child != NULL ; child = SP_OBJECT_NEXT(child) ) { + Inkscape::XML::Node* c_repr=NULL; + if ( SP_IS_FLOWTSPAN (child) ) { + c_repr = child->updateRepr(NULL, flags); + } else if ( SP_IS_FLOWPARA (child) ) { + c_repr = child->updateRepr(NULL, flags); + } else if ( SP_IS_STRING(child) ) { + c_repr = sp_repr_new_text(SP_STRING(child)->string.c_str()); + } + if ( c_repr ) l = g_slist_prepend (l, c_repr); + } + while ( l ) { + repr->addChild((Inkscape::XML::Node *) l->data, NULL); + Inkscape::GC::release((Inkscape::XML::Node *) l->data); + l = g_slist_remove (l, l->data); + } + } else { + for (SPObject* child = sp_object_first_child(object) ; child != NULL ; child = SP_OBJECT_NEXT(child) ) { + if ( SP_IS_FLOWTSPAN (child) ) { + child->updateRepr(flags); + } else if ( SP_IS_FLOWPARA (child) ) { + child->updateRepr(flags); + } else if ( SP_IS_STRING(child) ) { + SP_OBJECT_REPR (child)->setContent(SP_STRING(child)->string.c_str()); + } + } + } + + if (((SPObjectClass *) (flowtspan_parent_class))->write) + ((SPObjectClass *) (flowtspan_parent_class))->write (object, repr, flags); + + return repr; +} + + + +/* + * + */ + +GType +sp_flowpara_get_type (void) +{ + static GType group_type = 0; + if (!group_type) { + GTypeInfo group_info = { + sizeof (SPFlowparaClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) sp_flowpara_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (SPFlowpara), + 16, /* n_preallocs */ + (GInstanceInitFunc) sp_flowpara_init, + NULL, /* value_table */ + }; + group_type = g_type_register_static (SP_TYPE_ITEM, "SPFlowpara", &group_info, (GTypeFlags)0); + } + return group_type; +} + +static void +sp_flowpara_class_init (SPFlowparaClass *klass) +{ + GObjectClass * object_class; + SPObjectClass * sp_object_class; + + object_class = (GObjectClass *) klass; + sp_object_class = (SPObjectClass *) klass; + + flowpara_parent_class = (SPItemClass *)g_type_class_ref (SP_TYPE_ITEM); + + sp_object_class->build = sp_flowpara_build; + sp_object_class->set = sp_flowpara_set; + sp_object_class->release = sp_flowpara_release; + sp_object_class->write = sp_flowpara_write; + sp_object_class->update = sp_flowpara_update; + sp_object_class->modified = sp_flowpara_modified; +} + +static void +sp_flowpara_init (SPFlowpara *group) +{ +} +static void +sp_flowpara_release (SPObject *object) +{ + if (((SPObjectClass *) flowpara_parent_class)->release) + ((SPObjectClass *) flowpara_parent_class)->release (object); +} + +static void +sp_flowpara_update (SPObject *object, SPCtx *ctx, unsigned int flags) +{ + SPItemCtx *ictx=(SPItemCtx *) ctx; + SPItemCtx cctx=*ictx; + + if (((SPObjectClass *) (flowpara_parent_class))->update) + ((SPObjectClass *) (flowpara_parent_class))->update (object, ctx, flags); + + if (flags & SP_OBJECT_MODIFIED_FLAG) flags |= SP_OBJECT_PARENT_MODIFIED_FLAG; + flags &= SP_OBJECT_MODIFIED_CASCADE; + + GSList* l = NULL; + for (SPObject *child = sp_object_first_child(object) ; child != NULL ; child = SP_OBJECT_NEXT(child) ) { + g_object_ref (G_OBJECT (child)); + l = g_slist_prepend (l, child); + } + l = g_slist_reverse (l); + while (l) { + SPObject *child = SP_OBJECT (l->data); + l = g_slist_remove (l, child); + if (flags || (child->uflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { + if (SP_IS_ITEM (child)) { + SPItem const &chi = *SP_ITEM(child); + cctx.i2doc = chi.transform * ictx->i2doc; + cctx.i2vp = chi.transform * ictx->i2vp; + child->updateDisplay((SPCtx *)&cctx, flags); + } else { + child->updateDisplay(ctx, flags); + } + } + g_object_unref (G_OBJECT (child)); + } +} +static void +sp_flowpara_modified (SPObject *object, guint flags) +{ + SPObject *child; + GSList *l; + + if (((SPObjectClass *) (flowpara_parent_class))->modified) + ((SPObjectClass *) (flowpara_parent_class))->modified (object, flags); + + if (flags & SP_OBJECT_MODIFIED_FLAG) flags |= SP_OBJECT_PARENT_MODIFIED_FLAG; + flags &= SP_OBJECT_MODIFIED_CASCADE; + + l = NULL; + for (child = sp_object_first_child(object) ; child != NULL ; child = SP_OBJECT_NEXT(child) ) { + g_object_ref (G_OBJECT (child)); + l = g_slist_prepend (l, child); + } + l = g_slist_reverse (l); + while (l) { + child = SP_OBJECT (l->data); + l = g_slist_remove (l, child); + if (flags || (child->mflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { + child->emitModified(flags); + } + g_object_unref (G_OBJECT (child)); + } +} +static void +sp_flowpara_build (SPObject *object, SPDocument *doc, Inkscape::XML::Node *repr) +{ + if (((SPObjectClass *) flowpara_parent_class)->build) + ((SPObjectClass *) flowpara_parent_class)->build (object, doc, repr); +} +static void +sp_flowpara_set (SPObject *object, unsigned int key, const gchar *value) +{ + if (((SPObjectClass *) flowpara_parent_class)->set) + (((SPObjectClass *) flowpara_parent_class)->set) (object, key, value); +} +static Inkscape::XML::Node * +sp_flowpara_write (SPObject *object, Inkscape::XML::Node *repr, guint flags) +{ + // SPFlowpara *group = SP_FLOWPARA (object); + + if ( flags&SP_OBJECT_WRITE_BUILD ) { + if ( repr == NULL ) repr = sp_repr_new ("svg:flowPara"); + GSList *l = NULL; + for (SPObject* child = sp_object_first_child(object) ; child != NULL ; child = SP_OBJECT_NEXT(child) ) { + Inkscape::XML::Node* c_repr=NULL; + if ( SP_IS_FLOWTSPAN (child) ) { + c_repr = child->updateRepr(NULL, flags); + } else if ( SP_IS_FLOWPARA (child) ) { + c_repr = child->updateRepr(NULL, flags); + } else if ( SP_IS_STRING(child) ) { + c_repr = sp_repr_new_text(SP_STRING(child)->string.c_str()); + } + if ( c_repr ) l = g_slist_prepend (l, c_repr); + } + while ( l ) { + repr->addChild((Inkscape::XML::Node *) l->data, NULL); + Inkscape::GC::release((Inkscape::XML::Node *) l->data); + l = g_slist_remove (l, l->data); + } + } else { + for (SPObject* child = sp_object_first_child(object) ; child != NULL ; child = SP_OBJECT_NEXT(child) ) { + if ( SP_IS_FLOWTSPAN (child) ) { + child->updateRepr(flags); + } else if ( SP_IS_FLOWPARA (child) ) { + child->updateRepr(flags); + } else if ( SP_IS_STRING(child) ) { + SP_OBJECT_REPR (child)->setContent(SP_STRING(child)->string.c_str()); + } + } + } + + if (((SPObjectClass *) (flowpara_parent_class))->write) + ((SPObjectClass *) (flowpara_parent_class))->write (object, repr, flags); + + return repr; +} + +/* + * + */ + +GType +sp_flowline_get_type (void) +{ + static GType group_type = 0; + if (!group_type) { + GTypeInfo group_info = { + sizeof (SPFlowlineClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) sp_flowline_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (SPFlowline), + 16, /* n_preallocs */ + (GInstanceInitFunc) sp_flowline_init, + NULL, /* value_table */ + }; + group_type = g_type_register_static (SP_TYPE_OBJECT, "SPFlowline", &group_info, (GTypeFlags)0); + } + return group_type; +} + +static void +sp_flowline_class_init (SPFlowlineClass *klass) +{ + GObjectClass * object_class; + SPObjectClass * sp_object_class; + + object_class = (GObjectClass *) klass; + sp_object_class = (SPObjectClass *) klass; + + flowline_parent_class = (SPObjectClass *)g_type_class_ref (SP_TYPE_OBJECT); + + sp_object_class->release = sp_flowline_release; + sp_object_class->write = sp_flowline_write; + sp_object_class->modified = sp_flowline_modified; +} + +static void +sp_flowline_init (SPFlowline *group) +{ +} +static void +sp_flowline_release (SPObject *object) +{ + if (((SPObjectClass *) flowline_parent_class)->release) + ((SPObjectClass *) flowline_parent_class)->release (object); +} + +static void +sp_flowline_modified (SPObject *object, guint flags) +{ + if (((SPObjectClass *) (flowline_parent_class))->modified) + ((SPObjectClass *) (flowline_parent_class))->modified (object, flags); + + if (flags & SP_OBJECT_MODIFIED_FLAG) flags |= SP_OBJECT_PARENT_MODIFIED_FLAG; + flags &= SP_OBJECT_MODIFIED_CASCADE; +} +static Inkscape::XML::Node * +sp_flowline_write (SPObject *object, Inkscape::XML::Node *repr, guint flags) +{ + if ( flags&SP_OBJECT_WRITE_BUILD ) { + if ( repr == NULL ) repr = sp_repr_new ("svg:flowLine"); + } else { + } + + if (((SPObjectClass *) (flowline_parent_class))->write) + ((SPObjectClass *) (flowline_parent_class))->write (object, repr, flags); + + return repr; +} + +/* + * + */ + +GType +sp_flowregionbreak_get_type (void) +{ + static GType group_type = 0; + if (!group_type) { + GTypeInfo group_info = { + sizeof (SPFlowregionbreakClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) sp_flowregionbreak_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (SPFlowregionbreak), + 16, /* n_preallocs */ + (GInstanceInitFunc) sp_flowregionbreak_init, + NULL, /* value_table */ + }; + group_type = g_type_register_static (SP_TYPE_OBJECT, "SPFlowregionbreak", &group_info, (GTypeFlags)0); + } + return group_type; +} + +static void +sp_flowregionbreak_class_init (SPFlowregionbreakClass *klass) +{ + GObjectClass * object_class; + SPObjectClass * sp_object_class; + + object_class = (GObjectClass *) klass; + sp_object_class = (SPObjectClass *) klass; + + flowregionbreak_parent_class = (SPObjectClass *)g_type_class_ref (SP_TYPE_OBJECT); + + sp_object_class->release = sp_flowregionbreak_release; + sp_object_class->write = sp_flowregionbreak_write; + sp_object_class->modified = sp_flowregionbreak_modified; +} + +static void +sp_flowregionbreak_init (SPFlowregionbreak *group) +{ +} +static void +sp_flowregionbreak_release (SPObject *object) +{ + if (((SPObjectClass *) flowregionbreak_parent_class)->release) + ((SPObjectClass *) flowregionbreak_parent_class)->release (object); +} + +static void +sp_flowregionbreak_modified (SPObject *object, guint flags) +{ + if (((SPObjectClass *) (flowregionbreak_parent_class))->modified) + ((SPObjectClass *) (flowregionbreak_parent_class))->modified (object, flags); + + if (flags & SP_OBJECT_MODIFIED_FLAG) flags |= SP_OBJECT_PARENT_MODIFIED_FLAG; + flags &= SP_OBJECT_MODIFIED_CASCADE; +} +static Inkscape::XML::Node * +sp_flowregionbreak_write (SPObject *object, Inkscape::XML::Node *repr, guint flags) +{ + if ( flags&SP_OBJECT_WRITE_BUILD ) { + if ( repr == NULL ) repr = sp_repr_new ("svg:flowLine"); + } else { + } + + if (((SPObjectClass *) (flowregionbreak_parent_class))->write) + ((SPObjectClass *) (flowregionbreak_parent_class))->write (object, repr, flags); + + return repr; +} diff --git a/src/sp-flowdiv.h b/src/sp-flowdiv.h new file mode 100644 index 000000000..c01ada3b0 --- /dev/null +++ b/src/sp-flowdiv.h @@ -0,0 +1,84 @@ +#ifndef __SP_ITEM_FLOWDIV_H__ +#define __SP_ITEM_FLOWDIV_H__ + +/* + */ + +#include "sp-object.h" +#include "sp-item.h" + +#define SP_TYPE_FLOWDIV (sp_flowdiv_get_type ()) +#define SP_FLOWDIV(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SP_TYPE_FLOWDIV, SPFlowdiv)) +#define SP_FLOWDIV_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SP_TYPE_FLOWDIV, SPFlowdivClass)) +#define SP_IS_FLOWDIV(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_FLOWDIV)) +#define SP_IS_FLOWDIV_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SP_TYPE_FLOWDIV)) + +#define SP_TYPE_FLOWTSPAN (sp_flowtspan_get_type ()) +#define SP_FLOWTSPAN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SP_TYPE_FLOWTSPAN, SPFlowtspan)) +#define SP_FLOWTSPAN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SP_TYPE_FLOWTSPAN, SPFlowtspanClass)) +#define SP_IS_FLOWTSPAN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_FLOWTSPAN)) +#define SP_IS_FLOWTSPAN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SP_TYPE_FLOWTSPAN)) + +#define SP_TYPE_FLOWPARA (sp_flowpara_get_type ()) +#define SP_FLOWPARA(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SP_TYPE_FLOWPARA, SPFlowpara)) +#define SP_FLOWPARA_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SP_TYPE_FLOWPARA, SPFlowparaClass)) +#define SP_IS_FLOWPARA(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_FLOWPARA)) +#define SP_IS_FLOWPARA_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SP_TYPE_FLOWPARA)) + +#define SP_TYPE_FLOWLINE (sp_flowline_get_type ()) +#define SP_FLOWLINE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SP_TYPE_FLOWLINE, SPFlowline)) +#define SP_FLOWLINE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SP_TYPE_FLOWLINE, SPFlowlineClass)) +#define SP_IS_FLOWLINE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_FLOWLINE)) +#define SP_IS_FLOWLINE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SP_TYPE_FLOWLINE)) + +#define SP_TYPE_FLOWREGIONBREAK (sp_flowregionbreak_get_type ()) +#define SP_FLOWREGIONBREAK(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SP_TYPE_FLOWREGIONBREAK, SPFlowregionbreak)) +#define SP_FLOWREGIONBREAK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SP_TYPE_FLOWREGIONBREAK, SPFlowregionbreakClass)) +#define SP_IS_FLOWREGIONBREAK(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_FLOWREGIONBREAK)) +#define SP_IS_FLOWREGIONBREAK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SP_TYPE_FLOWREGIONBREAK)) + +// these 3 are derivatives of SPItem to get the automatic style handling +struct SPFlowdiv : public SPItem { +}; + +struct SPFlowtspan : public SPItem { +}; + +struct SPFlowpara : public SPItem { +}; + +// these do not need any style +struct SPFlowline : public SPObject { +}; + +struct SPFlowregionbreak : public SPObject { +}; + + +struct SPFlowdivClass { + SPItemClass parent_class; +}; + +struct SPFlowtspanClass { + SPItemClass parent_class; +}; + +struct SPFlowparaClass { + SPItemClass parent_class; +}; + +struct SPFlowlineClass { + SPObjectClass parent_class; +}; + +struct SPFlowregionbreakClass { + SPObjectClass parent_class; +}; + +GType sp_flowdiv_get_type (void); +GType sp_flowtspan_get_type (void); +GType sp_flowpara_get_type (void); +GType sp_flowline_get_type (void); +GType sp_flowregionbreak_get_type (void); + +#endif diff --git a/src/sp-flowregion.cpp b/src/sp-flowregion.cpp new file mode 100644 index 000000000..4071e4d92 --- /dev/null +++ b/src/sp-flowregion.cpp @@ -0,0 +1,544 @@ +#define __SP_FLOWREGION_C__ + +/* + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif +#include + +#include +#include "display/curve.h" +#include "sp-shape.h" +#include "sp-text.h" +#include "sp-use.h" +#include "style.h" + +#include "sp-flowregion.h" + +#include "display/canvas-bpath.h" + + +#include "livarot/Path.h" +#include "livarot/Shape.h" + +static void sp_flowregion_class_init (SPFlowregionClass *klass); +static void sp_flowregion_init (SPFlowregion *group); +static void sp_flowregion_dispose (GObject *object); + +static void sp_flowregion_child_added (SPObject * object, Inkscape::XML::Node * child, Inkscape::XML::Node * ref); +static void sp_flowregion_remove_child (SPObject * object, Inkscape::XML::Node * child); +static void sp_flowregion_update (SPObject *object, SPCtx *ctx, guint flags); +static void sp_flowregion_modified (SPObject *object, guint flags); +static Inkscape::XML::Node *sp_flowregion_write (SPObject *object, Inkscape::XML::Node *repr, guint flags); + +static gchar * sp_flowregion_description (SPItem * item); + +static SPItemClass * flowregion_parent_class; + +static void sp_flowregionexclude_class_init (SPFlowregionExcludeClass *klass); +static void sp_flowregionexclude_init (SPFlowregionExclude *group); +static void sp_flowregionexclude_dispose (GObject *object); + +static void sp_flowregionexclude_child_added (SPObject * object, Inkscape::XML::Node * child, Inkscape::XML::Node * ref); +static void sp_flowregionexclude_remove_child (SPObject * object, Inkscape::XML::Node * child); +static void sp_flowregionexclude_update (SPObject *object, SPCtx *ctx, guint flags); +static void sp_flowregionexclude_modified (SPObject *object, guint flags); +static Inkscape::XML::Node *sp_flowregionexclude_write (SPObject *object, Inkscape::XML::Node *repr, guint flags); + +static gchar * sp_flowregionexclude_description (SPItem * item); + +static SPItemClass * flowregionexclude_parent_class; + + +static void GetDest(SPObject* child,Shape **computed,NR::Matrix itr_mat); + +GType +sp_flowregion_get_type (void) +{ + static GType group_type = 0; + if (!group_type) { + GTypeInfo group_info = { + sizeof (SPFlowregionClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) sp_flowregion_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (SPFlowregion), + 16, /* n_preallocs */ + (GInstanceInitFunc) sp_flowregion_init, + NULL, /* value_table */ + }; + group_type = g_type_register_static (SP_TYPE_ITEM, "SPFlowregion", &group_info, (GTypeFlags)0); + } + return group_type; +} + +static void +sp_flowregion_class_init (SPFlowregionClass *klass) +{ + GObjectClass * object_class; + SPObjectClass * sp_object_class; + SPItemClass * item_class; + + object_class = (GObjectClass *) klass; + sp_object_class = (SPObjectClass *) klass; + item_class = (SPItemClass *) klass; + + flowregion_parent_class = (SPItemClass *)g_type_class_ref (SP_TYPE_ITEM); + + object_class->dispose = sp_flowregion_dispose; + + sp_object_class->child_added = sp_flowregion_child_added; + sp_object_class->remove_child = sp_flowregion_remove_child; + sp_object_class->update = sp_flowregion_update; + sp_object_class->modified = sp_flowregion_modified; + sp_object_class->write = sp_flowregion_write; + + item_class->description = sp_flowregion_description; +} + +static void +sp_flowregion_init (SPFlowregion *group) +{ + new (&group->computed) std::vector; +} + +static void +sp_flowregion_dispose(GObject *object) +{ + SPFlowregion *group=(SPFlowregion *)object; + for (std::vector::iterator it = group->computed.begin() ; it != group->computed.end() ; it++) + delete *it; + group->computed.~vector(); +} + +static void +sp_flowregion_child_added (SPObject *object, Inkscape::XML::Node *child, Inkscape::XML::Node *ref) +{ + SPItem *item; + + item = SP_ITEM (object); + + if (((SPObjectClass *) (flowregion_parent_class))->child_added) + (* ((SPObjectClass *) (flowregion_parent_class))->child_added) (object, child, ref); + + object->requestModified(SP_OBJECT_MODIFIED_FLAG); +} + +/* fixme: hide (Lauris) */ + +static void +sp_flowregion_remove_child (SPObject * object, Inkscape::XML::Node * child) +{ + if (((SPObjectClass *) (flowregion_parent_class))->remove_child) + (* ((SPObjectClass *) (flowregion_parent_class))->remove_child) (object, child); + + object->requestModified(SP_OBJECT_MODIFIED_FLAG); +} + + +static void +sp_flowregion_update (SPObject *object, SPCtx *ctx, unsigned int flags) +{ + SPFlowregion *group; + SPObject *child; + SPItemCtx *ictx, cctx; + GSList *l; + + group = SP_FLOWREGION (object); + ictx = (SPItemCtx *) ctx; + cctx = *ictx; + + if (((SPObjectClass *) (flowregion_parent_class))->update) + ((SPObjectClass *) (flowregion_parent_class))->update (object, ctx, flags); + + if (flags & SP_OBJECT_MODIFIED_FLAG) flags |= SP_OBJECT_PARENT_MODIFIED_FLAG; + flags &= SP_OBJECT_MODIFIED_CASCADE; + + l = NULL; + for (child = sp_object_first_child(object) ; child != NULL ; child = SP_OBJECT_NEXT(child) ) { + g_object_ref (G_OBJECT (child)); + l = g_slist_prepend (l, child); + } + l = g_slist_reverse (l); + while (l) { + child = SP_OBJECT (l->data); + l = g_slist_remove (l, child); + if (flags || (child->uflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { + if (SP_IS_ITEM (child)) { + SPItem const &chi = *SP_ITEM(child); + cctx.i2doc = chi.transform * ictx->i2doc; + cctx.i2vp = chi.transform * ictx->i2vp; + child->updateDisplay((SPCtx *)&cctx, flags); + } else { + child->updateDisplay(ctx, flags); + } + } + g_object_unref (G_OBJECT (child)); + } + + group->UpdateComputed(); +} + +void SPFlowregion::UpdateComputed(void) +{ + SPObject* object=SP_OBJECT(this); + + NR::Matrix itr_mat=sp_item_i2root_affine (SP_ITEM(object)); + itr_mat=itr_mat.inverse(); + + for (std::vector::iterator it = computed.begin() ; it != computed.end() ; it++) + delete *it; + computed.clear(); + + for (SPObject* child = sp_object_first_child(object) ; child != NULL ; child = SP_OBJECT_NEXT(child) ) { + Shape *shape = NULL; + GetDest(child,&shape,itr_mat); + computed.push_back(shape); + } +} + +static void +sp_flowregion_modified (SPObject *object, guint flags) +{ + SPFlowregion *group; + SPObject *child; + GSList *l; + + group = SP_FLOWREGION (object); + + if (flags & SP_OBJECT_MODIFIED_FLAG) flags |= SP_OBJECT_PARENT_MODIFIED_FLAG; + flags &= SP_OBJECT_MODIFIED_CASCADE; + + l = NULL; + for (child = sp_object_first_child(object) ; child != NULL ; child = SP_OBJECT_NEXT(child) ) { + g_object_ref (G_OBJECT (child)); + l = g_slist_prepend (l, child); + } + l = g_slist_reverse (l); + while (l) { + child = SP_OBJECT (l->data); + l = g_slist_remove (l, child); + if (flags || (child->mflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { + child->emitModified(flags); + } + g_object_unref (G_OBJECT (child)); + } +} + +static Inkscape::XML::Node * +sp_flowregion_write (SPObject *object, Inkscape::XML::Node *repr, guint flags) +{ + if (flags & SP_OBJECT_WRITE_BUILD) { + if ( repr == NULL ) repr = sp_repr_new ("svg:flowRegion"); + + GSList *l = NULL; + for ( SPObject *child = sp_object_first_child(object) ; child != NULL; child = SP_OBJECT_NEXT(child) ) { + Inkscape::XML::Node *crepr = child->updateRepr(NULL, flags); + if (crepr) l = g_slist_prepend(l, crepr); + } + + while (l) { + repr->addChild((Inkscape::XML::Node *) l->data, NULL); + Inkscape::GC::release((Inkscape::XML::Node *) l->data); + l = g_slist_remove(l, l->data); + } + + } else { + for ( SPObject *child = sp_object_first_child(object) ; child != NULL; child = SP_OBJECT_NEXT(child) ) { + child->updateRepr(flags); + } + } + + if (((SPObjectClass *) (flowregion_parent_class))->write) + ((SPObjectClass *) (flowregion_parent_class))->write (object, repr, flags); + + return repr; +} + + +static gchar *sp_flowregion_description(SPItem *item) +{ + // TRANSLATORS: "Flow region" is an area where text is allowed to flow + return g_strdup_printf(_("Flow region")); +} + +/* + * + */ + +GType +sp_flowregionexclude_get_type (void) +{ + static GType group_type = 0; + if (!group_type) { + GTypeInfo group_info = { + sizeof (SPFlowregionExcludeClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) sp_flowregionexclude_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (SPFlowregionExclude), + 16, /* n_preallocs */ + (GInstanceInitFunc) sp_flowregionexclude_init, + NULL, /* value_table */ + }; + group_type = g_type_register_static (SP_TYPE_ITEM, "SPFlowregionExclude", &group_info, (GTypeFlags)0); + } + return group_type; +} + +static void +sp_flowregionexclude_class_init (SPFlowregionExcludeClass *klass) +{ + GObjectClass * object_class; + SPObjectClass * sp_object_class; + SPItemClass * item_class; + + object_class = (GObjectClass *) klass; + sp_object_class = (SPObjectClass *) klass; + item_class = (SPItemClass *) klass; + + flowregionexclude_parent_class = (SPItemClass *)g_type_class_ref (SP_TYPE_ITEM); + + object_class->dispose = sp_flowregionexclude_dispose; + + sp_object_class->child_added = sp_flowregionexclude_child_added; + sp_object_class->remove_child = sp_flowregionexclude_remove_child; + sp_object_class->update = sp_flowregionexclude_update; + sp_object_class->modified = sp_flowregionexclude_modified; + sp_object_class->write = sp_flowregionexclude_write; + + item_class->description = sp_flowregionexclude_description; +} + +static void +sp_flowregionexclude_init (SPFlowregionExclude *group) +{ + group->computed = NULL; +} + +static void +sp_flowregionexclude_dispose(GObject *object) +{ + SPFlowregionExclude *group=(SPFlowregionExclude *)object; + if (group->computed) { + delete group->computed; + group->computed = NULL; + } +} + +static void +sp_flowregionexclude_child_added (SPObject *object, Inkscape::XML::Node *child, Inkscape::XML::Node *ref) +{ + SPItem *item; + + item = SP_ITEM (object); + + if (((SPObjectClass *) (flowregionexclude_parent_class))->child_added) + (* ((SPObjectClass *) (flowregionexclude_parent_class))->child_added) (object, child, ref); + + object->requestModified(SP_OBJECT_MODIFIED_FLAG); +} + +/* fixme: hide (Lauris) */ + +static void +sp_flowregionexclude_remove_child (SPObject * object, Inkscape::XML::Node * child) +{ + if (((SPObjectClass *) (flowregionexclude_parent_class))->remove_child) + (* ((SPObjectClass *) (flowregionexclude_parent_class))->remove_child) (object, child); + + object->requestModified(SP_OBJECT_MODIFIED_FLAG); +} + + +static void +sp_flowregionexclude_update (SPObject *object, SPCtx *ctx, unsigned int flags) +{ + SPFlowregionExclude *group; + SPObject *child; + SPItemCtx *ictx, cctx; + GSList *l; + + group = SP_FLOWREGIONEXCLUDE (object); + ictx = (SPItemCtx *) ctx; + cctx = *ictx; + + if (((SPObjectClass *) (flowregionexclude_parent_class))->update) + ((SPObjectClass *) (flowregionexclude_parent_class))->update (object, ctx, flags); + + if (flags & SP_OBJECT_MODIFIED_FLAG) flags |= SP_OBJECT_PARENT_MODIFIED_FLAG; + flags &= SP_OBJECT_MODIFIED_CASCADE; + + l = NULL; + for (child = sp_object_first_child(object) ; child != NULL ; child = SP_OBJECT_NEXT(child) ) { + g_object_ref (G_OBJECT (child)); + l = g_slist_prepend (l, child); + } + l = g_slist_reverse (l); + while (l) { + child = SP_OBJECT (l->data); + l = g_slist_remove (l, child); + if (flags || (child->uflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { + if (SP_IS_ITEM (child)) { + SPItem const &chi = *SP_ITEM(child); + cctx.i2doc = chi.transform * ictx->i2doc; + cctx.i2vp = chi.transform * ictx->i2vp; + child->updateDisplay((SPCtx *)&cctx, flags); + } else { + child->updateDisplay(ctx, flags); + } + } + g_object_unref (G_OBJECT (child)); + } + + group->UpdateComputed(); +} +void SPFlowregionExclude::UpdateComputed(void) +{ + SPObject* object=SP_OBJECT(this); + + if (computed) { + delete computed; + computed = NULL; + } + NR::Matrix itr_mat=sp_item_i2root_affine (SP_ITEM(object)); + itr_mat=itr_mat.inverse(); + + for (SPObject* child = sp_object_first_child(object) ; child != NULL ; child = SP_OBJECT_NEXT(child) ) { + GetDest(child,&computed,itr_mat); + } +} + +static void +sp_flowregionexclude_modified (SPObject *object, guint flags) +{ + SPFlowregionExclude *group; + SPObject *child; + GSList *l; + + group = SP_FLOWREGIONEXCLUDE (object); + + if (flags & SP_OBJECT_MODIFIED_FLAG) flags |= SP_OBJECT_PARENT_MODIFIED_FLAG; + flags &= SP_OBJECT_MODIFIED_CASCADE; + + l = NULL; + for (child = sp_object_first_child(object) ; child != NULL ; child = SP_OBJECT_NEXT(child) ) { + g_object_ref (G_OBJECT (child)); + l = g_slist_prepend (l, child); + } + l = g_slist_reverse (l); + while (l) { + child = SP_OBJECT (l->data); + l = g_slist_remove (l, child); + if (flags || (child->mflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { + child->emitModified(flags); + } + g_object_unref (G_OBJECT (child)); + } +} + +static Inkscape::XML::Node * +sp_flowregionexclude_write (SPObject *object, Inkscape::XML::Node *repr, guint flags) +{ + if (flags & SP_OBJECT_WRITE_BUILD) { + if ( repr == NULL ) repr = sp_repr_new ("svg:flowRegionExclude"); + + GSList *l = NULL; + for ( SPObject *child = sp_object_first_child(object) ; child != NULL; child = SP_OBJECT_NEXT(child) ) { + Inkscape::XML::Node *crepr = child->updateRepr(NULL, flags); + if (crepr) l = g_slist_prepend(l, crepr); + } + + while (l) { + repr->addChild((Inkscape::XML::Node *) l->data, NULL); + Inkscape::GC::release((Inkscape::XML::Node *) l->data); + l = g_slist_remove(l, l->data); + } + + } else { + for ( SPObject *child = sp_object_first_child(object) ; child != NULL; child = SP_OBJECT_NEXT(child) ) { + child->updateRepr(flags); + } + } + + if (((SPObjectClass *) (flowregionexclude_parent_class))->write) + ((SPObjectClass *) (flowregionexclude_parent_class))->write (object, repr, flags); + + return repr; +} + + +static gchar *sp_flowregionexclude_description(SPItem *item) +{ + /* TRANSLATORS: A region "cut out of" a flow region; text is not allowed to flow inside the + * flow excluded region. flowRegionExclude in SVG 1.2: see + * http://www.w3.org/TR/2004/WD-SVG12-20041027/flow.html#flowRegion-elem and + * http://www.w3.org/TR/2004/WD-SVG12-20041027/flow.html#flowRegionExclude-elem. */ + return g_strdup_printf(_("Flow excluded region")); +} + +/* + * + */ + +static void UnionShape(Shape **base_shape, Shape const *add_shape) +{ + if (*base_shape == NULL) + *base_shape = new Shape; + if ( (*base_shape)->hasEdges() == false ) { + (*base_shape)->Copy(const_cast(add_shape)); + } else if ( add_shape->hasEdges() ) { + Shape* temp=new Shape; + temp->Booleen(const_cast(add_shape), *base_shape, bool_op_union); + delete *base_shape; + *base_shape = temp; + } +} + +static void GetDest(SPObject* child,Shape **computed,NR::Matrix itr_mat) +{ + if ( child == NULL ) return; + + SPCurve *curve=NULL; + + SPObject* u_child=child; + if ( SP_IS_USE(u_child) ) { + u_child=SP_USE(u_child)->child; + } + if ( SP_IS_SHAPE (u_child) ) { + curve = sp_shape_get_curve (SP_SHAPE (u_child)); + } else if ( SP_IS_TEXT (u_child) ) { + curve = SP_TEXT (u_child)->getNormalizedBpath (); + } + + if ( curve ) { + Path* temp=new Path; + NR::Matrix tr_mat=sp_item_i2root_affine (SP_ITEM(u_child)); + tr_mat=itr_mat*tr_mat; + temp->LoadArtBPath(curve->bpath,tr_mat,true); + Shape* n_shp=new Shape; + temp->Convert(0.25); + temp->Fill(n_shp,0); + Shape* uncross=new Shape; + SPStyle* style=SP_OBJECT_STYLE(u_child); + if ( style && style->fill_rule.computed == SP_WIND_RULE_EVENODD ) { + uncross->ConvertToShape(n_shp,fill_oddEven); + } else { + uncross->ConvertToShape(n_shp,fill_nonZero); + } + UnionShape(computed, uncross); + delete uncross; + delete n_shp; + delete temp; + sp_curve_unref(curve); + } else { +// printf("no curve\n"); + } +} + diff --git a/src/sp-flowregion.h b/src/sp-flowregion.h new file mode 100644 index 000000000..46b584cf2 --- /dev/null +++ b/src/sp-flowregion.h @@ -0,0 +1,50 @@ +#ifndef __SP_ITEM_FLOWREGION_H__ +#define __SP_ITEM_FLOWREGION_H__ + +/* + */ + +#include "sp-item.h" + +#define SP_TYPE_FLOWREGION (sp_flowregion_get_type ()) +#define SP_FLOWREGION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SP_TYPE_FLOWREGION, SPFlowregion)) +#define SP_FLOWREGION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SP_TYPE_FLOWREGION, SPFlowregionClass)) +#define SP_IS_FLOWREGION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_FLOWREGION)) +#define SP_IS_FLOWREGION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SP_TYPE_FLOWREGION)) + +#define SP_TYPE_FLOWREGIONEXCLUDE (sp_flowregionexclude_get_type ()) +#define SP_FLOWREGIONEXCLUDE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SP_TYPE_FLOWREGIONEXCLUDE, SPFlowregionExclude)) +#define SP_FLOWREGIONEXCLUDE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SP_TYPE_FLOWREGIONEXCLUDE, SPFlowregionExcludeClass)) +#define SP_IS_FLOWREGIONEXCLUDE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_FLOWREGIONEXCLUDE)) +#define SP_IS_FLOWREGIONEXCLUDE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SP_TYPE_FLOWREGIONEXCLUDE)) + +class Path; +class Shape; +class flow_dest; +class FloatLigne; + +struct SPFlowregion : public SPItem { + std::vector computed; + + void UpdateComputed(void); +}; + +struct SPFlowregionClass { + SPItemClass parent_class; +}; + +GType sp_flowregion_get_type (void); + +struct SPFlowregionExclude : public SPItem { + Shape *computed; + + void UpdateComputed(void); +}; + +struct SPFlowregionExcludeClass { + SPItemClass parent_class; +}; + +GType sp_flowregionexclude_get_type (void); + +#endif diff --git a/src/sp-flowtext.cpp b/src/sp-flowtext.cpp new file mode 100644 index 000000000..fbf0efabd --- /dev/null +++ b/src/sp-flowtext.cpp @@ -0,0 +1,681 @@ +/* + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif +#include + +#include "attributes.h" +#include "xml/repr.h" +#include "style.h" +#include "inkscape.h" +#include "document.h" +#include "selection.h" +#include "desktop-handles.h" +#include "desktop.h" +#include "desktop-affine.h" + +#include "xml/repr.h" + +#include "sp-flowdiv.h" +#include "sp-flowregion.h" +#include "sp-flowtext.h" +#include "sp-string.h" +#include "sp-use.h" +#include "sp-rect.h" +#include "text-tag-attributes.h" + + +#include "livarot/Shape.h" + +#include "display/nr-arena-glyphs.h" + + +static void sp_flowtext_class_init(SPFlowtextClass *klass); +static void sp_flowtext_init(SPFlowtext *group); +static void sp_flowtext_dispose(GObject *object); + +static void sp_flowtext_child_added(SPObject *object, Inkscape::XML::Node *child, Inkscape::XML::Node *ref); +static void sp_flowtext_remove_child(SPObject *object, Inkscape::XML::Node *child); +static void sp_flowtext_update(SPObject *object, SPCtx *ctx, guint flags); +static void sp_flowtext_modified(SPObject *object, guint flags); +static Inkscape::XML::Node *sp_flowtext_write(SPObject *object, Inkscape::XML::Node *repr, guint flags); +static void sp_flowtext_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr); +static void sp_flowtext_set(SPObject *object, unsigned key, gchar const *value); + +static void sp_flowtext_bbox(SPItem const *item, NRRect *bbox, NR::Matrix const &transform, unsigned const flags); +static void sp_flowtext_print(SPItem *item, SPPrintContext *ctx); +static gchar *sp_flowtext_description(SPItem *item); +static NRArenaItem *sp_flowtext_show(SPItem *item, NRArena *arena, unsigned key, unsigned flags); +static void sp_flowtext_hide(SPItem *item, unsigned key); + +static SPItemClass *parent_class; + +GType +sp_flowtext_get_type(void) +{ + static GType group_type = 0; + if (!group_type) { + GTypeInfo group_info = { + sizeof(SPFlowtextClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) sp_flowtext_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof(SPFlowtext), + 16, /* n_preallocs */ + (GInstanceInitFunc) sp_flowtext_init, + NULL, /* value_table */ + }; + group_type = g_type_register_static(SP_TYPE_ITEM, "SPFlowtext", &group_info, (GTypeFlags)0); + } + return group_type; +} + +static void +sp_flowtext_class_init(SPFlowtextClass *klass) +{ + GObjectClass *object_class = (GObjectClass *) klass; + SPObjectClass *sp_object_class = (SPObjectClass *) klass; + SPItemClass *item_class = (SPItemClass *) klass; + + parent_class = (SPItemClass *)g_type_class_ref(SP_TYPE_ITEM); + + object_class->dispose = sp_flowtext_dispose; + + sp_object_class->child_added = sp_flowtext_child_added; + sp_object_class->remove_child = sp_flowtext_remove_child; + sp_object_class->update = sp_flowtext_update; + sp_object_class->modified = sp_flowtext_modified; + sp_object_class->write = sp_flowtext_write; + sp_object_class->build = sp_flowtext_build; + sp_object_class->set = sp_flowtext_set; + + item_class->bbox = sp_flowtext_bbox; + item_class->print = sp_flowtext_print; + item_class->description = sp_flowtext_description; + item_class->show = sp_flowtext_show; + item_class->hide = sp_flowtext_hide; +} + +static void +sp_flowtext_init(SPFlowtext *group) +{ + new (&group->layout) Inkscape::Text::Layout(); +} + +static void +sp_flowtext_dispose(GObject *object) +{ + SPFlowtext *group = (SPFlowtext*)object; + + group->layout.~Layout(); +} + +static void +sp_flowtext_child_added(SPObject *object, Inkscape::XML::Node *child, Inkscape::XML::Node *ref) +{ + if (((SPObjectClass *) (parent_class))->child_added) + (* ((SPObjectClass *) (parent_class))->child_added)(object, child, ref); + + object->requestModified(SP_OBJECT_MODIFIED_FLAG); +} + +/* fixme: hide (Lauris) */ + +static void +sp_flowtext_remove_child(SPObject *object, Inkscape::XML::Node *child) +{ + if (((SPObjectClass *) (parent_class))->remove_child) + (* ((SPObjectClass *) (parent_class))->remove_child)(object, child); + + object->requestModified(SP_OBJECT_MODIFIED_FLAG); +} + +static void +sp_flowtext_update(SPObject *object, SPCtx *ctx, unsigned flags) +{ + SPFlowtext *group = SP_FLOWTEXT(object); + SPItemCtx *ictx = (SPItemCtx *) ctx; + SPItemCtx cctx = *ictx; + + if (((SPObjectClass *) (parent_class))->update) + ((SPObjectClass *) (parent_class))->update(object, ctx, flags); + + if (flags & SP_OBJECT_MODIFIED_FLAG) flags |= SP_OBJECT_PARENT_MODIFIED_FLAG; + flags &= SP_OBJECT_MODIFIED_CASCADE; + + GSList *l = NULL; + for (SPObject *child = sp_object_first_child(object) ; child != NULL ; child = SP_OBJECT_NEXT(child) ) { + g_object_ref(G_OBJECT(child)); + l = g_slist_prepend(l, child); + } + l = g_slist_reverse(l); + while (l) { + SPObject *child = SP_OBJECT(l->data); + l = g_slist_remove(l, child); + if (flags || (child->uflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { + if (SP_IS_ITEM(child)) { + SPItem const &chi = *SP_ITEM(child); + cctx.i2doc = chi.transform * ictx->i2doc; + cctx.i2vp = chi.transform * ictx->i2vp; + child->updateDisplay((SPCtx *)&cctx, flags); + } else { + child->updateDisplay(ctx, flags); + } + } + g_object_unref(G_OBJECT(child)); + } + + group->rebuildLayout(); + + // pass the bbox of the flowtext object as paintbox (used for paintserver fills) + NRRect paintbox; + sp_item_invoke_bbox(group, &paintbox, NR::identity(), TRUE); + for (SPItemView *v = group->display; v != NULL; v = v->next) { + group->_clearFlow(NR_ARENA_GROUP(v->arenaitem)); + group->layout.show(NR_ARENA_GROUP(v->arenaitem), &paintbox); + } +} + +static void +sp_flowtext_modified(SPObject *object, guint flags) +{ + SPObject *ft = SP_FLOWTEXT (object); + SPObject *region = NULL; + + if (flags & SP_OBJECT_MODIFIED_FLAG) flags |= SP_OBJECT_PARENT_MODIFIED_FLAG; + flags &= SP_OBJECT_MODIFIED_CASCADE; + + for (SPObject *o = sp_object_first_child(SP_OBJECT(ft)) ; o != NULL ; o = SP_OBJECT_NEXT(o) ) { + if (SP_IS_FLOWREGION(o)) { + region = o; + break; + } + } + + if (!region) return; + + if (flags || (region->mflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { + region->emitModified(flags); // pass down to the region only + } +} + +static void +sp_flowtext_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr) +{ + object->_requireSVGVersion(Inkscape::Version(1, 2)); + + if (((SPObjectClass *) (parent_class))->build) { + (* ((SPObjectClass *) (parent_class))->build)(object, document, repr); + } + + sp_object_read_attr(object, "inkscape:layoutOptions"); // must happen after css has been read +} + +static void +sp_flowtext_set(SPObject *object, unsigned key, gchar const *value) +{ + SPFlowtext *group = (SPFlowtext *) object; + + switch (key) { + case SP_ATTR_LAYOUT_OPTIONS: { + // deprecated attribute, read for backward compatibility only + SPCSSAttr *opts = sp_repr_css_attr((SP_OBJECT(group))->repr, "inkscape:layoutOptions"); + { + gchar const *val = sp_repr_css_property(opts, "justification", NULL); + if (val != NULL && !object->style->text_align.set) { + if ( strcmp(val, "0") == 0 || strcmp(val, "false") == 0 ) { + object->style->text_align.value = SP_CSS_TEXT_ALIGN_LEFT; + } else { + object->style->text_align.value = SP_CSS_TEXT_ALIGN_JUSTIFY; + } + object->style->text_align.set = TRUE; + object->style->text_align.inherit = FALSE; + object->style->text_align.computed = object->style->text_align.value; + } + } + /* no equivalent css attribute for these two (yet) + { + gchar const *val = sp_repr_css_property(opts, "layoutAlgo", NULL); + if ( val == NULL ) { + group->algo = 0; + } else { + if ( strcmp(val, "better") == 0 ) { // knuth-plass, never worked for general cases + group->algo = 2; + } else if ( strcmp(val, "simple") == 0 ) { // greedy, but allowed lines to be compressed by up to 20% if it would make them fit + group->algo = 1; + } else if ( strcmp(val, "default") == 0 ) { // the same one we use, a standard greedy + group->algo = 0; + } + } + } + { // This would probably translate to padding-left, if SPStyle had it. + gchar const *val = sp_repr_css_property(opts, "par-indent", NULL); + if ( val == NULL ) { + group->par_indent = 0.0; + } else { + sp_repr_get_double((Inkscape::XML::Node*)opts, "par-indent", &group->par_indent); + } + } + */ + sp_repr_css_attr_unref(opts); + object->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + } + default: + if (((SPObjectClass *) (parent_class))->set) { + (* ((SPObjectClass *) (parent_class))->set)(object, key, value); + } + break; + } +} + +static Inkscape::XML::Node * +sp_flowtext_write(SPObject *object, Inkscape::XML::Node *repr, guint flags) +{ + if ( flags & SP_OBJECT_WRITE_BUILD ) { + if ( repr == NULL ) repr = sp_repr_new("svg:flowRoot"); + GSList *l = NULL; + for (SPObject *child = sp_object_first_child(object) ; child != NULL ; child = SP_OBJECT_NEXT(child) ) { + Inkscape::XML::Node *c_repr = NULL; + if ( SP_IS_FLOWDIV(child) || SP_IS_FLOWPARA(child) || SP_IS_FLOWREGION(child) || SP_IS_FLOWREGIONEXCLUDE(child)) { + c_repr = child->updateRepr(NULL, flags); + } + if ( c_repr ) l = g_slist_prepend(l, c_repr); + } + while ( l ) { + repr->addChild((Inkscape::XML::Node *) l->data, NULL); + Inkscape::GC::release((Inkscape::XML::Node *) l->data); + l = g_slist_remove(l, l->data); + } + } else { + for (SPObject *child = sp_object_first_child(object) ; child != NULL ; child = SP_OBJECT_NEXT(child) ) { + if ( SP_IS_FLOWDIV(child) || SP_IS_FLOWPARA(child) || SP_IS_FLOWREGION(child) || SP_IS_FLOWREGIONEXCLUDE(child) ) { + child->updateRepr(flags); + } + } + } + + if (((SPObjectClass *) (parent_class))->write) + ((SPObjectClass *) (parent_class))->write(object, repr, flags); + + return repr; +} + +static void +sp_flowtext_bbox(SPItem const *item, NRRect *bbox, NR::Matrix const &transform, unsigned const /*flags*/) +{ + SPFlowtext *group = SP_FLOWTEXT(item); + group->layout.getBoundingBox(bbox, transform); +} + +static void +sp_flowtext_print(SPItem *item, SPPrintContext *ctx) +{ + SPFlowtext *group = SP_FLOWTEXT(item); + + NRRect pbox; + sp_item_invoke_bbox(item, &pbox, NR::identity(), TRUE); + NRRect bbox; + sp_item_bbox_desktop(item, &bbox); + NRRect dbox; + dbox.x0 = 0.0; + dbox.y0 = 0.0; + dbox.x1 = sp_document_width(SP_OBJECT_DOCUMENT(item)); + dbox.y1 = sp_document_height(SP_OBJECT_DOCUMENT(item)); + NR::Matrix const ctm = sp_item_i2d_affine(item); + + group->layout.print(ctx, &pbox, &dbox, &bbox, ctm); +} + + +static gchar *sp_flowtext_description(SPItem *item) +{ + Inkscape::Text::Layout const &layout = SP_FLOWTEXT(item)->layout; + int const nChars = layout.iteratorToCharIndex(layout.end()); + if (SP_FLOWTEXT(item)->has_internal_frame()) + return g_strdup_printf(_("Flowed text (%d characters)"), nChars); + else + return g_strdup_printf(_("Linked flowed text (%d characters)"), nChars); +} + +static NRArenaItem * +sp_flowtext_show(SPItem *item, NRArena *arena, unsigned/* key*/, unsigned /*flags*/) +{ + SPFlowtext *group = (SPFlowtext *) item; + NRArenaGroup *flowed = NRArenaGroup::create(arena); + nr_arena_group_set_transparent(flowed, FALSE); + + // pass the bbox of the flowtext object as paintbox (used for paintserver fills) + NRRect paintbox; + sp_item_invoke_bbox(item, &paintbox, NR::identity(), TRUE); + group->layout.show(flowed, &paintbox); + + return flowed; +} + +static void +sp_flowtext_hide(SPItem *item, unsigned int key) +{ + if (((SPItemClass *) parent_class)->hide) + ((SPItemClass *) parent_class)->hide(item, key); +} + + +/* + * + */ + +void SPFlowtext::_buildLayoutInput(SPObject *root, Shape const *exclusion_shape, std::list *shapes, SPObject **pending_line_break_object) +{ + if (*pending_line_break_object) { + if (SP_IS_FLOWREGIONBREAK(*pending_line_break_object)) + layout.appendControlCode(Inkscape::Text::Layout::SHAPE_BREAK, *pending_line_break_object); + else + layout.appendControlCode(Inkscape::Text::Layout::PARAGRAPH_BREAK, *pending_line_break_object); + *pending_line_break_object = NULL; + } + + for (SPObject *child = sp_object_first_child(root) ; child != NULL ; child = SP_OBJECT_NEXT(child) ) { + if (SP_IS_STRING(child)) { + if (*pending_line_break_object) { + if (SP_IS_FLOWREGIONBREAK(*pending_line_break_object)) + layout.appendControlCode(Inkscape::Text::Layout::SHAPE_BREAK, *pending_line_break_object); + else + layout.appendControlCode(Inkscape::Text::Layout::PARAGRAPH_BREAK, *pending_line_break_object); + *pending_line_break_object = NULL; + } + layout.appendText(SP_STRING(child)->string, root->style, child); + } else if (SP_IS_FLOWREGION(child)) { + std::vector const &computed = SP_FLOWREGION(child)->computed; + for (std::vector::const_iterator it = computed.begin() ; it != computed.end() ; it++) { + shapes->push_back(Shape()); + if (exclusion_shape->hasEdges()) + shapes->back().Booleen(*it, const_cast(exclusion_shape), bool_op_diff); + else + shapes->back().Copy(*it); + layout.appendWrapShape(&shapes->back()); + } + } + else if (!SP_IS_FLOWREGIONEXCLUDE(child)) + _buildLayoutInput(child, exclusion_shape, shapes, pending_line_break_object); + } + + if (SP_IS_FLOWDIV(root) || SP_IS_FLOWPARA(root) || SP_IS_FLOWREGIONBREAK(root) || SP_IS_FLOWLINE(root)) { + if (!root->hasChildren()) + layout.appendText("", root->style, root); + *pending_line_break_object = root; + } +} + +Shape* SPFlowtext::_buildExclusionShape() const +{ + Shape *shape = new Shape; + Shape *shape_temp = new Shape; + + for (SPObject *child = children ; child != NULL ; child = SP_OBJECT_NEXT(child) ) { + // RH: is it right that this shouldn't be recursive? + if ( SP_IS_FLOWREGIONEXCLUDE(child) ) { + SPFlowregionExclude *c_child = SP_FLOWREGIONEXCLUDE(child); + if (c_child->computed == NULL || !c_child->computed->hasEdges()) + continue; + if (shape->hasEdges()) { + shape_temp->Booleen(shape, c_child->computed, bool_op_union); + std::swap(shape, shape_temp); + } else + shape->Copy(c_child->computed); + } + } + delete shape_temp; + return shape; +} + +void SPFlowtext::rebuildLayout() +{ + std::list shapes; + + layout.clear(); + Shape *exclusion_shape = _buildExclusionShape(); + SPObject *pending_line_break_object = NULL; + _buildLayoutInput(this, exclusion_shape, &shapes, &pending_line_break_object); + delete exclusion_shape; + layout.calculateFlow(); + //g_print(layout.dumpAsText().c_str()); +} + +void SPFlowtext::_clearFlow(NRArenaGroup *in_arena) +{ + nr_arena_item_request_render(NR_ARENA_ITEM(in_arena)); + for (NRArenaItem *child = in_arena->children; child != NULL; ) { + NRArenaItem *nchild = child->next; + + nr_arena_glyphs_group_clear(NR_ARENA_GLYPHS_GROUP(child)); + nr_arena_item_remove_child(NR_ARENA_ITEM(in_arena), child); + + child = nchild; + } +} + +void SPFlowtext::convert_to_text() +{ + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + Inkscape::Selection *selection = SP_DT_SELECTION(desktop); + SPItem *item = selection->singleItem(); + if (!SP_IS_FLOWTEXT(item)) return; + + SPFlowtext *group = SP_FLOWTEXT(item); + + if (!group->layout.outputExists()) return; + + Inkscape::XML::Node *repr = sp_repr_new("svg:text"); + repr->setAttribute("xml:space", "preserve"); + repr->setAttribute("style", SP_OBJECT_REPR(group)->attribute("style")); + NR::Point anchor_point = group->layout.characterAnchorPoint(group->layout.begin()); + sp_repr_set_svg_double(repr, "x", anchor_point[NR::X]); + sp_repr_set_svg_double(repr, "y", anchor_point[NR::Y]); + + for (Inkscape::Text::Layout::iterator it = group->layout.begin() ; it != group->layout.end() ; ) { + + Inkscape::XML::Node *line_tspan = sp_repr_new("svg:tspan"); + line_tspan->setAttribute("sodipodi:role", "line"); + + Inkscape::Text::Layout::iterator it_line_end = it; + it_line_end.nextStartOfLine(); + while (it != it_line_end) { + + Inkscape::XML::Node *span_tspan = sp_repr_new("svg:tspan"); + NR::Point anchor_point = group->layout.characterAnchorPoint(it); + // use kerning to simulate justification and whatnot + Inkscape::Text::Layout::iterator it_span_end = it; + it_span_end.nextStartOfSpan(); + Inkscape::Text::Layout::OptionalTextTagAttrs attrs; + group->layout.simulateLayoutUsingKerning(it, it_span_end, &attrs); + // set x,y attributes only when we need to + bool set_x = false; + bool set_y = false; + if (!item->transform.test_identity()) { + set_x = set_y = true; + } else { + Inkscape::Text::Layout::iterator it_chunk_start = it; + it_chunk_start.thisStartOfChunk(); + if (it == it_chunk_start) { + set_x = true; + // don't set y so linespacing adjustments and things will still work + } + Inkscape::Text::Layout::iterator it_shape_start = it; + it_shape_start.thisStartOfShape(); + if (it == it_shape_start) + set_y = true; + } + if (set_x && !attrs.dx.empty()) + attrs.dx[0] = 0.0; + TextTagAttributes(attrs).writeTo(span_tspan); + if (set_x) + sp_repr_set_svg_double(span_tspan, "x", anchor_point[NR::X]); // FIXME: this will pick up the wrong end of counter-directional runs + if (set_y) + sp_repr_set_svg_double(span_tspan, "y", anchor_point[NR::Y]); + + SPObject *source_obj; + Glib::ustring::iterator span_text_start_iter; + group->layout.getSourceOfCharacter(it, (void**)&source_obj, &span_text_start_iter); + gchar *style_text = sp_style_write_difference((SP_IS_STRING(source_obj) ? source_obj->parent : source_obj)->style, group->style); + if (style_text && *style_text) { + span_tspan->setAttribute("style", style_text); + g_free(style_text); + } + + if (SP_IS_STRING(source_obj)) { + Glib::ustring *string = &SP_STRING(source_obj)->string; + SPObject *span_end_obj; + Glib::ustring::iterator span_text_end_iter; + group->layout.getSourceOfCharacter(it_span_end, (void**)&span_end_obj, &span_text_end_iter); + if (span_end_obj != source_obj) { + if (it_span_end == group->layout.end()) { + span_text_end_iter = span_text_start_iter; + for (int i = group->layout.iteratorToCharIndex(it_span_end) - group->layout.iteratorToCharIndex(it) ; i ; --i) + ++span_text_end_iter; + } else + span_text_end_iter = string->end(); // spans will never straddle a source boundary + } + + if (span_text_start_iter != span_text_end_iter) { + Glib::ustring new_string; + while (span_text_start_iter != span_text_end_iter) + new_string += *span_text_start_iter++; // grr. no substr() with iterators + Inkscape::XML::Node *new_text = sp_repr_new_text(new_string.c_str()); + span_tspan->appendChild(new_text); + Inkscape::GC::release(new_text); + } + } + it = it_span_end; + + line_tspan->appendChild(span_tspan); + Inkscape::GC::release(span_tspan); + } + repr->appendChild(line_tspan); + Inkscape::GC::release(line_tspan); + } + + Inkscape::XML::Node *parent = SP_OBJECT_REPR(item)->parent(); + parent->appendChild(repr); + SPItem *new_item = (SPItem *) SP_DT_DOCUMENT(desktop)->getObjectByRepr(repr); + sp_item_write_transform(new_item, repr, item->transform); + SP_OBJECT(new_item)->updateRepr(); + + Inkscape::GC::release(repr); + selection->set(new_item); + item->deleteObject(); + + sp_document_done(SP_DT_DOCUMENT(desktop)); +} + +SPItem *SPFlowtext::get_frame(SPItem *after) +{ + SPObject *ft = SP_OBJECT (this); + SPObject *region = NULL; + + for (SPObject *o = sp_object_first_child(SP_OBJECT(ft)) ; o != NULL ; o = SP_OBJECT_NEXT(o) ) { + if (SP_IS_FLOWREGION(o)) { + region = o; + break; + } + } + + if (!region) return NULL; + + bool past = false; + SPItem *frame = NULL; + + for (SPObject *o = sp_object_first_child(SP_OBJECT(region)) ; o != NULL ; o = SP_OBJECT_NEXT(o) ) { + if (SP_IS_ITEM(o)) { + if (after == NULL || past) { + frame = SP_ITEM(o); + } else { + if (SP_ITEM(o) == after) { + past = true; + } + } + } + } + + if (!frame) return NULL; + + if (SP_IS_USE (frame)) { + return sp_use_get_original(SP_USE(frame)); + } else { + return frame; + } +} + +bool SPFlowtext::has_internal_frame() +{ + SPItem *frame = get_frame(NULL); + + return (frame && SP_OBJECT(this)->isAncestorOf(SP_OBJECT(frame)) && SP_IS_RECT(frame)); +} + + +SPItem *create_flowtext_with_internal_frame (SPDesktop *desktop, NR::Point p0, NR::Point p1) +{ + SPDocument *doc = SP_DT_DOCUMENT (desktop); + + Inkscape::XML::Node *root_repr = sp_repr_new("svg:flowRoot"); + root_repr->setAttribute("xml:space", "preserve"); // we preserve spaces in the text objects we create + SPItem *ft_item = SP_ITEM(desktop->currentLayer()->appendChildRepr(root_repr)); + SPObject *root_object = doc->getObjectByRepr(root_repr); + g_assert(SP_IS_FLOWTEXT(root_object)); + + Inkscape::XML::Node *region_repr = sp_repr_new("svg:flowRegion"); + root_repr->appendChild(region_repr); + SPObject *region_object = doc->getObjectByRepr(region_repr); + g_assert(SP_IS_FLOWREGION(region_object)); + + Inkscape::XML::Node *rect_repr = sp_repr_new("svg:rect"); // FIXME: use path!!! after rects are converted to use path + region_repr->appendChild(rect_repr); + + SPObject *rect = doc->getObjectByRepr(rect_repr); + + p0 = sp_desktop_dt2root_xy_point(desktop, p0); + p1 = sp_desktop_dt2root_xy_point(desktop, p1); + using NR::X; + using NR::Y; + NR::Coord const x0 = MIN(p0[X], p1[X]); + NR::Coord const y0 = MIN(p0[Y], p1[Y]); + NR::Coord const x1 = MAX(p0[X], p1[X]); + NR::Coord const y1 = MAX(p0[Y], p1[Y]); + NR::Coord const w = x1 - x0; + NR::Coord const h = y1 - y0; + + sp_rect_position_set(SP_RECT(rect), x0, y0, w, h); + SP_OBJECT(rect)->updateRepr(); + + Inkscape::XML::Node *para_repr = sp_repr_new("svg:flowPara"); + root_repr->appendChild(para_repr); + SPObject *para_object = doc->getObjectByRepr(para_repr); + g_assert(SP_IS_FLOWPARA(para_object)); + + Inkscape::XML::Node *text = sp_repr_new_text(""); + para_repr->appendChild(text); + + Inkscape::GC::release(root_repr); + Inkscape::GC::release(region_repr); + Inkscape::GC::release(para_repr); + Inkscape::GC::release(rect_repr); + + return ft_item; +} + + +/* + 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 : diff --git a/src/sp-flowtext.h b/src/sp-flowtext.h new file mode 100644 index 000000000..9e6d711fa --- /dev/null +++ b/src/sp-flowtext.h @@ -0,0 +1,56 @@ +#ifndef __SP_ITEM_FLOWTEXT_H__ +#define __SP_ITEM_FLOWTEXT_H__ + +/* + */ + +#include "sp-item.h" + +#include "display/nr-arena-forward.h" + +#include "libnrtype/Layout-TNG.h" + +#define SP_TYPE_FLOWTEXT (sp_flowtext_get_type ()) +#define SP_FLOWTEXT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SP_TYPE_FLOWTEXT, SPFlowtext)) +#define SP_FLOWTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SP_TYPE_FLOWTEXT, SPFlowtextClass)) +#define SP_IS_FLOWTEXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_FLOWTEXT)) +#define SP_IS_FLOWTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SP_TYPE_FLOWTEXT)) + +struct SPFlowtext : public SPItem { + /** Completely recalculates the layout. */ + void rebuildLayout(); + + /** Converts the current selection (which must be a flowroot) into + a \ tree, keeping all the formatting and positioning, but losing + the automatic wrapping ability. */ + static void convert_to_text(); + + SPItem *get_frame(SPItem *after); + + bool has_internal_frame(); + +//semiprivate: (need to be accessed by the C-style functions still) + Inkscape::Text::Layout layout; + + /** discards the NRArena objects representing this text. */ + void _clearFlow(NRArenaGroup* in_arena); + +private: + /** Recursively walks the xml tree adding tags and their contents. */ + void _buildLayoutInput(SPObject *root, Shape const *exclusion_shape, std::list *shapes, SPObject **pending_line_break_object); + + /** calculates the union of all the \ children + of this flowroot. */ + Shape* _buildExclusionShape() const; + +}; + +struct SPFlowtextClass { + SPItemClass parent_class; +}; + +GType sp_flowtext_get_type (void); + +SPItem *create_flowtext_with_internal_frame (SPDesktop *desktop, NR::Point p1, NR::Point p2); + +#endif diff --git a/src/sp-gradient-fns.h b/src/sp-gradient-fns.h new file mode 100644 index 000000000..9780db182 --- /dev/null +++ b/src/sp-gradient-fns.h @@ -0,0 +1,76 @@ +#ifndef SEEN_SP_GRADIENT_FNS_H +#define SEEN_SP_GRADIENT_FNS_H + +/** \file + * Macros and fn declarations related to gradients. + */ + +#include +#include +#include "libnr/nr-forward.h" +#include "sp-gradient-spread.h" +#include "sp-gradient-units.h" + +class SPGradient; + +namespace Inkscape { +namespace XML { +class Node; +} +} + +#define SP_TYPE_GRADIENT (sp_gradient_get_type()) +#define SP_GRADIENT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), SP_TYPE_GRADIENT, SPGradient)) +#define SP_GRADIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), SP_TYPE_GRADIENT, SPGradientClass)) +#define SP_IS_GRADIENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), SP_TYPE_GRADIENT)) +#define SP_IS_GRADIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), SP_TYPE_GRADIENT)) + +#define SP_GRADIENT_STATE_IS_SET(g) (SP_GRADIENT(g)->state != SP_GRADIENT_STATE_UNKNOWN) +#define SP_GRADIENT_IS_VECTOR(g) (SP_GRADIENT(g)->state == SP_GRADIENT_STATE_VECTOR) +#define SP_GRADIENT_IS_PRIVATE(g) (SP_GRADIENT(g)->state == SP_GRADIENT_STATE_PRIVATE) +#define SP_GRADIENT_HAS_STOPS(g) (SP_GRADIENT(g)->has_stops) +#define SP_GRADIENT_SPREAD(g) (SP_GRADIENT(g)->spread) +#define SP_GRADIENT_UNITS(g) (SP_GRADIENT(g)->units) + +GType sp_gradient_get_type(); + +/** Forces vector to be built, if not present (i.e. changed) */ +void sp_gradient_ensure_vector(SPGradient *gradient); + +/** Ensures that color array is populated */ +void sp_gradient_ensure_colors(SPGradient *gradient); + +void sp_gradient_set_units(SPGradient *gr, SPGradientUnits units); +void sp_gradient_set_spread(SPGradient *gr, SPGradientSpread spread); + +SPGradient *sp_gradient_get_vector (SPGradient *gradient, bool force_private); +SPGradientSpread sp_gradient_get_spread (SPGradient *gradient); + +/* Gradient repr methods */ +void sp_gradient_repr_write_vector(SPGradient *gr); +void sp_gradient_repr_clear_vector(SPGradient *gr); + +void sp_gradient_render_vector_block_rgba(SPGradient *gr, guchar *px, gint w, gint h, gint rs, gint pos, gint span, bool horizontal); +void sp_gradient_render_vector_block_rgb(SPGradient *gr, guchar *px, gint w, gint h, gint rs, gint pos, gint span, bool horizontal); + +/** Transforms to/from gradient position space in given environment */ +NR::Matrix sp_gradient_get_g2d_matrix(SPGradient const *gr, NR::Matrix const &ctm, + NR::Rect const &bbox); +NR::Matrix sp_gradient_get_gs2d_matrix(SPGradient const *gr, NR::Matrix const &ctm, + NR::Rect const &bbox); +void sp_gradient_set_gs2d_matrix(SPGradient *gr, NR::Matrix const &ctm, NR::Rect const &bbox, + NR::Matrix const &gs2d); + + +#endif /* !SEEN_SP_GRADIENT_FNS_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:encoding=utf-8:textwidth=99 : diff --git a/src/sp-gradient-reference.cpp b/src/sp-gradient-reference.cpp new file mode 100644 index 000000000..618e1085a --- /dev/null +++ b/src/sp-gradient-reference.cpp @@ -0,0 +1,22 @@ +#include "sp-gradient-reference.h" +#include "sp-gradient-fns.h" + +bool +SPGradientReference::_acceptObject(SPObject *obj) const +{ + return SP_IS_GRADIENT(obj); + /* effic: Don't bother making this an inline function: _acceptObject is a virtual function, + typically called from a context where the runtime type is not known at compile time. */ +} + + +/* + 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:textwidth=99 : diff --git a/src/sp-gradient-reference.h b/src/sp-gradient-reference.h new file mode 100644 index 000000000..8f368b825 --- /dev/null +++ b/src/sp-gradient-reference.h @@ -0,0 +1,31 @@ +#ifndef SEEN_SP_GRADIENT_REFERENCE_H +#define SEEN_SP_GRADIENT_REFERENCE_H + +#include "uri-references.h" +class SPObject; + +class SPGradientReference : public Inkscape::URIReference { +public: + SPGradientReference(SPObject *obj) : URIReference(obj) {} + + SPGradient *getObject() const { + return (SPGradient *)URIReference::getObject(); + } + +protected: + virtual bool _acceptObject(SPObject *obj) const; +}; + + +#endif /* !SEEN_SP_GRADIENT_REFERENCE_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:encoding=utf-8:textwidth=99 : diff --git a/src/sp-gradient-spread.h b/src/sp-gradient-spread.h new file mode 100644 index 000000000..537b6aad7 --- /dev/null +++ b/src/sp-gradient-spread.h @@ -0,0 +1,22 @@ +#ifndef SEEN_SP_GRADIENT_SPREAD_H +#define SEEN_SP_GRADIENT_SPREAD_H + +enum SPGradientSpread { + SP_GRADIENT_SPREAD_PAD, + SP_GRADIENT_SPREAD_REFLECT, + SP_GRADIENT_SPREAD_REPEAT +}; + + +#endif /* !SEEN_SP_GRADIENT_SPREAD_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:encoding=utf-8:textwidth=99 : diff --git a/src/sp-gradient-test.cpp b/src/sp-gradient-test.cpp new file mode 100644 index 000000000..051beb928 --- /dev/null +++ b/src/sp-gradient-test.cpp @@ -0,0 +1,139 @@ +#include "attributes.h" +#include "inkscape-private.h" +#include "sp-gradient.h" +#include "sp-object.h" +#include "document.h" +#include "libnr/nr-matrix.h" +#include "libnr/nr-matrix-fns.h" +#include "libnr/nr-matrix-ops.h" +#include "libnr/nr-rect.h" +#include "libnr/nr-rotate-fns.h" +#include "svg/svg.h" +#include "utest/utest.h" +#include "xml/repr.h" + +/// Dummy functions to keep linker happy +int sp_main_gui (int, char const**) { return 0; } +int sp_main_console (int, char const**) { return 0; } + +static bool +test_gradient() +{ + utest_start("gradient"); + UTEST_TEST("init") { + SPGradient *gr = static_cast(g_object_new(SP_TYPE_GRADIENT, NULL)); + UTEST_ASSERT(gr->gradientTransform.test_identity()); + UTEST_ASSERT(gr->gradientTransform == NR::identity()); + g_object_unref(gr); + } + + /* Create the global inkscape object. */ + static_cast(g_object_new(inkscape_get_type(), NULL)); + + + SPDocument *doc = sp_document_new_dummy(); + + UTEST_TEST("sp_object_set(\"gradientTransform\")") { + SPGradient *gr = static_cast(g_object_new(SP_TYPE_GRADIENT, NULL)); + SP_OBJECT(gr)->document = doc; + sp_object_set(SP_OBJECT(gr), SP_ATTR_GRADIENTTRANSFORM, "translate(5, 8)"); + UTEST_ASSERT(gr->gradientTransform == NR::Matrix(NR::translate(5, 8))); + sp_object_set(SP_OBJECT(gr), SP_ATTR_GRADIENTTRANSFORM, ""); + UTEST_ASSERT(gr->gradientTransform == NR::identity()); + sp_object_set(SP_OBJECT(gr), SP_ATTR_GRADIENTTRANSFORM, "rotate(90)"); + UTEST_ASSERT(gr->gradientTransform == NR::Matrix(rotate_degrees(90))); + g_object_unref(gr); + } + + UTEST_TEST("write") { + SPGradient *gr = static_cast(g_object_new(SP_TYPE_GRADIENT, NULL)); + SP_OBJECT(gr)->document = doc; + sp_object_set(SP_OBJECT(gr), SP_ATTR_GRADIENTTRANSFORM, "matrix(0, 1, -1, 0, 0, 0)"); + Inkscape::XML::Node *repr = sp_repr_new("svg:radialGradient"); + SP_OBJECT(gr)->updateRepr(repr, SP_OBJECT_WRITE_ALL); + { + gchar const *tr = repr->attribute("gradientTransform"); + NR::Matrix svd; + bool const valid = sp_svg_transform_read(tr, &svd); + UTEST_ASSERT(valid); + UTEST_ASSERT(svd == NR::Matrix(rotate_degrees(90))); + } + g_object_unref(gr); + } + + UTEST_TEST("get_g2d, get_gs2d, set_gs2d") { + SPGradient *gr = static_cast(g_object_new(SP_TYPE_GRADIENT, NULL)); + SP_OBJECT(gr)->document = doc; + NR::Matrix const grXform(2, 1, + 1, 3, + 4, 6); + gr->gradientTransform = grXform; + NR::Rect const unit_rect(NR::Point(0, 0), NR::Point(1, 1)); + { + NR::Matrix const g2d(sp_gradient_get_g2d_matrix(gr, NR::identity(), unit_rect)); + NR::Matrix const gs2d(sp_gradient_get_gs2d_matrix(gr, NR::identity(), unit_rect)); + UTEST_ASSERT(g2d == NR::identity()); + UTEST_ASSERT(NR::matrix_equalp(gs2d, gr->gradientTransform * g2d, 1e-12)); + + sp_gradient_set_gs2d_matrix(gr, NR::identity(), unit_rect, gs2d); + UTEST_ASSERT(NR::matrix_equalp(gr->gradientTransform, grXform, 1e-12)); + } + + gr->gradientTransform = grXform; + NR::Matrix const funny(2, 3, + 4, 5, + 6, 7); + { + NR::Matrix const g2d(sp_gradient_get_g2d_matrix(gr, funny, unit_rect)); + NR::Matrix const gs2d(sp_gradient_get_gs2d_matrix(gr, funny, unit_rect)); + UTEST_ASSERT(g2d == funny); + UTEST_ASSERT(NR::matrix_equalp(gs2d, gr->gradientTransform * g2d, 1e-12)); + + sp_gradient_set_gs2d_matrix(gr, funny, unit_rect, gs2d); + UTEST_ASSERT(NR::matrix_equalp(gr->gradientTransform, grXform, 1e-12)); + } + + gr->gradientTransform = grXform; + NR::Rect const larger_rect(NR::Point(5, 6), NR::Point(8, 10)); + { + NR::Matrix const g2d(sp_gradient_get_g2d_matrix(gr, funny, larger_rect)); + NR::Matrix const gs2d(sp_gradient_get_gs2d_matrix(gr, funny, larger_rect)); + UTEST_ASSERT(g2d == NR::Matrix(3, 0, + 0, 4, + 5, 6) * funny); + UTEST_ASSERT(NR::matrix_equalp(gs2d, gr->gradientTransform * g2d, 1e-12)); + + sp_gradient_set_gs2d_matrix(gr, funny, larger_rect, gs2d); + UTEST_ASSERT(NR::matrix_equalp(gr->gradientTransform, grXform, 1e-12)); + + sp_object_set(SP_OBJECT(gr), SP_ATTR_GRADIENTUNITS, "userSpaceOnUse"); + NR::Matrix const user_g2d(sp_gradient_get_g2d_matrix(gr, funny, larger_rect)); + NR::Matrix const user_gs2d(sp_gradient_get_gs2d_matrix(gr, funny, larger_rect)); + UTEST_ASSERT(user_g2d == funny); + UTEST_ASSERT(NR::matrix_equalp(user_gs2d, gr->gradientTransform * user_g2d, 1e-12)); + } + g_object_unref(gr); + } + + return utest_end(); +} + +int main() +{ + g_type_init(); + Inkscape::GC::init(); + return ( test_gradient() + ? EXIT_SUCCESS + : EXIT_FAILURE ); +} + +/* + 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:textwidth=99 : diff --git a/src/sp-gradient-units.h b/src/sp-gradient-units.h new file mode 100644 index 000000000..f79b4c264 --- /dev/null +++ b/src/sp-gradient-units.h @@ -0,0 +1,21 @@ +#ifndef SEEN_SP_GRADIENT_UNITS_H +#define SEEN_SP_GRADIENT_UNITS_H + +enum SPGradientUnits { + SP_GRADIENT_UNITS_OBJECTBOUNDINGBOX, + SP_GRADIENT_UNITS_USERSPACEONUSE +}; + + +#endif /* !SEEN_SP_GRADIENT_UNITS_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:encoding=utf-8:textwidth=99 : diff --git a/src/sp-gradient-vector.h b/src/sp-gradient-vector.h new file mode 100644 index 000000000..7bdfb51bf --- /dev/null +++ b/src/sp-gradient-vector.h @@ -0,0 +1,42 @@ +#ifndef SEEN_SP_GRADIENT_VECTOR_H +#define SEEN_SP_GRADIENT_VECTOR_H + +#include +#include +#include "color.h" + +/** + * Differs from SPStop in that SPStop mirrors the \ element in the document, whereas + * SPGradientStop shows more the effective stop color. + * + * For example, SPGradientStop has no currentColor option: currentColor refers to the color + * property value of the gradient where currentColor appears, so we interpret currentColor before + * copying from SPStop to SPGradientStop. + */ +struct SPGradientStop { + gdouble offset; + SPColor color; + gfloat opacity; +}; + +/** + * The effective gradient vector, after copying stops from the referenced gradient if necessary. + */ +struct SPGradientVector { + bool built; + std::vector stops; +}; + + +#endif /* !SEEN_SP_GRADIENT_VECTOR_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:encoding=utf-8:textwidth=99 : diff --git a/src/sp-gradient.cpp b/src/sp-gradient.cpp new file mode 100644 index 000000000..db2360225 --- /dev/null +++ b/src/sp-gradient.cpp @@ -0,0 +1,1809 @@ +#define __SP_GRADIENT_C__ + +/** \file + * SPGradient, SPStop, SPLinearGradient, SPRadialGradient. + */ +/* + * Authors: + * Lauris Kaplinski + * bulia byak + * + * Copyright (C) 1999-2002 Lauris Kaplinski + * Copyright (C) 2000-2001 Ximian, Inc. + * Copyright (C) 2004 David Turner + * + * Released under GNU GPL, read the file 'COPYING' for more information + * + */ + +#define noSP_GRADIENT_VERBOSE + + +#include +#include +#include +#include +#include +#include "libnr/nr-scale-translate-ops.h" + + +#include "display/nr-gradient-gpl.h" +#include "svg/svg.h" +#include "svg/css-ostringstream.h" +#include "attributes.h" +#include "document-private.h" +#include "gradient-chemistry.h" +#include "sp-gradient-reference.h" +#include "sp-linear-gradient.h" +#include "sp-radial-gradient.h" +#include "sp-stop.h" +#include "streq.h" +#include "uri.h" +#include "xml/repr.h" + +#define SP_MACROS_SILENT +#include "macros.h" + +/// Has to be power of 2 +#define NCOLORS NR_GRADIENT_VECTOR_LENGTH + +static void sp_stop_class_init(SPStopClass *klass); +static void sp_stop_init(SPStop *stop); + +static void sp_stop_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr); +static void sp_stop_set(SPObject *object, unsigned key, gchar const *value); +static Inkscape::XML::Node *sp_stop_write(SPObject *object, Inkscape::XML::Node *repr, guint flags); + +static SPObjectClass *stop_parent_class; + +/** + * Registers SPStop class and returns its type. + */ +GType +sp_stop_get_type() +{ + static GType type = 0; + if (!type) { + GTypeInfo info = { + sizeof(SPStopClass), + NULL, NULL, + (GClassInitFunc) sp_stop_class_init, + NULL, NULL, + sizeof(SPStop), + 16, + (GInstanceInitFunc) sp_stop_init, + NULL, /* value_table */ + }; + type = g_type_register_static(SP_TYPE_OBJECT, "SPStop", &info, (GTypeFlags)0); + } + return type; +} + +/** + * Callback to initialize SPStop vtable. + */ +static void sp_stop_class_init(SPStopClass *klass) +{ + SPObjectClass *sp_object_class = (SPObjectClass *) klass; + + stop_parent_class = (SPObjectClass *) g_type_class_ref(SP_TYPE_OBJECT); + + sp_object_class->build = sp_stop_build; + sp_object_class->set = sp_stop_set; + sp_object_class->write = sp_stop_write; +} + +/** + * Callback to initialize SPStop object. + */ +static void +sp_stop_init(SPStop *stop) +{ + stop->offset = 0.0; + stop->currentColor = false; + sp_color_set_rgb_rgba32(&stop->specified_color, 0x000000ff); + stop->opacity = 1.0; +} + +/** + * Virtual build: set stop attributes from its associated XML node. + */ +static void sp_stop_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr) +{ + if (((SPObjectClass *) stop_parent_class)->build) + (* ((SPObjectClass *) stop_parent_class)->build)(object, document, repr); + + sp_object_read_attr(object, "offset"); + sp_object_read_attr(object, "stop-color"); + sp_object_read_attr(object, "stop-opacity"); + sp_object_read_attr(object, "style"); +} + +/** + * Virtual set: set attribute to value. + */ +static void +sp_stop_set(SPObject *object, unsigned key, gchar const *value) +{ + SPStop *stop = SP_STOP(object); + + switch (key) { + case SP_ATTR_STYLE: { + /** \todo + * fixme: We are reading simple values 3 times during build (Lauris). + * \par + * We need presentation attributes etc. + * \par + * remove the hackish "style reading" from here: see comments in + * sp_object_get_style_property about the bugs in our current + * approach. However, note that SPStyle doesn't currently have + * stop-color and stop-opacity properties. + */ + { + gchar const *p = sp_object_get_style_property(object, "stop-color", "black"); + if (streq(p, "currentColor")) { + stop->currentColor = true; + } else { + guint32 const color = sp_svg_read_color(p, 0); + sp_color_set_rgb_rgba32(&stop->specified_color, color); + } + } + { + gchar const *p = sp_object_get_style_property(object, "stop-opacity", "1"); + gdouble opacity = sp_svg_read_percentage(p, stop->opacity); + stop->opacity = opacity; + } + object->requestModified(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG); + break; + } + case SP_PROP_STOP_COLOR: { + { + gchar const *p = sp_object_get_style_property(object, "stop-color", "black"); + if (streq(p, "currentColor")) { + stop->currentColor = true; + } else { + stop->currentColor = false; + guint32 const color = sp_svg_read_color(p, 0); + sp_color_set_rgb_rgba32(&stop->specified_color, color); + } + } + object->requestModified(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG); + break; + } + case SP_PROP_STOP_OPACITY: { + { + gchar const *p = sp_object_get_style_property(object, "stop-opacity", "1"); + gdouble opacity = sp_svg_read_percentage(p, stop->opacity); + stop->opacity = opacity; + } + object->requestModified(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG); + break; + } + case SP_ATTR_OFFSET: { + stop->offset = sp_svg_read_percentage(value, 0.0); + object->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + } + default: { + if (((SPObjectClass *) stop_parent_class)->set) + (* ((SPObjectClass *) stop_parent_class)->set)(object, key, value); + break; + } + } +} + +/** + * Virtual write: write object attributes to repr. + */ +static Inkscape::XML::Node * +sp_stop_write(SPObject *object, Inkscape::XML::Node *repr, guint flags) +{ + SPStop *stop = SP_STOP(object); + + if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { + repr = sp_repr_new("svg:stop"); + } + + + Inkscape::CSSOStringStream os; + os << "stop-color:"; + if (stop->currentColor) { + os << "currentColor"; + } else { + gchar c[64]; + sp_svg_write_color(c, 64, sp_color_get_rgba32_ualpha(&stop->specified_color, 255)); + os << c; + } + os << ";stop-opacity:" << stop->opacity; + repr->setAttribute("style", os.str().c_str()); + repr->setAttribute("stop-color", NULL); + repr->setAttribute("stop-opacity", NULL); + sp_repr_set_css_double(repr, "offset", stop->offset); + /* strictly speaking, offset an SVG rather than a CSS one, but exponents make no sense + * for offset proportions. */ + + if (((SPObjectClass *) stop_parent_class)->write) + (* ((SPObjectClass *) stop_parent_class)->write)(object, repr, flags); + + return repr; +} + +/** + * Return stop's color as 32bit value. + */ +guint32 +sp_stop_get_rgba32(SPStop const *const stop) +{ + guint32 rgb0 = 0; + /* Default value: arbitrarily black. (SVG1.1 and CSS2 both say that the initial + * value depends on user agent, and don't give any further restrictions that I can + * see.) */ + if (stop->currentColor) { + char const *str = sp_object_get_style_property(stop, "color", NULL); + if (str) { + rgb0 = sp_svg_read_color(str, rgb0); + } + unsigned const alpha = static_cast(stop->opacity * 0xff + 0.5); + g_return_val_if_fail((alpha & ~0xff) == 0, + rgb0 | 0xff); + return rgb0 | alpha; + } else { + return sp_color_get_rgba32_falpha(&stop->specified_color, stop->opacity); + } +} + +/** + * Return stop's color as SPColor. + */ +static SPColor +sp_stop_get_color(SPStop const *const stop) +{ + if (stop->currentColor) { + char const *str = sp_object_get_style_property(stop, "color", NULL); + guint32 const dfl = 0; + /* Default value: arbitrarily black. (SVG1.1 and CSS2 both say that the initial + * value depends on user agent, and don't give any further restrictions that I can + * see.) */ + guint32 color = dfl; + if (str) { + color = sp_svg_read_color(str, dfl); + } + SPColor ret; + sp_color_set_rgb_rgba32(&ret, color); + return ret; + } else { + return stop->specified_color; + } +} + +/* + * Gradient + */ + +static void sp_gradient_class_init(SPGradientClass *klass); +static void sp_gradient_init(SPGradient *gr); + +static void sp_gradient_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr); +static void sp_gradient_release(SPObject *object); +static void sp_gradient_set(SPObject *object, unsigned key, gchar const *value); +static void sp_gradient_child_added(SPObject *object, + Inkscape::XML::Node *child, + Inkscape::XML::Node *ref); +static void sp_gradient_remove_child(SPObject *object, Inkscape::XML::Node *child); +static void sp_gradient_modified(SPObject *object, guint flags); +static Inkscape::XML::Node *sp_gradient_write(SPObject *object, Inkscape::XML::Node *repr, + guint flags); + +static void gradient_ref_modified(SPObject *href, guint flags, SPGradient *gradient); + +static bool sp_gradient_invalidate_vector(SPGradient *gr); +static void sp_gradient_rebuild_vector(SPGradient *gr); + +static void gradient_ref_changed(SPObject *old_ref, SPObject *ref, SPGradient *gradient); + +static SPPaintServerClass *gradient_parent_class; + +/** + * Registers SPGradient class and returns its type. + */ +GType +sp_gradient_get_type() +{ + static GType gradient_type = 0; + if (!gradient_type) { + GTypeInfo gradient_info = { + sizeof(SPGradientClass), + NULL, NULL, + (GClassInitFunc) sp_gradient_class_init, + NULL, NULL, + sizeof(SPGradient), + 16, + (GInstanceInitFunc) sp_gradient_init, + NULL, /* value_table */ + }; + gradient_type = g_type_register_static(SP_TYPE_PAINT_SERVER, "SPGradient", + &gradient_info, (GTypeFlags)0); + } + return gradient_type; +} + +/** + * SPGradient vtable initialization. + */ +static void +sp_gradient_class_init(SPGradientClass *klass) +{ + SPObjectClass *sp_object_class = (SPObjectClass *) klass; + + gradient_parent_class = (SPPaintServerClass *)g_type_class_ref(SP_TYPE_PAINT_SERVER); + + sp_object_class->build = sp_gradient_build; + sp_object_class->release = sp_gradient_release; + sp_object_class->set = sp_gradient_set; + sp_object_class->child_added = sp_gradient_child_added; + sp_object_class->remove_child = sp_gradient_remove_child; + sp_object_class->modified = sp_gradient_modified; + sp_object_class->write = sp_gradient_write; +} + +/** + * Callback for SPGradient object initialization. + */ +static void +sp_gradient_init(SPGradient *gr) +{ + gr->ref = new SPGradientReference(SP_OBJECT(gr)); + gr->ref->changedSignal().connect(sigc::bind(sigc::ptr_fun(gradient_ref_changed), gr)); + + /** \todo + * Fixme: reprs being rearranged (e.g. via the XML editor) + * may require us to clear the state. + */ + gr->state = SP_GRADIENT_STATE_UNKNOWN; + + gr->units = SP_GRADIENT_UNITS_OBJECTBOUNDINGBOX; + gr->units_set = FALSE; + + gr->gradientTransform = NR::identity(); + gr->gradientTransform_set = FALSE; + + gr->spread = SP_GRADIENT_SPREAD_PAD; + gr->spread_set = FALSE; + + gr->has_stops = FALSE; + + gr->vector.built = false; + gr->vector.stops.clear(); + + gr->color = NULL; +} + +/** + * Virtual build: set gradient attributes from its associated repr. + */ +static void +sp_gradient_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr) +{ + SPGradient *gradient = SP_GRADIENT(object); + + if (((SPObjectClass *) gradient_parent_class)->build) + (* ((SPObjectClass *) gradient_parent_class)->build)(object, document, repr); + + SPObject *ochild; + for ( ochild = sp_object_first_child(object) ; ochild ; ochild = SP_OBJECT_NEXT(ochild) ) { + if (SP_IS_STOP(ochild)) { + gradient->has_stops = TRUE; + break; + } + } + + sp_object_read_attr(object, "gradientUnits"); + sp_object_read_attr(object, "gradientTransform"); + sp_object_read_attr(object, "spreadMethod"); + sp_object_read_attr(object, "xlink:href"); + + /* Register ourselves */ + sp_document_add_resource(document, "gradient", object); +} + +/** + * Virtual release of SPGradient members before destruction. + */ +static void +sp_gradient_release(SPObject *object) +{ + SPGradient *gradient = (SPGradient *) object; + +#ifdef SP_GRADIENT_VERBOSE + g_print("Releasing gradient %s\n", SP_OBJECT_ID(object)); +#endif + + if (SP_OBJECT_DOCUMENT(object)) { + /* Unregister ourselves */ + sp_document_remove_resource(SP_OBJECT_DOCUMENT(object), "gradient", SP_OBJECT(object)); + } + + if (gradient->ref) { + if (gradient->ref->getObject()) { + sp_signal_disconnect_by_data(gradient->ref->getObject(), gradient); + } + gradient->ref->detach(); + delete gradient->ref; + gradient->ref = NULL; + } + + if (gradient->color) { + g_free(gradient->color); + gradient->color = NULL; + } + + if (((SPObjectClass *) gradient_parent_class)->release) + ((SPObjectClass *) gradient_parent_class)->release(object); +} + +/** + * Set gradient attribute to value. + */ +static void +sp_gradient_set(SPObject *object, unsigned key, gchar const *value) +{ + SPGradient *gr = SP_GRADIENT(object); + + switch (key) { + case SP_ATTR_GRADIENTUNITS: + if (value) { + if (!strcmp(value, "userSpaceOnUse")) { + gr->units = SP_GRADIENT_UNITS_USERSPACEONUSE; + } else { + gr->units = SP_GRADIENT_UNITS_OBJECTBOUNDINGBOX; + } + gr->units_set = TRUE; + } else { + gr->units = SP_GRADIENT_UNITS_OBJECTBOUNDINGBOX; + gr->units_set = FALSE; + } + object->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_GRADIENTTRANSFORM: { + NR::Matrix t; + if (value && sp_svg_transform_read(value, &t)) { + gr->gradientTransform = t; + gr->gradientTransform_set = TRUE; + } else { + gr->gradientTransform = NR::identity(); + gr->gradientTransform_set = FALSE; + } + object->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + } + case SP_ATTR_SPREADMETHOD: + if (value) { + if (!strcmp(value, "reflect")) { + gr->spread = SP_GRADIENT_SPREAD_REFLECT; + } else if (!strcmp(value, "repeat")) { + gr->spread = SP_GRADIENT_SPREAD_REPEAT; + } else { + gr->spread = SP_GRADIENT_SPREAD_PAD; + } + gr->spread_set = TRUE; + } else { + gr->spread_set = FALSE; + } + object->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_XLINK_HREF: + if (value) { + try { + gr->ref->attach(Inkscape::URI(value)); + } catch (Inkscape::BadURIException &e) { + g_warning("%s", e.what()); + gr->ref->detach(); + } + } else { + gr->ref->detach(); + } + break; + default: + if (((SPObjectClass *) gradient_parent_class)->set) + ((SPObjectClass *) gradient_parent_class)->set(object, key, value); + break; + } +} + +/** + * Gets called when the gradient is (re)attached to another gradient. + */ +static void +gradient_ref_changed(SPObject *old_ref, SPObject *ref, SPGradient *gr) +{ + if (old_ref) { + sp_signal_disconnect_by_data(old_ref, gr); + } + if ( SP_IS_GRADIENT(ref) + && ref != gr ) + { + g_signal_connect(G_OBJECT(ref), "modified", G_CALLBACK(gradient_ref_modified), gr); + } + /// \todo Fixme: what should the flags (second) argument be? */ + gradient_ref_modified(ref, 0, gr); +} + +/** + * Callback for child_added event. + */ +static void +sp_gradient_child_added(SPObject *object, Inkscape::XML::Node *child, Inkscape::XML::Node *ref) +{ + SPGradient *gr = SP_GRADIENT(object); + + sp_gradient_invalidate_vector(gr); + + if (((SPObjectClass *) gradient_parent_class)->child_added) + (* ((SPObjectClass *) gradient_parent_class)->child_added)(object, child, ref); + + SPObject *ochild = sp_object_get_child_by_repr(object, child); + if ( ochild && SP_IS_STOP(ochild) ) { + gr->has_stops = TRUE; + } + + /// \todo Fixme: should we schedule "modified" here? + object->requestModified(SP_OBJECT_MODIFIED_FLAG); +} + +/** + * Callback for remove_child event. + */ +static void +sp_gradient_remove_child(SPObject *object, Inkscape::XML::Node *child) +{ + SPGradient *gr = SP_GRADIENT(object); + + sp_gradient_invalidate_vector(gr); + + if (((SPObjectClass *) gradient_parent_class)->remove_child) + (* ((SPObjectClass *) gradient_parent_class)->remove_child)(object, child); + + gr->has_stops = FALSE; + SPObject *ochild; + for ( ochild = sp_object_first_child(object) ; ochild ; ochild = SP_OBJECT_NEXT(ochild) ) { + if (SP_IS_STOP(ochild)) { + gr->has_stops = TRUE; + break; + } + } + + /* Fixme: should we schedule "modified" here? */ + object->requestModified(SP_OBJECT_MODIFIED_FLAG); +} + +/** + * Callback for modified event. + */ +static void +sp_gradient_modified(SPObject *object, guint flags) +{ + SPGradient *gr = SP_GRADIENT(object); + + if (flags & SP_OBJECT_CHILD_MODIFIED_FLAG) { + sp_gradient_invalidate_vector(gr); + } + + if (flags & SP_OBJECT_MODIFIED_FLAG) flags |= SP_OBJECT_PARENT_MODIFIED_FLAG; + flags &= SP_OBJECT_MODIFIED_CASCADE; + + // FIXME: climb up the ladder of hrefs + GSList *l = NULL; + for (SPObject *child = sp_object_first_child(object) ; child != NULL; child = SP_OBJECT_NEXT(child) ) { + g_object_ref(G_OBJECT(child)); + l = g_slist_prepend(l, child); + } + l = g_slist_reverse(l); + while (l) { + SPObject *child = SP_OBJECT(l->data); + l = g_slist_remove(l, child); + if (flags || (child->mflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { + child->emitModified(flags); + } + g_object_unref(G_OBJECT(child)); + } +} + +/** + * Write gradient attributes to repr. + */ +static Inkscape::XML::Node * +sp_gradient_write(SPObject *object, Inkscape::XML::Node *repr, guint flags) +{ + SPGradient *gr = SP_GRADIENT(object); + + if (((SPObjectClass *) gradient_parent_class)->write) + (* ((SPObjectClass *) gradient_parent_class)->write)(object, repr, flags); + + if (flags & SP_OBJECT_WRITE_BUILD) { + GSList *l = NULL; + for (SPObject *child = sp_object_first_child(object); child; child = SP_OBJECT_NEXT(child)) { + Inkscape::XML::Node *crepr; + crepr = child->updateRepr(NULL, flags); + if (crepr) l = g_slist_prepend(l, crepr); + } + while (l) { + repr->addChild((Inkscape::XML::Node *) l->data, NULL); + Inkscape::GC::release((Inkscape::XML::Node *) l->data); + l = g_slist_remove(l, l->data); + } + } + + if (gr->ref->getURI()) { + gchar *uri_string = gr->ref->getURI()->toString(); + repr->setAttribute("xlink:href", uri_string); + g_free(uri_string); + } + + if ((flags & SP_OBJECT_WRITE_ALL) || gr->units_set) { + switch (gr->units) { + case SP_GRADIENT_UNITS_USERSPACEONUSE: + repr->setAttribute("gradientUnits", "userSpaceOnUse"); + break; + default: + repr->setAttribute("gradientUnits", "objectBoundingBox"); + break; + } + } + + if ((flags & SP_OBJECT_WRITE_ALL) || gr->gradientTransform_set) { + gchar c[256]; + if (sp_svg_transform_write(c, 256, gr->gradientTransform)) { + repr->setAttribute("gradientTransform", c); + } else { + repr->setAttribute("gradientTransform", NULL); + } + } + + if ((flags & SP_OBJECT_WRITE_ALL) || gr->spread_set) { + /* FIXME: Ensure that gr->spread is the inherited value + * if !gr->spread_set. Not currently happening: see sp_gradient_modified. + */ + switch (gr->spread) { + case SP_GRADIENT_SPREAD_REFLECT: + repr->setAttribute("spreadMethod", "reflect"); + break; + case SP_GRADIENT_SPREAD_REPEAT: + repr->setAttribute("spreadMethod", "repeat"); + break; + default: + repr->setAttribute("spreadMethod", "pad"); + break; + } + } + + return repr; +} + +/** + * Forces the vector to be built, if not present (i.e., changed). + * + * \pre SP_IS_GRADIENT(gradient). + */ +void +sp_gradient_ensure_vector(SPGradient *gradient) +{ + g_return_if_fail(gradient != NULL); + g_return_if_fail(SP_IS_GRADIENT(gradient)); + + if (!gradient->vector.built) { + sp_gradient_rebuild_vector(gradient); + } +} + +/** + * Set units property of gradient and emit modified. + */ +void +sp_gradient_set_units(SPGradient *gr, SPGradientUnits units) +{ + if (units != gr->units) { + gr->units = units; + gr->units_set = TRUE; + SP_OBJECT(gr)->requestModified(SP_OBJECT_MODIFIED_FLAG); + } +} + +/** + * Set spread property of gradient and emit modified. + */ +void +sp_gradient_set_spread(SPGradient *gr, SPGradientSpread spread) +{ + if (spread != gr->spread) { + gr->spread = spread; + gr->spread_set = TRUE; + SP_OBJECT(gr)->requestModified(SP_OBJECT_MODIFIED_FLAG); + } +} + +/** + * Returns the first of {src, src-\>ref-\>getObject(), + * src-\>ref-\>getObject()-\>ref-\>getObject(),...} + * for which \a match is true, or NULL if none found. + * + * The raison d'être of this routine is that it correctly handles cycles in the href chain (e.g., if + * a gradient gives itself as its href, or if each of two gradients gives the other as its href). + * + * \pre SP_IS_GRADIENT(src). + */ +static SPGradient * +chase_hrefs(SPGradient *const src, bool (*match)(SPGradient const *)) +{ + g_return_val_if_fail(SP_IS_GRADIENT(src), NULL); + + /* Use a pair of pointers for detecting loops: p1 advances half as fast as p2. If there is a + loop, then once p1 has entered the loop, we'll detect it the next time the distance between + p1 and p2 is a multiple of the loop size. */ + SPGradient *p1 = src, *p2 = src; + bool do1 = false; + for (;;) { + if (match(p2)) { + return p2; + } + + p2 = p2->ref->getObject(); + if (!p2) { + return p2; + } + if (do1) { + p1 = p1->ref->getObject(); + } + do1 = !do1; + + if ( p2 == p1 ) { + /* We've been here before, so return NULL to indicate that no matching gradient found + * in the chain. */ + return NULL; + } + } +} + +/** + * True if gradient has stops. + */ +static bool +has_stops(SPGradient const *gr) +{ + return SP_GRADIENT_HAS_STOPS(gr); +} + +/** + * True if gradient has spread set. + */ +static bool +has_spread_set(SPGradient const *gr) +{ + return gr->spread_set; +} + + +/** + * Returns private vector of given gradient (the gradient at the end of the href chain which has + * stops), optionally normalizing it. + * + * \pre SP_IS_GRADIENT(gradient). + * \pre There exists a gradient in the chain that has stops. + */ +SPGradient * +sp_gradient_get_vector(SPGradient *gradient, bool force_vector) +{ + g_return_val_if_fail(gradient != NULL, NULL); + g_return_val_if_fail(SP_IS_GRADIENT(gradient), NULL); + + SPGradient *const src = chase_hrefs(gradient, has_stops); + return ( force_vector + ? sp_gradient_ensure_vector_normalized(src) + : src ); +} + +/** + * Returns the effective spread of given gradient (climbing up the refs chain if needed). + * + * \pre SP_IS_GRADIENT(gradient). + */ +SPGradientSpread +sp_gradient_get_spread(SPGradient *gradient) +{ + g_return_val_if_fail(SP_IS_GRADIENT(gradient), SP_GRADIENT_SPREAD_PAD); + + SPGradient const *src = chase_hrefs(gradient, has_spread_set); + return ( src + ? src->spread + : SP_GRADIENT_SPREAD_PAD ); // pad is the default +} + +/** + * Clears the gradient's svg:stop children from its repr. + */ +void +sp_gradient_repr_clear_vector(SPGradient *gr) +{ + Inkscape::XML::Node *repr = SP_OBJECT_REPR(gr); + + /* Collect stops from original repr */ + GSList *sl = NULL; + for (Inkscape::XML::Node *child = repr->firstChild() ; child != NULL; child = child->next() ) { + if (!strcmp(child->name(), "svg:stop")) { + sl = g_slist_prepend(sl, child); + } + } + /* Remove all stops */ + while (sl) { + /** \todo + * fixme: This should work, unless we make gradient + * into generic group. + */ + sp_repr_unparent((Inkscape::XML::Node *)sl->data); + sl = g_slist_remove(sl, sl->data); + } +} + +/** + * Writes the gradient's internal vector (whether from its own stops, or + * inherited from refs) into the gradient repr as svg:stop elements. + */ +void +sp_gradient_repr_write_vector(SPGradient *gr) +{ + g_return_if_fail(gr != NULL); + g_return_if_fail(SP_IS_GRADIENT(gr)); + + Inkscape::XML::Node *repr = SP_OBJECT_REPR(gr); + + /* We have to be careful, as vector may be our own, so construct repr list at first */ + GSList *cl = NULL; + + for (guint i = 0; i < gr->vector.stops.size(); i++) { + Inkscape::CSSOStringStream os; + Inkscape::XML::Node *child = sp_repr_new("svg:stop"); + sp_repr_set_css_double(child, "offset", gr->vector.stops[i].offset); + /* strictly speaking, offset an SVG rather than a CSS one, but exponents make no + * sense for offset proportions. */ + gchar c[64]; + sp_svg_write_color(c, 64, sp_color_get_rgba32_ualpha(&gr->vector.stops[i].color, 0x00)); + os << "stop-color:" << c << ";stop-opacity:" << gr->vector.stops[i].opacity; + child->setAttribute("style", os.str().c_str()); + /* Order will be reversed here */ + cl = g_slist_prepend(cl, child); + } + + sp_gradient_repr_clear_vector(gr); + + /* And insert new children from list */ + while (cl) { + Inkscape::XML::Node *child = static_cast(cl->data); + repr->addChild(child, NULL); + Inkscape::GC::release(child); + cl = g_slist_remove(cl, child); + } +} + + +static void +gradient_ref_modified(SPObject *href, guint flags, SPGradient *gradient) +{ + if (sp_gradient_invalidate_vector(gradient)) { + SP_OBJECT(gradient)->requestModified(SP_OBJECT_MODIFIED_FLAG); + /* Conditional to avoid causing infinite loop if there's a cycle in the href chain. */ + } +} + +/** Return true iff change made. */ +static bool +sp_gradient_invalidate_vector(SPGradient *gr) +{ + bool ret = false; + + if (gr->color != NULL) { + g_free(gr->color); + gr->color = NULL; + ret = true; + } + + if (gr->vector.built) { + gr->vector.built = false; + gr->vector.stops.clear(); + ret = true; + } + + return ret; +} + +/** Creates normalized color vector */ +static void +sp_gradient_rebuild_vector(SPGradient *gr) +{ + gint len = 0; + for ( SPObject *child = sp_object_first_child(SP_OBJECT(gr)) ; + child != NULL ; + child = SP_OBJECT_NEXT(child) ) { + if (SP_IS_STOP(child)) { + len ++; + } + } + + gr->has_stops = (len != 0); + + gr->vector.stops.clear(); + + SPGradient *ref = gr->ref->getObject(); + if ( !gr->has_stops && ref ) { + /* Copy vector from referenced gradient */ + gr->vector.built = true; // Prevent infinite recursion. + sp_gradient_ensure_vector(ref); + if (!ref->vector.stops.empty()) { + gr->vector.built = ref->vector.built; + gr->vector.stops.assign(ref->vector.stops.begin(), ref->vector.stops.end()); + return; + } + } + + for (SPObject *child = sp_object_first_child(SP_OBJECT(gr)) ; + child != NULL; + child = SP_OBJECT_NEXT(child) ) { + if (SP_IS_STOP(child)) { + SPStop *stop = SP_STOP(child); + + SPGradientStop gstop; + if (gr->vector.stops.size() > 0) { + // "Each gradient offset value is required to be equal to or greater than the + // previous gradient stop's offset value. If a given gradient stop's offset + // value is not equal to or greater than all previous offset values, then the + // offset value is adjusted to be equal to the largest of all previous offset + // values." + gstop.offset = MAX(stop->offset, gr->vector.stops.back().offset); + } else { + gstop.offset = stop->offset; + } + + // "Gradient offset values less than 0 (or less than 0%) are rounded up to + // 0%. Gradient offset values greater than 1 (or greater than 100%) are rounded + // down to 100%." + gstop.offset = CLAMP(gstop.offset, 0, 1); + + gstop.color = sp_stop_get_color(stop); + gstop.opacity = stop->opacity; + + gr->vector.stops.push_back(gstop); + } + } + + // Normalize per section 13.2.4 of SVG 1.1. + if (gr->vector.stops.size() == 0) { + /* "If no stops are defined, then painting shall occur as if 'none' were specified as the + * paint style." + */ + { + SPGradientStop gstop; + gstop.offset = 0.0; + sp_color_set_rgb_rgba32(&gstop.color, 0x00000000); + gstop.opacity = 0.0; + gr->vector.stops.push_back(gstop); + } + { + SPGradientStop gstop; + gstop.offset = 1.0; + sp_color_set_rgb_rgba32(&gstop.color, 0x00000000); + gstop.opacity = 0.0; + gr->vector.stops.push_back(gstop); + } + } else { + /* "If one stop is defined, then paint with the solid color fill using the color defined + * for that gradient stop." + */ + if (gr->vector.stops.front().offset > 0.0) { + // If the first one is not at 0, then insert a copy of the first at 0. + SPGradientStop gstop; + gstop.offset = 0.0; + sp_color_copy(&gstop.color, &gr->vector.stops.front().color); + gstop.opacity = gr->vector.stops.front().opacity; + gr->vector.stops.insert(gr->vector.stops.begin(), gstop); + } + if (gr->vector.stops.back().offset < 1.0) { + // If the last one is not at 1, then insert a copy of the last at 1. + SPGradientStop gstop; + gstop.offset = 1.0; + sp_color_copy(&gstop.color, &gr->vector.stops.back().color); + gstop.opacity = gr->vector.stops.back().opacity; + gr->vector.stops.push_back(gstop); + } + } + + gr->vector.built = true; +} + +/** + * The gradient's color array is newly created and set up from vector. + */ +void +sp_gradient_ensure_colors(SPGradient *gr) +{ + if (!gr->vector.built) { + sp_gradient_rebuild_vector(gr); + } + g_return_if_fail(!gr->vector.stops.empty()); + + /// \todo Where is the memory freed? + if (!gr->color) { + gr->color = g_new(guchar, 4 * NCOLORS); + } + + for (guint i = 0; i < gr->vector.stops.size() - 1; i++) { + guint32 color = sp_color_get_rgba32_falpha(&gr->vector.stops[i].color, + gr->vector.stops[i].opacity); + gint r0 = (color >> 24) & 0xff; + gint g0 = (color >> 16) & 0xff; + gint b0 = (color >> 8) & 0xff; + gint a0 = color & 0xff; + color = sp_color_get_rgba32_falpha(&gr->vector.stops[i + 1].color, + gr->vector.stops[i + 1].opacity); + gint r1 = (color >> 24) & 0xff; + gint g1 = (color >> 16) & 0xff; + gint b1 = (color >> 8) & 0xff; + gint a1 = color & 0xff; + gint o0 = (gint) floor(gr->vector.stops[i].offset * (NCOLORS - 0.001)); + gint o1 = (gint) floor(gr->vector.stops[i + 1].offset * (NCOLORS - 0.001)); + if (o1 > o0) { + gint dr = ((r1 - r0) << 16) / (o1 - o0); + gint dg = ((g1 - g0) << 16) / (o1 - o0); + gint db = ((b1 - b0) << 16) / (o1 - o0); + gint da = ((a1 - a0) << 16) / (o1 - o0); + gint r = r0 << 16; + gint g = g0 << 16; + gint b = b0 << 16; + gint a = a0 << 16; + for (int j = o0; j < o1 + 1; j++) { + gr->color[4 * j] = r >> 16; + gr->color[4 * j + 1] = g >> 16; + gr->color[4 * j + 2] = b >> 16; + gr->color[4 * j + 3] = a >> 16; + r += dr; + g += dg; + b += db; + a += da; + } + } + } +} + +/** + * Renders gradient vector to buffer as line. + * + * RGB buffer background should be set up beforehand. + * + * @param len,width,height,rowstride Buffer parameters (1 or 2 dimensional). + * @param span Full integer width of requested gradient. + * @param pos Buffer starting position in span. + */ +static void +sp_gradient_render_vector_line_rgba(SPGradient *const gradient, guchar *buf, + gint const len, gint const pos, gint const span) +{ + g_return_if_fail(gradient != NULL); + g_return_if_fail(SP_IS_GRADIENT(gradient)); + g_return_if_fail(buf != NULL); + g_return_if_fail(len > 0); + g_return_if_fail(pos >= 0); + g_return_if_fail(pos + len <= span); + g_return_if_fail(span > 0); + + if (!gradient->color) { + sp_gradient_ensure_colors(gradient); + } + + gint idx = (pos * 1024 << 8) / span; + gint didx = (1024 << 8) / span; + + for (gint x = 0; x < len; x++) { + /// \todo Can this be done with 4 byte copies? + *buf++ = gradient->color[4 * (idx >> 8)]; + *buf++ = gradient->color[4 * (idx >> 8) + 1]; + *buf++ = gradient->color[4 * (idx >> 8) + 2]; + *buf++ = gradient->color[4 * (idx >> 8) + 3]; + idx += didx; + } +} + +/** + * Render rectangular RGBA area from gradient vector. + */ +void +sp_gradient_render_vector_block_rgba(SPGradient *const gradient, guchar *buf, + gint const width, gint const height, gint const rowstride, + gint const pos, gint const span, bool const horizontal) +{ + g_return_if_fail(gradient != NULL); + g_return_if_fail(SP_IS_GRADIENT(gradient)); + g_return_if_fail(buf != NULL); + g_return_if_fail(width > 0); + g_return_if_fail(height > 0); + g_return_if_fail(pos >= 0); + g_return_if_fail((horizontal && (pos + width <= span)) || (!horizontal && (pos + height <= span))); + g_return_if_fail(span > 0); + + if (horizontal) { + sp_gradient_render_vector_line_rgba(gradient, buf, width, pos, span); + for (gint y = 1; y < height; y++) { + memcpy(buf + y * rowstride, buf, 4 * width); + } + } else { + guchar *tmp = (guchar *)alloca(4 * height); + sp_gradient_render_vector_line_rgba(gradient, tmp, height, pos, span); + for (gint y = 0; y < height; y++) { + guchar *b = buf + y * rowstride; + for (gint x = 0; x < width; x++) { + *b++ = tmp[0]; + *b++ = tmp[1]; + *b++ = tmp[2]; + *b++ = tmp[3]; + } + tmp += 4; + } + } +} + +/** + * Render rectangular RGB area from gradient vector. + */ +void +sp_gradient_render_vector_block_rgb(SPGradient *gradient, guchar *buf, + gint const width, gint const height, gint const rowstride, + gint const pos, gint const span, bool const horizontal) +{ + g_return_if_fail(gradient != NULL); + g_return_if_fail(SP_IS_GRADIENT(gradient)); + g_return_if_fail(buf != NULL); + g_return_if_fail(width > 0); + g_return_if_fail(height > 0); + g_return_if_fail(pos >= 0); + g_return_if_fail((horizontal && (pos + width <= span)) || (!horizontal && (pos + height <= span))); + g_return_if_fail(span > 0); + + if (horizontal) { + guchar *tmp = (guchar*)alloca(4 * width); + sp_gradient_render_vector_line_rgba(gradient, tmp, width, pos, span); + for (gint y = 0; y < height; y++) { + guchar *t = tmp; + for (gint x = 0; x < width; x++) { + gint a = t[3]; + gint fc = (t[0] - buf[0]) * a; + buf[0] = buf[0] + ((fc + (fc >> 8) + 0x80) >> 8); + fc = (t[1] - buf[1]) * a; + buf[1] = buf[1] + ((fc + (fc >> 8) + 0x80) >> 8); + fc = (t[2] - buf[2]) * a; + buf[2] = buf[2] + ((fc + (fc >> 8) + 0x80) >> 8); + buf += 3; + t += 4; + } + } + } else { + guchar *tmp = (guchar*)alloca(4 * height); + sp_gradient_render_vector_line_rgba(gradient, tmp, height, pos, span); + for (gint y = 0; y < height; y++) { + guchar *t = tmp + 4 * y; + for (gint x = 0; x < width; x++) { + gint a = t[3]; + gint fc = (t[0] - buf[0]) * a; + buf[0] = buf[0] + ((fc + (fc >> 8) + 0x80) >> 8); + fc = (t[1] - buf[1]) * a; + buf[1] = buf[1] + ((fc + (fc >> 8) + 0x80) >> 8); + fc = (t[2] - buf[2]) * a; + buf[2] = buf[2] + ((fc + (fc >> 8) + 0x80) >> 8); + } + } + } +} + +NR::Matrix +sp_gradient_get_g2d_matrix(SPGradient const *gr, NR::Matrix const &ctm, NR::Rect const &bbox) +{ + if (gr->units == SP_GRADIENT_UNITS_OBJECTBOUNDINGBOX) { + return ( NR::scale(bbox.dimensions()) + * NR::translate(bbox.min()) + * ctm ); + } else { + return ctm; + } +} + +NR::Matrix +sp_gradient_get_gs2d_matrix(SPGradient const *gr, NR::Matrix const &ctm, NR::Rect const &bbox) +{ + if (gr->units == SP_GRADIENT_UNITS_OBJECTBOUNDINGBOX) { + return ( gr->gradientTransform + * NR::scale(bbox.dimensions()) + * NR::translate(bbox.min()) + * ctm ); + } else { + return gr->gradientTransform * ctm; + } +} + +void +sp_gradient_set_gs2d_matrix(SPGradient *gr, NR::Matrix const &ctm, + NR::Rect const &bbox, NR::Matrix const &gs2d) +{ + gr->gradientTransform = gs2d / ctm; + if ( gr->units == SP_GRADIENT_UNITS_OBJECTBOUNDINGBOX ) { + gr->gradientTransform = ( gr->gradientTransform + / NR::translate(bbox.min()) + / NR::scale(bbox.dimensions()) ); + } + gr->gradientTransform_set = TRUE; + + SP_OBJECT(gr)->requestModified(SP_OBJECT_MODIFIED_FLAG); +} + +/* + * Linear Gradient + */ + +class SPLGPainter; + +/// A context with linear gradient, painter, and gradient renderer. +struct SPLGPainter { + SPPainter painter; + SPLinearGradient *lg; + + NRLGradientRenderer lgr; +}; + +static void sp_lineargradient_class_init(SPLinearGradientClass *klass); +static void sp_lineargradient_init(SPLinearGradient *lg); + +static void sp_lineargradient_build(SPObject *object, + SPDocument *document, + Inkscape::XML::Node *repr); +static void sp_lineargradient_set(SPObject *object, unsigned key, gchar const *value); +static Inkscape::XML::Node *sp_lineargradient_write(SPObject *object, Inkscape::XML::Node *repr, + guint flags); + +static SPPainter *sp_lineargradient_painter_new(SPPaintServer *ps, + NR::Matrix const &full_transform, + NR::Matrix const &parent_transform, + NRRect const *bbox); +static void sp_lineargradient_painter_free(SPPaintServer *ps, SPPainter *painter); + +static void sp_lg_fill(SPPainter *painter, NRPixBlock *pb); + +static SPGradientClass *lg_parent_class; + +/** + * Register SPLinearGradient class and return its type. + */ +GType +sp_lineargradient_get_type() +{ + static GType type = 0; + if (!type) { + GTypeInfo info = { + sizeof(SPLinearGradientClass), + NULL, NULL, + (GClassInitFunc) sp_lineargradient_class_init, + NULL, NULL, + sizeof(SPLinearGradient), + 16, + (GInstanceInitFunc) sp_lineargradient_init, + NULL, /* value_table */ + }; + type = g_type_register_static(SP_TYPE_GRADIENT, "SPLinearGradient", &info, (GTypeFlags)0); + } + return type; +} + +/** + * SPLinearGradient vtable initialization. + */ +static void sp_lineargradient_class_init(SPLinearGradientClass *klass) +{ + SPObjectClass *sp_object_class = (SPObjectClass *) klass; + SPPaintServerClass *ps_class = (SPPaintServerClass *) klass; + + lg_parent_class = (SPGradientClass*)g_type_class_ref(SP_TYPE_GRADIENT); + + sp_object_class->build = sp_lineargradient_build; + sp_object_class->set = sp_lineargradient_set; + sp_object_class->write = sp_lineargradient_write; + + ps_class->painter_new = sp_lineargradient_painter_new; + ps_class->painter_free = sp_lineargradient_painter_free; +} + +/** + * Callback for SPLinearGradient object initialization. + */ +static void sp_lineargradient_init(SPLinearGradient *lg) +{ + lg->x1.unset(SVGLength::PERCENT, 0.0, 0.0); + lg->y1.unset(SVGLength::PERCENT, 0.5, 0.5); + lg->x2.unset(SVGLength::PERCENT, 1.0, 1.0); + lg->y2.unset(SVGLength::PERCENT, 0.5, 0.5); +} + +/** + * Callback: set attributes from associated repr. + */ +static void sp_lineargradient_build(SPObject *object, + SPDocument *document, + Inkscape::XML::Node *repr) +{ + if (((SPObjectClass *) lg_parent_class)->build) + (* ((SPObjectClass *) lg_parent_class)->build)(object, document, repr); + + sp_object_read_attr(object, "x1"); + sp_object_read_attr(object, "y1"); + sp_object_read_attr(object, "x2"); + sp_object_read_attr(object, "y2"); +} + +/** + * Callback: set attribute. + */ +static void +sp_lineargradient_set(SPObject *object, unsigned key, gchar const *value) +{ + SPLinearGradient *lg = SP_LINEARGRADIENT(object); + + switch (key) { + case SP_ATTR_X1: + lg->x1.readOrUnset(value, SVGLength::PERCENT, 0.0, 0.0); + object->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_Y1: + lg->y1.readOrUnset(value, SVGLength::PERCENT, 0.5, 0.5); + object->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_X2: + lg->x2.readOrUnset(value, SVGLength::PERCENT, 1.0, 1.0); + object->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_Y2: + lg->y2.readOrUnset(value, SVGLength::PERCENT, 0.5, 0.5); + object->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + default: + if (((SPObjectClass *) lg_parent_class)->set) + (* ((SPObjectClass *) lg_parent_class)->set)(object, key, value); + break; + } +} + +/** + * Callback: write attributes to associated repr. + */ +static Inkscape::XML::Node * +sp_lineargradient_write(SPObject *object, Inkscape::XML::Node *repr, guint flags) +{ + SPLinearGradient *lg = SP_LINEARGRADIENT(object); + + if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { + repr = sp_repr_new("svg:linearGradient"); + } + + if ((flags & SP_OBJECT_WRITE_ALL) || lg->x1._set) + sp_repr_set_svg_double(repr, "x1", lg->x1.computed); + if ((flags & SP_OBJECT_WRITE_ALL) || lg->y1._set) + sp_repr_set_svg_double(repr, "y1", lg->y1.computed); + if ((flags & SP_OBJECT_WRITE_ALL) || lg->x2._set) + sp_repr_set_svg_double(repr, "x2", lg->x2.computed); + if ((flags & SP_OBJECT_WRITE_ALL) || lg->y2._set) + sp_repr_set_svg_double(repr, "y2", lg->y2.computed); + + if (((SPObjectClass *) lg_parent_class)->write) + (* ((SPObjectClass *) lg_parent_class)->write)(object, repr, flags); + + return repr; +} + +/** + * Create linear gradient context. + * + * Basically we have to deal with transformations + * + * 1) color2norm - maps point in (0,NCOLORS) vector to (0,1) vector + * 2) norm2pos - maps (0,1) vector to x1,y1 - x2,y2 + * 2) gradientTransform + * 3) bbox2user + * 4) ctm == userspace to pixel grid + * + * See also (*) in sp-pattern about why we may need parent_transform. + * + * \todo (point 1 above) fixme: I do not know how to deal with start > 0 + * and end < 1. + */ +static SPPainter * +sp_lineargradient_painter_new(SPPaintServer *ps, + NR::Matrix const &full_transform, + NR::Matrix const &parent_transform, + NRRect const *bbox) +{ + SPLinearGradient *lg = SP_LINEARGRADIENT(ps); + SPGradient *gr = SP_GRADIENT(ps); + + if (!gr->color) sp_gradient_ensure_colors(gr); + + SPLGPainter *lgp = g_new(SPLGPainter, 1); + + lgp->painter.type = SP_PAINTER_IND; + lgp->painter.fill = sp_lg_fill; + + lgp->lg = lg; + + /** \todo + * Technically speaking, we map NCOLORS on line [start,end] onto line + * [0,1]. I almost think we should fill color array start and end in + * that case. The alternative would be to leave these just empty garbage + * or something similar. Originally I had 1023.9999 here - not sure + * whether we have really to cut out ceil int (Lauris). + */ + NR::Matrix color2norm(NR::identity()); + NR::Matrix color2px; + if (gr->units == SP_GRADIENT_UNITS_OBJECTBOUNDINGBOX) { + NR::Matrix norm2pos(NR::identity()); + + /* BBox to user coordinate system */ + NR::Matrix bbox2user(bbox->x1 - bbox->x0, 0, 0, bbox->y1 - bbox->y0, bbox->x0, bbox->y0); + + NR::Matrix color2pos = color2norm * norm2pos; + NR::Matrix color2tpos = color2pos * gr->gradientTransform; + NR::Matrix color2user = color2tpos * bbox2user; + color2px = color2user * full_transform; + + } else { + /* Problem: What to do, if we have mixed lengths and percentages? */ + /* Currently we do ignore percentages at all, but that is not good (lauris) */ + + NR::Matrix norm2pos(NR::identity()); + NR::Matrix color2pos = color2norm * norm2pos; + NR::Matrix color2tpos = color2pos * gr->gradientTransform; + color2px = color2tpos * full_transform; + + } + + NRMatrix v2px; + color2px.copyto(&v2px); + + nr_lgradient_renderer_setup(&lgp->lgr, gr->color, sp_gradient_get_spread(gr), &v2px, + lg->x1.computed, lg->y1.computed, + lg->x2.computed, lg->y2.computed); + + return (SPPainter *) lgp; +} + +static void +sp_lineargradient_painter_free(SPPaintServer *ps, SPPainter *painter) +{ + g_free(painter); +} + +/** + * Directly set properties of linear gradient and request modified. + */ +void +sp_lineargradient_set_position(SPLinearGradient *lg, + gdouble x1, gdouble y1, + gdouble x2, gdouble y2) +{ + g_return_if_fail(lg != NULL); + g_return_if_fail(SP_IS_LINEARGRADIENT(lg)); + + /* fixme: units? (Lauris) */ + lg->x1.set(SVGLength::NONE, x1, x1); + lg->y1.set(SVGLength::NONE, y1, y1); + lg->x2.set(SVGLength::NONE, x2, x2); + lg->y2.set(SVGLength::NONE, y2, y2); + + SP_OBJECT(lg)->requestModified(SP_OBJECT_MODIFIED_FLAG); +} + +/** + * Callback when linear gradient object is rendered. + */ +static void +sp_lg_fill(SPPainter *painter, NRPixBlock *pb) +{ + SPLGPainter *lgp = (SPLGPainter *) painter; + + if (lgp->lg->color == NULL) { + sp_gradient_ensure_colors (lgp->lg); + lgp->lgr.vector = lgp->lg->color; + } + + nr_render((NRRenderer *) &lgp->lgr, pb, NULL); +} + +/* + * Radial Gradient + */ + +class SPRGPainter; + +/// A context with radial gradient, painter, and gradient renderer. +struct SPRGPainter { + SPPainter painter; + SPRadialGradient *rg; + NRRGradientRenderer rgr; +}; + +static void sp_radialgradient_class_init(SPRadialGradientClass *klass); +static void sp_radialgradient_init(SPRadialGradient *rg); + +static void sp_radialgradient_build(SPObject *object, + SPDocument *document, + Inkscape::XML::Node *repr); +static void sp_radialgradient_set(SPObject *object, unsigned key, gchar const *value); +static Inkscape::XML::Node *sp_radialgradient_write(SPObject *object, Inkscape::XML::Node *repr, + guint flags); + +static SPPainter *sp_radialgradient_painter_new(SPPaintServer *ps, + NR::Matrix const &full_transform, + NR::Matrix const &parent_transform, + NRRect const *bbox); +static void sp_radialgradient_painter_free(SPPaintServer *ps, SPPainter *painter); + +static void sp_rg_fill(SPPainter *painter, NRPixBlock *pb); + +static SPGradientClass *rg_parent_class; + +/** + * Register SPRadialGradient class and return its type. + */ +GType +sp_radialgradient_get_type() +{ + static GType type = 0; + if (!type) { + GTypeInfo info = { + sizeof(SPRadialGradientClass), + NULL, NULL, + (GClassInitFunc) sp_radialgradient_class_init, + NULL, NULL, + sizeof(SPRadialGradient), + 16, + (GInstanceInitFunc) sp_radialgradient_init, + NULL, /* value_table */ + }; + type = g_type_register_static(SP_TYPE_GRADIENT, "SPRadialGradient", &info, (GTypeFlags)0); + } + return type; +} + +/** + * SPRadialGradient vtable initialization. + */ +static void sp_radialgradient_class_init(SPRadialGradientClass *klass) +{ + SPObjectClass *sp_object_class = (SPObjectClass *) klass; + SPPaintServerClass *ps_class = (SPPaintServerClass *) klass; + + rg_parent_class = (SPGradientClass*)g_type_class_ref(SP_TYPE_GRADIENT); + + sp_object_class->build = sp_radialgradient_build; + sp_object_class->set = sp_radialgradient_set; + sp_object_class->write = sp_radialgradient_write; + + ps_class->painter_new = sp_radialgradient_painter_new; + ps_class->painter_free = sp_radialgradient_painter_free; +} + +/** + * Callback for SPRadialGradient object initialization. + */ +static void +sp_radialgradient_init(SPRadialGradient *rg) +{ + rg->cx.unset(SVGLength::PERCENT, 0.5, 0.5); + rg->cy.unset(SVGLength::PERCENT, 0.5, 0.5); + rg->r.unset(SVGLength::PERCENT, 0.5, 0.5); + rg->fx.unset(SVGLength::PERCENT, 0.5, 0.5); + rg->fy.unset(SVGLength::PERCENT, 0.5, 0.5); +} + +/** + * Set radial gradient attributes from associated repr. + */ +static void +sp_radialgradient_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr) +{ + if (((SPObjectClass *) rg_parent_class)->build) + (* ((SPObjectClass *) rg_parent_class)->build)(object, document, repr); + + sp_object_read_attr(object, "cx"); + sp_object_read_attr(object, "cy"); + sp_object_read_attr(object, "r"); + sp_object_read_attr(object, "fx"); + sp_object_read_attr(object, "fy"); +} + +/** + * Set radial gradient attribute. + */ +static void +sp_radialgradient_set(SPObject *object, unsigned key, gchar const *value) +{ + SPRadialGradient *rg = SP_RADIALGRADIENT(object); + + switch (key) { + case SP_ATTR_CX: + if (!rg->cx.read(value)) { + rg->cx.unset(SVGLength::PERCENT, 0.5, 0.5); + } + if (!rg->fx._set) { + rg->fx.value = rg->cx.value; + rg->fx.computed = rg->cx.computed; + } + object->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_CY: + if (!rg->cy.read(value)) { + rg->cy.unset(SVGLength::PERCENT, 0.5, 0.5); + } + if (!rg->fy._set) { + rg->fy.value = rg->cy.value; + rg->fy.computed = rg->cy.computed; + } + object->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_R: + if (!rg->r.read(value)) { + rg->r.unset(SVGLength::PERCENT, 0.5, 0.5); + } + object->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_FX: + if (!rg->fx.read(value)) { + rg->fx.unset(rg->cx.unit, rg->cx.value, rg->cx.computed); + } + object->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_FY: + if (!rg->fy.read(value)) { + rg->fy.unset(rg->cy.unit, rg->cy.value, rg->cy.computed); + } + object->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + default: + if (((SPObjectClass *) rg_parent_class)->set) + ((SPObjectClass *) rg_parent_class)->set(object, key, value); + break; + } +} + +/** + * Write radial gradient attributes to associated repr. + */ +static Inkscape::XML::Node * +sp_radialgradient_write(SPObject *object, Inkscape::XML::Node *repr, guint flags) +{ + SPRadialGradient *rg = SP_RADIALGRADIENT(object); + + if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { + repr = sp_repr_new("svg:radialGradient"); + } + + if ((flags & SP_OBJECT_WRITE_ALL) || rg->cx._set) sp_repr_set_svg_double(repr, "cx", rg->cx.computed); + if ((flags & SP_OBJECT_WRITE_ALL) || rg->cy._set) sp_repr_set_svg_double(repr, "cy", rg->cy.computed); + if ((flags & SP_OBJECT_WRITE_ALL) || rg->r._set) sp_repr_set_svg_double(repr, "r", rg->r.computed); + if ((flags & SP_OBJECT_WRITE_ALL) || rg->fx._set) sp_repr_set_svg_double(repr, "fx", rg->fx.computed); + if ((flags & SP_OBJECT_WRITE_ALL) || rg->fy._set) sp_repr_set_svg_double(repr, "fy", rg->fy.computed); + + if (((SPObjectClass *) rg_parent_class)->write) + (* ((SPObjectClass *) rg_parent_class)->write)(object, repr, flags); + + return repr; +} + +/** + * Create radial gradient context. + */ +static SPPainter * +sp_radialgradient_painter_new(SPPaintServer *ps, + NR::Matrix const &full_transform, + NR::Matrix const &parent_transform, + NRRect const *bbox) +{ + SPRadialGradient *rg = SP_RADIALGRADIENT(ps); + SPGradient *gr = SP_GRADIENT(ps); + + if (!gr->color) sp_gradient_ensure_colors(gr); + + SPRGPainter *rgp = g_new(SPRGPainter, 1); + + rgp->painter.type = SP_PAINTER_IND; + rgp->painter.fill = sp_rg_fill; + + rgp->rg = rg; + + NR::Matrix gs2px; + + if (gr->units == SP_GRADIENT_UNITS_OBJECTBOUNDINGBOX) { + /** \todo + * fixme: We may try to normalize here too, look at + * linearGradient (Lauris) + */ + + /* BBox to user coordinate system */ + NR::Matrix bbox2user(bbox->x1 - bbox->x0, 0, 0, bbox->y1 - bbox->y0, bbox->x0, bbox->y0); + + NR::Matrix gs2user = gr->gradientTransform * bbox2user; + + gs2px = gs2user * full_transform; + } else { + /** \todo + * Problem: What to do, if we have mixed lengths and percentages? + * Currently we do ignore percentages at all, but that is not + * good (lauris) + */ + + gs2px = gr->gradientTransform * full_transform; + } + + NRMatrix gs2px_nr; + gs2px.copyto(&gs2px_nr); + + nr_rgradient_renderer_setup(&rgp->rgr, gr->color, sp_gradient_get_spread(gr), + &gs2px_nr, + rg->cx.computed, rg->cy.computed, + rg->fx.computed, rg->fy.computed, + rg->r.computed); + + return (SPPainter *) rgp; +} + +static void +sp_radialgradient_painter_free(SPPaintServer *ps, SPPainter *painter) +{ + g_free(painter); +} + +/** + * Directly set properties of radial gradient and request modified. + */ +void +sp_radialgradient_set_position(SPRadialGradient *rg, + gdouble cx, gdouble cy, gdouble fx, gdouble fy, gdouble r) +{ + g_return_if_fail(rg != NULL); + g_return_if_fail(SP_IS_RADIALGRADIENT(rg)); + + /* fixme: units? (Lauris) */ + rg->cx.set(SVGLength::NONE, cx, cx); + rg->cy.set(SVGLength::NONE, cy, cy); + rg->fx.set(SVGLength::NONE, fx, fx); + rg->fy.set(SVGLength::NONE, fy, fy); + rg->r.set(SVGLength::NONE, r, r); + + SP_OBJECT(rg)->requestModified(SP_OBJECT_MODIFIED_FLAG); +} + +/** + * Callback when radial gradient object is rendered. + */ +static void +sp_rg_fill(SPPainter *painter, NRPixBlock *pb) +{ + SPRGPainter *rgp = (SPRGPainter *) painter; + + if (rgp->rg->color == NULL) { + sp_gradient_ensure_colors (rgp->rg); + rgp->rgr.vector = rgp->rg->color; + } + + nr_render((NRRenderer *) &rgp->rgr, pb, NULL); +} + +/* + 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:textwidth=99 : diff --git a/src/sp-gradient.h b/src/sp-gradient.h new file mode 100644 index 000000000..9c152598b --- /dev/null +++ b/src/sp-gradient.h @@ -0,0 +1,95 @@ +#ifndef __SP_GRADIENT_H__ +#define __SP_GRADIENT_H__ + +/** \file + * SVG and implementation + * + * Authors: + * Lauris Kaplinski + * + * Copyright (C) 1999-2002 Lauris Kaplinski + * Copyright (C) 2000-2001 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include +#include "libnr/nr-matrix.h" +#include "sp-paint-server.h" +#include "sp-gradient-spread.h" +#include "sp-gradient-units.h" +#include "sp-gradient-vector.h" + +struct SPGradientReference; + +typedef enum { + SP_GRADIENT_TYPE_UNKNOWN, + SP_GRADIENT_TYPE_LINEAR, + SP_GRADIENT_TYPE_RADIAL +} SPGradientType; + +typedef enum { + SP_GRADIENT_STATE_UNKNOWN, + SP_GRADIENT_STATE_VECTOR, + SP_GRADIENT_STATE_PRIVATE +} SPGradientState; + +typedef enum { + POINT_LG_P1, + POINT_LG_P2, + POINT_RG_CENTER, + POINT_RG_R1, + POINT_RG_R2, + POINT_RG_FOCUS +} GrPoint; + +/** + * Gradient + * + * Implement spread, stops list + * \todo fixme: Implement more here (Lauris) + */ +struct SPGradient : public SPPaintServer { + /** Reference (href) */ + SPGradientReference *ref; + /** State in Inkscape gradient system */ + guint state : 2; + /** gradientUnits attribute */ + SPGradientUnits units; + guint units_set : 1; + /** gradientTransform attribute */ + NR::Matrix gradientTransform; + guint gradientTransform_set : 1; + /** spreadMethod attribute */ + SPGradientSpread spread; + guint spread_set : 1; + /** Gradient stops */ + guint has_stops : 1; + /** Composed vector */ + SPGradientVector vector; + /** Rendered color array (4 * 1024 bytes) */ + guchar *color; +}; + +/** + * The SPGradient vtable. + */ +struct SPGradientClass { + SPPaintServerClass parent_class; +}; + + +#include "sp-gradient-fns.h" + +#endif /* !__SP_GRADIENT_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:encoding=utf-8:textwidth=99 : diff --git a/src/sp-guide-attachment.h b/src/sp-guide-attachment.h new file mode 100644 index 000000000..277b435b6 --- /dev/null +++ b/src/sp-guide-attachment.h @@ -0,0 +1,43 @@ +#ifndef __SP_GUIDE_ATTACHMENT_H__ +#define __SP_GUIDE_ATTACHMENT_H__ + +#include + +class SPGuideAttachment { +public: + SPItem *item; + int snappoint_ix; + +public: + SPGuideAttachment() : + item(static_cast(0)) + { } + + SPGuideAttachment(SPItem *i, int s) : + item(i), + snappoint_ix(s) + { } + + bool operator==(SPGuideAttachment const &o) const { + return ( ( item == o.item ) + && ( snappoint_ix == o.snappoint_ix ) ); + } + + bool operator!=(SPGuideAttachment const &o) const { + return !(*this == o); + } +}; + + +#endif /* !__SP_GUIDE_ATTACHMENT_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:encoding=utf-8:textwidth=99 : diff --git a/src/sp-guide-constraint.h b/src/sp-guide-constraint.h new file mode 100644 index 000000000..5444b8468 --- /dev/null +++ b/src/sp-guide-constraint.h @@ -0,0 +1,44 @@ +#ifndef __SP_GUIDE_CONSTRAINT_H__ +#define __SP_GUIDE_CONSTRAINT_H__ + +#include + +class SPGuideConstraint { +public: + SPGuide *g; + int snappoint_ix; + +public: + explicit SPGuideConstraint() : + g(static_cast(0)) + { } + + explicit SPGuideConstraint(SPGuide *g, int snappoint_ix) : + g(g), + snappoint_ix(snappoint_ix) + { } + + bool operator==(SPGuideConstraint const &o) const { + return ( ( g == o.g ) + && ( snappoint_ix == o.snappoint_ix ) ); + } + + bool operator!=(SPGuideConstraint const &o) const { + return !( *this == o ); + } +}; + + +#endif /* !__SP_GUIDE_CONSTRAINT_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:encoding=utf-8:textwidth=99 : diff --git a/src/sp-guide.cpp b/src/sp-guide.cpp new file mode 100644 index 000000000..98ca66092 --- /dev/null +++ b/src/sp-guide.cpp @@ -0,0 +1,326 @@ +#define __SP_GUIDE_C__ + +/* + * Inkscape guideline implementation + * + * Authors: + * Lauris Kaplinski + * Peter Moulder + * + * Copyright (C) 2000-2002 authors + * Copyright (C) 2004 Monash University + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifdef HAVE_CONFIG_H +# include +#endif +#include "display/guideline.h" +#include "svg/svg.h" +#include "attributes.h" +#include "sp-guide.h" +#include +#include +#include +#include +#include +#include +using std::vector; + +enum { + PROP_0, + PROP_COLOR, + PROP_HICOLOR +}; + +static void sp_guide_class_init(SPGuideClass *gc); +static void sp_guide_init(SPGuide *guide); +static void sp_guide_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); +static void sp_guide_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); + +static void sp_guide_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr); +static void sp_guide_release(SPObject *object); +static void sp_guide_set(SPObject *object, unsigned int key, const gchar *value); + +static SPObjectClass *parent_class; + +GType sp_guide_get_type(void) +{ + static GType guide_type = 0; + + if (!guide_type) { + GTypeInfo guide_info = { + sizeof(SPGuideClass), + NULL, NULL, + (GClassInitFunc) sp_guide_class_init, + NULL, NULL, + sizeof(SPGuide), + 16, + (GInstanceInitFunc) sp_guide_init, + NULL, /* value_table */ + }; + guide_type = g_type_register_static(SP_TYPE_OBJECT, "SPGuide", &guide_info, (GTypeFlags) 0); + } + + return guide_type; +} + +static void sp_guide_class_init(SPGuideClass *gc) +{ + GObjectClass *gobject_class = (GObjectClass *) gc; + SPObjectClass *sp_object_class = (SPObjectClass *) gc; + + parent_class = (SPObjectClass*) g_type_class_ref(SP_TYPE_OBJECT); + + gobject_class->set_property = sp_guide_set_property; + gobject_class->get_property = sp_guide_get_property; + + sp_object_class->build = sp_guide_build; + sp_object_class->release = sp_guide_release; + sp_object_class->set = sp_guide_set; + + g_object_class_install_property(gobject_class, + PROP_COLOR, + g_param_spec_uint("color", "Color", "Color", + 0, + 0xffffffff, + 0xff000000, + (GParamFlags) G_PARAM_READWRITE)); + + g_object_class_install_property(gobject_class, + PROP_HICOLOR, + g_param_spec_uint("hicolor", "HiColor", "HiColor", + 0, + 0xffffffff, + 0xff000000, + (GParamFlags) G_PARAM_READWRITE)); +} + +static void sp_guide_init(SPGuide *guide) +{ + guide->normal = component_vectors[NR::Y]; + /* constrain y coordinate; horizontal line. I doubt it ever matters what we initialize + this to. */ + guide->position = 0.0; + guide->color = 0x0000ff7f; + guide->hicolor = 0xff00007f; +} + +static void sp_guide_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + SPGuide &guide = *SP_GUIDE(object); + + switch (prop_id) { + case PROP_COLOR: + guide.color = g_value_get_uint(value); + for (GSList *l = guide.views; l != NULL; l = l->next) { + sp_guideline_set_color(SP_GUIDELINE(l->data), guide.color); + } + break; + + case PROP_HICOLOR: + guide.hicolor = g_value_get_uint(value); + break; + } +} + +static void sp_guide_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + SPGuide const &guide = *SP_GUIDE(object); + + switch (prop_id) { + case PROP_COLOR: + g_value_set_uint(value, guide.color); + break; + case PROP_HICOLOR: + g_value_set_uint(value, guide.hicolor); + break; + } +} + +static void sp_guide_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr) +{ + if (((SPObjectClass *) (parent_class))->build) { + (* ((SPObjectClass *) (parent_class))->build)(object, document, repr); + } + + sp_object_read_attr(object, "orientation"); + sp_object_read_attr(object, "position"); +} + +static void sp_guide_release(SPObject *object) +{ + SPGuide *guide = (SPGuide *) object; + + while (guide->views) { + gtk_object_destroy(GTK_OBJECT(guide->views->data)); + guide->views = g_slist_remove(guide->views, guide->views->data); + } + + if (((SPObjectClass *) parent_class)->release) { + ((SPObjectClass *) parent_class)->release(object); + } +} + +static void sp_guide_set(SPObject *object, unsigned int key, const gchar *value) +{ + SPGuide *guide = SP_GUIDE(object); + + switch (key) { + case SP_ATTR_ORIENTATION: + if (value && !strcmp(value, "horizontal")) { + /* Visual representation of a horizontal line, constrain vertically (y coordinate). */ + guide->normal = component_vectors[NR::Y]; + } else { + guide->normal = component_vectors[NR::X]; + } + break; + case SP_ATTR_POSITION: + sp_svg_number_read_d(value, &guide->position); + // update position in non-committing way + // fixme: perhaps we need to add an update method instead, and request_update here + sp_guide_moveto(*guide, guide->position, false); + break; + default: + if (((SPObjectClass *) (parent_class))->set) { + ((SPObjectClass *) (parent_class))->set(object, key, value); + } + break; + } +} + +void sp_guide_show(SPGuide *guide, SPCanvasGroup *group, GCallback handler) +{ + bool const vertical_line_p = ( guide->normal == component_vectors[NR::X] ); + g_assert(( guide->normal == component_vectors[NR::X] ) || + ( guide->normal == component_vectors[NR::Y] ) ); + SPCanvasItem *item = sp_guideline_new(group, guide->position, vertical_line_p); + sp_guideline_set_color(SP_GUIDELINE(item), guide->color); + + g_signal_connect(G_OBJECT(item), "event", G_CALLBACK(handler), guide); + + guide->views = g_slist_prepend(guide->views, item); +} + +void sp_guide_hide(SPGuide *guide, SPCanvas *canvas) +{ + g_assert(guide != NULL); + g_assert(SP_IS_GUIDE(guide)); + g_assert(canvas != NULL); + g_assert(SP_IS_CANVAS(canvas)); + + for (GSList *l = guide->views; l != NULL; l = l->next) { + if (canvas == SP_CANVAS_ITEM(l->data)->canvas) { + gtk_object_destroy(GTK_OBJECT(l->data)); + guide->views = g_slist_remove(guide->views, l->data); + return; + } + } + + g_assert_not_reached(); +} + +void sp_guide_sensitize(SPGuide *guide, SPCanvas *canvas, gboolean sensitive) +{ + g_assert(guide != NULL); + g_assert(SP_IS_GUIDE(guide)); + g_assert(canvas != NULL); + g_assert(SP_IS_CANVAS(canvas)); + + for (GSList *l = guide->views; l != NULL; l = l->next) { + if (canvas == SP_CANVAS_ITEM(l->data)->canvas) { + sp_guideline_set_sensitive(SP_GUIDELINE(l->data), sensitive); + return; + } + } + + g_assert_not_reached(); +} + +double sp_guide_position_from_pt(SPGuide const *guide, NR::Point const &pt) +{ + return dot(guide->normal, pt); +} + +/** + * \arg commit False indicates temporary moveto in response to motion event while dragging, + * true indicates a "committing" version: in response to button release event after + * dragging a guideline, or clicking OK in guide editing dialog. + */ +void sp_guide_moveto(SPGuide const &guide, gdouble const position, bool const commit) +{ + g_assert(SP_IS_GUIDE(&guide)); + + for (GSList *l = guide.views; l != NULL; l = l->next) { + sp_guideline_set_position(SP_GUIDELINE(l->data), + position); + } + + /* Calling sp_repr_set_svg_double must precede calling sp_item_notify_moveto in the commit + case, so that the guide's new position is available for sp_item_rm_unsatisfied_cns. */ + if (commit) { + sp_repr_set_svg_double(SP_OBJECT(&guide)->repr, + "position", position); + } + + for (vector::const_iterator i(guide.attached_items.begin()), + iEnd(guide.attached_items.end()); + i != iEnd; ++i) + { + SPGuideAttachment const &att = *i; + sp_item_notify_moveto(*att.item, guide, att.snappoint_ix, position, commit); + } +} + +/** + * Returns a human-readable description of the guideline for use in dialog boxes and status bar. + * + * The caller is responsible for freeing the string. + */ +char *sp_guide_description(SPGuide const *guide) +{ + using NR::X; + using NR::Y; + + if ( guide->normal == component_vectors[X] ) { + return g_strdup(_("vertical guideline")); + } else if ( guide->normal == component_vectors[Y] ) { + return g_strdup(_("horizontal guideline")); + } else { + double const radians = atan2(guide->normal[X], + guide->normal[Y]); + /* flip y axis and rotate 90 degrees to convert to line angle */ + double const degrees = ( radians / M_PI ) * 180.0; + int const degrees_int = (int) floor( degrees + .5 ); + return g_strdup_printf("%d degree guideline", degrees_int); + /* Alternative suggestion: "angled guideline". */ + } +} + +void sp_guide_remove(SPGuide *guide) +{ + g_assert(SP_IS_GUIDE(guide)); + + for (vector::const_iterator i(guide->attached_items.begin()), + iEnd(guide->attached_items.end()); + i != iEnd; ++i) + { + SPGuideAttachment const &att = *i; + remove_last(att.item->constraints, SPGuideConstraint(guide, att.snappoint_ix)); + } + guide->attached_items.clear(); + + sp_repr_unparent(SP_OBJECT(guide)->repr); +} + +/* + 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 : diff --git a/src/sp-guide.h b/src/sp-guide.h new file mode 100644 index 000000000..a3b876483 --- /dev/null +++ b/src/sp-guide.h @@ -0,0 +1,64 @@ +#ifndef SP_GUIDE_H +#define SP_GUIDE_H + +/* + * SPGuide + * + * A guideline + * + * Copyright (C) Lauris Kaplinski 2000 + * + */ + +#include + +#include "display/display-forward.h" +#include "libnr/nr-point.h" +#include "sp-object.h" +#include "sp-guide-attachment.h" + +#define SP_TYPE_GUIDE (sp_guide_get_type()) +#define SP_GUIDE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), SP_TYPE_GUIDE, SPGuide)) +#define SP_GUIDE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), SP_TYPE_GUIDE, SPGuideClass)) +#define SP_IS_GUIDE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), SP_TYPE_GUIDE)) +#define SP_IS_GUIDE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), SP_TYPE_GUIDE)) + +/* Represents the constraint on p that dot(g.direction, p) == g.position. */ +struct SPGuide : public SPObject { + NR::Point normal; + gdouble position; + guint32 color; + guint32 hicolor; + GSList *views; + std::vector attached_items; +}; + +struct SPGuideClass { + SPObjectClass parent_class; +}; + +GType sp_guide_get_type(); + +void sp_guide_show(SPGuide *guide, SPCanvasGroup *group, GCallback handler); +void sp_guide_hide(SPGuide *guide, SPCanvas *canvas); +void sp_guide_sensitize(SPGuide *guide, SPCanvas *canvas, gboolean sensitive); + +double sp_guide_position_from_pt(SPGuide const *guide, NR::Point const &pt); +void sp_guide_moveto(SPGuide const &guide, gdouble const position, bool const commit); +void sp_guide_remove(SPGuide *guide); + +char *sp_guide_description(SPGuide const *guide); + + +#endif /* !SP_GUIDE_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:encoding=utf-8:textwidth=99 : diff --git a/src/sp-image.cpp b/src/sp-image.cpp new file mode 100644 index 000000000..869981567 --- /dev/null +++ b/src/sp-image.cpp @@ -0,0 +1,1200 @@ +#define __SP_IMAGE_C__ + +/* + * SVG implementation + * + * Authors: + * Lauris Kaplinski + * Edward Flick (EAF) + * + * Copyright (C) 1999-2005 Authors + * Copyright (C) 2000-2001 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif +#include + +//#define GDK_PIXBUF_ENABLE_BACKEND 1 +//#include +#include "display/nr-arena-image.h" + +//Added for preserveAspectRatio support -- EAF +#include "enums.h" +#include "attributes.h" + +#include "print.h" +#include "brokenimage.xpm" +#include "document.h" +#include "sp-image.h" +#include +#include "xml/quote.h" +#include + +#include "io/sys.h" +#include + +/* + * SPImage + */ + + +static void sp_image_class_init (SPImageClass * klass); +static void sp_image_init (SPImage * image); + +static void sp_image_build (SPObject * object, SPDocument * document, Inkscape::XML::Node * repr); +static void sp_image_release (SPObject * object); +static void sp_image_set (SPObject *object, unsigned int key, const gchar *value); +static void sp_image_update (SPObject *object, SPCtx *ctx, unsigned int flags); +static Inkscape::XML::Node *sp_image_write (SPObject *object, Inkscape::XML::Node *repr, guint flags); + +static void sp_image_bbox(SPItem const *item, NRRect *bbox, NR::Matrix const &transform, unsigned const flags); +static void sp_image_print (SPItem * item, SPPrintContext *ctx); +static gchar * sp_image_description (SPItem * item); +static void sp_image_snappoints(SPItem const *item, SnapPointsIter p); +static NRArenaItem *sp_image_show (SPItem *item, NRArena *arena, unsigned int key, unsigned int flags); +static NR::Matrix sp_image_set_transform (SPItem *item, NR::Matrix const &xform); + +GdkPixbuf * sp_image_repr_read_image (Inkscape::XML::Node * repr); +static GdkPixbuf *sp_image_pixbuf_force_rgba (GdkPixbuf * pixbuf); +static void sp_image_update_canvas_image (SPImage *image); +static GdkPixbuf * sp_image_repr_read_dataURI (const gchar * uri_data); +static GdkPixbuf * sp_image_repr_read_b64 (const gchar * uri_data); + +static SPItemClass *parent_class; + + +extern "C" +{ + void user_read_data( png_structp png_ptr, png_bytep data, png_size_t length ); + void user_write_data( png_structp png_ptr, png_bytep data, png_size_t length ); + void user_flush_data( png_structp png_ptr ); + +} + +namespace Inkscape { +namespace IO { + +class PushPull +{ +public: + gboolean first; + FILE* fp; + guchar* scratch; + gsize size; + gsize used; + gsize offset; + GdkPixbufLoader *loader; + + PushPull() : first(TRUE), + fp(0), + scratch(0), + size(0), + used(0), + offset(0), + loader(0) {}; + + gboolean readMore() + { + gboolean good = FALSE; + if ( offset ) + { + g_memmove( scratch, scratch + offset, used - offset ); + used -= offset; + offset = 0; + } + if ( used < size ) + { + gsize space = size - used; + gsize got = fread( scratch + used, 1, space, fp ); + if ( got ) + { + if ( loader ) + { + GError *err = NULL; + //g_message( " __read %d bytes", (int)got ); + if ( !gdk_pixbuf_loader_write( loader, scratch + used, got, &err ) ) + { + //g_message("_error writing pixbuf data"); + } + } + + used += got; + good = TRUE; + } + else + { + good = FALSE; + } + } + return good; + } + + gsize available() const + { + return (used - offset); + } + + gsize readOut( gpointer data, gsize length ) + { + gsize giving = available(); + if ( length < giving ) + { + giving = length; + } + g_memmove( data, scratch + offset, giving ); + offset += giving; + if ( offset >= used ) + { + offset = 0; + used = 0; + } + return giving; + } + + void clear() + { + offset = 0; + used = 0; + } + +private: + PushPull& operator = (const PushPull& other); + PushPull(const PushPull& other); +}; + +void user_read_data( png_structp png_ptr, png_bytep data, png_size_t length ) +{ +// g_message( "user_read_data(%d)", length ); + + PushPull* youme = (PushPull*)png_get_io_ptr(png_ptr); + + gsize filled = 0; + gboolean canRead = TRUE; + + while ( filled < length && canRead ) + { + gsize some = youme->readOut( data + filled, length - filled ); + filled += some; + if ( filled < length ) + { + canRead &= youme->readMore(); + } + } +// g_message("things out"); +} + +void user_write_data( png_structp png_ptr, png_bytep data, png_size_t length ) +{ + //g_message( "user_write_data(%d)", length ); +} + +void user_flush_data( png_structp png_ptr ) +{ + //g_message( "user_flush_data" ); +} + +GdkPixbuf* pixbuf_new_from_file( const char *filename, GError **error ) +{ + GdkPixbuf* buf = NULL; + PushPull youme; + gint dpiX = 0; + gint dpiY = 0; + + //buf = gdk_pixbuf_new_from_file( filename, error ); + dump_fopen_call( filename, "pixbuf_new_from_file" ); + FILE* fp = fopen_utf8name( filename, "r" ); + if ( fp ) + { + GdkPixbufLoader *loader = gdk_pixbuf_loader_new(); + if ( loader ) + { + GError *err = NULL; + + // short buffer + guchar scratch[1024]; + gboolean latter = FALSE; + gboolean isPng = FALSE; + png_structp pngPtr = NULL; + png_infop infoPtr = NULL; + //png_infop endPtr = NULL; + + youme.fp = fp; + youme.scratch = scratch; + youme.size = sizeof(scratch); + youme.used = 0; + youme.offset = 0; + youme.loader = loader; + + while ( !feof(fp) ) + { + if ( youme.readMore() ) + { + if ( youme.first ) + { + //g_message( "First data chunk" ); + youme.first = FALSE; + isPng = !png_sig_cmp( scratch + youme.offset, 0, youme.available() ); + //g_message( " png? %s", (isPng ? "Yes":"No") ); + if ( isPng ) + { + pngPtr = png_create_read_struct( PNG_LIBPNG_VER_STRING, + NULL,//(png_voidp)user_error_ptr, + NULL,//user_error_fn, + NULL//user_warning_fn + ); + if ( pngPtr ) + { + infoPtr = png_create_info_struct( pngPtr ); + //endPtr = png_create_info_struct( pngPtr ); + + png_set_read_fn( pngPtr, &youme, user_read_data ); + //g_message( "In" ); + + //png_read_info( pngPtr, infoPtr ); + png_read_png( pngPtr, infoPtr, PNG_TRANSFORM_IDENTITY, NULL ); + + //g_message("out"); + + //png_read_end(pngPtr, endPtr); + + /* + if ( png_get_valid( pngPtr, infoPtr, PNG_INFO_pHYs ) ) + { + g_message("pHYs chunk now valid" ); + } + if ( png_get_valid( pngPtr, infoPtr, PNG_INFO_sCAL ) ) + { + g_message("sCAL chunk now valid" ); + } + */ + + png_uint_32 res_x = 0; + png_uint_32 res_y = 0; + int unit_type = 0; + if ( png_get_pHYs( pngPtr, infoPtr, &res_x, &res_y, &unit_type) ) + { +// g_message( "pHYs yes (%d, %d) %d (%s)", (int)res_x, (int)res_y, unit_type, +// (unit_type == 1? "per meter" : "unknown") +// ); + +// g_message( " dpi: (%d, %d)", +// (int)(0.5 + ((double)res_x)/39.37), +// (int)(0.5 + ((double)res_y)/39.37) ); + if ( unit_type == PNG_RESOLUTION_METER ) + { + // TODO come up with a more accurate DPI setting + dpiX = (int)(0.5 + ((double)res_x)/39.37); + dpiY = (int)(0.5 + ((double)res_y)/39.37); + } + } + else + { +// g_message( "pHYs no" ); + } + +/* + double width = 0; + double height = 0; + int unit = 0; + if ( png_get_sCAL(pngPtr, infoPtr, &unit, &width, &height) ) + { + gchar* vals[] = { + "unknown", // PNG_SCALE_UNKNOWN + "meter", // PNG_SCALE_METER + "radian", // PNG_SCALE_RADIAN + "last", // + NULL + }; + + g_message( "sCAL: (%f, %f) %d (%s)", + width, height, unit, + ((unit >= 0 && unit < 3) ? vals[unit]:"???") + ); + } +*/ + + // now clean it up. + png_destroy_read_struct( &pngPtr, &infoPtr, NULL );//&endPtr ); + } + else + { + g_message("Error when creating PNG read struct"); + } + } + } + else if ( !latter ) + { + latter = TRUE; + //g_message(" READing latter"); + } + // Now clear out the buffer so we can read more. + // (dumping out unused) + youme.clear(); + } + } + + gboolean ok = gdk_pixbuf_loader_close(loader, &err); + if ( ok ) + { + buf = gdk_pixbuf_loader_get_pixbuf( loader ); + if ( buf ) + { + g_object_ref(buf); + + if ( dpiX ) + { + gchar *tmp = g_strdup_printf( "%d", dpiX ); + if ( tmp ) + { + //gdk_pixbuf_set_option( buf, "Inkscape::DpiX", tmp ); + g_free( tmp ); + } + } + if ( dpiY ) + { + gchar *tmp = g_strdup_printf( "%d", dpiY ); + if ( tmp ) + { + //gdk_pixbuf_set_option( buf, "Inkscape::DpiY", tmp ); + g_free( tmp ); + } + } + } + } + else + { + // do something + g_message("error loading pixbuf at close"); + } + + g_object_unref(loader); + } + else + { + g_message("error when creating pixbuf loader"); + } + fclose( fp ); + fp = NULL; + } + else + { + g_warning ("unable to open file: %s", filename); + } + +/* + if ( buf ) + { + const gchar* bloop = gdk_pixbuf_get_option( buf, "Inkscape::DpiX" ); + if ( bloop ) + { + g_message("DPI X is [%s]", bloop); + } + bloop = gdk_pixbuf_get_option( buf, "Inkscape::DpiY" ); + if ( bloop ) + { + g_message("DPI Y is [%s]", bloop); + } + } +*/ + + return buf; +} + +} +} + +GType +sp_image_get_type (void) +{ + static GType image_type = 0; + if (!image_type) { + GTypeInfo image_info = { + sizeof (SPImageClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) sp_image_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (SPImage), + 16, /* n_preallocs */ + (GInstanceInitFunc) sp_image_init, + NULL, /* value_table */ + }; + image_type = g_type_register_static (sp_item_get_type (), "SPImage", &image_info, (GTypeFlags)0); + } + return image_type; +} + +static void +sp_image_class_init (SPImageClass * klass) +{ + GObjectClass * gobject_class; + SPObjectClass * sp_object_class; + SPItemClass * item_class; + + gobject_class = (GObjectClass *) klass; + sp_object_class = (SPObjectClass *) klass; + item_class = (SPItemClass *) klass; + + parent_class = (SPItemClass*)g_type_class_ref (sp_item_get_type ()); + + sp_object_class->build = sp_image_build; + sp_object_class->release = sp_image_release; + sp_object_class->set = sp_image_set; + sp_object_class->update = sp_image_update; + sp_object_class->write = sp_image_write; + + item_class->bbox = sp_image_bbox; + item_class->print = sp_image_print; + item_class->description = sp_image_description; + item_class->show = sp_image_show; + item_class->snappoints = sp_image_snappoints; + item_class->set_transform = sp_image_set_transform; +} + +static void +sp_image_init (SPImage *image) +{ + image->x.unset(); + image->y.unset(); + image->width.unset(); + image->height.unset(); + image->aspect_align = SP_ASPECT_NONE; +} + +static void +sp_image_build (SPObject *object, SPDocument *document, Inkscape::XML::Node *repr) +{ + if (((SPObjectClass *) parent_class)->build) + ((SPObjectClass *) parent_class)->build (object, document, repr); + + sp_object_read_attr (object, "xlink:href"); + sp_object_read_attr (object, "x"); + sp_object_read_attr (object, "y"); + sp_object_read_attr (object, "width"); + sp_object_read_attr (object, "height"); + sp_object_read_attr (object, "preserveAspectRatio"); + + /* Register */ + sp_document_add_resource (document, "image", object); +} + +static void +sp_image_release (SPObject *object) +{ + SPImage *image; + + image = SP_IMAGE (object); + + if (SP_OBJECT_DOCUMENT (object)) { + /* Unregister ourselves */ + sp_document_remove_resource (SP_OBJECT_DOCUMENT (object), "image", SP_OBJECT (object)); + } + + if (image->href) { + g_free (image->href); + image->href = NULL; + } + + if (image->pixbuf) { + gdk_pixbuf_unref (image->pixbuf); + image->pixbuf = NULL; + } + + if (((SPObjectClass *) parent_class)->release) + ((SPObjectClass *) parent_class)->release (object); +} + +static void +sp_image_set (SPObject *object, unsigned int key, const gchar *value) +{ + SPImage *image; + + image = SP_IMAGE (object); + + switch (key) { + case SP_ATTR_XLINK_HREF: + g_free (image->href); + image->href = (value) ? g_strdup (value) : NULL; + object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_IMAGE_HREF_MODIFIED_FLAG); + break; + case SP_ATTR_X: + if (!image->x.readAbsolute(value)) { + /* fixme: em, ex, % are probably valid, but require special treatment (Lauris) */ + image->x.unset(); + } + object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_Y: + if (!image->y.readAbsolute(value)) { + /* fixme: em, ex, % are probably valid, but require special treatment (Lauris) */ + image->y.unset(); + } + object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_WIDTH: + if (!image->width.readAbsolute(value)) { + /* fixme: em, ex, % are probably valid, but require special treatment (Lauris) */ + image->width.unset(); + } + object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_HEIGHT: + if (!image->height.readAbsolute(value)) { + /* fixme: em, ex, % are probably valid, but require special treatment (Lauris) */ + image->height.unset(); + } + object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_PRESERVEASPECTRATIO: + /* Do setup before, so we can use break to escape */ + image->aspect_align = SP_ASPECT_NONE; + image->aspect_clip = SP_ASPECT_MEET; + object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG); + if (value) { + int len; + gchar c[256]; + const gchar *p, *e; + unsigned int align, clip; + p = value; + while (*p && *p == 32) p += 1; + if (!*p) break; + e = p; + while (*e && *e != 32) e += 1; + len = e - p; + if (len > 8) break; + memcpy (c, value, len); + c[len] = 0; + /* Now the actual part */ + if (!strcmp (c, "none")) { + align = SP_ASPECT_NONE; + } else if (!strcmp (c, "xMinYMin")) { + align = SP_ASPECT_XMIN_YMIN; + } else if (!strcmp (c, "xMidYMin")) { + align = SP_ASPECT_XMID_YMIN; + } else if (!strcmp (c, "xMaxYMin")) { + align = SP_ASPECT_XMAX_YMIN; + } else if (!strcmp (c, "xMinYMid")) { + align = SP_ASPECT_XMIN_YMID; + } else if (!strcmp (c, "xMidYMid")) { + align = SP_ASPECT_XMID_YMID; + } else if (!strcmp (c, "xMaxYMid")) { + align = SP_ASPECT_XMAX_YMID; + } else if (!strcmp (c, "xMinYMax")) { + align = SP_ASPECT_XMIN_YMAX; + } else if (!strcmp (c, "xMidYMax")) { + align = SP_ASPECT_XMID_YMAX; + } else if (!strcmp (c, "xMaxYMax")) { + align = SP_ASPECT_XMAX_YMAX; + } else { + break; + } + clip = SP_ASPECT_MEET; + while (*e && *e == 32) e += 1; + if (e) { + if (!strcmp (e, "meet")) { + clip = SP_ASPECT_MEET; + } else if (!strcmp (e, "slice")) { + clip = SP_ASPECT_SLICE; + } else { + break; + } + } + image->aspect_align = align; + image->aspect_clip = clip; + } + break; + default: + if (((SPObjectClass *) (parent_class))->set) + ((SPObjectClass *) (parent_class))->set (object, key, value); + break; + } +} + +static void +sp_image_update (SPObject *object, SPCtx *ctx, unsigned int flags) +{ + SPImage *image; + + image = (SPImage *) object; + + if (((SPObjectClass *) (parent_class))->update) + ((SPObjectClass *) (parent_class))->update (object, ctx, flags); + + if (flags & SP_IMAGE_HREF_MODIFIED_FLAG) { + if (image->pixbuf) { + gdk_pixbuf_unref (image->pixbuf); + image->pixbuf = NULL; + } + if (image->href) { + GdkPixbuf *pixbuf; + pixbuf = sp_image_repr_read_image (object->repr); + if (pixbuf) { + pixbuf = sp_image_pixbuf_force_rgba (pixbuf); + image->pixbuf = pixbuf; + } + } + } + // preserveAspectRatio calculate bounds / clipping rectangle -- EAF + if (image->pixbuf && (image->aspect_align != SP_ASPECT_NONE)) { + int imagewidth, imageheight; + double x,y; + + imagewidth = gdk_pixbuf_get_width (image->pixbuf); + imageheight = gdk_pixbuf_get_height (image->pixbuf); + + switch (image->aspect_align) { + case SP_ASPECT_XMIN_YMIN: + x = 0.0; + y = 0.0; + break; + case SP_ASPECT_XMID_YMIN: + x = 0.5; + y = 0.0; + break; + case SP_ASPECT_XMAX_YMIN: + x = 1.0; + y = 0.0; + break; + case SP_ASPECT_XMIN_YMID: + x = 0.0; + y = 0.5; + break; + case SP_ASPECT_XMID_YMID: + x = 0.5; + y = 0.5; + break; + case SP_ASPECT_XMAX_YMID: + x = 1.0; + y = 0.5; + break; + case SP_ASPECT_XMIN_YMAX: + x = 0.0; + y = 1.0; + break; + case SP_ASPECT_XMID_YMAX: + x = 0.5; + y = 1.0; + break; + case SP_ASPECT_XMAX_YMAX: + x = 1.0; + y = 1.0; + break; + default: + x = 0.0; + y = 0.0; + break; + } + + if (image->aspect_clip == SP_ASPECT_SLICE) { + image->viewx = image->x.computed; + image->viewy = image->y.computed; + image->viewwidth = image->width.computed; + image->viewheight = image->height.computed; + if ((imagewidth*image->height.computed)>(image->width.computed*imageheight)) { + // Pixels aspect is wider than bounding box + image->trimheight = imageheight; + image->trimwidth = static_cast(static_cast(imageheight) * image->width.computed / image->height.computed); + image->trimy = 0; + image->trimx = static_cast(static_cast(imagewidth - image->trimwidth) * x); + } else { + // Pixels aspect is taller than bounding box + image->trimwidth = imagewidth; + image->trimheight = static_cast(static_cast(imagewidth) * image->height.computed / image->width.computed); + image->trimx = 0; + image->trimy = static_cast(static_cast(imageheight - image->trimheight) * y); + } + } else { + // Otherwise, assume SP_ASPECT_MEET + image->trimx = 0; + image->trimy = 0; + image->trimwidth = imagewidth; + image->trimheight = imageheight; + if ((imagewidth*image->height.computed)>(image->width.computed*imageheight)) { + // Pixels aspect is wider than bounding boz + image->viewwidth = image->width.computed; + image->viewheight = image->viewwidth * imageheight / imagewidth; + image->viewx=image->x.computed; + image->viewy=(image->height.computed - image->viewheight) * y + image->y.computed; + } else { + // Pixels aspect is taller than bounding box + image->viewheight = image->height.computed; + image->viewwidth = image->viewheight * imagewidth / imageheight; + image->viewy=image->y.computed; + image->viewx=(image->width.computed - image->viewwidth) * x + image->x.computed; + } + } + } + + sp_image_update_canvas_image ((SPImage *) object); +} + +static Inkscape::XML::Node * +sp_image_write (SPObject *object, Inkscape::XML::Node *repr, guint flags) +{ + SPImage *image; + + image = SP_IMAGE (object); + + if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { + repr = sp_repr_new ("svg:image"); + } + + repr->setAttribute("xlink:href", image->href); + /* fixme: Reset attribute if needed (Lauris) */ + if (image->x._set) sp_repr_set_svg_double(repr, "x", image->x.computed); + if (image->y._set) sp_repr_set_svg_double(repr, "y", image->y.computed); + if (image->width._set) sp_repr_set_svg_double(repr, "width", image->width.computed); + if (image->height._set) sp_repr_set_svg_double(repr, "height", image->height.computed); + repr->setAttribute("preserveAspectRatio", object->repr->attribute("preserveAspectRatio")); + + if (((SPObjectClass *) (parent_class))->write) + ((SPObjectClass *) (parent_class))->write (object, repr, flags); + + return repr; +} + +static void +sp_image_bbox(SPItem const *item, NRRect *bbox, NR::Matrix const &transform, unsigned const flags) +{ + SPImage const &image = *SP_IMAGE(item); + + if ((image.width.computed > 0.0) && (image.height.computed > 0.0)) { + double const x0 = image.x.computed; + double const y0 = image.y.computed; + double const x1 = x0 + image.width.computed; + double const y1 = y0 + image.height.computed; + + nr_rect_union_pt(bbox, NR::Point(x0, y0) * transform); + nr_rect_union_pt(bbox, NR::Point(x1, y0) * transform); + nr_rect_union_pt(bbox, NR::Point(x1, y1) * transform); + nr_rect_union_pt(bbox, NR::Point(x0, y1) * transform); + } +} + +static void +sp_image_print (SPItem *item, SPPrintContext *ctx) +{ + SPImage *image; + NRMatrix tp, ti, s, t; + guchar *px; + int w, h, rs, pixskip; + + image = SP_IMAGE (item); + + if (!image->pixbuf) return; + if ((image->width.computed <= 0.0) || (image->height.computed <= 0.0)) return; + + px = gdk_pixbuf_get_pixels (image->pixbuf); + w = gdk_pixbuf_get_width (image->pixbuf); + h = gdk_pixbuf_get_height (image->pixbuf); + rs = gdk_pixbuf_get_rowstride (image->pixbuf); + pixskip = gdk_pixbuf_get_n_channels (image->pixbuf) * gdk_pixbuf_get_bits_per_sample (image->pixbuf) / 8; + + if (image->aspect_align == SP_ASPECT_NONE) { + /* fixme: (Lauris) */ + nr_matrix_set_translate (&tp, image->x.computed, image->y.computed); + nr_matrix_set_scale (&s, image->width.computed, -image->height.computed); + nr_matrix_set_translate (&ti, 0.0, -1.0); + } else { // preserveAspectRatio + nr_matrix_set_translate (&tp, image->viewx, image->viewy); + nr_matrix_set_scale (&s, image->viewwidth, -image->viewheight); + nr_matrix_set_translate (&ti, 0.0, -1.0); + } + + nr_matrix_multiply (&t, &s, &tp); + nr_matrix_multiply (&t, &ti, &t); + + if (image->aspect_align == SP_ASPECT_NONE) + sp_print_image_R8G8B8A8_N (ctx, px, w, h, rs, &t, SP_OBJECT_STYLE (item)); + else // preserveAspectRatio + sp_print_image_R8G8B8A8_N (ctx, px + image->trimx*pixskip + image->trimy*rs, image->trimwidth, image->trimheight, rs, &t, SP_OBJECT_STYLE (item)); +} + +static gchar * +sp_image_description(SPItem *item) +{ + SPImage *image = SP_IMAGE(item); + char *href_desc; + if (image->href) { + href_desc = (strncmp(image->href, "data:", 5) == 0) + ? g_strdup(_("embedded")) + : xml_quote_strdup(image->href); + } else { + g_warning("Attempting to call strncmp() with a null pointer."); + href_desc = g_strdup(_("(null_pointer)")); // we call g_free() on href_desc + } + + char *ret = ( image->pixbuf == NULL + ? g_strdup_printf(_("Image with bad reference: %s"), href_desc) + : g_strdup_printf(_("Image %d × %d: %s"), + gdk_pixbuf_get_width(image->pixbuf), + gdk_pixbuf_get_height(image->pixbuf), + href_desc) ); + g_free(href_desc); + return ret; +} + +static NRArenaItem * +sp_image_show (SPItem *item, NRArena *arena, unsigned int key, unsigned int flags) +{ + int pixskip, rs; + SPImage * image; + NRArenaItem *ai; + + image = (SPImage *) item; + + ai = NRArenaImage::create(arena); + + if (image->pixbuf) { + pixskip = gdk_pixbuf_get_n_channels (image->pixbuf) * gdk_pixbuf_get_bits_per_sample (image->pixbuf) / 8; + rs = gdk_pixbuf_get_rowstride (image->pixbuf); + if (image->aspect_align == SP_ASPECT_NONE) + nr_arena_image_set_pixels (NR_ARENA_IMAGE (ai), + gdk_pixbuf_get_pixels (image->pixbuf), + gdk_pixbuf_get_width (image->pixbuf), + gdk_pixbuf_get_height (image->pixbuf), + rs); + else // preserveAspectRatio + nr_arena_image_set_pixels (NR_ARENA_IMAGE (ai), + gdk_pixbuf_get_pixels (image->pixbuf) + image->trimx*pixskip + image->trimy*rs, + image->trimwidth, + image->trimheight, + rs); + } else { + nr_arena_image_set_pixels (NR_ARENA_IMAGE (ai), NULL, 0, 0, 0); + } + if (image->aspect_align == SP_ASPECT_NONE) + nr_arena_image_set_geometry (NR_ARENA_IMAGE (ai), image->x.computed, image->y.computed, image->width.computed, image->height.computed); + else // preserveAspectRatio + nr_arena_image_set_geometry (NR_ARENA_IMAGE (ai), image->viewx, image->viewy, image->viewwidth, image->viewheight); + + return ai; +} + +/* + * utility function to try loading image from href + * + * docbase/relative_src + * absolute_src + * + */ + +GdkPixbuf * +sp_image_repr_read_image (Inkscape::XML::Node * repr) +{ + const gchar * filename, * docbase; + gchar * fullname; + GdkPixbuf * pixbuf; + + filename = repr->attribute("xlink:href"); + if (filename == NULL) filename = repr->attribute("href"); /* FIXME */ + if (filename != NULL) { + if (strncmp (filename,"file:",5) == 0) { + fullname = g_filename_from_uri(filename, NULL, NULL); + if (fullname) { + // TODO check this. Was doing a UTF-8 to filename conversion here. + pixbuf = Inkscape::IO::pixbuf_new_from_file (fullname, NULL); + if (pixbuf != NULL) return pixbuf; + } + } else if (strncmp (filename,"data:",5) == 0) { + /* data URI - embedded image */ + filename += 5; + pixbuf = sp_image_repr_read_dataURI (filename); + if (pixbuf != NULL) return pixbuf; + } else if (!g_path_is_absolute (filename)) { + /* try to load from relative pos */ + docbase = sp_repr_document_root (sp_repr_document (repr))->attribute("sodipodi:docbase"); + if (!docbase) docbase = "."; + fullname = g_build_filename(docbase, filename, NULL); + pixbuf = Inkscape::IO::pixbuf_new_from_file( fullname, NULL ); + g_free (fullname); + if (pixbuf != NULL) return pixbuf; + } else { + /* try absolute filename */ + pixbuf = Inkscape::IO::pixbuf_new_from_file( filename, NULL ); + if (pixbuf != NULL) return pixbuf; + } + } + /* at last try to load from sp absolute path name */ + filename = repr->attribute("sodipodi:absref"); + if (filename != NULL) { + pixbuf = Inkscape::IO::pixbuf_new_from_file( filename, NULL ); + if (pixbuf != NULL) return pixbuf; + } + /* Nope: We do not find any valid pixmap file :-( */ + pixbuf = gdk_pixbuf_new_from_xpm_data ((const gchar **) brokenimage_xpm); + + /* It should be included xpm, so if it still does not does load, */ + /* our libraries are broken */ + g_assert (pixbuf != NULL); + + return pixbuf; +} + +static GdkPixbuf * +sp_image_pixbuf_force_rgba (GdkPixbuf * pixbuf) +{ + GdkPixbuf * newbuf; + + if (gdk_pixbuf_get_has_alpha (pixbuf)) return pixbuf; + + newbuf = gdk_pixbuf_add_alpha (pixbuf, FALSE, 0, 0, 0); + gdk_pixbuf_unref (pixbuf); + + return newbuf; +} + +/* We assert that realpixbuf is either NULL or identical size to pixbuf */ + +static void +sp_image_update_canvas_image (SPImage *image) +{ + int rs, pixskip; + SPItem *item; + SPItemView *v; + + item = SP_ITEM (image); + + if (image->pixbuf) { + /* fixme: We are slightly violating spec here (Lauris) */ + if (!image->width._set) { + image->width.computed = gdk_pixbuf_get_width (image->pixbuf); + } + if (!image->height._set) { + image->height.computed = gdk_pixbuf_get_height (image->pixbuf); + } + } + + for (v = item->display; v != NULL; v = v->next) { + pixskip = gdk_pixbuf_get_n_channels (image->pixbuf) * gdk_pixbuf_get_bits_per_sample (image->pixbuf) / 8; + rs = gdk_pixbuf_get_rowstride (image->pixbuf); + if (image->aspect_align == SP_ASPECT_NONE) { + nr_arena_image_set_pixels (NR_ARENA_IMAGE (v->arenaitem), + gdk_pixbuf_get_pixels (image->pixbuf), + gdk_pixbuf_get_width (image->pixbuf), + gdk_pixbuf_get_height (image->pixbuf), + rs); + nr_arena_image_set_geometry (NR_ARENA_IMAGE (v->arenaitem), + image->x.computed, image->y.computed, + image->width.computed, image->height.computed); + } else { // preserveAspectRatio + nr_arena_image_set_pixels (NR_ARENA_IMAGE (v->arenaitem), + gdk_pixbuf_get_pixels (image->pixbuf) + image->trimx*pixskip + image->trimy*rs, + image->trimwidth, + image->trimheight, + rs); + nr_arena_image_set_geometry (NR_ARENA_IMAGE (v->arenaitem), + image->viewx, image->viewy, + image->viewwidth, image->viewheight); + } + } +} + +static void sp_image_snappoints(SPItem const *item, SnapPointsIter p) +{ + if (((SPItemClass *) parent_class)->snappoints) { + ((SPItemClass *) parent_class)->snappoints (item, p); + } +} + +/* + * Initially we'll do: + * Transform x, y, set x, y, clear translation + */ + +static NR::Matrix +sp_image_set_transform(SPItem *item, NR::Matrix const &xform) +{ + SPImage *image = SP_IMAGE(item); + + /* Calculate position in parent coords. */ + NR::Point pos( NR::Point(image->x.computed, image->y.computed) * xform ); + + /* This function takes care of translation and scaling, we return whatever parts we can't + handle. */ + NR::Matrix ret(NR::transform(xform)); + NR::Point const scale(hypot(ret[0], ret[1]), + hypot(ret[2], ret[3])); + if ( scale[NR::X] > 1e-9 ) { + ret[0] /= scale[NR::X]; + ret[1] /= scale[NR::X]; + } else { + ret[0] = 1.0; + ret[1] = 0.0; + } + if ( scale[NR::Y] > 1e-9 ) { + ret[2] /= scale[NR::Y]; + ret[3] /= scale[NR::Y]; + } else { + ret[2] = 0.0; + ret[3] = 1.0; + } + + image->width = image->width.computed * scale[NR::X]; + image->height = image->height.computed * scale[NR::Y]; + + /* Find position in item coords */ + pos = pos * ret.inverse(); + image->x = pos[NR::X]; + image->y = pos[NR::Y]; + + item->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + + return ret; +} + +static GdkPixbuf * +sp_image_repr_read_dataURI (const gchar * uri_data) +{ GdkPixbuf * pixbuf = NULL; + + gint data_is_image = 0; + gint data_is_base64 = 0; + + const gchar * data = uri_data; + + while (*data) { + if (strncmp (data,"base64",6) == 0) { + /* base64-encoding */ + data_is_base64 = 1; + data_is_image = 1; // Illustrator produces embedded images without MIME type, so we assume it's image no matter what + data += 6; + } + else if (strncmp (data,"image/png",9) == 0) { + /* PNG image */ + data_is_image = 1; + data += 9; + } + else if (strncmp (data,"image/jpg",9) == 0) { + /* JPEG image */ + data_is_image = 1; + data += 9; + } + else if (strncmp (data,"image/jpeg",10) == 0) { + /* JPEG image */ + data_is_image = 1; + data += 10; + } + else { /* unrecognized option; skip it */ + while (*data) { + if (((*data) == ';') || ((*data) == ',')) break; + data++; + } + } + if ((*data) == ';') { + data++; + continue; + } + if ((*data) == ',') { + data++; + break; + } + } + + if ((*data) && data_is_image && data_is_base64) { + pixbuf = sp_image_repr_read_b64 (data); + } + + return pixbuf; +} + +static GdkPixbuf * +sp_image_repr_read_b64 (const gchar * uri_data) +{ GdkPixbuf * pixbuf = NULL; + GdkPixbufLoader * loader = NULL; + + gint j; + gint k; + gint l; + gint b; + gint len; + gint eos = 0; + gint failed = 0; + + guint32 bits; + + static const gchar B64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + + const gchar* btr = uri_data; + + gchar ud[4]; + + guchar bd[57]; + + loader = gdk_pixbuf_loader_new (); + + if (loader == NULL) return NULL; + + while (eos == 0) { + l = 0; + for (j = 0; j < 19; j++) { + len = 0; + for (k = 0; k < 4; k++) { + while (isspace ((int) (*btr))) { + if ((*btr) == '\0') break; + btr++; + } + if (eos) { + ud[k] = 0; + continue; + } + if (((*btr) == '\0') || ((*btr) == '=')) { + eos = 1; + ud[k] = 0; + continue; + } + ud[k] = 64; + for (b = 0; b < 64; b++) { /* There must a faster way to do this... ?? */ + if (B64[b] == (*btr)) { + ud[k] = (gchar) b; + break; + } + } + if (ud[k] == 64) { /* data corruption ?? */ + eos = 1; + ud[k] = 0; + continue; + } + btr++; + len++; + } + bits = (guint32) ud[0]; + bits = (bits << 6) | (guint32) ud[1]; + bits = (bits << 6) | (guint32) ud[2]; + bits = (bits << 6) | (guint32) ud[3]; + bd[l++] = (guchar) ((bits & 0xff0000) >> 16); + if (len > 2) { + bd[l++] = (guchar) ((bits & 0xff00) >> 8); + } + if (len > 3) { + bd[l++] = (guchar) (bits & 0xff); + } + } + + if (!gdk_pixbuf_loader_write (loader, (const guchar *) bd, (size_t) l, NULL)) { + failed = 1; + break; + } + } + + gdk_pixbuf_loader_close (loader, NULL); + + if (!failed) pixbuf = gdk_pixbuf_loader_get_pixbuf (loader); + + return pixbuf; +} + +/* + 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 : diff --git a/src/sp-image.h b/src/sp-image.h new file mode 100644 index 000000000..500d9699e --- /dev/null +++ b/src/sp-image.h @@ -0,0 +1,60 @@ +#ifndef __SP_IMAGE_H__ +#define __SP_IMAGE_H__ + +/* + * SVG implementation + * + * Authors: + * Lauris Kaplinski + * Edward Flick (EAF) + * + * Copyright (C) 1999-2005 Authors + * Copyright (C) 2000-2001 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#define SP_TYPE_IMAGE (sp_image_get_type ()) +#define SP_IMAGE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SP_TYPE_IMAGE, SPImage)) +#define SP_IMAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SP_TYPE_IMAGE, SPImageClass)) +#define SP_IS_IMAGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_IMAGE)) +#define SP_IS_IMAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SP_TYPE_IMAGE)) + +class SPImage; +class SPImageClass; + +/* SPImage */ + +#include +#include "svg/svg-length.h" +#include "sp-item.h" + +#define SP_IMAGE_HREF_MODIFIED_FLAG SP_OBJECT_USER_MODIFIED_FLAG_A + +struct SPImage : public SPItem { + SVGLength x; + SVGLength y; + SVGLength width; + SVGLength height; + + // Added by EAF + /* preserveAspectRatio */ + unsigned int aspect_align : 4; + unsigned int aspect_clip : 1; + int trimx, trimy, trimwidth, trimheight; + double viewx, viewy, viewwidth, viewheight; + + gchar *href; + + GdkPixbuf *pixbuf; +}; + +struct SPImageClass { + SPItemClass parent_class; +}; + +GType sp_image_get_type (void); + + + +#endif diff --git a/src/sp-item-group.cpp b/src/sp-item-group.cpp new file mode 100644 index 000000000..c093c569b --- /dev/null +++ b/src/sp-item-group.cpp @@ -0,0 +1,699 @@ +#define __SP_GROUP_C__ + +/* + * SVG implementation + * + * Authors: + * Lauris Kaplinski + * bulia byak + * + * Copyright (C) 1999-2005 authors + * Copyright (C) 2000-2001 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#if defined(WIN32) || defined(__APPLE__) +# include +#endif + +#include "display/nr-arena-group.h" +#include "libnr/nr-matrix-ops.h" +#include "libnr/nr-matrix-fns.h" +#include "xml/repr.h" +#include "svg/svg.h" +#include "document.h" +#include "style.h" +#include "attributes.h" + +#include "sp-root.h" +#include "sp-use.h" +#include "prefs-utils.h" + +static void sp_group_class_init (SPGroupClass *klass); +static void sp_group_init (SPGroup *group); +static void sp_group_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr); +static void sp_group_release(SPObject *object); +static void sp_group_dispose (GObject *object); + +static void sp_group_child_added (SPObject * object, Inkscape::XML::Node * child, Inkscape::XML::Node * ref); +static void sp_group_remove_child (SPObject * object, Inkscape::XML::Node * child); +static void sp_group_order_changed (SPObject * object, Inkscape::XML::Node * child, Inkscape::XML::Node * old_ref, Inkscape::XML::Node * new_ref); +static void sp_group_update (SPObject *object, SPCtx *ctx, guint flags); +static void sp_group_modified (SPObject *object, guint flags); +static Inkscape::XML::Node *sp_group_write (SPObject *object, Inkscape::XML::Node *repr, guint flags); +static void sp_group_set(SPObject *object, unsigned key, char const *value); + +static void sp_group_bbox(SPItem const *item, NRRect *bbox, NR::Matrix const &transform, unsigned const flags); +static void sp_group_print (SPItem * item, SPPrintContext *ctx); +static gchar * sp_group_description (SPItem * item); +static NRArenaItem *sp_group_show (SPItem *item, NRArena *arena, unsigned int key, unsigned int flags); +static void sp_group_hide (SPItem * item, unsigned int key); +static void sp_group_snappoints (SPItem const *item, SnapPointsIter p); + +static SPItemClass * parent_class; + +GType +sp_group_get_type (void) +{ + static GType group_type = 0; + if (!group_type) { + GTypeInfo group_info = { + sizeof (SPGroupClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) sp_group_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (SPGroup), + 16, /* n_preallocs */ + (GInstanceInitFunc) sp_group_init, + NULL, /* value_table */ + }; + group_type = g_type_register_static (SP_TYPE_ITEM, "SPGroup", &group_info, (GTypeFlags)0); + } + return group_type; +} + +static void +sp_group_class_init (SPGroupClass *klass) +{ + GObjectClass * object_class; + SPObjectClass * sp_object_class; + SPItemClass * item_class; + + object_class = (GObjectClass *) klass; + sp_object_class = (SPObjectClass *) klass; + item_class = (SPItemClass *) klass; + + parent_class = (SPItemClass *)g_type_class_ref (SP_TYPE_ITEM); + + object_class->dispose = sp_group_dispose; + + sp_object_class->child_added = sp_group_child_added; + sp_object_class->remove_child = sp_group_remove_child; + sp_object_class->order_changed = sp_group_order_changed; + sp_object_class->update = sp_group_update; + sp_object_class->modified = sp_group_modified; + sp_object_class->set = sp_group_set; + sp_object_class->write = sp_group_write; + sp_object_class->release = sp_group_release; + sp_object_class->build = sp_group_build; + + item_class->bbox = sp_group_bbox; + item_class->print = sp_group_print; + item_class->description = sp_group_description; + item_class->show = sp_group_show; + item_class->hide = sp_group_hide; + item_class->snappoints = sp_group_snappoints; +} + +static void +sp_group_init (SPGroup *group) +{ + group->_layer_mode = SPGroup::GROUP; + new (&group->_display_modes) std::map(); +} + +static void sp_group_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr) +{ + sp_object_read_attr(object, "inkscape:groupmode"); + + if (((SPObjectClass *)parent_class)->build) { + ((SPObjectClass *)parent_class)->build(object, document, repr); + } +} + +static void sp_group_release(SPObject *object) { + if ( SP_GROUP(object)->_layer_mode == SPGroup::LAYER ) { + sp_document_remove_resource(SP_OBJECT_DOCUMENT(object), "layer", object); + } + if (((SPObjectClass *)parent_class)->release) { + ((SPObjectClass *)parent_class)->release(object); + } +} + +static void +sp_group_dispose(GObject *object) +{ + SP_GROUP(object)->_display_modes.~map(); +} + +static void +sp_group_child_added (SPObject *object, Inkscape::XML::Node *child, Inkscape::XML::Node *ref) +{ + SPItem *item; + + item = SP_ITEM (object); + + if (((SPObjectClass *) (parent_class))->child_added) + (* ((SPObjectClass *) (parent_class))->child_added) (object, child, ref); + + SPObject *last_child = object->lastChild(); + if (last_child && SP_OBJECT_REPR(last_child) == child) { + // optimization for the common special case where the child is being added at the end + SPObject *ochild = last_child; + if ( SP_IS_ITEM(ochild) ) { + /* TODO: this should be moved into SPItem somehow */ + SPItemView *v; + NRArenaItem *ac; + + for (v = item->display; v != NULL; v = v->next) { + ac = sp_item_invoke_show (SP_ITEM (ochild), NR_ARENA_ITEM_ARENA (v->arenaitem), v->key, v->flags); + + if (ac) { + nr_arena_item_append_child (v->arenaitem, ac); + nr_arena_item_unref (ac); + } + } + } + } else { // general case + SPObject *ochild = sp_object_get_child_by_repr(object, child); + if ( ochild && SP_IS_ITEM(ochild) ) { + /* TODO: this should be moved into SPItem somehow */ + SPItemView *v; + NRArenaItem *ac; + + unsigned position = sp_item_pos_in_parent(SP_ITEM(ochild)); + + for (v = item->display; v != NULL; v = v->next) { + ac = sp_item_invoke_show (SP_ITEM (ochild), NR_ARENA_ITEM_ARENA (v->arenaitem), v->key, v->flags); + + if (ac) { + nr_arena_item_add_child (v->arenaitem, ac, NULL); + nr_arena_item_set_order (ac, position); + nr_arena_item_unref (ac); + } + } + } + } + + object->requestModified(SP_OBJECT_MODIFIED_FLAG); +} + +/* fixme: hide (Lauris) */ + +static void +sp_group_remove_child (SPObject * object, Inkscape::XML::Node * child) +{ + if (((SPObjectClass *) (parent_class))->remove_child) + (* ((SPObjectClass *) (parent_class))->remove_child) (object, child); + + object->requestModified(SP_OBJECT_MODIFIED_FLAG); +} + +static void +sp_group_order_changed (SPObject *object, Inkscape::XML::Node *child, Inkscape::XML::Node *old_ref, Inkscape::XML::Node *new_ref) +{ + if (((SPObjectClass *) (parent_class))->order_changed) + (* ((SPObjectClass *) (parent_class))->order_changed) (object, child, old_ref, new_ref); + + SPObject *ochild = sp_object_get_child_by_repr(object, child); + if ( ochild && SP_IS_ITEM(ochild) ) { + /* TODO: this should be moved into SPItem somehow */ + SPItemView *v; + unsigned position = sp_item_pos_in_parent(SP_ITEM(ochild)); + for ( v = SP_ITEM (ochild)->display ; v != NULL ; v = v->next ) { + nr_arena_item_set_order (v->arenaitem, position); + } + } + + object->requestModified(SP_OBJECT_MODIFIED_FLAG); +} + +static void +sp_group_update (SPObject *object, SPCtx *ctx, unsigned int flags) +{ + SPGroup *group; + SPObject *child; + SPItemCtx *ictx, cctx; + GSList *l; + + group = SP_GROUP (object); + ictx = (SPItemCtx *) ctx; + cctx = *ictx; + + if (((SPObjectClass *) (parent_class))->update) + ((SPObjectClass *) (parent_class))->update (object, ctx, flags); + + if (flags & SP_OBJECT_MODIFIED_FLAG) flags |= SP_OBJECT_PARENT_MODIFIED_FLAG; + flags &= SP_OBJECT_MODIFIED_CASCADE; + + l = NULL; + for (child = sp_object_first_child(object) ; child != NULL ; child = SP_OBJECT_NEXT(child) ) { + g_object_ref (G_OBJECT (child)); + l = g_slist_prepend (l, child); + } + l = g_slist_reverse (l); + while (l) { + child = SP_OBJECT (l->data); + l = g_slist_remove (l, child); + if (flags || (child->uflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { + if (SP_IS_ITEM (child)) { + SPItem const &chi = *SP_ITEM(child); + cctx.i2doc = chi.transform * ictx->i2doc; + cctx.i2vp = chi.transform * ictx->i2vp; + child->updateDisplay((SPCtx *)&cctx, flags); + } else { + child->updateDisplay(ctx, flags); + } + } + g_object_unref (G_OBJECT (child)); + } +} + +static void +sp_group_modified (SPObject *object, guint flags) +{ + SPGroup *group; + SPObject *child; + GSList *l; + + group = SP_GROUP (object); + + if (flags & SP_OBJECT_MODIFIED_FLAG) flags |= SP_OBJECT_PARENT_MODIFIED_FLAG; + flags &= SP_OBJECT_MODIFIED_CASCADE; + + l = NULL; + for (child = sp_object_first_child(object) ; child != NULL ; child = SP_OBJECT_NEXT(child) ) { + g_object_ref (G_OBJECT (child)); + l = g_slist_prepend (l, child); + } + l = g_slist_reverse (l); + while (l) { + child = SP_OBJECT (l->data); + l = g_slist_remove (l, child); + if (flags || (child->mflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { + child->emitModified(flags); + } + g_object_unref (G_OBJECT (child)); + } +} + +static Inkscape::XML::Node * +sp_group_write (SPObject *object, Inkscape::XML::Node *repr, guint flags) +{ + SPGroup *group; + SPObject *child; + Inkscape::XML::Node *crepr; + + group = SP_GROUP (object); + + if (flags & SP_OBJECT_WRITE_BUILD) { + GSList *l; + if (!repr) repr = sp_repr_new ("svg:g"); + l = NULL; + for (child = sp_object_first_child(object); child != NULL; child = SP_OBJECT_NEXT(child) ) { + crepr = child->updateRepr(NULL, flags); + if (crepr) l = g_slist_prepend (l, crepr); + } + while (l) { + repr->addChild((Inkscape::XML::Node *) l->data, NULL); + Inkscape::GC::release((Inkscape::XML::Node *) l->data); + l = g_slist_remove (l, l->data); + } + } else { + for (child = sp_object_first_child(object) ; child != NULL; child = SP_OBJECT_NEXT(child) ) { + child->updateRepr(flags); + } + } + + if ( flags & SP_OBJECT_WRITE_EXT ) { + const char *value; + if ( group->_layer_mode == SPGroup::LAYER ) { + value = "layer"; + } else if ( flags & SP_OBJECT_WRITE_ALL ) { + value = "group"; + } else { + value = NULL; + } + repr->setAttribute("inkscape:groupmode", value); + } + + if (((SPObjectClass *) (parent_class))->write) + ((SPObjectClass *) (parent_class))->write (object, repr, flags); + + return repr; +} + +static void +sp_group_bbox(SPItem const *item, NRRect *bbox, NR::Matrix const &transform, unsigned const flags) +{ + for (SPObject *o = sp_object_first_child(SP_OBJECT(item)); o != NULL; o = SP_OBJECT_NEXT(o)) { + if (SP_IS_ITEM(o)) { + SPItem *child = SP_ITEM(o); + NR::Matrix const ct(child->transform * transform); + sp_item_invoke_bbox_full(child, bbox, ct, flags, FALSE); + } + } +} + +static void +sp_group_print (SPItem * item, SPPrintContext *ctx) +{ + SPGroup * group; + SPItem * child; + SPObject * o; + + group = SP_GROUP (item); + + for (o = sp_object_first_child(SP_OBJECT(item)) ; o != NULL ; o = SP_OBJECT_NEXT(o) ) { + if (SP_IS_ITEM (o)) { + child = SP_ITEM (o); + sp_item_invoke_print (SP_ITEM (o), ctx); + } + } +} + +static gchar * sp_group_description (SPItem * item) +{ + SPGroup * group; + SPObject * o; + gint len; + + group = SP_GROUP (item); + + len = 0; + for ( o = sp_object_first_child(SP_OBJECT(item)) ; o != NULL ; o = SP_OBJECT_NEXT(o) ) { + if (SP_IS_ITEM(o)) { + len += 1; + } + } + + return g_strdup_printf( + ngettext("Group of %d object", + "Group of %d objects", + len), len); +} + +static void sp_group_set(SPObject *object, unsigned key, char const *value) { + SPGroup *group=SP_GROUP(object); + + switch (key) { + case SP_ATTR_INKSCAPE_GROUPMODE: { + if ( value && !strcmp(value, "layer") ) { + group->setLayerMode(SPGroup::LAYER); + } else { + group->setLayerMode(SPGroup::GROUP); + } + } break; + default: { + if (((SPObjectClass *) (parent_class))->set) { + (* ((SPObjectClass *) (parent_class))->set)(object, key, value); + } + } + } +} + +static NRArenaItem * +sp_group_show (SPItem *item, NRArena *arena, unsigned int key, unsigned int flags) +{ + SPGroup *group; + NRArenaItem *ai, *ac, *ar; + SPItem * child; + SPObject * o; + + group = (SPGroup *) item; + + ai = NRArenaGroup::create(arena); + nr_arena_group_set_transparent(NR_ARENA_GROUP (ai), + group->effectiveLayerMode(key) == + SPGroup::LAYER); + + ar = NULL; + + for (o = sp_object_first_child(SP_OBJECT(item)) ; o != NULL; o = SP_OBJECT_NEXT(o) ) { + if (SP_IS_ITEM (o)) { + child = SP_ITEM (o); + ac = sp_item_invoke_show (child, arena, key, flags); + if (ac) { + nr_arena_item_add_child (ai, ac, ar); + ar = ac; + nr_arena_item_unref (ac); + } + } + } + + return ai; +} + +static void +sp_group_hide (SPItem *item, unsigned int key) +{ + SPGroup * group; + SPItem * child; + SPObject * o; + + group = (SPGroup *) item; + + for (o = sp_object_first_child(SP_OBJECT(item)) ; o != NULL; o = SP_OBJECT_NEXT(o) ) { + if (SP_IS_ITEM (o)) { + child = SP_ITEM (o); + sp_item_invoke_hide (child, key); + } + } + + if (((SPItemClass *) parent_class)->hide) + ((SPItemClass *) parent_class)->hide (item, key); +} + +static void sp_group_snappoints (SPItem const *item, SnapPointsIter p) +{ + for (SPObject const *o = sp_object_first_child(SP_OBJECT(item)); + o != NULL; + o = SP_OBJECT_NEXT(o)) + { + if (SP_IS_ITEM(o)) { + sp_item_snappoints(SP_ITEM(o), p); + } + } +} + + +void +sp_item_group_ungroup (SPGroup *group, GSList **children, bool do_done) +{ + g_return_if_fail (group != NULL); + g_return_if_fail (SP_IS_GROUP (group)); + + SPDocument *doc = SP_OBJECT_DOCUMENT (group); + SPObject *root = SP_DOCUMENT_ROOT (doc); + SPObject *defs = SP_OBJECT (SP_ROOT (root)->defs); + + SPItem *gitem = SP_ITEM (group); + Inkscape::XML::Node *grepr = SP_OBJECT_REPR (gitem); + + g_return_if_fail (!strcmp (grepr->name(), "svg:g") || !strcmp (grepr->name(), "svg:a") || !strcmp (grepr->name(), "svg:switch")); + + // this converts the gradient/pattern fill/stroke on the group, if any, to userSpaceOnUse + sp_item_adjust_paint_recursive (gitem, NR::identity(), NR::identity(), false); + + SPItem *pitem = SP_ITEM (SP_OBJECT_PARENT (gitem)); + Inkscape::XML::Node *prepr = SP_OBJECT_REPR (pitem); + + /* Step 1 - generate lists of children objects */ + GSList *items = NULL; + GSList *objects = NULL; + for (SPObject *child = sp_object_first_child(SP_OBJECT(group)) ; child != NULL; child = SP_OBJECT_NEXT(child) ) { + + if (SP_IS_ITEM (child)) { + + SPItem *citem = SP_ITEM (child); + + /* Merging of style */ + // this converts the gradient/pattern fill/stroke, if any, to userSpaceOnUse; we need to do + // it here _before_ the new transform is set, so as to use the pre-transform bbox + sp_item_adjust_paint_recursive (citem, NR::identity(), NR::identity(), false); + + sp_style_merge_from_dying_parent(SP_OBJECT_STYLE(child), SP_OBJECT_STYLE(gitem)); + /* + * fixme: We currently make no allowance for the case where child is cloned + * and the group has any style settings. + * + * (This should never occur with documents created solely with the current + * version of inkscape without using the XML editor: we usually apply group + * style changes to children rather than to the group itself.) + * + * If the group has no style settings, then + * sp_style_merge_from_dying_parent should be a no-op. Otherwise (i.e. if + * we change the child's style to compensate for its parent going away) + * then those changes will typically be reflected in any clones of child, + * whereas we'd prefer for Ungroup not to affect the visual appearance. + * + * The only way of preserving styling appearance in general is for child to + * be put into a new group -- a somewhat surprising response to an Ungroup + * command. We could add a new groupmode:transparent that would mostly + * hide the existence of such groups from the user (i.e. editing behaves as + * if the transparent group's children weren't in a group), though that's + * extra complication & maintenance burden and this case is rare. + */ + + child->updateRepr(); + + Inkscape::XML::Node *nrepr = SP_OBJECT_REPR (child)->duplicate(); + + // Merging transform + NR::Matrix ctrans; + NR::Matrix const g(gitem->transform); + if (SP_IS_USE(citem) && sp_use_get_original (SP_USE(citem)) && + SP_OBJECT_PARENT (sp_use_get_original (SP_USE(citem))) == SP_OBJECT(group)) { + // make sure a clone's effective transform is the same as was under group + ctrans = g.inverse() * citem->transform * g; + } else { + ctrans = citem->transform * g; + } + + // FIXME: constructing a transform that would fully preserve the appearance of a + // textpath if it is ungrouped with its path seems to be impossible in general + // case. E.g. if the group was squeezed, to keep the ungrouped textpath squeezed + // as well, we'll need to relink it to some "virtual" path which is inversely + // stretched relative to the actual path, and then squeeze the textpath back so it + // would both fit the actual path _and_ be squeezed as before. It's a bummer. + + // This is just a way to temporarily remember the transform in repr. When repr is + // reattached outside of the group, the transform will be written more properly + // (i.e. optimized into the object if the corresponding preference is set) + gchar affinestr[80]; + if (sp_svg_transform_write(affinestr, 79, ctrans)) { + nrepr->setAttribute("transform", affinestr); + } else { + nrepr->setAttribute("transform", NULL); + } + + items = g_slist_prepend (items, nrepr); + + } else { + Inkscape::XML::Node *nrepr = SP_OBJECT_REPR (child)->duplicate(); + objects = g_slist_prepend (objects, nrepr); + } + } + + /* Step 2 - clear group */ + // remember the position of the group + gint pos = SP_OBJECT_REPR(group)->position(); + + // the group is leaving forever, no heir, clones should take note; its children however are going to reemerge + SP_OBJECT (group)->deleteObject(true, false); + + /* Step 3 - add nonitems */ + if (objects) { + Inkscape::XML::Node *last_def = SP_OBJECT_REPR(defs)->lastChild(); + while (objects) { + SP_OBJECT_REPR(defs)->addChild((Inkscape::XML::Node *) objects->data, last_def); + Inkscape::GC::release((Inkscape::XML::Node *) objects->data); + objects = g_slist_remove (objects, objects->data); + } + } + + /* Step 4 - add items */ + gint const preserve = prefs_get_int_attribute("options.preservetransform", "value", 0); + while (items) { + Inkscape::XML::Node *repr = (Inkscape::XML::Node *) items->data; + // add item + prepr->appendChild(repr); + // restore position; since the items list was prepended (i.e. reverse), we now add + // all children at the same pos, which inverts the order once again + repr->setPosition(pos > 0 ? pos : 0); + + // fill in the children list if non-null + SPItem *nitem = (SPItem *) doc->getObjectByRepr(repr); + + /* Optimize the transform matrix if requested. */ + // No compensations are required because this is supposed to be a non-transformation visually. + if (!preserve) { + NR::Matrix (*set_transform)(SPItem *, NR::Matrix const &) = ((SPItemClass *) G_OBJECT_GET_CLASS(nitem))->set_transform; + if (set_transform) { + sp_item_set_item_transform(nitem, set_transform(nitem, nitem->transform)); + nitem->updateRepr(); + } + } + + Inkscape::GC::release(repr); + if (children && SP_IS_ITEM (nitem)) + *children = g_slist_prepend (*children, nitem); + + items = g_slist_remove (items, items->data); + } + + if (do_done) sp_document_done (doc); +} + +/* + * some API for list aspect of SPGroup + */ + +GSList * +sp_item_group_item_list (SPGroup * group) +{ + GSList *s; + SPObject *o; + + g_return_val_if_fail (group != NULL, NULL); + g_return_val_if_fail (SP_IS_GROUP (group), NULL); + + s = NULL; + + for ( o = sp_object_first_child(SP_OBJECT(group)) ; o != NULL ; o = SP_OBJECT_NEXT(o) ) { + if (SP_IS_ITEM (o)) { + s = g_slist_prepend (s, o); + } + } + + return g_slist_reverse (s); +} + +SPObject * +sp_item_group_get_child_by_name (SPGroup *group, SPObject *ref, const gchar *name) +{ + SPObject *child; + child = (ref) ? SP_OBJECT_NEXT(ref) : sp_object_first_child(SP_OBJECT(group)); + while ( child && strcmp (SP_OBJECT_REPR(child)->name(), name) ) { + child = SP_OBJECT_NEXT(child); + } + return child; +} + +void SPGroup::setLayerMode(LayerMode mode) { + if ( _layer_mode != mode ) { + if ( mode == LAYER ) { + sp_document_add_resource(SP_OBJECT_DOCUMENT(this), "layer", this); + } else { + sp_document_remove_resource(SP_OBJECT_DOCUMENT(this), "layer", this); + } + _layer_mode = mode; + _updateLayerMode(); + } +} + +SPGroup::LayerMode SPGroup::layerDisplayMode(unsigned int dkey) const { + std::map::const_iterator iter; + iter = _display_modes.find(dkey); + if ( iter != _display_modes.end() ) { + return (*iter).second; + } else { + return GROUP; + } +} + +void SPGroup::setLayerDisplayMode(unsigned int dkey, SPGroup::LayerMode mode) { + if ( layerDisplayMode(dkey) != mode ) { + _display_modes[dkey] = mode; + _updateLayerMode(dkey); + } +} + +void SPGroup::_updateLayerMode(unsigned int display_key) { + SPItemView *view; + for ( view = this->display ; view ; view = view->next ) { + if ( !display_key || view->key == display_key ) { + NRArenaGroup *arena_group=NR_ARENA_GROUP(view->arenaitem); + if (arena_group) { + nr_arena_group_set_transparent(arena_group, effectiveLayerMode(view->key) == SPGroup::LAYER); + } + } + } +} diff --git a/src/sp-item-group.h b/src/sp-item-group.h new file mode 100644 index 000000000..578454c92 --- /dev/null +++ b/src/sp-item-group.h @@ -0,0 +1,61 @@ +#ifndef __SP_ITEM_GROUP_H__ +#define __SP_ITEM_GROUP_H__ + +/* + * SVG implementation + * + * Authors: + * Lauris Kaplinski + * + * Copyright (C) 1999-2002 authors + * Copyright (C) 2000-2001 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include +#include "sp-item.h" + +#define SP_TYPE_GROUP (sp_group_get_type ()) +#define SP_GROUP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SP_TYPE_GROUP, SPGroup)) +#define SP_GROUP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SP_TYPE_GROUP, SPGroupClass)) +#define SP_IS_GROUP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_GROUP)) +#define SP_IS_GROUP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SP_TYPE_GROUP)) + +struct SPGroup : public SPItem { + enum LayerMode { GROUP, LAYER }; + + LayerMode _layer_mode; + std::map _display_modes; + + LayerMode layerMode() const { return _layer_mode; } + void setLayerMode(LayerMode mode); + + LayerMode effectiveLayerMode(unsigned int display_key) const { + if ( _layer_mode == LAYER ) { + return LAYER; + } else { + return layerDisplayMode(display_key); + } + } + + LayerMode layerDisplayMode(unsigned int display_key) const; + void setLayerDisplayMode(unsigned int display_key, LayerMode mode); + +private: + void _updateLayerMode(unsigned int display_key=0); +}; + +struct SPGroupClass { + SPItemClass parent_class; +}; + +GType sp_group_get_type (void); + +void sp_item_group_ungroup (SPGroup *group, GSList **children, bool do_done = true); + + +GSList *sp_item_group_item_list (SPGroup *group); +SPObject *sp_item_group_get_child_by_name (SPGroup *group, SPObject *ref, const gchar *name); + +#endif diff --git a/src/sp-item-notify-moveto.cpp b/src/sp-item-notify-moveto.cpp new file mode 100644 index 000000000..c84792215 --- /dev/null +++ b/src/sp-item-notify-moveto.cpp @@ -0,0 +1,76 @@ +/** \file + * Implementation of sp_item_notify_moveto(). + */ + +#include +#include +#include +#include +using std::vector; + + +/** + * Called by sp_guide_moveto to indicate that the guide line corresponding to g has been moved, and + * that consequently this item should move with it. + * + * \pre exist [cn in item.constraints] g eq cn.g. + */ +void sp_item_notify_moveto(SPItem &item, SPGuide const &mv_g, int const snappoint_ix, + double const position, bool const commit) +{ + g_return_if_fail(SP_IS_ITEM(&item)); + g_return_if_fail( unsigned(snappoint_ix) < 8 ); + NR::Point const dir( mv_g.normal ); + double const dir_lensq(dot(dir, dir)); + g_return_if_fail( dir_lensq != 0 ); + + vector snappoints; + sp_item_snappoints(&item, SnapPointsIter(snappoints)); + g_return_if_fail( snappoint_ix < int(snappoints.size()) ); + + double const pos0 = dot(dir, snappoints[snappoint_ix]); + /// \todo effic: skip if mv_g is already satisfied. + + /* Translate along dir to make dot(dir, snappoints(item)[snappoint_ix]) == position. */ + + /* Calculation: + dot(dir, snappoints[snappoint_ix] + s * dir) = position. + dot(dir, snappoints[snappoint_ix]) + dot(dir, s * dir) = position. + pos0 + s * dot(dir, dir) = position. + s * lensq(dir) = position - pos0. + s = (position - pos0) / dot(dir, dir). */ + NR::translate const tr( ( position - pos0 ) + * ( dir / dir_lensq ) ); + sp_item_set_i2d_affine(&item, sp_item_i2d_affine(&item) * tr); + /// \todo Reget snappoints, check satisfied. + + if (commit) { + /// \todo Consider maintaining a set of dirty items. + + /* Commit repr. */ + { + sp_item_write_transform(&item, SP_OBJECT_REPR(&item), item.transform); + } + + sp_item_rm_unsatisfied_cns(item); +#if 0 /* nyi */ + move_cn_to_front(mv_g, snappoint_ix, item.constraints); + /** \note If the guideline is connected to multiple snappoints of + * this item, then keeping those cns in order requires that the + * guide send notifications in order of increasing importance. + */ +#endif + } +} + + +/* + 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:textwidth=99 : diff --git a/src/sp-item-notify-moveto.h b/src/sp-item-notify-moveto.h new file mode 100644 index 000000000..41bd9ef21 --- /dev/null +++ b/src/sp-item-notify-moveto.h @@ -0,0 +1,22 @@ +#ifndef __SP_ITEM_NOTIFY_MOVETO_H__ +#define __SP_ITEM_NOTIFY_MOVETO_H__ + +#include + +void sp_item_notify_moveto(SPItem &item, SPGuide const &g, int const snappoint_ix, + double position, bool const commit); + + +#endif /* !__SP_ITEM_NOTIFY_MOVETO_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:encoding=utf-8:textwidth=99 : diff --git a/src/sp-item-rm-unsatisfied-cns.cpp b/src/sp-item-rm-unsatisfied-cns.cpp new file mode 100644 index 000000000..d71c6fe0c --- /dev/null +++ b/src/sp-item-rm-unsatisfied-cns.cpp @@ -0,0 +1,40 @@ + +#include +#include +#include +#include +#include +using std::vector; + +void sp_item_rm_unsatisfied_cns(SPItem &item) +{ + if (item.constraints.empty()) { + return; + } + vector snappoints; + sp_item_snappoints(&item, SnapPointsIter(snappoints)); + for (unsigned i = item.constraints.size(); i--;) { + g_assert( i < item.constraints.size() ); + SPGuideConstraint const &cn = item.constraints[i]; + int const snappoint_ix = cn.snappoint_ix; + g_assert( snappoint_ix < int(snappoints.size()) ); + if (!approx_equal(dot(cn.g->normal, snappoints[snappoint_ix]), cn.g->position)) { + remove_last(cn.g->attached_items, SPGuideAttachment(&item, cn.snappoint_ix)); + g_assert( i < item.constraints.size() ); + vector::iterator const ei(&item.constraints[i]); + item.constraints.erase(ei); + } + } +} + + +/* + 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:textwidth=99 : diff --git a/src/sp-item-rm-unsatisfied-cns.h b/src/sp-item-rm-unsatisfied-cns.h new file mode 100644 index 000000000..72a6e0c66 --- /dev/null +++ b/src/sp-item-rm-unsatisfied-cns.h @@ -0,0 +1,19 @@ +#ifndef __SP_ITEM_RM_UNSATISFIED_CNS_H__ +#define __SP_ITEM_RM_UNSATISFIED_CNS_H__ +#include + +void sp_item_rm_unsatisfied_cns(SPItem &item); + + +#endif /* !__SP_ITEM_RM_UNSATISFIED_CNS_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:encoding=utf-8:textwidth=99 : diff --git a/src/sp-item-transform.cpp b/src/sp-item-transform.cpp new file mode 100644 index 000000000..817bc1b44 --- /dev/null +++ b/src/sp-item-transform.cpp @@ -0,0 +1,148 @@ +#define __SP_ITEM_TRANSFORM_C__ + +/* + * Transforming single items + * + * Authors: + * Lauris Kaplinski + * Frank Felfe + * bulia byak + * + * Copyright (C) 1999-2005 authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include +#include "libnr/nr-matrix-rotate-ops.h" +#include "libnr/nr-matrix-scale-ops.h" +#include "libnr/nr-matrix-translate-ops.h" +#include "sp-item.h" + +static NR::translate inverse(NR::translate const m) +{ + /* TODO: Move this to nr-matrix-fns.h or the like. */ + return NR::translate(-m[0], -m[1]); +} + +void +sp_item_rotate_rel(SPItem *item, NR::rotate const &rotation) +{ + NR::translate const s(sp_item_bbox_desktop(item).midpoint()); + + // Rotate item. + sp_item_set_i2d_affine(item, + sp_item_i2d_affine(item) * inverse(s) * rotation * s); + + // Use each item's own transform writer, consistent with sp_selection_apply_affine() + sp_item_write_transform(item, SP_OBJECT_REPR(item), item->transform); +} + +void +sp_item_scale_rel (SPItem *item, NR::scale const &scale) +{ + NR::translate const s(sp_item_bbox_desktop(item).midpoint()); + + sp_item_set_i2d_affine(item, + sp_item_i2d_affine(item) * inverse(s) * scale * s); + sp_item_write_transform(item, SP_OBJECT_REPR(item), item->transform); +} + +void +sp_item_skew_rel (SPItem *item, double skewX, double skewY) +{ + NR::Rect bbox(sp_item_bbox_desktop(item)); + + NR::translate const s(bbox.midpoint()); + + NR::Matrix const skew(1, skewY, skewX, 1, 0, 0); + + sp_item_set_i2d_affine(item, + sp_item_i2d_affine(item) * inverse(s) * skew * s); + sp_item_write_transform(item, SP_OBJECT_REPR(item), item->transform); +} + +void sp_item_move_rel(SPItem *item, NR::translate const &tr) +{ + sp_item_set_i2d_affine(item, sp_item_i2d_affine(item) * tr); + + sp_item_write_transform(item, SP_OBJECT_REPR(item), item->transform); +} + +/* +** Returns the matrix you need to apply to an object with given bbox and strokewidth to +scale/move it to the new box x0/y0/x1/y1. Takes into account the "scale stroke" +preference value passed to it. Has to solve a quadratic equation to make sure +the goal is met exactly and the stroke scaling is obeyed. +*/ + +NR::Matrix +get_scale_transform_with_stroke (NR::Rect &bbox_param, gdouble strokewidth, bool transform_stroke, gdouble x0, gdouble y0, gdouble x1, gdouble y1) +{ + NR::Rect bbox (bbox_param); + + NR::Matrix p2o = NR::Matrix (NR::translate (-bbox.min())); + NR::Matrix o2n = NR::Matrix (NR::translate (x0, y0)); + + NR::Matrix scale = NR::Matrix (NR::scale (1, 1)); // scale component + NR::Matrix unbudge = NR::Matrix (NR::translate (0, 0)); // move component to compensate for the drift caused by stroke width change + + gdouble w0 = bbox.extent(NR::X); + gdouble h0 = bbox.extent(NR::Y); + gdouble w1 = x1 - x0; + gdouble h1 = y1 - y0; + gdouble r0 = strokewidth; + + if (bbox.isEmpty() || bbox.extent(NR::X) < 1e-06 || bbox.extent(NR::Y) < 1e-06 || + fabs(w0 - r0) < 1e-6 || fabs(h0 - r0) < 1e-6 || + (!transform_stroke && (fabs(w1 - r0) < 1e-6 || fabs(h1 - r0) < 1e-6)) + ) { + NR::Matrix move = NR::Matrix(NR::translate(x0 - bbox.min()[NR::X], y0 - bbox.min()[NR::Y])); + return (move); // sorry, cannot scale from or to empty boxes, so only translate + } + + NR::Matrix direct = NR::Matrix (NR::scale(w1 / w0, h1 / h0)); + gdouble ratio_x = (w1 - r0) / (w0 - r0); + gdouble ratio_y = (h1 - r0) / (h0 - r0); + NR::Matrix direct_constant_r = NR::Matrix (NR::scale(ratio_x, ratio_y)); + + if (transform_stroke && r0 != 0 && r0 != NR_HUGE) { // there's stroke, and we need to scale it + // These coefficients are obtained from the assumption that scaling applies to the + // non-stroked "shape proper" and that stroke scale is scaled by the expansion of that + // matrix + gdouble A = -(w0 *h0) + r0*(w0 + h0); + gdouble B = -(w1 + h1) * r0*r0; + gdouble C = w1 * h1 * r0*r0; + if (B*B - 4*A*C > 0) { + gdouble r1 = (-B - sqrt (B*B - 4*A*C))/(2*A); + //gdouble r2 = (-B + sqrt (B*B - 4*A*C))/(2*A); + //std::cout << "r0" << r0 << " r1" << r1 << " r2" << r2 << "\n"; + gdouble scale_x = (w1 - r1)/(w0 - r0); + gdouble scale_y = (h1 - r1)/(h0 - r0); + scale *= NR::scale(scale_x, scale_y); + unbudge *= NR::translate (-0.5 * (r0 * scale_x - r1), -0.5 * (r0 * scale_y - r1)); + } else { + scale *= direct; + } + } else { + if (r0 == 0 || r0 == NR_HUGE) { // no stroke to scale + scale *= direct; + } else {// nonscaling strokewidth + scale *= direct_constant_r; + unbudge *= NR::translate (0.5 * r0 * (1 - ratio_x), 0.5 * r0 * (1 - ratio_y)); + } + } + + return (p2o * scale * unbudge * o2n); +} + +/* + 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:textwidth=99 : diff --git a/src/sp-item-transform.h b/src/sp-item-transform.h new file mode 100644 index 000000000..23d96987f --- /dev/null +++ b/src/sp-item-transform.h @@ -0,0 +1,29 @@ +#ifndef SP_ITEM_TRANSFORM_H +#define SP_ITEM_TRANSFORM_H + +#include "forward.h" +namespace NR { +class translate; +class rotate; +class Rect; +} + +void sp_item_rotate_rel(SPItem *item, NR::rotate const &rotation); +void sp_item_scale_rel (SPItem *item, NR::scale const &scale); +void sp_item_skew_rel (SPItem *item, double skewX, double skewY); +void sp_item_move_rel(SPItem *item, NR::translate const &tr); + +NR::Matrix get_scale_transform_with_stroke (NR::Rect &bbox, gdouble strokewidth, bool transform_stroke, gdouble x0, gdouble y0, gdouble x1, gdouble y1); + +#endif /* !SP_ITEM_TRANSFORM_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:encoding=utf-8:textwidth=99 : diff --git a/src/sp-item-update-cns.cpp b/src/sp-item-update-cns.cpp new file mode 100644 index 000000000..e1857dcca --- /dev/null +++ b/src/sp-item-update-cns.cpp @@ -0,0 +1,45 @@ + +#include "satisfied-guide-cns.h" +#include "sp-guide-constraint.h" +#include +#include +using std::find; +using std::vector; + +void sp_item_update_cns(SPItem &item, SPDesktop const &desktop) +{ + vector snappoints; + sp_item_snappoints(&item, SnapPointsIter(snappoints)); + /* TODO: Implement the ordering. */ + vector found_cns; + satisfied_guide_cns(desktop, snappoints, found_cns); + /* effic: It might be nice to avoid an n^2 algorithm, but in practice n will be + small enough that it's still usually more efficient. */ + + for (vector::const_iterator fi(found_cns.begin()), + fiEnd(found_cns.end()); + fi != fiEnd; ++fi) + { + SPGuideConstraint const &cn = *fi; + if ( find(item.constraints.begin(), + item.constraints.end(), + cn) + == item.constraints.end() ) + { + item.constraints.push_back(cn); + cn.g->attached_items.push_back(SPGuideAttachment(&item, cn.snappoint_ix)); + } + } +} + + +/* + 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:textwidth=99 : diff --git a/src/sp-item-update-cns.h b/src/sp-item-update-cns.h new file mode 100644 index 000000000..74bb1f8cd --- /dev/null +++ b/src/sp-item-update-cns.h @@ -0,0 +1,19 @@ +#ifndef __SP_ITEM_UPDATE_CNS_H__ +#define __SP_ITEM_UPDATE_CNS_H__ +#include + +void sp_item_update_cns(SPItem &item, SPDesktop const &desktop); + + +#endif /* !__SP_ITEM_UPDATE_CNS_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:encoding=utf-8:textwidth=99 : diff --git a/src/sp-item.cpp b/src/sp-item.cpp new file mode 100644 index 000000000..33bbe9e05 --- /dev/null +++ b/src/sp-item.cpp @@ -0,0 +1,1320 @@ +#define __SP_ITEM_C__ + +/** \file + * Base class for visual SVG elements + */ +/* + * Authors: + * Lauris Kaplinski + * bulia byak + * + * Copyright (C) 2001-2005 authors + * Copyright (C) 2001 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +/** \class SPItem + * + * SPItem is an abstract base class for all graphic (visible) SVG nodes. It + * is a subclass of SPObject, with great deal of specific functionality. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + + + +#include "svg/svg.h" +#include "print.h" +#include "display/nr-arena.h" +#include "display/nr-arena-item.h" +#include "attributes.h" +#include "document.h" +#include "uri.h" + +#include "style.h" +#include +#include "sp-root.h" +#include "sp-clippath.h" +#include "sp-mask.h" +#include "sp-rect.h" +#include "sp-use.h" +#include "sp-text.h" +#include "sp-item-rm-unsatisfied-cns.h" +#include "sp-pattern.h" +#include "gradient-chemistry.h" +#include "prefs-utils.h" +#include "conn-avoid-ref.h" + +#include "libnr/nr-matrix-div.h" +#include "libnr/nr-matrix-fns.h" +#include "libnr/nr-matrix-scale-ops.h" +#include "libnr/nr-matrix-translate-ops.h" +#include "libnr/nr-scale-translate-ops.h" +#include "libnr/nr-translate-scale-ops.h" +#include "algorithms/find-last-if.h" +#include "util/reverse-list.h" + +#include "xml/repr.h" + +#define noSP_ITEM_DEBUG_IDLE + +static void sp_item_class_init(SPItemClass *klass); +static void sp_item_init(SPItem *item); + +static void sp_item_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr); +static void sp_item_release(SPObject *object); +static void sp_item_set(SPObject *object, unsigned key, gchar const *value); +static void sp_item_update(SPObject *object, SPCtx *ctx, guint flags); +static Inkscape::XML::Node *sp_item_write(SPObject *object, Inkscape::XML::Node *repr, guint flags); + +static gchar *sp_item_private_description(SPItem *item); +static void sp_item_private_snappoints(SPItem const *item, SnapPointsIter p); + +static SPItemView *sp_item_view_new_prepend(SPItemView *list, SPItem *item, unsigned flags, unsigned key, NRArenaItem *arenaitem); +static SPItemView *sp_item_view_list_remove(SPItemView *list, SPItemView *view); + +static SPObjectClass *parent_class; + +static void clip_ref_changed(SPObject *old_clip, SPObject *clip, SPItem *item); +static void mask_ref_changed(SPObject *old_clip, SPObject *clip, SPItem *item); + +/** + * Registers SPItem class and returns its type number. + */ +GType +sp_item_get_type(void) +{ + static GType type = 0; + if (!type) { + GTypeInfo info = { + sizeof(SPItemClass), + NULL, NULL, + (GClassInitFunc) sp_item_class_init, + NULL, NULL, + sizeof(SPItem), + 16, + (GInstanceInitFunc) sp_item_init, + NULL, /* value_table */ + }; + type = g_type_register_static(SP_TYPE_OBJECT, "SPItem", &info, (GTypeFlags)0); + } + return type; +} + +/** + * SPItem vtable initialization. + */ +static void +sp_item_class_init(SPItemClass *klass) +{ + SPObjectClass *sp_object_class = (SPObjectClass *) klass; + + parent_class = (SPObjectClass *)g_type_class_ref(SP_TYPE_OBJECT); + + sp_object_class->build = sp_item_build; + sp_object_class->release = sp_item_release; + sp_object_class->set = sp_item_set; + sp_object_class->update = sp_item_update; + sp_object_class->write = sp_item_write; + + klass->description = sp_item_private_description; + klass->snappoints = sp_item_private_snappoints; +} + +/** + * Callback for SPItem object initialization. + */ +static void +sp_item_init(SPItem *item) +{ + SPObject *object = SP_OBJECT(item); + + item->sensitive = TRUE; + + item->r_cx = 0; + item->r_cx = 0; + + item->transform = NR::identity(); + + item->display = NULL; + + item->clip_ref = new SPClipPathReference(SP_OBJECT(item)); + { + sigc::signal cs1=item->clip_ref->changedSignal(); + sigc::slot2 sl1=sigc::bind(sigc::ptr_fun(clip_ref_changed), item); + cs1.connect(sl1); + } + + item->mask_ref = new SPMaskReference(SP_OBJECT(item)); + sigc::signal cs2=item->mask_ref->changedSignal(); + sigc::slot2 sl2=sigc::bind(sigc::ptr_fun(mask_ref_changed), item); + cs2.connect(sl2); + + if (!object->style) object->style = sp_style_new_from_object(SP_OBJECT(item)); + + item->avoidRef = new SPAvoidRef(item); + + new (&item->_transformed_signal) sigc::signal(); +} + +bool SPItem::isVisibleAndUnlocked() const { + return (!isHidden() && !isLocked()); +} + +bool SPItem::isVisibleAndUnlocked(unsigned display_key) const { + return (!isHidden(display_key) && !isLocked()); +} + +bool SPItem::isLocked() const { + for (SPObject *o = SP_OBJECT(this); o != NULL; o = SP_OBJECT_PARENT(o)) { + if (SP_IS_ITEM(o) && !(SP_ITEM(o)->sensitive)) + return true; + } + return false; +} + +void SPItem::setLocked(bool locked) { + SP_OBJECT_REPR(this)->setAttribute("sodipodi:insensitive", + ( locked ? "1" : NULL )); + updateRepr(); +} + +bool SPItem::isHidden() const { + return style->display.computed == SP_CSS_DISPLAY_NONE; +} + +void SPItem::setHidden(bool hide) { + style->display.set = TRUE; + style->display.value = ( hide ? SP_CSS_DISPLAY_NONE : SP_CSS_DISPLAY_INLINE ); + style->display.computed = style->display.value; + style->display.inherit = FALSE; + updateRepr(); +} + +bool SPItem::isHidden(unsigned display_key) const { + for ( SPItemView *view(display) ; view ; view = view->next ) { + if ( view->key == display_key ) { + g_assert(view->arenaitem != NULL); + for ( NRArenaItem *arenaitem = view->arenaitem ; + arenaitem ; arenaitem = arenaitem->parent ) + { + if (!arenaitem->visible) { + return true; + } + } + return false; + } + } + return true; +} + +/** + * Returns something suitable for the `Hide' checkbox in the Object Properties dialog box. + * Corresponds to setExplicitlyHidden. + */ +bool +SPItem::isExplicitlyHidden() const +{ + return (this->style->display.set + && this->style->display.value == SP_CSS_DISPLAY_NONE); +} + +/** + * Sets the display CSS property to `hidden' if \a val is true, + * otherwise makes it unset + */ +void +SPItem::setExplicitlyHidden(bool const val) { + this->style->display.set = val; + this->style->display.value = ( val ? SP_CSS_DISPLAY_NONE : SP_CSS_DISPLAY_INLINE ); + this->style->display.computed = this->style->display.value; + this->updateRepr(); +} + +namespace { + +bool is_item(SPObject const &object) { + return SP_IS_ITEM(&object); +} + +} + +void SPItem::raiseToTop() { + using Inkscape::Algorithms::find_last_if; + + SPObject *topmost=find_last_if( + SP_OBJECT_NEXT(this), NULL, &is_item + ); + if (topmost) { + Inkscape::XML::Node *repr=SP_OBJECT_REPR(this); + sp_repr_parent(repr)->changeOrder(repr, SP_OBJECT_REPR(topmost)); + } +} + +void SPItem::raiseOne() { + SPObject *next_higher=std::find_if( + SP_OBJECT_NEXT(this), NULL, &is_item + ); + if (next_higher) { + Inkscape::XML::Node *repr=SP_OBJECT_REPR(this); + Inkscape::XML::Node *ref=SP_OBJECT_REPR(next_higher); + sp_repr_parent(repr)->changeOrder(repr, ref); + } +} + +void SPItem::lowerOne() { + using Inkscape::Util::MutableList; + using Inkscape::Util::reverse_list; + + MutableList next_lower=std::find_if( + reverse_list( + SP_OBJECT_PARENT(this)->firstChild(), this + ), + MutableList(), + &is_item + ); + if (next_lower) { + ++next_lower; + Inkscape::XML::Node *repr=SP_OBJECT_REPR(this); + Inkscape::XML::Node *ref=( next_lower ? SP_OBJECT_REPR(&*next_lower) : NULL ); + sp_repr_parent(repr)->changeOrder(repr, ref); + } +} + +void SPItem::lowerToBottom() { + using Inkscape::Algorithms::find_last_if; + using Inkscape::Util::MutableList; + using Inkscape::Util::reverse_list; + + MutableList bottom=find_last_if( + reverse_list( + SP_OBJECT_PARENT(this)->firstChild(), this + ), + MutableList(), + &is_item + ); + if (bottom) { + ++bottom; + Inkscape::XML::Node *repr=SP_OBJECT_REPR(this); + Inkscape::XML::Node *ref=( bottom ? SP_OBJECT_REPR(&*bottom) : NULL ); + sp_repr_parent(repr)->changeOrder(repr, ref); + } +} + +static void +sp_item_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr) +{ + sp_object_read_attr(object, "style"); + sp_object_read_attr(object, "transform"); + sp_object_read_attr(object, "clip-path"); + sp_object_read_attr(object, "mask"); + sp_object_read_attr(object, "sodipodi:insensitive"); + sp_object_read_attr(object, "sodipodi:nonprintable"); + sp_object_read_attr(object, "inkscape:r_cx"); + sp_object_read_attr(object, "inkscape:r_cy"); + sp_object_read_attr(object, "inkscape:connector-avoid"); + + if (((SPObjectClass *) (parent_class))->build) { + (* ((SPObjectClass *) (parent_class))->build)(object, document, repr); + } +} + +static void +sp_item_release(SPObject *object) +{ + SPItem *item = (SPItem *) object; + + if (item->clip_ref) { + item->clip_ref->detach(); + delete item->clip_ref; + item->clip_ref = NULL; + } + + if (item->mask_ref) { + item->mask_ref->detach(); + delete item->mask_ref; + item->mask_ref = NULL; + } + + if (item->avoidRef) { + delete item->avoidRef; + item->avoidRef = NULL; + } + + if (((SPObjectClass *) (parent_class))->release) { + ((SPObjectClass *) parent_class)->release(object); + } + + while (item->display) { + nr_arena_item_unparent(item->display->arenaitem); + item->display = sp_item_view_list_remove(item->display, item->display); + } + + item->_transformed_signal.~signal(); +} + +static void +sp_item_set(SPObject *object, unsigned key, gchar const *value) +{ + SPItem *item = (SPItem *) object; + + switch (key) { + case SP_ATTR_TRANSFORM: { + NR::Matrix t; + if (value && sp_svg_transform_read(value, &t)) { + sp_item_set_item_transform(item, t); + } else { + sp_item_set_item_transform(item, NR::identity()); + } + break; + } + case SP_PROP_CLIP_PATH: { + gchar *uri = Inkscape::parse_css_url(value); + if (uri) { + try { + item->clip_ref->attach(Inkscape::URI(uri)); + } catch (Inkscape::BadURIException &e) { + g_warning("%s", e.what()); + item->clip_ref->detach(); + } + g_free(uri); + } else { + item->clip_ref->detach(); + } + + break; + } + case SP_PROP_MASK: { + gchar *uri=Inkscape::parse_css_url(value); + if (uri) { + try { + item->mask_ref->attach(Inkscape::URI(uri)); + } catch (Inkscape::BadURIException &e) { + g_warning("%s", e.what()); + item->mask_ref->detach(); + } + g_free(uri); + } else { + item->mask_ref->detach(); + } + + break; + } + case SP_ATTR_SODIPODI_INSENSITIVE: + item->sensitive = !value; + for (SPItemView *v = item->display; v != NULL; v = v->next) { + nr_arena_item_set_sensitive(v->arenaitem, item->sensitive); + } + break; + case SP_ATTR_STYLE: + sp_style_read_from_object(object->style, object); + object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG); + break; + case SP_ATTR_CONNECTOR_AVOID: + item->avoidRef->setAvoid(value); + break; + default: + if (SP_ATTRIBUTE_IS_CSS(key)) { + sp_style_read_from_object(object->style, object); + object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG); + } else { + if (((SPObjectClass *) (parent_class))->set) { + (* ((SPObjectClass *) (parent_class))->set)(object, key, value); + } + } + break; + } +} + +static void +clip_ref_changed(SPObject *old_clip, SPObject *clip, SPItem *item) +{ + if (old_clip) { + SPItemView *v; + /* Hide clippath */ + for (v = item->display; v != NULL; v = v->next) { + sp_clippath_hide(SP_CLIPPATH(old_clip), NR_ARENA_ITEM_GET_KEY(v->arenaitem)); + nr_arena_item_set_clip(v->arenaitem, NULL); + } + } + if (SP_IS_CLIPPATH(clip)) { + NRRect bbox; + sp_item_invoke_bbox(item, &bbox, NR::identity(), TRUE); + for (SPItemView *v = item->display; v != NULL; v = v->next) { + if (!v->arenaitem->key) { + NR_ARENA_ITEM_SET_KEY(v->arenaitem, sp_item_display_key_new(3)); + } + NRArenaItem *ai = sp_clippath_show(SP_CLIPPATH(clip), + NR_ARENA_ITEM_ARENA(v->arenaitem), + NR_ARENA_ITEM_GET_KEY(v->arenaitem)); + nr_arena_item_set_clip(v->arenaitem, ai); + nr_arena_item_unref(ai); + sp_clippath_set_bbox(SP_CLIPPATH(clip), NR_ARENA_ITEM_GET_KEY(v->arenaitem), &bbox); + } + } +} + +static void +mask_ref_changed(SPObject *old_mask, SPObject *mask, SPItem *item) +{ + if (old_mask) { + /* Hide mask */ + for (SPItemView *v = item->display; v != NULL; v = v->next) { + sp_mask_hide(SP_MASK(old_mask), NR_ARENA_ITEM_GET_KEY(v->arenaitem)); + nr_arena_item_set_mask(v->arenaitem, NULL); + } + } + if (SP_IS_MASK(mask)) { + NRRect bbox; + sp_item_invoke_bbox(item, &bbox, NR::identity(), TRUE); + for (SPItemView *v = item->display; v != NULL; v = v->next) { + if (!v->arenaitem->key) { + NR_ARENA_ITEM_SET_KEY(v->arenaitem, sp_item_display_key_new(3)); + } + NRArenaItem *ai = sp_mask_show(SP_MASK(mask), + NR_ARENA_ITEM_ARENA(v->arenaitem), + NR_ARENA_ITEM_GET_KEY(v->arenaitem)); + nr_arena_item_set_mask(v->arenaitem, ai); + nr_arena_item_unref(ai); + sp_mask_set_bbox(SP_MASK(mask), NR_ARENA_ITEM_GET_KEY(v->arenaitem), &bbox); + } + } +} + +static void +sp_item_update(SPObject *object, SPCtx *ctx, guint flags) +{ + SPItem *item = SP_ITEM(object); + + if (((SPObjectClass *) (parent_class))->update) + (* ((SPObjectClass *) (parent_class))->update)(object, ctx, flags); + + if (flags & (SP_OBJECT_CHILD_MODIFIED_FLAG | SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG)) { + if (flags & SP_OBJECT_MODIFIED_FLAG) { + for (SPItemView *v = item->display; v != NULL; v = v->next) { + nr_arena_item_set_transform(v->arenaitem, item->transform); + } + } + + SPClipPath *clip_path = item->clip_ref->getObject(); + SPMask *mask = item->mask_ref->getObject(); + + if ( clip_path || mask ) { + NRRect bbox; + sp_item_invoke_bbox(item, &bbox, NR::identity(), TRUE); + if (clip_path) { + for (SPItemView *v = item->display; v != NULL; v = v->next) { + sp_clippath_set_bbox(clip_path, NR_ARENA_ITEM_GET_KEY(v->arenaitem), &bbox); + } + } + if (mask) { + for (SPItemView *v = item->display; v != NULL; v = v->next) { + sp_mask_set_bbox(mask, NR_ARENA_ITEM_GET_KEY(v->arenaitem), &bbox); + } + } + } + + if (flags & SP_OBJECT_STYLE_MODIFIED_FLAG) { + for (SPItemView *v = item->display; v != NULL; v = v->next) { + nr_arena_item_set_opacity(v->arenaitem, SP_SCALE24_TO_FLOAT(object->style->opacity.value)); + nr_arena_item_set_visible(v->arenaitem, !item->isHidden()); + } + } + } + + // Update libavoid with item geometry (for connector routing). + item->avoidRef->handleSettingChange(); +} + +static Inkscape::XML::Node * +sp_item_write(SPObject *const object, Inkscape::XML::Node *repr, guint flags) +{ + SPItem *item = SP_ITEM(object); + + gchar c[256]; + if (sp_svg_transform_write(c, 256, item->transform)) { + repr->setAttribute("transform", c); + } else { + repr->setAttribute("transform", NULL); + } + + SPObject const *const parent = SP_OBJECT_PARENT(object); + /** \todo Can someone please document why this is conditional on having + * a parent? The only parentless thing I can think of is the top-level + * element (SPRoot). SPRoot is derived from SPGroup, and can have + * style. I haven't looked at callers. + */ + if (parent) { + SPStyle const *const obj_style = SP_OBJECT_STYLE(object); + if (obj_style) { + gchar *s = sp_style_write_string(obj_style, SP_STYLE_FLAG_IFSET); + repr->setAttribute("style", ( *s ? s : NULL )); + g_free(s); + } else { + /** \todo I'm not sure what to do in this case. Bug #1165868 + * suggests that it can arise, but the submitter doesn't know + * how to do so reliably. The main two options are either + * leave repr's style attribute unchanged, or explicitly clear it. + * Must also consider what to do with property attributes for + * the element; see below. + */ + char const *style_str = repr->attribute("style"); + if (!style_str) { + style_str = "NULL"; + } + g_warning("Item's style is NULL; repr style attribute is %s", style_str); + } + + /** \note We treat object->style as authoritative. Its effects have + * been written to the style attribute above; any properties that are + * unset we take to be deliberately unset (e.g. so that clones can + * override the property). + * + * Note that the below has an undesirable consequence of changing the + * appearance on renderers that lack CSS support (e.g. SVG tiny); + * possibly we should write property attributes instead of a style + * attribute. + */ + sp_style_unset_property_attrs (object); + } + + if (flags & SP_OBJECT_WRITE_EXT) { + repr->setAttribute("sodipodi:insensitive", ( item->sensitive ? NULL : "true" )); + repr->setAttribute("inkscape:r_cx", ( item->r_cx ? NULL : "true" )); + repr->setAttribute("inkscape:r_cy", ( item->r_cy ? NULL : "true" )); + } + + if (((SPObjectClass *) (parent_class))->write) { + ((SPObjectClass *) (parent_class))->write(object, repr, flags); + } + + return repr; +} + +NR::Rect SPItem::invokeBbox(NR::Matrix const &transform) const +{ + NRRect r; + sp_item_invoke_bbox_full(this, &r, transform, 0, TRUE); + return NR::Rect(r); +} + +void +sp_item_invoke_bbox(SPItem const *item, NRRect *bbox, NR::Matrix const &transform, unsigned const clear) +{ + sp_item_invoke_bbox_full(item, bbox, transform, 0, clear); +} + +void +sp_item_invoke_bbox_full(SPItem const *item, NRRect *bbox, NR::Matrix const &transform, unsigned const flags, unsigned const clear) +{ + g_assert(item != NULL); + g_assert(SP_IS_ITEM(item)); + g_assert(bbox != NULL); + + if (clear) { + bbox->x0 = bbox->y0 = 1e18; + bbox->x1 = bbox->y1 = -1e18; + } + + if (((SPItemClass *) G_OBJECT_GET_CLASS(item))->bbox) { + ((SPItemClass *) G_OBJECT_GET_CLASS(item))->bbox(item, bbox, transform, flags); + } +} + +unsigned sp_item_pos_in_parent(SPItem *item) +{ + g_assert(item != NULL); + g_assert(SP_IS_ITEM(item)); + + SPObject *parent = SP_OBJECT_PARENT(item); + g_assert(parent != NULL); + g_assert(SP_IS_OBJECT(parent)); + + SPObject *object = SP_OBJECT(item); + + unsigned pos=0; + for ( SPObject *iter = sp_object_first_child(parent) ; iter ; iter = SP_OBJECT_NEXT(iter)) { + if ( iter == object ) { + return pos; + } + if (SP_IS_ITEM(iter)) { + pos++; + } + } + + g_assert_not_reached(); + return 0; +} + +void +sp_item_bbox_desktop(SPItem *item, NRRect *bbox) +{ + g_assert(item != NULL); + g_assert(SP_IS_ITEM(item)); + g_assert(bbox != NULL); + + sp_item_invoke_bbox(item, bbox, sp_item_i2d_affine(item), TRUE); +} + +NR::Rect sp_item_bbox_desktop(SPItem *item) +{ + NRRect ret; + sp_item_bbox_desktop(item, &ret); + return NR::Rect(ret); +} + +static void sp_item_private_snappoints(SPItem const *item, SnapPointsIter p) +{ + NR::Rect const bbox = item->invokeBbox(sp_item_i2d_affine(item)); + /* Just a pair of opposite corners of the bounding box suffices given that we don't yet + support angled guide lines. */ + + *p = bbox.min(); + *p = bbox.max(); +} + +void sp_item_snappoints(SPItem const *item, SnapPointsIter p) +{ + g_assert (item != NULL); + g_assert (SP_IS_ITEM(item)); + + SPItemClass const &item_class = *(SPItemClass const *) G_OBJECT_GET_CLASS(item); + if (item_class.snappoints) { + item_class.snappoints(item, p); + } +} + +void +sp_item_invoke_print(SPItem *item, SPPrintContext *ctx) +{ + if (!item->isHidden()) { + if (((SPItemClass *) G_OBJECT_GET_CLASS(item))->print) { + if (!item->transform.test_identity() + || SP_OBJECT_STYLE(item)->opacity.value != SP_SCALE24_MAX) + { + sp_print_bind(ctx, item->transform, SP_SCALE24_TO_FLOAT(SP_OBJECT_STYLE(item)->opacity.value)); + ((SPItemClass *) G_OBJECT_GET_CLASS(item))->print(item, ctx); + sp_print_release(ctx); + } else { + ((SPItemClass *) G_OBJECT_GET_CLASS(item))->print(item, ctx); + } + } + } +} + +static gchar * +sp_item_private_description(SPItem *item) +{ + return g_strdup(_("Object")); +} + +/** + * Returns a string suitable for status bar, formatted in pango markup language. + * + * Must be freed by caller. + */ +gchar * +sp_item_description(SPItem *item) +{ + g_assert(item != NULL); + g_assert(SP_IS_ITEM(item)); + + if (((SPItemClass *) G_OBJECT_GET_CLASS(item))->description) { + return ((SPItemClass *) G_OBJECT_GET_CLASS(item))->description(item); + } + + g_assert_not_reached(); + return NULL; +} + +/** + * Allocates unique integer keys. + * \param numkeys Number of keys required. + * \return First allocated key; hence if the returned key is n + * you can use n, n + 1, ..., n + (numkeys - 1) + */ +unsigned +sp_item_display_key_new(unsigned numkeys) +{ + static unsigned dkey = 0; + + dkey += numkeys; + + return dkey - numkeys; +} + +NRArenaItem * +sp_item_invoke_show(SPItem *item, NRArena *arena, unsigned key, unsigned flags) +{ + g_assert(item != NULL); + g_assert(SP_IS_ITEM(item)); + g_assert(arena != NULL); + g_assert(NR_IS_ARENA(arena)); + + NRArenaItem *ai = NULL; + if (((SPItemClass *) G_OBJECT_GET_CLASS(item))->show) { + ai = ((SPItemClass *) G_OBJECT_GET_CLASS(item))->show(item, arena, key, flags); + } + + if (ai != NULL) { + item->display = sp_item_view_new_prepend(item->display, item, flags, key, ai); + nr_arena_item_set_transform(ai, item->transform); + nr_arena_item_set_opacity(ai, SP_SCALE24_TO_FLOAT(SP_OBJECT_STYLE(item)->opacity.value)); + nr_arena_item_set_visible(ai, !item->isHidden()); + nr_arena_item_set_sensitive(ai, item->sensitive); + if (item->clip_ref->getObject()) { + NRArenaItem *ac; + if (!item->display->arenaitem->key) NR_ARENA_ITEM_SET_KEY(item->display->arenaitem, sp_item_display_key_new(3)); + ac = sp_clippath_show(item->clip_ref->getObject(), arena, NR_ARENA_ITEM_GET_KEY(item->display->arenaitem)); + nr_arena_item_set_clip(ai, ac); + nr_arena_item_unref(ac); + } + if (item->mask_ref->getObject()) { + NRArenaItem *ac; + if (!item->display->arenaitem->key) NR_ARENA_ITEM_SET_KEY(item->display->arenaitem, sp_item_display_key_new(3)); + ac = sp_mask_show(item->mask_ref->getObject(), arena, NR_ARENA_ITEM_GET_KEY(item->display->arenaitem)); + nr_arena_item_set_mask(ai, ac); + nr_arena_item_unref(ac); + } + NR_ARENA_ITEM_SET_DATA(ai, item); + } + + return ai; +} + +void +sp_item_invoke_hide(SPItem *item, unsigned key) +{ + g_assert(item != NULL); + g_assert(SP_IS_ITEM(item)); + + if (((SPItemClass *) G_OBJECT_GET_CLASS(item))->hide) { + ((SPItemClass *) G_OBJECT_GET_CLASS(item))->hide(item, key); + } + + SPItemView *ref = NULL; + SPItemView *v = item->display; + while (v != NULL) { + SPItemView *next = v->next; + if (v->key == key) { + if (item->clip_ref->getObject()) { + sp_clippath_hide(item->clip_ref->getObject(), NR_ARENA_ITEM_GET_KEY(v->arenaitem)); + nr_arena_item_set_clip(v->arenaitem, NULL); + } + if (item->mask_ref->getObject()) { + sp_mask_hide(item->mask_ref->getObject(), NR_ARENA_ITEM_GET_KEY(v->arenaitem)); + nr_arena_item_set_mask(v->arenaitem, NULL); + } + if (!ref) { + item->display = v->next; + } else { + ref->next = v->next; + } + nr_arena_item_unparent(v->arenaitem); + nr_arena_item_unref(v->arenaitem); + g_free(v); + } else { + ref = v; + } + v = next; + } +} + +// Adjusters + +void +sp_item_adjust_pattern (SPItem *item, NR::Matrix const &postmul, bool set) +{ + SPStyle *style = SP_OBJECT_STYLE (item); + + if (style && (style->fill.type == SP_PAINT_TYPE_PAINTSERVER)) { + SPObject *server = SP_OBJECT_STYLE_FILL_SERVER (item); + if (SP_IS_PATTERN (server)) { + SPPattern *pattern = sp_pattern_clone_if_necessary (item, SP_PATTERN (server), "fill"); + sp_pattern_transform_multiply (pattern, postmul, set); + } + } + + if (style && (style->stroke.type == SP_PAINT_TYPE_PAINTSERVER)) { + SPObject *server = SP_OBJECT_STYLE_STROKE_SERVER (item); + if (SP_IS_PATTERN (server)) { + SPPattern *pattern = sp_pattern_clone_if_necessary (item, SP_PATTERN (server), "stroke"); + sp_pattern_transform_multiply (pattern, postmul, set); + } + } + +} + +void +sp_item_adjust_gradient (SPItem *item, NR::Matrix const &postmul, bool set) +{ + SPStyle *style = SP_OBJECT_STYLE (item); + + if (style && (style->fill.type == SP_PAINT_TYPE_PAINTSERVER)) { + SPObject *server = SP_OBJECT_STYLE_FILL_SERVER(item); + if (SP_IS_GRADIENT (server)) { + + /** + * \note Bbox units for a gradient are generally a bad idea because + * with them, you cannot preserve the relative position of the + * object and its gradient after rotation or skew. So now we + * convert them to userspace units which are easy to keep in sync + * just by adding the object's transform to gradientTransform. + * \todo FIXME: convert back to bbox units after transforming with + * the item, so as to preserve the original units. + */ + SPGradient *gradient = sp_gradient_convert_to_userspace (SP_GRADIENT (server), item, "fill"); + + sp_gradient_transform_multiply (gradient, postmul, set); + } + } + + if (style && (style->stroke.type == SP_PAINT_TYPE_PAINTSERVER)) { + SPObject *server = SP_OBJECT_STYLE_STROKE_SERVER(item); + if (SP_IS_GRADIENT (server)) { + SPGradient *gradient = sp_gradient_convert_to_userspace (SP_GRADIENT (server), item, "stroke"); + sp_gradient_transform_multiply (gradient, postmul, set); + } + } +} + +void +sp_item_adjust_stroke (SPItem *item, gdouble ex) +{ + SPStyle *style = SP_OBJECT_STYLE (item); + + if (style && style->stroke.type != SP_PAINT_TYPE_NONE && !NR_DF_TEST_CLOSE (ex, 1.0, NR_EPSILON)) { + + style->stroke_width.computed *= ex; + + if (style->stroke_dash.n_dash != 0) { + int i; + for (i = 0; i < style->stroke_dash.n_dash; i++) { + style->stroke_dash.dash[i] *= ex; + } + style->stroke_dash.offset *= ex; + } + + SP_OBJECT(item)->updateRepr(); + } +} + +/** + * Find out the inverse of previous transform of an item (from its repr) + */ +NR::Matrix +sp_item_transform_repr (SPItem *item) +{ + NR::Matrix t_old(NR::identity()); + gchar const *t_attr = SP_OBJECT_REPR(item)->attribute("transform"); + if (t_attr) { + NR::Matrix t; + if (sp_svg_transform_read(t_attr, &t)) { + t_old = t; + } + } + + return t_old; +} + + +/** + * Recursively scale stroke width in \a item and its children by \a expansion. + */ +void +sp_item_adjust_stroke_width_recursive(SPItem *item, double expansion) +{ + sp_item_adjust_stroke (item, expansion); + + for (SPObject *o = SP_OBJECT(item)->children; o != NULL; o = o->next) { + if (SP_IS_ITEM(o)) + sp_item_adjust_stroke_width_recursive(SP_ITEM(o), expansion); + } +} + +/** + * Recursively adjust rx and ry of rects. + */ +void +sp_item_adjust_rects_recursive(SPItem *item, NR::Matrix advertized_transform) +{ + if (SP_IS_RECT (item)) { + sp_rect_compensate_rxry (SP_RECT(item), advertized_transform); + } + + for (SPObject *o = SP_OBJECT(item)->children; o != NULL; o = o->next) { + if (SP_IS_ITEM(o)) + sp_item_adjust_rects_recursive(SP_ITEM(o), advertized_transform); + } +} + +/** + * Recursively compensate pattern or gradient transform. + */ +void +sp_item_adjust_paint_recursive (SPItem *item, NR::Matrix advertized_transform, NR::Matrix t_ancestors, bool is_pattern) +{ +// A clone must not touch the style (it's that of its parent!) and has no children, so quit now + if (item && SP_IS_USE(item)) + return; + +// _Before_ full pattern/gradient transform: t_paint * t_item * t_ancestors +// _After_ full pattern/gradient transform: t_paint_new * t_item * t_ancestors * advertised_transform +// By equating these two expressions we get t_paint_new = t_paint * paint_delta, where: + NR::Matrix t_item = sp_item_transform_repr (item); + NR::Matrix paint_delta = t_item * t_ancestors * advertized_transform * t_ancestors.inverse() * t_item.inverse(); + + if (is_pattern) + sp_item_adjust_pattern (item, paint_delta); + else + sp_item_adjust_gradient (item, paint_delta); + +// Within text, we do not fork gradients, and so must not recurse to avoid double compensation + if (item && SP_IS_TEXT(item)) + return; + + for (SPObject *o = SP_OBJECT(item)->children; o != NULL; o = o->next) { + if (SP_IS_ITEM(o)) { +// At the level of the transformed item, t_ancestors is identity; +// below it, it is the accmmulated chain of transforms from this level to the top level + sp_item_adjust_paint_recursive (SP_ITEM(o), advertized_transform, t_item * t_ancestors, is_pattern); + } + } +} + +/** + * A temporary wrapper for the next function accepting the NRMatrix + * instead of NR::Matrix + */ +void +sp_item_write_transform(SPItem *item, Inkscape::XML::Node *repr, NRMatrix const *transform, NR::Matrix const *adv) +{ + if (transform == NULL) + sp_item_write_transform(item, repr, NR::identity(), adv); + else + sp_item_write_transform(item, repr, NR::Matrix (transform), adv); +} + +/** + * Set a new transform on an object. + * + * Compensate for stroke scaling and gradient/pattern fill transform, if + * necessary. Call the object's set_transform method if transforms are + * stored optimized. Send _transformed_signal. Invoke _write method so that + * the repr is updated with the new transform. + */ +void +sp_item_write_transform(SPItem *item, Inkscape::XML::Node *repr, NR::Matrix const &transform, NR::Matrix const *adv) +{ + g_return_if_fail(item != NULL); + g_return_if_fail(SP_IS_ITEM(item)); + g_return_if_fail(repr != NULL); + + // calculate the relative transform, if not given by the adv attribute + NR::Matrix advertized_transform; + if (adv != NULL) { + advertized_transform = *adv; + } else { + advertized_transform = sp_item_transform_repr (item).inverse() * transform; + } + + // recursively compensate for stroke scaling, depending on user preference + if (prefs_get_int_attribute("options.transform", "stroke", 1) == 0) { + double const expansion = 1. / NR::expansion(advertized_transform); + sp_item_adjust_stroke_width_recursive(item, expansion); + } + + // recursively compensate rx/ry of a rect if requested + if (prefs_get_int_attribute("options.transform", "rectcorners", 1) == 0) { + sp_item_adjust_rects_recursive(item, advertized_transform); + } + + // recursively compensate pattern fill if it's not to be transformed + if (prefs_get_int_attribute("options.transform", "pattern", 1) == 0) { + sp_item_adjust_paint_recursive (item, advertized_transform.inverse(), NR::identity(), true); + } + /// \todo FIXME: add the same else branch as for gradients below, to convert patterns to userSpaceOnUse as well + /// recursively compensate gradient fill if it's not to be transformed + if (prefs_get_int_attribute("options.transform", "gradient", 1) == 0) { + sp_item_adjust_paint_recursive (item, advertized_transform.inverse(), NR::identity(), false); + } else { + // this converts the gradient/pattern fill/stroke, if any, to userSpaceOnUse; we need to do + // it here _before_ the new transform is set, so as to use the pre-transform bbox + sp_item_adjust_paint_recursive (item, NR::identity(), NR::identity(), false); + } + + // run the object's set_transform if transforms are stored optimized + gint preserve = prefs_get_int_attribute("options.preservetransform", "value", 0); + NR::Matrix transform_attr (transform); + if (((SPItemClass *) G_OBJECT_GET_CLASS(item))->set_transform && !preserve) { + transform_attr = ((SPItemClass *) G_OBJECT_GET_CLASS(item))->set_transform(item, transform); + } + sp_item_set_item_transform(item, transform_attr); + + // Note: updateRepr comes before emitting the transformed signal since + // it causes clone SPUse's copy of the original object to brought up to + // date with the original. Otherwise, sp_use_bbox returns incorrect + // values if called in code handling the transformed signal. + SP_OBJECT(item)->updateRepr(); + + // send the relative transform with a _transformed_signal + item->_transformed_signal.emit(&advertized_transform, item); +} + +gint +sp_item_event(SPItem *item, SPEvent *event) +{ + g_return_val_if_fail(item != NULL, FALSE); + g_return_val_if_fail(SP_IS_ITEM(item), FALSE); + g_return_val_if_fail(event != NULL, FALSE); + + if (((SPItemClass *) G_OBJECT_GET_CLASS(item))->event) + return ((SPItemClass *) G_OBJECT_GET_CLASS(item))->event(item, event); + + return FALSE; +} + +/** + * Sets item private transform (not propagated to repr), without compensating stroke widths, + * gradients, patterns as sp_item_write_transform does. + */ +void +sp_item_set_item_transform(SPItem *item, NR::Matrix const &transform) +{ + g_return_if_fail(item != NULL); + g_return_if_fail(SP_IS_ITEM(item)); + + if (!matrix_equalp(transform, item->transform, NR_EPSILON)) { + item->transform = transform; + /* The SP_OBJECT_USER_MODIFIED_FLAG_B is used to mark the fact that it's only a + transformation. It's apparently not used anywhere else. */ + item->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_USER_MODIFIED_FLAG_B); + sp_item_rm_unsatisfied_cns(*item); + } +} + + +/** + * \pre \a ancestor really is an ancestor (\>=) of \a object, or NULL. + * ("Ancestor (\>=)" here includes as far as \a object itself.) + */ +NR::Matrix +i2anc_affine(SPObject const *object, SPObject const *const ancestor) { + NR::Matrix ret(NR::identity()); + g_return_val_if_fail(object != NULL, ret); + + /* stop at first non-renderable ancestor */ + while ( object != ancestor && SP_IS_ITEM(object) ) { + if (SP_IS_ROOT(object)) { + ret *= SP_ROOT(object)->c2p; + } + ret *= SP_ITEM(object)->transform; + object = SP_OBJECT_PARENT(object); + } + return ret; +} + +NR::Matrix +i2i_affine(SPObject const *src, SPObject const *dest) { + g_return_val_if_fail(src != NULL && dest != NULL, NR::identity()); + SPObject const *ancestor = src->nearestCommonAncestor(dest); + return i2anc_affine(src, ancestor) / i2anc_affine(dest, ancestor); +} + +NR::Matrix SPItem::getRelativeTransform(SPObject const *dest) const { + return i2i_affine(this, dest); +} + +/** + * Returns the accumulated transformation of the item and all its ancestors, including root's viewport. + * \pre (item != NULL) and SP_IS_ITEM(item). + */ +NR::Matrix sp_item_i2doc_affine(SPItem const *item) +{ + return i2anc_affine(item, NULL); +} + +/** + * Returns the accumulated transformation of the item and all its ancestors, but excluding root's viewport. + * Used in path operations mostly. + * \pre (item != NULL) and SP_IS_ITEM(item). + */ +NR::Matrix sp_item_i2root_affine(SPItem const *item) +{ + g_assert(item != NULL); + g_assert(SP_IS_ITEM(item)); + + NR::Matrix ret(NR::identity()); + g_assert(ret.test_identity()); + while ( NULL != SP_OBJECT_PARENT(item) ) { + ret *= item->transform; + item = SP_ITEM(SP_OBJECT_PARENT(item)); + } + g_assert(SP_IS_ROOT(item)); + + ret *= item->transform; + + return ret; +} + +/* fixme: This is EVIL!!! */ + +NR::Matrix sp_item_i2d_affine(SPItem const *item) +{ + g_assert(item != NULL); + g_assert(SP_IS_ITEM(item)); + + NR::Matrix const ret( sp_item_i2doc_affine(item) + * NR::scale(1, -1) + * NR::translate(0, sp_document_height(SP_OBJECT_DOCUMENT(item))) ); + return ret; +} + +// same as i2d but with i2root instead of i2doc +NR::Matrix sp_item_i2r_affine(SPItem const *item) +{ + g_assert(item != NULL); + g_assert(SP_IS_ITEM(item)); + + NR::Matrix const ret( sp_item_i2root_affine(item) + * NR::scale(1, -1) + * NR::translate(0, sp_document_height(SP_OBJECT_DOCUMENT(item))) ); + return ret; +} + +/** + * Converts a matrix \a m into the desktop coords of the \a item. + * Will become a noop when we eliminate the coordinate flipping. + */ +NR::Matrix matrix_to_desktop(NR::Matrix const m, SPItem const *item) +{ + NR::Matrix const ret(m + * NR::translate(0, -sp_document_height(SP_OBJECT_DOCUMENT(item))) + * NR::scale(1, -1)); + return ret; +} + +/** + * Converts a matrix \a m from the desktop coords of the \a item. + * Will become a noop when we eliminate the coordinate flipping. + */ +NR::Matrix matrix_from_desktop(NR::Matrix const m, SPItem const *item) +{ + NR::Matrix const ret(NR::scale(1, -1) + * NR::translate(0, sp_document_height(SP_OBJECT_DOCUMENT(item))) + * m); + return ret; +} + +void sp_item_set_i2d_affine(SPItem *item, NR::Matrix const &i2dt) +{ + g_return_if_fail( item != NULL ); + g_return_if_fail( SP_IS_ITEM(item) ); + + NR::Matrix dt2p; /* desktop to item parent transform */ + if (SP_OBJECT_PARENT(item)) { + dt2p = sp_item_i2d_affine((SPItem *) SP_OBJECT_PARENT(item)).inverse(); + } else { + dt2p = ( NR::translate(0, -sp_document_height(SP_OBJECT_DOCUMENT(item))) + * NR::scale(1, -1) ); + } + + NR::Matrix const i2p( i2dt * dt2p ); + sp_item_set_item_transform(item, i2p); +} + + +NR::Matrix +sp_item_dt2i_affine(SPItem const *item) +{ + /* fixme: Implement the right way (Lauris) */ + return sp_item_i2d_affine(item).inverse(); +} + +/* Item views */ + +static SPItemView * +sp_item_view_new_prepend(SPItemView *list, SPItem *item, unsigned flags, unsigned key, NRArenaItem *arenaitem) +{ + SPItemView *new_view; + + g_assert(item != NULL); + g_assert(SP_IS_ITEM(item)); + g_assert(arenaitem != NULL); + g_assert(NR_IS_ARENA_ITEM(arenaitem)); + + new_view = g_new(SPItemView, 1); + + new_view->next = list; + new_view->flags = flags; + new_view->key = key; + new_view->arenaitem = nr_arena_item_ref(arenaitem); + + return new_view; +} + +static SPItemView * +sp_item_view_list_remove(SPItemView *list, SPItemView *view) +{ + if (view == list) { + list = list->next; + } else { + SPItemView *prev; + prev = list; + while (prev->next != view) prev = prev->next; + prev->next = view->next; + } + + nr_arena_item_unref(view->arenaitem); + g_free(view); + + return list; +} + +/** + * Return the arenaitem corresponding to the given item in the display + * with the given key + */ +NRArenaItem * +sp_item_get_arenaitem(SPItem *item, unsigned key) +{ + for ( SPItemView *iv = item->display ; iv ; iv = iv->next ) { + if ( iv->key == key ) { + return iv->arenaitem; + } + } + + return NULL; +} + +int +sp_item_repr_compare_position(SPItem *first, SPItem *second) +{ + return sp_repr_compare_position(SP_OBJECT_REPR(first), + SP_OBJECT_REPR(second)); +} + +SPItem * +sp_item_first_item_child (SPObject *obj) +{ + for ( SPObject *iter = sp_object_first_child(obj) ; iter ; iter = SP_OBJECT_NEXT(iter)) { + if (SP_IS_ITEM (iter)) + return SP_ITEM (iter); + } + return NULL; +} + + +/* + 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 : diff --git a/src/sp-item.h b/src/sp-item.h new file mode 100644 index 000000000..326ea2759 --- /dev/null +++ b/src/sp-item.h @@ -0,0 +1,246 @@ +#ifndef __SP_ITEM_H__ +#define __SP_ITEM_H__ + +/** \file + * Some things pertinent to all visible shapes: SPItem, SPItemView, SPItemCtx, SPItemClass, SPEvent. + */ + +/* + * Authors: + * Lauris Kaplinski + * bulia byak + * + * Copyright (C) 1999-2005 authors + * Copyright (C) 2001-2002 Ximian, Inc. + * Copyright (C) 2004 Monash University + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include +#include + +#include "display/nr-arena-forward.h" +#include "forward.h" +#include "sp-object.h" +#include + +namespace Inkscape { class URIReference; } +class SPGuideConstraint; + +enum { + SP_EVENT_INVALID, + SP_EVENT_NONE, + SP_EVENT_ACTIVATE, + SP_EVENT_MOUSEOVER, + SP_EVENT_MOUSEOUT +}; + +/** + * Event structure. + * + * \todo This is just placeholder. Plan: + * We do extensible event structure, that hold applicable (ui, non-ui) + * data pointers. So it is up to given object/arena implementation + * to process correct ones in meaningful way. + * Also, this probably goes to SPObject base class. + * + */ +struct SPEvent { + unsigned int type; + gpointer data; +}; + +class SPItemView; + +/// SPItemView +struct SPItemView { + SPItemView *next; + unsigned int flags; + unsigned int key; + NRArenaItem *arenaitem; +}; + +/* flags */ + +#define SP_ITEM_BBOX_VISUAL 1 + +#define SP_ITEM_SHOW_DISPLAY (1 << 0) + +/** + * Flag for referenced views (i.e. clippaths, masks and patterns); always display + */ +#define SP_ITEM_REFERENCE_FLAGS SP_ITEM_SHOW_DISPLAY + +class SPItemCtx; + +/// Contains transformations to document/viewport and the viewport size. +struct SPItemCtx { + SPCtx ctx; + /** Item to document transformation */ + NR::Matrix i2doc; + /** Viewport size */ + NRRect vp; + /** Item to viewport transformation */ + NR::Matrix i2vp; +}; + +/** Abstract base class for all visible shapes. */ +struct SPItem : public SPObject { + unsigned int sensitive : 1; + unsigned int stop_paint: 1; + double r_cx; + double r_cy; + + NR::Matrix transform; + + SPClipPathReference *clip_ref; + SPMaskReference *mask_ref; + + // Used for object-avoiding connectors + SPAvoidRef *avoidRef; + + SPItemView *display; + + std::vector constraints; + + sigc::signal _transformed_signal; + + bool isLocked() const; + void setLocked(bool lock); + + bool isHidden() const; + void setHidden(bool hidden); + + bool isHidden(unsigned display_key) const; + + bool isExplicitlyHidden() const; + + void setExplicitlyHidden(bool val); + + bool isVisibleAndUnlocked() const; + + bool isVisibleAndUnlocked(unsigned display_key) const; + + NR::Matrix getRelativeTransform(SPObject const *obj) const; + + void raiseOne(); + void lowerOne(); + void raiseToTop(); + void lowerToBottom(); + + NR::Rect invokeBbox(NR::Matrix const &transform) const; + + sigc::connection connectTransformed(sigc::slot slot) { + return _transformed_signal.connect(slot); + } +}; + +typedef std::back_insert_iterator > SnapPointsIter; + +/// The SPItem vtable. +struct SPItemClass { + SPObjectClass parent_class; + + /** BBox union in given coordinate system */ + void (* bbox) (SPItem const *item, NRRect *bbox, NR::Matrix const &transform, unsigned const flags); + + /** Printing method. Assumes ctm is set to item affine matrix */ + /* \todo Think about it, and maybe implement generic export method instead (Lauris) */ + void (* print) (SPItem *item, SPPrintContext *ctx); + + /** Give short description of item (for status display) */ + gchar * (* description) (SPItem * item); + + NRArenaItem * (* show) (SPItem *item, NRArena *arena, unsigned int key, unsigned int flags); + void (* hide) (SPItem *item, unsigned int key); + + /** Write to an iterator the points that should be considered for snapping + * as the item's `nodes'. + */ + void (* snappoints) (SPItem const *item, SnapPointsIter p); + + /** Apply the transform optimally, and return any residual transformation */ + NR::Matrix (* set_transform)(SPItem *item, NR::Matrix const &transform); + + /** Emit event, if applicable */ + gint (* event) (SPItem *item, SPEvent *event); +}; + +/* Flag testing macros */ + +#define SP_ITEM_STOP_PAINT(i) (SP_ITEM (i)->stop_paint) + +/* Methods */ + +void sp_item_invoke_bbox(SPItem const *item, NRRect *bbox, NR::Matrix const &transform, unsigned const clear); +void sp_item_invoke_bbox_full(SPItem const *item, NRRect *bbox, NR::Matrix const &transform, unsigned const flags, unsigned const clear); + +unsigned sp_item_pos_in_parent(SPItem *item); + +gchar *sp_item_description(SPItem * item); +void sp_item_invoke_print(SPItem *item, SPPrintContext *ctx); + +/** Shows/Hides item on given arena display list */ +unsigned int sp_item_display_key_new(unsigned int numkeys); +NRArenaItem *sp_item_invoke_show(SPItem *item, NRArena *arena, unsigned int key, unsigned int flags); +void sp_item_invoke_hide(SPItem *item, unsigned int key); + +void sp_item_snappoints(SPItem const *item, SnapPointsIter p); + +void sp_item_adjust_pattern(SPItem *item, /* NR::Matrix const &premul, */ NR::Matrix const &postmul, bool set = false); +void sp_item_adjust_gradient(SPItem *item, /* NR::Matrix const &premul, */ NR::Matrix const &postmul, bool set = false); +void sp_item_adjust_stroke(SPItem *item, gdouble ex); +void sp_item_adjust_stroke_width_recursive(SPItem *item, gdouble ex); +void sp_item_adjust_paint_recursive(SPItem *item, NR::Matrix advertized_transform, NR::Matrix t_ancestors, bool is_pattern); + +void sp_item_write_transform(SPItem *item, Inkscape::XML::Node *repr, NRMatrix const *transform, NR::Matrix const *adv = NULL); +void sp_item_write_transform(SPItem *item, Inkscape::XML::Node *repr, NR::Matrix const &transform, NR::Matrix const *adv = NULL); + +void sp_item_set_item_transform(SPItem *item, NR::Matrix const &transform); + +gint sp_item_event (SPItem *item, SPEvent *event); + +/* Utility */ + +NRArenaItem *sp_item_get_arenaitem(SPItem *item, unsigned int key); + +void sp_item_bbox_desktop(SPItem *item, NRRect *bbox) __attribute__ ((deprecated)); +NR::Rect sp_item_bbox_desktop(SPItem *item); + +NR::Matrix i2anc_affine(SPObject const *item, SPObject const *ancestor); +NR::Matrix i2i_affine(SPObject const *src, SPObject const *dest); + +NR::Matrix sp_item_i2doc_affine(SPItem const *item); +NR::Matrix sp_item_i2root_affine(SPItem const *item); + +NR::Matrix matrix_to_desktop (NR::Matrix m, SPItem const *item); +NR::Matrix matrix_from_desktop (NR::Matrix m, SPItem const *item); + +/* fixme: - these are evil, but OK */ + +/* Fill *TRANSFORM with the item-to-desktop transform. See doc/coordinates.txt + * for a description of `Desktop coordinates'; though see also mental's comment + * at the top of that file. + * + * \return TRANSFORM. + */ +NR::Matrix sp_item_i2d_affine(SPItem const *item); +NR::Matrix sp_item_i2r_affine(SPItem const *item); +void sp_item_set_i2d_affine(SPItem *item, NR::Matrix const &transform); +NR::Matrix sp_item_dt2i_affine(SPItem const *item); +int sp_item_repr_compare_position(SPItem *first, SPItem *second); +SPItem *sp_item_first_item_child (SPObject *obj); + +#endif + +/* + 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:textwidth=99 : diff --git a/src/sp-line.cpp b/src/sp-line.cpp new file mode 100644 index 000000000..cca470530 --- /dev/null +++ b/src/sp-line.cpp @@ -0,0 +1,227 @@ +#define __SP_LINE_C__ + +/* + * SVG implementation + * + * Authors: + * Lauris Kaplinski + * + * Copyright (C) 1999-2002 Lauris Kaplinski + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifdef HAVE_CONFIG_H +# include +#endif +#include "attributes.h" +#include "style.h" +#include "sp-line.h" +#include "display/curve.h" +#include +#include +#include + +static void sp_line_class_init (SPLineClass *klass); +static void sp_line_init (SPLine *line); + +static void sp_line_build (SPObject * object, SPDocument * document, Inkscape::XML::Node * repr); +static void sp_line_set (SPObject *object, unsigned int key, const gchar *value); +static Inkscape::XML::Node *sp_line_write (SPObject *object, Inkscape::XML::Node *repr, guint flags); + +static gchar *sp_line_description (SPItem * item); +static NR::Matrix sp_line_set_transform(SPItem *item, NR::Matrix const &xform); + +static void sp_line_update (SPObject *object, SPCtx *ctx, guint flags); +static void sp_line_set_shape (SPShape *shape); + +static SPShapeClass *parent_class; + +GType +sp_line_get_type (void) +{ + static GType line_type = 0; + + if (!line_type) { + GTypeInfo line_info = { + sizeof (SPLineClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) sp_line_class_init, + NULL, /* klass_finalize */ + NULL, /* klass_data */ + sizeof (SPLine), + 16, /* n_preallocs */ + (GInstanceInitFunc) sp_line_init, + NULL, /* value_table */ + }; + line_type = g_type_register_static (SP_TYPE_SHAPE, "SPLine", &line_info, (GTypeFlags)0); + } + return line_type; +} + +static void +sp_line_class_init (SPLineClass *klass) +{ + parent_class = (SPShapeClass *) g_type_class_ref (SP_TYPE_SHAPE); + + SPObjectClass *sp_object_class = (SPObjectClass *) klass; + sp_object_class->build = sp_line_build; + sp_object_class->set = sp_line_set; + sp_object_class->write = sp_line_write; + + SPItemClass *item_class = (SPItemClass *) klass; + item_class->description = sp_line_description; + item_class->set_transform = sp_line_set_transform; + + sp_object_class->update = sp_line_update; + + SPShapeClass *shape_class = (SPShapeClass *) klass; + shape_class->set_shape = sp_line_set_shape; +} + +static void +sp_line_init (SPLine * line) +{ + line->x1.unset(); + line->y1.unset(); + line->x2.unset(); + line->y2.unset(); +} + + +static void +sp_line_build (SPObject * object, SPDocument * document, Inkscape::XML::Node * repr) +{ + if (((SPObjectClass *) parent_class)->build) { + ((SPObjectClass *) parent_class)->build (object, document, repr); + } + + sp_object_read_attr (object, "x1"); + sp_object_read_attr (object, "y1"); + sp_object_read_attr (object, "x2"); + sp_object_read_attr (object, "y2"); +} + +static void +sp_line_set (SPObject *object, unsigned int key, const gchar *value) +{ + SPLine * line = SP_LINE (object); + + /* fixme: we should really collect updates */ + + switch (key) { + case SP_ATTR_X1: + line->x1.readOrUnset(value); + object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_Y1: + line->y1.readOrUnset(value); + object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_X2: + line->x2.readOrUnset(value); + object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_Y2: + line->y2.readOrUnset(value); + object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + break; + default: + if (((SPObjectClass *) parent_class)->set) + ((SPObjectClass *) parent_class)->set (object, key, value); + break; + } +} + +static void +sp_line_update (SPObject *object, SPCtx *ctx, guint flags) +{ + if (flags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG)) { + SPLine *line = SP_LINE (object); + + SPStyle const *style = object->style; + double const d = 1.0 / NR::expansion(((SPItemCtx const *) ctx)->i2vp); + double const em = style->font_size.computed; + double const ex = em * 0.5; // fixme: get from pango or libnrtype. + line->x1.update(em, ex, d); + line->x2.update(em, ex, d); + line->y1.update(em, ex, d); + line->y2.update(em, ex, d); + + sp_shape_set_shape ((SPShape *) object); + } + + if (((SPObjectClass *) parent_class)->update) + ((SPObjectClass *) parent_class)->update (object, ctx, flags); +} + + +static Inkscape::XML::Node * +sp_line_write (SPObject *object, Inkscape::XML::Node *repr, guint flags) +{ + SPLine *line = SP_LINE (object); + + if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { + repr = sp_repr_new ("svg:line"); + } + + if (repr != SP_OBJECT_REPR (object)) { + repr->mergeFrom(SP_OBJECT_REPR (object), "id"); + } + + sp_repr_set_svg_double(repr, "x1", line->x1.computed); + sp_repr_set_svg_double(repr, "y1", line->y1.computed); + sp_repr_set_svg_double(repr, "x2", line->x2.computed); + sp_repr_set_svg_double(repr, "y2", line->y2.computed); + + if (((SPObjectClass *) (parent_class))->write) + ((SPObjectClass *) (parent_class))->write (object, repr, flags); + + return repr; +} + +static gchar * +sp_line_description(SPItem *item) +{ + return g_strdup(_("Line")); +} + +static NR::Matrix +sp_line_set_transform (SPItem *item, NR::Matrix const &xform) +{ + SPLine *line = SP_LINE (item); + NR::Point points[2]; + + points[0] = NR::Point(line->x1.computed, line->y1.computed); + points[1] = NR::Point(line->x2.computed, line->y2.computed); + + points[0] *= xform; + points[1] *= xform; + + line->x1.computed = points[0][NR::X]; + line->y1.computed = points[0][NR::Y]; + line->x2.computed = points[1][NR::X]; + line->y2.computed = points[1][NR::Y]; + + sp_item_adjust_stroke(item, NR::expansion(xform)); + + SP_OBJECT (item)->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG); + + return NR::identity(); +} + +static void +sp_line_set_shape (SPShape *shape) +{ + SPLine *line = SP_LINE (shape); + + SPCurve *c = sp_curve_new (); + + sp_curve_moveto (c, line->x1.computed, line->y1.computed); + sp_curve_lineto (c, line->x2.computed, line->y2.computed); + + sp_shape_set_curve_insync (shape, c, TRUE); // *_insync does not call update, avoiding infinite recursion when set_shape is called by update + + sp_curve_unref (c); +} diff --git a/src/sp-line.h b/src/sp-line.h new file mode 100644 index 000000000..cc6802b7f --- /dev/null +++ b/src/sp-line.h @@ -0,0 +1,44 @@ +#ifndef __SP_LINE_H__ +#define __SP_LINE_H__ + +/* + * SVG implementation + * + * Authors: + * Lauris Kaplinski + * + * Copyright (C) 1999-2002 Lauris Kaplinski + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "svg/svg-length.h" +#include "sp-shape.h" + + + +#define SP_TYPE_LINE (sp_line_get_type ()) +#define SP_LINE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SP_TYPE_LINE, SPLine)) +#define SP_LINE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SP_TYPE_LINE, SPLineClass)) +#define SP_IS_LINE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_LINE)) +#define SP_IS_LINE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SP_TYPE_LINE)) + +class SPLine; +class SPLineClass; + +struct SPLine : public SPShape { + SVGLength x1; + SVGLength y1; + SVGLength x2; + SVGLength y2; +}; + +struct SPLineClass { + SPShapeClass parent_class; +}; + +GType sp_line_get_type (void); + + + +#endif diff --git a/src/sp-linear-gradient-fns.h b/src/sp-linear-gradient-fns.h new file mode 100644 index 000000000..0962bae35 --- /dev/null +++ b/src/sp-linear-gradient-fns.h @@ -0,0 +1,40 @@ +#ifndef SP_LINEAR_GRADIENT_FNS_H +#define SP_LINEAR_GRADIENT_FNS_H + +/** \file + * Macros and fn declarations related to linear gradients. + */ + +#include +#include + +namespace Inkscape { +namespace XML { +class Node; +} +} + +class SPLinearGradient; + +#define SP_TYPE_LINEARGRADIENT (sp_lineargradient_get_type()) +#define SP_LINEARGRADIENT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), SP_TYPE_LINEARGRADIENT, SPLinearGradient)) +#define SP_LINEARGRADIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), SP_TYPE_LINEARGRADIENT, SPLinearGradientClass)) +#define SP_IS_LINEARGRADIENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), SP_TYPE_LINEARGRADIENT)) +#define SP_IS_LINEARGRADIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), SP_TYPE_LINEARGRADIENT)) + +GType sp_lineargradient_get_type(); + +void sp_lineargradient_set_position(SPLinearGradient *lg, gdouble x1, gdouble y1, gdouble x2, gdouble y2); + +#endif /* !SP_LINEAR_GRADIENT_FNS_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:encoding=utf-8:textwidth=99 : diff --git a/src/sp-linear-gradient.h b/src/sp-linear-gradient.h new file mode 100644 index 000000000..eabf7f308 --- /dev/null +++ b/src/sp-linear-gradient.h @@ -0,0 +1,36 @@ +#ifndef SP_LINEAR_GRADIENT_H +#define SP_LINEAR_GRADIENT_H + +/** \file + * SPLinearGradient: SVG implementation + */ + +#include "sp-gradient.h" +#include "svg/svg-length.h" +#include "sp-linear-gradient-fns.h" + +/** Linear gradient. */ +struct SPLinearGradient : public SPGradient { + SVGLength x1; + SVGLength y1; + SVGLength x2; + SVGLength y2; +}; + +/// The SPLinearGradient vtable. +struct SPLinearGradientClass { + SPGradientClass parent_class; +}; + +#endif /* !SP_LINEAR_GRADIENT_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:encoding=utf-8:textwidth=99 : diff --git a/src/sp-marker-loc.h b/src/sp-marker-loc.h new file mode 100644 index 000000000..1b763f724 --- /dev/null +++ b/src/sp-marker-loc.h @@ -0,0 +1,29 @@ +#ifndef SEEN_SP_MARKER_LOC_H +#define SEEN_SP_MARKER_LOC_H + +/** + * These enums are to allow us to have 4-element arrays that represent a set of marker locations + * (all, start, mid, and end). This allows us to iterate through the array in places where we need + * to do a process across all of the markers, instead of separate code stanzas for each. + */ +enum SPMarkerLoc { + SP_MARKER_LOC, + SP_MARKER_LOC_START, + SP_MARKER_LOC_MID, + SP_MARKER_LOC_END, + SP_MARKER_LOC_QTY +}; + + +#endif /* !SEEN_SP_MARKER_LOC_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 : diff --git a/src/sp-marker.cpp b/src/sp-marker.cpp new file mode 100644 index 000000000..0c4c9215b --- /dev/null +++ b/src/sp-marker.cpp @@ -0,0 +1,639 @@ +#define __SP_MARKER_C__ + +/* + * SVG implementation + * + * Authors: + * Lauris Kaplinski + * + * Copyright (C) 1999-2003 Lauris Kaplinski + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "config.h" + + +#include "libnr/nr-matrix-fns.h" +#include "libnr/nr-matrix-ops.h" +#include "libnr/nr-scale-matrix-ops.h" +#include "libnr/nr-rotate-fns.h" +#include "svg/svg.h" +#include "display/nr-arena-group.h" +#include "xml/repr.h" +#include "attributes.h" +#include "sp-marker.h" + +struct SPMarkerView { + SPMarkerView *next; + unsigned int key; + unsigned int size; + NRArenaItem *items[1]; +}; + +static void sp_marker_class_init (SPMarkerClass *klass); +static void sp_marker_init (SPMarker *marker); + +static void sp_marker_build (SPObject *object, SPDocument *document, Inkscape::XML::Node *repr); +static void sp_marker_release (SPObject *object); +static void sp_marker_set (SPObject *object, unsigned int key, const gchar *value); +static void sp_marker_update (SPObject *object, SPCtx *ctx, guint flags); +static Inkscape::XML::Node *sp_marker_write (SPObject *object, Inkscape::XML::Node *repr, guint flags); + +static NRArenaItem *sp_marker_private_show (SPItem *item, NRArena *arena, unsigned int key, unsigned int flags); +static void sp_marker_private_hide (SPItem *item, unsigned int key); +static void sp_marker_bbox(SPItem const *item, NRRect *bbox, NR::Matrix const &transform, unsigned const flags); +static void sp_marker_print (SPItem *item, SPPrintContext *ctx); + +static void sp_marker_view_remove (SPMarker *marker, SPMarkerView *view, unsigned int destroyitems); + +static SPGroupClass *parent_class; + +GType +sp_marker_get_type (void) +{ + static GType type = 0; + if (!type) { + GTypeInfo info = { + sizeof (SPMarkerClass), + NULL, NULL, + (GClassInitFunc) sp_marker_class_init, + NULL, NULL, + sizeof (SPMarker), + 16, + (GInstanceInitFunc) sp_marker_init, + NULL, /* value_table */ + }; + type = g_type_register_static (SP_TYPE_GROUP, "SPMarker", &info, (GTypeFlags)0); + } + return type; +} + +static void +sp_marker_class_init (SPMarkerClass *klass) +{ + GObjectClass *object_class; + SPObjectClass *sp_object_class; + SPItemClass *sp_item_class; + + object_class = G_OBJECT_CLASS (klass); + sp_object_class = (SPObjectClass *) klass; + sp_item_class = (SPItemClass *) klass; + + parent_class = (SPGroupClass *)g_type_class_ref (SP_TYPE_GROUP); + + sp_object_class->build = sp_marker_build; + sp_object_class->release = sp_marker_release; + sp_object_class->set = sp_marker_set; + sp_object_class->update = sp_marker_update; + sp_object_class->write = sp_marker_write; + + sp_item_class->show = sp_marker_private_show; + sp_item_class->hide = sp_marker_private_hide; + sp_item_class->bbox = sp_marker_bbox; + sp_item_class->print = sp_marker_print; +} + +static void +sp_marker_init (SPMarker *marker) +{ + marker->viewBox_set = FALSE; + + nr_matrix_set_identity (&marker->c2p); +} + +static void +sp_marker_build (SPObject *object, SPDocument *document, Inkscape::XML::Node *repr) +{ + SPGroup *group; + SPMarker *marker; + + group = (SPGroup *) object; + marker = (SPMarker *) object; + + sp_object_read_attr (object, "markerUnits"); + sp_object_read_attr (object, "refX"); + sp_object_read_attr (object, "refY"); + sp_object_read_attr (object, "markerWidth"); + sp_object_read_attr (object, "markerHeight"); + sp_object_read_attr (object, "orient"); + sp_object_read_attr (object, "viewBox"); + sp_object_read_attr (object, "preserveAspectRatio"); + + if (((SPObjectClass *) parent_class)->build) + ((SPObjectClass *) parent_class)->build (object, document, repr); +} + +static void +sp_marker_release (SPObject *object) +{ + SPMarker *marker; + + marker = (SPMarker *) object; + + while (marker->views) { + /* Destroy all NRArenaitems etc. */ + /* Parent class ::hide method */ + ((SPItemClass *) parent_class)->hide ((SPItem *) marker, marker->views->key); + sp_marker_view_remove (marker, marker->views, TRUE); + } + + if (((SPObjectClass *) parent_class)->release) + ((SPObjectClass *) parent_class)->release (object); +} + +static void +sp_marker_set (SPObject *object, unsigned int key, const gchar *value) +{ + SPItem *item; + SPMarker *marker; + + item = SP_ITEM (object); + marker = SP_MARKER (object); + + switch (key) { + case SP_ATTR_MARKERUNITS: + marker->markerUnits_set = FALSE; + marker->markerUnits = SP_MARKER_UNITS_STROKEWIDTH; + if (value) { + if (!strcmp (value, "strokeWidth")) { + marker->markerUnits_set = TRUE; + } else if (!strcmp (value, "userSpaceOnUse")) { + marker->markerUnits = SP_MARKER_UNITS_USERSPACEONUSE; + marker->markerUnits_set = TRUE; + } + } + object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG); + break; + case SP_ATTR_REFX: + marker->refX.readOrUnset(value); + object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_REFY: + marker->refY.readOrUnset(value); + object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_MARKERWIDTH: + marker->markerWidth.readOrUnset(value, SVGLength::NONE, 3.0, 3.0); + object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_MARKERHEIGHT: + marker->markerHeight.readOrUnset(value, SVGLength::NONE, 3.0, 3.0); + object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_ORIENT: + marker->orient_set = FALSE; + marker->orient_auto = FALSE; + marker->orient = 0.0; + if (value) { + if (!strcmp (value, "auto")) { + marker->orient_auto = TRUE; + marker->orient_set = TRUE; + } else if (sp_svg_number_read_f (value, &marker->orient)) { + marker->orient_set = TRUE; + } + } + object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_VIEWBOX: + marker->viewBox_set = FALSE; + if (value) { + double x, y, width, height; + char *eptr; + /* fixme: We have to take original item affine into account */ + /* fixme: Think (Lauris) */ + eptr = (gchar *) value; + x = g_ascii_strtod (eptr, &eptr); + while (*eptr && ((*eptr == ',') || (*eptr == ' '))) eptr++; + y = g_ascii_strtod (eptr, &eptr); + while (*eptr && ((*eptr == ',') || (*eptr == ' '))) eptr++; + width = g_ascii_strtod (eptr, &eptr); + while (*eptr && ((*eptr == ',') || (*eptr == ' '))) eptr++; + height = g_ascii_strtod (eptr, &eptr); + while (*eptr && ((*eptr == ',') || (*eptr == ' '))) eptr++; + if ((width > 0) && (height > 0)) { + /* Set viewbox */ + marker->viewBox.x0 = x; + marker->viewBox.y0 = y; + marker->viewBox.x1 = x + width; + marker->viewBox.y1 = y + height; + marker->viewBox_set = TRUE; + } + } + object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG); + break; + case SP_ATTR_PRESERVEASPECTRATIO: + /* Do setup before, so we can use break to escape */ + marker->aspect_set = FALSE; + marker->aspect_align = SP_ASPECT_NONE; + marker->aspect_clip = SP_ASPECT_MEET; + object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG); + if (value) { + int len; + gchar c[256]; + const gchar *p, *e; + unsigned int align, clip; + p = value; + while (*p && *p == 32) p += 1; + if (!*p) break; + e = p; + while (*e && *e != 32) e += 1; + len = e - p; + if (len > 8) break; + memcpy (c, value, len); + c[len] = 0; + /* Now the actual part */ + if (!strcmp (c, "none")) { + align = SP_ASPECT_NONE; + } else if (!strcmp (c, "xMinYMin")) { + align = SP_ASPECT_XMIN_YMIN; + } else if (!strcmp (c, "xMidYMin")) { + align = SP_ASPECT_XMID_YMIN; + } else if (!strcmp (c, "xMaxYMin")) { + align = SP_ASPECT_XMAX_YMIN; + } else if (!strcmp (c, "xMinYMid")) { + align = SP_ASPECT_XMIN_YMID; + } else if (!strcmp (c, "xMidYMid")) { + align = SP_ASPECT_XMID_YMID; + } else if (!strcmp (c, "xMaxYMin")) { + align = SP_ASPECT_XMAX_YMID; + } else if (!strcmp (c, "xMinYMax")) { + align = SP_ASPECT_XMIN_YMAX; + } else if (!strcmp (c, "xMidYMax")) { + align = SP_ASPECT_XMID_YMAX; + } else if (!strcmp (c, "xMaxYMax")) { + align = SP_ASPECT_XMAX_YMAX; + } else { + break; + } + clip = SP_ASPECT_MEET; + while (*e && *e == 32) e += 1; + if (e) { + if (!strcmp (e, "meet")) { + clip = SP_ASPECT_MEET; + } else if (!strcmp (e, "slice")) { + clip = SP_ASPECT_SLICE; + } else { + break; + } + } + marker->aspect_set = TRUE; + marker->aspect_align = align; + marker->aspect_clip = clip; + } + break; + default: + if (((SPObjectClass *) parent_class)->set) + ((SPObjectClass *) parent_class)->set (object, key, value); + break; + } +} + +/* + * Updating - we are not renderable anyways, so + * we as well cascade with identity transforms + */ + +static void +sp_marker_update (SPObject *object, SPCtx *ctx, guint flags) +{ + SPItem *item; + SPMarker *marker; + SPItemCtx rctx; + NRRect *vb; + double x, y, width, height; + NRMatrix q; + SPMarkerView *v; + + item = SP_ITEM (object); + marker = SP_MARKER (object); + + /* fixme: We have to set up clip here too */ + + /* Copy parent context */ + rctx.ctx = *ctx; + /* Initialize tranformations */ + rctx.i2doc = NR::identity(); + rctx.i2vp = NR::identity(); + /* Set up viewport */ + rctx.vp.x0 = 0.0; + rctx.vp.y0 = 0.0; + rctx.vp.x1 = marker->markerWidth.computed; + rctx.vp.y1 = marker->markerHeight.computed; + + /* Start with identity transform */ + nr_matrix_set_identity (&marker->c2p); + + /* Viewbox is always present, either implicitly or explicitly */ + if (marker->viewBox_set) { + vb = &marker->viewBox; + } else { + vb = &rctx.vp; + } + /* Now set up viewbox transformation */ + /* Determine actual viewbox in viewport coordinates */ + if (marker->aspect_align == SP_ASPECT_NONE) { + x = 0.0; + y = 0.0; + width = rctx.vp.x1 - rctx.vp.x0; + height = rctx.vp.y1 - rctx.vp.y0; + } else { + double scalex, scaley, scale; + /* Things are getting interesting */ + scalex = (rctx.vp.x1 - rctx.vp.x0) / (vb->x1 - vb->x0); + scaley = (rctx.vp.y1 - rctx.vp.y0) / (vb->y1 - vb->y0); + scale = (marker->aspect_clip == SP_ASPECT_MEET) ? MIN (scalex, scaley) : MAX (scalex, scaley); + width = (vb->x1 - vb->x0) * scale; + height = (vb->y1 - vb->y0) * scale; + /* Now place viewbox to requested position */ + switch (marker->aspect_align) { + case SP_ASPECT_XMIN_YMIN: + x = 0.0; + y = 0.0; + break; + case SP_ASPECT_XMID_YMIN: + x = 0.5 * ((rctx.vp.x1 - rctx.vp.x0) - width); + y = 0.0; + break; + case SP_ASPECT_XMAX_YMIN: + x = 1.0 * ((rctx.vp.x1 - rctx.vp.x0) - width); + y = 0.0; + break; + case SP_ASPECT_XMIN_YMID: + x = 0.0; + y = 0.5 * ((rctx.vp.y1 - rctx.vp.y0) - height); + break; + case SP_ASPECT_XMID_YMID: + x = 0.5 * ((rctx.vp.x1 - rctx.vp.x0) - width); + y = 0.5 * ((rctx.vp.y1 - rctx.vp.y0) - height); + break; + case SP_ASPECT_XMAX_YMID: + x = 1.0 * ((rctx.vp.x1 - rctx.vp.x0) - width); + y = 0.5 * ((rctx.vp.y1 - rctx.vp.y0) - height); + break; + case SP_ASPECT_XMIN_YMAX: + x = 0.0; + y = 1.0 * ((rctx.vp.y1 - rctx.vp.y0) - height); + break; + case SP_ASPECT_XMID_YMAX: + x = 0.5 * ((rctx.vp.x1 - rctx.vp.x0) - width); + y = 1.0 * ((rctx.vp.y1 - rctx.vp.y0) - height); + break; + case SP_ASPECT_XMAX_YMAX: + x = 1.0 * ((rctx.vp.x1 - rctx.vp.x0) - width); + y = 1.0 * ((rctx.vp.y1 - rctx.vp.y0) - height); + break; + default: + x = 0.0; + y = 0.0; + break; + } + } + /* Compose additional transformation from scale and position */ + q.c[0] = width / (vb->x1 - vb->x0); + q.c[1] = 0.0; + q.c[2] = 0.0; + q.c[3] = height / (vb->y1 - vb->y0); + q.c[4] = -vb->x0 * q.c[0] + x; + q.c[5] = -vb->y0 * q.c[3] + y; + /* Append viewbox transformation */ + nr_matrix_multiply (&marker->c2p, &q, &marker->c2p); + + + /* Append reference translation */ + /* fixme: lala (Lauris) */ + nr_matrix_set_translate (&q, -marker->refX.computed, -marker->refY.computed); + nr_matrix_multiply (&marker->c2p, &q, &marker->c2p); + + rctx.i2doc = marker->c2p * rctx.i2doc; + + /* If viewBox is set reinitialize child viewport */ + /* Otherwise it already correct */ + if (marker->viewBox_set) { + rctx.vp.x0 = marker->viewBox.x0; + rctx.vp.y0 = marker->viewBox.y0; + rctx.vp.x1 = marker->viewBox.x1; + rctx.vp.y1 = marker->viewBox.y1; + rctx.i2vp = NR::identity(); + } + + /* And invoke parent method */ + if (((SPObjectClass *) (parent_class))->update) + ((SPObjectClass *) (parent_class))->update (object, (SPCtx *) &rctx, flags); + + /* As last step set additional transform of arena group */ + for (v = marker->views; v != NULL; v = v->next) { + for (unsigned i = 0 ; i < v->size ; i++) { + if (v->items[i]) { + nr_arena_group_set_child_transform(NR_ARENA_GROUP(v->items[i]), &marker->c2p); + } + } + } +} + +static Inkscape::XML::Node * +sp_marker_write (SPObject *object, Inkscape::XML::Node *repr, guint flags) +{ + SPMarker *marker; + + marker = SP_MARKER (object); + + if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { + repr = sp_repr_new ("svg:marker"); + } + + if (marker->markerUnits_set) { + if (marker->markerUnits == SP_MARKER_UNITS_STROKEWIDTH) { + repr->setAttribute("markerUnits", "strokeWidth"); + } else { + repr->setAttribute("markerUnits", "userSpaceOnUse"); + } + } else { + repr->setAttribute("markerUnits", NULL); + } + if (marker->refX._set) { + sp_repr_set_svg_double(repr, "refX", marker->refX.computed); + } else { + repr->setAttribute("refX", NULL); + } + if (marker->refY._set) { + sp_repr_set_svg_double (repr, "refY", marker->refY.computed); + } else { + repr->setAttribute("refY", NULL); + } + if (marker->markerWidth._set) { + sp_repr_set_svg_double (repr, "markerWidth", marker->markerWidth.computed); + } else { + repr->setAttribute("markerWidth", NULL); + } + if (marker->markerHeight._set) { + sp_repr_set_svg_double (repr, "markerHeight", marker->markerHeight.computed); + } else { + repr->setAttribute("markerHeight", NULL); + } + if (marker->orient_set) { + if (marker->orient_auto) { + repr->setAttribute("orient", "auto"); + } else { + sp_repr_set_css_double(repr, "orient", marker->orient); + } + } else { + repr->setAttribute("orient", NULL); + } + /* fixme: */ + repr->setAttribute("viewBox", object->repr->attribute("viewBox")); + repr->setAttribute("preserveAspectRatio", object->repr->attribute("preserveAspectRatio")); + + if (((SPObjectClass *) (parent_class))->write) + ((SPObjectClass *) (parent_class))->write (object, repr, flags); + + return repr; +} + +static NRArenaItem * +sp_marker_private_show (SPItem *item, NRArena *arena, unsigned int key, unsigned int flags) +{ + /* Break propagation */ + return NULL; +} + +static void +sp_marker_private_hide (SPItem *item, unsigned int key) +{ + /* Break propagation */ +} + +static void +sp_marker_bbox(SPItem const *, NRRect *, NR::Matrix const &, unsigned const) +{ + /* Break propagation */ +} + +static void +sp_marker_print (SPItem *item, SPPrintContext *ctx) +{ + /* Break propagation */ +} + +/* fixme: Remove link if zero-sized (Lauris) */ + +/** +* First of all, removes any SPMarkerViews that a marker has with a specific key. +* Set up the NRArenaItem array's size in the specified SPMarker's SPMarkerView. +* \param marker Marker to create views in. +* \param key Key to give each SPMarkerView. +* \param size Number of NRArenaItems to put in the SPMarkerView. +*/ +void +sp_marker_show_dimension (SPMarker *marker, unsigned int key, unsigned int size) +{ + SPMarkerView *view; + unsigned int i; + + for (view = marker->views; view != NULL; view = view->next) { + if (view->key == key) break; + } + if (view && (view->size != size)) { + /* Free old view and allocate new */ + /* Parent class ::hide method */ + ((SPItemClass *) parent_class)->hide ((SPItem *) marker, key); + sp_marker_view_remove (marker, view, TRUE); + view = NULL; + } + if (!view) { + view = (SPMarkerView *)malloc (sizeof (SPMarkerView) + (size) * sizeof (NRArenaItem *)); + for (i = 0; i < size; i++) view->items[i] = NULL; + view->next = marker->views; + marker->views = view; + view->key = key; + view->size = size; + } +} + +NRArenaItem * +sp_marker_show_instance (SPMarker *marker, NRArenaItem *parent, + unsigned int key, unsigned int pos, + NR::Matrix const &base, float linewidth) +{ + for (SPMarkerView *v = marker->views; v != NULL; v = v->next) { + if (v->key == key) { + if (pos >= v->size) { + return NULL; + } + if (!v->items[pos]) { + /* Parent class ::show method */ + v->items[pos] = ((SPItemClass *) parent_class)->show ((SPItem *) marker, + parent->arena, key, + SP_ITEM_REFERENCE_FLAGS); + if (v->items[pos]) { + /* fixme: Position (Lauris) */ + nr_arena_item_add_child (parent, v->items[pos], NULL); + /* nr_arena_item_unref (v->items[pos]); */ + nr_arena_group_set_child_transform((NRArenaGroup *) v->items[pos], &marker->c2p); + } + } + if (v->items[pos]) { + NR::Matrix m; + if (marker->orient_auto) { + m = base; + } else { + /* fixme: Orient units (Lauris) */ + m = NR::Matrix(rotate_degrees(marker->orient)); + m *= get_translation(base); + } + if (marker->markerUnits == SP_MARKER_UNITS_STROKEWIDTH) { + m = NR::scale(linewidth) * m; + } + + nr_arena_item_set_transform(v->items[pos], m); + } + return v->items[pos]; + } + } + + return NULL; +} + +/* This replaces SPItem implementation because we have own views */ + +/** +* \param key SPMarkerView key to hide. +*/ +void +sp_marker_hide (SPMarker *marker, unsigned int key) +{ + SPMarkerView *v; + + v = marker->views; + while (v != NULL) { + SPMarkerView *next; + next = v->next; + if (v->key == key) { + /* Parent class ::hide method */ + ((SPItemClass *) parent_class)->hide ((SPItem *) marker, key); + sp_marker_view_remove (marker, v, TRUE); + return; + } + v = next; + } +} + +static void +sp_marker_view_remove (SPMarker *marker, SPMarkerView *view, unsigned int destroyitems) +{ + unsigned int i; + if (view == marker->views) { + marker->views = view->next; + } else { + SPMarkerView *v; + for (v = marker->views; v->next != view; v = v->next) if (!v->next) return; + v->next = view->next; + } + if (destroyitems) { + for (i = 0; i < view->size; i++) { + /* We have to walk through the whole array because there may be hidden items */ + if (view->items[i]) nr_arena_item_unref (view->items[i]); + } + } + g_free (view); +} diff --git a/src/sp-marker.h b/src/sp-marker.h new file mode 100644 index 000000000..1fba52d36 --- /dev/null +++ b/src/sp-marker.h @@ -0,0 +1,93 @@ +#ifndef __SP_MARKER_H__ +#define __SP_MARKER_H__ + +/* + * SVG implementation + * + * Authors: + * Lauris Kaplinski + * + * Copyright (C) 1999-2003 Lauris Kaplinski + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +/* + * This is quite similar in logic to + * Maybe we should merge them somehow (Lauris) + */ + +#define SP_TYPE_MARKER (sp_marker_get_type ()) +#define SP_MARKER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), SP_TYPE_MARKER, SPMarker)) +#define SP_IS_MARKER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), SP_TYPE_MARKER)) + +class SPMarker; +class SPMarkerClass; +class SPMarkerView; + +#include +#include +#include "svg/svg-length.h" +#include "enums.h" +#include "sp-item-group.h" +#include "sp-marker-loc.h" +#include "uri-references.h" + +struct SPMarker : public SPGroup { + /* units */ + unsigned int markerUnits_set : 1; + unsigned int markerUnits : 1; + + /* reference point */ + SVGLength refX; + SVGLength refY; + + /* dimensions */ + SVGLength markerWidth; + SVGLength markerHeight; + + /* orient */ + unsigned int orient_set : 1; + unsigned int orient_auto : 1; + float orient; + + /* viewBox; */ + unsigned int viewBox_set : 1; + NRRect viewBox; + + /* preserveAspectRatio */ + unsigned int aspect_set : 1; + unsigned int aspect_align : 4; + unsigned int aspect_clip : 1; + + /* Child to parent additional transform */ + NRMatrix c2p; + + /* Private views */ + SPMarkerView *views; +}; + +struct SPMarkerClass { + SPGroupClass parent_class; +}; + +GType sp_marker_get_type (void); + +class SPMarkerReference : public Inkscape::URIReference { + SPMarkerReference(SPObject *obj) : URIReference(obj) {} + SPMarker *getObject() const { + return (SPMarker *)URIReference::getObject(); + } +protected: + virtual bool _acceptObject(SPObject *obj) const { + return SP_IS_MARKER(obj); + } +}; + +void sp_marker_show_dimension (SPMarker *marker, unsigned int key, unsigned int size); +NRArenaItem *sp_marker_show_instance (SPMarker *marker, NRArenaItem *parent, + unsigned int key, unsigned int pos, + NR::Matrix const &base, float linewidth); +void sp_marker_hide (SPMarker *marker, unsigned int key); + +#endif diff --git a/src/sp-mask.cpp b/src/sp-mask.cpp new file mode 100644 index 000000000..1f2d531b7 --- /dev/null +++ b/src/sp-mask.cpp @@ -0,0 +1,375 @@ +#define __SP_MASK_C__ + +/* + * SVG implementation + * + * Authors: + * Lauris Kaplinski + * + * Copyright (C) 2003 authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + + +#include "display/nr-arena.h" +#include "display/nr-arena-group.h" +#include + +#include "enums.h" +#include "attributes.h" +#include "document.h" +#include "sp-item.h" + +#include "sp-mask.h" + +struct SPMaskView { + SPMaskView *next; + unsigned int key; + NRArenaItem *arenaitem; + NRRect bbox; +}; + +static void sp_mask_class_init (SPMaskClass *klass); +static void sp_mask_init (SPMask *mask); + +static void sp_mask_build (SPObject *object, SPDocument *document, Inkscape::XML::Node *repr); +static void sp_mask_release (SPObject * object); +static void sp_mask_set (SPObject *object, unsigned int key, const gchar *value); +static void sp_mask_child_added (SPObject *object, Inkscape::XML::Node *child, Inkscape::XML::Node *ref); +static void sp_mask_update (SPObject *object, SPCtx *ctx, guint flags); +static void sp_mask_modified (SPObject *object, guint flags); +static Inkscape::XML::Node *sp_mask_write (SPObject *object, Inkscape::XML::Node *repr, guint flags); + +SPMaskView *sp_mask_view_new_prepend (SPMaskView *list, unsigned int key, NRArenaItem *arenaitem); +SPMaskView *sp_mask_view_list_remove (SPMaskView *list, SPMaskView *view); + +static SPObjectGroupClass *parent_class; + +GType +sp_mask_get_type (void) +{ + static GType type = 0; + if (!type) { + GTypeInfo info = { + sizeof (SPMaskClass), + NULL, NULL, + (GClassInitFunc) sp_mask_class_init, + NULL, NULL, + sizeof (SPMask), + 16, + (GInstanceInitFunc) sp_mask_init, + NULL, /* value_table */ + }; + type = g_type_register_static (SP_TYPE_OBJECTGROUP, "SPMask", &info, (GTypeFlags)0); + } + return type; +} + +static void +sp_mask_class_init (SPMaskClass *klass) +{ + parent_class = (SPObjectGroupClass*) g_type_class_ref (SP_TYPE_OBJECTGROUP); + + SPObjectClass *sp_object_class = (SPObjectClass *) klass; + sp_object_class->build = sp_mask_build; + sp_object_class->release = sp_mask_release; + sp_object_class->set = sp_mask_set; + sp_object_class->child_added = sp_mask_child_added; + sp_object_class->update = sp_mask_update; + sp_object_class->modified = sp_mask_modified; + sp_object_class->write = sp_mask_write; +} + +static void +sp_mask_init (SPMask *mask) +{ + mask->maskUnits_set = FALSE; + mask->maskUnits = SP_CONTENT_UNITS_OBJECTBOUNDINGBOX; + + mask->maskUnits_set = FALSE; + mask->maskUnits = SP_CONTENT_UNITS_USERSPACEONUSE; + + mask->display = NULL; +} + +static void +sp_mask_build (SPObject *object, SPDocument *document, Inkscape::XML::Node *repr) +{ + if (((SPObjectClass *) parent_class)->build) { + ((SPObjectClass *) parent_class)->build (object, document, repr); + } + + sp_object_read_attr (object, "maskUnits"); + sp_object_read_attr (object, "maskContentUnits"); + + /* Register ourselves */ + sp_document_add_resource (document, "mask", object); +} + +static void +sp_mask_release (SPObject * object) +{ + if (SP_OBJECT_DOCUMENT (object)) { + /* Unregister ourselves */ + sp_document_remove_resource (SP_OBJECT_DOCUMENT (object), "mask", object); + } + + SPMask *cp = SP_MASK (object); + while (cp->display) { + /* We simply unref and let item to manage this in handler */ + cp->display = sp_mask_view_list_remove (cp->display, cp->display); + } + + if (((SPObjectClass *) (parent_class))->release) { + ((SPObjectClass *) parent_class)->release (object); + } +} + +static void +sp_mask_set (SPObject *object, unsigned int key, const gchar *value) +{ + SPMask *mask = SP_MASK (object); + + switch (key) { + case SP_ATTR_MASKUNITS: + mask->maskUnits = SP_CONTENT_UNITS_OBJECTBOUNDINGBOX; + mask->maskUnits_set = FALSE; + if (value) { + if (!strcmp (value, "userSpaceOnUse")) { + mask->maskUnits = SP_CONTENT_UNITS_USERSPACEONUSE; + mask->maskUnits_set = TRUE; + } else if (!strcmp (value, "objectBoundingBox")) { + mask->maskUnits_set = TRUE; + } + } + object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_MASKCONTENTUNITS: + mask->maskContentUnits = SP_CONTENT_UNITS_USERSPACEONUSE; + mask->maskContentUnits_set = FALSE; + if (value) { + if (!strcmp (value, "userSpaceOnUse")) { + mask->maskContentUnits_set = TRUE; + } else if (!strcmp (value, "objectBoundingBox")) { + mask->maskContentUnits = SP_CONTENT_UNITS_OBJECTBOUNDINGBOX; + mask->maskContentUnits_set = TRUE; + } + } + object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + break; + default: + if (((SPObjectClass *) parent_class)->set) + ((SPObjectClass *) parent_class)->set (object, key, value); + break; + } +} + +static void +sp_mask_child_added (SPObject *object, Inkscape::XML::Node *child, Inkscape::XML::Node *ref) +{ + /* Invoke SPObjectGroup implementation */ + ((SPObjectClass *) (parent_class))->child_added (object, child, ref); + + /* Show new object */ + SPObject *ochild = SP_OBJECT_DOCUMENT (object)->getObjectByRepr(child); + if (SP_IS_ITEM (ochild)) { + SPMask *cp = SP_MASK (object); + for (SPMaskView *v = cp->display; v != NULL; v = v->next) { + NRArenaItem *ac = sp_item_invoke_show (SP_ITEM (ochild), + NR_ARENA_ITEM_ARENA (v->arenaitem), + v->key, + SP_ITEM_REFERENCE_FLAGS); + if (ac) { + nr_arena_item_add_child (v->arenaitem, ac, NULL); + nr_arena_item_unref (ac); + } + } + } +} + +static void +sp_mask_update (SPObject *object, SPCtx *ctx, guint flags) +{ + if (flags & SP_OBJECT_MODIFIED_FLAG) { + flags |= SP_OBJECT_PARENT_MODIFIED_FLAG; + } + + flags &= SP_OBJECT_MODIFIED_CASCADE; + + SPObjectGroup *og = SP_OBJECTGROUP (object); + GSList *l = NULL; + for (SPObject *child = sp_object_first_child(SP_OBJECT(og)); child != NULL; child = SP_OBJECT_NEXT(child)) { + g_object_ref (G_OBJECT (child)); + l = g_slist_prepend (l, child); + } + l = g_slist_reverse (l); + while (l) { + SPObject *child = SP_OBJECT (l->data); + l = g_slist_remove (l, child); + if (flags || (child->uflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { + child->updateDisplay(ctx, flags); + } + g_object_unref (G_OBJECT (child)); + } + + SPMask *mask = SP_MASK (object); + for (SPMaskView *v = mask->display; v != NULL; v = v->next) { + if (mask->maskContentUnits == SP_CONTENT_UNITS_OBJECTBOUNDINGBOX) { + NRMatrix t; + nr_matrix_set_scale (&t, v->bbox.x1 - v->bbox.x0, v->bbox.y1 - v->bbox.y0); + t.c[4] = v->bbox.x0; + t.c[5] = v->bbox.y0; + nr_arena_group_set_child_transform (NR_ARENA_GROUP (v->arenaitem), &t); + } else { + nr_arena_group_set_child_transform (NR_ARENA_GROUP (v->arenaitem), NULL); + } + } +} + +static void +sp_mask_modified (SPObject *object, guint flags) +{ + if (flags & SP_OBJECT_MODIFIED_FLAG) { + flags |= SP_OBJECT_PARENT_MODIFIED_FLAG; + } + + flags &= SP_OBJECT_MODIFIED_CASCADE; + + SPObjectGroup *og = SP_OBJECTGROUP (object); + GSList *l = NULL; + for (SPObject *child = sp_object_first_child(SP_OBJECT(og)); child != NULL; child = SP_OBJECT_NEXT(child)) { + g_object_ref (G_OBJECT (child)); + l = g_slist_prepend (l, child); + } + l = g_slist_reverse (l); + while (l) { + SPObject *child = SP_OBJECT (l->data); + l = g_slist_remove (l, child); + if (flags || (child->mflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { + child->emitModified(flags); + } + g_object_unref (G_OBJECT (child)); + } +} + +static Inkscape::XML::Node * +sp_mask_write (SPObject *object, Inkscape::XML::Node *repr, guint flags) +{ + if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { + repr = sp_repr_new ("svg:mask"); + } + + if (((SPObjectClass *) (parent_class))->write) + ((SPObjectClass *) (parent_class))->write (object, repr, flags); + + return repr; +} + +NRArenaItem * +sp_mask_show (SPMask *mask, NRArena *arena, unsigned int key) +{ + g_return_val_if_fail (mask != NULL, NULL); + g_return_val_if_fail (SP_IS_MASK (mask), NULL); + g_return_val_if_fail (arena != NULL, NULL); + g_return_val_if_fail (NR_IS_ARENA (arena), NULL); + + NRArenaItem *ai = NRArenaGroup::create(arena); + mask->display = sp_mask_view_new_prepend (mask->display, key, ai); + + for (SPObject *child = sp_object_first_child(SP_OBJECT(mask)) ; child != NULL; child = SP_OBJECT_NEXT(child)) { + if (SP_IS_ITEM (child)) { + NRArenaItem *ac = sp_item_invoke_show (SP_ITEM (child), arena, key, SP_ITEM_REFERENCE_FLAGS); + if (ac) { + /* The order is not important in mask */ + nr_arena_item_add_child (ai, ac, NULL); + nr_arena_item_unref (ac); + } + } + } + + if (mask->maskContentUnits == SP_CONTENT_UNITS_OBJECTBOUNDINGBOX) { + NRMatrix t; + nr_matrix_set_scale (&t, mask->display->bbox.x1 - mask->display->bbox.x0, mask->display->bbox.y1 - mask->display->bbox.y0); + t.c[4] = mask->display->bbox.x0; + t.c[5] = mask->display->bbox.y0; + nr_arena_group_set_child_transform (NR_ARENA_GROUP (ai), &t); + } + + return ai; +} + +void +sp_mask_hide (SPMask *cp, unsigned int key) +{ + g_return_if_fail (cp != NULL); + g_return_if_fail (SP_IS_MASK (cp)); + + for (SPObject *child = sp_object_first_child(SP_OBJECT(cp)); child != NULL; child = SP_OBJECT_NEXT(child)) { + if (SP_IS_ITEM (child)) { + sp_item_invoke_hide (SP_ITEM (child), key); + } + } + + for (SPMaskView *v = cp->display; v != NULL; v = v->next) { + if (v->key == key) { + /* We simply unref and let item to manage this in handler */ + cp->display = sp_mask_view_list_remove (cp->display, v); + return; + } + } + + g_assert_not_reached (); +} + +void +sp_mask_set_bbox (SPMask *mask, unsigned int key, NRRect *bbox) +{ + for (SPMaskView *v = mask->display; v != NULL; v = v->next) { + if (v->key == key) { + if (!NR_DF_TEST_CLOSE (v->bbox.x0, bbox->x0, NR_EPSILON) || + !NR_DF_TEST_CLOSE (v->bbox.y0, bbox->y0, NR_EPSILON) || + !NR_DF_TEST_CLOSE (v->bbox.x1, bbox->x1, NR_EPSILON) || + !NR_DF_TEST_CLOSE (v->bbox.y1, bbox->y1, NR_EPSILON)) { + v->bbox = *bbox; + SP_OBJECT(mask)->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + } + break; + } + } +} + +/* Mask views */ + +SPMaskView * +sp_mask_view_new_prepend (SPMaskView *list, unsigned int key, NRArenaItem *arenaitem) +{ + SPMaskView *new_mask_view = g_new (SPMaskView, 1); + + new_mask_view->next = list; + new_mask_view->key = key; + new_mask_view->arenaitem = nr_arena_item_ref(arenaitem); + new_mask_view->bbox.x0 = new_mask_view->bbox.x1 = 0.0; + new_mask_view->bbox.y0 = new_mask_view->bbox.y1 = 0.0; + + return new_mask_view; +} + +SPMaskView * +sp_mask_view_list_remove (SPMaskView *list, SPMaskView *view) +{ + if (view == list) { + list = list->next; + } else { + SPMaskView *prev; + prev = list; + while (prev->next != view) prev = prev->next; + prev->next = view->next; + } + + nr_arena_item_unref (view->arenaitem); + g_free (view); + + return list; +} + diff --git a/src/sp-mask.h b/src/sp-mask.h new file mode 100644 index 000000000..23239f55d --- /dev/null +++ b/src/sp-mask.h @@ -0,0 +1,63 @@ +#ifndef __SP_MASK_H__ +#define __SP_MASK_H__ + +/* + * SVG implementation + * + * Authors: + * Lauris Kaplinski + * + * Copyright (C) 2003 authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#define SP_TYPE_MASK (sp_mask_get_type ()) +#define SP_MASK(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SP_TYPE_MASK, SPMask)) +#define SP_MASK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SP_TYPE_MASK, SPMaskClass)) +#define SP_IS_MASK(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_MASK)) +#define SP_IS_MASK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SP_TYPE_MASK)) + +class SPMask; +class SPMaskClass; +class SPMaskView; + +#include "display/nr-arena-forward.h" +#include "libnr/nr-forward.h" +#include "sp-object-group.h" +#include "uri-references.h" + +struct SPMask : public SPObjectGroup { + unsigned int maskUnits_set : 1; + unsigned int maskUnits : 1; + + unsigned int maskContentUnits_set : 1; + unsigned int maskContentUnits : 1; + + SPMaskView *display; +}; + +struct SPMaskClass { + SPObjectGroupClass parent_class; +}; + +GType sp_mask_get_type (void); + +class SPMaskReference : public Inkscape::URIReference { +public: + SPMaskReference(SPObject *obj) : URIReference(obj) {} + SPMask *getObject() const { + return (SPMask *)URIReference::getObject(); + } +protected: + virtual bool _acceptObject(SPObject *obj) const { + return SP_IS_MASK(obj); + } +}; + +NRArenaItem *sp_mask_show (SPMask *mask, NRArena *arena, unsigned int key); +void sp_mask_hide (SPMask *mask, unsigned int key); + +void sp_mask_set_bbox (SPMask *mask, unsigned int key, NRRect *bbox); + +#endif diff --git a/src/sp-metadata.cpp b/src/sp-metadata.cpp new file mode 100644 index 000000000..0f4b1fb1d --- /dev/null +++ b/src/sp-metadata.cpp @@ -0,0 +1,223 @@ +#define __SP_METADATA_C__ + +/* + * SVG implementation + * + * Authors: + * Kees Cook + * + * Copyright (C) 2004 Kees Cook + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "sp-metadata.h" +#include "xml/node-iterators.h" +#include "document.h" + +#include "sp-item-group.h" + +#define noDEBUG_METADATA +#ifdef DEBUG_METADATA +# define debug(f, a...) { g_print("%s(%d) %s:", \ + __FILE__,__LINE__,__FUNCTION__); \ + g_print(f, ## a); \ + g_print("\n"); \ + } +#else +# define debug(f, a...) /**/ +#endif + +/* Metadata base class */ + +static void sp_metadata_class_init (SPMetadataClass *klass); +static void sp_metadata_init (SPMetadata *metadata); + +static void sp_metadata_build (SPObject * object, SPDocument * document, Inkscape::XML::Node * repr); +static void sp_metadata_release (SPObject *object); +static void sp_metadata_set (SPObject *object, unsigned int key, const gchar *value); +static void sp_metadata_update(SPObject *object, SPCtx *ctx, guint flags); +static Inkscape::XML::Node *sp_metadata_write(SPObject *object, Inkscape::XML::Node *repr, guint flags); + +static SPObjectClass *metadata_parent_class; + +GType +sp_metadata_get_type (void) +{ + static GType metadata_type = 0; + + if (!metadata_type) { + GTypeInfo metadata_info = { + sizeof (SPMetadataClass), + NULL, NULL, + (GClassInitFunc) sp_metadata_class_init, + NULL, NULL, + sizeof (SPMetadata), + 16, + (GInstanceInitFunc) sp_metadata_init, + NULL, /* value_table */ + }; + metadata_type = g_type_register_static (SP_TYPE_OBJECT, "SPMetadata", &metadata_info, (GTypeFlags)0); + } + return metadata_type; +} + +static void +sp_metadata_class_init (SPMetadataClass *klass) +{ + //GObjectClass *gobject_class = (GObjectClass *)klass; + SPObjectClass *sp_object_class = (SPObjectClass *)klass; + + metadata_parent_class = (SPObjectClass*)g_type_class_peek_parent (klass); + + sp_object_class->build = sp_metadata_build; + sp_object_class->release = sp_metadata_release; + sp_object_class->write = sp_metadata_write; + sp_object_class->set = sp_metadata_set; + sp_object_class->update = sp_metadata_update; +} + +static void +sp_metadata_init (SPMetadata *metadata) +{ + debug("0x%08x",(unsigned int)metadata); +} + +namespace { + +void strip_ids_recursively(Inkscape::XML::Node *node) { + using Inkscape::XML::NodeSiblingIterator; + if ( node->type() == Inkscape::XML::ELEMENT_NODE ) { + node->setAttribute("id", NULL); + } + for ( NodeSiblingIterator iter=node->firstChild() ; iter ; ++iter ) { + strip_ids_recursively(iter); + } +} + +} + +/* + * \brief Reads the Inkscape::XML::Node, and initializes SPMetadata variables. + * For this to get called, our name must be associated with + * a repr via "sp_object_type_register". Best done through + * sp-object-repr.cpp's repr_name_entries array. + */ +static void +sp_metadata_build (SPObject *object, SPDocument *document, Inkscape::XML::Node *repr) +{ + using Inkscape::XML::NodeSiblingIterator; + + debug("0x%08x",(unsigned int)object); + + /* clean up our mess from earlier versions; elements under rdf:RDF should not + * have id= attributes... */ + static GQuark const rdf_root_name=g_quark_from_static_string("rdf:RDF"); + for ( NodeSiblingIterator iter=repr->firstChild() ; iter ; ++iter ) { + if ( (GQuark)iter->code() == rdf_root_name ) { + strip_ids_recursively(iter); + } + } + + if (((SPObjectClass *) metadata_parent_class)->build) + ((SPObjectClass *) metadata_parent_class)->build (object, document, repr); +} + +/* + * \brief Drops any allocated memory + */ +static void +sp_metadata_release (SPObject *object) +{ + debug("0x%08x",(unsigned int)object); + + /* handle ourself */ + + if (((SPObjectClass *) metadata_parent_class)->release) + ((SPObjectClass *) metadata_parent_class)->release (object); +} + +/* + * \brief Sets a specific value in the SPMetadata + */ +static void +sp_metadata_set (SPObject *object, unsigned int key, const gchar *value) +{ + debug("0x%08x %s(%u): '%s'",(unsigned int)object, + sp_attribute_name(key),key,value); + SPMetadata * metadata; + + metadata = SP_METADATA (object); + + /* see if any parents need this value */ + if (((SPObjectClass *) metadata_parent_class)->set) + ((SPObjectClass *) metadata_parent_class)->set (object, key, value); +} + +/* + * \brief Receives update notifications + */ +static void +sp_metadata_update(SPObject *object, SPCtx *ctx, guint flags) +{ + debug("0x%08x",(unsigned int)object); + //SPMetadata *metadata = SP_METADATA(object); + + if (flags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG | + SP_OBJECT_VIEWPORT_MODIFIED_FLAG)) { + + /* do something? */ + + } + + if (((SPObjectClass *) metadata_parent_class)->update) + ((SPObjectClass *) metadata_parent_class)->update(object, ctx, flags); +} + +/* + * \brief Writes it's settings to an incoming repr object, if any + */ +static Inkscape::XML::Node * +sp_metadata_write(SPObject *object, Inkscape::XML::Node *repr, guint flags) +{ + debug("0x%08x",(unsigned int)object); + //SPMetadata *metadata = SP_METADATA(object); + + // only create a repr when we're writing out an Inkscape SVG + if ( flags & SP_OBJECT_WRITE_EXT && repr != SP_OBJECT_REPR(object) ) { + if (repr) { + repr->mergeFrom(SP_OBJECT_REPR (object), "id"); + } else { + repr = SP_OBJECT_REPR (object)->duplicate(); + } + } + + if (((SPObjectClass *) metadata_parent_class)->write) + ((SPObjectClass *) metadata_parent_class)->write(object, repr, flags); + + return repr; +} + +/* + * \brief Retrieves the metadata object associated with a document + */ +SPMetadata * +sp_document_metadata (SPDocument *document) +{ + SPObject *nv; + + g_return_val_if_fail (document != NULL, NULL); + + nv = sp_item_group_get_child_by_name ((SPGroup *) document->root, NULL, + "metadata"); + g_assert (nv != NULL); + + return (SPMetadata *)nv; +} + + +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/sp-metadata.h b/src/sp-metadata.h new file mode 100644 index 000000000..82b7c4fc5 --- /dev/null +++ b/src/sp-metadata.h @@ -0,0 +1,39 @@ +#ifndef __SP_METADATA_H__ +#define __SP_METADATA_H__ + +/* + * SVG implementation + * + * Authors: + * Kees Cook + * + * Copyright (C) 2004 Kees Cook + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "sp-object.h" + + +/* Metadata base class */ + +#define SP_TYPE_METADATA (sp_metadata_get_type ()) +#define SP_METADATA(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), SP_TYPE_METADATA, SPMetadata)) +#define SP_IS_METADATA(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), SP_TYPE_METADATA)) + +class SPMetadata; +class SPMetadataClass; + +struct SPMetadata : public SPObject { +}; + +struct SPMetadataClass { + SPObjectClass parent_class; +}; + +GType sp_metadata_get_type (void); + +SPMetadata * sp_document_metadata (SPDocument *document); + +#endif +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/sp-metric.h b/src/sp-metric.h new file mode 100644 index 000000000..76db44710 --- /dev/null +++ b/src/sp-metric.h @@ -0,0 +1,26 @@ +#ifndef INKSCAPE_SP_METRIC_H +#define INKSCAPE_SP_METRIC_H + +/** Known metrics so far. (I don't know why this doesn't include pica.) */ +enum SPMetric { + NONE, + SP_MM, + SP_CM, + SP_IN, + SP_PT, + SP_PX, + SP_M +}; + +#endif /* !INKSCAPE_SP_METRIC_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:encoding=utf-8:textwidth=99 : diff --git a/src/sp-metrics.cpp b/src/sp-metrics.cpp new file mode 100644 index 000000000..27d65422f --- /dev/null +++ b/src/sp-metrics.cpp @@ -0,0 +1,108 @@ +#include "sp-metrics.h" +#include "unit-constants.h" + +/* + * SPMetric handling and stuff + * I hope this will be usefull :-) + */ + +gdouble +sp_absolute_metric_to_metric (gdouble length_src, const SPMetric metric_src, const SPMetric metric_dst) +{ + gdouble src = 1; + gdouble dst = 1; + + switch (metric_src) { + case SP_M: + src = M_PER_IN; + break; + case SP_MM: + src = MM_PER_IN; + break; + case SP_CM: + src = CM_PER_IN; + break; + case SP_IN: + src = IN_PER_IN; + break; + case SP_PT: + src = PT_PER_IN; + break; + case SP_PX: + src = PX_PER_IN; + break; + case NONE: + src = 1; + break; + } + + switch (metric_dst) { + case SP_M: + dst = M_PER_IN; + break; + case SP_MM: + dst = MM_PER_IN; + break; + case SP_CM: + dst = CM_PER_IN; + break; + case SP_IN: + dst = IN_PER_IN; + break; + case SP_PT: + dst = PT_PER_IN; + break; + case SP_PX: + dst = PX_PER_IN; + break; + case NONE: + dst = 1; + break; + } + + return length_src * (dst/src); +} + +/** + * Create a human-readable string suitable for status-bar display. + */ +GString * +sp_metric_to_metric_string(gdouble const length, + SPMetric const metric_src, SPMetric const metric_dst, + gboolean const m) +{ + gdouble const len = sp_absolute_metric_to_metric(length, metric_src, metric_dst); + GString *str = g_string_new(""); + g_string_printf(str, "%0.02f", len); + /* We need a fixed number of fractional digits, because otherwise the live statusbar display of + * lengths will be too jerky */ + + if (m) { + char const *unit_str; + switch (metric_dst) { + case SP_M: unit_str = " m"; break; + case SP_MM: unit_str = " mm"; break; + case SP_CM: unit_str = " cm"; break; + case SP_IN: unit_str = "\""; break; + case SP_PT: unit_str = " pt"; break; + case SP_PX: unit_str = " px"; break; + default: unit_str = NULL; break; + } + if (unit_str) { + g_string_append(str, unit_str); + } + } + return str; +} + + +/* + 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:textwidth=99 : diff --git a/src/sp-metrics.h b/src/sp-metrics.h new file mode 100644 index 000000000..23c1b6c13 --- /dev/null +++ b/src/sp-metrics.h @@ -0,0 +1,21 @@ +#ifndef SP_METRICS_H +#define SP_METRICS_H + +#include +#include +#include "sp-metric.h" + +gdouble sp_absolute_metric_to_metric (gdouble length_src, const SPMetric metric_src, const SPMetric metric_dst); +GString * sp_metric_to_metric_string (gdouble length, const SPMetric metric_src, const SPMetric metric_dst, gboolean m); + +// convenience since we mostly deal with points +#define SP_METRIC_TO_PT(l,m) sp_absolute_metric_to_metric(l,m,SP_PT); +#define SP_PT_TO_METRIC(l,m) sp_absolute_metric_to_metric(l,SP_PT,m); + +#define SP_PT_TO_METRIC_STRING(l,m) sp_metric_to_metric_string(l, SP_PT, m, TRUE) +#define SP_PT_TO_STRING(l,m) sp_metric_to_metric_string(l, SP_PT, m, FALSE) + +#define SP_PX_TO_METRIC_STRING(l,m) sp_metric_to_metric_string(l, SP_PX, m, TRUE) +#define SP_PX_TO_STRING(l,m) sp_metric_to_metric_string(l, SP_PX, m, FALSE) + +#endif diff --git a/src/sp-namedview.cpp b/src/sp-namedview.cpp new file mode 100644 index 000000000..c6e6b872b --- /dev/null +++ b/src/sp-namedview.cpp @@ -0,0 +1,989 @@ +#define __SP_NAMEDVIEW_C__ + +/* + * implementation + * + * Authors: + * Lauris Kaplinski + * bulia byak + * + * Copyright (C) 1999-2005 Authors + * Copyright (C) 2000-2001 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "config.h" + + + + +#include "display/canvas-grid.h" +#include "helper/units.h" +#include "svg/svg.h" +#include "xml/repr.h" +#include "attributes.h" +#include "document.h" +#include "desktop-events.h" +#include "desktop-handles.h" +#include "sp-guide.h" +#include "sp-item-group.h" +#include "sp-namedview.h" +#include "prefs-utils.h" +#include "desktop.h" + +#include "isnan.h" //temp fox for isnan(). include last + +#define DEFAULTTOLERANCE 0.4 +#define DEFAULTGRIDCOLOR 0x3f3fff25 +#define DEFAULTGRIDEMPCOLOR 0x3f3fff60 +#define DEFAULTGRIDEMPSPACING 5 +#define DEFAULTGUIDECOLOR 0x0000ff7f +#define DEFAULTGUIDEHICOLOR 0xff00007f +#define DEFAULTBORDERCOLOR 0x000000ff +#define DEFAULTPAGECOLOR 0xffffff00 + +static void sp_namedview_class_init(SPNamedViewClass *klass); +static void sp_namedview_init(SPNamedView *namedview); + +static void sp_namedview_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr); +static void sp_namedview_release(SPObject *object); +static void sp_namedview_set(SPObject *object, unsigned int key, const gchar *value); +static void sp_namedview_child_added(SPObject *object, Inkscape::XML::Node *child, Inkscape::XML::Node *ref); +static void sp_namedview_remove_child(SPObject *object, Inkscape::XML::Node *child); +static Inkscape::XML::Node *sp_namedview_write(SPObject *object, Inkscape::XML::Node *repr, guint flags); + +static void sp_namedview_setup_guides(SPNamedView * nv); + +static void sp_namedview_setup_grid(SPNamedView * nv); +static void sp_namedview_setup_grid_item(SPNamedView * nv, SPCanvasItem * item); + +static gboolean sp_str_to_bool(const gchar *str); +static gboolean sp_nv_read_length(const gchar *str, guint base, gdouble *val, const SPUnit **unit); +static gboolean sp_nv_read_opacity(const gchar *str, guint32 *color); + +static SPObjectGroupClass * parent_class; + +GType +sp_namedview_get_type() +{ + static GType namedview_type = 0; + if (!namedview_type) { + GTypeInfo namedview_info = { + sizeof(SPNamedViewClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) sp_namedview_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof(SPNamedView), + 16, /* n_preallocs */ + (GInstanceInitFunc) sp_namedview_init, + NULL, /* value_table */ + }; + namedview_type = g_type_register_static(SP_TYPE_OBJECTGROUP, "SPNamedView", &namedview_info, (GTypeFlags)0); + } + return namedview_type; +} + +static void sp_namedview_class_init(SPNamedViewClass * klass) +{ + GObjectClass * gobject_class; + SPObjectClass * sp_object_class; + + gobject_class = (GObjectClass *) klass; + sp_object_class = (SPObjectClass *) klass; + + parent_class = (SPObjectGroupClass*) g_type_class_ref(SP_TYPE_OBJECTGROUP); + + sp_object_class->build = sp_namedview_build; + sp_object_class->release = sp_namedview_release; + sp_object_class->set = sp_namedview_set; + sp_object_class->child_added = sp_namedview_child_added; + sp_object_class->remove_child = sp_namedview_remove_child; + sp_object_class->write = sp_namedview_write; +} + +static void sp_namedview_init(SPNamedView *nv) +{ + nv->editable = TRUE; + nv->showgrid = FALSE; + nv->showguides = TRUE; + nv->showborder = TRUE; + nv->showpageshadow = TRUE; + + nv->guides = NULL; + nv->viewcount = 0; + + nv->default_layer_id = 0; + + new (&nv->grid_snapper) Inkscape::GridSnapper(nv, 0); + new (&nv->guide_snapper) Inkscape::GuideSnapper(nv, 0); + new (&nv->object_snapper) Inkscape::ObjectSnapper(nv, 0); +} + +static void sp_namedview_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr) +{ + SPNamedView *nv = (SPNamedView *) object; + SPObjectGroup *og = (SPObjectGroup *) object; + + if (((SPObjectClass *) (parent_class))->build) { + (* ((SPObjectClass *) (parent_class))->build)(object, document, repr); + } + + sp_object_read_attr(object, "inkscape:document-units"); + sp_object_read_attr(object, "viewonly"); + sp_object_read_attr(object, "showgrid"); + sp_object_read_attr(object, "showguides"); + sp_object_read_attr(object, "gridtolerance"); + sp_object_read_attr(object, "guidetolerance"); + sp_object_read_attr(object, "objecttolerance"); + sp_object_read_attr(object, "inkscape:has_abs_tolerance"); + sp_object_read_attr(object, "gridoriginx"); + sp_object_read_attr(object, "gridoriginy"); + sp_object_read_attr(object, "gridspacingx"); + sp_object_read_attr(object, "gridspacingy"); + sp_object_read_attr(object, "gridempspacing"); + sp_object_read_attr(object, "gridcolor"); + sp_object_read_attr(object, "gridempcolor"); + sp_object_read_attr(object, "gridopacity"); + sp_object_read_attr(object, "gridempopacity"); + sp_object_read_attr(object, "guidecolor"); + sp_object_read_attr(object, "guideopacity"); + sp_object_read_attr(object, "guidehicolor"); + sp_object_read_attr(object, "guidehiopacity"); + sp_object_read_attr(object, "showborder"); + sp_object_read_attr(object, "inkscape:showpageshadow"); + sp_object_read_attr(object, "borderlayer"); + sp_object_read_attr(object, "bordercolor"); + sp_object_read_attr(object, "borderopacity"); + sp_object_read_attr(object, "pagecolor"); + sp_object_read_attr(object, "inkscape:pageopacity"); + sp_object_read_attr(object, "inkscape:pageshadow"); + sp_object_read_attr(object, "inkscape:zoom"); + sp_object_read_attr(object, "inkscape:cx"); + sp_object_read_attr(object, "inkscape:cy"); + sp_object_read_attr(object, "inkscape:window-width"); + sp_object_read_attr(object, "inkscape:window-height"); + sp_object_read_attr(object, "inkscape:window-x"); + sp_object_read_attr(object, "inkscape:window-y"); + sp_object_read_attr(object, "inkscape:grid-bbox"); + sp_object_read_attr(object, "inkscape:guide-bbox"); + sp_object_read_attr(object, "inkscape:object-bbox"); + sp_object_read_attr(object, "inkscape:grid-points"); + sp_object_read_attr(object, "inkscape:guide-points"); + sp_object_read_attr(object, "inkscape:object-points"); + sp_object_read_attr(object, "inkscape:object-paths"); + sp_object_read_attr(object, "inkscape:object-nodes"); + sp_object_read_attr(object, "inkscape:current-layer"); + + /* Construct guideline list */ + + for (SPObject *o = sp_object_first_child(SP_OBJECT(og)) ; o != NULL; o = SP_OBJECT_NEXT(o) ) { + if (SP_IS_GUIDE(o)) { + SPGuide * g = SP_GUIDE(o); + nv->guides = g_slist_prepend(nv->guides, g); + g_object_set(G_OBJECT(g), "color", nv->guidecolor, "hicolor", nv->guidehicolor, NULL); + } + } +} + +static void sp_namedview_release(SPObject *object) +{ + SPNamedView *namedview = (SPNamedView *) object; + + if (namedview->guides) { + g_slist_free(namedview->guides); + namedview->guides = NULL; + } + + while (namedview->gridviews) { + gtk_object_unref(GTK_OBJECT(namedview->gridviews->data)); + namedview->gridviews = g_slist_remove(namedview->gridviews, namedview->gridviews->data); + } + + namedview->grid_snapper.~GridSnapper(); + namedview->guide_snapper.~GuideSnapper(); + namedview->object_snapper.~ObjectSnapper(); + + if (((SPObjectClass *) parent_class)->release) { + ((SPObjectClass *) parent_class)->release(object); + } +} + +static void sp_namedview_set(SPObject *object, unsigned int key, const gchar *value) +{ + SPNamedView *nv = SP_NAMEDVIEW(object); + SPUnit const &px = sp_unit_get_by_id(SP_UNIT_PX); + + switch (key) { + case SP_ATTR_VIEWONLY: + nv->editable = (!value); + object->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_SHOWGRID: + nv->showgrid = sp_str_to_bool(value); + sp_namedview_setup_grid(nv); + if (!nv->showgrid) { // grid goes off, disable snaps even if they are turned on + nv->grid_snapper.setSnapTo(Inkscape::Snapper::BBOX_POINT, false); + nv->grid_snapper.setSnapTo(Inkscape::Snapper::SNAP_POINT, false); + } else { // grid goes on, enable snaps if they are turned on + nv->grid_snapper.setSnapTo(Inkscape::Snapper::BBOX_POINT, nv->snap_grid_bbox); + nv->grid_snapper.setSnapTo(Inkscape::Snapper::SNAP_POINT, nv->snap_grid_point); + } + object->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_SHOWGUIDES: + if (!value) { // show guides if not specified, for backwards compatibility + nv->showguides = TRUE; + } else { + nv->showguides = sp_str_to_bool(value); + } + if (!nv->showguides) { // guides go off, disable snaps even if they are turned on + nv->guide_snapper.setSnapTo(Inkscape::Snapper::BBOX_POINT, false); + nv->guide_snapper.setSnapTo(Inkscape::Snapper::SNAP_POINT, false); + } else { // guides go on, enable snaps if they are turned on + nv->guide_snapper.setSnapTo(Inkscape::Snapper::BBOX_POINT, nv->snap_guide_bbox); + nv->guide_snapper.setSnapTo(Inkscape::Snapper::SNAP_POINT, nv->snap_guide_point); + } + sp_namedview_setup_guides(nv); + object->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_GRIDTOLERANCE: + nv->gridtoleranceunit = &px; + nv->gridtolerance = DEFAULTTOLERANCE; + if (value) { + sp_nv_read_length(value, SP_UNIT_ABSOLUTE | SP_UNIT_DEVICE, &nv->gridtolerance, &nv->gridtoleranceunit); + } + object->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_GUIDETOLERANCE: + nv->guidetoleranceunit = &px; + nv->guidetolerance = DEFAULTTOLERANCE; + if (value) { + sp_nv_read_length(value, SP_UNIT_ABSOLUTE | SP_UNIT_DEVICE, &nv->guidetolerance, &nv->guidetoleranceunit); + } + object->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_OBJECTTOLERANCE: + nv->objecttoleranceunit = &px; + nv->objecttolerance = DEFAULTTOLERANCE; + if (value) { + sp_nv_read_length(value, SP_UNIT_ABSOLUTE | SP_UNIT_DEVICE, &nv->objecttolerance, &nv->objecttoleranceunit); + } + object->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_ABS_TOLERANCE: + if (!value) + nv->has_abs_tolerance = true; + else + nv->has_abs_tolerance = (sp_str_to_bool (value) == TRUE); + object->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_GRIDORIGINX: + case SP_ATTR_GRIDORIGINY: + { + unsigned const d = (key == SP_ATTR_GRIDORIGINY); + nv->gridunit = nv->doc_units; + nv->gridorigin[d] = 0.0; + if (value) { + sp_nv_read_length(value, SP_UNIT_ABSOLUTE | SP_UNIT_DEVICE, &nv->gridorigin[d], &nv->gridunit); + } + nv->gridorigin[d] = sp_units_get_pixels(nv->gridorigin[d], *(nv->gridunit)); + sp_namedview_setup_grid(nv); + object->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + } + case SP_ATTR_GRIDSPACINGX: + case SP_ATTR_GRIDSPACINGY: + { + unsigned const d = (key == SP_ATTR_GRIDSPACINGY); + nv->gridunit = nv->doc_units; + nv->gridspacing[d] = 1.0; + if (value) { + sp_nv_read_length(value, SP_UNIT_ABSOLUTE | SP_UNIT_DEVICE, &nv->gridspacing[d], &nv->gridunit); + } + nv->gridspacing[d] = sp_units_get_pixels(nv->gridspacing[d], *(nv->gridunit)); + sp_namedview_setup_grid(nv); + object->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + } + case SP_ATTR_GRIDCOLOR: + nv->gridcolor = (nv->gridcolor & 0xff) | (DEFAULTGRIDCOLOR & 0xffffff00); + if (value) { + nv->gridcolor = (nv->gridcolor & 0xff) | sp_svg_read_color(value, nv->gridcolor); + } + sp_namedview_setup_grid(nv); + object->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_GRIDEMPCOLOR: + nv->gridempcolor = (nv->gridempcolor & 0xff) | (DEFAULTGRIDEMPCOLOR & 0xffffff00); + if (value) { + nv->gridempcolor = (nv->gridempcolor & 0xff) | sp_svg_read_color(value, nv->gridempcolor); + } + sp_namedview_setup_grid(nv); + object->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_GRIDOPACITY: + nv->gridcolor = (nv->gridcolor & 0xffffff00) | (DEFAULTGRIDCOLOR & 0xff); + sp_nv_read_opacity(value, &nv->gridcolor); + sp_namedview_setup_grid(nv); + object->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_GRIDEMPOPACITY: + nv->gridempcolor = (nv->gridempcolor & 0xffffff00) | (DEFAULTGRIDEMPCOLOR & 0xff); + sp_nv_read_opacity(value, &nv->gridempcolor); + sp_namedview_setup_grid(nv); + object->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_GRIDEMPSPACING: + nv->gridempspacing = DEFAULTGRIDEMPSPACING; + if (value != NULL) + nv->gridempspacing = atoi(value); + sp_namedview_setup_grid(nv); + object->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_GUIDECOLOR: + nv->guidecolor = (nv->guidecolor & 0xff) | (DEFAULTGUIDECOLOR & 0xffffff00); + if (value) { + nv->guidecolor = (nv->guidecolor & 0xff) | sp_svg_read_color(value, nv->guidecolor); + } + for (GSList *l = nv->guides; l != NULL; l = l->next) { + g_object_set(G_OBJECT(l->data), "color", nv->guidecolor, NULL); + } + object->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_GUIDEOPACITY: + nv->guidecolor = (nv->guidecolor & 0xffffff00) | (DEFAULTGUIDECOLOR & 0xff); + sp_nv_read_opacity(value, &nv->guidecolor); + for (GSList *l = nv->guides; l != NULL; l = l->next) { + g_object_set(G_OBJECT(l->data), "color", nv->guidecolor, NULL); + } + object->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_GUIDEHICOLOR: + nv->guidehicolor = (nv->guidehicolor & 0xff) | (DEFAULTGUIDEHICOLOR & 0xffffff00); + if (value) { + nv->guidehicolor = (nv->guidehicolor & 0xff) | sp_svg_read_color(value, nv->guidehicolor); + } + for (GSList *l = nv->guides; l != NULL; l = l->next) { + g_object_set(G_OBJECT(l->data), "hicolor", nv->guidehicolor, NULL); + } + object->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_GUIDEHIOPACITY: + nv->guidehicolor = (nv->guidehicolor & 0xffffff00) | (DEFAULTGUIDEHICOLOR & 0xff); + sp_nv_read_opacity(value, &nv->guidehicolor); + for (GSList *l = nv->guides; l != NULL; l = l->next) { + g_object_set(G_OBJECT(l->data), "hicolor", nv->guidehicolor, NULL); + } + object->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_SHOWBORDER: + nv->showborder = (value) ? sp_str_to_bool (value) : TRUE; + object->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_BORDERLAYER: + nv->borderlayer = SP_BORDER_LAYER_BOTTOM; + if (value && !strcasecmp(value, "true")) nv->borderlayer = SP_BORDER_LAYER_TOP; + object->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_BORDERCOLOR: + nv->bordercolor = (nv->bordercolor & 0xff) | (DEFAULTBORDERCOLOR & 0xffffff00); + if (value) { + nv->bordercolor = (nv->bordercolor & 0xff) | sp_svg_read_color (value, nv->bordercolor); + } + object->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_BORDEROPACITY: + nv->bordercolor = (nv->bordercolor & 0xffffff00) | (DEFAULTBORDERCOLOR & 0xff); + sp_nv_read_opacity(value, &nv->bordercolor); + object->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_PAGECOLOR: + nv->pagecolor = (nv->pagecolor & 0xff) | (DEFAULTPAGECOLOR & 0xffffff00); + if (value) { + nv->pagecolor = (nv->pagecolor & 0xff) | sp_svg_read_color(value, nv->pagecolor); + } + object->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_INKSCAPE_PAGEOPACITY: + nv->pagecolor = (nv->pagecolor & 0xffffff00) | (DEFAULTPAGECOLOR & 0xff); + sp_nv_read_opacity(value, &nv->pagecolor); + object->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_INKSCAPE_PAGESHADOW: + nv->pageshadow = value? atoi(value) : 2; // 2 is the default + object->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_SHOWPAGESHADOW: + nv->showpageshadow = (value) ? sp_str_to_bool(value) : TRUE; + object->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_INKSCAPE_ZOOM: + nv->zoom = value ? g_ascii_strtod(value, NULL) : 0; // zero means not set + object->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_INKSCAPE_CX: + nv->cx = value ? g_ascii_strtod(value, NULL) : HUGE_VAL; // HUGE_VAL means not set + object->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_INKSCAPE_CY: + nv->cy = value ? g_ascii_strtod(value, NULL) : HUGE_VAL; // HUGE_VAL means not set + object->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_INKSCAPE_WINDOW_WIDTH: + nv->window_width = value? atoi(value) : -1; // -1 means not set + object->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_INKSCAPE_WINDOW_HEIGHT: + nv->window_height = value ? atoi(value) : -1; // -1 means not set + object->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_INKSCAPE_WINDOW_X: + nv->window_x = value ? atoi(value) : -1; // -1 means not set + object->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_INKSCAPE_WINDOW_Y: + nv->window_y = value ? atoi(value) : -1; // -1 means not set + object->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_INKSCAPE_GRID_BBOX: + nv->snap_grid_bbox = (value) ? sp_str_to_bool(value) : TRUE; + nv->grid_snapper.setSnapTo(Inkscape::Snapper::BBOX_POINT, nv->showgrid && nv->snap_grid_bbox); + object->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_INKSCAPE_GRID_POINTS: + nv->snap_grid_point = (value) ? sp_str_to_bool(value) : FALSE; + nv->grid_snapper.setSnapTo(Inkscape::Snapper::SNAP_POINT, nv->showgrid && nv->snap_grid_point); + object->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_INKSCAPE_GUIDE_BBOX: + nv->snap_guide_bbox = (value) ? sp_str_to_bool(value) : TRUE; + nv->guide_snapper.setSnapTo(Inkscape::Snapper::BBOX_POINT, nv->showguides && nv->snap_guide_bbox); + object->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_INKSCAPE_GUIDE_POINTS: + nv->snap_guide_point = (value) ? sp_str_to_bool(value) : FALSE; + nv->guide_snapper.setSnapTo(Inkscape::Snapper::SNAP_POINT, nv->showguides && nv->snap_guide_point); + object->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_INKSCAPE_OBJECT_BBOX: + nv->snap_object_bbox = (value) ? sp_str_to_bool(value) : FALSE; + nv->object_snapper.setSnapTo(Inkscape::Snapper::BBOX_POINT, nv->snap_object_bbox); + object->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_INKSCAPE_OBJECT_POINTS: + nv->snap_object_point = (value) ? sp_str_to_bool(value) : FALSE; + nv->object_snapper.setSnapTo(Inkscape::Snapper::SNAP_POINT, nv->snap_object_point); + object->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_INKSCAPE_OBJECT_PATHS: + nv->snap_object_paths = (value) ? sp_str_to_bool(value) : TRUE; + nv->object_snapper.setSnapToPaths(nv->snap_object_paths); + object->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_INKSCAPE_OBJECT_NODES: + nv->snap_object_nodes = (value) ? sp_str_to_bool(value) : TRUE; + nv->object_snapper.setSnapToNodes(nv->snap_object_nodes); + object->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_INKSCAPE_CURRENT_LAYER: + nv->default_layer_id = value ? g_quark_from_string(value) : 0; + object->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_INKSCAPE_DOCUMENT_UNITS: { + /* The default unit if the document doesn't override this: e.g. for files saved as + * `plain SVG', or non-inkscape files, or files created by an inkscape 0.40 & + * earlier. + * + * Here we choose `px': useful for screen-destined SVGs, and fewer bug reports + * about "not the same numbers as what's in the SVG file" (at least for documents + * without a viewBox attribute on the root element). Similarly, it's also + * the most reliable unit (i.e. least likely to be wrong in different viewing + * conditions) for viewBox-less SVG files given that it's the unit that inkscape + * uses for all coordinates. + * + * For documents that do have a viewBox attribute on the root element, it + * might be better if we used either viewBox coordinates or if we used the unit of + * say the width attribute of the root element. However, these pose problems + * in that they aren't in general absolute units as currently required by + * doc_units. + */ + SPUnit const *new_unit = &sp_unit_get_by_id(SP_UNIT_PX); + + if (value) { + SPUnit const *const req_unit = sp_unit_get_by_abbreviation(value); + if ( req_unit == NULL ) { + g_warning("Unrecognized unit `%s'", value); + /* fixme: Document errors should be reported in the status bar or + * the like (e.g. as per + * http://www.w3.org/TR/SVG11/implnote.html#ErrorProcessing); g_log + * should be only for programmer errors. */ + } else if ( req_unit->base == SP_UNIT_ABSOLUTE || + req_unit->base == SP_UNIT_DEVICE ) { + new_unit = req_unit; + } else { + g_warning("Document units must be absolute like `mm', `pt' or `px', but found `%s'", + value); + /* fixme: Don't use g_log (see above). */ + } + } + nv->doc_units = new_unit; + object->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + } + default: + if (((SPObjectClass *) (parent_class))->set) { + ((SPObjectClass *) (parent_class))->set(object, key, value); + } + break; + } +} + +static void sp_namedview_child_added(SPObject *object, Inkscape::XML::Node *child, Inkscape::XML::Node *ref) +{ + SPNamedView *nv = (SPNamedView *) object; + + if (((SPObjectClass *) (parent_class))->child_added) { + (* ((SPObjectClass *) (parent_class))->child_added)(object, child, ref); + } + + const gchar *id = child->attribute("id"); + SPObject *no = object->document->getObjectById(id); + g_assert(SP_IS_OBJECT(no)); + + if (SP_IS_GUIDE(no)) { + SPGuide *g = (SPGuide *) no; + nv->guides = g_slist_prepend(nv->guides, g); + g_object_set(G_OBJECT(g), "color", nv->guidecolor, "hicolor", nv->guidehicolor, NULL); + if (nv->editable) { + for (GSList *l = nv->views; l != NULL; l = l->next) { + sp_guide_show(g, static_cast(l->data)->guides, (GCallback) sp_dt_guide_event); + if (static_cast(l->data)->guides_active) + sp_guide_sensitize(g, + SP_DT_CANVAS(static_cast (l->data)), + TRUE); + if (nv->showguides) { + for (GSList *v = SP_GUIDE(g)->views; v != NULL; v = v->next) { + sp_canvas_item_show(SP_CANVAS_ITEM(v->data)); + } + } else { + for (GSList *v = SP_GUIDE(g)->views; v != NULL; v = v->next) { + sp_canvas_item_hide(SP_CANVAS_ITEM(v->data)); + } + } + } + } + } +} + +static void sp_namedview_remove_child(SPObject *object, Inkscape::XML::Node *child) +{ + SPNamedView *nv = (SPNamedView *) object; + + GSList **ref = &nv->guides; + for ( GSList *iter = nv->guides ; iter ; iter = iter->next ) { + if ( SP_OBJECT_REPR((SPObject *)iter->data) == child ) { + *ref = iter->next; + iter->next = NULL; + g_slist_free_1(iter); + break; + } + ref = &iter->next; + } + + if (((SPObjectClass *) (parent_class))->remove_child) { + (* ((SPObjectClass *) (parent_class))->remove_child)(object, child); + } +} + +static Inkscape::XML::Node *sp_namedview_write(SPObject *object, Inkscape::XML::Node *repr, guint flags) +{ + if ( ( flags & SP_OBJECT_WRITE_EXT ) && + repr != SP_OBJECT_REPR(object) ) + { + if (repr) { + repr->mergeFrom(SP_OBJECT_REPR(object), "id"); + } else { + repr = SP_OBJECT_REPR(object)->duplicate(); + } + } + + return repr; +} + +void SPNamedView::show(SPDesktop *desktop) +{ + for (GSList *l = guides; l != NULL; l = l->next) { + sp_guide_show(SP_GUIDE(l->data), desktop->guides, (GCallback) sp_dt_guide_event); + if (desktop->guides_active) { + sp_guide_sensitize(SP_GUIDE(l->data), SP_DT_CANVAS(desktop), TRUE); + } + if (showguides) { + for (GSList *v = SP_GUIDE(l->data)->views; v != NULL; v = v->next) { + sp_canvas_item_show(SP_CANVAS_ITEM(v->data)); + } + } else { + for (GSList *v = SP_GUIDE(l->data)->views; v != NULL; v = v->next) { + sp_canvas_item_hide(SP_CANVAS_ITEM(v->data)); + } + } + } + + views = g_slist_prepend(views, desktop); + + SPCanvasItem *item = sp_canvas_item_new(SP_DT_GRID(desktop), SP_TYPE_CGRID, NULL); + // since we're keeping a copy, we need to bump up the ref count + gtk_object_ref(GTK_OBJECT(item)); + gridviews = g_slist_prepend(gridviews, item); + sp_namedview_setup_grid_item(this, item); +} + +/* + * Restores window geometry from the document settings + */ +void sp_namedview_window_from_document(SPDesktop *desktop) +{ + SPNamedView *nv = desktop->namedview; + gint save_geometry = prefs_get_int_attribute("options.savewindowgeometry", "value", 0); + + // restore window size and position + if (save_geometry) { + if (nv->window_width != -1 && nv->window_height != -1) + desktop->setWindowSize(nv->window_width, nv->window_height); + if (nv->window_x != -1 && nv->window_y != -1) + desktop->setWindowPosition(NR::Point(nv->window_x, nv->window_y)); + } + + // restore zoom and view + if (nv->zoom != 0 && nv->zoom != HUGE_VAL && !isNaN(nv->zoom) + && nv->cx != HUGE_VAL && !isNaN(nv->cx) + && nv->cy != HUGE_VAL && !isNaN(nv->cy)) { + desktop->zoom_absolute(nv->cx, nv->cy, nv->zoom); + } else if (SP_DT_DOCUMENT(desktop)) { // document without saved zoom, zoom to its page + desktop->zoom_page(); + } + + // cancel any history of zooms up to this point + if (desktop->zooms_past) { + g_list_free(desktop->zooms_past); + desktop->zooms_past = NULL; + } + + SPObject *layer = NULL; + SPDocument *document = desktop->doc(); + if ( nv->default_layer_id != 0 ) { + layer = document->getObjectById(g_quark_to_string(nv->default_layer_id)); + } + // don't use that object if it's not at least group + if ( !layer || !SP_IS_GROUP(layer) ) { + layer = NULL; + } + // if that didn't work out, look for the topmost layer + if (!layer) { + SPObject *iter = sp_object_first_child(SP_DOCUMENT_ROOT(document)); + for ( ; iter ; iter = SP_OBJECT_NEXT(iter) ) { + if (desktop->isLayer(iter)) { + layer = iter; + } + } + } + if (layer) { + desktop->setCurrentLayer(layer); + } +} + +void sp_namedview_document_from_window(SPDesktop *desktop) +{ + gint save_geometry = prefs_get_int_attribute("options.savewindowgeometry", "value", 0); + Inkscape::XML::Node *view = SP_OBJECT_REPR(desktop->namedview); + NR::Rect const r = desktop->get_display_area(); + + // saving window geometry is not undoable + gboolean saved = sp_document_get_undo_sensitive(SP_DT_DOCUMENT(desktop)); + sp_document_set_undo_sensitive(SP_DT_DOCUMENT(desktop), FALSE); + + sp_repr_set_svg_double(view, "inkscape:zoom", desktop->current_zoom()); + sp_repr_set_svg_double(view, "inkscape:cx", r.midpoint()[NR::X]); + sp_repr_set_svg_double(view, "inkscape:cy", r.midpoint()[NR::Y]); + + if (save_geometry) { + gint w, h, x, y; + desktop->getWindowGeometry(x, y, w, h); + sp_repr_set_int(view, "inkscape:window-width", w); + sp_repr_set_int(view, "inkscape:window-height", h); + sp_repr_set_int(view, "inkscape:window-x", x); + sp_repr_set_int(view, "inkscape:window-y", y); + } + + view->setAttribute("inkscape:current-layer", SP_OBJECT_ID(desktop->currentLayer())); + + // restore undoability + sp_document_set_undo_sensitive(SP_DT_DOCUMENT(desktop), saved); +} + +void SPNamedView::hide(SPDesktop const *desktop) +{ + g_assert(desktop != NULL); + g_assert(g_slist_find(views, desktop)); + + for (GSList *l = guides; l != NULL; l = l->next) { + sp_guide_hide(SP_GUIDE(l->data), SP_DT_CANVAS(desktop)); + } + + views = g_slist_remove(views, desktop); + + GSList *l; + for (l = gridviews; l != NULL; l = l->next) { + if (SP_CANVAS_ITEM(l->data)->canvas == SP_DT_CANVAS(desktop)) { + break; + } + } + + g_assert(l); + + sp_canvas_item_hide(SP_CANVAS_ITEM(l->data)); + gtk_object_unref(GTK_OBJECT(l->data)); + gridviews = g_slist_remove(gridviews, l->data); +} + +void SPNamedView::activateGuides(gpointer desktop, gboolean active) +{ + g_assert(desktop != NULL); + g_assert(g_slist_find(views, desktop)); + + SPDesktop *dt = static_cast(desktop); + + for (GSList *l = guides; l != NULL; l = l->next) { + sp_guide_sensitize(SP_GUIDE(l->data), SP_DT_CANVAS(dt), active); + } +} + +static void sp_namedview_setup_guides(SPNamedView *nv) +{ + for (GSList *l = nv->guides; l != NULL; l = l->next) { + if (nv->showguides) { + for (GSList *v = SP_GUIDE(l->data)->views; v != NULL; v = v->next) { + sp_canvas_item_show(SP_CANVAS_ITEM(v->data)); + } + } else { + for (GSList *v = SP_GUIDE(l->data)->views; v != NULL; v = v->next) { + sp_canvas_item_hide(SP_CANVAS_ITEM(v->data)); + } + } + } +} + +void sp_namedview_toggle_guides(SPDocument *doc, Inkscape::XML::Node *repr) +{ + unsigned int v; + unsigned int set = sp_repr_get_boolean(repr, "showguides", &v); + if (!set) { // hide guides if not specified, for backwards compatibility + v = FALSE; + } else { + v = !v; + } + + gboolean saved = sp_document_get_undo_sensitive(doc); + sp_document_set_undo_sensitive(doc, FALSE); + + sp_repr_set_boolean(repr, "showguides", v); + + doc->rroot->setAttribute("sodipodi:modified", "true"); + sp_document_set_undo_sensitive(doc, saved); +} + +void sp_namedview_toggle_grid(SPDocument *doc, Inkscape::XML::Node *repr) +{ + unsigned int v; + sp_repr_get_boolean(repr, "showgrid", &v); + v = !v; + + gboolean saved = sp_document_get_undo_sensitive(doc); + sp_document_set_undo_sensitive(doc, FALSE); + + sp_repr_set_boolean(repr, "showgrid", v); + + doc->rroot->setAttribute("sodipodi:modified", "true"); + sp_document_set_undo_sensitive(doc, saved); +} + +static void sp_namedview_setup_grid(SPNamedView *nv) +{ + for (GSList *l = nv->gridviews; l != NULL; l = l->next) { + sp_namedview_setup_grid_item(nv, SP_CANVAS_ITEM(l->data)); + } +} + +static void sp_namedview_setup_grid_item(SPNamedView *nv, SPCanvasItem *item) +{ + if (nv->showgrid) { + sp_canvas_item_show(item); + } else { + sp_canvas_item_hide(item); + } + + sp_canvas_item_set((GtkObject *) item, + "color", nv->gridcolor, + "originx", nv->gridorigin[NR::X], + "originy", nv->gridorigin[NR::Y], + "spacingx", nv->gridspacing[NR::X], + "spacingy", nv->gridspacing[NR::Y], + "empcolor", nv->gridempcolor, + "empspacing", nv->gridempspacing, + NULL); +} + +gchar const *SPNamedView::getName() const +{ + SPException ex; + SP_EXCEPTION_INIT(&ex); + return sp_object_getAttribute(SP_OBJECT(this), "id", &ex); +} + +guint SPNamedView::getViewCount() +{ + return ++viewcount; +} + +GSList const *SPNamedView::getViewList() const +{ + return views; +} + +/* This should be moved somewhere */ + +static gboolean sp_str_to_bool(const gchar *str) +{ + if (str) { + if (!g_strcasecmp(str, "true") || + !g_strcasecmp(str, "yes") || + !g_strcasecmp(str, "y") || + (atoi(str) != 0)) { + return TRUE; + } + } + + return FALSE; +} + +/* fixme: Collect all these length parsing methods and think common sane API */ + +static gboolean sp_nv_read_length(const gchar *str, guint base, gdouble *val, const SPUnit **unit) +{ + if (!str) { + return FALSE; + } + + gchar *u; + gdouble v = g_ascii_strtod(str, &u); + if (!u) { + return FALSE; + } + while (isspace(*u)) { + u += 1; + } + + if (!*u) { + /* No unit specified - keep default */ + *val = v; + return TRUE; + } + + if (base & SP_UNIT_DEVICE) { + if (u[0] && u[1] && !isalnum(u[2]) && !strncmp(u, "px", 2)) { + *unit = &sp_unit_get_by_id(SP_UNIT_PX); + *val = v; + return TRUE; + } + } + + if (base & SP_UNIT_ABSOLUTE) { + if (!strncmp(u, "pt", 2)) { + *unit = &sp_unit_get_by_id(SP_UNIT_PT); + } else if (!strncmp(u, "mm", 2)) { + *unit = &sp_unit_get_by_id(SP_UNIT_MM); + } else if (!strncmp(u, "cm", 2)) { + *unit = &sp_unit_get_by_id(SP_UNIT_CM); + } else if (!strncmp(u, "m", 1)) { + *unit = &sp_unit_get_by_id(SP_UNIT_M); + } else if (!strncmp(u, "in", 2)) { + *unit = &sp_unit_get_by_id(SP_UNIT_IN); + } else { + return FALSE; + } + *val = v; + return TRUE; + } + + return FALSE; +} + +static gboolean sp_nv_read_opacity(const gchar *str, guint32 *color) +{ + if (!str) { + return FALSE; + } + + gchar *u; + gdouble v = strtod(str, &u); + if (!u) { + return FALSE; + } + v = CLAMP(v, 0.0, 1.0); + + *color = (*color & 0xffffff00) | (guint32) floor(v * 255.9999); + + return TRUE; +} + +SPNamedView *sp_document_namedview(SPDocument *document, const gchar *id) +{ + g_return_val_if_fail(document != NULL, NULL); + + SPObject *nv = sp_item_group_get_child_by_name((SPGroup *) document->root, NULL, "sodipodi:namedview"); + g_assert(nv != NULL); + + if (id == NULL) { + return (SPNamedView *) nv; + } + + while (nv && strcmp(nv->id, id)) { + nv = sp_item_group_get_child_by_name((SPGroup *) document->root, nv, "sodipodi:namedview"); + } + + return (SPNamedView *) nv; +} + +/** + * Returns namedview's default metric. + */ +SPMetric SPNamedView::getDefaultMetric() const +{ + if (doc_units) { + return sp_unit_get_metric(doc_units); + } else { + return SP_PT; + } +} + +SPNamedView::SnapperList SPNamedView::getSnappers() const +{ + SnapperList s; + s.push_back(&grid_snapper); + s.push_back(&guide_snapper); + s.push_back(&object_snapper); + return s; +} + +/* + 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 : diff --git a/src/sp-namedview.h b/src/sp-namedview.h new file mode 100644 index 000000000..f96207794 --- /dev/null +++ b/src/sp-namedview.h @@ -0,0 +1,136 @@ +#ifndef INKSCAPE_SP_NAMEDVIEW_H +#define INKSCAPE_SP_NAMEDVIEW_H + +/* + * implementation + * + * Authors: + * Lauris Kaplinski + * + * Copyright (C) Lauris Kaplinski 2000-2002 + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#define SP_TYPE_NAMEDVIEW (sp_namedview_get_type()) +#define SP_NAMEDVIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), SP_TYPE_NAMEDVIEW, SPNamedView)) +#define SP_NAMEDVIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), SP_TYPE_NAMEDVIEW, SPNamedViewClass)) +#define SP_IS_NAMEDVIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), SP_TYPE_NAMEDVIEW)) +#define SP_IS_NAMEDVIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), SP_TYPE_NAMEDVIEW)) + +#include "helper/helper-forward.h" +#include "sp-object-group.h" +#include "libnr/nr-point.h" +#include "sp-metric.h" +#include "grid-snapper.h" +#include "guide-snapper.h" +#include "object-snapper.h" + + +enum { + SP_BORDER_LAYER_BOTTOM, + SP_BORDER_LAYER_TOP +}; + +struct SPNamedView : public SPObjectGroup { + unsigned int editable : 1; + unsigned int showgrid : 1; + unsigned int showguides : 1; + unsigned int showborder : 1; + unsigned int showpageshadow : 1; + unsigned int borderlayer : 2; + + int snap_grid_bbox; + int snap_grid_point; + int snap_guide_bbox; + int snap_guide_point; + int snap_object_bbox; + int snap_object_point; + int snap_object_paths; + int snap_object_nodes; + + double zoom; + double cx; + double cy; + gint window_width; + gint window_height; + gint window_x; + gint window_y; + + Inkscape::GridSnapper grid_snapper; + Inkscape::GuideSnapper guide_snapper; + Inkscape::ObjectSnapper object_snapper; + + SPUnit const *gridunit; + /* Grid data is in points regardless of unit */ + NR::Point gridorigin; + gdouble gridspacing[2]; + gint gridempspacing; + + SPUnit const *doc_units; + + SPUnit const *gridtoleranceunit; + gdouble gridtolerance; + + SPUnit const *guidetoleranceunit; + gdouble guidetolerance; + + SPUnit const *objecttoleranceunit; + gdouble objecttolerance; + + bool has_abs_tolerance; + + GQuark default_layer_id; + + guint32 gridcolor; + guint32 gridempcolor; + guint32 guidecolor; + guint32 guidehicolor; + guint32 bordercolor; + guint32 pagecolor; + guint32 pageshadow; + + GSList *guides; + GSList *views; + GSList *gridviews; + gint viewcount; + + void show(SPDesktop *desktop); + void hide(SPDesktop const *desktop); + void activateGuides(gpointer desktop, gboolean active); + gchar const *getName() const; + guint getViewCount(); + GSList const *getViewList() const; + SPMetric getDefaultMetric() const; + + typedef std::list SnapperList; + SnapperList getSnappers() const; +}; + +struct SPNamedViewClass { + SPObjectGroupClass parent_class; +}; + +GType sp_namedview_get_type(); + +SPNamedView *sp_document_namedview(SPDocument *document, gchar const *name); + +void sp_namedview_window_from_document(SPDesktop *desktop); +void sp_namedview_document_from_window(SPDesktop *desktop); + +void sp_namedview_toggle_guides(SPDocument *doc, Inkscape::XML::Node *repr); +void sp_namedview_toggle_grid(SPDocument *doc, Inkscape::XML::Node *repr); + +#endif /* !INKSCAPE_SP_NAMEDVIEW_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:encoding=utf-8:textwidth=99 : diff --git a/src/sp-object-group.cpp b/src/sp-object-group.cpp new file mode 100644 index 000000000..ec698592f --- /dev/null +++ b/src/sp-object-group.cpp @@ -0,0 +1,132 @@ +#define __SP_OBJECTGROUP_C__ + +/* + * Abstract base class for non-item groups + * + * Authors: + * Lauris Kaplinski + * + * Copyright (C) 1999-2003 Authors + * Copyright (C) 2001-2002 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "sp-object-group.h" +#include "xml/repr.h" + +static void sp_objectgroup_class_init (SPObjectGroupClass *klass); +static void sp_objectgroup_init (SPObjectGroup *objectgroup); + +static void sp_objectgroup_child_added (SPObject * object, Inkscape::XML::Node * child, Inkscape::XML::Node * ref); +static void sp_objectgroup_remove_child (SPObject * object, Inkscape::XML::Node * child); +static void sp_objectgroup_order_changed (SPObject * object, Inkscape::XML::Node * child, Inkscape::XML::Node * old_ref, Inkscape::XML::Node * new_ref); +static Inkscape::XML::Node *sp_objectgroup_write (SPObject *object, Inkscape::XML::Node *repr, guint flags); + +static SPObjectClass *parent_class; + +GType +sp_objectgroup_get_type (void) +{ + static GType objectgroup_type = 0; + if (!objectgroup_type) { + GTypeInfo objectgroup_info = { + sizeof (SPObjectGroupClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) sp_objectgroup_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (SPObjectGroup), + 16, /* n_preallocs */ + (GInstanceInitFunc) sp_objectgroup_init, + NULL, /* value_table */ + }; + objectgroup_type = g_type_register_static (SP_TYPE_OBJECT, "SPObjectGroup", &objectgroup_info, (GTypeFlags)0); + } + return objectgroup_type; +} + +static void +sp_objectgroup_class_init (SPObjectGroupClass *klass) +{ + GObjectClass * object_class; + SPObjectClass * sp_object_class; + + object_class = (GObjectClass *) klass; + sp_object_class = (SPObjectClass *) klass; + + parent_class = (SPObjectClass *)g_type_class_ref (SP_TYPE_OBJECT); + + sp_object_class->child_added = sp_objectgroup_child_added; + sp_object_class->remove_child = sp_objectgroup_remove_child; + sp_object_class->order_changed = sp_objectgroup_order_changed; + sp_object_class->write = sp_objectgroup_write; +} + +static void +sp_objectgroup_init (SPObjectGroup *objectgroup) +{ +} + +static void +sp_objectgroup_child_added (SPObject *object, Inkscape::XML::Node *child, Inkscape::XML::Node *ref) +{ + if (((SPObjectClass *) (parent_class))->child_added) + (* ((SPObjectClass *) (parent_class))->child_added) (object, child, ref); + + object->requestModified(SP_OBJECT_MODIFIED_FLAG); +} + +static void +sp_objectgroup_remove_child (SPObject *object, Inkscape::XML::Node *child) +{ + if (((SPObjectClass *) (parent_class))->remove_child) + (* ((SPObjectClass *) (parent_class))->remove_child) (object, child); + + object->requestModified(SP_OBJECT_MODIFIED_FLAG); +} + +static void +sp_objectgroup_order_changed (SPObject *object, Inkscape::XML::Node *child, Inkscape::XML::Node *old_ref, Inkscape::XML::Node *new_ref) +{ + if (((SPObjectClass *) (parent_class))->order_changed) + (* ((SPObjectClass *) (parent_class))->order_changed) (object, child, old_ref, new_ref); + + object->requestModified(SP_OBJECT_MODIFIED_FLAG); +} + +static Inkscape::XML::Node * +sp_objectgroup_write (SPObject *object, Inkscape::XML::Node *repr, guint flags) +{ + SPObjectGroup *group; + SPObject *child; + Inkscape::XML::Node *crepr; + + group = SP_OBJECTGROUP (object); + + if (flags & SP_OBJECT_WRITE_BUILD) { + GSList *l; + if (!repr) repr = sp_repr_new ("svg:g"); + l = NULL; + for ( child = sp_object_first_child(object) ; child != NULL ; child = SP_OBJECT_NEXT(child) ) { + crepr = child->updateRepr(NULL, flags); + if (crepr) l = g_slist_prepend (l, crepr); + } + while (l) { + repr->addChild((Inkscape::XML::Node *) l->data, NULL); + Inkscape::GC::release((Inkscape::XML::Node *) l->data); + l = g_slist_remove (l, l->data); + } + } else { + for ( child = sp_object_first_child(object) ; child != NULL ; child = SP_OBJECT_NEXT(child) ) { + child->updateRepr(flags); + } + } + + if (((SPObjectClass *) (parent_class))->write) + ((SPObjectClass *) (parent_class))->write (object, repr, flags); + + return repr; +} + diff --git a/src/sp-object-group.h b/src/sp-object-group.h new file mode 100644 index 000000000..5d67df6fe --- /dev/null +++ b/src/sp-object-group.h @@ -0,0 +1,33 @@ +#ifndef __SP_OBJECTGROUP_H__ +#define __SP_OBJECTGROUP_H__ + +/* + * Abstract base class for non-item groups + * + * Author: + * Lauris Kaplinski + * + * Copyright (C) 1999-2003 Authors + * Copyright (C) 2001-2002 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "sp-object.h" + +#define SP_TYPE_OBJECTGROUP (sp_objectgroup_get_type ()) +#define SP_OBJECTGROUP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SP_TYPE_OBJECTGROUP, SPObjectGroup)) +#define SP_OBJECTGROUP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SP_TYPE_OBJECTGROUP, SPObjectGroupClass)) +#define SP_IS_OBJECTGROUP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_OBJECTGROUP)) +#define SP_IS_OBJECTGROUP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SP_TYPE_OBJECTGROUP)) + +struct SPObjectGroup : public SPObject { +}; + +struct SPObjectGroupClass { + SPObjectClass parent_class; +}; + +GType sp_objectgroup_get_type (void); + +#endif diff --git a/src/sp-object-repr.cpp b/src/sp-object-repr.cpp new file mode 100644 index 000000000..4b631f3d5 --- /dev/null +++ b/src/sp-object-repr.cpp @@ -0,0 +1,208 @@ +#define __SP_OBJECT_REPR_C__ + +/* + * Object type dictionary and build frontend + * + * Authors: + * Lauris Kaplinski + * + * Copyright (C) 1999-2003 Lauris Kaplinski + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "sp-defs.h" +#include "sp-symbol.h" +#include "sp-marker.h" +#include "sp-use.h" +#include "sp-root.h" +#include "sp-image.h" +#include "sp-linear-gradient-fns.h" +#include "sp-path.h" +#include "sp-radial-gradient-fns.h" +#include "sp-rect.h" +#include "sp-ellipse.h" +#include "sp-star.h" +#include "sp-stop-fns.h" +#include "sp-spiral.h" +#include "sp-offset.h" +#include "sp-line.h" +#include "sp-metadata.h" +#include "sp-polyline.h" +#include "sp-textpath.h" +#include "sp-tspan.h" +#include "sp-pattern.h" +#include "sp-clippath.h" +#include "sp-mask.h" +#include "sp-anchor.h" +//#include "sp-animation.h" +#include "sp-flowdiv.h" +#include "sp-flowregion.h" +#include "sp-flowtext.h" +#include "sp-style-elem.h" +#include "xml/repr.h" + +enum NameType { REPR_NAME, SODIPODI_TYPE }; +static unsigned const N_NAME_TYPES = SODIPODI_TYPE + 1; + +static GType name_to_gtype(NameType name_type, gchar const *name); + +/** + * Construct an SPRoot and all its descendents from the given repr. + */ +SPObject * +sp_object_repr_build_tree(SPDocument *document, Inkscape::XML::Node *repr) +{ + g_assert(document != NULL); + g_assert(repr != NULL); + + gchar const * const name = repr->name(); + g_assert(name != NULL); + GType const type = name_to_gtype(REPR_NAME, name); + g_assert(g_type_is_a(type, SP_TYPE_ROOT)); + gpointer newobj = g_object_new(type, 0); + g_assert(newobj != NULL); + SPObject *const object = SP_OBJECT(newobj); + g_assert(object != NULL); + sp_object_invoke_build(object, document, repr, FALSE); + + return object; +} + +GType +sp_repr_type_lookup(Inkscape::XML::Node *repr) +{ + if ( repr->type() == Inkscape::XML::TEXT_NODE ) { + return SP_TYPE_STRING; + } else if ( repr->type() == Inkscape::XML::ELEMENT_NODE ) { + gchar const * const type_name = repr->attribute("sodipodi:type"); + return ( type_name + ? name_to_gtype(SODIPODI_TYPE, type_name) + : name_to_gtype(REPR_NAME, repr->name()) ); + } else { + return 0; + } +} + +static GHashTable *t2dtable[N_NAME_TYPES] = {NULL}; + +static void +populate_dtables() +{ + struct NameTypeEntry { char const *const name; GType const type_id; }; + NameTypeEntry const repr_name_entries[] = { + { "svg:a", SP_TYPE_ANCHOR }, + //{ "svg:animate", SP_TYPE_ANIMATE }, + { "svg:circle", SP_TYPE_CIRCLE }, + { "svg:clipPath", SP_TYPE_CLIPPATH }, + { "svg:defs", SP_TYPE_DEFS }, + { "svg:ellipse", SP_TYPE_ELLIPSE }, + /* Note: flow* elements are proposed additions for SVG 1.2, they aren't in + SVG 1.1. */ + { "svg:flowDiv", SP_TYPE_FLOWDIV }, + { "svg:flowLine", SP_TYPE_FLOWLINE }, + { "svg:flowPara", SP_TYPE_FLOWPARA }, + { "svg:flowRegion", SP_TYPE_FLOWREGION }, + { "svg:flowRegionBreak", SP_TYPE_FLOWREGIONBREAK }, + { "svg:flowRegionExclude", SP_TYPE_FLOWREGIONEXCLUDE }, + { "svg:flowRoot", SP_TYPE_FLOWTEXT }, + { "svg:flowSpan", SP_TYPE_FLOWTSPAN }, + { "svg:g", SP_TYPE_GROUP }, + { "svg:image", SP_TYPE_IMAGE }, + { "svg:line", SP_TYPE_LINE }, + { "svg:linearGradient", SP_TYPE_LINEARGRADIENT }, + { "svg:marker", SP_TYPE_MARKER }, + { "svg:mask", SP_TYPE_MASK }, + { "svg:metadata", SP_TYPE_METADATA }, + { "svg:path", SP_TYPE_PATH }, + { "svg:pattern", SP_TYPE_PATTERN }, + { "svg:polygon", SP_TYPE_POLYGON }, + { "svg:polyline", SP_TYPE_POLYLINE }, + { "svg:radialGradient", SP_TYPE_RADIALGRADIENT }, + { "svg:rect", SP_TYPE_RECT }, + { "svg:stop", SP_TYPE_STOP }, + { "svg:svg", SP_TYPE_ROOT }, + { "svg:style", SP_TYPE_STYLE_ELEM }, + { "svg:switch", SP_TYPE_GROUP }, + { "svg:symbol", SP_TYPE_SYMBOL }, + { "svg:text", SP_TYPE_TEXT }, + { "svg:textPath", SP_TYPE_TEXTPATH }, + { "svg:tspan", SP_TYPE_TSPAN }, + { "svg:use", SP_TYPE_USE } + }; + NameTypeEntry const sodipodi_name_entries[] = { + { "arc", SP_TYPE_ARC }, + { "inkscape:offset", SP_TYPE_OFFSET }, + { "spiral", SP_TYPE_SPIRAL }, + { "star", SP_TYPE_STAR } + }; + + NameTypeEntry const *const t2entries[] = { + repr_name_entries, + sodipodi_name_entries + }; + unsigned const t2n_entries[] = { + G_N_ELEMENTS(repr_name_entries), + G_N_ELEMENTS(sodipodi_name_entries) + }; + + for (unsigned nt = 0; nt < N_NAME_TYPES; ++nt) { + NameTypeEntry const *const entries = t2entries[nt]; + unsigned const n_entries = t2n_entries[nt]; + GHashTable *&dtable = t2dtable[nt]; + + dtable = g_hash_table_new(g_str_hash, g_str_equal); + for (unsigned i = 0; i < n_entries; ++i) { + g_hash_table_insert(dtable, + (void *)entries[i].name, + (gpointer) entries[i].type_id); + } + } +} + +static inline void +ensure_dtables_populated() +{ + if (!*t2dtable) { + populate_dtables(); + } +} + +static GType +name_to_gtype(NameType const name_type, gchar const *name) +{ + ensure_dtables_populated(); + + gpointer const data = g_hash_table_lookup(t2dtable[name_type], name); + return ( ( data == NULL ) + ? SP_TYPE_OBJECT + : (GType) data ); +} + +void +sp_object_type_register(gchar const *name, GType const gtype) +{ + GType const current = name_to_gtype(REPR_NAME, name); + if (current == SP_TYPE_OBJECT) { + g_hash_table_insert(t2dtable[REPR_NAME], + const_cast(name), + (gpointer) gtype); + } else { + /* Already registered. */ + if (current != gtype) { + g_warning("repr type `%s' already registered as type #%lu, ignoring attempt to re-register as #%lu.", + name, current, gtype); + } + } +} + +/* + 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:textwidth=99 : diff --git a/src/sp-object-repr.h b/src/sp-object-repr.h new file mode 100644 index 000000000..f3a80f83c --- /dev/null +++ b/src/sp-object-repr.h @@ -0,0 +1,41 @@ +#ifndef __SP_OBJECT_REPR_H__ +#define __SP_OBJECT_REPR_H__ + +/* + * Object type dictionary and build frontend + * + * Authors: + * Lauris Kaplinski + * + * Copyright (C) 1999-2003 Lauris Kaplinski + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "forward.h" + +namespace Inkscape { +namespace XML { +class Node; +} +} + + +SPObject *sp_object_repr_build_tree (SPDocument *document, Inkscape::XML::Node *repr); + +GType sp_repr_type_lookup (Inkscape::XML::Node *repr); + +void sp_object_type_register(gchar const *name, GType type); + +#endif + +/* + 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:textwidth=99 : diff --git a/src/sp-object.cpp b/src/sp-object.cpp new file mode 100644 index 000000000..d23a4d640 --- /dev/null +++ b/src/sp-object.cpp @@ -0,0 +1,1548 @@ +#define __SP_OBJECT_C__ +/** \file + * SPObject implementation. + * + * Authors: + * Lauris Kaplinski + * bulia byak + * + * Copyright (C) 1999-2005 authors + * Copyright (C) 2001-2002 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +/** \class SPObject + * + * SPObject is an abstract base class of all of the document nodes at the + * SVG document level. Each SPObject subclass implements a certain SVG + * element node type, or is an abstract base class for different node + * types. The SPObject layer is bound to the SPRepr layer, closely + * following the SPRepr mutations via callbacks. During creation, + * SPObject parses and interprets all textual attributes and CSS style + * strings of the SPRepr, and later updates the internal state whenever + * it receives a signal about a change. The opposite is not true - there + * are methods manipulating SPObjects directly and such changes do not + * propagate to the SPRepr layer. This is important for implementation of + * the undo stack, animations and other features. + * + * SPObjects are bound to the higher-level container SPDocument, which + * provides document level functionality such as the undo stack, + * dictionary and so on. Source: doc/architecture.txt + */ + + +#include "helper/sp-marshal.h" +#include "xml/node-event-vector.h" +#include "attributes.h" +#include "document.h" +#include "style.h" +#include "sp-object-repr.h" +#include "sp-root.h" +#include "streq.h" +#include "strneq.h" +#include "xml/repr.h" +#include "xml/node-fns.h" +#include "debug/event-tracker.h" + +#include "algorithms/longest-common-suffix.h" +using std::memcpy; +using std::strchr; +using std::strcmp; +using std::strlen; +using std::strstr; + +#define noSP_OBJECT_DEBUG_CASCADE + +#define noSP_OBJECT_DEBUG + +#ifdef SP_OBJECT_DEBUG +# define debug(f, a...) { g_print("%s(%d) %s:", \ + __FILE__,__LINE__,__FUNCTION__); \ + g_print(f, ## a); \ + g_print("\n"); \ + } +#else +# define debug(f, a...) /**/ +#endif + +static void sp_object_class_init(SPObjectClass *klass); +static void sp_object_init(SPObject *object); +static void sp_object_finalize(GObject *object); + +static void sp_object_child_added(SPObject *object, Inkscape::XML::Node *child, Inkscape::XML::Node *ref); +static void sp_object_remove_child(SPObject *object, Inkscape::XML::Node *child); +static void sp_object_order_changed(SPObject *object, Inkscape::XML::Node *child, Inkscape::XML::Node *old_ref, Inkscape::XML::Node *new_ref); + +static void sp_object_release(SPObject *object); +static void sp_object_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr); + +static void sp_object_private_set(SPObject *object, unsigned int key, gchar const *value); +static Inkscape::XML::Node *sp_object_private_write(SPObject *object, Inkscape::XML::Node *repr, guint flags); + +/* Real handlers of repr signals */ + +static void sp_object_repr_attr_changed(Inkscape::XML::Node *repr, gchar const *key, gchar const *oldval, gchar const *newval, bool is_interactive, gpointer data); + +static void sp_object_repr_content_changed(Inkscape::XML::Node *repr, gchar const *oldcontent, gchar const *newcontent, gpointer data); + +static void sp_object_repr_child_added(Inkscape::XML::Node *repr, Inkscape::XML::Node *child, Inkscape::XML::Node *ref, gpointer data); +static void sp_object_repr_child_removed(Inkscape::XML::Node *repr, Inkscape::XML::Node *child, Inkscape::XML::Node *ref, void *data); + +static void sp_object_repr_order_changed(Inkscape::XML::Node *repr, Inkscape::XML::Node *child, Inkscape::XML::Node *old, Inkscape::XML::Node *newer, gpointer data); + +static gchar *sp_object_get_unique_id(SPObject *object, gchar const *defid); + +guint update_in_progress = 0; // guard against update-during-update + +enum {RELEASE, MODIFIED, LAST_SIGNAL}; + +Inkscape::XML::NodeEventVector object_event_vector = { + sp_object_repr_child_added, + sp_object_repr_child_removed, + sp_object_repr_attr_changed, + sp_object_repr_content_changed, + sp_object_repr_order_changed +}; + +static GObjectClass *parent_class; +static guint object_signals[LAST_SIGNAL] = {0}; + +/** + * Registers the SPObject class with Gdk and returns its type number. + */ +GType +sp_object_get_type(void) +{ + static GType type = 0; + if (!type) { + GTypeInfo info = { + sizeof(SPObjectClass), + NULL, NULL, + (GClassInitFunc) sp_object_class_init, + NULL, NULL, + sizeof(SPObject), + 16, + (GInstanceInitFunc) sp_object_init, + NULL + }; + type = g_type_register_static(G_TYPE_OBJECT, "SPObject", &info, (GTypeFlags)0); + } + return type; +} + +/** + * Initializes the SPObject vtable. + */ +static void +sp_object_class_init(SPObjectClass *klass) +{ + GObjectClass *object_class; + + object_class = (GObjectClass *) klass; + + parent_class = (GObjectClass *) g_type_class_ref(G_TYPE_OBJECT); + + object_signals[RELEASE] = g_signal_new("release", + G_TYPE_FROM_CLASS(klass), + (GSignalFlags)(G_SIGNAL_RUN_CLEANUP | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS), + G_STRUCT_OFFSET(SPObjectClass, release), + NULL, NULL, + sp_marshal_VOID__VOID, + G_TYPE_NONE, 0); + object_signals[MODIFIED] = g_signal_new("modified", + G_TYPE_FROM_CLASS(klass), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET(SPObjectClass, modified), + NULL, NULL, + sp_marshal_NONE__UINT, + G_TYPE_NONE, 1, G_TYPE_UINT); + + object_class->finalize = sp_object_finalize; + + klass->child_added = sp_object_child_added; + klass->remove_child = sp_object_remove_child; + klass->order_changed = sp_object_order_changed; + + klass->release = sp_object_release; + + klass->build = sp_object_build; + + klass->set = sp_object_private_set; + klass->write = sp_object_private_write; +} + +/** + * Callback to initialize the SPObject object. + */ +static void +sp_object_init(SPObject *object) +{ + debug("id=%x, typename=%s",object, g_type_name_from_instance((GTypeInstance*)object)); + + object->hrefcount = 0; + object->_total_hrefcount = 0; + object->document = NULL; + object->children = object->_last_child = NULL; + object->parent = object->next = NULL; + object->repr = NULL; + object->id = NULL; + object->style = NULL; + + object->_collection_policy = SPObject::COLLECT_WITH_PARENT; + + new (&object->_delete_signal) sigc::signal(); + object->_successor = NULL; + + object->_label = NULL; + object->_default_label = NULL; +} + +/** + * Callback to destroy all members and connections of object and itself. + */ +static void +sp_object_finalize(GObject *object) +{ + SPObject *spobject = (SPObject *)object; + + g_free(spobject->_label); + g_free(spobject->_default_label); + spobject->_label = NULL; + spobject->_default_label = NULL; + + if (spobject->_successor) { + sp_object_unref(spobject->_successor, NULL); + spobject->_successor = NULL; + } + + if (((GObjectClass *) (parent_class))->finalize) { + (* ((GObjectClass *) (parent_class))->finalize)(object); + } + + spobject->_delete_signal.~signal(); +} + +namespace { + +Inkscape::Util::SharedCStringPtr stringify(SPObject *obj) { + char *temp=g_strdup_printf("%p", obj); + Inkscape::Util::SharedCStringPtr result=Inkscape::Util::SharedCStringPtr::copy(temp); + g_free(temp); + return result; +} + +Inkscape::Util::SharedCStringPtr stringify(unsigned n) { + char *temp=g_strdup_printf("%u", n); + Inkscape::Util::SharedCStringPtr result=Inkscape::Util::SharedCStringPtr::copy(temp); + g_free(temp); + return result; +} + +class RefEvent : public Inkscape::Debug::Event { +public: + enum Type { REF, UNREF }; + + RefEvent(SPObject *object, Type type) + : _object(stringify(object)), _refcount(G_OBJECT(object)->ref_count), + _type(type) + {} + + static Category category() { return REFCOUNT; } + + Inkscape::Util::SharedCStringPtr name() const { + if ( _type == REF) { + return Inkscape::Util::SharedCStringPtr::coerce("sp-object-ref"); + } else { + return Inkscape::Util::SharedCStringPtr::coerce("sp-object-unref"); + } + } + unsigned propertyCount() const { return 2; } + PropertyPair property(unsigned index) const { + switch (index) { + case 0: + return PropertyPair("object", _object); + case 1: + return PropertyPair("refcount", stringify( _type == REF ? _refcount + 1 : _refcount - 1 )); + default: + return PropertyPair(); + } + } + +private: + Inkscape::Util::SharedCStringPtr _object; + unsigned _refcount; + Type _type; +}; + +} + +/** + * Increase reference count of object, with possible debugging. + * + * \param owner If non-NULL, make debug log entry. + * \return object, NULL is error. + * \pre object points to real object + */ +SPObject * +sp_object_ref(SPObject *object, SPObject *owner) +{ + g_return_val_if_fail(object != NULL, NULL); + g_return_val_if_fail(SP_IS_OBJECT(object), NULL); + g_return_val_if_fail(!owner || SP_IS_OBJECT(owner), NULL); + + Inkscape::Debug::EventTracker<> tracker; + tracker.set(object, RefEvent::REF); + + g_object_ref(G_OBJECT(object)); + + return object; +} + +/** + * Decrease reference count of object, with possible debugging and + * finalization. + * + * \param owner If non-NULL, make debug log entry. + * \return always NULL + * \pre object points to real object + */ +SPObject * +sp_object_unref(SPObject *object, SPObject *owner) +{ + g_return_val_if_fail(object != NULL, NULL); + g_return_val_if_fail(SP_IS_OBJECT(object), NULL); + g_return_val_if_fail(!owner || SP_IS_OBJECT(owner), NULL); + + Inkscape::Debug::EventTracker<> tracker; + tracker.set(object, RefEvent::UNREF); + + g_object_unref(G_OBJECT(object)); + + return NULL; +} + +/** + * Increase weak refcount. + * + * Hrefcount is used for weak references, for example, to + * determine whether any graphical element references a certain gradient + * node. + * \param owner Ignored. + * \return object, NULL is error + * \pre object points to real object + */ +SPObject * +sp_object_href(SPObject *object, gpointer owner) +{ + g_return_val_if_fail(object != NULL, NULL); + g_return_val_if_fail(SP_IS_OBJECT(object), NULL); + + object->hrefcount++; + object->_updateTotalHRefCount(1); + + return object; +} + +/** + * Decrease weak refcount. + * + * Hrefcount is used for weak references, for example, to determine whether + * any graphical element references a certain gradient node. + * \param owner Ignored. + * \return always NULL + * \pre object points to real object and hrefcount>0 + */ +SPObject * +sp_object_hunref(SPObject *object, gpointer owner) +{ + g_return_val_if_fail(object != NULL, NULL); + g_return_val_if_fail(SP_IS_OBJECT(object), NULL); + g_return_val_if_fail(object->hrefcount > 0, NULL); + + object->hrefcount--; + object->_updateTotalHRefCount(-1); + + return NULL; +} + +/** + * Adds increment to _total_hrefcount of object and its parents. + */ +void +SPObject::_updateTotalHRefCount(int increment) { + SPObject *topmost_collectable = NULL; + for ( SPObject *iter = this ; iter ; iter = SP_OBJECT_PARENT(iter) ) { + iter->_total_hrefcount += increment; + if ( iter->_total_hrefcount < iter->hrefcount ) { + g_critical("HRefs overcounted"); + } + if ( iter->_total_hrefcount == 0 && + iter->_collection_policy != COLLECT_WITH_PARENT ) + { + topmost_collectable = iter; + } + } + if (topmost_collectable) { + topmost_collectable->requestOrphanCollection(); + } +} + +/** + * True if object is non-NULL and this is some in/direct parent of object. + */ +bool +SPObject::isAncestorOf(SPObject const *object) const { + g_return_val_if_fail(object != NULL, false); + object = SP_OBJECT_PARENT(object); + while (object) { + if ( object == this ) { + return true; + } + object = SP_OBJECT_PARENT(object); + } + return false; +} + +namespace { + +bool same_objects(SPObject const &a, SPObject const &b) { + return &a == &b; +} + +} + +/** + * Returns youngest object being parent to this and object. + */ +SPObject const * +SPObject::nearestCommonAncestor(SPObject const *object) const { + g_return_val_if_fail(object != NULL, NULL); + + using Inkscape::Algorithms::longest_common_suffix; + return longest_common_suffix(this, object, NULL, &same_objects); +} + +SPObject const *AncestorSon(SPObject const *obj, SPObject const *ancestor) { + if (obj == NULL || ancestor == NULL) + return NULL; + if (SP_OBJECT_PARENT(obj) == ancestor) + return obj; + return AncestorSon(SP_OBJECT_PARENT(obj), ancestor); +} + +/** + * Compares height of objects in tree. + * + * Works for different-parent objects, so long as they have a common ancestor. + * \return \verbatim + * 0 positions are equivalent + * 1 first object's position is greater than the second + * -1 first object's position is less than the second \endverbatim + */ +int +sp_object_compare_position(SPObject const *first, SPObject const *second) +{ + if (first == second) return 0; + + SPObject const *ancestor = first->nearestCommonAncestor(second); + if (ancestor == NULL) return 0; // cannot compare, no common ancestor! + + // we have an object and its ancestor (should not happen when sorting selection) + if (ancestor == first) + return 1; + if (ancestor == second) + return -1; + + SPObject const *to_first = AncestorSon(first, ancestor); + SPObject const *to_second = AncestorSon(second, ancestor); + + g_assert(SP_OBJECT_PARENT(to_second) == SP_OBJECT_PARENT(to_first)); + + return sp_repr_compare_position(SP_OBJECT_REPR(to_first), SP_OBJECT_REPR(to_second)); +} + + +/** + * Append repr as child of this object. + * \pre this is not a cloned object + */ +SPObject * +SPObject::appendChildRepr(Inkscape::XML::Node *repr) { + if (!SP_OBJECT_IS_CLONED(this)) { + SP_OBJECT_REPR(this)->appendChild(repr); + return SP_OBJECT_DOCUMENT(this)->getObjectByRepr(repr); + } else { + g_critical("Attempt to append repr as child of cloned object"); + return NULL; + } +} + +/** Gets the label property for the object or a default if no label + * is defined. + */ +gchar const * +SPObject::label() const { + return _label; +} + +/** Returns a default label property for the object. */ +gchar const * +SPObject::defaultLabel() const { + if (_label) { + return _label; + } else { + if (!_default_label) { + gchar const *id=SP_OBJECT_ID(this); + if (id) { + _default_label = g_strdup_printf("#%s", id); + } else { + _default_label = g_strdup_printf("<%s>", SP_OBJECT_REPR(this)->name()); + } + } + return _default_label; + } +} + +/** Sets the label property for the object */ +void +SPObject::setLabel(gchar const *label) { + SP_OBJECT_REPR(this)->setAttribute("inkscape:label", label, false); +} + + +/** Queues the object for orphan collection */ +void +SPObject::requestOrphanCollection() { + g_return_if_fail(document != NULL); + document->queueForOrphanCollection(this); + + /** \todo + * This is a temporary hack added to make fill&stroke rebuild its + * gradient list when the defs are vacuumed. gradient-vector.cpp + * listens to the modified signal on defs, and now we give it that + * signal. Mental says that this should be made automatic by + * merging SPObjectGroup with SPObject; SPObjectGroup would issue + * this signal automatically. Or maybe just derive SPDefs from + * SPObjectGroup? + */ + + this->requestModified(SP_OBJECT_CHILD_MODIFIED_FLAG); +} + +/** Sends the delete signal to all children of this object recursively */ +void +SPObject::_sendDeleteSignalRecursive() { + for (SPObject *child = sp_object_first_child(this); child; child = SP_OBJECT_NEXT(child)) { + child->_delete_signal.emit(child); + child->_sendDeleteSignalRecursive(); + } +} + +/** + * Deletes the object reference, unparenting it from its parent. + * + * If the \a propagate parameter is set to true, it emits a delete + * signal. If the \a propagate_descendants parameter is true, it + * recursively sends the delete signal to children. + */ +void +SPObject::deleteObject(bool propagate, bool propagate_descendants) +{ + sp_object_ref(this, NULL); + if (propagate) { + _delete_signal.emit(this); + } + if (propagate_descendants) { + this->_sendDeleteSignalRecursive(); + } + + Inkscape::XML::Node *repr=SP_OBJECT_REPR(this); + if (repr && sp_repr_parent(repr)) { + sp_repr_unparent(repr); + } + + if (_successor) { + _successor->deleteObject(propagate, propagate_descendants); + } + sp_object_unref(this, NULL); +} + +/** + * Put object into object tree, under parent, and behind prev; + * also update object's XML space. + */ +void +sp_object_attach(SPObject *parent, SPObject *object, SPObject *prev) +{ + g_return_if_fail(parent != NULL); + g_return_if_fail(SP_IS_OBJECT(parent)); + g_return_if_fail(object != NULL); + g_return_if_fail(SP_IS_OBJECT(object)); + g_return_if_fail(!prev || SP_IS_OBJECT(prev)); + g_return_if_fail(!prev || prev->parent == parent); + g_return_if_fail(!object->parent); + + sp_object_ref(object, parent); + object->parent = parent; + parent->_updateTotalHRefCount(object->_total_hrefcount); + + SPObject *next; + if (prev) { + next = prev->next; + prev->next = object; + } else { + next = parent->children; + parent->children = object; + } + object->next = next; + if (!next) { + parent->_last_child = object; + } + if (!object->xml_space.set) + object->xml_space.value = parent->xml_space.value; +} + +/** + * In list of object's siblings, move object behind prev. + */ +void +sp_object_reorder(SPObject *object, SPObject *prev) { + g_return_if_fail(object != NULL); + g_return_if_fail(SP_IS_OBJECT(object)); + g_return_if_fail(object->parent != NULL); + g_return_if_fail(object != prev); + g_return_if_fail(!prev || SP_IS_OBJECT(prev)); + g_return_if_fail(!prev || prev->parent == object->parent); + + SPObject *const parent=object->parent; + + SPObject *old_prev=NULL; + for ( SPObject *child = parent->children ; child && child != object ; + child = child->next ) + { + old_prev = child; + } + + SPObject *next=object->next; + if (old_prev) { + old_prev->next = next; + } else { + parent->children = next; + } + if (!next) { + parent->_last_child = old_prev; + } + if (prev) { + next = prev->next; + prev->next = object; + } else { + next = parent->children; + parent->children = object; + } + object->next = next; + if (!next) { + parent->_last_child = object; + } +} + +/** + * Remove object from parent's children, release and unref it. + */ +void +sp_object_detach(SPObject *parent, SPObject *object) { + g_return_if_fail(parent != NULL); + g_return_if_fail(SP_IS_OBJECT(parent)); + g_return_if_fail(object != NULL); + g_return_if_fail(SP_IS_OBJECT(object)); + g_return_if_fail(object->parent == parent); + + SPObject *prev=NULL; + for ( SPObject *child = parent->children ; child && child != object ; + child = child->next ) + { + prev = child; + } + + SPObject *next=object->next; + if (prev) { + prev->next = next; + } else { + parent->children = next; + } + if (!next) { + parent->_last_child = prev; + } + + object->next = NULL; + object->parent = NULL; + + sp_object_invoke_release(object); + parent->_updateTotalHRefCount(-object->_total_hrefcount); + sp_object_unref(object, parent); +} + +/** + * Return object's child whose node pointer equals repr. + */ +SPObject * +sp_object_get_child_by_repr(SPObject *object, Inkscape::XML::Node *repr) +{ + g_return_val_if_fail(object != NULL, NULL); + g_return_val_if_fail(SP_IS_OBJECT(object), NULL); + g_return_val_if_fail(repr != NULL, NULL); + + if (object->_last_child && SP_OBJECT_REPR(object->_last_child) == repr) + return object->_last_child; // optimization for common scenario + for ( SPObject *child = object->children ; child ; child = child->next ) { + if ( SP_OBJECT_REPR(child) == repr ) { + return child; + } + } + + return NULL; +} + +/** + * Callback for child_added event. + * Invoked whenever the given mutation event happens in the XML tree. + */ +static void +sp_object_child_added(SPObject *object, Inkscape::XML::Node *child, Inkscape::XML::Node *ref) +{ + GType type = sp_repr_type_lookup(child); + if (!type) { + return; + } + SPObject *ochild = SP_OBJECT(g_object_new(type, 0)); + SPObject *prev = ref ? sp_object_get_child_by_repr(object, ref) : NULL; + sp_object_attach(object, ochild, prev); + sp_object_unref(ochild, NULL); + + sp_object_invoke_build(ochild, object->document, child, SP_OBJECT_IS_CLONED(object)); +} + +/** + * Removes, releases and unrefs all children of object. + * + * This is the opposite of build. It has to be invoked as soon as the + * object is removed from the tree, even if it is still alive according + * to reference count. The frontend unregisters the object from the + * document and releases the SPRepr bindings; implementations should free + * state data and release all child objects. Invoking release on + * SPRoot destroys the whole document tree. + * \see sp_object_build() + */ +static void sp_object_release(SPObject *object) +{ + debug("id=%x, typename=%s", object, g_type_name_from_instance((GTypeInstance*)object)); + while (object->children) { + sp_object_detach(object, object->children); + } +} + +/** + * Remove object's child whose node equals repr, release and + * unref it. + * + * Invoked whenever the given mutation event happens in the XML + * tree, BEFORE removal from the XML tree happens, so grouping + * objects can safely release the child data. + */ +static void +sp_object_remove_child(SPObject *object, Inkscape::XML::Node *child) +{ + debug("id=%x, typename=%s", object, g_type_name_from_instance((GTypeInstance*)object)); + SPObject *ochild = sp_object_get_child_by_repr(object, child); + g_return_if_fail(ochild != NULL); + sp_object_detach(object, ochild); +} + +/** + * Move object corresponding to child after sibling object corresponding + * to new_ref. + * Invoked whenever the given mutation event happens in the XML tree. + * \param old_ref Ignored + */ +static void sp_object_order_changed(SPObject *object, Inkscape::XML::Node *child, Inkscape::XML::Node *old_ref, + Inkscape::XML::Node *new_ref) +{ + SPObject *ochild = sp_object_get_child_by_repr(object, child); + g_return_if_fail(ochild != NULL); + SPObject *prev = new_ref ? sp_object_get_child_by_repr(object, new_ref) : NULL; + sp_object_reorder(ochild, prev); +} + +/** + * Virtual build callback. + * + * This has to be invoked immediately after creation of an SPObject. The + * frontend method ensures that the new object is properly attached to + * the document and repr; implementation then will parse all of the attributes, + * generate the children objects and so on. Invoking build on the SPRoot + * object results in creation of the whole document tree (this is, what + * SPDocument does after the creation of the XML tree). + * \see sp_object_release() + */ +static void +sp_object_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr) +{ + /* Nothing specific here */ + debug("id=%x, typename=%s", object, g_type_name_from_instance((GTypeInstance*)object)); + + sp_object_read_attr(object, "xml:space"); + sp_object_read_attr(object, "inkscape:label"); + sp_object_read_attr(object, "inkscape:collect"); + + for (Inkscape::XML::Node *rchild = repr->firstChild() ; rchild != NULL; rchild = rchild->next()) { + GType type = sp_repr_type_lookup(rchild); + if (!type) { + continue; + } + SPObject *child = SP_OBJECT(g_object_new(type, 0)); + sp_object_attach(object, child, object->lastChild()); + sp_object_unref(child, NULL); + sp_object_invoke_build(child, document, rchild, SP_OBJECT_IS_CLONED(object)); + } +} + +void +sp_object_invoke_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr, unsigned int cloned) +{ + debug("id=%x, typename=%s", object, g_type_name_from_instance((GTypeInstance*)object)); + + g_assert(object != NULL); + g_assert(SP_IS_OBJECT(object)); + g_assert(document != NULL); + g_assert(repr != NULL); + + g_assert(object->document == NULL); + g_assert(object->repr == NULL); + g_assert(object->id == NULL); + + /* Bookkeeping */ + + object->document = document; + object->repr = repr; + Inkscape::GC::anchor(repr); + object->cloned = cloned; + + if (!SP_OBJECT_IS_CLONED(object)) { + object->document->bindObjectToRepr(object->repr, object); + + if (Inkscape::XML::id_permitted(object->repr)) { + /* If we are not cloned, force unique id */ + gchar const *id = object->repr->attribute("id"); + gchar *realid = sp_object_get_unique_id(object, id); + g_assert(realid != NULL); + + object->document->bindObjectToId(realid, object); + object->id = realid; + + /* Redefine ID, if required */ + if ((id == NULL) || (strcmp(id, realid) != 0)) { + gboolean undo_sensitive=sp_document_get_undo_sensitive(document); + sp_document_set_undo_sensitive(document, FALSE); + object->repr->setAttribute("id", realid); + sp_document_set_undo_sensitive(document, undo_sensitive); + } + } + } else { + g_assert(object->id == NULL); + } + + /* Invoke derived methods, if any */ + + if (((SPObjectClass *) G_OBJECT_GET_CLASS(object))->build) { + (*((SPObjectClass *) G_OBJECT_GET_CLASS(object))->build)(object, document, repr); + } + + /* Signalling (should be connected AFTER processing derived methods */ + sp_repr_add_listener(repr, &object_event_vector, object); +} + +void +sp_object_invoke_release(SPObject *object) +{ + g_assert(object != NULL); + g_assert(SP_IS_OBJECT(object)); + + // we need to remember our parent + // g_assert(!object->parent); + g_assert(!object->next); + g_assert(object->document); + g_assert(object->repr); + + sp_repr_remove_listener_by_data(object->repr, object); + + g_signal_emit(G_OBJECT(object), object_signals[RELEASE], 0); + + /* all hrefs should be released by the "release" handlers */ + g_assert(object->hrefcount == 0); + + if (!SP_OBJECT_IS_CLONED(object)) { + if (object->id) { + object->document->bindObjectToId(object->id, NULL); + } + g_free(object->id); + object->id = NULL; + + g_free(object->_default_label); + object->_default_label = NULL; + + object->document->bindObjectToRepr(object->repr, NULL); + } else { + g_assert(!object->id); + } + + if (object->style) { + object->style = sp_style_unref(object->style); + } + + Inkscape::GC::release(object->repr); + + object->document = NULL; + object->repr = NULL; +} + +/** + * Callback for child_added node event. + */ +static void +sp_object_repr_child_added(Inkscape::XML::Node *repr, Inkscape::XML::Node *child, Inkscape::XML::Node *ref, gpointer data) +{ + SPObject *object = SP_OBJECT(data); + + if (((SPObjectClass *) G_OBJECT_GET_CLASS(object))->child_added) + (*((SPObjectClass *)G_OBJECT_GET_CLASS(object))->child_added)(object, child, ref); +} + +/** + * Callback for remove_child node event. + */ +static void +sp_object_repr_child_removed(Inkscape::XML::Node *repr, Inkscape::XML::Node *child, Inkscape::XML::Node *ref, gpointer data) +{ + SPObject *object = SP_OBJECT(data); + + if (((SPObjectClass *) G_OBJECT_GET_CLASS(object))->remove_child) { + (* ((SPObjectClass *)G_OBJECT_GET_CLASS(object))->remove_child)(object, child); + } +} + +/** + * Callback for order_changed node event. + * + * \todo fixme: + */ +static void +sp_object_repr_order_changed(Inkscape::XML::Node *repr, Inkscape::XML::Node *child, Inkscape::XML::Node *old, Inkscape::XML::Node *newer, gpointer data) +{ + SPObject *object = SP_OBJECT(data); + + if (((SPObjectClass *) G_OBJECT_GET_CLASS(object))->order_changed) { + (* ((SPObjectClass *)G_OBJECT_GET_CLASS(object))->order_changed)(object, child, old, newer); + } +} + +/** + * Callback for set event. + */ +static void +sp_object_private_set(SPObject *object, unsigned int key, gchar const *value) +{ + g_assert(key != SP_ATTR_INVALID); + + switch (key) { + case SP_ATTR_ID: + if ( !SP_OBJECT_IS_CLONED(object) && object->repr->type() == Inkscape::XML::ELEMENT_NODE ) { + SPDocument *document=object->document; + SPObject *conflict=NULL; + + if (value) { + conflict = document->getObjectById((char const *)value); + } + if ( conflict && conflict != object ) { + sp_object_ref(conflict, NULL); + // give the conflicting object a new ID + gchar *new_conflict_id = sp_object_get_unique_id(conflict, NULL); + SP_OBJECT_REPR(conflict)->setAttribute("id", new_conflict_id); + g_free(new_conflict_id); + sp_object_unref(conflict, NULL); + } + + if (object->id) { + document->bindObjectToId(object->id, NULL); + g_free(object->id); + } + + if (value) { + object->id = g_strdup((char const*)value); + document->bindObjectToId(object->id, object); + } else { + object->id = NULL; + } + + g_free(object->_default_label); + object->_default_label = NULL; + } + break; + case SP_ATTR_INKSCAPE_LABEL: + g_free(object->_label); + if (value) { + object->_label = g_strdup(value); + } else { + object->_label = NULL; + } + g_free(object->_default_label); + object->_default_label = NULL; + break; + case SP_ATTR_INKSCAPE_COLLECT: + if ( value && !strcmp(value, "always") ) { + object->setCollectionPolicy(SPObject::ALWAYS_COLLECT); + } else { + object->setCollectionPolicy(SPObject::COLLECT_WITH_PARENT); + } + break; + case SP_ATTR_XML_SPACE: + if (value && !strcmp(value, "preserve")) { + object->xml_space.value = SP_XML_SPACE_PRESERVE; + object->xml_space.set = TRUE; + } else if (value && !strcmp(value, "default")) { + object->xml_space.value = SP_XML_SPACE_DEFAULT; + object->xml_space.set = TRUE; + } else if (object->parent) { + SPObject *parent; + parent = object->parent; + object->xml_space.value = parent->xml_space.value; + } + object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG); + break; + default: + break; + } +} + +/** + * Call virtual set() function of object. + */ +void +sp_object_set(SPObject *object, unsigned int key, gchar const *value) +{ + g_assert(object != NULL); + g_assert(SP_IS_OBJECT(object)); + + if (((SPObjectClass *) G_OBJECT_GET_CLASS(object))->set) { + ((SPObjectClass *) G_OBJECT_GET_CLASS(object))->set(object, key, value); + } +} + +/** + * Read value of key attribute from XML node into object. + */ +void +sp_object_read_attr(SPObject *object, gchar const *key) +{ + g_assert(object != NULL); + g_assert(SP_IS_OBJECT(object)); + g_assert(key != NULL); + + g_assert(object->repr != NULL); + + unsigned int keyid = sp_attribute_lookup(key); + if (keyid != SP_ATTR_INVALID) { + /* Retrieve the 'key' attribute from the object's XML representation */ + gchar const *value = object->repr->attribute(key); + + sp_object_set(object, keyid, value); + } +} + +/** + * Callback for attr_changed node event. + */ +static void +sp_object_repr_attr_changed(Inkscape::XML::Node *repr, gchar const *key, gchar const *oldval, gchar const *newval, bool is_interactive, gpointer data) +{ + SPObject *object = SP_OBJECT(data); + + sp_object_read_attr(object, key); + + // manual changes to extension attributes require the normal + // attributes, which depend on them, to be updated immediately + if (is_interactive) { + object->updateRepr(repr, 0); + } +} + +/** + * Callback for content_changed node event. + */ +static void +sp_object_repr_content_changed(Inkscape::XML::Node *repr, gchar const *oldcontent, gchar const *newcontent, gpointer data) +{ + SPObject *object = SP_OBJECT(data); + + if (((SPObjectClass *) G_OBJECT_GET_CLASS(object))->read_content) + (*((SPObjectClass *) G_OBJECT_GET_CLASS(object))->read_content)(object); +} + +/** + * Return string representation of space value. + */ +static gchar const* +sp_xml_get_space_string(unsigned int space) +{ + switch (space) { + case SP_XML_SPACE_DEFAULT: + return "default"; + case SP_XML_SPACE_PRESERVE: + return "preserve"; + default: + return NULL; + } +} + +/** + * Callback for write event. + */ +static Inkscape::XML::Node * +sp_object_private_write(SPObject *object, Inkscape::XML::Node *repr, guint flags) +{ + if (!repr && (flags & SP_OBJECT_WRITE_BUILD)) { + repr = SP_OBJECT_REPR(object)->duplicate(); + if (!( flags & SP_OBJECT_WRITE_EXT )) { + repr->setAttribute("inkscape:collect", NULL); + } + } else { + repr->setAttribute("id", object->id); + + if (object->xml_space.set) { + char const *xml_space; + xml_space = sp_xml_get_space_string(object->xml_space.value); + repr->setAttribute("xml:space", xml_space); + } + + if ( flags & SP_OBJECT_WRITE_EXT && + object->collectionPolicy() == SPObject::ALWAYS_COLLECT ) + { + repr->setAttribute("inkscape:collect", "always"); + } else { + repr->setAttribute("inkscape:collect", NULL); + } + } + + return repr; +} + +/** + * Update this object's XML node with flags value. + */ +Inkscape::XML::Node * +SPObject::updateRepr(unsigned int flags) { + if (!SP_OBJECT_IS_CLONED(this)) { + Inkscape::XML::Node *repr=SP_OBJECT_REPR(this); + if (repr) { + return updateRepr(repr, flags); + } else { + g_critical("Attempt to update non-existent repr"); + return NULL; + } + } else { + /* cloned objects have no repr */ + return NULL; + } +} + +Inkscape::XML::Node * +SPObject::updateRepr(Inkscape::XML::Node *repr, unsigned int flags) { + if (SP_OBJECT_IS_CLONED(this)) { + /* cloned objects have no repr */ + return NULL; + } + if (((SPObjectClass *) G_OBJECT_GET_CLASS(this))->write) { + if (!(flags & SP_OBJECT_WRITE_BUILD) && !repr) { + repr = SP_OBJECT_REPR(this); + } + return ((SPObjectClass *) G_OBJECT_GET_CLASS(this))->write(this, repr, flags); + } else { + g_warning("Class %s does not implement ::write", G_OBJECT_TYPE_NAME(this)); + if (!repr) { + if (flags & SP_OBJECT_WRITE_BUILD) { + repr = SP_OBJECT_REPR(this)->duplicate(); + } + /// \todo fixme: else probably error (Lauris) */ + } else { + repr->mergeFrom(SP_OBJECT_REPR(this), "id"); + } + return repr; + } +} + +/* Modification */ + +/** + * Add \a flags to \a object's as dirtiness flags, and + * recursively add CHILD_MODIFIED flag to + * parent and ancestors (as far up as necessary). + */ +void +SPObject::requestDisplayUpdate(unsigned int flags) +{ + if (update_in_progress) { + g_print("WARNING: Requested update while update in progress, counter = %d\n", update_in_progress); + } + + g_return_if_fail(!(flags & SP_OBJECT_PARENT_MODIFIED_FLAG)); + g_return_if_fail((flags & SP_OBJECT_MODIFIED_FLAG) || (flags & SP_OBJECT_CHILD_MODIFIED_FLAG)); + g_return_if_fail(!((flags & SP_OBJECT_MODIFIED_FLAG) && (flags & SP_OBJECT_CHILD_MODIFIED_FLAG))); + + /* Check for propagate before we set any flags */ + /* Propagate means, that this is not passed through by modification request cascade yet */ + unsigned int propagate = (!(this->uflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))); + + /* Just set this flags safe even if some have been set before */ + this->uflags |= flags; + + if (propagate) { + if (this->parent) { + this->parent->requestDisplayUpdate(SP_OBJECT_CHILD_MODIFIED_FLAG); + } else { + sp_document_request_modified(this->document); + } + } +} + +void +SPObject::updateDisplay(SPCtx *ctx, unsigned int flags) +{ + g_return_if_fail(!(flags & ~SP_OBJECT_MODIFIED_CASCADE)); + + update_in_progress ++; + +#ifdef SP_OBJECT_DEBUG_CASCADE + g_print("Update %s:%s %x %x %x\n", g_type_name_from_instance((GTypeInstance *) this), SP_OBJECT_ID(this), flags, this->uflags, this->mflags); +#endif + + /* Get this flags */ + flags |= this->uflags; + /* Copy flags to modified cascade for later processing */ + this->mflags |= this->uflags; + /* We have to clear flags here to allow rescheduling update */ + this->uflags = 0; + + // Merge style if we have good reasons to think that parent style is changed */ + /** \todo + * I am not sure whether we should check only propagated + * flag. We are currently assuming that style parsing is + * done immediately. I think this is correct (Lauris). + */ + if ((flags & SP_OBJECT_STYLE_MODIFIED_FLAG) && (flags & SP_OBJECT_PARENT_MODIFIED_FLAG)) { + if (this->style && this->parent) { + sp_style_merge_from_parent(this->style, this->parent->style); + } + } + + if (((SPObjectClass *) G_OBJECT_GET_CLASS(this))->update) + ((SPObjectClass *) G_OBJECT_GET_CLASS(this))->update(this, ctx, flags); + + update_in_progress --; +} + +void +SPObject::requestModified(unsigned int flags) +{ + g_return_if_fail( this->document != NULL ); + + /* PARENT_MODIFIED is computed later on and is not intended to be + * "manually" queued */ + g_return_if_fail(!(flags & SP_OBJECT_PARENT_MODIFIED_FLAG)); + + /* we should be setting either MODIFIED or CHILD_MODIFIED... */ + g_return_if_fail((flags & SP_OBJECT_MODIFIED_FLAG) || (flags & SP_OBJECT_CHILD_MODIFIED_FLAG)); + + /* ...but not both */ + g_return_if_fail(!((flags & SP_OBJECT_MODIFIED_FLAG) && (flags & SP_OBJECT_CHILD_MODIFIED_FLAG))); + + unsigned int old_mflags=this->mflags; + this->mflags |= flags; + + /* If we already had MODIFIED or CHILD_MODIFIED queued, we will + * have already queued CHILD_MODIFIED with our ancestors and + * need not disturb them again. + */ + if (!( old_mflags & ( SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG ) )) { + SPObject *parent=SP_OBJECT_PARENT(this); + if (parent) { + parent->requestModified(SP_OBJECT_CHILD_MODIFIED_FLAG); + } else { + sp_document_request_modified(SP_OBJECT_DOCUMENT(this)); + } + } +} + +void +SPObject::emitModified(unsigned int flags) +{ + /* only the MODIFIED_CASCADE flag is legal here */ + g_return_if_fail(!(flags & ~SP_OBJECT_MODIFIED_CASCADE)); + +#ifdef SP_OBJECT_DEBUG_CASCADE + g_print("Modified %s:%s %x %x %x\n", g_type_name_from_instance((GTypeInstance *) this), SP_OBJECT_ID(this), flags, this->uflags, this->mflags); +#endif + + flags |= this->mflags; + /* We have to clear mflags beforehand, as signal handlers may + * make changes and therefore queue new modification notifications + * themselves. */ + this->mflags = 0; + + g_object_ref(G_OBJECT(this)); + g_signal_emit(G_OBJECT(this), object_signals[MODIFIED], 0, flags); + g_object_unref(G_OBJECT(this)); +} + +/* + * Get and set descriptive parameters + * + * These are inefficent, so they are not intended to be used interactively + */ + +gchar const * +sp_object_title_get(SPObject *object) +{ + return NULL; +} + +gchar const * +sp_object_description_get(SPObject *object) +{ + return NULL; +} + +unsigned int +sp_object_title_set(SPObject *object, gchar const *title) +{ + return FALSE; +} + +unsigned int +sp_object_description_set(SPObject *object, gchar const *desc) +{ + return FALSE; +} + +gchar const * +sp_object_tagName_get(SPObject const *object, SPException *ex) +{ + /* If exception is not clear, return */ + if (!SP_EXCEPTION_IS_OK(ex)) { + return NULL; + } + + /// \todo fixme: Exception if object is NULL? */ + return object->repr->name(); +} + +gchar const * +sp_object_getAttribute(SPObject const *object, gchar const *key, SPException *ex) +{ + /* If exception is not clear, return */ + if (!SP_EXCEPTION_IS_OK(ex)) { + return NULL; + } + + /// \todo fixme: Exception if object is NULL? */ + return (gchar const *) object->repr->attribute(key); +} + +void +sp_object_setAttribute(SPObject *object, gchar const *key, gchar const *value, SPException *ex) +{ + /* If exception is not clear, return */ + g_return_if_fail(SP_EXCEPTION_IS_OK(ex)); + + /// \todo fixme: Exception if object is NULL? */ + if (!sp_repr_set_attr(object->repr, key, value)) { + ex->code = SP_NO_MODIFICATION_ALLOWED_ERR; + } +} + +void +sp_object_removeAttribute(SPObject *object, gchar const *key, SPException *ex) +{ + /* If exception is not clear, return */ + g_return_if_fail(SP_EXCEPTION_IS_OK(ex)); + + /// \todo fixme: Exception if object is NULL? */ + if (!sp_repr_set_attr(object->repr, key, NULL)) { + ex->code = SP_NO_MODIFICATION_ALLOWED_ERR; + } +} + +/* Helper */ + +static gchar * +sp_object_get_unique_id(SPObject *object, gchar const *id) +{ + static unsigned long count = 0; + + g_assert(SP_IS_OBJECT(object)); + + count++; + + gchar const *name = object->repr->name(); + g_assert(name != NULL); + + gchar const *local = strchr(name, ':'); + if (local) { + name = local + 1; + } + + if (id != NULL) { + if (object->document->getObjectById(id) == NULL) { + return g_strdup(id); + } + } + + size_t const name_len = strlen(name); + size_t const buflen = name_len + (sizeof(count) * 10 / 4) + 1; + gchar *const buf = (gchar *) g_malloc(buflen); + memcpy(buf, name, name_len); + gchar *const count_buf = buf + name_len; + size_t const count_buflen = buflen - name_len; + do { + ++count; + g_snprintf(count_buf, count_buflen, "%lu", count); + } while ( object->document->getObjectById(buf) != NULL ); + return buf; +} + +/* Style */ + +/** + * Returns an object style property. + * + * \todo + * fixme: Use proper CSS parsing. The current version is buggy + * in a number of situations where key is a substring of the + * style string other than as a property name (including + * where key is a substring of a property name), and is also + * buggy in its handling of inheritance for properties that + * aren't inherited by default. It also doesn't allow for + * the case where the property is specified but with an invalid + * value (in which case I believe the CSS2 error-handling + * behaviour applies, viz. behave as if the property hadn't + * been specified). Also, the current code doesn't use CRSelEng + * stuff to take a value from stylesheets. Also, we aren't + * setting any hooks to force an update for changes in any of + * the inputs (i.e., in any of the elements that this function + * queries). + * + * \par + * Given that the default value for a property depends on what + * property it is (e.g., whether to inherit or not), and given + * the above comment about ignoring invalid values, and that the + * repr parent isn't necessarily the right element to inherit + * from (e.g., maybe we need to inherit from the referencing + * element instead), we should probably make the caller + * responsible for ascending the repr tree as necessary. + */ +gchar const * +sp_object_get_style_property(SPObject const *object, gchar const *key, gchar const *def) +{ + g_return_val_if_fail(object != NULL, NULL); + g_return_val_if_fail(SP_IS_OBJECT(object), NULL); + g_return_val_if_fail(key != NULL, NULL); + + gchar const *style = object->repr->attribute("style"); + if (style) { + size_t const len = strlen(key); + char const *p; + while ( (p = strstr(style, key)) + != NULL ) + { + p += len; + while ((*p <= ' ') && *p) p++; + if (*p++ != ':') break; + while ((*p <= ' ') && *p) p++; + size_t const inherit_len = sizeof("inherit") - 1; + if (*p + && !(strneq(p, "inherit", inherit_len) + && (p[inherit_len] == '\0' + || p[inherit_len] == ';' + || g_ascii_isspace(p[inherit_len])))) { + return p; + } + } + } + gchar const *val = object->repr->attribute(key); + if (val && !streq(val, "inherit")) { + return val; + } + if (object->parent) { + return sp_object_get_style_property(object->parent, key, def); + } + + return def; +} + +/** + * Lifts SVG version of all root objects to version. + */ +void +SPObject::_requireSVGVersion(Inkscape::Version version) { + for ( SPObject::ParentIterator iter=this ; iter ; ++iter ) { + SPObject *object=iter; + if (SP_IS_ROOT(object)) { + SPRoot *root=SP_ROOT(object); + if ( root->version.svg < version ) { + root->version.svg = version; + } + } + } +} + +/** + * Return sodipodi version of first root ancestor or (0,0). + */ +Inkscape::Version +sp_object_get_sodipodi_version(SPObject *object) +{ + static Inkscape::Version const zero_version(0, 0); + + while (object) { + if (SP_IS_ROOT(object)) { + return SP_ROOT(object)->version.sodipodi; + } + object = SP_OBJECT_PARENT(object); + } + + return zero_version; +} + +/** + * Returns previous object in sibling list or NULL. + */ +SPObject * +sp_object_prev(SPObject *child) +{ + SPObject *parent = SP_OBJECT_PARENT(child); + for ( SPObject *i = sp_object_first_child(parent); i; i = SP_OBJECT_NEXT(i) ) { + if (SP_OBJECT_NEXT(i) == child) + return i; + } + return NULL; +} + + +/* + 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:textwidth=99 : diff --git a/src/sp-object.h b/src/sp-object.h new file mode 100644 index 000000000..767f8b978 --- /dev/null +++ b/src/sp-object.h @@ -0,0 +1,539 @@ +#ifndef __SP_OBJECT_H__ +#define __SP_OBJECT_H__ + +/** \file + * Abstract base class for all nodes + * + * Authors: + * Lauris Kaplinski + * + * Copyright (C) 1999-2002 authors + * Copyright (C) 2001-2002 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +/* SPObject flags */ + +/* Async modification flags */ +#define SP_OBJECT_MODIFIED_FLAG (1 << 0) +#define SP_OBJECT_CHILD_MODIFIED_FLAG (1 << 1) +#define SP_OBJECT_PARENT_MODIFIED_FLAG (1 << 2) +#define SP_OBJECT_STYLE_MODIFIED_FLAG (1 << 3) +#define SP_OBJECT_VIEWPORT_MODIFIED_FLAG (1 << 4) +#define SP_OBJECT_USER_MODIFIED_FLAG_A (1 << 5) +#define SP_OBJECT_USER_MODIFIED_FLAG_B (1 << 6) +#define SP_OBJECT_USER_MODIFIED_FLAG_C (1 << 7) + +/* Conveneience */ +#define SP_OBJECT_FLAGS_ALL 0xff + +/* Flags that mark object as modified */ +/* Object, Child, Style, Viewport, User */ +#define SP_OBJECT_MODIFIED_STATE (SP_OBJECT_FLAGS_ALL & ~(SP_OBJECT_PARENT_MODIFIED_FLAG)) + +/* Flags that will propagate downstreams */ +/* Parent, Style, Viewport, User */ +#define SP_OBJECT_MODIFIED_CASCADE (SP_OBJECT_FLAGS_ALL & ~(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG)) + +/* Generic */ +#define SP_OBJECT_IS_CLONED(o) (((SPObject *) (o))->cloned) + +/* Write flags */ +#define SP_OBJECT_WRITE_BUILD (1 << 0) +#define SP_OBJECT_WRITE_EXT (1 << 1) +#define SP_OBJECT_WRITE_ALL (1 << 2) + +/* Convenience stuff */ +#define SP_OBJECT_ID(o) (((SPObject *) (o))->id) +#define SP_OBJECT_REPR(o) (((SPObject *) (o))->repr) +#define SP_OBJECT_DOCUMENT(o) (((SPObject *) (o))->document) +#define SP_OBJECT_PARENT(o) (((SPObject *) (o))->parent) +#define SP_OBJECT_NEXT(o) (((SPObject *) (o))->next) +#define SP_OBJECT_PREV(o) (sp_object_prev((SPObject *) (o))) +#define SP_OBJECT_HREFCOUNT(o) (((SPObject *) (o))->hrefcount) +#define SP_OBJECT_STYLE(o) (((SPObject *) (o))->style) +#define SP_OBJECT_TITLE(o) sp_object_title_get((SPObject *) (o)) +#define SP_OBJECT_DESCRIPTION(o) sp_object_description_get((SPObject *) (o)) + + +#include +#include +#include +#include + +#include "forward.h" +#include "version.h" +#include "util/forward-pointer-iterator.h" + +namespace Inkscape { +namespace XML { +class Node; +} +} + + +typedef enum { + SP_NO_EXCEPTION, + SP_INDEX_SIZE_ERR, + SP_DOMSTRING_SIZE_ERR, + SP_HIERARCHY_REQUEST_ERR, + SP_WRONG_DOCUMENT_ERR, + SP_INVALID_CHARACTER_ERR, + SP_NO_DATA_ALLOWED_ERR, + SP_NO_MODIFICATION_ALLOWED_ERR, + SP_NOT_FOUND_ERR, + SP_NOT_SUPPORTED_ERR, + SP_INUSE_ATTRIBUTE_ERR, + SP_INVALID_STATE_ERR, + SP_SYNTAX_ERR, + SP_INVALID_MODIFICATION_ERR, + SP_NAMESPACE_ERR, + SP_INVALID_ACCESS_ERR +} SPExceptionType; + +class SPException; + +/// An attempt to implement exceptions, unused? +struct SPException { + SPExceptionType code; +}; + +#define SP_EXCEPTION_INIT(ex) {(ex)->code = SP_NO_EXCEPTION;} +#define SP_EXCEPTION_IS_OK(ex) (!(ex) || ((ex)->code == SP_NO_EXCEPTION)) + +class SPCtx; + +/// Unused +struct SPCtx { + unsigned int flags; +}; + +enum { + SP_XML_SPACE_DEFAULT, + SP_XML_SPACE_PRESERVE +}; + +class SPIXmlSpace; + +/// Internal class consisting of two bits. +struct SPIXmlSpace { + guint set : 1; + guint value : 1; +}; + +class SPObject; + +/* + * Refcounting + * + * Owner is here for debug reasons, you can set it to NULL safely + * Ref should return object, NULL is error, unref return always NULL + */ + +SPObject *sp_object_ref(SPObject *object, SPObject *owner=NULL); +SPObject *sp_object_unref(SPObject *object, SPObject *owner=NULL); + +SPObject *sp_object_href(SPObject *object, gpointer owner); +SPObject *sp_object_hunref(SPObject *object, gpointer owner); + +/// A refcounting tree node object. +struct SPObject : public GObject { + enum CollectionPolicy { + COLLECT_WITH_PARENT, + ALWAYS_COLLECT + }; + + unsigned int cloned : 1; + unsigned int uflags : 8; + unsigned int mflags : 8; + SPIXmlSpace xml_space; + unsigned int hrefcount; /* number of xlink:href references */ + unsigned int _total_hrefcount; /* our hrefcount + total descendants */ + SPDocument *document; /* Document we are part of */ + SPObject *parent; /* Our parent (only one allowed) */ + SPObject *children; /* Our children */ + SPObject *_last_child; /* Remembered last child */ + SPObject *next; /* Next object in linked list */ + Inkscape::XML::Node *repr; /* Our xml representation */ + gchar *id; /* Our very own unique id */ + + /** + * Represents the style properties, whether from presentation attributes, the style + * attribute, or inherited. + * + * sp_object_private_set doesn't handle SP_ATTR_STYLE or any presentation attributes at the + * time of writing, so this is probably NULL for all SPObject's that aren't an SPItem. + * + * However, this gives rise to the bugs mentioned in sp_object_get_style_property. + * Note that some non-SPItem SPObject's, such as SPStop, do need styling information, + * and need to inherit properties even through other non-SPItem parents like \. + */ + SPStyle *style; + + /// Switch containing next() method. + struct ParentIteratorStrategy { + static SPObject const *next(SPObject const *object) { + return object->parent; + } + }; + /// Switch containing next() method. + struct SiblingIteratorStrategy { + static SPObject const *next(SPObject const *object) { + return object->next; + } + }; + + typedef Inkscape::Util::ForwardPointerIterator ParentIterator; + typedef Inkscape::Util::ForwardPointerIterator ConstParentIterator; + typedef Inkscape::Util::ForwardPointerIterator SiblingIterator; + typedef Inkscape::Util::ForwardPointerIterator ConstSiblingIterator; + + bool isSiblingOf(SPObject const *object) const { + g_return_val_if_fail(object != NULL, false); + return this->parent && this->parent == object->parent; + } + bool isAncestorOf(SPObject const *object) const; + + SPObject const *nearestCommonAncestor(SPObject const *object) const; + /* A non-const version can be similarly constructed if you want one. + * (Don't just cast away the constness, which would be ill-formed.) */ + + bool hasChildren() const { return ( children != NULL ); } + + SPObject *firstChild() { return children; } + SPObject const *firstChild() const { return children; } + SPObject *lastChild() { return _last_child; } + SPObject const *lastChild() const { return _last_child; } + + SPObject *appendChildRepr(Inkscape::XML::Node *repr); + + /** @brief Gets the author-visible label for this object. */ + gchar const *label() const; + /** @brief Returns a default label for this object. */ + gchar const *defaultLabel() const; + /** @brief Sets the author-visible label for this object. + * + * Sets the author-visible label for the object. + * + * @param label the new label + */ + void setLabel(gchar const *label); + + /** Retrieves the title of this object */ + gchar const *title() const { return NULL; /* TODO */ } + /** Sets the title of this object */ + void setTitle(gchar const *title) { /* TODO */ } + + /** Retrieves the description of this object */ + gchar const *desc() const { return NULL; /* TODO */ } + /** Sets the description of this object */ + void setDesc(gchar const *desc) { /* TODO */ } + + /** @brief Set the policy under which this object will be + * orphan-collected. + * + * Orphan-collection is the process of deleting all objects which no longer have + * hyper-references pointing to them. The policy determines when this happens. Many objects + * should not be deleted simply because they are no longer referred to; other objects (like + * "intermediate" gradients) are more or less throw-away and should always be collected when no + * longer in use. + * + * Along these lines, there are currently two orphan-collection policies: + * + * COLLECT_WITH_PARENT - don't worry about the object's hrefcount; + * if its parent is collected, this object + * will be too + * + * COLLECT_ALWAYS - always collect the object as soon as its + * hrefcount reaches zero + * + * @returns the current collection policy in effect for this object + */ + CollectionPolicy collectionPolicy() const { return _collection_policy; } + + /** @brief Sets the orphan-collection policy in effect for this object. + * + * @see SPObject::collectionPolicy + * + * @param policy the new policy to adopt + */ + void setCollectionPolicy(CollectionPolicy policy) { + _collection_policy = policy; + } + + /** @brief Requests a later automatic call to collectOrphan(). + * + * This method requests that collectOrphan() be called during the document update cycle, + * deleting the object if it is no longer used. + * + * If the current collection policy is COLLECT_WITH_PARENT, this function has no effect. + * + * @see SPObject::collectOrphan + */ + void requestOrphanCollection(); + + /** @brief Unconditionally delete the object if it is not referenced. + * + * Unconditionally delete the object if there are no outstanding hyper-references to it. + * Observers are not notified of the object's deletion (at the SPObject level; XML tree + * notifications still fire). + * + * @see SPObject::deleteObject + */ + void collectOrphan() { + if ( _total_hrefcount == 0 ) { + deleteObject(false); + } + } + + /** @brief Deletes an object. + * + * Detaches the object's repr, and optionally sends notification that the object has been + * deleted. + * + * @param propagate notify observers that the object has been deleted? + * + * @param propagate_descendants notify observers of children that they have been deleted? + */ + void deleteObject(bool propagate, bool propagate_descendants); + + /** @brief Deletes on object. + * + * @param propagate Notify observers of this object and its children that they have been + * deleted? + */ + void deleteObject(bool propagate=true) { + deleteObject(propagate, propagate); + } + + /** @brief Connects a slot to be called when an object is deleted. + * + * This connects a slot to an object's internal delete signal, which is invoked when the object + * is deleted + * + * The signal is mainly useful for e.g. knowing when to break hrefs or dissociate clones. + * + * @param slot the slot to connect + * + * @see SPObject::deleteObject + */ + sigc::connection connectDelete(sigc::slot slot) { + return _delete_signal.connect(slot); + } + + /** @brief Returns the object which supercedes this one (if any). + * + * This is mainly useful for ensuring we can correctly perform a series of moves or deletes, + * even if the objects in question have been replaced in the middle of the sequence. + */ + SPObject *successor() { return _successor; } + + /** @brief Indicates that another object supercedes this one. */ + void setSuccessor(SPObject *successor) { + g_assert(successor != NULL); + g_assert(_successor == NULL); + g_assert(successor->_successor == NULL); + sp_object_ref(successor, NULL); + _successor = successor; + } + + /* modifications; all three sets of methods should probably ultimately be protected, as they + * are not really part of its public interface. However, other parts of the code to + * occasionally use them at present. */ + + /* the no-argument version of updateRepr() is intended to be a bit more public, however -- it + * essentially just flushes any changes back to the backing store (the repr layer); maybe it + * should be called something else and made public at that point. */ + + /** @brief Updates the object's repr based on the object's state. + * + * This method updates the the repr attached to the object to reflect the object's current + * state; see the two-argument version for details. + * + * @param flags object write flags that apply to this update + * + * @return the updated repr + */ + Inkscape::XML::Node *updateRepr(unsigned int flags=SP_OBJECT_WRITE_EXT); + + /** @brief Updates the given repr based on the object's state. + * + * This method updates the given repr to reflect the object's current state. There are + * several flags that affect this: + * + * SP_OBJECT_WRITE_BUILD - create new reprs + * + * SP_OBJECT_WRITE_EXT - write elements and attributes + * which are not part of pure SVG + * (i.e. the Inkscape and Sodipodi + * namespaces) + * + * SP_OBJECT_WRITE_ALL - create all nodes and attributes, + * even those which might be redundant + * + * @param repr the repr to update + * @param flags object write flags that apply to this update + * + * @return the updated repr + */ + Inkscape::XML::Node *updateRepr(Inkscape::XML::Node *repr, unsigned int flags); + + /** @brief Queues an deferred update of this object's display. + * + * This method sets flags to indicate updates to be performed later, during the idle loop. + * + * There are several flags permitted here: + * + * SP_OBJECT_MODIFIED_FLAG - the object has been modified + * + * SP_OBJECT_CHILD_MODIFIED_FLAG - a child of the object has been + * modified + * + * SP_OBJECT_STYLE_MODIFIED_FLAG - the object's style has been + * modified + * + * There are also some subclass-specific modified flags which are hardly ever used. + * + * One of either MODIFIED or CHILD_MODIFIED is required. + * + * @param flags flags indicating what to update + */ + void requestDisplayUpdate(unsigned int flags); + + /** @brief Updates the object's display immediately + * + * This method is called during the idle loop by SPDocument in order to update the object's + * display. + * + * One additional flag is legal here: + * + * SP_OBJECT_PARENT_MODIFIED_FLAG - the parent has been + * modified + * + * @param ctx an SPCtx which accumulates various state + * during the recursive update -- beware! some + * subclasses try to cast this to an SPItemCtx * + * + * @param flags flags indicating what to update (in addition + * to any already set flags) + */ + void updateDisplay(SPCtx *ctx, unsigned int flags); + + /** @brief Requests that a modification notification signal + * be emitted later (e.g. during the idle loop) + * + * @param flags flags indicating what has been modified + */ + void requestModified(unsigned int flags); + + /** @brief Emits a modification notification signal + * + * @param flags indicating what has been modified + */ + void emitModified(unsigned int flags); + + void _sendDeleteSignalRecursive(); + void _updateTotalHRefCount(int increment); + + void _requireSVGVersion(unsigned major, unsigned minor) { + _requireSVGVersion(Inkscape::Version(major, minor)); + } + void _requireSVGVersion(Inkscape::Version version); + + sigc::signal _delete_signal; + SPObject *_successor; + CollectionPolicy _collection_policy; + gchar *_label; + mutable gchar *_default_label; +}; + +/// The SPObject vtable. +struct SPObjectClass { + GObjectClass parent_class; + + void (* build) (SPObject *object, SPDocument *doc, Inkscape::XML::Node *repr); + void (* release) (SPObject *object); + + /* Virtual handlers of repr signals */ + void (* child_added) (SPObject *object, Inkscape::XML::Node *child, Inkscape::XML::Node *ref); + void (* remove_child) (SPObject *object, Inkscape::XML::Node *child); + + void (* order_changed) (SPObject *object, Inkscape::XML::Node *child, Inkscape::XML::Node *old, Inkscape::XML::Node *new_repr); + + void (* set) (SPObject *object, unsigned int key, gchar const *value); + + void (* read_content) (SPObject *object); + + /* Update handler */ + void (* update) (SPObject *object, SPCtx *ctx, unsigned int flags); + /* Modification handler */ + void (* modified) (SPObject *object, unsigned int flags); + + Inkscape::XML::Node * (* write) (SPObject *object, Inkscape::XML::Node *repr, unsigned int flags); +}; + + +/* + * Attaching/detaching + */ + +void sp_object_attach(SPObject *parent, SPObject *object, SPObject *prev); +void sp_object_reorder(SPObject *object, SPObject *prev); +void sp_object_detach(SPObject *parent, SPObject *object); + +inline SPObject *sp_object_first_child(SPObject *parent) { + return parent->firstChild(); +} +SPObject *sp_object_get_child_by_repr(SPObject *object, Inkscape::XML::Node *repr); + +void sp_object_invoke_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr, unsigned int cloned); +void sp_object_invoke_release(SPObject *object); + +void sp_object_set(SPObject *object, unsigned int key, gchar const *value); + +void sp_object_read_attr(SPObject *object, gchar const *key); + +/* + * Get and set descriptive parameters. + * + * These are inefficent, so they are not intended to be used interactively. + */ + +gchar const *sp_object_title_get(SPObject *object); +gchar const *sp_object_description_get(SPObject *object); +unsigned int sp_object_title_set(SPObject *object, gchar const *title); +unsigned int sp_object_description_set(SPObject *object, gchar const *desc); + +/* Public */ + +gchar const *sp_object_tagName_get(SPObject const *object, SPException *ex); +gchar const *sp_object_getAttribute(SPObject const *object, gchar const *key, SPException *ex); +void sp_object_setAttribute(SPObject *object, gchar const *key, gchar const *value, SPException *ex); +void sp_object_removeAttribute(SPObject *object, gchar const *key, SPException *ex); + +/* Style */ + +gchar const *sp_object_get_style_property(SPObject const *object, + gchar const *key, gchar const *def); + +Inkscape::Version sp_object_get_sodipodi_version(SPObject *object); + +int sp_object_compare_position(SPObject const *first, SPObject const *second); + +SPObject *sp_object_prev(SPObject *child); + + +#endif + + +/* + 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:textwidth=99 : diff --git a/src/sp-offset.cpp b/src/sp-offset.cpp new file mode 100644 index 000000000..5c79eb334 --- /dev/null +++ b/src/sp-offset.cpp @@ -0,0 +1,1238 @@ +#define __SP_OFFSET_C__ + +/** \file + * Implementation of . + */ + +/* + * Authors: (of the sp-spiral.c upon which this file was constructed): + * Mitsuru Oka + * Lauris Kaplinski + * + * Copyright (C) 1999-2002 Lauris Kaplinski + * Copyright (C) 2000-2001 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + + +#include "svg/svg.h" +#include "attributes.h" +#include "display/curve.h" +#include + +#include "livarot/Path.h" +#include "livarot/Shape.h" + +#include "enums.h" +#include "prefs-utils.h" +#include "sp-text.h" +#include "sp-offset.h" +#include "sp-use-reference.h" +#include "uri.h" + +#include "libnr/n-art-bpath.h" +#include + +#include "xml/repr.h" + +class SPDocument; + +#define noOFFSET_VERBOSE + +/** \note + * SPOffset is a derivative of SPShape, much like the SPSpiral or SPRect. + * The goal is to have a source shape (= originalPath), an offset (= radius) + * and compute the offset of the source by the radius. To get it to work, + * one needs to know what the source is and what the radius is, and how it's + * stored in the xml representation. The object itself is a "path" element, + * to get lots of shape functionality for free. The source is the easy part: + * it's stored in a "inkscape:original" attribute in the path. In case of + * "linked" offset, as they've been dubbed, there is an additional + * "inkscape:href" that contains the id of an element of the svg. + * When built, the object will attach a listener vector to that object and + * rebuild the "inkscape:original" whenever the href'd object changes. This + * is of course grossly inefficient, and also does not react to changes + * to the href'd during context stuff (like changing the shape of a star by + * dragging control points) unless the path of that object is changed during + * the context (seems to be the case for SPEllipse). The computation of the + * offset is done in sp_offset_set_shape(), a function that is called whenever + * a change occurs to the offset (change of source or change of radius). + * just like the sp-star and other, this path derivative can make control + * points, or more precisely one control point, that's enough to define the + * radius (look in object-edit). + */ + +static void sp_offset_class_init (SPOffsetClass * klass); +static void sp_offset_init (SPOffset * offset); +static void sp_offset_finalize(GObject *obj); + +static void sp_offset_build (SPObject * object, SPDocument * document, + Inkscape::XML::Node * repr); +static Inkscape::XML::Node *sp_offset_write (SPObject * object, Inkscape::XML::Node * repr, + guint flags); +static void sp_offset_set (SPObject * object, unsigned int key, + const gchar * value); +static void sp_offset_update (SPObject * object, SPCtx * ctx, guint flags); +static void sp_offset_release (SPObject * object); + +static gchar *sp_offset_description (SPItem * item); +static void sp_offset_snappoints(SPItem const *item, SnapPointsIter p); +static void sp_offset_set_shape (SPShape * shape); + +Path *bpath_to_liv_path (NArtBpath * bpath); + +static void refresh_offset_source(SPOffset* offset); + +static void sp_offset_start_listening(SPOffset *offset,SPObject* to); +static void sp_offset_quit_listening(SPOffset *offset); +static void sp_offset_href_changed(SPObject *old_ref, SPObject *ref, SPOffset *offset); +static void sp_offset_move_compensate(NR::Matrix const *mp, SPItem *original, SPOffset *self); +static void sp_offset_delete_self(SPObject *deleted, SPOffset *self); +static void sp_offset_source_modified (SPObject *iSource, guint flags, SPItem *item); + + +// slow= source path->polygon->offset of polygon->polygon->path +// fast= source path->offset of source path->polygon->path +// fast is not mathematically correct, because computing the offset of a single +// cubic bezier patch is not trivial; in particular, there are problems with holes +// reappearing in offset when the radius becomes too large +static bool use_slow_but_correct_offset_method=false; + + +// nothing special here, same for every class in sodipodi/inkscape +static SPShapeClass *parent_class; + +/** + * Register SPOffset class and return its type number. + */ +GType +sp_offset_get_type (void) +{ + static GType offset_type = 0; + + if (!offset_type) + { + GTypeInfo offset_info = { + sizeof (SPOffsetClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) sp_offset_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (SPOffset), + 16, /* n_preallocs */ + (GInstanceInitFunc) sp_offset_init, + NULL, /* value_table */ + }; + offset_type = + g_type_register_static (SP_TYPE_SHAPE, "SPOffset", &offset_info, + (GTypeFlags) 0); + } + return offset_type; +} + +/** + * SPOffset vtable initialization. + */ +static void +sp_offset_class_init(SPOffsetClass *klass) +{ + GObjectClass *gobject_class = (GObjectClass *) klass; + SPObjectClass *sp_object_class = (SPObjectClass *) klass; + SPItemClass *item_class = (SPItemClass *) klass; + SPShapeClass *shape_class = (SPShapeClass *) klass; + + parent_class = (SPShapeClass *) g_type_class_ref (SP_TYPE_SHAPE); + + gobject_class->finalize = sp_offset_finalize; + + sp_object_class->build = sp_offset_build; + sp_object_class->write = sp_offset_write; + sp_object_class->set = sp_offset_set; + sp_object_class->update = sp_offset_update; + sp_object_class->release = sp_offset_release; + + item_class->description = sp_offset_description; + item_class->snappoints = sp_offset_snappoints; + + shape_class->set_shape = sp_offset_set_shape; +} + +/** + * Callback for SPOffset object initialization. + */ +static void +sp_offset_init(SPOffset *offset) +{ + offset->rad = 1.0; + offset->original = NULL; + offset->originalPath = NULL; + offset->knotSet = false; + offset->sourceDirty=false; + offset->isUpdating=false; + // init various connections + offset->sourceHref = NULL; + offset->sourceRepr = NULL; + offset->sourceObject = NULL; + new (&offset->_delete_connection) sigc::connection(); + new (&offset->_changed_connection) sigc::connection(); + new (&offset->_transformed_connection) sigc::connection(); + // set up the uri reference + offset->sourceRef = new SPUseReference(SP_OBJECT(offset)); + offset->_changed_connection = offset->sourceRef->changedSignal().connect(sigc::bind(sigc::ptr_fun(sp_offset_href_changed), offset)); +} + +/** + * Callback for SPOffset finalization. + */ +static void +sp_offset_finalize(GObject *obj) +{ + SPOffset *offset = (SPOffset *) obj; + + delete offset->sourceRef; + offset->_delete_connection.~connection(); + offset->_changed_connection.~connection(); + offset->_transformed_connection.~connection(); +} + +/** + * Virtual build: set offset attributes from corresponding repr. + */ +static void +sp_offset_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr) +{ + if (((SPObjectClass *) parent_class)->build) + ((SPObjectClass *) parent_class)->build (object, document, repr); + + if (object->repr->attribute("inkscape:radius")) { + sp_object_read_attr (object, "inkscape:radius"); + } else { + gchar const *oldA = object->repr->attribute("sodipodi:radius"); + object->repr->setAttribute("inkscape:radius",oldA); + object->repr->setAttribute("sodipodi:radius",NULL); + + sp_object_read_attr (object, "inkscape:radius"); + } + if (object->repr->attribute("inkscape:original")) { + sp_object_read_attr (object, "inkscape:original"); + } else { + gchar const *oldA = object->repr->attribute("sodipodi:original"); + object->repr->setAttribute("inkscape:original",oldA); + object->repr->setAttribute("sodipodi:original",NULL); + + sp_object_read_attr (object, "inkscape:original"); + } + if (object->repr->attribute("xlink:href")) { + sp_object_read_attr(object, "xlink:href"); + } else { + gchar const *oldA = object->repr->attribute("inkscape:href"); + if (oldA) { + size_t lA = strlen(oldA); + char *nA=(char*)malloc((lA+1)*sizeof(char)); + memcpy(nA+1,oldA,lA*sizeof(char)); + nA[0]='#'; + nA[lA+1]=0; + object->repr->setAttribute("xlink:href",nA); + free(nA); + object->repr->setAttribute("inkscape:href",NULL); + } + sp_object_read_attr (object, "xlink:href"); + } +} + +/** + * Virtual write: write offset attributes to corresponding repr. + */ +static Inkscape::XML::Node * +sp_offset_write(SPObject *object, Inkscape::XML::Node *repr, guint flags) +{ + SPOffset *offset = SP_OFFSET (object); + + if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { + repr = sp_repr_new ("svg:path"); + } + + if (flags & SP_OBJECT_WRITE_EXT) { + /** \todo + * Fixme: we may replace these attributes by + * inkscape:offset="cx cy exp revo rad arg t0" + */ + repr->setAttribute("sodipodi:type", "inkscape:offset"); + sp_repr_set_svg_double(repr, "inkscape:radius", offset->rad); + repr->setAttribute("inkscape:original", offset->original); + repr->setAttribute("inkscape:href", offset->sourceHref); + } + + + // Make sure the object has curve + SPCurve *curve = sp_shape_get_curve (SP_SHAPE (offset)); + if (curve == NULL) { + sp_offset_set_shape (SP_SHAPE (offset)); + } + + // write that curve to "d" + char *d = sp_svg_write_path (((SPShape *) offset)->curve->bpath); + repr->setAttribute("d", d); + g_free (d); + + if (((SPObjectClass *) (parent_class))->write) + ((SPObjectClass *) (parent_class))->write (object, repr, + flags | SP_SHAPE_WRITE_PATH); + + return repr; +} + +/** + * Virtual release callback. + */ +static void +sp_offset_release(SPObject *object) +{ + SPOffset *offset = (SPOffset *) object; + + if (offset->original) free (offset->original); + if (offset->originalPath) delete ((Path *) offset->originalPath); + offset->original = NULL; + offset->originalPath = NULL; + + sp_offset_quit_listening(offset); + + offset->_changed_connection.disconnect(); + g_free(offset->sourceHref); + offset->sourceHref = NULL; + offset->sourceRef->detach(); + + if (((SPObjectClass *) parent_class)->release) { + ((SPObjectClass *) parent_class)->release (object); + } + +} + +/** + * Set callback: the function that is called whenever a change is made to + * the description of the object. + */ +static void +sp_offset_set(SPObject *object, unsigned key, gchar const *value) +{ + SPOffset *offset = SP_OFFSET (object); + + if ( offset->sourceDirty ) refresh_offset_source(offset); + + /* fixme: we should really collect updates */ + switch (key) + { + case SP_ATTR_INKSCAPE_ORIGINAL: + case SP_ATTR_SODIPODI_ORIGINAL: + if (value == NULL) { + } else { + if (offset->original) { + free (offset->original); + delete ((Path *) offset->originalPath); + offset->original = NULL; + offset->originalPath = NULL; + } + NArtBpath *bpath; + SPCurve *curve; + + offset->original = strdup (value); + + bpath = sp_svg_read_path (offset->original); + curve = sp_curve_new_from_bpath (bpath); // curve se chargera de detruire bpath + g_assert (curve != NULL); + offset->originalPath = bpath_to_liv_path (curve->bpath); + sp_curve_unref (curve); + + offset->knotSet = false; + if ( offset->isUpdating == false ) object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + } + break; + case SP_ATTR_INKSCAPE_RADIUS: + case SP_ATTR_SODIPODI_RADIUS: + if (!sp_svg_length_read_computed_absolute (value, &offset->rad)) { + if (fabs (offset->rad) < 0.01) + offset->rad = (offset->rad < 0) ? -0.01 : 0.01; + offset->knotSet = false; // knotset=false because it's not set from the context + } + if ( offset->isUpdating == false ) object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_INKSCAPE_HREF: + case SP_ATTR_XLINK_HREF: + if ( value == NULL ) { + sp_offset_quit_listening(offset); + if ( offset->sourceHref ) g_free(offset->sourceHref); + offset->sourceHref = NULL; + offset->sourceRef->detach(); + } else { + if ( offset->sourceHref && ( strcmp(value, offset->sourceHref) == 0 ) ) { + } else { + if ( offset->sourceHref ) g_free(offset->sourceHref); + offset->sourceHref = g_strdup(value); + try { + offset->sourceRef->attach(Inkscape::URI(value)); + } catch (Inkscape::BadURIException &e) { + g_warning("%s", e.what()); + offset->sourceRef->detach(); + } + } + } + break; + default: + if (((SPObjectClass *) parent_class)->set) + ((SPObjectClass *) parent_class)->set (object, key, value); + break; + } +} + +/** + * Update callback: the object has changed, recompute its shape. + */ +static void +sp_offset_update(SPObject *object, SPCtx *ctx, guint flags) +{ + SPOffset* offset = SP_OFFSET(object); + offset->isUpdating=true; // prevent sp_offset_set from requesting updates + if ( offset->sourceDirty ) refresh_offset_source(offset); + if (flags & + (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG | + SP_OBJECT_VIEWPORT_MODIFIED_FLAG)) { + sp_shape_set_shape ((SPShape *) object); + } + offset->isUpdating=false; + + if (((SPObjectClass *) parent_class)->update) + ((SPObjectClass *) parent_class)->update (object, ctx, flags); +} + +/** + * Returns a textual description of object. + */ +static gchar * +sp_offset_description(SPItem *item) +{ + SPOffset *offset = SP_OFFSET (item); + + if ( offset->sourceHref ) { + // TRANSLATORS COMMENT: %s is either "outset" or "inset" depending on sign + return g_strdup_printf(_("Linked offset, %s by %f pt"), + (offset->rad >= 0)? _("outset") : _("inset"), fabs (offset->rad)); + } else { + // TRANSLATORS COMMENT: %s is either "outset" or "inset" depending on sign + return g_strdup_printf(_("Dynamic offset, %s by %f pt"), + (offset->rad >= 0)? _("outset") : _("inset"), fabs (offset->rad)); + } +} + +/** + * Converts an NArtBpath (like the one stored in a SPCurve) into a + * livarot Path. Duplicate of splivarot. + */ +Path * +bpath_to_liv_path(NArtBpath *bpath) +{ + if (bpath == NULL) + return NULL; + + Path *dest = new Path; + dest->SetBackData (false); + { + int i; + bool closed = false; + float lastX = 0.0; + float lastY = 0.0; + + for (i = 0; bpath[i].code != NR_END; i++) + { + switch (bpath[i].code) + { + case NR_LINETO: + lastX = bpath[i].x3; + lastY = bpath[i].y3; + { + NR::Point tmp(lastX,lastY); + dest->LineTo (tmp); + } + break; + + case NR_CURVETO: + { + NR::Point tmp(bpath[i].x3, bpath[i].y3); + NR::Point tms; + tms[0]=3 * (bpath[i].x1 - lastX); + tms[1]=3 * (bpath[i].y1 - lastY); + NR::Point tme; + tme[0]=3 * (bpath[i].x3 - bpath[i].x2); + tme[1]= 3 * (bpath[i].y3 - bpath[i].y2); + dest->CubicTo (tmp,tms,tme); + } + lastX = bpath[i].x3; + lastY = bpath[i].y3; + break; + + case NR_MOVETO_OPEN: + case NR_MOVETO: + if (closed) + dest->Close (); + closed = (bpath[i].code == NR_MOVETO); + lastX = bpath[i].x3; + lastY = bpath[i].y3; + { + NR::Point tmp(lastX,lastY); + dest->MoveTo(tmp); + } + break; + default: + break; + } + } + if (closed) + dest->Close (); + } + + return dest; +} + +/** + * Compute and set shape's offset. + */ +static void +sp_offset_set_shape(SPShape *shape) +{ + SPOffset *offset = SP_OFFSET (shape); + + if ( offset->originalPath == NULL ) { + // oops : no path?! (the offset object should do harakiri) + return; + } +#ifdef OFFSET_VERBOSE + g_print ("rad=%g\n", offset->rad); +#endif + // au boulot + + if ( fabs(offset->rad) < 0.01 ) { + // grosso modo: 0 + // just put the source shape as the offseted one, no one will notice + // it's also useless to compute the offset with a 0 radius + + const char *res_d = SP_OBJECT(shape)->repr->attribute("inkscape:original"); + if ( res_d ) { + NArtBpath *bpath = sp_svg_read_path (res_d); + SPCurve *c = sp_curve_new_from_bpath (bpath); + g_assert(c != NULL); + sp_shape_set_curve_insync ((SPShape *) offset, c, TRUE); + sp_curve_unref (c); + } + return; + } + + // extra paraniac careful check. the preceding if () should take care of this case + if (fabs (offset->rad) < 0.01) + offset->rad = (offset->rad < 0) ? -0.01 : 0.01; + + Path *orig = new Path; + orig->Copy ((Path *) offset->originalPath); + + if ( use_slow_but_correct_offset_method == false ) { + // version par outline + Shape *theShape = new Shape; + Shape *theRes = new Shape; + Path *originaux[1]; + Path *res = new Path; + res->SetBackData (false); + + // and now: offset + float o_width; + if (offset->rad >= 0) + { + o_width = offset->rad; + orig->OutsideOutline (res, o_width, join_round, butt_straight, 20.0); + } + else + { + o_width = -offset->rad; + orig->OutsideOutline (res, -o_width, join_round, butt_straight, 20.0); + } + + if (o_width >= 1.0) + { + // res->ConvertForOffset (1.0, orig, offset->rad); + res->ConvertWithBackData (1.0); + } + else + { + // res->ConvertForOffset (o_width, orig, offset->rad); + res->ConvertWithBackData (o_width); + } + res->Fill (theShape, 0); + theRes->ConvertToShape (theShape, fill_positive); + originaux[0] = res; + + theRes->ConvertToForme (orig, 1, originaux); + + SPItem *item = shape; + NR::Rect bbox = sp_item_bbox_desktop (item); + if (!bbox.isEmpty()) { + gdouble size = L2(bbox.dimensions()); + gdouble const exp = NR::expansion(item->transform); + if (exp != 0) + size /= exp; + orig->Coalesce (size * 0.001); + //g_print ("coa %g exp %g item %p\n", size * 0.001, exp, item); + } + + + // if (o_width >= 1.0) + // { + // orig->Coalesce (0.1); // small treshhold, since we only want to get rid of small segments + // the curve should already be computed by the Outline() function + // orig->ConvertEvenLines (1.0); + // orig->Simplify (0.5); + // } + // else + // { + // orig->Coalesce (0.1*o_width); + // orig->ConvertEvenLines (o_width); + // orig->Simplify (0.5 * o_width); + // } + + delete theShape; + delete theRes; + delete res; + } else { + // version par makeoffset + Shape *theShape = new Shape; + Shape *theRes = new Shape; + + + // and now: offset + float o_width; + if (offset->rad >= 0) + { + o_width = offset->rad; + } + else + { + o_width = -offset->rad; + } + + // one has to have a measure of the details + if (o_width >= 1.0) + { + orig->ConvertWithBackData (0.5); + } + else + { + orig->ConvertWithBackData (0.5*o_width); + } + orig->Fill (theShape, 0); + theRes->ConvertToShape (theShape, fill_positive); + Path *originaux[1]; + originaux[0]=orig; + Path *res = new Path; + theRes->ConvertToForme (res, 1, originaux); + int nbPart=0; + Path** parts=res->SubPaths(nbPart,true); + char *holes=(char*)malloc(nbPart*sizeof(char)); + // we offset contours separately, because we can. + // this way, we avoid doing a unique big ConvertToShape when dealing with big shapes with lots of holes + { + Shape* onePart=new Shape; + Shape* oneCleanPart=new Shape; + theShape->Reset(); + for (int i=0;iSurface(); + parts[i]->Convert(1.0); + { + // raffiner si besoin + double bL,bT,bR,bB; + parts[i]->PolylineBoundingBox(bL,bT,bR,bB); + double mesure=((bR-bL)+(bB-bT))*0.5; + if ( mesure < 10.0 ) { + parts[i]->Convert(0.02*mesure); + } + } + if ( partSurf < 0 ) { // inverse par rapport a la realite + // plein + holes[i]=0; + parts[i]->Fill(oneCleanPart,0); + onePart->ConvertToShape(oneCleanPart,fill_positive); // there aren't intersections in that one, but maybe duplicate points and null edges + oneCleanPart->MakeOffset(onePart,offset->rad,join_round,20.0); + onePart->ConvertToShape(oneCleanPart,fill_positive); + + onePart->CalcBBox(); + double typicalSize=0.5*((onePart->rightX-onePart->leftX)+(onePart->bottomY-onePart->topY)); + if ( typicalSize < 0.05 ) typicalSize=0.05; + typicalSize*=0.01; + if ( typicalSize > 1.0 ) typicalSize=1.0; + onePart->ConvertToForme (parts[i]); + parts[i]->ConvertEvenLines (typicalSize); + parts[i]->Simplify (typicalSize); + double nPartSurf=parts[i]->Surface(); + if ( nPartSurf >= 0 ) { + // inversion de la surface -> disparait + delete parts[i]; + parts[i]=NULL; + } else { + } +/* int firstP=theShape->nbPt; + for (int j=0;jnbPt;j++) theShape->AddPoint(onePart->pts[j].x); + for (int j=0;jnbAr;j++) theShape->AddEdge(firstP+onePart->aretes[j].st,firstP+onePart->aretes[j].en);*/ + } else { + // trou + holes[i]=1; + parts[i]->Fill(oneCleanPart,0,false,true,true); + onePart->ConvertToShape(oneCleanPart,fill_positive); + oneCleanPart->MakeOffset(onePart,-offset->rad,join_round,20.0); + onePart->ConvertToShape(oneCleanPart,fill_positive); +// for (int j=0;jnbAr;j++) onePart->Inverse(j); // pas oublier de reinverser + + onePart->CalcBBox(); + double typicalSize=0.5*((onePart->rightX-onePart->leftX)+(onePart->bottomY-onePart->topY)); + if ( typicalSize < 0.05 ) typicalSize=0.05; + typicalSize*=0.01; + if ( typicalSize > 1.0 ) typicalSize=1.0; + onePart->ConvertToForme (parts[i]); + parts[i]->ConvertEvenLines (typicalSize); + parts[i]->Simplify (typicalSize); + double nPartSurf=parts[i]->Surface(); + if ( nPartSurf >= 0 ) { + // inversion de la surface -> disparait + delete parts[i]; + parts[i]=NULL; + } else { + } + + /* int firstP=theShape->nbPt; + for (int j=0;jnbPt;j++) theShape->AddPoint(onePart->pts[j].x); + for (int j=0;jnbAr;j++) theShape->AddEdge(firstP+onePart->aretes[j].en,firstP+onePart->aretes[j].st);*/ + } +// delete parts[i]; + } +// theShape->MakeOffset(theRes,offset->rad,join_round,20.0); + delete onePart; + delete oneCleanPart; + } + if ( nbPart > 1 ) { + theShape->Reset(); + for (int i=0;iConvertWithBackData(1.0); + if ( holes[i] ) { + parts[i]->Fill(theShape,i,true,true,true); + } else { + parts[i]->Fill(theShape,i,true,true,false); + } + } + } + theRes->ConvertToShape (theShape, fill_positive); + theRes->ConvertToForme (orig,nbPart,parts); + for (int i=0;iCopy(parts[0]); + for (int i=0;iReset(); + } +// theRes->ConvertToShape (theShape, fill_positive); +// theRes->ConvertToForme (orig); + +/* if (o_width >= 1.0) { + orig->ConvertEvenLines (1.0); + orig->Simplify (1.0); + } else { + orig->ConvertEvenLines (1.0*o_width); + orig->Simplify (1.0 * o_width); + }*/ + + if ( parts ) free(parts); + if ( holes ) free(holes); + delete res; + delete theShape; + delete theRes; + } + { + char *res_d = NULL; + if (orig->descr_cmd.size() <= 1) + { + // Aie.... nothing left. + res_d = strdup ("M 0 0 L 0 0 z"); + //printf("%s\n",res_d); + } + else + { + + res_d = orig->svg_dump_path (); + } + delete orig; + + NArtBpath *bpath = sp_svg_read_path (res_d); + SPCurve *c = sp_curve_new_from_bpath (bpath); + g_assert(c != NULL); + sp_shape_set_curve_insync ((SPShape *) offset, c, TRUE); + sp_curve_unref (c); + + free (res_d); + } +} + +/** + * Virtual snappoints function. + */ +static void sp_offset_snappoints(SPItem const *item, SnapPointsIter p) +{ + if (((SPItemClass *) parent_class)->snappoints) { + ((SPItemClass *) parent_class)->snappoints (item, p); + } +} + + +// utilitaires pour les poignees +// used to get the distance to the shape: distance to polygon give the fabs(radius), we still need +// the sign. for edges, it's easy to determine which side the point is on, for points of the polygon +// it's trickier: we need to identify which angle the point is in; to that effect, we take each +// successive clockwise angle (A,C) and check if the vector B given by the point is in the angle or +// outside. +// another method would be to use the Winding() function to test whether the point is inside or outside +// the polygon (it would be wiser to do so, in fact, but i like being stupid) + +/** + * + * \todo + * FIXME: This can be done using linear operations, more stably and + * faster. method: transform A and C into B's space, A should be + * negative and B should be positive in the orthogonal component. I + * think this is equivalent to + * dot(A, rot90(B))*dot(C, rot90(B)) == -1. + * -- njh + */ +bool +vectors_are_clockwise (NR::Point A, NR::Point B, NR::Point C) +{ + using NR::rot90; + double ab_s = dot(A, rot90(B)); + double ab_c = dot(A, B); + double bc_s = dot(B, rot90(C)); + double bc_c = dot(B, C); + double ca_s = dot(C, rot90(A)); + double ca_c = dot(C, A); + + double ab_a = acos (ab_c); + if (ab_c <= -1.0) + ab_a = M_PI; + if (ab_c >= 1.0) + ab_a = 0; + if (ab_s < 0) + ab_a = 2 * M_PI - ab_a; + double bc_a = acos (bc_c); + if (bc_c <= -1.0) + bc_a = M_PI; + if (bc_c >= 1.0) + bc_a = 0; + if (bc_s < 0) + bc_a = 2 * M_PI - bc_a; + double ca_a = acos (ca_c); + if (ca_c <= -1.0) + ca_a = M_PI; + if (ca_c >= 1.0) + ca_a = 0; + if (ca_s < 0) + ca_a = 2 * M_PI - ca_a; + + double lim = 2 * M_PI - ca_a; + + if (ab_a < lim) + return true; + return false; +} + +/** + * Distance to the original path; that function is called from object-edit + * to set the radius when the control knot moves. + * + * The sign of the result is the radius we're going to offset the shape with, + * so result > 0 ==outset and result < 0 ==inset. thus result<0 means + * 'px inside source'. + */ +double +sp_offset_distance_to_original (SPOffset * offset, NR::Point px) +{ + if (offset == NULL || offset->originalPath == NULL + || ((Path *) offset->originalPath)->descr_cmd.size() <= 1) + return 1.0; + double dist = 1.0; + Shape *theShape = new Shape; + Shape *theRes = new Shape; + + /** \todo + * Awfully damn stupid method: uncross the source path EACH TIME you + * need to compute the distance. The good way to do this would be to + * store the uncrossed source path somewhere, and delete it when the + * context is finished. Hopefully this part is much faster than actually + * computing the offset (which happen just after), so the time spent in + * this function should end up being negligible with respect to the + * delay of one context. + */ + // move + ((Path *) offset->originalPath)->Convert (1.0); + ((Path *) offset->originalPath)->Fill (theShape, 0); + theRes->ConvertToShape (theShape, fill_oddEven); + + if (theRes->numberOfEdges() <= 1) + { + + } + else + { + double ptDist = -1.0; + bool ptSet = false; + double arDist = -1.0; + bool arSet = false; + // first get the minimum distance to the points + for (int i = 0; i < theRes->numberOfPoints(); i++) + { + if (theRes->getPoint(i).totalDegree() > 0) + { + NR::Point nx = theRes->getPoint(i).x; + NR::Point nxpx = px-nx; + double ndist = sqrt (dot(nxpx,nxpx)); + if (ptSet == false || fabs (ndist) < fabs (ptDist)) + { + // we have a new minimum distance + // now we need to wheck if px is inside or outside (for the sign) + nx = px - theRes->getPoint(i).x; + double nlen = sqrt (dot(nx , nx)); + nx /= nlen; + int pb, cb, fb; + fb = theRes->getPoint(i).incidentEdge[LAST]; + pb = theRes->getPoint(i).incidentEdge[LAST]; + cb = theRes->getPoint(i).incidentEdge[FIRST]; + do + { + // one angle + NR::Point prx, nex; + prx = theRes->getEdge(pb).dx; + nlen = sqrt (dot(prx, prx)); + prx /= nlen; + nex = theRes->getEdge(cb).dx; + nlen = sqrt (dot(nex , nex)); + nex /= nlen; + if (theRes->getEdge(pb).en == i) + { + prx = -prx; + } + if (theRes->getEdge(cb).en == i) + { + nex = -nex; + } + + if (vectors_are_clockwise (nex, nx, prx)) + { + // we're in that angle. set the sign, and exit that loop + if (theRes->getEdge(cb).st == i) + { + ptDist = -ndist; + ptSet = true; + } + else + { + ptDist = ndist; + ptSet = true; + } + break; + } + pb = cb; + cb = theRes->NextAt (i, cb); + } + while (cb >= 0 && pb >= 0 && pb != fb); + } + } + } + // loop over the edges to try to improve the distance + for (int i = 0; i < theRes->numberOfEdges(); i++) + { + NR::Point sx = theRes->getPoint(theRes->getEdge(i).st).x; + NR::Point ex = theRes->getPoint(theRes->getEdge(i).en).x; + NR::Point nx = ex - sx; + double len = sqrt (dot(nx,nx)); + if (len > 0.0001) + { + NR::Point pxsx=px-sx; + double ab = dot(nx,pxsx); + if (ab > 0 && ab < len * len) + { + // we're in the zone of influence of the segment + double ndist = (cross(pxsx,nx)) / len; + if (arSet == false || fabs (ndist) < fabs (arDist)) + { + arDist = ndist; + arSet = true; + } + } + } + } + if (arSet || ptSet) + { + if (arSet == false) + arDist = ptDist; + if (ptSet == false) + ptDist = arDist; + if (fabs (ptDist) < fabs (arDist)) + dist = ptDist; + else + dist = arDist; + } + } + + delete theShape; + delete theRes; + + return dist; +} + +/** + * Computes a point on the offset; used to set a "seed" position for + * the control knot. + * + * \return the topmost point on the offset. + */ +void +sp_offset_top_point (SPOffset * offset, NR::Point *px) +{ + (*px) = NR::Point(0, 0); + if (offset == NULL) + return; + + if (offset->knotSet) + { + (*px) = offset->knot; + return; + } + + SPCurve *curve = sp_shape_get_curve (SP_SHAPE (offset)); + if (curve == NULL) + { + sp_offset_set_shape (SP_SHAPE (offset)); + curve = sp_shape_get_curve (SP_SHAPE (offset)); + if (curve == NULL) + return; + } + + Path *finalPath = bpath_to_liv_path (curve->bpath); + if (finalPath == NULL) + { + sp_curve_unref (curve); + return; + } + + Shape *theShape = new Shape; + + finalPath->Convert (1.0); + finalPath->Fill (theShape, 0); + + if (theShape->hasPoints()) + { + theShape->SortPoints (); + *px = theShape->getPoint(0).x; + } + + delete theShape; + delete finalPath; + sp_curve_unref (curve); +} + +// the listening functions +static void sp_offset_start_listening(SPOffset *offset,SPObject* to) +{ + if ( to == NULL ) + return; + + offset->sourceObject = to; + offset->sourceRepr = SP_OBJECT_REPR(to); + + offset->_delete_connection = SP_OBJECT(to)->connectDelete(sigc::bind(sigc::ptr_fun(&sp_offset_delete_self), offset)); + offset->_transformed_connection = SP_ITEM(to)->connectTransformed(sigc::bind(sigc::ptr_fun(&sp_offset_move_compensate), offset)); + offset->_modified_connection = g_signal_connect (G_OBJECT (to), "modified", G_CALLBACK (sp_offset_source_modified), offset); +} + +static void sp_offset_quit_listening(SPOffset *offset) +{ + if ( offset->sourceObject == NULL ) + return; + + g_signal_handler_disconnect (offset->sourceObject, offset->_modified_connection); + offset->_delete_connection.disconnect(); + offset->_transformed_connection.disconnect(); + + offset->sourceRepr = NULL; + offset->sourceObject = NULL; +} + +static void +sp_offset_href_changed(SPObject */*old_ref*/, SPObject */*ref*/, SPOffset *offset) +{ + sp_offset_quit_listening(offset); + if (offset->sourceRef) { + SPItem *refobj = offset->sourceRef->getObject(); + if (refobj) sp_offset_start_listening(offset,refobj); + offset->sourceDirty=true; + SP_OBJECT(offset)->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + } +} + +static void +sp_offset_move_compensate(NR::Matrix const *mp, SPItem *original, SPOffset *self) +{ + guint mode = prefs_get_int_attribute("options.clonecompensation", "value", SP_CLONE_COMPENSATION_PARALLEL); + if (mode == SP_CLONE_COMPENSATION_NONE) return; + + NR::Matrix m(*mp); + if (!(m.is_translation())) return; + + // calculate the compensation matrix and the advertized movement matrix + SPItem *item = SP_ITEM(self); + + NR::Matrix compensate; + NR::Matrix advertized_move; + + if (mode == SP_CLONE_COMPENSATION_UNMOVED) { + compensate = NR::identity(); + advertized_move.set_identity(); + } else if (mode == SP_CLONE_COMPENSATION_PARALLEL) { + compensate = m; + advertized_move = m; + } else { + g_assert_not_reached(); + } + + item->transform *= compensate; + + // commit the compensation + sp_item_write_transform(item, SP_OBJECT_REPR(item), item->transform, &advertized_move); + SP_OBJECT(item)->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); +} + +static void +sp_offset_delete_self(SPObject */*deleted*/, SPOffset *offset) +{ + guint const mode = prefs_get_int_attribute("options.cloneorphans", "value", SP_CLONE_ORPHANS_UNLINK); + + if (mode == SP_CLONE_ORPHANS_UNLINK) { + // leave it be. just forget about the source + sp_offset_quit_listening(offset); + if ( offset->sourceHref ) g_free(offset->sourceHref); + offset->sourceHref = NULL; + offset->sourceRef->detach(); + } else if (mode == SP_CLONE_ORPHANS_DELETE) { + SP_OBJECT(offset)->deleteObject(); + } +} + +static void +sp_offset_source_modified (SPObject *iSource, guint flags, SPItem *item) +{ + SPOffset *offset = SP_OFFSET(item); + offset->sourceDirty=true; + refresh_offset_source(offset); + sp_shape_set_shape ((SPShape *) offset); +} + +static void +refresh_offset_source(SPOffset* offset) +{ + if ( offset == NULL ) return; + offset->sourceDirty=false; + Path *orig = NULL; + + // le mauvais cas: pas d'attribut d => il faut verifier que c'est une SPShape puis prendre le contour + // The bad case: no d attribute. Must check that it's an SPShape and then take the outline. + SPObject *refobj=offset->sourceObject; + if ( refobj == NULL ) return; + SPItem *item = SP_ITEM (refobj); + + SPCurve *curve=NULL; + if (!SP_IS_SHAPE (item) && !SP_IS_TEXT (item)) return; + if (SP_IS_SHAPE (item)) { + curve = sp_shape_get_curve (SP_SHAPE (item)); + if (curve == NULL) + return; + } + if (SP_IS_TEXT (item)) { + curve = SP_TEXT (item)->getNormalizedBpath (); + if (curve == NULL) + return; + } + orig = bpath_to_liv_path (curve->bpath); + sp_curve_unref (curve); + + + // Finish up. + { + SPCSSAttr *css; + const gchar *val; + Shape *theShape = new Shape; + Shape *theRes = new Shape; + + orig->ConvertWithBackData (1.0); + orig->Fill (theShape, 0); + + css = sp_repr_css_attr (offset->sourceRepr , "style"); + val = sp_repr_css_property (css, "fill-rule", NULL); + if (val && strcmp (val, "nonzero") == 0) + { + theRes->ConvertToShape (theShape, fill_nonZero); + } + else if (val && strcmp (val, "evenodd") == 0) + { + theRes->ConvertToShape (theShape, fill_oddEven); + } + else + { + theRes->ConvertToShape (theShape, fill_nonZero); + } + + Path *originaux[1]; + originaux[0] = orig; + Path *res = new Path; + theRes->ConvertToForme (res, 1, originaux); + + delete theShape; + delete theRes; + + char *res_d = res->svg_dump_path (); + delete res; + delete orig; + + SP_OBJECT (offset)->repr->setAttribute("inkscape:original", res_d); + + free (res_d); + } +} + +SPItem * +sp_offset_get_source (SPOffset *offset) +{ + if (offset && offset->sourceRef) { + SPItem *refobj = offset->sourceRef->getObject(); + if (SP_IS_ITEM (refobj)) + return (SPItem *) refobj; + } + return NULL; +} + + +/* + 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:textwidth=99 : diff --git a/src/sp-offset.h b/src/sp-offset.h new file mode 100644 index 000000000..52c793d0e --- /dev/null +++ b/src/sp-offset.h @@ -0,0 +1,108 @@ +#ifndef __SP_OFFSET_H__ +#define __SP_OFFSET_H__ + +/** \file + * SPOffset class. + * + * Authors: + * Mitsuru Oka + * Lauris Kaplinski + * (of the sp-spiral.h upon which this file was created) + * Copyright (C) 1999-2002 Lauris Kaplinski + * Copyright (C) 2000-2001 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "sp-shape.h" + +#include + +#define SP_TYPE_OFFSET (sp_offset_get_type ()) +#define SP_OFFSET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SP_TYPE_OFFSET, SPOffset)) +#define SP_OFFSET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SP_TYPE_OFFSET, SPOffsetClass)) +#define SP_IS_OFFSET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_OFFSET)) +#define SP_IS_OFFSET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SP_TYPE_OFFSET)) + +class SPOffset; +class SPOffsetClass; +class SPUseReference; + +/** + * SPOffset class. + * + * An offset is defined by curve and radius. The original curve is kept as + * a path in a sodipodi:original attribute. It's not possible to change + * the original curve. + * + * SPOffset is a derivative of SPShape, much like the SPSpiral or SPRect. + * The goal is to have a source shape (= originalPath), an offset (= radius) + * and compute the offset of the source by the radius. To get it to work, + * one needs to know what the source is and what the radius is, and how it's + * stored in the xml representation. The object itself is a "path" element, + * to get lots of shape functionality for free. The source is the easy part: + * it's stored in a "inkscape:original" attribute in the path. In case of + * "linked" offset, as they've been dubbed, there is an additional + * "inkscape:href" that contains the id of an element of the svg. + * When built, the object will attach a listener vector to that object and + * rebuild the "inkscape:original" whenever the href'd object changes. This + * is of course grossly inefficient, and also does not react to changes + * to the href'd during context stuff (like changing the shape of a star by + * dragging control points) unless the path of that object is changed during + * the context (seems to be the case for SPEllipse). The computation of the + * offset is done in sp_offset_set_shape(), a function that is called whenever + * a change occurs to the offset (change of source or change of radius). + * just like the sp-star and other, this path derivative can make control + * points, or more precisely one control point, that's enough to define the + * radius (look in object-edit). + */ +struct SPOffset : public SPShape { + void *originalPath; ///< will be a livarot Path, just don't declare it here to please the gcc linker + char *original; ///< SVG description of the source path + float rad; ///< offset radius + + /// for interactive setting of the radius + bool knotSet; + NR::Point knot; + + bool sourceDirty; + bool isUpdating; + + gchar *sourceHref; + SPUseReference *sourceRef; + Inkscape::XML::Node *sourceRepr; ///< the repr associated with that id + SPObject *sourceObject; + + gulong _modified_connection; + sigc::connection _delete_connection; + sigc::connection _changed_connection; + sigc::connection _transformed_connection; +}; + +/// The SPOffset vtable. +struct SPOffsetClass +{ + SPShapeClass parent_class; +}; + + +/* Standard Gtk function */ +GType sp_offset_get_type (void); + +double sp_offset_distance_to_original (SPOffset * offset, NR::Point px); +void sp_offset_top_point (SPOffset * offset, NR::Point *px); + +SPItem *sp_offset_get_source (SPOffset *offset); + +#endif + +/* + 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:textwidth=99 : diff --git a/src/sp-paint-server.cpp b/src/sp-paint-server.cpp new file mode 100644 index 000000000..24727628c --- /dev/null +++ b/src/sp-paint-server.cpp @@ -0,0 +1,163 @@ +#define __SP_PAINT_SERVER_C__ + +/* + * Base class for gradients and patterns + * + * Author: + * Lauris Kaplinski + * + * Copyright (C) 1999-2002 Lauris Kaplinski + * Copyright (C) 2000-2001 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include +#include "sp-paint-server.h" + +static void sp_paint_server_class_init(SPPaintServerClass *psc); +static void sp_paint_server_init(SPPaintServer *ps); + +static void sp_paint_server_release(SPObject *object); + +static void sp_painter_stale_fill(SPPainter *painter, NRPixBlock *pb); + +static SPObjectClass *parent_class; +static GSList *stale_painters = NULL; + +GType sp_paint_server_get_type (void) +{ + static GType type = 0; + if (!type) { + GTypeInfo info = { + sizeof(SPPaintServerClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) sp_paint_server_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof(SPPaintServer), + 16, /* n_preallocs */ + (GInstanceInitFunc) sp_paint_server_init, + NULL, /* value_table */ + }; + type = g_type_register_static(SP_TYPE_OBJECT, "SPPaintServer", &info, (GTypeFlags) 0); + } + return type; +} + +static void sp_paint_server_class_init(SPPaintServerClass *psc) +{ + SPObjectClass *sp_object_class = (SPObjectClass *) psc; + sp_object_class->release = sp_paint_server_release; + parent_class = (SPObjectClass *) g_type_class_ref(SP_TYPE_OBJECT); +} + +static void sp_paint_server_init(SPPaintServer *ps) +{ + ps->painters = NULL; +} + +static void sp_paint_server_release(SPObject *object) +{ + SPPaintServer *ps = SP_PAINT_SERVER(object); + + while (ps->painters) { + SPPainter *painter = ps->painters; + ps->painters = painter->next; + stale_painters = g_slist_prepend(stale_painters, painter); + painter->next = NULL; + painter->server = NULL; + painter->fill = sp_painter_stale_fill; + } + + if (((SPObjectClass *) parent_class)->release) { + ((SPObjectClass *) parent_class)->release(object); + } +} + +SPPainter *sp_paint_server_painter_new(SPPaintServer *ps, + NR::Matrix const &full_transform, + NR::Matrix const &parent_transform, + const NRRect *bbox) +{ + g_return_val_if_fail(ps != NULL, NULL); + g_return_val_if_fail(SP_IS_PAINT_SERVER(ps), NULL); + g_return_val_if_fail(bbox != NULL, NULL); + + SPPainter *painter = NULL; + SPPaintServerClass *psc = (SPPaintServerClass *) G_OBJECT_GET_CLASS(ps); + if ( psc->painter_new ) { + painter = (*psc->painter_new)(ps, full_transform, parent_transform, bbox); + } + + if (painter) { + painter->next = ps->painters; + painter->server = ps; + painter->type = (SPPainterType) G_OBJECT_TYPE(ps); + ps->painters = painter; + } + + return painter; +} + +static void sp_paint_server_painter_free(SPPaintServer *ps, SPPainter *painter) +{ + g_return_if_fail(ps != NULL); + g_return_if_fail(SP_IS_PAINT_SERVER(ps)); + g_return_if_fail(painter != NULL); + + SPPaintServerClass *psc = (SPPaintServerClass *) G_OBJECT_GET_CLASS(ps); + + SPPainter *r = NULL; + for (SPPainter *p = ps->painters; p != NULL; p = p->next) { + if (p == painter) { + if (r) { + r->next = p->next; + } else { + ps->painters = p->next; + } + p->next = NULL; + if (psc->painter_free) { + (*psc->painter_free) (ps, painter); + } + return; + } + r = p; + } + + g_assert_not_reached(); +} + +SPPainter *sp_painter_free(SPPainter *painter) +{ + g_return_val_if_fail(painter != NULL, NULL); + + if (painter->server) { + sp_paint_server_painter_free(painter->server, painter); + } else { + SPPaintServerClass *psc = (SPPaintServerClass *) g_type_class_ref(painter->type); + if (psc->painter_free) + (*psc->painter_free)(NULL, painter); + stale_painters = g_slist_remove(stale_painters, painter); + } + + return NULL; +} + +static void sp_painter_stale_fill(SPPainter *painter, NRPixBlock *pb) +{ + nr_pixblock_render_gray_noise(pb, NULL); +} + + +/* + 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 : diff --git a/src/sp-paint-server.h b/src/sp-paint-server.h new file mode 100644 index 000000000..9589b04d3 --- /dev/null +++ b/src/sp-paint-server.h @@ -0,0 +1,66 @@ +#ifndef __SP_PAINT_SERVER_H__ +#define __SP_PAINT_SERVER_H__ + +/* + * Base class for gradients and patterns + * + * Author: + * Lauris Kaplinski + * + * Copyright (C) 1999-2002 Lauris Kaplinski + * Copyright (C) 2000-2001 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include +#include "sp-object.h" + + + +class SPPainter; + +#define SP_TYPE_PAINT_SERVER (sp_paint_server_get_type ()) +#define SP_PAINT_SERVER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SP_TYPE_PAINT_SERVER, SPPaintServer)) +#define SP_PAINT_SERVER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SP_TYPE_PAINT_SERVER, SPPaintServerClass)) +#define SP_IS_PAINT_SERVER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_PAINT_SERVER)) +#define SP_IS_PAINT_SERVER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SP_TYPE_PAINT_SERVER)) + +typedef enum { + SP_PAINTER_IND, + SP_PAINTER_DEP +} SPPainterType; + +typedef void (* SPPainterFillFunc) (SPPainter *painter, NRPixBlock *pb); + +/* fixme: I do not like that class thingie (Lauris) */ +struct SPPainter { + SPPainter *next; + SPPaintServer *server; + GType server_type; + SPPainterType type; + SPPainterFillFunc fill; +}; + +struct SPPaintServer : public SPObject { + /* List of paints */ + SPPainter *painters; +}; + +struct SPPaintServerClass { + SPObjectClass sp_object_class; + /* Get SPPaint instance */ + SPPainter * (* painter_new) (SPPaintServer *ps, NR::Matrix const &full_transform, NR::Matrix const &parent_transform, const NRRect *bbox); + /* Free SPPaint instance */ + void (* painter_free) (SPPaintServer *ps, SPPainter *painter); +}; + +GType sp_paint_server_get_type (void); + +SPPainter *sp_paint_server_painter_new (SPPaintServer *ps, NR::Matrix const &full_transform, NR::Matrix const &parent_transform, const NRRect *bbox); + +SPPainter *sp_painter_free (SPPainter *painter); + + + +#endif diff --git a/src/sp-path.cpp b/src/sp-path.cpp new file mode 100644 index 000000000..9fe2f54c5 --- /dev/null +++ b/src/sp-path.cpp @@ -0,0 +1,325 @@ +#define __SP_PATH_C__ + +/* + * SVG implementation + * + * Authors: + * Lauris Kaplinski + * David Turner + * + * Copyright (C) 2004 David Turner + * Copyright (C) 1999-2002 Lauris Kaplinski + * Copyright (C) 2000-2001 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#if defined(WIN32) || defined(__APPLE__) +# include +#endif + +#include +#include +#include +#include + +#include "svg/svg.h" +#include "xml/repr.h" +#include "attributes.h" + +#include "sp-path.h" + +#define noPATH_VERBOSE + +static void sp_path_class_init(SPPathClass *klass); +static void sp_path_init(SPPath *path); +static void sp_path_finalize(GObject *obj); +static void sp_path_release(SPObject *object); + +static void sp_path_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr); +static void sp_path_set(SPObject *object, unsigned key, gchar const *value); + +static Inkscape::XML::Node *sp_path_write(SPObject *object, Inkscape::XML::Node *repr, guint flags); +static NR::Matrix sp_path_set_transform(SPItem *item, NR::Matrix const &xform); +static gchar * sp_path_description(SPItem *item); + +static void sp_path_update(SPObject *object, SPCtx *ctx, guint flags); + +static SPShapeClass *parent_class; + +/** + * Gets the GType object for SPPathClass + */ +GType +sp_path_get_type(void) +{ + static GType type = 0; + + if (!type) { + GTypeInfo info = { + sizeof(SPPathClass), + NULL, NULL, + (GClassInitFunc) sp_path_class_init, + NULL, NULL, + sizeof(SPPath), + 16, + (GInstanceInitFunc) sp_path_init, + NULL, /* value_table */ + }; + type = g_type_register_static(SP_TYPE_SHAPE, "SPPath", &info, (GTypeFlags)0); + } + return type; +} + +/** + * Does the object-oriented work of initializing the class structure + * including parent class, and registers function pointers for + * the functions build, set, write, and set_transform. + */ +static void +sp_path_class_init(SPPathClass * klass) +{ + GObjectClass *gobject_class = (GObjectClass *) klass; + SPObjectClass *sp_object_class = (SPObjectClass *) klass; + SPItemClass *item_class = (SPItemClass *) klass; + + parent_class = (SPShapeClass *)g_type_class_peek_parent(klass); + + gobject_class->finalize = sp_path_finalize; + + sp_object_class->build = sp_path_build; + sp_object_class->release = sp_path_release; + sp_object_class->set = sp_path_set; + sp_object_class->write = sp_path_write; + sp_object_class->update = sp_path_update; + + item_class->description = sp_path_description; + item_class->set_transform = sp_path_set_transform; +} + + +gint +sp_nodes_in_path(SPPath *path) +{ + SPCurve *curve = SP_SHAPE(path)->curve; + if (!curve) return 0; + gint r = curve->end; + gint i = curve->length - 1; + if (i > r) i = r; // sometimes after switching from node editor length is wrong, e.g. f6 - draw - f2 - tab - f1, this fixes it + for (; i >= 0; i --) + if ((curve->bpath + i) -> code == NR_MOVETO) + r --; + return r; +} + +static gchar * +sp_path_description(SPItem * item) +{ + int count = sp_nodes_in_path(SP_PATH(item)); + return g_strdup_printf(ngettext("Path (%i node)", + "Path (%i nodes)",count), count); +} + +/** + * Initializes an SPPath. Currently does nothing. + */ +static void +sp_path_init(SPPath *path) +{ + new (&path->connEndPair) SPConnEndPair(path); +} + +static void +sp_path_finalize(GObject *obj) +{ + SPPath *path = (SPPath *) obj; + + path->connEndPair.~SPConnEndPair(); +} + +/** + * Given a repr, this sets the data items in the path object such as + * fill & style attributes, markers, and CSS properties. + */ +static void +sp_path_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr) +{ + sp_object_read_attr(object, "d"); + + /* d is a required attribute */ + gchar const *d = sp_object_getAttribute(object, "d", NULL); + if (d == NULL) { + sp_object_set(object, sp_attribute_lookup("d"), ""); + } + + /* Are these calls actually necessary? */ + sp_object_read_attr(object, "marker"); + sp_object_read_attr(object, "marker-start"); + sp_object_read_attr(object, "marker-mid"); + sp_object_read_attr(object, "marker-end"); + + sp_conn_end_pair_build(object); + + if (((SPObjectClass *) parent_class)->build) { + ((SPObjectClass *) parent_class)->build(object, document, repr); + } +} + +static void +sp_path_release(SPObject *object) +{ + SPPath *path = SP_PATH(object); + + path->connEndPair.release(); + + if (((SPObjectClass *) parent_class)->release) { + ((SPObjectClass *) parent_class)->release(object); + } +} + +/** + * Sets a value in the path object given by 'key', to 'value'. This is used + * for setting attributes and markers on a path object. + */ +static void +sp_path_set(SPObject *object, unsigned int key, gchar const *value) +{ + SPPath *path = (SPPath *) object; + + switch (key) { + case SP_ATTR_D: + if (value) { + NArtBpath *bpath = sp_svg_read_path(value); + SPCurve *curve = sp_curve_new_from_bpath(bpath); + if (curve) { + sp_shape_set_curve((SPShape *) path, curve, TRUE); + sp_curve_unref(curve); + } + } else { + sp_shape_set_curve((SPShape *) path, NULL, TRUE); + } + object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_PROP_MARKER: + case SP_PROP_MARKER_START: + case SP_PROP_MARKER_MID: + case SP_PROP_MARKER_END: + sp_shape_set_marker(object, key, value); + object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_CONNECTOR_TYPE: + case SP_ATTR_CONNECTION_START: + case SP_ATTR_CONNECTION_END: + path->connEndPair.setAttr(key, value); + break; + default: + if (((SPObjectClass *) parent_class)->set) { + ((SPObjectClass *) parent_class)->set(object, key, value); + } + break; + } +} + +/** + * + * Writes the path object into a Inkscape::XML::Node + */ +static Inkscape::XML::Node * +sp_path_write(SPObject *object, Inkscape::XML::Node *repr, guint flags) +{ + SPShape *shape = (SPShape *) object; + + if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { + repr = sp_repr_new("svg:path"); + } + + if ( shape->curve != NULL ) { + NArtBpath *abp = sp_curve_first_bpath(shape->curve); + if (abp) { + gchar *str = sp_svg_write_path(abp); + repr->setAttribute("d", str); + g_free(str); + } else { + repr->setAttribute("d", ""); + } + } else { + repr->setAttribute("d", NULL); + } + + SP_PATH(shape)->connEndPair.writeRepr(repr); + + if (((SPObjectClass *)(parent_class))->write) { + ((SPObjectClass *)(parent_class))->write(object, repr, flags); + } + + return repr; +} + +static void +sp_path_update(SPObject *object, SPCtx *ctx, guint flags) +{ + if (flags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG)) { + flags &= ~SP_OBJECT_USER_MODIFIED_FLAG_B; // since we change the description, it's not a "just translation" anymore + } + + if (((SPObjectClass *) parent_class)->update) { + ((SPObjectClass *) parent_class)->update(object, ctx, flags); + } + + SPPath *path = SP_PATH(object); + path->connEndPair.update(); +} + + +/** + * Writes the given transform into the repr for the given item. + */ +static NR::Matrix +sp_path_set_transform(SPItem *item, NR::Matrix const &xform) +{ + SPShape *shape = (SPShape *) item; + + if (!shape->curve) { // 0 nodes, nothing to transform + return NR::identity(); + } + + /* Transform the path */ + NRBPath dpath, spath; + spath.path = shape->curve->bpath; + nr_path_duplicate_transform(&dpath, &spath, xform); + SPCurve *curve = sp_curve_new_from_bpath(dpath.path); + if (curve) { + sp_shape_set_curve(shape, curve, TRUE); + sp_curve_unref(curve); + } + + // Adjust stroke + sp_item_adjust_stroke(item, NR::expansion(xform)); + + // Adjust pattern fill + sp_item_adjust_pattern(item, xform); + + // Adjust gradient fill + sp_item_adjust_gradient(item, xform); + + item->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG); + + // nothing remains - we've written all of the transform, so return identity + return NR::identity(); +} + + +/* + 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 : diff --git a/src/sp-path.h b/src/sp-path.h new file mode 100644 index 000000000..7c2af5eec --- /dev/null +++ b/src/sp-path.h @@ -0,0 +1,46 @@ +#ifndef __SP_PATH_H__ +#define __SP_PATH_H__ + +/* + * SVG implementation + * + * Authors: + * Lauris Kaplinski + * + * Copyright (C) 1999-2002 Lauris Kaplinski + * Copyright (C) 2000-2001 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "sp-shape.h" +#include "sp-conn-end-pair.h" + + +#define SP_TYPE_PATH (sp_path_get_type ()) +#define SP_PATH(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SP_TYPE_PATH, SPPath)) +#define SP_IS_PATH(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_PATH)) + +struct SPPath : public SPShape { + SPConnEndPair connEndPair; +}; + +struct SPPathClass { + SPShapeClass shape_class; +}; + +GType sp_path_get_type (void); + + +#endif + +/* + 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 : diff --git a/src/sp-pattern.cpp b/src/sp-pattern.cpp new file mode 100644 index 000000000..beea89b02 --- /dev/null +++ b/src/sp-pattern.cpp @@ -0,0 +1,979 @@ +#define __SP_PATTERN_C__ + +/* + * SVG implementation + * + * Author: + * Lauris Kaplinski + * bulia byak + * + * Copyright (C) 2002 Lauris Kaplinski + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "config.h" + +#include +#include "libnr/nr-matrix-fns.h" +#include +#include "macros.h" +#include "svg/svg.h" +#include "display/nr-arena.h" +#include "display/nr-arena-group.h" +#include "attributes.h" +#include "document-private.h" +#include "uri.h" +#include "sp-pattern.h" +#include "xml/repr.h" + +/* + * Pattern + */ + +class SPPatPainter; + +struct SPPatPainter { + SPPainter painter; + SPPattern *pat; + + NRMatrix ps2px; + NRMatrix px2ps; + NRMatrix pcs2px; + + NRArena *arena; + unsigned int dkey; + NRArenaItem *root; + + bool use_cached_tile; + NRMatrix ca2pa; + NRMatrix pa2ca; + NRRectL cached_bbox; + NRPixBlock cached_tile; +}; + +static void sp_pattern_class_init (SPPatternClass *klass); +static void sp_pattern_init (SPPattern *gr); + +static void sp_pattern_build (SPObject *object, SPDocument *document, Inkscape::XML::Node *repr); +static void sp_pattern_release (SPObject *object); +static void sp_pattern_set (SPObject *object, unsigned int key, const gchar *value); +static void sp_pattern_child_added (SPObject *object, Inkscape::XML::Node *child, Inkscape::XML::Node *ref); +static void sp_pattern_update (SPObject *object, SPCtx *ctx, unsigned int flags); +static void sp_pattern_modified (SPObject *object, unsigned int flags); + +static void pattern_ref_changed(SPObject *old_ref, SPObject *ref, SPPattern *pat); +static void pattern_ref_modified (SPObject *ref, guint flags, SPPattern *pattern); + +static SPPainter *sp_pattern_painter_new (SPPaintServer *ps, NR::Matrix const &full_transform, NR::Matrix const &parent_transform, const NRRect *bbox); +static void sp_pattern_painter_free (SPPaintServer *ps, SPPainter *painter); + +static SPPaintServerClass * pattern_parent_class; + +GType +sp_pattern_get_type (void) +{ + static GType pattern_type = 0; + if (!pattern_type) { + GTypeInfo pattern_info = { + sizeof (SPPatternClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) sp_pattern_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (SPPattern), + 16, /* n_preallocs */ + (GInstanceInitFunc) sp_pattern_init, + NULL, /* value_table */ + }; + pattern_type = g_type_register_static (SP_TYPE_PAINT_SERVER, "SPPattern", &pattern_info, (GTypeFlags)0); + } + return pattern_type; +} + +static void +sp_pattern_class_init (SPPatternClass *klass) +{ + SPObjectClass *sp_object_class; + SPPaintServerClass *ps_class; + + sp_object_class = (SPObjectClass *) klass; + ps_class = (SPPaintServerClass *) klass; + + pattern_parent_class = (SPPaintServerClass*)g_type_class_ref (SP_TYPE_PAINT_SERVER); + + sp_object_class->build = sp_pattern_build; + sp_object_class->release = sp_pattern_release; + sp_object_class->set = sp_pattern_set; + sp_object_class->child_added = sp_pattern_child_added; + sp_object_class->update = sp_pattern_update; + sp_object_class->modified = sp_pattern_modified; + + // do we need _write? seems to work without it + + ps_class->painter_new = sp_pattern_painter_new; + ps_class->painter_free = sp_pattern_painter_free; +} + +static void +sp_pattern_init (SPPattern *pat) +{ + pat->ref = new SPPatternReference(SP_OBJECT(pat)); + pat->ref->changedSignal().connect(sigc::bind(sigc::ptr_fun(pattern_ref_changed), pat)); + + pat->patternUnits = SP_PATTERN_UNITS_OBJECTBOUNDINGBOX; + pat->patternUnits_set = FALSE; + + pat->patternContentUnits = SP_PATTERN_UNITS_USERSPACEONUSE; + pat->patternContentUnits_set = FALSE; + + pat->patternTransform = NR::identity(); + pat->patternTransform_set = FALSE; + + pat->x.unset(); + pat->y.unset(); + pat->width.unset(); + pat->height.unset(); + + pat->viewBox_set = FALSE; +} + +static void +sp_pattern_build (SPObject *object, SPDocument *document, Inkscape::XML::Node *repr) +{ + if (((SPObjectClass *) pattern_parent_class)->build) + (* ((SPObjectClass *) pattern_parent_class)->build) (object, document, repr); + + sp_object_read_attr (object, "patternUnits"); + sp_object_read_attr (object, "patternContentUnits"); + sp_object_read_attr (object, "patternTransform"); + sp_object_read_attr (object, "x"); + sp_object_read_attr (object, "y"); + sp_object_read_attr (object, "width"); + sp_object_read_attr (object, "height"); + sp_object_read_attr (object, "viewBox"); + sp_object_read_attr (object, "xlink:href"); + + /* Register ourselves */ + sp_document_add_resource (document, "pattern", object); +} + +static void +sp_pattern_release (SPObject *object) +{ + SPPattern *pat; + + pat = (SPPattern *) object; + + if (SP_OBJECT_DOCUMENT (object)) { + /* Unregister ourselves */ + sp_document_remove_resource (SP_OBJECT_DOCUMENT (object), "pattern", SP_OBJECT (object)); + } + + if (pat->ref) { + if (pat->ref->getObject()) + sp_signal_disconnect_by_data(pat->ref->getObject(), pat); + pat->ref->detach(); + delete pat->ref; + pat->ref = NULL; + } + + if (((SPObjectClass *) pattern_parent_class)->release) + ((SPObjectClass *) pattern_parent_class)->release (object); +} + +static void +sp_pattern_set (SPObject *object, unsigned int key, const gchar *value) +{ + SPPattern *pat = SP_PATTERN (object); + + switch (key) { + case SP_ATTR_PATTERNUNITS: + if (value) { + if (!strcmp (value, "userSpaceOnUse")) { + pat->patternUnits = SP_PATTERN_UNITS_USERSPACEONUSE; + } else { + pat->patternUnits = SP_PATTERN_UNITS_OBJECTBOUNDINGBOX; + } + pat->patternUnits_set = TRUE; + } else { + pat->patternUnits_set = FALSE; + } + object->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_PATTERNCONTENTUNITS: + if (value) { + if (!strcmp (value, "userSpaceOnUse")) { + pat->patternContentUnits = SP_PATTERN_UNITS_USERSPACEONUSE; + } else { + pat->patternContentUnits = SP_PATTERN_UNITS_OBJECTBOUNDINGBOX; + } + pat->patternContentUnits_set = TRUE; + } else { + pat->patternContentUnits_set = FALSE; + } + object->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_PATTERNTRANSFORM: { + NR::Matrix t; + if (value && sp_svg_transform_read (value, &t)) { + pat->patternTransform = t; + pat->patternTransform_set = TRUE; + } else { + pat->patternTransform = NR::identity(); + pat->patternTransform_set = FALSE; + } + object->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + } + case SP_ATTR_X: + pat->x.readOrUnset(value); + object->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_Y: + pat->y.readOrUnset(value); + object->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_WIDTH: + pat->width.readOrUnset(value); + object->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_HEIGHT: + pat->height.readOrUnset(value); + object->requestModified(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_VIEWBOX: { + /* fixme: Think (Lauris) */ + double x, y, width, height; + char *eptr; + + if (value) { + eptr = (gchar *) value; + x = g_ascii_strtod (eptr, &eptr); + while (*eptr && ((*eptr == ',') || (*eptr == ' '))) eptr++; + y = g_ascii_strtod (eptr, &eptr); + while (*eptr && ((*eptr == ',') || (*eptr == ' '))) eptr++; + width = g_ascii_strtod (eptr, &eptr); + while (*eptr && ((*eptr == ',') || (*eptr == ' '))) eptr++; + height = g_ascii_strtod (eptr, &eptr); + while (*eptr && ((*eptr == ',') || (*eptr == ' '))) eptr++; + if ((width > 0) && (height > 0)) { + pat->viewBox.x0 = x; + pat->viewBox.y0 = y; + pat->viewBox.x1 = x + width; + pat->viewBox.y1 = y + height; + pat->viewBox_set = TRUE; + } else { + pat->viewBox_set = FALSE; + } + } else { + pat->viewBox_set = FALSE; + } + object->requestModified(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG); + break; + } + case SP_ATTR_XLINK_HREF: + if ( value && pat->href && ( strcmp(value, pat->href) == 0 ) ) { + /* Href unchanged, do nothing. */ + } else { + g_free(pat->href); + pat->href = NULL; + if (value) { + // First, set the href field; it's only used in the "unchanged" check above. + pat->href = g_strdup(value); + // Now do the attaching, which emits the changed signal. + if (value) { + try { + pat->ref->attach(Inkscape::URI(value)); + } catch (Inkscape::BadURIException &e) { + g_warning("%s", e.what()); + pat->ref->detach(); + } + } else { + pat->ref->detach(); + } + } + } + break; + default: + if (((SPObjectClass *) pattern_parent_class)->set) + ((SPObjectClass *) pattern_parent_class)->set (object, key, value); + break; + } +} + +static void +sp_pattern_child_added (SPObject *object, Inkscape::XML::Node *child, Inkscape::XML::Node *ref) +{ + SPPattern *pat = SP_PATTERN (object); + + if (((SPObjectClass *) (pattern_parent_class))->child_added) + (* ((SPObjectClass *) (pattern_parent_class))->child_added) (object, child, ref); + + SPObject *ochild = sp_object_get_child_by_repr(object, child); + if (SP_IS_ITEM (ochild)) { + + SPPaintServer *ps = SP_PAINT_SERVER (pat); + unsigned position = sp_item_pos_in_parent(SP_ITEM(ochild)); + + for (SPPainter *p = ps->painters; p != NULL; p = p->next) { + + SPPatPainter *pp = (SPPatPainter *) p; + NRArenaItem *ai = sp_item_invoke_show (SP_ITEM (ochild), pp->arena, pp->dkey, SP_ITEM_REFERENCE_FLAGS); + + if (ai) { + nr_arena_item_add_child (pp->root, ai, NULL); + nr_arena_item_set_order (ai, position); + nr_arena_item_unref (ai); + } + } + } +} + +/* TODO: do we need a ::remove_child handler? */ + +/* fixme: We need ::order_changed handler too (Lauris) */ + +GSList * +pattern_getchildren (SPPattern *pat) +{ + GSList *l = NULL; + + for (SPPattern *pat_i = pat; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) { + if (sp_object_first_child(SP_OBJECT(pat_i))) { // find the first one with children + for (SPObject *child = sp_object_first_child(SP_OBJECT (pat)) ; child != NULL ; child = SP_OBJECT_NEXT(child) ) { + l = g_slist_prepend (l, child); + } + break; // do not go further up the chain if children are found + } + } + + return l; +} + +static void +sp_pattern_update (SPObject *object, SPCtx *ctx, unsigned int flags) +{ + SPPattern *pat = SP_PATTERN (object); + + if (flags & SP_OBJECT_MODIFIED_FLAG) flags |= SP_OBJECT_PARENT_MODIFIED_FLAG; + flags &= SP_OBJECT_MODIFIED_CASCADE; + + GSList *l = pattern_getchildren (pat); + l = g_slist_reverse (l); + + while (l) { + SPObject *child = SP_OBJECT (l->data); + sp_object_ref (child, NULL); + l = g_slist_remove (l, child); + if (flags || (child->mflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { + child->updateDisplay(ctx, flags); + } + sp_object_unref (child, NULL); + } +} + +static void +sp_pattern_modified (SPObject *object, guint flags) +{ + SPPattern *pat = SP_PATTERN (object); + + if (flags & SP_OBJECT_MODIFIED_FLAG) flags |= SP_OBJECT_PARENT_MODIFIED_FLAG; + flags &= SP_OBJECT_MODIFIED_CASCADE; + + GSList *l = pattern_getchildren (pat); + l = g_slist_reverse (l); + + while (l) { + SPObject *child = SP_OBJECT (l->data); + sp_object_ref (child, NULL); + l = g_slist_remove (l, child); + if (flags || (child->mflags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG))) { + child->emitModified(flags); + } + sp_object_unref (child, NULL); + } +} + +/** +Gets called when the pattern is reattached to another +*/ +static void +pattern_ref_changed(SPObject *old_ref, SPObject *ref, SPPattern *pat) +{ + if (old_ref) { + sp_signal_disconnect_by_data(old_ref, pat); + } + if (SP_IS_PATTERN (ref)) { + g_signal_connect(G_OBJECT (ref), "modified", G_CALLBACK (pattern_ref_modified), pat); + } + + pattern_ref_modified (ref, 0, pat); +} + +/** +Gets called when the referenced is changed +*/ +static void +pattern_ref_modified (SPObject *ref, guint flags, SPPattern *pattern) +{ + if (SP_IS_OBJECT (pattern)) + SP_OBJECT (pattern)->requestModified(SP_OBJECT_MODIFIED_FLAG); +} + +guint +pattern_users (SPPattern *pattern) +{ + return SP_OBJECT (pattern)->hrefcount; +} + +SPPattern * +pattern_chain (SPPattern *pattern) +{ + SPDocument *document = SP_OBJECT_DOCUMENT (pattern); + Inkscape::XML::Node *defsrepr = SP_OBJECT_REPR (SP_DOCUMENT_DEFS (document)); + + Inkscape::XML::Node *repr = sp_repr_new ("svg:pattern"); + repr->setAttribute("inkscape:collect", "always"); + gchar *parent_ref = g_strconcat ("#", SP_OBJECT_REPR(pattern)->attribute("id"), NULL); + repr->setAttribute("xlink:href", parent_ref); + g_free (parent_ref); + + defsrepr->addChild(repr, NULL); + const gchar *child_id = repr->attribute("id"); + SPObject *child = document->getObjectById(child_id); + g_assert (SP_IS_PATTERN (child)); + + return SP_PATTERN (child); +} + +SPPattern * +sp_pattern_clone_if_necessary (SPItem *item, SPPattern *pattern, const gchar *property) +{ + if (pattern_users(pattern) > 1) { + pattern = pattern_chain (pattern); + gchar *href = g_strconcat ("url(#", SP_OBJECT_REPR (pattern)->attribute("id"), ")", NULL); + + SPCSSAttr *css = sp_repr_css_attr_new (); + sp_repr_css_set_property (css, property, href); + sp_repr_css_change_recursive (SP_OBJECT_REPR (item), css, "style"); + } + return pattern; +} + +void +sp_pattern_transform_multiply (SPPattern *pattern, NR::Matrix postmul, bool set) +{ + // this formula is for a different interpretation of pattern transforms as described in (*) in sp-pattern.cpp + // for it to work, we also need sp_object_read_attr (SP_OBJECT (item), "transform"); + //pattern->patternTransform = premul * item->transform * pattern->patternTransform * item->transform.inverse() * postmul; + + // otherwise the formula is much simpler + if (set) { + pattern->patternTransform = postmul; + } else { + pattern->patternTransform = pattern_patternTransform(pattern) * postmul; + } + pattern->patternTransform_set = TRUE; + + gchar c[256]; + if (sp_svg_transform_write(c, 256, pattern->patternTransform)) { + SP_OBJECT_REPR(pattern)->setAttribute("patternTransform", c); + } else { + SP_OBJECT_REPR(pattern)->setAttribute("patternTransform", NULL); + } +} + +const gchar * +pattern_tile (GSList *reprs, NR::Rect bounds, SPDocument *document, NR::Matrix transform, NR::Matrix move) +{ + Inkscape::XML::Node *defsrepr = SP_OBJECT_REPR (SP_DOCUMENT_DEFS (document)); + + Inkscape::XML::Node *repr = sp_repr_new ("svg:pattern"); + repr->setAttribute("patternUnits", "userSpaceOnUse"); + sp_repr_set_svg_double(repr, "width", bounds.extent(NR::X)); + sp_repr_set_svg_double(repr, "height", bounds.extent(NR::Y)); + + gchar t[256]; + if (sp_svg_transform_write(t, 256, transform)) { + repr->setAttribute("patternTransform", t); + } else { + repr->setAttribute("patternTransform", NULL); + } + + + defsrepr->appendChild(repr); + const gchar *pat_id = repr->attribute("id"); + SPObject *pat_object = document->getObjectById(pat_id); + + for (GSList *i = reprs; i != NULL; i = i->next) { + Inkscape::XML::Node *node = (Inkscape::XML::Node *)(i->data); + SPItem *copy = SP_ITEM(pat_object->appendChildRepr(node)); + + NR::Matrix dup_transform; + if (!sp_svg_transform_read (node->attribute("transform"), &dup_transform)) + dup_transform = NR::identity(); + dup_transform *= move; + + sp_item_write_transform(copy, SP_OBJECT_REPR(copy), dup_transform); + } + + Inkscape::GC::release(repr); + return pat_id; +} + +SPPattern * +pattern_getroot (SPPattern *pat) +{ + for (SPPattern *pat_i = pat; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) { + if (sp_object_first_child(SP_OBJECT(pat_i))) { // find the first one with children + return pat_i; + } + } + return pat; // document is broken, we can't get to root; but at least we can return pat which is supposedly a valid pattern +} + + + +// Access functions that look up fields up the chain of referenced patterns and return the first one which is set + +guint pattern_patternUnits (SPPattern *pat) +{ + for (SPPattern *pat_i = pat; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) { + if (pat_i->patternUnits_set) + return pat_i->patternUnits; + } + return pat->patternUnits; +} + +guint pattern_patternContentUnits (SPPattern *pat) +{ + for (SPPattern *pat_i = pat; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) { + if (pat_i->patternContentUnits_set) + return pat_i->patternContentUnits; + } + return pat->patternContentUnits; +} + +NR::Matrix const &pattern_patternTransform(SPPattern const *pat) +{ + for (SPPattern const *pat_i = pat; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) { + if (pat_i->patternTransform_set) + return pat_i->patternTransform; + } + return pat->patternTransform; +} + +gdouble pattern_x (SPPattern *pat) +{ + for (SPPattern *pat_i = pat; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) { + if (pat_i->x._set) + return pat_i->x.computed; + } + return 0; +} + +gdouble pattern_y (SPPattern *pat) +{ + for (SPPattern *pat_i = pat; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) { + if (pat_i->y._set) + return pat_i->y.computed; + } + return 0; +} + +gdouble pattern_width (SPPattern *pat) +{ + for (SPPattern *pat_i = pat; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) { + if (pat_i->width._set) + return pat_i->width.computed; + } + return 0; +} + +gdouble pattern_height (SPPattern *pat) +{ + for (SPPattern *pat_i = pat; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) { + if (pat_i->height._set) + return pat_i->height.computed; + } + return 0; +} + +NRRect *pattern_viewBox (SPPattern *pat) +{ + for (SPPattern *pat_i = pat; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) { + if (pat_i->viewBox_set) + return &(pat_i->viewBox); + } + return &(pat->viewBox); +} + +bool pattern_hasItemChildren (SPPattern *pat) +{ + for (SPObject *child = sp_object_first_child(SP_OBJECT(pat)) ; child != NULL; child = SP_OBJECT_NEXT(child) ) { + if (SP_IS_ITEM (child)) { + return true; + } + } + return false; +} + + + +/* Painter */ + +static void sp_pat_fill (SPPainter *painter, NRPixBlock *pb); + +/** +Creates a painter (i.e. the thing that does actual filling at the given zoom). +See (*) below for why the parent_transform may be necessary. +*/ +static SPPainter * +sp_pattern_painter_new (SPPaintServer *ps, NR::Matrix const &full_transform, NR::Matrix const &parent_transform, const NRRect *bbox) +{ + SPPattern *pat = SP_PATTERN (ps); + SPPatPainter *pp = g_new (SPPatPainter, 1); + + pp->painter.type = SP_PAINTER_IND; + pp->painter.fill = sp_pat_fill; + + pp->pat = pat; + + if (pattern_patternUnits (pat) == SP_PATTERN_UNITS_OBJECTBOUNDINGBOX) { + /* BBox to user coordinate system */ + NR::Matrix bbox2user (bbox->x1 - bbox->x0, 0.0, 0.0, bbox->y1 - bbox->y0, bbox->x0, bbox->y0); + + // the final patternTransform, taking into account bbox + NR::Matrix const ps2user(pattern_patternTransform(pat) * bbox2user); + + // see (*) comment below + NR::Matrix ps2px = ps2user * full_transform; + + ps2px.copyto (&pp->ps2px); + + } else { + /* Problem: What to do, if we have mixed lengths and percentages? */ + /* Currently we do ignore percentages at all, but that is not good (lauris) */ + + /* fixme: We may try to normalize here too, look at linearGradient (Lauris) */ + + // (*) The spec says, "This additional transformation matrix [patternTransform] is + // post-multiplied to (i.e., inserted to the right of) any previously defined + // transformations, including the implicit transformation necessary to convert from + // object bounding box units to user space." To me, this means that the order should be: + // item_transform * patternTransform * parent_transform + // However both Batik and Adobe plugin use: + // patternTransform * item_transform * parent_transform + // So here I comply with the majority opinion, but leave my interpretation commented out below. + // (To get item_transform, I subtract parent from full.) + + //NR::Matrix ps2px = (full_transform / parent_transform) * pattern_patternTransform(pat) * parent_transform; + NR::Matrix ps2px = pattern_patternTransform(pat) * full_transform; + + ps2px.copyto (&pp->ps2px); + } + + nr_matrix_invert (&pp->px2ps, &pp->ps2px); + + if (pat->viewBox_set) { + gdouble tmp_x = (pattern_viewBox(pat)->x1 - pattern_viewBox(pat)->x0) / pattern_width (pat); + gdouble tmp_y = (pattern_viewBox(pat)->y1 - pattern_viewBox(pat)->y0) / pattern_height (pat); + + // FIXME: preserveAspectRatio must be taken into account here too! + NR::Matrix vb2ps (tmp_x, 0.0, 0.0, tmp_y, pattern_x(pat) - pattern_viewBox(pat)->x0, pattern_y(pat) - pattern_viewBox(pat)->y0); + + NR::Matrix vb2us = vb2ps * pattern_patternTransform(pat); + + // see (*) + NR::Matrix pcs2px = vb2us * full_transform; + + pcs2px.copyto (&pp->pcs2px); + } else { + NR::Matrix pcs2px; + + /* No viewbox, have to parse units */ + if (pattern_patternContentUnits (pat) == SP_PATTERN_UNITS_OBJECTBOUNDINGBOX) { + /* BBox to user coordinate system */ + NR::Matrix bbox2user (bbox->x1 - bbox->x0, 0.0, 0.0, bbox->y1 - bbox->y0, bbox->x0, bbox->y0); + + NR::Matrix pcs2user = pattern_patternTransform(pat) * bbox2user; + + // see (*) + pcs2px = pcs2user * full_transform; + } else { + // see (*) + //pcs2px = (full_transform / parent_transform) * pattern_patternTransform(pat) * parent_transform; + pcs2px = pattern_patternTransform(pat) * full_transform; + } + + pcs2px = NR::translate (pattern_x (pat), pattern_y (pat)) * pcs2px; + + pcs2px.copyto (&pp->pcs2px); + } + + /* Create arena */ + pp->arena = NRArena::create(); + + pp->dkey = sp_item_display_key_new (1); + + /* Create group */ + pp->root = NRArenaGroup::create(pp->arena); + + /* Show items */ + for (SPPattern *pat_i = pat; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) { + if (pat_i && SP_IS_OBJECT (pat_i) && pattern_hasItemChildren(pat_i)) { // find the first one with item children + for (SPObject *child = sp_object_first_child(SP_OBJECT(pat_i)) ; child != NULL; child = SP_OBJECT_NEXT(child) ) { + if (SP_IS_ITEM (child)) { + NRArenaItem *cai; + cai = sp_item_invoke_show (SP_ITEM (child), pp->arena, pp->dkey, SP_ITEM_REFERENCE_FLAGS); + nr_arena_item_append_child (pp->root, cai); + nr_arena_item_unref (cai); + } + } + break; // do not go further up the chain if children are found + } + } + + { + NRRect one_tile,tr_tile; + one_tile.x0=pattern_x(pp->pat); + one_tile.y0=pattern_y(pp->pat); + one_tile.x1=one_tile.x0+pattern_width (pp->pat); + one_tile.y1=one_tile.y0+pattern_height (pp->pat); + nr_rect_d_matrix_transform (&tr_tile, &one_tile, &pp->ps2px); + int tr_width=(int)ceil(1.3*(tr_tile.x1-tr_tile.x0)); + int tr_height=(int)ceil(1.3*(tr_tile.y1-tr_tile.y0)); +// if ( tr_width < 10000 && tr_height < 10000 && tr_width*tr_height < 1000000 ) { + pp->use_cached_tile=false;//true; + if ( tr_width > 1000 ) tr_width=1000; + if ( tr_height > 1000 ) tr_height=1000; + pp->cached_bbox.x0=0; + pp->cached_bbox.y0=0; + pp->cached_bbox.x1=tr_width; + pp->cached_bbox.y1=tr_height; + + if (pp->use_cached_tile) { + nr_pixblock_setup (&pp->cached_tile,NR_PIXBLOCK_MODE_R8G8B8A8N, pp->cached_bbox.x0, pp->cached_bbox.y0, pp->cached_bbox.x1, pp->cached_bbox.y1,TRUE); + } + + pp->pa2ca.c[0]=((double)tr_width)/(one_tile.x1-one_tile.x0); + pp->pa2ca.c[1]=0; + pp->pa2ca.c[2]=0; + pp->pa2ca.c[3]=((double)tr_height)/(one_tile.y1-one_tile.y0); + pp->pa2ca.c[4]=-one_tile.x0*pp->pa2ca.c[0]; + pp->pa2ca.c[5]=-one_tile.y0*pp->pa2ca.c[1]; + pp->ca2pa.c[0]=(one_tile.x1-one_tile.x0)/((double)tr_width); + pp->ca2pa.c[1]=0; + pp->ca2pa.c[2]=0; + pp->ca2pa.c[3]=(one_tile.y1-one_tile.y0)/((double)tr_height); + pp->ca2pa.c[4]=one_tile.x0; + pp->ca2pa.c[5]=one_tile.y0; +// } else { +// pp->use_cached_tile=false; +// } + } + + NRGC gc(NULL); + if ( pp->use_cached_tile ) { + gc.transform=pp->pa2ca; + } else { + gc.transform = pp->pcs2px; + } + nr_arena_item_invoke_update (pp->root, NULL, &gc, NR_ARENA_ITEM_STATE_ALL, NR_ARENA_ITEM_STATE_ALL); + if ( pp->use_cached_tile ) { + nr_arena_item_invoke_render (pp->root, &pp->cached_bbox, &pp->cached_tile, 0); + } else { + // nothing to do now + } + + return (SPPainter *) pp; +} + +static void +sp_pattern_painter_free (SPPaintServer *ps, SPPainter *painter) +{ + SPPatPainter *pp = (SPPatPainter *) painter; + SPPattern *pat = pp->pat; + + for (SPPattern *pat_i = pat; pat_i != NULL; pat_i = pat_i->ref ? pat_i->ref->getObject() : NULL) { + if (pat_i && SP_IS_OBJECT (pat_i) && pattern_hasItemChildren(pat_i)) { // find the first one with item children + for (SPObject *child = sp_object_first_child(SP_OBJECT(pat_i)) ; child != NULL; child = SP_OBJECT_NEXT(child) ) { + if (SP_IS_ITEM (child)) { + sp_item_invoke_hide (SP_ITEM (child), pp->dkey); + } + } + break; // do not go further up the chain if children are found + } + } + if ( pp->use_cached_tile ) nr_pixblock_release(&pp->cached_tile); + g_free (pp); +} + +void +get_cached_tile_pixel(SPPatPainter* pp,double x,double y,unsigned char &r,unsigned char &g,unsigned char &b,unsigned char &a) +{ + int ca_h=(int)floor(x); + int ca_v=(int)floor(y); + int r_x=(int)floor(16*(x-floor(x))); + int r_y=(int)floor(16*(y-floor(y))); + unsigned int tl_m=(16-r_x)*(16-r_y); + unsigned int bl_m=(16-r_x)*r_y; + unsigned int tr_m=r_x*(16-r_y); + unsigned int br_m=r_x*r_y; + int cb_h=ca_h+1; + int cb_v=ca_v+1; + if ( cb_h >= pp->cached_bbox.x1 ) cb_h=0; + if ( cb_v >= pp->cached_bbox.y1 ) cb_v=0; + + unsigned char* tlx=NR_PIXBLOCK_PX(&pp->cached_tile)+(ca_v*pp->cached_tile.rs)+4*ca_h; + unsigned char* trx=NR_PIXBLOCK_PX(&pp->cached_tile)+(ca_v*pp->cached_tile.rs)+4*cb_h; + unsigned char* blx=NR_PIXBLOCK_PX(&pp->cached_tile)+(cb_v*pp->cached_tile.rs)+4*ca_h; + unsigned char* brx=NR_PIXBLOCK_PX(&pp->cached_tile)+(cb_v*pp->cached_tile.rs)+4*cb_h; + + unsigned int tl_c=tlx[0]; + unsigned int tr_c=trx[0]; + unsigned int bl_c=blx[0]; + unsigned int br_c=brx[0]; + unsigned int f_c=(tl_m*tl_c+tr_m*tr_c+bl_m*bl_c+br_m*br_c)>>8; + r=f_c; + tl_c=tlx[1]; + tr_c=trx[1]; + bl_c=blx[1]; + br_c=brx[1]; + f_c=(tl_m*tl_c+tr_m*tr_c+bl_m*bl_c+br_m*br_c)>>8; + g=f_c; + tl_c=tlx[2]; + tr_c=trx[2]; + bl_c=blx[2]; + br_c=brx[2]; + f_c=(tl_m*tl_c+tr_m*tr_c+bl_m*bl_c+br_m*br_c)>>8; + b=f_c; + tl_c=tlx[3]; + tr_c=trx[3]; + bl_c=blx[3]; + br_c=brx[3]; + f_c=(tl_m*tl_c+tr_m*tr_c+bl_m*bl_c+br_m*br_c)>>8; + a=f_c; +} + +static void +sp_pat_fill (SPPainter *painter, NRPixBlock *pb) +{ + SPPatPainter *pp; + NRRect ba, psa; + NRRectL area; + double x, y; + + pp = (SPPatPainter *) painter; + + if (pattern_width (pp->pat) < NR_EPSILON) return; + if (pattern_height (pp->pat) < NR_EPSILON) return; + + /* Find buffer area in gradient space */ + /* fixme: This is suboptimal (Lauris) */ + + if ( pp->use_cached_tile ) { + double pat_w=pattern_width (pp->pat); + double pat_h=pattern_height (pp->pat); + if ( pb->mode == NR_PIXBLOCK_MODE_R8G8B8A8N || pb->mode == NR_PIXBLOCK_MODE_R8G8B8A8P ) { // same thing because it's filling an empty pixblock + unsigned char* lpx=NR_PIXBLOCK_PX(pb); + double px_y=pb->area.y0; + for (int j=pb->area.y0;jarea.y1;j++) { + unsigned char* cpx=lpx; + double px_x = pb->area.x0; + + double ps_x=pp->px2ps.c[0]*px_x+pp->px2ps.c[2]*px_y+pp->px2ps.c[4]; + double ps_y=pp->px2ps.c[1]*px_x+pp->px2ps.c[3]*px_y+pp->px2ps.c[5]; + for (int i=pb->area.x0;iarea.x1;i++) { + while ( ps_x > pat_w ) ps_x-=pat_w; + while ( ps_x < 0 ) ps_x+=pat_w; + while ( ps_y > pat_h ) ps_y-=pat_h; + while ( ps_y < 0 ) ps_y+=pat_h; + double ca_x=pp->pa2ca.c[0]*ps_x+pp->pa2ca.c[2]*ps_y+pp->pa2ca.c[4]; + double ca_y=pp->pa2ca.c[1]*ps_x+pp->pa2ca.c[3]*ps_y+pp->pa2ca.c[5]; + unsigned char n_a,n_r,n_g,n_b; + get_cached_tile_pixel(pp,ca_x,ca_y,n_r,n_g,n_b,n_a); + cpx[0]=n_r; + cpx[1]=n_g; + cpx[2]=n_b; + cpx[3]=n_a; + + px_x+=1.0; + ps_x+=pp->px2ps.c[0]; + ps_y+=pp->px2ps.c[1]; + cpx+=4; + } + px_y+=1.0; + lpx+=pb->rs; + } + } else if ( pb->mode == NR_PIXBLOCK_MODE_R8G8B8 ) { + unsigned char* lpx=NR_PIXBLOCK_PX(pb); + double px_y=pb->area.y0; + for (int j=pb->area.y0;jarea.y1;j++) { + unsigned char* cpx=lpx; + double px_x = pb->area.x0; + + double ps_x=pp->px2ps.c[0]*px_x+pp->px2ps.c[2]*px_y+pp->px2ps.c[4]; + double ps_y=pp->px2ps.c[1]*px_x+pp->px2ps.c[3]*px_y+pp->px2ps.c[5]; + for (int i=pb->area.x0;iarea.x1;i++) { + while ( ps_x > pat_w ) ps_x-=pat_w; + while ( ps_x < 0 ) ps_x+=pat_w; + while ( ps_y > pat_h ) ps_y-=pat_h; + while ( ps_y < 0 ) ps_y+=pat_h; + double ca_x=pp->pa2ca.c[0]*ps_x+pp->pa2ca.c[2]*ps_y+pp->pa2ca.c[4]; + double ca_y=pp->pa2ca.c[1]*ps_x+pp->pa2ca.c[3]*ps_y+pp->pa2ca.c[5]; + unsigned char n_a,n_r,n_g,n_b; + get_cached_tile_pixel(pp,ca_x,ca_y,n_r,n_g,n_b,n_a); + cpx[0]=n_r; + cpx[1]=n_g; + cpx[2]=n_b; + + px_x+=1.0; + ps_x+=pp->px2ps.c[0]; + ps_y+=pp->px2ps.c[1]; + cpx+=4; + } + px_y+=1.0; + lpx+=pb->rs; + } + } + } else { + ba.x0 = pb->area.x0; + ba.y0 = pb->area.y0; + ba.x1 = pb->area.x1; + ba.y1 = pb->area.y1; + nr_rect_d_matrix_transform (&psa, &ba, &pp->px2ps); + + psa.x0 = floor ((psa.x0 - pattern_x (pp->pat)) / pattern_width (pp->pat)) -1; + psa.y0 = floor ((psa.y0 - pattern_y (pp->pat)) / pattern_height (pp->pat)) -1; + psa.x1 = ceil ((psa.x1 - pattern_x (pp->pat)) / pattern_width (pp->pat)) +1; + psa.y1 = ceil ((psa.y1 - pattern_y (pp->pat)) / pattern_height (pp->pat)) +1; + + for (y = psa.y0; y < psa.y1; y++) { + for (x = psa.x0; x < psa.x1; x++) { + NRPixBlock ppb; + double psx, psy; + + psx = x * pattern_width (pp->pat); + psy = y * pattern_height (pp->pat); + + area.x0 = (gint32)(pb->area.x0 - (pp->ps2px.c[0] * psx + pp->ps2px.c[2] * psy)); + area.y0 = (gint32)(pb->area.y0 - (pp->ps2px.c[1] * psx + pp->ps2px.c[3] * psy)); + area.x1 = area.x0 + pb->area.x1 - pb->area.x0; + area.y1 = area.y0 + pb->area.y1 - pb->area.y0; + + // We do not update here anymore + + // Set up buffer + // fixme: (Lauris) + nr_pixblock_setup_extern (&ppb, pb->mode, area.x0, area.y0, area.x1, area.y1, NR_PIXBLOCK_PX (pb), pb->rs, FALSE, FALSE); + + nr_arena_item_invoke_render (pp->root, &area, &ppb, 0); + + nr_pixblock_release (&ppb); + } + } + } +} diff --git a/src/sp-pattern.h b/src/sp-pattern.h new file mode 100644 index 000000000..42cac7a7e --- /dev/null +++ b/src/sp-pattern.h @@ -0,0 +1,98 @@ +#ifndef __SP_PATTERN_H__ +#define __SP_PATTERN_H__ + +/* + * SVG implementation + * + * Author: + * Lauris Kaplinski + * + * Copyright (C) 2002 Lauris Kaplinski + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include + +#include "forward.h" + +#define SP_TYPE_PATTERN (sp_pattern_get_type ()) +#define SP_PATTERN(o) (GTK_CHECK_CAST ((o), SP_TYPE_PATTERN, SPPattern)) +#define SP_PATTERN_CLASS(k) (GTK_CHECK_CLASS_CAST ((k), SP_TYPE_PATTERN, SPPatternClass)) +#define SP_IS_PATTERN(o) (GTK_CHECK_TYPE ((o), SP_TYPE_PATTERN)) +#define SP_IS_PATTERN_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), SP_TYPE_PATTERN)) + +GType sp_pattern_get_type (void); + +class SPPatternClass; + +#include +#include +#include "svg/svg-length.h" +#include "sp-paint-server.h" +#include "uri-references.h" + +class SPPatternReference : public Inkscape::URIReference { +public: + SPPatternReference (SPObject *obj) : URIReference(obj) {} + SPPattern *getObject() const { + return (SPPattern *)URIReference::getObject(); + } +protected: + virtual bool _acceptObject(SPObject *obj) const { + return SP_IS_PATTERN (obj); + } +}; + +enum { + SP_PATTERN_UNITS_USERSPACEONUSE, + SP_PATTERN_UNITS_OBJECTBOUNDINGBOX +}; + +struct SPPattern : public SPPaintServer { + /* Reference (href) */ + gchar *href; + SPPatternReference *ref; + + /* patternUnits and patternContentUnits attribute */ + guint patternUnits : 1; + guint patternUnits_set : 1; + guint patternContentUnits : 1; + guint patternContentUnits_set : 1; + /* patternTransform attribute */ + NR::Matrix patternTransform; + guint patternTransform_set : 1; + /* Tile rectangle */ + SVGLength x; + SVGLength y; + SVGLength width; + SVGLength height; + /* VieBox */ + NRRect viewBox; + guint viewBox_set : 1; +}; + +struct SPPatternClass { + SPPaintServerClass parent_class; +}; + +guint pattern_users (SPPattern *pattern); +SPPattern *pattern_chain (SPPattern *pattern); +SPPattern *sp_pattern_clone_if_necessary (SPItem *item, SPPattern *pattern, const gchar *property); +void sp_pattern_transform_multiply (SPPattern *pattern, NR::Matrix postmul, bool set); + +const gchar *pattern_tile (GSList *reprs, NR::Rect bounds, SPDocument *document, NR::Matrix transform, NR::Matrix move); + +SPPattern *pattern_getroot (SPPattern *pat); + +guint pattern_patternUnits (SPPattern *pat); +guint pattern_patternContentUnits (SPPattern *pat); +NR::Matrix const &pattern_patternTransform(SPPattern const *pat); +gdouble pattern_x (SPPattern *pat); +gdouble pattern_y (SPPattern *pat); +gdouble pattern_width (SPPattern *pat); +gdouble pattern_height (SPPattern *pat); +NRRect *pattern_viewBox (SPPattern *pat); + + +#endif diff --git a/src/sp-polygon.cpp b/src/sp-polygon.cpp new file mode 100644 index 000000000..eb5efc176 --- /dev/null +++ b/src/sp-polygon.cpp @@ -0,0 +1,225 @@ +#define __SP_POLYGON_C__ + +/* + * SVG implementation + * + * Authors: + * Lauris Kaplinski + * + * Copyright (C) 1999-2002 Lauris Kaplinski + * Copyright (C) 2000-2001 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "config.h" + +#include "attributes.h" +#include "sp-polygon.h" +#include "display/curve.h" +#include +#include "libnr/n-art-bpath.h" +#include "svg/stringstream.h" +#include "xml/repr.h" + +static void sp_polygon_class_init(SPPolygonClass *pc); +static void sp_polygon_init(SPPolygon *polygon); + +static void sp_polygon_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr); +static Inkscape::XML::Node *sp_polygon_write(SPObject *object, Inkscape::XML::Node *repr, guint flags); +static void sp_polygon_set(SPObject *object, unsigned int key, const gchar *value); + +static gchar *sp_polygon_description(SPItem *item); + +static SPShapeClass *parent_class; + +GType sp_polygon_get_type(void) +{ + static GType polygon_type = 0; + + if (!polygon_type) { + GTypeInfo polygon_info = { + sizeof(SPPolygonClass), + NULL, NULL, + (GClassInitFunc) sp_polygon_class_init, + NULL, NULL, + sizeof(SPPolygon), + 16, + (GInstanceInitFunc) sp_polygon_init, + NULL, /* value_table */ + }; + polygon_type = g_type_register_static(SP_TYPE_SHAPE, "SPPolygon", &polygon_info, (GTypeFlags) 0); + } + + return polygon_type; +} + +static void sp_polygon_class_init(SPPolygonClass *pc) +{ + SPObjectClass *sp_object_class = (SPObjectClass *) pc; + SPItemClass *item_class = (SPItemClass *) pc; + + parent_class = (SPShapeClass *) g_type_class_ref(SP_TYPE_SHAPE); + + sp_object_class->build = sp_polygon_build; + sp_object_class->write = sp_polygon_write; + sp_object_class->set = sp_polygon_set; + + item_class->description = sp_polygon_description; +} + +static void sp_polygon_init(SPPolygon *polygon) +{ + /* Nothing here */ +} + +static void sp_polygon_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr) +{ + if (((SPObjectClass *) parent_class)->build) { + ((SPObjectClass *) parent_class)->build(object, document, repr); + } + + sp_object_read_attr(object, "points"); +} + + +/* + * sp_svg_write_polygon: Write points attribute for polygon tag. + * @bpath: + * + * Return value: points attribute string. + */ +static gchar *sp_svg_write_polygon(const NArtBpath *bpath) +{ + g_return_val_if_fail(bpath != NULL, NULL); + + Inkscape::SVGOStringStream os; + + for (int i = 0; bpath[i].code != NR_END; i++) { + switch (bpath [i].code) { + case NR_LINETO: + case NR_MOVETO: + case NR_MOVETO_OPEN: + os << bpath [i].x3 << "," << bpath [i].y3 << " "; + break; + + case NR_CURVETO: + default: + g_assert_not_reached(); + } + } + + return g_strdup(os.str().c_str()); +} + +static Inkscape::XML::Node *sp_polygon_write(SPObject *object, Inkscape::XML::Node *repr, guint flags) +{ + SPShape *shape = SP_SHAPE(object); + // Tolerable workaround: we need to update the object's curve before we set points= + // because it's out of sync when e.g. some extension attrs of the polygon or star are changed in XML editor + sp_shape_set_shape(shape); + + if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { + repr = sp_repr_new("svg:polygon"); + } + + /* We can safely write points here, because all subclasses require it too (Lauris) */ + NArtBpath *abp = sp_curve_first_bpath(shape->curve); + gchar *str = sp_svg_write_polygon(abp); + repr->setAttribute("points", str); + g_free(str); + + if (((SPObjectClass *) (parent_class))->write) { + ((SPObjectClass *) (parent_class))->write(object, repr, flags); + } + + return repr; +} + + +static gboolean polygon_get_value(gchar const **p, gdouble *v) +{ + while (**p != '\0' && (**p == ',' || **p == '\x20' || **p == '\x9' || **p == '\xD' || **p == '\xA')) { + (*p)++; + } + + if (*p == '\0') { + return false; + } + + gchar *e = NULL; + *v = g_ascii_strtod(*p, &e); + if (e == *p) { + return false; + } + + *p = e; + return true; +} + + +static void sp_polygon_set(SPObject *object, unsigned int key, const gchar *value) +{ + SPPolygon *polygon = SP_POLYGON(object); + + switch (key) { + case SP_ATTR_POINTS: { + if (!value) { + break; + } + SPCurve *curve = sp_curve_new(); + gboolean hascpt = FALSE; + + const gchar *cptr = value; + + while (TRUE) { + gdouble x; + if (!polygon_get_value(&cptr, &x)) { + break; + } + + gdouble y; + if (!polygon_get_value(&cptr, &y)) { + break; + } + + if (hascpt) { + sp_curve_lineto(curve, x, y); + } else { + sp_curve_moveto(curve, x, y); + hascpt = TRUE; + } + } + + /* TODO: if *cptr != '\0' or if the break came after parsing an x without a y then + * there's an error, which should be handled according to + * http://www.w3.org/TR/SVG11/implnote.html#ErrorProcessing. */ + + sp_curve_closepath(curve); + sp_shape_set_curve(SP_SHAPE(polygon), curve, TRUE); + sp_curve_unref(curve); + break; + } + default: + if (((SPObjectClass *) parent_class)->set) { + ((SPObjectClass *) parent_class)->set(object, key, value); + } + break; + } +} + +static gchar *sp_polygon_description(SPItem *item) +{ + return g_strdup(_("Polygon")); +} + +/* + 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 : diff --git a/src/sp-polygon.h b/src/sp-polygon.h new file mode 100644 index 000000000..0da720fc2 --- /dev/null +++ b/src/sp-polygon.h @@ -0,0 +1,33 @@ +#ifndef __SP_POLYGON_H__ +#define __SP_POLYGON_H__ + +/* + * SVG implementation + * + * Authors: + * Lauris Kaplinski + * + * Copyright (C) 1999-2002 Lauris Kaplinski + * Copyright (C) 2000-2001 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "sp-shape.h" + +#define SP_TYPE_POLYGON (sp_polygon_get_type ()) +#define SP_POLYGON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SP_TYPE_POLYGON, SPPolygon)) +#define SP_POLYGON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SP_TYPE_POLYGON, SPPolygonClass)) +#define SP_IS_POLYGON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_POLYGON)) +#define SP_IS_POLYGON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SP_TYPE_POLYGON)) + +struct SPPolygon : public SPShape { +}; + +struct SPPolygonClass { + SPShapeClass parent_class; +}; + +GType sp_polygon_get_type (void); + +#endif diff --git a/src/sp-polyline.cpp b/src/sp-polyline.cpp new file mode 100644 index 000000000..54a38ccd1 --- /dev/null +++ b/src/sp-polyline.cpp @@ -0,0 +1,177 @@ +#define __SP_POLYLINE_C__ + +/* + * SVG implementation + * + * Authors: + * Lauris Kaplinski + * + * Copyright (C) 1999-2002 Lauris Kaplinski + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "config.h" + +#include "attributes.h" +#include "sp-polyline.h" +#include "display/curve.h" +#include +#include "xml/repr.h" + +static void sp_polyline_class_init (SPPolyLineClass *klass); +static void sp_polyline_init (SPPolyLine *polyline); + +static void sp_polyline_build (SPObject * object, SPDocument * document, Inkscape::XML::Node * repr); +static void sp_polyline_set (SPObject *object, unsigned int key, const gchar *value); +static Inkscape::XML::Node *sp_polyline_write (SPObject *object, Inkscape::XML::Node *repr, guint flags); + +static gchar * sp_polyline_description (SPItem * item); + +static SPShapeClass *parent_class; + +GType +sp_polyline_get_type (void) +{ + static GType polyline_type = 0; + + if (!polyline_type) { + GTypeInfo polyline_info = { + sizeof (SPPolyLineClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) sp_polyline_class_init, + NULL, /* klass_finalize */ + NULL, /* klass_data */ + sizeof (SPPolyLine), + 16, /* n_preallocs */ + (GInstanceInitFunc) sp_polyline_init, + NULL, /* value_table */ + }; + polyline_type = g_type_register_static (SP_TYPE_SHAPE, "SPPolyLine", &polyline_info, (GTypeFlags)0); + } + return polyline_type; +} + +static void +sp_polyline_class_init (SPPolyLineClass *klass) +{ + GObjectClass * gobject_class; + SPObjectClass * sp_object_class; + SPItemClass * item_class; + + gobject_class = (GObjectClass *) klass; + sp_object_class = (SPObjectClass *) klass; + item_class = (SPItemClass *) klass; + + parent_class = (SPShapeClass *)g_type_class_ref (SP_TYPE_SHAPE); + + sp_object_class->build = sp_polyline_build; + sp_object_class->set = sp_polyline_set; + sp_object_class->write = sp_polyline_write; + + item_class->description = sp_polyline_description; +} + +static void +sp_polyline_init (SPPolyLine * polyline) +{ + /* Nothing here */ +} + +static void +sp_polyline_build (SPObject * object, SPDocument * document, Inkscape::XML::Node * repr) +{ + + if (((SPObjectClass *) parent_class)->build) + ((SPObjectClass *) parent_class)->build (object, document, repr); + + sp_object_read_attr (object, "points"); +} + +static void +sp_polyline_set (SPObject *object, unsigned int key, const gchar *value) +{ + SPPolyLine *polyline; + + polyline = SP_POLYLINE (object); + + switch (key) { + case SP_ATTR_POINTS: { + SPCurve * curve; + const gchar * cptr; + char * eptr; + gboolean hascpt; + + if (!value) break; + curve = sp_curve_new (); + hascpt = FALSE; + + cptr = value; + eptr = NULL; + + while (TRUE) { + gdouble x, y; + + while (*cptr != '\0' && (*cptr == ',' || *cptr == '\x20' || *cptr == '\x9' || *cptr == '\xD' || *cptr == '\xA')) { + cptr++; + } + if (!*cptr) break; + + x = g_ascii_strtod (cptr, &eptr); + if (eptr == cptr) break; + cptr = eptr; + + while (*cptr != '\0' && (*cptr == ',' || *cptr == '\x20' || *cptr == '\x9' || *cptr == '\xD' || *cptr == '\xA')) { + cptr++; + } + if (!*cptr) break; + + y = g_ascii_strtod (cptr, &eptr); + if (eptr == cptr) break; + cptr = eptr; + if (hascpt) { + sp_curve_lineto (curve, x, y); + } else { + sp_curve_moveto (curve, x, y); + hascpt = TRUE; + } + } + + sp_shape_set_curve (SP_SHAPE (polyline), curve, TRUE); + sp_curve_unref (curve); + break; + } + default: + if (((SPObjectClass *) parent_class)->set) + ((SPObjectClass *) parent_class)->set (object, key, value); + break; + } +} + +static Inkscape::XML::Node * +sp_polyline_write (SPObject *object, Inkscape::XML::Node *repr, guint flags) +{ + SPPolyLine *polyline; + + polyline = SP_POLYLINE (object); + + if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { + repr = sp_repr_new ("svg:polyline"); + } + + if (repr != SP_OBJECT_REPR (object)) { + repr->mergeFrom(SP_OBJECT_REPR (object), "id"); + } + + if (((SPObjectClass *) (parent_class))->write) + ((SPObjectClass *) (parent_class))->write (object, repr, flags); + + return repr; +} + +static gchar * +sp_polyline_description(SPItem *item) +{ + return g_strdup(_("Polyline")); +} diff --git a/src/sp-polyline.h b/src/sp-polyline.h new file mode 100644 index 000000000..3ee18d6a5 --- /dev/null +++ b/src/sp-polyline.h @@ -0,0 +1,28 @@ +#ifndef SP_POLYLINE_H +#define SP_POLYLINE_H + +#include "sp-shape.h" + + + +#define SP_TYPE_POLYLINE (sp_polyline_get_type ()) +#define SP_POLYLINE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SP_TYPE_POLYLINE, SPPolyLine)) +#define SP_POLYLINE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SP_TYPE_POLYLINE, SPPolyLineClass)) +#define SP_IS_POLYLINE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_POLYLINE)) +#define SP_IS_POLYLINE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SP_TYPE_POLYLINE)) + +class SPPolyLine; +class SPPolyLineClass; + +struct SPPolyLine : public SPShape { +}; + +struct SPPolyLineClass { + SPShapeClass parent_class; +}; + +GType sp_polyline_get_type (void); + + + +#endif diff --git a/src/sp-radial-gradient-fns.h b/src/sp-radial-gradient-fns.h new file mode 100644 index 000000000..6d38e1605 --- /dev/null +++ b/src/sp-radial-gradient-fns.h @@ -0,0 +1,40 @@ +#ifndef SP_RADIAL_GRADIENT_FNS_H +#define SP_RADIAL_GRADIENT_FNS_H + +/** \file + * Macros and fn definitions related to radial gradients. + */ + +#include + +namespace Inkscape { +namespace XML { +class Node; +} +} + +class SPRadialGradient; + +#define SP_TYPE_RADIALGRADIENT (sp_radialgradient_get_type()) +#define SP_RADIALGRADIENT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), SP_TYPE_RADIALGRADIENT, SPRadialGradient)) +#define SP_RADIALGRADIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), SP_TYPE_RADIALGRADIENT, SPRadialGradientClass)) +#define SP_IS_RADIALGRADIENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), SP_TYPE_RADIALGRADIENT)) +#define SP_IS_RADIALGRADIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), SP_TYPE_RADIALGRADIENT)) + + +GType sp_radialgradient_get_type(); + +void sp_radialgradient_set_position(SPRadialGradient *rg, gdouble cx, gdouble cy, gdouble fx, gdouble fy, gdouble r); + +#endif /* !SP_RADIAL_GRADIENT_FNS_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:encoding=utf-8:textwidth=99 : diff --git a/src/sp-radial-gradient.h b/src/sp-radial-gradient.h new file mode 100644 index 000000000..bec6cbe00 --- /dev/null +++ b/src/sp-radial-gradient.h @@ -0,0 +1,39 @@ +#ifndef SP_RADIAL_GRADIENT_H +#define SP_RADIAL_GRADIENT_H + +/** \file + * SPRadialGradient: SVG implementtion. + */ + +#include +#include "sp-gradient.h" +#include "svg/svg-length.h" +#include "sp-radial-gradient-fns.h" + +/** Radial gradient. */ +struct SPRadialGradient : public SPGradient { + SVGLength cx; + SVGLength cy; + SVGLength r; + SVGLength fx; + SVGLength fy; +}; + +/// The SPRadialGradient vtable. +struct SPRadialGradientClass { + SPGradientClass parent_class; +}; + + +#endif /* !SP_RADIAL_GRADIENT_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:encoding=utf-8:textwidth=99 : diff --git a/src/sp-rect.cpp b/src/sp-rect.cpp new file mode 100644 index 000000000..edcea21a2 --- /dev/null +++ b/src/sp-rect.cpp @@ -0,0 +1,561 @@ +#define __SP_RECT_C__ + +/* + * SVG implementation + * + * Authors: + * Lauris Kaplinski + * bulia byak + * + * Copyright (C) 1999-2002 Lauris Kaplinski + * Copyright (C) 2000-2001 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + + +#include +#include +#include + +#include "attributes.h" +#include "style.h" +#include "sp-rect.h" +#include +#include "xml/repr.h" + +#define noRECT_VERBOSE + +static void sp_rect_class_init(SPRectClass *klass); +static void sp_rect_init(SPRect *rect); + +static void sp_rect_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr); +static void sp_rect_set(SPObject *object, unsigned key, gchar const *value); +static void sp_rect_update(SPObject *object, SPCtx *ctx, guint flags); +static Inkscape::XML::Node *sp_rect_write(SPObject *object, Inkscape::XML::Node *repr, guint flags); + +static gchar *sp_rect_description(SPItem *item); +static NR::Matrix sp_rect_set_transform(SPItem *item, NR::Matrix const &xform); + +static void sp_rect_set_shape(SPShape *shape); + +static SPShapeClass *parent_class; + +GType +sp_rect_get_type(void) +{ + static GType type = 0; + + if (!type) { + GTypeInfo info = { + sizeof(SPRectClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) sp_rect_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof(SPRect), + 16, /* n_preallocs */ + (GInstanceInitFunc) sp_rect_init, + NULL, /* value_table */ + }; + type = g_type_register_static(SP_TYPE_SHAPE, "SPRect", &info, (GTypeFlags)0); + } + return type; +} + +static void +sp_rect_class_init(SPRectClass *klass) +{ + SPObjectClass *sp_object_class = (SPObjectClass *) klass; + SPItemClass *item_class = (SPItemClass *) klass; + SPShapeClass *shape_class = (SPShapeClass *) klass; + + parent_class = (SPShapeClass *)g_type_class_ref(SP_TYPE_SHAPE); + + sp_object_class->build = sp_rect_build; + sp_object_class->write = sp_rect_write; + sp_object_class->set = sp_rect_set; + sp_object_class->update = sp_rect_update; + + item_class->description = sp_rect_description; + item_class->set_transform = sp_rect_set_transform; + + shape_class->set_shape = sp_rect_set_shape; +} + +static void +sp_rect_init(SPRect *rect) +{ + /* Initializing to zero is automatic */ + /* sp_svg_length_unset(&rect->x, SP_SVG_UNIT_NONE, 0.0, 0.0); */ + /* sp_svg_length_unset(&rect->y, SP_SVG_UNIT_NONE, 0.0, 0.0); */ + /* sp_svg_length_unset(&rect->width, SP_SVG_UNIT_NONE, 0.0, 0.0); */ + /* sp_svg_length_unset(&rect->height, SP_SVG_UNIT_NONE, 0.0, 0.0); */ + /* sp_svg_length_unset(&rect->rx, SP_SVG_UNIT_NONE, 0.0, 0.0); */ + /* sp_svg_length_unset(&rect->ry, SP_SVG_UNIT_NONE, 0.0, 0.0); */ +} + +static void +sp_rect_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr) +{ + SPRect *rect = SP_RECT(object); + + if (((SPObjectClass *) parent_class)->build) + ((SPObjectClass *) parent_class)->build(object, document, repr); + + sp_object_read_attr(object, "x"); + sp_object_read_attr(object, "y"); + sp_object_read_attr(object, "width"); + sp_object_read_attr(object, "height"); + sp_object_read_attr(object, "rx"); + sp_object_read_attr(object, "ry"); + + Inkscape::Version const version = sp_object_get_sodipodi_version(object); + + if ( version.major == 0 && version.minor == 29 ) { + if (rect->rx._set && rect->ry._set) { + /* 0.29 treated 0.0 radius as missing value */ + if ((rect->rx.value != 0.0) && (rect->ry.value == 0.0)) { + repr->setAttribute("ry", NULL); + sp_object_read_attr(object, "ry"); + } else if ((rect->ry.value != 0.0) && (rect->rx.value == 0.0)) { + repr->setAttribute("rx", NULL); + sp_object_read_attr(object, "rx"); + } + } + } +} + +static void +sp_rect_set(SPObject *object, unsigned key, gchar const *value) +{ + SPRect *rect = SP_RECT(object); + + /* fixme: We need real error processing some time */ + + switch (key) { + case SP_ATTR_X: + rect->x.readOrUnset(value); + object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_Y: + rect->y.readOrUnset(value); + object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_WIDTH: + if (!rect->width.read(value) || rect->width.value < 0.0) { + rect->width.unset(); + } + object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_HEIGHT: + if (!rect->height.read(value) || rect->height.value < 0.0) { + rect->height.unset(); + } + object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_RX: + if (!rect->rx.read(value) || rect->rx.value < 0.0) { + rect->rx.unset(); + } + object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_RY: + if (!rect->ry.read(value) || rect->ry.value < 0.0) { + rect->ry.unset(); + } + object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + break; + default: + if (((SPObjectClass *) parent_class)->set) + ((SPObjectClass *) parent_class)->set(object, key, value); + break; + } +} + +static void +sp_rect_update(SPObject *object, SPCtx *ctx, guint flags) +{ + if (flags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG)) { + SPRect *rect = (SPRect *) object; + SPStyle *style = object->style; + SPItemCtx const *ictx = (SPItemCtx const *) ctx; + double const d = NR::expansion(ictx->i2vp); + double const w = (ictx->vp.x1 - ictx->vp.x0) / d; + double const h = (ictx->vp.y1 - ictx->vp.y0) / d; + double const em = style->font_size.computed; + double const ex = 0.5 * em; // fixme: get x height from pango or libnrtype. + rect->x.update(em, ex, w); + rect->y.update(em, ex, h); + rect->width.update(em, ex, w); + rect->height.update(em, ex, h); + rect->rx.update(em, ex, w); + rect->ry.update(em, ex, h); + sp_shape_set_shape((SPShape *) object); + flags &= ~SP_OBJECT_USER_MODIFIED_FLAG_B; // since we change the description, it's not a "just translation" anymore + } + + if (((SPObjectClass *) parent_class)->update) + ((SPObjectClass *) parent_class)->update(object, ctx, flags); +} + +static Inkscape::XML::Node * +sp_rect_write(SPObject *object, Inkscape::XML::Node *repr, guint flags) +{ + SPRect *rect = SP_RECT(object); + + if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { + repr = sp_repr_new("svg:rect"); + } + + sp_repr_set_svg_double(repr, "width", rect->width.computed); + sp_repr_set_svg_double(repr, "height", rect->height.computed); + if (rect->rx._set) sp_repr_set_svg_double(repr, "rx", rect->rx.computed); + if (rect->ry._set) sp_repr_set_svg_double(repr, "ry", rect->ry.computed); + sp_repr_set_svg_double(repr, "x", rect->x.computed); + sp_repr_set_svg_double(repr, "y", rect->y.computed); + + if (((SPObjectClass *) parent_class)->write) + ((SPObjectClass *) parent_class)->write(object, repr, flags); + + return repr; +} + +static gchar * +sp_rect_description(SPItem *item) +{ + g_return_val_if_fail(SP_IS_RECT(item), NULL); + + return g_strdup(_("Rectangle")); +} + +#define C1 0.554 + +static void +sp_rect_set_shape(SPShape *shape) +{ + SPRect *rect = (SPRect *) shape; + + if ((rect->height.computed < 1e-18) || (rect->width.computed < 1e-18)) return; + + SPCurve *c = sp_curve_new(); + + double const x = rect->x.computed; + double const y = rect->y.computed; + double const w = rect->width.computed; + double const h = rect->height.computed; + double const w2 = w / 2; + double const h2 = h / 2; + double const rx = std::min(( rect->rx._set + ? rect->rx.computed + : ( rect->ry._set + ? rect->ry.computed + : 0.0 ) ), + .5 * rect->width.computed); + double const ry = std::min(( rect->ry._set + ? rect->ry.computed + : ( rect->rx._set + ? rect->rx.computed + : 0.0 ) ), + .5 * rect->height.computed); + /* TODO: Handle negative rx or ry as per + * http://www.w3.org/TR/SVG11/shapes.html#RectElementRXAttribute once Inkscape has proper error + * handling (see http://www.w3.org/TR/SVG11/implnote.html#ErrorProcessing). + */ + + /* We don't use proper circular/elliptical arcs, but bezier curves can approximate a 90-degree + * arc fairly well. + */ + if ((rx > 1e-18) && (ry > 1e-18)) { + sp_curve_moveto(c, x + rx, y); + if (rx < w2) sp_curve_lineto(c, x + w - rx, y); + sp_curve_curveto(c, x + w - rx * (1 - C1), y, x + w, y + ry * (1 - C1), x + w, y + ry); + if (ry < h2) sp_curve_lineto(c, x + w, y + h - ry); + sp_curve_curveto(c, x + w, y + h - ry * (1 - C1), x + w - rx * (1 - C1), y + h, x + w - rx, y + h); + if (rx < w2) sp_curve_lineto(c, x + rx, y + h); + sp_curve_curveto(c, x + rx * (1 - C1), y + h, x, y + h - ry * (1 - C1), x, y + h - ry); + if (ry < h2) sp_curve_lineto(c, x, y + ry); + sp_curve_curveto(c, x, y + ry * (1 - C1), x + rx * (1 - C1), y, x + rx, y); + } else { + sp_curve_moveto(c, x + 0.0, y + 0.0); + sp_curve_lineto(c, x + w, y + 0.0); + sp_curve_lineto(c, x + w, y + h); + sp_curve_lineto(c, x + 0.0, y + h); + sp_curve_lineto(c, x + 0.0, y + 0.0); + } + + sp_curve_closepath_current(c); + sp_shape_set_curve_insync(SP_SHAPE(rect), c, TRUE); + sp_curve_unref(c); +} + +/* fixme: Think (Lauris) */ + +void +sp_rect_position_set(SPRect *rect, gdouble x, gdouble y, gdouble width, gdouble height) +{ + g_return_if_fail(rect != NULL); + g_return_if_fail(SP_IS_RECT(rect)); + + rect->x.computed = x; + rect->y.computed = y; + rect->width.computed = width; + rect->height.computed = height; + + SP_OBJECT(rect)->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); +} + +void +sp_rect_set_rx(SPRect *rect, gboolean set, gdouble value) +{ + g_return_if_fail(rect != NULL); + g_return_if_fail(SP_IS_RECT(rect)); + + rect->rx._set = set; + if (set) rect->rx.computed = value; + + SP_OBJECT(rect)->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); +} + +void +sp_rect_set_ry(SPRect *rect, gboolean set, gdouble value) +{ + g_return_if_fail(rect != NULL); + g_return_if_fail(SP_IS_RECT(rect)); + + rect->ry._set = set; + if (set) rect->ry.computed = value; + + SP_OBJECT(rect)->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); +} + +/* + * Initially we'll do: + * Transform x, y, set x, y, clear translation + */ + +/* fixme: Use preferred units somehow (Lauris) */ +/* fixme: Alternately preserve whatever units there are (lauris) */ + +static NR::Matrix +sp_rect_set_transform(SPItem *item, NR::Matrix const &xform) +{ + SPRect *rect = SP_RECT(item); + + /* Calculate rect start in parent coords. */ + NR::Point pos( NR::Point(rect->x.computed, rect->y.computed) * xform ); + + /* This function takes care of translation and scaling, we return whatever parts we can't + handle. */ + NR::Matrix ret(NR::transform(xform)); + gdouble const sw = hypot(ret[0], ret[1]); + gdouble const sh = hypot(ret[2], ret[3]); + if (sw > 1e-9) { + ret[0] /= sw; + ret[1] /= sw; + } else { + ret[0] = 1.0; + ret[1] = 0.0; + } + if (sh > 1e-9) { + ret[2] /= sh; + ret[3] /= sh; + } else { + ret[2] = 0.0; + ret[3] = 1.0; + } + + /* fixme: Would be nice to preserve units here */ + rect->width = rect->width.computed * sw; + rect->height = rect->height.computed * sh; + if (rect->rx._set) { + rect->rx = rect->rx.computed * sw; + } + if (rect->ry._set) { + rect->ry = rect->ry.computed * sh; + } + + /* Find start in item coords */ + pos = pos * ret.inverse(); + rect->x = pos[NR::X]; + rect->y = pos[NR::Y]; + + sp_rect_set_shape(rect); + + // Adjust stroke width + sp_item_adjust_stroke(item, sqrt(fabs(sw * sh))); + + // Adjust pattern fill + sp_item_adjust_pattern(item, xform / ret); + + // Adjust gradient fill + sp_item_adjust_gradient(item, xform / ret); + + item->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG); + + return ret; +} + + +/** +Returns the ratio in which the vector from p0 to p1 is stretched by transform + */ +static gdouble +vector_stretch(NR::Point p0, NR::Point p1, NR::Matrix xform) +{ + if (p0 == p1) + return 0; + return (NR::distance(p0 * xform, p1 * xform) / NR::distance(p0, p1)); +} + +void +sp_rect_set_visible_rx(SPRect *rect, gdouble rx) +{ + if (rx == 0) { + rect->rx.computed = 0; + rect->rx._set = false; + } else { + rect->rx.computed = rx / vector_stretch( + NR::Point(rect->x.computed + 1, rect->y.computed), + NR::Point(rect->x.computed, rect->y.computed), + SP_ITEM(rect)->transform); + rect->rx._set = true; + } + SP_OBJECT(rect)->updateRepr(); +} + +void +sp_rect_set_visible_ry(SPRect *rect, gdouble ry) +{ + if (ry == 0) { + rect->ry.computed = 0; + rect->ry._set = false; + } else { + rect->ry.computed = ry / vector_stretch( + NR::Point(rect->x.computed, rect->y.computed + 1), + NR::Point(rect->x.computed, rect->y.computed), + SP_ITEM(rect)->transform); + rect->ry._set = true; + } + SP_OBJECT(rect)->updateRepr(); +} + +gdouble +sp_rect_get_visible_rx(SPRect *rect) +{ + if (!rect->rx._set) + return 0; + return rect->rx.computed * vector_stretch( + NR::Point(rect->x.computed + 1, rect->y.computed), + NR::Point(rect->x.computed, rect->y.computed), + SP_ITEM(rect)->transform); +} + +gdouble +sp_rect_get_visible_ry(SPRect *rect) +{ + if (!rect->ry._set) + return 0; + return rect->ry.computed * vector_stretch( + NR::Point(rect->x.computed, rect->y.computed + 1), + NR::Point(rect->x.computed, rect->y.computed), + SP_ITEM(rect)->transform); +} + +void +sp_rect_compensate_rxry(SPRect *rect, NR::Matrix xform) +{ + if (rect->rx.computed == 0 && rect->ry.computed == 0) + return; // nothing to compensate + + // test unit vectors to find out compensation: + NR::Point c(rect->x.computed, rect->y.computed); + NR::Point cx = c + NR::Point(1, 0); + NR::Point cy = c + NR::Point(0, 1); + + // apply previous transform if any + c *= SP_ITEM(rect)->transform; + cx *= SP_ITEM(rect)->transform; + cy *= SP_ITEM(rect)->transform; + + // find out stretches that we need to compensate + gdouble eX = vector_stretch(cx, c, xform); + gdouble eY = vector_stretch(cy, c, xform); + + // If only one of the radii is set, set both radii so they have the same visible length + // This is needed because if we just set them the same length in SVG, they might end up unequal because of transform + if ((rect->rx._set && !rect->ry._set) || (rect->ry._set && !rect->rx._set)) { + gdouble r = MAX(rect->rx.computed, rect->ry.computed); + rect->rx.computed = r / eX; + rect->ry.computed = r / eY; + } else { + rect->rx.computed = rect->rx.computed / eX; + rect->ry.computed = rect->ry.computed / eY; + } + + // Note that a radius may end up larger than half-side if the rect is scaled down; + // that's ok because this preserves the intended radii in case the rect is enlarged again, + // and set_shape will take care of trimming too large radii when generating d= + + rect->rx._set = rect->ry._set = true; +} + +void +sp_rect_set_visible_width(SPRect *rect, gdouble width) +{ + rect->width.computed = width / vector_stretch( + NR::Point(rect->x.computed + 1, rect->y.computed), + NR::Point(rect->x.computed, rect->y.computed), + SP_ITEM(rect)->transform); + rect->width._set = true; + SP_OBJECT(rect)->updateRepr(); +} + +void +sp_rect_set_visible_height(SPRect *rect, gdouble height) +{ + rect->height.computed = height / vector_stretch( + NR::Point(rect->x.computed, rect->y.computed + 1), + NR::Point(rect->x.computed, rect->y.computed), + SP_ITEM(rect)->transform); + rect->height._set = true; + SP_OBJECT(rect)->updateRepr(); +} + +gdouble +sp_rect_get_visible_width(SPRect *rect) +{ + if (!rect->width._set) + return 0; + return rect->width.computed * vector_stretch( + NR::Point(rect->x.computed + 1, rect->y.computed), + NR::Point(rect->x.computed, rect->y.computed), + SP_ITEM(rect)->transform); +} + +gdouble +sp_rect_get_visible_height(SPRect *rect) +{ + if (!rect->height._set) + return 0; + return rect->height.computed * vector_stretch( + NR::Point(rect->x.computed, rect->y.computed + 1), + NR::Point(rect->x.computed, rect->y.computed), + SP_ITEM(rect)->transform); +} + +/* + 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 : diff --git a/src/sp-rect.h b/src/sp-rect.h new file mode 100644 index 000000000..4cf3b24ba --- /dev/null +++ b/src/sp-rect.h @@ -0,0 +1,65 @@ +#ifndef __SP_RECT_H__ +#define __SP_RECT_H__ + +/* + * SVG implementation + * + * Authors: + * Lauris Kaplinski + * + * Copyright (C) 1999-2002 Lauris Kaplinski + * Copyright (C) 2000-2001 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "svg/svg-length.h" +#include "sp-shape.h" + + + +#define SP_TYPE_RECT (sp_rect_get_type ()) +#define SP_RECT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SP_TYPE_RECT, SPRect)) +#define SP_RECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SP_TYPE_RECT, SPRectClass)) +#define SP_IS_RECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_RECT)) +#define SP_IS_RECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SP_TYPE_RECT)) + +class SPRect; +class SPRectClass; + +struct SPRect : public SPShape { + SVGLength x; + SVGLength y; + SVGLength width; + SVGLength height; + SVGLength rx; + SVGLength ry; +}; + +struct SPRectClass { + SPShapeClass parent_class; +}; + + +/* Standard GType function */ +GType sp_rect_get_type (void); + +void sp_rect_position_set (SPRect * rect, gdouble x, gdouble y, gdouble width, gdouble height); + +/* If SET if FALSE, VALUE is just ignored */ +void sp_rect_set_rx(SPRect * rect, gboolean set, gdouble value); +void sp_rect_set_ry(SPRect * rect, gboolean set, gdouble value); + +void sp_rect_set_visible_rx (SPRect *rect, gdouble rx); +void sp_rect_set_visible_ry (SPRect *rect, gdouble ry); +gdouble sp_rect_get_visible_rx (SPRect *rect); +gdouble sp_rect_get_visible_ry (SPRect *rect); + +void sp_rect_set_visible_width (SPRect *rect, gdouble rx); +void sp_rect_set_visible_height (SPRect *rect, gdouble ry); +gdouble sp_rect_get_visible_width (SPRect *rect); +gdouble sp_rect_get_visible_height (SPRect *rect); + +void sp_rect_compensate_rxry (SPRect *rect, NR::Matrix xform); + +#endif diff --git a/src/sp-root.cpp b/src/sp-root.cpp new file mode 100644 index 000000000..1bb77ccc7 --- /dev/null +++ b/src/sp-root.cpp @@ -0,0 +1,678 @@ +#define __SP_ROOT_C__ + +/** \file + * SVG \ implementation. + */ +/* + * Authors: + * Lauris Kaplinski + * + * Copyright (C) 1999-2002 Lauris Kaplinski + * Copyright (C) 2000-2001 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "config.h" + +#include "svg/svg.h" +#include "display/nr-arena-group.h" +#include "attributes.h" +#include "print.h" +#include "document.h" +#include "sp-defs.h" +#include "sp-root.h" +#include +#include +#include +#include +#include +#include +#include "svg/stringstream.h" +#include "inkscape_version.h" + +class SPDesktop; + +static void sp_root_class_init(SPRootClass *klass); +static void sp_root_init(SPRoot *root); + +static void sp_root_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr); +static void sp_root_release(SPObject *object); +static void sp_root_set(SPObject *object, unsigned int key, gchar const *value); +static void sp_root_child_added(SPObject *object, Inkscape::XML::Node *child, Inkscape::XML::Node *ref); +static void sp_root_remove_child(SPObject *object, Inkscape::XML::Node *child); +static void sp_root_update(SPObject *object, SPCtx *ctx, guint flags); +static void sp_root_modified(SPObject *object, guint flags); +static Inkscape::XML::Node *sp_root_write(SPObject *object, Inkscape::XML::Node *repr, guint flags); + +static NRArenaItem *sp_root_show(SPItem *item, NRArena *arena, unsigned int key, unsigned int flags); +static void sp_root_bbox(SPItem const *item, NRRect *bbox, NR::Matrix const &transform, unsigned const flags); +static void sp_root_print(SPItem *item, SPPrintContext *ctx); + +static SPGroupClass *parent_class; + +/** + * Returns the type info of sp_root, including its class sizes and initialization routines. + */ +GType +sp_root_get_type(void) +{ + static GType type = 0; + if (!type) { + GTypeInfo info = { + sizeof(SPRootClass), + NULL, NULL, + (GClassInitFunc) sp_root_class_init, + NULL, NULL, + sizeof(SPRoot), + 16, + (GInstanceInitFunc) sp_root_init, + NULL, /* value_table */ + }; + type = g_type_register_static(SP_TYPE_GROUP, "SPRoot", &info, (GTypeFlags)0); + } + return type; +} + +/** + * Initializes an SPRootClass object by setting its class and parent class objects, and registering + * function pointers (i.e.\ gobject-style virtual functions) for various operations. + */ +static void +sp_root_class_init(SPRootClass *klass) +{ + GObjectClass *object_class; + SPObjectClass *sp_object_class; + SPItemClass *sp_item_class; + + object_class = G_OBJECT_CLASS(klass); + sp_object_class = (SPObjectClass *) klass; + sp_item_class = (SPItemClass *) klass; + + parent_class = (SPGroupClass *)g_type_class_ref(SP_TYPE_GROUP); + + sp_object_class->build = sp_root_build; + sp_object_class->release = sp_root_release; + sp_object_class->set = sp_root_set; + sp_object_class->child_added = sp_root_child_added; + sp_object_class->remove_child = sp_root_remove_child; + sp_object_class->update = sp_root_update; + sp_object_class->modified = sp_root_modified; + sp_object_class->write = sp_root_write; + + sp_item_class->show = sp_root_show; + sp_item_class->bbox = sp_root_bbox; + sp_item_class->print = sp_root_print; +} + +/** + * Initializes an SPRoot object by setting its default parameter values. + */ +static void +sp_root_init(SPRoot *root) +{ + static Inkscape::Version const zero_version(0, 0); + + sp_version_from_string(SVG_VERSION, &root->original.svg); + root->version.svg = root->original.svg; + root->version.inkscape = root->original.inkscape = + root->version.sodipodi = root->original.sodipodi = zero_version; + + root->x.unset(); + root->y.unset(); + root->width.unset(SVGLength::PERCENT, 1.0, 1.0); + root->height.unset(SVGLength::PERCENT, 1.0, 1.0); + + /* nr_matrix_set_identity(&root->viewbox); */ + root->viewBox_set = FALSE; + + root->c2p.set_identity(); + + root->defs = NULL; +} + +/** + * Fills in the data for an SPObject from its Inkscape::XML::Node object. + * It fills in data such as version, x, y, width, height, etc. + * It then calls the object's parent class object's build function. + */ +static void +sp_root_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr) +{ + SPGroup *group = (SPGroup *) object; + SPRoot *root = (SPRoot *) object; + + if (repr->attribute("sodipodi:docname") || repr->attribute("SP-DOCNAME")) { + /* so we have a nonzero initial version */ + root->original.sodipodi.major = 0; + root->original.sodipodi.minor = 1; + } + sp_object_read_attr(object, "version"); + sp_object_read_attr(object, "sodipodi:version"); + sp_object_read_attr(object, "inkscape:version"); + /* It is important to parse these here, so objects will have viewport build-time */ + sp_object_read_attr(object, "x"); + sp_object_read_attr(object, "y"); + sp_object_read_attr(object, "width"); + sp_object_read_attr(object, "height"); + sp_object_read_attr(object, "viewBox"); + sp_object_read_attr(object, "preserveAspectRatio"); + + if (((SPObjectClass *) parent_class)->build) + (* ((SPObjectClass *) parent_class)->build) (object, document, repr); + + /* Search for first node */ + for (SPObject *o = sp_object_first_child(SP_OBJECT(group)) ; o != NULL; o = SP_OBJECT_NEXT(o) ) { + if (SP_IS_DEFS(o)) { + root->defs = SP_DEFS(o); + break; + } + } + + // clear transform, if any was read in - SVG does not allow transform= on + SP_ITEM(object)->transform = NR::identity(); +} + +/** + * This is a destructor routine for SPRoot objects. It de-references any \ items and calls + * the parent class destructor. + */ +static void +sp_root_release(SPObject *object) +{ + SPRoot *root = (SPRoot *) object; + root->defs = NULL; + + if (((SPObjectClass *) parent_class)->release) + ((SPObjectClass *) parent_class)->release(object); +} + +/** + * Sets the attribute given by key for SPRoot objects to the value specified by value. + */ +static void +sp_root_set(SPObject *object, unsigned int key, gchar const *value) +{ + SPRoot *root = SP_ROOT(object); + + switch (key) { + case SP_ATTR_VERSION: + if (!sp_version_from_string(value, &root->version.svg)) { + root->version.svg = root->original.svg; + } + break; + case SP_ATTR_SODIPODI_VERSION: + if (!sp_version_from_string(value, &root->version.sodipodi)) { + root->version.sodipodi = root->original.sodipodi; + } + case SP_ATTR_INKSCAPE_VERSION: + if (!sp_version_from_string(value, &root->version.inkscape)) { + root->version.inkscape = root->original.inkscape; + } + break; + case SP_ATTR_X: + if (!root->x.readAbsolute(value)) { + /* fixme: em, ex, % are probably valid, but require special treatment (Lauris) */ + root->x.unset(); + } + /* fixme: I am almost sure these do not require viewport flag (Lauris) */ + object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG); + break; + case SP_ATTR_Y: + if (!root->y.readAbsolute(value)) { + /* fixme: em, ex, % are probably valid, but require special treatment (Lauris) */ + root->y.unset(); + } + /* fixme: I am almost sure these do not require viewport flag (Lauris) */ + object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG); + break; + case SP_ATTR_WIDTH: + if (!root->width.readAbsolute(value) || !(root->width.computed > 0.0)) { + /* fixme: em, ex, % are probably valid, but require special treatment (Lauris) */ + root->width.unset(SVGLength::PERCENT, 1.0, 1.0); + } + object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG); + break; + case SP_ATTR_HEIGHT: + if (!root->height.readAbsolute(value) || !(root->height.computed > 0.0)) { + /* fixme: em, ex, % are probably valid, but require special treatment (Lauris) */ + root->height.unset(SVGLength::PERCENT, 1.0, 1.0); + } + object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG); + break; + case SP_ATTR_VIEWBOX: + if (value) { + double x, y, width, height; + char *eptr; + /* fixme: We have to take original item affine into account */ + /* fixme: Think (Lauris) */ + eptr = (gchar *) value; + x = g_ascii_strtod(eptr, &eptr); + while (*eptr && ((*eptr == ',') || (*eptr == ' '))) eptr++; + y = g_ascii_strtod(eptr, &eptr); + while (*eptr && ((*eptr == ',') || (*eptr == ' '))) eptr++; + width = g_ascii_strtod(eptr, &eptr); + while (*eptr && ((*eptr == ',') || (*eptr == ' '))) eptr++; + height = g_ascii_strtod(eptr, &eptr); + while (*eptr && ((*eptr == ',') || (*eptr == ' '))) eptr++; + if ((width > 0) && (height > 0)) { + /* Set viewbox */ + root->viewBox.x0 = x; + root->viewBox.y0 = y; + root->viewBox.x1 = x + width; + root->viewBox.y1 = y + height; + root->viewBox_set = TRUE; + } else { + root->viewBox_set = FALSE; + } + } else { + root->viewBox_set = FALSE; + } + object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG); + break; + case SP_ATTR_PRESERVEASPECTRATIO: + /* Do setup before, so we can use break to escape */ + root->aspect_set = FALSE; + root->aspect_align = SP_ASPECT_XMID_YMID; + root->aspect_clip = SP_ASPECT_MEET; + object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG); + if (value) { + int len; + gchar c[256]; + gchar const *p, *e; + unsigned int align, clip; + p = value; + while (*p && *p == 32) p += 1; + if (!*p) break; + e = p; + while (*e && *e != 32) e += 1; + len = e - p; + if (len > 8) break; + memcpy(c, value, len); + c[len] = 0; + /* Now the actual part */ + if (!strcmp(c, "none")) { + align = SP_ASPECT_NONE; + } else if (!strcmp(c, "xMinYMin")) { + align = SP_ASPECT_XMIN_YMIN; + } else if (!strcmp(c, "xMidYMin")) { + align = SP_ASPECT_XMID_YMIN; + } else if (!strcmp(c, "xMaxYMin")) { + align = SP_ASPECT_XMAX_YMIN; + } else if (!strcmp(c, "xMinYMid")) { + align = SP_ASPECT_XMIN_YMID; + } else if (!strcmp(c, "xMidYMid")) { + align = SP_ASPECT_XMID_YMID; + } else if (!strcmp(c, "xMaxYMin")) { + align = SP_ASPECT_XMAX_YMID; + } else if (!strcmp(c, "xMinYMax")) { + align = SP_ASPECT_XMIN_YMAX; + } else if (!strcmp(c, "xMidYMax")) { + align = SP_ASPECT_XMID_YMAX; + } else if (!strcmp(c, "xMaxYMax")) { + align = SP_ASPECT_XMAX_YMAX; + } else { + break; + } + clip = SP_ASPECT_MEET; + while (*e && *e == 32) e += 1; + if (e) { + if (!strcmp(e, "meet")) { + clip = SP_ASPECT_MEET; + } else if (!strcmp(e, "slice")) { + clip = SP_ASPECT_SLICE; + } else { + break; + } + } + root->aspect_set = TRUE; + root->aspect_align = align; + root->aspect_clip = clip; + } + break; + default: + /* Pass the set event to the parent */ + if (((SPObjectClass *) parent_class)->set) { + ((SPObjectClass *) parent_class)->set(object, key, value); + } + break; + } +} + +/** + * This routine is for adding a child SVG object to an SPRoot object. + * The SPRoot object is taken to be an SPGroup. + */ +static void +sp_root_child_added(SPObject *object, Inkscape::XML::Node *child, Inkscape::XML::Node *ref) +{ + SPRoot *root = (SPRoot *) object; + SPGroup *group = (SPGroup *) object; + + if (((SPObjectClass *) (parent_class))->child_added) + (* ((SPObjectClass *) (parent_class))->child_added)(object, child, ref); + + SPObject *co = object->document->getObjectByRepr(child); + g_assert(co != NULL); + + if (SP_IS_DEFS(co)) { + SPObject *c; + /* We search for first node - it is not beautiful, but works */ + for (c = sp_object_first_child(SP_OBJECT(group)) ; c != NULL; c = SP_OBJECT_NEXT(c) ) { + if (SP_IS_DEFS(c)) { + root->defs = SP_DEFS(c); + break; + } + } + } +} + +/** + * Removes the given child from this SPRoot object. + */ +static void sp_root_remove_child(SPObject *object, Inkscape::XML::Node *child) +{ + SPRoot *root = (SPRoot *) object; + + if ( root->defs && SP_OBJECT_REPR(root->defs) == child ) { + SPObject *iter; + /* We search for first remaining node - it is not beautiful, but works */ + for ( iter = sp_object_first_child(object) ; iter ; iter = SP_OBJECT_NEXT(iter) ) { + if ( SP_IS_DEFS(iter) && (SPDefs *)iter != root->defs ) { + root->defs = (SPDefs *)iter; + break; + } + } + if (!iter) { + /* we should probably create a new here? */ + g_critical("Last removed"); + root->defs = NULL; + } + } + + if (((SPObjectClass *) (parent_class))->remove_child) + (* ((SPObjectClass *) (parent_class))->remove_child)(object, child); +} + +/** + * This callback routine updates the SPRoot object when its attributes have been changed. + */ +static void +sp_root_update(SPObject *object, SPCtx *ctx, guint flags) +{ + SPItemView *v; + + SPItem *item = SP_ITEM(object); + SPRoot *root = SP_ROOT(object); + SPItemCtx *ictx = (SPItemCtx *) ctx; + + /* fixme: This will be invoked too often (Lauris) */ + /* fixme: We should calculate only if parent viewport has changed (Lauris) */ + /* If position is specified as percentage, calculate actual values */ + if (root->x.unit == SVGLength::PERCENT) { + root->x.computed = root->x.value * (ictx->vp.x1 - ictx->vp.x0); + } + if (root->y.unit == SVGLength::PERCENT) { + root->y.computed = root->y.value * (ictx->vp.y1 - ictx->vp.y0); + } + if (root->width.unit == SVGLength::PERCENT) { + root->width.computed = root->width.value * (ictx->vp.x1 - ictx->vp.x0); + } + if (root->height.unit == SVGLength::PERCENT) { + root->height.computed = root->height.value * (ictx->vp.y1 - ictx->vp.y0); + } + + /* Create copy of item context */ + SPItemCtx rctx = *ictx; + + /* Calculate child to parent transformation */ + root->c2p.set_identity(); + + if (object->parent) { + /* + * fixme: I am not sure whether setting x and y does or does not + * fixme: translate the content of inner SVG. + * fixme: Still applying translation and setting viewport to width and + * fixme: height seems natural, as this makes the inner svg element + * fixme: self-contained. The spec is vague here. + */ + root->c2p = NR::Matrix(NR::translate(root->x.computed, + root->y.computed)); + } + + if (root->viewBox_set) { + double x, y, width, height; + /* Determine actual viewbox in viewport coordinates */ + if (root->aspect_align == SP_ASPECT_NONE) { + x = 0.0; + y = 0.0; + width = root->width.computed; + height = root->height.computed; + } else { + double scalex, scaley, scale; + /* Things are getting interesting */ + scalex = root->width.computed / (root->viewBox.x1 - root->viewBox.x0); + scaley = root->height.computed / (root->viewBox.y1 - root->viewBox.y0); + scale = (root->aspect_clip == SP_ASPECT_MEET) ? MIN(scalex, scaley) : MAX(scalex, scaley); + width = (root->viewBox.x1 - root->viewBox.x0) * scale; + height = (root->viewBox.y1 - root->viewBox.y0) * scale; + /* Now place viewbox to requested position */ + /* todo: Use an array lookup to find the 0.0/0.5/1.0 coefficients, + as is done for dialogs/align.cpp. */ + switch (root->aspect_align) { + case SP_ASPECT_XMIN_YMIN: + x = 0.0; + y = 0.0; + break; + case SP_ASPECT_XMID_YMIN: + x = 0.5 * (root->width.computed - width); + y = 0.0; + break; + case SP_ASPECT_XMAX_YMIN: + x = 1.0 * (root->width.computed - width); + y = 0.0; + break; + case SP_ASPECT_XMIN_YMID: + x = 0.0; + y = 0.5 * (root->height.computed - height); + break; + case SP_ASPECT_XMID_YMID: + x = 0.5 * (root->width.computed - width); + y = 0.5 * (root->height.computed - height); + break; + case SP_ASPECT_XMAX_YMID: + x = 1.0 * (root->width.computed - width); + y = 0.5 * (root->height.computed - height); + break; + case SP_ASPECT_XMIN_YMAX: + x = 0.0; + y = 1.0 * (root->height.computed - height); + break; + case SP_ASPECT_XMID_YMAX: + x = 0.5 * (root->width.computed - width); + y = 1.0 * (root->height.computed - height); + break; + case SP_ASPECT_XMAX_YMAX: + x = 1.0 * (root->width.computed - width); + y = 1.0 * (root->height.computed - height); + break; + default: + x = 0.0; + y = 0.0; + break; + } + } + + /* Compose additional transformation from scale and position */ + NR::Point const viewBox_min(root->viewBox.x0, + root->viewBox.y0); + NR::Point const viewBox_max(root->viewBox.x1, + root->viewBox.y1); + NR::scale const viewBox_length( viewBox_max - viewBox_min ); + NR::scale const new_length(width, height); + + /* Append viewbox transformation */ + /* TODO: The below looks suspicious to me (pjrm): I wonder whether the RHS + expression should have c2p at the beginning rather than at the end. Test it. */ + root->c2p = NR::translate(-viewBox_min) * ( new_length / viewBox_length ) * NR::translate(x, y) * root->c2p; + } + + rctx.i2doc = root->c2p * rctx.i2doc; + + /* Initialize child viewport */ + if (root->viewBox_set) { + rctx.vp.x0 = root->viewBox.x0; + rctx.vp.y0 = root->viewBox.y0; + rctx.vp.x1 = root->viewBox.x1; + rctx.vp.y1 = root->viewBox.y1; + } else { + /* fixme: I wonder whether this logic is correct (Lauris) */ + if (object->parent) { + rctx.vp.x0 = root->x.computed; + rctx.vp.y0 = root->y.computed; + } else { + rctx.vp.x0 = 0.0; + rctx.vp.y0 = 0.0; + } + rctx.vp.x1 = root->width.computed; + rctx.vp.y1 = root->height.computed; + } + + rctx.i2vp = NR::identity(); + + /* And invoke parent method */ + if (((SPObjectClass *) (parent_class))->update) + ((SPObjectClass *) (parent_class))->update(object, (SPCtx *) &rctx, flags); + + /* As last step set additional transform of arena group */ + for (v = item->display; v != NULL; v = v->next) { + nr_arena_group_set_child_transform(NR_ARENA_GROUP(v->arenaitem), root->c2p); + } +} + +/** + * Calls the modified routine of the SPRoot object's parent class. + * Also, if the viewport has been modified, it sets the document size to the new + * height and width. + */ +static void +sp_root_modified(SPObject *object, guint flags) +{ + SPRoot *root = SP_ROOT(object); + + if (((SPObjectClass *) (parent_class))->modified) + (* ((SPObjectClass *) (parent_class))->modified)(object, flags); + + /* fixme: (Lauris) */ + if (!object->parent && (flags & SP_OBJECT_VIEWPORT_MODIFIED_FLAG)) { + sp_document_resized_signal_emit (SP_OBJECT_DOCUMENT(root), root->width.computed, root->height.computed); + } +} + +/** + * Writes the object into the repr object, then calls the parent's write routine. + */ +static Inkscape::XML::Node * +sp_root_write(SPObject *object, Inkscape::XML::Node *repr, guint flags) +{ + SPRoot *root = SP_ROOT(object); + + if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { + repr = sp_repr_new("svg:svg"); + } + + if (flags & SP_OBJECT_WRITE_EXT) { + repr->setAttribute("sodipodi:version", SODIPODI_VERSION); + repr->setAttribute("inkscape:version", INKSCAPE_VERSION); + } + + repr->setAttribute("version", SVG_VERSION); + + if (fabs(root->x.computed) > 1e-9) + sp_repr_set_svg_double(repr, "x", root->x.computed); + if (fabs(root->y.computed) > 1e-9) + sp_repr_set_svg_double(repr, "y", root->y.computed); + + /* Unlike all other SPObject, here we want to preserve absolute units too (and only here, + * according to the recommendation in http://www.w3.org/TR/SVG11/coords.html#Units). + */ + repr->setAttribute("width", sp_svg_length_write_with_units(root->width).c_str()); + repr->setAttribute("height", sp_svg_length_write_with_units(root->height).c_str()); + + if (root->viewBox_set) { + Inkscape::SVGOStringStream os; + os << root->viewBox.x0 << " " << root->viewBox.y0 << " " << root->viewBox.x1 - root->viewBox.x0 << " " << root->viewBox.y1 - root->viewBox.y0; + repr->setAttribute("viewBox", os.str().c_str()); + } + + if (((SPObjectClass *) (parent_class))->write) + ((SPObjectClass *) (parent_class))->write(object, repr, flags); + + return repr; +} + +/** + * Displays the SPRoot item on the NRArena. + */ +static NRArenaItem * +sp_root_show(SPItem *item, NRArena *arena, unsigned int key, unsigned int flags) +{ + SPRoot *root = SP_ROOT(item); + + NRArenaItem *ai; + if (((SPItemClass *) (parent_class))->show) { + ai = ((SPItemClass *) (parent_class))->show(item, arena, key, flags); + if (ai) { + nr_arena_group_set_child_transform(NR_ARENA_GROUP(ai), root->c2p); + } + } else { + ai = NULL; + } + + return ai; +} + +/** + * Virtual bbox callback. + */ +static void +sp_root_bbox(SPItem const *item, NRRect *bbox, NR::Matrix const &transform, unsigned const flags) +{ + SPRoot const *root = SP_ROOT(item); + + if (((SPItemClass *) (parent_class))->bbox) { + NR::Matrix const product( root->c2p * transform ); + ((SPItemClass *) (parent_class))->bbox(item, bbox, + product, + flags); + } +} + +/** + * Virtual print callback. + */ +static void +sp_root_print(SPItem *item, SPPrintContext *ctx) +{ + SPRoot *root = SP_ROOT(item); + + sp_print_bind(ctx, root->c2p, 1.0); + + if (((SPItemClass *) (parent_class))->print) { + ((SPItemClass *) (parent_class))->print(item, ctx); + } + + sp_print_release(ctx); +} + + +/* + 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:textwidth=99 : diff --git a/src/sp-root.h b/src/sp-root.h new file mode 100644 index 000000000..8a6a4ed57 --- /dev/null +++ b/src/sp-root.h @@ -0,0 +1,81 @@ +#ifndef SP_ROOT_H_SEEN +#define SP_ROOT_H_SEEN + +/** \file + * SPRoot: SVG \ implementation. + */ +/* + * Authors: + * Lauris Kaplinski + * + * Copyright (C) 1999-2002 Lauris Kaplinski + * Copyright (C) 2000-2001 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#define SP_TYPE_ROOT (sp_root_get_type()) +#define SP_ROOT(o) (G_TYPE_CHECK_INSTANCE_CAST((o), SP_TYPE_ROOT, SPRoot)) +#define SP_ROOT_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), SP_TYPE_ROOT, SPRootClass)) +#define SP_IS_ROOT(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), SP_TYPE_ROOT)) +#define SP_IS_ROOT_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE((k), SP_TYPE_ROOT)) + +#include +#include "version.h" +#include "svg/svg-length.h" +#include "enums.h" +#include "sp-item-group.h" + +/** \ element */ +struct SPRoot : public SPGroup { + struct { + Inkscape::Version svg; + Inkscape::Version sodipodi; + Inkscape::Version inkscape; + } version, original; + + SVGLength x; + SVGLength y; + SVGLength width; + SVGLength height; + + /* viewBox; */ + unsigned int viewBox_set : 1; + NRRect viewBox; + + /* preserveAspectRatio */ + unsigned int aspect_set : 1; + unsigned int aspect_align : 4; + unsigned int aspect_clip : 1; + + /** Child to parent additional transform. */ + NR::Matrix c2p; + + /** + * Primary \ element where we put new defs (patterns, gradients etc.). + * + * At the time of writing, this is chosen as the first \ child of + * this \ element: see writers of this member in sp-root.cpp. + */ + SPDefs *defs; +}; + +struct SPRootClass { + SPGroupClass parent_class; +}; + +GType sp_root_get_type(); + + +#endif /* !SP_ROOT_H_SEEN */ + +/* + 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:textwidth=99 : diff --git a/src/sp-shape.cpp b/src/sp-shape.cpp new file mode 100644 index 000000000..2ae76ef2e --- /dev/null +++ b/src/sp-shape.cpp @@ -0,0 +1,919 @@ +#define __SP_SHAPE_C__ + +/* + * Base class for shapes, including element + * + * Author: + * Lauris Kaplinski + * + * Copyright (C) 1999-2002 Lauris Kaplinski + * Copyright (C) 2000-2001 Ximian, Inc. + * Copyright (C) 2004 John Cliff + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + + +#include +#include +#include +#include +#include + + +#include "macros.h" +#include "display/nr-arena-shape.h" +#include "print.h" +#include "document.h" +#include "marker-status.h" +#include "style.h" +#include "sp-marker.h" +#include "sp-path.h" +#include "prefs-utils.h" + +#define noSHAPE_VERBOSE + +static void sp_shape_class_init (SPShapeClass *klass); +static void sp_shape_init (SPShape *shape); + +static void sp_shape_build (SPObject * object, SPDocument * document, Inkscape::XML::Node * repr); +static void sp_shape_release (SPObject *object); + +static void sp_shape_update (SPObject *object, SPCtx *ctx, unsigned int flags); +static void sp_shape_modified (SPObject *object, unsigned int flags); + +static void sp_shape_bbox(SPItem const *item, NRRect *bbox, NR::Matrix const &transform, unsigned const flags); +void sp_shape_print (SPItem * item, SPPrintContext * ctx); +static NRArenaItem *sp_shape_show (SPItem *item, NRArena *arena, unsigned int key, unsigned int flags); +static void sp_shape_hide (SPItem *item, unsigned int key); +static void sp_shape_snappoints (SPItem const *item, SnapPointsIter p); + +static void sp_shape_update_marker_view (SPShape *shape, NRArenaItem *ai); +static int sp_shape_has_markers (SPShape const *shape); +static int sp_shape_number_of_markers (SPShape* Shape, int type); + +static SPItemClass *parent_class; + +GType +sp_shape_get_type (void) +{ + static GType type = 0; + if (!type) { + GTypeInfo info = { + sizeof (SPShapeClass), + NULL, NULL, + (GClassInitFunc) sp_shape_class_init, + NULL, NULL, + sizeof (SPShape), + 16, + (GInstanceInitFunc) sp_shape_init, + NULL, /* value_table */ + }; + type = g_type_register_static (SP_TYPE_ITEM, "SPShape", &info, (GTypeFlags)0); + } + return type; +} + +static void +sp_shape_class_init (SPShapeClass *klass) +{ + SPObjectClass *sp_object_class; + SPItemClass * item_class; + SPPathClass * path_class; + + sp_object_class = (SPObjectClass *) klass; + item_class = (SPItemClass *) klass; + path_class = (SPPathClass *) klass; + + parent_class = (SPItemClass *)g_type_class_peek_parent (klass); + + sp_object_class->build = sp_shape_build; + sp_object_class->release = sp_shape_release; + sp_object_class->update = sp_shape_update; + sp_object_class->modified = sp_shape_modified; + + item_class->bbox = sp_shape_bbox; + item_class->print = sp_shape_print; + item_class->show = sp_shape_show; + item_class->hide = sp_shape_hide; + item_class->snappoints = sp_shape_snappoints; +} + +static void +sp_shape_init (SPShape *shape) +{ + /* Nothing here */ +} + +static void +sp_shape_build (SPObject *object, SPDocument *document, Inkscape::XML::Node *repr) +{ + if (((SPObjectClass *) (parent_class))->build) { + (*((SPObjectClass *) (parent_class))->build) (object, document, repr); + } +} + +static void +sp_shape_release (SPObject *object) +{ + SPItem *item; + SPShape *shape; + SPItemView *v; + int i; + + item = (SPItem *) object; + shape = (SPShape *) object; + + for (i=SP_MARKER_LOC_START; imarker[i]) { + sp_signal_disconnect_by_data (shape->marker[i], object); + for (v = item->display; v != NULL; v = v->next) { + sp_marker_hide ((SPMarker *) shape->marker[i], NR_ARENA_ITEM_GET_KEY (v->arenaitem) + i); + } + shape->marker[i] = sp_object_hunref (shape->marker[i], object); + } + } + if (shape->curve) { + shape->curve = sp_curve_unref (shape->curve); + } + + if (((SPObjectClass *) parent_class)->release) { + ((SPObjectClass *) parent_class)->release (object); + } +} + +static void +sp_shape_update (SPObject *object, SPCtx *ctx, unsigned int flags) +{ + SPItem *item = (SPItem *) object; + SPShape *shape = (SPShape *) object; + + if (((SPObjectClass *) (parent_class))->update) { + (* ((SPObjectClass *) (parent_class))->update) (object, ctx, flags); + } + + /* This stanza checks that an object's marker style agrees with + * the marker objects it has allocated. sp_shape_set_marker ensures + * that the appropriate marker objects are present (or absent) to + * match the style. + */ + /* TODO: It would be nice if this could be done at an earlier level */ + for (int i = 0 ; i < SP_MARKER_LOC_QTY ; i++) { + sp_shape_set_marker (object, i, object->style->marker[i].value); + } + + if (flags & (SP_OBJECT_STYLE_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG)) { + SPStyle *style; + style = SP_OBJECT_STYLE (object); + if (style->stroke_width.unit == SP_CSS_UNIT_PERCENT) { + SPItemCtx *ictx = (SPItemCtx *) ctx; + double const aw = 1.0 / NR::expansion(ictx->i2vp); + style->stroke_width.computed = style->stroke_width.value * aw; + for (SPItemView *v = ((SPItem *) (shape))->display; v != NULL; v = v->next) { + nr_arena_shape_set_style ((NRArenaShape *) v->arenaitem, style); + } + } + } + + if (flags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_PARENT_MODIFIED_FLAG)) { + /* This is suboptimal, because changing parent style schedules recalculation */ + /* But on the other hand - how can we know that parent does not tie style and transform */ + NR::Rect const paintbox = SP_ITEM(object)->invokeBbox(NR::identity()); + for (SPItemView *v = SP_ITEM (shape)->display; v != NULL; v = v->next) { + NRArenaShape * const s = NR_ARENA_SHAPE(v->arenaitem); + if (flags & SP_OBJECT_MODIFIED_FLAG) { + nr_arena_shape_set_path(s, shape->curve, (flags & SP_OBJECT_USER_MODIFIED_FLAG_B)); + } + s->setPaintBox(paintbox); + } + } + + if (sp_shape_has_markers (shape)) { + + /* Dimension marker views */ + for (SPItemView *v = item->display; v != NULL; v = v->next) { + + if (!v->arenaitem->key) { + /* Get enough keys for all, start, mid and end marker types, + ** and set this view's arenaitem key to the first of these keys. + */ + NR_ARENA_ITEM_SET_KEY ( + v->arenaitem, + sp_item_display_key_new (SP_MARKER_LOC_QTY) + ); + } + + for (int i = 0 ; i < SP_MARKER_LOC_QTY ; i++) { + if (shape->marker[i]) { + sp_marker_show_dimension ((SPMarker *) shape->marker[i], + NR_ARENA_ITEM_GET_KEY (v->arenaitem) + i - SP_MARKER_LOC, + sp_shape_number_of_markers (shape, i)); + } + } + } + + /* Update marker views */ + for (SPItemView *v = item->display; v != NULL; v = v->next) { + sp_shape_update_marker_view (shape, v->arenaitem); + } + } +} + + +/** +* Works out whether a marker of a given type is required at a particular +* point on a shape. +* +* \param shape Shape of interest. +* \param m Marker type (e.g. SP_MARKER_LOC_START) +* \param bp Path segment. +* \return 1 if a marker is required here, otherwise 0. +*/ +static bool +sp_shape_marker_required(SPShape const *shape, int const m, NArtBpath *bp) +{ + if (shape->marker[m] == NULL) { + return false; + } + + if (bp == shape->curve->bpath) + return m == SP_MARKER_LOC_START; + else if (bp[1].code == NR_END) + return m == SP_MARKER_LOC_END; + else + return m == SP_MARKER_LOC_MID; +} + +static bool +is_moveto(NRPathcode const c) +{ + return c == NR_MOVETO || c == NR_MOVETO_OPEN; +} + +/** \pre The bpath[] containing bp begins with a moveto. */ +static NArtBpath const * +first_seg_in_subpath(NArtBpath const *bp) +{ + while (!is_moveto(bp->code)) { + --bp; + } + return bp; +} + +static NArtBpath const * +last_seg_in_subpath(NArtBpath const *bp) +{ + for(;;) { + ++bp; + switch (bp->code) { + case NR_MOVETO: + case NR_MOVETO_OPEN: + case NR_END: + --bp; + return bp; + + default: continue; + } + } +} + + +/* A subpath begins with a moveto and ends immediately before the next moveto or NR_END. + * (`moveto' here means either NR_MOVETO or NR_MOVETO_OPEN.) I'm assuming that non-empty + * paths always begin with a moveto. + * + * The control points of the subpath are the control points of the path elements of the subpath. + * + * As usual, the control points of a moveto or NR_LINETO are {c(3)}, and + * the control points of a NR_CURVETO are {c(1), c(2), c(3)}. + * (It follows from the definition that NR_END isn't part of a subpath.) + * + * The initial control point is bpath[bi0].c(3). + * + * Reference: http://www.w3.org/TR/SVG11/painting.html#MarkerElement, the `orient' attribute. + * Reference for behaviour of zero-length segments: + * http://www.w3.org/TR/SVG11/implnote.html#PathElementImplementationNotes + */ + +static double const no_tangent = 128.0; /* arbitrarily-chosen value outside the range of atan2, i.e. outside of [-pi, pi]. */ + +/** \pre The bpath[] containing bp0 begins with a moveto. */ +static double +outgoing_tangent(NArtBpath const *bp0) +{ + /* See notes in comment block above. */ + + g_assert(bp0->code != NR_END); + NR::Point const &p0 = bp0->c(3); + NR::Point other; + for (NArtBpath const *bp = bp0;;) { + ++bp; + switch (bp->code) { + case NR_LINETO: + other = bp->c(3); + if (other != p0) { + goto found; + } + break; + + case NR_CURVETO: + for (unsigned ci = 1; ci <= 3; ++ci) { + other = bp->c(ci); + if (other != p0) { + goto found; + } + } + break; + + case NR_MOVETO_OPEN: + case NR_END: + case NR_MOVETO: + bp = first_seg_in_subpath(bp0); + if (bp == bp0) { + /* Gone right around the subpath without finding any different point since the + * initial moveto. */ + return no_tangent; + } + if (bp->code != NR_MOVETO) { + /* Open subpath. */ + return no_tangent; + } + other = bp->c(3); + if (other != p0) { + goto found; + } + break; + } + + if (bp == bp0) { + /* Back where we started, so zero-length subpath. */ + return no_tangent; + + /* Note: this test must come after we've looked at element bp, in case bp0 is a curve: + * we must look at c(1) and c(2). (E.g. single-curve subpath.) + */ + } + } + +found: + return atan2( other - p0 ); +} + +/** \pre The bpath[] containing bp0 begins with a moveto. */ +static double +incoming_tangent(NArtBpath const *bp0) +{ + /* See notes in comment block before outgoing_tangent. */ + + g_assert(bp0->code != NR_END); + NR::Point const &p0 = bp0->c(3); + NR::Point other; + for (NArtBpath const *bp = bp0;;) { + switch (bp->code) { + case NR_LINETO: + other = bp->c(3); + if (other != p0) { + goto found; + } + --bp; + break; + + case NR_CURVETO: + for (unsigned ci = 3; ci != 0; --ci) { + other = bp->c(ci); + if (other != p0) { + goto found; + } + } + --bp; + break; + + case NR_MOVETO: + case NR_MOVETO_OPEN: + other = bp->c(3); + if (other != p0) { + goto found; + } + if (bp->code != NR_MOVETO) { + /* Open subpath. */ + return no_tangent; + } + bp = last_seg_in_subpath(bp0); + break; + + default: /* includes NR_END */ + g_error("Found invalid path code %u in middle of path.", bp->code); + return no_tangent; + } + + if (bp == bp0) { + /* Back where we started from: zero-length subpath. */ + return no_tangent; + } + } + +found: + return atan2( p0 - other ); +} + + +/** +* Calculate the transform required to get a marker's path object in the +* right place for particular path segment on a shape. You should +* call sp_shape_marker_required first to see if a marker is required +* at this point. +* +* \see sp_shape_marker_required. +* +* \param shape Shape which the marker is for. +* \param m Marker type (e.g. SP_MARKER_LOC_START) +* \param bp Path segment which the arrow is for. +* \return Transform matrix. +*/ + +static NR::Matrix +sp_shape_marker_get_transform(SPShape const *shape, NArtBpath const *bp) +{ + g_return_val_if_fail(( is_moveto(shape->curve->bpath[0].code) + && ( 0 < shape->curve->end ) + && ( shape->curve->bpath[shape->curve->end].code == NR_END ) ), + NR::Matrix(NR::translate(bp->c(3)))); + double const angle1 = incoming_tangent(bp); + double const angle2 = outgoing_tangent(bp); + + /* angle1 and angle2 are now each either unset (i.e. still 100 from their initialization) or in + [-pi, pi] from atan2. */ + g_assert((-3.15 < angle1 && angle1 < 3.15) || (angle1 == no_tangent)); + g_assert((-3.15 < angle2 && angle2 < 3.15) || (angle2 == no_tangent)); + + double ret_angle; + if (angle1 == no_tangent) { + /* First vertex of an open subpath. */ + ret_angle = ( angle2 == no_tangent + ? 0. + : angle2 ); + } else if (angle2 == no_tangent) { + /* Last vertex of an open subpath. */ + ret_angle = angle1; + } else { + ret_angle = .5 * (angle1 + angle2); + + if ( fabs( angle2 - angle1 ) > M_PI ) { + /* ret_angle is in the middle of the larger of the two sectors between angle1 and + * angle2, so flip it by 180degrees to force it to the middle of the smaller sector. + * + * (Imagine a circle with rays drawn at angle1 and angle2 from the centre of the + * circle. Those two rays divide the circle into two sectors.) + */ + ret_angle += M_PI; + } + } + + return NR::Matrix(NR::rotate(ret_angle)) * NR::translate(bp->c(3)); +} + +/* Marker views have to be scaled already */ + +static void +sp_shape_update_marker_view (SPShape *shape, NRArenaItem *ai) +{ + SPStyle *style = ((SPObject *) shape)->style; + + marker_status("sp_shape_update_marker_view: Updating views of markers"); + + for (int i = SP_MARKER_LOC_START; i < SP_MARKER_LOC_QTY; i++) { + if (shape->marker[i] == NULL) { + continue; + } + + int n = 0; + + for (NArtBpath *bp = shape->curve->bpath; bp->code != NR_END; bp++) { + if (sp_shape_marker_required (shape, i, bp)) { + NR::Matrix const m(sp_shape_marker_get_transform(shape, bp)); + sp_marker_show_instance ((SPMarker* ) shape->marker[i], ai, + NR_ARENA_ITEM_GET_KEY(ai) + i, n, m, + style->stroke_width.computed); + n++; + } + } + } +} + +static void +sp_shape_modified (SPObject *object, unsigned int flags) +{ + SPShape *shape = SP_SHAPE (object); + + if (((SPObjectClass *) (parent_class))->modified) { + (* ((SPObjectClass *) (parent_class))->modified) (object, flags); + } + + if (flags & SP_OBJECT_STYLE_MODIFIED_FLAG) { + for (SPItemView *v = SP_ITEM (shape)->display; v != NULL; v = v->next) { + nr_arena_shape_set_style (NR_ARENA_SHAPE (v->arenaitem), object->style); + } + } +} + +static void sp_shape_bbox(SPItem const *item, NRRect *bbox, NR::Matrix const &transform, unsigned const flags) +{ + SPShape const *shape = SP_SHAPE (item); + + if (shape->curve) { + + NRRect cbbox; + NRBPath bp; + + bp.path = SP_CURVE_BPATH (shape->curve); + + cbbox.x0 = cbbox.y0 = NR_HUGE; + cbbox.x1 = cbbox.y1 = -NR_HUGE; + + nr_path_matrix_bbox_union(&bp, transform, &cbbox); + + SPStyle* style=SP_OBJECT_STYLE (item); + if (style->stroke.type != SP_PAINT_TYPE_NONE) { + double const scale = expansion(transform); + if ( fabs(style->stroke_width.computed * scale) > 0.01 ) { // sinon c'est 0=oon veut pas de bord + double const width = MAX(0.125, style->stroke_width.computed * scale); + if ( fabs(cbbox.x1-cbbox.x0) > -0.00001 && fabs(cbbox.y1-cbbox.y0) > -0.00001 ) { + cbbox.x0-=0.5*width; + cbbox.x1+=0.5*width; + cbbox.y0-=0.5*width; + cbbox.y1+=0.5*width; + } + } + } + + // Union with bboxes of the markers, if any + if (sp_shape_has_markers (shape)) { + for (NArtBpath* bp = shape->curve->bpath; bp->code != NR_END; bp++) { + for (int m = SP_MARKER_LOC_START; m < SP_MARKER_LOC_QTY; m++) { + if (sp_shape_marker_required (shape, m, bp)) { + + SPMarker* marker = SP_MARKER (shape->marker[m]); + SPItem* marker_item = sp_item_first_item_child (SP_OBJECT (shape->marker[m])); + + NR::Matrix tr(sp_shape_marker_get_transform(shape, bp)); + + if (marker->markerUnits == SP_MARKER_UNITS_STROKEWIDTH) { + tr = NR::scale(style->stroke_width.computed) * tr; + } + + // total marker transform + tr = marker_item->transform * marker->c2p * tr * transform; + + // get bbox of the marker with that transform + NRRect marker_bbox; + sp_item_invoke_bbox (marker_item, &marker_bbox, tr, true); + // union it with the shape bbox + nr_rect_d_union (&cbbox, &cbbox, &marker_bbox); + } + } + } + } + + if ( fabs(cbbox.x1-cbbox.x0) > -0.00001 && fabs(cbbox.y1-cbbox.y0) > -0.00001 ) { + NRRect tbbox=*bbox; + nr_rect_d_union (bbox, &cbbox, &tbbox); + } + } +} + +void +sp_shape_print (SPItem *item, SPPrintContext *ctx) +{ + NRRect pbox, dbox, bbox; + + SPShape *shape = SP_SHAPE(item); + + if (!shape->curve) return; + + gint add_comments = prefs_get_int_attribute_limited ("printing.debug", "add-label-comments", 0, 0, 1); + if (add_comments) { + gchar * comment = g_strdup_printf("begin '%s'", + SP_OBJECT(item)->defaultLabel()); + sp_print_comment(ctx, comment); + g_free(comment); + } + + /* fixme: Think (Lauris) */ + sp_item_invoke_bbox(item, &pbox, NR::identity(), TRUE); + dbox.x0 = 0.0; + dbox.y0 = 0.0; + dbox.x1 = sp_document_width (SP_OBJECT_DOCUMENT (item)); + dbox.y1 = sp_document_height (SP_OBJECT_DOCUMENT (item)); + sp_item_bbox_desktop (item, &bbox); + NR::Matrix const i2d = sp_item_i2d_affine(item); + + SPStyle* style = SP_OBJECT_STYLE (item); + + if (style->fill.type != SP_PAINT_TYPE_NONE) { + NRBPath bp; + bp.path = shape->curve->bpath; + sp_print_fill (ctx, &bp, i2d, style, &pbox, &dbox, &bbox); + } + + if (style->stroke.type != SP_PAINT_TYPE_NONE) { + NRBPath bp; + bp.path = shape->curve->bpath; + sp_print_stroke (ctx, &bp, i2d, style, &pbox, &dbox, &bbox); + } + + for (NArtBpath* bp = shape->curve->bpath; bp->code != NR_END; bp++) { + for (int m = SP_MARKER_LOC_START; m < SP_MARKER_LOC_QTY; m++) { + if (sp_shape_marker_required (shape, m, bp)) { + + SPMarker* marker = SP_MARKER (shape->marker[m]); + SPItem* marker_item = sp_item_first_item_child (SP_OBJECT (shape->marker[m])); + + NR::Matrix tr(sp_shape_marker_get_transform(shape, bp)); + + if (marker->markerUnits == SP_MARKER_UNITS_STROKEWIDTH) { + tr = NR::scale(style->stroke_width.computed) * tr; + } + + tr = marker_item->transform * marker->c2p * tr; + + NR::Matrix old_tr = marker_item->transform; + marker_item->transform = tr; + sp_item_invoke_print (marker_item, ctx); + marker_item->transform = old_tr; + } + } + } + + if (add_comments) { + gchar * comment = g_strdup_printf("end '%s'", + SP_OBJECT(item)->defaultLabel()); + sp_print_comment(ctx, comment); + g_free(comment); + } +} + +static NRArenaItem * +sp_shape_show (SPItem *item, NRArena *arena, unsigned int key, unsigned int flags) +{ + SPObject *object = SP_OBJECT(item); + SPShape *shape = SP_SHAPE(item); + + NRArenaItem *arenaitem = NRArenaShape::create(arena); + NRArenaShape * const s = NR_ARENA_SHAPE(arenaitem); + nr_arena_shape_set_style(s, object->style); + nr_arena_shape_set_path(s, shape->curve, false); + NR::Rect const paintbox = item->invokeBbox(NR::identity()); + s->setPaintBox(paintbox); + + if (sp_shape_has_markers (shape)) { + + /* Dimension marker views */ + if (!arenaitem->key) { + NR_ARENA_ITEM_SET_KEY (arenaitem, sp_item_display_key_new (SP_MARKER_LOC_QTY)); + } + + for (int i = 0; i < SP_MARKER_LOC_QTY; i++) { + if (shape->marker[i]) { + sp_marker_show_dimension ((SPMarker *) shape->marker[i], + NR_ARENA_ITEM_GET_KEY (arenaitem) + i - SP_MARKER_LOC, + sp_shape_number_of_markers (shape, i)); + } + } + + + /* Update marker views */ + sp_shape_update_marker_view (shape, arenaitem); + } + + return arenaitem; +} + +static void +sp_shape_hide (SPItem *item, unsigned int key) +{ + SPShape *shape; + SPItemView *v; + int i; + + shape = (SPShape *) item; + + for (i=0; imarker[i]) { + for (v = item->display; v != NULL; v = v->next) { + if (key == v->key) { + sp_marker_hide ((SPMarker *) shape->marker[i], + NR_ARENA_ITEM_GET_KEY (v->arenaitem) + i); + } + } + } + } + + if (((SPItemClass *) parent_class)->hide) { + ((SPItemClass *) parent_class)->hide (item, key); + } +} + +/* Marker stuff */ + +/** +* \param shape Shape. +* \return TRUE if the shape has any markers, or FALSE if not. +*/ +static int +sp_shape_has_markers (SPShape const *shape) +{ + /* Note, we're ignoring 'marker' settings, which technically should apply for + all three settings. This should be fixed later such that if 'marker' is + specified, then all three should appear. */ + + return ( + shape->curve && + (shape->marker[SP_MARKER_LOC_START] || + shape->marker[SP_MARKER_LOC_MID] || + shape->marker[SP_MARKER_LOC_END]) + ); +} + + +/** +* \param shape Shape. +* \param type Marker type (e.g. SP_MARKER_LOC_START) +* \return Number of markers that the shape has of this type. +*/ +static int +sp_shape_number_of_markers (SPShape *shape, int type) +{ + int n = 0; + for (NArtBpath* bp = shape->curve->bpath; bp->code != NR_END; bp++) { + if (sp_shape_marker_required (shape, type, bp)) { + n++; + } + } + + return n; +} + +static void +sp_shape_marker_release (SPObject *marker, SPShape *shape) +{ + SPItem *item; + int i; + + item = (SPItem *) shape; + + marker_status("sp_shape_marker_release: Releasing markers"); + for (i = SP_MARKER_LOC_START; i < SP_MARKER_LOC_QTY; i++) { + if (marker == shape->marker[i]) { + SPItemView *v; + /* Hide marker */ + for (v = item->display; v != NULL; v = v->next) { + sp_marker_hide ((SPMarker *) (shape->marker[i]), NR_ARENA_ITEM_GET_KEY (v->arenaitem) + i); + /* fixme: Do we need explicit remove here? (Lauris) */ + /* nr_arena_item_set_mask (v->arenaitem, NULL); */ + } + /* Detach marker */ + sp_signal_disconnect_by_data (shape->marker[i], item); + shape->marker[i] = sp_object_hunref (shape->marker[i], item); + } + } +} + +static void +sp_shape_marker_modified (SPObject *marker, guint flags, SPItem *item) +{ + /* I think mask does update automagically */ + /* g_warning ("Item %s mask %s modified", SP_OBJECT_ID (item), SP_OBJECT_ID (mask)); */ +} + +void +sp_shape_set_marker (SPObject *object, unsigned int key, const gchar *value) +{ + SPItem *item = (SPItem *) object; + SPShape *shape = (SPShape *) object; + + if (key < SP_MARKER_LOC_START || key > SP_MARKER_LOC_END) { + return; + } + + SPObject *mrk = sp_uri_reference_resolve (SP_OBJECT_DOCUMENT (object), value); + if (mrk != shape->marker[key]) { + if (shape->marker[key]) { + SPItemView *v; + + /* Detach marker */ + g_signal_handler_disconnect (shape->marker[key], shape->release_connect[key]); + g_signal_handler_disconnect (shape->marker[key], shape->modified_connect[key]); + + /* Hide marker */ + for (v = item->display; v != NULL; v = v->next) { + sp_marker_hide ((SPMarker *) (shape->marker[key]), + NR_ARENA_ITEM_GET_KEY (v->arenaitem) + key); + /* fixme: Do we need explicit remove here? (Lauris) */ + /* nr_arena_item_set_mask (v->arenaitem, NULL); */ + } + + /* Unref marker */ + shape->marker[key] = sp_object_hunref (shape->marker[key], object); + } + if (SP_IS_MARKER (mrk)) { + shape->marker[key] = sp_object_href (mrk, object); + shape->release_connect[key] = g_signal_connect (G_OBJECT (shape->marker[key]), "release", + G_CALLBACK (sp_shape_marker_release), shape); + shape->modified_connect[key] = g_signal_connect (G_OBJECT (shape->marker[key]), "modified", + G_CALLBACK (sp_shape_marker_modified), shape); + } + } +} + + + +/* Shape section */ + +void +sp_shape_set_shape (SPShape *shape) +{ + g_return_if_fail (shape != NULL); + g_return_if_fail (SP_IS_SHAPE (shape)); + + if (SP_SHAPE_CLASS (G_OBJECT_GET_CLASS (shape))->set_shape) { + SP_SHAPE_CLASS (G_OBJECT_GET_CLASS (shape))->set_shape (shape); + } +} + +void +sp_shape_set_curve (SPShape *shape, SPCurve *curve, unsigned int owner) +{ + if (shape->curve) { + shape->curve = sp_curve_unref (shape->curve); + } + if (curve) { + if (owner) { + shape->curve = sp_curve_ref (curve); + } else { + shape->curve = sp_curve_copy (curve); + } + } + SP_OBJECT(shape)->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); +} + +/* Return duplicate of curve or NULL */ +SPCurve * +sp_shape_get_curve (SPShape *shape) +{ + if (shape->curve) { + return sp_curve_copy (shape->curve); + } + return NULL; +} + +/* NOT FOR GENERAL PUBLIC UNTIL SORTED OUT (Lauris) */ +void +sp_shape_set_curve_insync (SPShape *shape, SPCurve *curve, unsigned int owner) +{ + if (shape->curve) { + shape->curve = sp_curve_unref (shape->curve); + } + if (curve) { + if (owner) { + shape->curve = sp_curve_ref (curve); + } else { + shape->curve = sp_curve_copy (curve); + } + } +} + +static void sp_shape_snappoints(SPItem const *item, SnapPointsIter p) +{ + g_assert(item != NULL); + g_assert(SP_IS_SHAPE(item)); + + SPShape const *shape = SP_SHAPE(item); + if (shape->curve == NULL) { + return; + } + + NR::Matrix const i2d (sp_item_i2d_affine (item)); + + /* Use the end points of each segment of the path */ + NArtBpath const *bp = shape->curve->bpath; + while (bp->code != NR_END) { + *p = bp->c(3) * i2d; + bp++; + } +} + + +/* + 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:textwidth=99 : diff --git a/src/sp-shape.h b/src/sp-shape.h new file mode 100644 index 000000000..547928436 --- /dev/null +++ b/src/sp-shape.h @@ -0,0 +1,62 @@ +#ifndef __SP_SHAPE_H__ +#define __SP_SHAPE_H__ + +/* + * Base class for shapes, including element + * + * Author: + * Lauris Kaplinski + * + * Copyright (C) 1999-2002 Lauris Kaplinski + * Copyright (C) 2000-2001 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "display/display-forward.h" +#include "sp-item.h" +#include "sp-marker-loc.h" + + + +#define SP_TYPE_SHAPE (sp_shape_get_type ()) +#define SP_SHAPE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SP_TYPE_SHAPE, SPShape)) +#define SP_SHAPE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SP_TYPE_SHAPE, SPShapeClass)) +#define SP_IS_SHAPE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_SHAPE)) +#define SP_IS_SHAPE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SP_TYPE_SHAPE)) + +#define SP_SHAPE_WRITE_PATH (1 << 2) + +struct SPShape : public SPItem { + SPCurve *curve; + + SPObject *marker[SP_MARKER_LOC_QTY]; + gulong release_connect [SP_MARKER_LOC_QTY]; + gulong modified_connect [SP_MARKER_LOC_QTY]; +}; + +struct SPShapeClass { + SPItemClass item_class; + + /* Build bpath from extra shape attributes */ + void (* set_shape) (SPShape *shape); +}; + +GType sp_shape_get_type (void); + +void sp_shape_set_shape (SPShape *shape); + +/* Return duplicate of curve or NULL */ +SPCurve *sp_shape_get_curve (SPShape *shape); + +void sp_shape_set_curve (SPShape *shape, SPCurve *curve, unsigned int owner); + +/* NOT FOR GENERAL PUBLIC UNTIL SORTED OUT (Lauris) */ +void sp_shape_set_curve_insync (SPShape *shape, SPCurve *curve, unsigned int owner); + +/* PROTECTED */ +void sp_shape_set_marker (SPObject *object, unsigned int key, const gchar *value); + + + +#endif diff --git a/src/sp-skeleton.cpp b/src/sp-skeleton.cpp new file mode 100644 index 000000000..f45ff1fda --- /dev/null +++ b/src/sp-skeleton.cpp @@ -0,0 +1,215 @@ +#define __SP_SKELETON_CPP__ + +/** \file + * SVG implementation, used as an example for a base starting class + * when implementing new sp-objects. + * + * In vi, three global search-and-replaces will let you rename everything + * in this and the .h file: + * + * :%s/SKELETON/YOURNAME/g + * :%s/Skeleton/Yourname/g + * :%s/skeleton/yourname/g + */ +/* + * Authors: + * Kees Cook + * + * Copyright (C) 2004 Kees Cook + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "attributes.h" +#include "sp-skeleton.h" +#include "xml/repr.h" + +#define DEBUG_SKELETON +#ifdef DEBUG_SKELETON +# define debug(f, a...) { g_print("%s(%d) %s:", \ + __FILE__,__LINE__,__FUNCTION__); \ + g_print(f, ## a); \ + g_print("\n"); \ + } +#else +# define debug(f, a...) /**/ +#endif + +/* Skeleton base class */ + +static void sp_skeleton_class_init(SPSkeletonClass *klass); +static void sp_skeleton_init(SPSkeleton *skeleton); + +static void sp_skeleton_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr); +static void sp_skeleton_release(SPObject *object); +static void sp_skeleton_set(SPObject *object, unsigned int key, gchar const *value); +static void sp_skeleton_update(SPObject *object, SPCtx *ctx, guint flags); +static Inkscape::XML::Node *sp_skeleton_write(SPObject *object, Inkscape::XML::Node *repr, guint flags); + +static SPObjectClass *skeleton_parent_class; + +GType +sp_skeleton_get_type() +{ + static GType skeleton_type = 0; + + if (!skeleton_type) { + GTypeInfo skeleton_info = { + sizeof(SPSkeletonClass), + NULL, NULL, + (GClassInitFunc) sp_skeleton_class_init, + NULL, NULL, + sizeof(SPSkeleton), + 16, + (GInstanceInitFunc) sp_skeleton_init, + NULL, /* value_table */ + }; + skeleton_type = g_type_register_static(SP_TYPE_OBJECT, "SPSkeleton", &skeleton_info, (GTypeFlags)0); + } + return skeleton_type; +} + +static void +sp_skeleton_class_init(SPSkeletonClass *klass) +{ + //GObjectClass *gobject_class = (GObjectClass *)klass; + SPObjectClass *sp_object_class = (SPObjectClass *)klass; + + skeleton_parent_class = (SPObjectClass*)g_type_class_peek_parent(klass); + + sp_object_class->build = sp_skeleton_build; + sp_object_class->release = sp_skeleton_release; + sp_object_class->write = sp_skeleton_write; + sp_object_class->set = sp_skeleton_set; + sp_object_class->update = sp_skeleton_update; +} + +static void +sp_skeleton_init(SPSkeleton *skeleton) +{ + debug("0x%p",skeleton); +} + +/** + * Reads the Inkscape::XML::Node, and initializes SPSkeleton variables. For this to get called, + * our name must be associated with a repr via "sp_object_type_register". Best done through + * sp-object-repr.cpp's repr_name_entries array. + */ +static void +sp_skeleton_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr) +{ + debug("0x%p",object); + if (((SPObjectClass *) skeleton_parent_class)->build) { + ((SPObjectClass *) skeleton_parent_class)->build(object, document, repr); + } + + /* + Pay attention to certain settings here + + sp_object_read_attr(object, "xlink:href"); + sp_object_read_attr(object, "attributeName"); + sp_object_read_attr(object, "attributeType"); + sp_object_read_attr(object, "begin"); + sp_object_read_attr(object, "dur"); + sp_object_read_attr(object, "end"); + sp_object_read_attr(object, "min"); + sp_object_read_attr(object, "max"); + sp_object_read_attr(object, "restart"); + sp_object_read_attr(object, "repeatCount"); + sp_object_read_attr(object, "repeatDur"); + sp_object_read_attr(object, "fill"); + */ +} + +/** + * Drops any allocated memory. + */ +static void +sp_skeleton_release(SPObject *object) +{ + debug("0x%p",object); + + /* deal with our children and our selves here */ + + if (((SPObjectClass *) skeleton_parent_class)->release) + ((SPObjectClass *) skeleton_parent_class)->release(object); +} + +/** + * Sets a specific value in the SPSkeleton. + */ +static void +sp_skeleton_set(SPObject *object, unsigned int key, gchar const *value) +{ + debug("0x%p %s(%u): '%s'",object, + sp_attribute_name(key),key,value); + SPSkeleton *skeleton = SP_SKELETON(object); + + /* See if any parents need this value. */ + if (((SPObjectClass *) skeleton_parent_class)->set) { + ((SPObjectClass *) skeleton_parent_class)->set(object, key, value); + } +} + +/** + * Receives update notifications. + */ +static void +sp_skeleton_update(SPObject *object, SPCtx *ctx, guint flags) +{ + debug("0x%p",object); + //SPSkeleton *skeleton = SP_SKELETON(object); + + if (flags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG | + SP_OBJECT_VIEWPORT_MODIFIED_FLAG)) { + + /* do something to trigger redisplay, updates? */ + + } + + if (((SPObjectClass *) skeleton_parent_class)->update) { + ((SPObjectClass *) skeleton_parent_class)->update(object, ctx, flags); + } +} + +/** + * Writes its settings to an incoming repr object, if any. + */ +static Inkscape::XML::Node * +sp_skeleton_write(SPObject *object, Inkscape::XML::Node *repr, guint flags) +{ + debug("0x%p",object); + //SPSkeleton *skeleton = SP_SKELETON(object); + + // Inkscape-only object, not copied during an "plain SVG" dump: + if (flags & SP_OBJECT_WRITE_EXT) { + if (repr) { + // is this sane? + repr->mergeFrom(SP_OBJECT_REPR(object), "id"); + } else { + repr = SP_OBJECT_REPR(object)->duplicate(); + } + } + + if (((SPObjectClass *) skeleton_parent_class)->write) { + ((SPObjectClass *) skeleton_parent_class)->write(object, repr, flags); + } + + return repr; +} + + +/* + 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:textwidth=99 : diff --git a/src/sp-skeleton.h b/src/sp-skeleton.h new file mode 100644 index 000000000..fc706aacd --- /dev/null +++ b/src/sp-skeleton.h @@ -0,0 +1,48 @@ +#ifndef SP_SKELETON_H_SEEN +#define SP_SKELETON_H_SEEN + +/** \file + * SVG implementation, see sp-skeleton.cpp. + */ +/* + * Authors: + * Kees Cook + * + * Copyright (C) 2004 Kees Cook + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "sp-object.h" + +/* Skeleton base class */ + +#define SP_TYPE_SKELETON (sp_skeleton_get_type()) +#define SP_SKELETON(o) (G_TYPE_CHECK_INSTANCE_CAST((o), SP_TYPE_SKELETON, SPSkeleton)) +#define SP_IS_SKELETON(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), SP_TYPE_SKELETON)) + +class SPSkeleton; +class SPSkeletonClass; + +struct SPSkeleton : public SPObject { +}; + +struct SPSkeletonClass { + SPObjectClass parent_class; +}; + +GType sp_skeleton_get_type(); + + +#endif /* !SP_SKELETON_H_SEEN */ + +/* + 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:textwidth=99 : diff --git a/src/sp-spiral.cpp b/src/sp-spiral.cpp new file mode 100644 index 000000000..aced4ec53 --- /dev/null +++ b/src/sp-spiral.cpp @@ -0,0 +1,617 @@ +#define __SP_SPIRAL_C__ + +/** \file + * implementation + */ +/* + * Authors: + * Mitsuru Oka + * Lauris Kaplinski + * + * Copyright (C) 1999-2002 Lauris Kaplinski + * Copyright (C) 2000-2001 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "config.h" + + +#include "svg/svg.h" +#include "attributes.h" +#include "display/bezier-utils.h" +#include "display/curve.h" +#include +#include "xml/repr.h" + +#include "sp-spiral.h" + +static void sp_spiral_class_init (SPSpiralClass *klass); +static void sp_spiral_init (SPSpiral *spiral); + +static void sp_spiral_build (SPObject * object, SPDocument * document, Inkscape::XML::Node * repr); +static Inkscape::XML::Node *sp_spiral_write (SPObject *object, Inkscape::XML::Node *repr, guint flags); +static void sp_spiral_set (SPObject *object, unsigned int key, const gchar *value); +static void sp_spiral_update (SPObject *object, SPCtx *ctx, guint flags); + +static gchar * sp_spiral_description (SPItem * item); +static void sp_spiral_snappoints(SPItem const *item, SnapPointsIter p); +static void sp_spiral_set_shape (SPShape *shape); + +static NR::Point sp_spiral_get_tangent (SPSpiral const *spiral, gdouble t); + +static SPShapeClass *parent_class; + +/** + * Register SPSpiral class and return its type number. + */ +GType +sp_spiral_get_type (void) +{ + static GType spiral_type = 0; + + if (!spiral_type) { + GTypeInfo spiral_info = { + sizeof (SPSpiralClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) sp_spiral_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (SPSpiral), + 16, /* n_preallocs */ + (GInstanceInitFunc) sp_spiral_init, + NULL, /* value_table */ + }; + spiral_type = g_type_register_static (SP_TYPE_SHAPE, "SPSpiral", &spiral_info, (GTypeFlags)0); + } + return spiral_type; +} + +/** + * SPSpiral vtable initialization. + */ +static void +sp_spiral_class_init (SPSpiralClass *klass) +{ + GObjectClass * gobject_class; + SPObjectClass * sp_object_class; + SPItemClass * item_class; + SPShapeClass *shape_class; + + gobject_class = (GObjectClass *) klass; + sp_object_class = (SPObjectClass *) klass; + item_class = (SPItemClass *) klass; + shape_class = (SPShapeClass *) klass; + + parent_class = (SPShapeClass *)g_type_class_ref (SP_TYPE_SHAPE); + + sp_object_class->build = sp_spiral_build; + sp_object_class->write = sp_spiral_write; + sp_object_class->set = sp_spiral_set; + sp_object_class->update = sp_spiral_update; + + item_class->description = sp_spiral_description; + item_class->snappoints = sp_spiral_snappoints; + + shape_class->set_shape = sp_spiral_set_shape; +} + +/** + * Callback for SPSpiral object initialization. + */ +static void +sp_spiral_init (SPSpiral * spiral) +{ + spiral->cx = 0.0; + spiral->cy = 0.0; + spiral->exp = 1.0; + spiral->revo = 3.0; + spiral->rad = 1.0; + spiral->arg = 0.0; + spiral->t0 = 0.0; +} + +/** + * Virtual build: set spiral properties from corresponding repr. + */ +static void +sp_spiral_build (SPObject * object, SPDocument * document, Inkscape::XML::Node * repr) +{ + if (((SPObjectClass *) parent_class)->build) + ((SPObjectClass *) parent_class)->build (object, document, repr); + + sp_object_read_attr (object, "sodipodi:cx"); + sp_object_read_attr (object, "sodipodi:cy"); + sp_object_read_attr (object, "sodipodi:expansion"); + sp_object_read_attr (object, "sodipodi:revolution"); + sp_object_read_attr (object, "sodipodi:radius"); + sp_object_read_attr (object, "sodipodi:argument"); + sp_object_read_attr (object, "sodipodi:t0"); +} + +/** + * Virtual write: write spiral attributes to corresponding repr. + */ +static Inkscape::XML::Node * +sp_spiral_write (SPObject *object, Inkscape::XML::Node *repr, guint flags) +{ + SPSpiral *spiral = SP_SPIRAL (object); + + if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { + repr = sp_repr_new ("svg:path"); + } + + if (flags & SP_OBJECT_WRITE_EXT) { + /* Fixme: we may replace these attributes by + * sodipodi:spiral="cx cy exp revo rad arg t0" + */ + repr->setAttribute("sodipodi:type", "spiral"); + sp_repr_set_svg_double(repr, "sodipodi:cx", spiral->cx); + sp_repr_set_svg_double(repr, "sodipodi:cy", spiral->cy); + sp_repr_set_svg_double(repr, "sodipodi:expansion", spiral->exp); + sp_repr_set_svg_double(repr, "sodipodi:revolution", spiral->revo); + sp_repr_set_svg_double(repr, "sodipodi:radius", spiral->rad); + sp_repr_set_svg_double(repr, "sodipodi:argument", spiral->arg); + sp_repr_set_svg_double(repr, "sodipodi:t0", spiral->t0); + } + + //Duplicate the path + SPCurve *curve = ((SPShape *) spiral)->curve; + //Nulls might be possible if this called iteratively + if ( !curve ) { + //g_warning("sp_spiral_write(): No path to copy\n"); + return NULL; + } + NArtBpath *bpath = curve->bpath; + if ( !bpath ) { + //g_warning("sp_spiral_write(): No path to copy\n"); + return NULL; + } + char *d = sp_svg_write_path ( bpath ); + repr->setAttribute("d", d); + g_free (d); + + if (((SPObjectClass *) (parent_class))->write) + ((SPObjectClass *) (parent_class))->write (object, repr, flags | SP_SHAPE_WRITE_PATH); + + return repr; +} + +/** + * Virtual set: change spiral object attribute. + */ +static void +sp_spiral_set (SPObject *object, unsigned int key, const gchar *value) +{ + SPSpiral *spiral; + SPShape *shape; + + spiral = SP_SPIRAL (object); + shape = SP_SHAPE (object); + + /// \todo fixme: we should really collect updates + switch (key) { + case SP_ATTR_SODIPODI_CX: + if (!sp_svg_length_read_computed_absolute (value, &spiral->cx)) { + spiral->cx = 0.0; + } + object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_SODIPODI_CY: + if (!sp_svg_length_read_computed_absolute (value, &spiral->cy)) { + spiral->cy = 0.0; + } + object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_SODIPODI_EXPANSION: + if (value) { + /** \todo + * FIXME: check that value looks like a (finite) + * number. Create a routine that uses strtod, and + * accepts a default value (if strtod finds an error). + * N.B. atof/sscanf/strtod consider "nan" and "inf" + * to be valid numbers. + */ + spiral->exp = g_ascii_strtod (value, NULL); + spiral->exp = CLAMP (spiral->exp, 0.0, 1000.0); + } else { + spiral->exp = 1.0; + } + object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_SODIPODI_REVOLUTION: + if (value) { + spiral->revo = g_ascii_strtod (value, NULL); + spiral->revo = CLAMP (spiral->revo, 0.05, 1024.0); + } else { + spiral->revo = 3.0; + } + object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_SODIPODI_RADIUS: + if (!sp_svg_length_read_computed_absolute (value, &spiral->rad)) { + spiral->rad = MAX (spiral->rad, 0.001); + } + object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_SODIPODI_ARGUMENT: + if (value) { + spiral->arg = g_ascii_strtod (value, NULL); + /** \todo + * FIXME: We still need some bounds on arg, for + * numerical reasons. E.g., we don't want inf or NaN, + * nor near-infinite numbers. I'm inclined to take + * modulo 2*pi. If so, then change the knot editors, + * which use atan2 - revo*2*pi, which typically + * results in very negative arg. + */ + } else { + spiral->arg = 0.0; + } + object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_SODIPODI_T0: + if (value) { + spiral->t0 = g_ascii_strtod (value, NULL); + spiral->t0 = CLAMP (spiral->t0, 0.0, 0.999); + /** \todo + * Have shared constants for the allowable bounds for + * attributes. There was a bug here where we used -1.0 + * as the minimum (which leads to NaN via, e.g., + * pow(-1.0, 0.5); see sp_spiral_get_xy for + * requirements. + */ + } else { + spiral->t0 = 0.0; + } + object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + break; + default: + if (((SPObjectClass *) parent_class)->set) + ((SPObjectClass *) parent_class)->set (object, key, value); + break; + } +} + +/** + * Virtual update callback. + */ +static void +sp_spiral_update (SPObject *object, SPCtx *ctx, guint flags) +{ + if (flags & (SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG | SP_OBJECT_VIEWPORT_MODIFIED_FLAG)) { + sp_shape_set_shape ((SPShape *) object); + } + + if (((SPObjectClass *) parent_class)->update) + ((SPObjectClass *) parent_class)->update (object, ctx, flags); +} + +/** + * Return textual description of spiral. + */ +static gchar * +sp_spiral_description (SPItem * item) +{ + // TRANSLATORS: since turn count isn't an integer, please adjust the + // string as needed to deal with an localized plural forms. + return g_strdup_printf (_("Spiral with %3f turns"), SP_SPIRAL(item)->revo); +} + + +/** + * Fit beziers together to spiral and draw it. + * + * \pre dstep \> 0. + * \pre is_unit_vector(*hat1). + * \post is_unit_vector(*hat2). + **/ +static void +sp_spiral_fit_and_draw (SPSpiral const *spiral, + SPCurve *c, + double dstep, + NR::Point darray[], + NR::Point const &hat1, + NR::Point &hat2, + double *t) +{ +#define BEZIER_SIZE 4 +#define FITTING_MAX_BEZIERS 4 +#define BEZIER_LENGTH (BEZIER_SIZE * FITTING_MAX_BEZIERS) + g_assert (dstep > 0); + g_assert (is_unit_vector (hat1)); + + NR::Point bezier[BEZIER_LENGTH]; + double d; + int depth, i; + + for (d = *t, i = 0; i <= SAMPLE_SIZE; d += dstep, i++) { + darray[i] = sp_spiral_get_xy(spiral, d); + + /* Avoid useless adjacent dups. (Otherwise we can have all of darray filled with + the same value, which upsets chord_length_parameterize.) */ + if ((i != 0) + && (darray[i] == darray[i - 1]) + && (d < 1.0)) { + i--; + d += dstep; + /** We mustn't increase dstep for subsequent values of + * i: for large spiral.exp values, rate of growth + * increases very rapidly. + */ + /** \todo + * Get the function itself to decide what value of d + * to use next: ensure that we move at least 0.25 * + * stroke width, for example. The derivative (as used + * for get_tangent before normalization) would be + * useful for estimating the appropriate d value. Or + * perhaps just start with a small dstep and scale by + * some small number until we move >= 0.25 * + * stroke_width. Must revert to the original dstep + * value for next iteration to avoid the problem + * mentioned above. + */ + } + } + + double const next_t = d - 2 * dstep; + /* == t + (SAMPLE_SIZE - 1) * dstep, in absence of dups. */ + + hat2 = -sp_spiral_get_tangent (spiral, next_t); + + /** \todo + * We should use better algorithm to specify maximum error. + */ + depth = sp_bezier_fit_cubic_full (bezier, NULL, darray, SAMPLE_SIZE, + hat1, hat2, + SPIRAL_TOLERANCE*SPIRAL_TOLERANCE, + FITTING_MAX_BEZIERS); + g_assert(depth * BEZIER_SIZE <= gint(G_N_ELEMENTS(bezier))); +#ifdef SPIRAL_DEBUG + if (*t == spiral->t0 || *t == 1.0) + g_print ("[%s] depth=%d, dstep=%g, t0=%g, t=%g, arg=%g\n", + debug_state, depth, dstep, spiral->t0, *t, spiral->arg); +#endif + if (depth != -1) { + for (i = 0; i < 4*depth; i += 4) { + sp_curve_curveto (c, + bezier[i + 1], + bezier[i + 2], + bezier[i + 3]); + } + } else { +#ifdef SPIRAL_VERBOSE + g_print ("cant_fit_cubic: t=%g\n", *t); +#endif + for (i = 1; i < SAMPLE_SIZE; i++) + sp_curve_lineto (c, darray[i]); + } + *t = next_t; + g_assert (is_unit_vector (hat2)); +} + +static void +sp_spiral_set_shape (SPShape *shape) +{ + NR::Point darray[SAMPLE_SIZE + 1]; + double t; + + SPSpiral *spiral = SP_SPIRAL(shape); + + SP_OBJECT (spiral)->requestModified(SP_OBJECT_MODIFIED_FLAG); + + SPCurve *c = sp_curve_new (); + +#ifdef SPIRAL_VERBOSE + g_print ("cx=%g, cy=%g, exp=%g, revo=%g, rad=%g, arg=%g, t0=%g\n", + spiral->cx, + spiral->cy, + spiral->exp, + spiral->revo, + spiral->rad, + spiral->arg, + spiral->t0); +#endif + + /* Initial moveto. */ + sp_curve_moveto(c, sp_spiral_get_xy(spiral, spiral->t0)); + + double const tstep = SAMPLE_STEP / spiral->revo; + double const dstep = tstep / (SAMPLE_SIZE - 1); + + NR::Point hat1 = sp_spiral_get_tangent (spiral, spiral->t0); + NR::Point hat2; + for (t = spiral->t0; t < (1.0 - tstep);) { + sp_spiral_fit_and_draw (spiral, c, dstep, darray, hat1, hat2, &t); + + hat1 = -hat2; + } + if ((1.0 - t) > SP_EPSILON) + sp_spiral_fit_and_draw (spiral, c, (1.0 - t)/(SAMPLE_SIZE - 1.0), + darray, hat1, hat2, &t); + + sp_shape_set_curve_insync ((SPShape *) spiral, c, TRUE); + sp_curve_unref (c); +} + +/** + * Set spiral properties and update display. + */ +void +sp_spiral_position_set (SPSpiral *spiral, + gdouble cx, + gdouble cy, + gdouble exp, + gdouble revo, + gdouble rad, + gdouble arg, + gdouble t0) +{ + g_return_if_fail (spiral != NULL); + g_return_if_fail (SP_IS_SPIRAL (spiral)); + + /** \todo + * Consider applying CLAMP or adding in-bounds assertions for + * some of these parameters. + */ + spiral->cx = cx; + spiral->cy = cy; + spiral->exp = exp; + spiral->revo = revo; + spiral->rad = MAX (rad, 0.001); + spiral->arg = arg; + spiral->t0 = CLAMP(t0, 0.0, 0.999); + + ((SPObject *)spiral)->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); +} + +/** + * Virtual snappoints callback. + */ +static void sp_spiral_snappoints(SPItem const *item, SnapPointsIter p) +{ + if (((SPItemClass *) parent_class)->snappoints) { + ((SPItemClass *) parent_class)->snappoints (item, p); + } +} + +/** + * Return one of the points on the spiral. + * + * \param t specifies how far along the spiral. + * \pre \a t in [0.0, 2.03]. (It doesn't make sense for t to be much more + * than 1.0, though some callers go slightly beyond 1.0 for curve-fitting + * purposes.) + */ +NR::Point sp_spiral_get_xy (SPSpiral const *spiral, gdouble t) +{ + g_assert (spiral != NULL); + g_assert (SP_IS_SPIRAL(spiral)); + g_assert (spiral->exp >= 0.0); + /* Otherwise we get NaN for t==0. */ + g_assert (spiral->exp <= 1000.0); + /* Anything much more results in infinities. Even allowing 1000 is somewhat overkill. */ + g_assert (t >= 0.0); + /* Any callers passing -ve t will have a bug for non-integral values of exp. */ + + double const rad = spiral->rad * pow(t, (double) spiral->exp); + double const arg = 2.0 * M_PI * spiral->revo * t + spiral->arg; + + return NR::Point(rad * cos (arg) + spiral->cx, + rad * sin (arg) + spiral->cy); +} + + +/** + * Returns the derivative of sp_spiral_get_xy with respect to t, + * scaled to a unit vector. + * + * \pre spiral != 0. + * \pre 0 \<= t. + * \pre p != NULL. + * \post is_unit_vector(*p). + */ +static NR::Point +sp_spiral_get_tangent (SPSpiral const *spiral, gdouble t) +{ + NR::Point ret(1.0, 0.0); + g_return_val_if_fail (( ( spiral != NULL ) + && SP_IS_SPIRAL(spiral) ), + ret); + g_assert (t >= 0.0); + g_assert (spiral->exp >= 0.0); + /* See above for comments on these assertions. */ + + double const t_scaled = 2.0 * M_PI * spiral->revo * t; + double const arg = t_scaled + spiral->arg; + double const s = sin (arg); + double const c = cos (arg); + + if (spiral->exp == 0.0) { + ret = NR::Point(-s, c); + } else if (t_scaled == 0.0) { + ret = NR::Point(c, s); + } else { + NR::Point unrotated(spiral->exp, t_scaled); + double const s_len = L2 (unrotated); + g_assert (s_len != 0); + /** \todo + * Check that this isn't being too hopeful of the hypot + * function. E.g. test with numbers around 2**-1070 + * (denormalized numbers), preferably on a few different + * platforms. However, njh says that the usual implementation + * does handle both very big and very small numbers. + */ + unrotated /= s_len; + + /* ret = spiral->exp * (c, s) + t_scaled * (-s, c); + alternatively ret = (spiral->exp, t_scaled) * (( c, s), + (-s, c)).*/ + ret = NR::Point(dot(unrotated, NR::Point(c, -s)), + dot(unrotated, NR::Point(s, c))); + /* ret should already be approximately normalized: the + matrix ((c, -s), (s, c)) is orthogonal (it just + rotates by arg), and unrotated has been normalized, + so ret is already of unit length other than numerical + error in the above matrix multiplication. */ + + /** \todo + * I haven't checked how important it is for ret to be very + * near unit length; we could get rid of the below. + */ + + ret.normalize(); + /* Proof that ret length is non-zero: see above. (Should be near 1.) */ + } + + g_assert (is_unit_vector (ret)); + return ret; +} + +/** + * Compute rad and/or arg for point on spiral. + */ +void +sp_spiral_get_polar (SPSpiral const *spiral, gdouble t, gdouble *rad, gdouble *arg) +{ + g_return_if_fail (spiral != NULL); + g_return_if_fail (SP_IS_SPIRAL(spiral)); + + if (rad) + *rad = spiral->rad * pow(t, (double) spiral->exp); + if (arg) + *arg = 2.0 * M_PI * spiral->revo * t + spiral->arg; +} + +/** + * Return true if spiral has properties that make it invalid. + */ +bool +sp_spiral_is_invalid (SPSpiral const *spiral) +{ + gdouble rad; + + sp_spiral_get_polar (spiral, 0.0, &rad, NULL); + if (rad < 0.0 || rad > SP_HUGE) { + g_print ("rad(t=0)=%g\n", rad); + return TRUE; + } + sp_spiral_get_polar (spiral, 1.0, &rad, NULL); + if (rad < 0.0 || rad > SP_HUGE) { + g_print ("rad(t=1)=%g\n", rad); + return TRUE; + } + return FALSE; +} + +/* + 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:textwidth=99 : diff --git a/src/sp-spiral.h b/src/sp-spiral.h new file mode 100644 index 000000000..62c916e82 --- /dev/null +++ b/src/sp-spiral.h @@ -0,0 +1,91 @@ +#ifndef __SP_SPIRAL_H__ +#define __SP_SPIRAL_H__ + +/** \file + * SPSpiral: implementation + * + * Authors: + * Mitsuru Oka + * Lauris Kaplinski + * + * Copyright (C) 1999-2002 Lauris Kaplinski + * Copyright (C) 2000-2001 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "sp-shape.h" + +#define noSPIRAL_VERBOSE + +#define SP_EPSILON 1e-5 +#define SP_EPSILON_2 (SP_EPSILON * SP_EPSILON) +#define SP_HUGE 1e5 + +#define SPIRAL_TOLERANCE 3.0 +#define SAMPLE_STEP (1.0/4.0) ///< step per 2PI +#define SAMPLE_SIZE 8 ///< sample size per one bezier + +#define SP_TYPE_SPIRAL (sp_spiral_get_type ()) +#define SP_SPIRAL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SP_TYPE_SPIRAL, SPSpiral)) +#define SP_SPIRAL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SP_TYPE_SPIRAL, SPSpiralClass)) +#define SP_IS_SPIRAL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_SPIRAL)) +#define SP_IS_SPIRAL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SP_TYPE_SPIRAL)) + +class SPSpiral; +class SPSpiralClass; + +/** + * A spiral Shape. + * + * The Spiral shape is defined as: + * \verbatim + x(t) = rad * t^exp cos(2 * Pi * revo*t + arg) + cx + y(t) = rad * t^exp sin(2 * Pi * revo*t + arg) + cy \endverbatim + * where spiral curve is drawn for {t | t0 <= t <= 1}. The rad and arg + * parameters can also be represented by transformation. + * + * \todo Should I remove these attributes? + */ +struct SPSpiral : public SPShape { + float cx, cy; + float exp; ///< Spiral expansion factor + float revo; ///< Spiral revolution factor + float rad; ///< Spiral radius + float arg; ///< Spiral argument + float t0; +}; + +/// The SPSpiral vtable. +struct SPSpiralClass { + SPShapeClass parent_class; +}; + + +/* Standard Gtk function */ +GType sp_spiral_get_type (void); + +/* Lowlevel interface */ +void sp_spiral_position_set (SPSpiral *spiral, + gdouble cx, + gdouble cy, + gdouble exp, + gdouble revo, + gdouble rad, + gdouble arg, + gdouble t0); + +NR::Point sp_spiral_get_xy (SPSpiral const *spiral, + gdouble t); + +void sp_spiral_get_polar (SPSpiral const *spiral, + gdouble t, + gdouble *rad, + gdouble *arg); + +bool sp_spiral_is_invalid (SPSpiral const *spiral); + + + + +#endif diff --git a/src/sp-star.cpp b/src/sp-star.cpp new file mode 100644 index 000000000..dfa34be95 --- /dev/null +++ b/src/sp-star.cpp @@ -0,0 +1,544 @@ +#define __SP_STAR_C__ + +/* + * implementation + * + * Authors: + * Mitsuru Oka + * Lauris Kaplinski + * bulia byak + * + * Copyright (C) 1999-2002 Lauris Kaplinski + * Copyright (C) 2000-2001 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "config.h" + +#if defined(WIN32) || defined(__APPLE__) +# include +#endif + +#include "svg/svg.h" +#include "attributes.h" +#include "display/curve.h" +#include "xml/repr.h" + +#include "sp-star.h" + +static void sp_star_class_init (SPStarClass *klass); +static void sp_star_init (SPStar *star); + +static void sp_star_build (SPObject * object, SPDocument * document, Inkscape::XML::Node * repr); +static Inkscape::XML::Node *sp_star_write (SPObject *object, Inkscape::XML::Node *repr, guint flags); +static void sp_star_set (SPObject *object, unsigned int key, const gchar *value); +static void sp_star_update (SPObject *object, SPCtx *ctx, guint flags); + +static gchar * sp_star_description (SPItem * item); +static void sp_star_snappoints(SPItem const *item, SnapPointsIter p); + +static void sp_star_set_shape (SPShape *shape); + +static SPShapeClass *parent_class; + +GType +sp_star_get_type (void) +{ + static GType type = 0; + + if (!type) { + GTypeInfo info = { + sizeof (SPStarClass), + NULL, NULL, + (GClassInitFunc) sp_star_class_init, + NULL, NULL, + sizeof (SPStar), + 16, + (GInstanceInitFunc) sp_star_init, + NULL, /* value_table */ + }; + type = g_type_register_static (SP_TYPE_SHAPE, "SPStar", &info, (GTypeFlags)0); + } + return type; +} + +static void +sp_star_class_init (SPStarClass *klass) +{ + GObjectClass * gobject_class; + SPObjectClass * sp_object_class; + SPItemClass * item_class; + SPPathClass * path_class; + SPShapeClass * shape_class; + + gobject_class = (GObjectClass *) klass; + sp_object_class = (SPObjectClass *) klass; + item_class = (SPItemClass *) klass; + path_class = (SPPathClass *) klass; + shape_class = (SPShapeClass *) klass; + + parent_class = (SPShapeClass *)g_type_class_ref (SP_TYPE_SHAPE); + + sp_object_class->build = sp_star_build; + sp_object_class->write = sp_star_write; + sp_object_class->set = sp_star_set; + sp_object_class->update = sp_star_update; + + item_class->description = sp_star_description; + item_class->snappoints = sp_star_snappoints; + + shape_class->set_shape = sp_star_set_shape; +} + +static void +sp_star_init (SPStar * star) +{ + star->sides = 5; + star->center = NR::Point(0, 0); + star->r[0] = 1.0; + star->r[1] = 0.001; + star->arg[0] = star->arg[1] = 0.0; + star->flatsided = 0; + star->rounded = 0.0; + star->randomized = 0.0; +} + +static void +sp_star_build (SPObject * object, SPDocument * document, Inkscape::XML::Node * repr) +{ + if (((SPObjectClass *) parent_class)->build) + ((SPObjectClass *) parent_class)->build (object, document, repr); + + sp_object_read_attr (object, "sodipodi:cx"); + sp_object_read_attr (object, "sodipodi:cy"); + sp_object_read_attr (object, "sodipodi:sides"); + sp_object_read_attr (object, "sodipodi:r1"); + sp_object_read_attr (object, "sodipodi:r2"); + sp_object_read_attr (object, "sodipodi:arg1"); + sp_object_read_attr (object, "sodipodi:arg2"); + sp_object_read_attr (object, "inkscape:flatsided"); + sp_object_read_attr (object, "inkscape:rounded"); + sp_object_read_attr (object, "inkscape:randomized"); +} + +static Inkscape::XML::Node * +sp_star_write (SPObject *object, Inkscape::XML::Node *repr, guint flags) +{ + SPStar *star = SP_STAR (object); + + if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { + repr = sp_repr_new ("svg:path"); + } + + if (flags & SP_OBJECT_WRITE_EXT) { + repr->setAttribute("sodipodi:type", "star"); + sp_repr_set_int (repr, "sodipodi:sides", star->sides); + sp_repr_set_svg_double(repr, "sodipodi:cx", star->center[NR::X]); + sp_repr_set_svg_double(repr, "sodipodi:cy", star->center[NR::Y]); + sp_repr_set_svg_double(repr, "sodipodi:r1", star->r[0]); + sp_repr_set_svg_double(repr, "sodipodi:r2", star->r[1]); + sp_repr_set_svg_double(repr, "sodipodi:arg1", star->arg[0]); + sp_repr_set_svg_double(repr, "sodipodi:arg2", star->arg[1]); + sp_repr_set_boolean (repr, "inkscape:flatsided", star->flatsided); + sp_repr_set_svg_double(repr, "inkscape:rounded", star->rounded); + sp_repr_set_svg_double(repr, "inkscape:randomized", star->randomized); + } + + sp_star_set_shape ((SPShape *) star); + char *d = sp_svg_write_path (((SPShape *) star)->curve->bpath); + repr->setAttribute("d", d); + g_free (d); + + if (((SPObjectClass *) (parent_class))->write) + ((SPObjectClass *) (parent_class))->write (object, repr, flags); + + return repr; +} + +static void +sp_star_set (SPObject *object, unsigned int key, const gchar *value) +{ + SVGLength::Unit unit; + + SPStar *star = SP_STAR (object); + + /* fixme: we should really collect updates */ + switch (key) { + case SP_ATTR_SODIPODI_SIDES: + if (value) { + star->sides = atoi (value); + star->sides = CLAMP (star->sides, 3, 1024); + } else { + star->sides = 5; + } + object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_SODIPODI_CX: + if (!sp_svg_length_read_ldd (value, &unit, NULL, &star->center[NR::X]) || + (unit == SVGLength::EM) || + (unit == SVGLength::EX) || + (unit == SVGLength::PERCENT)) { + star->center[NR::X] = 0.0; + } + object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_SODIPODI_CY: + if (!sp_svg_length_read_ldd (value, &unit, NULL, &star->center[NR::Y]) || + (unit == SVGLength::EM) || + (unit == SVGLength::EX) || + (unit == SVGLength::PERCENT)) { + star->center[NR::Y] = 0.0; + } + object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_SODIPODI_R1: + if (!sp_svg_length_read_ldd (value, &unit, NULL, &star->r[0]) || + (unit == SVGLength::EM) || + (unit == SVGLength::EX) || + (unit == SVGLength::PERCENT)) { + star->r[0] = 1.0; + } + /* fixme: Need CLAMP (Lauris) */ + object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_SODIPODI_R2: + if (!sp_svg_length_read_ldd (value, &unit, NULL, &star->r[1]) || + (unit == SVGLength::EM) || + (unit == SVGLength::EX) || + (unit == SVGLength::PERCENT)) { + star->r[1] = 0.0; + } + object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + return; + case SP_ATTR_SODIPODI_ARG1: + if (value) { + star->arg[0] = g_ascii_strtod (value, NULL); + } else { + star->arg[0] = 0.0; + } + object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_SODIPODI_ARG2: + if (value) { + star->arg[1] = g_ascii_strtod (value, NULL); + } else { + star->arg[1] = 0.0; + } + object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_INKSCAPE_FLATSIDED: + if (value && !strcmp (value, "true")) + star->flatsided = true; + else star->flatsided = false; + object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_INKSCAPE_ROUNDED: + if (value) { + star->rounded = g_ascii_strtod (value, NULL); + } else { + star->rounded = 0.0; + } + object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + break; + case SP_ATTR_INKSCAPE_RANDOMIZED: + if (value) { + star->randomized = g_ascii_strtod (value, NULL); + } else { + star->randomized = 0.0; + } + object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + break; + default: + if (((SPObjectClass *) parent_class)->set) + ((SPObjectClass *) parent_class)->set (object, key, value); + break; + } +} + +static void +sp_star_update (SPObject *object, SPCtx *ctx, guint flags) +{ + if (flags & (SP_OBJECT_MODIFIED_FLAG | + SP_OBJECT_STYLE_MODIFIED_FLAG | + SP_OBJECT_VIEWPORT_MODIFIED_FLAG)) { + sp_shape_set_shape ((SPShape *) object); + } + + if (((SPObjectClass *) parent_class)->update) + ((SPObjectClass *) parent_class)->update (object, ctx, flags); +} + +static gchar * +sp_star_description (SPItem *item) +{ + SPStar *star = SP_STAR (item); + + // while there will never be less than 3 vertices, we still need to + // make calls to ngettext because the pluralization may be different + // for various numbers >=3. The singular form is used as the index. + if (star->flatsided == false ) + return g_strdup_printf (ngettext("Star with %d vertex", + "Star with %d vertices", + star->sides), star->sides); + else + return g_strdup_printf (ngettext("Polygon with %d vertex", + "Polygon with %d vertices", + star->sides), star->sides); +} + +/** +Returns a unit-length vector at 90 degrees to the direction from o to n + */ +static NR::Point +rot90_rel (NR::Point o, NR::Point n) +{ + return ((1/NR::L2(n - o)) * NR::Point ((n - o)[NR::Y], (o - n)[NR::X])); +} + +/** +Returns a unique 32 bit int for a given point. +Obvious (but acceptable for my purposes) limits to uniqueness: +- returned value for x,y repeats for x+n*1024,y+n*1024 +- returned value is unchanged when the point is moved by less than 1/1024 of px +*/ +static guint32 +point_unique_int (NR::Point o) +{ + return ((guint32) + 65536 * + (((int) floor (o[NR::X] * 64)) % 1024 + ((int) floor (o[NR::X] * 1024)) % 64) + + + (((int) floor (o[NR::Y] * 64)) % 1024 + ((int) floor (o[NR::Y] * 1024)) % 64) + ); +} + +/** +Returns the next pseudorandom value using the Linear Congruential Generator algorithm (LCG) +with the parameters (m = 2^32, a = 69069, b = 1). These parameters give a full-period generator, +i.e. it is guaranteed to go through all integers < 2^32 (see http://random.mat.sbg.ac.at/~charly/server/server.html) +*/ +static inline guint32 +lcg_next(guint32 const prev) +{ + return (guint32) ( 69069 * prev + 1 ); +} + +/** +Returns a random number in the range [-0.5, 0.5) from the given seed, stepping the given number of steps from the seed. +*/ +static double +rnd (guint32 const seed, unsigned steps) { + guint32 lcg = seed; + for (; steps > 0; steps --) + lcg = lcg_next (lcg); + + return ( lcg / 4294967296. ) - 0.5; +} + +static NR::Point +sp_star_get_curvepoint (SPStar *star, SPStarPoint point, gint index, bool previ) +{ + // the point whose neighboring curve handle we're calculating + NR::Point o = sp_star_get_xy (star, point, index); + + // indices of previous and next points + gint pi = (index > 0)? (index - 1) : (star->sides - 1); + gint ni = (index < star->sides - 1)? (index + 1) : 0; + + // the other point type + SPStarPoint other = (point == SP_STAR_POINT_KNOT2? SP_STAR_POINT_KNOT1 : SP_STAR_POINT_KNOT2); + + // the neighbors of o; depending on flatsided, they're either the same type (polygon) or the other type (star) + NR::Point prev = (star->flatsided? sp_star_get_xy (star, point, pi) : sp_star_get_xy (star, other, point == SP_STAR_POINT_KNOT2? index : pi)); + NR::Point next = (star->flatsided? sp_star_get_xy (star, point, ni) : sp_star_get_xy (star, other, point == SP_STAR_POINT_KNOT1? index : ni)); + + // prev-next midpoint + NR::Point mid = 0.5 * (prev + next); + + // point to which we direct the bissector of the curve handles; + // it's far enough outside the star on the perpendicular to prev-next through mid + NR::Point biss = mid + 100000 * rot90_rel (mid, next); + + // lengths of vectors to prev and next + gdouble prev_len = NR::L2 (prev - o); + gdouble next_len = NR::L2 (next - o); + + // unit-length vector perpendicular to o-biss + NR::Point rot = rot90_rel (o, biss); + + // multiply rot by star->rounded coefficient and the distance to the star point; flip for next + NR::Point ret; + if (previ) { + ret = (star->rounded * prev_len) * rot; + } else { + ret = (star->rounded * next_len * -1) * rot; + } + + if (star->randomized == 0) { + // add the vector to o to get the final curvepoint + return o + ret; + } else { + // the seed corresponding to the exact point + guint32 seed = point_unique_int (o); + + // randomly rotate (by step 3 from the seed) and scale (by step 4) the vector + ret = ret * NR::Matrix (NR::rotate (star->randomized * M_PI * rnd (seed, 3))); + ret *= ( 1 + star->randomized * rnd (seed, 4)); + + // the randomized corner point + NR::Point o_randomized = sp_star_get_xy (star, point, index, true); + + return o_randomized + ret; + } +} + + +#define NEXT false +#define PREV true + +static void +sp_star_set_shape (SPShape *shape) +{ + SPStar *star = SP_STAR (shape); + + SPCurve *c = sp_curve_new (); + + gint sides = star->sides; + bool not_rounded = (fabs (star->rounded) < 1e-4); + + // note that we pass randomized=true to sp_star_get_xy, because the curve must be randomized; + // other places that call that function (e.g. the knotholder) need the exact point + + // draw 1st segment + sp_curve_moveto (c, sp_star_get_xy (star, SP_STAR_POINT_KNOT1, 0, true)); + if (star->flatsided == false) { + if (not_rounded) { + sp_curve_lineto (c, sp_star_get_xy (star, SP_STAR_POINT_KNOT2, 0, true)); + } else { + sp_curve_curveto (c, + sp_star_get_curvepoint (star, SP_STAR_POINT_KNOT1, 0, NEXT), + sp_star_get_curvepoint (star, SP_STAR_POINT_KNOT2, 0, PREV), + sp_star_get_xy (star, SP_STAR_POINT_KNOT2, 0, true)); + } + } + + // draw all middle segments + for (gint i = 1; i < sides; i++) { + if (not_rounded) { + sp_curve_lineto (c, sp_star_get_xy (star, SP_STAR_POINT_KNOT1, i, true)); + } else { + if (star->flatsided == false) { + sp_curve_curveto (c, + sp_star_get_curvepoint (star, SP_STAR_POINT_KNOT2, i - 1, NEXT), + sp_star_get_curvepoint (star, SP_STAR_POINT_KNOT1, i, PREV), + sp_star_get_xy (star, SP_STAR_POINT_KNOT1, i, true)); + } else { + sp_curve_curveto (c, + sp_star_get_curvepoint (star, SP_STAR_POINT_KNOT1, i - 1, NEXT), + sp_star_get_curvepoint (star, SP_STAR_POINT_KNOT1, i, PREV), + sp_star_get_xy (star, SP_STAR_POINT_KNOT1, i, true)); + } + } + if (star->flatsided == false) { + + if (not_rounded) { + sp_curve_lineto (c, sp_star_get_xy (star, SP_STAR_POINT_KNOT2, i, true)); + } else { + sp_curve_curveto (c, + sp_star_get_curvepoint (star, SP_STAR_POINT_KNOT1, i, NEXT), + sp_star_get_curvepoint (star, SP_STAR_POINT_KNOT2, i, PREV), + sp_star_get_xy (star, SP_STAR_POINT_KNOT2, i, true)); + } + } + } + + // draw last segment + if (not_rounded) { + sp_curve_lineto (c, sp_star_get_xy (star, SP_STAR_POINT_KNOT1, 0, true)); + } else { + if (star->flatsided == false) { + sp_curve_curveto (c, + sp_star_get_curvepoint (star, SP_STAR_POINT_KNOT2, sides - 1, NEXT), + sp_star_get_curvepoint (star, SP_STAR_POINT_KNOT1, 0, PREV), + sp_star_get_xy (star, SP_STAR_POINT_KNOT1, 0, true)); + } else { + sp_curve_curveto (c, + sp_star_get_curvepoint (star, SP_STAR_POINT_KNOT1, sides - 1, NEXT), + sp_star_get_curvepoint (star, SP_STAR_POINT_KNOT1, 0, PREV), + sp_star_get_xy (star, SP_STAR_POINT_KNOT1, 0, true)); + } + } + + sp_curve_closepath (c); + sp_shape_set_curve_insync (SP_SHAPE (star), c, TRUE); + sp_curve_unref (c); +} + +void +sp_star_position_set (SPStar *star, gint sides, NR::Point center, gdouble r1, gdouble r2, gdouble arg1, gdouble arg2, bool isflat, double rounded, double randomized) +{ + g_return_if_fail (star != NULL); + g_return_if_fail (SP_IS_STAR (star)); + + star->sides = CLAMP (sides, 3, 1024); + star->center = center; + star->r[0] = MAX (r1, 0.001); + if (isflat == false) { + star->r[1] = CLAMP (r2, 0.0, star->r[0]); + } else { + star->r[1] = CLAMP ( r1*cos(M_PI/sides) ,0.0, star->r[0] ); + } + star->arg[0] = arg1; + star->arg[1] = arg2; + star->flatsided = isflat; + star->rounded = rounded; + star->randomized = randomized; + SP_OBJECT(star)->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); +} + +/* fixme: We should use all corners of star (Lauris) */ + +static void sp_star_snappoints(SPItem const *item, SnapPointsIter p) +{ + if (((SPItemClass *) parent_class)->snappoints) { + ((SPItemClass *) parent_class)->snappoints (item, p); + } +} + +/** + * sp_star_get_xy: Get X-Y value as item coordinate system + * @star: star item + * @point: point type to obtain X-Y value + * @index: index of vertex + * @p: pointer to store X-Y value + * @randomized: false (default) if you want to get exact, not randomized point + * + * Initial item coordinate system is same as document coordinate system. + */ + +NR::Point +sp_star_get_xy (SPStar *star, SPStarPoint point, gint index, bool randomized) +{ + gdouble darg = 2.0 * M_PI / (double) star->sides; + + double arg = star->arg[point]; + arg += index * darg; + + NR::Point xy = star->r[point] * NR::Point(cos(arg), sin(arg)) + star->center; + + if (!randomized || star->randomized == 0) { + // return the exact point + return xy; + } else { // randomize the point + // find out the seed, unique for this point so that randomization is the same so long as the original point is stationary + guint32 seed = point_unique_int (xy); + // the full range (corresponding to star->randomized == 1.0) is equal to the star's diameter + double range = 2 * MAX (star->r[0], star->r[1]); + // find out the random displacement; x is controlled by step 1 from the seed, y by the step 2 + NR::Point shift (star->randomized * range * rnd (seed, 1), star->randomized * range * rnd (seed, 2)); + // add the shift to the exact point + return xy + shift; + } +} + diff --git a/src/sp-star.h b/src/sp-star.h new file mode 100644 index 000000000..f6b70df22 --- /dev/null +++ b/src/sp-star.h @@ -0,0 +1,59 @@ +#ifndef __SP_STAR_H__ +#define __SP_STAR_H__ + +/* + * implementation + * + * Authors: + * Mitsuru Oka + * Lauris Kaplinski + * + * Copyright (C) 1999-2002 Lauris Kaplinski + * Copyright (C) 2000-2001 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "sp-polygon.h" + + + +#define SP_TYPE_STAR (sp_star_get_type ()) +#define SP_STAR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SP_TYPE_STAR, SPStar)) +#define SP_STAR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SP_TYPE_STAR, SPStarClass)) +#define SP_IS_STAR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_STAR)) +#define SP_IS_STAR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SP_TYPE_STAR)) + +class SPStar; +class SPStarClass; + +typedef enum { + SP_STAR_POINT_KNOT1, + SP_STAR_POINT_KNOT2 +} SPStarPoint; + +struct SPStar : public SPPolygon { + gint sides; + + NR::Point center; + double r[2]; + double arg[2]; + bool flatsided; + + double rounded; + double randomized; +}; + +struct SPStarClass { + SPPolygonClass parent_class; +}; + +GType sp_star_get_type (void); + +void sp_star_position_set (SPStar *star, gint sides, NR::Point center, gdouble r1, gdouble r2, gdouble arg1, gdouble arg2, bool isflat, double rounded, double randomized); + +NR::Point sp_star_get_xy (SPStar *star, SPStarPoint point, gint index, bool randomized = false); + + + +#endif diff --git a/src/sp-stop-fns.h b/src/sp-stop-fns.h new file mode 100644 index 000000000..9903359e9 --- /dev/null +++ b/src/sp-stop-fns.h @@ -0,0 +1,17 @@ +#ifndef SEEN_SP_STOP_FNS_H +#define SEEN_SP_STOP_FNS_H + +#include +struct SPStop; +struct SPStopClass; + +#define SP_TYPE_STOP (sp_stop_get_type()) +#define SP_STOP(o) (G_TYPE_CHECK_INSTANCE_CAST((o), SP_TYPE_STOP, SPStop)) +#define SP_STOP_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), SP_TYPE_STOP, SPStopClass)) +#define SP_IS_STOP(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), SP_TYPE_STOP)) +#define SP_IS_STOP_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE((k), SP_TYPE_STOP)) + +GType sp_stop_get_type(); + + +#endif /* !SEEN_SP_STOP_FNS_H */ diff --git a/src/sp-stop.h b/src/sp-stop.h new file mode 100644 index 000000000..20f72a3f5 --- /dev/null +++ b/src/sp-stop.h @@ -0,0 +1,56 @@ +#ifndef SEEN_SP_STOP_H +#define SEEN_SP_STOP_H + +/** \file + * + * SPStop: SVG implementation. + * + * Authors? + */ + +#include +//#include +//#include "sp-object.h" +//#include "color.h" +#include "sp-stop-fns.h" + +class SPObjectClass; +class SPColor; + +/** Gradient stop. */ +struct SPStop : public SPObject { + /// \todo fixme: Should be SPSVGPercentage + gfloat offset; + + bool currentColor; + + /** \note + * N.B.\ Meaningless if currentColor is true. Use sp_stop_get_rgba32 or sp_stop_get_color + * (currently static in sp-gradient.cpp) if you want the effective color. + */ + SPColor specified_color; + + /// \todo fixme: Implement SPSVGNumber or something similar. + gfloat opacity; +}; + +/// The SPStop vtable. +struct SPStopClass { + SPObjectClass parent_class; +}; + +guint32 sp_stop_get_rgba32(SPStop const *); + + +#endif /* !SEEN_SP_STOP_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:encoding=utf-8:textwidth=99 : diff --git a/src/sp-string.cpp b/src/sp-string.cpp new file mode 100644 index 000000000..ba3df3ef2 --- /dev/null +++ b/src/sp-string.cpp @@ -0,0 +1,178 @@ +#define __SP_STRING_C__ + +/* + * SVG and implementation + * + * Author: + * Lauris Kaplinski + * + * Copyright (C) 1999-2002 Lauris Kaplinski + * Copyright (C) 2000-2001 Ximian, Inc. + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +/* + * fixme: + * + * These subcomponents should not be items, or alternately + * we have to invent set of flags to mark, whether standard + * attributes are applicable to given item (I even like this + * idea somewhat - Lauris) + * + */ + + + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + + +#include "sp-string.h" +#include "xml/repr.h" + + +/*##################################################### +# SPSTRING +#####################################################*/ + +static void sp_string_class_init(SPStringClass *classname); +static void sp_string_init(SPString *string); + +static void sp_string_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr); +static void sp_string_release(SPObject *object); +static void sp_string_read_content(SPObject *object); +static void sp_string_update(SPObject *object, SPCtx *ctx, unsigned flags); + +static void sp_string_calculate_dimensions(SPString *string); + +static SPObjectClass *string_parent_class; + +GType +sp_string_get_type() +{ + static GType type = 0; + if (!type) { + GTypeInfo info = { + sizeof(SPStringClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) sp_string_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof(SPString), + 16, /* n_preallocs */ + (GInstanceInitFunc) sp_string_init, + NULL, /* value_table */ + }; + type = g_type_register_static(SP_TYPE_OBJECT, "SPString", &info, (GTypeFlags)0); + } + return type; +} + +static void +sp_string_class_init(SPStringClass *classname) +{ + SPObjectClass *sp_object_class; + SPItemClass *item_class; + + sp_object_class = (SPObjectClass *) classname; + item_class = (SPItemClass *) classname; + + string_parent_class = (SPObjectClass*)g_type_class_ref(SP_TYPE_OBJECT); + + sp_object_class->build = sp_string_build; + sp_object_class->release = sp_string_release; + sp_object_class->read_content = sp_string_read_content; + sp_object_class->update = sp_string_update; +} + +static void +sp_string_init(SPString *string) +{ + new (&string->string) Glib::ustring(); +} + +static void +sp_string_build(SPObject *object, SPDocument *doc, Inkscape::XML::Node *repr) +{ + sp_string_read_content(object); + + if (((SPObjectClass *) string_parent_class)->build) + ((SPObjectClass *) string_parent_class)->build(object, doc, repr); +} + +static void +sp_string_release(SPObject *object) +{ + SPString *string = SP_STRING(object); + + string->string.~ustring(); + + if (((SPObjectClass *) string_parent_class)->release) + ((SPObjectClass *) string_parent_class)->release(object); +} + +static void +sp_string_read_content(SPObject *object) +{ + SPString *string = SP_STRING(object); + + string->string.clear(); + gchar const *xml_string = string->repr->content(); + // see algorithms described in svg 1.1 section 10.15 + if (object->xml_space.value == SP_XML_SPACE_PRESERVE) { + for ( ; *xml_string ; xml_string = g_utf8_next_char(xml_string) ) { + gunichar c = g_utf8_get_char(xml_string); + if (c == '\n' || c == '\t') c = ' '; + string->string += c; + } + } + else { + bool whitespace = false; + for ( ; *xml_string ; xml_string = g_utf8_next_char(xml_string) ) { + gunichar c = g_utf8_get_char(xml_string); + if (c == '\n') continue; + if (c == ' ' || c == '\t') whitespace = true; + else { + if (whitespace && (!string->string.empty() || SP_OBJECT_PREV(object) != NULL)) + string->string += ' '; + string->string += c; + whitespace = false; + } + } + if (whitespace && SP_OBJECT_REPR(object)->next() != NULL) // can't use SP_OBJECT_NEXT() when the SPObject tree is still being built + string->string += ' '; + } + object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); +} + +static void +sp_string_update(SPObject *object, SPCtx *ctx, unsigned flags) +{ + if (((SPObjectClass *) string_parent_class)->update) + ((SPObjectClass *) string_parent_class)->update(object, ctx, flags); + + if (flags & (SP_OBJECT_STYLE_MODIFIED_FLAG | SP_OBJECT_MODIFIED_FLAG)) { + /* Parent style or we ourselves changed, so recalculate */ + flags &= ~SP_OBJECT_USER_MODIFIED_FLAG_B; // won't be "just a transformation" anymore, we're going to recompute "x" and "y" attributes + sp_string_calculate_dimensions(SP_STRING(object)); + } +} + +static void +sp_string_calculate_dimensions(SPString *) +{ +} + +/* + 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:textwidth=99 : diff --git a/src/sp-string.h b/src/sp-string.h new file mode 100644 index 000000000..7242589c6 --- /dev/null +++ b/src/sp-string.h @@ -0,0 +1,30 @@ +#ifndef __SP_STRING_H__ +#define __SP_STRING_H__ + +/* + * string elements + * extracted from sp-text + */ + +#include + +#include "sp-object.h" + +#define SP_TYPE_STRING (sp_string_get_type ()) +#define SP_STRING(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SP_TYPE_STRING, SPString)) +#define SP_STRING_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SP_TYPE_STRING, SPStringClass)) +#define SP_IS_STRING(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_STRING)) +#define SP_IS_STRING_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SP_TYPE_STRING)) + + +struct SPString : public SPObject { + Glib::ustring string; +}; + +struct SPStringClass { + SPObjectClass parent_class; +}; + +GType sp_string_get_type (); + +#endif diff --git a/src/sp-style-elem-test.cpp b/src/sp-style-elem-test.cpp new file mode 100644 index 000000000..97be4fead --- /dev/null +++ b/src/sp-style-elem-test.cpp @@ -0,0 +1,118 @@ +#include "attributes.h" +#include "document.h" +#include "inkscape-private.h" +#include "sp-style-elem.h" +#include "streq.h" +#include "utest/utest.h" +#include "xml/repr.h" + +/// Dummy functions to keep linker happy +int sp_main_gui (int, char const**) { return 0; } +int sp_main_console (int, char const**) { return 0; } + +static bool +test_style_elem() +{ + utest_start("SPStyleElem"); +//#if 0 + UTEST_TEST("init") { + SPStyleElem *style_elem = static_cast(g_object_new(SP_TYPE_STYLE_ELEM, NULL)); + UTEST_ASSERT(!style_elem->is_css); + UTEST_ASSERT(style_elem->media.print); + UTEST_ASSERT(style_elem->media.screen); + g_object_unref(style_elem); + } +//#endif + + /* Create the global inkscape object. */ + static_cast(g_object_new(inkscape_get_type(), NULL)); + +//#if 0 + SPDocument *doc = sp_document_new_dummy(); + + UTEST_TEST("sp_object_set(\"type\")") { + SPStyleElem *style_elem = static_cast(g_object_new(SP_TYPE_STYLE_ELEM, NULL)); + SP_OBJECT(style_elem)->document = doc; + sp_object_set(SP_OBJECT(style_elem), SP_ATTR_TYPE, "something unrecognized"); + UTEST_ASSERT(!style_elem->is_css); + sp_object_set(SP_OBJECT(style_elem), SP_ATTR_TYPE, "text/css"); + UTEST_ASSERT(style_elem->is_css); + sp_object_set(SP_OBJECT(style_elem), SP_ATTR_TYPE, "atext/css"); + UTEST_ASSERT(!style_elem->is_css); + sp_object_set(SP_OBJECT(style_elem), SP_ATTR_TYPE, "text/cssx"); + UTEST_ASSERT(!style_elem->is_css); + g_object_unref(style_elem); + } + + UTEST_TEST("write") { + SPStyleElem *style_elem = SP_STYLE_ELEM(g_object_new(SP_TYPE_STYLE_ELEM, NULL)); + SP_OBJECT(style_elem)->document = doc; + sp_object_set(SP_OBJECT(style_elem), SP_ATTR_TYPE, "text/css"); + Inkscape::XML::Node *repr = sp_repr_new("svg:style"); + SP_OBJECT(style_elem)->updateRepr(repr, SP_OBJECT_WRITE_ALL); + { + gchar const *typ = repr->attribute("type"); + UTEST_ASSERT(streq(typ, "text/css")); + } + g_object_unref(style_elem); + } + + UTEST_TEST("build") { + SPStyleElem &style_elem = *SP_STYLE_ELEM(g_object_new(SP_TYPE_STYLE_ELEM, NULL)); + Inkscape::XML::Node *const repr = sp_repr_new("svg:style"); + repr->setAttribute("type", "text/css"); + sp_object_invoke_build(&style_elem, doc, repr, false); + UTEST_ASSERT(style_elem.is_css); + UTEST_ASSERT(style_elem.media.print); + UTEST_ASSERT(style_elem.media.screen); + + /* Some checks relevant to the read_content test below. */ + { + g_assert(doc->style_cascade); + CRStyleSheet const *const stylesheet = cr_cascade_get_sheet(doc->style_cascade, ORIGIN_AUTHOR); + g_assert(stylesheet); + g_assert(stylesheet->statements == NULL); + } + + g_object_unref(&style_elem); + Inkscape::GC::release(repr); + } + + UTEST_TEST("read_content") { + SPStyleElem &style_elem = *SP_STYLE_ELEM(g_object_new(SP_TYPE_STYLE_ELEM, NULL)); + Inkscape::XML::Node *const repr = sp_repr_new("svg:style"); + repr->setAttribute("type", "text/css"); + Inkscape::XML::Node *const content_repr = sp_repr_new_text(".myclass { }"); + repr->addChild(content_repr, NULL); + sp_object_invoke_build(&style_elem, doc, repr, false); + UTEST_ASSERT(style_elem.is_css); + UTEST_ASSERT(doc->style_cascade); + CRStyleSheet const *const stylesheet = cr_cascade_get_sheet(doc->style_cascade, ORIGIN_AUTHOR); + UTEST_ASSERT(stylesheet != NULL); + UTEST_ASSERT(stylesheet->statements != NULL); + g_object_unref(&style_elem); + Inkscape::GC::release(repr); + } +//#endif + return utest_end(); +} + +int main() +{ + g_type_init(); + Inkscape::GC::init(); + return ( test_style_elem() + ? EXIT_SUCCESS + : EXIT_FAILURE ); +} + +/* + 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:textwidth=99 : diff --git a/src/sp-style-elem.cpp b/src/sp-style-elem.cpp new file mode 100644 index 000000000..ff27f3de0 --- /dev/null +++ b/src/sp-style-elem.cpp @@ -0,0 +1,407 @@ +#include +#include "xml/node-event-vector.h" +#include "xml/repr.h" +#include "document.h" +#include "sp-style-elem.h" +#include "attributes.h" +using Inkscape::XML::TEXT_NODE; + +static void sp_style_elem_init(SPStyleElem *style_elem); +static void sp_style_elem_class_init(SPStyleElemClass *klass); +static void sp_style_elem_build(SPObject *object, SPDocument *doc, Inkscape::XML::Node *repr); +static void sp_style_elem_set(SPObject *object, unsigned const key, gchar const *const value); +static void sp_style_elem_read_content(SPObject *); +static Inkscape::XML::Node *sp_style_elem_write(SPObject *, Inkscape::XML::Node *, guint flags); + +static SPObjectClass *parent_class; + +GType +sp_style_elem_get_type() +{ + static GType type = 0; + if (!type) { + GTypeInfo info = { + sizeof(SPStyleElemClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) sp_style_elem_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof(SPStyleElem), + 16, /* n_preallocs */ + (GInstanceInitFunc) sp_style_elem_init, + NULL, /* value_table */ + }; + type = g_type_register_static(SP_TYPE_OBJECT, "SPStyleElem", &info, (GTypeFlags) 0); + } + + return type; +} + +static void +sp_style_elem_class_init(SPStyleElemClass *klass) +{ + parent_class = (SPObjectClass *)g_type_class_ref(SP_TYPE_OBJECT); + /* FIXME */ + + klass->build = sp_style_elem_build; + klass->set = sp_style_elem_set; + klass->read_content = sp_style_elem_read_content; + klass->write = sp_style_elem_write; +} + +static void +sp_style_elem_init(SPStyleElem *style_elem) +{ + media_set_all(style_elem->media); + style_elem->is_css = false; +} + +static void +sp_style_elem_set(SPObject *object, unsigned const key, gchar const *const value) +{ + g_return_if_fail(object); + SPStyleElem &style_elem = *SP_STYLE_ELEM(object); + + switch (key) { + case SP_ATTR_TYPE: { + if (!value) { + /* TODO: `type' attribute is required. Give error message as per + http://www.w3.org/TR/SVG11/implnote.html#ErrorProcessing. */ + style_elem.is_css = false; + } else { + /* fixme: determine what whitespace is allowed. Will probably need to ask on SVG + * list; though the relevant RFC may give info on its lexer. */ + style_elem.is_css = ( g_ascii_strncasecmp(value, "text/css", 8) == 0 + && ( value[8] == '\0' || + value[8] == ';' ) ); + } + break; + } + +#if 0 /* unfinished */ + case SP_ATTR_MEDIA: { + parse_media(style_elem, value); + break; + } +#endif + + /* title is ignored. */ + default: { + if (parent_class->set) { + parent_class->set(object, key, value); + } + break; + } + } +} + +static void +child_add_rm_cb(Inkscape::XML::Node *, Inkscape::XML::Node *, Inkscape::XML::Node *, + void *const data) +{ + sp_style_elem_read_content(static_cast(data)); +} + +static void +content_changed_cb(Inkscape::XML::Node *, gchar const *, gchar const *, + void *const data) +{ + sp_style_elem_read_content(static_cast(data)); +} + +static void +child_order_changed_cb(Inkscape::XML::Node *, Inkscape::XML::Node *, + Inkscape::XML::Node *, Inkscape::XML::Node *, + void *const data) +{ + sp_style_elem_read_content(static_cast(data)); +} + +static Inkscape::XML::Node * +sp_style_elem_write(SPObject *const object, Inkscape::XML::Node *repr, guint const flags) +{ + if ((flags & SP_OBJECT_WRITE_BUILD) && !repr) { + repr = sp_repr_new("svg:style"); + } + + g_return_val_if_fail(object, repr); + SPStyleElem &style_elem = *SP_STYLE_ELEM(object); + if (flags & SP_OBJECT_WRITE_BUILD) { + g_warning("nyi: Forming